diff --git a/.clang-format b/.clang-format index fe563fa..94165fc 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,5 @@ BasedOnStyle: Google -ColumnLimit: 100 +ColumnLimit: 120 UseTab: Never IndentWidth: 4 BreakBeforeBraces: Allman diff --git a/.gitignore b/.gitignore index b7cc7e7..b0c3f74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,2 @@ -# Visual code -.vs/ - -# Visual studio project files -*.vcxproj -*.vcxproj.filters -*.sln - -# Visual studio temp files -*.dir/ -Debug/ -Release/ -x64/ - -# CMake cache files -cmake_install.cmake -CMakeCache.txt -CMakeFiles/ \ No newline at end of file +build/ +CMakeUserPresets.json \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b12af44..0000000 --- a/.gitmodules +++ /dev/null @@ -1,28 +0,0 @@ -[submodule "Foundation/Lib/external/cryptopp"] - path = Foundation/Lib/external/cryptopp - url = https://github.com/weidai11/cryptopp.git - ignore = dirty -[submodule "Foundation/Lib/external/jsoncpp"] - path = Foundation/Lib/external/jsoncpp - url = https://github.com/open-source-parsers/jsoncpp.git - ignore = dirty -[submodule "Foundation/Lib/external/glm"] - path = Foundation/Lib/external/glm - url = https://github.com/g-truc/glm.git - ignore = dirty -[submodule "Foundation/Lib/external/tinyxml2"] - path = Foundation/Lib/external/tinyxml2 - url = https://github.com/leethomason/tinyxml2.git - ignore = dirty -[submodule "Graphics/Lib/external/glfw"] - path = Graphics/Lib/external/glfw - url = https://github.com/glfw/glfw.git - ignore = dirty -[submodule "Graphics/Lib/external/tinyobjloader"] - path = Graphics/Lib/external/tinyobjloader - url = https://github.com/syoyo/tinyobjloader.git - ignore = dirty -[submodule "Graphics/Lib/external/lodepng"] - path = Graphics/Lib/external/lodepng - url = https://github.com/lvandeve/lodepng.git - ignore = dirty diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0db5873 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": true +} \ No newline at end of file diff --git a/Application/CMakeLists.txt b/Application/CMakeLists.txt deleted file mode 100644 index 2284b45..0000000 --- a/Application/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required (VERSION 3.0.0) -project (Application) - -set(CXX_STANDARD_REQUIRED ON) - -add_subdirectory (Lib) -add_subdirectory (Test) \ No newline at end of file diff --git a/Application/Lib/CMakeLists.txt b/Application/Lib/CMakeLists.txt deleted file mode 100644 index e7d7102..0000000 --- a/Application/Lib/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Application library source files -file(GLOB_RECURSE SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hxx - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hxx -) - -add_library (${PROJECT_NAME} ${SOURCE_FILES}) - -# Properties -set_target_properties(${PROJECT_NAME} PROPERTIES - CXX_STANDARD 11 -) - -# Includes -target_include_directories(${PROJECT_NAME} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include -) - -# Link dependencies -target_link_libraries(${PROJECT_NAME} - LINK_PUBLIC Graphics -) \ No newline at end of file diff --git a/Application/Lib/include/application/app/AGameApplication.h b/Application/Lib/include/application/app/AGameApplication.h deleted file mode 100644 index fea43f8..0000000 --- a/Application/Lib/include/application/app/AGameApplication.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -class AGameApplication : public AApplication -{ -public: - - virtual bool initialize() override; - virtual void deinitialize() override; - -private: - -}; \ No newline at end of file diff --git a/Application/Lib/include/application/io/LoadGame.h b/Application/Lib/include/application/io/LoadGame.h deleted file mode 100644 index d3944ba..0000000 --- a/Application/Lib/include/application/io/LoadGame.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace Json -{ -class Value; -} - -class IResourceManager; -class CGameSystem; - -/** - * \brief Loads entire game. - */ -bool load(const std::string &file, IResourceManager &manager, CGameSystem &system); -bool loadGameStates(const Json::Value &node, IResourceManager &manager, CGameSystem &system); -bool loadGameState(const Json::Value &node, IResourceManager &manager, CGameSystem &system); -bool loadGameState(const std::string &file, const std::string &name, IResourceManager &manager, - CGameSystem &system); \ No newline at end of file diff --git a/Application/Lib/source/app/AGameApplication.cpp b/Application/Lib/source/app/AGameApplication.cpp deleted file mode 100644 index b6a3211..0000000 --- a/Application/Lib/source/app/AGameApplication.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "application/app/AGameApplication.h" - -bool AGameApplication::initialize() -{ - return true; -} - -void AGameApplication::deinitialize() -{ - return; -} \ No newline at end of file diff --git a/Application/Lib/source/game/IController.cpp b/Application/Lib/source/game/IController.cpp deleted file mode 100644 index c7fb405..0000000 --- a/Application/Lib/source/game/IController.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "application/game/IController.h" - -IController::~IController() { return; } \ No newline at end of file diff --git a/Application/Lib/source/game/IGameState.cpp b/Application/Lib/source/game/IGameState.cpp deleted file mode 100644 index d1cbaee..0000000 --- a/Application/Lib/source/game/IGameState.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "application/game/IGameState.h" - -IGameState::~IGameState() { return; } \ No newline at end of file diff --git a/Application/Test/CMakeLists.txt b/Application/Test/CMakeLists.txt deleted file mode 100644 index 588fb31..0000000 --- a/Application/Test/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -# Boost libraries -set(Boost_USE_STATIC_LIBS ON CACHE BOOL "") -find_package(Boost 1.55 REQUIRED system unit_test_framework) - - -set (TEST_NAME ${PROJECT_NAME}Test) - -file(GLOB_RECURSE SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hxx - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hxx -) - -add_executable (${TEST_NAME} ${SOURCE_FILES}) - -# Require C++11 -set_target_properties(${TEST_NAME} PROPERTIES - CXX_STANDARD 11 -) - -# Library -target_link_libraries (${TEST_NAME} - LINK_PRIVATE ${PROJECT_NAME} - LINK_PRIVATE ${Boost_LIBRARIES} -) - -target_include_directories(${TEST_NAME} - PRIVATE ${Boost_INCLUDE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source/ -) \ No newline at end of file diff --git a/Application/Test/source/Main.cpp b/Application/Test/source/Main.cpp deleted file mode 100644 index 03f094e..0000000 --- a/Application/Test/source/Main.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include - -int main(int argc, char** argv) { return 0; } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index d43e6c0..11913a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,50 @@ -cmake_minimum_required (VERSION 3.0.0) -project (KernEngine) +cmake_minimum_required(VERSION 3.25.0) +project(KernEngine) -# Use folder structure -set_property (GLOBAL PROPERTY USE_FOLDERS ON) +# Demo project as default startup +set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT RenderDemo) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +set(CXX_STANDARD_REQUIRED ON) -# Foundation library -add_subdirectory (Foundation) +if (MSVC) + # Ignore warnings about missing pdb + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4099") + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4099") +endif() -# Graphics and rendering library -add_subdirectory (Graphics) -# Application layer library -add_subdirectory (Application) +# Testing +find_package(catch2 REQUIRED) -# Utility library for toolkit -add_subdirectory (Util) +# Dependencies +# Foundation +find_package(glm REQUIRED) +find_package(nlohmann_json REQUIRED) +find_package(SQLite3 REQUIRED) +find_package(fmtlog REQUIRED) -# Tools and applications -add_subdirectory (Toolkit) +# Graphics +find_package(OpenGL REQUIRED) +find_package(glfw3 REQUIRED) +find_package(glad REQUIRED) +find_package(tinyobjloader REQUIRED) +find_package(assimp REQUIRED) +find_package(stb REQUIRED) +find_package(Freetype REQUIRED) +find_package(imgui REQUIRED) -# Demo -add_subdirectory (Demo) \ No newline at end of file +# Audio +find_package(OpenAL REQUIRED) +find_package(vorbis REQUIRED) +find_package(minimp3 REQUIRED) + +# Scripting +find_package(lua REQUIRED) + +# Engine +add_subdirectory(Engine) + +# Demo applications and sample games +# Depends on Engine +add_subdirectory(Demo) \ No newline at end of file diff --git a/Demo/CG2015/CMakeLists.txt b/Demo/CG2015/CMakeLists.txt index 652121e..0525365 100644 --- a/Demo/CG2015/CMakeLists.txt +++ b/Demo/CG2015/CMakeLists.txt @@ -1,26 +1,27 @@ -cmake_minimum_required (VERSION 3.0.0) -project (DemoCG2015) +# Computer Graphics 2 project from 2015 +project (CG2015) -file (GLOB_RECURSE SOURCE_FILES +file (GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hxx ) +# Source group to preserve folder structure in ide +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) add_executable (${PROJECT_NAME} ${SOURCE_FILES}) set_target_properties (${PROJECT_NAME} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 + FOLDER "Demo" ) -# Link dependencies target_link_libraries (${PROJECT_NAME} - LINK_PRIVATE Application + PRIVATE EngineLib ) -# Includes target_include_directories (${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source ) diff --git a/Demo/CG2015/data/audio/bgm/kim-lightyear-stardust-vision-ii-135754.mp3 b/Demo/CG2015/data/audio/bgm/kim-lightyear-stardust-vision-ii-135754.mp3 new file mode 100644 index 0000000..b2061a3 Binary files /dev/null and b/Demo/CG2015/data/audio/bgm/kim-lightyear-stardust-vision-ii-135754.mp3 differ diff --git a/Demo/CG2015/data/audio/bgm/this-minimal-technology-pure-12327.mp3 b/Demo/CG2015/data/audio/bgm/this-minimal-technology-pure-12327.mp3 new file mode 100644 index 0000000..84fcd5e Binary files /dev/null and b/Demo/CG2015/data/audio/bgm/this-minimal-technology-pure-12327.mp3 differ diff --git a/Demo/CG2015/data/audio/sfx/Readme.txt b/Demo/CG2015/data/audio/sfx/Readme.txt deleted file mode 100644 index 84ed1c2..0000000 --- a/Demo/CG2015/data/audio/sfx/Readme.txt +++ /dev/null @@ -1,4 +0,0 @@ -File: explosion1.pm3 -Artist: Unknown -Source: Unknown -License type: Fair Use \ No newline at end of file diff --git a/Demo/CG2015/data/audio/sfx/explosion-91872.mp3 b/Demo/CG2015/data/audio/sfx/explosion-91872.mp3 new file mode 100644 index 0000000..3433572 Binary files /dev/null and b/Demo/CG2015/data/audio/sfx/explosion-91872.mp3 differ diff --git a/Demo/CG2015/data/audio/sfx/explosion1.mp3 b/Demo/CG2015/data/audio/sfx/explosion1.mp3 deleted file mode 100644 index b721c7a..0000000 Binary files a/Demo/CG2015/data/audio/sfx/explosion1.mp3 and /dev/null differ diff --git a/Demo/CG2015/data/audio/sfx/shoot02wav-14562.mp3 b/Demo/CG2015/data/audio/sfx/shoot02wav-14562.mp3 new file mode 100644 index 0000000..3992452 Binary files /dev/null and b/Demo/CG2015/data/audio/sfx/shoot02wav-14562.mp3 differ diff --git a/Demo/CG2015/data/image/lava_ground.png b/Demo/CG2015/data/image/lava_ground.png deleted file mode 100644 index 9d17afb..0000000 Binary files a/Demo/CG2015/data/image/lava_ground.png and /dev/null differ diff --git a/Demo/CG2015/data/material/stone_lava.json b/Demo/CG2015/data/material/stone_lava.json index 6053cfb..0cceffd 100644 --- a/Demo/CG2015/data/material/stone_lava.json +++ b/Demo/CG2015/data/material/stone_lava.json @@ -1,4 +1,4 @@ { - "base" : "data/image/lava_ground.png", + "base" : "data/image/lava_ground.jpg", "glow" : "data/image/lava_ground_glow.png" } \ No newline at end of file diff --git a/Demo/CG2015/data/script/main.lua b/Demo/CG2015/data/script/main.lua deleted file mode 100644 index 3bacd23..0000000 --- a/Demo/CG2015/data/script/main.lua +++ /dev/null @@ -1,2 +0,0 @@ --- Main script, loaded and exectured on run -io.write("Using lua version ", _VERSION, "\n") diff --git a/Demo/CG2015/data/startup.ini b/Demo/CG2015/data/startup.ini index eaba956..8633799 100644 --- a/Demo/CG2015/data/startup.ini +++ b/Demo/CG2015/data/startup.ini @@ -12,8 +12,8 @@ # and sets the application into the initial game state. # This mode is used for actual games. # The default value is demo. -type=demo -#type=game +#type=demo +type=game [scene] diff --git a/Demo/CG2015/source/CEngine.cpp b/Demo/CG2015/source/CEngine.cpp deleted file mode 100644 index d29fca5..0000000 --- a/Demo/CG2015/source/CEngine.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include "CEngine.h" - -#include -#include -#include - -// Debug -#include -#include -#include -#include - -#include -#include - -#include -#include - -// Graphics -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/renderer/debug/RendererDebug.h" -#include "graphics/graphics/system/CGraphicsSystem.h" - -#include - -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/graphics/camera/CFreeCamera.h" - -// Renderer types -#include "graphics/graphics/renderer/CDeferredRenderer.h" -#include "graphics/graphics/renderer/CForwardRenderer.h" - -#include "graphics/graphics/CDebugInfoDisplay.h" -#include "graphics/graphics/resource/CGraphicsResourceManager.h" -#include "graphics/graphics/scene/CScene.h" -#include "graphics/graphics/window/CGlfwWindow.h" - -// Resource system -#include "graphics/resource/Resource.h" - -#include "CFreeFlightCameraController.h" -#include "graphics/input/provider/CGlfwInputProvider.h" -#include "graphics/io/CSceneLoader.h" - -// Animation -#include "graphics/animation/CAnimationWorld.h" - -// Game -#include "application/game/CGameSystem.h" - -#include "state/CDemoState.h" -#include "state/CGamePlayState.h" -#include "state/CLoadState.h" -#include "state/CLoseState.h" -#include "state/CTitleState.h" -#include "state/CWinState.h" - -CEngine::CEngine() {} - -CEngine::~CEngine() -{ - m_gameSystem = nullptr; - std::stringstream ss; - if (!CProfiler::write(ss)) - { - KERN_WARNING("Failed to retrieve profiling data."); - } - KERN_DEBUG("Profiler info: " << ss.str()); -} - -bool CEngine::init(const char *configFile) -{ - // Init log file - std::string logFile = "log_" + createTimeStamp() + ".log"; - if (!CLogger::initLogFile(logFile)) - { - KERN_WARNING("Failed to create log file at " << logFile); - } - - // Load configuration file - if (!load(configFile, m_engineConfig)) - { - KERN_WARNING("Failed to load config file " << configFile - << ". Starting with default settings."); - // TODO Return if no config exists? - } - - // Create window for rendering - if (!initWindow(m_engineConfig.m_windowWidth, m_engineConfig.m_windowHeight, - m_engineConfig.m_windowTitle)) - { - LOG_ERROR("Failed to initialize window."); - return false; - } - // TODO GLFW handle not properly wrapped away, GFLW should not be used - // directly - m_inputProvider = std::make_shared(m_window->getGlfwHandle()); - - // Create central resource manager - m_resourceManager.reset(createResourceManager()); - if (m_resourceManager == nullptr) - { - LOG_ERROR("Failed to initialize resource manager."); - return false; - } - - // Create and initialize graphics system - m_graphicsSystem = std::make_shared(); - if (!m_graphicsSystem->init(*m_resourceManager)) - { - LOG_ERROR("Failed to initialize graphics system."); - return false; - } - - // Legacy stuff to keep demo mode working - // TODO Should be removed - if (!m_engineConfig.m_sceneFile.empty() && m_engineConfig.m_modeType != "game") - { - if (!initDemo(m_engineConfig.m_sceneFile)) - { - LOG_ERROR("Failed to initialize demo mode."); - return false; - } - } - else if (!m_engineConfig.m_gameFile.empty()) // Create and initialize game system - { - if (!initGameSystem(m_engineConfig.m_gameFile)) - { - LOG_ERROR("Failed to initialize game system."); - return false; - } - } - else - { - KERN_ERROR("No scene file or game file specified"); - return false; - } - return true; -} - -void CEngine::run() -{ - // Fn key cooldown values - double f1Cooldown = 0.0; - double f2Cooldown = 0.0; - double f3Cooldown = 0.0; - double f4Cooldown = 0.0; - double f5Cooldown = 0.0; - double f6Cooldown = 0.0; - double f7Cooldown = 0.0; - double f8Cooldown = 0.0; - double f9Cooldown = 0.0; - - // Numeric key cooldown values - double k1Cooldown = 0.0; - double k2Cooldown = 0.0; - double k3Cooldown = 0.0; - double k4Cooldown = 0.0; - double k5Cooldown = 0.0; - - double timeDiff = 0.0; - bool running = true; - - // Activate mouse capture as default - m_window->toggleMouseCapture(); - - do - { - double startTime = glfwGetTime(); - - // Cooldown calculations - f1Cooldown -= timeDiff; - f2Cooldown -= timeDiff; - f3Cooldown -= timeDiff; - f4Cooldown -= timeDiff; - f5Cooldown -= timeDiff; - f6Cooldown -= timeDiff; - f7Cooldown -= timeDiff; - f8Cooldown -= timeDiff; - f9Cooldown -= timeDiff; - - k1Cooldown -= timeDiff; - k2Cooldown -= timeDiff; - k3Cooldown -= timeDiff; - k4Cooldown -= timeDiff; - k5Cooldown -= timeDiff; - - // Global key mappings - // Key F1 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F1) == GLFW_PRESS && f1Cooldown <= 0.f) - { - f1Cooldown = 0.3f; - // Not implemented - } - - // Key F2 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F2) == GLFW_PRESS && f2Cooldown <= 0.f) - { - f2Cooldown = 0.3f; - // Turns debug overlay on / off - m_graphicsSystem->toggleDebugOverlay(); - } - - // Key F3 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F3) == GLFW_PRESS && f3Cooldown <= 0.f) - { - f3Cooldown = 0.3f; - // Turns wireframe mode on / off - m_graphicsSystem->toggleWireframeMode(); - } - - // Key F4 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F4) == GLFW_PRESS && f4Cooldown <= 0.f) - { - f4Cooldown = 0.3f; - // Toggles global texture filtering between nearest neighbor and bilinear - // TODO Implement - } - - // Key F5 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F5) == GLFW_PRESS && f5Cooldown <= 0.f) - { - f5Cooldown = 0.3f; - // Toggles global texture mip map filtering between off, nearest neighbor - // and bilinear - // TODO Implement - } - - // Key F6 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F6) == GLFW_PRESS && f6Cooldown <= 0.f) - { - f6Cooldown = 0.3f; - // Unused - } - - // Key F7 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F7) == GLFW_PRESS && f7Cooldown <= 0.f) - { - f7Cooldown = 0.3f; - // Unused - } - - // Key F8 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F8) == GLFW_PRESS && f8Cooldown <= 0.f) - { - f8Cooldown = 0.3f; - // Toggles view frustum culling on/off - m_graphicsSystem->toggleViewFrustumCulling(); - } - - // Key F9 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F9) == GLFW_PRESS && f9Cooldown <= 0.f) - { - f9Cooldown = 0.3f; - m_graphicsSystem->toggleDebugOverlayTransparency(); - } - - // Key 1 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_1) == GLFW_PRESS && k1Cooldown <= 0.f) - { - k1Cooldown = 0.3f; - // Turns mouse capture on/off - m_window->toggleMouseCapture(); - } - - // Key 2 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_2) == GLFW_PRESS && k2Cooldown <= 0.f) - { - k2Cooldown = 0.3f; - // Sets active rendering device to deferred renderer - m_graphicsSystem->setActiveRenderer("deferred"); - } - - // Key 3 - if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_3) == GLFW_PRESS && k3Cooldown <= 0.f) - { - k3Cooldown = 0.3f; - // Sets active rendering device to forward renderer - m_graphicsSystem->setActiveRenderer("forward"); - } - - // Game system update - if (!m_gameSystem->update((float)timeDiff)) - { - // On return false quit application - running = false; - } - - // Draw active scene from active camera with active rendering device - m_graphicsSystem->draw(*m_window); - - // Swap buffers after draw - m_window->swapBuffer(); - - // Update input - glfwPollEvents(); - - // Frame time - timeDiff = glfwGetTime() - startTime; - - } while (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_ESCAPE) != GLFW_PRESS && - glfwWindowShouldClose(m_window->getGlfwHandle()) == 0 && running); - - glfwTerminate(); - return; -} - -bool CEngine::initWindow(unsigned int width, unsigned int height, const std::string &title) -{ - // Check if already initialized - if (m_window != nullptr) - { - return true; - } - - LOG_INFO("Initializing application window."); - LOG_INFO("Window width: %u.", width); - LOG_INFO("Window height: %u.", height); - LOG_INFO("Window title: %s.", title.c_str()); - - // Create window - CGlfwWindow *window = new CGlfwWindow; - if (!window->init(width, height, title)) - { - LOG_ERROR("Failed to initialize GLFW window wrapper."); - delete window; - return false; - } - - // Set pointer - m_window.reset(window); - return true; -} - -bool CEngine::initGameSystem(const std::string &gameFile) -{ - // Create and set game system - m_gameSystem = std::make_shared(); - - // TODO Load from game file - m_gameSystem->addState("load", new CLoadState("data/world/load_1.json", 10.f)); - m_gameSystem->addState("title", new CTitleState("data/world/intro_1.json")); - m_gameSystem->addState("game", new CGamePlayState()); - m_gameSystem->addState("lose", new CLoseState("data/world/lose.json")); - m_gameSystem->addState("win", new CWinState("data/world/win.json")); - if (!m_gameSystem->init("load", m_graphicsSystem.get(), m_inputProvider.get(), - m_resourceManager.get())) - { - LOG_ERROR("Failed to initialize game system."); - return false; - } - - return true; -} - -bool CEngine::initDemo(const std::string &sceneFile) -{ - // Create and set game system - m_gameSystem = std::make_shared(); - - // Create demo state from with scene file - m_gameSystem->addState("demo", new CDemoState(sceneFile)); - if (!m_gameSystem->init("demo", m_graphicsSystem.get(), m_inputProvider.get(), - m_resourceManager.get())) - { - LOG_ERROR("Failed to initialize game system."); - return false; - } - return true; -} diff --git a/Demo/CG2015/source/CEngine.h b/Demo/CG2015/source/CEngine.h deleted file mode 100644 index aab918f..0000000 --- a/Demo/CG2015/source/CEngine.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "IEngine.h" -#include "SEngineConfig.h" - -// Resource -class IResourceManager; - -// Game -class CGameSystem; - -// Graphics -class IGraphicsSystem; -class CGlfwWindow; - -// Input -class IInputProvider; - -/** - * \brief Demo application class. - */ -class CEngine : public IEngine -{ - public: - CEngine(); - ~CEngine(); - - /** - * \brief Initialize demo from config file. - */ - bool init(const char *configFile); - - /** - * \brief Run demo. - */ - void run(); - - private: - /** - * \brief Creates and initializes the application window. - */ - bool initWindow(unsigned int width, unsigned int height, const std::string &title); - - /** - * \brief Creates and initializes the game system. - */ - bool initGameSystem(const std::string &gameFile); - - /** - * \brief Creates and initializes game system in demo mode. - * TODO Should be considered legacy and removed later. - */ - bool initDemo(const std::string &sceneFile); - - // Engine configuration - SEngineConfig m_engineConfig; - - // TODO Should use interface instead of concrete class. - std::shared_ptr m_gameSystem; /**< Game system. */ - std::shared_ptr m_graphicsSystem; /**< Graphics system. */ - std::shared_ptr m_resourceManager; /**< Resource loader and manager. */ - - // TODO Should use interface instead of concrete class - std::shared_ptr m_window; /**< Application window. */ - std::shared_ptr m_inputProvider; /**< User input provider. */ -}; diff --git a/Demo/CG2015/source/Engine.cpp b/Demo/CG2015/source/Engine.cpp index ad5ece3..2d2f348 100644 --- a/Demo/CG2015/source/Engine.cpp +++ b/Demo/CG2015/source/Engine.cpp @@ -1,5 +1,337 @@ #include "Engine.h" -#include "CEngine.h" +#define GLFW_INCLUDE_NONE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -IEngine *createEngine() { return new CEngine; } \ No newline at end of file +#include +#include +#include + +#include "FreeFlightCameraController.h" +#include "state/DemoState.h" +#include "state/GamePlayState.h" +#include "state/LoadState.h" +#include "state/LoseState.h" +#include "state/TitleState.h" +#include "state/WinState.h" + +Engine::Engine() {} + +Engine::~Engine() { m_gameSystem = nullptr; } + +bool Engine::init(const char *configFile) +{ + // Load configuration file + if (!load(configFile, m_engineConfig)) + { + logw("Failed to load config file {}. Starting with default settings.", configFile); + // TODO Return if no config exists? + } + + // Sound system + m_soundSystem = std::make_shared("data/audio/"); + + // Create window for rendering + if (!initWindow(m_engineConfig.m_windowWidth, m_engineConfig.m_windowHeight, m_engineConfig.m_windowTitle)) + { + loge("Failed to initialize window."); + return false; + } + + // TODO GLFW handle not properly wrapped away, GFLW should not be used + // directly + m_inputProvider = std::make_shared(m_window->getGlfwHandle()); + + // Create central resource manager + m_resourceManager = std::make_shared(); + if (m_resourceManager == nullptr) + { + loge("Failed to initialize resource manager."); + return false; + } + + // Create and initialize graphics system + m_graphicsSystem = std::make_shared(); + if (!m_graphicsSystem->init(*m_resourceManager)) + { + loge("Failed to initialize graphics system."); + return false; + } + + // Legacy stuff to keep demo mode working + // TODO Should be removed + if (!m_engineConfig.m_sceneFile.empty() && m_engineConfig.m_modeType != "game") + { + if (!initDemo(m_engineConfig.m_sceneFile)) + { + loge("Failed to initialize demo mode."); + return false; + } + } + else if (!m_engineConfig.m_gameFile.empty()) // Create and initialize game system + { + if (!initGameSystem(m_engineConfig.m_gameFile)) + { + loge("Failed to initialize game system."); + return false; + } + } + else + { + loge("No scene file or game file specified"); + return false; + } + return true; +} + +void Engine::run() +{ + // Fn key cooldown values + double f1Cooldown = 0.0; + double f2Cooldown = 0.0; + double f3Cooldown = 0.0; + double f4Cooldown = 0.0; + double f5Cooldown = 0.0; + double f6Cooldown = 0.0; + double f7Cooldown = 0.0; + double f8Cooldown = 0.0; + double f9Cooldown = 0.0; + + // Numeric key cooldown values + double k1Cooldown = 0.0; + double k2Cooldown = 0.0; + double k3Cooldown = 0.0; + double k4Cooldown = 0.0; + double k5Cooldown = 0.0; + + double timeDiff = 0.0; + bool running = true; + + // Activate mouse capture as default + m_window->toggleMouseCapture(); + + do + { + double startTime = glfwGetTime(); + + // Cooldown calculations + f1Cooldown -= timeDiff; + f2Cooldown -= timeDiff; + f3Cooldown -= timeDiff; + f4Cooldown -= timeDiff; + f5Cooldown -= timeDiff; + f6Cooldown -= timeDiff; + f7Cooldown -= timeDiff; + f8Cooldown -= timeDiff; + f9Cooldown -= timeDiff; + + k1Cooldown -= timeDiff; + k2Cooldown -= timeDiff; + k3Cooldown -= timeDiff; + k4Cooldown -= timeDiff; + k5Cooldown -= timeDiff; + + // Global key mappings + // Key F1 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F1) == GLFW_PRESS && f1Cooldown <= 0.f) + { + f1Cooldown = 0.3f; + // Not implemented + } + + // Key F2 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F2) == GLFW_PRESS && f2Cooldown <= 0.f) + { + f2Cooldown = 0.3f; + // Turns debug overlay on / off + m_graphicsSystem->toggleDebugOverlay(); + } + + // Key F3 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F3) == GLFW_PRESS && f3Cooldown <= 0.f) + { + f3Cooldown = 0.3f; + // Turns wireframe mode on / off + m_graphicsSystem->toggleWireframeMode(); + } + + // Key F4 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F4) == GLFW_PRESS && f4Cooldown <= 0.f) + { + f4Cooldown = 0.3f; + // Toggles global texture filtering between nearest neighbor and bilinear + // TODO Implement + } + + // Key F5 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F5) == GLFW_PRESS && f5Cooldown <= 0.f) + { + f5Cooldown = 0.3f; + // Toggles global texture mip map filtering between off, nearest neighbor + // and bilinear + // TODO Implement + } + + // Key F6 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F6) == GLFW_PRESS && f6Cooldown <= 0.f) + { + f6Cooldown = 0.3f; + // Unused + } + + // Key F7 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F7) == GLFW_PRESS && f7Cooldown <= 0.f) + { + f7Cooldown = 0.3f; + // Unused + } + + // Key F8 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F8) == GLFW_PRESS && f8Cooldown <= 0.f) + { + f8Cooldown = 0.3f; + // Toggles view frustum culling on/off + m_graphicsSystem->toggleViewFrustumCulling(); + } + + // Key F9 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_F9) == GLFW_PRESS && f9Cooldown <= 0.f) + { + f9Cooldown = 0.3f; + m_graphicsSystem->toggleDebugOverlayTransparency(); + } + + // Key 1 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_1) == GLFW_PRESS && k1Cooldown <= 0.f) + { + k1Cooldown = 0.3f; + // Turns mouse capture on/off + m_window->toggleMouseCapture(); + } + + // Key 2 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_2) == GLFW_PRESS && k2Cooldown <= 0.f) + { + k2Cooldown = 0.3f; + // Sets active rendering device to deferred renderer + m_graphicsSystem->setActiveRenderer("deferred"); + } + + // Key 3 + if (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_3) == GLFW_PRESS && k3Cooldown <= 0.f) + { + k3Cooldown = 0.3f; + // Sets active rendering device to forward renderer + m_graphicsSystem->setActiveRenderer("forward"); + } + + // Game system update + if (!m_gameSystem->update((float)timeDiff)) + { + // On return false quit application + running = false; + } + + // Sound update + m_soundSystem->update(timeDiff); + + // Draw active scene from active camera with active rendering device + m_graphicsSystem->draw(*m_window); + + // Swap buffers after draw + m_window->swapBuffer(); + + // Update input + glfwPollEvents(); + + // Frame time + timeDiff = glfwGetTime() - startTime; + + } while (glfwGetKey(m_window->getGlfwHandle(), GLFW_KEY_ESCAPE) != GLFW_PRESS && + glfwWindowShouldClose(m_window->getGlfwHandle()) == 0 && running); + + glfwTerminate(); + return; +} + +bool Engine::initWindow(unsigned int width, unsigned int height, const std::string &title) +{ + // Check if already initialized + if (m_window != nullptr) + { + return true; + } + + logi("Initializing application window."); + logi("Window width: {}.", width); + logi("Window height: {}.", height); + logi("Window title: {}.", title.c_str()); + + // Create window + Window *window = new Window; + if (!window->init(width, height, title)) + { + loge("Failed to initialize GLFW window wrapper."); + delete window; + return false; + } + + // Set pointer + m_window.reset(window); + return true; +} + +bool Engine::initGameSystem(const std::string &gameFile) +{ + // Create and set game system + m_gameSystem = std::make_shared(); + + // TODO Load from game file + m_gameSystem->addState("load", new LoadState("data/world/load_1.json", 10.f)); + m_gameSystem->addState("title", new TitleState("data/world/intro_1.json")); + m_gameSystem->addState("game", new GamePlayState()); + m_gameSystem->addState("lose", new LoseState("data/world/lose.json")); + m_gameSystem->addState("win", new WinState("data/world/win.json")); + if (!m_gameSystem->init("load", m_graphicsSystem.get(), m_inputProvider.get(), m_resourceManager.get(), + m_soundSystem.get())) + { + loge("Failed to initialize game system."); + return false; + } + + return true; +} + +bool Engine::initDemo(const std::string &sceneFile) +{ + // Create and set game system + m_gameSystem = std::make_shared(); + + // Create demo state from with scene file + m_gameSystem->addState("demo", new DemoState(sceneFile)); + if (!m_gameSystem->init("demo", m_graphicsSystem.get(), m_inputProvider.get(), m_resourceManager.get(), + m_soundSystem.get())) + { + loge("Failed to initialize game system."); + return false; + } + return true; +} diff --git a/Demo/CG2015/source/Engine.h b/Demo/CG2015/source/Engine.h index 00468cb..0eb6d1e 100644 --- a/Demo/CG2015/source/Engine.h +++ b/Demo/CG2015/source/Engine.h @@ -1,5 +1,71 @@ #pragma once -#include "IEngine.h" +#include +#include +#include -IEngine *createEngine(); \ No newline at end of file +#include "EngineConfig.h" + +// Resource +class IResourceManager; + +// Game +class GameSystem; + +// Graphics +class IGraphicsSystem; +class Window; + +// Input +class IInputProvider; +class SoundSystem; + +/** + * \brief Demo application class. + */ +class Engine +{ + public: + Engine(); + ~Engine(); + + /** + * \brief Initialize demo from config file. + */ + bool init(const char *configFile); + + /** + * \brief Run demo. + */ + void run(); + + private: + /** + * \brief Creates and initializes the application window. + */ + bool initWindow(unsigned int width, unsigned int height, const std::string &title); + + /** + * \brief Creates and initializes the game system. + */ + bool initGameSystem(const std::string &gameFile); + + /** + * \brief Creates and initializes game system in demo mode. + * TODO Should be considered legacy and removed later. + */ + bool initDemo(const std::string &sceneFile); + + // Engine configuration + EngineConfig m_engineConfig; + + // TODO Should use interface instead of concrete class. + std::shared_ptr m_gameSystem; /**< Game system. */ + std::shared_ptr m_graphicsSystem; /**< Graphics system. */ + std::shared_ptr m_resourceManager; /**< Resource loader and manager. */ + + // TODO Should use interface instead of concrete class + std::shared_ptr m_window; /**< Application window. */ + std::shared_ptr m_inputProvider; /**< User input provider. */ + std::shared_ptr m_soundSystem; +}; diff --git a/Demo/CG2015/source/SEngineConfig.cpp b/Demo/CG2015/source/EngineConfig.cpp similarity index 68% rename from Demo/CG2015/source/SEngineConfig.cpp rename to Demo/CG2015/source/EngineConfig.cpp index fb56f8d..d53fee1 100644 --- a/Demo/CG2015/source/SEngineConfig.cpp +++ b/Demo/CG2015/source/EngineConfig.cpp @@ -1,15 +1,15 @@ -#include "SEngineConfig.h" +#include "EngineConfig.h" -#include -#include -#include -#include +#include +#include +#include +#include -bool load(const std::string& configFile, SEngineConfig& config) +bool load(const std::string& configFile, EngineConfig& config) { // Config data with default values - config.m_modeType = "demo"; // Startup mode for the application - config.m_sceneFile = "data/world/test_1.json"; // Scene file to load and render if mode is demo + config.m_modeType = "demo"; // Startup mode for the application + config.m_sceneFile = "data/world/test_1.json"; // Scene file to load and render if mode is demo config.m_gameFile = "data/game/defenders_of_cthedra/game.json"; // Game file to load if mode // is game config.m_rendererType = "deferred"; // Renderer type to use @@ -23,14 +23,13 @@ bool load(const std::string& configFile, SEngineConfig& config) bool loadSuccess = false; if (getFileExtension(configFile) == "ini") { - CIniFile configIni; + IniFile configIni; if (configIni.load(configFile)) { // Load values config.m_modeType = configIni.getValue("mode", "type", "demo"); config.m_sceneFile = configIni.getValue("scene", "file", "data/world/test_1.json"); - config.m_gameFile = - configIni.getValue("game", "file", "data/game/defenders_of_cthedra/game.json"); + config.m_gameFile = configIni.getValue("game", "file", "data/game/defenders_of_cthedra/game.json"); config.m_rendererType = configIni.getValue("renderer", "type", "forward"); config.m_windowWidth = configIni.getValue("window", "width", 800); config.m_windowHeight = configIni.getValue("window", "height", 600); @@ -40,13 +39,13 @@ bool load(const std::string& configFile, SEngineConfig& config) } else if (getFileExtension(configFile) == "json") { - Json::Value root; + nlohmann::json root; if (load(configFile, root)) { // Sub nodes - Json::Value game = root["game"]; - Json::Value renderer = root["renderer"]; - Json::Value window = root["window"]; + nlohmann::json game = root["game"]; + nlohmann::json renderer = root["renderer"]; + nlohmann::json window = root["window"]; // Load values config.m_modeType = "game"; // Json only supports game mode @@ -61,7 +60,7 @@ bool load(const std::string& configFile, SEngineConfig& config) } else { - KERN_WARNING("The config file " << configFile << " has an unknown file extension."); + logw("The config file {} has an unknown file extension.", configFile); } return loadSuccess; } \ No newline at end of file diff --git a/Demo/CG2015/source/SEngineConfig.h b/Demo/CG2015/source/EngineConfig.h similarity index 79% rename from Demo/CG2015/source/SEngineConfig.h rename to Demo/CG2015/source/EngineConfig.h index f705727..d4adf6c 100644 --- a/Demo/CG2015/source/SEngineConfig.h +++ b/Demo/CG2015/source/EngineConfig.h @@ -2,7 +2,7 @@ #include -struct SEngineConfig +struct EngineConfig { std::string m_modeType = "demo"; std::string m_sceneFile; @@ -13,4 +13,4 @@ struct SEngineConfig std::string m_windowTitle = "CG 2015"; }; -bool load(const std::string& file, SEngineConfig& config); \ No newline at end of file +bool load(const std::string& file, EngineConfig& config); \ No newline at end of file diff --git a/Demo/CG2015/source/CFreeFlightCameraController.cpp b/Demo/CG2015/source/FreeFlightCameraController.cpp similarity index 75% rename from Demo/CG2015/source/CFreeFlightCameraController.cpp rename to Demo/CG2015/source/FreeFlightCameraController.cpp index 804a1e3..02cff30 100644 --- a/Demo/CG2015/source/CFreeFlightCameraController.cpp +++ b/Demo/CG2015/source/FreeFlightCameraController.cpp @@ -1,22 +1,21 @@ -#include "CFreeFlightCameraController.h" +#include "FreeFlightCameraController.h" #include #include +#define GLFW_INCLUDE_NONE #include -#include +#include +#include +#include +#include +#include -#include -#include -#include +#include -#include "graphics/graphics/camera/IControllableCamera.h" +FreeFlightCameraController::FreeFlightCameraController() {} -#include "graphics/input/IInputProvider.h" - -CFreeFlightCameraController::CFreeFlightCameraController() {} - -CFreeFlightCameraController::~CFreeFlightCameraController() +FreeFlightCameraController::~FreeFlightCameraController() { if (m_inputProvider != nullptr) { @@ -24,12 +23,9 @@ CFreeFlightCameraController::~CFreeFlightCameraController() } } -void CFreeFlightCameraController::setCamera(std::shared_ptr camera) -{ - m_camera = camera; -} +void FreeFlightCameraController::setCamera(std::shared_ptr camera) { m_camera = camera; } -void CFreeFlightCameraController::setInputProvider(IInputProvider *provider) +void FreeFlightCameraController::setInputProvider(IInputProvider *provider) { if (m_inputProvider != nullptr) { @@ -44,45 +40,25 @@ void CFreeFlightCameraController::setInputProvider(IInputProvider *provider) } } -bool CFreeFlightCameraController::loadSequence(std::string file) +bool FreeFlightCameraController::loadSequence(const std::string &file) { m_sequenceTime = 0; m_sequencePoints.clear(); - Json::Reader reader; - Json::Value root; - - // Load scene file - std::ifstream ifs(file); - if (!ifs.is_open()) - { - LOG_ERROR("Failed to open json file %s.", file.c_str()); - return false; - } - - // Parse json data - if (!reader.parse(ifs, root)) - { - LOG_ERROR("Failed to load scene file %s with error %s.", file.c_str(), - reader.getFormattedErrorMessages().c_str()); - return false; - } - // Read done, close file - ifs.close(); - - Json::Value node = root["positions"]; + nlohmann::json root = nlohmann::json::parse(file); + nlohmann::json node = root["positions"]; // Node empty? if (node.empty()) { - LOG_INFO("Missing or empty 'positions' node. No scene objects are loaded."); + logi("Missing or empty 'positions' node. No scene objects are loaded."); return true; } // Node is array type - if (!node.isArray()) + if (!node.is_array()) { - LOG_ERROR("The node 'positions' must be array type."); + loge("The node 'positions' must be array type."); return false; } @@ -98,35 +74,35 @@ bool CFreeFlightCameraController::loadSequence(std::string file) if (!load(node[i], "position", position)) { - LOG_ERROR("Failed loading node 'position' for element #%i.", i); + loge("Failed loading node 'position' for element #{}.", i); success = false; break; } if (!load(node[i], "orientation", orientation)) { - LOG_ERROR("Failed loading node 'orientation' for element #%i.", i); + loge("Failed loading node 'orientation' for element #{}.", i); success = false; break; } if (!load(node[i], "timestamp", timestamp)) { - LOG_ERROR("Failed loading node 'timestamp' for element #%i.", i); + loge("Failed loading node 'timestamp' for element #{}.", i); success = false; break; } if (!load(node[i], "fxaa", fxaaActive)) { - LOG_ERROR("Failed loading node 'fxaa' for element #%i.", i); + loge("Failed loading node 'fxaa' for element #{}.", i); success = false; break; } if (!load(node[i], "fog", fogActive)) { - LOG_ERROR("Failed loading node 'fog' for element #%i.", i); + loge("Failed loading node 'fog' for element #{}.", i); success = false; break; } @@ -139,7 +115,7 @@ bool CFreeFlightCameraController::loadSequence(std::string file) return success; } -void CFreeFlightCameraController::animate(float dt) +void FreeFlightCameraController::animate(float dt) { if (m_inputProvider != nullptr && m_camera != nullptr) { @@ -156,12 +132,12 @@ void CFreeFlightCameraController::animate(float dt) } } -void CFreeFlightCameraController::animateFeatures(float dt) +void FreeFlightCameraController::animateFeatures(float dt) { // tODO } -void CFreeFlightCameraController::animateSequence(float dt) +void FreeFlightCameraController::animateSequence(float dt) { if (m_inputProvider->isKeyPressed(GLFW_KEY_C)) { @@ -212,7 +188,7 @@ void CFreeFlightCameraController::animateSequence(float dt) m_camera->getFeatureInfoForWrite().fxaaActive = before.fxaaActive; } -void CFreeFlightCameraController::animateManual(float dt) +void FreeFlightCameraController::animateManual(float dt) { float walkingModifier = 1.0f; if (m_inputProvider->isKeyPressed(GLFW_KEY_SPACE)) @@ -267,7 +243,7 @@ void CFreeFlightCameraController::animateManual(float dt) } } -void CFreeFlightCameraController::handleKeyEvent(EKeyEventType type, int keyCode) +void FreeFlightCameraController::handleKeyEvent(EKeyEventType type, int keyCode) { if (type != EKeyEventType::KEY_PRESSED) { @@ -352,7 +328,7 @@ void CFreeFlightCameraController::handleKeyEvent(EKeyEventType type, int keyCode } } -void CFreeFlightCameraController::handleMouseMovementEvent(int x, int y) +void FreeFlightCameraController::handleMouseMovementEvent(int x, int y) { m_camera->pitch((y - m_lastY) * m_speed / 1000); m_camera->yaw(-(x - m_lastX) * m_speed / 1000); @@ -361,12 +337,12 @@ void CFreeFlightCameraController::handleMouseMovementEvent(int x, int y) m_lastY = y; } -void CFreeFlightCameraController::handleMouseButtonEvent(EMouseButtonEventType type, int buttonCode) +void FreeFlightCameraController::handleMouseButtonEvent(EMouseButtonEventType type, int buttonCode) { // TODO } -void CFreeFlightCameraController::handleResizeEvent(int width, int height) +void FreeFlightCameraController::handleResizeEvent(int width, int height) { m_camera->setProjection(m_camera->getFieldOfView(), (float)width / height, m_camera->getZNear(), m_camera->getZFar()); diff --git a/Demo/CG2015/source/CFreeFlightCameraController.h b/Demo/CG2015/source/FreeFlightCameraController.h similarity index 80% rename from Demo/CG2015/source/CFreeFlightCameraController.h rename to Demo/CG2015/source/FreeFlightCameraController.h index 851ac3a..7a0abba 100644 --- a/Demo/CG2015/source/CFreeFlightCameraController.h +++ b/Demo/CG2015/source/FreeFlightCameraController.h @@ -5,23 +5,23 @@ #include -#include "graphics/graphics/window/CGlfwWindow.h" +#include "kern/graphics/Window.h" -#include "graphics/input/IInputListener.h" +#include "kern/graphics/input/IInputListener.h" class IControllableCamera; class IInputProvider; -class CFreeFlightCameraController : public IInputListener, public IGlfwWindowListener +class FreeFlightCameraController : public IInputListener, public IWindowListener { public: - CFreeFlightCameraController(); - ~CFreeFlightCameraController(); + FreeFlightCameraController(); + ~FreeFlightCameraController(); void setCamera(std::shared_ptr camera); void setInputProvider(IInputProvider *provider); - bool loadSequence(std::string file); + bool loadSequence(const std::string& file); void animate(float dt); diff --git a/Demo/CG2015/source/IEngine.cpp b/Demo/CG2015/source/IEngine.cpp deleted file mode 100644 index f40c653..0000000 --- a/Demo/CG2015/source/IEngine.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "IEngine.h" - -IEngine::~IEngine() { return; } \ No newline at end of file diff --git a/Demo/CG2015/source/IEngine.h b/Demo/CG2015/source/IEngine.h deleted file mode 100644 index 01c26ec..0000000 --- a/Demo/CG2015/source/IEngine.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -/** - * \brief Game engine interface. - */ -class IEngine -{ - public: - /** - * \brief Virtual destructor for interface class. - */ - virtual ~IEngine(); - - /** - * \brief Initializes engine and subsystems. - * \parm config Config file name containing initialization parameters. - * \return True on success and false on error. - */ - virtual bool init(const char *configFile) = 0; - - /** - * \brief Starts game loop. - * - * The function returns after the game loop ends. - */ - virtual void run() = 0; -}; diff --git a/Demo/CG2015/source/Main.cpp b/Demo/CG2015/source/Main.cpp index 7ff065f..51fb3b4 100644 --- a/Demo/CG2015/source/Main.cpp +++ b/Demo/CG2015/source/Main.cpp @@ -1,20 +1,32 @@ -#include +#include #include "Engine.h" -int main(int argc, const char **argv) +int main(int argc, const char** argv) { - // Create engine interface - std::unique_ptr engine(createEngine()); +#ifndef NDEBUG + fmtlog::setLogLevel(fmtlog::DBG); +#endif + fmtlog::startPollingThread(); - // TODO Parse program arguments + try + { + // Create engine interface + Engine engine; + + // Initialize from config file + if (!engine.init("data/startup.ini")) + { + return EXIT_FAILURE; + } + // Run engine + engine.run(); - // Initialize from config file - if (!engine->init("data/startup.ini")) + return EXIT_SUCCESS; + } + catch (const std::exception& e) { - return 1; + loge("{}", e.what()); + return EXIT_FAILURE; } - // Run engine - engine->run(); - return 0; } diff --git a/Demo/CG2015/source/control/CHealthController.cpp b/Demo/CG2015/source/control/CHealthController.cpp deleted file mode 100644 index dae13e4..0000000 --- a/Demo/CG2015/source/control/CHealthController.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "control/CHealthController.h" - -#include "application/game/CGameObject.h" -#include "graphics/collision/CCollidable.h" - -CHealthController::CHealthController(float health) : m_health(health), m_active(true) { return; } - -CHealthController::~CHealthController() { return; } - -void CHealthController::attach(CGameObject *object) { m_object = object; } - -void CHealthController::detach() { m_object = nullptr; } - -void CHealthController::update(float dtime) -{ - if (m_active && m_object != nullptr && m_object->hasCollidable()) - { - // Set health - m_health -= m_object->getCollidable()->getDamageReceived(); - if (m_health <= 0.f) - { - // Set object into death state - m_object->setDead(); - } - } -} - -void CHealthController::setActive(bool state) { m_active = state; } - -void CHealthController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CLinearMovementController.cpp b/Demo/CG2015/source/control/CLinearMovementController.cpp deleted file mode 100644 index bc40205..0000000 --- a/Demo/CG2015/source/control/CLinearMovementController.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "control/CLinearMovementController.h" - -#include - -#include "application/game/CGameObject.h" - -CLinearMovementController::CLinearMovementController(const glm::vec3 &direction, float speed) - : m_direction(direction), m_speed(speed) -{ - return; -} - -CLinearMovementController::~CLinearMovementController() {} - -void CLinearMovementController::attach(CGameObject *object) { m_object = object; } - -void CLinearMovementController::detach() { m_object = nullptr; } - -void CLinearMovementController::update(float dtime) -{ - if (m_active && m_object != nullptr) - { - m_object->setPosition(m_object->getPosition() + m_direction * m_speed * dtime); - } -} - -void CLinearMovementController::setActive(bool state) { m_active = state; } - -void CLinearMovementController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CRemoveOnDeathController.cpp b/Demo/CG2015/source/control/CRemoveOnDeathController.cpp deleted file mode 100644 index 4e65dab..0000000 --- a/Demo/CG2015/source/control/CRemoveOnDeathController.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "control/CRemoveOnDeathController.h" - -#include "application/game/CGameObject.h" -#include "state/CGamePlayState.h" - -CRemoveOnDeathController::CRemoveOnDeathController(CGamePlayState *state) - : m_object(nullptr), m_gameState(state), m_active(true) -{ - return; -} - -CRemoveOnDeathController::~CRemoveOnDeathController() { return; } - -void CRemoveOnDeathController::attach(CGameObject *object) { m_object = object; } - -void CRemoveOnDeathController::detach() { m_object = nullptr; } - -void CRemoveOnDeathController::update(float dtime) -{ - if (m_object != nullptr && m_active && m_object->isDead()) - { - // Mark for deletion - m_gameState->winCount(); - m_object->markDeleted(); - } -} - -void CRemoveOnDeathController::setActive(bool state) { m_active = state; } - -void CRemoveOnDeathController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CWeaponController.cpp b/Demo/CG2015/source/control/CWeaponController.cpp deleted file mode 100644 index 6dd99a4..0000000 --- a/Demo/CG2015/source/control/CWeaponController.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "control/CWeaponController.h" - -#include - -#include "application/game/CGameObject.h" -#include "control/CLinearMovementController.h" - -#include - -CWeaponController::CWeaponController(IInputProvider *provider, CGameWorld *gameWorld, IScene *scene, - ResourceId mesh, ResourceId material, - IResourceManager *resourceManager, - CCollisionSystem *collisionSystem, int collisionGroup) - : m_collisionGroup(collisionGroup), - m_collisionSystem(collisionSystem), - m_resourceManager(resourceManager), - m_inputProvider(provider), - m_gameWorld(gameWorld), - m_scene(scene), - m_mesh(mesh), - m_material(material) -{ - return; -} - -CWeaponController::~CWeaponController() {} - -void CWeaponController::attach(CGameObject *object) { m_object = object; } - -void CWeaponController::detach() { m_object = nullptr; } - -void CWeaponController::update(float dtime) -{ - if (m_active && m_object != nullptr) - { - m_weaponCooldown -= dtime; - // Check for space key - if (m_inputProvider->isKeyPressed(GLFW_KEY_SPACE) && m_weaponCooldown <= 0.f) - { - // Reset cooldown - m_weaponCooldown = 0.3f; - - glm::vec3 direction = m_object->getForward(); - glm::vec3 position = m_object->getPosition(); - - // Create game object - CGameObject *bullet = new CGameObject; - bullet->addController(std::make_shared(direction, 50.f)); - bullet->setPosition(position + direction * 2.f); - bullet->setRotation(m_object->getRotation()); - - // Bullet colidable - std::vector bulletVertices; - std::vector bulletIndices; - std::vector bulletNormals; - std::vector bulletUvs; - EPrimitiveType bulletType; - m_resourceManager->getMesh(m_mesh, bulletVertices, bulletIndices, bulletNormals, - bulletUvs, bulletType); - bullet->setCollidable( - m_collisionSystem->add(CAABBox::create(bulletVertices), m_collisionGroup)); - bullet->getCollidable()->setDamage(50.f); - - // Create scene proxy - CSceneObjectProxy *proxy = new CSceneObjectProxy( - m_scene, m_scene->createObject(m_mesh, m_material, glm::vec3(0.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(1.f))); - bullet->setSceneObject(proxy); - - // Add to world - m_gameWorld->addObject(bullet); - } - } -} - -void CWeaponController::setActive(bool state) { m_active = state; } - -void CWeaponController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CWeaponController.h b/Demo/CG2015/source/control/CWeaponController.h deleted file mode 100644 index c149831..0000000 --- a/Demo/CG2015/source/control/CWeaponController.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "graphics/graphics/IScene.h" -#include "graphics/input/IInputProvider.h" -#include "graphics/resource/IResourceManager.h" - -// Collision -#include "graphics/collision/CCollidable.h" -#include "graphics/collision/CCollisionSystem.h" - -#include "application/game/CGameWorld.h" -#include "application/game/IController.h" -#include "application/game/Message.h" - -/** - * \brief Controls weapons, creates projectiles. - */ -class CWeaponController : public IController -{ - public: - CWeaponController(IInputProvider *provider, CGameWorld *gameWorld, IScene *scene, - ResourceId mesh, ResourceId material, IResourceManager *resourceManager, - CCollisionSystem *collisionSystem, int collisionGroup); - ~CWeaponController(); - - void attach(CGameObject *object); - void detach(); - void update(float dtime); - void setActive(bool state); - void receiveMessage(Message msg); - - private: - CGameObject *m_object = nullptr; /**< Controlled game object. */ - bool m_active = true; /**< Active state flag. */ - IInputProvider *m_inputProvider = nullptr; - float m_weaponCooldown = 0.f; - CGameWorld *m_gameWorld = nullptr; - IResourceManager *m_resourceManager = nullptr; - IScene *m_scene = nullptr; - ResourceId m_mesh = invalidResource; - ResourceId m_material = invalidResource; - CCollisionSystem *m_collisionSystem = nullptr; - - unsigned int m_collisionGroup; /**< Player collision group. */ -}; \ No newline at end of file diff --git a/Demo/CG2015/source/control/CCameraController.cpp b/Demo/CG2015/source/control/CameraController.cpp similarity index 69% rename from Demo/CG2015/source/control/CCameraController.cpp rename to Demo/CG2015/source/control/CameraController.cpp index a2758a5..4aa606f 100644 --- a/Demo/CG2015/source/control/CCameraController.cpp +++ b/Demo/CG2015/source/control/CameraController.cpp @@ -1,20 +1,20 @@ -#include "control/CCameraController.h" +#include "control/CameraController.h" -#include "application/game/CGameObject.h" +#include "kern/game/GameObject.h" -CCameraController::CCameraController(IControllableCamera *camera) : m_camera(camera) { return; } +CameraController::CameraController(IControllableCamera *camera) : m_camera(camera) { return; } -CCameraController::~CCameraController() {} +CameraController::~CameraController() {} -void CCameraController::attach(CGameObject *object) { m_object = object; } +void CameraController::attach(GameObject *object) { m_object = object; } -void CCameraController::detach() +void CameraController::detach() { m_object = nullptr; m_camera = nullptr; } -void CCameraController::update(float dtime) +void CameraController::update(float dtime) { if (m_active && m_object != nullptr && m_camera != nullptr) { @@ -23,7 +23,7 @@ void CCameraController::update(float dtime) glm::vec3 forward = m_object->getForward(); // Where the camera should be - glm::vec3 camPos(pos.x - forward.x * 8.f, pos.y * 0.95f + 3.f, pos.z - forward.z * 8.f); + glm::vec3 camPos(pos.x - forward.x * 8.f, pos.y * 0.95f + 5.f, pos.z - forward.z * 8.f); m_camera->setPosition(camPos); // Init on first update @@ -60,6 +60,6 @@ void CCameraController::update(float dtime) } } -void CCameraController::setActive(bool state) { m_active = state; } +void CameraController::setActive(bool state) { m_active = state; } -void CCameraController::receiveMessage(Message msg) {} \ No newline at end of file +void CameraController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CCameraController.h b/Demo/CG2015/source/control/CameraController.h similarity index 69% rename from Demo/CG2015/source/control/CCameraController.h rename to Demo/CG2015/source/control/CameraController.h index d569000..31bcdd4 100644 --- a/Demo/CG2015/source/control/CCameraController.h +++ b/Demo/CG2015/source/control/CameraController.h @@ -2,31 +2,31 @@ #include -#include "application/game/IController.h" -#include "application/game/Message.h" +#include "kern/game/IGameObjectController.h" +#include "kern/game/Message.h" -#include "graphics/graphics/camera/IControllableCamera.h" +#include "kern/graphics/camera/IControllableCamera.h" /** * \brief Controls camera movement based on the attached game object. */ -class CCameraController : public IController +class CameraController : public IGameObjectController { public: /** * \brief Sets camera. */ - CCameraController(IControllableCamera *camera); + CameraController(IControllableCamera *camera); /** * \brief Destructor for cleanup. */ - ~CCameraController(); + ~CameraController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On detaching from game object. @@ -50,7 +50,7 @@ class CCameraController : public IController private: IControllableCamera *m_camera = nullptr; /**< Controlled camera. */ - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ bool m_active = true; /**< Active state flag. */ glm::vec3 m_prevLookAt; bool m_first = true; diff --git a/Demo/CG2015/source/control/HealthController.cpp b/Demo/CG2015/source/control/HealthController.cpp new file mode 100644 index 0000000..55abd21 --- /dev/null +++ b/Demo/CG2015/source/control/HealthController.cpp @@ -0,0 +1,30 @@ +#include "control/HealthController.h" + +#include +#include + +HealthController::HealthController(float health) : m_health(health), m_active(true) { return; } + +HealthController::~HealthController() { return; } + +void HealthController::attach(GameObject *object) { m_object = object; } + +void HealthController::detach() { m_object = nullptr; } + +void HealthController::update(float dtime) +{ + if (m_active && m_object != nullptr && m_object->hasCollidable()) + { + // Set health + m_health -= m_object->getCollidable()->getDamageReceived(); + if (m_health <= 0.f) + { + // Set object into death state + m_object->setDead(); + } + } +} + +void HealthController::setActive(bool state) { m_active = state; } + +void HealthController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CHealthController.h b/Demo/CG2015/source/control/HealthController.h similarity index 73% rename from Demo/CG2015/source/control/CHealthController.h rename to Demo/CG2015/source/control/HealthController.h index 560d419..773e80b 100644 --- a/Demo/CG2015/source/control/CHealthController.h +++ b/Demo/CG2015/source/control/HealthController.h @@ -1,28 +1,28 @@ #pragma once -#include "application/game/IController.h" +#include "kern/game/IGameObjectController.h" /** * \brief Stores health state and marks object for deletion on death. * TODO This should actually send an onDeath event to the object. */ -class CHealthController : public IController +class HealthController : public IGameObjectController { public: /** * \brief Sets health. */ - CHealthController(float health); + HealthController(float health); /** * \brief Destructor for cleanup. */ - ~CHealthController(); + ~HealthController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On dettaching from game object. @@ -42,7 +42,7 @@ class CHealthController : public IController void receiveMessage(Message msg); private: - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ float m_health; /**< Health value. */ bool m_active; /**< Cative flag. */ }; \ No newline at end of file diff --git a/Demo/CG2015/source/control/LinearMovementController.cpp b/Demo/CG2015/source/control/LinearMovementController.cpp new file mode 100644 index 0000000..8ecf5ea --- /dev/null +++ b/Demo/CG2015/source/control/LinearMovementController.cpp @@ -0,0 +1,30 @@ +#include "control/LinearMovementController.h" + +#define GLFW_INCLUDE_NONE +#include + +#include "kern/game/GameObject.h" + +LinearMovementController::LinearMovementController(const glm::vec3 &direction, float speed) + : m_direction(direction), m_speed(speed) +{ + return; +} + +LinearMovementController::~LinearMovementController() {} + +void LinearMovementController::attach(GameObject *object) { m_object = object; } + +void LinearMovementController::detach() { m_object = nullptr; } + +void LinearMovementController::update(float dtime) +{ + if (m_active && m_object != nullptr) + { + m_object->setPosition(m_object->getPosition() + m_direction * m_speed * dtime); + } +} + +void LinearMovementController::setActive(bool state) { m_active = state; } + +void LinearMovementController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CLinearMovementController.h b/Demo/CG2015/source/control/LinearMovementController.h similarity index 52% rename from Demo/CG2015/source/control/CLinearMovementController.h rename to Demo/CG2015/source/control/LinearMovementController.h index ee17b0f..33de9cb 100644 --- a/Demo/CG2015/source/control/CLinearMovementController.h +++ b/Demo/CG2015/source/control/LinearMovementController.h @@ -2,26 +2,26 @@ #include -#include "application/game/IController.h" -#include "application/game/Message.h" +#include "kern/game/IGameObjectController.h" +#include "kern/game/Message.h" /** * \brief Controls object to move a linear path. */ -class CLinearMovementController : public IController +class LinearMovementController : public IGameObjectController { public: - CLinearMovementController(const glm::vec3 &direction, float speed); - ~CLinearMovementController(); + LinearMovementController(const glm::vec3 &direction, float speed); + ~LinearMovementController(); - void attach(CGameObject *object); + void attach(GameObject *object); void detach(); void update(float dtime); void setActive(bool state); void receiveMessage(Message msg); private: - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ bool m_active = true; /**< Active state flag. */ glm::vec3 m_direction = glm::vec3(0.f); diff --git a/Demo/CG2015/source/control/CPlayerMovementController.cpp b/Demo/CG2015/source/control/PlayerMovementController.cpp similarity index 68% rename from Demo/CG2015/source/control/CPlayerMovementController.cpp rename to Demo/CG2015/source/control/PlayerMovementController.cpp index e932e4a..1c77d5b 100644 --- a/Demo/CG2015/source/control/CPlayerMovementController.cpp +++ b/Demo/CG2015/source/control/PlayerMovementController.cpp @@ -1,32 +1,33 @@ -#include "control/CPlayerMovementController.h" +#include "control/PlayerMovementController.h" +#define GLFW_INCLUDE_NONE #include #include -#include -#include +#include "kern/foundation/TransformUtils.h" +#include "kern/graphics/input/IInputProvider.h" -#include "application/game/CGameObject.h" +#include "kern/game/GameObject.h" -CPlayerMovementController::CPlayerMovementController(IInputProvider *inputProvider, float speed) +PlayerMovementController::PlayerMovementController(IInputProvider *inputProvider, float speed) : m_inputProvider(inputProvider), m_speed(speed) { return; } -CPlayerMovementController::~CPlayerMovementController() { return; } +PlayerMovementController::~PlayerMovementController() { return; } -void CPlayerMovementController::attach(CGameObject *object) { m_object = object; } +void PlayerMovementController::attach(GameObject *object) { m_object = object; } -void CPlayerMovementController::detach() +void PlayerMovementController::detach() { m_object = nullptr; m_rotationDegree = 0.f; } -void CPlayerMovementController::setActive(bool state) { m_active = state; } +void PlayerMovementController::setActive(bool state) { m_active = state; } -void CPlayerMovementController::update(float dtime) +void PlayerMovementController::update(float dtime) { if (m_active && m_object != nullptr) { @@ -82,4 +83,4 @@ void CPlayerMovementController::update(float dtime) } } -void CPlayerMovementController::receiveMessage(Message msg) {} +void PlayerMovementController::receiveMessage(Message msg) {} diff --git a/Demo/CG2015/source/control/CPlayerMovementController.h b/Demo/CG2015/source/control/PlayerMovementController.h similarity index 67% rename from Demo/CG2015/source/control/CPlayerMovementController.h rename to Demo/CG2015/source/control/PlayerMovementController.h index b9c8498..33af7ca 100644 --- a/Demo/CG2015/source/control/CPlayerMovementController.h +++ b/Demo/CG2015/source/control/PlayerMovementController.h @@ -2,27 +2,27 @@ #include -#include "application/game/IController.h" -#include "application/game/Message.h" -#include "graphics/input/IInputProvider.h" +#include "kern/game/IGameObjectController.h" +#include "kern/game/Message.h" +#include "kern/graphics/input/IInputProvider.h" /** * \brief Player side movement. */ -class CPlayerMovementController : public IController +class PlayerMovementController : public IGameObjectController { public: - CPlayerMovementController(IInputProvider *inputProvider, float speed); + PlayerMovementController(IInputProvider *inputProvider, float speed); /** * \brief Destructor for cleanup. */ - ~CPlayerMovementController(); + ~PlayerMovementController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On dettaching from game object. @@ -46,7 +46,7 @@ class CPlayerMovementController : public IController private: IInputProvider *m_inputProvider = nullptr; - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ float m_speed = 0.f; /**< Side movement speed. */ float m_rotationDegree = 0.f; /**< Current rotation in degree. */ bool m_active = true; /**< Active state flag. */ diff --git a/Demo/CG2015/source/control/RemoveOnDeathController.cpp b/Demo/CG2015/source/control/RemoveOnDeathController.cpp new file mode 100644 index 0000000..ef8e432 --- /dev/null +++ b/Demo/CG2015/source/control/RemoveOnDeathController.cpp @@ -0,0 +1,31 @@ +#include "control/RemoveOnDeathController.h" + +#include "kern/game/GameObject.h" +#include "state/GamePlayState.h" + +RemoveOnDeathController::RemoveOnDeathController(GamePlayState *state, const std::shared_ptr &emitter) + : m_object(nullptr), m_gameState(state), m_active(true), m_emitter(emitter) +{ + return; +} + +RemoveOnDeathController::~RemoveOnDeathController() { return; } + +void RemoveOnDeathController::attach(GameObject *object) { m_object = object; } + +void RemoveOnDeathController::detach() { m_object = nullptr; } + +void RemoveOnDeathController::update(float dtime) +{ + if (m_object != nullptr && m_active && m_object->isDead()) + { + // Mark for deletion + m_gameState->winCount(); + m_object->markDeleted(); + m_emitter->play(); + } +} + +void RemoveOnDeathController::setActive(bool state) { m_active = state; } + +void RemoveOnDeathController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CRemoveOnDeathController.h b/Demo/CG2015/source/control/RemoveOnDeathController.h similarity index 58% rename from Demo/CG2015/source/control/CRemoveOnDeathController.h rename to Demo/CG2015/source/control/RemoveOnDeathController.h index 51e3c3d..3b3edb6 100644 --- a/Demo/CG2015/source/control/CRemoveOnDeathController.h +++ b/Demo/CG2015/source/control/RemoveOnDeathController.h @@ -2,32 +2,33 @@ #include -#include "application/game/IController.h" +#include +#include -class CGamePlayState; +class GamePlayState; /** * \brief Checks the object state for death state and trigger explosion effect. * TODO This should actually react to an onDeath event. * TODO This actually can play any sound on death. */ -class CRemoveOnDeathController : public IController +class RemoveOnDeathController : public IGameObjectController { public: /** * \brief Sets sound system and sound name. */ - CRemoveOnDeathController(CGamePlayState *state); + RemoveOnDeathController(GamePlayState *state, const std::shared_ptr& emitter); /** * \brief Destructor for cleanup. */ - ~CRemoveOnDeathController(); + ~RemoveOnDeathController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On detaching from game object. @@ -44,7 +45,8 @@ class CRemoveOnDeathController : public IController void receiveMessage(Message msg); private: - CGameObject *m_object = nullptr; /**< Controlled game object. */ - CGamePlayState *m_gameState = nullptr; + GameObject *m_object = nullptr; /**< Controlled game object. */ + GamePlayState *m_gameState = nullptr; bool m_active = false; + std::shared_ptr m_emitter; }; diff --git a/Demo/CG2015/source/control/CRestrictPositionController.cpp b/Demo/CG2015/source/control/RestrictPositionController.cpp similarity index 63% rename from Demo/CG2015/source/control/CRestrictPositionController.cpp rename to Demo/CG2015/source/control/RestrictPositionController.cpp index aefb0f4..1ffdb88 100644 --- a/Demo/CG2015/source/control/CRestrictPositionController.cpp +++ b/Demo/CG2015/source/control/RestrictPositionController.cpp @@ -1,25 +1,25 @@ -#include "control/CRestrictPositionController.h" +#include "control/RestrictPositionController.h" #include -#include "application/game/CGameObject.h" +#include "kern/game/GameObject.h" -CRestrictPositionController::CRestrictPositionController(const glm::vec2 &minCoords, +RestrictPositionController::RestrictPositionController(const glm::vec2 &minCoords, const glm::vec2 &maxCoords) : m_minCoords(minCoords), m_maxCoords(maxCoords) { return; } -CRestrictPositionController::~CRestrictPositionController() { return; } +RestrictPositionController::~RestrictPositionController() { return; } -void CRestrictPositionController::attach(CGameObject *object) { m_object = object; } +void RestrictPositionController::attach(GameObject *object) { m_object = object; } -void CRestrictPositionController::detach() { m_object = nullptr; } +void RestrictPositionController::detach() { m_object = nullptr; } -void CRestrictPositionController::setActive(bool state) { m_active = state; } +void RestrictPositionController::setActive(bool state) { m_active = state; } -void CRestrictPositionController::update(float dtime) +void RestrictPositionController::update(float dtime) { if (m_active && m_object != nullptr) { @@ -58,7 +58,7 @@ void CRestrictPositionController::update(float dtime) } } -void CRestrictPositionController::receiveMessage(Message msg) +void RestrictPositionController::receiveMessage(Message msg) { // Empty } \ No newline at end of file diff --git a/Demo/CG2015/source/control/CRestrictPositionController.h b/Demo/CG2015/source/control/RestrictPositionController.h similarity index 65% rename from Demo/CG2015/source/control/CRestrictPositionController.h rename to Demo/CG2015/source/control/RestrictPositionController.h index 8db431a..e35d425 100644 --- a/Demo/CG2015/source/control/CRestrictPositionController.h +++ b/Demo/CG2015/source/control/RestrictPositionController.h @@ -2,10 +2,10 @@ #include -#include "application/game/IController.h" -#include "application/game/Message.h" +#include "kern/game/IGameObjectController.h" +#include "kern/game/Message.h" -#include "graphics/input/IInputProvider.h" +#include "kern/graphics/input/IInputProvider.h" /** * \brief Restricts object position in space. @@ -13,20 +13,20 @@ * Restricts x and z coordinates to a plane and reenters an object from the * other side. */ -class CRestrictPositionController : public IController +class RestrictPositionController : public IGameObjectController { public: - CRestrictPositionController(const glm::vec2 &minCoords, const glm::vec2 &maxCoords); + RestrictPositionController(const glm::vec2 &minCoords, const glm::vec2 &maxCoords); /** * \brief Destructor for cleanup. */ - ~CRestrictPositionController(); + ~RestrictPositionController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On dettaching from game object. @@ -49,7 +49,7 @@ class CRestrictPositionController : public IController void receiveMessage(Message msg); private: - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ glm::vec2 m_minCoords; glm::vec2 m_maxCoords; bool m_active = true; /**< Active state flag. */ diff --git a/Demo/CG2015/source/control/CSimpleWaypointController.cpp b/Demo/CG2015/source/control/SimpleWaypointController.cpp similarity index 62% rename from Demo/CG2015/source/control/CSimpleWaypointController.cpp rename to Demo/CG2015/source/control/SimpleWaypointController.cpp index c9a6842..e70f9a6 100644 --- a/Demo/CG2015/source/control/CSimpleWaypointController.cpp +++ b/Demo/CG2015/source/control/SimpleWaypointController.cpp @@ -1,29 +1,30 @@ -#include "control/CSimpleWaypointController.h" +#include "control/SimpleWaypointController.h" +#define GLFW_INCLUDE_NONE #include #include -#include +#include -#include "application/game/AGameState.h" -#include "application/game/CGameObject.h" +#include "kern/game/AGameState.h" +#include "kern/game/GameObject.h" -CSimpleWaypointController::CSimpleWaypointController(const glm::vec3 &end, float speed, +SimpleWaypointController::SimpleWaypointController(const glm::vec3 &end, float speed, AGameState *state) : m_end(end), m_speed(speed), m_gameState(state) { return; } -CSimpleWaypointController::~CSimpleWaypointController() { return; } +SimpleWaypointController::~SimpleWaypointController() { return; } -void CSimpleWaypointController::attach(CGameObject *object) { m_object = object; } +void SimpleWaypointController::attach(GameObject *object) { m_object = object; } -void CSimpleWaypointController::detach() { m_object = nullptr; } +void SimpleWaypointController::detach() { m_object = nullptr; } -void CSimpleWaypointController::setActive(bool state) { m_active = state; } +void SimpleWaypointController::setActive(bool state) { m_active = state; } -void CSimpleWaypointController::update(float dtime) +void SimpleWaypointController::update(float dtime) { glm::vec3 position = m_object->getPosition(); if (m_active && m_object != nullptr) @@ -60,4 +61,4 @@ void CSimpleWaypointController::update(float dtime) } } -void CSimpleWaypointController::receiveMessage(Message msg) {} \ No newline at end of file +void SimpleWaypointController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/CSimpleWaypointController.h b/Demo/CG2015/source/control/SimpleWaypointController.h similarity index 68% rename from Demo/CG2015/source/control/CSimpleWaypointController.h rename to Demo/CG2015/source/control/SimpleWaypointController.h index f228719..a20a45d 100644 --- a/Demo/CG2015/source/control/CSimpleWaypointController.h +++ b/Demo/CG2015/source/control/SimpleWaypointController.h @@ -2,28 +2,28 @@ #include -#include "application/game/IController.h" -#include "application/game/Message.h" +#include "kern/game/IGameObjectController.h" +#include "kern/game/Message.h" class AGameState; /** * \brief Point to point movement. */ -class CSimpleWaypointController : public IController +class SimpleWaypointController : public IGameObjectController { public: - CSimpleWaypointController(const glm::vec3 &end, float speed, AGameState *gameState); + SimpleWaypointController(const glm::vec3 &end, float speed, AGameState *gameState); /** * \brief Destructor for cleanup. */ - ~CSimpleWaypointController(); + ~SimpleWaypointController(); /** * \brief On attach to object. */ - void attach(CGameObject *object); + void attach(GameObject *object); /** * \brief On dettaching from game object. @@ -49,7 +49,7 @@ class CSimpleWaypointController : public IController glm::vec3 m_end; float m_speed = 0.f; /**< Side movement speed. */ AGameState *m_gameState = nullptr; - CGameObject *m_object = nullptr; /**< Controlled game object. */ + GameObject *m_object = nullptr; /**< Controlled game object. */ bool m_active = true; /**< Active state flag. */ float m_idleTimer = 5.f; }; diff --git a/Demo/CG2015/source/control/WeaponController.cpp b/Demo/CG2015/source/control/WeaponController.cpp new file mode 100644 index 0000000..55d8291 --- /dev/null +++ b/Demo/CG2015/source/control/WeaponController.cpp @@ -0,0 +1,81 @@ +#include "control/WeaponController.h" + +#include + +#include + +#include "control/LinearMovementController.h" + +#define GLFW_INCLUDE_NONE +#include + +WeaponController::WeaponController(IInputProvider *provider, GameWorld *gameWorld, IScene *scene, ResourceId mesh, + ResourceId material, IResourceManager *resourceManager, + CollisionSystem *collisionSystem, int collisionGroup, + std::shared_ptr emitter) + : m_collisionGroup(collisionGroup), + m_collisionSystem(collisionSystem), + m_resourceManager(resourceManager), + m_inputProvider(provider), + m_gameWorld(gameWorld), + m_scene(scene), + m_mesh(mesh), + m_material(material), + m_emitter(emitter) +{ + return; +} + +WeaponController::~WeaponController() {} + +void WeaponController::attach(GameObject *object) { m_object = object; } + +void WeaponController::detach() { m_object = nullptr; } + +void WeaponController::update(float dtime) +{ + if (m_active && m_object != nullptr) + { + m_weaponCooldown -= dtime; + // Check for space key + if (m_inputProvider->isKeyPressed(GLFW_KEY_SPACE) && m_weaponCooldown <= 0.f) + { + // Reset cooldown + m_weaponCooldown = 0.3f; + + glm::vec3 direction = m_object->getForward(); + glm::vec3 position = m_object->getPosition(); + + // Create game object + GameObject *bullet = new GameObject; + bullet->addController(std::make_shared(direction, 50.f)); + bullet->setPosition(position + direction * 2.f); + bullet->setRotation(m_object->getRotation()); + + // Bullet colidable + std::vector bulletVertices; + std::vector bulletIndices; + std::vector bulletNormals; + std::vector bulletUvs; + PrimitiveType bulletType; + m_resourceManager->getMesh(m_mesh, bulletVertices, bulletIndices, bulletNormals, bulletUvs, bulletType); + bullet->setCollidable(m_collisionSystem->add(AABBox::create(bulletVertices), m_collisionGroup)); + bullet->getCollidable()->setDamage(50.f); + + // Create scene proxy + SceneObjectProxy *proxy = + new SceneObjectProxy(m_scene, m_scene->createObject(m_mesh, m_material, glm::vec3(0.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(1.f))); + bullet->setSceneObject(proxy); + + // Add to world + m_gameWorld->addObject(bullet); + // Play sound + m_emitter->play(); + } + } +} + +void WeaponController::setActive(bool state) { m_active = state; } + +void WeaponController::receiveMessage(Message msg) {} \ No newline at end of file diff --git a/Demo/CG2015/source/control/WeaponController.h b/Demo/CG2015/source/control/WeaponController.h new file mode 100644 index 0000000..f226d6b --- /dev/null +++ b/Demo/CG2015/source/control/WeaponController.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "kern/graphics/IScene.h" +#include "kern/graphics/input/IInputProvider.h" +#include "kern/resource/IResourceManager.h" + +/** + * \brief Controls weapons, creates projectiles. + */ +class WeaponController : public IGameObjectController +{ + public: + WeaponController(IInputProvider *provider, GameWorld *gameWorld, IScene *scene, ResourceId mesh, + ResourceId material, IResourceManager *resourceManager, CollisionSystem *collisionSystem, + int collisionGroup, std::shared_ptr emitter); + ~WeaponController(); + + void attach(GameObject *object); + void detach(); + void update(float dtime); + void setActive(bool state); + void receiveMessage(Message msg); + + private: + GameObject *m_object = nullptr; /**< Controlled game object. */ + bool m_active = true; /**< Active state flag. */ + IInputProvider *m_inputProvider = nullptr; + float m_weaponCooldown = 0.f; + GameWorld *m_gameWorld = nullptr; + IResourceManager *m_resourceManager = nullptr; + IScene *m_scene = nullptr; + ResourceId m_mesh = InvalidResource; + ResourceId m_material = InvalidResource; + CollisionSystem *m_collisionSystem = nullptr; + std::shared_ptr m_emitter; + + unsigned int m_collisionGroup; /**< Player collision group. */ +}; \ No newline at end of file diff --git a/Demo/CG2015/source/state/CGamePlayState.cpp b/Demo/CG2015/source/state/CGamePlayState.cpp deleted file mode 100644 index 0d1f8c6..0000000 --- a/Demo/CG2015/source/state/CGamePlayState.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "state/CGamePlayState.h" - -#include -#include - -#include -#include - -// GameObject -#include "application/game/CGameObject.h" - -// Controller -#include "control/CCameraController.h" -#include "control/CHealthController.h" -#include "control/CLinearMovementController.h" -#include "control/CPlayerMovementController.h" -#include "control/CRemoveOnDeathController.h" -#include "control/CRestrictPositionController.h" -#include "control/CSimpleWaypointController.h" -#include "control/CWeaponController.h" - -#include "graphics/graphics/camera/CFirstPersonCamera.h" - -#include "graphics/animation/CAnimationWorld.h" -#include "graphics/io/CSceneLoader.h" - -// Collision -#include "graphics/collision/CCollidable.h" -#include "graphics/collision/CCollisionSystem.h" - -const std::string exitStr = "lose"; -const std::string exitStrW = "win"; - -CGamePlayState::CGamePlayState() : m_enemyCount(6), m_enemyTime(4.f), m_enemyXPosition(-75.f) {} - -CGamePlayState::~CGamePlayState() -{ - // Empty -} - -bool CGamePlayState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) -{ - m_collisionSystem = new CCollisionSystem(); - m_graphicsSystem = graphicsSystem; - m_inputProvider = inputProvider; - m_resourceManager = resourceManager; - m_scene = m_graphicsSystem->createScene(); - - // Collision group ids for static entities, enemy objects and the player model - m_playerGroup = m_collisionSystem->getNewGroupId(); - m_enemyGroup = m_collisionSystem->getNewGroupId(); - - CAnimationWorld animWorld; - CSceneLoader loader(*resourceManager); - loader.load("data/world/game_1.json", *m_scene, animWorld); - - m_camera = std::make_shared( - glm::vec3(90.f, 70.f, 90.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f), 45.f, - 4.f / 3.f, 0.01f, 1000.f); - - // Disable god ray - m_camera->getFeatureInfoForWrite().godRayActive = false; - - // Create player - m_player = new CGameObject(); - - m_player->addController(std::make_shared(inputProvider, 20.f)); - m_player->addController(std::make_shared(m_camera.get())); - m_player->addController(std::make_shared(glm::vec2(-100.f, -100.f), - glm::vec2(100.f, 100.f))); - - // Load bullet - ResourceId bulletMesh = m_resourceManager->loadMesh("data/mesh/bullet.obj"); - if (bulletMesh == invalidResource) - { - return false; - } - ResourceId bulletMaterial = m_resourceManager->loadMaterial("data/material/white.json"); - if (bulletMaterial == invalidResource) - { - return false; - } - - m_player->addController(std::make_shared( - m_inputProvider, &getGameWorld(), m_scene, bulletMesh, bulletMaterial, m_resourceManager, - m_collisionSystem, m_playerGroup)); - m_player->setPosition(glm::vec3(0.f, 20.f, -100.f)); - m_player->setRotation(glm::vec3(0.f)); - m_player->setScale(glm::vec3(0.5f)); - - // Get model resources - ResourceId playerShip = m_resourceManager->loadMesh("data/mesh/ship_2.obj"); - if (playerShip == invalidResource) - { - return false; - } - - // Player collidable added to player collision group - std::vector playerVertices; - std::vector playerIndices; - std::vector playerNormals; - std::vector playerUvs; - EPrimitiveType playerType; - m_resourceManager->getMesh(playerShip, playerVertices, playerIndices, playerNormals, playerUvs, - playerType); - m_player->setCollidable(m_collisionSystem->add(CAABBox::create(playerVertices), m_playerGroup)); - m_player->getCollidable()->setDamage(50.f); - - ResourceId playerShipMaterial = - m_resourceManager->loadMaterial("data/material/line_metal.json"); - if (playerShipMaterial == invalidResource) - { - return false; - } - // Create scene object - CSceneObjectProxy *playerSceneObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(playerShip, playerShipMaterial, glm::vec3(0.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(1.f))); - m_player->setSceneObject(playerSceneObject); - - // Add player - getGameWorld().addObject(m_player); - - // Create mothership - m_mothership = new CGameObject(); - m_mothership->setPosition(glm::vec3(0.f, 68.f, 700.f)); - m_mothership->setRotation(glm::vec3(0.f)); - m_mothership->setScale(glm::vec3(60.f)); - m_mothership->addController( - std::make_shared(glm::vec3(0.f, 68.f, 0.f), 5.f, this)); - - // Get model resources - ResourceId motherShip = m_resourceManager->loadMesh("data/mesh/mothership.obj"); - if (motherShip == invalidResource) - { - return false; - } - ResourceId motherShipMaterial = - m_resourceManager->loadMaterial("data/material/mothership.json"); - if (motherShipMaterial == invalidResource) - { - return false; - } - // Create scene object - CSceneObjectProxy *motherSceneObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(motherShip, motherShipMaterial, glm::vec3(0.f, 68.f, 700.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(60.f))); - m_mothership->setSceneObject(motherSceneObject); - - // Add player - getGameWorld().addObject(m_mothership); - - // Create pyramide - CGameObject *m_pyramide = new CGameObject(); - m_pyramide->setPosition(glm::vec3(0.f, 2.f, 0.f)); - m_pyramide->setRotation(glm::vec3(0.f, -90.f, 0.f)); - m_pyramide->setScale(glm::vec3(3.f)); - - // Get model resources - ResourceId pyramide = m_resourceManager->loadMesh("data/mesh/piramyde.obj"); - if (pyramide == invalidResource) - { - return false; - } - - ResourceId pyramideMaterial = m_resourceManager->loadMaterial("data/material/sand.json"); - if (pyramideMaterial == invalidResource) - { - return false; - } - // Create scene object - // glm::vec3(0.f, -90.f, 0.f) - CSceneObjectProxy *pyramideSceneObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(pyramide, pyramideMaterial, glm::vec3(0.f, 2.f, 0.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(3.f))); - m_pyramide->setSceneObject(pyramideSceneObject); - - // Add player - getGameWorld().addObject(m_pyramide); - - // LOAD ENEMY RESOURCE - // Get model resources - enemyShip = m_resourceManager->loadMesh("data/mesh/enemy.obj"); - if (enemyShip == invalidResource) - { - return false; - } - - enemyShipMaterial = m_resourceManager->loadMaterial("data/material/enemy.json"); - if (enemyShipMaterial == invalidResource) - { - return false; - } - - // Load boss Enemy resources - // Add enemy with rotating ring - m_bossEnemy = new CGameObject(); - m_bossEnemy->setPosition(glm::vec3(0.f, 20.f, -50.f)); - m_bossEnemy->setRotation(glm::vec3(0.f)); - m_bossEnemy->setScale(glm::vec3(0.6f)); - m_bossEnemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - m_bossEnemy->addController( - std::make_shared(m_bossEnemy->getForward(), 17.f)); - m_bossEnemy->addController(std::make_shared(300.f)); - m_bossEnemy->addController(std::make_shared(this)); - - bossShip = m_resourceManager->loadMesh("data/mesh/ship_2.obj"); - if (bossShip == invalidResource) - { - return false; - } - - bossShipMaterial = m_resourceManager->loadMaterial("data/material/metallic_galvanized.json"); - if (enemyShipMaterial == invalidResource) - { - return false; - } - - // Create scene object - CSceneObjectProxy *bossSceneObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(bossShip, bossShipMaterial, glm::vec3(0.f, 20.f, -50.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); - m_bossEnemy->setSceneObject(bossSceneObject); - - getGameWorld().addObject(m_bossEnemy); - - m_ring = new CGameObject(); - m_ring->setPosition(glm::vec3(0.f, 20.f, -50.f)); - m_ring->setRotation(glm::vec3(0.f)); - m_ring->setScale(glm::vec3(0.5f)); - m_ring->addController(std::make_shared(glm::vec2(-100.f, -100.f), - glm::vec2(100.f, 100.f))); - m_ring->addController(std::make_shared(m_ring->getForward(), 17.f)); - - bossRing = m_resourceManager->loadMesh("data/mesh/ring_animation.obj"); - if (bossRing == invalidResource) - { - return false; - } - - bossRingMaterial = m_resourceManager->loadMaterial("data/material/metallic_galvanized.json"); - if (bossRingMaterial == invalidResource) - { - return false; - } - - // Create scene object - CSceneObjectProxy *bossRingObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(bossRing, bossRingMaterial, glm::vec3(0.f, 20.f, -50.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); - m_ring->setSceneObject(bossRingObject); - - getGameWorld().addObject(m_ring); - - return true; -} - -void CGamePlayState::onEnter() -{ - m_graphicsSystem->setActiveCamera(m_camera.get()); - m_graphicsSystem->setActiveScene(m_scene); -} - -bool CGamePlayState::update(float dtime) -{ - m_enemyTime -= dtime; - if (m_enemyCount > 0.f && m_enemyTime <= 0.f) - { - m_enemyTime = 2.f; - m_enemyId++; - // Create new enemy - CGameObject *enemy = new CGameObject(); - if (m_enemyId == 1) - { - enemy->setPosition(glm::vec3(-50.f, 30.f, 50.f)); - enemy->setRotation(glm::vec3(0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController( - std::make_shared(enemy->getForward(), 15.f)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - if (m_enemyId == 2) - { - enemy->setPosition(glm::vec3(0.f, 45.f, -50.f)); - enemy->setRotation(glm::vec3(0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController( - std::make_shared(enemy->getForward(), 15.f)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - if (m_enemyId == 3) - { - enemy->setPosition(glm::vec3(50.f, 20.f, 0.f)); - enemy->setRotation(glm::vec3(0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController( - std::make_shared(enemy->getForward(), 15.f)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - if (m_enemyId == 4) - { - enemy->setPosition(glm::vec3(50.f, 25.f, 0.f)); - enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController(std::make_shared( - glm::vec3(-101.f, 25.f, 0.f), 15.f, this)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - if (m_enemyId == 5) - { - enemy->setPosition(glm::vec3(0.f, 40.f, -50.f)); - enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController(std::make_shared( - glm::vec3(-101.f, 40.f, -50.f), 15.f, this)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - if (m_enemyId == 6) - { - enemy->setPosition(glm::vec3(-50.f, 50.f, 50.f)); - enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); - enemy->setScale(glm::vec3(0.5f)); - enemy->addController(std::make_shared( - glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); - enemy->addController(std::make_shared( - glm::vec3(-101.f, 50.f, 50.f), 15.f, this)); - enemy->addController(std::make_shared(100.f)); - enemy->addController(std::make_shared(this)); - } - - // Player collidable added to player collision group - std::vector enemyVertices; - std::vector enemyIndices; - std::vector enemyNormals; - std::vector enemyUvs; - EPrimitiveType enemyType; - m_resourceManager->getMesh(enemyShip, enemyVertices, enemyIndices, enemyNormals, enemyUvs, - enemyType); - enemy->setCollidable(m_collisionSystem->add(CAABBox::create(enemyVertices), m_enemyGroup)); - - // Create scene object - CSceneObjectProxy *enemySceneObject = new CSceneObjectProxy( - m_scene, m_scene->createObject(enemyShip, enemyShipMaterial, - glm::vec3(m_enemyXPosition, 25.f, 0.f), - glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); - enemy->setSceneObject(enemySceneObject); - - // Add enemy - getGameWorld().addObject(enemy); - - m_enemyCount -= 1; - m_enemyXPosition += 25.f; - } - - m_ring->setRotation(glm::vec3(m_ring->getRotation().x, m_ring->getRotation().y, - m_ring->getRotation().z + dtime)); - - if (m_inputProvider->isKeyPressed(GLFW_KEY_P)) - { - return false; - } - if (m_inputProvider->isKeyPressed(GLFW_KEY_O)) - { - m_winCounter = 6; - return false; - } - if (m_winCounter == 6) - { - return false; - } - - if (m_inputProvider->isKeyPressed(GLFW_KEY_K)) - { - m_camera->getFeatureInfoForWrite().toonActive = true; - } - if (m_inputProvider->isKeyPressed(GLFW_KEY_L)) - { - m_camera->getFeatureInfoForWrite().toonActive = false; - } - // Update collision system - m_collisionSystem->update(); - // Update gameworld - return AGameState::update(dtime); -} - -void CGamePlayState::onExit() -{ - // Cleanup? -} - -const std::string &CGamePlayState::getNextState() const -{ - if (m_winCounter == 6) - { - return exitStrW; - } - else - { - return exitStr; - } -} - -void CGamePlayState::winCount() { m_winCounter++; } diff --git a/Demo/CG2015/source/state/CGamePlayState.h b/Demo/CG2015/source/state/CGamePlayState.h deleted file mode 100644 index 39d109b..0000000 --- a/Demo/CG2015/source/state/CGamePlayState.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "graphics/animation/CAnimationWorld.h" - -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" -#include "graphics/graphics/camera/IControllableCamera.h" - -#include "graphics/resource/IResourceManager.h" - -#include "graphics/input/IInputProvider.h" - -#include "graphics/collision/CAABBox.h" -#include "graphics/collision/CCollisionSystem.h" - -#include "application/game/AGameState.h" -#include "application/game/CGameObject.h" -#include "application/game/CGameWorld.h" - -class CGamePlayState : public AGameState -{ - public: - CGamePlayState(); - ~CGamePlayState(); - - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); - void onEnter(); - bool update(float dtime); - void onExit(); - const std::string &getNextState() const; - void winCount(); - - private: - IGraphicsSystem *m_graphicsSystem = nullptr; - IScene *m_scene = nullptr; - IResourceManager *m_resourceManager = nullptr; - IInputProvider *m_inputProvider = nullptr; - std::shared_ptr m_camera = nullptr; - CCollisionSystem *m_collisionSystem = nullptr; /**< Collision system. */ - - CGameObject *m_player = nullptr; /**< Player object. */ - CGameObject *m_mothership = nullptr; /**< Mothership object. */ - CGameObject *m_enemy = nullptr; /**< Mothership object. */ - CGameObject *m_ring = nullptr; /**< Ring object. */ - CGameObject *m_bossEnemy = nullptr; /**< Mothership object. */ - - int m_enemyCount = 0; /**< Enemy spawn counter. */ - int m_enemyId = 0; - float m_enemyTime = 0.0; /**< Enemy spawn time. */ - float m_enemyXPosition = 0.0; // Hack - unsigned int m_playerGroup = 0; /**< Player collision group. */ - unsigned int m_enemyGroup = 0; /**< Enemy collision group. */ - - ResourceId enemyShip = invalidResource; - ResourceId enemyShipMaterial = invalidResource; - ResourceId bossShip = invalidResource; - ResourceId bossShipMaterial = invalidResource; - ResourceId bossRing = invalidResource; - ResourceId bossRingMaterial = invalidResource; - - int m_winCounter = 0; -}; diff --git a/Demo/CG2015/source/state/CLoadState.h b/Demo/CG2015/source/state/CLoadState.h deleted file mode 100644 index 2642b44..0000000 --- a/Demo/CG2015/source/state/CLoadState.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "graphics/animation/CAnimationWorld.h" -#include "graphics/resource/IResourceManager.h" - -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" - -#include "application/game/CGameSystem.h" -#include "application/game/IGameState.h" - -/** - * \brief Load state. - * - * Just for showing off some effects. - */ -class CLoadState : public IGameState -{ - public: - CLoadState(const std::string &sceneFile, float transitionTime); - ~CLoadState(); - - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); - - void onEnter(); - bool update(float dtime); - void onExit(); - const std::string &getNextState() const; - - private: - float m_transitionTime = 0.f; - float m_timeLeft = 0.f; - std::string m_sceneFile; - std::shared_ptr m_camera = nullptr; - IScene *m_scene = nullptr; - IGraphicsSystem *m_graphicsSystem = nullptr; - IResourceManager *m_resourceManager = nullptr; - CAnimationWorld m_animationWorld; - std::string m_nextState; /**< Next state. */ - CGameSystem *m_gameSystem = nullptr; /**< Game system. */ -}; diff --git a/Demo/CG2015/source/state/CLoseState.cpp b/Demo/CG2015/source/state/CLoseState.cpp deleted file mode 100644 index 3be16c1..0000000 --- a/Demo/CG2015/source/state/CLoseState.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "state/CLoseState.h" - -#include - -#include - -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/io/CSceneLoader.h" - -const std::string gameStr = "game"; - -CLoseState::CLoseState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} - -CLoseState::~CLoseState() -{ - // Empty -} - -bool CLoseState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) -{ - m_graphicsSystem = graphicsSystem; - m_inputProvider = inputProvider; - m_resourceManager = resourceManager; - - // TODO Refactor, camera movement should be implemented with a single camera - // and camera controllers. - m_camera = std::make_shared( - glm::vec3(-4.4f, 5.f, 14.5), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f), 45.f, - 4.f / 3.f, 0.01f, 1000.f); - - m_camera->getFeatureInfoForWrite().godRayActive = false; - - // Create new scene object - m_scene = m_graphicsSystem->createScene(); - - // Load scene from file - LOG_INFO("Loading scene from file %s.", m_sceneFile.c_str()); - CSceneLoader loader(*resourceManager); - if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) - { - LOG_ERROR("Failed to load scene file %s.", m_sceneFile.c_str()); - return false; - } - return true; -} - -void CLoseState::onEnter() -{ - m_fadeInTime = 3.f; - m_graphicsSystem->setActiveCamera(m_camera.get()); - m_graphicsSystem->setActiveScene(m_scene); -} - -bool CLoseState::update(float dtime) -{ - // Ignore user input for some time - if (m_fadeInTime > 0.0f) - { - m_fadeInTime -= dtime; - } - - m_animationWorld.update(dtime); - return true; -} - -void CLoseState::onExit() -{ - // Nothing -} - -const std::string &CLoseState::getNextState() const { return gameStr; } \ No newline at end of file diff --git a/Demo/CG2015/source/state/CDemoState.cpp b/Demo/CG2015/source/state/DemoState.cpp similarity index 59% rename from Demo/CG2015/source/state/CDemoState.cpp rename to Demo/CG2015/source/state/DemoState.cpp index 0f5626c..b8d0349 100644 --- a/Demo/CG2015/source/state/CDemoState.cpp +++ b/Demo/CG2015/source/state/DemoState.cpp @@ -1,30 +1,30 @@ -#include "state/CDemoState.h" +#include "state/DemoState.h" -#include +#include -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/io/CSceneLoader.h" +#include "kern/graphics/camera/FirstPersonCamera.h" +#include "kern/graphics/io/SceneLoader.h" const std::string exitStr = "exit"; -CDemoState::CDemoState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} +DemoState::DemoState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} -CDemoState::~CDemoState() +DemoState::~DemoState() { // Empty } -bool CDemoState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) +bool DemoState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) { m_graphicsSystem = graphicsSystem; // TODO Refactor, camera movement should be implemented with a single camera // and camera controllers. - m_camera = std::make_shared( + m_camera = std::make_shared( glm::vec3(0.5f, 0.f, 0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); - m_cameraController = std::make_shared(); + m_cameraController = std::make_shared(); m_cameraController->setCamera(m_camera); m_cameraController->setInputProvider(inputProvider); m_camera->getFeatureInfoForWrite().lenseFlareActive = false; @@ -33,23 +33,23 @@ bool CDemoState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProv m_scene = m_graphicsSystem->createScene(); // Load scene from file - LOG_INFO("Loading scene from file %s.", m_sceneFile.c_str()); - CSceneLoader loader(*resourceManager); + logi("Loading scene from file {}.", m_sceneFile.c_str()); + SceneLoader loader(*resourceManager); if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) { - LOG_ERROR("Failed to load scene file %s.", m_sceneFile.c_str()); + loge("Failed to load scene file {}.", m_sceneFile.c_str()); return false; } return true; } -void CDemoState::onEnter() +void DemoState::onEnter() { m_graphicsSystem->setActiveCamera(m_camera.get()); m_graphicsSystem->setActiveScene(m_scene); } -bool CDemoState::update(float dtime) +bool DemoState::update(float dtime) { // Key F5 starts replay of camera movement // Disabled and to be moved into game state @@ -64,9 +64,9 @@ bool CDemoState::update(float dtime) return true; } -void CDemoState::onExit() +void DemoState::onExit() { // Nothing } -const std::string &CDemoState::getNextState() const { return exitStr; } \ No newline at end of file +const std::string &DemoState::getNextState() const { return exitStr; } \ No newline at end of file diff --git a/Demo/CG2015/source/state/CDemoState.h b/Demo/CG2015/source/state/DemoState.h similarity index 51% rename from Demo/CG2015/source/state/CDemoState.h rename to Demo/CG2015/source/state/DemoState.h index 9a6c3c0..c307584 100644 --- a/Demo/CG2015/source/state/CDemoState.h +++ b/Demo/CG2015/source/state/DemoState.h @@ -1,16 +1,16 @@ #pragma once -#include "application/game/IGameState.h" +#include "kern/game/IGameState.h" -#include "graphics/animation/CAnimationWorld.h" +#include "kern/graphics/animation/AnimationWorld.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" -#include "graphics/graphics/camera/IControllableCamera.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/camera/IControllableCamera.h" -#include "CFreeFlightCameraController.h" +#include "FreeFlightCameraController.h" -#include "graphics/resource/IResourceManager.h" +#include "kern/resource/IResourceManager.h" /** * \brief Represents the demo state of the engine. @@ -19,14 +19,14 @@ * A scene is loaded form a file and rendered with a freely movable camera * controlled by the user. */ -class CDemoState : public IGameState +class DemoState : public IGameState { public: - CDemoState(const std::string &sceneFile); - ~CDemoState(); + DemoState(const std::string &sceneFile); + ~DemoState(); - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); void onEnter(); bool update(float dtime); @@ -36,9 +36,9 @@ class CDemoState : public IGameState private: std::string m_sceneFile; - std::shared_ptr m_cameraController = nullptr; + std::shared_ptr m_cameraController = nullptr; std::shared_ptr m_camera = nullptr; IScene *m_scene = nullptr; IGraphicsSystem *m_graphicsSystem = nullptr; - CAnimationWorld m_animationWorld; + AnimationWorld m_animationWorld; }; \ No newline at end of file diff --git a/Demo/CG2015/source/state/GamePlayState.cpp b/Demo/CG2015/source/state/GamePlayState.cpp new file mode 100644 index 0000000..fdb5676 --- /dev/null +++ b/Demo/CG2015/source/state/GamePlayState.cpp @@ -0,0 +1,429 @@ +#include "state/GamePlayState.h" + +#define GLFW_INCLUDE_NONE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "control/CameraController.h" +#include "control/HealthController.h" +#include "control/LinearMovementController.h" +#include "control/PlayerMovementController.h" +#include "control/RemoveOnDeathController.h" +#include "control/RestrictPositionController.h" +#include "control/SimpleWaypointController.h" +#include "control/WeaponController.h" + +const std::string exitStr = "lose"; +const std::string exitStrW = "win"; + +GamePlayState::GamePlayState() : m_enemyCount(6), m_enemyTime(4.f), m_enemyXPosition(-75.f) {} + +GamePlayState::~GamePlayState() +{ + // Empty +} + +bool GamePlayState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, + IResourceManager *resourceManager, SoundSystem *soundSystem) +{ + // Sound + m_soundSystem = soundSystem; + m_soundSystem->getManager()->registerSound("playbgm", "bgm/kim-lightyear-stardust-vision-ii-135754.mp3"); + m_soundSystem->getManager()->registerSound("shotsfx", "sfx/shoot02wav-14562.mp3"); + m_soundSystem->getManager()->registerSound("explosfx", "sfx/explosion-91872.mp3"); + + m_bgmSound = m_soundSystem->getManager()->getSound("playbgm"); + m_bgmEmitter = m_soundSystem->getGlobalSoundEmitter(); + auto shotEmitter = m_soundSystem->createEmitter(soundSystem->getManager()->getSound("shotsfx")); + + m_collisionSystem = new CollisionSystem(); + m_graphicsSystem = graphicsSystem; + m_inputProvider = inputProvider; + m_resourceManager = resourceManager; + m_scene = m_graphicsSystem->createScene(); + + // Collision group ids for static entities, enemy objects and the player model + m_playerGroup = m_collisionSystem->getNewGroupId(); + m_enemyGroup = m_collisionSystem->getNewGroupId(); + + AnimationWorld animWorld; + SceneLoader loader(*resourceManager); + loader.load("data/world/game_1.json", *m_scene, animWorld); + + m_camera = std::make_shared(glm::vec3(90.f, 70.f, 90.f), glm::vec3(0.f, 0.f, 0.f), + glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); + + // Disable god ray + m_camera->getFeatureInfoForWrite().godRayActive = false; + + // Create player + m_player = new GameObject(); + + m_player->addController(std::make_shared(inputProvider, 20.f)); + m_player->addController(std::make_shared(m_camera.get())); + m_player->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + + // Load bullet + ResourceId bulletMesh = m_resourceManager->loadMesh("data/mesh/bullet.obj"); + if (bulletMesh == InvalidResource) + { + return false; + } + ResourceId bulletMaterial = m_resourceManager->loadMaterial("data/material/white_glowing.json"); + if (bulletMaterial == InvalidResource) + { + return false; + } + + m_player->addController(std::make_shared(m_inputProvider, &getGameWorld(), m_scene, bulletMesh, + bulletMaterial, m_resourceManager, m_collisionSystem, + m_playerGroup, shotEmitter)); + m_player->setPosition(glm::vec3(0.f, 20.f, -100.f)); + m_player->setRotation(glm::vec3(0.f)); + m_player->setScale(glm::vec3(0.5f)); + + // Get model resources + ResourceId playerShip = m_resourceManager->loadMesh("data/mesh/ship_2.obj"); + if (playerShip == InvalidResource) + { + return false; + } + + // Player collidable added to player collision group + std::vector playerVertices; + std::vector playerIndices; + std::vector playerNormals; + std::vector playerUvs; + PrimitiveType playerType; + m_resourceManager->getMesh(playerShip, playerVertices, playerIndices, playerNormals, playerUvs, playerType); + m_player->setCollidable(m_collisionSystem->add(AABBox::create(playerVertices), m_playerGroup)); + m_player->getCollidable()->setDamage(50.f); + + ResourceId playerShipMaterial = m_resourceManager->loadMaterial("data/material/line_metal.json"); + if (playerShipMaterial == InvalidResource) + { + return false; + } + // Create scene object + SceneObjectProxy *playerSceneObject = + new SceneObjectProxy(m_scene, m_scene->createObject(playerShip, playerShipMaterial, glm::vec3(0.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(1.f))); + m_player->setSceneObject(playerSceneObject); + + // Add player + getGameWorld().addObject(m_player); + + // Create mothership + m_mothership = new GameObject(); + m_mothership->setPosition(glm::vec3(0.f, 68.f, 700.f)); + m_mothership->setRotation(glm::vec3(0.f)); + m_mothership->setScale(glm::vec3(60.f)); + m_mothership->addController(std::make_shared(glm::vec3(0.f, 68.f, 0.f), 5.f, this)); + + // Get model resources + ResourceId motherShip = m_resourceManager->loadMesh("data/mesh/mothership.obj"); + if (motherShip == InvalidResource) + { + return false; + } + ResourceId motherShipMaterial = m_resourceManager->loadMaterial("data/material/mothership.json"); + if (motherShipMaterial == InvalidResource) + { + return false; + } + // Create scene object + SceneObjectProxy *motherSceneObject = + new SceneObjectProxy(m_scene, m_scene->createObject(motherShip, motherShipMaterial, glm::vec3(0.f, 68.f, 700.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(60.f))); + m_mothership->setSceneObject(motherSceneObject); + + // Add player + getGameWorld().addObject(m_mothership); + + // Create pyramide + GameObject *m_pyramide = new GameObject(); + m_pyramide->setPosition(glm::vec3(0.f, 2.f, 0.f)); + m_pyramide->setRotation(glm::vec3(0.f, -90.f, 0.f)); + m_pyramide->setScale(glm::vec3(3.f)); + + // Get model resources + ResourceId pyramide = m_resourceManager->loadMesh("data/mesh/piramyde.obj"); + if (pyramide == InvalidResource) + { + return false; + } + + ResourceId pyramideMaterial = m_resourceManager->loadMaterial("data/material/sand.json"); + if (pyramideMaterial == InvalidResource) + { + return false; + } + // Create scene object + // glm::vec3(0.f, -90.f, 0.f) + SceneObjectProxy *pyramideSceneObject = + new SceneObjectProxy(m_scene, m_scene->createObject(pyramide, pyramideMaterial, glm::vec3(0.f, 2.f, 0.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(3.f))); + m_pyramide->setSceneObject(pyramideSceneObject); + + // Add player + getGameWorld().addObject(m_pyramide); + + // LOAD ENEMY RESOURCE + // Get model resources + enemyShip = m_resourceManager->loadMesh("data/mesh/enemy.obj"); + if (enemyShip == InvalidResource) + { + return false; + } + + enemyShipMaterial = m_resourceManager->loadMaterial("data/material/enemy.json"); + if (enemyShipMaterial == InvalidResource) + { + return false; + } + + // Explosion sound + auto exploSound = soundSystem->getManager()->getSound("explosfx"); + + // Load boss Enemy resources + // Add enemy with rotating ring + m_bossEnemy = new GameObject(); + m_bossEnemy->setPosition(glm::vec3(0.f, 20.f, -50.f)); + m_bossEnemy->setRotation(glm::vec3(0.f)); + m_bossEnemy->setScale(glm::vec3(0.6f)); + m_bossEnemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + m_bossEnemy->addController(std::make_shared(m_bossEnemy->getForward(), 17.f)); + m_bossEnemy->addController(std::make_shared(300.f)); + m_bossEnemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + + bossShip = m_resourceManager->loadMesh("data/mesh/ship_2.obj"); + if (bossShip == InvalidResource) + { + return false; + } + + bossShipMaterial = m_resourceManager->loadMaterial("data/material/metallic_galvanized.json"); + if (enemyShipMaterial == InvalidResource) + { + return false; + } + + // Create scene object + SceneObjectProxy *bosSceneObject = + new SceneObjectProxy(m_scene, m_scene->createObject(bossShip, bossShipMaterial, glm::vec3(0.f, 20.f, -50.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); + m_bossEnemy->setSceneObject(bosSceneObject); + + getGameWorld().addObject(m_bossEnemy); + + m_ring = new GameObject(); + m_ring->setPosition(glm::vec3(0.f, 20.f, -50.f)); + m_ring->setRotation(glm::vec3(0.f)); + m_ring->setScale(glm::vec3(0.5f)); + m_ring->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + m_ring->addController(std::make_shared(m_ring->getForward(), 17.f)); + + bossRing = m_resourceManager->loadMesh("data/mesh/ring_animation.obj"); + if (bossRing == InvalidResource) + { + return false; + } + + bossRingMaterial = m_resourceManager->loadMaterial("data/material/metallic_galvanized.json"); + if (bossRingMaterial == InvalidResource) + { + return false; + } + + // Create scene object + SceneObjectProxy *bossRingObject = + new SceneObjectProxy(m_scene, m_scene->createObject(bossRing, bossRingMaterial, glm::vec3(0.f, 20.f, -50.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); + m_ring->setSceneObject(bossRingObject); + + getGameWorld().addObject(m_ring); + return true; +} + +void GamePlayState::onEnter() +{ + m_graphicsSystem->setActiveCamera(m_camera.get()); + m_graphicsSystem->setActiveScene(m_scene); + m_bgmEmitter->play(m_bgmSound); +} + +bool GamePlayState::update(float dtime) +{ + m_enemyTime -= dtime; + if (m_enemyCount > 0.f && m_enemyTime <= 0.f) + { + auto exploSound = m_soundSystem->getManager()->getSound("explosfx"); + + m_enemyTime = 2.f; + m_enemyId++; + // Create new enemy + GameObject *enemy = new GameObject(); + if (m_enemyId == 1) + { + enemy->setPosition(glm::vec3(-50.f, 30.f, 50.f)); + enemy->setRotation(glm::vec3(0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController(std::make_shared(enemy->getForward(), 15.f)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + if (m_enemyId == 2) + { + enemy->setPosition(glm::vec3(0.f, 45.f, -50.f)); + enemy->setRotation(glm::vec3(0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController(std::make_shared(enemy->getForward(), 15.f)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + if (m_enemyId == 3) + { + enemy->setPosition(glm::vec3(50.f, 20.f, 0.f)); + enemy->setRotation(glm::vec3(0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController(std::make_shared(enemy->getForward(), 15.f)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + if (m_enemyId == 4) + { + enemy->setPosition(glm::vec3(50.f, 25.f, 0.f)); + enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController(std::make_shared(glm::vec3(-101.f, 25.f, 0.f), 15.f, this)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + if (m_enemyId == 5) + { + enemy->setPosition(glm::vec3(0.f, 40.f, -50.f)); + enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController( + std::make_shared(glm::vec3(-101.f, 40.f, -50.f), 15.f, this)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + if (m_enemyId == 6) + { + enemy->setPosition(glm::vec3(-50.f, 50.f, 50.f)); + enemy->setRotation(glm::vec3(0.f, 92.6, 0.f)); + enemy->setScale(glm::vec3(0.5f)); + enemy->addController( + std::make_shared(glm::vec2(-100.f, -100.f), glm::vec2(100.f, 100.f))); + enemy->addController(std::make_shared(glm::vec3(-101.f, 50.f, 50.f), 15.f, this)); + enemy->addController(std::make_shared(100.f)); + enemy->addController( + std::make_shared(this, m_soundSystem->createEmitter(exploSound))); + } + + // Player collidable added to player collision group + std::vector enemyVertices; + std::vector enemyIndices; + std::vector enemyNormals; + std::vector enemyUvs; + PrimitiveType enemyType; + m_resourceManager->getMesh(enemyShip, enemyVertices, enemyIndices, enemyNormals, enemyUvs, enemyType); + enemy->setCollidable(m_collisionSystem->add(AABBox::create(enemyVertices), m_enemyGroup)); + + // Create scene object + SceneObjectProxy *enemySceneObject = new SceneObjectProxy( + m_scene, m_scene->createObject(enemyShip, enemyShipMaterial, glm::vec3(m_enemyXPosition, 25.f, 0.f), + glm::quat(0.f, 0.f, 0.f, 0.f), glm::vec3(0.5f))); + enemy->setSceneObject(enemySceneObject); + + // Add enemy + getGameWorld().addObject(enemy); + + m_enemyCount -= 1; + m_enemyXPosition += 25.f; + } + + m_ring->setRotation(glm::vec3(m_ring->getRotation().x, m_ring->getRotation().y, m_ring->getRotation().z + dtime)); + + if (m_inputProvider->isKeyPressed(GLFW_KEY_P)) + { + return false; + } + + if (m_inputProvider->isKeyPressed(GLFW_KEY_O)) + { + m_winCounter = 6; + return false; + } + + if (m_winCounter == 6) + { + return false; + } + + if (m_inputProvider->isKeyPressed(GLFW_KEY_K)) + { + m_camera->getFeatureInfoForWrite().toonActive = true; + } + if (m_inputProvider->isKeyPressed(GLFW_KEY_L)) + { + m_camera->getFeatureInfoForWrite().toonActive = false; + } + // Update collision system + m_collisionSystem->update(); + // Update gameworld + return AGameState::update(dtime); +} + +void GamePlayState::onExit() +{ + // Cleanup? +} + +const std::string &GamePlayState::getNextState() const +{ + if (m_winCounter == 6) + { + return exitStrW; + } + else + { + return exitStr; + } +} + +void GamePlayState::winCount() { m_winCounter++; } diff --git a/Demo/CG2015/source/state/GamePlayState.h b/Demo/CG2015/source/state/GamePlayState.h new file mode 100644 index 0000000..ffcf420 --- /dev/null +++ b/Demo/CG2015/source/state/GamePlayState.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class GamePlayState : public AGameState +{ + public: + GamePlayState(); + ~GamePlayState(); + + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); + void onEnter(); + bool update(float dtime); + void onExit(); + const std::string &getNextState() const; + void winCount(); + + private: + IGraphicsSystem *m_graphicsSystem = nullptr; + IScene *m_scene = nullptr; + IResourceManager *m_resourceManager = nullptr; + IInputProvider *m_inputProvider = nullptr; + std::shared_ptr m_camera = nullptr; + CollisionSystem *m_collisionSystem = nullptr; /**< Collision system. */ + SoundSystem *m_soundSystem = nullptr; + + GameObject *m_player = nullptr; /**< Player object. */ + GameObject *m_mothership = nullptr; /**< Mothership object. */ + GameObject *m_enemy = nullptr; /**< Mothership object. */ + GameObject *m_ring = nullptr; /**< Ring object. */ + GameObject *m_bossEnemy = nullptr; /**< Mothership object. */ + + int m_enemyCount = 0; /**< Enemy spawn counter. */ + int m_enemyId = 0; + float m_enemyTime = 0.0; /**< Enemy spawn time. */ + float m_enemyXPosition = 0.0; // Hack + unsigned int m_playerGroup = 0; /**< Player collision group. */ + unsigned int m_enemyGroup = 0; /**< Enemy collision group. */ + + ResourceId enemyShip = InvalidResource; + ResourceId enemyShipMaterial = InvalidResource; + ResourceId bossShip = InvalidResource; + ResourceId bossShipMaterial = InvalidResource; + ResourceId bossRing = InvalidResource; + ResourceId bossRingMaterial = InvalidResource; + std::shared_ptr m_bgmSound; + std::shared_ptr m_bgmEmitter; + + int m_winCounter = 0; +}; diff --git a/Demo/CG2015/source/state/CLoadState.cpp b/Demo/CG2015/source/state/LoadState.cpp similarity index 51% rename from Demo/CG2015/source/state/CLoadState.cpp rename to Demo/CG2015/source/state/LoadState.cpp index a650d96..0321bcb 100644 --- a/Demo/CG2015/source/state/CLoadState.cpp +++ b/Demo/CG2015/source/state/LoadState.cpp @@ -1,32 +1,33 @@ -#include "state/CLoadState.h" +#include "state/LoadState.h" +#define GLFW_INCLUDE_NONE #include -#include +#include -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/io/CSceneLoader.h" +#include "kern/graphics/camera/FirstPersonCamera.h" +#include "kern/graphics/io/SceneLoader.h" const std::string titleStr = "title"; -CLoadState::CLoadState(const std::string &sceneFile, float transitionTime) +LoadState::LoadState(const std::string &sceneFile, float transitionTime) : m_transitionTime(transitionTime), m_sceneFile(sceneFile) { } -CLoadState::~CLoadState() +LoadState::~LoadState() { // Empty } -bool CLoadState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) +bool LoadState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) { m_graphicsSystem = graphicsSystem; m_resourceManager = resourceManager; // TODO Refactor, camera movement should be implemented with a single camera // and camera controllers. - m_camera = std::make_shared( + m_camera = std::make_shared( glm::vec3(6.f, 0.f, -1.5f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); @@ -37,24 +38,30 @@ bool CLoadState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProv m_scene = m_graphicsSystem->createScene(); // Load scene from file - LOG_INFO("Loading scene from file %s.", m_sceneFile.c_str()); - CSceneLoader loader(*resourceManager); + logi("Loading scene from file {}.", m_sceneFile.c_str()); + SceneLoader loader(*resourceManager); if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) { - LOG_ERROR("Failed to load scene file %s.", m_sceneFile.c_str()); + loge("Failed to load scene file {}.", m_sceneFile.c_str()); return false; } + + // Load sound + soundSystem->getManager()->registerSound("loadbgm", "bgm/sion_-_ambients_-_stars_at_night.mp3"); + m_bgmSound = soundSystem->getManager()->getSound("loadbgm"); + m_bgmEmitter = soundSystem->getGlobalSoundEmitter(); return true; } -void CLoadState::onEnter() +void LoadState::onEnter() { m_timeLeft = m_transitionTime; m_graphicsSystem->setActiveCamera(m_camera.get()); m_graphicsSystem->setActiveScene(m_scene); + m_bgmEmitter->play(m_bgmSound); } -bool CLoadState::update(float dtime) +bool LoadState::update(float dtime) { // Ignore user input for some time if (m_timeLeft > 0.0f) @@ -70,9 +77,8 @@ bool CLoadState::update(float dtime) return true; } -void CLoadState::onExit() +void LoadState::onExit() { - // Nothing } -const std::string &CLoadState::getNextState() const { return titleStr; } +const std::string &LoadState::getNextState() const { return titleStr; } diff --git a/Demo/CG2015/source/state/LoadState.h b/Demo/CG2015/source/state/LoadState.h new file mode 100644 index 0000000..7eed748 --- /dev/null +++ b/Demo/CG2015/source/state/LoadState.h @@ -0,0 +1,43 @@ +#pragma once + +#include "kern/game/GameSystem.h" +#include "kern/game/IGameState.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/animation/AnimationWorld.h" +#include "kern/resource/IResourceManager.h" + +/** + * \brief Load state. + * + * Just for showing off some effects. + */ +class LoadState : public IGameState +{ + public: + LoadState(const std::string &sceneFile, float transitionTime); + ~LoadState(); + + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) override; + + void onEnter(); + bool update(float dtime); + void onExit(); + const std::string &getNextState() const; + + private: + float m_transitionTime = 0.f; + float m_timeLeft = 0.f; + std::string m_sceneFile; + std::shared_ptr m_camera; + IScene *m_scene = nullptr; + IGraphicsSystem *m_graphicsSystem = nullptr; + IResourceManager *m_resourceManager = nullptr; + AnimationWorld m_animationWorld; + std::string m_nextState; /**< Next state. */ + GameSystem *m_gameSystem = nullptr; /**< Game system. */ + std::shared_ptr m_bgmSound; + std::shared_ptr m_bgmEmitter; +}; diff --git a/Demo/CG2015/source/state/CWinState.cpp b/Demo/CG2015/source/state/LoseState.cpp similarity index 57% rename from Demo/CG2015/source/state/CWinState.cpp rename to Demo/CG2015/source/state/LoseState.cpp index 7b5da18..1c72232 100644 --- a/Demo/CG2015/source/state/CWinState.cpp +++ b/Demo/CG2015/source/state/LoseState.cpp @@ -1,23 +1,24 @@ -#include "state/CWinState.h" +#include "state/LoseState.h" +#define GLFW_INCLUDE_NONE #include -#include +#include -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/io/CSceneLoader.h" +#include "kern/graphics/camera/FirstPersonCamera.h" +#include "kern/graphics/io/SceneLoader.h" const std::string gameStr = "game"; -CWinState::CWinState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} +LoseState::LoseState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} -CWinState::~CWinState() +LoseState::~LoseState() { // Empty } -bool CWinState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) +bool LoseState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) { m_graphicsSystem = graphicsSystem; m_inputProvider = inputProvider; @@ -25,7 +26,7 @@ bool CWinState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvi // TODO Refactor, camera movement should be implemented with a single camera // and camera controllers. - m_camera = std::make_shared( + m_camera = std::make_shared( glm::vec3(-4.4f, 5.f, 14.5), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); @@ -35,24 +36,24 @@ bool CWinState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvi m_scene = m_graphicsSystem->createScene(); // Load scene from file - LOG_INFO("Loading scene from file %s.", m_sceneFile.c_str()); - CSceneLoader loader(*resourceManager); + logi("Loading scene from file {}.", m_sceneFile.c_str()); + SceneLoader loader(*resourceManager); if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) { - LOG_ERROR("Failed to load scene file %s.", m_sceneFile.c_str()); + loge("Failed to load scene file {}.", m_sceneFile.c_str()); return false; } return true; } -void CWinState::onEnter() +void LoseState::onEnter() { m_fadeInTime = 3.f; m_graphicsSystem->setActiveCamera(m_camera.get()); m_graphicsSystem->setActiveScene(m_scene); } -bool CWinState::update(float dtime) +bool LoseState::update(float dtime) { // Ignore user input for some time if (m_fadeInTime > 0.0f) @@ -64,9 +65,9 @@ bool CWinState::update(float dtime) return true; } -void CWinState::onExit() +void LoseState::onExit() { // Nothing } -const std::string &CWinState::getNextState() const { return gameStr; } \ No newline at end of file +const std::string &LoseState::getNextState() const { return gameStr; } \ No newline at end of file diff --git a/Demo/CG2015/source/state/CLoseState.h b/Demo/CG2015/source/state/LoseState.h similarity index 51% rename from Demo/CG2015/source/state/CLoseState.h rename to Demo/CG2015/source/state/LoseState.h index f88dff6..3413a2b 100644 --- a/Demo/CG2015/source/state/CLoseState.h +++ b/Demo/CG2015/source/state/LoseState.h @@ -1,28 +1,28 @@ #pragma once -#include "graphics/animation/CAnimationWorld.h" +#include "kern/graphics/animation/AnimationWorld.h" -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IScene.h" -#include "graphics/input/IInputProvider.h" -#include "graphics/resource/IResourceManager.h" +#include "kern/graphics/input/IInputProvider.h" +#include "kern/resource/IResourceManager.h" -#include "application/game/CGameSystem.h" -#include "application/game/IGameState.h" +#include "kern/game/GameSystem.h" +#include "kern/game/IGameState.h" /** * \brief Lose state, similar to demo state with static camera. */ -class CLoseState : public IGameState +class LoseState : public IGameState { public: - CLoseState(const std::string &sceneFile); - ~CLoseState(); + LoseState(const std::string &sceneFile); + ~LoseState(); - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); void onEnter(); bool update(float dtime); @@ -37,7 +37,7 @@ class CLoseState : public IGameState IScene *m_scene = nullptr; IGraphicsSystem *m_graphicsSystem = nullptr; IResourceManager *m_resourceManager = nullptr; - CAnimationWorld m_animationWorld; + AnimationWorld m_animationWorld; std::string m_nextState; /**< Next state. */ - CGameSystem *m_gameSystem = nullptr; /**< Game system. */ + GameSystem *m_gameSystem = nullptr; /**< Game system. */ }; diff --git a/Demo/CG2015/source/state/CTitleState.cpp b/Demo/CG2015/source/state/TitleState.cpp similarity index 59% rename from Demo/CG2015/source/state/CTitleState.cpp rename to Demo/CG2015/source/state/TitleState.cpp index 2f9ba3d..723bb65 100644 --- a/Demo/CG2015/source/state/CTitleState.cpp +++ b/Demo/CG2015/source/state/TitleState.cpp @@ -1,23 +1,24 @@ -#include "state/CTitleState.h" +#include "state/TitleState.h" +#define GLFW_INCLUDE_NONE #include -#include +#include -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/io/CSceneLoader.h" +#include "kern/graphics/camera/FirstPersonCamera.h" +#include "kern/graphics/io/SceneLoader.h" const std::string gameStr = "game"; -CTitleState::CTitleState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} +TitleState::TitleState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} -CTitleState::~CTitleState() +TitleState::~TitleState() { // Empty } -bool CTitleState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) +bool TitleState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) { m_graphicsSystem = graphicsSystem; m_inputProvider = inputProvider; @@ -25,7 +26,7 @@ bool CTitleState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputPro // TODO Refactor, camera movement should be implemented with a single camera // and camera controllers. - m_camera = std::make_shared( + m_camera = std::make_shared( glm::vec3(-4.4f, 5.f, 14.5), glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); @@ -35,24 +36,24 @@ bool CTitleState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputPro m_scene = m_graphicsSystem->createScene(); // Load scene from file - LOG_INFO("Loading scene from file %s.", m_sceneFile.c_str()); - CSceneLoader loader(*resourceManager); + logi("Loading scene from file {}.", m_sceneFile.c_str()); + SceneLoader loader(*resourceManager); if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) { - LOG_ERROR("Failed to load scene file %s.", m_sceneFile.c_str()); + loge("Failed to load scene file {}.", m_sceneFile.c_str()); return false; } return true; } -void CTitleState::onEnter() +void TitleState::onEnter() { m_fadeInTime = 3.f; m_graphicsSystem->setActiveCamera(m_camera.get()); m_graphicsSystem->setActiveScene(m_scene); } -bool CTitleState::update(float dtime) +bool TitleState::update(float dtime) { // Ignore user input for some time if (m_fadeInTime > 0.0f) @@ -71,9 +72,9 @@ bool CTitleState::update(float dtime) return true; } -void CTitleState::onExit() +void TitleState::onExit() { // Nothing } -const std::string &CTitleState::getNextState() const { return gameStr; } \ No newline at end of file +const std::string &TitleState::getNextState() const { return gameStr; } \ No newline at end of file diff --git a/Demo/CG2015/source/state/CTitleState.h b/Demo/CG2015/source/state/TitleState.h similarity index 53% rename from Demo/CG2015/source/state/CTitleState.h rename to Demo/CG2015/source/state/TitleState.h index 54e1147..207ee12 100644 --- a/Demo/CG2015/source/state/CTitleState.h +++ b/Demo/CG2015/source/state/TitleState.h @@ -1,28 +1,28 @@ #pragma once -#include "application/game/CGameSystem.h" -#include "application/game/IGameState.h" +#include "kern/game/GameSystem.h" +#include "kern/game/IGameState.h" -#include "graphics/animation/CAnimationWorld.h" +#include "kern/graphics/animation/AnimationWorld.h" -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IScene.h" -#include "graphics/input/IInputProvider.h" -#include "graphics/resource/IResourceManager.h" +#include "kern/graphics/input/IInputProvider.h" +#include "kern/resource/IResourceManager.h" /** * \brief Title state, similar to demo state with static camera. */ -class CTitleState : public IGameState +class TitleState : public IGameState { public: - CTitleState(const std::string &sceneFile); - ~CTitleState(); + TitleState(const std::string &sceneFile); + ~TitleState(); - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); void onEnter(); bool update(float dtime); @@ -37,6 +37,6 @@ class CTitleState : public IGameState IScene *m_scene = nullptr; IGraphicsSystem *m_graphicsSystem = nullptr; IResourceManager *m_resourceManager = nullptr; - CAnimationWorld m_animationWorld; + AnimationWorld m_animationWorld; std::string m_nextState; /**< Next state. */ }; diff --git a/Demo/CG2015/source/state/WinState.cpp b/Demo/CG2015/source/state/WinState.cpp new file mode 100644 index 0000000..438ae82 --- /dev/null +++ b/Demo/CG2015/source/state/WinState.cpp @@ -0,0 +1,71 @@ +#include "state/WinState.h" + +#define GLFW_INCLUDE_NONE +#include +#include + +#include "kern/graphics/camera/FirstPersonCamera.h" +#include "kern/graphics/io/SceneLoader.h" + +const std::string gameStr = "game"; + +WinState::WinState(const std::string &sceneFile) : m_sceneFile(sceneFile) {} + +WinState::~WinState() +{ + // Empty +} + +bool WinState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) +{ + m_graphicsSystem = graphicsSystem; + m_inputProvider = inputProvider; + m_resourceManager = resourceManager; + + // TODO Refactor, camera movement should be implemented with a single camera + // and camera controllers. + m_camera = std::make_shared(glm::vec3(-4.4f, 5.f, 14.5), glm::vec3(0.f, 0.f, 0.f), + glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); + + m_camera->getFeatureInfoForWrite().godRayActive = false; + + // Create new scene object + m_scene = m_graphicsSystem->createScene(); + + // Load scene from file + logi("Loading scene from file {}.", m_sceneFile.c_str()); + SceneLoader loader(*resourceManager); + if (!loader.load(m_sceneFile, *m_scene, m_animationWorld)) + { + loge("Failed to load scene file {}.", m_sceneFile.c_str()); + return false; + } + return true; +} + +void WinState::onEnter() +{ + m_fadeInTime = 3.f; + m_graphicsSystem->setActiveCamera(m_camera.get()); + m_graphicsSystem->setActiveScene(m_scene); +} + +bool WinState::update(float dtime) +{ + // Ignore user input for some time + if (m_fadeInTime > 0.0f) + { + m_fadeInTime -= dtime; + } + + m_animationWorld.update(dtime); + return true; +} + +void WinState::onExit() +{ + // Nothing +} + +const std::string &WinState::getNextState() const { return gameStr; } \ No newline at end of file diff --git a/Demo/CG2015/source/state/CWinState.h b/Demo/CG2015/source/state/WinState.h similarity index 51% rename from Demo/CG2015/source/state/CWinState.h rename to Demo/CG2015/source/state/WinState.h index 612bf96..5b1f765 100644 --- a/Demo/CG2015/source/state/CWinState.h +++ b/Demo/CG2015/source/state/WinState.h @@ -1,26 +1,26 @@ #pragma once -#include "application/game/CGameSystem.h" -#include "application/game/IGameState.h" +#include "kern/game/GameSystem.h" +#include "kern/game/IGameState.h" -#include "graphics/animation/CAnimationWorld.h" -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IScene.h" -#include "graphics/input/IInputProvider.h" -#include "graphics/resource/IResourceManager.h" +#include "kern/graphics/animation/AnimationWorld.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/input/IInputProvider.h" +#include "kern/resource/IResourceManager.h" /** * \brief Lose state, similar to demo state with static camera. */ -class CWinState : public IGameState +class WinState : public IGameState { public: - CWinState(const std::string &sceneFile); - ~CWinState(); + WinState(const std::string &sceneFile); + ~WinState(); - bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); + bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); void onEnter(); bool update(float dtime); @@ -28,13 +28,13 @@ class CWinState : public IGameState const std::string &getNextState() const; private: - float m_fadeInTime; + float m_fadeInTime = 1.f; std::string m_sceneFile; IInputProvider *m_inputProvider = nullptr; std::shared_ptr m_camera = nullptr; IScene *m_scene = nullptr; IGraphicsSystem *m_graphicsSystem = nullptr; IResourceManager *m_resourceManager = nullptr; - CAnimationWorld m_animationWorld; + AnimationWorld m_animationWorld; std::string m_nextState; /**< Next state. */ }; diff --git a/Demo/CMakeLists.txt b/Demo/CMakeLists.txt index 129a8b7..97cf358 100644 --- a/Demo/CMakeLists.txt +++ b/Demo/CMakeLists.txt @@ -1,7 +1,6 @@ -cmake_minimum_required (VERSION 3.0.0) -project (Demo) +# Demos -set (CXX_STANDARD_REQUIRED ON) - -add_subdirectory (RTR2014) -add_subdirectory (CG2015) \ No newline at end of file +add_subdirectory(RenderDemo) +add_subdirectory(LuaDemo) +add_subdirectory(RTR2014) +add_subdirectory(CG2015) \ No newline at end of file diff --git a/Demo/LuaDemo/CMakeLists.txt b/Demo/LuaDemo/CMakeLists.txt new file mode 100644 index 0000000..b7ec32f --- /dev/null +++ b/Demo/LuaDemo/CMakeLists.txt @@ -0,0 +1,27 @@ +project(LuaDemo) + +file (GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp +) +# Source group to preserve folder structure in ide +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) + +add_executable (${PROJECT_NAME} ${SOURCE_FILES}) + +set_target_properties (${PROJECT_NAME} PROPERTIES + CXX_STANDARD 17 + FOLDER "Demo" +) + +target_link_libraries (${PROJECT_NAME} + PRIVATE lua::lua +) + +target_include_directories (${PROJECT_NAME} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source +) + +# Copy runtime data +file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderCommon.cpp b/Demo/LuaDemo/data/hello.lua similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderCommon.cpp rename to Demo/LuaDemo/data/hello.lua diff --git a/Demo/LuaDemo/source/Main.cpp b/Demo/LuaDemo/source/Main.cpp new file mode 100644 index 0000000..afbf6fa --- /dev/null +++ b/Demo/LuaDemo/source/Main.cpp @@ -0,0 +1,55 @@ +#include +#include +#include + +int println(lua_State *s) +{ + std::cout << lua_tostring(s, 1) << std::endl; + return 0; +} + +class LuaState +{ + public: + LuaState() + { + state = luaL_newstate(); + luaL_openlibs(state); + lua_pushcfunction(state, println); + lua_setglobal(state, "myprintln"); + } + + ~LuaState() { lua_close(state); } + + lua_State *state = nullptr; +}; + +void onError(lua_State *state) +{ + std::cout << "Error: " << lua_tostring(state, -1) << std::endl; + lua_pop(state, 1); + throw std::runtime_error("Error"); +} + +void eval(const std::string &line) +{ + LuaState state; + + int err = luaL_loadstring(state.state, line.c_str()); + std::cout << "Eval string: " << line << std::endl; + if (err) + onError(state.state); + + err = lua_pcall(state.state, 0, 0, 0); + if (err) + onError(state.state); +} + +int main(int argc, char **argv) { + std::string line; + std::getline(std::cin, line); + eval(line); + + return 0; + +} \ No newline at end of file diff --git a/Demo/RTR2014/CMakeLists.txt b/Demo/RTR2014/CMakeLists.txt index af4365b..258e796 100644 --- a/Demo/RTR2014/CMakeLists.txt +++ b/Demo/RTR2014/CMakeLists.txt @@ -1,26 +1,25 @@ -cmake_minimum_required (VERSION 3.0.0) -project (RTR2014) +# Realtime Rendering project from 2014 +project(RTR2014) -file (GLOB_RECURSE SOURCE_FILES +file (GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hxx ) +# Source group to preserve folder structure in ide +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) add_executable (${PROJECT_NAME} ${SOURCE_FILES}) set_target_properties (${PROJECT_NAME} PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 17 + FOLDER "Demo" ) -# Link dependencies target_link_libraries (${PROJECT_NAME} - LINK_PRIVATE Application + PRIVATE EngineLib ) -# Includes target_include_directories (${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source ) diff --git a/Demo/RTR2014/data/audio/electric-windmill-74468.mp3 b/Demo/RTR2014/data/audio/electric-windmill-74468.mp3 new file mode 100644 index 0000000..ed1817f Binary files /dev/null and b/Demo/RTR2014/data/audio/electric-windmill-74468.mp3 differ diff --git a/Demo/RTR2014/data/audio/inspiring-cinematic-ambient-116199.mp3 b/Demo/RTR2014/data/audio/inspiring-cinematic-ambient-116199.mp3 new file mode 100644 index 0000000..6f1d478 Binary files /dev/null and b/Demo/RTR2014/data/audio/inspiring-cinematic-ambient-116199.mp3 differ diff --git a/Demo/RTR2014/data/demo.ini b/Demo/RTR2014/data/demo.ini index 85a8a48..b74c561 100644 --- a/Demo/RTR2014/data/demo.ini +++ b/Demo/RTR2014/data/demo.ini @@ -5,6 +5,8 @@ [scene] # Defines the scene file to be loaded. # Needs either absolute path or relative path in respect to the executable. +#file=data/scene/test/duck_1.json +#file=data/scene/test/test_1.json file=data/scene/all.json [renderer] diff --git a/Demo/RTR2014/data/image/red.png b/Demo/RTR2014/data/image/red.png new file mode 100644 index 0000000..dd7f06a Binary files /dev/null and b/Demo/RTR2014/data/image/red.png differ diff --git a/Demo/RTR2014/data/material/brick_1_diffuse.ini b/Demo/RTR2014/data/material/brick_1_diffuse.ini index aa41b8e..2b16919 100644 --- a/Demo/RTR2014/data/material/brick_1_diffuse.ini +++ b/Demo/RTR2014/data/material/brick_1_diffuse.ini @@ -1,2 +1,2 @@ [base] -file=data/images/brick_1_diffuse.png \ No newline at end of file +file=data/image/brick_1_diffuse.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/brick_1_diffuse.json b/Demo/RTR2014/data/material/brick_1_diffuse.json index 93b9c96..255f074 100644 --- a/Demo/RTR2014/data/material/brick_1_diffuse.json +++ b/Demo/RTR2014/data/material/brick_1_diffuse.json @@ -1,3 +1,3 @@ { - "diffuse" : "data/images/brick_1_diffuse.png" + "diffuse" : "data/image/brick_1_diffuse.png" } \ No newline at end of file diff --git a/Demo/RTR2014/data/material/brick_1_diffuse_normal.ini b/Demo/RTR2014/data/material/brick_1_diffuse_normal.ini index 016934f..70149d5 100644 --- a/Demo/RTR2014/data/material/brick_1_diffuse_normal.ini +++ b/Demo/RTR2014/data/material/brick_1_diffuse_normal.ini @@ -1,5 +1,5 @@ [diffuse] -file=data/images/brick_1_diffuse.png +file=data/image/brick_1_diffuse.png [normal] -file=data/images/brick_1_normal.png \ No newline at end of file +file=data/image/brick_1_normal.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/brick_1_diffuse_normal_specular.ini b/Demo/RTR2014/data/material/brick_1_diffuse_normal_specular.ini index 2578919..ff30c39 100644 --- a/Demo/RTR2014/data/material/brick_1_diffuse_normal_specular.ini +++ b/Demo/RTR2014/data/material/brick_1_diffuse_normal_specular.ini @@ -1,8 +1,8 @@ [diffuse] -file=data/images/brick_1_diffuse.png +file=data/image/brick_1_diffuse.png [normal] -file=data/images/brick_1_normal.png +file=data/image/brick_1_normal.png [specular] -file=data/images/brick_1_specular.png \ No newline at end of file +file=data/image/brick_1_specular.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/brick_1_diffuse_specular.ini b/Demo/RTR2014/data/material/brick_1_diffuse_specular.ini index 56cf8cd..09beb72 100644 --- a/Demo/RTR2014/data/material/brick_1_diffuse_specular.ini +++ b/Demo/RTR2014/data/material/brick_1_diffuse_specular.ini @@ -1,5 +1,5 @@ [diffuse] -file=data/images/brick_1_diffuse.png +file=data/image/brick_1_diffuse.png [specular] -file=data/images/brick_1_specular.png \ No newline at end of file +file=data/image/brick_1_specular.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/duck_1_diffuse.ini b/Demo/RTR2014/data/material/duck_1_diffuse.ini index 733af7a..cec296c 100644 --- a/Demo/RTR2014/data/material/duck_1_diffuse.ini +++ b/Demo/RTR2014/data/material/duck_1_diffuse.ini @@ -1,2 +1,2 @@ [diffuse] -file=data/images/duck_1_diffuse.png \ No newline at end of file +file=data/image/duck_1_diffuse.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/metal_1_diffuse_specular.ini b/Demo/RTR2014/data/material/metal_1_diffuse_specular.ini index d5a8286..74a09d3 100644 --- a/Demo/RTR2014/data/material/metal_1_diffuse_specular.ini +++ b/Demo/RTR2014/data/material/metal_1_diffuse_specular.ini @@ -1,5 +1,5 @@ [diffuse] -file=data/images/metal_1_diffuse.png +file=data/image/metal_1_diffuse.png [specular] -file=data/images/metal_1_specular.png \ No newline at end of file +file=data/image/metal_1_specular.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/moss_1_diffuse.ini b/Demo/RTR2014/data/material/moss_1_diffuse.ini index 39123ea..9b8bcb3 100644 --- a/Demo/RTR2014/data/material/moss_1_diffuse.ini +++ b/Demo/RTR2014/data/material/moss_1_diffuse.ini @@ -1,2 +1,2 @@ [diffuse] -file=data/images/moss_1_diffuse.png \ No newline at end of file +file=data/image/moss_1_diffuse.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/moss_1_diffuse_normal.ini b/Demo/RTR2014/data/material/moss_1_diffuse_normal.ini index 869c378..22825b8 100644 --- a/Demo/RTR2014/data/material/moss_1_diffuse_normal.ini +++ b/Demo/RTR2014/data/material/moss_1_diffuse_normal.ini @@ -1,5 +1,5 @@ [diffuse] -file=data/images/moss_1_diffuse.png +file=data/image/moss_1_diffuse.png [normal] -file=data/images/moss_1_normal.png \ No newline at end of file +file=data/image/moss_1_normal.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/moss_1_diffuse_normal_specular.ini b/Demo/RTR2014/data/material/moss_1_diffuse_normal_specular.ini index 2132466..b59f392 100644 --- a/Demo/RTR2014/data/material/moss_1_diffuse_normal_specular.ini +++ b/Demo/RTR2014/data/material/moss_1_diffuse_normal_specular.ini @@ -1,8 +1,8 @@ [diffuse] -file=data/images/moss_1_diffuse.png +file=data/image/moss_1_diffuse.png [normal] -file=data/images/moss_1_normal.png +file=data/image/moss_1_normal.png [specular] -file=data/images/moss_1_specular.png \ No newline at end of file +file=data/image/moss_1_specular.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/moss_1_diffuse_specular.ini b/Demo/RTR2014/data/material/moss_1_diffuse_specular.ini index 869c378..22825b8 100644 --- a/Demo/RTR2014/data/material/moss_1_diffuse_specular.ini +++ b/Demo/RTR2014/data/material/moss_1_diffuse_specular.ini @@ -1,5 +1,5 @@ [diffuse] -file=data/images/moss_1_diffuse.png +file=data/image/moss_1_diffuse.png [normal] -file=data/images/moss_1_normal.png \ No newline at end of file +file=data/image/moss_1_normal.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/stone_1_diffuse_normal.ini b/Demo/RTR2014/data/material/stone_1_diffuse_normal.ini index 86fd138..1f4d35a 100644 --- a/Demo/RTR2014/data/material/stone_1_diffuse_normal.ini +++ b/Demo/RTR2014/data/material/stone_1_diffuse_normal.ini @@ -1,5 +1,5 @@ [base] -file=data/images/stone_1_diffuse.png +file=data/image/stone_1_diffuse.png [normal] -file=data/images/stone_1_normal.png \ No newline at end of file +file=data/image/stone_1_normal.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/stone_1_diffuse_normal_specular.ini b/Demo/RTR2014/data/material/stone_1_diffuse_normal_specular.ini index 9df50fd..996dcc9 100644 --- a/Demo/RTR2014/data/material/stone_1_diffuse_normal_specular.ini +++ b/Demo/RTR2014/data/material/stone_1_diffuse_normal_specular.ini @@ -1,8 +1,8 @@ [base] -file=data/images/stone_1_diffuse.png +file=data/image/stone_1_diffuse.png [normal] -file=data/images/stone_1_normal.png +file=data/image/stone_1_normal.png [specular] -file=data/images/stone_1_specular.png \ No newline at end of file +file=data/image/stone_1_specular.png \ No newline at end of file diff --git a/Demo/RTR2014/data/material/test_1.ini b/Demo/RTR2014/data/material/test_1.ini index c1279a2..921c372 100644 --- a/Demo/RTR2014/data/material/test_1.ini +++ b/Demo/RTR2014/data/material/test_1.ini @@ -1,11 +1,11 @@ [diffuse] -file=data/images/test_1_diffuse.png +file=data/image/test_1_diffuse.png [normal] -file=data/images/test_1_normal.png +file=data/image/test_1_normal.png [specular] -file=data/images/test_1_specular.png +file=data/image/test_1_specular.png [glow] -file=data/images/test_1_glow.png \ No newline at end of file +file=data/image/test_1_glow.png \ No newline at end of file diff --git a/Demo/RTR2014/data/scene/test/cave_1.json b/Demo/RTR2014/data/scene/test/cave_1.json index d23cc6a..b21f275 100644 --- a/Demo/RTR2014/data/scene/test/cave_1.json +++ b/Demo/RTR2014/data/scene/test/cave_1.json @@ -9,7 +9,7 @@ } ], "ambient_light" : { - color : [ 1, 1, 1 ], - intensity : 0.1 + "color" : [ 1, 1, 1 ], + "intensity" : 0.1 } } \ No newline at end of file diff --git a/Demo/RTR2014/data/scene/test/duck_1.json b/Demo/RTR2014/data/scene/test/duck_1.json index 4bc5931..d260269 100644 --- a/Demo/RTR2014/data/scene/test/duck_1.json +++ b/Demo/RTR2014/data/scene/test/duck_1.json @@ -7,5 +7,9 @@ "rotation" : [ 0 , 0, 0 ], "scale" : [ 2, 2, 2 ] } - ] + ], + "ambient_light" : { + "color" : [ 1, 1, 1 ], + "intensity" : 0.9 + } } \ No newline at end of file diff --git a/Demo/RTR2014/data/scene/test/test_1.json b/Demo/RTR2014/data/scene/test/test_1.json index 7305269..0873cb1 100644 --- a/Demo/RTR2014/data/scene/test/test_1.json +++ b/Demo/RTR2014/data/scene/test/test_1.json @@ -63,5 +63,9 @@ "rotation" : [ 0 , 0, 0 ], "scale" : [ 1, 1, 1 ] } - ] + ], + "ambient_light" : { + "color" : [ 1, 1, 1 ], + "intensity" : 0.5 + } } \ No newline at end of file diff --git a/Demo/RTR2014/source/CCameraController.cpp b/Demo/RTR2014/source/CameraController.cpp similarity index 75% rename from Demo/RTR2014/source/CCameraController.cpp rename to Demo/RTR2014/source/CameraController.cpp index 4dd74e8..1123509 100644 --- a/Demo/RTR2014/source/CCameraController.cpp +++ b/Demo/RTR2014/source/CameraController.cpp @@ -1,20 +1,20 @@ -#include "CCameraController.h" - -#include +#include "CameraController.h" +#define GLFW_INCLUDE_NONE #include -#include - -#include -#include -#include +#include +#include +#include +#include +#include -#include "graphics/graphics/camera/IControllableCamera.h" -#include "graphics/input/IInputProvider.h" +#include +#include +#include -CCameraController::CCameraController() {} +CameraController::CameraController() {} -CCameraController::~CCameraController() +CameraController::~CameraController() { if (m_inputProvider != nullptr) { @@ -22,12 +22,9 @@ CCameraController::~CCameraController() } } -void CCameraController::setCamera(std::shared_ptr camera) -{ - m_camera = camera; -} +void CameraController::setCamera(std::shared_ptr camera) { m_camera = camera; } -void CCameraController::setInputProvider(IInputProvider* provider) +void CameraController::setInputProvider(IInputProvider* provider) { if (m_inputProvider != nullptr) { @@ -42,51 +39,54 @@ void CCameraController::setInputProvider(IInputProvider* provider) } } -bool CCameraController::loadSequence(std::string file) +bool CameraController::loadSequence(std::string file) { m_sequenceTime = 0; m_sequencePoints.clear(); - Json::Reader reader; - Json::Value root; + nlohmann::json root; // Load scene file std::ifstream ifs(file); if (!ifs.is_open()) { - LOG_ERROR("Failed to open json file %s.", file.c_str()); + loge("Failed to open json file {}.", file.c_str()); return false; } // Parse json data - if (!reader.parse(ifs, root)) + try { - LOG_ERROR("Failed to load scene file %s with error %s.", file.c_str(), - reader.getFormattedErrorMessages().c_str()); + ifs >> root; + } + catch (const std::exception& e) + { + loge("Failed to load scene file {} with error {}.", file.c_str(), e.what()); return false; } // Read done, close file ifs.close(); - Json::Value node = root["positions"]; - // Node empty? - if (node.empty()) + if (root.find("positions") == root.end()) { - LOG_INFO("Missing or empty 'positions' node. No scene objects are loaded."); + logi("Missing or empty 'positions' node. No scene objects are loaded."); return true; } + nlohmann::json node = root.at("positions"); + // Node is array type - if (!node.isArray()) + if (!node.is_array()) { - LOG_ERROR("The node 'positions' must be array type."); + loge("The node 'positions' must be array type."); return false; } bool success = true; - for (unsigned int i = 0; i < node.size(); ++i) + int i = 0; + for (auto it : node) { glm::vec3 position; glm::vec3 orientation; @@ -94,50 +94,51 @@ bool CCameraController::loadSequence(std::string file) bool fxaaActive; bool fogActive; - if (!load(node[i], "position", position)) + if (!load(it, "position", position)) { - LOG_ERROR("Failed loading node 'position' for element #%i.", i); + loge("Failed loading node 'position' for element #{}.", i); success = false; break; } - if (!load(node[i], "orientation", orientation)) + if (!load(it, "orientation", orientation)) { - LOG_ERROR("Failed loading node 'orientation' for element #%i.", i); + loge("Failed loading node 'orientation' for element #{}.", i); success = false; break; } - if (!load(node[i], "timestamp", timestamp)) + if (!load(it, "timestamp", timestamp)) { - LOG_ERROR("Failed loading node 'timestamp' for element #%i.", i); + loge("Failed loading node 'timestamp' for element #{}.", i); success = false; break; } - if (!load(node[i], "fxaa", fxaaActive)) + if (!load(it, "fxaa", fxaaActive)) { - LOG_ERROR("Failed loading node 'fxaa' for element #%i.", i); + loge("Failed loading node 'fxaa' for element #{}.", i); success = false; break; } - if (!load(node[i], "fog", fogActive)) + if (!load(it, "fog", fogActive)) { - LOG_ERROR("Failed loading node 'fog' for element #%i.", i); + loge("Failed loading node 'fog' for element #{}.", i); success = false; break; } SequencePoint sp{position, glm::normalize(orientation), timestamp, fxaaActive, fogActive}; m_sequencePoints.push_back(sp); + ++i; } m_isRunningSequence = success; return success; } -void CCameraController::animate(float dt) +void CameraController::animate(float dt) { if (m_inputProvider != nullptr && m_camera != nullptr) { @@ -154,12 +155,12 @@ void CCameraController::animate(float dt) } } -void CCameraController::animateFeatures(float dt) +void CameraController::animateFeatures(float dt) { - // tODO + // TODO } -void CCameraController::animateSequence(float dt) +void CameraController::animateSequence(float dt) { if (m_inputProvider->isKeyPressed(GLFW_KEY_C)) { @@ -210,7 +211,7 @@ void CCameraController::animateSequence(float dt) m_camera->getFeatureInfoForWrite().fxaaActive = before.fxaaActive; } -void CCameraController::animateManual(float dt) +void CameraController::animateManual(float dt) { float walkingModifier = 1.0f; if (m_inputProvider->isKeyPressed(GLFW_KEY_SPACE)) @@ -265,7 +266,7 @@ void CCameraController::animateManual(float dt) } } -void CCameraController::handleKeyEvent(EKeyEventType type, int keyCode) +void CameraController::handleKeyEvent(EKeyEventType type, int keyCode) { if (type != EKeyEventType::KEY_PRESSED) { @@ -350,7 +351,7 @@ void CCameraController::handleKeyEvent(EKeyEventType type, int keyCode) } } -void CCameraController::handleMouseMovementEvent(int x, int y) +void CameraController::handleMouseMovementEvent(int x, int y) { m_camera->pitch((y - m_lastY) * m_speed / 1000); m_camera->yaw(-(x - m_lastX) * m_speed / 1000); @@ -359,12 +360,12 @@ void CCameraController::handleMouseMovementEvent(int x, int y) m_lastY = y; } -void CCameraController::handleMouseButtonEvent(EMouseButtonEventType type, int buttonCode) +void CameraController::handleMouseButtonEvent(EMouseButtonEventType type, int buttonCode) { // TODO } -void CCameraController::handleResizeEvent(int width, int height) +void CameraController::handleResizeEvent(int width, int height) { m_camera->setProjection(m_camera->getFieldOfView(), (float)width / height, m_camera->getZNear(), m_camera->getZFar()); diff --git a/Demo/RTR2014/source/CCameraController.h b/Demo/RTR2014/source/CameraController.h similarity index 85% rename from Demo/RTR2014/source/CCameraController.h rename to Demo/RTR2014/source/CameraController.h index f85bdb4..e543d7b 100644 --- a/Demo/RTR2014/source/CCameraController.h +++ b/Demo/RTR2014/source/CameraController.h @@ -1,21 +1,20 @@ #pragma once -#include -#include +#include +#include #include - -#include "graphics/graphics/window/CGlfwWindow.h" -#include "graphics/input/IInputListener.h" +#include +#include class IControllableCamera; class IInputProvider; -class CCameraController : public IInputListener, public IGlfwWindowListener +class CameraController : public IInputListener, public IWindowListener { public: - CCameraController(); - ~CCameraController(); + CameraController(); + ~CameraController(); void setCamera(std::shared_ptr camera); void setInputProvider(IInputProvider* provider); diff --git a/Demo/RTR2014/source/Main.cpp b/Demo/RTR2014/source/Main.cpp index c5150e8..27444d9 100644 --- a/Demo/RTR2014/source/Main.cpp +++ b/Demo/RTR2014/source/Main.cpp @@ -1,14 +1,25 @@ +#include + #include "RTRDemo.h" int main(int argc, const char** argv) { - RTRDemo demo; +#ifndef NDEBUG + fmtlog::setLogLevel(fmtlog::DBG); +#endif + fmtlog::startPollingThread(); - int result = demo.init("data/demo.ini"); - if (result != 0) + try { - return result; - } + RTRDemo demo; + if (demo.init("data/demo.ini") != 0) + return EXIT_FAILURE; - return demo.run(); + return demo.run(); + } + catch (const std::exception& e) + { + loge("{}", e.what()); + return EXIT_FAILURE; + } } \ No newline at end of file diff --git a/Demo/RTR2014/source/RTRDemo.cpp b/Demo/RTR2014/source/RTRDemo.cpp index 2c736a1..74eac57 100644 --- a/Demo/RTR2014/source/RTRDemo.cpp +++ b/Demo/RTR2014/source/RTRDemo.cpp @@ -1,114 +1,102 @@ #include "RTRDemo.h" +#include + #include #include - -// Debug -#include -#include -#include - -// Graphics -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/renderer/debug/RendererDebug.h" - +#define GLFW_INCLUDE_NONE #include - -#include "graphics/graphics/camera/CFirstPersonCamera.h" -#include "graphics/graphics/camera/CFreeCamera.h" - -// Renderer types -#include "graphics/graphics/renderer/CDeferredRenderer.h" -#include "graphics/graphics/renderer/CForwardRenderer.h" - -// Resource system -#include "graphics/resource/Resource.h" - -#include "graphics/graphics/resource/CGraphicsResourceManager.h" -#include "graphics/graphics/scene/CScene.h" -#include "graphics/graphics/window/CGlfwWindow.h" - -#include "graphics/graphics/CDebugInfoDisplay.h" -#include "graphics/input/provider/CGlfwInputProvider.h" -#include "graphics/io/CSceneLoader.h" - -#include "CCameraController.h" - -// Animation -#include "graphics/animation/CAnimationWorld.h" - -RTRDemo::RTRDemo() {} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CameraController.h" + +RTRDemo::RTRDemo() +{ + m_soundSystem = std::make_unique("data/audio"); + m_bgMusic = m_soundSystem->createEmitter(); + m_bgSfx = m_soundSystem->createEmitter(); +} RTRDemo::~RTRDemo() {} int RTRDemo::init(const std::string& configFile) { - // Init log file - std::string logFile = "log/" + createTimeStamp() + ".log"; - if (!CLogger::initLogFile(logFile)) - { - LOG_WARNING("Failed to create log file at %s.", logFile.c_str()); - } - - m_debugInfo = std::make_shared(); - CLogger::addListener(m_debugInfo.get()); - if (!m_config.load(configFile)) { - LOG_WARNING("Failed to load config file %s, starting with default settings.", - configFile.c_str()); + logw("Failed to load config file {}, starting with default settings.", configFile.c_str()); } // Create window for rendering if (!initWindow()) { - LOG_ERROR("Failed to initialize window."); + loge("Failed to initialize window."); return 1; } - m_inputProvider = std::make_shared(m_window->getGlfwHandle()); + m_inputProvider = std::make_shared(m_window->getGlfwHandle()); // Create resource manager - m_resourceManager.reset(createResourceManager()); + m_resourceManager = std::make_shared(); if (m_resourceManager == nullptr) { - LOG_ERROR("Failed to initialize resource manager."); + loge("Failed to initialize resource manager."); return 1; } // Create animation world - m_animationWorld = std::make_shared(); + m_animationWorld = std::make_shared(); // Graphics resource manager, listens to resource manager - CGraphicsResourceManager* manager = new CGraphicsResourceManager; + GraphicsResourceManager* manager = new GraphicsResourceManager; m_resourceManager->addResourceListener(manager); m_graphicsResourceManager.reset(manager); // Create renderer if (!initRenderer()) { - LOG_ERROR("Failed to initialize renderer."); + loge("Failed to initialize renderer."); return 1; } if (!initScene()) { - LOG_ERROR("Failed to initialize scene."); + loge("Failed to initialize scene."); return 1; } - m_camera = std::make_shared( - glm::vec3(0.5f, 0.f, 0.5f), glm::vec3(0.f, 0.f, 1.f), glm::vec3(0.f, 1.f, 0.f), 45.f, - 4.f / 3.f, 0.01f, 1000.f); + m_camera = std::make_shared(glm::vec3(0.5f, 0.f, 0.5f), glm::vec3(0.f, 0.f, 1.f), + glm::vec3(0.f, 1.f, 0.f), 45.f, 4.f / 3.f, 0.01f, 1000.f); - m_cameraController = std::make_shared(); + m_cameraController = std::make_shared(); m_cameraController->setCamera(m_camera); m_cameraController->setInputProvider(m_inputProvider.get()); - m_debugInfoDisplay = std::make_shared(*m_resourceManager); - m_window->addListener(m_cameraController.get()); + // Sound + m_soundSystem->getManager()->registerSound("demobgm", "inspiring-cinematic-ambient-116199.mp3"); + auto soundBgm = m_soundSystem->getManager()->getSound("demobgm"); + m_bgMusic->setSound(soundBgm); + m_bgMusic->setVolume(0.8); + m_bgMusic->setLooping(true); + + m_soundSystem->getManager()->registerSound("demosfx", "electric-windmill-74468.mp3"); + auto soundSfx = m_soundSystem->getManager()->getSound("demosfx"); + m_bgSfx->setSound(soundSfx); + m_bgSfx->setVolume(0.3); + m_bgSfx->setLooping(true); + return 0; } @@ -128,6 +116,8 @@ int RTRDemo::run() bool displayDebugInfo = false; m_window->toggleMouseCapture(); + m_bgMusic->play(); + m_bgSfx->play(); do { @@ -174,19 +164,7 @@ int RTRDemo::run() m_cameraController->animate((float)timeDiff); - m_renderer->draw(*m_scene.get(), *m_camera.get(), *m_window.get(), - *m_graphicsResourceManager.get()); - - if (displayDebugInfo) - { - m_debugInfo->setValue("TimeDiff", std::to_string(timeDiff)); - m_debugInfo->setValue("Camera x", std::to_string(m_camera->getPosition().x)); - m_debugInfo->setValue("Camera y", std::to_string(m_camera->getPosition().y)); - m_debugInfo->setValue("Camera z", std::to_string(m_camera->getPosition().z)); - m_debugInfo->setValue("FPS", std::to_string(lastFrameCount)); - - m_debugInfoDisplay->draw(*m_debugInfo.get(), true); - } + m_renderer->draw(*m_scene.get(), *m_camera.get(), *m_window.get(), *m_graphicsResourceManager.get()); // Perform animation update m_animationWorld->update((float)timeDiff); @@ -223,22 +201,22 @@ bool RTRDemo::initWindow() return true; } - LOG_INFO("Initializing application window."); + logi("Initializing application window."); // Read config values unsigned int width = m_config.getValue("window", "width", 800); unsigned int height = m_config.getValue("window", "height", 600); std::string title = m_config.getValue("window", "title", "Demo"); - LOG_INFO("Window width: %u.", width); - LOG_INFO("Window height: %u.", height); - LOG_INFO("Window title: %s.", title.c_str()); + logi("Window width: {}.", width); + logi("Window height: {}.", height); + logi("Window title: {}.", title); // Create window - CGlfwWindow* window = new CGlfwWindow; + Window* window = new Window; if (!window->init(width, height, title)) { - LOG_ERROR("Failed to initialize GLFW window wrapper."); + loge("Failed to initialize GLFW window wrapper."); delete window; return false; } @@ -252,31 +230,31 @@ bool RTRDemo::initRenderer() { if (m_renderer != nullptr || m_deferredRenderer != nullptr || m_forwardRenderer != nullptr) { - LOG_INFO("Renderer already initialized and re-initialization is not supported."); + logi("Renderer already initialized and re-initialization is not supported."); return true; } // Initialize deferred renderer - LOG_INFO("Initializing deferred renderer."); - m_deferredRenderer.reset(CDeferredRenderer::create(*m_resourceManager)); + logi("Initializing deferred renderer."); + m_deferredRenderer.reset(DeferredRenderer::create(*m_resourceManager)); if (m_deferredRenderer == nullptr) { - LOG_ERROR("Failed to initialize deferred renderer."); + loge("Failed to initialize deferred renderer."); return false; } // Initialize forward renderer - LOG_INFO("Initializing forward renderer."); - m_forwardRenderer.reset(CForwardRenderer::create(*m_resourceManager)); + logi("Initializing forward renderer."); + m_forwardRenderer.reset(ForwardRenderer::create(*m_resourceManager)); if (m_forwardRenderer == nullptr) { - LOG_ERROR("Failed to initialize forward renderer."); + loge("Failed to initialize forward renderer."); return false; } // Set renderer std::string rendererType = m_config.getValue("renderer", "type", "forward"); - LOG_INFO("Initial renderer type set to %s.", rendererType.c_str()); + logi("Initial renderer type set to {}.", rendererType.c_str()); // Set renderer object if (rendererType == "forward") @@ -290,15 +268,14 @@ bool RTRDemo::initRenderer() else { // Should not happen as default renderer is set to forward in config call - LOG_WARNING("Invalid renderer type %s specified. Fallback to forward renderer.", - rendererType.c_str()); + logw("Invalid renderer type {} specified. Fallback to forward renderer.", rendererType.c_str()); m_renderer = m_forwardRenderer; } // Initialize renderer resources if (m_renderer == nullptr) { - LOG_ERROR("Failed to initialize renderer."); + loge("Failed to initialize renderer."); return false; } return true; @@ -306,15 +283,15 @@ bool RTRDemo::initRenderer() bool RTRDemo::initScene() { - m_scene = std::make_shared(m_graphicsResourceManager.get()); - CSceneLoader loader(*m_resourceManager); + m_scene = std::make_shared(m_graphicsResourceManager.get()); + SceneLoader loader(*m_resourceManager); // Get startup scene from config std::string sceneFile = m_config.getValue("scene", "file", "data/scene/test_1.json"); - LOG_INFO("Loading initial scene from file %s.", sceneFile.c_str()); + logi("Loading initial scene from file {}.", sceneFile.c_str()); if (!loader.load(sceneFile, *m_scene, *m_animationWorld)) { - LOG_ERROR("Failed to load scene file %s.", sceneFile.c_str()); + loge("Failed to load scene file {}.", sceneFile.c_str()); m_scene = nullptr; return false; } diff --git a/Demo/RTR2014/source/RTRDemo.h b/Demo/RTR2014/source/RTRDemo.h index 55fa3e3..c4898d7 100644 --- a/Demo/RTR2014/source/RTRDemo.h +++ b/Demo/RTR2014/source/RTRDemo.h @@ -1,32 +1,22 @@ #pragma once +#include + #include #include #include -#include - -// GLFW -struct GLFWwindow; - -// Graphics -class CGlfwWindow; +class Window; class IRenderer; class IScene; - -// Resource class IResourceManager; - -// Animation class IInputProvider; class IControllableCamera; -class CCameraController; +class CameraController; class IGraphicsResourceManager; -class CAnimationWorld; - -// Debug -class CDebugInfo; -class CDebugInfoDisplay; +class AnimationWorld; +class SoundSystem; +class SoundEmitter; /** * \brief Demo application class. @@ -52,29 +42,26 @@ class RTRDemo bool initRenderer(); bool initScene(); - void updateAnimation(float timeDiff); + IniFile m_config; - CIniFile m_config; - - std::shared_ptr m_resourceManager = - nullptr; /**< Resource loader and manager. */ + std::shared_ptr m_resourceManager = nullptr; /**< Resource loader and manager. */ std::shared_ptr m_graphicsResourceManager = nullptr; /**< Resource manager for graphics resources. */ - std::shared_ptr m_window = nullptr; + std::shared_ptr m_window = nullptr; std::shared_ptr m_inputProvider = nullptr; - std::shared_ptr m_renderer = nullptr; /**< Active renderer. */ - std::shared_ptr m_deferredRenderer = nullptr; /**< Deferred renderer. */ - std::shared_ptr m_forwardRenderer = nullptr; /**< Forward renderer. */ - std::shared_ptr m_scene = nullptr; /**< Active scene. */ - std::shared_ptr m_camera = nullptr; /**< Active camera. */ - std::shared_ptr m_cameraController = nullptr; /**< Camera controller. */ - - std::shared_ptr m_debugInfo = nullptr; /**< Debug information storage. */ - std::shared_ptr m_debugInfoDisplay = - nullptr; /**< Debug information renderer. */ + std::shared_ptr m_renderer = nullptr; /**< Active renderer. */ + std::shared_ptr m_deferredRenderer = nullptr; /**< Deferred renderer. */ + std::shared_ptr m_forwardRenderer = nullptr; /**< Forward renderer. */ + std::shared_ptr m_scene = nullptr; /**< Active scene. */ + std::shared_ptr m_camera = nullptr; /**< Active camera. */ + std::shared_ptr m_cameraController = nullptr; /**< Camera controller. */ // Animation - std::shared_ptr m_animationWorld; + std::shared_ptr m_animationWorld; + // Sound + std::unique_ptr m_soundSystem; + std::shared_ptr m_bgMusic; + std::shared_ptr m_bgSfx; }; diff --git a/Demo/RenderDemo/CMakeLists.txt b/Demo/RenderDemo/CMakeLists.txt new file mode 100644 index 0000000..d832076 --- /dev/null +++ b/Demo/RenderDemo/CMakeLists.txt @@ -0,0 +1,27 @@ +# Educational project for learning 3d rendering +project(RenderDemo) + +file (GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp +) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) + +add_executable (${PROJECT_NAME} ${SOURCE_FILES}) + +set_target_properties (${PROJECT_NAME} PROPERTIES + CXX_STANDARD 17 + FOLDER "Demo" +) + +target_link_libraries (${PROJECT_NAME} + PRIVATE EngineLib +) + +target_include_directories (${PROJECT_NAME} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source +) + +# Copy runtime data +file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file diff --git a/Demo/RenderDemo/data/backpack/ao.jpg b/Demo/RenderDemo/data/backpack/ao.jpg new file mode 100644 index 0000000..11a2aee Binary files /dev/null and b/Demo/RenderDemo/data/backpack/ao.jpg differ diff --git a/Demo/RenderDemo/data/backpack/backpack.mtl b/Demo/RenderDemo/data/backpack/backpack.mtl new file mode 100644 index 0000000..159cf11 --- /dev/null +++ b/Demo/RenderDemo/data/backpack/backpack.mtl @@ -0,0 +1,16 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl Scene_-_Root +Ns 225.000000 +Ka 1.000000 1.000000 1.000000 +Kd 0.800000 0.800000 0.800000 +Ks 0.500000 0.500000 0.500000 +Ke 0.0 0.0 0.0 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd diffuse.jpg +map_Kn normal.jpg +map_Ks specular.jpg + diff --git a/Demo/RenderDemo/data/backpack/backpack.obj b/Demo/RenderDemo/data/backpack/backpack.obj new file mode 100644 index 0000000..c067a11 --- /dev/null +++ b/Demo/RenderDemo/data/backpack/backpack.obj @@ -0,0 +1,199481 @@ +# Blender v2.80 (sub 44) OBJ File: '' +# www.blender.org +mtllib backpack.mtl +o Cube.028__0 +v -0.556751 -0.023763 -0.141540 +v -0.556645 0.003057 -0.140628 +v -0.557624 0.003306 -0.148676 +v -0.557766 -0.024541 -0.149907 +v -0.556161 0.007524 -0.142045 +v -0.556644 0.008013 -0.148648 +v -0.556744 0.008562 -0.159640 +v -0.557765 0.003637 -0.159869 +v -0.557910 -0.025586 -0.161228 +v 0.565100 -0.025586 -0.161228 +v 0.564871 0.003637 -0.159869 +v 0.564651 0.003306 -0.148676 +v 0.564873 -0.024541 -0.149907 +v 0.563268 0.008562 -0.159640 +v 0.563111 0.008013 -0.148648 +v 0.562352 0.007524 -0.142045 +v 0.563113 0.003057 -0.140628 +v 0.563283 -0.023761 -0.141539 +v -0.534047 -0.023283 -0.137597 +v -0.534090 0.002997 -0.136865 +v -0.552147 0.002989 -0.137337 +v -0.552174 -0.023423 -0.138093 +v -0.534092 0.007653 -0.140079 +v -0.552088 0.007630 -0.140416 +v -0.556161 0.007524 -0.142045 +v -0.556645 0.003057 -0.140628 +v -0.556751 -0.023763 -0.141540 +v 0.538596 -0.200635 -0.169365 +v 0.557654 -0.200949 -0.169379 +v 0.557625 -0.191845 -0.157748 +v 0.538594 -0.191473 -0.157667 +v 0.563360 -0.199167 -0.169297 +v 0.563210 -0.190287 -0.157866 +v 0.562488 -0.184115 -0.150954 +v 0.557537 -0.183610 -0.149306 +v 0.538581 -0.182954 -0.148940 +v -0.534091 0.008998 -0.159620 +v -0.552163 0.008944 -0.159622 +v -0.552144 0.008371 -0.148441 +v -0.534091 0.008421 -0.148375 +v -0.556744 0.008562 -0.159640 +v -0.556644 0.008013 -0.148648 +v -0.556161 0.007524 -0.142045 +v -0.552088 0.007630 -0.140416 +v -0.534092 0.007653 -0.140079 +v 0.463542 0.008998 -0.159620 +v 0.439826 0.008998 -0.159620 +v 0.439888 0.008421 -0.148301 +v 0.463543 0.008422 -0.148375 +v 0.409472 0.008998 -0.159620 +v 0.409547 0.008426 -0.148007 +v 0.409841 0.007619 -0.136592 +v 0.440444 0.007656 -0.139720 +v 0.463553 0.007658 -0.140079 +v 0.348713 0.008998 -0.159620 +v 0.347951 0.008449 -0.147918 +v 0.255941 0.008998 -0.159620 +v 0.255143 0.008452 -0.147887 +v 0.249552 0.007908 -0.136175 +v 0.341585 0.007889 -0.136443 +v 0.136898 0.008998 -0.159620 +v 0.136457 0.008452 -0.147871 +v 0.004545 0.008998 -0.159620 +v 0.004543 0.008452 -0.147869 +v 0.004529 0.007901 -0.136032 +v 0.133362 0.007902 -0.136050 +v -0.126883 0.008998 -0.159620 +v -0.126442 0.008452 -0.147869 +v -0.245266 0.008998 -0.159620 +v -0.244426 0.008452 -0.147869 +v -0.238541 0.007901 -0.136032 +v -0.123353 0.007901 -0.136032 +v -0.339829 0.008998 -0.159620 +v -0.338944 0.008447 -0.147870 +v -0.403055 0.008998 -0.159620 +v -0.403028 0.008424 -0.147958 +v -0.402302 0.007595 -0.136078 +v -0.331605 0.007870 -0.136037 +v -0.456613 -0.198306 -0.169257 +v -0.432363 -0.199363 -0.169306 +v -0.432402 -0.190090 -0.157520 +v -0.456608 -0.189146 -0.157559 +v -0.400976 -0.211076 -0.169850 +v -0.400957 -0.201467 -0.157715 +v -0.400301 -0.188967 -0.145216 +v -0.432837 -0.180976 -0.148431 +v -0.456573 -0.180648 -0.148833 +v -0.337564 -0.239386 -0.171166 +v -0.336686 -0.230104 -0.158959 +v -0.243074 -0.274395 -0.172794 +v -0.242240 -0.265062 -0.160583 +v -0.236398 -0.255346 -0.148270 +v -0.329398 -0.221316 -0.146691 +v -0.125656 -0.302939 -0.174121 +v -0.125218 -0.293465 -0.161904 +v 0.003595 -0.314611 -0.174663 +v 0.003598 -0.305077 -0.162444 +v 0.003618 -0.293958 -0.150064 +v -0.122150 -0.282772 -0.149544 +v 0.132846 -0.302939 -0.174121 +v 0.132422 -0.293423 -0.161904 +v 0.250264 -0.274395 -0.172794 +v 0.249489 -0.264999 -0.160598 +v 0.244063 -0.254849 -0.148386 +v 0.129450 -0.282434 -0.149546 +v 0.344757 -0.239386 -0.171166 +v 0.344021 -0.230058 -0.159004 +v 0.408196 -0.211076 -0.169850 +v 0.408316 -0.201452 -0.157762 +v 0.408966 -0.188857 -0.145714 +v 0.337787 -0.220948 -0.147071 +v 0.463491 -0.022885 -0.137578 +v 0.463562 0.003058 -0.136862 +v 0.441721 0.003059 -0.136458 +v 0.441965 -0.022800 -0.137177 +v 0.463553 0.007658 -0.140079 +v 0.440444 0.007656 -0.139720 +v 0.441721 0.003059 -0.136458 +v 0.425112 0.002940 -0.133572 +v 0.425112 0.002940 -0.133572 +v 0.426823 -0.022893 -0.134398 +v 0.400635 0.002584 -0.126834 +v 0.403286 -0.023361 -0.127952 +v 0.380235 0.007013 -0.126756 +v 0.400635 0.002584 -0.126834 +v 0.380235 0.007013 -0.126756 +v 0.354970 0.006525 -0.120841 +v 0.361768 0.002044 -0.119906 +v 0.362981 -0.024935 -0.120916 +v 0.122659 -0.269249 -0.137467 +v 0.003665 -0.280461 -0.137936 +v 0.231661 -0.243612 -0.136642 +v 0.219270 -0.232636 -0.127851 +v 0.115880 -0.256142 -0.128332 +v 0.003719 -0.266956 -0.128747 +v 0.324258 0.007320 -0.125880 +v 0.236774 0.007321 -0.124987 +v 0.223993 0.006469 -0.116752 +v 0.307261 0.006559 -0.118402 +v 0.354970 0.006525 -0.120841 +v -0.311849 0.007262 -0.124627 +v -0.225092 0.007300 -0.124559 +v -0.367957 0.006920 -0.124760 +v -0.339868 0.006393 -0.118058 +v -0.292644 0.006461 -0.116383 +v -0.211645 0.006430 -0.116039 +v 0.301667 0.001398 -0.115632 +v 0.300619 -0.028156 -0.116574 +v 0.307261 0.006559 -0.118402 +v 0.223993 0.006469 -0.116752 +v 0.218304 0.000690 -0.113615 +v 0.216851 -0.032259 -0.114657 +v 0.116049 0.000076 -0.112908 +v 0.115149 -0.036033 -0.114084 +v 0.119214 0.006393 -0.116130 +v 0.004462 0.006366 -0.116042 +v 0.004431 -0.000203 -0.112816 +v 0.004330 -0.037808 -0.114060 +v -0.106123 0.000020 -0.112806 +v -0.105520 -0.036370 -0.113993 +v -0.109233 0.006385 -0.116041 +v -0.211645 0.006430 -0.116039 +v -0.205725 0.000576 -0.112780 +v -0.204598 -0.032781 -0.113826 +v -0.286064 0.001233 -0.113235 +v -0.285046 -0.028618 -0.114137 +v -0.292644 0.006461 -0.116383 +v -0.339868 0.006393 -0.118058 +v -0.345602 0.001871 -0.116596 +v -0.346499 -0.025215 -0.117510 +v -0.417442 -0.139594 -0.138968 +v -0.415503 -0.170161 -0.140801 +v -0.386384 -0.171686 -0.132537 +v -0.389235 -0.140850 -0.130956 +v -0.366070 -0.189229 -0.133878 +v -0.337984 -0.191386 -0.127252 +v -0.343817 -0.179343 -0.125020 +v -0.345222 -0.147739 -0.123205 +v 0.126289 0.007298 -0.124613 +v 0.004496 0.007293 -0.124559 +v 0.004462 0.006366 -0.116042 +v 0.119214 0.006393 -0.116130 +v 0.320632 -0.213691 -0.136125 +v 0.378963 -0.188719 -0.135809 +v 0.353180 -0.190353 -0.129929 +v 0.303782 -0.207086 -0.128286 +v -0.309744 -0.214812 -0.134950 +v -0.223044 -0.245099 -0.136292 +v -0.209680 -0.235088 -0.127266 +v -0.290607 -0.208958 -0.126397 +v -0.116292 0.007295 -0.124559 +v -0.109233 0.006385 -0.116041 +v -0.115137 -0.270259 -0.137462 +v -0.108119 -0.257808 -0.128322 +v -0.556786 -0.199186 -0.169297 +v -0.552230 -0.201004 -0.169382 +v -0.552212 -0.191900 -0.157750 +v -0.556689 -0.190308 -0.157867 +v -0.533838 -0.200711 -0.169369 +v -0.533837 -0.191548 -0.157670 +v -0.533829 -0.183028 -0.148943 +v -0.552155 -0.183666 -0.149308 +v -0.556223 -0.184144 -0.150955 +v -0.458544 0.008998 -0.159620 +v -0.496791 0.008998 -0.159620 +v -0.496791 0.008421 -0.148375 +v -0.458545 0.008421 -0.148375 +v -0.496795 0.007656 -0.140079 +v -0.458551 0.007658 -0.140079 +v -0.458213 -0.022887 -0.137578 +v -0.458521 0.003057 -0.136862 +v -0.496778 0.003027 -0.136864 +v -0.496598 -0.023088 -0.137588 +v -0.458551 0.007658 -0.140079 +v -0.496795 0.007656 -0.140079 +v 0.563283 -0.023761 -0.141539 +v 0.563113 0.003057 -0.140628 +v 0.557379 0.002990 -0.137337 +v 0.557443 -0.023413 -0.138093 +v 0.562352 0.007524 -0.142045 +v 0.557283 0.007630 -0.140416 +v 0.538328 0.007654 -0.140079 +v 0.538337 0.002998 -0.136865 +v 0.538367 -0.023270 -0.137596 +v 0.563268 0.008562 -0.159640 +v 0.557401 0.008944 -0.159622 +v 0.557372 0.008371 -0.148441 +v 0.563111 0.008013 -0.148648 +v 0.538325 0.008998 -0.159620 +v 0.538325 0.008421 -0.148375 +v 0.538328 0.007654 -0.140079 +v 0.557283 0.007630 -0.140416 +v 0.562352 0.007524 -0.142045 +v 0.463309 -0.198290 -0.169256 +v 0.501176 -0.199470 -0.169311 +v 0.501171 -0.190309 -0.157613 +v 0.463302 -0.189130 -0.157558 +v 0.501140 -0.181800 -0.148886 +v 0.463252 -0.180633 -0.148832 +v 0.439563 -0.199363 -0.169306 +v 0.439628 -0.190089 -0.157529 +v 0.440181 -0.180969 -0.148487 +v 0.501199 0.003028 -0.136864 +v 0.501174 -0.023078 -0.137587 +v 0.501190 0.007656 -0.140079 +v 0.501183 0.008998 -0.159620 +v 0.501184 0.008421 -0.148375 +v 0.501190 0.007656 -0.140079 +v -0.418856 -0.022933 -0.133545 +v -0.417452 0.002902 -0.132756 +v -0.436173 0.003054 -0.136359 +v -0.436132 -0.022805 -0.137070 +v -0.417452 0.002902 -0.132756 +v -0.434988 0.007653 -0.139662 +v -0.436173 0.003054 -0.136359 +v -0.434988 0.007653 -0.139662 +v -0.434474 0.008998 -0.159620 +v -0.434517 0.008422 -0.148292 +v -0.495668 -0.199522 -0.169313 +v -0.495666 -0.190361 -0.157615 +v -0.495644 -0.181852 -0.148888 +v -0.418135 -0.080601 -0.136226 +v -0.435337 -0.080539 -0.139754 +v -0.434571 -0.139602 -0.142499 +v -0.457487 -0.080823 -0.140271 +v -0.456783 -0.140091 -0.143026 +v 0.538494 -0.141938 -0.143112 +v 0.538426 -0.081931 -0.140323 +v 0.501096 -0.081376 -0.140297 +v 0.501040 -0.141014 -0.143069 +v 0.463293 -0.080816 -0.140271 +v 0.463130 -0.140078 -0.143026 +v 0.563341 -0.145094 -0.147180 +v 0.563312 -0.083751 -0.144328 +v 0.557518 -0.082395 -0.140835 +v 0.557595 -0.142727 -0.143639 +v -0.496173 -0.081401 -0.140298 +v -0.495763 -0.141055 -0.143071 +v -0.533943 -0.081967 -0.140325 +v -0.533844 -0.141998 -0.143115 +v -0.388161 0.002470 -0.124441 +v -0.390518 -0.023490 -0.125500 +v -0.388161 0.002470 -0.124441 +v -0.367957 0.006920 -0.124760 +v -0.203281 -0.183532 -0.120834 +v -0.203936 -0.107319 -0.117291 +v -0.284344 -0.095319 -0.117238 +v -0.283659 -0.163533 -0.120409 +v -0.345849 -0.085784 -0.120325 +v 0.003882 -0.207784 -0.121961 +v 0.004108 -0.121861 -0.117967 +v -0.105146 -0.117700 -0.117774 +v -0.104775 -0.200844 -0.121639 +v 0.213866 -0.181161 -0.121566 +v 0.215363 -0.105882 -0.118073 +v 0.114112 -0.116734 -0.117835 +v 0.113065 -0.199237 -0.121669 +v 0.362093 -0.147000 -0.126540 +v 0.362523 -0.085277 -0.123696 +v 0.299501 -0.094201 -0.119626 +v 0.298392 -0.161744 -0.122747 +v 0.426676 -0.139556 -0.139808 +v 0.426728 -0.080561 -0.137073 +v 0.403158 -0.081346 -0.130630 +v 0.403069 -0.140665 -0.133369 +v 0.441794 -0.080534 -0.139860 +v 0.441664 -0.139597 -0.142605 +v -0.552192 -0.082421 -0.140836 +v -0.552210 -0.142771 -0.143641 +v -0.556764 -0.083761 -0.144329 +v -0.556777 -0.145110 -0.147181 +v 0.565100 -0.157862 -0.167377 +v 0.565100 -0.091048 -0.164271 +v 0.564877 -0.086864 -0.152804 +v 0.564880 -0.150540 -0.155764 +v 0.563312 -0.083751 -0.144328 +v 0.563341 -0.145094 -0.147180 +v -0.556777 -0.145110 -0.147181 +v -0.556764 -0.083761 -0.144329 +v -0.557767 -0.086865 -0.152804 +v -0.557769 -0.150542 -0.155764 +v -0.557910 -0.091048 -0.164271 +v -0.557910 -0.157862 -0.167377 +v -0.556223 -0.184144 -0.150955 +v -0.556687 -0.175664 -0.148937 +v -0.557634 -0.182008 -0.157291 +v -0.556689 -0.190308 -0.157867 +v -0.557770 -0.190687 -0.168902 +v -0.556786 -0.199186 -0.169297 +v 0.563360 -0.199167 -0.169297 +v 0.564883 -0.190684 -0.168902 +v 0.564673 -0.182004 -0.157290 +v 0.563210 -0.190287 -0.157866 +v 0.563206 -0.175644 -0.148936 +v 0.562488 -0.184115 -0.150954 +v -0.533816 -0.172234 -0.145011 +v -0.552204 -0.173104 -0.145523 +v -0.556687 -0.175664 -0.148937 +v 0.463151 -0.169937 -0.144904 +v 0.441399 -0.169522 -0.144478 +v 0.424937 -0.170111 -0.141598 +v 0.400299 -0.171450 -0.134873 +v 0.360470 -0.178461 -0.128225 +v 0.298456 -0.195693 -0.124742 +v 0.213964 -0.219015 -0.123810 +v 0.113006 -0.240760 -0.124101 +v 0.003768 -0.251007 -0.124475 +v -0.105061 -0.242640 -0.124086 +v -0.203852 -0.221782 -0.123116 +v -0.284110 -0.197773 -0.122486 +v -0.456540 -0.169951 -0.144905 +v -0.495622 -0.171105 -0.144958 +v 0.563206 -0.175644 -0.148936 +v 0.557608 -0.173052 -0.145521 +v 0.538548 -0.172163 -0.145008 +v 0.501074 -0.171056 -0.144956 +v -0.434018 -0.169527 -0.144382 +v -0.389862 -0.081504 -0.128197 +vt 0.283512 0.401314 +vt 0.283512 0.394454 +vt 0.282644 0.394395 +vt 0.283512 0.385651 +vt 0.282643 0.385618 +vt 0.283512 0.375864 +vt 0.282643 0.375864 +vt 0.283512 0.366145 +vt 0.282643 0.366178 +vt 0.283512 0.357391 +vt 0.282643 0.357453 +vt 0.282643 0.350464 +vt 0.480567 0.163382 +vt 0.485004 0.163380 +vt 0.485045 0.160620 +vt 0.489356 0.160629 +vt 0.480698 0.089793 +vt 0.485081 0.089744 +vt 0.485038 0.086884 +vt 0.489350 0.086855 +vt 0.475869 0.123823 +vt 0.482223 0.123844 +vt 0.482531 0.115766 +vt 0.488545 0.115743 +vt 0.288463 0.186231 +vt 0.287632 0.181733 +vt 0.287632 0.186578 +vt 0.288463 0.190944 +vt 0.289083 0.181531 +vt 0.289058 0.179547 +vt 0.288459 0.179556 +vt 0.288463 0.181618 +vt 0.288942 0.179221 +vt 0.288451 0.179208 +vt 0.287639 0.179204 +vt 0.287633 0.179570 +vt 0.287632 0.207733 +vt 0.287634 0.209896 +vt 0.288458 0.209908 +vt 0.288461 0.207847 +vt 0.287648 0.210263 +vt 0.288458 0.210258 +vt 0.288950 0.210245 +vt 0.289063 0.209918 +vt 0.289086 0.207935 +vt 0.489336 0.084086 +vt 0.491276 0.084085 +vt 0.491271 0.082750 +vt 0.489322 0.082747 +vt 0.491595 0.084089 +vt 0.491591 0.082759 +vt 0.491571 0.082459 +vt 0.491253 0.082422 +vt 0.489272 0.082412 +vt 0.476057 0.163413 +vt 0.476034 0.164822 +vt 0.476788 0.164807 +vt 0.476816 0.163400 +vt 0.476165 0.165244 +vt 0.476902 0.165221 +vt 0.477406 0.165160 +vt 0.477455 0.164792 +vt 0.477506 0.163390 +vt 0.283513 0.336033 +vt 0.283512 0.334697 +vt 0.282684 0.334698 +vt 0.282680 0.336033 +vt 0.283512 0.334358 +vt 0.282698 0.334366 +vt 0.282208 0.334401 +vt 0.282088 0.334703 +vt 0.282064 0.336033 +vt 0.283512 0.409805 +vt 0.283512 0.408051 +vt 0.282674 0.408056 +vt 0.282680 0.409805 +vt 0.283512 0.405807 +vt 0.282653 0.405812 +vt 0.281806 0.405834 +vt 0.282037 0.408097 +vt 0.282064 0.409806 +vt 0.282646 0.401257 +vt 0.281777 0.393981 +vt 0.281797 0.400787 +vt 0.281767 0.375863 +vt 0.281768 0.385389 +vt 0.281767 0.357888 +vt 0.281767 0.366406 +vt 0.283512 0.350398 +vt 0.283513 0.345723 +vt 0.282649 0.345725 +vt 0.281768 0.345779 +vt 0.281767 0.351007 +vt 0.476224 0.089829 +vt 0.476146 0.091622 +vt 0.476913 0.091607 +vt 0.476982 0.089817 +vt 0.475280 0.093942 +vt 0.476075 0.093931 +vt 0.477085 0.093966 +vt 0.477650 0.091565 +vt 0.477671 0.089811 +vt 0.473187 0.098629 +vt 0.473958 0.098681 +vt 0.470598 0.105614 +vt 0.471373 0.105662 +vt 0.472177 0.106081 +vt 0.474693 0.099207 +vt 0.468488 0.114294 +vt 0.469274 0.114313 +vt 0.467625 0.123850 +vt 0.468415 0.123837 +vt 0.469323 0.123826 +vt 0.470150 0.114527 +vt 0.468489 0.133407 +vt 0.469278 0.133363 +vt 0.470601 0.142090 +vt 0.471380 0.142020 +vt 0.472216 0.141606 +vt 0.470176 0.133130 +vt 0.473190 0.149079 +vt 0.473964 0.149011 +vt 0.475284 0.153771 +vt 0.476080 0.153767 +vt 0.477094 0.153803 +vt 0.474721 0.148538 +vt 0.489370 0.157842 +vt 0.491285 0.157850 +vt 0.491288 0.156234 +vt 0.489379 0.156250 +vt 0.491601 0.157853 +vt 0.491603 0.156144 +vt 0.281771 0.408190 +vt 0.281557 0.406962 +vt 0.491300 0.155003 +vt 0.489392 0.155128 +vt 0.491322 0.153186 +vt 0.489404 0.153380 +vt 0.281078 0.403645 +vt 0.281059 0.405152 +vt 0.491649 0.151678 +vt 0.491655 0.149803 +vt 0.491332 0.150304 +vt 0.489339 0.150392 +vt 0.471234 0.132616 +vt 0.470404 0.123817 +vt 0.473127 0.140677 +vt 0.473999 0.139752 +vt 0.472264 0.132106 +vt 0.471465 0.123812 +vt 0.281015 0.399506 +vt 0.280949 0.393036 +vt 0.280337 0.392091 +vt 0.280459 0.398249 +vt 0.280639 0.401776 +vt 0.280922 0.352468 +vt 0.280917 0.358883 +vt 0.280930 0.348319 +vt 0.280433 0.350396 +vt 0.280309 0.353888 +vt 0.280284 0.359877 +vt 0.491315 0.145855 +vt 0.489133 0.145776 +vt 0.491675 0.146273 +vt 0.491680 0.140114 +vt 0.491277 0.139689 +vt 0.488844 0.139580 +vt 0.491237 0.132128 +vt 0.488570 0.132059 +vt 0.491678 0.132366 +vt 0.491677 0.123882 +vt 0.491216 0.123875 +vt 0.488439 0.123865 +vt 0.491232 0.115701 +vt 0.491677 0.115475 +vt 0.491680 0.107903 +vt 0.491273 0.108336 +vt 0.488810 0.108417 +vt 0.491317 0.102397 +vt 0.489113 0.102470 +vt 0.491680 0.101914 +vt 0.491662 0.098425 +vt 0.491340 0.097999 +vt 0.489339 0.097930 +vt 0.480764 0.092697 +vt 0.478501 0.092839 +vt 0.478448 0.094983 +vt 0.480730 0.094774 +vt 0.477147 0.096485 +vt 0.477037 0.098553 +vt 0.477939 0.098121 +vt 0.480279 0.098018 +vt 0.280921 0.384866 +vt 0.280917 0.375860 +vt 0.280284 0.375858 +vt 0.280290 0.384343 +vt 0.475334 0.147258 +vt 0.477175 0.151573 +vt 0.477097 0.149660 +vt 0.475877 0.146004 +vt 0.475257 0.100648 +vt 0.473018 0.107056 +vt 0.473820 0.108035 +vt 0.475750 0.102054 +vt 0.280917 0.366928 +vt 0.280284 0.367450 +vt 0.471158 0.115034 +vt 0.472140 0.115543 +vt 0.476158 0.082422 +vt 0.476024 0.082759 +vt 0.476778 0.082748 +vt 0.476894 0.082417 +vt 0.476046 0.084119 +vt 0.476804 0.084107 +vt 0.477495 0.084098 +vt 0.477445 0.082744 +vt 0.477398 0.082445 +vt 0.283512 0.341620 +vt 0.283512 0.338792 +vt 0.282680 0.338792 +vt 0.282680 0.341620 +vt 0.282064 0.338791 +vt 0.282064 0.341619 +vt 0.489365 0.089693 +vt 0.491281 0.089672 +vt 0.491278 0.086844 +vt 0.491596 0.089674 +vt 0.491596 0.086847 +vt 0.489278 0.165225 +vt 0.491259 0.165215 +vt 0.491277 0.164787 +vt 0.489328 0.164790 +vt 0.491577 0.165160 +vt 0.491597 0.164784 +vt 0.491601 0.163382 +vt 0.491281 0.163378 +vt 0.489342 0.163379 +vt 0.283512 0.417179 +vt 0.283512 0.416745 +vt 0.282684 0.416743 +vt 0.282698 0.417168 +vt 0.283512 0.415335 +vt 0.282680 0.415335 +vt 0.282064 0.415335 +vt 0.282088 0.416737 +vt 0.282208 0.417111 +vt 0.476230 0.157846 +vt 0.476143 0.160646 +vt 0.476901 0.160633 +vt 0.476988 0.157834 +vt 0.477591 0.160622 +vt 0.477677 0.157821 +vt 0.476150 0.156090 +vt 0.476918 0.156083 +vt 0.477654 0.156115 +vt 0.491283 0.160632 +vt 0.491601 0.160636 +vt 0.283512 0.412588 +vt 0.282680 0.412588 +vt 0.282064 0.412589 +vt 0.489391 0.092599 +vt 0.491299 0.092704 +vt 0.491284 0.091324 +vt 0.489375 0.091325 +vt 0.281497 0.344658 +vt 0.282033 0.343362 +vt 0.281764 0.343273 +vt 0.491599 0.091416 +vt 0.283512 0.343400 +vt 0.282674 0.343397 +vt 0.476134 0.086941 +vt 0.476892 0.086929 +vt 0.477582 0.086922 +vt 0.485127 0.092649 +vt 0.485106 0.091381 +vt 0.480738 0.091435 +vt 0.480635 0.160613 +vt 0.485086 0.157825 +vt 0.480704 0.157810 +vt 0.480305 0.165223 +vt 0.484842 0.165224 +vt 0.484967 0.164792 +vt 0.480505 0.164795 +vt 0.480627 0.086911 +vt 0.484996 0.084091 +vt 0.480557 0.084095 +vt 0.280881 0.346824 +vt 0.489408 0.094685 +vt 0.491327 0.094861 +vt 0.491653 0.096355 +vt 0.477662 0.108507 +vt 0.483298 0.108462 +vt 0.484181 0.102518 +vt 0.479137 0.102565 +vt 0.484860 0.097975 +vt 0.476382 0.115789 +vt 0.477833 0.139351 +vt 0.483400 0.139466 +vt 0.482602 0.131978 +vt 0.476501 0.131896 +vt 0.480313 0.150320 +vt 0.484877 0.150355 +vt 0.484249 0.145690 +vt 0.479254 0.145604 +vt 0.480765 0.155111 +vt 0.485128 0.155118 +vt 0.485117 0.153368 +vt 0.480730 0.153358 +vt 0.485110 0.156235 +vt 0.480742 0.156222 +vt 0.484959 0.082742 +vt 0.480496 0.082738 +vt 0.484835 0.082408 +vt 0.480298 0.082404 +vt 0.287632 0.197943 +vt 0.287632 0.202888 +vt 0.288461 0.203235 +vt 0.288461 0.198522 +vt 0.289086 0.203495 +vt 0.289086 0.198955 +vt 0.289083 0.190513 +vt 0.289083 0.185972 +vt 0.287632 0.191524 +vt 0.288941 0.193408 +vt 0.289058 0.192776 +vt 0.288459 0.193273 +vt 0.288451 0.193887 +vt 0.287633 0.193954 +vt 0.287639 0.194582 +vt 0.287648 0.194889 +vt 0.287635 0.195515 +vt 0.288458 0.196194 +vt 0.288458 0.195582 +vt 0.289063 0.196693 +vt 0.288950 0.196062 +vt 0.478317 0.084096 +vt 0.478250 0.082737 +vt 0.478037 0.082409 +vt 0.478492 0.157810 +vt 0.478526 0.156201 +vt 0.478503 0.154981 +vt 0.478453 0.153151 +vt 0.477985 0.150198 +vt 0.476741 0.145607 +vt 0.475030 0.139357 +vt 0.473427 0.131890 +vt 0.472670 0.123813 +vt 0.473288 0.115766 +vt 0.474830 0.108463 +vt 0.476601 0.102531 +vt 0.478487 0.089810 +vt 0.478401 0.086920 +vt 0.478044 0.165212 +vt 0.478259 0.164795 +vt 0.478328 0.163385 +vt 0.478410 0.160614 +vt 0.478522 0.091475 +vt 0.485118 0.094730 +vn 0.0001 0.9989 0.0473 +vn 0.0000 0.9989 0.0464 +vn -0.0001 0.9989 0.0464 +vn -0.0008 0.9987 0.0516 +vn 0.0124 -0.0544 0.9984 +vn 0.0128 -0.0464 0.9988 +vn 0.0000 -0.0464 0.9989 +vn 0.0000 -0.0371 0.9993 +vn -0.0111 -0.0547 0.9984 +vn -0.0114 -0.0466 0.9988 +vn -0.0114 -0.0466 0.9989 +vn 0.0000 -0.0370 0.9993 +vn 0.0005 -0.0526 0.9986 +vn 0.0006 -0.0464 0.9989 +vn 0.0005 -0.0464 0.9989 +vn 0.0001 -0.0395 0.9992 +vn -0.9978 -0.0030 0.0661 +vn -0.9999 0.0018 0.0127 +vn -0.9999 -0.0006 0.0127 +vn -0.9978 -0.0052 0.0668 +vn -0.8645 -0.0182 0.5023 +vn -0.8275 0.1616 0.5377 +vn -0.9933 0.0950 0.0653 +vn -0.9978 -0.0005 0.0667 +vn -0.6295 0.6833 0.3699 +vn -0.6688 0.7390 0.0809 +vn -0.6638 0.7467 0.0433 +vn -0.9946 0.1030 0.0156 +vn -0.9999 0.0014 0.0126 +vn 0.9998 0.0027 0.0199 +vn 0.9871 0.1582 0.0243 +vn 0.9842 0.1456 0.1010 +vn 0.9946 -0.0007 0.1039 +vn 0.6155 0.7867 0.0479 +vn 0.6259 0.7736 0.0988 +vn 0.5693 0.7139 0.4077 +vn 0.7803 0.1871 0.5968 +vn 0.8166 -0.0201 0.5769 +vn -0.0135 -0.0372 0.9992 +vn -0.0120 0.2817 0.9594 +vn -0.2846 0.2391 0.9284 +vn -0.3269 -0.0354 0.9444 +vn -0.0062 0.8611 0.5084 +vn -0.1710 0.8190 0.5477 +vn -0.6295 0.6833 0.3698 +vn -0.8275 0.1615 0.5377 +vn -0.8645 -0.0182 0.5022 +vn -0.0181 -0.7872 0.6165 +vn 0.1013 -0.7835 0.6131 +vn 0.0991 -0.7528 0.6508 +vn -0.0172 -0.7525 0.6583 +vn 0.5477 -0.6569 0.5182 +vn 0.6889 -0.5380 0.4859 +vn 0.6304 -0.4319 0.6450 +vn 0.1407 -0.5194 0.8429 +vn -0.0089 -0.5418 0.8404 +vn -0.0015 0.9987 0.0512 +vn -0.0430 0.9978 0.0509 +vn -0.0403 0.9967 0.0703 +vn -0.0015 0.9974 0.0717 +vn -0.6295 0.6832 0.3700 +vn -0.1710 0.8190 0.5478 +vn -0.0062 0.8610 0.5085 +vn 0.0000 0.9987 0.0511 +vn 0.0003 0.9987 0.0507 +vn 0.0013 0.9977 0.0673 +vn 0.0003 0.9975 0.0712 +vn 0.0002 0.9988 0.0490 +vn 0.0016 0.9982 0.0592 +vn 0.0754 0.9415 0.3284 +vn 0.0320 0.8879 0.4589 +vn 0.0041 0.8662 0.4996 +vn 0.0000 0.9989 0.0469 +vn 0.0008 0.9987 0.0516 +vn 0.0000 0.9989 0.0465 +vn 0.0002 0.9988 0.0500 +vn 0.0027 0.9982 0.0593 +vn 0.0000 0.9988 0.0497 +vn -0.0000 0.9988 0.0496 +vn -0.0002 0.9989 0.0466 +vn -0.0002 0.9988 0.0497 +vn -0.0002 0.9989 0.0470 +vn -0.0009 0.9987 0.0516 +vn -0.0002 0.9988 0.0490 +vn -0.0017 0.9983 0.0591 +vn -0.0738 0.9447 0.3195 +vn -0.0025 0.9983 0.0586 +vn -0.0043 -0.7871 0.6168 +vn -0.1623 -0.7754 0.6102 +vn -0.1441 -0.7381 0.6592 +vn -0.0031 -0.7511 0.6602 +vn -0.2991 -0.7484 0.5920 +vn -0.2809 -0.7162 0.6389 +vn -0.2630 -0.5543 0.7897 +vn -0.1211 -0.5299 0.8394 +vn -0.0035 -0.5395 0.8420 +vn -0.2918 -0.7508 0.5926 +vn -0.2859 -0.7208 0.6315 +vn -0.2219 -0.7672 0.6018 +vn -0.2215 -0.7423 0.6325 +vn -0.1985 -0.6816 0.7043 +vn -0.2571 -0.6520 0.7133 +vn -0.1221 -0.7822 0.6110 +vn -0.1235 -0.7607 0.6373 +vn 0.0000 -0.7884 0.6152 +vn 0.0003 -0.7674 0.6411 +vn 0.0011 -0.7087 0.7055 +vn -0.1118 -0.7024 0.7030 +vn 0.1220 -0.7813 0.6121 +vn 0.1230 -0.7567 0.6421 +vn 0.2212 -0.7658 0.6039 +vn 0.2195 -0.7374 0.6388 +vn 0.1936 -0.6662 0.7202 +vn 0.1110 -0.6906 0.7147 +vn 0.2911 -0.7502 0.5937 +vn 0.2838 -0.7185 0.6350 +vn 0.2989 -0.7483 0.5922 +vn 0.2804 -0.7152 0.6402 +vn 0.2581 -0.5514 0.7933 +vn 0.2515 -0.6429 0.7235 +vn 0.0093 -0.0370 0.9993 +vn 0.0084 0.2882 0.9575 +vn 0.0777 0.3207 0.9440 +vn 0.0985 -0.0359 0.9945 +vn 0.0041 0.8663 0.4996 +vn 0.1759 0.3698 0.9123 +vn 0.1759 0.3699 0.9123 +vn 0.2211 -0.0320 0.9747 +vn 0.2113 0.4240 0.8807 +vn 0.2210 -0.0327 0.9747 +vn 0.0912 0.8690 0.4864 +vn 0.0502 0.7920 0.6085 +vn 0.1343 0.2513 0.9585 +vn 0.1233 -0.0390 0.9916 +vn 0.0926 -0.5994 0.7951 +vn 0.0020 -0.6198 0.7847 +vn 0.1581 -0.5757 0.8023 +vn 0.1033 -0.3997 0.9108 +vn 0.0596 -0.4140 0.9083 +vn 0.0025 -0.4260 0.9047 +vn 0.0037 0.9964 0.0848 +vn 0.0005 0.9969 0.0785 +vn 0.0079 0.8256 0.5642 +vn 0.0279 0.8009 0.5981 +vn 0.0502 0.7920 0.6084 +vn -0.0031 0.9967 0.0809 +vn -0.0001 0.9970 0.0770 +vn -0.0883 0.8826 0.4618 +vn -0.0438 0.8144 0.5786 +vn -0.0186 0.8194 0.5730 +vn -0.0006 0.8360 0.5487 +vn 0.0388 0.2073 0.9775 +vn 0.0479 -0.0401 0.9980 +vn 0.0079 0.8256 0.5643 +vn 0.0122 0.2218 0.9750 +vn 0.0159 -0.0395 0.9991 +vn 0.0029 0.2169 0.9762 +vn 0.0040 -0.0396 0.9992 +vn 0.0014 0.8243 0.5662 +vn 0.0002 0.8212 0.5707 +vn 0.0004 0.2133 0.9770 +vn 0.0004 -0.0398 0.9992 +vn 0.0005 0.2182 0.9759 +vn 0.0007 0.8261 0.5636 +vn -0.0012 0.2310 0.9730 +vn -0.0029 -0.0389 0.9992 +vn -0.0222 0.2323 0.9724 +vn -0.0312 -0.0390 0.9988 +vn -0.0186 0.8193 0.5731 +vn -0.1286 0.2757 0.9526 +vn -0.1198 -0.0381 0.9921 +vn -0.2366 -0.0595 0.9698 +vn -0.2278 -0.2249 0.9474 +vn -0.2501 -0.2271 0.9412 +vn -0.2301 -0.0589 0.9714 +vn -0.2487 -0.4635 0.8505 +vn -0.1843 -0.3931 0.9008 +vn -0.1536 -0.1753 0.9725 +vn -0.1211 -0.0547 0.9911 +vn 0.0000 0.9968 0.0795 +vn 0.0000 0.9967 0.0806 +vn 0.0002 0.8211 0.5707 +vn 0.0015 0.8243 0.5662 +vn 0.2083 -0.5605 0.8015 +vn 0.2393 -0.4509 0.8599 +vn 0.1751 -0.3712 0.9119 +vn 0.1396 -0.3846 0.9124 +vn -0.2182 -0.5821 0.7833 +vn -0.1637 -0.6017 0.7818 +vn -0.1027 -0.4230 0.9003 +vn -0.1439 -0.4107 0.9003 +vn 0.0001 0.9969 0.0788 +vn 0.0007 0.8261 0.5635 +vn -0.0916 -0.6167 0.7818 +vn -0.0557 -0.4266 0.9027 +vn -0.5939 -0.6325 0.4972 +vn -0.1269 -0.7812 0.6113 +vn -0.1263 -0.7510 0.6481 +vn -0.7358 -0.5048 0.4514 +vn 0.0178 -0.7871 0.6166 +vn 0.0169 -0.7525 0.6583 +vn 0.0081 -0.5413 0.8408 +vn -0.1735 -0.5147 0.8396 +vn -0.6928 -0.4075 0.5950 +vn 0.0000 0.9987 0.0512 +vn -0.0000 0.9974 0.0716 +vn -0.0001 0.9974 0.0714 +vn -0.0001 0.8639 0.5037 +vn -0.0047 0.8668 0.4987 +vn -0.0114 -0.0372 0.9992 +vn -0.0103 0.2894 0.9572 +vn -0.0002 0.2856 0.9583 +vn -0.0047 0.8667 0.4987 +vn 0.8165 -0.0201 0.5769 +vn 0.7802 0.1871 0.5968 +vn 0.2384 0.2429 0.9403 +vn 0.2737 -0.0357 0.9611 +vn 0.5693 0.7140 0.4076 +vn 0.1373 0.8261 0.5465 +vn 0.0059 0.8611 0.5084 +vn 0.0114 0.2816 0.9594 +vn 0.0129 -0.0371 0.9992 +vn 0.0340 0.9981 0.0512 +vn 0.0320 0.9970 0.0705 +vn 0.6258 0.7737 0.0988 +vn 0.0014 0.9987 0.0512 +vn 0.0014 0.9974 0.0717 +vn 0.0059 0.8612 0.5083 +vn 0.1374 0.8261 0.5466 +vn 0.0050 -0.7870 0.6170 +vn -0.0236 -0.7871 0.6164 +vn -0.0224 -0.7526 0.6581 +vn 0.0034 -0.7508 0.6606 +vn -0.0155 -0.5433 0.8394 +vn 0.0027 -0.5388 0.8424 +vn 0.1629 -0.7753 0.6102 +vn 0.1439 -0.7373 0.6601 +vn 0.1165 -0.5257 0.8426 +vn 0.0002 0.2858 0.9583 +vn 0.0001 0.8639 0.5036 +vn -0.2349 -0.0335 0.9714 +vn -0.1865 0.3824 0.9050 +vn -0.0861 0.3284 0.9406 +vn -0.1103 -0.0367 0.9932 +vn -0.1865 0.3823 0.9050 +vn -0.0339 0.8919 0.4509 +vn -0.0862 0.3284 0.9406 +vn -0.0002 0.9987 0.0505 +vn -0.0013 0.9977 0.0671 +vn 0.0236 -0.7871 0.6164 +vn 0.0224 -0.7526 0.6581 +vn 0.0155 -0.5431 0.8395 +vn -0.2377 -0.0480 0.9701 +vn -0.1123 -0.0476 0.9925 +vn -0.1111 -0.0567 0.9922 +vn -0.0002 -0.0546 0.9985 +vn 0.0092 -0.0465 0.9989 +vn 0.0091 -0.0546 0.9985 +vn 0.8181 -0.0318 0.5742 +vn 0.8190 -0.0263 0.5733 +vn 0.2758 -0.0444 0.9602 +vn 0.2754 -0.0511 0.9600 +vn 0.0002 -0.0546 0.9985 +vn -0.0134 -0.0464 0.9988 +vn -0.0130 -0.0545 0.9984 +vn -0.2146 0.4340 0.8750 +vn -0.2287 -0.0337 0.9729 +vn -0.0046 -0.0530 0.9986 +vn -0.0031 -0.0465 0.9989 +vn -0.0318 -0.0467 0.9984 +vn -0.0334 -0.0533 0.9980 +vn -0.1190 -0.0474 0.9918 +vn 0.0005 -0.0527 0.9986 +vn -0.0008 -0.0526 0.9986 +vn 0.0004 -0.0464 0.9989 +vn 0.0173 -0.0526 0.9985 +vn 0.0161 -0.0466 0.9988 +vn 0.0041 -0.0465 0.9989 +vn 0.0050 -0.0527 0.9986 +vn 0.1230 -0.0533 0.9910 +vn 0.1218 -0.0465 0.9915 +vn 0.0479 -0.0468 0.9978 +vn 0.0485 -0.0526 0.9974 +vn 0.2224 -0.0566 0.9733 +vn 0.2236 -0.0455 0.9736 +vn 0.2189 -0.0456 0.9747 +vn 0.2205 -0.0564 0.9738 +vn 0.1005 -0.0464 0.9939 +vn 0.0996 -0.0552 0.9935 +vn -0.3288 -0.0438 0.9434 +vn -0.3263 -0.0503 0.9439 +vn -0.8659 -0.0231 0.4996 +vn -0.8639 -0.0280 0.5028 +vn 0.9997 -0.0056 0.0225 +vn 0.9998 -0.0009 0.0198 +vn 0.9947 -0.0047 0.1026 +vn 0.9947 -0.0079 0.1029 +vn 0.8189 -0.0263 0.5733 +vn -0.8639 -0.0280 0.5029 +vn -0.9977 -0.0052 0.0669 +vn -0.9999 -0.0006 0.0129 +vn -0.9999 -0.0037 0.0145 +vn -0.6928 -0.4074 0.5950 +vn -0.8140 -0.1328 0.5655 +vn -0.9930 -0.0596 0.1021 +vn -0.7359 -0.5048 0.4514 +vn -0.9932 -0.0872 0.0770 +vn 0.9841 -0.1331 0.1173 +vn 0.9838 -0.0904 0.1548 +vn 0.6888 -0.5381 0.4859 +vn 0.7685 -0.1440 0.6234 +vn 0.6304 -0.4320 0.6450 +vn -0.0065 -0.2035 0.9791 +vn -0.2832 -0.1728 0.9434 +vn -0.8140 -0.1327 0.5655 +vn 0.0062 -0.2037 0.9790 +vn 0.0955 -0.2046 0.9742 +vn 0.2154 -0.2188 0.9517 +vn 0.2419 -0.2230 0.9443 +vn 0.1527 -0.1669 0.9741 +vn 0.0715 -0.1517 0.9858 +vn 0.0427 -0.1613 0.9860 +vn 0.0220 -0.1638 0.9862 +vn 0.0014 -0.1660 0.9861 +vn -0.0177 -0.1670 0.9858 +vn -0.0342 -0.1695 0.9849 +vn -0.0624 -0.1637 0.9845 +vn -0.0078 -0.2042 0.9789 +vn 0.0048 -0.2052 0.9787 +vn 0.2372 -0.1762 0.9553 +vn 0.0057 -0.2032 0.9791 +vn -0.0048 -0.2052 0.9787 +vn -0.1049 -0.2085 0.9724 +vn -0.2275 -0.0477 0.9726 +usemtl Scene_-_Root +s off +f 55/1/1 57/2/2 58/3/2 +f 57/2/2 61/4/2 62/5/2 +f 57/2/2 62/5/2 58/3/2 +f 61/4/2 63/6/2 64/7/2 +f 61/4/2 64/7/2 62/5/2 +f 63/6/2 67/8/2 68/9/2 +f 63/6/2 68/9/2 64/7/2 +f 67/8/2 69/10/2 70/11/2 +f 67/8/2 70/11/2 68/9/2 +f 69/10/3 74/12/4 70/11/3 +f 267/13/5 268/14/6 269/15/7 +f 268/14/6 244/16/8 269/15/7 +f 266/17/9 265/18/10 277/19/7 +f 265/18/11 213/20/12 277/19/7 +f 290/21/13 291/22/14 292/23/7 +f 291/22/15 160/24/16 292/23/7 +f 320/25/17 9/26/18 322/27/19 +f 321/28/20 320/25/17 322/27/19 +s 1 +f 1/29/21 2/30/22 3/31/23 +f 1/29/21 3/31/23 4/32/24 +f 2/30/22 5/33/25 6/34/26 +f 2/30/22 6/34/26 3/31/23 +f 3/31/23 6/34/26 7/35/27 +f 3/31/23 7/35/27 8/36/28 +f 4/32/24 3/31/23 8/36/28 +f 4/32/24 8/36/28 9/26/29 +f 10/37/30 11/38/31 12/39/32 +f 10/37/30 12/39/32 13/40/33 +f 11/38/31 14/41/34 15/42/35 +f 11/38/31 15/42/35 12/39/32 +f 12/39/32 15/42/35 16/43/36 +f 12/39/32 16/43/36 17/44/37 +f 13/40/33 12/39/32 17/44/37 +f 13/40/33 17/44/37 18/45/38 +f 19/46/39 20/47/40 21/48/41 +f 19/46/39 21/48/41 22/49/42 +f 20/47/40 23/50/43 24/51/44 +f 20/47/40 24/51/44 21/48/41 +f 21/48/41 24/51/44 25/52/45 +f 21/48/41 25/52/45 26/53/46 +f 22/49/42 21/48/41 26/53/46 +f 22/49/42 26/53/46 27/54/47 +f 28/55/48 29/56/49 30/57/50 +f 28/55/48 30/57/50 31/58/51 +f 29/56/49 32/59/52 33/60/53 +f 29/56/49 33/60/53 30/57/50 +f 30/57/50 33/60/53 34/61/54 +f 30/57/50 34/61/54 35/62/55 +f 31/58/51 30/57/50 35/62/55 +f 31/58/51 35/62/55 36/63/56 +f 37/64/57 38/65/58 39/66/59 +f 37/64/57 39/66/59 40/67/60 +f 38/65/58 41/68/27 42/69/26 +f 38/65/58 42/69/26 39/66/59 +f 39/66/59 42/69/26 43/70/61 +f 39/66/59 43/70/61 44/71/62 +f 40/67/60 39/66/59 44/71/62 +f 40/67/60 44/71/62 45/72/63 +f 46/73/64 47/74/65 48/75/66 +f 46/73/64 48/75/66 49/76/67 +f 47/74/65 50/77/68 51/78/69 +f 47/74/65 51/78/69 48/75/66 +f 48/75/66 51/78/69 52/79/70 +f 48/75/66 52/79/70 53/80/71 +f 49/76/67 48/75/66 53/80/71 +f 49/76/67 53/80/71 54/81/72 +f 50/77/68 55/1/73 56/82/74 +f 50/77/68 56/82/74 51/78/69 +f 55/1/73 58/3/75 56/82/74 +f 56/82/74 58/3/75 59/83/76 +f 56/82/74 59/83/76 60/84/77 +f 51/78/69 56/82/74 60/84/77 +f 51/78/69 60/84/77 52/79/70 +f 62/5/2 64/7/2 65/85/78 +f 62/5/2 65/85/78 66/86/79 +f 58/3/75 62/5/2 66/86/79 +f 58/3/75 66/86/79 59/83/76 +f 68/9/2 70/11/80 71/87/81 +f 68/9/2 71/87/81 72/88/79 +f 64/7/2 68/9/2 72/88/79 +f 64/7/2 72/88/79 65/85/78 +f 69/10/2 73/89/82 74/12/83 +f 73/89/82 75/90/84 76/91/85 +f 73/89/82 76/91/85 74/12/83 +f 74/12/83 76/91/85 77/92/86 +f 74/12/83 77/92/86 78/93/87 +f 70/11/80 74/12/83 78/93/87 +f 70/11/80 78/93/87 71/87/81 +f 79/94/88 80/95/89 81/96/90 +f 79/94/88 81/96/90 82/97/91 +f 80/95/89 83/98/92 84/99/93 +f 80/95/89 84/99/93 81/96/90 +f 81/96/90 84/99/93 85/100/94 +f 81/96/90 85/100/94 86/101/95 +f 82/97/91 81/96/90 86/101/95 +f 82/97/91 86/101/95 87/102/96 +f 83/98/92 88/103/97 89/104/98 +f 83/98/92 89/104/98 84/99/93 +f 88/103/97 90/105/99 91/106/100 +f 88/103/97 91/106/100 89/104/98 +f 89/104/98 91/106/100 92/107/101 +f 89/104/98 92/107/101 93/108/102 +f 84/99/93 89/104/98 93/108/102 +f 84/99/93 93/108/102 85/100/94 +f 90/105/99 94/109/103 95/110/104 +f 90/105/99 95/110/104 91/106/100 +f 94/109/103 96/111/105 97/112/106 +f 94/109/103 97/112/106 95/110/104 +f 95/110/104 97/112/106 98/113/107 +f 95/110/104 98/113/107 99/114/108 +f 91/106/100 95/110/104 99/114/108 +f 91/106/100 99/114/108 92/107/101 +f 96/111/105 100/115/109 101/116/110 +f 96/111/105 101/116/110 97/112/106 +f 100/115/109 102/117/111 103/118/112 +f 100/115/109 103/118/112 101/116/110 +f 101/116/110 103/118/112 104/119/113 +f 101/116/110 104/119/113 105/120/114 +f 97/112/106 101/116/110 105/120/114 +f 97/112/106 105/120/114 98/113/107 +f 102/117/111 106/121/115 107/122/116 +f 102/117/111 107/122/116 103/118/112 +f 106/121/115 108/123/117 109/124/118 +f 106/121/115 109/124/118 107/122/116 +f 107/122/116 109/124/118 110/125/119 +f 107/122/116 110/125/119 111/126/120 +f 103/118/112 107/122/116 111/126/120 +f 103/118/112 111/126/120 104/119/113 +f 112/127/121 113/128/122 114/129/123 +f 112/127/121 114/129/123 115/130/124 +f 113/128/122 116/131/125 117/132/71 +f 113/128/122 117/132/71 114/129/123 +f 118/133/123 53/80/71 52/79/70 +f 118/133/123 52/79/70 119/134/126 +f 115/130/124 114/129/123 120/135/127 +f 115/130/124 120/135/127 121/136/128 +f 121/136/128 120/135/127 122/137/129 +f 121/136/128 122/137/129 123/138/130 +f 119/134/126 52/79/70 124/139/131 +f 119/134/126 124/139/131 125/140/129 +f 122/137/129 126/141/131 127/142/132 +f 122/137/129 127/142/132 128/143/133 +f 123/138/130 122/137/129 128/143/133 +f 123/138/130 128/143/133 129/144/134 +f 98/113/107 105/120/114 130/145/135 +f 98/113/107 130/145/135 131/146/136 +f 105/120/114 104/119/113 132/147/137 +f 105/120/114 132/147/137 130/145/135 +f 130/145/135 132/147/137 133/148/138 +f 130/145/135 133/148/138 134/149/139 +f 131/146/136 130/145/135 134/149/139 +f 131/146/136 134/149/139 135/150/140 +f 52/79/70 60/84/77 136/151/141 +f 52/79/70 136/151/141 124/139/131 +f 60/84/77 59/83/76 137/152/142 +f 60/84/77 137/152/142 136/151/141 +f 136/151/141 137/152/142 138/153/143 +f 136/151/141 138/153/143 139/154/144 +f 124/139/131 136/151/141 139/154/144 +f 124/139/131 139/154/144 140/155/145 +f 71/87/81 78/93/87 141/156/146 +f 71/87/81 141/156/146 142/157/147 +f 78/93/87 77/92/86 143/158/148 +f 78/93/87 143/158/148 141/156/146 +f 141/156/146 143/158/148 144/159/149 +f 141/156/146 144/159/149 145/160/150 +f 142/157/147 141/156/146 145/160/150 +f 142/157/147 145/160/150 146/161/151 +f 129/144/134 128/143/133 147/162/152 +f 129/144/134 147/162/152 148/163/153 +f 128/143/133 127/142/132 149/164/144 +f 128/143/133 149/164/144 147/162/152 +f 147/162/152 149/164/144 150/165/154 +f 147/162/152 150/165/154 151/166/155 +f 148/163/153 147/162/152 151/166/155 +f 148/163/153 151/166/155 152/167/156 +f 152/167/156 151/166/155 153/168/157 +f 152/167/156 153/168/157 154/169/158 +f 151/166/155 150/165/154 155/170/159 +f 151/166/155 155/170/159 153/168/157 +f 153/168/157 155/170/159 156/171/160 +f 153/168/157 156/171/160 157/172/161 +f 154/169/158 153/168/157 157/172/161 +f 154/169/158 157/172/161 158/173/162 +f 158/173/162 157/172/161 159/174/163 +f 158/173/162 159/174/163 160/24/16 +f 157/172/161 156/171/160 161/175/164 +f 157/172/161 161/175/164 159/174/163 +f 159/174/163 161/175/164 162/176/151 +f 159/174/163 162/176/151 163/177/165 +f 160/24/16 159/174/163 163/177/165 +f 160/24/16 163/177/165 164/178/166 +f 164/178/166 163/177/165 165/179/167 +f 164/178/166 165/179/167 166/180/168 +f 163/177/165 162/176/151 167/181/169 +f 163/177/165 167/181/169 165/179/167 +f 165/179/167 167/181/169 168/182/149 +f 165/179/167 168/182/149 169/183/170 +f 166/180/168 165/179/167 169/183/170 +f 166/180/168 169/183/170 170/184/171 +f 171/185/172 172/186/173 173/187/174 +f 171/185/172 173/187/174 174/188/175 +f 172/186/173 85/100/94 175/189/176 +f 172/186/173 175/189/176 173/187/174 +f 173/187/174 175/189/176 176/190/177 +f 173/187/174 176/190/177 177/191/178 +f 174/188/175 173/187/174 177/191/178 +f 174/188/175 177/191/178 178/192/179 +f 59/83/76 66/86/79 179/193/180 +f 59/83/76 179/193/180 137/152/142 +f 66/86/79 65/85/78 180/194/181 +f 66/86/79 180/194/181 179/193/180 +f 179/193/180 180/194/181 181/195/182 +f 179/193/180 181/195/182 182/196/183 +f 137/152/142 179/193/180 182/196/183 +f 137/152/142 182/196/183 138/153/143 +f 104/119/113 111/126/120 183/197/184 +f 104/119/113 183/197/184 132/147/137 +f 111/126/120 110/125/119 184/198/185 +f 111/126/120 184/198/185 183/197/184 +f 183/197/184 184/198/185 185/199/186 +f 183/197/184 185/199/186 186/200/187 +f 132/147/137 183/197/184 186/200/187 +f 132/147/137 186/200/187 133/148/138 +f 85/100/94 93/108/102 187/201/188 +f 85/100/94 187/201/188 175/189/176 +f 93/108/102 92/107/101 188/202/189 +f 93/108/102 188/202/189 187/201/188 +f 187/201/188 188/202/189 189/203/190 +f 187/201/188 189/203/190 190/204/191 +f 175/189/176 187/201/188 190/204/191 +f 175/189/176 190/204/191 176/190/177 +f 65/85/78 72/88/79 191/205/192 +f 65/85/78 191/205/192 180/194/181 +f 72/88/79 71/87/81 142/157/147 +f 72/88/79 142/157/147 191/205/192 +f 191/205/192 142/157/147 146/161/151 +f 191/205/192 146/161/151 192/206/193 +f 180/194/181 191/205/192 192/206/193 +f 180/194/181 192/206/193 181/195/182 +f 92/107/101 99/114/108 193/207/194 +f 92/107/101 193/207/194 188/202/189 +f 99/114/108 98/113/107 131/146/136 +f 99/114/108 131/146/136 193/207/194 +f 193/207/194 131/146/136 135/150/140 +f 193/207/194 135/150/140 194/208/195 +f 188/202/189 193/207/194 194/208/195 +f 188/202/189 194/208/195 189/203/190 +f 195/209/196 196/210/197 197/211/198 +f 195/209/196 197/211/198 198/212/199 +f 196/210/197 199/213/200 200/214/201 +f 196/210/197 200/214/201 197/211/198 +f 197/211/198 200/214/201 201/215/202 +f 197/211/198 201/215/202 202/216/203 +f 198/212/199 197/211/198 202/216/203 +f 198/212/199 202/216/203 203/217/204 +f 204/218/205 205/219/205 206/220/206 +f 204/218/205 206/220/206 207/221/207 +f 205/219/205 37/64/57 40/67/60 +f 205/219/205 40/67/60 206/220/206 +f 206/220/206 40/67/60 45/72/63 +f 206/220/206 45/72/63 208/222/208 +f 207/221/207 206/220/206 208/222/208 +f 207/221/207 208/222/208 209/223/209 +f 210/224/210 211/225/211 212/226/212 +f 210/224/210 212/226/212 213/20/12 +f 211/225/211 214/227/213 215/228/208 +f 211/225/211 215/228/208 212/226/212 +f 212/226/212 215/228/208 23/50/43 +f 212/226/212 23/50/43 20/47/40 +f 213/20/12 212/226/212 20/47/40 +f 213/20/12 20/47/40 19/46/39 +f 216/229/214 217/230/215 218/231/216 +f 216/229/214 218/231/216 219/232/217 +f 217/230/215 220/233/218 221/234/219 +f 217/230/215 221/234/219 218/231/216 +f 218/231/216 221/234/219 222/235/220 +f 218/231/216 222/235/220 223/236/221 +f 219/232/217 218/231/216 223/236/221 +f 219/232/217 223/236/221 224/237/222 +f 225/238/34 226/239/223 227/240/224 +f 225/238/34 227/240/224 228/241/225 +f 226/239/223 229/242/226 230/243/227 +f 226/239/223 230/243/227 227/240/224 +f 227/240/224 230/243/227 231/244/228 +f 227/240/224 231/244/228 232/245/229 +f 228/241/225 227/240/224 232/245/229 +f 228/241/225 232/245/229 233/246/36 +f 234/247/230 235/248/231 236/249/232 +f 234/247/230 236/249/232 237/250/233 +f 235/248/231 28/55/48 31/58/51 +f 235/248/231 31/58/51 236/249/232 +f 236/249/232 31/58/51 36/63/56 +f 236/249/232 36/63/56 238/251/234 +f 237/250/233 236/249/232 238/251/234 +f 237/250/233 238/251/234 239/252/235 +f 108/123/117 240/253/236 241/254/237 +f 108/123/117 241/254/237 109/124/118 +f 240/253/236 234/247/230 237/250/233 +f 240/253/236 237/250/233 241/254/237 +f 241/254/237 237/250/233 239/252/235 +f 241/254/237 239/252/235 242/255/238 +f 109/124/118 241/254/237 242/255/238 +f 109/124/118 242/255/238 110/125/119 +f 224/237/222 223/236/221 243/256/239 +f 224/237/222 243/256/239 244/16/12 +f 223/236/221 222/235/220 245/257/240 +f 223/236/221 245/257/240 243/256/239 +f 243/256/239 245/257/240 116/131/125 +f 243/256/239 116/131/125 113/128/122 +f 244/16/12 243/256/239 113/128/122 +f 244/16/12 113/128/122 112/127/121 +f 229/242/226 246/258/205 247/259/206 +f 229/242/226 247/259/206 230/243/227 +f 246/258/205 46/73/64 49/76/67 +f 246/258/205 49/76/67 247/259/206 +f 247/259/206 49/76/67 54/81/72 +f 247/259/206 54/81/72 248/260/240 +f 230/243/227 247/259/206 248/260/240 +f 230/243/227 248/260/240 231/244/228 +f 249/261/241 250/262/242 251/263/243 +f 249/261/241 251/263/243 252/264/244 +f 253/265/245 77/92/86 254/266/246 +f 253/265/245 254/266/246 255/267/247 +f 251/263/243 256/268/246 214/227/213 +f 251/263/243 214/227/213 211/225/211 +f 252/264/244 251/263/243 211/225/211 +f 252/264/244 211/225/211 210/224/210 +f 75/90/84 257/269/248 258/270/249 +f 75/90/84 258/270/249 76/91/85 +f 257/269/248 204/218/205 207/221/207 +f 257/269/248 207/221/207 258/270/249 +f 258/270/249 207/221/207 209/223/209 +f 258/270/249 209/223/209 254/266/246 +f 76/91/85 258/270/249 254/266/246 +f 76/91/85 254/266/246 77/92/86 +f 199/213/200 259/271/250 260/272/251 +f 199/213/200 260/272/251 200/214/201 +f 259/271/250 79/94/88 82/97/91 +f 259/271/250 82/97/91 260/272/251 +f 260/272/251 82/97/91 87/102/96 +f 260/272/251 87/102/96 261/273/252 +f 200/214/201 260/272/251 261/273/252 +f 200/214/201 261/273/252 201/215/202 +f 171/185/172 262/274/253 263/275/254 +f 171/185/172 263/275/254 264/276/255 +f 262/274/253 249/261/241 252/264/244 +f 262/274/253 252/264/244 263/275/254 +f 263/275/254 252/264/244 210/224/210 +f 263/275/254 210/224/210 265/18/11 +f 264/276/255 263/275/254 265/18/11 +f 264/276/255 265/18/11 266/17/9 +f 267/13/5 269/15/7 270/277/256 +f 268/14/6 224/237/222 244/16/12 +f 269/15/7 244/16/12 112/127/121 +f 269/15/7 112/127/121 271/278/257 +f 270/277/256 269/15/7 271/278/257 +f 270/277/256 271/278/257 272/279/258 +f 273/280/259 274/281/260 275/282/261 +f 273/280/259 275/282/261 276/283/262 +f 274/281/260 216/229/214 219/232/217 +f 274/281/260 219/232/217 275/282/261 +f 275/282/261 219/232/217 224/237/222 +f 275/282/261 224/237/222 268/14/6 +f 276/283/262 275/282/261 268/14/6 +f 276/283/262 268/14/6 267/13/5 +f 266/17/9 277/19/7 278/284/263 +f 265/18/11 210/224/210 213/20/12 +f 277/19/7 213/20/12 19/46/39 +f 277/19/7 19/46/39 279/285/264 +f 278/284/263 277/19/7 279/285/264 +f 278/284/263 279/285/264 280/286/265 +f 77/92/86 253/265/245 281/287/266 +f 77/92/86 281/287/266 143/158/148 +f 250/262/242 249/261/241 282/288/267 +f 250/262/242 282/288/267 283/289/266 +f 283/289/266 282/288/267 170/184/171 +f 283/289/266 170/184/171 169/183/170 +f 284/290/148 283/289/266 169/183/170 +f 284/290/148 169/183/170 168/182/149 +f 285/291/268 286/292/269 287/293/270 +f 285/291/268 287/293/270 288/294/271 +f 286/292/269 164/178/166 166/180/168 +f 286/292/269 166/180/168 287/293/270 +f 287/293/270 166/180/168 170/184/171 +f 287/293/270 170/184/171 289/295/272 +f 288/294/271 287/293/270 289/295/272 +f 288/294/271 289/295/272 178/192/179 +f 290/21/273 292/23/7 293/296/274 +f 291/22/275 158/173/162 160/24/16 +f 292/23/7 160/24/16 164/178/166 +f 292/23/7 164/178/166 286/292/269 +f 293/296/274 292/23/7 286/292/269 +f 293/296/274 286/292/269 285/291/268 +f 294/297/276 295/298/277 296/299/278 +f 294/297/276 296/299/278 297/300/279 +f 295/298/277 152/167/156 154/169/158 +f 295/298/277 154/169/158 296/299/278 +f 296/299/278 154/169/158 158/173/162 +f 296/299/278 158/173/162 291/22/275 +f 297/300/279 296/299/278 291/22/275 +f 297/300/279 291/22/275 290/21/273 +f 298/301/280 299/302/281 300/303/282 +f 298/301/280 300/303/282 301/304/283 +f 299/302/281 129/144/134 148/163/153 +f 299/302/281 148/163/153 300/303/282 +f 300/303/282 148/163/153 152/167/156 +f 300/303/282 152/167/156 295/298/277 +f 301/304/283 300/303/282 295/298/277 +f 301/304/283 295/298/277 294/297/276 +f 302/305/284 303/306/285 304/307/286 +f 302/305/284 304/307/286 305/308/287 +f 303/306/285 121/136/128 123/138/130 +f 303/306/285 123/138/130 304/307/286 +f 304/307/286 123/138/130 129/144/134 +f 304/307/286 129/144/134 299/302/281 +f 305/308/287 304/307/286 299/302/281 +f 305/308/287 299/302/281 298/301/280 +f 272/279/258 271/278/257 306/309/288 +f 272/279/258 306/309/288 307/310/289 +f 271/278/257 112/127/121 115/130/124 +f 271/278/257 115/130/124 306/309/288 +f 306/309/288 115/130/124 121/136/128 +f 306/309/288 121/136/128 303/306/285 +f 307/310/289 306/309/288 303/306/285 +f 307/310/289 303/306/285 302/305/284 +f 280/286/265 279/285/264 308/311/290 +f 280/286/265 308/311/290 309/312/291 +f 279/285/264 19/46/39 22/49/42 +f 279/285/264 22/49/42 308/311/290 +f 308/311/290 22/49/42 27/54/47 +f 308/311/290 27/54/47 310/313/292 +f 309/312/291 308/311/290 310/313/292 +f 309/312/291 310/313/292 311/314/293 +f 312/315/294 313/316/295 314/317/296 +f 312/315/294 314/317/296 315/318/297 +f 313/316/295 10/37/30 13/40/33 +f 313/316/295 13/40/33 314/317/296 +f 314/317/296 13/40/33 18/45/38 +f 314/317/296 18/45/38 316/319/298 +f 315/318/297 314/317/296 316/319/298 +f 315/318/297 316/319/298 317/320/259 +f 318/321/299 319/322/292 320/25/17 +f 318/321/299 320/25/17 321/28/300 +f 319/322/292 1/29/21 4/32/24 +f 319/322/292 4/32/24 320/25/17 +f 320/25/17 4/32/24 9/26/29 +f 321/28/300 322/27/301 323/323/302 +f 324/324/303 325/325/304 326/326/305 +f 324/324/303 326/326/305 327/327/306 +f 325/325/304 318/321/299 321/28/300 +f 325/325/304 321/28/300 326/326/305 +f 326/326/305 321/28/300 323/323/302 +f 326/326/305 323/323/302 328/328/307 +f 327/327/306 326/326/305 328/328/307 +f 327/327/306 328/328/307 329/329/196 +f 330/330/52 331/331/308 332/332/309 +f 330/330/52 332/332/309 333/333/310 +f 331/331/308 312/315/294 315/318/297 +f 331/331/308 315/318/297 332/332/309 +f 332/332/309 315/318/297 317/320/259 +f 332/332/309 317/320/259 334/334/311 +f 333/333/310 332/332/309 334/334/311 +f 333/333/310 334/334/311 335/335/312 +f 201/215/202 336/336/313 337/337/314 +f 201/215/202 337/337/314 202/216/203 +f 336/336/313 280/286/265 309/312/291 +f 336/336/313 309/312/291 337/337/314 +f 337/337/314 309/312/291 311/314/293 +f 337/337/314 311/314/293 338/338/315 +f 202/216/203 337/337/314 338/338/315 +f 202/216/203 338/338/315 203/217/204 +f 239/252/235 339/339/316 340/340/317 +f 239/252/235 340/340/317 242/255/238 +f 339/339/316 272/279/258 307/310/289 +f 339/339/316 307/310/289 340/340/317 +f 340/340/317 307/310/289 302/305/284 +f 340/340/317 302/305/284 341/341/318 +f 242/255/238 340/340/317 341/341/318 +f 242/255/238 341/341/318 110/125/119 +f 110/125/119 341/341/318 342/342/319 +f 110/125/119 342/342/319 184/198/185 +f 341/341/318 302/305/284 305/308/287 +f 341/341/318 305/308/287 342/342/319 +f 342/342/319 305/308/287 298/301/280 +f 342/342/319 298/301/280 343/343/320 +f 184/198/185 342/342/319 343/343/320 +f 184/198/185 343/343/320 185/199/186 +f 185/199/186 343/343/320 344/344/321 +f 185/199/186 344/344/321 186/200/187 +f 343/343/320 298/301/280 301/304/283 +f 343/343/320 301/304/283 344/344/321 +f 344/344/321 301/304/283 294/297/276 +f 344/344/321 294/297/276 345/345/322 +f 186/200/187 344/344/321 345/345/322 +f 186/200/187 345/345/322 133/148/138 +f 133/148/138 345/345/322 346/346/323 +f 133/148/138 346/346/323 134/149/139 +f 345/345/322 294/297/276 297/300/279 +f 345/345/322 297/300/279 346/346/323 +f 346/346/323 297/300/279 290/21/273 +f 346/346/323 290/21/273 347/347/324 +f 134/149/139 346/346/323 347/347/324 +f 134/149/139 347/347/324 135/150/140 +f 135/150/140 347/347/324 348/348/325 +f 135/150/140 348/348/325 194/208/195 +f 347/347/324 290/21/273 293/296/274 +f 347/347/324 293/296/274 348/348/325 +f 348/348/325 293/296/274 285/291/268 +f 348/348/325 285/291/268 349/349/326 +f 194/208/195 348/348/325 349/349/326 +f 194/208/195 349/349/326 189/203/190 +f 189/203/190 349/349/326 350/350/327 +f 189/203/190 350/350/327 190/204/191 +f 349/349/326 285/291/268 288/294/271 +f 349/349/326 288/294/271 350/350/327 +f 350/350/327 288/294/271 178/192/179 +f 350/350/327 178/192/179 177/191/178 +f 190/204/191 350/350/327 177/191/178 +f 190/204/191 177/191/178 176/190/177 +f 87/102/96 351/351/328 352/352/329 +f 87/102/96 352/352/329 261/273/252 +f 351/351/328 266/17/9 278/284/263 +f 351/351/328 278/284/263 352/352/329 +f 352/352/329 278/284/263 280/286/265 +f 352/352/329 280/286/265 336/336/313 +f 261/273/252 352/352/329 336/336/313 +f 261/273/252 336/336/313 201/215/202 +f 34/61/54 353/353/311 354/354/330 +f 34/61/54 354/354/330 35/62/55 +f 353/353/311 273/280/259 276/283/262 +f 353/353/311 276/283/262 354/354/330 +f 354/354/330 276/283/262 267/13/5 +f 354/354/330 267/13/5 355/355/331 +f 35/62/55 354/354/330 355/355/331 +f 35/62/55 355/355/331 36/63/56 +f 36/63/56 355/355/331 356/356/332 +f 36/63/56 356/356/332 238/251/234 +f 355/355/331 267/13/5 270/277/256 +f 355/355/331 270/277/256 356/356/332 +f 356/356/332 270/277/256 272/279/258 +f 356/356/332 272/279/258 339/339/316 +f 238/251/234 356/356/332 339/339/316 +f 238/251/234 339/339/316 239/252/235 +f 85/100/94 172/186/173 357/357/333 +f 85/100/94 357/357/333 86/101/95 +f 172/186/173 171/185/172 264/276/255 +f 172/186/173 264/276/255 357/357/333 +f 357/357/333 264/276/255 266/17/9 +f 357/357/333 266/17/9 351/351/328 +f 86/101/95 357/357/333 351/351/328 +f 86/101/95 351/351/328 87/102/96 +f 249/261/241 262/274/253 358/358/334 +f 249/261/241 358/358/334 282/288/267 +f 262/274/253 171/185/172 174/188/175 +f 262/274/253 174/188/175 358/358/334 +f 358/358/334 174/188/175 178/192/179 +f 358/358/334 178/192/179 289/295/272 +f 282/288/267 358/358/334 289/295/272 +f 282/288/267 289/295/272 170/184/171 +o Plane.008__0 +v -1.180226 -0.143283 -0.149002 +v -1.218160 -0.115742 -0.147101 +v -1.281381 -0.266515 -0.153075 +v -1.244086 -0.300418 -0.155262 +v -1.256066 -0.088140 -0.145197 +v -1.318656 -0.232550 -0.150886 +v -1.364044 -0.366243 -0.156358 +v -1.327153 -0.409081 -0.158954 +v -1.290235 -0.451770 -0.161543 +v -0.595620 1.146296 -0.098619 +v -0.550757 1.168050 -0.098342 +v -0.548477 1.207807 -0.096531 +v -0.595330 1.181730 -0.096976 +v -0.506078 1.179052 -0.098562 +v -0.501717 1.220628 -0.096700 +v -0.501168 1.232594 -0.096153 +v -0.548672 1.219239 -0.095996 +v -0.596076 1.191992 -0.096487 +v -0.605421 0.459350 -0.130396 +v -0.548514 0.466041 -0.131017 +v -0.534908 0.600446 -0.124991 +v -0.583055 0.593130 -0.124542 +v -0.488570 0.474458 -0.131607 +v -0.486032 0.608616 -0.125411 +v -0.495840 0.726866 -0.119753 +v -0.534909 0.721260 -0.119374 +v -0.575873 0.715897 -0.118952 +v 0.008788 -0.451053 -0.182780 +v -0.129566 -0.445634 -0.180263 +v -0.140569 -0.680712 -0.191012 +v 0.009458 -0.690322 -0.193915 +v -0.256866 -0.433085 -0.177595 +v -0.277582 -0.661270 -0.187865 +v -0.297824 -0.869838 -0.197230 +v -0.152416 -0.892030 -0.200642 +v 0.007756 -0.903205 -0.203784 +v -0.323359 0.504518 -0.132915 +v -0.281959 0.519061 -0.132916 +v -0.324329 0.644574 -0.126387 +v -0.353268 0.633553 -0.126426 +v -0.211839 0.540519 -0.133067 +v -0.293435 0.658064 -0.126266 +v -0.352569 0.758585 -0.120624 +v -0.372964 0.752018 -0.120596 +v -0.393454 0.745513 -0.120562 +v -0.320807 0.250176 -0.144781 +v -0.282370 0.229369 -0.146378 +v -0.273962 0.360730 -0.140408 +v -0.320463 0.352925 -0.140010 +v -0.206115 0.230432 -0.147577 +v -0.200641 0.368187 -0.141262 +v -0.108534 0.235760 -0.148927 +v -0.106285 0.364195 -0.142993 +v -0.000887 0.237960 -0.150588 +v -0.002451 0.360844 -0.144849 +v -0.004014 0.483697 -0.139111 +v -0.104640 0.495344 -0.136923 +v -0.832800 0.463774 -0.126467 +v -0.784932 0.458135 -0.127513 +v -0.747005 0.586015 -0.122189 +v -0.792200 0.589365 -0.121293 +v -0.723904 0.454033 -0.128703 +v -0.690011 0.584476 -0.123194 +v -0.674364 0.708571 -0.117680 +v -0.728434 0.709728 -0.116741 +v -0.771668 0.712626 -0.115899 +v -0.961982 0.178266 -0.137626 +v -0.909683 0.162412 -0.139220 +v -0.839580 0.319702 -0.133055 +v -0.889669 0.329869 -0.131762 +v -0.841303 0.145338 -0.141133 +v -0.774633 0.310113 -0.134564 +v -0.699089 0.125460 -0.144386 +v -0.625464 0.118499 -0.145915 +v -0.577536 0.307724 -0.137902 +v -0.643101 0.305884 -0.136914 +v -0.548919 0.113478 -0.147402 +v -0.508852 0.311655 -0.138844 +v -0.827375 1.106540 -0.096672 +v -0.762231 1.103168 -0.097896 +v -0.764438 1.129081 -0.096655 +v -0.830495 1.132607 -0.095409 +v -0.698942 1.106907 -0.098758 +v -0.700605 1.134162 -0.097464 +v -0.701450 1.142554 -0.097060 +v -0.765193 1.137184 -0.096266 +v -0.831623 1.140765 -0.095012 +v -0.728959 0.828388 -0.111216 +v -0.770345 0.829668 -0.110479 +v -0.676062 0.827254 -0.112135 +v -0.684466 0.916917 -0.107828 +v -0.736910 0.915873 -0.107018 +v -0.769280 0.901102 -0.107175 +v -0.545580 0.833439 -0.113984 +v -0.582366 0.830675 -0.113510 +v -0.511431 0.836768 -0.114388 +v -0.524965 0.919155 -0.110336 +v -0.557766 0.917182 -0.109891 +v -0.592655 0.916488 -0.109352 +v -0.411649 1.153555 -0.101294 +v -0.366463 1.129914 -0.103133 +v -0.355997 1.158621 -0.101969 +v -0.403721 1.187843 -0.099829 +v -0.331544 1.111354 -0.104567 +v -0.319776 1.136451 -0.103593 +v -0.323621 1.147466 -0.103018 +v -0.353393 1.167408 -0.101603 +v -0.401433 1.197733 -0.099407 +v -0.401919 0.864413 -0.114896 +v -0.422106 0.858977 -0.114818 +v -0.382768 0.868268 -0.115030 +v -0.383127 0.973777 -0.110119 +v -0.406882 0.974075 -0.109716 +v -0.443572 0.973907 -0.109123 +v -0.471812 -0.394417 -0.172277 +v -0.570314 -0.371377 -0.169594 +v -0.611768 -0.576451 -0.178449 +v -0.506845 -0.607081 -0.181591 +v -0.666299 -0.345907 -0.166838 +v -0.713576 -0.543465 -0.175249 +v -0.752177 -0.736669 -0.183599 +v -0.646338 -0.774068 -0.187071 +v -0.537146 -0.808307 -0.190450 +v -0.383583 0.121776 -0.149723 +v -0.469289 0.112584 -0.148747 +v -0.518772 -0.130948 -0.159259 +v -0.428953 -0.143001 -0.161290 +v -0.606605 -0.117300 -0.157187 +v -0.770586 0.133526 -0.142840 +v -0.847759 -0.063221 -0.150724 +v -0.772735 -0.081915 -0.152821 +v -0.920468 -0.041867 -0.148540 +v -0.997971 -0.229610 -0.156000 +v -0.923754 -0.259765 -0.158617 +v -0.845964 -0.288516 -0.161228 +v 0.001749 0.058785 -0.158961 +v -0.112966 0.055996 -0.157212 +v -0.119822 -0.171156 -0.167661 +v 0.005417 -0.171919 -0.169747 +v -0.218804 0.051559 -0.155686 +v -0.235517 -0.167820 -0.165612 +v -1.011952 0.195691 -0.135998 +v -1.050673 0.209476 -0.134723 +v -1.137522 0.048237 -0.140797 +v -1.098209 0.027839 -0.142389 +v -1.089337 0.223379 -0.133444 +v -1.176790 0.068725 -0.139202 +v -0.983640 -0.435257 -0.165796 +v -0.902051 -0.470997 -0.168793 +v -1.060655 -0.398939 -0.162846 +v -1.110084 -0.566130 -0.169810 +v -1.031579 -0.608853 -0.173082 +v -0.947108 -0.651242 -0.176436 +v -0.606223 -1.329103 -0.213533 +v -0.721657 -1.294463 -0.210032 +v -0.732346 -1.390920 -0.214342 +v -0.617229 -1.426759 -0.217893 +v -0.834562 -1.250284 -0.206129 +v -0.844310 -1.345171 -0.210381 +v -0.854103 -1.440032 -0.214631 +v -0.743065 -1.487363 -0.218650 +v -0.628242 -1.524413 -0.222253 +v -1.043432 -1.128656 -0.197055 +v -1.125159 -1.065540 -0.192782 +v -1.128127 -1.162135 -0.197224 +v -1.048977 -1.224511 -0.201420 +v -1.195930 -1.000032 -0.188578 +v -1.196582 -1.095911 -0.193025 +v -1.197251 -1.191772 -0.197470 +v -1.131147 -1.258685 -0.201664 +v -1.054564 -1.320334 -0.205784 +v -1.321855 -0.790985 -0.176797 +v -1.372468 -0.690557 -0.171299 +v -1.375423 -0.812070 -0.176900 +v -1.323091 -0.920595 -0.182802 +v -1.409389 -0.615186 -0.167190 +v -1.412290 -0.726823 -0.172333 +v -1.405098 -0.808962 -0.176270 +v -1.374104 -0.897532 -0.180895 +v -1.321622 -1.012691 -0.187108 +v 0.000119 -1.402047 -0.226852 +v -0.181279 -1.398349 -0.223710 +v -0.186775 -1.492542 -0.227999 +v -0.001473 -1.496501 -0.231217 +v -0.346226 -1.383319 -0.220310 +v -0.355399 -1.478290 -0.224576 +v -0.364538 -1.573263 -0.228842 +v -0.192250 -1.586737 -0.232289 +v -0.003068 -1.590957 -0.235583 +v 1.173513 -0.133780 -0.187100 +v 1.238368 -0.313013 -0.196495 +v 1.277339 -0.282430 -0.195711 +v 1.212558 -0.105507 -0.186425 +v 1.285421 -0.487321 -0.205369 +v 1.323656 -0.453830 -0.204438 +v 1.361885 -0.420279 -0.203504 +v 1.316306 -0.251831 -0.194926 +v 1.251578 -0.077179 -0.185746 +v 0.589368 0.983698 -0.125581 +v 0.581865 1.024334 -0.123569 +v 0.542602 1.031371 -0.122599 +v 0.545811 0.985393 -0.124789 +v 0.574957 1.064890 -0.121570 +v 0.539998 1.077305 -0.120420 +v 0.505547 1.084808 -0.119508 +v 0.504409 1.034483 -0.121829 +v 0.503904 0.984215 -0.124157 +v 0.598972 0.474784 -0.149399 +v 0.576784 0.604328 -0.143013 +v 0.532067 0.609987 -0.142017 +v 0.551977 0.478912 -0.148438 +v 0.570783 0.719938 -0.137539 +v 0.524441 0.724900 -0.136550 +v 0.480073 0.729056 -0.135630 +v 0.483993 0.615487 -0.140975 +v 0.497388 0.483576 -0.147327 +v 0.164573 -0.687316 -0.196315 +v 0.150872 -0.448059 -0.184967 +v 0.173389 -0.900369 -0.206365 +v 0.328829 -0.886716 -0.208275 +v 0.310247 -0.674722 -0.198115 +v 0.283946 -0.438523 -0.186703 +v 0.325403 0.504034 -0.143560 +v 0.348529 0.631820 -0.137997 +v 0.317352 0.640747 -0.137072 +v 0.281464 0.517706 -0.142205 +v 0.379789 0.737610 -0.133591 +v 0.358063 0.739403 -0.133152 +v 0.336482 0.741480 -0.132702 +v 0.284173 0.652217 -0.135995 +v 0.208147 0.538565 -0.140034 +v 0.322504 0.250082 -0.155319 +v 0.323559 0.352716 -0.150565 +v 0.275240 0.360208 -0.149425 +v 0.282956 0.229213 -0.155642 +v 0.199452 0.367498 -0.147845 +v 0.205672 0.230233 -0.154329 +v 0.102608 0.363772 -0.146433 +v 0.107180 0.235626 -0.152466 +v 0.098461 0.494559 -0.140285 +v 0.820107 0.477297 -0.152903 +v 0.783331 0.599070 -0.146639 +v 0.733203 0.596628 -0.145932 +v 0.765372 0.472903 -0.152211 +v 0.769041 0.715982 -0.140970 +v 0.724091 0.713417 -0.140353 +v 0.669114 0.712572 -0.139492 +v 0.673606 0.595976 -0.144986 +v 0.700719 0.470034 -0.151286 +v 0.957789 0.185113 -0.168741 +v 0.880310 0.340032 -0.160270 +v 0.825468 0.330534 -0.159814 +v 0.905278 0.167836 -0.168685 +v 0.758016 0.321556 -0.159127 +v 0.836846 0.148875 -0.168446 +v 0.697860 0.125950 -0.167236 +v 0.638851 0.316529 -0.157409 +v 0.581635 0.316512 -0.156473 +v 0.629295 0.118639 -0.166453 +v 0.517897 0.317818 -0.155369 +v 0.556958 0.113506 -0.165508 +v 0.807865 0.957289 -0.130386 +v 0.808877 1.033309 -0.126869 +v 0.739184 1.023394 -0.126188 +v 0.746232 0.983570 -0.128155 +v 0.807015 1.080704 -0.124635 +v 0.730702 1.060892 -0.124306 +v 0.662580 1.049287 -0.123730 +v 0.674133 1.015885 -0.125473 +v 0.685554 0.982500 -0.127212 +v 0.770723 0.830072 -0.135693 +v 0.729123 0.828847 -0.135069 +v 0.770172 0.901093 -0.132382 +v 0.737825 0.915871 -0.131165 +v 0.685383 0.916917 -0.130258 +v 0.676111 0.827754 -0.134252 +v 0.577798 0.831296 -0.132477 +v 0.531237 0.833929 -0.131592 +v 0.588024 0.916536 -0.128681 +v 0.542205 0.916788 -0.127919 +v 0.499445 0.915093 -0.127298 +v 0.488380 0.835127 -0.130835 +v 0.425450 0.937882 -0.125027 +v 0.433415 1.020805 -0.121302 +v 0.404236 1.011349 -0.121264 +v 0.396408 0.927024 -0.125057 +v 0.437891 1.079683 -0.118638 +v 0.408131 1.071689 -0.118522 +v 0.389655 1.056250 -0.118938 +v 0.383227 1.004359 -0.121245 +v 0.376221 0.919976 -0.125053 +v 0.402419 0.837671 -0.129309 +v 0.383065 0.834187 -0.129154 +v 0.364313 0.830180 -0.129034 +v 0.501440 -0.407473 -0.188820 +v 0.547028 -0.633775 -0.200088 +v 0.654979 -0.607704 -0.200644 +v 0.602050 -0.387268 -0.189528 +v 0.580407 -0.840875 -0.210263 +v 0.693649 -0.811259 -0.210740 +v 0.795807 -0.778708 -0.210900 +v 0.753122 -0.579490 -0.200939 +v 0.695075 -0.365124 -0.190022 +v 0.388647 0.121156 -0.162396 +v 0.445103 -0.147505 -0.175812 +v 0.536364 -0.136698 -0.176803 +v 0.477489 0.112155 -0.164269 +v 0.622556 -0.124655 -0.177655 +v 0.773850 -0.092583 -0.178641 +v 0.849280 -0.070909 -0.178868 +v 0.766762 0.135243 -0.167932 +v 0.850390 -0.313919 -0.190184 +v 0.928277 -0.280164 -0.189890 +v 1.005411 -0.240770 -0.189322 +v 0.924146 -0.043863 -0.178836 +v 0.132686 -0.171529 -0.171813 +v 0.117119 0.055967 -0.160981 +v 0.251318 -0.169054 -0.173640 +v 0.223889 0.051325 -0.162945 +v 1.007993 0.202295 -0.168765 +v 1.093116 0.040093 -0.177700 +v 1.132772 0.061610 -0.177349 +v 1.046936 0.214233 -0.168847 +v 1.172371 0.083239 -0.176991 +v 1.085798 0.226327 -0.168921 +v 0.911565 -0.515335 -0.200550 +v 0.990419 -0.473938 -0.199917 +v 0.957812 -0.704575 -0.210106 +v 1.035743 -0.659204 -0.209272 +v 1.113010 -0.609523 -0.208228 +v 1.068607 -0.427739 -0.199049 +v 0.625505 -1.321714 -0.233357 +v 0.628449 -1.416860 -0.237829 +v 0.752022 -1.376524 -0.237977 +v 0.748383 -1.283146 -0.233576 +v 0.631427 -1.511993 -0.242301 +v 0.755708 -1.469884 -0.242378 +v 0.867537 -1.421295 -0.241950 +v 0.863650 -1.329625 -0.237624 +v 0.859814 -1.237927 -0.233298 +v 1.030349 -1.138797 -0.231482 +v 1.031344 -1.229744 -0.235726 +v 1.097072 -1.181483 -0.234559 +v 1.098907 -1.089918 -0.230331 +v 1.032394 -1.320652 -0.239970 +v 1.095280 -1.273015 -0.238785 +v 1.154902 -1.220061 -0.237299 +v 1.160560 -1.126660 -0.233049 +v 1.166199 -1.033285 -0.228800 +v 1.305095 -0.828657 -0.221561 +v 1.291317 -0.971158 -0.227961 +v 1.344189 -0.886111 -0.224872 +v 1.354794 -0.751280 -0.218777 +v 1.278024 -1.074110 -0.232529 +v 1.331569 -0.984977 -0.229262 +v 1.364836 -0.912262 -0.226426 +v 1.380539 -0.822414 -0.222506 +v 1.390347 -0.695916 -0.216785 +v 0.183939 -1.488730 -0.233892 +v 0.183258 -1.393387 -0.229448 +v 0.184609 -1.584074 -0.238336 +v 0.355905 -1.567891 -0.240388 +v 0.354196 -1.471767 -0.235891 +v 0.352484 -1.375644 -0.231394 +v -0.484915 -1.359236 -0.216920 +v -0.495728 -1.455941 -0.221239 +v -0.506518 -1.552649 -0.225558 +v -0.308915 0.057512 -0.153934 +v -0.337045 -0.158987 -0.163538 +v -0.369315 -0.415420 -0.174932 +v -0.397726 -0.635893 -0.184717 +v -0.423709 -0.840888 -0.193823 +v -0.456578 0.732595 -0.120130 +v -0.477266 0.840469 -0.114775 +v -0.425014 0.737543 -0.120416 +v -0.450194 0.843256 -0.115089 +v -0.466770 0.907746 -0.111819 +v -0.491154 0.919842 -0.110858 +v -0.459285 1.172621 -0.099627 +v -0.453286 1.211938 -0.097897 +v -0.451965 1.223248 -0.097393 +v -0.437175 0.318156 -0.139715 +v -0.377902 0.327481 -0.140253 +v -0.373507 0.492142 -0.132669 +v -0.424959 0.484036 -0.132203 +v -0.434967 0.617038 -0.125856 +v -0.393629 0.623783 -0.126219 +v -0.944422 -1.192649 -0.201651 +v -0.952363 -1.287529 -0.205932 +v -0.960348 -1.382382 -0.210211 +v -0.759354 -0.317707 -0.164003 +v -0.811364 -0.507655 -0.171983 +v -0.853357 -0.694782 -0.179995 +v -0.691921 -0.100346 -0.155001 +v -0.622381 0.711074 -0.118415 +v -0.625877 0.828169 -0.112914 +v -0.634678 0.916145 -0.108680 +v -0.708422 0.305939 -0.135842 +v -0.663383 0.454770 -0.129660 +v -0.634483 0.587225 -0.123975 +v -0.643889 1.123110 -0.098906 +v -0.644857 1.153864 -0.097461 +v -0.645779 1.163017 -0.097020 +v -1.262402 -0.922011 -0.183862 +v -1.262031 -1.018011 -0.188331 +v -1.260998 -1.111773 -0.192707 +v -0.991654 -0.016728 -0.146206 +v -1.046607 0.004622 -0.144314 +v -1.128217 -0.171818 -0.151181 +v -1.071257 -0.197558 -0.153310 +v -0.871295 0.719076 -0.113967 +v -0.842384 0.718109 -0.114486 +v -0.846520 0.842484 -0.108636 +v -0.877892 0.842072 -0.108141 +v -0.813430 0.716786 -0.115021 +v -0.813781 0.841588 -0.109213 +v -0.810177 0.961104 -0.103716 +v -0.861159 0.958549 -0.103000 +v -0.896918 0.958091 -0.102436 +v -0.929000 1.114444 -0.094641 +v -0.885927 1.110472 -0.095531 +v -0.890286 1.137208 -0.094217 +v -0.933395 1.141938 -0.093291 +v -0.891432 1.145331 -0.093820 +v -0.927016 1.148222 -0.093103 +v -0.970487 0.351726 -0.129422 +v -1.004526 0.361309 -0.128419 +v -0.936397 0.342266 -0.130420 +v -0.876230 0.472037 -0.125372 +v -0.905340 0.478473 -0.124596 +v -0.934417 0.485005 -0.123816 +v -0.861637 0.598007 -0.119754 +v -0.889322 0.601508 -0.119138 +v -0.833933 0.594501 -0.120371 +v -1.135083 -0.361953 -0.159908 +v -1.192230 -0.333092 -0.157630 +v -1.239228 -0.489954 -0.164154 +v -1.183674 -0.523075 -0.166603 +v -1.219751 -0.688862 -0.173720 +v -1.149969 -0.742123 -0.177339 +v -1.270473 -0.647398 -0.170962 +v -1.278564 -0.754845 -0.175825 +v -1.242600 -0.816010 -0.179258 +v -1.177898 -0.881298 -0.183352 +v -0.892713 -0.897780 -0.188788 +v -0.787624 -0.946534 -0.192776 +v -0.989227 -0.845336 -0.184770 +v -1.021598 -1.000925 -0.191473 +v -0.922924 -1.061234 -0.195893 +v -0.814383 -1.115776 -0.200206 +v -0.449191 -1.054499 -0.203337 +v -0.317913 -1.082785 -0.206801 +v -0.566178 -1.021833 -0.199903 +v -0.588428 -1.192410 -0.207469 +v -0.468832 -1.223719 -0.210883 +v -0.333367 -1.249816 -0.214314 +v 0.004804 -1.111970 -0.213442 +v 0.178571 -1.107019 -0.216057 +v 0.002162 -1.272300 -0.220853 +v 0.181276 -1.264627 -0.223429 +v 0.347732 -1.247447 -0.225356 +v 0.340878 -1.091642 -0.218000 +v 1.312541 -0.650399 -0.213395 +v 1.349599 -0.607342 -0.212000 +v 1.385626 -0.564805 -0.210612 +v 0.992671 -0.886415 -0.219131 +v 1.067323 -0.838970 -0.218147 +v 1.015745 -1.023309 -0.225873 +v 1.087021 -0.974838 -0.224787 +v 1.157358 -0.919198 -0.223351 +v 1.141164 -0.786062 -0.216896 +v 0.602999 -1.042175 -0.219992 +v 0.720533 -1.009000 -0.220374 +v 0.616383 -1.195391 -0.227334 +v 0.736983 -1.159281 -0.227630 +v 0.846283 -1.117250 -0.227466 +v 0.826647 -0.971373 -0.220362 +v -0.164433 -1.103147 -0.210261 +v -0.173686 -1.266931 -0.217724 +v -1.357511 -0.551463 -0.165077 +v -1.320166 -0.609776 -0.168399 +v -1.393739 -0.493851 -0.161805 +v -1.073699 -0.794052 -0.181002 +v -1.104865 -0.941689 -0.187356 +v -0.678418 -0.986948 -0.196443 +v -0.702675 -1.158107 -0.204003 +v 0.479619 -1.069780 -0.219255 +v 0.461866 -0.866360 -0.209507 +v 0.489907 -1.224486 -0.226616 +v 0.499229 -1.448203 -0.237170 +v 0.496893 -1.352093 -0.232663 +v 0.501580 -1.544311 -0.241677 +v 0.353280 -0.161823 -0.174973 +v 0.314076 0.056855 -0.164165 +v 0.398262 -0.424734 -0.187933 +v 0.435108 -0.656408 -0.199308 +v 0.452931 0.833684 -0.130322 +v 0.440355 0.731869 -0.134849 +v 0.463456 0.907893 -0.127044 +v 0.441180 0.890926 -0.127468 +v 0.428347 0.831369 -0.130027 +v 0.410767 0.733886 -0.134271 +v 0.467680 1.030695 -0.121403 +v 0.464793 0.975116 -0.123940 +v 0.471194 1.084596 -0.118955 +v 0.445675 0.321402 -0.154020 +v 0.433037 0.488945 -0.146024 +v 0.378475 0.493723 -0.144908 +v 0.383464 0.328473 -0.152673 +v 0.432456 0.620560 -0.139895 +v 0.390367 0.624503 -0.139022 +v 1.211306 -0.728589 -0.215373 +v 1.183579 -0.560073 -0.207084 +v 1.225702 -0.851260 -0.221312 +v 1.266157 -0.787433 -0.219007 +v 1.262920 -0.683073 -0.214102 +v 1.235561 -0.522713 -0.206198 +v 1.227193 -1.056387 -0.230873 +v 1.237023 -0.956318 -0.226382 +v 1.216898 -1.153989 -0.235242 +v 0.992863 -0.012335 -0.178496 +v 1.074465 -0.199004 -0.188510 +v 1.124558 -0.166013 -0.187797 +v 1.043583 0.013980 -0.178103 +v 0.865284 0.716872 -0.142504 +v 0.874449 0.842071 -0.136834 +v 0.844464 0.842375 -0.136328 +v 0.838095 0.718027 -0.142005 +v 0.896002 0.958252 -0.131785 +v 0.859334 0.956524 -0.131265 +v 0.813244 0.841522 -0.135857 +v 0.810866 0.718827 -0.141522 +v 0.912742 1.049568 -0.127813 +v 0.870085 1.042957 -0.127422 +v 0.913168 1.096453 -0.125640 +v 0.875305 1.096988 -0.124996 +v 1.000539 0.354484 -0.161567 +v 0.965395 0.351527 -0.161129 +v 0.929092 0.474737 -0.154806 +v 0.898568 0.477425 -0.154181 +v 0.867996 0.480252 -0.153549 +v 0.930176 0.348742 -0.160682 +v 0.882892 0.594349 -0.148489 +v 0.855304 0.597363 -0.147897 +v 0.827693 0.600395 -0.147304 +v 1.138458 -0.381694 -0.198052 +v 1.189065 -0.346717 -0.197254 +v 0.915176 -0.930424 -0.219908 +v 0.880985 -0.743819 -0.210672 +v 0.937762 -1.071078 -0.226817 +v 0.955660 -1.279529 -0.236802 +v 0.952724 -1.188599 -0.232526 +v 0.958652 -1.370426 -0.241076 +v 0.835633 -0.549667 -0.200903 +v 0.775310 -0.341462 -0.190235 +v 0.700023 -0.110143 -0.178248 +v 0.625466 0.828699 -0.133378 +v 0.618078 0.715195 -0.138534 +v 0.634901 0.916151 -0.129467 +v 0.695917 0.317420 -0.158302 +v 0.645988 0.471162 -0.150337 +v 0.622004 0.599020 -0.144000 +v 0.623345 1.017273 -0.124576 +v 0.634271 0.981833 -0.126403 +v 0.612822 1.052688 -0.122757 +v -1.180751 -0.141792 -0.181080 +v -1.244518 -0.298312 -0.187313 +v -1.281836 -0.264559 -0.185133 +v -1.218686 -0.114251 -0.179178 +v -1.290017 -0.445365 -0.193405 +v -1.327110 -0.403866 -0.190868 +v -1.364324 -0.363192 -0.188368 +v -1.319151 -0.230864 -0.182955 +v -1.256591 -0.086648 -0.177275 +v -0.595732 1.147782 -0.130703 +v -0.595760 1.183220 -0.129056 +v -0.548515 1.209171 -0.128623 +v -0.549949 1.169367 -0.130450 +v -0.596582 1.193483 -0.128565 +v -0.548949 1.220630 -0.128083 +v -0.500055 1.233289 -0.128295 +v -0.500157 1.221119 -0.128859 +v -0.503786 1.179243 -0.130746 +v -0.605947 0.460841 -0.162474 +v -0.583581 0.594621 -0.156620 +v -0.535379 0.601981 -0.157067 +v -0.549039 0.467532 -0.163095 +v -0.576398 0.717388 -0.151030 +v -0.535432 0.722936 -0.151443 +v -0.494133 0.730395 -0.151772 +v -0.486168 0.609544 -0.157521 +v -0.489095 0.475949 -0.163685 +v 0.008263 -0.449561 -0.214858 +v 0.008933 -0.688831 -0.225993 +v -0.141095 -0.679220 -0.223089 +v -0.130092 -0.444143 -0.212340 +v 0.007231 -0.901713 -0.235862 +v -0.152942 -0.890538 -0.232720 +v -0.298349 -0.868347 -0.229308 +v -0.278108 -0.659779 -0.219942 +v -0.257392 -0.431594 -0.209672 +v -0.324260 0.507254 -0.164928 +v -0.356221 0.637609 -0.158345 +v -0.326014 0.648478 -0.158334 +v -0.282752 0.521440 -0.164948 +v -0.409782 0.749668 -0.152257 +v -0.376748 0.755841 -0.152511 +v -0.353768 0.760883 -0.152653 +v -0.294265 0.660388 -0.158300 +v -0.212432 0.542234 -0.165133 +v -0.321332 0.251667 -0.176859 +v -0.321035 0.354572 -0.172080 +v -0.274521 0.362331 -0.172481 +v -0.282895 0.230860 -0.178456 +v -0.201176 0.369711 -0.173338 +v -0.206640 0.231923 -0.179655 +v -0.106812 0.365690 -0.175070 +v -0.109059 0.237252 -0.181005 +v -0.105169 0.496848 -0.168999 +v -0.004539 0.485188 -0.171189 +v -0.002976 0.362335 -0.176927 +v -0.001412 0.239452 -0.182665 +v -0.833326 0.465265 -0.158545 +v -0.792725 0.590857 -0.153371 +v -0.747531 0.587507 -0.154267 +v -0.785457 0.459627 -0.159591 +v -0.772194 0.714118 -0.147976 +v -0.728960 0.711219 -0.148819 +v -0.674889 0.710063 -0.149758 +v -0.690536 0.585967 -0.155272 +v -0.724429 0.455524 -0.160781 +v -0.962507 0.179757 -0.169704 +v -0.890195 0.331361 -0.163840 +v -0.840105 0.321193 -0.165133 +v -0.910208 0.163903 -0.171297 +v -0.775158 0.311604 -0.166642 +v -0.841829 0.146829 -0.173211 +v -0.699614 0.126951 -0.176464 +v -0.643627 0.307375 -0.168992 +v -0.578061 0.309215 -0.169980 +v -0.625990 0.119990 -0.177993 +v -0.509378 0.313146 -0.170922 +v -0.549444 0.114969 -0.179479 +v -0.827901 1.108032 -0.128750 +v -0.831021 1.134099 -0.127487 +v -0.764964 1.130573 -0.128733 +v -0.762757 1.104659 -0.129974 +v -0.832149 1.142256 -0.127090 +v -0.765719 1.138675 -0.128344 +v -0.701975 1.144046 -0.129138 +v -0.701131 1.135653 -0.129542 +v -0.699468 1.108398 -0.130836 +v -0.770871 0.831159 -0.142556 +v -0.729484 0.829880 -0.143294 +v -0.769806 0.902593 -0.139253 +v -0.737435 0.917364 -0.139096 +v -0.684992 0.918409 -0.139906 +v -0.676587 0.828746 -0.144212 +v -0.582849 0.832166 -0.145588 +v -0.547058 0.834412 -0.146070 +v -0.592841 0.917975 -0.141435 +v -0.558748 0.915410 -0.142113 +v -0.537108 0.901092 -0.143133 +v -0.521395 0.837251 -0.146358 +v -0.406594 1.151443 -0.133630 +v -0.396611 1.187219 -0.132103 +v -0.349595 1.162222 -0.134020 +v -0.362119 1.132092 -0.135258 +v -0.394055 1.198947 -0.131366 +v -0.346296 1.170471 -0.133380 +v -0.311727 1.150017 -0.134887 +v -0.314765 1.143191 -0.135472 +v -0.328858 1.117640 -0.136475 +v -0.436074 0.861037 -0.146649 +v -0.406548 0.864948 -0.146951 +v -0.442511 0.969604 -0.141496 +v -0.409674 0.971785 -0.141932 +v -0.384251 0.974858 -0.142206 +v -0.384335 0.869524 -0.147102 +v -0.472338 -0.392926 -0.204355 +v -0.507371 -0.605590 -0.213669 +v -0.612294 -0.574960 -0.210527 +v -0.570840 -0.369885 -0.201671 +v -0.537671 -0.806815 -0.222528 +v -0.646864 -0.772576 -0.219149 +v -0.752702 -0.735177 -0.215677 +v -0.714101 -0.541974 -0.207326 +v -0.666825 -0.344416 -0.198915 +v -0.384109 0.123268 -0.181801 +v -0.429479 -0.141509 -0.193368 +v -0.519298 -0.129457 -0.191337 +v -0.469815 0.114075 -0.180825 +v -0.607130 -0.115809 -0.189264 +v -0.773261 -0.080423 -0.184899 +v -0.848285 -0.061729 -0.182801 +v -0.771111 0.135017 -0.174918 +v -0.846490 -0.287024 -0.193305 +v -0.924280 -0.258274 -0.190695 +v -0.998496 -0.228118 -0.188078 +v -0.920994 -0.040375 -0.180618 +v 0.001224 0.060277 -0.191039 +v 0.004892 -0.170428 -0.201825 +v -0.120347 -0.169665 -0.199739 +v -0.113492 0.057487 -0.189290 +v -0.236042 -0.166328 -0.197689 +v -0.219329 0.053050 -0.187763 +v -1.012477 0.197182 -0.168076 +v -1.098734 0.029331 -0.174467 +v -1.138048 0.049729 -0.172875 +v -1.051198 0.210968 -0.166801 +v -1.177316 0.070216 -0.171280 +v -1.089863 0.224870 -0.165521 +v -0.902577 -0.469505 -0.200871 +v -0.984165 -0.433766 -0.197874 +v -0.947633 -0.649751 -0.208513 +v -1.032105 -0.607362 -0.205160 +v -1.110609 -0.564639 -0.201888 +v -1.061180 -0.397448 -0.194924 +v -0.606749 -1.327612 -0.245610 +v -0.617755 -1.425268 -0.249970 +v -0.732872 -1.389429 -0.246419 +v -0.722183 -1.292972 -0.242110 +v -0.628767 -1.522921 -0.254330 +v -0.743591 -1.485871 -0.250728 +v -0.854628 -1.438541 -0.246709 +v -0.844836 -1.343679 -0.242459 +v -0.835088 -1.248793 -0.238207 +v -1.043957 -1.127165 -0.229132 +v -1.049502 -1.223020 -0.233498 +v -1.128386 -1.160943 -0.229320 +v -1.125329 -1.064441 -0.224884 +v -1.055089 -1.318843 -0.237862 +v -1.131564 -1.257320 -0.233749 +v -1.196903 -1.191295 -0.229610 +v -1.194974 -1.096809 -0.225248 +v -1.193621 -1.001682 -0.220848 +v -1.317097 -0.787802 -0.208882 +v -1.340518 -0.903354 -0.213844 +v -1.383733 -0.813282 -0.208892 +v -1.381357 -0.721572 -0.204724 +v -1.328322 -1.032639 -0.219820 +v -1.382828 -0.899875 -0.212633 +v -1.413867 -0.809112 -0.207744 +v -1.421831 -0.725954 -0.203908 +v -1.423700 -0.605009 -0.198377 +v -0.000406 -1.400555 -0.258930 +v -0.001999 -1.495010 -0.263295 +v -0.187300 -1.491051 -0.260077 +v -0.181804 -1.396858 -0.255788 +v -0.003593 -1.589465 -0.267660 +v -0.192775 -1.585246 -0.264367 +v -0.365063 -1.571772 -0.260919 +v -0.355925 -1.476798 -0.256653 +v -0.346751 -1.381828 -0.252388 +v 1.172988 -0.132288 -0.219178 +v 1.212033 -0.104016 -0.218503 +v 1.276814 -0.280939 -0.227789 +v 1.237842 -0.311522 -0.228573 +v 1.251052 -0.075688 -0.217824 +v 1.315781 -0.250340 -0.227004 +v 1.361359 -0.418787 -0.235582 +v 1.323131 -0.452339 -0.236516 +v 1.284896 -0.485830 -0.237447 +v 0.588842 0.985189 -0.157659 +v 0.545286 0.986885 -0.156867 +v 0.542077 1.032862 -0.154676 +v 0.581340 1.025825 -0.155647 +v 0.503379 0.985706 -0.156235 +v 0.503883 1.035975 -0.153907 +v 0.505022 1.086300 -0.151585 +v 0.539473 1.078796 -0.152498 +v 0.574432 1.066381 -0.153648 +v 0.598447 0.476276 -0.181477 +v 0.551452 0.480404 -0.180515 +v 0.531542 0.611478 -0.174095 +v 0.576258 0.605819 -0.175091 +v 0.496862 0.485068 -0.179404 +v 0.483468 0.616978 -0.173052 +v 0.479548 0.730547 -0.167708 +v 0.523916 0.726391 -0.168628 +v 0.570258 0.721429 -0.169617 +v 0.150347 -0.446568 -0.217045 +v 0.164048 -0.685824 -0.228393 +v 0.283421 -0.437032 -0.218781 +v 0.309721 -0.673230 -0.230192 +v 0.328304 -0.885225 -0.240353 +v 0.172864 -0.898877 -0.238443 +v 0.324878 0.505525 -0.175637 +v 0.280939 0.519197 -0.174282 +v 0.316827 0.642238 -0.169149 +v 0.348004 0.633312 -0.170075 +v 0.207622 0.540057 -0.172112 +v 0.283647 0.653708 -0.168073 +v 0.335956 0.742972 -0.164779 +v 0.357538 0.740895 -0.165229 +v 0.379264 0.739101 -0.165668 +v 0.321979 0.251573 -0.187397 +v 0.282431 0.230705 -0.187720 +v 0.274714 0.361699 -0.181503 +v 0.323034 0.354207 -0.182642 +v 0.205146 0.231724 -0.186407 +v 0.198927 0.368990 -0.179923 +v 0.106655 0.237118 -0.184543 +v 0.102082 0.365263 -0.178511 +v 0.097936 0.496051 -0.172362 +v 0.819582 0.478788 -0.184981 +v 0.764847 0.474395 -0.184289 +v 0.732677 0.598120 -0.178010 +v 0.782805 0.600561 -0.178717 +v 0.700194 0.471525 -0.183363 +v 0.673080 0.597468 -0.177064 +v 0.668589 0.714063 -0.171570 +v 0.723566 0.714908 -0.172431 +v 0.768516 0.717474 -0.173047 +v 0.957264 0.186604 -0.200819 +v 0.904752 0.169328 -0.200763 +v 0.824943 0.332026 -0.191892 +v 0.879785 0.341523 -0.192348 +v 0.836321 0.150366 -0.200524 +v 0.757491 0.323048 -0.191205 +v 0.697334 0.127441 -0.199314 +v 0.628770 0.120131 -0.198531 +v 0.581109 0.318003 -0.188551 +v 0.638326 0.318020 -0.189487 +v 0.556433 0.114998 -0.197585 +v 0.517372 0.319309 -0.187447 +v 0.807339 0.958780 -0.162464 +v 0.745707 0.985061 -0.160233 +v 0.738659 1.024886 -0.158266 +v 0.808352 1.034800 -0.158946 +v 0.685029 0.983991 -0.159289 +v 0.673608 1.017376 -0.157550 +v 0.662055 1.050779 -0.155808 +v 0.730177 1.062384 -0.156384 +v 0.806490 1.082196 -0.156712 +v 0.728597 0.830338 -0.167146 +v 0.770198 0.831563 -0.167771 +v 0.675586 0.829246 -0.166329 +v 0.684857 0.918409 -0.162336 +v 0.737299 0.917363 -0.163243 +v 0.769647 0.902584 -0.164460 +v 0.530712 0.835421 -0.163670 +v 0.577273 0.832787 -0.164555 +v 0.487855 0.836618 -0.162913 +v 0.498920 0.916584 -0.159376 +v 0.541679 0.918279 -0.159997 +v 0.587499 0.918027 -0.160759 +v 0.424925 0.939374 -0.157105 +v 0.395882 0.928516 -0.157134 +v 0.403711 1.012841 -0.153342 +v 0.432890 1.022296 -0.153380 +v 0.375695 0.921468 -0.157131 +v 0.382702 1.005851 -0.153323 +v 0.389130 1.057742 -0.151016 +v 0.407606 1.073180 -0.150600 +v 0.437366 1.081174 -0.150716 +v 0.382540 0.835678 -0.161232 +v 0.401894 0.839162 -0.161387 +v 0.363788 0.831671 -0.161111 +v 0.500915 -0.405981 -0.220898 +v 0.601525 -0.385777 -0.221606 +v 0.654454 -0.606213 -0.232721 +v 0.546502 -0.632284 -0.232166 +v 0.694550 -0.363633 -0.222100 +v 0.752597 -0.577998 -0.233016 +v 0.795282 -0.777217 -0.242978 +v 0.693124 -0.809768 -0.242818 +v 0.579882 -0.839384 -0.242341 +v 0.388121 0.122647 -0.194474 +v 0.476963 0.113647 -0.196347 +v 0.535839 -0.135206 -0.208881 +v 0.444578 -0.146014 -0.207889 +v 0.622031 -0.123164 -0.209732 +v 0.766237 0.136734 -0.200010 +v 0.848754 -0.069418 -0.210946 +v 0.773324 -0.091091 -0.210718 +v 0.923621 -0.042372 -0.210914 +v 1.004886 -0.239278 -0.221399 +v 0.927752 -0.278673 -0.221968 +v 0.849865 -0.312428 -0.222262 +v 0.116594 0.057458 -0.193059 +v 0.132160 -0.170038 -0.203891 +v 0.223364 0.052817 -0.195023 +v 0.250793 -0.167562 -0.205718 +v 1.007467 0.203787 -0.200842 +v 1.046411 0.215724 -0.200925 +v 1.132247 0.063101 -0.209426 +v 1.092590 0.041584 -0.209777 +v 1.085273 0.227818 -0.200999 +v 1.171845 0.084730 -0.209069 +v 0.989894 -0.472447 -0.231995 +v 0.911040 -0.513844 -0.232628 +v 1.068081 -0.426248 -0.231127 +v 1.112485 -0.608031 -0.240305 +v 1.035217 -0.657712 -0.241350 +v 0.957287 -0.703083 -0.242183 +v 0.625281 -1.320104 -0.265434 +v 0.748692 -1.281341 -0.265653 +v 0.754102 -1.374440 -0.270069 +v 0.628791 -1.415027 -0.269905 +v 0.860229 -1.236176 -0.265379 +v 0.866693 -1.328600 -0.269779 +v 0.878620 -1.430593 -0.274675 +v 0.758873 -1.468722 -0.274525 +v 0.632109 -1.510028 -0.274376 +v 1.029056 -1.138043 -0.263581 +v 1.097651 -1.089028 -0.262425 +v 1.094454 -1.181713 -0.266682 +v 1.028685 -1.230324 -0.267865 +v 1.165406 -1.032008 -0.260884 +v 1.159266 -1.125784 -0.265143 +v 1.153307 -1.219426 -0.269399 +v 1.091905 -1.273877 -0.270925 +v 1.029386 -1.321714 -0.272126 +v 1.304570 -0.827166 -0.253639 +v 1.354269 -0.749789 -0.250855 +v 1.343664 -0.884620 -0.256950 +v 1.290792 -0.969667 -0.260038 +v 1.389822 -0.694425 -0.248863 +v 1.380013 -0.820923 -0.254584 +v 1.364311 -0.910770 -0.258504 +v 1.331043 -0.983486 -0.261340 +v 1.277498 -1.072618 -0.264607 +v 0.182733 -1.391896 -0.261526 +v 0.183414 -1.487239 -0.265970 +v 0.351959 -1.374153 -0.263472 +v 0.353671 -1.470276 -0.267969 +v 0.355380 -1.566400 -0.272466 +v 0.184084 -1.582583 -0.270413 +v -0.496253 -1.454450 -0.253317 +v -0.485441 -1.357745 -0.248998 +v -0.507043 -1.551157 -0.257636 +v -0.337570 -0.157496 -0.195616 +v -0.309440 0.059003 -0.186011 +v -0.369840 -0.413928 -0.207010 +v -0.398252 -0.634401 -0.216795 +v -0.424234 -0.839397 -0.225900 +v -0.478268 0.797872 -0.148895 +v -0.494453 0.860374 -0.145724 +v -0.468391 0.861713 -0.146089 +v -0.454471 0.781484 -0.150047 +v -0.517702 0.968938 -0.140296 +v -0.477883 0.970293 -0.140885 +v -0.448534 1.210808 -0.130179 +v -0.455212 1.170610 -0.131943 +v -0.448093 1.222988 -0.129597 +v -0.437702 0.319652 -0.171793 +v -0.425496 0.485566 -0.164279 +v -0.374125 0.493944 -0.164731 +v -0.378438 0.329011 -0.172328 +v -0.434582 0.614379 -0.158141 +v -0.448842 0.699517 -0.153950 +v -0.417785 0.684591 -0.155152 +v -0.393569 0.619162 -0.158591 +v -0.952888 -1.286037 -0.238010 +v -0.944947 -1.191158 -0.233729 +v -0.960873 -1.380891 -0.242289 +v -0.811889 -0.506164 -0.204060 +v -0.759879 -0.316216 -0.196081 +v -0.853882 -0.693290 -0.212073 +v -0.692446 -0.098855 -0.187079 +v -0.626398 0.829660 -0.144992 +v -0.622907 0.712565 -0.150493 +v -0.635161 0.917636 -0.140758 +v -0.708947 0.307431 -0.167920 +v -0.663908 0.456261 -0.161738 +v -0.635008 0.588717 -0.156053 +v -0.645370 1.155355 -0.129539 +v -0.644364 1.124601 -0.130985 +v -0.646303 1.164508 -0.129098 +v -1.253683 -1.030436 -0.221201 +v -1.252084 -0.943656 -0.217193 +v -1.255444 -1.117186 -0.225206 +v -1.290436 -1.054099 -0.221700 +v -1.294858 -0.980040 -0.218184 +v -1.287005 -0.921452 -0.215589 +v -0.992180 -0.015237 -0.178284 +v -1.071783 -0.196066 -0.185388 +v -1.128742 -0.170327 -0.183258 +v -1.047132 0.006113 -0.176392 +v -0.871821 0.720567 -0.146045 +v -0.878418 0.843563 -0.140219 +v -0.847045 0.843975 -0.140713 +v -0.842910 0.719600 -0.146564 +v -0.897443 0.959582 -0.134513 +v -0.861684 0.960041 -0.135077 +v -0.810703 0.962595 -0.135793 +v -0.814307 0.843079 -0.141291 +v -0.813956 0.718277 -0.147099 +v -0.929525 1.115936 -0.126719 +v -0.933920 1.143430 -0.125369 +v -0.890811 1.138700 -0.126294 +v -0.886453 1.111964 -0.127609 +v -0.927542 1.149714 -0.125181 +v -0.891958 1.146823 -0.125898 +v -1.005052 0.362800 -0.160497 +v -0.971012 0.353217 -0.161500 +v -0.934942 0.486496 -0.155894 +v -0.905866 0.479964 -0.156674 +v -0.876756 0.473528 -0.157450 +v -0.936923 0.343758 -0.162498 +v -0.889847 0.603000 -0.151216 +v -0.862162 0.599498 -0.151832 +v -0.834459 0.595992 -0.152449 +v -1.135605 -0.360442 -0.191985 +v -1.184177 -0.521433 -0.198674 +v -1.239571 -0.487256 -0.196178 +v -1.192733 -0.331450 -0.189702 +v -1.150407 -0.740727 -0.209423 +v -1.221019 -0.688211 -0.205825 +v -1.177725 -0.880576 -0.215478 +v -1.245441 -0.822316 -0.211660 +v -1.275245 -0.645469 -0.202950 +v -0.788150 -0.945043 -0.224854 +v -0.893239 -0.896289 -0.220866 +v -0.814909 -1.114285 -0.232284 +v -0.923450 -1.059742 -0.227971 +v -1.022123 -0.999434 -0.223551 +v -0.989753 -0.843845 -0.216848 +v -0.318438 -1.081294 -0.238879 +v -0.449717 -1.053008 -0.235415 +v -0.333892 -1.248324 -0.246392 +v -0.469358 -1.222228 -0.242960 +v -0.588954 -1.190920 -0.239547 +v -0.566704 -1.020342 -0.231980 +v 0.178046 -1.105528 -0.248135 +v 0.004279 -1.110478 -0.245520 +v 0.340353 -1.090151 -0.250078 +v 0.347207 -1.245956 -0.257434 +v 0.180751 -1.263136 -0.255507 +v 0.001637 -1.270809 -0.252931 +v 1.349074 -0.605851 -0.244078 +v 1.312016 -0.648908 -0.245473 +v 1.385101 -0.563313 -0.242690 +v 1.066798 -0.837479 -0.250225 +v 0.992146 -0.884923 -0.251208 +v 1.140639 -0.784571 -0.248974 +v 1.156833 -0.917706 -0.255429 +v 1.086495 -0.973347 -0.256864 +v 1.015220 -1.021818 -0.257951 +v 0.720008 -1.007509 -0.252452 +v 0.602474 -1.040684 -0.252070 +v 0.826121 -0.969881 -0.252440 +v 0.845758 -1.115759 -0.259544 +v 0.736457 -1.157790 -0.259708 +v 0.615857 -1.193899 -0.259412 +v -0.164958 -1.101655 -0.242339 +v -0.174211 -1.265439 -0.249802 +v -1.321431 -0.580237 -0.199161 +v -1.356679 -0.532100 -0.196346 +v -1.342740 -0.651760 -0.202137 +v -1.372671 -0.622963 -0.200309 +v -1.398054 -0.566253 -0.197256 +v -1.391818 -0.483438 -0.193508 +v -1.074214 -0.792573 -0.213081 +v -1.105303 -0.940295 -0.219440 +v -0.678944 -0.985457 -0.228521 +v -0.703200 -1.156616 -0.236081 +v 0.461340 -0.864868 -0.241585 +v 0.479094 -1.068289 -0.251333 +v 0.489382 -1.222995 -0.258694 +v 0.496405 -1.350586 -0.264741 +v 0.498812 -1.446670 -0.269248 +v 0.501206 -1.542760 -0.273754 +v 0.313551 0.058346 -0.196242 +v 0.352754 -0.160331 -0.207051 +v 0.397736 -0.423243 -0.220011 +v 0.434583 -0.654917 -0.231385 +v 0.439830 0.733361 -0.166927 +v 0.452406 0.835176 -0.162399 +v 0.410241 0.735378 -0.166349 +v 0.427822 0.832860 -0.162104 +v 0.440655 0.892417 -0.159545 +v 0.462931 0.909384 -0.159122 +v 0.464267 0.976608 -0.156018 +v 0.467155 1.032186 -0.153481 +v 0.470669 1.086088 -0.151033 +v 0.445150 0.322893 -0.186098 +v 0.382939 0.329965 -0.184750 +v 0.377950 0.495214 -0.176986 +v 0.432511 0.490436 -0.178101 +v 0.431931 0.622051 -0.171973 +v 0.389842 0.625994 -0.171100 +v 1.183054 -0.558581 -0.239162 +v 1.210781 -0.727098 -0.247451 +v 1.235036 -0.521222 -0.238276 +v 1.262395 -0.681581 -0.246180 +v 1.265632 -0.785942 -0.251085 +v 1.225177 -0.849769 -0.253390 +v 1.236465 -0.954853 -0.258460 +v 1.226571 -1.054973 -0.262953 +v 1.216239 -1.152605 -0.267323 +v 0.992338 -0.010844 -0.210573 +v 1.043058 0.015471 -0.210181 +v 1.124033 -0.164522 -0.219875 +v 1.073940 -0.197513 -0.220588 +v 0.864758 0.718363 -0.174582 +v 0.837570 0.719518 -0.174083 +v 0.843938 0.843867 -0.168406 +v 0.873924 0.843562 -0.168911 +v 0.810341 0.720318 -0.173600 +v 0.812719 0.843013 -0.167934 +v 0.858809 0.958015 -0.163342 +v 0.895477 0.959744 -0.163862 +v 0.869559 1.044449 -0.159500 +v 0.912216 1.051060 -0.159891 +v 0.874780 1.098480 -0.157073 +v 0.912642 1.097944 -0.157718 +v 0.964870 0.353019 -0.193207 +v 1.000013 0.355975 -0.193645 +v 0.929651 0.350233 -0.192760 +v 0.867470 0.481743 -0.185627 +v 0.898043 0.478917 -0.186259 +v 0.928567 0.476229 -0.186884 +v 0.854778 0.598854 -0.179975 +v 0.882367 0.595840 -0.180567 +v 0.827168 0.601887 -0.179382 +v 1.137933 -0.380203 -0.230130 +v 1.188540 -0.345225 -0.229332 +v 0.880460 -0.742328 -0.242750 +v 0.914651 -0.928933 -0.251986 +v 0.937237 -1.069587 -0.258895 +v 0.952297 -1.187382 -0.264618 +v 0.955782 -1.279031 -0.268936 +v 0.961711 -1.369950 -0.273254 +v 0.774785 -0.339971 -0.222313 +v 0.835108 -0.548176 -0.232981 +v 0.699498 -0.108651 -0.210326 +v 0.617553 0.716686 -0.170612 +v 0.624941 0.830190 -0.165456 +v 0.634375 0.917643 -0.161545 +v 0.695391 0.318912 -0.190380 +v 0.645462 0.472653 -0.182415 +v 0.621478 0.600511 -0.176078 +v 0.633746 0.983325 -0.158481 +v 0.622820 1.018764 -0.156654 +v 0.612297 1.054179 -0.154835 +v 1.157294 -1.272062 -0.240119 +v 1.158585 -1.273343 -0.241216 +v 1.218872 -1.208215 -0.239175 +v 1.217464 -1.207062 -0.238082 +v 1.158585 -1.273343 -0.241216 +v 1.158726 -1.273406 -0.243974 +v 1.219030 -1.208260 -0.241933 +v 1.218872 -1.208215 -0.239175 +v 1.218872 -1.208215 -0.239175 +v 1.219030 -1.208260 -0.241933 +v 1.279374 -1.128126 -0.239196 +v 1.279197 -1.128106 -0.236439 +v 1.279197 -1.128106 -0.236439 +v 1.277664 -1.127124 -0.235352 +v -0.370033 -1.628132 -0.231666 +v -0.370280 -1.629935 -0.232762 +v -0.195542 -1.643076 -0.236234 +v -0.195419 -1.641262 -0.235135 +v -0.370280 -1.629935 -0.232762 +v -0.370358 -1.630072 -0.235520 +v -0.195602 -1.643213 -0.238993 +v -0.195542 -1.643076 -0.236234 +v -0.003871 -1.647579 -0.242335 +v -0.003828 -1.647440 -0.239576 +v -0.003828 -1.647440 -0.239576 +v -0.003823 -1.645623 -0.238475 +v 1.111601 0.236326 -0.169242 +v 1.113181 0.237353 -0.170237 +v 1.026219 0.360742 -0.163076 +v 1.024608 0.359755 -0.162080 +v 1.113181 0.237353 -0.170237 +v 1.113364 0.237621 -0.172981 +v 1.026407 0.361004 -0.165820 +v 1.026219 0.360742 -0.163076 +v 0.953073 0.477515 -0.159203 +v 0.952874 0.477278 -0.156457 +v 0.952874 0.477278 -0.156457 +v 0.951181 0.476469 -0.155451 +v -0.599582 1.201944 -0.096330 +v -0.600359 1.203716 -0.097251 +v -0.649770 1.174623 -0.097795 +v -0.649051 1.172823 -0.096874 +v -0.600359 1.203716 -0.097251 +v -0.600513 1.204090 -0.099985 +v -0.649915 1.175001 -0.100528 +v -0.649770 1.174623 -0.097795 +v -0.704219 1.154855 -0.100576 +v -0.704110 1.154464 -0.097842 +v -0.704110 1.154464 -0.097842 +v -0.703636 1.152573 -0.096922 +v -1.115166 0.234076 -0.132887 +v -1.116807 0.235053 -0.133831 +v -1.204663 0.083452 -0.139440 +v -1.203002 0.082523 -0.138494 +v -1.116807 0.235053 -0.133831 +v -1.117083 0.235313 -0.136567 +v -1.204943 0.083707 -0.142177 +v -1.204663 0.083452 -0.139440 +v -1.283795 -0.070134 -0.148039 +v -1.283508 -0.070373 -0.145301 +v -1.283508 -0.070373 -0.145301 +v -1.281797 -0.071199 -0.144351 +v -0.190958 0.606381 -0.130710 +v -0.189983 0.607989 -0.131667 +v -0.272090 0.675203 -0.127198 +v -0.273473 0.673956 -0.126217 +v -0.189983 0.607989 -0.131667 +v -0.189886 0.608340 -0.134406 +v -0.271935 0.675502 -0.129940 +v -0.272090 0.675203 -0.127198 +v -0.272090 0.675203 -0.127198 +v -0.271935 0.675502 -0.129940 +v -0.333761 0.765909 -0.124724 +v -0.333957 0.765675 -0.121979 +v -0.333957 0.765675 -0.121979 +v -0.335629 0.764880 -0.120972 +v -1.061880 -1.374161 -0.208530 +v -1.063025 -1.375597 -0.209594 +v -0.969264 -1.437671 -0.214015 +v -0.968267 -1.436131 -0.212944 +v -1.063025 -1.375597 -0.209594 +v -1.063231 -1.375682 -0.212348 +v -0.969448 -1.437770 -0.216770 +v -0.969264 -1.437671 -0.214015 +v -0.863312 -1.495863 -0.221209 +v -0.863150 -1.495752 -0.218453 +v -0.863150 -1.495752 -0.218453 +v -0.862308 -1.494128 -0.217375 +v -0.833568 1.150970 -0.094869 +v -0.833971 1.152917 -0.095788 +v -0.899162 1.157667 -0.094500 +v -0.897998 1.155665 -0.093596 +v -0.833971 1.152917 -0.095788 +v -0.834070 1.153317 -0.098521 +v -0.899370 1.158075 -0.097231 +v -0.899162 1.157667 -0.094500 +v -0.947308 1.160224 -0.096346 +v -0.946980 1.159811 -0.093617 +v -0.946980 1.159811 -0.093617 +v -0.944983 1.157764 -0.092729 +v -0.600904 1.205198 -0.123817 +v -0.600840 1.205079 -0.126577 +v -0.650250 1.175986 -0.127120 +v -0.650305 1.176109 -0.124360 +v -0.600840 1.205079 -0.126577 +v -0.600095 1.203401 -0.127683 +v -0.649564 1.174281 -0.128227 +v -0.650250 1.175986 -0.127120 +v -0.704149 1.154030 -0.128275 +v -0.704590 1.155827 -0.127168 +v -0.704590 1.155827 -0.127168 +v -0.704609 1.155963 -0.124408 +v 0.438186 1.114899 -0.117369 +v 0.437747 1.116771 -0.118291 +v 0.403777 1.108203 -0.118133 +v 0.404832 1.106444 -0.117216 +v 0.437747 1.116771 -0.118291 +v 0.437641 1.117160 -0.121025 +v 0.403584 1.108575 -0.120866 +v 0.403777 1.108203 -0.118133 +v 0.403777 1.108203 -0.118133 +v 0.403584 1.108575 -0.120866 +v 0.377454 1.077333 -0.121891 +v 0.377726 1.077000 -0.119157 +v 0.377726 1.077000 -0.119157 +v 0.379328 1.075520 -0.118236 +v -0.635805 -1.580392 -0.225095 +v -0.636333 -1.582137 -0.226183 +v -0.513764 -1.610078 -0.229489 +v -0.513381 -1.608297 -0.228396 +v -0.636333 -1.582137 -0.226183 +v -0.636452 -1.582266 -0.228941 +v -0.513861 -1.610211 -0.232247 +v -0.513764 -1.610078 -0.229489 +v -0.501636 1.243982 -0.095979 +v -0.501757 1.245993 -0.096900 +v -0.551618 1.231921 -0.096738 +v -0.551077 1.230021 -0.095819 +v -0.501757 1.245993 -0.096900 +v -0.501817 1.246401 -0.099633 +v -0.551737 1.232314 -0.099471 +v -0.551618 1.231921 -0.096738 +v 0.657387 1.073645 -0.122876 +v 0.657521 1.075602 -0.123804 +v 0.609888 1.079651 -0.122835 +v 0.609441 1.077765 -0.121900 +v 0.657521 1.075602 -0.123804 +v 0.657497 1.076002 -0.126538 +v 0.609909 1.080041 -0.125571 +v 0.609888 1.079651 -0.122835 +v 0.574697 1.094466 -0.124324 +v 0.574653 1.094085 -0.121588 +v 0.574653 1.094085 -0.121588 +v 0.574045 1.092266 -0.120646 +v 0.359326 0.919010 -0.125185 +v 0.357472 0.919625 -0.126143 +v 0.346149 0.831229 -0.130067 +v 0.347941 0.830594 -0.129110 +v 0.357472 0.919625 -0.126143 +v 0.357165 0.919834 -0.128881 +v 0.345851 0.831442 -0.132805 +v 0.346149 0.831229 -0.130067 +v 0.317272 0.747301 -0.136249 +v 0.317550 0.747047 -0.133512 +v 0.317550 0.747047 -0.133512 +v 0.319192 0.746112 -0.132567 +v -0.921566 0.958349 -0.102383 +v -0.923517 0.958474 -0.103362 +v -0.902796 0.841488 -0.109140 +v -0.900901 0.841526 -0.108153 +v -0.923517 0.958474 -0.103362 +v -0.923839 0.958613 -0.106103 +v -0.903109 0.841604 -0.111883 +v -0.902796 0.841488 -0.109140 +v -0.895409 0.720399 -0.117644 +v -0.895098 0.720253 -0.114903 +v -0.895098 0.720253 -0.114903 +v -0.893216 0.720074 -0.113926 +v 1.037323 -1.372099 -0.242806 +v 1.038407 -1.373555 -0.243907 +v 1.100381 -1.325834 -0.242703 +v 1.099194 -1.324457 -0.241604 +v 1.038407 -1.373555 -0.243907 +v 1.038519 -1.373642 -0.246667 +v 1.100508 -1.325911 -0.245463 +v 1.100381 -1.325834 -0.242703 +v -0.766616 1.149218 -0.097063 +v -0.766371 1.147290 -0.096140 +v -0.766694 1.149614 -0.099796 +v -0.766616 1.149218 -0.097063 +v 0.364545 1.008461 -0.122128 +v 0.366382 1.007465 -0.121188 +v 0.364240 1.008723 -0.124864 +v 0.364545 1.008461 -0.122128 +v 0.261719 0.668596 -0.136245 +v 0.263091 0.667292 -0.135313 +v 0.261480 0.668903 -0.138981 +v 0.261719 0.668596 -0.136245 +v 0.261719 0.668596 -0.136245 +v 0.261480 0.668903 -0.138981 +v 0.183470 0.605711 -0.140641 +v 0.183655 0.605358 -0.137908 +v 0.183655 0.605358 -0.137908 +v 0.184647 0.603733 -0.136983 +v 0.635093 -1.566668 -0.245266 +v 0.635621 -1.568402 -0.246371 +v 0.761053 -1.525122 -0.246413 +v 0.760365 -1.523444 -0.245307 +v 0.635621 -1.568402 -0.246371 +v 0.635654 -1.568529 -0.249131 +v 0.761108 -1.525241 -0.249173 +v 0.761053 -1.525122 -0.246413 +v 0.873829 -1.475451 -0.248703 +v 0.873751 -1.475343 -0.245944 +v 0.873751 -1.475343 -0.245944 +v 0.872910 -1.473734 -0.244839 +v -0.958426 1.122687 -0.094139 +v -0.960736 1.124294 -0.095043 +v -0.944904 1.056857 -0.098438 +v -0.942781 1.056029 -0.097495 +v -0.960736 1.124294 -0.095043 +v -0.961109 1.124644 -0.097774 +v -0.945250 1.057096 -0.101174 +v -0.944904 1.056857 -0.098438 +v 1.112973 0.238729 -0.196813 +v 1.112700 0.238717 -0.199562 +v 1.025739 0.362106 -0.192402 +v 1.026016 0.362112 -0.189652 +v 1.112700 0.238717 -0.199562 +v 1.111088 0.237784 -0.200595 +v 1.024095 0.361212 -0.193433 +v 1.025739 0.362106 -0.192402 +v 0.950668 0.477927 -0.186804 +v 0.952394 0.478642 -0.185783 +v 0.952394 0.478642 -0.185783 +v 0.952683 0.478623 -0.183035 +v -0.370748 -1.628963 -0.259352 +v -0.370760 -1.628572 -0.262088 +v -0.196022 -1.641713 -0.265560 +v -0.195992 -1.642106 -0.262825 +v -0.370760 -1.628572 -0.262088 +v -0.370546 -1.626674 -0.263019 +v -0.195932 -1.639804 -0.266488 +v -0.196022 -1.641713 -0.265560 +v -0.004337 -1.644166 -0.269828 +v -0.004308 -1.646077 -0.268902 +v -0.004308 -1.646077 -0.268902 +v -0.004261 -1.646471 -0.266167 +v -1.434430 -0.578689 -0.165447 +v -1.436306 -0.578522 -0.166424 +v -1.438542 -0.689918 -0.171567 +v -1.436666 -0.689852 -0.170578 +v -1.436306 -0.578522 -0.166424 +v -1.436615 -0.578377 -0.169166 +v -1.438853 -0.689807 -0.174310 +v -1.438542 -0.689918 -0.171567 +v -1.422550 -0.807220 -0.180035 +v -1.422244 -0.807295 -0.177291 +v -1.422244 -0.807295 -0.177291 +v -1.420400 -0.806976 -0.176290 +v 0.357791 -1.623318 -0.243359 +v 0.358034 -1.625116 -0.244463 +v 0.504715 -1.601403 -0.245762 +v 0.504336 -1.599630 -0.244657 +v 0.358034 -1.625116 -0.244463 +v 0.358026 -1.625252 -0.247223 +v 0.504727 -1.601536 -0.248522 +v 0.504715 -1.601403 -0.245762 +v -1.389682 -0.342802 -0.155212 +v -1.391496 -0.342256 -0.156173 +v -1.420887 -0.463694 -0.161338 +v -1.419035 -0.464065 -0.160369 +v -1.391496 -0.342256 -0.156173 +v -1.391797 -0.342057 -0.158913 +v -1.421194 -0.463520 -0.164078 +v -1.420887 -0.463694 -0.161338 +v 0.185584 -1.640978 -0.242377 +v 0.185468 -1.639166 -0.241274 +v 0.185558 -1.641116 -0.245136 +v 0.185584 -1.640978 -0.242377 +v -0.834460 1.154425 -0.122353 +v -0.834451 1.154281 -0.125113 +v -0.899642 1.159031 -0.123825 +v -0.899760 1.159183 -0.121063 +v -0.834451 1.154281 -0.125113 +v -0.834081 1.152428 -0.126222 +v -0.898511 1.157123 -0.124949 +v -0.899642 1.159031 -0.123825 +v -0.945496 1.159221 -0.124082 +v -0.947460 1.161174 -0.122943 +v -0.947460 1.161174 -0.122943 +v -0.947698 1.161332 -0.120178 +v 0.886345 0.716716 -0.143220 +v 0.888198 0.716871 -0.144259 +v 0.898647 0.841468 -0.138637 +v 0.896781 0.841522 -0.137588 +v 0.888198 0.716871 -0.144259 +v 0.888420 0.717014 -0.147009 +v 0.898871 0.841582 -0.141389 +v 0.898647 0.841468 -0.138637 +v 0.923410 0.960437 -0.136265 +v 0.923175 0.960283 -0.133515 +v 0.923175 0.960283 -0.133515 +v 0.921227 0.960049 -0.132478 +v 0.185104 -1.639615 -0.271703 +v 0.185168 -1.640008 -0.268968 +v 0.184954 -1.637708 -0.272627 +v 0.185104 -1.639615 -0.271703 +v 0.357278 -1.621860 -0.274712 +v 0.357554 -1.623753 -0.273789 +v 0.357554 -1.623753 -0.273789 +v 0.357635 -1.624144 -0.271055 +v -1.063621 -1.374574 -0.236180 +v -1.063505 -1.374234 -0.238920 +v -0.969744 -1.436307 -0.243341 +v -0.969838 -1.436662 -0.240602 +v -1.063505 -1.374234 -0.238920 +v -1.062393 -1.372703 -0.239883 +v -0.968781 -1.434674 -0.244297 +v -0.969744 -1.436307 -0.243341 +v -0.862821 -1.492671 -0.248729 +v -0.863630 -1.494389 -0.247779 +v -0.863630 -1.494389 -0.247779 +v -0.863702 -1.494755 -0.245041 +v -1.117473 0.236421 -0.160399 +v -1.117287 0.236416 -0.163156 +v -1.205143 0.084816 -0.168766 +v -1.205333 0.084815 -0.166009 +v -1.117287 0.236416 -0.163156 +v -1.115679 0.235533 -0.164240 +v -1.203516 0.083981 -0.169847 +v -1.205143 0.084816 -0.168766 +v -1.282310 -0.069742 -0.175704 +v -1.283988 -0.069010 -0.174627 +v -1.283988 -0.069010 -0.174627 +v -1.284185 -0.069026 -0.171870 +v 1.277918 -0.060010 -0.185743 +v 1.279612 -0.059217 -0.186750 +v 1.200318 0.098634 -0.178113 +v 1.198699 0.097686 -0.177114 +v 1.279612 -0.059217 -0.186750 +v 1.279811 -0.058982 -0.189496 +v 1.200507 0.098890 -0.180857 +v 1.200318 0.098634 -0.178113 +v -1.383338 -0.936211 -0.183921 +v -1.381567 -0.935636 -0.182907 +v -1.383634 -0.936172 -0.186668 +v -1.383338 -0.936211 -0.183921 +v -1.329312 -1.060578 -0.193341 +v -1.329032 -1.060583 -0.190593 +v -1.329032 -1.060583 -0.190593 +v -1.327364 -1.059769 -0.189566 +v -0.955848 0.491203 -0.123541 +v -0.957587 0.491977 -0.124493 +v -1.029830 0.370607 -0.128952 +v -1.028161 0.369673 -0.128007 +v -0.957587 0.491977 -0.124493 +v -0.957878 0.492208 -0.127230 +v -1.030112 0.370861 -0.131689 +v -1.029830 0.370607 -0.128952 +v 1.334946 -1.032347 -0.232899 +v 1.333287 -1.031582 -0.231820 +v 1.335140 -1.032336 -0.235655 +v 1.334946 -1.032347 -0.232899 +v 1.379316 -0.921405 -0.231221 +v 1.379108 -0.921452 -0.228467 +v 1.379108 -0.921452 -0.228467 +v 1.377347 -0.920935 -0.227397 +v 0.806262 1.110492 -0.123601 +v 0.806337 1.112518 -0.124524 +v 0.725774 1.088873 -0.124304 +v 0.725907 1.086921 -0.123381 +v 0.806337 1.112518 -0.124524 +v 0.806305 1.112929 -0.127258 +v 0.725713 1.089273 -0.127038 +v 0.725774 1.088873 -0.124304 +v -0.306096 1.105396 -0.105624 +v -0.303899 1.106164 -0.106641 +v -0.291569 1.130679 -0.105703 +v -0.293796 1.129715 -0.104695 +v -0.303899 1.106164 -0.106641 +v -0.303628 1.106394 -0.109388 +v -0.291293 1.130939 -0.108449 +v -0.291569 1.130679 -0.105703 +v -0.304569 1.148040 -0.107436 +v -0.304816 1.147760 -0.104692 +v -0.304816 1.147760 -0.104692 +v -0.306844 1.146646 -0.103694 +v 1.405863 -0.797785 -0.223155 +v 1.404042 -0.797524 -0.222097 +v 1.406080 -0.797702 -0.225908 +v 1.405863 -0.797785 -0.223155 +v 1.416755 -0.669826 -0.220138 +v 1.416535 -0.669943 -0.217386 +v 1.416535 -0.669943 -0.217386 +v 1.414691 -0.669926 -0.216339 +v -1.422940 -0.806112 -0.203867 +v -1.421430 -0.806562 -0.206643 +v -1.383720 -0.931223 -0.213077 +v -1.384024 -0.935065 -0.210500 +v -1.421430 -0.806562 -0.206643 +v -1.383720 -0.931223 -0.213077 +v -1.329617 -1.056626 -0.219807 +v -1.329617 -1.056626 -0.219807 +v -1.329702 -1.059470 -0.217173 +v 0.943538 1.060778 -0.129176 +v 0.941418 1.059579 -0.128181 +v 0.943799 1.061070 -0.131920 +v 0.943538 1.060778 -0.129176 +v 0.936338 1.123170 -0.128911 +v 0.936107 1.122749 -0.126173 +v 0.936107 1.122749 -0.126173 +v 0.934191 1.120645 -0.125223 +v 0.437251 1.118268 -0.144857 +v 0.437266 1.118135 -0.147617 +v 0.403297 1.109566 -0.147459 +v 0.403193 1.109683 -0.144698 +v 0.437266 1.118135 -0.147617 +v 0.437673 1.116357 -0.148722 +v 0.404319 1.107902 -0.148569 +v 0.403297 1.109566 -0.147459 +v 0.378814 1.076977 -0.149589 +v 0.377245 1.078364 -0.148483 +v 0.403193 1.109683 -0.144698 +v 0.403297 1.109566 -0.147459 +v 0.377245 1.078364 -0.148483 +v 0.377064 1.078441 -0.145723 +v 0.923020 0.961545 -0.160097 +v 0.922694 0.961646 -0.162840 +v 0.943058 1.062142 -0.158502 +v 0.943408 1.062178 -0.155752 +v 0.922694 0.961646 -0.162840 +v 0.920714 0.961507 -0.163831 +v 0.940904 1.061037 -0.159534 +v 0.943058 1.062142 -0.158502 +v 0.933677 1.122103 -0.156576 +v 0.935627 1.124112 -0.155499 +v 0.935627 1.124112 -0.155499 +v 0.935947 1.124278 -0.152743 +v 0.356774 0.920942 -0.152713 +v 0.356992 0.920988 -0.155468 +v 0.345669 0.832593 -0.159392 +v 0.345461 0.832550 -0.156637 +v 0.356992 0.920988 -0.155468 +v 0.358813 0.920468 -0.156538 +v 0.347428 0.832051 -0.160463 +v 0.345669 0.832593 -0.159392 +v 0.318679 0.747569 -0.163920 +v 0.317070 0.748410 -0.162838 +v 0.317070 0.748410 -0.162838 +v 0.316882 0.748409 -0.160081 +v -0.004796 0.552478 -0.136264 +v -0.004811 0.554360 -0.137193 +v -0.099688 0.567783 -0.135015 +v -0.100186 0.565966 -0.134075 +v -0.004811 0.554360 -0.137193 +v -0.004856 0.554749 -0.139927 +v -0.099660 0.568164 -0.137751 +v -0.099688 0.567783 -0.135015 +v 1.378926 -0.920297 -0.255053 +v 1.378628 -0.920088 -0.257792 +v 1.405383 -0.796422 -0.252481 +v 1.405690 -0.796594 -0.249740 +v 1.378628 -0.920088 -0.257792 +v 1.376833 -0.919477 -0.258750 +v 1.403529 -0.796066 -0.253450 +v 1.405383 -0.796422 -0.252481 +v 1.414178 -0.668468 -0.247692 +v 1.416054 -0.668580 -0.246712 +v 1.416054 -0.668580 -0.246712 +v 1.416365 -0.668717 -0.243969 +v 0.905690 0.595168 -0.150203 +v 0.903901 0.594669 -0.149181 +v 0.905903 0.595361 -0.152951 +v 0.905690 0.595168 -0.150203 +v 0.507372 1.117476 -0.118382 +v 0.507658 1.119393 -0.119314 +v 0.472971 1.120698 -0.118685 +v 0.472980 1.118775 -0.117759 +v 0.507658 1.119393 -0.119314 +v 0.507655 1.119788 -0.122049 +v 0.472927 1.121094 -0.121419 +v 0.472971 1.120698 -0.118685 +v 0.888029 0.718122 -0.170841 +v 0.887717 0.718235 -0.173584 +v 0.898167 0.842831 -0.167963 +v 0.898481 0.842690 -0.165221 +v 0.887717 0.718235 -0.173584 +v 0.885832 0.718174 -0.174573 +v 0.896268 0.842980 -0.168941 +v 0.898167 0.842831 -0.167963 +v -0.190277 0.609448 -0.158238 +v -0.190463 0.609353 -0.160993 +v -0.272571 0.676566 -0.156524 +v -0.272325 0.676610 -0.153772 +v -0.190463 0.609353 -0.160993 +v -0.191472 0.607839 -0.162063 +v -0.273986 0.675414 -0.157570 +v -0.272571 0.676566 -0.156524 +v -0.336142 0.766338 -0.152325 +v -0.334437 0.767038 -0.151304 +v -0.272325 0.676610 -0.153772 +v -0.272571 0.676566 -0.156524 +v -0.334437 0.767038 -0.151304 +v -0.334151 0.767017 -0.148556 +v -0.895799 0.721507 -0.141476 +v -0.895578 0.721616 -0.144228 +v -0.912701 0.606927 -0.149280 +v -0.912914 0.606863 -0.146526 +v -0.895578 0.721616 -0.144228 +v -0.893729 0.721531 -0.145279 +v -0.910911 0.606526 -0.150344 +v -0.912701 0.606927 -0.149280 +v -0.956361 0.492661 -0.154894 +v -0.958067 0.493340 -0.153818 +v -0.958067 0.493340 -0.153818 +v -0.958268 0.493316 -0.151062 +v -1.268627 -1.161632 -0.225679 +v -1.268793 -1.162337 -0.222953 +v -1.266665 -1.159425 -0.226633 +v -1.268627 -1.161632 -0.225679 +v -1.203676 -1.243190 -0.231548 +v -1.205101 -1.244409 -0.230565 +v -1.205101 -1.244409 -0.230565 +v -1.205262 -1.244704 -0.227823 +v 0.541423 1.109361 -0.120333 +v 0.540900 1.107509 -0.119395 +v 0.541455 1.109747 -0.123069 +v 0.541423 1.109361 -0.120333 +v -0.343689 1.175658 -0.102758 +v -0.345209 1.174286 -0.101781 +v -0.304816 1.147760 -0.104692 +v -0.304569 1.148040 -0.107436 +v -0.343514 1.175975 -0.105500 +v -0.343689 1.175658 -0.102758 +v -0.396144 1.209232 -0.103092 +v -0.396229 1.208871 -0.100354 +v -0.396229 1.208871 -0.100354 +v -0.397123 1.207192 -0.099401 +v -0.310410 1.153195 -0.132772 +v -0.310885 1.152238 -0.134004 +v -0.343521 1.173346 -0.132524 +v -0.342136 1.175313 -0.131491 +v -0.376868 1.195784 -0.130910 +v -0.373728 1.197662 -0.129667 +v 0.092023 0.566797 -0.138200 +v 0.092549 0.564977 -0.137277 +v 0.091904 0.567178 -0.140934 +v 0.092023 0.566797 -0.138200 +v 0.935947 1.124278 -0.152743 +v 0.935627 1.124112 -0.155499 +v 0.883970 1.134170 -0.154185 +v 0.884160 1.134357 -0.151426 +v 0.882937 1.132015 -0.155285 +v 0.883970 1.134170 -0.154185 +v 0.805748 1.111949 -0.154954 +v 0.805857 1.113882 -0.153850 +v 0.805857 1.113882 -0.153850 +v 0.805915 1.114037 -0.151090 +v -0.364658 0.873148 -0.145876 +v -0.364352 0.873060 -0.143132 +v -0.366504 0.872913 -0.146873 +v -0.364658 0.873148 -0.145876 +v -0.364727 0.975940 -0.142112 +v -0.362855 0.975765 -0.141135 +v -0.362855 0.975765 -0.141135 +v -0.362545 0.975619 -0.138393 +v 1.412259 -0.541629 -0.240747 +v 1.412570 -0.541736 -0.238004 +v 1.410386 -0.541734 -0.241738 +v 1.412259 -0.541629 -0.240747 +v 1.387797 -0.400603 -0.234806 +v 1.389643 -0.400296 -0.233806 +v 1.389643 -0.400296 -0.233806 +v 1.389949 -0.400373 -0.231061 +v -1.346536 -0.210886 -0.180199 +v -1.346741 -0.210922 -0.177443 +v -1.344802 -0.211478 -0.181271 +v -1.346536 -0.210886 -0.180199 +v -1.390179 -0.341255 -0.186561 +v -1.391974 -0.340881 -0.185498 +v -1.391974 -0.340881 -0.185498 +v -1.392187 -0.340950 -0.182745 +v -0.304018 1.107502 -0.133220 +v -0.304316 1.107717 -0.135959 +v -0.289896 1.130759 -0.135123 +v -0.289601 1.130570 -0.132428 +v -0.304316 1.107717 -0.135959 +v -0.306097 1.108373 -0.136915 +v -0.291608 1.131384 -0.136051 +v -0.289896 1.130759 -0.135123 +v -0.289639 1.137031 -0.135671 +v -0.288571 1.137342 -0.134860 +v -0.288571 1.137342 -0.134860 +v -0.288297 1.137336 -0.132447 +v -0.364180 0.871779 -0.116551 +v -0.366004 0.871418 -0.115522 +v -0.363962 0.871953 -0.119300 +v -0.364180 0.871779 -0.116551 +v -0.362154 0.974511 -0.114561 +v -0.362387 0.974364 -0.111811 +v -0.362387 0.974364 -0.111811 +v -0.364315 0.974183 -0.110772 +v 0.884450 1.132807 -0.124860 +v 0.883451 1.130557 -0.123932 +v 0.936107 1.122749 -0.126173 +v 0.936338 1.123170 -0.128911 +v 0.884550 1.133249 -0.127594 +v 0.884450 1.132807 -0.124860 +v 0.261238 0.669960 -0.165571 +v 0.261089 0.670011 -0.162813 +v 0.262578 0.668750 -0.166666 +v 0.261238 0.669960 -0.165571 +v 0.184133 0.605191 -0.168336 +v 0.183174 0.606721 -0.167233 +v 0.261089 0.670011 -0.162813 +v 0.261238 0.669960 -0.165571 +v 0.183174 0.606721 -0.167233 +v 0.183079 0.606819 -0.164474 +v -0.912221 0.605564 -0.119954 +v -0.910398 0.605068 -0.118991 +v -0.912524 0.605756 -0.122694 +v -0.912221 0.605564 -0.119954 +v -1.268140 -1.163421 -0.196371 +v -1.266592 -1.162407 -0.195333 +v -1.268404 -1.163445 -0.199121 +v -1.268140 -1.163421 -0.196371 +v -1.204872 -1.245812 -0.203991 +v -1.204627 -1.245765 -0.201239 +v -1.204627 -1.245765 -0.201239 +v -1.203207 -1.244586 -0.200192 +v 1.388310 -0.402061 -0.203453 +v 1.390123 -0.401659 -0.204480 +v 1.344661 -0.233683 -0.195926 +v 1.342899 -0.234287 -0.194909 +v 1.390123 -0.401659 -0.204480 +v 1.390340 -0.401481 -0.207229 +v 1.344871 -0.233476 -0.198674 +v 1.344661 -0.233683 -0.195926 +v -0.413375 1.221846 -0.126469 +v -0.415186 1.221848 -0.128858 +v -0.452679 1.238840 -0.127433 +v -0.452376 1.238964 -0.124723 +v -0.415186 1.221848 -0.128858 +v -0.422558 1.223883 -0.129456 +v -0.453115 1.237057 -0.128494 +v -0.452679 1.238840 -0.127433 +v -0.501829 1.245284 -0.127345 +v -0.502197 1.247337 -0.126227 +v -0.502197 1.247337 -0.126227 +v -0.502207 1.247509 -0.123466 +v 0.091542 0.568161 -0.167526 +v 0.091514 0.568286 -0.164766 +v 0.092035 0.566435 -0.168630 +v 0.091542 0.568161 -0.167526 +v -0.005310 0.553935 -0.167617 +v -0.005291 0.555723 -0.166518 +v -0.005291 0.555723 -0.166518 +v -0.005246 0.555857 -0.163759 +v 0.574307 1.095574 -0.148156 +v 0.574172 1.095448 -0.150913 +v 0.540943 1.110725 -0.149659 +v 0.541065 1.110855 -0.146901 +v 0.574172 1.095448 -0.150913 +v 0.573531 1.093724 -0.151999 +v 0.540386 1.108967 -0.150748 +v 0.540943 1.110725 -0.149659 +v 0.506859 1.118933 -0.149735 +v 0.507177 1.120757 -0.148639 +v 0.507177 1.120757 -0.148639 +v 0.507265 1.120896 -0.145881 +v 0.905210 0.596532 -0.179529 +v 0.905513 0.596468 -0.176784 +v 0.903388 0.596127 -0.180534 +v 0.905210 0.596532 -0.179529 +v -1.139509 -1.312355 -0.234798 +v -1.139645 -1.312676 -0.232058 +v -1.138251 -1.310949 -0.235770 +v -1.139509 -1.312355 -0.234798 +v -1.139645 -1.312676 -0.232058 +v -1.139509 -1.312355 -0.234798 +v 0.657107 1.077110 -0.150370 +v 0.657041 1.076966 -0.153129 +v 0.609408 1.081014 -0.152161 +v 0.609519 1.081149 -0.149403 +v 0.657041 1.076966 -0.153129 +v 0.656873 1.075103 -0.154229 +v 0.608928 1.079223 -0.153253 +v 0.609408 1.081014 -0.152161 +v -1.346056 -0.212250 -0.150873 +v -1.344292 -0.212947 -0.149918 +v -1.346351 -0.212030 -0.153611 +v -1.346056 -0.212250 -0.150873 +v -1.437006 -0.577269 -0.192998 +v -1.435676 -0.580107 -0.195916 +v -1.437179 -0.692733 -0.201113 +v -1.439243 -0.688699 -0.198142 +v -1.435676 -0.580107 -0.195916 +v -1.437179 -0.692733 -0.201113 +v -1.421174 -0.462826 -0.190692 +v -1.421584 -0.462412 -0.187910 +v -1.418381 -0.464426 -0.191837 +v -1.421174 -0.462826 -0.190692 +v 0.936719 -1.440634 -0.275683 +v 0.920413 -1.444456 -0.275840 +v 0.971281 -1.407464 -0.275096 +v 0.977126 -1.413304 -0.275148 +v 1.033785 -1.362591 -0.274053 +v 1.038397 -1.369783 -0.274145 +v -0.752267 -1.542855 -0.251856 +v -0.752317 -1.543231 -0.249119 +v -0.751616 -1.541068 -0.252799 +v -0.752267 -1.542855 -0.251856 +v -0.636318 -1.578934 -0.256448 +v -0.636813 -1.580774 -0.255509 +v -0.636813 -1.580774 -0.255509 +v -0.636842 -1.581158 -0.252773 +v 1.278984 -1.127018 -0.263028 +v 1.278717 -1.126743 -0.265764 +v 1.334466 -1.030984 -0.262225 +v 1.334750 -1.031228 -0.259487 +v 1.278717 -1.126743 -0.265764 +v 1.277151 -1.125666 -0.266705 +v 1.332773 -1.030125 -0.263173 +v 1.334466 -1.030984 -0.262225 +v 0.504240 -1.600038 -0.275088 +v 0.504337 -1.600428 -0.272354 +v 0.503860 -1.598157 -0.276010 +v 0.504240 -1.600038 -0.275088 +v 0.634881 -1.565092 -0.276618 +v 0.635178 -1.567024 -0.275697 +v 0.635178 -1.567024 -0.275697 +v 0.635263 -1.567421 -0.272963 +v 0.757652 -1.525549 -0.275804 +v 0.760854 -1.524362 -0.273097 +v 0.754933 -1.524699 -0.276689 +v 0.757652 -1.525549 -0.275804 +v 0.827748 -1.496398 -0.276492 +v 0.848989 -1.488869 -0.275822 +v 0.848989 -1.488869 -0.275822 +v 0.879772 -1.473131 -0.273348 +v -0.924229 0.959721 -0.129936 +v -0.923997 0.959837 -0.132687 +v -0.903276 0.842851 -0.138466 +v -0.903499 0.842711 -0.135715 +v -0.923997 0.959837 -0.132687 +v -0.922080 0.959806 -0.133736 +v -0.901414 0.842983 -0.139506 +v -0.903276 0.842851 -0.138466 +v 1.412739 -0.542993 -0.211422 +v 1.410899 -0.543192 -0.210385 +v 1.412960 -0.542844 -0.214172 +v 1.412739 -0.542993 -0.211422 +v 0.965075 -1.423711 -0.245039 +v 0.964102 -1.422177 -0.243935 +v 0.965171 -1.423809 -0.247798 +v 0.965075 -1.423711 -0.245039 +v -0.961499 1.125752 -0.121606 +v -0.961216 1.125657 -0.124369 +v -0.945385 1.058220 -0.127763 +v -0.945640 1.058204 -0.125006 +v -0.961216 1.125657 -0.124369 +v -0.958939 1.124145 -0.125492 +v -0.943294 1.057487 -0.128848 +v -0.945385 1.058220 -0.127763 +v 0.364064 1.009824 -0.151454 +v 0.363849 1.009831 -0.148696 +v 0.365869 1.008923 -0.152541 +v 0.364064 1.009824 -0.151454 +v 0.725294 1.090236 -0.153630 +v 0.725322 1.090381 -0.150870 +v 0.725394 1.088379 -0.154734 +v 0.725294 1.090236 -0.153630 +v -0.449888 1.236022 -0.098213 +v -0.450238 1.234098 -0.097281 +v -0.449881 1.236418 -0.100948 +v -0.449888 1.236022 -0.098213 +v -0.751788 -1.544219 -0.222530 +v -0.751103 -1.542525 -0.221446 +v -0.751927 -1.544339 -0.225287 +v -0.751788 -1.544219 -0.222530 +v 0.472491 1.122062 -0.148011 +v 0.472537 1.122202 -0.145252 +v 0.472466 1.120232 -0.149112 +v 0.472491 1.122062 -0.148011 +v 1.344181 -0.232320 -0.225252 +v 1.344481 -0.232368 -0.222506 +v 1.342386 -0.232829 -0.226262 +v 1.344181 -0.232320 -0.225252 +v 1.277405 -0.058552 -0.217096 +v 1.279132 -0.057853 -0.216076 +v 1.279132 -0.057853 -0.216076 +v 1.279421 -0.057874 -0.213328 +v -0.767097 1.150581 -0.126388 +v -0.767084 1.150722 -0.123628 +v -0.766884 1.148748 -0.127493 +v -0.767097 1.150581 -0.126388 +v -1.139029 -1.313717 -0.205473 +v -1.137744 -1.312398 -0.204416 +v -1.139255 -1.313785 -0.208226 +v -1.139029 -1.313717 -0.205473 +v -1.139029 -1.313717 -0.205473 +v -1.139255 -1.313785 -0.208226 +v -0.100168 0.569147 -0.164341 +v -0.100050 0.569272 -0.161583 +v -0.100699 0.567424 -0.165428 +v -0.100168 0.569147 -0.164341 +v -1.030311 0.371970 -0.158278 +v -1.030502 0.371969 -0.155521 +v -1.028674 0.371131 -0.159360 +v -1.030311 0.371970 -0.158278 +v -0.552093 1.233282 -0.126064 +v -0.552127 1.233422 -0.123303 +v -0.551550 1.231460 -0.127173 +v -0.552093 1.233282 -0.126064 +v 1.199838 0.099997 -0.207438 +v 1.200117 0.099998 -0.204689 +v 1.198186 0.099143 -0.208467 +v 1.199838 0.099997 -0.207438 +v -0.514245 -1.608715 -0.258815 +v -0.514251 -1.609103 -0.256079 +v -0.513895 -1.606839 -0.259749 +v -0.514245 -1.608715 -0.258815 +v 1.038718 -1.372135 -0.270490 +v 1.039524 -1.371136 -0.273210 +v 1.100021 -1.324402 -0.272028 +v 1.100191 -1.324752 -0.269293 +v 1.039524 -1.371136 -0.273210 +v 1.098245 -1.323401 -0.272968 +v 1.100021 -1.324402 -0.272028 +v 1.156513 -1.270818 -0.271478 +v 1.158071 -1.272007 -0.270542 +v 1.158071 -1.272007 -0.270542 +v 1.158336 -1.272297 -0.267807 +v -0.958183 0.493073 -0.145835 +v -0.912828 0.606621 -0.141299 +v -0.958073 0.492763 -0.139146 +v -0.912719 0.606310 -0.134610 +v -0.895604 0.720953 -0.129560 +v -0.895714 0.721264 -0.136249 +v -0.957963 0.492451 -0.132458 +v -0.912609 0.605999 -0.127921 +v -0.895495 0.720642 -0.122871 +v -1.205177 -1.244947 -0.222596 +v -1.268708 -1.162580 -0.217726 +v -1.205067 -1.245258 -0.215907 +v -1.268599 -1.162890 -0.211037 +v -1.329507 -1.060024 -0.205257 +v -1.329617 -1.059713 -0.211946 +v -1.204957 -1.245569 -0.209219 +v -1.268488 -1.163201 -0.204349 +v -1.329398 -1.060335 -0.198569 +v 0.377149 1.078198 -0.140496 +v 0.403279 1.109440 -0.139471 +v 0.377259 1.077887 -0.133807 +v 0.403389 1.109129 -0.132782 +v 0.403279 1.109440 -0.139471 +v 0.403389 1.109129 -0.132782 +v 0.437446 1.117714 -0.132941 +v 0.437336 1.118025 -0.139629 +v 0.377368 1.077576 -0.127118 +v 0.403498 1.108818 -0.126093 +v 0.403498 1.108818 -0.126093 +v 0.437556 1.117403 -0.126252 +v 0.923105 0.961302 -0.154870 +v 0.898566 0.842447 -0.159994 +v 0.923215 0.960991 -0.148181 +v 0.898676 0.842136 -0.153305 +v 0.888225 0.717568 -0.158925 +v 0.888115 0.717879 -0.165614 +v 0.923324 0.960680 -0.141492 +v 0.898785 0.841825 -0.146616 +v 0.888334 0.717257 -0.152237 +v -0.371896 1.197801 -0.128148 +v -0.341699 1.176118 -0.130373 +v -0.371896 1.197801 -0.128148 +v -0.365657 1.193370 -0.126693 +v -0.341604 1.176138 -0.128165 +v -0.341699 1.176118 -0.130373 +v -0.317540 1.158880 -0.129084 +v -0.311463 1.154400 -0.131155 +v -0.342136 1.175313 -0.131491 +v -0.310410 1.153195 -0.132772 +v -0.395684 1.210541 -0.116266 +v -0.396181 1.209565 -0.108412 +v -0.343464 1.176167 -0.110767 +v -0.342783 1.176173 -0.117549 +v -0.304160 1.147990 -0.112781 +v -0.300351 1.145971 -0.120829 +v -0.334065 0.766774 -0.143329 +v -0.272239 0.676367 -0.148545 +v -0.333956 0.766463 -0.136640 +v -0.272130 0.676056 -0.141856 +v -0.272239 0.676367 -0.148545 +v -0.272130 0.676056 -0.141856 +v -0.190081 0.608894 -0.146322 +v -0.190191 0.609205 -0.153011 +v -0.333846 0.766152 -0.129952 +v -0.272020 0.675745 -0.135167 +v -0.272020 0.675745 -0.135167 +v -0.189972 0.608583 -0.139633 +v 0.806000 1.113794 -0.145863 +v 0.884245 1.134114 -0.146199 +v 0.806110 1.113483 -0.139174 +v 0.884355 1.133803 -0.139510 +v 0.936143 1.123724 -0.140827 +v 0.936033 1.124035 -0.147515 +v 0.806219 1.113172 -0.132485 +v 0.884464 1.133492 -0.132822 +v 0.936252 1.123413 -0.134138 +v -0.362459 0.975376 -0.133166 +v -0.364266 0.872818 -0.137904 +v -0.362350 0.975065 -0.126477 +v -0.364157 0.872507 -0.131216 +v -0.362240 0.974754 -0.119788 +v -0.364047 0.872195 -0.124527 +v 1.390035 -0.400616 -0.225834 +v 1.412655 -0.541979 -0.232777 +v 1.390145 -0.400927 -0.219145 +v 1.412765 -0.542290 -0.226088 +v 1.416560 -0.669271 -0.232054 +v 1.416451 -0.668961 -0.238742 +v 1.390254 -0.401237 -0.212456 +v 1.412874 -0.542601 -0.219399 +v 1.416670 -0.669582 -0.225365 +v 0.936033 1.124035 -0.147515 +v 0.943494 1.061935 -0.150525 +v 0.936143 1.123724 -0.140827 +v 0.943604 1.061625 -0.143836 +v 0.936252 1.123413 -0.134138 +v 0.943713 1.061313 -0.137147 +v -1.392102 -0.341192 -0.177517 +v -1.346655 -0.211165 -0.172216 +v -1.391992 -0.341503 -0.170829 +v -1.346546 -0.211476 -0.165527 +v -1.283990 -0.069580 -0.159955 +v -1.284100 -0.069269 -0.166643 +v -1.391882 -0.341815 -0.164140 +v -1.346436 -0.211787 -0.158839 +v -1.283880 -0.069891 -0.153266 +v 1.405776 -0.796837 -0.244513 +v 1.405885 -0.797148 -0.237824 +v 1.379121 -0.920851 -0.243137 +v 1.379012 -0.920540 -0.249826 +v 1.405995 -0.797459 -0.231136 +v 1.379231 -0.921162 -0.236449 +v -0.303933 1.107259 -0.127993 +v -0.334970 1.055604 -0.129886 +v -0.335055 1.055847 -0.135113 +v -0.303823 1.106948 -0.121304 +v -0.334860 1.055293 -0.123197 +v -0.303713 1.106637 -0.114615 +v -0.334751 1.054982 -0.116508 +v -0.334665 1.054739 -0.111281 +v 0.574392 1.095330 -0.142929 +v 0.609604 1.080906 -0.144176 +v 0.574502 1.095020 -0.136240 +v 0.609714 1.080595 -0.137487 +v 0.657302 1.076556 -0.138454 +v 0.657192 1.076867 -0.145143 +v 0.574611 1.094708 -0.129551 +v 0.609823 1.080284 -0.130798 +v 0.657412 1.076245 -0.131765 +v 1.334836 -1.031471 -0.254260 +v 1.334945 -1.031782 -0.247571 +v 1.279179 -1.127572 -0.251112 +v 1.279069 -1.127261 -0.257801 +v 1.335055 -1.032093 -0.240883 +v 1.279288 -1.127882 -0.244423 +v -1.205247 0.084572 -0.160782 +v -1.205138 0.084261 -0.154093 +v -1.117278 0.235867 -0.148483 +v -1.117388 0.236178 -0.155172 +v -1.205028 0.083950 -0.147405 +v -1.117168 0.235556 -0.141795 +v -1.383938 -0.935308 -0.205273 +v -1.383829 -0.935619 -0.198584 +v -1.422745 -0.806666 -0.191952 +v -1.422855 -0.806355 -0.198640 +v -1.383719 -0.935930 -0.191895 +v -1.422636 -0.806977 -0.185263 +v 0.952769 0.478380 -0.177808 +v 1.026102 0.361869 -0.184425 +v 0.952878 0.478069 -0.171119 +v 1.026212 0.361558 -0.177736 +v 1.113168 0.238175 -0.184896 +v 1.113059 0.238486 -0.191585 +v 0.952988 0.477758 -0.164430 +v 1.026321 0.361247 -0.171048 +v 1.113278 0.237864 -0.178208 +v -0.502121 1.247266 -0.118238 +v -0.451914 1.238535 -0.119586 +v -0.502012 1.246955 -0.111549 +v -0.450375 1.237309 -0.112966 +v -0.411376 1.220770 -0.122016 +v -0.501902 1.246644 -0.104861 +v -0.449954 1.236684 -0.106200 +v -0.005161 0.555614 -0.158532 +v 0.091600 0.568043 -0.159539 +v -0.005051 0.555304 -0.151843 +v 0.091709 0.567732 -0.152850 +v 0.183275 0.606265 -0.152557 +v 0.183165 0.606576 -0.159246 +v -0.004942 0.554993 -0.145154 +v 0.091819 0.567421 -0.146161 +v 0.183384 0.605954 -0.145869 +v 0.507351 1.120653 -0.140654 +v 0.541150 1.110612 -0.141674 +v 0.507460 1.120342 -0.133965 +v 0.541260 1.110301 -0.134985 +v 0.507570 1.120031 -0.127276 +v 0.541369 1.109990 -0.128296 +v 0.905598 0.596226 -0.171556 +v 0.905708 0.595915 -0.164867 +v 0.905817 0.595603 -0.158179 +v -1.063535 -1.374817 -0.230953 +v -1.139560 -1.312920 -0.226830 +v -1.063426 -1.375128 -0.224264 +v -1.139450 -1.313230 -0.220142 +v -1.139560 -1.312920 -0.226830 +v -1.139450 -1.313230 -0.220142 +v -1.063316 -1.375439 -0.217576 +v -1.139340 -1.313542 -0.213453 +v -1.139340 -1.313542 -0.213453 +v 0.357721 -1.624387 -0.265827 +v 0.185253 -1.640252 -0.263741 +v 0.357831 -1.624699 -0.259139 +v 0.185363 -1.640563 -0.257052 +v -0.004066 -1.647025 -0.254251 +v -0.004176 -1.646714 -0.260940 +v 0.357940 -1.625009 -0.252450 +v 0.185472 -1.640873 -0.250364 +v -0.003957 -1.647336 -0.247562 +v -1.439157 -0.688942 -0.192914 +v -1.439048 -0.689253 -0.186226 +v -1.436810 -0.577823 -0.181082 +v -1.436921 -0.577512 -0.187771 +v -1.438938 -0.689564 -0.179537 +v -1.436701 -0.578134 -0.174393 +v 0.874195 -1.474476 -0.267390 +v 0.760962 -1.524354 -0.267798 +v 0.873634 -1.474898 -0.260619 +v 0.760913 -1.524687 -0.261089 +v 0.635459 -1.567976 -0.261047 +v 0.635349 -1.567665 -0.267736 +v 0.873743 -1.475209 -0.253931 +v 0.761023 -1.524998 -0.254400 +v 0.635568 -1.568286 -0.254359 +v -1.421499 -0.462656 -0.182683 +v -1.421389 -0.462966 -0.175994 +v -1.421279 -0.463277 -0.169306 +v 1.038288 -1.372727 -0.265270 +v 0.965181 -1.422816 -0.266421 +v 0.967776 -1.421244 -0.271691 +v 1.038324 -1.373088 -0.258583 +v 0.964976 -1.423255 -0.259714 +v 1.038434 -1.373399 -0.251894 +v 0.965085 -1.423566 -0.253026 +v -0.636756 -1.581401 -0.247545 +v -0.752232 -1.543474 -0.243891 +v -0.636647 -1.581712 -0.240857 +v -0.752122 -1.543786 -0.237203 +v -0.863508 -1.495309 -0.233125 +v -0.863617 -1.494998 -0.239814 +v -0.636537 -1.582023 -0.234168 +v -0.752013 -1.544096 -0.230514 +v -0.863398 -1.495620 -0.226437 +v -0.903414 0.842469 -0.130488 +v -0.903304 0.842158 -0.123799 +v -0.924034 0.959167 -0.118019 +v -0.924143 0.959478 -0.124708 +v -0.903194 0.841846 -0.117110 +v -0.923924 0.958856 -0.111331 +v 0.504422 -1.600671 -0.267127 +v 0.504532 -1.600982 -0.260438 +v 0.504641 -1.601293 -0.253749 +v 0.261175 0.669768 -0.157586 +v 0.261285 0.669457 -0.150897 +v 0.261175 0.669768 -0.157586 +v 0.261285 0.669457 -0.150897 +v 0.317077 0.747855 -0.148165 +v 0.316968 0.748166 -0.154854 +v 0.261394 0.669146 -0.144208 +v 0.261394 0.669146 -0.144208 +v 0.317187 0.747544 -0.141477 +v 0.345546 0.832307 -0.151410 +v 0.345656 0.831996 -0.144721 +v 0.356970 0.920388 -0.140797 +v 0.356860 0.920699 -0.147486 +v 0.345765 0.831685 -0.138033 +v 0.357079 0.920077 -0.134109 +v -0.947613 1.161089 -0.114950 +v -0.899675 1.158940 -0.115835 +v -0.947503 1.160779 -0.108262 +v -0.899565 1.158629 -0.109147 +v -0.834265 1.153871 -0.110437 +v -0.834375 1.154181 -0.117126 +v -0.947393 1.160467 -0.101573 +v -0.899456 1.158318 -0.102458 +v -0.834156 1.153559 -0.103748 +v 1.218725 -1.207395 -0.260538 +v 1.218639 -1.207151 -0.265765 +v 1.218835 -1.207705 -0.253849 +v 1.218725 -1.207395 -0.260538 +v 1.218835 -1.207705 -0.253849 +v 1.158531 -1.272851 -0.255891 +v 1.158422 -1.272541 -0.262579 +v 1.218639 -1.207151 -0.265765 +v 1.218944 -1.208016 -0.247161 +v 1.218944 -1.208016 -0.247161 +v 1.158641 -1.273162 -0.249202 +v -0.961414 1.125509 -0.116379 +v -0.965759 1.155319 -0.114922 +v -0.965844 1.155562 -0.120149 +v -0.961304 1.125198 -0.109690 +v -0.965649 1.155008 -0.108233 +v -0.965759 1.155319 -0.114922 +v -0.965649 1.155008 -0.108233 +v -0.965844 1.155562 -0.120149 +v -0.961195 1.124887 -0.103001 +v -0.965539 1.154697 -0.101544 +v -0.965454 1.154454 -0.096317 +v -0.965539 1.154697 -0.101544 +v -0.965454 1.154454 -0.096317 +v 0.363935 1.009588 -0.143469 +v 0.364045 1.009278 -0.136780 +v 0.364154 1.008966 -0.130092 +v 0.725408 1.090138 -0.145643 +v 0.725518 1.089827 -0.138954 +v 0.725627 1.089515 -0.132265 +v -0.704524 1.155720 -0.119180 +v -0.650220 1.175866 -0.119133 +v -0.704414 1.155409 -0.112492 +v -0.650110 1.175555 -0.112444 +v -0.600708 1.204644 -0.111901 +v -0.600818 1.204955 -0.118589 +v -0.704305 1.155098 -0.105803 +v -0.650001 1.175244 -0.105756 +v -0.600599 1.204333 -0.105212 +v -0.195907 -1.642350 -0.257597 +v -0.195797 -1.642660 -0.250909 +v -0.370553 -1.629518 -0.247436 +v -0.370663 -1.629206 -0.254125 +v -0.195688 -1.642972 -0.244220 +v -0.370443 -1.629828 -0.240748 +v 0.472622 1.121959 -0.140024 +v 0.472732 1.121649 -0.133335 +v 0.472842 1.121337 -0.126647 +v 1.279506 -0.058117 -0.208101 +v 1.344566 -0.232611 -0.217278 +v 1.279616 -0.058428 -0.201412 +v 1.344676 -0.232922 -0.210590 +v 1.279726 -0.058739 -0.194723 +v 1.344785 -0.233233 -0.203901 +v -0.766999 1.150479 -0.118401 +v -0.766889 1.150168 -0.111712 +v -0.766779 1.149857 -0.105024 +v -0.969753 -1.436904 -0.235375 +v -0.969643 -1.437215 -0.228686 +v -0.969533 -1.437526 -0.221998 +v -0.099964 0.569029 -0.156356 +v -0.099855 0.568718 -0.149667 +v -0.099745 0.568407 -0.142978 +v -1.030416 0.371726 -0.150294 +v -1.030307 0.371415 -0.143605 +v -1.030197 0.371104 -0.136917 +v -0.552042 1.233179 -0.118076 +v -0.551932 1.232868 -0.111387 +v -0.551823 1.232557 -0.104698 +v 1.200202 0.099755 -0.199462 +v 1.200312 0.099444 -0.192773 +v 1.200421 0.099133 -0.186085 +v -0.514166 -1.609347 -0.250852 +v -0.514056 -1.609657 -0.244163 +v -0.513947 -1.609969 -0.237475 +v 1.100213 -1.325039 -0.264067 +v 1.100313 -1.325356 -0.257379 +v 1.100422 -1.325667 -0.250690 +v 1.218388 -1.206855 -0.268501 +v 1.216917 -1.205631 -0.269436 +v 1.218388 -1.206855 -0.268501 +v 1.218388 -1.206855 -0.268501 +v -0.950212 0.489170 -0.123410 +v -1.022367 0.367096 -0.127904 +v -1.109149 0.231132 -0.132804 +v -0.210896 0.155735 -0.150972 +v -0.110044 0.163096 -0.152281 +v 0.000027 0.167075 -0.153898 +v -0.832661 1.146424 -0.094777 +v -0.895060 1.151009 -0.093542 +v -0.938885 1.153065 -0.092729 +v -0.915164 0.958169 -0.102179 +v -0.894801 0.841727 -0.107926 +v -0.887273 0.719710 -0.113722 +v -0.399218 1.203198 -0.099234 +v -0.451077 1.229510 -0.097162 +v -0.501393 1.239179 -0.095889 +v -0.904660 0.603842 -0.118824 +v -0.340341 0.210517 -0.146305 +v -0.292548 0.158271 -0.149517 +v -0.597836 1.197730 -0.096237 +v -0.647434 1.168579 -0.096780 +v -0.702576 1.148146 -0.096827 +v -0.950812 1.118971 -0.094119 +v -0.935774 1.054173 -0.097378 +v -0.915649 1.051988 -0.097763 +v -0.194806 0.596776 -0.130775 +v -0.278242 0.669555 -0.126026 +v -0.340638 0.762800 -0.120669 +v -0.004696 0.540722 -0.136494 +v -0.101766 0.554303 -0.134274 +v -0.692049 0.994146 -0.104114 +v -0.689373 0.960810 -0.105707 +v -0.639024 0.959698 -0.106583 +v -0.640385 0.995984 -0.104874 +v -0.597380 0.959693 -0.107265 +v -0.597629 0.999979 -0.105388 +v -0.313066 1.104893 -0.105216 +v -0.300879 1.128968 -0.104296 +v -0.312830 1.145146 -0.103348 +v -0.371251 0.870472 -0.115162 +v -0.369996 0.973888 -0.110374 +v -0.526094 1.007538 -0.106208 +v -0.529891 0.961871 -0.108269 +v -0.493726 0.961158 -0.108895 +v -0.486522 1.006102 -0.106923 +v -0.460528 0.931723 -0.110807 +v -1.196902 0.079273 -0.138427 +v -1.275672 -0.074665 -0.144295 +v -1.338086 -0.216524 -0.149868 +v -1.383391 -0.346599 -0.155174 +v -1.323812 -1.052420 -0.188965 +v -1.263262 -1.154272 -0.194692 +v -1.200053 -1.235896 -0.199522 +v -0.633976 -1.570334 -0.224339 +v -0.511892 -1.598220 -0.227634 +v -0.368947 -1.618115 -0.230900 +v -1.059028 -1.364901 -0.207828 +v -0.965594 -1.426708 -0.212232 +v -0.859864 -1.484514 -0.216650 +v -0.194835 -1.631269 -0.234362 +v -0.003745 -1.635607 -0.237693 +v -1.428110 -0.583470 -0.165454 +v -1.430441 -0.694013 -0.170556 +v -1.414979 -0.806799 -0.176053 +v 1.105644 0.233383 -0.168964 +v 1.018814 0.357471 -0.161773 +v 0.945494 0.474934 -0.155111 +v 0.110230 0.163075 -0.155889 +v 0.211321 0.155680 -0.157887 +v 0.927626 1.113336 -0.125138 +v 0.880521 1.122531 -0.123939 +v 0.806204 1.103363 -0.123613 +v 0.880513 0.716537 -0.142814 +v 0.890766 0.841752 -0.137161 +v 0.914712 0.959494 -0.132079 +v 0.506630 1.110173 -0.118392 +v 0.472748 1.111272 -0.117786 +v 0.438879 1.107356 -0.117413 +v 0.898184 0.593841 -0.148808 +v 0.293263 0.158172 -0.159114 +v 0.342140 0.210449 -0.157483 +v 0.657783 1.067314 -0.122859 +v 0.609074 1.071465 -0.121868 +v 0.573093 1.085794 -0.120613 +v 0.934137 1.056130 -0.127904 +v 0.324146 0.743998 -0.132428 +v 0.267946 0.662898 -0.135278 +v 0.188763 0.594176 -0.137177 +v 0.094329 0.553338 -0.137529 +v 0.592139 0.957662 -0.126837 +v 0.638480 0.957930 -0.127583 +v 0.689415 0.959354 -0.128351 +v 0.383522 1.070009 -0.118243 +v 0.371593 1.005208 -0.121061 +v 0.364592 0.918145 -0.124994 +v 0.353034 0.829519 -0.128925 +v 0.435447 0.909339 -0.126518 +v 0.465550 0.944205 -0.125390 +v 0.503761 0.954408 -0.125541 +v 1.271699 -0.063447 -0.185483 +v 1.192610 0.094322 -0.176853 +v 1.381875 -0.404960 -0.203165 +v 1.336530 -0.237447 -0.194634 +v 1.154759 -1.263296 -0.239352 +v 1.214957 -1.198382 -0.237320 +v 1.275056 -1.118745 -0.234601 +v 0.357115 -1.613239 -0.242562 +v 0.503317 -1.589606 -0.243857 +v 0.633705 -1.556793 -0.244466 +v 0.870773 -1.464354 -0.244050 +v 0.961730 -1.413012 -0.243152 +v 1.034823 -1.363103 -0.242029 +v 0.185138 -1.629105 -0.240483 +v 1.372483 -0.918622 -0.226892 +v 1.398014 -0.799772 -0.221785 +v 1.408464 -0.673075 -0.216065 +v -0.348987 1.171245 -0.101542 +v -0.748950 -1.532660 -0.220705 +v -0.435322 0.850435 -0.114999 +v -0.407402 0.741213 -0.120534 +v -0.346218 0.497272 -0.132877 +v -0.346330 0.341255 -0.140129 +v -0.371288 0.627883 -0.126394 +v -0.549874 1.225485 -0.095731 +v -0.562968 0.960082 -0.107811 +v -0.561502 1.004072 -0.105790 +v -1.134739 -1.303357 -0.203727 +v -0.765828 1.142791 -0.096040 +v -0.784884 0.925294 -0.105795 +v -0.744778 0.958614 -0.104902 +v -0.751577 0.992002 -0.103239 +v -1.377493 -0.930177 -0.182402 +v -1.157277 -0.158084 -0.150066 +v -1.074831 0.016294 -0.143309 +v -0.989008 0.187332 -0.136762 +v -0.794887 0.715045 -0.115406 +v -0.793313 0.835783 -0.109818 +v -0.915567 0.336222 -0.131042 +v -0.857621 0.467807 -0.125874 +v -0.815977 0.591961 -0.120783 +v -1.267661 -0.472961 -0.162898 +v -1.221339 -0.317953 -0.156450 +v -1.412722 -0.468355 -0.160354 +v 1.404561 -0.546167 -0.210101 +v -1.297325 -0.772967 -0.176361 +v -1.297365 -0.631976 -0.169805 +v -1.191656 -0.947633 -0.186211 +v -1.256360 -0.873963 -0.181727 +v -0.827392 -1.195702 -0.203709 +v -0.937563 -1.138562 -0.199249 +v -1.037241 -1.074787 -0.194651 +v -0.340828 -1.328644 -0.217857 +v -0.478346 -1.303687 -0.214445 +v -0.599223 -1.273088 -0.211043 +v 0.350910 -1.321201 -0.228837 +v 0.182569 -1.339149 -0.226915 +v 0.000954 -1.348012 -0.224353 +v 1.165498 -0.982342 -0.226420 +v 1.096631 -1.039312 -0.227942 +v 1.026821 -1.088263 -0.229074 +v 0.855663 -1.186285 -0.230829 +v 0.744760 -1.230399 -0.231064 +v 0.622614 -1.267938 -0.230809 +v -0.178100 -1.344209 -0.221245 +v -1.119958 -1.012011 -0.190378 +v -0.714467 -1.238988 -0.207571 +v 0.407098 1.099169 -0.117273 +v 0.758580 -1.513804 -0.244512 +v 0.494658 -1.297752 -0.230100 +v 0.394125 0.735774 -0.133911 +v 0.414815 0.834702 -0.129650 +v 0.350279 0.341329 -0.151531 +v 0.349529 0.497394 -0.144264 +v 0.367558 0.627264 -0.138520 +v 0.726710 1.080390 -0.123380 +v 0.744975 0.957577 -0.129343 +v 0.785416 0.924819 -0.131529 +v 1.330074 -1.024639 -0.231127 +v 1.284273 -0.803687 -0.220059 +v 1.235394 -0.906822 -0.224054 +v 1.262487 -0.504668 -0.205800 +v 1.290033 -0.666525 -0.213776 +v 0.984935 0.194658 -0.168742 +v 1.069859 0.027776 -0.177891 +v 1.150514 -0.149285 -0.187444 +v 0.793644 0.836057 -0.135790 +v 0.792962 0.718079 -0.141264 +v 0.848270 0.480180 -0.153230 +v 0.908526 0.345666 -0.160470 +v 0.809437 0.600816 -0.146985 +v 1.215296 -0.329386 -0.196878 +v 0.539866 1.100625 -0.119380 +v 0.546816 0.957186 -0.126117 +v 1.096647 -1.315598 -0.240832 +v 0.948566 -1.137725 -0.230093 +v -1.109673 0.232619 -0.164791 +v -1.022891 0.368583 -0.159891 +v -0.950736 0.490657 -0.155397 +v -0.000498 0.168566 -0.185976 +v -0.110569 0.164587 -0.184359 +v -0.211421 0.157227 -0.183049 +v -0.939408 1.154552 -0.124716 +v -0.895583 1.152496 -0.125529 +v -0.833184 1.147911 -0.126764 +v -0.887797 0.721197 -0.145709 +v -0.895324 0.843214 -0.139913 +v -0.915688 0.959656 -0.134166 +v -0.500954 1.240196 -0.127913 +v -0.450813 1.231135 -0.129115 +v -0.411978 1.215176 -0.130195 +v -0.413786 0.707821 -0.154138 +v -0.451700 0.740925 -0.151978 +v -0.483292 0.774465 -0.149901 +v -0.905184 0.605330 -0.150811 +v -0.293074 0.159762 -0.181595 +v -0.340867 0.212008 -0.178383 +v -0.703099 1.149633 -0.128814 +v -0.647957 1.170066 -0.128767 +v -0.598357 1.199216 -0.128224 +v -0.951335 1.120458 -0.126106 +v -0.955592 1.148956 -0.124711 +v -0.963241 1.153525 -0.124056 +v -0.508193 0.848910 -0.146032 +v -0.532100 0.924588 -0.142122 +v -0.341246 0.764387 -0.152650 +v -0.278802 0.671146 -0.158007 +v -0.195339 0.598295 -0.162761 +v -0.102291 0.555793 -0.166261 +v -0.005220 0.542208 -0.168482 +v -0.596778 1.001452 -0.137490 +v -0.596928 0.961172 -0.139360 +v -0.639427 0.961188 -0.138663 +v -0.640739 0.997473 -0.136955 +v -0.689898 0.962301 -0.137785 +v -0.692575 0.995637 -0.136191 +v -0.311971 1.110586 -0.137034 +v -0.342985 1.057755 -0.138982 +v -0.358568 1.060519 -0.138644 +v -0.337193 1.056510 -0.138817 +v -0.370353 0.976037 -0.142333 +v -0.371875 0.872019 -0.147144 +v -1.276196 -0.073178 -0.176282 +v -1.197426 0.080760 -0.170415 +v -1.383847 -0.344707 -0.187143 +v -1.338601 -0.214986 -0.181853 +v -1.200362 -1.234681 -0.231525 +v -1.260869 -1.154228 -0.226796 +v -1.304531 -1.057192 -0.221586 +v -0.369470 -1.616628 -0.262887 +v -0.512415 -1.596733 -0.259622 +v -0.634500 -1.568847 -0.256326 +v -0.860388 -1.483027 -0.248638 +v -0.966117 -1.425220 -0.244219 +v -1.059551 -1.363414 -0.239815 +v -0.004269 -1.634120 -0.269680 +v -0.195359 -1.629781 -0.266350 +v 0.944971 0.476421 -0.187098 +v 1.018290 0.358958 -0.193760 +v 1.105120 0.234870 -0.200951 +v 0.210796 0.157171 -0.189965 +v 0.109704 0.164567 -0.187966 +v 0.805680 1.104850 -0.155600 +v 0.879997 1.124018 -0.155926 +v 0.927102 1.114823 -0.157125 +v 0.914189 0.960980 -0.164066 +v 0.890243 0.843239 -0.169148 +v 0.879989 0.718024 -0.174802 +v 0.438356 1.108843 -0.149400 +v 0.472224 1.112759 -0.149773 +v 0.506106 1.111660 -0.150379 +v 0.897660 0.595329 -0.180795 +v 0.341615 0.211941 -0.189561 +v 0.292738 0.159663 -0.191191 +v 0.572569 1.087281 -0.152600 +v 0.608550 1.072953 -0.153856 +v 0.657259 1.068801 -0.154846 +v 0.933613 1.057617 -0.159891 +v 0.188240 0.595663 -0.169164 +v 0.267423 0.664385 -0.167265 +v 0.323622 0.745485 -0.164415 +v 0.093805 0.554825 -0.169516 +v 0.688890 0.960845 -0.160429 +v 0.637955 0.959421 -0.159661 +v 0.591614 0.959153 -0.158915 +v 0.364068 0.919632 -0.156981 +v 0.371069 1.006695 -0.153048 +v 0.382998 1.071496 -0.150230 +v 0.352511 0.831006 -0.160912 +v 0.503235 0.955899 -0.157619 +v 0.465024 0.945697 -0.157467 +v 0.434922 0.910831 -0.158596 +v 1.192086 0.095809 -0.208840 +v 1.271175 -0.061960 -0.217470 +v 1.336006 -0.235960 -0.226621 +v 1.381352 -0.403472 -0.235152 +v 1.274532 -1.117258 -0.266588 +v 1.214337 -1.196972 -0.269309 +v 1.153466 -1.262424 -0.271355 +v 0.634048 -1.554965 -0.276452 +v 0.502902 -1.588077 -0.275844 +v 0.356591 -1.611751 -0.274549 +v 0.184614 -1.627618 -0.272470 +v 1.407940 -0.671588 -0.248053 +v 1.397490 -0.798285 -0.253772 +v 1.371959 -0.917135 -0.258880 +v -0.749474 -1.531173 -0.252692 +v -0.346889 0.342858 -0.172201 +v -0.347013 0.499658 -0.164909 +v -0.373141 0.627258 -0.158549 +v -0.550272 1.226913 -0.127723 +v -0.561350 0.956796 -0.140146 +v -0.557968 1.001267 -0.138134 +v -1.135236 -1.301904 -0.235716 +v -0.766351 1.144278 -0.128027 +v -0.745303 0.960105 -0.136980 +v -0.752102 0.993494 -0.135316 +v -0.785410 0.926786 -0.137872 +v -1.316800 -0.950164 -0.216431 +v -1.298343 -0.879658 -0.213460 +v -0.989533 0.188823 -0.168840 +v -1.075356 0.017785 -0.175387 +v -1.157803 -0.156592 -0.182144 +v -0.793839 0.837275 -0.141896 +v -0.795413 0.716536 -0.147484 +v -0.858146 0.469298 -0.157951 +v -0.916093 0.337714 -0.163120 +v -0.816502 0.593452 -0.152861 +v -1.221799 -0.316026 -0.188509 +v -1.267661 -0.467991 -0.194823 +v -1.411494 -0.576606 -0.197491 +v -1.411019 -0.465196 -0.192303 +v 1.404037 -0.544680 -0.242088 +v -1.301249 -0.613415 -0.201034 +v -1.335573 -0.698332 -0.204420 +v -1.252195 -0.890997 -0.214743 +v -1.190170 -0.948362 -0.218425 +v -1.037767 -1.073296 -0.226729 +v -0.938089 -1.137071 -0.231326 +v -0.827918 -1.194211 -0.235787 +v -0.599748 -1.271596 -0.243121 +v -0.478872 -1.302196 -0.246522 +v -0.341354 -1.327153 -0.249935 +v 0.000429 -1.346520 -0.256431 +v 0.182044 -1.337658 -0.258993 +v 0.350385 -1.319710 -0.260915 +v 1.026200 -1.086864 -0.261155 +v 1.096014 -1.037896 -0.260021 +v 1.164940 -0.980876 -0.258499 +v 0.622127 -1.266432 -0.262887 +v 0.744339 -1.228868 -0.263142 +v 0.855255 -1.184762 -0.262907 +v -0.178625 -1.342718 -0.253323 +v -1.379306 -0.670456 -0.202403 +v -1.120232 -1.010797 -0.222473 +v -0.714992 -1.237496 -0.239648 +v 0.406574 1.100656 -0.149261 +v 0.849591 -1.480566 -0.276359 +v 0.757564 -1.513704 -0.276536 +v 0.494138 -1.296260 -0.262178 +v 0.414290 0.836194 -0.161728 +v 0.393600 0.737265 -0.165988 +v 0.349004 0.498885 -0.176341 +v 0.349754 0.342820 -0.183609 +v 0.367032 0.628756 -0.170598 +v 0.726186 1.081877 -0.155367 +v 0.784891 0.926311 -0.163606 +v 0.744450 0.959069 -0.161421 +v 1.329550 -1.023152 -0.263114 +v 1.234864 -0.905334 -0.256132 +v 1.283748 -0.802196 -0.252137 +v 1.289508 -0.665033 -0.245854 +v 1.261962 -0.503177 -0.237878 +v 1.149988 -0.147793 -0.219522 +v 1.069334 0.029268 -0.209969 +v 0.984410 0.196149 -0.200820 +v 0.792437 0.719570 -0.173342 +v 0.793119 0.837548 -0.167868 +v 0.908000 0.347158 -0.192548 +v 0.847745 0.481671 -0.185308 +v 0.808912 0.602307 -0.179063 +v 1.214771 -0.327895 -0.228956 +v 0.539342 1.102112 -0.151367 +v 0.546290 0.958678 -0.158195 +v 1.094234 -1.315695 -0.272862 +v 0.948053 -1.136267 -0.262172 +v -0.373728 1.197662 -0.129667 +v -0.392497 1.210473 -0.128052 +v -0.390079 1.209766 -0.125221 +v -0.375648 1.199755 -0.123068 +v -0.308800 1.152728 -0.126349 +v -0.295314 1.143162 -0.129870 +v -0.289454 1.138075 -0.127857 +v -0.295314 1.143162 -0.129870 +v -0.289454 1.138075 -0.127857 +v -0.293566 1.141884 -0.132861 +v -0.293566 1.141884 -0.132861 +v -0.341776 1.176032 -0.123836 +v 0.974357 -1.417005 -0.274305 +v 0.974357 -1.417005 -0.274305 +v 0.920656 -1.452124 -0.275288 +v 0.920656 -1.452124 -0.275288 +v 0.891558 -1.467290 -0.276046 +v 0.891558 -1.467290 -0.276046 +v -0.395579 1.209684 -0.129854 +v -0.395579 1.209684 -0.129854 +v -0.392497 1.210473 -0.128052 +v -0.293788 1.141592 -0.134683 +v -0.310885 1.152238 -0.134004 +v -0.293788 1.141592 -0.134683 +v -0.293788 1.141592 -0.134683 +v -0.294438 1.140140 -0.135598 +v -0.297349 1.134066 -0.136138 +v -0.936297 1.055660 -0.129365 +v -0.916174 1.053480 -0.129841 +v -0.343336 1.053889 -0.107091 +v -0.359252 1.057148 -0.106634 +v -0.336985 1.054149 -0.107501 +v -0.955068 1.147469 -0.092724 +v -0.962728 1.152067 -0.092703 +v -0.945335 1.057339 -0.106401 +v -0.945445 1.057650 -0.113090 +v -0.945554 1.057961 -0.119779 +v -0.300351 1.145971 -0.120829 +v -0.304160 1.147990 -0.112781 +v -0.291255 1.131108 -0.113707 +v -0.290646 1.130954 -0.120526 +v -0.289739 1.130504 -0.127264 +v -0.965556 1.155414 -0.122914 +v -0.965556 1.155414 -0.122914 +v -0.965556 1.155414 -0.122914 +v -0.335360 1.056036 -0.137853 +v -0.335360 1.056036 -0.137853 +v -0.334918 1.054560 -0.108532 +v -0.334918 1.054560 -0.108532 +v -0.965076 1.154050 -0.093588 +v -0.965076 1.154050 -0.093588 +v -0.965076 1.154050 -0.093588 +v -0.876251 1.051708 -0.130577 +v -0.821086 1.050491 -0.131537 +v -0.696115 1.052239 -0.133502 +v -0.642514 1.061172 -0.133964 +v -0.596114 1.074648 -0.134098 +v -0.511962 1.088949 -0.134810 +v -0.469341 1.083364 -0.135768 +v -0.427309 1.073519 -0.136914 +v -0.388310 1.065574 -0.137922 +v -0.758075 1.050535 -0.132567 +v -0.553641 1.086433 -0.134245 +v -0.875725 1.050217 -0.098499 +v -0.820560 1.049000 -0.099459 +v -0.642117 1.059682 -0.101884 +v -0.695590 1.050748 -0.101424 +v -0.596617 1.073169 -0.102002 +v -0.472678 1.090610 -0.103221 +v -0.516038 1.093229 -0.102389 +v -0.428646 1.078843 -0.104489 +v -0.388861 1.066473 -0.105715 +v -0.757550 1.049043 -0.100489 +v -0.556151 1.086004 -0.102068 +vt 0.233760 0.665886 +vt 0.230796 0.664083 +vt 0.227052 0.675587 +vt 0.230008 0.677863 +vt 0.224097 0.673306 +vt 0.221565 0.683442 +vt 0.224545 0.686380 +vt 0.227527 0.689307 +vt 0.269014 0.567228 +vt 0.272190 0.565353 +vt 0.272116 0.562406 +vt 0.268820 0.564612 +vt 0.275417 0.564272 +vt 0.275486 0.561179 +vt 0.272473 0.617965 +vt 0.276628 0.617129 +vt 0.276813 0.607132 +vt 0.273308 0.607961 +vt 0.280997 0.616147 +vt 0.280367 0.606234 +vt 0.278924 0.597570 +vt 0.276078 0.598219 +vt 0.273090 0.598861 +vt 0.323300 0.681429 +vt 0.313066 0.681863 +vt 0.313686 0.699272 +vt 0.324806 0.699077 +vt 0.303604 0.681704 +vt 0.303465 0.698663 +vt 0.303242 0.714172 +vt 0.314098 0.714933 +vt 0.325976 0.714792 +vt 0.292995 0.612934 +vt 0.295958 0.611612 +vt 0.292071 0.602608 +vt 0.290004 0.603595 +vt 0.294266 0.601426 +vt 0.289295 0.594367 +vt 0.287831 0.594974 +vt 0.286360 0.595577 +vt 0.294731 0.631683 +vt 0.297691 0.632986 +vt 0.297512 0.623244 +vt 0.294131 0.624100 +vt 0.303307 0.632448 +vt 0.302872 0.622253 +vt 0.300998 0.609607 +vt 0.310470 0.631467 +vt 0.309854 0.621979 +vt 0.318393 0.630657 +vt 0.317530 0.621601 +vt 0.316667 0.612547 +vt 0.309177 0.612293 +vt 0.255681 0.619009 +vt 0.259245 0.619136 +vt 0.261263 0.609474 +vt 0.257910 0.609499 +vt 0.263770 0.619071 +vt 0.265475 0.609244 +vt 0.265873 0.599995 +vt 0.261879 0.600235 +vt 0.258674 0.600282 +vt 0.247895 0.640850 +vt 0.251847 0.641704 +vt 0.256058 0.629678 +vt 0.252303 0.629230 +vt 0.256993 0.642552 +vt 0.260905 0.629995 +vt 0.267599 0.643162 +vt 0.273070 0.643232 +vt 0.275452 0.628983 +vt 0.270629 0.629514 +vt 0.278744 0.643141 +vt 0.280492 0.628280 +vt 0.252169 0.571557 +vt 0.256993 0.571413 +vt 0.256672 0.569515 +vt 0.251780 0.569653 +vt 0.261636 0.570756 +vt 0.261348 0.568756 +vt 0.261118 0.591484 +vt 0.258059 0.591639 +vt 0.265025 0.591249 +vt 0.263860 0.584685 +vt 0.260000 0.585078 +vt 0.257703 0.586363 +vt 0.274608 0.590007 +vt 0.271913 0.590433 +vt 0.277106 0.589556 +vt 0.275606 0.583559 +vt 0.273200 0.583902 +vt 0.270632 0.584164 +vt 0.282535 0.565584 +vt 0.286010 0.567056 +vt 0.286607 0.564875 +vt 0.282910 0.563007 +vt 0.289412 0.566293 +vt 0.285012 0.586857 +vt 0.283556 0.587379 +vt 0.286400 0.586457 +vt 0.285732 0.578675 +vt 0.283978 0.578796 +vt 0.281274 0.579030 +vt 0.287521 0.680146 +vt 0.280118 0.679040 +vt 0.278310 0.694419 +vt 0.286232 0.696046 +vt 0.272886 0.677739 +vt 0.270602 0.692598 +vt 0.268932 0.707084 +vt 0.276964 0.709206 +vt 0.285223 0.711074 +vt 0.290884 0.641533 +vt 0.284621 0.642728 +vt 0.282455 0.660992 +vt 0.289150 0.661340 +vt 0.275896 0.660514 +vt 0.262278 0.642998 +vt 0.257786 0.657977 +vt 0.263431 0.658904 +vt 0.252295 0.656840 +vt 0.247724 0.671157 +vt 0.253379 0.672935 +vt 0.259290 0.674587 +vt 0.319678 0.643859 +vt 0.311237 0.644756 +vt 0.312114 0.661555 +vt 0.321353 0.660857 +vt 0.303460 0.645721 +vt 0.303563 0.662006 +vt 0.244104 0.639865 +vt 0.241165 0.639082 +vt 0.235743 0.651500 +vt 0.238766 0.652768 +vt 0.232723 0.650225 +vt 0.227833 0.662275 +vt 0.250032 0.686242 +vt 0.256265 0.688387 +vt 0.244133 0.684027 +vt 0.241506 0.696659 +vt 0.247554 0.699338 +vt 0.254040 0.701956 +vt 0.283299 0.749911 +vt 0.274578 0.748051 +vt 0.274377 0.755231 +vt 0.283082 0.757182 +vt 0.265984 0.745472 +vt 0.265843 0.752531 +vt 0.249844 0.737757 +vt 0.243434 0.733593 +vt 0.243803 0.740737 +vt 0.250019 0.744862 +vt 0.237817 0.729186 +vt 0.238353 0.736264 +vt 0.227260 0.714523 +vt 0.222917 0.707419 +vt 0.223439 0.716401 +vt 0.227958 0.724092 +vt 0.220202 0.710334 +vt 0.328449 0.751640 +vt 0.315052 0.752460 +vt 0.315220 0.759442 +vt 0.328907 0.758618 +vt 0.302799 0.752344 +vt 0.302701 0.759406 +vt 0.407244 0.651007 +vt 0.413117 0.663839 +vt 0.415804 0.661348 +vt 0.409951 0.648686 +vt 0.417647 0.676415 +vt 0.420263 0.673714 +vt 0.357374 0.572085 +vt 0.356573 0.569133 +vt 0.353635 0.568850 +vt 0.354152 0.572223 +vt 0.353164 0.565477 +vt 0.350578 0.565131 +vt 0.350800 0.568851 +vt 0.351069 0.572562 +vt 0.361179 0.609572 +vt 0.358755 0.600149 +vt 0.355423 0.600001 +vt 0.357689 0.609550 +vt 0.357609 0.591656 +vt 0.354162 0.591569 +vt 0.350865 0.591530 +vt 0.351845 0.599884 +vt 0.353636 0.609535 +vt 0.336224 0.697921 +vt 0.333758 0.680353 +vt 0.338171 0.713585 +vt 0.349549 0.711642 +vt 0.346888 0.696114 +vt 0.343511 0.678848 +vt 0.340831 0.609062 +vt 0.341758 0.599495 +vt 0.339405 0.599025 +vt 0.337508 0.608318 +vt 0.343419 0.591503 +vt 0.341806 0.591501 +vt 0.336889 0.598378 +vt 0.331975 0.607221 +vt 0.342163 0.627814 +vt 0.341616 0.620236 +vt 0.338008 0.619975 +vt 0.339374 0.629592 +vt 0.332376 0.619893 +vt 0.333670 0.629982 +vt 0.325258 0.620752 +vt 0.326375 0.630178 +vt 0.324156 0.611128 +vt 0.377468 0.608054 +vt 0.374016 0.599292 +vt 0.370335 0.599774 +vt 0.373459 0.608708 +vt 0.372250 0.590753 +vt 0.368952 0.591213 +vt 0.364904 0.591607 +vt 0.365944 0.600182 +vt 0.368710 0.609309 +vt 0.389398 0.628781 +vt 0.382743 0.617818 +vt 0.378757 0.618849 +vt 0.385632 0.630371 +vt 0.373838 0.619918 +vt 0.380702 0.632182 +vt 0.370594 0.634711 +vt 0.365083 0.621007 +vt 0.360864 0.621353 +vt 0.365583 0.635663 +vt 0.356157 0.621640 +vt 0.360281 0.636478 +vt 0.373644 0.572717 +vt 0.373256 0.567103 +vt 0.368178 0.568254 +vt 0.368940 0.571150 +vt 0.367324 0.565539 +vt 0.362372 0.566806 +vt 0.363427 0.569200 +vt 0.364473 0.571594 +vt 0.371680 0.582326 +vt 0.368620 0.582667 +vt 0.371207 0.577090 +vt 0.368732 0.576195 +vt 0.364859 0.576434 +vt 0.364718 0.583067 +vt 0.357448 0.583398 +vt 0.353999 0.583484 +vt 0.357683 0.577048 +vt 0.354304 0.577306 +vt 0.351161 0.577688 +vt 0.350832 0.583654 +vt 0.345567 0.576453 +vt 0.345649 0.570287 +vt 0.343556 0.571161 +vt 0.343492 0.577429 +vt 0.343475 0.566686 +vt 0.344479 0.583984 +vt 0.343073 0.584358 +vt 0.359358 0.675247 +vt 0.364097 0.691667 +vt 0.371897 0.689094 +vt 0.366653 0.673150 +vt 0.367818 0.706745 +vt 0.375987 0.703878 +vt 0.383322 0.700861 +vt 0.378962 0.686421 +vt 0.373377 0.670956 +vt 0.347824 0.636927 +vt 0.353622 0.656407 +vt 0.360285 0.655060 +vt 0.354429 0.637056 +vt 0.366567 0.653653 +vt 0.377526 0.650375 +vt 0.382956 0.648322 +vt 0.375617 0.633610 +vt 0.384517 0.666243 +vt 0.390054 0.663283 +vt 0.395501 0.659913 +vt 0.388311 0.645876 +vt 0.330734 0.660062 +vt 0.328201 0.643372 +vt 0.339465 0.659164 +vt 0.336102 0.643071 +vt 0.392995 0.627210 +vt 0.400258 0.638664 +vt 0.403051 0.636838 +vt 0.395794 0.626095 +vt 0.390253 0.680734 +vt 0.395815 0.677205 +vt 0.394815 0.694416 +vt 0.400285 0.690599 +vt 0.405679 0.686469 +vt 0.401299 0.673325 +vt 0.374070 0.741946 +vt 0.374866 0.748948 +vt 0.383732 0.745228 +vt 0.382895 0.738361 +vt 0.384572 0.752093 +vt 0.392521 0.747835 +vt 0.391677 0.741095 +vt 0.390836 0.734354 +vt 0.402806 0.726013 +vt 0.403433 0.732717 +vt 0.407985 0.728760 +vt 0.407563 0.721994 +vt 0.408410 0.735524 +vt 0.412484 0.731258 +vt 0.412333 0.724333 +vt 0.412180 0.717411 +vt 0.421175 0.701478 +vt 0.421027 0.712074 +vt 0.424408 0.705481 +vt 0.424369 0.695470 +vt 0.424079 0.712851 +vt 0.342530 0.756927 +vt 0.341899 0.749898 +vt 0.343160 0.763957 +vt 0.355691 0.761732 +vt 0.354980 0.754650 +vt 0.354269 0.747569 +vt 0.292427 0.751403 +vt 0.292218 0.758603 +vt 0.296780 0.645824 +vt 0.296024 0.661966 +vt 0.295206 0.681078 +vt 0.294453 0.697514 +vt 0.293785 0.712794 +vt 0.281784 0.596911 +vt 0.279602 0.589077 +vt 0.284081 0.596355 +vt 0.281581 0.588708 +vt 0.279967 0.584051 +vt 0.278095 0.583305 +vt 0.278906 0.564465 +vt 0.279109 0.561528 +vt 0.285737 0.627368 +vt 0.290051 0.626323 +vt 0.289373 0.614149 +vt 0.285628 0.615057 +vt 0.284081 0.605305 +vt 0.287088 0.604559 +vt 0.257533 0.741881 +vt 0.257525 0.748929 +vt 0.265853 0.676219 +vt 0.263175 0.690545 +vt 0.261217 0.704603 +vt 0.269502 0.659777 +vt 0.269690 0.599497 +vt 0.268720 0.590880 +vt 0.267535 0.584442 +vt 0.265812 0.629904 +vt 0.268227 0.618653 +vt 0.269552 0.608707 +vt 0.265597 0.569229 +vt 0.265338 0.566966 +vt 0.232441 0.723831 +vt 0.233053 0.730911 +vt 0.246894 0.655414 +vt 0.242712 0.654170 +vt 0.237769 0.667678 +vt 0.242125 0.669234 +vt 0.251289 0.600406 +vt 0.253427 0.600303 +vt 0.252365 0.591153 +vt 0.255569 0.600227 +vt 0.254784 0.591022 +vt 0.254322 0.582183 +vt 0.250579 0.582678 +vt 0.250054 0.591372 +vt 0.244628 0.571586 +vt 0.247828 0.571620 +vt 0.247344 0.569673 +vt 0.238230 0.638289 +vt 0.246212 0.628104 +vt 0.248783 0.628597 +vt 0.252429 0.618661 +vt 0.250243 0.618361 +vt 0.243644 0.627602 +vt 0.248060 0.618055 +vt 0.252738 0.609280 +vt 0.254802 0.609371 +vt 0.250676 0.609188 +vt 0.238420 0.681746 +vt 0.234031 0.679962 +vt 0.231520 0.691817 +vt 0.235818 0.693926 +vt 0.234167 0.706374 +vt 0.239636 0.709883 +vt 0.230175 0.703620 +vt 0.230232 0.711596 +vt 0.233256 0.715892 +vt 0.238424 0.720318 +vt 0.259551 0.719816 +vt 0.267596 0.722780 +vt 0.252116 0.716529 +vt 0.250676 0.728202 +vt 0.258319 0.732057 +vt 0.266653 0.735427 +vt 0.293206 0.728706 +vt 0.303057 0.730002 +vt 0.284382 0.727001 +vt 0.283779 0.739720 +vt 0.292788 0.741309 +vt 0.302935 0.742418 +vt 0.327029 0.730212 +vt 0.339811 0.728800 +vt 0.327810 0.742056 +vt 0.340970 0.740411 +vt 0.353138 0.738141 +vt 0.351684 0.726688 +vt 0.420639 0.688282 +vt 0.423110 0.684883 +vt 0.398492 0.707621 +vt 0.403707 0.703671 +vt 0.401026 0.717581 +vt 0.405987 0.713576 +vt 0.410834 0.709047 +vt 0.408830 0.699323 +vt 0.370709 0.721459 +vt 0.379173 0.718304 +vt 0.372629 0.732682 +vt 0.381301 0.729291 +vt 0.389104 0.725532 +vt 0.386768 0.714889 +vt 0.314498 0.730580 +vt 0.314812 0.742719 +vt 0.223174 0.697067 +vt 0.226282 0.701144 +vt 0.220152 0.693035 +vt 0.219737 0.702081 +vt 0.245576 0.713254 +vt 0.244176 0.724334 +vt 0.275894 0.725104 +vt 0.275147 0.737877 +vt 0.361781 0.724239 +vt 0.359233 0.709339 +vt 0.363481 0.735590 +vt 0.365530 0.752038 +vt 0.364772 0.744962 +vt 0.366288 0.759114 +vt 0.375665 0.755948 +vt 0.346939 0.658017 +vt 0.342718 0.642120 +vt 0.351856 0.677142 +vt 0.355983 0.694011 +vt 0.348227 0.583974 +vt 0.347920 0.591561 +vt 0.348552 0.578436 +vt 0.347012 0.579822 +vt 0.346429 0.584293 +vt 0.345726 0.591591 +vt 0.348115 0.569351 +vt 0.348241 0.573469 +vt 0.348047 0.565354 +vt 0.345621 0.565917 +vt 0.350810 0.621811 +vt 0.348859 0.609527 +vt 0.344807 0.609503 +vt 0.346180 0.621664 +vt 0.348015 0.599821 +vt 0.344887 0.599783 +vt 0.413651 0.694661 +vt 0.410581 0.682396 +vt 0.415459 0.703624 +vt 0.418054 0.698671 +vt 0.417180 0.690992 +vt 0.414187 0.679326 +vt 0.416818 0.718748 +vt 0.416934 0.711306 +vt 0.416653 0.726010 +vt 0.420673 0.719749 +vt 0.393186 0.643136 +vt 0.400339 0.656415 +vt 0.403831 0.653680 +vt 0.396765 0.640889 +vt 0.379341 0.590108 +vt 0.379255 0.580816 +vt 0.377042 0.580975 +vt 0.377329 0.590187 +vt 0.380137 0.572115 +vt 0.377444 0.572464 +vt 0.374745 0.581226 +vt 0.375317 0.590292 +vt 0.380815 0.565278 +vt 0.377710 0.566023 +vt 0.377766 0.562005 +vt 0.372830 0.563618 +vt 0.398585 0.624969 +vt 0.391519 0.616028 +vt 0.388946 0.616458 +vt 0.385519 0.607587 +vt 0.383253 0.607572 +vt 0.380981 0.607548 +vt 0.386366 0.616875 +vt 0.381385 0.599041 +vt 0.379333 0.598985 +vt 0.377278 0.598927 +vt 0.406169 0.669508 +vt 0.409687 0.666622 +vt 0.393046 0.711334 +vt 0.389389 0.697774 +vt 0.395567 0.721575 +vt 0.398156 0.736845 +vt 0.397386 0.730155 +vt 0.398930 0.743533 +vt 0.404064 0.739417 +vt 0.384864 0.683724 +vt 0.379149 0.668727 +vt 0.372190 0.652115 +vt 0.360979 0.583303 +vt 0.361125 0.591721 +vt 0.361142 0.576794 +vt 0.369285 0.620597 +vt 0.364668 0.609556 +vt 0.362121 0.600268 +vt 0.359674 0.569404 +vt 0.360696 0.571952 +vt 0.358683 0.566854 +vt 0.355817 0.566182 +vt 0.196776 0.665885 +vt 0.200524 0.677816 +vt 0.203481 0.675551 +vt 0.199740 0.664082 +vt 0.202984 0.688938 +vt 0.205971 0.686100 +vt 0.161493 0.567227 +vt 0.161711 0.564613 +vt 0.158386 0.562414 +vt 0.158249 0.565359 +vt 0.158488 0.561571 +vt 0.154960 0.560343 +vt 0.154893 0.561241 +vt 0.154906 0.564352 +vt 0.158064 0.617966 +vt 0.157230 0.607962 +vt 0.153721 0.607128 +vt 0.153909 0.617129 +vt 0.157448 0.598862 +vt 0.154461 0.598205 +vt 0.151461 0.597407 +vt 0.150138 0.606274 +vt 0.149541 0.616147 +vt 0.107236 0.681429 +vt 0.105730 0.699076 +vt 0.116850 0.699271 +vt 0.117470 0.681862 +vt 0.104559 0.714791 +vt 0.116437 0.714931 +vt 0.127293 0.714170 +vt 0.127070 0.698662 +vt 0.126932 0.681703 +vt 0.137578 0.612845 +vt 0.140728 0.603421 +vt 0.138567 0.602437 +vt 0.134604 0.611548 +vt 0.145359 0.595477 +vt 0.142961 0.594822 +vt 0.136299 0.601367 +vt 0.129546 0.609591 +vt 0.135806 0.631683 +vt 0.136411 0.624089 +vt 0.133029 0.623237 +vt 0.132846 0.632986 +vt 0.127666 0.622251 +vt 0.127230 0.632448 +vt 0.120684 0.621979 +vt 0.120068 0.631468 +vt 0.121361 0.612293 +vt 0.113871 0.612547 +vt 0.113008 0.621601 +vt 0.112144 0.630657 +vt 0.174856 0.619009 +vt 0.172627 0.609499 +vt 0.169274 0.609474 +vt 0.171292 0.619136 +vt 0.171864 0.600282 +vt 0.168658 0.600235 +vt 0.164665 0.599995 +vt 0.165063 0.609244 +vt 0.166768 0.619071 +vt 0.182642 0.640849 +vt 0.178234 0.629230 +vt 0.174479 0.629678 +vt 0.178690 0.641704 +vt 0.169632 0.629994 +vt 0.173544 0.642552 +vt 0.162938 0.643161 +vt 0.159908 0.629514 +vt 0.155085 0.628983 +vt 0.157467 0.643232 +vt 0.150045 0.628280 +vt 0.151793 0.643141 +vt 0.178369 0.571558 +vt 0.178758 0.569653 +vt 0.173866 0.569516 +vt 0.173546 0.571414 +vt 0.173971 0.568923 +vt 0.169304 0.568142 +vt 0.169191 0.568756 +vt 0.168902 0.570757 +vt 0.172479 0.591640 +vt 0.169419 0.591485 +vt 0.172835 0.586363 +vt 0.170538 0.585079 +vt 0.166678 0.584686 +vt 0.165512 0.591250 +vt 0.158622 0.590433 +vt 0.155997 0.590052 +vt 0.159881 0.584163 +vt 0.157352 0.584147 +vt 0.155669 0.585073 +vt 0.154122 0.589688 +vt 0.147976 0.587419 +vt 0.145823 0.586953 +vt 0.149112 0.579449 +vt 0.146704 0.579090 +vt 0.143016 0.680145 +vt 0.144304 0.696045 +vt 0.152226 0.694417 +vt 0.150418 0.679039 +vt 0.145313 0.711072 +vt 0.153572 0.709204 +vt 0.161603 0.707082 +vt 0.159933 0.692597 +vt 0.157650 0.677738 +vt 0.139653 0.641533 +vt 0.141386 0.661339 +vt 0.148082 0.660991 +vt 0.145916 0.642727 +vt 0.154641 0.660513 +vt 0.167105 0.658903 +vt 0.172750 0.657976 +vt 0.168258 0.642997 +vt 0.171246 0.674586 +vt 0.177157 0.672933 +vt 0.182813 0.671156 +vt 0.178241 0.656839 +vt 0.110859 0.643859 +vt 0.109184 0.660857 +vt 0.118422 0.661555 +vt 0.119300 0.644756 +vt 0.126973 0.662005 +vt 0.127076 0.645721 +vt 0.186433 0.639865 +vt 0.191771 0.652767 +vt 0.194793 0.651499 +vt 0.189371 0.639081 +vt 0.174271 0.688386 +vt 0.180504 0.686240 +vt 0.176495 0.701954 +vt 0.182982 0.699336 +vt 0.189030 0.696657 +vt 0.186403 0.684025 +vt 0.147235 0.749908 +vt 0.147452 0.757179 +vt 0.156158 0.755228 +vt 0.155957 0.748048 +vt 0.156361 0.762408 +vt 0.164836 0.759585 +vt 0.164692 0.752528 +vt 0.164551 0.745469 +vt 0.180691 0.737754 +vt 0.180516 0.744859 +vt 0.186710 0.740754 +vt 0.187072 0.733617 +vt 0.186358 0.747884 +vt 0.191577 0.743406 +vt 0.192010 0.736424 +vt 0.192490 0.729398 +vt 0.102085 0.751638 +vt 0.101628 0.758615 +vt 0.115314 0.759439 +vt 0.115482 0.752457 +vt 0.115144 0.766421 +vt 0.127929 0.766465 +vt 0.127834 0.759403 +vt 0.127736 0.752342 +vt 0.023292 0.651008 +vt 0.020586 0.648687 +vt 0.014732 0.661349 +vt 0.017420 0.663840 +vt 0.012046 0.658857 +vt 0.007660 0.671009 +vt 0.010274 0.673714 +vt 0.012889 0.676415 +vt 0.073165 0.572087 +vt 0.076387 0.572224 +vt 0.076903 0.568852 +vt 0.073965 0.569135 +vt 0.079469 0.572564 +vt 0.079738 0.568852 +vt 0.069358 0.609573 +vt 0.072848 0.609552 +vt 0.075114 0.600002 +vt 0.071783 0.600150 +vt 0.076902 0.609536 +vt 0.078692 0.599886 +vt 0.079673 0.591531 +vt 0.076376 0.591570 +vt 0.072929 0.591657 +vt 0.096778 0.680352 +vt 0.094312 0.697920 +vt 0.087025 0.678847 +vt 0.083648 0.696113 +vt 0.080987 0.711641 +vt 0.092365 0.713584 +vt 0.089707 0.609063 +vt 0.093029 0.608319 +vt 0.091133 0.599026 +vt 0.088780 0.599497 +vt 0.093649 0.598379 +vt 0.090335 0.591479 +vt 0.088732 0.591503 +vt 0.087119 0.591504 +vt 0.088374 0.627815 +vt 0.091163 0.629593 +vt 0.092530 0.619975 +vt 0.088921 0.620237 +vt 0.096868 0.629983 +vt 0.098162 0.619894 +vt 0.098562 0.607222 +vt 0.104162 0.630178 +vt 0.105279 0.620752 +vt 0.106381 0.611129 +vt 0.053069 0.608056 +vt 0.057078 0.608710 +vt 0.060203 0.599776 +vt 0.056522 0.599294 +vt 0.061828 0.609311 +vt 0.064593 0.600183 +vt 0.065634 0.591609 +vt 0.061586 0.591215 +vt 0.058288 0.590755 +vt 0.041139 0.628782 +vt 0.044906 0.630372 +vt 0.051781 0.618851 +vt 0.047795 0.617820 +vt 0.049836 0.632183 +vt 0.056699 0.619919 +vt 0.059944 0.634712 +vt 0.064954 0.635664 +vt 0.069673 0.621354 +vt 0.065455 0.621008 +vt 0.070257 0.636478 +vt 0.074380 0.621641 +vt 0.056894 0.572720 +vt 0.061598 0.571152 +vt 0.062360 0.568256 +vt 0.057282 0.567105 +vt 0.066066 0.571596 +vt 0.067111 0.569202 +vt 0.061918 0.582669 +vt 0.058858 0.582328 +vt 0.065820 0.583069 +vt 0.065679 0.576436 +vt 0.061806 0.576197 +vt 0.059331 0.577092 +vt 0.076539 0.583486 +vt 0.073090 0.583400 +vt 0.079706 0.583656 +vt 0.079377 0.577690 +vt 0.076235 0.577307 +vt 0.072855 0.577050 +vt 0.084971 0.576454 +vt 0.087047 0.577430 +vt 0.086983 0.571162 +vt 0.084889 0.570289 +vt 0.088489 0.571805 +vt 0.087465 0.584360 +vt 0.086059 0.583986 +vt 0.088823 0.584768 +vt 0.088492 0.578072 +vt 0.071178 0.675246 +vt 0.063883 0.673150 +vt 0.058639 0.689093 +vt 0.066439 0.691667 +vt 0.057159 0.670956 +vt 0.051574 0.686421 +vt 0.047214 0.700860 +vt 0.054548 0.703877 +vt 0.062717 0.706744 +vt 0.082713 0.636928 +vt 0.076108 0.637057 +vt 0.070252 0.655061 +vt 0.076915 0.656407 +vt 0.063970 0.653653 +vt 0.054920 0.633611 +vt 0.047581 0.648322 +vt 0.053010 0.650376 +vt 0.042226 0.645876 +vt 0.035035 0.659913 +vt 0.040482 0.663284 +vt 0.046020 0.666243 +vt 0.102336 0.643372 +vt 0.099803 0.660061 +vt 0.094435 0.643072 +vt 0.091071 0.659164 +vt 0.037542 0.627212 +vt 0.034744 0.626097 +vt 0.027486 0.636839 +vt 0.030279 0.638665 +vt 0.024698 0.635005 +vt 0.017881 0.646362 +vt 0.034721 0.677205 +vt 0.040283 0.680734 +vt 0.029238 0.673326 +vt 0.024857 0.686469 +vt 0.030251 0.690599 +vt 0.035721 0.694416 +vt 0.056443 0.741934 +vt 0.047580 0.738331 +vt 0.046615 0.745167 +vt 0.055607 0.748916 +vt 0.039632 0.734328 +vt 0.038592 0.741107 +vt 0.027781 0.726071 +vt 0.023022 0.722042 +vt 0.022694 0.728899 +vt 0.027247 0.732881 +vt 0.018374 0.717428 +vt 0.018256 0.724383 +vt 0.009360 0.701478 +vt 0.006167 0.695470 +vt 0.006128 0.705481 +vt 0.009509 0.712074 +vt 0.003836 0.700563 +vt 0.088635 0.749896 +vt 0.088005 0.756925 +vt 0.076266 0.747568 +vt 0.075555 0.754649 +vt 0.138316 0.758600 +vt 0.138108 0.751401 +vt 0.138523 0.765799 +vt 0.147670 0.764449 +vt 0.134512 0.661965 +vt 0.133756 0.645824 +vt 0.135331 0.681077 +vt 0.136083 0.697513 +vt 0.136751 0.712792 +vt 0.150702 0.592333 +vt 0.152276 0.587820 +vt 0.150363 0.587564 +vt 0.148848 0.593399 +vt 0.154651 0.579951 +vt 0.151724 0.579611 +vt 0.151024 0.561691 +vt 0.151272 0.564696 +vt 0.147052 0.563118 +vt 0.147570 0.565818 +vt 0.144800 0.627368 +vt 0.144910 0.615055 +vt 0.141174 0.614127 +vt 0.140488 0.626321 +vt 0.146364 0.605607 +vt 0.147934 0.599412 +vt 0.145553 0.600326 +vt 0.143370 0.605007 +vt 0.173009 0.748926 +vt 0.173001 0.741879 +vt 0.173020 0.755972 +vt 0.180345 0.751962 +vt 0.167361 0.690544 +vt 0.164683 0.676218 +vt 0.169318 0.704602 +vt 0.161034 0.659776 +vt 0.161818 0.590880 +vt 0.160847 0.599497 +vt 0.162999 0.584443 +vt 0.164725 0.629903 +vt 0.162310 0.618653 +vt 0.160986 0.608707 +vt 0.165199 0.566967 +vt 0.164938 0.569230 +vt 0.165324 0.566298 +vt 0.161834 0.563861 +vt 0.196743 0.731881 +vt 0.197153 0.725470 +vt 0.196345 0.738292 +vt 0.199309 0.733848 +vt 0.200086 0.728412 +vt 0.199863 0.724042 +vt 0.183643 0.655413 +vt 0.188411 0.669233 +vt 0.192767 0.667677 +vt 0.187824 0.654169 +vt 0.179248 0.600406 +vt 0.180484 0.591372 +vt 0.178173 0.591153 +vt 0.177111 0.600304 +vt 0.182593 0.582928 +vt 0.179959 0.582679 +vt 0.176216 0.582183 +vt 0.175754 0.591022 +vt 0.174968 0.600227 +vt 0.185910 0.571587 +vt 0.186401 0.569585 +vt 0.183194 0.569674 +vt 0.182710 0.571620 +vt 0.183328 0.569082 +vt 0.178891 0.569058 +vt 0.192307 0.638288 +vt 0.186893 0.627602 +vt 0.184325 0.628104 +vt 0.182477 0.618054 +vt 0.180294 0.618361 +vt 0.178108 0.618661 +vt 0.181754 0.628596 +vt 0.179862 0.609188 +vt 0.177799 0.609280 +vt 0.175735 0.609371 +vt 0.192116 0.681743 +vt 0.194717 0.693913 +vt 0.199009 0.691725 +vt 0.196505 0.679949 +vt 0.190892 0.709887 +vt 0.196418 0.706438 +vt 0.192055 0.720369 +vt 0.197402 0.716478 +vt 0.202896 0.714364 +vt 0.200676 0.703611 +vt 0.162939 0.722778 +vt 0.170984 0.719814 +vt 0.163882 0.735424 +vt 0.172216 0.732054 +vt 0.179859 0.728200 +vt 0.178419 0.716527 +vt 0.127478 0.730000 +vt 0.137329 0.728704 +vt 0.127600 0.742416 +vt 0.137747 0.741306 +vt 0.146755 0.739717 +vt 0.146153 0.726999 +vt 0.090724 0.728798 +vt 0.103506 0.730210 +vt 0.078851 0.726686 +vt 0.077397 0.738139 +vt 0.089565 0.740409 +vt 0.102725 0.742054 +vt 0.007427 0.684883 +vt 0.009897 0.688283 +vt 0.005029 0.681528 +vt 0.003883 0.691172 +vt 0.026829 0.703671 +vt 0.032044 0.707620 +vt 0.021706 0.699323 +vt 0.019702 0.709047 +vt 0.024549 0.713575 +vt 0.029509 0.717580 +vt 0.051362 0.718303 +vt 0.059826 0.721458 +vt 0.043768 0.714888 +vt 0.041432 0.725531 +vt 0.049234 0.729290 +vt 0.057907 0.732681 +vt 0.116038 0.730578 +vt 0.115723 0.742717 +vt 0.204479 0.699077 +vt 0.207371 0.695738 +vt 0.205614 0.704482 +vt 0.207997 0.702538 +vt 0.184959 0.713253 +vt 0.186352 0.724338 +vt 0.154641 0.725102 +vt 0.155388 0.737875 +vt 0.071302 0.709338 +vt 0.068755 0.724238 +vt 0.067054 0.735589 +vt 0.065760 0.744959 +vt 0.064997 0.752033 +vt 0.087819 0.642120 +vt 0.083598 0.658017 +vt 0.078680 0.677141 +vt 0.074553 0.694010 +vt 0.082618 0.591563 +vt 0.082311 0.583976 +vt 0.084812 0.591592 +vt 0.084109 0.584295 +vt 0.083526 0.579824 +vt 0.081987 0.578438 +vt 0.082297 0.573471 +vt 0.082423 0.569353 +vt 0.079727 0.621812 +vt 0.084357 0.621665 +vt 0.085731 0.609504 +vt 0.081679 0.609528 +vt 0.082523 0.599822 +vt 0.085650 0.599784 +vt 0.019955 0.682396 +vt 0.016885 0.694661 +vt 0.016350 0.679327 +vt 0.013356 0.690992 +vt 0.012482 0.698671 +vt 0.015076 0.703624 +vt 0.013604 0.711308 +vt 0.013724 0.718754 +vt 0.037351 0.643137 +vt 0.033772 0.640890 +vt 0.026706 0.653681 +vt 0.030198 0.656416 +vt 0.051197 0.590110 +vt 0.053209 0.590188 +vt 0.053496 0.580977 +vt 0.055221 0.590293 +vt 0.055793 0.581228 +vt 0.053095 0.572466 +vt 0.051283 0.580818 +vt 0.050402 0.572118 +vt 0.052828 0.566025 +vt 0.031952 0.624970 +vt 0.041592 0.616459 +vt 0.044171 0.616877 +vt 0.049557 0.607549 +vt 0.047285 0.607574 +vt 0.039018 0.616029 +vt 0.045018 0.607588 +vt 0.051205 0.598986 +vt 0.053259 0.598929 +vt 0.049153 0.599043 +vt 0.024368 0.669508 +vt 0.020849 0.666623 +vt 0.041147 0.697774 +vt 0.037490 0.711334 +vt 0.034968 0.721574 +vt 0.033140 0.730173 +vt 0.032326 0.736914 +vt 0.051388 0.668727 +vt 0.045672 0.683724 +vt 0.058347 0.652116 +vt 0.069413 0.591722 +vt 0.069560 0.583305 +vt 0.069396 0.576796 +vt 0.061253 0.620598 +vt 0.065870 0.609557 +vt 0.068417 0.600269 +vt 0.069843 0.571954 +vt 0.070864 0.569406 +vt 0.303409 0.637988 +vt 0.310800 0.636837 +vt 0.318892 0.635881 +vt 0.293532 0.634726 +vt 0.297374 0.638293 +vt 0.309030 0.607927 +vt 0.301911 0.605354 +vt 0.262831 0.579033 +vt 0.263231 0.581477 +vt 0.266950 0.581255 +vt 0.266629 0.578587 +vt 0.270020 0.581005 +vt 0.269757 0.578034 +vt 0.274985 0.577046 +vt 0.274983 0.580438 +vt 0.277654 0.580272 +vt 0.277912 0.576913 +vt 0.280281 0.582244 +vt 0.327041 0.635512 +vt 0.334540 0.635448 +vt 0.340566 0.634771 +vt 0.343852 0.630620 +vt 0.323494 0.606817 +vt 0.316269 0.608344 +vt 0.357736 0.573989 +vt 0.361152 0.573691 +vt 0.364898 0.573279 +vt 0.346478 0.578498 +vt 0.348485 0.575745 +vt 0.351240 0.574762 +vt 0.366692 0.762446 +vt 0.399416 0.746656 +vt 0.282634 0.588089 +vt 0.285357 0.595979 +vt 0.291353 0.613606 +vt 0.292295 0.625117 +vt 0.288710 0.604122 +vt 0.272555 0.580769 +vt 0.272396 0.577515 +vt 0.244168 0.747878 +vt 0.250132 0.755280 +vt 0.250190 0.751965 +vt 0.256405 0.584672 +vt 0.259159 0.581972 +vt 0.258455 0.579550 +vt 0.235543 0.666840 +vt 0.240560 0.653479 +vt 0.245847 0.640344 +vt 0.256947 0.600243 +vt 0.256328 0.591326 +vt 0.250355 0.628917 +vt 0.253827 0.618861 +vt 0.256142 0.609451 +vt 0.229321 0.690735 +vt 0.231792 0.679020 +vt 0.228959 0.713046 +vt 0.228098 0.702645 +vt 0.237814 0.725295 +vt 0.232594 0.720250 +vt 0.266181 0.741402 +vt 0.257710 0.737850 +vt 0.249972 0.733745 +vt 0.302864 0.748278 +vt 0.292573 0.747266 +vt 0.283475 0.745736 +vt 0.353821 0.743562 +vt 0.341518 0.745901 +vt 0.328182 0.747648 +vt 0.411818 0.713657 +vt 0.407088 0.718274 +vt 0.402238 0.722306 +vt 0.390216 0.730569 +vt 0.382307 0.734491 +vt 0.373530 0.737996 +vt 0.314957 0.748446 +vt 0.243492 0.729612 +vt 0.274770 0.743915 +vt 0.393022 0.750992 +vt 0.364277 0.740967 +vt 0.344487 0.591552 +vt 0.345411 0.584129 +vt 0.343655 0.620915 +vt 0.342650 0.609406 +vt 0.343189 0.599717 +vt 0.369006 0.573075 +vt 0.372187 0.575248 +vt 0.419488 0.699761 +vt 0.416512 0.707664 +vt 0.416062 0.677833 +vt 0.419078 0.689608 +vt 0.391341 0.627913 +vt 0.398619 0.639713 +vt 0.405643 0.652289 +vt 0.373334 0.581747 +vt 0.374001 0.590455 +vt 0.379527 0.607672 +vt 0.384789 0.617233 +vt 0.375930 0.599006 +vt 0.411516 0.665186 +vt 0.354398 0.574297 +vt 0.396770 0.726427 +vt 0.111645 0.635881 +vt 0.119737 0.636837 +vt 0.127128 0.637988 +vt 0.145400 0.598588 +vt 0.148397 0.596374 +vt 0.150930 0.594090 +vt 0.133163 0.638292 +vt 0.137005 0.634726 +vt 0.153220 0.588748 +vt 0.155443 0.583309 +vt 0.128627 0.605352 +vt 0.121508 0.607927 +vt 0.114268 0.608345 +vt 0.160680 0.578028 +vt 0.160445 0.581001 +vt 0.163579 0.581255 +vt 0.163897 0.578587 +vt 0.167307 0.581477 +vt 0.167707 0.579034 +vt 0.147813 0.767872 +vt 0.180402 0.755277 +vt 0.101170 0.765593 +vt 0.115064 0.769722 +vt 0.095997 0.635449 +vt 0.103496 0.635512 +vt 0.086685 0.630620 +vt 0.089971 0.634771 +vt 0.107044 0.606817 +vt 0.100330 0.603236 +vt 0.065640 0.573281 +vt 0.069387 0.573692 +vt 0.072802 0.573991 +vt 0.079298 0.574764 +vt 0.082053 0.575746 +vt 0.084061 0.578500 +vt 0.054784 0.755904 +vt 0.063835 0.762440 +vt 0.064236 0.759107 +vt 0.087375 0.763955 +vt 0.100948 0.768891 +vt 0.156519 0.765785 +vt 0.138246 0.625109 +vt 0.139209 0.613542 +vt 0.141913 0.604286 +vt 0.157796 0.581109 +vt 0.157817 0.577808 +vt 0.191568 0.746628 +vt 0.171379 0.581973 +vt 0.172083 0.579551 +vt 0.174133 0.584673 +vt 0.201885 0.726340 +vt 0.200954 0.721027 +vt 0.184690 0.640343 +vt 0.189977 0.653478 +vt 0.194994 0.666839 +vt 0.174209 0.591327 +vt 0.173590 0.600243 +vt 0.176710 0.618861 +vt 0.180182 0.628917 +vt 0.174396 0.609451 +vt 0.198741 0.678986 +vt 0.201198 0.690473 +vt 0.202789 0.701403 +vt 0.204803 0.707875 +vt 0.197482 0.721586 +vt 0.192560 0.725444 +vt 0.180562 0.733743 +vt 0.172825 0.737847 +vt 0.164354 0.741399 +vt 0.147060 0.745734 +vt 0.137962 0.747263 +vt 0.127670 0.748276 +vt 0.102353 0.747646 +vt 0.089016 0.745899 +vt 0.076714 0.743561 +vt 0.028304 0.722313 +vt 0.023454 0.718280 +vt 0.018720 0.713658 +vt 0.057003 0.737994 +vt 0.048221 0.734487 +vt 0.040311 0.730565 +vt 0.115578 0.748444 +vt 0.208197 0.706082 +vt 0.187023 0.729629 +vt 0.155765 0.743912 +vt 0.037092 0.748559 +vt 0.045512 0.755420 +vt 0.045689 0.752093 +vt 0.066258 0.740965 +vt 0.085127 0.584130 +vt 0.086051 0.591553 +vt 0.087887 0.609407 +vt 0.086882 0.620916 +vt 0.087349 0.599718 +vt 0.058352 0.575250 +vt 0.061533 0.573077 +vt 0.014024 0.707664 +vt 0.011048 0.699761 +vt 0.011458 0.689608 +vt 0.014474 0.677833 +vt 0.024894 0.652290 +vt 0.031918 0.639714 +vt 0.039196 0.627914 +vt 0.056537 0.590456 +vt 0.057205 0.581749 +vt 0.045749 0.617234 +vt 0.051010 0.607674 +vt 0.054608 0.599008 +vt 0.019021 0.665186 +vt 0.076141 0.574299 +vt 0.033765 0.726428 +vt 0.033926 0.749330 +vt 0.038928 0.752420 +vt 0.184545 0.576114 +vt 0.181591 0.576004 +vt 0.177516 0.575762 +vt 0.168313 0.574880 +vt 0.164415 0.573898 +vt 0.161076 0.572624 +vt 0.154959 0.571063 +vt 0.151782 0.571218 +vt 0.148623 0.571691 +vt 0.145700 0.572042 +vt 0.144173 0.566977 +vt 0.172871 0.575379 +vt 0.158016 0.571499 +vt 0.247945 0.582927 +vt 0.248947 0.576003 +vt 0.253022 0.575761 +vt 0.245993 0.576113 +vt 0.266113 0.573898 +vt 0.262225 0.574879 +vt 0.269386 0.572629 +vt 0.278418 0.570596 +vt 0.275205 0.570664 +vt 0.281736 0.571198 +vt 0.284745 0.571871 +vt 0.286985 0.572381 +vt 0.288697 0.568215 +vt 0.257667 0.575378 +vt 0.272291 0.571438 +vt 0.275453 0.560292 +vt 0.272032 0.561564 +vt 0.268703 0.563860 +vt 0.261234 0.568141 +vt 0.256567 0.568922 +vt 0.251648 0.569058 +vt 0.289062 0.565503 +vt 0.286745 0.564211 +vt 0.283019 0.562263 +vt 0.265698 0.759588 +vt 0.274173 0.762411 +vt 0.282865 0.764452 +vt 0.238887 0.743340 +vt 0.221232 0.716350 +vt 0.224057 0.722698 +vt 0.228627 0.730877 +vt 0.302605 0.766468 +vt 0.315390 0.766424 +vt 0.329364 0.765596 +vt 0.422877 0.671008 +vt 0.418491 0.658856 +vt 0.412656 0.646361 +vt 0.340203 0.591478 +vt 0.342207 0.567936 +vt 0.342049 0.571803 +vt 0.342046 0.578070 +vt 0.341715 0.584767 +vt 0.405839 0.635004 +vt 0.426089 0.707286 +vt 0.426700 0.700563 +vt 0.426653 0.691172 +vt 0.292011 0.765802 +vt 0.279138 0.560686 +vt 0.257514 0.755975 +vt 0.265214 0.566297 +vt 0.233700 0.737822 +vt 0.244137 0.569584 +vt 0.247210 0.569081 +vt 0.244569 0.569082 +vt 0.425507 0.681527 +vt 0.380561 0.561816 +vt 0.208963 0.683324 +vt 0.206438 0.673290 +vt 0.202703 0.662274 +vt 0.141298 0.594312 +vt 0.143434 0.564679 +vt 0.146936 0.562237 +vt 0.143241 0.564049 +vt 0.140568 0.565350 +vt 0.140750 0.565873 +vt 0.141633 0.567843 +vt 0.144848 0.578710 +vt 0.144213 0.586481 +vt 0.197813 0.650224 +vt 0.203919 0.723029 +vt 0.207654 0.716644 +vt 0.208037 0.709865 +vt 0.202233 0.732492 +vt 0.207060 0.723026 +vt 0.209901 0.716516 +vt 0.210995 0.710430 +vt 0.211869 0.701520 +vt 0.079960 0.565133 +vt 0.077375 0.565479 +vt 0.074722 0.566184 +vt 0.068166 0.566808 +vt 0.063214 0.565541 +vt 0.057708 0.563620 +vt 0.088331 0.567938 +vt 0.087063 0.566688 +vt 0.084917 0.565919 +vt 0.018125 0.731327 +vt 0.022321 0.735714 +vt 0.026639 0.739619 +vt 0.004447 0.707286 +vt 0.006457 0.712851 +vt 0.009862 0.719748 +vt 0.074844 0.761730 +vt 0.151066 0.560789 +vt 0.185969 0.569083 +vt 0.210213 0.698507 +vt 0.210258 0.692360 +vt 0.082492 0.565355 +vt 0.013892 0.726018 +vt 0.049723 0.565280 +vt 0.052772 0.562007 +vt 0.049977 0.561819 +vt 0.031335 0.743585 +vt 0.071855 0.566857 +vt 0.412977 0.735081 +vt 0.413082 0.735170 +vt 0.417130 0.730002 +vt 0.417018 0.729923 +vt 0.880489 0.287946 +vt 0.880285 0.287958 +vt 0.880339 0.292960 +vt 0.880542 0.292947 +vt 0.988553 0.660500 +vt 0.988349 0.660486 +vt 0.988334 0.665677 +vt 0.988537 0.665690 +vt 0.421091 0.723729 +vt 0.420970 0.723663 +vt 0.302534 0.770550 +vt 0.302529 0.770687 +vt 0.315492 0.770604 +vt 0.315489 0.770466 +vt 0.880242 0.172546 +vt 0.880038 0.172542 +vt 0.880020 0.185257 +vt 0.880224 0.185260 +vt 0.880009 0.199296 +vt 0.880212 0.199298 +vt 0.329654 0.769771 +vt 0.329642 0.769634 +vt 0.400427 0.624077 +vt 0.400539 0.623994 +vt 0.393376 0.615415 +vt 0.393262 0.615495 +vt 0.988522 0.767478 +vt 0.988319 0.767485 +vt 0.988333 0.777486 +vt 0.988536 0.777479 +vt 0.988344 0.786831 +vt 0.988547 0.786826 +vt 0.387259 0.607260 +vt 0.387138 0.607327 +vt 0.268384 0.563147 +vt 0.268317 0.563024 +vt 0.264851 0.565468 +vt 0.264914 0.565594 +vt 0.099208 0.099352 +vt 0.099005 0.099359 +vt 0.099011 0.103091 +vt 0.099215 0.103085 +vt 0.099016 0.107161 +vt 0.099219 0.107157 +vt 0.260968 0.567283 +vt 0.261013 0.567417 +vt 0.236261 0.637656 +vt 0.236136 0.637597 +vt 0.230581 0.649310 +vt 0.230707 0.649366 +vt 0.211934 0.349079 +vt 0.212137 0.349089 +vt 0.212089 0.337640 +vt 0.211885 0.337631 +vt 0.212047 0.326050 +vt 0.211844 0.326042 +vt 0.225704 0.661133 +vt 0.225833 0.661181 +vt 0.302137 0.604623 +vt 0.302201 0.604501 +vt 0.295738 0.600037 +vt 0.295642 0.600135 +vt 0.816020 0.037235 +vt 0.816223 0.037246 +vt 0.816237 0.031370 +vt 0.816034 0.031355 +vt 0.586975 0.123064 +vt 0.587179 0.123053 +vt 0.587165 0.115747 +vt 0.586961 0.115752 +vt 0.290626 0.593735 +vt 0.290506 0.593801 +vt 0.249979 0.755981 +vt 0.249904 0.756096 +vt 0.257195 0.760111 +vt 0.257258 0.759989 +vt 0.880486 0.123926 +vt 0.880283 0.123913 +vt 0.880226 0.130251 +vt 0.880430 0.130263 +vt 0.880172 0.137531 +vt 0.880376 0.137542 +vt 0.265373 0.763757 +vt 0.265423 0.763629 +vt 0.251443 0.568317 +vt 0.251402 0.568179 +vt 0.246567 0.568221 +vt 0.246664 0.568359 +vt 0.099220 0.116758 +vt 0.099016 0.116761 +vt 0.099015 0.121574 +vt 0.099219 0.121562 +vt 0.099015 0.125110 +vt 0.099218 0.125090 +vt 0.243028 0.568351 +vt 0.243187 0.568487 +vt 0.097240 0.099359 +vt 0.097037 0.099352 +vt 0.097043 0.103085 +vt 0.097246 0.103091 +vt 0.162221 0.563025 +vt 0.162154 0.563148 +vt 0.165624 0.565595 +vt 0.165687 0.565469 +vt 0.169525 0.567417 +vt 0.169570 0.567283 +vt 0.097047 0.107157 +vt 0.097251 0.107161 +vt 0.345429 0.563318 +vt 0.345386 0.563185 +vt 0.342934 0.564022 +vt 0.343021 0.564142 +vt 0.360298 0.023206 +vt 0.360502 0.023202 +vt 0.360500 0.020661 +vt 0.360296 0.020671 +vt 0.948846 0.898552 +vt 0.948643 0.898534 +vt 0.948655 0.900914 +vt 0.948858 0.900929 +vt 0.341203 0.566481 +vt 0.341329 0.566578 +vt 0.282648 0.768629 +vt 0.282622 0.768763 +vt 0.291829 0.770086 +vt 0.291845 0.769950 +vt 0.880293 0.153434 +vt 0.880089 0.153426 +vt 0.880060 0.162180 +vt 0.880264 0.162186 +vt 0.275350 0.559456 +vt 0.275330 0.559311 +vt 0.271740 0.560650 +vt 0.271790 0.560784 +vt 0.099199 0.091946 +vt 0.098996 0.091947 +vt 0.098999 0.095675 +vt 0.099202 0.095671 +vt 0.361842 0.565041 +vt 0.361841 0.564898 +vt 0.358304 0.564887 +vt 0.358282 0.565026 +vt 0.360288 0.039332 +vt 0.360491 0.039334 +vt 0.360492 0.035829 +vt 0.360289 0.035823 +vt 0.360496 0.033267 +vt 0.360292 0.033260 +vt 0.355619 0.564034 +vt 0.355584 0.564169 +vt 0.340807 0.578244 +vt 0.340668 0.578213 +vt 0.340371 0.584802 +vt 0.340506 0.584836 +vt 0.948841 0.912625 +vt 0.948638 0.912619 +vt 0.948628 0.919188 +vt 0.948831 0.919195 +vt 0.948631 0.925489 +vt 0.948835 0.925498 +vt 0.338775 0.591185 +vt 0.338900 0.591241 +vt 0.246127 0.583058 +vt 0.245984 0.583063 +vt 0.248223 0.591569 +vt 0.248362 0.591552 +vt 0.212007 0.403109 +vt 0.212210 0.403110 +vt 0.212235 0.394509 +vt 0.212031 0.394510 +vt 0.212250 0.385563 +vt 0.212047 0.385562 +vt 0.249529 0.600466 +vt 0.249667 0.600466 +vt 0.404741 0.743184 +vt 0.404831 0.743287 +vt 0.409110 0.739393 +vt 0.409013 0.739296 +vt 0.880407 0.278238 +vt 0.880204 0.278248 +vt 0.880242 0.283220 +vt 0.880446 0.283209 +vt 0.256391 0.568046 +vt 0.256419 0.568184 +vt 0.099017 0.111792 +vt 0.099220 0.111791 +vt 0.340649 0.571617 +vt 0.340789 0.571676 +vt 0.948650 0.906025 +vt 0.948853 0.906035 +vt 0.335136 0.597309 +vt 0.335243 0.597394 +vt 0.948655 0.931437 +vt 0.948858 0.931450 +vt 0.816034 0.070786 +vt 0.816237 0.070772 +vt 0.816224 0.064830 +vt 0.816020 0.064840 +vt 0.329765 0.602445 +vt 0.329847 0.602556 +vt 0.376269 0.759961 +vt 0.376319 0.760088 +vt 0.385304 0.756140 +vt 0.385242 0.756017 +vt 0.880256 0.246946 +vt 0.880052 0.246949 +vt 0.880084 0.256542 +vt 0.880288 0.256537 +vt 0.880123 0.265258 +vt 0.880326 0.265251 +vt 0.393310 0.751788 +vt 0.393237 0.751672 +vt 0.242409 0.571156 +vt 0.242230 0.571054 +vt 0.243808 0.575934 +vt 0.243968 0.575979 +vt 0.211968 0.415277 +vt 0.212171 0.415293 +vt 0.212187 0.410338 +vt 0.211984 0.410331 +vt 0.986554 0.767485 +vt 0.986351 0.767478 +vt 0.986364 0.777478 +vt 0.986568 0.777486 +vt 0.029998 0.623995 +vt 0.030110 0.624078 +vt 0.037275 0.615496 +vt 0.037161 0.615417 +vt 0.043400 0.607328 +vt 0.043278 0.607261 +vt 0.986376 0.786826 +vt 0.986579 0.786831 +vt 0.878273 0.172543 +vt 0.878070 0.172548 +vt 0.878052 0.185262 +vt 0.878255 0.185259 +vt 0.128005 0.770684 +vt 0.128000 0.770547 +vt 0.115046 0.770464 +vt 0.115042 0.770601 +vt 0.100893 0.769632 +vt 0.100880 0.769768 +vt 0.878041 0.199300 +vt 0.878244 0.199298 +vt 0.217669 0.699540 +vt 0.217531 0.699542 +vt 0.218044 0.707773 +vt 0.218180 0.707754 +vt 0.211780 0.288045 +vt 0.211983 0.288045 +vt 0.211991 0.279796 +vt 0.211788 0.279798 +vt 0.212012 0.271154 +vt 0.211809 0.271158 +vt 0.219960 0.716335 +vt 0.220093 0.716297 +vt 0.356168 0.765810 +vt 0.356198 0.765944 +vt 0.366869 0.763311 +vt 0.366828 0.763180 +vt 0.880218 0.226064 +vt 0.880014 0.226065 +vt 0.880029 0.237045 +vt 0.880232 0.237043 +vt 0.219532 0.681868 +vt 0.219397 0.681842 +vt 0.217969 0.690978 +vt 0.218106 0.690991 +vt 0.211791 0.305642 +vt 0.211995 0.305647 +vt 0.211984 0.296583 +vt 0.211781 0.296580 +vt 0.343580 0.768153 +vt 0.343559 0.768017 +vt 0.880007 0.213262 +vt 0.880211 0.213262 +vt 0.097251 0.116762 +vt 0.097048 0.116758 +vt 0.097047 0.121563 +vt 0.097250 0.121574 +vt 0.179135 0.568180 +vt 0.179096 0.568318 +vt 0.183875 0.568360 +vt 0.183971 0.568222 +vt 0.187352 0.568488 +vt 0.187510 0.568352 +vt 0.097046 0.125091 +vt 0.097250 0.125111 +vt 0.380895 0.589994 +vt 0.381032 0.589974 +vt 0.381044 0.580719 +vt 0.380905 0.580723 +vt 0.988552 0.805083 +vt 0.988349 0.805081 +vt 0.988342 0.814081 +vt 0.988545 0.814085 +vt 0.988333 0.822506 +vt 0.988536 0.822507 +vt 0.382130 0.571806 +vt 0.381986 0.571832 +vt 0.878039 0.213264 +vt 0.878242 0.213263 +vt 0.086975 0.768015 +vt 0.086954 0.768151 +vt 0.074367 0.765808 +vt 0.074336 0.765942 +vt 0.878046 0.226066 +vt 0.878249 0.226066 +vt 0.878518 0.123914 +vt 0.878315 0.123928 +vt 0.878258 0.130265 +vt 0.878461 0.130252 +vt 0.180630 0.756093 +vt 0.180556 0.755978 +vt 0.173277 0.759986 +vt 0.173339 0.760108 +vt 0.165111 0.763626 +vt 0.165162 0.763753 +vt 0.878204 0.137544 +vt 0.878407 0.137533 +vt 0.213902 0.349090 +vt 0.214105 0.349081 +vt 0.214057 0.337633 +vt 0.213853 0.337641 +vt 0.194401 0.637596 +vt 0.194276 0.637655 +vt 0.199829 0.649365 +vt 0.199956 0.649309 +vt 0.204703 0.661180 +vt 0.204832 0.661132 +vt 0.214015 0.326044 +vt 0.213812 0.326051 +vt 0.414494 0.644937 +vt 0.414615 0.644871 +vt 0.407808 0.633703 +vt 0.407693 0.633780 +vt 0.988498 0.743916 +vt 0.988295 0.743921 +vt 0.988306 0.756360 +vt 0.988509 0.756353 +vt 0.223613 0.725611 +vt 0.223739 0.725555 +vt 0.212050 0.261718 +vt 0.211846 0.261725 +vt 0.212097 0.252659 +vt 0.211894 0.252668 +vt 0.228374 0.734459 +vt 0.228491 0.734386 +vt 0.246443 0.617727 +vt 0.246311 0.617684 +vt 0.241723 0.627073 +vt 0.241851 0.627129 +vt 0.212022 0.368509 +vt 0.212226 0.368516 +vt 0.212186 0.359347 +vt 0.211982 0.359338 +vt 0.424618 0.716329 +vt 0.424490 0.716280 +vt 0.988319 0.672066 +vt 0.988522 0.672077 +vt 0.988305 0.679692 +vt 0.988509 0.679700 +vt 0.427199 0.707882 +vt 0.427065 0.707851 +vt 0.372594 0.561426 +vt 0.372589 0.561279 +vt 0.366793 0.563508 +vt 0.366813 0.563649 +vt 0.360295 0.050433 +vt 0.360498 0.050435 +vt 0.360494 0.044413 +vt 0.360290 0.044413 +vt 0.290611 0.568502 +vt 0.290769 0.568435 +vt 0.291529 0.566552 +vt 0.291369 0.566634 +vt 0.586964 0.091167 +vt 0.587168 0.091163 +vt 0.587170 0.089505 +vt 0.586967 0.089511 +vt 0.587167 0.088105 +vt 0.586963 0.088113 +vt 0.290449 0.565372 +vt 0.290304 0.565464 +vt 0.428419 0.698597 +vt 0.428282 0.698586 +vt 0.988295 0.688447 +vt 0.988499 0.688453 +vt 0.988288 0.697686 +vt 0.988492 0.697690 +vt 0.428428 0.689102 +vt 0.428290 0.689108 +vt 0.213777 0.271155 +vt 0.213979 0.271117 +vt 0.214017 0.261995 +vt 0.213814 0.261719 +vt 0.210476 0.716370 +vt 0.206936 0.725340 +vt 0.202184 0.734265 +vt 0.214066 0.252862 +vt 0.213862 0.252660 +vt 0.383019 0.564269 +vt 0.382869 0.564368 +vt 0.988325 0.829644 +vt 0.988528 0.829635 +vt 0.988324 0.834272 +vt 0.988527 0.834254 +vt 0.382094 0.559742 +vt 0.381964 0.559906 +vt 0.362266 0.023202 +vt 0.362470 0.023205 +vt 0.362468 0.020671 +vt 0.362265 0.020661 +vt 0.085152 0.563187 +vt 0.085110 0.563320 +vt 0.087517 0.564144 +vt 0.087604 0.564024 +vt 0.089209 0.566579 +vt 0.089335 0.566482 +vt 0.946878 0.898530 +vt 0.946674 0.898547 +vt 0.946686 0.900924 +vt 0.946890 0.900910 +vt 0.986568 0.822506 +vt 0.986364 0.822507 +vt 0.986356 0.829635 +vt 0.986560 0.829644 +vt 0.048408 0.571808 +vt 0.048552 0.571834 +vt 0.047669 0.564370 +vt 0.047519 0.564271 +vt 0.048574 0.559909 +vt 0.048444 0.559744 +vt 0.986356 0.834254 +vt 0.986559 0.834272 +vt 0.946873 0.912615 +vt 0.946669 0.912620 +vt 0.946660 0.919190 +vt 0.946863 0.919184 +vt 0.089870 0.578214 +vt 0.089731 0.578246 +vt 0.090032 0.584837 +vt 0.090167 0.584804 +vt 0.091638 0.591243 +vt 0.091763 0.591186 +vt 0.946663 0.925493 +vt 0.946867 0.925485 +vt 0.316191 0.607478 +vt 0.316180 0.607342 +vt 0.309103 0.606923 +vt 0.309076 0.607058 +vt 0.816008 0.050769 +vt 0.816212 0.050770 +vt 0.816215 0.043801 +vt 0.816011 0.043795 +vt 0.986541 0.679691 +vt 0.986337 0.679700 +vt 0.986327 0.688453 +vt 0.986530 0.688446 +vt 0.003336 0.707881 +vt 0.003471 0.707851 +vt 0.002254 0.698586 +vt 0.002117 0.698597 +vt 0.002246 0.689109 +vt 0.002108 0.689102 +vt 0.986320 0.697690 +vt 0.986524 0.697686 +vt 0.383063 0.598847 +vt 0.382933 0.598892 +vt 0.988349 0.795982 +vt 0.988553 0.795980 +vt 0.350514 0.562711 +vt 0.350525 0.562571 +vt 0.347960 0.562683 +vt 0.347971 0.562822 +vt 0.360298 0.028379 +vt 0.360502 0.028383 +vt 0.360502 0.025820 +vt 0.360299 0.025820 +vt 0.986584 0.805081 +vt 0.986380 0.805083 +vt 0.986374 0.814085 +vt 0.986577 0.814081 +vt 0.049505 0.589975 +vt 0.049643 0.589995 +vt 0.049633 0.580725 +vt 0.049493 0.580721 +vt 0.817988 0.037246 +vt 0.818191 0.037234 +vt 0.818206 0.031355 +vt 0.818002 0.031370 +vt 0.128337 0.604501 +vt 0.128400 0.604623 +vt 0.134896 0.600135 +vt 0.134800 0.600037 +vt 0.140032 0.593802 +vt 0.139912 0.593736 +vt 0.588944 0.123052 +vt 0.589147 0.123062 +vt 0.589133 0.115751 +vt 0.588929 0.115746 +vt 0.214015 0.385564 +vt 0.214218 0.385564 +vt 0.214216 0.377034 +vt 0.214012 0.377038 +vt 0.181008 0.600466 +vt 0.180870 0.600466 +vt 0.181437 0.609053 +vt 0.181573 0.609030 +vt 0.184095 0.617727 +vt 0.184226 0.617683 +vt 0.214194 0.368511 +vt 0.213990 0.368518 +vt 0.214117 0.245256 +vt 0.213913 0.245212 +vt 0.196915 0.741474 +vt 0.197048 0.741644 +vt 0.191761 0.747274 +vt 0.191860 0.747368 +vt 0.214167 0.239301 +vt 0.213964 0.239288 +vt 0.353076 0.563107 +vt 0.353047 0.563244 +vt 0.360499 0.030853 +vt 0.360296 0.030847 +vt 0.287413 0.563548 +vt 0.287307 0.563656 +vt 0.099220 0.077667 +vt 0.099017 0.077645 +vt 0.099011 0.080445 +vt 0.099214 0.080462 +vt 0.099004 0.084241 +vt 0.099207 0.084252 +vt 0.283337 0.561414 +vt 0.283280 0.561541 +vt 0.140493 0.565099 +vt 0.140520 0.565178 +vt 0.143055 0.563817 +vt 0.142966 0.563660 +vt 0.145650 0.562363 +vt 0.145432 0.562200 +vt 0.323244 0.605841 +vt 0.323292 0.605970 +vt 0.816215 0.057956 +vt 0.816011 0.057960 +vt 0.362265 0.060073 +vt 0.362468 0.060052 +vt 0.362470 0.056262 +vt 0.362267 0.056274 +vt 0.052376 0.559483 +vt 0.052314 0.559314 +vt 0.057944 0.561428 +vt 0.057950 0.561281 +vt 0.362467 0.050433 +vt 0.362263 0.050435 +vt 0.589125 0.107647 +vt 0.588922 0.107648 +vt 0.142919 0.586123 +vt 0.142786 0.586090 +vt 0.143416 0.578511 +vt 0.143278 0.578509 +vt 0.589125 0.100157 +vt 0.588921 0.100162 +vt 0.986316 0.707024 +vt 0.986520 0.707022 +vt 0.003297 0.679782 +vt 0.003161 0.679759 +vt 0.005822 0.669507 +vt 0.005689 0.669469 +vt 0.986316 0.717620 +vt 0.986519 0.717621 +vt 0.213984 0.315382 +vt 0.213780 0.315388 +vt 0.208448 0.672012 +vt 0.208580 0.671975 +vt 0.211003 0.681860 +vt 0.211139 0.681839 +vt 0.213963 0.305644 +vt 0.213759 0.305648 +vt 0.588933 0.091162 +vt 0.589136 0.091153 +vt 0.589139 0.089627 +vt 0.588939 0.089635 +vt 0.139765 0.568422 +vt 0.139899 0.568388 +vt 0.138971 0.566603 +vt 0.138842 0.566635 +vt 0.138860 0.566174 +vt 0.138785 0.566142 +vt 0.589140 0.089161 +vt 0.588962 0.089156 +vt 0.287751 0.586090 +vt 0.287618 0.586125 +vt 0.587157 0.107649 +vt 0.586953 0.107649 +vt 0.587156 0.100163 +vt 0.586953 0.100161 +vt 0.287259 0.578511 +vt 0.287117 0.578533 +vt 0.378224 0.559311 +vt 0.378163 0.559480 +vt 0.360296 0.060052 +vt 0.360500 0.060073 +vt 0.360502 0.056274 +vt 0.360299 0.056263 +vt 0.946686 0.931445 +vt 0.946890 0.931433 +vt 0.095294 0.597395 +vt 0.095402 0.597310 +vt 0.100691 0.602557 +vt 0.100772 0.602445 +vt 0.818002 0.070772 +vt 0.818206 0.070786 +vt 0.818192 0.064840 +vt 0.817988 0.064830 +vt 0.248965 0.609031 +vt 0.249101 0.609053 +vt 0.212248 0.377037 +vt 0.212044 0.377032 +vt 0.233490 0.741679 +vt 0.233596 0.741592 +vt 0.212148 0.245211 +vt 0.211945 0.245223 +vt 0.212199 0.239287 +vt 0.211996 0.239300 +vt 0.238674 0.747371 +vt 0.238770 0.747273 +vt 0.424715 0.669506 +vt 0.424848 0.669468 +vt 0.420473 0.657350 +vt 0.420346 0.657402 +vt 0.988488 0.717620 +vt 0.988284 0.717621 +vt 0.988288 0.730424 +vt 0.988491 0.730421 +vt 0.097210 0.085454 +vt 0.097031 0.085585 +vt 0.097029 0.088308 +vt 0.097229 0.088288 +vt 0.148634 0.560670 +vt 0.149189 0.560567 +vt 0.151522 0.559780 +vt 0.151502 0.559642 +vt 0.155164 0.559467 +vt 0.155205 0.559314 +vt 0.097027 0.091944 +vt 0.097231 0.091947 +vt 0.818183 0.057960 +vt 0.817980 0.057955 +vt 0.107245 0.605970 +vt 0.107294 0.605842 +vt 0.114347 0.607479 +vt 0.114357 0.607343 +vt 0.818180 0.050769 +vt 0.817977 0.050770 +vt 0.362261 0.033267 +vt 0.362464 0.033260 +vt 0.362468 0.030847 +vt 0.362264 0.030853 +vt 0.074919 0.564036 +vt 0.074955 0.564171 +vt 0.077491 0.563246 +vt 0.077463 0.563109 +vt 0.080024 0.562713 +vt 0.080013 0.562572 +vt 0.362470 0.028379 +vt 0.362267 0.028383 +vt 0.986381 0.795980 +vt 0.986585 0.795982 +vt 0.047605 0.598893 +vt 0.047475 0.598848 +vt 0.214218 0.234449 +vt 0.214015 0.234434 +vt 0.186525 0.751879 +vt 0.186610 0.751986 +vt 0.878574 0.118878 +vt 0.878371 0.118893 +vt 0.362256 0.039334 +vt 0.362459 0.039332 +vt 0.362461 0.035823 +vt 0.362257 0.035829 +vt 0.068697 0.564900 +vt 0.068697 0.565043 +vt 0.072257 0.565028 +vt 0.072234 0.564889 +vt 0.221955 0.671977 +vt 0.222088 0.672015 +vt 0.212015 0.315387 +vt 0.211812 0.315380 +vt 0.213748 0.288047 +vt 0.213953 0.287831 +vt 0.213961 0.279495 +vt 0.213756 0.279798 +vt 0.212905 0.699750 +vt 0.212330 0.708068 +vt 0.213953 0.296546 +vt 0.213749 0.296584 +vt 0.212332 0.691116 +vt 0.212550 0.691011 +vt 0.032748 0.748948 +vt 0.030401 0.746295 +vt 0.029935 0.746689 +vt 0.026066 0.742608 +vt 0.025682 0.743110 +vt 0.878158 0.145293 +vt 0.878361 0.145283 +vt 0.156617 0.766527 +vt 0.156656 0.766658 +vt 0.147886 0.768625 +vt 0.147912 0.768760 +vt 0.878121 0.153435 +vt 0.878324 0.153428 +vt 0.986569 0.665677 +vt 0.986366 0.665690 +vt 0.986350 0.672077 +vt 0.986554 0.672065 +vt 0.009445 0.723728 +vt 0.009565 0.723663 +vt 0.006046 0.716279 +vt 0.005917 0.716328 +vt 0.878061 0.237045 +vt 0.878264 0.237047 +vt 0.063703 0.763177 +vt 0.063665 0.763309 +vt 0.054245 0.759948 +vt 0.054212 0.760085 +vt 0.878084 0.246950 +vt 0.878287 0.246951 +vt 0.878113 0.256309 +vt 0.878314 0.256552 +vt 0.045639 0.756245 +vt 0.045435 0.756288 +vt 0.040443 0.753719 +vt 0.038923 0.753032 +vt 0.878124 0.263339 +vt 0.878302 0.265736 +vt 0.213975 0.403111 +vt 0.214179 0.403111 +vt 0.214203 0.394512 +vt 0.213999 0.394510 +vt 0.184554 0.583063 +vt 0.184411 0.583058 +vt 0.182176 0.591552 +vt 0.182314 0.591569 +vt 0.427375 0.679759 +vt 0.427239 0.679782 +vt 0.988285 0.707022 +vt 0.988488 0.707024 +vt 0.399729 0.747429 +vt 0.399647 0.747319 +vt 0.880164 0.272420 +vt 0.880367 0.272411 +vt 0.213936 0.415295 +vt 0.214139 0.415279 +vt 0.214156 0.410332 +vt 0.213952 0.410340 +vt 0.188308 0.571055 +vt 0.188129 0.571157 +vt 0.186570 0.575980 +vt 0.186730 0.575934 +vt 0.946682 0.906030 +vt 0.946885 0.906021 +vt 0.089750 0.571678 +vt 0.089889 0.571618 +vt 0.362462 0.044413 +vt 0.362259 0.044413 +vt 0.063726 0.563651 +vt 0.063746 0.563510 +vt 0.279215 0.559734 +vt 0.279200 0.559876 +vt 0.098998 0.088137 +vt 0.099201 0.088141 +vt 0.273878 0.766661 +vt 0.273917 0.766530 +vt 0.880126 0.145282 +vt 0.880330 0.145291 +vt 0.362470 0.025820 +vt 0.362267 0.025820 +vt 0.082568 0.562824 +vt 0.082579 0.562685 +vt 0.986319 0.730421 +vt 0.986523 0.730424 +vt 0.010191 0.657403 +vt 0.010063 0.657351 +vt 0.016043 0.644938 +vt 0.015921 0.644872 +vt 0.986327 0.743915 +vt 0.986530 0.743921 +vt 0.097049 0.111791 +vt 0.097252 0.111793 +vt 0.174119 0.568185 +vt 0.174147 0.568047 +vt 0.243924 0.751989 +vt 0.244009 0.751881 +vt 0.212250 0.234433 +vt 0.212047 0.234447 +vt 0.880542 0.118891 +vt 0.880339 0.118877 +vt 0.818183 0.043795 +vt 0.817979 0.043801 +vt 0.121462 0.607058 +vt 0.121435 0.606924 +vt 0.214154 0.359340 +vt 0.213951 0.359349 +vt 0.188686 0.627128 +vt 0.188813 0.627072 +vt 0.097031 0.095671 +vt 0.097234 0.095676 +vt 0.158746 0.560786 +vt 0.158798 0.560651 +vt 0.986338 0.756353 +vt 0.986541 0.756360 +vt 0.022844 0.633781 +vt 0.022729 0.633704 +vt 0.878093 0.162188 +vt 0.878296 0.162182 +vt 0.138690 0.769947 +vt 0.138705 0.770083 +vt 0.878439 0.278296 +vt 0.878237 0.278367 +vt 0.878275 0.283221 +vt 0.878478 0.283228 +vt 0.025592 0.743198 +vt 0.021552 0.739327 +vt 0.021416 0.739386 +vt 0.017576 0.735097 +vt 0.017455 0.735171 +vt 0.878317 0.287945 +vt 0.878520 0.287959 +vt 0.213603 0.368517 +vt 0.213625 0.377038 +vt 0.213108 0.368517 +vt 0.213130 0.377037 +vt 0.213132 0.385564 +vt 0.213628 0.385564 +vt 0.212613 0.368516 +vt 0.212635 0.377037 +vt 0.212637 0.385563 +vt 0.213577 0.239288 +vt 0.213526 0.245212 +vt 0.213081 0.239287 +vt 0.213031 0.245212 +vt 0.212980 0.252660 +vt 0.213475 0.252660 +vt 0.212586 0.239287 +vt 0.212535 0.245211 +vt 0.212485 0.252659 +vt 0.947277 0.900911 +vt 0.947265 0.898530 +vt 0.947772 0.900912 +vt 0.947760 0.898532 +vt 0.361878 0.020661 +vt 0.361382 0.020661 +vt 0.361384 0.023202 +vt 0.361879 0.023202 +vt 0.948267 0.900913 +vt 0.948256 0.898533 +vt 0.360887 0.020661 +vt 0.360889 0.023202 +vt 0.986955 0.822506 +vt 0.986964 0.814081 +vt 0.987450 0.822506 +vt 0.987460 0.814081 +vt 0.987466 0.805081 +vt 0.986971 0.805081 +vt 0.987945 0.822506 +vt 0.987955 0.814081 +vt 0.987962 0.805081 +vt 0.145300 0.562173 +vt 0.142940 0.563594 +vt 0.097224 0.082456 +vt 0.097355 0.082009 +vt 0.097338 0.080279 +vt 0.097175 0.080284 +vt 0.097363 0.078549 +vt 0.097233 0.078111 +vt 0.097095 0.080317 +vt 0.097120 0.078035 +vt 0.098026 0.084190 +vt 0.098609 0.084237 +vt 0.098621 0.080435 +vt 0.098121 0.080378 +vt 0.098623 0.077609 +vt 0.098040 0.077325 +vt 0.588542 0.115746 +vt 0.588557 0.123052 +vt 0.588047 0.115746 +vt 0.588061 0.123053 +vt 0.817615 0.031370 +vt 0.817120 0.031370 +vt 0.817105 0.037246 +vt 0.817601 0.037246 +vt 0.587552 0.115746 +vt 0.587566 0.123053 +vt 0.816624 0.031370 +vt 0.816610 0.037246 +vt 0.361876 0.050435 +vt 0.361880 0.056274 +vt 0.361381 0.050435 +vt 0.361385 0.056274 +vt 0.361382 0.060073 +vt 0.361877 0.060073 +vt 0.360885 0.050435 +vt 0.360889 0.056274 +vt 0.360887 0.060073 +vt 0.588534 0.100162 +vt 0.588535 0.107648 +vt 0.588039 0.100162 +vt 0.588039 0.107648 +vt 0.587543 0.100162 +vt 0.587544 0.107648 +vt 0.986906 0.717621 +vt 0.986907 0.707022 +vt 0.987402 0.717621 +vt 0.987402 0.707022 +vt 0.987406 0.697686 +vt 0.986911 0.697686 +vt 0.987897 0.717621 +vt 0.987898 0.707022 +vt 0.987901 0.697686 +vt 0.986946 0.834272 +vt 0.986947 0.829644 +vt 0.987441 0.834272 +vt 0.987442 0.829644 +vt 0.987937 0.834272 +vt 0.987937 0.829644 +vt 0.213372 0.305648 +vt 0.213393 0.315388 +vt 0.212877 0.305647 +vt 0.212898 0.315387 +vt 0.212929 0.326050 +vt 0.213424 0.326051 +vt 0.212382 0.305647 +vt 0.212402 0.315387 +vt 0.212434 0.326050 +vt 0.986918 0.688446 +vt 0.987413 0.688446 +vt 0.987423 0.679691 +vt 0.986928 0.679691 +vt 0.987908 0.688446 +vt 0.987918 0.679691 +vt 0.588545 0.091163 +vt 0.588539 0.094597 +vt 0.588926 0.094597 +vt 0.588050 0.091163 +vt 0.588044 0.094597 +vt 0.587555 0.091163 +vt 0.587548 0.094597 +vt 0.587161 0.094598 +vt 0.361874 0.033267 +vt 0.361870 0.035829 +vt 0.361378 0.033267 +vt 0.361375 0.035829 +vt 0.361374 0.039334 +vt 0.361869 0.039334 +vt 0.360883 0.033267 +vt 0.360880 0.035829 +vt 0.360878 0.039334 +vt 0.986941 0.672065 +vt 0.987436 0.672066 +vt 0.987451 0.665677 +vt 0.986956 0.665677 +vt 0.987932 0.672066 +vt 0.987947 0.665677 +vt 0.213466 0.337641 +vt 0.212971 0.337641 +vt 0.213019 0.349089 +vt 0.213514 0.349090 +vt 0.212476 0.337640 +vt 0.212524 0.349089 +vt 0.213427 0.261719 +vt 0.212932 0.261718 +vt 0.212894 0.271154 +vt 0.213390 0.271155 +vt 0.212437 0.261718 +vt 0.212399 0.271154 +vt 0.986966 0.786831 +vt 0.986955 0.777486 +vt 0.987461 0.786831 +vt 0.987450 0.777486 +vt 0.987437 0.767485 +vt 0.986941 0.767485 +vt 0.987957 0.786831 +vt 0.987946 0.777486 +vt 0.987932 0.767485 +vt 0.097618 0.091947 +vt 0.097611 0.088261 +vt 0.098113 0.091947 +vt 0.098106 0.088158 +vt 0.097545 0.085314 +vt 0.098609 0.091947 +vt 0.098609 0.088136 +vt 0.817590 0.050770 +vt 0.817593 0.057955 +vt 0.817094 0.050770 +vt 0.817097 0.057955 +vt 0.817106 0.064830 +vt 0.817601 0.064830 +vt 0.816599 0.050770 +vt 0.816602 0.057956 +vt 0.816611 0.064830 +vt 0.361879 0.028383 +vt 0.361877 0.030853 +vt 0.361384 0.028383 +vt 0.361382 0.030853 +vt 0.360889 0.028383 +vt 0.360886 0.030853 +vt 0.986972 0.795982 +vt 0.987467 0.795982 +vt 0.987962 0.795982 +vt 0.878905 0.123914 +vt 0.878961 0.118878 +vt 0.879400 0.123913 +vt 0.879456 0.118877 +vt 0.213628 0.234434 +vt 0.213132 0.234433 +vt 0.879896 0.123913 +vt 0.879952 0.118877 +vt 0.212637 0.234433 +vt 0.878636 0.226066 +vt 0.878629 0.213263 +vt 0.879132 0.226065 +vt 0.879125 0.213262 +vt 0.879126 0.199297 +vt 0.878631 0.199297 +vt 0.879627 0.226065 +vt 0.879620 0.213262 +vt 0.879622 0.199296 +vt 0.213369 0.279797 +vt 0.212873 0.279797 +vt 0.212866 0.288046 +vt 0.213361 0.288046 +vt 0.212378 0.279797 +vt 0.212370 0.288046 +vt 0.878740 0.265309 +vt 0.878705 0.256555 +vt 0.879240 0.265259 +vt 0.879202 0.256543 +vt 0.879170 0.246950 +vt 0.878674 0.246950 +vt 0.879736 0.265258 +vt 0.879697 0.256543 +vt 0.879665 0.246950 +vt 0.213362 0.296584 +vt 0.212867 0.296584 +vt 0.212371 0.296583 +vt 0.878826 0.278255 +vt 0.878785 0.272445 +vt 0.878394 0.272654 +vt 0.879321 0.278249 +vt 0.879281 0.272421 +vt 0.879817 0.278248 +vt 0.879777 0.272420 +vt 0.878711 0.153427 +vt 0.878748 0.145283 +vt 0.879207 0.153427 +vt 0.879244 0.145283 +vt 0.879290 0.137532 +vt 0.878794 0.137532 +vt 0.879702 0.153426 +vt 0.879739 0.145282 +vt 0.879785 0.137532 +vt 0.213612 0.394510 +vt 0.213117 0.394510 +vt 0.213093 0.403110 +vt 0.213588 0.403111 +vt 0.212622 0.394509 +vt 0.212598 0.403110 +vt 0.878651 0.237046 +vt 0.879146 0.237046 +vt 0.879642 0.237045 +vt 0.817615 0.070772 +vt 0.817120 0.070772 +vt 0.947277 0.931434 +vt 0.947772 0.931435 +vt 0.947749 0.925487 +vt 0.947254 0.925486 +vt 0.816624 0.070772 +vt 0.948267 0.931436 +vt 0.948244 0.925488 +vt 0.947251 0.919185 +vt 0.947746 0.919186 +vt 0.947755 0.912617 +vt 0.947260 0.912616 +vt 0.948241 0.919188 +vt 0.948251 0.912619 +vt 0.097637 0.125111 +vt 0.097637 0.121574 +vt 0.098132 0.125111 +vt 0.098133 0.121574 +vt 0.098134 0.116761 +vt 0.097638 0.116761 +vt 0.098628 0.125110 +vt 0.098628 0.121574 +vt 0.098629 0.116761 +vt 0.986972 0.660486 +vt 0.986585 0.660485 +vt 0.987467 0.660486 +vt 0.878961 0.292961 +vt 0.879456 0.292961 +vt 0.879403 0.287959 +vt 0.878908 0.287959 +vt 0.878574 0.292962 +vt 0.987962 0.660486 +vt 0.879952 0.292961 +vt 0.879898 0.287958 +vt 0.213549 0.415294 +vt 0.213543 0.417488 +vt 0.213930 0.417488 +vt 0.213053 0.415294 +vt 0.213048 0.417488 +vt 0.097638 0.126468 +vt 0.098133 0.126468 +vt 0.097251 0.126468 +vt 0.212558 0.415294 +vt 0.212553 0.417487 +vt 0.212165 0.417487 +vt 0.098629 0.126468 +vt 0.099016 0.126468 +vt 0.947273 0.906022 +vt 0.947768 0.906023 +vt 0.948263 0.906024 +vt 0.361871 0.044413 +vt 0.361376 0.044413 +vt 0.360881 0.044413 +vt 0.097638 0.107161 +vt 0.097633 0.103091 +vt 0.098133 0.107161 +vt 0.098129 0.103091 +vt 0.098122 0.099359 +vt 0.097627 0.099359 +vt 0.098629 0.107161 +vt 0.098624 0.103091 +vt 0.098618 0.099359 +vt 0.878642 0.185258 +vt 0.879138 0.185258 +vt 0.879156 0.172543 +vt 0.878660 0.172543 +vt 0.879633 0.185257 +vt 0.879651 0.172542 +vt 0.361880 0.025820 +vt 0.361385 0.025820 +vt 0.360889 0.025820 +vt 0.986917 0.743921 +vt 0.986910 0.730424 +vt 0.987412 0.743921 +vt 0.987405 0.730424 +vt 0.987908 0.743921 +vt 0.987900 0.730424 +vt 0.097639 0.111793 +vt 0.098134 0.111793 +vt 0.098630 0.111792 +vt 0.878848 0.130252 +vt 0.879344 0.130252 +vt 0.879839 0.130251 +vt 0.817592 0.043801 +vt 0.817097 0.043801 +vt 0.816602 0.043801 +vt 0.213563 0.359348 +vt 0.213068 0.359348 +vt 0.212573 0.359348 +vt 0.097621 0.095676 +vt 0.098116 0.095676 +vt 0.098612 0.095675 +vt 0.986928 0.756360 +vt 0.987423 0.756360 +vt 0.987919 0.756360 +vt 0.878683 0.162182 +vt 0.879178 0.162181 +vt 0.879673 0.162181 +vt 0.878865 0.283222 +vt 0.879360 0.283221 +vt 0.879855 0.283221 +vt 0.878371 0.292948 +vt 0.013519 0.729925 +vt 0.013405 0.730002 +vt 0.986381 0.660500 +vt 0.246870 0.617843 +vt 0.242293 0.627283 +vt 0.236722 0.637836 +vt 0.251537 0.568646 +vt 0.246908 0.568684 +vt 0.243664 0.568796 +vt 0.246599 0.583032 +vt 0.248810 0.591499 +vt 0.250107 0.600456 +vt 0.283149 0.561847 +vt 0.279165 0.560218 +vt 0.275397 0.559808 +vt 0.249531 0.609108 +vt 0.268538 0.563447 +vt 0.265059 0.565896 +vt 0.261117 0.567736 +vt 0.242992 0.571384 +vt 0.244496 0.576073 +vt 0.295317 0.600487 +vt 0.290149 0.593984 +vt 0.290099 0.568581 +vt 0.290851 0.566731 +vt 0.289872 0.565609 +vt 0.287236 0.586225 +vt 0.286699 0.578588 +vt 0.231176 0.649568 +vt 0.226306 0.661399 +vt 0.222567 0.672241 +vt 0.220019 0.682110 +vt 0.228707 0.733822 +vt 0.233792 0.740971 +vt 0.238949 0.746612 +vt 0.282722 0.767875 +vt 0.291893 0.769197 +vt 0.302553 0.769803 +vt 0.257397 0.759277 +vt 0.265545 0.762904 +vt 0.315470 0.769725 +vt 0.329586 0.768894 +vt 0.218163 0.699854 +vt 0.218664 0.708023 +vt 0.220491 0.716251 +vt 0.400006 0.624329 +vt 0.392848 0.615698 +vt 0.386728 0.607474 +vt 0.381524 0.560484 +vt 0.377995 0.560089 +vt 0.372633 0.561951 +vt 0.380466 0.590041 +vt 0.380460 0.580742 +vt 0.381509 0.571911 +vt 0.350504 0.563253 +vt 0.347999 0.563376 +vt 0.345525 0.563869 +vt 0.382516 0.598986 +vt 0.361909 0.565505 +vt 0.358292 0.565492 +vt 0.355552 0.564651 +vt 0.382353 0.564665 +vt 0.339278 0.591367 +vt 0.335628 0.597688 +vt 0.330208 0.603235 +vt 0.341671 0.566958 +vt 0.341186 0.571810 +vt 0.341200 0.578276 +vt 0.340887 0.584883 +vt 0.414056 0.645227 +vt 0.407264 0.634064 +vt 0.424258 0.669758 +vt 0.419895 0.657673 +vt 0.412737 0.734449 +vt 0.416780 0.729297 +vt 0.420726 0.723060 +vt 0.356056 0.765070 +vt 0.376106 0.759240 +vt 0.404501 0.742534 +vt 0.343473 0.767276 +vt 0.426692 0.707709 +vt 0.427851 0.698787 +vt 0.427850 0.689378 +vt 0.287047 0.563902 +vt 0.274015 0.765788 +vt 0.271905 0.561110 +vt 0.244175 0.751195 +vt 0.256486 0.568512 +vt 0.224006 0.725127 +vt 0.218597 0.691269 +vt 0.426790 0.680039 +vt 0.343232 0.564665 +vt 0.385051 0.755316 +vt 0.366911 0.564125 +vt 0.424210 0.715786 +vt 0.353012 0.563758 +vt 0.408770 0.738657 +vt 0.193815 0.637836 +vt 0.188244 0.627283 +vt 0.183667 0.617842 +vt 0.186874 0.568797 +vt 0.183630 0.568685 +vt 0.179002 0.568647 +vt 0.180430 0.600456 +vt 0.181728 0.591500 +vt 0.183938 0.583032 +vt 0.155068 0.559838 +vt 0.151316 0.560205 +vt 0.148356 0.561147 +vt 0.181007 0.609108 +vt 0.169421 0.567737 +vt 0.165480 0.565897 +vt 0.162000 0.563448 +vt 0.187546 0.571384 +vt 0.188033 0.569307 +vt 0.188625 0.569015 +vt 0.140396 0.593978 +vt 0.135224 0.600480 +vt 0.140345 0.568262 +vt 0.142310 0.572346 +vt 0.143476 0.572236 +vt 0.141876 0.572402 +vt 0.143831 0.578539 +vt 0.143310 0.586222 +vt 0.204231 0.661398 +vt 0.199360 0.649567 +vt 0.210515 0.682077 +vt 0.207968 0.672235 +vt 0.196519 0.741057 +vt 0.200329 0.734161 +vt 0.127981 0.769800 +vt 0.138642 0.769194 +vt 0.164990 0.762901 +vt 0.173137 0.759273 +vt 0.043810 0.607475 +vt 0.037689 0.615699 +vt 0.030532 0.624330 +vt 0.057906 0.561953 +vt 0.052543 0.560092 +vt 0.049014 0.560486 +vt 0.049030 0.571913 +vt 0.050078 0.580744 +vt 0.050072 0.590043 +vt 0.085013 0.563871 +vt 0.082540 0.563378 +vt 0.080035 0.563255 +vt 0.048022 0.598988 +vt 0.074986 0.564654 +vt 0.072246 0.565494 +vt 0.068629 0.565507 +vt 0.048186 0.564667 +vt 0.094910 0.597689 +vt 0.091260 0.591368 +vt 0.089338 0.578277 +vt 0.089352 0.571812 +vt 0.088867 0.566960 +vt 0.089651 0.584885 +vt 0.023273 0.634065 +vt 0.016481 0.645228 +vt 0.010642 0.657674 +vt 0.006279 0.669759 +vt 0.009809 0.723059 +vt 0.013762 0.729303 +vt 0.017851 0.734498 +vt 0.054367 0.759207 +vt 0.074478 0.765068 +vt 0.087062 0.767274 +vt 0.002686 0.689378 +vt 0.002685 0.698787 +vt 0.003844 0.707709 +vt 0.158623 0.561115 +vt 0.186357 0.751195 +vt 0.174052 0.568513 +vt 0.211141 0.699352 +vt 0.211785 0.691130 +vt 0.003747 0.680039 +vt 0.087306 0.564667 +vt 0.063627 0.564127 +vt 0.006325 0.715786 +vt 0.077526 0.563760 +vt 0.021894 0.738784 +vt 0.097110 0.082590 +vt 0.097160 0.083942 +vt 0.097374 0.083768 +vt 0.097587 0.082733 +vt 0.097598 0.077924 +vt 0.097389 0.076951 +vt 0.097563 0.076535 +vt 0.588798 0.088643 +vt 0.588627 0.089072 +vt 0.589013 0.088766 +vt 0.097175 0.076822 +vt 0.097658 0.080297 +vt 0.030118 0.746975 +vt 0.878198 0.273177 +vt 0.878153 0.268925 +vt 0.033863 0.749890 +vt 0.035915 0.751186 +vt 0.878102 0.266655 +vt 0.147115 0.561450 +vt 0.097026 0.084170 +vt 0.146895 0.561365 +vt 0.097041 0.076838 +vt 0.097031 0.078071 +vt 0.589147 0.088792 +vt 0.139195 0.565860 +vt 0.139233 0.565974 +vt 0.139410 0.566441 +vt 0.186042 0.576074 +vt 0.288178 0.572526 +vt 0.288645 0.572469 +vt 0.242505 0.569307 +vt 0.241913 0.569015 +vt 0.212575 0.410339 +vt 0.213070 0.410339 +vt 0.213565 0.410339 +vt 0.588145 0.088350 +vt 0.587561 0.088132 +vt 0.587559 0.089511 +vt 0.588062 0.089553 +vt 0.588557 0.089620 +vt 0.097048 0.126444 +vt 0.188809 0.568886 +vt 0.214134 0.417469 +vt 0.589130 0.094589 +vt 0.141739 0.572421 +vt 0.288796 0.572429 +vt 0.586958 0.094598 +vt 0.241729 0.568885 +vt 0.099219 0.126444 +vt 0.211962 0.417467 +vn 0.0164 -0.0464 0.9988 +vn 0.0155 -0.0461 0.9988 +vn 0.0155 -0.0462 0.9988 +vn 0.0163 -0.0464 0.9988 +vn 0.0172 -0.0459 0.9988 +vn 0.0177 -0.0459 0.9988 +vn 0.0164 -0.0461 0.9988 +vn 0.0165 -0.0462 0.9988 +vn 0.0182 -0.0459 0.9988 +vn 0.0180 -0.0462 0.9988 +vn 0.0179 -0.0466 0.9988 +vn 0.0155 -0.0460 0.9988 +vn 0.0145 -0.0466 0.9988 +vn 0.0167 -0.0455 0.9988 +vn 0.0165 -0.0456 0.9988 +vn 0.0156 -0.0459 0.9988 +vn 0.0162 -0.0462 0.9988 +vn 0.0161 -0.0453 0.9988 +vn 0.0163 -0.0453 0.9988 +vn 0.0156 -0.0454 0.9988 +vn 0.0165 -0.0469 0.9988 +vn 0.0166 -0.0469 0.9988 +vn 0.0168 -0.0470 0.9988 +vn 0.0168 -0.0469 0.9988 +vn 0.0180 -0.0472 0.9987 +vn 0.0164 -0.0469 0.9988 +vn 0.0150 -0.0464 0.9988 +vn 0.0151 -0.0466 0.9988 +vn 0.0153 -0.0467 0.9988 +vn 0.0154 -0.0459 0.9988 +vn 0.0153 -0.0458 0.9988 +vn 0.0152 -0.0459 0.9988 +vn 0.0151 -0.0461 0.9988 +vn 0.0154 -0.0463 0.9988 +vn 0.0152 -0.0464 0.9988 +vn 0.0163 -0.0456 0.9988 +vn 0.0162 -0.0456 0.9988 +vn 0.0171 -0.0470 0.9987 +vn 0.0173 -0.0470 0.9987 +vn 0.0177 -0.0464 0.9988 +vn 0.0176 -0.0466 0.9988 +vn 0.0176 -0.0464 0.9988 +vn 0.0175 -0.0466 0.9988 +vn 0.0176 -0.0465 0.9988 +vn 0.0163 -0.0455 0.9988 +vn 0.0161 -0.0455 0.9988 +vn 0.0173 -0.0458 0.9988 +vn 0.0175 -0.0457 0.9988 +vn 0.0175 -0.0458 0.9988 +vn 0.0176 -0.0459 0.9988 +vn 0.0177 -0.0461 0.9988 +vn 0.0166 -0.0468 0.9988 +vn 0.0165 -0.0454 0.9988 +vn 0.0168 -0.0453 0.9988 +vn -0.0164 0.0464 -0.9988 +vn -0.0163 0.0464 -0.9988 +vn -0.0179 0.0499 -0.9986 +vn -0.0161 0.0506 -0.9986 +vn -0.0162 0.0467 -0.9988 +vn -0.0156 0.0470 -0.9988 +vn -0.0164 0.0503 -0.9986 +vn -0.0171 0.0499 -0.9986 +vn -0.0165 0.0460 -0.9988 +vn -0.0166 0.0460 -0.9988 +vn -0.0168 0.0459 -0.9988 +vn -0.0169 0.0460 -0.9988 +vn -0.0164 0.0460 -0.9988 +vn -0.0154 0.0467 -0.9988 +vn -0.0154 0.0466 -0.9988 +vn -0.0171 0.0470 -0.9987 +vn -0.0178 0.0470 -0.9987 +vn -0.0184 0.0467 -0.9987 +vn -0.0181 0.0468 -0.9987 +vn -0.0182 0.0466 -0.9987 +vn -0.0154 0.0469 -0.9988 +vn -0.0156 0.0468 -0.9988 +vn -0.0144 0.0461 -0.9988 +vn -0.0163 0.0465 -0.9988 +vn -0.0141 0.0498 -0.9987 +vn -0.0105 0.0556 -0.9984 +vn -0.0161 0.0468 -0.9988 +vn -0.0166 0.0461 -0.9988 +vn -0.0179 0.0498 -0.9986 +vn -0.0183 0.0498 -0.9986 +vn -0.0171 0.0460 -0.9988 +vn -0.0171 0.0462 -0.9988 +vn -0.0167 0.0464 -0.9988 +vn -0.0177 0.0465 -0.9988 +vn -0.0176 0.0463 -0.9988 +vn -0.0176 0.0465 -0.9988 +vn -0.0175 0.0462 -0.9988 +vn -0.0176 0.0474 -0.9987 +vn -0.0174 0.0462 -0.9988 +vn -0.0160 0.0507 -0.9986 +vn -0.0161 0.0505 -0.9986 +vn -0.0173 0.0470 -0.9987 +vn -0.0174 0.0470 -0.9987 +vn -0.0175 0.0470 -0.9987 +vn -0.0174 0.0471 -0.9987 +vn -0.0176 0.0467 -0.9988 +vn -0.0168 0.0463 -0.9988 +vn -0.0153 0.0465 -0.9988 +vn -0.0150 0.0464 -0.9988 +vn -0.0151 0.0465 -0.9988 +vn -0.0151 0.0463 -0.9988 +vn -0.0152 0.0462 -0.9988 +vn -0.0154 0.0470 -0.9988 +vn -0.0153 0.0471 -0.9988 +vn -0.0151 0.0470 -0.9988 +vn -0.0150 0.0467 -0.9988 +vn 0.0164 -0.0460 0.9988 +vn 0.0199 -0.0339 0.9992 +vn 0.0248 -0.0333 0.9991 +vn 0.0166 -0.0461 0.9988 +vn 0.0161 -0.0460 0.9988 +vn 0.0130 -0.0339 0.9993 +vn 0.0162 -0.0460 0.9988 +vn 0.0163 -0.0460 0.9988 +vn 0.0164 -0.0338 0.9993 +vn 0.0164 -0.0470 0.9988 +vn 0.0198 -0.0628 0.9978 +vn 0.0263 -0.0621 0.9977 +vn 0.0167 -0.0469 0.9988 +vn 0.0159 -0.0469 0.9988 +vn 0.0052 -0.0612 0.9981 +vn 0.0160 -0.0469 0.9988 +vn 0.0166 -0.0470 0.9988 +vn 0.0245 -0.0625 0.9977 +vn 0.0167 -0.0471 0.9987 +vn -0.0155 0.0470 -0.9988 +vn -0.0079 0.0596 -0.9982 +vn -0.0160 0.0468 -0.9988 +vn -0.0161 0.0469 -0.9988 +vn -0.0128 0.0590 -0.9982 +vn -0.0162 0.0469 -0.9988 +vn -0.0163 0.0469 -0.9988 +vn -0.0163 0.0591 -0.9981 +vn -0.0164 0.0468 -0.9988 +vn -0.0208 0.0305 -0.9993 +vn -0.0166 0.0459 -0.9988 +vn -0.0275 0.0317 -0.9991 +vn -0.0167 0.0459 -0.9988 +vn -0.0172 0.0299 -0.9994 +vn -0.0164 0.0472 -0.9988 +vn -0.0197 0.0590 -0.9981 +vn -0.0164 0.0467 -0.9988 +vn -0.0245 0.0595 -0.9979 +vn -0.0166 0.0468 -0.9988 +vn -0.0162 0.0458 -0.9988 +vn -0.0129 0.0301 -0.9995 +vn -0.0163 0.0460 -0.9988 +vn -0.0163 0.0459 -0.9988 +vn -0.0163 0.0299 -0.9994 +vn -0.0164 0.0459 -0.9988 +vn -0.0165 0.0459 -0.9988 +vn -0.0224 0.0307 -0.9993 +vn -0.0168 0.0460 -0.9988 +vn -0.0327 0.0330 -0.9989 +vn -0.0170 0.0459 -0.9988 +vn -0.0170 0.0462 -0.9988 +vn -0.0202 0.0456 -0.9988 +vn -0.0166 0.0464 -0.9988 +vn -0.0165 0.0464 -0.9988 +vn -0.0164 0.0463 -0.9988 +vn -0.0141 0.0420 -0.9990 +vn -0.0095 0.0291 -0.9995 +vn -0.0156 0.0451 -0.9989 +vn 0.0147 -0.0091 -0.9999 +vn 0.0100 -0.0087 -0.9999 +vn -0.0140 0.0418 -0.9990 +vn -0.0176 0.0462 -0.9988 +vn 0.0152 -0.0466 0.9988 +vn 0.0151 -0.0467 0.9988 +vn 0.0176 -0.0469 0.9987 +vn 0.0174 -0.0470 0.9987 +vn 0.0151 -0.0460 0.9988 +vn 0.0154 -0.0462 0.9988 +vn 0.0162 -0.0425 0.9990 +vn 0.0148 -0.0428 0.9990 +vn 0.0144 -0.0431 0.9990 +vn 0.0167 -0.0461 0.9988 +vn 0.0176 -0.0456 0.9988 +vn 0.0178 -0.0458 0.9988 +vn 0.0156 -0.0429 0.9990 +vn 0.0163 -0.0426 0.9990 +vn 0.0166 -0.0424 0.9990 +vn 0.0173 -0.0469 0.9987 +vn 0.0181 -0.0460 0.9988 +vn 0.0197 -0.0426 0.9989 +vn 0.0186 -0.0430 0.9989 +vn 0.0163 -0.0465 0.9988 +vn 0.0183 -0.0430 0.9989 +vn 0.0181 -0.0462 0.9988 +vn 0.0152 -0.0458 0.9988 +vn 0.0161 -0.0469 0.9988 +vn 0.0162 -0.0469 0.9988 +vn 0.0158 -0.0469 0.9988 +vn 0.0162 -0.0467 0.9988 +vn 0.0146 -0.0464 0.9988 +vn 0.0146 -0.0466 0.9988 +vn 0.0143 -0.0469 0.9988 +vn 0.0145 -0.0470 0.9988 +vn 0.0152 -0.0470 0.9988 +vn 0.0163 -0.0469 0.9988 +vn 0.0163 -0.0470 0.9988 +vn 0.0174 -0.0462 0.9988 +vn 0.0173 -0.0461 0.9988 +vn 0.0168 -0.0452 0.9988 +vn 0.0167 -0.0453 0.9988 +vn 0.0148 -0.0457 0.9988 +vn 0.0154 -0.0457 0.9988 +vn 0.0160 -0.0452 0.9988 +vn 0.0161 -0.0451 0.9989 +vn 0.0163 -0.0451 0.9988 +vn 0.0162 -0.0455 0.9988 +vn 0.0155 -0.0454 0.9989 +vn 0.0141 -0.0458 0.9989 +vn 0.0144 -0.0462 0.9988 +vn 0.0144 -0.0460 0.9988 +vn 0.0165 -0.0471 0.9988 +vn 0.0167 -0.0472 0.9987 +vn 0.0168 -0.0471 0.9988 +vn 0.0169 -0.0471 0.9987 +vn 0.0170 -0.0471 0.9987 +vn 0.0176 -0.0472 0.9987 +vn 0.0184 -0.0470 0.9987 +vn 0.0184 -0.0468 0.9987 +vn 0.0177 -0.0465 0.9988 +vn 0.0164 -0.0471 0.9988 +vn 0.0177 -0.0427 0.9989 +vn 0.0148 -0.0431 0.9990 +vn 0.0156 -0.0469 0.9988 +vn 0.0150 -0.0466 0.9988 +vn 0.0166 -0.0422 0.9990 +vn 0.0163 -0.0415 0.9990 +vn 0.0155 -0.0459 0.9988 +vn 0.0153 -0.0460 0.9988 +vn 0.0151 -0.0462 0.9988 +vn 0.0175 -0.0464 0.9988 +vn 0.0165 -0.0470 0.9988 +vn 0.0172 -0.0471 0.9987 +vn 0.0177 -0.0457 0.9988 +vn 0.0162 -0.0453 0.9988 +vn 0.0168 -0.0471 0.9987 +vn 0.0166 -0.0452 0.9988 +vn -0.0173 0.0467 -0.9988 +vn -0.0173 0.0468 -0.9988 +vn -0.0172 0.0469 -0.9988 +vn -0.0160 0.0510 -0.9986 +vn -0.0149 0.0471 -0.9988 +vn -0.0154 0.0472 -0.9988 +vn -0.0164 0.0502 -0.9986 +vn -0.0160 0.0469 -0.9988 +vn -0.0105 0.0555 -0.9984 +vn -0.0076 0.0612 -0.9981 +vn -0.0160 0.0471 -0.9988 +vn 0.0260 0.1040 -0.9942 +vn 0.0432 0.1416 -0.9890 +vn 0.0787 0.2009 -0.9765 +vn -0.0050 0.0645 -0.9979 +vn -0.0150 0.0465 -0.9988 +vn -0.0149 0.0462 -0.9988 +vn -0.0147 0.0467 -0.9988 +vn -0.0172 0.0469 -0.9987 +vn -0.0176 0.0472 -0.9987 +vn -0.0167 0.0458 -0.9988 +vn -0.0169 0.0458 -0.9988 +vn -0.0170 0.0458 -0.9988 +vn -0.0211 0.0450 -0.9988 +vn -0.0249 0.0445 -0.9987 +vn -0.0209 0.0459 -0.9987 +vn -0.0672 0.0247 -0.9974 +vn -0.0734 0.0280 -0.9969 +vn -0.0796 0.0306 -0.9964 +vn -0.0711 0.0399 -0.9967 +vn -0.0651 0.0462 -0.9968 +vn -0.0164 0.0458 -0.9988 +vn -0.0152 0.0469 -0.9988 +vn -0.0162 0.0474 -0.9987 +vn -0.0160 0.0475 -0.9987 +vn -0.0159 0.0476 -0.9987 +vn -0.0167 0.0467 -0.9988 +vn -0.0176 0.0473 -0.9987 +vn -0.0181 0.0472 -0.9987 +vn -0.0164 0.0476 -0.9987 +vn -0.0166 0.0475 -0.9987 +vn -0.0166 0.0474 -0.9987 +vn -0.0184 0.0466 -0.9987 +vn -0.0185 0.0467 -0.9987 +vn -0.0187 0.0471 -0.9987 +vn -0.0169 0.0474 -0.9987 +vn -0.0165 0.0473 -0.9987 +vn -0.0182 0.0468 -0.9987 +vn -0.0152 0.0472 -0.9988 +vn -0.0152 0.0471 -0.9988 +vn -0.0162 0.0463 -0.9988 +vn -0.0163 0.0461 -0.9988 +vn -0.0157 0.0454 -0.9988 +vn -0.0162 0.0460 -0.9988 +vn -0.0158 0.0459 -0.9988 +vn -0.0159 0.0459 -0.9988 +vn -0.0160 0.0459 -0.9988 +vn -0.0142 0.0461 -0.9988 +vn -0.0143 0.0459 -0.9988 +vn -0.0147 0.0457 -0.9988 +vn -0.0154 0.0458 -0.9988 +vn -0.0165 0.0456 -0.9988 +vn -0.0163 0.0467 -0.9988 +vn -0.0140 0.0497 -0.9987 +vn -0.0094 0.0568 -0.9983 +vn -0.0162 0.0465 -0.9988 +vn -0.0168 0.0457 -0.9988 +vn -0.0180 0.0500 -0.9986 +vn -0.0173 0.0457 -0.9988 +vn -0.0174 0.0458 -0.9988 +vn -0.0175 0.0460 -0.9988 +vn -0.0177 0.0475 -0.9987 +vn -0.0166 0.0517 -0.9985 +vn -0.0160 0.0508 -0.9986 +vn -0.0169 0.0463 -0.9988 +vn -0.0147 0.0466 -0.9988 +vn -0.0170 0.0464 -0.9988 +vn -0.0174 0.0463 -0.9988 +vn -0.0174 0.0466 -0.9988 +vn -0.0164 0.0473 -0.9987 +vn -0.0157 0.0459 -0.9988 +vn -0.0149 0.0465 -0.9988 +vn -0.0146 0.0462 -0.9988 +vn -0.0151 0.0462 -0.9988 +vn -0.0152 0.0463 -0.9988 +vn -0.0164 0.0475 -0.9987 +vn -0.0153 0.0475 -0.9988 +vn -0.0151 0.0473 -0.9988 +vn -0.0148 0.0471 -0.9988 +vn -0.0147 0.0468 -0.9988 +vn -0.0161 0.0454 -0.9988 +vn -0.0162 0.0476 -0.9987 +vn 0.2063 -0.2377 0.9492 +vn 0.5975 -0.6205 0.5078 +vn 0.6524 -0.5619 0.5086 +vn 0.2255 -0.2200 0.9491 +vn 0.7024 -0.7117 0.0037 +vn 0.7672 -0.6414 0.0058 +vn 0.7672 -0.6413 0.0058 +vn 0.8328 -0.5535 0.0088 +vn 0.7081 -0.4885 0.5100 +vn 0.7081 -0.4885 0.5099 +vn 0.2459 -0.1978 0.9489 +vn -0.0126 -0.3090 0.9510 +vn -0.0806 -0.8565 0.5098 +vn -0.0326 -0.8599 0.5095 +vn 0.0026 -0.3095 0.9509 +vn -0.0806 -0.8565 0.5097 +vn -0.1060 -0.9944 0.0038 +vn -0.0488 -0.9988 0.0027 +vn -0.0326 -0.8600 0.5093 +vn 0.0057 -1.0000 0.0017 +vn 0.0131 -0.8610 0.5085 +vn 0.0131 -0.8611 0.5083 +vn 0.0171 -0.3102 0.9505 +vn 0.2427 0.1063 0.9643 +vn 0.7051 0.4373 0.5581 +vn 0.7009 0.4349 0.5653 +vn 0.2385 0.1033 0.9656 +vn 0.7051 0.4373 0.5582 +vn 0.8325 0.5507 0.0604 +vn 0.8322 0.5512 0.0606 +vn 0.8908 0.4510 0.0549 +vn 0.7443 0.3485 0.5697 +vn 0.7442 0.3485 0.5699 +vn 0.2485 0.0734 0.9659 +vn -0.1254 0.1967 0.9724 +vn -0.4111 0.6935 0.5917 +vn -0.3447 0.7164 0.6066 +vn -0.0984 0.1964 0.9756 +vn -0.4110 0.6934 0.5918 +vn -0.5025 0.8591 0.0968 +vn -0.4278 0.8986 0.0978 +vn -0.2160 0.9714 0.0982 +vn -0.1677 0.7701 0.6154 +vn -0.1677 0.7702 0.6153 +vn -0.0409 0.2082 0.9772 +vn -0.2164 0.0966 0.9715 +vn -0.7044 0.4085 0.5805 +vn -0.7250 0.3738 0.5785 +vn -0.2231 0.0853 0.9711 +vn -0.7044 0.4085 0.5804 +vn -0.8519 0.5166 0.0863 +vn -0.8760 0.4748 0.0847 +vn -0.9010 0.4258 0.0828 +vn -0.7463 0.3331 0.5763 +vn -0.7463 0.3330 0.5763 +vn -0.2301 0.0721 0.9705 +vn 0.1466 0.1644 0.9754 +vn 0.4415 0.6732 0.5931 +vn 0.6150 0.5290 0.5847 +vn 0.2027 0.1242 0.9713 +vn 0.4415 0.6733 0.5930 +vn 0.5256 0.8470 0.0789 +vn 0.7372 0.6723 0.0674 +vn 0.6149 0.5287 0.5851 +vn 0.6149 0.5288 0.5851 +vn 0.7372 0.6723 0.0673 +vn 0.9051 0.4218 0.0533 +vn 0.7505 0.3215 0.5774 +vn 0.7506 0.3215 0.5773 +vn 0.2455 0.0622 0.9674 +vn -0.1442 -0.2622 0.9542 +vn -0.4884 -0.6998 0.5213 +vn -0.4245 -0.7418 0.5192 +vn -0.1230 -0.2744 0.9537 +vn -0.4884 -0.6999 0.5212 +vn -0.5916 -0.8059 0.0204 +vn -0.5159 -0.8565 0.0168 +vn -0.4245 -0.7418 0.5191 +vn -0.4396 -0.8981 0.0137 +vn -0.3606 -0.7770 0.5160 +vn -0.3605 -0.7769 0.5162 +vn -0.1025 -0.2856 0.9528 +vn 0.0334 0.2339 0.9717 +vn 0.0631 0.8045 0.5906 +vn 0.0577 0.8051 0.5903 +vn 0.0334 0.2354 0.9713 +vn 0.0631 0.8043 0.5908 +vn 0.0654 0.9935 0.0937 +vn 0.0600 0.9937 0.0942 +vn 0.0577 0.8051 0.5904 +vn -0.1341 0.9853 0.1062 +vn -0.1044 0.7849 0.6108 +vn -0.1045 0.7849 0.6107 +vn -0.0021 0.2229 0.9748 +vn -0.5041 0.8637 -0.0006 +vn -0.4288 0.7442 -0.5121 +vn -0.3633 0.7691 -0.5259 +vn -0.4294 0.9031 0.0000 +vn -0.4288 0.7443 -0.5121 +vn -0.1565 0.2855 -0.9455 +vn -0.1296 0.2855 -0.9496 +vn -0.3633 0.7690 -0.5259 +vn -0.0724 0.2973 -0.9520 +vn -0.1866 0.8237 -0.5354 +vn -0.2177 0.9760 -0.0005 +vn -0.0324 0.2248 0.9739 +vn -0.1403 0.7989 0.5849 +vn -0.4398 0.6925 0.5719 +vn -0.1352 0.1981 0.9708 +vn -0.1403 0.7988 0.5849 +vn -0.1765 0.9795 0.0969 +vn -0.5298 0.8421 0.1006 +vn -0.4398 0.6924 0.5720 +vn -0.9002 0.4268 0.0867 +vn -0.7508 0.3421 0.5650 +vn -0.7509 0.3421 0.5649 +vn -0.2478 0.0681 0.9664 +vn -0.0561 -0.3027 0.9514 +vn -0.2160 -0.8320 0.5111 +vn -0.1425 -0.8486 0.5096 +vn -0.0325 -0.3076 0.9509 +vn -0.2160 -0.8319 0.5111 +vn -0.2672 -0.9636 0.0079 +vn -0.1797 -0.9837 0.0055 +vn -0.1425 -0.8485 0.5096 +vn 0.0037 0.2503 0.9682 +vn -0.0269 0.8196 0.5723 +vn -0.3170 0.7493 0.5814 +vn -0.0991 0.2214 0.9701 +vn -0.0411 0.9943 0.0980 +vn -0.3872 0.9167 0.0983 +vn 0.0049 0.2032 0.9791 +vn -0.0360 0.7887 0.6138 +vn 0.2015 0.7650 0.6117 +vn 0.0747 0.1944 0.9781 +vn -0.0360 0.7886 0.6138 +vn -0.0527 0.9939 0.0965 +vn 0.2359 0.9676 0.0906 +vn 0.2015 0.7649 0.6119 +vn 0.3997 0.9127 0.0845 +vn 0.3412 0.7357 0.5851 +vn 0.3413 0.7357 0.5850 +vn 0.1223 0.2001 0.9721 +vn -0.2540 -0.0162 0.9671 +vn -0.8173 0.0587 0.5732 +vn -0.7939 0.1578 0.5872 +vn -0.2395 0.0155 0.9708 +vn -0.9926 0.0997 0.0698 +vn -0.9723 0.2215 0.0747 +vn -0.8884 0.4513 0.0842 +vn -0.7207 0.3455 0.6010 +vn -0.7207 0.3456 0.6010 +vn -0.2111 0.0714 0.9749 +vn -0.2459 -0.0958 0.9645 +vn -0.8060 -0.1873 0.5614 +vn -0.8126 -0.1254 0.5692 +vn -0.2457 -0.0758 0.9664 +vn -0.8060 -0.1874 0.5615 +vn -0.9790 -0.1960 0.0557 +vn -0.9908 -0.1218 0.0591 +vn -0.8129 -0.1255 0.5688 +vn -0.9970 0.0391 0.0667 +vn -0.8132 0.0076 0.5820 +vn -0.8130 0.0075 0.5822 +vn -0.2419 -0.0338 0.9697 +vn 0.1730 -0.2612 0.9497 +vn 0.5004 -0.7013 0.5078 +vn 0.5452 -0.6674 0.5073 +vn 0.1883 -0.2517 0.9493 +vn 0.5003 -0.7012 0.5080 +vn 0.5875 -0.8092 0.0011 +vn 0.6404 -0.7681 0.0021 +vn 0.5451 -0.6674 0.5074 +vn -0.0012 0.7988 0.6015 +vn 0.0112 0.2250 0.9743 +vn -0.0126 0.9954 0.0955 +vn -0.0012 0.7988 0.6016 +vn -0.8198 0.0882 0.5658 +vn -0.2613 -0.0099 0.9652 +vn -0.9887 0.1316 0.0714 +vn -0.8199 0.0882 0.5657 +vn -0.5894 0.5351 0.6052 +vn -0.1682 0.1264 0.9776 +vn -0.7271 0.6803 0.0918 +vn -0.7271 0.6804 0.0918 +vn -0.5121 0.8535 0.0964 +vn -0.4122 0.6770 0.6097 +vn -0.4122 0.6771 0.6097 +vn -0.1106 0.1639 0.9803 +vn 0.0921 -0.3013 0.9491 +vn 0.2478 -0.8274 0.5040 +vn 0.3148 -0.8042 0.5042 +vn 0.1135 -0.2941 0.9490 +vn 0.2478 -0.8272 0.5043 +vn 0.2856 -0.9584 -0.0008 +vn 0.3654 -0.9308 -0.0009 +vn 0.3148 -0.8041 0.5044 +vn 0.4487 -0.8937 -0.0007 +vn 0.3848 -0.7734 0.5037 +vn 0.1364 -0.2853 0.9487 +vn -0.2471 -0.0996 0.9639 +vn -0.8060 -0.1777 0.5646 +vn -0.8025 -0.2100 0.5585 +vn -0.2453 -0.1032 0.9640 +vn -0.8060 -0.1778 0.5646 +vn -0.9805 -0.1877 0.0582 +vn -0.9733 -0.2229 0.0542 +vn -0.8027 -0.2100 0.5582 +vn 0.8309 0.5552 -0.0362 +vn 0.6872 0.4883 -0.5379 +vn 0.6828 0.4865 -0.5450 +vn 0.8306 0.5557 -0.0364 +vn 0.6871 0.4882 -0.5380 +vn 0.2115 0.1958 -0.9576 +vn 0.2068 0.1927 -0.9592 +vn 0.2166 0.1627 -0.9626 +vn 0.7258 0.4010 -0.5590 +vn 0.7258 0.4010 -0.5589 +vn 0.8892 0.4556 -0.0419 +vn -0.1076 -0.9899 -0.0925 +vn -0.0985 -0.8058 -0.5840 +vn -0.0505 -0.8089 -0.5857 +vn -0.0504 -0.9943 -0.0937 +vn -0.0985 -0.8056 -0.5842 +vn -0.0441 -0.2194 -0.9746 +vn -0.0289 -0.2199 -0.9751 +vn -0.0505 -0.8090 -0.5857 +vn -0.0145 -0.2206 -0.9753 +vn -0.0049 -0.8101 -0.5863 +vn -0.0049 -0.8100 -0.5864 +vn 0.0041 -0.9955 -0.0947 +vn -0.2604 -0.0231 0.9652 +vn -0.8276 0.0383 0.5600 +vn -0.8305 -0.0752 0.5520 +vn -0.2660 -0.0605 0.9621 +vn -0.8278 0.0383 0.5597 +vn -0.9950 0.0735 0.0678 +vn -0.9962 -0.0617 0.0616 +vn -0.8304 -0.0752 0.5520 +vn -0.9749 -0.2161 0.0541 +vn -0.8125 -0.2050 0.5457 +vn -0.2625 -0.1054 0.9592 +vn 0.0490 -0.3088 0.9499 +vn 0.1136 -0.8549 0.5063 +vn 0.1779 -0.8449 0.5045 +vn 0.0696 -0.3067 0.9492 +vn 0.1136 -0.8549 0.5061 +vn 0.1257 -0.9921 0.0000 +vn 0.2022 -0.9793 -0.0006 +vn 0.1779 -0.8450 0.5043 +vn -0.2476 0.0330 0.9683 +vn -0.7951 0.2107 0.5687 +vn -0.8153 0.1284 0.5647 +vn -0.2549 0.0062 0.9670 +vn -0.7953 0.2108 0.5684 +vn -0.9572 0.2791 0.0767 +vn -0.9808 0.1809 0.0726 +vn -0.8154 0.1284 0.5645 +vn 0.0610 -0.8594 0.5077 +vn 0.0322 -0.3096 0.9503 +vn 0.0629 -0.9980 0.0009 +vn 0.0610 -0.8594 0.5076 +vn 0.0638 0.9980 -0.0032 +vn 0.0450 0.8558 -0.5154 +vn 0.0396 0.8565 -0.5147 +vn 0.0584 0.9983 -0.0035 +vn 0.0450 0.8559 -0.5152 +vn 0.0020 0.3228 -0.9465 +vn 0.0020 0.3246 -0.9459 +vn 0.0396 0.8566 -0.5145 +vn -0.0336 0.3123 -0.9494 +vn -0.1232 0.8380 -0.5316 +vn -0.1360 0.9907 -0.0099 +vn 0.2725 -0.0366 0.9615 +vn 0.8310 -0.0019 0.5562 +vn 0.8280 -0.1442 0.5419 +vn 0.2760 -0.0816 0.9577 +vn 0.8311 -0.0019 0.5561 +vn 0.9990 0.0278 0.0336 +vn 0.9892 -0.1444 0.0259 +vn 0.9793 -0.2013 0.0231 +vn 0.8254 -0.1916 0.5311 +vn 0.8253 -0.1917 0.5312 +vn 0.2802 -0.0985 0.9549 +vn 0.0431 -0.8085 -0.5869 +vn 0.0613 -0.9935 -0.0956 +vn 0.0007 -0.2200 -0.9755 +vn 0.0431 -0.8084 -0.5870 +vn 0.0175 -0.2192 -0.9755 +vn 0.0957 -0.8039 -0.5869 +vn 0.0957 -0.8039 -0.5870 +vn 0.1241 -0.9876 -0.0962 +vn -0.5932 -0.8015 -0.0758 +vn -0.5062 -0.6492 -0.5676 +vn -0.4424 -0.6912 -0.5715 +vn -0.5175 -0.8520 -0.0793 +vn -0.5063 -0.6493 -0.5676 +vn -0.1757 -0.1727 -0.9692 +vn -0.1545 -0.1849 -0.9705 +vn -0.4423 -0.6911 -0.5717 +vn -0.1340 -0.1962 -0.9714 +vn -0.3784 -0.7264 -0.5738 +vn -0.3785 -0.7265 -0.5736 +vn -0.4411 -0.8936 -0.0825 +vn -0.8534 0.5211 -0.0102 +vn -0.7224 0.4596 -0.5166 +vn -0.7430 0.4248 -0.5173 +vn -0.8776 0.4792 -0.0117 +vn -0.7223 0.4595 -0.5168 +vn -0.2478 0.1859 -0.9508 +vn -0.2545 0.1746 -0.9512 +vn -0.7429 0.4247 -0.5174 +vn -0.2615 0.1614 -0.9516 +vn -0.7643 0.3839 -0.5182 +vn -0.7644 0.3840 -0.5180 +vn -0.9026 0.4303 -0.0134 +vn 0.2681 0.0654 0.9612 +vn 0.7778 0.3098 0.5469 +vn 0.7392 0.3857 0.5521 +vn 0.2551 0.0902 0.9627 +vn 0.9164 0.3968 0.0517 +vn 0.8711 0.4878 0.0567 +vn 0.7391 0.3857 0.5523 +vn -0.7791 -0.3149 0.5420 +vn -0.2479 -0.1422 0.9583 +vn -0.9367 -0.3469 0.0473 +vn -0.7792 -0.3149 0.5420 +vn -0.8884 -0.4571 0.0414 +vn -0.7386 -0.4076 0.5370 +vn -0.7386 -0.4076 0.5369 +vn -0.2317 -0.1717 0.9575 +vn -0.2193 0.0703 0.9731 +vn -0.7317 0.3389 0.5915 +vn -0.6987 0.4107 0.5858 +vn -0.2124 0.0958 0.9725 +vn -0.7316 0.3389 0.5915 +vn -0.8948 0.4386 0.0835 +vn -0.8488 0.5216 0.0867 +vn -0.6987 0.4108 0.5857 +vn 0.7646 -0.3920 0.5116 +vn 0.2685 -0.1682 0.9485 +vn 0.8988 -0.4381 0.0132 +vn 0.7644 -0.3919 0.5119 +vn 0.9561 -0.2924 0.0190 +vn 0.8133 -0.2695 0.5156 +vn 0.8133 -0.2696 0.5156 +vn 0.2889 -0.1276 0.9488 +vn -0.0566 0.2148 0.9750 +vn -0.2124 0.7779 0.5914 +vn -0.1874 0.7784 0.5991 +vn -0.0451 0.2106 0.9765 +vn -0.2124 0.7778 0.5916 +vn -0.2648 0.9593 0.0978 +vn -0.2352 0.9670 0.0976 +vn 0.2874 -0.1991 0.9369 +vn 0.7616 -0.4334 0.4818 +vn 0.8528 0.0629 0.5184 +vn 0.3154 -0.0612 0.9470 +vn 0.7616 -0.4334 0.4819 +vn 0.8760 -0.4823 0.0081 +vn 0.9932 0.1007 0.0589 +vn 0.8527 0.0628 0.5186 +vn 0.6921 0.7167 0.0862 +vn 0.5842 0.5648 0.5828 +vn 0.5842 0.5649 0.5828 +vn 0.1940 0.1484 0.9697 +vn 0.8394 -0.1484 0.5229 +vn 0.2947 -0.0852 0.9518 +vn 0.9886 -0.1487 0.0251 +vn 0.8394 -0.1485 0.5228 +vn 0.9991 -0.0281 0.0305 +vn 0.8477 -0.0470 0.5283 +vn 0.8477 -0.0470 0.5284 +vn 0.2946 -0.0513 0.9542 +vn -0.9540 -0.1910 -0.2309 +vn -0.5776 -0.0919 -0.8112 +vn -0.5563 -0.1460 -0.8181 +vn -0.9103 -0.3361 -0.2417 +vn -0.5774 -0.0919 -0.8113 +vn -0.5562 -0.1460 -0.8181 +vn -0.5496 -0.2222 -0.8053 +vn -0.5497 -0.2222 -0.8052 +vn -0.8719 -0.4482 -0.1974 +vn 0.8404 -0.0519 0.5395 +vn 0.2874 -0.0686 0.9553 +vn 0.9986 -0.0387 0.0358 +vn 0.7307 0.6766 0.0907 +vn 0.6186 0.5422 0.5687 +vn 0.6186 0.5421 0.5687 +vn 0.2025 0.1146 0.9725 +vn -0.1782 0.9840 0.0002 +vn -0.1581 0.8494 -0.5035 +vn -0.4572 0.7418 -0.4906 +vn -0.5315 0.8470 -0.0046 +vn -0.1581 0.8495 -0.5034 +vn -0.0638 0.3141 -0.9473 +vn -0.1665 0.2870 -0.9433 +vn -0.4573 0.7419 -0.4905 +vn -0.2792 0.1570 -0.9473 +vn -0.7684 0.3919 -0.5059 +vn -0.5315 0.8470 -0.0047 +vn -0.7684 0.3919 -0.5060 +vn -0.9019 0.4317 -0.0171 +vn 0.9777 -0.1968 -0.0740 +vn 0.8073 -0.1404 -0.5732 +vn 0.8222 -0.0003 -0.5691 +vn 0.9968 -0.0337 -0.0718 +vn 0.8073 -0.1403 -0.5733 +vn 0.2487 -0.0091 -0.9685 +vn 0.2559 0.0207 -0.9665 +vn 0.8222 -0.0003 -0.5693 +vn 0.1708 0.2046 -0.9638 +vn 0.6005 0.5935 -0.5359 +vn 0.6006 0.5935 -0.5358 +vn 0.7284 0.6832 -0.0513 +vn -0.9942 0.1042 -0.0278 +vn -0.8355 0.1103 -0.5383 +vn -0.8125 0.2103 -0.5437 +vn -0.9739 0.2260 -0.0220 +vn -0.8355 0.1103 -0.5382 +vn -0.2856 0.0732 -0.9556 +vn -0.2712 0.1052 -0.9568 +vn -0.8125 0.2103 -0.5436 +vn -0.2427 0.1612 -0.9566 +vn -0.7395 0.3987 -0.5424 +vn -0.7394 0.3987 -0.5425 +vn -0.8900 0.4558 -0.0129 +vn 0.0175 0.1985 0.9800 +vn 0.0152 0.7958 0.6053 +vn 0.2369 0.7630 0.6015 +vn 0.0832 0.1876 0.9787 +vn 0.0153 0.7959 0.6053 +vn 0.0080 0.9955 0.0940 +vn 0.2774 0.9567 0.0880 +vn 0.2369 0.7629 0.6015 +vn 0.9545 -0.2880 -0.0772 +vn 0.7957 -0.2194 -0.5646 +vn 0.8217 -0.0981 -0.5615 +vn 0.9870 -0.1442 -0.0711 +vn 0.7957 -0.2193 -0.5646 +vn 0.2576 -0.0385 -0.9655 +vn 0.2634 0.0039 -0.9647 +vn 0.8217 -0.0980 -0.5614 +vn 0.2632 0.0379 -0.9640 +vn 0.8300 0.0035 -0.5578 +vn 0.8299 0.0035 -0.5578 +vn 0.9976 -0.0236 -0.0656 +vn 0.8033 0.1866 0.5656 +vn 0.2639 0.0216 0.9643 +vn 0.9655 0.2564 0.0446 +vn 0.8032 0.1866 0.5656 +vn 0.0615 0.2320 0.9708 +vn 0.1463 0.8054 0.5744 +vn -0.0210 0.8128 0.5821 +vn 0.0054 0.2305 0.9731 +vn 0.1639 0.9822 0.0919 +vn -0.0351 0.9948 0.0954 +vn -0.0210 0.8129 0.5821 +vn 0.9975 0.0323 -0.0635 +vn 0.8125 0.0510 -0.5807 +vn 0.8096 -0.0921 -0.5797 +vn 0.9876 -0.1399 -0.0714 +vn 0.8125 0.0510 -0.5808 +vn 0.2407 0.0532 -0.9691 +vn 0.2445 0.0081 -0.9696 +vn 0.8097 -0.0921 -0.5796 +vn 0.5241 0.8515 -0.0171 +vn 0.4230 0.7261 -0.5421 +vn 0.5963 0.5817 -0.5532 +vn 0.7356 0.6768 -0.0287 +vn 0.1149 0.2544 -0.9602 +vn 0.1710 0.2140 -0.9617 +vn 0.5964 0.5818 -0.5530 +vn 0.2141 0.1522 -0.9649 +vn 0.7323 0.3748 -0.5686 +vn 0.5962 0.5817 -0.5533 +vn 0.7321 0.3748 -0.5688 +vn 0.9035 0.4263 -0.0431 +vn -0.9986 0.0436 -0.0302 +vn -0.8318 0.0603 -0.5518 +vn -0.8031 0.2404 -0.5452 +vn -0.9649 0.2619 -0.0207 +vn -0.8316 0.0603 -0.5521 +vn -0.2730 0.0560 -0.9604 +vn -0.2636 0.1114 -0.9582 +vn -0.8030 0.2404 -0.5454 +vn -0.2507 0.1599 -0.9548 +vn -0.7500 0.3912 -0.5333 +vn -0.7501 0.3912 -0.5332 +vn -0.8964 0.4431 -0.0132 +vn -0.6167 -0.3781 -0.6905 +vn -0.8232 -0.5531 -0.1283 +vn -0.1392 -0.0372 -0.9896 +vn -0.6166 -0.3781 -0.6905 +vn -0.2052 -0.1195 -0.9714 +vn -0.6302 -0.5089 -0.5863 +vn -0.6303 -0.5089 -0.5863 +vn -0.7570 -0.6488 -0.0772 +vn 0.3046 0.7593 0.5751 +vn 0.1139 0.2139 0.9702 +vn 0.3532 0.9316 0.0862 +vn 0.3046 0.7593 0.5750 +vn 0.4739 0.6602 0.5827 +vn 0.1686 0.1829 0.9686 +vn 0.5842 0.5648 0.5829 +vn 0.6921 0.7167 0.0863 +vn 0.5597 0.8244 0.0848 +vn 0.4739 0.6603 0.5826 +vn 0.4943 0.8649 0.0868 +vn 0.4225 0.7017 0.5736 +vn 0.4226 0.7018 0.5735 +vn 0.1564 0.2028 0.9667 +vn 0.4925 0.7490 -0.4432 +vn 0.2808 0.4906 -0.8249 +vn 0.1622 0.3120 -0.9361 +vn 0.3673 0.5772 -0.7293 +vn 0.1434 0.2840 -0.9481 +vn 0.3584 0.5966 -0.7181 +vn -0.2038 0.7669 0.6086 +vn -0.0477 0.1894 0.9807 +vn -0.2584 0.9612 0.0969 +vn -0.2038 0.7670 0.6085 +vn 0.7284 0.6832 -0.0514 +vn 0.6005 0.5935 -0.5358 +vn -0.0279 0.8552 -0.5176 +vn -0.0273 0.9996 -0.0090 +vn -0.0415 0.3126 -0.9490 +vn -0.0280 0.8551 -0.5177 +vn -0.0880 0.3040 -0.9486 +vn -0.2304 0.8289 -0.5097 +vn -0.2305 0.8290 -0.5096 +vn -0.2664 0.9639 0.0003 +vn 0.8039 0.1329 -0.5797 +vn 0.9895 0.1320 -0.0583 +vn 0.2380 0.0786 -0.9681 +vn 0.8041 0.1329 -0.5795 +vn 0.2349 0.0031 -0.9720 +vn 0.7973 -0.1161 -0.5923 +vn 0.7972 -0.1161 -0.5925 +vn 0.9828 -0.1700 -0.0722 +vn 0.8271 0.1046 -0.5523 +vn 0.9935 0.0968 -0.0599 +vn 0.2613 0.0714 -0.9626 +vn 0.8270 0.1046 -0.5524 +vn 0.2540 0.1029 -0.9617 +vn 0.8111 0.2014 -0.5491 +vn 0.8112 0.2015 -0.5490 +vn 0.9757 0.2122 -0.0543 +vn -0.7883 0.3316 -0.5183 +vn -0.9299 0.3674 -0.0159 +vn -0.2704 0.1450 -0.9518 +vn -0.7882 0.3316 -0.5185 +vn -0.2542 0.1160 -0.9602 +vn -0.7915 0.2566 -0.5547 +vn -0.7918 0.2567 -0.5542 +vn -0.9583 0.2837 -0.0327 +vn 0.8519 -0.5179 -0.0778 +vn 0.7051 -0.4115 -0.5775 +vn 0.7902 -0.2965 -0.5364 +vn 0.9385 -0.3441 -0.0290 +vn 0.7052 -0.4116 -0.5773 +vn 0.2203 -0.0989 -0.9704 +vn 0.2664 -0.0681 -0.9615 +vn 0.7901 -0.2965 -0.5364 +vn 0.3253 0.1619 -0.9316 +vn 0.8052 0.3013 -0.5108 +vn 0.8051 0.3012 -0.5109 +vn 0.9495 0.3135 -0.0128 +vn 0.8203 0.0795 0.5664 +vn 0.2671 -0.0108 0.9636 +vn 0.9911 0.1274 0.0386 +vn 0.9842 -0.1752 0.0250 +vn 0.8139 -0.1719 0.5550 +vn 0.8138 -0.1719 0.5551 +vn 0.2643 -0.0839 0.9608 +vn -0.0097 0.8033 0.5955 +vn -0.0101 0.2230 0.9748 +vn -0.0255 0.9944 0.1026 +vn -0.0097 0.8034 0.5954 +vn -0.6081 0.5880 -0.5334 +vn -0.7287 0.6848 -0.0045 +vn -0.1998 0.2162 -0.9557 +vn -0.6081 0.5880 -0.5333 +vn -0.1423 0.2539 -0.9567 +vn -0.4308 0.7301 -0.5304 +vn -0.4309 0.7301 -0.5304 +vn -0.5137 0.8580 -0.0001 +vn -0.7844 0.1875 0.5912 +vn -0.2321 0.0216 0.9724 +vn -0.9633 0.2574 0.0764 +vn -0.7845 0.1875 0.5911 +vn -0.6862 -0.4960 0.5321 +vn -0.2122 -0.1994 0.9566 +vn -0.8262 -0.5622 0.0355 +vn -0.6861 -0.4959 0.5322 +vn -0.7555 -0.6544 0.0301 +vn -0.6264 -0.5731 0.5284 +vn -0.6263 -0.5731 0.5285 +vn -0.1908 -0.2231 0.9559 +vn 0.2854 0.0137 0.9583 +vn 0.8290 0.1509 0.5385 +vn 0.8071 0.2309 0.5434 +vn 0.2772 0.0395 0.9600 +vn 0.9773 0.2077 0.0418 +vn 0.9518 0.3031 0.0468 +vn 0.8069 0.2308 0.5436 +vn 0.4221 0.8768 -0.2303 +vn 0.2947 0.6367 -0.7126 +vn 0.2285 0.8175 -0.5286 +vn 0.2867 0.9572 -0.0390 +vn 0.1102 0.3135 -0.9432 +vn 0.0723 0.3250 -0.9429 +vn 0.2284 0.8175 -0.5287 +vn -0.0260 0.3266 -0.9448 +vn -0.0548 0.8626 -0.5029 +vn -0.0548 0.8626 -0.5028 +vn -0.0532 0.9986 -0.0033 +vn -0.2224 0.8198 -0.5277 +vn -0.2599 0.9656 0.0011 +vn -0.0795 0.2795 -0.9568 +vn -0.0143 0.2880 -0.9575 +vn -0.0033 0.8486 -0.5291 +vn -0.0033 0.8487 -0.5289 +vn 0.0064 1.0000 -0.0013 +vn 0.3981 0.9173 -0.0125 +vn 0.3230 0.7873 -0.5252 +vn 0.2868 0.8099 -0.5117 +vn 0.3516 0.9361 -0.0108 +vn 0.3231 0.7874 -0.5250 +vn 0.0906 0.2894 -0.9529 +vn 0.0824 0.3030 -0.9494 +vn 0.0301 0.3210 -0.9466 +vn 0.1287 0.8554 -0.5017 +vn 0.1287 0.8555 -0.5016 +vn 0.1623 0.9867 -0.0057 +vn 0.7847 0.2395 -0.5718 +vn 0.9639 0.2609 -0.0521 +vn 0.2324 0.1114 -0.9662 +vn 0.7846 0.2395 -0.5718 +vn -0.5775 -0.5922 -0.5619 +vn -0.6772 -0.7324 -0.0711 +vn -0.1999 -0.1559 -0.9673 +vn -0.5774 -0.5921 -0.5621 +vn -0.5775 -0.5921 -0.5620 +vn -0.0543 0.9985 -0.0021 +vn -0.0548 0.8421 -0.5365 +vn 0.1826 0.8187 -0.5444 +vn 0.2342 0.9721 -0.0080 +vn -0.0268 0.2930 -0.9557 +vn 0.0430 0.2843 -0.9578 +vn 0.1825 0.8187 -0.5444 +vn -0.7701 0.2808 0.5728 +vn -0.2385 0.0555 0.9695 +vn -0.9283 0.3630 0.0803 +vn -0.7702 0.2808 0.5728 +vn -0.9760 0.0950 -0.1958 +vn -0.5708 0.0668 -0.8183 +vn -0.5643 -0.0164 -0.8254 +vn -0.9652 -0.0258 -0.2602 +vn -0.5710 0.0668 -0.8183 +vn -0.5642 -0.0164 -0.8255 +vn -0.7155 0.1628 -0.6794 +vn -0.9764 0.1896 -0.1032 +vn -0.1501 0.0695 -0.9862 +vn 0.1743 -0.2426 -0.9543 +vn 0.0147 -0.0090 -0.9999 +vn -0.0050 0.0288 -0.9996 +vn 0.1604 -0.2070 -0.9651 +vn -0.0049 0.0308 -0.9995 +vn 0.1568 -0.1892 -0.9693 +vn -0.3080 -0.7571 -0.5762 +vn -0.3572 -0.9301 -0.0856 +vn -0.1114 -0.2057 -0.9722 +vn -0.3079 -0.7569 -0.5764 +vn -0.0876 -0.2132 -0.9731 +vn -0.2338 -0.7814 -0.5786 +vn -0.2338 -0.7812 -0.5788 +vn -0.2688 -0.9591 -0.0885 +vn 0.8312 -0.5490 -0.0873 +vn 0.6901 -0.4379 -0.5761 +vn 0.7468 -0.3416 -0.5706 +vn 0.8972 -0.4337 -0.0831 +vn 0.6902 -0.4379 -0.5761 +vn 0.2141 -0.1083 -0.9708 +vn 0.2372 -0.0791 -0.9682 +vn 0.7469 -0.3417 -0.5704 +vn 0.1597 -0.7933 -0.5875 +vn 0.2006 -0.9749 -0.0970 +vn 0.0379 -0.2157 -0.9757 +vn 0.1597 -0.7932 -0.5876 +vn 0.0614 -0.2143 -0.9748 +vn 0.2317 -0.7906 -0.5668 +vn 0.2316 -0.7907 -0.5667 +vn 0.2834 -0.9564 -0.0701 +vn 0.3004 -0.8220 -0.4838 +vn 0.3605 -0.9148 0.1822 +vn 0.0771 -0.2203 -0.9724 +vn 0.3003 -0.8219 -0.4840 +vn 0.0964 -0.2379 -0.9665 +vn 0.3445 -0.7994 -0.4922 +vn 0.3446 -0.7994 -0.4921 +vn 0.4616 -0.8808 0.1055 +vn -0.9806 -0.1915 -0.0417 +vn -0.8242 -0.1357 -0.5498 +vn -0.8312 -0.0734 -0.5511 +vn -0.9924 -0.1173 -0.0378 +vn -0.2774 -0.0063 -0.9607 +vn -0.2772 0.0143 -0.9607 +vn -0.8310 -0.0734 -0.5514 +vn 0.8448 0.0542 0.5323 +vn 0.2928 -0.0178 0.9560 +vn 0.9951 0.0923 0.0362 +vn 0.8448 0.0542 0.5324 +vn 0.4518 -0.7353 0.5052 +vn 0.1579 -0.2729 0.9490 +vn 0.5288 -0.8487 0.0002 +vn 0.4518 -0.7353 0.5053 +vn -0.9822 -0.1830 -0.0434 +vn -0.8243 -0.1258 -0.5520 +vn -0.8208 -0.1586 -0.5487 +vn -0.9749 -0.2184 -0.0428 +vn -0.8242 -0.1258 -0.5521 +vn -0.2789 -0.0101 -0.9603 +vn -0.2768 -0.0137 -0.9608 +vn -0.8206 -0.1585 -0.5491 +vn -0.8378 0.1390 -0.5280 +vn -0.9903 0.1361 -0.0266 +vn -0.2927 0.0793 -0.9529 +vn -0.2057 0.8304 -0.5179 +vn -0.2368 0.9716 0.0002 +vn -0.0767 0.3003 -0.9508 +vn -0.2057 0.8304 -0.5178 +vn 0.2803 0.7725 0.5698 +vn 0.1131 0.2316 0.9662 +vn 0.3237 0.9418 0.0912 +vn -0.2901 -0.8076 0.5134 +vn -0.0799 -0.2951 0.9521 +vn -0.3556 -0.9346 0.0104 +vn -0.2901 -0.8077 0.5132 +vn -0.0388 0.8634 -0.5031 +vn -0.0367 0.9993 -0.0015 +vn -0.0260 0.3198 -0.9471 +vn -0.0388 0.8634 -0.5030 +vn 0.7892 0.2815 -0.5459 +vn 0.9502 0.3076 -0.0495 +vn 0.2458 0.1287 -0.9607 +vn 0.7892 0.2815 -0.5458 +vn 0.2367 0.1547 -0.9592 +vn 0.7599 0.3604 -0.5409 +vn 0.7600 0.3604 -0.5409 +vn 0.9149 0.4013 -0.0446 +vn -0.0196 0.8512 -0.5245 +vn -0.0142 0.9999 -0.0023 +vn -0.0202 0.3141 -0.9492 +vn -0.5595 -0.6424 0.5237 +vn -0.1684 -0.2451 0.9548 +vn -0.6756 -0.7368 0.0250 +vn -0.5595 -0.6425 0.5236 +vn -0.5594 -0.6425 0.5237 +vn -0.6756 -0.7368 0.0251 +vn 0.2183 0.8158 -0.5355 +vn 0.2759 0.9612 -0.0078 +vn 0.0516 0.2780 -0.9592 +vn 0.2183 0.8159 -0.5354 +vn -0.7169 0.4623 -0.5218 +vn -0.8504 0.5261 -0.0102 +vn -0.2441 0.1853 -0.9519 +vn -0.7169 0.4623 -0.5219 +vn -0.3334 0.7955 -0.5060 +vn -0.3888 0.9213 -0.0020 +vn -0.1274 0.3033 -0.9443 +vn -0.3334 0.7954 -0.5061 +vn 0.7213 0.4363 -0.5379 +vn 0.8696 0.4922 -0.0397 +vn 0.2236 0.1795 -0.9580 +vn 0.7212 0.4364 -0.5380 +vn -0.1604 -0.7979 -0.5811 +vn -0.1813 -0.9792 -0.0908 +vn -0.0640 -0.2181 -0.9738 +vn -0.1604 -0.7977 -0.5813 +vn 0.5886 -0.8074 -0.0397 +vn 0.5067 -0.6692 -0.5435 +vn 0.5325 -0.6185 -0.5779 +vn 0.6394 -0.7639 -0.0873 +vn 0.5067 -0.6692 -0.5436 +vn 0.1589 -0.1675 -0.9730 +vn 0.1722 -0.1470 -0.9740 +vn 0.5794 -0.5683 -0.5842 +vn 0.5795 -0.5683 -0.5841 +vn 0.7011 -0.7071 -0.0922 +vn -0.8967 0.4412 0.0352 +vn -0.9652 0.2599 0.0279 +vn -0.9990 0.0415 0.0183 +vn -0.7572 -0.6529 -0.0180 +vn -0.8280 -0.5606 -0.0125 +vn -0.7572 -0.6529 -0.0179 +vn -0.8903 -0.4554 -0.0066 +vn -0.9032 0.4277 0.0347 +vn -0.5315 0.8457 0.0480 +vn -0.1774 0.9829 0.0486 +vn -0.5315 0.8457 0.0481 +vn 0.9796 -0.1993 -0.0253 +vn 0.9896 -0.1421 -0.0228 +vn 0.9994 0.0302 -0.0150 +vn 0.5349 0.8093 -0.2429 +vn 0.5451 0.7851 -0.2939 +vn 0.5349 0.8092 -0.2431 +vn 0.5788 0.8145 0.0399 +vn 0.5810 0.8138 0.0111 +vn 0.5451 0.7852 -0.2937 +vn 0.5808 0.8139 -0.0137 +vn 0.5609 0.8044 -0.1958 +vn 0.3672 0.5772 -0.7294 +vn 0.4925 0.7490 -0.4431 +vn 0.4954 0.8521 0.1686 +vn 0.4939 0.8665 0.0721 +vn 0.5602 0.8261 0.0618 +vn 0.5637 0.8177 0.1168 +vn 0.6856 0.7247 0.0689 +vn 0.6984 0.7002 0.1481 +vn 0.9054 0.4245 0.0049 +vn 0.7374 0.6752 0.0193 +vn 0.7373 0.6753 0.0193 +vn 0.5255 0.8502 0.0309 +vn -0.2661 0.9627 0.0491 +vn -0.0302 0.9984 0.0469 +vn 0.7326 0.6804 0.0196 +vn 0.9848 -0.1719 -0.0241 +vn 0.9915 0.1300 -0.0102 +vn 0.9776 0.2102 -0.0062 +vn 0.9954 0.0947 -0.0119 +vn 0.9995 -0.0259 -0.0176 +vn 0.7326 0.6804 0.0197 +vn 0.9991 -0.0393 -0.0182 +vn -0.9591 0.2817 0.0288 +vn -0.9302 0.3656 0.0322 +vn -0.9302 0.3656 0.0323 +vn -0.9028 0.4286 0.0347 +vn 0.9889 -0.1466 -0.0230 +vn 0.9564 -0.2905 -0.0292 +vn 0.8578 -0.5140 -0.0076 +vn 0.9066 -0.4206 -0.0344 +vn 0.9045 -0.4185 -0.0818 +vn 0.8661 -0.4998 0.0019 +vn 0.8733 -0.4869 -0.0176 +vn 0.9055 -0.4242 0.0100 +vn 0.3993 0.9161 0.0360 +vn 0.2354 0.9710 0.0413 +vn 0.3993 0.9161 0.0361 +vn -0.0530 0.9975 0.0473 +vn -0.0530 0.9975 0.0472 +vn 0.8991 -0.4364 -0.0350 +vn 0.8330 -0.5519 -0.0393 +vn -0.8778 0.4776 0.0365 +vn -0.8778 0.4775 0.0366 +vn -0.8536 0.5195 0.0381 +vn -0.8778 0.4776 0.0366 +vn -0.9386 -0.3451 -0.0007 +vn -0.9768 -0.2142 0.0061 +vn -0.9768 -0.2141 0.0060 +vn 0.8911 0.4537 0.0065 +vn 0.8324 0.5540 0.0121 +vn 0.8326 0.5537 0.0121 +vn 0.8327 0.5537 0.0121 +vn -0.0492 0.9968 0.0625 +vn 0.2912 0.9516 0.0983 +vn -0.0451 0.9969 0.0642 +vn 0.3198 0.9393 0.1243 +vn 0.4409 0.8916 0.1036 +vn -0.0425 0.9977 0.0523 +vn 0.3244 0.9438 0.0638 +vn 0.0072 0.9989 0.0463 +vn -0.2595 0.9645 0.0491 +vn -0.5136 0.8567 0.0483 +vn -0.5136 0.8567 0.0482 +vn 0.0072 0.9989 0.0464 +vn 0.1633 0.9856 0.0431 +vn 0.3530 0.9349 0.0377 +vn 0.1633 0.9856 0.0432 +vn 0.9659 0.2589 -0.0038 +vn -0.5931 -0.8047 -0.0277 +vn -0.6772 -0.7355 -0.0230 +vn -0.6772 -0.7354 -0.0231 +vn -0.6772 -0.7355 -0.0231 +vn -0.5931 -0.8047 -0.0278 +vn -0.6772 -0.7355 -0.0232 +vn 0.1250 -0.9910 -0.0482 +vn 0.0622 -0.9969 -0.0474 +vn 0.1250 -0.9910 -0.0481 +vn 0.0049 -0.9989 -0.0465 +vn 0.1250 -0.9910 -0.0480 +vn 0.0622 -0.9969 -0.0473 +vn 0.0049 -0.9989 -0.0466 +vn -0.9981 -0.0595 0.0136 +vn -0.9969 0.0758 0.0199 +vn -0.9969 0.0758 0.0198 +vn 0.4388 -0.8979 0.0348 +vn 0.3643 -0.9313 -0.0051 +vn 0.4473 -0.8935 -0.0396 +vn 0.3647 -0.9301 -0.0446 +vn 0.2851 -0.9573 -0.0484 +vn 0.2849 -0.9576 -0.0431 +vn 0.4484 -0.8925 -0.0488 +vn 0.3651 -0.9297 -0.0492 +vn 0.2851 -0.9572 -0.0491 +vn -0.9827 0.1833 0.0246 +vn 0.5877 -0.8084 -0.0338 +vn 0.5266 -0.8497 0.0269 +vn 0.5155 -0.8156 0.2629 +vn 0.5874 -0.8080 -0.0457 +vn 0.5285 -0.8479 -0.0413 +vn 0.5874 -0.8079 -0.0472 +vn 0.5287 -0.8475 -0.0480 +vn -0.2683 -0.9625 -0.0404 +vn -0.3568 -0.9334 -0.0376 +vn -0.2683 -0.9625 -0.0403 +vn -0.3568 -0.9334 -0.0375 +vn -0.4409 -0.8969 -0.0345 +vn -0.9928 -0.1196 0.0107 +vn -0.9810 -0.1938 0.0071 +vn -0.9810 -0.1938 0.0070 +vn 0.2017 -0.9782 -0.0488 +vn -0.7288 0.6834 0.0437 +vn -0.8902 0.4542 0.0357 +vn -0.9742 0.2243 0.0264 +vn -0.9945 0.1022 0.0210 +vn -0.1305 0.9903 0.0481 +vn 0.0595 0.9972 0.0454 +vn -0.1305 0.9903 0.0482 +vn 0.0646 0.9969 0.0453 +vn 0.7673 -0.6399 -0.0423 +vn 0.7656 -0.6368 -0.0907 +vn 0.7025 -0.7103 -0.0445 +vn 0.7656 -0.6369 -0.0907 +vn 0.7025 -0.7103 -0.0446 +vn -0.9823 -0.1869 0.0074 +vn -0.8475 0.5295 0.0384 +vn -0.8443 0.5346 -0.0362 +vn -0.8475 0.5294 0.0385 +vn -0.9823 -0.1869 0.0073 +vn -0.8419 0.5277 0.1132 +vn -0.9908 0.1334 0.0224 +vn -0.2360 0.9705 0.0490 +vn -0.2172 0.9749 0.0489 +vn -0.4290 0.9020 0.0489 +vn -0.4290 0.9020 0.0490 +vn -0.5039 0.8624 0.0484 +vn -0.5039 0.8624 0.0483 +vn -0.0497 -0.9977 -0.0456 +vn -0.1069 -0.9933 -0.0444 +vn -0.0497 -0.9977 -0.0455 +vn -0.1069 -0.9933 -0.0445 +vn -0.0360 0.9982 0.0470 +vn 0.9167 0.3995 0.0036 +vn 0.9521 0.3057 -0.0014 +vn -0.0137 0.9988 0.0466 +vn -0.0137 0.9988 0.0467 +vn -0.5173 -0.8552 -0.0313 +vn 0.2770 0.9600 0.0401 +vn -0.8506 0.5244 0.0383 +vn -0.3889 0.9200 0.0491 +vn -0.3889 0.9200 0.0492 +vn 0.8714 0.4906 0.0085 +vn -0.1807 -0.9826 -0.0427 +vn 0.6403 -0.7668 -0.0449 +vn 0.6403 -0.7667 -0.0460 +vn 0.6403 -0.7667 -0.0461 +vn 0.6338 -0.5104 -0.5812 +vn 0.1926 -0.1297 -0.9727 +vn 0.6337 -0.5104 -0.5814 +vn 0.6338 -0.5104 -0.5811 +vn -0.0074 -0.0351 0.9994 +vn -0.0060 -0.0327 0.9994 +vn -0.0052 -0.0333 0.9994 +vn 0.0188 -0.0072 0.9998 +vn 0.0189 -0.0064 0.9998 +vn 0.0147 -0.0088 0.9999 +vn -0.0095 -0.0514 0.9986 +vn -0.0101 -0.0495 0.9987 +vn -0.0100 -0.0453 0.9989 +vn 0.0362 -0.0116 0.9993 +vn 0.0301 -0.0079 0.9995 +vn 0.0147 -0.0056 0.9999 +vn -0.0094 -0.0395 0.9992 +vn -0.0034 -0.0127 0.9999 +vn 0.0005 -0.0127 0.9999 +vn 0.0084 -0.0111 0.9999 +vn -0.0085 -0.0516 0.9986 +vn -0.0088 -0.0520 0.9986 +vn 0.0248 -0.0332 0.9991 +vn 0.0333 -0.0320 0.9989 +vn 0.0410 -0.0354 0.9985 +vn 0.0164 -0.0337 0.9993 +vn 0.0199 -0.0338 0.9992 +vn 0.0165 -0.0460 0.9988 +vn 0.0421 -0.0610 0.9973 +vn 0.0473 -0.0438 0.9979 +vn 0.0406 -0.0192 0.9990 +vn 0.0447 -0.0425 0.9981 +vn 0.0435 -0.0506 0.9978 +vn -0.0050 -0.0348 0.9994 +vn -0.0053 -0.0362 0.9993 +vn -0.0059 -0.0378 0.9993 +vn -0.0067 -0.0399 0.9992 +vn -0.0082 -0.0582 0.9983 +vn -0.0035 -0.0593 0.9982 +vn 0.0001 -0.0600 0.9982 +vn 0.0119 -0.0623 0.9980 +vn 0.0134 -0.0626 0.9979 +vn 0.0146 -0.0628 0.9979 +vn 0.0052 -0.0613 0.9981 +vn 0.0070 -0.0616 0.9981 +vn 0.0086 -0.0619 0.9980 +vn 0.0155 -0.0630 0.9979 +vn 0.0164 -0.0630 0.9979 +vn -0.0096 -0.0450 0.9989 +vn -0.0140 -0.0491 0.9987 +vn -0.0155 -0.0536 0.9984 +vn 0.0377 -0.0322 0.9988 +vn 0.0389 -0.0316 0.9987 +vn 0.0176 -0.0457 0.9988 +vn 0.0410 -0.0342 0.9986 +vn 0.0346 -0.0319 0.9989 +vn 0.0140 -0.0222 0.9997 +vn 0.0098 -0.0229 0.9997 +vn 0.0428 -0.0456 0.9980 +vn 0.0430 -0.0501 0.9978 +vn 0.0177 -0.0466 0.9988 +vn 0.0423 -0.0517 0.9978 +vn 0.0176 -0.0467 0.9988 +vn 0.0205 -0.0221 0.9995 +vn 0.0154 -0.0235 0.9996 +vn 0.0122 -0.0241 0.9996 +vn 0.0427 -0.0396 0.9983 +vn 0.0152 -0.0226 0.9996 +vn 0.0218 -0.0226 0.9995 +vn 0.0265 -0.0225 0.9994 +vn 0.0427 -0.0489 0.9979 +vn -0.0085 -0.0343 0.9994 +vn -0.0004 -0.0319 0.9995 +vn 0.0081 -0.0334 0.9994 +vn 0.0130 -0.0338 0.9993 +vn -0.0141 -0.0353 0.9993 +vn -0.0159 -0.0425 0.9990 +vn -0.0149 -0.0431 0.9990 +vn -0.0132 -0.0396 0.9991 +vn 0.0385 -0.0369 0.9986 +vn 0.0377 -0.0344 0.9987 +vn 0.0406 -0.0414 0.9983 +vn 0.0394 -0.0391 0.9985 +vn 0.0314 -0.0613 0.9976 +vn 0.0342 -0.0607 0.9976 +vn 0.0380 -0.0600 0.9975 +vn 0.0184 -0.0628 0.9979 +vn 0.0213 -0.0627 0.9978 +vn 0.0167 -0.0470 0.9988 +vn 0.0276 -0.0618 0.9977 +vn 0.0174 -0.0629 0.9979 +vn 0.0479 -0.0558 0.9973 +vn 0.0470 -0.0515 0.9976 +vn 0.0445 -0.0476 0.9979 +vn 0.0382 -0.0137 0.9992 +vn 0.0103 -0.0621 0.9980 +vn 0.0003 -0.0095 1.0000 +vn 0.0028 -0.0607 0.9982 +vn 0.0157 -0.0086 0.9998 +vn -0.0126 -0.0564 0.9983 +vn -0.0078 -0.0423 0.9991 +vn 0.0425 -0.0443 0.9981 +vn 0.0002 -0.0245 0.9997 +vn 0.0228 -0.0626 0.9978 +vn 0.0107 -0.0224 0.9997 +vn 0.0437 -0.0587 0.9973 +vn 0.0253 -0.0227 0.9994 +vn 0.0293 -0.0616 0.9977 +vn -0.0379 0.0595 -0.9975 +vn -0.0387 0.0601 -0.9974 +vn -0.0402 0.0579 -0.9975 +vn -0.0181 0.0841 -0.9963 +vn -0.0137 0.0864 -0.9962 +vn -0.0138 0.0856 -0.9962 +vn -0.0427 0.0476 -0.9980 +vn -0.0427 0.0434 -0.9981 +vn -0.0177 0.0463 -0.9988 +vn -0.0422 0.0414 -0.9983 +vn -0.0172 0.0840 -0.9963 +vn -0.0001 0.0833 -0.9965 +vn 0.0556 0.1547 -0.9864 +vn -0.0418 0.0531 -0.9977 +vn -0.0177 0.0468 -0.9987 +vn -0.0243 0.0817 -0.9964 +vn -0.0322 0.0801 -0.9963 +vn -0.0360 0.0801 -0.9961 +vn -0.0412 0.0413 -0.9983 +vn -0.0385 0.0606 -0.9974 +vn -0.2383 0.1495 -0.9596 +vn 0.0081 0.0574 -0.9983 +vn 0.0006 0.0609 -0.9981 +vn 0.0072 0.0331 -0.9994 +vn 0.0085 0.0355 -0.9993 +vn -0.0151 0.0459 -0.9988 +vn 0.2238 -0.0635 -0.9726 +vn 0.0108 0.0421 -0.9991 +vn 0.0118 0.0502 -0.9987 +vn -0.0380 0.0567 -0.9977 +vn -0.0377 0.0580 -0.9976 +vn -0.0397 0.0529 -0.9978 +vn -0.0386 0.0551 -0.9977 +vn -0.0326 0.0363 -0.9988 +vn -0.0298 0.0401 -0.9987 +vn -0.0181 0.0300 -0.9994 +vn -0.0193 0.0303 -0.9994 +vn -0.0241 0.0309 -0.9992 +vn -0.0256 0.0313 -0.9992 +vn -0.0275 0.0316 -0.9991 +vn 0.0083 0.0586 -0.9982 +vn 0.0061 0.0612 -0.9981 +vn 0.0049 0.0606 -0.9982 +vn -0.0228 0.0699 -0.9973 +vn -0.0186 0.0705 -0.9973 +vn 0.0020 0.0611 -0.9981 +vn 0.0096 0.0412 -0.9991 +vn 0.0103 0.0427 -0.9990 +vn 0.0104 0.0473 -0.9988 +vn -0.0205 0.0688 -0.9974 +vn -0.0173 0.0694 -0.9974 +vn -0.0124 0.0703 -0.9974 +vn 0.0100 0.0533 -0.9985 +vn -0.0062 0.0703 -0.9975 +vn -0.0111 0.0700 -0.9975 +vn -0.0175 0.0702 -0.9974 +vn 0.0101 0.0439 -0.9990 +vn -0.0245 0.0594 -0.9979 +vn -0.0331 0.0610 -0.9976 +vn -0.0412 0.0585 -0.9974 +vn -0.0163 0.0468 -0.9988 +vn -0.0165 0.0469 -0.9988 +vn -0.0475 0.0497 -0.9976 +vn -0.0486 0.0504 -0.9975 +vn -0.0469 0.0575 -0.9972 +vn -0.0460 0.0532 -0.9975 +vn 0.0050 0.0584 -0.9983 +vn 0.0058 0.0560 -0.9984 +vn 0.0067 0.0537 -0.9985 +vn 0.0079 0.0515 -0.9986 +vn 0.0052 0.0328 -0.9994 +vn 0.0014 0.0321 -0.9995 +vn -0.0015 0.0317 -0.9995 +vn -0.0114 0.0300 -0.9995 +vn -0.0143 0.0301 -0.9994 +vn -0.0153 0.0300 -0.9994 +vn 0.0118 0.0452 -0.9989 +vn 0.0143 0.0413 -0.9990 +vn 0.0151 0.0371 -0.9992 +vn -0.0319 0.0825 -0.9961 +vn -0.0299 0.0322 -0.9990 +vn -0.0170 0.0842 -0.9963 +vn -0.0202 0.0455 -0.9988 +vn -0.0307 0.0466 -0.9984 +vn -0.0365 0.0495 -0.9981 +vn 0.0098 0.0486 -0.9988 +vn -0.0199 0.0461 -0.9987 +vn -0.0324 0.0682 -0.9971 +vn -0.0141 0.0419 -0.9990 +vn -0.0220 0.0704 -0.9973 +vn 0.0109 0.0342 -0.9994 +vn -0.0073 0.0701 -0.9975 +vn -0.0036 0.0313 -0.9995 +vn 0.4144 0.7546 -0.5087 +vn 0.5097 0.8600 -0.0242 +vn 0.5515 0.8197 0.1548 +vn 0.5827 0.8121 0.0321 +vn 0.6009 0.7992 0.0128 +vn 0.8616 0.4436 0.2466 +vn 0.6038 0.7847 -0.1403 +vn 0.5736 0.8131 0.0997 +vn 0.5085 -0.7352 -0.4483 +vn 0.5084 -0.7351 -0.4484 +vn 0.4662 -0.7664 -0.4420 +vn 0.4661 -0.7664 -0.4420 +vn 0.3327 -0.6385 -0.6940 +vn 0.3325 -0.6382 -0.6943 +vn 0.2183 0.4229 -0.8795 +vn 0.2183 0.4230 -0.8795 +vn 0.4468 0.6477 -0.6171 +vn 0.2808 0.4904 -0.8250 +vn 0.4467 0.6477 -0.6172 +vn 0.1474 0.2609 -0.9541 +vn 0.0144 0.0531 -0.9985 +vn -0.0417 0.0408 -0.9983 +vn 0.0419 -0.0572 0.9975 +vn 0.0179 -0.0471 0.9987 +vn 0.2662 -0.1529 0.9517 +vn -0.0060 -0.0320 0.9995 +vn -0.2066 0.0595 0.9766 +vn -0.9753 -0.2208 0.0057 +vn 0.6984 0.7002 0.1482 +vn 0.9944 0.0859 0.0620 +vn 0.9766 -0.0098 0.2148 +vn 0.9599 -0.2134 0.1818 +vn -0.7149 0.4657 -0.5215 +vn -0.7149 0.4656 -0.5217 +vn -0.7149 0.4657 -0.5216 +vn 0.7397 -0.3241 -0.5898 +vn 0.7398 -0.3241 -0.5896 +vn 0.7673 -0.3879 0.5106 +vn 0.7674 -0.3879 0.5106 +vn -0.6967 0.4141 0.5857 +vn -0.6967 0.4142 0.5857 +usemtl Scene_-_Root +s off +f 359/359/335 360/360/335 361/361/335 +f 359/359/335 361/361/335 362/362/335 +f 360/360/335 364/363/336 361/361/335 +f 361/361/335 365/364/337 366/365/335 +f 362/362/335 361/361/335 366/365/335 +f 362/362/335 366/365/335 367/366/335 +f 368/367/335 369/368/335 370/369/335 +f 368/367/335 370/369/335 371/370/335 +f 369/368/335 372/371/335 373/372/335 +f 369/368/335 373/372/335 370/369/335 +f 377/373/335 378/374/335 379/375/335 +f 377/373/335 379/375/335 380/376/335 +f 378/374/335 381/377/335 382/378/335 +f 378/374/335 382/378/335 379/375/335 +f 379/375/335 382/378/335 383/379/335 +f 379/375/335 383/379/335 384/380/335 +f 380/376/335 379/375/335 384/380/335 +f 380/376/335 384/380/335 385/381/335 +f 386/382/335 387/383/335 388/384/335 +f 386/382/335 388/384/335 389/385/335 +f 387/383/335 390/386/335 391/387/335 +f 387/383/335 391/387/335 388/384/335 +f 388/384/335 391/387/335 392/388/335 +f 388/384/335 392/388/335 393/389/335 +f 389/385/335 388/384/335 393/389/335 +f 389/385/335 393/389/335 394/390/335 +f 395/391/335 396/392/335 397/393/335 +f 395/391/338 397/393/338 398/394/338 +f 396/392/335 400/395/339 397/393/335 +f 397/393/338 401/396/340 402/397/338 +f 398/394/338 397/393/338 402/397/338 +f 398/394/335 402/397/335 403/398/335 +f 404/399/335 405/400/335 406/401/335 +f 404/399/338 406/401/338 407/402/338 +f 405/400/338 408/403/338 409/404/338 +f 405/400/335 409/404/335 406/401/335 +f 406/401/335 409/404/335 399/405/335 +f 406/401/335 399/405/335 396/392/335 +f 407/402/338 406/401/338 396/392/338 +f 407/402/335 396/392/335 395/391/335 +f 408/403/335 410/406/335 411/407/335 +f 408/403/335 411/407/335 409/404/335 +f 410/406/335 412/408/335 413/409/335 +f 410/406/335 413/409/335 411/407/335 +f 411/407/335 413/409/335 414/410/335 +f 411/407/335 414/410/335 415/411/335 +f 409/404/335 411/407/335 415/411/335 +f 409/404/335 415/411/341 399/405/342 +f 416/412/335 417/413/335 418/414/335 +f 416/412/335 418/414/335 419/415/335 +f 417/413/335 420/416/335 421/417/335 +f 417/413/335 421/417/335 418/414/335 +f 418/414/335 421/417/335 422/418/335 +f 418/414/335 422/418/335 423/419/335 +f 419/415/335 418/414/335 423/419/335 +f 419/415/335 423/419/335 424/420/335 +f 425/421/335 426/422/335 427/423/335 +f 425/421/335 427/423/335 428/424/335 +f 426/422/335 429/425/335 430/426/335 +f 426/422/335 430/426/335 427/423/335 +f 427/423/335 430/426/335 420/416/335 +f 427/423/335 420/416/335 417/413/335 +f 428/424/335 427/423/335 417/413/335 +f 428/424/335 417/413/335 416/412/335 +f 431/427/335 432/428/335 433/429/335 +f 431/427/335 433/429/335 434/430/335 +f 432/428/335 435/431/335 436/432/335 +f 432/428/335 436/432/335 433/429/335 +f 433/429/335 436/432/335 381/377/335 +f 433/429/335 381/377/335 378/374/335 +f 434/430/335 433/429/335 378/374/335 +f 434/430/335 378/374/335 377/373/335 +f 437/433/335 438/434/335 439/435/335 +f 437/433/335 439/435/335 440/436/335 +f 438/434/335 441/437/335 442/438/335 +f 438/434/335 442/438/335 439/435/335 +f 424/420/335 423/419/335 446/439/335 +f 424/420/335 446/439/335 447/440/335 +f 423/419/335 422/418/335 448/441/335 +f 423/419/335 448/441/335 446/439/335 +f 446/439/335 448/441/335 449/442/335 +f 446/439/338 449/442/338 450/443/338 +f 447/440/335 446/439/335 450/443/335 +f 447/440/335 450/443/335 451/444/335 +f 385/381/335 384/380/335 452/445/335 +f 385/381/335 452/445/335 453/446/335 +f 384/380/335 383/379/335 454/447/335 +f 384/380/335 454/447/335 452/445/335 +f 452/445/335 454/447/335 455/448/335 +f 452/445/335 455/448/335 456/449/335 +f 453/446/335 452/445/335 456/449/335 +f 453/446/335 456/449/335 457/450/335 +f 458/451/335 459/452/335 460/453/335 +f 458/451/335 460/453/335 461/454/335 +f 459/452/335 463/455/343 460/453/335 +f 403/398/335 402/397/335 467/456/335 +f 403/398/335 467/456/335 468/457/335 +f 402/397/335 469/458/344 467/456/335 +f 467/456/338 470/459/345 471/460/338 +f 468/457/335 467/456/335 471/460/335 +f 468/457/335 471/460/335 472/461/335 +f 473/462/335 474/463/335 475/464/335 +f 473/462/335 475/464/335 476/465/335 +f 474/463/335 477/466/335 478/467/335 +f 474/463/335 478/467/335 475/464/335 +f 475/464/335 478/467/335 479/468/335 +f 475/464/335 479/468/335 480/469/335 +f 476/465/335 475/464/335 480/469/335 +f 476/465/335 480/469/335 481/470/335 +f 482/471/338 483/472/338 484/473/338 +f 482/471/335 484/473/335 485/474/335 +f 483/472/335 435/431/335 486/475/335 +f 483/472/335 486/475/335 484/473/335 +f 484/473/335 486/475/335 477/466/335 +f 484/473/335 477/466/335 474/463/335 +f 485/474/335 484/473/335 474/463/335 +f 485/474/335 474/463/335 473/462/335 +f 431/427/335 487/476/335 488/477/335 +f 431/427/335 488/477/335 489/478/335 +f 487/476/335 429/425/335 490/479/335 +f 487/476/335 490/479/335 488/477/335 +f 488/477/335 490/479/335 491/480/335 +f 488/477/335 491/480/335 492/481/335 +f 489/478/335 488/477/335 492/481/335 +f 489/478/335 492/481/335 493/482/335 +f 494/483/335 495/484/335 496/485/335 +f 494/483/335 496/485/335 497/486/335 +f 495/484/335 498/487/335 499/488/335 +f 495/484/335 499/488/335 496/485/335 +f 496/485/335 499/488/335 390/386/335 +f 496/485/335 390/386/335 387/383/335 +f 497/486/335 496/485/335 387/383/335 +f 497/486/335 387/383/335 386/382/335 +f 500/489/335 501/490/335 502/491/335 +f 500/489/335 502/491/335 503/492/335 +f 501/490/335 505/493/346 502/491/335 +f 502/491/335 363/494/346 360/360/335 +f 503/492/335 502/491/335 360/360/335 +f 503/492/335 360/360/335 359/359/335 +f 493/482/335 492/481/335 506/495/335 +f 493/482/335 506/495/335 507/496/335 +f 492/481/335 491/480/335 508/497/335 +f 492/481/335 508/497/335 506/495/335 +f 506/495/335 508/497/335 509/498/335 +f 506/495/335 509/498/335 510/499/335 +f 507/496/335 506/495/335 510/499/335 +f 507/496/335 510/499/335 511/500/335 +f 512/501/335 513/502/335 514/503/335 +f 512/501/335 514/503/335 515/504/335 +f 513/502/335 516/505/335 517/506/335 +f 513/502/335 517/506/335 514/503/335 +f 521/507/335 522/508/335 523/509/335 +f 521/507/335 523/509/335 524/510/335 +f 522/508/335 525/511/335 526/512/335 +f 522/508/335 526/512/335 523/509/335 +f 530/513/335 531/514/335 532/515/335 +f 530/513/335 532/515/335 533/516/335 +f 531/514/335 535/517/347 532/515/335 +f 539/518/335 540/519/335 541/520/335 +f 539/518/335 541/520/335 542/521/335 +f 540/519/335 543/522/335 544/523/335 +f 540/519/335 544/523/335 541/520/335 +f 548/524/335 549/525/335 550/526/335 +f 548/524/335 550/526/335 551/527/335 +f 549/525/335 552/528/335 553/529/335 +f 549/525/335 553/529/335 550/526/335 +f 557/530/335 558/531/335 559/532/335 +f 557/530/335 559/532/335 560/533/335 +f 558/531/335 562/534/348 559/532/335 +f 559/532/338 563/535/349 564/536/338 +f 560/533/338 559/532/338 564/536/338 +f 560/533/335 564/536/335 565/537/335 +f 566/538/335 567/539/335 568/540/335 +f 566/538/335 568/540/335 569/541/335 +f 567/539/335 570/542/335 571/543/335 +f 567/539/335 571/543/335 568/540/335 +f 568/540/335 571/543/335 572/544/335 +f 568/540/335 572/544/335 573/545/335 +f 569/541/335 568/540/335 573/545/335 +f 569/541/335 573/545/335 574/546/335 +f 386/382/335 389/385/335 575/547/335 +f 386/382/335 575/547/335 576/548/335 +f 389/385/335 394/390/335 577/549/335 +f 389/385/335 577/549/335 575/547/335 +f 575/547/335 577/549/335 578/550/335 +f 575/547/335 578/550/335 579/551/335 +f 576/548/335 575/547/335 579/551/335 +f 576/548/335 579/551/335 580/552/335 +f 581/553/335 582/554/335 583/555/335 +f 581/553/335 583/555/335 584/556/335 +f 582/554/338 585/557/338 586/558/338 +f 582/554/335 586/558/335 583/555/335 +f 584/556/335 588/559/350 589/560/335 +f 590/561/335 591/562/335 592/563/335 +f 590/561/338 592/563/338 593/564/338 +f 591/562/335 581/553/335 584/556/335 +f 591/562/335 584/556/335 592/563/335 +f 592/563/335 584/556/335 589/560/351 +f 592/563/335 589/560/335 594/565/335 +f 593/564/335 592/563/335 594/565/335 +f 593/564/335 594/565/335 595/566/335 +f 595/566/335 594/565/335 596/567/335 +f 595/566/338 596/567/338 597/568/338 +f 594/565/335 589/560/335 598/569/335 +f 594/565/335 598/569/335 596/567/335 +f 596/567/335 598/569/335 414/410/335 +f 596/567/335 414/410/335 413/409/335 +f 597/568/335 596/567/335 413/409/335 +f 597/568/335 413/409/335 412/408/335 +f 599/570/335 600/571/335 601/572/335 +f 599/570/335 601/572/335 602/573/335 +f 600/571/335 603/574/335 604/575/335 +f 600/571/335 604/575/335 601/572/335 +f 601/572/335 604/575/335 605/576/335 +f 601/572/335 605/576/335 606/577/335 +f 602/573/335 601/572/335 606/577/335 +f 602/573/335 606/577/335 607/578/335 +f 608/579/335 609/580/335 610/581/335 +f 608/579/335 610/581/335 611/582/335 +f 609/580/335 599/570/335 602/573/335 +f 609/580/335 602/573/335 610/581/335 +f 610/581/335 602/573/335 607/578/335 +f 610/581/335 607/578/335 612/583/335 +f 611/582/335 610/581/335 612/583/335 +f 611/582/335 612/583/335 613/584/335 +f 614/585/335 615/586/335 616/587/335 +f 614/585/335 616/587/335 617/588/335 +f 615/586/335 566/538/335 569/541/335 +f 615/586/335 569/541/335 616/587/335 +f 616/587/335 569/541/335 574/546/335 +f 616/587/335 574/546/335 618/589/335 +f 617/588/335 616/587/335 618/589/335 +f 617/588/335 618/589/335 619/590/335 +f 620/591/335 621/592/335 622/593/335 +f 620/591/338 622/593/338 623/594/338 +f 621/592/335 625/595/352 622/593/335 +f 622/593/335 626/596/353 627/597/335 +f 623/594/335 622/593/335 627/597/335 +f 623/594/335 627/597/335 628/598/335 +f 603/574/335 629/599/335 630/600/335 +f 603/574/338 630/600/338 604/575/338 +f 629/599/335 631/601/335 632/602/335 +f 629/599/335 632/602/335 630/600/335 +f 630/600/335 632/602/335 633/603/335 +f 630/600/335 633/603/335 634/604/335 +f 604/575/335 630/600/335 634/604/335 +f 604/575/335 634/604/335 605/576/335 +f 570/542/335 635/605/335 636/606/335 +f 570/542/335 636/606/335 571/543/335 +f 635/605/335 637/607/335 638/608/335 +f 635/605/335 638/608/335 636/606/335 +f 636/606/335 638/608/335 639/609/335 +f 636/606/335 639/609/335 640/610/335 +f 571/543/335 636/606/335 640/610/335 +f 571/543/335 640/610/335 572/544/335 +f 641/611/335 642/612/335 643/613/335 +f 641/611/338 643/613/338 644/614/338 +f 642/612/335 646/615/354 643/613/335 +f 585/557/338 650/616/338 651/617/338 +f 585/557/338 651/617/338 586/558/338 +f 650/616/338 641/611/338 644/614/338 +f 650/616/338 644/614/338 651/617/338 +f 653/618/335 654/619/335 655/620/335 +f 653/618/335 655/620/335 656/621/335 +f 654/619/335 657/622/335 658/623/335 +f 654/619/335 658/623/335 655/620/335 +f 655/620/335 658/623/335 659/624/335 +f 655/620/335 659/624/335 660/625/335 +f 656/621/335 655/620/335 660/625/335 +f 656/621/335 660/625/335 661/626/335 +f 662/627/335 663/628/335 664/629/335 +f 662/627/335 664/629/335 665/630/335 +f 663/628/335 653/618/335 656/621/335 +f 663/628/335 656/621/335 664/629/335 +f 664/629/335 656/621/335 661/626/335 +f 664/629/335 661/626/335 666/631/335 +f 665/630/335 664/629/335 666/631/335 +f 665/630/335 666/631/335 619/590/335 +f 614/585/335 667/632/335 668/633/335 +f 614/585/335 668/633/335 669/634/335 +f 667/632/335 670/635/335 671/636/335 +f 667/632/335 671/636/335 668/633/335 +f 668/633/335 671/636/335 672/637/335 +f 668/633/335 672/637/335 673/638/335 +f 669/634/335 668/633/335 673/638/335 +f 669/634/335 673/638/335 613/584/335 +f 494/483/335 497/486/335 674/639/335 +f 494/483/335 674/639/335 675/640/335 +f 497/486/335 386/382/335 576/548/335 +f 497/486/335 576/548/335 674/639/335 +f 674/639/335 576/548/335 580/552/335 +f 674/639/335 580/552/335 676/641/335 +f 675/640/335 674/639/335 676/641/335 +f 675/640/335 676/641/335 677/642/335 +f 678/643/335 679/644/335 680/645/335 +f 678/643/335 680/645/335 681/646/335 +f 679/644/335 548/524/335 551/527/335 +f 679/644/335 551/527/335 680/645/335 +f 670/635/335 684/647/335 685/648/335 +f 670/635/335 685/648/335 671/636/335 +f 684/647/335 686/649/335 687/650/335 +f 684/647/335 687/650/335 685/648/335 +f 685/648/335 687/650/335 688/651/335 +f 685/648/335 688/651/335 689/652/335 +f 671/636/335 685/648/335 689/652/335 +f 671/636/335 689/652/335 672/637/335 +f 690/653/335 691/654/335 692/655/335 +f 690/653/335 692/655/335 693/656/335 +f 691/654/335 695/657/355 692/655/335 +f 692/655/335 696/658/356 697/659/335 +f 693/656/335 692/655/335 697/659/335 +f 693/656/335 697/659/335 698/660/335 +f 699/661/335 700/662/335 701/663/335 +f 699/661/335 701/663/335 702/664/335 +f 700/662/335 704/665/357 701/663/335 +f 701/663/335 705/666/358 706/667/335 +f 702/664/335 701/663/335 706/667/335 +f 702/664/335 706/667/335 707/668/335 +f 708/669/335 709/670/335 710/671/335 +f 708/669/335 710/671/335 711/672/335 +f 709/670/335 713/673/359 710/671/335 +f 539/518/335 542/521/335 717/674/335 +f 539/518/335 717/674/335 718/675/335 +f 542/521/335 719/676/360 717/674/335 +f 717/674/335 720/677/360 721/678/335 +f 718/675/335 717/674/335 721/678/335 +f 718/675/335 721/678/335 722/679/335 +f 543/522/335 723/680/335 724/681/335 +f 543/522/335 724/681/335 544/523/335 +f 723/680/335 512/501/335 515/504/335 +f 723/680/335 515/504/335 724/681/335 +f 498/487/335 726/682/335 727/683/335 +f 498/487/335 727/683/335 499/488/335 +f 726/682/335 482/471/335 485/474/335 +f 726/682/335 485/474/335 727/683/335 +f 727/683/335 485/474/335 473/462/335 +f 727/683/335 473/462/335 728/684/335 +f 499/488/335 727/683/335 728/684/335 +f 499/488/335 728/684/335 390/386/335 +f 390/386/335 728/684/335 729/685/335 +f 390/386/335 729/685/335 391/387/335 +f 728/684/335 473/462/335 476/465/335 +f 728/684/335 476/465/335 729/685/335 +f 729/685/335 476/465/335 481/470/335 +f 729/685/335 481/470/335 730/686/335 +f 391/387/335 729/685/335 730/686/335 +f 391/387/335 730/686/335 392/388/335 +f 383/379/335 731/687/335 732/688/335 +f 383/379/338 732/688/338 454/447/338 +f 731/687/338 733/689/338 734/690/338 +f 731/687/335 734/690/335 732/688/335 +f 732/688/335 734/690/335 735/691/335 +f 732/688/335 735/691/335 736/692/335 +f 454/447/338 732/688/338 736/692/338 +f 454/447/335 736/692/335 455/448/335 +f 372/371/335 737/693/335 738/694/335 +f 372/371/335 738/694/335 373/372/335 +f 737/693/335 458/451/335 461/454/335 +f 737/693/335 461/454/335 738/694/335 +f 435/431/335 483/472/335 740/695/335 +f 435/431/335 740/695/335 436/432/335 +f 483/472/338 482/471/338 741/696/338 +f 483/472/335 741/696/335 740/695/335 +f 740/695/335 741/696/335 742/697/335 +f 740/695/338 742/697/338 743/698/338 +f 436/432/335 740/695/335 743/698/335 +f 436/432/335 743/698/335 381/377/335 +f 381/377/335 743/698/335 744/699/335 +f 381/377/335 744/699/335 382/378/335 +f 743/698/338 742/697/338 745/700/338 +f 743/698/335 745/700/335 744/699/335 +f 744/699/335 745/700/335 733/689/335 +f 744/699/338 733/689/338 731/687/338 +f 382/378/335 744/699/335 731/687/335 +f 382/378/335 731/687/335 383/379/335 +f 516/505/335 746/701/335 747/702/335 +f 516/505/335 747/702/335 517/506/335 +f 746/701/335 521/507/335 524/510/335 +f 746/701/335 524/510/335 747/702/335 +f 477/466/335 749/703/335 750/704/335 +f 477/466/335 750/704/335 478/467/335 +f 749/703/335 493/482/335 507/496/335 +f 749/703/335 507/496/335 750/704/335 +f 750/704/335 507/496/335 511/500/335 +f 750/704/335 511/500/335 751/705/335 +f 478/467/335 750/704/335 751/705/335 +f 478/467/335 751/705/335 479/468/335 +f 435/431/335 432/428/335 752/706/335 +f 435/431/335 752/706/335 486/475/335 +f 432/428/335 431/427/335 489/478/335 +f 432/428/335 489/478/335 752/706/335 +f 752/706/335 489/478/335 493/482/335 +f 752/706/335 493/482/335 749/703/335 +f 486/475/335 752/706/335 749/703/335 +f 486/475/335 749/703/335 477/466/335 +f 422/418/335 753/707/335 754/708/335 +f 422/418/338 754/708/338 448/441/338 +f 753/707/335 385/381/335 453/446/335 +f 753/707/335 453/446/335 754/708/335 +f 754/708/335 453/446/335 457/450/335 +f 754/708/335 457/450/335 755/709/335 +f 448/441/338 754/708/338 755/709/338 +f 448/441/335 755/709/335 449/442/335 +f 429/425/335 487/476/335 756/710/335 +f 429/425/335 756/710/335 430/426/335 +f 487/476/335 431/427/335 434/430/335 +f 487/476/335 434/430/335 756/710/335 +f 756/710/335 434/430/335 377/373/335 +f 756/710/335 377/373/335 757/711/335 +f 430/426/335 756/710/335 757/711/335 +f 430/426/335 757/711/335 420/416/335 +f 420/416/335 757/711/335 758/712/335 +f 420/416/335 758/712/335 421/417/335 +f 757/711/335 377/373/335 380/376/335 +f 757/711/335 380/376/335 758/712/335 +f 758/712/335 380/376/335 385/381/335 +f 758/712/335 385/381/335 753/707/335 +f 421/417/335 758/712/335 753/707/335 +f 421/417/335 753/707/335 422/418/335 +f 441/437/335 759/713/335 760/714/335 +f 441/437/335 760/714/335 442/438/335 +f 759/713/335 368/367/335 371/370/335 +f 759/713/335 371/370/335 760/714/335 +f 525/511/335 762/715/335 763/716/335 +f 525/511/335 763/716/335 526/512/335 +f 762/715/335 530/513/335 533/516/335 +f 762/715/335 533/516/335 763/716/335 +f 429/425/335 426/422/335 765/717/335 +f 429/425/335 765/717/335 490/479/335 +f 426/422/335 425/421/335 766/718/335 +f 426/422/335 766/718/335 765/717/335 +f 765/717/335 766/718/335 767/719/335 +f 765/717/335 767/719/335 768/720/335 +f 490/479/335 765/717/335 768/720/335 +f 490/479/335 768/720/335 491/480/335 +f 769/721/361 770/722/335 771/723/335 +f 770/722/335 773/724/335 774/725/335 +f 770/722/338 774/725/338 771/723/338 +f 771/723/338 774/725/338 775/726/338 +f 771/723/335 775/726/335 776/727/335 +f 772/728/362 771/723/335 776/727/335 +f 778/729/363 779/730/335 780/731/335 +f 779/730/338 437/433/338 440/436/338 +f 779/730/335 440/436/335 780/731/335 +f 504/732/364 501/490/335 784/733/335 +f 501/490/335 500/489/335 786/734/335 +f 501/490/338 786/734/338 784/733/338 +f 784/733/338 786/734/338 787/735/338 +f 784/733/335 787/735/335 788/736/335 +f 785/737/365 784/733/335 788/736/335 +f 789/738/366 788/736/335 790/739/335 +f 788/736/335 787/735/335 792/740/335 +f 788/736/335 792/740/335 790/739/335 +f 790/739/335 792/740/335 773/724/335 +f 790/739/335 773/724/335 770/722/335 +f 791/741/367 790/739/335 770/722/335 +f 491/480/335 768/720/335 793/742/335 +f 491/480/335 793/742/335 508/497/335 +f 768/720/335 767/719/335 794/743/335 +f 768/720/335 794/743/335 793/742/335 +f 793/742/335 794/743/335 795/744/335 +f 793/742/335 795/744/335 796/745/335 +f 508/497/335 793/742/335 796/745/335 +f 508/497/335 796/745/335 509/498/335 +f 509/498/335 796/745/335 797/746/335 +f 509/498/335 797/746/335 798/747/335 +f 796/745/335 795/744/335 799/748/335 +f 796/745/335 799/748/335 797/746/335 +f 797/746/335 799/748/335 800/749/335 +f 797/746/335 800/749/335 801/750/335 +f 798/747/335 797/746/335 801/750/335 +f 798/747/335 801/750/335 802/751/335 +f 479/468/335 751/705/335 803/752/335 +f 479/468/335 803/752/335 804/753/335 +f 751/705/335 511/500/335 805/754/335 +f 751/705/335 805/754/335 803/752/335 +f 803/752/335 805/754/335 806/755/335 +f 803/752/335 806/755/335 807/756/335 +f 804/753/335 803/752/335 807/756/335 +f 804/753/335 807/756/335 808/757/335 +f 392/388/335 730/686/335 809/758/335 +f 392/388/335 809/758/335 810/759/335 +f 730/686/335 481/470/335 811/760/335 +f 730/686/335 811/760/335 809/758/335 +f 809/758/335 811/760/335 812/761/335 +f 809/758/335 812/761/335 813/762/335 +f 810/759/335 809/758/335 813/762/335 +f 810/759/335 813/762/335 814/763/335 +f 394/390/335 815/764/335 816/765/335 +f 394/390/335 816/765/335 577/549/335 +f 815/764/335 817/766/335 818/767/335 +f 815/764/335 818/767/335 816/765/335 +f 816/765/335 818/767/335 819/768/335 +f 816/765/335 819/768/335 820/769/335 +f 577/549/335 816/765/335 820/769/335 +f 577/549/335 820/769/335 578/550/335 +f 552/528/335 821/770/335 822/771/335 +f 552/528/335 822/771/335 553/529/335 +f 821/770/335 708/669/335 711/672/335 +f 821/770/335 711/672/335 822/771/335 +f 686/649/335 824/772/335 825/773/335 +f 686/649/335 825/773/335 687/650/335 +f 824/772/335 826/774/335 827/775/335 +f 824/772/335 827/775/335 825/773/335 +f 825/773/335 827/775/335 828/776/335 +f 825/773/335 828/776/335 829/777/335 +f 687/650/335 825/773/335 829/777/335 +f 687/650/335 829/777/335 688/651/335 +f 657/622/335 830/778/335 831/779/335 +f 657/622/335 831/779/335 658/623/335 +f 830/778/335 832/780/335 833/781/335 +f 830/778/335 833/781/335 831/779/335 +f 831/779/335 833/781/335 834/782/335 +f 831/779/335 834/782/335 835/783/335 +f 658/623/335 831/779/335 835/783/335 +f 658/623/335 835/783/335 659/624/335 +f 394/390/335 393/389/335 836/784/335 +f 394/390/335 836/784/335 815/764/335 +f 393/389/335 392/388/335 810/759/335 +f 393/389/335 810/759/335 836/784/335 +f 836/784/335 810/759/335 814/763/335 +f 836/784/335 814/763/335 837/785/335 +f 815/764/335 836/784/335 837/785/335 +f 815/764/335 837/785/335 817/766/335 +f 367/366/335 366/365/335 838/786/335 +f 367/366/335 838/786/335 839/787/335 +f 366/365/335 840/788/368 838/786/335 +f 838/786/335 534/789/369 531/514/335 +f 839/787/335 838/786/335 531/514/335 +f 839/787/335 531/514/335 530/513/335 +f 511/500/335 510/499/335 841/790/335 +f 511/500/335 841/790/335 805/754/335 +f 510/499/335 509/498/335 798/747/335 +f 510/499/335 798/747/335 841/790/335 +f 841/790/335 798/747/335 802/751/335 +f 841/790/335 802/751/335 842/791/335 +f 805/754/335 841/790/335 842/791/335 +f 805/754/335 842/791/335 806/755/335 +f 481/470/335 480/469/335 843/792/335 +f 481/470/335 843/792/335 811/760/335 +f 480/469/335 479/468/335 804/753/335 +f 480/469/335 804/753/335 843/792/335 +f 843/792/335 804/753/335 808/757/335 +f 843/792/335 808/757/335 844/793/335 +f 811/760/335 843/792/335 844/793/335 +f 811/760/335 844/793/335 812/761/335 +f 578/550/335 820/769/335 845/794/335 +f 578/550/335 845/794/335 846/795/335 +f 820/769/335 819/768/335 847/796/335 +f 820/769/335 847/796/335 845/794/335 +f 845/794/335 847/796/335 832/780/335 +f 845/794/335 832/780/335 830/778/335 +f 846/795/335 845/794/335 830/778/335 +f 846/795/335 830/778/335 657/622/335 +f 722/679/335 721/678/335 848/797/335 +f 722/679/335 848/797/335 849/798/335 +f 721/678/335 850/799/360 848/797/335 +f 848/797/335 694/800/355 691/654/335 +f 849/798/335 848/797/335 691/654/335 +f 849/798/335 691/654/335 690/653/335 +f 677/642/335 676/641/335 851/801/335 +f 677/642/335 851/801/335 852/802/335 +f 676/641/335 580/552/335 853/803/335 +f 676/641/335 853/803/335 851/801/335 +f 851/801/335 853/803/335 653/618/335 +f 851/801/335 653/618/335 663/628/335 +f 852/802/335 851/801/335 663/628/335 +f 852/802/335 663/628/335 662/627/335 +f 580/552/335 579/551/335 854/804/335 +f 580/552/335 854/804/335 853/803/335 +f 579/551/335 578/550/335 846/795/335 +f 579/551/335 846/795/335 854/804/335 +f 854/804/335 846/795/335 657/622/335 +f 854/804/335 657/622/335 654/619/335 +f 853/803/335 854/804/335 654/619/335 +f 853/803/335 654/619/335 653/618/335 +f 572/544/335 640/610/335 855/805/335 +f 572/544/335 855/805/335 856/806/335 +f 640/610/335 639/609/335 857/807/335 +f 640/610/335 857/807/335 855/805/335 +f 855/805/335 857/807/335 858/808/335 +f 855/805/335 858/808/335 859/809/335 +f 856/806/335 855/805/335 859/809/335 +f 856/806/335 859/809/335 860/810/335 +f 565/537/335 564/536/335 861/811/335 +f 565/537/338 861/811/338 862/812/338 +f 564/536/335 863/813/370 861/811/335 +f 861/811/338 645/814/371 642/612/338 +f 862/812/338 861/811/338 642/612/338 +f 862/812/335 642/612/335 641/611/335 +f 619/590/335 618/589/335 864/815/335 +f 619/590/335 864/815/335 665/630/335 +f 618/589/338 574/546/338 865/816/338 +f 618/589/335 865/816/335 864/815/335 +f 864/815/335 865/816/335 866/817/335 +f 864/815/338 866/817/338 867/818/338 +f 665/630/338 864/815/338 867/818/338 +f 665/630/335 867/818/335 662/627/335 +f 574/546/335 573/545/335 868/819/335 +f 574/546/338 868/819/338 865/816/338 +f 573/545/335 572/544/335 856/806/335 +f 573/545/335 856/806/335 868/819/335 +f 868/819/335 856/806/335 860/810/335 +f 868/819/335 860/810/335 869/820/335 +f 865/816/335 868/819/335 869/820/335 +f 865/816/335 869/820/335 866/817/335 +f 688/651/335 829/777/335 870/821/335 +f 688/651/335 870/821/335 871/822/335 +f 829/777/335 828/776/335 872/823/335 +f 829/777/335 872/823/335 870/821/335 +f 870/821/335 872/823/335 873/824/335 +f 870/821/335 873/824/335 874/825/335 +f 871/822/335 870/821/335 874/825/335 +f 871/822/335 874/825/335 875/826/335 +f 707/668/335 706/667/335 876/827/335 +f 707/668/335 876/827/335 877/828/335 +f 706/667/335 878/829/372 876/827/335 +f 876/827/335 712/830/373 709/670/335 +f 877/828/335 876/827/335 709/670/335 +f 877/828/335 709/670/335 708/669/335 +f 613/584/335 673/638/335 879/831/335 +f 613/584/335 879/831/335 611/582/335 +f 673/638/335 672/637/335 880/832/335 +f 673/638/335 880/832/335 879/831/335 +f 879/831/335 880/832/335 881/833/335 +f 879/831/335 881/833/335 882/834/335 +f 611/582/335 879/831/335 882/834/335 +f 611/582/335 882/834/335 608/579/335 +f 883/835/374 884/836/375 885/837/335 +f 883/835/376 885/837/338 886/838/338 +f 884/836/375 887/839/377 888/840/335 +f 884/836/375 888/840/335 885/837/335 +f 885/837/335 888/840/335 620/591/335 +f 885/837/335 620/591/335 889/841/335 +f 886/838/335 885/837/335 889/841/335 +f 886/838/335 889/841/335 890/842/335 +f 887/839/377 891/843/378 892/844/335 +f 887/839/377 892/844/335 888/840/335 +f 891/843/378 894/845/379 892/844/335 +f 892/844/335 624/846/380 621/592/335 +f 888/840/338 892/844/338 621/592/338 +f 888/840/335 621/592/335 620/591/335 +f 683/847/381 895/848/382 896/849/335 +f 683/847/381 896/849/335 681/646/335 +f 895/848/383 897/850/384 898/851/335 +f 895/848/383 898/851/335 896/849/335 +f 896/849/335 898/851/335 899/852/335 +f 896/849/335 899/852/335 900/853/335 +f 681/646/335 896/849/335 900/853/335 +f 681/646/335 900/853/335 678/643/335 +f 897/850/384 901/854/385 902/855/335 +f 897/850/384 902/855/335 898/851/335 +f 901/854/385 883/835/376 886/838/338 +f 901/854/385 886/838/335 902/855/335 +f 902/855/335 886/838/335 890/842/335 +f 902/855/335 890/842/335 903/856/335 +f 898/851/335 902/855/335 903/856/335 +f 898/851/335 903/856/335 899/852/335 +f 672/637/335 689/652/335 904/857/335 +f 672/637/335 904/857/335 880/832/335 +f 689/652/335 688/651/335 871/822/335 +f 689/652/335 871/822/335 904/857/335 +f 904/857/335 871/822/335 875/826/335 +f 904/857/335 875/826/335 905/858/335 +f 880/832/335 904/857/335 905/858/335 +f 880/832/335 905/858/335 881/833/335 +f 659/624/335 835/783/335 906/859/335 +f 659/624/335 906/859/335 907/860/335 +f 835/783/335 834/782/335 908/861/335 +f 835/783/335 908/861/335 906/859/335 +f 906/859/335 908/861/335 826/774/335 +f 906/859/335 826/774/335 824/772/335 +f 907/860/335 906/859/335 824/772/335 +f 907/860/335 824/772/335 686/649/335 +f 698/660/335 697/659/335 909/862/335 +f 698/660/335 909/862/335 910/863/335 +f 697/659/335 911/864/386 909/862/335 +f 909/862/335 703/865/386 700/662/335 +f 910/863/335 909/862/335 700/662/335 +f 910/863/335 700/662/335 699/661/335 +f 661/626/335 660/625/335 912/866/335 +f 661/626/335 912/866/335 913/867/335 +f 660/625/335 659/624/335 907/860/335 +f 660/625/335 907/860/335 912/866/335 +f 912/866/335 907/860/335 686/649/335 +f 912/866/335 686/649/335 684/647/335 +f 913/867/335 912/866/335 684/647/335 +f 913/867/335 684/647/335 670/635/335 +f 619/590/335 666/631/335 914/868/335 +f 619/590/335 914/868/335 617/588/335 +f 666/631/335 661/626/335 913/867/335 +f 666/631/335 913/867/335 914/868/335 +f 914/868/335 913/867/335 670/635/335 +f 914/868/335 670/635/335 667/632/335 +f 617/588/335 914/868/335 667/632/335 +f 617/588/335 667/632/335 614/585/335 +f 605/576/335 634/604/335 915/869/335 +f 605/576/335 915/869/335 916/870/335 +f 634/604/335 633/603/335 917/871/335 +f 634/604/335 917/871/335 915/869/335 +f 915/869/335 917/871/335 637/607/335 +f 915/869/335 637/607/335 635/605/335 +f 916/870/335 915/869/335 635/605/335 +f 916/870/335 635/605/335 570/542/335 +f 613/584/335 612/583/335 918/872/335 +f 613/584/335 918/872/335 669/634/335 +f 612/583/335 607/578/335 919/873/335 +f 612/583/335 919/873/335 918/872/335 +f 918/872/335 919/873/335 566/538/335 +f 918/872/335 566/538/335 615/586/335 +f 669/634/335 918/872/335 615/586/335 +f 669/634/335 615/586/335 614/585/335 +f 607/578/335 606/577/335 920/874/335 +f 607/578/335 920/874/335 919/873/335 +f 606/577/335 605/576/335 916/870/335 +f 606/577/335 916/870/335 920/874/335 +f 920/874/335 916/870/335 570/542/335 +f 920/874/335 570/542/335 567/539/335 +f 919/873/335 920/874/335 567/539/335 +f 919/873/335 567/539/335 566/538/335 +f 628/598/335 627/597/335 921/875/335 +f 628/598/335 921/875/335 922/876/335 +f 627/597/335 923/877/387 921/875/335 +f 921/875/335 561/878/388 558/531/335 +f 922/876/335 921/875/335 558/531/335 +f 922/876/335 558/531/335 557/530/335 +f 924/879/389 925/880/389 926/881/389 +f 924/879/389 926/881/389 927/882/389 +f 925/880/389 928/883/389 929/884/389 +f 925/880/389 929/884/389 926/881/389 +f 933/885/389 934/886/389 935/887/389 +f 933/885/389 935/887/389 936/888/389 +f 934/886/390 938/889/391 935/887/390 +f 935/887/389 939/890/392 940/891/389 +f 936/888/389 935/887/389 940/891/393 +f 936/888/389 940/891/389 941/892/389 +f 942/893/389 943/894/389 944/895/389 +f 942/893/389 944/895/389 945/896/389 +f 943/894/389 946/897/389 947/898/389 +f 943/894/389 947/898/389 944/895/389 +f 944/895/389 947/898/389 948/899/389 +f 944/895/389 948/899/389 949/900/389 +f 945/896/389 944/895/389 949/900/389 +f 945/896/389 949/900/389 950/901/389 +f 951/902/389 952/903/389 953/904/389 +f 951/902/389 953/904/389 954/905/389 +f 952/903/389 955/906/389 956/907/389 +f 952/903/389 956/907/389 953/904/389 +f 953/904/389 956/907/389 957/908/389 +f 953/904/389 957/908/389 958/909/389 +f 954/905/389 953/904/389 958/909/389 +f 954/905/389 958/909/389 959/910/389 +f 960/911/389 961/912/389 962/913/389 +f 960/911/389 962/913/389 963/914/389 +f 961/912/389 964/915/389 965/916/389 +f 961/912/389 965/916/389 962/913/389 +f 963/914/389 967/917/394 968/918/389 +f 969/919/389 970/920/389 971/921/389 +f 969/919/389 971/921/389 972/922/389 +f 970/920/389 960/911/389 963/914/389 +f 970/920/389 963/914/389 971/921/389 +f 971/921/389 963/914/389 968/918/393 +f 971/921/389 968/918/389 973/923/389 +f 972/922/389 971/921/389 973/923/389 +f 972/922/389 973/923/389 974/924/389 +f 974/924/389 973/923/389 975/925/389 +f 974/924/389 975/925/389 976/926/389 +f 973/923/389 968/918/389 977/927/389 +f 973/923/389 977/927/389 975/925/389 +f 975/925/389 977/927/389 978/928/389 +f 975/925/389 978/928/389 979/929/389 +f 976/926/389 975/925/389 979/929/389 +f 976/926/389 979/929/389 980/930/389 +f 981/931/389 982/932/389 983/933/389 +f 981/931/389 983/933/389 984/934/389 +f 982/932/389 985/935/389 986/936/389 +f 982/932/389 986/936/389 983/933/389 +f 983/933/389 986/936/389 987/937/389 +f 983/933/389 987/937/389 988/938/389 +f 984/934/389 983/933/389 988/938/389 +f 984/934/389 988/938/389 989/939/389 +f 990/940/389 991/941/389 992/942/389 +f 990/940/389 992/942/389 993/943/389 +f 991/941/389 981/931/389 984/934/389 +f 991/941/389 984/934/389 992/942/389 +f 992/942/389 984/934/389 989/939/389 +f 992/942/389 989/939/389 994/944/389 +f 993/943/389 992/942/389 994/944/389 +f 993/943/389 994/944/389 995/945/389 +f 996/946/389 997/947/389 998/948/389 +f 996/946/389 998/948/389 999/949/389 +f 997/947/389 942/893/389 945/896/389 +f 997/947/389 945/896/389 998/948/389 +f 998/948/389 945/896/389 950/901/389 +f 998/948/389 950/901/389 1000/950/389 +f 999/949/389 998/948/389 1000/950/389 +f 999/949/389 1000/950/389 1001/951/389 +f 1002/952/389 1003/953/389 1004/954/389 +f 1002/952/389 1004/954/389 1005/955/389 +f 1003/953/389 1007/956/395 1004/954/389 +f 1004/954/389 1008/957/396 1009/958/389 +f 1005/955/389 1004/954/389 1009/958/389 +f 1005/955/389 1009/958/389 1010/959/389 +f 985/935/389 1011/960/389 1012/961/389 +f 985/935/389 1012/961/389 986/936/389 +f 1011/960/389 1013/962/389 1014/963/389 +f 1011/960/389 1014/963/389 1012/961/389 +f 1012/961/389 1014/963/389 1015/964/389 +f 1012/961/389 1015/964/389 1016/965/389 +f 986/936/389 1012/961/389 1016/965/389 +f 986/936/389 1016/965/389 987/937/389 +f 946/897/389 1017/966/389 1018/967/389 +f 946/897/389 1018/967/389 947/898/389 +f 1017/966/389 1019/968/389 1020/969/389 +f 1017/966/389 1020/969/389 1018/967/389 +f 1018/967/389 1020/969/389 1021/970/389 +f 1018/967/389 1021/970/389 1022/971/389 +f 947/898/389 1018/967/389 1022/971/389 +f 947/898/389 1022/971/389 948/899/389 +f 964/915/389 1032/972/389 1033/973/389 +f 964/915/389 1033/973/389 965/916/389 +f 1032/972/389 1034/974/389 1035/975/389 +f 1032/972/389 1035/975/389 1033/973/389 +f 1038/976/389 1039/977/389 1040/978/389 +f 1038/976/389 1040/978/389 1041/979/389 +f 1039/977/389 1042/980/389 1043/981/389 +f 1039/977/389 1043/981/389 1040/978/389 +f 1040/978/389 1043/981/389 1044/982/389 +f 1040/978/389 1044/982/389 1045/983/389 +f 1041/979/389 1040/978/389 1045/983/389 +f 1041/979/389 1045/983/389 1046/984/389 +f 1047/985/389 1048/986/389 1049/987/389 +f 1047/985/389 1049/987/389 1050/988/389 +f 1048/986/389 1038/976/389 1041/979/389 +f 1048/986/389 1041/979/389 1049/987/389 +f 1049/987/389 1041/979/389 1046/984/389 +f 1049/987/389 1046/984/389 1051/989/389 +f 1050/988/389 1049/987/389 1051/989/389 +f 1050/988/389 1051/989/389 1001/951/389 +f 996/946/389 1052/990/389 1053/991/389 +f 996/946/389 1053/991/389 1054/992/389 +f 1052/990/389 1055/993/389 1056/994/389 +f 1052/990/389 1056/994/389 1053/991/389 +f 1053/991/389 1056/994/389 1057/995/389 +f 1053/991/389 1057/995/389 1058/996/389 +f 1054/992/389 1053/991/389 1058/996/389 +f 1054/992/389 1058/996/389 995/945/389 +f 1059/997/389 1060/998/389 1061/999/389 +f 1059/997/389 1061/999/389 1062/1000/389 +f 1060/998/389 951/902/389 954/905/389 +f 1060/998/389 954/905/389 1061/999/389 +f 1061/999/389 954/905/389 959/910/389 +f 1061/999/389 959/910/389 1063/1001/389 +f 1062/1000/389 1061/999/389 1063/1001/389 +f 1062/1000/389 1063/1001/389 1064/1002/389 +f 1065/1003/389 1066/1004/389 1067/1005/389 +f 1065/1003/389 1067/1005/389 1068/1006/389 +f 1066/1004/389 924/879/389 927/882/389 +f 1066/1004/389 927/882/389 1067/1005/389 +f 1055/993/389 1071/1007/389 1072/1008/389 +f 1055/993/389 1072/1008/389 1056/994/389 +f 1071/1007/389 1073/1009/389 1074/1010/389 +f 1071/1007/389 1074/1010/389 1072/1008/389 +f 1072/1008/389 1074/1010/389 1075/1011/389 +f 1072/1008/389 1075/1011/389 1076/1012/389 +f 1056/994/389 1072/1008/389 1076/1012/389 +f 1056/994/389 1076/1012/389 1057/995/389 +f 1077/1013/389 1078/1014/389 1079/1015/389 +f 1077/1013/389 1079/1015/389 1080/1016/389 +f 1078/1014/389 1082/1017/397 1079/1015/389 +f 1079/1015/389 1083/1018/398 1084/1019/389 +f 1080/1016/389 1079/1015/389 1084/1019/389 +f 1080/1016/389 1084/1019/389 1085/1020/389 +f 1086/1021/389 1087/1022/389 1088/1023/389 +f 1086/1021/389 1088/1023/389 1089/1024/389 +f 1087/1022/389 1091/1025/399 1088/1023/389 +f 1088/1023/389 1092/1026/400 1093/1027/389 +f 1089/1024/389 1088/1023/389 1093/1027/389 +f 1089/1024/389 1093/1027/389 1094/1028/389 +f 1104/1029/389 1105/1030/389 1106/1031/389 +f 1104/1029/389 1106/1031/389 1107/1032/389 +f 1105/1030/389 1109/1033/401 1106/1031/389 +f 1106/1031/389 1110/1034/401 1111/1035/389 +f 1107/1032/389 1106/1031/389 1111/1035/389 +f 1107/1032/389 1111/1035/389 1112/1036/389 +f 1113/1037/389 1114/1038/389 1115/1039/389 +f 1113/1037/389 1115/1039/389 1116/1040/389 +f 1114/1038/389 1118/1041/402 1115/1039/389 +f 1115/1039/389 1119/1042/403 1120/1043/389 +f 1116/1040/389 1115/1039/389 1120/1043/389 +f 1116/1040/389 1120/1043/389 1121/1044/389 +f 1122/1045/389 1123/1046/389 1124/1047/389 +f 1122/1045/389 1124/1047/389 1125/1048/389 +f 1123/1046/389 1126/1049/389 1127/1050/389 +f 1123/1046/390 1127/1050/390 1124/1047/390 +f 1131/1051/389 1132/1052/389 1133/1053/389 +f 1131/1051/389 1133/1053/389 1134/1054/389 +f 1132/1052/389 1135/1055/389 1136/1056/389 +f 1132/1052/389 1136/1056/389 1133/1053/389 +f 1133/1053/389 1136/1056/389 1137/1057/389 +f 1133/1053/389 1137/1057/389 1138/1058/389 +f 1134/1054/389 1133/1053/389 1138/1058/389 +f 1134/1054/389 1138/1058/389 1139/1059/389 +f 951/902/389 1140/1060/389 1141/1061/389 +f 951/902/389 1141/1061/389 952/903/389 +f 1140/1060/389 1142/1062/389 1143/1063/389 +f 1140/1060/389 1143/1063/389 1141/1061/389 +f 1141/1061/389 1143/1063/389 1144/1064/389 +f 1141/1061/389 1144/1064/389 1145/1065/389 +f 952/903/389 1141/1061/389 1145/1065/389 +f 952/903/389 1145/1065/389 955/906/389 +f 1146/1066/389 1147/1067/389 1148/1068/389 +f 1146/1066/389 1148/1068/389 1149/1069/389 +f 1147/1067/389 1151/1070/404 1148/1068/389 +f 1148/1068/389 1152/1071/405 1153/1072/389 +f 1149/1069/389 1148/1068/389 1153/1072/389 +f 1149/1069/389 1153/1072/389 1154/1073/389 +f 1155/1074/389 1156/1075/389 1157/1076/389 +f 1155/1074/389 1157/1076/389 1158/1077/389 +f 1156/1075/389 1159/1078/389 1160/1079/389 +f 1156/1075/389 1160/1079/389 1157/1076/389 +f 1157/1076/389 1160/1079/389 1150/1080/389 +f 1157/1076/389 1150/1080/389 1147/1067/389 +f 1158/1077/389 1157/1076/389 1147/1067/389 +f 1158/1077/389 1147/1067/389 1146/1066/389 +f 1159/1078/389 1161/1081/389 1162/1082/389 +f 1159/1078/389 1162/1082/389 1160/1079/389 +f 1161/1081/389 980/930/389 979/929/389 +f 1161/1081/389 979/929/389 1162/1082/389 +f 1162/1082/389 979/929/389 978/928/389 +f 1162/1082/389 978/928/389 1163/1083/389 +f 1160/1079/389 1162/1082/389 1163/1083/389 +f 1160/1079/389 1163/1083/389 1150/1080/389 +f 1164/1084/389 1165/1085/389 1166/1086/389 +f 1164/1084/389 1166/1086/389 1167/1087/389 +f 1165/1085/389 1168/1088/389 1169/1089/389 +f 1165/1085/389 1169/1089/389 1166/1086/389 +f 1166/1086/389 1169/1089/389 1170/1090/389 +f 1166/1086/389 1170/1090/389 1171/1091/389 +f 1167/1087/389 1166/1086/389 1171/1091/389 +f 1167/1087/389 1171/1091/389 1172/1092/389 +f 1173/1093/389 1174/1094/389 1175/1095/389 +f 1173/1093/389 1175/1095/389 1176/1096/389 +f 1174/1094/389 1177/1097/389 1178/1098/389 +f 1174/1094/389 1178/1098/389 1175/1095/389 +f 1175/1095/389 1178/1098/389 1168/1088/389 +f 1175/1095/389 1168/1088/389 1165/1085/389 +f 1176/1096/389 1175/1095/389 1165/1085/389 +f 1176/1096/389 1165/1085/389 1164/1084/389 +f 1179/1099/389 1180/1100/389 1181/1101/389 +f 1179/1099/389 1181/1101/389 1182/1102/389 +f 1180/1100/389 1183/1103/389 1184/1104/389 +f 1180/1100/389 1184/1104/389 1181/1101/389 +f 1181/1101/389 1184/1104/389 1135/1055/389 +f 1181/1101/389 1135/1055/389 1132/1052/389 +f 1182/1102/389 1181/1101/389 1132/1052/389 +f 1182/1102/389 1132/1052/389 1131/1051/389 +f 1185/1105/389 1186/1106/389 1187/1107/389 +f 1185/1105/389 1187/1107/389 1188/1108/389 +f 1186/1106/389 1189/1109/389 1190/1110/389 +f 1186/1106/389 1190/1110/389 1187/1107/389 +f 1172/1092/389 1171/1091/389 1194/1111/389 +f 1172/1092/389 1194/1111/389 1195/1112/389 +f 1171/1091/389 1170/1090/389 1196/1113/389 +f 1171/1091/389 1196/1113/389 1194/1111/389 +f 1194/1111/389 1196/1113/389 1197/1114/389 +f 1194/1111/389 1197/1114/389 1198/1115/389 +f 1195/1112/389 1194/1111/389 1198/1115/389 +f 1195/1112/389 1198/1115/389 1199/1116/389 +f 1139/1059/389 1138/1058/389 1200/1117/389 +f 1139/1059/389 1200/1117/389 1201/1118/389 +f 1138/1058/389 1137/1057/389 1202/1119/389 +f 1138/1058/389 1202/1119/389 1200/1117/389 +f 1200/1117/389 1202/1119/389 1203/1120/389 +f 1200/1117/389 1203/1120/389 1204/1121/389 +f 1201/1118/389 1200/1117/389 1204/1121/389 +f 1201/1118/389 1204/1121/389 1205/1122/389 +f 1206/1123/389 1207/1124/389 1208/1125/389 +f 1206/1123/389 1208/1125/389 1209/1126/389 +f 1207/1124/390 1211/1127/406 1208/1125/390 +f 1154/1073/389 1153/1072/389 1215/1128/389 +f 1154/1073/390 1215/1128/390 1216/1129/390 +f 1153/1072/389 1217/1130/407 1215/1128/389 +f 1215/1128/389 1210/1131/408 1207/1124/389 +f 1216/1129/390 1215/1128/390 1207/1124/390 +f 1216/1129/389 1207/1124/389 1206/1123/389 +f 1218/1132/389 1219/1133/389 1220/1134/389 +f 1218/1132/389 1220/1134/389 1221/1135/389 +f 1219/1133/389 1222/1136/389 1223/1137/389 +f 1219/1133/389 1223/1137/389 1220/1134/389 +f 1220/1134/389 1223/1137/389 1224/1138/389 +f 1220/1134/389 1224/1138/389 1225/1139/389 +f 1221/1135/389 1220/1134/389 1225/1139/389 +f 1221/1135/389 1225/1139/389 1226/1140/389 +f 1227/1141/389 1228/1142/389 1229/1143/389 +f 1227/1141/389 1229/1143/389 1230/1144/389 +f 1228/1142/389 1183/1103/389 1231/1145/389 +f 1228/1142/389 1231/1145/389 1229/1143/389 +f 1229/1143/389 1231/1145/389 1222/1136/389 +f 1229/1143/389 1222/1136/389 1219/1133/389 +f 1230/1144/389 1229/1143/389 1219/1133/389 +f 1230/1144/389 1219/1133/389 1218/1132/389 +f 1179/1099/389 1232/1146/389 1233/1147/389 +f 1179/1099/389 1233/1147/389 1234/1148/389 +f 1232/1146/389 1177/1097/389 1235/1149/389 +f 1232/1146/389 1235/1149/389 1233/1147/389 +f 1233/1147/389 1235/1149/389 1236/1150/389 +f 1233/1147/389 1236/1150/389 1237/1151/389 +f 1234/1148/389 1233/1147/389 1237/1151/389 +f 1234/1148/389 1237/1151/389 1238/1152/389 +f 1059/997/389 1239/1153/389 1240/1154/389 +f 1059/997/389 1240/1154/389 1060/998/389 +f 1239/1153/389 1241/1155/389 1242/1156/389 +f 1239/1153/389 1242/1156/389 1240/1154/389 +f 1240/1154/389 1242/1156/389 1142/1062/389 +f 1240/1154/389 1142/1062/389 1140/1060/389 +f 1060/998/389 1240/1154/389 1140/1060/389 +f 1060/998/389 1140/1060/389 951/902/389 +f 1243/1157/389 1244/1158/389 1245/1159/389 +f 1243/1157/389 1245/1159/389 1246/1160/389 +f 1244/1158/389 1248/1161/409 1245/1159/389 +f 1245/1159/389 1117/1162/410 1114/1038/389 +f 1246/1160/389 1245/1159/389 1114/1038/389 +f 1246/1160/389 1114/1038/389 1113/1037/389 +f 1238/1152/389 1237/1151/389 1249/1163/389 +f 1238/1152/389 1249/1163/389 1250/1164/389 +f 1237/1151/389 1236/1150/389 1251/1165/389 +f 1237/1151/389 1251/1165/389 1249/1163/389 +f 1249/1163/389 1251/1165/389 1252/1166/389 +f 1249/1163/389 1252/1166/389 1253/1167/389 +f 1250/1164/389 1249/1163/389 1253/1167/389 +f 1250/1164/389 1253/1167/389 1254/1168/389 +f 1255/1169/389 1256/1170/389 1257/1171/389 +f 1255/1169/390 1257/1171/390 1258/1172/390 +f 1256/1170/390 1259/1173/390 1260/1174/390 +f 1256/1170/390 1260/1174/390 1257/1171/390 +f 1264/1175/389 1265/1176/389 1266/1177/389 +f 1264/1175/389 1266/1177/389 1267/1178/389 +f 1265/1176/389 1268/1179/389 1269/1180/389 +f 1265/1176/389 1269/1180/389 1266/1177/389 +f 1273/1181/390 1274/1182/390 1275/1183/390 +f 1273/1181/389 1275/1183/389 1276/1184/389 +f 1274/1182/389 1278/1185/411 1275/1183/389 +f 1104/1029/389 1282/1186/389 1283/1187/389 +f 1104/1029/389 1283/1187/389 1105/1030/389 +f 1282/1186/389 1284/1188/389 1285/1189/389 +f 1282/1186/389 1285/1189/389 1283/1187/389 +f 1112/1036/389 1111/1035/389 1288/1190/389 +f 1112/1036/389 1288/1190/389 1289/1191/389 +f 1111/1035/389 1290/1192/401 1288/1190/389 +f 1288/1190/389 1081/1193/397 1078/1014/389 +f 1289/1191/389 1288/1190/389 1078/1014/389 +f 1289/1191/389 1078/1014/389 1077/1013/389 +f 1064/1002/389 1063/1001/389 1291/1194/389 +f 1064/1002/389 1291/1194/389 1292/1195/389 +f 1063/1001/389 959/910/389 1293/1196/389 +f 1063/1001/389 1293/1196/389 1291/1194/389 +f 1291/1194/389 1293/1196/389 1038/976/389 +f 1291/1194/389 1038/976/389 1048/986/389 +f 1292/1195/389 1291/1194/389 1048/986/389 +f 1292/1195/389 1048/986/389 1047/985/389 +f 959/910/389 958/909/389 1294/1197/389 +f 959/910/389 1294/1197/389 1293/1196/389 +f 958/909/389 957/908/389 1295/1198/389 +f 958/909/389 1295/1198/389 1294/1197/389 +f 1294/1197/389 1295/1198/389 1042/980/389 +f 1294/1197/389 1042/980/389 1039/977/389 +f 1293/1196/389 1294/1197/389 1039/977/389 +f 1293/1196/389 1039/977/389 1038/976/389 +f 1296/1199/390 1297/1200/390 1298/1201/390 +f 1296/1199/389 1298/1201/389 1299/1202/389 +f 1297/1200/389 1300/1203/389 1301/1204/389 +f 1297/1200/390 1301/1204/390 1298/1201/390 +f 1298/1201/390 1301/1204/390 1034/974/390 +f 1298/1201/389 1034/974/389 1032/972/389 +f 1299/1202/389 1298/1201/389 1032/972/389 +f 1299/1202/389 1032/972/389 964/915/389 +f 941/892/412 1302/1205/413 1303/1206/412 +f 1303/1206/412 1024/1207/414 1023/1208/415 +f 1001/951/389 1000/950/389 1305/1209/389 +f 1001/951/389 1305/1209/389 1050/988/389 +f 1000/950/389 950/901/389 1306/1210/389 +f 1000/950/389 1306/1210/389 1305/1209/389 +f 1305/1209/389 1306/1210/389 1307/1211/389 +f 1305/1209/389 1307/1211/389 1308/1212/389 +f 1050/988/389 1305/1209/389 1308/1212/389 +f 1050/988/389 1308/1212/389 1047/985/389 +f 950/901/389 949/900/389 1309/1213/389 +f 950/901/389 1309/1213/389 1306/1210/389 +f 949/900/389 948/899/389 1310/1214/389 +f 949/900/389 1310/1214/389 1309/1213/389 +f 1309/1213/390 1310/1214/390 1311/1215/390 +f 1309/1213/389 1311/1215/389 1312/1216/389 +f 1306/1210/389 1309/1213/389 1312/1216/389 +f 1306/1210/389 1312/1216/389 1307/1211/389 +f 1085/1020/389 1084/1019/389 1313/1217/389 +f 1085/1020/389 1313/1217/389 1314/1218/389 +f 1084/1019/389 1315/1219/398 1313/1217/389 +f 1313/1217/389 1090/1220/416 1087/1022/389 +f 1314/1218/389 1313/1217/389 1087/1022/389 +f 1314/1218/389 1087/1022/389 1086/1021/389 +f 1046/984/389 1045/983/389 1316/1221/389 +f 1046/984/389 1316/1221/389 1317/1222/389 +f 1045/983/389 1044/982/389 1318/1223/389 +f 1045/983/389 1318/1223/389 1316/1221/389 +f 1316/1221/389 1318/1223/389 1073/1009/389 +f 1316/1221/389 1073/1009/389 1071/1007/389 +f 1317/1222/389 1316/1221/389 1071/1007/389 +f 1317/1222/389 1071/1007/389 1055/993/389 +f 1001/951/389 1051/989/389 1319/1224/389 +f 1001/951/389 1319/1224/389 999/949/389 +f 1051/989/389 1046/984/389 1317/1222/389 +f 1051/989/389 1317/1222/389 1319/1224/389 +f 1319/1224/389 1317/1222/389 1055/993/389 +f 1319/1224/389 1055/993/389 1052/990/389 +f 999/949/389 1319/1224/389 1052/990/389 +f 999/949/389 1052/990/389 996/946/389 +f 987/937/389 1016/965/389 1320/1225/389 +f 987/937/389 1320/1225/389 1321/1226/389 +f 1016/965/389 1015/964/389 1322/1227/389 +f 1016/965/389 1322/1227/389 1320/1225/389 +f 1320/1225/389 1322/1227/389 1019/968/389 +f 1320/1225/389 1019/968/389 1017/966/389 +f 1321/1226/389 1320/1225/389 1017/966/389 +f 1321/1226/389 1017/966/389 946/897/389 +f 995/945/389 994/944/389 1323/1228/389 +f 995/945/389 1323/1228/389 1054/992/389 +f 994/944/389 989/939/389 1324/1229/389 +f 994/944/389 1324/1229/389 1323/1228/389 +f 1323/1228/389 1324/1229/389 942/893/389 +f 1323/1228/389 942/893/389 997/947/389 +f 1054/992/389 1323/1228/389 997/947/389 +f 1054/992/389 997/947/389 996/946/389 +f 989/939/389 988/938/389 1325/1230/389 +f 989/939/389 1325/1230/389 1324/1229/389 +f 988/938/389 987/937/389 1321/1226/389 +f 988/938/389 1321/1226/389 1325/1230/389 +f 1325/1230/389 1321/1226/389 946/897/389 +f 1325/1230/389 946/897/389 943/894/389 +f 1324/1229/389 1325/1230/389 943/894/389 +f 1324/1229/389 943/894/389 942/893/389 +f 1010/959/389 1009/958/389 1326/1231/389 +f 1010/959/389 1326/1231/389 1327/1232/389 +f 1009/958/389 1328/1233/417 1326/1231/389 +f 1326/1231/389 937/1234/418 934/886/389 +f 1327/1232/389 1326/1231/389 934/886/389 +f 1327/1232/389 934/886/389 933/885/389 +f 1094/1028/389 1093/1027/389 1329/1235/389 +f 1094/1028/389 1329/1235/389 1330/1236/389 +f 1093/1027/389 1331/1237/419 1329/1235/389 +f 1329/1235/389 1332/1238/420 1333/1239/421 +f 1330/1236/389 1329/1235/389 1333/1239/389 +f 1330/1236/389 1333/1239/389 1334/1240/389 +f 995/945/389 1058/996/389 1335/1241/389 +f 995/945/389 1335/1241/389 993/943/389 +f 1058/996/389 1057/995/389 1336/1242/389 +f 1058/996/389 1336/1242/389 1335/1241/389 +f 1335/1241/389 1336/1242/389 1337/1243/389 +f 1335/1241/389 1337/1243/389 1338/1244/389 +f 993/943/389 1335/1241/389 1338/1244/389 +f 993/943/389 1338/1244/389 990/940/389 +f 1339/1245/422 1340/1246/423 1341/1247/389 +f 1339/1245/424 1341/1247/389 1342/1248/389 +f 1340/1246/423 1343/1249/425 1344/1250/389 +f 1340/1246/423 1344/1250/389 1341/1247/389 +f 1341/1247/389 1344/1250/389 1345/1251/389 +f 1341/1247/389 1345/1251/389 1346/1252/389 +f 1342/1248/389 1341/1247/389 1346/1252/389 +f 1342/1248/389 1346/1252/389 1347/1253/389 +f 1348/1254/425 1349/1255/426 1350/1256/389 +f 1348/1254/427 1350/1256/389 1351/1257/389 +f 1349/1255/426 1353/1258/428 1350/1256/389 +f 1350/1256/389 1006/1259/429 1003/953/389 +f 1351/1257/389 1350/1256/389 1003/953/389 +f 1351/1257/389 1003/953/389 1002/952/389 +f 1070/1260/430 1354/1261/431 1355/1262/389 +f 1070/1260/430 1355/1262/389 1068/1006/389 +f 1354/1261/431 1356/1263/432 1357/1264/389 +f 1354/1261/433 1357/1264/389 1355/1262/389 +f 1355/1262/389 1357/1264/389 1358/1265/389 +f 1355/1262/390 1358/1265/390 1359/1266/390 +f 1068/1006/390 1355/1262/390 1359/1266/390 +f 1068/1006/389 1359/1266/389 1065/1003/389 +f 1356/1263/432 1360/1267/434 1361/1268/389 +f 1356/1263/432 1361/1268/389 1357/1264/389 +f 1360/1267/434 1339/1245/424 1342/1248/389 +f 1360/1267/434 1342/1248/389 1361/1268/389 +f 1361/1268/389 1342/1248/389 1347/1253/389 +f 1361/1268/389 1347/1253/389 1362/1269/389 +f 1357/1264/389 1361/1268/389 1362/1269/389 +f 1357/1264/389 1362/1269/389 1358/1265/389 +f 1057/995/389 1076/1012/389 1363/1270/389 +f 1057/995/389 1363/1270/389 1336/1242/389 +f 1076/1012/389 1075/1011/389 1364/1271/389 +f 1076/1012/389 1364/1271/389 1363/1270/389 +f 1363/1270/389 1364/1271/389 1365/1272/389 +f 1363/1270/389 1365/1272/389 1366/1273/389 +f 1336/1242/389 1363/1270/389 1366/1273/389 +f 1336/1242/389 1366/1273/389 1337/1243/389 +f 1075/1011/389 1367/1274/389 1368/1275/389 +f 1075/1011/389 1368/1275/389 1364/1271/389 +f 1367/1274/389 1369/1276/389 1370/1277/389 +f 1367/1274/389 1370/1277/389 1368/1275/389 +f 1368/1275/389 1095/1278/435 1371/1279/389 +f 1364/1271/389 1368/1275/389 1371/1279/389 +f 1364/1271/389 1371/1279/389 1365/1272/389 +f 1044/982/389 1372/1280/389 1373/1281/389 +f 1044/982/389 1373/1281/389 1318/1223/389 +f 1372/1280/389 1374/1282/389 1375/1283/389 +f 1372/1280/389 1375/1283/389 1373/1281/389 +f 1373/1281/389 1375/1283/389 1376/1284/389 +f 1373/1281/389 1376/1284/389 1377/1285/389 +f 1318/1223/389 1373/1281/389 1377/1285/389 +f 1318/1223/389 1377/1285/389 1073/1009/389 +f 957/908/389 1378/1286/389 1379/1287/389 +f 957/908/389 1379/1287/389 1295/1198/389 +f 1378/1286/389 1380/1288/389 1381/1289/389 +f 1378/1286/389 1381/1289/389 1379/1287/389 +f 1379/1287/389 1381/1289/389 1382/1290/389 +f 1379/1287/389 1382/1290/389 1383/1291/389 +f 1295/1198/389 1379/1287/389 1383/1291/389 +f 1295/1198/389 1383/1291/389 1042/980/389 +f 955/906/389 1145/1065/389 1384/1292/389 +f 955/906/389 1384/1292/389 1385/1293/389 +f 1145/1065/389 1144/1064/389 1386/1294/389 +f 1145/1065/389 1386/1294/389 1384/1292/389 +f 1384/1292/389 1386/1294/389 1387/1295/389 +f 1384/1292/389 1387/1295/389 1388/1296/389 +f 1385/1293/389 1384/1292/389 1388/1296/389 +f 1385/1293/389 1388/1296/389 1389/1297/389 +f 1121/1044/389 1120/1043/389 1390/1298/389 +f 1121/1044/389 1390/1298/389 1391/1299/389 +f 1120/1043/389 1392/1300/436 1390/1298/389 +f 1390/1298/389 1277/1301/437 1274/1182/389 +f 1391/1299/389 1390/1298/389 1274/1182/389 +f 1391/1299/389 1274/1182/389 1273/1181/389 +f 1254/1168/389 1253/1167/389 1393/1302/389 +f 1254/1168/389 1393/1302/389 1394/1303/389 +f 1253/1167/389 1252/1166/389 1395/1304/389 +f 1253/1167/389 1395/1304/389 1393/1302/389 +f 1393/1302/389 1395/1304/389 1396/1305/389 +f 1393/1302/389 1396/1305/389 1397/1306/389 +f 1394/1303/389 1393/1302/389 1397/1306/389 +f 1394/1303/389 1397/1306/389 1398/1307/389 +f 1226/1140/389 1225/1139/389 1399/1308/389 +f 1226/1140/389 1399/1308/389 1400/1309/389 +f 1225/1139/389 1224/1138/389 1401/1310/389 +f 1225/1139/389 1401/1310/389 1399/1308/389 +f 1399/1308/389 1401/1310/389 1402/1311/389 +f 1399/1308/389 1402/1311/389 1403/1312/389 +f 1400/1309/389 1399/1308/389 1403/1312/389 +f 1400/1309/389 1403/1312/389 1404/1313/389 +f 955/906/389 1385/1293/389 1405/1314/389 +f 955/906/389 1405/1314/389 956/907/389 +f 1385/1293/389 1389/1297/389 1406/1315/389 +f 1385/1293/389 1406/1315/389 1405/1314/389 +f 1405/1314/389 1406/1315/389 1380/1288/389 +f 1405/1314/389 1380/1288/389 1378/1286/389 +f 956/907/389 1405/1314/389 1378/1286/389 +f 956/907/389 1378/1286/389 957/908/389 +f 928/883/389 1407/1316/389 1408/1317/389 +f 928/883/389 1408/1317/389 929/884/389 +f 1407/1316/389 1409/1318/389 1410/1319/389 +f 1407/1316/389 1410/1319/389 1408/1317/389 +f 1073/1009/389 1377/1285/389 1413/1320/389 +f 1073/1009/389 1413/1320/389 1074/1010/389 +f 1377/1285/389 1376/1284/389 1414/1321/389 +f 1377/1285/389 1414/1321/389 1413/1320/389 +f 1413/1320/389 1414/1321/389 1369/1276/389 +f 1413/1320/389 1369/1276/389 1367/1274/389 +f 1074/1010/389 1413/1320/389 1367/1274/389 +f 1074/1010/389 1367/1274/389 1075/1011/389 +f 1042/980/389 1383/1291/389 1415/1322/389 +f 1042/980/389 1415/1322/389 1043/981/389 +f 1383/1291/389 1382/1290/389 1416/1323/389 +f 1383/1291/389 1416/1323/389 1415/1322/389 +f 1415/1322/389 1416/1323/389 1374/1282/389 +f 1415/1322/389 1374/1282/389 1372/1280/389 +f 1043/981/389 1415/1322/389 1372/1280/389 +f 1043/981/389 1372/1280/389 1044/982/389 +f 1144/1064/389 1417/1324/389 1418/1325/389 +f 1144/1064/389 1418/1325/389 1386/1294/389 +f 1417/1324/389 1226/1140/389 1400/1309/389 +f 1417/1324/389 1400/1309/389 1418/1325/389 +f 1418/1325/389 1400/1309/389 1404/1313/389 +f 1418/1325/389 1404/1313/389 1419/1326/389 +f 1386/1294/389 1418/1325/389 1419/1326/389 +f 1386/1294/389 1419/1326/389 1387/1295/389 +f 1284/1188/389 1420/1327/389 1421/1328/389 +f 1284/1188/389 1421/1328/389 1285/1189/389 +f 1420/1327/389 1255/1169/389 1258/1172/389 +f 1420/1327/389 1258/1172/389 1421/1328/389 +f 1241/1155/389 1423/1329/389 1424/1330/389 +f 1241/1155/389 1424/1330/389 1242/1156/389 +f 1423/1329/389 1227/1141/389 1230/1144/389 +f 1423/1329/389 1230/1144/389 1424/1330/389 +f 1424/1330/389 1230/1144/389 1218/1132/389 +f 1424/1330/389 1218/1132/389 1425/1331/389 +f 1242/1156/389 1424/1330/389 1425/1331/389 +f 1242/1156/389 1425/1331/389 1142/1062/389 +f 1142/1062/389 1425/1331/389 1426/1332/389 +f 1142/1062/389 1426/1332/389 1143/1063/389 +f 1425/1331/389 1218/1132/389 1221/1135/389 +f 1425/1331/389 1221/1135/389 1426/1332/389 +f 1426/1332/389 1221/1135/389 1226/1140/389 +f 1426/1332/389 1226/1140/389 1417/1324/389 +f 1143/1063/389 1426/1332/389 1417/1324/389 +f 1143/1063/389 1417/1324/389 1144/1064/389 +f 1137/1057/389 1427/1333/389 1428/1334/389 +f 1137/1057/389 1428/1334/389 1202/1119/389 +f 1427/1333/389 1429/1335/389 1430/1336/389 +f 1427/1333/389 1430/1336/389 1428/1334/389 +f 1428/1334/389 1430/1336/389 1431/1337/389 +f 1428/1334/389 1431/1337/389 1432/1338/389 +f 1202/1119/389 1428/1334/389 1432/1338/389 +f 1202/1119/389 1432/1338/389 1203/1120/389 +f 1126/1049/390 1433/1339/390 1434/1340/390 +f 1126/1049/389 1434/1340/389 1127/1050/389 +f 1433/1339/389 1206/1123/389 1209/1126/389 +f 1433/1339/389 1209/1126/389 1434/1340/389 +f 1183/1103/389 1228/1142/389 1436/1341/389 +f 1183/1103/389 1436/1341/389 1184/1104/389 +f 1228/1142/389 1227/1141/389 1437/1342/389 +f 1228/1142/389 1437/1342/389 1436/1341/389 +f 1436/1341/389 1437/1342/389 1438/1343/389 +f 1436/1341/389 1438/1343/389 1439/1344/389 +f 1184/1104/389 1436/1341/389 1439/1344/389 +f 1184/1104/389 1439/1344/389 1135/1055/389 +f 1135/1055/389 1439/1344/389 1440/1345/389 +f 1135/1055/389 1440/1345/389 1136/1056/389 +f 1439/1344/389 1438/1343/389 1441/1346/389 +f 1439/1344/389 1441/1346/389 1440/1345/389 +f 1440/1345/389 1441/1346/389 1429/1335/389 +f 1440/1345/389 1429/1335/389 1427/1333/389 +f 1136/1056/389 1440/1345/389 1427/1333/389 +f 1136/1056/389 1427/1333/389 1137/1057/389 +f 1252/1166/389 1442/1347/389 1443/1348/389 +f 1252/1166/389 1443/1348/389 1395/1304/389 +f 1442/1347/389 1444/1349/389 1445/1350/389 +f 1442/1347/389 1445/1350/389 1443/1348/389 +f 1443/1348/389 1445/1350/389 1446/1351/389 +f 1443/1348/389 1446/1351/389 1447/1352/389 +f 1395/1304/389 1443/1348/389 1447/1352/389 +f 1395/1304/389 1447/1352/389 1396/1305/389 +f 1268/1179/389 1448/1353/389 1449/1354/389 +f 1268/1179/389 1449/1354/389 1269/1180/389 +f 1448/1353/389 1273/1181/389 1276/1184/389 +f 1448/1353/389 1276/1184/389 1449/1354/389 +f 1177/1097/389 1174/1094/389 1451/1355/389 +f 1177/1097/389 1451/1355/389 1235/1149/389 +f 1174/1094/389 1173/1093/389 1452/1356/389 +f 1174/1094/389 1452/1356/389 1451/1355/389 +f 1451/1355/389 1452/1356/389 1453/1357/389 +f 1451/1355/389 1453/1357/389 1454/1358/389 +f 1235/1149/389 1451/1355/389 1454/1358/389 +f 1235/1149/389 1454/1358/389 1236/1150/389 +f 1455/1359/438 1456/1360/389 1457/1361/389 +f 1456/1360/389 1459/1362/389 1460/1363/389 +f 1456/1360/389 1460/1363/389 1457/1361/389 +f 1457/1361/389 1460/1363/389 1185/1105/389 +f 1457/1361/389 1185/1105/389 1461/1364/389 +f 1458/1365/439 1457/1361/389 1461/1364/389 +f 1462/1366/440 1461/1364/389 1463/1367/389 +f 1461/1364/389 1185/1105/389 1188/1108/389 +f 1461/1364/389 1188/1108/389 1463/1367/389 +f 1247/1368/441 1244/1158/389 1467/1369/389 +f 1244/1158/389 1243/1157/389 1469/1370/389 +f 1244/1158/389 1469/1370/389 1467/1369/389 +f 1467/1369/389 1469/1370/389 1470/1371/389 +f 1467/1369/389 1470/1371/389 1471/1372/389 +f 1468/1373/442 1467/1369/389 1471/1372/389 +f 1472/1374/443 1471/1372/389 1473/1375/389 +f 1471/1372/389 1470/1371/389 1475/1376/389 +f 1471/1372/389 1475/1376/389 1473/1375/389 +f 1473/1375/389 1475/1376/389 1459/1362/389 +f 1473/1375/389 1459/1362/389 1456/1360/389 +f 1474/1377/444 1473/1375/389 1456/1360/389 +f 1236/1150/389 1454/1358/389 1476/1378/389 +f 1236/1150/389 1476/1378/389 1251/1165/389 +f 1454/1358/389 1453/1357/389 1477/1379/389 +f 1454/1358/389 1477/1379/389 1476/1378/389 +f 1476/1378/389 1477/1379/389 1444/1349/389 +f 1476/1378/389 1444/1349/389 1442/1347/389 +f 1251/1165/389 1476/1378/389 1442/1347/389 +f 1251/1165/389 1442/1347/389 1252/1166/389 +f 1224/1138/389 1478/1380/389 1479/1381/389 +f 1224/1138/389 1479/1381/389 1401/1310/389 +f 1478/1380/389 1254/1168/389 1394/1303/389 +f 1478/1380/389 1394/1303/389 1479/1381/389 +f 1479/1381/389 1394/1303/389 1398/1307/389 +f 1479/1381/389 1398/1307/389 1480/1382/389 +f 1401/1310/389 1479/1381/389 1480/1382/389 +f 1401/1310/389 1480/1382/389 1402/1311/389 +f 1259/1173/390 1481/1383/390 1482/1384/390 +f 1259/1173/389 1482/1384/389 1260/1174/389 +f 1481/1383/389 1264/1175/389 1267/1178/389 +f 1481/1383/389 1267/1178/389 1482/1384/389 +f 1222/1136/389 1484/1385/389 1485/1386/389 +f 1222/1136/389 1485/1386/389 1223/1137/389 +f 1484/1385/389 1238/1152/389 1250/1164/389 +f 1484/1385/389 1250/1164/389 1485/1386/389 +f 1485/1386/389 1250/1164/389 1254/1168/389 +f 1485/1386/389 1254/1168/389 1478/1380/389 +f 1223/1137/389 1485/1386/389 1478/1380/389 +f 1223/1137/389 1478/1380/389 1224/1138/389 +f 1183/1103/389 1180/1100/389 1486/1387/389 +f 1183/1103/389 1486/1387/389 1231/1145/389 +f 1180/1100/389 1179/1099/389 1234/1148/389 +f 1180/1100/389 1234/1148/389 1486/1387/389 +f 1486/1387/389 1234/1148/389 1238/1152/389 +f 1486/1387/389 1238/1152/389 1484/1385/389 +f 1231/1145/389 1486/1387/389 1484/1385/389 +f 1231/1145/389 1484/1385/389 1222/1136/389 +f 1170/1090/389 1487/1388/389 1488/1389/389 +f 1170/1090/389 1488/1389/389 1196/1113/389 +f 1487/1388/389 1139/1059/389 1201/1118/389 +f 1487/1388/389 1201/1118/389 1488/1389/389 +f 1488/1389/389 1201/1118/389 1205/1122/389 +f 1488/1389/389 1205/1122/389 1489/1390/389 +f 1196/1113/389 1488/1389/389 1489/1390/389 +f 1196/1113/389 1489/1390/389 1197/1114/389 +f 1177/1097/389 1232/1146/389 1490/1391/389 +f 1177/1097/389 1490/1391/389 1178/1098/389 +f 1232/1146/389 1179/1099/389 1182/1102/389 +f 1232/1146/389 1182/1102/389 1490/1391/389 +f 1490/1391/389 1182/1102/389 1131/1051/389 +f 1490/1391/389 1131/1051/389 1491/1392/389 +f 1178/1098/389 1490/1391/389 1491/1392/389 +f 1178/1098/389 1491/1392/389 1168/1088/389 +f 1168/1088/389 1491/1392/389 1492/1393/389 +f 1168/1088/389 1492/1393/389 1169/1089/389 +f 1491/1392/389 1131/1051/389 1134/1054/389 +f 1491/1392/389 1134/1054/389 1492/1393/389 +f 1492/1393/390 1134/1054/390 1139/1059/390 +f 1492/1393/389 1139/1059/389 1487/1388/389 +f 1169/1089/389 1492/1393/389 1487/1388/389 +f 1169/1089/389 1487/1388/389 1170/1090/389 +f 1189/1109/389 1493/1394/389 1494/1395/389 +f 1189/1109/389 1494/1395/389 1190/1110/389 +f 1493/1394/389 1122/1045/389 1125/1048/389 +f 1493/1394/389 1125/1048/389 1494/1395/389 +f 408/403/335 2681/1396/335 2682/1397/335 +f 408/403/335 2682/1397/335 410/406/335 +f 2681/1396/335 498/487/335 495/484/335 +f 2681/1396/335 495/484/335 2682/1397/335 +f 2682/1397/335 495/484/335 494/483/335 +f 2682/1397/335 494/483/335 2683/1398/335 +f 410/406/335 2682/1397/335 2683/1398/335 +f 410/406/335 2683/1398/335 412/408/335 +f 404/399/335 2694/1399/335 2695/1400/335 +f 404/399/335 2695/1400/335 405/400/335 +f 2694/1399/335 482/471/335 726/682/335 +f 2694/1399/335 726/682/335 2695/1400/335 +f 2695/1400/335 726/682/335 498/487/335 +f 2695/1400/335 498/487/335 2681/1396/335 +f 405/400/335 2695/1400/335 2681/1396/335 +f 405/400/338 2681/1396/338 408/403/338 +f 414/410/445 2706/1401/446 415/411/445 +f 415/411/341 2702/1402/447 399/405/448 +f 2707/1403/335 2708/1404/335 2709/1405/335 +f 2707/1403/335 2709/1405/335 2710/1406/335 +f 2708/1404/335 449/442/335 755/709/335 +f 2708/1404/335 755/709/335 2709/1405/335 +f 2709/1405/335 755/709/335 457/450/335 +f 2709/1405/335 457/450/335 2711/1407/335 +f 2710/1406/335 2709/1405/335 2711/1407/335 +f 2710/1406/335 2711/1407/335 2712/1408/335 +f 2718/1409/338 2719/1410/338 2720/1411/338 +f 2718/1409/335 2720/1411/335 2721/1412/335 +f 2719/1410/335 455/448/335 736/692/335 +f 2719/1410/338 736/692/338 2720/1411/338 +f 2720/1411/338 736/692/338 735/691/338 +f 2720/1411/335 735/691/335 2722/1413/335 +f 2721/1412/335 2720/1411/335 2722/1413/335 +f 2721/1412/335 2722/1413/335 472/461/335 +f 412/408/335 2683/1398/335 2744/1414/335 +f 412/408/335 2744/1414/335 597/568/335 +f 2683/1398/335 494/483/335 675/640/335 +f 2683/1398/335 675/640/335 2744/1414/335 +f 2744/1414/335 675/640/335 677/642/335 +f 2744/1414/335 677/642/335 2745/1415/335 +f 597/568/335 2744/1414/335 2745/1415/335 +f 597/568/338 2745/1415/338 595/566/338 +f 595/566/335 2745/1415/335 2756/1416/335 +f 595/566/335 2756/1416/335 593/564/335 +f 2745/1415/335 677/642/335 852/802/335 +f 2745/1415/335 852/802/335 2756/1416/335 +f 2756/1416/335 852/802/335 662/627/335 +f 2756/1416/335 662/627/335 2757/1417/335 +f 593/564/338 2756/1416/338 2757/1417/338 +f 593/564/338 2757/1417/338 590/561/338 +f 589/560/449 2765/1418/450 598/569/451 +f 598/569/452 2705/1419/453 414/410/341 +f 557/530/335 2766/1420/335 2767/1421/335 +f 557/530/335 2767/1421/335 922/876/335 +f 2766/1420/335 637/607/335 917/871/335 +f 2766/1420/335 917/871/335 2767/1421/335 +f 2767/1421/335 917/871/335 633/603/335 +f 2767/1421/335 633/603/335 2768/1422/335 +f 922/876/335 2767/1421/335 2768/1422/335 +f 922/876/335 2768/1422/335 628/598/335 +f 641/611/335 2773/1423/335 2774/1424/335 +f 641/611/335 2774/1424/335 862/812/335 +f 2773/1423/335 858/808/335 857/807/335 +f 2773/1423/335 857/807/335 2774/1424/335 +f 2774/1424/335 857/807/335 639/609/335 +f 2774/1424/335 639/609/335 2775/1425/335 +f 862/812/335 2774/1424/335 2775/1425/335 +f 862/812/335 2775/1425/335 565/537/335 +f 720/677/454 2784/1426/455 850/799/454 +f 696/658/356 2787/1427/456 911/864/457 +f 472/461/335 2722/1413/335 2795/1428/335 +f 472/461/338 2795/1428/338 468/457/338 +f 2722/1413/335 735/691/335 734/690/335 +f 2722/1413/335 734/690/335 2795/1428/335 +f 2795/1428/335 734/690/335 733/689/335 +f 2795/1428/335 733/689/335 2796/1429/335 +f 468/457/338 2795/1428/338 2796/1429/338 +f 468/457/338 2796/1429/338 403/398/338 +f 395/391/338 2797/1430/338 2798/1431/338 +f 395/391/335 2798/1431/335 407/402/335 +f 2797/1430/335 742/697/335 741/696/335 +f 2797/1430/338 741/696/338 2798/1431/338 +f 2798/1431/338 741/696/338 482/471/338 +f 2798/1431/335 482/471/335 2694/1399/335 +f 407/402/335 2798/1431/335 2694/1399/335 +f 407/402/335 2694/1399/335 404/399/335 +f 403/398/338 2796/1429/338 2799/1432/338 +f 403/398/335 2799/1432/335 398/394/335 +f 2796/1429/335 733/689/335 745/700/335 +f 2796/1429/335 745/700/335 2799/1432/335 +f 2799/1432/335 745/700/335 742/697/335 +f 2799/1432/335 742/697/335 2797/1430/335 +f 398/394/335 2799/1432/335 2797/1430/335 +f 398/394/338 2797/1430/338 395/391/338 +f 2712/1408/335 2711/1407/335 2801/1433/335 +f 2712/1408/335 2801/1433/335 2802/1434/335 +f 2711/1407/335 457/450/335 456/449/335 +f 2711/1407/335 456/449/335 2801/1433/335 +f 2801/1433/335 456/449/335 455/448/335 +f 2801/1433/335 455/448/335 2719/1410/335 +f 2802/1434/335 2801/1433/335 2719/1410/335 +f 2802/1434/335 2719/1410/335 2718/1409/335 +f 528/1435/458 2733/1436/459 529/1437/460 +f 775/726/335 2805/1438/335 2806/1439/335 +f 775/726/335 2806/1439/335 2807/1440/335 +f 2805/1438/335 451/444/335 450/443/335 +f 2805/1438/335 450/443/335 2806/1439/335 +f 2806/1439/338 450/443/338 449/442/338 +f 2806/1439/335 449/442/335 2708/1404/335 +f 2807/1440/335 2806/1439/335 2708/1404/335 +f 2807/1440/338 2708/1404/338 2707/1403/338 +f 359/359/335 2809/1441/335 2810/1442/335 +f 359/359/335 2810/1442/335 503/492/335 +f 2809/1441/335 767/719/335 766/718/335 +f 2809/1441/335 766/718/335 2810/1442/335 +f 2810/1442/335 766/718/335 425/421/335 +f 2810/1442/335 425/421/335 2811/1443/335 +f 503/492/335 2810/1442/335 2811/1443/335 +f 503/492/335 2811/1443/335 500/489/335 +f 773/724/335 2812/1444/335 2813/1445/335 +f 773/724/338 2813/1445/338 774/725/338 +f 2812/1444/338 424/420/338 447/440/338 +f 2812/1444/335 447/440/335 2813/1445/335 +f 2813/1445/335 447/440/335 451/444/335 +f 2813/1445/335 451/444/335 2805/1438/335 +f 774/725/338 2813/1445/338 2805/1438/338 +f 774/725/335 2805/1438/335 775/726/335 +f 500/489/335 2811/1443/335 2814/1446/335 +f 500/489/335 2814/1446/335 786/734/335 +f 2811/1443/335 425/421/335 428/424/335 +f 2811/1443/335 428/424/335 2814/1446/335 +f 2814/1446/335 428/424/335 416/412/335 +f 2814/1446/335 416/412/335 2815/1447/335 +f 786/734/335 2814/1446/335 2815/1447/335 +f 786/734/335 2815/1447/335 787/735/335 +f 787/735/335 2815/1447/335 2816/1448/335 +f 787/735/338 2816/1448/338 792/740/338 +f 2815/1447/335 416/412/335 419/415/335 +f 2815/1447/335 419/415/335 2816/1448/335 +f 2816/1448/335 419/415/335 424/420/335 +f 2816/1448/338 424/420/338 2812/1444/338 +f 792/740/338 2816/1448/338 2812/1444/338 +f 792/740/335 2812/1444/335 773/724/335 +f 367/366/335 2817/1449/335 2818/1450/335 +f 367/366/335 2818/1450/335 362/362/335 +f 2817/1449/335 795/744/335 794/743/335 +f 2817/1449/335 794/743/335 2818/1450/335 +f 2818/1450/335 794/743/335 767/719/335 +f 2818/1450/335 767/719/335 2809/1441/335 +f 362/362/335 2818/1450/335 2809/1441/335 +f 362/362/335 2809/1441/335 359/359/335 +f 530/513/335 2821/1451/335 2822/1452/335 +f 530/513/335 2822/1452/335 839/787/335 +f 2821/1451/338 800/749/338 799/748/338 +f 2821/1451/335 799/748/335 2822/1452/335 +f 2822/1452/335 799/748/335 795/744/335 +f 2822/1452/335 795/744/335 2817/1449/335 +f 839/787/335 2822/1452/335 2817/1449/335 +f 839/787/335 2817/1449/335 367/366/335 +f 525/511/335 2823/1453/335 2824/1454/335 +f 525/511/335 2824/1454/335 762/715/335 +f 2823/1453/335 802/751/335 801/750/335 +f 2823/1453/335 801/750/335 2824/1454/335 +f 2824/1454/335 801/750/335 800/749/335 +f 2824/1454/338 800/749/338 2821/1451/338 +f 762/715/335 2824/1454/335 2821/1451/335 +f 762/715/335 2821/1451/335 530/513/335 +f 516/505/335 2825/1455/335 2826/1456/335 +f 516/505/335 2826/1456/335 746/701/335 +f 2825/1455/335 808/757/335 807/756/335 +f 2825/1455/335 807/756/335 2826/1456/335 +f 2826/1456/335 807/756/335 806/755/335 +f 2826/1456/335 806/755/335 2827/1457/335 +f 746/701/335 2826/1456/335 2827/1457/335 +f 746/701/335 2827/1457/335 521/507/335 +f 543/522/335 2828/1458/335 2829/1459/335 +f 543/522/335 2829/1459/335 723/680/335 +f 2828/1458/335 814/763/335 813/762/335 +f 2828/1458/335 813/762/335 2829/1459/335 +f 2829/1459/335 813/762/335 812/761/335 +f 2829/1459/335 812/761/335 2830/1460/335 +f 723/680/335 2829/1459/335 2830/1460/335 +f 723/680/335 2830/1460/335 512/501/335 +f 722/679/335 2831/1461/335 2832/1462/335 +f 722/679/335 2832/1462/335 718/675/335 +f 2831/1461/335 819/768/335 818/767/335 +f 2831/1461/335 818/767/335 2832/1462/335 +f 2832/1462/335 818/767/335 817/766/335 +f 2832/1462/335 817/766/335 2833/1463/335 +f 718/675/335 2832/1462/335 2833/1463/335 +f 718/675/335 2833/1463/335 539/518/335 +f 707/668/335 2834/1464/335 2835/1465/335 +f 707/668/335 2835/1465/335 702/664/335 +f 2834/1464/335 828/776/335 827/775/335 +f 2834/1464/335 827/775/335 2835/1465/335 +f 2835/1465/335 827/775/335 826/774/335 +f 2835/1465/335 826/774/335 2836/1466/335 +f 702/664/335 2835/1465/335 2836/1466/335 +f 702/664/335 2836/1466/335 699/661/335 +f 698/660/335 2837/1467/335 2838/1468/335 +f 698/660/335 2838/1468/335 693/656/335 +f 2837/1467/335 834/782/335 833/781/335 +f 2837/1467/335 833/781/335 2838/1468/335 +f 2838/1468/335 833/781/335 832/780/335 +f 2838/1468/335 832/780/335 2839/1469/335 +f 693/656/335 2838/1468/335 2839/1469/335 +f 693/656/335 2839/1469/335 690/653/335 +f 539/518/335 2833/1463/335 2840/1470/335 +f 539/518/335 2840/1470/335 540/519/335 +f 2833/1463/335 817/766/335 837/785/335 +f 2833/1463/335 837/785/335 2840/1470/335 +f 2840/1470/335 837/785/335 814/763/335 +f 2840/1470/335 814/763/335 2828/1458/335 +f 540/519/335 2840/1470/335 2828/1458/335 +f 540/519/335 2828/1458/335 543/522/335 +f 521/507/335 2827/1457/335 2841/1471/335 +f 521/507/335 2841/1471/335 522/508/335 +f 2827/1457/335 806/755/335 842/791/335 +f 2827/1457/335 842/791/335 2841/1471/335 +f 2841/1471/335 842/791/335 802/751/335 +f 2841/1471/335 802/751/335 2823/1453/335 +f 522/508/335 2841/1471/335 2823/1453/335 +f 522/508/335 2823/1453/335 525/511/335 +f 512/501/335 2830/1460/335 2842/1472/335 +f 512/501/335 2842/1472/335 513/502/335 +f 2830/1460/335 812/761/335 844/793/335 +f 2830/1460/335 844/793/335 2842/1472/335 +f 2842/1472/335 844/793/335 808/757/335 +f 2842/1472/335 808/757/335 2825/1455/335 +f 513/502/335 2842/1472/335 2825/1455/335 +f 513/502/335 2825/1455/335 516/505/335 +f 695/657/461 2786/1473/462 696/658/463 +f 690/653/335 2839/1469/335 2845/1474/335 +f 690/653/335 2845/1474/335 849/798/335 +f 2839/1469/335 832/780/335 847/796/335 +f 2839/1469/335 847/796/335 2845/1474/335 +f 2845/1474/335 847/796/335 819/768/335 +f 2845/1474/335 819/768/335 2831/1461/335 +f 849/798/335 2845/1474/335 2831/1461/335 +f 849/798/335 2831/1461/335 722/679/335 +f 585/557/335 2846/1475/335 2847/1476/335 +f 585/557/335 2847/1476/335 650/616/335 +f 2846/1475/338 860/810/338 859/809/338 +f 2846/1475/338 859/809/338 2847/1476/338 +f 2847/1476/338 859/809/338 858/808/338 +f 2847/1476/338 858/808/338 2773/1423/338 +f 650/616/335 2847/1476/335 2773/1423/335 +f 650/616/335 2773/1423/335 641/611/335 +f 590/561/335 2757/1417/335 2848/1477/335 +f 590/561/338 2848/1477/338 591/562/338 +f 2757/1417/335 662/627/335 867/818/335 +f 2757/1417/335 867/818/335 2848/1477/335 +f 2848/1477/335 867/818/335 866/817/335 +f 2848/1477/338 866/817/338 2849/1478/338 +f 591/562/338 2848/1477/338 2849/1478/338 +f 591/562/335 2849/1478/335 581/553/335 +f 581/553/335 2849/1478/335 2850/1479/335 +f 581/553/338 2850/1479/338 582/554/338 +f 2849/1478/338 866/817/338 869/820/338 +f 2849/1478/335 869/820/335 2850/1479/335 +f 2850/1479/335 869/820/335 860/810/335 +f 2850/1479/338 860/810/338 2846/1475/338 +f 582/554/338 2850/1479/338 2846/1475/338 +f 582/554/335 2846/1475/335 585/557/335 +f 628/598/335 2768/1422/335 2852/1480/335 +f 628/598/335 2852/1480/335 623/594/335 +f 2768/1422/335 633/603/335 632/602/335 +f 2768/1422/335 632/602/335 2852/1480/335 +f 2852/1480/335 632/602/335 631/601/335 +f 2852/1480/335 631/601/335 2853/1481/335 +f 623/594/335 2852/1480/335 2853/1481/335 +f 623/594/338 2853/1481/338 620/591/338 +f 708/669/335 2855/1482/335 2856/1483/335 +f 708/669/335 2856/1483/335 877/828/335 +f 2855/1482/338 873/824/338 872/823/338 +f 2855/1482/335 872/823/335 2856/1483/335 +f 2856/1483/335 872/823/335 828/776/335 +f 2856/1483/335 828/776/335 2834/1464/335 +f 877/828/335 2856/1483/335 2834/1464/335 +f 877/828/335 2834/1464/335 707/668/335 +f 552/528/335 2857/1484/335 2858/1485/335 +f 552/528/335 2858/1485/335 821/770/335 +f 2857/1484/335 875/826/335 874/825/335 +f 2857/1484/335 874/825/335 2858/1485/335 +f 2858/1485/335 874/825/335 873/824/335 +f 2858/1485/338 873/824/338 2855/1482/338 +f 821/770/335 2858/1485/335 2855/1482/335 +f 821/770/335 2855/1482/335 708/669/335 +f 678/643/335 2859/1486/335 2860/1487/335 +f 678/643/335 2860/1487/335 679/644/335 +f 2859/1486/335 608/579/335 882/834/335 +f 2859/1486/335 882/834/335 2860/1487/335 +f 2860/1487/335 882/834/335 881/833/335 +f 2860/1487/335 881/833/335 2861/1488/335 +f 679/644/335 2860/1487/335 2861/1488/335 +f 679/644/335 2861/1488/335 548/524/335 +f 620/591/338 2853/1481/338 2862/1489/338 +f 620/591/338 2862/1489/338 889/841/338 +f 2853/1481/335 631/601/335 629/599/335 +f 2853/1481/335 629/599/335 2862/1489/335 +f 2862/1489/335 629/599/335 603/574/335 +f 2862/1489/335 603/574/335 2863/1490/335 +f 889/841/338 2862/1489/338 2863/1490/338 +f 889/841/338 2863/1490/338 890/842/338 +f 899/852/338 2864/1491/338 2865/1492/338 +f 899/852/335 2865/1492/335 900/853/335 +f 2864/1491/335 599/570/335 609/580/335 +f 2864/1491/335 609/580/335 2865/1492/335 +f 2865/1492/335 609/580/335 608/579/335 +f 2865/1492/335 608/579/335 2859/1486/335 +f 900/853/335 2865/1492/335 2859/1486/335 +f 900/853/335 2859/1486/335 678/643/335 +f 890/842/338 2863/1490/338 2866/1493/338 +f 890/842/335 2866/1493/335 903/856/335 +f 2863/1490/335 603/574/335 600/571/335 +f 2863/1490/335 600/571/335 2866/1493/335 +f 2866/1493/338 600/571/338 599/570/338 +f 2866/1493/335 599/570/335 2864/1491/335 +f 903/856/335 2866/1493/335 2864/1491/335 +f 903/856/338 2864/1491/338 899/852/338 +f 548/524/335 2861/1488/335 2867/1494/335 +f 548/524/335 2867/1494/335 549/525/335 +f 2861/1488/335 881/833/335 905/858/335 +f 2861/1488/335 905/858/335 2867/1494/335 +f 2867/1494/335 905/858/335 875/826/335 +f 2867/1494/338 875/826/338 2857/1484/338 +f 549/525/335 2867/1494/335 2857/1484/335 +f 549/525/335 2857/1484/335 552/528/335 +f 565/537/338 2775/1425/338 2869/1495/338 +f 565/537/335 2869/1495/335 560/533/335 +f 2775/1425/335 639/609/335 638/608/335 +f 2775/1425/338 638/608/338 2869/1495/338 +f 2869/1495/335 638/608/335 637/607/335 +f 2869/1495/335 637/607/335 2766/1420/335 +f 560/533/335 2869/1495/335 2766/1420/335 +f 560/533/335 2766/1420/335 557/530/335 +f 699/661/335 2836/1466/335 2871/1496/335 +f 699/661/335 2871/1496/335 910/863/335 +f 2836/1466/335 826/774/335 908/861/335 +f 2836/1466/335 908/861/335 2871/1496/335 +f 2871/1496/335 908/861/335 834/782/335 +f 2871/1496/335 834/782/335 2837/1467/335 +f 910/863/335 2871/1496/335 2837/1467/335 +f 910/863/335 2837/1467/335 698/660/335 +f 980/930/389 2875/1497/389 2876/1498/389 +f 980/930/389 2876/1498/389 976/926/389 +f 2875/1497/389 1059/997/389 1062/1000/389 +f 2875/1497/389 1062/1000/389 2876/1498/389 +f 2876/1498/389 1062/1000/389 1064/1002/389 +f 2876/1498/389 1064/1002/389 2877/1499/389 +f 976/926/389 2876/1498/389 2877/1499/389 +f 976/926/389 2877/1499/389 974/924/389 +f 964/915/390 2887/1500/390 2888/1501/390 +f 964/915/390 2888/1501/390 1299/1202/390 +f 2887/1500/389 1311/1215/389 1310/1214/389 +f 2887/1500/389 1310/1214/389 2888/1501/389 +f 2888/1501/389 1310/1214/389 948/899/389 +f 2888/1501/389 948/899/389 2889/1502/389 +f 1299/1202/389 2888/1501/389 2889/1502/389 +f 1299/1202/389 2889/1502/389 1296/1199/389 +f 974/924/389 2877/1499/389 2891/1503/389 +f 974/924/389 2891/1503/389 972/922/389 +f 2877/1499/389 1064/1002/389 1292/1195/389 +f 2877/1499/389 1292/1195/389 2891/1503/389 +f 2891/1503/389 1292/1195/389 1047/985/389 +f 2891/1503/389 1047/985/389 2892/1504/389 +f 972/922/389 2891/1503/389 2892/1504/389 +f 972/922/389 2892/1504/389 969/919/389 +f 1296/1199/389 2889/1502/389 2899/1505/389 +f 1296/1199/389 2899/1505/389 1297/1200/389 +f 2889/1502/390 948/899/390 1022/971/390 +f 2889/1502/389 1022/971/389 2899/1505/389 +f 2899/1505/389 1022/971/389 1021/970/389 +f 2899/1505/389 1021/970/389 2900/1506/389 +f 1297/1200/389 2899/1505/389 2900/1506/389 +f 1297/1200/389 2900/1506/389 1300/1203/389 +f 967/917/464 2903/1507/465 968/918/466 +f 968/918/467 2904/1508/468 977/927/469 +f 977/927/470 2905/1509/471 978/928/472 +f 2906/1510/389 2907/1511/389 2908/1512/389 +f 2906/1510/389 2908/1512/389 2909/1513/389 +f 2907/1511/389 1019/968/389 1322/1227/389 +f 2907/1511/389 1322/1227/389 2908/1512/389 +f 2908/1512/389 1322/1227/389 1015/964/389 +f 2908/1512/389 1015/964/389 2910/1514/389 +f 2909/1513/389 2908/1512/389 2910/1514/389 +f 2909/1513/389 2910/1514/389 2911/1515/389 +f 1290/1192/401 2927/1516/473 1081/1193/397 +f 1315/1219/474 2930/1517/475 1090/1220/476 +f 1108/1518/401 2932/1519/477 1109/1033/401 +f 1159/1078/389 2936/1520/389 2937/1521/389 +f 1159/1078/389 2937/1521/389 1161/1081/389 +f 2936/1520/389 1241/1155/389 1239/1153/389 +f 2936/1520/389 1239/1153/389 2937/1521/389 +f 2937/1521/389 1239/1153/389 1059/997/389 +f 2937/1521/389 1059/997/389 2875/1497/389 +f 1161/1081/389 2937/1521/389 2875/1497/389 +f 1161/1081/389 2875/1497/389 980/930/389 +f 1155/1074/389 2948/1522/389 2949/1523/389 +f 1155/1074/390 2949/1523/390 1156/1075/390 +f 2948/1522/389 1227/1141/389 1423/1329/389 +f 2948/1522/389 1423/1329/389 2949/1523/389 +f 2949/1523/389 1423/1329/389 1241/1155/389 +f 2949/1523/389 1241/1155/389 2936/1520/389 +f 1156/1075/389 2949/1523/389 2936/1520/389 +f 1156/1075/389 2936/1520/389 1159/1078/389 +f 978/928/478 2957/1524/479 1163/1083/478 +f 1163/1083/480 2954/1525/481 1150/1080/482 +f 1189/1109/389 2958/1526/389 2959/1527/389 +f 1189/1109/389 2959/1527/389 1493/1394/389 +f 2958/1526/389 1197/1114/389 1489/1390/389 +f 2958/1526/389 1489/1390/389 2959/1527/389 +f 2959/1527/389 1489/1390/389 1205/1122/389 +f 2959/1527/389 1205/1122/389 2960/1528/389 +f 1493/1394/389 2959/1527/389 2960/1528/389 +f 1493/1394/389 2960/1528/389 1122/1045/389 +f 1126/1049/389 2965/1529/389 2966/1530/389 +f 1126/1049/390 2966/1530/390 1433/1339/390 +f 2965/1529/389 1203/1120/389 1432/1338/389 +f 2965/1529/389 1432/1338/389 2966/1530/389 +f 2966/1530/389 1432/1338/389 1431/1337/389 +f 2966/1530/390 1431/1337/390 2967/1531/390 +f 1433/1339/390 2966/1530/390 2967/1531/390 +f 1433/1339/389 2967/1531/389 1206/1123/389 +f 1263/1532/483 2976/1533/484 1422/1534/485 +f 1287/1535/486 2931/1536/487 1108/1518/488 +f 1081/1193/489 2982/1537/490 1082/1017/489 +f 969/919/389 2892/1504/389 2983/1538/389 +f 969/919/389 2983/1538/389 970/920/389 +f 2892/1504/389 1047/985/389 1308/1212/389 +f 2892/1504/389 1308/1212/389 2983/1538/389 +f 2983/1538/389 1308/1212/389 1307/1211/389 +f 2983/1538/389 1307/1211/389 2984/1539/389 +f 970/920/389 2983/1538/389 2984/1539/389 +f 970/920/389 2984/1539/389 960/911/389 +f 960/911/389 2984/1539/389 2985/1540/389 +f 960/911/389 2985/1540/389 961/912/389 +f 2984/1539/389 1307/1211/389 1312/1216/389 +f 2984/1539/389 1312/1216/389 2985/1540/389 +f 2985/1540/389 1312/1216/389 1311/1215/389 +f 2985/1540/389 1311/1215/389 2887/1500/389 +f 961/912/389 2985/1540/389 2887/1500/389 +f 961/912/389 2887/1500/389 964/915/389 +f 1300/1203/389 2900/1506/389 2987/1541/389 +f 1300/1203/389 2987/1541/389 2988/1542/389 +f 2900/1506/390 1021/970/390 1020/969/390 +f 2900/1506/389 1020/969/389 2987/1541/389 +f 2987/1541/389 1020/969/389 1019/968/389 +f 2987/1541/390 1019/968/390 2907/1511/390 +f 2988/1542/390 2987/1541/390 2907/1511/390 +f 2988/1542/389 2907/1511/389 2906/1510/389 +f 1091/1025/491 2922/1543/492 1092/1026/493 +f 2911/1515/389 2910/1514/389 2991/1544/389 +f 2911/1515/389 2991/1544/389 2992/1545/389 +f 2910/1514/389 1015/964/389 1014/963/389 +f 2910/1514/389 1014/963/389 2991/1544/389 +f 2991/1544/389 1014/963/389 1013/962/389 +f 2991/1544/389 1013/962/389 2993/1546/389 +f 2992/1545/389 2991/1544/389 2993/1546/389 +f 2992/1545/389 2993/1546/389 1345/1251/389 +f 1332/1238/494 2994/1547/495 1333/1239/496 +f 2994/1547/495 1095/1278/435 2995/1548/497 +f 1333/1239/496 2994/1547/495 2995/1548/496 +f 1333/1239/390 2995/1548/390 1334/1240/390 +f 1065/1003/389 2996/1549/389 2997/1550/389 +f 1065/1003/389 2997/1550/389 1066/1004/389 +f 2996/1549/389 990/940/389 1338/1244/389 +f 2996/1549/389 1338/1244/389 2997/1550/389 +f 2997/1550/389 1338/1244/389 1337/1243/389 +f 2997/1550/389 1337/1243/389 2998/1551/389 +f 1066/1004/389 2997/1550/389 2998/1551/389 +f 1066/1004/389 2998/1551/389 924/879/389 +f 1345/1251/389 2993/1546/389 2999/1552/389 +f 1345/1251/390 2999/1552/390 1346/1252/390 +f 2993/1546/390 1013/962/390 1011/960/390 +f 2993/1546/389 1011/960/389 2999/1552/389 +f 2999/1552/389 1011/960/389 985/935/389 +f 2999/1552/389 985/935/389 3000/1553/389 +f 1346/1252/390 2999/1552/390 3000/1553/390 +f 1346/1252/389 3000/1553/389 1347/1253/389 +f 1358/1265/389 3001/1554/389 3002/1555/389 +f 1358/1265/389 3002/1555/389 1359/1266/389 +f 3001/1554/389 981/931/389 991/941/389 +f 3001/1554/390 991/941/390 3002/1555/390 +f 3002/1555/389 991/941/389 990/940/389 +f 3002/1555/389 990/940/389 2996/1549/389 +f 1359/1266/389 3002/1555/389 2996/1549/389 +f 1359/1266/389 2996/1549/389 1065/1003/389 +f 1347/1253/389 3000/1553/389 3003/1556/389 +f 1347/1253/390 3003/1556/390 1362/1269/390 +f 3000/1553/389 985/935/389 982/932/389 +f 3000/1553/389 982/932/389 3003/1556/389 +f 3003/1556/389 982/932/389 981/931/389 +f 3003/1556/389 981/931/389 3001/1554/389 +f 1362/1269/390 3003/1556/390 3001/1554/390 +f 1362/1269/389 3001/1554/389 1358/1265/389 +f 924/879/389 2998/1551/389 3004/1557/389 +f 924/879/390 3004/1557/390 925/880/390 +f 2998/1551/389 1337/1243/389 1366/1273/389 +f 2998/1551/389 1366/1273/389 3004/1557/389 +f 3004/1557/389 1366/1273/389 1365/1272/389 +f 3004/1557/390 1365/1272/390 3005/1558/390 +f 925/880/390 3004/1557/390 3005/1558/390 +f 925/880/389 3005/1558/389 928/883/389 +f 928/883/389 3005/1558/389 3009/1559/389 +f 928/883/389 3009/1559/389 1407/1316/389 +f 3005/1558/390 1365/1272/390 1371/1279/390 +f 3005/1558/389 1371/1279/389 3009/1559/389 +f 3009/1559/389 1095/1278/435 3010/1560/389 +f 1407/1316/389 3009/1559/389 3010/1560/389 +f 1407/1316/389 3010/1560/389 1409/1318/389 +f 1334/1240/389 2995/1548/389 3011/1561/389 +f 1334/1240/389 3011/1561/389 1330/1236/389 +f 2995/1548/389 1095/1278/435 1370/1277/389 +f 2995/1548/389 1370/1277/389 3011/1561/389 +f 3011/1561/389 1370/1277/389 1369/1276/389 +f 3011/1561/389 1369/1276/389 3012/1562/389 +f 1330/1236/389 3011/1561/389 3012/1562/389 +f 1330/1236/389 3012/1562/389 1094/1028/389 +f 1086/1021/389 3013/1563/389 3014/1564/389 +f 1086/1021/389 3014/1564/389 1314/1218/389 +f 3013/1563/389 1376/1284/389 1375/1283/389 +f 3013/1563/389 1375/1283/389 3014/1564/389 +f 3014/1564/389 1375/1283/389 1374/1282/389 +f 3014/1564/389 1374/1282/389 3015/1565/389 +f 1314/1218/389 3014/1564/389 3015/1565/389 +f 1314/1218/389 3015/1565/389 1085/1020/389 +f 1077/1013/389 3016/1566/389 3017/1567/389 +f 1077/1013/389 3017/1567/389 1289/1191/389 +f 3016/1566/389 1382/1290/389 1381/1289/389 +f 3016/1566/389 1381/1289/389 3017/1567/389 +f 3017/1567/389 1381/1289/389 1380/1288/389 +f 3017/1567/389 1380/1288/389 3018/1568/389 +f 1289/1191/389 3017/1567/389 3018/1568/389 +f 1289/1191/389 3018/1568/389 1112/1036/389 +f 1104/1029/389 3019/1569/389 3020/1570/389 +f 1104/1029/389 3020/1570/389 1282/1186/389 +f 3019/1569/389 1389/1297/389 1388/1296/389 +f 3019/1569/389 1388/1296/389 3020/1570/389 +f 3020/1570/389 1388/1296/389 1387/1295/389 +f 3020/1570/389 1387/1295/389 3021/1571/389 +f 1282/1186/389 3020/1570/389 3021/1571/389 +f 1282/1186/389 3021/1571/389 1284/1188/389 +f 1264/1175/389 3022/1572/389 3023/1573/389 +f 1264/1175/389 3023/1573/389 1265/1176/389 +f 3022/1572/389 1398/1307/389 1397/1306/389 +f 3022/1572/389 1397/1306/389 3023/1573/389 +f 3023/1573/389 1397/1306/389 1396/1305/389 +f 3023/1573/389 1396/1305/389 3024/1574/389 +f 1265/1176/389 3023/1573/389 3024/1574/389 +f 1265/1176/389 3024/1574/389 1268/1179/389 +f 1255/1169/389 3025/1575/389 3026/1576/389 +f 1255/1169/389 3026/1576/389 1256/1170/389 +f 3025/1575/389 1404/1313/389 1403/1312/389 +f 3025/1575/389 1403/1312/389 3026/1576/389 +f 3026/1576/389 1403/1312/389 1402/1311/389 +f 3026/1576/389 1402/1311/389 3027/1577/389 +f 1256/1170/389 3026/1576/389 3027/1577/389 +f 1256/1170/389 3027/1577/389 1259/1173/389 +f 1112/1036/389 3018/1568/389 3028/1578/389 +f 1112/1036/389 3028/1578/389 1107/1032/389 +f 3018/1568/389 1380/1288/389 1406/1315/389 +f 3018/1568/389 1406/1315/389 3028/1578/389 +f 3028/1578/389 1406/1315/389 1389/1297/389 +f 3028/1578/389 1389/1297/389 3019/1569/389 +f 1107/1032/389 3028/1578/389 3019/1569/389 +f 1107/1032/389 3019/1569/389 1104/1029/389 +f 1409/1318/498 3029/1579/495 1410/1319/498 +f 1094/1028/389 3012/1562/389 3030/1580/389 +f 1094/1028/389 3030/1580/389 1089/1024/389 +f 3012/1562/389 1369/1276/389 1414/1321/389 +f 3012/1562/389 1414/1321/389 3030/1580/389 +f 3030/1580/389 1414/1321/389 1376/1284/389 +f 3030/1580/389 1376/1284/389 3013/1563/389 +f 1089/1024/389 3030/1580/389 3013/1563/389 +f 1089/1024/389 3013/1563/389 1086/1021/389 +f 1085/1020/389 3015/1565/389 3031/1581/389 +f 1085/1020/389 3031/1581/389 1080/1016/389 +f 3015/1565/389 1374/1282/389 1416/1323/389 +f 3015/1565/389 1416/1323/389 3031/1581/389 +f 3031/1581/389 1416/1323/389 1382/1290/389 +f 3031/1581/389 1382/1290/389 3016/1566/389 +f 1080/1016/389 3031/1581/389 3016/1566/389 +f 1080/1016/389 3016/1566/389 1077/1013/389 +f 1261/1582/499 3034/1583/500 1262/1584/501 +f 1284/1188/389 3021/1571/389 3035/1585/389 +f 1284/1188/389 3035/1585/389 1420/1327/389 +f 3021/1571/389 1387/1295/389 1419/1326/389 +f 3021/1571/389 1419/1326/389 3035/1585/389 +f 3035/1585/389 1419/1326/389 1404/1313/389 +f 3035/1585/389 1404/1313/389 3025/1575/389 +f 1420/1327/389 3035/1585/389 3025/1575/389 +f 1420/1327/389 3025/1575/389 1255/1169/389 +f 1206/1123/389 2967/1531/389 3036/1586/389 +f 1206/1123/389 3036/1586/389 1216/1129/389 +f 2967/1531/390 1431/1337/390 1430/1336/390 +f 2967/1531/390 1430/1336/390 3036/1586/390 +f 3036/1586/390 1430/1336/390 1429/1335/390 +f 3036/1586/389 1429/1335/389 3037/1587/389 +f 1216/1129/389 3036/1586/389 3037/1587/389 +f 1216/1129/390 3037/1587/390 1154/1073/390 +f 1146/1066/390 3038/1588/390 3039/1589/390 +f 1146/1066/390 3039/1589/390 1158/1077/390 +f 3038/1588/389 1438/1343/389 1437/1342/389 +f 3038/1588/389 1437/1342/389 3039/1589/389 +f 3039/1589/389 1437/1342/389 1227/1141/389 +f 3039/1589/389 1227/1141/389 2948/1522/389 +f 1158/1077/390 3039/1589/390 2948/1522/390 +f 1158/1077/389 2948/1522/389 1155/1074/389 +f 1154/1073/390 3037/1587/390 3040/1590/390 +f 1154/1073/389 3040/1590/389 1149/1069/389 +f 3037/1587/389 1429/1335/389 1441/1346/389 +f 3037/1587/389 1441/1346/389 3040/1590/389 +f 3040/1590/389 1441/1346/389 1438/1343/389 +f 3040/1590/389 1438/1343/389 3038/1588/389 +f 1149/1069/390 3040/1590/390 3038/1588/390 +f 1149/1069/390 3038/1588/390 1146/1066/390 +f 1185/1105/389 3042/1591/389 3043/1592/389 +f 1185/1105/389 3043/1592/389 1186/1106/389 +f 3042/1591/389 1199/1116/389 1198/1115/389 +f 3042/1591/389 1198/1115/389 3043/1592/389 +f 3043/1592/389 1198/1115/389 1197/1114/389 +f 3043/1592/389 1197/1114/389 2958/1526/389 +f 1186/1106/389 3043/1592/389 2958/1526/389 +f 1186/1106/389 2958/1526/389 1189/1109/389 +f 1268/1179/389 3024/1574/389 3045/1593/389 +f 1268/1179/389 3045/1593/389 1448/1353/389 +f 3024/1574/389 1396/1305/389 1447/1352/389 +f 3024/1574/389 1447/1352/389 3045/1593/389 +f 3045/1593/389 1447/1352/389 1446/1351/389 +f 3045/1593/390 1446/1351/390 3046/1594/390 +f 1448/1353/390 3045/1593/390 3046/1594/390 +f 1448/1353/389 3046/1594/389 1273/1181/389 +f 1273/1181/389 3046/1594/389 3047/1595/389 +f 1273/1181/389 3047/1595/389 1391/1299/389 +f 3046/1594/390 1446/1351/390 1445/1350/390 +f 3046/1594/389 1445/1350/389 3047/1595/389 +f 3047/1595/389 1445/1350/389 1444/1349/389 +f 3047/1595/389 1444/1349/389 3048/1596/389 +f 1391/1299/389 3047/1595/389 3048/1596/389 +f 1391/1299/389 3048/1596/389 1121/1044/389 +f 1113/1037/389 3049/1597/389 3050/1598/389 +f 1113/1037/389 3050/1598/389 1246/1160/389 +f 3049/1597/389 1453/1357/389 1452/1356/389 +f 3049/1597/389 1452/1356/389 3050/1598/389 +f 3050/1598/389 1452/1356/389 1173/1093/389 +f 3050/1598/389 1173/1093/389 3051/1599/389 +f 1246/1160/389 3050/1598/389 3051/1599/389 +f 1246/1160/389 3051/1599/389 1243/1157/389 +f 1459/1362/389 3052/1600/389 3053/1601/389 +f 1459/1362/390 3053/1601/390 1460/1363/390 +f 3052/1600/389 1172/1092/389 1195/1112/389 +f 3052/1600/389 1195/1112/389 3053/1601/389 +f 3053/1601/389 1195/1112/389 1199/1116/389 +f 3053/1601/389 1199/1116/389 3042/1591/389 +f 1460/1363/390 3053/1601/390 3042/1591/390 +f 1460/1363/389 3042/1591/389 1185/1105/389 +f 1243/1157/389 3051/1599/389 3054/1602/389 +f 1243/1157/389 3054/1602/389 1469/1370/389 +f 3051/1599/389 1173/1093/389 1176/1096/389 +f 3051/1599/389 1176/1096/389 3054/1602/389 +f 3054/1602/389 1176/1096/389 1164/1084/389 +f 3054/1602/389 1164/1084/389 3055/1603/389 +f 1469/1370/389 3054/1602/389 3055/1603/389 +f 1469/1370/390 3055/1603/390 1470/1371/390 +f 1470/1371/390 3055/1603/390 3056/1604/390 +f 1470/1371/389 3056/1604/389 1475/1376/389 +f 3055/1603/389 1164/1084/389 1167/1087/389 +f 3055/1603/390 1167/1087/390 3056/1604/390 +f 3056/1604/390 1167/1087/390 1172/1092/390 +f 3056/1604/389 1172/1092/389 3052/1600/389 +f 1475/1376/389 3056/1604/389 3052/1600/389 +f 1475/1376/389 3052/1600/389 1459/1362/389 +f 1121/1044/389 3048/1596/389 3057/1605/389 +f 1121/1044/389 3057/1605/389 1116/1040/389 +f 3048/1596/389 1444/1349/389 1477/1379/389 +f 3048/1596/389 1477/1379/389 3057/1605/389 +f 3057/1605/389 1477/1379/389 1453/1357/389 +f 3057/1605/389 1453/1357/389 3049/1597/389 +f 1116/1040/389 3057/1605/389 3049/1597/389 +f 1116/1040/389 3049/1597/389 1113/1037/389 +f 1122/1045/389 2960/1528/389 3059/1606/389 +f 1122/1045/389 3059/1606/389 1123/1046/389 +f 2960/1528/389 1205/1122/389 1204/1121/389 +f 2960/1528/389 1204/1121/389 3059/1606/389 +f 3059/1606/389 1204/1121/389 1203/1120/389 +f 3059/1606/389 1203/1120/389 2965/1529/389 +f 1123/1046/389 3059/1606/389 2965/1529/389 +f 1123/1046/389 2965/1529/389 1126/1049/389 +f 1259/1173/389 3027/1577/389 3061/1607/389 +f 1259/1173/390 3061/1607/390 1481/1383/390 +f 3027/1577/389 1402/1311/389 1480/1382/389 +f 3027/1577/389 1480/1382/389 3061/1607/389 +f 3061/1607/389 1480/1382/389 1398/1307/389 +f 3061/1607/389 1398/1307/389 3022/1572/389 +f 1481/1383/390 3061/1607/390 3022/1572/390 +f 1481/1383/389 3022/1572/389 1264/1175/389 +f 2200/1608/502 3033/1609/503 1261/1582/504 +f 1343/1249/505 3090/1610/505 3114/1611/389 +f 1343/1249/425 3114/1611/389 1344/1250/389 +f 3090/1610/425 1348/1254/427 1351/1257/389 +f 3090/1610/425 1351/1257/389 3114/1611/389 +f 3114/1611/389 1351/1257/389 1002/952/389 +f 3114/1611/389 1002/952/389 3115/1612/389 +f 1344/1250/389 3114/1611/389 3115/1612/389 +f 1344/1250/389 3115/1612/389 1345/1251/389 +f 2911/1515/389 3116/1613/389 3117/1614/389 +f 2911/1515/389 3117/1614/389 2909/1513/389 +f 3116/1613/389 1010/959/389 1327/1232/389 +f 3116/1613/389 1327/1232/389 3117/1614/389 +f 3117/1614/389 1327/1232/389 933/885/389 +f 3117/1614/389 933/885/389 3118/1615/389 +f 2909/1513/389 3117/1614/389 3118/1615/389 +f 2909/1513/389 3118/1615/389 2906/1510/389 +f 1300/1203/389 3119/1616/389 3120/1617/389 +f 1300/1203/389 3120/1617/389 1301/1204/389 +f 3119/1616/389 941/892/389 1303/1206/389 +f 3119/1616/389 1303/1206/389 3120/1617/389 +f 3120/1617/389 1303/1206/389 1023/1208/389 +f 3120/1617/389 1023/1208/389 3121/1618/389 +f 1301/1204/389 3120/1617/389 3121/1618/389 +f 1301/1204/390 3121/1618/390 1034/974/390 +f 1034/974/389 3121/1618/389 3122/1619/389 +f 1034/974/389 3122/1619/389 1035/975/389 +f 3121/1618/389 1026/1620/415 3122/1619/389 +f 1345/1251/389 3115/1612/389 3123/1621/389 +f 1345/1251/389 3123/1621/389 2992/1545/389 +f 3115/1612/389 1002/952/389 1005/955/389 +f 3115/1612/389 1005/955/389 3123/1621/389 +f 3123/1621/389 1005/955/389 1010/959/389 +f 3123/1621/389 1010/959/389 3116/1613/389 +f 2992/1545/389 3123/1621/389 3116/1613/389 +f 2992/1545/389 3116/1613/389 2911/1515/389 +f 2906/1510/390 3118/1615/390 3124/1622/390 +f 2906/1510/389 3124/1622/389 2988/1542/389 +f 3118/1615/389 933/885/389 936/888/389 +f 3118/1615/389 936/888/389 3124/1622/389 +f 3124/1622/389 936/888/389 941/892/389 +f 3124/1622/389 941/892/389 3119/1616/389 +f 2988/1542/389 3124/1622/389 3119/1616/389 +f 2988/1542/389 3119/1616/389 1300/1203/389 +f 777/1623/506 776/727/335 3125/1624/335 +f 776/727/335 775/726/335 3126/1625/335 +f 776/727/335 3126/1625/335 3125/1624/335 +f 3125/1624/335 3126/1625/335 437/433/335 +f 3125/1624/338 437/433/338 779/730/338 +f 2701/1626/507 3125/1624/335 779/730/335 +f 2707/1403/335 2710/1406/335 3127/1627/335 +f 2707/1403/335 3127/1627/335 3128/1628/335 +f 2710/1406/335 2712/1408/335 3129/1629/335 +f 2710/1406/335 3129/1629/335 3127/1627/335 +f 3127/1627/338 3129/1629/338 368/367/338 +f 3127/1627/335 368/367/335 759/713/335 +f 3128/1628/335 3127/1627/335 759/713/335 +f 3128/1628/335 759/713/335 441/437/335 +f 2718/1409/335 2721/1412/335 3130/1630/335 +f 2718/1409/338 3130/1630/338 3131/1631/338 +f 2721/1412/335 472/461/335 3132/1632/335 +f 2721/1412/335 3132/1632/335 3130/1630/335 +f 3130/1630/335 3132/1632/335 458/451/335 +f 3130/1630/335 458/451/335 737/693/335 +f 3131/1631/338 3130/1630/338 737/693/338 +f 3131/1631/335 737/693/335 372/371/335 +f 472/461/335 471/460/335 3133/1633/335 +f 472/461/338 3133/1633/338 3132/1632/338 +f 471/460/335 3092/1634/508 3133/1633/335 +f 3133/1633/338 462/1635/509 459/452/338 +f 3132/1632/338 3133/1633/338 459/452/338 +f 3132/1632/335 459/452/335 458/451/335 +f 775/726/335 2807/1440/335 3134/1636/335 +f 775/726/335 3134/1636/335 3126/1625/335 +f 2807/1440/338 2707/1403/338 3128/1628/338 +f 2807/1440/335 3128/1628/335 3134/1636/335 +f 3134/1636/335 3128/1628/335 441/437/335 +f 3134/1636/335 441/437/335 438/434/335 +f 3126/1625/335 3134/1636/335 438/434/335 +f 3126/1625/335 438/434/335 437/433/335 +f 2712/1408/335 2802/1434/335 3135/1637/335 +f 2712/1408/335 3135/1637/335 3129/1629/335 +f 2802/1434/335 2718/1409/335 3131/1631/335 +f 2802/1434/335 3131/1631/335 3135/1637/335 +f 3135/1637/335 3131/1631/335 372/371/335 +f 3135/1637/335 372/371/335 369/368/335 +f 3129/1629/335 3135/1637/335 369/368/335 +f 3129/1629/335 369/368/335 368/367/335 +s 1 +f 360/360/335 363/494/336 364/363/510 +f 361/361/335 364/363/510 365/364/511 +f 370/369/335 373/372/335 374/1638/512 +f 370/369/335 374/1638/512 375/1639/513 +f 371/370/338 370/369/335 375/1639/513 +f 371/370/338 375/1639/513 376/1640/514 +f 396/392/335 399/405/515 400/395/516 +f 397/393/335 400/395/516 401/396/517 +f 439/435/335 442/438/335 443/1641/518 +f 439/435/335 443/1641/518 444/1642/519 +f 440/436/335 439/435/335 444/1642/519 +f 440/436/335 444/1642/519 445/1643/520 +f 459/452/338 462/1635/521 463/455/522 +f 460/453/338 463/455/522 464/1644/523 +f 460/453/338 464/1644/523 465/1645/524 +f 461/454/525 460/453/338 465/1645/524 +f 461/454/525 465/1645/524 466/1646/526 +f 402/397/338 401/396/517 469/458/527 +f 467/456/335 469/458/527 470/459/345 +f 501/490/335 504/732/528 505/493/346 +f 502/491/335 505/493/346 363/494/336 +f 514/503/335 517/506/335 518/1647/529 +f 514/503/335 518/1647/529 519/1648/530 +f 515/504/335 514/503/335 519/1648/530 +f 515/504/335 519/1648/530 520/1649/530 +f 523/509/335 526/512/335 527/1650/531 +f 523/509/335 527/1650/531 528/1435/458 +f 524/510/335 523/509/335 528/1435/458 +f 524/510/335 528/1435/458 529/1437/532 +f 531/514/335 534/789/533 535/517/534 +f 532/515/335 535/517/534 536/1651/535 +f 532/515/335 536/1651/535 537/1652/536 +f 533/516/335 532/515/335 537/1652/536 +f 533/516/335 537/1652/536 538/1653/537 +f 541/520/335 544/523/335 545/1654/538 +f 541/520/335 545/1654/538 546/1655/539 +f 542/521/335 541/520/335 546/1655/539 +f 542/521/335 546/1655/539 547/1656/454 +f 550/526/335 553/529/338 554/1657/540 +f 550/526/335 554/1657/540 555/1658/541 +f 551/527/335 550/526/335 555/1658/541 +f 551/527/335 555/1658/541 556/1659/541 +f 558/531/335 561/878/542 562/534/543 +f 559/532/335 562/534/543 563/535/387 +f 583/555/338 586/558/335 587/1660/544 +f 583/555/338 587/1660/544 588/559/545 +f 584/556/338 583/555/338 588/559/545 +f 621/592/335 624/846/546 625/595/547 +f 622/593/335 625/595/547 626/596/548 +f 642/612/335 645/814/549 646/615/550 +f 643/613/338 646/615/550 647/1661/551 +f 643/613/338 647/1661/551 648/1662/552 +f 644/614/335 643/613/338 648/1662/552 +f 644/614/335 648/1662/552 649/1663/552 +f 651/617/338 644/614/335 649/1663/552 +f 651/617/338 649/1663/552 652/1664/553 +f 586/558/335 651/617/338 652/1664/553 +f 586/558/335 652/1664/553 587/1660/544 +f 680/645/335 551/527/335 556/1659/541 +f 680/645/335 556/1659/541 682/1665/339 +f 681/646/335 680/645/335 682/1665/339 +f 681/646/335 682/1665/339 683/847/382 +f 691/654/335 694/800/554 695/657/555 +f 692/655/335 695/657/355 696/658/356 +f 700/662/335 703/865/556 704/665/557 +f 701/663/335 704/665/557 705/666/558 +f 709/670/335 712/830/559 713/673/359 +f 710/671/335 713/673/359 714/1666/560 +f 710/671/335 714/1666/560 715/1667/561 +f 711/672/335 710/671/335 715/1667/561 +f 711/672/335 715/1667/561 716/1668/562 +f 542/521/335 547/1656/454 719/676/563 +f 717/674/335 719/676/563 720/677/360 +f 724/681/335 515/504/335 520/1649/530 +f 724/681/335 520/1649/530 725/1669/538 +f 544/523/335 724/681/335 725/1669/538 +f 544/523/335 725/1669/538 545/1654/538 +f 738/694/335 461/454/525 466/1646/526 +f 738/694/335 466/1646/526 739/1670/564 +f 373/372/335 738/694/335 739/1670/564 +f 373/372/335 739/1670/564 374/1638/512 +f 747/702/335 524/510/335 529/1437/532 +f 747/702/335 529/1437/532 748/1671/529 +f 517/506/335 747/702/335 748/1671/529 +f 517/506/335 748/1671/529 518/1647/529 +f 760/714/335 371/370/338 376/1640/514 +f 760/714/335 376/1640/514 761/1672/565 +f 442/438/335 760/714/335 761/1672/565 +f 442/438/335 761/1672/565 443/1641/518 +f 763/716/335 533/516/335 538/1653/537 +f 763/716/335 538/1653/537 764/1673/566 +f 526/512/335 763/716/335 764/1673/566 +f 526/512/335 764/1673/566 527/1650/531 +f 769/721/361 771/723/335 772/728/567 +f 772/728/567 776/727/335 777/1623/507 +f 778/729/507 780/731/335 781/1674/510 +f 780/731/335 440/436/335 445/1643/520 +f 780/731/335 445/1643/520 782/1675/568 +f 781/1674/510 780/731/335 782/1675/568 +f 781/1674/510 782/1675/568 783/1676/569 +f 504/732/528 784/733/335 785/737/570 +f 785/737/570 788/736/335 789/738/571 +f 789/738/571 790/739/335 791/741/572 +f 791/741/572 770/722/335 769/721/361 +f 822/771/335 711/672/335 716/1668/562 +f 822/771/335 716/1668/562 823/1677/573 +f 553/529/338 822/771/335 823/1677/573 +f 553/529/338 823/1677/573 554/1657/540 +f 366/365/335 365/364/511 840/788/368 +f 838/786/338 840/788/368 534/789/533 +f 721/678/335 720/677/360 850/799/360 +f 848/797/335 850/799/574 694/800/554 +f 564/536/338 563/535/387 863/813/379 +f 861/811/335 863/813/379 645/814/549 +f 706/667/335 705/666/558 878/829/575 +f 876/827/335 878/829/575 712/830/559 +f 891/843/345 893/1678/576 894/845/577 +f 892/844/335 894/845/577 624/846/546 +f 697/659/335 696/658/356 911/864/386 +f 909/862/335 911/864/578 703/865/556 +f 627/597/335 626/596/548 923/877/579 +f 921/875/335 923/877/579 561/878/542 +f 926/881/389 929/884/389 930/1679/580 +f 926/881/389 930/1679/580 931/1680/581 +f 927/882/389 926/881/389 931/1680/581 +f 927/882/389 931/1680/581 932/1681/582 +f 934/886/389 937/1234/418 938/889/391 +f 935/887/390 938/889/391 939/890/583 +f 962/913/390 965/916/389 966/1682/584 +f 962/913/390 966/1682/584 967/917/585 +f 963/914/390 962/913/390 967/917/585 +f 1003/953/389 1006/1259/429 1007/956/586 +f 1004/954/389 1007/956/586 1008/957/396 +f 1023/1208/587 1024/1207/588 1025/1683/589 +f 1023/1208/587 1025/1683/589 1026/1620/590 +f 1024/1207/588 1027/1684/591 1028/1685/592 +f 1024/1207/588 1028/1685/592 1025/1683/589 +f 1025/1683/589 1028/1685/592 1029/1686/593 +f 1025/1683/589 1029/1686/593 1030/1687/594 +f 1026/1620/590 1025/1683/589 1030/1687/594 +f 1026/1620/590 1030/1687/594 1031/1688/595 +f 1033/973/389 1035/975/389 1036/1689/596 +f 1033/973/389 1036/1689/596 1037/1690/597 +f 965/916/389 1033/973/389 1037/1690/597 +f 965/916/389 1037/1690/597 966/1682/584 +f 1067/1005/389 927/882/389 932/1681/582 +f 1067/1005/389 932/1681/582 1069/1691/598 +f 1068/1006/389 1067/1005/389 1069/1691/598 +f 1068/1006/389 1069/1691/598 1070/1260/599 +f 1078/1014/389 1081/1193/397 1082/1017/397 +f 1079/1015/389 1082/1017/474 1083/1018/600 +f 1087/1022/389 1090/1220/601 1091/1025/602 +f 1088/1023/389 1091/1025/399 1092/1026/400 +f 1095/1278/421 1096/1692/603 1097/1693/604 +f 1095/1278/421 1097/1693/604 1098/1694/605 +f 1096/1692/603 1099/1695/606 1100/1696/607 +f 1096/1692/603 1100/1696/607 1097/1693/604 +f 1097/1693/604 1100/1696/607 1101/1697/608 +f 1097/1693/604 1101/1697/608 1102/1698/609 +f 1098/1694/605 1097/1693/604 1102/1698/609 +f 1098/1694/605 1102/1698/609 1103/1699/610 +f 1105/1030/389 1108/1518/488 1109/1033/401 +f 1106/1031/389 1109/1033/488 1110/1034/611 +f 1114/1038/389 1117/1162/612 1118/1041/402 +f 1115/1039/389 1118/1041/402 1119/1042/444 +f 1124/1047/389 1127/1050/389 1128/1700/613 +f 1124/1047/389 1128/1700/613 1129/1701/614 +f 1125/1048/389 1124/1047/389 1129/1701/614 +f 1125/1048/389 1129/1701/614 1130/1702/615 +f 1147/1067/389 1150/1080/616 1151/1070/617 +f 1148/1068/389 1151/1070/617 1152/1071/618 +f 1187/1107/389 1190/1110/389 1191/1703/619 +f 1187/1107/389 1191/1703/619 1192/1704/620 +f 1188/1108/389 1187/1107/389 1192/1704/620 +f 1188/1108/389 1192/1704/620 1193/1705/621 +f 1207/1124/389 1210/1131/622 1211/1127/623 +f 1208/1125/390 1211/1127/623 1212/1706/624 +f 1208/1125/390 1212/1706/624 1213/1707/625 +f 1209/1126/389 1208/1125/390 1213/1707/625 +f 1209/1126/389 1213/1707/625 1214/1708/626 +f 1153/1072/389 1152/1071/618 1217/1130/627 +f 1215/1128/389 1217/1130/627 1210/1131/622 +f 1244/1158/389 1247/1368/628 1248/1161/629 +f 1245/1159/389 1248/1161/629 1117/1162/612 +f 1257/1171/630 1260/1174/631 1261/1582/499 +f 1257/1171/630 1261/1582/499 1262/1584/632 +f 1258/1172/390 1257/1171/630 1262/1584/632 +f 1258/1172/390 1262/1584/632 1263/1532/633 +f 1266/1177/389 1269/1180/389 1270/1709/634 +f 1266/1177/389 1270/1709/634 1271/1710/635 +f 1267/1178/389 1266/1177/389 1271/1710/635 +f 1267/1178/389 1271/1710/635 1272/1711/636 +f 1274/1182/389 1277/1301/437 1278/1185/637 +f 1275/1183/389 1278/1185/637 1279/1712/638 +f 1275/1183/389 1279/1712/638 1280/1713/639 +f 1276/1184/389 1275/1183/389 1280/1713/639 +f 1276/1184/389 1280/1713/639 1281/1714/640 +f 1283/1187/389 1285/1189/389 1286/1715/486 +f 1283/1187/389 1286/1715/486 1287/1535/486 +f 1105/1030/389 1283/1187/389 1287/1535/486 +f 1105/1030/389 1287/1535/486 1108/1518/488 +f 1111/1035/389 1110/1034/611 1290/1192/641 +f 1288/1190/389 1290/1192/489 1081/1193/489 +f 941/892/390 940/891/642 1302/1205/643 +f 940/891/642 939/890/583 1304/1716/644 +f 940/891/642 1304/1716/644 1302/1205/643 +f 1302/1205/643 1304/1716/644 1027/1684/591 +f 1302/1205/643 1027/1684/591 1024/1207/588 +f 1303/1206/645 1302/1205/643 1024/1207/588 +f 1084/1019/389 1083/1018/600 1315/1219/646 +f 1313/1217/389 1315/1219/398 1090/1220/416 +f 1009/958/390 1008/957/396 1328/1233/647 +f 1326/1231/389 1328/1233/647 937/1234/418 +f 1093/1027/389 1092/1026/648 1331/1237/649 +f 1329/1235/389 1331/1237/649 1332/1238/650 +f 1349/1255/651 1352/1717/652 1353/1258/653 +f 1350/1256/389 1353/1258/653 1006/1259/429 +f 1368/1275/389 1370/1277/389 1095/1278/654 +f 1120/1043/389 1119/1042/444 1392/1300/655 +f 1390/1298/389 1392/1300/655 1277/1301/437 +f 1408/1317/389 1410/1319/656 1411/1718/657 +f 1408/1317/389 1411/1718/657 1412/1719/658 +f 929/884/389 1408/1317/389 1412/1719/658 +f 929/884/389 1412/1719/658 930/1679/580 +f 1421/1328/389 1258/1172/390 1263/1532/633 +f 1421/1328/389 1263/1532/633 1422/1534/631 +f 1285/1189/389 1421/1328/389 1422/1534/631 +f 1285/1189/389 1422/1534/631 1286/1715/486 +f 1434/1340/389 1209/1126/389 1214/1708/626 +f 1434/1340/389 1214/1708/626 1435/1720/659 +f 1127/1050/389 1434/1340/389 1435/1720/659 +f 1127/1050/389 1435/1720/659 1128/1700/613 +f 1449/1354/389 1276/1184/389 1281/1714/640 +f 1449/1354/389 1281/1714/640 1450/1721/660 +f 1269/1180/389 1449/1354/389 1450/1721/660 +f 1269/1180/389 1450/1721/660 1270/1709/634 +f 1455/1359/661 1457/1361/389 1458/1365/662 +f 1458/1365/662 1461/1364/389 1462/1366/663 +f 1462/1366/663 1463/1367/389 1464/1722/664 +f 1463/1367/389 1188/1108/389 1193/1705/621 +f 1463/1367/389 1193/1705/621 1465/1723/665 +f 1464/1722/664 1463/1367/389 1465/1723/665 +f 1464/1722/664 1465/1723/665 1466/1724/666 +f 1247/1368/628 1467/1369/389 1468/1373/667 +f 1468/1373/667 1471/1372/389 1472/1374/668 +f 1472/1374/668 1473/1375/389 1474/1377/669 +f 1474/1377/669 1456/1360/389 1455/1359/661 +f 1482/1384/389 1267/1178/389 1272/1711/636 +f 1482/1384/389 1272/1711/636 1483/1725/670 +f 1260/1174/631 1482/1384/389 1483/1725/670 +f 1260/1174/631 1483/1725/670 1261/1582/499 +f 1494/1395/389 1125/1048/389 1130/1702/615 +f 1494/1395/389 1130/1702/615 1495/1726/671 +f 1190/1110/389 1494/1395/389 1495/1726/671 +f 1190/1110/389 1495/1726/671 1191/1703/619 +f 1496/1727/672 1497/1728/673 1498/1729/674 +f 1496/1727/672 1498/1729/674 1499/1730/675 +f 1500/1731/673 1501/1732/676 1502/1733/677 +f 1500/1731/673 1502/1733/677 1503/1734/674 +f 1504/1735/674 1505/1736/678 1506/1737/679 +f 1504/1735/674 1506/1737/679 1507/1738/680 +f 1499/1730/675 1498/1729/674 1508/1739/681 +f 1499/1730/675 1508/1739/681 1509/1740/682 +f 1510/1741/683 1511/1742/684 1512/1743/685 +f 1510/1741/683 1512/1743/685 1513/1744/686 +f 1514/1745/687 1515/1746/688 1516/1747/689 +f 1514/1745/687 1516/1747/689 1517/1748/690 +f 1517/1748/690 1516/1747/689 1518/1749/691 +f 1517/1748/690 1518/1749/691 1519/1750/692 +f 1513/1744/686 1512/1743/685 1520/1751/693 +f 1513/1744/686 1520/1751/693 1521/1752/694 +f 1522/1753/695 1523/1754/696 1524/1755/697 +f 1522/1753/695 1524/1755/697 1525/1756/698 +f 1526/1757/699 1527/1758/700 1528/1759/701 +f 1526/1757/699 1528/1759/701 1529/1760/697 +f 1529/1760/697 1528/1759/701 1530/1761/702 +f 1529/1760/697 1530/1761/702 1531/1762/703 +f 1525/1756/698 1524/1755/697 1532/1763/704 +f 1525/1756/698 1532/1763/704 1533/1764/705 +f 1534/1765/706 1535/1766/707 1536/1767/708 +f 1534/1765/706 1536/1767/708 1537/1768/709 +f 1538/1769/710 1539/1770/711 1540/1771/712 +f 1538/1769/710 1540/1771/712 1541/1772/708 +f 1541/1772/708 1540/1771/712 1542/1773/713 +f 1541/1772/708 1542/1773/713 1543/1774/714 +f 1537/1768/709 1536/1767/708 1544/1775/715 +f 1537/1768/709 1544/1775/715 1545/1776/716 +f 1546/1777/717 1547/1778/718 1548/1779/719 +f 1546/1777/717 1548/1779/719 1549/1780/720 +f 1550/1781/721 1551/1782/722 1552/1783/723 +f 1550/1781/721 1552/1783/723 1553/1784/719 +f 1553/1784/719 1552/1783/723 1554/1785/724 +f 1553/1784/719 1554/1785/724 1555/1786/725 +f 1549/1780/720 1548/1779/719 1556/1787/726 +f 1549/1780/720 1556/1787/726 1557/1788/727 +f 1558/1789/728 1559/1790/729 1560/1791/730 +f 1558/1789/728 1560/1791/730 1561/1792/731 +f 1562/1793/732 1563/1794/733 1564/1795/734 +f 1562/1793/732 1564/1795/734 1565/1796/735 +f 1566/1797/736 1567/1798/737 1568/1799/738 +f 1566/1797/736 1568/1799/738 1569/1800/739 +f 1561/1792/731 1560/1791/730 1570/1801/740 +f 1561/1792/731 1570/1801/740 1571/1802/741 +f 1572/1803/742 1573/1804/743 1574/1805/744 +f 1572/1803/742 1574/1805/744 1575/1806/745 +f 1576/1807/746 1577/1808/747 1578/1809/748 +f 1576/1807/746 1578/1809/748 1579/1810/749 +f 1579/1810/749 1578/1809/748 1580/1811/750 +f 1579/1810/749 1580/1811/750 1581/1812/751 +f 1575/1806/745 1574/1805/744 1582/1813/752 +f 1575/1806/745 1582/1813/752 1583/1814/753 +f 1584/1815/754 1585/1816/755 1586/1817/756 +f 1584/1815/754 1586/1817/756 1587/1818/757 +f 1588/1819/758 1589/1820/759 1590/1821/760 +f 1588/1819/758 1590/1821/760 1591/1822/761 +f 1591/1822/761 1590/1821/760 1592/1823/762 +f 1591/1822/761 1592/1823/762 1593/1824/763 +f 1587/1818/757 1586/1817/756 1594/1825/764 +f 1587/1818/757 1594/1825/764 1595/1826/765 +f 1596/1827/766 1597/1828/767 1598/1829/768 +f 1596/1827/766 1598/1829/768 1599/1830/769 +f 1600/1831/770 1601/1832/771 1602/1833/772 +f 1600/1831/770 1602/1833/772 1603/1834/773 +f 1603/1834/773 1602/1833/772 1604/1835/774 +f 1603/1834/773 1604/1835/774 1605/1836/775 +f 1599/1830/769 1598/1829/768 1606/1837/775 +f 1599/1830/769 1606/1837/775 1607/1838/776 +f 1608/1839/777 1609/1840/778 1610/1841/779 +f 1608/1839/777 1610/1841/779 1611/1842/780 +f 1612/1843/781 1613/1844/782 1614/1845/783 +f 1612/1843/781 1614/1845/783 1615/1846/784 +f 1616/1847/784 1617/1848/783 1618/1849/785 +f 1616/1847/784 1618/1849/785 1619/1850/786 +f 1611/1842/780 1610/1841/779 1620/1851/787 +f 1611/1842/780 1620/1851/787 1621/1852/788 +f 1622/1853/789 1623/1854/790 1624/1855/791 +f 1622/1853/789 1624/1855/791 1625/1856/792 +f 1626/1857/793 1627/1858/794 1628/1859/795 +f 1626/1857/793 1628/1859/795 1629/1860/796 +f 1629/1860/796 1628/1859/795 1515/1746/688 +f 1629/1860/796 1515/1746/688 1514/1745/687 +f 1625/1856/792 1624/1855/791 1511/1742/684 +f 1625/1856/792 1511/1742/684 1510/1741/683 +f 1630/1861/797 1631/1862/798 1632/1863/799 +f 1630/1861/797 1632/1863/799 1633/1864/800 +f 1634/1865/798 1635/1866/801 1636/1867/802 +f 1634/1865/798 1636/1867/802 1637/1868/799 +f 1637/1868/799 1636/1867/802 1539/1770/711 +f 1637/1868/799 1539/1770/711 1538/1769/710 +f 1633/1864/800 1632/1863/799 1535/1766/707 +f 1633/1864/800 1535/1766/707 1534/1765/706 +f 1638/1869/803 1639/1870/804 1640/1871/805 +f 1638/1869/803 1640/1871/805 1641/1872/806 +f 1642/1873/807 1643/1874/808 1644/1875/809 +f 1642/1873/807 1644/1875/809 1645/1876/810 +f 1645/1876/810 1644/1875/809 1646/1877/811 +f 1645/1876/810 1646/1877/811 1647/1878/812 +f 1641/1872/806 1640/1871/805 1648/1879/813 +f 1641/1872/806 1648/1879/813 1649/1880/814 +f 1650/1881/815 1651/1882/816 1652/1883/817 +f 1650/1881/815 1652/1883/817 1653/1884/818 +f 1654/1885/816 1655/1886/819 1656/1887/820 +f 1654/1885/816 1656/1887/820 1657/1888/817 +f 1657/1888/817 1656/1887/820 1658/1889/821 +f 1657/1888/817 1658/1889/821 1659/1890/822 +f 1653/1884/818 1652/1883/817 1660/1891/823 +f 1653/1884/818 1660/1891/823 1661/1892/824 +f 1662/1893/825 1663/1894/826 1664/1895/827 +f 1662/1893/825 1664/1895/827 1665/1896/828 +f 1666/1897/829 1667/1898/830 1668/1899/831 +f 1666/1897/829 1668/1899/831 1669/1900/832 +f 1669/1900/832 1668/1899/831 1670/1901/833 +f 1669/1900/832 1670/1901/833 1671/1902/834 +f 1665/1896/828 1664/1895/827 1672/1903/835 +f 1665/1896/828 1672/1903/835 1673/1904/836 +f 1674/1905/837 1675/1906/838 1676/1907/839 +f 1674/1905/837 1676/1907/839 1677/1908/840 +f 1678/1909/841 1679/1910/842 1680/1911/843 +f 1678/1909/841 1680/1911/843 1681/1912/844 +f 1681/1912/844 1680/1911/843 1501/1732/676 +f 1681/1912/844 1501/1732/676 1500/1731/673 +f 1677/1908/840 1676/1907/839 1497/1728/673 +f 1677/1908/840 1497/1728/673 1496/1727/672 +f 1545/1776/716 1544/1775/715 1682/1913/845 +f 1545/1776/716 1682/1913/845 1683/1914/846 +f 1543/1774/714 1542/1773/713 1684/1915/847 +f 1543/1774/714 1684/1915/847 1685/1916/848 +f 1685/1916/848 1684/1915/847 1589/1820/759 +f 1685/1916/848 1589/1820/759 1588/1819/758 +f 1683/1914/846 1682/1913/845 1585/1816/755 +f 1683/1914/846 1585/1816/755 1584/1815/754 +f 1621/1852/788 1620/1851/787 1686/1917/849 +f 1621/1852/788 1686/1917/849 1687/1918/850 +f 1619/1850/786 1618/1849/785 1688/1919/851 +f 1619/1850/786 1688/1919/851 1689/1920/852 +f 1689/1920/852 1688/1919/851 1655/1886/819 +f 1689/1920/852 1655/1886/819 1654/1885/816 +f 1687/1918/850 1686/1917/849 1651/1882/816 +f 1687/1918/850 1651/1882/816 1650/1881/815 +f 1661/1892/824 1660/1891/823 1690/1921/853 +f 1661/1892/824 1690/1921/853 1691/1922/854 +f 1659/1890/822 1658/1889/821 1692/1923/855 +f 1659/1890/822 1692/1923/855 1693/1924/853 +f 1694/1925/853 1695/1926/856 1696/1927/857 +f 1694/1925/853 1696/1927/857 1697/1928/858 +f 1691/1922/854 1690/1921/853 1698/1929/859 +f 1691/1922/854 1698/1929/859 1699/1930/860 +f 1700/1931/861 1701/1932/862 1702/1933/863 +f 1700/1931/861 1702/1933/863 1703/1934/864 +f 1704/1935/865 1705/1936/866 1706/1937/867 +f 1704/1935/865 1706/1937/867 1707/1938/868 +f 1707/1938/868 1706/1937/867 1708/1939/869 +f 1707/1938/868 1708/1939/869 1709/1940/870 +f 1703/1934/864 1702/1933/863 1710/1941/870 +f 1703/1934/864 1710/1941/870 1711/1942/871 +f 1712/1943/872 1713/1944/873 1714/1945/874 +f 1712/1943/872 1714/1945/874 1715/1946/875 +f 1716/1947/876 1717/1948/877 1718/1949/878 +f 1716/1947/876 1718/1949/878 1719/1950/879 +f 1719/1950/879 1718/1949/878 1667/1898/830 +f 1719/1950/879 1667/1898/830 1666/1897/829 +f 1715/1946/875 1714/1945/874 1663/1894/826 +f 1715/1946/875 1663/1894/826 1662/1893/825 +f 1720/1951/880 1721/1952/881 1722/1953/882 +f 1720/1951/880 1722/1953/882 1723/1954/883 +f 1724/1955/884 1725/1956/885 1726/1957/886 +f 1724/1955/884 1726/1957/886 1727/1958/882 +f 1727/1958/882 1726/1957/886 1728/1959/887 +f 1727/1958/882 1728/1959/887 1729/1960/888 +f 1723/1954/883 1722/1953/882 1730/1961/889 +f 1723/1954/883 1730/1961/889 1731/1962/890 +f 1732/1963/891 1733/1964/892 1734/1965/893 +f 1732/1963/891 1734/1965/893 1735/1966/894 +f 1736/1967/895 1737/1968/896 1738/1969/897 +f 1736/1967/895 1738/1969/897 1739/1970/898 +f 1739/1970/898 1738/1969/897 1740/1971/899 +f 1739/1970/898 1740/1971/899 1741/1972/900 +f 1735/1966/894 1734/1965/893 1742/1973/901 +f 1735/1966/894 1742/1973/901 1743/1974/902 +f 1744/1975/903 1745/1976/904 1746/1977/905 +f 1744/1975/903 1746/1977/905 1747/1978/906 +f 1748/1979/907 1749/1980/908 1750/1981/909 +f 1748/1979/907 1750/1981/909 1751/1982/910 +f 1751/1982/910 1750/1981/909 1752/1983/911 +f 1751/1982/910 1752/1983/911 1753/1984/912 +f 1747/1978/906 1746/1977/905 1754/1985/912 +f 1747/1978/906 1754/1985/912 1755/1986/913 +f 1756/1987/914 1757/1988/915 1758/1989/916 +f 1756/1987/914 1758/1989/916 1759/1990/917 +f 1760/1991/918 1761/1992/919 1762/1993/920 +f 1760/1991/918 1762/1993/920 1763/1994/921 +f 1763/1994/921 1762/1993/920 1705/1936/866 +f 1763/1994/921 1705/1936/866 1704/1935/865 +f 1759/1990/917 1758/1989/916 1701/1932/862 +f 1759/1990/917 1701/1932/862 1700/1931/861 +f 1764/1995/922 1765/1996/923 1766/1997/924 +f 1764/1995/922 1766/1997/924 1767/1998/925 +f 1768/1999/926 1769/2000/927 1770/2001/928 +f 1768/1999/926 1770/2001/928 1771/2002/929 +f 1771/2002/929 1770/2001/928 1749/1980/908 +f 1771/2002/929 1749/1980/908 1748/1979/907 +f 1767/1998/925 1766/1997/924 1745/1976/904 +f 1767/1998/925 1745/1976/904 1744/1975/903 +f 1521/1752/694 1520/1751/693 1772/2003/930 +f 1521/1752/694 1772/2003/930 1773/2004/931 +f 1519/1750/692 1518/1749/691 1774/2005/932 +f 1519/1750/692 1774/2005/932 1775/2006/933 +f 1775/2006/933 1774/2005/932 1761/1992/919 +f 1775/2006/933 1761/1992/919 1760/1991/918 +f 1773/2004/931 1772/2003/930 1757/1988/915 +f 1773/2004/931 1757/1988/915 1756/1987/914 +f 1776/2007/934 1777/2008/935 1778/2009/936 +f 1776/2007/934 1778/2009/936 1779/2010/937 +f 1780/2011/938 1781/2012/939 1782/2013/940 +f 1780/2011/938 1782/2013/940 1783/2014/941 +f 1783/2014/941 1782/2013/940 1784/2015/942 +f 1783/2014/941 1784/2015/942 1785/2016/943 +f 1779/2010/937 1778/2009/936 1786/2017/943 +f 1779/2010/937 1786/2017/943 1787/2018/944 +f 1788/2019/945 1789/2020/946 1790/2021/947 +f 1788/2019/945 1790/2021/947 1791/2022/948 +f 1792/2023/949 1793/2024/950 1794/2025/951 +f 1792/2023/949 1794/2025/951 1795/2026/947 +f 1795/2026/947 1794/2025/951 1796/2027/952 +f 1795/2026/947 1796/2027/952 1797/2028/953 +f 1791/2022/948 1790/2021/947 1798/2029/954 +f 1791/2022/948 1798/2029/954 1799/2030/955 +f 1743/1974/902 1742/1973/901 1800/2031/956 +f 1743/1974/902 1800/2031/956 1801/2032/957 +f 1741/1972/900 1740/1971/899 1802/2033/958 +f 1741/1972/900 1802/2033/958 1803/2034/959 +f 1803/2034/959 1802/2033/958 1804/2035/960 +f 1803/2034/959 1804/2035/960 1805/2036/961 +f 1801/2032/957 1800/2031/956 1806/2037/962 +f 1801/2032/957 1806/2037/962 1807/2038/963 +f 1808/2039/964 1809/2040/965 1810/2041/966 +f 1808/2039/964 1810/2041/966 1811/2042/967 +f 1812/2043/968 1813/2044/969 1814/2045/970 +f 1812/2043/968 1814/2045/970 1815/2046/971 +f 1815/2046/971 1814/2045/970 1816/2047/972 +f 1815/2046/971 1816/2047/972 1817/2048/973 +f 1811/2042/967 1810/2041/966 1818/2049/974 +f 1811/2042/967 1818/2049/974 1819/2050/975 +f 1820/2051/976 1821/2052/977 1822/2053/978 +f 1820/2051/976 1822/2053/978 1823/2054/979 +f 1824/2055/980 1825/2056/981 1826/2057/982 +f 1824/2055/980 1826/2057/982 1827/2058/983 +f 1827/2058/983 1826/2057/982 1828/2059/984 +f 1827/2058/983 1828/2059/984 1829/2060/985 +f 1823/2054/979 1822/2053/978 1830/2061/986 +f 1823/2054/979 1830/2061/986 1831/2062/987 +f 1832/2063/988 1833/2064/989 1834/2065/990 +f 1832/2063/988 1834/2065/990 1835/2066/991 +f 1836/2067/989 1837/2068/992 1838/2069/993 +f 1836/2067/989 1838/2069/993 1839/2070/994 +f 1839/2070/994 1838/2069/993 1527/1758/700 +f 1839/2070/994 1527/1758/700 1526/1757/699 +f 1835/2066/991 1834/2065/990 1523/1754/696 +f 1835/2066/991 1523/1754/696 1522/1753/695 +f 1755/1986/913 1754/1985/912 1840/2071/995 +f 1755/1986/913 1840/2071/995 1841/2072/996 +f 1753/1984/912 1752/1983/911 1842/2073/997 +f 1753/1984/912 1842/2073/997 1843/2074/998 +f 1843/2074/998 1842/2073/997 1844/2075/999 +f 1843/2074/998 1844/2075/999 1845/2076/1000 +f 1841/2072/996 1840/2071/995 1846/2077/1001 +f 1841/2072/996 1846/2077/1001 1847/2078/1002 +f 1848/2079/1003 1849/2080/1004 1850/2081/1005 +f 1848/2079/1003 1850/2081/1005 1851/2082/1006 +f 1852/2083/1007 1853/2084/1008 1854/2085/1009 +f 1852/2083/1007 1854/2085/1009 1855/2086/1010 +f 1855/2086/1010 1854/2085/1009 1551/1782/722 +f 1855/2086/1010 1551/1782/722 1550/1781/721 +f 1851/2082/1006 1850/2081/1005 1547/1778/718 +f 1851/2082/1006 1547/1778/718 1546/1777/717 +f 1509/1740/682 1508/1739/681 1856/2087/1011 +f 1509/1740/682 1856/2087/1011 1857/2088/1012 +f 1507/1738/680 1506/1737/679 1858/2089/1013 +f 1507/1738/680 1858/2089/1013 1859/2090/1014 +f 1859/2090/1014 1858/2089/1013 1860/2091/1015 +f 1859/2090/1014 1860/2091/1015 1861/2092/1016 +f 1857/2088/1012 1856/2087/1011 1862/2093/1017 +f 1857/2088/1012 1862/2093/1017 1863/2094/1018 +f 1864/2095/1019 1865/2096/1020 1866/2097/1021 +f 1864/2095/1019 1866/2097/1021 1867/2098/1022 +f 1868/2099/1023 1869/2100/1024 1870/2101/1025 +f 1868/2099/1023 1870/2101/1025 1871/2102/1021 +f 1871/2102/1021 1870/2101/1025 1643/1874/808 +f 1871/2102/1021 1643/1874/808 1642/1873/807 +f 1867/2098/1022 1866/2097/1021 1639/1870/804 +f 1867/2098/1022 1639/1870/804 1638/1869/803 +f 1872/2103/1026 1873/2104/1027 1874/2105/1028 +f 1872/2103/1026 1874/2105/1028 1875/2106/1029 +f 1876/2107/1030 1877/2108/1031 1878/2109/1032 +f 1876/2107/1030 1878/2109/1032 1879/2110/1033 +f 1879/2110/1033 1878/2109/1032 1880/2111/1034 +f 1879/2110/1033 1880/2111/1034 1881/2112/1035 +f 1875/2106/1029 1874/2105/1028 1882/2113/1036 +f 1875/2106/1029 1882/2113/1036 1883/2114/1037 +f 1863/2094/1018 1862/2093/1017 1884/2115/1038 +f 1863/2094/1018 1884/2115/1038 1885/2116/1039 +f 1861/2092/1016 1860/2091/1015 1886/2117/1040 +f 1861/2092/1016 1886/2117/1040 1887/2118/1041 +f 1887/2118/1041 1886/2117/1040 1888/2119/1042 +f 1887/2118/1041 1888/2119/1042 1889/2120/1043 +f 1885/2116/1039 1884/2115/1038 1890/2121/1044 +f 1885/2116/1039 1890/2121/1044 1891/2122/1045 +f 1892/2123/1046 1893/2124/1047 1894/2125/1048 +f 1892/2123/1046 1894/2125/1048 1895/2126/1049 +f 1896/2127/1050 1101/1697/608 1100/1696/607 +f 1896/2127/1050 1100/1696/607 1897/2128/1051 +f 1897/2128/1051 1100/1696/607 1099/1695/606 +f 1897/2128/1051 1099/1695/606 1898/2129/1052 +f 1895/2126/1049 1894/2125/1048 1899/2130/1053 +f 1895/2126/1049 1899/2130/1053 1900/2131/1054 +f 1799/2030/955 1798/2029/954 1901/2132/1055 +f 1799/2030/955 1901/2132/1055 1902/2133/1056 +f 1797/2028/953 1796/2027/952 1903/2134/1057 +f 1797/2028/953 1903/2134/1057 1904/2135/1055 +f 1904/2135/1055 1903/2134/1057 1905/2136/1058 +f 1904/2135/1055 1905/2136/1058 1906/2137/1059 +f 1902/2133/1056 1901/2132/1055 1907/2138/1060 +f 1902/2133/1056 1907/2138/1060 1908/2139/1061 +f 1909/2140/1062 1910/2141/1063 1911/2142/1064 +f 1909/2140/1062 1911/2142/1064 1912/2143/1065 +f 1913/2144/1066 1914/2145/1067 1915/2146/1068 +f 1913/2144/1066 1915/2146/1068 1916/2147/1069 +f 1916/2147/1069 1915/2146/1068 1917/2148/1070 +f 1916/2147/1069 1917/2148/1070 1918/2149/1071 +f 1919/2150/1072 1920/2151/1064 1921/2152/1073 +f 1919/2150/1072 1921/2152/1073 1922/2153/1074 +f 1923/2154/1075 1924/2155/1076 1925/2156/1077 +f 1923/2154/1075 1925/2156/1077 1926/2157/1078 +f 1927/2158/1079 1928/2159/1080 1929/2160/1081 +f 1927/2158/1079 1929/2160/1081 1930/2161/1082 +f 1930/2161/1082 1929/2160/1081 1931/2162/1083 +f 1930/2161/1082 1931/2162/1083 1932/2163/1084 +f 1926/2157/1078 1925/2156/1077 1933/2164/1085 +f 1926/2157/1078 1933/2164/1085 1934/2165/1086 +f 1935/2166/1087 1936/2167/1088 1937/2168/1089 +f 1935/2166/1087 1937/2168/1089 1938/2169/1090 +f 1939/2170/1091 1940/2171/1092 1941/2172/1093 +f 1939/2170/1091 1941/2172/1093 1942/2173/1094 +f 1942/2173/1094 1941/2172/1093 1943/2174/1095 +f 1942/2173/1094 1943/2174/1095 1944/2175/1096 +f 1938/2169/1090 1937/2168/1089 1945/2176/1097 +f 1938/2169/1090 1945/2176/1097 1946/2177/1098 +f 1947/2178/1099 1948/2179/1100 1949/2180/1101 +f 1947/2178/1099 1949/2180/1101 1950/2181/1102 +f 1951/2182/1103 1952/2183/1104 1953/2184/1105 +f 1951/2182/1103 1953/2184/1105 1954/2185/1106 +f 1954/2185/1106 1953/2184/1105 1563/1794/733 +f 1954/2185/1106 1563/1794/733 1562/1793/732 +f 1950/2181/1102 1949/2180/1101 1559/1790/729 +f 1950/2181/1102 1559/1790/729 1558/1789/728 +f 1955/2186/1107 1956/2187/1108 1957/2188/1109 +f 1955/2186/1107 1957/2188/1109 1958/2189/1110 +f 1959/2190/1111 1960/2191/1112 1961/2192/1113 +f 1959/2190/1111 1961/2192/1113 1962/2193/1114 +f 1962/2193/1114 1961/2192/1113 1963/2194/1115 +f 1962/2193/1114 1963/2194/1115 1964/2195/1116 +f 1958/2189/1110 1957/2188/1109 1965/2196/1117 +f 1958/2189/1110 1965/2196/1117 1966/2197/1118 +f 1533/1764/705 1532/1763/704 1967/2198/1119 +f 1533/1764/705 1967/2198/1119 1968/2199/1120 +f 1531/1762/703 1530/1761/702 1969/2200/1121 +f 1531/1762/703 1969/2200/1121 1970/2201/1122 +f 1970/2201/1122 1969/2200/1121 1793/2024/950 +f 1970/2201/1122 1793/2024/950 1792/2023/949 +f 1968/2199/1120 1967/2198/1119 1789/2020/946 +f 1968/2199/1120 1789/2020/946 1788/2019/945 +f 1971/2202/1123 1972/2203/1124 1973/2204/1125 +f 1971/2202/1123 1973/2204/1125 1974/2205/1126 +f 1975/2206/1124 1976/2207/1127 1977/2208/1128 +f 1975/2206/1124 1977/2208/1128 1978/2209/1129 +f 1978/2209/1129 1977/2208/1128 1613/1844/782 +f 1978/2209/1129 1613/1844/782 1612/1843/781 +f 1974/2205/1126 1973/2204/1125 1609/1840/778 +f 1974/2205/1126 1609/1840/778 1608/1839/777 +f 1979/2210/1130 1980/2211/1131 1981/2212/1132 +f 1979/2210/1130 1981/2212/1132 1982/2213/1133 +f 1983/2214/1134 1984/2215/1135 1985/2216/1136 +f 1983/2214/1134 1985/2216/1136 1986/2217/1137 +f 1986/2217/1137 1985/2216/1136 1928/2159/1080 +f 1986/2217/1137 1928/2159/1080 1927/2158/1079 +f 1982/2213/1133 1981/2212/1132 1924/2155/1076 +f 1982/2213/1133 1924/2155/1076 1923/2154/1075 +f 1987/2218/1138 1988/2219/1139 1989/2220/1140 +f 1987/2218/1138 1989/2220/1140 1990/2221/1141 +f 1991/2222/1139 1992/2223/1142 1993/2224/1143 +f 1991/2222/1139 1993/2224/1143 1994/2225/1144 +f 1994/2225/1144 1993/2224/1143 1995/2226/1145 +f 1994/2225/1144 1995/2226/1145 1996/2227/1146 +f 1997/2228/1141 1998/2229/1147 1999/2230/1148 +f 1997/2228/1141 1999/2230/1148 2000/2231/1149 +f 2001/2232/1150 2002/2233/1151 2003/2234/1152 +f 2001/2232/1150 2003/2234/1152 2004/2235/1153 +f 2005/2236/1154 2006/2237/1155 2007/2238/1156 +f 2005/2236/1154 2007/2238/1156 2008/2239/1157 +f 2008/2239/1157 2007/2238/1156 2009/2240/1158 +f 2008/2239/1157 2009/2240/1158 2010/2241/1159 +f 2004/2235/1153 2003/2234/1152 2011/2242/1160 +f 2004/2235/1153 2011/2242/1160 2012/2243/1161 +f 1900/2131/1054 1899/2130/1053 2013/2244/1162 +f 1900/2131/1054 2013/2244/1162 2014/2245/1163 +f 1898/2129/1052 1099/1695/606 2015/2246/1164 +f 1898/2129/1052 2015/2246/1164 2016/2247/1165 +f 2016/2247/1165 2015/2246/1164 2017/2248/1166 +f 2016/2247/1165 2017/2248/1166 2018/2249/1167 +f 2014/2245/1163 2013/2244/1162 2019/2250/1168 +f 2014/2245/1163 2019/2250/1168 2020/2251/1169 +f 1649/1880/814 1648/1879/813 2021/2252/1170 +f 1649/1880/814 2021/2252/1170 2022/2253/1171 +f 1647/1878/812 1646/1877/811 2023/2254/1172 +f 1647/1878/812 2023/2254/1172 2024/2255/1173 +f 2024/2255/1173 2023/2254/1172 1976/2207/1127 +f 2024/2255/1173 1976/2207/1127 1975/2206/1124 +f 2022/2253/1171 2021/2252/1170 1972/2203/1124 +f 2022/2253/1171 1972/2203/1124 1971/2202/1123 +f 1883/2114/1037 1882/2113/1036 2025/2256/1174 +f 1883/2114/1037 2025/2256/1174 2026/2257/1175 +f 2027/2258/1176 2028/2259/1177 2029/2260/1178 +f 2027/2258/1176 2029/2260/1178 2030/2261/1179 +f 2030/2261/1179 2029/2260/1178 2031/2262/1180 +f 2030/2261/1179 2031/2262/1180 2032/2263/1181 +f 2026/2257/1175 2025/2256/1174 2033/2264/1182 +f 2026/2257/1175 2033/2264/1182 2034/2265/1183 +f 2035/2266/1184 2036/2267/1185 2037/2268/1186 +f 2035/2266/1184 2037/2268/1186 2038/2269/1187 +f 2036/2267/1185 1029/1686/593 1028/1685/592 +f 2036/2267/1185 1028/1685/592 2037/2268/1186 +f 2037/2268/1186 1028/1685/592 1027/1684/591 +f 2037/2268/1186 1027/1684/591 2039/2270/1188 +f 2038/2269/1187 2037/2268/1186 2039/2270/1188 +f 2038/2269/1187 2039/2270/1188 2040/2271/1189 +f 1699/1930/860 1698/1929/859 2041/2272/1190 +f 1699/1930/860 2041/2272/1190 2042/2273/1191 +f 1697/1928/858 1696/1927/857 2043/2274/1192 +f 1697/1928/858 2043/2274/1192 2044/2275/1193 +f 2044/2275/1193 2043/2274/1192 1952/2183/1104 +f 2044/2275/1193 1952/2183/1104 1951/2182/1103 +f 2042/2273/1191 2041/2272/1190 1948/2179/1100 +f 2042/2273/1191 1948/2179/1100 1947/2178/1099 +f 2045/2276/1194 2046/2277/1195 2047/2278/1196 +f 2045/2276/1194 2047/2278/1196 2048/2279/1197 +f 1932/2163/1084 1931/2162/1083 2049/2280/1198 +f 1932/2163/1084 2049/2280/1198 2050/2281/1199 +f 2050/2281/1199 2049/2280/1198 2051/2282/1200 +f 2050/2281/1199 2051/2282/1200 2052/2283/1201 +f 2048/2279/1197 2047/2278/1196 2053/2284/1202 +f 2048/2279/1197 2053/2284/1202 2054/2285/1203 +f 2000/2231/1149 1999/2230/1148 2055/2286/1204 +f 2000/2231/1149 2055/2286/1204 2056/2287/1205 +f 1996/2227/1146 1995/2226/1145 2057/2288/1206 +f 1996/2227/1146 2057/2288/1206 2058/2289/1207 +f 2058/2289/1207 2057/2288/1206 2059/2290/1208 +f 2058/2289/1207 2059/2290/1208 2060/2291/1209 +f 2056/2287/1205 2055/2286/1204 2061/2292/1210 +f 2056/2287/1205 2061/2292/1210 2062/2293/1211 +f 1966/2197/1118 1965/2196/1117 2063/2294/1212 +f 1966/2197/1118 2063/2294/1212 2064/2295/1213 +f 1964/2195/1116 1963/2194/1115 2065/2296/1214 +f 1964/2195/1116 2065/2296/1214 2066/2297/1215 +f 2066/2297/1215 2065/2296/1214 2067/2298/1216 +f 2066/2297/1215 2067/2298/1216 2068/2299/1217 +f 2064/2295/1213 2063/2294/1212 2069/2300/1218 +f 2064/2295/1213 2069/2300/1218 2070/2301/1219 +f 1831/2062/987 1830/2061/986 2071/2302/1220 +f 1831/2062/987 2071/2302/1220 2072/2303/1221 +f 1829/2060/985 1828/2059/984 2073/2304/1222 +f 1829/2060/985 2073/2304/1222 2074/2305/1223 +f 2074/2305/1223 2073/2304/1222 2075/2306/1224 +f 2074/2305/1223 2075/2306/1224 2076/2307/1225 +f 2072/2303/1221 2071/2302/1220 2077/2308/1226 +f 2072/2303/1221 2077/2308/1226 2078/2309/1227 +f 2079/2310/1228 2080/2311/1229 2081/2312/1230 +f 2079/2310/1228 2081/2312/1230 2082/2313/1231 +f 2083/2314/1232 2084/2315/1233 2085/2316/1234 +f 2083/2314/1232 2085/2316/1234 2086/2317/1235 +f 2086/2317/1235 2085/2316/1234 2087/2318/1236 +f 2086/2317/1235 2087/2318/1236 2088/2319/1237 +f 2082/2313/1231 2081/2312/1230 2089/2320/1238 +f 2082/2313/1231 2089/2320/1238 2090/2321/1239 +f 1571/1802/741 1570/1801/740 2091/2322/1240 +f 1571/1802/741 2091/2322/1240 2092/2323/1241 +f 1569/1800/739 1568/1799/738 2093/2324/1242 +f 1569/1800/739 2093/2324/1242 2094/2325/1240 +f 2094/2325/1240 2093/2324/1242 2095/2326/1243 +f 2094/2325/1240 2095/2326/1243 2096/2327/1244 +f 2092/2323/1241 2091/2322/1240 2097/2328/1245 +f 2092/2323/1241 2097/2328/1245 2098/2329/1246 +f 1908/2139/1061 1907/2138/1060 2099/2330/1247 +f 1908/2139/1061 2099/2330/1247 2100/2331/1248 +f 2101/2332/1060 2102/2333/1058 2103/2334/1249 +f 2101/2332/1060 2103/2334/1249 2104/2335/1250 +f 2104/2335/1250 2103/2334/1249 1869/2100/1024 +f 2104/2335/1250 1869/2100/1024 1868/2099/1023 +f 2100/2331/1248 2099/2330/1247 1865/2096/1020 +f 2100/2331/1248 1865/2096/1020 1864/2095/1019 +f 1946/2177/1098 1945/2176/1097 2105/2336/1251 +f 1946/2177/1098 2105/2336/1251 2106/2337/1252 +f 1944/2175/1096 1943/2174/1095 2107/2338/1253 +f 1944/2175/1096 2107/2338/1253 2108/2339/1254 +f 2108/2339/1254 2107/2338/1253 2109/2340/1255 +f 2108/2339/1254 2109/2340/1255 2110/2341/1256 +f 2111/2342/1252 2112/2343/1254 2113/2344/1257 +f 2111/2342/1252 2113/2344/1257 2114/2345/1258 +f 1673/1904/836 1672/1903/835 2115/2346/1259 +f 1673/1904/836 2115/2346/1259 2116/2347/1260 +f 1671/1902/834 1670/1901/833 2117/2348/1261 +f 1671/1902/834 2117/2348/1261 2118/2349/1262 +f 2118/2349/1262 2117/2348/1261 1853/2084/1008 +f 2118/2349/1262 1853/2084/1008 1852/2083/1007 +f 2116/2347/1260 2115/2346/1259 1849/2080/1004 +f 2116/2347/1260 1849/2080/1004 1848/2079/1003 +f 1847/2078/1002 1846/2077/1001 2119/2350/1263 +f 1847/2078/1002 2119/2350/1263 2120/2351/1264 +f 1845/2076/1000 1844/2075/999 2121/2352/1265 +f 1845/2076/1000 2121/2352/1265 2122/2353/1266 +f 2122/2353/1266 2121/2352/1265 2123/2354/1267 +f 2122/2353/1266 2123/2354/1267 2124/2355/1268 +f 2120/2351/1264 2119/2350/1263 2125/2356/1269 +f 2120/2351/1264 2125/2356/1269 2126/2357/1270 +f 2127/2358/1271 2128/2359/1272 2129/2360/1273 +f 2127/2358/1271 2129/2360/1273 2130/2361/1274 +f 2131/2362/1272 2132/2363/1275 2133/2364/1276 +f 2131/2362/1272 2133/2364/1276 2134/2365/1277 +f 2134/2365/1277 2133/2364/1276 1837/2068/992 +f 2134/2365/1277 1837/2068/992 1836/2067/989 +f 2130/2361/1274 2129/2360/1273 1833/2064/989 +f 2130/2361/1274 1833/2064/989 1832/2063/988 +f 2135/2366/1278 2136/2367/1279 2137/2368/1280 +f 2135/2366/1278 2137/2368/1280 2138/2369/1281 +f 2139/2370/1279 2140/2371/1282 2141/2372/1283 +f 2139/2370/1279 2141/2372/1283 2142/2373/1284 +f 2142/2373/1284 2141/2372/1283 2143/2374/1285 +f 2142/2373/1284 2143/2374/1285 2144/2375/1286 +f 2138/2369/1281 2137/2368/1280 2145/2376/1287 +f 2138/2369/1281 2145/2376/1287 2146/2377/1288 +f 2114/2345/1258 2113/2344/1257 2147/2378/1289 +f 2114/2345/1258 2147/2378/1289 2148/2379/1290 +f 2110/2341/1256 2109/2340/1255 2149/2380/1291 +f 2110/2341/1256 2149/2380/1291 2150/2381/1289 +f 2150/2381/1289 2149/2380/1291 2151/2382/1292 +f 2150/2381/1289 2151/2382/1292 2152/2383/1293 +f 2148/2379/1290 2147/2378/1289 2153/2384/1294 +f 2148/2379/1290 2153/2384/1294 2154/2385/1295 +f 2155/2386/1296 2156/2387/1297 2157/2388/1298 +f 2155/2386/1296 2157/2388/1298 2158/2389/1299 +f 2159/2390/1300 2160/2391/1301 2161/2392/1302 +f 2159/2390/1300 2161/2392/1302 2162/2393/1298 +f 2162/2393/1298 2161/2392/1302 2163/2394/1303 +f 2162/2393/1298 2163/2394/1303 2164/2395/1304 +f 2158/2389/1299 2157/2388/1298 2165/2396/1305 +f 2158/2389/1299 2165/2396/1305 2166/2397/1306 +f 1731/1962/890 1730/1961/889 2167/2398/1307 +f 1731/1962/890 2167/2398/1307 2168/2399/1308 +f 1729/1960/888 1728/1959/887 2169/2400/1309 +f 1729/1960/888 2169/2400/1309 2170/2401/1310 +f 2170/2401/1310 2169/2400/1309 1984/2215/1135 +f 2170/2401/1310 1984/2215/1135 1983/2214/1134 +f 2168/2399/1308 2167/2398/1307 1980/2211/1131 +f 2168/2399/1308 1980/2211/1131 1979/2210/1130 +f 2020/2251/1169 2019/2250/1168 2171/2402/1311 +f 2020/2251/1169 2171/2402/1311 2172/2403/1312 +f 2018/2249/1167 2017/2248/1166 2173/2404/1313 +f 2018/2249/1167 2173/2404/1313 2174/2405/1314 +f 2174/2405/1314 2173/2404/1313 1813/2044/969 +f 2174/2405/1314 1813/2044/969 1812/2043/968 +f 2175/2406/1312 2176/2407/1315 1809/2040/965 +f 2175/2406/1312 1809/2040/965 1808/2039/964 +f 2177/2408/1316 2178/2409/1317 2179/2410/1318 +f 2177/2408/1316 2179/2410/1318 2180/2411/1319 +f 2181/2412/1317 2182/2413/1320 2183/2414/1321 +f 2181/2412/1317 2183/2414/1321 2184/2415/1322 +f 2184/2415/1322 2183/2414/1321 2160/2391/1301 +f 2184/2415/1322 2160/2391/1301 2159/2390/1300 +f 2180/2411/1319 2179/2410/1318 2156/2387/1297 +f 2180/2411/1319 2156/2387/1297 2155/2386/1296 +f 1557/1788/727 1556/1787/726 2185/2416/1323 +f 1557/1788/727 2185/2416/1323 2186/2417/1324 +f 1555/1786/725 1554/1785/724 2187/2418/1325 +f 1555/1786/725 2187/2418/1325 2188/2419/1326 +f 2188/2419/1326 2187/2418/1325 1769/2000/927 +f 2188/2419/1326 1769/2000/927 1768/1999/926 +f 2186/2417/1324 2185/2416/1323 1765/1996/923 +f 2186/2417/1324 1765/1996/923 1764/1995/922 +f 2189/2420/1327 2190/2421/1328 2191/2422/1329 +f 2189/2420/1327 2191/2422/1329 2192/2423/1330 +f 2193/2424/1331 1103/1699/610 1102/1698/609 +f 2193/2424/1331 1102/1698/609 2194/2425/1332 +f 2194/2425/1332 1102/1698/609 1101/1697/608 +f 2194/2425/1332 1101/1697/608 1896/2127/1050 +f 2192/2423/1330 2191/2422/1329 1893/2124/1047 +f 2192/2423/1330 1893/2124/1047 1892/2123/1046 +f 2078/2309/1227 2077/2308/1226 2195/2426/1333 +f 2078/2309/1227 2195/2426/1333 2196/2427/1334 +f 2076/2307/1225 2075/2306/1224 2197/2428/1335 +f 2076/2307/1225 2197/2428/1335 2198/2429/1333 +f 2198/2429/1333 2197/2428/1335 1103/1699/610 +f 2198/2429/1333 1103/1699/610 2193/2424/1331 +f 2196/2427/1334 2195/2426/1333 2190/2421/1328 +f 2196/2427/1334 2190/2421/1328 2189/2420/1327 +f 2199/2430/1336 2200/1608/1337 2201/2431/1338 +f 2199/2430/1336 2201/2431/1338 2202/2432/1339 +f 2200/1608/1337 1261/1582/499 1483/1725/670 +f 2200/1608/1337 1483/1725/670 2201/2431/1338 +f 2201/2431/1338 1483/1725/670 1272/1711/636 +f 2201/2431/1338 1272/1711/636 2203/2433/1340 +f 2202/2432/1339 2201/2431/1338 2203/2433/1340 +f 2202/2432/1339 2203/2433/1340 2204/2434/1341 +f 1819/2050/975 1818/2049/974 2205/2435/1342 +f 1819/2050/975 2205/2435/1342 2206/2436/1343 +f 1817/2048/973 1816/2047/972 2207/2437/1344 +f 1817/2048/973 2207/2437/1344 2208/2438/1345 +f 2208/2438/1345 2207/2437/1344 2209/2439/1346 +f 2208/2438/1345 2209/2439/1346 2210/2440/1347 +f 2206/2436/1343 2205/2435/1342 2211/2441/1348 +f 2206/2436/1343 2211/2441/1348 2212/2442/1349 +f 2213/2443/1350 2214/2444/1351 2215/2445/1352 +f 2213/2443/1350 2215/2445/1352 2216/2446/1353 +f 2217/2447/1354 2218/2448/1355 2219/2449/1356 +f 2217/2447/1354 2219/2449/1356 2220/2450/1357 +f 2220/2450/1357 2219/2449/1356 1960/2191/1112 +f 2220/2450/1357 1960/2191/1112 1959/2190/1111 +f 2216/2446/1353 2215/2445/1352 1956/2187/1108 +f 2216/2446/1353 1956/2187/1108 1955/2186/1107 +f 1807/2038/963 1806/2037/962 2221/2451/1358 +f 1807/2038/963 2221/2451/1358 2222/2452/1359 +f 1805/2036/961 1804/2035/960 2223/2453/1360 +f 1805/2036/961 2223/2453/1360 2224/2454/1361 +f 2224/2454/1361 2223/2453/1360 2225/2455/1362 +f 2224/2454/1361 2225/2455/1362 2226/2456/1363 +f 2222/2452/1359 2221/2451/1358 2227/2457/1364 +f 2222/2452/1359 2227/2457/1364 2228/2458/1365 +f 2228/2458/1365 2227/2457/1364 2229/2459/1366 +f 2228/2458/1365 2229/2459/1366 2230/2460/1367 +f 2226/2456/1363 2225/2455/1362 2231/2461/1368 +f 2226/2456/1363 2231/2461/1368 2232/2462/1369 +f 2232/2462/1369 2231/2461/1368 2233/2463/1370 +f 2232/2462/1369 2233/2463/1370 2234/2464/1371 +f 2230/2460/1367 2229/2459/1366 2235/2465/1372 +f 2230/2460/1367 2235/2465/1372 2236/2466/1373 +f 2237/2467/1374 2238/2468/1375 2239/2469/1376 +f 2237/2467/1374 2239/2469/1376 2240/2470/1377 +f 2241/2471/1375 2242/2472/1378 2243/2473/1379 +f 2241/2471/1375 2243/2473/1379 2244/2474/1380 +f 2244/2474/1380 2243/2473/1379 2006/2237/1155 +f 2244/2474/1380 2006/2237/1155 2005/2236/1154 +f 2240/2470/1377 2239/2469/1376 2002/2233/1151 +f 2240/2470/1377 2002/2233/1151 2001/2232/1150 +f 1891/2122/1045 1890/2121/1044 2245/2475/1381 +f 1891/2122/1045 2245/2475/1381 2246/2476/1382 +f 1889/2120/1043 1888/2119/1042 2247/2477/1383 +f 1889/2120/1043 2247/2477/1383 2248/2478/1384 +f 2248/2478/1384 2247/2477/1383 2132/2363/1275 +f 2248/2478/1384 2132/2363/1275 2131/2362/1272 +f 2246/2476/1382 2245/2475/1381 2128/2359/1272 +f 2246/2476/1382 2128/2359/1272 2127/2358/1271 +f 1711/1942/871 1710/1941/870 2249/2479/1385 +f 1711/1942/871 2249/2479/1385 2250/2480/1386 +f 1709/1940/870 1708/1939/869 2251/2481/1387 +f 1709/1940/870 2251/2481/1387 2252/2482/1388 +f 2252/2482/1388 2251/2481/1387 1679/1910/842 +f 2252/2482/1388 1679/1910/842 1678/1909/841 +f 2250/2480/1386 2249/2479/1385 1675/1906/838 +f 2250/2480/1386 1675/1906/838 1674/1905/837 +f 2253/2483/1389 2254/2484/1390 2255/2485/1391 +f 2253/2483/1389 2255/2485/1391 2256/2486/1392 +f 2257/2487/1393 2258/2488/1394 2259/2489/1395 +f 2257/2487/1393 2259/2489/1395 2260/2490/1396 +f 2260/2490/1396 2259/2489/1395 2242/2472/1378 +f 2260/2490/1396 2242/2472/1378 2241/2471/1375 +f 2256/2486/1392 2255/2485/1391 2238/2468/1375 +f 2256/2486/1392 2238/2468/1375 2237/2467/1374 +f 1922/2153/1074 1921/2152/1073 2261/2491/1397 +f 1922/2153/1074 2261/2491/1397 2262/2492/1398 +f 1918/2149/1071 1917/2148/1070 2263/2493/1399 +f 1918/2149/1071 2263/2493/1399 2264/2494/1397 +f 2264/2494/1397 2263/2493/1399 1940/2171/1092 +f 2264/2494/1397 1940/2171/1092 1939/2170/1091 +f 2262/2492/1398 2261/2491/1397 1936/2167/1088 +f 2262/2492/1398 1936/2167/1088 1935/2166/1087 +f 2054/2285/1203 2053/2284/1202 2265/2495/1400 +f 2054/2285/1203 2265/2495/1400 2266/2496/1401 +f 2052/2283/1201 2051/2282/1200 2267/2497/1402 +f 2052/2283/1201 2267/2497/1402 2268/2498/1403 +f 2268/2498/1403 2267/2497/1402 2182/2413/1320 +f 2268/2498/1403 2182/2413/1320 2181/2412/1317 +f 2266/2496/1401 2265/2495/1400 2178/2409/1317 +f 2266/2496/1401 2178/2409/1317 2177/2408/1316 +f 2034/2265/1183 2033/2264/1182 2269/2499/1404 +f 2034/2265/1183 2269/2499/1404 2270/2500/1405 +f 2032/2263/1181 2031/2262/1180 2271/2501/1406 +f 2032/2263/1181 2271/2501/1406 2272/2502/1404 +f 2272/2502/1404 2271/2501/1406 1635/1866/801 +f 2272/2502/1404 1635/1866/801 1634/1865/798 +f 2270/2500/1405 2269/2499/1404 1631/1862/798 +f 2270/2500/1405 1631/1862/798 1630/1861/797 +f 1583/1814/753 1582/1813/752 2273/2503/1407 +f 1583/1814/753 2273/2503/1407 2274/2504/1408 +f 1581/1812/751 1580/1811/750 2275/2505/1409 +f 1581/1812/751 2275/2505/1409 2276/2506/1410 +f 2276/2506/1410 2275/2505/1409 1627/1858/794 +f 2276/2506/1410 1627/1858/794 1626/1857/793 +f 2274/2504/1408 2273/2503/1407 1623/1854/790 +f 2274/2504/1408 1623/1854/790 1622/1853/789 +f 2166/2397/1306 2165/2396/1305 2277/2507/1411 +f 2166/2397/1306 2277/2507/1411 2278/2508/1412 +f 2164/2395/1304 2163/2394/1303 2279/2509/1413 +f 2164/2395/1304 2279/2509/1413 2280/2510/1414 +f 2280/2510/1414 2279/2509/1413 1914/2145/1067 +f 2280/2510/1414 1914/2145/1067 1913/2144/1066 +f 2278/2508/1412 2277/2507/1411 1910/2141/1063 +f 2278/2508/1412 1910/2141/1063 1909/2140/1062 +f 2070/2301/1219 2069/2300/1218 2281/2511/1415 +f 2070/2301/1219 2281/2511/1415 2282/2512/1416 +f 2068/2299/1217 2067/2298/1216 2283/2513/1417 +f 2068/2299/1217 2283/2513/1417 2284/2514/1418 +f 2284/2514/1418 2283/2513/1417 2285/2515/1419 +f 2284/2514/1418 2285/2515/1419 2286/2516/1420 +f 2282/2512/1416 2281/2511/1415 2287/2517/1421 +f 2282/2512/1416 2287/2517/1421 2288/2518/1422 +f 1607/1838/776 1606/1837/775 2289/2519/1423 +f 1607/1838/776 2289/2519/1423 2290/2520/1424 +f 1605/1836/775 1604/1835/774 2291/2521/1425 +f 1605/1836/775 2291/2521/1425 2292/2522/1423 +f 2292/2522/1423 2291/2521/1425 1781/2012/939 +f 2292/2522/1423 1781/2012/939 1780/2011/938 +f 2290/2520/1424 2289/2519/1423 1777/2008/935 +f 2290/2520/1424 1777/2008/935 1776/2007/934 +f 2126/2357/1270 2125/2356/1269 2293/2523/1426 +f 2126/2357/1270 2293/2523/1426 2294/2524/1427 +f 2124/2355/1268 2123/2354/1267 2295/2525/1428 +f 2124/2355/1268 2295/2525/1428 2296/2526/1429 +f 2297/2527/1430 2298/2528/1431 1577/1808/747 +f 2297/2527/1430 1577/1808/747 1576/1807/746 +f 2294/2524/1427 2293/2523/1426 1573/1804/743 +f 2294/2524/1427 1573/1804/743 1572/1803/742 +f 2154/2385/1295 2153/2384/1294 2299/2529/1432 +f 2154/2385/1295 2299/2529/1432 2300/2530/1433 +f 2152/2383/1293 2151/2382/1292 2301/2531/1434 +f 2152/2383/1293 2301/2531/1434 2302/2532/1435 +f 2302/2532/1435 2301/2531/1434 1992/2223/1142 +f 2302/2532/1435 1992/2223/1142 1991/2222/1139 +f 2300/2530/1433 2299/2529/1432 1988/2219/1139 +f 2300/2530/1433 1988/2219/1139 1987/2218/1138 +f 2012/2243/1161 2011/2242/1160 2303/2533/1436 +f 2012/2243/1161 2303/2533/1436 2304/2534/1437 +f 2010/2241/1159 2009/2240/1158 2305/2535/1438 +f 2010/2241/1159 2305/2535/1438 2306/2536/1439 +f 2306/2536/1439 2305/2535/1438 1825/2056/981 +f 2306/2536/1439 1825/2056/981 1824/2055/980 +f 2304/2534/1437 2303/2533/1436 1821/2052/977 +f 2304/2534/1437 1821/2052/977 1820/2051/976 +f 2146/2377/1288 2145/2376/1287 2307/2537/1440 +f 2146/2377/1288 2307/2537/1440 2308/2538/1441 +f 2144/2375/1286 2143/2374/1285 2309/2539/1442 +f 2144/2375/1286 2309/2539/1442 2310/2540/1443 +f 2310/2540/1443 2309/2539/1442 1601/1832/771 +f 2310/2540/1443 1601/1832/771 1600/1831/770 +f 2308/2538/1441 2307/2537/1440 1597/1828/767 +f 2308/2538/1441 1597/1828/767 1596/1827/766 +f 2288/2518/1422 2287/2517/1421 2311/2541/1444 +f 2288/2518/1422 2311/2541/1444 2312/2542/1445 +f 2286/2516/1420 2285/2515/1419 2313/2543/1446 +f 2286/2516/1420 2313/2543/1446 2314/2544/1447 +f 2314/2544/1447 2313/2543/1446 1725/1956/885 +f 2314/2544/1447 1725/1956/885 1724/1955/884 +f 2312/2542/1445 2311/2541/1444 1721/1952/881 +f 2312/2542/1445 1721/1952/881 1720/1951/880 +f 2212/2442/1349 2211/2441/1348 2315/2545/1448 +f 2212/2442/1349 2315/2545/1448 2316/2546/1449 +f 2210/2440/1347 2209/2439/1346 2317/2547/1450 +f 2210/2440/1347 2317/2547/1450 2318/2548/1451 +f 2318/2548/1451 2317/2547/1450 1737/1968/896 +f 2318/2548/1451 1737/1968/896 1736/1967/895 +f 2316/2546/1449 2315/2545/1448 1733/1964/892 +f 2316/2546/1449 1733/1964/892 1732/1963/891 +f 2319/2549/1452 2320/2550/1453 2321/2551/1454 +f 2319/2549/1452 2321/2551/1454 2322/2552/1455 +f 2323/2553/1456 2204/2434/1341 2324/2554/1457 +f 2323/2553/1456 2324/2554/1457 2325/2555/1454 +f 2325/2555/1454 2324/2554/1457 2326/2556/1458 +f 2325/2555/1454 2326/2556/1458 2327/2557/1459 +f 2322/2552/1455 2321/2551/1454 2328/2558/1460 +f 2322/2552/1455 2328/2558/1460 2329/2559/1461 +f 2012/2243/1161 2330/2560/1462 2331/2561/1463 +f 2012/2243/1161 2331/2561/1463 2004/2235/1153 +f 2330/2560/1462 2332/2562/1462 2333/2563/1463 +f 2330/2560/1462 2333/2563/1463 2331/2561/1463 +f 2331/2561/1463 2333/2563/1463 2334/2564/1464 +f 2331/2561/1463 2334/2564/1464 2335/2565/1464 +f 2004/2235/1153 2331/2561/1463 2335/2565/1464 +f 2004/2235/1153 2335/2565/1464 2001/2232/1150 +f 2332/2562/1462 2336/2566/1462 2337/2567/1463 +f 2332/2562/1462 2337/2567/1463 2333/2563/1463 +f 2336/2566/1462 1853/2084/1008 2117/2348/1261 +f 2336/2566/1462 2117/2348/1261 2337/2567/1463 +f 2337/2567/1463 2117/2348/1261 1670/1901/833 +f 2337/2567/1463 1670/1901/833 2338/2568/1464 +f 2333/2563/1463 2337/2567/1463 2338/2568/1464 +f 2333/2563/1463 2338/2568/1464 2334/2564/1464 +f 2020/2251/1169 2339/2569/1465 2340/2570/1466 +f 2020/2251/1169 2340/2570/1466 2014/2245/1163 +f 2339/2569/1465 2341/2571/1467 2342/2572/1466 +f 2339/2569/1465 2342/2572/1466 2340/2570/1466 +f 2340/2570/1466 2342/2572/1466 2343/2573/1468 +f 2340/2570/1466 2343/2573/1468 2344/2574/1468 +f 2014/2245/1163 2340/2570/1466 2344/2574/1468 +f 2014/2245/1163 2344/2574/1468 1900/2131/1054 +f 2341/2571/1467 2345/2575/1465 2346/2576/1466 +f 2341/2571/1467 2346/2576/1466 2342/2572/1466 +f 2345/2575/1465 2123/2354/1267 2121/2352/1265 +f 2345/2575/1465 2121/2352/1265 2346/2576/1466 +f 2346/2576/1466 2121/2352/1265 1844/2075/999 +f 2346/2576/1466 1844/2075/999 2347/2577/1468 +f 2342/2572/1466 2346/2576/1466 2347/2577/1468 +f 2342/2572/1466 2347/2577/1468 2343/2573/1468 +f 1922/2153/1074 2348/2578/1469 2349/2579/1470 +f 1922/2153/1074 2349/2579/1470 1919/2150/1072 +f 2348/2578/1469 2350/2580/1469 2351/2581/1470 +f 2348/2578/1469 2351/2581/1470 2349/2579/1470 +f 2352/2582/1470 2353/2583/1470 2354/2584/1471 +f 2352/2582/1470 2354/2584/1471 2355/2585/1471 +f 1912/2143/1065 2352/2582/1470 2355/2585/1471 +f 1912/2143/1065 2355/2585/1471 1909/2140/1062 +f 2350/2580/1469 2356/2586/1469 2357/2587/1470 +f 2350/2580/1469 2357/2587/1470 2351/2581/1470 +f 2356/2586/1469 1618/1849/785 1617/1848/783 +f 2356/2586/1469 1617/1848/783 2357/2587/1470 +f 2358/2588/1472 1614/1845/783 1613/1844/782 +f 2358/2588/1472 1613/1844/782 2359/2589/1471 +f 2353/2583/1470 2358/2588/1472 2359/2589/1471 +f 2353/2583/1470 2359/2589/1471 2354/2584/1471 +f 1923/2154/1075 2360/2590/1473 2361/2591/1474 +f 1923/2154/1075 2361/2591/1474 1982/2213/1133 +f 2360/2590/1473 2362/2592/1473 2363/2593/1474 +f 2360/2590/1473 2363/2593/1474 2361/2591/1474 +f 2361/2591/1474 2363/2593/1474 2364/2594/1475 +f 2361/2591/1474 2364/2594/1475 2365/2595/1475 +f 1982/2213/1133 2361/2591/1474 2365/2595/1475 +f 1982/2213/1133 2365/2595/1475 1979/2210/1130 +f 2362/2592/1473 2366/2596/1473 2367/2597/1474 +f 2362/2592/1473 2367/2597/1474 2363/2593/1474 +f 2366/2596/1473 1796/2027/952 1794/2025/951 +f 2366/2596/1473 1794/2025/951 2367/2597/1474 +f 2367/2597/1474 1794/2025/951 1793/2024/950 +f 2367/2597/1474 1793/2024/950 2368/2598/1475 +f 2363/2593/1474 2367/2597/1474 2368/2598/1475 +f 2363/2593/1474 2368/2598/1475 2364/2594/1475 +f 2040/2271/1189 2369/2599/1476 2370/2600/1477 +f 2040/2271/1189 2370/2600/1477 2038/2269/1187 +f 2371/2601/1478 2372/2602/1479 2373/2603/1480 +f 2371/2601/1478 2373/2603/1480 2374/2604/1481 +f 2374/2604/1481 2373/2603/1480 2375/2605/1482 +f 2374/2604/1481 2375/2605/1482 2376/2606/1483 +f 2377/2607/1484 2374/2604/1481 2376/2606/1483 +f 2377/2607/1484 2376/2606/1483 2378/2608/1485 +f 2379/2609/1486 2380/2610/1487 2381/2611/1488 +f 2379/2609/1486 2381/2611/1488 2382/2612/1489 +f 2380/2610/1487 2031/2262/1180 2029/2260/1178 +f 2380/2610/1487 2029/2260/1178 2381/2611/1488 +f 2381/2611/1488 2029/2260/1178 2028/2259/1177 +f 2381/2611/1488 2028/2259/1177 2383/2613/1490 +f 2382/2612/1489 2381/2611/1488 2383/2613/1490 +f 2382/2612/1489 2383/2613/1490 2384/2614/1491 +f 2000/2231/1149 2385/2615/1492 2386/2616/1493 +f 2000/2231/1149 2386/2616/1493 1997/2228/1141 +f 2385/2615/1492 2387/2617/1492 2388/2618/1493 +f 2385/2615/1492 2388/2618/1493 2386/2616/1493 +f 2389/2619/1494 2390/2620/1494 2391/2621/1495 +f 2389/2619/1494 2391/2621/1495 2392/2622/1495 +f 1990/2221/1141 2389/2619/1494 2392/2622/1495 +f 1990/2221/1141 2392/2622/1495 1987/2218/1138 +f 2387/2617/1492 2393/2623/1492 2394/2624/1493 +f 2387/2617/1492 2394/2624/1493 2388/2618/1493 +f 2393/2623/1492 1568/1799/738 1567/1798/737 +f 2393/2623/1492 1567/1798/737 2394/2624/1493 +f 2395/2625/1494 1564/1795/734 1563/1794/733 +f 2395/2625/1494 1563/1794/733 2396/2626/1495 +f 2390/2620/1494 2395/2625/1494 2396/2626/1495 +f 2390/2620/1494 2396/2626/1495 2391/2621/1495 +f 2054/2285/1203 2397/2627/1496 2398/2628/1497 +f 2054/2285/1203 2398/2628/1497 2048/2279/1197 +f 2397/2627/1496 2399/2629/1496 2400/2630/1497 +f 2397/2627/1496 2400/2630/1497 2398/2628/1497 +f 2398/2628/1497 2400/2630/1497 2401/2631/1498 +f 2398/2628/1497 2401/2631/1498 2402/2632/1498 +f 2048/2279/1197 2398/2628/1497 2402/2632/1498 +f 2048/2279/1197 2402/2632/1498 2045/2276/1194 +f 2399/2629/1496 2403/2633/1496 2404/2634/1497 +f 2399/2629/1496 2404/2634/1497 2400/2630/1497 +f 2403/2633/1496 1869/2100/1024 2103/2334/1249 +f 2403/2633/1496 2103/2334/1249 2404/2634/1497 +f 2404/2634/1497 2103/2334/1249 2102/2333/1058 +f 2404/2634/1497 2102/2333/1058 2405/2635/1498 +f 2400/2630/1497 2404/2634/1497 2405/2635/1498 +f 2400/2630/1497 2405/2635/1498 2401/2631/1498 +f 2062/2293/1211 2406/2636/1499 2407/2637/1500 +f 2062/2293/1211 2407/2637/1500 2056/2287/1205 +f 2406/2636/1499 2408/2638/1499 2409/2639/1500 +f 2406/2636/1499 2409/2639/1500 2407/2637/1500 +f 2407/2637/1500 2409/2639/1500 2387/2617/1492 +f 2407/2637/1500 2387/2617/1492 2385/2615/1492 +f 2056/2287/1205 2407/2637/1500 2385/2615/1492 +f 2056/2287/1205 2385/2615/1492 2000/2231/1149 +f 2408/2638/1499 2410/2640/1499 2411/2641/1500 +f 2408/2638/1499 2411/2641/1500 2409/2639/1500 +f 2410/2640/1499 2095/2326/1243 2093/2324/1242 +f 2410/2640/1499 2093/2324/1242 2411/2641/1500 +f 2411/2641/1500 2093/2324/1242 1568/1799/738 +f 2411/2641/1500 1568/1799/738 2393/2623/1492 +f 2409/2639/1500 2411/2641/1500 2393/2623/1492 +f 2409/2639/1500 2393/2623/1492 2387/2617/1492 +f 2070/2301/1219 2412/2642/1501 2413/2643/1502 +f 2070/2301/1219 2413/2643/1502 2064/2295/1213 +f 2412/2642/1501 2414/2644/1501 2415/2645/1502 +f 2412/2642/1501 2415/2645/1502 2413/2643/1502 +f 2413/2643/1502 2415/2645/1502 2416/2646/1503 +f 2413/2643/1502 2416/2646/1503 2417/2647/1503 +f 2064/2295/1213 2413/2643/1502 2417/2647/1503 +f 2064/2295/1213 2417/2647/1503 1966/2197/1118 +f 2414/2644/1501 2418/2648/1501 2419/2649/1502 +f 2414/2644/1501 2419/2649/1502 2415/2645/1502 +f 2418/2648/1501 2132/2363/1275 2247/2477/1383 +f 2418/2648/1501 2247/2477/1383 2419/2649/1502 +f 2419/2649/1502 2247/2477/1383 1888/2119/1042 +f 2419/2649/1502 1888/2119/1042 2420/2650/1503 +f 2415/2645/1502 2419/2649/1502 2420/2650/1503 +f 2415/2645/1502 2420/2650/1503 2416/2646/1503 +f 1934/2165/1086 2421/2651/1504 2422/2652/1505 +f 1934/2165/1086 2422/2652/1505 1926/2157/1078 +f 2421/2651/1504 2423/2653/1498 2424/2654/1505 +f 2421/2651/1504 2424/2654/1505 2422/2652/1505 +f 2422/2652/1505 2424/2654/1505 2362/2592/1473 +f 2422/2652/1505 2362/2592/1473 2360/2590/1473 +f 1926/2157/1078 2422/2652/1505 2360/2590/1473 +f 1926/2157/1078 2360/2590/1473 1923/2154/1075 +f 2423/2653/1498 2425/2655/1504 2426/2656/1505 +f 2423/2653/1498 2426/2656/1505 2424/2654/1505 +f 2425/2655/1504 1905/2136/1058 1903/2134/1057 +f 2425/2655/1504 1903/2134/1057 2426/2656/1505 +f 2426/2656/1505 1903/2134/1057 1796/2027/952 +f 2426/2656/1505 1796/2027/952 2366/2596/1473 +f 2424/2654/1505 2426/2656/1505 2366/2596/1473 +f 2424/2654/1505 2366/2596/1473 2362/2592/1473 +f 2078/2309/1227 2427/2657/1506 2428/2658/1507 +f 2078/2309/1227 2428/2658/1507 2072/2303/1221 +f 2427/2657/1506 2429/2659/1506 2430/2660/1508 +f 2427/2657/1506 2430/2660/1508 2428/2658/1507 +f 2428/2658/1507 2430/2660/1508 2431/2661/1509 +f 2428/2658/1507 2431/2661/1509 2432/2662/1509 +f 2072/2303/1221 2428/2658/1507 2432/2662/1509 +f 2072/2303/1221 2432/2662/1509 1831/2062/987 +f 2429/2659/1506 2433/2663/1506 2434/2664/1507 +f 2429/2659/1506 2434/2664/1507 2430/2660/1508 +f 2433/2663/1506 1769/2000/927 2187/2418/1325 +f 2433/2663/1506 2187/2418/1325 2434/2664/1507 +f 2434/2664/1507 2187/2418/1325 1554/1785/724 +f 2434/2664/1507 1554/1785/724 2435/2665/1509 +f 2430/2660/1508 2434/2664/1507 2435/2665/1509 +f 2430/2660/1508 2435/2665/1509 2431/2661/1509 +f 1966/2197/1118 2417/2647/1503 2436/2666/1510 +f 1966/2197/1118 2436/2666/1510 1958/2189/1110 +f 2417/2647/1503 2416/2646/1503 2437/2667/1510 +f 2417/2647/1503 2437/2667/1510 2436/2666/1510 +f 2436/2666/1510 2437/2667/1510 2438/2668/1511 +f 2436/2666/1510 2438/2668/1511 2439/2669/1511 +f 1958/2189/1110 2436/2666/1510 2439/2669/1511 +f 1958/2189/1110 2439/2669/1511 1955/2186/1107 +f 2416/2646/1503 2420/2650/1503 2440/2670/1510 +f 2416/2646/1503 2440/2670/1510 2437/2667/1510 +f 2420/2650/1503 1888/2119/1042 1886/2117/1040 +f 2420/2650/1503 1886/2117/1040 2440/2670/1510 +f 2440/2670/1510 1886/2117/1040 1860/2091/1015 +f 2440/2670/1510 1860/2091/1015 2441/2671/1511 +f 2437/2667/1510 2440/2670/1510 2441/2671/1511 +f 2437/2667/1510 2441/2671/1511 2438/2668/1511 +f 2079/2310/1228 2442/2672/1512 2443/2673/1513 +f 2079/2310/1228 2443/2673/1513 2444/2674/1514 +f 2442/2672/1512 2445/2675/1515 2446/2676/1513 +f 2442/2672/1512 2446/2676/1513 2443/2673/1513 +f 2443/2673/1513 2446/2676/1513 2408/2638/1499 +f 2443/2673/1513 2408/2638/1499 2406/2636/1499 +f 2444/2674/1514 2443/2673/1513 2406/2636/1499 +f 2444/2674/1514 2406/2636/1499 2062/2293/1211 +f 2445/2675/1515 2447/2677/1516 2448/2678/1513 +f 2445/2675/1515 2448/2678/1513 2446/2676/1513 +f 2447/2677/1516 1877/2108/1031 2449/2679/1517 +f 2447/2677/1516 2449/2679/1517 2448/2678/1513 +f 2448/2678/1513 2449/2679/1517 2095/2326/1243 +f 2448/2678/1513 2095/2326/1243 2410/2640/1499 +f 2446/2676/1513 2448/2678/1513 2410/2640/1499 +f 2446/2676/1513 2410/2640/1499 2408/2638/1499 +f 2155/2386/1296 2450/2680/1518 2451/2681/1519 +f 2155/2386/1296 2451/2681/1519 2180/2411/1319 +f 2450/2680/1518 2452/2682/1520 2453/2683/1519 +f 2450/2680/1518 2453/2683/1519 2451/2681/1519 +f 2451/2681/1519 2453/2683/1519 2454/2684/1521 +f 2451/2681/1519 2454/2684/1521 2455/2685/1522 +f 2180/2411/1319 2451/2681/1519 2455/2685/1522 +f 2180/2411/1319 2455/2685/1522 2177/2408/1316 +f 2452/2682/1520 2456/2686/1518 2457/2687/1519 +f 2452/2682/1520 2457/2687/1519 2453/2683/1519 +f 2456/2686/1518 1646/1877/811 1644/1875/809 +f 2456/2686/1518 1644/1875/809 2457/2687/1519 +f 2457/2687/1519 1644/1875/809 1643/1874/808 +f 2457/2687/1519 1643/1874/808 2458/2688/1522 +f 2453/2683/1519 2457/2687/1519 2458/2688/1522 +f 2453/2683/1519 2458/2688/1522 2454/2684/1521 +f 1955/2186/1107 2439/2669/1511 2459/2689/1523 +f 1955/2186/1107 2459/2689/1523 2216/2446/1353 +f 2439/2669/1511 2438/2668/1511 2460/2690/1523 +f 2439/2669/1511 2460/2690/1523 2459/2689/1523 +f 2459/2689/1523 2460/2690/1523 2461/2691/1524 +f 2459/2689/1523 2461/2691/1524 2462/2692/1524 +f 2216/2446/1353 2459/2689/1523 2462/2692/1524 +f 2216/2446/1353 2462/2692/1524 2213/2443/1350 +f 2438/2668/1511 2441/2671/1511 2463/2693/1523 +f 2438/2668/1511 2463/2693/1523 2460/2690/1523 +f 2441/2671/1511 1860/2091/1015 1858/2089/1013 +f 2441/2671/1511 1858/2089/1013 2463/2693/1523 +f 2463/2693/1523 1858/2089/1013 1506/1737/679 +f 2463/2693/1523 1506/1737/679 2464/2694/1524 +f 2460/2690/1523 2463/2693/1523 2464/2694/1524 +f 2460/2690/1523 2464/2694/1524 2461/2691/1524 +f 1831/2062/987 2432/2662/1509 2465/2695/1525 +f 1831/2062/987 2465/2695/1525 1823/2054/979 +f 2432/2662/1509 2431/2661/1509 2466/2696/1526 +f 2432/2662/1509 2466/2696/1526 2465/2695/1525 +f 2465/2695/1525 2466/2696/1526 2467/2697/1527 +f 2465/2695/1525 2467/2697/1527 2468/2698/1527 +f 1823/2054/979 2465/2695/1525 2468/2698/1527 +f 1823/2054/979 2468/2698/1527 1820/2051/976 +f 2431/2661/1509 2435/2665/1509 2469/2699/1528 +f 2431/2661/1509 2469/2699/1528 2466/2696/1526 +f 2435/2665/1509 1554/1785/724 1552/1783/723 +f 2435/2665/1509 1552/1783/723 2469/2699/1528 +f 2469/2699/1528 1552/1783/723 1551/1782/722 +f 2469/2699/1528 1551/1782/722 2470/2700/1527 +f 2466/2696/1526 2469/2699/1528 2470/2700/1527 +f 2466/2696/1526 2470/2700/1527 2467/2697/1527 +f 1900/2131/1054 2344/2574/1468 2471/2701/1529 +f 1900/2131/1054 2471/2701/1529 1895/2126/1049 +f 2344/2574/1468 2343/2573/1468 2472/2702/1529 +f 2344/2574/1468 2472/2702/1529 2471/2701/1529 +f 2471/2701/1529 2472/2702/1529 2473/2703/1530 +f 2471/2701/1529 2473/2703/1530 2474/2704/1531 +f 1895/2126/1049 2471/2701/1529 2474/2704/1531 +f 1895/2126/1049 2474/2704/1531 1892/2123/1046 +f 2343/2573/1468 2347/2577/1468 2475/2705/1529 +f 2343/2573/1468 2475/2705/1529 2472/2702/1529 +f 2347/2577/1468 1844/2075/999 1842/2073/997 +f 2347/2577/1468 1842/2073/997 2475/2705/1529 +f 2475/2705/1529 1842/2073/997 1752/1983/911 +f 2475/2705/1529 1752/1983/911 2476/2706/1531 +f 2472/2702/1529 2475/2705/1529 2476/2706/1531 +f 2472/2702/1529 2476/2706/1531 2473/2703/1530 +f 1731/1962/890 2477/2707/1532 2478/2708/1533 +f 1731/1962/890 2478/2708/1533 1723/1954/883 +f 2477/2707/1532 2479/2709/1532 2480/2710/1533 +f 2477/2707/1532 2480/2710/1533 2478/2708/1533 +f 2478/2708/1533 2480/2710/1533 2481/2711/1534 +f 2478/2708/1533 2481/2711/1534 2482/2712/1534 +f 1723/1954/883 2478/2708/1533 2482/2712/1534 +f 1723/1954/883 2482/2712/1534 1720/1951/880 +f 2479/2709/1532 2483/2713/1532 2484/2714/1533 +f 2479/2709/1532 2484/2714/1533 2480/2710/1533 +f 2483/2713/1532 1530/1761/702 1528/1759/701 +f 2483/2713/1532 1528/1759/701 2484/2714/1533 +f 2484/2714/1533 1528/1759/701 1527/1758/700 +f 2484/2714/1533 1527/1758/700 2485/2715/1535 +f 2480/2710/1533 2484/2714/1533 2485/2715/1535 +f 2480/2710/1533 2485/2715/1535 2481/2711/1534 +f 2146/2377/1288 2486/2716/1536 2487/2717/1537 +f 2146/2377/1288 2487/2717/1537 2138/2369/1281 +f 2486/2716/1536 2488/2718/1538 2489/2719/1539 +f 2486/2716/1536 2489/2719/1539 2487/2717/1537 +f 2487/2717/1537 2489/2719/1539 2379/2609/1486 +f 2487/2717/1537 2379/2609/1486 2490/2720/1540 +f 2138/2369/1281 2487/2717/1537 2490/2720/1540 +f 2138/2369/1281 2490/2720/1540 2135/2366/1278 +f 2488/2718/1538 2491/2721/1541 2492/2722/1542 +f 2488/2718/1538 2492/2722/1542 2489/2719/1539 +f 2491/2721/1541 1635/1866/801 2271/2501/1406 +f 2491/2721/1541 2271/2501/1406 2492/2722/1542 +f 2492/2722/1542 2271/2501/1406 2031/2262/1180 +f 2492/2722/1542 2031/2262/1180 2380/2610/1487 +f 2489/2719/1539 2492/2722/1542 2380/2610/1487 +f 2489/2719/1539 2380/2610/1487 2379/2609/1486 +f 2154/2385/1295 2493/2723/1543 2494/2724/1544 +f 2154/2385/1295 2494/2724/1544 2148/2379/1290 +f 2493/2723/1543 2495/2725/1543 2496/2726/1544 +f 2493/2723/1543 2496/2726/1544 2494/2724/1544 +f 2494/2724/1544 2496/2726/1544 2497/2727/1545 +f 2494/2724/1544 2497/2727/1545 2498/2728/1546 +f 2148/2379/1290 2494/2724/1544 2498/2728/1546 +f 2148/2379/1290 2498/2728/1546 2114/2345/1258 +f 2495/2725/1543 2499/2729/1547 2500/2730/1544 +f 2495/2725/1543 2500/2730/1544 2496/2726/1544 +f 2499/2729/1547 1952/2183/1104 2043/2274/1192 +f 2499/2729/1547 2043/2274/1192 2500/2730/1544 +f 2500/2730/1544 2043/2274/1192 1696/1927/857 +f 2500/2730/1544 1696/1927/857 2501/2731/1546 +f 2496/2726/1544 2500/2730/1544 2501/2731/1546 +f 2496/2726/1544 2501/2731/1546 2497/2727/1545 +f 2166/2397/1306 2502/2732/1548 2503/2733/1549 +f 2166/2397/1306 2503/2733/1549 2158/2389/1299 +f 2502/2732/1548 2504/2734/1550 2505/2735/1549 +f 2502/2732/1548 2505/2735/1549 2503/2733/1549 +f 2503/2733/1549 2505/2735/1549 2452/2682/1520 +f 2503/2733/1549 2452/2682/1520 2450/2680/1518 +f 2158/2389/1299 2503/2733/1549 2450/2680/1518 +f 2158/2389/1299 2450/2680/1518 2155/2386/1296 +f 2504/2734/1550 2506/2736/1550 2507/2737/1549 +f 2504/2734/1550 2507/2737/1549 2505/2735/1549 +f 2506/2736/1550 1976/2207/1127 2023/2254/1172 +f 2506/2736/1550 2023/2254/1172 2507/2737/1549 +f 2507/2737/1549 2023/2254/1172 1646/1877/811 +f 2507/2737/1549 1646/1877/811 2456/2686/1518 +f 2505/2735/1549 2507/2737/1549 2456/2686/1518 +f 2505/2735/1549 2456/2686/1518 2452/2682/1520 +f 1979/2210/1130 2365/2595/1475 2508/2738/1551 +f 1979/2210/1130 2508/2738/1551 2168/2399/1308 +f 2365/2595/1475 2364/2594/1475 2509/2739/1551 +f 2365/2595/1475 2509/2739/1551 2508/2738/1551 +f 2508/2738/1551 2509/2739/1551 2479/2709/1532 +f 2508/2738/1551 2479/2709/1532 2477/2707/1532 +f 2168/2399/1308 2508/2738/1551 2477/2707/1532 +f 2168/2399/1308 2477/2707/1532 1731/1962/890 +f 2364/2594/1475 2368/2598/1475 2510/2740/1551 +f 2364/2594/1475 2510/2740/1551 2509/2739/1551 +f 2368/2598/1475 1793/2024/950 1969/2200/1121 +f 2368/2598/1475 1969/2200/1121 2510/2740/1551 +f 2510/2740/1551 1969/2200/1121 1530/1761/702 +f 2510/2740/1551 1530/1761/702 2483/2713/1532 +f 2509/2739/1551 2510/2740/1551 2483/2713/1532 +f 2509/2739/1551 2483/2713/1532 2479/2709/1532 +f 1808/2039/964 2511/2741/1552 2512/2742/1553 +f 1808/2039/964 2512/2742/1553 2175/2406/1312 +f 2511/2741/1552 2513/2743/1552 2514/2744/1554 +f 2511/2741/1552 2514/2744/1554 2512/2742/1553 +f 2515/2745/1555 2516/2746/1554 2341/2571/1467 +f 2515/2745/1555 2341/2571/1467 2339/2569/1465 +f 2172/2403/1312 2515/2745/1555 2339/2569/1465 +f 2172/2403/1312 2339/2569/1465 2020/2251/1169 +f 2513/2743/1552 2517/2747/1556 2518/2748/1555 +f 2513/2743/1552 2518/2748/1555 2514/2744/1554 +f 2517/2747/1556 1577/1808/747 2298/2528/1431 +f 2517/2747/1556 2298/2528/1431 2518/2748/1555 +f 2519/2749/1557 2295/2525/1428 2123/2354/1267 +f 2519/2749/1557 2123/2354/1267 2345/2575/1465 +f 2516/2746/1554 2519/2749/1557 2345/2575/1465 +f 2516/2746/1554 2345/2575/1465 2341/2571/1467 +f 1807/2038/963 2520/2750/1558 2521/2751/1559 +f 1807/2038/963 2521/2751/1559 1801/2032/957 +f 2520/2750/1558 2522/2752/1560 2523/2753/1559 +f 2520/2750/1558 2523/2753/1559 2521/2751/1559 +f 2521/2751/1559 2523/2753/1559 2524/2754/1561 +f 2521/2751/1559 2524/2754/1561 2525/2755/1561 +f 1801/2032/957 2521/2751/1559 2525/2755/1561 +f 1801/2032/957 2525/2755/1561 1743/1974/902 +f 2522/2752/1560 2526/2756/1562 2527/2757/1563 +f 2522/2752/1560 2527/2757/1563 2523/2753/1559 +f 2526/2756/1562 1761/1992/919 1774/2005/932 +f 2526/2756/1562 1774/2005/932 2527/2757/1563 +f 2527/2757/1563 1774/2005/932 1518/1749/691 +f 2527/2757/1563 1518/1749/691 2528/2758/1564 +f 2523/2753/1559 2527/2757/1563 2528/2758/1564 +f 2523/2753/1559 2528/2758/1564 2524/2754/1561 +f 1892/2123/1046 2474/2704/1531 2529/2759/1565 +f 1892/2123/1046 2529/2759/1565 2192/2423/1330 +f 2474/2704/1531 2473/2703/1530 2530/2760/1565 +f 2474/2704/1531 2530/2760/1565 2529/2759/1565 +f 2529/2759/1565 2530/2760/1565 2531/2761/1566 +f 2529/2759/1565 2531/2761/1566 2532/2762/1567 +f 2192/2423/1330 2529/2759/1565 2532/2762/1567 +f 2192/2423/1330 2532/2762/1567 2189/2420/1327 +f 2473/2703/1530 2476/2706/1531 2533/2763/1565 +f 2473/2703/1530 2533/2763/1565 2530/2760/1565 +f 2476/2706/1531 1752/1983/911 1750/1981/909 +f 2476/2706/1531 1750/1981/909 2533/2763/1565 +f 2533/2763/1565 1750/1981/909 1749/1980/908 +f 2533/2763/1565 1749/1980/908 2534/2764/1567 +f 2530/2760/1565 2533/2763/1565 2534/2764/1567 +f 2530/2760/1565 2534/2764/1567 2531/2761/1566 +f 2236/2466/1373 2535/2765/1568 2536/2766/1569 +f 2236/2466/1373 2536/2766/1569 2230/2460/1367 +f 2535/2765/1568 2537/2767/1570 2538/2768/1571 +f 2535/2765/1568 2538/2768/1571 2536/2766/1569 +f 2536/2766/1569 2538/2768/1571 2539/2769/1572 +f 2536/2766/1569 2539/2769/1572 2540/2770/1573 +f 2230/2460/1367 2536/2766/1569 2540/2770/1573 +f 2230/2460/1367 2540/2770/1573 2228/2458/1365 +f 2537/2767/1570 2541/2771/1574 2542/2772/1575 +f 2537/2767/1570 2542/2772/1575 2538/2768/1571 +f 2541/2771/1574 1708/1939/869 1706/1937/867 +f 2541/2771/1574 1706/1937/867 2542/2772/1575 +f 2542/2772/1575 1706/1937/867 1705/1936/866 +f 2542/2772/1575 1705/1936/866 2543/2773/1576 +f 2538/2768/1571 2542/2772/1575 2543/2773/1576 +f 2538/2768/1571 2543/2773/1576 2539/2769/1572 +f 2189/2420/1327 2532/2762/1567 2544/2774/1577 +f 2189/2420/1327 2544/2774/1577 2196/2427/1334 +f 2532/2762/1567 2531/2761/1566 2545/2775/1577 +f 2532/2762/1567 2545/2775/1577 2544/2774/1577 +f 2544/2774/1577 2545/2775/1577 2429/2659/1506 +f 2544/2774/1577 2429/2659/1506 2427/2657/1506 +f 2196/2427/1334 2544/2774/1577 2427/2657/1506 +f 2196/2427/1334 2427/2657/1506 2078/2309/1227 +f 2531/2761/1566 2534/2764/1567 2546/2776/1577 +f 2531/2761/1566 2546/2776/1577 2545/2775/1577 +f 2534/2764/1567 1749/1980/908 1770/2001/928 +f 2534/2764/1567 1770/2001/928 2546/2776/1577 +f 2546/2776/1577 1770/2001/928 1769/2000/927 +f 2546/2776/1577 1769/2000/927 2433/2663/1506 +f 2545/2775/1577 2546/2776/1577 2433/2663/1506 +f 2545/2775/1577 2433/2663/1506 2429/2659/1506 +f 2319/2549/1452 2547/2777/1578 2548/2778/1579 +f 2319/2549/1452 2548/2778/1579 2549/2779/1580 +f 2547/2777/1578 2550/2780/1581 2551/2781/1582 +f 2547/2777/1578 2551/2781/1582 2548/2778/1579 +f 2548/2778/1579 2551/2781/1582 2537/2767/1570 +f 2548/2778/1579 2537/2767/1570 2535/2765/1568 +f 2549/2779/1580 2548/2778/1579 2535/2765/1568 +f 2549/2779/1580 2535/2765/1568 2236/2466/1373 +f 2550/2780/1581 2552/2782/1583 2553/2783/1584 +f 2550/2780/1581 2553/2783/1584 2551/2781/1582 +f 2552/2782/1583 1679/1910/842 2251/2481/1387 +f 2552/2782/1583 2251/2481/1387 2553/2783/1584 +f 2553/2783/1584 2251/2481/1387 1708/1939/869 +f 2553/2783/1584 1708/1939/869 2541/2771/1574 +f 2551/2781/1582 2553/2783/1584 2541/2771/1574 +f 2551/2781/1582 2541/2771/1574 2537/2767/1570 +f 2212/2442/1349 2554/2784/1585 2555/2785/1586 +f 2212/2442/1349 2555/2785/1586 2206/2436/1343 +f 2554/2784/1585 2556/2786/1587 2557/2787/1588 +f 2554/2784/1585 2557/2787/1588 2555/2785/1586 +f 2555/2785/1586 2557/2787/1588 2558/2788/1589 +f 2555/2785/1586 2558/2788/1589 2559/2789/1589 +f 2206/2436/1343 2555/2785/1586 2559/2789/1589 +f 2206/2436/1343 2559/2789/1589 1819/2050/975 +f 2556/2786/1587 2560/2790/1585 2561/2791/1586 +f 2556/2786/1587 2561/2791/1586 2557/2787/1588 +f 2560/2790/1585 1627/1858/794 2275/2505/1409 +f 2560/2790/1585 2275/2505/1409 2561/2791/1586 +f 2561/2791/1586 2275/2505/1409 1580/1811/750 +f 2561/2791/1586 1580/1811/750 2562/2792/1589 +f 2557/2787/1588 2561/2791/1586 2562/2792/1589 +f 2557/2787/1588 2562/2792/1589 2558/2788/1589 +f 2001/2232/1150 2335/2565/1464 2563/2793/1590 +f 2001/2232/1150 2563/2793/1590 2240/2470/1377 +f 2335/2565/1464 2334/2564/1464 2564/2794/1590 +f 2335/2565/1464 2564/2794/1590 2563/2793/1590 +f 2563/2793/1590 2564/2794/1590 2565/2795/1591 +f 2563/2793/1590 2565/2795/1591 2566/2796/1592 +f 2240/2470/1377 2563/2793/1590 2566/2796/1592 +f 2240/2470/1377 2566/2796/1592 2237/2467/1374 +f 2334/2564/1464 2338/2568/1464 2567/2797/1590 +f 2334/2564/1464 2567/2797/1590 2564/2794/1590 +f 2338/2568/1464 1670/1901/833 1668/1899/831 +f 2338/2568/1464 1668/1899/831 2567/2797/1590 +f 2567/2797/1590 1668/1899/831 1667/1898/830 +f 2567/2797/1590 1667/1898/830 2568/2798/1592 +f 2564/2794/1590 2567/2797/1590 2568/2798/1592 +f 2564/2794/1590 2568/2798/1592 2565/2795/1591 +f 2228/2458/1365 2540/2770/1573 2569/2799/1593 +f 2228/2458/1365 2569/2799/1593 2222/2452/1359 +f 2540/2770/1573 2539/2769/1572 2570/2800/1593 +f 2540/2770/1573 2570/2800/1593 2569/2799/1593 +f 2569/2799/1593 2570/2800/1593 2522/2752/1560 +f 2569/2799/1593 2522/2752/1560 2520/2750/1558 +f 2222/2452/1359 2569/2799/1593 2520/2750/1558 +f 2222/2452/1359 2520/2750/1558 1807/2038/963 +f 2539/2769/1572 2543/2773/1576 2571/2801/1593 +f 2539/2769/1572 2571/2801/1593 2570/2800/1593 +f 2543/2773/1576 1705/1936/866 1762/1993/920 +f 2543/2773/1576 1762/1993/920 2571/2801/1593 +f 2571/2801/1593 1762/1993/920 1761/1992/919 +f 2571/2801/1593 1761/1992/919 2526/2756/1562 +f 2570/2800/1593 2571/2801/1593 2526/2756/1562 +f 2570/2800/1593 2526/2756/1562 2522/2752/1560 +f 2114/2345/1258 2498/2728/1546 2572/2802/1594 +f 2114/2345/1258 2572/2802/1594 2111/2342/1252 +f 2498/2728/1546 2497/2727/1545 2573/2803/1594 +f 2498/2728/1546 2573/2803/1594 2572/2802/1594 +f 2574/2804/1594 2575/2805/1594 2576/2806/1595 +f 2574/2804/1594 2576/2806/1595 2577/2807/1595 +f 2106/2337/1252 2574/2804/1594 2577/2807/1595 +f 2106/2337/1252 2577/2807/1595 1946/2177/1098 +f 2497/2727/1545 2501/2731/1546 2578/2808/1594 +f 2497/2727/1545 2578/2808/1594 2573/2803/1594 +f 2501/2731/1546 1696/1927/857 1695/1926/856 +f 2501/2731/1546 1695/1926/856 2578/2808/1594 +f 2579/2809/1594 1692/1923/855 1658/1889/821 +f 2579/2809/1594 1658/1889/821 2580/2810/1595 +f 2575/2805/1594 2579/2809/1594 2580/2810/1595 +f 2575/2805/1594 2580/2810/1595 2576/2806/1595 +f 1946/2177/1098 2577/2807/1595 2581/2811/1596 +f 1946/2177/1098 2581/2811/1596 1938/2169/1090 +f 2577/2807/1595 2576/2806/1595 2582/2812/1596 +f 2577/2807/1595 2582/2812/1596 2581/2811/1596 +f 2581/2811/1596 2582/2812/1596 2583/2813/1597 +f 2581/2811/1596 2583/2813/1597 2584/2814/1597 +f 1938/2169/1090 2581/2811/1596 2584/2814/1597 +f 1938/2169/1090 2584/2814/1597 1935/2166/1087 +f 2576/2806/1595 2580/2810/1595 2585/2815/1596 +f 2576/2806/1595 2585/2815/1596 2582/2812/1596 +f 2580/2810/1595 1658/1889/821 1656/1887/820 +f 2580/2810/1595 1656/1887/820 2585/2815/1596 +f 2585/2815/1596 1656/1887/820 1655/1886/819 +f 2585/2815/1596 1655/1886/819 2586/2816/1597 +f 2582/2812/1596 2585/2815/1596 2586/2816/1597 +f 2582/2812/1596 2586/2816/1597 2583/2813/1597 +f 1787/2018/944 2587/2817/1598 2588/2818/1599 +f 1787/2018/944 2588/2818/1599 1779/2010/937 +f 2587/2817/1598 2589/2819/1600 2590/2820/1599 +f 2587/2817/1598 2590/2820/1599 2588/2818/1599 +f 2588/2818/1599 2590/2820/1599 2591/2821/1601 +f 2588/2818/1599 2591/2821/1601 2592/2822/1601 +f 1779/2010/937 2588/2818/1599 2592/2822/1601 +f 1779/2010/937 2592/2822/1601 1776/2007/934 +f 2589/2819/1600 2593/2823/1600 2594/2824/1599 +f 2589/2819/1600 2594/2824/1599 2590/2820/1599 +f 2593/2823/1600 1592/1823/762 1590/1821/760 +f 2593/2823/1600 1590/1821/760 2594/2824/1599 +f 2594/2824/1599 1590/1821/760 1589/1820/759 +f 2594/2824/1599 1589/1820/759 2595/2825/1601 +f 2590/2820/1599 2594/2824/1599 2595/2825/1601 +f 2590/2820/1599 2595/2825/1601 2591/2821/1601 +f 2213/2443/1350 2462/2692/1524 2596/2826/1602 +f 2213/2443/1350 2596/2826/1602 2597/2827/1603 +f 2462/2692/1524 2461/2691/1524 2598/2828/1602 +f 2462/2692/1524 2598/2828/1602 2596/2826/1602 +f 2599/2829/1602 2600/2830/1602 2601/2831/1604 +f 2599/2829/1602 2601/2831/1604 2602/2832/1604 +f 2603/2833/1605 2599/2829/1602 2602/2832/1604 +f 2603/2833/1605 2602/2832/1604 2329/2559/1461 +f 2461/2691/1524 2464/2694/1524 2604/2834/1602 +f 2461/2691/1524 2604/2834/1602 2598/2828/1602 +f 2464/2694/1524 1506/1737/679 1505/1736/678 +f 2464/2694/1524 1505/1736/678 2604/2834/1602 +f 2605/2835/1602 1502/1733/677 1501/1732/676 +f 2605/2835/1602 1501/1732/676 2606/2836/1606 +f 2600/2830/1602 2605/2835/1602 2606/2836/1606 +f 2600/2830/1602 2606/2836/1606 2601/2831/1604 +f 2253/2483/1389 2607/2837/1607 2608/2838/1608 +f 2253/2483/1389 2608/2838/1608 2609/2839/1609 +f 2607/2837/1607 2610/2840/1607 2611/2841/1610 +f 2607/2837/1607 2611/2841/1610 2608/2838/1608 +f 2612/2842/1610 2613/2843/1610 2589/2819/1600 +f 2612/2842/1610 2589/2819/1600 2587/2817/1598 +f 2614/2844/1609 2612/2842/1610 2587/2817/1598 +f 2614/2844/1609 2587/2817/1598 1787/2018/944 +f 2610/2840/1607 2615/2845/1611 2616/2846/1610 +f 2610/2840/1607 2616/2846/1610 2611/2841/1610 +f 2615/2845/1611 1717/1948/877 2617/2847/1612 +f 2615/2845/1611 2617/2847/1612 2616/2846/1610 +f 2618/2848/1610 2619/2849/1612 1592/1823/762 +f 2618/2848/1610 1592/1823/762 2593/2823/1600 +f 2613/2843/1610 2618/2848/1610 2593/2823/1600 +f 2613/2843/1610 2593/2823/1600 2589/2819/1600 +f 1935/2166/1087 2584/2814/1597 2620/2850/1613 +f 1935/2166/1087 2620/2850/1613 2262/2492/1398 +f 2584/2814/1597 2583/2813/1597 2621/2851/1613 +f 2584/2814/1597 2621/2851/1613 2620/2850/1613 +f 2620/2850/1613 2621/2851/1613 2350/2580/1469 +f 2620/2850/1613 2350/2580/1469 2348/2578/1469 +f 2262/2492/1398 2620/2850/1613 2348/2578/1469 +f 2262/2492/1398 2348/2578/1469 1922/2153/1074 +f 2583/2813/1597 2586/2816/1597 2622/2852/1613 +f 2583/2813/1597 2622/2852/1613 2621/2851/1613 +f 2586/2816/1597 1655/1886/819 1688/1919/851 +f 2586/2816/1597 1688/1919/851 2622/2852/1613 +f 2622/2852/1613 1688/1919/851 1618/1849/785 +f 2622/2852/1613 1618/1849/785 2356/2586/1469 +f 2621/2851/1613 2622/2852/1613 2356/2586/1469 +f 2621/2851/1613 2356/2586/1469 2350/2580/1469 +f 2177/2408/1316 2455/2685/1522 2623/2853/1614 +f 2177/2408/1316 2623/2853/1614 2266/2496/1401 +f 2455/2685/1522 2454/2684/1521 2624/2854/1614 +f 2455/2685/1522 2624/2854/1614 2623/2853/1614 +f 2623/2853/1614 2624/2854/1614 2399/2629/1496 +f 2623/2853/1614 2399/2629/1496 2397/2627/1496 +f 2266/2496/1401 2623/2853/1614 2397/2627/1496 +f 2266/2496/1401 2397/2627/1496 2054/2285/1203 +f 2454/2684/1521 2458/2688/1522 2625/2855/1614 +f 2454/2684/1521 2625/2855/1614 2624/2854/1614 +f 2458/2688/1522 1643/1874/808 1870/2101/1025 +f 2458/2688/1522 1870/2101/1025 2625/2855/1614 +f 2625/2855/1614 1870/2101/1025 1869/2100/1024 +f 2625/2855/1614 1869/2100/1024 2403/2633/1496 +f 2624/2854/1614 2625/2855/1614 2403/2633/1496 +f 2624/2854/1614 2403/2633/1496 2399/2629/1496 +f 1607/1838/776 2626/2856/1615 2627/2857/1616 +f 1607/1838/776 2627/2857/1616 1599/1830/769 +f 2626/2856/1615 2628/2858/1615 2629/2859/1617 +f 2626/2856/1615 2629/2859/1617 2627/2857/1616 +f 2627/2857/1616 2629/2859/1617 2630/2860/1618 +f 2627/2857/1616 2630/2860/1618 2631/2861/1619 +f 1599/1830/769 2627/2857/1616 2631/2861/1619 +f 1599/1830/769 2631/2861/1619 1596/1827/766 +f 2628/2858/1615 2632/2862/1615 2633/2863/1617 +f 2628/2858/1615 2633/2863/1617 2629/2859/1617 +f 2632/2862/1615 1542/1773/713 1540/1771/712 +f 2632/2862/1615 1540/1771/712 2633/2863/1617 +f 2633/2863/1617 1540/1771/712 1539/1770/711 +f 2633/2863/1617 1539/1770/711 2634/2864/1619 +f 2629/2859/1617 2633/2863/1617 2634/2864/1619 +f 2629/2859/1617 2634/2864/1619 2630/2860/1618 +f 1743/1974/902 2525/2755/1561 2635/2865/1620 +f 1743/1974/902 2635/2865/1620 1735/1966/894 +f 2525/2755/1561 2524/2754/1561 2636/2866/1620 +f 2525/2755/1561 2636/2866/1620 2635/2865/1620 +f 2635/2865/1620 2636/2866/1620 2637/2867/1621 +f 2635/2865/1620 2637/2867/1621 2638/2868/1621 +f 1735/1966/894 2635/2865/1620 2638/2868/1621 +f 1735/1966/894 2638/2868/1621 1732/1963/891 +f 2524/2754/1561 2528/2758/1564 2639/2869/1622 +f 2524/2754/1561 2639/2869/1622 2636/2866/1620 +f 2528/2758/1564 1518/1749/691 1516/1747/689 +f 2528/2758/1564 1516/1747/689 2639/2869/1622 +f 2639/2869/1622 1516/1747/689 1515/1746/688 +f 2639/2869/1622 1515/1746/688 2640/2870/1623 +f 2636/2866/1620 2639/2869/1622 2640/2870/1623 +f 2636/2866/1620 2640/2870/1623 2637/2867/1621 +f 1909/2140/1062 2355/2585/1471 2641/2871/1624 +f 1909/2140/1062 2641/2871/1624 2278/2508/1412 +f 2355/2585/1471 2354/2584/1471 2642/2872/1624 +f 2355/2585/1471 2642/2872/1624 2641/2871/1624 +f 2641/2871/1624 2642/2872/1624 2504/2734/1550 +f 2641/2871/1624 2504/2734/1550 2502/2732/1548 +f 2278/2508/1412 2641/2871/1624 2502/2732/1548 +f 2278/2508/1412 2502/2732/1548 2166/2397/1306 +f 2354/2584/1471 2359/2589/1471 2643/2873/1624 +f 2354/2584/1471 2643/2873/1624 2642/2872/1624 +f 2359/2589/1471 1613/1844/782 1977/2208/1128 +f 2359/2589/1471 1977/2208/1128 2643/2873/1624 +f 2643/2873/1624 1977/2208/1128 1976/2207/1127 +f 2643/2873/1624 1976/2207/1127 2506/2736/1550 +f 2642/2872/1624 2643/2873/1624 2506/2736/1550 +f 2642/2872/1624 2506/2736/1550 2504/2734/1550 +f 2288/2518/1422 2644/2874/1625 2645/2875/1626 +f 2288/2518/1422 2645/2875/1626 2282/2512/1416 +f 2644/2874/1625 2646/2876/1625 2647/2877/1626 +f 2644/2874/1625 2647/2877/1626 2645/2875/1626 +f 2645/2875/1626 2647/2877/1626 2414/2644/1501 +f 2645/2875/1626 2414/2644/1501 2412/2642/1501 +f 2282/2512/1416 2645/2875/1626 2412/2642/1501 +f 2282/2512/1416 2412/2642/1501 2070/2301/1219 +f 2646/2876/1625 2648/2878/1625 2649/2879/1626 +f 2646/2876/1625 2649/2879/1626 2647/2877/1626 +f 2648/2878/1625 1837/2068/992 2133/2364/1276 +f 2648/2878/1625 2133/2364/1276 2649/2879/1626 +f 2649/2879/1626 2133/2364/1276 2132/2363/1275 +f 2649/2879/1626 2132/2363/1275 2418/2648/1501 +f 2647/2877/1626 2649/2879/1626 2418/2648/1501 +f 2647/2877/1626 2418/2648/1501 2414/2644/1501 +f 1776/2007/934 2592/2822/1601 2650/2880/1627 +f 1776/2007/934 2650/2880/1627 2290/2520/1424 +f 2592/2822/1601 2591/2821/1601 2651/2881/1628 +f 2592/2822/1601 2651/2881/1628 2650/2880/1627 +f 2650/2880/1627 2651/2881/1628 2628/2858/1615 +f 2650/2880/1627 2628/2858/1615 2626/2856/1615 +f 2290/2520/1424 2650/2880/1627 2626/2856/1615 +f 2290/2520/1424 2626/2856/1615 1607/1838/776 +f 2591/2821/1601 2595/2825/1601 2652/2882/1628 +f 2591/2821/1601 2652/2882/1628 2651/2881/1628 +f 2595/2825/1601 1589/1820/759 1684/1915/847 +f 2595/2825/1601 1684/1915/847 2652/2882/1628 +f 2652/2882/1628 1684/1915/847 1542/1773/713 +f 2652/2882/1628 1542/1773/713 2632/2862/1615 +f 2651/2881/1628 2652/2882/1628 2632/2862/1615 +f 2651/2881/1628 2632/2862/1615 2628/2858/1615 +f 1819/2050/975 2559/2789/1589 2653/2883/1629 +f 1819/2050/975 2653/2883/1629 1811/2042/967 +f 2559/2789/1589 2558/2788/1589 2654/2884/1629 +f 2559/2789/1589 2654/2884/1629 2653/2883/1629 +f 2653/2883/1629 2654/2884/1629 2513/2743/1552 +f 2653/2883/1629 2513/2743/1552 2511/2741/1552 +f 1811/2042/967 2653/2883/1629 2511/2741/1552 +f 1811/2042/967 2511/2741/1552 1808/2039/964 +f 2558/2788/1589 2562/2792/1589 2655/2885/1629 +f 2558/2788/1589 2655/2885/1629 2654/2884/1629 +f 2562/2792/1589 1580/1811/750 1578/1809/748 +f 2562/2792/1589 1578/1809/748 2655/2885/1629 +f 2655/2885/1629 1578/1809/748 1577/1808/747 +f 2655/2885/1629 1577/1808/747 2517/2747/1556 +f 2654/2884/1629 2655/2885/1629 2517/2747/1556 +f 2654/2884/1629 2517/2747/1556 2513/2743/1552 +f 1987/2218/1138 2392/2622/1495 2656/2886/1630 +f 1987/2218/1138 2656/2886/1630 2300/2530/1433 +f 2392/2622/1495 2391/2621/1495 2657/2887/1630 +f 2392/2622/1495 2657/2887/1630 2656/2886/1630 +f 2656/2886/1630 2657/2887/1630 2495/2725/1543 +f 2656/2886/1630 2495/2725/1543 2493/2723/1543 +f 2300/2530/1433 2656/2886/1630 2493/2723/1543 +f 2300/2530/1433 2493/2723/1543 2154/2385/1295 +f 2391/2621/1495 2396/2626/1495 2658/2888/1630 +f 2391/2621/1495 2658/2888/1630 2657/2887/1630 +f 2396/2626/1495 1563/1794/733 1953/2184/1105 +f 2396/2626/1495 1953/2184/1105 2658/2888/1630 +f 2658/2888/1630 1953/2184/1105 1952/2183/1104 +f 2658/2888/1630 1952/2183/1104 2499/2729/1547 +f 2657/2887/1630 2658/2888/1630 2499/2729/1547 +f 2657/2887/1630 2499/2729/1547 2495/2725/1543 +f 1820/2051/976 2468/2698/1527 2659/2889/1631 +f 1820/2051/976 2659/2889/1631 2304/2534/1437 +f 2468/2698/1527 2467/2697/1527 2660/2890/1631 +f 2468/2698/1527 2660/2890/1631 2659/2889/1631 +f 2659/2889/1631 2660/2890/1631 2332/2562/1462 +f 2659/2889/1631 2332/2562/1462 2330/2560/1462 +f 2304/2534/1437 2659/2889/1631 2330/2560/1462 +f 2304/2534/1437 2330/2560/1462 2012/2243/1161 +f 2467/2697/1527 2470/2700/1527 2661/2891/1631 +f 2467/2697/1527 2661/2891/1631 2660/2890/1631 +f 2470/2700/1527 1551/1782/722 1854/2085/1009 +f 2470/2700/1527 1854/2085/1009 2661/2891/1631 +f 2661/2891/1631 1854/2085/1009 1853/2084/1008 +f 2661/2891/1631 1853/2084/1008 2336/2566/1462 +f 2660/2890/1631 2661/2891/1631 2336/2566/1462 +f 2660/2890/1631 2336/2566/1462 2332/2562/1462 +f 1596/1827/766 2631/2861/1619 2662/2892/1632 +f 1596/1827/766 2662/2892/1632 2308/2538/1441 +f 2631/2861/1619 2630/2860/1618 2663/2893/1633 +f 2631/2861/1619 2663/2893/1633 2662/2892/1632 +f 2662/2892/1632 2663/2893/1633 2488/2718/1538 +f 2662/2892/1632 2488/2718/1538 2486/2716/1536 +f 2308/2538/1441 2662/2892/1632 2486/2716/1536 +f 2308/2538/1441 2486/2716/1536 2146/2377/1288 +f 2630/2860/1618 2634/2864/1619 2664/2894/1632 +f 2630/2860/1618 2664/2894/1632 2663/2893/1633 +f 2634/2864/1619 1539/1770/711 1636/1867/802 +f 2634/2864/1619 1636/1867/802 2664/2894/1632 +f 2664/2894/1632 1636/1867/802 1635/1866/801 +f 2664/2894/1632 1635/1866/801 2491/2721/1541 +f 2663/2893/1633 2664/2894/1632 2491/2721/1541 +f 2663/2893/1633 2491/2721/1541 2488/2718/1538 +f 1720/1951/880 2482/2712/1534 2665/2895/1634 +f 1720/1951/880 2665/2895/1634 2312/2542/1445 +f 2482/2712/1534 2481/2711/1534 2666/2896/1634 +f 2482/2712/1534 2666/2896/1634 2665/2895/1634 +f 2665/2895/1634 2666/2896/1634 2646/2876/1625 +f 2665/2895/1634 2646/2876/1625 2644/2874/1625 +f 2312/2542/1445 2665/2895/1634 2644/2874/1625 +f 2312/2542/1445 2644/2874/1625 2288/2518/1422 +f 2481/2711/1534 2485/2715/1535 2667/2897/1634 +f 2481/2711/1534 2667/2897/1634 2666/2896/1634 +f 2485/2715/1535 1527/1758/700 1838/2069/993 +f 2485/2715/1535 1838/2069/993 2667/2897/1634 +f 2667/2897/1634 1838/2069/993 1837/2068/992 +f 2667/2897/1634 1837/2068/992 2648/2878/1625 +f 2666/2896/1634 2667/2897/1634 2648/2878/1625 +f 2666/2896/1634 2648/2878/1625 2646/2876/1625 +f 1732/1963/891 2638/2868/1621 2668/2898/1635 +f 1732/1963/891 2668/2898/1635 2316/2546/1449 +f 2638/2868/1621 2637/2867/1621 2669/2899/1635 +f 2638/2868/1621 2669/2899/1635 2668/2898/1635 +f 2668/2898/1635 2669/2899/1635 2556/2786/1587 +f 2668/2898/1635 2556/2786/1587 2554/2784/1585 +f 2316/2546/1449 2668/2898/1635 2554/2784/1585 +f 2316/2546/1449 2554/2784/1585 2212/2442/1349 +f 2637/2867/1621 2640/2870/1623 2670/2900/1635 +f 2637/2867/1621 2670/2900/1635 2669/2899/1635 +f 2640/2870/1623 1515/1746/688 1628/1859/795 +f 2640/2870/1623 1628/1859/795 2670/2900/1635 +f 2670/2900/1635 1628/1859/795 1627/1858/794 +f 2670/2900/1635 1627/1858/794 2560/2790/1585 +f 2669/2899/1635 2670/2900/1635 2560/2790/1585 +f 2669/2899/1635 2560/2790/1585 2556/2786/1587 +f 2329/2559/1461 2602/2832/1604 2671/2901/1636 +f 2329/2559/1461 2671/2901/1636 2322/2552/1455 +f 2602/2832/1604 2601/2831/1604 2672/2902/1637 +f 2602/2832/1604 2672/2902/1637 2671/2901/1636 +f 2671/2901/1636 2672/2902/1637 2550/2780/1581 +f 2671/2901/1636 2550/2780/1581 2547/2777/1578 +f 2322/2552/1455 2671/2901/1636 2547/2777/1578 +f 2322/2552/1455 2547/2777/1578 2319/2549/1452 +f 2601/2831/1604 2606/2836/1606 2673/2903/1638 +f 2601/2831/1604 2673/2903/1638 2672/2902/1637 +f 2606/2836/1606 1501/1732/676 1680/1911/843 +f 2606/2836/1606 1680/1911/843 2673/2903/1638 +f 2673/2903/1638 1680/1911/843 1679/1910/842 +f 2673/2903/1638 1679/1910/842 2552/2782/1583 +f 2672/2902/1637 2673/2903/1638 2552/2782/1583 +f 2672/2902/1637 2552/2782/1583 2550/2780/1581 +f 2329/2559/1461 2328/2558/1460 2674/2904/1639 +f 2329/2559/1461 2674/2904/1639 2603/2833/1605 +f 2327/2557/1459 2326/2556/1458 2675/2905/1640 +f 2327/2557/1459 2675/2905/1640 2676/2906/1641 +f 2676/2906/1641 2675/2905/1640 2218/2448/1355 +f 2676/2906/1641 2218/2448/1355 2217/2447/1354 +f 2597/2827/1603 2677/2907/1642 2214/2444/1351 +f 2597/2827/1603 2214/2444/1351 2213/2443/1350 +f 789/738/571 2678/2908/1643 2679/2909/1644 +f 789/738/571 2679/2909/1644 785/737/570 +f 2678/2908/1643 1848/2079/1003 1851/2082/1006 +f 2678/2908/1643 1851/2082/1006 2679/2909/1644 +f 2679/2909/1644 1851/2082/1006 1546/1777/717 +f 2679/2909/1644 1546/1777/717 2680/2910/1645 +f 785/737/570 2679/2909/1644 2680/2910/1645 +f 785/737/570 2680/2910/1645 504/732/528 +f 445/1643/520 2684/2911/1646 2685/2912/1647 +f 445/1643/520 2685/2912/1647 782/1675/568 +f 2684/2911/1646 1584/1815/754 1587/1818/757 +f 2684/2911/1646 1587/1818/757 2685/2912/1647 +f 2685/2912/1647 1587/1818/757 1595/1826/765 +f 2685/2912/1647 1595/1826/765 2686/2913/1648 +f 782/1675/568 2685/2912/1647 2686/2913/1648 +f 782/1675/568 2686/2913/1648 783/1676/569 +f 777/1623/507 2687/2914/1649 2688/2915/1650 +f 777/1623/507 2688/2915/1650 772/728/567 +f 2687/2914/1649 1662/1893/825 1665/1896/828 +f 2687/2914/1649 1665/1896/828 2688/2915/1650 +f 2688/2915/1650 1665/1896/828 1673/1904/836 +f 2688/2915/1650 1673/1904/836 2689/2916/1651 +f 772/728/567 2688/2915/1650 2689/2916/1651 +f 772/728/567 2689/2916/1651 769/721/361 +f 466/1646/526 2690/2917/1652 2691/2918/1653 +f 466/1646/526 2691/2918/1653 739/1670/564 +f 2690/2917/1652 2034/2265/1183 2270/2500/1405 +f 2690/2917/1652 2270/2500/1405 2691/2918/1653 +f 2691/2918/1653 2270/2500/1405 1630/1861/797 +f 2691/2918/1653 1630/1861/797 2692/2919/1654 +f 739/1670/564 2691/2918/1653 2692/2919/1654 +f 739/1670/564 2692/2919/1654 374/1638/512 +f 769/721/361 2689/2916/1651 2693/2920/1655 +f 769/721/361 2693/2920/1655 791/741/572 +f 2689/2916/1651 1673/1904/836 2116/2347/1260 +f 2689/2916/1651 2116/2347/1260 2693/2920/1655 +f 2693/2920/1655 2116/2347/1260 1848/2079/1003 +f 2693/2920/1655 1848/2079/1003 2678/2908/1643 +f 791/741/572 2693/2920/1655 2678/2908/1643 +f 791/741/572 2678/2908/1643 789/738/571 +f 376/1640/514 2696/2921/1656 2697/2922/1657 +f 376/1640/514 2697/2922/1657 761/1672/565 +f 2696/2921/1656 1534/1765/706 1537/1768/709 +f 2696/2921/1656 1537/1768/709 2697/2922/1657 +f 2697/2922/1657 1537/1768/709 1545/1776/716 +f 2697/2922/1657 1545/1776/716 2698/2923/1658 +f 761/1672/565 2697/2922/1657 2698/2923/1658 +f 761/1672/565 2698/2923/1658 443/1641/518 +f 778/729/507 2699/2924/1659 2700/2925/1660 +f 778/729/507 2700/2925/1660 2701/1626/363 +f 2699/2924/1659 1712/1943/872 1715/1946/875 +f 2699/2924/1659 1715/1946/875 2700/2925/1660 +f 2700/2925/1660 1715/1946/875 1662/1893/825 +f 2700/2925/1660 1662/1893/825 2687/2914/1649 +f 2701/1626/363 2700/2925/1660 2687/2914/1649 +f 2701/1626/363 2687/2914/1649 777/1623/507 +f 399/405/515 2702/1402/1661 2703/2926/1662 +f 399/405/515 2703/2926/1662 400/395/516 +f 2702/1402/1661 1558/1789/728 1561/1792/731 +f 2702/1402/1661 1561/1792/731 2703/2926/1662 +f 2703/2926/1662 1561/1792/731 1571/1802/741 +f 2703/2926/1662 1571/1802/741 2704/2927/1663 +f 400/395/516 2703/2926/1662 2704/2927/1663 +f 400/395/516 2704/2927/1663 401/396/517 +f 414/410/445 2705/1419/1664 2706/1401/1665 +f 2705/1419/1664 1947/2178/1099 1950/2181/1102 +f 2705/1419/1664 1950/2181/1102 2706/1401/1665 +f 2706/1401/1665 1950/2181/1102 1558/1789/728 +f 2706/1401/1665 1558/1789/728 2702/1402/1661 +f 415/411/1666 2706/1401/1665 2702/1402/1661 +f 462/1635/521 2713/2928/1667 2714/2929/1668 +f 462/1635/521 2714/2929/1668 463/455/522 +f 2713/2928/1667 1872/2103/1026 1875/2106/1029 +f 2713/2928/1667 1875/2106/1029 2714/2929/1668 +f 2714/2929/1668 1875/2106/1029 1883/2114/1037 +f 2714/2929/1668 1883/2114/1037 2715/2930/1669 +f 463/455/522 2714/2929/1668 2715/2930/1669 +f 463/455/522 2715/2930/1669 464/1644/523 +f 401/396/517 2704/2927/1663 2716/2931/1670 +f 401/396/517 2716/2931/1670 469/458/527 +f 2704/2927/1663 1571/1802/741 2092/2323/1241 +f 2704/2927/1663 2092/2323/1241 2716/2931/1670 +f 2716/2931/1670 2092/2323/1241 2098/2329/1246 +f 2716/2931/1670 2098/2329/1246 2717/2932/1671 +f 469/458/527 2716/2931/1670 2717/2932/1671 +f 469/458/527 2717/2932/1671 470/459/345 +f 504/732/528 2680/2910/1645 2723/2933/1672 +f 504/732/528 2723/2933/1672 505/493/346 +f 2680/2910/1645 1546/1777/717 1549/1780/720 +f 2680/2910/1645 1549/1780/720 2723/2933/1672 +f 2723/2933/1672 1549/1780/720 1557/1788/727 +f 2723/2933/1672 1557/1788/727 2724/2934/1673 +f 505/493/346 2723/2933/1672 2724/2934/1673 +f 505/493/346 2724/2934/1673 363/494/336 +f 363/494/336 2724/2934/1673 2725/2935/1674 +f 363/494/336 2725/2935/1674 364/363/510 +f 2724/2934/1673 1557/1788/727 2186/2417/1324 +f 2724/2934/1673 2186/2417/1324 2725/2935/1674 +f 2725/2935/1674 2186/2417/1324 1764/1995/922 +f 2725/2935/1674 1764/1995/922 2726/2936/1675 +f 364/363/510 2725/2935/1674 2726/2936/1675 +f 364/363/510 2726/2936/1675 365/364/511 +f 538/1653/537 2727/2937/1676 2728/2938/1677 +f 538/1653/537 2728/2938/1677 764/1673/566 +f 2727/2937/1676 1847/2078/1002 2120/2351/1264 +f 2727/2937/1676 2120/2351/1264 2728/2938/1677 +f 2728/2938/1677 2120/2351/1264 2126/2357/1270 +f 2728/2938/1677 2126/2357/1270 2729/2939/1678 +f 764/1673/566 2728/2938/1677 2729/2939/1678 +f 764/1673/566 2729/2939/1678 527/1650/531 +f 520/1649/530 2730/2940/1679 2731/2941/1680 +f 520/1649/530 2731/2941/1680 725/1669/538 +f 2730/2940/1679 1622/1853/789 1625/1856/792 +f 2730/2940/1679 1625/1856/792 2731/2941/1680 +f 2731/2941/1680 1625/1856/792 1510/1741/683 +f 2731/2941/1680 1510/1741/683 2732/2942/1681 +f 725/1669/538 2731/2941/1680 2732/2942/1681 +f 725/1669/538 2732/2942/1681 545/1654/538 +f 529/1437/532 2733/1436/1682 2734/2943/1683 +f 529/1437/532 2734/2943/1683 748/1671/529 +f 2733/1436/1682 1572/1803/742 1575/1806/745 +f 2733/1436/1682 1575/1806/745 2734/2943/1683 +f 2734/2943/1683 1575/1806/745 1583/1814/753 +f 2734/2943/1683 1583/1814/753 2735/2944/1684 +f 748/1671/529 2734/2943/1683 2735/2944/1684 +f 748/1671/529 2735/2944/1684 518/1647/529 +f 545/1654/538 2732/2942/1681 2736/2945/1685 +f 545/1654/538 2736/2945/1685 546/1655/539 +f 2732/2942/1681 1510/1741/683 1513/1744/686 +f 2732/2942/1681 1513/1744/686 2736/2945/1685 +f 2736/2945/1685 1513/1744/686 1521/1752/694 +f 2736/2945/1685 1521/1752/694 2737/2946/1686 +f 546/1655/539 2736/2945/1685 2737/2946/1686 +f 546/1655/539 2737/2946/1686 547/1656/454 +f 534/789/533 2738/2947/1687 2739/2948/1688 +f 534/789/533 2739/2948/1688 535/517/534 +f 2738/2947/1687 1744/1975/903 1747/1978/906 +f 2738/2947/1687 1747/1978/906 2739/2948/1688 +f 2739/2948/1688 1747/1978/906 1755/1986/913 +f 2739/2948/1688 1755/1986/913 2740/2949/1689 +f 535/517/534 2739/2948/1688 2740/2949/1689 +f 535/517/534 2740/2949/1689 536/1651/535 +f 683/847/382 2741/2950/1690 2742/2951/1691 +f 683/847/382 2742/2951/1691 895/848/1692 +f 2741/2950/1690 1522/1753/695 1525/1756/698 +f 2741/2950/1690 1525/1756/698 2742/2951/1691 +f 2742/2951/1691 1525/1756/698 1533/1764/705 +f 2742/2951/1691 1533/1764/705 2743/2952/1693 +f 895/848/1692 2742/2951/1691 2743/2952/1693 +f 895/848/1692 2743/2952/1693 897/850/384 +f 893/1678/576 2746/2953/1694 2747/2954/1695 +f 893/1678/576 2747/2954/1695 894/845/577 +f 2746/2953/1694 1908/2139/1061 2100/2331/1248 +f 2746/2953/1694 2100/2331/1248 2747/2954/1695 +f 2747/2954/1695 2100/2331/1248 1864/2095/1019 +f 2747/2954/1695 1864/2095/1019 2748/2955/1696 +f 894/845/577 2747/2954/1695 2748/2955/1696 +f 894/845/577 2748/2955/1696 624/846/546 +f 883/835/374 2749/2956/1697 2750/2957/1698 +f 883/835/374 2750/2957/1698 884/836/1699 +f 2749/2956/1697 1788/2019/945 1791/2022/948 +f 2749/2956/1697 1791/2022/948 2750/2957/1698 +f 2750/2957/1698 1791/2022/948 1799/2030/955 +f 2750/2957/1698 1799/2030/955 2751/2958/1700 +f 884/836/1699 2750/2957/1698 2751/2958/1700 +f 884/836/1699 2751/2958/1700 887/839/1701 +f 563/535/387 2752/2959/1702 2753/2960/1703 +f 563/535/387 2753/2960/1703 863/813/379 +f 2752/2959/1702 1971/2202/1123 1974/2205/1126 +f 2752/2959/1702 1974/2205/1126 2753/2960/1703 +f 2753/2960/1703 1974/2205/1126 1608/1839/777 +f 2753/2960/1703 1608/1839/777 2754/2961/1704 +f 863/813/379 2753/2960/1703 2754/2961/1704 +f 863/813/379 2754/2961/1704 645/814/549 +f 897/850/384 2743/2952/1693 2755/2962/1705 +f 897/850/384 2755/2962/1705 901/854/385 +f 2743/2952/1693 1533/1764/705 1968/2199/1120 +f 2743/2952/1693 1968/2199/1120 2755/2962/1705 +f 2755/2962/1705 1968/2199/1120 1788/2019/945 +f 2755/2962/1705 1788/2019/945 2749/2956/1697 +f 901/854/385 2755/2962/1705 2749/2956/1697 +f 901/854/385 2749/2956/1697 883/835/374 +f 626/596/548 2758/2963/1706 2759/2964/1707 +f 626/596/548 2759/2964/1707 923/877/579 +f 2758/2963/1706 1638/1869/803 1641/1872/806 +f 2758/2963/1706 1641/1872/806 2759/2964/1707 +f 2759/2964/1707 1641/1872/806 1649/1880/814 +f 2759/2964/1707 1649/1880/814 2760/2965/1708 +f 923/877/579 2759/2964/1707 2760/2965/1708 +f 923/877/579 2760/2965/1708 561/878/542 +f 887/839/1701 2751/2958/1700 2761/2966/1709 +f 887/839/1701 2761/2966/1709 891/843/345 +f 2751/2958/1700 1799/2030/955 1902/2133/1056 +f 2751/2958/1700 1902/2133/1056 2761/2966/1709 +f 2761/2966/1709 1902/2133/1056 1908/2139/1061 +f 2761/2966/1709 1908/2139/1061 2746/2953/1694 +f 891/843/345 2761/2966/1709 2746/2953/1694 +f 891/843/345 2746/2953/1694 893/1678/576 +f 587/1660/544 2762/2967/1710 2763/2968/1711 +f 587/1660/544 2763/2968/1711 588/559/545 +f 2762/2967/1710 1661/1892/824 1691/1922/854 +f 2762/2967/1710 1691/1922/854 2763/2968/1711 +f 2763/2968/1711 1691/1922/854 1699/1930/860 +f 2763/2968/1711 1699/1930/860 2764/2969/1712 +f 588/559/545 2763/2968/1711 2764/2969/1712 +f 588/559/545 2764/2969/1712 589/560/449 +f 589/560/449 2764/2969/1712 2765/1418/1713 +f 2764/2969/1712 1699/1930/860 2042/2273/1191 +f 2764/2969/1712 2042/2273/1191 2765/1418/1713 +f 2765/1418/1713 2042/2273/1191 1947/2178/1099 +f 2765/1418/1713 1947/2178/1099 2705/1419/1664 +f 598/569/452 2765/1418/1713 2705/1419/1664 +f 647/1661/551 2769/2970/1714 2770/2971/1715 +f 647/1661/551 2770/2971/1715 648/1662/552 +f 2769/2970/1714 1621/1852/788 1687/1918/850 +f 2769/2970/1714 1687/1918/850 2770/2971/1715 +f 2770/2971/1715 1687/1918/850 1650/1881/815 +f 2770/2971/1715 1650/1881/815 2771/2972/1716 +f 648/1662/552 2770/2971/1715 2771/2972/1716 +f 648/1662/552 2771/2972/1716 649/1663/552 +f 649/1663/552 2771/2972/1716 2772/2973/1717 +f 649/1663/552 2772/2973/1717 652/1664/553 +f 2771/2972/1716 1650/1881/815 1653/1884/818 +f 2771/2972/1716 1653/1884/818 2772/2973/1717 +f 2772/2973/1717 1653/1884/818 1661/1892/824 +f 2772/2973/1717 1661/1892/824 2762/2967/1710 +f 652/1664/553 2772/2973/1717 2762/2967/1710 +f 652/1664/553 2762/2967/1710 587/1660/544 +f 556/1659/541 2776/2974/1718 2777/2975/1719 +f 556/1659/541 2777/2975/1719 682/1665/339 +f 2776/2974/1718 1832/2063/988 1835/2066/991 +f 2776/2974/1718 1835/2066/991 2777/2975/1719 +f 2777/2975/1719 1835/2066/991 1522/1753/695 +f 2777/2975/1719 1522/1753/695 2741/2950/1690 +f 682/1665/339 2777/2975/1719 2741/2950/1690 +f 682/1665/339 2741/2950/1690 683/847/382 +f 554/1657/540 2778/2976/1720 2779/2977/1721 +f 554/1657/540 2779/2977/1721 555/1658/541 +f 2778/2976/1720 2127/2358/1271 2130/2361/1274 +f 2778/2976/1720 2130/2361/1274 2779/2977/1721 +f 2779/2977/1721 2130/2361/1274 1832/2063/988 +f 2779/2977/1721 1832/2063/988 2776/2974/1718 +f 555/1658/541 2779/2977/1721 2776/2974/1718 +f 555/1658/541 2776/2974/1718 556/1659/541 +f 705/666/558 2780/2978/1722 2781/2979/1723 +f 705/666/558 2781/2979/1723 878/829/575 +f 2780/2978/1722 1496/1727/672 1499/1730/675 +f 2780/2978/1722 1499/1730/675 2781/2979/1723 +f 2781/2979/1723 1499/1730/675 1509/1740/682 +f 2781/2979/1723 1509/1740/682 2782/2980/1724 +f 878/829/575 2781/2979/1723 2782/2980/1724 +f 878/829/575 2782/2980/1724 712/830/559 +f 720/677/360 2783/2981/1725 2784/1426/455 +f 2783/2981/1725 1756/1987/914 1759/1990/917 +f 2783/2981/1725 1759/1990/917 2784/1426/455 +f 2784/1426/455 1759/1990/917 1700/1931/861 +f 2784/1426/455 1700/1931/861 2785/2982/1726 +f 850/799/574 2784/1426/455 2785/2982/1726 +f 850/799/574 2785/2982/1726 694/800/554 +f 696/658/1727 2786/1473/462 2787/1427/456 +f 2786/1473/462 1711/1942/871 2250/2480/1386 +f 2786/1473/462 2250/2480/1386 2787/1427/456 +f 2787/1427/456 2250/2480/1386 1674/1905/837 +f 2787/1427/456 1674/1905/837 2788/2983/1728 +f 911/864/578 2787/1427/456 2788/2983/1728 +f 911/864/578 2788/2983/1728 703/865/556 +f 547/1656/454 2737/2946/1686 2789/2984/1729 +f 547/1656/454 2789/2984/1729 719/676/563 +f 2737/2946/1686 1521/1752/694 1773/2004/931 +f 2737/2946/1686 1773/2004/931 2789/2984/1729 +f 2789/2984/1729 1773/2004/931 1756/1987/914 +f 2789/2984/1729 1756/1987/914 2783/2981/1725 +f 719/676/563 2789/2984/1729 2783/2981/1725 +f 719/676/563 2783/2981/1725 720/677/360 +f 714/1666/560 2790/2985/1730 2791/2986/1731 +f 714/1666/560 2791/2986/1731 715/1667/561 +f 2790/2985/1730 1863/2094/1018 1885/2116/1039 +f 2790/2985/1730 1885/2116/1039 2791/2986/1731 +f 2791/2986/1731 1885/2116/1039 1891/2122/1045 +f 2791/2986/1731 1891/2122/1045 2792/2987/1732 +f 715/1667/561 2791/2986/1731 2792/2987/1732 +f 715/1667/561 2792/2987/1732 716/1668/562 +f 464/1644/523 2715/2930/1669 2793/2988/1733 +f 464/1644/523 2793/2988/1733 465/1645/524 +f 2715/2930/1669 1883/2114/1037 2026/2257/1175 +f 2715/2930/1669 2026/2257/1175 2793/2988/1733 +f 2793/2988/1733 2026/2257/1175 2034/2265/1183 +f 2793/2988/1733 2034/2265/1183 2690/2917/1652 +f 465/1645/524 2793/2988/1733 2690/2917/1652 +f 465/1645/524 2690/2917/1652 466/1646/526 +f 518/1647/529 2735/2944/1684 2794/2989/1734 +f 518/1647/529 2794/2989/1734 519/1648/530 +f 2735/2944/1684 1583/1814/753 2274/2504/1408 +f 2735/2944/1684 2274/2504/1408 2794/2989/1734 +f 2794/2989/1734 2274/2504/1408 1622/1853/789 +f 2794/2989/1734 1622/1853/789 2730/2940/1679 +f 519/1648/530 2794/2989/1734 2730/2940/1679 +f 519/1648/530 2730/2940/1679 520/1649/530 +f 374/1638/512 2692/2919/1654 2800/2990/1735 +f 374/1638/512 2800/2990/1735 375/1639/513 +f 2692/2919/1654 1630/1861/797 1633/1864/800 +f 2692/2919/1654 1633/1864/800 2800/2990/1735 +f 2800/2990/1735 1633/1864/800 1534/1765/706 +f 2800/2990/1735 1534/1765/706 2696/2921/1656 +f 375/1639/513 2800/2990/1735 2696/2921/1656 +f 375/1639/513 2696/2921/1656 376/1640/514 +f 527/1650/531 2729/2939/1678 2803/2991/1736 +f 527/1650/531 2803/2991/1736 528/1435/458 +f 2729/2939/1678 2126/2357/1270 2294/2524/1427 +f 2729/2939/1678 2294/2524/1427 2803/2991/1736 +f 2803/2991/1736 2294/2524/1427 1572/1803/742 +f 2803/2991/1736 1572/1803/742 2733/1436/1682 +f 528/1435/458 2803/2991/1736 2733/1436/1682 +f 443/1641/518 2698/2923/1658 2804/2992/1737 +f 443/1641/518 2804/2992/1737 444/1642/519 +f 2698/2923/1658 1545/1776/716 1683/1914/846 +f 2698/2923/1658 1683/1914/846 2804/2992/1737 +f 2804/2992/1737 1683/1914/846 1584/1815/754 +f 2804/2992/1737 1584/1815/754 2684/2911/1646 +f 444/1642/519 2804/2992/1737 2684/2911/1646 +f 444/1642/519 2684/2911/1646 445/1643/520 +f 536/1651/535 2740/2949/1689 2808/2993/1738 +f 536/1651/535 2808/2993/1738 537/1652/536 +f 2740/2949/1689 1755/1986/913 1841/2072/996 +f 2740/2949/1689 1841/2072/996 2808/2993/1738 +f 2808/2993/1738 1841/2072/996 1847/2078/1002 +f 2808/2993/1738 1847/2078/1002 2727/2937/1676 +f 537/1652/536 2808/2993/1738 2727/2937/1676 +f 537/1652/536 2727/2937/1676 538/1653/537 +f 365/364/511 2726/2936/1675 2819/2994/1739 +f 365/364/511 2819/2994/1739 840/788/368 +f 2726/2936/1675 1764/1995/922 1767/1998/925 +f 2726/2936/1675 1767/1998/925 2819/2994/1739 +f 2819/2994/1739 1767/1998/925 1744/1975/903 +f 2819/2994/1739 1744/1975/903 2738/2947/1687 +f 840/788/368 2819/2994/1739 2738/2947/1687 +f 840/788/368 2738/2947/1687 534/789/533 +f 716/1668/562 2792/2987/1732 2820/2995/1740 +f 716/1668/562 2820/2995/1740 823/1677/573 +f 2792/2987/1732 1891/2122/1045 2246/2476/1382 +f 2792/2987/1732 2246/2476/1382 2820/2995/1740 +f 2820/2995/1740 2246/2476/1382 2127/2358/1271 +f 2820/2995/1740 2127/2358/1271 2778/2976/1720 +f 823/1677/573 2820/2995/1740 2778/2976/1720 +f 823/1677/573 2778/2976/1720 554/1657/540 +f 645/814/549 2754/2961/1704 2843/2996/1741 +f 645/814/549 2843/2996/1741 646/615/550 +f 2754/2961/1704 1608/1839/777 1611/1842/780 +f 2754/2961/1704 1611/1842/780 2843/2996/1741 +f 2843/2996/1741 1611/1842/780 1621/1852/788 +f 2843/2996/1741 1621/1852/788 2769/2970/1714 +f 646/615/550 2843/2996/1741 2769/2970/1714 +f 646/615/550 2769/2970/1714 647/1661/551 +f 694/800/554 2785/2982/1726 2844/2997/1742 +f 694/800/554 2844/2997/1742 695/657/555 +f 2785/2982/1726 1700/1931/861 1703/1934/864 +f 2785/2982/1726 1703/1934/864 2844/2997/1742 +f 2844/2997/1742 1703/1934/864 1711/1942/871 +f 2844/2997/1742 1711/1942/871 2786/1473/462 +f 695/657/555 2844/2997/1742 2786/1473/462 +f 624/846/546 2748/2955/1696 2851/2998/1743 +f 624/846/546 2851/2998/1743 625/595/547 +f 2748/2955/1696 1864/2095/1019 1867/2098/1022 +f 2748/2955/1696 1867/2098/1022 2851/2998/1743 +f 2851/2998/1743 1867/2098/1022 1638/1869/803 +f 2851/2998/1743 1638/1869/803 2758/2963/1706 +f 625/595/547 2851/2998/1743 2758/2963/1706 +f 625/595/547 2758/2963/1706 626/596/548 +f 712/830/559 2782/2980/1724 2854/2999/1744 +f 712/830/559 2854/2999/1744 713/673/359 +f 2782/2980/1724 1509/1740/682 1857/2088/1012 +f 2782/2980/1724 1857/2088/1012 2854/2999/1744 +f 2854/2999/1744 1857/2088/1012 1863/2094/1018 +f 2854/2999/1744 1863/2094/1018 2790/2985/1730 +f 713/673/359 2854/2999/1744 2790/2985/1730 +f 713/673/359 2790/2985/1730 714/1666/560 +f 561/878/542 2760/2965/1708 2868/3000/1745 +f 561/878/542 2868/3000/1745 562/534/543 +f 2760/2965/1708 1649/1880/814 2022/2253/1171 +f 2760/2965/1708 2022/2253/1171 2868/3000/1745 +f 2868/3000/1745 2022/2253/1171 1971/2202/1123 +f 2868/3000/1745 1971/2202/1123 2752/2959/1702 +f 562/534/543 2868/3000/1745 2752/2959/1702 +f 562/534/543 2752/2959/1702 563/535/387 +f 703/865/556 2788/2983/1728 2870/3001/1746 +f 703/865/556 2870/3001/1746 704/665/557 +f 2788/2983/1728 1674/1905/837 1677/1908/840 +f 2788/2983/1728 1677/1908/840 2870/3001/1746 +f 2870/3001/1746 1677/1908/840 1496/1727/672 +f 2870/3001/1746 1496/1727/672 2780/2978/1722 +f 704/665/557 2870/3001/1746 2780/2978/1722 +f 704/665/557 2780/2978/1722 705/666/558 +f 1070/1260/599 2872/3002/1747 2873/3003/1748 +f 1070/1260/599 2873/3003/1748 1354/1261/433 +f 2872/3002/1747 1825/2056/981 2305/2535/1438 +f 2872/3002/1747 2305/2535/1438 2873/3003/1748 +f 2873/3003/1748 2305/2535/1438 2009/2240/1158 +f 2873/3003/1748 2009/2240/1158 2874/3004/1749 +f 1354/1261/433 2873/3003/1748 2874/3004/1749 +f 1354/1261/433 2874/3004/1749 1356/1263/432 +f 1352/1717/652 2878/3005/1750 2879/3006/1751 +f 1352/1717/652 2879/3006/1751 1353/1258/653 +f 2878/3005/1750 1784/2015/942 1782/2013/940 +f 2878/3005/1750 1782/2013/940 2879/3006/1751 +f 2879/3006/1751 1782/2013/940 1781/2012/939 +f 2879/3006/1751 1781/2012/939 2880/3007/1752 +f 1353/1258/653 2879/3006/1751 2880/3007/1752 +f 1353/1258/653 2880/3007/1752 1006/1259/429 +f 1339/1245/422 2881/3008/1753 2882/3009/1754 +f 1339/1245/422 2882/3009/1754 1340/1246/1755 +f 2881/3008/1753 2006/2237/1155 2243/2473/1379 +f 2881/3008/1753 2243/2473/1379 2882/3009/1754 +f 2882/3009/1754 2243/2473/1379 2242/2472/1378 +f 2882/3009/1754 2242/2472/1378 2883/3010/1756 +f 1340/1246/1755 2882/3009/1754 2883/3010/1756 +f 1340/1246/1755 2883/3010/1756 1343/1249/505 +f 939/890/583 2884/3011/1757 2885/3012/1758 +f 939/890/583 2885/3012/1758 1304/1716/644 +f 2884/3011/1757 2143/2374/1285 2141/2372/1283 +f 2884/3011/1757 2141/2372/1283 2885/3012/1758 +f 2885/3012/1758 2141/2372/1283 2140/2371/1282 +f 2885/3012/1758 2140/2371/1282 2886/3013/1759 +f 1304/1716/644 2885/3012/1758 2886/3013/1759 +f 1304/1716/644 2886/3013/1759 1027/1684/591 +f 1356/1263/432 2874/3004/1749 2890/3014/1760 +f 1356/1263/432 2890/3014/1760 1360/1267/1761 +f 2874/3004/1749 2009/2240/1158 2007/2238/1156 +f 2874/3004/1749 2007/2238/1156 2890/3014/1760 +f 2890/3014/1760 2007/2238/1156 2006/2237/1155 +f 2890/3014/1760 2006/2237/1155 2881/3008/1753 +f 1360/1267/1761 2890/3014/1760 2881/3008/1753 +f 1360/1267/1761 2881/3008/1753 1339/1245/422 +f 1008/957/396 2893/3015/1762 2894/3016/1763 +f 1008/957/396 2894/3016/1763 1328/1233/647 +f 2893/3015/1762 1604/1835/774 1602/1833/772 +f 2893/3015/1762 1602/1833/772 2894/3016/1763 +f 2894/3016/1763 1602/1833/772 1601/1832/771 +f 2894/3016/1763 1601/1832/771 2895/3017/1764 +f 1328/1233/647 2894/3016/1763 2895/3017/1764 +f 1328/1233/647 2895/3017/1764 937/1234/418 +f 1348/1254/505 2896/3018/1765 2897/3019/1766 +f 1348/1254/505 2897/3019/1766 1349/1255/651 +f 2896/3018/1765 2258/2488/1394 2898/3020/1767 +f 2896/3018/1765 2898/3020/1767 2897/3019/1766 +f 2897/3019/1766 2898/3020/1767 1784/2015/942 +f 2897/3019/1766 1784/2015/942 2878/3005/1750 +f 1349/1255/651 2897/3019/1766 2878/3005/1750 +f 1349/1255/651 2878/3005/1750 1352/1717/652 +f 966/1682/584 2901/3021/1768 2902/3022/1769 +f 966/1682/584 2902/3022/1769 967/917/585 +f 2901/3021/1768 1995/2226/1145 1993/2224/1143 +f 2901/3021/1768 1993/2224/1143 2902/3022/1769 +f 2902/3022/1769 1993/2224/1143 1992/2223/1142 +f 2902/3022/1769 1992/2223/1142 2903/1507/465 +f 967/917/585 2902/3022/1769 2903/1507/465 +f 968/918/590 2903/1507/465 2904/1508/468 +f 2903/1507/465 1992/2223/1142 2301/2531/1434 +f 2903/1507/465 2301/2531/1434 2904/1508/468 +f 2904/1508/468 2301/2531/1434 2151/2382/1292 +f 2904/1508/468 2151/2382/1292 2905/1509/471 +f 977/927/642 2904/1508/468 2905/1509/471 +f 1031/1688/595 2912/3023/1770 2913/3024/1771 +f 1031/1688/595 2913/3024/1771 2914/3025/1772 +f 2912/3023/1770 2084/2315/1233 2915/3026/1773 +f 2912/3023/1770 2915/3026/1773 2913/3024/1771 +f 2913/3024/1771 2915/3026/1773 2059/2290/1208 +f 2913/3024/1771 2059/2290/1208 2916/3027/1774 +f 2914/3025/1772 2913/3024/1771 2916/3027/1774 +f 2914/3025/1772 2916/3027/1774 1036/1689/596 +f 1036/1689/596 2916/3027/1774 2917/3028/1775 +f 1036/1689/596 2917/3028/1775 1037/1690/597 +f 2916/3027/1774 2059/2290/1208 2057/2288/1206 +f 2916/3027/1774 2057/2288/1206 2917/3028/1775 +f 2917/3028/1775 2057/2288/1206 1995/2226/1145 +f 2917/3028/1775 1995/2226/1145 2901/3021/1768 +f 1037/1690/597 2917/3028/1775 2901/3021/1768 +f 1037/1690/597 2901/3021/1768 966/1682/584 +f 932/1681/582 2918/3029/1776 2919/3030/1777 +f 932/1681/582 2919/3030/1777 1069/1691/598 +f 2918/3029/1776 1828/2059/984 1826/2057/982 +f 2918/3029/1776 1826/2057/982 2919/3030/1777 +f 2919/3030/1777 1826/2057/982 1825/2056/981 +f 2919/3030/1777 1825/2056/981 2872/3002/1747 +f 1069/1691/598 2919/3030/1777 2872/3002/1747 +f 1069/1691/598 2872/3002/1747 1070/1260/599 +f 930/1679/580 2920/3031/1778 2921/3032/1779 +f 930/1679/580 2921/3032/1779 931/1680/581 +f 2920/3031/1778 2075/2306/1224 2073/2304/1222 +f 2920/3031/1778 2073/2304/1222 2921/3032/1779 +f 2921/3032/1779 2073/2304/1222 1828/2059/984 +f 2921/3032/1779 1828/2059/984 2918/3029/1776 +f 931/1680/581 2921/3032/1779 2918/3029/1776 +f 931/1680/581 2918/3029/1776 932/1681/582 +f 1092/1026/648 2922/1543/492 2923/3033/1780 +f 1092/1026/648 2923/3033/1780 1331/1237/649 +f 2922/1543/492 2017/2248/1166 2015/2246/1164 +f 2922/1543/492 2015/2246/1164 2923/3033/1780 +f 2923/3033/1780 2015/2246/1164 1099/1695/606 +f 2923/3033/1780 1099/1695/606 2924/3034/1781 +f 1331/1237/649 2923/3033/1780 2924/3034/1781 +f 1331/1237/649 2924/3034/1781 1332/1238/650 +f 1110/1034/611 2925/3035/1782 2926/3036/1783 +f 1110/1034/611 2926/3036/1783 1290/1192/641 +f 2925/3035/1782 1737/1968/896 2317/2547/1450 +f 2925/3035/1782 2317/2547/1450 2926/3036/1783 +f 2926/3036/1783 2317/2547/1450 2209/2439/1346 +f 2926/3036/1783 2209/2439/1346 2927/1516/473 +f 1290/1192/641 2926/3036/1783 2927/1516/473 +f 1083/1018/600 2928/3037/1784 2929/3038/1785 +f 1083/1018/600 2929/3038/1785 1315/1219/646 +f 2928/3037/1784 1816/2047/972 1814/2045/970 +f 2928/3037/1784 1814/2045/970 2929/3038/1785 +f 2929/3038/1785 1814/2045/970 1813/2044/969 +f 2929/3038/1785 1813/2044/969 2930/1517/1786 +f 1315/1219/646 2929/3038/1785 2930/1517/1786 +f 1108/1518/488 2931/1536/487 2932/1519/477 +f 2931/1536/487 1740/1971/899 1738/1969/897 +f 2931/1536/487 1738/1969/897 2932/1519/477 +f 2932/1519/477 1738/1969/897 1737/1968/896 +f 2932/1519/477 1737/1968/896 2925/3035/1782 +f 1109/1033/488 2932/1519/477 2925/3035/1782 +f 1109/1033/488 2925/3035/1782 1110/1034/611 +f 1472/1374/668 2933/3039/1787 2934/3040/1788 +f 1472/1374/668 2934/3040/1788 1468/1373/667 +f 2933/3039/1787 1728/1959/887 1726/1957/886 +f 2933/3039/1787 1726/1957/886 2934/3040/1788 +f 2934/3040/1788 1726/1957/886 1725/1956/885 +f 2934/3040/1788 1725/1956/885 2935/3041/1789 +f 1468/1373/667 2934/3040/1788 2935/3041/1789 +f 1468/1373/667 2935/3041/1789 1247/1368/628 +f 1193/1705/621 2938/3042/1790 2939/3043/1791 +f 1193/1705/621 2939/3043/1791 1465/1723/665 +f 2938/3042/1790 2051/2282/1200 2049/2280/1198 +f 2938/3042/1790 2049/2280/1198 2939/3043/1791 +f 2939/3043/1791 2049/2280/1198 1931/2162/1083 +f 2939/3043/1791 1931/2162/1083 2940/3044/1792 +f 1465/1723/665 2939/3043/1791 2940/3044/1792 +f 1465/1723/665 2940/3044/1792 1466/1724/666 +f 1462/1366/663 2941/3045/1793 2942/3046/1794 +f 1462/1366/663 2942/3046/1794 1458/1365/662 +f 2941/3045/1793 1928/2159/1080 1985/2216/1136 +f 2941/3045/1793 1985/2216/1136 2942/3046/1794 +f 2942/3046/1794 1985/2216/1136 1984/2215/1135 +f 2942/3046/1794 1984/2215/1135 2943/3047/1795 +f 1458/1365/662 2942/3046/1794 2943/3047/1795 +f 1458/1365/662 2943/3047/1795 1455/1359/661 +f 1214/1708/626 2944/3048/1796 2945/3049/1797 +f 1214/1708/626 2945/3049/1797 1435/1720/659 +f 2944/3048/1796 1914/2145/1067 2279/2509/1413 +f 2944/3048/1796 2279/2509/1413 2945/3049/1797 +f 2945/3049/1797 2279/2509/1413 2163/2394/1303 +f 2945/3049/1797 2163/2394/1303 2946/3050/1798 +f 1435/1720/659 2945/3049/1797 2946/3050/1798 +f 1435/1720/659 2946/3050/1798 1128/1700/613 +f 1455/1359/661 2943/3047/1795 2947/3051/1799 +f 1455/1359/661 2947/3051/1799 1474/1377/669 +f 2943/3047/1795 1984/2215/1135 2169/2400/1309 +f 2943/3047/1795 2169/2400/1309 2947/3051/1799 +f 2947/3051/1799 2169/2400/1309 1728/1959/887 +f 2947/3051/1799 1728/1959/887 2933/3039/1787 +f 1474/1377/669 2947/3051/1799 2933/3039/1787 +f 1474/1377/669 2933/3039/1787 1472/1374/668 +f 1130/1702/615 2950/3052/1800 2951/3053/1801 +f 1130/1702/615 2951/3053/1801 1495/1726/671 +f 2950/3052/1800 2160/2391/1301 2183/2414/1321 +f 2950/3052/1800 2183/2414/1321 2951/3053/1801 +f 2951/3053/1801 2183/2414/1321 2182/2413/1320 +f 2951/3053/1801 2182/2413/1320 2952/3054/1802 +f 1495/1726/671 2951/3053/1801 2952/3054/1802 +f 1495/1726/671 2952/3054/1802 1191/1703/619 +f 1466/1724/666 2940/3044/1792 2953/3055/1803 +f 1466/1724/666 2953/3055/1803 1464/1722/664 +f 2940/3044/1792 1931/2162/1083 1929/2160/1081 +f 2940/3044/1792 1929/2160/1081 2953/3055/1803 +f 2953/3055/1803 1929/2160/1081 1928/2159/1080 +f 2953/3055/1803 1928/2159/1080 2941/3045/1793 +f 1464/1722/664 2953/3055/1803 2941/3045/1793 +f 1464/1722/664 2941/3045/1793 1462/1366/663 +f 1150/1080/616 2954/1525/1804 2955/3056/1805 +f 1150/1080/616 2955/3056/1805 1151/1070/617 +f 2954/1525/1804 2109/2340/1255 2107/2338/1253 +f 2954/1525/1804 2107/2338/1253 2955/3056/1805 +f 2955/3056/1805 2107/2338/1253 1943/2174/1095 +f 2955/3056/1805 1943/2174/1095 2956/3057/1806 +f 1151/1070/617 2955/3056/1805 2956/3057/1806 +f 1151/1070/617 2956/3057/1806 1152/1071/618 +f 978/928/1807 2905/1509/471 2957/1524/479 +f 2905/1509/471 2151/2382/1292 2149/2380/1291 +f 2905/1509/471 2149/2380/1291 2957/1524/479 +f 2957/1524/479 2149/2380/1291 2109/2340/1255 +f 2957/1524/479 2109/2340/1255 2954/1525/1804 +f 1163/1083/1808 2957/1524/479 2954/1525/1804 +f 1210/1131/622 2961/3058/1809 2962/3059/1810 +f 1210/1131/622 2962/3059/1810 1211/1127/623 +f 2961/3058/1809 1940/2171/1092 2263/2493/1399 +f 2961/3058/1809 2263/2493/1399 2962/3059/1810 +f 2962/3059/1810 2263/2493/1399 1917/2148/1070 +f 2962/3059/1810 1917/2148/1070 2963/3060/1811 +f 1211/1127/623 2962/3059/1810 2963/3060/1811 +f 1211/1127/623 2963/3060/1811 1212/1706/624 +f 1152/1071/618 2956/3057/1806 2964/3061/1812 +f 1152/1071/618 2964/3061/1812 1217/1130/627 +f 2956/3057/1806 1943/2174/1095 1941/2172/1093 +f 2956/3057/1806 1941/2172/1093 2964/3061/1812 +f 2964/3061/1812 1941/2172/1093 1940/2171/1092 +f 2964/3061/1812 1940/2171/1092 2961/3058/1809 +f 1217/1130/627 2964/3061/1812 2961/3058/1809 +f 1217/1130/627 2961/3058/1809 1210/1131/622 +f 1247/1368/628 2935/3041/1789 2968/3062/1813 +f 1247/1368/628 2968/3062/1813 1248/1161/629 +f 2935/3041/1789 1725/1956/885 2313/2543/1446 +f 2935/3041/1789 2313/2543/1446 2968/3062/1813 +f 2968/3062/1813 2313/2543/1446 2285/2515/1419 +f 2968/3062/1813 2285/2515/1419 2969/3063/1814 +f 1248/1161/629 2968/3062/1813 2969/3063/1814 +f 1248/1161/629 2969/3063/1814 1117/1162/612 +f 1117/1162/612 2969/3063/1814 2970/3064/1815 +f 1117/1162/612 2970/3064/1815 1118/1041/402 +f 2969/3063/1814 2285/2515/1419 2283/2513/1417 +f 2969/3063/1814 2283/2513/1417 2970/3064/1815 +f 2970/3064/1815 2283/2513/1417 2067/2298/1216 +f 2970/3064/1815 2067/2298/1216 2971/3065/1816 +f 1118/1041/402 2970/3064/1815 2971/3065/1816 +f 1118/1041/402 2971/3065/1816 1119/1042/444 +f 1281/1714/640 2972/3066/1817 2973/3067/1818 +f 1281/1714/640 2973/3067/1818 1450/1721/660 +f 2972/3066/1817 2218/2448/1355 2675/2905/1640 +f 2972/3066/1817 2675/2905/1640 2973/3067/1818 +f 2973/3067/1818 2675/2905/1640 2326/2556/1458 +f 2973/3067/1818 2326/2556/1458 2974/3068/1819 +f 1450/1721/660 2973/3067/1818 2974/3068/1819 +f 1450/1721/660 2974/3068/1819 1270/1709/634 +f 1263/1532/633 2975/3069/1820 2976/1533/484 +f 2975/3069/1820 2225/2455/1362 2223/2453/1360 +f 2975/3069/1820 2223/2453/1360 2976/1533/484 +f 2976/1533/484 2223/2453/1360 1804/2035/960 +f 2976/1533/484 1804/2035/960 2977/3070/1821 +f 1422/1534/631 2976/1533/484 2977/3070/1821 +f 1422/1534/631 2977/3070/1821 1286/1715/486 +f 1286/1715/486 2977/3070/1821 2978/3071/1822 +f 1286/1715/486 2978/3071/1822 1287/1535/486 +f 2977/3070/1821 1804/2035/960 1802/2033/958 +f 2977/3070/1821 1802/2033/958 2978/3071/1822 +f 2978/3071/1822 1802/2033/958 1740/1971/899 +f 2978/3071/1822 1740/1971/899 2931/1536/487 +f 1287/1535/486 2978/3071/1822 2931/1536/487 +f 1277/1301/437 2979/3072/1823 2980/3073/1824 +f 1277/1301/437 2980/3073/1824 1278/1185/637 +f 2979/3072/1823 1963/2194/1115 1961/2192/1113 +f 2979/3072/1823 1961/2192/1113 2980/3073/1824 +f 2980/3073/1824 1961/2192/1113 1960/2191/1112 +f 2980/3073/1824 1960/2191/1112 2981/3074/1825 +f 1278/1185/637 2980/3073/1824 2981/3074/1825 +f 1278/1185/637 2981/3074/1825 1279/1712/638 +f 1081/1193/489 2927/1516/473 2982/1537/490 +f 2927/1516/473 2209/2439/1346 2207/2437/1344 +f 2927/1516/473 2207/2437/1344 2982/1537/490 +f 2982/1537/490 2207/2437/1344 1816/2047/972 +f 2982/1537/490 1816/2047/972 2928/3037/1784 +f 1082/1017/474 2982/1537/490 2928/3037/1784 +f 1082/1017/474 2928/3037/1784 1083/1018/600 +f 937/1234/418 2895/3017/1764 2986/3075/1826 +f 937/1234/418 2986/3075/1826 938/889/391 +f 2895/3017/1764 1601/1832/771 2309/2539/1442 +f 2895/3017/1764 2309/2539/1442 2986/3075/1826 +f 2986/3075/1826 2309/2539/1442 2143/2374/1285 +f 2986/3075/1826 2143/2374/1285 2884/3011/1757 +f 938/889/391 2986/3075/1826 2884/3011/1757 +f 938/889/391 2884/3011/1757 939/890/583 +f 1090/1220/601 2930/1517/1786 2989/3076/1827 +f 1090/1220/601 2989/3076/1827 1091/1025/602 +f 2930/1517/1786 1813/2044/969 2173/2404/1313 +f 2930/1517/1786 2173/2404/1313 2989/3076/1827 +f 2989/3076/1827 2173/2404/1313 2017/2248/1166 +f 2989/3076/1827 2017/2248/1166 2922/1543/492 +f 1091/1025/602 2989/3076/1827 2922/1543/492 +f 1006/1259/429 2880/3007/1752 2990/3077/1828 +f 1006/1259/429 2990/3077/1828 1007/956/586 +f 2880/3007/1752 1781/2012/939 2291/2521/1425 +f 2880/3007/1752 2291/2521/1425 2990/3077/1828 +f 2990/3077/1828 2291/2521/1425 1604/1835/774 +f 2990/3077/1828 1604/1835/774 2893/3015/1762 +f 1007/956/586 2990/3077/1828 2893/3015/1762 +f 1007/956/586 2893/3015/1762 1008/957/396 +f 1332/1238/650 2924/3034/1781 2994/1547/1829 +f 2924/3034/1781 1099/1695/606 1096/1692/603 +f 2924/3034/1781 1096/1692/603 2994/1547/1829 +f 2994/1547/1829 1096/1692/603 1095/1278/421 +f 1411/1718/657 3006/3078/1830 3007/3079/1831 +f 1411/1718/657 3007/3079/1831 1412/1719/658 +f 3006/3078/1830 1103/1699/610 2197/2428/1335 +f 3006/3078/1830 2197/2428/1335 3007/3079/1831 +f 3007/3079/1831 2197/2428/1335 2075/2306/1224 +f 3007/3079/1831 2075/2306/1224 2920/3031/1778 +f 1412/1719/658 3007/3079/1831 2920/3031/1778 +f 1412/1719/658 2920/3031/1778 930/1679/580 +f 1119/1042/444 2971/3065/1816 3008/3080/1832 +f 1119/1042/444 3008/3080/1832 1392/1300/655 +f 2971/3065/1816 2067/2298/1216 2065/2296/1214 +f 2971/3065/1816 2065/2296/1214 3008/3080/1832 +f 3008/3080/1832 2065/2296/1214 1963/2194/1115 +f 3008/3080/1832 1963/2194/1115 2979/3072/1823 +f 1392/1300/655 3008/3080/1832 2979/3072/1823 +f 1392/1300/655 2979/3072/1823 1277/1301/437 +f 3009/1559/389 1371/1279/389 1095/1278/654 +f 1409/1318/497 3010/1560/412 3029/1579/1833 +f 3010/1560/412 1095/1278/421 1098/1694/605 +f 3010/1560/412 1098/1694/605 3029/1579/1833 +f 3029/1579/1833 1098/1694/605 1103/1699/610 +f 3029/1579/1833 1103/1699/610 3006/3078/1830 +f 1410/1319/656 3029/1579/1833 3006/3078/1830 +f 1410/1319/656 3006/3078/1830 1411/1718/657 +f 1212/1706/624 2963/3060/1811 3032/3081/1834 +f 1212/1706/624 3032/3081/1834 1213/1707/625 +f 2963/3060/1811 1917/2148/1070 1915/2146/1068 +f 2963/3060/1811 1915/2146/1068 3032/3081/1834 +f 3032/3081/1834 1915/2146/1068 1914/2145/1067 +f 3032/3081/1834 1914/2145/1067 2944/3048/1796 +f 1213/1707/625 3032/3081/1834 2944/3048/1796 +f 1213/1707/625 2944/3048/1796 1214/1708/626 +f 1261/1582/1835 3033/1609/503 3034/1583/500 +f 3033/1609/503 2233/2463/1370 2231/2461/1368 +f 3033/1609/503 2231/2461/1368 3034/1583/500 +f 3034/1583/500 2231/2461/1368 2225/2455/1362 +f 3034/1583/500 2225/2455/1362 2975/3069/1820 +f 1262/1584/632 3034/1583/500 2975/3069/1820 +f 1262/1584/632 2975/3069/1820 1263/1532/633 +f 1191/1703/619 2952/3054/1802 3041/3082/1836 +f 1191/1703/619 3041/3082/1836 1192/1704/620 +f 2952/3054/1802 2182/2413/1320 2267/2497/1402 +f 2952/3054/1802 2267/2497/1402 3041/3082/1836 +f 3041/3082/1836 2267/2497/1402 2051/2282/1200 +f 3041/3082/1836 2051/2282/1200 2938/3042/1790 +f 1192/1704/620 3041/3082/1836 2938/3042/1790 +f 1192/1704/620 2938/3042/1790 1193/1705/621 +f 1279/1712/638 2981/3074/1825 3044/3083/1837 +f 1279/1712/638 3044/3083/1837 1280/1713/639 +f 2981/3074/1825 1960/2191/1112 2219/2449/1356 +f 2981/3074/1825 2219/2449/1356 3044/3083/1837 +f 3044/3083/1837 2219/2449/1356 2218/2448/1355 +f 3044/3083/1837 2218/2448/1355 2972/3066/1817 +f 1280/1713/639 3044/3083/1837 2972/3066/1817 +f 1280/1713/639 2972/3066/1817 1281/1714/640 +f 1128/1700/613 2946/3050/1798 3058/3084/1838 +f 1128/1700/613 3058/3084/1838 1129/1701/614 +f 2946/3050/1798 2163/2394/1303 2161/2392/1302 +f 2946/3050/1798 2161/2392/1302 3058/3084/1838 +f 3058/3084/1838 2161/2392/1302 2160/2391/1301 +f 3058/3084/1838 2160/2391/1301 2950/3052/1800 +f 1129/1701/614 3058/3084/1838 2950/3052/1800 +f 1129/1701/614 2950/3052/1800 1130/1702/615 +f 1270/1709/634 2974/3068/1819 3060/3085/1839 +f 1270/1709/634 3060/3085/1839 1271/1710/635 +f 2974/3068/1819 2326/2556/1458 2324/2554/1457 +f 2974/3068/1819 2324/2554/1457 3060/3085/1839 +f 3060/3085/1839 2324/2554/1457 2204/2434/1341 +f 3060/3085/1839 2204/2434/1341 2203/2433/1340 +f 1271/1710/635 3060/3085/1839 2203/2433/1340 +f 1271/1710/635 2203/2433/1340 1272/1711/636 +f 3062/3086/1189 3063/3087/1840 3064/3088/1841 +f 3062/3086/1189 3064/3088/1841 2371/2601/1478 +f 3063/3087/1840 2135/2366/1278 2490/2720/1540 +f 3063/3087/1840 2490/2720/1540 3064/3088/1841 +f 3064/3088/1841 2490/2720/1540 2379/2609/1486 +f 3064/3088/1841 2379/2609/1486 3065/3089/1842 +f 2371/2601/1478 3064/3088/1841 3065/3089/1842 +f 2371/2601/1478 3065/3089/1842 2372/2602/1479 +f 2375/2605/1482 3066/3090/1843 3067/3091/1844 +f 2375/2605/1482 3067/3091/1844 2376/2606/1483 +f 3066/3090/1843 2384/2614/1491 3068/3092/1845 +f 3066/3090/1843 3068/3092/1845 3067/3091/1844 +f 3069/3093/1844 3070/3094/1845 2090/2321/1239 +f 3069/3093/1844 2090/2321/1239 3071/3095/1846 +f 2376/2606/1483 3067/3091/1844 3072/3096/1846 +f 2376/2606/1483 3072/3096/1846 2378/2608/1485 +f 2372/2602/1479 3065/3089/1842 3073/3097/1847 +f 2372/2602/1479 3073/3097/1847 2373/2603/1480 +f 3065/3089/1842 2379/2609/1486 2382/2612/1489 +f 3065/3089/1842 2382/2612/1489 3073/3097/1847 +f 3073/3097/1847 2382/2612/1489 2384/2614/1491 +f 3073/3097/1847 2384/2614/1491 3066/3090/1843 +f 2373/2603/1480 3073/3097/1847 3066/3090/1843 +f 2373/2603/1480 3066/3090/1843 2375/2605/1482 +f 2204/2434/1341 2323/2553/1456 3074/3098/1848 +f 2204/2434/1341 3074/3098/1848 2202/2432/1339 +f 2320/2550/1453 2319/2549/1452 2549/2779/1580 +f 2320/2550/1453 2549/2779/1580 3075/3099/1849 +f 3075/3099/1849 2549/2779/1580 2236/2466/1373 +f 3075/3099/1849 2236/2466/1373 3076/3100/1850 +f 2202/2432/1339 3074/3098/1848 3077/3101/1851 +f 2202/2432/1339 3077/3101/1851 2199/2430/1336 +f 2199/2430/1336 3077/3101/1851 3078/3102/1852 +f 2199/2430/1336 3078/3102/1852 2200/1608/1337 +f 3076/3100/1850 2236/2466/1373 2235/2465/1372 +f 3076/3100/1850 2235/2465/1372 3079/3103/1853 +f 3078/3102/1852 2234/2464/1371 2233/2463/1370 +f 3078/3102/1852 2233/2463/1370 3033/1609/503 +f 2200/1608/1337 3078/3102/1852 3033/1609/503 +f 1027/1684/591 2886/3013/1759 3080/3104/1854 +f 1027/1684/591 3080/3104/1854 2039/2270/1188 +f 2886/3013/1759 2140/2371/1282 2139/2370/1279 +f 2886/3013/1759 2139/2370/1279 3080/3104/1854 +f 3081/3105/1855 2136/2367/1279 2135/2366/1278 +f 3081/3105/1855 2135/2366/1278 3063/3087/1840 +f 2039/2270/1188 3080/3104/1854 3082/3106/1840 +f 2039/2270/1188 3082/3106/1840 2040/2271/1189 +f 2378/2608/1485 3072/3096/1846 3083/3107/1856 +f 2378/2608/1485 3083/3107/1856 3084/3108/1857 +f 3071/3095/1846 2090/2321/1239 2089/2320/1238 +f 3071/3095/1846 2089/2320/1238 3085/3109/1858 +f 3086/3110/1858 2088/2319/1237 2087/2318/1236 +f 3086/3110/1858 2087/2318/1236 3087/3111/1859 +f 2036/2267/1185 3086/3110/1858 3087/3111/1859 +f 2036/2267/1185 3087/3111/1859 1029/1686/593 +f 1029/1686/593 3087/3111/1859 3088/3112/1860 +f 1029/1686/593 3088/3112/1860 1030/1687/594 +f 3087/3111/1859 2087/2318/1236 2085/2316/1234 +f 3087/3111/1859 2085/2316/1234 3088/3112/1860 +f 3088/3112/1860 2085/2316/1234 2084/2315/1233 +f 3088/3112/1860 2084/2315/1233 2912/3023/1770 +f 1030/1687/594 3088/3112/1860 2912/3023/1770 +f 1030/1687/594 2912/3023/1770 1031/1688/595 +f 1343/1249/505 2883/3010/1756 3089/3113/1861 +f 1343/1249/505 3089/3113/1861 3090/1610/425 +f 2883/3010/1756 2242/2472/1378 2259/2489/1395 +f 2883/3010/1756 2259/2489/1395 3089/3113/1861 +f 3089/3113/1861 2259/2489/1395 2258/2488/1394 +f 3089/3113/1861 2258/2488/1394 2896/3018/1765 +f 3090/1610/425 3089/3113/1861 2896/3018/1765 +f 3090/1610/425 2896/3018/1765 1348/1254/505 +f 470/459/345 2717/2932/1671 3091/3114/1862 +f 470/459/345 3091/3114/1862 3092/1634/1863 +f 2717/2932/1671 2098/2329/1246 3093/3115/1864 +f 2717/2932/1671 3093/3115/1864 3091/3114/1862 +f 3091/3114/1862 3093/3115/1864 1872/2103/1026 +f 3091/3114/1862 1872/2103/1026 2713/2928/1667 +f 3092/1634/1863 3091/3114/1862 2713/2928/1667 +f 3092/1634/1863 2713/2928/1667 462/1635/521 +f 783/1676/569 2686/2913/1648 3094/3116/1865 +f 783/1676/569 3094/3116/1865 781/1674/510 +f 2686/2913/1648 1595/1826/765 3095/3117/1866 +f 2686/2913/1648 3095/3117/1866 3094/3116/1865 +f 3094/3116/1865 3095/3117/1866 1712/1943/872 +f 3094/3116/1865 1712/1943/872 2699/2924/1659 +f 781/1674/510 3094/3116/1865 2699/2924/1659 +f 781/1674/510 2699/2924/1659 778/729/507 +f 2565/2795/1591 2568/2798/1592 3096/3118/1867 +f 2565/2795/1591 3096/3118/1867 3097/3119/1867 +f 2568/2798/1592 1667/1898/830 1718/1949/878 +f 2568/2798/1592 1718/1949/878 3096/3118/1867 +f 3096/3118/1867 1718/1949/878 1717/1948/877 +f 3096/3118/1867 1717/1948/877 2615/2845/1611 +f 3097/3119/1867 3096/3118/1867 2615/2845/1611 +f 3097/3119/1867 2615/2845/1611 2610/2840/1607 +f 2237/2467/1374 2566/2796/1592 3098/3120/1867 +f 2237/2467/1374 3098/3120/1867 2256/2486/1392 +f 2566/2796/1592 2565/2795/1591 3097/3119/1867 +f 2566/2796/1592 3097/3119/1867 3098/3120/1867 +f 3098/3120/1867 3097/3119/1867 2610/2840/1607 +f 3098/3120/1867 2610/2840/1607 2607/2837/1607 +f 2256/2486/1392 3098/3120/1867 2607/2837/1607 +f 2256/2486/1392 2607/2837/1607 2253/2483/1389 +f 3099/3121/1868 3100/3122/1490 3101/3123/1869 +f 3099/3121/1868 3101/3123/1869 3102/3124/1870 +f 3100/3122/1490 1880/2111/1034 1878/2109/1032 +f 3100/3122/1490 1878/2109/1032 3101/3123/1869 +f 3101/3123/1869 1878/2109/1032 1877/2108/1031 +f 3101/3123/1869 1877/2108/1031 2447/2677/1516 +f 3102/3124/1870 3101/3123/1869 2447/2677/1516 +f 3102/3124/1870 2447/2677/1516 2445/2675/1515 +f 2090/2321/1239 3070/3094/1845 3103/3125/1871 +f 2090/2321/1239 3103/3125/1871 2082/2313/1231 +f 3070/3094/1845 3099/3121/1868 3102/3124/1870 +f 3070/3094/1845 3102/3124/1870 3103/3125/1871 +f 3103/3125/1871 3102/3124/1870 2445/2675/1515 +f 3103/3125/1871 2445/2675/1515 2442/2672/1512 +f 2082/2313/1231 3103/3125/1871 2442/2672/1512 +f 2082/2313/1231 2442/2672/1512 2079/2310/1228 +f 1787/2018/944 1786/2017/943 3104/3126/1872 +f 1787/2018/944 3104/3126/1872 2614/2844/1609 +f 1785/2016/943 1784/2015/942 2898/3020/1767 +f 1785/2016/943 2898/3020/1767 3105/3127/1873 +f 3105/3127/1873 2898/3020/1767 2258/2488/1394 +f 3105/3127/1873 2258/2488/1394 2257/2487/1393 +f 2609/2839/1609 3106/3128/1874 2254/2484/1390 +f 2609/2839/1609 2254/2484/1390 2253/2483/1389 +f 2062/2293/1211 2061/2292/1210 3107/3129/1875 +f 2062/2293/1211 3107/3129/1875 2444/2674/1514 +f 2060/2291/1209 2059/2290/1208 2915/3026/1773 +f 2060/2291/1209 2915/3026/1773 3108/3130/1876 +f 3108/3130/1876 2915/3026/1773 2084/2315/1233 +f 3108/3130/1876 2084/2315/1233 2083/2314/1232 +f 2444/2674/1514 3107/3129/1875 2080/2311/1229 +f 2444/2674/1514 2080/2311/1229 2079/2310/1228 +f 2098/2329/1246 2097/2328/1245 3109/3131/1877 +f 2098/2329/1246 3109/3131/1877 3093/3115/1864 +f 2096/2327/1244 2095/2326/1243 2449/2679/1517 +f 2096/2327/1244 2449/2679/1517 3110/3132/1878 +f 3110/3132/1878 2449/2679/1517 1877/2108/1031 +f 3110/3132/1878 1877/2108/1031 1876/2107/1030 +f 3093/3115/1864 3109/3131/1877 1873/2104/1027 +f 3093/3115/1864 1873/2104/1027 1872/2103/1026 +f 1595/1826/765 1594/1825/764 3111/3133/1879 +f 1595/1826/765 3111/3133/1879 3095/3117/1866 +f 1593/1824/763 1592/1823/762 2619/2849/1612 +f 1593/1824/763 2619/2849/1612 3112/3134/1880 +f 3113/3135/1880 2617/2847/1612 1717/1948/877 +f 3113/3135/1880 1717/1948/877 1716/1947/876 +f 3095/3117/1866 3111/3133/1879 1713/1944/873 +f 3095/3117/1866 1713/1944/873 1712/1943/872 +f 3121/1618/389 1023/1208/587 1026/1620/590 +f 3122/1619/389 1026/1620/590 1031/1688/595 +f 3122/1619/389 1031/1688/595 2914/3025/1772 +f 1035/975/389 3122/1619/389 2914/3025/1772 +f 1035/975/389 2914/3025/1772 1036/1689/596 +f 777/1623/507 3125/1624/335 2701/1626/363 +f 2701/1626/363 779/730/335 778/729/507 +f 471/460/338 470/459/345 3092/1634/1863 +f 3133/1633/335 3092/1634/1863 462/1635/521 +o Cube.029__0 +v -0.263502 -0.060252 -0.089221 +v -0.264065 -0.049981 -0.088743 +v -0.264065 -0.048717 -0.115929 +v -0.263502 -0.058988 -0.116406 +v 0.268838 -0.029860 -0.115052 +v 0.268275 -0.019589 -0.114575 +v 0.268275 -0.020853 -0.087389 +v 0.268838 -0.031124 -0.087866 +v -0.175342 -0.045126 -0.088517 +v -0.264065 -0.049981 -0.088743 +v -0.264065 -0.050116 -0.085830 +v -0.175342 -0.045261 -0.085604 +v 0.180114 -0.034715 -0.115278 +v 0.268838 -0.029860 -0.115052 +v 0.268838 -0.031124 -0.087866 +v 0.180114 -0.035978 -0.088092 +v -0.175342 -0.043862 -0.115703 +v -0.264065 -0.048717 -0.115929 +v 0.268275 -0.019589 -0.114575 +v 0.179551 -0.024444 -0.114800 +v 0.179551 -0.025707 -0.087615 +v 0.268275 -0.020853 -0.087389 +v 0.090828 -0.029298 -0.115026 +v 0.090828 -0.030562 -0.087841 +v 0.002105 -0.034153 -0.115252 +v 0.002105 -0.035417 -0.088066 +v -0.086619 -0.039007 -0.115478 +v -0.086619 -0.040271 -0.088292 +v -0.263502 -0.058988 -0.116406 +v -0.174779 -0.054133 -0.116180 +v -0.174779 -0.055397 -0.088995 +v -0.263502 -0.060252 -0.089221 +v 0.180114 -0.034715 -0.115278 +v 0.180114 -0.035978 -0.088092 +v 0.180275 -0.038918 -0.088229 +v 0.180275 -0.037654 -0.115414 +v -0.086056 -0.049278 -0.115955 +v 0.002668 -0.044424 -0.115729 +v 0.002668 -0.045688 -0.088543 +v -0.086056 -0.050542 -0.088769 +v 0.091391 -0.039569 -0.115504 +v 0.091391 -0.040833 -0.088318 +v -0.086056 -0.050542 -0.088769 +v -0.174779 -0.055397 -0.088995 +v -0.174618 -0.058337 -0.089131 +v -0.085894 -0.053482 -0.088906 +v 0.268838 -0.031124 -0.087866 +v 0.268275 -0.020853 -0.087389 +v 0.179551 -0.025707 -0.087615 +v 0.180114 -0.035978 -0.088092 +v 0.180114 -0.035978 -0.088092 +v 0.179551 -0.025707 -0.087615 +v 0.090828 -0.030562 -0.087841 +v 0.091391 -0.040833 -0.088318 +v 0.002105 -0.035417 -0.088066 +v 0.002668 -0.045688 -0.088543 +v 0.002668 -0.045823 -0.085630 +v 0.002105 -0.035552 -0.085153 +v 0.002668 -0.045688 -0.088543 +v 0.002105 -0.035417 -0.088066 +v -0.086619 -0.040271 -0.088292 +v -0.086056 -0.050542 -0.088769 +v -0.086056 -0.050542 -0.088769 +v -0.086619 -0.040271 -0.088292 +v -0.175342 -0.045126 -0.088517 +v -0.174779 -0.055397 -0.088995 +v -0.174618 -0.057073 -0.116317 +v -0.085894 -0.052218 -0.116091 +v -0.085894 -0.053482 -0.088906 +v -0.174618 -0.058337 -0.089131 +v 0.091552 -0.042509 -0.115640 +v 0.180275 -0.037654 -0.115414 +v 0.180275 -0.038918 -0.088229 +v 0.091552 -0.043773 -0.088454 +v -0.174779 -0.055397 -0.088995 +v -0.174779 -0.054133 -0.116180 +v -0.174618 -0.057073 -0.116317 +v -0.174618 -0.058337 -0.089131 +v 0.180114 -0.035978 -0.088092 +v 0.091391 -0.040833 -0.088318 +v 0.091552 -0.043773 -0.088454 +v 0.180275 -0.038918 -0.088229 +v 0.091391 -0.039569 -0.115504 +v 0.180114 -0.034715 -0.115278 +v 0.180275 -0.037654 -0.115414 +v 0.091552 -0.042509 -0.115640 +v 0.091391 -0.040833 -0.088318 +v 0.091391 -0.039569 -0.115504 +v 0.091552 -0.042509 -0.115640 +v 0.091552 -0.043773 -0.088454 +v -0.086056 -0.049278 -0.115955 +v -0.086056 -0.050542 -0.088769 +v -0.085894 -0.053482 -0.088906 +v -0.085894 -0.052218 -0.116091 +v -0.174779 -0.054133 -0.116180 +v -0.086056 -0.049278 -0.115955 +v -0.085894 -0.052218 -0.116091 +v -0.174618 -0.057073 -0.116317 +v -0.174779 -0.055532 -0.086081 +v -0.175342 -0.045261 -0.085604 +v -0.264065 -0.050116 -0.085830 +v -0.263502 -0.060387 -0.086307 +v 0.091391 -0.040968 -0.085404 +v 0.090828 -0.030697 -0.084927 +v 0.002105 -0.035552 -0.085153 +v 0.002668 -0.045823 -0.085630 +v -0.174779 -0.055532 -0.086081 +v -0.263502 -0.060387 -0.086307 +v 0.002105 -0.035552 -0.085153 +v 0.090828 -0.030697 -0.084927 +v 0.091391 -0.040968 -0.085404 +v 0.002668 -0.045823 -0.085630 +v -0.263502 -0.060387 -0.086307 +v -0.264065 -0.050116 -0.085830 +v 0.091391 -0.040833 -0.088318 +v 0.090828 -0.030562 -0.087841 +v 0.090828 -0.030697 -0.084927 +v 0.091391 -0.040968 -0.085404 +v -0.174779 -0.055397 -0.088995 +v -0.175342 -0.045126 -0.088517 +v -0.175342 -0.045261 -0.085604 +v -0.174779 -0.055532 -0.086081 +vt 0.591529 0.773061 +vt 0.590768 0.773061 +vt 0.590768 0.775074 +vt 0.591529 0.775074 +vt 0.204060 0.419299 +vt 0.204821 0.419299 +vt 0.204821 0.417286 +vt 0.204060 0.417286 +vt 0.977681 0.345901 +vt 0.977681 0.352472 +vt 0.977896 0.352472 +vt 0.977896 0.345901 +vt 0.660598 0.057668 +vt 0.660598 0.064239 +vt 0.662610 0.064239 +vt 0.662610 0.057668 +vt 0.975668 0.345901 +vt 0.975668 0.352472 +vt 0.975668 0.313048 +vt 0.975668 0.319619 +vt 0.977681 0.319619 +vt 0.977681 0.313048 +vt 0.975668 0.326189 +vt 0.977681 0.326189 +vt 0.975668 0.332760 +vt 0.977681 0.332760 +vt 0.975668 0.339331 +vt 0.977681 0.339331 +vt 0.940656 0.146048 +vt 0.940656 0.152618 +vt 0.942669 0.152618 +vt 0.942669 0.146048 +vt 0.215136 0.709644 +vt 0.215136 0.711657 +vt 0.215354 0.711657 +vt 0.215354 0.709644 +vt 0.355114 0.001670 +vt 0.355114 0.008240 +vt 0.357127 0.008240 +vt 0.357127 0.001670 +vt 0.355114 0.014811 +vt 0.357127 0.014811 +vt 0.215107 0.353630 +vt 0.215107 0.360201 +vt 0.215325 0.360201 +vt 0.215325 0.353630 +vt 0.408530 0.352110 +vt 0.407768 0.352110 +vt 0.407768 0.358680 +vt 0.408530 0.358680 +vt 0.408530 0.358680 +vt 0.407768 0.358680 +vt 0.407768 0.365251 +vt 0.408530 0.365251 +vt 0.215269 0.691114 +vt 0.215269 0.690352 +vt 0.215053 0.690352 +vt 0.215053 0.691114 +vt 0.215107 0.347060 +vt 0.214346 0.347060 +vt 0.214346 0.353630 +vt 0.215107 0.353630 +vt 0.215107 0.353630 +vt 0.214346 0.353630 +vt 0.214346 0.360201 +vt 0.215107 0.360201 +vt 0.951096 0.732131 +vt 0.951096 0.738702 +vt 0.953109 0.738702 +vt 0.953109 0.732131 +vt 0.952262 0.146048 +vt 0.952262 0.152618 +vt 0.954275 0.152618 +vt 0.954275 0.146048 +vt 0.215136 0.711697 +vt 0.215136 0.713710 +vt 0.215354 0.713710 +vt 0.215354 0.711697 +vt 0.408530 0.358680 +vt 0.408530 0.365251 +vt 0.408748 0.365251 +vt 0.408748 0.358680 +vt 0.215136 0.730607 +vt 0.215136 0.737177 +vt 0.215354 0.737177 +vt 0.215354 0.730607 +vt 0.215136 0.705539 +vt 0.215136 0.707551 +vt 0.215354 0.707551 +vt 0.215354 0.705539 +vt 0.215136 0.707592 +vt 0.215136 0.709604 +vt 0.215354 0.709604 +vt 0.215354 0.707592 +vt 0.215136 0.723905 +vt 0.215136 0.730475 +vt 0.215354 0.730475 +vt 0.215354 0.723905 +vt 0.214484 0.308403 +vt 0.215245 0.308403 +vt 0.215245 0.301832 +vt 0.214484 0.301832 +vt 0.408716 0.297638 +vt 0.407954 0.297638 +vt 0.407954 0.304209 +vt 0.408716 0.304209 +vt 0.942884 0.152618 +vt 0.942884 0.146048 +vt 0.977896 0.332760 +vt 0.977896 0.326189 +vt 0.357343 0.014811 +vt 0.357343 0.008240 +vt 0.591529 0.772846 +vt 0.590768 0.772846 +vt 0.215269 0.691891 +vt 0.215269 0.691129 +vt 0.215053 0.691129 +vt 0.215053 0.691891 +vt 0.215269 0.690337 +vt 0.215269 0.689576 +vt 0.215053 0.689576 +vt 0.215053 0.690337 +vn -0.9985 -0.0546 -0.0025 +vn 0.9985 0.0546 0.0025 +vn -0.0547 0.9974 0.0464 +vn 0.0547 -0.9974 -0.0464 +vn 0.0000 -0.0464 0.9989 +vn 0.0000 0.0464 -0.9989 +vn 0.9985 0.0547 0.0025 +usemtl Scene_-_Root +s off +f 3136/3136/1881 3137/3137/1881 3138/3138/1881 +f 3136/3136/1881 3138/3138/1881 3139/3139/1881 +f 3140/3140/1882 3141/3141/1882 3142/3142/1882 +f 3140/3140/1882 3142/3142/1882 3143/3143/1882 +f 3144/3144/1883 3145/3145/1883 3146/3146/1883 +f 3144/3144/1883 3146/3146/1883 3147/3147/1883 +f 3148/3148/1884 3149/3149/1884 3150/3150/1884 +f 3148/3148/1884 3150/3150/1884 3151/3151/1884 +f 3152/3152/1883 3153/3153/1883 3145/3145/1883 +f 3152/3152/1883 3145/3145/1883 3144/3144/1883 +f 3154/3154/1883 3155/3155/1883 3156/3156/1883 +f 3154/3154/1883 3156/3156/1883 3157/3157/1883 +f 3155/3155/1883 3158/3158/1883 3159/3159/1883 +f 3155/3155/1883 3159/3159/1883 3156/3156/1883 +f 3158/3158/1883 3160/3160/1883 3161/3161/1883 +f 3158/3158/1883 3161/3161/1883 3159/3159/1883 +f 3160/3160/1883 3162/3162/1883 3163/3163/1883 +f 3160/3160/1883 3163/3163/1883 3161/3161/1883 +f 3162/3162/1883 3152/3152/1883 3144/3144/1883 +f 3162/3162/1883 3144/3144/1883 3163/3163/1883 +f 3164/3164/1884 3165/3165/1884 3166/3166/1884 +f 3164/3164/1884 3166/3166/1884 3167/3167/1884 +f 3168/3168/1882 3169/3169/1882 3170/3170/1882 +f 3168/3168/1882 3170/3170/1882 3171/3171/1882 +f 3172/3172/1884 3173/3173/1884 3174/3174/1884 +f 3172/3172/1884 3174/3174/1884 3175/3175/1884 +f 3173/3173/1884 3176/3176/1884 3177/3177/1884 +f 3173/3173/1884 3177/3177/1884 3174/3174/1884 +f 3178/3178/1885 3179/3179/1885 3180/3180/1885 +f 3178/3178/1885 3180/3180/1885 3181/3181/1885 +f 3182/3182/1885 3183/3183/1885 3184/3184/1885 +f 3182/3182/1885 3184/3184/1885 3185/3185/1885 +f 3186/3186/1885 3187/3187/1885 3188/3188/1885 +f 3186/3186/1885 3188/3188/1885 3189/3189/1885 +f 3190/3190/1881 3191/3191/1881 3192/3192/1881 +f 3190/3190/1881 3192/3192/1881 3193/3193/1881 +f 3194/3194/1885 3195/3195/1885 3196/3196/1885 +f 3194/3194/1885 3196/3196/1885 3197/3197/1885 +f 3198/3198/1885 3199/3199/1885 3200/3200/1885 +f 3198/3198/1885 3200/3200/1885 3201/3201/1885 +f 3202/3202/1884 3203/3203/1884 3204/3204/1884 +f 3202/3202/1884 3204/3204/1884 3205/3205/1884 +f 3206/3206/1884 3207/3207/1884 3208/3208/1884 +f 3206/3206/1884 3208/3208/1884 3209/3209/1884 +f 3210/3210/1881 3211/3211/1881 3212/3212/1881 +f 3210/3210/1881 3212/3212/1881 3213/3213/1881 +f 3214/3214/1885 3215/3215/1885 3216/3216/1885 +f 3214/3214/1885 3216/3216/1885 3217/3217/1885 +f 3218/3218/1886 3219/3219/1886 3220/3220/1886 +f 3218/3218/1886 3220/3220/1886 3221/3221/1886 +f 3222/3222/1881 3223/3223/1881 3224/3224/1881 +f 3222/3222/1881 3224/3224/1881 3225/3225/1881 +f 3226/3226/1882 3227/3227/1882 3228/3228/1882 +f 3226/3226/1882 3228/3228/1882 3229/3229/1882 +f 3230/3230/1886 3231/3231/1886 3232/3232/1886 +f 3230/3230/1886 3232/3232/1886 3233/3233/1886 +f 3234/3234/1885 3235/3235/1885 3236/3236/1885 +f 3234/3234/1885 3236/3236/1885 3237/3237/1885 +f 3238/3238/1885 3239/3239/1885 3240/3240/1885 +f 3238/3238/1885 3240/3240/1885 3241/3241/1885 +f 3167/3167/1884 3166/3166/1884 3242/3242/1884 +f 3167/3167/1884 3242/3242/1884 3243/3243/1884 +f 3159/3159/1883 3161/3161/1883 3244/3244/1883 +f 3159/3159/1883 3244/3244/1883 3245/3245/1883 +f 3174/3174/1884 3177/3177/1884 3246/3246/1884 +f 3174/3174/1884 3246/3246/1884 3247/3247/1884 +f 3137/3137/1881 3136/3136/1881 3248/3248/1881 +f 3137/3137/1881 3248/3248/1881 3249/3249/1881 +f 3250/3250/1887 3251/3251/1887 3252/3252/1887 +f 3250/3250/1887 3252/3252/1887 3253/3253/1887 +f 3254/3254/1882 3255/3255/1882 3256/3256/1882 +f 3254/3254/1882 3256/3256/1882 3257/3257/1882 +o Plane.009__0 +v 0.949844 0.476250 -0.309294 +v 0.901524 0.594616 -0.309519 +v 0.899452 0.595572 -0.278623 +v 0.946856 0.477590 -0.278595 +v 0.882372 0.716890 -0.306475 +v 0.881615 0.717182 -0.278243 +v 0.881029 0.716856 -0.272503 +v 0.898722 0.595218 -0.272503 +v 0.945975 0.477313 -0.272503 +v -0.009825 -1.622963 -0.864179 +v -0.009915 -1.620273 -0.864055 +v 0.174507 -1.613991 -0.864055 +v 0.175062 -1.616673 -0.864179 +v -0.009953 -1.619202 -0.863184 +v 0.174281 -1.612916 -0.863184 +v 0.342015 -1.597482 -0.863184 +v 0.342417 -1.598560 -0.864055 +v 0.343400 -1.601213 -0.864179 +v -1.098055 0.216709 -0.856822 +v -1.012679 0.349717 -0.858891 +v -1.010128 0.347468 -0.858766 +v -1.095327 0.214730 -0.856697 +v -0.938578 0.472383 -0.862339 +v -0.935823 0.470265 -0.862215 +v -0.934779 0.469232 -0.861344 +v -1.009037 0.346479 -0.857895 +v -1.094124 0.213862 -0.855826 +v 1.007834 -1.355713 -0.864179 +v 1.005060 -1.353589 -0.864055 +v 1.065448 -1.307098 -0.864055 +v 1.068403 -1.309113 -0.864179 +v 1.003782 -1.352613 -0.863184 +v 1.064061 -1.306154 -0.863184 +v 1.120671 -1.255045 -0.863184 +v 1.122164 -1.255946 -0.864055 +v 1.125290 -1.257838 -0.864179 +v -1.397415 -0.342694 -0.863183 +v -1.352091 -0.212585 -0.862992 +v -1.350564 -0.212975 -0.863829 +v -1.395818 -0.342935 -0.864054 +v -1.289674 -0.070598 -0.861651 +v -1.288239 -0.071145 -0.862253 +v -1.285062 -0.072363 -0.862339 +v -1.347216 -0.213834 -0.863949 +v -1.392343 -0.343462 -0.864179 +v 0.614417 -1.545907 -0.864179 +v 0.612730 -1.543363 -0.864055 +v 0.734890 -1.501220 -0.864055 +v 0.736906 -1.503677 -0.864179 +v 0.612014 -1.542289 -0.863184 +v 0.734016 -1.500162 -0.863184 +v 0.843632 -1.451705 -0.863184 +v 0.844658 -1.452741 -0.864055 +v 0.846974 -1.455090 -0.864179 +v -1.304472 -1.049729 -0.864179 +v -1.357637 -0.928149 -0.864179 +v -1.354176 -0.927149 -0.864054 +v -1.301160 -1.048412 -0.864054 +v -1.395752 -0.802116 -0.864179 +v -1.392185 -0.801447 -0.864054 +v -1.390530 -0.801137 -0.863183 +v -1.352575 -0.926687 -0.863183 +v -1.299638 -1.047808 -0.863183 +v 1.243145 -1.115889 -0.864179 +v 1.239665 -1.114357 -0.864055 +v 1.293954 -1.020980 -0.864054 +v 1.297597 -1.022263 -0.864179 +v 1.237957 -1.113608 -0.863184 +v 1.292147 -1.020345 -0.863183 +v 1.335049 -0.912336 -0.863183 +v 1.336935 -0.912831 -0.864054 +v 1.340707 -0.913825 -0.864179 +v -0.627327 -1.559227 -0.864179 +v -0.740102 -1.522219 -0.864179 +v -0.738337 -1.519748 -0.864055 +v -0.625856 -1.556676 -0.864055 +v -0.848906 -1.474903 -0.864179 +v -0.846852 -1.472539 -0.864055 +v -0.845984 -1.471544 -0.863184 +v -0.737602 -1.518725 -0.863184 +v -0.625253 -1.555636 -0.863184 +v -0.641437 -1.583750 -0.863184 +v -0.756905 -1.545786 -0.863184 +v -0.756170 -1.544763 -0.864055 +v -0.640834 -1.582710 -0.864055 +v -0.868287 -1.497264 -0.863184 +v -0.867418 -1.496269 -0.864055 +v -0.865365 -1.493905 -0.864179 +v -0.754405 -1.542294 -0.864179 +v -0.639363 -1.580159 -0.864179 +v -0.974426 -1.439120 -0.863184 +v -0.973423 -1.438163 -0.864055 +v -1.068215 -1.376980 -0.863184 +v -1.067086 -1.376070 -0.864055 +v -1.064504 -1.373981 -0.864179 +v -0.971090 -1.435931 -0.864179 +v -1.144251 -1.315033 -0.863184 +v -1.143013 -1.314172 -0.864055 +v -1.209886 -1.247010 -0.863184 +v -1.208549 -1.246211 -0.864055 +v -1.205579 -1.244431 -0.864179 +v -1.140224 -1.312229 -0.864179 +v -1.273448 -1.164585 -0.863184 +v -1.272016 -1.163869 -0.864055 +v -1.334405 -1.061651 -0.863183 +v -1.332883 -1.061048 -0.864054 +v -1.329570 -1.059730 -0.864179 +v -1.268870 -1.162293 -0.864179 +v -1.388795 -0.937168 -0.863183 +v -1.387194 -0.936707 -0.864054 +v -1.427792 -0.808136 -0.863183 +v -1.426136 -0.807827 -0.864054 +v -1.422569 -0.807157 -0.864179 +v -1.383734 -0.935707 -0.864179 +v -1.444177 -0.690653 -0.863183 +v -1.442499 -0.690483 -0.864054 +v -1.442026 -0.579157 -0.863183 +v -1.440354 -0.579119 -0.864054 +v -1.436751 -0.579040 -0.864179 +v -1.438889 -0.690116 -0.864179 +v -0.008965 -1.649128 -0.863184 +v -0.200654 -1.644762 -0.863184 +v -0.200504 -1.643697 -0.864055 +v -0.009002 -1.648057 -0.864055 +v -0.375379 -1.631606 -0.863184 +v -0.375055 -1.630549 -0.864055 +v -0.374247 -1.627899 -0.864179 +v -0.200124 -1.641018 -0.864179 +v -0.009092 -1.645366 -0.864179 +v 1.242897 -0.070644 -0.864179 +v 1.239385 -0.071946 -0.864054 +v 1.162000 0.081977 -0.864055 +v 1.165294 0.083696 -0.864179 +v 1.237620 -0.072598 -0.863183 +v 1.160352 0.081119 -0.863183 +v 1.075472 0.216196 -0.863183 +v 1.076992 0.217230 -0.864055 +v 1.080047 0.219313 -0.864179 +v 1.410302 -0.670650 -0.863183 +v 1.408342 -0.670486 -0.864054 +v 1.404451 -0.543610 -0.864055 +v 1.406410 -0.543603 -0.863183 +v 1.404456 -0.670161 -0.864179 +v 1.400573 -0.543623 -0.864179 +v 1.377949 -0.402754 -0.864179 +v 1.381766 -0.402364 -0.864054 +v 1.383693 -0.402167 -0.863183 +v 1.273694 -0.059217 -0.338909 +v 1.194370 0.098807 -0.338269 +v 1.194187 0.098779 -0.282217 +v 1.273602 -0.059251 -0.282297 +v 1.107884 0.237552 -0.333929 +v 1.107030 0.237633 -0.281675 +v 1.106367 0.237277 -0.272503 +v 1.193573 0.098469 -0.272503 +v 1.272958 -0.059489 -0.272503 +v 0.630322 -1.569978 -0.863184 +v 0.629606 -1.568905 -0.864055 +v 0.754822 -1.525586 -0.864055 +v 0.755696 -1.526645 -0.863184 +v 0.627918 -1.566360 -0.864179 +v 0.752806 -1.523130 -0.864179 +v 0.864988 -1.473423 -0.864179 +v 0.867304 -1.475771 -0.864055 +v 0.868330 -1.476807 -0.863184 +v 0.945974 0.477313 -0.863183 +v 0.944688 0.476039 -0.864054 +v 0.897480 0.592880 -0.864054 +v 0.898722 0.594133 -0.863183 +v 0.942039 0.473679 -0.864179 +v 0.894872 0.590984 -0.864179 +v 0.876881 0.706333 -0.864179 +v 0.879676 0.707296 -0.864054 +v 0.881029 0.708170 -0.863183 +v -1.123271 0.235055 -0.857052 +v -1.036442 0.370701 -0.858777 +v -1.035355 0.369709 -0.858876 +v -1.122069 0.234187 -0.856850 +v -0.964334 0.492143 -0.861650 +v -0.963324 0.491083 -0.862253 +v -0.960803 0.488776 -0.862339 +v -1.032833 0.367436 -0.858891 +v -1.119341 0.232208 -0.856822 +v 1.377142 -0.667865 -0.864179 +v 1.373256 -0.667539 -0.864054 +v 1.369470 -0.543726 -0.864055 +v 1.373348 -0.543714 -0.864179 +v 1.371296 -0.667376 -0.863183 +v 1.367512 -0.543733 -0.863183 +v 1.345402 -0.406087 -0.863183 +v 1.347329 -0.405891 -0.864054 +v 1.351145 -0.405501 -0.864179 +v 0.922154 0.459334 -0.864179 +v 0.919245 0.457475 -0.864054 +v 0.870393 0.584193 -0.864054 +v 0.873765 0.584688 -0.864179 +v 0.917788 0.456542 -0.863183 +v 0.868632 0.583892 -0.863183 +v 0.848106 0.709305 -0.863183 +v 0.850359 0.709030 -0.864054 +v 0.854324 0.708320 -0.864179 +v -0.902085 0.720525 -0.863183 +v -0.909357 0.839918 -0.863183 +v -0.908429 0.838933 -0.864054 +v -0.901094 0.719484 -0.864054 +v -0.909357 0.839918 -0.863183 +v -0.926476 0.943632 -0.863183 +v -0.925729 0.943072 -0.864054 +v -0.908429 0.838933 -0.864054 +v -0.925729 0.943072 -0.864054 +v -0.923399 0.942571 -0.864179 +v -0.905636 0.837786 -0.864179 +v -0.898074 0.717971 -0.864179 +v 1.032856 -1.374903 -0.863184 +v 1.031578 -1.373927 -0.864055 +v 1.093381 -1.326186 -0.864055 +v 1.094769 -1.327129 -0.863184 +v 1.028804 -1.371803 -0.864179 +v 1.090427 -1.324170 -0.864179 +v 1.148288 -1.271790 -0.864179 +v 1.151414 -1.273682 -0.864055 +v 1.152907 -1.274583 -0.863184 +v 1.336258 -0.234496 -0.864055 +v 1.338118 -0.234074 -0.863183 +v 1.332566 -0.235334 -0.864179 +v 1.267681 -0.061443 -0.864179 +v 1.271194 -0.060141 -0.864054 +v 1.272958 -0.059489 -0.863183 +v -0.919094 0.605784 -0.862992 +v -0.918098 0.604724 -0.863829 +v -0.915287 0.602756 -0.863949 +v -1.019763 1.112778 -0.272503 +v -1.018785 1.113919 -0.271632 +v -1.029921 1.141555 -0.271752 +v -1.030896 1.140287 -0.272589 +v -1.015553 1.114803 -0.271508 +v -1.026767 1.142273 -0.271632 +v -1.029214 1.148117 -0.272503 +v -1.032092 1.147823 -0.272588 +v -1.032817 1.146430 -0.273001 +v -0.868599 0.714921 -0.271508 +v -0.864439 0.714145 -0.271632 +v -0.884001 0.838098 -0.271632 +v -0.888070 0.838806 -0.271508 +v -0.863286 0.713210 -0.272503 +v -0.882899 0.837152 -0.272503 +v -0.884001 0.838098 -0.271632 +v -0.882899 0.837152 -0.272503 +v -0.922318 0.952601 -0.272503 +v -0.923168 0.953401 -0.271632 +v -0.923168 0.953401 -0.271632 +v -0.926657 0.954201 -0.271508 +v 0.614418 -1.545907 -0.271508 +v 0.736906 -1.503676 -0.271508 +v 0.734890 -1.501221 -0.271633 +v 0.612730 -1.543363 -0.271633 +v 0.846975 -1.455090 -0.271508 +v 0.844658 -1.452741 -0.271633 +v 0.843632 -1.451705 -0.272504 +v 0.734016 -1.500161 -0.272504 +v 0.612014 -1.542288 -0.272504 +v -1.366021 -0.347477 -0.271508 +v -1.362546 -0.348005 -0.271632 +v -1.318357 -0.221262 -0.271632 +v -1.321706 -0.220403 -0.271508 +v -1.360949 -0.348246 -0.272504 +v -1.316830 -0.221652 -0.272503 +v -1.256077 -0.083505 -0.272503 +v -1.257513 -0.082958 -0.271632 +v -1.260690 -0.081740 -0.271508 +v 1.007835 -1.355713 -0.271508 +v 1.068403 -1.309113 -0.271508 +v 1.065449 -1.307098 -0.271633 +v 1.005061 -1.353589 -0.271632 +v 1.125290 -1.257838 -0.271508 +v 1.122164 -1.255946 -0.271632 +v 1.120671 -1.255045 -0.272504 +v 1.064062 -1.306154 -0.272503 +v 1.003782 -1.352613 -0.272504 +v -1.098055 0.216709 -0.271508 +v -1.095327 0.214730 -0.271632 +v -1.010127 0.347468 -0.271633 +v -1.012679 0.349717 -0.271508 +v -1.094124 0.213862 -0.272503 +v -1.009036 0.346479 -0.272503 +v -0.934779 0.469232 -0.272503 +v -0.935822 0.470265 -0.271632 +v -0.938577 0.472383 -0.271508 +v -0.008965 -1.649128 -0.272504 +v 0.180414 -1.642654 -0.272504 +v 0.180189 -1.641579 -0.271633 +v -0.009002 -1.648057 -0.271633 +v 0.352825 -1.626770 -0.272504 +v 0.352422 -1.625691 -0.271633 +v 0.351440 -1.623037 -0.271508 +v 0.179633 -1.638897 -0.271508 +v -0.009092 -1.645366 -0.271508 +v -1.044257 -1.357563 -0.271508 +v -1.041675 -1.355474 -0.271633 +v -1.115789 -1.295172 -0.271633 +v -1.118578 -1.297115 -0.271508 +v -1.040545 -1.354564 -0.272504 +v -1.114551 -1.294312 -0.272503 +v -1.178438 -1.228143 -0.272504 +v -1.179775 -1.228942 -0.271633 +v -1.182745 -1.230721 -0.271508 +v 1.377142 -0.667865 -0.271508 +v 1.373348 -0.543714 -0.271508 +v 1.369470 -0.543726 -0.271633 +v 1.373256 -0.667539 -0.271632 +v 1.351146 -0.405501 -0.271508 +v 1.347329 -0.405891 -0.271632 +v 1.345402 -0.406088 -0.272504 +v 1.367512 -0.543733 -0.272503 +v 1.371296 -0.667376 -0.272504 +v -0.627326 -1.559227 -0.271508 +v -0.625855 -1.556676 -0.271633 +v -0.738337 -1.519748 -0.271633 +v -0.740101 -1.522219 -0.271508 +v -0.625253 -1.555636 -0.272504 +v -0.737602 -1.518725 -0.272504 +v -0.845984 -1.471544 -0.272504 +v -0.846852 -1.472539 -0.271633 +v -0.848905 -1.474903 -0.271508 +v -0.641437 -1.583750 -0.272504 +v -0.640834 -1.582710 -0.271633 +v -0.756170 -1.544763 -0.271633 +v -0.756905 -1.545786 -0.272504 +v -0.639363 -1.580159 -0.271508 +v -0.754405 -1.542294 -0.271508 +v -0.865365 -1.493905 -0.271508 +v -0.867418 -1.496269 -0.271633 +v -0.868287 -1.497264 -0.272504 +v -0.973422 -1.438163 -0.271633 +v -0.974426 -1.439120 -0.272504 +v -0.971090 -1.435931 -0.271508 +v -1.064504 -1.373981 -0.271508 +v -1.067085 -1.376070 -0.271633 +v -1.068215 -1.376980 -0.272504 +v -1.304472 -1.049729 -0.271508 +v -1.301160 -1.048412 -0.271633 +v -1.354176 -0.927149 -0.271633 +v -1.357636 -0.928149 -0.271508 +v -1.299637 -1.047808 -0.272504 +v -1.352575 -0.926687 -0.272503 +v -1.390530 -0.801137 -0.272504 +v -1.392185 -0.801447 -0.271633 +v -1.395752 -0.802116 -0.271508 +v -1.209886 -1.247010 -0.272504 +v -1.208549 -1.246211 -0.271633 +v -1.272016 -1.163869 -0.271633 +v -1.273448 -1.164585 -0.272503 +v -1.205579 -1.244431 -0.271508 +v -1.268870 -1.162292 -0.271508 +v -1.329570 -1.059730 -0.271508 +v -1.332882 -1.061048 -0.271633 +v -1.334404 -1.061651 -0.272504 +v -1.387194 -0.936707 -0.271633 +v -1.388794 -0.937168 -0.272503 +v -1.383733 -0.935707 -0.271508 +v -1.422569 -0.807157 -0.271508 +v -1.426136 -0.807827 -0.271633 +v -1.427792 -0.808136 -0.272504 +v -1.442498 -0.690483 -0.271632 +v -1.444176 -0.690653 -0.272503 +v -1.438888 -0.690116 -0.271508 +v -1.436751 -0.579040 -0.271508 +v -1.440354 -0.579119 -0.271632 +v -1.442026 -0.579157 -0.272504 +v -0.200503 -1.643697 -0.271633 +v -0.200654 -1.644762 -0.272504 +v -0.200124 -1.641018 -0.271508 +v -0.374246 -1.627899 -0.271508 +v -0.375055 -1.630549 -0.271633 +v -0.375379 -1.631606 -0.272504 +v 0.922154 0.459334 -0.271508 +v 0.873765 0.585773 -0.271508 +v 0.870394 0.585278 -0.271632 +v 0.919246 0.457475 -0.271632 +v 0.854324 0.717006 -0.271508 +v 0.850359 0.717716 -0.271632 +v 0.848106 0.717991 -0.272503 +v 0.868632 0.584978 -0.272503 +v 0.917788 0.456542 -0.272503 +v 1.410302 -0.670650 -0.272504 +v 1.406410 -0.543603 -0.272503 +v 1.404451 -0.543610 -0.271632 +v 1.408342 -0.670486 -0.271632 +v 1.383693 -0.402167 -0.272504 +v 1.381766 -0.402364 -0.271632 +v 1.377949 -0.402754 -0.271508 +v 1.400573 -0.543623 -0.271508 +v 1.404456 -0.670161 -0.271508 +v -0.883484 0.591407 -0.271632 +v -0.886993 0.592835 -0.271508 +v -0.882389 0.590424 -0.272503 +v 0.630322 -1.569978 -0.272504 +v 0.755696 -1.526645 -0.272504 +v 0.754822 -1.525586 -0.271633 +v 0.629606 -1.568905 -0.271633 +v 0.868330 -1.476807 -0.272504 +v 0.867305 -1.475771 -0.271633 +v 0.864988 -1.473423 -0.271508 +v 0.752806 -1.523130 -0.271508 +v 0.627918 -1.566359 -0.271508 +v 0.945975 0.477313 -0.272503 +v 0.898722 0.595218 -0.272503 +v 0.897480 0.593966 -0.271632 +v 0.944688 0.476039 -0.271632 +v 0.881029 0.716856 -0.272503 +v 0.879676 0.715981 -0.271632 +v 0.876882 0.715019 -0.271508 +v 0.894872 0.592069 -0.271508 +v 0.942039 0.473679 -0.271508 +v -1.123271 0.235054 -0.272503 +v -1.122068 0.234187 -0.271632 +v -1.035355 0.369709 -0.271633 +v -1.036442 0.370701 -0.272503 +v -1.119341 0.232208 -0.271508 +v -1.032833 0.367436 -0.271508 +v -0.960803 0.488776 -0.271508 +v -0.963324 0.491082 -0.271632 +v -0.964334 0.492143 -0.272503 +v 1.273365 -1.129204 -0.272504 +v 1.329021 -1.033358 -0.272504 +v 1.327214 -1.032722 -0.271632 +v 1.271656 -1.128455 -0.271632 +v 1.373084 -0.922364 -0.272504 +v 1.371197 -0.921869 -0.271632 +v 1.367426 -0.920877 -0.271508 +v 1.323571 -1.031439 -0.271508 +v 1.268176 -1.126925 -0.271508 +v 1.272958 -0.059489 -0.272503 +v 1.193573 0.098469 -0.272503 +v 1.191925 0.097611 -0.271632 +v 1.271194 -0.060142 -0.271632 +v 1.106367 0.237277 -0.272503 +v 1.104848 0.236243 -0.271632 +v 1.101792 0.234160 -0.271508 +v 1.188631 0.095892 -0.271508 +v 1.267681 -0.061443 -0.271508 +v 0.499465 -1.603024 -0.272504 +v 0.498902 -1.601944 -0.271633 +v 0.497550 -1.599334 -0.271508 +v 1.032856 -1.374903 -0.272504 +v 1.094769 -1.327129 -0.272504 +v 1.093382 -1.326186 -0.271632 +v 1.031578 -1.373927 -0.271632 +v 1.152907 -1.274583 -0.272504 +v 1.151415 -1.273682 -0.271632 +v 1.148288 -1.271790 -0.271508 +v 1.090427 -1.324170 -0.271508 +v 1.028804 -1.371803 -0.271508 +v 1.338118 -0.234075 -0.272503 +v 1.336258 -0.234496 -0.271632 +v 1.332566 -0.235334 -0.271508 +v -0.918691 0.604723 -0.271632 +v -0.919687 0.605784 -0.272503 +v -0.915879 0.602756 -0.271508 +v -0.902818 0.717971 -0.271508 +v -0.905838 0.719484 -0.271632 +v -0.906829 0.720525 -0.272503 +v 0.848106 0.709305 -0.863183 +v 0.868632 0.583892 -0.863183 +v 0.867979 0.583797 -0.859686 +v 0.847245 0.709575 -0.858568 +v 0.917788 0.456542 -0.863183 +v 0.917255 0.456201 -0.860217 +v 0.917180 0.456152 -0.851396 +v 0.867886 0.583939 -0.847152 +v 0.847121 0.710854 -0.838205 +v 1.272958 -0.059489 -0.863183 +v 1.193573 0.098469 -0.863183 +v 1.194173 0.098782 -0.859639 +v 1.273602 -0.059251 -0.859608 +v 1.106367 0.237277 -0.863183 +v 1.106920 0.237653 -0.859841 +v 1.106999 0.237706 -0.848389 +v 1.194259 0.098826 -0.846774 +v 1.273694 -0.059216 -0.846524 +v 0.871644 0.892092 -0.863183 +v 0.855215 0.817604 -0.863183 +v 0.854101 0.818262 -0.857096 +v 0.870322 0.893046 -0.855855 +v 0.853942 0.822078 -0.826434 +v 0.870133 0.899387 -0.816505 +v 1.273364 -1.129205 -0.863184 +v 1.329021 -1.033358 -0.863183 +v 1.329678 -1.033588 -0.859596 +v 1.273983 -1.129475 -0.859595 +v 1.373083 -0.922364 -0.863183 +v 1.373771 -0.922544 -0.859597 +v 1.373869 -0.922570 -0.846437 +v 1.329772 -1.033620 -0.846428 +v 1.274071 -1.129514 -0.846420 +v 1.237620 -0.072598 -0.863183 +v 1.301043 -0.242501 -0.863183 +v 1.300362 -0.242656 -0.859603 +v 1.236976 -0.072836 -0.859606 +v 1.345402 -0.406087 -0.863183 +v 1.344697 -0.406159 -0.859601 +v 1.344596 -0.406170 -0.846473 +v 1.300265 -0.242677 -0.846488 +v 1.236884 -0.072870 -0.846506 +v 0.630322 -1.569978 -0.863184 +v 0.755696 -1.526645 -0.863184 +v 0.755995 -1.527006 -0.859591 +v 0.630565 -1.570341 -0.859591 +v 0.868330 -1.476807 -0.863184 +v 0.868685 -1.477164 -0.859591 +v 0.868736 -1.477215 -0.846392 +v 0.756038 -1.527058 -0.846389 +v 0.630599 -1.570393 -0.846387 +v 1.075472 0.216196 -0.863183 +v 1.160352 0.081119 -0.863183 +v 1.159751 0.080807 -0.859631 +v 1.074919 0.215820 -0.859793 +v 1.159666 0.080762 -0.846708 +v 1.074840 0.215767 -0.848003 +v 0.959588 -1.425116 -0.863184 +v 0.959993 -1.425467 -0.859592 +v 1.032856 -1.374903 -0.863184 +v 1.033307 -1.375247 -0.859592 +v 1.033371 -1.375295 -0.846399 +v 0.960050 -1.425517 -0.846395 +v 1.120671 -1.255045 -0.863184 +v 1.064061 -1.306154 -0.863184 +v 1.063569 -1.305820 -0.859593 +v 1.120137 -1.254724 -0.859593 +v 1.064061 -1.306154 -0.863184 +v 1.003782 -1.352613 -0.863184 +v 1.003332 -1.352270 -0.859592 +v 1.063569 -1.305820 -0.859593 +v 1.003268 -1.352221 -0.846396 +v 1.063498 -1.305771 -0.846399 +v 1.063498 -1.305771 -0.846399 +v 1.120061 -1.254677 -0.846404 +v 1.344596 -0.406170 -0.338960 +v 1.366692 -0.543736 -0.338974 +v 1.366795 -0.543736 -0.282305 +v 1.344697 -0.406160 -0.282304 +v 1.370476 -0.667307 -0.338985 +v 1.370579 -0.667315 -0.282307 +v 1.371296 -0.667376 -0.272504 +v 1.367512 -0.543733 -0.272503 +v 1.345402 -0.406088 -0.272504 +v 0.342015 -1.597482 -0.863184 +v 0.174281 -1.612916 -0.863184 +v 0.174207 -1.612562 -0.859590 +v 0.341881 -1.597126 -0.859590 +v -0.009953 -1.619202 -0.863184 +v -0.009965 -1.618851 -0.859590 +v -0.009966 -1.618801 -0.846379 +v 0.174196 -1.612512 -0.846380 +v 0.341862 -1.597074 -0.846381 +v 1.399734 -0.798594 -0.863183 +v 1.400442 -0.798716 -0.859598 +v 1.410302 -0.670650 -0.863183 +v 1.411019 -0.670710 -0.859600 +v 1.411122 -0.670719 -0.846458 +v 1.400542 -0.798734 -0.846447 +v 0.932456 -1.401442 -0.863184 +v 0.932051 -1.401091 -0.859592 +v 0.843632 -1.451705 -0.863184 +v 0.843277 -1.451348 -0.859591 +v 0.843227 -1.451297 -0.846390 +v 0.931993 -1.401041 -0.846392 +v -0.375379 -1.631606 -0.863184 +v -0.375485 -1.631952 -0.859590 +v -0.519016 -1.612071 -0.859590 +v -0.518860 -1.611725 -0.863184 +v -0.375500 -1.632002 -0.846378 +v -0.519038 -1.612120 -0.846377 +v -0.641666 -1.584145 -0.846376 +v -0.641637 -1.584095 -0.859590 +v -0.641437 -1.583750 -0.863184 +v 0.612014 -1.542289 -0.863184 +v 0.484686 -1.574407 -0.863184 +v 0.484497 -1.574046 -0.859591 +v 0.611771 -1.541926 -0.859591 +v 0.484470 -1.573995 -0.846383 +v 0.611736 -1.541874 -0.846385 +v 1.360193 -0.791749 -0.338996 +v 1.360293 -0.791767 -0.282308 +v 1.334264 -0.912130 -0.339005 +v 1.334362 -0.912156 -0.282309 +v 1.335050 -0.912336 -0.272504 +v 1.361001 -0.791889 -0.272504 +v 1.371296 -0.667376 -0.863183 +v 1.361001 -0.791889 -0.863183 +v 1.360293 -0.791767 -0.859597 +v 1.370579 -0.667315 -0.859598 +v 1.335049 -0.912336 -0.863183 +v 1.334362 -0.912156 -0.859596 +v 1.334264 -0.912130 -0.846429 +v 1.360192 -0.791749 -0.846437 +v 1.370476 -0.667307 -0.846448 +v -0.625024 -1.555243 -0.339058 +v -0.625052 -1.555291 -0.282316 +v -0.505841 -1.582486 -0.282316 +v -0.505818 -1.582438 -0.339058 +v -0.625253 -1.555636 -0.272504 +v -0.505996 -1.582832 -0.272504 +v -0.366408 -1.602160 -0.272504 +v -0.366302 -1.601813 -0.282316 +v -0.366286 -1.601764 -0.339057 +v -1.040545 -1.354564 -0.863184 +v -1.040157 -1.354251 -0.859589 +v -0.948927 -1.414672 -0.859589 +v -0.949270 -1.414999 -0.863184 +v -1.040102 -1.354206 -0.846373 +v -0.948878 -1.414626 -0.846374 +v -0.845647 -1.471160 -0.846374 +v -0.845689 -1.471208 -0.859589 +v -0.845984 -1.471544 -0.863184 +v -1.177905 -1.227825 -0.339061 +v -1.177972 -1.227865 -0.282316 +v -1.114122 -1.294014 -0.282316 +v -1.114060 -1.293972 -0.339060 +v -1.178438 -1.228143 -0.272504 +v -1.114551 -1.294312 -0.272503 +v -1.040545 -1.354564 -0.272504 +v -1.040157 -1.354251 -0.282316 +v -1.040102 -1.354206 -0.339060 +v -1.178438 -1.228143 -0.863184 +v -1.177972 -1.227865 -0.859589 +v -1.114122 -1.294014 -0.859589 +v -1.114551 -1.294312 -0.863184 +v -1.177905 -1.227825 -0.846373 +v -1.114060 -1.293972 -0.846373 +v 0.918918 0.450945 -0.309937 +v 0.990953 0.333918 -0.322886 +v 0.990194 0.336414 -0.280294 +v 0.917473 0.455550 -0.278676 +v 1.075135 0.214874 -0.333978 +v 1.074956 0.215709 -0.281681 +v 1.075472 0.216196 -0.272503 +v 0.990588 0.337175 -0.272503 +v 0.917788 0.456542 -0.272503 +v -1.390530 -0.801137 -0.863183 +v -1.389945 -0.801027 -0.859589 +v -1.352011 -0.926525 -0.859589 +v -1.352575 -0.926687 -0.863183 +v -1.389862 -0.801012 -0.846371 +v -1.351930 -0.926501 -0.846372 +v -1.299026 -1.047566 -0.846372 +v -1.299102 -1.047596 -0.859589 +v -1.299638 -1.047808 -0.863183 +v 0.352825 -1.626770 -0.863184 +v 0.499465 -1.603024 -0.863184 +v 0.499653 -1.603384 -0.859591 +v 0.352958 -1.627126 -0.859591 +v 0.499680 -1.603436 -0.846385 +v 0.352978 -1.627178 -0.846383 +v -1.289674 -0.070598 -0.861651 +v -1.290175 -0.070407 -0.858669 +v -1.211436 0.083591 -0.856945 +v -1.210977 0.083344 -0.858777 +v -1.290247 -0.070380 -0.846064 +v -1.211502 0.083626 -0.845490 +v -1.123745 0.235396 -0.845145 +v -1.123686 0.235353 -0.855910 +v -1.123271 0.235055 -0.857052 +v -1.360949 -0.348246 -0.863183 +v -1.360387 -0.348330 -0.859589 +v -1.388880 -0.466538 -0.859589 +v -1.389460 -0.466504 -0.863183 +v -1.360307 -0.348342 -0.846371 +v -1.388797 -0.466544 -0.846371 +v -1.403706 -0.578315 -0.846371 +v -1.403790 -0.578318 -0.859589 +v -1.404380 -0.578331 -0.863183 +v 1.152907 -1.274583 -0.863184 +v 1.213121 -1.209390 -0.863184 +v 1.213697 -1.209691 -0.859594 +v 1.153441 -1.274905 -0.859594 +v 1.213780 -1.209734 -0.846414 +v 1.153517 -1.274951 -0.846408 +v -1.093651 0.213521 -0.339062 +v -1.093710 0.213563 -0.282316 +v -1.179023 0.066022 -0.282316 +v -1.178957 0.065986 -0.339062 +v -1.094124 0.213862 -0.272503 +v -1.179482 0.066268 -0.272503 +v -1.256077 -0.083505 -0.272503 +v -1.255577 -0.083695 -0.282316 +v -1.255505 -0.083723 -0.339062 +v 1.367512 -0.543733 -0.863183 +v 1.366794 -0.543736 -0.859600 +v 1.366692 -0.543736 -0.846459 +v 1.236884 -0.072870 -0.338927 +v 1.300266 -0.242677 -0.338945 +v 1.300363 -0.242655 -0.282302 +v 1.236976 -0.072836 -0.282299 +v 1.301043 -0.242501 -0.272503 +v 1.237620 -0.072598 -0.272503 +v -1.036812 0.371042 -0.856945 +v -1.036442 0.370701 -0.858777 +v -1.036865 0.371091 -0.845489 +v -0.964714 0.492569 -0.846064 +v -0.964667 0.492516 -0.858669 +v -0.964334 0.492143 -0.861650 +v 1.373869 -0.922570 -0.338997 +v 1.400543 -0.798734 -0.338987 +v 1.400442 -0.798716 -0.282307 +v 1.373771 -0.922544 -0.282308 +v 1.411122 -0.670719 -0.338975 +v 1.411020 -0.670710 -0.282305 +v 1.410302 -0.670650 -0.272504 +v 1.399734 -0.798594 -0.272504 +v 1.373084 -0.922364 -0.272504 +v -0.858541 0.713210 -0.863183 +v -0.858256 0.712789 -0.859588 +v -0.881493 0.590026 -0.859364 +v -0.881796 0.590424 -0.862953 +v -0.858215 0.712729 -0.846370 +v -0.881449 0.589969 -0.846179 +v -0.934399 0.468806 -0.844838 +v -0.934447 0.468859 -0.857787 +v -0.934779 0.469232 -0.861344 +v -0.902085 0.720525 -0.863183 +v -0.902370 0.720946 -0.859588 +v -0.909638 0.840371 -0.859603 +v -0.902411 0.721006 -0.846370 +v -0.909760 0.840672 -0.846488 +v -0.927464 0.946125 -0.847309 +v -0.926782 0.944157 -0.859706 +v -0.917641 0.951277 -0.342275 +v -0.921825 0.952136 -0.282718 +v -0.882359 0.836707 -0.282367 +v -0.880157 0.836544 -0.339464 +v -0.863286 0.713210 -0.272503 +v -0.862901 0.712789 -0.282316 +v -0.862169 0.712729 -0.339062 +v -0.008965 -1.649128 -0.863184 +v -0.008953 -1.649478 -0.859590 +v -0.200704 -1.645109 -0.859590 +v -0.200654 -1.644762 -0.863184 +v -0.008951 -1.649528 -0.846380 +v -0.200711 -1.645158 -0.846379 +v -0.891282 0.941632 -0.863183 +v -0.891107 0.941534 -0.859706 +v -0.867486 0.835382 -0.859603 +v -0.867751 0.835782 -0.863183 +v -0.891641 0.943137 -0.847309 +v -0.867517 0.835527 -0.846488 +v -1.360307 -0.348342 -0.339062 +v -1.360387 -0.348330 -0.282316 +v -1.388880 -0.466538 -0.282316 +v -1.388797 -0.466544 -0.339062 +v -1.360949 -0.348246 -0.272504 +v -1.389460 -0.466504 -0.272503 +v -1.404380 -0.578331 -0.272504 +v -1.403790 -0.578318 -0.282316 +v -1.403705 -0.578315 -0.339062 +v 1.237957 -1.113608 -0.863184 +v 1.179300 -1.191625 -0.863184 +v 1.178724 -1.191323 -0.859594 +v 1.237338 -1.113338 -0.859595 +v 1.178641 -1.191280 -0.846409 +v 1.237250 -1.113299 -0.846415 +v -1.021614 1.139430 -0.358513 +v -1.031672 1.145892 -0.284812 +v -1.030977 1.148030 -0.284758 +v -1.020961 1.141611 -0.358469 +v -1.032817 1.146430 -0.273001 +v -1.032092 1.147823 -0.272588 +v -1.030977 1.148030 -0.284758 +v -1.032092 1.147823 -0.272588 +v -1.029214 1.148117 -0.272503 +v -1.028213 1.148182 -0.284741 +v -1.020961 1.141611 -0.358469 +v -1.018245 1.141917 -0.358463 +v -1.442026 -0.579157 -0.863183 +v -1.442616 -0.579170 -0.859589 +v -1.427282 -0.464196 -0.859589 +v -1.426702 -0.464231 -0.863183 +v -1.442701 -0.579172 -0.846371 +v -1.427365 -0.464191 -0.846371 +v -1.398057 -0.342597 -0.846371 +v -1.397976 -0.342609 -0.859589 +v -1.397415 -0.342694 -0.863183 +v -0.930170 1.075013 -0.863183 +v -0.931061 1.076957 -0.860293 +v -0.928796 1.077495 -0.860277 +v -0.927953 1.075632 -0.863098 +v -0.931061 1.076957 -0.860293 +v -0.934392 1.087269 -0.852003 +v -0.932114 1.087652 -0.852003 +v -0.928796 1.077495 -0.860277 +v -0.930829 1.087330 -0.852003 +v -0.927525 1.077271 -0.860228 +v -0.927525 1.077271 -0.860228 +v -0.927023 1.075643 -0.862686 +v -1.068215 -1.376980 -0.863184 +v -1.068604 -1.377293 -0.859589 +v -1.144680 -1.315331 -0.859589 +v -1.144251 -1.315033 -0.863184 +v -1.068659 -1.377337 -0.846374 +v -1.144742 -1.315373 -0.846373 +v -1.210419 -1.247328 -0.846373 +v -1.210352 -1.247288 -0.859589 +v -1.209886 -1.247010 -0.863184 +v -0.954015 1.067869 -0.862686 +v -0.954940 1.069790 -0.860228 +v -0.955185 1.072026 -0.860277 +v -0.953967 1.069427 -0.863098 +v -0.958435 1.081649 -0.852003 +v -0.958550 1.083946 -0.852003 +v -0.955185 1.072026 -0.860277 +v -0.958550 1.083946 -0.852003 +v -0.956043 1.085011 -0.852003 +v -0.952742 1.073272 -0.860293 +v -0.953967 1.069427 -0.863098 +v -0.951653 1.070822 -0.863183 +v -1.008666 0.346138 -0.854411 +v -1.009037 0.346479 -0.857895 +v -1.008613 0.346090 -0.841964 +v -1.093651 0.213521 -0.840240 +v -1.093710 0.213564 -0.852385 +v -1.094124 0.213862 -0.855826 +v -0.196382 -1.614603 -0.282316 +v -0.196375 -1.614553 -0.339056 +v -0.196432 -1.614951 -0.272504 +v -0.009952 -1.619202 -0.272504 +v -0.009965 -1.618851 -0.282316 +v -0.009966 -1.618802 -0.339055 +v -1.009652 1.106304 -0.355433 +v -1.018725 1.111525 -0.284363 +v -1.029763 1.138917 -0.284725 +v -1.019808 1.132632 -0.358205 +v -1.019763 1.112778 -0.272503 +v -1.030896 1.140287 -0.272589 +v -0.757151 -1.546128 -0.859590 +v -0.756905 -1.545786 -0.863184 +v -0.757186 -1.546177 -0.846375 +v -0.868623 -1.497648 -0.846375 +v -0.868581 -1.497600 -0.859589 +v -0.868287 -1.497264 -0.863184 +v -1.389862 -0.801012 -0.339062 +v -1.389945 -0.801027 -0.282316 +v -1.352011 -0.926525 -0.282316 +v -1.351930 -0.926501 -0.339061 +v -1.390530 -0.801137 -0.272504 +v -1.352575 -0.926687 -0.272503 +v -1.299637 -1.047808 -0.272504 +v -1.299102 -1.047596 -0.282316 +v -1.299026 -1.047566 -0.339061 +v 0.341862 -1.597074 -0.339052 +v 0.174196 -1.612512 -0.339054 +v 0.174207 -1.612562 -0.282315 +v 0.341881 -1.597125 -0.282315 +v 0.174282 -1.612916 -0.272504 +v 0.342015 -1.597482 -0.272504 +v -0.737356 -1.518383 -0.859589 +v -0.737602 -1.518725 -0.863184 +v -0.737321 -1.518334 -0.846375 +v -0.625024 -1.555243 -0.846375 +v -0.625053 -1.555291 -0.859589 +v -0.625253 -1.555636 -0.863184 +v -1.334405 -1.061651 -0.863183 +v -1.334940 -1.061863 -0.859589 +v -1.389359 -0.937331 -0.859589 +v -1.388795 -0.937168 -0.863183 +v -1.335017 -1.061893 -0.846372 +v -1.389440 -0.937354 -0.846372 +v -1.428460 -0.808262 -0.846372 +v -1.428377 -0.808246 -0.859589 +v -1.427792 -0.808136 -0.863183 +v -1.398057 -0.342597 -0.339062 +v -1.397976 -0.342609 -0.282316 +v -1.352626 -0.212449 -0.282316 +v -1.352703 -0.212430 -0.339062 +v -1.397415 -0.342694 -0.272504 +v -1.352091 -0.212585 -0.272503 +v -1.289674 -0.070598 -0.272503 +v -1.290175 -0.070408 -0.282316 +v -1.290247 -0.070380 -0.339062 +v 0.945974 0.477313 -0.863183 +v 0.898722 0.594133 -0.863183 +v 0.899165 0.594656 -0.859819 +v 0.946438 0.477791 -0.860401 +v 0.881029 0.708170 -0.863183 +v 0.881516 0.708727 -0.858615 +v 0.881586 0.710047 -0.838585 +v 0.899229 0.594886 -0.848217 +v 0.946504 0.477860 -0.852875 +v -0.366408 -1.602160 -0.863184 +v -0.366302 -1.601813 -0.859590 +v -0.196382 -1.614603 -0.859590 +v -0.196432 -1.614951 -0.863184 +v -0.366287 -1.601764 -0.846377 +v -0.196375 -1.614553 -0.846378 +v 0.907610 0.884823 -0.863183 +v 0.915893 0.915403 -0.863098 +v 0.916680 0.916008 -0.855314 +v 0.908365 0.885394 -0.855858 +v 0.916791 0.920441 -0.862686 +v 0.917212 0.921419 -0.855189 +v 0.917300 0.928997 -0.811688 +v 0.916794 0.923387 -0.812304 +v 0.908473 0.891680 -0.816523 +v -0.964714 0.492569 -0.339062 +v -0.964667 0.492516 -0.282316 +v -0.919978 0.606182 -0.282316 +v -0.919934 0.606239 -0.339062 +v -0.964334 0.492143 -0.272503 +v -0.919687 0.605784 -0.272503 +v -0.906829 0.720525 -0.272503 +v -0.907016 0.720946 -0.282316 +v -0.906365 0.721006 -0.339062 +v 1.019359 0.360733 -0.863183 +v 1.019864 0.361162 -0.860254 +v 1.019936 0.361223 -0.851695 +v 0.990588 0.337175 -0.863183 +v 0.990075 0.336762 -0.860121 +v 0.990001 0.336704 -0.850625 +v 1.383693 -0.402167 -0.863183 +v 1.338118 -0.234074 -0.863183 +v 1.338798 -0.233921 -0.859605 +v 1.384398 -0.402095 -0.859603 +v 1.338895 -0.233899 -0.846504 +v 1.384498 -0.402085 -0.846486 +v 0.352825 -1.626770 -0.863184 +v 0.352422 -1.625691 -0.864055 +v 0.498902 -1.601944 -0.864055 +v 0.499465 -1.603024 -0.863184 +v 0.351439 -1.623037 -0.864179 +v 0.497550 -1.599334 -0.864179 +v -0.886401 0.592835 -0.863949 +v -0.882892 0.591407 -0.863824 +v -0.863855 0.714921 -0.864179 +v -0.859695 0.714145 -0.864054 +v -0.858541 0.713210 -0.863183 +v -0.881796 0.590424 -0.862953 +v 1.184205 -1.194195 -0.271508 +v 1.180902 -1.192462 -0.271633 +v 1.243146 -1.115888 -0.271508 +v 1.239666 -1.114357 -0.271632 +v 1.237957 -1.113608 -0.272504 +v 1.179301 -1.191625 -0.272503 +v 1.213121 -1.209390 -0.272504 +v 1.211519 -1.208552 -0.271632 +v 1.208216 -1.206820 -0.271508 +v 0.907610 0.928253 -0.272503 +v 0.915894 0.966433 -0.272589 +v 0.913811 0.967646 -0.271752 +v 0.905606 0.929108 -0.271632 +v 0.916791 0.972557 -0.273001 +v 0.915058 0.973734 -0.272589 +v 0.911229 0.975667 -0.272503 +v 0.909963 0.969511 -0.271632 +v 0.901935 0.930506 -0.271508 +v -1.425057 -0.464330 -0.271632 +v -1.426702 -0.464231 -0.272503 +v -1.421498 -0.464546 -0.271508 +v -1.392343 -0.343463 -0.271508 +v -1.395817 -0.342935 -0.271632 +v -1.397415 -0.342694 -0.272504 +v -0.988171 1.111596 -0.271508 +v -0.985590 1.111315 -0.271632 +v -0.996275 1.137678 -0.271752 +v -0.999080 1.137926 -0.271632 +v -0.985590 1.111315 -0.271632 +v -0.985430 1.111353 -0.272503 +v -0.995869 1.137655 -0.272589 +v -0.996275 1.137678 -0.271752 +v -0.997487 1.142139 -0.273001 +v -0.998195 1.142521 -0.272589 +v -0.998195 1.142521 -0.272589 +v -1.001374 1.142890 -0.272503 +v 1.080047 0.219312 -0.271508 +v 0.994855 0.340609 -0.271508 +v 0.992002 0.338311 -0.271633 +v 1.076992 0.217230 -0.271632 +v 0.990588 0.337175 -0.272503 +v 1.075472 0.216196 -0.272503 +v 1.340708 -0.913824 -0.271508 +v 1.366790 -0.792888 -0.271508 +v 1.362938 -0.792222 -0.271633 +v 1.336936 -0.912831 -0.271632 +v 1.361001 -0.791889 -0.272504 +v 1.335050 -0.912336 -0.272504 +v 0.959588 -1.425116 -0.272504 +v 0.958428 -1.424109 -0.271632 +v 0.955861 -1.421873 -0.271508 +v 1.306595 -0.241242 -0.271508 +v 1.302903 -0.242080 -0.271633 +v 1.242897 -0.070644 -0.271508 +v 1.239385 -0.071946 -0.271632 +v 1.237620 -0.072598 -0.272503 +v 1.301043 -0.242501 -0.272503 +v -1.289674 -0.070598 -0.272503 +v -1.288239 -0.071145 -0.271632 +v -1.209652 0.082632 -0.271632 +v -1.210976 0.083344 -0.272503 +v -1.285062 -0.072363 -0.271508 +v -1.206688 0.081029 -0.271508 +v 0.879483 0.935174 -0.271508 +v 0.887726 0.973803 -0.271632 +v 0.883079 0.973742 -0.271752 +v 0.874892 0.935393 -0.271632 +v 0.889027 0.979900 -0.272503 +v 0.884442 0.979772 -0.272589 +v 0.881660 0.979632 -0.273001 +v 0.879756 0.973745 -0.272588 +v 0.871644 0.935522 -0.272503 +v -0.518390 -1.610675 -0.271633 +v -0.518860 -1.611725 -0.272504 +v -0.517226 -1.608067 -0.271508 +v 1.165294 0.083696 -0.271508 +v 1.162000 0.081977 -0.271633 +v 1.160352 0.081119 -0.272503 +v -1.409655 -0.578448 -0.271508 +v -1.406052 -0.578368 -0.271632 +v -1.391105 -0.466404 -0.271632 +v -1.394663 -0.466188 -0.271508 +v -1.404380 -0.578331 -0.272504 +v -1.389460 -0.466504 -0.272503 +v 1.019359 0.360732 -0.272503 +v 1.017967 0.359554 -0.271632 +v 1.015146 0.357193 -0.271508 +v 1.399734 -0.798594 -0.272504 +v 1.397797 -0.798260 -0.271632 +v 1.393945 -0.797595 -0.271508 +v -0.009825 -1.622963 -0.271508 +v -0.009915 -1.620273 -0.271633 +v -0.196582 -1.616015 -0.271633 +v -0.196962 -1.618694 -0.271508 +v -0.009952 -1.619202 -0.272504 +v -0.196432 -1.614951 -0.272504 +v -0.366408 -1.602160 -0.272504 +v -0.366731 -1.603216 -0.271633 +v -0.367540 -1.605866 -0.271508 +v -1.241738 -1.148671 -0.271633 +v -1.244884 -1.150248 -0.271508 +v -1.240306 -1.147955 -0.272503 +v -1.408154 -0.686991 -0.271632 +v -1.411764 -0.687358 -0.271508 +v -1.406476 -0.686821 -0.272503 +v -0.950274 -1.415956 -0.271633 +v -0.952605 -1.418187 -0.271508 +v -0.949269 -1.414999 -0.272503 +v -0.506466 -1.583882 -0.271633 +v -0.507629 -1.586491 -0.271508 +v -0.505996 -1.582832 -0.272504 +v 1.297597 -1.022263 -0.271508 +v 1.293954 -1.020980 -0.271633 +v 1.292147 -1.020345 -0.272503 +v -1.143012 -1.314172 -0.271633 +v -1.144251 -1.315033 -0.272503 +v -1.140224 -1.312229 -0.271508 +v 0.343400 -1.601214 -0.271508 +v 0.486600 -1.578095 -0.271508 +v 0.485249 -1.575486 -0.271633 +v 0.342417 -1.598560 -0.271633 +v 0.484686 -1.574407 -0.272504 +v 0.342015 -1.597482 -0.272504 +v -1.180807 0.066981 -0.271632 +v -1.183770 0.068584 -0.271508 +v -1.179482 0.066268 -0.272503 +v 0.936183 -1.404685 -0.271508 +v 0.933616 -1.402448 -0.271633 +v 0.932456 -1.401442 -0.272503 +v -1.350564 -0.212975 -0.271632 +v -1.352091 -0.212585 -0.272503 +v -1.347216 -0.213834 -0.271508 +v 0.175062 -1.616673 -0.271508 +v 0.174507 -1.613991 -0.271633 +v 0.174282 -1.612916 -0.272504 +v -0.923751 0.840539 -0.271632 +v -0.924700 0.841527 -0.272503 +v -0.920916 0.839373 -0.271508 +v -0.955492 0.955271 -0.271508 +v -0.958164 0.955917 -0.271632 +v -0.924700 0.841527 -0.272503 +v -0.923751 0.840539 -0.271632 +v -0.958164 0.955917 -0.271632 +v -0.959077 0.956507 -0.272503 +v 1.180902 -1.192462 -0.864055 +v 1.184205 -1.194195 -0.864179 +v 1.179300 -1.191625 -0.863184 +v 1.211519 -1.208552 -0.864055 +v 1.213121 -1.209390 -0.863184 +v 1.208216 -1.206820 -0.864179 +v 1.268175 -1.126925 -0.864179 +v 1.271655 -1.128455 -0.864055 +v 1.273364 -1.129205 -0.863184 +v 0.907610 0.884823 -0.863183 +v 0.905606 0.885678 -0.864054 +v 0.913811 0.916615 -0.863935 +v 0.915893 0.915403 -0.863098 +v 0.901935 0.887077 -0.864179 +v 0.909962 0.918481 -0.864054 +v 0.911229 0.923551 -0.863183 +v 0.915058 0.921618 -0.863098 +v 0.916791 0.920441 -0.862686 +v -1.426702 -0.464231 -0.863183 +v -1.425057 -0.464330 -0.864054 +v -1.421499 -0.464546 -0.864179 +v -0.923912 1.055517 -0.864179 +v -0.928658 1.071753 -0.864054 +v -0.926462 1.072467 -0.863935 +v -0.921552 1.056050 -0.864054 +v -0.930170 1.075013 -0.863183 +v -0.927953 1.075632 -0.863098 +v -0.927023 1.075643 -0.862686 +v -0.925658 1.072806 -0.863098 +v -0.920810 1.056374 -0.863183 +v 0.992002 0.338311 -0.864054 +v 0.994855 0.340609 -0.864179 +v 0.990588 0.337175 -0.863183 +v 1.362938 -0.792222 -0.864054 +v 1.366790 -0.792889 -0.864179 +v 1.361001 -0.791889 -0.863183 +v 0.958427 -1.424109 -0.864055 +v 0.959588 -1.425116 -0.863184 +v 0.955861 -1.421873 -0.864179 +v 1.302903 -0.242080 -0.864055 +v 1.306594 -0.241242 -0.864179 +v 1.301043 -0.242501 -0.863183 +v -1.210977 0.083344 -0.858777 +v -1.209652 0.082632 -0.858876 +v -1.206688 0.081029 -0.858891 +v 0.879483 0.891744 -0.864179 +v 0.874892 0.891963 -0.864054 +v 0.883079 0.922712 -0.863935 +v 0.887726 0.922773 -0.864054 +v 0.871644 0.892092 -0.863183 +v 0.879755 0.922714 -0.863098 +v 0.881660 0.927516 -0.862686 +v 0.884441 0.927656 -0.863098 +v 0.889027 0.927784 -0.863183 +v -0.518860 -1.611725 -0.863184 +v -0.518390 -1.610675 -0.864055 +v -0.517227 -1.608067 -0.864179 +v 1.191925 0.097611 -0.864055 +v 1.193573 0.098469 -0.863183 +v 1.188631 0.095892 -0.864179 +v 1.101792 0.234161 -0.864179 +v 1.104848 0.236243 -0.864055 +v 1.106367 0.237277 -0.863183 +v -1.409655 -0.578448 -0.864179 +v -1.394664 -0.466188 -0.864179 +v -1.391105 -0.466404 -0.864054 +v -1.406052 -0.578368 -0.864054 +v -1.366021 -0.347477 -0.864179 +v -1.362546 -0.348005 -0.864054 +v -1.360949 -0.348246 -0.863183 +v -1.389460 -0.466504 -0.863183 +v -1.404380 -0.578331 -0.863183 +v 1.017967 0.359554 -0.864054 +v 1.019359 0.360733 -0.863183 +v 1.015146 0.357193 -0.864179 +v 1.373083 -0.922364 -0.863183 +v 1.371197 -0.921869 -0.864054 +v 1.397797 -0.798261 -0.864054 +v 1.399734 -0.798594 -0.863183 +v 1.367425 -0.920877 -0.864179 +v 1.393945 -0.797595 -0.864179 +v -0.196962 -1.618694 -0.864179 +v -0.196583 -1.616015 -0.864055 +v -0.367540 -1.605866 -0.864179 +v -0.366732 -1.603216 -0.864055 +v -0.366408 -1.602160 -0.863184 +v -0.196432 -1.614951 -0.863184 +v -1.182745 -1.230721 -0.864179 +v -1.244884 -1.150248 -0.864179 +v -1.241739 -1.148672 -0.864055 +v -1.179775 -1.228942 -0.864055 +v -1.240306 -1.147955 -0.863184 +v -1.178438 -1.228143 -0.863184 +v -1.411764 -0.687359 -0.864179 +v -1.408154 -0.686992 -0.864054 +v -1.406476 -0.686821 -0.863183 +v -0.952605 -1.418187 -0.864179 +v -0.950274 -1.415956 -0.864055 +v -1.044257 -1.357563 -0.864179 +v -1.041676 -1.355474 -0.864055 +v -1.040545 -1.354564 -0.863184 +v -0.949270 -1.414999 -0.863184 +v -0.507630 -1.586491 -0.864179 +v -0.506467 -1.583882 -0.864055 +v -0.505996 -1.582832 -0.863184 +v 1.327214 -1.032722 -0.864054 +v 1.329021 -1.033358 -0.863183 +v 1.323571 -1.031439 -0.864179 +v -1.118578 -1.297115 -0.864179 +v -1.115789 -1.295172 -0.864055 +v -1.114551 -1.294312 -0.863184 +v 0.485249 -1.575486 -0.864055 +v 0.486600 -1.578095 -0.864179 +v 0.484686 -1.574407 -0.863184 +v -1.260690 -0.081740 -0.862339 +v -1.183770 0.068584 -0.858891 +v -1.180807 0.066981 -0.858766 +v -1.257513 -0.082958 -0.862215 +v -1.179483 0.066269 -0.857895 +v -1.256078 -0.083505 -0.861344 +v 0.933616 -1.402448 -0.864055 +v 0.936182 -1.404685 -0.864179 +v 0.932456 -1.401442 -0.863184 +v -1.321706 -0.220403 -0.863949 +v -1.318357 -0.221262 -0.863825 +v -1.316831 -0.221651 -0.862954 +v 0.180188 -1.641579 -0.864055 +v 0.180413 -1.642655 -0.863184 +v 0.179633 -1.638898 -0.864179 +v -0.872940 0.837408 -0.864179 +v -0.868873 0.836721 -0.864054 +v -0.895764 0.943016 -0.864179 +v -0.892282 0.942378 -0.864054 +v -0.891282 0.941632 -0.863183 +v -0.867751 0.835782 -0.863183 +v -1.001374 1.142890 -0.272503 +v -1.000450 1.142802 -0.284741 +v -1.007153 1.143124 -0.284741 +v -1.007811 1.143354 -0.272503 +v -0.991397 1.137976 -0.358462 +v -0.997721 1.138003 -0.358463 +v -1.005554 1.138634 -0.358462 +v -1.015360 1.144151 -0.284741 +v -1.015875 1.144487 -0.272503 +v 0.889099 0.980238 -0.304036 +v 0.889090 0.980196 -0.277938 +v 0.894063 0.980354 -0.277938 +v 0.894072 0.980396 -0.304039 +v 0.889027 0.979900 -0.272503 +v 0.894001 0.980055 -0.272503 +v 0.899475 0.979571 -0.272503 +v 0.899535 0.979872 -0.277938 +v 0.899543 0.979916 -0.304039 +v 0.889027 0.927784 -0.863183 +v 0.889090 0.929165 -0.855250 +v 0.894063 0.929323 -0.855249 +v 0.894001 0.927939 -0.863183 +v 0.889099 0.936808 -0.811659 +v 0.894071 0.936966 -0.811656 +v 0.899543 0.936485 -0.811656 +v 0.899534 0.928842 -0.855249 +v 0.899474 0.927455 -0.863183 +v 1.189604 -1.197032 -0.271508 +v 1.248783 -1.118372 -0.271508 +v 1.130452 -1.260969 -0.271508 +v 1.136790 -1.264814 -0.271508 +v 1.196211 -1.200507 -0.271508 +v 1.255661 -1.121407 -0.271508 +v 1.202817 -1.203982 -0.271508 +v 1.262539 -1.124440 -0.271508 +v 1.143127 -1.268659 -0.271508 +v -0.894035 0.594569 -0.271508 +v -0.943721 0.475856 -0.271508 +v -0.877240 0.714996 -0.271508 +v -0.887664 0.715183 -0.271508 +v -0.902632 0.596870 -0.271508 +v -0.950090 0.480256 -0.271508 +v -0.910333 0.599865 -0.271508 +v -0.956160 0.484899 -0.271508 +v -0.896622 0.716317 -0.271508 +v 1.312464 -0.239907 -0.271508 +v 1.248495 -0.068566 -0.271508 +v 1.357204 -0.404880 -0.271508 +v 1.364548 -0.404127 -0.271508 +v 1.319581 -0.238288 -0.271508 +v 1.255289 -0.066044 -0.271508 +v 1.326697 -0.236669 -0.271508 +v 1.262083 -0.063521 -0.271508 +v 1.371891 -0.403375 -0.271508 +v 1.073336 -1.312485 -0.271508 +v 1.012522 -1.359308 -0.271508 +v 1.018319 -1.363758 -0.271508 +v 1.079415 -1.316641 -0.271508 +v 1.085494 -1.320798 -0.271508 +v 1.024117 -1.368208 -0.271508 +v -0.896516 0.838630 -0.271508 +v -0.933820 0.954562 -0.271508 +v -0.942505 0.954680 -0.271508 +v -0.906611 0.838264 -0.271508 +v -0.915117 0.838519 -0.271508 +v -0.950119 0.954867 -0.271508 +v 1.170562 0.086448 -0.271508 +v 1.084952 0.222661 -0.271508 +v 1.176963 0.089794 -0.271508 +v 1.090920 0.226737 -0.271508 +v 1.183363 0.093140 -0.271508 +v 1.096887 0.230812 -0.271508 +v 1.303454 -1.024332 -0.271508 +v 1.346739 -0.915415 -0.271508 +v 1.310584 -1.026851 -0.271508 +v 1.354067 -0.917350 -0.271508 +v 1.317714 -1.029371 -0.271508 +v 1.361394 -0.919285 -0.271508 +v -1.017183 0.353632 -0.271508 +v -1.102791 0.220156 -0.271508 +v -1.022806 0.358536 -0.271508 +v -1.108698 0.224458 -0.271508 +v -1.028391 0.363470 -0.271508 +v -1.114604 0.228761 -0.271508 +v 0.878941 0.586517 -0.271508 +v 0.859989 0.715771 -0.271508 +v 0.926780 0.462322 -0.271508 +v 0.932312 0.466105 -0.271508 +v 0.884924 0.587803 -0.271508 +v 0.866358 0.714700 -0.271508 +v 0.890513 0.589819 -0.271508 +v 0.872267 0.714480 -0.271508 +v 0.937702 0.470149 -0.271508 +v 0.740439 -1.507996 -0.271508 +v 0.850985 -1.459169 -0.271508 +v 0.617412 -1.550440 -0.271508 +v 0.621168 -1.556133 -0.271508 +v 0.744856 -1.513403 -0.271508 +v 0.855981 -1.464256 -0.271508 +v 0.749274 -1.518810 -0.271508 +v 0.860978 -1.469343 -0.271508 +v 0.624925 -1.561827 -0.271508 +v 0.862401 0.842587 -0.271508 +v 0.867955 0.841317 -0.271508 +v 0.884669 0.934793 -0.271508 +v 0.874114 0.839829 -0.271508 +v 0.890388 0.933911 -0.271508 +v 0.880192 0.838505 -0.271508 +v 0.896510 0.932307 -0.271508 +v 0.885231 0.837618 -0.271508 +v 1.379502 -0.543693 -0.271508 +v 1.383315 -0.668384 -0.271508 +v 1.390799 -0.669013 -0.271508 +v 1.386961 -0.543668 -0.271508 +v 1.394419 -0.543643 -0.271508 +v 1.398283 -0.669642 -0.271508 +v 0.999447 0.344315 -0.271508 +v 1.005028 0.348850 -0.271508 +v 1.010591 0.353419 -0.271508 +v -1.400664 -0.465821 -0.271508 +v -1.415716 -0.578580 -0.271508 +v -1.371903 -0.346581 -0.271508 +v -1.379181 -0.345470 -0.271508 +v -1.408081 -0.465367 -0.271508 +v -1.423203 -0.578743 -0.271508 +v -1.415497 -0.464913 -0.271508 +v -1.430689 -0.578907 -0.271508 +v -1.386460 -0.344359 -0.271508 +v -1.417833 -0.687976 -0.271508 +v -1.401751 -0.803244 -0.271508 +v -1.425326 -0.688737 -0.271508 +v -1.409161 -0.804637 -0.271508 +v -1.432819 -0.689499 -0.271508 +v -1.416570 -0.806030 -0.271508 +v -1.363472 -0.929838 -0.271508 +v -1.310081 -1.051963 -0.271508 +v -1.370685 -0.931928 -0.271508 +v -1.317021 -1.054729 -0.271508 +v -1.377897 -0.934017 -0.271508 +v -1.323961 -1.057496 -0.271508 +v -0.197659 -1.623616 -0.271508 +v -0.009663 -1.627904 -0.271508 +v -0.369020 -1.610726 -0.271508 +v -0.370893 -1.616883 -0.271508 +v -0.198543 -1.629856 -0.271508 +v -0.009458 -1.634165 -0.271508 +v -0.199426 -1.636096 -0.271508 +v -0.009254 -1.640426 -0.271508 +v -0.372767 -1.623039 -0.271508 +v -1.123399 -1.300480 -0.271508 +v -1.048759 -1.361213 -0.271508 +v -1.187837 -1.233778 -0.271508 +v -1.194161 -1.237576 -0.271508 +v -1.129401 -1.304672 -0.271508 +v -1.054380 -1.365772 -0.271508 +v -1.135403 -1.308864 -0.271508 +v -1.060001 -1.370331 -0.271508 +v -1.200487 -1.241375 -0.271508 +v -0.956709 -1.422125 -0.271508 +v -0.852554 -1.479114 -0.271508 +v -0.961847 -1.427060 -0.271508 +v -0.857135 -1.484404 -0.271508 +v -0.966986 -1.431993 -0.271508 +v -0.861716 -1.489695 -0.271508 +v -0.743268 -1.526660 -0.271508 +v -0.629987 -1.563853 -0.271508 +v -0.747253 -1.532256 -0.271508 +v -0.633345 -1.569693 -0.271508 +v -0.751239 -1.537852 -0.271508 +v -0.636703 -1.575534 -0.271508 +v -0.509748 -1.591254 -0.271508 +v -0.512428 -1.597279 -0.271508 +v -0.515107 -1.603304 -0.271508 +v 1.372924 -0.793951 -0.271508 +v 1.380368 -0.795241 -0.271508 +v 1.387811 -0.796532 -0.271508 +v -1.250239 -1.152936 -0.271508 +v -1.256876 -1.156270 -0.271508 +v -1.263515 -1.159605 -0.271508 +v 0.176072 -1.621577 -0.271508 +v 0.345177 -1.606035 -0.271508 +v 0.177348 -1.627786 -0.271508 +v 0.347420 -1.612126 -0.271508 +v 0.178623 -1.633993 -0.271508 +v 0.349663 -1.618217 -0.271508 +v -1.327402 -0.218937 -0.271508 +v -1.266126 -0.079649 -0.271508 +v -1.272876 -0.077051 -0.271508 +v -1.334461 -0.217118 -0.271508 +v -1.341519 -0.215300 -0.271508 +v -1.279625 -0.074454 -0.271508 +v 0.940573 -1.408517 -0.271508 +v 0.946022 -1.413279 -0.271508 +v 0.951471 -1.418040 -0.271508 +v -1.188877 0.071355 -0.271508 +v -1.195230 0.074806 -0.271508 +v -1.201582 0.078257 -0.271508 +v 0.489024 -1.582795 -0.271508 +v 0.492076 -1.588715 -0.271508 +v 0.495126 -1.594636 -0.271508 +v -1.004817 1.138613 -0.271632 +v -0.993521 1.112449 -0.271508 +v -1.007811 1.143354 -0.272503 +v -1.015875 1.144487 -0.272503 +v -1.012451 1.139833 -0.271632 +v -1.000887 1.113594 -0.271508 +v -1.020439 1.141413 -0.271632 +v -1.008988 1.114580 -0.271508 +v -1.023498 1.146547 -0.272503 +v 1.189604 -1.197032 -0.864179 +v 1.130452 -1.260969 -0.864179 +v 1.248782 -1.118373 -0.864179 +v 1.255660 -1.121407 -0.864179 +v 1.196211 -1.200507 -0.864179 +v 1.136789 -1.264814 -0.864179 +v 1.202817 -1.203982 -0.864179 +v 1.143126 -1.268659 -0.864179 +v 1.262539 -1.124440 -0.864179 +v -0.893442 0.594569 -0.863949 +v -0.872496 0.714996 -0.864179 +v -0.943721 0.475856 -0.862339 +v -0.950091 0.480257 -0.862339 +v -0.902039 0.596870 -0.863949 +v -0.882919 0.715183 -0.864179 +v -0.909739 0.599865 -0.863949 +v -0.891878 0.716317 -0.864179 +v -0.956160 0.484899 -0.862339 +v 1.312463 -0.239907 -0.864179 +v 1.357203 -0.404880 -0.864179 +v 1.248495 -0.068567 -0.864179 +v 1.255289 -0.066043 -0.864179 +v 1.319580 -0.238288 -0.864179 +v 1.364547 -0.404127 -0.864179 +v 1.326697 -0.236668 -0.864179 +v 1.371891 -0.403374 -0.864179 +v 1.262083 -0.063520 -0.864179 +v 1.073336 -1.312485 -0.864179 +v 1.012522 -1.359308 -0.864179 +v 1.079415 -1.316642 -0.864179 +v 1.018319 -1.363758 -0.864179 +v 1.085494 -1.320798 -0.864179 +v 1.024116 -1.368208 -0.864179 +v -0.881384 0.837192 -0.864179 +v -0.902906 0.943053 -0.864179 +v -0.891456 0.836771 -0.864179 +v -0.911409 0.942745 -0.864179 +v -0.899903 0.836973 -0.864179 +v -0.918555 0.942497 -0.864179 +v 1.170562 0.086449 -0.864179 +v 1.084952 0.222661 -0.864179 +v 1.090919 0.226737 -0.864179 +v 1.176962 0.089794 -0.864179 +v 1.183362 0.093140 -0.864179 +v 1.096887 0.230812 -0.864179 +v 1.303454 -1.024332 -0.864179 +v 1.346739 -0.915415 -0.864179 +v 1.354066 -0.917350 -0.864179 +v 1.310584 -1.026851 -0.864179 +v 1.317713 -1.029371 -0.864179 +v 1.361394 -0.919285 -0.864179 +v -1.017183 0.353632 -0.858891 +v -1.102792 0.220156 -0.856822 +v -1.108698 0.224458 -0.856822 +v -1.022806 0.358536 -0.858891 +v -1.028391 0.363471 -0.858891 +v -1.114604 0.228761 -0.856822 +v 0.878941 0.585431 -0.864179 +v 0.926780 0.462322 -0.864179 +v 0.859989 0.707085 -0.864179 +v 0.866358 0.706014 -0.864179 +v 0.884924 0.586718 -0.864179 +v 0.932312 0.466105 -0.864179 +v 0.890513 0.588733 -0.864179 +v 0.937702 0.470149 -0.864179 +v 0.872267 0.705795 -0.864179 +v 0.740438 -1.507996 -0.864179 +v 0.617411 -1.550440 -0.864179 +v 0.850985 -1.459169 -0.864179 +v 0.855981 -1.464256 -0.864179 +v 0.744856 -1.513403 -0.864179 +v 0.621168 -1.556133 -0.864179 +v 0.749273 -1.518810 -0.864179 +v 0.624924 -1.561827 -0.864179 +v 0.860978 -1.469343 -0.864179 +v 0.892729 0.922854 -0.864054 +v 0.884669 0.891363 -0.864179 +v 0.894001 0.927939 -0.863183 +v 0.899474 0.927455 -0.863183 +v 0.898236 0.922316 -0.864054 +v 0.890388 0.890481 -0.864179 +v 0.904369 0.920648 -0.864054 +v 0.896510 0.888877 -0.864179 +v 0.905609 0.925777 -0.863183 +v 1.379502 -0.543693 -0.864179 +v 1.383315 -0.668384 -0.864179 +v 1.386961 -0.543668 -0.864179 +v 1.390799 -0.669013 -0.864179 +v 1.394419 -0.543643 -0.864179 +v 1.398283 -0.669642 -0.864179 +v 0.999447 0.344316 -0.864179 +v 1.005028 0.348851 -0.864179 +v 1.010590 0.353419 -0.864179 +v -1.400664 -0.465821 -0.864179 +v -1.371903 -0.346580 -0.864179 +v -1.415717 -0.578580 -0.864179 +v -1.423203 -0.578743 -0.864179 +v -1.408081 -0.465367 -0.864179 +v -1.379182 -0.345470 -0.864179 +v -1.415498 -0.464913 -0.864179 +v -1.386460 -0.344359 -0.864179 +v -1.430690 -0.578907 -0.864179 +v -1.417833 -0.687976 -0.864179 +v -1.401751 -0.803244 -0.864179 +v -1.409161 -0.804637 -0.864179 +v -1.425327 -0.688737 -0.864179 +v -1.432819 -0.689499 -0.864179 +v -1.416570 -0.806030 -0.864179 +v -1.363472 -0.929839 -0.864179 +v -1.310081 -1.051964 -0.864179 +v -1.317021 -1.054729 -0.864179 +v -1.370685 -0.931928 -0.864179 +v -1.377898 -0.934017 -0.864179 +v -1.323962 -1.057496 -0.864179 +v -0.197660 -1.623616 -0.864179 +v -0.369020 -1.610726 -0.864179 +v -0.009664 -1.627904 -0.864179 +v -0.009459 -1.634165 -0.864179 +v -0.198543 -1.629857 -0.864179 +v -0.370893 -1.616883 -0.864179 +v -0.199427 -1.636096 -0.864179 +v -0.372767 -1.623039 -0.864179 +v -0.009254 -1.640426 -0.864179 +v -1.123399 -1.300480 -0.864179 +v -1.187837 -1.233778 -0.864179 +v -1.048759 -1.361213 -0.864179 +v -1.054380 -1.365772 -0.864179 +v -1.129401 -1.304672 -0.864179 +v -1.194162 -1.237576 -0.864179 +v -1.135404 -1.308864 -0.864179 +v -1.200487 -1.241375 -0.864179 +v -1.060002 -1.370331 -0.864179 +v -0.956709 -1.422125 -0.864179 +v -0.852554 -1.479114 -0.864179 +v -0.857135 -1.484404 -0.864179 +v -0.961848 -1.427059 -0.864179 +v -0.966987 -1.431993 -0.864179 +v -0.861717 -1.489695 -0.864179 +v -0.743268 -1.526660 -0.864179 +v -0.629988 -1.563853 -0.864179 +v -0.633345 -1.569693 -0.864179 +v -0.747253 -1.532256 -0.864179 +v -0.751239 -1.537851 -0.864179 +v -0.636703 -1.575534 -0.864179 +v -0.509749 -1.591253 -0.864179 +v -0.512428 -1.597279 -0.864179 +v -0.515108 -1.603304 -0.864179 +v 1.372924 -0.793951 -0.864179 +v 1.380368 -0.795241 -0.864179 +v 1.387811 -0.796533 -0.864179 +v -1.250239 -1.152936 -0.864179 +v -1.256877 -1.156270 -0.864179 +v -1.263515 -1.159605 -0.864179 +v 0.176072 -1.621577 -0.864179 +v 0.345177 -1.606035 -0.864179 +v 0.347420 -1.612126 -0.864179 +v 0.177347 -1.627785 -0.864179 +v 0.178623 -1.633993 -0.864179 +v 0.349662 -1.618217 -0.864179 +v -1.327402 -0.218937 -0.863949 +v -1.266127 -0.079649 -0.862339 +v -1.334461 -0.217118 -0.863949 +v -1.272876 -0.077051 -0.862339 +v -1.341520 -0.215300 -0.863949 +v -1.279625 -0.074453 -0.862339 +v 0.940573 -1.408517 -0.864179 +v 0.946022 -1.413279 -0.864179 +v 0.951471 -1.418040 -0.864179 +v -1.188877 0.071355 -0.858891 +v -1.195230 0.074806 -0.858891 +v -1.201582 0.078258 -0.858891 +v 0.489024 -1.582795 -0.864179 +v 0.492075 -1.588715 -0.864179 +v 0.495126 -1.594636 -0.864179 +v -0.913556 1.015090 -0.864179 +v -0.919352 1.014883 -0.864179 +v -0.928695 1.054776 -0.864179 +v -0.926455 1.014343 -0.864179 +v -0.934883 1.053804 -0.864179 +v -0.932783 1.013517 -0.864179 +v -0.940983 1.052577 -0.864179 +v -0.937187 1.012642 -0.864179 +v -0.945460 1.051084 -0.864179 +v -0.947533 1.048098 -0.863183 +v -0.952128 1.063763 -0.863098 +v -0.951855 1.065280 -0.863935 +v -0.947287 1.049421 -0.864054 +v -0.952128 1.063763 -0.863098 +v -0.954015 1.067869 -0.862686 +v -0.951855 1.065280 -0.863935 +v -0.949800 1.067003 -0.864054 +v -0.947287 1.049421 -0.864054 +v 0.905670 0.978194 -0.277938 +v 0.905678 0.978237 -0.304036 +v 0.905610 0.977893 -0.272503 +v 0.911229 0.975667 -0.272503 +v 0.911291 0.975966 -0.277937 +v 0.911300 0.976008 -0.304030 +v 0.905669 0.927164 -0.855250 +v 0.905609 0.925777 -0.863183 +v 0.905678 0.934807 -0.811659 +v 0.911299 0.932578 -0.811665 +v 0.911291 0.924935 -0.855250 +v 0.911229 0.923551 -0.863183 +v -0.943969 1.085137 -0.852003 +v -0.940608 1.074219 -0.860293 +v -0.947232 1.073698 -0.860293 +v -0.950554 1.085055 -0.852003 +v -0.940608 1.074219 -0.860293 +v -0.939816 1.072305 -0.863183 +v -0.946329 1.071558 -0.863183 +v -0.947232 1.073698 -0.860293 +v -0.951653 1.070822 -0.863183 +v -0.952742 1.073272 -0.860293 +v -1.022789 1.146348 -0.284741 +v -1.023498 1.146547 -0.272503 +v -1.012842 1.140411 -0.358463 +v 1.406410 -0.543603 -0.863183 +v 1.407126 -0.543601 -0.859601 +v 1.407229 -0.543600 -0.846471 +v 1.274071 -1.129514 -0.339013 +v 1.329772 -1.033620 -0.339005 +v 1.329678 -1.033587 -0.282309 +v 1.273983 -1.129475 -0.282310 +v 1.329021 -1.033358 -0.272504 +v 1.273365 -1.129204 -0.272504 +v -0.935014 1.075564 -0.860293 +v -0.938370 1.086126 -0.852003 +v -0.934188 1.073663 -0.863183 +v -0.935014 1.075564 -0.860293 +v -1.405883 -0.686761 -0.282316 +v -1.405798 -0.686752 -0.339062 +v -1.406476 -0.686821 -0.272503 +v 0.917300 0.972427 -0.304007 +v 0.915188 0.974019 -0.304020 +v 0.915164 0.973988 -0.277952 +v 0.917212 0.972449 -0.277999 +v 0.915058 0.973734 -0.272589 +v 0.916791 0.972557 -0.273001 +v -1.210418 -1.247328 -0.339061 +v -1.210352 -1.247288 -0.282316 +v -1.273949 -1.164835 -0.282316 +v -1.274021 -1.164871 -0.339061 +v -1.209886 -1.247010 -0.272504 +v -1.273448 -1.164585 -0.272503 +v -1.334404 -1.061651 -0.272504 +v -1.334940 -1.061863 -0.282316 +v -1.335016 -1.061893 -0.339061 +v 1.022443 0.360563 -0.322727 +v 1.020177 0.361079 -0.280275 +v 1.019359 0.360732 -0.272503 +v -0.948927 -1.414672 -0.282316 +v -0.948878 -1.414626 -0.339060 +v -0.949269 -1.414999 -0.272503 +v -0.845984 -1.471544 -0.272504 +v -0.845689 -1.471208 -0.282316 +v -0.845647 -1.471160 -0.339059 +v -1.389359 -0.937331 -0.282316 +v -1.389440 -0.937354 -0.339061 +v -1.388794 -0.937168 -0.272503 +v -1.427792 -0.808136 -0.272504 +v -1.428377 -0.808246 -0.282316 +v -1.428460 -0.808262 -0.339061 +v -0.737356 -1.518384 -0.282316 +v -0.737321 -1.518334 -0.339059 +v -0.737602 -1.518725 -0.272504 +v -0.008951 -1.649528 -0.339054 +v -0.008952 -1.649478 -0.282316 +v -0.200704 -1.645109 -0.282316 +v -0.200711 -1.645158 -0.339055 +v -0.008965 -1.649128 -0.272504 +v -0.200654 -1.644762 -0.272504 +v -0.375379 -1.631606 -0.272504 +v -0.375484 -1.631952 -0.282316 +v -0.375500 -1.632002 -0.339056 +v -1.239804 -1.147705 -0.282316 +v -1.239732 -1.147669 -0.339061 +v -1.240306 -1.147955 -0.272503 +v -1.178438 -1.228143 -0.272504 +v -1.177972 -1.227865 -0.282316 +v -1.177905 -1.227825 -0.339061 +v -0.641666 -1.584145 -0.339058 +v -0.641637 -1.584095 -0.282316 +v -0.757151 -1.546128 -0.282316 +v -0.757186 -1.546177 -0.339058 +v -0.641437 -1.583750 -0.272504 +v -0.756905 -1.545786 -0.272504 +v -0.868287 -1.497264 -0.272504 +v -0.868580 -1.497600 -0.282316 +v -0.868623 -1.497648 -0.339059 +v -1.316295 -0.221788 -0.282316 +v -1.316218 -0.221807 -0.339062 +v -1.316830 -0.221652 -0.272503 +v -0.519016 -1.612071 -0.282316 +v -0.519038 -1.612120 -0.339057 +v -0.518860 -1.611725 -0.272504 +v -0.934399 0.468806 -0.339062 +v -0.934447 0.468859 -0.282316 +v -1.008666 0.346138 -0.282316 +v -1.008613 0.346089 -0.339062 +v -0.934779 0.469232 -0.272503 +v -1.009036 0.346479 -0.272503 +v 0.916791 0.920441 -0.862686 +v 0.915058 0.921618 -0.863098 +v 0.915164 0.922957 -0.855236 +v 0.917212 0.921419 -0.855189 +v 0.915188 0.930589 -0.811675 +v 0.917300 0.928997 -0.811688 +v -1.068659 -1.377337 -0.339060 +v -1.068604 -1.377293 -0.282316 +v -1.144680 -1.315331 -0.282316 +v -1.144741 -1.315373 -0.339060 +v -1.068215 -1.376980 -0.272504 +v -1.144251 -1.315033 -0.272503 +v -1.209886 -1.247010 -0.272504 +v -1.210352 -1.247288 -0.282316 +v -1.210418 -1.247328 -0.339061 +v -0.977827 1.106811 -0.355147 +v -0.985558 1.110820 -0.284327 +v -0.959582 1.047266 -0.283522 +v -0.953406 1.044824 -0.348703 +v -0.959652 1.047746 -0.272503 +v -1.442701 -0.579172 -0.339062 +v -1.442616 -0.579170 -0.282316 +v -1.427282 -0.464196 -0.282316 +v -1.427365 -0.464191 -0.339062 +v -1.442026 -0.579157 -0.272504 +v -1.426702 -0.464231 -0.272503 +v -0.882073 0.590026 -0.282316 +v -0.881944 0.589969 -0.339062 +v -0.882389 0.590424 -0.272503 +v 1.292147 -1.020345 -0.863183 +v 1.291490 -1.020114 -0.859595 +v 1.291396 -1.020082 -0.846421 +v -1.211436 0.083591 -0.282316 +v -1.211502 0.083626 -0.339062 +v -1.210976 0.083344 -0.272503 +v -1.123271 0.235054 -0.272503 +v -1.123686 0.235353 -0.282316 +v -1.123745 0.235396 -0.339062 +v -0.920810 1.056374 -0.863183 +v -0.921008 1.057682 -0.860175 +v -0.909916 1.015443 -0.859941 +v -0.909891 1.014822 -0.863183 +v -0.923809 1.065972 -0.851064 +v -0.911593 1.020386 -0.849187 +v 1.291396 -1.020082 -0.339012 +v 1.291490 -1.020114 -0.282310 +v 1.237250 -1.113299 -0.339019 +v 1.237339 -1.113338 -0.282311 +v 1.237957 -1.113608 -0.272504 +v 1.292147 -1.020345 -0.272503 +v 0.908473 0.927871 -0.303970 +v 0.916794 0.965912 -0.303991 +v 0.916680 0.965975 -0.277948 +v 0.908365 0.927919 -0.277930 +v 0.917300 0.972427 -0.304007 +v 0.917212 0.972449 -0.277999 +v 0.916791 0.972557 -0.273001 +v 0.915894 0.966433 -0.272589 +v 0.907610 0.928253 -0.272503 +v -0.924664 0.841928 -0.282368 +v -0.922504 0.841862 -0.339473 +v -0.958713 0.956616 -0.282727 +v -0.954303 0.955644 -0.342347 +v -1.179023 0.066022 -0.854411 +v -1.179483 0.066269 -0.857895 +v -1.178957 0.065987 -0.841964 +v -1.255506 -0.083722 -0.844838 +v -1.255577 -0.083695 -0.857788 +v -1.256078 -0.083505 -0.861344 +v 0.843227 -1.451297 -0.339044 +v 0.733674 -1.499748 -0.339046 +v 0.733717 -1.499800 -0.282315 +v 0.843278 -1.451348 -0.282314 +v 0.611736 -1.541874 -0.339049 +v 0.611771 -1.541926 -0.282315 +v 0.612014 -1.542288 -0.272504 +v 0.734016 -1.500161 -0.272504 +v 0.843632 -1.451705 -0.272504 +v -1.036812 0.371042 -0.282316 +v -1.036865 0.371090 -0.339062 +v -1.036442 0.370701 -0.272503 +v 1.033371 -1.375295 -0.339035 +v 1.095331 -1.327512 -0.339030 +v 1.095261 -1.327464 -0.282313 +v 1.033307 -1.375247 -0.282313 +v 1.153518 -1.274951 -0.339025 +v 1.153441 -1.274905 -0.282312 +v 1.152907 -1.274583 -0.272504 +v 1.094769 -1.327129 -0.272504 +v 1.032856 -1.374903 -0.272504 +v 0.868736 -1.477215 -0.339042 +v 0.960051 -1.425517 -0.339038 +v 0.959993 -1.425467 -0.282314 +v 0.868685 -1.477164 -0.282314 +v 0.959588 -1.425116 -0.272504 +v 0.868330 -1.476807 -0.272504 +v -0.947978 1.048930 -0.860175 +v -0.952697 1.064848 -0.860262 +v -0.951142 1.058559 -0.851064 +v -0.956256 1.076269 -0.851886 +v 1.094769 -1.327129 -0.863184 +v 1.095261 -1.327465 -0.859593 +v 1.152907 -1.274583 -0.863184 +v 1.153441 -1.274905 -0.859594 +v 1.153517 -1.274951 -0.846408 +v 1.095331 -1.327512 -0.846403 +v -1.316295 -0.221787 -0.859364 +v -1.316831 -0.221651 -0.862954 +v -1.316219 -0.221807 -0.846179 +v -0.919397 0.606182 -0.859474 +v -0.919094 0.605784 -0.862992 +v -0.919440 0.606239 -0.846332 +v 0.180413 -1.642655 -0.863184 +v 0.180488 -1.643008 -0.859590 +v 0.180499 -1.643058 -0.846381 +v -1.405883 -0.686761 -0.859589 +v -1.406476 -0.686821 -0.863183 +v -1.405798 -0.686752 -0.846371 +v 1.407229 -0.543600 -0.338962 +v 1.407127 -0.543601 -0.282304 +v 1.384498 -0.402085 -0.338947 +v 1.384398 -0.402095 -0.282302 +v 1.383693 -0.402167 -0.272504 +v 1.406410 -0.543603 -0.272503 +v -1.239804 -1.147705 -0.859589 +v -1.240306 -1.147955 -0.863184 +v -1.239733 -1.147669 -0.846372 +v -1.177905 -1.227825 -0.846373 +v -1.177972 -1.227865 -0.859589 +v -1.178438 -1.228143 -0.863184 +v -1.352626 -0.212449 -0.859474 +v -1.352091 -0.212585 -0.862992 +v -1.352703 -0.212429 -0.846333 +v -0.505841 -1.582486 -0.859590 +v -0.505996 -1.582832 -0.863184 +v -0.505818 -1.582438 -0.846376 +v -1.444769 -0.690714 -0.859589 +v -1.444177 -0.690653 -0.863183 +v -1.444854 -0.690722 -0.846371 +v -1.444769 -0.690713 -0.282316 +v -1.444854 -0.690722 -0.339061 +v -1.444176 -0.690653 -0.272503 +v -1.209886 -1.247010 -0.863184 +v -1.210352 -1.247288 -0.859589 +v -1.273950 -1.164835 -0.859589 +v -1.273448 -1.164585 -0.863184 +v -1.210419 -1.247328 -0.846373 +v -1.274022 -1.164871 -0.846373 +v 0.734016 -1.500162 -0.863184 +v 0.733716 -1.499800 -0.859591 +v 0.733674 -1.499748 -0.846387 +v -0.974768 -1.439445 -0.859589 +v -0.974426 -1.439120 -0.863184 +v -0.974817 -1.439492 -0.846374 +v -0.974768 -1.439445 -0.282316 +v -0.974817 -1.439492 -0.339059 +v -0.974426 -1.439120 -0.272504 +v 1.003268 -1.352221 -0.339038 +v 0.931993 -1.401041 -0.339041 +v 0.932051 -1.401091 -0.282314 +v 1.003332 -1.352270 -0.282313 +v 0.932456 -1.401442 -0.272503 +v 1.003782 -1.352613 -0.272504 +v 0.484470 -1.573995 -0.339051 +v 0.484498 -1.574046 -0.282315 +v 0.484686 -1.574407 -0.272504 +v 0.180499 -1.643058 -0.339052 +v 0.180489 -1.643008 -0.282315 +v 0.352978 -1.627178 -0.339051 +v 0.352959 -1.627126 -0.282315 +v 0.352825 -1.626770 -0.272504 +v 0.180414 -1.642654 -0.272504 +v 1.178642 -1.191280 -0.339025 +v 1.178724 -1.191323 -0.282312 +v 1.120061 -1.254677 -0.339030 +v 1.120137 -1.254723 -0.282312 +v 1.120671 -1.255045 -0.272504 +v 1.179301 -1.191625 -0.272503 +v 1.063499 -1.305771 -0.339034 +v 1.063569 -1.305820 -0.282313 +v 1.063499 -1.305771 -0.339034 +v 1.063569 -1.305820 -0.282313 +v 1.064062 -1.306154 -0.272503 +v 1.064062 -1.306154 -0.272503 +v 0.630600 -1.570393 -0.339047 +v 0.756038 -1.527058 -0.339044 +v 0.755996 -1.527006 -0.282314 +v 0.630565 -1.570341 -0.282315 +v 0.755696 -1.526645 -0.272504 +v 0.630322 -1.569978 -0.272504 +v 0.499680 -1.603436 -0.339049 +v 0.499654 -1.603384 -0.282315 +v 0.499465 -1.603024 -0.272504 +v 1.159703 0.080651 -0.338293 +v 1.159756 0.080793 -0.282220 +v 1.160352 0.081119 -0.272503 +v 1.153518 -1.274951 -0.339025 +v 1.213780 -1.209734 -0.339020 +v 1.213697 -1.209691 -0.282311 +v 1.153441 -1.274905 -0.282312 +v 1.213121 -1.209390 -0.272504 +v 1.152907 -1.274583 -0.272504 +v 0.884441 0.927656 -0.863098 +v 0.884422 0.929024 -0.855234 +v 0.881660 0.927516 -0.862686 +v 0.881013 0.928744 -0.855187 +v 0.880880 0.936374 -0.811675 +v 0.884404 0.936665 -0.811665 +v 1.338896 -0.233898 -0.338929 +v 1.338798 -0.233921 -0.282300 +v 1.338118 -0.234075 -0.272503 +v 0.870133 0.935579 -0.303991 +v 0.854015 0.843492 -0.304362 +v 0.854110 0.843739 -0.277979 +v 0.870322 0.935571 -0.277932 +v 0.847707 0.715686 -0.307079 +v 0.847318 0.717779 -0.278318 +v 0.848106 0.717991 -0.272503 +v 0.855216 0.843662 -0.272503 +v 0.871644 0.935522 -0.272503 +v 0.884404 0.980095 -0.304030 +v 0.884422 0.980054 -0.277953 +v 0.880880 0.979804 -0.304021 +v 0.881014 0.979774 -0.278001 +v 0.881660 0.979632 -0.273001 +v 0.884442 0.979772 -0.272589 +v -0.997136 1.142380 -0.284757 +v -0.988242 1.137693 -0.358460 +v -0.998195 1.142521 -0.272589 +v -0.997487 1.142139 -0.273001 +v -0.996450 1.141656 -0.284803 +v -0.988242 1.137693 -0.358460 +v -0.997136 1.142380 -0.284757 +v -0.996450 1.141656 -0.284803 +v -0.987621 1.136971 -0.358442 +v 0.905145 0.937210 -0.609671 +v 0.908933 0.935072 -0.609709 +v 0.914406 0.944178 -0.714392 +v 0.910530 0.946186 -0.714365 +v 0.910969 0.933403 -0.609761 +v 0.916508 0.942576 -0.714430 +v 0.893336 0.976717 -0.361374 +v 0.888366 0.976584 -0.361365 +v 0.898801 0.976209 -0.361374 +v 0.893608 0.950263 -0.426095 +v 0.888183 0.950964 -0.426095 +v 0.883230 0.951009 -0.426083 +v -0.998388 1.128177 -0.523801 +v -0.998927 1.126055 -0.523940 +v -0.995748 1.128855 -0.523781 +v -0.998388 1.128177 -0.523801 +v -0.975816 1.125262 -0.691309 +v -0.978415 1.124353 -0.691347 +v -0.978415 1.124353 -0.691347 +v -0.978913 1.122218 -0.691610 +v -0.946072 1.110754 -0.836276 +v -0.942014 1.111301 -0.836276 +v -0.951694 1.110591 -0.836276 +v -0.960301 1.139747 -0.818544 +v -0.954655 1.139084 -0.818544 +v -0.950516 1.139035 -0.818544 +v 1.273694 -0.059216 -0.785427 +v 1.338895 -0.233898 -0.784076 +v 1.338895 -0.233898 -0.818907 +v 1.273694 -0.059216 -0.819124 +v 1.384498 -0.402085 -0.783824 +v 1.384498 -0.402085 -0.818834 +v 0.917180 0.456152 -0.816812 +v 0.867763 0.584063 -0.791920 +v 0.867871 0.584226 -0.821427 +v 0.917179 0.456152 -0.834618 +v 0.846138 0.711844 -0.743387 +v 0.846998 0.713150 -0.794113 +v -1.405798 -0.686752 -0.466422 +v -1.403706 -0.578315 -0.466422 +v -1.389861 -0.801012 -0.466422 +v -1.389862 -0.801012 -0.601053 +v -1.405798 -0.686752 -0.601054 +v -1.403705 -0.578315 -0.601054 +v -1.389862 -0.801012 -0.783365 +v -1.351930 -0.926501 -0.783365 +v -1.351930 -0.926501 -0.818504 +v -1.389862 -0.801012 -0.818504 +v -1.299026 -1.047566 -0.783366 +v -1.299026 -1.047566 -0.818505 +v 0.890942 0.837303 -0.304265 +v 0.890618 0.835555 -0.363888 +v 0.907805 0.924709 -0.361752 +v 0.882857 0.717451 -0.372328 +v 0.879952 0.718643 -0.466877 +v 0.887562 0.822978 -0.441847 +v 0.903132 0.902575 -0.430437 +v -0.009966 -1.618801 -0.783393 +v 0.174196 -1.612512 -0.783398 +v 0.174196 -1.612512 -0.818528 +v -0.009966 -1.618801 -0.818524 +v 0.341862 -1.597074 -0.783404 +v 0.341862 -1.597074 -0.818532 +v -0.845647 -1.471160 -0.783375 +v -0.737321 -1.518334 -0.783377 +v -0.737321 -1.518334 -0.818512 +v -0.845648 -1.471160 -0.818511 +v -0.625024 -1.555242 -0.783379 +v -0.625024 -1.555243 -0.818514 +v -1.442701 -0.579173 -0.783364 +v -1.427365 -0.464191 -0.783364 +v -1.427365 -0.464191 -0.818503 +v -1.442701 -0.579172 -0.818504 +v -1.398057 -0.342597 -0.783363 +v -1.398057 -0.342597 -0.818503 +v -0.505818 -1.582437 -0.466410 +v -0.625024 -1.555243 -0.466412 +v -0.366286 -1.601764 -0.466408 +v -0.366287 -1.601764 -0.601033 +v -0.505818 -1.582438 -0.601036 +v -0.625024 -1.555242 -0.601039 +v -0.375500 -1.632002 -0.783389 +v -0.519038 -1.612120 -0.783385 +v -0.519038 -1.612120 -0.818518 +v -0.375500 -1.632001 -0.818521 +v -0.641666 -1.584145 -0.783382 +v -0.641666 -1.584145 -0.818516 +v -0.974817 -1.439492 -0.466415 +v -0.868623 -1.497648 -0.466414 +v -1.068659 -1.377337 -0.466417 +v -1.068659 -1.377337 -0.601046 +v -0.974817 -1.439492 -0.601044 +v -0.868623 -1.497648 -0.601042 +v -1.068659 -1.377337 -0.783373 +v -1.144742 -1.315373 -0.783371 +v -1.144742 -1.315373 -0.818508 +v -1.068659 -1.377337 -0.818510 +v -1.210419 -1.247328 -0.783370 +v -1.210419 -1.247328 -0.818507 +v -1.008613 0.346089 -0.466424 +v -0.934399 0.468806 -0.466424 +v -1.093650 0.213521 -0.466424 +v -1.093651 0.213521 -0.601056 +v -1.008613 0.346089 -0.601056 +v -0.934399 0.468806 -0.601056 +v -0.519038 -1.612120 -0.466408 +v -0.375500 -1.632001 -0.466405 +v -0.641666 -1.584145 -0.466410 +v -0.641666 -1.584145 -0.601037 +v -0.519038 -1.612120 -0.601034 +v -0.375500 -1.632002 -0.601030 +v -1.178957 0.065986 -0.466424 +v -1.255506 -0.083723 -0.466423 +v -1.255506 -0.083723 -0.601055 +v -1.178957 0.065986 -0.601056 +v -0.948215 1.138713 -0.818544 +v -0.939728 1.111344 -0.836277 +v -0.947011 1.137805 -0.818544 +v -0.938508 1.110815 -0.836276 +v -0.986911 1.132378 -0.357999 +v -0.965584 1.122943 -0.522416 +v -0.967123 1.127481 -0.523722 +v -0.957406 1.098631 -0.513985 +v -0.938739 1.096418 -0.675938 +v -0.946508 1.120833 -0.689193 +v -0.949118 1.125821 -0.691227 +v -0.875126 0.836337 -0.467612 +v -0.907436 0.949621 -0.475925 +v -0.860588 0.712729 -0.466424 +v -0.859006 0.712729 -0.601057 +v -0.870136 0.836275 -0.602926 +v -0.897562 0.949124 -0.616016 +v -1.290247 -0.070380 -0.783363 +v -1.211502 0.083626 -0.783362 +v -1.211501 0.083626 -0.818392 +v -1.290247 -0.070380 -0.818464 +v -1.123745 0.235396 -0.783362 +v -1.123745 0.235396 -0.818349 +v 1.063498 -1.305771 -0.466342 +v 1.003268 -1.352221 -0.466353 +v 1.120061 -1.254677 -0.466330 +v 1.063498 -1.305771 -0.466342 +v 1.120061 -1.254677 -0.600925 +v 1.063498 -1.305771 -0.600942 +v 1.063498 -1.305771 -0.600942 +v 1.003268 -1.352221 -0.600958 +v 1.120061 -1.254677 -0.783494 +v 1.178641 -1.191280 -0.783514 +v 1.178641 -1.191280 -0.818611 +v 1.120061 -1.254677 -0.818596 +v 1.237250 -1.113298 -0.783537 +v 1.237250 -1.113299 -0.818627 +v -1.211501 0.083626 -0.466424 +v -1.290247 -0.070380 -0.466423 +v -1.123745 0.235396 -0.466424 +v -1.123745 0.235396 -0.601056 +v -1.211502 0.083626 -0.601056 +v -1.290247 -0.070380 -0.601055 +v -0.937293 1.039867 -0.494933 +v -0.922184 1.038411 -0.645947 +v 1.334263 -0.912130 -0.783594 +v 1.360192 -0.791749 -0.783629 +v 1.360192 -0.791749 -0.818694 +v 1.334264 -0.912130 -0.818668 +v 1.370476 -0.667307 -0.783669 +v 1.370476 -0.667307 -0.818723 +v 0.914406 0.970236 -0.361320 +v 0.910530 0.972244 -0.361347 +v 0.916508 0.968635 -0.361282 +v 0.910969 0.942088 -0.425967 +v 0.908933 0.943758 -0.426019 +v 0.905145 0.945896 -0.426057 +v -1.274021 -1.164871 -0.466419 +v -1.210419 -1.247327 -0.466419 +v -1.335017 -1.061893 -0.466420 +v -1.335017 -1.061893 -0.601051 +v -1.274021 -1.164871 -0.601050 +v -1.210419 -1.247328 -0.601049 +v -0.997397 1.119902 -0.523042 +v -0.989212 1.095793 -0.514856 +v -0.977664 1.116255 -0.690293 +v -0.971084 1.092793 -0.677469 +v -0.919737 0.606239 -0.466424 +v -0.964714 0.492569 -0.466424 +v -0.904783 0.721006 -0.466424 +v -0.903202 0.721006 -0.601056 +v -0.919539 0.606239 -0.601056 +v -0.964714 0.492569 -0.601056 +v 1.095331 -1.327512 -0.466331 +v 1.153518 -1.274951 -0.466317 +v 1.033371 -1.375295 -0.466344 +v 1.033371 -1.375295 -0.600945 +v 1.095331 -1.327512 -0.600927 +v 1.153518 -1.274951 -0.600907 +v 1.033371 -1.375295 -0.783474 +v 0.960051 -1.425517 -0.783459 +v 0.960050 -1.425517 -0.818572 +v 1.033371 -1.375295 -0.818582 +v 0.868736 -1.477215 -0.783446 +v 0.868736 -1.477215 -0.818562 +v 1.344596 -0.406170 -0.783770 +v 1.300265 -0.242677 -0.784014 +v 1.300266 -0.242677 -0.818862 +v 1.344596 -0.406170 -0.818795 +v 1.236884 -0.072870 -0.785356 +v 1.236884 -0.072870 -0.819072 +v -0.930682 0.955709 -0.789322 +v -0.951489 1.046751 -0.801231 +v -0.946428 1.031509 -0.827424 +v -0.928984 0.950635 -0.821476 +v -0.966754 1.106763 -0.813067 +v -0.958519 1.081226 -0.833362 +v -0.941896 1.017963 -0.849187 +v 0.756038 -1.527058 -0.466372 +v 0.868736 -1.477215 -0.466364 +v 0.630599 -1.570393 -0.466379 +v 0.630599 -1.570393 -0.600993 +v 0.756038 -1.527058 -0.600984 +v 0.868736 -1.477215 -0.600972 +v -1.388797 -0.466543 -0.466423 +v -1.360307 -0.348342 -0.466423 +v -1.388797 -0.466544 -0.601054 +v -1.360307 -0.348342 -0.601055 +v -1.036865 0.371090 -0.466424 +v -1.036866 0.371090 -0.601056 +v 0.630599 -1.570393 -0.783425 +v 0.499680 -1.603436 -0.783417 +v 0.499680 -1.603436 -0.818541 +v 0.630599 -1.570393 -0.818547 +v 0.352978 -1.627178 -0.783409 +v 0.352978 -1.627177 -0.818536 +v -1.351930 -0.926501 -0.466421 +v -1.299026 -1.047566 -0.466421 +v -1.299026 -1.047566 -0.601052 +v -1.351930 -0.926501 -0.601052 +v 0.850992 0.825048 -0.683159 +v 0.853573 0.828964 -0.758627 +v 0.865227 0.904333 -0.633648 +v 0.869519 0.910863 -0.728857 +v -1.114060 -1.293972 -0.466419 +v -1.177905 -1.227825 -0.466419 +v -1.040102 -1.354207 -0.466417 +v -1.040102 -1.354207 -0.601047 +v -1.114060 -1.293972 -0.601049 +v -1.177905 -1.227825 -0.601050 +v -1.427365 -0.464191 -0.466422 +v -1.442701 -0.579172 -0.466422 +v -1.398057 -0.342597 -0.466423 +v -1.398057 -0.342597 -0.601054 +v -1.427365 -0.464191 -0.601054 +v -1.442701 -0.579172 -0.601054 +v -0.737321 -1.518334 -0.466414 +v -0.845647 -1.471160 -0.466415 +v -0.737321 -1.518334 -0.601042 +v -0.845647 -1.471160 -0.601044 +v -1.389440 -0.937354 -0.466421 +v -1.428460 -0.808262 -0.466421 +v -1.428460 -0.808262 -0.601052 +v -1.389440 -0.937354 -0.601052 +v 1.360192 -0.791749 -0.466232 +v 1.334264 -0.912130 -0.466257 +v 1.370476 -0.667307 -0.466203 +v 1.370476 -0.667307 -0.600748 +v 1.360192 -0.791749 -0.600789 +v 1.334264 -0.912130 -0.600824 +v -1.144742 -1.315373 -0.466418 +v -1.210419 -1.247327 -0.466419 +v -1.210419 -1.247328 -0.601049 +v -1.144742 -1.315373 -0.601047 +v 0.174196 -1.612512 -0.466398 +v -0.009966 -1.618801 -0.466402 +v 0.341862 -1.597074 -0.466394 +v 0.341862 -1.597074 -0.601015 +v 0.174196 -1.612512 -0.601020 +v -0.009966 -1.618801 -0.601025 +v -0.757186 -1.546177 -0.466412 +v -0.757186 -1.546177 -0.601040 +v 0.931993 -1.401041 -0.466363 +v 0.843227 -1.451297 -0.466371 +v 0.931993 -1.401041 -0.600971 +v 0.843227 -1.451297 -0.600982 +v 1.400543 -0.798734 -0.466207 +v 1.411122 -0.670719 -0.466174 +v 1.373869 -0.922570 -0.466235 +v 1.373869 -0.922570 -0.600794 +v 1.400543 -0.798734 -0.600754 +v 1.411122 -0.670719 -0.600708 +v 0.484470 -1.573995 -0.466390 +v 0.611736 -1.541874 -0.466384 +v 0.611736 -1.541874 -0.601001 +v 0.484470 -1.573995 -0.601008 +v 0.180499 -1.643059 -0.466395 +v 0.352978 -1.627177 -0.466390 +v -0.008951 -1.649528 -0.466399 +v -0.008951 -1.649528 -0.601021 +v 0.180499 -1.643058 -0.601015 +v 0.352978 -1.627178 -0.601009 +v 1.178641 -1.191280 -0.466315 +v 1.237250 -1.113298 -0.466299 +v 1.237250 -1.113298 -0.600882 +v 1.178641 -1.191280 -0.600905 +v 0.960051 -1.425517 -0.466354 +v 0.960051 -1.425517 -0.600959 +v 1.300266 -0.242677 -0.466108 +v 1.344596 -0.406170 -0.466130 +v 1.236884 -0.072870 -0.466216 +v 1.236884 -0.072870 -0.601966 +v 1.300266 -0.242677 -0.600767 +v 1.344596 -0.406170 -0.600648 +v 0.499680 -1.603436 -0.466385 +v 0.499680 -1.603436 -0.601002 +v 1.159894 0.080305 -0.464906 +v 1.076667 0.212108 -0.453900 +v 1.079685 0.208128 -0.594810 +v 1.160271 0.079808 -0.603190 +v 1.213780 -1.209734 -0.466301 +v 1.274071 -1.129514 -0.466282 +v 1.153518 -1.274951 -0.466317 +v 1.153518 -1.274951 -0.600907 +v 1.213780 -1.209734 -0.600885 +v 1.274071 -1.129514 -0.600859 +v 0.947230 0.478568 -0.765400 +v 0.899246 0.593633 -0.717616 +v 0.899745 0.593875 -0.641117 +v 0.947450 0.479882 -0.718795 +v 0.877507 0.697172 -0.648472 +v 0.878678 0.704635 -0.569126 +v 0.892289 0.623908 -0.505816 +v 0.905954 0.572843 -0.536576 +v 0.912292 0.548478 -0.640304 +v 0.943191 0.480644 -0.692092 +v 1.338895 -0.233898 -0.466064 +v 1.273695 -0.059217 -0.466164 +v 1.384499 -0.402085 -0.466092 +v 1.384498 -0.402085 -0.600594 +v 1.338895 -0.233898 -0.600705 +v 1.273694 -0.059217 -0.601895 +v 0.878211 0.973782 -0.304008 +v 0.877493 0.970254 -0.361356 +v 0.869520 0.932578 -0.361813 +v 0.880880 0.979804 -0.304021 +v 0.880150 0.976193 -0.361320 +v 0.875035 0.950912 -0.426020 +v 0.872470 0.945558 -0.426546 +v 0.865227 0.911572 -0.430520 +v -0.958153 1.111457 -0.836276 +v -0.963532 1.112204 -0.836277 +v -0.971902 1.143099 -0.818544 +v -0.966633 1.141562 -0.818544 +v -0.968194 1.128147 -0.523774 +v -0.971014 1.128109 -0.523781 +v -0.987621 1.136971 -0.358442 +v -0.967123 1.127481 -0.523722 +v -0.949118 1.125821 -0.691227 +v -0.950723 1.126638 -0.691299 +v -0.953229 1.126433 -0.691309 +v 0.869454 0.578841 -0.310851 +v 0.868176 0.584110 -0.278790 +v 0.868632 0.584978 -0.272503 +v 0.733674 -1.499748 -0.466378 +v 0.733674 -1.499748 -0.600992 +v -0.894371 0.951244 -0.789225 +v -0.867859 0.836540 -0.784094 +v -0.867682 0.836007 -0.818871 +v -0.892961 0.946981 -0.821464 +v -0.858215 0.712729 -0.783361 +v -0.858215 0.712729 -0.818501 +v -0.939939 1.012185 -0.859941 +v -0.939574 1.011525 -0.863183 +v -0.927023 1.075643 -0.862686 +v -0.927525 1.077271 -0.860228 +v -0.925904 1.074346 -0.860262 +v -0.925658 1.072806 -0.863098 +v -0.930829 1.087330 -0.852003 +v -0.929158 1.084126 -0.851886 +v -0.995460 1.137030 -0.284700 +v -0.939128 1.011954 -0.864054 +v -0.939128 1.011954 -0.864054 +v -0.939816 1.072305 -0.863183 +v -0.938654 1.069371 -0.864054 +v -0.944912 1.068279 -0.864054 +v -0.946329 1.071558 -0.863183 +v -0.932896 1.070615 -0.864054 +v -0.934188 1.073663 -0.863183 +v -0.976533 1.050162 -0.271508 +v -0.984223 1.050646 -0.271508 +v -0.990144 1.050770 -0.271508 +v -0.962932 1.048665 -0.271508 +v -0.968851 1.049426 -0.271508 +v -0.910724 1.015003 -0.864054 +v -0.910724 1.015003 -0.864054 +v -0.921552 1.056050 -0.864054 +v -0.892282 0.942378 -0.864054 +v -0.960060 1.048091 -0.271632 +v -0.960060 1.048091 -0.271632 +v -0.993260 1.049602 -0.283547 +v -0.986264 1.046540 -0.348909 +v -0.994004 1.050189 -0.272503 +v -0.959077 0.956507 -0.272503 +v -0.993073 1.050524 -0.271632 +v -0.994004 1.050189 -0.272503 +v 0.853693 0.841397 -0.364176 +v 0.847960 0.712724 -0.374132 +v 0.850893 0.829301 -0.442265 +v 0.845350 0.712570 -0.469544 +v -0.196375 -1.614553 -0.466405 +v -0.196375 -1.614553 -0.601030 +v 0.878404 0.973775 -0.277951 +v 0.881014 0.979774 -0.278001 +v 0.879756 0.973745 -0.272588 +v 0.881660 0.979632 -0.273001 +v 0.890767 0.837342 -0.277967 +v 0.890137 0.837321 -0.272503 +v 0.874114 0.813771 -0.864179 +v 0.880191 0.812447 -0.864179 +v 0.885231 0.811560 -0.864179 +v 0.862401 0.816529 -0.864179 +v 0.867955 0.815259 -0.864179 +v 0.899475 0.979571 -0.272503 +v 0.898236 0.973346 -0.271632 +v 0.904369 0.971679 -0.271632 +v 0.905610 0.977893 -0.272503 +v 0.892729 0.973885 -0.271632 +v 0.894001 0.980055 -0.272503 +v 0.858024 0.817273 -0.864054 +v 0.855215 0.817604 -0.863183 +v 0.888463 0.811253 -0.864054 +v 0.890137 0.811263 -0.863183 +v 0.858024 0.843331 -0.271632 +v 0.855216 0.843662 -0.272503 +v 0.890137 0.837321 -0.272503 +v 0.888464 0.837311 -0.271632 +v 0.890137 0.811263 -0.863183 +v 0.890755 0.811833 -0.857105 +v 0.890843 0.815637 -0.826496 +v 0.881660 0.927516 -0.862686 +v 0.879755 0.922714 -0.863098 +v 0.878404 0.923808 -0.855312 +v 0.881013 0.928744 -0.855187 +v 0.878211 0.931257 -0.812288 +v 0.880880 0.936374 -0.811675 +v 0.910969 0.933403 -0.609761 +v 0.910546 0.927679 -0.612804 +v 0.916013 0.936681 -0.716274 +v 0.916508 0.942576 -0.714430 +v 0.903132 0.895336 -0.633722 +v 0.907805 0.902994 -0.728909 +v 0.872469 0.937052 -0.612737 +v 0.877493 0.944739 -0.716226 +v 0.875035 0.942226 -0.609708 +v 0.880149 0.950135 -0.714392 +v -0.947011 1.137805 -0.818544 +v -0.945091 1.132803 -0.817811 +v -0.936775 1.106935 -0.835906 +v -0.938508 1.110815 -0.836276 +v -0.937423 1.106852 -0.812680 +v -0.930363 1.085264 -0.833314 +v -0.902411 0.721006 -0.783361 +v -0.910161 0.841871 -0.784106 +v -0.909949 0.841236 -0.818873 +v -0.902411 0.721006 -0.818501 +v 1.194686 0.098612 -0.464838 +v 1.110416 0.235996 -0.453763 +v 1.195101 0.098147 -0.603098 +v 1.113739 0.232276 -0.594638 +v 0.875035 0.942226 -0.609708 +v 0.878553 0.942372 -0.609670 +v 0.883673 0.950407 -0.714365 +v 0.880149 0.950135 -0.714392 +v 0.883229 0.942323 -0.609646 +v 0.888365 0.950526 -0.714347 +v 0.871974 0.562310 -0.394306 +v 0.921680 0.439543 -0.371752 +v 0.860494 0.591758 -0.513429 +v 0.877787 0.516906 -0.548789 +v 0.890917 0.489134 -0.453580 +v 0.922515 0.425320 -0.412949 +v 1.025742 0.361397 -0.424966 +v 0.955483 0.472635 -0.369725 +v 1.045358 0.335117 -0.570666 +v 1.011209 0.384715 -0.547341 +v 0.997140 0.404321 -0.449122 +v 0.957204 0.467233 -0.409236 +v 1.153517 -1.274951 -0.783511 +v 1.095331 -1.327512 -0.783491 +v 1.095331 -1.327512 -0.818595 +v 1.153517 -1.274951 -0.818609 +v 1.074840 0.215767 -0.798970 +v 0.990001 0.336704 -0.813813 +v 0.990001 0.336704 -0.832411 +v 1.074840 0.215767 -0.824328 +v 1.407229 -0.543600 -0.466136 +v 1.407229 -0.543600 -0.600655 +v 1.329772 -1.033620 -0.466260 +v 1.329772 -1.033621 -0.600828 +v 1.366692 -0.543736 -0.466169 +v 1.366692 -0.543736 -0.600702 +v -1.036866 0.371091 -0.783362 +v -1.036865 0.371091 -0.818392 +v -0.964714 0.492569 -0.783362 +v -0.964715 0.492569 -0.818463 +v -0.008951 -1.649528 -0.783397 +v -0.200711 -1.645159 -0.783393 +v -0.200711 -1.645159 -0.818524 +v -0.008951 -1.649528 -0.818527 +v 0.611736 -1.541874 -0.783418 +v 0.733674 -1.499748 -0.783426 +v 0.733674 -1.499748 -0.818548 +v 0.611736 -1.541874 -0.818542 +v 0.843227 -1.451297 -0.783436 +v 0.843227 -1.451297 -0.818555 +v 1.373869 -0.922570 -0.783624 +v 1.329772 -1.033621 -0.783590 +v 1.329772 -1.033620 -0.818666 +v 1.373869 -0.922570 -0.818690 +v 1.274071 -1.129514 -0.783560 +v 1.274071 -1.129514 -0.818644 +v 1.003268 -1.352221 -0.783461 +v 1.063498 -1.305771 -0.783476 +v 1.063498 -1.305771 -0.818584 +v 1.003268 -1.352221 -0.818573 +v 1.063498 -1.305771 -0.783476 +v 1.063498 -1.305771 -0.818584 +v -0.868623 -1.497648 -0.783376 +v -0.974817 -1.439492 -0.783374 +v -0.974817 -1.439492 -0.818511 +v -0.868623 -1.497648 -0.818512 +v -0.948878 -1.414626 -0.466416 +v -0.948879 -1.414626 -0.601046 +v -1.316218 -0.221807 -0.466423 +v -1.316219 -0.221807 -0.601055 +v -0.917487 0.841604 -0.467639 +v -0.944212 0.953583 -0.476142 +v -0.934587 0.952997 -0.616399 +v -0.912528 0.841531 -0.602974 +v -1.428460 -0.808262 -0.783365 +v -1.444854 -0.690722 -0.783365 +v -1.444854 -0.690722 -0.818504 +v -1.428460 -0.808262 -0.818504 +v -1.444854 -0.690722 -0.466422 +v -1.444854 -0.690722 -0.601053 +v -0.200711 -1.645159 -0.466402 +v -0.200711 -1.645159 -0.601026 +v -1.040102 -1.354207 -0.783371 +v -0.948879 -1.414626 -0.783373 +v -0.948879 -1.414626 -0.818510 +v -1.040102 -1.354207 -0.818508 +v 1.407229 -0.543600 -0.783763 +v 1.407229 -0.543600 -0.818790 +v 1.411122 -0.670719 -0.783710 +v 1.411122 -0.670719 -0.818752 +v 0.916013 0.962196 -0.361307 +v 0.916508 0.968635 -0.361282 +v 0.910546 0.936184 -0.426478 +v 0.910969 0.942088 -0.425967 +v 0.756038 -1.527058 -0.783435 +v 0.756038 -1.527058 -0.818554 +v 1.291396 -1.020082 -0.466280 +v 1.291396 -1.020082 -0.600855 +v -1.403705 -0.578315 -0.783364 +v -1.405798 -0.686752 -0.783364 +v -1.405798 -0.686752 -0.818504 +v -1.403706 -0.578316 -0.818503 +v 1.400542 -0.798734 -0.783664 +v 1.400543 -0.798734 -0.818719 +v -0.970419 1.040333 -0.495558 +v -0.955969 1.038566 -0.647047 +v 1.366692 -0.543736 -0.783716 +v 1.366692 -0.543736 -0.818757 +v 1.213780 -1.209734 -0.783534 +v 1.213780 -1.209734 -0.818625 +v 1.153517 -1.274951 -0.783511 +v 1.153517 -1.274951 -0.818609 +v -0.919440 0.606239 -0.783361 +v -0.919440 0.606239 -0.818497 +v 0.484470 -1.573995 -0.783410 +v 0.484470 -1.573995 -0.818537 +v -0.934399 0.468806 -0.783055 +v -1.008613 0.346090 -0.782480 +v -1.008613 0.346090 -0.815857 +v -0.934399 0.468806 -0.817582 +v -1.093651 0.213521 -0.782136 +v -1.093651 0.213521 -0.814823 +v -0.973709 1.133418 -0.818089 +v -0.964507 1.103109 -0.835941 +v -0.975200 1.140494 -0.818640 +v -0.966361 1.109247 -0.836289 +v 0.883673 0.976465 -0.361348 +v 0.880150 0.976193 -0.361320 +v 0.878553 0.951058 -0.426058 +v 0.875035 0.950912 -0.426020 +v 1.291396 -1.020082 -0.783563 +v 1.291396 -1.020082 -0.818646 +v -1.352703 -0.212430 -0.466423 +v -1.352704 -0.212430 -0.601055 +v -0.881746 0.589969 -0.466424 +v -0.881548 0.589969 -0.601056 +v 0.931993 -1.401041 -0.783448 +v 0.931993 -1.401041 -0.818563 +v -0.881449 0.589969 -0.783323 +v -0.881449 0.589969 -0.818386 +v -1.352704 -0.212429 -0.783363 +v -1.352703 -0.212429 -0.818498 +v -0.919777 1.044750 -0.800952 +v -0.915547 1.031926 -0.827389 +v -1.210419 -1.247328 -0.783370 +v -1.274021 -1.164871 -0.783368 +v -1.274021 -1.164871 -0.818506 +v -1.210419 -1.247328 -0.818507 +v -1.335017 -1.061893 -0.783367 +v -1.335017 -1.061893 -0.818506 +v -0.974615 1.142791 -0.818556 +v -0.966140 1.111521 -0.836278 +v -0.974615 1.142791 -0.818556 +v -0.966140 1.111521 -0.836278 +v -1.255506 -0.083722 -0.783056 +v -1.316219 -0.221807 -0.783324 +v -1.316219 -0.221807 -0.818388 +v -1.255506 -0.083722 -0.817582 +v -1.360307 -0.348342 -0.783363 +v -1.360307 -0.348343 -0.818502 +v -1.239732 -1.147669 -0.466420 +v -1.177905 -1.227825 -0.466419 +v -1.177905 -1.227825 -0.601050 +v -1.239733 -1.147669 -0.601051 +v -1.178957 0.065987 -0.782481 +v -1.178957 0.065987 -0.815858 +v -0.757186 -1.546177 -0.783379 +v -0.757186 -1.546177 -0.818514 +v -1.239733 -1.147669 -0.783368 +v -1.239732 -1.147669 -0.818506 +v -1.177905 -1.227825 -0.783369 +v -1.177905 -1.227825 -0.818506 +v 0.180499 -1.643058 -0.783403 +v 0.180499 -1.643059 -0.818532 +v -0.366287 -1.601764 -0.783385 +v -0.196375 -1.614553 -0.783389 +v -0.196375 -1.614553 -0.818521 +v -0.366287 -1.601764 -0.818519 +v -1.389440 -0.937354 -0.783366 +v -1.389440 -0.937354 -0.818505 +v -1.177905 -1.227825 -0.783369 +v -1.114060 -1.293972 -0.783370 +v -1.114060 -1.293972 -0.818508 +v -1.177905 -1.227825 -0.818506 +v 1.106999 0.237706 -0.799884 +v 1.194259 0.098826 -0.789480 +v 1.194259 0.098826 -0.820225 +v 1.106999 0.237707 -0.825361 +v -0.505818 -1.582438 -0.783382 +v -0.505818 -1.582437 -0.818516 +v 0.880515 0.710780 -0.744277 +v 0.899095 0.594978 -0.794364 +v 0.899212 0.595169 -0.824263 +v 0.881452 0.712310 -0.795126 +v 0.946504 0.477860 -0.820195 +v 0.946504 0.477860 -0.838553 +v -1.388797 -0.466544 -0.783363 +v -1.388797 -0.466543 -0.818503 +v 0.887632 0.817834 -0.683331 +v 0.890442 0.822426 -0.758796 +v 1.159666 0.080762 -0.789296 +v 1.159666 0.080762 -0.820045 +v 1.019936 0.361223 -0.816274 +v 1.019936 0.361223 -0.835261 +v -0.963667 1.124796 -0.691309 +v -0.970366 1.125037 -0.691309 +v -0.990303 1.128150 -0.523781 +v -0.983286 1.127333 -0.523781 +v -0.957651 1.125499 -0.691309 +v -0.976369 1.127535 -0.523782 +v 0.893608 0.941577 -0.609634 +v 0.899643 0.939657 -0.609646 +v 0.904924 0.948442 -0.714347 +v 0.898801 0.950151 -0.714338 +v 0.888183 0.942278 -0.609634 +v 0.893335 0.950660 -0.714338 +v 0.898830 0.879382 -0.548506 +v 0.893118 0.854239 -0.572252 +v 0.899100 0.884119 -0.545076 +v 0.891979 0.851074 -0.507869 +v 0.891801 0.847002 -0.510778 +v 0.887109 0.826685 -0.531142 +v 0.898830 0.880445 -0.474850 +v 0.893118 0.855144 -0.486936 +v 0.899100 0.885204 -0.473161 +v 0.845462 0.801816 -0.628993 +v 0.856028 0.865654 -0.572199 +v 0.844304 0.703885 -0.701278 +v 0.843279 0.697091 -0.650559 +v 0.842154 0.785960 -0.580974 +v 0.850509 0.839551 -0.531140 +v 0.845450 0.801953 -0.518293 +v 0.856028 0.866559 -0.486992 +v 0.844209 0.700811 -0.571225 +v -0.949783 1.149493 -0.803258 +v -0.941202 1.120254 -0.795236 +v -0.952065 1.155866 -0.804409 +v -0.951633 1.157509 -0.792701 +v -0.948939 1.150496 -0.791087 +v -0.940141 1.120597 -0.780033 +v -0.943885 1.135195 -0.769276 +v -0.935645 1.107936 -0.755668 +v -0.946826 1.141393 -0.771322 +v -0.954611 1.056337 -0.777734 +v -0.971818 1.122872 -0.796385 +v -0.931729 0.958897 -0.758869 +v -0.931752 0.958955 -0.730127 +v -0.954669 1.056510 -0.756162 +v -0.971858 1.123147 -0.781868 +v -0.952569 1.047084 -0.726175 +v -0.967994 1.107199 -0.757604 +v -0.931352 0.955826 -0.694427 +v -0.947011 1.137805 -0.818544 +v -0.948215 1.138713 -0.818544 +v -0.953381 1.157277 -0.804411 +v -0.952065 1.155866 -0.804409 +v -0.955705 1.157785 -0.804411 +v -0.953381 1.157277 -0.804411 +v -0.955705 1.157785 -0.804411 +v -0.955493 1.159565 -0.792722 +v -0.953151 1.159151 -0.792719 +v -0.951633 1.157509 -0.792701 +v -0.948529 1.142692 -0.771374 +v -0.946826 1.141393 -0.771322 +v -0.950899 1.142744 -0.771381 +v 0.867581 0.895529 -0.545013 +v 0.872225 0.895120 -0.544996 +v 0.864074 0.895655 -0.545039 +v 0.857498 0.864238 -0.507869 +v 0.860999 0.863948 -0.507869 +v 0.865622 0.863323 -0.507869 +v 0.867582 0.896614 -0.473223 +v 0.872225 0.896205 -0.473240 +v 0.864074 0.896741 -0.473197 +v 0.867582 0.896614 -0.473223 +v 0.864074 0.896741 -0.473197 +v 0.875035 0.950912 -0.426020 +v 0.878553 0.951058 -0.426058 +v 0.872225 0.896205 -0.473240 +v 0.883230 0.951009 -0.426083 +v 0.861704 0.891574 -0.548460 +v 0.864074 0.895655 -0.545039 +v 0.855245 0.860884 -0.510777 +v 0.857498 0.864238 -0.507869 +v 0.855245 0.860884 -0.510777 +v 0.861704 0.892637 -0.474896 +v 0.861704 0.892637 -0.474896 +v 0.864074 0.896741 -0.473197 +v 1.338895 -0.233898 -0.750307 +v 1.384498 -0.402085 -0.749737 +v 1.273694 -0.059216 -0.754015 +v 1.273694 -0.059216 -0.722891 +v 1.338895 -0.233899 -0.717808 +v 1.384498 -0.402085 -0.717082 +v 1.338895 -0.233898 -0.678683 +v 1.384498 -0.402085 -0.678209 +v 1.273694 -0.059216 -0.682280 +v 0.867544 0.582573 -0.765243 +v 0.917120 0.455842 -0.801818 +v 0.916703 0.453674 -0.772073 +v 0.867486 0.578260 -0.723275 +v 0.991052 0.329893 -0.425386 +v 0.960669 0.366735 -0.449844 +v 0.974739 0.348088 -0.546236 +v 1.009926 0.303447 -0.570648 +v 1.213780 -1.209734 -0.749537 +v 1.153517 -1.274951 -0.749521 +v 1.274071 -1.129514 -0.749555 +v 1.274071 -1.129514 -0.717082 +v 1.213780 -1.209734 -0.717082 +v 1.153517 -1.274951 -0.717082 +v 1.213780 -1.209734 -0.678409 +v 1.153517 -1.274951 -0.678425 +v 1.274071 -1.129514 -0.678391 +v 1.159662 0.080758 -0.763509 +v 1.074816 0.215731 -0.779878 +v 1.236884 -0.072870 -0.753966 +v 1.236884 -0.072870 -0.722891 +v 1.159641 0.080726 -0.735280 +v 1.074643 0.215481 -0.752309 +v 1.159763 0.080466 -0.690282 +v 1.075621 0.213397 -0.696182 +v 1.236884 -0.072870 -0.682329 +v 0.499680 -1.603436 -0.749457 +v 0.352978 -1.627178 -0.749452 +v 0.630599 -1.570393 -0.749463 +v 0.630599 -1.570393 -0.717082 +v 0.499680 -1.603436 -0.717082 +v 0.352978 -1.627178 -0.717082 +v 0.499680 -1.603436 -0.678490 +v 0.352978 -1.627178 -0.678495 +v 0.630599 -1.570393 -0.678484 +v 1.300266 -0.242677 -0.750264 +v 1.344596 -0.406170 -0.749700 +v 1.344596 -0.406170 -0.717082 +v 1.300265 -0.242677 -0.717808 +v 1.300266 -0.242677 -0.678725 +v 1.344596 -0.406170 -0.678246 +v 0.960051 -1.425517 -0.749486 +v 0.868736 -1.477216 -0.749477 +v 1.033371 -1.375295 -0.749496 +v 1.033371 -1.375295 -0.717082 +v 0.960050 -1.425517 -0.717082 +v 0.868736 -1.477215 -0.717082 +v 0.960051 -1.425517 -0.678460 +v 0.868736 -1.477216 -0.678469 +v 1.033371 -1.375295 -0.678450 +v 1.178641 -1.191280 -0.749523 +v 1.237250 -1.113299 -0.749539 +v 1.120061 -1.254677 -0.749510 +v 1.120061 -1.254677 -0.717082 +v 1.178641 -1.191280 -0.717082 +v 1.237250 -1.113299 -0.717082 +v 1.178641 -1.191280 -0.678423 +v 1.237250 -1.113299 -0.678407 +v 1.120061 -1.254677 -0.678437 +v 0.180499 -1.643059 -0.749447 +v -0.008951 -1.649528 -0.749444 +v 0.180499 -1.643058 -0.717082 +v -0.008951 -1.649528 -0.717082 +v 0.180499 -1.643059 -0.678499 +v -0.008951 -1.649528 -0.678503 +v 0.484470 -1.573995 -0.749452 +v 0.611736 -1.541874 -0.749457 +v 0.341862 -1.597074 -0.749448 +v 0.341862 -1.597074 -0.717082 +v 0.484470 -1.573995 -0.717082 +v 0.611736 -1.541874 -0.717082 +v 0.484470 -1.573995 -0.678494 +v 0.611736 -1.541874 -0.678489 +v 0.341862 -1.597074 -0.678499 +v 1.400543 -0.798734 -0.749627 +v 1.373869 -0.922570 -0.749599 +v 1.411122 -0.670719 -0.749659 +v 1.411122 -0.670719 -0.717082 +v 1.400542 -0.798734 -0.717082 +v 1.373869 -0.922570 -0.717082 +v 1.400543 -0.798734 -0.678319 +v 1.373869 -0.922570 -0.678346 +v 1.411122 -0.670719 -0.678287 +v 0.931993 -1.401041 -0.749478 +v 1.003268 -1.352221 -0.749487 +v 0.843227 -1.451297 -0.749470 +v 0.843227 -1.451297 -0.717082 +v 0.931993 -1.401041 -0.717082 +v 1.003268 -1.352221 -0.717082 +v 0.931993 -1.401041 -0.678468 +v 1.003268 -1.352221 -0.678459 +v 0.843227 -1.451297 -0.678476 +v -0.757186 -1.546177 -0.749431 +v -0.868623 -1.497648 -0.749429 +v -0.641666 -1.584145 -0.749433 +v -0.641666 -1.584145 -0.717082 +v -0.757186 -1.546177 -0.717082 +v -0.868623 -1.497648 -0.717082 +v -0.757186 -1.546177 -0.678516 +v -0.868623 -1.497648 -0.678517 +v -0.641666 -1.584145 -0.678514 +v 0.174196 -1.612512 -0.749444 +v -0.009966 -1.618802 -0.749440 +v -0.009966 -1.618801 -0.717082 +v 0.174196 -1.612512 -0.717082 +v 0.174196 -1.612512 -0.678502 +v -0.009966 -1.618802 -0.678506 +v -1.144742 -1.315373 -0.749425 +v -1.210419 -1.247328 -0.749424 +v -1.068659 -1.377337 -0.749426 +v -1.068659 -1.377337 -0.717082 +v -1.144742 -1.315373 -0.717082 +v -1.210419 -1.247328 -0.717082 +v -1.144742 -1.315373 -0.678521 +v -1.210419 -1.247328 -0.678522 +v -1.068659 -1.377337 -0.678520 +v 1.360192 -0.791749 -0.749603 +v 1.370476 -0.667307 -0.749630 +v 1.334264 -0.912130 -0.749578 +v 1.334264 -0.912130 -0.717082 +v 1.360192 -0.791749 -0.717082 +v 1.370476 -0.667307 -0.717082 +v 1.360192 -0.791749 -0.678343 +v 1.370476 -0.667307 -0.678315 +v 1.334264 -0.912130 -0.678367 +v -1.389440 -0.937354 -0.749422 +v -1.428460 -0.808262 -0.749422 +v -1.335017 -1.061893 -0.749423 +v -1.335017 -1.061893 -0.717082 +v -1.389440 -0.937354 -0.717082 +v -1.428460 -0.808262 -0.717082 +v -1.389440 -0.937354 -0.678524 +v -1.428460 -0.808262 -0.678524 +v -1.335017 -1.061893 -0.678523 +v -0.737321 -1.518334 -0.749429 +v -0.625024 -1.555243 -0.749431 +v -0.845647 -1.471160 -0.749428 +v -0.845647 -1.471160 -0.717082 +v -0.737321 -1.518335 -0.717082 +v -0.625024 -1.555243 -0.717082 +v -0.737321 -1.518334 -0.678517 +v -0.625024 -1.555243 -0.678515 +v -0.845647 -1.471160 -0.678519 +v -1.427365 -0.464191 -0.749420 +v -1.398057 -0.342597 -0.749420 +v -1.442701 -0.579172 -0.749421 +v -1.442701 -0.579172 -0.717082 +v -1.427365 -0.464191 -0.717082 +v -1.398057 -0.342597 -0.717082 +v -1.427365 -0.464191 -0.678525 +v -1.398057 -0.342597 -0.678526 +v -1.442701 -0.579172 -0.678525 +v -1.114060 -1.293972 -0.749424 +v -1.040102 -1.354207 -0.749426 +v -1.177905 -1.227825 -0.749424 +v -1.177905 -1.227825 -0.717082 +v -1.114060 -1.293972 -0.717082 +v -1.040102 -1.354206 -0.717082 +v -1.114060 -1.293972 -0.678522 +v -1.040102 -1.354207 -0.678521 +v -1.177905 -1.227825 -0.678523 +v 1.407229 -0.543600 -0.749695 +v 1.407229 -0.543600 -0.717082 +v 1.407229 -0.543600 -0.678251 +v -1.351930 -0.926501 -0.749422 +v -1.299026 -1.047566 -0.749422 +v -1.389862 -0.801012 -0.749421 +v -1.389862 -0.801012 -0.717082 +v -1.351930 -0.926501 -0.717082 +v -1.299026 -1.047566 -0.717082 +v -1.351930 -0.926501 -0.678524 +v -1.299026 -1.047566 -0.678524 +v -1.389862 -0.801012 -0.678525 +v 0.756038 -1.527058 -0.749469 +v 0.756038 -1.527058 -0.717082 +v 0.756038 -1.527058 -0.678477 +v -1.036865 0.371091 -0.749419 +v -0.964714 0.492569 -0.749419 +v -1.123745 0.235396 -0.749419 +v -1.123745 0.235396 -0.717082 +v -1.036866 0.371091 -0.717082 +v -0.964714 0.492569 -0.717082 +v -1.036865 0.371091 -0.678527 +v -0.964714 0.492569 -0.678527 +v -1.123745 0.235396 -0.678527 +v -1.388797 -0.466543 -0.749420 +v -1.403706 -0.578315 -0.749420 +v -1.360307 -0.348343 -0.749420 +v -1.360307 -0.348342 -0.717082 +v -1.388797 -0.466543 -0.717082 +v -1.403706 -0.578316 -0.717082 +v -1.388797 -0.466543 -0.678526 +v -1.403706 -0.578315 -0.678525 +v -1.360307 -0.348343 -0.678526 +v 1.329772 -1.033620 -0.749576 +v 1.329772 -1.033620 -0.717082 +v 1.329772 -1.033620 -0.678370 +v -0.910292 0.842269 -0.750600 +v -0.902411 0.721006 -0.749419 +v -0.902411 0.721006 -0.717082 +v -0.910295 0.842276 -0.718712 +v -0.910480 0.841885 -0.680515 +v -0.902510 0.721006 -0.678527 +v 1.366692 -0.543736 -0.749663 +v 1.366692 -0.543736 -0.717082 +v 1.366692 -0.543736 -0.678283 +v 1.095331 -1.327512 -0.749508 +v 1.153517 -1.274951 -0.749521 +v 1.153517 -1.274951 -0.717082 +v 1.095331 -1.327512 -0.717082 +v 1.095331 -1.327512 -0.678439 +v 1.153517 -1.274951 -0.678425 +v -0.919440 0.606239 -0.749419 +v -0.919440 0.606239 -0.717082 +v -0.919453 0.606239 -0.678527 +v 0.733674 -1.499749 -0.749463 +v 0.733674 -1.499748 -0.717082 +v 0.733674 -1.499749 -0.678483 +v -1.008613 0.346090 -0.749309 +v -1.093651 0.213521 -0.749266 +v -0.934399 0.468806 -0.749380 +v -0.934399 0.468806 -0.717082 +v -1.008613 0.346090 -0.717082 +v -1.093651 0.213521 -0.717082 +v -1.008613 0.346090 -0.678527 +v -1.093651 0.213521 -0.678527 +v -0.934399 0.468806 -0.678527 +v -0.979339 1.152647 -0.804085 +v -0.980588 1.160441 -0.804696 +v -0.979255 1.152946 -0.792406 +v -0.980387 1.160731 -0.793160 +v -0.974649 1.133665 -0.770668 +v -0.975769 1.140493 -0.771806 +v 0.897206 0.885935 -0.545040 +v 0.899100 0.884119 -0.545076 +v 0.893607 0.888351 -0.545014 +v 0.886683 0.855561 -0.507869 +v 0.890169 0.852978 -0.507869 +v 0.891979 0.851074 -0.507869 +v 0.891979 0.851074 -0.507869 +v 0.890169 0.852978 -0.507869 +v 0.897206 0.887020 -0.473196 +v 0.899100 0.885204 -0.473161 +v 0.886683 0.855561 -0.507869 +v 0.893607 0.889437 -0.473222 +v 0.905145 0.945896 -0.426057 +v 0.908933 0.943758 -0.426019 +v 0.910969 0.942088 -0.425967 +v 1.291396 -1.020082 -0.749557 +v 1.291396 -1.020082 -0.717082 +v 1.291396 -1.020082 -0.678389 +v -0.867950 0.836862 -0.750564 +v -0.858215 0.712729 -0.749419 +v -0.895099 0.953822 -0.758581 +v -0.894843 0.953825 -0.729668 +v -0.867918 0.836863 -0.718655 +v -0.858215 0.712729 -0.717082 +v -0.868083 0.836552 -0.680454 +v -0.858314 0.712729 -0.678527 +v -0.894283 0.951338 -0.693944 +v -1.211501 0.083626 -0.749419 +v -1.290247 -0.070380 -0.749419 +v -1.290247 -0.070380 -0.717082 +v -1.211502 0.083626 -0.717082 +v -1.211501 0.083626 -0.678527 +v -1.290247 -0.070380 -0.678526 +v 1.063498 -1.305771 -0.749497 +v 1.063498 -1.305771 -0.749497 +v 1.063498 -1.305771 -0.717082 +v 1.063498 -1.305771 -0.717082 +v 1.063498 -1.305771 -0.678449 +v 1.063498 -1.305771 -0.678449 +v -0.881449 0.589969 -0.749414 +v -0.881449 0.589969 -0.717082 +v -0.881462 0.589969 -0.678527 +v -1.352703 -0.212429 -0.749420 +v -1.352703 -0.212429 -0.717082 +v -1.352703 -0.212429 -0.678526 +v -0.921979 1.052547 -0.776907 +v -0.921238 1.052596 -0.754843 +v -0.918679 1.045107 -0.724784 +v -1.274021 -1.164871 -0.749424 +v -1.210419 -1.247328 -0.749424 +v -1.210419 -1.247328 -0.717082 +v -1.274021 -1.164871 -0.717082 +v -1.274021 -1.164871 -0.678523 +v -1.210419 -1.247328 -0.678522 +v -0.979798 1.162837 -0.804447 +v -0.977038 1.163019 -0.804411 +v -0.979798 1.162837 -0.804447 +v -0.979592 1.163164 -0.792777 +v -0.977038 1.163019 -0.804411 +v -0.979798 1.162837 -0.804447 +v -0.979592 1.163164 -0.792777 +v -0.976856 1.163506 -0.792722 +v -0.976856 1.163506 -0.792722 +v -0.979592 1.163164 -0.792777 +v -0.975132 1.142787 -0.771434 +v -0.972478 1.143490 -0.771381 +v -0.975132 1.142787 -0.771434 +v -0.972478 1.143490 -0.771381 +v -0.975132 1.142787 -0.771434 +v -1.178957 0.065987 -0.749309 +v -1.255506 -0.083722 -0.749381 +v -1.178957 0.065987 -0.717082 +v -1.255506 -0.083722 -0.717082 +v -1.178957 0.065987 -0.678527 +v -1.255506 -0.083722 -0.678527 +v -0.519038 -1.612120 -0.749435 +v -0.375500 -1.632002 -0.749437 +v -0.375500 -1.632002 -0.717082 +v -0.519038 -1.612120 -0.717082 +v -0.519038 -1.612120 -0.678512 +v -0.375500 -1.632002 -0.678509 +v -1.316219 -0.221807 -0.749415 +v -1.316219 -0.221807 -0.717082 +v -1.316219 -0.221807 -0.678526 +v -0.974817 -1.439492 -0.749428 +v -0.974817 -1.439492 -0.717082 +v -0.974817 -1.439492 -0.678519 +v -1.239733 -1.147669 -0.749423 +v -1.177905 -1.227825 -0.749424 +v -1.239733 -1.147669 -0.717082 +v -1.177905 -1.227825 -0.717082 +v -1.239733 -1.147669 -0.678523 +v -1.177905 -1.227825 -0.678523 +v -0.200711 -1.645159 -0.749440 +v -0.200711 -1.645159 -0.717082 +v -0.200711 -1.645159 -0.678506 +v -0.505818 -1.582437 -0.749433 +v -0.366287 -1.601764 -0.749435 +v -0.505818 -1.582438 -0.717082 +v -0.366287 -1.601764 -0.717082 +v -0.505818 -1.582437 -0.678514 +v -0.366287 -1.601764 -0.678511 +v -1.444854 -0.690722 -0.749421 +v -1.444854 -0.690722 -0.717082 +v -1.444854 -0.690722 -0.678525 +v -0.948878 -1.414626 -0.749427 +v -0.948878 -1.414626 -0.717082 +v -0.948878 -1.414626 -0.678520 +v 1.020031 0.361334 -0.797658 +v 1.107037 0.237752 -0.779244 +v 0.946595 0.477948 -0.799037 +v 1.020700 0.362108 -0.765177 +v 1.107303 0.238068 -0.750765 +v 0.904833 0.590789 -0.389303 +v 0.921800 0.539371 -0.443822 +v -0.196375 -1.614553 -0.749438 +v -0.196375 -1.614553 -0.717082 +v -0.196375 -1.614553 -0.678509 +v 0.881615 0.793181 -0.628952 +v 0.878533 0.702577 -0.700569 +v 0.878025 0.776664 -0.580718 +v 0.881633 0.793959 -0.517978 +v -1.405798 -0.686752 -0.749421 +v -1.405798 -0.686752 -0.717082 +v -1.405798 -0.686752 -0.678525 +v 0.898913 0.593997 -0.763149 +v 1.020918 0.365734 -0.695021 +v 1.109182 0.237091 -0.695738 +v 0.987633 0.413429 -0.649836 +v 0.989936 0.336583 -0.799600 +v 0.989477 0.335737 -0.769670 +v 0.867631 0.566168 -0.645965 +v 0.914848 0.447953 -0.720515 +v 0.910432 0.440150 -0.688914 +v 0.882717 0.499198 -0.645327 +v 1.194264 0.098832 -0.763478 +v 1.194297 0.098871 -0.735088 +v 1.194532 0.098749 -0.690178 +v -0.954992 1.142170 -0.771381 +v -0.960647 1.141967 -0.771381 +v -0.959623 1.159591 -0.792722 +v -0.965261 1.160223 -0.792722 +v -0.959872 1.158055 -0.804411 +v -0.965527 1.159024 -0.804411 +v -0.959872 1.158055 -0.804411 +v -0.965527 1.159024 -0.804411 +v -0.967111 1.142785 -0.771381 +v -0.971589 1.162000 -0.792722 +v -0.971810 1.161190 -0.804411 +v -0.971810 1.161190 -0.804411 +v 0.877143 0.894693 -0.544988 +v 0.882479 0.893579 -0.544988 +v 0.870519 0.862668 -0.507869 +v 0.875802 0.861305 -0.507869 +v 0.877143 0.895779 -0.473248 +v 0.882479 0.894664 -0.473248 +v 0.877143 0.895779 -0.473248 +v 0.888183 0.950964 -0.426095 +v 0.882479 0.894664 -0.473248 +v 0.893608 0.950263 -0.426095 +v 0.888328 0.891206 -0.544997 +v 0.881539 0.858661 -0.507869 +v 0.881539 0.858661 -0.507869 +v 0.888328 0.892292 -0.473240 +v 0.875802 0.861305 -0.507869 +v 0.899643 0.948343 -0.426082 +v 0.904924 0.974500 -0.361365 +v 0.899643 0.948343 -0.426082 +v 0.986953 0.334939 -0.695294 +v 0.952470 0.376798 -0.645826 +v 0.989140 0.395256 -0.533089 +v 0.978410 0.409281 -0.455378 +v 0.985906 0.414196 -0.454592 +v 0.996987 0.399152 -0.535958 +v 0.978410 0.409281 -0.455378 +v 0.949007 0.453742 -0.426753 +v 0.954911 0.461785 -0.423972 +v 0.985906 0.414196 -0.454592 +v 0.954911 0.461785 -0.423972 +v 0.957204 0.467233 -0.409236 +v 0.997140 0.404321 -0.449122 +v 1.011209 0.384715 -0.547341 +v 0.890354 0.479463 -0.646025 +v 0.887637 0.491784 -0.562798 +v 0.910632 0.439321 -0.677324 +v 0.890354 0.479463 -0.646025 +v 0.910632 0.439321 -0.677324 +v 0.916022 0.446732 -0.674069 +v 0.896148 0.486005 -0.643664 +v 0.887637 0.491784 -0.562798 +v 0.890354 0.479463 -0.646025 +v 0.896148 0.486005 -0.643664 +v 0.893415 0.498571 -0.562093 +v 0.954045 0.379841 -0.455457 +v 0.965207 0.365751 -0.535503 +v 0.925159 0.421577 -0.428158 +v 0.954045 0.379841 -0.455457 +v 0.925159 0.421577 -0.428158 +v 0.931113 0.428308 -0.429654 +v 0.958999 0.388080 -0.456056 +v 0.958999 0.388080 -0.456056 +v 0.969744 0.374560 -0.533624 +v 0.900328 0.467281 -0.474471 +v 0.900328 0.467281 -0.474471 +v 0.906523 0.473338 -0.475629 +v 0.900328 0.467281 -0.474471 +v 0.906523 0.473338 -0.475629 +v 0.949007 0.453742 -0.426753 +v 0.921032 0.507788 -0.467752 +v 0.925363 0.519732 -0.463336 +v 0.954911 0.461785 -0.423972 +v 0.905682 0.538539 -0.551087 +v 0.909467 0.551620 -0.548295 +v 0.932876 0.472782 -0.670542 +v 0.967320 0.422371 -0.622983 +v 0.974684 0.426160 -0.629603 +v 0.938566 0.479208 -0.677395 +v 0.987633 0.413429 -0.649836 +v 0.938566 0.479208 -0.677395 +v 0.974684 0.426160 -0.629603 +v 0.909942 0.520878 -0.635357 +v 0.914142 0.531696 -0.637818 +v 0.932876 0.472782 -0.670542 +v 0.968707 0.398690 -0.455674 +v 0.940060 0.441025 -0.428203 +v 0.978410 0.409281 -0.455378 +v 0.989140 0.395256 -0.533089 +v 0.979460 0.384979 -0.533009 +v 0.968707 0.398690 -0.455674 +v 0.913780 0.490572 -0.471647 +v 0.899566 0.518626 -0.556243 +v 0.921032 0.507788 -0.467752 +v 0.913780 0.490572 -0.471647 +v 0.940060 0.441025 -0.428203 +v 0.931113 0.428308 -0.429654 +v 0.932876 0.472782 -0.670542 +v 0.909942 0.520878 -0.635357 +v 0.903097 0.503647 -0.638511 +v 0.924522 0.460043 -0.670915 +v 0.903097 0.503647 -0.638511 +v 0.967320 0.422371 -0.622983 +v 0.958024 0.411765 -0.622538 +v 0.967320 0.422371 -0.622983 +v 0.958024 0.411765 -0.622538 +v 0.948624 0.400747 -0.624091 +v 0.948624 0.400747 -0.624091 +v 0.944070 0.392023 -0.627541 +v 0.916022 0.446732 -0.674069 +vt 0.480965 0.761217 +vt 0.474816 0.757383 +vt 0.474641 0.757799 +vt 0.480818 0.761647 +vt 0.469747 0.753458 +vt 0.469549 0.753857 +vt 0.469307 0.754348 +vt 0.474428 0.758307 +vt 0.480639 0.762173 +vt 0.474214 0.758815 +vt 0.480460 0.762698 +vt 0.469064 0.754839 +vt 0.583949 0.590529 +vt 0.593156 0.593551 +vt 0.593239 0.593022 +vt 0.584171 0.590128 +vt 0.602271 0.594121 +vt 0.602221 0.593484 +vt 0.602167 0.592716 +vt 0.593353 0.592374 +vt 0.584455 0.589631 +vt 0.593524 0.591789 +vt 0.584758 0.589155 +vt 0.602193 0.592050 +vt 0.557982 0.754491 +vt 0.545822 0.760272 +vt 0.545958 0.760695 +vt 0.558171 0.754890 +vt 0.534005 0.764603 +vt 0.534090 0.765045 +vt 0.534193 0.765580 +vt 0.546123 0.761208 +vt 0.558401 0.755373 +vt 0.546288 0.761721 +vt 0.558631 0.755857 +vt 0.534296 0.766116 +vt 0.465602 0.749602 +vt 0.465385 0.749986 +vt 0.461778 0.745445 +vt 0.461544 0.745813 +vt 0.461253 0.746268 +vt 0.465118 0.750460 +vt 0.464851 0.750934 +vt 0.460963 0.746723 +vt 0.611274 0.591893 +vt 0.611206 0.591273 +vt 0.619528 0.588314 +vt 0.619509 0.587785 +vt 0.619461 0.587145 +vt 0.611114 0.590533 +vt 0.611079 0.589905 +vt 0.619426 0.586584 +vt 0.578299 0.740651 +vt 0.568855 0.747792 +vt 0.569092 0.748162 +vt 0.578578 0.740990 +vt 0.569380 0.748611 +vt 0.578916 0.741403 +vt 0.569667 0.749061 +vt 0.579255 0.741816 +vt 0.496482 0.767097 +vt 0.488214 0.764622 +vt 0.488100 0.765066 +vt 0.496404 0.767551 +vt 0.487960 0.765606 +vt 0.496309 0.768103 +vt 0.487820 0.766147 +vt 0.496213 0.768654 +vt 0.564083 0.580438 +vt 0.574433 0.585865 +vt 0.574692 0.585508 +vt 0.564306 0.580067 +vt 0.575018 0.585063 +vt 0.564585 0.579605 +vt 0.575345 0.584621 +vt 0.564864 0.579143 +vt 0.613518 0.720852 +vt 0.603974 0.723124 +vt 0.604062 0.723500 +vt 0.613464 0.721277 +vt 0.594968 0.727495 +vt 0.595218 0.727816 +vt 0.595533 0.728199 +vt 0.604195 0.723932 +vt 0.613426 0.721752 +vt 0.604380 0.724330 +vt 0.613448 0.722188 +vt 0.595865 0.728570 +vt 0.453420 0.734249 +vt 0.449131 0.726464 +vt 0.448836 0.726752 +vt 0.453145 0.734571 +vt 0.445231 0.717724 +vt 0.444916 0.717974 +vt 0.444521 0.718287 +vt 0.448466 0.727111 +vt 0.452803 0.734971 +vt 0.448096 0.727471 +vt 0.452460 0.735371 +vt 0.444125 0.718600 +vt 0.629756 0.721303 +vt 0.622824 0.720640 +vt 0.622766 0.721057 +vt 0.622696 0.721520 +vt 0.629761 0.721687 +vt 0.629733 0.722113 +vt 0.622638 0.721975 +vt 0.523964 0.767123 +vt 0.524005 0.767576 +vt 0.514840 0.768199 +vt 0.514842 0.768657 +vt 0.514844 0.769211 +vt 0.524055 0.768124 +vt 0.524105 0.768673 +vt 0.514846 0.769766 +vt 0.586688 0.733605 +vt 0.586991 0.733919 +vt 0.587361 0.734301 +vt 0.587734 0.734681 +vt 0.503485 0.562618 +vt 0.511853 0.563000 +vt 0.511842 0.562556 +vt 0.503436 0.562173 +vt 0.520785 0.564346 +vt 0.520813 0.563907 +vt 0.520848 0.563365 +vt 0.511827 0.562008 +vt 0.503376 0.561623 +vt 0.511813 0.561459 +vt 0.503316 0.561073 +vt 0.520883 0.562822 +vt 0.487093 0.565076 +vt 0.495446 0.563161 +vt 0.495362 0.562719 +vt 0.486972 0.564642 +vt 0.495257 0.562173 +vt 0.486821 0.564106 +vt 0.495153 0.561626 +vt 0.486671 0.563569 +vt 0.469436 0.573380 +vt 0.478052 0.568688 +vt 0.477890 0.568270 +vt 0.469235 0.572981 +vt 0.477690 0.567753 +vt 0.468987 0.572488 +vt 0.477489 0.567236 +vt 0.468738 0.571996 +vt 0.435533 0.672297 +vt 0.434643 0.658503 +vt 0.434276 0.658484 +vt 0.435170 0.672341 +vt 0.434490 0.645873 +vt 0.434122 0.645795 +vt 0.433656 0.645697 +vt 0.433810 0.658459 +vt 0.434710 0.672396 +vt 0.433345 0.658434 +vt 0.434250 0.672451 +vt 0.433191 0.645598 +vt 0.448429 0.594497 +vt 0.452404 0.588642 +vt 0.452125 0.588309 +vt 0.448131 0.594190 +vt 0.456883 0.583496 +vt 0.456625 0.583141 +vt 0.456305 0.582700 +vt 0.451778 0.587894 +vt 0.447759 0.593805 +vt 0.451430 0.587480 +vt 0.447386 0.593421 +vt 0.455984 0.582259 +vt 0.441040 0.609621 +vt 0.444552 0.601629 +vt 0.444235 0.601352 +vt 0.440707 0.609380 +vt 0.443838 0.601006 +vt 0.440287 0.609077 +vt 0.443442 0.600659 +vt 0.439868 0.608774 +vt 0.436254 0.626462 +vt 0.438254 0.617929 +vt 0.437907 0.617724 +vt 0.435896 0.626296 +vt 0.437469 0.617467 +vt 0.435444 0.626087 +vt 0.437031 0.617210 +vt 0.434992 0.625877 +vt 0.435015 0.635443 +vt 0.434651 0.635317 +vt 0.434190 0.635159 +vt 0.433728 0.635000 +vt 0.505561 0.768240 +vt 0.505523 0.768698 +vt 0.505476 0.769254 +vt 0.505428 0.769810 +vt 0.462413 0.578408 +vt 0.462180 0.578031 +vt 0.461892 0.577564 +vt 0.461603 0.577098 +vt 0.439410 0.698142 +vt 0.437187 0.685858 +vt 0.436832 0.685964 +vt 0.439067 0.698304 +vt 0.436383 0.686097 +vt 0.438632 0.698508 +vt 0.435934 0.686231 +vt 0.438198 0.698712 +vt 0.530434 0.566790 +vt 0.530505 0.566362 +vt 0.541044 0.570389 +vt 0.541163 0.569975 +vt 0.541311 0.569462 +vt 0.530594 0.565831 +vt 0.530682 0.565300 +vt 0.541459 0.568949 +vt 0.457709 0.740489 +vt 0.457454 0.740836 +vt 0.457139 0.741267 +vt 0.456823 0.741699 +vt 0.552616 0.575083 +vt 0.552787 0.574689 +vt 0.553001 0.574200 +vt 0.553214 0.573710 +vt 0.442036 0.708528 +vt 0.441705 0.708737 +vt 0.441289 0.708999 +vt 0.440872 0.709262 +vt 0.474020 0.803264 +vt 0.479235 0.799530 +vt 0.479077 0.799108 +vt 0.473838 0.802856 +vt 0.485526 0.795930 +vt 0.485396 0.795494 +vt 0.485237 0.794961 +vt 0.478883 0.798591 +vt 0.473615 0.802356 +vt 0.478689 0.798074 +vt 0.473391 0.801855 +vt 0.485078 0.794429 +vt 0.538650 0.794578 +vt 0.550291 0.799366 +vt 0.550443 0.798947 +vt 0.538752 0.794139 +vt 0.562220 0.805617 +vt 0.562424 0.805225 +vt 0.562672 0.804750 +vt 0.550628 0.798440 +vt 0.538875 0.793607 +vt 0.550812 0.797933 +vt 0.538998 0.793075 +vt 0.562920 0.804275 +vt 0.465752 0.810976 +vt 0.469732 0.806963 +vt 0.469530 0.806570 +vt 0.465532 0.810599 +vt 0.469281 0.806086 +vt 0.465259 0.810132 +vt 0.469032 0.805601 +vt 0.464986 0.809666 +vt 0.616819 0.971897 +vt 0.609281 0.969246 +vt 0.609187 0.969864 +vt 0.616756 0.972422 +vt 0.600303 0.968081 +vt 0.600221 0.968848 +vt 0.609063 0.970599 +vt 0.616655 0.973043 +vt 0.609000 0.971220 +vt 0.616570 0.973565 +vt 0.600221 0.969515 +vt 0.572827 0.812738 +vt 0.573077 0.812377 +vt 0.581989 0.820246 +vt 0.582280 0.819917 +vt 0.582635 0.819517 +vt 0.573382 0.811938 +vt 0.573687 0.811499 +vt 0.582989 0.819117 +vt 0.492899 0.792802 +vt 0.492802 0.792353 +vt 0.501255 0.790642 +vt 0.501194 0.790184 +vt 0.501120 0.789629 +vt 0.492683 0.791806 +vt 0.492564 0.791260 +vt 0.501045 0.789073 +vt 0.598141 0.834050 +vt 0.606891 0.838760 +vt 0.606994 0.838387 +vt 0.598403 0.833739 +vt 0.615783 0.841330 +vt 0.615745 0.840903 +vt 0.615725 0.840426 +vt 0.607144 0.837960 +vt 0.598732 0.833368 +vt 0.607343 0.837569 +vt 0.599078 0.833010 +vt 0.615764 0.839990 +vt 0.448158 0.838080 +vt 0.452390 0.829484 +vt 0.452105 0.829185 +vt 0.447853 0.837819 +vt 0.456973 0.821858 +vt 0.456710 0.821526 +vt 0.456383 0.821113 +vt 0.451750 0.828811 +vt 0.447470 0.837490 +vt 0.451394 0.828437 +vt 0.447087 0.837162 +vt 0.456056 0.820699 +vt 0.519639 0.790244 +vt 0.528714 0.791670 +vt 0.528772 0.791219 +vt 0.519658 0.789786 +vt 0.528843 0.790672 +vt 0.519681 0.789231 +vt 0.528914 0.790125 +vt 0.519704 0.788676 +vt 0.590102 0.827618 +vt 0.590416 0.827316 +vt 0.590801 0.826948 +vt 0.591187 0.826582 +vt 0.517779 0.994462 +vt 0.508803 0.995465 +vt 0.508775 0.995909 +vt 0.500428 0.995527 +vt 0.500362 0.995970 +vt 0.500281 0.996518 +vt 0.508740 0.996457 +vt 0.517790 0.994902 +vt 0.517804 0.995446 +vt 0.508704 0.997005 +vt 0.500199 0.997066 +vt 0.492417 0.994674 +vt 0.492315 0.995113 +vt 0.484144 0.992438 +vt 0.484006 0.992867 +vt 0.483835 0.993398 +vt 0.492190 0.995656 +vt 0.492065 0.996199 +vt 0.483665 0.993929 +vt 0.475249 0.988476 +vt 0.475071 0.988888 +vt 0.466819 0.983451 +vt 0.466604 0.983841 +vt 0.466337 0.984325 +vt 0.474851 0.989398 +vt 0.474631 0.989908 +vt 0.466069 0.984809 +vt 0.434677 0.909568 +vt 0.435314 0.896935 +vt 0.434946 0.896940 +vt 0.434307 0.909631 +vt 0.436731 0.883166 +vt 0.436370 0.883108 +vt 0.435912 0.883035 +vt 0.434480 0.896947 +vt 0.433838 0.909712 +vt 0.434014 0.896954 +vt 0.433369 0.909792 +vt 0.435455 0.882962 +vt 0.454665 0.972846 +vt 0.450386 0.967524 +vt 0.450095 0.967847 +vt 0.454393 0.973191 +vt 0.446638 0.961512 +vt 0.446329 0.961809 +vt 0.445942 0.962179 +vt 0.449732 0.968248 +vt 0.454056 0.973620 +vt 0.449369 0.968650 +vt 0.453719 0.974049 +vt 0.445556 0.962549 +vt 0.443038 0.954228 +vt 0.442711 0.954492 +vt 0.439835 0.946095 +vt 0.439492 0.946324 +vt 0.439062 0.946611 +vt 0.442301 0.954824 +vt 0.441892 0.955155 +vt 0.438631 0.946898 +vt 0.437369 0.937675 +vt 0.437014 0.937866 +vt 0.435697 0.929059 +vt 0.435333 0.929211 +vt 0.434873 0.929403 +vt 0.436567 0.938107 +vt 0.436119 0.938347 +vt 0.434414 0.929596 +vt 0.434803 0.920025 +vt 0.434434 0.920136 +vt 0.433967 0.920277 +vt 0.433501 0.920418 +vt 0.510370 0.789847 +vt 0.510349 0.789387 +vt 0.510323 0.788829 +vt 0.510297 0.788271 +vt 0.459995 0.978149 +vt 0.459748 0.978517 +vt 0.459442 0.978973 +vt 0.459136 0.979429 +vt 0.438902 0.869659 +vt 0.438552 0.869540 +vt 0.441594 0.857452 +vt 0.441256 0.857277 +vt 0.440830 0.857056 +vt 0.438108 0.869389 +vt 0.437664 0.869238 +vt 0.440404 0.856835 +vt 0.461496 0.815780 +vt 0.461256 0.815422 +vt 0.460957 0.814978 +vt 0.460658 0.814535 +vt 0.444614 0.847160 +vt 0.444292 0.846939 +vt 0.443886 0.846660 +vt 0.443479 0.846381 +vt 0.624814 0.975003 +vt 0.621943 0.973869 +vt 0.621874 0.974293 +vt 0.621769 0.974809 +vt 0.624715 0.975347 +vt 0.624587 0.975792 +vt 0.621650 0.975265 +vt 0.626278 0.584029 +vt 0.626264 0.583461 +vt 0.630816 0.581228 +vt 0.626255 0.585039 +vt 0.626273 0.584599 +vt 0.630758 0.582380 +vt 0.630795 0.581831 +vt 0.623704 0.840853 +vt 0.623663 0.840395 +vt 0.629422 0.839905 +vt 0.623798 0.841738 +vt 0.623756 0.841319 +vt 0.629495 0.840797 +vt 0.629483 0.840369 +vt 0.736172 0.262752 +vt 0.736191 0.254131 +vt 0.733906 0.254066 +vt 0.733901 0.262662 +vt 0.735966 0.245145 +vt 0.733878 0.245126 +vt 0.733454 0.245152 +vt 0.733453 0.254094 +vt 0.733451 0.262684 +vt 0.436928 0.883197 +vt 0.439094 0.869725 +vt 0.437007 0.883210 +vt 0.439172 0.869751 +vt 0.441856 0.857588 +vt 0.441779 0.857549 +vt 0.561664 0.980019 +vt 0.572210 0.974986 +vt 0.572069 0.974778 +vt 0.561544 0.979801 +vt 0.581892 0.970685 +vt 0.581762 0.970463 +vt 0.581697 0.970377 +vt 0.572008 0.974689 +vt 0.561492 0.979705 +vt 0.465883 0.811199 +vt 0.469852 0.807199 +vt 0.465943 0.811302 +vt 0.469910 0.807309 +vt 0.474184 0.803629 +vt 0.474130 0.803511 +vt 0.517841 0.996809 +vt 0.527807 0.994687 +vt 0.527791 0.994572 +vt 0.517837 0.996690 +vt 0.538804 0.991421 +vt 0.538777 0.991311 +vt 0.538717 0.991067 +vt 0.527759 0.994318 +vt 0.517830 0.996430 +vt 0.448329 0.838227 +vt 0.452551 0.829655 +vt 0.448403 0.838290 +vt 0.452622 0.829729 +vt 0.457191 0.822135 +vt 0.457124 0.822050 +vt 0.475354 0.988231 +vt 0.466947 0.983220 +vt 0.484226 0.992182 +vt 0.484266 0.992064 +vt 0.475404 0.988118 +vt 0.467006 0.983114 +vt 0.485606 0.796200 +vt 0.492960 0.793081 +vt 0.485646 0.796332 +vt 0.492991 0.793219 +vt 0.501313 0.791070 +vt 0.501293 0.790928 +vt 0.437567 0.937568 +vt 0.435898 0.928974 +vt 0.440028 0.945966 +vt 0.440110 0.945911 +vt 0.437650 0.937524 +vt 0.435981 0.928940 +vt 0.433768 0.929867 +vt 0.435486 0.938689 +vt 0.435567 0.938645 +vt 0.433849 0.929832 +vt 0.438016 0.947310 +vt 0.438096 0.947255 +vt 0.438289 0.947127 +vt 0.435764 0.938538 +vt 0.434050 0.929748 +vt 0.441301 0.955635 +vt 0.441380 0.955570 +vt 0.444993 0.963090 +vt 0.445069 0.963016 +vt 0.445246 0.962846 +vt 0.441565 0.955420 +vt 0.448835 0.969242 +vt 0.448909 0.969159 +vt 0.453220 0.974686 +vt 0.453290 0.974596 +vt 0.453448 0.974394 +vt 0.449077 0.968972 +vt 0.458680 0.980112 +vt 0.458745 0.980014 +vt 0.465669 0.985536 +vt 0.465726 0.985430 +vt 0.465854 0.985199 +vt 0.458889 0.979797 +vt 0.474300 0.990678 +vt 0.474348 0.990565 +vt 0.483407 0.994733 +vt 0.483444 0.994614 +vt 0.483526 0.994359 +vt 0.474453 0.990320 +vt 0.491876 0.997021 +vt 0.491903 0.996900 +vt 0.500077 0.997895 +vt 0.500095 0.997773 +vt 0.500134 0.997509 +vt 0.491963 0.996638 +vt 0.434820 0.882860 +vt 0.433368 0.896964 +vt 0.433446 0.896963 +vt 0.434897 0.882873 +vt 0.432717 0.909905 +vt 0.432797 0.909891 +vt 0.432999 0.909856 +vt 0.433646 0.896960 +vt 0.435094 0.882905 +vt 0.562092 0.805862 +vt 0.572670 0.812963 +vt 0.562029 0.805986 +vt 0.572593 0.813076 +vt 0.581720 0.820553 +vt 0.581809 0.820451 +vt 0.519743 0.787785 +vt 0.519736 0.787930 +vt 0.529009 0.789389 +vt 0.529029 0.789246 +vt 0.519723 0.788218 +vt 0.528972 0.789674 +vt 0.539100 0.792637 +vt 0.539164 0.792360 +vt 0.539197 0.792220 +vt 0.738342 0.301478 +vt 0.738299 0.290007 +vt 0.734153 0.290010 +vt 0.734155 0.301481 +vt 0.737984 0.279979 +vt 0.734119 0.279976 +vt 0.733441 0.280004 +vt 0.733435 0.290035 +vt 0.733430 0.301501 +vt 0.446540 0.836690 +vt 0.446611 0.836753 +vt 0.450948 0.827967 +vt 0.450879 0.827893 +vt 0.446782 0.836900 +vt 0.451109 0.828138 +vt 0.455794 0.820367 +vt 0.455643 0.820176 +vt 0.455578 0.820091 +vt 0.599682 0.832469 +vt 0.599575 0.832552 +vt 0.607712 0.837096 +vt 0.607817 0.837016 +vt 0.599378 0.832724 +vt 0.607549 0.837270 +vt 0.615846 0.839656 +vt 0.615943 0.839460 +vt 0.616021 0.839369 +vt 0.562776 0.982039 +vt 0.573530 0.976924 +vt 0.573468 0.976835 +vt 0.562724 0.981943 +vt 0.583105 0.972757 +vt 0.583036 0.972673 +vt 0.582890 0.972467 +vt 0.573324 0.976629 +vt 0.562604 0.981725 +vt 0.519627 0.790532 +vt 0.528677 0.791955 +vt 0.519622 0.790677 +vt 0.528660 0.792098 +vt 0.538555 0.794993 +vt 0.538586 0.794854 +vt 0.597978 0.834247 +vt 0.606824 0.839003 +vt 0.597897 0.834345 +vt 0.606787 0.839129 +vt 0.615799 0.841795 +vt 0.615799 0.841627 +vt 0.600436 0.970303 +vt 0.609130 0.971941 +vt 0.609065 0.971864 +vt 0.600368 0.970221 +vt 0.756990 0.974588 +vt 0.756941 0.982190 +vt 0.757006 0.982152 +vt 0.757056 0.974519 +vt 0.616546 0.974096 +vt 0.616531 0.973921 +vt 0.609007 0.971648 +vt 0.600285 0.969985 +vt 0.464577 0.808963 +vt 0.464636 0.809066 +vt 0.468710 0.804973 +vt 0.468655 0.804862 +vt 0.464766 0.809289 +vt 0.468831 0.805208 +vt 0.473209 0.801448 +vt 0.473099 0.801201 +vt 0.473048 0.801083 +vt 0.551060 0.797252 +vt 0.551109 0.797119 +vt 0.550965 0.797515 +vt 0.563124 0.803883 +vt 0.563252 0.803638 +vt 0.563317 0.803514 +vt 0.591860 0.970490 +vt 0.591791 0.970407 +vt 0.591672 0.970182 +vt 0.630614 0.580443 +vt 0.630704 0.580511 +vt 0.632668 0.579515 +vt 0.632569 0.579448 +vt 0.630790 0.580744 +vt 0.632742 0.579742 +vt 0.633157 0.579521 +vt 0.633117 0.579311 +vt 0.633009 0.579265 +vt 0.602240 0.594431 +vt 0.611248 0.592197 +vt 0.602179 0.594518 +vt 0.611185 0.592280 +vt 0.166833 0.261869 +vt 0.166898 0.261936 +vt 0.166899 0.253507 +vt 0.166835 0.253450 +vt 0.619492 0.588575 +vt 0.449299 0.726300 +vt 0.445407 0.717583 +vt 0.453578 0.734064 +vt 0.453648 0.733978 +vt 0.449372 0.726225 +vt 0.445482 0.717520 +vt 0.520768 0.564604 +vt 0.530392 0.567041 +vt 0.520761 0.564720 +vt 0.530373 0.567153 +vt 0.540944 0.570736 +vt 0.540975 0.570630 +vt 0.465732 0.749371 +vt 0.461917 0.745227 +vt 0.469866 0.753215 +vt 0.469923 0.753096 +vt 0.465792 0.749260 +vt 0.461981 0.745123 +vt 0.563954 0.580651 +vt 0.574284 0.586067 +vt 0.563898 0.580741 +vt 0.574218 0.586150 +vt 0.583741 0.590825 +vt 0.583810 0.590745 +vt 0.433611 0.672524 +vt 0.435308 0.686414 +vt 0.435385 0.686394 +vt 0.433690 0.672518 +vt 0.437588 0.698996 +vt 0.437665 0.698963 +vt 0.437854 0.698874 +vt 0.435579 0.686337 +vt 0.433887 0.672495 +vt 0.448599 0.594673 +vt 0.452565 0.588834 +vt 0.448674 0.594747 +vt 0.452637 0.588916 +vt 0.457101 0.583792 +vt 0.457033 0.583702 +vt 0.523938 0.766838 +vt 0.514839 0.767911 +vt 0.533952 0.764324 +vt 0.533925 0.764180 +vt 0.523925 0.766690 +vt 0.514839 0.767762 +vt 0.436451 0.626554 +vt 0.438448 0.618042 +vt 0.436532 0.626588 +vt 0.438528 0.618086 +vt 0.441307 0.609811 +vt 0.441228 0.609756 +vt 0.434356 0.625578 +vt 0.434436 0.625619 +vt 0.436490 0.616891 +vt 0.436410 0.616840 +vt 0.434634 0.625711 +vt 0.436683 0.617005 +vt 0.439534 0.608532 +vt 0.439347 0.608396 +vt 0.439268 0.608335 +vt 0.442946 0.600225 +vt 0.442869 0.600154 +vt 0.443125 0.600383 +vt 0.447089 0.593113 +vt 0.446918 0.592936 +vt 0.446844 0.592856 +vt 0.469554 0.573614 +vt 0.478148 0.568936 +vt 0.469609 0.573719 +vt 0.478193 0.569047 +vt 0.487199 0.565450 +vt 0.487166 0.565333 +vt 0.455508 0.581600 +vt 0.455576 0.581696 +vt 0.461234 0.576499 +vt 0.461173 0.576395 +vt 0.455726 0.581904 +vt 0.461371 0.576721 +vt 0.468537 0.571597 +vt 0.468419 0.571362 +vt 0.468365 0.571250 +vt 0.477231 0.566568 +vt 0.477187 0.566450 +vt 0.477327 0.566817 +vt 0.486549 0.563135 +vt 0.486477 0.562877 +vt 0.486444 0.562754 +vt 0.495018 0.560920 +vt 0.494995 0.560794 +vt 0.495068 0.561184 +vt 0.503267 0.560628 +vt 0.503238 0.560363 +vt 0.503224 0.560237 +vt 0.432778 0.658403 +vt 0.432699 0.658395 +vt 0.432978 0.658414 +vt 0.432823 0.645521 +vt 0.432623 0.645478 +vt 0.432543 0.645457 +vt 0.603915 0.722879 +vt 0.594813 0.727293 +vt 0.613545 0.720555 +vt 0.613551 0.720384 +vt 0.603882 0.722748 +vt 0.594735 0.727188 +vt 0.514849 0.770653 +vt 0.524185 0.769551 +vt 0.524172 0.769410 +vt 0.514848 0.770511 +vt 0.534461 0.766972 +vt 0.534434 0.766835 +vt 0.534380 0.766557 +vt 0.524146 0.769126 +vt 0.514847 0.770223 +vt 0.593074 0.593818 +vt 0.593009 0.593901 +vt 0.443560 0.719045 +vt 0.447560 0.727990 +vt 0.447632 0.727922 +vt 0.443634 0.718989 +vt 0.451958 0.735956 +vt 0.452027 0.735877 +vt 0.452185 0.735692 +vt 0.447800 0.727759 +vt 0.443811 0.718849 +vt 0.596447 0.729128 +vt 0.604830 0.724896 +vt 0.604730 0.724816 +vt 0.596345 0.729045 +vt 0.613679 0.722814 +vt 0.613606 0.722723 +vt 0.613517 0.722524 +vt 0.604573 0.724637 +vt 0.596153 0.728866 +vt 0.565272 0.578461 +vt 0.565216 0.578559 +vt 0.575760 0.584068 +vt 0.575826 0.583978 +vt 0.565087 0.578773 +vt 0.575609 0.584269 +vt 0.585014 0.588789 +vt 0.585167 0.588588 +vt 0.585239 0.588503 +vt 0.480179 0.763521 +vt 0.487600 0.767001 +vt 0.487634 0.766867 +vt 0.480223 0.763394 +vt 0.496062 0.769530 +vt 0.496086 0.769391 +vt 0.496135 0.769108 +vt 0.487706 0.766591 +vt 0.480313 0.763129 +vt 0.558998 0.756627 +vt 0.570126 0.749774 +vt 0.570052 0.749661 +vt 0.558938 0.756505 +vt 0.579793 0.742468 +vt 0.579706 0.742366 +vt 0.579533 0.742155 +vt 0.569904 0.749431 +vt 0.558820 0.756255 +vt 0.440282 0.709631 +vt 0.440358 0.709586 +vt 0.440541 0.709470 +vt 0.460526 0.747405 +vt 0.464445 0.751653 +vt 0.464505 0.751548 +vt 0.460589 0.747308 +vt 0.468691 0.755593 +vt 0.468747 0.755481 +vt 0.468867 0.755239 +vt 0.464634 0.751319 +vt 0.460728 0.747091 +vt 0.546553 0.762541 +vt 0.546510 0.762410 +vt 0.546425 0.762144 +vt 0.593828 0.591142 +vt 0.593900 0.591059 +vt 0.593701 0.591362 +vt 0.602275 0.591584 +vt 0.602367 0.591351 +vt 0.602438 0.591268 +vt 0.363580 0.259541 +vt 0.363569 0.268734 +vt 0.363829 0.268743 +vt 0.363922 0.259523 +vt 0.363518 0.277972 +vt 0.363738 0.277998 +vt 0.364391 0.278000 +vt 0.364756 0.268730 +vt 0.365428 0.259425 +vt 0.777121 0.301492 +vt 0.777125 0.290026 +vt 0.776863 0.290002 +vt 0.776856 0.301473 +vt 0.777131 0.279996 +vt 0.776884 0.279967 +vt 0.776037 0.279963 +vt 0.775912 0.289998 +vt 0.775888 0.301470 +vt 0.363517 0.245959 +vt 0.363553 0.251517 +vt 0.364004 0.251471 +vt 0.364061 0.245891 +vt 0.366271 0.251183 +vt 0.366970 0.245415 +vt 0.777132 0.380544 +vt 0.777127 0.373315 +vt 0.776861 0.373331 +vt 0.776867 0.380562 +vt 0.777122 0.364998 +vt 0.776857 0.365009 +vt 0.775883 0.365011 +vt 0.775887 0.373333 +vt 0.775892 0.380565 +vt 0.363137 0.315955 +vt 0.363071 0.328287 +vt 0.363337 0.328299 +vt 0.363402 0.315974 +vt 0.363032 0.340217 +vt 0.363298 0.340224 +vt 0.364269 0.340222 +vt 0.364307 0.328299 +vt 0.364371 0.315974 +vt 0.653383 0.272005 +vt 0.653405 0.262839 +vt 0.653139 0.262816 +vt 0.653117 0.271986 +vt 0.653429 0.254630 +vt 0.653163 0.254603 +vt 0.652187 0.254600 +vt 0.652162 0.262813 +vt 0.652141 0.271984 +vt 0.363327 0.295182 +vt 0.363225 0.304867 +vt 0.363489 0.304891 +vt 0.363578 0.295211 +vt 0.364444 0.304892 +vt 0.364451 0.295212 +vt 0.653455 0.248006 +vt 0.653189 0.247975 +vt 0.653479 0.242707 +vt 0.653213 0.242673 +vt 0.652237 0.242668 +vt 0.652213 0.247971 +vt 0.363489 0.403701 +vt 0.363578 0.407671 +vt 0.363845 0.407647 +vt 0.363755 0.403678 +vt 0.688867 0.225764 +vt 0.688781 0.230002 +vt 0.689047 0.230037 +vt 0.689133 0.225802 +vt 0.690023 0.230041 +vt 0.690109 0.225807 +vt 0.364820 0.407641 +vt 0.364730 0.403672 +vt 0.401801 0.340110 +vt 0.401789 0.350195 +vt 0.405980 0.350182 +vt 0.405991 0.340096 +vt 0.401802 0.359310 +vt 0.405993 0.359298 +vt 0.406717 0.359297 +vt 0.406704 0.350177 +vt 0.406714 0.340086 +vt 0.688308 0.277732 +vt 0.688271 0.290041 +vt 0.688537 0.290048 +vt 0.688575 0.277743 +vt 0.688248 0.303611 +vt 0.688515 0.303613 +vt 0.689492 0.303613 +vt 0.689514 0.290049 +vt 0.689551 0.277744 +vt 0.777119 0.355782 +vt 0.776853 0.355789 +vt 0.777116 0.346299 +vt 0.776851 0.346301 +vt 0.775879 0.346302 +vt 0.775881 0.355790 +vt 0.688691 0.235044 +vt 0.688957 0.235076 +vt 0.688596 0.241372 +vt 0.688863 0.241399 +vt 0.689839 0.241403 +vt 0.689933 0.235079 +vt 0.653348 0.346193 +vt 0.653082 0.346200 +vt 0.653091 0.356855 +vt 0.653357 0.356844 +vt 0.652105 0.346201 +vt 0.652113 0.356856 +vt 0.652126 0.365985 +vt 0.653103 0.365983 +vt 0.653369 0.365969 +vt 0.688422 0.258055 +vt 0.688358 0.267306 +vt 0.688624 0.267322 +vt 0.688689 0.258074 +vt 0.689601 0.267323 +vt 0.689665 0.258076 +vt 0.401835 0.368537 +vt 0.406027 0.368526 +vt 0.401891 0.377519 +vt 0.406083 0.377508 +vt 0.406807 0.377517 +vt 0.406751 0.368530 +vt 0.363035 0.359428 +vt 0.363069 0.368661 +vt 0.363336 0.368654 +vt 0.363302 0.359425 +vt 0.363126 0.377647 +vt 0.363392 0.377636 +vt 0.364366 0.377631 +vt 0.364309 0.368650 +vt 0.364274 0.359422 +vt 0.727080 0.349273 +vt 0.731276 0.349272 +vt 0.731235 0.340350 +vt 0.727039 0.340351 +vt 0.732001 0.349285 +vt 0.731960 0.340359 +vt 0.731934 0.329969 +vt 0.731209 0.329963 +vt 0.727014 0.329965 +vt 0.688652 0.380879 +vt 0.688919 0.380851 +vt 0.688818 0.373843 +vt 0.688551 0.373867 +vt 0.689896 0.380847 +vt 0.689795 0.373839 +vt 0.689701 0.365963 +vt 0.688724 0.365966 +vt 0.688458 0.365987 +vt 0.727624 0.391568 +vt 0.731820 0.391570 +vt 0.731707 0.386557 +vt 0.727511 0.386555 +vt 0.732545 0.391603 +vt 0.732432 0.386587 +vt 0.732330 0.380851 +vt 0.731605 0.380824 +vt 0.727409 0.380823 +vt 0.688867 0.391631 +vt 0.689133 0.391598 +vt 0.689020 0.386584 +vt 0.688754 0.386615 +vt 0.690111 0.391592 +vt 0.689998 0.386579 +vt 0.404431 0.278259 +vt 0.403387 0.286658 +vt 0.406537 0.286467 +vt 0.406744 0.277917 +vt 0.402463 0.295163 +vt 0.406331 0.295091 +vt 0.407009 0.295051 +vt 0.407113 0.286407 +vt 0.407200 0.277841 +vt 0.210652 0.384322 +vt 0.210386 0.384313 +vt 0.210385 0.393488 +vt 0.210651 0.393501 +vt 0.209409 0.384311 +vt 0.209408 0.393486 +vt 0.209405 0.402295 +vt 0.210383 0.402297 +vt 0.210648 0.402314 +vt 0.653354 0.292383 +vt 0.653367 0.281600 +vt 0.653101 0.281585 +vt 0.653089 0.292372 +vt 0.652124 0.281583 +vt 0.652112 0.292370 +vt 0.756549 0.906018 +vt 0.756328 0.906030 +vt 0.756276 0.917677 +vt 0.756413 0.917661 +vt 0.755396 0.906030 +vt 0.755429 0.917678 +vt 0.755493 0.929191 +vt 0.756289 0.929190 +vt 0.756374 0.929170 +vt 0.210644 0.350776 +vt 0.210378 0.350781 +vt 0.210382 0.359591 +vt 0.210648 0.359590 +vt 0.209400 0.350782 +vt 0.209404 0.359591 +vt 0.209407 0.367890 +vt 0.210384 0.367890 +vt 0.210650 0.367893 +vt 0.777144 0.391602 +vt 0.777138 0.386627 +vt 0.776873 0.386648 +vt 0.776878 0.391625 +vt 0.775898 0.386651 +vt 0.775903 0.391628 +vt 0.171847 0.308572 +vt 0.167649 0.308570 +vt 0.167659 0.319696 +vt 0.171856 0.319698 +vt 0.166924 0.308549 +vt 0.166933 0.319679 +vt 0.166941 0.330948 +vt 0.167667 0.330960 +vt 0.171864 0.330961 +vt 0.363022 0.350308 +vt 0.363288 0.350310 +vt 0.364260 0.350308 +vt 0.401908 0.315862 +vt 0.401841 0.328186 +vt 0.406030 0.328172 +vt 0.406095 0.315846 +vt 0.406753 0.328156 +vt 0.406819 0.315824 +vt 0.756458 0.939513 +vt 0.756594 0.939490 +vt 0.755610 0.939515 +vt 0.755727 0.948737 +vt 0.756659 0.948735 +vt 0.756880 0.948709 +vt 0.738350 0.365018 +vt 0.738346 0.355797 +vt 0.734153 0.355797 +vt 0.734157 0.365018 +vt 0.738343 0.346309 +vt 0.734151 0.346310 +vt 0.733426 0.346307 +vt 0.733428 0.355790 +vt 0.733432 0.365006 +vt 0.210588 0.271022 +vt 0.210322 0.271052 +vt 0.210309 0.280185 +vt 0.210574 0.280156 +vt 0.209344 0.271057 +vt 0.209334 0.280189 +vt 0.209240 0.289282 +vt 0.210198 0.289278 +vt 0.210461 0.289251 +vt 0.757028 0.965794 +vt 0.756762 0.965824 +vt 0.756724 0.974620 +vt 0.755785 0.965826 +vt 0.755754 0.974640 +vt 0.755765 0.982368 +vt 0.756683 0.982227 +vt 0.172060 0.253592 +vt 0.167655 0.253540 +vt 0.167627 0.261967 +vt 0.171850 0.261973 +vt 0.166898 0.271044 +vt 0.167624 0.271074 +vt 0.171821 0.271076 +vt 0.653342 0.319071 +vt 0.653076 0.319069 +vt 0.653077 0.333251 +vt 0.653343 0.333249 +vt 0.652099 0.319069 +vt 0.652100 0.333252 +vt 0.210587 0.254227 +vt 0.210330 0.254233 +vt 0.210322 0.262017 +vt 0.210587 0.261988 +vt 0.209413 0.254117 +vt 0.209352 0.262006 +vt 0.171876 0.350790 +vt 0.167679 0.350791 +vt 0.167683 0.359601 +vt 0.171880 0.359600 +vt 0.166953 0.350786 +vt 0.166957 0.359600 +vt 0.166960 0.367903 +vt 0.167686 0.367900 +vt 0.171883 0.367899 +vt 0.363297 0.392849 +vt 0.363394 0.398814 +vt 0.363660 0.398793 +vt 0.363563 0.392831 +vt 0.364635 0.398787 +vt 0.364538 0.392825 +vt 0.719437 0.996238 +vt 0.713971 0.996668 +vt 0.713967 0.996829 +vt 0.719434 0.996402 +vt 0.713096 0.996702 +vt 0.713066 0.996808 +vt 0.126797 0.014739 +vt 0.126791 0.013836 +vt 0.126580 0.013849 +vt 0.126594 0.014757 +vt 0.126557 0.020247 +vt 0.126359 0.020265 +vt 0.756566 0.867927 +vt 0.756299 0.867923 +vt 0.756294 0.876469 +vt 0.756560 0.876469 +vt 0.755321 0.867921 +vt 0.755316 0.876467 +vt 0.755329 0.885550 +vt 0.756307 0.885551 +vt 0.756573 0.885548 +vt 0.215133 0.703844 +vt 0.215350 0.703917 +vt 0.215351 0.703752 +vt 0.215139 0.703683 +vt 0.626325 0.975725 +vt 0.627061 0.976064 +vt 0.627110 0.975900 +vt 0.626386 0.975564 +vt 0.627099 0.975803 +vt 0.626381 0.975469 +vt 0.215354 0.703657 +vt 0.215169 0.703614 +vt 0.653466 0.397993 +vt 0.653200 0.398021 +vt 0.653230 0.403788 +vt 0.653496 0.403757 +vt 0.652223 0.398025 +vt 0.652252 0.403793 +vt 0.652284 0.408805 +vt 0.653262 0.408800 +vt 0.653528 0.408766 +vt 0.756835 0.991272 +vt 0.756652 0.991410 +vt 0.756654 0.991575 +vt 0.756865 0.991387 +vt 0.756035 0.992273 +vt 0.756035 0.992442 +vt 0.625741 0.977450 +vt 0.626594 0.977805 +vt 0.626695 0.977631 +vt 0.625855 0.977282 +vt 0.625558 0.977337 +vt 0.625682 0.977180 +vt 0.209956 0.298541 +vt 0.210214 0.298516 +vt 0.209036 0.298544 +vt 0.208917 0.308563 +vt 0.209815 0.308560 +vt 0.210070 0.308539 +vt 0.731197 0.317364 +vt 0.727002 0.317366 +vt 0.731922 0.317365 +vt 0.731926 0.303583 +vt 0.731201 0.303586 +vt 0.727006 0.303589 +vt 0.719234 0.993832 +vt 0.713964 0.994175 +vt 0.713969 0.996160 +vt 0.719418 0.995742 +vt 0.713085 0.994262 +vt 0.713069 0.996255 +vt 0.653121 0.374609 +vt 0.653387 0.374591 +vt 0.652144 0.374611 +vt 0.652166 0.382961 +vt 0.653144 0.382958 +vt 0.653410 0.382937 +vt 0.171885 0.384320 +vt 0.167688 0.384322 +vt 0.167687 0.393498 +vt 0.171884 0.393495 +vt 0.166962 0.384332 +vt 0.166961 0.393511 +vt 0.166958 0.402324 +vt 0.167684 0.402307 +vt 0.171881 0.402303 +vt 0.727066 0.277720 +vt 0.727028 0.290025 +vt 0.731224 0.290021 +vt 0.731261 0.277716 +vt 0.731949 0.290013 +vt 0.731986 0.277704 +vt 0.688647 0.357756 +vt 0.688381 0.357773 +vt 0.689625 0.357753 +vt 0.689566 0.349297 +vt 0.688589 0.349300 +vt 0.688323 0.349313 +vt 0.756834 0.832659 +vt 0.756567 0.832641 +vt 0.756460 0.841652 +vt 0.756727 0.841666 +vt 0.755590 0.832636 +vt 0.755483 0.841647 +vt 0.755396 0.851048 +vt 0.756374 0.851052 +vt 0.756640 0.851062 +vt 0.717813 0.885463 +vt 0.713616 0.885453 +vt 0.713650 0.895224 +vt 0.717846 0.895235 +vt 0.712891 0.885447 +vt 0.712925 0.895214 +vt 0.712981 0.905918 +vt 0.713706 0.905932 +vt 0.717902 0.905943 +vt 0.777141 0.262676 +vt 0.777144 0.254166 +vt 0.776895 0.254127 +vt 0.776935 0.262640 +vt 0.777144 0.245785 +vt 0.776806 0.245743 +vt 0.775324 0.245645 +vt 0.776037 0.254110 +vt 0.776379 0.262634 +vt 0.688257 0.329997 +vt 0.688523 0.329990 +vt 0.688511 0.317391 +vt 0.688244 0.317393 +vt 0.689500 0.329989 +vt 0.689488 0.317390 +vt 0.777140 0.232661 +vt 0.777132 0.230380 +vt 0.776557 0.230333 +vt 0.776598 0.232617 +vt 0.777102 0.230005 +vt 0.776547 0.229932 +vt 0.773330 0.229372 +vt 0.773375 0.229788 +vt 0.773688 0.232153 +vt 0.718233 0.948651 +vt 0.714037 0.948637 +vt 0.714074 0.957188 +vt 0.718270 0.957202 +vt 0.713312 0.948609 +vt 0.713349 0.957158 +vt 0.713340 0.965677 +vt 0.714065 0.965710 +vt 0.718262 0.965726 +vt 0.777137 0.271100 +vt 0.776920 0.271067 +vt 0.776287 0.271062 +vt 0.363431 0.286538 +vt 0.363658 0.286570 +vt 0.364361 0.286572 +vt 0.777115 0.326527 +vt 0.777117 0.314224 +vt 0.776853 0.314211 +vt 0.776851 0.326520 +vt 0.775883 0.314209 +vt 0.775880 0.326519 +vt 0.439807 0.856524 +vt 0.439881 0.856564 +vt 0.442978 0.846037 +vt 0.442905 0.845985 +vt 0.440067 0.856660 +vt 0.443157 0.846160 +vt 0.591211 0.967971 +vt 0.591139 0.967701 +vt 0.600378 0.967447 +vt 0.600359 0.967134 +vt 0.600302 0.967041 +vt 0.591078 0.967611 +vt 0.474922 0.757129 +vt 0.481055 0.760950 +vt 0.481100 0.760817 +vt 0.474974 0.757002 +vt 0.473882 0.759604 +vt 0.473933 0.759484 +vt 0.474040 0.759231 +vt 0.629427 0.723413 +vt 0.632294 0.723777 +vt 0.632370 0.723619 +vt 0.629477 0.723263 +vt 0.632751 0.723802 +vt 0.632827 0.723668 +vt 0.632944 0.723375 +vt 0.632482 0.723324 +vt 0.629557 0.722985 +vt 0.511795 0.560752 +vt 0.511791 0.560627 +vt 0.511802 0.561016 +vt 0.520911 0.562383 +vt 0.520928 0.562124 +vt 0.520936 0.562001 +vt 0.630730 0.582779 +vt 0.630726 0.582970 +vt 0.632599 0.582014 +vt 0.632600 0.581807 +vt 0.166838 0.241943 +vt 0.166902 0.241940 +vt 0.166909 0.240024 +vt 0.166847 0.240023 +vt 0.166939 0.239696 +vt 0.166909 0.239670 +vt 0.632944 0.581839 +vt 0.632951 0.581603 +vt 0.586501 0.733410 +vt 0.578126 0.740439 +vt 0.586408 0.733310 +vt 0.578040 0.740330 +vt 0.505586 0.767952 +vt 0.496531 0.766813 +vt 0.505598 0.767804 +vt 0.496556 0.766667 +vt 0.456354 0.742337 +vt 0.456421 0.742249 +vt 0.456569 0.742046 +vt 0.545736 0.760005 +vt 0.557864 0.754241 +vt 0.557805 0.754112 +vt 0.545694 0.759868 +vt 0.541679 0.568181 +vt 0.541647 0.568294 +vt 0.553484 0.573088 +vt 0.553529 0.572983 +vt 0.541578 0.568536 +vt 0.553385 0.573317 +vt 0.632656 0.721661 +vt 0.632621 0.721319 +vt 0.629743 0.720963 +vt 0.633113 0.721714 +vt 0.633074 0.721377 +vt 0.633046 0.721172 +vt 0.632600 0.721071 +vt 0.629731 0.720720 +vt 0.433164 0.634806 +vt 0.433084 0.634775 +vt 0.433364 0.634875 +vt 0.568707 0.747560 +vt 0.568634 0.747441 +vt 0.503514 0.562882 +vt 0.511860 0.563263 +vt 0.503528 0.563001 +vt 0.511864 0.563381 +vt 0.588329 0.735275 +vt 0.588233 0.735183 +vt 0.588041 0.734992 +vt 0.505353 0.770696 +vt 0.505365 0.770555 +vt 0.505390 0.770268 +vt 0.435731 0.672273 +vt 0.434843 0.658513 +vt 0.435810 0.672260 +vt 0.434922 0.658514 +vt 0.434770 0.645928 +vt 0.434690 0.645915 +vt 0.462549 0.578629 +vt 0.462611 0.578726 +vt 0.495497 0.563424 +vt 0.495520 0.563543 +vt 0.444731 0.601785 +vt 0.444808 0.601850 +vt 0.435215 0.635511 +vt 0.435296 0.635535 +vt 0.488286 0.764345 +vt 0.488321 0.764204 +vt 0.450990 0.586954 +vt 0.450919 0.586865 +vt 0.451151 0.587147 +vt 0.442220 0.708412 +vt 0.439600 0.698052 +vt 0.442296 0.708360 +vt 0.439677 0.698012 +vt 0.552517 0.575311 +vt 0.552473 0.575409 +vt 0.457857 0.740285 +vt 0.457924 0.740190 +vt 0.530795 0.564619 +vt 0.530814 0.564501 +vt 0.530754 0.564871 +vt 0.437381 0.685799 +vt 0.437459 0.685772 +vt 0.611172 0.589257 +vt 0.611239 0.589177 +vt 0.611104 0.589473 +vt 0.619421 0.586186 +vt 0.619452 0.585985 +vt 0.713285 0.974554 +vt 0.713223 0.974484 +vt 0.713146 0.982887 +vt 0.713209 0.982928 +vt 0.479332 0.799789 +vt 0.479379 0.799914 +vt 0.478434 0.797394 +vt 0.478389 0.797268 +vt 0.478531 0.797652 +vt 0.484948 0.793992 +vt 0.484868 0.793723 +vt 0.484829 0.793590 +vt 0.629228 0.839053 +vt 0.629272 0.839208 +vt 0.631618 0.838892 +vt 0.631549 0.838728 +vt 0.629340 0.839490 +vt 0.631719 0.839192 +vt 0.632104 0.839145 +vt 0.631997 0.838847 +vt 0.631927 0.838709 +vt 0.508652 0.997834 +vt 0.508659 0.997712 +vt 0.508676 0.997449 +vt 0.625961 0.975501 +vt 0.626034 0.975347 +vt 0.624875 0.974835 +vt 0.626188 0.975642 +vt 0.626254 0.975485 +vt 0.626264 0.975417 +vt 0.626068 0.975291 +vt 0.624907 0.974783 +vt 0.589907 0.827806 +vt 0.589812 0.827900 +vt 0.510383 0.790136 +vt 0.510391 0.790281 +vt 0.460277 0.813968 +vt 0.460215 0.813874 +vt 0.460417 0.814177 +vt 0.550195 0.799629 +vt 0.550148 0.799761 +vt 0.550831 0.987071 +vt 0.550791 0.986967 +vt 0.550701 0.986735 +vt 0.629475 0.841181 +vt 0.629449 0.841519 +vt 0.631781 0.841203 +vt 0.631828 0.840863 +vt 0.629429 0.841759 +vt 0.631751 0.841447 +vt 0.632122 0.841352 +vt 0.632157 0.841149 +vt 0.632209 0.840814 +vt 0.432849 0.920615 +vt 0.432929 0.920591 +vt 0.433131 0.920529 +vt 0.574094 0.810913 +vt 0.574173 0.810799 +vt 0.573938 0.811138 +vt 0.583280 0.818788 +vt 0.583461 0.818583 +vt 0.583552 0.818481 +vt 0.508821 0.995202 +vt 0.500467 0.995263 +vt 0.517772 0.994202 +vt 0.517771 0.994082 +vt 0.508830 0.995080 +vt 0.500486 0.995141 +vt 0.591706 0.826098 +vt 0.591806 0.826007 +vt 0.591506 0.826283 +vt 0.500929 0.788187 +vt 0.500947 0.788330 +vt 0.510263 0.787522 +vt 0.510257 0.787377 +vt 0.500984 0.788616 +vt 0.510276 0.787811 +vt 0.435514 0.896931 +vt 0.434879 0.909533 +vt 0.434961 0.909519 +vt 0.435594 0.896930 +vt 0.460140 0.977933 +vt 0.454823 0.972644 +vt 0.460207 0.977834 +vt 0.454895 0.972554 +vt 0.492477 0.994412 +vt 0.492506 0.994291 +vt 0.443223 0.954077 +vt 0.446816 0.961342 +vt 0.446894 0.961268 +vt 0.443304 0.954012 +vt 0.435006 0.919964 +vt 0.435088 0.919939 +vt 0.492406 0.790532 +vt 0.492377 0.790393 +vt 0.492466 0.790811 +vt 0.450555 0.967337 +vt 0.450631 0.967254 +vt 0.444793 0.847283 +vt 0.444868 0.847334 +vt 0.538254 0.989192 +vt 0.550000 0.984938 +vt 0.549909 0.984706 +vt 0.538194 0.988947 +vt 0.549870 0.984602 +vt 0.538168 0.988837 +vt 0.461637 0.815989 +vt 0.461701 0.816083 +vt 0.527513 0.992386 +vt 0.527481 0.992132 +vt 0.527468 0.992016 +vt 0.437122 0.869053 +vt 0.437047 0.869026 +vt 0.437314 0.869118 +vt 0.609269 0.968941 +vt 0.616805 0.971636 +vt 0.616760 0.971556 +vt 0.609211 0.968850 +vt 0.124512 0.014055 +vt 0.124530 0.014963 +vt 0.125024 0.014915 +vt 0.124987 0.014009 +vt 0.124368 0.020461 +vt 0.124833 0.020417 +vt 0.125412 0.020361 +vt 0.125632 0.014855 +vt 0.125584 0.013951 +vt 0.659455 0.235052 +vt 0.659510 0.233123 +vt 0.659144 0.233112 +vt 0.659089 0.235041 +vt 0.659525 0.232722 +vt 0.659158 0.232711 +vt 0.658752 0.232700 +vt 0.658738 0.233101 +vt 0.658683 0.235030 +vt 0.144157 0.128373 +vt 0.144121 0.127785 +vt 0.143756 0.127807 +vt 0.143791 0.128395 +vt 0.143952 0.124553 +vt 0.143586 0.124575 +vt 0.143181 0.124601 +vt 0.143350 0.127833 +vt 0.143385 0.128421 +vt 0.629654 0.722574 +vt 0.622605 0.722352 +vt 0.632613 0.581380 +vt 0.632944 0.581126 +vt 0.632975 0.580526 +vt 0.632654 0.580811 +vt 0.632719 0.580213 +vt 0.633078 0.579952 +vt 0.591273 0.968504 +vt 0.582100 0.971095 +vt 0.582363 0.971602 +vt 0.591363 0.969156 +vt 0.591511 0.969749 +vt 0.582648 0.972091 +vt 0.572456 0.975353 +vt 0.561873 0.980399 +vt 0.562134 0.980872 +vt 0.572764 0.975811 +vt 0.573074 0.976266 +vt 0.562395 0.981345 +vt 0.631880 0.840496 +vt 0.632266 0.840450 +vt 0.632281 0.840044 +vt 0.631892 0.840088 +vt 0.631826 0.839622 +vt 0.632215 0.839578 +vt 0.517819 0.995990 +vt 0.527568 0.992817 +vt 0.538357 0.989610 +vt 0.527636 0.993352 +vt 0.538485 0.990129 +vt 0.527704 0.993887 +vt 0.538613 0.990648 +vt 0.550156 0.985339 +vt 0.550350 0.985837 +vt 0.550545 0.986335 +vt 0.624440 0.976228 +vt 0.621545 0.975580 +vt 0.624289 0.976543 +vt 0.756886 0.989834 +vt 0.756869 0.990975 +vt 0.756931 0.991088 +vt 0.756950 0.989933 +vt 0.625159 0.977149 +vt 0.625444 0.977326 +vt 0.625272 0.977143 +vt 0.625417 0.977009 +vt 0.624151 0.976662 +vt 0.658277 0.233090 +vt 0.658223 0.235019 +vt 0.658292 0.232689 +vt 0.657867 0.232681 +vt 0.657852 0.233082 +vt 0.657798 0.235010 +vt 0.142891 0.127864 +vt 0.142926 0.128452 +vt 0.142722 0.124632 +vt 0.142298 0.124663 +vt 0.142467 0.127894 +vt 0.142502 0.128482 +vt 0.626816 0.976747 +vt 0.626036 0.976400 +vt 0.625937 0.976882 +vt 0.626749 0.977229 +vt 0.215350 0.704609 +vt 0.215132 0.704543 +vt 0.215134 0.705021 +vt 0.215352 0.705095 +vt 0.215135 0.705410 +vt 0.215354 0.705500 +vt 0.126188 0.014799 +vt 0.126154 0.013893 +vt 0.125955 0.020306 +vt 0.777115 0.336920 +vt 0.776850 0.336918 +vt 0.775879 0.336918 +vt 0.738362 0.380572 +vt 0.738355 0.373340 +vt 0.734162 0.373339 +vt 0.734168 0.380570 +vt 0.733437 0.373324 +vt 0.733442 0.380552 +vt 0.626187 0.976002 +vt 0.626940 0.976345 +vt 0.215132 0.704134 +vt 0.215350 0.704202 +vt 0.167688 0.375920 +vt 0.171885 0.375918 +vt 0.166962 0.375926 +vt 0.657338 0.235001 +vt 0.657502 0.235004 +vt 0.657557 0.233078 +vt 0.657399 0.233079 +vt 0.657575 0.232682 +vt 0.657441 0.232710 +vt 0.718295 0.819283 +vt 0.714099 0.819276 +vt 0.713988 0.825147 +vt 0.718185 0.825154 +vt 0.713374 0.819297 +vt 0.713263 0.825166 +vt 0.713152 0.832558 +vt 0.713877 0.832543 +vt 0.718073 0.832550 +vt 0.737161 0.271112 +vt 0.734021 0.271080 +vt 0.733446 0.271108 +vt 0.731504 0.373816 +vt 0.727308 0.373815 +vt 0.732229 0.373839 +vt 0.732135 0.365959 +vt 0.731411 0.365939 +vt 0.727215 0.365939 +vt 0.713770 0.841553 +vt 0.717966 0.841561 +vt 0.713045 0.841566 +vt 0.712958 0.850962 +vt 0.713683 0.850953 +vt 0.717880 0.850962 +vt 0.731334 0.357729 +vt 0.727138 0.357729 +vt 0.732059 0.357745 +vt 0.614574 0.319074 +vt 0.610378 0.319074 +vt 0.610379 0.333257 +vt 0.614576 0.333257 +vt 0.609652 0.319076 +vt 0.609653 0.333254 +vt 0.609659 0.346199 +vt 0.610384 0.346206 +vt 0.614581 0.346206 +vt 0.167681 0.409550 +vt 0.171878 0.409546 +vt 0.166955 0.409570 +vt 0.166951 0.415334 +vt 0.167677 0.415312 +vt 0.171874 0.415308 +vt 0.614603 0.365990 +vt 0.610406 0.365988 +vt 0.610423 0.374614 +vt 0.614620 0.374616 +vt 0.609680 0.365974 +vt 0.609698 0.374597 +vt 0.609720 0.382942 +vt 0.610446 0.382963 +vt 0.614643 0.382965 +vt 0.167674 0.341324 +vt 0.171871 0.341324 +vt 0.166948 0.341315 +vt 0.610393 0.356860 +vt 0.614590 0.356861 +vt 0.609667 0.356850 +vt 0.171830 0.289290 +vt 0.167633 0.289287 +vt 0.167641 0.298550 +vt 0.171838 0.298553 +vt 0.166907 0.289261 +vt 0.166915 0.298526 +vt 0.142076 0.128477 +vt 0.142211 0.128497 +vt 0.142172 0.127914 +vt 0.142014 0.127923 +vt 0.142002 0.124685 +vt 0.141840 0.124699 +vt 0.614700 0.398030 +vt 0.610503 0.398027 +vt 0.610532 0.403793 +vt 0.614729 0.403797 +vt 0.609777 0.397999 +vt 0.609806 0.403763 +vt 0.609838 0.408772 +vt 0.610564 0.408806 +vt 0.614761 0.408810 +vt 0.173014 0.242254 +vt 0.167777 0.241980 +vt 0.167716 0.246608 +vt 0.172537 0.246772 +vt 0.166901 0.246573 +vt 0.717805 0.867834 +vt 0.713609 0.867825 +vt 0.713603 0.876371 +vt 0.717800 0.876381 +vt 0.712884 0.867826 +vt 0.712878 0.876369 +vt 0.167627 0.280196 +vt 0.171824 0.280199 +vt 0.166901 0.280168 +vt 0.363204 0.385774 +vt 0.363471 0.385758 +vt 0.364445 0.385753 +vt 0.713782 0.917579 +vt 0.717978 0.917591 +vt 0.713057 0.917561 +vt 0.713146 0.929070 +vt 0.713871 0.929092 +vt 0.718067 0.929105 +vt 0.210588 0.245824 +vt 0.210365 0.245728 +vt 0.210348 0.248821 +vt 0.210588 0.248866 +vt 0.209692 0.245123 +vt 0.209552 0.248460 +vt 0.401969 0.385641 +vt 0.406162 0.385630 +vt 0.402061 0.392713 +vt 0.406255 0.392703 +vt 0.406979 0.392718 +vt 0.406886 0.385643 +vt 0.735776 0.229485 +vt 0.735777 0.226652 +vt 0.733851 0.226648 +vt 0.733850 0.229482 +vt 0.735778 0.226170 +vt 0.733854 0.226169 +vt 0.733485 0.226162 +vt 0.733454 0.226617 +vt 0.733449 0.229460 +vt 0.714015 0.974585 +vt 0.718241 0.974597 +vt 0.713966 0.982939 +vt 0.718381 0.982893 +vt 0.209974 0.319686 +vt 0.210232 0.319669 +vt 0.209053 0.319689 +vt 0.209274 0.330952 +vt 0.210232 0.330950 +vt 0.210495 0.330938 +vt 0.727355 0.241379 +vt 0.727262 0.249244 +vt 0.731457 0.249238 +vt 0.731549 0.241372 +vt 0.727180 0.258052 +vt 0.731375 0.258047 +vt 0.732100 0.258027 +vt 0.732182 0.249214 +vt 0.732274 0.241344 +vt 0.713963 0.939415 +vt 0.718159 0.939428 +vt 0.713238 0.939390 +vt 0.614710 0.242673 +vt 0.614733 0.238205 +vt 0.610538 0.238211 +vt 0.610515 0.242679 +vt 0.614759 0.234026 +vt 0.610564 0.234033 +vt 0.609839 0.234073 +vt 0.609813 0.238248 +vt 0.609790 0.242713 +vt 0.614661 0.254604 +vt 0.614686 0.247975 +vt 0.610491 0.247980 +vt 0.610465 0.254609 +vt 0.609765 0.248011 +vt 0.609740 0.254636 +vt 0.756662 0.989893 +vt 0.756658 0.991053 +vt 0.755982 0.990592 +vt 0.756031 0.991883 +vt 0.653502 0.238242 +vt 0.653237 0.238205 +vt 0.653528 0.234067 +vt 0.653262 0.234027 +vt 0.652287 0.234022 +vt 0.652261 0.238200 +vt 0.210356 0.341314 +vt 0.210621 0.341305 +vt 0.209380 0.341316 +vt 0.756756 0.957288 +vt 0.757017 0.957260 +vt 0.755785 0.957290 +vt 0.653346 0.305089 +vt 0.653080 0.305082 +vt 0.652103 0.305082 +vt 0.210386 0.375910 +vt 0.210652 0.375916 +vt 0.209408 0.375909 +vt 0.738340 0.336925 +vt 0.734150 0.336926 +vt 0.738340 0.326526 +vt 0.734150 0.326528 +vt 0.733425 0.326536 +vt 0.733425 0.336928 +vt 0.210379 0.409540 +vt 0.210645 0.409560 +vt 0.209402 0.409538 +vt 0.209398 0.415300 +vt 0.210375 0.415303 +vt 0.210641 0.415324 +vt 0.756332 0.895323 +vt 0.756593 0.895315 +vt 0.755360 0.895321 +vt 0.688549 0.340377 +vt 0.688282 0.340387 +vt 0.689526 0.340375 +vt 0.756322 0.859677 +vt 0.756589 0.859684 +vt 0.755345 0.859674 +vt 0.713632 0.859578 +vt 0.717828 0.859587 +vt 0.712907 0.859583 +vt 0.757056 0.819397 +vt 0.756789 0.819375 +vt 0.756679 0.825245 +vt 0.756945 0.825266 +vt 0.755812 0.819369 +vt 0.755701 0.825240 +vt 0.688504 0.249242 +vt 0.688770 0.249265 +vt 0.689747 0.249268 +vt 0.653171 0.390941 +vt 0.653437 0.390917 +vt 0.652193 0.390945 +vt 0.610473 0.390947 +vt 0.614670 0.390950 +vt 0.609748 0.390922 +vt 0.727540 0.230017 +vt 0.727449 0.235056 +vt 0.731644 0.235048 +vt 0.731734 0.230009 +vt 0.732368 0.235016 +vt 0.732459 0.229974 +vt 0.727116 0.267299 +vt 0.731311 0.267294 +vt 0.732036 0.267278 +vt 0.614579 0.305086 +vt 0.610382 0.305088 +vt 0.614587 0.292375 +vt 0.610391 0.292377 +vt 0.609665 0.292388 +vt 0.609657 0.305094 +vt 0.402157 0.398675 +vt 0.406351 0.398665 +vt 0.402252 0.403560 +vt 0.406446 0.403550 +vt 0.407170 0.403570 +vt 0.407076 0.398683 +vt 0.402341 0.407529 +vt 0.406535 0.407520 +vt 0.727626 0.225783 +vt 0.731820 0.225775 +vt 0.732545 0.225736 +vt 0.407260 0.407540 +vt 0.614615 0.271988 +vt 0.614637 0.262818 +vt 0.610441 0.262822 +vt 0.610419 0.271991 +vt 0.609715 0.262845 +vt 0.609694 0.272010 +vt 0.614599 0.281588 +vt 0.610403 0.281590 +vt 0.609677 0.281605 +vt 0.402043 0.304787 +vt 0.406189 0.304764 +vt 0.406907 0.304736 +vt 0.738374 0.391635 +vt 0.738368 0.386658 +vt 0.734173 0.386656 +vt 0.734179 0.391633 +vt 0.733448 0.386635 +vt 0.733454 0.391610 +vt 0.144494 0.128346 +vt 0.144464 0.127763 +vt 0.144696 0.128303 +vt 0.144714 0.127745 +vt 0.144556 0.124518 +vt 0.144297 0.124533 +vt 0.738340 0.314216 +vt 0.734152 0.314219 +vt 0.733427 0.314232 +vt 0.404866 0.242628 +vt 0.404876 0.249485 +vt 0.406827 0.249461 +vt 0.406793 0.242622 +vt 0.404704 0.258948 +vt 0.406831 0.258789 +vt 0.407260 0.258769 +vt 0.407230 0.249462 +vt 0.407193 0.242620 +vt 0.659801 0.235062 +vt 0.659854 0.233135 +vt 0.660060 0.235070 +vt 0.660104 0.233146 +vt 0.660066 0.232776 +vt 0.659862 0.232739 +vt 0.124285 0.014988 +vt 0.124135 0.020484 +vt 0.124277 0.014085 +vt 0.124226 0.014121 +vt 0.124232 0.014998 +vt 0.173260 0.239999 +vt 0.167809 0.239677 +vt 0.167812 0.239729 +vt 0.173258 0.240051 +vt 0.141834 0.109722 +vt 0.141546 0.109747 +vt 0.141669 0.117476 +vt 0.141963 0.117453 +vt 0.141389 0.109763 +vt 0.141507 0.117492 +vt 0.659007 0.239285 +vt 0.659373 0.239296 +vt 0.658601 0.239274 +vt 0.658730 0.244111 +vt 0.659134 0.244121 +vt 0.659500 0.244131 +vt 0.731696 0.995516 +vt 0.731706 0.995357 +vt 0.125824 0.032615 +vt 0.126016 0.032600 +vt 0.125536 0.045090 +vt 0.125723 0.045076 +vt 0.744116 0.995331 +vt 0.744135 0.995171 +vt 0.628695 0.977135 +vt 0.628773 0.976843 +vt 0.628631 0.977546 +vt 0.630712 0.978444 +vt 0.630715 0.978024 +vt 0.630750 0.977720 +vt 0.771369 0.301471 +vt 0.771266 0.314210 +vt 0.773842 0.314210 +vt 0.773862 0.301471 +vt 0.771245 0.326520 +vt 0.773835 0.326520 +vt 0.366948 0.277992 +vt 0.368841 0.268709 +vt 0.366658 0.268703 +vt 0.365631 0.277996 +vt 0.372441 0.259334 +vt 0.368689 0.259246 +vt 0.181305 0.375916 +vt 0.181303 0.367897 +vt 0.181305 0.384318 +vt 0.191264 0.384316 +vt 0.191263 0.375913 +vt 0.191262 0.367894 +vt 0.204748 0.384313 +vt 0.204747 0.393487 +vt 0.207346 0.393487 +vt 0.207348 0.384312 +vt 0.204745 0.402296 +vt 0.207344 0.402295 +vt 0.735801 0.236224 +vt 0.740211 0.236353 +vt 0.740050 0.229720 +vt 0.740837 0.245101 +vt 0.747831 0.245020 +vt 0.745977 0.237290 +vt 0.745131 0.231367 +vt 0.694149 0.303610 +vt 0.694171 0.290046 +vt 0.691574 0.290047 +vt 0.691551 0.303611 +vt 0.694208 0.277741 +vt 0.691611 0.277743 +vt 0.694360 0.365960 +vt 0.694283 0.357750 +vt 0.691685 0.357752 +vt 0.691762 0.365962 +vt 0.694225 0.349294 +vt 0.691627 0.349296 +vt 0.750662 0.867910 +vt 0.750657 0.876456 +vt 0.753255 0.876462 +vt 0.753261 0.867916 +vt 0.750670 0.885539 +vt 0.753268 0.885545 +vt 0.717622 0.340357 +vt 0.717663 0.349279 +vt 0.717597 0.329971 +vt 0.707642 0.329977 +vt 0.707667 0.340364 +vt 0.707708 0.349285 +vt 0.647446 0.346202 +vt 0.647454 0.356857 +vt 0.650053 0.356857 +vt 0.650044 0.346202 +vt 0.647467 0.365986 +vt 0.650065 0.365985 +vt 0.624090 0.390948 +vt 0.624063 0.382964 +vt 0.624119 0.398029 +vt 0.634077 0.398028 +vt 0.634048 0.390947 +vt 0.634020 0.382963 +vt 0.647563 0.398026 +vt 0.647592 0.403793 +vt 0.650191 0.403793 +vt 0.650162 0.398025 +vt 0.647624 0.408806 +vt 0.650223 0.408805 +vt 0.181258 0.298551 +vt 0.181251 0.289288 +vt 0.181267 0.308570 +vt 0.191225 0.308567 +vt 0.191217 0.298548 +vt 0.191209 0.289286 +vt 0.624009 0.356860 +vt 0.624000 0.346205 +vt 0.624022 0.365989 +vt 0.633980 0.365987 +vt 0.633967 0.356859 +vt 0.633958 0.346204 +vt 0.181276 0.319695 +vt 0.181284 0.330959 +vt 0.191243 0.330957 +vt 0.191234 0.319693 +vt 0.630748 0.977548 +vt 0.628797 0.976675 +vt 0.630692 0.977451 +vt 0.628769 0.976581 +vt 0.173226 0.240389 +vt 0.185385 0.241027 +vt 0.185482 0.240696 +vt 0.184761 0.242803 +vt 0.196739 0.242915 +vt 0.197720 0.241131 +vt 0.197870 0.240769 +vt 0.181328 0.261973 +vt 0.181944 0.253685 +vt 0.181241 0.271069 +vt 0.191199 0.271063 +vt 0.191337 0.261962 +vt 0.192306 0.253694 +vt 0.750759 0.906019 +vt 0.750835 0.917667 +vt 0.753425 0.917673 +vt 0.753355 0.906025 +vt 0.750924 0.929181 +vt 0.753511 0.929187 +vt 0.718212 0.225789 +vt 0.718125 0.230023 +vt 0.392837 0.403588 +vt 0.392926 0.407557 +vt 0.382884 0.403618 +vt 0.382972 0.407587 +vt 0.708259 0.225795 +vt 0.708172 0.230029 +vt 0.369383 0.403658 +vt 0.369287 0.398773 +vt 0.366691 0.398781 +vt 0.366787 0.403666 +vt 0.369188 0.392811 +vt 0.366593 0.392819 +vt 0.727396 0.917613 +vt 0.727321 0.905965 +vt 0.727486 0.929127 +vt 0.737442 0.929150 +vt 0.737353 0.917636 +vt 0.737277 0.905988 +vt 0.183351 0.247093 +vt 0.194520 0.247159 +vt 0.369013 0.377617 +vt 0.368954 0.368636 +vt 0.366361 0.368644 +vt 0.366419 0.377625 +vt 0.368917 0.359408 +vt 0.366324 0.359416 +vt 0.657422 0.239246 +vt 0.657718 0.239253 +vt 0.657260 0.239241 +vt 0.657412 0.244077 +vt 0.657570 0.244082 +vt 0.657859 0.244090 +vt 0.727603 0.825176 +vt 0.727713 0.819305 +vt 0.727492 0.832571 +vt 0.737448 0.832594 +vt 0.737559 0.825198 +vt 0.737670 0.819327 +vt 0.731643 0.994908 +vt 0.731055 0.993154 +vt 0.744041 0.994735 +vt 0.743108 0.993022 +vt 0.727689 0.957224 +vt 0.727652 0.948672 +vt 0.727683 0.965753 +vt 0.737642 0.965782 +vt 0.737646 0.957248 +vt 0.737608 0.948695 +vt 0.624149 0.238204 +vt 0.624174 0.234025 +vt 0.624127 0.242672 +vt 0.634082 0.242671 +vt 0.634104 0.238202 +vt 0.634129 0.234024 +vt 0.647583 0.242669 +vt 0.647558 0.247971 +vt 0.650155 0.247971 +vt 0.650180 0.242669 +vt 0.647531 0.254600 +vt 0.650129 0.254600 +vt 0.368906 0.340208 +vt 0.368927 0.328285 +vt 0.366350 0.328292 +vt 0.366316 0.340216 +vt 0.368894 0.315960 +vt 0.366400 0.315968 +vt 0.751470 0.983055 +vt 0.752299 0.989710 +vt 0.754247 0.988606 +vt 0.753851 0.982692 +vt 0.753138 0.994092 +vt 0.754657 0.992238 +vt 0.755866 0.987625 +vt 0.624055 0.262817 +vt 0.624078 0.254603 +vt 0.624034 0.271987 +vt 0.633990 0.271986 +vt 0.634011 0.262815 +vt 0.634035 0.254602 +vt 0.181301 0.359598 +vt 0.181297 0.350788 +vt 0.191259 0.359595 +vt 0.191255 0.350786 +vt 0.727578 0.939450 +vt 0.737534 0.939473 +vt 0.647484 0.271984 +vt 0.647467 0.281584 +vt 0.650064 0.281583 +vt 0.650082 0.271984 +vt 0.647454 0.292371 +vt 0.650052 0.292371 +vt 0.181304 0.393493 +vt 0.181301 0.402301 +vt 0.191260 0.402299 +vt 0.191262 0.393490 +vt 0.376871 0.250942 +vt 0.371285 0.250661 +vt 0.380499 0.245026 +vt 0.373451 0.244550 +vt 0.718093 0.386561 +vt 0.718206 0.391574 +vt 0.717992 0.380829 +vt 0.708037 0.380835 +vt 0.708138 0.386568 +vt 0.708251 0.391581 +vt 0.727218 0.876402 +vt 0.727223 0.867856 +vt 0.727231 0.885485 +vt 0.737187 0.885508 +vt 0.737174 0.876425 +vt 0.737180 0.867879 +vt 0.717721 0.357735 +vt 0.717797 0.365945 +vt 0.707766 0.357742 +vt 0.707842 0.365951 +vt 0.727384 0.841583 +vt 0.727298 0.850983 +vt 0.737254 0.851006 +vt 0.737341 0.841606 +vt 0.392426 0.368566 +vt 0.392480 0.377547 +vt 0.392394 0.359338 +vt 0.382444 0.359368 +vt 0.382475 0.368595 +vt 0.382529 0.377577 +vt 0.624149 0.403796 +vt 0.624181 0.408809 +vt 0.634139 0.408807 +vt 0.634107 0.403795 +vt 0.717612 0.290031 +vt 0.717589 0.303595 +vt 0.717650 0.277726 +vt 0.707695 0.277732 +vt 0.707657 0.290037 +vt 0.707634 0.303601 +vt 0.624040 0.374615 +vt 0.633997 0.374614 +vt 0.718034 0.235062 +vt 0.717939 0.241385 +vt 0.708081 0.235068 +vt 0.707986 0.241391 +vt 0.747756 0.355795 +vt 0.747751 0.346307 +vt 0.747761 0.365017 +vt 0.757714 0.365015 +vt 0.757708 0.355793 +vt 0.757702 0.346305 +vt 0.717699 0.267305 +vt 0.717764 0.258058 +vt 0.707810 0.258065 +vt 0.707745 0.267312 +vt 0.623997 0.305085 +vt 0.624006 0.292374 +vt 0.623993 0.319072 +vt 0.633951 0.319071 +vt 0.633955 0.305084 +vt 0.633963 0.292373 +vt 0.392744 0.398703 +vt 0.392648 0.392741 +vt 0.382696 0.392771 +vt 0.382791 0.398733 +vt 0.624103 0.247974 +vt 0.634059 0.247973 +vt 0.392437 0.328214 +vt 0.392396 0.340138 +vt 0.392494 0.315890 +vt 0.382455 0.315920 +vt 0.382479 0.328244 +vt 0.382449 0.340168 +vt 0.624017 0.281587 +vt 0.633974 0.281585 +vt 0.392679 0.304840 +vt 0.393593 0.295389 +vt 0.383169 0.295704 +vt 0.382452 0.304906 +vt 0.747782 0.386656 +vt 0.747775 0.380571 +vt 0.747789 0.391633 +vt 0.757744 0.391631 +vt 0.757737 0.386654 +vt 0.757729 0.380569 +vt 0.769908 0.262581 +vt 0.766377 0.254204 +vt 0.760718 0.254186 +vt 0.766461 0.262484 +vt 0.761263 0.246610 +vt 0.755394 0.246057 +vt 0.750711 0.251988 +vt 0.752985 0.255725 +vt 0.760658 0.257508 +vt 0.764486 0.262440 +vt 0.747744 0.314215 +vt 0.747755 0.301476 +vt 0.747744 0.326525 +vt 0.757693 0.326523 +vt 0.757703 0.314213 +vt 0.757794 0.301474 +vt 0.404847 0.239778 +vt 0.400608 0.240054 +vt 0.400591 0.242864 +vt 0.404842 0.239324 +vt 0.400606 0.239606 +vt 0.395832 0.241505 +vt 0.395798 0.241910 +vt 0.395520 0.244446 +vt 0.628635 0.978028 +vt 0.628640 0.978430 +vt 0.630850 0.979327 +vt 0.630786 0.978926 +vt 0.123796 0.032809 +vt 0.124003 0.032790 +vt 0.124086 0.020488 +vt 0.123714 0.032814 +vt 0.123575 0.045269 +vt 0.123697 0.045261 +vt 0.123881 0.045245 +vt 0.404415 0.268982 +vt 0.406787 0.268590 +vt 0.407251 0.268523 +vt 0.717847 0.249250 +vt 0.707893 0.249256 +vt 0.205117 0.253526 +vt 0.204737 0.261933 +vt 0.207309 0.261971 +vt 0.207501 0.253836 +vt 0.204684 0.271058 +vt 0.207283 0.271057 +vt 0.756665 0.987207 +vt 0.756906 0.987160 +vt 0.210551 0.244416 +vt 0.210370 0.244298 +vt 0.210372 0.244509 +vt 0.210582 0.244623 +vt 0.209761 0.243563 +vt 0.209753 0.243795 +vt 0.167805 0.240068 +vt 0.756971 0.987193 +vt 0.621477 0.975716 +vt 0.625900 0.976325 +vt 0.625694 0.976213 +vt 0.625556 0.976662 +vt 0.625785 0.976796 +vt 0.625839 0.975802 +vt 0.626051 0.975925 +vt 0.626235 0.583024 +vt 0.621963 0.973661 +vt 0.210652 0.248855 +vt 0.210652 0.245850 +vt 0.210652 0.254174 +vt 0.626231 0.585254 +vt 0.166837 0.246549 +vt 0.713955 0.989688 +vt 0.718799 0.989498 +vt 0.713137 0.989727 +vt 0.619490 0.585910 +vt 0.626198 0.582810 +vt 0.626168 0.582740 +vt 0.400454 0.249654 +vt 0.399746 0.259181 +vt 0.394685 0.250575 +vt 0.392693 0.259223 +vt 0.717585 0.317372 +vt 0.707630 0.317379 +vt 0.406774 0.239772 +vt 0.406766 0.239320 +vt 0.407169 0.239768 +vt 0.407134 0.239327 +vt 0.733855 0.236222 +vt 0.733451 0.236225 +vt 0.623645 0.840017 +vt 0.633156 0.722485 +vt 0.632689 0.722437 +vt 0.632606 0.722899 +vt 0.633072 0.722947 +vt 0.632694 0.722028 +vt 0.633157 0.722079 +vt 0.623812 0.842066 +vt 0.623812 0.842275 +vt 0.623652 0.839777 +vt 0.623669 0.839654 +vt 0.622850 0.720313 +vt 0.622857 0.720101 +vt 0.622615 0.722711 +vt 0.622603 0.722591 +vt 0.777142 0.238143 +vt 0.776692 0.238099 +vt 0.774428 0.237818 +vt 0.363534 0.243307 +vt 0.363507 0.243669 +vt 0.364085 0.243591 +vt 0.364090 0.243217 +vt 0.367266 0.243032 +vt 0.367306 0.242644 +vt 0.758394 0.229066 +vt 0.758619 0.229490 +vt 0.766272 0.228809 +vt 0.766136 0.228372 +vt 0.760168 0.231899 +vt 0.767208 0.231319 +vt 0.382030 0.242579 +vt 0.374369 0.242017 +vt 0.382250 0.242187 +vt 0.374500 0.241609 +vt 0.207287 0.239876 +vt 0.207233 0.240240 +vt 0.208571 0.242130 +vt 0.208598 0.241848 +vt 0.206853 0.242138 +vt 0.208379 0.243715 +vt 0.751125 0.965815 +vt 0.751140 0.974716 +vt 0.753712 0.974676 +vt 0.753724 0.965821 +vt 0.747661 0.290018 +vt 0.746847 0.280086 +vt 0.757888 0.290050 +vt 0.757267 0.280350 +vt 0.144075 0.109578 +vt 0.143817 0.109591 +vt 0.143961 0.117322 +vt 0.144219 0.117309 +vt 0.143472 0.109611 +vt 0.143615 0.117342 +vt 0.398242 0.270213 +vt 0.399857 0.279105 +vt 0.389445 0.268104 +vt 0.386816 0.273581 +vt 0.393843 0.275566 +vt 0.396811 0.280162 +vt 0.744723 0.271040 +vt 0.740641 0.263004 +vt 0.755498 0.272929 +vt 0.753775 0.269353 +vt 0.746511 0.267942 +vt 0.743564 0.263398 +vt 0.647635 0.234022 +vt 0.647608 0.238201 +vt 0.650204 0.238200 +vt 0.650231 0.234022 +vt 0.368077 0.295201 +vt 0.367083 0.286564 +vt 0.365708 0.286568 +vt 0.366201 0.295207 +vt 0.747747 0.336923 +vt 0.757697 0.336922 +vt 0.747768 0.373339 +vt 0.757721 0.373337 +vt 0.392383 0.350223 +vt 0.382434 0.350253 +vt 0.751016 0.939504 +vt 0.753606 0.939510 +vt 0.751090 0.948726 +vt 0.753686 0.948732 +vt 0.647440 0.319069 +vt 0.647441 0.333253 +vt 0.650039 0.333252 +vt 0.650039 0.319069 +vt 0.694321 0.258073 +vt 0.694403 0.249265 +vt 0.691805 0.249267 +vt 0.691724 0.258075 +vt 0.694494 0.241400 +vt 0.691897 0.241401 +vt 0.771237 0.365012 +vt 0.771240 0.373334 +vt 0.773834 0.373334 +vt 0.773831 0.365012 +vt 0.771243 0.380566 +vt 0.773838 0.380566 +vt 0.694677 0.230038 +vt 0.694762 0.225804 +vt 0.692165 0.225805 +vt 0.692081 0.230040 +vt 0.369474 0.407627 +vt 0.366877 0.407635 +vt 0.647507 0.382961 +vt 0.647534 0.390945 +vt 0.650133 0.390945 +vt 0.650105 0.382961 +vt 0.717891 0.373821 +vt 0.707936 0.373827 +vt 0.181291 0.341322 +vt 0.191250 0.341320 +vt 0.727726 0.974618 +vt 0.728290 0.982798 +vt 0.738677 0.982812 +vt 0.737742 0.974652 +vt 0.750737 0.851037 +vt 0.750685 0.859663 +vt 0.753284 0.859669 +vt 0.753335 0.851043 +vt 0.727247 0.859609 +vt 0.737203 0.859632 +vt 0.623995 0.333256 +vt 0.633952 0.333254 +vt 0.694555 0.380844 +vt 0.694453 0.373836 +vt 0.691855 0.373838 +vt 0.691956 0.380845 +vt 0.771241 0.336919 +vt 0.773831 0.336918 +vt 0.771238 0.346303 +vt 0.773830 0.346302 +vt 0.740016 0.226928 +vt 0.740014 0.226451 +vt 0.744838 0.228864 +vt 0.744800 0.228426 +vt 0.647506 0.262814 +vt 0.650104 0.262813 +vt 0.392557 0.385669 +vt 0.382605 0.385699 +vt 0.204746 0.367891 +vt 0.204748 0.375910 +vt 0.207347 0.375910 +vt 0.207345 0.367891 +vt 0.771237 0.355791 +vt 0.773830 0.355790 +vt 0.729668 0.989119 +vt 0.740892 0.989064 +vt 0.368900 0.350294 +vt 0.366308 0.350302 +vt 0.771247 0.386652 +vt 0.773842 0.386651 +vt 0.771251 0.391629 +vt 0.773847 0.391628 +vt 0.751128 0.957279 +vt 0.753726 0.957285 +vt 0.694257 0.267320 +vt 0.691660 0.267322 +vt 0.204671 0.289283 +vt 0.204636 0.298545 +vt 0.207105 0.298545 +vt 0.207224 0.289282 +vt 0.204619 0.308564 +vt 0.207037 0.308564 +vt 0.753493 0.996038 +vt 0.754834 0.993834 +vt 0.753530 0.996556 +vt 0.754855 0.994281 +vt 0.659719 0.239305 +vt 0.659978 0.239311 +vt 0.659845 0.244140 +vt 0.660104 0.244145 +vt 0.369093 0.385739 +vt 0.366499 0.385747 +vt 0.727265 0.895257 +vt 0.737221 0.895280 +vt 0.181245 0.280197 +vt 0.191203 0.280194 +vt 0.694587 0.235076 +vt 0.691991 0.235078 +vt 0.204684 0.280190 +vt 0.207278 0.280190 +vt 0.750703 0.895311 +vt 0.753302 0.895317 +vt 0.205985 0.246682 +vt 0.207940 0.247618 +vt 0.751153 0.819358 +vt 0.751042 0.825230 +vt 0.753641 0.825235 +vt 0.753751 0.819364 +vt 0.750930 0.832625 +vt 0.753529 0.832631 +vt 0.753524 0.996727 +vt 0.754854 0.994450 +vt 0.630803 0.979523 +vt 0.628566 0.978615 +vt 0.204705 0.330953 +vt 0.204731 0.341317 +vt 0.207325 0.341316 +vt 0.207258 0.330953 +vt 0.204740 0.350783 +vt 0.207339 0.350782 +vt 0.181298 0.409544 +vt 0.181294 0.415306 +vt 0.191252 0.415304 +vt 0.191256 0.409542 +vt 0.204654 0.319690 +vt 0.207122 0.319689 +vt 0.647484 0.374612 +vt 0.650083 0.374612 +vt 0.204741 0.409539 +vt 0.207340 0.409538 +vt 0.204738 0.415301 +vt 0.207337 0.415300 +vt 0.647445 0.305082 +vt 0.650043 0.305082 +vt 0.694158 0.329986 +vt 0.694146 0.317387 +vt 0.691548 0.317389 +vt 0.691560 0.329988 +vt 0.750823 0.841637 +vt 0.753422 0.841643 +vt 0.694769 0.391589 +vt 0.694656 0.386576 +vt 0.692058 0.386578 +vt 0.692171 0.391591 +vt 0.772449 0.279964 +vt 0.771674 0.289999 +vt 0.773948 0.289999 +vt 0.774333 0.279963 +vt 0.694184 0.340372 +vt 0.691586 0.340374 +vt 0.768349 0.245595 +vt 0.772053 0.254104 +vt 0.774265 0.254089 +vt 0.772110 0.245479 +vt 0.773961 0.262635 +vt 0.775319 0.262635 +vt 0.204744 0.359592 +vt 0.207343 0.359592 +vt 0.763839 0.237666 +vt 0.769421 0.237318 +vt 0.368690 0.304879 +vt 0.366416 0.304886 +vt 0.773667 0.271063 +vt 0.775071 0.271062 +vt 0.124641 0.045176 +vt 0.125134 0.045128 +vt 0.125421 0.032655 +vt 0.124902 0.032706 +vt 0.124202 0.045216 +vt 0.124394 0.032754 +vt 0.142704 0.109658 +vt 0.142250 0.109690 +vt 0.142386 0.117421 +vt 0.142845 0.117389 +vt 0.143106 0.109632 +vt 0.143250 0.117364 +vt 0.753865 0.233090 +vt 0.755622 0.234963 +vt 0.753611 0.232740 +vt 0.750860 0.235201 +vt 0.751075 0.235502 +vt 0.752582 0.237016 +vt 0.748417 0.233013 +vt 0.749312 0.234897 +vt 0.748292 0.232660 +vt 0.380888 0.252665 +vt 0.385063 0.247901 +vt 0.375559 0.259919 +vt 0.379312 0.260413 +vt 0.384446 0.253837 +vt 0.388111 0.249839 +vt 0.389074 0.252631 +vt 0.391364 0.247815 +vt 0.385177 0.260118 +vt 0.206157 0.239019 +vt 0.205563 0.241158 +vt 0.206242 0.238554 +vt 0.205376 0.238432 +vt 0.205256 0.238943 +vt 0.204438 0.241130 +vt 0.203643 0.240061 +vt 0.202636 0.242054 +vt 0.203794 0.239611 +vt 0.750555 0.990404 +vt 0.751893 0.995262 +vt 0.749215 0.983282 +vt 0.747090 0.983281 +vt 0.748959 0.990412 +vt 0.750820 0.995280 +vt 0.746747 0.989718 +vt 0.749035 0.994111 +vt 0.744451 0.983045 +vt 0.124378 0.054626 +vt 0.124471 0.054615 +vt 0.124831 0.053499 +vt 0.124728 0.053511 +vt 0.632095 0.978272 +vt 0.632079 0.978097 +vt 0.125004 0.053481 +vt 0.124913 0.052619 +vt 0.124739 0.052636 +vt 0.124620 0.052649 +vt 0.124176 0.051134 +vt 0.124044 0.051145 +vt 0.124350 0.051117 +vt 0.144118 0.104867 +vt 0.143773 0.104888 +vt 0.144377 0.104853 +vt 0.144550 0.102145 +vt 0.144290 0.102161 +vt 0.143947 0.102183 +vt 0.143789 0.099568 +vt 0.143445 0.099591 +vt 0.144048 0.099550 +vt 0.163767 0.092656 +vt 0.163511 0.092612 +vt 0.163486 0.096754 +vt 0.163739 0.096818 +vt 0.164109 0.092696 +vt 0.164078 0.096886 +vt 0.386806 0.245961 +vt 0.387055 0.245651 +vt 0.389607 0.248242 +vt 0.389818 0.247986 +vt 0.144714 0.102356 +vt 0.144212 0.099673 +vt 0.392246 0.245867 +vt 0.392368 0.245555 +vt 0.768768 0.314211 +vt 0.768724 0.326521 +vt 0.769046 0.301472 +vt 0.766744 0.301472 +vt 0.766364 0.314211 +vt 0.766309 0.326521 +vt 0.763470 0.314212 +vt 0.763434 0.326522 +vt 0.763740 0.301473 +vt 0.370814 0.268814 +vt 0.368057 0.278012 +vt 0.370258 0.278167 +vt 0.373918 0.269123 +vt 0.395807 0.286977 +vt 0.394037 0.284366 +vt 0.386891 0.285716 +vt 0.385042 0.288898 +vt 0.768732 0.386652 +vt 0.768737 0.391629 +vt 0.768728 0.380567 +vt 0.766326 0.380567 +vt 0.766332 0.386653 +vt 0.766337 0.391630 +vt 0.763471 0.386653 +vt 0.763478 0.391630 +vt 0.763464 0.380568 +vt 0.370597 0.304874 +vt 0.369489 0.295200 +vt 0.371215 0.315953 +vt 0.373513 0.315947 +vt 0.372685 0.304870 +vt 0.371528 0.295213 +vt 0.376012 0.304879 +vt 0.375677 0.295351 +vt 0.376513 0.315938 +vt 0.644955 0.281584 +vt 0.644942 0.292371 +vt 0.644972 0.271984 +vt 0.642577 0.271985 +vt 0.642560 0.281584 +vt 0.642548 0.292372 +vt 0.639706 0.281585 +vt 0.639694 0.292372 +vt 0.639722 0.271985 +vt 0.371423 0.328277 +vt 0.371426 0.340201 +vt 0.373838 0.340194 +vt 0.373823 0.328270 +vt 0.376714 0.328261 +vt 0.376710 0.340185 +vt 0.645045 0.247972 +vt 0.645019 0.254600 +vt 0.645070 0.242669 +vt 0.642673 0.242670 +vt 0.642648 0.247972 +vt 0.642623 0.254601 +vt 0.639791 0.247972 +vt 0.639767 0.254601 +vt 0.639815 0.242670 +vt 0.371800 0.398766 +vt 0.371702 0.392804 +vt 0.371896 0.403651 +vt 0.374294 0.403643 +vt 0.374199 0.398759 +vt 0.374103 0.392797 +vt 0.377058 0.398750 +vt 0.376963 0.392788 +vt 0.377152 0.403635 +vt 0.644933 0.305082 +vt 0.644929 0.319070 +vt 0.642539 0.305083 +vt 0.642535 0.319070 +vt 0.639686 0.305083 +vt 0.639682 0.319070 +vt 0.696768 0.267319 +vt 0.696833 0.258072 +vt 0.696719 0.277739 +vt 0.699112 0.277738 +vt 0.699162 0.267317 +vt 0.699226 0.258070 +vt 0.702015 0.267315 +vt 0.702080 0.258068 +vt 0.701966 0.277736 +vt 0.768719 0.355791 +vt 0.768721 0.365013 +vt 0.768719 0.346303 +vt 0.766310 0.346304 +vt 0.766312 0.355792 +vt 0.766315 0.365013 +vt 0.763445 0.355792 +vt 0.763450 0.365014 +vt 0.763440 0.346304 +vt 0.697099 0.235075 +vt 0.697189 0.230036 +vt 0.697006 0.241398 +vt 0.699401 0.241396 +vt 0.699495 0.235073 +vt 0.699585 0.230035 +vt 0.702350 0.235072 +vt 0.702441 0.230033 +vt 0.702255 0.241395 +vt 0.644973 0.374612 +vt 0.644996 0.382962 +vt 0.644956 0.365986 +vt 0.642563 0.365986 +vt 0.642581 0.374613 +vt 0.642603 0.382962 +vt 0.639728 0.374613 +vt 0.639751 0.382962 +vt 0.639710 0.365987 +vt 0.696682 0.290044 +vt 0.696660 0.303608 +vt 0.699053 0.303606 +vt 0.699075 0.290043 +vt 0.701928 0.290041 +vt 0.701905 0.303605 +vt 0.645081 0.403794 +vt 0.645114 0.408806 +vt 0.645052 0.398026 +vt 0.642660 0.398026 +vt 0.642689 0.403794 +vt 0.642721 0.408806 +vt 0.639837 0.403794 +vt 0.639869 0.408807 +vt 0.639808 0.398027 +vt 0.371470 0.368628 +vt 0.371434 0.359401 +vt 0.371528 0.377610 +vt 0.373931 0.377603 +vt 0.373875 0.368621 +vt 0.373841 0.359394 +vt 0.376740 0.368613 +vt 0.376708 0.359385 +vt 0.376794 0.377594 +vt 0.748313 0.841631 +vt 0.748227 0.851032 +vt 0.748420 0.832620 +vt 0.746029 0.832614 +vt 0.745921 0.841625 +vt 0.745835 0.851026 +vt 0.743070 0.841619 +vt 0.742984 0.851019 +vt 0.743177 0.832608 +vt 0.696793 0.357749 +vt 0.696735 0.349292 +vt 0.696870 0.365958 +vt 0.699262 0.365957 +vt 0.699185 0.357747 +vt 0.699127 0.349291 +vt 0.702037 0.357745 +vt 0.701979 0.349289 +vt 0.702113 0.365955 +vt 0.748146 0.876450 +vt 0.748159 0.885533 +vt 0.748152 0.867904 +vt 0.745760 0.867899 +vt 0.745755 0.876445 +vt 0.745768 0.885528 +vt 0.742904 0.876438 +vt 0.742917 0.885521 +vt 0.742909 0.867892 +vt 0.697167 0.386575 +vt 0.697065 0.380842 +vt 0.697279 0.391588 +vt 0.699671 0.391586 +vt 0.699558 0.386573 +vt 0.699456 0.380841 +vt 0.702410 0.386571 +vt 0.702308 0.380839 +vt 0.702522 0.391584 +vt 0.768721 0.336919 +vt 0.766309 0.336920 +vt 0.763436 0.336920 +vt 0.202237 0.393488 +vt 0.202234 0.402296 +vt 0.202238 0.384313 +vt 0.199846 0.384314 +vt 0.199844 0.393488 +vt 0.199842 0.402297 +vt 0.196993 0.393489 +vt 0.196990 0.402298 +vt 0.196994 0.384314 +vt 0.644994 0.262814 +vt 0.642598 0.262814 +vt 0.639743 0.262815 +vt 0.748506 0.939498 +vt 0.748580 0.948721 +vt 0.748414 0.929175 +vt 0.746022 0.929169 +vt 0.746114 0.939493 +vt 0.746189 0.948715 +vt 0.743263 0.939486 +vt 0.743337 0.948708 +vt 0.743171 0.929163 +vt 0.202233 0.359593 +vt 0.202236 0.367892 +vt 0.202229 0.350783 +vt 0.199837 0.350784 +vt 0.199841 0.359593 +vt 0.199844 0.367892 +vt 0.196989 0.359594 +vt 0.196992 0.367893 +vt 0.196985 0.350785 +vt 0.768724 0.373335 +vt 0.766320 0.373335 +vt 0.763457 0.373336 +vt 0.748662 0.974740 +vt 0.748615 0.965809 +vt 0.746223 0.965804 +vt 0.746304 0.974735 +vt 0.743479 0.974699 +vt 0.743372 0.965797 +vt 0.371418 0.350286 +vt 0.373827 0.350279 +vt 0.376697 0.350270 +vt 0.645094 0.238201 +vt 0.645121 0.234023 +vt 0.642721 0.234023 +vt 0.642696 0.238201 +vt 0.639838 0.238202 +vt 0.639862 0.234023 +vt 0.748618 0.957273 +vt 0.746226 0.957268 +vt 0.743375 0.957261 +vt 0.696914 0.249263 +vt 0.699308 0.249262 +vt 0.702163 0.249260 +vt 0.202182 0.298546 +vt 0.202188 0.308565 +vt 0.202180 0.289283 +vt 0.199791 0.289284 +vt 0.199799 0.298546 +vt 0.199807 0.308565 +vt 0.196947 0.298547 +vt 0.196956 0.308566 +vt 0.196939 0.289285 +vt 0.752445 0.997437 +vt 0.752487 0.998008 +vt 0.751581 0.997457 +vt 0.751634 0.998028 +vt 0.749985 0.996045 +vt 0.750066 0.996546 +vt 0.141892 0.105023 +vt 0.141745 0.105038 +vt 0.142168 0.104999 +vt 0.142361 0.102295 +vt 0.142092 0.102316 +vt 0.141950 0.102328 +vt 0.166221 0.089688 +vt 0.166061 0.089799 +vt 0.166057 0.092410 +vt 0.166222 0.092308 +vt 0.165770 0.089933 +vt 0.165760 0.092531 +vt 0.165742 0.096848 +vt 0.166049 0.096750 +vt 0.166222 0.096660 +vt 0.371608 0.385732 +vt 0.374010 0.385724 +vt 0.376871 0.385716 +vt 0.202257 0.261910 +vt 0.202173 0.271058 +vt 0.202850 0.253338 +vt 0.200712 0.253337 +vt 0.199897 0.261911 +vt 0.199781 0.271059 +vt 0.197071 0.261935 +vt 0.196929 0.271060 +vt 0.198069 0.253520 +vt 0.748325 0.917661 +vt 0.748249 0.906013 +vt 0.745857 0.906008 +vt 0.745933 0.917656 +vt 0.743082 0.917649 +vt 0.743006 0.906001 +vt 0.371986 0.407620 +vt 0.697274 0.225802 +vt 0.699671 0.225801 +vt 0.374384 0.407613 +vt 0.377241 0.407604 +vt 0.702528 0.225799 +vt 0.202176 0.280191 +vt 0.199785 0.280192 +vt 0.196933 0.280192 +vt 0.748193 0.895305 +vt 0.745802 0.895299 +vt 0.742950 0.895293 +vt 0.204207 0.246112 +vt 0.202574 0.246106 +vt 0.200351 0.246654 +vt 0.748532 0.825224 +vt 0.748642 0.819353 +vt 0.746251 0.819347 +vt 0.746140 0.825218 +vt 0.743289 0.825212 +vt 0.743399 0.819341 +vt 0.632242 0.980086 +vt 0.632281 0.979885 +vt 0.752469 0.998188 +vt 0.751606 0.998211 +vt 0.126594 0.053321 +vt 0.126797 0.053304 +vt 0.126700 0.052446 +vt 0.126500 0.052461 +vt 0.215133 0.697600 +vt 0.215335 0.697628 +vt 0.215335 0.696055 +vt 0.215132 0.696054 +vt 0.750039 0.996717 +vt 0.125939 0.050965 +vt 0.126132 0.050952 +vt 0.202200 0.319691 +vt 0.202214 0.330954 +vt 0.199816 0.319691 +vt 0.199825 0.330955 +vt 0.196965 0.319692 +vt 0.196973 0.330955 +vt 0.644943 0.356857 +vt 0.644935 0.346202 +vt 0.642542 0.346203 +vt 0.642550 0.356858 +vt 0.639697 0.356858 +vt 0.639688 0.346203 +vt 0.202223 0.341317 +vt 0.199832 0.341318 +vt 0.196980 0.341318 +vt 0.645023 0.390946 +vt 0.642631 0.390946 +vt 0.639778 0.390946 +vt 0.202231 0.409539 +vt 0.202227 0.415301 +vt 0.199838 0.409540 +vt 0.199835 0.415302 +vt 0.196986 0.409541 +vt 0.196982 0.415303 +vt 0.644930 0.333253 +vt 0.642536 0.333253 +vt 0.639683 0.333254 +vt 0.696694 0.340371 +vt 0.696668 0.329984 +vt 0.699086 0.340369 +vt 0.699061 0.329983 +vt 0.701938 0.340367 +vt 0.701913 0.329981 +vt 0.748175 0.859657 +vt 0.745784 0.859652 +vt 0.742932 0.859645 +vt 0.696964 0.373834 +vt 0.699355 0.373833 +vt 0.702207 0.373831 +vt 0.772290 0.271055 +vt 0.770922 0.279960 +vt 0.772396 0.262628 +vt 0.769887 0.270996 +vt 0.768816 0.279937 +vt 0.742092 0.254404 +vt 0.746124 0.258159 +vt 0.696656 0.317385 +vt 0.699049 0.317384 +vt 0.701901 0.317382 +vt 0.759818 0.239505 +vt 0.765116 0.246207 +vt 0.756251 0.240735 +vt 0.751609 0.239449 +vt 0.202237 0.375911 +vt 0.199845 0.375911 +vt 0.196994 0.375912 +vt 0.769745 0.254177 +vt 0.764698 0.270728 +vt 0.764745 0.280005 +vt 0.761358 0.267291 +vt 0.368134 0.286570 +vt 0.370348 0.286627 +vt 0.379637 0.269999 +vt 0.374074 0.278585 +vt 0.376419 0.279169 +vt 0.379673 0.274894 +vt 0.769750 0.289999 +vt 0.767650 0.289997 +vt 0.764329 0.290006 +vt 0.124648 0.051090 +vt 0.125063 0.051051 +vt 0.125216 0.052590 +vt 0.125634 0.052549 +vt 0.125311 0.053452 +vt 0.125731 0.053410 +vt 0.632076 0.978580 +vt 0.632095 0.979004 +vt 0.125542 0.051004 +vt 0.126106 0.052501 +vt 0.126202 0.053361 +vt 0.632195 0.979485 +vt 0.143409 0.104910 +vt 0.143011 0.104937 +vt 0.143583 0.102207 +vt 0.143188 0.102234 +vt 0.143081 0.099615 +vt 0.142683 0.099641 +vt 0.164472 0.092740 +vt 0.164438 0.096957 +vt 0.164875 0.092740 +vt 0.164841 0.096989 +vt 0.142569 0.104968 +vt 0.142753 0.102265 +vt 0.165351 0.090079 +vt 0.165334 0.092657 +vt 0.164895 0.090184 +vt 0.165307 0.096941 +vt 0.658142 0.239263 +vt 0.658276 0.244100 +vt 0.375852 0.286679 +vt 0.379554 0.283695 +vt 0.493742 0.091502 +vt 0.495124 0.085836 +vt 0.494601 0.085720 +vt 0.493164 0.091654 +vt 0.588337 0.267579 +vt 0.588310 0.271543 +vt 0.589001 0.271810 +vt 0.589001 0.267586 +vt 0.497310 0.083615 +vt 0.497267 0.082507 +vt 0.493766 0.085253 +vt 0.491974 0.092413 +vt 0.379613 0.276325 +vt 0.385770 0.275406 +vt 0.377276 0.279227 +vt 0.589376 0.268741 +vt 0.589067 0.271982 +vt 0.589698 0.271719 +vt 0.589998 0.268547 +vt 0.754927 0.261763 +vt 0.761083 0.262666 +vt 0.760908 0.262167 +vt 0.754875 0.261247 +vt 0.393629 0.283422 +vt 0.387696 0.284442 +vt 0.395684 0.280433 +vt 0.585644 0.266721 +vt 0.585539 0.270494 +vt 0.586177 0.270674 +vt 0.586282 0.267035 +vt 0.393577 0.282797 +vt 0.387827 0.283776 +vt 0.392287 0.277153 +vt 0.748393 0.263542 +vt 0.748479 0.263078 +vt 0.585779 0.274292 +vt 0.586406 0.274421 +vt 0.744860 0.264416 +vt 0.747894 0.260495 +vt 0.747567 0.259601 +vt 0.744654 0.263806 +vt 0.754059 0.258261 +vt 0.753852 0.257285 +vt 0.497310 0.101903 +vt 0.494864 0.098233 +vt 0.494296 0.098664 +vt 0.496876 0.102360 +vt 0.493147 0.100082 +vt 0.763400 0.262558 +vt 0.759862 0.266385 +vt 0.760292 0.259554 +vt 0.760474 0.258743 +vt 0.762893 0.263048 +vt 0.587310 0.267308 +vt 0.587243 0.271108 +vt 0.393595 0.281164 +vt 0.387835 0.282180 +vt 0.387857 0.282972 +vt 0.393589 0.281979 +vt 0.748183 0.261786 +vt 0.754441 0.259748 +vt 0.588692 0.275991 +vt 0.587550 0.275206 +vt 0.744968 0.265379 +vt 0.745076 0.266343 +vt 0.591759 0.270697 +vt 0.592209 0.266860 +vt 0.591117 0.267695 +vt 0.590748 0.271196 +vt 0.760526 0.260845 +vt 0.381215 0.280272 +vt 0.381263 0.281087 +vt 0.592209 0.275315 +vt 0.591221 0.275645 +vt 0.590204 0.275992 +vt 0.381163 0.281934 +vt 0.380916 0.282595 +vt 0.377507 0.278661 +vn -0.0134 0.0088 0.9999 +vn -0.0128 0.0105 0.9999 +vn -0.0000 0.0000 1.0000 +vn -0.0133 0.0087 0.9999 +vn -0.0127 0.0105 0.9999 +vn -0.0120 0.0120 0.9999 +vn 0.0166 -0.0084 0.9998 +vn 0.0171 -0.0048 0.9998 +vn 0.0165 -0.0084 0.9998 +vn 0.0170 -0.0048 0.9998 +vn 0.0171 0.0003 0.9999 +vn 0.0170 -0.0049 0.9998 +vn -0.0147 -0.0064 0.9999 +vn -0.0153 -0.0049 0.9999 +vn -0.0155 -0.0033 0.9999 +vn -0.0121 0.0120 0.9999 +vn -0.0114 0.0134 0.9998 +vn -0.0114 0.0135 0.9998 +vn -0.0108 0.0147 0.9998 +vn -0.0113 0.0134 0.9998 +vn 0.0178 0.0049 0.9998 +vn 0.0204 0.0076 0.9998 +vn -0.0138 -0.0092 0.9999 +vn -0.0142 -0.0080 0.9999 +vn -0.0148 -0.0064 0.9999 +vn -0.0145 0.0044 0.9999 +vn -0.0139 0.0067 0.9999 +vn -0.0140 0.0067 0.9999 +vn 0.0156 -0.0095 0.9998 +vn 0.0158 -0.0098 0.9998 +vn 0.0155 -0.0095 0.9998 +vn 0.0157 -0.0098 0.9998 +vn -0.0171 -0.0011 0.9999 +vn -0.0183 -0.0051 0.9998 +vn -0.0184 -0.0051 0.9998 +vn -0.0172 -0.0083 0.9998 +vn -0.0001 -0.0000 1.0000 +vn -0.0087 0.0170 0.9998 +vn -0.0074 0.0185 0.9998 +vn -0.0075 0.0185 0.9998 +vn -0.0061 0.0197 0.9998 +vn -0.0134 0.0043 0.9999 +vn -0.0148 0.0018 0.9999 +vn -0.0147 0.0018 0.9999 +vn 0.0001 0.0016 1.0000 +vn 0.0003 0.0016 1.0000 +vn -0.0154 -0.0014 0.9999 +vn -0.0154 -0.0033 0.9999 +vn -0.0154 0.0004 0.9999 +vn -0.0148 -0.0096 0.9998 +vn -0.0147 -0.0096 0.9998 +vn 0.0167 -0.0012 0.9999 +vn 0.0167 -0.0031 0.9999 +vn 0.0166 -0.0048 0.9999 +vn 0.0159 0.0035 0.9999 +vn 0.0163 0.0010 0.9999 +vn 0.0160 0.0035 0.9999 +vn 0.0150 0.0076 0.9999 +vn 0.0156 0.0057 0.9999 +vn 0.0157 0.0057 0.9999 +vn -0.0001 0.0227 0.9997 +vn 0.0011 0.0226 0.9997 +vn 0.0025 0.0223 0.9997 +vn 0.0112 0.0150 0.9998 +vn 0.0123 0.0132 0.9998 +vn 0.0134 0.0114 0.9998 +vn 0.0089 0.0178 0.9998 +vn 0.0101 0.0166 0.9998 +vn 0.0101 0.0165 0.9998 +vn 0.0058 0.0203 0.9998 +vn 0.0074 0.0191 0.9998 +vn 0.0025 0.0222 0.9997 +vn 0.0040 0.0214 0.9998 +vn -0.0151 0.0023 0.9999 +vn -0.0152 0.0023 0.9999 +vn 0.0142 0.0096 0.9999 +vn -0.0029 0.0218 0.9998 +vn -0.0015 0.0225 0.9997 +vn -0.0029 0.0219 0.9998 +vn -0.0015 0.0224 0.9997 +vn 0.0165 -0.0064 0.9998 +vn 0.0162 -0.0077 0.9998 +vn -0.0099 0.0156 0.9998 +vn -0.0099 0.0157 0.9998 +vn -0.0088 0.0170 0.9998 +vn 0.0163 -0.0077 0.9998 +vn 0.0159 -0.0087 0.9998 +vn -0.0060 0.0197 0.9998 +vn -0.0045 0.0208 0.9998 +vn -0.0060 0.0198 0.9998 +vn -0.0045 0.0209 0.9998 +vn -0.0120 0.0120 -0.9999 +vn -0.0127 0.0105 -0.9999 +vn 0.0000 0.0000 -1.0000 +vn -0.0133 0.0087 -0.9999 +vn -0.0128 0.0105 -0.9999 +vn -0.0154 -0.0033 -0.9999 +vn -0.0152 -0.0049 -0.9999 +vn -0.0153 -0.0049 -0.9999 +vn -0.0147 -0.0064 -0.9999 +vn -0.0107 0.0146 -0.9998 +vn -0.0114 0.0134 -0.9998 +vn -0.0108 0.0147 -0.9998 +vn 0.0193 0.0046 -0.9998 +vn 0.0171 0.0028 -0.9998 +vn 0.0172 0.0028 -0.9998 +vn -0.0001 -0.0009 -1.0000 +vn -0.0002 -0.0009 -1.0000 +vn -0.0003 -0.0009 -1.0000 +vn -0.0148 -0.0064 -0.9999 +vn -0.0142 -0.0080 -0.9999 +vn -0.0141 -0.0080 -0.9999 +vn -0.0138 -0.0092 -0.9999 +vn -0.0134 0.0087 -0.9999 +vn -0.0139 0.0067 -0.9999 +vn -0.0133 0.0088 -0.9999 +vn -0.0145 0.0044 -0.9999 +vn -0.0171 -0.0083 -0.9998 +vn -0.0183 -0.0051 -0.9998 +vn -0.0172 -0.0083 -0.9998 +vn -0.0184 -0.0052 -0.9998 +vn -0.0172 -0.0011 -0.9999 +vn -0.0183 -0.0052 -0.9998 +vn -0.0060 0.0197 -0.9998 +vn -0.0074 0.0185 -0.9998 +vn -0.0061 0.0198 -0.9998 +vn -0.0075 0.0185 -0.9998 +vn -0.0087 0.0170 -0.9998 +vn -0.0154 0.0004 -0.9999 +vn -0.0154 -0.0014 -0.9999 +vn -0.0147 -0.0096 -0.9998 +vn 0.0168 -0.0040 -0.9999 +vn 0.0167 -0.0031 -0.9999 +vn 0.0168 -0.0031 -0.9999 +vn 0.0167 -0.0012 -0.9999 +vn 0.0002 0.0007 -1.0000 +vn 0.0001 0.0008 -1.0000 +vn 0.0163 0.0010 -0.9999 +vn 0.0159 0.0035 -0.9999 +vn 0.0156 0.0057 -0.9999 +vn 0.0150 0.0076 -0.9999 +vn 0.0025 0.0222 -0.9998 +vn 0.0011 0.0226 -0.9997 +vn 0.0025 0.0223 -0.9997 +vn -0.0001 0.0227 -0.9997 +vn 0.0133 0.0114 -0.9998 +vn 0.0123 0.0131 -0.9998 +vn 0.0134 0.0114 -0.9998 +vn 0.0112 0.0150 -0.9998 +vn 0.0101 0.0165 -0.9998 +vn 0.0089 0.0178 -0.9998 +vn 0.0074 0.0191 -0.9998 +vn 0.0058 0.0203 -0.9998 +vn 0.0040 0.0213 -0.9998 +vn 0.0040 0.0214 -0.9998 +vn -0.0144 0.0044 -0.9999 +vn -0.0151 0.0023 -0.9999 +vn 0.0142 0.0095 -0.9999 +vn -0.0015 0.0224 -0.9997 +vn -0.0029 0.0219 -0.9998 +vn -0.0099 0.0156 -0.9998 +vn -0.0099 0.0157 -0.9998 +vn -0.0029 0.0218 -0.9998 +vn -0.0045 0.0208 -0.9998 +vn -0.0045 0.0209 -0.9998 +vn -0.0060 0.0198 -0.9998 +vn -0.0044 0.0208 -0.9998 +vn 0.0236 0.0103 -0.9997 +vn 0.0222 0.0057 -0.9997 +vn 0.0001 0.0000 -1.0000 +vn 0.0192 0.0046 -0.9998 +vn -0.0008 0.0037 -1.0000 +vn -0.0007 0.0038 -1.0000 +vn 0.0003 0.0025 1.0000 +vn 0.0235 0.0093 0.9997 +vn 0.0004 0.0025 1.0000 +vn -0.0001 0.0000 -1.0000 +vn 0.0005 0.0019 -1.0000 +vn -0.0149 0.0022 -0.9999 +vn -0.0148 0.0022 -0.9999 +vn 0.0001 0.0020 -1.0000 +vn 0.0004 0.0019 -1.0000 +vn 0.8889 0.4557 0.0465 +vn 0.9620 0.2700 0.0418 +vn 0.9617 0.2584 0.0916 +vn 0.8875 0.4508 0.0951 +vn 0.9988 0.0431 0.0216 +vn 0.9969 0.0339 0.0715 +vn 0.8298 0.0221 0.5576 +vn 0.7945 0.2034 0.5722 +vn 0.7209 0.3612 0.5915 +vn -0.0021 0.3515 -0.9362 +vn -0.0224 0.3466 -0.9377 +vn -0.0048 0.8792 -0.4764 +vn -0.0545 0.8754 -0.4803 +vn -0.1085 0.8657 -0.4886 +vn -0.0437 0.3364 -0.9407 +vn 0.0146 -0.0095 -0.9998 +vn 0.0040 -0.0243 -0.9997 +vn 0.2324 -0.1654 -0.9585 +vn 0.2366 -0.1450 -0.9607 +vn 0.0063 -0.0234 -0.9997 +vn 0.2571 -0.1490 -0.9548 +vn 0.7426 -0.3979 -0.5388 +vn 0.7029 -0.4499 -0.5510 +vn 0.7080 -0.4314 -0.5592 +vn -0.1584 0.2163 -0.9634 +vn -0.1655 0.1964 -0.9664 +vn -0.0113 0.0135 -0.9998 +vn -0.4822 0.6651 -0.5702 +vn -0.5196 0.6245 -0.5831 +vn -0.5640 0.5723 -0.5953 +vn -0.1742 0.1745 -0.9691 +vn -0.7874 0.2312 -0.5715 +vn -0.7539 0.2985 -0.5853 +vn -0.2317 0.0970 -0.9679 +vn -0.2573 0.0773 -0.9633 +vn -0.6848 0.3326 -0.6484 +vn -0.1546 0.0876 -0.9841 +vn -0.0046 0.0188 -0.9998 +vn -0.0139 0.0119 -0.9998 +vn -0.0175 0.0061 -0.9998 +vn -0.0918 0.3018 -0.9489 +vn -0.1123 0.2811 -0.9531 +vn -0.0074 0.0184 -0.9998 +vn -0.2432 0.8221 -0.5148 +vn -0.3086 0.7904 -0.5292 +vn -0.3744 0.7497 -0.5457 +vn -0.1309 0.2564 -0.9577 +vn 0.2329 0.0853 -0.9688 +vn 0.2244 0.1144 -0.9678 +vn 0.2373 0.0518 -0.9700 +vn 0.7825 0.1720 -0.5985 +vn 0.7556 0.2788 -0.5927 +vn 0.7193 0.3693 -0.5884 +vn -0.0134 0.0088 -0.9999 +vn -0.1907 0.1253 -0.9736 +vn -0.1981 0.0953 -0.9755 +vn -0.6549 0.4354 -0.6177 +vn -0.6995 0.3408 -0.6282 +vn -0.7389 0.2250 -0.6351 +vn -0.2053 0.0621 -0.9767 +vn 0.0058 0.0202 -0.9998 +vn 0.1146 0.2964 -0.9482 +vn 0.0892 0.3156 -0.9447 +vn 0.1363 0.2748 -0.9518 +vn 0.3734 0.7656 -0.5238 +vn 0.3043 0.8037 -0.5114 +vn 0.2301 0.8352 -0.4994 +vn -0.2346 -0.8392 -0.4907 +vn -0.3093 -0.8076 -0.5022 +vn -0.1171 -0.3122 -0.9428 +vn -0.0904 -0.3323 -0.9388 +vn -0.3787 -0.7694 -0.5145 +vn -0.1402 -0.2902 -0.9466 +vn -0.0092 -0.0191 -0.9998 +vn -0.0076 -0.0204 -0.9998 +vn -0.0059 -0.0217 -0.9997 +vn -0.4403 -0.7272 -0.5266 +vn -0.1591 -0.2666 -0.9506 +vn -0.5007 -0.6784 -0.5377 +vn -0.1768 -0.2435 -0.9536 +vn -0.0117 -0.0162 -0.9998 +vn -0.0105 -0.0176 -0.9998 +vn -0.5669 -0.6149 -0.5481 +vn -0.1955 -0.2154 -0.9567 +vn -0.6283 -0.5415 -0.5586 +vn -0.2116 -0.1845 -0.9598 +vn -0.0142 -0.0124 -0.9998 +vn -0.0131 -0.0145 -0.9998 +vn -0.6828 -0.4622 -0.5658 +vn -0.2264 -0.1550 -0.9616 +vn -0.7302 -0.3735 -0.5721 +vn -0.2383 -0.1229 -0.9634 +vn -0.0162 -0.0084 -0.9998 +vn -0.0153 -0.0105 -0.9998 +vn -0.7666 -0.2819 -0.5769 +vn -0.2472 -0.0916 -0.9646 +vn -0.7974 -0.1749 -0.5775 +vn -0.2570 -0.0567 -0.9647 +vn -0.0176 -0.0039 -0.9998 +vn -0.0169 -0.0063 -0.9998 +vn -0.8148 -0.0489 -0.5777 +vn -0.2632 -0.0153 -0.9646 +vn -0.8139 0.0615 -0.5778 +vn -0.2622 0.0207 -0.9648 +vn -0.0179 0.0014 -0.9998 +vn -0.0180 -0.0010 -0.9998 +vn 0.0051 -0.8823 -0.4706 +vn -0.0435 -0.8813 -0.4705 +vn -0.0173 -0.3604 -0.9326 +vn 0.0019 -0.3614 -0.9324 +vn -0.0943 -0.8755 -0.4740 +vn -0.0372 -0.3568 -0.9334 +vn -0.0024 -0.0232 -0.9997 +vn -0.0011 -0.0234 -0.9997 +vn 0.0001 -0.0235 -0.9997 +vn -0.2064 -0.0897 -0.9743 +vn -0.1988 -0.1119 -0.9736 +vn -0.7167 -0.3131 -0.6232 +vn -0.6830 -0.3853 -0.6205 +vn -0.6546 -0.4350 -0.6183 +vn -0.1939 -0.1289 -0.9725 +vn 0.7865 -0.0206 -0.6173 +vn 0.2296 -0.0056 -0.9733 +vn 0.2306 0.0227 -0.9728 +vn 0.7852 0.0745 -0.6147 +vn 0.0166 -0.0004 -0.9999 +vn 0.0167 0.0017 -0.9999 +vn 0.0165 0.0036 -0.9999 +vn 0.2276 0.0497 -0.9725 +vn 0.7720 0.1658 -0.6136 +vn 0.9166 0.3998 0.0009 +vn 0.8724 0.4888 0.0042 +vn 0.8708 0.4901 0.0390 +vn 0.9160 0.3995 0.0363 +vn 0.8365 0.5477 0.0142 +vn 0.8324 0.5518 0.0504 +vn 0.6862 0.4566 0.5663 +vn 0.7220 0.4067 0.5597 +vn 0.7599 0.3312 0.5593 +vn 0.2479 -0.8258 -0.5066 +vn 0.0925 -0.3172 -0.9438 +vn 0.1141 -0.2954 -0.9485 +vn 0.3137 -0.7939 -0.5209 +vn 0.0061 -0.0211 -0.9998 +vn 0.0076 -0.0197 -0.9998 +vn 0.0090 -0.0184 -0.9998 +vn 0.1346 -0.2729 -0.9526 +vn 0.3808 -0.7539 -0.5355 +vn 0.6985 0.3548 -0.6215 +vn 0.2098 0.1105 -0.9715 +vn 0.2422 0.0735 -0.9674 +vn 0.7812 0.2091 -0.5882 +vn 0.0151 0.0079 -0.9999 +vn 0.0181 0.0055 -0.9998 +vn 0.0195 0.0012 -0.9998 +vn 0.2678 0.0183 -0.9633 +vn 0.8275 0.0226 -0.5611 +vn -0.4917 0.2982 -0.8181 +vn -0.5645 0.3321 -0.7557 +vn -0.0520 0.0100 -0.9986 +vn 0.0150 -0.0097 -0.9998 +vn -0.7030 0.3263 -0.6319 +vn -0.1691 0.0612 -0.9837 +vn -0.0215 -0.0103 -0.9997 +vn -0.0144 -0.0130 -0.9998 +vn 0.0000 -0.0006 -1.0000 +vn -0.2161 0.0059 -0.9763 +vn -0.2157 -0.0200 -0.9763 +vn -0.0153 -0.0014 -0.9999 +vn -0.7736 0.0199 -0.6334 +vn -0.7707 -0.0738 -0.6330 +vn -0.7603 -0.1641 -0.6285 +vn -0.2157 -0.0458 -0.9754 +vn -0.2317 -0.1126 -0.9662 +vn -0.2388 -0.0672 -0.9687 +vn -0.7188 -0.3547 -0.5979 +vn -0.7725 -0.2103 -0.5992 +vn -0.7809 -0.0401 -0.6233 +vn -0.2124 -0.0142 -0.9771 +vn -0.8890 0.0248 -0.4572 +vn -0.9173 -0.1118 -0.3822 +vn -0.4011 -0.0374 -0.9153 +vn -0.3337 0.0246 -0.9424 +vn -0.9284 -0.1681 -0.3315 +vn -0.4607 -0.0810 -0.8838 +vn -0.4014 -0.0375 -0.9151 +vn -0.4604 -0.0809 -0.8840 +vn -0.0265 -0.0048 -0.9996 +vn -0.0224 -0.0022 -0.9997 +vn -0.0190 0.0003 -0.9998 +vn 0.4863 -0.6672 -0.5642 +vn 0.1620 -0.2246 -0.9609 +vn 0.1710 -0.2070 -0.9633 +vn 0.5257 -0.6279 -0.5739 +vn 0.0111 -0.0154 -0.9998 +vn 0.0118 -0.0143 -0.9998 +vn 0.0126 -0.0129 -0.9998 +vn 0.1812 -0.1853 -0.9658 +vn 0.5714 -0.5765 -0.5842 +vn 0.2235 0.0723 -0.9720 +vn 0.7533 0.2419 -0.6115 +vn 0.0161 0.0052 -0.9999 +vn 0.0158 0.0069 -0.9999 +vn 0.2181 0.0956 -0.9712 +vn 0.7277 0.3173 -0.6081 +vn -0.8187 0.2059 -0.5360 +vn -0.2628 0.0693 -0.9624 +vn -0.0198 -0.0021 -0.9998 +vn -0.8311 -0.3379 0.4417 +vn -0.2883 -0.1147 0.9506 +vn -0.2846 -0.0321 0.9581 +vn -0.8395 -0.2805 0.4653 +vn -0.0182 -0.0048 0.9998 +vn -0.0100 0.0829 0.9965 +vn 0.0544 0.7756 0.6289 +vn -0.5496 0.6109 0.5698 +vn -0.9305 0.0152 0.3659 +vn 0.3775 0.0234 0.9257 +vn 0.4400 0.1296 0.8886 +vn 0.8925 -0.0128 0.4508 +vn 0.8951 0.2089 0.3940 +vn 0.4401 0.1297 0.8885 +vn 0.8950 0.2089 0.3942 +vn 0.8985 0.3254 0.2945 +vn 0.5108 0.1933 0.8377 +vn 0.5105 0.1933 0.8379 +vn -0.1120 0.2807 0.9532 +vn -0.0917 0.3018 0.9489 +vn -0.1307 0.2562 0.9577 +vn -0.3838 0.7697 0.5102 +vn -0.3155 0.8090 0.4960 +vn -0.2481 0.8397 0.4831 +vn 0.0166 -0.0048 0.9998 +vn 0.2469 -0.0718 0.9664 +vn 0.2453 -0.0959 0.9647 +vn 0.0164 -0.0064 0.9998 +vn 0.8060 -0.2380 0.5419 +vn 0.7855 -0.3098 0.5358 +vn 0.7658 -0.3643 0.5300 +vn 0.2433 -0.1153 0.9631 +vn -0.1655 0.1965 0.9664 +vn -0.1584 0.2164 0.9634 +vn -0.1742 0.1745 0.9691 +vn -0.5848 0.5940 0.5524 +vn -0.5373 0.6463 0.5418 +vn -0.4973 0.6863 0.5307 +vn 0.2369 -0.1447 0.9607 +vn 0.2438 -0.1516 0.9579 +vn 0.7286 -0.4438 0.5217 +vn 0.7284 -0.4542 0.5130 +vn 0.7686 -0.3992 0.4999 +vn 0.2689 -0.1350 0.9537 +vn 0.0052 -0.8964 0.4432 +vn 0.0569 -0.8928 0.4468 +vn 0.0219 -0.3573 0.9337 +vn 0.0019 -0.3609 0.9326 +vn 0.1133 -0.8841 0.4533 +vn 0.0431 -0.3490 0.9361 +vn 0.0028 -0.0229 0.9997 +vn 0.0014 -0.0233 0.9997 +vn 0.0001 -0.0235 0.9997 +vn 0.1702 0.2288 0.9585 +vn 0.1859 0.2000 0.9620 +vn 0.5069 0.6928 0.5129 +vn 0.5742 0.6281 0.5252 +vn 0.6390 0.5541 0.5336 +vn 0.2012 0.1724 0.9643 +vn -0.2157 -0.0200 0.9763 +vn -0.2162 0.0059 0.9763 +vn -0.2157 -0.0458 0.9754 +vn -0.7963 -0.1722 0.5799 +vn -0.8079 -0.0777 0.5842 +vn -0.8114 0.0207 0.5842 +vn 0.0894 0.3160 0.9445 +vn 0.1143 0.2959 0.9483 +vn 0.2342 0.8511 0.4698 +vn 0.3103 0.8202 0.4805 +vn 0.3816 0.7831 0.4911 +vn 0.1365 0.2751 0.9517 +vn -0.2392 -0.8547 0.4607 +vn -0.0905 -0.3325 0.9388 +vn -0.1171 -0.3126 0.9426 +vn -0.3158 -0.8237 0.4708 +vn -0.0059 -0.0217 0.9997 +vn -0.0076 -0.0205 0.9998 +vn -0.0092 -0.0191 0.9998 +vn -0.1402 -0.2898 0.9468 +vn -0.3873 -0.7861 0.4818 +vn -0.1590 -0.2666 0.9506 +vn -0.4512 -0.7444 0.4922 +vn -0.0105 -0.0177 0.9998 +vn -0.0117 -0.0162 0.9998 +vn -0.1767 -0.2434 0.9537 +vn -0.5140 -0.6958 0.5017 +vn 0.2244 0.1144 0.9678 +vn 0.2329 0.0853 0.9688 +vn 0.7443 0.3823 0.5476 +vn 0.7828 0.2889 0.5512 +vn 0.8113 0.1785 0.5567 +vn 0.2373 0.0518 0.9701 +vn -0.6476 -0.5577 0.5192 +vn -0.2117 -0.1845 0.9598 +vn -0.2262 -0.1547 0.9617 +vn -0.7049 -0.4768 0.5251 +vn -0.0142 -0.0124 0.9998 +vn -0.0153 -0.0105 0.9998 +vn -0.0162 -0.0084 0.9998 +vn -0.2383 -0.1229 0.9634 +vn -0.7548 -0.3859 0.5304 +vn -0.2473 -0.0916 0.9646 +vn -0.7934 -0.2916 0.5343 +vn -0.0169 -0.0063 0.9998 +vn -0.0176 -0.0039 0.9998 +vn -0.2570 -0.0567 0.9647 +vn -0.8256 -0.1809 0.5345 +vn -0.2627 -0.0152 0.9647 +vn -0.8437 -0.0507 0.5344 +vn -0.0180 -0.0010 0.9998 +vn -0.0179 0.0014 0.9998 +vn -0.2623 0.0207 0.9648 +vn -0.8424 0.0634 0.5351 +vn -0.0173 -0.3604 0.9326 +vn -0.0442 -0.8953 0.4433 +vn -0.0011 -0.0235 0.9997 +vn -0.0024 -0.0232 0.9997 +vn -0.0371 -0.3563 0.9336 +vn -0.0960 -0.8899 0.4459 +vn -0.0171 -0.0083 0.9998 +vn -0.0184 -0.0050 0.9998 +vn -0.2393 -0.0659 0.9687 +vn -0.2320 -0.1123 0.9662 +vn -0.2115 -0.0137 0.9773 +vn -0.7933 -0.0378 0.6077 +vn -0.7959 -0.2068 0.5691 +vn -0.7447 -0.3631 0.5600 +vn 0.8235 -0.0217 0.5668 +vn 0.8218 0.0777 0.5644 +vn 0.2309 0.0227 0.9727 +vn 0.2293 -0.0055 0.9733 +vn 0.8075 0.1732 0.5639 +vn 0.2277 0.0497 0.9725 +vn 0.0165 0.0036 0.9999 +vn 0.0167 0.0017 0.9999 +vn 0.0165 -0.0004 0.9999 +vn 0.3140 -0.0802 0.9460 +vn 0.8398 -0.2502 0.4817 +vn 0.2534 -0.8429 0.4747 +vn 0.3213 -0.8120 0.4872 +vn 0.1142 -0.2959 0.9484 +vn 0.0926 -0.3169 0.9439 +vn 0.3909 -0.7730 0.4996 +vn 0.1346 -0.2730 0.9526 +vn 0.0090 -0.0184 0.9998 +vn 0.0076 -0.0198 0.9998 +vn 0.0061 -0.0210 0.9998 +vn 0.7209 0.3612 0.5914 +vn 0.2427 0.0722 0.9674 +vn 0.2097 0.1101 0.9715 +vn 0.2699 0.0180 0.9627 +vn 0.0197 0.0012 0.9998 +vn 0.0181 0.0054 0.9998 +vn 0.0151 0.0079 0.9999 +vn -0.7319 0.4458 0.5153 +vn -0.2429 0.1475 0.9588 +vn -0.2408 0.1489 0.9591 +vn -0.7295 0.4493 0.5157 +vn -0.0160 0.0097 0.9998 +vn -0.0157 0.0097 0.9998 +vn -0.0160 0.0081 0.9998 +vn -0.2523 0.1272 0.9593 +vn -0.7737 0.3733 0.5118 +vn 0.6943 -0.4589 0.5544 +vn 0.7466 -0.3616 0.5585 +vn 0.2134 -0.1048 0.9713 +vn 0.2019 -0.1353 0.9700 +vn 0.7918 -0.2404 0.5615 +vn 0.2237 -0.0684 0.9723 +vn 0.0161 -0.0049 0.9999 +vn 0.0152 -0.0075 0.9999 +vn 0.0143 -0.0096 0.9999 +vn 0.7599 0.3312 0.5594 +vn 0.2087 0.1179 0.9709 +vn 0.2181 0.0956 0.9712 +vn 0.1991 0.1325 0.9710 +vn 0.0142 0.0095 0.9999 +vn 0.0150 0.0085 0.9999 +vn 0.0157 0.0069 0.9999 +vn 0.1812 -0.8676 0.4631 +vn 0.0676 -0.3359 0.9395 +vn 0.0044 -0.0222 0.9997 +vn 0.5018 -0.6880 0.5242 +vn 0.5438 -0.6489 0.5322 +vn 0.1710 -0.2069 0.9633 +vn 0.1620 -0.2245 0.9609 +vn 0.5925 -0.5973 0.5405 +vn 0.1811 -0.1850 0.9659 +vn 0.0126 -0.0129 0.9998 +vn 0.0118 -0.0143 0.9998 +vn 0.0111 -0.0153 0.9998 +vn 0.7873 0.2526 0.5625 +vn 0.2239 0.0726 0.9719 +vn 0.0161 0.0052 0.9999 +vn -0.2851 0.0803 0.9551 +vn -0.8527 0.1971 0.4839 +vn -0.0170 0.0047 0.9998 +vn -0.0192 0.0003 0.9998 +vn -0.3422 0.0090 0.9396 +vn -0.9123 -0.0378 0.4078 +vn -0.7809 -0.0401 -0.6234 +vn -0.7724 -0.2103 -0.5993 +vn -0.9608 -0.2608 -0.0941 +vn -0.9943 -0.0488 -0.0944 +vn -0.7188 -0.3547 -0.5980 +vn -0.8918 -0.4401 -0.1045 +vn -0.8970 -0.4420 -0.0036 +vn -0.9650 -0.2621 0.0001 +vn -0.9988 -0.0498 -0.0041 +vn 0.7277 0.3174 -0.6080 +vn 0.6918 0.3899 -0.6078 +vn 0.8669 0.4886 -0.0987 +vn 0.9122 0.3979 -0.0980 +vn 0.6578 0.4379 -0.6129 +vn 0.8279 0.5511 -0.1042 +vn 0.8324 0.5542 -0.0041 +vn 0.8711 0.4911 -0.0037 +vn 0.9165 0.4000 -0.0037 +vn -0.7141 0.1734 -0.6782 +vn -0.7488 0.1035 -0.6547 +vn -0.9846 0.1371 -0.1083 +vn -0.9652 0.2319 -0.1211 +vn -0.9905 0.1360 -0.0219 +vn -0.9727 0.2291 -0.0383 +vn 0.6662 -0.4408 -0.6016 +vn 0.7147 -0.3466 -0.6075 +vn 0.8954 -0.4343 -0.0984 +vn 0.8301 -0.5495 -0.0948 +vn 0.7570 -0.2300 -0.6116 +vn 0.9520 -0.2891 -0.1009 +vn 0.9568 -0.2908 -0.0039 +vn 0.8995 -0.4368 -0.0037 +vn 0.8335 -0.5525 -0.0036 +vn -0.7434 -0.2393 -0.6246 +vn -0.9472 -0.3047 -0.0997 +vn -0.9120 -0.3982 -0.0986 +vn -0.7603 -0.1642 -0.6284 +vn -0.9725 -0.2097 -0.1011 +vn -0.9776 -0.2104 -0.0038 +vn -0.9520 -0.3060 -0.0038 +vn -0.9165 -0.4000 -0.0037 +vn 0.2479 -0.8257 -0.5068 +vn 0.3135 -0.7936 -0.5214 +vn 0.3656 -0.9286 -0.0640 +vn 0.2859 -0.9564 -0.0599 +vn 0.3807 -0.7539 -0.5354 +vn 0.4487 -0.8911 -0.0686 +vn 0.4492 -0.8935 -0.0026 +vn 0.3658 -0.9307 -0.0024 +vn 0.2859 -0.9583 -0.0023 +vn -0.6545 -0.4349 -0.6184 +vn -0.6830 -0.3853 -0.6206 +vn -0.8668 -0.4888 -0.0988 +vn -0.8285 -0.5505 -0.1023 +vn -0.8711 -0.4911 -0.0037 +vn -0.8329 -0.5533 -0.0040 +vn 0.4430 -0.7075 -0.5506 +vn 0.5285 -0.8458 -0.0734 +vn 0.5867 -0.8061 -0.0777 +vn 0.5881 -0.8088 -0.0029 +vn 0.5294 -0.8484 -0.0028 +vn -0.5197 0.6245 -0.5830 +vn -0.6383 0.7654 -0.0821 +vn -0.7000 0.7089 -0.0864 +vn -0.5860 0.8066 -0.0779 +vn -0.5881 0.8088 -0.0029 +vn -0.6410 0.7676 -0.0031 +vn -0.7031 0.7111 -0.0033 +vn -0.9776 -0.2104 0.0009 +vn -0.9955 -0.0948 0.0009 +vn -0.9948 -0.0949 0.0373 +vn -0.9769 -0.2104 0.0368 +vn -0.9997 0.0259 0.0009 +vn -0.9990 0.0258 0.0375 +vn -0.8113 0.0207 0.5842 +vn -0.8079 -0.0776 0.5842 +vn -0.0545 0.8753 -0.4805 +vn -0.0627 0.9967 -0.0516 +vn -0.1253 0.9907 -0.0534 +vn -0.0056 0.9987 -0.0505 +vn -0.0057 1.0000 -0.0019 +vn -0.0629 0.9980 -0.0019 +vn -0.1258 0.9921 -0.0020 +vn 0.7792 -0.1157 -0.6161 +vn 0.9840 -0.1461 -0.1021 +vn 0.7865 -0.0206 -0.6172 +vn 0.9944 -0.0260 -0.1023 +vn 0.9997 -0.0259 -0.0039 +vn 0.9892 -0.1468 -0.0039 +vn -0.4372 0.7041 -0.5596 +vn -0.5274 0.8464 -0.0736 +vn -0.3744 0.7498 -0.5456 +vn -0.4474 0.8917 -0.0689 +vn -0.4491 0.8935 -0.0026 +vn -0.5293 0.8484 -0.0028 +vn -0.0943 -0.8756 -0.4737 +vn -0.1062 -0.9930 -0.0514 +vn -0.1801 -0.9822 -0.0529 +vn -0.1591 -0.8625 -0.4804 +vn -0.1062 -0.9943 -0.0019 +vn -0.1800 -0.9837 -0.0020 +vn -0.2676 -0.9635 -0.0021 +vn -0.2676 -0.9619 -0.0554 +vn -0.2346 -0.8393 -0.4905 +vn -0.1733 0.8479 -0.5011 +vn -0.2017 0.9778 -0.0564 +vn -0.2849 0.9567 -0.0601 +vn -0.2024 0.9793 -0.0021 +vn -0.2859 0.9583 -0.0022 +vn -0.9892 0.1468 0.0009 +vn -0.9885 0.1467 0.0375 +vn -0.9568 0.2908 0.0009 +vn -0.9561 0.2907 0.0371 +vn -0.7745 0.2360 0.5869 +vn -0.8018 0.1189 0.5856 +vn -0.7736 0.0198 -0.6334 +vn -0.7645 0.1134 -0.6346 +vn -0.9839 0.1459 -0.1029 +vn -0.9944 0.0256 -0.1030 +vn -0.9517 0.2895 -0.1019 +vn -0.9568 0.2908 -0.0039 +vn -0.9892 0.1468 -0.0039 +vn -0.9997 0.0259 -0.0039 +vn 0.2676 0.9635 0.0005 +vn 0.2674 0.9634 0.0202 +vn 0.1798 0.9835 0.0192 +vn 0.1800 0.9837 0.0005 +vn 0.2342 0.8510 0.4701 +vn 0.1579 0.8736 0.4602 +vn 0.0937 0.8870 0.4522 +vn 0.1061 0.9942 0.0186 +vn 0.1062 0.9943 0.0004 +vn 0.4940 0.6745 -0.5487 +vn 0.5907 0.8039 -0.0693 +vn 0.5152 0.8546 -0.0657 +vn 0.4349 0.7238 -0.5357 +vn 0.5925 0.8055 -0.0026 +vn 0.5167 0.8562 -0.0025 +vn 0.4402 0.8979 -0.0023 +vn 0.4390 0.8964 -0.0621 +vn 0.7568 0.6536 0.0007 +vn 0.7564 0.6535 0.0279 +vn 0.6763 0.7362 0.0266 +vn 0.6767 0.7362 0.0006 +vn 0.6390 0.5540 0.5337 +vn 0.5742 0.6281 0.5251 +vn 0.5068 0.6927 0.5131 +vn 0.5922 0.8054 0.0252 +vn 0.5926 0.8055 0.0006 +vn 0.6198 0.5370 -0.5723 +vn 0.7543 0.6521 -0.0767 +vn 0.6744 0.7347 -0.0732 +vn 0.5583 0.6101 -0.5622 +vn 0.7568 0.6536 -0.0029 +vn 0.6767 0.7363 -0.0028 +vn -0.8942 -0.4468 0.0284 +vn -0.8311 -0.5557 0.0213 +vn -0.8342 -0.5484 0.0575 +vn -0.8954 -0.4406 0.0650 +vn -0.8304 -0.5571 0.0071 +vn -0.8316 -0.5537 0.0436 +vn -0.6834 -0.4545 0.5713 +vn -0.6890 -0.4514 0.5670 +vn -0.7446 -0.3631 0.5601 +vn 0.7823 0.1720 -0.5986 +vn 0.9732 0.2137 -0.0854 +vn 0.9350 0.3445 -0.0841 +vn 0.9767 0.2144 -0.0032 +vn 0.9384 0.3455 -0.0032 +vn 0.8900 0.4559 -0.0031 +vn 0.8869 0.4546 -0.0823 +vn 0.7194 0.3693 -0.5883 +vn 0.1112 -0.8690 -0.4822 +vn 0.1775 -0.8518 -0.4929 +vn 0.2025 -0.9777 -0.0562 +vn 0.1259 -0.9906 -0.0533 +vn 0.2024 -0.9793 -0.0021 +vn 0.1258 -0.9921 -0.0020 +vn -0.6848 0.3325 -0.6484 +vn -0.8986 0.4277 -0.0979 +vn -0.8692 0.4744 -0.1396 +vn -0.5670 0.3175 -0.7601 +vn -0.9033 0.4291 -0.0030 +vn -0.8783 0.4781 -0.0032 +vn -0.8541 0.5200 -0.0034 +vn -0.8422 0.5129 -0.1662 +vn -0.4918 0.2984 -0.8180 +vn 0.7798 -0.2295 -0.5825 +vn 0.9562 -0.2814 -0.0808 +vn 0.9796 -0.1832 -0.0827 +vn 0.7951 -0.1492 -0.5879 +vn 0.9594 -0.2820 -0.0031 +vn 0.9830 -0.1835 -0.0031 +vn 0.9971 -0.0759 -0.0032 +vn 0.9935 -0.0759 -0.0843 +vn 0.8029 -0.0617 -0.5929 +vn 0.5713 -0.5764 -0.5843 +vn 0.6185 -0.5149 -0.5936 +vn 0.7652 -0.6374 -0.0907 +vn 0.7009 -0.7080 -0.0865 +vn 0.7679 -0.6405 -0.0034 +vn 0.7031 -0.7111 -0.0033 +vn 0.8539 -0.5204 0.0006 +vn 0.8536 -0.5202 0.0266 +vn 0.8780 -0.4779 0.0272 +vn 0.8783 -0.4781 0.0007 +vn 0.7286 -0.4439 0.5216 +vn 0.7472 -0.4068 0.5256 +vn 0.7659 -0.3643 0.5299 +vn 0.9029 -0.4289 0.0279 +vn 0.9033 -0.4291 0.0007 +vn -0.7706 -0.0738 -0.6330 +vn -0.9902 -0.0946 -0.1024 +vn -0.9955 -0.0948 -0.0039 +vn -0.9165 -0.4000 0.0009 +vn -0.9520 -0.3060 0.0009 +vn -0.9514 -0.3059 0.0363 +vn -0.9159 -0.3998 0.0359 +vn -0.7778 -0.2506 0.5765 +vn -0.7493 -0.3275 0.5756 +vn -0.8446 0.5187 -0.1328 +vn -0.5647 0.3321 -0.7555 +vn -0.8511 0.5250 -0.0031 +vn -0.8972 0.4416 -0.0026 +vn -0.8951 0.4375 -0.0858 +vn 0.9568 -0.2908 0.0009 +vn 0.9892 -0.1468 0.0009 +vn 0.9885 -0.1467 0.0374 +vn 0.9562 -0.2905 0.0370 +vn 0.9997 -0.0259 0.0009 +vn 0.9990 -0.0260 0.0374 +vn 0.8235 -0.0217 0.5669 +vn 0.8157 -0.1212 0.5656 +vn 0.8753 -0.0568 -0.4803 +vn 0.9972 -0.0603 -0.0443 +vn 0.9528 -0.2976 -0.0594 +vn 0.8157 -0.2603 -0.5166 +vn 0.9984 -0.0558 -0.0008 +vn 0.9554 -0.2952 -0.0022 +vn 0.8879 -0.4600 -0.0026 +vn 0.8849 -0.4609 -0.0679 +vn 0.7426 -0.3979 -0.5387 +vn -0.9982 0.0395 -0.0446 +vn -0.9927 -0.1141 -0.0378 +vn -0.9991 0.0427 -0.0029 +vn -0.9934 -0.1142 -0.0100 +vn -0.9826 -0.1832 -0.0311 +vn -0.9830 -0.1776 -0.0460 +vn 0.9417 0.3306 0.0624 +vn 0.9385 0.3431 0.0400 +vn 0.9710 0.2361 0.0372 +vn 0.9739 0.2239 0.0384 +vn 0.8924 -0.0128 0.4510 +vn 0.9996 -0.0035 0.0288 +vn 0.9998 -0.0105 0.0165 +vn 0.0057 -0.9987 -0.0504 +vn -0.0489 -0.9975 -0.0503 +vn 0.0057 -1.0000 -0.0019 +vn -0.0489 -0.9988 -0.0019 +vn 0.8962 0.2111 -0.3903 +vn 0.9727 0.2317 -0.0148 +vn 0.9892 0.1437 -0.0273 +vn 0.8924 0.1247 -0.4336 +vn 0.9718 0.2354 0.0157 +vn 0.9890 0.1477 0.0044 +vn 0.9594 -0.2820 0.0007 +vn 0.9590 -0.2820 0.0294 +vn 0.9825 -0.1836 0.0301 +vn 0.9830 -0.1835 0.0007 +vn 0.8060 -0.2380 0.5420 +vn 0.8228 -0.1546 0.5469 +vn 0.8319 -0.0641 0.5512 +vn 0.9966 -0.0759 0.0307 +vn 0.9971 -0.0759 0.0007 +vn -0.6548 0.4354 -0.6177 +vn -0.6095 0.5100 -0.6070 +vn -0.7643 0.6384 -0.0912 +vn -0.8294 0.5505 -0.0954 +vn -0.7679 0.6406 -0.0034 +vn -0.8335 0.5525 -0.0036 +vn -0.9906 0.0115 -0.1362 +vn -0.9930 0.0386 -0.1113 +vn -0.5970 0.7963 -0.0979 +vn -0.6387 0.7547 -0.1502 +vn -0.9306 0.0153 0.3657 +vn -0.5496 0.6110 0.5698 +vn -0.5970 0.7962 -0.0979 +vn 0.1045 0.9941 -0.0306 +vn -0.6388 0.7545 -0.1503 +vn 0.0597 0.9955 -0.0730 +vn -0.8140 0.0615 -0.5777 +vn -0.9936 0.0753 -0.0839 +vn -0.9797 0.1826 -0.0824 +vn -0.8048 0.1497 -0.5744 +vn -0.9971 0.0759 -0.0032 +vn -0.9830 0.1835 -0.0031 +vn -0.9594 0.2820 -0.0031 +vn -0.9564 0.2808 -0.0804 +vn -0.7874 0.2312 -0.5714 +vn -0.1482 0.5435 -0.8262 +vn -0.1913 0.6880 -0.7000 +vn 0.0056 0.7319 -0.6814 +vn 0.1023 0.6106 -0.7853 +vn -0.1914 0.6880 -0.7000 +vn -0.1147 0.5575 -0.8222 +vn 0.0492 0.5984 -0.7997 +vn 0.0057 0.7319 -0.6814 +vn 0.6056 0.5965 -0.5267 +vn 0.6042 0.6722 -0.4280 +vn 0.6041 0.6722 -0.4281 +vn 0.6054 0.6119 -0.5090 +vn -0.5916 -0.8033 -0.0691 +vn -0.6754 -0.7339 -0.0729 +vn -0.5670 -0.6150 -0.5480 +vn -0.5926 -0.8055 -0.0026 +vn -0.6767 -0.7362 -0.0028 +vn -0.7568 -0.6536 -0.0029 +vn -0.7549 -0.6513 -0.0764 +vn -0.8745 -0.2873 -0.3907 +vn -0.9615 -0.2628 -0.0801 +vn -0.7575 0.2642 -0.5970 +vn -0.6320 0.1714 -0.7558 +vn -0.9715 -0.2103 -0.1094 +vn -0.6297 0.2738 -0.7270 +vn -0.7574 0.2643 -0.5970 +vn -0.6299 0.2737 -0.7269 +vn -0.0944 0.5154 -0.8517 +vn -0.1800 0.6201 -0.7636 +vn -0.6322 0.1713 -0.7557 +vn -0.1729 0.4915 -0.8535 +vn 0.8457 -0.5286 -0.0730 +vn 0.8487 -0.5288 -0.0028 +vn 0.8539 -0.5204 -0.0030 +vn 0.8515 -0.5189 -0.0759 +vn 0.7081 -0.4315 -0.5589 +vn 0.0489 0.9986 0.0183 +vn 0.0489 0.9988 0.0004 +vn 0.0433 0.8927 0.4486 +vn -0.0049 0.8935 0.4490 +vn -0.0057 0.9998 0.0183 +vn -0.0057 1.0000 0.0004 +vn -0.9261 -0.3662 -0.0914 +vn -0.9246 -0.3753 -0.0656 +vn -0.9434 -0.3225 -0.0778 +vn -0.9444 -0.3127 -0.1021 +vn -0.8395 -0.2805 0.4654 +vn -0.3559 -0.9327 -0.0584 +vn -0.3093 -0.8076 -0.5021 +vn -0.3562 -0.9344 -0.0022 +vn -0.4403 -0.8979 -0.0023 +vn -0.4398 -0.8960 -0.0618 +vn -0.3787 -0.7694 -0.5144 +vn 0.9767 0.2144 0.0007 +vn 0.9763 0.2143 0.0310 +vn 0.9379 0.3454 0.0306 +vn 0.9384 0.3455 0.0007 +vn 0.8114 0.1785 0.5566 +vn 0.7443 0.3823 0.5475 +vn 0.8896 0.4558 0.0299 +vn 0.8900 0.4559 0.0007 +vn -0.1258 0.9921 0.0005 +vn -0.0629 0.9980 0.0004 +vn -0.0629 0.9978 0.0187 +vn -0.1257 0.9919 0.0193 +vn -0.0553 0.8900 0.4526 +vn -0.1102 0.8811 0.4600 +vn 0.3551 0.9330 -0.0587 +vn 0.3043 0.8035 -0.5116 +vn 0.3561 0.9344 -0.0022 +vn 0.2676 0.9635 -0.0021 +vn 0.2668 0.9621 -0.0556 +vn 0.2301 0.8352 -0.4996 +vn -0.8872 -0.4541 -0.0818 +vn -0.9352 -0.3441 -0.0836 +vn -0.7667 -0.2819 -0.5768 +vn -0.8900 -0.4559 -0.0031 +vn -0.9384 -0.3455 -0.0032 +vn -0.9767 -0.2144 -0.0032 +vn -0.9733 -0.2135 -0.0848 +vn -0.7974 -0.1749 -0.5776 +vn -0.9594 0.2820 0.0007 +vn -0.9590 0.2818 0.0293 +vn -0.9303 0.3658 0.0285 +vn -0.9306 0.3660 0.0007 +vn -0.8148 0.2386 0.5284 +vn -0.7922 0.3109 0.5251 +vn -0.7705 0.3657 0.5221 +vn -0.9030 0.4288 0.0278 +vn -0.9033 0.4291 0.0007 +vn 0.6984 0.3547 -0.6216 +vn 0.7813 0.2090 -0.5881 +vn 0.9611 0.2614 -0.0887 +vn 0.8855 0.4510 -0.1116 +vn 0.8273 0.0226 -0.5612 +vn 0.9978 0.0306 -0.0590 +vn 0.9995 0.0317 0.0007 +vn 0.9643 0.2649 -0.0074 +vn 0.8902 0.4554 -0.0067 +vn 0.0923 0.8725 -0.4799 +vn 0.1058 0.9931 -0.0512 +vn 0.0488 0.9975 -0.0504 +vn 0.0427 0.8785 -0.4757 +vn 0.1062 0.9943 -0.0019 +vn 0.0489 0.9988 -0.0019 +vn 0.7853 -0.1967 -0.5870 +vn 0.7848 -0.1406 -0.6036 +vn 0.9815 -0.1903 -0.0210 +vn 0.9691 -0.2459 -0.0219 +vn 0.8066 0.2887 -0.5157 +vn 0.9185 0.3848 -0.0915 +vn 0.9123 0.4049 -0.0611 +vn 0.9841 -0.1750 0.0291 +vn 0.9692 -0.2435 0.0367 +vn -0.8980 0.4401 0.0003 +vn -0.8981 0.4392 0.0237 +vn -0.9705 0.2404 0.0170 +vn -0.9697 0.2444 -0.0032 +vn -0.7737 0.3734 0.5119 +vn -0.8527 0.1971 0.4837 +vn -0.9121 -0.0378 0.4081 +vn -0.9999 -0.0161 -0.0002 +vn -0.9999 -0.0049 -0.0159 +vn 0.6505 0.4332 -0.6238 +vn 0.8269 0.5508 -0.1137 +vn 0.8321 0.5546 -0.0051 +vn -0.6621 -0.4338 -0.6110 +vn -0.8316 -0.5448 -0.1076 +vn -0.8366 -0.5477 -0.0050 +vn 0.7533 0.2419 -0.6116 +vn 0.9474 0.3043 -0.0993 +vn 0.9727 0.2090 -0.1005 +vn 0.9520 0.3060 -0.0038 +vn 0.9776 0.2104 -0.0038 +vn 0.1112 -0.8688 -0.4826 +vn 0.0431 -0.3490 -0.9361 +vn 0.0676 -0.3360 -0.9394 +vn 0.1776 -0.8519 -0.4927 +vn 0.0028 -0.0229 -0.9997 +vn 0.0044 -0.0222 -0.9997 +vn 0.0141 -0.0114 -0.9998 +vn 0.3038 -0.0915 -0.9483 +vn 0.0165 -0.0016 -0.9999 +vn 0.3566 -0.0044 -0.9342 +vn 0.8754 -0.0568 -0.4800 +vn -0.1827 0.1510 0.9715 +vn -0.0134 0.0087 0.9999 +vn -0.1908 0.1253 0.9736 +vn -0.6831 0.4547 0.5715 +vn -0.6340 0.5310 0.5622 +vn 0.6431 -0.5347 0.5481 +vn 0.1914 -0.1613 0.9682 +vn 0.0135 -0.0114 0.9998 +vn 0.7762 -0.1576 0.6105 +vn 0.7707 -0.1090 0.6278 +vn 0.1992 0.0211 0.9797 +vn 0.2080 -0.0406 0.9773 +vn 0.7939 0.3304 0.5104 +vn 0.4480 0.5997 0.6631 +vn 0.3108 0.6756 0.6686 +vn 0.0432 0.0640 0.9970 +vn 0.0162 -0.0016 0.9999 +vn -0.2617 0.0497 0.9639 +vn -0.8324 0.1546 0.5323 +vn -0.0179 0.0034 0.9998 +vn -0.0177 0.0053 0.9998 +vn -0.2594 0.0772 0.9627 +vn -0.8147 0.2386 0.5286 +vn 0.0243 0.0122 0.9996 +vn 0.5810 0.2355 0.7791 +vn 0.4883 0.2519 0.8356 +vn 0.0294 0.1004 0.9945 +vn 0.5810 0.2354 0.7791 +vn 0.9210 0.3685 0.1266 +vn 0.9089 0.3485 0.2289 +vn 0.4881 0.2518 0.8356 +vn 0.8161 0.5217 0.2486 +vn 0.3737 0.7236 0.5803 +vn 0.3735 0.7237 0.5803 +vn 0.0769 0.7700 0.6334 +vn -0.2051 -0.1338 0.9695 +vn -0.1938 -0.1288 0.9725 +vn -0.6891 -0.4514 0.5669 +vn -0.2128 0.0317 0.9766 +vn -0.2053 0.0621 0.9767 +vn -0.7746 0.2360 0.5868 +vn 0.4561 -0.7276 0.5124 +vn 0.1518 -0.2465 0.9572 +vn 0.0103 -0.0168 0.9998 +vn -0.2132 -0.0681 0.9746 +vn -0.2064 -0.0898 0.9743 +vn -0.7777 -0.2506 0.5765 +vn -0.2506 0.1193 0.9607 +vn -0.2468 0.1343 0.9597 +vn -0.7510 0.4087 0.5186 +vn -0.0169 0.0080 0.9998 +vn -0.0165 0.0090 0.9998 +vn -0.0136 0.0043 0.9999 +vn -0.0136 0.0744 0.9971 +vn -0.1248 0.0902 0.9881 +vn -0.1456 0.0302 0.9889 +vn -0.0278 0.7355 0.6770 +vn -0.0965 0.7296 0.6770 +vn -0.4955 0.6706 0.5521 +vn -0.6884 0.2235 0.6900 +vn -0.7106 0.1393 0.6896 +vn -0.0621 -0.3481 0.9354 +vn -0.1621 -0.8772 0.4519 +vn -0.0040 -0.0227 0.9997 +vn -0.0141 -0.0080 0.9999 +vn -0.1988 -0.1119 0.9736 +vn -0.7137 -0.4027 0.5731 +vn 0.2473 -0.0182 0.9688 +vn 0.2481 -0.0456 0.9677 +vn 0.8318 -0.0641 0.5513 +vn 0.6773 0.4500 0.5819 +vn 0.1957 0.1308 0.9719 +vn 0.0143 0.0095 0.9999 +vn 0.8158 -0.1212 0.5656 +vn 0.2277 -0.0336 0.9731 +vn 0.0164 -0.0024 0.9999 +vn -0.0021 0.3515 0.9362 +vn 0.0176 0.3516 0.9360 +vn 0.0011 0.0227 0.9997 +vn -0.0049 0.8934 0.4492 +vn 0.0433 0.8926 0.4487 +vn 0.0937 0.8871 0.4519 +vn 0.0378 0.3458 0.9375 +vn 0.2133 0.1436 0.9664 +vn 0.6949 0.4729 0.5417 +vn 0.2421 0.0148 0.9701 +vn 0.0162 0.0010 0.9999 +vn 0.8291 0.0490 0.5570 +vn 0.1546 0.2535 0.9549 +vn 0.4453 0.7417 0.5016 +vn 0.0621 0.3322 0.9411 +vn -0.1981 0.0953 0.9755 +vn -0.7317 0.3568 0.5808 +vn -0.1955 -0.2154 0.9568 +vn -0.5832 -0.6320 0.5103 +vn -0.0131 -0.0145 0.9998 +vn -0.0044 0.0209 0.9998 +vn -0.0677 0.3201 0.9450 +vn -0.0437 0.3363 0.9407 +vn -0.1764 0.8643 0.4710 +vn -0.1103 0.8810 0.4601 +vn 0.2403 -0.1308 0.9618 +vn 0.0160 -0.0087 0.9998 +vn 0.7471 -0.4068 0.5256 +vn -0.1475 0.2337 0.9611 +vn -0.4496 0.7247 0.5222 +vn -0.2551 0.1010 0.9616 +vn -0.7923 0.3109 0.5250 +vn -0.0173 0.0069 0.9998 +vn -0.0224 0.3466 0.9377 +vn -0.0553 0.8900 0.4527 +vn -0.4102 -0.0777 0.9087 +vn -0.9177 -0.2186 0.3318 +vn -0.0224 -0.0044 0.9997 +vn -0.0240 -0.0077 0.9997 +vn -0.4240 -0.1355 0.8955 +vn -0.9176 -0.2186 0.3319 +vn -0.4102 -0.0778 0.9087 +vn -0.4241 -0.1354 0.8954 +vn -0.8898 -0.3029 0.3412 +vn -0.1827 0.1510 -0.9715 +vn -0.6096 0.5101 -0.6068 +vn 0.1914 -0.1613 -0.9682 +vn 0.0134 -0.0114 -0.9998 +vn 0.0143 -0.0096 -0.9999 +vn 0.2018 -0.1353 -0.9700 +vn 0.6661 -0.4407 -0.6018 +vn 0.2047 -0.0495 -0.9776 +vn 0.2019 0.0246 -0.9791 +vn 0.7848 -0.1407 -0.6036 +vn 0.0160 -0.0019 -0.9999 +vn 0.0485 0.0761 -0.9959 +vn 0.3005 0.6500 -0.6980 +vn 0.4370 0.5748 -0.6918 +vn 0.8067 0.2887 -0.5157 +vn -0.8049 0.1497 -0.5743 +vn -0.2616 0.0497 -0.9639 +vn -0.0179 0.0034 -0.9998 +vn -0.0119 0.1263 -0.9919 +vn 0.3254 0.2274 -0.9178 +vn 0.4077 0.1167 -0.9056 +vn -0.1482 0.5436 -0.8261 +vn 0.1024 0.6107 -0.7852 +vn 0.6055 0.6119 -0.5089 +vn 0.8174 0.3494 -0.4580 +vn 0.8867 0.2468 -0.3910 +vn -0.2051 -0.1338 -0.9696 +vn -0.6622 -0.4339 -0.6110 +vn -0.2132 0.0319 -0.9765 +vn 0.1518 -0.2465 -0.9572 +vn 0.4431 -0.7076 -0.5504 +vn 0.0103 -0.0167 -0.9998 +vn -0.2132 -0.0681 -0.9746 +vn -0.0152 -0.0048 -0.9999 +vn -0.7435 -0.2394 -0.6245 +vn -0.5669 0.3174 -0.7602 +vn -0.0395 0.0365 -0.9986 +vn 0.0045 0.0155 -0.9999 +vn -0.0134 0.0053 -0.9999 +vn -0.1454 0.0375 -0.9887 +vn -0.1243 0.1097 -0.9862 +vn -0.0137 0.0904 -0.9958 +vn -0.7142 0.1734 -0.6781 +vn -0.6829 0.2662 -0.6803 +vn -0.4824 0.6590 -0.5770 +vn -0.0924 0.7003 -0.7079 +vn -0.0266 0.7054 -0.7084 +vn -0.0621 -0.3481 -0.9354 +vn -0.0040 -0.0227 -0.9997 +vn 0.2087 0.1179 -0.9709 +vn 0.6919 0.3900 -0.6076 +vn 0.0150 0.0085 -0.9999 +vn 0.1991 0.1325 -0.9710 +vn 0.6578 0.4379 -0.6128 +vn 0.2481 -0.0456 -0.9677 +vn 0.2474 -0.0182 -0.9688 +vn 0.2470 -0.0710 -0.9664 +vn 0.7949 -0.1492 -0.5881 +vn 0.8030 -0.0617 -0.5928 +vn 0.1963 0.1311 -0.9717 +vn 0.6507 0.4333 -0.6236 +vn 0.0139 0.0093 -0.9999 +vn 0.2237 -0.0684 -0.9723 +vn 0.2277 -0.0336 -0.9732 +vn 0.7791 -0.1157 -0.6161 +vn 0.0161 -0.0049 -0.9999 +vn 0.0164 -0.0024 -0.9999 +vn 0.0175 0.3512 -0.9361 +vn 0.0024 0.0222 -0.9998 +vn 0.0377 0.3457 -0.9376 +vn 0.0923 0.8726 -0.4796 +vn 0.0427 0.8784 -0.4760 +vn 0.2132 0.1435 -0.9664 +vn 0.2012 0.1724 -0.9643 +vn 0.6726 0.4574 -0.5817 +vn 0.2420 0.0148 -0.9702 +vn 0.7993 0.0474 -0.5991 +vn 0.1546 0.2535 -0.9549 +vn 0.1702 0.2288 -0.9585 +vn 0.4940 0.6745 -0.5486 +vn 0.4350 0.7239 -0.5355 +vn 0.0622 0.3325 -0.9411 +vn 0.1555 0.8586 -0.4885 +vn 0.2133 -0.1047 -0.9714 +vn 0.0152 -0.0075 -0.9999 +vn 0.0123 0.0132 -0.9998 +vn 0.1859 0.2000 -0.9620 +vn 0.5582 0.6100 -0.5624 +vn -0.0676 0.3198 -0.9451 +vn -0.1733 0.8478 -0.5011 +vn 0.0221 0.0067 -0.9997 +vn 0.0232 0.0058 -0.9997 +vn 0.2479 -0.1171 -0.9617 +vn 0.2487 -0.1012 -0.9633 +vn 0.7292 -0.3865 -0.5646 +vn 0.7455 -0.3444 -0.5707 +vn -0.1473 0.2335 -0.9611 +vn -0.4372 0.7040 -0.5596 +vn 0.0180 -0.0004 -0.9998 +vn 0.2467 -0.0900 -0.9649 +vn 0.7616 -0.2962 -0.5765 +vn 0.0219 -0.3572 -0.9338 +vn 0.0559 -0.8784 -0.4747 +vn 0.0014 -0.0233 -0.9997 +vn 0.3948 0.0714 -0.9160 +vn 0.4114 0.1006 -0.9059 +vn 0.8962 0.2111 -0.3902 +vn 0.8925 0.1247 -0.4335 +vn 0.0781 0.9965 -0.0310 +vn 0.0812 0.9960 -0.0369 +vn 0.0796 0.7687 0.6346 +vn 0.0323 0.9977 -0.0590 +vn 0.0279 0.9976 -0.0629 +vn 0.1428 0.9884 -0.0518 +vn 0.1949 0.9804 -0.0303 +vn 0.1582 0.7547 0.6367 +vn -0.0299 0.9991 -0.0308 +vn -0.0308 0.9991 0.0277 +vn 0.0282 0.9992 0.0285 +vn 0.0293 0.9991 -0.0314 +vn 0.0220 0.7465 0.6650 +vn 0.1327 0.7389 0.6606 +vn 0.1764 0.9839 0.0290 +vn 0.1776 0.9836 -0.0320 +vn -0.0266 0.7053 -0.7084 +vn -0.0308 0.9846 -0.1719 +vn 0.0278 0.9847 -0.1723 +vn 0.0216 0.7157 -0.6980 +vn -0.0295 0.9873 -0.1562 +vn 0.0289 0.9874 -0.1558 +vn 0.1756 0.9725 -0.1527 +vn 0.1741 0.9699 -0.1704 +vn 0.1284 0.7087 -0.6937 +vn 0.0002 0.0016 1.0000 +vn 0.0005 0.0015 1.0000 +vn 0.0184 -0.0023 0.9998 +vn 0.0108 0.0970 0.9952 +vn 0.0004 0.0026 1.0000 +vn 0.0797 0.7687 0.6346 +vn 0.1582 0.7547 0.6366 +vn 0.0176 0.1035 0.9945 +vn 0.0229 0.1031 0.9944 +vn 0.0002 0.0025 1.0000 +vn 0.2079 0.7394 0.6404 +vn -0.0027 -0.0067 -1.0000 +vn -0.0000 -0.0010 -1.0000 +vn -0.0098 -0.0154 -0.9998 +vn -0.0110 -0.0152 -0.9998 +vn -0.0029 -0.0069 -1.0000 +vn -0.0001 -0.0010 -1.0000 +vn -0.0036 -0.0068 -1.0000 +vn -0.0002 -0.0010 -1.0000 +vn -0.0114 -0.0151 -0.9998 +vn -0.0116 -0.0147 -0.9998 +vn -0.0009 -0.0000 -1.0000 +vn -0.0007 -0.0001 -1.0000 +vn -0.0118 -0.0146 -0.9998 +vn -0.0126 -0.0142 -0.9998 +vn 0.0026 0.0891 -0.9960 +vn 0.0002 0.0020 -1.0000 +vn 0.0215 0.7158 -0.6980 +vn 0.1285 0.7087 -0.6937 +vn 0.0156 0.0865 -0.9961 +vn 0.0275 0.0823 -0.9962 +vn 0.0006 0.0019 -1.0000 +vn 0.2273 0.6793 -0.6978 +vn 0.0001 0.0009 -1.0000 +vn 0.0016 0.0060 -1.0000 +vn 0.0056 0.0145 -0.9999 +vn 0.0015 0.0060 -1.0000 +vn 0.0056 0.0144 -0.9999 +vn 0.0055 0.0143 -0.9999 +vn 0.0074 0.0144 -0.9999 +vn 0.0077 0.0141 -0.9999 +vn 0.0076 0.0141 -0.9999 +vn -0.0006 0.0038 -1.0000 +vn -0.0007 0.0039 -1.0000 +vn -0.0010 0.0039 -1.0000 +vn -0.0289 -0.0060 -0.9996 +vn -0.0284 -0.0029 -0.9996 +vn -0.9221 -0.2225 -0.3166 +vn -0.8833 -0.2863 -0.3714 +vn -0.3992 -0.0793 -0.9134 +vn -0.4596 -0.1214 -0.8798 +vn -0.8833 -0.2862 -0.3714 +vn -0.8745 -0.2872 -0.3908 +vn -0.0649 0.1024 -0.9926 +vn -0.4597 -0.1214 -0.8797 +vn 0.3164 0.9482 0.0287 +vn 0.3176 0.9477 -0.0321 +vn 0.2356 0.7071 0.6667 +vn 0.4116 0.9109 0.0279 +vn 0.4132 0.9101 -0.0318 +vn 0.3125 0.9355 -0.1650 +vn 0.2273 0.6792 -0.6978 +vn 0.3142 0.9380 -0.1466 +vn 0.4092 0.9016 -0.1404 +vn 0.4071 0.8995 -0.1588 +vn -0.0439 0.5573 -0.8292 +vn -0.1061 0.7067 -0.6995 +vn -0.0537 0.6918 -0.7201 +vn 0.0032 0.5526 -0.8334 +vn -0.0971 0.5520 -0.8281 +vn -0.0639 0.5437 -0.8369 +vn -0.0537 0.6917 -0.7201 +vn -0.1730 0.4914 -0.8536 +vn 0.2805 0.9597 -0.0181 +vn 0.2079 0.7394 0.6403 +vn 0.2331 0.9715 -0.0433 +vn 0.7852 0.0745 -0.6148 +vn 0.9904 0.0940 -0.1017 +vn 0.9955 0.0948 -0.0039 +vn 0.8335 -0.5525 0.0008 +vn 0.8995 -0.4369 0.0009 +vn 0.8990 -0.4364 0.0360 +vn 0.8332 -0.5520 0.0347 +vn 0.7465 -0.3616 0.5585 +vn -0.1925 0.6902 -0.6975 +vn -0.1179 0.5498 -0.8269 +vn -0.1541 0.5393 -0.8279 +vn 0.9977 0.0595 0.0311 +vn 0.9982 0.0596 0.0007 +vn 0.8290 0.0491 0.5571 +vn 0.9086 0.4172 -0.0186 +vn 0.5310 0.8468 -0.0307 +vn 0.5255 0.8505 0.0243 +vn 0.9149 0.4009 0.0481 +vn 0.7940 0.3303 0.5104 +vn -0.7568 -0.6536 0.0007 +vn -0.7567 -0.6532 0.0279 +vn -0.8274 -0.5609 0.0289 +vn -0.8277 -0.5612 0.0007 +vn -0.6476 -0.5576 0.5193 +vn -0.7049 -0.4768 0.5252 +vn -0.7549 -0.3859 0.5304 +vn -0.8897 -0.4556 0.0299 +vn -0.8900 -0.4559 0.0007 +vn 0.8362 0.5475 0.0319 +vn 0.8313 0.5509 0.0738 +vn 0.6774 0.4500 0.5819 +vn 0.5164 0.8560 0.0238 +vn 0.5167 0.8562 0.0006 +vn 0.3815 0.7830 0.4913 +vn 0.4400 0.8977 0.0225 +vn 0.4402 0.8979 0.0005 +vn -0.9380 -0.3452 0.0305 +vn -0.9384 -0.3455 0.0007 +vn -0.7934 -0.2916 0.5344 +vn -0.8256 -0.1809 0.5344 +vn -0.9763 -0.2142 0.0310 +vn -0.9767 -0.2144 0.0007 +vn 0.3559 0.9343 0.0212 +vn 0.3561 0.9344 0.0005 +vn 0.3103 0.8202 0.4806 +vn 0.0057 -1.0000 0.0004 +vn 0.0057 -0.9998 0.0183 +vn -0.0490 -0.9986 0.0182 +vn -0.0489 -0.9988 0.0004 +vn -0.0443 -0.8954 0.4431 +vn -0.0959 -0.8899 0.4460 +vn -0.1062 -0.9942 0.0185 +vn -0.1062 -0.9943 0.0005 +vn 0.8272 0.5612 0.0290 +vn 0.8276 0.5612 0.0007 +vn 0.6949 0.4728 0.5418 +vn -0.2676 -0.9635 0.0005 +vn -0.2677 -0.9633 0.0202 +vn -0.3562 -0.9342 0.0212 +vn -0.3561 -0.9344 0.0005 +vn -0.3158 -0.8237 0.4710 +vn -0.3873 -0.7861 0.4817 +vn -0.4403 -0.8976 0.0225 +vn -0.4403 -0.8979 0.0005 +vn 0.9302 -0.3660 0.0286 +vn 0.9306 -0.3660 0.0007 +vn 0.7855 -0.3098 0.5357 +vn -0.1801 -0.9835 0.0192 +vn -0.1800 -0.9837 0.0005 +vn -0.1621 -0.8773 0.4517 +vn 0.8887 -0.4585 0.0006 +vn 0.8884 -0.4585 0.0244 +vn 0.8485 -0.5286 0.0258 +vn 0.8488 -0.5288 0.0006 +vn 0.7685 -0.3992 0.5001 +vn 0.7284 -0.4543 0.5128 +vn 0.4371 0.5748 -0.6918 +vn 0.5232 0.8393 -0.1480 +vn 0.9184 0.3848 -0.0915 +vn 0.5267 0.8400 -0.1302 +vn -0.5926 -0.8055 0.0006 +vn -0.5926 -0.8051 0.0251 +vn -0.6767 -0.7358 0.0266 +vn -0.6767 -0.7362 0.0006 +vn -0.5140 -0.6958 0.5016 +vn -0.7567 -0.6532 0.0278 +vn 0.9295 0.3578 0.0896 +vn 0.9302 0.3654 0.0339 +vn 0.9279 0.3713 0.0336 +vn 0.9288 0.3619 0.0797 +vn 0.9155 0.3648 0.1699 +vn -0.9971 0.0759 0.0007 +vn -0.9967 0.0757 0.0306 +vn -0.9826 0.1833 0.0300 +vn -0.9830 0.1835 0.0007 +vn -0.8424 0.0635 0.5352 +vn -0.8323 0.1546 0.5324 +vn 0.9599 -0.2794 0.0243 +vn 0.9596 -0.2812 0.0043 +vn 0.8398 -0.2502 0.4818 +vn -0.6995 0.3407 -0.6281 +vn -0.8949 0.4352 -0.0992 +vn -0.8995 0.4369 -0.0038 +vn -0.8780 0.4779 0.0272 +vn -0.8783 0.4781 0.0007 +vn -0.8539 0.5198 0.0266 +vn -0.8542 0.5200 0.0006 +vn 0.8866 0.2468 -0.3911 +vn 0.9634 0.2680 -0.0062 +vn 0.9679 0.2513 -0.0058 +vn 0.8975 0.2314 -0.3753 +vn 0.9608 0.2738 0.0441 +vn 0.9659 0.2565 0.0351 +vn -0.8995 0.4369 0.0009 +vn -0.8988 0.4368 0.0361 +vn -0.8335 0.5525 0.0008 +vn -0.8329 0.5524 0.0347 +vn -0.6831 0.4547 0.5716 +vn 0.9794 -0.2019 0.0022 +vn 0.9895 -0.1447 -0.0000 +vn 0.9854 -0.1543 0.0712 +vn 0.9769 -0.2009 0.0734 +vn 0.9149 0.4008 0.0481 +vn 0.7706 -0.1091 0.6279 +vn -0.9767 -0.2132 -0.0255 +vn -0.9795 -0.1975 -0.0388 +vn -0.9482 -0.3140 -0.0486 +vn -0.9522 -0.2985 -0.0644 +vn 0.8763 -0.4756 -0.0771 +vn 0.7293 -0.3865 -0.5646 +vn 0.8783 -0.4780 -0.0030 +vn 0.9033 -0.4290 -0.0030 +vn 0.9010 -0.4268 -0.0777 +vn -0.4491 0.8935 0.0006 +vn -0.3658 0.9307 0.0006 +vn -0.3655 0.9305 0.0232 +vn -0.4487 0.8933 0.0249 +vn -0.2859 0.9583 0.0005 +vn -0.2856 0.9581 0.0217 +vn -0.3155 0.8091 0.4958 +vn -0.3839 0.7697 0.5101 +vn -0.8509 0.5248 0.0258 +vn -0.8511 0.5250 0.0006 +vn -0.7296 0.4494 0.5155 +vn 0.5881 -0.8088 0.0007 +vn 0.6410 -0.7675 0.0007 +vn 0.6409 -0.7670 0.0299 +vn 0.5881 -0.8083 0.0283 +vn 0.7031 -0.7111 0.0008 +vn 0.7030 -0.7105 0.0315 +vn 0.5925 -0.5972 0.5406 +vn 0.5438 -0.6488 0.5323 +vn 0.5018 -0.6879 0.5244 +vn 0.4491 -0.8935 0.0006 +vn 0.5294 -0.8484 0.0006 +vn 0.5294 -0.8479 0.0268 +vn 0.4493 -0.8931 0.0250 +vn 0.4561 -0.7276 0.5125 +vn 0.3910 -0.7730 0.4995 +vn -0.9671 -0.2441 -0.0713 +vn -0.9420 -0.3351 -0.0172 +vn -0.9653 -0.2550 -0.0560 +vn -0.9440 -0.3264 0.0489 +vn 0.6393 -0.7646 -0.0819 +vn 0.5713 -0.5764 -0.5842 +vn 0.7009 -0.7080 -0.0864 +vn 0.6410 -0.7675 -0.0031 +vn 0.9278 -0.3647 -0.0790 +vn 0.7615 -0.2962 -0.5766 +vn 0.9306 -0.3660 -0.0030 +vn -0.9647 0.2563 -0.0605 +vn -0.9656 0.2600 -0.0021 +vn 0.0630 -0.9967 -0.0517 +vn 0.0629 -0.9980 -0.0019 +vn 0.9946 0.0592 -0.0855 +vn 0.7994 0.0474 -0.5989 +vn 0.9982 0.0596 -0.0032 +vn 0.9955 0.0948 0.0009 +vn 0.9948 0.0946 0.0372 +vn 0.9776 0.2104 0.0009 +vn 0.9770 0.2102 0.0367 +vn 0.8217 0.0776 0.5645 +vn 0.8248 0.5598 -0.0799 +vn 0.8276 0.5613 -0.0030 +vn 0.7543 0.6520 -0.0767 +vn -0.9274 0.3648 -0.0827 +vn -0.7538 0.2984 -0.5854 +vn -0.9306 0.3660 -0.0030 +vn 0.1794 0.9823 -0.0531 +vn 0.1554 0.8584 -0.4888 +vn 0.1800 0.9837 -0.0020 +vn -0.9946 -0.0595 -0.0848 +vn -0.8149 -0.0489 -0.5776 +vn -0.9982 -0.0596 -0.0032 +vn -0.9977 -0.0596 0.0310 +vn -0.9982 -0.0596 0.0008 +vn -0.8437 -0.0508 0.5345 +vn -0.7549 -0.6514 -0.0764 +vn -0.8253 -0.5591 -0.0794 +vn -0.6827 -0.4622 -0.5659 +vn -0.8277 -0.5612 -0.0030 +vn -0.3085 0.7903 -0.5294 +vn -0.3645 0.9290 -0.0642 +vn -0.3658 0.9307 -0.0024 +vn -0.5160 -0.8541 -0.0653 +vn -0.5167 -0.8561 -0.0025 +vn -0.5167 -0.8558 0.0238 +vn -0.5167 -0.8562 0.0006 +vn -0.4511 -0.7444 0.4924 +vn -0.5881 0.8088 0.0007 +vn -0.5294 0.8484 0.0006 +vn -0.5289 0.8482 0.0267 +vn -0.5877 0.8086 0.0283 +vn -0.4496 0.7248 0.5221 +vn -0.4972 0.6863 0.5308 +vn -0.2024 0.9793 0.0005 +vn -0.2022 0.9791 0.0204 +vn -0.1764 0.8643 0.4711 +vn 0.0629 -0.9980 0.0005 +vn 0.0630 -0.9978 0.0187 +vn 0.1258 -0.9921 0.0005 +vn 0.1259 -0.9919 0.0193 +vn 0.1133 -0.8841 0.4534 +vn -0.7679 0.6406 0.0008 +vn -0.7673 0.6404 0.0332 +vn -0.7031 0.7111 0.0008 +vn -0.7025 0.7109 0.0315 +vn -0.6410 0.7676 0.0007 +vn -0.6405 0.7674 0.0299 +vn -0.5373 0.6463 0.5419 +vn -0.5373 0.6462 0.5419 +vn 0.2859 -0.9583 0.0005 +vn 0.3658 -0.9307 0.0006 +vn 0.3660 -0.9303 0.0233 +vn 0.2860 -0.9580 0.0218 +vn 0.3212 -0.8120 0.4874 +vn 0.2534 -0.8429 0.4748 +vn 0.2024 -0.9793 0.0005 +vn 0.2026 -0.9791 0.0204 +vn 0.1812 -0.8678 0.4626 +vn -0.8707 -0.4917 0.0015 +vn -0.8704 -0.4910 0.0371 +vn -0.7136 -0.4027 0.5732 +vn 0.7679 -0.6405 0.0008 +vn 0.7677 -0.6400 0.0331 +vn 0.6431 -0.5347 0.5482 +vn -0.0924 0.7002 -0.7079 +vn -0.0554 0.9836 -0.1715 +vn -0.4824 0.6591 -0.5770 +vn -0.5607 0.8103 -0.1704 +vn -0.5449 0.8278 -0.1334 +vn -0.0542 0.9862 -0.1562 +vn 0.9520 0.3060 0.0009 +vn 0.9514 0.3057 0.0362 +vn -0.9818 0.1900 0.0030 +vn -0.9938 0.1116 -0.0011 +vn -0.9891 0.1132 0.0947 +vn -0.9750 0.1892 0.1167 +vn -0.9985 -0.0549 -0.0039 +vn -0.9966 -0.0495 0.0658 +vn -0.7933 -0.0378 0.6076 +vn -0.7494 0.0867 0.6565 +vn -0.7106 0.1394 0.6896 +vn -0.0551 0.9980 -0.0305 +vn -0.0534 0.9982 0.0255 +vn -0.5735 0.8190 -0.0200 +vn -0.5956 0.8002 0.0698 +vn -0.4955 0.6705 0.5522 +vn 0.4140 0.9103 0.0063 +vn 0.4071 0.9134 -0.0064 +vn 0.3736 0.7237 0.5803 +vn 0.8162 0.5216 0.2487 +vn 0.8644 0.4993 0.0597 +vn 0.4073 0.9133 -0.0063 +vn 0.4141 0.9102 0.0063 +vn 0.8643 0.4994 0.0597 +vn 0.8654 0.4954 0.0759 +vn 0.4252 0.8306 0.3597 +vn 0.5339 0.7696 0.3503 +vn 0.5398 0.8418 -0.0062 +vn 0.4234 0.9058 -0.0121 +vn 0.8781 0.3985 0.2648 +vn 0.9060 0.4230 0.0153 +vn 0.0399 0.9746 -0.2202 +vn -0.0190 0.9758 -0.2179 +vn 0.1840 0.9573 -0.2232 +vn 0.1795 0.7911 -0.5847 +vn 0.0593 0.8107 -0.5824 +vn 0.0104 0.8136 -0.5814 +vn -0.6932 0.7095 -0.1268 +vn -0.9920 -0.0005 -0.1265 +vn -0.0455 0.9974 -0.0551 +vn -0.1030 0.9903 0.0933 +vn -0.7388 0.6739 0.0056 +vn -0.7389 0.6738 0.0056 +vn -0.9971 -0.0022 -0.0757 +vn -0.0436 0.5235 -0.8509 +vn -0.0381 0.5332 -0.8451 +vn 0.0267 0.5277 -0.8490 +vn 0.1023 0.5703 -0.8151 +vn 0.0247 0.5670 -0.8233 +vn 0.0357 0.5771 -0.8159 +vn 0.9165 0.4000 -0.0000 +vn 0.9520 0.3060 -0.0000 +vn 0.9776 0.2104 -0.0000 +vn -0.8974 -0.4411 -0.0085 +vn -0.9659 -0.2578 -0.0215 +vn -0.9654 -0.2608 -0.0025 +vn -0.8971 -0.4419 0.0001 +vn -0.9984 -0.0423 -0.0364 +vn -0.9988 -0.0473 -0.0113 +vn 0.9982 0.0596 -0.0000 +vn 0.9971 -0.0759 -0.0000 +vn 0.9767 0.2144 0.0000 +vn 0.9384 0.3455 0.0000 +vn 0.8900 0.4559 0.0000 +vn 0.9913 -0.1313 0.0062 +vn 0.9913 -0.1311 -0.0079 +vn 0.9792 -0.2028 -0.0007 +vn 0.9987 0.0487 -0.0120 +vn 0.9982 0.0513 -0.0307 +vn 0.9918 -0.1267 -0.0192 +vn 0.9785 -0.2060 0.0032 +vn -0.0057 1.0000 0.0000 +vn -0.0629 0.9980 0.0000 +vn -0.1258 0.9921 0.0000 +vn 0.4402 0.8979 -0.0000 +vn 0.3561 0.9344 -0.0000 +vn 0.2676 0.9635 0.0000 +vn -0.9971 0.0759 -0.0000 +vn -0.9830 0.1835 -0.0000 +vn -0.9594 0.2820 -0.0000 +vn 0.1800 0.9837 -0.0000 +vn 0.1062 0.9943 0.0000 +vn -0.1062 -0.9943 -0.0000 +vn -0.1800 -0.9837 0.0000 +vn -0.2676 -0.9635 0.0000 +vn -0.5167 -0.8562 -0.0000 +vn -0.4402 -0.8979 0.0000 +vn -0.5926 -0.8055 0.0000 +vn -0.6767 -0.7362 -0.0000 +vn -0.7568 -0.6536 -0.0000 +vn 0.8488 -0.5288 -0.0000 +vn 0.8884 -0.4591 0.0004 +vn 0.8539 -0.5204 0.0000 +vn 0.8882 -0.4595 0.0002 +vn 0.8783 -0.4781 0.0000 +vn 0.9033 -0.4291 -0.0000 +vn 0.2870 0.6061 -0.7418 +vn 0.1452 0.5735 -0.8063 +vn 0.7335 0.5184 -0.4396 +vn 0.6634 0.5499 -0.5075 +vn 0.9534 0.2848 0.0995 +vn 0.9347 0.3403 0.1021 +vn 0.7832 0.6174 0.0735 +vn 0.9325 0.3473 0.0992 +vn 0.9403 0.3284 0.0896 +vn 0.9158 0.3897 0.0976 +vn 0.7339 0.6698 0.1133 +vn 0.9794 0.1981 0.0388 +vn 0.9507 0.3029 0.0660 +vn 0.9995 -0.0267 0.0159 +vn 0.9990 -0.0429 0.0135 +vn 0.9847 0.1710 0.0330 +vn 0.9610 0.2705 0.0570 +vn -0.9033 0.4291 0.0000 +vn -0.8783 0.4781 0.0000 +vn -0.8542 0.5200 -0.0000 +vn -0.6410 0.7675 0.0000 +vn -0.5881 0.8088 -0.0000 +vn -0.7031 0.7111 0.0000 +vn -0.6410 0.7676 -0.0000 +vn -0.7679 0.6406 -0.0000 +vn -0.8335 0.5525 0.0000 +vn 0.9370 0.3380 0.0879 +vn 0.9489 0.3059 0.0773 +vn -0.9568 0.2908 0.0000 +vn -0.9892 0.1468 0.0000 +vn -0.9997 0.0259 -0.0000 +vn 0.5283 0.8218 -0.2136 +vn 0.4133 0.8833 -0.2213 +vn 0.8915 0.4290 -0.1457 +vn 0.8390 0.3558 -0.4116 +vn 0.4748 0.6769 -0.5625 +vn 0.3721 0.7250 -0.5796 +vn -0.8276 -0.5612 0.0000 +vn -0.8900 -0.4559 0.0000 +vn -0.8277 -0.5612 0.0000 +vn -0.9486 -0.2988 -0.1046 +vn -0.9333 -0.3464 -0.0950 +vn -0.9574 -0.2718 -0.0978 +vn -0.9441 -0.3166 -0.0918 +vn -0.9681 0.2505 -0.0037 +vn -0.8976 0.4408 -0.0002 +vn -0.9998 0.0122 -0.0159 +vn -0.9995 0.0290 -0.0134 +vn -0.9667 0.2560 -0.0032 +vn -0.8974 0.4413 -0.0003 +vn 0.6410 -0.7676 0.0000 +vn 0.7031 -0.7111 0.0000 +vn 0.5881 -0.8088 0.0000 +vn 0.5294 -0.8484 -0.0000 +vn 0.4491 -0.8935 -0.0000 +vn -0.9776 -0.2104 -0.0000 +vn -0.9520 -0.3060 -0.0000 +vn -0.9165 -0.4000 0.0000 +vn -0.9793 -0.2015 -0.0196 +vn -0.9701 -0.2398 -0.0375 +vn -0.9720 -0.2284 -0.0546 +vn -0.9809 -0.1928 -0.0279 +vn -0.9650 -0.2586 -0.0445 +vn -0.9644 -0.2590 -0.0540 +vn -0.9750 -0.2134 -0.0623 +vn 0.3658 -0.9307 -0.0000 +vn 0.2859 -0.9583 -0.0000 +vn 0.9830 -0.1835 0.0000 +vn 0.9594 -0.2820 0.0000 +vn -0.8511 0.5250 0.0000 +vn 0.2024 -0.9793 -0.0000 +vn 0.1258 -0.9921 -0.0000 +vn -0.9902 0.1355 -0.0338 +vn -0.9905 0.1353 -0.0244 +vn -0.9767 0.2136 -0.0220 +vn -0.9744 0.2226 -0.0326 +vn 0.6767 0.7362 -0.0000 +vn 0.7568 0.6536 0.0000 +vn 0.5926 0.8055 -0.0000 +vn -0.9384 -0.3455 0.0000 +vn -0.9768 -0.2144 0.0000 +vn -0.9767 -0.2144 0.0000 +vn -0.3561 -0.9344 0.0000 +vn -0.5294 0.8484 0.0000 +vn -0.4491 0.8935 0.0000 +vn 0.9892 -0.1468 0.0000 +vn 0.9997 -0.0259 -0.0000 +vn 0.9568 -0.2908 -0.0000 +vn -0.2024 0.9793 0.0000 +vn -0.2859 0.9583 0.0000 +vn 0.0629 -0.9980 -0.0000 +vn 0.0057 -1.0000 0.0000 +vn -0.9166 -0.3999 -0.0001 +vn -0.9166 -0.3998 0.0001 +vn -0.8708 -0.4916 -0.0003 +vn -0.8282 -0.5605 0.0026 +vn -0.8280 -0.5608 0.0008 +vn -0.8710 -0.4913 0.0007 +vn 0.7679 -0.6406 -0.0000 +vn 0.8335 -0.5525 -0.0000 +vn 0.8862 0.4629 -0.0194 +vn 0.9563 0.2923 -0.0028 +vn 0.9667 0.2557 0.0060 +vn 0.8884 0.4581 0.0288 +vn 0.9959 0.0904 0.0036 +vn 0.9962 0.0846 -0.0210 +vn 0.9755 0.2190 -0.0216 +vn 0.9680 0.2491 -0.0286 +vn 0.9665 0.2274 0.1189 +vn 0.8893 0.4261 0.1660 +vn 0.9168 0.3994 0.0002 +vn 0.9170 0.3989 0.0001 +vn -0.9508 0.3097 -0.0002 +vn -0.9457 0.3235 -0.0325 +vn -0.9816 0.1908 0.0011 +vn -0.5735 0.8190 -0.0199 +vn -0.5406 0.8259 -0.1601 +vn -0.4884 0.7430 -0.4576 +vn -0.9124 0.3710 -0.1729 +vn -0.9813 0.1926 -0.0002 +vn 0.0722 0.5239 -0.8487 +vn -0.0204 0.4961 -0.8680 +vn 0.0484 0.5517 -0.8327 +vn 0.1528 0.5683 -0.8086 +vn 0.2948 0.9556 0.0031 +vn -0.0511 0.9979 -0.0407 +vn 0.8655 0.4952 0.0759 +vn 0.7338 0.6699 0.1133 +vn 0.2536 0.9611 0.1091 +vn -0.1004 0.9910 0.0886 +vn -0.9656 -0.2597 0.0113 +vn -0.9650 -0.2558 0.0576 +vn -0.3658 0.9307 0.0000 +vn 0.9698 0.2438 0.0068 +vn 0.9884 0.1518 0.0030 +vn 0.9887 0.1499 0.0051 +vn 0.9706 0.2403 0.0144 +vn 0.9985 -0.0547 0.0006 +vn 0.9985 -0.0551 0.0008 +vn -0.9771 -0.2027 -0.0644 +vn -0.9307 -0.1896 -0.3128 +vn 0.6053 0.6119 -0.5091 +vn 0.6039 0.6723 -0.4282 +vn 0.9283 0.3651 -0.0701 +vn 0.8174 0.3494 -0.4581 +vn 0.6057 0.5965 -0.5267 +vn 0.9256 0.3705 -0.0770 +vn 0.9545 0.2929 0.0566 +vn -0.4977 -0.1035 -0.8612 +vn -0.4973 -0.1035 -0.8614 +vn -0.0971 0.5521 -0.8281 +vn -0.0251 0.1315 -0.9910 +vn -0.0214 0.1275 -0.9916 +vn -0.0639 0.5437 -0.8368 +vn -0.0332 0.1255 -0.9915 +vn -0.1541 0.5394 -0.8278 +vn -0.0209 -0.0079 0.9998 +vn 0.0235 0.0094 0.9997 +vn 0.0221 0.0057 -0.9997 +vn 0.4160 0.1079 -0.9029 +vn 0.4161 0.1079 -0.9029 +vn 0.4079 0.1167 -0.9056 +vn 0.5715 0.2284 0.7882 +vn 0.5714 0.2284 0.7882 +vn -0.9303 -0.3619 -0.0608 +vn -0.9332 -0.3497 -0.0822 +vn -0.8572 -0.3351 0.3910 +vn -0.8899 -0.3029 0.3411 +vn -0.3486 -0.1351 0.9275 +vn -0.8572 -0.3351 0.3909 +vn -0.9938 0.1105 0.0084 +vn -0.9982 -0.0574 0.0178 +vn -0.9944 0.1036 0.0228 +vn -0.9979 -0.0585 0.0293 +vn 0.0489 0.9988 0.0000 +vn -0.9499 0.2928 0.1093 +vn -0.5956 0.8003 0.0698 +vn 0.9890 -0.1327 0.0648 +vn 0.8100 -0.1072 0.5765 +vn 0.0181 -0.0027 -0.9998 +vn 0.1328 0.7389 0.6606 +vn 0.0130 0.0722 0.9973 +vn 0.0229 0.0688 0.9974 +vn 0.0023 0.0739 0.9973 +vn 0.0219 0.7465 0.6650 +vn -0.1706 0.0240 -0.9851 +vn -0.7489 0.1035 -0.6546 +vn 0.2477 -0.0361 -0.9682 +vn 0.8140 -0.1283 -0.5666 +vn -0.1698 0.0196 0.9853 +vn -0.7494 0.0867 0.6564 +vn 0.2499 -0.0303 0.9678 +vn 0.8139 -0.1283 -0.5666 +vn 0.9865 -0.1599 -0.0347 +vn 0.9870 -0.1592 0.0203 +vn -0.9290 0.3476 -0.1274 +vn -0.5607 0.8103 -0.1703 +vn -0.9303 0.3614 -0.0619 +vn -0.5449 0.8279 -0.1334 +vn 0.9861 -0.1602 0.0452 +vn 0.9856 -0.1660 0.0319 +vn 0.9741 -0.2252 0.0205 +vn 0.9710 -0.2367 0.0336 +vn -0.9385 0.3443 0.0253 +vn -0.9327 0.3585 -0.0407 +vn -0.5039 0.8222 0.2647 +vn -0.5318 0.8460 -0.0385 +vn 0.7335 0.5184 -0.4395 +vn 0.9452 0.3222 -0.0525 +vn 0.9348 0.3490 -0.0660 +vn 0.6634 0.5499 -0.5074 +vn 0.9600 0.2798 0.0122 +vn 0.9593 0.2798 0.0373 +vn -0.9991 0.0417 -0.0008 +vn -0.9926 -0.1209 -0.0063 +vn -0.9930 -0.1175 -0.0085 +vn -0.9991 0.0423 -0.0012 +vn 0.8740 0.4859 0.0027 +vn 0.8409 0.5412 0.0091 +vn 0.8748 0.4846 -0.0014 +vn 0.8418 0.5397 -0.0043 +vn -0.0094 0.9389 0.3441 +vn -0.0431 0.9985 -0.0325 +vn -0.5317 0.8460 -0.0385 +vn 0.0149 0.9368 0.3495 +vn -0.0183 0.9993 -0.0311 +vn -0.9655 -0.2567 0.0450 +vn -0.8862 -0.4566 0.0789 +vn -0.9812 -0.1922 0.0197 +vn -0.9540 -0.2996 0.0142 +vn -0.9334 -0.3537 0.0600 +vn -0.8675 -0.4891 0.0901 +vn 0.8337 0.5520 0.0120 +vn 0.8863 0.4632 0.0027 +vn 0.8255 0.5644 -0.0063 +vn 0.7799 0.6259 -0.0004 +vn 0.7873 0.6133 -0.0644 +vn 0.8699 0.4778 -0.1223 +vn 0.6410 -0.7675 0.0000 +vn -0.8328 -0.5535 -0.0013 +vn -0.8365 -0.5480 -0.0040 +vn -0.8367 -0.5477 -0.0000 +vn -0.8330 -0.5533 0.0000 +vn 0.9955 0.0948 -0.0000 +vn 0.8995 -0.4369 -0.0000 +vn -0.9955 -0.0948 0.0000 +vn -0.8972 0.4417 0.0000 +vn -0.0489 -0.9988 -0.0000 +vn 0.5167 0.8562 -0.0000 +vn 0.9306 -0.3660 -0.0000 +vn -0.9845 -0.1709 -0.0386 +vn -0.9606 -0.2703 -0.0649 +vn -0.9696 -0.2381 -0.0565 +vn -0.9891 -0.1436 -0.0328 +vn -0.9982 -0.0596 0.0000 +vn 0.9903 -0.1373 -0.0187 +vn 0.8915 0.4290 -0.1456 +vn 0.9890 -0.1127 -0.0959 +vn -0.8995 0.4369 0.0000 +vn -0.9420 -0.3249 -0.0841 +vn -0.9531 -0.2926 -0.0769 +vn -0.9656 0.2601 0.0000 +vn 0.8879 -0.4600 0.0000 +vn -0.9672 -0.2471 -0.0584 +vn -0.9569 -0.2903 0.0021 +vn -0.9156 -0.0100 -0.4019 +vn -0.9528 -0.1136 -0.2817 +vn -0.0437 0.9756 -0.2151 +vn -0.0120 0.8176 -0.5757 +vn -0.4883 0.7430 -0.4577 +vn -0.9306 0.3660 0.0000 +vn 0.9582 -0.2862 0.0037 +vn 0.9566 -0.2913 0.0031 +vn 0.9555 -0.2951 0.0000 +vn 0.9632 0.2684 0.0123 +vn 0.9639 0.2646 0.0301 +vn -0.4282 0.4121 -0.8043 +vn -0.4950 0.3226 -0.8068 +vn -0.4283 0.4121 -0.8042 +vn -0.4951 0.3224 -0.8068 +vn 0.8277 0.5612 -0.0000 +vn 0.8325 0.5540 -0.0015 +vn 0.8711 0.4910 -0.0002 +vn 0.8711 0.4911 0.0000 +vn 0.8323 0.5543 -0.0000 +vn 0.9990 0.0258 0.0353 +vn 0.9647 0.2628 0.0171 +vn 0.9646 0.2635 0.0028 +vn 0.9995 0.0291 0.0126 +vn 0.8902 0.4556 0.0011 +vn 0.8903 0.4554 0.0002 +vn 0.9871 -0.1567 0.0317 +vn 0.9871 -0.1579 0.0256 +vn -0.8711 -0.4911 -0.0001 +vn -0.8711 -0.4911 -0.0000 +vn 0.8322 0.5545 -0.0029 +vn 0.8321 0.5546 -0.0000 +vn 0.0008 0.9952 0.0976 +vn 0.0814 0.9911 0.1056 +vn 0.1349 0.9905 -0.0278 +vn 0.0532 0.9980 -0.0345 +vn -0.1185 0.9891 0.0874 +vn -0.0602 0.9972 -0.0446 +vn 0.2078 0.9106 0.3572 +vn 0.3368 0.8697 0.3607 +vn 0.3283 0.9444 -0.0169 +vn 0.1890 0.9817 -0.0228 +vn 0.0710 0.9333 0.3521 +vn 0.0413 0.9987 -0.0284 +vn 0.9845 -0.1695 0.0454 +vn 0.9775 -0.2108 0.0079 +vn 0.8793 0.2710 0.3916 +vn 0.9649 0.2330 -0.1214 +vn 0.9805 -0.1950 0.0234 +vn 0.9815 -0.1914 -0.0052 +vn 0.9887 -0.0755 -0.1292 +vn 0.9777 -0.2101 0.0069 +vn 0.8241 0.2829 -0.4908 +vn -0.9933 0.1110 -0.0335 +vn -0.9801 0.1983 -0.0111 +vn -0.9972 -0.0603 -0.0447 +vn -0.9959 -0.0890 -0.0151 +vn -0.9978 0.0658 0.0028 +vn -0.9851 0.1719 0.0079 +vn -0.9967 0.0758 0.0285 +vn -0.9816 0.1911 0.0011 +vn -0.9962 -0.0856 0.0150 +vn 0.9485 0.3083 -0.0727 +vn 0.9629 0.2672 -0.0368 +vn 0.7830 0.5460 -0.2979 +vn 0.8057 0.5847 0.0949 +vn 0.9414 0.3370 -0.0106 +vn 0.9640 0.2617 -0.0476 +vn 0.9303 0.3639 0.0460 +vn 0.9564 0.2909 0.0255 +vn 0.7804 0.6007 0.1735 +vn -0.9701 -0.2424 -0.0136 +vn -0.9679 -0.2507 -0.0171 +vn -0.9786 -0.2057 -0.0072 +vn -0.9786 -0.2058 -0.0035 +vn -0.9702 -0.2422 -0.0057 +vn -0.9690 -0.2471 -0.0038 +vn -0.9645 -0.2607 -0.0426 +vn -0.9595 -0.2768 -0.0517 +vn -0.9762 -0.2147 -0.0294 +vn 0.7335 0.5185 -0.4395 +vn 0.2869 0.6062 -0.7418 +vn 0.4006 0.7996 -0.4474 +vn 0.0931 0.8621 -0.4980 +vn 0.4007 0.7995 -0.4474 +vn 0.0931 0.8622 -0.4980 +vn 0.0649 0.9654 0.2525 +vn 0.4055 0.8911 0.2035 +vn 0.8056 0.5848 0.0949 +vn 0.3482 0.8642 0.3632 +vn 0.7805 0.6006 0.1735 +vn -0.0406 0.9050 0.4234 +vn 0.0384 0.7828 0.6211 +vn 0.0597 0.7777 0.6258 +vn -0.5244 0.7119 0.4670 +vn -0.5164 0.8320 -0.2028 +vn 0.0815 0.9963 -0.0259 +vn 0.1090 0.9937 -0.0255 +vn 0.0345 0.6876 -0.7253 +vn 0.0538 0.6830 -0.7284 +vn -0.4094 0.6726 -0.6165 +vn -0.4884 0.7430 -0.4577 +vn -0.9467 0.3123 0.0787 +vn -0.5244 0.7120 0.4670 +vn -0.9548 0.2972 0.0057 +vn -0.5163 0.8320 -0.2028 +vn -0.9548 0.2971 0.0058 +vn -0.8553 0.4500 -0.2568 +vn -0.4093 0.6726 -0.6165 +vn 0.9166 0.3999 -0.0000 +vn 0.9167 0.3996 -0.0001 +vn 0.9169 0.3992 -0.0002 +vn -0.9651 -0.2591 -0.0377 +vn -0.8975 -0.4401 -0.0269 +vn -0.8964 -0.4407 -0.0475 +vn -0.9642 -0.2626 -0.0360 +vn -0.8088 -0.5871 0.0336 +vn -0.8242 -0.5651 0.0372 +vn -0.8191 -0.5736 0.0091 +vn -0.7969 -0.6041 -0.0004 +vn -0.8709 -0.4915 -0.0018 +vn -0.8318 -0.5550 -0.0081 +vn -0.8705 -0.4922 -0.0022 +vn -0.8295 -0.5583 -0.0130 +vn -0.8704 -0.4923 0.0001 +vn -0.8277 -0.5612 -0.0053 +vn -0.9165 -0.4001 -0.0000 +vn -0.9924 -0.1228 -0.0023 +vn -0.9991 0.0414 -0.0001 +vn -0.9992 0.0410 -0.0012 +vn -0.9923 -0.1235 -0.0026 +vn -0.9917 -0.1277 -0.0168 +vn -0.9992 0.0384 -0.0071 +vn -0.9656 0.2601 -0.0001 +vn -0.9658 0.2591 -0.0018 +vn 0.8880 -0.4598 0.0001 +vn -0.9787 -0.1998 -0.0466 +vn -0.9497 0.1286 -0.2857 +vn -0.9827 -0.1819 0.0363 +vn -0.9826 0.1061 0.1526 +vn -0.9729 -0.2285 -0.0350 +vn -0.9961 0.0056 0.0881 +vn 0.4990 0.6230 0.6023 +vn 0.8794 0.2710 0.3915 +vn 0.4010 0.6729 0.6216 +vn 0.5453 0.8379 -0.0248 +vn 0.6633 0.7480 -0.0244 +vn 0.9648 0.2332 -0.1214 +vn 0.9648 0.2332 -0.1215 +vn 0.6633 0.7480 -0.0245 +vn 0.4477 0.5523 -0.7032 +vn 0.3567 0.5931 -0.7218 +vn 0.8391 0.3558 -0.4116 +vn 0.9883 0.1523 -0.0003 +vn 0.9985 -0.0544 -0.0000 +vn 0.9700 0.2429 -0.0054 +vn 0.9708 0.2398 -0.0068 +vn 0.9884 0.1518 0.0006 +vn 0.9985 -0.0543 0.0014 +vn 0.9877 0.1553 0.0161 +vn 0.9986 -0.0520 0.0072 +vn 0.9686 0.2474 0.0253 +vn 0.9555 -0.2949 0.0003 +vn 0.9558 -0.2940 0.0014 +vn 0.9649 0.2621 -0.0181 +vn 0.9668 0.2539 -0.0276 +vn 0.9615 0.2734 0.0284 +vn -0.5594 0.7273 -0.3976 +vn 0.0865 0.8882 -0.4513 +vn -0.5593 0.7274 -0.3976 +vn -0.5931 0.7406 0.3158 +vn -0.5593 0.7273 -0.3976 +vn -0.5930 0.7406 0.3159 +vn 0.0509 0.9411 0.3342 +vn 0.0508 0.9411 0.3342 +vn -0.5930 0.7407 0.3159 +vn -0.7009 0.5964 0.3913 +vn -0.0424 0.8776 0.4775 +vn -0.7008 0.5964 0.3914 +vn -0.7009 0.5964 0.3914 +vn 0.8327 0.5535 -0.0154 +vn 0.8335 0.5525 -0.0094 +vn 0.8887 0.4583 -0.0089 +vn 0.8332 0.5523 -0.0256 +vn 0.8353 0.5496 -0.0170 +vn 0.9605 0.2779 -0.0104 +vn 0.9404 0.3292 -0.0848 +vn 0.9910 -0.1307 0.0294 +vn 0.9980 0.0515 0.0378 +vn 0.9964 -0.0842 -0.0051 +vn 0.9946 -0.1011 -0.0230 +vn 0.9617 0.2737 0.0164 +vn 0.8281 0.5604 -0.0125 +vn 0.8383 0.5450 -0.0161 +vn 0.7935 0.6062 0.0532 +vn -0.8352 -0.5496 -0.0186 +vn -0.8306 -0.5558 -0.0345 +vn -0.9738 -0.2245 -0.0367 +vn -0.8958 -0.4301 -0.1121 +vn -0.8880 -0.4390 -0.1370 +vn -0.9524 -0.2879 -0.0997 +vn 0.8714 0.4905 -0.0026 +vn 0.8722 0.4891 -0.0057 +vn 0.8736 0.4866 -0.0059 +vn -0.0726 0.9014 0.4269 +vn 0.0422 0.9011 0.4315 +vn 0.0437 0.9592 0.2794 +vn 0.1736 0.9397 0.2946 +vn 0.0806 0.8594 -0.5050 +vn 0.2009 0.8509 -0.4854 +vn 0.0806 0.8593 -0.5050 +vn 0.2008 0.8509 -0.4855 +vn 0.1210 0.8885 0.4425 +vn 0.2454 0.9189 0.3088 +vn 0.2681 0.8466 -0.4598 +vn 0.1051 0.7691 0.6304 +vn 0.2183 0.7423 0.6335 +vn 0.1679 0.9855 -0.0261 +vn 0.3190 0.9474 -0.0261 +vn 0.0936 0.6730 -0.7337 +vn 0.1931 0.6489 -0.7359 +vn 0.1930 0.6489 -0.7359 +vn 0.3259 0.7056 0.6292 +vn 0.4543 0.8905 -0.0253 +vn 0.2887 0.6195 -0.7300 +vn 0.3159 0.9484 -0.0265 +vn 0.2929 0.7566 -0.5846 +vn 0.3199 0.9207 -0.2235 +vn -0.8126 -0.5814 -0.0411 +vn -0.8177 -0.5748 -0.0308 +vn -0.5876 0.8081 0.0408 +vn -0.4810 0.6233 -0.6166 +vn 0.2973 0.8375 -0.4585 +vn 0.2762 0.9600 0.0459 +vn -0.4809 0.6233 -0.6166 +vn 0.2719 0.1268 -0.9539 +vn 0.7271 0.3956 -0.5611 +vn 0.2974 0.8375 -0.4585 +vn 0.7873 0.6132 -0.0643 +vn -0.5160 -0.7685 0.3783 +vn -0.2511 -0.9668 -0.0472 +vn -0.8551 -0.4124 0.3141 +vn -0.2559 -0.1410 0.9564 +vn 0.6329 -0.5551 0.5397 +vn -0.5160 -0.7685 0.3782 +vn 0.8668 -0.4935 -0.0711 +vn -0.9458 -0.1615 -0.2817 +vn -0.9947 -0.0963 0.0353 +vn -0.7686 -0.4441 -0.4605 +vn 0.0667 -0.0744 -0.9950 +vn -0.6555 0.4673 -0.5932 +vn -0.6555 0.4673 -0.5933 +vn -0.8310 0.5538 0.0515 +vn -0.3959 -0.8215 -0.4104 +vn -0.3960 -0.8215 -0.4104 +vn 0.7375 -0.4507 -0.5030 +vn 0.7374 -0.4507 -0.5030 +vn 0.2720 0.1268 -0.9539 +vn 0.8467 -0.2149 -0.4868 +vn 0.9532 0.0937 -0.2873 +vn 0.9528 -0.2939 -0.0758 +vn 0.9987 -0.0103 -0.0507 +vn 0.3465 0.2088 0.9145 +vn -0.3771 0.7335 0.5655 +vn 0.4698 0.8164 0.3358 +vn 0.8089 0.3789 0.4495 +vn 0.4698 0.8164 0.3359 +vn 0.8766 -0.2792 0.3919 +vn 0.9618 -0.0002 0.2737 +vn -0.5778 0.5521 -0.6012 +vn 0.2146 0.0578 -0.9750 +vn -0.7386 0.6710 0.0658 +vn -0.5777 0.5521 -0.6012 +vn 0.8317 -0.2660 -0.4873 +vn 0.9459 -0.3161 -0.0731 +vn 0.8467 -0.2150 -0.4868 +vn 0.2146 0.0577 -0.9750 +vn 0.7789 -0.3941 0.4878 +vn -0.0802 -0.0227 0.9965 +vn 0.7789 -0.3942 0.4878 +vn -0.6598 0.5045 0.5569 +vn -0.3772 0.7335 0.5655 +vn -0.7688 0.3747 0.5182 +vn -0.9422 -0.2013 0.2677 +vn -0.2560 -0.1410 0.9564 +usemtl Scene_-_Root +s off +f 4195/3258/1888 4193/3259/1889 4499/3260/1890 +f 4195/3258/1891 4499/3260/1890 4500/3261/1890 +f 4193/3259/1892 3532/3262/1893 4501/3263/1890 +f 4193/3259/1892 4501/3263/1890 4499/3260/1890 +f 4499/3260/1890 4501/3263/1890 4502/3264/1890 +f 4499/3260/1890 4502/3264/1890 4503/3265/1890 +f 4500/3261/1890 4499/3260/1890 4503/3265/1890 +f 4500/3261/1890 4503/3265/1890 4504/3266/1890 +f 4504/3266/1890 4503/3265/1890 4505/3267/1890 +f 4504/3266/1890 4505/3267/1890 4506/3268/1890 +f 4503/3265/1890 4502/3264/1890 4507/3269/1890 +f 4503/3265/1890 4507/3269/1890 4505/3267/1890 +f 3545/3270/1894 3652/3271/1895 4508/3272/1890 +f 3545/3270/1896 4508/3272/1890 4509/3273/1890 +f 3652/3271/1897 3498/3274/1898 4510/3275/1890 +f 3652/3271/1899 4510/3275/1890 4508/3272/1890 +f 4508/3272/1890 4510/3275/1890 4511/3276/1890 +f 4508/3272/1890 4511/3276/1890 4512/3277/1890 +f 4509/3273/1890 4508/3272/1890 4512/3277/1890 +f 4509/3273/1890 4512/3277/1890 4513/3278/1890 +f 4513/3278/1890 4512/3277/1890 4514/3279/1890 +f 4513/3278/1890 4514/3279/1890 4515/3280/1890 +f 4512/3277/1890 4511/3276/1890 4516/3281/1890 +f 4512/3277/1890 4516/3281/1890 4514/3279/1890 +f 4246/3282/1900 4244/3283/1901 4517/3284/1890 +f 4246/3282/1900 4517/3284/1890 4518/3285/1890 +f 4244/3283/1901 3568/3286/1902 4519/3287/1890 +f 4244/3283/1901 4519/3287/1890 4517/3284/1890 +f 4517/3284/1890 4519/3287/1890 4520/3288/1890 +f 4517/3284/1890 4520/3288/1890 4521/3289/1890 +f 4518/3285/1890 4517/3284/1890 4521/3289/1890 +f 4518/3285/1890 4521/3289/1890 4522/3290/1890 +f 4522/3290/1890 4521/3289/1890 4523/3291/1890 +f 4522/3290/1890 4523/3291/1890 4524/3292/1890 +f 4521/3289/1890 4520/3288/1890 4525/3293/1890 +f 4521/3289/1890 4525/3293/1890 4523/3291/1890 +f 3532/3262/1903 3529/3294/1904 4526/3295/1890 +f 3532/3262/1893 4526/3295/1890 4501/3263/1890 +f 3529/3294/1905 3528/3296/1906 4527/3297/1890 +f 3529/3294/1907 4527/3297/1890 4526/3295/1890 +f 4526/3295/1890 4527/3297/1890 4528/3298/1890 +f 4526/3295/1890 4528/3298/1890 4529/3299/1890 +f 4501/3263/1890 4526/3295/1890 4529/3299/1890 +f 4501/3263/1890 4529/3299/1890 4502/3264/1890 +f 4502/3264/1890 4529/3299/1890 4530/3300/1890 +f 4502/3264/1890 4530/3300/1890 4507/3269/1890 +f 4529/3299/1890 4528/3298/1890 4531/3301/1890 +f 4529/3299/1890 4531/3301/1890 4530/3300/1890 +f 3498/3274/1898 3501/3302/1908 4532/3303/1890 +f 3498/3274/1898 4532/3303/1890 4510/3275/1890 +f 3501/3302/1908 3509/3304/1909 4533/3305/1890 +f 3501/3302/1908 4533/3305/1890 4532/3303/1890 +f 4532/3303/1890 4533/3305/1890 4534/3306/1890 +f 4532/3303/1890 4534/3306/1890 4535/3307/1890 +f 4510/3275/1890 4532/3303/1890 4535/3307/1890 +f 4510/3275/1890 4535/3307/1890 4511/3276/1890 +f 4511/3276/1890 4535/3307/1890 4536/3308/1890 +f 4511/3276/1890 4536/3308/1890 4516/3281/1890 +f 4535/3307/1890 4534/3306/1890 4537/3309/1890 +f 4535/3307/1890 4537/3309/1890 4536/3308/1890 +f 4229/3310/1910 4268/3311/1911 4538/3312/1890 +f 4229/3310/1910 4538/3312/1890 4539/3313/1890 +f 4268/3311/1911 4246/3282/1912 4518/3285/1890 +f 4268/3311/1911 4518/3285/1890 4538/3312/1890 +f 4538/3312/1890 4518/3285/1890 4522/3290/1890 +f 4538/3312/1890 4522/3290/1890 4540/3314/1890 +f 4539/3313/1890 4538/3312/1890 4540/3314/1890 +f 4539/3313/1890 4540/3314/1890 4541/3315/1890 +f 4541/3315/1890 4540/3314/1890 4542/3316/1890 +f 4541/3315/1890 4542/3316/1890 4543/3317/1890 +f 4540/3314/1890 4522/3290/1890 4524/3292/1890 +f 4540/3314/1890 4524/3292/1890 4542/3316/1890 +f 4235/3318/1913 4304/3319/1914 4544/3320/1890 +f 4235/3318/1913 4544/3320/1890 4545/3321/1890 +f 4304/3319/1915 4195/3258/1888 4500/3261/1890 +f 4304/3319/1914 4500/3261/1890 4544/3320/1890 +f 4544/3320/1890 4500/3261/1890 4504/3266/1890 +f 4544/3320/1890 4504/3266/1890 4546/3322/1890 +f 4545/3321/1890 4544/3320/1890 4546/3322/1890 +f 4545/3321/1890 4546/3322/1890 4547/3323/1890 +f 4547/3323/1890 4546/3322/1890 4548/3324/1890 +f 4547/3323/1890 4548/3324/1890 4549/3325/1890 +f 4546/3322/1890 4504/3266/1890 4506/3268/1890 +f 4546/3322/1890 4506/3268/1890 4548/3324/1890 +f 3537/3326/1916 3540/3327/1917 4550/3328/1890 +f 3537/3326/1918 4550/3328/1890 4551/3329/1890 +f 3540/3327/1919 3545/3270/1896 4509/3273/1890 +f 3540/3327/1917 4509/3273/1890 4550/3328/1890 +f 4550/3328/1890 4509/3273/1890 4513/3278/1890 +f 4550/3328/1890 4513/3278/1890 4552/3330/1890 +f 4551/3329/1890 4550/3328/1890 4552/3330/1890 +f 4551/3329/1890 4552/3330/1890 4553/3331/1890 +f 4553/3331/1890 4552/3330/1890 4554/3332/1890 +f 4553/3331/1890 4554/3332/1890 4555/3333/1890 +f 4552/3330/1890 4513/3278/1890 4515/3280/1890 +f 4552/3330/1890 4515/3280/1890 4554/3332/1890 +f 3637/3334/1920 3634/3335/1921 4556/3336/1890 +f 3637/3334/1920 4556/3336/1890 4557/3337/1890 +f 3634/3335/1922 3633/3338/1923 4558/3339/1890 +f 3634/3335/1922 4558/3339/1890 4556/3336/1890 +f 4556/3336/1890 4558/3339/1890 4559/3340/1890 +f 4556/3336/1890 4559/3340/1890 4560/3341/1890 +f 4557/3337/1890 4556/3336/1890 4560/3341/1890 +f 4557/3337/1890 4560/3341/1890 4561/3342/1890 +f 4561/3342/1890 4560/3341/1890 4562/3343/1890 +f 4561/3342/1924 4562/3343/1924 4563/3344/1924 +f 4560/3341/1890 4559/3340/1890 4564/3345/1890 +f 4560/3341/1890 4564/3345/1890 4562/3343/1890 +f 3514/3346/1925 3511/3347/1926 4565/3348/1890 +f 3514/3346/1925 4565/3348/1890 4566/3349/1890 +f 3511/3347/1927 3510/3350/1928 4567/3351/1890 +f 3511/3347/1926 4567/3351/1890 4565/3348/1890 +f 4565/3348/1890 4567/3351/1890 4568/3352/1890 +f 4565/3348/1890 4568/3352/1890 4569/3353/1890 +f 4566/3349/1890 4565/3348/1890 4569/3353/1890 +f 4566/3349/1890 4569/3353/1890 4570/3354/1890 +f 4570/3354/1890 4569/3353/1890 4571/3355/1890 +f 4570/3354/1890 4571/3355/1890 4572/3356/1890 +f 4569/3353/1890 4568/3352/1890 4573/3357/1890 +f 4569/3353/1890 4573/3357/1890 4571/3355/1890 +f 4256/3358/1929 4574/3359/1930 4575/3360/1890 +f 4574/3359/1931 3637/3334/1920 4557/3337/1890 +f 4574/3359/1931 4557/3337/1890 4575/3360/1890 +f 4575/3360/1890 4557/3337/1890 4561/3342/1890 +f 4575/3360/1890 4561/3342/1890 4577/3361/1890 +f 4576/3362/1932 4575/3360/1890 4577/3361/1890 +f 4578/3363/1933 4577/3361/1890 4579/3364/1890 +f 4577/3361/1890 4561/3342/1890 4563/3344/1890 +f 4577/3361/1890 4563/3344/1890 4579/3364/1890 +f 3568/3286/1902 3565/3365/1934 4582/3366/1890 +f 3568/3286/1935 4582/3366/1890 4519/3287/1890 +f 3565/3365/1934 3564/3367/1936 4583/3368/1890 +f 3565/3365/1934 4583/3368/1890 4582/3366/1890 +f 4582/3366/1890 4583/3368/1890 4584/3369/1890 +f 4582/3366/1890 4584/3369/1890 4585/3370/1890 +f 4519/3287/1890 4582/3366/1890 4585/3370/1890 +f 4519/3287/1890 4585/3370/1890 4520/3288/1890 +f 4520/3288/1890 4585/3370/1890 4586/3371/1890 +f 4520/3288/1890 4586/3371/1890 4525/3293/1890 +f 4585/3370/1890 4584/3369/1890 4587/3372/1890 +f 4585/3370/1890 4587/3372/1890 4586/3371/1890 +f 3633/3338/1923 4230/3373/1937 4588/3374/1890 +f 3633/3338/1923 4588/3374/1890 4558/3339/1890 +f 4230/3373/1938 4229/3310/1910 4539/3313/1890 +f 4230/3373/1938 4539/3313/1890 4588/3374/1890 +f 4588/3374/1890 4539/3313/1890 4541/3315/1890 +f 4588/3374/1890 4541/3315/1890 4589/3375/1890 +f 4558/3339/1890 4588/3374/1890 4589/3375/1890 +f 4558/3339/1890 4589/3375/1890 4559/3340/1890 +f 4559/3340/1890 4589/3375/1890 4590/3376/1890 +f 4559/3340/1890 4590/3376/1890 4564/3345/1890 +f 4589/3375/1890 4541/3315/1890 4543/3317/1890 +f 4589/3375/1890 4543/3317/1890 4590/3376/1890 +f 4271/3377/1939 4274/3378/1940 4591/3379/1890 +f 4271/3377/1939 4591/3379/1890 4592/3380/1890 +f 4274/3378/1940 3519/3381/1941 4593/3382/1890 +f 4274/3378/1940 4593/3382/1890 4591/3379/1890 +f 4591/3379/1890 4593/3382/1890 4594/3383/1890 +f 4591/3379/1890 4594/3383/1890 4595/3384/1890 +f 4592/3380/1890 4591/3379/1890 4595/3384/1890 +f 4592/3380/1890 4595/3384/1890 4596/3385/1890 +f 4596/3385/1890 4595/3384/1890 4597/3386/1890 +f 4596/3385/1890 4597/3386/1890 4598/3387/1890 +f 4595/3384/1890 4594/3383/1890 4599/3388/1890 +f 4595/3384/1890 4599/3388/1890 4597/3386/1890 +f 3605/3389/1942 4296/3390/1943 4600/3391/1890 +f 3605/3389/1944 4600/3391/1890 4601/3392/1890 +f 4296/3390/1943 4271/3377/1939 4592/3380/1890 +f 4296/3390/1943 4592/3380/1890 4600/3391/1890 +f 4600/3391/1890 4592/3380/1890 4596/3385/1890 +f 4600/3391/1890 4596/3385/1890 4602/3393/1890 +f 4601/3392/1890 4600/3391/1890 4602/3393/1890 +f 4601/3392/1890 4602/3393/1890 4603/3394/1890 +f 4603/3394/1890 4602/3393/1890 4604/3395/1890 +f 4603/3394/1890 4604/3395/1890 4605/3396/1890 +f 4602/3393/1890 4596/3385/1890 4598/3387/1890 +f 4602/3393/1890 4598/3387/1890 4604/3395/1890 +f 3597/3397/1945 3600/3398/1946 4606/3399/1890 +f 3597/3397/1945 4606/3399/1890 4607/3400/1890 +f 3600/3398/1947 3605/3389/1942 4601/3392/1890 +f 3600/3398/1947 4601/3392/1890 4606/3399/1890 +f 4606/3399/1890 4601/3392/1890 4603/3394/1890 +f 4606/3399/1890 4603/3394/1890 4608/3401/1890 +f 4607/3400/1890 4606/3399/1890 4608/3401/1890 +f 4607/3400/1890 4608/3401/1890 4609/3402/1890 +f 4609/3402/1890 4608/3401/1890 4610/3403/1890 +f 4609/3402/1890 4610/3403/1890 4611/3404/1890 +f 4608/3401/1890 4603/3394/1890 4605/3396/1890 +f 4608/3401/1890 4605/3396/1890 4610/3403/1890 +f 4283/3405/1948 4286/3406/1949 4612/3407/1890 +f 4283/3405/1948 4612/3407/1890 4613/3408/1890 +f 4286/3406/1949 4291/3409/1950 4614/3410/1890 +f 4286/3406/1949 4614/3410/1890 4612/3407/1890 +f 4612/3407/1890 4614/3410/1890 4615/3411/1890 +f 4612/3407/1890 4615/3411/1890 4616/3412/1890 +f 4613/3408/1890 4612/3407/1890 4616/3412/1890 +f 4613/3408/1890 4616/3412/1890 4617/3413/1890 +f 4617/3413/1890 4616/3412/1890 4618/3414/1890 +f 4617/3413/1890 4618/3414/1890 4619/3415/1890 +f 4616/3412/1890 4615/3411/1890 4620/3416/1890 +f 4616/3412/1890 4620/3416/1890 4618/3414/1890 +f 3555/3417/1951 3558/3418/1952 4621/3419/1890 +f 3555/3417/1951 4621/3419/1890 4622/3420/1890 +f 3558/3418/1952 3563/3421/1953 4623/3422/1890 +f 3558/3418/1952 4623/3422/1890 4621/3419/1890 +f 4621/3419/1890 4623/3422/1890 4624/3423/1890 +f 4621/3419/1890 4624/3423/1890 4625/3424/1890 +f 4622/3420/1890 4621/3419/1890 4625/3424/1890 +f 4622/3420/1890 4625/3424/1890 4626/3425/1890 +f 4626/3425/1890 4625/3424/1890 4627/3426/1890 +f 4626/3425/1890 4627/3426/1890 4628/3427/1890 +f 4625/3424/1890 4624/3423/1890 4629/3428/1890 +f 4625/3424/1890 4629/3428/1890 4627/3426/1890 +f 3581/3429/1954 4299/3430/1955 4630/3431/1890 +f 3581/3429/1954 4630/3431/1890 4631/3432/1890 +f 4299/3430/1955 3555/3417/1951 4622/3420/1890 +f 4299/3430/1956 4622/3420/1890 4630/3431/1890 +f 4630/3431/1890 4622/3420/1890 4626/3425/1890 +f 4630/3431/1890 4626/3425/1890 4632/3433/1890 +f 4631/3432/1890 4630/3431/1890 4632/3433/1890 +f 4631/3432/1890 4632/3433/1890 4633/3434/1890 +f 4633/3434/1890 4632/3433/1890 4634/3435/1890 +f 4633/3434/1890 4634/3435/1890 4635/3436/1890 +f 4632/3433/1890 4626/3425/1890 4628/3427/1890 +f 4632/3433/1890 4628/3427/1890 4634/3435/1890 +f 3573/3437/1957 3576/3438/1958 4636/3439/1890 +f 3573/3437/1957 4636/3439/1890 4637/3440/1890 +f 3576/3438/1958 3581/3429/1954 4631/3432/1890 +f 3576/3438/1958 4631/3432/1890 4636/3439/1890 +f 4636/3439/1890 4631/3432/1890 4633/3434/1890 +f 4636/3439/1890 4633/3434/1890 4638/3441/1890 +f 4637/3440/1890 4636/3439/1890 4638/3441/1890 +f 4637/3440/1890 4638/3441/1890 4639/3442/1890 +f 4639/3442/1890 4638/3441/1890 4640/3443/1890 +f 4639/3442/1890 4640/3443/1890 4641/3444/1890 +f 4638/3441/1890 4633/3434/1890 4635/3436/1890 +f 4638/3441/1890 4635/3436/1890 4640/3443/1890 +f 4291/3409/1959 4302/3445/1960 4642/3446/1890 +f 4291/3409/1959 4642/3446/1890 4614/3410/1890 +f 4302/3445/1960 3573/3437/1957 4637/3440/1890 +f 4302/3445/1960 4637/3440/1890 4642/3446/1890 +f 4642/3446/1890 4637/3440/1890 4639/3442/1890 +f 4642/3446/1890 4639/3442/1890 4643/3447/1890 +f 4614/3410/1890 4642/3446/1890 4643/3447/1890 +f 4614/3410/1890 4643/3447/1890 4615/3411/1890 +f 4615/3411/1890 4643/3447/1890 4644/3448/1890 +f 4615/3411/1890 4644/3448/1890 4620/3416/1890 +f 4643/3447/1890 4639/3442/1890 4641/3444/1890 +f 4643/3447/1890 4641/3444/1890 4644/3448/1890 +f 3564/3367/1936 4236/3449/1961 4645/3450/1890 +f 3564/3367/1936 4645/3450/1890 4583/3368/1890 +f 4236/3449/1962 4235/3318/1913 4545/3321/1890 +f 4236/3449/1961 4545/3321/1890 4645/3450/1890 +f 4645/3450/1890 4545/3321/1890 4547/3323/1890 +f 4645/3450/1890 4547/3323/1890 4646/3451/1890 +f 4583/3368/1890 4645/3450/1890 4646/3451/1890 +f 4583/3368/1890 4646/3451/1890 4584/3369/1890 +f 4584/3369/1890 4646/3451/1890 4647/3452/1890 +f 4584/3369/1890 4647/3452/1890 4587/3372/1890 +f 4646/3451/1890 4547/3323/1890 4549/3325/1890 +f 4646/3451/1890 4549/3325/1890 4647/3452/1890 +f 3563/3421/1953 4293/3453/1963 4648/3454/1890 +f 3563/3421/1953 4648/3454/1890 4623/3422/1890 +f 4293/3453/1963 3597/3397/1945 4607/3400/1890 +f 4293/3453/1963 4607/3400/1890 4648/3454/1890 +f 4648/3454/1890 4607/3400/1890 4609/3402/1890 +f 4648/3454/1890 4609/3402/1890 4649/3455/1890 +f 4623/3422/1890 4648/3454/1890 4649/3455/1890 +f 4623/3422/1890 4649/3455/1890 4624/3423/1890 +f 4624/3423/1890 4649/3455/1890 4650/3456/1890 +f 4624/3423/1890 4650/3456/1890 4629/3428/1890 +f 4649/3455/1890 4609/3402/1890 4611/3404/1890 +f 4649/3455/1890 4611/3404/1890 4650/3456/1890 +f 4310/3457/1964 4325/3458/1965 4651/3459/1890 +f 4310/3457/1966 4651/3459/1890 4652/3460/1890 +f 4325/3458/1967 4283/3405/1948 4613/3408/1890 +f 4325/3458/1965 4613/3408/1890 4651/3459/1890 +f 4651/3459/1890 4613/3408/1890 4617/3413/1890 +f 4651/3459/1890 4617/3413/1890 4653/3461/1890 +f 4652/3460/1890 4651/3459/1890 4653/3461/1890 +f 4652/3460/1890 4653/3461/1890 4654/3462/1890 +f 4654/3462/1890 4653/3461/1890 4655/3463/1890 +f 4654/3462/1890 4655/3463/1890 4656/3464/1890 +f 4653/3461/1890 4617/3413/1890 4619/3415/1890 +f 4653/3461/1890 4619/3415/1890 4655/3463/1890 +f 3519/3381/1941 3522/3465/1968 4657/3466/1890 +f 3519/3381/1941 4657/3466/1890 4593/3382/1890 +f 3522/3465/1968 3527/3467/1969 4658/3468/1890 +f 3522/3465/1968 4658/3468/1890 4657/3466/1890 +f 4657/3466/1890 4658/3468/1890 4659/3469/1890 +f 4657/3466/1890 4659/3469/1890 4660/3470/1890 +f 4593/3382/1890 4657/3466/1890 4660/3470/1890 +f 4593/3382/1890 4660/3470/1890 4594/3383/1890 +f 4594/3383/1890 4660/3470/1890 4661/3471/1890 +f 4594/3383/1890 4661/3471/1890 4599/3388/1890 +f 4660/3470/1890 4659/3469/1890 4662/3472/1890 +f 4660/3470/1890 4662/3472/1890 4661/3471/1890 +f 3528/3296/1906 4319/3473/1970 4663/3474/1890 +f 3528/3296/1906 4663/3474/1890 4527/3297/1890 +f 4319/3473/1971 3514/3346/1972 4566/3349/1890 +f 4319/3473/1971 4566/3349/1890 4663/3474/1890 +f 4663/3474/1890 4566/3349/1890 4570/3354/1890 +f 4663/3474/1890 4570/3354/1890 4664/3475/1890 +f 4527/3297/1890 4663/3474/1890 4664/3475/1890 +f 4527/3297/1890 4664/3475/1890 4528/3298/1890 +f 4528/3298/1890 4664/3475/1890 4665/3476/1890 +f 4528/3298/1890 4665/3476/1890 4531/3301/1890 +f 4664/3475/1890 4570/3354/1890 4572/3356/1890 +f 4664/3475/1890 4572/3356/1890 4665/3476/1890 +f 3527/3467/1973 4317/3477/1974 4666/3478/1890 +f 3527/3467/1973 4666/3478/1890 4658/3468/1890 +f 4317/3477/1974 3537/3326/1918 4551/3329/1890 +f 4317/3477/1974 4551/3329/1890 4666/3478/1890 +f 4666/3478/1890 4551/3329/1890 4553/3331/1890 +f 4666/3478/1890 4553/3331/1890 4667/3479/1890 +f 4658/3468/1890 4666/3478/1890 4667/3479/1890 +f 4658/3468/1890 4667/3479/1890 4659/3469/1890 +f 4659/3469/1890 4667/3479/1890 4668/3480/1890 +f 4659/3469/1890 4668/3480/1890 4662/3472/1890 +f 4667/3479/1890 4553/3331/1890 4555/3333/1890 +f 4667/3479/1890 4555/3333/1890 4668/3480/1890 +f 3510/3350/1975 4311/3481/1976 4669/3482/1890 +f 3510/3350/1977 4669/3482/1890 4567/3351/1890 +f 4311/3481/1978 4310/3457/1966 4652/3460/1890 +f 4311/3481/1976 4652/3460/1890 4669/3482/1890 +f 4669/3482/1890 4652/3460/1890 4654/3462/1890 +f 4669/3482/1890 4654/3462/1890 4670/3483/1890 +f 4567/3351/1890 4669/3482/1890 4670/3483/1890 +f 4567/3351/1890 4670/3483/1890 4568/3352/1890 +f 4568/3352/1890 4670/3483/1890 4671/3484/1890 +f 4568/3352/1890 4671/3484/1890 4573/3357/1890 +f 4670/3483/1890 4654/3462/1890 4656/3464/1890 +f 4670/3483/1890 4656/3464/1890 4671/3484/1890 +f 3293/3485/1979 4338/3486/1980 4681/3487/1981 +f 3293/3485/1979 4681/3487/1981 4682/3488/1981 +f 4338/3486/1980 3321/3489/1982 4683/3490/1981 +f 4338/3486/1983 4683/3490/1981 4681/3487/1981 +f 4681/3487/1981 4683/3490/1981 4684/3491/1981 +f 4681/3487/1981 4684/3491/1981 4685/3492/1981 +f 4682/3488/1981 4681/3487/1981 4685/3492/1981 +f 4682/3488/1981 4685/3492/1981 4686/3493/1981 +f 4686/3493/1981 4685/3492/1981 4687/3494/1981 +f 4686/3493/1981 4687/3494/1981 4688/3495/1981 +f 4685/3492/1981 4684/3491/1981 4689/3496/1981 +f 4685/3492/1981 4689/3496/1981 4687/3494/1981 +f 3449/3497/1984 4377/3498/1985 4699/3499/1981 +f 3449/3497/1984 4699/3499/1981 4700/3500/1981 +f 4377/3498/1986 3387/3501/1987 4701/3502/1981 +f 4377/3498/1985 4701/3502/1981 4699/3499/1981 +f 4699/3499/1981 4701/3502/1981 4702/3503/1981 +f 4699/3499/1981 4702/3503/1981 4703/3504/1981 +f 4700/3500/1981 4699/3499/1981 4703/3504/1981 +f 4700/3500/1981 4703/3504/1981 4704/3505/1981 +f 4704/3505/1981 4703/3504/1981 4705/3506/1981 +f 4704/3505/1981 4705/3506/1981 4706/3507/1981 +f 4703/3504/1981 4702/3503/1981 4707/3508/1981 +f 4703/3504/1981 4707/3508/1981 4705/3506/1981 +f 3285/3509/1988 3288/3510/1989 4708/3511/1981 +f 3285/3509/1990 4708/3511/1981 4709/3512/1981 +f 3288/3510/1989 3293/3485/1979 4682/3488/1981 +f 3288/3510/1989 4682/3488/1981 4708/3511/1981 +f 4708/3511/1981 4682/3488/1981 4686/3493/1981 +f 4708/3511/1981 4686/3493/1981 4710/3513/1981 +f 4709/3512/1981 4708/3511/1981 4710/3513/1981 +f 4709/3512/1981 4710/3513/1981 4711/3514/1981 +f 4711/3514/1981 4710/3513/1981 4712/3515/1981 +f 4711/3514/1981 4712/3515/1981 4713/3516/1981 +f 4710/3513/1981 4686/3493/1981 4688/3495/1981 +f 4710/3513/1981 4688/3495/1981 4712/3515/1981 +f 4468/3517/1991 4466/3518/1992 4714/3519/1981 +f 4468/3517/1991 4714/3519/1981 4715/3520/1981 +f 4466/3518/1993 4691/3521/1994 4714/3519/1981 +f 4714/3519/1981 4695/3522/1995 4716/3523/1981 +f 4715/3520/1981 4714/3519/1981 4716/3523/1981 +f 4715/3520/1981 4716/3523/1981 4717/3524/1981 +f 4717/3524/1981 4716/3523/1981 4718/3525/1981 +f 4717/3524/1981 4718/3525/1981 4719/3526/1981 +f 4716/3523/1981 4697/3527/1996 4718/3525/1981 +f 3387/3501/1997 3390/3528/1998 4720/3529/1981 +f 3387/3501/1987 4720/3529/1981 4701/3502/1981 +f 3390/3528/1999 3395/3530/2000 4721/3531/1981 +f 3390/3528/1998 4721/3531/1981 4720/3529/1981 +f 4720/3529/1981 4721/3531/1981 4722/3532/1981 +f 4720/3529/1981 4722/3532/1981 4723/3533/1981 +f 4701/3502/1981 4720/3529/1981 4723/3533/1981 +f 4701/3502/1981 4723/3533/1981 4702/3503/1981 +f 4702/3503/1981 4723/3533/1981 4724/3534/1981 +f 4702/3503/1981 4724/3534/1981 4707/3508/1981 +f 4723/3533/1981 4722/3532/1981 4725/3535/1981 +f 4723/3533/1981 4725/3535/1981 4724/3534/1981 +f 3321/3489/2001 3324/3536/2002 4726/3537/1981 +f 3321/3489/2003 4726/3537/1981 4683/3490/1981 +f 3324/3536/2002 3329/3538/2004 4727/3539/1981 +f 3324/3536/2002 4727/3539/1981 4726/3537/1981 +f 4726/3537/1981 4727/3539/1981 4728/3540/1981 +f 4726/3537/1981 4728/3540/1981 4729/3541/1981 +f 4683/3490/1981 4726/3537/1981 4729/3541/1981 +f 4683/3490/1981 4729/3541/1981 4684/3491/1981 +f 4684/3491/1981 4729/3541/1981 4730/3542/1981 +f 4684/3491/1981 4730/3542/1981 4689/3496/1981 +f 4729/3541/1981 4728/3540/1981 4731/3543/1981 +f 4729/3541/1981 4731/3543/1981 4730/3542/1981 +f 3450/3544/2005 3453/3545/2006 4738/3546/1981 +f 3450/3544/2007 4738/3546/1981 4739/3547/1981 +f 3453/3545/2008 3458/3548/2009 4740/3549/1981 +f 3453/3545/2010 4740/3549/1981 4738/3546/1981 +f 4738/3546/1981 4740/3549/1981 4741/3550/1981 +f 4738/3546/1981 4741/3550/1981 4742/3551/1981 +f 4739/3547/1981 4738/3546/1981 4742/3551/1981 +f 4739/3547/1981 4742/3551/1981 4743/3552/1981 +f 4743/3552/1981 4742/3551/1981 4744/3553/1981 +f 4743/3552/1981 4744/3553/1981 4745/3554/1981 +f 4742/3551/1981 4741/3550/1981 4746/3555/1981 +f 4742/3551/1981 4746/3555/1981 4744/3553/1981 +f 3303/3556/2011 3306/3557/2012 4747/3558/1981 +f 3303/3556/2013 4747/3558/1981 4748/3559/1981 +f 3306/3557/2014 3311/3560/2015 4749/3561/1981 +f 3306/3557/2012 4749/3561/1981 4747/3558/1981 +f 4747/3558/1981 4749/3561/1981 4750/3562/1981 +f 4747/3558/1981 4750/3562/1981 4751/3563/1981 +f 4748/3559/1981 4747/3558/1981 4751/3563/1981 +f 4748/3559/1981 4751/3563/1981 4752/3564/1981 +f 4752/3564/1981 4751/3563/1981 4753/3565/1981 +f 4752/3564/1981 4753/3565/1981 4754/3566/1981 +f 4751/3563/1981 4750/3562/1981 4755/3567/1981 +f 4751/3563/1981 4755/3567/1981 4753/3565/1981 +f 3441/3568/2016 3444/3569/2017 4765/3570/1981 +f 3441/3568/2016 4765/3570/1981 4766/3571/1981 +f 3444/3569/2017 3449/3497/1984 4700/3500/1981 +f 3444/3569/2017 4700/3500/1981 4765/3570/1981 +f 4765/3570/1981 4700/3500/1981 4704/3505/1981 +f 4765/3570/1981 4704/3505/1981 4767/3572/1981 +f 4766/3571/1981 4765/3570/1981 4767/3572/1981 +f 4766/3571/1981 4767/3572/1981 4768/3573/1981 +f 4768/3573/1981 4767/3572/1981 4769/3574/1981 +f 4768/3573/1981 4769/3574/1981 4770/3575/1981 +f 4767/3572/1981 4704/3505/1981 4706/3507/1981 +f 4767/3572/1981 4706/3507/1981 4769/3574/1981 +f 3395/3530/2000 4368/3576/2018 4771/3577/1981 +f 3395/3530/2000 4771/3577/1981 4721/3531/1981 +f 4368/3576/2018 3450/3544/2007 4739/3547/1981 +f 4368/3576/2018 4739/3547/1981 4771/3577/1981 +f 4771/3577/1981 4739/3547/1981 4743/3552/1981 +f 4771/3577/1981 4743/3552/1981 4772/3578/1981 +f 4721/3531/1981 4771/3577/1981 4772/3578/1981 +f 4721/3531/1981 4772/3578/1981 4722/3532/1981 +f 4722/3532/1981 4772/3578/1981 4773/3579/1981 +f 4722/3532/1981 4773/3579/1981 4725/3535/1981 +f 4772/3578/1981 4743/3552/1981 4745/3554/1981 +f 4772/3578/1981 4745/3554/1981 4773/3579/1981 +f 4404/3580/2019 4401/3581/2020 4774/3582/1981 +f 4401/3581/2021 4400/3583/2022 4776/3584/1981 +f 4401/3581/2020 4776/3584/1981 4774/3582/1981 +f 4774/3582/1981 4776/3584/1981 4777/3585/1981 +f 4774/3582/1981 4777/3585/1981 4778/3586/1981 +f 4775/3587/2023 4774/3582/1981 4778/3586/1981 +f 4779/3588/2024 4778/3586/1981 4780/3589/1981 +f 4778/3586/1981 4777/3585/1981 4782/3590/1981 +f 4778/3586/1981 4782/3590/1981 4780/3589/1981 +f 4400/3583/2022 4430/3591/2025 4783/3592/1981 +f 4400/3583/2022 4783/3592/1981 4776/3584/1981 +f 4430/3591/2025 3316/3593/2026 4784/3594/1981 +f 4430/3591/2025 4784/3594/1981 4783/3592/1981 +f 4783/3592/1981 4784/3594/1981 4785/3595/1981 +f 4783/3592/1981 4785/3595/1981 4786/3596/1981 +f 4776/3584/1981 4783/3592/1981 4786/3596/1981 +f 4776/3584/1981 4786/3596/1981 4777/3585/1981 +f 4777/3585/1981 4786/3596/1981 4787/3597/1981 +f 4777/3585/1981 4787/3597/1981 4782/3590/1981 +f 4786/3596/1981 4785/3595/1981 4788/3598/1981 +f 4786/3596/1981 4788/3598/1981 4787/3597/1981 +f 3316/3593/2026 3313/3599/2027 4789/3600/1981 +f 3316/3593/2026 4789/3600/1981 4784/3594/1981 +f 3313/3599/2027 3312/3601/2028 4790/3602/1981 +f 3313/3599/2027 4790/3602/1981 4789/3600/1981 +f 4789/3600/1981 4790/3602/1981 4791/3603/1981 +f 4789/3600/1981 4791/3603/1981 4792/3604/1981 +f 4784/3594/1981 4789/3600/1981 4792/3604/1981 +f 4784/3594/1981 4792/3604/1981 4785/3595/1981 +f 4785/3595/1981 4792/3604/1981 4793/3605/1981 +f 4785/3595/1981 4793/3605/1981 4788/3598/1981 +f 4792/3604/1981 4791/3603/1981 4794/3606/1981 +f 4792/3604/1981 4794/3606/1981 4793/3605/1981 +f 4420/3607/2029 4418/3608/2030 4795/3609/1981 +f 4420/3607/2031 4795/3609/1981 4796/3610/1981 +f 4418/3608/2030 3267/3611/2032 4797/3612/1981 +f 4418/3608/2030 4797/3612/1981 4795/3609/1981 +f 4795/3609/1981 4797/3612/1981 4798/3613/1981 +f 4795/3609/1981 4798/3613/1981 4799/3614/1981 +f 4796/3610/1981 4795/3609/1981 4799/3614/1981 +f 4796/3610/1981 4799/3614/1981 4800/3615/1981 +f 4800/3615/1981 4799/3614/1981 4801/3616/1981 +f 4800/3615/1981 4801/3616/1981 4802/3617/1981 +f 4799/3614/1981 4798/3613/1981 4803/3618/1981 +f 4799/3614/1981 4803/3618/1981 4801/3616/1981 +f 4424/3619/2033 4445/3620/2034 4804/3621/1981 +f 4424/3619/2035 4804/3621/1981 4805/3622/1981 +f 4445/3620/2034 4435/3623/2036 4806/3624/1981 +f 4445/3620/2034 4806/3624/1981 4804/3621/1981 +f 4804/3621/1981 4806/3624/1981 4807/3625/1981 +f 4804/3621/1981 4807/3625/1981 4808/3626/1981 +f 4805/3622/1981 4804/3621/1981 4808/3626/1981 +f 4805/3622/1981 4808/3626/1981 4809/3627/1981 +f 4809/3627/1981 4808/3626/1981 4810/3628/1981 +f 4809/3627/1981 4810/3628/1981 4811/3629/1981 +f 4808/3626/1981 4807/3625/1981 4812/3630/1981 +f 4808/3626/1981 4812/3630/1981 4810/3628/1981 +f 4435/3623/2036 4433/3631/2037 4813/3632/1981 +f 4435/3623/2036 4813/3632/1981 4806/3624/1981 +f 4433/3631/2037 3334/3633/2038 4814/3634/1981 +f 4433/3631/2037 4814/3634/1981 4813/3632/1981 +f 4813/3632/1981 4814/3634/1981 4815/3635/1981 +f 4813/3632/1981 4815/3635/1981 4816/3636/1981 +f 4806/3624/1981 4813/3632/1981 4816/3636/1981 +f 4806/3624/1981 4816/3636/1981 4807/3625/1981 +f 4807/3625/1981 4816/3636/1981 4817/3637/1981 +f 4807/3625/1981 4817/3637/1981 4812/3630/1981 +f 4816/3636/1981 4815/3635/1981 4818/3638/1981 +f 4816/3636/1981 4818/3638/1981 4817/3637/1981 +f 3334/3633/2038 3331/3639/2039 4819/3640/1981 +f 3334/3633/2038 4819/3640/1981 4814/3634/1981 +f 3331/3639/2039 3330/3641/2040 4820/3642/1981 +f 3331/3639/2039 4820/3642/1981 4819/3640/1981 +f 4819/3640/1981 4820/3642/1981 4821/3643/1981 +f 4819/3640/1981 4821/3643/1981 4822/3644/1981 +f 4814/3634/1981 4819/3640/1981 4822/3644/1981 +f 4814/3634/1981 4822/3644/1981 4815/3635/1981 +f 4815/3635/1981 4822/3644/1981 4823/3645/1981 +f 4815/3635/1981 4823/3645/1981 4818/3638/1981 +f 4822/3644/1981 4821/3643/1981 4824/3646/1981 +f 4822/3644/1981 4824/3646/1981 4823/3645/1981 +f 3330/3641/2040 4439/3647/2041 4825/3648/1981 +f 3330/3641/2040 4825/3648/1981 4820/3642/1981 +f 4439/3647/2042 4420/3607/2031 4796/3610/1981 +f 4439/3647/2041 4796/3610/1981 4825/3648/1981 +f 4825/3648/1981 4796/3610/1981 4800/3615/1981 +f 4825/3648/1981 4800/3615/1981 4826/3649/1981 +f 4820/3642/1981 4825/3648/1981 4826/3649/1981 +f 4820/3642/1981 4826/3649/1981 4821/3643/1981 +f 4821/3643/1981 4826/3649/1981 4827/3650/1981 +f 4821/3643/1981 4827/3650/1981 4824/3646/1981 +f 4826/3649/1981 4800/3615/1981 4802/3617/1981 +f 4826/3649/1981 4802/3617/1981 4827/3650/1981 +f 3329/3538/2043 4371/3651/2044 4828/3652/1981 +f 3329/3538/2004 4828/3652/1981 4727/3539/1981 +f 4371/3651/2044 3441/3568/2016 4766/3571/1981 +f 4371/3651/2044 4766/3571/1981 4828/3652/1981 +f 4828/3652/1981 4766/3571/1981 4768/3573/1981 +f 4828/3652/1981 4768/3573/1981 4829/3653/1981 +f 4727/3539/1981 4828/3652/1981 4829/3653/1981 +f 4727/3539/1981 4829/3653/1981 4728/3540/1981 +f 4728/3540/1981 4829/3653/1981 4830/3654/1981 +f 4728/3540/1981 4830/3654/1981 4731/3543/1981 +f 4829/3653/1981 4768/3573/1981 4770/3575/1981 +f 4829/3653/1981 4770/3575/1981 4830/3654/1981 +f 3312/3601/2028 4425/3655/2045 4831/3656/1981 +f 3312/3601/2028 4831/3656/1981 4790/3602/1981 +f 4425/3655/2045 4424/3619/2035 4805/3622/1981 +f 4425/3655/2045 4805/3622/1981 4831/3656/1981 +f 4831/3656/1981 4805/3622/1981 4809/3627/1981 +f 4831/3656/1981 4809/3627/1981 4832/3657/1981 +f 4790/3602/1981 4831/3656/1981 4832/3657/1981 +f 4790/3602/1981 4832/3657/1981 4791/3603/1981 +f 4791/3603/1981 4832/3657/1981 4833/3658/1981 +f 4791/3603/1981 4833/3658/1981 4794/3606/1981 +f 4832/3657/1981 4809/3627/1981 4811/3629/1981 +f 4832/3657/1981 4811/3629/1981 4833/3658/1981 +f 3267/3611/2032 3270/3659/2046 4834/3660/1981 +f 3267/3611/2032 4834/3660/1981 4797/3612/1981 +f 3270/3659/2046 3275/3661/2047 4835/3662/1981 +f 3270/3659/2046 4835/3662/1981 4834/3660/1981 +f 4834/3660/1981 4835/3662/1981 4836/3663/1981 +f 4834/3660/1981 4836/3663/1981 4837/3664/1981 +f 4797/3612/1981 4834/3660/1981 4837/3664/1981 +f 4797/3612/1981 4837/3664/1981 4798/3613/1981 +f 4798/3613/1981 4837/3664/1981 4838/3665/1981 +f 4798/3613/1981 4838/3665/1981 4803/3618/1981 +f 4837/3664/1981 4836/3663/1981 4839/3666/1981 +f 4837/3664/1981 4839/3666/1981 4838/3665/1981 +f 3311/3560/2015 4458/3667/2048 4846/3668/1981 +f 3311/3560/2015 4846/3668/1981 4749/3561/1981 +f 4458/3667/2049 3285/3509/1990 4709/3512/1981 +f 4458/3667/2048 4709/3512/1981 4846/3668/1981 +f 4846/3668/1981 4709/3512/1981 4711/3514/1981 +f 4846/3668/1981 4711/3514/1981 4847/3669/1981 +f 4749/3561/1981 4846/3668/1981 4847/3669/1981 +f 4749/3561/1981 4847/3669/1981 4750/3562/1981 +f 4750/3562/1981 4847/3669/1981 4848/3670/1981 +f 4750/3562/1981 4848/3670/1981 4755/3567/1981 +f 4847/3669/1981 4711/3514/1981 4713/3516/1981 +f 4847/3669/1981 4713/3516/1981 4848/3670/1981 +f 3275/3661/2050 4449/3671/2051 4852/3672/1981 +f 3275/3661/2047 4852/3672/1981 4835/3662/1981 +f 4449/3671/2052 3303/3556/2053 4748/3559/1981 +f 4449/3671/2054 4748/3559/1981 4852/3672/1981 +f 4852/3672/1981 4748/3559/1981 4752/3564/1981 +f 4852/3672/1981 4752/3564/1981 4853/3673/1981 +f 4835/3662/1981 4852/3672/1981 4853/3673/1981 +f 4835/3662/1981 4853/3673/1981 4836/3663/1981 +f 4836/3663/1981 4853/3673/1981 4854/3674/1981 +f 4836/3663/1981 4854/3674/1981 4839/3666/1981 +f 4853/3673/1981 4752/3564/1981 4754/3566/1981 +f 4853/3673/1981 4754/3566/1981 4854/3674/1981 +f 4358/3675/2055 4855/3676/2056 4856/3677/2057 +f 4855/3676/2056 4468/3517/2058 4715/3520/1981 +f 4855/3676/2056 4715/3520/1981 4856/3677/1981 +f 4856/3677/1981 4715/3520/1981 4717/3524/1981 +f 4856/3677/1981 4717/3524/1981 4858/3678/1981 +f 4857/3679/2059 4856/3677/1981 4858/3678/1981 +f 4859/3680/2060 4858/3678/1981 4860/3681/1981 +f 4858/3678/1981 4717/3524/1981 4719/3526/1981 +f 4858/3678/1981 4719/3526/1981 4860/3681/1981 +f 4534/3306/1890 5602/3682/1890 5603/3683/1890 +f 4534/3306/1890 5603/3683/1890 4537/3309/1890 +f 5602/3682/1890 4679/3684/2061 5603/3683/1890 +f 3509/3304/1909 5605/3685/2062 5606/3686/1890 +f 3509/3304/1909 5606/3686/1890 4533/3305/1890 +f 5605/3685/2062 4673/3687/2061 5606/3686/1890 +f 5606/3686/1890 4677/3688/2063 5602/3682/1890 +f 4533/3305/1890 5606/3686/1890 5602/3682/1890 +f 4533/3305/1890 5602/3682/1890 4534/3306/1890 +f 4741/3550/1981 5631/3689/1981 5632/3690/1981 +f 4741/3550/1981 5632/3690/1981 4746/3555/1981 +f 5631/3689/2064 4763/3691/2065 5632/3690/2064 +f 3458/3548/2009 5634/3692/2066 5635/3693/2064 +f 3458/3548/2009 5635/3693/1981 4740/3549/1981 +f 5634/3692/2067 4757/3694/2068 5635/3693/1981 +f 5635/3693/2057 4761/3695/2069 5631/3689/2057 +f 4740/3549/2057 5635/3693/2057 5631/3689/2057 +f 4740/3549/1981 5631/3689/1981 4741/3550/1981 +s 1 +f 3258/3696/2070 3259/3697/2071 3260/3698/2072 +f 3258/3696/2070 3260/3698/2072 3261/3699/2073 +f 3259/3697/2071 3262/3700/2074 3263/3701/2075 +f 3259/3697/2071 3263/3701/2075 3260/3698/2072 +f 3260/3698/2072 3263/3701/2075 3264/3702/2076 +f 3260/3698/2072 3264/3702/2076 3265/3703/2077 +f 3261/3699/2073 3260/3698/2072 3265/3703/2077 +f 3261/3699/2073 3265/3703/2077 3266/3704/2078 +f 3267/3611/2032 3268/3705/2079 3269/3706/2080 +f 3267/3611/2032 3269/3706/2080 3270/3659/2046 +f 3268/3705/2079 3271/3707/2081 3272/3708/2082 +f 3268/3705/2079 3272/3708/2082 3269/3706/2080 +f 3269/3706/2080 3272/3708/2082 3273/3709/2083 +f 3269/3706/2080 3273/3709/2083 3274/3710/2084 +f 3270/3659/2046 3269/3706/2080 3274/3710/2084 +f 3270/3659/2046 3274/3710/2084 3275/3661/2050 +f 3276/3711/2085 3277/3712/2086 3278/3713/2087 +f 3276/3711/2085 3278/3713/2087 3279/3714/2088 +f 3277/3712/2086 3280/3715/2089 3281/3716/2090 +f 3277/3712/2086 3281/3716/2090 3278/3713/2087 +f 3278/3713/2087 3281/3716/2090 3282/3717/2091 +f 3278/3713/2087 3282/3717/2091 3283/3718/2092 +f 3279/3714/2088 3278/3713/2087 3283/3718/2092 +f 3279/3714/2088 3283/3718/2092 3284/3719/2093 +f 3285/3509/1990 3286/3720/2094 3287/3721/2095 +f 3285/3509/1990 3287/3721/2095 3288/3510/2096 +f 3286/3720/2094 3289/3722/2097 3290/3723/2098 +f 3286/3720/2094 3290/3723/2098 3287/3721/2095 +f 3287/3721/2095 3290/3723/2098 3291/3724/2099 +f 3287/3721/2095 3291/3724/2099 3292/3725/2100 +f 3288/3510/2096 3287/3721/2095 3292/3725/2100 +f 3288/3510/2096 3292/3725/2100 3293/3485/1979 +f 3294/3726/2101 3295/3727/2102 3296/3728/2103 +f 3294/3726/2101 3296/3728/2103 3297/3729/2104 +f 3295/3727/2102 3298/3730/2105 3299/3731/2106 +f 3295/3727/2102 3299/3731/2106 3296/3728/2103 +f 3296/3728/2103 3299/3731/2106 3300/3732/2107 +f 3296/3728/2103 3300/3732/2107 3301/3733/2108 +f 3297/3729/2104 3296/3728/2103 3301/3733/2108 +f 3297/3729/2104 3301/3733/2108 3302/3734/2109 +f 3303/3556/2011 3304/3735/2110 3305/3736/2111 +f 3303/3556/2011 3305/3736/2111 3306/3557/2112 +f 3304/3735/2110 3307/3737/2113 3308/3738/2114 +f 3304/3735/2110 3308/3738/2114 3305/3736/2111 +f 3305/3736/2111 3308/3738/2114 3309/3739/2115 +f 3305/3736/2111 3309/3739/2115 3310/3740/2116 +f 3306/3557/2112 3305/3736/2111 3310/3740/2116 +f 3306/3557/2112 3310/3740/2116 3311/3560/2015 +f 3312/3601/2028 3313/3599/2027 3314/3741/2117 +f 3312/3601/2028 3314/3741/2117 3315/3742/2118 +f 3313/3599/2027 3316/3593/2026 3317/3743/2119 +f 3313/3599/2027 3317/3743/2119 3314/3741/2117 +f 3314/3741/2117 3317/3743/2119 3318/3744/2120 +f 3314/3741/2117 3318/3744/2120 3319/3745/2121 +f 3315/3742/2118 3314/3741/2117 3319/3745/2121 +f 3315/3742/2118 3319/3745/2121 3320/3746/2122 +f 3321/3489/2123 3322/3747/2124 3323/3748/2125 +f 3321/3489/2123 3323/3748/2125 3324/3536/2002 +f 3322/3747/2124 3325/3749/2126 3326/3750/2127 +f 3322/3747/2124 3326/3750/2127 3323/3748/2125 +f 3323/3748/2125 3326/3750/2127 3327/3751/2128 +f 3323/3748/2125 3327/3751/2128 3328/3752/2129 +f 3324/3536/2002 3323/3748/2125 3328/3752/2129 +f 3324/3536/2002 3328/3752/2129 3329/3538/2004 +f 3330/3641/2130 3331/3639/2039 3332/3753/2131 +f 3330/3641/2130 3332/3753/2131 3333/3754/2132 +f 3331/3639/2039 3334/3633/2038 3335/3755/2133 +f 3331/3639/2039 3335/3755/2133 3332/3753/2131 +f 3332/3753/2131 3335/3755/2133 3336/3756/2134 +f 3332/3753/2131 3336/3756/2134 3337/3757/2135 +f 3333/3754/2132 3332/3753/2131 3337/3757/2135 +f 3333/3754/2132 3337/3757/2135 3338/3758/2136 +f 3339/3759/2137 3340/3760/2138 3341/3761/2139 +f 3339/3759/2137 3341/3761/2139 3342/3762/2140 +f 3340/3760/2138 3343/3763/2141 3344/3764/2142 +f 3340/3760/2138 3344/3764/2142 3341/3761/2139 +f 3341/3761/2139 3344/3764/2142 3345/3765/2143 +f 3341/3761/2139 3345/3765/2143 3346/3766/2144 +f 3342/3762/2140 3341/3761/2139 3346/3766/2144 +f 3342/3762/2140 3346/3766/2144 3347/3767/2145 +f 3343/3763/2141 3348/3768/2146 3349/3769/2147 +f 3343/3763/2141 3349/3769/2147 3344/3764/2142 +f 3348/3768/2146 3350/3770/2148 3351/3771/2149 +f 3348/3768/2146 3351/3771/2149 3349/3769/2147 +f 3349/3769/2147 3351/3771/2149 3352/3772/2150 +f 3349/3769/2147 3352/3772/2150 3353/3773/2151 +f 3344/3764/2142 3349/3769/2147 3353/3773/2151 +f 3344/3764/2142 3353/3773/2151 3345/3765/2143 +f 3350/3770/2148 3354/3774/2152 3355/3775/2153 +f 3350/3770/2148 3355/3775/2153 3351/3771/2149 +f 3354/3774/2152 3356/3776/2154 3357/3777/2155 +f 3354/3774/2152 3357/3777/2155 3355/3775/2153 +f 3355/3775/2153 3357/3777/2155 3358/3778/2156 +f 3355/3775/2153 3358/3778/2156 3359/3779/2157 +f 3351/3771/2149 3355/3775/2153 3359/3779/2157 +f 3351/3771/2149 3359/3779/2157 3352/3772/2150 +f 3356/3776/2154 3360/3780/2158 3361/3781/2159 +f 3356/3776/2154 3361/3781/2159 3357/3777/2155 +f 3360/3780/2158 3362/3782/2160 3363/3783/2161 +f 3360/3780/2158 3363/3783/2161 3361/3781/2159 +f 3361/3781/2159 3363/3783/2161 3364/3784/2162 +f 3361/3781/2159 3364/3784/2162 3365/3785/2163 +f 3357/3777/2155 3361/3781/2159 3365/3785/2163 +f 3357/3777/2155 3365/3785/2163 3358/3778/2156 +f 3362/3782/2160 3366/3786/2164 3367/3787/2165 +f 3362/3782/2160 3367/3787/2165 3363/3783/2161 +f 3366/3786/2164 3368/3788/2166 3369/3789/2167 +f 3366/3786/2164 3369/3789/2167 3367/3787/2165 +f 3367/3787/2165 3369/3789/2167 3370/3790/2168 +f 3367/3787/2165 3370/3790/2168 3371/3791/2169 +f 3363/3783/2161 3367/3787/2165 3371/3791/2169 +f 3363/3783/2161 3371/3791/2169 3364/3784/2162 +f 3368/3788/2166 3372/3792/2170 3373/3793/2171 +f 3368/3788/2166 3373/3793/2171 3369/3789/2167 +f 3372/3792/2170 3374/3794/2172 3375/3795/2173 +f 3372/3792/2170 3375/3795/2173 3373/3793/2171 +f 3373/3793/2171 3375/3795/2173 3376/3796/2174 +f 3373/3793/2171 3376/3796/2174 3377/3797/2175 +f 3369/3789/2167 3373/3793/2171 3377/3797/2175 +f 3369/3789/2167 3377/3797/2175 3370/3790/2168 +f 3378/3798/2176 3379/3799/2177 3380/3800/2178 +f 3378/3798/2176 3380/3800/2178 3381/3801/2179 +f 3379/3799/2177 3382/3802/2180 3383/3803/2181 +f 3379/3799/2177 3383/3803/2181 3380/3800/2178 +f 3380/3800/2178 3383/3803/2181 3384/3804/2182 +f 3380/3800/2178 3384/3804/2182 3385/3805/2183 +f 3381/3801/2179 3380/3800/2178 3385/3805/2183 +f 3381/3801/2179 3385/3805/2183 3386/3806/2184 +f 3387/3501/1987 3388/3807/2185 3389/3808/2186 +f 3387/3501/1987 3389/3808/2186 3390/3528/1998 +f 3388/3807/2185 3391/3809/2187 3392/3810/2188 +f 3388/3807/2185 3392/3810/2188 3389/3808/2186 +f 3389/3808/2186 3392/3810/2188 3393/3811/2189 +f 3389/3808/2186 3393/3811/2189 3394/3812/2190 +f 3390/3528/1998 3389/3808/2186 3394/3812/2190 +f 3390/3528/1998 3394/3812/2190 3395/3530/2000 +f 3396/3813/2191 3397/3814/2192 3398/3815/2193 +f 3396/3813/2191 3398/3815/2193 3399/3816/2194 +f 3397/3814/2192 3400/3817/2195 3401/3818/2196 +f 3397/3814/2192 3401/3818/2196 3398/3815/2193 +f 3398/3815/2193 3401/3818/2196 3402/3819/2197 +f 3398/3815/2193 3402/3819/2197 3403/3820/2198 +f 3399/3816/2194 3398/3815/2193 3403/3820/2198 +f 3399/3816/2194 3403/3820/2198 3404/3821/2199 +f 3405/3822/2200 3406/3823/2201 3407/3824/2202 +f 3405/3822/2200 3407/3824/2202 3408/3825/2203 +f 3406/3823/2201 3409/3826/2204 3410/3827/2205 +f 3406/3823/2201 3410/3827/2205 3407/3824/2202 +f 3407/3824/2202 3410/3827/2205 3411/3828/2206 +f 3407/3824/2202 3411/3828/2206 3412/3829/2207 +f 3408/3825/2203 3407/3824/2202 3412/3829/2207 +f 3408/3825/2203 3412/3829/2207 3413/3830/2208 +f 3414/3831/2209 3415/3832/2210 3416/3833/2211 +f 3414/3831/2209 3416/3833/2211 3417/3834/2212 +f 3415/3832/2210 3418/3835/2213 3419/3836/2214 +f 3415/3832/2210 3419/3836/2214 3416/3833/2211 +f 3416/3833/2211 3419/3836/2214 3420/3837/2215 +f 3416/3833/2211 3420/3837/2215 3421/3838/2216 +f 3417/3834/2212 3416/3833/2211 3421/3838/2216 +f 3417/3834/2212 3421/3838/2216 3422/3839/2217 +f 3423/3840/2218 3424/3841/2219 3425/3842/2220 +f 3423/3840/2218 3425/3842/2220 3426/3843/2221 +f 3424/3841/2219 3427/3844/2222 3428/3845/2223 +f 3424/3841/2219 3428/3845/2223 3425/3842/2220 +f 3425/3842/2220 3428/3845/2223 3429/3846/2224 +f 3425/3842/2220 3429/3846/2224 3430/3847/2225 +f 3426/3843/2221 3425/3842/2220 3430/3847/2225 +f 3426/3843/2221 3430/3847/2225 3431/3848/2226 +f 3432/3849/2227 3433/3850/2228 3434/3851/2229 +f 3432/3849/2227 3434/3851/2229 3435/3852/2230 +f 3433/3850/2228 3436/3853/2231 3437/3854/2232 +f 3433/3850/2228 3437/3854/2232 3434/3851/2229 +f 3434/3851/2229 3437/3854/2232 3438/3855/2233 +f 3434/3851/2229 3438/3855/2233 3439/3856/2234 +f 3435/3852/2230 3434/3851/2229 3439/3856/2234 +f 3435/3852/2230 3439/3856/2234 3440/3857/2235 +f 3441/3568/2016 3442/3858/2236 3443/3859/2237 +f 3441/3568/2016 3443/3859/2237 3444/3569/2238 +f 3442/3858/2236 3445/3860/2239 3446/3861/2240 +f 3442/3858/2236 3446/3861/2240 3443/3859/2237 +f 3443/3859/2237 3446/3861/2240 3447/3862/2241 +f 3443/3859/2237 3447/3862/2241 3448/3863/2242 +f 3444/3569/2238 3443/3859/2237 3448/3863/2242 +f 3444/3569/2238 3448/3863/2242 3449/3497/1984 +f 3450/3544/2005 3451/3864/2243 3452/3865/2244 +f 3450/3544/2005 3452/3865/2244 3453/3545/2008 +f 3451/3864/2243 3454/3866/2245 3455/3867/2246 +f 3451/3864/2243 3455/3867/2246 3452/3865/2244 +f 3452/3865/2244 3455/3867/2246 3456/3868/2247 +f 3452/3865/2244 3456/3868/2247 3457/3869/2248 +f 3453/3545/2008 3452/3865/2244 3457/3869/2248 +f 3453/3545/2008 3457/3869/2248 3458/3548/2009 +f 3459/3870/2249 3460/3871/2250 3461/3872/2251 +f 3459/3870/2249 3461/3872/2251 3462/3873/2252 +f 3463/3874/2250 3464/3875/2253 3465/3876/2254 +f 3463/3874/2250 3465/3876/2254 3466/3877/2255 +f 3461/3872/2251 3467/3878/2256 3468/3879/2257 +f 3461/3872/2251 3468/3879/2257 3469/3880/2258 +f 3462/3873/2252 3461/3872/2251 3469/3880/2258 +f 3462/3873/2252 3469/3880/2258 3470/3881/2259 +f 3471/3882/2260 3472/3883/2261 3473/3884/2262 +f 3471/3882/2260 3473/3884/2262 3474/3885/2263 +f 3472/3883/2261 3475/3886/2264 3476/3887/2265 +f 3472/3883/2261 3476/3887/2265 3473/3884/2262 +f 3473/3884/2262 3476/3887/2265 3477/3888/2266 +f 3473/3884/2262 3477/3888/2266 3478/3889/2267 +f 3474/3885/2263 3473/3884/2262 3478/3889/2267 +f 3474/3885/2263 3478/3889/2267 3479/3890/2268 +f 3404/3821/2199 3403/3820/2198 3480/3891/2269 +f 3404/3821/2199 3480/3891/2269 3481/3892/2270 +f 3403/3820/2198 3402/3819/2197 3482/3893/2271 +f 3403/3820/2198 3482/3893/2271 3480/3891/2269 +f 3480/3891/2269 3482/3893/2271 3483/3894/2272 +f 3480/3891/2269 3483/3894/2272 3484/3895/2273 +f 3481/3892/2270 3480/3891/2269 3484/3895/2273 +f 3481/3892/2270 3484/3895/2273 3485/3896/2274 +f 3436/3853/2231 3486/3897/2275 3487/3898/2276 +f 3436/3853/2231 3487/3898/2276 3437/3854/2232 +f 3486/3897/2275 3459/3870/2249 3462/3873/2252 +f 3486/3897/2275 3462/3873/2252 3487/3898/2276 +f 3487/3898/2276 3462/3873/2252 3470/3881/2259 +f 3487/3898/2276 3470/3881/2259 3488/3899/2277 +f 3437/3854/2232 3487/3898/2276 3488/3899/2277 +f 3437/3854/2232 3488/3899/2277 3438/3855/2233 +f 3489/3900/2278 3490/3901/2279 3491/3902/2280 +f 3489/3900/2278 3491/3902/2280 3492/3903/2281 +f 3490/3901/2279 3493/3904/2282 3494/3905/2283 +f 3490/3901/2279 3494/3905/2283 3491/3902/2280 +f 3491/3902/2280 3494/3905/2283 3495/3906/2284 +f 3491/3902/2280 3495/3906/2284 3496/3907/2285 +f 3492/3903/2281 3491/3902/2280 3496/3907/2285 +f 3492/3903/2281 3496/3907/2285 3497/3908/2286 +f 3498/3274/1898 3499/3909/2287 3500/3910/2288 +f 3498/3274/1898 3500/3910/2288 3501/3302/1908 +f 3499/3909/2287 3502/3911/2289 3503/3912/2290 +f 3499/3909/2287 3503/3912/2290 3500/3910/2288 +f 3504/3913/2291 3505/3914/2292 3506/3915/2293 +f 3504/3913/2291 3506/3915/2293 3507/3916/2294 +f 3501/3302/1908 3500/3910/2288 3508/3917/2295 +f 3501/3302/1908 3508/3917/2295 3509/3304/1909 +f 3510/3350/1977 3511/3347/1926 3512/3918/2296 +f 3510/3350/1977 3512/3918/2296 3513/3919/2297 +f 3511/3347/1926 3514/3346/1925 3515/3920/2298 +f 3511/3347/1926 3515/3920/2298 3512/3918/2296 +f 3512/3918/2296 3515/3920/2298 3516/3921/2299 +f 3512/3918/2296 3516/3921/2299 3517/3922/2300 +f 3513/3919/2297 3512/3918/2296 3517/3922/2300 +f 3513/3919/2297 3517/3922/2300 3518/3923/2301 +f 3519/3381/2302 3520/3924/2303 3521/3925/2304 +f 3519/3381/2302 3521/3925/2304 3522/3465/2305 +f 3520/3924/2303 3523/3926/2306 3524/3927/2307 +f 3520/3924/2303 3524/3927/2307 3521/3925/2304 +f 3521/3925/2304 3524/3927/2307 3525/3928/2308 +f 3521/3925/2304 3525/3928/2308 3526/3929/2309 +f 3522/3465/2305 3521/3925/2304 3526/3929/2309 +f 3522/3465/2305 3526/3929/2309 3527/3467/1973 +f 3528/3296/1906 3529/3294/1907 3530/3930/2310 +f 3528/3296/1906 3530/3930/2310 3531/3931/2311 +f 3529/3294/1907 3532/3262/1903 3533/3932/2312 +f 3529/3294/1907 3533/3932/2312 3530/3930/2310 +f 3530/3930/2310 3533/3932/2312 3534/3933/2313 +f 3530/3930/2310 3534/3933/2313 3535/3934/2314 +f 3531/3931/2311 3530/3930/2310 3535/3934/2314 +f 3531/3931/2311 3535/3934/2314 3536/3935/2315 +f 3537/3326/1918 3538/3936/2316 3539/3937/2317 +f 3537/3326/1918 3539/3937/2317 3540/3327/1917 +f 3538/3936/2316 3541/3938/2318 3542/3939/2319 +f 3538/3936/2316 3542/3939/2319 3539/3937/2317 +f 3539/3937/2317 3542/3939/2319 3543/3940/2320 +f 3539/3937/2317 3543/3940/2320 3544/3941/2321 +f 3540/3327/1917 3539/3937/2317 3544/3941/2321 +f 3540/3327/1917 3544/3941/2321 3545/3270/1896 +f 3546/3942/2322 3547/3943/2323 3548/3944/2324 +f 3546/3942/2322 3548/3944/2324 3549/3945/2325 +f 3547/3943/2323 3550/3946/2326 3551/3947/2327 +f 3547/3943/2323 3551/3947/2327 3548/3944/2324 +f 3548/3944/2324 3551/3947/2327 3552/3948/2328 +f 3548/3944/2324 3552/3948/2328 3553/3949/2329 +f 3549/3945/2325 3548/3944/2324 3553/3949/2329 +f 3549/3945/2325 3553/3949/2329 3554/3950/2330 +f 3555/3417/1951 3556/3951/2331 3557/3952/2332 +f 3555/3417/1951 3557/3952/2332 3558/3418/1952 +f 3556/3951/2331 3559/3953/2333 3560/3954/2334 +f 3556/3951/2331 3560/3954/2334 3557/3952/2332 +f 3557/3952/2332 3560/3954/2334 3561/3955/2335 +f 3557/3952/2332 3561/3955/2335 3562/3956/2336 +f 3558/3418/1952 3557/3952/2332 3562/3956/2336 +f 3558/3418/1952 3562/3956/2336 3563/3421/1953 +f 3564/3367/1936 3565/3365/1934 3566/3957/2337 +f 3564/3367/1936 3566/3957/2337 3567/3958/2338 +f 3565/3365/1934 3568/3286/1935 3569/3959/2339 +f 3565/3365/1934 3569/3959/2339 3566/3957/2337 +f 3566/3957/2337 3569/3959/2339 3570/3960/2340 +f 3566/3957/2337 3570/3960/2340 3571/3961/2341 +f 3567/3958/2338 3566/3957/2337 3571/3961/2341 +f 3567/3958/2338 3571/3961/2341 3572/3962/2342 +f 3573/3437/1957 3574/3963/2343 3575/3964/2344 +f 3573/3437/1957 3575/3964/2344 3576/3438/1958 +f 3574/3963/2343 3577/3965/2345 3578/3966/2346 +f 3574/3963/2343 3578/3966/2346 3575/3964/2344 +f 3575/3964/2344 3578/3966/2346 3579/3967/2347 +f 3575/3964/2344 3579/3967/2347 3580/3968/2348 +f 3576/3438/1958 3575/3964/2344 3580/3968/2348 +f 3576/3438/1958 3580/3968/2348 3581/3429/1954 +f 3582/3969/2349 3583/3970/2350 3584/3971/2351 +f 3582/3969/2349 3584/3971/2351 3585/3972/2352 +f 3583/3970/2350 3586/3973/2353 3587/3974/2354 +f 3583/3970/2350 3587/3974/2354 3584/3971/2351 +f 3584/3971/2351 3587/3974/2354 3588/3975/2355 +f 3584/3971/2351 3588/3975/2355 3589/3976/2356 +f 3585/3972/2352 3584/3971/2351 3589/3976/2356 +f 3585/3972/2352 3589/3976/2356 3590/3977/2357 +f 3590/3977/2357 3589/3976/2356 3591/3978/2358 +f 3590/3977/2357 3591/3978/2358 3592/3979/2359 +f 3589/3976/2356 3588/3975/2355 3593/3980/2360 +f 3589/3976/2356 3593/3980/2360 3591/3978/2358 +f 3591/3978/2358 3593/3980/2360 3594/3981/2361 +f 3591/3978/2358 3594/3981/2361 3595/3982/2362 +f 3592/3979/2359 3591/3978/2358 3595/3982/2362 +f 3592/3979/2359 3595/3982/2362 3596/3983/2363 +f 3597/3397/1945 3598/3984/2364 3599/3985/2365 +f 3597/3397/1945 3599/3985/2365 3600/3398/1947 +f 3598/3984/2364 3601/3986/2366 3602/3987/2367 +f 3598/3984/2364 3602/3987/2367 3599/3985/2365 +f 3599/3985/2365 3602/3987/2367 3603/3988/2368 +f 3599/3985/2365 3603/3988/2368 3604/3989/2369 +f 3600/3398/1947 3599/3985/2365 3604/3989/2369 +f 3600/3398/1947 3604/3989/2369 3605/3389/1944 +f 3606/3990/2370 3607/3991/2371 3608/3992/2372 +f 3606/3990/2370 3608/3992/2372 3609/3993/2373 +f 3607/3991/2371 3610/3994/2374 3611/3995/2375 +f 3607/3991/2371 3611/3995/2375 3608/3992/2372 +f 3608/3992/2372 3611/3995/2375 3612/3996/2376 +f 3608/3992/2372 3612/3996/2376 3613/3997/2377 +f 3609/3993/2373 3608/3992/2372 3613/3997/2377 +f 3609/3993/2373 3613/3997/2377 3614/3998/2378 +f 3614/3998/2378 3613/3997/2377 3615/3999/2379 +f 3614/3998/2378 3615/3999/2379 3616/4000/2380 +f 3613/3997/2377 3612/3996/2376 3617/4001/2381 +f 3613/3997/2377 3617/4001/2381 3615/3999/2379 +f 3615/3999/2379 3617/4001/2381 3618/4002/2382 +f 3615/3999/2379 3618/4002/2382 3619/4003/2383 +f 3616/4000/2380 3615/3999/2379 3619/4003/2383 +f 3616/4000/2380 3619/4003/2383 3620/4004/2384 +f 3620/4004/2384 3619/4003/2383 3621/4005/2385 +f 3620/4004/2384 3621/4005/2385 3622/4006/2386 +f 3619/4003/2383 3618/4002/2382 3623/4007/2387 +f 3619/4003/2383 3623/4007/2387 3621/4005/2385 +f 3621/4005/2385 3623/4007/2387 3624/4008/2388 +f 3621/4005/2385 3624/4008/2388 3625/4009/2389 +f 3622/4006/2386 3621/4005/2385 3625/4009/2389 +f 3622/4006/2386 3625/4009/2389 3626/4010/2390 +f 3546/3942/2322 3549/3945/2325 3627/4011/2391 +f 3546/3942/2322 3627/4011/2391 3628/4012/2392 +f 3549/3945/2325 3554/3950/2330 3629/4013/2393 +f 3549/3945/2325 3629/4013/2393 3627/4011/2391 +f 3627/4011/2391 3629/4013/2393 3630/4014/2394 +f 3627/4011/2391 3630/4014/2394 3631/4015/2395 +f 3628/4012/2392 3627/4011/2391 3631/4015/2395 +f 3628/4012/2392 3631/4015/2395 3632/4016/2396 +f 3633/3338/2397 3634/3335/2398 3635/4017/2399 +f 3633/3338/2397 3635/4017/2399 3636/4018/2400 +f 3634/3335/2398 3637/3334/1920 3638/4019/2401 +f 3634/3335/2398 3638/4019/2401 3635/4017/2399 +f 3635/4017/2399 3638/4019/2401 3639/4020/2402 +f 3635/4017/2399 3639/4020/2402 3640/4021/2403 +f 3636/4018/2400 3635/4017/2399 3640/4021/2403 +f 3636/4018/2400 3640/4021/2403 3641/4022/2404 +f 3642/4023/2405 3643/4024/2406 3644/4025/2407 +f 3642/4023/2405 3644/4025/2407 3645/4026/2408 +f 3643/4024/2406 3646/4027/2409 3647/4028/2410 +f 3643/4024/2406 3647/4028/2410 3644/4025/2407 +f 3644/4025/2407 3647/4028/2410 3648/4029/2411 +f 3644/4025/2407 3648/4029/2411 3649/4030/2412 +f 3645/4026/2408 3644/4025/2407 3649/4030/2412 +f 3645/4026/2408 3649/4030/2412 3650/4031/2413 +f 3545/3270/1896 3544/3941/2321 3651/4032/2414 +f 3545/3270/1896 3651/4032/2414 3652/3271/1897 +f 3544/3941/2321 3543/3940/2320 3653/4033/2415 +f 3544/3941/2321 3653/4033/2415 3651/4032/2414 +f 3651/4032/2414 3653/4033/2415 3502/3911/2289 +f 3651/4032/2414 3502/3911/2289 3499/3909/2287 +f 3652/3271/1897 3651/4032/2414 3499/3909/2287 +f 3652/3271/1897 3499/3909/2287 3498/3274/1898 +f 3654/4034/2416 3655/4035/2417 3656/4036/2418 +f 3654/4034/2416 3656/4036/2418 3657/4037/2419 +f 3655/4035/2417 3658/4038/2420 3659/4039/2421 +f 3655/4035/2417 3659/4039/2421 3656/4036/2418 +f 3656/4036/2418 3659/4039/2421 3660/4040/2422 +f 3656/4036/2418 3660/4040/2422 3661/4041/2423 +f 3657/4037/2419 3656/4036/2418 3661/4041/2423 +f 3657/4037/2419 3661/4041/2423 3662/4042/2424 +f 3663/4043/2425 3664/4044/2077 3665/4045/2426 +f 3663/4043/2425 3665/4045/2426 3666/4046/2427 +f 3664/4044/2077 3667/4047/2076 3668/4048/2428 +f 3664/4044/2077 3668/4048/2428 3665/4045/2426 +f 3665/4045/2426 3668/4048/2428 3669/4049/2429 +f 3665/4045/2426 3669/4049/2429 3670/4050/2430 +f 3666/4046/2427 3665/4045/2426 3670/4050/2430 +f 3666/4046/2427 3670/4050/2430 3671/4051/2431 +f 3672/4052/2432 3673/4053/2433 3674/4054/2434 +f 3672/4052/2432 3674/4054/2434 3675/4055/2435 +f 3673/4053/2433 3676/4056/2436 3677/4057/2437 +f 3673/4053/2433 3677/4057/2437 3674/4054/2434 +f 3674/4054/2434 3677/4057/2437 3678/4058/2438 +f 3674/4054/2434 3678/4058/2438 3679/4059/2439 +f 3675/4055/2435 3674/4054/2434 3679/4059/2439 +f 3675/4055/2435 3679/4059/2439 3680/4060/2440 +f 3681/4061/2441 3682/4062/2442 3683/4063/2443 +f 3681/4061/2441 3683/4063/2443 3684/4064/2444 +f 3682/4062/2442 3685/4065/2445 3686/4066/2446 +f 3682/4062/2442 3686/4066/2446 3683/4063/2443 +f 3683/4063/2443 3686/4066/2446 3687/4067/2447 +f 3683/4063/2443 3687/4067/2447 3688/4068/2448 +f 3684/4064/2444 3683/4063/2443 3688/4068/2448 +f 3684/4064/2444 3688/4068/2448 3689/4069/2449 +f 3690/4070/2450 3691/4071/2207 3692/4072/2451 +f 3690/4070/2450 3692/4072/2451 3693/4073/2452 +f 3691/4071/2207 3694/4074/2206 3695/4075/2453 +f 3691/4071/2207 3695/4075/2453 3692/4072/2451 +f 3692/4072/2451 3695/4075/2453 3696/4076/2454 +f 3692/4072/2451 3696/4076/2454 3697/4077/2455 +f 3693/4073/2452 3692/4072/2451 3697/4077/2455 +f 3693/4073/2452 3697/4077/2455 3698/4078/2456 +f 3550/3946/2326 3699/4079/2457 3700/4080/2458 +f 3550/3946/2326 3700/4080/2458 3551/3947/2327 +f 3699/4079/2457 3654/4034/2416 3657/4037/2419 +f 3699/4079/2457 3657/4037/2419 3700/4080/2458 +f 3700/4080/2458 3657/4037/2419 3662/4042/2424 +f 3700/4080/2458 3662/4042/2424 3701/4081/2459 +f 3551/3947/2327 3700/4080/2458 3701/4081/2459 +f 3551/3947/2327 3701/4081/2459 3552/3948/2328 +f 3702/4082/2460 3703/4083/2461 3704/4084/2462 +f 3702/4082/2460 3704/4084/2462 3705/4085/2463 +f 3703/4083/2461 3706/4086/2464 3707/4087/2465 +f 3703/4083/2461 3707/4087/2465 3704/4084/2462 +f 3704/4084/2462 3707/4087/2465 3708/4088/2466 +f 3704/4084/2462 3708/4088/2466 3709/4089/2467 +f 3705/4085/2463 3704/4084/2462 3709/4089/2467 +f 3705/4085/2463 3709/4089/2467 3710/4090/2468 +f 3646/4027/2409 3711/4091/2469 3712/4092/2470 +f 3646/4027/2409 3712/4092/2470 3647/4028/2410 +f 3711/4091/2469 3690/4070/2450 3693/4073/2452 +f 3711/4091/2469 3693/4073/2452 3712/4092/2470 +f 3712/4092/2470 3693/4073/2452 3698/4078/2456 +f 3712/4092/2470 3698/4078/2456 3713/4093/2471 +f 3647/4028/2410 3712/4092/2470 3713/4093/2471 +f 3647/4028/2410 3713/4093/2471 3648/4029/2411 +f 3680/4060/2440 3679/4059/2439 3714/4094/2472 +f 3680/4060/2440 3714/4094/2472 3715/4095/2473 +f 3679/4059/2439 3678/4058/2438 3716/4096/2474 +f 3679/4059/2439 3716/4096/2474 3714/4094/2472 +f 3714/4094/2472 3716/4096/2474 3717/4097/2475 +f 3714/4094/2472 3717/4097/2475 3718/4098/2476 +f 3715/4095/2473 3714/4094/2472 3718/4098/2476 +f 3715/4095/2473 3718/4098/2476 3719/4099/2477 +f 3720/4100/2478 3721/4101/2479 3722/4102/2480 +f 3720/4100/2478 3722/4102/2480 3723/4103/2481 +f 3721/4101/2479 3724/4104/2482 3725/4105/2483 +f 3721/4101/2479 3725/4105/2483 3722/4102/2480 +f 3722/4102/2480 3725/4105/2483 3726/4106/2484 +f 3722/4102/2480 3726/4106/2484 3727/4107/2485 +f 3723/4103/2481 3722/4102/2480 3727/4107/2485 +f 3723/4103/2481 3727/4107/2485 3728/4108/2486 +f 3729/4109/2487 3730/4110/2488 3731/4111/2489 +f 3729/4109/2487 3731/4111/2489 3732/4112/2490 +f 3730/4110/2488 3733/4113/2491 3734/4114/2492 +f 3730/4110/2488 3734/4114/2492 3731/4111/2489 +f 3731/4111/2489 3734/4114/2492 3735/4115/2493 +f 3731/4111/2489 3735/4115/2493 3736/4116/2494 +f 3732/4112/2490 3731/4111/2489 3736/4116/2494 +f 3732/4112/2490 3736/4116/2494 3737/4117/2495 +f 3738/4118/2496 3739/4119/2497 3740/4120/2498 +f 3738/4118/2496 3740/4120/2498 3741/4121/2499 +f 3739/4119/2497 3720/4100/2478 3723/4103/2481 +f 3739/4119/2497 3723/4103/2481 3740/4120/2498 +f 3740/4120/2498 3723/4103/2481 3728/4108/2486 +f 3740/4120/2498 3728/4108/2486 3742/4122/2500 +f 3741/4121/2499 3740/4120/2498 3742/4122/2500 +f 3741/4121/2499 3742/4122/2500 3743/4123/2501 +f 3744/4124/2502 3745/4125/2503 3746/4126/2504 +f 3744/4124/2502 3746/4126/2504 3747/4127/2505 +f 3745/4125/2503 3748/4128/2506 3749/4129/2507 +f 3745/4125/2503 3749/4129/2507 3746/4126/2504 +f 3746/4126/2504 3749/4129/2507 3750/4130/2508 +f 3746/4126/2504 3750/4130/2508 3751/4131/2509 +f 3747/4127/2505 3746/4126/2504 3751/4131/2509 +f 3747/4127/2505 3751/4131/2509 3752/4132/2510 +f 3753/4133/2187 3754/4134/2511 3755/4135/2512 +f 3753/4133/2187 3755/4135/2512 3756/4136/2513 +f 3754/4134/2511 3757/4137/2514 3758/4138/2515 +f 3754/4134/2511 3758/4138/2515 3755/4135/2512 +f 3755/4135/2512 3758/4138/2515 3759/4139/2516 +f 3755/4135/2512 3759/4139/2516 3760/4140/2517 +f 3756/4136/2513 3755/4135/2512 3760/4140/2517 +f 3756/4136/2513 3760/4140/2517 3761/4141/2518 +f 3762/4142/2519 3763/4143/2520 3764/4144/2521 +f 3762/4142/2519 3764/4144/2521 3765/4145/2522 +f 3763/4143/2520 3766/4146/2523 3767/4147/2524 +f 3763/4143/2520 3767/4147/2524 3764/4144/2521 +f 3764/4144/2521 3767/4147/2524 3768/4148/2525 +f 3764/4144/2521 3768/4148/2525 3769/4149/2526 +f 3765/4145/2522 3764/4144/2521 3769/4149/2526 +f 3765/4145/2522 3769/4149/2526 3770/4150/2527 +f 3771/4151/2528 3772/4152/2529 3773/4153/2530 +f 3771/4151/2528 3773/4153/2530 3774/4154/2531 +f 3772/4152/2529 3753/4133/2187 3756/4136/2513 +f 3772/4152/2529 3756/4136/2513 3773/4153/2530 +f 3773/4153/2530 3756/4136/2513 3761/4141/2518 +f 3773/4153/2530 3761/4141/2518 3775/4155/2532 +f 3774/4154/2531 3773/4153/2530 3775/4155/2532 +f 3774/4154/2531 3775/4155/2532 3776/4156/2533 +f 3766/4146/2523 3777/4157/2534 3778/4158/2535 +f 3766/4146/2523 3778/4158/2535 3767/4147/2524 +f 3777/4157/2534 3779/4159/2260 3780/4160/2536 +f 3777/4157/2534 3780/4160/2536 3778/4158/2535 +f 3778/4158/2535 3780/4160/2536 3781/4161/2537 +f 3778/4158/2535 3781/4161/2537 3782/4162/2538 +f 3767/4147/2524 3778/4158/2535 3782/4162/2538 +f 3767/4147/2524 3782/4162/2538 3768/4148/2525 +f 3783/4163/2099 3784/4164/2539 3785/4165/2540 +f 3783/4163/2099 3785/4165/2540 3786/4166/2541 +f 3787/4167/2539 3788/4168/2097 3789/4169/2542 +f 3787/4167/2539 3789/4169/2542 3790/4170/2540 +f 3790/4170/2540 3789/4169/2542 3791/4171/2543 +f 3790/4170/2540 3791/4171/2543 3792/4172/2544 +f 3786/4166/2541 3785/4165/2540 3793/4173/2544 +f 3786/4166/2541 3793/4173/2544 3794/4174/2545 +f 3795/4175/2546 3796/4176/2547 3797/4177/2548 +f 3795/4175/2546 3797/4177/2548 3798/4178/2549 +f 3796/4176/2547 3799/4179/2550 3800/4180/2551 +f 3796/4176/2547 3800/4180/2551 3797/4177/2548 +f 3797/4177/2548 3800/4180/2551 3801/4181/2552 +f 3797/4177/2548 3801/4181/2552 3802/4182/2553 +f 3798/4178/2549 3797/4177/2548 3802/4182/2553 +f 3798/4178/2549 3802/4182/2553 3803/4183/2340 +f 3804/4184/2083 3805/4185/2554 3806/4186/2555 +f 3804/4184/2083 3806/4186/2555 3807/4187/2556 +f 3805/4185/2554 3808/4188/2081 3809/4189/2557 +f 3805/4185/2554 3809/4189/2557 3806/4186/2555 +f 3806/4186/2555 3809/4189/2557 3810/4190/2558 +f 3806/4186/2555 3810/4190/2558 3811/4191/2559 +f 3807/4187/2556 3806/4186/2555 3811/4191/2559 +f 3807/4187/2556 3811/4191/2559 3812/4192/2560 +f 3748/4128/2506 3813/4193/2561 3814/4194/2562 +f 3748/4128/2506 3814/4194/2562 3749/4129/2507 +f 3813/4193/2561 3815/4195/2563 3816/4196/2564 +f 3813/4193/2561 3816/4196/2564 3814/4194/2562 +f 3814/4194/2562 3816/4196/2564 3817/4197/2565 +f 3814/4194/2562 3817/4197/2565 3818/4198/2566 +f 3749/4129/2507 3814/4194/2562 3818/4198/2566 +f 3749/4129/2507 3818/4198/2566 3750/4130/2508 +f 3788/4168/2097 3819/4199/2567 3820/4200/2568 +f 3788/4168/2097 3820/4200/2568 3789/4169/2542 +f 3819/4199/2567 3821/4201/2569 3822/4202/2570 +f 3819/4199/2567 3822/4202/2570 3820/4200/2568 +f 3820/4200/2568 3822/4202/2570 3823/4203/2571 +f 3820/4200/2568 3823/4203/2571 3824/4204/2572 +f 3789/4169/2542 3820/4200/2568 3824/4204/2572 +f 3789/4169/2542 3824/4204/2572 3791/4171/2543 +f 3825/4205/2573 3826/4206/2574 3827/4207/2575 +f 3825/4205/2573 3827/4207/2575 3828/4208/2576 +f 3826/4206/2574 3829/4209/2577 3830/4210/2578 +f 3826/4206/2574 3830/4210/2578 3827/4207/2575 +f 3827/4207/2575 3830/4210/2578 3831/4211/2579 +f 3827/4207/2575 3831/4211/2579 3832/4212/2580 +f 3828/4208/2576 3827/4207/2575 3832/4212/2580 +f 3828/4208/2576 3832/4212/2580 3833/4213/2581 +f 3834/4214/2113 3835/4215/2582 3836/4216/2583 +f 3834/4214/2113 3836/4216/2583 3837/4217/2584 +f 3835/4215/2582 3804/4184/2083 3807/4187/2556 +f 3835/4215/2582 3807/4187/2556 3836/4216/2583 +f 3836/4216/2583 3807/4187/2556 3812/4192/2560 +f 3836/4216/2583 3812/4192/2560 3838/4218/2585 +f 3837/4217/2584 3836/4216/2583 3838/4218/2585 +f 3837/4217/2584 3838/4218/2585 3839/4219/2586 +f 3799/4179/2550 3840/4220/2587 3841/4221/2588 +f 3799/4179/2550 3841/4221/2588 3800/4180/2551 +f 3840/4220/2587 3842/4222/2589 3843/4223/2590 +f 3840/4220/2587 3843/4223/2590 3841/4221/2588 +f 3841/4221/2588 3843/4223/2590 3844/4224/2591 +f 3841/4221/2588 3844/4224/2591 3845/4225/2592 +f 3800/4180/2551 3841/4221/2588 3845/4225/2592 +f 3800/4180/2551 3845/4225/2592 3801/4181/2552 +f 3846/4226/2593 3847/4227/2594 3848/4228/2595 +f 3846/4226/2593 3848/4228/2595 3849/4229/2596 +f 3847/4227/2594 3850/4230/2128 3851/4231/2597 +f 3847/4227/2594 3851/4231/2597 3848/4228/2595 +f 3848/4228/2595 3851/4231/2597 3852/4232/2598 +f 3848/4228/2595 3852/4232/2598 3853/4233/2599 +f 3849/4229/2596 3848/4228/2595 3853/4233/2599 +f 3849/4229/2596 3853/4233/2599 3854/4234/2600 +f 3855/4235/2601 3856/4236/2602 3857/4237/2603 +f 3855/4235/2601 3857/4237/2603 3858/4238/2604 +f 3856/4236/2602 3859/4239/2605 3860/4240/2606 +f 3856/4236/2602 3860/4240/2606 3857/4237/2603 +f 3857/4237/2603 3860/4240/2606 3861/4241/2607 +f 3857/4237/2603 3861/4241/2607 3862/4242/2608 +f 3858/4238/2604 3857/4237/2603 3862/4242/2608 +f 3858/4238/2604 3862/4242/2608 3863/4243/2609 +f 3864/4244/2610 3865/4245/2611 3866/4246/2612 +f 3864/4244/2610 3866/4246/2612 3867/4247/2613 +f 3865/4245/2611 3868/4248/2614 3869/4249/2615 +f 3865/4245/2611 3869/4249/2615 3866/4246/2612 +f 3866/4246/2612 3869/4249/2615 3870/4250/2616 +f 3866/4246/2612 3870/4250/2616 3871/4251/2617 +f 3867/4247/2613 3866/4246/2612 3871/4251/2617 +f 3867/4247/2613 3871/4251/2617 3872/4252/2134 +f 3873/4253/2618 3874/4254/2619 3875/4255/2620 +f 3873/4253/2618 3875/4255/2620 3876/4256/2621 +f 3874/4254/2619 3877/4257/2622 3878/4258/2623 +f 3874/4254/2619 3878/4258/2623 3875/4255/2620 +f 3875/4255/2620 3878/4258/2623 3879/4259/2624 +f 3875/4255/2620 3879/4259/2624 3880/4260/2625 +f 3876/4256/2621 3875/4255/2620 3880/4260/2625 +f 3876/4256/2621 3880/4260/2625 3881/4261/2626 +f 3882/4262/2627 3883/4263/2628 3884/4264/2629 +f 3882/4262/2627 3884/4264/2629 3885/4265/2630 +f 3883/4263/2628 3886/4266/2631 3887/4267/2632 +f 3883/4263/2628 3887/4267/2632 3884/4264/2629 +f 3884/4264/2629 3887/4267/2632 3868/4248/2614 +f 3884/4264/2629 3868/4248/2614 3865/4245/2611 +f 3885/4265/2630 3884/4264/2629 3865/4245/2611 +f 3885/4265/2630 3865/4245/2611 3864/4244/2610 +f 3888/4268/2633 3889/4269/2634 3890/4270/2635 +f 3888/4268/2633 3890/4270/2635 3891/4271/2636 +f 3889/4269/2634 3892/4272/2637 3893/4273/2638 +f 3889/4269/2634 3893/4273/2638 3890/4270/2635 +f 3890/4270/2635 3893/4273/2638 3894/4274/2639 +f 3890/4270/2635 3894/4274/2639 3895/4275/2640 +f 3891/4271/2636 3890/4270/2635 3895/4275/2640 +f 3891/4271/2636 3895/4275/2640 3896/4276/2641 +f 3897/4277/2642 3898/4278/2643 3899/4279/2644 +f 3897/4277/2642 3899/4279/2644 3900/4280/2121 +f 3898/4278/2643 3901/4281/2645 3902/4282/2646 +f 3898/4278/2643 3902/4282/2646 3899/4279/2644 +f 3899/4279/2644 3902/4282/2646 3903/4283/2647 +f 3899/4279/2644 3903/4283/2647 3904/4284/2648 +f 3900/4280/2121 3899/4279/2644 3904/4284/2648 +f 3900/4280/2121 3904/4284/2648 3905/4285/2649 +f 3906/4286/2650 3907/4287/2651 3908/4288/2652 +f 3906/4286/2650 3908/4288/2652 3909/4289/2653 +f 3907/4287/2651 3762/4142/2519 3765/4145/2522 +f 3907/4287/2651 3765/4145/2522 3908/4288/2652 +f 3908/4288/2652 3765/4145/2522 3770/4150/2527 +f 3908/4288/2652 3770/4150/2527 3910/4290/2654 +f 3909/4289/2653 3908/4288/2652 3910/4290/2654 +f 3909/4289/2653 3910/4290/2654 3911/4291/2655 +f 3912/4292/2656 3913/4293/2657 3914/4294/2658 +f 3912/4292/2656 3914/4294/2658 3915/4295/2659 +f 3913/4293/2657 3916/4296/2660 3917/4297/2661 +f 3913/4293/2657 3917/4297/2661 3914/4294/2658 +f 3914/4294/2658 3917/4297/2661 3918/4298/2662 +f 3914/4294/2658 3918/4298/2662 3919/4299/2663 +f 3915/4295/2659 3914/4294/2658 3919/4299/2663 +f 3915/4295/2659 3919/4299/2663 3920/4300/2664 +f 3921/4301/2665 3922/4302/2666 3923/4303/2667 +f 3921/4301/2665 3923/4303/2667 3924/4304/2668 +f 3922/4302/2666 3925/4305/2669 3926/4306/2670 +f 3922/4302/2666 3926/4306/2670 3923/4303/2667 +f 3923/4303/2667 3926/4306/2670 3927/4307/2671 +f 3923/4303/2667 3927/4307/2671 3928/4308/2672 +f 3924/4304/2668 3923/4303/2667 3928/4308/2672 +f 3924/4304/2668 3928/4308/2672 3929/4309/2673 +f 3930/4310/2674 3931/4311/2675 3932/4312/2676 +f 3930/4310/2674 3932/4312/2676 3933/4313/2677 +f 3931/4311/2675 3744/4124/2502 3747/4127/2505 +f 3931/4311/2675 3747/4127/2505 3932/4312/2676 +f 3932/4312/2676 3747/4127/2505 3752/4132/2510 +f 3932/4312/2676 3752/4132/2510 3934/4314/2678 +f 3933/4313/2677 3932/4312/2676 3934/4314/2678 +f 3933/4313/2677 3934/4314/2678 3935/4315/2679 +f 3936/4316/2680 3937/4317/2681 3938/4318/2682 +f 3936/4316/2680 3938/4318/2682 3939/4319/2683 +f 3937/4317/2681 3940/4320/2684 3941/4321/2685 +f 3937/4317/2681 3941/4321/2685 3938/4318/2682 +f 3938/4318/2682 3941/4321/2685 3942/4322/2686 +f 3938/4318/2682 3942/4322/2686 3943/4323/2687 +f 3939/4319/2683 3938/4318/2682 3943/4323/2687 +f 3939/4319/2683 3943/4323/2687 3944/4324/2688 +f 3757/4137/2514 3945/4325/2689 3946/4326/2690 +f 3757/4137/2514 3946/4326/2690 3758/4138/2515 +f 3945/4325/2689 3846/4226/2593 3849/4229/2596 +f 3945/4325/2689 3849/4229/2596 3946/4326/2690 +f 3946/4326/2690 3849/4229/2596 3854/4234/2600 +f 3946/4326/2690 3854/4234/2600 3947/4327/2691 +f 3758/4138/2515 3946/4326/2690 3947/4327/2691 +f 3758/4138/2515 3947/4327/2691 3759/4139/2516 +f 3948/4328/2692 3949/4329/2693 3950/4330/2694 +f 3948/4328/2692 3950/4330/2694 3951/4331/2695 +f 3949/4329/2693 3795/4175/2546 3798/4178/2549 +f 3949/4329/2693 3798/4178/2549 3950/4330/2694 +f 3950/4330/2694 3798/4178/2549 3803/4183/2340 +f 3950/4330/2694 3803/4183/2340 3952/4332/2696 +f 3951/4331/2695 3950/4330/2694 3952/4332/2696 +f 3951/4331/2695 3952/4332/2696 3953/4333/2697 +f 3920/4300/2664 3919/4299/2663 3954/4334/2698 +f 3920/4300/2664 3954/4334/2698 3955/4335/2699 +f 3919/4299/2663 3918/4298/2662 3956/4336/2700 +f 3919/4299/2663 3956/4336/2700 3954/4334/2698 +f 3954/4334/2698 3956/4336/2700 3957/4337/2701 +f 3954/4334/2698 3957/4337/2701 3958/4338/2702 +f 3955/4335/2699 3954/4334/2698 3958/4338/2702 +f 3955/4335/2699 3958/4338/2702 3959/4339/2231 +f 3960/4340/2703 3961/4341/2704 3962/4342/2705 +f 3960/4340/2703 3962/4342/2705 3963/4343/2706 +f 3961/4341/2704 3964/4344/2707 3965/4345/2708 +f 3961/4341/2704 3965/4345/2708 3962/4342/2705 +f 3962/4342/2705 3965/4345/2708 3966/4346/2709 +f 3962/4342/2705 3966/4346/2709 3967/4347/2710 +f 3963/4343/2706 3962/4342/2705 3967/4347/2710 +f 3963/4343/2706 3967/4347/2710 3968/4348/2445 +f 3969/4349/2711 3970/4350/2712 3971/4351/2713 +f 3969/4349/2711 3971/4351/2713 3972/4352/2714 +f 3970/4350/2712 3973/4353/2715 3974/4354/2716 +f 3970/4350/2712 3974/4354/2716 3971/4351/2713 +f 3971/4351/2713 3974/4354/2716 3975/4355/2717 +f 3971/4351/2713 3975/4355/2717 3976/4356/2718 +f 3972/4352/2714 3971/4351/2713 3976/4356/2718 +f 3972/4352/2714 3976/4356/2718 3977/4357/2719 +f 3978/4358/2249 3979/4359/2720 3980/4360/2721 +f 3978/4358/2249 3980/4360/2721 3463/3874/2250 +f 3979/4359/2720 3981/4361/2722 3982/4362/2723 +f 3979/4359/2720 3982/4362/2723 3980/4360/2721 +f 3980/4360/2721 3982/4362/2723 3983/4363/2724 +f 3980/4360/2721 3983/4363/2724 3984/4364/2725 +f 3463/3874/2250 3980/4360/2721 3984/4364/2725 +f 3463/3874/2250 3984/4364/2725 3464/3875/2253 +f 3985/4365/2726 3986/4366/2727 3987/4367/2728 +f 3985/4365/2726 3987/4367/2728 3988/4368/2729 +f 3986/4366/2727 3506/3915/2293 3505/3914/2292 +f 3986/4366/2727 3505/3914/2292 3987/4367/2728 +f 3987/4367/2728 3505/3914/2292 3989/4369/2730 +f 3987/4367/2728 3989/4369/2730 3990/4370/2731 +f 3988/4368/2729 3987/4367/2728 3990/4370/2731 +f 3988/4368/2729 3990/4370/2731 3991/4371/2732 +f 3992/4372/2176 3993/4373/2733 3994/4374/2734 +f 3992/4372/2176 3994/4374/2734 3995/4375/2177 +f 3993/4373/2733 3996/4376/2735 3997/4377/2736 +f 3993/4373/2733 3997/4377/2736 3994/4374/2734 +f 3994/4374/2734 3997/4377/2736 3829/4209/2577 +f 3994/4374/2734 3829/4209/2577 3826/4206/2574 +f 3995/4375/2177 3994/4374/2734 3826/4206/2574 +f 3995/4375/2177 3826/4206/2574 3825/4205/2573 +f 3998/4378/2737 3999/4379/2738 4000/4380/2739 +f 3998/4378/2737 4000/4380/2739 4001/4381/2740 +f 3999/4379/2738 4002/4382/2741 4003/4383/2742 +f 3999/4379/2738 4003/4383/2742 4000/4380/2739 +f 4000/4380/2739 4003/4383/2742 3973/4353/2715 +f 4000/4380/2739 3973/4353/2715 3970/4350/2712 +f 4001/4381/2740 4000/4380/2739 3970/4350/2712 +f 4001/4381/2740 3970/4350/2712 3969/4349/2711 +f 4004/4384/2743 4005/4385/2744 4006/4386/2745 +f 4004/4384/2743 4006/4386/2745 4007/4387/2746 +f 4005/4385/2744 4008/4388/2747 4009/4389/2748 +f 4005/4385/2744 4009/4389/2748 4006/4386/2745 +f 4006/4386/2745 4009/4389/2748 4010/4390/2749 +f 4006/4386/2745 4010/4390/2749 4011/4391/2750 +f 4007/4387/2746 4006/4386/2745 4011/4391/2750 +f 4007/4387/2746 4011/4391/2750 4012/4392/2751 +f 4013/4393/2752 4014/4394/2753 4015/4395/2754 +f 4013/4393/2752 4015/4395/2754 4016/4396/2755 +f 4014/4394/2753 3783/4163/2099 3786/4166/2541 +f 4014/4394/2753 3786/4166/2541 4015/4395/2754 +f 4015/4395/2754 3786/4166/2541 3794/4174/2545 +f 4015/4395/2754 3794/4174/2545 4017/4397/2756 +f 4016/4396/2755 4015/4395/2754 4017/4397/2756 +f 4016/4396/2755 4017/4397/2756 4018/4398/2757 +f 4019/4399/2758 4020/4400/2759 4021/4401/2760 +f 4019/4399/2758 4021/4401/2760 4022/4402/2761 +f 4020/4400/2759 4023/4403/2762 4024/4404/2763 +f 4020/4400/2759 4024/4404/2763 4021/4401/2760 +f 4025/4405/2764 4026/4406/2285 4027/4407/2284 +f 4025/4405/2764 4027/4407/2284 4028/4408/2765 +f 4029/4409/2766 4025/4405/2764 4028/4408/2765 +f 4029/4409/2766 4028/4408/2765 4030/4410/2767 +f 4031/4411/2768 4032/4412/2769 4033/4413/2770 +f 4031/4411/2768 4033/4413/2770 4034/4414/2771 +f 4032/4412/2769 4035/4415/2772 4036/4416/2773 +f 4032/4412/2769 4036/4416/2773 4033/4413/2770 +f 4033/4413/2770 4036/4416/2773 4037/4417/2774 +f 4033/4413/2770 4037/4417/2774 4038/4418/2775 +f 4034/4414/2771 4033/4413/2770 4038/4418/2775 +f 4034/4414/2771 4038/4418/2775 4039/4419/2776 +f 4040/4420/2777 4041/4421/2778 4042/4422/2779 +f 4040/4420/2777 4042/4422/2779 4043/4423/2780 +f 4044/4424/2781 4045/4425/2782 4046/4426/2783 +f 4044/4424/2781 4046/4426/2783 4047/4427/2784 +f 4047/4427/2784 4046/4426/2783 4048/4428/2785 +f 4047/4427/2784 4048/4428/2785 4049/4429/2786 +f 4043/4423/2780 4042/4422/2779 4050/4430/2787 +f 4043/4423/2780 4050/4430/2787 4051/4431/2788 +f 4052/4432/2148 4053/4433/2789 4054/4434/2790 +f 4052/4432/2148 4054/4434/2790 4055/4435/2791 +f 4053/4433/2789 4056/4436/2792 4057/4437/2793 +f 4053/4433/2789 4057/4437/2793 4054/4434/2790 +f 4054/4434/2790 4057/4437/2793 4058/4438/2794 +f 4054/4434/2790 4058/4438/2794 4059/4439/2795 +f 4055/4435/2791 4054/4434/2790 4059/4439/2795 +f 4055/4435/2791 4059/4439/2795 4060/4440/2154 +f 4061/4441/2796 4062/4442/2797 4063/4443/2798 +f 4061/4441/2796 4063/4443/2798 4064/4444/2799 +f 4062/4442/2797 4065/4445/2800 4066/4446/2801 +f 4062/4442/2797 4066/4446/2801 4063/4443/2798 +f 4067/4447/2802 4068/4448/2803 4069/4449/2804 +f 4067/4447/2802 4069/4449/2804 4070/4450/2805 +f 4071/4451/2806 4067/4447/2802 4070/4450/2805 +f 4071/4451/2806 4070/4450/2805 4072/4452/2807 +f 3977/4357/2719 3976/4356/2718 4073/4453/2808 +f 3977/4357/2719 4073/4453/2808 4074/4454/2092 +f 3976/4356/2718 3975/4355/2717 4075/4455/2809 +f 3976/4356/2718 4075/4455/2809 4073/4453/2808 +f 4073/4453/2808 4075/4455/2809 4076/4456/2810 +f 4073/4453/2808 4076/4456/2810 4077/4457/2811 +f 4074/4454/2092 4073/4453/2808 4077/4457/2811 +f 4074/4454/2092 4077/4457/2811 4078/4458/2812 +f 3863/4243/2609 3862/4242/2608 4079/4459/2813 +f 3863/4243/2609 4079/4459/2813 4080/4460/2814 +f 3862/4242/2608 3861/4241/2607 4081/4461/2815 +f 3862/4242/2608 4081/4461/2815 4079/4459/2813 +f 4079/4459/2813 4081/4461/2815 4082/4462/2816 +f 4079/4459/2813 4082/4462/2816 4083/4463/2817 +f 4080/4460/2814 4079/4459/2813 4083/4463/2817 +f 4080/4460/2814 4083/4463/2817 4084/4464/2818 +f 4085/4465/2819 4086/4466/2820 4087/4467/2821 +f 4085/4465/2819 4087/4467/2821 4088/4468/2822 +f 4086/4466/2820 4089/4469/2278 4090/4470/2823 +f 4086/4466/2820 4090/4470/2823 4087/4467/2821 +f 4087/4467/2821 4090/4470/2823 4023/4403/2762 +f 4087/4467/2821 4023/4403/2762 4020/4400/2759 +f 4088/4468/2822 4087/4467/2821 4020/4400/2759 +f 4088/4468/2822 4020/4400/2759 4019/4399/2758 +f 3833/4213/2581 3832/4212/2580 4091/4471/2824 +f 3833/4213/2581 4091/4471/2824 4092/4472/2825 +f 3832/4212/2580 3831/4211/2579 4093/4473/2826 +f 3832/4212/2580 4093/4473/2826 4091/4471/2824 +f 4091/4471/2824 4093/4473/2826 4094/4474/2827 +f 4091/4471/2824 4094/4474/2827 4095/4475/2828 +f 4092/4472/2825 4091/4471/2824 4095/4475/2828 +f 4092/4472/2825 4095/4475/2828 4096/4476/2829 +f 4097/4477/2830 4098/4478/2831 4099/4479/2832 +f 4097/4477/2830 4099/4479/2832 4100/4480/2833 +f 4098/4478/2831 4101/4481/2834 4102/4482/2367 +f 4098/4478/2831 4102/4482/2367 4099/4479/2832 +f 4099/4479/2832 4102/4482/2367 4103/4483/2835 +f 4099/4479/2832 4103/4483/2835 4104/4484/2836 +f 4100/4480/2833 4099/4479/2832 4104/4484/2836 +f 4100/4480/2833 4104/4484/2836 4105/4485/2837 +f 4106/4486/2838 4107/4487/2839 4108/4488/2840 +f 4106/4486/2838 4108/4488/2840 4109/4489/2841 +f 4107/4487/2839 4084/4464/2818 4083/4463/2817 +f 4107/4487/2839 4083/4463/2817 4108/4488/2840 +f 4108/4488/2840 4083/4463/2817 4082/4462/2816 +f 4108/4488/2840 4082/4462/2816 4110/4490/2842 +f 4109/4489/2841 4108/4488/2840 4110/4490/2842 +f 4109/4489/2841 4110/4490/2842 4111/4491/2843 +f 3872/4252/2134 3871/4251/2617 4112/4492/2844 +f 3872/4252/2134 4112/4492/2844 4113/4493/2845 +f 3871/4251/2617 3870/4250/2616 4114/4494/2846 +f 3871/4251/2617 4114/4494/2846 4112/4492/2844 +f 4112/4492/2844 4114/4494/2846 4115/4495/2847 +f 4112/4492/2844 4115/4495/2847 4116/4496/2848 +f 4113/4493/2845 4112/4492/2844 4116/4496/2848 +f 4113/4493/2845 4116/4496/2848 4117/4497/2849 +f 4118/4498/2160 4119/4499/2850 4120/4500/2851 +f 4118/4498/2160 4120/4500/2851 4121/4501/2852 +f 4119/4499/2850 4122/4502/2853 4123/4503/2854 +f 4119/4499/2850 4123/4503/2854 4120/4500/2851 +f 4120/4500/2851 4123/4503/2854 4124/4504/2855 +f 4120/4500/2851 4124/4504/2855 4125/4505/2856 +f 4121/4501/2852 4120/4500/2851 4125/4505/2856 +f 4121/4501/2852 4125/4505/2856 4126/4506/2857 +f 4127/4507/2858 4128/4508/2859 4129/4509/2860 +f 4127/4507/2858 4129/4509/2860 4130/4510/2861 +f 4128/4508/2859 4131/4511/2862 4132/4512/2863 +f 4128/4508/2859 4132/4512/2863 4129/4509/2860 +f 4129/4509/2860 4132/4512/2863 4133/4513/2864 +f 4129/4509/2860 4133/4513/2864 4134/4514/2865 +f 4130/4510/2861 4129/4509/2860 4134/4514/2865 +f 4130/4510/2861 4134/4514/2865 4135/4515/2866 +f 4136/4516/2867 4137/4517/2868 4138/4518/2869 +f 4136/4516/2867 4138/4518/2869 4139/4519/2870 +f 4137/4517/2868 4140/4520/2871 4141/4521/2872 +f 4137/4517/2868 4141/4521/2872 4138/4518/2869 +f 4138/4518/2869 4141/4521/2872 4142/4522/2873 +f 4138/4518/2869 4142/4522/2873 4143/4523/2874 +f 4139/4519/2870 4138/4518/2869 4143/4523/2874 +f 4139/4519/2870 4143/4523/2874 4144/4524/2875 +f 4145/4525/2876 4146/4526/2877 4147/4527/2878 +f 4145/4525/2876 4147/4527/2878 4148/4528/2879 +f 4146/4526/2877 4149/4529/2880 4150/4530/2881 +f 4146/4526/2877 4150/4530/2881 4147/4527/2878 +f 4147/4527/2878 4150/4530/2881 3810/4190/2558 +f 4147/4527/2878 3810/4190/2558 3809/4189/2557 +f 4148/4528/2879 4147/4527/2878 3809/4189/2557 +f 4148/4528/2879 3809/4189/2557 3808/4188/2081 +f 4151/4531/2882 4152/4532/2883 4153/4533/2884 +f 4151/4531/2882 4153/4533/2884 4154/4534/2885 +f 4152/4532/2883 4155/4535/2886 4156/4536/2887 +f 4152/4532/2883 4156/4536/2887 4153/4533/2884 +f 4153/4533/2884 4156/4536/2887 4157/4537/2888 +f 4153/4533/2884 4157/4537/2888 4158/4538/2889 +f 4154/4534/2885 4153/4533/2884 4158/4538/2889 +f 4154/4534/2885 4158/4538/2889 4159/4539/2890 +f 4160/4540/2891 4161/4541/2892 4162/4542/2893 +f 4160/4540/2891 4162/4542/2893 4163/4543/2894 +f 4161/4541/2892 4164/4544/2895 4165/4545/2896 +f 4161/4541/2892 4165/4545/2896 4162/4542/2893 +f 4162/4542/2893 4165/4545/2896 4166/4546/2897 +f 4162/4542/2893 4166/4546/2897 4167/4547/2898 +f 4163/4543/2894 4162/4542/2893 4167/4547/2898 +f 4163/4543/2894 4167/4547/2898 4168/4548/2899 +f 3733/4113/2491 4169/4549/2900 4170/4550/2901 +f 3733/4113/2491 4170/4550/2901 3734/4114/2492 +f 4169/4549/2900 4136/4516/2867 4139/4519/2870 +f 4169/4549/2900 4139/4519/2870 4170/4550/2901 +f 4170/4550/2901 4139/4519/2870 4144/4524/2875 +f 4170/4550/2901 4144/4524/2875 4171/4551/2902 +f 3734/4114/2492 4170/4550/2901 4171/4551/2902 +f 3734/4114/2492 4171/4551/2902 3735/4115/2493 +f 3724/4104/2482 4172/4552/2903 4173/4553/2904 +f 3724/4104/2482 4173/4553/2904 3725/4105/2483 +f 4172/4552/2903 3771/4151/2528 3774/4154/2531 +f 4172/4552/2903 3774/4154/2531 4173/4553/2904 +f 4173/4553/2904 3774/4154/2531 3776/4156/2533 +f 4173/4553/2904 3776/4156/2533 4174/4554/2905 +f 3725/4105/2483 4173/4553/2904 4174/4554/2905 +f 3725/4105/2483 4174/4554/2905 3726/4106/2484 +f 4175/4555/2199 4176/4556/2906 4177/4557/2907 +f 4175/4555/2199 4177/4557/2907 4178/4558/2908 +f 4176/4556/2906 3729/4109/2487 3732/4112/2490 +f 4176/4556/2906 3732/4112/2490 4177/4557/2907 +f 4177/4557/2907 3732/4112/2490 3737/4117/2495 +f 4177/4557/2907 3737/4117/2495 4179/4559/2909 +f 4178/4558/2908 4177/4557/2907 4179/4559/2909 +f 4178/4558/2908 4179/4559/2909 4180/4560/2910 +f 4181/4561/2911 4182/4562/2912 4183/4563/2913 +f 4181/4561/2911 4183/4563/2913 4184/4564/2914 +f 4182/4562/2912 4185/4565/2915 4186/4566/2916 +f 4182/4562/2912 4186/4566/2916 4183/4563/2913 +f 4183/4563/2913 4186/4566/2916 3418/3835/2213 +f 4183/4563/2913 3418/3835/2213 3415/3832/2210 +f 4184/4564/2914 4183/4563/2913 3415/3832/2210 +f 4184/4564/2914 3415/3832/2210 3414/3831/2209 +f 3280/3715/2089 4187/4567/2917 4188/4568/2918 +f 3280/3715/2089 4188/4568/2918 3281/3716/2090 +f 4187/4567/2917 4189/4569/2919 4190/4570/2920 +f 4187/4567/2917 4190/4570/2920 4188/4568/2918 +f 4188/4568/2918 4190/4570/2920 4191/4571/2921 +f 4188/4568/2918 4191/4571/2921 4192/4572/2714 +f 3281/3716/2090 4188/4568/2918 4192/4572/2714 +f 3281/3716/2090 4192/4572/2714 3282/3717/2091 +f 3532/3262/1903 4193/3259/1892 4194/4573/2922 +f 3532/3262/1903 4194/4573/2922 3533/3932/2312 +f 4193/3259/1892 4195/3258/2923 4196/4574/2924 +f 4193/3259/1892 4196/4574/2924 4194/4573/2922 +f 4194/4573/2922 4196/4574/2924 4197/4575/2925 +f 4194/4573/2922 4197/4575/2925 4198/4576/2926 +f 3533/3932/2312 4194/4573/2922 4198/4576/2926 +f 3533/3932/2312 4198/4576/2926 3534/3933/2313 +f 3706/4086/2464 4199/4577/2927 4200/4578/2928 +f 3706/4086/2464 4200/4578/2928 3707/4087/2465 +f 4199/4577/2927 3681/4061/2441 3684/4064/2444 +f 4199/4577/2927 3684/4064/2444 4200/4578/2928 +f 4200/4578/2928 3684/4064/2444 3689/4069/2449 +f 4200/4578/2928 3689/4069/2449 4201/4579/2929 +f 3707/4087/2465 4200/4578/2928 4201/4579/2929 +f 3707/4087/2465 4201/4579/2929 3708/4088/2466 +f 4202/4580/2930 4203/4581/2931 4204/4582/2932 +f 4202/4580/2930 4204/4582/2932 4205/4583/2933 +f 4203/4581/2931 4206/4584/2934 4207/4585/2935 +f 4203/4581/2931 4207/4585/2935 4204/4582/2932 +f 4204/4582/2932 4207/4585/2935 4208/4586/2936 +f 4204/4582/2932 4208/4586/2936 4209/4587/2937 +f 4205/4583/2933 4204/4582/2932 4209/4587/2937 +f 4205/4583/2933 4209/4587/2937 4210/4588/2938 +f 3626/4010/2390 3625/4009/2389 4211/4589/2939 +f 3626/4010/2390 4211/4589/2939 4212/4590/2940 +f 3625/4009/2389 3624/4008/2388 4213/4591/2941 +f 3625/4009/2389 4213/4591/2941 4211/4589/2939 +f 4211/4589/2939 4213/4591/2941 4214/4592/2942 +f 4211/4589/2939 4214/4592/2942 4215/4593/2943 +f 4212/4590/2940 4211/4589/2939 4215/4593/2943 +f 4212/4590/2940 4215/4593/2943 4216/4594/2944 +f 4217/4595/2945 4218/4596/2946 4219/4597/2947 +f 4217/4595/2945 4219/4597/2947 4220/4598/2948 +f 4221/4599/2949 4222/4600/2950 4223/4601/2951 +f 4221/4599/2949 4223/4601/2951 4224/4602/2952 +f 4224/4602/2952 4223/4601/2951 4225/4603/2953 +f 4224/4602/2952 4225/4603/2953 4226/4604/2954 +f 4220/4598/2948 4219/4597/2947 4227/4605/2955 +f 4220/4598/2948 4227/4605/2955 4228/4606/2956 +f 4229/3310/1910 4230/3373/1937 4231/4607/2957 +f 4229/3310/1910 4231/4607/2957 4232/4608/2958 +f 4230/3373/1937 3633/3338/2397 3636/4018/2400 +f 4230/3373/1937 3636/4018/2400 4231/4607/2957 +f 4231/4607/2957 3636/4018/2400 3641/4022/2404 +f 4231/4607/2957 3641/4022/2404 4233/4609/2959 +f 4232/4608/2958 4231/4607/2957 4233/4609/2959 +f 4232/4608/2958 4233/4609/2959 4234/4610/2639 +f 4235/3318/1913 4236/3449/1961 4237/4611/2960 +f 4235/3318/1913 4237/4611/2960 4238/4612/2961 +f 4236/3449/1961 3564/3367/1936 3567/3958/2338 +f 4236/3449/1961 3567/3958/2338 4237/4611/2960 +f 4237/4611/2960 3567/3958/2338 3572/3962/2342 +f 4237/4611/2960 3572/3962/2342 4239/4613/2592 +f 4238/4612/2961 4237/4611/2960 4239/4613/2592 +f 4238/4612/2961 4239/4613/2592 4240/4614/2962 +f 3658/4038/2420 4241/4615/2963 4242/4616/2964 +f 3658/4038/2420 4242/4616/2964 3659/4039/2421 +f 4241/4615/2963 3702/4082/2460 3705/4085/2463 +f 4241/4615/2963 3705/4085/2463 4242/4616/2964 +f 4242/4616/2964 3705/4085/2463 3710/4090/2468 +f 4242/4616/2964 3710/4090/2468 4243/4617/2965 +f 3659/4039/2421 4242/4616/2964 4243/4617/2965 +f 3659/4039/2421 4243/4617/2965 3660/4040/2422 +f 3568/3286/1935 4244/3283/1901 4245/4618/2966 +f 3568/3286/1935 4245/4618/2966 3569/3959/2339 +f 4244/3283/1901 4246/3282/1900 4247/4619/2967 +f 4244/3283/1901 4247/4619/2967 4245/4618/2966 +f 4245/4618/2966 4247/4619/2967 4248/4620/2697 +f 4245/4618/2966 4248/4620/2697 4249/4621/2968 +f 3569/3959/2339 4245/4618/2966 4249/4621/2968 +f 3569/3959/2339 4249/4621/2968 3570/3960/2340 +f 4250/4622/2864 4251/4623/2969 4252/4624/2970 +f 4250/4622/2864 4252/4624/2970 4253/4625/2971 +f 4251/4623/2969 4254/4626/2972 4255/4627/2973 +f 4251/4623/2969 4255/4627/2973 4252/4624/2970 +f 4252/4624/2970 4255/4627/2973 3676/4056/2436 +f 4252/4624/2970 3676/4056/2436 3673/4053/2433 +f 4253/4625/2971 4252/4624/2970 3673/4053/2433 +f 4253/4625/2971 3673/4053/2433 3672/4052/2432 +f 4256/3358/2974 4257/4628/2975 4258/4629/2976 +f 4256/3358/2974 4258/4629/2976 4259/4630/2977 +f 4257/4628/2975 4260/4631/2978 4261/4632/2979 +f 4257/4628/2975 4261/4632/2979 4258/4629/2976 +f 4258/4629/2976 4261/4632/2979 4262/4633/2980 +f 4258/4629/2976 4262/4633/2980 4263/4634/2981 +f 4259/4630/2977 4258/4629/2976 4263/4634/2981 +f 4259/4630/2977 4263/4634/2981 4264/4635/2982 +f 3632/4016/2396 3631/4015/2395 4265/4636/2983 +f 3632/4016/2396 4265/4636/2983 4266/4637/2984 +f 3631/4015/2395 3630/4014/2394 4267/4638/2985 +f 3631/4015/2395 4267/4638/2985 4265/4636/2983 +f 4265/4636/2983 4267/4638/2985 3586/3973/2353 +f 4265/4636/2983 3586/3973/2353 3583/3970/2350 +f 4266/4637/2984 4265/4636/2983 3583/3970/2350 +f 4266/4637/2984 3583/3970/2350 3582/3969/2349 +f 4246/3282/1900 4268/3311/2986 4269/4639/2987 +f 4246/3282/1900 4269/4639/2987 4247/4619/2967 +f 4268/3311/2986 4229/3310/1910 4232/4608/2958 +f 4268/3311/2986 4232/4608/2958 4269/4639/2987 +f 4269/4639/2987 4232/4608/2958 4234/4610/2639 +f 4269/4639/2987 4234/4610/2639 4270/4640/2988 +f 4247/4619/2967 4269/4639/2987 4270/4640/2988 +f 4247/4619/2967 4270/4640/2988 4248/4620/2697 +f 4271/3377/1939 4272/4641/2989 4273/4642/2990 +f 4271/3377/1939 4273/4642/2990 4274/3378/1940 +f 4272/4641/2989 4275/4643/2991 4276/4644/2748 +f 4272/4641/2989 4276/4644/2748 4273/4642/2990 +f 4273/4642/2990 4276/4644/2748 3523/3926/2306 +f 4273/4642/2990 3523/3926/2306 3520/3924/2303 +f 4274/3378/1940 4273/4642/2990 3520/3924/2303 +f 4274/3378/1940 3520/3924/2303 3519/3381/2302 +f 3694/4074/2206 4277/4645/2992 4278/4646/2993 +f 3694/4074/2206 4278/4646/2993 3695/4075/2453 +f 4277/4645/2992 3663/4043/2425 3666/4046/2427 +f 4277/4645/2992 3666/4046/2427 4278/4646/2993 +f 4278/4646/2993 3666/4046/2427 3671/4051/2431 +f 4278/4646/2993 3671/4051/2431 4279/4647/2994 +f 3695/4075/2453 4278/4646/2993 4279/4647/2994 +f 3695/4075/2453 4279/4647/2994 3696/4076/2454 +f 3685/4065/2445 4280/4648/2995 4281/4649/2996 +f 3685/4065/2445 4281/4649/2996 3686/4066/2446 +f 4280/4648/2995 3642/4023/2405 3645/4026/2408 +f 4280/4648/2995 3645/4026/2408 4281/4649/2996 +f 4281/4649/2996 3645/4026/2408 3650/4031/2413 +f 4281/4649/2996 3650/4031/2413 4282/4650/2997 +f 3686/4066/2446 4281/4649/2996 4282/4650/2997 +f 3686/4066/2446 4282/4650/2997 3687/4067/2447 +f 4283/3405/1948 4284/4651/2998 4285/4652/2999 +f 4283/3405/1948 4285/4652/2999 4286/3406/3000 +f 4284/4651/2998 4287/4653/3001 4288/4654/3002 +f 4284/4651/2998 4288/4654/3002 4285/4652/2999 +f 4285/4652/2999 4288/4654/3002 4289/4655/3003 +f 4285/4652/2999 4289/4655/3003 4290/4656/3004 +f 4286/3406/3000 4285/4652/2999 4290/4656/3004 +f 4286/3406/3000 4290/4656/3004 4291/3409/1950 +f 3563/3421/1953 3562/3956/2336 4292/4657/3005 +f 3563/3421/1953 4292/4657/3005 4293/3453/2454 +f 3562/3956/2336 3561/3955/2335 4294/4658/3006 +f 3562/3956/2336 4294/4658/3006 4292/4657/3005 +f 4292/4657/3005 4294/4658/3006 3601/3986/2366 +f 4292/4657/3005 3601/3986/2366 3598/3984/2364 +f 4293/3453/2454 4292/4657/3005 3598/3984/2364 +f 4293/3453/2454 3598/3984/2364 3597/3397/1945 +f 3605/3389/1944 3604/3989/2369 4295/4659/3007 +f 3605/3389/1944 4295/4659/3007 4296/3390/3008 +f 3604/3989/2369 3603/3988/2368 4297/4660/3009 +f 3604/3989/2369 4297/4660/3009 4295/4659/3007 +f 4295/4659/3007 4297/4660/3009 4275/4643/2991 +f 4295/4659/3007 4275/4643/2991 4272/4641/2989 +f 4296/3390/3008 4295/4659/3007 4272/4641/2989 +f 4296/3390/3008 4272/4641/2989 4271/3377/1939 +f 3581/3429/1954 3580/3968/2348 4298/4661/3010 +f 3581/3429/1954 4298/4661/3010 4299/3430/1956 +f 3580/3968/2348 3579/3967/2347 4300/4662/3011 +f 3580/3968/2348 4300/4662/3011 4298/4661/3010 +f 4298/4661/3010 4300/4662/3011 3559/3953/2333 +f 4298/4661/3010 3559/3953/2333 3556/3951/2331 +f 4299/3430/1956 4298/4661/3010 3556/3951/2331 +f 4299/3430/1956 3556/3951/2331 3555/3417/1951 +f 4291/3409/1950 4290/4656/3004 4301/4663/3012 +f 4291/3409/1950 4301/4663/3012 4302/3445/1960 +f 4290/4656/3004 4289/4655/3003 4303/4664/2606 +f 4290/4656/3004 4303/4664/2606 4301/4663/3012 +f 4301/4663/3012 4303/4664/2606 3577/3965/2345 +f 4301/4663/3012 3577/3965/2345 3574/3963/2343 +f 4302/3445/1960 4301/4663/3012 3574/3963/2343 +f 4302/3445/1960 3574/3963/2343 3573/3437/1957 +f 4195/3258/2923 4304/3319/1914 4305/4665/3013 +f 4195/3258/2923 4305/4665/3013 4196/4574/2924 +f 4304/3319/1914 4235/3318/1913 4238/4612/2961 +f 4304/3319/1914 4238/4612/2961 4305/4665/3013 +f 4305/4665/3013 4238/4612/2961 4240/4614/2962 +f 4305/4665/3013 4240/4614/2962 4306/4666/3014 +f 4196/4574/2924 4305/4665/3013 4306/4666/3014 +f 4196/4574/2924 4306/4666/3014 4197/4575/2925 +f 3596/3983/2363 3595/3982/2362 4307/4667/3015 +f 3596/3983/2363 4307/4667/3015 4308/4668/3016 +f 3595/3982/2362 3594/3981/2361 4309/4669/3017 +f 3595/3982/2362 4309/4669/3017 4307/4667/3015 +f 4307/4667/3015 4309/4669/3017 3610/3994/2374 +f 4307/4667/3015 3610/3994/2374 3607/3991/2371 +f 4308/4668/3016 4307/4667/3015 3607/3991/2371 +f 4308/4668/3016 3607/3991/2371 3606/3990/2370 +f 4310/3457/1966 4311/3481/3018 4312/4670/3019 +f 4310/3457/1966 4312/4670/3019 4313/4671/3020 +f 4311/3481/3018 3510/3350/1977 3513/3919/2297 +f 4311/3481/3018 3513/3919/2297 4312/4670/3019 +f 4312/4670/3019 3513/3919/2297 3518/3923/2301 +f 4312/4670/3019 3518/3923/2301 4314/4672/3021 +f 4313/4671/3020 4312/4670/3019 4314/4672/3021 +f 4313/4671/3020 4314/4672/3021 4315/4673/3022 +f 3527/3467/1973 3526/3929/2309 4316/4674/3023 +f 3527/3467/1973 4316/4674/3023 4317/3477/3024 +f 3526/3929/2309 3525/3928/2308 4318/4675/3025 +f 3526/3929/2309 4318/4675/3025 4316/4674/3023 +f 4316/4674/3023 4318/4675/3025 3541/3938/2318 +f 4316/4674/3023 3541/3938/2318 3538/3936/2316 +f 4317/3477/3024 4316/4674/3023 3538/3936/2316 +f 4317/3477/3024 3538/3936/2316 3537/3326/1918 +f 3514/3346/1925 4319/3473/1971 4320/4676/3026 +f 3514/3346/1925 4320/4676/3026 3515/3920/2298 +f 4319/3473/1971 3528/3296/1906 3531/3931/2311 +f 4319/3473/1971 3531/3931/2311 4320/4676/3026 +f 4320/4676/3026 3531/3931/2311 3536/3935/2315 +f 4320/4676/3026 3536/3935/2315 4321/4677/3027 +f 3515/3920/2298 4320/4676/3026 4321/4677/3027 +f 3515/3920/2298 4321/4677/3027 3516/3921/2299 +f 4216/4594/2944 4215/4593/2943 4322/4678/3028 +f 4216/4594/2944 4322/4678/3028 4323/4679/3029 +f 4215/4593/2943 4214/4592/2942 4324/4680/3030 +f 4215/4593/2943 4324/4680/3030 4322/4678/3028 +f 4322/4678/3028 4324/4680/3030 4254/4626/2972 +f 4322/4678/3028 4254/4626/2972 4251/4623/2969 +f 4323/4679/3029 4322/4678/3028 4251/4623/2969 +f 4323/4679/3029 4251/4623/2969 4250/4622/2864 +f 4283/3405/1948 4325/3458/1965 4326/4681/3031 +f 4283/3405/1948 4326/4681/3031 4284/4651/2998 +f 4325/3458/1965 4310/3457/1966 4313/4671/3020 +f 4325/3458/1965 4313/4671/3020 4326/4681/3031 +f 4326/4681/3031 4313/4671/3020 4315/4673/3022 +f 4326/4681/3031 4315/4673/3022 4327/4682/3032 +f 4284/4651/2998 4326/4681/3031 4327/4682/3032 +f 4284/4651/2998 4327/4682/3032 4287/4653/3001 +f 3719/4099/2477 3718/4098/2476 4328/4683/3033 +f 3719/4099/2477 4328/4683/3033 4329/4684/3034 +f 3718/4098/2476 3717/4097/2475 4330/4685/3035 +f 3718/4098/2476 4330/4685/3035 4328/4683/3033 +f 4328/4683/3033 4330/4685/3035 4331/4686/3036 +f 4328/4683/3033 4331/4686/3036 4332/4687/3037 +f 4333/4688/3038 4334/4689/3039 4335/4690/3040 +f 4333/4688/3038 4335/4690/3040 4336/4691/3041 +f 3293/3485/1979 3292/3725/2100 4337/4692/3042 +f 3293/3485/1979 4337/4692/3042 4338/3486/1980 +f 3292/3725/2100 3291/3724/2099 4339/4693/3043 +f 3292/3725/2100 4339/4693/3043 4337/4692/3042 +f 4337/4692/3042 4339/4693/3043 3325/3749/2126 +f 4337/4692/3042 3325/3749/2126 3322/3747/2124 +f 4338/3486/1980 4337/4692/3042 3322/3747/2124 +f 4338/3486/1980 3322/3747/2124 3321/3489/2123 +f 3479/3890/2268 3478/3889/2267 4340/4694/3044 +f 3479/3890/2268 4340/4694/3044 4341/4695/2675 +f 3478/3889/2267 3477/3888/2266 4342/4696/3045 +f 3478/3889/2267 4342/4696/3045 4340/4694/3044 +f 4340/4694/3044 4342/4696/3045 4343/4697/3046 +f 4340/4694/3044 4343/4697/3046 4344/4698/3047 +f 4341/4695/2675 4340/4694/3044 4344/4698/3047 +f 4341/4695/2675 4344/4698/3047 4345/4699/3048 +f 4346/4700/2882 4347/4701/3049 4348/4702/3050 +f 4346/4700/2882 4348/4702/3050 4349/4703/3051 +f 4347/4701/3049 4350/4704/3052 4351/4705/3053 +f 4347/4701/3049 4351/4705/3053 4348/4702/3050 +f 4348/4702/3050 4351/4705/3053 4352/4706/3054 +f 4348/4702/3050 4352/4706/3054 4353/4707/3055 +f 4349/4703/3051 4348/4702/3050 4353/4707/3055 +f 4349/4703/3051 4353/4707/3055 4354/4708/3056 +f 3374/3794/2172 4355/4709/3057 4356/4710/3058 +f 3374/3794/2172 4356/4710/3058 3375/3795/2173 +f 4355/4709/3057 3294/3726/2101 3297/3729/2104 +f 4355/4709/3057 3297/3729/2104 4356/4710/3058 +f 4356/4710/3058 3297/3729/2104 3302/3734/2109 +f 4356/4710/3058 3302/3734/2109 4357/4711/3059 +f 3375/3795/2173 4356/4710/3058 4357/4711/3059 +f 3375/3795/2173 4357/4711/3059 3376/3796/2174 +f 4358/3675/2055 4359/4712/3060 4360/4713/3061 +f 4358/3675/2055 4360/4713/3061 4361/4714/3062 +f 4359/4712/3060 4362/4715/3063 4363/4716/3064 +f 4359/4712/3060 4363/4716/3064 4360/4713/3061 +f 4360/4713/3061 4363/4716/3064 4364/4717/3065 +f 4360/4713/3061 4364/4717/3065 4365/4718/3066 +f 4361/4714/3062 4360/4713/3061 4365/4718/3066 +f 4361/4714/3062 4365/4718/3066 4366/4719/3067 +f 3395/3530/2000 3394/3812/2190 4367/4720/3068 +f 3395/3530/2000 4367/4720/3068 4368/3576/2018 +f 3394/3812/2190 3393/3811/2189 4369/4721/3069 +f 3394/3812/2190 4369/4721/3069 4367/4720/3068 +f 4367/4720/3068 4369/4721/3069 3454/3866/2245 +f 4367/4720/3068 3454/3866/2245 3451/3864/2243 +f 4368/3576/2018 4367/4720/3068 3451/3864/2243 +f 4368/3576/2018 3451/3864/2243 3450/3544/2005 +f 3329/3538/2004 3328/3752/2129 4370/4722/3070 +f 3329/3538/2004 4370/4722/3070 4371/3651/2044 +f 3328/3752/2129 3327/3751/2128 4372/4723/2594 +f 3328/3752/2129 4372/4723/2594 4370/4722/3070 +f 4370/4722/3070 4372/4723/2594 3445/3860/2239 +f 4370/4722/3070 3445/3860/2239 3442/3858/2236 +f 4371/3651/2044 4370/4722/3070 3442/3858/2236 +f 4371/3651/2044 3442/3858/2236 3441/3568/2016 +f 3422/3839/2217 3421/3838/2216 4373/4724/3071 +f 3422/3839/2217 4373/4724/3071 4374/4725/3072 +f 3421/3838/2216 3420/3837/2215 4375/4726/3073 +f 3421/3838/2216 4375/4726/3073 4373/4724/3071 +f 4373/4724/3071 4375/4726/3073 3475/3886/2264 +f 4373/4724/3071 3475/3886/2264 3472/3883/2261 +f 4374/4725/3072 4373/4724/3071 3472/3883/2261 +f 4374/4725/3072 3472/3883/2261 3471/3882/2260 +f 3449/3497/1984 3448/3863/2242 4376/4727/3074 +f 3449/3497/1984 4376/4727/3074 4377/3498/3075 +f 3448/3863/2242 3447/3862/2241 4378/4728/3076 +f 3448/3863/2242 4378/4728/3076 4376/4727/3074 +f 4376/4727/3074 4378/4728/3076 3391/3809/2187 +f 4376/4727/3074 3391/3809/2187 3388/3807/2185 +f 4377/3498/3075 4376/4727/3074 3388/3807/2185 +f 4377/3498/3075 3388/3807/2185 3387/3501/1987 +f 3298/3730/2105 4379/4729/3077 4380/4730/3078 +f 3298/3730/2105 4380/4730/3078 3299/3731/2106 +f 4379/4729/3077 3432/3849/2227 3435/3852/2230 +f 4379/4729/3077 3435/3852/2230 4380/4730/3078 +f 4380/4730/3078 3435/3852/2230 3440/3857/2235 +f 4380/4730/3078 3440/3857/2235 4381/4731/3079 +f 3299/3731/2106 4380/4730/3078 4381/4731/3079 +f 3299/3731/2106 4381/4731/3079 3300/3732/2107 +f 4382/4732/3080 4383/4733/3081 4384/4734/3082 +f 4382/4732/3080 4384/4734/3082 4385/4735/3083 +f 4383/4733/3081 4386/4736/3084 4387/4737/3085 +f 4383/4733/3081 4387/4737/3085 4384/4734/3082 +f 4384/4734/3082 4387/4737/3085 4388/4738/3086 +f 4384/4734/3082 4388/4738/3086 4389/4739/3087 +f 4385/4735/3083 4384/4734/3082 4389/4739/3087 +f 4385/4735/3083 4389/4739/3087 4390/4740/3088 +f 3382/3802/2180 4391/4741/2576 4392/4742/3089 +f 3382/3802/2180 4392/4742/3089 3383/3803/2181 +f 4391/4741/2576 3339/3759/2137 3342/3762/2140 +f 4391/4741/2576 3342/3762/2140 4392/4742/3089 +f 4392/4742/3089 3342/3762/2140 3347/3767/2145 +f 4392/4742/3089 3347/3767/2145 4393/4743/3090 +f 3383/3803/2181 4392/4742/3089 4393/4743/3090 +f 3383/3803/2181 4393/4743/3090 3384/3804/2182 +f 3485/3896/2274 3484/3895/2273 4394/4744/3091 +f 3485/3896/2274 4394/4744/3091 4395/4745/3092 +f 3484/3895/2273 3483/3894/2272 4396/4746/3093 +f 3484/3895/2273 4396/4746/3093 4394/4744/3091 +f 4394/4744/3091 4396/4746/3093 4397/4747/2045 +f 4394/4744/3091 4397/4747/2045 4398/4748/3094 +f 4395/4745/3092 4394/4744/3091 4398/4748/3094 +f 4395/4745/3092 4398/4748/3094 4399/4749/3095 +f 4400/3583/2022 4401/3581/2020 4402/4750/3096 +f 4400/3583/2022 4402/4750/3096 4403/4751/3097 +f 4401/3581/2020 4404/3580/2019 4405/4752/3098 +f 4401/3581/2020 4405/4752/3098 4402/4750/3096 +f 4402/4750/3096 4405/4752/3098 4406/4753/2665 +f 4402/4750/3096 4406/4753/2665 4407/4754/3099 +f 4403/4751/3097 4402/4750/3096 4407/4754/3099 +f 4403/4751/3097 4407/4754/3099 4408/4755/3100 +f 4399/4749/3095 4398/4748/3094 4409/4756/3101 +f 4399/4749/3095 4409/4756/3101 4410/4757/3102 +f 4398/4748/3094 4397/4747/2045 4411/4758/3103 +f 4398/4748/3094 4411/4758/3103 4409/4756/3101 +f 4409/4756/3101 4411/4758/3103 3427/3844/2222 +f 4409/4756/3101 3427/3844/2222 3424/3841/2219 +f 4410/4757/3102 4409/4756/3101 3424/3841/2219 +f 4410/4757/3102 3424/3841/2219 3423/3840/2218 +f 4412/4759/2506 4413/4760/3104 4414/4761/3105 +f 4412/4759/2506 4414/4761/3105 4415/4762/3106 +f 4413/4760/3104 4416/4763/3107 4417/4764/3108 +f 4413/4760/3104 4417/4764/3108 4414/4761/3105 +f 4414/4761/3105 4417/4764/3108 3400/3817/2195 +f 4414/4761/3105 3400/3817/2195 3397/3814/2192 +f 4415/4762/3106 4414/4761/3105 3397/3814/2192 +f 4415/4762/3106 3397/3814/2192 3396/3813/2191 +f 3267/3611/2032 4418/3608/2030 4419/4765/3109 +f 3267/3611/2032 4419/4765/3109 3268/3705/2079 +f 4418/3608/2030 4420/3607/3110 4421/4766/3111 +f 4418/3608/2030 4421/4766/3111 4419/4765/3109 +f 4419/4765/3109 4421/4766/3111 4422/4767/3112 +f 4419/4765/3109 4422/4767/3112 4423/4768/3113 +f 3268/3705/2079 4419/4765/3109 4423/4768/3113 +f 3268/3705/2079 4423/4768/3113 3271/3707/2081 +f 4424/3619/2033 4425/3655/2045 4426/4769/3114 +f 4424/3619/2033 4426/4769/3114 4427/4770/3115 +f 4425/3655/2045 3312/3601/2028 3315/3742/2118 +f 4425/3655/2045 3315/3742/2118 4426/4769/3114 +f 4426/4769/3114 3315/3742/2118 3320/3746/2122 +f 4426/4769/3114 3320/3746/2122 4428/4771/3116 +f 4427/4770/3115 4426/4769/3114 4428/4771/3116 +f 4427/4770/3115 4428/4771/3116 4429/4772/2627 +f 3316/3593/2026 4430/3591/2025 4431/4773/3117 +f 3316/3593/2026 4431/4773/3117 3317/3743/2119 +f 4430/3591/2025 4400/3583/2022 4403/4751/3097 +f 4430/3591/2025 4403/4751/3097 4431/4773/3117 +f 4431/4773/3117 4403/4751/3097 4408/4755/3100 +f 4431/4773/3117 4408/4755/3100 4432/4774/3118 +f 3317/3743/2119 4431/4773/3117 4432/4774/3118 +f 3317/3743/2119 4432/4774/3118 3318/3744/2120 +f 3334/3633/2038 4433/3631/2037 4434/4775/3119 +f 3334/3633/2038 4434/4775/3119 3335/3755/2133 +f 4433/3631/2037 4435/3623/2036 4436/4776/3120 +f 4433/3631/2037 4436/4776/3120 4434/4775/3119 +f 4434/4775/3119 4436/4776/3120 4437/4777/3121 +f 4434/4775/3119 4437/4777/3121 4438/4778/3122 +f 3335/3755/2133 4434/4775/3119 4438/4778/3122 +f 3335/3755/2133 4438/4778/3122 3336/3756/2134 +f 4420/3607/3110 4439/3647/2041 4440/4779/3123 +f 4420/3607/3110 4440/4779/3123 4421/4766/3111 +f 4439/3647/2041 3330/3641/2130 3333/3754/2132 +f 4439/3647/2041 3333/3754/2132 4440/4779/3123 +f 4440/4779/3123 3333/3754/2132 3338/3758/2136 +f 4440/4779/3123 3338/3758/2136 4441/4780/3124 +f 4421/4766/3111 4440/4779/3123 4441/4780/3124 +f 4421/4766/3111 4441/4780/3124 4422/4767/3112 +f 4345/4699/3048 4344/4698/3047 4442/4781/3125 +f 4345/4699/3048 4442/4781/3125 4443/4782/2503 +f 4344/4698/3047 4343/4697/3046 4444/4783/3126 +f 4344/4698/3047 4444/4783/3126 4442/4781/3125 +f 4442/4781/3125 4444/4783/3126 4416/4763/3107 +f 4442/4781/3125 4416/4763/3107 4413/4760/3104 +f 4443/4782/2503 4442/4781/3125 4413/4760/3104 +f 4443/4782/2503 4413/4760/3104 4412/4759/2506 +f 4435/3623/2036 4445/3620/3127 4446/4784/3128 +f 4435/3623/2036 4446/4784/3128 4436/4776/3120 +f 4445/3620/3127 4424/3619/2033 4427/4770/3115 +f 4445/3620/3127 4427/4770/3115 4446/4784/3128 +f 4446/4784/3128 4427/4770/3115 4429/4772/2627 +f 4446/4784/3128 4429/4772/2627 4447/4785/3129 +f 4436/4776/3120 4446/4784/3128 4447/4785/3129 +f 4436/4776/3120 4447/4785/3129 4437/4777/3121 +f 3275/3661/2050 3274/3710/2084 4448/4786/3130 +f 3275/3661/2050 4448/4786/3130 4449/3671/2054 +f 3274/3710/2084 3273/3709/2083 4450/4787/3131 +f 3274/3710/2084 4450/4787/3131 4448/4786/3130 +f 4448/4786/3130 4450/4787/3131 3307/3737/2113 +f 4448/4786/3130 3307/3737/2113 3304/3735/2110 +f 4449/3671/2054 4448/4786/3130 3304/3735/2110 +f 4449/3671/2054 3304/3735/2110 3303/3556/2011 +f 4451/4788/3132 4452/4789/3133 4453/4790/3134 +f 4451/4788/3132 4453/4790/3134 4454/4791/3135 +f 4452/4789/3133 3276/3711/2085 3279/3714/2088 +f 4452/4789/3133 3279/3714/2088 4453/4790/3134 +f 4453/4790/3134 3279/3714/2088 3284/3719/2093 +f 4453/4790/3134 3284/3719/2093 4455/4792/3136 +f 4454/4791/3135 4453/4790/3134 4455/4792/3136 +f 4454/4791/3135 4455/4792/3136 4456/4793/3137 +f 3311/3560/2015 3310/3740/2116 4457/4794/3138 +f 3311/3560/2015 4457/4794/3138 4458/3667/2048 +f 3310/3740/2116 3309/3739/2115 4459/4795/3139 +f 3310/3740/2116 4459/4795/3139 4457/4794/3138 +f 4457/4794/3138 4459/4795/3139 3289/3722/2097 +f 4457/4794/3138 3289/3722/2097 3286/3720/2094 +f 4458/3667/2048 4457/4794/3138 3286/3720/2094 +f 4458/3667/2048 3286/3720/2094 3285/3509/1990 +f 4404/3580/2019 4460/4796/3140 4461/4797/3141 +f 4404/3580/2019 4461/4797/3141 4405/4752/3098 +f 4460/4796/3140 4451/4788/3132 4454/4791/3135 +f 4460/4796/3140 4454/4791/3135 4461/4797/3141 +f 4461/4797/3141 4454/4791/3135 4456/4793/3137 +f 4461/4797/3141 4456/4793/3137 4462/4798/3142 +f 4405/4752/3098 4461/4797/3141 4462/4798/3142 +f 4405/4752/3098 4462/4798/3142 4406/4753/2665 +f 3378/3798/2176 3381/3801/2179 4463/4799/3143 +f 3378/3798/2176 4463/4799/3143 4464/4800/3144 +f 3381/3801/2179 3386/3806/2184 4465/4801/3145 +f 3381/3801/2179 4465/4801/3145 4463/4799/3143 +f 4463/4799/3143 4465/4801/3145 4185/4565/2915 +f 4463/4799/3143 4185/4565/2915 4182/4562/2912 +f 4464/4800/3144 4463/4799/3143 4182/4562/2912 +f 4464/4800/3144 4182/4562/2912 4181/4561/2911 +f 4189/4569/2919 4466/3518/1992 4467/4802/3146 +f 4189/4569/2919 4467/4802/3146 4190/4570/2920 +f 4466/3518/1992 4468/3517/1991 4469/4803/3147 +f 4466/3518/1992 4469/4803/3147 4467/4802/3146 +f 4467/4802/3146 4469/4803/3147 4470/4804/3148 +f 4467/4802/3146 4470/4804/3148 4471/4805/3149 +f 4190/4570/2920 4467/4802/3146 4471/4805/3149 +f 4190/4570/2920 4471/4805/3149 4191/4571/2921 +f 4472/4806/2956 4473/4807/3150 4474/4808/3151 +f 4472/4806/2956 4474/4808/3151 4475/4809/3152 +f 4473/4807/3150 4476/4810/3153 4477/4811/3154 +f 4473/4807/3150 4477/4811/3154 4474/4808/3151 +f 4474/4808/3151 4477/4811/3154 4478/4812/3155 +f 4474/4808/3151 4478/4812/3155 4479/4813/3156 +f 4475/4809/3152 4474/4808/3151 4479/4813/3156 +f 4475/4809/3152 4479/4813/3156 4480/4814/3157 +f 4481/4815/3158 4482/4816/3159 4483/4817/3160 +f 4481/4815/3158 4483/4817/3160 4484/4818/3161 +f 4482/4816/3159 4485/4819/2978 4486/4820/3162 +f 4482/4816/3159 4486/4820/3162 4483/4817/3160 +f 4483/4817/3160 4486/4820/3162 4487/4821/3163 +f 4483/4817/3160 4487/4821/3163 4488/4822/3164 +f 4484/4818/3161 4483/4817/3160 4488/4822/3164 +f 4484/4818/3161 4488/4822/3164 4489/4823/3165 +f 4490/4824/3166 4491/4825/3167 4492/4826/3168 +f 4490/4824/3166 4492/4826/3168 4493/4827/3169 +f 4491/4825/3167 4494/4828/3170 4495/4829/3171 +f 4491/4825/3167 4495/4829/3171 4492/4826/3168 +f 4492/4826/3168 4495/4829/3171 4496/4830/3172 +f 4492/4826/3168 4496/4830/3172 4497/4831/3173 +f 4493/4827/3169 4492/4826/3168 4497/4831/3173 +f 4493/4827/3169 4497/4831/3173 4498/4832/3174 +f 4505/3267/1890 4507/3269/1890 3708/4088/2466 +f 4505/3267/1890 3708/4088/2466 4201/4579/2929 +f 4506/3268/1890 4505/3267/1890 4201/4579/2929 +f 4506/3268/1890 4201/4579/2929 3689/4069/2449 +f 4514/3279/1890 4516/3281/1890 3717/4097/2475 +f 4514/3279/1890 3717/4097/2475 3716/4096/2474 +f 4515/3280/1890 4514/3279/1890 3716/4096/2474 +f 4515/3280/1890 3716/4096/2474 3678/4058/2438 +f 4523/3291/1890 4525/3293/1890 3648/4029/2411 +f 4523/3291/1890 3648/4029/2411 3713/4093/2471 +f 4524/3292/1890 4523/3291/1890 3713/4093/2471 +f 4524/3292/1890 3713/4093/2471 3698/4078/2456 +f 4530/3300/1890 4531/3301/1890 3710/4090/2468 +f 4530/3300/1890 3710/4090/2468 3709/4089/2467 +f 4507/3269/1890 4530/3300/1890 3709/4089/2467 +f 4507/3269/1890 3709/4089/2467 3708/4088/2466 +f 4536/3308/1890 4537/3309/1890 4331/4686/3036 +f 4536/3308/1890 4331/4686/3036 4330/4685/3035 +f 4516/3281/1890 4536/3308/1890 4330/4685/3035 +f 4516/3281/1890 4330/4685/3035 3717/4097/2475 +f 4542/3316/1890 4524/3292/1890 3698/4078/2456 +f 4542/3316/1890 3698/4078/2456 3697/4077/2455 +f 4543/3317/1890 4542/3316/1890 3697/4077/2455 +f 4543/3317/1890 3697/4077/2455 3696/4076/2454 +f 4548/3324/1890 4506/3268/1890 3689/4069/2449 +f 4548/3324/1890 3689/4069/2449 3688/4068/2448 +f 4549/3325/1890 4548/3324/1890 3688/4068/2448 +f 4549/3325/1890 3688/4068/2448 3687/4067/2447 +f 4554/3332/1890 4515/3280/1890 3678/4058/2438 +f 4554/3332/1890 3678/4058/2438 3677/4057/2437 +f 4555/3333/1890 4554/3332/1890 3677/4057/2437 +f 4555/3333/1890 3677/4057/2437 3676/4056/2436 +f 4562/3343/1890 4564/3345/1890 3671/4051/2431 +f 4562/3343/1890 3671/4051/2431 3670/4050/2430 +f 4563/3344/1890 4562/3343/1890 3670/4050/2430 +f 4563/3344/1890 3670/4050/2430 3669/4049/2429 +f 4571/3355/1890 4573/3357/1890 3662/4042/2424 +f 4571/3355/1890 3662/4042/2424 3661/4041/2423 +f 4572/3356/1890 4571/3355/1890 3661/4041/2423 +f 4572/3356/1890 3661/4041/2423 3660/4040/2422 +f 4256/3358/2974 4575/3360/1924 4576/3362/3175 +f 4576/3362/3175 4577/3361/1890 4578/3363/1933 +f 4578/3363/1933 4579/3364/1890 4580/4833/3176 +f 4579/3364/1890 4563/3344/1890 3669/4049/2429 +f 4579/3364/1890 3669/4049/2429 4581/4834/3177 +f 4580/4833/3176 4579/3364/1890 4581/4834/3177 +f 4580/4833/3176 4581/4834/3177 4210/4588/2938 +f 4586/3371/1890 4587/3372/1890 3650/4031/2413 +f 4586/3371/1890 3650/4031/2413 3649/4030/2412 +f 4525/3293/1890 4586/3371/1890 3649/4030/2412 +f 4525/3293/1890 3649/4030/2412 3648/4029/2411 +f 4590/3376/1890 4543/3317/1890 3696/4076/2454 +f 4590/3376/1890 3696/4076/2454 4279/4647/2994 +f 4564/3345/1890 4590/3376/1890 4279/4647/2994 +f 4564/3345/1890 4279/4647/2994 3671/4051/2431 +f 4597/3386/1890 4599/3388/1890 4214/4592/2942 +f 4597/3386/1890 4214/4592/2942 4213/4591/2941 +f 4598/3387/1890 4597/3386/1890 4213/4591/2941 +f 4598/3387/1890 4213/4591/2941 3624/4008/2388 +f 4604/3395/1890 4598/3387/1890 3624/4008/2388 +f 4604/3395/1890 3624/4008/2388 3623/4007/2387 +f 4605/3396/1890 4604/3395/1890 3623/4007/2387 +f 4605/3396/1890 3623/4007/2387 3618/4002/2382 +f 4610/3403/1890 4605/3396/1890 3618/4002/2382 +f 4610/3403/1890 3618/4002/2382 3617/4001/2381 +f 4611/3404/1890 4610/3403/1890 3617/4001/2381 +f 4611/3404/1890 3617/4001/2381 3612/3996/2376 +f 4618/3414/1890 4620/3416/1890 3630/4014/2394 +f 4618/3414/1890 3630/4014/2394 3629/4013/2393 +f 4619/3415/1890 4618/3414/1890 3629/4013/2393 +f 4619/3415/1890 3629/4013/2393 3554/3950/2330 +f 4627/3426/1890 4629/3428/1890 3610/3994/2374 +f 4627/3426/1890 3610/3994/2374 4309/4669/3017 +f 4628/3427/1890 4627/3426/1890 4309/4669/3017 +f 4628/3427/1890 4309/4669/3017 3594/3981/2361 +f 4634/3435/1890 4628/3427/1890 3594/3981/2361 +f 4634/3435/1890 3594/3981/2361 3593/3980/2360 +f 4635/3436/1890 4634/3435/1890 3593/3980/2360 +f 4635/3436/1890 3593/3980/2360 3588/3975/2355 +f 4640/3443/1890 4635/3436/1890 3588/3975/2355 +f 4640/3443/1890 3588/3975/2355 3587/3974/2354 +f 4641/3444/1890 4640/3443/1890 3587/3974/2354 +f 4641/3444/1890 3587/3974/2354 3586/3973/2353 +f 4644/3448/1890 4641/3444/1890 3586/3973/2353 +f 4644/3448/1890 3586/3973/2353 4267/4638/2985 +f 4620/3416/1890 4644/3448/1890 4267/4638/2985 +f 4620/3416/1890 4267/4638/2985 3630/4014/2394 +f 4647/3452/1890 4549/3325/1890 3687/4067/2447 +f 4647/3452/1890 3687/4067/2447 4282/4650/2997 +f 4587/3372/1890 4647/3452/1890 4282/4650/2997 +f 4587/3372/1890 4282/4650/2997 3650/4031/2413 +f 4650/3456/1890 4611/3404/1890 3612/3996/2376 +f 4650/3456/1890 3612/3996/2376 3611/3995/2375 +f 4629/3428/1890 4650/3456/1890 3611/3995/2375 +f 4629/3428/1890 3611/3995/2375 3610/3994/2374 +f 4655/3463/1890 4619/3415/1890 3554/3950/2330 +f 4655/3463/1890 3554/3950/2330 3553/3949/2329 +f 4656/3464/1890 4655/3463/1890 3553/3949/2329 +f 4656/3464/1890 3553/3949/2329 3552/3948/2328 +f 4661/3471/1890 4662/3472/1890 4254/4626/2972 +f 4661/3471/1890 4254/4626/2972 4324/4680/3030 +f 4599/3388/1890 4661/3471/1890 4324/4680/3030 +f 4599/3388/1890 4324/4680/3030 4214/4592/2942 +f 4665/3476/1890 4572/3356/1890 3660/4040/2422 +f 4665/3476/1890 3660/4040/2422 4243/4617/2965 +f 4531/3301/1890 4665/3476/1890 4243/4617/2965 +f 4531/3301/1890 4243/4617/2965 3710/4090/2468 +f 4668/3480/1890 4555/3333/1890 3676/4056/2436 +f 4668/3480/1890 3676/4056/2436 4255/4627/2973 +f 4662/3472/1890 4668/3480/1890 4255/4627/2973 +f 4662/3472/1890 4255/4627/2973 4254/4626/2972 +f 4671/3484/1890 4656/3464/1890 3552/3948/2328 +f 4671/3484/1890 3552/3948/2328 3701/4081/2459 +f 4573/3357/1890 4671/3484/1890 3701/4081/2459 +f 4573/3357/1890 3701/4081/2459 3662/4042/2424 +f 4217/4595/2945 4220/4598/2948 4672/4835/3178 +f 4217/4595/2945 4672/4835/3178 4673/3687/3179 +f 4220/4598/2948 4228/4606/2956 4674/4836/3180 +f 4220/4598/2948 4674/4836/3180 4672/4835/3178 +f 4672/4835/3178 4674/4836/3180 4675/4837/3181 +f 4672/4835/3178 4675/4837/3181 4676/4838/3182 +f 4673/3687/3179 4672/4835/3178 4676/4838/3182 +f 4673/3687/3179 4676/4838/3182 4677/3688/3179 +f 4677/3688/3179 4676/4838/3182 4678/4839/3183 +f 4677/3688/3179 4678/4839/3183 4679/3684/3184 +f 4676/4838/3182 4675/4837/3181 4680/4840/3185 +f 4676/4838/3182 4680/4840/3185 4678/4839/3183 +f 4678/4839/3183 4680/4840/3185 3495/3906/2284 +f 4678/4839/3183 3495/3906/2284 3494/3905/2283 +f 4679/3684/3184 4678/4839/3183 3494/3905/2283 +f 4679/3684/3184 3494/3905/2283 3493/3904/2282 +f 4687/3494/1981 4689/3496/1981 4343/4697/3046 +f 4687/3494/1981 4343/4697/3046 4342/4696/3045 +f 4688/3495/1981 4687/3494/1981 4342/4696/3045 +f 4688/3495/1981 4342/4696/3045 3477/3888/2266 +f 4189/4569/2919 4187/4567/2917 4690/4841/3186 +f 4189/4569/2919 4690/4841/3186 4691/3521/3187 +f 4187/4567/2917 3280/3715/2089 4692/4842/3188 +f 4187/4567/2917 4692/4842/3188 4690/4841/3186 +f 4690/4841/3186 4692/4842/3188 4693/4843/3189 +f 4690/4841/3186 4693/4843/3189 4694/4844/3190 +f 4691/3521/3187 4690/4841/3186 4694/4844/3190 +f 4691/3521/3187 4694/4844/3190 4695/3522/3191 +f 4695/3522/3191 4694/4844/3190 4696/4845/3192 +f 4695/3522/3191 4696/4845/3192 4697/3527/3193 +f 4694/4844/3190 4693/4843/3189 4698/4846/3194 +f 4694/4844/3190 4698/4846/3194 4696/4845/3192 +f 4696/4845/3192 4698/4846/3194 3438/3855/2233 +f 4696/4845/3192 3438/3855/2233 3488/3899/2277 +f 4697/3527/3193 4696/4845/3192 3488/3899/2277 +f 4697/3527/3193 3488/3899/2277 3470/3881/2259 +f 4705/3506/1981 4707/3508/1981 3483/3894/2272 +f 4705/3506/1981 3483/3894/2272 3482/3893/2271 +f 4706/3507/1981 4705/3506/1981 3482/3893/2271 +f 4706/3507/1981 3482/3893/2271 3402/3819/2197 +f 4712/3515/1981 4688/3495/1981 3477/3888/2266 +f 4712/3515/1981 3477/3888/2266 3476/3887/2265 +f 4713/3516/1981 4712/3515/1981 3476/3887/2265 +f 4713/3516/1981 3476/3887/2265 3475/3886/2264 +f 4466/3518/1992 4189/4569/2919 4691/3521/3187 +f 4714/3519/1981 4691/3521/3187 4695/3522/3191 +f 4716/3523/1981 4695/3522/3191 4697/3527/3193 +f 4718/3525/1981 4697/3527/3193 3470/3881/2259 +f 4718/3525/1981 3470/3881/2259 3469/3880/2258 +f 4719/3526/1981 4718/3525/1981 3469/3880/2258 +f 4719/3526/1981 3469/3880/2258 3468/3879/2257 +f 4724/3534/1981 4725/3535/1981 4397/4747/2045 +f 4724/3534/1981 4397/4747/2045 4396/4746/3093 +f 4707/3508/1981 4724/3534/1981 4396/4746/3093 +f 4707/3508/1981 4396/4746/3093 3483/3894/2272 +f 4730/3542/1981 4731/3543/1981 4416/4763/3107 +f 4730/3542/1981 4416/4763/3107 4444/4783/3126 +f 4689/3496/1981 4730/3542/1981 4444/4783/3126 +f 4689/3496/1981 4444/4783/3126 4343/4697/3046 +f 3280/3715/2089 3277/3712/2086 4732/4847/3195 +f 3280/3715/2089 4732/4847/3195 4692/4842/3188 +f 3277/3712/2086 3276/3711/2085 4733/4848/3196 +f 3277/3712/2086 4733/4848/3196 4732/4847/3195 +f 4732/4847/3195 4733/4848/3196 4734/4849/3197 +f 4732/4847/3195 4734/4849/3197 4735/4850/3198 +f 4692/4842/3188 4732/4847/3195 4735/4850/3198 +f 4692/4842/3188 4735/4850/3198 4693/4843/3189 +f 4693/4843/3189 4735/4850/3198 4736/4851/3199 +f 4693/4843/3189 4736/4851/3199 4698/4846/3194 +f 4735/4850/3198 4734/4849/3197 4737/4852/3196 +f 4735/4850/3198 4737/4852/3196 4736/4851/3199 +f 4736/4851/3199 4737/4852/3196 3440/3857/2235 +f 4736/4851/3199 3440/3857/2235 3439/3856/2234 +f 4698/4846/3194 4736/4851/3199 3439/3856/2234 +f 4698/4846/3194 3439/3856/2234 3438/3855/2233 +f 4744/3553/1981 4746/3555/1981 3429/3846/2224 +f 4744/3553/1981 3429/3846/2224 3428/3845/2223 +f 4745/3554/1981 4744/3553/1981 3428/3845/2223 +f 4745/3554/1981 3428/3845/2223 3427/3844/2222 +f 4753/3565/1981 4755/3567/1981 3420/3837/2215 +f 4753/3565/1981 3420/3837/2215 3419/3836/2214 +f 4754/3566/1981 4753/3565/1981 3419/3836/2214 +f 4754/3566/1981 3419/3836/2214 3418/3835/2213 +f 4382/4732/3080 4385/4735/3083 4756/4853/3200 +f 4382/4732/3080 4756/4853/3200 4757/3694/3201 +f 4385/4735/3083 4390/4740/3088 4758/4854/3202 +f 4385/4735/3083 4758/4854/3202 4756/4853/3200 +f 4756/4853/3200 4758/4854/3202 4759/4855/3203 +f 4756/4853/3200 4759/4855/3203 4760/4856/3204 +f 4757/3694/3201 4756/4853/3200 4760/4856/3204 +f 4757/3694/3201 4760/4856/3204 4761/3695/2069 +f 4761/3695/2069 4760/4856/3204 4762/4857/3205 +f 4761/3695/2069 4762/4857/3205 4763/3691/3206 +f 4760/4856/3204 4759/4855/3203 4764/4858/3207 +f 4760/4856/3204 4764/4858/3207 4762/4857/3205 +f 4762/4857/3205 4764/4858/3207 4352/4706/3054 +f 4762/4857/3205 4352/4706/3054 4351/4705/3053 +f 4763/3691/3206 4762/4857/3205 4351/4705/3053 +f 4763/3691/3206 4351/4705/3053 4350/4704/3052 +f 4769/3574/1981 4706/3507/1981 3402/3819/2197 +f 4769/3574/1981 3402/3819/2197 3401/3818/2196 +f 4770/3575/1981 4769/3574/1981 3401/3818/2196 +f 4770/3575/1981 3401/3818/2196 3400/3817/2195 +f 4773/3579/1981 4745/3554/1981 3427/3844/2222 +f 4773/3579/1981 3427/3844/2222 4411/4758/3103 +f 4725/3535/1981 4773/3579/1981 4411/4758/3103 +f 4725/3535/1981 4411/4758/3103 4397/4747/2045 +f 4404/3580/2019 4774/3582/1981 4775/3587/3208 +f 4775/3587/3208 4778/3586/1981 4779/3588/3208 +f 4779/3588/3208 4780/3589/1981 4781/4859/2024 +f 4780/3589/1981 4782/3590/1981 3376/3796/2174 +f 4780/3589/1981 3376/3796/2174 4357/4711/3059 +f 4781/4859/2024 4780/3589/1981 4357/4711/3059 +f 4781/4859/2024 4357/4711/3059 3302/3734/2109 +f 4787/3597/1981 4788/3598/1981 3370/3790/2168 +f 4787/3597/1981 3370/3790/2168 3377/3797/2175 +f 4782/3590/1981 4787/3597/1981 3377/3797/2175 +f 4782/3590/1981 3377/3797/2175 3376/3796/2174 +f 4793/3605/1981 4794/3606/1981 3364/3784/2162 +f 4793/3605/1981 3364/3784/2162 3371/3791/2169 +f 4788/3598/1981 4793/3605/1981 3371/3791/2169 +f 4788/3598/1981 3371/3791/2169 3370/3790/2168 +f 4801/3616/1981 4803/3618/1981 3386/3806/2184 +f 4801/3616/1981 3386/3806/2184 3385/3805/2183 +f 4802/3617/1981 4801/3616/1981 3385/3805/2183 +f 4802/3617/1981 3385/3805/2183 3384/3804/2182 +f 4810/3628/1981 4812/3630/1981 3352/3772/2150 +f 4810/3628/1981 3352/3772/2150 3359/3779/2157 +f 4811/3629/1981 4810/3628/1981 3359/3779/2157 +f 4811/3629/1981 3359/3779/2157 3358/3778/2156 +f 4817/3637/1981 4818/3638/1981 3345/3765/2143 +f 4817/3637/1981 3345/3765/2143 3353/3773/2151 +f 4812/3630/1981 4817/3637/1981 3353/3773/2151 +f 4812/3630/1981 3353/3773/2151 3352/3772/2150 +f 4823/3645/1981 4824/3646/1981 3347/3767/2145 +f 4823/3645/1981 3347/3767/2145 3346/3766/2144 +f 4818/3638/1981 4823/3645/1981 3346/3766/2144 +f 4818/3638/1981 3346/3766/2144 3345/3765/2143 +f 4827/3650/1981 4802/3617/1981 3384/3804/2182 +f 4827/3650/1981 3384/3804/2182 4393/4743/3090 +f 4824/3646/1981 4827/3650/1981 4393/4743/3090 +f 4824/3646/1981 4393/4743/3090 3347/3767/2145 +f 4830/3654/1981 4770/3575/1981 3400/3817/2195 +f 4830/3654/1981 3400/3817/2195 4417/4764/3108 +f 4731/3543/1981 4830/3654/1981 4417/4764/3108 +f 4731/3543/1981 4417/4764/3108 4416/4763/3107 +f 4833/3658/1981 4811/3629/1981 3358/3778/2156 +f 4833/3658/1981 3358/3778/2156 3365/3785/2163 +f 4794/3606/1981 4833/3658/1981 3365/3785/2163 +f 4794/3606/1981 3365/3785/2163 3364/3784/2162 +f 4838/3665/1981 4839/3666/1981 4185/4565/2915 +f 4838/3665/1981 4185/4565/2915 4465/4801/3145 +f 4803/3618/1981 4838/3665/1981 4465/4801/3145 +f 4803/3618/1981 4465/4801/3145 3386/3806/2184 +f 4451/4788/3132 4460/4796/3140 4840/4860/3209 +f 4451/4788/3132 4840/4860/3209 4841/4861/3210 +f 4460/4796/3140 4404/3580/2019 4775/3587/3208 +f 4460/4796/3140 4775/3587/3208 4840/4860/3209 +f 4840/4860/3209 4775/3587/3208 4779/3588/3208 +f 4840/4860/3209 4779/3588/3208 4842/4862/3211 +f 4841/4861/3210 4840/4860/3209 4842/4862/3211 +f 4841/4861/3210 4842/4862/3211 4843/4863/3212 +f 4843/4863/3212 4842/4862/3211 4844/4864/3211 +f 4843/4863/3212 4844/4864/3211 4845/4865/3213 +f 4842/4862/3211 4779/3588/3208 4781/4859/2024 +f 4842/4862/3211 4781/4859/2024 4844/4864/3211 +f 4844/4864/3211 4781/4859/2024 3302/3734/2109 +f 4844/4864/3211 3302/3734/2109 3301/3733/2108 +f 4845/4865/3213 4844/4864/3211 3301/3733/2108 +f 4845/4865/3213 3301/3733/2108 3300/3732/2107 +f 4848/3670/1981 4713/3516/1981 3475/3886/2264 +f 4848/3670/1981 3475/3886/2264 4375/4726/3073 +f 4755/3567/1981 4848/3670/1981 4375/4726/3073 +f 4755/3567/1981 4375/4726/3073 3420/3837/2215 +f 3276/3711/2085 4452/4789/3133 4849/4866/3214 +f 3276/3711/2085 4849/4866/3214 4733/4848/3196 +f 4452/4789/3133 4451/4788/3132 4841/4861/3210 +f 4452/4789/3133 4841/4861/3210 4849/4866/3214 +f 4849/4866/3214 4841/4861/3210 4843/4863/3212 +f 4849/4866/3214 4843/4863/3212 4850/4867/3215 +f 4733/4848/3196 4849/4866/3214 4850/4867/3215 +f 4733/4848/3196 4850/4867/3215 4734/4849/3197 +f 4734/4849/3197 4850/4867/3215 4851/4868/3216 +f 4734/4849/3197 4851/4868/3216 4737/4852/3196 +f 4850/4867/3215 4843/4863/3212 4845/4865/3213 +f 4850/4867/3215 4845/4865/3213 4851/4868/3216 +f 4851/4868/3216 4845/4865/3213 3300/3732/2107 +f 4851/4868/3216 3300/3732/2107 4381/4731/3079 +f 4737/4852/3196 4851/4868/3216 4381/4731/3079 +f 4737/4852/3196 4381/4731/3079 3440/3857/2235 +f 4854/3674/1981 4754/3566/1981 3418/3835/2213 +f 4854/3674/1981 3418/3835/2213 4186/4566/2916 +f 4839/3666/1981 4854/3674/1981 4186/4566/2916 +f 4839/3666/1981 4186/4566/2916 4185/4565/2915 +f 4358/3675/2055 4856/3677/1981 4857/3679/3217 +f 4857/3679/3217 4858/3678/1981 4859/3680/3218 +f 4859/3680/3218 4860/3681/2064 4861/4869/3219 +f 4860/3681/2064 4719/3526/1981 3468/3879/2257 +f 4860/3681/2064 3468/3879/2257 4862/4870/3220 +f 4861/4869/3219 4860/3681/2064 4862/4870/3220 +f 4861/4869/3219 4862/4870/3220 4863/4871/3221 +f 4864/4872/3222 4865/4873/3223 4866/4874/3224 +f 4864/4872/3222 4866/4874/3224 4867/4875/3225 +f 4868/4876/3226 4869/4877/3227 4071/4451/2806 +f 4868/4876/3226 4071/4451/2806 4870/4878/3224 +f 4870/4878/3224 4071/4451/2806 4072/4452/2807 +f 4870/4878/3224 4072/4452/2807 4871/4879/3228 +f 4872/4880/3229 4870/4878/3224 4871/4879/3228 +f 4872/4880/3229 4871/4879/3228 4863/4871/3221 +f 4489/4823/3165 4488/4822/3164 4873/4881/3230 +f 4489/4823/3165 4873/4881/3230 4874/4882/3231 +f 4488/4822/3164 4487/4821/3163 4875/4883/3232 +f 4488/4822/3164 4875/4883/3232 4873/4881/3230 +f 4873/4881/3230 4875/4883/3232 4876/4884/2936 +f 4873/4881/3230 4876/4884/2936 4877/4885/3233 +f 4874/4882/3231 4873/4881/3230 4877/4885/3233 +f 4874/4882/3231 4877/4885/3233 4878/4886/3234 +f 4498/4832/3174 4497/4831/3173 4879/4887/3235 +f 4498/4832/3174 4879/4887/3235 4880/4888/3236 +f 4497/4831/3173 4496/4830/3172 4881/4889/3237 +f 4497/4831/3173 4881/4889/3237 4879/4887/3235 +f 4879/4887/3235 4881/4889/3237 4882/4890/3238 +f 4879/4887/3235 4882/4890/3238 4883/4891/3239 +f 4880/4888/3236 4879/4887/3235 4883/4891/3239 +f 4880/4888/3236 4883/4891/3239 4884/4892/3054 +f 4885/4893/3240 4886/4894/3241 4887/4895/3242 +f 4885/4893/3240 4887/4895/3242 4888/4896/3243 +f 4889/4897/3241 4890/4898/3244 4891/4899/3245 +f 4889/4897/3241 4891/4899/3245 4892/4900/3246 +f 4892/4900/3246 4891/4899/3245 4893/4901/3247 +f 4892/4900/3246 4893/4901/3247 4894/4902/2805 +f 4888/4896/3243 4887/4895/3242 4070/4450/2805 +f 4888/4896/3243 4070/4450/2805 4069/4449/2804 +f 4480/4814/3157 4479/4813/3156 4895/4903/3248 +f 4480/4814/3157 4895/4903/3248 4896/4904/3249 +f 4479/4813/3156 4478/4812/3155 4897/4905/3250 +f 4479/4813/3156 4897/4905/3250 4895/4903/3248 +f 4895/4903/3248 4897/4905/3250 4030/4410/2767 +f 4895/4903/3248 4030/4410/2767 4028/4408/2765 +f 4896/4904/3249 4895/4903/3248 4028/4408/2765 +f 4896/4904/3249 4028/4408/2765 4027/4407/2284 +f 3815/4195/2563 4898/4906/3251 4899/4907/3252 +f 3815/4195/2563 4899/4907/3252 3816/4196/2564 +f 4898/4906/3251 4175/4555/2199 4178/4558/2908 +f 4898/4906/3251 4178/4558/2908 4899/4907/3252 +f 4899/4907/3252 4178/4558/2908 4180/4560/2910 +f 4899/4907/3252 4180/4560/2910 4900/4908/3253 +f 3816/4196/2564 4899/4907/3252 4900/4908/3253 +f 3816/4196/2564 4900/4908/3253 3817/4197/2565 +f 4901/4909/3254 4902/4910/3255 4903/4911/3256 +f 4901/4909/3254 4903/4911/3256 4904/4912/3257 +f 4902/4910/3255 3960/4340/2703 3963/4343/2706 +f 4902/4910/3255 3963/4343/2706 4903/4911/3256 +f 4903/4911/3256 3963/4343/2706 3968/4348/2445 +f 4903/4911/3256 3968/4348/2445 4905/4913/3258 +f 4904/4912/3257 4903/4911/3256 4905/4913/3258 +f 4904/4912/3257 4905/4913/3258 4906/4914/2441 +f 4045/4425/2782 4044/4424/2781 4907/4915/3259 +f 4045/4425/2782 4907/4915/3259 4908/4916/3260 +f 4041/4421/2778 4040/4420/2777 4909/4917/3261 +f 4041/4421/2778 4909/4917/3261 4910/4918/3259 +f 4910/4918/3259 4909/4917/3261 4890/4898/3244 +f 4910/4918/3259 4890/4898/3244 4889/4897/3241 +f 4908/4916/3260 4907/4915/3259 4886/4894/3241 +f 4908/4916/3260 4886/4894/3241 4885/4893/3240 +f 4012/4392/2751 4011/4391/2750 4911/4919/3262 +f 4012/4392/2751 4911/4919/3262 4912/4920/3263 +f 4011/4391/2750 4010/4390/2749 4913/4921/3264 +f 4011/4391/2750 4913/4921/3264 4911/4919/3262 +f 4911/4919/3262 4913/4921/3264 4101/4481/2834 +f 4911/4919/3262 4101/4481/2834 4098/4478/2831 +f 4912/4920/3263 4911/4919/3262 4098/4478/2831 +f 4912/4920/3263 4098/4478/2831 4097/4477/2830 +f 4914/4922/3265 4915/4923/3266 4916/4924/3267 +f 4914/4922/3265 4916/4924/3267 4917/4925/3268 +f 4915/4923/3266 4878/4886/3234 4877/4885/3233 +f 4915/4923/3266 4877/4885/3233 4916/4924/3267 +f 4916/4924/3267 4877/4885/3233 4876/4884/2936 +f 4916/4924/3267 4876/4884/2936 4918/4926/2935 +f 4917/4925/3268 4916/4924/3267 4918/4926/2935 +f 4917/4925/3268 4918/4926/2935 4919/4927/3269 +f 4920/4928/3270 4921/4929/3271 4922/4930/3272 +f 4920/4928/3270 4922/4930/3272 4923/4931/3273 +f 4921/4929/3271 4924/4932/3274 4925/4933/3275 +f 4921/4929/3271 4925/4933/3275 4922/4930/3272 +f 4922/4930/3272 4925/4933/3275 4926/4934/3276 +f 4922/4930/3272 4926/4934/3276 4927/4935/3277 +f 4923/4931/3273 4922/4930/3272 4927/4935/3277 +f 4923/4931/3273 4927/4935/3277 4928/4936/3278 +f 3409/3826/2204 4929/4937/3279 4930/4938/3280 +f 3409/3826/2204 4930/4938/3280 3410/3827/2205 +f 4929/4937/3279 3258/3696/2070 3261/3699/2073 +f 4929/4937/3279 3261/3699/2073 4930/4938/3280 +f 4930/4938/3280 3261/3699/2073 3266/3704/2078 +f 4930/4938/3280 3266/3704/2078 4931/4939/3281 +f 3410/3827/2205 4930/4938/3280 4931/4939/3281 +f 3410/3827/2205 4931/4939/3281 3411/3828/2206 +f 3881/4261/2626 3880/4260/2625 4932/4940/3282 +f 3881/4261/2626 4932/4940/3282 4933/4941/3283 +f 3880/4260/2625 3879/4259/2624 4934/4942/3011 +f 3880/4260/2625 4934/4942/3011 4932/4940/3282 +f 4932/4940/3282 4934/4942/3011 4935/4943/3284 +f 4932/4940/3282 4935/4943/3284 4936/4944/3285 +f 4933/4941/3283 4932/4940/3282 4936/4944/3285 +f 4933/4941/3283 4936/4944/3285 4937/4945/3286 +f 4928/4936/3278 4927/4935/3277 4938/4946/3287 +f 4928/4936/3278 4938/4946/3287 4939/4947/3288 +f 4927/4935/3277 4926/4934/3276 4940/4948/3289 +f 4927/4935/3277 4940/4948/3289 4938/4946/3287 +f 4938/4946/3287 4940/4948/3289 4941/4949/3290 +f 4938/4946/3287 4941/4949/3290 4942/4950/3291 +f 4939/4947/3288 4938/4946/3287 4942/4950/3291 +f 4939/4947/3288 4942/4950/3291 4943/4951/3292 +f 4937/4945/3286 4936/4944/3285 4944/4952/3293 +f 4937/4945/3286 4944/4952/3293 4945/4953/3294 +f 4936/4944/3285 4935/4943/3284 4946/4954/3295 +f 4936/4944/3285 4946/4954/3295 4944/4952/3293 +f 4944/4952/3293 4946/4954/3295 3859/4239/2605 +f 4944/4952/3293 3859/4239/2605 3856/4236/2602 +f 4945/4953/3294 4944/4952/3293 3856/4236/2602 +f 4945/4953/3294 3856/4236/2602 3855/4235/2601 +f 4947/4955/3296 4948/4956/3297 4949/4957/3298 +f 4947/4955/3296 4949/4957/3298 4950/4958/3299 +f 4948/4956/3297 4951/4959/2322 4952/4960/3300 +f 4948/4956/3297 4952/4960/3300 4949/4957/3298 +f 4949/4957/3298 4952/4960/3300 4953/4961/3301 +f 4949/4957/3298 4953/4961/3301 4954/4962/3302 +f 4950/4958/3299 4949/4957/3298 4954/4962/3302 +f 4950/4958/3299 4954/4962/3302 4955/4963/3303 +f 4105/4485/2837 4104/4484/2836 4956/4964/3304 +f 4105/4485/2837 4956/4964/3304 4957/4965/3305 +f 4104/4484/2836 4103/4483/2835 4958/4966/3306 +f 4104/4484/2836 4958/4966/3306 4956/4964/3304 +f 4956/4964/3304 4958/4966/3306 4959/4967/2622 +f 4956/4964/3304 4959/4967/2622 4960/4968/2619 +f 4957/4965/3305 4956/4964/3304 4960/4968/2619 +f 4957/4965/3305 4960/4968/2619 4961/4969/2618 +f 4962/4970/3307 4963/4971/3308 4964/4972/3309 +f 4962/4970/3307 4964/4972/3309 4965/4973/3310 +f 4963/4971/3308 4966/4974/2349 4967/4975/3311 +f 4963/4971/3308 4967/4975/3311 4964/4972/3309 +f 4964/4972/3309 4967/4975/3311 4968/4976/3312 +f 4964/4972/3309 4968/4976/3312 4969/4977/3313 +f 4965/4973/3310 4964/4972/3309 4969/4977/3313 +f 4965/4973/3310 4969/4977/3313 4970/4978/3314 +f 3944/4324/2688 3943/4323/2687 4971/4979/3315 +f 3944/4324/2688 4971/4979/3315 4972/4980/3316 +f 3943/4323/2687 3942/4322/2686 4973/4981/3317 +f 3943/4323/2687 4973/4981/3317 4971/4979/3315 +f 4971/4979/3315 4973/4981/3317 4008/4388/2747 +f 4971/4979/3315 4008/4388/2747 4005/4385/2744 +f 4972/4980/3316 4971/4979/3315 4005/4385/2744 +f 4972/4980/3316 4005/4385/2744 4004/4384/2743 +f 4955/4963/3303 4954/4962/3302 4974/4982/3318 +f 4955/4963/3303 4974/4982/3318 4975/4983/3319 +f 4954/4962/3302 4953/4961/3301 4976/4984/3320 +f 4954/4962/3302 4976/4984/3320 4974/4982/3318 +f 4974/4982/3318 4976/4984/3320 4966/4974/2349 +f 4974/4982/3318 4966/4974/2349 4963/4971/3308 +f 4975/4983/3319 4974/4982/3318 4963/4971/3308 +f 4975/4983/3319 4963/4971/3308 4962/4970/3307 +f 4977/4985/3321 4978/4986/3322 4979/4987/3323 +f 4977/4985/3321 4979/4987/3323 4980/4988/3324 +f 4978/4986/3322 4981/4989/3325 4982/4990/3326 +f 4978/4986/3322 4982/4990/3326 4979/4987/3323 +f 4979/4987/3323 4982/4990/3326 3940/4320/2684 +f 4979/4987/3323 3940/4320/2684 3937/4317/2681 +f 4980/4988/3324 4979/4987/3323 3937/4317/2681 +f 4980/4988/3324 3937/4317/2681 3936/4316/2680 +f 4983/4991/2886 4984/4992/3327 4985/4993/3328 +f 4983/4991/2886 4985/4993/3328 4986/4994/3329 +f 4984/4992/3327 4884/4892/3054 4883/4891/3239 +f 4984/4992/3327 4883/4891/3239 4985/4993/3328 +f 4985/4993/3328 4883/4891/3239 4882/4890/3238 +f 4985/4993/3328 4882/4890/3238 4987/4995/3330 +f 4986/4994/3329 4985/4993/3328 4987/4995/3330 +f 4986/4994/3329 4987/4995/3330 4988/4996/2888 +f 4989/4997/3331 4990/4998/3332 4991/4999/3333 +f 4989/4997/3331 4991/4999/3333 4992/5000/3334 +f 4990/4998/3332 4993/5001/3335 4994/5002/3016 +f 4990/4998/3332 4994/5002/3016 4991/4999/3333 +f 4991/4999/3333 4994/5002/3016 4995/5003/2370 +f 4991/4999/3333 4995/5003/2370 4996/5004/3336 +f 4992/5000/3334 4991/4999/3333 4996/5004/3336 +f 4992/5000/3334 4996/5004/3336 4997/5005/3270 +f 4998/5006/3337 4999/5007/3338 5000/5008/3339 +f 4998/5006/3337 5000/5008/3339 5001/5009/3340 +f 4999/5007/3338 4222/4600/2950 5002/5010/3341 +f 4999/5007/3338 5002/5010/3341 5000/5008/3339 +f 5000/5008/3339 5002/5010/3341 3506/3915/2293 +f 5000/5008/3339 3506/3915/2293 3986/4366/2727 +f 5001/5009/3340 5000/5008/3339 3986/4366/2727 +f 5001/5009/3340 3986/4366/2727 3985/4365/2726 +f 5003/5011/3342 5004/5012/3343 5005/5013/3344 +f 5003/5011/3342 5005/5013/3344 5006/5014/3345 +f 5004/5012/3343 5007/5015/3346 5008/5016/3347 +f 5004/5012/3343 5008/5016/3347 5005/5013/3344 +f 5005/5013/3344 5008/5016/3347 4131/4511/2862 +f 5005/5013/3344 4131/4511/2862 4128/4508/2859 +f 5006/5014/3345 5005/5013/3344 4128/4508/2859 +f 5006/5014/3345 4128/4508/2859 4127/4507/2858 +f 3991/4371/2732 3990/4370/2731 5009/5017/3348 +f 3991/4371/2732 5009/5017/3348 5010/5018/3349 +f 3990/4370/2731 3989/4369/2730 5011/5019/3350 +f 3990/4370/2731 5011/5019/3350 5009/5017/3348 +f 5009/5017/3348 5011/5019/3350 4981/4989/3325 +f 5009/5017/3348 4981/4989/3325 4978/4986/3322 +f 5010/5018/3349 5009/5017/3348 4978/4986/3322 +f 5010/5018/3349 4978/4986/3322 4977/4985/3321 +f 3850/4230/2128 5012/5020/3351 5013/5021/3352 +f 3850/4230/2128 5013/5021/3352 3851/4231/2597 +f 5012/5020/3351 4013/4393/2752 4016/4396/2755 +f 5012/5020/3351 4016/4396/2755 5013/5021/3352 +f 5013/5021/3352 4016/4396/2755 4018/4398/2757 +f 5013/5021/3352 4018/4398/2757 5014/5022/3353 +f 3851/4231/2597 5013/5021/3352 5014/5022/3353 +f 3851/4231/2597 5014/5022/3353 3852/4232/2598 +f 4135/4515/2866 4134/4514/2865 5015/5023/3354 +f 4135/4515/2866 5015/5023/3354 5016/5024/3355 +f 4134/4514/2865 4133/4513/2864 5017/5025/2971 +f 4134/4514/2865 5017/5025/2971 5015/5023/3354 +f 5015/5023/3354 5017/5025/2971 5018/5026/2432 +f 5015/5023/3354 5018/5026/2432 5019/5027/3356 +f 5016/5024/3355 5015/5023/3354 5019/5027/3356 +f 5016/5024/3355 5019/5027/3356 5020/5028/3357 +f 5021/5029/3358 5022/5030/3359 5023/5031/3360 +f 5021/5029/3358 5023/5031/3360 5024/5032/3361 +f 5022/5030/3359 5025/5033/3362 5026/5034/3363 +f 5022/5030/3359 5026/5034/3363 5023/5031/3360 +f 5023/5031/3360 5026/5034/3363 4002/4382/2741 +f 5023/5031/3360 4002/4382/2741 3999/4379/2738 +f 5024/5032/3361 5023/5031/3360 3999/4379/2738 +f 5024/5032/3361 3999/4379/2738 3998/4378/2737 +f 3842/4222/2589 5027/5035/3364 5028/5036/3365 +f 3842/4222/2589 5028/5036/3365 3843/4223/2590 +f 5027/5035/3364 5029/5037/3366 5030/5038/3367 +f 5027/5035/3364 5030/5038/3367 5028/5036/3365 +f 5028/5036/3365 5030/5038/3367 5031/5039/3368 +f 5028/5036/3365 5031/5039/3368 5032/5040/3014 +f 3843/4223/2590 5028/5036/3365 5032/5040/3014 +f 3843/4223/2590 5032/5040/3014 3844/4224/2591 +f 5033/5041/3369 5034/5042/3370 5035/5043/3371 +f 5033/5041/3369 5035/5043/3371 5036/5044/3372 +f 5034/5042/3370 5037/5045/3265 5038/5046/3373 +f 5034/5042/3370 5038/5046/3373 5035/5043/3371 +f 5035/5043/3371 5038/5046/3373 5039/5047/2934 +f 5035/5043/3371 5039/5047/2934 5040/5048/3374 +f 5036/5044/3372 5035/5043/3371 5040/5048/3374 +f 5036/5044/3372 5040/5048/3374 5041/5049/2930 +f 4168/4548/2899 4167/4547/2898 5042/5050/3375 +f 4168/4548/2899 5042/5050/3375 5043/5051/3376 +f 4167/4547/2898 4166/4546/2897 4333/4688/3038 +f 4167/4547/2898 4333/4688/3038 5042/5050/3375 +f 5042/5050/3375 4333/4688/3038 4336/4691/3041 +f 5042/5050/3375 4336/4691/3041 5044/5052/3377 +f 5043/5051/3376 5042/5050/3375 5044/5052/3377 +f 5043/5051/3376 5044/5052/3377 5045/5053/3378 +f 4078/4458/2812 4077/4457/2811 5046/5054/3379 +f 4078/4458/2812 5046/5054/3379 5047/5055/3380 +f 4077/4457/2811 4076/4456/2810 5048/5056/3381 +f 4077/4457/2811 5048/5056/3381 5046/5054/3379 +f 5046/5054/3379 5048/5056/3381 5049/5057/3382 +f 5046/5054/3379 5049/5057/3382 5050/5058/3383 +f 5047/5055/3380 5046/5054/3379 5050/5058/3383 +f 5047/5055/3380 5050/5058/3383 5051/5059/3137 +f 5052/5060/3384 5053/5061/3385 5054/5062/3386 +f 5052/5060/3384 5054/5062/3386 5055/5063/3387 +f 5053/5061/3385 5056/5064/3388 5057/5065/3389 +f 5053/5061/3385 5057/5065/3389 5054/5062/3386 +f 5054/5062/3386 5057/5065/3389 5058/5066/2301 +f 5054/5062/3386 5058/5066/2301 5059/5067/3390 +f 5055/5063/3387 5054/5062/3386 5059/5067/3390 +f 5055/5063/3387 5059/5067/3390 5060/5068/3391 +f 5020/5028/3357 5019/5027/3356 5061/5069/3392 +f 5020/5028/3357 5061/5069/3392 5062/5070/3393 +f 5019/5027/3356 5018/5026/2432 5063/5071/3394 +f 5019/5027/3356 5063/5071/3394 5061/5069/3392 +f 5061/5069/3392 5063/5071/3394 4164/4544/2895 +f 5061/5069/3392 4164/4544/2895 4161/4541/2892 +f 5062/5070/3393 5061/5069/3392 4161/4541/2892 +f 5062/5070/3393 4161/4541/2892 4160/4540/2891 +f 5064/5072/3395 5065/5073/3396 5066/5074/3397 +f 5064/5072/3395 5066/5074/3397 5067/5075/3398 +f 5065/5073/3396 5068/5076/3399 5069/5077/3400 +f 5065/5073/3396 5069/5077/3400 5066/5074/3397 +f 5066/5074/3397 5069/5077/3400 5070/5078/3401 +f 5066/5074/3397 5070/5078/3401 5071/5079/3402 +f 5067/5075/3398 5066/5074/3397 5071/5079/3402 +f 5067/5075/3398 5071/5079/3402 5072/5080/3403 +f 5073/5081/3404 5074/5082/3405 5075/5083/3406 +f 5073/5081/3404 5075/5083/3406 5076/5084/3407 +f 5074/5082/3405 5064/5072/3395 5067/5075/3398 +f 5074/5082/3405 5067/5075/3398 5075/5083/3406 +f 5075/5083/3406 5067/5075/3398 5072/5080/3403 +f 5075/5083/3406 5072/5080/3403 5077/5085/3408 +f 5076/5084/3407 5075/5083/3406 5077/5085/3408 +f 5076/5084/3407 5077/5085/3408 5078/5086/3409 +f 4864/4872/3222 5079/5087/3410 5080/5088/3411 +f 4864/4872/3222 5080/5088/3411 4865/4873/3223 +f 5079/5087/3410 5081/5089/3412 5082/5090/3413 +f 5079/5087/3410 5082/5090/3413 5080/5088/3411 +f 5080/5088/3411 5082/5090/3413 4065/4445/2800 +f 5080/5088/3411 4065/4445/2800 4062/4442/2797 +f 4865/4873/3223 5080/5088/3411 4062/4442/2797 +f 4865/4873/3223 4062/4442/2797 4061/4441/2796 +f 3779/4159/2260 5083/5091/2263 5084/5092/3414 +f 3779/4159/2260 5084/5092/3414 3780/4160/2536 +f 5083/5091/2263 5085/5093/3415 5086/5094/3416 +f 5083/5091/2263 5086/5094/3416 5084/5092/3414 +f 5084/5092/3414 5086/5094/3416 5087/5095/2679 +f 5084/5092/3414 5087/5095/2679 5088/5096/3417 +f 3780/4160/2536 5084/5092/3414 5088/5096/3417 +f 3780/4160/2536 5088/5096/3417 3781/4161/2537 +f 5051/5059/3137 5050/5058/3383 5089/5097/3418 +f 5051/5059/3137 5089/5097/3418 5090/5098/3419 +f 5050/5058/3383 5049/5057/3382 5091/5099/3420 +f 5050/5058/3383 5091/5099/3420 5089/5097/3418 +f 5089/5097/3418 5091/5099/3420 3925/4305/2669 +f 5089/5097/3418 3925/4305/2669 3922/4302/2666 +f 5090/5098/3419 5089/5097/3418 3922/4302/2666 +f 5090/5098/3419 3922/4302/2666 3921/4301/2665 +f 3959/4339/2231 3958/4338/2702 5092/5100/3421 +f 3959/4339/2231 5092/5100/3421 5093/5101/2275 +f 3958/4338/2702 3957/4337/2701 5094/5102/3422 +f 3958/4338/2702 5094/5102/3422 5092/5100/3421 +f 5092/5100/3421 5094/5102/3422 3981/4361/2722 +f 5092/5100/3421 3981/4361/2722 3979/4359/2720 +f 5093/5101/2275 5092/5100/3421 3979/4359/2720 +f 5093/5101/2275 3979/4359/2720 3978/4358/2249 +f 3992/4372/2176 5095/5103/3144 5096/5104/3423 +f 3992/4372/2176 5096/5104/3423 3993/4373/2733 +f 5095/5103/3144 3906/4286/2650 3909/4289/2653 +f 5095/5103/3144 3909/4289/2653 5096/5104/3423 +f 5096/5104/3423 3909/4289/2653 3911/4291/2655 +f 5096/5104/3423 3911/4291/2655 5097/5105/3424 +f 3993/4373/2733 5096/5104/3423 5097/5105/3424 +f 3993/4373/2733 5097/5105/3424 3996/4376/2735 +f 3929/4309/2673 3928/4308/2672 5098/5106/3425 +f 3929/4309/2673 5098/5106/3425 5099/5107/3426 +f 3928/4308/2672 3927/4307/2671 5100/5108/3427 +f 3928/4308/2672 5100/5108/3427 5098/5106/3425 +f 5098/5106/3425 5100/5108/3427 3901/4281/2645 +f 5098/5106/3425 3901/4281/2645 3898/4278/2643 +f 5099/5107/3426 5098/5106/3425 3898/4278/2643 +f 5099/5107/3426 3898/4278/2643 3897/4277/2642 +f 3964/4344/2707 5101/5109/3428 5102/5110/3429 +f 3964/4344/2707 5102/5110/3429 3965/4345/2708 +f 5101/5109/3428 5103/5111/3430 5104/5112/3431 +f 5101/5109/3428 5104/5112/3431 5102/5110/3429 +f 5102/5110/3429 5104/5112/3431 5105/5113/2409 +f 5102/5110/3429 5105/5113/2409 5106/5114/3432 +f 3965/4345/2708 5102/5110/3429 5106/5114/3432 +f 3965/4345/2708 5106/5114/3432 3966/4346/2709 +f 3905/4285/2649 3904/4284/2648 5107/5115/3433 +f 3905/4285/2649 5107/5115/3433 5108/5116/3116 +f 3904/4284/2648 3903/4283/2647 5109/5117/3434 +f 3904/4284/2648 5109/5117/3434 5107/5115/3433 +f 5107/5115/3433 5109/5117/3434 5110/5118/2631 +f 5107/5115/3433 5110/5118/2631 5111/5119/3435 +f 5108/5116/3116 5107/5115/3433 5111/5119/3435 +f 5108/5116/3116 5111/5119/3435 5112/5120/2627 +f 4039/4419/2776 4038/4418/2775 5113/5121/3436 +f 4039/4419/2776 5113/5121/3436 5114/5122/3437 +f 4038/4418/2775 4037/4417/2774 5115/5123/3438 +f 4038/4418/2775 5115/5123/3438 5113/5121/3436 +f 5113/5121/3436 5115/5123/3438 3916/4296/2660 +f 5113/5121/3436 3916/4296/2660 3913/4293/2657 +f 5114/5122/3437 5113/5121/3436 3913/4293/2657 +f 5114/5122/3437 3913/4293/2657 3912/4292/2656 +f 4117/4497/2849 4116/4496/2848 5116/5124/3439 +f 4117/4497/2849 5116/5124/3439 5117/5125/3440 +f 4116/4496/2848 4115/4495/2847 5118/5126/3441 +f 4116/4496/2848 5118/5126/3441 5116/5124/3439 +f 5116/5124/3439 5118/5126/3441 4149/4529/2880 +f 5116/5124/3439 4149/4529/2880 4146/4526/2877 +f 5117/5125/3440 5116/5124/3439 4146/4526/2877 +f 5117/5125/3440 4146/4526/2877 4145/4525/2876 +f 4126/4506/2857 4125/4505/2856 5119/5127/3442 +f 4126/4506/2857 5119/5127/3442 5120/5128/3443 +f 4125/4505/2856 4124/4504/2855 5121/5129/3444 +f 4125/4505/2856 5121/5129/3444 5119/5127/3442 +f 5119/5127/3442 5121/5129/3444 4035/4415/2772 +f 5119/5127/3442 4035/4415/2772 4032/4412/2769 +f 5120/5128/3443 5119/5127/3442 4032/4412/2769 +f 5120/5128/3443 4032/4412/2769 4031/4411/2768 +f 4943/4951/3292 4942/4950/3291 5122/5130/3445 +f 4943/4951/3292 5122/5130/3445 5123/5131/3446 +f 4942/4950/3291 4941/4949/3290 5124/5132/3447 +f 4942/4950/3291 5124/5132/3447 5122/5130/3445 +f 5122/5130/3445 5124/5132/3447 5007/5015/3346 +f 5122/5130/3445 5007/5015/3346 5004/5012/3343 +f 5123/5131/3446 5122/5130/3445 5004/5012/3343 +f 5123/5131/3446 5004/5012/3343 5003/5011/3342 +f 5125/5133/2154 5126/5134/3448 5127/5135/3449 +f 5125/5133/2154 5127/5135/3449 5128/5136/3450 +f 5126/5134/3448 5129/5137/2794 5130/5138/3451 +f 5126/5134/3448 5130/5138/3451 5127/5135/3449 +f 5127/5135/3449 5130/5138/3451 4122/4502/2853 +f 5127/5135/3449 4122/4502/2853 4119/4499/2850 +f 5128/5136/3450 5127/5135/3449 4119/4499/2850 +f 5128/5136/3450 4119/4499/2850 4118/4498/2160 +f 3821/4201/2569 5131/5139/3452 5132/5140/3453 +f 3821/4201/2569 5132/5140/3453 3822/4202/2570 +f 5131/5139/3452 3834/4214/2113 3837/4217/2584 +f 5131/5139/3452 3837/4217/2584 5132/5140/3453 +f 5132/5140/3453 3837/4217/2584 3839/4219/2586 +f 5132/5140/3453 3839/4219/2586 5133/5141/3454 +f 3822/4202/2570 5132/5140/3453 5133/5141/3454 +f 3822/4202/2570 5133/5141/3454 3823/4203/2571 +f 4096/4476/2829 4095/4475/2828 5134/5142/3455 +f 4096/4476/2829 5134/5142/3455 5135/5143/2146 +f 4095/4475/2828 4094/4474/2827 5136/5144/3456 +f 4095/4475/2828 5136/5144/3456 5134/5142/3455 +f 5134/5142/3455 5136/5144/3456 4056/4436/2792 +f 5134/5142/3455 4056/4436/2792 4053/4433/2789 +f 5135/5143/2146 5134/5142/3455 4053/4433/2789 +f 5135/5143/2146 4053/4433/2789 4052/4432/2148 +f 4970/4978/3314 4969/4977/3313 5137/5145/3457 +f 4970/4978/3314 5137/5145/3457 5138/5146/3458 +f 4969/4977/3313 4968/4976/3312 5139/5147/3459 +f 4969/4977/3313 5139/5147/3459 5137/5145/3457 +f 5137/5145/3457 5139/5147/3459 4993/5001/3335 +f 5137/5145/3457 4993/5001/3335 4990/4998/3332 +f 5138/5146/3458 5137/5145/3457 4990/4998/3332 +f 5138/5146/3458 4990/4998/3332 4989/4997/3331 +f 5140/5148/3460 5141/5149/3461 5142/5150/3462 +f 5140/5148/3460 5142/5150/3462 5143/5151/3463 +f 5141/5149/3461 5052/5060/3384 5055/5063/3387 +f 5141/5149/3461 5055/5063/3387 5142/5150/3462 +f 5142/5150/3462 5055/5063/3387 5060/5068/3391 +f 5142/5150/3462 5060/5068/3391 5144/5152/3464 +f 5143/5151/3463 5142/5150/3462 5144/5152/3464 +f 5143/5151/3463 5144/5152/3464 5145/5153/3465 +f 5056/5064/3388 5146/5154/3466 5147/5155/3467 +f 5056/5064/3388 5147/5155/3467 5057/5065/3389 +f 5146/5154/3466 4106/4486/2838 4109/4489/2841 +f 5146/5154/3466 4109/4489/2841 5147/5155/3467 +f 5147/5155/3467 4109/4489/2841 4111/4491/2843 +f 5147/5155/3467 4111/4491/2843 5148/5156/3468 +f 5057/5065/3389 5147/5155/3467 5148/5156/3468 +f 5057/5065/3389 5148/5156/3468 5058/5066/2301 +f 4947/4955/3296 5149/5157/3469 5150/5158/3470 +f 4947/4955/3296 5150/5158/3470 4948/4956/3297 +f 5149/5157/3469 5151/5159/3471 5152/5160/3472 +f 5149/5157/3469 5152/5160/3472 5150/5158/3470 +f 5150/5158/3470 5152/5160/3472 5153/5161/3473 +f 5150/5158/3470 5153/5161/3473 5154/5162/2323 +f 4948/4956/3297 5150/5158/3470 5154/5162/2323 +f 4948/4956/3297 5154/5162/2323 4951/4959/2322 +f 5029/5037/3366 5155/5163/3474 5156/5164/3475 +f 5029/5037/3366 5156/5164/3475 5030/5038/3367 +f 5155/5163/3474 5157/5165/3476 5158/5166/3477 +f 5155/5163/3474 5158/5166/3477 5156/5164/3475 +f 5156/5164/3475 5158/5166/3477 5159/5167/2313 +f 5156/5164/3475 5159/5167/2313 5160/5168/2926 +f 5030/5038/3367 5156/5164/3475 5160/5168/2926 +f 5030/5038/3367 5160/5168/2926 5031/5039/3368 +f 5157/5165/3476 5161/5169/3478 5162/5170/3479 +f 5157/5165/3476 5162/5170/3479 5158/5166/3477 +f 5163/5171/3478 5140/5148/3460 5143/5151/3463 +f 5163/5171/3478 5143/5151/3463 5164/5172/3479 +f 5164/5172/3479 5143/5151/3463 5145/5153/3465 +f 5164/5172/3479 5145/5153/3465 5165/5173/3480 +f 5158/5166/3477 5162/5170/3479 5166/5174/3481 +f 5158/5166/3477 5166/5174/3481 5159/5167/2313 +f 5167/5175/3482 5168/5176/3483 5169/5177/3484 +f 5167/5175/3482 5169/5177/3484 5170/5178/3485 +f 5168/5176/3483 5073/5081/3404 5076/5084/3407 +f 5168/5176/3483 5076/5084/3407 5169/5177/3484 +f 5169/5177/3484 5076/5084/3407 5078/5086/3409 +f 5169/5177/3484 5078/5086/3409 5171/5179/3486 +f 5170/5178/3485 5169/5177/3484 5171/5179/3486 +f 5170/5178/3485 5171/5179/3486 5172/5180/3487 +f 5151/5159/3471 5173/5181/3488 5174/5182/3489 +f 5151/5159/3471 5174/5182/3489 5152/5160/3472 +f 5173/5181/3488 5167/5175/3482 5170/5178/3485 +f 5173/5181/3488 5170/5178/3485 5174/5182/3489 +f 5174/5182/3489 5170/5178/3485 5172/5180/3487 +f 5174/5182/3489 5172/5180/3487 5175/5183/3490 +f 5152/5160/3472 5174/5182/3489 5175/5183/3490 +f 5152/5160/3472 5175/5183/3490 5153/5161/3473 +f 3892/4272/2637 5176/5184/3491 5177/5185/3492 +f 3892/4272/2637 5177/5185/3492 3893/4273/2638 +f 5176/5184/3491 3948/4328/2692 3951/4331/2695 +f 5176/5184/3491 3951/4331/2695 5177/5185/3492 +f 5177/5185/3492 3951/4331/2695 3953/4333/2697 +f 5177/5185/3492 3953/4333/2697 5178/5186/3493 +f 3893/4273/2638 5177/5185/3492 5178/5186/3493 +f 3893/4273/2638 5178/5186/3493 3894/4274/2639 +f 5179/5187/3399 5180/5188/3494 5181/5189/3495 +f 5179/5187/3399 5181/5189/3495 5182/5190/3400 +f 5180/5188/3494 4901/4909/3254 4904/4912/3257 +f 5180/5188/3494 4904/4912/3257 5181/5189/3495 +f 5181/5189/3495 4904/4912/3257 4906/4914/2441 +f 5181/5189/3495 4906/4914/2441 5183/5191/3496 +f 5182/5190/3400 5181/5189/3495 5183/5191/3496 +f 5182/5190/3400 5183/5191/3496 5184/5192/3401 +f 4490/4824/3166 5185/5193/3497 5186/5194/3498 +f 4490/4824/3166 5186/5194/3498 4491/4825/3167 +f 5185/5193/3497 5187/5195/3499 5188/5196/3500 +f 5185/5193/3497 5188/5196/3500 5186/5194/3498 +f 5186/5194/3498 5188/5196/3500 5189/5197/3501 +f 5186/5194/3498 5189/5197/3501 5190/5198/3502 +f 4491/4825/3167 5186/5194/3498 5190/5198/3502 +f 4491/4825/3167 5190/5198/3502 4494/4828/3170 +f 5103/5111/3430 5191/5199/3503 5192/5200/3504 +f 5103/5111/3430 5192/5200/3504 5104/5112/3431 +f 5191/5199/3503 3405/3822/2200 3408/3825/2203 +f 5191/5199/3503 3408/3825/2203 5192/5200/3504 +f 5192/5200/3504 3408/3825/2203 3413/3830/2208 +f 5192/5200/3504 3413/3830/2208 5193/5201/2469 +f 5104/5112/3431 5192/5200/3504 5193/5201/2469 +f 5104/5112/3431 5193/5201/2469 5105/5113/2409 +f 5194/5202/3505 5195/5203/3506 5196/5204/3507 +f 5194/5202/3505 5196/5204/3507 5197/5205/3508 +f 5195/5203/3506 5198/5206/3509 5199/5207/3510 +f 5195/5203/3506 5199/5207/3510 5196/5204/3507 +f 5196/5204/3507 5199/5207/3510 5200/5208/3511 +f 5196/5204/3507 5200/5208/3511 5201/5209/3512 +f 5197/5205/3508 5196/5204/3507 5201/5209/3512 +f 5197/5205/3508 5201/5209/3512 5202/5210/3513 +f 4481/4815/3158 5203/5211/3514 5204/5212/3515 +f 4481/4815/3158 5204/5212/3515 4482/4816/3159 +f 5203/5211/3514 5205/5213/3516 5206/5214/3517 +f 5203/5211/3514 5206/5214/3517 5204/5212/3515 +f 5204/5212/3515 5206/5214/3517 5207/5215/3518 +f 5204/5212/3515 5207/5215/3518 5208/5216/2979 +f 4482/4816/3159 5204/5212/3515 5208/5216/2979 +f 4482/4816/3159 5208/5216/2979 4485/4819/2978 +f 4476/4810/3153 4473/4807/3150 5209/5217/3519 +f 4476/4810/3153 5209/5217/3519 5210/5218/3520 +f 4473/4807/3150 4472/4806/2956 5211/5219/3521 +f 4473/4807/3150 5211/5219/3521 5209/5217/3519 +f 5209/5217/3519 5211/5219/3521 5212/5220/3522 +f 5209/5217/3519 5212/5220/3522 5213/5221/3523 +f 5214/5222/3524 5215/5223/3525 5216/5224/3526 +f 5214/5222/3524 5216/5224/3526 5217/5225/3527 +f 5218/5226/3528 5219/5227/3529 5220/5228/3530 +f 5218/5226/3528 5220/5228/3530 5221/5229/3531 +f 5219/5227/3529 5222/5230/3532 5223/5231/3533 +f 5219/5227/3529 5223/5231/3533 5220/5228/3530 +f 5220/5228/3530 5223/5231/3533 4988/4996/2888 +f 5220/5228/3530 4988/4996/2888 4987/4995/3330 +f 5221/5229/3531 5220/5228/3530 4987/4995/3330 +f 5221/5229/3531 4987/4995/3330 4882/4890/3238 +f 4481/4815/3158 4484/4818/3161 5224/5232/3534 +f 4481/4815/3158 5224/5232/3534 5225/5233/3535 +f 4484/4818/3161 4489/4823/3165 5226/5234/3536 +f 4484/4818/3161 5226/5234/3536 5224/5232/3534 +f 5224/5232/3534 5226/5234/3536 5227/5235/3537 +f 5224/5232/3534 5227/5235/3537 5228/5236/3538 +f 5225/5233/3535 5224/5232/3534 5228/5236/3538 +f 5225/5233/3535 5228/5236/3538 5229/5237/3539 +f 4019/4399/2758 4022/4402/2761 5230/5238/3540 +f 4019/4399/2758 5230/5238/3540 5231/5239/3541 +f 4029/4409/2766 4030/4410/2767 5232/5240/3542 +f 4029/4409/2766 5232/5240/3542 5233/5241/3540 +f 5233/5241/3540 5232/5240/3542 5234/5242/3543 +f 5233/5241/3540 5234/5242/3543 5235/5243/3544 +f 5231/5239/3541 5230/5238/3540 5236/5244/3545 +f 5231/5239/3541 5236/5244/3545 5237/5245/3546 +f 4045/4425/2782 4908/4916/3260 5238/5246/3547 +f 4045/4425/2782 5238/5246/3547 5239/5247/3548 +f 4908/4916/3260 4885/4893/3240 5240/5248/3549 +f 4908/4916/3260 5240/5248/3549 5238/5246/3547 +f 5238/5246/3547 5240/5248/3549 5241/5249/3550 +f 5238/5246/3547 5241/5249/3550 5242/5250/3551 +f 5239/5247/3548 5238/5246/3547 5242/5250/3551 +f 5239/5247/3548 5242/5250/3551 5243/5251/3552 +f 5244/5252/3553 5245/5253/3554 5246/5254/3554 +f 5244/5252/3553 5246/5254/3554 5247/5255/3553 +f 5245/5253/3554 5248/5256/3555 5249/5257/3555 +f 5245/5253/3554 5249/5257/3555 5246/5254/3554 +f 5246/5254/3554 5249/5257/3555 4180/4560/2910 +f 5246/5254/3554 4180/4560/2910 4179/4559/2909 +f 5247/5255/3553 5246/5254/3554 4179/4559/2909 +f 5247/5255/3553 4179/4559/2909 3737/4117/2495 +f 5250/5258/3556 5251/5259/3557 5252/5260/3558 +f 5250/5258/3556 5252/5260/3558 5253/5261/3559 +f 5251/5259/3557 5254/5262/3560 5255/5263/3561 +f 5251/5259/3557 5255/5263/3561 5252/5260/3558 +f 5252/5260/3558 5255/5263/3561 3728/4108/2486 +f 5252/5260/3558 3728/4108/2486 3727/4107/2485 +f 5253/5261/3559 5252/5260/3558 3727/4107/2485 +f 5253/5261/3559 3727/4107/2485 3726/4106/2484 +f 4012/4392/2751 4912/4920/3263 5256/5264/3562 +f 4012/4392/2751 5256/5264/3562 5257/5265/3563 +f 4912/4920/3263 4097/4477/2830 5258/5266/3564 +f 4912/4920/3263 5258/5266/3564 5256/5264/3562 +f 5256/5264/3562 5258/5266/3564 5259/5267/3564 +f 5256/5264/3562 5259/5267/3564 5260/5268/3562 +f 5257/5265/3563 5256/5264/3562 5260/5268/3562 +f 5257/5265/3563 5260/5268/3562 5261/5269/3563 +f 5262/5270/3564 5263/5271/3565 5264/5272/3565 +f 5262/5270/3564 5264/5272/3565 5265/5273/3564 +f 5263/5271/3565 5266/5274/3566 5267/5275/3566 +f 5263/5271/3565 5267/5275/3566 5264/5272/3565 +f 5264/5272/3565 5267/5275/3566 3903/4283/2647 +f 5264/5272/3565 3903/4283/2647 3902/4282/2646 +f 5265/5273/3564 5264/5272/3565 3902/4282/2646 +f 5265/5273/3564 3902/4282/2646 3901/4281/2645 +f 5033/5041/3369 5268/5276/3567 5269/5277/3568 +f 5033/5041/3369 5269/5277/3568 5270/5278/3569 +f 5268/5276/3567 3262/3700/2074 5271/5279/3570 +f 5268/5276/3567 5271/5279/3570 5269/5277/3568 +f 5269/5277/3568 5271/5279/3570 5272/5280/3571 +f 5269/5277/3568 5272/5280/3571 5273/5281/3572 +f 5270/5278/3569 5269/5277/3568 5273/5281/3572 +f 5270/5278/3569 5273/5281/3572 5274/5282/3573 +f 5275/5283/3574 5276/5284/3575 5277/5285/3575 +f 5275/5283/3574 5277/5285/3575 5278/5286/3574 +f 5276/5284/3575 5279/5287/3576 5280/5288/3576 +f 5276/5284/3575 5280/5288/3576 5277/5285/3575 +f 5277/5285/3575 5280/5288/3576 3812/4192/2560 +f 5277/5285/3575 3812/4192/2560 3811/4191/2559 +f 5278/5286/3574 5277/5285/3575 3811/4191/2559 +f 5278/5286/3574 3811/4191/2559 3810/4190/2558 +f 5281/5289/3577 5282/5290/3578 5283/5291/3578 +f 5281/5289/3577 5283/5291/3578 5284/5292/3577 +f 5282/5290/3578 5285/5293/3579 5286/5294/3579 +f 5282/5290/3578 5286/5294/3579 5283/5291/3578 +f 5283/5291/3578 5286/5294/3579 4115/4495/2847 +f 5283/5291/3578 4115/4495/2847 4114/4494/2846 +f 5284/5292/3577 5283/5291/3578 4114/4494/2846 +f 5284/5292/3577 4114/4494/2846 3870/4250/2616 +f 5287/5295/3580 5288/5296/3581 5289/5297/3581 +f 5287/5295/3580 5289/5297/3581 5290/5298/3580 +f 5288/5296/3581 5291/5299/3582 5292/5300/3582 +f 5288/5296/3581 5292/5300/3582 5289/5297/3581 +f 5289/5297/3581 5292/5300/3582 4037/4417/2774 +f 5289/5297/3581 4037/4417/2774 4036/4416/2773 +f 5290/5298/3580 5289/5297/3581 4036/4416/2773 +f 5290/5298/3580 4036/4416/2773 4035/4415/2772 +f 3855/4235/2601 3858/4238/2604 5293/5301/3583 +f 3855/4235/2601 5293/5301/3583 5294/5302/3579 +f 3858/4238/2604 3863/4243/2609 5295/5303/3584 +f 3858/4238/2604 5295/5303/3584 5293/5301/3583 +f 5293/5301/3583 5295/5303/3584 5296/5304/3584 +f 5293/5301/3583 5296/5304/3584 5297/5305/3583 +f 5294/5302/3579 5293/5301/3583 5297/5305/3583 +f 5294/5302/3579 5297/5305/3583 5298/5306/3579 +f 5299/5307/3585 5300/5308/3586 5301/5309/3586 +f 5299/5307/3585 5301/5309/3586 5302/5310/3585 +f 5300/5308/3586 5303/5311/3587 5304/5312/3587 +f 5300/5308/3586 5304/5312/3587 5301/5309/3586 +f 5301/5309/3586 5304/5312/3587 3831/4211/2579 +f 5301/5309/3586 3831/4211/2579 3830/4210/2578 +f 5302/5310/3585 5301/5309/3586 3830/4210/2578 +f 5302/5310/3585 3830/4210/2578 3829/4209/2577 +f 4970/4978/3314 5138/5146/3458 5305/5313/3588 +f 4970/4978/3314 5305/5313/3588 5306/5314/3589 +f 5138/5146/3458 4989/4997/3331 5307/5315/3590 +f 5138/5146/3458 5307/5315/3590 5305/5313/3588 +f 5305/5313/3588 5307/5315/3590 5308/5316/3590 +f 5305/5313/3588 5308/5316/3590 5309/5317/3588 +f 5306/5314/3589 5305/5313/3588 5309/5317/3588 +f 5306/5314/3589 5309/5317/3588 5310/5318/3589 +f 5311/5319/3590 5312/5320/3591 5313/5321/3591 +f 5311/5319/3590 5313/5321/3591 5314/5322/3590 +f 5312/5320/3591 5315/5323/3592 5316/5324/3592 +f 5312/5320/3591 5316/5324/3592 5313/5321/3591 +f 5313/5321/3591 5316/5324/3592 4058/4438/2794 +f 5313/5321/3591 4058/4438/2794 4057/4437/2793 +f 5314/5322/3590 5313/5321/3591 4057/4437/2793 +f 5314/5322/3590 4057/4437/2793 4056/4436/2792 +f 4977/4985/3321 4980/4988/3324 5317/5325/3593 +f 4977/4985/3321 5317/5325/3593 5318/5326/3594 +f 4980/4988/3324 3936/4316/2680 5319/5327/3595 +f 4980/4988/3324 5319/5327/3595 5317/5325/3593 +f 5317/5325/3593 5319/5327/3595 5320/5328/3595 +f 5317/5325/3593 5320/5328/3595 5321/5329/3593 +f 5318/5326/3594 5317/5325/3593 5321/5329/3593 +f 5318/5326/3594 5321/5329/3593 5322/5330/3596 +f 4955/4963/3303 4975/4983/3319 5323/5331/3586 +f 4955/4963/3303 5323/5331/3586 5324/5332/3585 +f 4975/4983/3319 4962/4970/3307 5325/5333/3587 +f 4975/4983/3319 5325/5333/3587 5323/5331/3586 +f 5323/5331/3586 5325/5333/3587 5326/5334/3587 +f 5323/5331/3586 5326/5334/3587 5327/5335/3586 +f 5324/5332/3585 5323/5331/3586 5327/5335/3586 +f 5324/5332/3585 5327/5335/3586 5328/5336/3585 +f 3936/4316/2680 3939/4319/2683 5329/5337/3597 +f 3936/4316/2680 5329/5337/3597 5319/5327/3595 +f 3939/4319/2683 3944/4324/2688 5330/5338/3598 +f 3939/4319/2683 5330/5338/3598 5329/5337/3597 +f 5329/5337/3597 5330/5338/3598 5331/5339/3598 +f 5329/5337/3597 5331/5339/3598 5332/5340/3597 +f 5319/5327/3595 5329/5337/3597 5332/5340/3597 +f 5319/5327/3595 5332/5340/3597 5320/5328/3595 +f 5243/5251/3552 5333/5341/3599 5334/5342/3600 +f 5243/5251/3552 5334/5342/3600 5239/5247/3548 +f 5333/5341/3599 5335/5343/3601 5336/5344/3602 +f 5333/5341/3599 5336/5344/3602 5334/5342/3600 +f 5334/5342/3600 5336/5344/3602 4048/4428/2785 +f 5334/5342/3600 4048/4428/2785 4046/4426/2783 +f 5239/5247/3548 5334/5342/3600 4046/4426/2783 +f 5239/5247/3548 4046/4426/2783 4045/4425/2782 +f 5217/5225/3527 5337/5345/3603 5338/5346/3604 +f 5217/5225/3527 5338/5346/3604 5339/5347/3605 +f 5337/5345/3603 4998/5006/3337 5340/5348/3606 +f 5337/5345/3603 5340/5348/3606 5338/5346/3604 +f 5338/5346/3604 5340/5348/3606 5341/5349/3607 +f 5338/5346/3604 5341/5349/3607 5342/5350/3608 +f 5339/5347/3605 5338/5346/3604 5342/5350/3608 +f 5339/5347/3605 5342/5350/3608 5343/5351/3609 +f 3985/4365/2726 3988/4368/2729 5344/5352/3610 +f 3985/4365/2726 5344/5352/3610 5345/5353/3611 +f 3988/4368/2729 3991/4371/2732 5346/5354/3612 +f 3988/4368/2729 5346/5354/3612 5344/5352/3610 +f 5344/5352/3610 5346/5354/3612 5347/5355/3613 +f 5344/5352/3610 5347/5355/3613 5348/5356/3614 +f 5345/5353/3611 5344/5352/3610 5348/5356/3614 +f 5345/5353/3611 5348/5356/3614 5349/5357/3615 +f 5350/5358/3616 5351/5359/3617 5352/5360/3617 +f 5350/5358/3616 5352/5360/3617 5353/5361/3616 +f 5351/5359/3617 5354/5362/3618 5355/5363/3618 +f 5351/5359/3617 5355/5363/3618 5352/5360/3617 +f 5352/5360/3617 5355/5363/3618 3918/4298/2662 +f 5352/5360/3617 3918/4298/2662 3917/4297/2661 +f 5353/5361/3616 5352/5360/3617 3917/4297/2661 +f 5353/5361/3616 3917/4297/2661 3916/4296/2660 +f 5140/5148/3460 5163/5171/3478 5356/5364/3619 +f 5140/5148/3460 5356/5364/3619 5357/5365/3620 +f 5161/5169/3478 5157/5165/3476 5358/5366/3621 +f 5161/5169/3478 5358/5366/3621 5359/5367/3622 +f 5359/5367/3622 5358/5366/3621 5360/5368/3621 +f 5359/5367/3622 5360/5368/3621 5361/5369/3622 +f 5357/5365/3620 5356/5364/3619 5362/5370/3619 +f 5357/5365/3620 5362/5370/3619 5363/5371/3620 +f 5364/5372/3621 5365/5373/3623 5366/5374/3623 +f 5364/5372/3621 5366/5374/3623 5367/5375/3621 +f 5365/5373/3623 5368/5376/3624 5369/5377/3624 +f 5365/5373/3623 5369/5377/3624 5366/5374/3623 +f 5366/5374/3623 5369/5377/3624 4018/4398/2757 +f 5366/5374/3623 4018/4398/2757 4017/4397/2756 +f 5367/5375/3621 5366/5374/3623 4017/4397/2756 +f 5367/5375/3621 4017/4397/2756 3794/4174/2545 +f 4135/4515/2866 5016/5024/3355 5370/5378/3617 +f 4135/4515/2866 5370/5378/3617 5371/5379/3616 +f 5016/5024/3355 5020/5028/3357 5372/5380/3618 +f 5016/5024/3355 5372/5380/3618 5370/5378/3617 +f 5370/5378/3617 5372/5380/3618 5373/5381/3618 +f 5370/5378/3617 5373/5381/3618 5374/5382/3617 +f 5371/5379/3616 5370/5378/3617 5374/5382/3617 +f 5371/5379/3616 5374/5382/3617 5375/5383/3616 +f 4998/5006/3337 5001/5009/3340 5376/5384/3625 +f 4998/5006/3337 5376/5384/3625 5340/5348/3606 +f 5001/5009/3340 3985/4365/2726 5345/5353/3611 +f 5001/5009/3340 5345/5353/3611 5376/5384/3625 +f 5376/5384/3625 5345/5353/3611 5349/5357/3615 +f 5376/5384/3625 5349/5357/3615 5377/5385/3626 +f 5340/5348/3606 5376/5384/3625 5377/5385/3626 +f 5340/5348/3606 5377/5385/3626 5341/5349/3607 +f 5378/5386/3627 5379/5387/3628 5380/5388/3628 +f 5378/5386/3627 5380/5388/3628 5381/5389/3627 +f 5379/5387/3628 5382/5390/3629 5383/5391/3629 +f 5379/5387/3628 5383/5391/3629 5380/5388/3628 +f 5380/5388/3628 5383/5391/3629 3854/4234/2600 +f 5380/5388/3628 3854/4234/2600 3853/4233/2599 +f 5381/5389/3627 5380/5388/3628 3853/4233/2599 +f 5381/5389/3627 3853/4233/2599 3852/4232/2598 +f 4878/4886/3234 4915/4923/3266 5384/5392/3630 +f 4878/4886/3234 5384/5392/3630 5385/5393/3631 +f 4915/4923/3266 4914/4922/3265 5386/5394/3632 +f 4915/4923/3266 5386/5394/3632 5384/5392/3630 +f 5384/5392/3630 5386/5394/3632 5387/5395/3633 +f 5384/5392/3630 5387/5395/3633 5388/5396/3634 +f 5385/5393/3631 5384/5392/3630 5388/5396/3634 +f 5385/5393/3631 5388/5396/3634 5389/5397/3635 +f 4920/4928/3270 4923/4931/3273 5390/5398/3636 +f 4920/4928/3270 5390/5398/3636 5391/5399/3592 +f 4923/4931/3273 4928/4936/3278 5392/5400/3637 +f 4923/4931/3273 5392/5400/3637 5390/5398/3636 +f 5390/5398/3636 5392/5400/3637 5393/5401/3637 +f 5390/5398/3636 5393/5401/3637 5394/5402/3638 +f 5391/5399/3592 5390/5398/3636 5394/5402/3638 +f 5391/5399/3592 5394/5402/3638 5395/5403/3592 +f 4085/4465/2819 4088/4468/2822 5396/5404/3639 +f 4085/4465/2819 5396/5404/3639 5397/5405/3640 +f 4088/4468/2822 4019/4399/2758 5231/5239/3541 +f 4088/4468/2822 5231/5239/3541 5396/5404/3639 +f 5396/5404/3639 5231/5239/3541 5237/5245/3546 +f 5396/5404/3639 5237/5245/3546 5398/5406/3641 +f 5397/5405/3640 5396/5404/3639 5398/5406/3641 +f 5397/5405/3640 5398/5406/3641 5399/5407/3642 +f 4160/4540/2891 4163/4543/2894 5400/5408/3643 +f 4160/4540/2891 5400/5408/3643 5401/5409/3644 +f 4163/4543/2894 4168/4548/2899 5402/5410/3645 +f 4163/4543/2894 5402/5410/3645 5400/5408/3643 +f 5400/5408/3643 5402/5410/3645 5403/5411/3646 +f 5400/5408/3643 5403/5411/3646 5404/5412/3647 +f 5401/5409/3644 5400/5408/3643 5404/5412/3647 +f 5401/5409/3644 5404/5412/3647 5405/5413/3648 +f 5068/5076/3399 5065/5073/3396 5406/5414/3649 +f 5068/5076/3399 5406/5414/3649 5407/5415/3650 +f 5065/5073/3396 5064/5072/3395 5408/5416/3651 +f 5065/5073/3396 5408/5416/3651 5406/5414/3649 +f 5406/5414/3649 5408/5416/3651 5409/5417/3651 +f 5406/5414/3649 5409/5417/3651 5410/5418/3649 +f 5407/5415/3650 5406/5414/3649 5410/5418/3649 +f 5407/5415/3650 5410/5418/3649 5411/5419/3650 +f 5412/5420/3651 5413/5421/3652 5414/5422/3652 +f 5412/5420/3651 5414/5422/3652 5415/5423/3651 +f 5413/5421/3652 5416/5424/3653 5417/5425/3653 +f 5413/5421/3652 5417/5425/3653 5414/5422/3652 +f 5414/5422/3652 5417/5425/3653 3768/4148/2525 +f 5414/5422/3652 3768/4148/2525 3782/4162/2538 +f 5415/5423/3651 5414/5422/3652 3782/4162/2538 +f 5415/5423/3651 3782/4162/2538 3781/4161/2537 +f 5418/5426/3654 5419/5427/3655 5420/5428/3655 +f 5418/5426/3654 5420/5428/3655 5421/5429/3654 +f 5419/5427/3655 5422/5430/3656 5423/5431/3656 +f 5419/5427/3655 5423/5431/3656 5420/5428/3655 +f 5420/5428/3655 5423/5431/3656 3761/4141/2518 +f 5420/5428/3655 3761/4141/2518 3760/4140/2517 +f 5421/5429/3654 5420/5428/3655 3760/4140/2517 +f 5421/5429/3654 3760/4140/2517 3759/4139/2516 +f 5424/5432/3657 5425/5433/3658 5426/5434/3659 +f 5424/5432/3657 5426/5434/3659 5427/5435/3660 +f 5425/5433/3658 5428/5436/3661 5429/5437/3662 +f 5425/5433/3658 5429/5437/3662 5426/5434/3659 +f 5426/5434/3659 5429/5437/3662 5081/5089/3412 +f 5426/5434/3659 5081/5089/3412 5430/5438/3663 +f 5427/5435/3660 5426/5434/3659 5430/5438/3663 +f 5427/5435/3660 5430/5438/3663 3983/4363/2724 +f 5073/5081/3404 5168/5176/3483 5431/5439/3664 +f 5073/5081/3404 5431/5439/3664 5432/5440/3653 +f 5168/5176/3483 5167/5175/3482 5433/5441/3665 +f 5168/5176/3483 5433/5441/3665 5431/5439/3664 +f 5431/5439/3664 5433/5441/3665 5434/5442/3665 +f 5431/5439/3664 5434/5442/3665 5435/5443/3664 +f 5432/5440/3653 5431/5439/3664 5435/5443/3664 +f 5432/5440/3653 5435/5443/3664 5436/5444/3653 +f 4004/4384/2743 4007/4387/2746 5437/5445/3666 +f 4004/4384/2743 5437/5445/3666 5438/5446/3667 +f 4007/4387/2746 4012/4392/2751 5257/5265/3563 +f 4007/4387/2746 5257/5265/3563 5437/5445/3666 +f 5437/5445/3666 5257/5265/3563 5261/5269/3563 +f 5437/5445/3666 5261/5269/3563 5439/5447/3666 +f 5438/5446/3667 5437/5445/3666 5439/5447/3666 +f 5438/5446/3667 5439/5447/3666 5440/5448/3667 +f 5020/5028/3357 5062/5070/3393 5441/5449/3668 +f 5020/5028/3357 5441/5449/3668 5372/5380/3618 +f 5062/5070/3393 4160/4540/2891 5401/5409/3644 +f 5062/5070/3393 5401/5409/3644 5441/5449/3668 +f 5441/5449/3668 5401/5409/3644 5405/5413/3648 +f 5441/5449/3668 5405/5413/3648 5442/5450/3668 +f 5372/5380/3618 5441/5449/3668 5442/5450/3668 +f 5372/5380/3618 5442/5450/3668 5373/5381/3618 +f 5443/5451/3665 5444/5452/3669 5445/5453/3669 +f 5443/5451/3665 5445/5453/3669 5446/5454/3665 +f 5444/5452/3669 5447/5455/3670 5448/5456/3670 +f 5444/5452/3669 5448/5456/3670 5445/5453/3669 +f 5445/5453/3669 5448/5456/3670 3911/4291/2655 +f 5445/5453/3669 3911/4291/2655 3910/4290/2654 +f 5446/5454/3665 5445/5453/3669 3910/4290/2654 +f 5446/5454/3665 3910/4290/2654 3770/4150/2527 +f 4097/4477/2830 4100/4480/2833 5449/5457/3565 +f 4097/4477/2830 5449/5457/3565 5258/5266/3564 +f 4100/4480/2833 4105/4485/2837 5450/5458/3566 +f 4100/4480/2833 5450/5458/3566 5449/5457/3565 +f 5449/5457/3565 5450/5458/3566 5451/5459/3566 +f 5449/5457/3565 5451/5459/3566 5452/5460/3565 +f 5258/5266/3564 5449/5457/3565 5452/5460/3565 +f 5258/5266/3564 5452/5460/3565 5259/5267/3564 +f 5254/5262/3560 5453/5461/3671 5454/5462/3672 +f 5254/5262/3560 5454/5462/3672 5255/5263/3561 +f 5453/5461/3671 5455/5463/3673 5456/5464/3674 +f 5453/5461/3671 5456/5464/3674 5454/5462/3672 +f 5454/5462/3672 5456/5464/3674 3743/4123/2501 +f 5454/5462/3672 3743/4123/2501 3742/4122/2500 +f 5255/5263/3561 5454/5462/3672 3742/4122/2500 +f 5255/5263/3561 3742/4122/2500 3728/4108/2486 +f 3873/4253/2618 3876/4256/2621 5457/5465/3675 +f 3873/4253/2618 5457/5465/3675 5458/5466/3676 +f 3876/4256/2621 3881/4261/2626 5459/5467/3677 +f 3876/4256/2621 5459/5467/3677 5457/5465/3675 +f 5457/5465/3675 5459/5467/3677 5460/5468/3677 +f 5457/5465/3675 5460/5468/3677 5461/5469/3675 +f 5458/5466/3676 5457/5465/3675 5461/5469/3675 +f 5458/5466/3676 5461/5469/3675 5462/5470/3676 +f 5003/5011/3342 5006/5014/3345 5463/5471/3581 +f 5003/5011/3342 5463/5471/3581 5464/5472/3580 +f 5006/5014/3345 4127/4507/2858 5465/5473/3582 +f 5006/5014/3345 5465/5473/3582 5463/5471/3581 +f 5463/5471/3581 5465/5473/3582 5466/5474/3582 +f 5463/5471/3581 5466/5474/3582 5467/5475/3581 +f 5464/5472/3580 5463/5471/3581 5467/5475/3581 +f 5464/5472/3580 5467/5475/3581 5468/5476/3580 +f 4937/4945/3286 4945/4953/3294 5469/5477/3578 +f 4937/4945/3286 5469/5477/3578 5470/5478/3577 +f 4945/4953/3294 3855/4235/2601 5294/5302/3579 +f 4945/4953/3294 5294/5302/3579 5469/5477/3578 +f 5469/5477/3578 5294/5302/3579 5298/5306/3579 +f 5469/5477/3578 5298/5306/3579 5471/5479/3578 +f 5470/5478/3577 5469/5477/3578 5471/5479/3578 +f 5470/5478/3577 5471/5479/3578 5472/5480/3577 +f 4928/4936/3278 4939/4947/3288 5473/5481/3678 +f 4928/4936/3278 5473/5481/3678 5392/5400/3637 +f 4939/4947/3288 4943/4951/3292 5474/5482/3679 +f 4939/4947/3288 5474/5482/3679 5473/5481/3678 +f 5473/5481/3678 5474/5482/3679 5475/5483/3680 +f 5473/5481/3678 5475/5483/3680 5476/5484/3678 +f 5392/5400/3637 5473/5481/3678 5476/5484/3678 +f 5392/5400/3637 5476/5484/3678 5393/5401/3637 +f 3842/4222/2589 3840/4220/2587 5477/5485/3628 +f 3842/4222/2589 5477/5485/3628 5478/5486/3627 +f 3840/4220/2587 3799/4179/2550 5479/5487/3629 +f 3840/4220/2587 5479/5487/3629 5477/5485/3628 +f 5477/5485/3628 5479/5487/3629 5480/5488/3629 +f 5477/5485/3628 5480/5488/3629 5481/5489/3628 +f 5478/5486/3627 5477/5485/3628 5481/5489/3628 +f 5478/5486/3627 5481/5489/3628 5482/5490/3627 +f 4989/4997/3331 4992/5000/3334 5483/5491/3591 +f 4989/4997/3331 5483/5491/3591 5307/5315/3590 +f 4992/5000/3334 4997/5005/3270 5484/5492/3592 +f 4992/5000/3334 5484/5492/3592 5483/5491/3591 +f 5483/5491/3591 5484/5492/3592 5485/5493/3592 +f 5483/5491/3591 5485/5493/3592 5486/5494/3591 +f 5307/5315/3590 5483/5491/3591 5486/5494/3591 +f 5307/5315/3590 5486/5494/3591 5308/5316/3590 +f 4084/4464/2818 4107/4487/2839 5487/5495/3575 +f 4084/4464/2818 5487/5495/3575 5488/5496/3574 +f 4107/4487/2839 4106/4486/2838 5489/5497/3576 +f 4107/4487/2839 5489/5497/3576 5487/5495/3575 +f 5487/5495/3575 5489/5497/3576 5490/5498/3576 +f 5487/5495/3575 5490/5498/3576 5491/5499/3575 +f 5488/5496/3574 5487/5495/3575 5491/5499/3575 +f 5488/5496/3574 5491/5499/3575 5492/5500/3574 +f 4962/4970/3307 4965/4973/3310 5493/5501/3681 +f 4962/4970/3307 5493/5501/3681 5325/5333/3587 +f 4965/4973/3310 4970/4978/3314 5306/5314/3589 +f 4965/4973/3310 5306/5314/3589 5493/5501/3681 +f 5493/5501/3681 5306/5314/3589 5310/5318/3589 +f 5493/5501/3681 5310/5318/3589 5494/5502/3681 +f 5325/5333/3587 5493/5501/3681 5494/5502/3681 +f 5325/5333/3587 5494/5502/3681 5326/5334/3587 +f 5052/5060/3384 5141/5149/3461 5495/5503/3682 +f 5052/5060/3384 5495/5503/3682 5496/5504/3683 +f 5141/5149/3461 5140/5148/3460 5357/5365/3620 +f 5141/5149/3461 5357/5365/3620 5495/5503/3682 +f 5495/5503/3682 5357/5365/3620 5363/5371/3620 +f 5495/5503/3682 5363/5371/3620 5497/5505/3682 +f 5496/5504/3683 5495/5503/3682 5497/5505/3682 +f 5496/5504/3683 5497/5505/3682 5498/5506/3683 +f 3964/4344/2707 3961/4341/2704 5499/5507/3684 +f 3964/4344/2707 5499/5507/3684 5500/5508/3685 +f 3961/4341/2704 3960/4340/2703 5501/5509/3686 +f 3961/4341/2704 5501/5509/3686 5499/5507/3684 +f 5499/5507/3684 5501/5509/3686 5502/5510/3686 +f 5499/5507/3684 5502/5510/3686 5503/5511/3684 +f 5500/5508/3685 5499/5507/3684 5503/5511/3684 +f 5500/5508/3685 5503/5511/3684 5504/5512/3685 +f 4106/4486/2838 5146/5154/3466 5505/5513/3687 +f 4106/4486/2838 5505/5513/3687 5489/5497/3576 +f 5146/5154/3466 5056/5064/3388 5506/5514/3688 +f 5146/5154/3466 5506/5514/3688 5505/5513/3687 +f 5505/5513/3687 5506/5514/3688 5507/5515/3688 +f 5505/5513/3687 5507/5515/3688 5508/5516/3687 +f 5489/5497/3576 5505/5513/3687 5508/5516/3687 +f 5489/5497/3576 5508/5516/3687 5490/5498/3576 +f 5151/5159/3471 5149/5157/3469 5509/5517/3689 +f 5151/5159/3471 5509/5517/3689 5510/5518/3670 +f 5149/5157/3469 4947/4955/3296 5511/5519/3690 +f 5149/5157/3469 5511/5519/3690 5509/5517/3689 +f 5509/5517/3689 5511/5519/3690 5512/5520/3690 +f 5509/5517/3689 5512/5520/3690 5513/5521/3689 +f 5510/5518/3670 5509/5517/3689 5513/5521/3689 +f 5510/5518/3670 5513/5521/3689 5514/5522/3670 +f 5157/5165/3476 5155/5163/3474 5515/5523/3623 +f 5157/5165/3476 5515/5523/3623 5358/5366/3621 +f 5155/5163/3474 5029/5037/3366 5516/5524/3624 +f 5155/5163/3474 5516/5524/3624 5515/5523/3623 +f 5515/5523/3623 5516/5524/3624 5517/5525/3624 +f 5515/5523/3623 5517/5525/3624 5518/5526/3623 +f 5358/5366/3621 5515/5523/3623 5518/5526/3623 +f 5358/5366/3621 5518/5526/3623 5360/5368/3621 +f 5064/5072/3395 5074/5082/3405 5519/5527/3652 +f 5064/5072/3395 5519/5527/3652 5408/5416/3651 +f 5074/5082/3405 5073/5081/3404 5432/5440/3653 +f 5074/5082/3405 5432/5440/3653 5519/5527/3652 +f 5519/5527/3652 5432/5440/3653 5436/5444/3653 +f 5519/5527/3652 5436/5444/3653 5520/5528/3652 +f 5408/5416/3651 5519/5527/3652 5520/5528/3652 +f 5408/5416/3651 5520/5528/3652 5409/5417/3651 +f 3795/4175/2546 3949/4329/2693 5521/5529/3655 +f 3795/4175/2546 5521/5529/3655 5522/5530/3654 +f 3949/4329/2693 3948/4328/2692 5523/5531/3691 +f 3949/4329/2693 5523/5531/3691 5521/5529/3655 +f 5521/5529/3655 5523/5531/3691 5524/5532/3692 +f 5521/5529/3655 5524/5532/3692 5525/5533/3655 +f 5522/5530/3654 5521/5529/3655 5525/5533/3655 +f 5522/5530/3654 5525/5533/3655 5526/5534/3654 +f 5167/5175/3482 5173/5181/3488 5527/5535/3669 +f 5167/5175/3482 5527/5535/3669 5433/5441/3665 +f 5173/5181/3488 5151/5159/3471 5510/5518/3670 +f 5173/5181/3488 5510/5518/3670 5527/5535/3669 +f 5527/5535/3669 5510/5518/3670 5514/5522/3670 +f 5527/5535/3669 5514/5522/3670 5528/5536/3669 +f 5433/5441/3665 5527/5535/3669 5528/5536/3669 +f 5433/5441/3665 5528/5536/3669 5434/5442/3665 +f 3948/4328/2692 5176/5184/3491 5529/5537/3693 +f 3948/4328/2692 5529/5537/3693 5523/5531/3691 +f 5176/5184/3491 3892/4272/2637 5530/5538/3694 +f 5176/5184/3491 5530/5538/3694 5529/5537/3693 +f 5529/5537/3693 5530/5538/3694 5531/5539/3695 +f 5529/5537/3693 5531/5539/3695 5532/5540/3696 +f 5523/5531/3691 5529/5537/3693 5532/5540/3696 +f 5523/5531/3691 5532/5540/3696 5524/5532/3692 +f 4901/4909/3254 5180/5188/3494 5533/5541/3697 +f 4901/4909/3254 5533/5541/3697 5534/5542/3698 +f 5180/5188/3494 5179/5187/3399 5535/5543/3650 +f 5180/5188/3494 5535/5543/3650 5533/5541/3697 +f 5533/5541/3697 5535/5543/3650 5536/5544/3650 +f 5533/5541/3697 5536/5544/3650 5537/5545/3697 +f 5534/5542/3698 5533/5541/3697 5537/5545/3697 +f 5534/5542/3698 5537/5545/3697 5538/5546/3698 +f 5539/5547/3699 5540/5548/3700 5541/5549/3701 +f 5539/5547/3699 5541/5549/3701 5542/5550/3702 +f 5543/5551/3703 5544/5552/3704 5541/5549/3701 +f 5543/5551/3703 5541/5549/3701 5540/5548/3700 +f 5272/5280/3571 5545/5553/3705 5541/5549/3701 +f 5272/5280/3571 5541/5549/3701 5544/5552/3704 +f 5546/5554/3706 5547/5555/3707 5541/5549/3701 +f 5546/5554/3706 5541/5549/3701 5545/5553/3705 +f 5548/5556/3708 5542/5550/3702 5541/5549/3701 +f 5548/5556/3708 5541/5549/3701 5547/5555/3707 +f 3405/3822/2200 5191/5199/3503 5549/5557/3554 +f 3405/3822/2200 5549/5557/3554 5550/5558/3709 +f 5191/5199/3503 5103/5111/3430 5551/5559/3555 +f 5191/5199/3503 5551/5559/3555 5549/5557/3554 +f 5549/5557/3554 5551/5559/3555 5552/5560/3555 +f 5549/5557/3554 5552/5560/3555 5553/5561/3554 +f 5550/5558/3709 5549/5557/3554 5553/5561/3554 +f 5550/5558/3709 5553/5561/3554 5554/5562/3710 +f 5194/5202/3505 5555/5563/3711 5556/5564/3712 +f 5194/5202/3505 5556/5564/3712 5557/5565/3713 +f 5555/5563/3711 5558/5566/3714 5559/5567/3715 +f 5555/5563/3711 5559/5567/3715 5556/5564/3712 +f 5556/5564/3712 5559/5567/3715 5560/5568/3716 +f 5556/5564/3712 5560/5568/3716 5561/5569/3717 +f 5557/5565/3713 5556/5564/3712 5561/5569/3717 +f 5557/5565/3713 5561/5569/3717 5562/5570/3718 +f 4885/4893/3240 4888/4896/3243 5563/5571/3719 +f 4885/4893/3240 5563/5571/3719 5240/5248/3549 +f 4888/4896/3243 4069/4449/2804 5564/5572/3720 +f 4888/4896/3243 5564/5572/3720 5563/5571/3719 +f 5563/5571/3719 5564/5572/3720 5565/5573/3721 +f 5563/5571/3719 5565/5573/3721 5566/5574/3722 +f 5240/5248/3549 5563/5571/3719 5566/5574/3722 +f 5240/5248/3549 5566/5574/3722 5241/5249/3550 +f 4476/4810/3153 5210/5218/3520 5567/5575/3723 +f 4476/4810/3153 5567/5575/3723 5568/5576/3724 +f 5210/5218/3520 5569/5577/3725 5570/5578/3605 +f 5210/5218/3520 5570/5578/3605 5567/5575/3723 +f 5567/5575/3723 5570/5578/3605 5571/5579/3726 +f 5567/5575/3723 5571/5579/3726 5572/5580/3727 +f 5568/5576/3724 5567/5575/3723 5572/5580/3727 +f 5568/5576/3724 5572/5580/3727 5573/5581/3728 +f 5198/5206/3509 5574/5582/3729 5575/5583/3730 +f 5198/5206/3509 5575/5583/3730 5199/5207/3510 +f 5574/5582/3729 3888/4268/2633 3891/4271/2636 +f 5574/5582/3729 3891/4271/2636 5575/5583/3730 +f 5575/5583/3730 3891/4271/2636 3896/4276/2641 +f 5575/5583/3730 3896/4276/2641 5576/5584/2403 +f 5199/5207/3510 5575/5583/3730 5576/5584/2403 +f 5199/5207/3510 5576/5584/2403 5200/5208/3511 +f 5056/5064/3388 5053/5061/3385 5577/5585/3731 +f 5056/5064/3388 5577/5585/3731 5506/5514/3688 +f 5053/5061/3385 5052/5060/3384 5496/5504/3683 +f 5053/5061/3385 5496/5504/3683 5577/5585/3731 +f 5577/5585/3731 5496/5504/3683 5498/5506/3683 +f 5577/5585/3731 5498/5506/3683 5578/5586/3731 +f 5506/5514/3688 5577/5585/3731 5578/5586/3731 +f 5506/5514/3688 5578/5586/3731 5507/5515/3688 +f 5579/5587/3732 5580/5588/3733 5581/5589/3734 +f 5579/5587/3732 5581/5589/3734 5582/5590/3735 +f 5580/5588/3733 5583/5591/3736 5584/5592/3737 +f 5580/5588/3733 5584/5592/3737 5581/5589/3734 +f 5581/5589/3734 5584/5592/3737 3973/4353/2715 +f 5581/5589/3734 3973/4353/2715 4003/4383/2742 +f 5582/5590/3735 5581/5589/3734 4003/4383/2742 +f 5582/5590/3735 4003/4383/2742 4002/4382/2741 +f 3464/3875/2253 3984/4364/2725 5585/5593/3738 +f 3464/3875/2253 5585/5593/3738 5586/5594/3739 +f 3984/4364/2725 3983/4363/2724 5430/5438/3663 +f 3984/4364/2725 5430/5438/3663 5585/5593/3738 +f 5585/5593/3738 5430/5438/3663 5081/5089/3412 +f 5585/5593/3738 5081/5089/3412 5079/5087/3410 +f 5586/5594/3739 5585/5593/3738 5079/5087/3410 +f 5586/5594/3739 5079/5087/3410 4864/4872/3222 +f 5587/5595/3740 5588/5596/3741 5589/5597/3742 +f 5587/5595/3740 5589/5597/3742 5590/5598/3743 +f 5588/5596/3741 5591/5599/3744 5592/5600/3745 +f 5588/5596/3741 5592/5600/3745 5589/5597/3742 +f 5589/5597/3742 5592/5600/3745 5025/5033/3362 +f 5589/5597/3742 5025/5033/3362 5022/5030/3359 +f 5590/5598/3743 5589/5597/3742 5022/5030/3359 +f 5590/5598/3743 5022/5030/3359 5021/5029/3358 +f 5217/5225/3527 5216/5224/3526 5593/5601/3746 +f 5217/5225/3527 5593/5601/3746 5337/5345/3603 +f 5216/5224/3526 4225/4603/2953 4223/4601/2951 +f 5216/5224/3526 4223/4601/2951 5593/5601/3746 +f 5593/5601/3746 4223/4601/2951 4222/4600/2950 +f 5593/5601/3746 4222/4600/2950 4999/5007/3338 +f 5337/5345/3603 5593/5601/3746 4999/5007/3338 +f 5337/5345/3603 4999/5007/3338 4998/5006/3337 +f 3464/3875/2253 5586/5594/3739 5594/5602/3747 +f 3464/3875/2253 5594/5602/3747 3465/3876/2254 +f 5586/5594/3739 4864/4872/3222 4867/4875/3225 +f 5586/5594/3739 4867/4875/3225 5594/5602/3747 +f 5595/5603/3748 4872/4880/3229 4863/4871/3221 +f 5595/5603/3748 4863/4871/3221 4862/4870/3220 +f 3467/3878/2256 5595/5603/3748 4862/4870/3220 +f 3467/3878/2256 4862/4870/3220 3468/3879/2257 +f 5596/5604/3749 5597/5605/3750 5598/5606/3751 +f 5596/5604/3749 5598/5606/3751 5599/5607/3752 +f 5597/5605/3750 4859/3680/3218 4861/4869/3219 +f 5597/5605/3750 4861/4869/3219 5598/5606/3751 +f 5598/5606/3751 4861/4869/3219 4863/4871/3221 +f 5598/5606/3751 4863/4871/3221 4871/4879/3228 +f 5599/5607/3752 5598/5606/3751 4871/4879/3228 +f 5599/5607/3752 4871/4879/3228 4072/4452/2807 +f 4362/4715/3063 4359/4712/3060 5600/5608/3753 +f 4362/4715/3063 5600/5608/3753 5601/5609/3754 +f 4359/4712/3060 4358/3675/2055 4857/3679/3217 +f 4359/4712/3060 4857/3679/3217 5600/5608/3753 +f 5600/5608/3753 4857/3679/3217 4859/3680/3218 +f 5600/5608/3753 4859/3680/3218 5597/5605/3750 +f 5601/5609/3754 5600/5608/3753 5597/5605/3750 +f 5601/5609/3754 5597/5605/3750 5596/5604/3749 +f 5602/3682/1890 4677/3688/3179 4679/3684/3184 +f 5603/3683/1890 4679/3684/3184 3493/3904/2282 +f 5603/3683/1890 3493/3904/2282 5604/5610/3755 +f 4537/3309/1890 5603/3683/1890 5604/5610/3755 +f 4537/3309/1890 5604/5610/3755 4331/4686/3036 +f 5605/3685/3756 4217/4595/2945 4673/3687/3179 +f 5606/3686/1890 4673/3687/3179 4677/3688/3179 +f 4468/3517/1991 4855/3676/3757 5607/5611/3758 +f 4468/3517/1991 5607/5611/3758 4469/4803/3147 +f 4855/3676/3757 4358/3675/2055 4361/4714/3062 +f 4855/3676/3757 4361/4714/3062 5607/5611/3758 +f 5608/5612/3759 5609/5613/3760 5021/5029/3358 +f 5608/5612/3759 5021/5029/3358 5024/5032/3361 +f 5610/5614/3147 5608/5612/3759 5024/5032/3361 +f 5610/5614/3147 5024/5032/3361 3998/4378/2737 +f 3509/3304/1909 3508/3917/2295 5611/5615/3761 +f 3509/3304/1909 5611/5615/3761 5605/3685/3756 +f 3507/3916/2294 3506/3915/2293 5002/5010/3341 +f 3507/3916/2294 5002/5010/3341 5612/5616/3762 +f 5612/5616/3762 5002/5010/3341 4222/4600/2950 +f 5612/5616/3762 4222/4600/2950 4221/4599/2949 +f 5605/3685/3756 5611/5615/3761 4218/4596/2946 +f 5605/3685/3756 4218/4596/2946 4217/4595/2945 +f 5045/5053/3378 5044/5052/3377 5613/5617/3763 +f 5045/5053/3378 5613/5617/3763 5614/5618/3764 +f 5044/5052/3377 4336/4691/3041 5615/5619/3765 +f 5044/5052/3377 5615/5619/3765 5613/5617/3763 +f 5613/5617/3763 5615/5619/3765 4089/4469/2278 +f 5613/5617/3763 4089/4469/2278 4086/4466/2820 +f 5614/5618/3764 5613/5617/3763 4086/4466/2820 +f 5614/5618/3764 4086/4466/2820 4085/4465/2819 +f 5616/5620/3766 4332/4687/3037 5617/5621/3767 +f 5616/5620/3766 5617/5621/3767 5618/5622/3768 +f 4332/4687/3037 4331/4686/3036 5604/5610/3755 +f 4332/4687/3037 5604/5610/3755 5617/5621/3767 +f 5617/5621/3767 5604/5610/3755 3493/3904/2282 +f 5617/5621/3767 3493/3904/2282 3490/3901/2279 +f 5618/5622/3768 5617/5621/3767 3490/3901/2279 +f 5618/5622/3768 3490/3901/2279 3489/3900/2278 +f 5198/5206/3509 5195/5203/3506 5619/5623/3769 +f 5198/5206/3509 5619/5623/3769 5620/5624/3770 +f 5195/5203/3506 5194/5202/3505 5557/5565/3713 +f 5195/5203/3506 5557/5565/3713 5619/5623/3769 +f 5619/5623/3769 5557/5565/3713 5562/5570/3718 +f 5619/5623/3769 5562/5570/3718 5621/5625/3771 +f 5620/5624/3770 5619/5623/3769 5621/5625/3771 +f 5620/5624/3770 5621/5625/3771 5622/5626/3772 +f 3863/4243/2609 4080/4460/2814 5623/5627/3773 +f 3863/4243/2609 5623/5627/3773 5295/5303/3584 +f 4080/4460/2814 4084/4464/2818 5488/5496/3574 +f 4080/4460/2814 5488/5496/3574 5623/5627/3773 +f 5623/5627/3773 5488/5496/3574 5492/5500/3574 +f 5623/5627/3773 5492/5500/3574 5624/5628/3773 +f 5295/5303/3584 5623/5627/3773 5624/5628/3773 +f 5295/5303/3584 5624/5628/3773 5296/5304/3584 +f 5558/5566/3714 5555/5563/3711 5625/5629/3774 +f 5558/5566/3714 5625/5629/3774 5626/5630/3775 +f 5555/5563/3711 5194/5202/3505 5197/5205/3508 +f 5555/5563/3711 5197/5205/3508 5625/5629/3774 +f 5625/5629/3774 5197/5205/3508 5202/5210/3513 +f 5625/5629/3774 5202/5210/3513 5627/5631/2981 +f 5626/5630/3775 5625/5629/3774 5627/5631/2981 +f 5626/5630/3775 5627/5631/2981 5628/5632/2980 +f 3262/3700/2074 5268/5276/3567 5629/5633/3776 +f 3262/3700/2074 5629/5633/3776 3263/3701/2075 +f 5268/5276/3567 5033/5041/3369 5036/5044/3372 +f 5268/5276/3567 5036/5044/3372 5629/5633/3776 +f 5629/5633/3776 5036/5044/3372 5041/5049/2930 +f 5629/5633/3776 5041/5049/2930 5630/5634/3777 +f 3263/3701/2075 5629/5633/3776 5630/5634/3777 +f 3263/3701/2075 5630/5634/3777 3264/3702/2076 +f 5631/3689/1981 4761/3695/2069 4763/3691/3206 +f 5632/3690/1981 4763/3691/3206 4350/4704/3052 +f 5632/3690/1981 4350/4704/3052 5633/5635/3778 +f 4746/3555/1981 5632/3690/1981 5633/5635/3778 +f 4746/3555/1981 5633/5635/3778 3429/3846/2224 +f 5634/3692/2067 4382/4732/3080 4757/3694/3201 +f 5635/3693/1981 4757/3694/3201 4761/3695/2069 +f 5636/5636/3779 5637/5637/3780 5638/5638/3781 +f 5636/5636/3779 5638/5638/3781 5639/5639/3232 +f 5637/5637/3780 4578/3363/1933 4580/4833/3176 +f 5637/5637/3780 4580/4833/3176 5638/5638/3781 +f 5638/5638/3781 4580/4833/3176 4210/4588/2938 +f 5638/5638/3781 4210/4588/2938 4209/4587/2937 +f 5639/5639/3232 5638/5638/3781 4209/4587/2937 +f 5639/5639/3232 4209/4587/2937 4208/4586/2936 +f 4260/4631/2978 4257/4628/2975 5640/5640/3782 +f 4260/4631/2978 5640/5640/3782 5641/5641/3783 +f 4257/4628/2975 4256/3358/2974 4576/3362/3175 +f 4257/4628/2975 4576/3362/3175 5640/5640/3782 +f 5640/5640/3782 4576/3362/3175 4578/3363/1933 +f 5640/5640/3782 4578/3363/1933 5637/5637/3780 +f 5641/5641/3783 5640/5640/3782 5637/5637/3780 +f 5641/5641/3783 5637/5637/3780 5636/5636/3779 +f 3458/3548/2009 3457/3869/2248 5642/5642/3784 +f 3458/3548/2009 5642/5642/3784 5634/3692/2067 +f 3457/3869/2248 3456/3868/2247 5643/5643/3785 +f 3457/3869/2248 5643/5643/3785 5642/5642/3784 +f 5642/5642/3784 5643/5643/3785 4386/4736/3084 +f 5642/5642/3784 4386/4736/3084 4383/4733/3081 +f 5634/3692/2067 5642/5642/3784 4383/4733/3081 +f 5634/3692/2067 4383/4733/3081 4382/4732/3080 +f 3431/3848/2226 3430/3847/2225 5644/5644/3786 +f 3431/3848/2226 5644/5644/3786 5645/5645/3787 +f 3430/3847/2225 3429/3846/2224 5633/5635/3778 +f 3430/3847/2225 5633/5635/3778 5644/5644/3786 +f 5644/5644/3786 5633/5635/3778 4350/4704/3052 +f 5644/5644/3786 4350/4704/3052 4347/4701/3049 +f 5645/5645/3787 5644/5644/3786 4347/4701/3049 +f 5645/5645/3787 4347/4701/3049 4346/4700/2882 +f 3637/3334/1920 4574/3359/1931 5646/5646/3788 +f 3637/3334/1920 5646/5646/3788 3638/4019/2401 +f 4574/3359/1931 4256/3358/2974 4259/4630/2977 +f 4574/3359/1931 4259/4630/2977 5646/5646/3788 +f 5646/5646/3788 4259/4630/2977 4264/4635/2982 +f 5646/5646/3788 4264/4635/2982 5647/5647/3789 +f 3638/4019/2401 5646/5646/3788 5647/5647/3789 +f 3638/4019/2401 5647/5647/3789 3639/4020/2402 +f 3667/4047/2076 5648/5648/3777 5649/5649/3790 +f 3667/4047/2076 5649/5649/3790 3668/4048/2428 +f 5648/5648/3777 4202/4580/2930 4205/4583/2933 +f 5648/5648/3777 4205/4583/2933 5649/5649/3790 +f 5649/5649/3790 4205/4583/2933 4210/4588/2938 +f 5649/5649/3790 4210/4588/2938 4581/4834/3177 +f 3668/4048/2428 5649/5649/3790 4581/4834/3177 +f 3668/4048/2428 4581/4834/3177 3669/4049/2429 +f 4140/4520/2871 5650/5650/3791 5651/5651/3792 +f 4140/4520/2871 5651/5651/3792 4141/4521/2872 +f 5650/5650/3791 4151/4531/2882 4154/4534/2885 +f 5650/5650/3791 4154/4534/2885 5651/5651/3792 +f 5651/5651/3792 4154/4534/2885 4159/4539/2890 +f 5651/5651/3792 4159/4539/2890 5652/5652/3793 +f 4141/4521/2872 5651/5651/3792 5652/5652/3793 +f 4141/4521/2872 5652/5652/3793 4142/4522/2873 +f 5653/5653/3499 5654/5654/3085 5655/5655/3794 +f 5653/5653/3499 5655/5655/3794 5656/5656/3795 +f 5654/5654/3085 3738/4118/2496 3741/4121/2499 +f 5654/5654/3085 3741/4121/2499 5655/5655/3794 +f 5655/5655/3794 3741/4121/2499 3743/4123/2501 +f 5655/5655/3794 3743/4123/2501 5657/5657/3796 +f 5656/5656/3795 5655/5655/3794 5657/5657/3796 +f 5656/5656/3795 5657/5657/3796 5658/5658/3797 +f 5659/5659/3532 5660/5660/3798 5661/5661/3799 +f 5659/5659/3532 5661/5661/3799 5662/5662/3533 +f 5660/5660/3798 5663/5663/3800 5664/5664/3801 +f 5660/5660/3798 5664/5664/3801 5661/5661/3799 +f 5661/5661/3799 5664/5664/3801 4159/4539/2890 +f 5661/5661/3799 4159/4539/2890 4158/4538/2889 +f 5662/5662/3533 5661/5661/3799 4158/4538/2889 +f 5662/5662/3533 4158/4538/2889 4157/4537/2888 +f 5455/5463/3673 5665/5665/3802 5666/5666/3803 +f 5455/5463/3673 5666/5666/3803 5456/5464/3674 +f 5665/5665/3802 5667/5667/3804 5668/5668/3805 +f 5665/5665/3802 5668/5668/3805 5666/5666/3803 +f 5666/5666/3803 5668/5668/3805 5658/5658/3797 +f 5666/5666/3803 5658/5658/3797 5657/5657/3796 +f 5456/5464/3674 5666/5666/3803 5657/5657/3796 +f 5456/5464/3674 5657/5657/3796 3743/4123/2501 +f 5669/5669/3806 5670/5670/3807 5671/5671/3808 +f 5669/5669/3806 5671/5671/3808 5672/5672/3809 +f 5670/5670/3807 5673/5673/3810 5674/5674/3811 +f 5670/5670/3807 5674/5674/3811 5671/5671/3808 +f 5671/5671/3808 5674/5674/3811 5025/5033/3362 +f 5671/5671/3808 5025/5033/3362 5592/5600/3745 +f 5672/5672/3809 5671/5671/3808 5592/5600/3745 +f 5672/5672/3809 5592/5600/3745 5591/5599/3744 +f 5675/5675/3812 5676/5676/3813 5677/5677/3814 +f 5675/5675/3812 5677/5677/3814 5678/5678/3815 +f 5676/5676/3813 5424/5432/3657 5427/5435/3660 +f 5676/5676/3813 5427/5435/3660 5677/5677/3814 +f 5677/5677/3814 5427/5435/3660 3983/4363/2724 +f 5677/5677/3814 3983/4363/2724 3982/4362/2723 +f 5678/5678/3815 5677/5677/3814 3982/4362/2723 +f 5678/5678/3815 3982/4362/2723 3981/4361/2722 +f 3409/3826/2204 3406/3823/2201 5679/5679/3816 +f 3409/3826/2204 5679/5679/3816 5680/5680/3817 +f 3406/3823/2201 3405/3822/2200 5550/5558/3709 +f 3406/3823/2201 5550/5558/3709 5679/5679/3816 +f 5679/5679/3816 5550/5558/3709 5554/5562/3710 +f 5679/5679/3816 5554/5562/3710 5681/5681/3818 +f 5680/5680/3817 5679/5679/3816 5681/5681/3818 +f 5680/5680/3817 5681/5681/3818 5682/5682/3819 +f 5683/5683/3804 5684/5684/3820 5685/5685/3821 +f 5683/5683/3804 5685/5685/3821 5686/5686/3822 +f 5684/5684/3820 5687/5687/3823 5688/5688/3824 +f 5684/5684/3820 5688/5688/3824 5685/5685/3821 +f 5685/5685/3821 5688/5688/3824 4494/4828/3170 +f 5685/5685/3821 4494/4828/3170 5190/5198/3502 +f 5686/5686/3822 5685/5685/3821 5190/5198/3502 +f 5686/5686/3822 5190/5198/3502 5189/5197/3501 +f 3888/4268/2633 5574/5582/3729 5689/5689/3825 +f 3888/4268/2633 5689/5689/3825 5690/5690/3826 +f 5198/5206/3509 5620/5624/3770 5689/5689/3825 +f 5198/5206/3509 5689/5689/3825 5574/5582/3729 +f 5622/5626/3772 5691/5691/3827 5689/5689/3825 +f 5622/5626/3772 5689/5689/3825 5620/5624/3770 +f 5692/5692/3828 5693/5693/3829 5689/5689/3825 +f 5692/5692/3828 5689/5689/3825 5691/5691/3827 +f 5694/5694/3830 5690/5690/3826 5689/5689/3825 +f 5694/5694/3830 5689/5689/3825 5693/5693/3829 +f 3258/3696/2070 4929/4937/3279 5695/5695/3831 +f 3258/3696/2070 5695/5695/3831 5696/5696/3832 +f 3409/3826/2204 5680/5680/3817 5695/5695/3831 +f 3409/3826/2204 5695/5695/3831 4929/4937/3279 +f 5682/5682/3819 5697/5697/3833 5695/5695/3831 +f 5682/5682/3819 5695/5695/3831 5680/5680/3817 +f 5698/5698/3834 5699/5699/3835 5695/5695/3831 +f 5698/5698/3834 5695/5695/3831 5697/5697/3833 +f 5700/5700/3836 5696/5696/3832 5695/5695/3831 +f 5700/5700/3836 5695/5695/3831 5699/5699/3835 +f 5701/5701/3650 5702/5702/3837 5703/5703/3837 +f 5701/5701/3650 5703/5703/3837 5704/5704/3650 +f 5702/5702/3837 5412/5420/3651 5415/5423/3651 +f 5702/5702/3837 5415/5423/3651 5703/5703/3837 +f 5703/5703/3837 5415/5423/3651 3781/4161/2537 +f 5703/5703/3837 3781/4161/2537 5088/5096/3417 +f 5704/5704/3650 5703/5703/3837 5088/5096/3417 +f 5704/5704/3650 5088/5096/3417 5087/5095/2679 +f 5705/5705/3838 5706/5706/3839 5707/5707/3840 +f 5705/5705/3838 5707/5707/3840 5708/5708/3841 +f 5706/5706/3839 5250/5258/3556 5253/5261/3559 +f 5706/5706/3839 5253/5261/3559 5707/5707/3840 +f 5707/5707/3840 5253/5261/3559 3726/4106/2484 +f 5707/5707/3840 3726/4106/2484 4174/4554/2905 +f 5708/5708/3841 5707/5707/3840 4174/4554/2905 +f 5708/5708/3841 4174/4554/2905 3776/4156/2533 +f 5103/5111/3430 5101/5109/3428 5709/5709/3842 +f 5103/5111/3430 5709/5709/3842 5551/5559/3555 +f 5101/5109/3428 3964/4344/2707 5500/5508/3685 +f 5101/5109/3428 5500/5508/3685 5709/5709/3842 +f 5709/5709/3842 5500/5508/3685 5504/5512/3685 +f 5709/5709/3842 5504/5512/3685 5710/5710/3842 +f 5551/5559/3555 5709/5709/3842 5710/5710/3842 +f 5551/5559/3555 5710/5710/3842 5552/5560/3555 +f 3960/4340/2703 4902/4910/3255 5711/5711/3843 +f 3960/4340/2703 5711/5711/3843 5501/5509/3686 +f 4902/4910/3255 4901/4909/3254 5534/5542/3698 +f 4902/4910/3255 5534/5542/3698 5711/5711/3843 +f 5711/5711/3843 5534/5542/3698 5538/5546/3698 +f 5711/5711/3843 5538/5546/3698 5712/5712/3843 +f 5501/5509/3686 5711/5711/3843 5712/5712/3843 +f 5501/5509/3686 5712/5712/3843 5502/5510/3686 +f 3799/4179/2550 3796/4176/2547 5713/5713/3844 +f 3799/4179/2550 5713/5713/3844 5479/5487/3629 +f 3796/4176/2547 3795/4175/2546 5522/5530/3654 +f 3796/4176/2547 5522/5530/3654 5713/5713/3844 +f 5713/5713/3844 5522/5530/3654 5526/5534/3654 +f 5713/5713/3844 5526/5534/3654 5714/5714/3844 +f 5479/5487/3629 5713/5713/3844 5714/5714/3844 +f 5479/5487/3629 5714/5714/3844 5480/5488/3629 +f 5354/5362/3618 5715/5715/3668 5716/5716/3668 +f 5354/5362/3618 5716/5716/3668 5355/5363/3618 +f 5715/5715/3668 5717/5717/3845 5718/5718/3845 +f 5715/5715/3668 5718/5718/3845 5716/5716/3668 +f 5716/5716/3668 5718/5718/3845 3957/4337/2701 +f 5716/5716/3668 3957/4337/2701 3956/4336/2700 +f 5355/5363/3618 5716/5716/3668 3956/4336/2700 +f 5355/5363/3618 3956/4336/2700 3918/4298/2662 +f 5719/5719/3690 5720/5720/3846 5721/5721/3846 +f 5719/5719/3690 5721/5721/3846 5722/5722/3690 +f 5720/5720/3846 5299/5307/3585 5302/5310/3585 +f 5720/5720/3846 5302/5310/3585 5721/5721/3846 +f 5721/5721/3846 5302/5310/3585 3829/4209/2577 +f 5721/5721/3846 3829/4209/2577 3997/4377/2736 +f 5722/5722/3690 5721/5721/3846 3997/4377/2736 +f 5722/5722/3690 3997/4377/2736 3996/4376/2735 +f 5723/5723/3688 5724/5724/3731 5725/5725/3731 +f 5723/5723/3688 5725/5725/3731 5726/5726/3688 +f 5724/5724/3731 5727/5727/3683 5728/5728/3683 +f 5724/5724/3731 5728/5728/3683 5725/5725/3731 +f 5725/5725/3731 5728/5728/3683 3823/4203/2571 +f 5725/5725/3731 3823/4203/2571 5133/5141/3454 +f 5726/5726/3688 5725/5725/3731 5133/5141/3454 +f 5726/5726/3688 5133/5141/3454 3839/4219/2586 +f 5729/5729/3686 5730/5730/3843 5731/5731/3843 +f 5729/5729/3686 5731/5731/3843 5732/5732/3686 +f 5730/5730/3843 5733/5733/3698 5734/5734/3698 +f 5730/5730/3843 5734/5734/3698 5731/5731/3843 +f 5731/5731/3843 5734/5734/3698 3752/4132/2510 +f 5731/5731/3843 3752/4132/2510 3751/4131/2509 +f 5732/5732/3686 5731/5731/3843 3751/4131/2509 +f 5732/5732/3686 3751/4131/2509 3750/4130/2508 +f 5735/5735/3620 5736/5736/3619 5737/5737/3619 +f 5735/5735/3620 5737/5737/3619 5738/5738/3620 +f 5739/5739/3622 5364/5372/3621 5367/5375/3621 +f 5739/5739/3622 5367/5375/3621 5740/5740/3622 +f 5740/5740/3622 5367/5375/3621 3794/4174/2545 +f 5740/5740/3622 3794/4174/2545 3793/4173/2544 +f 5738/5738/3620 5737/5737/3619 3792/4172/2544 +f 5738/5738/3620 3792/4172/2544 3791/4171/2543 +f 5741/5741/3589 5742/5742/3588 5743/5743/3588 +f 5741/5741/3589 5743/5743/3588 5744/5744/3589 +f 5742/5742/3588 5311/5319/3590 5314/5322/3590 +f 5742/5742/3588 5314/5322/3590 5743/5743/3588 +f 5743/5743/3588 5314/5322/3590 4056/4436/2792 +f 5743/5743/3588 4056/4436/2792 5136/5144/3456 +f 5744/5744/3589 5743/5743/3588 5136/5144/3456 +f 5744/5744/3589 5136/5144/3456 4094/4474/2827 +f 3881/4261/2626 4933/4941/3283 5745/5745/3847 +f 3881/4261/2626 5745/5745/3847 5459/5467/3677 +f 4933/4941/3283 4937/4945/3286 5470/5478/3577 +f 4933/4941/3283 5470/5478/3577 5745/5745/3847 +f 5745/5745/3847 5470/5478/3577 5472/5480/3577 +f 5745/5745/3847 5472/5480/3577 5746/5746/3847 +f 5459/5467/3677 5745/5745/3847 5746/5746/3847 +f 5459/5467/3677 5746/5746/3847 5460/5468/3677 +f 3944/4324/2688 4972/4980/3316 5747/5747/3848 +f 3944/4324/2688 5747/5747/3848 5330/5338/3598 +f 4972/4980/3316 4004/4384/2743 5438/5446/3667 +f 4972/4980/3316 5438/5446/3667 5747/5747/3848 +f 5747/5747/3848 5438/5446/3667 5440/5448/3667 +f 5747/5747/3848 5440/5448/3667 5748/5748/3848 +f 5330/5338/3598 5747/5747/3848 5748/5748/3848 +f 5330/5338/3598 5748/5748/3848 5331/5339/3598 +f 4168/4548/2899 5043/5051/3376 5749/5749/3849 +f 4168/4548/2899 5749/5749/3849 5402/5410/3645 +f 5043/5051/3376 5045/5053/3378 5750/5750/3850 +f 5043/5051/3376 5750/5750/3850 5749/5749/3849 +f 5749/5749/3849 5750/5750/3850 5751/5751/3851 +f 5749/5749/3849 5751/5751/3851 5752/5752/3852 +f 5402/5410/3645 5749/5749/3849 5752/5752/3852 +f 5402/5410/3645 5752/5752/3852 5403/5411/3646 +f 5753/5753/3680 5754/5754/3853 5755/5755/3853 +f 5753/5753/3680 5755/5755/3853 5756/5756/3679 +f 5754/5754/3853 5287/5295/3580 5290/5298/3580 +f 5754/5754/3853 5290/5298/3580 5755/5755/3853 +f 5755/5755/3853 5290/5298/3580 4035/4415/2772 +f 5755/5755/3853 4035/4415/2772 5121/5129/3444 +f 5756/5756/3679 5755/5755/3853 5121/5129/3444 +f 5756/5756/3679 5121/5129/3444 4124/4504/2855 +f 4943/4951/3292 5123/5131/3446 5757/5757/3853 +f 4943/4951/3292 5757/5757/3853 5474/5482/3679 +f 5123/5131/3446 5003/5011/3342 5464/5472/3580 +f 5123/5131/3446 5464/5472/3580 5757/5757/3853 +f 5757/5757/3853 5464/5472/3580 5468/5476/3580 +f 5757/5757/3853 5468/5476/3580 5758/5758/3853 +f 5474/5482/3679 5757/5757/3853 5758/5758/3853 +f 5474/5482/3679 5758/5758/3853 5475/5483/3680 +f 4947/4955/3296 4950/4958/3299 5759/5759/3846 +f 4947/4955/3296 5759/5759/3846 5511/5519/3690 +f 4950/4958/3299 4955/4963/3303 5324/5332/3585 +f 4950/4958/3299 5324/5332/3585 5759/5759/3846 +f 5759/5759/3846 5324/5332/3585 5328/5336/3585 +f 5759/5759/3846 5328/5336/3585 5760/5760/3846 +f 5511/5519/3690 5759/5759/3846 5760/5760/3846 +f 5511/5519/3690 5760/5760/3846 5512/5520/3690 +f 5761/5761/3677 5762/5762/3847 5763/5763/3847 +f 5761/5761/3677 5763/5763/3847 5764/5764/3677 +f 5762/5762/3847 5281/5289/3577 5284/5292/3577 +f 5762/5762/3847 5284/5292/3577 5763/5763/3847 +f 5763/5763/3847 5284/5292/3577 3870/4250/2616 +f 5763/5763/3847 3870/4250/2616 3869/4249/2615 +f 5764/5764/3677 5763/5763/3847 3869/4249/2615 +f 5764/5764/3677 3869/4249/2615 3868/4248/2614 +f 5248/5256/3555 5765/5765/3842 5766/5766/3842 +f 5248/5256/3555 5766/5766/3842 5249/5257/3555 +f 5765/5765/3842 5767/5767/3685 5768/5768/3685 +f 5765/5765/3842 5768/5768/3685 5766/5766/3842 +f 5766/5766/3842 5768/5768/3685 3817/4197/2565 +f 5766/5766/3842 3817/4197/2565 4900/4908/3253 +f 5249/5257/3555 5766/5766/3842 4900/4908/3253 +f 5249/5257/3555 4900/4908/3253 4180/4560/2910 +f 5037/5045/3265 5034/5042/3370 5769/5769/3854 +f 5037/5045/3265 5769/5769/3854 5770/5770/3855 +f 5034/5042/3370 5033/5041/3369 5270/5278/3569 +f 5034/5042/3370 5270/5278/3569 5769/5769/3854 +f 5769/5769/3854 5270/5278/3569 5274/5282/3573 +f 5769/5769/3854 5274/5282/3573 5771/5771/3856 +f 5770/5770/3855 5769/5769/3854 5771/5771/3856 +f 5770/5770/3855 5771/5771/3856 5772/5772/3633 +f 5416/5424/3653 5773/5773/3664 5774/5774/3664 +f 5416/5424/3653 5774/5774/3664 5417/5425/3653 +f 5773/5773/3664 5443/5451/3665 5446/5454/3665 +f 5773/5773/3664 5446/5454/3665 5774/5774/3664 +f 5774/5774/3664 5446/5454/3665 3770/4150/2527 +f 5774/5774/3664 3770/4150/2527 3769/4149/2526 +f 5417/5425/3653 5774/5774/3664 3769/4149/2526 +f 5417/5425/3653 3769/4149/2526 3768/4148/2525 +f 5029/5037/3366 5027/5035/3364 5775/5775/3857 +f 5029/5037/3366 5775/5775/3857 5516/5524/3624 +f 5027/5035/3364 3842/4222/2589 5478/5486/3627 +f 5027/5035/3364 5478/5486/3627 5775/5775/3857 +f 5775/5775/3857 5478/5486/3627 5482/5490/3627 +f 5775/5775/3857 5482/5490/3627 5776/5776/3857 +f 5516/5524/3624 5775/5775/3857 5776/5776/3857 +f 5516/5524/3624 5776/5776/3857 5517/5525/3624 +f 5777/5777/3563 5778/5778/3562 5779/5779/3562 +f 5777/5777/3563 5779/5779/3562 5780/5780/3563 +f 5778/5778/3562 5262/5270/3564 5265/5273/3564 +f 5778/5778/3562 5265/5273/3564 5779/5779/3562 +f 5779/5779/3562 5265/5273/3564 3901/4281/2645 +f 5779/5779/3562 3901/4281/2645 5100/5108/3427 +f 5780/5780/3563 5779/5779/3562 5100/5108/3427 +f 5780/5780/3563 5100/5108/3427 3927/4307/2671 +f 5767/5767/3685 5781/5781/3684 5782/5782/3684 +f 5767/5767/3685 5782/5782/3684 5768/5768/3685 +f 5781/5781/3684 5729/5729/3686 5732/5732/3686 +f 5781/5781/3684 5732/5732/3686 5782/5782/3684 +f 5782/5782/3684 5732/5732/3686 3750/4130/2508 +f 5782/5782/3684 3750/4130/2508 3818/4198/2566 +f 5768/5768/3685 5782/5782/3684 3818/4198/2566 +f 5768/5768/3685 3818/4198/2566 3817/4197/2565 +f 5045/5053/3378 5614/5618/3764 5783/5783/3858 +f 5045/5053/3378 5783/5783/3858 5750/5750/3850 +f 5614/5618/3764 4085/4465/2819 5397/5405/3640 +f 5614/5618/3764 5397/5405/3640 5783/5783/3858 +f 5783/5783/3858 5397/5405/3640 5399/5407/3642 +f 5783/5783/3858 5399/5407/3642 5784/5784/3859 +f 5750/5750/3850 5783/5783/3858 5784/5784/3859 +f 5750/5750/3850 5784/5784/3859 5751/5751/3851 +f 5382/5390/3629 5785/5785/3844 5786/5786/3844 +f 5382/5390/3629 5786/5786/3844 5383/5391/3629 +f 5785/5785/3844 5418/5426/3654 5421/5429/3654 +f 5785/5785/3844 5421/5429/3654 5786/5786/3844 +f 5786/5786/3844 5421/5429/3654 3759/4139/2516 +f 5786/5786/3844 3759/4139/2516 3947/4327/2691 +f 5383/5391/3629 5786/5786/3844 3947/4327/2691 +f 5383/5391/3629 3947/4327/2691 3854/4234/2600 +f 5733/5733/3698 5787/5787/3697 5788/5788/3697 +f 5733/5733/3698 5788/5788/3697 5734/5734/3698 +f 5787/5787/3697 5789/5789/3650 5790/5790/3650 +f 5787/5787/3697 5790/5790/3650 5788/5788/3697 +f 5788/5788/3697 5790/5790/3650 3935/4315/2679 +f 5788/5788/3697 3935/4315/2679 3934/4314/2678 +f 5734/5734/3698 5788/5788/3697 3934/4314/2678 +f 5734/5734/3698 3934/4314/2678 3752/4132/2510 +f 5717/5717/3845 5791/5791/3860 5792/5792/3860 +f 5717/5717/3845 5792/5792/3860 5718/5718/3845 +f 5791/5791/3860 5675/5675/3812 5678/5678/3815 +f 5791/5791/3860 5678/5678/3815 5792/5792/3860 +f 5792/5792/3860 5678/5678/3815 3981/4361/2722 +f 5792/5792/3860 3981/4361/2722 5094/5102/3422 +f 5718/5718/3845 5792/5792/3860 5094/5102/3422 +f 5718/5718/3845 5094/5102/3422 3957/4337/2701 +f 5279/5287/3576 5793/5793/3687 5794/5794/3687 +f 5279/5287/3576 5794/5794/3687 5280/5288/3576 +f 5793/5793/3687 5723/5723/3688 5726/5726/3688 +f 5793/5793/3687 5726/5726/3688 5794/5794/3687 +f 5794/5794/3687 5726/5726/3688 3839/4219/2586 +f 5794/5794/3687 3839/4219/2586 3838/4218/2585 +f 5280/5288/3576 5794/5794/3687 3838/4218/2585 +f 5280/5288/3576 3838/4218/2585 3812/4192/2560 +f 5795/5795/3861 5796/5796/3593 5797/5797/3593 +f 5795/5795/3861 5797/5797/3593 5798/5798/3861 +f 5796/5796/3593 5799/5799/3595 5800/5800/3595 +f 5796/5796/3593 5800/5800/3595 5797/5797/3593 +f 5797/5797/3593 5800/5800/3595 4076/4456/2810 +f 5797/5797/3593 4076/4456/2810 4075/4455/2809 +f 5798/5798/3861 5797/5797/3593 4075/4455/2809 +f 5798/5798/3861 4075/4455/2809 3975/4355/2717 +f 5428/5436/3661 5801/5801/3862 5802/5802/3863 +f 5428/5436/3661 5802/5802/3863 5429/5437/3662 +f 5801/5801/3862 5803/5803/3864 5804/5804/3865 +f 5801/5801/3862 5804/5804/3865 5802/5802/3863 +f 5802/5802/3863 5804/5804/3865 4065/4445/2800 +f 5802/5802/3863 4065/4445/2800 5082/5090/3413 +f 5429/5437/3662 5802/5802/3863 5082/5090/3413 +f 5429/5437/3662 5082/5090/3413 5081/5089/3412 +f 5205/5213/3516 5203/5211/3514 5805/5805/3866 +f 5205/5213/3516 5805/5805/3866 5806/5806/3715 +f 5203/5211/3514 4481/4815/3158 5225/5233/3535 +f 5203/5211/3514 5225/5233/3535 5805/5805/3866 +f 5805/5805/3866 5225/5233/3535 5229/5237/3539 +f 5805/5805/3866 5229/5237/3539 5807/5807/3867 +f 5806/5806/3715 5805/5805/3866 5807/5807/3867 +f 5806/5806/3715 5807/5807/3867 5808/5808/3868 +f 5368/5376/3624 5809/5809/3857 5810/5810/3857 +f 5368/5376/3624 5810/5810/3857 5369/5377/3624 +f 5809/5809/3857 5378/5386/3627 5381/5389/3627 +f 5809/5809/3857 5381/5389/3627 5810/5810/3857 +f 5810/5810/3857 5381/5389/3627 3852/4232/2598 +f 5810/5810/3857 3852/4232/2598 5014/5022/3353 +f 5369/5377/3624 5810/5810/3857 5014/5022/3353 +f 5369/5377/3624 5014/5022/3353 4018/4398/2757 +f 4127/4507/2858 4130/4510/2861 5811/5811/3869 +f 4127/4507/2858 5811/5811/3869 5465/5473/3582 +f 4130/4510/2861 4135/4515/2866 5371/5379/3616 +f 4130/4510/2861 5371/5379/3616 5811/5811/3869 +f 5811/5811/3869 5371/5379/3616 5375/5383/3616 +f 5811/5811/3869 5375/5383/3616 5812/5812/3869 +f 5465/5473/3582 5811/5811/3869 5812/5812/3869 +f 5465/5473/3582 5812/5812/3869 5466/5474/3582 +f 3991/4371/2732 5010/5018/3349 5813/5813/3870 +f 3991/4371/2732 5813/5813/3870 5346/5354/3612 +f 5010/5018/3349 4977/4985/3321 5318/5326/3594 +f 5010/5018/3349 5318/5326/3594 5813/5813/3870 +f 5813/5813/3870 5318/5326/3594 5322/5330/3596 +f 5813/5813/3870 5322/5330/3596 5814/5814/3871 +f 5346/5354/3612 5813/5813/3870 5814/5814/3871 +f 5346/5354/3612 5814/5814/3871 5347/5355/3613 +f 5727/5727/3683 5815/5815/3682 5816/5816/3682 +f 5727/5727/3683 5816/5816/3682 5728/5728/3683 +f 5815/5815/3682 5735/5735/3620 5738/5738/3620 +f 5815/5815/3682 5738/5738/3620 5816/5816/3682 +f 5816/5816/3682 5738/5738/3620 3791/4171/2543 +f 5816/5816/3682 3791/4171/2543 3824/4204/2572 +f 5728/5728/3683 5816/5816/3682 3824/4204/2572 +f 5728/5728/3683 3824/4204/2572 3823/4203/2571 +f 5583/5591/3736 5817/5817/3872 5818/5818/3872 +f 5583/5591/3736 5818/5818/3872 5584/5592/3737 +f 5817/5817/3872 5795/5795/3861 5798/5798/3861 +f 5817/5817/3872 5798/5798/3861 5818/5818/3872 +f 5818/5818/3872 5798/5798/3861 3975/4355/2717 +f 5818/5818/3872 3975/4355/2717 3974/4354/2716 +f 5584/5592/3737 5818/5818/3872 3974/4354/2716 +f 5584/5592/3737 3974/4354/2716 3973/4353/2715 +f 5291/5299/3582 5819/5819/3869 5820/5820/3869 +f 5291/5299/3582 5820/5820/3869 5292/5300/3582 +f 5819/5819/3869 5350/5358/3616 5353/5361/3616 +f 5819/5819/3869 5353/5361/3616 5820/5820/3869 +f 5820/5820/3869 5353/5361/3616 3916/4296/2660 +f 5820/5820/3869 3916/4296/2660 5115/5123/3438 +f 5292/5300/3582 5820/5820/3869 5115/5123/3438 +f 5292/5300/3582 5115/5123/3438 4037/4417/2774 +f 5673/5673/3810 5821/5821/3873 5822/5822/3874 +f 5673/5673/3810 5822/5822/3874 5674/5674/3811 +f 5821/5821/3873 5579/5587/3732 5582/5590/3735 +f 5821/5821/3873 5582/5590/3735 5822/5822/3874 +f 5822/5822/3874 5582/5590/3735 4002/4382/2741 +f 5822/5822/3874 4002/4382/2741 5026/5034/3363 +f 5674/5674/3811 5822/5822/3874 5026/5034/3363 +f 5674/5674/3811 5026/5034/3363 5025/5033/3362 +f 5823/5823/3592 5824/5824/3638 5825/5825/3638 +f 5823/5823/3592 5825/5825/3638 5826/5826/3592 +f 5824/5824/3638 5827/5827/3637 5828/5828/3637 +f 5824/5824/3638 5828/5828/3637 5825/5825/3638 +f 5825/5825/3638 5828/5828/3637 4122/4502/2853 +f 5825/5825/3638 4122/4502/2853 5130/5138/3451 +f 5826/5826/3592 5825/5825/3638 5130/5138/3451 +f 5826/5826/3592 5130/5138/3451 5129/5137/2794 +f 5803/5803/3864 5829/5829/3875 5830/5830/3876 +f 5803/5803/3864 5830/5830/3876 5804/5804/3865 +f 5831/5831/3877 5565/5573/3721 5564/5572/3720 +f 5831/5831/3877 5564/5572/3720 5832/5832/3878 +f 5832/5832/3878 5564/5572/3720 4069/4449/2804 +f 5832/5832/3878 4069/4449/2804 4068/4448/2803 +f 5804/5804/3865 5830/5830/3876 4066/4446/2801 +f 5804/5804/3865 4066/4446/2801 4065/4445/2800 +f 5833/5833/3598 5834/5834/3848 5835/5835/3848 +f 5833/5833/3598 5835/5835/3848 5836/5836/3598 +f 5834/5834/3848 5837/5837/3667 5838/5838/3667 +f 5834/5834/3848 5838/5838/3667 5835/5835/3848 +f 5835/5835/3848 5838/5838/3667 3925/4305/2669 +f 5835/5835/3848 3925/4305/2669 5091/5099/3420 +f 5836/5836/3598 5835/5835/3848 5091/5099/3420 +f 5836/5836/3598 5091/5099/3420 5049/5057/3382 +f 4105/4485/2837 4957/4965/3305 5839/5839/3879 +f 4105/4485/2837 5839/5839/3879 5450/5458/3566 +f 4957/4965/3305 4961/4969/2618 5840/5840/3676 +f 4957/4965/3305 5840/5840/3676 5839/5839/3879 +f 5839/5839/3879 5840/5840/3676 5841/5841/3676 +f 5839/5839/3879 5841/5841/3676 5842/5842/3879 +f 5450/5458/3566 5839/5839/3879 5842/5842/3879 +f 5450/5458/3566 5842/5842/3879 5451/5459/3566 +f 5799/5799/3595 5843/5843/3597 5844/5844/3597 +f 5799/5799/3595 5844/5844/3597 5800/5800/3595 +f 5843/5843/3597 5833/5833/3598 5836/5836/3598 +f 5843/5843/3597 5836/5836/3598 5844/5844/3597 +f 5844/5844/3597 5836/5836/3598 5049/5057/3382 +f 5844/5844/3597 5049/5057/3382 5048/5056/3381 +f 5800/5800/3595 5844/5844/3597 5048/5056/3381 +f 5800/5800/3595 5048/5056/3381 4076/4456/2810 +f 5303/5311/3587 5845/5845/3681 5846/5846/3681 +f 5303/5311/3587 5846/5846/3681 5304/5312/3587 +f 5845/5845/3681 5741/5741/3589 5744/5744/3589 +f 5845/5845/3681 5744/5744/3589 5846/5846/3681 +f 5846/5846/3681 5744/5744/3589 4094/4474/2827 +f 5846/5846/3681 4094/4474/2827 4093/4473/2826 +f 5304/5312/3587 5846/5846/3681 4093/4473/2826 +f 5304/5312/3587 4093/4473/2826 3831/4211/2579 +f 5266/5274/3566 5847/5847/3879 5848/5848/3879 +f 5266/5274/3566 5848/5848/3879 5267/5275/3566 +f 5847/5847/3879 5849/5849/3676 5850/5850/3676 +f 5847/5847/3879 5850/5850/3676 5848/5848/3879 +f 5848/5848/3879 5850/5850/3676 5110/5118/2631 +f 5848/5848/3879 5110/5118/2631 5109/5117/3434 +f 5267/5275/3566 5848/5848/3879 5109/5117/3434 +f 5267/5275/3566 5109/5117/3434 3903/4283/2647 +f 5447/5455/3670 5851/5851/3689 5852/5852/3689 +f 5447/5455/3670 5852/5852/3689 5448/5456/3670 +f 5851/5851/3689 5719/5719/3690 5722/5722/3690 +f 5851/5851/3689 5722/5722/3690 5852/5852/3689 +f 5852/5852/3689 5722/5722/3690 3996/4376/2735 +f 5852/5852/3689 3996/4376/2735 5097/5105/3424 +f 5448/5456/3670 5852/5852/3689 5097/5105/3424 +f 5448/5456/3670 5097/5105/3424 3911/4291/2655 +f 5853/5853/3584 5854/5854/3773 5855/5855/3773 +f 5853/5853/3584 5855/5855/3773 5856/5856/3584 +f 5854/5854/3773 5275/5283/3574 5278/5286/3574 +f 5854/5854/3773 5278/5286/3574 5855/5855/3773 +f 5855/5855/3773 5278/5286/3574 3810/4190/2558 +f 5855/5855/3773 3810/4190/2558 4150/4530/2881 +f 5856/5856/3584 5855/5855/3773 4150/4530/2881 +f 5856/5856/3584 4150/4530/2881 4149/4529/2880 +f 5827/5827/3637 5857/5857/3678 5858/5858/3678 +f 5827/5827/3637 5858/5858/3678 5828/5828/3637 +f 5857/5857/3678 5753/5753/3680 5756/5756/3679 +f 5857/5857/3678 5756/5756/3679 5858/5858/3678 +f 5858/5858/3678 5756/5756/3679 4124/4504/2855 +f 5858/5858/3678 4124/4504/2855 4123/4503/2854 +f 5828/5828/3637 5858/5858/3678 4123/4503/2854 +f 5828/5828/3637 4123/4503/2854 4122/4502/2853 +f 5859/5859/3676 5860/5860/3675 5861/5861/3675 +f 5859/5859/3676 5861/5861/3675 5862/5862/3676 +f 5860/5860/3675 5761/5761/3677 5764/5764/3677 +f 5860/5860/3675 5764/5764/3677 5861/5861/3675 +f 5861/5861/3675 5764/5764/3677 3868/4248/2614 +f 5861/5861/3675 3868/4248/2614 3887/4267/2632 +f 5862/5862/3676 5861/5861/3675 3887/4267/2632 +f 5862/5862/3676 3887/4267/2632 3886/4266/2631 +f 5863/5863/3880 5864/5864/3881 5865/5865/3882 +f 5863/5863/3880 5865/5865/3882 5866/5866/3883 +f 5864/5864/3881 5244/5252/3553 5247/5255/3553 +f 5864/5864/3881 5247/5255/3553 5865/5865/3882 +f 5865/5865/3882 5247/5255/3553 3737/4117/2495 +f 5865/5865/3882 3737/4117/2495 3736/4116/2494 +f 5866/5866/3883 5865/5865/3882 3736/4116/2494 +f 5866/5866/3883 3736/4116/2494 3735/4115/2493 +f 5285/5293/3579 5867/5867/3583 5868/5868/3583 +f 5285/5293/3579 5868/5868/3583 5286/5294/3579 +f 5867/5867/3583 5853/5853/3584 5856/5856/3584 +f 5867/5867/3583 5856/5856/3584 5868/5868/3583 +f 5868/5868/3583 5856/5856/3584 4149/4529/2880 +f 5868/5868/3583 4149/4529/2880 5118/5126/3441 +f 5286/5294/3579 5868/5868/3583 5118/5126/3441 +f 5286/5294/3579 5118/5126/3441 4115/4495/2847 +f 5869/5869/3884 5870/5870/3885 5871/5871/3886 +f 5869/5869/3884 5871/5871/3886 5872/5872/3887 +f 5870/5870/3885 5873/5873/3888 5874/5874/3889 +f 5870/5870/3885 5874/5874/3889 5871/5871/3886 +f 5871/5871/3886 5874/5874/3889 4144/4524/2875 +f 5871/5871/3886 4144/4524/2875 4143/4523/2874 +f 5872/5872/3887 5871/5871/3886 4143/4523/2874 +f 5872/5872/3887 4143/4523/2874 4142/4522/2873 +f 5837/5837/3667 5875/5875/3666 5876/5876/3666 +f 5837/5837/3667 5876/5876/3666 5838/5838/3667 +f 5875/5875/3666 5777/5777/3563 5780/5780/3563 +f 5875/5875/3666 5780/5780/3563 5876/5876/3666 +f 5876/5876/3666 5780/5780/3563 3927/4307/2671 +f 5876/5876/3666 3927/4307/2671 3926/4306/2670 +f 5838/5838/3667 5876/5876/3666 3926/4306/2670 +f 5838/5838/3667 3926/4306/2670 3925/4305/2669 +f 5663/5663/3800 5877/5877/3890 5878/5878/3891 +f 5663/5663/3800 5878/5878/3891 5664/5664/3801 +f 5877/5877/3890 5869/5869/3884 5872/5872/3887 +f 5877/5877/3890 5872/5872/3887 5878/5878/3891 +f 5878/5878/3891 5872/5872/3887 4142/4522/2873 +f 5878/5878/3891 4142/4522/2873 5652/5652/3793 +f 5664/5664/3801 5878/5878/3891 5652/5652/3793 +f 5664/5664/3801 5652/5652/3793 4159/4539/2890 +f 5422/5430/3656 5879/5879/3892 5880/5880/3893 +f 5422/5430/3656 5880/5880/3893 5423/5431/3656 +f 5879/5879/3892 5705/5705/3838 5708/5708/3841 +f 5879/5879/3892 5708/5708/3841 5880/5880/3893 +f 5880/5880/3893 5708/5708/3841 3776/4156/2533 +f 5880/5880/3893 3776/4156/2533 3775/4155/2532 +f 5423/5431/3656 5880/5880/3893 3775/4155/2532 +f 5423/5431/3656 3775/4155/2532 3761/4141/2518 +f 5873/5873/3888 5881/5881/3894 5882/5882/3895 +f 5873/5873/3888 5882/5882/3895 5874/5874/3889 +f 5881/5881/3894 5863/5863/3880 5866/5866/3883 +f 5881/5881/3894 5866/5866/3883 5882/5882/3895 +f 5882/5882/3895 5866/5866/3883 3735/4115/2493 +f 5882/5882/3895 3735/4115/2493 4171/4551/2902 +f 5874/5874/3889 5882/5882/3895 4171/4551/2902 +f 5874/5874/3889 4171/4551/2902 4144/4524/2875 +f 5883/5883/3896 5884/5884/3897 5885/5885/3898 +f 5883/5883/3896 5885/5885/3898 5886/5886/3899 +f 5884/5884/3897 5234/5242/3543 5232/5240/3542 +f 5884/5884/3897 5232/5240/3542 5885/5885/3898 +f 5885/5885/3898 5232/5240/3542 4030/4410/2767 +f 5885/5885/3898 4030/4410/2767 4897/4905/3250 +f 5886/5886/3899 5885/5885/3898 4897/4905/3250 +f 5886/5886/3899 4897/4905/3250 4478/4812/3155 +f 5573/5581/3728 5887/5887/3900 5888/5888/3901 +f 5573/5581/3728 5888/5888/3901 5568/5576/3724 +f 5887/5887/3900 5883/5883/3896 5886/5886/3899 +f 5887/5887/3900 5886/5886/3899 5888/5888/3901 +f 5888/5888/3901 5886/5886/3899 4478/4812/3155 +f 5888/5888/3901 4478/4812/3155 4477/4811/3154 +f 5568/5576/3724 5888/5888/3901 4477/4811/3154 +f 5568/5576/3724 4477/4811/3154 4476/4810/3153 +f 5889/5889/3902 5890/5890/3903 5891/5891/3904 +f 5889/5889/3902 5891/5891/3904 5892/5892/3905 +f 5890/5890/3903 5218/5226/3528 5221/5229/3531 +f 5890/5890/3903 5221/5229/3531 5891/5891/3904 +f 5891/5891/3904 5221/5229/3531 4882/4890/3238 +f 5891/5891/3904 4882/4890/3238 4881/4889/3237 +f 5892/5892/3905 5891/5891/3904 4881/4889/3237 +f 5892/5892/3905 4881/4889/3237 4496/4830/3172 +f 5687/5687/3823 5893/5893/3906 5894/5894/3907 +f 5687/5687/3823 5894/5894/3907 5688/5688/3824 +f 5893/5893/3906 5889/5889/3902 5892/5892/3905 +f 5893/5893/3906 5892/5892/3905 5894/5894/3907 +f 5894/5894/3907 5892/5892/3905 4496/4830/3172 +f 5894/5894/3907 4496/4830/3172 4495/4829/3171 +f 5688/5688/3824 5894/5894/3907 4495/4829/3171 +f 5688/5688/3824 4495/4829/3171 4494/4828/3170 +f 5663/5663/3800 5660/5660/3798 5895/5895/3908 +f 5663/5663/3800 5895/5895/3908 5896/5896/3909 +f 5660/5660/3798 5659/5659/3532 5897/5897/3910 +f 5660/5660/3798 5897/5897/3910 5895/5895/3908 +f 5895/5895/3908 5897/5897/3910 5898/5898/3911 +f 5895/5895/3908 5898/5898/3911 5899/5899/3912 +f 5896/5896/3909 5895/5895/3908 5899/5899/3912 +f 5896/5896/3909 5899/5899/3912 5900/5900/3913 +f 5900/5900/3913 5899/5899/3912 5901/5901/3914 +f 5900/5900/3913 5901/5901/3914 5902/5902/3915 +f 5899/5899/3912 5898/5898/3911 5903/5903/3916 +f 5899/5899/3912 5903/5903/3916 5901/5901/3914 +f 5901/5901/3914 5903/5903/3916 5772/5772/3633 +f 5901/5901/3914 5772/5772/3633 5771/5771/3856 +f 5902/5902/3915 5901/5901/3914 5771/5771/3856 +f 5902/5902/3915 5771/5771/3856 5274/5282/3573 +f 5455/5463/3673 5453/5461/3671 5904/5904/3917 +f 5455/5463/3673 5904/5904/3917 5905/5905/3918 +f 5453/5461/3671 5254/5262/3560 5906/5906/3919 +f 5453/5461/3671 5906/5906/3919 5904/5904/3917 +f 5904/5904/3917 5906/5906/3919 5907/5907/3920 +f 5904/5904/3917 5907/5907/3920 5908/5908/3921 +f 5905/5905/3918 5904/5904/3917 5908/5908/3921 +f 5905/5905/3918 5908/5908/3921 5909/5909/3922 +f 5909/5909/3922 5908/5908/3921 5910/5910/3923 +f 5909/5909/3922 5910/5910/3923 5911/5911/3924 +f 5908/5908/3921 5907/5907/3920 5912/5912/3925 +f 5908/5908/3921 5912/5912/3925 5910/5910/3923 +f 5910/5910/3923 5912/5912/3925 5622/5626/3772 +f 5910/5910/3923 5622/5626/3772 5621/5625/3771 +f 5911/5911/3924 5910/5910/3923 5621/5625/3771 +f 5911/5911/3924 5621/5625/3771 5562/5570/3718 +f 5673/5673/3810 5670/5670/3807 5913/5913/3926 +f 5673/5673/3810 5913/5913/3926 5914/5914/3927 +f 5670/5670/3807 5669/5669/3806 5915/5915/3928 +f 5670/5670/3807 5915/5915/3928 5913/5913/3926 +f 5913/5913/3926 5915/5915/3928 5916/5916/3929 +f 5913/5913/3926 5916/5916/3929 5917/5917/3930 +f 5914/5914/3927 5913/5913/3926 5917/5917/3930 +f 5914/5914/3927 5917/5917/3930 5918/5918/3931 +f 5918/5918/3931 5917/5917/3930 5919/5919/3932 +f 5918/5918/3931 5919/5919/3932 5920/5920/3933 +f 5917/5917/3930 5916/5916/3929 5921/5921/3934 +f 5917/5917/3930 5921/5921/3934 5919/5919/3932 +f 5919/5919/3932 5921/5921/3934 5343/5351/3609 +f 5919/5919/3932 5343/5351/3609 5342/5350/3608 +f 5920/5920/3933 5919/5919/3932 5342/5350/3608 +f 5920/5920/3933 5342/5350/3608 5341/5349/3607 +f 5428/5436/3661 5425/5433/3658 5922/5922/3935 +f 5428/5436/3661 5922/5922/3935 5923/5923/3936 +f 5425/5433/3658 5424/5432/3657 5924/5924/3937 +f 5425/5433/3658 5924/5924/3937 5922/5922/3935 +f 5922/5922/3935 5924/5924/3937 5925/5925/3938 +f 5922/5922/3935 5925/5925/3938 5926/5926/3939 +f 5923/5923/3936 5922/5922/3935 5926/5926/3939 +f 5923/5923/3936 5926/5926/3939 5927/5927/3940 +f 5927/5927/3940 5926/5926/3939 5928/5928/3941 +f 5927/5927/3940 5928/5928/3941 5929/5929/3942 +f 5926/5926/3939 5925/5925/3938 5930/5930/3943 +f 5926/5926/3939 5930/5930/3943 5928/5928/3941 +f 5928/5928/3941 5930/5930/3943 5751/5751/3851 +f 5928/5928/3941 5751/5751/3851 5784/5784/3859 +f 5929/5929/3942 5928/5928/3941 5784/5784/3859 +f 5929/5929/3942 5784/5784/3859 5399/5407/3642 +f 5931/5931/3944 5932/5932/3945 5933/5933/3946 +f 5931/5931/3944 5933/5933/3946 5934/5934/3928 +f 5333/5341/3599 5243/5251/3552 5935/5935/3947 +f 5333/5341/3599 5935/5935/3947 5936/5936/3948 +f 5933/5933/3946 5937/5937/3949 5938/5938/3950 +f 5933/5933/3946 5938/5938/3950 5939/5939/3951 +f 5934/5934/3928 5933/5933/3946 5939/5939/3951 +f 5934/5934/3928 5939/5939/3951 5940/5940/3952 +f 5940/5940/3952 5939/5939/3951 5941/5941/3953 +f 5940/5940/3952 5941/5941/3953 5942/5942/3954 +f 5939/5939/3951 5938/5938/3950 5943/5943/3955 +f 5939/5939/3951 5943/5943/3955 5941/5941/3953 +f 5941/5941/3953 5943/5943/3955 5573/5581/3728 +f 5941/5941/3953 5573/5581/3728 5572/5580/3727 +f 5942/5942/3954 5941/5941/3953 5572/5580/3727 +f 5942/5942/3954 5572/5580/3727 5571/5579/3726 +f 5687/5687/3823 5684/5684/3820 5944/5944/3956 +f 5687/5687/3823 5944/5944/3956 5945/5945/3957 +f 5684/5684/3820 5683/5683/3804 5946/5946/3958 +f 5684/5684/3820 5946/5946/3958 5944/5944/3956 +f 5944/5944/3956 5946/5946/3958 5947/5947/3959 +f 5944/5944/3956 5947/5947/3959 5948/5948/3960 +f 5945/5945/3957 5944/5944/3956 5948/5948/3960 +f 5945/5945/3957 5948/5948/3960 5949/5949/3961 +f 5949/5949/3961 5948/5948/3960 5950/5950/3962 +f 5949/5949/3961 5950/5950/3962 5951/5951/3963 +f 5948/5948/3960 5947/5947/3959 5952/5952/3964 +f 5948/5948/3960 5952/5952/3964 5950/5950/3962 +f 5953/5953/3962 5954/5954/3964 5955/5955/3965 +f 5953/5953/3962 5955/5955/3965 5956/5956/3867 +f 5957/5957/3963 5953/5953/3962 5956/5956/3867 +f 5957/5957/3963 5956/5956/3867 5958/5958/3539 +f 5667/5667/3804 5665/5665/3802 5959/5959/3966 +f 5667/5667/3804 5959/5959/3966 5960/5960/3967 +f 5665/5665/3802 5455/5463/3673 5905/5905/3918 +f 5665/5665/3802 5905/5905/3918 5959/5959/3966 +f 5959/5959/3966 5905/5905/3918 5909/5909/3922 +f 5959/5959/3966 5909/5909/3922 5961/5961/3968 +f 5960/5960/3967 5959/5959/3966 5961/5961/3968 +f 5960/5960/3967 5961/5961/3968 5962/5962/3969 +f 5947/5947/3959 5963/5963/3970 5964/5964/3971 +f 5947/5947/3959 5964/5964/3971 5952/5952/3964 +f 5961/5961/3968 5909/5909/3922 5911/5911/3924 +f 5961/5961/3968 5911/5911/3924 5965/5965/3971 +f 5965/5965/3971 5911/5911/3924 5562/5570/3718 +f 5965/5965/3971 5562/5570/3718 5561/5569/3717 +f 5966/5966/3972 5965/5965/3971 5561/5569/3717 +f 5966/5966/3972 5561/5569/3717 5560/5568/3716 +f 5248/5256/3555 5245/5253/3554 5967/5967/3554 +f 5248/5256/3555 5967/5967/3554 5968/5968/3555 +f 5245/5253/3554 5244/5252/3553 5969/5969/3973 +f 5245/5253/3554 5969/5969/3973 5967/5967/3554 +f 5967/5967/3554 5969/5969/3973 5970/5970/3974 +f 5967/5967/3554 5970/5970/3974 5971/5971/3554 +f 5968/5968/3555 5967/5967/3554 5971/5971/3554 +f 5968/5968/3555 5971/5971/3554 5972/5972/3555 +f 5972/5972/3555 5971/5971/3554 5973/5973/3554 +f 5972/5972/3555 5973/5973/3554 5974/5974/3555 +f 5971/5971/3554 5970/5970/3974 5975/5975/3975 +f 5971/5971/3554 5975/5975/3975 5973/5973/3554 +f 5973/5973/3554 5975/5975/3975 5554/5562/3710 +f 5973/5973/3554 5554/5562/3710 5553/5561/3554 +f 5974/5974/3555 5973/5973/3554 5553/5561/3554 +f 5974/5974/3555 5553/5561/3554 5552/5560/3555 +f 5254/5262/3560 5251/5259/3557 5976/5976/3976 +f 5254/5262/3560 5976/5976/3976 5906/5906/3919 +f 5251/5259/3557 5250/5258/3556 5977/5977/3977 +f 5251/5259/3557 5977/5977/3977 5976/5976/3976 +f 5976/5976/3976 5977/5977/3977 5978/5978/3978 +f 5976/5976/3976 5978/5978/3978 5979/5979/3979 +f 5906/5906/3919 5976/5976/3976 5979/5979/3979 +f 5906/5906/3919 5979/5979/3979 5907/5907/3920 +f 3892/4272/2637 3889/4269/2634 5980/5980/3980 +f 3892/4272/2637 5980/5980/3980 5530/5538/3694 +f 3888/4268/2633 5690/5690/3826 5980/5980/3980 +f 3888/4268/2633 5980/5980/3980 3889/4269/2634 +f 5694/5694/3830 5981/5981/3981 5980/5980/3980 +f 5694/5694/3830 5980/5980/3980 5690/5690/3826 +f 5982/5982/3982 5983/5983/3983 5980/5980/3980 +f 5982/5982/3982 5980/5980/3980 5981/5981/3981 +f 5531/5539/3695 5530/5538/3694 5980/5980/3980 +f 5531/5539/3695 5980/5980/3980 5983/5983/3983 +f 5789/5789/3650 5787/5787/3697 5984/5984/3697 +f 5789/5789/3650 5984/5984/3697 5985/5985/3650 +f 5787/5787/3697 5733/5733/3698 5986/5986/3698 +f 5787/5787/3697 5986/5986/3698 5984/5984/3697 +f 5984/5984/3697 5986/5986/3698 5987/5987/3698 +f 5984/5984/3697 5987/5987/3698 5988/5988/3697 +f 5985/5985/3650 5984/5984/3697 5988/5988/3697 +f 5985/5985/3650 5988/5988/3697 5989/5989/3650 +f 5989/5989/3650 5988/5988/3697 5990/5990/3697 +f 5989/5989/3650 5990/5990/3697 5991/5991/3650 +f 5988/5988/3697 5987/5987/3698 5992/5992/3698 +f 5988/5988/3697 5992/5992/3698 5990/5990/3697 +f 5990/5990/3697 5992/5992/3698 5538/5546/3698 +f 5990/5990/3697 5538/5546/3698 5537/5545/3697 +f 5991/5991/3650 5990/5990/3697 5537/5545/3697 +f 5991/5991/3650 5537/5545/3697 5536/5544/3650 +f 5705/5705/3838 5879/5879/3892 5993/5993/3984 +f 5705/5705/3838 5993/5993/3984 5994/5994/3985 +f 5879/5879/3892 5422/5430/3656 5995/5995/3656 +f 5879/5879/3892 5995/5995/3656 5993/5993/3984 +f 5993/5993/3984 5995/5995/3656 5996/5996/3656 +f 5993/5993/3984 5996/5996/3656 5997/5997/3986 +f 5994/5994/3985 5993/5993/3984 5997/5997/3986 +f 5994/5994/3985 5997/5997/3986 5998/5998/3987 +f 5998/5998/3987 5997/5997/3986 5999/5999/3988 +f 5998/5998/3987 5999/5999/3988 6000/6000/3989 +f 5997/5997/3986 5996/5996/3656 6001/6001/3990 +f 5997/5997/3986 6001/6001/3990 5999/5999/3988 +f 5999/5999/3988 6001/6001/3990 5524/5532/3692 +f 5999/5999/3988 5524/5532/3692 5532/5540/3696 +f 6000/6000/3989 5999/5999/3988 5532/5540/3696 +f 6000/6000/3989 5532/5540/3696 5531/5539/3695 +f 5447/5455/3670 5444/5452/3669 6002/6002/3669 +f 5447/5455/3670 6002/6002/3669 6003/6003/3670 +f 5444/5452/3669 5443/5451/3665 6004/6004/3665 +f 5444/5452/3669 6004/6004/3665 6002/6002/3669 +f 6002/6002/3669 6004/6004/3665 6005/6005/3665 +f 6002/6002/3669 6005/6005/3665 6006/6006/3669 +f 6003/6003/3670 6002/6002/3669 6006/6006/3669 +f 6003/6003/3670 6006/6006/3669 6007/6007/3670 +f 6007/6007/3670 6006/6006/3669 6008/6008/3669 +f 6007/6007/3670 6008/6008/3669 6009/6009/3670 +f 6006/6006/3669 6005/6005/3665 6010/6010/3665 +f 6006/6006/3669 6010/6010/3665 6008/6008/3669 +f 6008/6008/3669 6010/6010/3665 5434/5442/3665 +f 6008/6008/3669 5434/5442/3665 5528/5536/3669 +f 6009/6009/3670 6008/6008/3669 5528/5536/3669 +f 6009/6009/3670 5528/5536/3669 5514/5522/3670 +f 5422/5430/3656 5419/5427/3655 6011/6011/3655 +f 5422/5430/3656 6011/6011/3655 5995/5995/3656 +f 5419/5427/3655 5418/5426/3654 6012/6012/3654 +f 5419/5427/3655 6012/6012/3654 6011/6011/3655 +f 6011/6011/3655 6012/6012/3654 6013/6013/3654 +f 6011/6011/3655 6013/6013/3654 6014/6014/3655 +f 5995/5995/3656 6011/6011/3655 6014/6014/3655 +f 5995/5995/3656 6014/6014/3655 5996/5996/3656 +f 5996/5996/3656 6014/6014/3655 6015/6015/3655 +f 5996/5996/3656 6015/6015/3655 6001/6001/3990 +f 6014/6014/3655 6013/6013/3654 6016/6016/3654 +f 6014/6014/3655 6016/6016/3654 6015/6015/3655 +f 6015/6015/3655 6016/6016/3654 5526/5534/3654 +f 6015/6015/3655 5526/5534/3654 5525/5533/3655 +f 6001/6001/3990 6015/6015/3655 5525/5533/3655 +f 6001/6001/3990 5525/5533/3655 5524/5532/3692 +f 5416/5424/3653 5413/5421/3652 6017/6017/3652 +f 5416/5424/3653 6017/6017/3652 6018/6018/3653 +f 5413/5421/3652 5412/5420/3651 6019/6019/3651 +f 5413/5421/3652 6019/6019/3651 6017/6017/3652 +f 6017/6017/3652 6019/6019/3651 6020/6020/3651 +f 6017/6017/3652 6020/6020/3651 6021/6021/3652 +f 6018/6018/3653 6017/6017/3652 6021/6021/3652 +f 6018/6018/3653 6021/6021/3652 6022/6022/3653 +f 6022/6022/3653 6021/6021/3652 6023/6023/3652 +f 6022/6022/3653 6023/6023/3652 6024/6024/3653 +f 6021/6021/3652 6020/6020/3651 6025/6025/3651 +f 6021/6021/3652 6025/6025/3651 6023/6023/3652 +f 6023/6023/3652 6025/6025/3651 5409/5417/3651 +f 6023/6023/3652 5409/5417/3651 5520/5528/3652 +f 6024/6024/3653 6023/6023/3652 5520/5528/3652 +f 6024/6024/3653 5520/5528/3652 5436/5444/3653 +f 5368/5376/3624 5365/5373/3623 6026/6026/3623 +f 5368/5376/3624 6026/6026/3623 6027/6027/3624 +f 5365/5373/3623 5364/5372/3621 6028/6028/3621 +f 5365/5373/3623 6028/6028/3621 6026/6026/3623 +f 6026/6026/3623 6028/6028/3621 6029/6029/3621 +f 6026/6026/3623 6029/6029/3621 6030/6030/3623 +f 6027/6027/3624 6026/6026/3623 6030/6030/3623 +f 6027/6027/3624 6030/6030/3623 6031/6031/3624 +f 6031/6031/3624 6030/6030/3623 6032/6032/3623 +f 6031/6031/3624 6032/6032/3623 6033/6033/3624 +f 6030/6030/3623 6029/6029/3621 6034/6034/3621 +f 6030/6030/3623 6034/6034/3621 6032/6032/3623 +f 6032/6032/3623 6034/6034/3621 5360/5368/3621 +f 6032/6032/3623 5360/5368/3621 5518/5526/3623 +f 6033/6033/3624 6032/6032/3623 5518/5526/3623 +f 6033/6033/3624 5518/5526/3623 5517/5525/3624 +f 5719/5719/3690 5851/5851/3689 6035/6035/3689 +f 5719/5719/3690 6035/6035/3689 6036/6036/3690 +f 5851/5851/3689 5447/5455/3670 6003/6003/3670 +f 5851/5851/3689 6003/6003/3670 6035/6035/3689 +f 6035/6035/3689 6003/6003/3670 6007/6007/3670 +f 6035/6035/3689 6007/6007/3670 6037/6037/3689 +f 6036/6036/3690 6035/6035/3689 6037/6037/3689 +f 6036/6036/3690 6037/6037/3689 6038/6038/3690 +f 6038/6038/3690 6037/6037/3689 6039/6039/3689 +f 6038/6038/3690 6039/6039/3689 6040/6040/3690 +f 6037/6037/3689 6007/6007/3670 6009/6009/3670 +f 6037/6037/3689 6009/6009/3670 6039/6039/3689 +f 6039/6039/3689 6009/6009/3670 5514/5522/3670 +f 6039/6039/3689 5514/5522/3670 5513/5521/3689 +f 6040/6040/3690 6039/6039/3689 5513/5521/3689 +f 6040/6040/3690 5513/5521/3689 5512/5520/3690 +f 5723/5723/3688 5793/5793/3687 6041/6041/3687 +f 5723/5723/3688 6041/6041/3687 6042/6042/3688 +f 5793/5793/3687 5279/5287/3576 6043/6043/3576 +f 5793/5793/3687 6043/6043/3576 6041/6041/3687 +f 6041/6041/3687 6043/6043/3576 6044/6044/3576 +f 6041/6041/3687 6044/6044/3576 6045/6045/3687 +f 6042/6042/3688 6041/6041/3687 6045/6045/3687 +f 6042/6042/3688 6045/6045/3687 6046/6046/3688 +f 6046/6046/3688 6045/6045/3687 6047/6047/3687 +f 6046/6046/3688 6047/6047/3687 6048/6048/3688 +f 6045/6045/3687 6044/6044/3576 6049/6049/3576 +f 6045/6045/3687 6049/6049/3576 6047/6047/3687 +f 6047/6047/3687 6049/6049/3576 5490/5498/3576 +f 6047/6047/3687 5490/5498/3576 5508/5516/3687 +f 6048/6048/3688 6047/6047/3687 5508/5516/3687 +f 6048/6048/3688 5508/5516/3687 5507/5515/3688 +f 5729/5729/3686 5781/5781/3684 6050/6050/3684 +f 5729/5729/3686 6050/6050/3684 6051/6051/3686 +f 5781/5781/3684 5767/5767/3685 6052/6052/3685 +f 5781/5781/3684 6052/6052/3685 6050/6050/3684 +f 6050/6050/3684 6052/6052/3685 6053/6053/3685 +f 6050/6050/3684 6053/6053/3685 6054/6054/3684 +f 6051/6051/3686 6050/6050/3684 6054/6054/3684 +f 6051/6051/3686 6054/6054/3684 6055/6055/3686 +f 6055/6055/3686 6054/6054/3684 6056/6056/3684 +f 6055/6055/3686 6056/6056/3684 6057/6057/3686 +f 6054/6054/3684 6053/6053/3685 6058/6058/3685 +f 6054/6054/3684 6058/6058/3685 6056/6056/3684 +f 6056/6056/3684 6058/6058/3685 5504/5512/3685 +f 6056/6056/3684 5504/5512/3685 5503/5511/3684 +f 6057/6057/3686 6056/6056/3684 5503/5511/3684 +f 6057/6057/3686 5503/5511/3684 5502/5510/3686 +f 5735/5735/3620 5815/5815/3682 6059/6059/3682 +f 5735/5735/3620 6059/6059/3682 6060/6060/3620 +f 5815/5815/3682 5727/5727/3683 6061/6061/3683 +f 5815/5815/3682 6061/6061/3683 6059/6059/3682 +f 6059/6059/3682 6061/6061/3683 6062/6062/3683 +f 6059/6059/3682 6062/6062/3683 6063/6063/3682 +f 6060/6060/3620 6059/6059/3682 6063/6063/3682 +f 6060/6060/3620 6063/6063/3682 6064/6064/3620 +f 6064/6064/3620 6063/6063/3682 6065/6065/3682 +f 6064/6064/3620 6065/6065/3682 6066/6066/3620 +f 6063/6063/3682 6062/6062/3683 6067/6067/3683 +f 6063/6063/3682 6067/6067/3683 6065/6065/3682 +f 6065/6065/3682 6067/6067/3683 5498/5506/3683 +f 6065/6065/3682 5498/5506/3683 5497/5505/3682 +f 6066/6066/3620 6065/6065/3682 5497/5505/3682 +f 6066/6066/3620 5497/5505/3682 5363/5371/3620 +f 5741/5741/3589 5845/5845/3681 6068/6068/3681 +f 5741/5741/3589 6068/6068/3681 6069/6069/3589 +f 5845/5845/3681 5303/5311/3587 6070/6070/3587 +f 5845/5845/3681 6070/6070/3587 6068/6068/3681 +f 6068/6068/3681 6070/6070/3587 6071/6071/3587 +f 6068/6068/3681 6071/6071/3587 6072/6072/3681 +f 6069/6069/3589 6068/6068/3681 6072/6072/3681 +f 6069/6069/3589 6072/6072/3681 6073/6073/3589 +f 6073/6073/3589 6072/6072/3681 6074/6074/3681 +f 6073/6073/3589 6074/6074/3681 6075/6075/3589 +f 6072/6072/3681 6071/6071/3587 6076/6076/3587 +f 6072/6072/3681 6076/6076/3587 6074/6074/3681 +f 6074/6074/3681 6076/6076/3587 5326/5334/3587 +f 6074/6074/3681 5326/5334/3587 5494/5502/3681 +f 6075/6075/3589 6074/6074/3681 5494/5502/3681 +f 6075/6075/3589 5494/5502/3681 5310/5318/3589 +f 5279/5287/3576 5276/5284/3575 6077/6077/3575 +f 5279/5287/3576 6077/6077/3575 6043/6043/3576 +f 5276/5284/3575 5275/5283/3574 6078/6078/3574 +f 5276/5284/3575 6078/6078/3574 6077/6077/3575 +f 6077/6077/3575 6078/6078/3574 6079/6079/3574 +f 6077/6077/3575 6079/6079/3574 6080/6080/3575 +f 6043/6043/3576 6077/6077/3575 6080/6080/3575 +f 6043/6043/3576 6080/6080/3575 6044/6044/3576 +f 6044/6044/3576 6080/6080/3575 6081/6081/3575 +f 6044/6044/3576 6081/6081/3575 6049/6049/3576 +f 6080/6080/3575 6079/6079/3574 6082/6082/3574 +f 6080/6080/3575 6082/6082/3574 6081/6081/3575 +f 6081/6081/3575 6082/6082/3574 5492/5500/3574 +f 6081/6081/3575 5492/5500/3574 5491/5499/3575 +f 6049/6049/3576 6081/6081/3575 5491/5499/3575 +f 6049/6049/3576 5491/5499/3575 5490/5498/3576 +f 5315/5323/3592 5312/5320/3591 6083/6083/3591 +f 5315/5323/3592 6083/6083/3591 6084/6084/3592 +f 5312/5320/3591 5311/5319/3590 6085/6085/3590 +f 5312/5320/3591 6085/6085/3590 6083/6083/3591 +f 6083/6083/3591 6085/6085/3590 6086/6086/3590 +f 6083/6083/3591 6086/6086/3590 6087/6087/3591 +f 6084/6084/3592 6083/6083/3591 6087/6087/3591 +f 6084/6084/3592 6087/6087/3591 6088/6088/3592 +f 6088/6088/3592 6087/6087/3591 6089/6089/3591 +f 6088/6088/3592 6089/6089/3591 6090/6090/3592 +f 6087/6087/3591 6086/6086/3590 6091/6091/3590 +f 6087/6087/3591 6091/6091/3590 6089/6089/3591 +f 6089/6089/3591 6091/6091/3590 5308/5316/3590 +f 6089/6089/3591 5308/5316/3590 5486/5494/3591 +f 6090/6090/3592 6089/6089/3591 5486/5494/3591 +f 6090/6090/3592 5486/5494/3591 5485/5493/3592 +f 5382/5390/3629 5379/5387/3628 6092/6092/3628 +f 5382/5390/3629 6092/6092/3628 6093/6093/3629 +f 5379/5387/3628 5378/5386/3627 6094/6094/3627 +f 5379/5387/3628 6094/6094/3627 6092/6092/3628 +f 6092/6092/3628 6094/6094/3627 6095/6095/3627 +f 6092/6092/3628 6095/6095/3627 6096/6096/3628 +f 6093/6093/3629 6092/6092/3628 6096/6096/3628 +f 6093/6093/3629 6096/6096/3628 6097/6097/3629 +f 6097/6097/3629 6096/6096/3628 6098/6098/3628 +f 6097/6097/3629 6098/6098/3628 6099/6099/3629 +f 6096/6096/3628 6095/6095/3627 6100/6100/3627 +f 6096/6096/3628 6100/6100/3627 6098/6098/3628 +f 6098/6098/3628 6100/6100/3627 5482/5490/3627 +f 6098/6098/3628 5482/5490/3627 5481/5489/3628 +f 6099/6099/3629 6098/6098/3628 5481/5489/3628 +f 6099/6099/3629 5481/5489/3628 5480/5488/3629 +f 5753/5753/3680 5857/5857/3678 6101/6101/3678 +f 5753/5753/3680 6101/6101/3678 6102/6102/3680 +f 5857/5857/3678 5827/5827/3637 6103/6103/3637 +f 5857/5857/3678 6103/6103/3637 6101/6101/3678 +f 6101/6101/3678 6103/6103/3637 6104/6104/3637 +f 6101/6101/3678 6104/6104/3637 6105/6105/3678 +f 6102/6102/3680 6101/6101/3678 6105/6105/3678 +f 6102/6102/3680 6105/6105/3678 6106/6106/3680 +f 6106/6106/3680 6105/6105/3678 6107/6107/3678 +f 6106/6106/3680 6107/6107/3678 6108/6108/3680 +f 6105/6105/3678 6104/6104/3637 6109/6109/3637 +f 6105/6105/3678 6109/6109/3637 6107/6107/3678 +f 6107/6107/3678 6109/6109/3637 5393/5401/3637 +f 6107/6107/3678 5393/5401/3637 5476/5484/3678 +f 6108/6108/3680 6107/6107/3678 5476/5484/3678 +f 6108/6108/3680 5476/5484/3678 5475/5483/3680 +f 5285/5293/3579 5282/5290/3578 6110/6110/3578 +f 5285/5293/3579 6110/6110/3578 6111/6111/3579 +f 5282/5290/3578 5281/5289/3577 6112/6112/3577 +f 5282/5290/3578 6112/6112/3577 6110/6110/3578 +f 6110/6110/3578 6112/6112/3577 6113/6113/3577 +f 6110/6110/3578 6113/6113/3577 6114/6114/3578 +f 6111/6111/3579 6110/6110/3578 6114/6114/3578 +f 6111/6111/3579 6114/6114/3578 6115/6115/3579 +f 6115/6115/3579 6114/6114/3578 6116/6116/3578 +f 6115/6115/3579 6116/6116/3578 6117/6117/3579 +f 6114/6114/3578 6113/6113/3577 6118/6118/3577 +f 6114/6114/3578 6118/6118/3577 6116/6116/3578 +f 6116/6116/3578 6118/6118/3577 5472/5480/3577 +f 6116/6116/3578 5472/5480/3577 5471/5479/3578 +f 6117/6117/3579 6116/6116/3578 5471/5479/3578 +f 6117/6117/3579 5471/5479/3578 5298/5306/3579 +f 5291/5299/3582 5288/5296/3581 6119/6119/3581 +f 5291/5299/3582 6119/6119/3581 6120/6120/3582 +f 5288/5296/3581 5287/5295/3580 6121/6121/3580 +f 5288/5296/3581 6121/6121/3580 6119/6119/3581 +f 6119/6119/3581 6121/6121/3580 6122/6122/3580 +f 6119/6119/3581 6122/6122/3580 6123/6123/3581 +f 6120/6120/3582 6119/6119/3581 6123/6123/3581 +f 6120/6120/3582 6123/6123/3581 6124/6124/3582 +f 6124/6124/3582 6123/6123/3581 6125/6125/3581 +f 6124/6124/3582 6125/6125/3581 6126/6126/3582 +f 6123/6123/3581 6122/6122/3580 6127/6127/3580 +f 6123/6123/3581 6127/6127/3580 6125/6125/3581 +f 6125/6125/3581 6127/6127/3580 5468/5476/3580 +f 6125/6125/3581 5468/5476/3580 5467/5475/3581 +f 6126/6126/3582 6125/6125/3581 5467/5475/3581 +f 6126/6126/3582 5467/5475/3581 5466/5474/3582 +f 5761/5761/3677 5860/5860/3675 6128/6128/3675 +f 5761/5761/3677 6128/6128/3675 6129/6129/3677 +f 5860/5860/3675 5859/5859/3676 6130/6130/3676 +f 5860/5860/3675 6130/6130/3676 6128/6128/3675 +f 6128/6128/3675 6130/6130/3676 6131/6131/3676 +f 6128/6128/3675 6131/6131/3676 6132/6132/3675 +f 6129/6129/3677 6128/6128/3675 6132/6132/3675 +f 6129/6129/3677 6132/6132/3675 6133/6133/3677 +f 6133/6133/3677 6132/6132/3675 6134/6134/3675 +f 6133/6133/3677 6134/6134/3675 6135/6135/3677 +f 6132/6132/3675 6131/6131/3676 6136/6136/3676 +f 6132/6132/3675 6136/6136/3676 6134/6134/3675 +f 6134/6134/3675 6136/6136/3676 5462/5470/3676 +f 6134/6134/3675 5462/5470/3676 5461/5469/3675 +f 6135/6135/3677 6134/6134/3675 5461/5469/3675 +f 6135/6135/3677 5461/5469/3675 5460/5468/3677 +f 5767/5767/3685 5765/5765/3842 6137/6137/3842 +f 5767/5767/3685 6137/6137/3842 6052/6052/3685 +f 5765/5765/3842 5248/5256/3555 5968/5968/3555 +f 5765/5765/3842 5968/5968/3555 6137/6137/3842 +f 6137/6137/3842 5968/5968/3555 5972/5972/3555 +f 6137/6137/3842 5972/5972/3555 6138/6138/3842 +f 6052/6052/3685 6137/6137/3842 6138/6138/3842 +f 6052/6052/3685 6138/6138/3842 6053/6053/3685 +f 6053/6053/3685 6138/6138/3842 6139/6139/3842 +f 6053/6053/3685 6139/6139/3842 6058/6058/3685 +f 6138/6138/3842 5972/5972/3555 5974/5974/3555 +f 6138/6138/3842 5974/5974/3555 6139/6139/3842 +f 6139/6139/3842 5974/5974/3555 5552/5560/3555 +f 6139/6139/3842 5552/5560/3555 5710/5710/3842 +f 6058/6058/3685 6139/6139/3842 5710/5710/3842 +f 6058/6058/3685 5710/5710/3842 5504/5512/3685 +f 5266/5274/3566 5263/5271/3565 6140/6140/3565 +f 5266/5274/3566 6140/6140/3565 6141/6141/3566 +f 5263/5271/3565 5262/5270/3564 6142/6142/3564 +f 5263/5271/3565 6142/6142/3564 6140/6140/3565 +f 6140/6140/3565 6142/6142/3564 6143/6143/3564 +f 6140/6140/3565 6143/6143/3564 6144/6144/3565 +f 6141/6141/3566 6140/6140/3565 6144/6144/3565 +f 6141/6141/3566 6144/6144/3565 6145/6145/3566 +f 6145/6145/3566 6144/6144/3565 6146/6146/3565 +f 6145/6145/3566 6146/6146/3565 6147/6147/3566 +f 6144/6144/3565 6143/6143/3564 6148/6148/3564 +f 6144/6144/3565 6148/6148/3564 6146/6146/3565 +f 6146/6146/3565 6148/6148/3564 5259/5267/3564 +f 6146/6146/3565 5259/5267/3564 5452/5460/3565 +f 6147/6147/3566 6146/6146/3565 5452/5460/3565 +f 6147/6147/3566 5452/5460/3565 5451/5459/3566 +f 5443/5451/3665 5773/5773/3664 6149/6149/3664 +f 5443/5451/3665 6149/6149/3664 6004/6004/3665 +f 5773/5773/3664 5416/5424/3653 6018/6018/3653 +f 5773/5773/3664 6018/6018/3653 6149/6149/3664 +f 6149/6149/3664 6018/6018/3653 6022/6022/3653 +f 6149/6149/3664 6022/6022/3653 6150/6150/3664 +f 6004/6004/3665 6149/6149/3664 6150/6150/3664 +f 6004/6004/3665 6150/6150/3664 6005/6005/3665 +f 6005/6005/3665 6150/6150/3664 6151/6151/3664 +f 6005/6005/3665 6151/6151/3664 6010/6010/3665 +f 6150/6150/3664 6022/6022/3653 6024/6024/3653 +f 6150/6150/3664 6024/6024/3653 6151/6151/3664 +f 6151/6151/3664 6024/6024/3653 5436/5444/3653 +f 6151/6151/3664 5436/5444/3653 5435/5443/3664 +f 6010/6010/3665 6151/6151/3664 5435/5443/3664 +f 6010/6010/3665 5435/5443/3664 5434/5442/3665 +f 5717/5717/3845 5715/5715/3668 6152/6152/3668 +f 5717/5717/3845 6152/6152/3668 6153/6153/3845 +f 5715/5715/3668 5354/5362/3618 6154/6154/3618 +f 5715/5715/3668 6154/6154/3618 6152/6152/3668 +f 6152/6152/3668 6154/6154/3618 6155/6155/3618 +f 6152/6152/3668 6155/6155/3618 6156/6156/3668 +f 6153/6153/3845 6152/6152/3668 6156/6156/3668 +f 6153/6153/3845 6156/6156/3668 6157/6157/3845 +f 6157/6157/3845 6156/6156/3668 6158/6158/3668 +f 6157/6157/3845 6158/6158/3668 6159/6159/3845 +f 6156/6156/3668 6155/6155/3618 6160/6160/3618 +f 6156/6156/3668 6160/6160/3618 6158/6158/3668 +f 6158/6158/3668 6160/6160/3618 5373/5381/3618 +f 6158/6158/3668 5373/5381/3618 5442/5450/3668 +f 6159/6159/3845 6158/6158/3668 5442/5450/3668 +f 6159/6159/3845 5442/5450/3668 5405/5413/3648 +f 5777/5777/3563 5875/5875/3666 6161/6161/3666 +f 5777/5777/3563 6161/6161/3666 6162/6162/3563 +f 5875/5875/3666 5837/5837/3667 6163/6163/3667 +f 5875/5875/3666 6163/6163/3667 6161/6161/3666 +f 6161/6161/3666 6163/6163/3667 6164/6164/3667 +f 6161/6161/3666 6164/6164/3667 6165/6165/3666 +f 6162/6162/3563 6161/6161/3666 6165/6165/3666 +f 6162/6162/3563 6165/6165/3666 6166/6166/3563 +f 6166/6166/3563 6165/6165/3666 6167/6167/3666 +f 6166/6166/3563 6167/6167/3666 6168/6168/3563 +f 6165/6165/3666 6164/6164/3667 6169/6169/3667 +f 6165/6165/3666 6169/6169/3667 6167/6167/3666 +f 6167/6167/3666 6169/6169/3667 5440/5448/3667 +f 6167/6167/3666 5440/5448/3667 5439/5447/3666 +f 6168/6168/3563 6167/6167/3666 5439/5447/3666 +f 6168/6168/3563 5439/5447/3666 5261/5269/3563 +f 5733/5733/3698 5730/5730/3843 6170/6170/3843 +f 5733/5733/3698 6170/6170/3843 5986/5986/3698 +f 5730/5730/3843 5729/5729/3686 6051/6051/3686 +f 5730/5730/3843 6051/6051/3686 6170/6170/3843 +f 6170/6170/3843 6051/6051/3686 6055/6055/3686 +f 6170/6170/3843 6055/6055/3686 6171/6171/3843 +f 5986/5986/3698 6170/6170/3843 6171/6171/3843 +f 5986/5986/3698 6171/6171/3843 5987/5987/3698 +f 5987/5987/3698 6171/6171/3843 6172/6172/3843 +f 5987/5987/3698 6172/6172/3843 5992/5992/3698 +f 6171/6171/3843 6055/6055/3686 6057/6057/3686 +f 6171/6171/3843 6057/6057/3686 6172/6172/3843 +f 6172/6172/3843 6057/6057/3686 5502/5510/3686 +f 6172/6172/3843 5502/5510/3686 5712/5712/3843 +f 5992/5992/3698 6172/6172/3843 5712/5712/3843 +f 5992/5992/3698 5712/5712/3843 5538/5546/3698 +f 5424/5432/3657 5676/5676/3813 6173/6173/3991 +f 5424/5432/3657 6173/6173/3991 5924/5924/3937 +f 5676/5676/3813 5675/5675/3812 6174/6174/3992 +f 5676/5676/3813 6174/6174/3992 6173/6173/3991 +f 6173/6173/3991 6174/6174/3992 6175/6175/3993 +f 6173/6173/3991 6175/6175/3993 6176/6176/3994 +f 5924/5924/3937 6173/6173/3991 6176/6176/3994 +f 5924/5924/3937 6176/6176/3994 5925/5925/3938 +f 5925/5925/3938 6176/6176/3994 6177/6177/3995 +f 5925/5925/3938 6177/6177/3995 5930/5930/3943 +f 6176/6176/3994 6175/6175/3993 6178/6178/3996 +f 6176/6176/3994 6178/6178/3996 6177/6177/3995 +f 6177/6177/3995 6178/6178/3996 5403/5411/3646 +f 6177/6177/3995 5403/5411/3646 5752/5752/3852 +f 5930/5930/3943 6177/6177/3995 5752/5752/3852 +f 5930/5930/3943 5752/5752/3852 5751/5751/3851 +f 5418/5426/3654 5785/5785/3844 6179/6179/3844 +f 5418/5426/3654 6179/6179/3844 6012/6012/3654 +f 5785/5785/3844 5382/5390/3629 6093/6093/3629 +f 5785/5785/3844 6093/6093/3629 6179/6179/3844 +f 6179/6179/3844 6093/6093/3629 6097/6097/3629 +f 6179/6179/3844 6097/6097/3629 6180/6180/3844 +f 6012/6012/3654 6179/6179/3844 6180/6180/3844 +f 6012/6012/3654 6180/6180/3844 6013/6013/3654 +f 6013/6013/3654 6180/6180/3844 6181/6181/3844 +f 6013/6013/3654 6181/6181/3844 6016/6016/3654 +f 6180/6180/3844 6097/6097/3629 6099/6099/3629 +f 6180/6180/3844 6099/6099/3629 6181/6181/3844 +f 6181/6181/3844 6099/6099/3629 5480/5488/3629 +f 6181/6181/3844 5480/5488/3629 5714/5714/3844 +f 6016/6016/3654 6181/6181/3844 5714/5714/3844 +f 6016/6016/3654 5714/5714/3844 5526/5534/3654 +f 5412/5420/3651 5702/5702/3837 6182/6182/3837 +f 5412/5420/3651 6182/6182/3837 6019/6019/3651 +f 5702/5702/3837 5701/5701/3650 6183/6183/3650 +f 5702/5702/3837 6183/6183/3650 6182/6182/3837 +f 6182/6182/3837 6183/6183/3650 6184/6184/3650 +f 6182/6182/3837 6184/6184/3650 6185/6185/3837 +f 6019/6019/3651 6182/6182/3837 6185/6185/3837 +f 6019/6019/3651 6185/6185/3837 6020/6020/3651 +f 6020/6020/3651 6185/6185/3837 6186/6186/3837 +f 6020/6020/3651 6186/6186/3837 6025/6025/3651 +f 6185/6185/3837 6184/6184/3650 6187/6187/3650 +f 6185/6185/3837 6187/6187/3650 6186/6186/3837 +f 6186/6186/3837 6187/6187/3650 5411/5419/3650 +f 6186/6186/3837 5411/5419/3650 5410/5418/3649 +f 6025/6025/3651 6186/6186/3837 5410/5418/3649 +f 6025/6025/3651 5410/5418/3649 5409/5417/3651 +f 5675/5675/3812 5791/5791/3860 6188/6188/3860 +f 5675/5675/3812 6188/6188/3860 6174/6174/3992 +f 5791/5791/3860 5717/5717/3845 6153/6153/3845 +f 5791/5791/3860 6153/6153/3845 6188/6188/3860 +f 6188/6188/3860 6153/6153/3845 6157/6157/3845 +f 6188/6188/3860 6157/6157/3845 6189/6189/3997 +f 6174/6174/3992 6188/6188/3860 6189/6189/3997 +f 6174/6174/3992 6189/6189/3997 6175/6175/3993 +f 6175/6175/3993 6189/6189/3997 6190/6190/3998 +f 6175/6175/3993 6190/6190/3998 6178/6178/3996 +f 6189/6189/3997 6157/6157/3845 6159/6159/3845 +f 6189/6189/3997 6159/6159/3845 6190/6190/3998 +f 6190/6190/3998 6159/6159/3845 5405/5413/3648 +f 6190/6190/3998 5405/5413/3648 5404/5412/3647 +f 6178/6178/3996 6190/6190/3998 5404/5412/3647 +f 6178/6178/3996 5404/5412/3647 5403/5411/3646 +f 5727/5727/3683 5724/5724/3731 6191/6191/3731 +f 5727/5727/3683 6191/6191/3731 6061/6061/3683 +f 5724/5724/3731 5723/5723/3688 6042/6042/3688 +f 5724/5724/3731 6042/6042/3688 6191/6191/3731 +f 6191/6191/3731 6042/6042/3688 6046/6046/3688 +f 6191/6191/3731 6046/6046/3688 6192/6192/3731 +f 6061/6061/3683 6191/6191/3731 6192/6192/3731 +f 6061/6061/3683 6192/6192/3731 6062/6062/3683 +f 6062/6062/3683 6192/6192/3731 6193/6193/3731 +f 6062/6062/3683 6193/6193/3731 6067/6067/3683 +f 6192/6192/3731 6046/6046/3688 6048/6048/3688 +f 6192/6192/3731 6048/6048/3688 6193/6193/3731 +f 6193/6193/3731 6048/6048/3688 5507/5515/3688 +f 6193/6193/3731 5507/5515/3688 5578/5586/3731 +f 6067/6067/3683 6193/6193/3731 5578/5586/3731 +f 6067/6067/3683 5578/5586/3731 5498/5506/3683 +f 5799/5799/3595 5796/5796/3593 6194/6194/3593 +f 5799/5799/3595 6194/6194/3593 6195/6195/3595 +f 5796/5796/3593 5795/5795/3861 6196/6196/3861 +f 5796/5796/3593 6196/6196/3861 6194/6194/3593 +f 6194/6194/3593 6196/6196/3861 6197/6197/3861 +f 6194/6194/3593 6197/6197/3861 6198/6198/3593 +f 6195/6195/3595 6194/6194/3593 6198/6198/3593 +f 6195/6195/3595 6198/6198/3593 6199/6199/3595 +f 6199/6199/3595 6198/6198/3593 6200/6200/3593 +f 6199/6199/3595 6200/6200/3593 6201/6201/3595 +f 6198/6198/3593 6197/6197/3861 6202/6202/3999 +f 6198/6198/3593 6202/6202/3999 6200/6200/3593 +f 6200/6200/3593 6202/6202/3999 5322/5330/3596 +f 6200/6200/3593 5322/5330/3596 5321/5329/3593 +f 6201/6201/3595 6200/6200/3593 5321/5329/3593 +f 6201/6201/3595 5321/5329/3593 5320/5328/3595 +f 5803/5803/3864 5801/5801/3862 6203/6203/4000 +f 5803/5803/3864 6203/6203/4000 6204/6204/4001 +f 5801/5801/3862 5428/5436/3661 5923/5923/3936 +f 5801/5801/3862 5923/5923/3936 6203/6203/4000 +f 6203/6203/4000 5923/5923/3936 5927/5927/3940 +f 6203/6203/4000 5927/5927/3940 6205/6205/4002 +f 6204/6204/4001 6203/6203/4000 6205/6205/4002 +f 6204/6204/4001 6205/6205/4002 6206/6206/4003 +f 6206/6206/4003 6205/6205/4002 6207/6207/4004 +f 6206/6206/4003 6207/6207/4004 6208/6208/4005 +f 6205/6205/4002 5927/5927/3940 5929/5929/3942 +f 6205/6205/4002 5929/5929/3942 6207/6207/4004 +f 6207/6207/4004 5929/5929/3942 5399/5407/3642 +f 6207/6207/4004 5399/5407/3642 5398/5406/3641 +f 6208/6208/4005 6207/6207/4004 5398/5406/3641 +f 6208/6208/4005 5398/5406/3641 5237/5245/3546 +f 5222/5230/3532 5219/5227/3529 6209/6209/4006 +f 5222/5230/3532 6209/6209/4006 6210/6210/4007 +f 5219/5227/3529 5218/5226/3528 6211/6211/4008 +f 5219/5227/3529 6211/6211/4008 6209/6209/4006 +f 6209/6209/4006 6211/6211/4008 6212/6212/4009 +f 6209/6209/4006 6212/6212/4009 6213/6213/4010 +f 6210/6210/4007 6209/6209/4006 6213/6213/4010 +f 6210/6210/4007 6213/6213/4010 6214/6214/4011 +f 6215/6215/4012 6216/6216/4013 6217/6217/4014 +f 6215/6215/4012 6217/6217/4014 6218/6218/3916 +f 6216/6216/4013 6219/6219/4009 6220/6220/4015 +f 6216/6216/4013 6220/6220/4015 6217/6217/4014 +f 6217/6217/4014 6220/6220/4015 6221/6221/3635 +f 6217/6217/4014 6221/6221/3635 6222/6222/3634 +f 6218/6218/3916 6217/6217/4014 6222/6222/3634 +f 6218/6218/3916 6222/6222/3634 6223/6223/4016 +f 5378/5386/3627 5809/5809/3857 6224/6224/3857 +f 5378/5386/3627 6224/6224/3857 6094/6094/3627 +f 5809/5809/3857 5368/5376/3624 6027/6027/3624 +f 5809/5809/3857 6027/6027/3624 6224/6224/3857 +f 6224/6224/3857 6027/6027/3624 6031/6031/3624 +f 6224/6224/3857 6031/6031/3624 6225/6225/3857 +f 6094/6094/3627 6224/6224/3857 6225/6225/3857 +f 6094/6094/3627 6225/6225/3857 6095/6095/3627 +f 6095/6095/3627 6225/6225/3857 6226/6226/3857 +f 6095/6095/3627 6226/6226/3857 6100/6100/3627 +f 6225/6225/3857 6031/6031/3624 6033/6033/3624 +f 6225/6225/3857 6033/6033/3624 6226/6226/3857 +f 6226/6226/3857 6033/6033/3624 5517/5525/3624 +f 6226/6226/3857 5517/5525/3624 5776/5776/3857 +f 6100/6100/3627 6226/6226/3857 5776/5776/3857 +f 6100/6100/3627 5776/5776/3857 5482/5490/3627 +f 5583/5591/3736 5580/5588/3733 6227/6227/4017 +f 5583/5591/3736 6227/6227/4017 6228/6228/4018 +f 5580/5588/3733 5579/5587/3732 6229/6229/4019 +f 5580/5588/3733 6229/6229/4019 6227/6227/4017 +f 6227/6227/4017 6229/6229/4019 6230/6230/4020 +f 6227/6227/4017 6230/6230/4020 6231/6231/4021 +f 6228/6228/4018 6227/6227/4017 6231/6231/4021 +f 6228/6228/4018 6231/6231/4021 6232/6232/4022 +f 6232/6232/4022 6231/6231/4021 6233/6233/4023 +f 6232/6232/4022 6233/6233/4023 6234/6234/4024 +f 6231/6231/4021 6230/6230/4020 6235/6235/4025 +f 6231/6231/4021 6235/6235/4025 6233/6233/4023 +f 6233/6233/4023 6235/6235/4025 5349/5357/3615 +f 6233/6233/4023 5349/5357/3615 5348/5356/3614 +f 6234/6234/4024 6233/6233/4023 5348/5356/3614 +f 6234/6234/4024 5348/5356/3614 5347/5355/3613 +f 5354/5362/3618 5351/5359/3617 6236/6236/3617 +f 5354/5362/3618 6236/6236/3617 6154/6154/3618 +f 5351/5359/3617 5350/5358/3616 6237/6237/3616 +f 5351/5359/3617 6237/6237/3616 6236/6236/3617 +f 6236/6236/3617 6237/6237/3616 6238/6238/3616 +f 6236/6236/3617 6238/6238/3616 6239/6239/3617 +f 6154/6154/3618 6236/6236/3617 6239/6239/3617 +f 6154/6154/3618 6239/6239/3617 6155/6155/3618 +f 6155/6155/3618 6239/6239/3617 6240/6240/3617 +f 6155/6155/3618 6240/6240/3617 6160/6160/3618 +f 6239/6239/3617 6238/6238/3616 6241/6241/3616 +f 6239/6239/3617 6241/6241/3616 6240/6240/3617 +f 6240/6240/3617 6241/6241/3616 5375/5383/3616 +f 6240/6240/3617 5375/5383/3616 5374/5382/3617 +f 6160/6160/3618 6240/6240/3617 5374/5382/3617 +f 6160/6160/3618 5374/5382/3617 5373/5381/3618 +f 5364/5372/3621 5739/5739/3622 6242/6242/3622 +f 5364/5372/3621 6242/6242/3622 6028/6028/3621 +f 5736/5736/3619 5735/5735/3620 6060/6060/3620 +f 5736/5736/3619 6060/6060/3620 6243/6243/3619 +f 6243/6243/3619 6060/6060/3620 6064/6064/3620 +f 6243/6243/3619 6064/6064/3620 6244/6244/3619 +f 6028/6028/3621 6242/6242/3622 6245/6245/3622 +f 6028/6028/3621 6245/6245/3622 6029/6029/3621 +f 6029/6029/3621 6245/6245/3622 6246/6246/3622 +f 6029/6029/3621 6246/6246/3622 6034/6034/3621 +f 6244/6244/3619 6064/6064/3620 6066/6066/3620 +f 6244/6244/3619 6066/6066/3620 6247/6247/3619 +f 6247/6247/3619 6066/6066/3620 5363/5371/3620 +f 6247/6247/3619 5363/5371/3620 5362/5370/3619 +f 6034/6034/3621 6246/6246/3622 5361/5369/3622 +f 6034/6034/3621 5361/5369/3622 5360/5368/3621 +f 5795/5795/3861 5817/5817/3872 6248/6248/3872 +f 5795/5795/3861 6248/6248/3872 6196/6196/3861 +f 5817/5817/3872 5583/5591/3736 6228/6228/4018 +f 5817/5817/3872 6228/6228/4018 6248/6248/3872 +f 6248/6248/3872 6228/6228/4018 6232/6232/4022 +f 6248/6248/3872 6232/6232/4022 6249/6249/4026 +f 6196/6196/3861 6248/6248/3872 6249/6249/4026 +f 6196/6196/3861 6249/6249/4026 6197/6197/3861 +f 6197/6197/3861 6249/6249/4026 6250/6250/4027 +f 6197/6197/3861 6250/6250/4027 6202/6202/3999 +f 6249/6249/4026 6232/6232/4022 6234/6234/4024 +f 6249/6249/4026 6234/6234/4024 6250/6250/4027 +f 6250/6250/4027 6234/6234/4024 5347/5355/3613 +f 6250/6250/4027 5347/5355/3613 5814/5814/3871 +f 6202/6202/3999 6250/6250/4027 5814/5814/3871 +f 6202/6202/3999 5814/5814/3871 5322/5330/3596 +f 5350/5358/3616 5819/5819/3869 6251/6251/3869 +f 5350/5358/3616 6251/6251/3869 6237/6237/3616 +f 5819/5819/3869 5291/5299/3582 6120/6120/3582 +f 5819/5819/3869 6120/6120/3582 6251/6251/3869 +f 6251/6251/3869 6120/6120/3582 6124/6124/3582 +f 6251/6251/3869 6124/6124/3582 6252/6252/3869 +f 6237/6237/3616 6251/6251/3869 6252/6252/3869 +f 6237/6237/3616 6252/6252/3869 6238/6238/3616 +f 6238/6238/3616 6252/6252/3869 6253/6253/3869 +f 6238/6238/3616 6253/6253/3869 6241/6241/3616 +f 6252/6252/3869 6124/6124/3582 6126/6126/3582 +f 6252/6252/3869 6126/6126/3582 6253/6253/3869 +f 6253/6253/3869 6126/6126/3582 5466/5474/3582 +f 6253/6253/3869 5466/5474/3582 5812/5812/3869 +f 6241/6241/3616 6253/6253/3869 5812/5812/3869 +f 6241/6241/3616 5812/5812/3869 5375/5383/3616 +f 5579/5587/3732 5821/5821/3873 6254/6254/4028 +f 5579/5587/3732 6254/6254/4028 6229/6229/4019 +f 5821/5821/3873 5673/5673/3810 5914/5914/3927 +f 5821/5821/3873 5914/5914/3927 6254/6254/4028 +f 6254/6254/4028 5914/5914/3927 5918/5918/3931 +f 6254/6254/4028 5918/5918/3931 6255/6255/4029 +f 6229/6229/4019 6254/6254/4028 6255/6255/4029 +f 6229/6229/4019 6255/6255/4029 6230/6230/4020 +f 6230/6230/4020 6255/6255/4029 6256/6256/4030 +f 6230/6230/4020 6256/6256/4030 6235/6235/4025 +f 6255/6255/4029 5918/5918/3931 5920/5920/3933 +f 6255/6255/4029 5920/5920/3933 6256/6256/4030 +f 6256/6256/4030 5920/5920/3933 5341/5349/3607 +f 6256/6256/4030 5341/5349/3607 5377/5385/3626 +f 6235/6235/4025 6256/6256/4030 5377/5385/3626 +f 6235/6235/4025 5377/5385/3626 5349/5357/3615 +f 5827/5827/3637 5824/5824/3638 6257/6257/3638 +f 5827/5827/3637 6257/6257/3638 6103/6103/3637 +f 5824/5824/3638 5823/5823/3592 6258/6258/3592 +f 5824/5824/3638 6258/6258/3592 6257/6257/3638 +f 6257/6257/3638 6258/6258/3592 6259/6259/3592 +f 6257/6257/3638 6259/6259/3592 6260/6260/3638 +f 6103/6103/3637 6257/6257/3638 6260/6260/3638 +f 6103/6103/3637 6260/6260/3638 6104/6104/3637 +f 6104/6104/3637 6260/6260/3638 6261/6261/3638 +f 6104/6104/3637 6261/6261/3638 6109/6109/3637 +f 6260/6260/3638 6259/6259/3592 6262/6262/3592 +f 6260/6260/3638 6262/6262/3592 6261/6261/3638 +f 6261/6261/3638 6262/6262/3592 5395/5403/3592 +f 6261/6261/3638 5395/5403/3592 5394/5402/3638 +f 6109/6109/3637 6261/6261/3638 5394/5402/3638 +f 6109/6109/3637 5394/5402/3638 5393/5401/3637 +f 5565/5573/3721 5831/5831/3877 6263/6263/4031 +f 5565/5573/3721 6263/6263/4031 6264/6264/4032 +f 5829/5829/3875 5803/5803/3864 6204/6204/4001 +f 5829/5829/3875 6204/6204/4001 6265/6265/4033 +f 6265/6265/4033 6204/6204/4001 6206/6206/4003 +f 6265/6265/4033 6206/6206/4003 6266/6266/4034 +f 6267/6267/4032 6268/6268/4035 6269/6269/4036 +f 6267/6267/4032 6269/6269/4036 6270/6270/4037 +f 6271/6271/4038 6272/6272/4039 6273/6273/4040 +f 6271/6271/4038 6273/6273/4040 6274/6274/4041 +f 6266/6266/4034 6206/6206/4003 6208/6208/4005 +f 6266/6266/4034 6208/6208/4005 6275/6275/4042 +f 6275/6275/4042 6208/6208/4005 5237/5245/3546 +f 6275/6275/4042 5237/5245/3546 5236/5244/3545 +f 6276/6276/4041 6277/6277/4043 5235/5243/3544 +f 6276/6276/4041 5235/5243/3544 5234/5242/3543 +f 5833/5833/3598 5843/5843/3597 6278/6278/3597 +f 5833/5833/3598 6278/6278/3597 6279/6279/3598 +f 5843/5843/3597 5799/5799/3595 6195/6195/3595 +f 5843/5843/3597 6195/6195/3595 6278/6278/3597 +f 6278/6278/3597 6195/6195/3595 6199/6199/3595 +f 6278/6278/3597 6199/6199/3595 6280/6280/3597 +f 6279/6279/3598 6278/6278/3597 6280/6280/3597 +f 6279/6279/3598 6280/6280/3597 6281/6281/3598 +f 6281/6281/3598 6280/6280/3597 6282/6282/3597 +f 6281/6281/3598 6282/6282/3597 6283/6283/3598 +f 6280/6280/3597 6199/6199/3595 6201/6201/3595 +f 6280/6280/3597 6201/6201/3595 6282/6282/3597 +f 6282/6282/3597 6201/6201/3595 5320/5328/3595 +f 6282/6282/3597 5320/5328/3595 5332/5340/3597 +f 6283/6283/3598 6282/6282/3597 5332/5340/3597 +f 6283/6283/3598 5332/5340/3597 5331/5339/3598 +f 5303/5311/3587 5300/5308/3586 6284/6284/3586 +f 5303/5311/3587 6284/6284/3586 6070/6070/3587 +f 5300/5308/3586 5299/5307/3585 6285/6285/3585 +f 5300/5308/3586 6285/6285/3585 6284/6284/3586 +f 6284/6284/3586 6285/6285/3585 6286/6286/3585 +f 6284/6284/3586 6286/6286/3585 6287/6287/3586 +f 6070/6070/3587 6284/6284/3586 6287/6287/3586 +f 6070/6070/3587 6287/6287/3586 6071/6071/3587 +f 6071/6071/3587 6287/6287/3586 6288/6288/3586 +f 6071/6071/3587 6288/6288/3586 6076/6076/3587 +f 6287/6287/3586 6286/6286/3585 6289/6289/3585 +f 6287/6287/3586 6289/6289/3585 6288/6288/3586 +f 6288/6288/3586 6289/6289/3585 5328/5336/3585 +f 6288/6288/3586 5328/5336/3585 5327/5335/3586 +f 6076/6076/3587 6288/6288/3586 5327/5335/3586 +f 6076/6076/3587 5327/5335/3586 5326/5334/3587 +f 5837/5837/3667 5834/5834/3848 6290/6290/3848 +f 5837/5837/3667 6290/6290/3848 6163/6163/3667 +f 5834/5834/3848 5833/5833/3598 6279/6279/3598 +f 5834/5834/3848 6279/6279/3598 6290/6290/3848 +f 6290/6290/3848 6279/6279/3598 6281/6281/3598 +f 6290/6290/3848 6281/6281/3598 6291/6291/3848 +f 6163/6163/3667 6290/6290/3848 6291/6291/3848 +f 6163/6163/3667 6291/6291/3848 6164/6164/3667 +f 6164/6164/3667 6291/6291/3848 6292/6292/3848 +f 6164/6164/3667 6292/6292/3848 6169/6169/3667 +f 6291/6291/3848 6281/6281/3598 6283/6283/3598 +f 6291/6291/3848 6283/6283/3598 6292/6292/3848 +f 6292/6292/3848 6283/6283/3598 5331/5339/3598 +f 6292/6292/3848 5331/5339/3598 5748/5748/3848 +f 6169/6169/3667 6292/6292/3848 5748/5748/3848 +f 6169/6169/3667 5748/5748/3848 5440/5448/3667 +f 5311/5319/3590 5742/5742/3588 6293/6293/3588 +f 5311/5319/3590 6293/6293/3588 6085/6085/3590 +f 5742/5742/3588 5741/5741/3589 6069/6069/3589 +f 5742/5742/3588 6069/6069/3589 6293/6293/3588 +f 6293/6293/3588 6069/6069/3589 6073/6073/3589 +f 6293/6293/3588 6073/6073/3589 6294/6294/3588 +f 6085/6085/3590 6293/6293/3588 6294/6294/3588 +f 6085/6085/3590 6294/6294/3588 6086/6086/3590 +f 6086/6086/3590 6294/6294/3588 6295/6295/3588 +f 6086/6086/3590 6295/6295/3588 6091/6091/3590 +f 6294/6294/3588 6073/6073/3589 6075/6075/3589 +f 6294/6294/3588 6075/6075/3589 6295/6295/3588 +f 6295/6295/3588 6075/6075/3589 5310/5318/3589 +f 6295/6295/3588 5310/5318/3589 5309/5317/3588 +f 6091/6091/3590 6295/6295/3588 5309/5317/3588 +f 6091/6091/3590 5309/5317/3588 5308/5316/3590 +f 5849/5849/3676 5847/5847/3879 6296/6296/3879 +f 5849/5849/3676 6296/6296/3879 6297/6297/3676 +f 5847/5847/3879 5266/5274/3566 6141/6141/3566 +f 5847/5847/3879 6141/6141/3566 6296/6296/3879 +f 6296/6296/3879 6141/6141/3566 6145/6145/3566 +f 6296/6296/3879 6145/6145/3566 6298/6298/3879 +f 6297/6297/3676 6296/6296/3879 6298/6298/3879 +f 6297/6297/3676 6298/6298/3879 6299/6299/3676 +f 6299/6299/3676 6298/6298/3879 6300/6300/3879 +f 6299/6299/3676 6300/6300/3879 6301/6301/3676 +f 6298/6298/3879 6145/6145/3566 6147/6147/3566 +f 6298/6298/3879 6147/6147/3566 6300/6300/3879 +f 6300/6300/3879 6147/6147/3566 5451/5459/3566 +f 6300/6300/3879 5451/5459/3566 5842/5842/3879 +f 6301/6301/3676 6300/6300/3879 5842/5842/3879 +f 6301/6301/3676 5842/5842/3879 5841/5841/3676 +f 5299/5307/3585 5720/5720/3846 6302/6302/3846 +f 5299/5307/3585 6302/6302/3846 6285/6285/3585 +f 5720/5720/3846 5719/5719/3690 6036/6036/3690 +f 5720/5720/3846 6036/6036/3690 6302/6302/3846 +f 6302/6302/3846 6036/6036/3690 6038/6038/3690 +f 6302/6302/3846 6038/6038/3690 6303/6303/3846 +f 6285/6285/3585 6302/6302/3846 6303/6303/3846 +f 6285/6285/3585 6303/6303/3846 6286/6286/3585 +f 6286/6286/3585 6303/6303/3846 6304/6304/3846 +f 6286/6286/3585 6304/6304/3846 6289/6289/3585 +f 6303/6303/3846 6038/6038/3690 6040/6040/3690 +f 6303/6303/3846 6040/6040/3690 6304/6304/3846 +f 6304/6304/3846 6040/6040/3690 5512/5520/3690 +f 6304/6304/3846 5512/5520/3690 5760/5760/3846 +f 6289/6289/3585 6304/6304/3846 5760/5760/3846 +f 6289/6289/3585 5760/5760/3846 5328/5336/3585 +f 5853/5853/3584 5867/5867/3583 6305/6305/3583 +f 5853/5853/3584 6305/6305/3583 6306/6306/3584 +f 5867/5867/3583 5285/5293/3579 6111/6111/3579 +f 5867/5867/3583 6111/6111/3579 6305/6305/3583 +f 6305/6305/3583 6111/6111/3579 6115/6115/3579 +f 6305/6305/3583 6115/6115/3579 6307/6307/3583 +f 6306/6306/3584 6305/6305/3583 6307/6307/3583 +f 6306/6306/3584 6307/6307/3583 6308/6308/3584 +f 6308/6308/3584 6307/6307/3583 6309/6309/3583 +f 6308/6308/3584 6309/6309/3583 6310/6310/3584 +f 6307/6307/3583 6115/6115/3579 6117/6117/3579 +f 6307/6307/3583 6117/6117/3579 6309/6309/3583 +f 6309/6309/3583 6117/6117/3579 5298/5306/3579 +f 6309/6309/3583 5298/5306/3579 5297/5305/3583 +f 6310/6310/3584 6309/6309/3583 5297/5305/3583 +f 6310/6310/3584 5297/5305/3583 5296/5304/3584 +f 5287/5295/3580 5754/5754/3853 6311/6311/3853 +f 5287/5295/3580 6311/6311/3853 6121/6121/3580 +f 5754/5754/3853 5753/5753/3680 6102/6102/3680 +f 5754/5754/3853 6102/6102/3680 6311/6311/3853 +f 6311/6311/3853 6102/6102/3680 6106/6106/3680 +f 6311/6311/3853 6106/6106/3680 6312/6312/3853 +f 6121/6121/3580 6311/6311/3853 6312/6312/3853 +f 6121/6121/3580 6312/6312/3853 6122/6122/3580 +f 6122/6122/3580 6312/6312/3853 6313/6313/3853 +f 6122/6122/3580 6313/6313/3853 6127/6127/3580 +f 6312/6312/3853 6106/6106/3680 6108/6108/3680 +f 6312/6312/3853 6108/6108/3680 6313/6313/3853 +f 6313/6313/3853 6108/6108/3680 5475/5483/3680 +f 6313/6313/3853 5475/5483/3680 5758/5758/3853 +f 6127/6127/3580 6313/6313/3853 5758/5758/3853 +f 6127/6127/3580 5758/5758/3853 5468/5476/3580 +f 5281/5289/3577 5762/5762/3847 6314/6314/3847 +f 5281/5289/3577 6314/6314/3847 6112/6112/3577 +f 5762/5762/3847 5761/5761/3677 6129/6129/3677 +f 5762/5762/3847 6129/6129/3677 6314/6314/3847 +f 6314/6314/3847 6129/6129/3677 6133/6133/3677 +f 6314/6314/3847 6133/6133/3677 6315/6315/3847 +f 6112/6112/3577 6314/6314/3847 6315/6315/3847 +f 6112/6112/3577 6315/6315/3847 6113/6113/3577 +f 6113/6113/3577 6315/6315/3847 6316/6316/3847 +f 6113/6113/3577 6316/6316/3847 6118/6118/3577 +f 6315/6315/3847 6133/6133/3677 6135/6135/3677 +f 6315/6315/3847 6135/6135/3677 6316/6316/3847 +f 6316/6316/3847 6135/6135/3677 5460/5468/3677 +f 6316/6316/3847 5460/5468/3677 5746/5746/3847 +f 6118/6118/3577 6316/6316/3847 5746/5746/3847 +f 6118/6118/3577 5746/5746/3847 5472/5480/3577 +f 5863/5863/3880 5881/5881/3894 6317/6317/4044 +f 5863/5863/3880 6317/6317/4044 6318/6318/4045 +f 5881/5881/3894 5873/5873/3888 6319/6319/4046 +f 5881/5881/3894 6319/6319/4046 6317/6317/4044 +f 6317/6317/4044 6319/6319/4046 5539/5547/3699 +f 6317/6317/4044 5539/5547/3699 6320/6320/4047 +f 6318/6318/4045 6317/6317/4044 6320/6320/4047 +f 6318/6318/4045 6320/6320/4047 6321/6321/4048 +f 3262/3700/2074 3259/3697/2071 6322/6322/4049 +f 3262/3700/2074 6322/6322/4049 5271/5279/3570 +f 3258/3696/2070 5696/5696/3832 6322/6322/4049 +f 3258/3696/2070 6322/6322/4049 3259/3697/2071 +f 5700/5700/3836 6323/6323/4050 6322/6322/4049 +f 5700/5700/3836 6322/6322/4049 5696/5696/3832 +f 5546/5554/3706 5545/5553/3705 6322/6322/4049 +f 5546/5554/3706 6322/6322/4049 6323/6323/4050 +f 5272/5280/3571 5271/5279/3570 6322/6322/4049 +f 5272/5280/3571 6322/6322/4049 5545/5553/3705 +f 5275/5283/3574 5854/5854/3773 6324/6324/3773 +f 5275/5283/3574 6324/6324/3773 6078/6078/3574 +f 5854/5854/3773 5853/5853/3584 6306/6306/3584 +f 5854/5854/3773 6306/6306/3584 6324/6324/3773 +f 6324/6324/3773 6306/6306/3584 6308/6308/3584 +f 6324/6324/3773 6308/6308/3584 6325/6325/3773 +f 6078/6078/3574 6324/6324/3773 6325/6325/3773 +f 6078/6078/3574 6325/6325/3773 6079/6079/3574 +f 6079/6079/3574 6325/6325/3773 6326/6326/3773 +f 6079/6079/3574 6326/6326/3773 6082/6082/3574 +f 6325/6325/3773 6308/6308/3584 6310/6310/3584 +f 6325/6325/3773 6310/6310/3584 6326/6326/3773 +f 6326/6326/3773 6310/6310/3584 5296/5304/3584 +f 6326/6326/3773 5296/5304/3584 5624/5628/3773 +f 6082/6082/3574 6326/6326/3773 5624/5628/3773 +f 6082/6082/3574 5624/5628/3773 5492/5500/3574 +f 5869/5869/3884 5877/5877/3890 6327/6327/4051 +f 5869/5869/3884 6327/6327/4051 6328/6328/4052 +f 5877/5877/3890 5663/5663/3800 5896/5896/3909 +f 5877/5877/3890 5896/5896/3909 6327/6327/4051 +f 6327/6327/4051 5896/5896/3909 5900/5900/3913 +f 6327/6327/4051 5900/5900/3913 6329/6329/4053 +f 6328/6328/4052 6327/6327/4051 6329/6329/4053 +f 6328/6328/4052 6329/6329/4053 5543/5551/3703 +f 5543/5551/3703 6329/6329/4053 6330/6330/4054 +f 5543/5551/3703 6330/6330/4054 5544/5552/3704 +f 6329/6329/4053 5900/5900/3913 5902/5902/3915 +f 6329/6329/4053 5902/5902/3915 6330/6330/4054 +f 6330/6330/4054 5902/5902/3915 5274/5282/3573 +f 6330/6330/4054 5274/5282/3573 5273/5281/3572 +f 5544/5552/3704 6330/6330/4054 5273/5281/3572 +f 5544/5552/3704 5273/5281/3572 5272/5280/3571 +f 5262/5270/3564 5778/5778/3562 6331/6331/3562 +f 5262/5270/3564 6331/6331/3562 6142/6142/3564 +f 5778/5778/3562 5777/5777/3563 6162/6162/3563 +f 5778/5778/3562 6162/6162/3563 6331/6331/3562 +f 6331/6331/3562 6162/6162/3563 6166/6166/3563 +f 6331/6331/3562 6166/6166/3563 6332/6332/3562 +f 6142/6142/3564 6331/6331/3562 6332/6332/3562 +f 6142/6142/3564 6332/6332/3562 6143/6143/3564 +f 6143/6143/3564 6332/6332/3562 6333/6333/3562 +f 6143/6143/3564 6333/6333/3562 6148/6148/3564 +f 6332/6332/3562 6166/6166/3563 6168/6168/3563 +f 6332/6332/3562 6168/6168/3563 6333/6333/3562 +f 6333/6333/3562 6168/6168/3563 5261/5269/3563 +f 6333/6333/3562 5261/5269/3563 5260/5268/3562 +f 6148/6148/3564 6333/6333/3562 5260/5268/3562 +f 6148/6148/3564 5260/5268/3562 5259/5267/3564 +f 5873/5873/3888 5870/5870/3885 6334/6334/4055 +f 5873/5873/3888 6334/6334/4055 6319/6319/4046 +f 5870/5870/3885 5869/5869/3884 6328/6328/4052 +f 5870/5870/3885 6328/6328/4052 6334/6334/4055 +f 6334/6334/4055 6328/6328/4052 5543/5551/3703 +f 6334/6334/4055 5543/5551/3703 5540/5548/3700 +f 6319/6319/4046 6334/6334/4055 5540/5548/3700 +f 6319/6319/4046 5540/5548/3700 5539/5547/3699 +f 6321/6321/4048 6320/6320/4047 6335/6335/4056 +f 6321/6321/4048 6335/6335/4056 6336/6336/4057 +f 5539/5547/3699 5542/5550/3702 6335/6335/4056 +f 5539/5547/3699 6335/6335/4056 6320/6320/4047 +f 5548/5556/3708 6337/6337/4058 6335/6335/4056 +f 5548/5556/3708 6335/6335/4056 5542/5550/3702 +f 5698/5698/3834 5697/5697/3833 6335/6335/4056 +f 5698/5698/3834 6335/6335/4056 6337/6337/4058 +f 5682/5682/3819 6336/6336/4057 6335/6335/4056 +f 5682/5682/3819 6335/6335/4056 5697/5697/3833 +f 5250/5258/3556 5706/5706/3839 6338/6338/4059 +f 5250/5258/3556 6338/6338/4059 5977/5977/3977 +f 5706/5706/3839 5705/5705/3838 5994/5994/3985 +f 5706/5706/3839 5994/5994/3985 6338/6338/4059 +f 6338/6338/4059 5994/5994/3985 5998/5998/3987 +f 6338/6338/4059 5998/5998/3987 6339/6339/4060 +f 5977/5977/3977 6338/6338/4059 6339/6339/4060 +f 5977/5977/3977 6339/6339/4060 5978/5978/3978 +f 5907/5907/3920 5979/5979/3979 6340/6340/4061 +f 5907/5907/3920 6340/6340/4061 5912/5912/3925 +f 5978/5978/3978 6341/6341/4062 6340/6340/4061 +f 5978/5978/3978 6340/6340/4061 5979/5979/3979 +f 6342/6342/4063 6343/6343/4064 6340/6340/4061 +f 6342/6342/4063 6340/6340/4061 6341/6341/4062 +f 5692/5692/3828 5691/5691/3827 6340/6340/4061 +f 5692/5692/3828 6340/6340/4061 6343/6343/4064 +f 5622/5626/3772 5912/5912/3925 6340/6340/4061 +f 5622/5626/3772 6340/6340/4061 5691/5691/3827 +f 5244/5252/3553 5864/5864/3881 6344/6344/4065 +f 5244/5252/3553 6344/6344/4065 5969/5969/3973 +f 5864/5864/3881 5863/5863/3880 6318/6318/4045 +f 5864/5864/3881 6318/6318/4045 6344/6344/4065 +f 6344/6344/4065 6318/6318/4045 6321/6321/4048 +f 6344/6344/4065 6321/6321/4048 6345/6345/4066 +f 5969/5969/3973 6344/6344/4065 6345/6345/4066 +f 5969/5969/3973 6345/6345/4066 5970/5970/3974 +f 5970/5970/3974 6345/6345/4066 6346/6346/4067 +f 5970/5970/3974 6346/6346/4067 5975/5975/3975 +f 6345/6345/4066 6321/6321/4048 6336/6336/4057 +f 6345/6345/4066 6336/6336/4057 6346/6346/4067 +f 6346/6346/4067 6336/6336/4057 5682/5682/3819 +f 6346/6346/4067 5682/5682/3819 5681/5681/3818 +f 5975/5975/3975 6346/6346/4067 5681/5681/3818 +f 5975/5975/3975 5681/5681/3818 5554/5562/3710 +f 5883/5883/3896 5887/5887/3900 6347/6347/4068 +f 5883/5883/3896 6347/6347/4068 6348/6348/4069 +f 5887/5887/3900 5573/5581/3728 5943/5943/3955 +f 5887/5887/3900 5943/5943/3955 6347/6347/4068 +f 6347/6347/4068 5943/5943/3955 5938/5938/3950 +f 6347/6347/4068 5938/5938/3950 6349/6349/4070 +f 6348/6348/4069 6347/6347/4068 6349/6349/4070 +f 6348/6348/4069 6349/6349/4070 6350/6350/4071 +f 6350/6350/4071 6349/6349/4070 6351/6351/4072 +f 6350/6350/4071 6351/6351/4072 6352/6352/4073 +f 6349/6349/4070 5938/5938/3950 5937/5937/3949 +f 6349/6349/4070 5937/5937/3949 6351/6351/4072 +f 6353/6353/4074 5935/5935/3947 5243/5251/3552 +f 6353/6353/4074 5243/5251/3552 5242/5250/3551 +f 6354/6354/4075 6353/6353/4074 5242/5250/3551 +f 6354/6354/4075 5242/5250/3551 5241/5249/3550 +f 5234/5242/3543 5884/5884/3897 6355/6355/4076 +f 5234/5242/3543 6355/6355/4076 6276/6276/4041 +f 5884/5884/3897 5883/5883/3896 6348/6348/4069 +f 5884/5884/3897 6348/6348/4069 6355/6355/4076 +f 6355/6355/4076 6348/6348/4069 6350/6350/4071 +f 6355/6355/4076 6350/6350/4071 6356/6356/4077 +f 6276/6276/4041 6355/6355/4076 6356/6356/4077 +f 6276/6276/4041 6356/6356/4077 6270/6270/4037 +f 6270/6270/4037 6356/6356/4077 6357/6357/4078 +f 6270/6270/4037 6357/6357/4078 6267/6267/4032 +f 6356/6356/4077 6350/6350/4071 6352/6352/4073 +f 6356/6356/4077 6352/6352/4073 6357/6357/4078 +f 6358/6358/4078 6354/6354/4075 5241/5249/3550 +f 6358/6358/4078 5241/5249/3550 5566/5574/3722 +f 6264/6264/4032 6358/6358/4078 5566/5574/3722 +f 6264/6264/4032 5566/5574/3722 5565/5573/3721 +f 5889/5889/3902 5893/5893/3906 6359/6359/4079 +f 5889/5889/3902 6359/6359/4079 6360/6360/4080 +f 5893/5893/3906 5687/5687/3823 5945/5945/3957 +f 5893/5893/3906 5945/5945/3957 6359/6359/4079 +f 6359/6359/4079 5945/5945/3957 5949/5949/3961 +f 6359/6359/4079 5949/5949/3961 6361/6361/4081 +f 6360/6360/4080 6359/6359/4079 6361/6361/4081 +f 6360/6360/4080 6361/6361/4081 6362/6362/4082 +f 6362/6362/4082 6361/6361/4081 6363/6363/4083 +f 6362/6362/4082 6363/6363/4083 6364/6364/4084 +f 6361/6361/4081 5949/5949/3961 5951/5951/3963 +f 6361/6361/4081 5951/5951/3963 6363/6363/4083 +f 6365/6365/4083 5957/5957/3963 5958/5958/3539 +f 6365/6365/4083 5958/5958/3539 6366/6366/3538 +f 6367/6367/4085 6365/6365/4083 6366/6366/3538 +f 6367/6367/4085 6366/6366/3538 6368/6368/3537 +f 5218/5226/3528 5890/5890/3903 6369/6369/4086 +f 5218/5226/3528 6369/6369/4086 6211/6211/4008 +f 5890/5890/3903 5889/5889/3902 6360/6360/4080 +f 5890/5890/3903 6360/6360/4080 6369/6369/4086 +f 6369/6369/4086 6360/6360/4080 6362/6362/4082 +f 6369/6369/4086 6362/6362/4082 6370/6370/4087 +f 6211/6211/4008 6369/6369/4086 6370/6370/4087 +f 6211/6211/4008 6370/6370/4087 6212/6212/4009 +f 6219/6219/4009 6371/6371/4087 6372/6372/4088 +f 6219/6219/4009 6372/6372/4088 6220/6220/4015 +f 6371/6371/4087 6373/6373/4089 6367/6367/4085 +f 6371/6371/4087 6367/6367/4085 6372/6372/4088 +f 6372/6372/4088 6367/6367/4085 6368/6368/3537 +f 6372/6372/4088 6368/6368/3537 6374/6374/4090 +f 6220/6220/4015 6372/6372/4088 6374/6374/4090 +f 6220/6220/4015 6374/6374/4090 6221/6221/3635 +f 4489/4823/3165 4874/4882/3231 6375/6375/4091 +f 4489/4823/3165 6375/6375/4091 5226/5234/3536 +f 4874/4882/3231 4878/4886/3234 5385/5393/3631 +f 4874/4882/3231 5385/5393/3631 6375/6375/4091 +f 6375/6375/4091 5385/5393/3631 5389/5397/3635 +f 6375/6375/4091 5389/5397/3635 6376/6376/4090 +f 5226/5234/3536 6375/6375/4091 6376/6376/4090 +f 5226/5234/3536 6376/6376/4090 5227/5235/3537 +f 5978/5978/3978 6339/6339/4060 6377/6377/4092 +f 5978/5978/3978 6377/6377/4092 6341/6341/4062 +f 5998/5998/3987 6000/6000/3989 6377/6377/4092 +f 5998/5998/3987 6377/6377/4092 6339/6339/4060 +f 5531/5539/3695 5983/5983/3983 6377/6377/4092 +f 5531/5539/3695 6377/6377/4092 6000/6000/3989 +f 5982/5982/3982 6378/6378/4093 6377/6377/4092 +f 5982/5982/3982 6377/6377/4092 5983/5983/3983 +f 6342/6342/4063 6341/6341/4062 6377/6377/4092 +f 6342/6342/4063 6377/6377/4092 6378/6378/4093 +f 6379/6379/4094 6380/6380/4095 6381/6381/4096 +f 6379/6379/4094 6381/6381/4096 6382/6382/4097 +f 6383/6383/4098 6384/6384/4099 6385/6385/4100 +f 6383/6383/4098 6385/6385/4100 6386/6386/4101 +f 6381/6381/4096 6387/6387/4100 6388/6388/3836 +f 6381/6381/4096 6388/6388/3836 6389/6389/4102 +f 6382/6382/4097 6381/6381/4096 6389/6389/4102 +f 6382/6382/4097 6389/6389/4102 6390/6390/3834 +f 5692/5692/3828 6343/6343/4064 6391/6391/4103 +f 5692/5692/3828 6391/6391/4103 6392/6392/4104 +f 6343/6343/4064 6342/6342/4063 6393/6393/4105 +f 6343/6343/4064 6393/6393/4105 6391/6391/4103 +f 6394/6394/4103 6395/6395/4105 6396/6396/4106 +f 6394/6394/4103 6396/6396/4106 6397/6397/4107 +f 6398/6398/4104 6399/6399/4108 6400/6400/4107 +f 6398/6398/4104 6400/6400/4107 6401/6401/4109 +f 5982/5982/3982 5981/5981/3981 6402/6402/4110 +f 5982/5982/3982 6402/6402/4110 6403/6403/4111 +f 5981/5981/3981 5694/5694/3830 6404/6404/4112 +f 5981/5981/3981 6404/6404/4112 6402/6402/4110 +f 6405/6405/4110 6406/6406/4112 6407/6407/4113 +f 6405/6405/4110 6407/6407/4113 6408/6408/4114 +f 6403/6403/4111 6402/6402/4110 6409/6409/4115 +f 6403/6403/4111 6409/6409/4115 6410/6410/4116 +f 5694/5694/3830 5693/5693/3829 6411/6411/4117 +f 5694/5694/3830 6411/6411/4117 6404/6404/4112 +f 5693/5693/3829 5692/5692/3828 6392/6392/4104 +f 5693/5693/3829 6392/6392/4104 6411/6411/4117 +f 6412/6412/4118 6398/6398/4104 6401/6401/4109 +f 6412/6412/4118 6401/6401/4109 6413/6413/4119 +f 6406/6406/4112 6414/6414/4117 6415/6415/4120 +f 6406/6406/4112 6415/6415/4120 6407/6407/4113 +f 6416/6416/4121 6417/6417/4122 6418/6418/4123 +f 6416/6416/4121 6418/6418/4123 6419/6419/4100 +f 6417/6417/4122 6420/6420/4124 6421/6421/4125 +f 6417/6417/4122 6421/6421/4125 6418/6418/4123 +f 6418/6418/4123 6421/6421/4125 5546/5554/3706 +f 6418/6418/4123 5546/5554/3706 6323/6323/4050 +f 6419/6419/4100 6418/6418/4123 6323/6323/4050 +f 6419/6419/4100 6323/6323/4050 5700/5700/3836 +f 6422/6422/4126 6423/6423/4127 6424/6424/4128 +f 6422/6422/4126 6424/6424/4128 6425/6425/4129 +f 6423/6423/4127 6379/6379/4094 6382/6382/4097 +f 6423/6423/4127 6382/6382/4097 6424/6424/4128 +f 6424/6424/4128 6382/6382/4097 6390/6390/3834 +f 6424/6424/4128 6390/6390/3834 6426/6426/4058 +f 6427/6427/4129 6428/6428/4130 6337/6337/4058 +f 6427/6427/4129 6337/6337/4058 5548/5556/3708 +f 6420/6420/4124 6429/6429/4131 6430/6430/4132 +f 6420/6420/4124 6430/6430/4132 6421/6421/4125 +f 6429/6429/4131 6431/6431/4126 6427/6427/4129 +f 6429/6429/4131 6427/6427/4129 6430/6430/4132 +f 6430/6430/4132 6427/6427/4129 5548/5556/3708 +f 6430/6430/4132 5548/5556/3708 5547/5555/3707 +f 6421/6421/4125 6430/6430/4132 5547/5555/3707 +f 6421/6421/4125 5547/5555/3707 5546/5554/3706 +f 6384/6384/4099 6383/6383/4098 6432/6432/4133 +f 6384/6384/4099 6432/6432/4133 6433/6433/4134 +f 6434/6434/4095 6435/6435/4094 6436/6436/4135 +f 6434/6434/4095 6436/6436/4135 6437/6437/4136 +f 6437/6437/4136 6436/6436/4135 6410/6410/4116 +f 6437/6437/4136 6410/6410/4116 6409/6409/4115 +f 6433/6433/4134 6432/6432/4133 6408/6408/4114 +f 6433/6433/4134 6408/6408/4114 6407/6407/4113 +f 6420/6420/4124 6417/6417/4122 6438/6438/4137 +f 6420/6420/4124 6438/6438/4137 6439/6439/4138 +f 6440/6440/4139 6384/6384/4099 6433/6433/4134 +f 6440/6440/4139 6433/6433/4134 6441/6441/4137 +f 6438/6438/4137 6442/6442/4140 6443/6443/4113 +f 6438/6438/4137 6443/6443/4113 6413/6413/4119 +f 6439/6439/4138 6438/6438/4137 6413/6413/4119 +f 6439/6439/4138 6413/6413/4119 6401/6401/4109 +f 6444/6444/4126 6445/6445/4131 6446/6446/4141 +f 6444/6444/4126 6446/6446/4141 6447/6447/4142 +f 6429/6429/4131 6420/6420/4124 6439/6439/4138 +f 6429/6429/4131 6439/6439/4138 6448/6448/4143 +f 6448/6448/4143 6439/6439/4138 6401/6401/4109 +f 6448/6448/4143 6401/6401/4109 6400/6400/4107 +f 6447/6447/4142 6446/6446/4141 6397/6397/4107 +f 6447/6447/4142 6397/6397/4107 6396/6396/4106 +f 6435/6435/4094 6449/6449/4127 6450/6450/4144 +f 6435/6435/4094 6450/6450/4144 6436/6436/4135 +f 6451/6451/4145 6444/6444/4126 6447/6447/4142 +f 6451/6451/4145 6447/6447/4142 6452/6452/4144 +f 6452/6452/4144 6447/6447/4142 6396/6396/4106 +f 6452/6452/4144 6396/6396/4106 6453/6453/4146 +f 6436/6436/4135 6450/6450/4144 6454/6454/4146 +f 6436/6436/4135 6454/6454/4146 6410/6410/4116 +f 6342/6342/4063 6378/6378/4093 6455/6455/4147 +f 6342/6342/4063 6455/6455/4147 6393/6393/4105 +f 6378/6378/4093 5982/5982/3982 6403/6403/4111 +f 6378/6378/4093 6403/6403/4111 6455/6455/4147 +f 6455/6455/4147 6403/6403/4111 6410/6410/4116 +f 6455/6455/4147 6410/6410/4116 6454/6454/4146 +f 6393/6393/4105 6455/6455/4147 6454/6454/4146 +f 6393/6393/4105 6454/6454/4146 6456/6456/4148 +o Plane.010__0 +v -1.186677 -0.143416 -0.864054 +v -1.224637 -0.115845 -0.864054 +v -1.287751 -0.266782 -0.864054 +v -1.250425 -0.300720 -0.864054 +v -1.262568 -0.088213 -0.864054 +v -1.325058 -0.232780 -0.864054 +v -1.370349 -0.366617 -0.864054 +v -1.333421 -0.409501 -0.864054 +v -1.296464 -0.452237 -0.864054 +v -0.622515 1.286027 -0.864054 +v -0.564318 1.265894 -0.864054 +v -0.566894 1.286074 -0.864054 +v -0.625318 1.307526 -0.864054 +v -0.508596 1.250367 -0.864054 +v -0.513019 1.269987 -0.864054 +v -0.513729 1.278823 -0.864054 +v -0.567787 1.294714 -0.864054 +v -0.626509 1.315803 -0.864054 +v -0.611424 0.459916 -0.864054 +v -0.546831 0.476511 -0.864054 +v -0.528511 0.613890 -0.864054 +v -0.587646 0.598480 -0.864054 +v -0.443033 0.553638 -0.864054 +v -0.434029 0.678121 -0.864054 +v -0.438820 0.808649 -0.864054 +v -0.523633 0.763346 -0.864054 +v -0.579919 0.753273 -0.864054 +v 0.008207 -0.438533 -0.864054 +v -0.118826 -0.406462 -0.864054 +v -0.144369 -0.676471 -0.864054 +v 0.004268 -0.689423 -0.864054 +v -0.232440 -0.363201 -0.864054 +v -0.279700 -0.653172 -0.864054 +v -0.303603 -0.870756 -0.864054 +v -0.158159 -0.892971 -0.864054 +v 0.002043 -0.904158 -0.864054 +v -0.042196 0.984719 -0.864054 +v -0.015499 1.015103 -0.864054 +v -0.036770 1.110231 -0.864054 +v -0.066478 1.048367 -0.864054 +v 0.024726 1.039252 -0.864054 +v -0.006091 1.173877 -0.864054 +v -0.053114 1.243853 -0.864054 +v -0.084731 1.168664 -0.864054 +v -0.116441 1.093538 -0.864054 +v -0.047734 0.824755 -0.864054 +v -0.038049 0.769611 -0.864054 +v -0.022230 0.883033 -0.864054 +v -0.041804 0.897684 -0.864054 +v -0.020821 0.665305 -0.864054 +v 0.003618 0.829663 -0.864054 +v 0.000743 0.511959 -0.864054 +v 0.033174 0.717257 -0.864054 +v 0.042802 0.370944 -0.864054 +v 0.076030 0.604380 -0.864054 +v 0.109511 0.842776 -0.864054 +v 0.065990 0.926973 -0.864054 +v -0.839666 0.464296 -0.864054 +v -0.791787 0.458651 -0.864054 +v -0.755035 0.591089 -0.864054 +v -0.800282 0.594234 -0.864054 +v -0.730747 0.454544 -0.864054 +v -0.697855 0.589739 -0.864054 +v -0.688639 0.746250 -0.864054 +v -0.744139 0.745870 -0.864054 +v -0.787728 0.747108 -0.864054 +v -0.968647 0.178479 -0.864054 +v -0.916329 0.162608 -0.864054 +v -0.846337 0.320068 -0.864054 +v -0.896441 0.330246 -0.864054 +v -0.847929 0.145516 -0.864054 +v -0.781374 0.310469 -0.864054 +v -0.705679 0.125617 -0.864054 +v -0.626723 0.129448 -0.864054 +v -0.577841 0.319455 -0.864054 +v -0.649718 0.306242 -0.864054 +v -0.512945 0.200027 -0.864054 +v -0.466267 0.402922 -0.864054 +v -0.900597 1.248671 -0.864054 +v -0.833988 1.263941 -0.864054 +v -0.838489 1.280871 -0.864054 +v -0.906596 1.265553 -0.864054 +v -0.756985 1.276412 -0.864054 +v -0.759937 1.294410 -0.864054 +v -0.760969 1.301485 -0.864054 +v -0.839576 1.287695 -0.864054 +v -0.908139 1.272404 -0.864054 +v -0.761929 0.934908 -0.864054 +v -0.803890 0.929922 -0.864054 +v -0.704914 0.938845 -0.864054 +v -0.727875 1.102389 -0.864054 +v -0.786624 1.091132 -0.864054 +v -0.816774 1.056235 -0.864054 +v -0.532001 0.942422 -0.864054 +v -0.588107 0.940894 -0.864054 +v -0.456401 0.962689 -0.864054 +v -0.474695 1.092160 -0.864054 +v -0.543689 1.093316 -0.864054 +v -0.600691 1.099482 -0.864054 +v -0.396763 1.283539 -0.864054 +v -0.342213 1.298418 -0.864054 +v -0.358918 1.315099 -0.864054 +v -0.412166 1.306546 -0.864054 +v -0.299741 1.305793 -0.864054 +v -0.316580 1.314693 -0.864054 +v -0.325790 1.319521 -0.864054 +v -0.360345 1.321725 -0.864054 +v -0.413215 1.314830 -0.864054 +v -0.155524 1.202554 -0.864054 +v -0.190035 1.132145 -0.864054 +v -0.122354 1.271042 -0.864054 +v -0.197577 1.279468 -0.864054 +v -0.234272 1.229837 -0.864054 +v -0.293955 1.171127 -0.864054 +v -0.437968 -0.308276 -0.864054 +v -0.551004 -0.317262 -0.864054 +v -0.614625 -0.570241 -0.864054 +v -0.507852 -0.596898 -0.864054 +v -0.663894 -0.327870 -0.864054 +v -0.718580 -0.541732 -0.864054 +v -0.758118 -0.737442 -0.864054 +v -0.652236 -0.774882 -0.864054 +v -0.543004 -0.809158 -0.864054 +v -0.161346 0.598900 -0.864054 +v -0.346301 0.377170 -0.864054 +v -0.447986 0.032318 -0.864054 +v -0.312082 0.121660 -0.864054 +v -0.587177 -0.062929 -0.864054 +v -0.777192 0.133691 -0.864054 +v -0.854226 -0.063267 -0.864054 +v -0.779178 -0.081982 -0.864054 +v -0.926961 -0.041891 -0.864054 +v -1.004331 -0.229836 -0.864054 +v -0.930081 -0.260025 -0.864054 +v -0.852260 -0.288806 -0.864054 +v 0.022678 0.123796 -0.864054 +v -0.035328 0.254235 -0.864054 +v -0.075650 -0.052426 -0.864054 +v 0.015572 -0.133128 -0.864054 +v -0.072609 0.403291 -0.864054 +v -0.150223 0.043014 -0.864054 +v -1.018638 0.195924 -0.864054 +v -1.057374 0.209723 -0.864054 +v -1.144113 0.048311 -0.864054 +v -1.104779 0.027891 -0.864054 +v -1.096055 0.223641 -0.864054 +v -1.183401 0.068820 -0.864054 +v -0.989841 -0.435705 -0.864054 +v -0.908215 -0.471484 -0.864054 +v -1.066894 -0.399349 -0.864054 +v -1.116202 -0.566720 -0.864054 +v -1.037656 -0.609490 -0.864054 +v -0.953140 -0.651924 -0.864054 +v -0.611694 -1.330516 -0.864055 +v -0.727170 -1.295839 -0.864055 +v -0.737786 -1.392400 -0.864055 +v -0.622627 -1.428278 -0.864055 +v -0.840124 -1.251613 -0.864055 +v -0.849801 -1.346602 -0.864055 +v -0.859522 -1.441565 -0.864055 +v -0.748434 -1.488946 -0.864055 +v -0.633567 -1.526038 -0.864055 +v -1.049113 -1.129854 -0.864055 +v -1.130900 -1.066669 -0.864054 +v -1.133795 -1.163368 -0.864055 +v -1.054586 -1.225812 -0.864055 +v -1.201730 -1.001091 -0.864054 +v -1.202309 -1.097073 -0.864054 +v -1.202906 -1.193037 -0.864055 +v -1.136743 -1.260022 -0.864055 +v -1.060102 -1.321738 -0.864055 +v -1.327831 -0.791818 -0.864054 +v -1.378528 -0.691281 -0.864054 +v -1.381391 -0.812925 -0.864054 +v -1.328969 -0.921568 -0.864054 +v -1.415511 -0.615829 -0.864054 +v -1.418328 -0.727586 -0.864054 +v -1.411072 -0.809814 -0.864054 +v -1.380007 -0.898480 -0.864054 +v -1.327430 -1.013762 -0.864054 +v -0.005214 -1.403539 -0.864055 +v -0.186640 -1.399837 -0.864055 +v -0.192065 -1.494133 -0.864055 +v -0.006735 -1.498096 -0.864055 +v -0.351621 -1.384791 -0.864055 +v -0.360723 -1.479865 -0.864055 +v -0.369791 -1.574940 -0.864055 +v -0.197469 -1.588428 -0.864055 +v -0.008259 -1.592653 -0.864055 +v 1.167371 -0.133903 -0.864054 +v 1.232371 -0.313330 -0.864054 +v 1.271324 -0.282714 -0.864054 +v 1.206400 -0.105599 -0.864054 +v 1.279563 -0.487826 -0.864054 +v 1.317778 -0.454298 -0.864054 +v 1.355986 -0.420712 -0.864054 +v 1.310273 -0.252082 -0.864054 +v 1.245403 -0.077241 -0.864054 +v 0.590895 1.035143 -0.864054 +v 0.600558 1.176546 -0.864054 +v 0.553914 1.173545 -0.864054 +v 0.544875 1.033492 -0.864054 +v 0.610815 1.317870 -0.864054 +v 0.563558 1.313555 -0.864054 +v 0.522078 1.298620 -0.864054 +v 0.511501 1.163193 -0.864054 +v 0.501560 1.027822 -0.864054 +v 0.592290 0.475318 -0.864054 +v 0.570000 0.605002 -0.864054 +v 0.525133 0.610684 -0.864054 +v 0.545237 0.479457 -0.864054 +v 0.563911 0.720737 -0.864054 +v 0.517364 0.725729 -0.864054 +v 0.471622 0.730059 -0.864054 +v 0.476067 0.616313 -0.864054 +v 0.490295 0.484168 -0.864054 +v 0.158803 -0.687833 -0.864054 +v 0.145517 -0.446898 -0.864054 +v 0.167697 -0.901319 -0.864054 +v 0.323148 -0.887653 -0.864054 +v 0.304401 -0.675428 -0.864054 +v 0.277917 -0.438976 -0.864054 +v 0.317741 0.539789 -0.864054 +v 0.332141 0.674300 -0.864054 +v 0.295802 0.768173 -0.864054 +v 0.278484 0.629164 -0.864054 +v 0.355850 0.778662 -0.864054 +v 0.318822 0.859417 -0.864054 +v 0.282192 0.945447 -0.864054 +v 0.259424 0.881731 -0.864054 +v 0.224521 0.770712 -0.864054 +v 0.317120 0.260779 -0.864054 +v 0.318697 0.374330 -0.864054 +v 0.275597 0.425778 -0.864054 +v 0.279163 0.251209 -0.864054 +v 0.212425 0.489541 -0.864054 +v 0.206042 0.269804 -0.864054 +v 0.140028 0.536597 -0.864054 +v 0.118096 0.299002 -0.864054 +v 0.162314 0.792480 -0.864054 +v 0.813453 0.477833 -0.864054 +v 0.776579 0.599738 -0.864054 +v 0.726446 0.597294 -0.864054 +v 0.758714 0.473435 -0.864054 +v 0.762198 0.716777 -0.864054 +v 0.717244 0.714208 -0.864054 +v 0.662261 0.713363 -0.864054 +v 0.666841 0.596641 -0.864054 +v 0.694054 0.470563 -0.864054 +v 0.951376 0.185334 -0.864054 +v 0.873768 0.340420 -0.864054 +v 0.818926 0.330912 -0.864054 +v 0.898870 0.168039 -0.864054 +v 0.751472 0.321924 -0.864054 +v 0.830444 0.149057 -0.864054 +v 0.691457 0.126107 -0.864054 +v 0.632295 0.316892 -0.864054 +v 0.575064 0.316875 -0.864054 +v 0.622888 0.118789 -0.864054 +v 0.511275 0.318188 -0.864054 +v 0.550545 0.113650 -0.864054 +v 0.797348 0.978263 -0.864054 +v 0.787417 1.116616 -0.864054 +v 0.733268 1.146554 -0.864054 +v 0.739738 1.024570 -0.864054 +v 0.775626 1.220227 -0.864054 +v 0.725456 1.265795 -0.864054 +v 0.689394 1.299618 -0.864054 +v 0.687405 1.166509 -0.864054 +v 0.685282 1.033417 -0.864054 +v 0.763794 0.830990 -0.864054 +v 0.722188 0.829763 -0.864054 +v 0.763188 0.902086 -0.864054 +v 0.730826 0.916882 -0.864054 +v 0.678376 0.917928 -0.864054 +v 0.669170 0.828669 -0.864054 +v 0.570842 0.832215 -0.864054 +v 0.524132 0.834868 -0.864054 +v 0.581004 0.917547 -0.864054 +v 0.535130 0.917805 -0.864054 +v 0.492024 0.916151 -0.864054 +v 0.480288 0.836190 -0.864054 +v 0.415970 0.976824 -0.864054 +v 0.443488 1.124629 -0.864054 +v 0.399354 1.124627 -0.864054 +v 0.367546 1.017084 -0.864054 +v 0.466455 1.239704 -0.864054 +v 0.425200 1.215809 -0.864054 +v 0.389267 1.193529 -0.864054 +v 0.360494 1.131584 -0.864054 +v 0.327722 1.051227 -0.864054 +v 0.379956 0.872566 -0.864054 +v 0.341170 0.933722 -0.864054 +v 0.302809 0.993633 -0.864054 +v 0.495417 -0.407891 -0.864054 +v 0.541182 -0.634438 -0.864054 +v 0.649128 -0.608339 -0.864054 +v 0.596025 -0.387665 -0.864054 +v 0.574724 -0.841762 -0.864054 +v 0.687958 -0.812113 -0.864054 +v 0.790106 -0.779528 -0.864054 +v 0.747263 -0.580093 -0.864054 +v 0.689045 -0.365496 -0.864054 +v 0.382205 0.121308 -0.864054 +v 0.438874 -0.147643 -0.864055 +v 0.530139 -0.136824 -0.864054 +v 0.471066 0.112298 -0.864055 +v 0.616334 -0.124768 -0.864055 +v 0.767623 -0.092662 -0.864054 +v 0.843046 -0.070964 -0.864054 +v 0.760361 0.135410 -0.864054 +v 0.844342 -0.314237 -0.864054 +v 0.922214 -0.280446 -0.864054 +v 0.999328 -0.241009 -0.864054 +v 0.917902 -0.043889 -0.864054 +v 0.128486 -0.166823 -0.864054 +v 0.114113 0.064165 -0.864054 +v 0.245080 -0.169215 -0.864054 +v 0.217479 0.051402 -0.864054 +v 1.001573 0.202535 -0.864054 +v 1.086830 0.040157 -0.864054 +v 1.126476 0.061697 -0.864054 +v 1.040512 0.214485 -0.864054 +v 1.166064 0.083350 -0.864054 +v 1.079370 0.226593 -0.864054 +v 0.905679 -0.515871 -0.864054 +v 0.984512 -0.474429 -0.864054 +v 0.952076 -0.705314 -0.864054 +v 1.029982 -0.659894 -0.864054 +v 1.107222 -0.610159 -0.864054 +v 1.062675 -0.428179 -0.864054 +v 0.620194 -1.323120 -0.864055 +v 0.623210 -1.418367 -0.864055 +v 0.746769 -1.377989 -0.864055 +v 0.743059 -1.284510 -0.864055 +v 0.626262 -1.513604 -0.864055 +v 0.750526 -1.471449 -0.864055 +v 0.862334 -1.422808 -0.864055 +v 0.858377 -1.331039 -0.864055 +v 0.854471 -1.239243 -0.864055 +v 1.024953 -1.140005 -0.864055 +v 1.026017 -1.231050 -0.864055 +v 1.091717 -1.182738 -0.864055 +v 1.093483 -1.091074 -0.864054 +v 1.027136 -1.322056 -0.864055 +v 1.089995 -1.274368 -0.864055 +v 1.149584 -1.221357 -0.864055 +v 1.155172 -1.127855 -0.864055 +v 1.160741 -1.034379 -0.864054 +v 1.299499 -0.829530 -0.864054 +v 1.285828 -0.972185 -0.864054 +v 1.338643 -0.887046 -0.864054 +v 1.349147 -0.752070 -0.864054 +v 1.272611 -1.075248 -0.864054 +v 1.326096 -0.986020 -0.864054 +v 1.359313 -0.913225 -0.864054 +v 1.374949 -0.823281 -0.864054 +v 1.384662 -0.696646 -0.864054 +v 0.178696 -1.490316 -0.864055 +v 0.177942 -1.394870 -0.864055 +v 0.179439 -1.585763 -0.864055 +v 0.350745 -1.569562 -0.864055 +v 0.348963 -1.473335 -0.864055 +v 0.347178 -1.377108 -0.864055 +v -0.490346 -1.360682 -0.864055 +v -0.501087 -1.457491 -0.864055 +v -0.511806 -1.554303 -0.864055 +v -0.108360 0.515725 -0.864054 +v -0.220877 0.112850 -0.864054 +v -0.334888 -0.325643 -0.864054 +v -0.398627 -0.625283 -0.864054 +v -0.429527 -0.841774 -0.864054 +v -0.311710 0.906922 -0.864054 +v -0.349714 1.012572 -0.864054 +v -0.195605 1.004773 -0.864054 +v -0.254930 1.063806 -0.864054 +v -0.308483 1.104208 -0.864054 +v -0.383244 1.100208 -0.864054 +v -0.452915 1.261161 -0.864054 +v -0.462986 1.283535 -0.864054 +v -0.463966 1.292430 -0.864054 +v -0.296415 0.592586 -0.864054 +v -0.137299 0.789479 -0.864054 +v -0.134256 0.885002 -0.864054 +v -0.282254 0.720075 -0.864054 +v -0.288085 0.814475 -0.864054 +v -0.153756 0.949108 -0.864054 +v -0.950041 -1.193915 -0.864055 +v -0.957912 -1.288898 -0.864055 +v -0.965825 -1.383853 -0.864055 +v -0.764535 -0.315730 -0.864054 +v -0.817353 -0.507895 -0.864054 +v -0.859344 -0.695510 -0.864054 +v -0.695111 -0.093624 -0.864054 +v -0.633162 0.749095 -0.864054 +v -0.645204 0.940726 -0.864054 +v -0.662606 1.103202 -0.864054 +v -0.715137 0.306292 -0.864054 +v -0.670116 0.455287 -0.864054 +v -0.641640 0.592549 -0.864054 +v -0.685977 1.287390 -0.864054 +v -0.688669 1.307641 -0.864054 +v -0.689842 1.315299 -0.864054 +v -1.268270 -0.922985 -0.864054 +v -1.267827 -1.019089 -0.864054 +v -1.266722 -1.112952 -0.864054 +v -0.998176 -0.016725 -0.864054 +v -1.053151 0.004648 -0.864054 +v -1.134638 -0.171982 -0.864054 +v -1.077652 -0.197750 -0.864054 +v -0.883667 0.745563 -0.864054 +v -0.856267 0.747458 -0.864054 +v -0.874400 0.928155 -0.864054 +v -0.900864 0.918654 -0.864054 +v -0.828825 0.748998 -0.864054 +v -0.846541 0.937567 -0.864054 +v -0.864710 1.126510 -0.864054 +v -0.904310 1.093316 -0.864054 +v -0.929842 1.076258 -0.864054 +v -0.963916 1.213121 -0.864054 +v -0.941924 1.228855 -0.864054 +v -0.947858 1.246189 -0.864054 +v -0.968620 1.231556 -0.864054 +v -0.949794 1.253422 -0.864054 +v -0.967164 1.240450 -0.864054 +v -0.977286 0.352127 -0.864054 +v -1.011336 0.361720 -0.864054 +v -0.943184 0.342657 -0.864054 +v -0.883108 0.472568 -0.864054 +v -0.912227 0.479010 -0.864054 +v -0.941313 0.485550 -0.864054 +v -0.869461 0.602243 -0.864054 +v -0.896963 0.605390 -0.864054 +v -0.841941 0.599091 -0.864054 +v -1.141361 -0.362322 -0.864054 +v -1.198537 -0.333431 -0.864054 +v -1.245422 -0.490461 -0.864054 +v -1.189836 -0.523619 -0.864054 +v -1.225791 -0.689584 -0.864054 +v -1.155959 -0.742902 -0.864054 +v -1.276552 -0.648076 -0.864054 +v -1.284562 -0.755638 -0.864054 +v -1.248546 -0.816870 -0.864054 +v -1.183786 -0.882228 -0.864054 +v -0.898551 -0.898728 -0.864054 +v -0.793411 -0.947534 -0.864054 +v -0.995118 -0.846227 -0.864054 +v -1.027374 -1.001985 -0.864054 +v -0.928641 -1.062357 -0.864054 +v -0.820044 -1.116959 -0.864055 +v -0.454850 -1.055616 -0.864054 +v -0.323532 -1.083933 -0.864054 +v -0.571878 -1.022915 -0.864054 +v -0.594002 -1.193677 -0.864055 +v -0.474365 -1.225018 -0.864055 +v -0.338861 -1.251143 -0.864055 +v -0.000750 -1.113149 -0.864055 +v 0.173037 -1.108193 -0.864055 +v -0.003270 -1.273653 -0.864055 +v 0.175862 -1.265972 -0.864055 +v 0.342328 -1.248773 -0.864055 +v 0.335354 -1.092800 -0.864054 +v 1.306811 -0.651080 -0.864054 +v 1.343841 -0.607976 -0.864054 +v 1.379841 -0.565393 -0.864054 +v 0.987078 -0.887350 -0.864054 +v 1.061704 -0.839854 -0.864054 +v 1.010260 -1.024393 -0.864054 +v 1.081507 -0.975870 -0.864054 +v 1.151812 -0.920169 -0.864054 +v 1.135514 -0.786890 -0.864054 +v 0.597472 -1.043279 -0.864054 +v 0.714996 -1.010068 -0.864054 +v 0.610974 -1.196660 -0.864055 +v 0.731563 -1.160511 -0.864055 +v 0.840846 -1.118436 -0.864055 +v 0.821095 -0.972400 -0.864054 +v -0.170016 -1.104316 -0.864055 +v -0.179146 -1.268276 -0.864055 +v -1.363674 -0.552037 -0.864054 +v -1.326281 -0.610412 -0.864054 +v -1.399951 -0.494362 -0.864054 +v -1.079639 -0.794888 -0.864054 +v -1.110697 -0.942685 -0.864054 +v -0.684159 -0.987993 -0.864054 +v -0.708289 -1.159336 -0.864055 +v 0.474096 -1.070914 -0.864054 +v 0.456186 -0.867273 -0.864054 +v 0.484504 -1.225787 -0.864055 +v 0.493997 -1.449745 -0.864055 +v 0.491588 -1.353531 -0.864055 +v 0.496422 -1.545957 -0.864055 +v 0.347049 -0.161976 -0.864054 +v 0.307674 0.056937 -0.864054 +v 0.392237 -0.425170 -0.864054 +v 0.429265 -0.657095 -0.864054 +v 0.442560 0.835030 -0.864054 +v 0.428777 0.733266 -0.864054 +v 0.455075 0.909064 -0.864054 +v 0.431235 0.892275 -0.864054 +v 0.415633 0.833005 -0.864054 +v 0.396063 0.735674 -0.864054 +v 0.478296 1.143331 -0.864054 +v 0.462844 1.013479 -0.864054 +v 0.494490 1.270408 -0.864054 +v 0.438943 0.321788 -0.864054 +v 0.425152 0.489640 -0.864054 +v 0.369799 0.494520 -0.864054 +v 0.376621 0.328880 -0.864054 +v 0.422277 0.621671 -0.864054 +v 0.377937 0.625899 -0.864054 +v 1.205622 -0.729354 -0.864054 +v 1.177763 -0.560657 -0.864054 +v 1.220113 -0.852158 -0.864054 +v 1.260525 -0.788262 -0.864054 +v 1.257208 -0.683789 -0.864054 +v 1.229723 -0.523256 -0.864054 +v 1.221760 -1.057507 -0.864054 +v 1.231516 -0.957329 -0.864054 +v 1.211539 -1.155213 -0.864055 +v 0.986605 -0.012328 -0.864054 +v 1.068359 -0.199197 -0.864054 +v 1.118434 -0.166172 -0.864054 +v 1.037311 0.014016 -0.864054 +v 0.858453 0.717667 -0.864054 +v 0.867320 0.843579 -0.864054 +v 0.837018 0.844903 -0.864054 +v 0.831260 0.718823 -0.864054 +v 0.887354 0.963929 -0.864054 +v 0.848006 0.971180 -0.864054 +v 0.805884 0.844217 -0.864054 +v 0.804027 0.719624 -0.864054 +v 0.899988 1.066735 -0.864054 +v 0.849423 1.087589 -0.864054 +v 0.893771 1.132315 -0.864054 +v 0.845146 1.171931 -0.864054 +v 0.994002 0.354887 -0.864054 +v 0.958856 0.351928 -0.864054 +v 0.922455 0.475271 -0.864054 +v 0.891924 0.477962 -0.864054 +v 0.861345 0.480792 -0.864054 +v 0.923635 0.349139 -0.864054 +v 0.876157 0.595012 -0.864054 +v 0.848563 0.598029 -0.864054 +v 0.820946 0.601065 -0.864054 +v 1.132500 -0.382085 -0.864054 +v 1.183087 -0.347070 -0.864054 +v 0.909606 -0.931407 -0.864054 +v 0.875268 -0.744600 -0.864054 +v 0.932302 -1.072214 -0.864054 +v 0.950361 -1.280889 -0.864055 +v 0.947355 -1.189860 -0.864055 +v 0.953422 -1.371885 -0.864055 +v 0.829762 -0.550239 -0.864054 +v 0.769273 -0.341809 -0.864054 +v 0.693800 -0.110240 -0.864054 +v 0.618518 0.829614 -0.864054 +v 0.611216 0.715988 -0.864054 +v 0.627888 0.917161 -0.864054 +v 0.689367 0.317784 -0.864054 +v 0.639314 0.471691 -0.864054 +v 0.615230 0.599688 -0.864054 +v 0.644527 1.175203 -0.864054 +v 0.636632 1.035185 -0.864054 +v 0.652825 1.315196 -0.864054 +v -1.186677 -0.143416 -0.896171 +v -1.250332 -0.300106 -0.896171 +v -1.287681 -0.266316 -0.896171 +v -1.224637 -0.115845 -0.896171 +v -1.295725 -0.447318 -0.896171 +v -1.332855 -0.405774 -0.896171 +v -1.370105 -0.365055 -0.896171 +v -1.325027 -0.232584 -0.896171 +v -1.262568 -0.088213 -0.896171 +v -0.622101 1.286022 -0.896171 +v -0.625222 1.307525 -0.896171 +v -0.566406 1.285946 -0.896171 +v -0.562984 1.265719 -0.896171 +v -0.626490 1.315802 -0.896171 +v -0.567538 1.294614 -0.896171 +v -0.512091 1.278026 -0.896171 +v -0.510932 1.268986 -0.896171 +v -0.505778 1.249065 -0.896171 +v -0.611424 0.459916 -0.896171 +v -0.587646 0.598480 -0.896171 +v -0.528679 0.613426 -0.896171 +v -0.546830 0.476511 -0.896171 +v -0.579919 0.753273 -0.896171 +v -0.525225 0.761019 -0.896171 +v -0.443353 0.795371 -0.896171 +v -0.434320 0.675446 -0.896171 +v -0.443033 0.553638 -0.896171 +v 0.008207 -0.438533 -0.896171 +v 0.004268 -0.689423 -0.896171 +v -0.144369 -0.676471 -0.896171 +v -0.118826 -0.406462 -0.896171 +v 0.002043 -0.904158 -0.896171 +v -0.158159 -0.892971 -0.896171 +v -0.303603 -0.870756 -0.896171 +v -0.279700 -0.653172 -0.896171 +v -0.232440 -0.363201 -0.896171 +v -0.042572 0.985965 -0.896171 +v -0.071132 1.046884 -0.896171 +v -0.038363 1.111775 -0.896171 +v -0.015767 1.015991 -0.896171 +v -0.156945 1.056073 -0.896171 +v -0.090425 1.167030 -0.896171 +v -0.053789 1.244661 -0.896171 +v -0.006397 1.174711 -0.896171 +v 0.024658 1.039476 -0.896171 +v -0.047734 0.824755 -0.896171 +v -0.041851 0.897840 -0.896171 +v -0.022264 0.883144 -0.896171 +v -0.038049 0.769611 -0.896171 +v 0.003608 0.829695 -0.896171 +v -0.020821 0.665305 -0.896171 +v 0.033174 0.717260 -0.896171 +v 0.000743 0.511959 -0.896171 +v 0.065987 0.926986 -0.896171 +v 0.109511 0.842776 -0.896171 +v 0.076030 0.604380 -0.896171 +v 0.042802 0.370944 -0.896171 +v -0.839666 0.464296 -0.896171 +v -0.800282 0.594234 -0.896171 +v -0.755036 0.591089 -0.896171 +v -0.791787 0.458651 -0.896171 +v -0.787728 0.747108 -0.896171 +v -0.744139 0.745870 -0.896171 +v -0.688639 0.746250 -0.896171 +v -0.697855 0.589739 -0.896171 +v -0.730747 0.454544 -0.896171 +v -0.968647 0.178479 -0.896171 +v -0.896441 0.330246 -0.896171 +v -0.846337 0.320068 -0.896171 +v -0.916329 0.162608 -0.896171 +v -0.781374 0.310469 -0.896171 +v -0.847929 0.145516 -0.896171 +v -0.705679 0.125617 -0.896171 +v -0.649718 0.306242 -0.896171 +v -0.577841 0.319455 -0.896171 +v -0.626723 0.129448 -0.896171 +v -0.466268 0.402922 -0.896171 +v -0.512945 0.200027 -0.896171 +v -0.900597 1.248671 -0.896171 +v -0.906596 1.265553 -0.896171 +v -0.838489 1.280871 -0.896171 +v -0.833988 1.263941 -0.896171 +v -0.908139 1.272404 -0.896171 +v -0.839576 1.287695 -0.896171 +v -0.760969 1.301485 -0.896171 +v -0.759937 1.294410 -0.896171 +v -0.756985 1.276412 -0.896171 +v -0.803890 0.929922 -0.896171 +v -0.761929 0.934908 -0.896171 +v -0.816774 1.056235 -0.896171 +v -0.786624 1.091132 -0.896171 +v -0.727875 1.102389 -0.896171 +v -0.704914 0.938845 -0.896171 +v -0.588065 0.940893 -0.896171 +v -0.536639 0.938955 -0.896171 +v -0.600352 1.099478 -0.896171 +v -0.547933 1.086970 -0.896171 +v -0.516181 1.053833 -0.896171 +v -0.496568 0.939194 -0.896171 +v -0.391179 1.279932 -0.896171 +v -0.404669 1.304776 -0.896144 +v -0.351976 1.317455 -0.896128 +v -0.337343 1.299106 -0.896171 +v -0.406625 1.317804 -0.895910 +v -0.352696 1.324731 -0.895819 +v -0.311793 1.325426 -0.895808 +v -0.310776 1.320777 -0.896126 +v -0.296532 1.310593 -0.896171 +v -0.234098 1.109595 -0.896171 +v -0.163095 1.198977 -0.896171 +v -0.302001 1.168024 -0.896171 +v -0.238126 1.226309 -0.896171 +v -0.198174 1.279057 -0.896171 +v -0.123395 1.270807 -0.896171 +v -0.437968 -0.308276 -0.896171 +v -0.507852 -0.596898 -0.896171 +v -0.614625 -0.570241 -0.896171 +v -0.551004 -0.317262 -0.896171 +v -0.543004 -0.809158 -0.896171 +v -0.652236 -0.774882 -0.896171 +v -0.758118 -0.737442 -0.896171 +v -0.718580 -0.541732 -0.896171 +v -0.663894 -0.327870 -0.896171 +v -0.161346 0.598900 -0.896171 +v -0.312082 0.121660 -0.896171 +v -0.447986 0.032318 -0.896171 +v -0.346301 0.377170 -0.896171 +v -0.587177 -0.062929 -0.896171 +v -0.779178 -0.081982 -0.896171 +v -0.854226 -0.063267 -0.896171 +v -0.777192 0.133691 -0.896171 +v -0.852260 -0.288806 -0.896171 +v -0.930081 -0.260025 -0.896171 +v -1.004331 -0.229836 -0.896171 +v -0.926961 -0.041891 -0.896171 +v 0.022678 0.123796 -0.896171 +v 0.015572 -0.133128 -0.896171 +v -0.075650 -0.052426 -0.896171 +v -0.035328 0.254235 -0.896171 +v -0.150223 0.043014 -0.896171 +v -0.072609 0.403291 -0.896171 +v -1.018638 0.195924 -0.896171 +v -1.104779 0.027891 -0.896171 +v -1.144113 0.048311 -0.896171 +v -1.057374 0.209723 -0.896171 +v -1.183401 0.068820 -0.896171 +v -1.096055 0.223641 -0.896171 +v -0.908215 -0.471484 -0.896171 +v -0.989841 -0.435705 -0.896171 +v -0.953140 -0.651924 -0.896171 +v -1.037656 -0.609490 -0.896171 +v -1.116202 -0.566720 -0.896171 +v -1.066894 -0.399349 -0.896171 +v -0.611694 -1.330516 -0.896172 +v -0.622627 -1.428278 -0.896171 +v -0.737786 -1.392400 -0.896172 +v -0.727170 -1.295839 -0.896171 +v -0.633567 -1.526037 -0.896171 +v -0.748434 -1.488946 -0.896171 +v -0.859522 -1.441565 -0.896171 +v -0.849801 -1.346602 -0.896171 +v -0.840124 -1.251613 -0.896172 +v -1.049113 -1.129854 -0.896171 +v -1.054586 -1.225812 -0.896171 +v -1.133528 -1.163667 -0.896171 +v -1.130545 -1.067062 -0.896171 +v -1.060102 -1.321738 -0.896171 +v -1.136633 -1.260149 -0.896171 +v -1.202031 -1.194053 -0.896171 +v -1.200174 -1.099465 -0.896171 +v -1.198893 -1.004235 -0.896171 +v -1.322548 -0.790123 -0.896171 +v -1.345885 -0.905799 -0.896144 +v -1.389175 -0.815628 -0.896088 +v -1.386868 -0.723822 -0.896144 +v -1.333593 -1.035213 -0.895910 +v -1.388209 -0.902300 -0.895788 +v -1.419324 -0.811432 -0.895627 +v -1.427350 -0.728191 -0.895788 +v -1.429309 -0.607121 -0.895910 +v -0.005214 -1.403539 -0.896172 +v -0.006735 -1.498096 -0.896171 +v -0.192065 -1.494132 -0.896172 +v -0.186640 -1.399837 -0.896171 +v -0.008259 -1.592653 -0.896171 +v -0.197469 -1.588428 -0.896171 +v -0.369791 -1.574940 -0.896171 +v -0.360723 -1.479865 -0.896171 +v -0.351621 -1.384791 -0.896172 +v 1.167371 -0.133903 -0.896171 +v 1.206400 -0.105599 -0.896171 +v 1.271324 -0.282714 -0.896171 +v 1.232371 -0.313330 -0.896171 +v 1.245403 -0.077241 -0.896171 +v 1.310274 -0.252082 -0.896171 +v 1.355986 -0.420712 -0.896171 +v 1.317778 -0.454298 -0.896171 +v 1.279563 -0.487826 -0.896171 +v 0.590895 1.035143 -0.896171 +v 0.544875 1.033492 -0.896171 +v 0.553914 1.173545 -0.896171 +v 0.600558 1.176546 -0.896171 +v 0.501560 1.027822 -0.896171 +v 0.511501 1.163193 -0.896171 +v 0.522078 1.298620 -0.896171 +v 0.563558 1.313555 -0.896171 +v 0.610815 1.317870 -0.896171 +v 0.592290 0.475318 -0.896171 +v 0.545237 0.479457 -0.896171 +v 0.525133 0.610684 -0.896171 +v 0.570000 0.605002 -0.896171 +v 0.490295 0.484168 -0.896171 +v 0.476067 0.616313 -0.896171 +v 0.471622 0.730059 -0.896171 +v 0.517364 0.725729 -0.896171 +v 0.563911 0.720737 -0.896171 +v 0.145517 -0.446898 -0.896171 +v 0.158803 -0.687833 -0.896171 +v 0.277917 -0.438976 -0.896171 +v 0.304401 -0.675428 -0.896171 +v 0.323148 -0.887653 -0.896171 +v 0.167697 -0.901319 -0.896171 +v 0.317741 0.539789 -0.896171 +v 0.278484 0.629164 -0.896171 +v 0.295802 0.768173 -0.896171 +v 0.332141 0.674300 -0.896171 +v 0.224521 0.770712 -0.896171 +v 0.259424 0.881731 -0.896171 +v 0.282192 0.945447 -0.896171 +v 0.318822 0.859417 -0.896171 +v 0.355850 0.778662 -0.896171 +v 0.317120 0.260779 -0.896171 +v 0.279163 0.251209 -0.896171 +v 0.275597 0.425778 -0.896171 +v 0.318697 0.374330 -0.896171 +v 0.206042 0.269804 -0.896171 +v 0.212425 0.489541 -0.896171 +v 0.118096 0.299002 -0.896171 +v 0.140028 0.536597 -0.896171 +v 0.162314 0.792480 -0.896171 +v 0.813453 0.477833 -0.896171 +v 0.758714 0.473435 -0.896171 +v 0.726446 0.597294 -0.896171 +v 0.776579 0.599738 -0.896171 +v 0.694054 0.470563 -0.896171 +v 0.666841 0.596641 -0.896171 +v 0.662261 0.713362 -0.896171 +v 0.717244 0.714208 -0.896171 +v 0.762198 0.716777 -0.896171 +v 0.951376 0.185334 -0.896171 +v 0.898870 0.168039 -0.896171 +v 0.818926 0.330912 -0.896171 +v 0.873768 0.340420 -0.896171 +v 0.830444 0.149057 -0.896171 +v 0.751472 0.321924 -0.896171 +v 0.691456 0.126107 -0.896171 +v 0.622888 0.118789 -0.896171 +v 0.575064 0.316875 -0.896171 +v 0.632295 0.316892 -0.896171 +v 0.550545 0.113650 -0.896171 +v 0.511275 0.318188 -0.896171 +v 0.797348 0.978263 -0.896171 +v 0.739738 1.024570 -0.896171 +v 0.733268 1.146554 -0.896171 +v 0.787417 1.116616 -0.896171 +v 0.685282 1.033417 -0.896171 +v 0.687405 1.166509 -0.896171 +v 0.689394 1.299618 -0.896171 +v 0.725456 1.265795 -0.896171 +v 0.775626 1.220227 -0.896171 +v 0.722188 0.829764 -0.896171 +v 0.763794 0.830990 -0.896171 +v 0.669170 0.828669 -0.896171 +v 0.678376 0.917928 -0.896171 +v 0.730826 0.916882 -0.896171 +v 0.763188 0.902086 -0.896171 +v 0.524132 0.834868 -0.896171 +v 0.570842 0.832215 -0.896171 +v 0.480288 0.836190 -0.896171 +v 0.492024 0.916151 -0.896171 +v 0.535130 0.917805 -0.896171 +v 0.581004 0.917547 -0.896171 +v 0.415970 0.976824 -0.896171 +v 0.367546 1.017084 -0.896171 +v 0.399354 1.124627 -0.896171 +v 0.443488 1.124629 -0.896171 +v 0.327722 1.051227 -0.896171 +v 0.360494 1.131584 -0.896171 +v 0.389267 1.193529 -0.896171 +v 0.425200 1.215809 -0.896171 +v 0.466455 1.239704 -0.896171 +v 0.341170 0.933722 -0.896171 +v 0.379956 0.872566 -0.896171 +v 0.302809 0.993633 -0.896171 +v 0.495417 -0.407891 -0.896171 +v 0.596025 -0.387665 -0.896171 +v 0.649128 -0.608339 -0.896171 +v 0.541182 -0.634438 -0.896171 +v 0.689045 -0.365496 -0.896171 +v 0.747263 -0.580094 -0.896171 +v 0.790106 -0.779527 -0.896171 +v 0.687958 -0.812113 -0.896171 +v 0.574724 -0.841762 -0.896171 +v 0.382205 0.121308 -0.896171 +v 0.471066 0.112298 -0.896171 +v 0.530139 -0.136824 -0.896171 +v 0.438874 -0.147643 -0.896171 +v 0.616334 -0.124768 -0.896171 +v 0.760361 0.135410 -0.896171 +v 0.843047 -0.070964 -0.896171 +v 0.767623 -0.092662 -0.896171 +v 0.917902 -0.043889 -0.896171 +v 0.999328 -0.241009 -0.896171 +v 0.922214 -0.280446 -0.896171 +v 0.844342 -0.314237 -0.896171 +v 0.114113 0.064165 -0.896171 +v 0.128486 -0.166823 -0.896171 +v 0.217479 0.051402 -0.896171 +v 0.245080 -0.169215 -0.896171 +v 1.001573 0.202535 -0.896171 +v 1.040512 0.214485 -0.896171 +v 1.126476 0.061697 -0.896171 +v 1.086830 0.040157 -0.896171 +v 1.079370 0.226593 -0.896171 +v 1.166064 0.083350 -0.896171 +v 0.984512 -0.474429 -0.896171 +v 0.905679 -0.515871 -0.896171 +v 1.062675 -0.428179 -0.896171 +v 1.107222 -0.610159 -0.896171 +v 1.029982 -0.659894 -0.896171 +v 0.952076 -0.705314 -0.896171 +v 0.620496 -1.323001 -0.896171 +v 0.743893 -1.284195 -0.896171 +v 0.749374 -1.377396 -0.896171 +v 0.624078 -1.418026 -0.896171 +v 0.855410 -1.238982 -0.896171 +v 0.861946 -1.331506 -0.896169 +v 0.873952 -1.433607 -0.896128 +v 0.754218 -1.471779 -0.896165 +v 0.627468 -1.513130 -0.896171 +v 1.024186 -1.140744 -0.896171 +v 1.092752 -1.091675 -0.896171 +v 1.089626 -1.184461 -0.896171 +v 1.023885 -1.233124 -0.896171 +v 1.160473 -1.034594 -0.896171 +v 1.154404 -1.128471 -0.896171 +v 1.148516 -1.222214 -0.896171 +v 1.087146 -1.276723 -0.896171 +v 1.024655 -1.324612 -0.896171 +v 1.299499 -0.829530 -0.896171 +v 1.349147 -0.752070 -0.896171 +v 1.338643 -0.887046 -0.896171 +v 1.285828 -0.972186 -0.896171 +v 1.384662 -0.696646 -0.896171 +v 1.374949 -0.823281 -0.896171 +v 1.359313 -0.913225 -0.896171 +v 1.326096 -0.986020 -0.896171 +v 1.272611 -1.075248 -0.896171 +v 0.177942 -1.394870 -0.896171 +v 0.178696 -1.490316 -0.896172 +v 0.347178 -1.377108 -0.896172 +v 0.348963 -1.473335 -0.896171 +v 0.350745 -1.569562 -0.896171 +v 0.179439 -1.585763 -0.896171 +v -0.501087 -1.457491 -0.896172 +v -0.490346 -1.360682 -0.896171 +v -0.511806 -1.554303 -0.896171 +v -0.220877 0.112850 -0.896171 +v -0.108360 0.515725 -0.896171 +v -0.334888 -0.325643 -0.896171 +v -0.398627 -0.625283 -0.896171 +v -0.429527 -0.841774 -0.896171 +v -0.390229 0.911252 -0.896171 +v -0.430926 0.987913 -0.896171 +v -0.339605 1.034147 -0.896171 +v -0.299716 0.954218 -0.896171 +v -0.479385 1.129951 -0.896171 +v -0.387404 1.132754 -0.896171 +v -0.457741 1.280997 -0.896166 +v -0.448314 1.257654 -0.896171 +v -0.459773 1.290824 -0.896144 +v -0.296416 0.592591 -0.896171 +v -0.282266 0.720114 -0.896171 +v -0.134350 0.885313 -0.896171 +v -0.137311 0.789518 -0.896171 +v -0.286936 0.809362 -0.896171 +v -0.297314 0.867663 -0.896171 +v -0.194029 0.949863 -0.896171 +v -0.154997 0.941854 -0.896171 +v -0.957912 -1.288898 -0.896171 +v -0.950041 -1.193915 -0.896171 +v -0.965826 -1.383853 -0.896171 +v -0.817353 -0.507894 -0.896171 +v -0.764535 -0.315730 -0.896171 +v -0.859344 -0.695510 -0.896171 +v -0.695111 -0.093624 -0.896171 +v -0.645198 0.940726 -0.896171 +v -0.633162 0.749095 -0.896171 +v -0.662563 1.103201 -0.896171 +v -0.715137 0.306292 -0.896171 +v -0.670116 0.455287 -0.896171 +v -0.641640 0.592549 -0.896171 +v -0.688657 1.307641 -0.896171 +v -0.685925 1.287389 -0.896171 +v -0.689840 1.315299 -0.896171 +v -1.258942 -1.033019 -0.896171 +v -1.257408 -0.946147 -0.896171 +v -1.260636 -1.119864 -0.896171 +v -1.295681 -1.056708 -0.896171 +v -1.300160 -0.982569 -0.896171 +v -1.292351 -0.923918 -0.896171 +v -0.998176 -0.016725 -0.896171 +v -1.077652 -0.197750 -0.896171 +v -1.134638 -0.171982 -0.896171 +v -1.053151 0.004648 -0.896171 +v -0.883667 0.745563 -0.896171 +v -0.900864 0.918654 -0.896171 +v -0.874400 0.928155 -0.896171 +v -0.856267 0.747458 -0.896171 +v -0.929842 1.076258 -0.896171 +v -0.904310 1.093316 -0.896171 +v -0.864710 1.126510 -0.896171 +v -0.846541 0.937567 -0.896171 +v -0.828825 0.748998 -0.896171 +v -0.963916 1.213121 -0.896171 +v -0.968620 1.231556 -0.896171 +v -0.947858 1.246189 -0.896171 +v -0.941924 1.228855 -0.896171 +v -0.967164 1.240450 -0.896171 +v -0.949795 1.253422 -0.896171 +v -1.011336 0.361720 -0.896171 +v -0.977286 0.352127 -0.896171 +v -0.941313 0.485550 -0.896171 +v -0.912227 0.479010 -0.896171 +v -0.883108 0.472568 -0.896171 +v -0.943184 0.342657 -0.896171 +v -0.896963 0.605390 -0.896171 +v -0.869461 0.602243 -0.896171 +v -0.841941 0.599091 -0.896171 +v -1.141357 -0.362303 -0.896171 +v -1.189813 -0.523468 -0.896171 +v -1.245241 -0.489253 -0.896171 +v -1.198515 -0.333280 -0.896171 +v -1.155872 -0.742999 -0.896171 +v -1.226533 -0.690426 -0.896171 +v -1.183088 -0.882998 -0.896171 +v -1.250856 -0.824675 -0.896171 +v -1.280799 -0.647638 -0.896171 +v -0.793411 -0.947535 -0.896171 +v -0.898551 -0.898728 -0.896171 +v -0.820044 -1.116959 -0.896172 +v -0.928641 -1.062357 -0.896171 +v -1.027374 -1.001985 -0.896171 +v -0.995118 -0.846227 -0.896171 +v -0.323532 -1.083933 -0.896171 +v -0.454850 -1.055616 -0.896171 +v -0.338861 -1.251143 -0.896172 +v -0.474365 -1.225018 -0.896172 +v -0.594002 -1.193677 -0.896172 +v -0.571878 -1.022915 -0.896171 +v 0.173037 -1.108193 -0.896172 +v -0.000750 -1.113149 -0.896171 +v 0.335354 -1.092800 -0.896171 +v 0.342328 -1.248773 -0.896172 +v 0.175862 -1.265972 -0.896171 +v -0.003270 -1.273652 -0.896172 +v 1.343841 -0.607976 -0.896171 +v 1.306811 -0.651080 -0.896171 +v 1.379841 -0.565393 -0.896171 +v 1.061704 -0.839854 -0.896171 +v 0.987078 -0.887350 -0.896171 +v 1.135514 -0.786890 -0.896171 +v 1.151812 -0.920169 -0.896171 +v 1.081508 -0.975870 -0.896171 +v 1.010259 -1.024393 -0.896171 +v 0.714996 -1.010068 -0.896171 +v 0.597472 -1.043279 -0.896171 +v 0.821096 -0.972400 -0.896171 +v 0.840846 -1.118436 -0.896172 +v 0.731563 -1.160511 -0.896171 +v 0.610974 -1.196660 -0.896172 +v -0.170016 -1.104316 -0.896171 +v -0.179146 -1.268276 -0.896172 +v -1.327040 -0.582335 -0.896171 +v -1.362330 -0.534146 -0.896171 +v -1.348298 -0.653935 -0.896171 +v -1.378255 -0.625107 -0.896171 +v -1.403685 -0.568336 -0.896171 +v -1.397511 -0.485432 -0.896171 +v -1.079628 -0.794900 -0.896171 +v -1.110610 -0.942781 -0.896171 +v -0.684159 -0.987993 -0.896171 +v -0.708289 -1.159336 -0.896172 +v 0.456186 -0.867273 -0.896171 +v 0.474096 -1.070914 -0.896171 +v 0.484504 -1.225787 -0.896171 +v 0.491625 -1.353516 -0.896171 +v 0.494106 -1.449703 -0.896172 +v 0.496573 -1.545897 -0.896171 +v 0.307674 0.056937 -0.896171 +v 0.347049 -0.161976 -0.896171 +v 0.392237 -0.425170 -0.896171 +v 0.429265 -0.657096 -0.896171 +v 0.428777 0.733266 -0.896171 +v 0.442560 0.835030 -0.896171 +v 0.396063 0.735674 -0.896171 +v 0.415633 0.833005 -0.896171 +v 0.431235 0.892275 -0.896171 +v 0.455075 0.909064 -0.896171 +v 0.462844 1.013479 -0.896171 +v 0.478296 1.143331 -0.896171 +v 0.494490 1.270408 -0.896171 +v 0.438943 0.321788 -0.896171 +v 0.376621 0.328880 -0.896171 +v 0.369799 0.494520 -0.896171 +v 0.425152 0.489640 -0.896171 +v 0.422277 0.621671 -0.896171 +v 0.377937 0.625899 -0.896171 +v 1.177763 -0.560657 -0.896171 +v 1.205622 -0.729354 -0.896171 +v 1.229723 -0.523256 -0.896171 +v 1.257208 -0.683789 -0.896171 +v 1.260525 -0.788262 -0.896171 +v 1.220113 -0.852158 -0.896171 +v 1.231482 -0.957355 -0.896171 +v 1.221664 -1.057584 -0.896171 +v 1.211405 -1.155321 -0.896171 +v 0.986605 -0.012328 -0.896171 +v 1.037311 0.014016 -0.896171 +v 1.118434 -0.166172 -0.896171 +v 1.068359 -0.199197 -0.896171 +v 0.858453 0.717667 -0.896171 +v 0.831260 0.718823 -0.896171 +v 0.837018 0.844903 -0.896171 +v 0.867320 0.843579 -0.896171 +v 0.804027 0.719624 -0.896171 +v 0.805884 0.844217 -0.896171 +v 0.848006 0.971180 -0.896171 +v 0.887354 0.963929 -0.896171 +v 0.849423 1.087589 -0.896171 +v 0.899988 1.066735 -0.896171 +v 0.845146 1.171931 -0.896171 +v 0.893771 1.132315 -0.896171 +v 0.958856 0.351928 -0.896171 +v 0.994002 0.354887 -0.896171 +v 0.923634 0.349139 -0.896171 +v 0.861345 0.480792 -0.896171 +v 0.891924 0.477962 -0.896171 +v 0.922454 0.475271 -0.896171 +v 0.848563 0.598029 -0.896171 +v 0.876157 0.595012 -0.896171 +v 0.820946 0.601065 -0.896171 +v 1.132500 -0.382085 -0.896171 +v 1.183087 -0.347070 -0.896171 +v 0.875268 -0.744601 -0.896171 +v 0.909606 -0.931407 -0.896171 +v 0.932302 -1.072214 -0.896171 +v 0.947454 -1.190135 -0.896171 +v 0.951009 -1.281884 -0.896171 +v 0.957008 -1.372901 -0.896165 +v 0.769273 -0.341809 -0.896171 +v 0.829762 -0.550239 -0.896171 +v 0.693800 -0.110240 -0.896171 +v 0.611216 0.715988 -0.896171 +v 0.618518 0.829614 -0.896171 +v 0.627887 0.917161 -0.896171 +v 0.689367 0.317784 -0.896171 +v 0.639314 0.471691 -0.896171 +v 0.615230 0.599688 -0.896171 +v 0.636632 1.035185 -0.896171 +v 0.644527 1.175203 -0.896171 +v 0.652825 1.315196 -0.896171 +v 1.152023 -1.273431 -0.864418 +v 1.153331 -1.274761 -0.865433 +v 1.213576 -1.209562 -0.865433 +v 1.212151 -1.208361 -0.864418 +v 1.153331 -1.274761 -0.865433 +v 1.153517 -1.274951 -0.868182 +v 1.213780 -1.209734 -0.868182 +v 1.213576 -1.209562 -0.865433 +v 1.274071 -1.129514 -0.868182 +v 1.273849 -1.129367 -0.865433 +v 1.273849 -1.129367 -0.865433 +v 1.272298 -1.128336 -0.864418 +v -0.375238 -1.629885 -0.864418 +v -0.375468 -1.631737 -0.865433 +v -0.200696 -1.644893 -0.865433 +v -0.200590 -1.643029 -0.864418 +v -0.375468 -1.631737 -0.865433 +v -0.375500 -1.632002 -0.868182 +v -0.200711 -1.645158 -0.868182 +v -0.200696 -1.644893 -0.865433 +v -0.008951 -1.649528 -0.868182 +v -0.008953 -1.649261 -0.865433 +v -0.008953 -1.649261 -0.865433 +v -0.008966 -1.647396 -0.864418 +v 1.105175 0.236585 -0.864418 +v 1.106771 0.237566 -0.865432 +v 1.019704 0.361089 -0.865432 +v 1.018077 0.360147 -0.864417 +v 1.106771 0.237566 -0.865432 +v 1.106999 0.237706 -0.868182 +v 1.019936 0.361223 -0.868182 +v 1.019704 0.361089 -0.865432 +v 0.946504 0.477860 -0.868182 +v 0.946260 0.477751 -0.865432 +v 0.946260 0.477751 -0.865432 +v 0.944551 0.476988 -0.864417 +v -0.630017 1.325748 -0.864417 +v -0.630779 1.327475 -0.865432 +v -0.693820 1.326854 -0.865432 +v -0.693116 1.325099 -0.864417 +v -0.630779 1.327475 -0.865432 +v -0.630888 1.327722 -0.868182 +v -0.693920 1.327105 -0.868182 +v -0.693820 1.326854 -0.865432 +v -0.763680 1.313608 -0.868182 +v -0.763615 1.313344 -0.865432 +v -0.763615 1.313344 -0.865432 +v -0.763157 1.311498 -0.864417 +v -1.121889 0.234333 -0.864417 +v -1.123513 0.235263 -0.865432 +v -1.211266 0.083500 -0.865432 +v -1.209621 0.082617 -0.864417 +v -1.123513 0.235263 -0.865432 +v -1.123745 0.235396 -0.868182 +v -1.211502 0.083626 -0.868182 +v -1.211266 0.083500 -0.865432 +v -1.211266 0.083500 -0.865432 +v -1.211502 0.083626 -0.868182 +v -1.290247 -0.070380 -0.868182 +v -1.290005 -0.070492 -0.865432 +v -1.290005 -0.070492 -0.865432 +v -1.288310 -0.071272 -0.864417 +v 0.048676 1.122694 -0.864417 +v 0.049667 1.124257 -0.865432 +v 0.016367 1.216638 -0.865432 +v 0.014968 1.215437 -0.864417 +v 0.049667 1.124257 -0.865432 +v 0.049809 1.124480 -0.868182 +v 0.016567 1.216809 -0.868182 +v 0.016367 1.216638 -0.865432 +v -0.028630 1.285300 -0.868182 +v -0.028872 1.285194 -0.865432 +v -0.028872 1.285194 -0.865432 +v -0.030560 1.284445 -0.864417 +v -1.067371 -1.375639 -0.864418 +v -1.068499 -1.377125 -0.865433 +v -0.974678 -1.439266 -0.865433 +v -0.973699 -1.437678 -0.864418 +v -1.068499 -1.377125 -0.865433 +v -1.068659 -1.377337 -0.868182 +v -0.974817 -1.439492 -0.868182 +v -0.974678 -1.439266 -0.865433 +v -0.868623 -1.497648 -0.868182 +v -0.868505 -1.497409 -0.865433 +v -0.868505 -1.497409 -0.865433 +v -0.867682 -1.495737 -0.864418 +v -0.910086 1.282604 -0.864417 +v -0.910473 1.284506 -0.865432 +v -0.956725 1.265079 -0.865432 +v -0.955577 1.263121 -0.864417 +v -0.910473 1.284506 -0.865432 +v -0.910528 1.284777 -0.868182 +v -0.956889 1.265358 -0.868182 +v -0.956725 1.265079 -0.865432 +v -0.981335 1.247422 -0.868182 +v -0.981052 1.247136 -0.865432 +v -0.981052 1.247136 -0.865432 +v -0.979069 1.245134 -0.864417 +v -0.630888 1.327722 -0.892043 +v -0.630779 1.327475 -0.894793 +v -0.693820 1.326854 -0.894793 +v -0.693920 1.327105 -0.892043 +v -0.630779 1.327475 -0.894793 +v -0.630017 1.325748 -0.895808 +v -0.693116 1.325099 -0.895808 +v -0.693820 1.326854 -0.894793 +v -0.763157 1.311498 -0.895808 +v -0.763615 1.313344 -0.894793 +v -0.763615 1.313344 -0.894793 +v -0.763680 1.313608 -0.892043 +v 0.475924 1.302464 -0.864417 +v 0.475499 1.304291 -0.865432 +v 0.430907 1.267789 -0.865432 +v 0.431947 1.266075 -0.864417 +v 0.475499 1.304291 -0.865432 +v 0.475438 1.304552 -0.868182 +v 0.430758 1.268034 -0.868182 +v 0.430907 1.267789 -0.865432 +v 0.378711 1.218174 -0.868182 +v 0.378938 1.217968 -0.865432 +v 0.378938 1.217968 -0.865432 +v 0.380524 1.216533 -0.864417 +v -0.641081 -1.582094 -0.864418 +v -0.641593 -1.583888 -0.865433 +v -0.518986 -1.611859 -0.865433 +v -0.518621 -1.610029 -0.864418 +v -0.641593 -1.583888 -0.865433 +v -0.641666 -1.584145 -0.868182 +v -0.519038 -1.612120 -0.868182 +v -0.518986 -1.611859 -0.865433 +v -0.514200 1.290207 -0.864417 +v -0.514306 1.292173 -0.865432 +v -0.570719 1.307347 -0.865432 +v -0.570194 1.305492 -0.864417 +v -0.514306 1.292173 -0.865432 +v -0.514321 1.292454 -0.868182 +v -0.570795 1.307612 -0.868182 +v -0.570719 1.307347 -0.865432 +v 0.690974 1.373821 -0.864417 +v 0.691122 1.375733 -0.865432 +v 0.659317 1.394394 -0.865432 +v 0.658855 1.392554 -0.864417 +v 0.691122 1.375733 -0.865432 +v 0.691143 1.376006 -0.868182 +v 0.659383 1.394658 -0.868182 +v 0.659317 1.394394 -0.865432 +v 0.659317 1.394394 -0.865432 +v 0.659383 1.394658 -0.868182 +v 0.619198 1.397647 -0.868182 +v 0.619109 1.397394 -0.865432 +v 0.619109 1.397394 -0.865432 +v 0.618485 1.395620 -0.864417 +v 0.300975 1.070195 -0.864417 +v 0.299137 1.070764 -0.865432 +v 0.275049 1.030093 -0.865432 +v 0.276788 1.028775 -0.864417 +v 0.299137 1.070764 -0.865432 +v 0.298874 1.070844 -0.868182 +v 0.274801 1.030281 -0.868182 +v 0.275049 1.030093 -0.865432 +v 0.257059 1.023417 -0.868182 +v 0.257249 1.022459 -0.865432 +v 0.257249 1.022459 -0.865432 +v 0.258581 1.015747 -0.864417 +v -0.949433 1.069155 -0.864417 +v -0.951368 1.069233 -0.865432 +v -0.923316 0.913687 -0.865432 +v -0.921437 0.913772 -0.864417 +v -0.951368 1.069233 -0.865432 +v -0.951644 1.069244 -0.868182 +v -0.923584 0.913675 -0.868182 +v -0.923316 0.913687 -0.865432 +v -0.906959 0.745264 -0.868182 +v -0.906693 0.745245 -0.865432 +v -0.906693 0.745245 -0.865432 +v -0.904827 0.745113 -0.864417 +v 1.032111 -1.373576 -0.864418 +v 1.033213 -1.375080 -0.865433 +v 1.095159 -1.327308 -0.865433 +v 1.093955 -1.325882 -0.864418 +v 1.033213 -1.375080 -0.865433 +v 1.033371 -1.375295 -0.868182 +v 1.095331 -1.327512 -0.868182 +v 1.095159 -1.327308 -0.865433 +v -0.840984 1.299678 -0.865432 +v -0.840755 1.297795 -0.864417 +v -0.841017 1.299947 -0.868182 +v -0.840984 1.299678 -0.865432 +v 0.333776 1.143266 -0.865432 +v 0.335597 1.142318 -0.864417 +v 0.333515 1.143402 -0.868182 +v 0.333776 1.143266 -0.865432 +v 0.333776 1.143266 -0.865432 +v 0.333515 1.143402 -0.868182 +v 0.298874 1.070844 -0.868182 +v 0.299137 1.070764 -0.865432 +v 0.239733 1.036787 -0.865432 +v 0.240243 1.018790 -0.864417 +v 0.257249 1.022459 -0.865432 +v 0.257059 1.023417 -0.868182 +v 0.239660 1.039358 -0.868182 +v 0.239733 1.036787 -0.865432 +v 0.239660 1.039358 -0.868182 +v 0.213855 1.044876 -0.868182 +v 0.213826 1.041323 -0.865432 +v 0.213624 1.016454 -0.864417 +v 0.629975 -1.568355 -0.864418 +v 0.630521 -1.570138 -0.865433 +v 0.755937 -1.526811 -0.865433 +v 0.755231 -1.525084 -0.864418 +v 0.630521 -1.570138 -0.865433 +v 0.630599 -1.570393 -0.868182 +v 0.756038 -1.527058 -0.868182 +v 0.755937 -1.526811 -0.865433 +v 0.868736 -1.477215 -0.868182 +v 0.868613 -1.476979 -0.865433 +v 0.868613 -1.476979 -0.865433 +v 0.867754 -1.475321 -0.864418 +v -0.982481 1.211838 -0.864417 +v -0.984776 1.213400 -0.865432 +v -0.972568 1.165903 -0.865432 +v -0.970460 1.165121 -0.864417 +v -0.984776 1.213400 -0.865432 +v -0.985104 1.213622 -0.868182 +v -0.972868 1.166014 -0.868182 +v -0.972568 1.165903 -0.865432 +v 1.106999 0.237706 -0.892043 +v 1.106771 0.237566 -0.894794 +v 1.019703 0.361089 -0.894793 +v 1.019936 0.361223 -0.892043 +v 1.106771 0.237566 -0.894794 +v 1.105175 0.236585 -0.895808 +v 1.018077 0.360148 -0.895808 +v 1.019703 0.361089 -0.894793 +v 0.944551 0.476988 -0.895808 +v 0.946260 0.477751 -0.894793 +v 0.946260 0.477751 -0.894793 +v 0.946504 0.477860 -0.892043 +v -0.375500 -1.632002 -0.892044 +v -0.375468 -1.631737 -0.894794 +v -0.200696 -1.644893 -0.894794 +v -0.200711 -1.645158 -0.892044 +v -0.375468 -1.631737 -0.894794 +v -0.375238 -1.629885 -0.895808 +v -0.200590 -1.643029 -0.895808 +v -0.200696 -1.644893 -0.894794 +v -0.008966 -1.647396 -0.895808 +v -0.008953 -1.649261 -0.894794 +v -0.008953 -1.649261 -0.894794 +v -0.008951 -1.649528 -0.892044 +v -1.440577 -0.579309 -0.864417 +v -1.442436 -0.579189 -0.865432 +v -1.444589 -0.690706 -0.865432 +v -1.442729 -0.690593 -0.864417 +v -1.442436 -0.579189 -0.865432 +v -1.442701 -0.579173 -0.868182 +v -1.444854 -0.690722 -0.868182 +v -1.444589 -0.690706 -0.865432 +v -1.428460 -0.808262 -0.868182 +v -1.428199 -0.808209 -0.865432 +v -1.428199 -0.808209 -0.865432 +v -1.426371 -0.807843 -0.864417 +v 0.352679 -1.625066 -0.864418 +v 0.352940 -1.626914 -0.865433 +v 0.499623 -1.603175 -0.865433 +v 0.499226 -1.601352 -0.864418 +v 0.352940 -1.626914 -0.865433 +v 0.352978 -1.627177 -0.868182 +v 0.499680 -1.603436 -0.868182 +v 0.499623 -1.603175 -0.865433 +v -1.396002 -0.343167 -0.864417 +v -1.397800 -0.342668 -0.865432 +v -1.427103 -0.464238 -0.865432 +v -1.425267 -0.464561 -0.864417 +v -1.397800 -0.342668 -0.865432 +v -1.398057 -0.342597 -0.868182 +v -1.427365 -0.464191 -0.868182 +v -1.427103 -0.464238 -0.865432 +v 0.180480 -1.642793 -0.865433 +v 0.180345 -1.640931 -0.864418 +v 0.180499 -1.643058 -0.868182 +v 0.180480 -1.642793 -0.865433 +v -0.910528 1.284777 -0.892043 +v -0.910473 1.284506 -0.894793 +v -0.956725 1.265079 -0.894793 +v -0.956889 1.265358 -0.892043 +v -0.910473 1.284506 -0.894793 +v -0.910086 1.282604 -0.895808 +v -0.955577 1.263121 -0.895808 +v -0.956725 1.265079 -0.894793 +v -0.979069 1.245134 -0.895808 +v -0.981052 1.247136 -0.894793 +v -0.981052 1.247136 -0.894793 +v -0.981335 1.247422 -0.892043 +v 0.879524 0.717494 -0.864417 +v 0.881392 0.717602 -0.865432 +v 0.891749 0.842334 -0.865432 +v 0.889866 0.842435 -0.864417 +v 0.881392 0.717602 -0.865432 +v 0.881660 0.717617 -0.868182 +v 0.892018 0.842319 -0.868182 +v 0.891749 0.842334 -0.865432 +v 0.916469 0.961303 -0.868182 +v 0.916189 0.961277 -0.865432 +v 0.916189 0.961277 -0.865432 +v 0.914225 0.961090 -0.864417 +v 0.180480 -1.642793 -0.894794 +v 0.180499 -1.643058 -0.892044 +v 0.180345 -1.640931 -0.895808 +v 0.180480 -1.642793 -0.894794 +v 0.352679 -1.625066 -0.895808 +v 0.352940 -1.626914 -0.894794 +v 0.352940 -1.626914 -0.894794 +v 0.352978 -1.627177 -0.892044 +v -1.068659 -1.377337 -0.892044 +v -1.068499 -1.377125 -0.894794 +v -0.974678 -1.439266 -0.894794 +v -0.974817 -1.439492 -0.892044 +v -1.068499 -1.377125 -0.894794 +v -1.067371 -1.375639 -0.895808 +v -0.973699 -1.437678 -0.895808 +v -0.974678 -1.439266 -0.894794 +v -0.867682 -1.495737 -0.895808 +v -0.868505 -1.497409 -0.894794 +v -0.868505 -1.497409 -0.894794 +v -0.868623 -1.497648 -0.892044 +v -1.123745 0.235396 -0.892043 +v -1.123513 0.235263 -0.894794 +v -1.211266 0.083500 -0.894794 +v -1.211502 0.083626 -0.892043 +v -1.123513 0.235263 -0.894794 +v -1.121889 0.234333 -0.895808 +v -1.209621 0.082617 -0.895808 +v -1.211266 0.083500 -0.894794 +v -1.288310 -0.071272 -0.895808 +v -1.290005 -0.070492 -0.894793 +v -1.211502 0.083626 -0.892043 +v -1.211266 0.083500 -0.894794 +v -1.290005 -0.070492 -0.894793 +v -1.290247 -0.070380 -0.892043 +v 1.271741 -0.060070 -0.864417 +v 1.273450 -0.059323 -0.865432 +v 1.194026 0.098697 -0.865432 +v 1.192391 0.097795 -0.864417 +v 1.273450 -0.059323 -0.865432 +v 1.273694 -0.059216 -0.868182 +v 1.194259 0.098826 -0.868182 +v 1.194026 0.098697 -0.865432 +v -1.389189 -0.937265 -0.865432 +v -1.387435 -0.936641 -0.864417 +v -1.389440 -0.937354 -0.868182 +v -1.389189 -0.937265 -0.865432 +v -1.335017 -1.061893 -0.868182 +v -1.334781 -1.061771 -0.865432 +v -1.334781 -1.061771 -0.865432 +v -1.333130 -1.060908 -0.864417 +v -0.962745 0.491738 -0.864417 +v -0.964468 0.492465 -0.865432 +v -1.036629 0.370964 -0.865432 +v -1.034975 0.370077 -0.864417 +v -0.964468 0.492465 -0.865432 +v -0.964714 0.492569 -0.868182 +v -1.036866 0.371091 -0.868182 +v -1.036629 0.370964 -0.865432 +v 1.329532 -1.033505 -0.865432 +v 1.327856 -1.032692 -0.864417 +v 1.329771 -1.033620 -0.868182 +v 1.329532 -1.033505 -0.865432 +v 1.373869 -0.922570 -0.868182 +v 1.373615 -0.922490 -0.865432 +v 1.373615 -0.922490 -0.865432 +v 1.371837 -0.921925 -0.864417 +v 0.770000 1.277696 -0.864417 +v 0.770090 1.279678 -0.865432 +v 0.720902 1.334489 -0.865432 +v 0.721019 1.332582 -0.864417 +v 0.770090 1.279678 -0.865432 +v 0.770103 1.279960 -0.868182 +v 0.720885 1.334761 -0.868182 +v 0.720902 1.334489 -0.865432 +v -0.270661 1.311740 -0.864417 +v -0.268449 1.312462 -0.865432 +v -0.285244 1.318410 -0.865432 +v -0.287488 1.317492 -0.864417 +v -0.268449 1.312462 -0.865432 +v -0.268133 1.312565 -0.868182 +v -0.284924 1.318541 -0.868182 +v -0.285244 1.318410 -0.865432 +v -0.305086 1.324731 -0.868182 +v -0.305378 1.324578 -0.865432 +v -0.305378 1.324578 -0.865432 +v -0.307421 1.323511 -0.864417 +v 1.400280 -0.798689 -0.865432 +v 1.398443 -0.798380 -0.864417 +v 1.373615 -0.922490 -0.865432 +v 1.373869 -0.922570 -0.868182 +v 1.400542 -0.798734 -0.868182 +v 1.400280 -0.798689 -0.865432 +v 1.411122 -0.670719 -0.868182 +v 1.410856 -0.670709 -0.865432 +v 1.410856 -0.670709 -0.865432 +v 1.408996 -0.670644 -0.864417 +v -1.428460 -0.808262 -0.892043 +v -1.426904 -0.808839 -0.894770 +v -1.389094 -0.933636 -0.894790 +v -1.389440 -0.937354 -0.892043 +v -1.426904 -0.808839 -0.894770 +v -1.389094 -0.933636 -0.894790 +v -1.334888 -1.059175 -0.894804 +v -1.334888 -1.059175 -0.894804 +v -1.335017 -1.061893 -0.892043 +v 0.935251 1.065346 -0.865432 +v 0.933114 1.064193 -0.864417 +v 0.935556 1.065511 -0.868182 +v 0.935251 1.065346 -0.865432 +v 0.919448 1.151937 -0.868182 +v 0.919173 1.151644 -0.865432 +v 0.919173 1.151644 -0.865432 +v 0.917241 1.149585 -0.864417 +v 0.475438 1.304552 -0.892043 +v 0.475499 1.304291 -0.894793 +v 0.430907 1.267789 -0.894793 +v 0.430758 1.268034 -0.892043 +v 0.475499 1.304291 -0.894793 +v 0.475924 1.302464 -0.895808 +v 0.431947 1.266075 -0.895808 +v 0.430907 1.267789 -0.894793 +v 0.380524 1.216533 -0.895808 +v 0.378938 1.217968 -0.894793 +v 0.378938 1.217968 -0.894793 +v 0.378711 1.218174 -0.892043 +v 0.916469 0.961303 -0.892043 +v 0.916189 0.961276 -0.894793 +v 0.935251 1.065347 -0.894793 +v 0.935556 1.065511 -0.892043 +v 0.916189 0.961276 -0.894793 +v 0.914225 0.961090 -0.895808 +v 0.933114 1.064193 -0.895808 +v 0.935251 1.065347 -0.894793 +v 0.917241 1.149585 -0.895808 +v 0.919173 1.151644 -0.894793 +v 0.919173 1.151644 -0.894793 +v 0.919448 1.151937 -0.892043 +v 0.298874 1.070844 -0.892043 +v 0.299137 1.070764 -0.894793 +v 0.275049 1.030093 -0.894793 +v 0.274801 1.030281 -0.892043 +v 0.299137 1.070764 -0.894793 +v 0.300975 1.070195 -0.895808 +v 0.276788 1.028775 -0.895808 +v 0.275049 1.030093 -0.894793 +v 0.258581 1.015747 -0.895808 +v 0.257249 1.022459 -0.894793 +v 0.257249 1.022459 -0.894793 +v 0.257059 1.023417 -0.892043 +v 0.127451 0.993025 -0.864417 +v 0.127747 1.000684 -0.865432 +v 0.085774 1.042081 -0.865432 +v 0.085225 1.039580 -0.864417 +v 0.127747 1.000684 -0.865432 +v 0.127789 1.001778 -0.868182 +v 0.085853 1.042438 -0.868182 +v 0.085774 1.042081 -0.865432 +v 1.373869 -0.922570 -0.892043 +v 1.373615 -0.922490 -0.894793 +v 1.400280 -0.798689 -0.894793 +v 1.400542 -0.798734 -0.892043 +v 1.373615 -0.922490 -0.894793 +v 1.371837 -0.921925 -0.895808 +v 1.398443 -0.798381 -0.895808 +v 1.400280 -0.798689 -0.894793 +v 1.408996 -0.670644 -0.895808 +v 1.410856 -0.670710 -0.894793 +v 1.410856 -0.670710 -0.894793 +v 1.411122 -0.670719 -0.892043 +v 0.898980 0.595768 -0.865432 +v 0.897174 0.595315 -0.864417 +v 0.899238 0.595832 -0.868182 +v 0.898980 0.595768 -0.865432 +v 0.528621 1.373829 -0.864417 +v 0.528922 1.375702 -0.865432 +v 0.502609 1.342879 -0.865432 +v 0.502603 1.341000 -0.864417 +v 0.528922 1.375702 -0.865432 +v 0.528965 1.375970 -0.868182 +v 0.502610 1.343147 -0.868182 +v 0.502609 1.342879 -0.865432 +v 0.881660 0.717617 -0.892043 +v 0.881392 0.717602 -0.894793 +v 0.891749 0.842334 -0.894793 +v 0.892018 0.842319 -0.892043 +v 0.881392 0.717602 -0.894793 +v 0.879524 0.717494 -0.895808 +v 0.889866 0.842435 -0.895808 +v 0.891749 0.842334 -0.894793 +v 0.049809 1.124480 -0.892043 +v 0.049667 1.124257 -0.894793 +v 0.016367 1.216638 -0.894793 +v 0.016567 1.216809 -0.892043 +v 0.049667 1.124257 -0.894793 +v 0.048676 1.122694 -0.895808 +v 0.014968 1.215437 -0.895808 +v 0.016367 1.216638 -0.894793 +v -0.030560 1.284445 -0.895808 +v -0.028872 1.285194 -0.894793 +v -0.028872 1.285194 -0.894793 +v -0.028630 1.285300 -0.892043 +v -0.906959 0.745264 -0.892043 +v -0.906693 0.745245 -0.894793 +v -0.919751 0.609207 -0.894793 +v -0.920009 0.609271 -0.892043 +v -0.906693 0.745245 -0.894793 +v -0.904827 0.745113 -0.895808 +v -0.917943 0.608758 -0.895808 +v -0.919751 0.609207 -0.894793 +v -0.962745 0.491738 -0.895808 +v -0.964468 0.492465 -0.894793 +v -0.964468 0.492465 -0.894793 +v -0.964714 0.492569 -0.892043 +v -1.273810 -1.164294 -0.894796 +v -1.274021 -1.164871 -0.892044 +v -1.271833 -1.162133 -0.895819 +v -1.273810 -1.164294 -0.894796 +v -1.208772 -1.245987 -0.895808 +v -1.210213 -1.247160 -0.894794 +v -1.210213 -1.247160 -0.894794 +v -1.210419 -1.247328 -0.892044 +v 0.571123 1.392596 -0.865432 +v 0.570584 1.390788 -0.864417 +v 0.571200 1.392854 -0.868182 +v 0.571123 1.392596 -0.865432 +v -0.350419 1.330546 -0.865432 +v -0.351954 1.329220 -0.864417 +v -0.350199 1.330735 -0.868182 +v -0.350419 1.330546 -0.865432 +v -0.407866 1.326149 -0.868182 +v -0.407996 1.325915 -0.865432 +v -0.407996 1.325915 -0.865432 +v -0.408906 1.324281 -0.864417 +v -0.310511 1.328699 -0.893822 +v -0.310966 1.327686 -0.895015 +v -0.349957 1.329152 -0.895051 +v -0.348585 1.331522 -0.894089 +v -0.389635 1.330800 -0.895026 +v -0.386534 1.334600 -0.893821 +v 0.173719 1.015060 -0.865432 +v 0.173383 0.996547 -0.864417 +v 0.213826 1.041323 -0.865432 +v 0.213855 1.044876 -0.868182 +v 0.173767 1.017705 -0.868182 +v 0.173719 1.015060 -0.865432 +v 0.127789 1.001778 -0.868182 +v 0.127747 1.000684 -0.865432 +v 0.850348 1.220585 -0.894793 +v 0.850493 1.220900 -0.892043 +v 0.849334 1.218380 -0.895808 +v 0.850348 1.220585 -0.894793 +v 0.770000 1.277696 -0.895808 +v 0.770090 1.279677 -0.894793 +v 0.770090 1.279677 -0.894793 +v 0.770103 1.279960 -0.892043 +v -0.028630 1.285300 -0.892043 +v -0.028872 1.285194 -0.894793 +v -0.096850 1.306666 -0.894793 +v -0.096589 1.306707 -0.892043 +v -0.098680 1.306384 -0.895808 +v -0.096850 1.306666 -0.894793 +v -0.098680 1.306384 -0.895808 +v -0.172767 1.304459 -0.895808 +v -0.170911 1.304331 -0.894793 +v -0.170646 1.304312 -0.892043 +v 1.406964 -0.543622 -0.894793 +v 1.407229 -0.543600 -0.892043 +v 1.405107 -0.543774 -0.895808 +v 1.406964 -0.543622 -0.894793 +v 1.382407 -0.402491 -0.895808 +v 1.384237 -0.402136 -0.894793 +v 1.384237 -0.402136 -0.894793 +v 1.384498 -0.402085 -0.892043 +v -1.352453 -0.212521 -0.894793 +v -1.352703 -0.212429 -0.892043 +v -1.350702 -0.213161 -0.895808 +v -1.352453 -0.212521 -0.894793 +v -1.395987 -0.343079 -0.895808 +v -1.397798 -0.342657 -0.894793 +v -1.397798 -0.342657 -0.894793 +v -1.398057 -0.342597 -0.892043 +v -0.268133 1.312565 -0.892043 +v -0.268385 1.312652 -0.894793 +v -0.282693 1.318332 -0.894793 +v -0.282444 1.318268 -0.892088 +v -0.268385 1.312652 -0.894793 +v -0.270150 1.313260 -0.895808 +v -0.284391 1.318911 -0.895777 +v -0.282693 1.318332 -0.894793 +v -0.282693 1.318332 -0.894793 +v -0.284391 1.318911 -0.895777 +v -0.286530 1.322087 -0.895627 +v -0.285476 1.322436 -0.894814 +v -0.285476 1.322436 -0.894814 +v -0.285241 1.322542 -0.892399 +v -0.096852 1.306661 -0.865432 +v -0.098693 1.306346 -0.864417 +v -0.028872 1.285194 -0.865432 +v -0.028630 1.285300 -0.868182 +v -0.096589 1.306707 -0.868182 +v -0.096852 1.306661 -0.865432 +v -0.170646 1.304312 -0.868182 +v -0.170924 1.304293 -0.865432 +v -0.098693 1.306346 -0.864417 +v -0.172868 1.304158 -0.864417 +v 0.850348 1.220585 -0.865432 +v 0.849334 1.218380 -0.864417 +v 0.850493 1.220900 -0.868182 +v 0.850348 1.220585 -0.865432 +v 0.257059 1.023417 -0.892043 +v 0.257249 1.022459 -0.894793 +v 0.239733 1.036787 -0.894793 +v 0.239660 1.039358 -0.892043 +v 0.240243 1.018790 -0.895808 +v 0.239733 1.036787 -0.894793 +v 0.213624 1.016454 -0.895808 +v 0.213826 1.041323 -0.894793 +v 0.239660 1.039358 -0.892043 +v 0.213855 1.044876 -0.892043 +v -0.919751 0.609207 -0.865432 +v -0.917943 0.608758 -0.864417 +v -0.920009 0.609271 -0.868182 +v -0.919751 0.609207 -0.865432 +v -0.964714 0.492569 -0.868182 +v -0.964468 0.492465 -0.865432 +v -1.273803 -1.164720 -0.865433 +v -1.272272 -1.163658 -0.864418 +v -1.274021 -1.164871 -0.868182 +v -1.273803 -1.164720 -0.865433 +v -1.210419 -1.247328 -0.868182 +v -1.210218 -1.247153 -0.865433 +v -1.210218 -1.247153 -0.865433 +v -1.208816 -1.245925 -0.864418 +v 1.382408 -0.402491 -0.864417 +v 1.384237 -0.402136 -0.865432 +v 1.338641 -0.233978 -0.865432 +v 1.336863 -0.234535 -0.864417 +v 1.384237 -0.402136 -0.865432 +v 1.384498 -0.402085 -0.868182 +v 1.338895 -0.233898 -0.868182 +v 1.338641 -0.233978 -0.865432 +v -0.427877 1.327997 -0.892399 +v -0.429520 1.326069 -0.894814 +v -0.464558 1.305059 -0.894793 +v -0.464324 1.305654 -0.892088 +v -0.429520 1.326069 -0.894814 +v -0.436253 1.319273 -0.895627 +v -0.464904 1.302197 -0.895777 +v -0.464558 1.305059 -0.894793 +v -0.513880 1.290050 -0.895808 +v -0.514266 1.292153 -0.894793 +v -0.514266 1.292153 -0.894793 +v -0.514321 1.292454 -0.892043 +v 0.213855 1.044876 -0.892043 +v 0.213826 1.041323 -0.894793 +v 0.173719 1.015060 -0.894793 +v 0.173767 1.017705 -0.892043 +v 0.173383 0.996547 -0.895808 +v 0.173719 1.015060 -0.894793 +v 0.127451 0.993025 -0.895808 +v 0.127747 1.000684 -0.894793 +v 0.127747 1.000684 -0.894793 +v 0.127789 1.001778 -0.892043 +v 0.619198 1.397647 -0.892043 +v 0.619109 1.397394 -0.894793 +v 0.571123 1.392596 -0.894793 +v 0.571200 1.392854 -0.892043 +v 0.619109 1.397394 -0.894793 +v 0.618485 1.395620 -0.895808 +v 0.570584 1.390788 -0.895808 +v 0.571123 1.392596 -0.894793 +v 0.528621 1.373829 -0.895808 +v 0.528922 1.375702 -0.894793 +v 0.528922 1.375702 -0.894793 +v 0.528965 1.375970 -0.892043 +v 0.898980 0.595768 -0.894793 +v 0.899238 0.595832 -0.892043 +v 0.897174 0.595315 -0.895808 +v 0.898980 0.595768 -0.894793 +v -1.144559 -1.315179 -0.894794 +v -1.144742 -1.315373 -0.892044 +v -1.143287 -1.313819 -0.895808 +v -1.144559 -1.315179 -0.894794 +v 0.691143 1.376006 -0.892043 +v 0.691122 1.375733 -0.894793 +v 0.659317 1.394394 -0.894793 +v 0.659383 1.394658 -0.892043 +v 0.691122 1.375733 -0.894793 +v 0.690974 1.373821 -0.895808 +v 0.658855 1.392554 -0.895808 +v 0.659317 1.394394 -0.894793 +v 0.659383 1.394658 -0.892043 +v 0.659317 1.394394 -0.894793 +v -1.352453 -0.212522 -0.865432 +v -1.350704 -0.213172 -0.864417 +v -1.352703 -0.212429 -0.868182 +v -1.352453 -0.212522 -0.865432 +v -1.442701 -0.579172 -0.892043 +v -1.441324 -0.582142 -0.894804 +v -1.442741 -0.694889 -0.894790 +v -1.444854 -0.690722 -0.892043 +v -1.441324 -0.582142 -0.894804 +v -1.442741 -0.694889 -0.894790 +v -1.426909 -0.464734 -0.894796 +v -1.427365 -0.464191 -0.892043 +v -1.424098 -0.466383 -0.895819 +v -1.426909 -0.464734 -0.894796 +v 0.932060 -1.443640 -0.895718 +v 0.915758 -1.447478 -0.895963 +v 0.966607 -1.410452 -0.896106 +v 0.972452 -1.416284 -0.895792 +v 1.029085 -1.365531 -0.896126 +v 1.033698 -1.372716 -0.895808 +v -0.757091 -1.545928 -0.894794 +v -0.757186 -1.546177 -0.892044 +v -0.756425 -1.544187 -0.895808 +v -0.757091 -1.545928 -0.894794 +v -0.641081 -1.582094 -0.895808 +v -0.641593 -1.583888 -0.894794 +v -0.757186 -1.546177 -0.892044 +v -0.757091 -1.545928 -0.894794 +v -0.641593 -1.583888 -0.894794 +v -0.641666 -1.584145 -0.892044 +v 1.274071 -1.129514 -0.892044 +v 1.273849 -1.129367 -0.894794 +v 1.329532 -1.033505 -0.894793 +v 1.329771 -1.033620 -0.892043 +v 1.273849 -1.129367 -0.894794 +v 1.272298 -1.128336 -0.895808 +v 1.327856 -1.032692 -0.895808 +v 1.329532 -1.033505 -0.894793 +v 1.373615 -0.922490 -0.894793 +v 1.373869 -0.922570 -0.892043 +v 0.499628 -1.603173 -0.894794 +v 0.499680 -1.603436 -0.892044 +v 0.499264 -1.601338 -0.895808 +v 0.499628 -1.603173 -0.894794 +v 0.630277 -1.568236 -0.895808 +v 0.630559 -1.570123 -0.894794 +v 0.630559 -1.570123 -0.894794 +v 0.630599 -1.570393 -0.892044 +v 0.753018 -1.528605 -0.894823 +v 0.756176 -1.527291 -0.892123 +v 0.750314 -1.527799 -0.895792 +v 0.753018 -1.528605 -0.894823 +v 0.823116 -1.499465 -0.895718 +v 0.844344 -1.491896 -0.895052 +v 0.844344 -1.491896 -0.895052 +v 0.875081 -1.476037 -0.892807 +v -0.951644 1.069244 -0.892043 +v -0.951368 1.069233 -0.894793 +v -0.923316 0.913687 -0.894793 +v -0.923584 0.913675 -0.892043 +v -0.951368 1.069233 -0.894793 +v -0.949433 1.069155 -0.895808 +v -0.921437 0.913772 -0.895808 +v -0.923316 0.913687 -0.894793 +v 1.406964 -0.543622 -0.865432 +v 1.405107 -0.543774 -0.864417 +v 1.407229 -0.543600 -0.868182 +v 1.406964 -0.543622 -0.865432 +v 0.959909 -1.425291 -0.865433 +v 0.958919 -1.423708 -0.864418 +v 0.960051 -1.425517 -0.868182 +v 0.959909 -1.425291 -0.865433 +v -0.985104 1.213622 -0.892043 +v -0.984776 1.213400 -0.894793 +v -0.972568 1.165903 -0.894793 +v -0.972868 1.166014 -0.892043 +v -0.984776 1.213400 -0.894793 +v -0.982481 1.211838 -0.895808 +v -0.970460 1.165121 -0.895808 +v -0.972568 1.165903 -0.894793 +v 0.333776 1.143266 -0.894793 +v 0.333515 1.143402 -0.892043 +v 0.335597 1.142318 -0.895808 +v 0.333776 1.143266 -0.894793 +v 0.333515 1.143402 -0.892043 +v 0.333776 1.143266 -0.894793 +v 0.299137 1.070764 -0.894793 +v 0.298874 1.070844 -0.892043 +v 0.720902 1.334489 -0.894793 +v 0.720885 1.334761 -0.892043 +v 0.721019 1.332582 -0.895808 +v 0.720902 1.334489 -0.894793 +v -0.461874 1.305154 -0.865432 +v -0.462240 1.303274 -0.864417 +v -0.461823 1.305423 -0.868182 +v -0.461874 1.305154 -0.865432 +v -0.757091 -1.545929 -0.865433 +v -0.756425 -1.544187 -0.864418 +v -0.757186 -1.546177 -0.868182 +v -0.757091 -1.545929 -0.865433 +v -0.757091 -1.545929 -0.865433 +v -0.757186 -1.546177 -0.868182 +v 0.502609 1.342879 -0.894793 +v 0.502610 1.343147 -0.892043 +v 0.502603 1.341000 -0.895808 +v 0.502609 1.342879 -0.894793 +v 1.338641 -0.233978 -0.894793 +v 1.338895 -0.233898 -0.892043 +v 1.336863 -0.234535 -0.895808 +v 1.338641 -0.233978 -0.894793 +v 1.271741 -0.060070 -0.895808 +v 1.273450 -0.059323 -0.894793 +v 1.273450 -0.059323 -0.894793 +v 1.273694 -0.059216 -0.892043 +v -0.840984 1.299678 -0.894793 +v -0.841017 1.299947 -0.892043 +v -0.840755 1.297795 -0.895808 +v -0.840984 1.299678 -0.894793 +v -1.144560 -1.315178 -0.865433 +v -1.143292 -1.313811 -0.864418 +v -1.144742 -1.315373 -0.868182 +v -1.144560 -1.315178 -0.865433 +v 0.127789 1.001778 -0.892043 +v 0.127747 1.000684 -0.894793 +v 0.085774 1.042081 -0.894793 +v 0.085853 1.042438 -0.892043 +v 0.085225 1.039580 -0.895808 +v 0.085774 1.042081 -0.894793 +v -0.964714 0.492569 -0.892043 +v -0.964468 0.492465 -0.894793 +v -1.036629 0.370964 -0.894793 +v -1.036866 0.371091 -0.892043 +v -1.034975 0.370077 -0.895808 +v -1.036629 0.370964 -0.894793 +v -0.570714 1.307344 -0.894793 +v -0.570795 1.307612 -0.892043 +v -0.570155 1.305473 -0.895808 +v -0.570714 1.307344 -0.894793 +v 1.194026 0.098697 -0.894794 +v 1.194259 0.098826 -0.892043 +v 1.192391 0.097795 -0.895808 +v 1.194026 0.098697 -0.894794 +v -0.518986 -1.611859 -0.894794 +v -0.519038 -1.612120 -0.892044 +v -0.518621 -1.610029 -0.895808 +v -0.518986 -1.611859 -0.894794 +v 1.033960 -1.374896 -0.892044 +v 1.034810 -1.374024 -0.894794 +v 1.095279 -1.327240 -0.894794 +v 1.095405 -1.327462 -0.892044 +v 1.034810 -1.374024 -0.894794 +v 1.093518 -1.326284 -0.895808 +v 1.095279 -1.327240 -0.894794 +v 1.151755 -1.273645 -0.895808 +v 1.153297 -1.274788 -0.894794 +v 1.153297 -1.274788 -0.894794 +v 1.153517 -1.274951 -0.892044 +v -0.964715 0.492569 -0.886809 +v -0.920009 0.609271 -0.886809 +v -0.964714 0.492569 -0.880113 +v -0.920009 0.609271 -0.880113 +v -0.906959 0.745264 -0.880113 +v -0.906959 0.745264 -0.886809 +v -0.964715 0.492569 -0.873416 +v -0.920009 0.609271 -0.873416 +v -0.906959 0.745264 -0.873416 +v -1.210419 -1.247328 -0.886810 +v -1.274021 -1.164871 -0.886810 +v -1.210419 -1.247328 -0.880113 +v -1.274022 -1.164871 -0.880113 +v -1.335017 -1.061893 -0.880113 +v -1.335017 -1.061893 -0.886810 +v -1.210419 -1.247328 -0.873416 +v -1.274021 -1.164871 -0.873416 +v -1.335017 -1.061893 -0.873416 +v 0.378711 1.218174 -0.886809 +v 0.430758 1.268034 -0.886809 +v 0.378711 1.218174 -0.880113 +v 0.430758 1.268034 -0.880113 +v 0.475438 1.304552 -0.880113 +v 0.475438 1.304552 -0.886809 +v 0.378711 1.218174 -0.873416 +v 0.430758 1.268034 -0.873416 +v 0.475438 1.304551 -0.873416 +v 0.916469 0.961303 -0.886809 +v 0.892018 0.842319 -0.886809 +v 0.916469 0.961303 -0.880113 +v 0.892018 0.842319 -0.880113 +v 0.881660 0.717617 -0.880113 +v 0.881660 0.717617 -0.886809 +v 0.916469 0.961303 -0.873416 +v 0.892018 0.842319 -0.873416 +v 0.881660 0.717617 -0.873416 +v -0.386534 1.334600 -0.893821 +v -0.384456 1.335638 -0.892280 +v -0.348166 1.332378 -0.893002 +v -0.348585 1.331522 -0.894089 +v -0.376931 1.335284 -0.890519 +v -0.348107 1.332500 -0.890796 +v -0.319283 1.329718 -0.890519 +v -0.311862 1.329151 -0.892280 +v -0.310511 1.328699 -0.893822 +v -0.408502 1.330085 -0.881393 +v -0.407956 1.326581 -0.873512 +v -0.350074 1.330841 -0.873451 +v -0.349348 1.331453 -0.880214 +v -0.304494 1.324722 -0.873512 +v -0.299763 1.324748 -0.881393 +v -0.028630 1.285300 -0.886809 +v 0.016567 1.216809 -0.886809 +v -0.028630 1.285300 -0.880113 +v 0.016567 1.216809 -0.880113 +v 0.049809 1.124481 -0.880113 +v 0.049809 1.124481 -0.886809 +v -0.028630 1.285300 -0.873416 +v 0.016567 1.216809 -0.873416 +v 0.049809 1.124481 -0.873416 +v 0.770103 1.279961 -0.886809 +v 0.850493 1.220899 -0.886809 +v 0.770103 1.279960 -0.880113 +v 0.850493 1.220900 -0.880113 +v 0.919448 1.151937 -0.880113 +v 0.919448 1.151937 -0.886809 +v 0.770103 1.279961 -0.873416 +v 0.850493 1.220899 -0.873416 +v 0.919448 1.151937 -0.873416 +v -0.170646 1.304312 -0.886809 +v -0.096589 1.306707 -0.886809 +v -0.170646 1.304312 -0.880113 +v -0.096589 1.306707 -0.880113 +v -0.028630 1.285300 -0.880113 +v -0.028630 1.285300 -0.886809 +v -0.170646 1.304312 -0.873416 +v -0.096589 1.306707 -0.873416 +v -0.028630 1.285300 -0.873416 +v 1.384498 -0.402085 -0.886810 +v 1.407229 -0.543600 -0.886810 +v 1.384498 -0.402085 -0.880113 +v 1.407229 -0.543600 -0.880113 +v 1.411122 -0.670719 -0.880113 +v 1.411122 -0.670719 -0.886810 +v 1.384498 -0.402085 -0.873416 +v 1.407229 -0.543600 -0.873416 +v 1.411122 -0.670719 -0.873416 +v 0.935556 1.065511 -0.886809 +v 0.935556 1.065511 -0.880113 +v 0.935556 1.065511 -0.873416 +v -1.398057 -0.342597 -0.886810 +v -1.352703 -0.212429 -0.886810 +v -1.398057 -0.342597 -0.880113 +v -1.352703 -0.212429 -0.880113 +v -1.290247 -0.070380 -0.880113 +v -1.290247 -0.070380 -0.886810 +v -1.398057 -0.342597 -0.873416 +v -1.352703 -0.212429 -0.873416 +v -1.290247 -0.070380 -0.873416 +v 1.400543 -0.798734 -0.886810 +v 1.400542 -0.798734 -0.880113 +v 1.373869 -0.922570 -0.880113 +v 1.373869 -0.922570 -0.886810 +v 1.400543 -0.798734 -0.873416 +v 1.373869 -0.922570 -0.873416 +v -0.268133 1.312565 -0.892043 +v -0.268133 1.312565 -0.886809 +v -0.230423 1.306132 -0.886809 +v -0.230422 1.306132 -0.892043 +v -0.268133 1.312565 -0.880113 +v -0.230422 1.306132 -0.880113 +v -0.268133 1.312565 -0.873416 +v -0.230423 1.306132 -0.873416 +v -0.230422 1.306132 -0.868182 +v 0.619198 1.397647 -0.886809 +v 0.659383 1.394658 -0.886809 +v 0.619198 1.397647 -0.880113 +v 0.659383 1.394658 -0.880113 +v 0.659383 1.394658 -0.886809 +v 0.659383 1.394658 -0.880113 +v 0.691144 1.376006 -0.880113 +v 0.691143 1.376006 -0.886809 +v 0.619198 1.397647 -0.873416 +v 0.659383 1.394658 -0.873416 +v 0.659383 1.394658 -0.873416 +v 0.691143 1.376006 -0.873416 +v 1.373869 -0.922570 -0.886810 +v 1.329772 -1.033621 -0.886810 +v 1.373869 -0.922570 -0.880113 +v 1.329772 -1.033621 -0.880113 +v 1.274071 -1.129514 -0.880113 +v 1.274071 -1.129514 -0.886810 +v 1.373869 -0.922570 -0.873416 +v 1.329772 -1.033621 -0.873416 +v 1.274071 -1.129514 -0.873416 +v -1.211501 0.083626 -0.886810 +v -1.211502 0.083626 -0.880113 +v -1.211501 0.083626 -0.886810 +v -1.211502 0.083626 -0.880113 +v -1.123745 0.235396 -0.880113 +v -1.123745 0.235396 -0.886810 +v -1.211501 0.083626 -0.873416 +v -1.211501 0.083626 -0.873416 +v -1.123745 0.235396 -0.873416 +v -1.389440 -0.937354 -0.886810 +v -1.389440 -0.937354 -0.880113 +v -1.428460 -0.808262 -0.880113 +v -1.428460 -0.808262 -0.886810 +v -1.389440 -0.937354 -0.873416 +v -1.428460 -0.808262 -0.873416 +v 0.946504 0.477860 -0.886809 +v 1.019936 0.361223 -0.886809 +v 0.946504 0.477860 -0.880113 +v 1.019936 0.361223 -0.880113 +v 1.106999 0.237706 -0.880113 +v 1.106999 0.237707 -0.886810 +v 0.946504 0.477860 -0.873416 +v 1.019936 0.361223 -0.873416 +v 1.106999 0.237707 -0.873416 +v -0.514321 1.292454 -0.886809 +v -0.463916 1.305752 -0.886929 +v -0.514321 1.292454 -0.880113 +v -0.462326 1.305900 -0.880234 +v -0.425762 1.328483 -0.887869 +v -0.514321 1.292454 -0.873416 +v -0.461845 1.305531 -0.873441 +v 0.127789 1.001778 -0.886809 +v 0.173767 1.017705 -0.886809 +v 0.127789 1.001778 -0.880113 +v 0.173767 1.017705 -0.880113 +v 0.213855 1.044875 -0.880113 +v 0.213855 1.044876 -0.886809 +v 0.127789 1.001778 -0.873416 +v 0.173767 1.017705 -0.873416 +v 0.213855 1.044876 -0.873416 +v 0.528965 1.375970 -0.886809 +v 0.571200 1.392854 -0.886809 +v 0.528965 1.375970 -0.880113 +v 0.571200 1.392854 -0.880113 +v 0.528965 1.375970 -0.873416 +v 0.571200 1.392854 -0.873416 +v 0.899238 0.595832 -0.886809 +v 0.899238 0.595832 -0.880113 +v 0.899238 0.595832 -0.873416 +v -1.068659 -1.377337 -0.886810 +v -1.144742 -1.315373 -0.886810 +v -1.068659 -1.377337 -0.880113 +v -1.144742 -1.315373 -0.880113 +v -1.068659 -1.377337 -0.873416 +v -1.144742 -1.315373 -0.873416 +v 0.352978 -1.627178 -0.886810 +v 0.180499 -1.643059 -0.886810 +v 0.352978 -1.627178 -0.880113 +v 0.180499 -1.643058 -0.880113 +v -0.008951 -1.649528 -0.880113 +v -0.008951 -1.649528 -0.886810 +v 0.352978 -1.627178 -0.873416 +v 0.180499 -1.643059 -0.873416 +v -0.008951 -1.649528 -0.873416 +v -1.444854 -0.690722 -0.886810 +v -1.444854 -0.690722 -0.880113 +v -1.442701 -0.579172 -0.880113 +v -1.442701 -0.579173 -0.886810 +v -1.444854 -0.690722 -0.873416 +v -1.442701 -0.579173 -0.873416 +v 0.869407 -1.477108 -0.886885 +v 0.756196 -1.527037 -0.886829 +v 0.868736 -1.477215 -0.880113 +v 0.756038 -1.527058 -0.880113 +v 0.630599 -1.570393 -0.880113 +v 0.630599 -1.570393 -0.886810 +v 0.868736 -1.477215 -0.873416 +v 0.756038 -1.527058 -0.873416 +v 0.630599 -1.570393 -0.873416 +v -1.427365 -0.464191 -0.886810 +v -1.427365 -0.464191 -0.880113 +v -1.427365 -0.464191 -0.873416 +v 1.033445 -1.375246 -0.886810 +v 0.960366 -1.425390 -0.886829 +v 0.963046 -1.424061 -0.892123 +v 1.033371 -1.375295 -0.880113 +v 0.960051 -1.425517 -0.880113 +v 1.033371 -1.375295 -0.873416 +v 0.960051 -1.425517 -0.873416 +v -0.641666 -1.584145 -0.886810 +v -0.757186 -1.546177 -0.886810 +v -0.641666 -1.584145 -0.880113 +v -0.757186 -1.546177 -0.880113 +v -0.757186 -1.546177 -0.886810 +v -0.757186 -1.546177 -0.880113 +v -0.868623 -1.497648 -0.880113 +v -0.868623 -1.497648 -0.886810 +v -0.641666 -1.584145 -0.873416 +v -0.757186 -1.546177 -0.873416 +v -0.757186 -1.546177 -0.873416 +v -0.868623 -1.497648 -0.873416 +v -0.923584 0.913675 -0.886809 +v -0.923584 0.913675 -0.880113 +v -0.951644 1.069244 -0.880113 +v -0.951644 1.069244 -0.886809 +v -0.923584 0.913675 -0.873416 +v -0.951644 1.069244 -0.873416 +v 0.499680 -1.603435 -0.886810 +v 0.499680 -1.603436 -0.880113 +v 0.499680 -1.603435 -0.873416 +v 0.239660 1.039358 -0.886809 +v 0.239660 1.039358 -0.892043 +v 0.239660 1.039358 -0.880113 +v 0.239660 1.039358 -0.886809 +v 0.239660 1.039358 -0.880113 +v 0.257059 1.023417 -0.880113 +v 0.257059 1.023417 -0.886809 +v 0.239660 1.039358 -0.873416 +v 0.239660 1.039358 -0.868182 +v 0.239660 1.039358 -0.873416 +v 0.257059 1.023417 -0.873416 +v 0.257059 1.023417 -0.886809 +v 0.274801 1.030281 -0.886809 +v 0.257059 1.023417 -0.880113 +v 0.274801 1.030281 -0.880113 +v 0.298874 1.070844 -0.880113 +v 0.298874 1.070845 -0.886809 +v 0.257059 1.023417 -0.873416 +v 0.274801 1.030281 -0.873416 +v 0.298874 1.070845 -0.873416 +v -0.981335 1.247422 -0.886809 +v -0.956889 1.265358 -0.886809 +v -0.981335 1.247422 -0.880113 +v -0.956889 1.265358 -0.880113 +v -0.910528 1.284777 -0.880113 +v -0.910528 1.284777 -0.886809 +v -0.981335 1.247422 -0.873416 +v -0.956889 1.265358 -0.873416 +v -0.910528 1.284777 -0.873416 +v 1.213780 -1.209734 -0.886810 +v 1.213780 -1.209734 -0.892044 +v 1.213780 -1.209734 -0.880113 +v 1.153517 -1.274951 -0.880113 +v 1.153517 -1.274951 -0.886810 +v 1.213780 -1.209734 -0.873416 +v 1.153517 -1.274951 -0.873416 +v -0.985104 1.213623 -0.886809 +v -0.989131 1.234596 -0.886809 +v -0.989132 1.234596 -0.892043 +v -0.985104 1.213623 -0.880113 +v -0.989132 1.234596 -0.880113 +v -0.989131 1.234596 -0.886809 +v -0.989132 1.234596 -0.880113 +v -0.989132 1.234596 -0.892043 +v -0.985104 1.213623 -0.873416 +v -0.989131 1.234596 -0.873416 +v -0.989132 1.234596 -0.868182 +v -0.989131 1.234596 -0.873416 +v -0.989132 1.234596 -0.868182 +v 0.298874 1.070845 -0.886809 +v 0.333515 1.143402 -0.886809 +v 0.298874 1.070844 -0.880113 +v 0.333515 1.143402 -0.880113 +v 0.333515 1.143402 -0.886809 +v 0.333515 1.143402 -0.880113 +v 0.298874 1.070845 -0.873416 +v 0.333515 1.143402 -0.873416 +v 0.333515 1.143402 -0.873416 +v 0.720885 1.334761 -0.886809 +v 0.720885 1.334761 -0.880113 +v 0.720885 1.334761 -0.873416 +v -0.763680 1.313608 -0.886809 +v -0.693920 1.327104 -0.886809 +v -0.763680 1.313608 -0.880113 +v -0.693920 1.327105 -0.880113 +v -0.630888 1.327722 -0.880113 +v -0.630888 1.327722 -0.886809 +v -0.763680 1.313608 -0.873416 +v -0.693920 1.327105 -0.873416 +v -0.630888 1.327722 -0.873416 +v -0.200711 -1.645159 -0.886810 +v -0.200711 -1.645158 -0.880113 +v -0.375500 -1.632002 -0.880113 +v -0.375500 -1.632002 -0.886810 +v -0.200711 -1.645159 -0.873416 +v -0.375500 -1.632002 -0.873416 +v 0.502610 1.343147 -0.886809 +v 0.502610 1.343147 -0.880113 +v 0.502610 1.343147 -0.873416 +v 1.273694 -0.059216 -0.886810 +v 1.338895 -0.233898 -0.886810 +v 1.273694 -0.059216 -0.880113 +v 1.338895 -0.233898 -0.880113 +v 1.273694 -0.059216 -0.873416 +v 1.338895 -0.233898 -0.873416 +v -0.841017 1.299947 -0.886809 +v -0.841017 1.299947 -0.880113 +v -0.841017 1.299947 -0.873416 +v -0.974817 -1.439492 -0.886810 +v -0.974817 -1.439492 -0.880113 +v -0.974817 -1.439492 -0.873416 +v 0.085853 1.042438 -0.886809 +v 0.085853 1.042438 -0.880113 +v 0.127789 1.001778 -0.880113 +v 0.127789 1.001778 -0.886809 +v 0.085853 1.042438 -0.873416 +v 0.127789 1.001778 -0.873416 +v -1.036866 0.371091 -0.886809 +v -1.036865 0.371091 -0.880113 +v -0.964714 0.492569 -0.880113 +v -0.964715 0.492569 -0.886809 +v -1.036866 0.371091 -0.873416 +v -0.964715 0.492569 -0.873416 +v -0.570795 1.307612 -0.886809 +v -0.570795 1.307612 -0.880113 +v -0.570795 1.307612 -0.873416 +v 1.194259 0.098826 -0.886810 +v 1.194259 0.098826 -0.880113 +v 1.194259 0.098826 -0.873416 +v -0.519038 -1.612120 -0.886810 +v -0.519038 -1.612120 -0.880113 +v -0.519038 -1.612120 -0.873416 +v 1.095340 -1.327506 -0.886810 +v 1.095331 -1.327512 -0.880113 +v 1.095331 -1.327512 -0.873416 +v 1.213572 -1.209566 -0.894794 +v 1.212118 -1.208387 -0.895808 +v 1.213572 -1.209566 -0.894794 +v -0.957112 0.489717 -0.864100 +v -1.029184 0.367511 -0.864100 +v -1.115874 0.231400 -0.864100 +v -0.036975 0.570696 -0.864054 +v -0.015900 0.400894 -0.864054 +v 0.027841 0.250414 -0.864054 +v -0.909180 1.278067 -0.864100 +v -0.952836 1.258631 -0.864100 +v -0.974011 1.241276 -0.864100 +v -0.943668 1.069908 -0.864100 +v -0.915645 0.914528 -0.864100 +v -0.898983 0.744943 -0.864100 +v -0.411003 1.320298 -0.864100 +v -0.463080 1.298696 -0.864100 +v -0.513959 1.285413 -0.864100 +v -0.912222 0.607568 -0.864100 +v -0.066626 0.790640 -0.864054 +v -0.054948 0.696225 -0.864054 +v -0.628273 1.321544 -0.864100 +v -0.691501 1.320865 -0.864100 +v -0.762098 1.307081 -0.864100 +v -0.976227 1.209323 -0.864100 +v -0.964486 1.164398 -0.864100 +v -0.951571 1.170061 -0.864054 +v 0.044299 1.110623 -0.864100 +v 0.009943 1.207777 -0.864100 +v -0.036274 1.278088 -0.864100 +v 0.124704 0.961113 -0.864100 +v 0.081826 1.021466 -0.864100 +v -0.744210 1.205981 -0.864054 +v -0.739336 1.177284 -0.864054 +v -0.670968 1.177849 -0.864054 +v -0.674592 1.208288 -0.864054 +v -0.606907 1.172533 -0.864054 +v -0.610398 1.203431 -0.864054 +v -0.278089 1.309761 -0.864100 +v -0.294964 1.315561 -0.864100 +v -0.313684 1.321197 -0.864100 +v -0.104806 1.301393 -0.864100 +v -0.172868 1.304158 -0.864417 +v -0.179291 1.300840 -0.864100 +v -0.488474 1.179242 -0.864054 +v -0.483163 1.152558 -0.864054 +v -0.394773 1.143826 -0.864054 +v -0.403871 1.173060 -0.864054 +v -0.298611 1.127967 -0.864054 +v -1.203524 0.079377 -0.864100 +v -1.282187 -0.074727 -0.864100 +v -1.344501 -0.216738 -0.864100 +v -1.389714 -0.346954 -0.864100 +v -1.329589 -1.053537 -0.864100 +v -1.268953 -1.155499 -0.864100 +v -1.205673 -1.237211 -0.864100 +v -0.639266 -1.572011 -0.864100 +v -0.517145 -1.599926 -0.864100 +v -0.374165 -1.619843 -0.864100 +v -1.064530 -1.366355 -0.864100 +v -0.971038 -1.428229 -0.864100 +v -0.865249 -1.486097 -0.864100 +v -0.200020 -1.633010 -0.864100 +v -0.008901 -1.637353 -0.864100 +v -1.434258 -0.584080 -0.864100 +v -1.436505 -0.694743 -0.864100 +v -1.420955 -0.807652 -0.864100 +v 1.099215 0.233654 -0.864100 +v 1.012278 0.357876 -0.864100 +v 0.938859 0.475466 -0.864100 +v 0.109412 0.179479 -0.864054 +v 0.205695 0.160782 -0.864054 +v 0.910221 1.143566 -0.864100 +v 0.846828 1.208948 -0.864100 +v 0.770550 1.267116 -0.864100 +v 0.873686 0.717329 -0.864100 +v 0.883819 0.842752 -0.864100 +v 0.907500 0.961126 -0.864100 +v 0.527288 1.361218 -0.864100 +v 0.501578 1.328955 -0.864100 +v 0.475468 1.291487 -0.864100 +v 0.891452 0.594501 -0.864100 +v 0.287129 0.161122 -0.864054 +v 0.335809 0.212335 -0.864054 +v 0.690521 1.361269 -0.864100 +v 0.657309 1.379728 -0.864100 +v 0.616458 1.382861 -0.864100 +v 0.925280 1.062304 -0.864100 +v 0.263816 0.995455 -0.864100 +v 0.243417 0.970257 -0.864100 +v 0.214249 0.945502 -0.864100 +v 0.171548 0.939276 -0.864100 +v 0.586163 0.965012 -0.864054 +v 0.632614 0.965519 -0.864054 +v 0.683225 0.966640 -0.864054 +v 0.384438 1.210494 -0.864100 +v 0.341716 1.139082 -0.864100 +v 0.307469 1.066850 -0.864100 +v 0.283021 1.022124 -0.864100 +v 0.425909 0.914855 -0.864054 +v 0.458673 0.949953 -0.864054 +v 0.497244 0.960781 -0.864054 +v 1.265518 -0.063497 -0.864100 +v 1.186298 0.094443 -0.864100 +v 1.375968 -0.405378 -0.864100 +v 1.330490 -0.237684 -0.864100 +v 1.149475 -1.264641 -0.864100 +v 1.209632 -1.199657 -0.864100 +v 1.269678 -1.119934 -0.864100 +v 0.351990 -1.614961 -0.864100 +v 0.498194 -1.591303 -0.864100 +v 0.628575 -1.558454 -0.864100 +v 0.865604 -1.465915 -0.864100 +v 0.956534 -1.414518 -0.864100 +v 1.029599 -1.364556 -0.864100 +v 0.180002 -1.630845 -0.864100 +v 1.366966 -0.919596 -0.864100 +v 1.392410 -0.800616 -0.864100 +v 1.402765 -0.673782 -0.864100 +v -0.355787 1.326034 -0.864100 +v -0.754284 -1.534296 -0.864100 +v -0.211709 1.094580 -0.864054 +v -0.140546 1.053405 -0.864054 +v -0.065562 0.959856 -0.864054 +v -0.063439 0.883533 -0.864054 +v -0.090799 1.012348 -0.864054 +v -0.568993 1.300966 -0.864100 +v -0.549500 1.162818 -0.864054 +v -0.552876 1.191430 -0.864054 +v -1.140300 -1.304745 -0.864100 +v -0.840213 1.293305 -0.864100 +v -0.836559 1.092606 -0.864054 +v -0.802128 1.162398 -0.864054 +v -0.812342 1.192073 -0.864054 +v -1.383370 -0.931162 -0.864100 +v -1.163713 -0.158233 -0.864054 +v -1.081388 0.016332 -0.864054 +v -0.995685 0.187555 -0.864054 +v -0.810931 0.748614 -0.864054 +v -0.827377 0.935224 -0.864054 +v -0.922347 0.336607 -0.864054 +v -0.864493 0.468333 -0.864054 +v -0.824062 0.596718 -0.864054 +v -1.273872 -0.473451 -0.864054 +v -1.227662 -0.318274 -0.864054 +v -1.418955 -0.468842 -0.864100 +v 1.398765 -0.546737 -0.864100 +v -1.303312 -0.773780 -0.864054 +v -1.303458 -0.632638 -0.864054 +v -1.197495 -0.948634 -0.864054 +v -1.262264 -0.874886 -0.864054 +v -0.832994 -1.196971 -0.864055 +v -0.943224 -1.139770 -0.864055 +v -1.042963 -1.075926 -0.864054 +v -0.346263 -1.330057 -0.864055 +v -0.483819 -1.305072 -0.864055 +v -0.604735 -1.274440 -0.864055 +v 0.345562 -1.322607 -0.864055 +v 0.177212 -1.340574 -0.864055 +v -0.004421 -1.349446 -0.864055 +v 1.160001 -0.983381 -0.864054 +v 1.091168 -1.040413 -0.864054 +v 1.021386 -1.089416 -0.864054 +v 0.850280 -1.187545 -0.864055 +v 0.739396 -1.231706 -0.864055 +v 0.617262 -1.269285 -0.864055 +v -0.183502 -1.345638 -0.864055 +v -1.125739 -1.013082 -0.864054 +v -0.720020 -1.240304 -0.864055 +v 0.433020 1.256906 -0.864100 +v 0.753433 -1.515419 -0.864100 +v 0.489311 -1.299133 -0.864055 +v 0.377094 0.742618 -0.864054 +v 0.400201 0.840650 -0.864054 +v 0.343641 0.344443 -0.864054 +v 0.340682 0.502601 -0.864054 +v 0.353789 0.633903 -0.864054 +v 0.721776 1.320965 -0.864100 +v 0.738038 0.963518 -0.864054 +v 0.778095 0.928178 -0.864054 +v 1.324632 -1.025726 -0.864100 +v 1.278656 -0.804533 -0.864054 +v 1.229848 -0.907780 -0.864054 +v 1.256639 -0.505191 -0.864054 +v 1.284312 -0.667223 -0.864054 +v 0.978518 0.194889 -0.864054 +v 1.063580 0.027828 -0.864054 +v 1.144381 -0.149424 -0.864054 +v 0.786633 0.837350 -0.864054 +v 0.786121 0.718875 -0.864054 +v 0.841618 0.480720 -0.864054 +v 0.901983 0.346061 -0.864054 +v 0.802687 0.601485 -0.864054 +v 1.209309 -0.329720 -0.864054 +v 0.568783 1.378035 -0.864100 +v 0.540521 0.964118 -0.864054 +v 1.091395 -1.316999 -0.864100 +v 0.943158 -1.138932 -0.864055 +v -1.115874 0.231401 -0.896126 +v -1.029184 0.367511 -0.896126 +v -0.957112 0.489717 -0.896126 +v 0.027841 0.250414 -0.896171 +v -0.015900 0.400894 -0.896171 +v -0.036975 0.570696 -0.896171 +v -0.974010 1.241276 -0.896126 +v -0.952836 1.258631 -0.896126 +v -0.909180 1.278067 -0.896126 +v -0.898983 0.744943 -0.896126 +v -0.915645 0.914528 -0.896126 +v -0.943668 1.069908 -0.896126 +v -0.512995 1.284943 -0.896126 +v -0.462634 1.297574 -0.896085 +v -0.426101 1.320697 -0.895788 +v -0.169080 0.992014 -0.896171 +v -0.293594 0.906374 -0.896171 +v -0.411902 0.862850 -0.896171 +v -0.912222 0.607568 -0.896126 +v -0.054948 0.696225 -0.896171 +v -0.066626 0.790640 -0.896171 +v -0.762098 1.307081 -0.896126 +v -0.691500 1.320865 -0.896126 +v -0.628270 1.321544 -0.896126 +v -0.976227 1.209323 -0.896126 +v -0.980246 1.228957 -0.896126 +v -0.986465 1.232381 -0.895808 +v -0.472641 0.956755 -0.896171 +v -0.506459 1.089592 -0.896171 +v -0.036358 1.278189 -0.896126 +v 0.009905 1.207880 -0.896126 +v 0.044289 1.110655 -0.896126 +v 0.081825 1.021470 -0.896126 +v 0.124704 0.961113 -0.896126 +v -0.609023 1.203413 -0.896171 +v -0.605929 1.172521 -0.896171 +v -0.670845 1.177847 -0.896171 +v -0.674420 1.208286 -0.896171 +v -0.739336 1.177284 -0.896171 +v -0.744210 1.205981 -0.896171 +v -0.276474 1.313971 -0.896126 +v -0.238860 1.305741 -0.896126 +v -0.258452 1.293731 -0.896171 +v -0.270150 1.313260 -0.895808 +v -0.232500 1.306620 -0.895808 +v -0.172767 1.304459 -0.895808 +v -0.179126 1.301503 -0.896126 +v -0.104906 1.301453 -0.896126 +v -1.282187 -0.074727 -0.896126 +v -1.203524 0.079377 -0.896126 +v -1.389646 -0.346548 -0.896126 +v -1.344492 -0.216688 -0.896126 +v -1.205459 -1.237484 -0.896126 +v -1.266035 -1.156944 -0.896129 +v -1.309776 -1.059804 -0.896144 +v -0.374165 -1.619843 -0.896126 +v -0.517145 -1.599927 -0.896126 +v -0.639266 -1.572011 -0.896126 +v -0.865249 -1.486097 -0.896126 +v -0.971038 -1.428228 -0.896126 +v -1.064530 -1.366355 -0.896126 +v -0.008901 -1.637353 -0.896126 +v -0.200020 -1.633010 -0.896126 +v 0.938859 0.475466 -0.896126 +v 1.012278 0.357876 -0.896126 +v 1.099215 0.233654 -0.896126 +v 0.205695 0.160782 -0.896171 +v 0.109412 0.179479 -0.896171 +v 0.770550 1.267116 -0.896126 +v 0.846828 1.208948 -0.896126 +v 0.910221 1.143566 -0.896126 +v 0.907500 0.961126 -0.896126 +v 0.883819 0.842752 -0.896126 +v 0.873685 0.717330 -0.896126 +v 0.475468 1.291487 -0.896126 +v 0.501578 1.328955 -0.896126 +v 0.527288 1.361218 -0.896126 +v 0.891452 0.594501 -0.896126 +v 0.335809 0.212335 -0.896171 +v 0.287129 0.161122 -0.896171 +v 0.616458 1.382861 -0.896126 +v 0.657309 1.379729 -0.896126 +v 0.690521 1.361269 -0.896126 +v 0.925280 1.062304 -0.896126 +v 0.214249 0.945502 -0.896126 +v 0.243417 0.970257 -0.896126 +v 0.263816 0.995455 -0.896126 +v 0.171548 0.939276 -0.896126 +v 0.683225 0.966640 -0.896171 +v 0.632614 0.965519 -0.896171 +v 0.586163 0.965012 -0.896171 +v 0.307469 1.066850 -0.896126 +v 0.341716 1.139082 -0.896126 +v 0.384438 1.210494 -0.896126 +v 0.283021 1.022124 -0.896126 +v 0.497244 0.960781 -0.896171 +v 0.458673 0.949954 -0.896171 +v 0.425909 0.914855 -0.896171 +v 1.186298 0.094443 -0.896126 +v 1.265518 -0.063497 -0.896126 +v 1.330490 -0.237684 -0.896126 +v 1.375969 -0.405378 -0.896126 +v 1.269679 -1.119934 -0.896126 +v 1.209536 -1.199734 -0.896126 +v 1.148706 -1.265257 -0.896126 +v 0.629442 -1.558113 -0.896126 +v 0.498302 -1.591260 -0.896126 +v 0.351990 -1.614961 -0.896126 +v 0.180002 -1.630844 -0.896126 +v 1.402765 -0.673782 -0.896126 +v 1.392410 -0.800616 -0.896126 +v 1.366966 -0.919596 -0.896126 +v -0.754284 -1.534295 -0.896126 +v -0.063473 0.883645 -0.896171 +v -0.065832 0.960751 -0.896171 +v -0.094913 1.006974 -0.896171 +v -0.568867 1.300907 -0.896126 +v -0.550000 1.155140 -0.896171 +v -0.549423 1.186061 -0.896171 +v -1.140273 -1.304780 -0.896126 +v -0.840213 1.293305 -0.896126 +v -0.802128 1.162398 -0.896171 +v -0.812342 1.192073 -0.896171 +v -0.836559 1.092606 -0.896171 +v -1.322127 -0.952662 -0.896166 +v -1.303722 -0.882080 -0.896171 +v -0.995685 0.187555 -0.896171 +v -1.081388 0.016332 -0.896171 +v -1.163713 -0.158233 -0.896171 +v -0.827377 0.935224 -0.896171 +v -0.810930 0.748614 -0.896171 +v -0.864493 0.468333 -0.896171 +v -0.922347 0.336607 -0.896171 +v -0.824062 0.596718 -0.896171 +v -1.227597 -0.317839 -0.896171 +v -1.273350 -0.469968 -0.896171 +v -1.417120 -0.578699 -0.896144 +v -1.416729 -0.467167 -0.896128 +v 1.398765 -0.546737 -0.896126 +v -1.306831 -0.615549 -0.896171 +v -1.341095 -0.700558 -0.896171 +v -1.257558 -0.893431 -0.896171 +v -1.195482 -0.950857 -0.896171 +v -1.042963 -1.075926 -0.896171 +v -0.943224 -1.139770 -0.896172 +v -0.832994 -1.196971 -0.896171 +v -0.604735 -1.274440 -0.896171 +v -0.483819 -1.305072 -0.896172 +v -0.346263 -1.330057 -0.896171 +v -0.004421 -1.349446 -0.896171 +v 0.177212 -1.340574 -0.896172 +v 0.345562 -1.322606 -0.896171 +v 1.021290 -1.089509 -0.896171 +v 1.091077 -1.040488 -0.896171 +v 1.159967 -0.983407 -0.896171 +v 0.617300 -1.269270 -0.896171 +v 0.739500 -1.231667 -0.896172 +v 0.850397 -1.187512 -0.896171 +v -0.183502 -1.345639 -0.896172 +v -1.384855 -0.672652 -0.896166 +v -1.125487 -1.013360 -0.896171 +v -0.720020 -1.240304 -0.896172 +v 0.433019 1.256906 -0.896126 +v 0.844954 -1.483626 -0.895963 +v 0.752942 -1.516808 -0.896106 +v 0.489316 -1.299131 -0.896172 +v 0.400201 0.840650 -0.896171 +v 0.377094 0.742618 -0.896171 +v 0.340682 0.502601 -0.896171 +v 0.343641 0.344443 -0.896171 +v 0.353788 0.633903 -0.896171 +v 0.721776 1.320965 -0.896126 +v 0.778095 0.928178 -0.896171 +v 0.738038 0.963518 -0.896171 +v 1.324632 -1.025726 -0.896126 +v 1.229844 -0.907783 -0.896171 +v 1.278656 -0.804533 -0.896171 +v 1.284312 -0.667223 -0.896171 +v 1.256639 -0.505191 -0.896171 +v 1.144381 -0.149424 -0.896171 +v 1.063581 0.027828 -0.896171 +v 0.978518 0.194889 -0.896171 +v 0.786121 0.718875 -0.896171 +v 0.786632 0.837350 -0.896171 +v 0.901983 0.346061 -0.896171 +v 0.841618 0.480720 -0.896171 +v 0.802687 0.601485 -0.896171 +v 1.209309 -0.329720 -0.896171 +v 0.568783 1.378034 -0.896126 +v 0.540521 0.964118 -0.896171 +v 1.089507 -1.318585 -0.896126 +v 0.943171 -1.138966 -0.896172 +v -0.407907 1.336359 -0.893110 +v -0.405190 1.337034 -0.890210 +v -0.388273 1.335959 -0.887359 +v -0.309182 1.327995 -0.887359 +v -0.293053 1.326181 -0.890210 +v -0.286708 1.322778 -0.887869 +v -0.293053 1.326181 -0.890210 +v -0.286708 1.322778 -0.887869 +v -0.290898 1.325856 -0.893110 +v -0.290898 1.325856 -0.893110 +v -0.348330 1.332313 -0.886470 +v 0.969670 -1.419943 -0.894823 +v 0.969670 -1.419943 -0.894823 +v 0.915992 -1.455112 -0.895052 +v 0.915992 -1.455112 -0.895052 +v 0.886910 -1.470319 -0.895581 +v 0.886910 -1.470319 -0.895581 +v -0.410812 1.333015 -0.894923 +v -0.410812 1.333015 -0.894923 +v -0.407907 1.336359 -0.893110 +v -0.291091 1.325479 -0.894921 +v -0.310966 1.327686 -0.895015 +v -0.291091 1.325479 -0.894921 +v -0.291091 1.325479 -0.894921 +v -0.291725 1.323986 -0.895777 +v -0.290532 1.320340 -0.896082 +v -0.964486 1.164398 -0.896126 +v -0.951571 1.170061 -0.896171 +v -0.239733 1.303359 -0.864100 +v -0.259660 1.291849 -0.864054 +v -0.232804 1.305716 -0.864417 +v -0.980246 1.228957 -0.864100 +v -0.986465 1.232381 -0.864417 +v -0.972868 1.166014 -0.873416 +v -0.972868 1.166014 -0.880113 +v -0.972868 1.166014 -0.886809 +v -0.284776 1.318539 -0.873441 +v -0.283918 1.318487 -0.880234 +v -0.282708 1.318313 -0.886929 +v -0.299763 1.324748 -0.881393 +v -0.283918 1.318487 -0.880234 +v -0.282708 1.318313 -0.886929 +v -0.282444 1.318268 -0.892088 +v -0.988799 1.234318 -0.894793 +v -0.988799 1.234318 -0.894793 +v -0.988799 1.234318 -0.894793 +v -0.230682 1.306193 -0.894793 +v -0.232500 1.306620 -0.895808 +v -0.230720 1.306080 -0.865432 +v -0.232804 1.305716 -0.864417 +v -0.270661 1.311740 -0.864417 +v -0.988799 1.234318 -0.865432 +v -0.988799 1.234318 -0.865432 +v -0.988799 1.234318 -0.865432 +v -0.927792 1.187225 -0.896171 +v -0.886642 1.210257 -0.896171 +v -0.750693 1.241418 -0.896171 +v -0.680135 1.247972 -0.896171 +v -0.615421 1.244748 -0.896171 +v -0.493788 1.208377 -0.896171 +v -0.424496 1.209100 -0.896171 +v -0.356264 1.230094 -0.896171 +v -0.298700 1.263880 -0.896171 +v -0.823964 1.230038 -0.896171 +v -0.555612 1.227416 -0.896171 +v -0.927792 1.187225 -0.864054 +v -0.886641 1.210257 -0.864054 +v -0.680264 1.247974 -0.864054 +v -0.750693 1.241418 -0.864054 +v -0.616450 1.244761 -0.864054 +v -0.428958 1.218116 -0.864054 +v -0.498488 1.214738 -0.864054 +v -0.357457 1.236258 -0.864054 +v -0.299556 1.266088 -0.864054 +v -0.823964 1.230038 -0.864054 +v -0.558618 1.228604 -0.864054 +vt 0.023333 0.881635 +vt 0.020639 0.879448 +vt 0.015378 0.890343 +vt 0.018001 0.892997 +vt 0.012758 0.887684 +vt 0.008882 0.897387 +vt 0.011439 0.900700 +vt 0.013999 0.904003 +vt 0.070675 0.778323 +vt 0.074893 0.780040 +vt 0.074783 0.778540 +vt 0.070553 0.776724 +vt 0.078947 0.781408 +vt 0.078699 0.779942 +vt 0.068216 0.839367 +vt 0.073052 0.838398 +vt 0.074951 0.828326 +vt 0.070522 0.829230 +vt 0.081025 0.833115 +vt 0.082184 0.823958 +vt 0.082348 0.814301 +vt 0.075904 0.817310 +vt 0.071707 0.817830 +vt 0.110416 0.908167 +vt 0.101160 0.905295 +vt 0.098202 0.925131 +vt 0.109129 0.926677 +vt 0.092941 0.901649 +vt 0.088299 0.922873 +vt 0.085670 0.938845 +vt 0.096324 0.941062 +vt 0.108113 0.942524 +vt 0.112341 0.802874 +vt 0.114434 0.800736 +vt 0.113240 0.793627 +vt 0.110800 0.798078 +vt 0.115759 0.789050 +vt 0.112563 0.783696 +vt 0.109930 0.789122 +vt 0.107289 0.794544 +vt 0.111297 0.814664 +vt 0.111794 0.818774 +vt 0.113412 0.810461 +vt 0.112025 0.809302 +vt 0.112652 0.826544 +vt 0.115110 0.814505 +vt 0.117500 0.799112 +vt 0.113637 0.837953 +vt 0.116847 0.822922 +vt 0.116183 0.848532 +vt 0.119564 0.831427 +vt 0.122983 0.813957 +vt 0.120103 0.807567 +vt 0.051375 0.838138 +vt 0.054889 0.838745 +vt 0.058129 0.829111 +vt 0.054800 0.828700 +vt 0.059381 0.839290 +vt 0.062347 0.829438 +vt 0.063649 0.817918 +vt 0.059548 0.817726 +vt 0.056334 0.817461 +vt 0.040714 0.858731 +vt 0.044516 0.860111 +vt 0.050310 0.848761 +vt 0.046650 0.847811 +vt 0.049500 0.861644 +vt 0.055070 0.849728 +vt 0.059927 0.863678 +vt 0.065774 0.863708 +vt 0.070139 0.849872 +vt 0.064777 0.850562 +vt 0.074458 0.858948 +vt 0.078711 0.844151 +vt 0.049988 0.779978 +vt 0.054968 0.779115 +vt 0.054703 0.777847 +vt 0.049612 0.778708 +vt 0.060705 0.778499 +vt 0.060558 0.777159 +vt 0.058984 0.803696 +vt 0.055865 0.803898 +vt 0.063211 0.803632 +vt 0.062164 0.791465 +vt 0.057780 0.792063 +vt 0.055415 0.794520 +vt 0.075997 0.804054 +vt 0.071847 0.803944 +vt 0.081661 0.802857 +vt 0.080824 0.793224 +vt 0.075732 0.792865 +vt 0.071547 0.792184 +vt 0.087339 0.779402 +vt 0.091427 0.778520 +vt 0.090259 0.777222 +vt 0.086293 0.777642 +vt 0.093385 0.777420 +vt 0.104835 0.786339 +vt 0.102007 0.791401 +vt 0.107557 0.781414 +vt 0.102035 0.780493 +vt 0.099127 0.784012 +vt 0.094486 0.788110 +vt 0.077978 0.896778 +vt 0.069594 0.896994 +vt 0.063891 0.915421 +vt 0.071671 0.917813 +vt 0.061214 0.897329 +vt 0.056326 0.912904 +vt 0.052629 0.927198 +vt 0.060301 0.930383 +vt 0.068233 0.933347 +vt 0.102010 0.830890 +vt 0.087469 0.846529 +vt 0.078590 0.871589 +vt 0.088982 0.865531 +vt 0.067932 0.878070 +vt 0.054677 0.862798 +vt 0.048206 0.877036 +vt 0.053675 0.878715 +vt 0.042919 0.875169 +vt 0.036458 0.888740 +vt 0.041823 0.891263 +vt 0.047456 0.893697 +vt 0.113716 0.866702 +vt 0.109949 0.856840 +vt 0.105754 0.879324 +vt 0.112172 0.885645 +vt 0.107787 0.845686 +vt 0.100625 0.871981 +vt 0.037091 0.857245 +vt 0.034285 0.856072 +vt 0.027238 0.867647 +vt 0.030062 0.869310 +vt 0.024418 0.865976 +vt 0.017947 0.877258 +vt 0.036712 0.903998 +vt 0.042598 0.906964 +vt 0.031165 0.901008 +vt 0.026859 0.913171 +vt 0.032490 0.916641 +vt 0.038564 0.920110 +vt 0.061090 0.971572 +vt 0.052699 0.968553 +vt 0.051531 0.975641 +vt 0.059895 0.978747 +vt 0.044532 0.964839 +vt 0.043440 0.971815 +vt 0.029579 0.955019 +vt 0.023789 0.950029 +vt 0.023191 0.957158 +vt 0.028794 0.962083 +vt 0.018818 0.944906 +vt 0.018394 0.951991 +vt 0.010335 0.928953 +vt 0.006989 0.921328 +vt 0.006295 0.930299 +vt 0.009736 0.938529 +vt 0.003905 0.923851 +vt 0.105595 0.979370 +vt 0.092209 0.978377 +vt 0.091434 0.985318 +vt 0.105107 0.986346 +vt 0.080084 0.976611 +vt 0.079034 0.983595 +vt 0.197240 0.890271 +vt 0.201329 0.903778 +vt 0.204327 0.901672 +vt 0.200235 0.888336 +vt 0.204122 0.916850 +vt 0.207077 0.914526 +vt 0.159301 0.801662 +vt 0.160576 0.791259 +vt 0.157119 0.791296 +vt 0.155896 0.801601 +vt 0.161894 0.780864 +vt 0.158387 0.780996 +vt 0.155264 0.781934 +vt 0.153945 0.791892 +vt 0.152674 0.801848 +vt 0.157182 0.843005 +vt 0.156051 0.833341 +vt 0.152759 0.832743 +vt 0.153724 0.842513 +vt 0.156060 0.824771 +vt 0.152642 0.824217 +vt 0.149281 0.823716 +vt 0.149158 0.832133 +vt 0.149684 0.841947 +vt 0.120549 0.927172 +vt 0.120524 0.909329 +vt 0.120359 0.942972 +vt 0.131895 0.942579 +vt 0.131352 0.926834 +vt 0.130335 0.909269 +vt 0.137160 0.837155 +vt 0.138758 0.827280 +vt 0.136446 0.820204 +vt 0.134615 0.830400 +vt 0.140923 0.819668 +vt 0.138509 0.813558 +vt 0.136145 0.807060 +vt 0.134210 0.811675 +vt 0.131191 0.819734 +vt 0.136007 0.857755 +vt 0.136574 0.849377 +vt 0.133595 0.845407 +vt 0.133166 0.858311 +vt 0.129182 0.840448 +vt 0.127839 0.856648 +vt 0.124022 0.836686 +vt 0.121459 0.854143 +vt 0.126683 0.817880 +vt 0.173527 0.843697 +vt 0.171288 0.834549 +vt 0.167575 0.834531 +vt 0.169467 0.843804 +vt 0.170690 0.825850 +vt 0.167360 0.825861 +vt 0.163295 0.825705 +vt 0.163170 0.834342 +vt 0.164680 0.843760 +vt 0.182553 0.865842 +vt 0.177437 0.854083 +vt 0.173349 0.854567 +vt 0.178607 0.866911 +vt 0.168331 0.854963 +vt 0.173478 0.868041 +vt 0.163121 0.869184 +vt 0.159508 0.854862 +vt 0.155281 0.854636 +vt 0.158027 0.869453 +vt 0.150575 0.854286 +vt 0.152664 0.869545 +vt 0.174324 0.806681 +vt 0.174139 0.796426 +vt 0.170259 0.794000 +vt 0.170253 0.803033 +vt 0.170155 0.785164 +vt 0.167626 0.782524 +vt 0.166951 0.792345 +vt 0.166266 0.802164 +vt 0.171261 0.817423 +vt 0.168183 0.817348 +vt 0.171499 0.812170 +vt 0.169167 0.810950 +vt 0.165297 0.810664 +vt 0.164263 0.817219 +vt 0.157015 0.816567 +vt 0.153575 0.816185 +vt 0.158104 0.810306 +vt 0.154717 0.810105 +vt 0.151526 0.810056 +vt 0.150342 0.815914 +vt 0.146150 0.805274 +vt 0.148769 0.794470 +vt 0.145509 0.794295 +vt 0.142733 0.802109 +vt 0.147780 0.787664 +vt 0.143076 0.812830 +vt 0.140454 0.808160 +vt 0.146522 0.907837 +vt 0.149003 0.924747 +vt 0.157080 0.923248 +vt 0.154033 0.906743 +vt 0.150658 0.940189 +vt 0.159139 0.938449 +vt 0.166813 0.936448 +vt 0.164440 0.921552 +vt 0.160992 0.905475 +vt 0.140261 0.868312 +vt 0.143379 0.888396 +vt 0.150163 0.887959 +vt 0.146788 0.869330 +vt 0.156577 0.887411 +vt 0.167878 0.885640 +vt 0.173535 0.884337 +vt 0.168247 0.868771 +vt 0.172665 0.902306 +vt 0.178551 0.900120 +vt 0.184403 0.897514 +vt 0.179171 0.882635 +vt 0.120378 0.888581 +vt 0.120233 0.871468 +vt 0.128980 0.889220 +vt 0.127817 0.872820 +vt 0.186329 0.864771 +vt 0.191982 0.877099 +vt 0.194996 0.875666 +vt 0.189253 0.864043 +vt 0.176395 0.917438 +vt 0.182383 0.914690 +vt 0.179071 0.931610 +vt 0.185005 0.928566 +vt 0.190907 0.925200 +vt 0.188339 0.911586 +vt 0.152106 0.975913 +vt 0.151951 0.982958 +vt 0.161237 0.980466 +vt 0.161334 0.973549 +vt 0.161144 0.987382 +vt 0.169595 0.984234 +vt 0.169667 0.977442 +vt 0.169743 0.970649 +vt 0.182728 0.963997 +vt 0.182445 0.970724 +vt 0.187490 0.967417 +vt 0.187984 0.960656 +vt 0.186999 0.974177 +vt 0.191610 0.970499 +vt 0.192394 0.963617 +vt 0.193176 0.956736 +vt 0.204238 0.942161 +vt 0.202662 0.952640 +vt 0.206901 0.946563 +vt 0.208212 0.936638 +vt 0.205581 0.953822 +vt 0.118834 0.986507 +vt 0.119157 0.979456 +vt 0.118510 0.993558 +vt 0.131227 0.993041 +vt 0.131477 0.985928 +vt 0.131727 0.978816 +vt 0.069933 0.974280 +vt 0.068756 0.981386 +vt 0.105593 0.837242 +vt 0.095684 0.866544 +vt 0.085523 0.898470 +vt 0.079626 0.920342 +vt 0.076484 0.936206 +vt 0.092126 0.807549 +vt 0.089739 0.799597 +vt 0.101090 0.800784 +vt 0.096943 0.796190 +vt 0.093148 0.792994 +vt 0.087610 0.792993 +vt 0.083103 0.780832 +vt 0.082448 0.779140 +vt 0.092009 0.830820 +vt 0.104542 0.816913 +vt 0.105146 0.809872 +vt 0.093560 0.821463 +vt 0.093504 0.814469 +vt 0.103960 0.805061 +vt 0.036642 0.960143 +vt 0.035684 0.967125 +vt 0.053829 0.896033 +vt 0.049165 0.910013 +vt 0.045319 0.923700 +vt 0.059838 0.879908 +vt 0.067758 0.817928 +vt 0.067629 0.803730 +vt 0.066988 0.791664 +vt 0.059946 0.850299 +vt 0.063862 0.839476 +vt 0.066510 0.829453 +vt 0.065993 0.777970 +vt 0.065875 0.776464 +vt 0.014213 0.938875 +vt 0.013864 0.945973 +vt 0.037759 0.873028 +vt 0.033783 0.871231 +vt 0.027064 0.883951 +vt 0.031170 0.886079 +vt 0.049242 0.817195 +vt 0.051273 0.817163 +vt 0.050651 0.803749 +vt 0.053306 0.817159 +vt 0.052746 0.803164 +vt 0.052154 0.789141 +vt 0.049097 0.791435 +vt 0.048658 0.804345 +vt 0.045170 0.782352 +vt 0.046857 0.781277 +vt 0.046487 0.779974 +vt 0.031483 0.854891 +vt 0.040766 0.845875 +vt 0.043247 0.846709 +vt 0.048199 0.837355 +vt 0.046074 0.836764 +vt 0.038289 0.845031 +vt 0.043952 0.836165 +vt 0.049722 0.827834 +vt 0.051742 0.828176 +vt 0.047703 0.827492 +vt 0.025812 0.897979 +vt 0.021703 0.895618 +vt 0.017617 0.907028 +vt 0.021591 0.909696 +vt 0.018277 0.921809 +vt 0.023223 0.926023 +vt 0.014692 0.918542 +vt 0.013674 0.926453 +vt 0.016091 0.931117 +vt 0.020615 0.936200 +vt 0.041617 0.938550 +vt 0.049189 0.942571 +vt 0.034693 0.934290 +vt 0.031692 0.945664 +vt 0.038745 0.950513 +vt 0.046549 0.954976 +vt 0.073766 0.951895 +vt 0.083352 0.954507 +vt 0.065252 0.949016 +vt 0.062940 0.961537 +vt 0.071652 0.964326 +vt 0.081556 0.966793 +vt 0.107077 0.957945 +vt 0.119932 0.958268 +vt 0.106254 0.969786 +vt 0.119515 0.969930 +vt 0.131878 0.969320 +vt 0.131982 0.957776 +vt 0.205486 0.929013 +vt 0.208392 0.925977 +vt 0.180933 0.945191 +vt 0.186634 0.941980 +vt 0.182102 0.955402 +vt 0.187557 0.952102 +vt 0.192970 0.948268 +vt 0.192295 0.938362 +vt 0.151538 0.955159 +vt 0.160351 0.953173 +vt 0.151927 0.966538 +vt 0.160977 0.964347 +vt 0.169216 0.961674 +vt 0.168336 0.950812 +vt 0.094610 0.956621 +vt 0.093285 0.968692 +vt 0.008639 0.911105 +vt 0.011169 0.915564 +vt 0.006188 0.906703 +vt 0.004557 0.915610 +vt 0.028654 0.930164 +vt 0.025773 0.940954 +vt 0.057097 0.945992 +vt 0.054635 0.958548 +vt 0.142316 0.956710 +vt 0.141802 0.941602 +vt 0.142470 0.968187 +vt 0.142283 0.984762 +vt 0.142487 0.977648 +vt 0.142080 0.991876 +vt 0.151798 0.990002 +vt 0.136540 0.889090 +vt 0.134500 0.872769 +vt 0.138833 0.908704 +vt 0.140647 0.925976 +vt 0.147551 0.815850 +vt 0.146129 0.823309 +vt 0.148769 0.810433 +vt 0.146942 0.811578 +vt 0.145554 0.815893 +vt 0.143722 0.823002 +vt 0.151414 0.793227 +vt 0.149757 0.802754 +vt 0.153114 0.783908 +vt 0.150922 0.786063 +vt 0.145247 0.853733 +vt 0.144895 0.841284 +vt 0.140826 0.840705 +vt 0.140672 0.852962 +vt 0.145206 0.831524 +vt 0.141948 0.831036 +vt 0.197702 0.934391 +vt 0.196314 0.921824 +vt 0.198285 0.943517 +vt 0.201523 0.938959 +vt 0.201693 0.931231 +vt 0.200300 0.919269 +vt 0.197592 0.958686 +vt 0.198710 0.951328 +vt 0.196449 0.965860 +vt 0.201277 0.960198 +vt 0.184371 0.880577 +vt 0.189668 0.894700 +vt 0.193497 0.892460 +vt 0.188221 0.878833 +vt 0.177803 0.826166 +vt 0.178957 0.816904 +vt 0.176725 0.816686 +vt 0.175799 0.825973 +vt 0.180915 0.808097 +vt 0.178037 0.807405 +vt 0.174422 0.816613 +vt 0.173791 0.825805 +vt 0.182256 0.800555 +vt 0.178604 0.798815 +vt 0.178623 0.792570 +vt 0.173680 0.788728 +vt 0.192171 0.863303 +vt 0.186375 0.853491 +vt 0.183767 0.853570 +vt 0.181568 0.844318 +vt 0.179324 0.843999 +vt 0.177076 0.843668 +vt 0.181155 0.853637 +vt 0.178624 0.835293 +vt 0.176598 0.834961 +vt 0.174570 0.834627 +vt 0.193679 0.908459 +vt 0.197555 0.906074 +vt 0.175036 0.948137 +vt 0.173242 0.934207 +vt 0.176154 0.958624 +vt 0.176660 0.974104 +vt 0.176799 0.967371 +vt 0.176525 0.980835 +vt 0.182167 0.977449 +vt 0.170652 0.919674 +vt 0.167011 0.904044 +vt 0.162356 0.886645 +vt 0.160526 0.816948 +vt 0.159535 0.825309 +vt 0.161565 0.810521 +vt 0.163727 0.855023 +vt 0.160641 0.843459 +vt 0.159370 0.833913 +vt 0.163818 0.791533 +vt 0.162679 0.801840 +vt 0.164987 0.781229 +vt 0.407510 0.881637 +vt 0.412833 0.892954 +vt 0.415458 0.890311 +vt 0.410204 0.879450 +vt 0.416770 0.903644 +vt 0.419348 0.900429 +vt 0.360139 0.778328 +vt 0.360284 0.776728 +vt 0.356025 0.778555 +vt 0.355853 0.780062 +vt 0.356075 0.777910 +vt 0.352045 0.779355 +vt 0.351995 0.780027 +vt 0.351694 0.781519 +vt 0.362628 0.839369 +vt 0.360322 0.829232 +vt 0.355907 0.828363 +vt 0.357791 0.838400 +vt 0.359137 0.817833 +vt 0.355067 0.817478 +vt 0.348883 0.815267 +vt 0.348692 0.824158 +vt 0.349819 0.833117 +vt 0.320427 0.908168 +vt 0.321714 0.926678 +vt 0.332641 0.925132 +vt 0.329683 0.905296 +vt 0.322730 0.942525 +vt 0.334518 0.941064 +vt 0.345172 0.938846 +vt 0.342544 0.922875 +vt 0.337902 0.901651 +vt 0.318525 0.802783 +vt 0.320393 0.798172 +vt 0.317715 0.793510 +vt 0.316426 0.800672 +vt 0.326695 0.797153 +vt 0.321341 0.789224 +vt 0.319546 0.814666 +vt 0.318822 0.809293 +vt 0.317434 0.810456 +vt 0.319050 0.818776 +vt 0.313348 0.799099 +vt 0.315735 0.814505 +vt 0.318191 0.826547 +vt 0.313997 0.822925 +vt 0.317207 0.837955 +vt 0.310741 0.807569 +vt 0.307861 0.813959 +vt 0.311280 0.831430 +vt 0.314660 0.848535 +vt 0.379469 0.838141 +vt 0.376044 0.828702 +vt 0.372715 0.829114 +vt 0.375955 0.838747 +vt 0.374510 0.817464 +vt 0.371296 0.817728 +vt 0.367195 0.817921 +vt 0.368497 0.829441 +vt 0.371462 0.839293 +vt 0.390129 0.858733 +vt 0.384194 0.847813 +vt 0.380533 0.848764 +vt 0.386328 0.860113 +vt 0.375773 0.849730 +vt 0.381344 0.861646 +vt 0.370916 0.863680 +vt 0.366066 0.850565 +vt 0.360705 0.849874 +vt 0.365069 0.863710 +vt 0.352133 0.844154 +vt 0.356386 0.858950 +vt 0.380856 0.779981 +vt 0.381233 0.778711 +vt 0.376141 0.777850 +vt 0.375876 0.779118 +vt 0.376195 0.777342 +vt 0.370334 0.776635 +vt 0.370286 0.777162 +vt 0.370139 0.778503 +vt 0.374978 0.803901 +vt 0.371859 0.803699 +vt 0.375429 0.794523 +vt 0.373064 0.792066 +vt 0.368680 0.791468 +vt 0.367633 0.803635 +vt 0.358994 0.803947 +vt 0.355204 0.804294 +vt 0.359272 0.792189 +vt 0.355450 0.793320 +vt 0.353237 0.795893 +vt 0.352243 0.804436 +vt 0.332181 0.792895 +vt 0.326582 0.786576 +vt 0.336964 0.788311 +vt 0.332015 0.784261 +vt 0.352865 0.896780 +vt 0.359172 0.917814 +vt 0.366952 0.915423 +vt 0.361249 0.896995 +vt 0.362610 0.933348 +vt 0.370542 0.930384 +vt 0.378214 0.927199 +vt 0.374517 0.912905 +vt 0.369629 0.897331 +vt 0.328834 0.830893 +vt 0.341861 0.865533 +vt 0.352253 0.871591 +vt 0.343374 0.846531 +vt 0.362912 0.878072 +vt 0.377168 0.878717 +vt 0.382637 0.877038 +vt 0.376166 0.862800 +vt 0.383387 0.893699 +vt 0.389021 0.891265 +vt 0.394385 0.888741 +vt 0.387925 0.875171 +vt 0.317127 0.866704 +vt 0.318671 0.885647 +vt 0.325089 0.879326 +vt 0.320894 0.856842 +vt 0.330218 0.871983 +vt 0.323056 0.845688 +vt 0.393752 0.857247 +vt 0.400781 0.869313 +vt 0.403605 0.867649 +vt 0.396558 0.856074 +vt 0.388245 0.906966 +vt 0.394132 0.904000 +vt 0.392279 0.920111 +vt 0.398353 0.916642 +vt 0.403984 0.913173 +vt 0.399678 0.901010 +vt 0.369752 0.971572 +vt 0.370948 0.978747 +vt 0.379311 0.975641 +vt 0.378144 0.968554 +vt 0.380480 0.982728 +vt 0.388497 0.978789 +vt 0.387403 0.971815 +vt 0.386311 0.964840 +vt 0.401264 0.955020 +vt 0.402049 0.962084 +vt 0.407633 0.957182 +vt 0.407029 0.950061 +vt 0.408245 0.964294 +vt 0.412813 0.959154 +vt 0.412300 0.952177 +vt 0.411828 0.945150 +vt 0.325248 0.979370 +vt 0.325735 0.986346 +vt 0.339408 0.985318 +vt 0.338633 0.978377 +vt 0.340181 0.992260 +vt 0.352855 0.990580 +vt 0.351808 0.983596 +vt 0.350759 0.976612 +vt 0.233603 0.890273 +vt 0.230608 0.888338 +vt 0.226516 0.901674 +vt 0.229514 0.903780 +vt 0.223517 0.899566 +vt 0.220810 0.912199 +vt 0.223765 0.914528 +vt 0.226721 0.916852 +vt 0.271543 0.801665 +vt 0.274948 0.801604 +vt 0.273725 0.791299 +vt 0.270268 0.791262 +vt 0.278170 0.801851 +vt 0.276899 0.791895 +vt 0.275580 0.781937 +vt 0.272457 0.780999 +vt 0.268950 0.780868 +vt 0.273661 0.843008 +vt 0.277120 0.842515 +vt 0.278084 0.832746 +vt 0.274793 0.833343 +vt 0.281159 0.841949 +vt 0.281686 0.832136 +vt 0.281563 0.823719 +vt 0.278201 0.824220 +vt 0.274783 0.824773 +vt 0.310319 0.909331 +vt 0.310294 0.927174 +vt 0.300508 0.909271 +vt 0.299491 0.926836 +vt 0.298948 0.942580 +vt 0.310484 0.942973 +vt 0.293683 0.837158 +vt 0.296228 0.830403 +vt 0.294398 0.820207 +vt 0.292086 0.827283 +vt 0.299652 0.819737 +vt 0.296634 0.811678 +vt 0.294699 0.807063 +vt 0.292335 0.813561 +vt 0.289921 0.819671 +vt 0.294836 0.857757 +vt 0.297678 0.858313 +vt 0.297248 0.845409 +vt 0.294269 0.849379 +vt 0.303005 0.856650 +vt 0.301661 0.840450 +vt 0.309384 0.854145 +vt 0.306822 0.836689 +vt 0.304160 0.817883 +vt 0.257316 0.843699 +vt 0.261377 0.843807 +vt 0.263268 0.834533 +vt 0.259556 0.834552 +vt 0.266164 0.843762 +vt 0.267673 0.834345 +vt 0.267549 0.825708 +vt 0.263484 0.825864 +vt 0.260154 0.825853 +vt 0.248290 0.865844 +vt 0.252236 0.866913 +vt 0.257495 0.854569 +vt 0.253406 0.854085 +vt 0.257366 0.868043 +vt 0.262513 0.854966 +vt 0.267722 0.869186 +vt 0.272816 0.869455 +vt 0.275562 0.854638 +vt 0.271335 0.854864 +vt 0.278179 0.869547 +vt 0.280268 0.854288 +vt 0.256520 0.806684 +vt 0.260591 0.803036 +vt 0.260585 0.794003 +vt 0.256704 0.796429 +vt 0.264578 0.802167 +vt 0.263893 0.792348 +vt 0.262660 0.817351 +vt 0.259583 0.817425 +vt 0.266581 0.817221 +vt 0.265547 0.810667 +vt 0.261677 0.810952 +vt 0.259345 0.812173 +vt 0.277268 0.816188 +vt 0.273829 0.816570 +vt 0.280502 0.815917 +vt 0.279317 0.810059 +vt 0.276127 0.810108 +vt 0.272740 0.810309 +vt 0.284694 0.805277 +vt 0.288111 0.802112 +vt 0.285335 0.794298 +vt 0.282075 0.794473 +vt 0.288177 0.793630 +vt 0.290390 0.808163 +vt 0.287768 0.812833 +vt 0.292985 0.803587 +vt 0.290917 0.799433 +vt 0.284321 0.907839 +vt 0.276809 0.906744 +vt 0.273763 0.923249 +vt 0.281839 0.924748 +vt 0.269851 0.905476 +vt 0.266403 0.921553 +vt 0.264030 0.936449 +vt 0.271703 0.938450 +vt 0.280185 0.940190 +vt 0.290582 0.868314 +vt 0.284055 0.869332 +vt 0.280680 0.887961 +vt 0.287464 0.888398 +vt 0.274266 0.887413 +vt 0.262596 0.868773 +vt 0.257308 0.884339 +vt 0.262965 0.885642 +vt 0.251672 0.882637 +vt 0.246440 0.897515 +vt 0.252292 0.900121 +vt 0.258177 0.902308 +vt 0.310610 0.871470 +vt 0.310465 0.888583 +vt 0.303026 0.872822 +vt 0.301863 0.889222 +vt 0.244514 0.864773 +vt 0.241590 0.864045 +vt 0.235848 0.875668 +vt 0.238861 0.877101 +vt 0.232838 0.874226 +vt 0.227615 0.886399 +vt 0.248460 0.914692 +vt 0.254447 0.917439 +vt 0.242504 0.911587 +vt 0.239935 0.925201 +vt 0.245838 0.928567 +vt 0.251772 0.931612 +vt 0.278713 0.975906 +vt 0.269445 0.973530 +vt 0.269410 0.980433 +vt 0.278826 0.982936 +vt 0.261029 0.970634 +vt 0.260914 0.977491 +vt 0.248174 0.964049 +vt 0.242915 0.960698 +vt 0.243514 0.967537 +vt 0.248563 0.970870 +vt 0.237686 0.956752 +vt 0.238507 0.963660 +vt 0.226604 0.942162 +vt 0.222630 0.936639 +vt 0.223942 0.946564 +vt 0.228180 0.952641 +vt 0.221007 0.942000 +vt 0.311685 0.979457 +vt 0.312008 0.986507 +vt 0.299115 0.978817 +vt 0.299365 0.985929 +vt 0.362087 0.981387 +vt 0.360909 0.974281 +vt 0.363263 0.988493 +vt 0.372144 0.985923 +vt 0.335160 0.866546 +vt 0.325250 0.837244 +vt 0.345320 0.898471 +vt 0.351217 0.920344 +vt 0.354358 0.936207 +vt 0.344500 0.806921 +vt 0.347201 0.801099 +vt 0.340273 0.798047 +vt 0.337644 0.804107 +vt 0.350217 0.790419 +vt 0.343412 0.790576 +vt 0.348019 0.779351 +vt 0.347415 0.781112 +vt 0.344005 0.777806 +vt 0.343107 0.779694 +vt 0.338835 0.830823 +vt 0.337284 0.821463 +vt 0.325704 0.809851 +vt 0.326302 0.816913 +vt 0.337275 0.814854 +vt 0.337810 0.810508 +vt 0.329855 0.804848 +vt 0.327004 0.805594 +vt 0.395159 0.967126 +vt 0.394200 0.960144 +vt 0.396120 0.974106 +vt 0.402837 0.969145 +vt 0.381678 0.910015 +vt 0.377014 0.896035 +vt 0.385524 0.923702 +vt 0.371006 0.879910 +vt 0.363215 0.803733 +vt 0.363086 0.817930 +vt 0.363853 0.791667 +vt 0.370898 0.850302 +vt 0.366981 0.839478 +vt 0.364333 0.829456 +vt 0.364969 0.776468 +vt 0.364847 0.777974 +vt 0.365026 0.775898 +vt 0.360345 0.776112 +vt 0.416377 0.947038 +vt 0.415919 0.940629 +vt 0.416847 0.953443 +vt 0.419185 0.948641 +vt 0.419221 0.943149 +vt 0.418412 0.938849 +vt 0.393085 0.873030 +vt 0.399673 0.886081 +vt 0.403780 0.883953 +vt 0.397060 0.871234 +vt 0.381602 0.817198 +vt 0.382186 0.804348 +vt 0.380193 0.803752 +vt 0.379571 0.817166 +vt 0.383701 0.792596 +vt 0.381747 0.791438 +vt 0.378691 0.789144 +vt 0.378098 0.803167 +vt 0.377538 0.817161 +vt 0.385674 0.782355 +vt 0.385949 0.780975 +vt 0.384357 0.779977 +vt 0.383987 0.781281 +vt 0.384471 0.779435 +vt 0.381319 0.778199 +vt 0.399360 0.854893 +vt 0.392555 0.845034 +vt 0.390078 0.845877 +vt 0.386892 0.836168 +vt 0.384769 0.836766 +vt 0.382644 0.837357 +vt 0.387597 0.846712 +vt 0.383141 0.827495 +vt 0.381122 0.827836 +vt 0.379102 0.828178 +vt 0.405031 0.897979 +vt 0.409250 0.909687 +vt 0.413208 0.906941 +vt 0.409138 0.895609 +vt 0.407614 0.926032 +vt 0.412624 0.921869 +vt 0.410179 0.936261 +vt 0.414953 0.931686 +vt 0.420111 0.928850 +vt 0.416462 0.918495 +vt 0.381654 0.942572 +vt 0.389226 0.938551 +vt 0.384294 0.954977 +vt 0.392098 0.950514 +vt 0.399151 0.945665 +vt 0.396150 0.934292 +vt 0.347490 0.954508 +vt 0.357077 0.951896 +vt 0.349286 0.966794 +vt 0.359191 0.964327 +vt 0.367903 0.961538 +vt 0.365591 0.949017 +vt 0.310910 0.958269 +vt 0.323766 0.957946 +vt 0.298860 0.957777 +vt 0.298964 0.969321 +vt 0.311328 0.969931 +vt 0.324589 0.969787 +vt 0.222450 0.925979 +vt 0.225356 0.929014 +vt 0.219622 0.922977 +vt 0.219787 0.932688 +vt 0.244209 0.941981 +vt 0.249909 0.945192 +vt 0.238547 0.938363 +vt 0.237872 0.948269 +vt 0.243286 0.952103 +vt 0.248741 0.955403 +vt 0.270492 0.953174 +vt 0.279304 0.955160 +vt 0.262506 0.950813 +vt 0.261627 0.961675 +vt 0.269865 0.964348 +vt 0.278915 0.966539 +vt 0.336233 0.956622 +vt 0.337557 0.968693 +vt 0.419619 0.913489 +vt 0.422034 0.909791 +vt 0.421473 0.918692 +vt 0.423571 0.916444 +vt 0.402188 0.930166 +vt 0.405063 0.940963 +vt 0.373745 0.945993 +vt 0.376207 0.958549 +vt 0.289041 0.941603 +vt 0.288526 0.956711 +vt 0.288372 0.968188 +vt 0.288353 0.977648 +vt 0.288551 0.984760 +vt 0.296343 0.872771 +vt 0.294303 0.889092 +vt 0.292010 0.908705 +vt 0.290195 0.925977 +vt 0.284715 0.823312 +vt 0.283293 0.815853 +vt 0.287121 0.823005 +vt 0.285290 0.815895 +vt 0.283902 0.811581 +vt 0.282075 0.810436 +vt 0.281086 0.802757 +vt 0.279430 0.793230 +vt 0.285596 0.853736 +vt 0.290171 0.852965 +vt 0.290018 0.840707 +vt 0.285949 0.841287 +vt 0.285637 0.831527 +vt 0.288896 0.831038 +vt 0.234529 0.921826 +vt 0.233141 0.934393 +vt 0.230543 0.919270 +vt 0.229150 0.931233 +vt 0.229319 0.938960 +vt 0.232558 0.943518 +vt 0.232135 0.951331 +vt 0.233258 0.958692 +vt 0.246472 0.880579 +vt 0.242622 0.878835 +vt 0.237346 0.892462 +vt 0.241175 0.894702 +vt 0.253041 0.826169 +vt 0.255045 0.825975 +vt 0.254119 0.816689 +vt 0.257053 0.825808 +vt 0.256421 0.816616 +vt 0.252806 0.807408 +vt 0.251886 0.816907 +vt 0.249929 0.808100 +vt 0.252240 0.798818 +vt 0.238672 0.863306 +vt 0.247076 0.853573 +vt 0.249689 0.853639 +vt 0.253767 0.843671 +vt 0.251520 0.844001 +vt 0.244469 0.853494 +vt 0.249275 0.844321 +vt 0.254246 0.834963 +vt 0.256274 0.834630 +vt 0.252220 0.835296 +vt 0.237163 0.908460 +vt 0.233288 0.906076 +vt 0.257601 0.934208 +vt 0.255806 0.948138 +vt 0.254688 0.958625 +vt 0.254037 0.967392 +vt 0.254139 0.974181 +vt 0.263831 0.904046 +vt 0.260191 0.919676 +vt 0.268487 0.886647 +vt 0.271308 0.825312 +vt 0.270318 0.816951 +vt 0.269279 0.810523 +vt 0.267116 0.855025 +vt 0.270202 0.843462 +vt 0.271473 0.833915 +vt 0.268164 0.801843 +vt 0.267026 0.791536 +vt 0.265857 0.781232 +vt 0.111084 0.833466 +vt 0.111966 0.846088 +vt 0.114600 0.857373 +vt 0.109767 0.817108 +vt 0.110254 0.824125 +vt 0.061369 0.783751 +vt 0.061615 0.785889 +vt 0.066667 0.786119 +vt 0.066520 0.783856 +vt 0.071377 0.786765 +vt 0.071242 0.784470 +vt 0.080151 0.786740 +vt 0.080438 0.788731 +vt 0.086931 0.789726 +vt 0.086376 0.787532 +vt 0.093971 0.791279 +vt 0.120343 0.862934 +vt 0.127380 0.864697 +vt 0.133396 0.864995 +vt 0.137195 0.861406 +vt 0.165574 0.776481 +vt 0.162569 0.776088 +vt 0.127948 0.807077 +vt 0.124575 0.805279 +vt 0.158673 0.806822 +vt 0.162106 0.806969 +vt 0.165849 0.807087 +vt 0.146638 0.809890 +vt 0.149197 0.807428 +vt 0.152089 0.806781 +vt 0.142031 0.995231 +vt 0.176585 0.983996 +vt 0.100257 0.794089 +vt 0.105350 0.797412 +vt 0.110517 0.804617 +vt 0.110371 0.810261 +vt 0.108861 0.800641 +vt 0.075579 0.787710 +vt 0.075443 0.785584 +vt 0.022590 0.964283 +vt 0.027502 0.972421 +vt 0.028006 0.969144 +vt 0.054098 0.791756 +vt 0.056918 0.786739 +vt 0.056282 0.784507 +vt 0.024971 0.882820 +vt 0.031744 0.870257 +vt 0.038753 0.857954 +vt 0.054626 0.817258 +vt 0.054152 0.803413 +vt 0.044762 0.847239 +vt 0.049558 0.837741 +vt 0.053053 0.828422 +vt 0.015583 0.905659 +vt 0.019612 0.894384 +vt 0.012217 0.927718 +vt 0.012766 0.917296 +vt 0.019339 0.941049 +vt 0.014848 0.935347 +vt 0.045275 0.960833 +vt 0.037361 0.956172 +vt 0.030247 0.951062 +vt 0.080697 0.972591 +vt 0.070636 0.970200 +vt 0.061827 0.967458 +vt 0.131824 0.974785 +vt 0.119318 0.975444 +vt 0.105868 0.975378 +vt 0.193324 0.952968 +vt 0.188014 0.956906 +vt 0.182665 0.960248 +vt 0.169638 0.966815 +vt 0.161273 0.969635 +vt 0.152103 0.971926 +vt 0.092656 0.974387 +vt 0.024383 0.946093 +vt 0.053447 0.964480 +vt 0.148521 0.784661 +vt 0.169665 0.987430 +vt 0.142534 0.973622 +vt 0.142349 0.822414 +vt 0.144445 0.815267 +vt 0.138298 0.851682 +vt 0.138707 0.839992 +vt 0.140196 0.830349 +vt 0.170102 0.781076 +vt 0.169885 0.807535 +vt 0.172703 0.810303 +vt 0.202798 0.940232 +vt 0.198783 0.947662 +vt 0.202360 0.918042 +vt 0.203761 0.930116 +vt 0.184596 0.865244 +vt 0.190216 0.877918 +vt 0.195480 0.891326 +vt 0.172973 0.817044 +vt 0.172465 0.825790 +vt 0.175619 0.843595 +vt 0.179543 0.853778 +vt 0.173223 0.834524 +vt 0.199560 0.904897 +vt 0.159029 0.776255 +vt 0.155897 0.777332 +vt 0.155299 0.806707 +vt 0.176691 0.963593 +vt 0.316243 0.857375 +vt 0.318877 0.846090 +vt 0.319760 0.833468 +vt 0.348315 0.778108 +vt 0.348130 0.778618 +vt 0.327845 0.801835 +vt 0.337382 0.807664 +vt 0.346293 0.810409 +vt 0.320589 0.824128 +vt 0.321077 0.817110 +vt 0.350406 0.803234 +vt 0.352377 0.793291 +vt 0.359500 0.784480 +vt 0.359395 0.786773 +vt 0.364168 0.786122 +vt 0.364311 0.783861 +vt 0.369229 0.785892 +vt 0.369475 0.783754 +vt 0.372747 0.989295 +vt 0.403341 0.972422 +vt 0.326223 0.993322 +vt 0.340546 0.995541 +vt 0.303463 0.864699 +vt 0.310500 0.862936 +vt 0.279922 0.786067 +vt 0.276974 0.779616 +vt 0.277730 0.783911 +vt 0.274947 0.777336 +vt 0.293648 0.861408 +vt 0.297447 0.864997 +vt 0.265270 0.776485 +vt 0.262890 0.777979 +vt 0.263218 0.782527 +vt 0.302896 0.807080 +vt 0.299717 0.806790 +vt 0.264995 0.807090 +vt 0.268738 0.806972 +vt 0.272171 0.806825 +vt 0.278755 0.806784 +vt 0.281647 0.807431 +vt 0.284206 0.809892 +vt 0.278953 0.989972 +vt 0.288803 0.995229 +vt 0.288751 0.991872 +vt 0.312332 0.993558 +vt 0.326448 0.996620 +vt 0.381092 0.986053 +vt 0.320475 0.810256 +vt 0.320343 0.804553 +vt 0.322308 0.801024 +vt 0.355333 0.788278 +vt 0.355167 0.785998 +vt 0.413238 0.962347 +vt 0.373926 0.786742 +vt 0.374563 0.784511 +vt 0.376746 0.791759 +vt 0.420725 0.940853 +vt 0.419086 0.935715 +vt 0.392090 0.857956 +vt 0.399099 0.870259 +vt 0.405873 0.882822 +vt 0.376692 0.803416 +vt 0.376218 0.817261 +vt 0.381286 0.837744 +vt 0.386082 0.847241 +vt 0.377791 0.828425 +vt 0.411224 0.894354 +vt 0.415207 0.905405 +vt 0.418258 0.916022 +vt 0.421126 0.922163 +vt 0.415721 0.936736 +vt 0.411364 0.941223 +vt 0.400595 0.951063 +vt 0.393482 0.956172 +vt 0.385567 0.960833 +vt 0.369016 0.967459 +vt 0.360207 0.970201 +vt 0.350146 0.972591 +vt 0.324974 0.975379 +vt 0.311524 0.975445 +vt 0.299018 0.974786 +vt 0.248184 0.960255 +vt 0.242835 0.956912 +vt 0.237521 0.952971 +vt 0.278736 0.971926 +vt 0.269561 0.969634 +vt 0.261195 0.966813 +vt 0.338186 0.974388 +vt 0.424247 0.919929 +vt 0.406442 0.946115 +vt 0.377395 0.964481 +vt 0.285806 0.789170 +vt 0.282323 0.784664 +vt 0.283064 0.787667 +vt 0.279051 0.782279 +vt 0.260432 0.985078 +vt 0.269700 0.990742 +vt 0.269427 0.987422 +vt 0.288308 0.973623 +vt 0.286399 0.815270 +vt 0.288495 0.822417 +vt 0.292136 0.839995 +vt 0.292545 0.851685 +vt 0.290647 0.830352 +vt 0.260742 0.781079 +vt 0.260689 0.785168 +vt 0.258141 0.810306 +vt 0.260959 0.807537 +vt 0.232060 0.947664 +vt 0.228045 0.940234 +vt 0.227082 0.930117 +vt 0.228483 0.918043 +vt 0.235363 0.891328 +vt 0.240627 0.877919 +vt 0.246247 0.865246 +vt 0.258378 0.825792 +vt 0.257870 0.817046 +vt 0.251300 0.853780 +vt 0.255224 0.843598 +vt 0.257621 0.834526 +vt 0.231283 0.904899 +vt 0.271815 0.776259 +vt 0.268275 0.776091 +vt 0.275545 0.806710 +vt 0.254151 0.963597 +vt 0.257399 0.986268 +vt 0.262772 0.988656 +vt 0.384933 0.785584 +vt 0.383109 0.784411 +vt 0.379978 0.782873 +vt 0.369813 0.781112 +vt 0.364576 0.780908 +vt 0.359809 0.781402 +vt 0.350970 0.784571 +vt 0.345849 0.784792 +vt 0.340726 0.783512 +vt 0.336340 0.781246 +vt 0.339055 0.778492 +vt 0.375270 0.781661 +vt 0.355460 0.782919 +vt 0.047143 0.792593 +vt 0.047735 0.784407 +vt 0.050866 0.782870 +vt 0.045911 0.785580 +vt 0.066259 0.780904 +vt 0.061031 0.781108 +vt 0.070959 0.781394 +vt 0.084701 0.784105 +vt 0.079553 0.784079 +vt 0.090054 0.783049 +vt 0.094449 0.781076 +vt 0.097498 0.779332 +vt 0.094593 0.778144 +vt 0.055574 0.781658 +vt 0.075166 0.782816 +vt 0.078681 0.779286 +vt 0.074752 0.777898 +vt 0.070498 0.776108 +vt 0.060510 0.776632 +vt 0.054650 0.777339 +vt 0.049525 0.778196 +vt 0.092724 0.777027 +vt 0.090180 0.776727 +vt 0.086248 0.777026 +vt 0.042345 0.978788 +vt 0.050362 0.982728 +vt 0.058699 0.985922 +vt 0.017969 0.959075 +vt 0.004115 0.929951 +vt 0.006058 0.936622 +vt 0.009483 0.945343 +vt 0.077987 0.990579 +vt 0.090661 0.992259 +vt 0.104619 0.993322 +vt 0.210033 0.912198 +vt 0.207326 0.899565 +vt 0.203228 0.886397 +vt 0.145038 0.789167 +vt 0.142667 0.793627 +vt 0.139927 0.799430 +vt 0.137859 0.803584 +vt 0.198005 0.874224 +vt 0.208324 0.948578 +vt 0.209836 0.941999 +vt 0.211056 0.932687 +vt 0.067580 0.988492 +vt 0.082411 0.778479 +vt 0.034723 0.974105 +vt 0.065818 0.775894 +vt 0.013574 0.952908 +vt 0.044896 0.780972 +vt 0.046373 0.779432 +vt 0.045039 0.780321 +vt 0.211220 0.922976 +vt 0.182057 0.795688 +vt 0.421937 0.897275 +vt 0.418082 0.887672 +vt 0.412896 0.877260 +vt 0.318327 0.783637 +vt 0.315105 0.788990 +vt 0.340063 0.777079 +vt 0.344098 0.776836 +vt 0.340087 0.776539 +vt 0.337063 0.776650 +vt 0.337006 0.776997 +vt 0.335995 0.777805 +vt 0.328855 0.780524 +vt 0.323365 0.781430 +vt 0.406426 0.865978 +vt 0.422294 0.937299 +vt 0.425134 0.930469 +vt 0.424599 0.923699 +vt 0.421900 0.946903 +vt 0.425406 0.936872 +vt 0.427344 0.930039 +vt 0.427606 0.923861 +vt 0.427271 0.914914 +vt 0.257164 0.788732 +vt 0.239314 0.970558 +vt 0.244063 0.974340 +vt 0.248869 0.977628 +vt 0.222519 0.948579 +vt 0.225261 0.953822 +vt 0.229565 0.960199 +vt 0.299615 0.993041 +vt 0.385806 0.780324 +vt 0.425224 0.912152 +vt 0.424439 0.906054 +vt 0.234404 0.965869 +vt 0.248588 0.800559 +vt 0.252221 0.792573 +vt 0.248787 0.795692 +vt 0.254057 0.980925 +vt 0.191584 0.974353 +vt 0.191675 0.974457 +vt 0.196383 0.969881 +vt 0.196283 0.969787 +vt 0.410546 0.528705 +vt 0.410342 0.528712 +vt 0.410410 0.534946 +vt 0.410614 0.534938 +vt 0.410499 0.541720 +vt 0.410703 0.541710 +vt 0.201153 0.964199 +vt 0.201043 0.964117 +vt 0.077366 0.994615 +vt 0.077342 0.994751 +vt 0.090198 0.996415 +vt 0.090214 0.996278 +vt 0.410675 0.417016 +vt 0.410471 0.417006 +vt 0.410379 0.427842 +vt 0.410583 0.427852 +vt 0.410293 0.440091 +vt 0.410496 0.440100 +vt 0.104343 0.997499 +vt 0.104350 0.997361 +vt 0.194116 0.862668 +vt 0.194238 0.862602 +vt 0.188297 0.853135 +vt 0.188174 0.853198 +vt 0.988600 0.750121 +vt 0.988803 0.750121 +vt 0.988802 0.738991 +vt 0.988598 0.738991 +vt 0.988801 0.728806 +vt 0.988597 0.728804 +vt 0.183336 0.844229 +vt 0.183207 0.844279 +vt 0.070278 0.775360 +vt 0.070229 0.775229 +vt 0.065570 0.775025 +vt 0.065615 0.775158 +vt 0.887629 0.636278 +vt 0.887426 0.636280 +vt 0.887425 0.640761 +vt 0.887628 0.640759 +vt 0.887418 0.645990 +vt 0.887621 0.645991 +vt 0.060362 0.775746 +vt 0.060388 0.775884 +vt 0.029618 0.853999 +vt 0.029501 0.853923 +vt 0.022418 0.864781 +vt 0.022536 0.864853 +vt 0.816008 0.014003 +vt 0.816212 0.013988 +vt 0.816214 0.004569 +vt 0.816010 0.004583 +vt 0.495507 0.416908 +vt 0.495711 0.416922 +vt 0.495590 0.408008 +vt 0.495387 0.407994 +vt 0.015991 0.875840 +vt 0.016113 0.875904 +vt 0.119601 0.793046 +vt 0.119680 0.792934 +vt 0.117587 0.785981 +vt 0.117479 0.786064 +vt 0.281339 0.262091 +vt 0.281542 0.262082 +vt 0.281542 0.254942 +vt 0.281339 0.254946 +vt 0.281542 0.248884 +vt 0.281339 0.248882 +vt 0.114518 0.780739 +vt 0.114390 0.780788 +vt 0.027255 0.973096 +vt 0.027166 0.973201 +vt 0.033849 0.978161 +vt 0.033927 0.978048 +vt 0.495246 0.311231 +vt 0.495449 0.311220 +vt 0.495525 0.304638 +vt 0.495321 0.304651 +vt 0.495614 0.298044 +vt 0.495410 0.298057 +vt 0.041460 0.982876 +vt 0.041527 0.982756 +vt 0.049421 0.777435 +vt 0.049400 0.777292 +vt 0.045907 0.778543 +vt 0.045984 0.778693 +vt 0.887607 0.657008 +vt 0.887404 0.657006 +vt 0.887395 0.660701 +vt 0.887599 0.660696 +vt 0.887387 0.662812 +vt 0.887591 0.662798 +vt 0.044039 0.779772 +vt 0.044178 0.779928 +vt 0.885661 0.636277 +vt 0.885457 0.636274 +vt 0.885456 0.640755 +vt 0.885660 0.640757 +vt 0.360615 0.775232 +vt 0.360566 0.775363 +vt 0.365229 0.775161 +vt 0.365274 0.775028 +vt 0.370456 0.775887 +vt 0.370482 0.775749 +vt 0.885450 0.645987 +vt 0.885653 0.645986 +vt 0.151870 0.781467 +vt 0.151846 0.781330 +vt 0.148408 0.783848 +vt 0.148478 0.783979 +vt 0.606799 0.035655 +vt 0.607002 0.035655 +vt 0.607003 0.031719 +vt 0.606799 0.031725 +vt 0.607006 0.026978 +vt 0.606803 0.026991 +vt 0.144371 0.787321 +vt 0.144483 0.787434 +vt 0.057921 0.990031 +vt 0.057876 0.990162 +vt 0.066821 0.992713 +vt 0.066855 0.992580 +vt 0.410854 0.401513 +vt 0.410651 0.401500 +vt 0.410559 0.408432 +vt 0.410763 0.408444 +vt 0.078692 0.778444 +vt 0.078691 0.778298 +vt 0.074585 0.776954 +vt 0.074617 0.777093 +vt 0.887616 0.628767 +vt 0.887412 0.628762 +vt 0.887418 0.632445 +vt 0.887621 0.632445 +vt 0.168037 0.777051 +vt 0.168055 0.776910 +vt 0.165780 0.775406 +vt 0.165739 0.775540 +vt 0.988598 0.661883 +vt 0.988801 0.661867 +vt 0.988801 0.659496 +vt 0.988597 0.659511 +vt 0.606816 0.050583 +vt 0.607019 0.050593 +vt 0.607008 0.047808 +vt 0.606805 0.047796 +vt 0.162822 0.775025 +vt 0.162769 0.775154 +vt 0.138027 0.797924 +vt 0.137893 0.797874 +vt 0.135953 0.800782 +vt 0.136076 0.800886 +vt 0.931597 0.531551 +vt 0.931394 0.531568 +vt 0.931390 0.534130 +vt 0.931593 0.534116 +vt 0.931394 0.535532 +vt 0.931597 0.535538 +vt 0.134608 0.801275 +vt 0.134680 0.801776 +vt 0.045668 0.793040 +vt 0.045526 0.793026 +vt 0.046980 0.804623 +vt 0.047119 0.804624 +vt 0.872424 0.445860 +vt 0.872220 0.445852 +vt 0.872196 0.457413 +vt 0.872399 0.457419 +vt 0.872184 0.469601 +vt 0.872387 0.469610 +vt 0.047539 0.817127 +vt 0.047677 0.817144 +vt 0.182330 0.981272 +vt 0.182405 0.981388 +vt 0.187170 0.978106 +vt 0.187087 0.977996 +vt 0.410452 0.517342 +vt 0.410249 0.517345 +vt 0.410291 0.523065 +vt 0.410495 0.523060 +vt 0.054593 0.776448 +vt 0.054603 0.776588 +vt 0.887411 0.651759 +vt 0.887615 0.651763 +vt 0.140739 0.792658 +vt 0.140870 0.792735 +vt 0.607019 0.022199 +vt 0.606816 0.022215 +vt 0.926352 0.411177 +vt 0.926555 0.411196 +vt 0.926555 0.406937 +vt 0.926352 0.406922 +vt 0.133371 0.800147 +vt 0.133337 0.801478 +vt 0.198624 0.417126 +vt 0.198692 0.417329 +vt 0.200357 0.417329 +vt 0.200190 0.417126 +vt 0.133375 0.799957 +vt 0.131491 0.799447 +vt 0.131475 0.799709 +vt 0.131362 0.801545 +vt 0.151855 0.994060 +vt 0.151888 0.994193 +vt 0.161323 0.991491 +vt 0.161278 0.991361 +vt 0.410342 0.484304 +vt 0.410138 0.484301 +vt 0.410148 0.493968 +vt 0.410351 0.493969 +vt 0.410172 0.503044 +vt 0.410376 0.503044 +vt 0.169843 0.988259 +vt 0.169787 0.988133 +vt 0.043794 0.782373 +vt 0.043630 0.782248 +vt 0.044343 0.785804 +vt 0.044496 0.785870 +vt 0.872454 0.434971 +vt 0.872251 0.434947 +vt 0.872240 0.438571 +vt 0.872443 0.438587 +vt 0.990568 0.750121 +vt 0.990771 0.750121 +vt 0.990770 0.738991 +vt 0.990567 0.738991 +vt 0.236605 0.862603 +vt 0.236727 0.862670 +vt 0.242670 0.853201 +vt 0.242546 0.853137 +vt 0.247637 0.844282 +vt 0.247507 0.844232 +vt 0.990769 0.728804 +vt 0.990566 0.728806 +vt 0.408706 0.417013 +vt 0.408503 0.417026 +vt 0.408411 0.427861 +vt 0.408614 0.427850 +vt 0.353500 0.994751 +vt 0.353476 0.994615 +vt 0.340628 0.996279 +vt 0.340643 0.996415 +vt 0.326492 0.997361 +vt 0.326499 0.997499 +vt 0.408325 0.440110 +vt 0.408528 0.440099 +vt 0.002850 0.912814 +vt 0.002714 0.912797 +vt 0.002112 0.921023 +vt 0.002250 0.921022 +vt 0.495096 0.375990 +vt 0.495299 0.375998 +vt 0.495266 0.368237 +vt 0.495063 0.368232 +vt 0.495250 0.359617 +vt 0.495046 0.359614 +vt 0.002856 0.929765 +vt 0.002993 0.929745 +vt 0.131149 0.997147 +vt 0.131161 0.997284 +vt 0.142089 0.996113 +vt 0.142067 0.995977 +vt 0.410377 0.464313 +vt 0.410173 0.464307 +vt 0.410146 0.474648 +vt 0.410350 0.474652 +vt 0.007080 0.895554 +vt 0.006949 0.895510 +vt 0.004302 0.904370 +vt 0.004437 0.904402 +vt 0.495205 0.391494 +vt 0.495408 0.391505 +vt 0.495346 0.383686 +vt 0.495142 0.383676 +vt 0.118360 0.997773 +vt 0.118358 0.997635 +vt 0.410223 0.452579 +vt 0.410426 0.452587 +vt 0.885639 0.657002 +vt 0.885436 0.657004 +vt 0.885427 0.660692 +vt 0.885630 0.660698 +vt 0.381444 0.777296 +vt 0.381423 0.777438 +vt 0.384860 0.778696 +vt 0.384937 0.778547 +vt 0.386666 0.779931 +vt 0.386805 0.779775 +vt 0.885419 0.662794 +vt 0.885623 0.662809 +vt 0.179358 0.826262 +vt 0.179497 0.826262 +vt 0.180757 0.817092 +vt 0.180618 0.817078 +vt 0.988598 0.711051 +vt 0.988801 0.711060 +vt 0.988802 0.703463 +vt 0.988599 0.703452 +vt 0.988804 0.696754 +vt 0.988600 0.696746 +vt 0.183034 0.808407 +vt 0.182888 0.808413 +vt 0.408255 0.452596 +vt 0.408458 0.452587 +vt 0.312484 0.997635 +vt 0.312482 0.997773 +vt 0.299693 0.997147 +vt 0.299681 0.997284 +vt 0.408206 0.464322 +vt 0.408409 0.464314 +vt 0.497214 0.311221 +vt 0.497417 0.311232 +vt 0.497493 0.304653 +vt 0.497289 0.304640 +vt 0.403677 0.973201 +vt 0.403587 0.973096 +vt 0.396915 0.978049 +vt 0.396993 0.978162 +vt 0.389315 0.982756 +vt 0.389382 0.982876 +vt 0.497582 0.298059 +vt 0.497378 0.298045 +vt 0.817976 0.013980 +vt 0.818180 0.013993 +vt 0.818182 0.004573 +vt 0.817978 0.004560 +vt 0.401342 0.853925 +vt 0.401226 0.854001 +vt 0.408308 0.864856 +vt 0.408426 0.864783 +vt 0.414730 0.875906 +vt 0.414852 0.875842 +vt 0.497475 0.416924 +vt 0.497679 0.416909 +vt 0.497558 0.407995 +vt 0.497355 0.408009 +vt 0.205241 0.885234 +vt 0.205371 0.885185 +vt 0.200131 0.873202 +vt 0.200007 0.873262 +vt 0.988602 0.775297 +vt 0.988805 0.775299 +vt 0.988804 0.762242 +vt 0.988601 0.762241 +vt 0.005225 0.939449 +vt 0.005357 0.939410 +vt 0.495253 0.349650 +vt 0.495049 0.349650 +vt 0.495272 0.339636 +vt 0.495069 0.339639 +vt 0.008750 0.948858 +vt 0.008875 0.948801 +vt 0.042393 0.835623 +vt 0.042269 0.835563 +vt 0.036457 0.844248 +vt 0.036576 0.844320 +vt 0.816010 0.030699 +vt 0.816213 0.030683 +vt 0.816214 0.023007 +vt 0.816010 0.023022 +vt 0.205647 0.957341 +vt 0.205526 0.957275 +vt 0.410613 0.548757 +vt 0.410817 0.548745 +vt 0.410753 0.555588 +vt 0.410957 0.555573 +vt 0.209343 0.949319 +vt 0.209214 0.949270 +vt 0.173492 0.784462 +vt 0.173507 0.784316 +vt 0.170091 0.780074 +vt 0.170092 0.780215 +vt 0.988599 0.670956 +vt 0.988802 0.670939 +vt 0.988802 0.665608 +vt 0.988598 0.665626 +vt 0.096765 0.777820 +vt 0.096931 0.777775 +vt 0.095714 0.777269 +vt 0.095545 0.777329 +vt 0.887627 0.610913 +vt 0.887424 0.610888 +vt 0.887426 0.611953 +vt 0.887630 0.611978 +vt 0.887429 0.613251 +vt 0.887632 0.613275 +vt 0.094251 0.776734 +vt 0.094096 0.776805 +vt 0.211804 0.940283 +vt 0.211670 0.940253 +vt 0.988597 0.834248 +vt 0.988801 0.834262 +vt 0.988802 0.827325 +vt 0.988599 0.827313 +vt 0.988804 0.819525 +vt 0.988600 0.819514 +vt 0.213093 0.930875 +vt 0.212956 0.930863 +vt 0.497014 0.359618 +vt 0.497217 0.359541 +vt 0.497222 0.349904 +vt 0.497017 0.349651 +vt 0.427893 0.929817 +vt 0.425596 0.939182 +vt 0.422090 0.948667 +vt 0.497242 0.339825 +vt 0.497037 0.339637 +vt 0.184855 0.800798 +vt 0.184692 0.800875 +vt 0.988805 0.690792 +vt 0.988602 0.690791 +vt 0.988805 0.684664 +vt 0.988602 0.684673 +vt 0.184010 0.794362 +vt 0.183859 0.794506 +vt 0.608767 0.035652 +vt 0.608970 0.035650 +vt 0.608971 0.031720 +vt 0.608768 0.031715 +vt 0.278998 0.781333 +vt 0.278974 0.781470 +vt 0.282366 0.783982 +vt 0.282436 0.783851 +vt 0.286361 0.787437 +vt 0.286472 0.787324 +vt 0.608974 0.026986 +vt 0.608771 0.026975 +vt 0.990569 0.696754 +vt 0.990772 0.696745 +vt 0.990773 0.690791 +vt 0.990570 0.690792 +vt 0.247810 0.808409 +vt 0.247956 0.808416 +vt 0.246151 0.800877 +vt 0.245989 0.800800 +vt 0.246985 0.794509 +vt 0.246834 0.794365 +vt 0.990774 0.684673 +vt 0.990570 0.684664 +vt 0.929629 0.531574 +vt 0.929425 0.531558 +vt 0.929421 0.534123 +vt 0.929625 0.534136 +vt 0.292950 0.797877 +vt 0.292817 0.797926 +vt 0.294768 0.800889 +vt 0.294891 0.800784 +vt 0.296164 0.801779 +vt 0.296236 0.801277 +vt 0.929425 0.535546 +vt 0.929629 0.535538 +vt 0.124904 0.802933 +vt 0.124956 0.802369 +vt 0.122021 0.799146 +vt 0.121970 0.799328 +vt 0.281339 0.272892 +vt 0.281542 0.272824 +vt 0.281542 0.268668 +vt 0.281338 0.268688 +vt 0.990566 0.834262 +vt 0.990769 0.834248 +vt 0.990771 0.827313 +vt 0.990567 0.827325 +vt 0.221499 0.949319 +vt 0.221628 0.949271 +vt 0.219173 0.940254 +vt 0.219038 0.940284 +vt 0.217887 0.930864 +vt 0.217749 0.930876 +vt 0.990772 0.819514 +vt 0.990569 0.819524 +vt 0.180312 0.835328 +vt 0.180177 0.835354 +vt 0.988800 0.719505 +vt 0.988597 0.719500 +vt 0.156046 0.776406 +vt 0.156075 0.776269 +vt 0.154001 0.778588 +vt 0.153994 0.778727 +vt 0.606788 0.040947 +vt 0.606992 0.040955 +vt 0.606996 0.038395 +vt 0.606793 0.038390 +vt 0.990566 0.711060 +vt 0.990769 0.711051 +vt 0.990771 0.703452 +vt 0.990567 0.703463 +vt 0.251347 0.826264 +vt 0.251485 0.826265 +vt 0.250225 0.817080 +vt 0.250087 0.817095 +vt 0.283307 0.262082 +vt 0.283510 0.262091 +vt 0.283511 0.254945 +vt 0.283307 0.254942 +vt 0.311164 0.792937 +vt 0.311243 0.793049 +vt 0.313365 0.786067 +vt 0.313257 0.785984 +vt 0.316454 0.780791 +vt 0.316326 0.780742 +vt 0.283510 0.248882 +vt 0.283307 0.248884 +vt 0.870419 0.469594 +vt 0.870216 0.469601 +vt 0.870234 0.478817 +vt 0.870438 0.478808 +vt 0.383304 0.817129 +vt 0.383167 0.817147 +vt 0.384677 0.827163 +vt 0.384808 0.827122 +vt 0.388450 0.835626 +vt 0.388574 0.835565 +vt 0.870286 0.485931 +vt 0.870490 0.485919 +vt 0.497273 0.331013 +vt 0.497069 0.330977 +vt 0.417842 0.956520 +vt 0.417996 0.956671 +vt 0.413517 0.962962 +vt 0.413628 0.963042 +vt 0.497313 0.323699 +vt 0.497109 0.323692 +vt 0.159259 0.775189 +vt 0.159212 0.775321 +vt 0.606997 0.044305 +vt 0.606794 0.044294 +vt 0.090948 0.776115 +vt 0.090830 0.776207 +vt 0.887431 0.616322 +vt 0.887634 0.616342 +vt 0.887428 0.620506 +vt 0.887631 0.620520 +vt 0.086677 0.776228 +vt 0.086604 0.776345 +vt 0.336955 0.776412 +vt 0.336993 0.776486 +vt 0.339867 0.776223 +vt 0.339756 0.776053 +vt 0.342791 0.775944 +vt 0.342547 0.775675 +vt 0.128409 0.801490 +vt 0.128311 0.802856 +vt 0.924384 0.634680 +vt 0.924182 0.634603 +vt 0.924179 0.638017 +vt 0.924381 0.638076 +vt 0.924181 0.641612 +vt 0.924384 0.641638 +vt 0.990772 0.677711 +vt 0.990569 0.677696 +vt 0.251727 0.789160 +vt 0.251644 0.789001 +vt 0.257352 0.784466 +vt 0.257337 0.784319 +vt 0.990771 0.670956 +vt 0.990567 0.670938 +vt 0.885651 0.594485 +vt 0.885447 0.594504 +vt 0.885456 0.598869 +vt 0.885659 0.598850 +vt 0.321398 0.778901 +vt 0.321262 0.778887 +vt 0.885380 0.599005 +vt 0.885379 0.604296 +vt 0.885454 0.604168 +vt 0.885657 0.604150 +vt 0.990773 0.811237 +vt 0.990570 0.811245 +vt 0.217670 0.921481 +vt 0.217533 0.921476 +vt 0.218786 0.910959 +vt 0.218650 0.910939 +vt 0.990773 0.801340 +vt 0.990570 0.801346 +vt 0.497457 0.399532 +vt 0.497254 0.399545 +vt 0.419901 0.886136 +vt 0.420028 0.886081 +vt 0.423762 0.895549 +vt 0.423894 0.895510 +vt 0.497377 0.391496 +vt 0.497173 0.391506 +vt 0.505940 0.774878 +vt 0.506143 0.774862 +vt 0.506138 0.773969 +vt 0.505938 0.773983 +vt 0.885456 0.610901 +vt 0.885381 0.611013 +vt 0.885385 0.611903 +vt 0.885458 0.611795 +vt 0.334942 0.777288 +vt 0.335065 0.777239 +vt 0.335210 0.776996 +vt 0.335131 0.776974 +vt 0.506137 0.773603 +vt 0.505959 0.773606 +vt 0.109582 0.778884 +vt 0.109445 0.778901 +vt 0.887619 0.594508 +vt 0.887416 0.594488 +vt 0.887424 0.598853 +vt 0.887627 0.598873 +vt 0.887422 0.604153 +vt 0.887625 0.604173 +vt 0.887702 0.599011 +vt 0.887700 0.604314 +vt 0.179200 0.788998 +vt 0.179116 0.789157 +vt 0.988804 0.677696 +vt 0.988601 0.677711 +vt 0.198692 0.419094 +vt 0.198624 0.419297 +vt 0.200190 0.419297 +vt 0.200357 0.419094 +vt 0.297507 0.801481 +vt 0.297473 0.800150 +vt 0.299482 0.801548 +vt 0.299368 0.799712 +vt 0.297468 0.799959 +vt 0.299352 0.799449 +vt 0.046035 0.827120 +vt 0.046167 0.827160 +vt 0.872203 0.478815 +vt 0.872406 0.478826 +vt 0.872255 0.485926 +vt 0.872458 0.485940 +vt 0.012845 0.956702 +vt 0.012962 0.956630 +vt 0.495304 0.330976 +vt 0.495101 0.330981 +vt 0.495344 0.323691 +vt 0.495141 0.323698 +vt 0.017214 0.963041 +vt 0.017323 0.962956 +vt 0.212056 0.910957 +vt 0.212193 0.910938 +vt 0.209492 0.898340 +vt 0.209359 0.898375 +vt 0.988602 0.801340 +vt 0.988805 0.801346 +vt 0.988805 0.788893 +vt 0.988602 0.788889 +vt 0.885637 0.621882 +vt 0.885458 0.622039 +vt 0.885450 0.624965 +vt 0.885650 0.624936 +vt 0.345756 0.776135 +vt 0.346280 0.776610 +vt 0.348464 0.777757 +vt 0.348427 0.777547 +vt 0.352129 0.778460 +vt 0.352150 0.778303 +vt 0.885444 0.628761 +vt 0.885648 0.628758 +vt 0.922417 0.634605 +vt 0.922212 0.634682 +vt 0.922210 0.638078 +vt 0.922414 0.638019 +vt 0.302533 0.802858 +vt 0.302435 0.801492 +vt 0.305940 0.802936 +vt 0.305887 0.802372 +vt 0.922212 0.641640 +vt 0.922416 0.641614 +vt 0.608773 0.047804 +vt 0.608976 0.047792 +vt 0.608965 0.044290 +vt 0.608762 0.044301 +vt 0.268021 0.775028 +vt 0.268075 0.775157 +vt 0.271632 0.775324 +vt 0.271585 0.775192 +vt 0.274798 0.776410 +vt 0.274769 0.776272 +vt 0.608960 0.040942 +vt 0.608757 0.040952 +vt 0.990769 0.719499 +vt 0.990565 0.719505 +vt 0.250666 0.835356 +vt 0.250531 0.835330 +vt 0.497359 0.317377 +vt 0.497155 0.317367 +vt 0.408949 0.968230 +vt 0.409049 0.968325 +vt 0.990566 0.661867 +vt 0.990770 0.661883 +vt 0.990769 0.659511 +vt 0.990565 0.659496 +vt 0.262788 0.776913 +vt 0.262807 0.777054 +vt 0.265105 0.775544 +vt 0.265064 0.775409 +vt 0.608784 0.050589 +vt 0.608988 0.050578 +vt 0.010815 0.886080 +vt 0.010941 0.886135 +vt 0.495489 0.399543 +vt 0.495286 0.399531 +vt 0.497063 0.375999 +vt 0.497268 0.375759 +vt 0.497235 0.367897 +vt 0.497031 0.368239 +vt 0.428059 0.913021 +vt 0.428611 0.921341 +vt 0.497314 0.383639 +vt 0.497110 0.383687 +vt 0.426327 0.904542 +vt 0.426528 0.904409 +vt 0.256180 0.986049 +vt 0.253497 0.983736 +vt 0.253088 0.984190 +vt 0.248704 0.980667 +vt 0.248392 0.981216 +vt 0.497679 0.292015 +vt 0.497475 0.292000 +vt 0.381290 0.986775 +vt 0.381346 0.986901 +vt 0.372921 0.990032 +vt 0.372966 0.990162 +vt 0.408989 0.395395 +vt 0.408786 0.395410 +vt 0.408683 0.401523 +vt 0.408886 0.401508 +vt 0.408735 0.541727 +vt 0.408532 0.541719 +vt 0.408645 0.548755 +vt 0.408848 0.548765 +vt 0.229689 0.964199 +vt 0.229799 0.964117 +vt 0.225316 0.957276 +vt 0.225195 0.957342 +vt 0.408786 0.555583 +vt 0.408989 0.555595 +vt 0.408178 0.474662 +vt 0.408381 0.474655 +vt 0.288772 0.995977 +vt 0.288752 0.996113 +vt 0.278964 0.994052 +vt 0.278951 0.994192 +vt 0.408171 0.484316 +vt 0.408374 0.484309 +vt 0.408177 0.493726 +vt 0.408377 0.493976 +vt 0.269938 0.991543 +vt 0.269741 0.991612 +vt 0.264448 0.989739 +vt 0.262850 0.989264 +vt 0.408174 0.500949 +vt 0.408350 0.503505 +vt 0.870456 0.445845 +vt 0.870252 0.445851 +vt 0.870227 0.457410 +vt 0.870431 0.457405 +vt 0.385318 0.793029 +vt 0.385176 0.793043 +vt 0.383725 0.804627 +vt 0.383864 0.804626 +vt 0.213310 0.921475 +vt 0.213172 0.921480 +vt 0.988805 0.811245 +vt 0.988601 0.811237 +vt 0.176792 0.984804 +vt 0.176725 0.984684 +vt 0.410208 0.510803 +vt 0.410411 0.510801 +vt 0.870486 0.434939 +vt 0.870283 0.434962 +vt 0.870271 0.438578 +vt 0.870475 0.438564 +vt 0.387214 0.782251 +vt 0.387051 0.782376 +vt 0.386348 0.785873 +vt 0.386501 0.785807 +vt 0.608988 0.022210 +vt 0.608784 0.022195 +vt 0.289974 0.792738 +vt 0.290104 0.792661 +vt 0.928319 0.411220 +vt 0.928523 0.411207 +vt 0.928523 0.406952 +vt 0.928319 0.406961 +vt 0.990770 0.665626 +vt 0.990567 0.665608 +vt 0.260752 0.780218 +vt 0.260753 0.780077 +vt 0.082616 0.777547 +vt 0.082581 0.777685 +vt 0.887419 0.624767 +vt 0.887622 0.624777 +vt 0.049496 0.986901 +vt 0.049552 0.986775 +vt 0.495711 0.291999 +vt 0.495507 0.292014 +vt 0.410957 0.395401 +vt 0.410753 0.395387 +vt 0.608964 0.038385 +vt 0.608761 0.038392 +vt 0.276850 0.778730 +vt 0.276842 0.778591 +vt 0.990774 0.788889 +vt 0.990570 0.788893 +vt 0.221484 0.898376 +vt 0.221350 0.898342 +vt 0.225601 0.885235 +vt 0.225472 0.885187 +vt 0.990773 0.775296 +vt 0.990570 0.775299 +vt 0.885443 0.651759 +vt 0.885646 0.651756 +vt 0.376242 0.776591 +vt 0.376251 0.776451 +vt 0.021794 0.968325 +vt 0.021893 0.968229 +vt 0.495391 0.317366 +vt 0.495187 0.317375 +vt 0.283307 0.272824 +vt 0.283511 0.272892 +vt 0.283510 0.268688 +vt 0.283307 0.268668 +vt 0.308874 0.799331 +vt 0.308823 0.799148 +vt 0.817978 0.030674 +vt 0.818181 0.030688 +vt 0.818182 0.023012 +vt 0.817978 0.022999 +vt 0.394268 0.844323 +vt 0.394386 0.844250 +vt 0.885450 0.632441 +vt 0.885653 0.632442 +vt 0.356225 0.777098 +vt 0.356259 0.776957 +vt 0.990772 0.762241 +vt 0.990569 0.762241 +vt 0.230836 0.873264 +vt 0.230711 0.873203 +vt 0.408592 0.408453 +vt 0.408795 0.408439 +vt 0.363987 0.992580 +vt 0.364021 0.992714 +vt 0.408484 0.517405 +vt 0.408282 0.517492 +vt 0.408324 0.523080 +vt 0.408527 0.523079 +vt 0.248315 0.981316 +vt 0.243789 0.978025 +vt 0.243663 0.978102 +vt 0.239279 0.974369 +vt 0.239170 0.974459 +vt 0.408374 0.528712 +vt 0.408577 0.528719 +vt 0.870877 0.485920 +vt 0.870825 0.478809 +vt 0.871372 0.485922 +vt 0.871320 0.478811 +vt 0.871302 0.469598 +vt 0.870806 0.469596 +vt 0.871868 0.485924 +vt 0.871816 0.478813 +vt 0.871797 0.469600 +vt 0.496722 0.323692 +vt 0.496682 0.330977 +vt 0.496227 0.323692 +vt 0.496186 0.330977 +vt 0.496154 0.339637 +vt 0.496650 0.339637 +vt 0.495731 0.323691 +vt 0.495691 0.330976 +vt 0.495659 0.339636 +vt 0.608384 0.026976 +vt 0.608380 0.031716 +vt 0.607888 0.026977 +vt 0.607885 0.031717 +vt 0.607884 0.035654 +vt 0.608380 0.035653 +vt 0.607393 0.026978 +vt 0.607390 0.031718 +vt 0.607389 0.035655 +vt 0.990182 0.696754 +vt 0.990180 0.703463 +vt 0.989686 0.696754 +vt 0.989685 0.703463 +vt 0.989683 0.711060 +vt 0.990179 0.711060 +vt 0.989191 0.696754 +vt 0.989189 0.703463 +vt 0.989188 0.711060 +vt 0.885535 0.618812 +vt 0.885650 0.618643 +vt 0.885595 0.616140 +vt 0.885515 0.616188 +vt 0.885780 0.618118 +vt 0.885759 0.616133 +vt 0.885778 0.614149 +vt 0.885648 0.613635 +vt 0.885534 0.613549 +vt 0.886452 0.620466 +vt 0.887034 0.620502 +vt 0.887041 0.616310 +vt 0.886541 0.616245 +vt 0.887034 0.613209 +vt 0.886452 0.612872 +vt 0.282920 0.248884 +vt 0.282920 0.254942 +vt 0.282425 0.248884 +vt 0.282425 0.254942 +vt 0.282424 0.262082 +vt 0.282920 0.262082 +vt 0.281929 0.248884 +vt 0.281929 0.254942 +vt 0.281929 0.262082 +vt 0.990180 0.670938 +vt 0.990182 0.677696 +vt 0.989685 0.670938 +vt 0.989687 0.677696 +vt 0.989688 0.684664 +vt 0.990183 0.684664 +vt 0.989190 0.670938 +vt 0.989191 0.677696 +vt 0.989192 0.684664 +vt 0.886044 0.604150 +vt 0.886046 0.598851 +vt 0.886539 0.604151 +vt 0.886541 0.598852 +vt 0.886533 0.594486 +vt 0.886038 0.594485 +vt 0.887035 0.604152 +vt 0.887037 0.598853 +vt 0.887029 0.594487 +vt 0.990183 0.801346 +vt 0.990182 0.811245 +vt 0.989688 0.801346 +vt 0.989687 0.811245 +vt 0.989686 0.819524 +vt 0.990182 0.819524 +vt 0.989192 0.801346 +vt 0.989192 0.811245 +vt 0.989191 0.819525 +vt 0.990183 0.690792 +vt 0.989688 0.690792 +vt 0.989192 0.690792 +vt 0.496786 0.391506 +vt 0.496867 0.399544 +vt 0.496291 0.391506 +vt 0.496371 0.399544 +vt 0.496472 0.408008 +vt 0.496968 0.408009 +vt 0.495795 0.391505 +vt 0.495876 0.399544 +vt 0.495977 0.408008 +vt 0.990180 0.827325 +vt 0.989685 0.827325 +vt 0.989683 0.834262 +vt 0.990179 0.834262 +vt 0.989190 0.827325 +vt 0.989188 0.834262 +vt 0.885659 0.610885 +vt 0.886046 0.610886 +vt 0.886044 0.608349 +vt 0.885657 0.608348 +vt 0.886542 0.610887 +vt 0.886539 0.608350 +vt 0.887037 0.610888 +vt 0.887035 0.608351 +vt 0.887422 0.608351 +vt 0.608386 0.047805 +vt 0.608397 0.050590 +vt 0.607890 0.047806 +vt 0.607902 0.050591 +vt 0.990178 0.659496 +vt 0.989683 0.659496 +vt 0.989684 0.661867 +vt 0.990179 0.661867 +vt 0.607395 0.047807 +vt 0.607406 0.050592 +vt 0.989188 0.659496 +vt 0.989188 0.661867 +vt 0.409376 0.555594 +vt 0.409236 0.548764 +vt 0.409871 0.555592 +vt 0.409731 0.548761 +vt 0.409617 0.541723 +vt 0.409122 0.541726 +vt 0.410366 0.555589 +vt 0.410226 0.548759 +vt 0.410112 0.541721 +vt 0.497088 0.416923 +vt 0.496593 0.416923 +vt 0.817591 0.004562 +vt 0.817096 0.004564 +vt 0.817094 0.013984 +vt 0.817589 0.013982 +vt 0.496098 0.416923 +vt 0.816601 0.004567 +vt 0.816599 0.013987 +vt 0.496630 0.349651 +vt 0.496135 0.349651 +vt 0.496132 0.359618 +vt 0.496627 0.359618 +vt 0.495640 0.349650 +vt 0.495637 0.359617 +vt 0.990179 0.728806 +vt 0.990180 0.738991 +vt 0.989683 0.728806 +vt 0.989684 0.738991 +vt 0.989685 0.750121 +vt 0.990181 0.750121 +vt 0.989188 0.728806 +vt 0.989189 0.738991 +vt 0.989190 0.750121 +vt 0.886035 0.628759 +vt 0.886032 0.624906 +vt 0.886530 0.628760 +vt 0.886527 0.624791 +vt 0.885972 0.621723 +vt 0.887025 0.628761 +vt 0.887030 0.624766 +vt 0.922803 0.641613 +vt 0.922801 0.638019 +vt 0.923299 0.641613 +vt 0.923297 0.638018 +vt 0.923299 0.634604 +vt 0.922804 0.634604 +vt 0.923794 0.641612 +vt 0.923792 0.638018 +vt 0.923795 0.634604 +vt 0.608370 0.040952 +vt 0.608375 0.044302 +vt 0.607874 0.040953 +vt 0.607880 0.044303 +vt 0.607379 0.040954 +vt 0.607384 0.044304 +vt 0.990178 0.719505 +vt 0.989683 0.719505 +vt 0.989188 0.719505 +vt 0.496826 0.311221 +vt 0.496768 0.317367 +vt 0.496331 0.311221 +vt 0.496273 0.317367 +vt 0.495836 0.311220 +vt 0.495778 0.317366 +vt 0.408796 0.464313 +vt 0.408845 0.452585 +vt 0.409291 0.464310 +vt 0.409340 0.452583 +vt 0.409410 0.440095 +vt 0.408915 0.440098 +vt 0.409786 0.464308 +vt 0.409836 0.452581 +vt 0.409906 0.440093 +vt 0.496643 0.368239 +vt 0.496148 0.368238 +vt 0.496181 0.375999 +vt 0.496676 0.375999 +vt 0.495653 0.368238 +vt 0.495686 0.375998 +vt 0.408789 0.503097 +vt 0.408769 0.493985 +vt 0.409290 0.503048 +vt 0.409265 0.493972 +vt 0.409256 0.484305 +vt 0.408761 0.484307 +vt 0.409785 0.503046 +vt 0.409761 0.493970 +vt 0.409751 0.484302 +vt 0.496723 0.383687 +vt 0.496228 0.383686 +vt 0.495733 0.383686 +vt 0.408871 0.517358 +vt 0.408829 0.510834 +vt 0.408438 0.511057 +vt 0.409366 0.517349 +vt 0.409325 0.510807 +vt 0.409862 0.517347 +vt 0.409820 0.510805 +vt 0.409273 0.401506 +vt 0.409376 0.395393 +vt 0.409768 0.401504 +vt 0.409871 0.395391 +vt 0.497088 0.292000 +vt 0.496593 0.291999 +vt 0.496496 0.298044 +vt 0.496991 0.298045 +vt 0.410264 0.401502 +vt 0.410366 0.395388 +vt 0.496098 0.291999 +vt 0.496001 0.298044 +vt 0.870818 0.457407 +vt 0.871313 0.457409 +vt 0.871338 0.445848 +vt 0.870843 0.445846 +vt 0.871809 0.457411 +vt 0.871833 0.445850 +vt 0.408768 0.474654 +vt 0.409263 0.474652 +vt 0.409759 0.474649 +vt 0.922798 0.632892 +vt 0.922411 0.632892 +vt 0.923293 0.632891 +vt 0.200357 0.418707 +vt 0.200357 0.418211 +vt 0.198692 0.418212 +vt 0.198692 0.418707 +vt 0.923788 0.632891 +vt 0.924176 0.632891 +vt 0.200357 0.417716 +vt 0.198692 0.417716 +vt 0.930016 0.535537 +vt 0.930012 0.534135 +vt 0.930512 0.535535 +vt 0.930507 0.534133 +vt 0.930511 0.531571 +vt 0.930016 0.531573 +vt 0.931007 0.535533 +vt 0.931003 0.534131 +vt 0.931007 0.531570 +vt 0.886010 0.662809 +vt 0.886018 0.660699 +vt 0.886505 0.662810 +vt 0.886513 0.660699 +vt 0.886522 0.657004 +vt 0.886026 0.657003 +vt 0.887000 0.662811 +vt 0.887008 0.660700 +vt 0.887017 0.657005 +vt 0.409032 0.534952 +vt 0.408645 0.534954 +vt 0.409528 0.534950 +vt 0.409460 0.528716 +vt 0.408964 0.528718 +vt 0.410023 0.534948 +vt 0.409955 0.528713 +vt 0.870874 0.434941 +vt 0.870877 0.433377 +vt 0.870490 0.433375 +vt 0.871369 0.434943 +vt 0.871372 0.433379 +vt 0.886004 0.663632 +vt 0.886500 0.663633 +vt 0.885617 0.663632 +vt 0.871864 0.434945 +vt 0.871868 0.433381 +vt 0.872255 0.433382 +vt 0.886995 0.663634 +vt 0.887382 0.663635 +vt 0.927932 0.406956 +vt 0.927932 0.411214 +vt 0.927437 0.406949 +vt 0.927437 0.411208 +vt 0.608397 0.022196 +vt 0.607902 0.022197 +vt 0.926942 0.406942 +vt 0.926942 0.411201 +vt 0.607406 0.022198 +vt 0.990179 0.665608 +vt 0.989684 0.665608 +vt 0.989189 0.665608 +vt 0.886040 0.645987 +vt 0.886047 0.640758 +vt 0.886536 0.645988 +vt 0.886542 0.640759 +vt 0.886543 0.636278 +vt 0.886048 0.636278 +vt 0.887031 0.645989 +vt 0.887037 0.640760 +vt 0.887038 0.636279 +vt 0.409002 0.427848 +vt 0.409497 0.427846 +vt 0.409589 0.417010 +vt 0.409093 0.417012 +vt 0.409992 0.427844 +vt 0.410084 0.417007 +vt 0.608374 0.038392 +vt 0.607878 0.038393 +vt 0.607383 0.038394 +vt 0.990183 0.775299 +vt 0.990183 0.788893 +vt 0.989687 0.775299 +vt 0.989688 0.788893 +vt 0.989192 0.775299 +vt 0.989192 0.788893 +vt 0.886033 0.651757 +vt 0.886529 0.651757 +vt 0.887024 0.651758 +vt 0.496902 0.304640 +vt 0.496407 0.304639 +vt 0.495912 0.304639 +vt 0.282920 0.268668 +vt 0.282424 0.268668 +vt 0.282425 0.272824 +vt 0.282920 0.272824 +vt 0.281929 0.268668 +vt 0.281929 0.272824 +vt 0.817591 0.023001 +vt 0.817096 0.023003 +vt 0.817095 0.030678 +vt 0.817591 0.030676 +vt 0.816601 0.023005 +vt 0.816600 0.030681 +vt 0.886040 0.632442 +vt 0.886536 0.632443 +vt 0.887031 0.632444 +vt 0.990182 0.762241 +vt 0.989687 0.762242 +vt 0.989191 0.762242 +vt 0.409182 0.408438 +vt 0.409677 0.408436 +vt 0.410172 0.408433 +vt 0.408914 0.523072 +vt 0.409409 0.523069 +vt 0.409904 0.523067 +vt 0.408442 0.534947 +vt 0.234562 0.969790 +vt 0.234459 0.969882 +vt 0.042802 0.835795 +vt 0.036993 0.844533 +vt 0.030050 0.854239 +vt 0.049470 0.777773 +vt 0.046169 0.779035 +vt 0.044536 0.780233 +vt 0.046097 0.793007 +vt 0.047550 0.804591 +vt 0.048108 0.817180 +vt 0.086433 0.776631 +vt 0.082501 0.778020 +vt 0.078690 0.778799 +vt 0.046585 0.827271 +vt 0.070391 0.775677 +vt 0.065718 0.775477 +vt 0.060449 0.776214 +vt 0.044246 0.782583 +vt 0.044934 0.785947 +vt 0.119229 0.793920 +vt 0.117077 0.786610 +vt 0.113943 0.781235 +vt 0.121647 0.800652 +vt 0.096208 0.777937 +vt 0.094985 0.777442 +vt 0.093625 0.776951 +vt 0.108974 0.779242 +vt 0.103958 0.778768 +vt 0.103470 0.778987 +vt 0.022973 0.865117 +vt 0.016552 0.876184 +vt 0.011386 0.886423 +vt 0.007529 0.895859 +vt 0.009166 0.948271 +vt 0.013240 0.956041 +vt 0.017589 0.962325 +vt 0.058095 0.989294 +vt 0.067004 0.991840 +vt 0.077486 0.993878 +vt 0.034161 0.977361 +vt 0.041745 0.982054 +vt 0.090296 0.995541 +vt 0.104394 0.996620 +vt 0.003298 0.913191 +vt 0.002693 0.921354 +vt 0.003394 0.929753 +vt 0.193665 0.862861 +vt 0.187736 0.853343 +vt 0.182780 0.844369 +vt 0.183317 0.794923 +vt 0.178894 0.789844 +vt 0.173491 0.785246 +vt 0.178927 0.826251 +vt 0.180173 0.817030 +vt 0.182392 0.808383 +vt 0.153870 0.779613 +vt 0.151793 0.782276 +vt 0.179751 0.835391 +vt 0.167954 0.777976 +vt 0.184106 0.800983 +vt 0.134986 0.803295 +vt 0.133379 0.805075 +vt 0.131126 0.806787 +vt 0.144748 0.787895 +vt 0.141309 0.792999 +vt 0.138493 0.798196 +vt 0.136510 0.801402 +vt 0.204768 0.885462 +vt 0.199544 0.873486 +vt 0.211569 0.911145 +vt 0.208876 0.898582 +vt 0.191431 0.973694 +vt 0.196132 0.969135 +vt 0.200883 0.963486 +vt 0.131138 0.996398 +vt 0.151791 0.993323 +vt 0.182180 0.980596 +vt 0.118373 0.996889 +vt 0.208864 0.949079 +vt 0.211215 0.940394 +vt 0.212483 0.931070 +vt 0.090534 0.776427 +vt 0.049750 0.986053 +vt 0.074687 0.777432 +vt 0.022150 0.967571 +vt 0.054625 0.776922 +vt 0.005679 0.939022 +vt 0.004886 0.904743 +vt 0.212692 0.921673 +vt 0.161184 0.990641 +vt 0.205316 0.956748 +vt 0.186933 0.977330 +vt 0.400793 0.854242 +vt 0.393850 0.844535 +vt 0.388042 0.835798 +vt 0.386308 0.780236 +vt 0.384675 0.779039 +vt 0.381374 0.777777 +vt 0.382736 0.817182 +vt 0.383294 0.804594 +vt 0.384747 0.793010 +vt 0.352084 0.778841 +vt 0.345525 0.776545 +vt 0.384259 0.827274 +vt 0.370395 0.776218 +vt 0.365126 0.775480 +vt 0.360453 0.775681 +vt 0.386599 0.782587 +vt 0.386818 0.781121 +vt 0.387263 0.780843 +vt 0.316907 0.781230 +vt 0.313769 0.786605 +vt 0.311615 0.793921 +vt 0.309197 0.800655 +vt 0.306269 0.805282 +vt 0.334500 0.777636 +vt 0.331754 0.778393 +vt 0.333249 0.779202 +vt 0.334036 0.777713 +vt 0.331281 0.778353 +vt 0.326878 0.778749 +vt 0.327359 0.778942 +vt 0.321878 0.779241 +vt 0.414292 0.876186 +vt 0.407870 0.865119 +vt 0.423307 0.895831 +vt 0.419457 0.886421 +vt 0.417393 0.956160 +vt 0.420238 0.948814 +vt 0.353356 0.993878 +vt 0.363838 0.991840 +vt 0.389097 0.982054 +vt 0.396681 0.977362 +vt 0.248063 0.844371 +vt 0.243107 0.853346 +vt 0.237179 0.862863 +vt 0.257353 0.785249 +vt 0.251950 0.789847 +vt 0.247527 0.794926 +vt 0.248452 0.808386 +vt 0.250671 0.817033 +vt 0.251917 0.826254 +vt 0.251092 0.835394 +vt 0.246737 0.800986 +vt 0.297465 0.805078 +vt 0.295858 0.803298 +vt 0.292351 0.798199 +vt 0.289535 0.793002 +vt 0.286096 0.787898 +vt 0.294334 0.801405 +vt 0.231299 0.873488 +vt 0.226075 0.885464 +vt 0.221967 0.898584 +vt 0.219273 0.911146 +vt 0.229959 0.963487 +vt 0.234718 0.969141 +vt 0.239471 0.973737 +vt 0.278986 0.993302 +vt 0.299704 0.996398 +vt 0.312470 0.996889 +vt 0.218359 0.931071 +vt 0.219627 0.940396 +vt 0.221979 0.949080 +vt 0.356148 0.777440 +vt 0.408691 0.967575 +vt 0.376219 0.776925 +vt 0.426257 0.912863 +vt 0.425786 0.904630 +vt 0.218151 0.921675 +vt 0.225527 0.956749 +vt 0.244055 0.977440 +vt 0.885588 0.620290 +vt 0.885803 0.620084 +vt 0.886014 0.618908 +vt 0.886012 0.613470 +vt 0.885800 0.612365 +vt 0.885972 0.611987 +vt 0.505794 0.773084 +vt 0.505623 0.773538 +vt 0.506009 0.773184 +vt 0.885585 0.612218 +vt 0.886079 0.616154 +vt 0.253308 0.984448 +vt 0.408241 0.511634 +vt 0.408197 0.506902 +vt 0.257412 0.986832 +vt 0.259621 0.987840 +vt 0.408148 0.504476 +vt 0.344346 0.775696 +vt 0.885453 0.620566 +vt 0.344118 0.775460 +vt 0.885451 0.612240 +vt 0.885445 0.613602 +vt 0.506143 0.773200 +vt 0.335534 0.776727 +vt 0.335587 0.776835 +vt 0.335513 0.777110 +vt 0.385910 0.785950 +vt 0.099016 0.778562 +vt 0.099537 0.778415 +vt 0.044027 0.781118 +vt 0.043581 0.780840 +vt 0.871853 0.438570 +vt 0.871357 0.438568 +vt 0.870862 0.438565 +vt 0.887037 0.611941 +vt 0.886535 0.611881 +vt 0.505556 0.773972 +vt 0.505141 0.772931 +vt 0.505061 0.773919 +vt 0.886040 0.611798 +vt 0.885658 0.611779 +vt 0.885414 0.663614 +vt 0.387428 0.780691 +vt 0.870286 0.433401 +vt 0.885454 0.608365 +vt 0.885379 0.608485 +vt 0.887625 0.608374 +vt 0.887700 0.608529 +vt 0.887702 0.611086 +vt 0.043416 0.780688 +vt 0.887585 0.663617 +vt 0.872458 0.433411 +vn 0.0000 0.0000 1.0000 +vn -0.0008 0.0003 1.0000 +vn -0.0008 0.0002 1.0000 +vn 0.0006 0.0002 1.0000 +vn 0.0004 0.0005 1.0000 +vn 0.0005 0.0002 1.0000 +vn 0.0011 0.0028 1.0000 +vn 0.0001 0.0007 1.0000 +vn 0.0001 0.0010 1.0000 +vn -0.0009 0.0004 1.0000 +vn -0.0018 -0.0002 1.0000 +vn -0.0003 0.0004 1.0000 +vn -0.0004 0.0002 1.0000 +vn 0.0003 0.0003 1.0000 +vn -0.0005 0.0007 1.0000 +vn 0.0002 -0.0004 1.0000 +vn 0.0005 -0.0006 1.0000 +vn 0.0005 -0.0005 1.0000 +vn 0.0017 -0.0007 1.0000 +vn 0.0000 -0.0005 1.0000 +vn 0.0001 -0.0005 1.0000 +vn -0.0014 -0.0000 1.0000 +vn -0.0014 -0.0002 1.0000 +vn -0.0017 -0.0004 1.0000 +vn -0.0010 0.0006 1.0000 +vn -0.0012 0.0005 1.0000 +vn -0.0013 0.0003 1.0000 +vn -0.0010 0.0001 1.0000 +vn -0.0011 0.0000 1.0000 +vn -0.0005 0.0004 1.0000 +vn 0.0007 -0.0006 1.0000 +vn 0.0009 -0.0006 1.0000 +vn 0.0013 0.0000 1.0000 +vn 0.0013 -0.0002 1.0000 +vn 0.0011 -0.0002 1.0000 +vn 0.0010 -0.0000 1.0000 +vn 0.0006 0.0006 1.0000 +vn 0.0003 0.0004 1.0000 +vn 0.0010 0.0006 1.0000 +vn 0.0011 0.0007 1.0000 +vn 0.0009 0.0006 1.0000 +vn 0.0013 0.0006 1.0000 +vn 0.0014 0.0003 1.0000 +vn 0.0003 -0.0004 1.0000 +vn 0.0001 0.0003 1.0000 +vn -0.0000 0.0003 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0011 0.0037 -1.0000 +vn 0.0001 0.0033 -1.0000 +vn 0.0005 0.0002 -1.0000 +vn 0.0006 0.0002 -1.0000 +vn 0.0003 0.0002 -1.0000 +vn -0.0008 0.0039 -1.0000 +vn -0.0007 0.0038 -1.0000 +vn -0.0002 -0.0005 -1.0000 +vn -0.0002 -0.0004 -1.0000 +vn -0.0005 -0.0005 -1.0000 +vn -0.0005 -0.0004 -1.0000 +vn 0.0000 -0.0005 -1.0000 +vn 0.0009 0.0003 -1.0000 +vn 0.0009 0.0002 -1.0000 +vn -0.0004 0.0004 -1.0000 +vn -0.0001 0.0003 -1.0000 +vn -0.0004 0.0002 -1.0000 +vn -0.0011 0.0005 -1.0000 +vn -0.0006 0.0003 -1.0000 +vn -0.0008 0.0004 -1.0000 +vn 0.0009 0.0005 -1.0000 +vn 0.0008 0.0003 -1.0000 +vn 0.0020 -0.0003 -1.0000 +vn -0.0001 -0.0005 -1.0000 +vn 0.0000 -0.0001 -1.0000 +vn -0.0006 0.0028 -1.0000 +vn -0.0000 0.0002 -1.0000 +vn -0.0018 0.0098 -1.0000 +vn -0.0002 0.0006 -1.0000 +vn -0.0003 -0.0004 -1.0000 +vn -0.0004 0.0041 -1.0000 +vn 0.0010 0.0045 -1.0000 +vn -0.0007 -0.0004 -1.0000 +vn -0.0007 -0.0003 -1.0000 +vn -0.0003 -0.0000 -1.0000 +vn -0.0014 -0.0000 -1.0000 +vn -0.0014 -0.0002 -1.0000 +vn -0.0015 -0.0003 -1.0000 +vn -0.0017 -0.0004 -1.0000 +vn -0.0025 0.0003 -1.0000 +vn -0.0022 0.0036 -1.0000 +vn -0.0013 0.0039 -1.0000 +vn -0.0010 0.0006 -1.0000 +vn -0.0009 0.0006 -1.0000 +vn -0.0012 0.0005 -1.0000 +vn -0.0011 0.0006 -1.0000 +vn -0.0013 0.0003 -1.0000 +vn -0.0005 -0.0001 -1.0000 +vn 0.0011 0.0001 -1.0000 +vn 0.0014 -0.0001 -1.0000 +vn 0.0013 0.0000 -1.0000 +vn 0.0013 -0.0002 -1.0000 +vn 0.0011 -0.0002 -1.0000 +vn 0.0009 0.0006 -1.0000 +vn 0.0011 0.0007 -1.0000 +vn 0.0013 0.0006 -1.0000 +vn 0.0014 0.0003 -1.0000 +vn 0.0004 0.0004 1.0000 +vn 0.0048 0.0141 0.9999 +vn 0.0003 0.0007 1.0000 +vn 0.0001 0.0004 1.0000 +vn -0.0003 0.0135 0.9999 +vn -0.0000 0.0004 1.0000 +vn 0.0000 0.0026 1.0000 +vn 0.0001 0.0001 1.0000 +vn 0.0022 0.0036 1.0000 +vn 0.0034 -0.0164 0.9999 +vn 0.0002 -0.0005 1.0000 +vn 0.0100 -0.0157 0.9998 +vn 0.0003 -0.0005 1.0000 +vn -0.0004 -0.0005 1.0000 +vn -0.0111 -0.0148 0.9998 +vn -0.0004 0.0006 1.0000 +vn -0.0152 0.0167 0.9997 +vn -0.0006 0.0009 1.0000 +vn 0.0002 -0.0006 1.0000 +vn 0.0082 -0.0161 0.9998 +vn 0.0003 -0.0007 1.0000 +vn 0.0172 0.0150 0.9997 +vn -0.0042 0.0144 0.9999 +vn -0.0001 0.0004 1.0000 +vn -0.0171 0.0168 0.9997 +vn -0.0003 0.0007 1.0000 +vn -0.0096 0.0307 -0.9995 +vn -0.0015 0.0082 -1.0000 +vn -0.0001 -0.0004 -1.0000 +vn -0.0045 -0.0160 -0.9999 +vn -0.0003 -0.0005 -1.0000 +vn -0.0111 -0.0148 -0.9998 +vn -0.0004 -0.0005 -1.0000 +vn 0.0000 -0.0004 -1.0000 +vn -0.0008 -0.0165 -0.9999 +vn -0.0006 0.0006 -1.0000 +vn -0.0221 0.0158 -0.9996 +vn -0.0008 0.0006 -1.0000 +vn -0.0006 0.0005 -1.0000 +vn -0.0171 0.0168 -0.9997 +vn -0.0004 0.0005 -1.0000 +vn 0.0001 0.0007 -1.0000 +vn 0.0048 0.0141 -0.9999 +vn 0.0003 0.0007 -1.0000 +vn 0.0164 0.0149 -0.9998 +vn 0.0000 0.0025 -1.0000 +vn -0.0000 0.0001 -1.0000 +vn 0.0001 0.0003 -1.0000 +vn -0.0010 0.0022 -1.0000 +vn 0.0002 -0.0007 -1.0000 +vn 0.0034 -0.0163 -0.9999 +vn 0.0001 -0.0004 -1.0000 +vn 0.0001 -0.0166 -0.9999 +vn -0.0060 -0.0157 -0.9999 +vn -0.0163 -0.0135 -0.9998 +vn -0.0006 -0.0005 -1.0000 +vn -0.0007 -0.0002 -1.0000 +vn -0.0039 -0.0009 -1.0000 +vn -0.0002 -0.0000 -1.0000 +vn -0.0001 -0.0000 -1.0000 +vn -0.0001 -0.0001 -1.0000 +vn -0.0038 -0.0008 -1.0000 +vn -0.0011 0.0009 -1.0000 +vn -0.0152 0.0167 -0.9997 +vn -0.0008 0.0013 -1.0000 +vn -0.0138 0.0145 -0.9998 +vn 0.0022 -0.0045 -1.0000 +vn 0.0069 -0.0173 -0.9998 +vn 0.0007 -0.0013 -1.0000 +vn 0.0004 0.0005 -1.0000 +vn 0.0172 0.0149 -0.9997 +vn 0.0006 0.0006 -1.0000 +vn -0.0003 0.0007 -1.0000 +vn -0.0041 0.0144 -0.9999 +vn -0.0001 0.0004 -1.0000 +vn -0.0003 0.0135 -0.9999 +vn -0.0000 0.0004 -1.0000 +vn 0.0311 -0.0555 -0.9980 +vn 0.0263 -0.0551 -0.9981 +vn 0.0024 -0.0047 -1.0000 +vn -0.0015 -0.0004 -1.0000 +vn -0.0001 0.0005 -1.0000 +vn -0.0002 0.0011 -1.0000 +vn -0.0015 -0.0003 1.0000 +vn 0.0003 0.0015 1.0000 +vn 0.0007 0.0017 1.0000 +vn -0.0010 0.0003 1.0000 +vn -0.0000 0.0029 1.0000 +vn 0.0012 0.0038 1.0000 +vn 0.0010 0.0045 1.0000 +vn 0.0010 0.0003 1.0000 +vn 0.0005 0.0006 1.0000 +vn 0.0004 0.0002 1.0000 +vn -0.0007 0.0039 1.0000 +vn -0.0008 0.0040 1.0000 +vn -0.0014 0.0040 1.0000 +vn 0.0008 0.0019 1.0000 +vn 0.0013 0.0030 1.0000 +vn 0.0008 0.0063 1.0000 +vn -0.0004 0.0060 1.0000 +vn -0.0017 0.0052 1.0000 +vn 0.0001 0.0009 1.0000 +vn 0.0001 0.0013 1.0000 +vn -0.0012 0.0007 1.0000 +vn -0.0008 0.0004 1.0000 +vn -0.0002 -0.0005 1.0000 +vn -0.0001 -0.0005 1.0000 +vn -0.0006 -0.0005 1.0000 +vn -0.0002 -0.0003 1.0000 +vn -0.0017 0.0001 1.0000 +vn -0.0017 -0.0002 1.0000 +vn -0.0020 -0.0005 1.0000 +vn -0.0019 -0.0006 1.0000 +vn -0.0011 -0.0005 1.0000 +vn 0.0010 0.0002 1.0000 +vn 0.0009 0.0003 1.0000 +vn 0.0009 0.0004 1.0000 +vn -0.0005 0.0002 1.0000 +vn 0.0002 0.0002 1.0000 +vn -0.0008 0.0009 1.0000 +vn -0.0014 0.0011 1.0000 +vn -0.0010 0.0005 1.0000 +vn -0.0006 0.0003 1.0000 +vn 0.0009 0.0005 1.0000 +vn 0.0012 0.0008 1.0000 +vn 0.0003 -0.0008 1.0000 +vn 0.0012 -0.0008 1.0000 +vn 0.0021 -0.0006 1.0000 +vn 0.0020 -0.0003 1.0000 +vn 0.0014 -0.0001 1.0000 +vn 0.0000 -0.0006 1.0000 +vn -0.0012 0.0036 1.0000 +vn -0.0003 -0.0005 1.0000 +vn -0.0004 0.0042 1.0000 +vn -0.0008 -0.0005 1.0000 +vn -0.0015 -0.0000 1.0000 +vn -0.0018 -0.0003 1.0000 +vn -0.0019 -0.0005 1.0000 +vn -0.0022 0.0000 1.0000 +vn -0.0024 0.0039 1.0000 +vn -0.0032 0.0030 1.0000 +vn -0.0009 0.0005 1.0000 +vn -0.0011 0.0005 1.0000 +vn -0.0012 0.0003 1.0000 +vn 0.0012 0.0001 1.0000 +vn 0.0001 -0.0006 1.0000 +vn -0.0007 0.0007 1.0000 +vn -0.0006 0.0005 1.0000 +vn -0.0004 0.0005 1.0000 +vn 0.0009 -0.0007 1.0000 +vn 0.0013 0.0005 1.0000 +vn 0.0007 0.0009 1.0000 +vn 0.0005 -0.0007 1.0000 +vn -0.0010 0.0003 -1.0000 +vn -0.0009 0.0003 -1.0000 +vn -0.0009 0.0004 -1.0000 +vn 0.0010 0.0046 -1.0000 +vn 0.0012 0.0038 -1.0000 +vn 0.0001 0.0034 -1.0000 +vn 0.0005 0.0006 -1.0000 +vn -0.0014 0.0040 -1.0000 +vn -0.0008 0.0041 -1.0000 +vn -0.0007 0.0039 -1.0000 +vn -0.0001 0.0007 -1.0000 +vn -0.0018 0.0212 -0.9998 +vn -0.0003 0.0014 -1.0000 +vn -0.0011 0.0428 -0.9991 +vn -0.0028 0.0909 -0.9959 +vn 0.0093 0.1820 -0.9833 +vn 0.0010 0.0356 -0.9994 +vn 0.0004 0.0031 -1.0000 +vn 0.0001 0.0012 -1.0000 +vn -0.0009 0.0005 -1.0000 +vn -0.0012 0.0007 -1.0000 +vn -0.0002 -0.0006 -1.0000 +vn -0.0003 -0.0006 -1.0000 +vn -0.0005 -0.0007 -1.0000 +vn -0.0007 -0.0007 -1.0000 +vn -0.0004 -0.0001 -1.0000 +vn -0.0047 -0.0014 -1.0000 +vn -0.0086 -0.0019 -1.0000 +vn -0.0045 -0.0005 -1.0000 +vn -0.0508 -0.0217 -0.9985 +vn -0.0571 -0.0184 -0.9982 +vn -0.0633 -0.0157 -0.9979 +vn -0.0548 -0.0064 -0.9985 +vn -0.0487 -0.0002 -0.9988 +vn -0.0000 -0.0006 -1.0000 +vn -0.0001 -0.0006 -1.0000 +vn 0.0012 0.0005 -1.0000 +vn 0.0010 0.0003 -1.0000 +vn -0.0003 0.0004 -1.0000 +vn -0.0006 0.0002 -1.0000 +vn -0.0003 0.0002 -1.0000 +vn 0.0004 0.0004 -1.0000 +vn -0.0010 0.0004 -1.0000 +vn -0.0011 0.0008 -1.0000 +vn -0.0005 0.0006 -1.0000 +vn -0.0008 0.0003 -1.0000 +vn 0.0011 0.0006 -1.0000 +vn 0.0002 -0.0001 -1.0000 +vn 0.0000 -0.0003 -1.0000 +vn 0.0006 -0.0010 -1.0000 +vn 0.0002 -0.0005 -1.0000 +vn 0.0006 -0.0005 -1.0000 +vn 0.0005 -0.0005 -1.0000 +vn 0.0004 -0.0006 -1.0000 +vn 0.0022 -0.0004 -1.0000 +vn 0.0021 -0.0006 -1.0000 +vn 0.0017 -0.0007 -1.0000 +vn 0.0009 -0.0006 -1.0000 +vn 0.0001 -0.0005 -1.0000 +vn -0.0001 -0.0008 -1.0000 +vn 0.0001 0.0000 -1.0000 +vn 0.0002 0.0002 -1.0000 +vn -0.0004 0.0027 -1.0000 +vn -0.0015 0.0085 -1.0000 +vn -0.0002 0.0001 -1.0000 +vn -0.0004 0.0042 -1.0000 +vn -0.0009 -0.0007 -1.0000 +vn -0.0010 -0.0006 -1.0000 +vn -0.0012 -0.0005 -1.0000 +vn -0.0033 0.0029 -1.0000 +vn -0.0022 0.0037 -1.0000 +vn -0.0006 -0.0001 -1.0000 +vn 0.0017 0.0001 -1.0000 +vn -0.0011 -0.0001 -1.0000 +vn -0.0010 0.0001 -1.0000 +vn 0.0001 -0.0003 -1.0000 +vn -0.0005 0.0004 -1.0000 +vn 0.0007 -0.0006 -1.0000 +vn 0.0018 0.0001 -1.0000 +vn 0.0012 -0.0001 -1.0000 +vn 0.0014 -0.0002 -1.0000 +vn 0.0010 -0.0000 -1.0000 +vn 0.0012 0.0007 -1.0000 +vn 0.0013 0.0008 -1.0000 +vn 0.0015 0.0007 -1.0000 +vn 0.0017 0.0004 -1.0000 +vn 0.0003 -0.0010 -1.0000 +vn 0.1907 -0.1933 0.9624 +vn 0.5892 -0.5959 0.5457 +vn 0.6440 -0.5372 0.5447 +vn 0.2099 -0.1756 0.9618 +vn 0.5891 -0.5958 0.5458 +vn 0.7023 -0.7103 0.0483 +vn 0.7670 -0.6398 0.0482 +vn 0.6439 -0.5372 0.5449 +vn 0.8325 -0.5519 0.0481 +vn 0.6997 -0.4638 0.5435 +vn 0.2304 -0.1534 0.9609 +vn -0.0282 -0.2645 0.9640 +vn -0.0889 -0.8320 0.5476 +vn -0.0409 -0.8353 0.5483 +vn -0.0130 -0.2650 0.9641 +vn -0.1061 -0.9932 0.0483 +vn -0.0489 -0.9976 0.0482 +vn -0.0409 -0.8353 0.5482 +vn 0.0057 -0.9988 0.0483 +vn 0.0047 -0.8364 0.5480 +vn 0.0047 -0.8366 0.5478 +vn 0.0015 -0.2657 0.9641 +vn 0.2268 0.1511 0.9621 +vn 0.6958 0.4633 0.5488 +vn 0.6916 0.4612 0.5558 +vn 0.2227 0.1482 0.9636 +vn 0.6959 0.4633 0.5488 +vn 0.8314 0.5536 0.0484 +vn 0.8311 0.5540 0.0486 +vn 0.8898 0.4538 0.0485 +vn 0.7348 0.3752 0.5650 +vn 0.7348 0.3751 0.5651 +vn 0.2326 0.1183 0.9653 +vn 0.0684 0.3321 0.9408 +vn 0.1242 0.8524 0.5080 +vn -0.0872 0.8401 0.5354 +vn -0.0266 0.2979 0.9542 +vn 0.1531 0.9873 0.0423 +vn -0.1010 0.9938 0.0469 +vn -0.0872 0.8400 0.5355 +vn -0.1817 0.9821 0.0491 +vn -0.1513 0.8177 0.5554 +vn -0.1513 0.8176 0.5556 +vn -0.0505 0.2723 0.9609 +vn -0.2322 0.1414 0.9623 +vn -0.7138 0.4345 0.5493 +vn -0.7343 0.3997 0.5487 +vn -0.2389 0.1300 0.9623 +vn -0.7138 0.4344 0.5494 +vn -0.8532 0.5194 0.0484 +vn -0.8773 0.4775 0.0484 +vn -0.9022 0.4285 0.0483 +vn -0.7556 0.3589 0.5480 +vn -0.7556 0.3589 0.5479 +vn -0.2459 0.1169 0.9622 +vn 0.2775 0.1142 0.9539 +vn 0.7957 0.3151 0.5173 +vn 0.7626 0.3847 0.5201 +vn 0.2715 0.1305 0.9536 +vn 0.9282 0.3699 0.0403 +vn 0.8928 0.4483 0.0445 +vn 0.6056 0.7948 0.0392 +vn 0.5384 0.6964 0.4745 +vn 0.5384 0.6963 0.4746 +vn 0.1927 0.3400 0.9205 +vn -0.1598 -0.2177 0.9629 +vn -0.4968 -0.6753 0.5451 +vn -0.4330 -0.7172 0.5460 +vn -0.1386 -0.2300 0.9633 +vn -0.4969 -0.6754 0.5449 +vn -0.5919 -0.8046 0.0481 +vn -0.5161 -0.8552 0.0481 +vn -0.4330 -0.7173 0.5460 +vn -0.4397 -0.8968 0.0482 +vn -0.3690 -0.7525 0.5456 +vn -0.3689 -0.7525 0.5456 +vn -0.1182 -0.2412 0.9632 +vn -0.0840 0.2624 0.9613 +vn -0.2495 0.7943 0.5539 +vn -0.4020 0.7103 0.5778 +vn -0.1226 0.2165 0.9686 +vn -0.2495 0.7943 0.5540 +vn -0.3004 0.9524 0.0517 +vn -0.4919 0.8686 0.0595 +vn -0.4020 0.7103 0.5779 +vn -0.7353 0.6740 0.0702 +vn -0.5909 0.5417 0.5978 +vn -0.5908 0.5417 0.5979 +vn -0.1630 0.1462 0.9757 +vn 0.1531 0.9873 -0.0424 +vn 0.1242 0.8523 -0.5081 +vn -0.0872 0.8401 -0.5354 +vn -0.1010 0.9938 -0.0469 +vn 0.1242 0.8523 -0.5080 +vn 0.0683 0.3319 -0.9408 +vn -0.0263 0.2977 -0.9543 +vn -0.0872 0.8400 -0.5355 +vn -0.0505 0.2723 -0.9609 +vn -0.1513 0.8176 -0.5556 +vn -0.1513 0.8177 -0.5554 +vn -0.1817 0.9821 -0.0491 +vn -0.2016 0.1939 0.9601 +vn -0.6427 0.5729 0.5087 +vn -0.5518 0.6240 0.5534 +vn -0.1748 0.1961 0.9649 +vn -0.7332 0.6788 0.0401 +vn -0.6619 0.7479 0.0501 +vn -0.5517 0.6239 0.5535 +vn -0.7793 0.6244 0.0537 +vn -0.6481 0.5202 0.5562 +vn -0.6482 0.5202 0.5561 +vn -0.2053 0.1638 0.9649 +vn -0.0716 -0.2583 0.9634 +vn -0.2243 -0.8075 0.5455 +vn -0.1509 -0.8241 0.5460 +vn -0.0480 -0.2632 0.9635 +vn -0.2243 -0.8074 0.5457 +vn -0.2673 -0.9624 0.0483 +vn -0.1798 -0.9825 0.0482 +vn -0.1509 -0.8241 0.5459 +vn 0.0016 0.2481 0.9687 +vn 0.0112 0.8084 0.5886 +vn 0.2499 0.8171 0.5196 +vn 0.0876 0.2930 0.9521 +vn 0.0112 0.8084 0.5885 +vn 0.0104 0.9986 0.0512 +vn 0.2888 0.9565 0.0421 +vn 0.2499 0.8171 0.5195 +vn 0.2707 0.2508 0.9294 +vn 0.5786 0.6541 0.4872 +vn 0.2534 0.8147 0.5216 +vn 0.0890 0.2771 0.9567 +vn 0.5786 0.6541 0.4871 +vn 0.6697 0.7416 0.0387 +vn 0.2973 0.9536 0.0477 +vn -0.0117 0.9989 0.0461 +vn -0.0074 0.8464 0.5325 +vn -0.0074 0.8464 0.5326 +vn -0.0084 0.2811 0.9597 +vn -0.2196 0.1153 0.9687 +vn -0.7226 0.3863 0.5732 +vn -0.4894 0.5204 0.6998 +vn -0.1302 0.1059 0.9858 +vn -0.7227 0.3863 0.5730 +vn -0.8808 0.4706 0.0518 +vn -0.6463 0.7581 0.0868 +vn 0.1785 0.9633 0.2005 +vn 0.0212 0.4897 0.8716 +vn 0.0212 0.4896 0.8717 +vn -0.0201 0.0612 0.9979 +vn -0.2639 -0.0521 0.9631 +vn -0.8148 -0.1632 0.5562 +vn -0.8218 -0.1148 0.5580 +vn -0.2647 -0.0363 0.9637 +vn -0.8149 -0.1633 0.5562 +vn -0.9794 -0.1958 0.0488 +vn -0.9893 -0.1379 0.0485 +vn -0.8219 -0.1149 0.5580 +vn -0.9988 -0.0016 0.0483 +vn -0.8246 -0.0018 0.5656 +vn -0.8245 -0.0018 0.5659 +vn -0.2600 0.0005 0.9656 +vn 0.1574 -0.2167 0.9635 +vn 0.4920 -0.6765 0.5480 +vn 0.5368 -0.6428 0.5465 +vn 0.1728 -0.2072 0.9629 +vn 0.4919 -0.6764 0.5481 +vn 0.5875 -0.8078 0.0483 +vn 0.6402 -0.7667 0.0482 +vn 0.5368 -0.6427 0.5466 +vn -0.1611 0.8171 0.5535 +vn -0.0541 0.2732 0.9604 +vn -0.1933 0.9799 0.0489 +vn -0.1611 0.8171 0.5536 +vn -0.7277 0.3924 0.5625 +vn -0.2272 0.1226 0.9661 +vn -0.8790 0.4740 0.0524 +vn -0.7277 0.3923 0.5626 +vn -0.7278 0.3924 0.5625 +vn -0.7227 0.3863 0.5731 +vn 0.2678 0.4672 0.8426 +vn 0.0104 0.0392 0.9992 +vn 0.1786 0.9633 0.2005 +vn 0.4182 0.8503 0.3195 +vn -0.1686 0.9141 0.3687 +vn -0.1113 0.4395 0.8913 +vn -0.0093 0.0286 0.9995 +vn 0.0765 -0.2569 0.9634 +vn 0.2395 -0.8028 0.5460 +vn 0.3065 -0.7797 0.5461 +vn 0.0980 -0.2497 0.9634 +vn 0.2395 -0.8027 0.5461 +vn 0.2856 -0.9571 0.0483 +vn 0.3654 -0.9296 0.0482 +vn 0.3065 -0.7797 0.5460 +vn 0.4486 -0.8924 0.0482 +vn 0.3765 -0.7489 0.5453 +vn 0.1208 -0.2408 0.9630 +vn -0.2704 -0.0645 0.9606 +vn -0.8137 -0.1800 0.5527 +vn -0.8101 -0.1942 0.5532 +vn -0.2641 -0.0615 0.9625 +vn -0.8138 -0.1800 0.5526 +vn -0.9748 -0.2177 0.0491 +vn -0.9716 -0.2317 0.0483 +vn -0.8101 -0.1942 0.5531 +vn 0.8314 0.5536 -0.0484 +vn 0.6959 0.4633 -0.5488 +vn 0.6916 0.4612 -0.5558 +vn 0.8311 0.5540 -0.0486 +vn 0.6958 0.4632 -0.5488 +vn 0.2271 0.1513 -0.9620 +vn 0.2225 0.1481 -0.9636 +vn 0.2324 0.1180 -0.9654 +vn 0.7348 0.3751 -0.5651 +vn 0.8898 0.4538 -0.0485 +vn -0.1061 -0.9932 -0.0483 +vn -0.0889 -0.8320 -0.5476 +vn -0.0409 -0.8353 -0.5483 +vn -0.0489 -0.9976 -0.0482 +vn -0.0282 -0.2645 -0.9640 +vn -0.0130 -0.2650 -0.9641 +vn -0.0409 -0.8354 -0.5482 +vn 0.0015 -0.2657 -0.9641 +vn 0.0047 -0.8365 -0.5480 +vn 0.0047 -0.8364 -0.5481 +vn 0.0057 -0.9988 -0.0483 +vn -0.2762 0.0216 0.9608 +vn -0.8367 0.0636 0.5439 +vn -0.8394 -0.0501 0.5411 +vn -0.2817 -0.0160 0.9594 +vn -0.8368 0.0636 0.5438 +vn -0.9960 0.0758 0.0480 +vn -0.9971 -0.0595 0.0481 +vn -0.8394 -0.0501 0.5412 +vn -0.9756 -0.2141 0.0481 +vn -0.8214 -0.1801 0.5412 +vn -0.8213 -0.1801 0.5414 +vn -0.2781 -0.0610 0.9586 +vn 0.0334 -0.2643 0.9639 +vn 0.1053 -0.8304 0.5472 +vn 0.1696 -0.8204 0.5460 +vn 0.0541 -0.2623 0.9635 +vn 0.1053 -0.8303 0.5472 +vn 0.1257 -0.9909 0.0483 +vn 0.2022 -0.9782 0.0482 +vn -0.2634 0.0777 0.9616 +vn -0.8043 0.2363 0.5452 +vn -0.8245 0.1538 0.5446 +vn -0.2707 0.0509 0.9613 +vn -0.8044 0.2364 0.5451 +vn -0.9583 0.2817 0.0482 +vn -0.9819 0.1833 0.0482 +vn -0.8244 0.1538 0.5447 +vn 0.0527 -0.8348 0.5480 +vn 0.0167 -0.2651 0.9641 +vn 0.0629 -0.9969 0.0483 +vn 0.0527 -0.8349 0.5479 +vn -0.3004 0.9524 -0.0517 +vn -0.2496 0.7943 -0.5539 +vn -0.4020 0.7103 -0.5779 +vn -0.4918 0.8686 -0.0597 +vn -0.0840 0.2625 -0.9613 +vn -0.1225 0.2164 -0.9686 +vn -0.4019 0.7103 -0.5779 +vn -0.1630 0.1462 -0.9757 +vn -0.5908 0.5417 -0.5979 +vn -0.5909 0.5417 -0.5978 +vn -0.7353 0.6740 -0.0702 +vn 0.2565 0.0083 0.9665 +vn 0.8218 0.0246 0.5692 +vn 0.8190 -0.1182 0.5615 +vn 0.2601 -0.0368 0.9649 +vn 0.9984 0.0301 0.0486 +vn 0.9886 -0.1423 0.0487 +vn 0.8191 -0.1183 0.5614 +vn 0.9805 -0.1904 0.0490 +vn 0.8180 -0.1586 0.5529 +vn 0.2640 -0.0516 0.9631 +vn 0.0527 -0.8350 -0.5478 +vn 0.0629 -0.9969 -0.0483 +vn 0.0167 -0.2651 -0.9641 +vn 0.0527 -0.8348 -0.5480 +vn 0.0334 -0.2643 -0.9639 +vn 0.1053 -0.8303 -0.5473 +vn 0.1053 -0.8302 -0.5475 +vn 0.1257 -0.9909 -0.0483 +vn -0.5919 -0.8046 -0.0481 +vn -0.4969 -0.6754 -0.5449 +vn -0.4329 -0.7173 -0.5460 +vn -0.5161 -0.8552 -0.0481 +vn -0.4969 -0.6753 -0.5450 +vn -0.1598 -0.2177 -0.9629 +vn -0.1386 -0.2300 -0.9633 +vn -0.4330 -0.7173 -0.5460 +vn -0.1182 -0.2413 -0.9632 +vn -0.3690 -0.7526 -0.5454 +vn -0.3690 -0.7525 -0.5456 +vn -0.4397 -0.8968 -0.0482 +vn -0.8532 0.5194 -0.0484 +vn -0.7137 0.4345 -0.5494 +vn -0.7343 0.3996 -0.5487 +vn -0.8773 0.4775 -0.0483 +vn -0.2322 0.1414 -0.9623 +vn -0.2388 0.1300 -0.9623 +vn -0.7343 0.3997 -0.5487 +vn -0.2459 0.1169 -0.9622 +vn -0.7557 0.3589 -0.5478 +vn -0.9022 0.4286 -0.0482 +vn 0.2524 0.1102 0.9613 +vn 0.7687 0.3355 0.5446 +vn 0.7300 0.4115 0.5457 +vn 0.2393 0.1350 0.9615 +vn 0.7687 0.3355 0.5445 +vn 0.9155 0.3995 0.0482 +vn 0.8701 0.4905 0.0483 +vn 0.7300 0.4114 0.5458 +vn -0.7878 -0.2900 0.5433 +vn -0.2636 -0.0978 0.9597 +vn -0.9373 -0.3451 0.0481 +vn -0.7878 -0.2900 0.5434 +vn -0.8890 -0.4554 0.0481 +vn -0.7473 -0.3828 0.5431 +vn -0.7473 -0.3828 0.5432 +vn -0.2473 -0.1272 0.9606 +vn -0.2350 0.1133 0.9654 +vn -0.7430 0.3602 0.5642 +vn -0.7083 0.4370 0.5544 +vn -0.2284 0.1407 0.9634 +vn -0.7430 0.3602 0.5641 +vn -0.8990 0.4354 0.0485 +vn -0.8501 0.5244 0.0486 +vn -0.7082 0.4370 0.5545 +vn 0.7561 -0.3672 0.5417 +vn 0.2529 -0.1237 0.9595 +vn 0.8985 -0.4364 0.0481 +vn 0.9557 -0.2905 0.0482 +vn 0.8048 -0.2447 0.5408 +vn 0.8048 -0.2447 0.5407 +vn 0.2734 -0.0832 0.9583 +vn 0.1752 0.1999 0.9640 +vn 0.5867 0.6247 0.5153 +vn 0.7008 0.5544 0.4489 +vn 0.2651 0.2239 0.9379 +vn 0.5868 0.6248 0.5150 +vn 0.6727 0.7387 0.0425 +vn 0.7791 0.6261 0.0312 +vn 0.7009 0.5544 0.4489 +vn 0.0942 0.3333 0.9381 +vn 0.2091 0.8852 0.4156 +vn 0.2721 0.8195 0.5043 +vn 0.0979 0.3081 0.9463 +vn 0.2091 0.8851 0.4157 +vn 0.2498 0.9678 0.0322 +vn 0.3155 0.9478 0.0458 +vn 0.2721 0.8195 0.5044 +vn 0.2134 0.9758 0.0484 +vn 0.1933 0.8453 0.4982 +vn 0.1934 0.8452 0.4982 +vn 0.0629 0.3437 0.9370 +vn 0.8307 -0.1234 0.5428 +vn 0.2791 -0.0407 0.9594 +vn 0.8047 -0.2447 0.5408 +vn 0.9880 -0.1466 0.0482 +vn 0.8308 -0.1234 0.5428 +vn 0.9985 -0.0259 0.0481 +vn 0.8390 -0.0218 0.5438 +vn 0.8390 -0.0218 0.5437 +vn 0.2790 -0.0067 0.9603 +vn -0.9501 -0.2022 -0.2375 +vn -0.5640 -0.1299 -0.8155 +vn -0.5428 -0.1842 -0.8194 +vn -0.9062 -0.3476 -0.2407 +vn -0.5641 -0.1299 -0.8154 +vn -0.5427 -0.1842 -0.8195 +vn -0.5364 -0.2597 -0.8030 +vn -0.8685 -0.4575 -0.1907 +vn 0.8301 0.0076 0.5575 +vn 0.2688 -0.0145 0.9631 +vn 0.9985 0.0049 0.0551 +vn 0.8302 0.0076 0.5575 +vn 0.8809 0.4688 0.0647 +vn 0.7234 0.3875 0.5715 +vn 0.7233 0.3875 0.5716 +vn 0.2191 0.0988 0.9707 +vn -0.7332 0.6788 -0.0404 +vn -0.6427 0.5729 -0.5086 +vn -0.5517 0.6239 -0.5535 +vn -0.6619 0.7479 -0.0502 +vn -0.6427 0.5728 -0.5088 +vn -0.2016 0.1939 -0.9601 +vn -0.1748 0.1961 -0.9649 +vn -0.5518 0.6239 -0.5534 +vn -0.2053 0.1638 -0.9649 +vn -0.6481 0.5202 -0.5562 +vn -0.7793 0.6244 -0.0535 +vn 0.9805 -0.1904 -0.0486 +vn 0.8181 -0.1586 -0.5528 +vn 0.8302 0.0076 -0.5575 +vn 0.9985 0.0049 -0.0551 +vn 0.8180 -0.1586 -0.5529 +vn 0.2639 -0.0516 -0.9632 +vn 0.2688 -0.0145 -0.9631 +vn 0.8301 0.0076 -0.5576 +vn 0.2191 0.0988 -0.9707 +vn 0.7233 0.3874 -0.5715 +vn 0.7234 0.3875 -0.5715 +vn 0.8809 0.4688 -0.0647 +vn -0.8808 0.4706 -0.0518 +vn -0.7227 0.3863 -0.5731 +vn -0.4894 0.5204 -0.6997 +vn -0.6463 0.7581 -0.0868 +vn -0.7226 0.3863 -0.5732 +vn -0.2197 0.1153 -0.9687 +vn -0.1302 0.1059 -0.9858 +vn -0.4893 0.5203 -0.6999 +vn -0.0201 0.0612 -0.9979 +vn 0.0212 0.4896 -0.8717 +vn 0.1786 0.9633 -0.2005 +vn 0.0252 0.0463 0.9986 +vn 0.1566 0.4487 0.8798 +vn 0.6739 0.4274 0.6027 +vn 0.1373 0.0940 0.9861 +vn 0.1565 0.4487 0.8799 +vn 0.2468 0.9413 0.2302 +vn 0.8233 0.5633 0.0699 +vn 0.9557 -0.2905 -0.0482 +vn 0.8047 -0.2447 -0.5408 +vn 0.8308 -0.1234 -0.5428 +vn 0.9880 -0.1466 -0.0482 +vn 0.8048 -0.2447 -0.5407 +vn 0.2734 -0.0831 -0.9583 +vn 0.2791 -0.0407 -0.9594 +vn 0.2790 -0.0067 -0.9603 +vn 0.8390 -0.0218 -0.5437 +vn 0.9985 -0.0259 -0.0481 +vn 0.7939 0.2133 0.5694 +vn 0.2481 0.0666 0.9664 +vn 0.9647 0.2590 0.0484 +vn -0.2761 0.2918 0.9158 +vn -0.5081 0.7253 0.4645 +vn -0.7216 0.5475 0.4237 +vn -0.3035 0.2206 0.9270 +vn -0.5081 0.7253 0.4646 +vn -0.5903 0.8064 0.0350 +vn -0.7984 0.6014 0.0291 +vn 0.9984 0.0301 -0.0487 +vn 0.8218 0.0246 -0.5692 +vn 0.8190 -0.1183 -0.5614 +vn 0.9886 -0.1423 -0.0487 +vn 0.2567 0.0083 -0.9665 +vn 0.2601 -0.0367 -0.9649 +vn 0.8190 -0.1182 -0.5615 +vn 0.9282 0.3699 -0.0403 +vn 0.7957 0.3151 -0.5173 +vn 0.7626 0.3847 -0.5201 +vn 0.8928 0.4483 -0.0444 +vn 0.7956 0.3151 -0.5174 +vn 0.2774 0.1141 -0.9539 +vn 0.2715 0.1305 -0.9535 +vn 0.1938 0.3425 -0.9193 +vn 0.5386 0.6971 -0.4732 +vn 0.5386 0.6971 -0.4731 +vn 0.6056 0.7948 -0.0390 +vn -0.9988 -0.0016 -0.0483 +vn -0.8247 -0.0018 -0.5656 +vn -0.7984 0.1873 -0.5722 +vn -0.9724 0.2284 -0.0484 +vn -0.8245 -0.0018 -0.5659 +vn -0.2600 0.0005 -0.9656 +vn -0.2472 0.0583 -0.9672 +vn -0.7984 0.1874 -0.5722 +vn -0.2350 0.1133 -0.9654 +vn -0.7430 0.3602 -0.5642 +vn -0.8990 0.4354 -0.0485 +vn -0.6053 -0.4102 -0.6822 +vn -0.8210 -0.5590 -0.1159 +vn -0.1230 -0.0833 -0.9889 +vn -0.6052 -0.4102 -0.6822 +vn -0.1892 -0.1646 -0.9680 +vn -0.6205 -0.5360 -0.5724 +vn -0.6206 -0.5361 -0.5723 +vn -0.7557 -0.6523 -0.0593 +vn -0.1964 0.8370 0.5107 +vn -0.0861 0.2973 0.9509 +vn -0.2354 0.9710 0.0426 +vn 0.0350 0.8781 0.4771 +vn -0.0045 0.3698 0.9291 +vn 0.0290 0.9981 0.0538 +vn 0.0350 0.8782 0.4771 +vn -0.2182 0.9739 0.0621 +vn -0.1808 0.8636 0.4706 +vn -0.0981 0.3592 0.9281 +vn 0.1157 0.9053 -0.4088 +vn 0.0501 0.5295 -0.8468 +vn 0.0111 0.2911 -0.9566 +vn 0.0487 0.6683 -0.7423 +vn 0.0068 0.2252 -0.9743 +vn 0.0338 0.6570 -0.7531 +vn -0.1775 0.4063 0.8963 +vn -0.0089 0.0321 0.9994 +vn -0.1112 0.4394 0.8914 +vn -0.1685 0.9141 0.3687 +vn -0.4231 0.8387 0.3429 +vn -0.1775 0.4062 0.8964 +vn 0.1566 0.4487 0.8799 +vn 0.5299 0.6210 -0.5776 +vn 0.6498 0.7578 -0.0588 +vn 0.1527 0.1751 -0.9726 +vn 0.5298 0.6209 -0.5777 +vn 0.1752 0.1999 -0.9640 +vn 0.5867 0.6247 -0.5154 +vn 0.5867 0.6248 -0.5152 +vn 0.6727 0.7387 -0.0426 +vn 0.1608 0.9308 -0.3282 +vn 0.1410 0.9899 -0.0145 +vn 0.0209 0.6936 -0.7201 +vn 0.0209 0.6937 -0.7199 +vn 0.0170 0.7865 -0.6174 +vn -0.0088 0.9999 0.0095 +vn -0.0017 1.0000 0.0025 +vn 0.8360 0.0795 -0.5429 +vn 0.9943 0.0947 -0.0481 +vn 0.2771 0.0268 -0.9605 +vn 0.2697 0.0584 -0.9612 +vn 0.8200 0.1764 -0.5445 +vn 0.8200 0.1764 -0.5444 +vn 0.9765 0.2102 -0.0482 +vn -0.7797 0.3066 -0.5459 +vn -0.9295 0.3656 -0.0481 +vn -0.2549 0.1004 -0.9617 +vn -0.7797 0.3066 -0.5460 +vn -0.2385 0.0711 -0.9685 +vn -0.7824 0.2300 -0.5788 +vn -0.7825 0.2300 -0.5787 +vn -0.9577 0.2812 -0.0616 +vn 0.2671 0.9637 0.0022 +vn 0.2402 0.9677 0.0764 +vn 0.5428 0.8242 -0.1612 +vn 0.6020 0.7984 0.0111 +vn 0.2402 0.9677 0.0765 +vn 0.2367 0.7196 -0.6528 +vn 0.2822 0.3308 -0.9005 +vn 0.5428 0.8243 -0.1611 +vn 0.5428 0.8243 -0.1612 +vn 0.2820 0.3306 -0.9007 +vn 0.2493 0.3248 -0.9123 +vn 0.6114 0.6359 -0.4710 +vn 0.6114 0.6359 -0.4711 +vn 0.6755 0.7373 0.0128 +vn 0.1592 0.9253 0.3442 +vn 0.0190 0.6510 0.7588 +vn 0.1409 0.9899 0.0164 +vn 0.1592 0.9253 0.3443 +vn -0.0020 1.0000 0.0060 +vn -0.0103 0.9952 0.0978 +vn 0.0189 0.6510 0.7588 +vn 0.0104 0.6313 0.7755 +vn 0.5299 0.6209 0.5776 +vn 0.1527 0.1752 0.9726 +vn 0.6498 0.7578 0.0587 +vn 0.5299 0.6210 0.5776 +vn 0.1785 0.9633 -0.2005 +vn 0.0212 0.4897 -0.8717 +vn 0.2678 0.4672 -0.8426 +vn 0.4183 0.8503 -0.3194 +vn 0.0105 0.0393 -0.9992 +vn -0.0092 0.0286 -0.9995 +vn -0.1113 0.4395 -0.8913 +vn 0.4182 0.8503 -0.3194 +vn -0.1686 0.9141 -0.3687 +vn -0.7985 0.1874 0.5721 +vn -0.2472 0.0583 0.9672 +vn -0.9724 0.2284 0.0488 +vn -0.7984 0.1873 0.5723 +vn -0.8989 0.4354 0.0485 +vn -0.6948 -0.4712 0.5433 +vn -0.2279 -0.1550 0.9613 +vn -0.8267 -0.5606 0.0480 +vn -0.6948 -0.4713 0.5432 +vn -0.7559 -0.6529 0.0481 +vn -0.6350 -0.5484 0.5441 +vn -0.6349 -0.5484 0.5442 +vn -0.2064 -0.1786 0.9620 +vn 0.2697 0.0584 0.9612 +vn 0.8201 0.1764 0.5444 +vn 0.7981 0.2565 0.5453 +vn 0.2615 0.0842 0.9615 +vn 0.9765 0.2102 0.0482 +vn 0.9509 0.3057 0.0482 +vn 0.7980 0.2565 0.5453 +vn -0.4377 0.8738 -0.2118 +vn -0.3102 0.5824 -0.7513 +vn -0.2904 0.6920 -0.6609 +vn -0.3917 0.9169 -0.0773 +vn -0.1005 0.1802 -0.9785 +vn -0.0673 0.1919 -0.9791 +vn -0.2905 0.6920 -0.6608 +vn 0.0039 0.2183 -0.9759 +vn 0.0178 0.7809 -0.6245 +vn 0.0178 0.7810 -0.6243 +vn 0.0047 0.9980 -0.0627 +vn -0.1775 0.4062 -0.8964 +vn -0.4231 0.8387 -0.3429 +vn -0.0089 0.0320 -0.9994 +vn -0.1775 0.4062 -0.8963 +vn 0.0252 0.0463 -0.9986 +vn 0.1566 0.4487 -0.8798 +vn 0.1567 0.4486 -0.8799 +vn 0.2468 0.9413 -0.2302 +vn -0.0117 0.9989 -0.0461 +vn -0.0074 0.8464 -0.5324 +vn -0.1963 0.8370 -0.5108 +vn -0.2354 0.9710 -0.0428 +vn -0.0074 0.8463 -0.5327 +vn -0.0084 0.2810 -0.9597 +vn -0.0861 0.2973 -0.9509 +vn -0.1964 0.8370 -0.5107 +vn -0.2760 0.2918 -0.9158 +vn -0.5081 0.7253 -0.4646 +vn -0.5903 0.8064 -0.0347 +vn 0.7939 0.2133 -0.5694 +vn 0.9647 0.2590 -0.0484 +vn 0.2481 0.0666 -0.9664 +vn 0.7939 0.2133 -0.5695 +vn -0.5681 -0.6180 -0.5435 +vn -0.6759 -0.7354 -0.0482 +vn -0.1841 -0.2009 -0.9621 +vn -0.5682 -0.6181 -0.5432 +vn 0.6697 0.7416 -0.0386 +vn 0.5786 0.6542 -0.4871 +vn 0.2534 0.8146 -0.5217 +vn 0.2973 0.9536 -0.0477 +vn 0.5786 0.6541 -0.4872 +vn 0.2707 0.2507 -0.9294 +vn 0.0890 0.2771 -0.9567 +vn 0.2534 0.8147 -0.5216 +vn -0.7794 0.3065 0.5464 +vn -0.2544 0.1003 0.9619 +vn -0.9295 0.3656 0.0482 +vn -0.7794 0.3065 0.5465 +vn -0.9727 0.0851 -0.2158 +vn -0.5574 0.0283 -0.8297 +vn -0.5507 -0.0551 -0.8329 +vn -0.9608 -0.0386 -0.2744 +vn -0.7043 0.1305 -0.6978 +vn -0.9746 0.1839 -0.1278 +vn -0.1339 0.0235 -0.9907 +vn 0.1900 -0.2867 -0.9390 +vn 0.0311 -0.0554 -0.9980 +vn 0.0114 -0.0177 -0.9998 +vn 0.1762 -0.2515 -0.9517 +vn 0.0115 -0.0157 -0.9998 +vn 0.1727 -0.2339 -0.9568 +vn -0.2984 -0.7830 -0.5457 +vn -0.3558 -0.9333 -0.0483 +vn -0.0955 -0.2508 -0.9633 +vn -0.2985 -0.7831 -0.5455 +vn -0.0716 -0.2582 -0.9634 +vn -0.2243 -0.8075 -0.5455 +vn -0.3557 -0.9333 -0.0482 +vn -0.2984 -0.7832 -0.5455 +vn -0.2243 -0.8074 -0.5456 +vn -0.2673 -0.9624 -0.0483 +vn 0.8325 -0.5519 -0.0481 +vn 0.6995 -0.4637 -0.5438 +vn 0.7561 -0.3672 -0.5417 +vn 0.8985 -0.4364 -0.0481 +vn 0.2300 -0.1531 -0.9611 +vn 0.2530 -0.1237 -0.9595 +vn 0.7562 -0.3672 -0.5416 +vn 0.8047 -0.2448 -0.5408 +vn 0.1693 -0.8195 -0.5475 +vn 0.2022 -0.9782 -0.0484 +vn 0.0539 -0.2608 -0.9639 +vn 0.1693 -0.8196 -0.5473 +vn 0.0774 -0.2594 -0.9627 +vn 0.2409 -0.8160 -0.5255 +vn 0.2409 -0.8158 -0.5257 +vn 0.2845 -0.9584 -0.0210 +vn 0.3082 -0.8433 -0.4403 +vn 0.3575 -0.9051 0.2303 +vn 0.0930 -0.2652 -0.9597 +vn 0.1122 -0.2824 -0.9527 +vn 0.3525 -0.8212 -0.4488 +vn 0.3526 -0.8211 -0.4488 +vn 0.4598 -0.8746 0.1538 +vn -0.9794 -0.1958 -0.0488 +vn -0.8149 -0.1633 -0.5562 +vn -0.8219 -0.1149 -0.5579 +vn -0.9893 -0.1379 -0.0484 +vn -0.8148 -0.1632 -0.5562 +vn -0.2638 -0.0521 -0.9632 +vn -0.2642 -0.0363 -0.9638 +vn -0.8217 -0.1148 -0.5582 +vn 0.8360 0.0795 0.5429 +vn 0.2771 0.0268 0.9605 +vn 0.9943 0.0947 0.0481 +vn 0.4434 -0.7107 0.5462 +vn 0.1423 -0.2284 0.9631 +vn 0.5288 -0.8474 0.0483 +vn 0.4434 -0.7106 0.5463 +vn -0.9748 -0.2176 -0.0492 +vn -0.8137 -0.1800 -0.5527 +vn -0.8102 -0.1942 -0.5531 +vn -0.9716 -0.2317 -0.0483 +vn -0.8138 -0.1800 -0.5526 +vn -0.2703 -0.0643 -0.9606 +vn -0.2641 -0.0616 -0.9625 +vn -0.8101 -0.1942 -0.5532 +vn -0.7277 0.3924 -0.5626 +vn -0.8790 0.4740 -0.0524 +vn -0.2271 0.1226 -0.9661 +vn -0.7227 0.3864 -0.5731 +vn 0.7009 0.5544 -0.4488 +vn 0.7791 0.6261 -0.0312 +vn 0.2651 0.2239 -0.9379 +vn 0.7008 0.5543 -0.4490 +vn -0.2631 0.8129 0.5196 +vn -0.0900 0.2883 0.9533 +vn -0.3012 0.9518 0.0575 +vn -0.2631 0.8129 0.5197 +vn -0.2985 -0.7832 0.5454 +vn -0.0955 -0.2507 0.9633 +vn -0.3557 -0.9333 0.0482 +vn -0.2984 -0.7832 0.5455 +vn -0.2985 -0.7831 0.5456 +vn -0.7216 0.5475 -0.4237 +vn -0.7984 0.6014 -0.0294 +vn -0.3035 0.2206 -0.9270 +vn 0.7981 0.2565 -0.5453 +vn 0.9509 0.3057 -0.0482 +vn 0.2615 0.0842 -0.9615 +vn 0.7980 0.2565 -0.5453 +vn 0.2524 0.1102 -0.9613 +vn 0.7687 0.3355 -0.5446 +vn 0.7687 0.3355 -0.5445 +vn 0.9155 0.3995 -0.0482 +vn -0.1611 0.8171 -0.5535 +vn -0.1934 0.9799 -0.0489 +vn -0.0541 0.2731 -0.9605 +vn -0.1611 0.8170 -0.5537 +vn -0.5680 -0.6179 0.5437 +vn -0.1840 -0.2007 0.9622 +vn -0.6759 -0.7354 0.0482 +vn -0.5679 -0.6178 0.5439 +vn 0.1566 0.4487 -0.8799 +vn 0.6739 0.4274 -0.6027 +vn 0.8233 0.5634 -0.0699 +vn 0.1373 0.0940 -0.9860 +vn 0.6738 0.4274 -0.6027 +vn -0.7429 0.3602 -0.5642 +vn -0.7082 0.4370 -0.5545 +vn -0.8501 0.5244 -0.0486 +vn -0.2285 0.1407 -0.9633 +vn 0.2497 0.8161 -0.5211 +vn 0.2888 0.9565 -0.0422 +vn 0.0868 0.2902 -0.9530 +vn 0.2497 0.8161 -0.5212 +vn 0.7300 0.4114 -0.5458 +vn 0.8701 0.4905 -0.0483 +vn 0.2392 0.1349 -0.9615 +vn 0.7299 0.4115 -0.5458 +vn -0.1509 -0.8241 -0.5460 +vn -0.1798 -0.9825 -0.0482 +vn -0.0480 -0.2632 -0.9635 +vn 0.5892 -0.8080 0.0075 +vn 0.5155 -0.6933 -0.5036 +vn 0.5419 -0.6443 -0.5397 +vn 0.6407 -0.7667 -0.0412 +vn 0.5155 -0.6933 -0.5035 +vn 0.1748 -0.2123 -0.9614 +vn 0.1881 -0.1919 -0.9632 +vn 0.5889 -0.5944 -0.5476 +vn 0.5890 -0.5944 -0.5475 +vn 0.7025 -0.7101 -0.0477 +vn -0.9001 0.4358 -0.0000 +vn -0.9735 0.2287 -0.0000 +vn -0.9001 0.4357 -0.0000 +vn -1.0000 -0.0014 0.0000 +vn -0.7568 -0.6536 0.0000 +vn -0.8277 -0.5612 -0.0000 +vn -0.8900 -0.4559 -0.0000 +vn -0.8276 -0.5613 0.0000 +vn -0.7805 0.6251 0.0000 +vn -0.6628 0.7488 -0.0000 +vn -0.7320 0.6813 0.0000 +vn 0.9816 -0.1907 0.0000 +vn 0.9898 -0.1423 0.0000 +vn 0.9995 0.0302 0.0000 +vn 0.0617 0.9479 -0.3125 +vn 0.0832 0.9520 -0.2944 +vn 0.0487 0.6684 -0.7422 +vn 0.0891 0.9958 -0.0186 +vn 0.0950 0.9953 0.0191 +vn 0.1010 0.9928 0.0646 +vn 0.1177 0.9886 -0.0934 +vn 0.1157 0.9052 -0.4089 +vn -0.1974 0.8838 0.4241 +vn -0.2196 0.9618 0.1636 +vn 0.0334 0.9932 0.1119 +vn 0.0559 0.9581 0.2809 +vn 0.2098 0.9758 0.0613 +vn 0.2515 0.9438 0.2144 +vn 0.6023 0.7983 0.0000 +vn 0.8941 0.4479 0.0000 +vn 0.6022 0.7983 -0.0000 +vn 0.9287 0.3707 0.0000 +vn 0.9288 0.3707 0.0000 +vn 0.6716 0.7409 0.0000 +vn 0.6515 0.7587 -0.0000 +vn 0.8848 0.4660 -0.0000 +vn -0.0009 1.0000 0.0000 +vn 0.1360 0.9907 0.0000 +vn 0.9776 0.2104 0.0000 +vn 0.9955 0.0948 -0.0000 +vn 0.9997 -0.0259 0.0000 +vn 1.0000 0.0016 0.0000 +vn -0.9594 0.2820 -0.0000 +vn -0.9306 0.3660 -0.0000 +vn -0.9033 0.4291 0.0000 +vn 0.9892 -0.1468 -0.0000 +vn 0.9568 -0.2908 0.0000 +vn 0.2672 0.9636 0.0064 +vn 0.0995 0.9950 0.0000 +vn 0.0976 0.9952 0.0057 +vn 0.2610 0.9653 0.0097 +vn 0.2553 0.9668 0.0057 +vn 0.0970 0.9952 0.0149 +vn -0.0126 0.9999 0.0000 +vn 0.2980 0.9546 -0.0000 +vn 0.6732 0.7395 -0.0000 +vn 0.8995 -0.4369 -0.0001 +vn 0.8995 -0.4369 -0.0000 +vn 0.8335 -0.5525 0.0000 +vn 0.8995 -0.4369 0.0001 +vn -0.8783 0.4781 0.0000 +vn -0.8542 0.5200 0.0000 +vn -0.9384 -0.3455 -0.0000 +vn -0.9767 -0.2144 0.0000 +vn 0.8909 0.4542 0.0000 +vn 0.8321 0.5546 0.0000 +vn 0.8323 0.5543 -0.0000 +vn 0.0028 1.0000 0.0052 +vn -0.3611 0.9233 0.1311 +vn 0.0052 0.9999 0.0141 +vn -0.3275 0.9208 0.2119 +vn -0.4016 0.8670 0.2951 +vn 0.0082 0.9999 0.0118 +vn -0.3080 0.9469 0.0920 +vn 0.2165 0.9763 0.0000 +vn -0.4480 0.8940 0.0000 +vn -0.1913 0.9815 0.0000 +vn -0.5950 0.8037 0.0000 +vn -0.2376 0.9714 0.0000 +vn 0.9658 0.2592 0.0000 +vn -0.5926 -0.8055 -0.0000 +vn -0.6767 -0.7362 0.0000 +vn 0.1258 -0.9921 -0.0000 +vn 0.0629 -0.9980 -0.0000 +vn 0.0057 -1.0000 0.0000 +vn -0.9982 -0.0596 -0.0000 +vn -0.9971 0.0759 -0.0000 +vn 0.4382 -0.8950 0.0836 +vn 0.3644 -0.9302 0.0441 +vn 0.4478 -0.8941 0.0092 +vn 0.3654 -0.9308 0.0046 +vn 0.2858 -0.9583 0.0007 +vn 0.2856 -0.9583 0.0061 +vn 0.4491 -0.8935 0.0000 +vn 0.3658 -0.9307 0.0000 +vn 0.2859 -0.9583 -0.0000 +vn -0.9830 0.1835 0.0000 +vn 0.5881 -0.8086 0.0135 +vn 0.5261 -0.8471 0.0749 +vn 0.5111 -0.8021 0.3088 +vn 0.5881 -0.8088 0.0015 +vn 0.5291 -0.8485 0.0067 +vn 0.5881 -0.8088 -0.0000 +vn 0.5294 -0.8484 -0.0000 +vn -0.2676 -0.9635 0.0000 +vn -0.3561 -0.9344 0.0000 +vn -0.3561 -0.9344 -0.0001 +vn -0.3561 -0.9344 0.0001 +vn -0.4402 -0.8979 0.0000 +vn -0.9904 -0.1380 -0.0000 +vn -0.9806 -0.1959 0.0000 +vn 0.2024 -0.9793 0.0000 +vn 0.4584 0.8888 -0.0000 +vn 0.1852 0.9827 0.0000 +vn 0.4183 0.8503 0.3194 +vn -0.6459 0.7635 0.0000 +vn -0.8821 0.4711 0.0000 +vn -0.7371 0.6758 0.0000 +vn -0.4924 0.8704 0.0000 +vn -0.3010 0.9536 -0.0000 +vn 0.7679 -0.6406 0.0000 +vn 0.7670 -0.6398 -0.0483 +vn 0.7031 -0.7111 0.0000 +vn -0.9758 -0.2189 0.0000 +vn -0.9842 0.1773 -0.0000 +vn -0.9806 0.1847 -0.0659 +vn -0.9806 0.1847 0.0659 +vn -0.9806 0.1847 0.0660 +vn -0.8802 0.4746 -0.0000 +vn 0.7787 0.6274 0.0000 +vn -0.1820 0.9833 -0.0000 +vn -0.1003 0.9950 0.0000 +vn 0.1559 0.9878 -0.0000 +vn -0.0489 -0.9988 -0.0000 +vn -0.1062 -0.9943 0.0000 +vn -0.7991 0.6012 0.0000 +vn 0.9165 0.4000 0.0000 +vn 0.9520 0.3060 0.0000 +vn -0.1936 0.9811 -0.0000 +vn -0.5167 -0.8562 0.0000 +vn 0.8211 0.5707 0.0000 +vn -0.8511 0.5250 0.0000 +vn 0.2884 0.9575 0.0000 +vn 0.8711 0.4911 0.0000 +vn -0.1800 -0.9837 0.0000 +vn 0.6409 -0.7676 0.0013 +vn 0.6410 -0.7676 0.0001 +vn 0.6410 -0.7676 0.0000 +vn 0.6432 -0.5364 -0.5465 +vn 0.2086 -0.1746 -0.9623 +vn 0.6431 -0.5364 -0.5465 +vn -0.0241 0.0115 0.9996 +vn -0.0224 0.0137 0.9997 +vn -0.0215 0.0131 0.9997 +vn -0.0122 0.0372 0.9992 +vn -0.0184 0.0307 0.9994 +vn -0.0238 0.0199 0.9995 +vn -0.0280 -0.0056 0.9996 +vn -0.0277 -0.0038 0.9996 +vn -0.0270 0.0000 0.9996 +vn -0.0158 0.0529 0.9985 +vn -0.0127 0.0398 0.9991 +vn 0.0001 0.0331 0.9995 +vn -0.0257 0.0060 0.9997 +vn 0.0105 0.0478 0.9988 +vn -0.0037 0.0420 0.9991 +vn -0.0071 0.0381 0.9992 +vn -0.0302 -0.0073 0.9995 +vn -0.0286 -0.0067 0.9996 +vn -0.0018 -0.0005 1.0000 +vn 0.0166 0.0067 0.9998 +vn 0.0202 0.0091 0.9998 +vn 0.0138 0.0193 0.9997 +vn 0.0023 0.0037 1.0000 +vn 0.0085 0.0055 0.9999 +vn 0.0115 0.0371 0.9992 +vn 0.0125 0.0398 0.9991 +vn 0.0082 0.0508 0.9987 +vn 0.0018 0.0382 0.9993 +vn 0.0104 0.6311 0.7756 +vn 0.0014 0.0499 0.9988 +vn -0.0214 0.0116 0.9997 +vn -0.0217 0.0103 0.9997 +vn -0.0223 0.0087 0.9997 +vn -0.0231 0.0066 0.9997 +vn -0.0246 -0.0118 0.9996 +vn -0.0199 -0.0129 0.9997 +vn -0.0163 -0.0136 0.9998 +vn -0.0045 -0.0159 0.9999 +vn -0.0030 -0.0162 0.9999 +vn -0.0018 -0.0164 0.9999 +vn -0.0112 -0.0149 0.9998 +vn -0.0093 -0.0152 0.9998 +vn -0.0077 -0.0155 0.9998 +vn -0.0008 -0.0166 0.9999 +vn 0.0001 -0.0166 0.9999 +vn -0.0260 0.0015 0.9997 +vn -0.0303 -0.0027 0.9995 +vn -0.0319 -0.0072 0.9995 +vn 0.0213 0.0142 0.9997 +vn 0.0225 0.0148 0.9996 +vn 0.0247 0.0122 0.9996 +vn 0.0133 0.0146 0.9998 +vn 0.0123 0.0146 0.9998 +vn 0.0014 0.0000 1.0000 +vn 0.0268 0.0008 0.9996 +vn 0.0264 -0.0037 0.9996 +vn 0.0014 -0.0002 1.0000 +vn 0.0248 -0.0048 0.9997 +vn -0.0223 0.0161 0.9996 +vn -0.0137 0.0143 0.9998 +vn 0.0263 0.0069 0.9996 +vn 0.0013 0.0003 1.0000 +vn 0.0164 0.0149 0.9998 +vn 0.0048 0.0140 0.9999 +vn 0.0243 -0.0008 0.9997 +vn -0.0046 0.0053 1.0000 +vn -0.0018 0.0031 1.0000 +vn -0.0011 0.0022 1.0000 +vn -0.0001 0.0001 1.0000 +vn 0.0001 0.0029 1.0000 +vn -0.0206 0.0156 0.9997 +vn -0.0218 0.0117 0.9997 +vn -0.0192 0.0099 0.9998 +vn -0.0124 0.0088 0.9999 +vn 0.0221 0.0096 0.9997 +vn 0.0213 0.0120 0.9997 +vn 0.0242 0.0051 0.9997 +vn 0.0230 0.0073 0.9997 +vn 0.0151 -0.0149 0.9998 +vn 0.0178 -0.0143 0.9997 +vn 0.0217 -0.0136 0.9997 +vn 0.0021 -0.0164 0.9999 +vn 0.0049 -0.0163 0.9999 +vn 0.0003 -0.0006 1.0000 +vn 0.0113 -0.0154 0.9998 +vn 0.0011 -0.0165 0.9999 +vn 0.0315 -0.0094 0.9995 +vn 0.0306 -0.0051 0.9995 +vn 0.0282 -0.0012 0.9996 +vn -0.0019 0.0564 0.9984 +vn -0.0061 -0.0157 0.9999 +vn 0.0124 0.0407 0.9991 +vn -0.0135 -0.0143 0.9998 +vn -0.0077 0.0388 0.9992 +vn -0.0289 -0.0100 0.9995 +vn -0.0242 0.0042 0.9997 +vn 0.0261 0.0022 0.9997 +vn 0.0064 -0.0162 0.9998 +vn 0.0273 -0.0123 0.9996 +vn -0.0001 0.0007 1.0000 +vn -0.0042 0.0145 0.9999 +vn 0.0129 -0.0152 0.9998 +vn -0.0216 0.0131 -0.9997 +vn -0.0224 0.0137 -0.9997 +vn -0.0241 0.0115 -0.9996 +vn -0.0243 0.0198 -0.9995 +vn -0.0188 0.0311 -0.9993 +vn -0.0122 0.0373 -0.9992 +vn -0.0013 0.0000 -1.0000 +vn -0.0270 0.0000 -0.9996 +vn -0.0277 -0.0038 -0.9996 +vn -0.0015 -0.0002 -1.0000 +vn -0.0280 -0.0056 -0.9996 +vn -0.0016 -0.0003 -1.0000 +vn 0.0004 0.0307 -0.9995 +vn -0.0097 0.0307 -0.9995 +vn -0.0235 0.0783 -0.9967 +vn -0.0257 0.0060 -0.9997 +vn -0.0071 0.0381 -0.9992 +vn -0.0037 0.0421 -0.9991 +vn 0.0105 0.0477 -0.9988 +vn -0.0018 -0.0004 -1.0000 +vn -0.0303 -0.0073 -0.9995 +vn -0.0322 0.0014 -0.9995 +vn -0.2641 0.0090 -0.9644 +vn 0.0138 0.0197 -0.9997 +vn 0.0200 0.0091 -0.9998 +vn 0.0166 0.0067 -0.9998 +vn 0.0084 0.0055 -0.9999 +vn 0.0006 0.0003 -1.0000 +vn 0.0020 0.0035 -1.0000 +vn 0.0392 0.0979 -0.9944 +vn 0.0208 0.1090 -0.9938 +vn 0.0004 0.0011 -1.0000 +vn 0.2367 0.7197 -0.6528 +vn 0.1121 0.8011 -0.5879 +vn 0.0170 0.7864 -0.6174 +vn 0.0031 0.0652 -0.9979 +vn 0.0019 0.0395 -0.9992 +vn -0.0217 0.0103 -0.9997 +vn -0.0214 0.0116 -0.9997 +vn -0.0234 0.0065 -0.9997 +vn -0.0223 0.0087 -0.9997 +vn -0.0163 -0.0134 -0.9998 +vn -0.0163 -0.0101 -0.9998 +vn -0.0135 -0.0063 -0.9999 +vn -0.0018 -0.0164 -0.9999 +vn -0.0030 -0.0162 -0.9999 +vn -0.0045 -0.0159 -0.9999 +vn -0.0077 -0.0155 -0.9999 +vn -0.0093 -0.0152 -0.9998 +vn 0.0246 0.0122 -0.9996 +vn 0.0225 0.0148 -0.9996 +vn 0.0213 0.0142 -0.9997 +vn 0.0123 0.0146 -0.9998 +vn 0.0134 0.0147 -0.9998 +vn 0.0202 0.0091 -0.9998 +vn 0.0249 -0.0047 -0.9997 +vn 0.0262 -0.0036 -0.9997 +vn 0.0268 0.0009 -0.9996 +vn -0.0139 0.0146 -0.9998 +vn -0.0007 0.0006 -1.0000 +vn 0.0263 0.0069 -0.9996 +vn -0.0003 0.0136 -0.9999 +vn 0.0165 0.0150 -0.9998 +vn 0.0004 0.0007 -1.0000 +vn 0.0242 -0.0008 -0.9997 +vn -0.0008 0.0023 -1.0000 +vn -0.0019 0.0030 -1.0000 +vn -0.0047 0.0056 -1.0000 +vn 0.0002 0.0025 -1.0000 +vn -0.0000 0.0003 -1.0000 +vn -0.0192 0.0099 -0.9998 +vn -0.0218 0.0117 -0.9997 +vn -0.0207 0.0157 -0.9997 +vn -0.0125 0.0088 -0.9999 +vn 0.0213 0.0120 -0.9997 +vn 0.0221 0.0096 -0.9997 +vn 0.0230 0.0073 -0.9997 +vn 0.0242 0.0050 -0.9997 +vn 0.0216 -0.0136 -0.9997 +vn 0.0178 -0.0143 -0.9997 +vn 0.0149 -0.0147 -0.9998 +vn 0.0050 -0.0165 -0.9999 +vn 0.0021 -0.0164 -0.9999 +vn 0.0011 -0.0165 -0.9999 +vn 0.0282 -0.0012 -0.9996 +vn 0.0306 -0.0051 -0.9995 +vn 0.0315 -0.0093 -0.9995 +vn 0.0123 0.0404 -0.9991 +vn -0.0135 -0.0143 -0.9998 +vn -0.0077 0.0385 -0.9992 +vn -0.0143 0.0002 -0.9999 +vn -0.0202 0.0030 -0.9998 +vn 0.0261 0.0021 -0.9997 +vn -0.0036 -0.0004 -1.0000 +vn -0.0007 0.0009 -1.0000 +vn 0.0023 -0.0045 -1.0000 +vn 0.0069 -0.0174 -0.9998 +vn 0.0003 0.0004 -1.0000 +vn 0.0172 0.0150 -0.9997 +vn 0.0273 -0.0123 -0.9996 +vn -0.0003 0.0008 -1.0000 +vn -0.0042 0.0145 -0.9999 +vn 0.0128 -0.0151 -0.9998 +vn -0.1974 0.8446 -0.4976 +vn -0.1271 0.9831 0.1319 +vn 0.0209 0.9626 0.2702 +vn 0.1379 0.9684 0.2078 +vn 0.2463 0.9568 0.1544 +vn 0.5015 0.8324 0.2359 +vn 0.2463 0.9568 0.1543 +vn 0.3525 0.9299 -0.1050 +vn 0.3526 0.9299 -0.1050 +vn 0.0865 0.9693 0.2302 +vn 0.5158 -0.7549 -0.4051 +vn 0.5157 -0.7548 -0.4054 +vn 0.4733 -0.7858 -0.3981 +vn 0.4734 -0.7858 -0.3981 +vn 0.3440 -0.6698 -0.6581 +vn -0.1334 0.4284 -0.8937 +vn -0.1335 0.4284 -0.8937 +vn 0.2555 0.7440 -0.6174 +vn 0.0501 0.5296 -0.8468 +vn 0.2554 0.7440 -0.6174 +vn 0.0868 0.2857 -0.9544 +vn 0.0277 0.0587 -0.9979 +vn -0.0286 -0.0067 -0.9996 +vn -0.0016 -0.0004 -1.0000 +vn 0.0067 0.0472 0.9989 +vn 0.0004 0.0019 1.0000 +vn 0.0599 0.4710 0.8801 +vn -0.0321 0.0015 0.9995 +vn -0.2642 0.0091 0.9644 +vn -0.9728 -0.2316 -0.0000 +vn 0.3255 0.9446 0.0430 +vn 0.3673 0.9216 0.1258 +vn 0.4883 0.8645 0.1191 +vn 0.2515 0.9438 0.2145 +vn 0.3673 0.9215 0.1259 +vn 0.4882 0.8646 0.1190 +vn -0.8082 0.1495 -0.5696 +vn -0.8081 0.1494 -0.5697 +vn -0.8082 0.1494 -0.5696 +vn 0.0799 0.9909 0.1087 +vn 0.1121 0.8010 -0.5880 +vn 0.0746 0.9773 0.1984 +vn 0.0599 0.4711 0.8800 +vn -0.8081 0.1495 0.5697 +vn -0.8082 0.1495 0.5696 +vn -0.8082 0.1494 0.5696 +usemtl Scene_-_Root +s off +f 6457/6457/4149 6458/6458/4149 6459/6459/4149 +f 6457/6457/4149 6459/6459/4149 6460/6460/4149 +f 6458/6458/4149 6462/6461/4150 6459/6459/4149 +f 6459/6459/4149 6463/6462/4151 6464/6463/4149 +f 6460/6460/4149 6459/6459/4149 6464/6463/4149 +f 6460/6460/4149 6464/6463/4149 6465/6464/4149 +f 6466/6465/4149 6467/6466/4149 6468/6467/4149 +f 6466/6465/4149 6468/6467/4149 6469/6468/4149 +f 6467/6466/4149 6470/6469/4149 6471/6470/4149 +f 6467/6466/4149 6471/6470/4149 6468/6467/4149 +f 6475/6471/4149 6476/6472/4149 6477/6473/4149 +f 6475/6471/4149 6477/6473/4149 6478/6474/4149 +f 6476/6472/4149 6479/6475/4149 6480/6476/4149 +f 6476/6472/4149 6480/6476/4149 6477/6473/4149 +f 6477/6473/4149 6480/6476/4149 6481/6477/4149 +f 6477/6473/4149 6481/6477/4149 6482/6478/4149 +f 6478/6474/4149 6477/6473/4149 6482/6478/4149 +f 6478/6474/4149 6482/6478/4149 6483/6479/4149 +f 6484/6480/4149 6485/6481/4149 6486/6482/4149 +f 6484/6480/4149 6486/6482/4149 6487/6483/4149 +f 6485/6481/4149 6488/6484/4149 6489/6485/4149 +f 6485/6481/4149 6489/6485/4149 6486/6482/4149 +f 6486/6482/4149 6489/6485/4149 6490/6486/4149 +f 6486/6482/4149 6490/6486/4149 6491/6487/4149 +f 6487/6483/4149 6486/6482/4149 6491/6487/4149 +f 6487/6483/4149 6491/6487/4149 6492/6488/4149 +f 6493/6489/4149 6494/6490/4149 6495/6491/4149 +f 6493/6489/4149 6495/6491/4149 6496/6492/4149 +f 6494/6490/4149 6498/6493/4152 6495/6491/4149 +f 6495/6491/4149 6499/6494/4153 6500/6495/4149 +f 6496/6492/4149 6495/6491/4149 6500/6495/4149 +f 6496/6492/4149 6500/6495/4149 6501/6496/4149 +f 6502/6497/4149 6503/6498/4149 6504/6499/4149 +f 6502/6497/4149 6504/6499/4149 6505/6500/4149 +f 6503/6498/4149 6506/6501/4149 6507/6502/4149 +f 6503/6498/4149 6507/6502/4149 6504/6499/4149 +f 6504/6499/4149 6497/6503/4154 6494/6490/4149 +f 6505/6500/4149 6504/6499/4149 6494/6490/4149 +f 6505/6500/4149 6494/6490/4149 6493/6489/4149 +f 6506/6501/4149 6508/6504/4149 6509/6505/4149 +f 6506/6501/4149 6509/6505/4149 6507/6502/4149 +f 6508/6504/4149 6510/6506/4149 6511/6507/4149 +f 6508/6504/4149 6511/6507/4149 6509/6505/4149 +f 6509/6505/4149 6511/6507/4149 6512/6508/4149 +f 6509/6505/4149 6512/6508/4149 6513/6509/4149 +f 6507/6502/4149 6509/6505/4149 6513/6509/4149 +f 6514/6510/4149 6515/6511/4149 6516/6512/4149 +f 6514/6510/4149 6516/6512/4149 6517/6513/4149 +f 6515/6511/4149 6518/6514/4149 6519/6515/4149 +f 6515/6511/4149 6519/6515/4149 6516/6512/4149 +f 6516/6512/4149 6519/6515/4149 6520/6516/4149 +f 6516/6512/4149 6520/6516/4149 6521/6517/4149 +f 6517/6513/4149 6516/6512/4149 6521/6517/4149 +f 6517/6513/4149 6521/6517/4149 6522/6518/4149 +f 6523/6519/4149 6524/6520/4149 6525/6521/4149 +f 6523/6519/4149 6525/6521/4149 6526/6522/4149 +f 6524/6520/4149 6527/6523/4149 6528/6524/4149 +f 6524/6520/4149 6528/6524/4149 6525/6521/4149 +f 6525/6521/4149 6528/6524/4149 6518/6514/4149 +f 6525/6521/4149 6518/6514/4149 6515/6511/4149 +f 6526/6522/4149 6525/6521/4149 6515/6511/4149 +f 6526/6522/4149 6515/6511/4149 6514/6510/4149 +f 6529/6525/4149 6530/6526/4149 6531/6527/4149 +f 6529/6525/4149 6531/6527/4149 6532/6528/4149 +f 6530/6526/4149 6533/6529/4149 6534/6530/4149 +f 6530/6526/4149 6534/6530/4149 6531/6527/4149 +f 6531/6527/4149 6534/6530/4149 6479/6475/4149 +f 6531/6527/4149 6479/6475/4149 6476/6472/4149 +f 6532/6528/4149 6531/6527/4149 6476/6472/4149 +f 6532/6528/4149 6476/6472/4149 6475/6471/4149 +f 6535/6531/4149 6536/6532/4149 6537/6533/4149 +f 6535/6531/4149 6537/6533/4149 6538/6534/4149 +f 6536/6532/4149 6539/6535/4149 6540/6536/4149 +f 6536/6532/4149 6540/6536/4149 6537/6533/4149 +f 6522/6518/4149 6521/6517/4149 6544/6537/4149 +f 6522/6518/4149 6544/6537/4149 6545/6538/4149 +f 6521/6517/4149 6520/6516/4149 6546/6539/4149 +f 6521/6517/4149 6546/6539/4149 6544/6537/4149 +f 6544/6537/4149 6546/6539/4149 6547/6540/4149 +f 6544/6537/4149 6547/6540/4149 6548/6541/4149 +f 6545/6538/4149 6544/6537/4149 6548/6541/4149 +f 6545/6538/4149 6548/6541/4149 6549/6542/4149 +f 6483/6479/4149 6482/6478/4149 6550/6543/4149 +f 6483/6479/4149 6550/6543/4149 6551/6544/4149 +f 6482/6478/4149 6481/6477/4149 6552/6545/4149 +f 6482/6478/4149 6552/6545/4149 6550/6543/4149 +f 6550/6543/4149 6552/6545/4149 6553/6546/4149 +f 6550/6543/4149 6553/6546/4149 6554/6547/4149 +f 6551/6544/4149 6550/6543/4149 6554/6547/4149 +f 6551/6544/4149 6554/6547/4149 6555/6548/4149 +f 6556/6549/4149 6557/6550/4149 6558/6551/4149 +f 6556/6549/4149 6558/6551/4149 6559/6552/4149 +f 6557/6550/4149 6561/6553/4155 6558/6551/4149 +f 6501/6496/4149 6500/6495/4149 6565/6554/4149 +f 6501/6496/4149 6565/6554/4149 6566/6555/4149 +f 6500/6495/4149 6567/6556/4156 6565/6554/4149 +f 6565/6554/4149 6568/6557/4157 6569/6558/4149 +f 6566/6555/4149 6565/6554/4149 6569/6558/4149 +f 6566/6555/4149 6569/6558/4149 6570/6559/4149 +f 6571/6560/4149 6572/6561/4149 6573/6562/4149 +f 6571/6560/4149 6573/6562/4149 6574/6563/4149 +f 6572/6561/4149 6575/6564/4149 6576/6565/4149 +f 6572/6561/4149 6576/6565/4149 6573/6562/4149 +f 6573/6562/4149 6576/6565/4149 6577/6566/4149 +f 6573/6562/4149 6577/6566/4149 6578/6567/4149 +f 6574/6563/4149 6573/6562/4149 6578/6567/4149 +f 6574/6563/4149 6578/6567/4149 6579/6568/4149 +f 6580/6569/4149 6581/6570/4149 6582/6571/4149 +f 6580/6569/4149 6582/6571/4149 6583/6572/4149 +f 6581/6570/4149 6533/6529/4149 6584/6573/4149 +f 6581/6570/4149 6584/6573/4149 6582/6571/4149 +f 6582/6571/4149 6584/6573/4149 6575/6564/4149 +f 6582/6571/4149 6575/6564/4149 6572/6561/4149 +f 6583/6572/4149 6582/6571/4149 6572/6561/4149 +f 6583/6572/4149 6572/6561/4149 6571/6560/4149 +f 6529/6525/4149 6585/6574/4149 6586/6575/4149 +f 6529/6525/4149 6586/6575/4149 6587/6576/4149 +f 6585/6574/4149 6527/6523/4149 6588/6577/4149 +f 6585/6574/4149 6588/6577/4149 6586/6575/4149 +f 6586/6575/4149 6588/6577/4149 6589/6578/4149 +f 6586/6575/4149 6589/6578/4149 6590/6579/4149 +f 6587/6576/4149 6586/6575/4149 6590/6579/4149 +f 6587/6576/4149 6590/6579/4149 6591/6580/4149 +f 6592/6581/4149 6593/6582/4149 6594/6583/4149 +f 6592/6581/4149 6594/6583/4149 6595/6584/4149 +f 6593/6582/4149 6596/6585/4149 6597/6586/4149 +f 6593/6582/4149 6597/6586/4149 6594/6583/4149 +f 6594/6583/4149 6597/6586/4149 6488/6484/4149 +f 6594/6583/4149 6488/6484/4149 6485/6481/4149 +f 6595/6584/4149 6594/6583/4149 6485/6481/4149 +f 6595/6584/4149 6485/6481/4149 6484/6480/4149 +f 6598/6587/4149 6599/6588/4149 6600/6589/4149 +f 6598/6587/4149 6600/6589/4149 6601/6590/4149 +f 6599/6588/4149 6603/6591/4158 6600/6589/4149 +f 6600/6589/4149 6461/6592/4158 6458/6458/4149 +f 6601/6590/4149 6600/6589/4149 6458/6458/4149 +f 6601/6590/4149 6458/6458/4149 6457/6457/4149 +f 6591/6580/4149 6590/6579/4149 6604/6593/4149 +f 6591/6580/4149 6604/6593/4149 6605/6594/4149 +f 6590/6579/4149 6589/6578/4149 6606/6595/4149 +f 6590/6579/4149 6606/6595/4149 6604/6593/4149 +f 6604/6593/4149 6606/6595/4149 6607/6596/4149 +f 6604/6593/4149 6607/6596/4149 6608/6597/4149 +f 6605/6594/4149 6604/6593/4149 6608/6597/4149 +f 6605/6594/4149 6608/6597/4149 6609/6598/4149 +f 6610/6599/4149 6611/6600/4149 6612/6601/4149 +f 6610/6599/4149 6612/6601/4149 6613/6602/4149 +f 6611/6600/4149 6614/6603/4149 6615/6604/4149 +f 6611/6600/4149 6615/6604/4149 6612/6601/4149 +f 6619/6605/4149 6620/6606/4149 6621/6607/4149 +f 6619/6605/4149 6621/6607/4149 6622/6608/4149 +f 6620/6606/4149 6623/6609/4149 6624/6610/4149 +f 6620/6606/4149 6624/6610/4149 6621/6607/4149 +f 6628/6611/4149 6629/6612/4149 6630/6613/4149 +f 6628/6611/4149 6630/6613/4149 6631/6614/4149 +f 6629/6612/4149 6633/6615/4159 6630/6613/4149 +f 6637/6616/4149 6638/6617/4149 6639/6618/4149 +f 6637/6616/4149 6639/6618/4149 6640/6619/4149 +f 6638/6617/4149 6641/6620/4149 6642/6621/4149 +f 6638/6617/4149 6642/6621/4149 6639/6618/4149 +f 6646/6622/4149 6647/6623/4149 6648/6624/4149 +f 6646/6622/4149 6648/6624/4149 6649/6625/4149 +f 6647/6623/4149 6650/6626/4149 6651/6627/4149 +f 6647/6623/4149 6651/6627/4149 6648/6624/4149 +f 6655/6628/4149 6656/6629/4149 6657/6630/4149 +f 6655/6628/4149 6657/6630/4149 6658/6631/4149 +f 6656/6629/4149 6659/6632/4149 6660/6633/4149 +f 6656/6629/4149 6660/6633/4149 6657/6630/4149 +f 6657/6630/4149 6661/6634/4160 6662/6635/4149 +f 6658/6631/4149 6657/6630/4149 6662/6635/4149 +f 6658/6631/4149 6662/6635/4149 6663/6636/4149 +f 6664/6637/4149 6665/6638/4149 6666/6639/4149 +f 6664/6637/4149 6666/6639/4149 6667/6640/4149 +f 6665/6638/4149 6668/6641/4149 6669/6642/4149 +f 6665/6638/4149 6669/6642/4149 6666/6639/4149 +f 6666/6639/4149 6669/6642/4149 6670/6643/4149 +f 6666/6639/4149 6670/6643/4149 6671/6644/4149 +f 6667/6640/4149 6666/6639/4149 6671/6644/4149 +f 6667/6640/4149 6671/6644/4149 6672/6645/4149 +f 6484/6480/4149 6487/6483/4149 6673/6646/4149 +f 6484/6480/4149 6673/6646/4149 6674/6647/4149 +f 6487/6483/4149 6492/6488/4149 6675/6648/4149 +f 6487/6483/4149 6675/6648/4149 6673/6646/4149 +f 6673/6646/4149 6675/6648/4149 6676/6649/4149 +f 6673/6646/4149 6676/6649/4149 6677/6650/4149 +f 6674/6647/4149 6673/6646/4149 6677/6650/4149 +f 6674/6647/4149 6677/6650/4149 6678/6651/4149 +f 6679/6652/4149 6680/6653/4149 6681/6654/4149 +f 6679/6652/4149 6681/6654/4149 6682/6655/4149 +f 6680/6653/4149 6683/6656/4149 6684/6657/4149 +f 6680/6653/4149 6684/6657/4149 6681/6654/4149 +f 6681/6654/4149 6685/6658/4161 6686/6659/4149 +f 6682/6655/4149 6681/6654/4149 6686/6659/4149 +f 6682/6655/4149 6686/6659/4149 6687/6660/4149 +f 6688/6661/4149 6689/6662/4149 6690/6663/4149 +f 6688/6661/4149 6690/6663/4149 6691/6664/4149 +f 6689/6662/4149 6679/6652/4149 6682/6655/4149 +f 6689/6662/4149 6682/6655/4149 6690/6663/4149 +f 6690/6663/4149 6682/6655/4149 6687/6660/4149 +f 6690/6663/4149 6687/6660/4149 6692/6665/4149 +f 6691/6664/4149 6690/6663/4149 6692/6665/4149 +f 6691/6664/4149 6692/6665/4149 6693/6666/4149 +f 6693/6666/4149 6692/6665/4149 6694/6667/4149 +f 6693/6666/4149 6694/6667/4149 6695/6668/4149 +f 6692/6665/4149 6687/6660/4149 6696/6669/4149 +f 6692/6665/4149 6696/6669/4149 6694/6667/4149 +f 6694/6667/4149 6696/6669/4149 6512/6508/4149 +f 6694/6667/4149 6512/6508/4149 6511/6507/4149 +f 6695/6668/4149 6694/6667/4149 6511/6507/4149 +f 6695/6668/4149 6511/6507/4149 6510/6506/4149 +f 6697/6670/4149 6698/6671/4149 6699/6672/4149 +f 6697/6670/4149 6699/6672/4149 6700/6673/4149 +f 6698/6671/4149 6701/6674/4149 6702/6675/4149 +f 6698/6671/4149 6702/6675/4149 6699/6672/4149 +f 6699/6672/4149 6702/6675/4149 6703/6676/4149 +f 6699/6672/4149 6703/6676/4149 6704/6677/4149 +f 6700/6673/4149 6699/6672/4149 6704/6677/4149 +f 6700/6673/4149 6704/6677/4149 6705/6678/4149 +f 6706/6679/4149 6707/6680/4149 6708/6681/4149 +f 6706/6679/4149 6708/6681/4149 6709/6682/4149 +f 6707/6680/4149 6697/6670/4149 6700/6673/4149 +f 6707/6680/4149 6700/6673/4149 6708/6681/4149 +f 6708/6681/4149 6700/6673/4149 6705/6678/4149 +f 6708/6681/4149 6705/6678/4149 6710/6683/4149 +f 6709/6682/4149 6708/6681/4149 6710/6683/4149 +f 6709/6682/4149 6710/6683/4149 6711/6684/4149 +f 6712/6685/4149 6713/6686/4149 6714/6687/4149 +f 6712/6685/4149 6714/6687/4149 6715/6688/4149 +f 6713/6686/4149 6664/6637/4149 6667/6640/4149 +f 6713/6686/4149 6667/6640/4149 6714/6687/4149 +f 6714/6687/4149 6667/6640/4149 6672/6645/4149 +f 6714/6687/4149 6672/6645/4149 6716/6689/4149 +f 6715/6688/4149 6714/6687/4149 6716/6689/4149 +f 6715/6688/4149 6716/6689/4149 6717/6690/4149 +f 6718/6691/4149 6719/6692/4149 6720/6693/4149 +f 6718/6691/4149 6720/6693/4149 6721/6694/4149 +f 6719/6692/4149 6723/6695/4162 6720/6693/4149 +f 6720/6693/4149 6724/6696/4162 6725/6697/4149 +f 6721/6694/4149 6720/6693/4149 6725/6697/4149 +f 6721/6694/4149 6725/6697/4149 6726/6698/4149 +f 6701/6674/4149 6727/6699/4149 6728/6700/4149 +f 6701/6674/4149 6728/6700/4149 6702/6675/4149 +f 6727/6699/4149 6729/6701/4149 6730/6702/4149 +f 6727/6699/4149 6730/6702/4149 6728/6700/4149 +f 6728/6700/4149 6730/6702/4149 6731/6703/4149 +f 6728/6700/4149 6731/6703/4149 6732/6704/4149 +f 6702/6675/4149 6728/6700/4149 6732/6704/4149 +f 6702/6675/4149 6732/6704/4149 6703/6676/4149 +f 6668/6641/4149 6733/6705/4149 6734/6706/4149 +f 6668/6641/4149 6734/6706/4149 6669/6642/4149 +f 6733/6705/4149 6735/6707/4149 6736/6708/4149 +f 6733/6705/4149 6736/6708/4149 6734/6706/4149 +f 6734/6706/4149 6736/6708/4149 6737/6709/4149 +f 6734/6706/4149 6737/6709/4149 6738/6710/4149 +f 6669/6642/4149 6734/6706/4149 6738/6710/4149 +f 6669/6642/4149 6738/6710/4149 6670/6643/4149 +f 6739/6711/4149 6740/6712/4149 6741/6713/4149 +f 6739/6711/4149 6741/6713/4149 6742/6714/4149 +f 6740/6712/4149 6744/6715/4163 6741/6713/4149 +f 6683/6656/4149 6748/6716/4149 6749/6717/4149 +f 6683/6656/4149 6749/6717/4149 6684/6657/4149 +f 6748/6716/4149 6739/6711/4149 6742/6714/4149 +f 6748/6716/4149 6742/6714/4149 6749/6717/4149 +f 6751/6718/4149 6752/6719/4149 6753/6720/4149 +f 6751/6718/4149 6753/6720/4149 6754/6721/4149 +f 6752/6719/4149 6755/6722/4149 6756/6723/4149 +f 6752/6719/4149 6756/6723/4149 6753/6720/4149 +f 6753/6720/4149 6756/6723/4149 6757/6724/4149 +f 6753/6720/4149 6757/6724/4149 6758/6725/4149 +f 6754/6721/4149 6753/6720/4149 6758/6725/4149 +f 6754/6721/4149 6758/6725/4149 6759/6726/4149 +f 6760/6727/4149 6761/6728/4149 6762/6729/4149 +f 6760/6727/4149 6762/6729/4149 6763/6730/4149 +f 6761/6728/4149 6751/6718/4149 6754/6721/4149 +f 6761/6728/4149 6754/6721/4149 6762/6729/4149 +f 6762/6729/4149 6754/6721/4149 6759/6726/4149 +f 6762/6729/4149 6759/6726/4149 6764/6731/4149 +f 6763/6730/4149 6762/6729/4149 6764/6731/4149 +f 6763/6730/4149 6764/6731/4149 6717/6690/4149 +f 6712/6685/4149 6765/6732/4149 6766/6733/4149 +f 6712/6685/4149 6766/6733/4149 6767/6734/4149 +f 6765/6732/4149 6768/6735/4149 6769/6736/4149 +f 6765/6732/4149 6769/6736/4149 6766/6733/4149 +f 6766/6733/4149 6769/6736/4149 6770/6737/4149 +f 6766/6733/4149 6770/6737/4149 6771/6738/4149 +f 6767/6734/4149 6766/6733/4149 6771/6738/4149 +f 6767/6734/4149 6771/6738/4149 6711/6684/4149 +f 6592/6581/4149 6595/6584/4149 6772/6739/4149 +f 6592/6581/4149 6772/6739/4149 6773/6740/4149 +f 6595/6584/4149 6484/6480/4149 6674/6647/4149 +f 6595/6584/4149 6674/6647/4149 6772/6739/4149 +f 6772/6739/4149 6674/6647/4149 6678/6651/4149 +f 6772/6739/4149 6678/6651/4149 6774/6741/4149 +f 6773/6740/4149 6772/6739/4149 6774/6741/4149 +f 6773/6740/4149 6774/6741/4149 6775/6742/4149 +f 6776/6743/4149 6777/6744/4149 6778/6745/4149 +f 6776/6743/4149 6778/6745/4149 6779/6746/4149 +f 6777/6744/4149 6646/6622/4149 6649/6625/4149 +f 6777/6744/4149 6649/6625/4149 6778/6745/4149 +f 6768/6735/4149 6782/6747/4149 6783/6748/4149 +f 6768/6735/4149 6783/6748/4149 6769/6736/4149 +f 6782/6747/4149 6784/6749/4149 6785/6750/4149 +f 6782/6747/4149 6785/6750/4149 6783/6748/4149 +f 6783/6748/4149 6785/6750/4149 6786/6751/4149 +f 6783/6748/4149 6786/6751/4149 6787/6752/4149 +f 6769/6736/4149 6783/6748/4149 6787/6752/4149 +f 6769/6736/4149 6787/6752/4149 6770/6737/4149 +f 6788/6753/4149 6789/6754/4149 6790/6755/4149 +f 6788/6753/4149 6790/6755/4149 6791/6756/4149 +f 6789/6754/4149 6793/6757/4164 6790/6755/4149 +f 6790/6755/4149 6794/6758/4164 6795/6759/4149 +f 6791/6756/4149 6790/6755/4149 6795/6759/4149 +f 6791/6756/4149 6795/6759/4149 6796/6760/4149 +f 6797/6761/4149 6798/6762/4149 6799/6763/4149 +f 6797/6761/4149 6799/6763/4149 6800/6764/4149 +f 6798/6762/4149 6802/6765/4165 6799/6763/4149 +f 6799/6763/4149 6803/6766/4166 6804/6767/4149 +f 6800/6764/4149 6799/6763/4149 6804/6767/4149 +f 6800/6764/4149 6804/6767/4149 6805/6768/4149 +f 6806/6769/4149 6807/6770/4149 6808/6771/4149 +f 6806/6769/4149 6808/6771/4149 6809/6772/4149 +f 6807/6770/4149 6811/6773/4167 6808/6771/4149 +f 6637/6616/4149 6640/6619/4149 6815/6774/4149 +f 6637/6616/4149 6815/6774/4149 6816/6775/4149 +f 6640/6619/4149 6817/6776/4168 6815/6774/4149 +f 6815/6774/4149 6818/6777/4169 6819/6778/4149 +f 6816/6775/4149 6815/6774/4149 6819/6778/4149 +f 6816/6775/4149 6819/6778/4149 6820/6779/4149 +f 6641/6620/4149 6821/6780/4149 6822/6781/4149 +f 6641/6620/4149 6822/6781/4149 6642/6621/4149 +f 6821/6780/4149 6610/6599/4149 6613/6602/4149 +f 6821/6780/4149 6613/6602/4149 6822/6781/4149 +f 6596/6585/4149 6824/6782/4149 6825/6783/4149 +f 6596/6585/4149 6825/6783/4149 6597/6586/4149 +f 6824/6782/4149 6580/6569/4149 6583/6572/4149 +f 6824/6782/4149 6583/6572/4149 6825/6783/4149 +f 6825/6783/4149 6583/6572/4149 6571/6560/4149 +f 6825/6783/4149 6571/6560/4149 6826/6784/4149 +f 6597/6586/4149 6825/6783/4149 6826/6784/4149 +f 6597/6586/4149 6826/6784/4149 6488/6484/4149 +f 6488/6484/4149 6826/6784/4149 6827/6785/4149 +f 6488/6484/4149 6827/6785/4149 6489/6485/4149 +f 6826/6784/4149 6571/6560/4149 6574/6563/4149 +f 6826/6784/4149 6574/6563/4149 6827/6785/4149 +f 6827/6785/4149 6574/6563/4149 6579/6568/4149 +f 6827/6785/4149 6579/6568/4149 6828/6786/4149 +f 6489/6485/4149 6827/6785/4149 6828/6786/4149 +f 6489/6485/4149 6828/6786/4149 6490/6486/4149 +f 6481/6477/4149 6829/6787/4149 6830/6788/4149 +f 6481/6477/4149 6830/6788/4149 6552/6545/4149 +f 6829/6787/4149 6831/6789/4149 6832/6790/4149 +f 6829/6787/4149 6832/6790/4149 6830/6788/4149 +f 6830/6788/4149 6832/6790/4149 6833/6791/4149 +f 6830/6788/4149 6833/6791/4149 6834/6792/4149 +f 6552/6545/4149 6830/6788/4149 6834/6792/4149 +f 6552/6545/4149 6834/6792/4149 6553/6546/4149 +f 6470/6469/4149 6835/6793/4149 6836/6794/4149 +f 6470/6469/4149 6836/6794/4149 6471/6470/4149 +f 6835/6793/4149 6556/6549/4149 6559/6552/4149 +f 6835/6793/4149 6559/6552/4149 6836/6794/4149 +f 6533/6529/4149 6581/6570/4149 6838/6795/4149 +f 6533/6529/4149 6838/6795/4149 6534/6530/4149 +f 6581/6570/4149 6580/6569/4149 6839/6796/4149 +f 6581/6570/4149 6839/6796/4149 6838/6795/4149 +f 6838/6795/4149 6839/6796/4149 6840/6797/4149 +f 6838/6795/4149 6840/6797/4149 6841/6798/4149 +f 6534/6530/4149 6838/6795/4149 6841/6798/4149 +f 6534/6530/4149 6841/6798/4149 6479/6475/4149 +f 6479/6475/4149 6841/6798/4149 6842/6799/4149 +f 6479/6475/4149 6842/6799/4149 6480/6476/4149 +f 6841/6798/4149 6840/6797/4149 6843/6800/4149 +f 6841/6798/4149 6843/6800/4149 6842/6799/4149 +f 6842/6799/4149 6843/6800/4149 6831/6789/4149 +f 6842/6799/4149 6831/6789/4149 6829/6787/4149 +f 6480/6476/4149 6842/6799/4149 6829/6787/4149 +f 6480/6476/4149 6829/6787/4149 6481/6477/4149 +f 6614/6603/4149 6844/6801/4149 6845/6802/4149 +f 6614/6603/4149 6845/6802/4149 6615/6604/4149 +f 6844/6801/4149 6619/6605/4149 6622/6608/4149 +f 6844/6801/4149 6622/6608/4149 6845/6802/4149 +f 6575/6564/4149 6847/6803/4149 6848/6804/4149 +f 6575/6564/4149 6848/6804/4149 6576/6565/4149 +f 6847/6803/4149 6591/6580/4149 6605/6594/4149 +f 6847/6803/4149 6605/6594/4149 6848/6804/4149 +f 6848/6804/4149 6605/6594/4149 6609/6598/4149 +f 6848/6804/4149 6609/6598/4149 6849/6805/4149 +f 6576/6565/4149 6848/6804/4149 6849/6805/4149 +f 6576/6565/4149 6849/6805/4149 6577/6566/4149 +f 6533/6529/4149 6530/6526/4149 6850/6806/4149 +f 6533/6529/4149 6850/6806/4149 6584/6573/4149 +f 6530/6526/4149 6529/6525/4149 6587/6576/4149 +f 6530/6526/4149 6587/6576/4149 6850/6806/4149 +f 6850/6806/4149 6587/6576/4149 6591/6580/4149 +f 6850/6806/4149 6591/6580/4149 6847/6803/4149 +f 6584/6573/4149 6850/6806/4149 6847/6803/4149 +f 6584/6573/4149 6847/6803/4149 6575/6564/4149 +f 6520/6516/4149 6851/6807/4149 6852/6808/4149 +f 6520/6516/4149 6852/6808/4149 6546/6539/4149 +f 6851/6807/4149 6483/6479/4149 6551/6544/4149 +f 6851/6807/4149 6551/6544/4149 6852/6808/4149 +f 6852/6808/4149 6551/6544/4149 6555/6548/4149 +f 6852/6808/4149 6555/6548/4149 6853/6809/4149 +f 6546/6539/4149 6852/6808/4149 6853/6809/4149 +f 6546/6539/4149 6853/6809/4149 6547/6540/4149 +f 6527/6523/4149 6585/6574/4149 6854/6810/4149 +f 6527/6523/4149 6854/6810/4149 6528/6524/4149 +f 6585/6574/4149 6529/6525/4149 6532/6528/4149 +f 6585/6574/4149 6532/6528/4149 6854/6810/4149 +f 6854/6810/4149 6532/6528/4149 6475/6471/4149 +f 6854/6810/4149 6475/6471/4149 6855/6811/4149 +f 6528/6524/4149 6854/6810/4149 6855/6811/4149 +f 6528/6524/4149 6855/6811/4149 6518/6514/4149 +f 6518/6514/4149 6855/6811/4149 6856/6812/4149 +f 6518/6514/4149 6856/6812/4149 6519/6515/4149 +f 6855/6811/4149 6475/6471/4149 6478/6474/4149 +f 6855/6811/4149 6478/6474/4149 6856/6812/4149 +f 6856/6812/4149 6478/6474/4149 6483/6479/4149 +f 6856/6812/4149 6483/6479/4149 6851/6807/4149 +f 6519/6515/4149 6856/6812/4149 6851/6807/4149 +f 6519/6515/4149 6851/6807/4149 6520/6516/4149 +f 6539/6535/4149 6857/6813/4149 6858/6814/4149 +f 6539/6535/4149 6858/6814/4149 6540/6536/4149 +f 6857/6813/4149 6466/6465/4149 6469/6468/4149 +f 6857/6813/4149 6469/6468/4149 6858/6814/4149 +f 6623/6609/4149 6860/6815/4149 6861/6816/4149 +f 6623/6609/4149 6861/6816/4149 6624/6610/4149 +f 6860/6815/4149 6628/6611/4149 6631/6614/4149 +f 6860/6815/4149 6631/6614/4149 6861/6816/4149 +f 6527/6523/4149 6524/6520/4149 6863/6817/4149 +f 6527/6523/4149 6863/6817/4149 6588/6577/4149 +f 6524/6520/4149 6523/6519/4149 6864/6818/4149 +f 6524/6520/4149 6864/6818/4149 6863/6817/4149 +f 6863/6817/4149 6864/6818/4149 6865/6819/4149 +f 6863/6817/4149 6865/6819/4149 6866/6820/4149 +f 6588/6577/4149 6863/6817/4149 6866/6820/4149 +f 6588/6577/4149 6866/6820/4149 6589/6578/4149 +f 6867/6821/4170 6868/6822/4149 6869/6823/4149 +f 6868/6822/4149 6871/6824/4149 6872/6825/4149 +f 6868/6822/4149 6872/6825/4149 6869/6823/4149 +f 6869/6823/4149 6872/6825/4149 6873/6826/4149 +f 6869/6823/4149 6873/6826/4149 6874/6827/4149 +f 6870/6828/4171 6869/6823/4149 6874/6827/4149 +f 6876/6829/4172 6877/6830/4149 6878/6831/4149 +f 6877/6830/4149 6535/6531/4149 6538/6534/4149 +f 6877/6830/4149 6538/6534/4149 6878/6831/4149 +f 6602/6832/4173 6599/6588/4149 6882/6833/4149 +f 6599/6588/4149 6598/6587/4149 6884/6834/4149 +f 6599/6588/4149 6884/6834/4149 6882/6833/4149 +f 6882/6833/4149 6884/6834/4149 6885/6835/4149 +f 6882/6833/4149 6885/6835/4149 6886/6836/4149 +f 6883/6837/4173 6882/6833/4149 6886/6836/4149 +f 6887/6838/4174 6886/6836/4149 6888/6839/4149 +f 6886/6836/4149 6885/6835/4149 6890/6840/4149 +f 6886/6836/4149 6890/6840/4149 6888/6839/4149 +f 6888/6839/4149 6890/6840/4149 6871/6824/4149 +f 6888/6839/4149 6871/6824/4149 6868/6822/4149 +f 6889/6841/4175 6888/6839/4149 6868/6822/4149 +f 6589/6578/4149 6866/6820/4149 6891/6842/4149 +f 6589/6578/4149 6891/6842/4149 6606/6595/4149 +f 6866/6820/4149 6865/6819/4149 6892/6843/4149 +f 6866/6820/4149 6892/6843/4149 6891/6842/4149 +f 6891/6842/4149 6892/6843/4149 6893/6844/4149 +f 6891/6842/4149 6893/6844/4149 6894/6845/4149 +f 6606/6595/4149 6891/6842/4149 6894/6845/4149 +f 6606/6595/4149 6894/6845/4149 6607/6596/4149 +f 6607/6596/4149 6894/6845/4149 6895/6846/4149 +f 6607/6596/4149 6895/6846/4149 6896/6847/4149 +f 6894/6845/4149 6893/6844/4149 6897/6848/4149 +f 6894/6845/4149 6897/6848/4149 6895/6846/4149 +f 6895/6846/4149 6897/6848/4149 6898/6849/4149 +f 6895/6846/4149 6898/6849/4149 6899/6850/4149 +f 6896/6847/4149 6895/6846/4149 6899/6850/4149 +f 6896/6847/4149 6899/6850/4149 6900/6851/4149 +f 6577/6566/4149 6849/6805/4149 6901/6852/4149 +f 6577/6566/4149 6901/6852/4149 6902/6853/4149 +f 6849/6805/4149 6609/6598/4149 6903/6854/4149 +f 6849/6805/4149 6903/6854/4149 6901/6852/4149 +f 6901/6852/4149 6903/6854/4149 6904/6855/4149 +f 6901/6852/4149 6904/6855/4149 6905/6856/4149 +f 6902/6853/4149 6901/6852/4149 6905/6856/4149 +f 6902/6853/4149 6905/6856/4149 6906/6857/4149 +f 6490/6486/4149 6828/6786/4149 6907/6858/4149 +f 6490/6486/4149 6907/6858/4149 6908/6859/4149 +f 6828/6786/4149 6579/6568/4149 6909/6860/4149 +f 6828/6786/4149 6909/6860/4149 6907/6858/4149 +f 6907/6858/4149 6909/6860/4149 6910/6861/4149 +f 6907/6858/4149 6910/6861/4149 6911/6862/4149 +f 6908/6859/4149 6907/6858/4149 6911/6862/4149 +f 6908/6859/4149 6911/6862/4149 6912/6863/4149 +f 6492/6488/4149 6913/6864/4149 6914/6865/4149 +f 6492/6488/4149 6914/6865/4149 6675/6648/4149 +f 6913/6864/4149 6915/6866/4149 6916/6867/4149 +f 6913/6864/4149 6916/6867/4149 6914/6865/4149 +f 6914/6865/4149 6916/6867/4149 6917/6868/4149 +f 6914/6865/4149 6917/6868/4149 6918/6869/4149 +f 6675/6648/4149 6914/6865/4149 6918/6869/4149 +f 6675/6648/4149 6918/6869/4149 6676/6649/4149 +f 6650/6626/4149 6919/6870/4149 6920/6871/4149 +f 6650/6626/4149 6920/6871/4149 6651/6627/4149 +f 6919/6870/4149 6806/6769/4149 6809/6772/4149 +f 6919/6870/4149 6809/6772/4149 6920/6871/4149 +f 6784/6749/4149 6922/6872/4149 6923/6873/4149 +f 6784/6749/4149 6923/6873/4149 6785/6750/4149 +f 6922/6872/4149 6924/6874/4149 6925/6875/4149 +f 6922/6872/4149 6925/6875/4149 6923/6873/4149 +f 6923/6873/4149 6925/6875/4149 6926/6876/4149 +f 6923/6873/4149 6926/6876/4149 6927/6877/4149 +f 6785/6750/4149 6923/6873/4149 6927/6877/4149 +f 6785/6750/4149 6927/6877/4149 6786/6751/4149 +f 6755/6722/4149 6928/6878/4149 6929/6879/4149 +f 6755/6722/4149 6929/6879/4149 6756/6723/4149 +f 6928/6878/4149 6930/6880/4149 6931/6881/4149 +f 6928/6878/4149 6931/6881/4149 6929/6879/4149 +f 6929/6879/4149 6931/6881/4149 6932/6882/4149 +f 6929/6879/4149 6932/6882/4149 6933/6883/4149 +f 6756/6723/4149 6929/6879/4149 6933/6883/4149 +f 6756/6723/4149 6933/6883/4149 6757/6724/4149 +f 6492/6488/4149 6491/6487/4149 6934/6884/4149 +f 6492/6488/4149 6934/6884/4149 6913/6864/4149 +f 6491/6487/4149 6490/6486/4149 6908/6859/4149 +f 6491/6487/4149 6908/6859/4149 6934/6884/4149 +f 6934/6884/4149 6908/6859/4149 6912/6863/4149 +f 6934/6884/4149 6912/6863/4149 6935/6885/4149 +f 6913/6864/4149 6934/6884/4149 6935/6885/4149 +f 6913/6864/4149 6935/6885/4149 6915/6866/4149 +f 6465/6464/4149 6464/6463/4149 6936/6886/4149 +f 6465/6464/4149 6936/6886/4149 6937/6887/4149 +f 6464/6463/4149 6938/6888/4176 6936/6886/4149 +f 6936/6886/4149 6632/6889/4177 6629/6612/4149 +f 6937/6887/4149 6936/6886/4149 6629/6612/4149 +f 6937/6887/4149 6629/6612/4149 6628/6611/4149 +f 6609/6598/4149 6608/6597/4149 6939/6890/4149 +f 6609/6598/4149 6939/6890/4149 6903/6854/4149 +f 6608/6597/4149 6607/6596/4149 6896/6847/4149 +f 6608/6597/4149 6896/6847/4149 6939/6890/4149 +f 6939/6890/4149 6896/6847/4149 6900/6851/4149 +f 6939/6890/4149 6900/6851/4149 6940/6891/4149 +f 6903/6854/4149 6939/6890/4149 6940/6891/4149 +f 6903/6854/4149 6940/6891/4149 6904/6855/4149 +f 6579/6568/4149 6578/6567/4149 6941/6892/4149 +f 6579/6568/4149 6941/6892/4149 6909/6860/4149 +f 6578/6567/4149 6577/6566/4149 6902/6853/4149 +f 6578/6567/4149 6902/6853/4149 6941/6892/4149 +f 6941/6892/4149 6902/6853/4149 6906/6857/4149 +f 6941/6892/4149 6906/6857/4149 6942/6893/4149 +f 6909/6860/4149 6941/6892/4149 6942/6893/4149 +f 6909/6860/4149 6942/6893/4149 6910/6861/4149 +f 6676/6649/4149 6918/6869/4149 6943/6894/4149 +f 6676/6649/4149 6943/6894/4149 6944/6895/4149 +f 6918/6869/4149 6917/6868/4149 6945/6896/4149 +f 6918/6869/4149 6945/6896/4149 6943/6894/4149 +f 6943/6894/4149 6945/6896/4149 6930/6880/4149 +f 6943/6894/4149 6930/6880/4149 6928/6878/4149 +f 6944/6895/4149 6943/6894/4149 6928/6878/4149 +f 6944/6895/4149 6928/6878/4149 6755/6722/4149 +f 6820/6779/4149 6819/6778/4149 6946/6897/4149 +f 6820/6779/4149 6946/6897/4149 6947/6898/4149 +f 6819/6778/4149 6948/6899/4169 6946/6897/4149 +f 6946/6897/4149 6792/6900/4169 6789/6754/4149 +f 6947/6898/4149 6946/6897/4149 6789/6754/4149 +f 6947/6898/4149 6789/6754/4149 6788/6753/4149 +f 6775/6742/4149 6774/6741/4149 6949/6901/4149 +f 6775/6742/4149 6949/6901/4149 6950/6902/4149 +f 6774/6741/4149 6678/6651/4149 6951/6903/4149 +f 6774/6741/4149 6951/6903/4149 6949/6901/4149 +f 6949/6901/4149 6951/6903/4149 6751/6718/4149 +f 6949/6901/4149 6751/6718/4149 6761/6728/4149 +f 6950/6902/4149 6949/6901/4149 6761/6728/4149 +f 6950/6902/4149 6761/6728/4149 6760/6727/4149 +f 6678/6651/4149 6677/6650/4149 6952/6904/4149 +f 6678/6651/4149 6952/6904/4149 6951/6903/4149 +f 6677/6650/4149 6676/6649/4149 6944/6895/4149 +f 6677/6650/4149 6944/6895/4149 6952/6904/4149 +f 6952/6904/4149 6944/6895/4149 6755/6722/4149 +f 6952/6904/4149 6755/6722/4149 6752/6719/4149 +f 6951/6903/4149 6952/6904/4149 6752/6719/4149 +f 6951/6903/4149 6752/6719/4149 6751/6718/4149 +f 6670/6643/4149 6738/6710/4149 6953/6905/4149 +f 6670/6643/4149 6953/6905/4149 6954/6906/4149 +f 6738/6710/4149 6737/6709/4149 6955/6907/4149 +f 6738/6710/4149 6955/6907/4149 6953/6905/4149 +f 6953/6905/4149 6955/6907/4149 6956/6908/4149 +f 6953/6905/4149 6956/6908/4149 6957/6909/4149 +f 6954/6906/4149 6953/6905/4149 6957/6909/4149 +f 6954/6906/4149 6957/6909/4149 6958/6910/4149 +f 6663/6636/4149 6662/6635/4149 6959/6911/4149 +f 6663/6636/4149 6959/6911/4149 6960/6912/4149 +f 6662/6635/4149 6961/6913/4178 6959/6911/4149 +f 6959/6911/4149 6743/6914/4160 6740/6712/4149 +f 6960/6912/4149 6959/6911/4149 6740/6712/4149 +f 6960/6912/4149 6740/6712/4149 6739/6711/4149 +f 6717/6690/4149 6716/6689/4149 6962/6915/4149 +f 6717/6690/4149 6962/6915/4149 6763/6730/4149 +f 6716/6689/4149 6672/6645/4149 6963/6916/4149 +f 6716/6689/4149 6963/6916/4149 6962/6915/4149 +f 6962/6915/4149 6963/6916/4149 6964/6917/4149 +f 6962/6915/4149 6964/6917/4149 6965/6918/4149 +f 6763/6730/4149 6962/6915/4149 6965/6918/4149 +f 6763/6730/4149 6965/6918/4149 6760/6727/4149 +f 6672/6645/4149 6671/6644/4149 6966/6919/4149 +f 6672/6645/4149 6966/6919/4149 6963/6916/4149 +f 6671/6644/4149 6670/6643/4149 6954/6906/4149 +f 6671/6644/4149 6954/6906/4149 6966/6919/4149 +f 6966/6919/4149 6954/6906/4149 6958/6910/4149 +f 6966/6919/4149 6958/6910/4149 6967/6920/4149 +f 6963/6916/4149 6966/6919/4149 6967/6920/4149 +f 6963/6916/4149 6967/6920/4149 6964/6917/4149 +f 6786/6751/4149 6927/6877/4149 6968/6921/4149 +f 6786/6751/4149 6968/6921/4149 6969/6922/4149 +f 6927/6877/4149 6926/6876/4149 6970/6923/4149 +f 6927/6877/4149 6970/6923/4149 6968/6921/4149 +f 6968/6921/4149 6970/6923/4149 6971/6924/4149 +f 6968/6921/4149 6971/6924/4149 6972/6925/4149 +f 6969/6922/4149 6968/6921/4149 6972/6925/4149 +f 6969/6922/4149 6972/6925/4149 6973/6926/4149 +f 6805/6768/4149 6804/6767/4149 6974/6927/4149 +f 6805/6768/4149 6974/6927/4149 6975/6928/4149 +f 6804/6767/4149 6976/6929/4179 6974/6927/4149 +f 6974/6927/4149 6810/6930/4180 6807/6770/4149 +f 6975/6928/4149 6974/6927/4149 6807/6770/4149 +f 6975/6928/4149 6807/6770/4149 6806/6769/4149 +f 6711/6684/4149 6771/6738/4149 6977/6931/4149 +f 6711/6684/4149 6977/6931/4149 6709/6682/4149 +f 6771/6738/4149 6770/6737/4149 6978/6932/4149 +f 6771/6738/4149 6978/6932/4149 6977/6931/4149 +f 6977/6931/4149 6978/6932/4149 6979/6933/4149 +f 6977/6931/4149 6979/6933/4149 6980/6934/4149 +f 6709/6682/4149 6977/6931/4149 6980/6934/4149 +f 6709/6682/4149 6980/6934/4149 6706/6679/4149 +f 6981/6935/4181 6982/6936/4182 6983/6937/4149 +f 6981/6935/4181 6983/6937/4149 6984/6938/4149 +f 6982/6936/4182 6985/6939/4183 6986/6940/4149 +f 6982/6936/4182 6986/6940/4149 6983/6937/4149 +f 6983/6937/4149 6986/6940/4149 6718/6691/4149 +f 6983/6937/4149 6718/6691/4149 6987/6941/4149 +f 6984/6938/4149 6983/6937/4149 6987/6941/4149 +f 6984/6938/4149 6987/6941/4149 6988/6942/4149 +f 6985/6939/4183 6989/6943/4184 6990/6944/4149 +f 6985/6939/4183 6990/6944/4149 6986/6940/4149 +f 6989/6943/4184 6992/6945/4185 6990/6944/4149 +f 6990/6944/4149 6722/6946/4186 6719/6692/4149 +f 6986/6940/4149 6990/6944/4149 6719/6692/4149 +f 6986/6940/4149 6719/6692/4149 6718/6691/4149 +f 6781/6947/4187 6993/6948/4188 6994/6949/4149 +f 6781/6947/4189 6994/6949/4149 6779/6746/4149 +f 6993/6948/4188 6995/6950/4190 6996/6951/4149 +f 6993/6948/4188 6996/6951/4149 6994/6949/4149 +f 6994/6949/4149 6996/6951/4149 6997/6952/4149 +f 6994/6949/4149 6997/6952/4149 6998/6953/4149 +f 6779/6746/4149 6994/6949/4149 6998/6953/4149 +f 6779/6746/4149 6998/6953/4149 6776/6743/4149 +f 6995/6950/4190 6999/6954/4191 7000/6955/4149 +f 6995/6950/4190 7000/6955/4149 6996/6951/4149 +f 6999/6954/4191 6981/6935/4181 6984/6938/4149 +f 6999/6954/4191 6984/6938/4149 7000/6955/4149 +f 7000/6955/4149 6984/6938/4149 6988/6942/4149 +f 7000/6955/4149 6988/6942/4149 7001/6956/4149 +f 6996/6951/4149 7000/6955/4149 7001/6956/4149 +f 6996/6951/4149 7001/6956/4149 6997/6952/4149 +f 6770/6737/4149 6787/6752/4149 7002/6957/4149 +f 6770/6737/4149 7002/6957/4149 6978/6932/4149 +f 6787/6752/4149 6786/6751/4149 6969/6922/4149 +f 6787/6752/4149 6969/6922/4149 7002/6957/4149 +f 7002/6957/4149 6969/6922/4149 6973/6926/4149 +f 7002/6957/4149 6973/6926/4149 7003/6958/4149 +f 6978/6932/4149 7002/6957/4149 7003/6958/4149 +f 6978/6932/4149 7003/6958/4149 6979/6933/4149 +f 6757/6724/4149 6933/6883/4149 7004/6959/4149 +f 6757/6724/4149 7004/6959/4149 7005/6960/4149 +f 6933/6883/4149 6932/6882/4149 7006/6961/4149 +f 6933/6883/4149 7006/6961/4149 7004/6959/4149 +f 7004/6959/4149 7006/6961/4149 6924/6874/4149 +f 7004/6959/4149 6924/6874/4149 6922/6872/4149 +f 7005/6960/4149 7004/6959/4149 6922/6872/4149 +f 7005/6960/4149 6922/6872/4149 6784/6749/4149 +f 6796/6760/4149 6795/6759/4149 7007/6962/4149 +f 6796/6760/4149 7007/6962/4149 7008/6963/4149 +f 6795/6759/4149 7009/6964/4164 7007/6962/4149 +f 7007/6962/4149 6801/6965/4192 6798/6762/4149 +f 7008/6963/4149 7007/6962/4149 6798/6762/4149 +f 7008/6963/4149 6798/6762/4149 6797/6761/4149 +f 6759/6726/4149 6758/6725/4149 7010/6966/4149 +f 6759/6726/4149 7010/6966/4149 7011/6967/4149 +f 6758/6725/4149 6757/6724/4149 7005/6960/4149 +f 6758/6725/4149 7005/6960/4149 7010/6966/4149 +f 7010/6966/4149 7005/6960/4149 6784/6749/4149 +f 7010/6966/4149 6784/6749/4149 6782/6747/4149 +f 7011/6967/4149 7010/6966/4149 6782/6747/4149 +f 7011/6967/4149 6782/6747/4149 6768/6735/4149 +f 6717/6690/4149 6764/6731/4149 7012/6968/4149 +f 6717/6690/4149 7012/6968/4149 6715/6688/4149 +f 6764/6731/4149 6759/6726/4149 7011/6967/4149 +f 6764/6731/4149 7011/6967/4149 7012/6968/4149 +f 7012/6968/4149 7011/6967/4149 6768/6735/4149 +f 7012/6968/4149 6768/6735/4149 6765/6732/4149 +f 6715/6688/4149 7012/6968/4149 6765/6732/4149 +f 6715/6688/4149 6765/6732/4149 6712/6685/4149 +f 6703/6676/4149 6732/6704/4149 7013/6969/4149 +f 6703/6676/4149 7013/6969/4149 7014/6970/4149 +f 6732/6704/4149 6731/6703/4149 7015/6971/4149 +f 6732/6704/4149 7015/6971/4149 7013/6969/4149 +f 7013/6969/4149 7015/6971/4149 6735/6707/4149 +f 7013/6969/4149 6735/6707/4149 6733/6705/4149 +f 7014/6970/4149 7013/6969/4149 6733/6705/4149 +f 7014/6970/4149 6733/6705/4149 6668/6641/4149 +f 6711/6684/4149 6710/6683/4149 7016/6972/4149 +f 6711/6684/4149 7016/6972/4149 6767/6734/4149 +f 6710/6683/4149 6705/6678/4149 7017/6973/4149 +f 6710/6683/4149 7017/6973/4149 7016/6972/4149 +f 7016/6972/4149 7017/6973/4149 6664/6637/4149 +f 7016/6972/4149 6664/6637/4149 6713/6686/4149 +f 6767/6734/4149 7016/6972/4149 6713/6686/4149 +f 6767/6734/4149 6713/6686/4149 6712/6685/4149 +f 6705/6678/4149 6704/6677/4149 7018/6974/4149 +f 6705/6678/4149 7018/6974/4149 7017/6973/4149 +f 6704/6677/4149 6703/6676/4149 7014/6970/4149 +f 6704/6677/4149 7014/6970/4149 7018/6974/4149 +f 7018/6974/4149 7014/6970/4149 6668/6641/4149 +f 7018/6974/4149 6668/6641/4149 6665/6638/4149 +f 7017/6973/4149 7018/6974/4149 6665/6638/4149 +f 7017/6973/4149 6665/6638/4149 6664/6637/4149 +f 6726/6698/4149 6725/6697/4149 7019/6975/4149 +f 6726/6698/4149 7019/6975/4149 7020/6976/4149 +f 6725/6697/4149 6724/6696/4186 7021/6977/4149 +f 6725/6697/4149 7021/6977/4193 7019/6975/4149 +f 7019/6975/4149 7021/6977/4193 6659/6632/4194 +f 7019/6975/4149 6659/6632/4149 6656/6629/4149 +f 7020/6976/4149 7019/6975/4149 6656/6629/4149 +f 7020/6976/4149 6656/6629/4149 6655/6628/4149 +f 7022/6978/4195 7023/6979/4195 7024/6980/4195 +f 7022/6978/4195 7024/6980/4195 7025/6981/4195 +f 7023/6979/4195 7026/6982/4195 7027/6983/4195 +f 7023/6979/4195 7027/6983/4195 7024/6980/4195 +f 7031/6984/4195 7032/6985/4195 7033/6986/4195 +f 7031/6984/4195 7033/6986/4195 7034/6987/4195 +f 7032/6985/4195 7036/6988/4196 7033/6986/4195 +f 7033/6986/4195 7037/6989/4197 7038/6990/4195 +f 7034/6987/4195 7033/6986/4195 7038/6990/4195 +f 7034/6987/4195 7038/6990/4195 7039/6991/4195 +f 7040/6992/4195 7041/6993/4195 7042/6994/4195 +f 7040/6992/4195 7042/6994/4195 7043/6995/4195 +f 7041/6993/4195 7044/6996/4195 7045/6997/4195 +f 7041/6993/4195 7045/6997/4195 7042/6994/4195 +f 7042/6994/4195 7045/6997/4195 7046/6998/4195 +f 7042/6994/4195 7046/6998/4195 7047/6999/4195 +f 7043/6995/4195 7042/6994/4195 7047/6999/4195 +f 7043/6995/4195 7047/6999/4195 7048/7000/4195 +f 7049/7001/4195 7050/7002/4195 7051/7003/4195 +f 7049/7001/4195 7051/7003/4195 7052/7004/4195 +f 7050/7002/4195 7053/7005/4195 7054/7006/4195 +f 7050/7002/4195 7054/7006/4195 7051/7003/4195 +f 7051/7003/4195 7054/7006/4195 7055/7007/4195 +f 7051/7003/4195 7055/7007/4195 7056/7008/4195 +f 7052/7004/4195 7051/7003/4195 7056/7008/4195 +f 7052/7004/4195 7056/7008/4195 7057/7009/4195 +f 7058/7010/4195 7059/7011/4195 7060/7012/4195 +f 7058/7010/4195 7060/7012/4195 7061/7013/4195 +f 7059/7011/4195 7062/7014/4195 7063/7015/4195 +f 7059/7011/4195 7063/7015/4195 7060/7012/4195 +f 7067/7016/4195 7068/7017/4195 7069/7018/4195 +f 7067/7016/4195 7069/7018/4195 7070/7019/4195 +f 7068/7017/4195 7058/7010/4195 7061/7013/4195 +f 7068/7017/4195 7061/7013/4195 7069/7018/4195 +f 7069/7018/4195 7066/7020/4198 7071/7021/4195 +f 7070/7019/4195 7069/7018/4195 7071/7021/4195 +f 7070/7019/4195 7071/7021/4195 7072/7022/4195 +f 7072/7022/4195 7071/7021/4195 7073/7023/4195 +f 7072/7022/4195 7073/7023/4195 7074/7024/4195 +f 7071/7021/4195 7066/7020/4199 7075/7025/4200 +f 7071/7021/4195 7075/7025/4195 7073/7023/4195 +f 7073/7023/4195 7075/7025/4195 7076/7026/4195 +f 7073/7023/4195 7076/7026/4195 7077/7027/4195 +f 7074/7024/4195 7073/7023/4195 7077/7027/4195 +f 7074/7024/4195 7077/7027/4195 7078/7028/4195 +f 7079/7029/4195 7080/7030/4195 7081/7031/4195 +f 7079/7029/4195 7081/7031/4195 7082/7032/4195 +f 7080/7030/4195 7083/7033/4195 7084/7034/4195 +f 7080/7030/4195 7084/7034/4195 7081/7031/4195 +f 7081/7031/4195 7084/7034/4195 7085/7035/4195 +f 7081/7031/4195 7085/7035/4195 7086/7036/4195 +f 7082/7032/4195 7081/7031/4195 7086/7036/4195 +f 7082/7032/4195 7086/7036/4195 7087/7037/4195 +f 7088/7038/4195 7089/7039/4195 7090/7040/4195 +f 7088/7038/4195 7090/7040/4195 7091/7041/4195 +f 7089/7039/4195 7079/7029/4195 7082/7032/4195 +f 7089/7039/4195 7082/7032/4195 7090/7040/4195 +f 7090/7040/4195 7082/7032/4195 7087/7037/4195 +f 7090/7040/4195 7087/7037/4195 7092/7042/4195 +f 7091/7041/4195 7090/7040/4195 7092/7042/4195 +f 7091/7041/4195 7092/7042/4195 7093/7043/4195 +f 7094/7044/4195 7095/7045/4195 7096/7046/4195 +f 7094/7044/4195 7096/7046/4195 7097/7047/4195 +f 7095/7045/4195 7040/6992/4195 7043/6995/4195 +f 7095/7045/4195 7043/6995/4195 7096/7046/4195 +f 7096/7046/4195 7043/6995/4195 7048/7000/4195 +f 7096/7046/4195 7048/7000/4195 7098/7048/4195 +f 7097/7047/4195 7096/7046/4195 7098/7048/4195 +f 7097/7047/4195 7098/7048/4195 7099/7049/4195 +f 7100/7050/4195 7101/7051/4195 7102/7052/4195 +f 7100/7050/4195 7102/7052/4195 7103/7053/4195 +f 7101/7051/4195 7105/7054/4201 7102/7052/4195 +f 7102/7052/4195 7106/7055/4202 7107/7056/4195 +f 7103/7053/4195 7102/7052/4195 7107/7056/4195 +f 7103/7053/4195 7107/7056/4195 7108/7057/4195 +f 7083/7033/4195 7109/7058/4195 7110/7059/4195 +f 7083/7033/4195 7110/7059/4195 7084/7034/4195 +f 7109/7058/4195 7111/7060/4195 7112/7061/4195 +f 7109/7058/4195 7112/7061/4195 7110/7059/4195 +f 7110/7059/4195 7112/7061/4195 7113/7062/4195 +f 7110/7059/4195 7113/7062/4195 7114/7063/4195 +f 7084/7034/4195 7110/7059/4195 7114/7063/4195 +f 7084/7034/4195 7114/7063/4195 7085/7035/4195 +f 7044/6996/4195 7115/7064/4195 7116/7065/4195 +f 7044/6996/4195 7116/7065/4195 7045/6997/4195 +f 7115/7064/4195 7117/7066/4195 7118/7067/4195 +f 7115/7064/4195 7118/7067/4195 7116/7065/4195 +f 7116/7065/4195 7118/7067/4195 7119/7068/4195 +f 7116/7065/4195 7119/7068/4195 7120/7069/4195 +f 7045/6997/4195 7116/7065/4195 7120/7069/4195 +f 7045/6997/4195 7120/7069/4195 7046/6998/4195 +f 7062/7014/4195 7130/7070/4195 7131/7071/4195 +f 7062/7014/4195 7131/7071/4195 7063/7015/4195 +f 7130/7070/4195 7132/7072/4195 7133/7073/4195 +f 7130/7070/4195 7133/7073/4195 7131/7071/4195 +f 7136/7074/4195 7137/7075/4195 7138/7076/4195 +f 7136/7074/4195 7138/7076/4195 7139/7077/4195 +f 7137/7075/4195 7140/7078/4195 7141/7079/4195 +f 7137/7075/4195 7141/7079/4195 7138/7076/4195 +f 7138/7076/4195 7141/7079/4195 7142/7080/4195 +f 7138/7076/4195 7142/7080/4195 7143/7081/4195 +f 7139/7077/4195 7138/7076/4195 7143/7081/4195 +f 7139/7077/4195 7143/7081/4195 7144/7082/4195 +f 7145/7083/4195 7146/7084/4195 7147/7085/4195 +f 7145/7083/4195 7147/7085/4195 7148/7086/4195 +f 7146/7084/4195 7136/7074/4195 7139/7077/4195 +f 7146/7084/4195 7139/7077/4195 7147/7085/4195 +f 7147/7085/4195 7139/7077/4195 7144/7082/4195 +f 7147/7085/4195 7144/7082/4195 7149/7087/4195 +f 7148/7086/4195 7147/7085/4195 7149/7087/4195 +f 7148/7086/4195 7149/7087/4195 7099/7049/4195 +f 7094/7044/4195 7150/7088/4195 7151/7089/4195 +f 7094/7044/4195 7151/7089/4195 7152/7090/4195 +f 7150/7088/4195 7153/7091/4195 7154/7092/4195 +f 7150/7088/4195 7154/7092/4195 7151/7089/4195 +f 7151/7089/4195 7154/7092/4195 7155/7093/4195 +f 7151/7089/4195 7155/7093/4195 7156/7094/4195 +f 7152/7090/4195 7151/7089/4195 7156/7094/4195 +f 7152/7090/4195 7156/7094/4195 7093/7043/4195 +f 7157/7095/4195 7158/7096/4195 7159/7097/4195 +f 7157/7095/4195 7159/7097/4195 7160/7098/4195 +f 7158/7096/4195 7049/7001/4195 7052/7004/4195 +f 7158/7096/4195 7052/7004/4195 7159/7097/4195 +f 7159/7097/4195 7052/7004/4195 7057/7009/4195 +f 7159/7097/4195 7057/7009/4195 7161/7099/4195 +f 7160/7098/4195 7159/7097/4195 7161/7099/4195 +f 7160/7098/4195 7161/7099/4195 7162/7100/4195 +f 7163/7101/4195 7164/7102/4195 7165/7103/4195 +f 7163/7101/4195 7165/7103/4195 7166/7104/4195 +f 7164/7102/4195 7022/6978/4195 7025/6981/4195 +f 7164/7102/4195 7025/6981/4195 7165/7103/4195 +f 7153/7091/4195 7169/7105/4195 7170/7106/4195 +f 7153/7091/4195 7170/7106/4195 7154/7092/4195 +f 7169/7105/4195 7171/7107/4195 7172/7108/4195 +f 7169/7105/4195 7172/7108/4195 7170/7106/4195 +f 7170/7106/4195 7172/7108/4195 7173/7109/4195 +f 7170/7106/4195 7173/7109/4195 7174/7110/4195 +f 7154/7092/4195 7170/7106/4195 7174/7110/4195 +f 7154/7092/4195 7174/7110/4195 7155/7093/4195 +f 7175/7111/4195 7176/7112/4195 7177/7113/4195 +f 7175/7111/4195 7177/7113/4195 7178/7114/4195 +f 7176/7112/4195 7180/7115/4203 7177/7113/4195 +f 7177/7113/4195 7181/7116/4204 7182/7117/4195 +f 7178/7114/4195 7177/7113/4195 7182/7117/4195 +f 7178/7114/4195 7182/7117/4195 7183/7118/4195 +f 7184/7119/4195 7185/7120/4195 7186/7121/4195 +f 7184/7119/4195 7186/7121/4195 7187/7122/4195 +f 7185/7120/4195 7189/7123/4205 7186/7121/4195 +f 7186/7121/4195 7190/7124/4206 7191/7125/4195 +f 7187/7122/4195 7186/7121/4195 7191/7125/4195 +f 7187/7122/4195 7191/7125/4195 7192/7126/4195 +f 7202/7127/4195 7203/7128/4195 7204/7129/4195 +f 7202/7127/4195 7204/7129/4195 7205/7130/4195 +f 7203/7128/4195 7207/7131/4207 7204/7129/4195 +f 7204/7129/4195 7208/7132/4207 7209/7133/4195 +f 7205/7130/4195 7204/7129/4195 7209/7133/4195 +f 7205/7130/4195 7209/7133/4195 7210/7134/4195 +f 7211/7135/4195 7212/7136/4195 7213/7137/4195 +f 7211/7135/4195 7213/7137/4195 7214/7138/4195 +f 7212/7136/4195 7216/7139/4208 7213/7137/4195 +f 7213/7137/4195 7217/7140/4209 7218/7141/4195 +f 7214/7138/4195 7213/7137/4195 7218/7141/4195 +f 7214/7138/4195 7218/7141/4195 7219/7142/4195 +f 7220/7143/4195 7221/7144/4195 7222/7145/4195 +f 7220/7143/4195 7222/7145/4195 7223/7146/4195 +f 7221/7144/4195 7224/7147/4195 7225/7148/4195 +f 7221/7144/4195 7225/7148/4195 7222/7145/4195 +f 7222/7145/4195 7226/7149/4210 7227/7150/4211 +f 7223/7146/4195 7222/7145/4195 7227/7150/4195 +f 7223/7146/4195 7227/7150/4195 7228/7151/4195 +f 7229/7152/4195 7230/7153/4195 7231/7154/4195 +f 7229/7152/4195 7231/7154/4195 7232/7155/4195 +f 7230/7153/4195 7233/7156/4195 7234/7157/4195 +f 7230/7153/4195 7234/7157/4195 7231/7154/4195 +f 7231/7154/4195 7234/7157/4195 7235/7158/4195 +f 7231/7154/4195 7235/7158/4195 7236/7159/4195 +f 7232/7155/4195 7231/7154/4195 7236/7159/4195 +f 7232/7155/4195 7236/7159/4195 7237/7160/4195 +f 7049/7001/4195 7238/7161/4195 7239/7162/4195 +f 7049/7001/4195 7239/7162/4195 7050/7002/4195 +f 7238/7161/4195 7240/7163/4195 7241/7164/4195 +f 7238/7161/4195 7241/7164/4195 7239/7162/4195 +f 7239/7162/4195 7241/7164/4195 7242/7165/4195 +f 7239/7162/4195 7242/7165/4195 7243/7166/4195 +f 7050/7002/4195 7239/7162/4195 7243/7166/4195 +f 7050/7002/4195 7243/7166/4195 7053/7005/4195 +f 7244/7167/4195 7245/7168/4195 7246/7169/4195 +f 7244/7167/4195 7246/7169/4195 7247/7170/4195 +f 7245/7168/4195 7248/7171/4195 7249/7172/4195 +f 7245/7168/4195 7249/7172/4195 7246/7169/4195 +f 7246/7169/4195 7250/7173/4212 7251/7174/4195 +f 7247/7170/4195 7246/7169/4195 7251/7174/4195 +f 7247/7170/4195 7251/7174/4195 7252/7175/4195 +f 7253/7176/4195 7254/7177/4195 7255/7178/4195 +f 7253/7176/4195 7255/7178/4195 7256/7179/4195 +f 7254/7177/4195 7257/7180/4195 7258/7181/4195 +f 7254/7177/4195 7258/7181/4195 7255/7178/4195 +f 7255/7178/4195 7258/7181/4195 7248/7171/4195 +f 7255/7178/4195 7248/7171/4195 7245/7168/4195 +f 7256/7179/4195 7255/7178/4195 7245/7168/4195 +f 7256/7179/4195 7245/7168/4195 7244/7167/4195 +f 7257/7180/4195 7259/7182/4195 7260/7183/4195 +f 7257/7180/4195 7260/7183/4195 7258/7181/4195 +f 7259/7182/4195 7078/7028/4195 7077/7027/4195 +f 7259/7182/4195 7077/7027/4195 7260/7183/4195 +f 7260/7183/4195 7077/7027/4195 7076/7026/4195 +f 7260/7183/4195 7076/7026/4195 7261/7184/4195 +f 7258/7181/4195 7260/7183/4195 7261/7184/4195 +f 7258/7181/4195 7261/7184/4195 7248/7171/4195 +f 7262/7185/4195 7263/7186/4195 7264/7187/4195 +f 7262/7185/4195 7264/7187/4195 7265/7188/4195 +f 7263/7186/4195 7266/7189/4195 7267/7190/4195 +f 7263/7186/4195 7267/7190/4195 7264/7187/4195 +f 7264/7187/4195 7267/7190/4195 7268/7191/4195 +f 7264/7187/4195 7268/7191/4195 7269/7192/4195 +f 7265/7188/4195 7264/7187/4195 7269/7192/4195 +f 7265/7188/4195 7269/7192/4195 7270/7193/4195 +f 7271/7194/4195 7272/7195/4195 7273/7196/4195 +f 7271/7194/4195 7273/7196/4195 7274/7197/4195 +f 7272/7195/4195 7275/7198/4195 7276/7199/4195 +f 7272/7195/4195 7276/7199/4195 7273/7196/4195 +f 7273/7196/4195 7276/7199/4195 7266/7189/4195 +f 7273/7196/4195 7266/7189/4195 7263/7186/4195 +f 7274/7197/4195 7273/7196/4195 7263/7186/4195 +f 7274/7197/4195 7263/7186/4195 7262/7185/4195 +f 7277/7200/4195 7278/7201/4195 7279/7202/4195 +f 7277/7200/4195 7279/7202/4195 7280/7203/4195 +f 7278/7201/4195 7281/7204/4195 7282/7205/4195 +f 7278/7201/4195 7282/7205/4195 7279/7202/4195 +f 7279/7202/4195 7282/7205/4195 7233/7156/4195 +f 7279/7202/4195 7233/7156/4195 7230/7153/4195 +f 7280/7203/4195 7279/7202/4195 7230/7153/4195 +f 7280/7203/4195 7230/7153/4195 7229/7152/4195 +f 7283/7206/4195 7284/7207/4195 7285/7208/4195 +f 7283/7206/4195 7285/7208/4195 7286/7209/4195 +f 7284/7207/4195 7287/7210/4195 7288/7211/4195 +f 7284/7207/4195 7288/7211/4195 7285/7208/4195 +f 7270/7193/4195 7269/7192/4195 7292/7212/4195 +f 7270/7193/4195 7292/7212/4195 7293/7213/4195 +f 7269/7192/4195 7268/7191/4195 7294/7214/4195 +f 7269/7192/4195 7294/7214/4195 7292/7212/4195 +f 7292/7212/4195 7294/7214/4195 7295/7215/4195 +f 7292/7212/4195 7295/7215/4195 7296/7216/4195 +f 7293/7213/4195 7292/7212/4195 7296/7216/4195 +f 7293/7213/4195 7296/7216/4195 7297/7217/4195 +f 7237/7160/4195 7236/7159/4195 7298/7218/4195 +f 7237/7160/4195 7298/7218/4195 7299/7219/4195 +f 7236/7159/4195 7235/7158/4195 7300/7220/4195 +f 7236/7159/4195 7300/7220/4195 7298/7218/4195 +f 7298/7218/4195 7300/7220/4195 7301/7221/4195 +f 7298/7218/4195 7301/7221/4195 7302/7222/4195 +f 7299/7219/4195 7298/7218/4195 7302/7222/4195 +f 7299/7219/4195 7302/7222/4195 7303/7223/4195 +f 7304/7224/4195 7305/7225/4195 7306/7226/4195 +f 7304/7224/4195 7306/7226/4195 7307/7227/4195 +f 7305/7225/4195 7309/7228/4213 7306/7226/4195 +f 7252/7175/4195 7251/7174/4195 7313/7229/4195 +f 7252/7175/4195 7313/7229/4195 7314/7230/4195 +f 7251/7174/4195 7315/7231/4214 7313/7229/4195 +f 7313/7229/4195 7308/7232/4215 7305/7225/4195 +f 7314/7230/4195 7313/7229/4195 7305/7225/4195 +f 7314/7230/4195 7305/7225/4195 7304/7224/4195 +f 7316/7233/4195 7317/7234/4195 7318/7235/4195 +f 7316/7233/4195 7318/7235/4195 7319/7236/4195 +f 7317/7234/4195 7320/7237/4195 7321/7238/4195 +f 7317/7234/4195 7321/7238/4195 7318/7235/4195 +f 7318/7235/4195 7321/7238/4195 7322/7239/4195 +f 7318/7235/4195 7322/7239/4195 7323/7240/4195 +f 7319/7236/4195 7318/7235/4195 7323/7240/4195 +f 7319/7236/4195 7323/7240/4195 7324/7241/4195 +f 7325/7242/4195 7326/7243/4195 7327/7244/4195 +f 7325/7242/4195 7327/7244/4195 7328/7245/4195 +f 7326/7243/4195 7281/7204/4195 7329/7246/4195 +f 7326/7243/4195 7329/7246/4195 7327/7244/4195 +f 7327/7244/4195 7329/7246/4195 7320/7237/4195 +f 7327/7244/4195 7320/7237/4195 7317/7234/4195 +f 7328/7245/4195 7327/7244/4195 7317/7234/4195 +f 7328/7245/4195 7317/7234/4195 7316/7233/4195 +f 7277/7200/4195 7330/7247/4195 7331/7248/4195 +f 7277/7200/4195 7331/7248/4195 7332/7249/4195 +f 7330/7247/4195 7275/7198/4195 7333/7250/4195 +f 7330/7247/4195 7333/7250/4195 7331/7248/4195 +f 7331/7248/4195 7333/7250/4195 7334/7251/4195 +f 7331/7248/4195 7334/7251/4195 7335/7252/4195 +f 7332/7249/4195 7331/7248/4195 7335/7252/4195 +f 7332/7249/4195 7335/7252/4195 7336/7253/4195 +f 7157/7095/4195 7337/7254/4195 7338/7255/4195 +f 7157/7095/4195 7338/7255/4195 7158/7096/4195 +f 7337/7254/4195 7339/7256/4195 7340/7257/4195 +f 7337/7254/4195 7340/7257/4195 7338/7255/4195 +f 7338/7255/4195 7340/7257/4195 7240/7163/4195 +f 7338/7255/4195 7240/7163/4195 7238/7161/4195 +f 7158/7096/4195 7338/7255/4195 7238/7161/4195 +f 7158/7096/4195 7238/7161/4195 7049/7001/4195 +f 7341/7258/4195 7342/7259/4195 7343/7260/4195 +f 7341/7258/4195 7343/7260/4195 7344/7261/4195 +f 7342/7259/4195 7346/7262/4216 7343/7260/4195 +f 7343/7260/4195 7215/7263/4217 7212/7136/4195 +f 7344/7261/4195 7343/7260/4195 7212/7136/4195 +f 7344/7261/4195 7212/7136/4195 7211/7135/4195 +f 7336/7253/4195 7335/7252/4195 7347/7264/4195 +f 7336/7253/4195 7347/7264/4195 7348/7265/4195 +f 7335/7252/4195 7334/7251/4195 7349/7266/4195 +f 7335/7252/4195 7349/7266/4195 7347/7264/4195 +f 7347/7264/4195 7349/7266/4195 7350/7267/4195 +f 7347/7264/4195 7350/7267/4195 7351/7268/4195 +f 7348/7265/4195 7347/7264/4195 7351/7268/4195 +f 7348/7265/4195 7351/7268/4195 7352/7269/4195 +f 7353/7270/4195 7354/7271/4195 7355/7272/4195 +f 7353/7270/4195 7355/7272/4195 7356/7273/4195 +f 7354/7271/4195 7357/7274/4195 7358/7275/4195 +f 7354/7271/4195 7358/7275/4195 7355/7272/4195 +f 7362/7276/4195 7363/7277/4195 7364/7278/4195 +f 7362/7276/4195 7364/7278/4195 7365/7279/4195 +f 7363/7277/4195 7366/7280/4195 7367/7281/4195 +f 7363/7277/4195 7367/7281/4195 7364/7278/4195 +f 7371/7282/4195 7372/7283/4195 7373/7284/4195 +f 7371/7282/4195 7373/7284/4195 7374/7285/4195 +f 7372/7283/4195 7376/7286/4218 7373/7284/4195 +f 7202/7127/4195 7380/7287/4195 7381/7288/4195 +f 7202/7127/4195 7381/7288/4195 7203/7128/4195 +f 7380/7287/4195 7382/7289/4195 7383/7290/4195 +f 7380/7287/4195 7383/7290/4195 7381/7288/4195 +f 7210/7134/4195 7209/7133/4195 7386/7291/4195 +f 7210/7134/4195 7386/7291/4195 7387/7292/4195 +f 7209/7133/4195 7388/7293/4219 7386/7291/4195 +f 7386/7291/4195 7179/7294/4219 7176/7112/4195 +f 7387/7292/4195 7386/7291/4195 7176/7112/4195 +f 7387/7292/4195 7176/7112/4195 7175/7111/4195 +f 7162/7100/4195 7161/7099/4195 7389/7295/4195 +f 7162/7100/4195 7389/7295/4195 7390/7296/4195 +f 7161/7099/4195 7057/7009/4195 7391/7297/4195 +f 7161/7099/4195 7391/7297/4195 7389/7295/4195 +f 7389/7295/4195 7391/7297/4195 7136/7074/4195 +f 7389/7295/4195 7136/7074/4195 7146/7084/4195 +f 7390/7296/4195 7389/7295/4195 7146/7084/4195 +f 7390/7296/4195 7146/7084/4195 7145/7083/4195 +f 7057/7009/4195 7056/7008/4195 7392/7298/4195 +f 7057/7009/4195 7392/7298/4195 7391/7297/4195 +f 7056/7008/4195 7055/7007/4195 7393/7299/4195 +f 7056/7008/4195 7393/7299/4195 7392/7298/4195 +f 7392/7298/4195 7393/7299/4195 7140/7078/4195 +f 7392/7298/4195 7140/7078/4195 7137/7075/4195 +f 7391/7297/4195 7392/7298/4195 7137/7075/4195 +f 7391/7297/4195 7137/7075/4195 7136/7074/4195 +f 7394/7300/4195 7395/7301/4195 7396/7302/4195 +f 7394/7300/4195 7396/7302/4195 7397/7303/4195 +f 7395/7301/4195 7398/7304/4195 7399/7305/4195 +f 7395/7301/4195 7399/7305/4195 7396/7302/4195 +f 7396/7302/4195 7399/7305/4195 7132/7072/4195 +f 7396/7302/4195 7132/7072/4195 7130/7070/4195 +f 7397/7303/4195 7396/7302/4195 7130/7070/4195 +f 7397/7303/4195 7130/7070/4195 7062/7014/4195 +f 7039/6991/4220 7400/7306/4221 7401/7307/4222 +f 7401/7307/4211 7122/7308/4223 7121/7309/4224 +f 7099/7049/4195 7098/7048/4195 7403/7310/4195 +f 7099/7049/4195 7403/7310/4195 7148/7086/4195 +f 7098/7048/4195 7048/7000/4195 7404/7311/4195 +f 7098/7048/4195 7404/7311/4195 7403/7310/4195 +f 7403/7310/4195 7404/7311/4195 7405/7312/4195 +f 7403/7310/4195 7405/7312/4195 7406/7313/4195 +f 7148/7086/4195 7403/7310/4195 7406/7313/4195 +f 7148/7086/4195 7406/7313/4195 7145/7083/4195 +f 7048/7000/4195 7047/6999/4195 7407/7314/4195 +f 7048/7000/4195 7407/7314/4195 7404/7311/4195 +f 7047/6999/4195 7046/6998/4195 7408/7315/4195 +f 7047/6999/4195 7408/7315/4195 7407/7314/4195 +f 7407/7314/4195 7408/7315/4195 7409/7316/4195 +f 7407/7314/4195 7409/7316/4195 7410/7317/4195 +f 7404/7311/4195 7407/7314/4195 7410/7317/4195 +f 7404/7311/4195 7410/7317/4195 7405/7312/4195 +f 7183/7118/4195 7182/7117/4195 7411/7318/4195 +f 7183/7118/4195 7411/7318/4195 7412/7319/4195 +f 7182/7117/4195 7413/7320/4204 7411/7318/4195 +f 7411/7318/4195 7188/7321/4225 7185/7120/4195 +f 7412/7319/4195 7411/7318/4195 7185/7120/4195 +f 7412/7319/4195 7185/7120/4195 7184/7119/4195 +f 7144/7082/4195 7143/7081/4195 7414/7322/4195 +f 7144/7082/4195 7414/7322/4195 7415/7323/4195 +f 7143/7081/4195 7142/7080/4195 7416/7324/4195 +f 7143/7081/4195 7416/7324/4195 7414/7322/4195 +f 7414/7322/4195 7416/7324/4195 7171/7107/4195 +f 7414/7322/4195 7171/7107/4195 7169/7105/4195 +f 7415/7323/4195 7414/7322/4195 7169/7105/4195 +f 7415/7323/4195 7169/7105/4195 7153/7091/4195 +f 7099/7049/4195 7149/7087/4195 7417/7325/4195 +f 7099/7049/4195 7417/7325/4195 7097/7047/4195 +f 7149/7087/4195 7144/7082/4195 7415/7323/4195 +f 7149/7087/4195 7415/7323/4195 7417/7325/4195 +f 7417/7325/4195 7415/7323/4195 7153/7091/4195 +f 7417/7325/4195 7153/7091/4195 7150/7088/4195 +f 7097/7047/4195 7417/7325/4195 7150/7088/4195 +f 7097/7047/4195 7150/7088/4195 7094/7044/4195 +f 7085/7035/4195 7114/7063/4195 7418/7326/4195 +f 7085/7035/4195 7418/7326/4195 7419/7327/4195 +f 7114/7063/4195 7113/7062/4195 7420/7328/4195 +f 7114/7063/4195 7420/7328/4195 7418/7326/4195 +f 7418/7326/4195 7420/7328/4195 7117/7066/4195 +f 7418/7326/4195 7117/7066/4195 7115/7064/4195 +f 7419/7327/4195 7418/7326/4195 7115/7064/4195 +f 7419/7327/4195 7115/7064/4195 7044/6996/4195 +f 7093/7043/4195 7092/7042/4195 7421/7329/4195 +f 7093/7043/4195 7421/7329/4195 7152/7090/4195 +f 7092/7042/4195 7087/7037/4195 7422/7330/4195 +f 7092/7042/4195 7422/7330/4195 7421/7329/4195 +f 7421/7329/4195 7422/7330/4195 7040/6992/4195 +f 7421/7329/4195 7040/6992/4195 7095/7045/4195 +f 7152/7090/4195 7421/7329/4195 7095/7045/4195 +f 7152/7090/4195 7095/7045/4195 7094/7044/4195 +f 7087/7037/4195 7086/7036/4195 7423/7331/4195 +f 7087/7037/4195 7423/7331/4195 7422/7330/4195 +f 7086/7036/4195 7085/7035/4195 7419/7327/4195 +f 7086/7036/4195 7419/7327/4195 7423/7331/4195 +f 7423/7331/4195 7419/7327/4195 7044/6996/4195 +f 7423/7331/4195 7044/6996/4195 7041/6993/4195 +f 7422/7330/4195 7423/7331/4195 7041/6993/4195 +f 7422/7330/4195 7041/6993/4195 7040/6992/4195 +f 7108/7057/4195 7107/7056/4195 7424/7332/4195 +f 7108/7057/4195 7424/7332/4195 7425/7333/4195 +f 7107/7056/4195 7426/7334/4226 7424/7332/4195 +f 7424/7332/4195 7035/7335/4227 7032/6985/4195 +f 7425/7333/4195 7424/7332/4195 7032/6985/4195 +f 7425/7333/4195 7032/6985/4195 7031/6984/4195 +f 7192/7126/4195 7191/7125/4195 7427/7336/4195 +f 7192/7126/4195 7427/7336/4195 7428/7337/4195 +f 7191/7125/4195 7429/7338/4228 7427/7336/4195 +f 7427/7336/4195 7430/7339/4229 7431/7340/4230 +f 7428/7337/4195 7427/7336/4195 7431/7340/4195 +f 7428/7337/4195 7431/7340/4195 7432/7341/4195 +f 7093/7043/4195 7156/7094/4195 7433/7342/4195 +f 7093/7043/4195 7433/7342/4195 7091/7041/4195 +f 7156/7094/4195 7155/7093/4195 7434/7343/4195 +f 7156/7094/4195 7434/7343/4195 7433/7342/4195 +f 7433/7342/4195 7434/7343/4195 7435/7344/4195 +f 7433/7342/4195 7435/7344/4195 7436/7345/4195 +f 7091/7041/4195 7433/7342/4195 7436/7345/4195 +f 7091/7041/4195 7436/7345/4195 7088/7038/4195 +f 7437/7346/4231 7438/7347/4232 7439/7348/4195 +f 7437/7346/4231 7439/7348/4195 7440/7349/4195 +f 7438/7347/4232 7441/7350/4233 7442/7351/4195 +f 7438/7347/4232 7442/7351/4195 7439/7348/4195 +f 7439/7348/4195 7442/7351/4195 7443/7352/4195 +f 7439/7348/4195 7443/7352/4195 7444/7353/4195 +f 7440/7349/4195 7439/7348/4195 7444/7353/4195 +f 7440/7349/4195 7444/7353/4195 7445/7354/4195 +f 7446/7355/4234 7447/7356/4235 7448/7357/4195 +f 7446/7355/4234 7448/7357/4195 7449/7358/4195 +f 7447/7356/4235 7451/7359/4236 7448/7357/4195 +f 7448/7357/4195 7104/7360/4237 7101/7051/4195 +f 7449/7358/4195 7448/7357/4195 7101/7051/4195 +f 7449/7358/4195 7101/7051/4195 7100/7050/4195 +f 7168/7361/4238 7452/7362/4238 7453/7363/4195 +f 7168/7361/4239 7453/7363/4195 7166/7104/4195 +f 7452/7362/4238 7454/7364/4240 7455/7365/4195 +f 7452/7362/4241 7455/7365/4195 7453/7363/4195 +f 7453/7363/4195 7455/7365/4195 7456/7366/4195 +f 7453/7363/4195 7456/7366/4195 7457/7367/4195 +f 7166/7104/4195 7453/7363/4195 7457/7367/4195 +f 7166/7104/4195 7457/7367/4195 7163/7101/4195 +f 7454/7364/4240 7458/7368/4242 7459/7369/4195 +f 7454/7364/4240 7459/7369/4195 7455/7365/4195 +f 7458/7368/4242 7437/7346/4231 7440/7349/4195 +f 7458/7368/4242 7440/7349/4195 7459/7369/4195 +f 7459/7369/4195 7440/7349/4195 7445/7354/4195 +f 7459/7369/4195 7445/7354/4195 7460/7370/4195 +f 7455/7365/4195 7459/7369/4195 7460/7370/4195 +f 7455/7365/4195 7460/7370/4195 7456/7366/4195 +f 7155/7093/4195 7174/7110/4195 7461/7371/4195 +f 7155/7093/4195 7461/7371/4195 7434/7343/4195 +f 7174/7110/4195 7173/7109/4195 7462/7372/4195 +f 7174/7110/4195 7462/7372/4195 7461/7371/4195 +f 7461/7371/4195 7462/7372/4195 7463/7373/4195 +f 7461/7371/4195 7463/7373/4195 7464/7374/4195 +f 7434/7343/4195 7461/7371/4195 7464/7374/4195 +f 7434/7343/4195 7464/7374/4195 7435/7344/4195 +f 7173/7109/4195 7465/7375/4195 7466/7376/4195 +f 7173/7109/4195 7466/7376/4195 7462/7372/4195 +f 7465/7375/4195 7467/7377/4195 7468/7378/4195 +f 7465/7375/4195 7468/7378/4195 7466/7376/4195 +f 7466/7376/4195 7193/7379/4243 7469/7380/4195 +f 7462/7372/4195 7466/7376/4195 7469/7380/4195 +f 7462/7372/4195 7469/7380/4195 7463/7373/4195 +f 7142/7080/4195 7470/7381/4195 7471/7382/4195 +f 7142/7080/4195 7471/7382/4195 7416/7324/4195 +f 7470/7381/4195 7472/7383/4195 7473/7384/4195 +f 7470/7381/4195 7473/7384/4195 7471/7382/4195 +f 7471/7382/4195 7473/7384/4195 7474/7385/4195 +f 7471/7382/4195 7474/7385/4195 7475/7386/4195 +f 7416/7324/4195 7471/7382/4195 7475/7386/4195 +f 7416/7324/4195 7475/7386/4195 7171/7107/4195 +f 7055/7007/4195 7476/7387/4195 7477/7388/4195 +f 7055/7007/4195 7477/7388/4195 7393/7299/4195 +f 7476/7387/4195 7478/7389/4195 7479/7390/4195 +f 7476/7387/4195 7479/7390/4195 7477/7388/4195 +f 7477/7388/4195 7479/7390/4195 7480/7391/4195 +f 7477/7388/4195 7480/7391/4195 7481/7392/4195 +f 7393/7299/4195 7477/7388/4195 7481/7392/4195 +f 7393/7299/4195 7481/7392/4195 7140/7078/4195 +f 7053/7005/4195 7243/7166/4195 7482/7393/4195 +f 7053/7005/4195 7482/7393/4195 7483/7394/4195 +f 7243/7166/4195 7242/7165/4195 7484/7395/4195 +f 7243/7166/4195 7484/7395/4195 7482/7393/4195 +f 7482/7393/4195 7484/7395/4195 7485/7396/4195 +f 7482/7393/4195 7485/7396/4195 7486/7397/4195 +f 7483/7394/4195 7482/7393/4195 7486/7397/4195 +f 7483/7394/4195 7486/7397/4195 7487/7398/4195 +f 7219/7142/4195 7218/7141/4195 7488/7399/4195 +f 7219/7142/4195 7488/7399/4195 7489/7400/4195 +f 7218/7141/4195 7490/7401/4244 7488/7399/4195 +f 7488/7399/4195 7375/7402/4245 7372/7283/4195 +f 7489/7400/4195 7488/7399/4195 7372/7283/4195 +f 7489/7400/4195 7372/7283/4195 7371/7282/4195 +f 7352/7269/4195 7351/7268/4195 7491/7403/4195 +f 7352/7269/4195 7491/7403/4195 7492/7404/4195 +f 7351/7268/4195 7350/7267/4195 7493/7405/4195 +f 7351/7268/4195 7493/7405/4195 7491/7403/4195 +f 7491/7403/4195 7493/7405/4195 7494/7406/4195 +f 7491/7403/4195 7494/7406/4195 7495/7407/4195 +f 7492/7404/4195 7491/7403/4195 7495/7407/4195 +f 7492/7404/4195 7495/7407/4195 7496/7408/4195 +f 7324/7241/4195 7323/7240/4195 7497/7409/4195 +f 7324/7241/4195 7497/7409/4195 7498/7410/4195 +f 7323/7240/4195 7322/7239/4195 7499/7411/4195 +f 7323/7240/4195 7499/7411/4195 7497/7409/4195 +f 7497/7409/4195 7499/7411/4195 7500/7412/4195 +f 7497/7409/4195 7500/7412/4195 7501/7413/4195 +f 7498/7410/4195 7497/7409/4195 7501/7413/4195 +f 7498/7410/4195 7501/7413/4195 7502/7414/4195 +f 7053/7005/4195 7483/7394/4195 7503/7415/4195 +f 7053/7005/4195 7503/7415/4195 7054/7006/4195 +f 7483/7394/4195 7487/7398/4195 7504/7416/4195 +f 7483/7394/4195 7504/7416/4195 7503/7415/4195 +f 7503/7415/4195 7504/7416/4195 7478/7389/4195 +f 7503/7415/4195 7478/7389/4195 7476/7387/4195 +f 7054/7006/4195 7503/7415/4195 7476/7387/4195 +f 7054/7006/4195 7476/7387/4195 7055/7007/4195 +f 7026/6982/4195 7505/7417/4195 7506/7418/4195 +f 7026/6982/4195 7506/7418/4195 7027/6983/4195 +f 7505/7417/4195 7507/7419/4195 7508/7420/4195 +f 7505/7417/4195 7508/7420/4195 7506/7418/4195 +f 7171/7107/4195 7475/7386/4195 7511/7421/4195 +f 7171/7107/4195 7511/7421/4195 7172/7108/4195 +f 7475/7386/4195 7474/7385/4195 7512/7422/4195 +f 7475/7386/4195 7512/7422/4195 7511/7421/4195 +f 7511/7421/4195 7512/7422/4195 7467/7377/4195 +f 7511/7421/4195 7467/7377/4195 7465/7375/4195 +f 7172/7108/4195 7511/7421/4195 7465/7375/4195 +f 7172/7108/4195 7465/7375/4195 7173/7109/4195 +f 7140/7078/4195 7481/7392/4195 7513/7423/4195 +f 7140/7078/4195 7513/7423/4195 7141/7079/4195 +f 7481/7392/4195 7480/7391/4195 7514/7424/4195 +f 7481/7392/4195 7514/7424/4195 7513/7423/4195 +f 7513/7423/4195 7514/7424/4195 7472/7383/4195 +f 7513/7423/4195 7472/7383/4195 7470/7381/4195 +f 7141/7079/4195 7513/7423/4195 7470/7381/4195 +f 7141/7079/4195 7470/7381/4195 7142/7080/4195 +f 7242/7165/4195 7515/7425/4195 7516/7426/4195 +f 7242/7165/4195 7516/7426/4195 7484/7395/4195 +f 7515/7425/4195 7324/7241/4195 7498/7410/4195 +f 7515/7425/4195 7498/7410/4195 7516/7426/4195 +f 7516/7426/4195 7498/7410/4195 7502/7414/4195 +f 7516/7426/4195 7502/7414/4195 7517/7427/4195 +f 7484/7395/4195 7516/7426/4195 7517/7427/4195 +f 7484/7395/4195 7517/7427/4195 7485/7396/4195 +f 7382/7289/4195 7518/7428/4195 7519/7429/4195 +f 7382/7289/4195 7519/7429/4195 7383/7290/4195 +f 7518/7428/4195 7353/7270/4195 7356/7273/4195 +f 7518/7428/4195 7356/7273/4195 7519/7429/4195 +f 7339/7256/4195 7521/7430/4195 7522/7431/4195 +f 7339/7256/4195 7522/7431/4195 7340/7257/4195 +f 7521/7430/4195 7325/7242/4195 7328/7245/4195 +f 7521/7430/4195 7328/7245/4195 7522/7431/4195 +f 7522/7431/4195 7328/7245/4195 7316/7233/4195 +f 7522/7431/4195 7316/7233/4195 7523/7432/4195 +f 7340/7257/4195 7522/7431/4195 7523/7432/4195 +f 7340/7257/4195 7523/7432/4195 7240/7163/4195 +f 7240/7163/4195 7523/7432/4195 7524/7433/4195 +f 7240/7163/4195 7524/7433/4195 7241/7164/4195 +f 7523/7432/4195 7316/7233/4195 7319/7236/4195 +f 7523/7432/4195 7319/7236/4195 7524/7433/4195 +f 7524/7433/4195 7319/7236/4195 7324/7241/4195 +f 7524/7433/4195 7324/7241/4195 7515/7425/4195 +f 7241/7164/4195 7524/7433/4195 7515/7425/4195 +f 7241/7164/4195 7515/7425/4195 7242/7165/4195 +f 7235/7158/4195 7525/7434/4195 7526/7435/4195 +f 7235/7158/4195 7526/7435/4195 7300/7220/4195 +f 7525/7434/4195 7527/7436/4195 7528/7437/4195 +f 7525/7434/4195 7528/7437/4195 7526/7435/4195 +f 7526/7435/4195 7528/7437/4195 7529/7438/4195 +f 7526/7435/4195 7529/7438/4195 7530/7439/4195 +f 7300/7220/4195 7526/7435/4195 7530/7439/4195 +f 7300/7220/4195 7530/7439/4195 7301/7221/4195 +f 7224/7147/4195 7531/7440/4195 7532/7441/4195 +f 7224/7147/4195 7532/7441/4195 7225/7148/4195 +f 7531/7440/4195 7304/7224/4195 7307/7227/4195 +f 7531/7440/4195 7307/7227/4195 7532/7441/4195 +f 7281/7204/4195 7326/7243/4195 7534/7442/4195 +f 7281/7204/4195 7534/7442/4195 7282/7205/4195 +f 7326/7243/4195 7325/7242/4195 7535/7443/4195 +f 7326/7243/4195 7535/7443/4195 7534/7442/4195 +f 7534/7442/4195 7535/7443/4195 7536/7444/4195 +f 7534/7442/4195 7536/7444/4195 7537/7445/4195 +f 7282/7205/4195 7534/7442/4195 7537/7445/4195 +f 7282/7205/4195 7537/7445/4195 7233/7156/4195 +f 7233/7156/4195 7537/7445/4195 7538/7446/4195 +f 7233/7156/4195 7538/7446/4195 7234/7157/4195 +f 7537/7445/4195 7536/7444/4195 7539/7447/4195 +f 7537/7445/4195 7539/7447/4195 7538/7446/4195 +f 7538/7446/4195 7539/7447/4195 7527/7436/4195 +f 7538/7446/4195 7527/7436/4195 7525/7434/4195 +f 7234/7157/4195 7538/7446/4195 7525/7434/4195 +f 7234/7157/4195 7525/7434/4195 7235/7158/4195 +f 7350/7267/4195 7540/7448/4195 7541/7449/4195 +f 7350/7267/4195 7541/7449/4195 7493/7405/4195 +f 7540/7448/4195 7542/7450/4195 7543/7451/4195 +f 7540/7448/4195 7543/7451/4195 7541/7449/4195 +f 7541/7449/4195 7543/7451/4195 7544/7452/4195 +f 7541/7449/4195 7544/7452/4195 7545/7453/4195 +f 7493/7405/4195 7541/7449/4195 7545/7453/4195 +f 7493/7405/4195 7545/7453/4195 7494/7406/4195 +f 7366/7280/4195 7546/7454/4195 7547/7455/4195 +f 7366/7280/4195 7547/7455/4195 7367/7281/4195 +f 7546/7454/4195 7371/7282/4195 7374/7285/4195 +f 7546/7454/4195 7374/7285/4195 7547/7455/4195 +f 7275/7198/4195 7272/7195/4195 7549/7456/4195 +f 7275/7198/4195 7549/7456/4195 7333/7250/4195 +f 7272/7195/4195 7271/7194/4195 7550/7457/4195 +f 7272/7195/4195 7550/7457/4195 7549/7456/4195 +f 7549/7456/4195 7550/7457/4195 7551/7458/4195 +f 7549/7456/4195 7551/7458/4195 7552/7459/4195 +f 7333/7250/4195 7549/7456/4195 7552/7459/4195 +f 7333/7250/4195 7552/7459/4195 7334/7251/4195 +f 7553/7460/4246 7554/7461/4195 7555/7462/4195 +f 7554/7461/4195 7557/7463/4195 7558/7464/4195 +f 7554/7461/4195 7558/7464/4195 7555/7462/4195 +f 7555/7462/4195 7558/7464/4195 7283/7206/4195 +f 7555/7462/4195 7283/7206/4195 7559/7465/4195 +f 7556/7466/4247 7555/7462/4195 7559/7465/4195 +f 7560/7467/4248 7559/7465/4195 7561/7468/4195 +f 7559/7465/4195 7283/7206/4195 7286/7209/4195 +f 7559/7465/4195 7286/7209/4195 7561/7468/4195 +f 7345/7469/4249 7342/7259/4195 7565/7470/4195 +f 7342/7259/4195 7341/7258/4195 7567/7471/4195 +f 7342/7259/4195 7567/7471/4195 7565/7470/4195 +f 7565/7470/4195 7567/7471/4195 7568/7472/4195 +f 7565/7470/4195 7568/7472/4195 7569/7473/4195 +f 7566/7474/4250 7565/7470/4195 7569/7473/4195 +f 7570/7475/4251 7569/7473/4195 7571/7476/4195 +f 7569/7473/4195 7568/7472/4195 7573/7477/4195 +f 7569/7473/4195 7573/7477/4195 7571/7476/4195 +f 7571/7476/4195 7573/7477/4195 7557/7463/4195 +f 7571/7476/4195 7557/7463/4195 7554/7461/4195 +f 7572/7478/4252 7571/7476/4195 7554/7461/4195 +f 7334/7251/4195 7552/7459/4195 7574/7479/4195 +f 7334/7251/4195 7574/7479/4195 7349/7266/4195 +f 7552/7459/4195 7551/7458/4195 7575/7480/4195 +f 7552/7459/4195 7575/7480/4195 7574/7479/4195 +f 7574/7479/4195 7575/7480/4195 7542/7450/4195 +f 7574/7479/4195 7542/7450/4195 7540/7448/4195 +f 7349/7266/4195 7574/7479/4195 7540/7448/4195 +f 7349/7266/4195 7540/7448/4195 7350/7267/4195 +f 7322/7239/4195 7576/7481/4195 7577/7482/4195 +f 7322/7239/4195 7577/7482/4195 7499/7411/4195 +f 7576/7481/4195 7352/7269/4195 7492/7404/4195 +f 7576/7481/4195 7492/7404/4195 7577/7482/4195 +f 7577/7482/4195 7492/7404/4195 7496/7408/4195 +f 7577/7482/4195 7496/7408/4195 7578/7483/4195 +f 7499/7411/4195 7577/7482/4195 7578/7483/4195 +f 7499/7411/4195 7578/7483/4195 7500/7412/4195 +f 7357/7274/4195 7579/7484/4195 7580/7485/4195 +f 7357/7274/4195 7580/7485/4195 7358/7275/4195 +f 7579/7484/4195 7362/7276/4195 7365/7279/4195 +f 7579/7484/4195 7365/7279/4195 7580/7485/4195 +f 7320/7237/4195 7582/7486/4195 7583/7487/4195 +f 7320/7237/4195 7583/7487/4195 7321/7238/4195 +f 7582/7486/4195 7336/7253/4195 7348/7265/4195 +f 7582/7486/4195 7348/7265/4195 7583/7487/4195 +f 7583/7487/4195 7348/7265/4195 7352/7269/4195 +f 7583/7487/4195 7352/7269/4195 7576/7481/4195 +f 7321/7238/4195 7583/7487/4195 7576/7481/4195 +f 7321/7238/4195 7576/7481/4195 7322/7239/4195 +f 7281/7204/4195 7278/7201/4195 7584/7488/4195 +f 7281/7204/4195 7584/7488/4195 7329/7246/4195 +f 7278/7201/4195 7277/7200/4195 7332/7249/4195 +f 7278/7201/4195 7332/7249/4195 7584/7488/4195 +f 7584/7488/4195 7332/7249/4195 7336/7253/4195 +f 7584/7488/4195 7336/7253/4195 7582/7486/4195 +f 7329/7246/4195 7584/7488/4195 7582/7486/4195 +f 7329/7246/4195 7582/7486/4195 7320/7237/4195 +f 7268/7191/4195 7585/7489/4195 7586/7490/4195 +f 7268/7191/4195 7586/7490/4195 7294/7214/4195 +f 7585/7489/4195 7237/7160/4195 7299/7219/4195 +f 7585/7489/4195 7299/7219/4195 7586/7490/4195 +f 7586/7490/4195 7299/7219/4195 7303/7223/4195 +f 7586/7490/4195 7303/7223/4195 7587/7491/4195 +f 7294/7214/4195 7586/7490/4195 7587/7491/4195 +f 7294/7214/4195 7587/7491/4195 7295/7215/4195 +f 7275/7198/4195 7330/7247/4195 7588/7492/4195 +f 7275/7198/4195 7588/7492/4195 7276/7199/4195 +f 7330/7247/4195 7277/7200/4195 7280/7203/4195 +f 7330/7247/4195 7280/7203/4195 7588/7492/4195 +f 7588/7492/4195 7280/7203/4195 7229/7152/4195 +f 7588/7492/4195 7229/7152/4195 7589/7493/4195 +f 7276/7199/4195 7588/7492/4195 7589/7493/4195 +f 7276/7199/4195 7589/7493/4195 7266/7189/4195 +f 7266/7189/4195 7589/7493/4195 7590/7494/4195 +f 7266/7189/4195 7590/7494/4195 7267/7190/4195 +f 7589/7493/4195 7229/7152/4195 7232/7155/4195 +f 7589/7493/4195 7232/7155/4195 7590/7494/4195 +f 7590/7494/4195 7232/7155/4195 7237/7160/4195 +f 7590/7494/4195 7237/7160/4195 7585/7489/4195 +f 7267/7190/4195 7590/7494/4195 7585/7489/4195 +f 7267/7190/4195 7585/7489/4195 7268/7191/4195 +f 7287/7210/4195 7591/7495/4195 7592/7496/4195 +f 7287/7210/4195 7592/7496/4195 7288/7211/4195 +f 7591/7495/4195 7220/7143/4195 7223/7146/4195 +f 7591/7495/4195 7223/7146/4195 7592/7496/4195 +f 7592/7496/4195 7223/7146/4195 7228/7151/4195 +f 7592/7496/4195 7228/7151/4195 7593/7497/4195 +f 7288/7211/4195 7592/7496/4195 7593/7497/4195 +f 6506/6501/4149 8816/7498/4149 8817/7499/4149 +f 6506/6501/4149 8817/7499/4149 6508/6504/4149 +f 8816/7498/4149 6596/6585/4149 6593/6582/4149 +f 8816/7498/4149 6593/6582/4149 8817/7499/4149 +f 8817/7499/4149 6593/6582/4149 6592/6581/4149 +f 8817/7499/4149 6592/6581/4149 8818/7500/4149 +f 6508/6504/4149 8817/7499/4149 8818/7500/4149 +f 6508/6504/4149 8818/7500/4149 6510/6506/4149 +f 6502/6497/4149 8829/7501/4149 8830/7502/4149 +f 6502/6497/4149 8830/7502/4149 6503/6498/4149 +f 8829/7501/4149 6580/6569/4149 6824/6782/4149 +f 8829/7501/4149 6824/6782/4149 8830/7502/4149 +f 8830/7502/4149 6824/6782/4149 6596/6585/4149 +f 8830/7502/4149 6596/6585/4149 8816/7498/4149 +f 6503/6498/4149 8830/7502/4149 8816/7498/4149 +f 6503/6498/4149 8816/7498/4149 6506/6501/4149 +f 8842/7503/4149 8843/7504/4149 8844/7505/4149 +f 8842/7503/4149 8844/7505/4149 8845/7506/4149 +f 8843/7504/4149 6547/6540/4149 6853/6809/4149 +f 8843/7504/4149 6853/6809/4149 8844/7505/4149 +f 8844/7505/4149 6853/6809/4149 6555/6548/4149 +f 8844/7505/4149 6555/6548/4149 8846/7507/4149 +f 8845/7506/4149 8844/7505/4149 8846/7507/4149 +f 8845/7506/4149 8846/7507/4149 8847/7508/4149 +f 8854/7509/4149 8855/7510/4149 8856/7511/4149 +f 8854/7509/4149 8856/7511/4149 8857/7512/4149 +f 8855/7510/4149 6553/6546/4149 6834/6792/4149 +f 8855/7510/4149 6834/6792/4149 8856/7511/4149 +f 8856/7511/4149 6834/6792/4149 6833/6791/4149 +f 8856/7511/4149 6833/6791/4149 8858/7513/4149 +f 8857/7512/4149 8856/7511/4149 8858/7513/4149 +f 8857/7512/4149 8858/7513/4149 6570/6559/4149 +f 6510/6506/4149 8818/7500/4149 8880/7514/4149 +f 6510/6506/4149 8880/7514/4149 6695/6668/4149 +f 8818/7500/4149 6592/6581/4149 6773/6740/4149 +f 8818/7500/4149 6773/6740/4149 8880/7514/4149 +f 8880/7514/4149 6773/6740/4149 6775/6742/4149 +f 8880/7514/4149 6775/6742/4149 8881/7515/4149 +f 6695/6668/4149 8880/7514/4149 8881/7515/4149 +f 6695/6668/4149 8881/7515/4149 6693/6666/4149 +f 6693/6666/4149 8881/7515/4149 8892/7516/4149 +f 6693/6666/4149 8892/7516/4149 6691/6664/4149 +f 8881/7515/4149 6775/6742/4149 6950/6902/4149 +f 8881/7515/4149 6950/6902/4149 8892/7516/4149 +f 8892/7516/4149 6950/6902/4149 6760/6727/4149 +f 8892/7516/4149 6760/6727/4149 8893/7517/4149 +f 6691/6664/4149 8892/7516/4149 8893/7517/4149 +f 6691/6664/4149 8893/7517/4149 6688/6661/4149 +f 6724/6696/4253 8895/7518/4254 7021/6977/4255 +f 7021/6977/4256 8896/7519/4257 6659/6632/4258 +f 6687/6660/4149 8901/7520/4259 6696/6669/4193 +f 6696/6669/4260 8840/7521/4261 6512/6508/4260 +f 6655/6628/4149 8902/7522/4149 8903/7523/4149 +f 6655/6628/4149 8903/7523/4149 7020/6976/4149 +f 8902/7522/4149 6735/6707/4149 7015/6971/4149 +f 8902/7522/4149 7015/6971/4149 8903/7523/4149 +f 8903/7523/4149 7015/6971/4149 6731/6703/4149 +f 8903/7523/4149 6731/6703/4149 8904/7524/4149 +f 7020/6976/4149 8903/7523/4149 8904/7524/4149 +f 7020/6976/4149 8904/7524/4149 6726/6698/4149 +f 6739/6711/4149 8909/7525/4149 8910/7526/4149 +f 6739/6711/4149 8910/7526/4149 6960/6912/4149 +f 8909/7525/4149 6956/6908/4149 6955/6907/4149 +f 8909/7525/4149 6955/6907/4149 8910/7526/4149 +f 8910/7526/4149 6955/6907/4149 6737/6709/4149 +f 8910/7526/4149 6737/6709/4149 8911/7527/4149 +f 6960/6912/4149 8910/7526/4149 8911/7527/4149 +f 6960/6912/4149 8911/7527/4149 6663/6636/4149 +f 6818/6777/4169 8920/7528/4262 6948/6899/4169 +f 6794/6758/4263 8923/7529/4264 7009/6964/4265 +f 6570/6559/4149 8858/7513/4149 8931/7530/4149 +f 6570/6559/4149 8931/7530/4149 6566/6555/4149 +f 8858/7513/4149 6833/6791/4149 6832/6790/4149 +f 8858/7513/4149 6832/6790/4149 8931/7530/4149 +f 8931/7530/4149 6832/6790/4149 6831/6789/4149 +f 8931/7530/4149 6831/6789/4149 8932/7531/4149 +f 6566/6555/4149 8931/7530/4149 8932/7531/4149 +f 6566/6555/4149 8932/7531/4149 6501/6496/4149 +f 6493/6489/4149 8933/7532/4149 8934/7533/4149 +f 6493/6489/4149 8934/7533/4149 6505/6500/4149 +f 8933/7532/4149 6840/6797/4149 6839/6796/4149 +f 8933/7532/4149 6839/6796/4149 8934/7533/4149 +f 8934/7533/4149 6839/6796/4149 6580/6569/4149 +f 8934/7533/4149 6580/6569/4149 8829/7501/4149 +f 6505/6500/4149 8934/7533/4149 8829/7501/4149 +f 6505/6500/4149 8829/7501/4149 6502/6497/4149 +f 6501/6496/4149 8932/7531/4149 8935/7534/4149 +f 6501/6496/4149 8935/7534/4149 6496/6492/4149 +f 8932/7531/4149 6831/6789/4149 6843/6800/4149 +f 8932/7531/4149 6843/6800/4149 8935/7534/4149 +f 8935/7534/4149 6843/6800/4149 6840/6797/4149 +f 8935/7534/4149 6840/6797/4149 8933/7532/4149 +f 6496/6492/4149 8935/7534/4149 8933/7532/4149 +f 6496/6492/4149 8933/7532/4149 6493/6489/4149 +f 8847/7508/4149 8846/7507/4149 8937/7535/4149 +f 8847/7508/4149 8937/7535/4149 8938/7536/4149 +f 8846/7507/4149 6555/6548/4149 6554/6547/4149 +f 8846/7507/4149 6554/6547/4149 8937/7535/4149 +f 8937/7535/4149 6554/6547/4149 6553/6546/4149 +f 8937/7535/4149 6553/6546/4149 8855/7510/4149 +f 8938/7536/4149 8937/7535/4149 8855/7510/4149 +f 8938/7536/4149 8855/7510/4149 8854/7509/4149 +f 6626/7537/4266 8869/7538/4267 6627/7539/4266 +f 6873/6826/4149 8941/7540/4149 8942/7541/4149 +f 6873/6826/4149 8942/7541/4149 8943/7542/4149 +f 8941/7540/4149 6549/6542/4149 6548/6541/4149 +f 8941/7540/4149 6548/6541/4149 8942/7541/4149 +f 8942/7541/4149 6548/6541/4149 6547/6540/4149 +f 8942/7541/4149 6547/6540/4149 8843/7504/4149 +f 8943/7542/4149 8942/7541/4149 8843/7504/4149 +f 8943/7542/4149 8843/7504/4149 8842/7503/4149 +f 6457/6457/4149 8945/7543/4149 8946/7544/4149 +f 6457/6457/4149 8946/7544/4149 6601/6590/4149 +f 8945/7543/4149 6865/6819/4149 6864/6818/4149 +f 8945/7543/4149 6864/6818/4149 8946/7544/4149 +f 8946/7544/4149 6864/6818/4149 6523/6519/4149 +f 8946/7544/4149 6523/6519/4149 8947/7545/4149 +f 6601/6590/4149 8946/7544/4149 8947/7545/4149 +f 6601/6590/4149 8947/7545/4149 6598/6587/4149 +f 6871/6824/4149 8948/7546/4149 8949/7547/4149 +f 6871/6824/4149 8949/7547/4149 6872/6825/4149 +f 8948/7546/4149 6522/6518/4149 6545/6538/4149 +f 8948/7546/4149 6545/6538/4149 8949/7547/4149 +f 8949/7547/4149 6545/6538/4149 6549/6542/4149 +f 8949/7547/4149 6549/6542/4149 8941/7540/4149 +f 6872/6825/4149 8949/7547/4149 8941/7540/4149 +f 6872/6825/4149 8941/7540/4149 6873/6826/4149 +f 6598/6587/4149 8947/7545/4149 8950/7548/4149 +f 6598/6587/4149 8950/7548/4149 6884/6834/4149 +f 8947/7545/4149 6523/6519/4149 6526/6522/4149 +f 8947/7545/4149 6526/6522/4149 8950/7548/4149 +f 8950/7548/4149 6526/6522/4149 6514/6510/4149 +f 8950/7548/4149 6514/6510/4149 8951/7549/4149 +f 6884/6834/4149 8950/7548/4149 8951/7549/4149 +f 6884/6834/4149 8951/7549/4149 6885/6835/4149 +f 6885/6835/4149 8951/7549/4149 8952/7550/4149 +f 6885/6835/4149 8952/7550/4149 6890/6840/4149 +f 8951/7549/4149 6514/6510/4149 6517/6513/4149 +f 8951/7549/4149 6517/6513/4149 8952/7550/4149 +f 8952/7550/4149 6517/6513/4149 6522/6518/4149 +f 8952/7550/4149 6522/6518/4149 8948/7546/4149 +f 6890/6840/4149 8952/7550/4149 8948/7546/4149 +f 6890/6840/4149 8948/7546/4149 6871/6824/4149 +f 6465/6464/4149 8953/7551/4149 8954/7552/4149 +f 6465/6464/4149 8954/7552/4149 6460/6460/4149 +f 8953/7551/4149 6893/6844/4149 6892/6843/4149 +f 8953/7551/4149 6892/6843/4149 8954/7552/4149 +f 8954/7552/4149 6892/6843/4149 6865/6819/4149 +f 8954/7552/4149 6865/6819/4149 8945/7543/4149 +f 6460/6460/4149 8954/7552/4149 8945/7543/4149 +f 6460/6460/4149 8945/7543/4149 6457/6457/4149 +f 6628/6611/4149 8957/7553/4149 8958/7554/4149 +f 6628/6611/4149 8958/7554/4149 6937/6887/4149 +f 8957/7553/4149 6898/6849/4149 6897/6848/4149 +f 8957/7553/4149 6897/6848/4149 8958/7554/4149 +f 8958/7554/4149 6897/6848/4149 6893/6844/4149 +f 8958/7554/4149 6893/6844/4149 8953/7551/4149 +f 6937/6887/4149 8958/7554/4149 8953/7551/4149 +f 6937/6887/4149 8953/7551/4149 6465/6464/4149 +f 6623/6609/4149 8959/7555/4149 8960/7556/4149 +f 6623/6609/4149 8960/7556/4149 6860/6815/4149 +f 8959/7555/4149 6900/6851/4149 6899/6850/4149 +f 8959/7555/4149 6899/6850/4149 8960/7556/4149 +f 8960/7556/4149 6899/6850/4149 6898/6849/4149 +f 8960/7556/4149 6898/6849/4149 8957/7553/4149 +f 6860/6815/4149 8960/7556/4149 8957/7553/4149 +f 6860/6815/4149 8957/7553/4149 6628/6611/4149 +f 6614/6603/4149 8961/7557/4149 8962/7558/4149 +f 6614/6603/4149 8962/7558/4149 6844/6801/4149 +f 8961/7557/4149 6906/6857/4149 6905/6856/4149 +f 8961/7557/4149 6905/6856/4149 8962/7558/4149 +f 8962/7558/4149 6905/6856/4149 6904/6855/4149 +f 8962/7558/4149 6904/6855/4149 8963/7559/4149 +f 6844/6801/4149 8962/7558/4149 8963/7559/4149 +f 6844/6801/4149 8963/7559/4149 6619/6605/4149 +f 6641/6620/4149 8964/7560/4149 8965/7561/4149 +f 6641/6620/4149 8965/7561/4149 6821/6780/4149 +f 8964/7560/4149 6912/6863/4149 6911/6862/4149 +f 8964/7560/4149 6911/6862/4149 8965/7561/4149 +f 8965/7561/4149 6911/6862/4149 6910/6861/4149 +f 8965/7561/4149 6910/6861/4149 8966/7562/4149 +f 6821/6780/4149 8965/7561/4149 8966/7562/4149 +f 6821/6780/4149 8966/7562/4149 6610/6599/4149 +f 6820/6779/4149 8967/7563/4149 8968/7564/4149 +f 6820/6779/4149 8968/7564/4149 6816/6775/4149 +f 8967/7563/4149 6917/6868/4149 6916/6867/4149 +f 8967/7563/4149 6916/6867/4149 8968/7564/4149 +f 8968/7564/4149 6916/6867/4149 6915/6866/4149 +f 8968/7564/4149 6915/6866/4149 8969/7565/4149 +f 6816/6775/4149 8968/7564/4149 8969/7565/4149 +f 6816/6775/4149 8969/7565/4149 6637/6616/4149 +f 6805/6768/4149 8970/7566/4149 8971/7567/4149 +f 6805/6768/4149 8971/7567/4149 6800/6764/4149 +f 8970/7566/4149 6926/6876/4149 6925/6875/4149 +f 8970/7566/4149 6925/6875/4149 8971/7567/4149 +f 8971/7567/4149 6925/6875/4149 6924/6874/4149 +f 8971/7567/4149 6924/6874/4149 8972/7568/4149 +f 6800/6764/4149 8971/7567/4149 8972/7568/4149 +f 6800/6764/4149 8972/7568/4149 6797/6761/4149 +f 6796/6760/4149 8973/7569/4149 8974/7570/4149 +f 6796/6760/4149 8974/7570/4149 6791/6756/4149 +f 8973/7569/4149 6932/6882/4149 6931/6881/4149 +f 8973/7569/4149 6931/6881/4149 8974/7570/4149 +f 8974/7570/4149 6931/6881/4149 6930/6880/4149 +f 8974/7570/4149 6930/6880/4149 8975/7571/4149 +f 6791/6756/4149 8974/7570/4149 8975/7571/4149 +f 6791/6756/4149 8975/7571/4149 6788/6753/4149 +f 6637/6616/4149 8969/7565/4149 8976/7572/4149 +f 6637/6616/4149 8976/7572/4149 6638/6617/4149 +f 8969/7565/4149 6915/6866/4149 6935/6885/4149 +f 8969/7565/4149 6935/6885/4149 8976/7572/4149 +f 8976/7572/4149 6935/6885/4149 6912/6863/4149 +f 8976/7572/4149 6912/6863/4149 8964/7560/4149 +f 6638/6617/4149 8976/7572/4149 8964/7560/4149 +f 6638/6617/4149 8964/7560/4149 6641/6620/4149 +f 6619/6605/4149 8963/7559/4149 8977/7573/4149 +f 6619/6605/4149 8977/7573/4149 6620/6606/4149 +f 8963/7559/4149 6904/6855/4149 6940/6891/4149 +f 8963/7559/4149 6940/6891/4149 8977/7573/4149 +f 8977/7573/4149 6940/6891/4149 6900/6851/4149 +f 8977/7573/4149 6900/6851/4149 8959/7555/4149 +f 6620/6606/4149 8977/7573/4149 8959/7555/4149 +f 6620/6606/4149 8959/7555/4149 6623/6609/4149 +f 6610/6599/4149 8966/7562/4149 8978/7574/4149 +f 6610/6599/4149 8978/7574/4149 6611/6600/4149 +f 8966/7562/4149 6910/6861/4149 6942/6893/4149 +f 8966/7562/4149 6942/6893/4149 8978/7574/4149 +f 8978/7574/4149 6942/6893/4149 6906/6857/4149 +f 8978/7574/4149 6906/6857/4149 8961/7557/4149 +f 6611/6600/4149 8978/7574/4149 8961/7557/4149 +f 6611/6600/4149 8961/7557/4149 6614/6603/4149 +f 6743/6914/4268 8979/7575/4269 6744/6715/4270 +f 6793/6757/4271 8922/7576/4272 6794/6758/4273 +f 6788/6753/4149 8975/7571/4149 8981/7577/4149 +f 6788/6753/4149 8981/7577/4149 6947/6898/4149 +f 8975/7571/4149 6930/6880/4149 6945/6896/4149 +f 8975/7571/4149 6945/6896/4149 8981/7577/4149 +f 8981/7577/4149 6945/6896/4149 6917/6868/4149 +f 8981/7577/4149 6917/6868/4149 8967/7563/4149 +f 6947/6898/4149 8981/7577/4149 8967/7563/4149 +f 6947/6898/4149 8967/7563/4149 6820/6779/4149 +f 6683/6656/4149 8982/7578/4149 8983/7579/4149 +f 6683/6656/4149 8983/7579/4149 6748/6716/4149 +f 8982/7578/4149 6958/6910/4149 6957/6909/4149 +f 8982/7578/4149 6957/6909/4149 8983/7579/4149 +f 8983/7579/4149 6957/6909/4149 6956/6908/4149 +f 8983/7579/4149 6956/6908/4149 8909/7525/4149 +f 6748/6716/4149 8983/7579/4149 8909/7525/4149 +f 6748/6716/4149 8909/7525/4149 6739/6711/4149 +f 6688/6661/4149 8893/7517/4149 8984/7580/4149 +f 6688/6661/4149 8984/7580/4149 6689/6662/4149 +f 8893/7517/4149 6760/6727/4149 6965/6918/4149 +f 8893/7517/4149 6965/6918/4149 8984/7580/4149 +f 8984/7580/4149 6965/6918/4149 6964/6917/4149 +f 8984/7580/4149 6964/6917/4149 8985/7581/4149 +f 6689/6662/4149 8984/7580/4149 8985/7581/4149 +f 6689/6662/4149 8985/7581/4149 6679/6652/4149 +f 6679/6652/4149 8985/7581/4149 8986/7582/4149 +f 6679/6652/4149 8986/7582/4149 6680/6653/4149 +f 8985/7581/4149 6964/6917/4149 6967/6920/4149 +f 8985/7581/4149 6967/6920/4149 8986/7582/4149 +f 8986/7582/4149 6967/6920/4149 6958/6910/4149 +f 8986/7582/4149 6958/6910/4149 8982/7578/4149 +f 6680/6653/4149 8986/7582/4149 8982/7578/4149 +f 6680/6653/4149 8982/7578/4149 6683/6656/4149 +f 6722/6946/4153 8987/7583/4274 6723/6695/4185 +f 6726/6698/4149 8904/7524/4149 8988/7584/4149 +f 6726/6698/4149 8988/7584/4149 6721/6694/4149 +f 8904/7524/4149 6731/6703/4149 6730/6702/4149 +f 8904/7524/4149 6730/6702/4149 8988/7584/4149 +f 8988/7584/4149 6730/6702/4149 6729/6701/4149 +f 8988/7584/4149 6729/6701/4149 8989/7585/4149 +f 6721/6694/4149 8988/7584/4149 8989/7585/4149 +f 6721/6694/4149 8989/7585/4149 6718/6691/4149 +f 6806/6769/4149 8991/7586/4149 8992/7587/4149 +f 6806/6769/4149 8992/7587/4149 6975/6928/4149 +f 8991/7586/4149 6971/6924/4149 6970/6923/4149 +f 8991/7586/4149 6970/6923/4149 8992/7587/4149 +f 8992/7587/4149 6970/6923/4149 6926/6876/4149 +f 8992/7587/4149 6926/6876/4149 8970/7566/4149 +f 6975/6928/4149 8992/7587/4149 8970/7566/4149 +f 6975/6928/4149 8970/7566/4149 6805/6768/4149 +f 6650/6626/4149 8993/7588/4149 8994/7589/4149 +f 6650/6626/4149 8994/7589/4149 6919/6870/4149 +f 8993/7588/4149 6973/6926/4149 6972/6925/4149 +f 8993/7588/4149 6972/6925/4149 8994/7589/4149 +f 8994/7589/4149 6972/6925/4149 6971/6924/4149 +f 8994/7589/4149 6971/6924/4149 8991/7586/4149 +f 6919/6870/4149 8994/7589/4149 8991/7586/4149 +f 6919/6870/4149 8991/7586/4149 6806/6769/4149 +f 6776/6743/4149 8995/7590/4149 8996/7591/4149 +f 6776/6743/4149 8996/7591/4149 6777/6744/4149 +f 8995/7590/4149 6706/6679/4149 6980/6934/4149 +f 8995/7590/4149 6980/6934/4149 8996/7591/4149 +f 8996/7591/4149 6980/6934/4149 6979/6933/4149 +f 8996/7591/4149 6979/6933/4149 8997/7592/4149 +f 6777/6744/4149 8996/7591/4149 8997/7592/4149 +f 6777/6744/4149 8997/7592/4149 6646/6622/4149 +f 6718/6691/4149 8989/7585/4149 8998/7593/4149 +f 6718/6691/4149 8998/7593/4149 6987/6941/4149 +f 8989/7585/4149 6729/6701/4149 6727/6699/4149 +f 8989/7585/4149 6727/6699/4149 8998/7593/4149 +f 8998/7593/4149 6727/6699/4149 6701/6674/4149 +f 8998/7593/4149 6701/6674/4149 8999/7594/4149 +f 6987/6941/4149 8998/7593/4149 8999/7594/4149 +f 6987/6941/4149 8999/7594/4149 6988/6942/4149 +f 6997/6952/4149 9000/7595/4149 9001/7596/4149 +f 6997/6952/4149 9001/7596/4149 6998/6953/4149 +f 9000/7595/4149 6697/6670/4149 6707/6680/4149 +f 9000/7595/4149 6707/6680/4149 9001/7596/4149 +f 9001/7596/4149 6707/6680/4149 6706/6679/4149 +f 9001/7596/4149 6706/6679/4149 8995/7590/4149 +f 6998/6953/4149 9001/7596/4149 8995/7590/4149 +f 6998/6953/4149 8995/7590/4149 6776/6743/4149 +f 6988/6942/4149 8999/7594/4149 9002/7597/4149 +f 6988/6942/4149 9002/7597/4149 7001/6956/4149 +f 8999/7594/4149 6701/6674/4149 6698/6671/4149 +f 8999/7594/4149 6698/6671/4149 9002/7597/4149 +f 9002/7597/4149 6698/6671/4149 6697/6670/4149 +f 9002/7597/4149 6697/6670/4149 9000/7595/4149 +f 7001/6956/4149 9002/7597/4149 9000/7595/4149 +f 7001/6956/4149 9000/7595/4149 6997/6952/4149 +f 6646/6622/4149 8997/7592/4149 9003/7598/4149 +f 6646/6622/4149 9003/7598/4149 6647/6623/4149 +f 8997/7592/4149 6979/6933/4149 7003/6958/4149 +f 8997/7592/4149 7003/6958/4149 9003/7598/4149 +f 9003/7598/4149 7003/6958/4149 6973/6926/4149 +f 9003/7598/4149 6973/6926/4149 8993/7588/4149 +f 6647/6623/4149 9003/7598/4149 8993/7588/4149 +f 6647/6623/4149 8993/7588/4149 6650/6626/4149 +f 6659/6632/4258 9004/7599/4275 6660/6633/4276 +f 6660/6633/4276 8888/7600/4277 6661/6634/4278 +f 6663/6636/4149 8911/7527/4149 9005/7601/4149 +f 6663/6636/4149 9005/7601/4149 6658/6631/4149 +f 8911/7527/4149 6737/6709/4149 6736/6708/4149 +f 8911/7527/4149 6736/6708/4149 9005/7601/4149 +f 9005/7601/4149 6736/6708/4149 6735/6707/4149 +f 9005/7601/4149 6735/6707/4149 8902/7522/4149 +f 6658/6631/4149 9005/7601/4149 8902/7522/4149 +f 6658/6631/4149 8902/7522/4149 6655/6628/4149 +f 6797/6761/4149 8972/7568/4149 9007/7602/4149 +f 6797/6761/4149 9007/7602/4149 7008/6963/4149 +f 8972/7568/4149 6924/6874/4149 7006/6961/4149 +f 8972/7568/4149 7006/6961/4149 9007/7602/4149 +f 9007/7602/4149 7006/6961/4149 6932/6882/4149 +f 9007/7602/4149 6932/6882/4149 8973/7569/4149 +f 7008/6963/4149 9007/7602/4149 8973/7569/4149 +f 7008/6963/4149 8973/7569/4149 6796/6760/4149 +f 7078/7028/4195 9011/7603/4195 9012/7604/4195 +f 7078/7028/4195 9012/7604/4195 7074/7024/4195 +f 9011/7603/4195 7157/7095/4195 7160/7098/4195 +f 9011/7603/4195 7160/7098/4195 9012/7604/4195 +f 9012/7604/4195 7160/7098/4195 7162/7100/4195 +f 9012/7604/4195 7162/7100/4195 9013/7605/4195 +f 7074/7024/4195 9012/7604/4195 9013/7605/4195 +f 7074/7024/4195 9013/7605/4195 7072/7022/4195 +f 7037/6989/4197 9021/7606/4279 7402/7607/4280 +f 7062/7014/4195 9023/7608/4195 9024/7609/4195 +f 7062/7014/4195 9024/7609/4195 7397/7303/4195 +f 9023/7608/4195 7409/7316/4195 7408/7315/4195 +f 9023/7608/4195 7408/7315/4195 9024/7609/4195 +f 9024/7609/4195 7408/7315/4195 7046/6998/4195 +f 9024/7609/4195 7046/6998/4195 9025/7610/4195 +f 7397/7303/4195 9024/7609/4195 9025/7610/4195 +f 7397/7303/4195 9025/7610/4195 7394/7300/4195 +f 7072/7022/4195 9013/7605/4195 9027/7611/4195 +f 7072/7022/4195 9027/7611/4195 7070/7019/4195 +f 9013/7605/4195 7162/7100/4195 7390/7296/4195 +f 9013/7605/4195 7390/7296/4195 9027/7611/4195 +f 9027/7611/4195 7390/7296/4195 7145/7083/4195 +f 9027/7611/4195 7145/7083/4195 9028/7612/4195 +f 7070/7019/4195 9027/7611/4195 9028/7612/4195 +f 7070/7019/4195 9028/7612/4195 7067/7016/4195 +f 7394/7300/4195 9025/7610/4195 9035/7613/4195 +f 7394/7300/4195 9035/7613/4195 7395/7301/4195 +f 9025/7610/4195 7046/6998/4195 7120/7069/4195 +f 9025/7610/4195 7120/7069/4195 9035/7613/4195 +f 9035/7613/4195 7120/7069/4195 7119/7068/4195 +f 9035/7613/4195 7119/7068/4195 9036/7614/4195 +f 7395/7301/4195 9035/7613/4195 9036/7614/4195 +f 7395/7301/4195 9036/7614/4195 7398/7304/4195 +f 9042/7615/4195 9043/7616/4195 9044/7617/4195 +f 9042/7615/4195 9044/7617/4195 9045/7618/4195 +f 9043/7616/4195 7117/7066/4195 7420/7328/4195 +f 9043/7616/4195 7420/7328/4195 9044/7617/4195 +f 9044/7617/4195 7420/7328/4195 7113/7062/4195 +f 9044/7617/4195 7113/7062/4195 9046/7619/4195 +f 9045/7618/4195 9044/7617/4195 9046/7619/4195 +f 9045/7618/4195 9046/7619/4195 9047/7620/4195 +f 7388/7293/4281 9065/7621/4282 7179/7294/4281 +f 7413/7320/4283 9068/7622/4284 7188/7321/4285 +f 7206/7623/4286 9070/7624/4287 7207/7131/4286 +f 7257/7180/4195 9074/7625/4195 9075/7626/4195 +f 7257/7180/4195 9075/7626/4195 7259/7182/4195 +f 9074/7625/4195 7339/7256/4195 7337/7254/4195 +f 9074/7625/4195 7337/7254/4195 9075/7626/4195 +f 9075/7626/4195 7337/7254/4195 7157/7095/4195 +f 9075/7626/4195 7157/7095/4195 9011/7603/4195 +f 7259/7182/4195 9075/7626/4195 9011/7603/4195 +f 7259/7182/4195 9011/7603/4195 7078/7028/4195 +f 7312/7627/4288 9083/7628/4289 7533/7629/4290 +f 7533/7629/4291 9084/7630/4292 7226/7149/4293 +f 7253/7176/4195 9086/7631/4195 9087/7632/4195 +f 7253/7176/4195 9087/7632/4195 7254/7177/4195 +f 9086/7631/4195 7325/7242/4195 7521/7430/4195 +f 9086/7631/4195 7521/7430/4195 9087/7632/4195 +f 9087/7632/4195 7521/7430/4195 7339/7256/4195 +f 9087/7632/4195 7339/7256/4195 9074/7625/4195 +f 7254/7177/4195 9087/7632/4195 9074/7625/4195 +f 7254/7177/4195 9074/7625/4195 7257/7180/4195 +f 7228/7151/4294 9089/7633/4295 7593/7497/4294 +f 7593/7497/4296 9090/7634/4297 7289/7635/4296 +f 7076/7026/4195 9095/7636/4298 7261/7184/4299 +f 7261/7184/4300 9092/7637/4301 7248/7171/4300 +f 7287/7210/4195 9096/7638/4195 9097/7639/4195 +f 7287/7210/4195 9097/7639/4195 7591/7495/4195 +f 9096/7638/4195 7295/7215/4195 7587/7491/4195 +f 9096/7638/4195 7587/7491/4195 9097/7639/4195 +f 9097/7639/4195 7587/7491/4195 7303/7223/4195 +f 9097/7639/4195 7303/7223/4195 9098/7640/4195 +f 7591/7495/4195 9097/7639/4195 9098/7640/4195 +f 7591/7495/4195 9098/7640/4195 7220/7143/4195 +f 7224/7147/4195 9103/7641/4195 9104/7642/4195 +f 7224/7147/4195 9104/7642/4195 7531/7440/4195 +f 9103/7641/4195 7301/7221/4195 7530/7439/4195 +f 9103/7641/4195 7530/7439/4195 9104/7642/4195 +f 9104/7642/4195 7530/7439/4195 7529/7438/4195 +f 9104/7642/4195 7529/7438/4195 9105/7643/4195 +f 7531/7440/4195 9104/7642/4195 9105/7643/4195 +f 7531/7440/4195 9105/7643/4195 7304/7224/4195 +f 7361/7644/4302 9114/7645/4303 7520/7646/4304 +f 7385/7647/4207 9069/7648/4305 7206/7623/4207 +f 7179/7294/4219 9120/7649/4306 7180/7115/4203 +f 7067/7016/4195 9028/7612/4195 9121/7650/4195 +f 7067/7016/4195 9121/7650/4195 7068/7017/4195 +f 9028/7612/4195 7145/7083/4195 7406/7313/4195 +f 9028/7612/4195 7406/7313/4195 9121/7650/4195 +f 9121/7650/4195 7406/7313/4195 7405/7312/4195 +f 9121/7650/4195 7405/7312/4195 9122/7651/4195 +f 7068/7017/4195 9121/7650/4195 9122/7651/4195 +f 7068/7017/4195 9122/7651/4195 7058/7010/4195 +f 7058/7010/4195 9122/7651/4195 9123/7652/4195 +f 7058/7010/4195 9123/7652/4195 7059/7011/4195 +f 9122/7651/4195 7405/7312/4195 7410/7317/4195 +f 9122/7651/4195 7410/7317/4195 9123/7652/4195 +f 9123/7652/4195 7410/7317/4195 7409/7316/4195 +f 9123/7652/4195 7409/7316/4195 9023/7608/4195 +f 7059/7011/4195 9123/7652/4195 9023/7608/4195 +f 7059/7011/4195 9023/7608/4195 7062/7014/4195 +f 7398/7304/4195 9036/7614/4195 9125/7653/4195 +f 7398/7304/4195 9125/7653/4195 9126/7654/4195 +f 9036/7614/4195 7119/7068/4195 7118/7067/4195 +f 9036/7614/4195 7118/7067/4195 9125/7653/4195 +f 9125/7653/4195 7118/7067/4195 7117/7066/4195 +f 9125/7653/4195 7117/7066/4195 9043/7616/4195 +f 9126/7654/4195 9125/7653/4195 9043/7616/4195 +f 9126/7654/4195 9043/7616/4195 9042/7615/4195 +f 7189/7123/4285 9060/7655/4307 7190/7124/4308 +f 9047/7620/4195 9046/7619/4195 9129/7656/4195 +f 9047/7620/4195 9129/7656/4195 9130/7657/4195 +f 9046/7619/4195 7113/7062/4195 7112/7061/4195 +f 9046/7619/4195 7112/7061/4195 9129/7656/4195 +f 9129/7656/4195 7112/7061/4195 7111/7060/4195 +f 9129/7656/4195 7111/7060/4195 9131/7658/4195 +f 9130/7657/4195 9129/7656/4195 9131/7658/4195 +f 9130/7657/4195 9131/7658/4195 7443/7352/4195 +f 7430/7339/4309 9132/7659/4310 7431/7340/4311 +f 9132/7659/4310 7193/7379/4243 9133/7660/4312 +f 7431/7340/4311 9132/7659/4310 9133/7660/4311 +f 7431/7340/4195 9133/7660/4195 7432/7341/4195 +f 7163/7101/4195 9134/7661/4195 9135/7662/4195 +f 7163/7101/4195 9135/7662/4195 7164/7102/4195 +f 9134/7661/4195 7088/7038/4195 7436/7345/4195 +f 9134/7661/4195 7436/7345/4195 9135/7662/4195 +f 9135/7662/4195 7436/7345/4195 7435/7344/4195 +f 9135/7662/4195 7435/7344/4195 9136/7663/4195 +f 7164/7102/4195 9135/7662/4195 9136/7663/4195 +f 7164/7102/4195 9136/7663/4195 7022/6978/4195 +f 7443/7352/4195 9131/7658/4195 9137/7664/4195 +f 7443/7352/4195 9137/7664/4195 7444/7353/4195 +f 9131/7658/4195 7111/7060/4195 7109/7058/4195 +f 9131/7658/4195 7109/7058/4195 9137/7664/4195 +f 9137/7664/4195 7109/7058/4195 7083/7033/4195 +f 9137/7664/4195 7083/7033/4195 9138/7665/4195 +f 7444/7353/4195 9137/7664/4195 9138/7665/4195 +f 7444/7353/4195 9138/7665/4195 7445/7354/4195 +f 7456/7366/4195 9139/7666/4195 9140/7667/4195 +f 7456/7366/4195 9140/7667/4195 7457/7367/4195 +f 9139/7666/4195 7079/7029/4195 7089/7039/4195 +f 9139/7666/4195 7089/7039/4195 9140/7667/4195 +f 9140/7667/4195 7089/7039/4195 7088/7038/4195 +f 9140/7667/4195 7088/7038/4195 9134/7661/4195 +f 7457/7367/4195 9140/7667/4195 9134/7661/4195 +f 7457/7367/4195 9134/7661/4195 7163/7101/4195 +f 7445/7354/4195 9138/7665/4195 9141/7668/4195 +f 7445/7354/4195 9141/7668/4195 7460/7370/4195 +f 9138/7665/4195 7083/7033/4195 7080/7030/4195 +f 9138/7665/4195 7080/7030/4195 9141/7668/4195 +f 9141/7668/4195 7080/7030/4195 7079/7029/4195 +f 9141/7668/4195 7079/7029/4195 9139/7666/4195 +f 7460/7370/4195 9141/7668/4195 9139/7666/4195 +f 7460/7370/4195 9139/7666/4195 7456/7366/4195 +f 7022/6978/4195 9136/7663/4195 9142/7669/4195 +f 7022/6978/4195 9142/7669/4195 7023/6979/4195 +f 9136/7663/4195 7435/7344/4195 7464/7374/4195 +f 9136/7663/4195 7464/7374/4195 9142/7669/4195 +f 9142/7669/4195 7464/7374/4195 7463/7373/4195 +f 9142/7669/4195 7463/7373/4195 9143/7670/4195 +f 7023/6979/4195 9142/7669/4195 9143/7670/4195 +f 7023/6979/4195 9143/7670/4195 7026/6982/4195 +f 7026/6982/4195 9143/7670/4195 9147/7671/4195 +f 7026/6982/4195 9147/7671/4195 7505/7417/4195 +f 9143/7670/4195 7463/7373/4195 7469/7380/4195 +f 9143/7670/4195 7469/7380/4195 9147/7671/4195 +f 9147/7671/4195 7193/7379/4243 9148/7672/4195 +f 7505/7417/4195 9147/7671/4195 9148/7672/4195 +f 7505/7417/4195 9148/7672/4195 7507/7419/4195 +f 7432/7341/4195 9133/7660/4195 9149/7673/4195 +f 7432/7341/4195 9149/7673/4195 7428/7337/4195 +f 9133/7660/4195 7193/7379/4243 7468/7378/4195 +f 9133/7660/4195 7468/7378/4195 9149/7673/4195 +f 9149/7673/4195 7468/7378/4195 7467/7377/4195 +f 9149/7673/4195 7467/7377/4195 9150/7674/4195 +f 7428/7337/4195 9149/7673/4195 9150/7674/4195 +f 7428/7337/4195 9150/7674/4195 7192/7126/4195 +f 7184/7119/4195 9151/7675/4195 9152/7676/4195 +f 7184/7119/4195 9152/7676/4195 7412/7319/4195 +f 9151/7675/4195 7474/7385/4195 7473/7384/4195 +f 9151/7675/4195 7473/7384/4195 9152/7676/4195 +f 9152/7676/4195 7473/7384/4195 7472/7383/4195 +f 9152/7676/4195 7472/7383/4195 9153/7677/4195 +f 7412/7319/4195 9152/7676/4195 9153/7677/4195 +f 7412/7319/4195 9153/7677/4195 7183/7118/4195 +f 7175/7111/4195 9154/7678/4195 9155/7679/4195 +f 7175/7111/4195 9155/7679/4195 7387/7292/4195 +f 9154/7678/4195 7480/7391/4195 7479/7390/4195 +f 9154/7678/4195 7479/7390/4195 9155/7679/4195 +f 9155/7679/4195 7479/7390/4195 7478/7389/4195 +f 9155/7679/4195 7478/7389/4195 9156/7680/4195 +f 7387/7292/4195 9155/7679/4195 9156/7680/4195 +f 7387/7292/4195 9156/7680/4195 7210/7134/4195 +f 7202/7127/4195 9157/7681/4195 9158/7682/4195 +f 7202/7127/4195 9158/7682/4195 7380/7287/4195 +f 9157/7681/4195 7487/7398/4195 7486/7397/4195 +f 9157/7681/4195 7486/7397/4195 9158/7682/4195 +f 9158/7682/4195 7486/7397/4195 7485/7396/4195 +f 9158/7682/4195 7485/7396/4195 9159/7683/4195 +f 7380/7287/4195 9158/7682/4195 9159/7683/4195 +f 7380/7287/4195 9159/7683/4195 7382/7289/4195 +f 7362/7276/4195 9160/7684/4195 9161/7685/4195 +f 7362/7276/4195 9161/7685/4195 7363/7277/4195 +f 9160/7684/4195 7496/7408/4195 7495/7407/4195 +f 9160/7684/4195 7495/7407/4195 9161/7685/4195 +f 9161/7685/4195 7495/7407/4195 7494/7406/4195 +f 9161/7685/4195 7494/7406/4195 9162/7686/4195 +f 7363/7277/4195 9161/7685/4195 9162/7686/4195 +f 7363/7277/4195 9162/7686/4195 7366/7280/4195 +f 7353/7270/4195 9163/7687/4195 9164/7688/4195 +f 7353/7270/4195 9164/7688/4195 7354/7271/4195 +f 9163/7687/4195 7502/7414/4195 7501/7413/4195 +f 9163/7687/4195 7501/7413/4195 9164/7688/4195 +f 9164/7688/4195 7501/7413/4195 7500/7412/4195 +f 9164/7688/4195 7500/7412/4195 9165/7689/4195 +f 7354/7271/4195 9164/7688/4195 9165/7689/4195 +f 7354/7271/4195 9165/7689/4195 7357/7274/4195 +f 7210/7134/4195 9156/7680/4195 9166/7690/4195 +f 7210/7134/4195 9166/7690/4195 7205/7130/4195 +f 9156/7680/4195 7478/7389/4195 7504/7416/4195 +f 9156/7680/4195 7504/7416/4195 9166/7690/4195 +f 9166/7690/4195 7504/7416/4195 7487/7398/4195 +f 9166/7690/4195 7487/7398/4195 9157/7681/4195 +f 7205/7130/4195 9166/7690/4195 9157/7681/4195 +f 7205/7130/4195 9157/7681/4195 7202/7127/4195 +f 7507/7419/4313 9167/7691/4314 7508/7420/4313 +f 7192/7126/4195 9150/7674/4195 9168/7692/4195 +f 7192/7126/4195 9168/7692/4195 7187/7122/4195 +f 9150/7674/4195 7467/7377/4195 7512/7422/4195 +f 9150/7674/4195 7512/7422/4195 9168/7692/4195 +f 9168/7692/4195 7512/7422/4195 7474/7385/4195 +f 9168/7692/4195 7474/7385/4195 9151/7675/4195 +f 7187/7122/4195 9168/7692/4195 9151/7675/4195 +f 7187/7122/4195 9151/7675/4195 7184/7119/4195 +f 7183/7118/4195 9153/7677/4195 9169/7693/4195 +f 7183/7118/4195 9169/7693/4195 7178/7114/4195 +f 9153/7677/4195 7472/7383/4195 7514/7424/4195 +f 9153/7677/4195 7514/7424/4195 9169/7693/4195 +f 9169/7693/4195 7514/7424/4195 7480/7391/4195 +f 9169/7693/4195 7480/7391/4195 9154/7678/4195 +f 7178/7114/4195 9169/7693/4195 9154/7678/4195 +f 7178/7114/4195 9154/7678/4195 7175/7111/4195 +f 7310/7694/4315 9170/7695/4316 7311/7696/4317 +f 7311/7696/4288 9082/7697/4318 7312/7627/4293 +f 7359/7698/4319 9172/7699/4320 7360/7700/4321 +f 7382/7289/4195 9159/7683/4195 9173/7701/4195 +f 7382/7289/4195 9173/7701/4195 7518/7428/4195 +f 9159/7683/4195 7485/7396/4195 7517/7427/4195 +f 9159/7683/4195 7517/7427/4195 9173/7701/4195 +f 9173/7701/4195 7517/7427/4195 7502/7414/4195 +f 9173/7701/4195 7502/7414/4195 9163/7687/4195 +f 7518/7428/4195 9173/7701/4195 9163/7687/4195 +f 7518/7428/4195 9163/7687/4195 7353/7270/4195 +f 7304/7224/4195 9105/7643/4195 9174/7702/4195 +f 7304/7224/4195 9174/7702/4195 7314/7230/4195 +f 9105/7643/4195 7529/7438/4195 7528/7437/4195 +f 9105/7643/4195 7528/7437/4195 9174/7702/4195 +f 9174/7702/4195 7528/7437/4195 7527/7436/4195 +f 9174/7702/4195 7527/7436/4195 9175/7703/4195 +f 7314/7230/4195 9174/7702/4195 9175/7703/4195 +f 7314/7230/4195 9175/7703/4195 7252/7175/4195 +f 7244/7167/4195 9176/7704/4195 9177/7705/4195 +f 7244/7167/4195 9177/7705/4195 7256/7179/4195 +f 9176/7704/4195 7536/7444/4195 7535/7443/4195 +f 9176/7704/4195 7535/7443/4195 9177/7705/4195 +f 9177/7705/4195 7535/7443/4195 7325/7242/4195 +f 9177/7705/4195 7325/7242/4195 9086/7631/4195 +f 7256/7179/4195 9177/7705/4195 9086/7631/4195 +f 7256/7179/4195 9086/7631/4195 7253/7176/4195 +f 7252/7175/4195 9175/7703/4195 9178/7706/4195 +f 7252/7175/4195 9178/7706/4195 7247/7170/4195 +f 9175/7703/4195 7527/7436/4195 7539/7447/4195 +f 9175/7703/4195 7539/7447/4195 9178/7706/4195 +f 9178/7706/4195 7539/7447/4195 7536/7444/4195 +f 9178/7706/4195 7536/7444/4195 9176/7704/4195 +f 7247/7170/4195 9178/7706/4195 9176/7704/4195 +f 7247/7170/4195 9176/7704/4195 7244/7167/4195 +f 7289/7635/4322 9179/7707/4323 7290/7708/4324 +f 7283/7206/4195 9180/7709/4195 9181/7710/4195 +f 7283/7206/4195 9181/7710/4195 7284/7207/4195 +f 9180/7709/4195 7297/7217/4195 7296/7216/4195 +f 9180/7709/4195 7296/7216/4195 9181/7710/4195 +f 9181/7710/4195 7296/7216/4195 7295/7215/4195 +f 9181/7710/4195 7295/7215/4195 9096/7638/4195 +f 7284/7207/4195 9181/7710/4195 9096/7638/4195 +f 7284/7207/4195 9096/7638/4195 7287/7210/4195 +f 7366/7280/4195 9162/7686/4195 9183/7711/4195 +f 7366/7280/4195 9183/7711/4195 7546/7454/4195 +f 9162/7686/4195 7494/7406/4195 7545/7453/4195 +f 9162/7686/4195 7545/7453/4195 9183/7711/4195 +f 9183/7711/4195 7545/7453/4195 7544/7452/4195 +f 9183/7711/4195 7544/7452/4195 9184/7712/4195 +f 7546/7454/4195 9183/7711/4195 9184/7712/4195 +f 7546/7454/4195 9184/7712/4195 7371/7282/4195 +f 7371/7282/4195 9184/7712/4195 9185/7713/4195 +f 7371/7282/4195 9185/7713/4195 7489/7400/4195 +f 9184/7712/4195 7544/7452/4195 7543/7451/4195 +f 9184/7712/4195 7543/7451/4195 9185/7713/4195 +f 9185/7713/4195 7543/7451/4195 7542/7450/4195 +f 9185/7713/4195 7542/7450/4195 9186/7714/4195 +f 7489/7400/4195 9185/7713/4195 9186/7714/4195 +f 7489/7400/4195 9186/7714/4195 7219/7142/4195 +f 7211/7135/4195 9187/7715/4195 9188/7716/4195 +f 7211/7135/4195 9188/7716/4195 7344/7261/4195 +f 9187/7715/4195 7551/7458/4195 7550/7457/4195 +f 9187/7715/4195 7550/7457/4195 9188/7716/4195 +f 9188/7716/4195 7550/7457/4195 7271/7194/4195 +f 9188/7716/4195 7271/7194/4195 9189/7717/4195 +f 7344/7261/4195 9188/7716/4195 9189/7717/4195 +f 7344/7261/4195 9189/7717/4195 7341/7258/4195 +f 7557/7463/4195 9190/7718/4195 9191/7719/4195 +f 7557/7463/4195 9191/7719/4195 7558/7464/4195 +f 9190/7718/4195 7270/7193/4195 7293/7213/4195 +f 9190/7718/4195 7293/7213/4195 9191/7719/4195 +f 9191/7719/4195 7293/7213/4195 7297/7217/4195 +f 9191/7719/4195 7297/7217/4195 9180/7709/4195 +f 7558/7464/4195 9191/7719/4195 9180/7709/4195 +f 7558/7464/4195 9180/7709/4195 7283/7206/4195 +f 7341/7258/4195 9189/7717/4195 9192/7720/4195 +f 7341/7258/4195 9192/7720/4195 7567/7471/4195 +f 9189/7717/4195 7271/7194/4195 7274/7197/4195 +f 9189/7717/4195 7274/7197/4195 9192/7720/4195 +f 9192/7720/4195 7274/7197/4195 7262/7185/4195 +f 9192/7720/4195 7262/7185/4195 9193/7721/4195 +f 7567/7471/4195 9192/7720/4195 9193/7721/4195 +f 7567/7471/4195 9193/7721/4195 7568/7472/4195 +f 7568/7472/4195 9193/7721/4195 9194/7722/4195 +f 7568/7472/4195 9194/7722/4195 7573/7477/4195 +f 9193/7721/4195 7262/7185/4195 7265/7188/4195 +f 9193/7721/4195 7265/7188/4195 9194/7722/4195 +f 9194/7722/4195 7265/7188/4195 7270/7193/4195 +f 9194/7722/4195 7270/7193/4195 9190/7718/4195 +f 7573/7477/4195 9194/7722/4195 9190/7718/4195 +f 7573/7477/4195 9190/7718/4195 7557/7463/4195 +f 7219/7142/4195 9186/7714/4195 9195/7723/4195 +f 7219/7142/4195 9195/7723/4195 7214/7138/4195 +f 9186/7714/4195 7542/7450/4195 7575/7480/4195 +f 9186/7714/4195 7575/7480/4195 9195/7723/4195 +f 9195/7723/4195 7575/7480/4195 7551/7458/4195 +f 9195/7723/4195 7551/7458/4195 9187/7715/4195 +f 7214/7138/4195 9195/7723/4195 9187/7715/4195 +f 7214/7138/4195 9187/7715/4195 7211/7135/4195 +f 7226/7149/4325 9196/7724/4326 7227/7150/4325 +f 7227/7150/4327 9088/7725/4328 7228/7151/4329 +f 7220/7143/4195 9098/7640/4195 9197/7726/4195 +f 7220/7143/4195 9197/7726/4195 7221/7144/4195 +f 9098/7640/4195 7303/7223/4195 7302/7222/4195 +f 9098/7640/4195 7302/7222/4195 9197/7726/4195 +f 9197/7726/4195 7302/7222/4195 7301/7221/4195 +f 9197/7726/4195 7301/7221/4195 9103/7641/4195 +f 7221/7144/4195 9197/7726/4195 9103/7641/4195 +f 7221/7144/4195 9103/7641/4195 7224/7147/4195 +f 7357/7274/4195 9165/7689/4195 9199/7727/4195 +f 7357/7274/4195 9199/7727/4195 7579/7484/4195 +f 9165/7689/4195 7500/7412/4195 7578/7483/4195 +f 9165/7689/4195 7578/7483/4195 9199/7727/4195 +f 9199/7727/4195 7578/7483/4195 7496/7408/4195 +f 9199/7727/4195 7496/7408/4195 9160/7684/4195 +f 7579/7484/4195 9199/7727/4195 9160/7684/4195 +f 7579/7484/4195 9160/7684/4195 7362/7276/4195 +f 8308/7728/4330 9171/7729/4331 7359/7698/4332 +f 7441/7350/4233 9227/7730/4333 9254/7731/4195 +f 7441/7350/4233 9254/7731/4195 7442/7351/4195 +f 9227/7730/4333 7446/7355/4234 7449/7358/4195 +f 9227/7730/4333 7449/7358/4195 9254/7731/4195 +f 9254/7731/4195 7449/7358/4195 7100/7050/4195 +f 9254/7731/4195 7100/7050/4195 9255/7732/4195 +f 7442/7351/4195 9254/7731/4195 9255/7732/4195 +f 7442/7351/4195 9255/7732/4195 7443/7352/4195 +f 9047/7620/4195 9256/7733/4195 9257/7734/4195 +f 9047/7620/4195 9257/7734/4195 9045/7618/4195 +f 9256/7733/4195 7108/7057/4195 7425/7333/4195 +f 9256/7733/4195 7425/7333/4195 9257/7734/4195 +f 9257/7734/4195 7425/7333/4195 7031/6984/4195 +f 9257/7734/4195 7031/6984/4195 9258/7735/4195 +f 9045/7618/4195 9257/7734/4195 9258/7735/4195 +f 9045/7618/4195 9258/7735/4195 9042/7615/4195 +f 7398/7304/4195 9259/7736/4195 9260/7737/4195 +f 7398/7304/4195 9260/7737/4195 7399/7305/4195 +f 9259/7736/4195 7039/6991/4195 7401/7307/4195 +f 9259/7736/4195 7401/7307/4195 9260/7737/4195 +f 9260/7737/4195 7121/7309/4334 9261/7738/4195 +f 7399/7305/4195 9260/7737/4195 9261/7738/4195 +f 7399/7305/4195 9261/7738/4195 7132/7072/4195 +f 7132/7072/4195 9261/7738/4195 9262/7739/4195 +f 7132/7072/4195 9262/7739/4195 7133/7073/4195 +f 9261/7738/4195 7124/7740/4335 9262/7739/4195 +f 7443/7352/4195 9255/7732/4195 9263/7741/4195 +f 7443/7352/4195 9263/7741/4195 9130/7657/4195 +f 9255/7732/4195 7100/7050/4195 7103/7053/4195 +f 9255/7732/4195 7103/7053/4195 9263/7741/4195 +f 9263/7741/4195 7103/7053/4195 7108/7057/4195 +f 9263/7741/4195 7108/7057/4195 9256/7733/4195 +f 9130/7657/4195 9263/7741/4195 9256/7733/4195 +f 9130/7657/4195 9256/7733/4195 9047/7620/4195 +f 9042/7615/4195 9258/7735/4195 9264/7742/4195 +f 9042/7615/4195 9264/7742/4195 9126/7654/4195 +f 9258/7735/4195 7031/6984/4195 7034/6987/4195 +f 9258/7735/4195 7034/6987/4195 9264/7742/4195 +f 9264/7742/4195 7034/6987/4195 7039/6991/4195 +f 9264/7742/4195 7039/6991/4195 9259/7736/4195 +f 9126/7654/4195 9264/7742/4195 9259/7736/4195 +f 9126/7654/4195 9259/7736/4195 7398/7304/4195 +f 6875/7743/4336 6874/6827/4149 9265/7744/4149 +f 6874/6827/4149 6873/6826/4149 9266/7745/4149 +f 6874/6827/4149 9266/7745/4149 9265/7744/4149 +f 9265/7744/4149 9266/7745/4149 6535/6531/4149 +f 9265/7744/4149 6535/6531/4149 6877/6830/4149 +f 8836/7746/4336 9265/7744/4149 6877/6830/4149 +f 8842/7503/4149 8845/7506/4149 9267/7747/4149 +f 8842/7503/4149 9267/7747/4149 9268/7748/4149 +f 8845/7506/4149 8847/7508/4149 9269/7749/4149 +f 8845/7506/4149 9269/7749/4149 9267/7747/4149 +f 9267/7747/4149 9269/7749/4149 6466/6465/4149 +f 9267/7747/4149 6466/6465/4149 6857/6813/4149 +f 9268/7748/4149 9267/7747/4149 6857/6813/4149 +f 9268/7748/4149 6857/6813/4149 6539/6535/4149 +f 8854/7509/4149 8857/7512/4149 9270/7750/4149 +f 8854/7509/4149 9270/7750/4149 9271/7751/4149 +f 8857/7512/4149 6570/6559/4149 9272/7752/4149 +f 8857/7512/4149 9272/7752/4149 9270/7750/4149 +f 9270/7750/4149 9272/7752/4149 6556/6549/4149 +f 9270/7750/4149 6556/6549/4149 6835/6793/4149 +f 9271/7751/4149 9270/7750/4149 6835/6793/4149 +f 9271/7751/4149 6835/6793/4149 6470/6469/4149 +f 6570/6559/4149 6569/6558/4149 9273/7753/4149 +f 6570/6559/4149 9273/7753/4149 9272/7752/4149 +f 6569/6558/4149 9229/7754/4337 9273/7753/4149 +f 9273/7753/4149 6560/7755/4338 6557/6550/4149 +f 9272/7752/4149 9273/7753/4149 6557/6550/4149 +f 9272/7752/4149 6557/6550/4149 6556/6549/4149 +f 6873/6826/4149 8943/7542/4149 9274/7756/4149 +f 6873/6826/4149 9274/7756/4149 9266/7745/4149 +f 8943/7542/4149 8842/7503/4149 9268/7748/4149 +f 8943/7542/4149 9268/7748/4149 9274/7756/4149 +f 9274/7756/4149 9268/7748/4149 6539/6535/4149 +f 9274/7756/4149 6539/6535/4149 6536/6532/4149 +f 9266/7745/4149 9274/7756/4149 6536/6532/4149 +f 9266/7745/4149 6536/6532/4149 6535/6531/4149 +f 8847/7508/4149 8938/7536/4149 9275/7757/4149 +f 8847/7508/4149 9275/7757/4149 9269/7749/4149 +f 8938/7536/4149 8854/7509/4149 9271/7751/4149 +f 8938/7536/4149 9271/7751/4149 9275/7757/4149 +f 9275/7757/4149 9271/7751/4149 6470/6469/4149 +f 9275/7757/4149 6470/6469/4149 6467/6466/4149 +f 9269/7749/4149 9275/7757/4149 6467/6466/4149 +f 9269/7749/4149 6467/6466/4149 6466/6465/4149 +s 1 +f 6458/6458/4149 6461/6592/4158 6462/6461/4174 +f 6459/6459/4149 6462/6461/4174 6463/6462/4339 +f 6468/6467/4149 6471/6470/4149 6472/7758/4340 +f 6468/6467/4149 6472/7758/4340 6473/7759/4341 +f 6469/6468/4149 6468/6467/4149 6473/7759/4341 +f 6469/6468/4149 6473/7759/4341 6474/7760/4342 +f 6494/6490/4149 6497/6503/4152 6498/6493/4343 +f 6495/6491/4149 6498/6493/4343 6499/6494/4344 +f 6504/6499/4149 6507/6502/4149 6497/6503/4152 +f 6507/6502/4149 6513/6509/4345 6497/6503/4152 +f 6537/6533/4149 6540/6536/4149 6541/7761/4346 +f 6537/6533/4149 6541/7761/4346 6542/7762/4347 +f 6538/6534/4149 6537/6533/4149 6542/7762/4347 +f 6538/6534/4149 6542/7762/4347 6543/7763/4348 +f 6557/6550/4149 6560/7755/4349 6561/6553/4350 +f 6558/6551/4149 6561/6553/4350 6562/7764/4351 +f 6558/6551/4149 6562/7764/4351 6563/7765/4352 +f 6559/6552/4149 6558/6551/4149 6563/7765/4352 +f 6559/6552/4149 6563/7765/4352 6564/7766/4353 +f 6500/6495/4149 6499/6494/4344 6567/6556/4354 +f 6565/6554/4149 6567/6556/4354 6568/6557/4355 +f 6599/6588/4149 6602/6832/4356 6603/6591/4357 +f 6600/6589/4149 6603/6591/4357 6461/6592/4158 +f 6612/6601/4149 6615/6604/4149 6616/7767/4358 +f 6612/6601/4149 6616/7767/4358 6617/7768/4358 +f 6613/6602/4149 6612/6601/4149 6617/7768/4358 +f 6613/6602/4149 6617/7768/4358 6618/7769/4359 +f 6621/6607/4149 6624/6610/4149 6625/7770/4360 +f 6621/6607/4149 6625/7770/4360 6626/7537/4266 +f 6622/6608/4149 6621/6607/4149 6626/7537/4266 +f 6622/6608/4149 6626/7537/4266 6627/7539/4361 +f 6629/6612/4149 6632/6889/4362 6633/6615/4363 +f 6630/6613/4149 6633/6615/4363 6634/7771/4364 +f 6630/6613/4149 6634/7771/4364 6635/7772/4365 +f 6631/6614/4149 6630/6613/4149 6635/7772/4365 +f 6631/6614/4149 6635/7772/4365 6636/7773/4366 +f 6639/6618/4149 6642/6621/4149 6643/7774/4359 +f 6639/6618/4149 6643/7774/4359 6644/7775/4168 +f 6640/6619/4149 6639/6618/4149 6644/7775/4168 +f 6640/6619/4149 6644/7775/4168 6645/7776/4168 +f 6648/6624/4149 6651/6627/4149 6652/7777/4367 +f 6648/6624/4149 6652/7777/4367 6653/7778/4368 +f 6649/6625/4149 6648/6624/4149 6653/7778/4368 +f 6649/6625/4149 6653/7778/4368 6654/7779/4369 +f 6657/6630/4149 6660/6633/4149 6661/6634/4160 +f 6681/6654/4149 6684/6657/4149 6685/6658/4370 +f 6719/6692/4149 6722/6946/4186 6723/6695/4162 +f 6720/6693/4149 6723/6695/4371 6724/6696/4344 +f 6740/6712/4149 6743/6914/4160 6744/6715/4163 +f 6741/6713/4149 6744/6715/4372 6745/7780/4373 +f 6741/6713/4149 6745/7780/4373 6746/7781/4374 +f 6742/6714/4149 6741/6713/4149 6746/7781/4374 +f 6742/6714/4149 6746/7781/4374 6747/7782/4357 +f 6749/6717/4149 6742/6714/4149 6747/7782/4357 +f 6749/6717/4149 6747/7782/4357 6750/7783/4375 +f 6684/6657/4149 6749/6717/4149 6750/7783/4375 +f 6684/6657/4149 6750/7783/4375 6685/6658/4370 +f 6778/6745/4149 6649/6625/4149 6654/7779/4369 +f 6778/6745/4149 6654/7779/4369 6780/7784/4376 +f 6779/6746/4149 6778/6745/4149 6780/7784/4376 +f 6779/6746/4149 6780/7784/4376 6781/6947/4377 +f 6789/6754/4149 6792/6900/4271 6793/6757/4378 +f 6790/6755/4149 6793/6757/4164 6794/6758/4164 +f 6798/6762/4149 6801/6965/4165 6802/6765/4165 +f 6799/6763/4149 6802/6765/4165 6803/6766/4179 +f 6807/6770/4149 6810/6930/4379 6811/6773/4167 +f 6808/6771/4149 6811/6773/4167 6812/7785/4380 +f 6808/6771/4149 6812/7785/4380 6813/7786/4381 +f 6809/6772/4149 6808/6771/4149 6813/7786/4381 +f 6809/6772/4149 6813/7786/4381 6814/7787/4382 +f 6640/6619/4149 6645/7776/4168 6817/6776/4383 +f 6815/6774/4149 6817/6776/4383 6818/6777/4169 +f 6822/6781/4149 6613/6602/4149 6618/7769/4359 +f 6822/6781/4149 6618/7769/4359 6823/7788/4359 +f 6642/6621/4149 6822/6781/4149 6823/7788/4359 +f 6642/6621/4149 6823/7788/4359 6643/7774/4359 +f 6836/6794/4149 6559/6552/4149 6564/7766/4353 +f 6836/6794/4149 6564/7766/4353 6837/7789/4384 +f 6471/6470/4149 6836/6794/4149 6837/7789/4384 +f 6471/6470/4149 6837/7789/4384 6472/7758/4340 +f 6845/6802/4149 6622/6608/4149 6627/7539/4361 +f 6845/6802/4149 6627/7539/4361 6846/7790/4385 +f 6615/6604/4149 6845/6802/4149 6846/7790/4385 +f 6615/6604/4149 6846/7790/4385 6616/7767/4358 +f 6858/6814/4149 6469/6468/4149 6474/7760/4342 +f 6858/6814/4149 6474/7760/4342 6859/7791/4386 +f 6540/6536/4149 6858/6814/4149 6859/7791/4386 +f 6540/6536/4149 6859/7791/4386 6541/7761/4346 +f 6861/6816/4149 6631/6614/4149 6636/7773/4366 +f 6861/6816/4149 6636/7773/4366 6862/7792/4387 +f 6624/6610/4149 6861/6816/4149 6862/7792/4387 +f 6624/6610/4149 6862/7792/4387 6625/7770/4360 +f 6867/6821/4388 6869/6823/4149 6870/6828/4389 +f 6870/6828/4389 6874/6827/4149 6875/7743/4172 +f 6876/6829/4390 6878/6831/4149 6879/7793/4391 +f 6878/6831/4149 6538/6534/4149 6543/7763/4348 +f 6878/6831/4149 6543/7763/4348 6880/7794/4392 +f 6879/7793/4391 6878/6831/4149 6880/7794/4392 +f 6879/7793/4391 6880/7794/4392 6881/7795/4393 +f 6602/6832/4356 6882/6833/4149 6883/6837/4394 +f 6883/6837/4394 6886/6836/4149 6887/6838/4395 +f 6887/6838/4395 6888/6839/4149 6889/6841/4396 +f 6889/6841/4396 6868/6822/4149 6867/6821/4388 +f 6920/6871/4149 6809/6772/4149 6814/7787/4382 +f 6920/6871/4149 6814/7787/4382 6921/7796/4397 +f 6651/6627/4149 6920/6871/4149 6921/7796/4397 +f 6651/6627/4149 6921/7796/4397 6652/7777/4367 +f 6464/6463/4149 6463/6462/4339 6938/6888/4176 +f 6936/6886/4149 6938/6888/4176 6632/6889/4362 +f 6819/6778/4149 6818/6777/4169 6948/6899/4169 +f 6946/6897/4149 6948/6899/4398 6792/6900/4271 +f 6662/6635/4149 6661/6634/4399 6961/6913/4400 +f 6959/6911/4149 6961/6913/4400 6743/6914/4401 +f 6804/6767/4149 6803/6766/4179 6976/6929/4402 +f 6974/6927/4149 6976/6929/4402 6810/6930/4379 +f 6989/6943/4181 6991/7797/4403 6992/6945/4344 +f 6990/6944/4149 6992/6945/4344 6722/6946/4404 +f 6795/6759/4149 6794/6758/4164 7009/6964/4164 +f 7007/6962/4149 7009/6964/4405 6801/6965/4165 +f 7024/6980/4195 7027/6983/4195 7028/7798/4406 +f 7024/6980/4195 7028/7798/4406 7029/7799/4407 +f 7025/6981/4195 7024/6980/4195 7029/7799/4407 +f 7025/6981/4195 7029/7799/4407 7030/7800/4408 +f 7032/6985/4195 7035/7335/4409 7036/6988/4410 +f 7033/6986/4195 7036/6988/4410 7037/6989/4411 +f 7060/7012/4195 7063/7015/4195 7064/7801/4412 +f 7060/7012/4195 7064/7801/4412 7065/7802/4217 +f 7061/7013/4195 7060/7012/4195 7065/7802/4217 +f 7061/7013/4195 7065/7802/4217 7066/7020/4198 +f 7069/7018/4195 7061/7013/4195 7066/7020/4198 +f 7101/7051/4195 7104/7360/4413 7105/7054/4414 +f 7102/7052/4195 7105/7054/4414 7106/7055/4415 +f 7121/7309/4416 7122/7308/4223 7123/7803/4417 +f 7121/7309/4416 7123/7803/4417 7124/7740/4418 +f 7122/7308/4223 7125/7804/4419 7126/7805/4420 +f 7122/7308/4223 7126/7805/4420 7123/7803/4417 +f 7123/7803/4417 7126/7805/4420 7127/7806/4421 +f 7123/7803/4417 7127/7806/4421 7128/7807/4422 +f 7124/7740/4418 7123/7803/4417 7128/7807/4422 +f 7124/7740/4418 7128/7807/4422 7129/7808/4423 +f 7131/7071/4195 7133/7073/4195 7134/7809/4424 +f 7131/7071/4195 7134/7809/4424 7135/7810/4294 +f 7063/7015/4195 7131/7071/4195 7135/7810/4294 +f 7063/7015/4195 7135/7810/4294 7064/7801/4412 +f 7165/7103/4195 7025/6981/4195 7030/7800/4408 +f 7165/7103/4195 7030/7800/4408 7167/7811/4425 +f 7166/7104/4195 7165/7103/4195 7167/7811/4425 +f 7166/7104/4195 7167/7811/4425 7168/7361/4426 +f 7176/7112/4195 7179/7294/4219 7180/7115/4204 +f 7177/7113/4195 7180/7115/4427 7181/7116/4428 +f 7185/7120/4195 7188/7321/4429 7189/7123/4430 +f 7186/7121/4195 7189/7123/4205 7190/7124/4206 +f 7193/7379/4431 7194/7812/4432 7195/7813/4433 +f 7193/7379/4431 7195/7813/4433 7196/7814/4434 +f 7194/7812/4432 7197/7815/4435 7198/7816/4436 +f 7194/7812/4432 7198/7816/4436 7195/7813/4433 +f 7195/7813/4433 7198/7816/4436 7199/7817/4437 +f 7195/7813/4433 7199/7817/4437 7200/7818/4438 +f 7196/7814/4434 7195/7813/4433 7200/7818/4438 +f 7196/7814/4434 7200/7818/4438 7201/7819/4439 +f 7203/7128/4195 7206/7623/4440 7207/7131/4207 +f 7204/7129/4195 7207/7131/4207 7208/7132/4441 +f 7212/7136/4195 7215/7263/4442 7216/7139/4443 +f 7213/7137/4195 7216/7139/4443 7217/7140/4252 +f 7222/7145/4195 7225/7148/4195 7226/7149/4444 +f 7246/7169/4195 7249/7172/4445 7250/7173/4446 +f 7285/7208/4195 7288/7211/4195 7289/7635/4447 +f 7285/7208/4195 7289/7635/4447 7290/7708/4447 +f 7286/7209/4195 7285/7208/4195 7290/7708/4447 +f 7286/7209/4195 7290/7708/4447 7291/7820/4322 +f 7305/7225/4195 7308/7232/4448 7309/7228/4408 +f 7306/7226/4195 7309/7228/4408 7310/7694/4449 +f 7306/7226/4195 7310/7694/4449 7311/7696/4450 +f 7307/7227/4195 7306/7226/4195 7311/7696/4450 +f 7307/7227/4195 7311/7696/4450 7312/7627/4210 +f 7251/7174/4195 7250/7173/4446 7315/7231/4451 +f 7313/7229/4195 7315/7231/4451 7308/7232/4448 +f 7342/7259/4195 7345/7469/4250 7346/7262/4452 +f 7343/7260/4195 7346/7262/4452 7215/7263/4442 +f 7355/7272/4453 7358/7275/4454 7359/7698/4319 +f 7355/7272/4453 7359/7698/4319 7360/7700/4455 +f 7356/7273/4195 7355/7272/4453 7360/7700/4455 +f 7356/7273/4195 7360/7700/4455 7361/7644/4456 +f 7364/7278/4195 7367/7281/4195 7368/7821/4457 +f 7364/7278/4195 7368/7821/4457 7369/7822/4458 +f 7365/7279/4195 7364/7278/4195 7369/7822/4458 +f 7365/7279/4195 7369/7822/4458 7370/7823/4459 +f 7372/7283/4195 7375/7402/4245 7376/7286/4460 +f 7373/7284/4195 7376/7286/4460 7377/7824/4461 +f 7373/7284/4195 7377/7824/4461 7378/7825/4462 +f 7374/7285/4195 7373/7284/4195 7378/7825/4462 +f 7374/7285/4195 7378/7825/4462 7379/7826/4463 +f 7381/7288/4195 7383/7290/4195 7384/7827/4464 +f 7381/7288/4195 7384/7827/4464 7385/7647/4207 +f 7203/7128/4195 7381/7288/4195 7385/7647/4207 +f 7203/7128/4195 7385/7647/4207 7206/7623/4440 +f 7209/7133/4195 7208/7132/4441 7388/7293/4465 +f 7386/7291/4195 7388/7293/4441 7179/7294/4441 +f 7039/6991/4466 7038/6990/4467 7400/7306/4468 +f 7038/6990/4467 7037/6989/4197 7402/7607/4469 +f 7038/6990/4467 7402/7607/4469 7400/7306/4468 +f 7400/7306/4468 7402/7607/4469 7125/7804/4419 +f 7400/7306/4468 7125/7804/4419 7122/7308/4223 +f 7401/7307/4470 7400/7306/4468 7122/7308/4223 +f 7182/7117/4195 7181/7116/4428 7413/7320/4429 +f 7411/7318/4195 7413/7320/4204 7188/7321/4225 +f 7107/7056/4195 7106/7055/4415 7426/7334/4471 +f 7424/7332/4195 7426/7334/4471 7035/7335/4409 +f 7191/7125/4195 7190/7124/4472 7429/7338/4473 +f 7427/7336/4195 7429/7338/4473 7430/7339/4474 +f 7447/7356/4235 7450/7828/4475 7451/7359/4476 +f 7448/7357/4195 7451/7359/4476 7104/7360/4413 +f 7466/7376/4195 7468/7378/4195 7193/7379/4477 +f 7218/7141/4195 7217/7140/4252 7490/7401/4478 +f 7488/7399/4195 7490/7401/4478 7375/7402/4245 +f 7506/7418/4195 7508/7420/4477 7509/7829/4479 +f 7506/7418/4195 7509/7829/4479 7510/7830/4480 +f 7027/6983/4195 7506/7418/4195 7510/7830/4480 +f 7027/6983/4195 7510/7830/4480 7028/7798/4406 +f 7519/7429/4195 7356/7273/4195 7361/7644/4456 +f 7519/7429/4195 7361/7644/4456 7520/7646/4481 +f 7383/7290/4195 7519/7429/4195 7520/7646/4481 +f 7383/7290/4195 7520/7646/4481 7384/7827/4464 +f 7532/7441/4195 7307/7227/4195 7312/7627/4210 +f 7532/7441/4195 7312/7627/4210 7533/7629/4482 +f 7225/7148/4195 7532/7441/4195 7533/7629/4482 +f 7225/7148/4195 7533/7629/4482 7226/7149/4444 +f 7547/7455/4195 7374/7285/4195 7379/7826/4463 +f 7547/7455/4195 7379/7826/4463 7548/7831/4483 +f 7367/7281/4195 7547/7455/4195 7548/7831/4483 +f 7367/7281/4195 7548/7831/4483 7368/7821/4457 +f 7553/7460/4484 7555/7462/4195 7556/7466/4485 +f 7556/7466/4485 7559/7465/4195 7560/7467/4486 +f 7560/7467/4486 7561/7468/4195 7562/7832/4487 +f 7561/7468/4195 7286/7209/4195 7291/7820/4322 +f 7561/7468/4195 7291/7820/4322 7563/7833/4324 +f 7562/7832/4487 7561/7468/4195 7563/7833/4324 +f 7562/7832/4487 7563/7833/4324 7564/7834/4488 +f 7345/7469/4250 7565/7470/4195 7566/7474/4489 +f 7566/7474/4489 7569/7473/4195 7570/7475/4490 +f 7570/7475/4490 7571/7476/4195 7572/7478/4491 +f 7572/7478/4491 7554/7461/4195 7553/7460/4484 +f 7580/7485/4195 7365/7279/4195 7370/7823/4459 +f 7580/7485/4195 7370/7823/4459 7581/7835/4492 +f 7358/7275/4454 7580/7485/4195 7581/7835/4492 +f 7358/7275/4454 7581/7835/4492 7359/7698/4319 +f 7288/7211/4195 7593/7497/4195 7289/7635/4447 +f 7594/7836/4493 7595/7837/4494 7596/7838/4495 +f 7594/7836/4493 7596/7838/4495 7597/7839/4496 +f 7598/7840/4497 7599/7841/4498 7600/7842/4499 +f 7598/7840/4497 7600/7842/4499 7601/7843/4500 +f 7601/7843/4500 7600/7842/4499 7602/7844/4501 +f 7601/7843/4500 7602/7844/4501 7603/7845/4502 +f 7597/7839/4496 7596/7838/4495 7604/7846/4502 +f 7597/7839/4496 7604/7846/4502 7605/7847/4503 +f 7606/7848/4504 7607/7849/4505 7608/7850/4506 +f 7606/7848/4504 7608/7850/4506 7609/7851/4507 +f 7610/7852/4505 7611/7853/4508 7612/7854/4509 +f 7610/7852/4505 7612/7854/4509 7613/7855/4510 +f 7613/7855/4510 7612/7854/4509 7614/7856/4511 +f 7613/7855/4510 7614/7856/4511 7615/7857/4512 +f 7609/7851/4507 7608/7850/4506 7616/7858/4513 +f 7609/7851/4507 7616/7858/4513 7617/7859/4514 +f 7618/7860/4515 7619/7861/4516 7620/7862/4517 +f 7618/7860/4515 7620/7862/4517 7621/7863/4518 +f 7622/7864/4519 7623/7865/4520 7624/7866/4521 +f 7622/7864/4519 7624/7866/4521 7625/7867/4517 +f 7625/7867/4517 7624/7866/4521 7626/7868/4522 +f 7625/7867/4517 7626/7868/4522 7627/7869/4523 +f 7621/7863/4518 7620/7862/4517 7628/7870/4524 +f 7621/7863/4518 7628/7870/4524 7629/7871/4525 +f 7630/7872/4526 7631/7873/4527 7632/7874/4528 +f 7630/7872/4526 7632/7874/4528 7633/7875/4529 +f 7634/7876/4527 7635/7877/4530 7636/7878/4531 +f 7634/7876/4527 7636/7878/4531 7637/7879/4532 +f 7637/7879/4532 7636/7878/4531 7638/7880/4533 +f 7637/7879/4532 7638/7880/4533 7639/7881/4534 +f 7633/7875/4529 7632/7874/4528 7640/7882/4535 +f 7633/7875/4529 7640/7882/4535 7641/7883/4536 +f 7642/7884/4537 7643/7885/4538 7644/7886/4539 +f 7642/7884/4537 7644/7886/4539 7645/7887/4540 +f 7646/7888/4541 7647/7889/4542 7648/7890/4543 +f 7646/7888/4541 7648/7890/4543 7649/7891/4539 +f 7650/7892/4539 7651/7893/4543 7652/7894/4544 +f 7650/7892/4539 7652/7894/4544 7653/7895/4545 +f 7645/7887/4540 7644/7886/4539 7654/7896/4546 +f 7645/7887/4540 7654/7896/4546 7655/7897/4547 +f 7656/7898/4548 7657/7899/4549 7658/7900/4550 +f 7656/7898/4548 7658/7900/4550 7659/7901/4551 +f 7660/7902/4549 7661/7903/4552 7662/7904/4553 +f 7660/7902/4549 7662/7904/4553 7663/7905/4550 +f 7663/7905/4550 7662/7904/4553 7664/7906/4554 +f 7663/7905/4550 7664/7906/4554 7665/7907/4555 +f 7659/7901/4551 7658/7900/4550 7666/7908/4556 +f 7659/7901/4551 7666/7908/4556 7667/7909/4557 +f 7668/7910/4558 7669/7911/4559 7670/7912/4560 +f 7668/7910/4558 7670/7912/4560 7671/7913/4561 +f 7672/7914/4562 7673/7915/4563 7674/7916/4564 +f 7672/7914/4562 7674/7916/4564 7675/7917/4565 +f 7675/7917/4565 7674/7916/4564 7676/7918/4566 +f 7675/7917/4565 7676/7918/4566 7677/7919/4567 +f 7671/7913/4561 7670/7912/4560 7678/7920/4568 +f 7671/7913/4561 7678/7920/4568 7679/7921/4569 +f 7680/7922/4570 7681/7923/4571 7682/7924/4572 +f 7680/7922/4570 7682/7924/4572 7683/7925/4573 +f 7684/7926/4574 7685/7927/4575 7686/7928/4576 +f 7684/7926/4574 7686/7928/4576 7687/7929/4577 +f 7687/7929/4577 7686/7928/4576 7688/7930/4578 +f 7687/7929/4577 7688/7930/4578 7689/7931/4579 +f 7683/7925/4573 7682/7924/4572 7690/7932/4580 +f 7683/7925/4573 7690/7932/4580 7691/7933/4581 +f 7692/7934/4582 7693/7935/4583 7694/7936/4584 +f 7692/7934/4582 7694/7936/4584 7695/7937/4585 +f 7696/7938/4586 7697/7939/4587 7698/7940/4588 +f 7696/7938/4586 7698/7940/4588 7699/7941/4589 +f 7699/7941/4589 7698/7940/4588 7700/7942/4590 +f 7699/7941/4589 7700/7942/4590 7701/7943/4591 +f 7695/7937/4585 7694/7936/4584 7702/7944/4592 +f 7695/7937/4585 7702/7944/4592 7703/7945/4593 +f 7704/7946/4594 7705/7947/4595 7706/7948/4596 +f 7704/7946/4594 7706/7948/4596 7707/7949/4597 +f 7708/7950/4595 7709/7951/4598 7710/7952/4599 +f 7708/7950/4595 7710/7952/4599 7711/7953/4600 +f 7711/7953/4600 7710/7952/4599 7712/7954/4601 +f 7711/7953/4600 7712/7954/4601 7713/7955/4602 +f 7707/7949/4597 7706/7948/4596 7714/7956/4603 +f 7707/7949/4597 7714/7956/4603 7715/7957/4604 +f 7716/7958/4605 7717/7959/4606 7718/7960/4607 +f 7716/7958/4605 7718/7960/4607 7719/7961/4608 +f 7720/7962/4609 7721/7963/4610 7722/7964/4611 +f 7720/7962/4609 7722/7964/4611 7723/7965/4612 +f 7723/7965/4612 7722/7964/4611 7611/7853/4508 +f 7723/7965/4612 7611/7853/4508 7610/7852/4505 +f 7719/7961/4608 7718/7960/4607 7607/7849/4505 +f 7719/7961/4608 7607/7849/4505 7606/7848/4504 +f 7724/7966/4613 7725/7967/4614 7726/7968/4615 +f 7724/7966/4613 7726/7968/4615 7727/7969/4616 +f 7728/7970/4617 7729/7971/4618 7730/7972/4619 +f 7728/7970/4617 7730/7972/4619 7731/7973/4620 +f 7731/7973/4620 7730/7972/4619 7635/7877/4530 +f 7731/7973/4620 7635/7877/4530 7634/7876/4527 +f 7727/7969/4616 7726/7968/4615 7631/7873/4527 +f 7727/7969/4616 7631/7873/4527 7630/7872/4526 +f 7732/7974/4621 7733/7975/4622 7734/7976/4623 +f 7732/7974/4621 7734/7976/4623 7735/7977/4624 +f 7736/7978/4625 7737/7979/4626 7738/7980/4627 +f 7736/7978/4625 7738/7980/4627 7739/7981/4623 +f 7740/7982/4623 7741/7983/4627 7742/7984/4628 +f 7740/7982/4623 7742/7984/4628 7743/7985/4629 +f 7735/7977/4624 7734/7976/4623 7744/7986/4630 +f 7735/7977/4624 7744/7986/4630 7745/7987/4631 +f 7746/7988/4632 7747/7989/4633 7748/7990/4634 +f 7746/7988/4632 7748/7990/4634 7749/7991/4635 +f 7750/7992/4636 7751/7993/4637 7752/7994/4638 +f 7750/7992/4636 7752/7994/4638 7753/7995/4634 +f 7753/7995/4634 7752/7994/4638 7754/7996/4639 +f 7753/7995/4634 7754/7996/4639 7755/7997/4640 +f 7749/7991/4635 7748/7990/4634 7756/7998/4641 +f 7749/7991/4635 7756/7998/4641 7757/7999/4642 +f 7758/8000/4643 7759/8001/4644 7760/8002/4645 +f 7758/8000/4643 7760/8002/4645 7761/8003/4646 +f 7762/8004/4647 7763/8005/4648 7764/8006/4649 +f 7762/8004/4647 7764/8006/4649 7765/8007/4650 +f 7765/8007/4650 7764/8006/4649 7766/8008/4651 +f 7765/8007/4650 7766/8008/4651 7767/8009/4652 +f 7761/8003/4646 7760/8002/4645 7768/8010/4653 +f 7761/8003/4646 7768/8010/4653 7769/8011/4654 +f 7770/8012/4655 7771/8013/4656 7772/8014/4657 +f 7770/8012/4655 7772/8014/4657 7773/8015/4658 +f 7774/8016/4659 7775/8017/4660 7776/8018/4661 +f 7774/8016/4659 7776/8018/4661 7777/8019/4662 +f 7777/8019/4662 7776/8018/4661 7599/7841/4498 +f 7777/8019/4662 7599/7841/4498 7598/7840/4497 +f 7773/8015/4658 7772/8014/4657 7595/7837/4494 +f 7773/8015/4658 7595/7837/4494 7594/7836/4493 +f 7641/7883/4536 7640/7882/4535 7778/8020/4663 +f 7641/7883/4536 7778/8020/4663 7779/8021/4664 +f 7639/7881/4534 7638/7880/4533 7780/8022/4665 +f 7639/7881/4534 7780/8022/4665 7781/8023/4666 +f 7781/8023/4666 7780/8022/4665 7685/7927/4575 +f 7781/8023/4666 7685/7927/4575 7684/7926/4574 +f 7779/8021/4664 7778/8020/4663 7681/7923/4571 +f 7779/8021/4664 7681/7923/4571 7680/7922/4570 +f 7715/7957/4604 7714/7956/4603 7782/8024/4667 +f 7715/7957/4604 7782/8024/4667 7783/8025/4668 +f 7713/7955/4602 7712/7954/4601 7784/8026/4669 +f 7713/7955/4602 7784/8026/4669 7785/8027/4670 +f 7786/8028/4671 7787/8029/4669 7788/8030/4637 +f 7786/8028/4671 7788/8030/4637 7789/8031/4672 +f 7783/8025/4668 7782/8024/4667 7747/7989/4633 +f 7783/8025/4668 7747/7989/4633 7746/7988/4632 +f 7757/7999/4642 7756/7998/4641 7790/8032/4673 +f 7757/7999/4642 7790/8032/4673 7791/8033/4674 +f 7792/8034/4641 7793/8035/4675 7794/8036/4676 +f 7792/8034/4641 7794/8036/4676 7795/8037/4673 +f 7790/8032/4673 7796/8038/4676 7797/8039/4677 +f 7790/8032/4673 7797/8039/4677 7798/8040/4678 +f 7791/8033/4674 7790/8032/4673 7798/8040/4678 +f 7791/8033/4674 7798/8040/4678 7799/8041/4679 +f 7800/8042/4680 7801/8043/4681 7802/8044/4682 +f 7800/8042/4680 7802/8044/4682 7803/8045/4683 +f 7804/8046/4684 7805/8047/4685 7806/8048/4686 +f 7804/8046/4684 7806/8048/4686 7807/8049/4687 +f 7807/8049/4687 7806/8048/4686 7808/8050/4688 +f 7807/8049/4687 7808/8050/4688 7809/8051/4689 +f 7803/8045/4683 7802/8044/4682 7810/8052/4689 +f 7803/8045/4683 7810/8052/4689 7811/8053/4690 +f 7812/8054/4691 7813/8055/4692 7814/8056/4693 +f 7812/8054/4691 7814/8056/4693 7815/8057/4694 +f 7816/8058/4695 7817/8059/4696 7818/8060/4697 +f 7816/8058/4695 7818/8060/4697 7819/8061/4698 +f 7819/8061/4698 7818/8060/4697 7763/8005/4648 +f 7819/8061/4698 7763/8005/4648 7762/8004/4647 +f 7815/8057/4694 7814/8056/4693 7759/8001/4644 +f 7815/8057/4694 7759/8001/4644 7758/8000/4643 +f 7820/8062/4699 7821/8063/4700 7822/8064/4701 +f 7820/8062/4699 7822/8064/4701 7823/8065/4702 +f 7824/8066/4703 7825/8067/4704 7826/8068/4705 +f 7824/8066/4703 7826/8068/4705 7827/8069/4701 +f 7827/8069/4701 7826/8068/4705 7828/8070/4706 +f 7827/8069/4701 7828/8070/4706 7829/8071/4707 +f 7823/8065/4702 7822/8064/4701 7830/8072/4707 +f 7823/8065/4702 7830/8072/4707 7831/8073/4708 +f 7832/8074/4709 7833/8075/4710 7834/8076/4711 +f 7832/8074/4709 7834/8076/4711 7835/8077/4712 +f 7836/8078/4710 7837/8079/4713 7838/8080/4714 +f 7836/8078/4710 7838/8080/4714 7839/8081/4715 +f 7839/8081/4715 7838/8080/4714 7840/8082/4716 +f 7839/8081/4715 7840/8082/4716 7841/8083/4717 +f 7835/8077/4712 7834/8076/4711 7842/8084/4718 +f 7835/8077/4712 7842/8084/4718 7843/8085/4719 +f 7844/8086/4720 7845/8087/4721 7846/8088/4722 +f 7844/8086/4720 7846/8088/4722 7847/8089/4723 +f 7848/8090/4724 7849/8091/4725 7850/8092/4726 +f 7848/8090/4724 7850/8092/4726 7851/8093/4727 +f 7851/8093/4727 7850/8092/4726 7852/8094/4728 +f 7851/8093/4727 7852/8094/4728 7853/8095/4729 +f 7847/8089/4723 7846/8088/4722 7854/8096/4730 +f 7847/8089/4723 7854/8096/4730 7855/8097/4731 +f 7856/8098/4732 7857/8099/4733 7858/8100/4734 +f 7856/8098/4732 7858/8100/4734 7859/8101/4735 +f 7860/8102/4736 7861/8103/4737 7862/8104/4738 +f 7860/8102/4736 7862/8104/4738 7863/8105/4734 +f 7863/8105/4734 7862/8104/4738 7805/8047/4685 +f 7863/8105/4734 7805/8047/4685 7804/8046/4684 +f 7859/8101/4735 7858/8100/4734 7801/8043/4681 +f 7859/8101/4735 7801/8043/4681 7800/8042/4680 +f 7864/8106/4739 7865/8107/4740 7866/8108/4741 +f 7864/8106/4739 7866/8108/4741 7867/8109/4742 +f 7868/8110/4743 7869/8111/4744 7870/8112/4745 +f 7868/8110/4743 7870/8112/4745 7871/8113/4746 +f 7871/8113/4746 7870/8112/4745 7849/8091/4725 +f 7871/8113/4746 7849/8091/4725 7848/8090/4724 +f 7867/8109/4742 7866/8108/4741 7845/8087/4721 +f 7867/8109/4742 7845/8087/4721 7844/8086/4720 +f 7617/7859/4514 7616/7858/4513 7872/8114/4747 +f 7617/7859/4514 7872/8114/4747 7873/8115/4748 +f 7615/7857/4512 7614/7856/4511 7874/8116/4749 +f 7615/7857/4512 7874/8116/4749 7875/8117/4750 +f 7875/8117/4750 7874/8116/4749 7861/8103/4737 +f 7875/8117/4750 7861/8103/4737 7860/8102/4736 +f 7873/8115/4748 7872/8114/4747 7857/8099/4733 +f 7873/8115/4748 7857/8099/4733 7856/8098/4732 +f 7876/8118/4751 7877/8119/4752 7878/8120/4753 +f 7876/8118/4751 7878/8120/4753 7879/8121/4754 +f 7880/8122/4752 7881/8123/4755 7882/8124/4756 +f 7880/8122/4752 7882/8124/4756 7883/8125/4757 +f 7883/8125/4757 7882/8124/4756 7884/8126/4758 +f 7883/8125/4757 7884/8126/4758 7885/8127/4759 +f 7879/8121/4754 7878/8120/4753 7886/8128/4760 +f 7879/8121/4754 7886/8128/4760 7887/8129/4761 +f 7888/8130/4762 7889/8131/4763 7890/8132/4764 +f 7888/8130/4762 7890/8132/4764 7891/8133/4765 +f 7892/8134/4763 7893/8135/4766 7894/8136/4767 +f 7892/8134/4763 7894/8136/4767 7895/8137/4768 +f 7895/8137/4768 7894/8136/4767 7896/8138/4769 +f 7895/8137/4768 7896/8138/4769 7897/8139/4770 +f 7891/8133/4765 7890/8132/4764 7898/8140/4770 +f 7891/8133/4765 7898/8140/4770 7899/8141/4771 +f 7843/8085/4719 7842/8084/4718 7900/8142/4772 +f 7843/8085/4719 7900/8142/4772 7901/8143/4773 +f 7841/8083/4717 7840/8082/4716 7902/8144/4774 +f 7841/8083/4717 7902/8144/4774 7903/8145/4775 +f 7903/8145/4775 7902/8144/4774 7904/8146/4776 +f 7903/8145/4775 7904/8146/4776 7905/8147/4777 +f 7901/8143/4773 7900/8142/4772 7906/8148/4778 +f 7901/8143/4773 7906/8148/4778 7907/8149/4779 +f 7908/8150/4780 7909/8151/4781 7910/8152/4782 +f 7908/8150/4780 7910/8152/4782 7911/8153/4783 +f 7912/8154/4784 7913/8155/4785 7914/8156/4786 +f 7912/8154/4784 7914/8156/4786 7915/8157/4787 +f 7915/8157/4787 7914/8156/4786 7916/8158/4788 +f 7915/8157/4787 7916/8158/4788 7917/8159/4789 +f 7911/8153/4783 7910/8152/4782 7918/8160/4790 +f 7911/8153/4783 7918/8160/4790 7919/8161/4791 +f 7920/8162/4792 7921/8163/4793 7922/8164/4794 +f 7920/8162/4792 7922/8164/4794 7923/8165/4795 +f 7924/8166/4793 7925/8167/4796 7926/8168/4797 +f 7924/8166/4793 7926/8168/4797 7927/8169/4798 +f 7927/8169/4798 7926/8168/4797 7928/8170/4799 +f 7927/8169/4798 7928/8170/4799 7929/8171/4800 +f 7930/8172/4795 7931/8173/4798 7932/8174/4800 +f 7930/8172/4795 7932/8174/4800 7933/8175/4801 +f 7934/8176/4802 7935/8177/4803 7936/8178/4804 +f 7934/8176/4802 7936/8178/4804 7937/8179/4805 +f 7938/8180/4806 7939/8181/4807 7940/8182/4808 +f 7938/8180/4806 7940/8182/4808 7941/8183/4809 +f 7941/8183/4809 7940/8182/4808 7623/7865/4520 +f 7941/8183/4809 7623/7865/4520 7622/7864/4519 +f 7937/8179/4805 7936/8178/4804 7619/7861/4516 +f 7937/8179/4805 7619/7861/4516 7618/7860/4515 +f 7855/8097/4731 7854/8096/4730 7942/8184/4810 +f 7855/8097/4731 7942/8184/4810 7943/8185/4811 +f 7853/8095/4729 7852/8094/4728 7944/8186/4812 +f 7853/8095/4729 7944/8186/4812 7945/8187/4813 +f 7945/8187/4813 7944/8186/4812 7946/8188/4814 +f 7945/8187/4813 7946/8188/4814 7947/8189/4815 +f 7943/8185/4811 7942/8184/4810 7948/8190/4816 +f 7943/8185/4811 7948/8190/4816 7949/8191/4817 +f 7950/8192/4818 7951/8193/4819 7952/8194/4820 +f 7950/8192/4818 7952/8194/4820 7953/8195/4821 +f 7954/8196/4822 7955/8197/4823 7956/8198/4824 +f 7954/8196/4822 7956/8198/4824 7957/8199/4825 +f 7957/8199/4825 7956/8198/4824 7647/7889/4542 +f 7957/8199/4825 7647/7889/4542 7646/7888/4541 +f 7953/8195/4821 7952/8194/4820 7643/7885/4538 +f 7953/8195/4821 7643/7885/4538 7642/7884/4537 +f 7605/7847/4503 7604/7846/4502 7958/8200/4826 +f 7605/7847/4503 7958/8200/4826 7959/8201/4827 +f 7603/7845/4502 7602/7844/4501 7960/8202/4828 +f 7603/7845/4502 7960/8202/4828 7961/8203/4826 +f 7961/8203/4826 7960/8202/4828 7962/8204/4829 +f 7961/8203/4826 7962/8204/4829 7963/8205/4830 +f 7959/8201/4827 7958/8200/4826 7964/8206/4831 +f 7959/8201/4827 7964/8206/4831 7965/8207/4832 +f 7966/8208/4833 7967/8209/4834 7968/8210/4835 +f 7966/8208/4833 7968/8210/4835 7969/8211/4836 +f 7970/8212/4837 7971/8213/4838 7972/8214/4839 +f 7970/8212/4837 7972/8214/4839 7973/8215/4840 +f 7973/8215/4840 7972/8214/4839 7737/7979/4626 +f 7973/8215/4840 7737/7979/4626 7736/7978/4625 +f 7969/8211/4836 7968/8210/4835 7733/7975/4622 +f 7969/8211/4836 7733/7975/4622 7732/7974/4621 +f 7974/8216/4841 7975/8217/4842 7976/8218/4843 +f 7974/8216/4841 7976/8218/4843 7977/8219/4844 +f 7978/8220/4845 7979/8221/4846 7980/8222/4847 +f 7978/8220/4845 7980/8222/4847 7981/8223/4848 +f 7981/8223/4848 7980/8222/4847 7982/8224/4849 +f 7981/8223/4848 7982/8224/4849 7983/8225/4850 +f 7977/8219/4844 7976/8218/4843 7984/8226/4851 +f 7977/8219/4844 7984/8226/4851 7985/8227/4852 +f 7965/8207/4832 7964/8206/4831 7986/8228/4853 +f 7965/8207/4832 7986/8228/4853 7987/8229/4854 +f 7988/8230/4855 7989/8231/4829 7990/8232/4856 +f 7988/8230/4855 7990/8232/4856 7991/8233/4857 +f 7991/8233/4857 7990/8232/4856 7992/8234/4858 +f 7991/8233/4857 7992/8234/4858 7993/8235/4859 +f 7987/8229/4854 7986/8228/4853 7994/8236/4860 +f 7987/8229/4854 7994/8236/4860 7995/8237/4861 +f 7996/8238/4862 7997/8239/4863 7998/8240/4864 +f 7996/8238/4862 7998/8240/4864 7999/8241/4865 +f 8000/8242/4866 7199/7817/4437 7198/7816/4436 +f 8000/8242/4866 7198/7816/4436 8001/8243/4867 +f 8001/8243/4867 7198/7816/4436 7197/7815/4435 +f 8001/8243/4867 7197/7815/4435 8002/8244/4868 +f 7999/8241/4865 7998/8240/4864 8003/8245/4868 +f 7999/8241/4865 8003/8245/4868 8004/8246/4869 +f 7899/8141/4771 7898/8140/4770 8005/8247/4870 +f 7899/8141/4771 8005/8247/4870 8006/8248/4871 +f 7897/8139/4770 7896/8138/4769 8007/8249/4872 +f 7897/8139/4770 8007/8249/4872 8008/8250/4873 +f 8008/8250/4873 8007/8249/4872 8009/8251/4874 +f 8008/8250/4873 8009/8251/4874 8010/8252/4875 +f 8006/8248/4871 8005/8247/4870 8011/8253/4876 +f 8006/8248/4871 8011/8253/4876 8012/8254/4877 +f 8013/8255/4878 8014/8256/4879 8015/8257/4880 +f 8013/8255/4878 8015/8257/4880 8016/8258/4881 +f 8017/8259/4882 8018/8260/4883 8019/8261/4884 +f 8017/8259/4882 8019/8261/4884 8020/8262/4885 +f 8020/8262/4885 8019/8261/4884 8021/8263/4886 +f 8020/8262/4885 8021/8263/4886 8022/8264/4887 +f 8016/8258/4881 8015/8257/4880 8023/8265/4887 +f 8016/8258/4881 8023/8265/4887 8024/8266/4888 +f 8025/8267/4889 8026/8268/4890 8027/8269/4891 +f 8025/8267/4889 8027/8269/4891 8028/8270/4892 +f 8029/8271/4893 8030/8272/4894 8031/8273/4895 +f 8029/8271/4893 8031/8273/4895 8032/8274/4896 +f 8032/8274/4896 8031/8273/4895 8033/8275/4897 +f 8032/8274/4896 8033/8275/4897 8034/8276/4898 +f 8028/8270/4892 8027/8269/4891 8035/8277/4899 +f 8028/8270/4892 8035/8277/4899 8036/8278/4900 +f 8037/8279/4901 8038/8280/4902 8039/8281/4903 +f 8037/8279/4901 8039/8281/4903 8040/8282/4904 +f 8041/8283/4905 8042/8284/4906 8043/8285/4907 +f 8041/8283/4905 8043/8285/4907 8044/8286/4908 +f 8044/8286/4908 8043/8285/4907 8045/8287/4909 +f 8044/8286/4908 8045/8287/4909 8046/8288/4910 +f 8040/8282/4904 8039/8281/4903 8047/8289/4910 +f 8040/8282/4904 8047/8289/4910 8048/8290/4911 +f 8049/8291/4912 8050/8292/4913 8051/8293/4914 +f 8049/8291/4912 8051/8293/4914 8052/8294/4915 +f 8053/8295/4916 8054/8296/4917 8055/8297/4918 +f 8053/8295/4916 8055/8297/4918 8056/8298/4914 +f 8056/8298/4914 8055/8297/4918 7661/7903/4552 +f 8056/8298/4914 7661/7903/4552 7660/7902/4549 +f 8052/8294/4915 8051/8293/4914 7657/7899/4549 +f 8052/8294/4915 7657/7899/4549 7656/7898/4548 +f 8057/8299/4919 8058/8300/4920 8059/8301/4921 +f 8057/8299/4919 8059/8301/4921 8060/8302/4922 +f 8061/8303/4923 8062/8304/4924 8063/8305/4925 +f 8061/8303/4923 8063/8305/4925 8064/8306/4921 +f 8064/8306/4921 8063/8305/4925 8065/8307/4926 +f 8064/8306/4921 8065/8307/4926 8066/8308/4927 +f 8060/8302/4922 8059/8301/4921 8067/8309/4927 +f 8060/8302/4922 8067/8309/4927 8068/8310/4928 +f 7629/7871/4525 7628/7870/4524 8069/8311/4929 +f 7629/7871/4525 8069/8311/4929 8070/8312/4930 +f 7627/7869/4523 7626/7868/4522 8071/8313/4931 +f 7627/7869/4523 8071/8313/4931 8072/8314/4929 +f 8072/8314/4929 8071/8313/4931 7893/8135/4766 +f 8072/8314/4929 7893/8135/4766 7892/8134/4763 +f 8070/8312/4930 8069/8311/4929 7889/8131/4763 +f 8070/8312/4930 7889/8131/4763 7888/8130/4762 +f 8073/8315/4932 8074/8316/4933 8075/8317/4934 +f 8073/8315/4932 8075/8317/4934 8076/8318/4935 +f 8077/8319/4936 8078/8320/4937 8079/8321/4938 +f 8077/8319/4936 8079/8321/4938 8080/8322/4934 +f 8080/8322/4934 8079/8321/4938 7709/7951/4598 +f 8080/8322/4934 7709/7951/4598 7708/7950/4595 +f 8076/8318/4935 8075/8317/4934 7705/7947/4595 +f 8076/8318/4935 7705/7947/4595 7704/7946/4594 +f 8081/8323/4939 8082/8324/4940 8083/8325/4941 +f 8081/8323/4939 8083/8325/4941 8084/8326/4942 +f 8085/8327/4940 8086/8328/4943 8087/8329/4944 +f 8085/8327/4940 8087/8329/4944 8088/8330/4945 +f 8088/8330/4945 8087/8329/4944 8030/8272/4894 +f 8088/8330/4945 8030/8272/4894 8029/8271/4893 +f 8084/8326/4942 8083/8325/4941 8026/8268/4890 +f 8084/8326/4942 8026/8268/4890 8025/8267/4889 +f 8089/8331/4946 8090/8332/4947 8091/8333/4948 +f 8089/8331/4946 8091/8333/4948 8092/8334/4949 +f 8093/8335/4950 8094/8336/4951 8095/8337/4952 +f 8093/8335/4950 8095/8337/4952 8096/8338/4948 +f 8096/8338/4948 8095/8337/4952 8097/8339/4953 +f 8096/8338/4948 8097/8339/4953 8098/8340/4954 +f 8092/8334/4949 8091/8333/4948 8099/8341/4955 +f 8092/8334/4949 8099/8341/4955 8100/8342/4956 +f 8101/8343/4957 8102/8344/4958 8103/8345/4959 +f 8101/8343/4957 8103/8345/4959 8104/8346/4960 +f 8105/8347/4961 8106/8348/4962 8107/8349/4963 +f 8105/8347/4961 8107/8349/4963 8108/8350/4964 +f 8108/8350/4964 8107/8349/4963 8109/8351/4965 +f 8108/8350/4964 8109/8351/4965 8110/8352/4966 +f 8104/8346/4960 8103/8345/4959 8111/8353/4966 +f 8104/8346/4960 8111/8353/4966 8112/8354/4967 +f 8004/8246/4869 8003/8245/4868 8113/8355/4968 +f 8004/8246/4869 8113/8355/4968 8114/8356/4969 +f 8002/8244/4868 7197/7815/4435 8115/8357/4970 +f 8002/8244/4868 8115/8357/4970 8116/8358/4971 +f 8116/8358/4971 8115/8357/4970 8117/8359/4972 +f 8116/8358/4971 8117/8359/4972 8118/8360/4973 +f 8114/8356/4969 8113/8355/4968 8119/8361/4974 +f 8114/8356/4969 8119/8361/4974 8120/8362/4975 +f 7745/7987/4631 7744/7986/4630 8121/8363/4976 +f 7745/7987/4631 8121/8363/4976 8122/8364/4977 +f 7743/7985/4629 7742/7984/4628 8123/8365/4978 +f 7743/7985/4629 8123/8365/4978 8124/8366/4976 +f 8124/8366/4976 8123/8365/4978 8078/8320/4937 +f 8124/8366/4976 8078/8320/4937 8077/8319/4936 +f 8122/8364/4977 8121/8363/4976 8074/8316/4933 +f 8122/8364/4977 8074/8316/4933 8073/8315/4932 +f 7985/8227/4852 7984/8226/4851 8125/8367/4979 +f 7985/8227/4852 8125/8367/4979 8126/8368/4980 +f 7983/8225/4850 7982/8224/4849 8127/8369/4981 +f 7983/8225/4850 8127/8369/4981 8128/8370/4982 +f 8128/8370/4982 8127/8369/4981 8129/8371/4983 +f 8128/8370/4982 8129/8371/4983 8130/8372/4984 +f 8126/8368/4980 8125/8367/4979 8131/8373/4984 +f 8126/8368/4980 8131/8373/4984 8132/8374/4985 +f 8133/8375/4986 8134/8376/4987 8135/8377/4988 +f 8133/8375/4986 8135/8377/4988 8136/8378/4989 +f 8134/8376/4987 7127/7806/4421 7126/7805/4420 +f 8134/8376/4987 7126/7805/4420 8135/8377/4988 +f 8135/8377/4988 7126/7805/4420 7125/7804/4419 +f 8135/8377/4988 7125/7804/4419 8137/8379/4990 +f 8136/8378/4989 8135/8377/4988 8137/8379/4990 +f 8136/8378/4989 8137/8379/4990 8138/8380/4991 +f 7799/8041/4679 7798/8040/4678 8139/8381/4992 +f 7799/8041/4679 8139/8381/4992 8140/8382/4993 +f 8141/8383/4994 8142/8384/4995 8143/8385/4996 +f 8141/8383/4994 8143/8385/4996 8144/8386/4997 +f 8144/8386/4997 8143/8385/4996 8145/8387/4917 +f 8144/8386/4997 8145/8387/4917 8146/8388/4998 +f 8140/8382/4993 8139/8381/4992 8050/8292/4913 +f 8140/8382/4993 8050/8292/4913 8049/8291/4912 +f 8036/8278/4900 8035/8277/4899 8147/8389/4999 +f 8036/8278/4900 8147/8389/4999 8148/8390/5000 +f 8034/8276/4898 8033/8275/4897 8149/8391/5001 +f 8034/8276/4898 8149/8391/5001 8150/8392/5002 +f 8150/8392/5002 8149/8391/5001 8151/8393/5003 +f 8150/8392/5002 8151/8393/5003 8152/8394/5004 +f 8148/8390/5000 8147/8389/4999 8153/8395/5005 +f 8148/8390/5000 8153/8395/5005 8154/8396/5006 +f 8155/8397/4956 8156/8398/4955 8157/8399/5007 +f 8155/8397/4956 8157/8399/5007 8158/8400/5008 +f 8098/8340/4954 8097/8339/4953 8159/8401/5009 +f 8098/8340/4954 8159/8401/5009 8160/8402/5007 +f 8157/8399/5007 8161/8403/5010 8162/8404/5011 +f 8157/8399/5007 8162/8404/5011 8163/8405/5012 +f 8158/8400/5008 8157/8399/5007 8163/8405/5012 +f 8158/8400/5008 8163/8405/5012 8164/8406/5013 +f 8068/8310/4928 8067/8309/4927 8165/8407/5014 +f 8068/8310/4928 8165/8407/5014 8166/8408/5015 +f 8066/8308/4927 8065/8307/4926 8167/8409/5016 +f 8066/8308/4927 8167/8409/5016 8168/8410/5014 +f 8168/8410/5014 8167/8409/5016 8169/8411/5017 +f 8168/8410/5014 8169/8411/5017 8170/8412/5018 +f 8166/8408/5015 8165/8407/5014 8171/8413/5019 +f 8166/8408/5015 8171/8413/5019 8172/8414/5020 +f 7933/8175/4801 7932/8174/4800 8173/8415/5021 +f 7933/8175/4801 8173/8415/5021 8174/8416/5022 +f 7929/8171/4800 7928/8170/4799 8175/8417/5023 +f 7929/8171/4800 8175/8417/5023 8176/8418/5024 +f 8176/8418/5024 8175/8417/5023 8177/8419/5025 +f 8176/8418/5024 8177/8419/5025 8178/8420/5026 +f 8174/8416/5022 8173/8415/5021 8179/8421/5027 +f 8174/8416/5022 8179/8421/5027 8180/8422/5028 +f 8181/8423/5029 8182/8424/5030 8183/8425/5031 +f 8181/8423/5029 8183/8425/5031 8184/8426/5032 +f 8185/8427/5033 8186/8428/5034 8187/8429/5035 +f 8185/8427/5033 8187/8429/5035 8188/8430/5036 +f 8189/8431/5037 8190/8432/5038 8191/8433/5039 +f 8189/8431/5037 8191/8433/5039 8192/8434/5040 +f 8184/8426/5032 8183/8425/5031 8193/8435/5041 +f 8184/8426/5032 8193/8435/5041 8194/8436/5042 +f 7667/7909/4557 7666/7908/4556 8195/8437/5043 +f 7667/7909/4557 8195/8437/5043 8196/8438/5044 +f 8197/8439/4555 8198/8440/4554 8199/8441/5045 +f 8197/8439/4555 8199/8441/5045 8200/8442/5046 +f 8200/8442/5046 8199/8441/5045 8201/8443/5047 +f 8200/8442/5046 8201/8443/5047 8202/8444/5048 +f 8203/8445/5049 8200/8442/5046 8202/8444/5048 +f 8203/8445/5049 8202/8444/5048 8204/8446/5050 +f 8012/8254/4877 8011/8253/4876 8205/8447/5051 +f 8012/8254/4877 8205/8447/5051 8206/8448/5052 +f 8010/8252/4875 8009/8251/4874 8207/8449/5053 +f 8010/8252/4875 8207/8449/5053 8208/8450/5054 +f 8208/8450/5054 8207/8449/5053 7971/8213/4838 +f 8208/8450/5054 7971/8213/4838 7970/8212/4837 +f 8206/8448/5052 8205/8447/5051 7967/8209/4834 +f 8206/8448/5052 7967/8209/4834 7966/8208/4833 +f 8209/8451/5055 8210/8452/5056 8211/8453/5057 +f 8209/8451/5055 8211/8453/5057 8212/8454/5058 +f 8046/8288/4910 8045/8287/4909 8213/8455/5059 +f 8046/8288/4910 8213/8455/5059 8214/8456/5057 +f 8214/8456/5057 8213/8455/5059 8215/8457/5060 +f 8214/8456/5057 8215/8457/5060 8216/8458/5061 +f 8217/8459/5062 8214/8456/5057 8216/8458/5061 +f 8217/8459/5062 8216/8458/5061 8218/8460/5063 +f 7769/8011/4654 7768/8010/4653 8219/8461/5064 +f 7769/8011/4654 8219/8461/5064 8220/8462/5065 +f 7767/8009/4652 7766/8008/4651 8221/8463/5066 +f 7767/8009/4652 8221/8463/5066 8222/8464/5067 +f 8222/8464/5067 8221/8463/5066 8223/8465/5068 +f 8222/8464/5067 8223/8465/5068 8224/8466/4822 +f 8220/8462/5065 8219/8461/5064 7951/8193/4819 +f 8220/8462/5065 7951/8193/4819 7950/8192/4818 +f 7949/8191/4817 7948/8190/4816 8225/8467/5069 +f 7949/8191/4817 8225/8467/5069 8226/8468/5070 +f 7947/8189/4815 7946/8188/4814 8227/8469/5071 +f 7947/8189/4815 8227/8469/5071 8228/8470/5072 +f 8228/8470/5072 8227/8469/5071 8229/8471/5073 +f 8228/8470/5072 8229/8471/5073 8230/8472/5074 +f 8226/8468/5070 8225/8467/5069 8231/8473/5075 +f 8226/8468/5070 8231/8473/5075 8232/8474/5076 +f 8233/8475/5077 8234/8476/5078 8235/8477/5079 +f 8233/8475/5077 8235/8477/5079 8236/8478/5080 +f 8237/8479/5078 8238/8480/5081 8239/8481/5082 +f 8237/8479/5078 8239/8481/5082 8240/8482/5083 +f 8240/8482/5083 8239/8481/5082 7939/8181/4807 +f 8240/8482/5083 7939/8181/4807 7938/8180/4806 +f 8236/8478/5080 8235/8477/5079 7935/8177/4803 +f 8236/8478/5080 7935/8177/4803 7934/8176/4802 +f 8241/8483/5084 8242/8484/5085 8243/8485/5086 +f 8241/8483/5084 8243/8485/5086 8244/8486/5087 +f 8245/8487/5085 8246/8488/5088 8247/8489/5089 +f 8245/8487/5085 8247/8489/5089 8248/8490/5090 +f 8248/8490/5090 8247/8489/5089 8249/8491/5091 +f 8248/8490/5090 8249/8491/5091 8250/8492/5092 +f 8244/8486/5087 8243/8485/5086 8251/8493/5093 +f 8244/8486/5087 8251/8493/5093 8252/8494/5094 +f 8253/8495/5063 8254/8496/5061 8255/8497/5095 +f 8253/8495/5063 8255/8497/5095 8256/8498/5096 +f 8216/8458/5061 8215/8457/5060 8257/8499/5097 +f 8216/8458/5061 8257/8499/5097 8258/8500/5098 +f 8258/8500/5098 8257/8499/5097 8259/8501/5099 +f 8258/8500/5098 8259/8501/5099 8260/8502/5100 +f 8256/8498/5096 8255/8497/5095 8261/8503/5101 +f 8256/8498/5096 8261/8503/5101 8262/8504/5102 +f 8263/8505/5103 8264/8506/5104 8265/8507/5105 +f 8263/8505/5103 8265/8507/5105 8266/8508/5106 +f 8267/8509/5107 8268/8510/5108 8269/8511/5109 +f 8267/8509/5107 8269/8511/5109 8270/8512/5110 +f 8270/8512/5110 8269/8511/5109 8271/8513/5111 +f 8270/8512/5110 8271/8513/5111 8272/8514/5112 +f 8266/8508/5106 8265/8507/5105 8273/8515/5112 +f 8266/8508/5106 8273/8515/5112 8274/8516/5113 +f 7831/8073/4708 7830/8072/4707 8275/8517/5114 +f 7831/8073/4708 8275/8517/5114 8276/8518/5115 +f 7829/8071/4707 7828/8070/4706 8277/8519/5116 +f 7829/8071/4707 8277/8519/5116 8278/8520/5117 +f 8278/8520/5117 8277/8519/5116 8086/8328/4943 +f 8278/8520/5117 8086/8328/4943 8085/8327/4940 +f 8276/8518/5115 8275/8517/5114 8082/8324/4940 +f 8276/8518/5115 8082/8324/4940 8081/8323/4939 +f 8120/8362/4975 8119/8361/4974 8279/8521/5118 +f 8120/8362/4975 8279/8521/5118 8280/8522/5119 +f 8118/8360/4973 8117/8359/4972 8281/8523/5120 +f 8118/8360/4973 8281/8523/5120 8282/8524/5121 +f 8282/8524/5121 8281/8523/5120 7913/8155/4785 +f 8282/8524/5121 7913/8155/4785 7912/8154/4784 +f 8280/8522/5119 8279/8521/5118 7909/8151/4781 +f 8280/8522/5119 7909/8151/4781 7908/8150/4780 +f 8283/8525/5122 8284/8526/5123 8285/8527/5124 +f 8283/8525/5122 8285/8527/5124 8286/8528/5125 +f 8287/8529/5126 8288/8530/5127 8289/8531/5128 +f 8287/8529/5126 8289/8531/5128 8290/8532/5129 +f 8290/8532/5129 8289/8531/5128 8268/8510/5108 +f 8290/8532/5129 8268/8510/5108 8267/8509/5107 +f 8291/8533/5125 8292/8534/5129 8264/8506/5104 +f 8291/8533/5125 8264/8506/5104 8263/8505/5103 +f 7655/7897/4547 7654/7896/4546 8293/8535/5130 +f 7655/7897/4547 8293/8535/5130 8294/8536/5131 +f 7653/7895/4545 7652/7894/4544 8295/8537/5132 +f 7653/7895/4545 8295/8537/5132 8296/8538/5133 +f 8296/8538/5133 8295/8537/5132 7869/8111/4744 +f 8296/8538/5133 7869/8111/4744 7868/8110/4743 +f 8294/8536/5131 8293/8535/5130 7865/8107/4740 +f 8294/8536/5131 7865/8107/4740 7864/8106/4739 +f 8297/8539/5134 8298/8540/5135 8299/8541/5136 +f 8297/8539/5134 8299/8541/5136 8300/8542/5137 +f 8301/8543/5135 7201/7819/4439 7200/7818/4438 +f 8301/8543/5135 7200/7818/4438 8302/8544/5136 +f 8302/8544/5136 7200/7818/4438 7199/7817/4437 +f 8302/8544/5136 7199/7817/4437 8000/8242/4866 +f 8300/8542/5137 8299/8541/5136 7997/8239/4863 +f 8300/8542/5137 7997/8239/4863 7996/8238/4862 +f 8180/8422/5028 8179/8421/5027 8303/8545/5138 +f 8180/8422/5028 8303/8545/5138 8304/8546/5139 +f 8178/8420/5026 8177/8419/5025 8305/8547/5140 +f 8178/8420/5026 8305/8547/5140 8306/8548/5138 +f 8306/8548/5138 8305/8547/5140 7201/7819/4439 +f 8306/8548/5138 7201/7819/4439 8301/8543/5135 +f 8304/8546/5139 8303/8545/5138 8298/8540/5135 +f 8304/8546/5139 8298/8540/5135 8297/8539/5134 +f 8307/8549/5141 8308/7728/5142 8309/8550/5143 +f 8307/8549/5141 8309/8550/5143 8310/8551/5144 +f 8308/7728/5142 7359/7698/4319 7581/7835/4492 +f 8308/7728/5142 7581/7835/4492 8309/8550/5143 +f 8309/8550/5143 7581/7835/4492 7370/7823/4459 +f 8309/8550/5143 7370/7823/4459 8311/8552/5145 +f 8310/8551/5144 8309/8550/5143 8311/8552/5145 +f 8310/8551/5144 8311/8552/5145 8312/8553/5146 +f 7919/8161/4791 7918/8160/4790 8313/8554/5147 +f 7919/8161/4791 8313/8554/5147 8314/8555/5148 +f 7917/8159/4789 7916/8158/4788 8315/8556/5149 +f 7917/8159/4789 8315/8556/5149 8316/8557/5150 +f 8316/8557/5150 8315/8556/5149 8317/8558/5151 +f 8316/8557/5150 8317/8558/5151 8318/8559/5152 +f 8319/8560/5153 8320/8561/5154 8321/8562/5155 +f 8319/8560/5153 8321/8562/5155 8322/8563/5156 +f 8323/8564/5157 8324/8565/5158 8325/8566/5159 +f 8323/8564/5157 8325/8566/5159 8326/8567/5160 +f 8327/8568/5158 8328/8569/5161 8329/8570/5162 +f 8327/8568/5158 8329/8570/5162 8330/8571/5163 +f 8330/8571/5163 8329/8570/5162 8062/8304/4924 +f 8330/8571/5163 8062/8304/4924 8061/8303/4923 +f 8326/8567/5160 8325/8566/5159 8331/8572/5164 +f 8326/8567/5160 8331/8572/5164 8332/8573/4919 +f 7907/8149/4779 7906/8148/4778 8333/8574/5165 +f 7907/8149/4779 8333/8574/5165 8334/8575/5166 +f 7905/8147/4777 7904/8146/4776 8335/8576/5167 +f 7905/8147/4777 8335/8576/5167 8336/8577/5168 +f 8336/8577/5168 8335/8576/5167 8337/8578/5169 +f 8336/8577/5168 8337/8578/5169 8338/8579/5170 +f 8334/8575/5166 8333/8574/5165 8339/8580/5171 +f 8334/8575/5166 8339/8580/5171 8340/8581/5172 +f 8340/8581/5172 8339/8580/5171 8341/8582/5173 +f 8340/8581/5172 8341/8582/5173 8342/8583/5174 +f 8338/8579/5170 8337/8578/5169 8343/8584/5175 +f 8338/8579/5170 8343/8584/5175 8344/8585/5173 +f 8344/8585/5173 8343/8584/5175 8345/8586/5176 +f 8344/8585/5173 8345/8586/5176 8346/8587/5177 +f 8342/8583/5174 8341/8582/5173 8347/8588/5178 +f 8342/8583/5174 8347/8588/5178 8348/8589/5179 +f 8349/8590/5180 8350/8591/5181 8351/8592/5182 +f 8349/8590/5180 8351/8592/5182 8352/8593/5183 +f 8353/8594/5184 8354/8595/5185 8355/8596/5186 +f 8353/8594/5184 8355/8596/5186 8356/8597/5187 +f 8356/8597/5187 8355/8596/5186 8106/8348/4962 +f 8356/8597/5187 8106/8348/4962 8105/8347/4961 +f 8352/8593/5183 8351/8592/5182 8102/8344/4958 +f 8352/8593/5183 8102/8344/4958 8101/8343/4957 +f 7995/8237/4861 7994/8236/4860 8357/8598/5188 +f 7995/8237/4861 8357/8598/5188 8358/8599/5189 +f 7993/8235/4859 7992/8234/4858 8359/8600/5190 +f 7993/8235/4859 8359/8600/5190 8360/8601/5188 +f 8360/8601/5188 8359/8600/5190 8238/8480/5081 +f 8360/8601/5188 8238/8480/5081 8237/8479/5078 +f 8358/8599/5189 8357/8598/5188 8234/8476/5078 +f 8358/8599/5189 8234/8476/5078 8233/8475/5077 +f 7811/8053/4690 7810/8052/4689 8361/8602/5191 +f 7811/8053/4690 8361/8602/5191 8362/8603/5192 +f 7809/8051/4689 7808/8050/4688 8363/8604/5193 +f 7809/8051/4689 8363/8604/5193 8364/8605/5194 +f 8364/8605/5194 8363/8604/5193 7775/8017/4660 +f 8364/8605/5194 7775/8017/4660 7774/8016/4659 +f 8362/8603/5192 8361/8602/5191 7771/8013/4656 +f 8362/8603/5192 7771/8013/4656 7770/8012/4655 +f 8365/8606/5195 8366/8607/5196 8367/8608/5197 +f 8365/8606/5195 8367/8608/5197 8368/8609/5198 +f 8369/8610/5199 8370/8611/5200 8371/8612/5201 +f 8369/8610/5199 8371/8612/5201 8372/8613/5202 +f 8372/8613/5202 8371/8612/5201 8354/8595/5185 +f 8372/8613/5202 8354/8595/5185 8353/8594/5184 +f 8368/8609/5198 8367/8608/5197 8350/8591/5181 +f 8368/8609/5198 8350/8591/5181 8349/8590/5180 +f 8024/8266/4888 8023/8265/4887 8373/8614/5203 +f 8024/8266/4888 8373/8614/5203 8374/8615/5204 +f 8022/8264/4887 8021/8263/4886 8375/8616/5205 +f 8022/8264/4887 8375/8616/5205 8376/8617/5203 +f 8376/8617/5203 8375/8616/5205 8042/8284/4906 +f 8376/8617/5203 8042/8284/4906 8041/8283/4905 +f 8377/8618/5204 8378/8619/5203 8379/8620/5206 +f 8377/8618/5204 8379/8620/5206 8380/8621/4901 +f 8154/8396/5006 8153/8395/5005 8381/8622/5207 +f 8154/8396/5006 8381/8622/5207 8382/8623/5208 +f 8152/8394/5004 8151/8393/5003 8383/8624/5209 +f 8152/8394/5004 8383/8624/5209 8384/8625/5210 +f 8384/8625/5210 8383/8624/5209 8288/8530/5127 +f 8384/8625/5210 8288/8530/5127 8287/8529/5126 +f 8382/8623/5208 8381/8622/5207 8284/8526/5123 +f 8382/8623/5208 8284/8526/5123 8283/8525/5122 +f 8132/8374/4985 8131/8373/4984 8385/8626/5211 +f 8132/8374/4985 8385/8626/5211 8386/8627/5212 +f 8130/8372/4984 8129/8371/4983 8387/8628/5213 +f 8130/8372/4984 8387/8628/5213 8388/8629/5214 +f 8388/8629/5214 8387/8628/5213 7729/7971/4618 +f 8388/8629/5214 7729/7971/4618 7728/7970/4617 +f 8386/8627/5212 8385/8626/5211 7725/7967/4614 +f 8386/8627/5212 7725/7967/4614 7724/7966/4613 +f 7679/7921/4569 7678/7920/4568 8389/8630/5215 +f 7679/7921/4569 8389/8630/5215 8390/8631/5216 +f 7677/7919/4567 7676/7918/4566 8391/8632/5217 +f 7677/7919/4567 8391/8632/5217 8392/8633/5218 +f 8393/8634/5219 8394/8635/5217 7721/7963/4610 +f 8393/8634/5219 7721/7963/4610 7720/7962/4609 +f 8390/8631/5216 8389/8630/5215 7717/7959/4606 +f 8390/8631/5216 7717/7959/4606 7716/7958/4605 +f 8274/8516/5113 8273/8515/5112 8395/8636/5220 +f 8274/8516/5113 8395/8636/5220 8396/8637/5221 +f 8272/8514/5112 8271/8513/5111 8397/8638/5222 +f 8272/8514/5112 8397/8638/5222 8398/8639/5220 +f 8398/8639/5220 8397/8638/5222 8018/8260/4883 +f 8398/8639/5220 8018/8260/4883 8017/8259/4882 +f 8396/8637/5221 8395/8636/5220 8014/8256/4879 +f 8396/8637/5221 8014/8256/4879 8013/8255/4878 +f 8172/8414/5020 8171/8413/5019 8399/8640/5223 +f 8172/8414/5020 8399/8640/5223 8400/8641/5224 +f 8170/8412/5018 8169/8411/5017 8401/8642/5225 +f 8170/8412/5018 8401/8642/5225 8402/8643/5226 +f 8402/8643/5226 8401/8642/5225 8403/8644/5227 +f 8402/8643/5226 8403/8644/5227 8404/8645/5228 +f 8400/8641/5224 8399/8640/5223 8405/8646/5229 +f 8400/8641/5224 8405/8646/5229 8406/8647/5230 +f 7703/7945/4593 7702/7944/4592 8407/8648/5231 +f 7703/7945/4593 8407/8648/5231 8408/8649/5232 +f 7701/7943/4591 7700/7942/4590 8409/8650/5233 +f 7701/7943/4591 8409/8650/5233 8410/8651/5234 +f 8410/8651/5234 8409/8650/5233 7881/8123/4755 +f 8410/8651/5234 7881/8123/4755 7880/8122/4752 +f 8408/8649/5232 8407/8648/5231 7877/8119/4752 +f 8408/8649/5232 7877/8119/4752 7876/8118/4751 +f 8232/8474/5076 8231/8473/5075 8411/8652/5235 +f 8232/8474/5076 8411/8652/5235 8412/8653/5236 +f 8230/8472/5074 8229/8471/5073 8413/8654/5237 +f 8230/8472/5074 8413/8654/5237 8414/8655/5238 +f 8414/8655/5238 8413/8654/5237 7673/7915/4563 +f 8414/8655/5238 7673/7915/4563 7672/7914/4562 +f 8412/8653/5236 8411/8652/5235 7669/7911/4559 +f 8412/8653/5236 7669/7911/4559 7668/7910/4558 +f 8415/8656/5102 8416/8657/5239 8417/8658/5240 +f 8415/8656/5102 8417/8658/5240 8418/8659/5241 +f 8260/8502/5100 8259/8501/5099 8419/8660/5242 +f 8260/8502/5100 8419/8660/5242 8420/8661/5243 +f 8420/8661/5243 8419/8660/5242 8094/8336/4951 +f 8420/8661/5243 8094/8336/4951 8093/8335/4950 +f 8418/8659/5241 8417/8658/5240 8090/8332/4947 +f 8418/8659/5241 8090/8332/4947 8089/8331/4946 +f 8421/8662/4967 8422/8663/5244 8423/8664/5245 +f 8421/8662/4967 8423/8664/5245 8424/8665/5246 +f 8110/8352/4966 8109/8351/4965 8425/8666/5247 +f 8110/8352/4966 8425/8666/5247 8426/8667/5245 +f 8426/8667/5245 8425/8666/5247 7925/8167/4796 +f 8426/8667/5245 7925/8167/4796 7924/8166/4793 +f 8424/8665/5246 8423/8664/5245 7921/8163/4793 +f 8424/8665/5246 7921/8163/4793 7920/8162/4792 +f 8252/8494/5094 8251/8493/5093 8427/8668/5248 +f 8252/8494/5094 8427/8668/5248 8428/8669/5249 +f 8250/8492/5092 8249/8491/5091 8429/8670/5250 +f 8250/8492/5092 8429/8670/5250 8430/8671/5251 +f 8430/8671/5251 8429/8670/5250 7697/7939/4587 +f 8430/8671/5251 7697/7939/4587 7696/7938/4586 +f 8428/8669/5249 8427/8668/5248 7693/7935/4583 +f 8428/8669/5249 7693/7935/4583 7692/7934/4582 +f 8406/8647/5230 8405/8646/5229 8431/8672/5252 +f 8406/8647/5230 8431/8672/5252 8432/8673/5253 +f 8404/8645/5228 8403/8644/5227 8433/8674/5254 +f 8404/8645/5228 8433/8674/5254 8434/8675/5255 +f 8434/8675/5255 8433/8674/5254 7825/8067/4704 +f 8434/8675/5255 7825/8067/4704 7824/8066/4703 +f 8432/8673/5253 8431/8672/5252 7821/8063/4700 +f 8432/8673/5253 7821/8063/4700 7820/8062/4699 +f 8322/8563/5156 8321/8562/5155 8435/8676/5256 +f 8322/8563/5156 8435/8676/5256 8436/8677/5257 +f 8318/8559/5152 8317/8558/5151 8437/8678/5258 +f 8318/8559/5152 8437/8678/5258 8438/8679/5256 +f 8438/8679/5256 8437/8678/5258 7837/8079/4713 +f 8438/8679/5256 7837/8079/4713 7836/8078/4710 +f 8436/8677/5257 8435/8676/5256 7833/8075/4710 +f 8436/8677/5257 7833/8075/4710 7832/8074/4709 +f 8439/8680/5259 8440/8681/5260 8441/8682/5261 +f 8439/8680/5259 8441/8682/5261 8442/8683/5262 +f 8443/8684/5263 8312/8553/5146 8444/8685/5264 +f 8443/8684/5263 8444/8685/5264 8445/8686/5261 +f 8445/8686/5261 8444/8685/5264 8446/8687/5265 +f 8445/8686/5261 8446/8687/5265 8447/8688/5266 +f 8442/8683/5262 8441/8682/5261 8448/8689/5267 +f 8442/8683/5262 8448/8689/5267 8449/8690/5268 +f 8112/8354/4967 8450/8691/5269 8451/8692/5270 +f 8112/8354/4967 8451/8692/5270 8104/8346/4960 +f 8450/8691/5269 8452/8693/5271 8453/8694/5270 +f 8450/8691/5269 8453/8694/5270 8451/8692/5270 +f 8451/8692/5270 8453/8694/5270 8454/8695/5272 +f 8451/8692/5270 8454/8695/5272 8455/8696/5272 +f 8104/8346/4960 8451/8692/5270 8455/8696/5272 +f 8104/8346/4960 8455/8696/5272 8101/8343/4957 +f 8452/8693/5271 8456/8697/5271 8457/8698/5270 +f 8452/8693/5271 8457/8698/5270 8453/8694/5270 +f 8456/8697/5271 8223/8465/5068 8221/8463/5066 +f 8456/8697/5271 8221/8463/5066 8457/8698/5270 +f 8457/8698/5270 8221/8463/5066 7766/8008/4651 +f 8457/8698/5270 7766/8008/4651 8458/8699/5272 +f 8453/8694/5270 8457/8698/5270 8458/8699/5272 +f 8453/8694/5270 8458/8699/5272 8454/8695/5272 +f 8120/8362/4975 8459/8700/5273 8460/8701/5274 +f 8120/8362/4975 8460/8701/5274 8114/8356/4969 +f 8459/8700/5273 8461/8702/5273 8462/8703/5274 +f 8459/8700/5273 8462/8703/5274 8460/8701/5274 +f 8460/8701/5274 8462/8703/5274 8463/8704/5275 +f 8460/8701/5274 8463/8704/5275 8464/8705/5275 +f 8114/8356/4969 8460/8701/5274 8464/8705/5275 +f 8114/8356/4969 8464/8705/5275 8004/8246/4869 +f 8461/8702/5273 8465/8706/5273 8466/8707/5276 +f 8461/8702/5273 8466/8707/5276 8462/8703/5274 +f 8465/8706/5273 8229/8471/5073 8227/8469/5071 +f 8465/8706/5273 8227/8469/5071 8466/8707/5276 +f 8466/8707/5276 8227/8469/5071 7946/8188/4814 +f 8466/8707/5276 7946/8188/4814 8467/8708/5275 +f 8462/8703/5274 8466/8707/5276 8467/8708/5275 +f 8462/8703/5274 8467/8708/5275 8463/8704/5275 +f 8024/8266/4888 8468/8709/5277 8469/8710/5278 +f 8024/8266/4888 8469/8710/5278 8016/8258/4881 +f 8468/8709/5277 8470/8711/5277 8471/8712/5278 +f 8468/8709/5277 8471/8712/5278 8469/8710/5278 +f 8469/8710/5278 8471/8712/5278 8472/8713/5279 +f 8469/8710/5278 8472/8713/5279 8473/8714/5279 +f 8016/8258/4881 8469/8710/5278 8473/8714/5279 +f 8016/8258/4881 8473/8714/5279 8013/8255/4878 +f 8470/8711/5277 8474/8715/5277 8475/8716/5278 +f 8470/8711/5277 8475/8716/5278 8471/8712/5278 +f 8474/8715/5277 7712/7954/4601 7710/7952/4599 +f 8474/8715/5277 7710/7952/4599 8475/8716/5278 +f 8475/8716/5278 7710/7952/4599 7709/7951/4598 +f 8475/8716/5278 7709/7951/4598 8476/8717/5279 +f 8471/8712/5278 8475/8716/5278 8476/8717/5279 +f 8471/8712/5278 8476/8717/5279 8472/8713/5279 +f 8025/8267/4889 8477/8718/5280 8478/8719/5281 +f 8025/8267/4889 8478/8719/5281 8084/8326/4942 +f 8477/8718/5280 8479/8720/5280 8480/8721/5281 +f 8477/8718/5280 8480/8721/5281 8478/8719/5281 +f 8478/8719/5281 8480/8721/5281 8481/8722/5282 +f 8478/8719/5281 8481/8722/5282 8482/8723/5282 +f 8084/8326/4942 8478/8719/5281 8482/8723/5282 +f 8084/8326/4942 8482/8723/5282 8081/8323/4939 +f 8479/8720/5280 8483/8724/5280 8484/8725/5281 +f 8479/8720/5280 8484/8725/5281 8480/8721/5281 +f 8483/8724/5280 7896/8138/4769 7894/8136/4767 +f 8483/8724/5280 7894/8136/4767 8484/8725/5281 +f 8484/8725/5281 7894/8136/4767 7893/8135/4766 +f 8484/8725/5281 7893/8135/4766 8485/8726/5282 +f 8480/8721/5281 8484/8725/5281 8485/8726/5282 +f 8480/8721/5281 8485/8726/5282 8481/8722/5282 +f 8486/8727/4991 8487/8728/5283 8488/8729/5284 +f 8486/8727/4991 8488/8729/5284 8489/8730/5285 +f 8487/8728/5283 8490/8731/5286 8491/8732/5287 +f 8487/8728/5283 8491/8732/5287 8488/8729/5284 +f 8488/8729/5284 8491/8732/5287 8492/8733/5288 +f 8488/8729/5284 8492/8733/5288 8493/8734/5289 +f 8489/8730/5285 8488/8729/5284 8493/8734/5289 +f 8489/8730/5285 8493/8734/5289 8494/8735/5290 +f 8495/8736/5291 8496/8737/5292 8497/8738/5293 +f 8495/8736/5291 8497/8738/5293 8498/8739/5294 +f 8496/8737/5292 8129/8371/4983 8127/8369/4981 +f 8496/8737/5292 8127/8369/4981 8497/8738/5293 +f 8497/8738/5293 8127/8369/4981 7982/8224/4849 +f 8497/8738/5293 7982/8224/4849 8499/8740/5295 +f 8498/8739/5294 8497/8738/5293 8499/8740/5295 +f 8498/8739/5294 8499/8740/5295 8500/8741/5296 +f 8100/8342/4956 8501/8742/5297 8502/8743/5298 +f 8100/8342/4956 8502/8743/5298 8092/8334/4949 +f 8501/8742/5297 8503/8744/5299 8504/8745/5298 +f 8501/8742/5297 8504/8745/5298 8502/8743/5298 +f 8502/8743/5298 8504/8745/5298 8505/8746/5300 +f 8502/8743/5298 8505/8746/5300 8506/8747/5300 +f 8092/8334/4949 8502/8743/5298 8506/8747/5300 +f 8092/8334/4949 8506/8747/5300 8089/8331/4946 +f 8503/8744/5299 8507/8748/5297 8508/8749/5298 +f 8503/8744/5299 8508/8749/5298 8504/8745/5298 +f 8507/8748/5297 7664/7906/4554 7662/7904/4553 +f 8507/8748/5297 7662/7904/4553 8508/8749/5298 +f 8508/8749/5298 7662/7904/4553 7661/7903/4552 +f 8508/8749/5298 7661/7903/4552 8509/8750/5301 +f 8504/8745/5298 8508/8749/5298 8509/8750/5301 +f 8504/8745/5298 8509/8750/5301 8505/8746/5300 +f 8154/8396/5006 8510/8751/5302 8511/8752/5303 +f 8154/8396/5006 8511/8752/5303 8148/8390/5000 +f 8510/8751/5302 8512/8753/5302 8513/8754/5303 +f 8510/8751/5302 8513/8754/5303 8511/8752/5303 +f 8511/8752/5303 8513/8754/5303 8514/8755/5304 +f 8511/8752/5303 8514/8755/5304 8515/8756/5304 +f 8148/8390/5000 8511/8752/5303 8515/8756/5304 +f 8148/8390/5000 8515/8756/5304 8036/8278/4900 +f 8512/8753/5302 8516/8757/5302 8517/8758/5303 +f 8512/8753/5302 8517/8758/5303 8513/8754/5303 +f 8516/8757/5302 7971/8213/4838 8207/8449/5053 +f 8516/8757/5302 8207/8449/5053 8517/8758/5303 +f 8517/8758/5303 8207/8449/5053 8009/8251/4874 +f 8517/8758/5303 8009/8251/4874 8518/8759/5304 +f 8513/8754/5303 8517/8758/5303 8518/8759/5304 +f 8513/8754/5303 8518/8759/5304 8514/8755/5304 +f 8164/8406/5013 8519/8760/5305 8520/8761/5306 +f 8164/8406/5013 8520/8761/5306 8158/8400/5008 +f 8519/8760/5305 8521/8762/5305 8522/8763/5306 +f 8519/8760/5305 8522/8763/5306 8520/8761/5306 +f 8520/8761/5306 8522/8763/5306 8523/8764/5297 +f 8520/8761/5306 8523/8764/5297 8524/8765/5297 +f 8158/8400/5008 8520/8761/5306 8524/8765/5297 +f 8158/8400/5008 8524/8765/5297 8155/8397/4956 +f 8521/8762/5305 8525/8766/5305 8526/8767/5306 +f 8521/8762/5305 8526/8767/5306 8522/8763/5306 +f 8525/8766/5305 8201/8443/5047 8199/8441/5045 +f 8525/8766/5305 8199/8441/5045 8526/8767/5306 +f 8526/8767/5306 8199/8441/5045 8198/8440/4554 +f 8526/8767/5306 8198/8440/4554 8527/8768/5297 +f 8522/8763/5306 8526/8767/5306 8527/8768/5297 +f 8522/8763/5306 8527/8768/5297 8523/8764/5297 +f 8172/8414/5020 8528/8769/5307 8529/8770/5308 +f 8172/8414/5020 8529/8770/5308 8166/8408/5015 +f 8528/8769/5307 8530/8771/5307 8531/8772/5308 +f 8528/8769/5307 8531/8772/5308 8529/8770/5308 +f 8529/8770/5308 8531/8772/5308 8532/8773/5309 +f 8529/8770/5308 8532/8773/5309 8533/8774/5309 +f 8166/8408/5015 8529/8770/5308 8533/8774/5309 +f 8166/8408/5015 8533/8774/5309 8068/8310/4928 +f 8530/8771/5307 8534/8775/5307 8535/8776/5308 +f 8530/8771/5307 8535/8776/5308 8531/8772/5308 +f 8534/8775/5307 8238/8480/5081 8359/8600/5190 +f 8534/8775/5307 8359/8600/5190 8535/8776/5308 +f 8535/8776/5308 8359/8600/5190 7992/8234/4858 +f 8535/8776/5308 7992/8234/4858 8536/8777/5309 +f 8531/8772/5308 8535/8776/5308 8536/8777/5309 +f 8531/8772/5308 8536/8777/5309 8532/8773/5309 +f 8036/8278/4900 8515/8756/5304 8537/8778/5310 +f 8036/8278/4900 8537/8778/5310 8028/8270/4892 +f 8515/8756/5304 8514/8755/5304 8538/8779/5310 +f 8515/8756/5304 8538/8779/5310 8537/8778/5310 +f 8537/8778/5310 8538/8779/5310 8479/8720/5280 +f 8537/8778/5310 8479/8720/5280 8477/8718/5280 +f 8028/8270/4892 8537/8778/5310 8477/8718/5280 +f 8028/8270/4892 8477/8718/5280 8025/8267/4889 +f 8514/8755/5304 8518/8759/5304 8539/8780/5310 +f 8514/8755/5304 8539/8780/5310 8538/8779/5310 +f 8518/8759/5304 8009/8251/4874 8007/8249/4872 +f 8518/8759/5304 8007/8249/4872 8539/8780/5310 +f 8539/8780/5310 8007/8249/4872 7896/8138/4769 +f 8539/8780/5310 7896/8138/4769 8483/8724/5280 +f 8538/8779/5310 8539/8780/5310 8483/8724/5280 +f 8538/8779/5310 8483/8724/5280 8479/8720/5280 +f 8180/8422/5028 8540/8781/5311 8541/8782/5312 +f 8180/8422/5028 8541/8782/5312 8174/8416/5022 +f 8540/8781/5311 8542/8783/5311 8543/8784/5312 +f 8540/8781/5311 8543/8784/5312 8541/8782/5312 +f 8541/8782/5312 8543/8784/5312 8544/8785/5313 +f 8541/8782/5312 8544/8785/5313 8545/8786/5313 +f 8174/8416/5022 8541/8782/5312 8545/8786/5313 +f 8174/8416/5022 8545/8786/5313 7933/8175/4801 +f 8542/8783/5311 8546/8787/5311 8547/8788/5312 +f 8542/8783/5311 8547/8788/5312 8543/8784/5312 +f 8546/8787/5311 7869/8111/4744 8295/8537/5132 +f 8546/8787/5311 8295/8537/5132 8547/8788/5312 +f 8547/8788/5312 8295/8537/5132 7652/7894/4544 +f 8547/8788/5312 7652/7894/4544 8548/8789/5313 +f 8543/8784/5312 8547/8788/5312 8548/8789/5313 +f 8543/8784/5312 8548/8789/5313 8544/8785/5313 +f 8068/8310/4928 8533/8774/5309 8549/8790/5314 +f 8068/8310/4928 8549/8790/5314 8060/8302/4922 +f 8533/8774/5309 8532/8773/5309 8550/8791/5314 +f 8533/8774/5309 8550/8791/5314 8549/8790/5314 +f 8549/8790/5314 8550/8791/5314 8551/8792/5315 +f 8549/8790/5314 8551/8792/5315 8552/8793/5315 +f 8060/8302/4922 8549/8790/5314 8552/8793/5315 +f 8060/8302/4922 8552/8793/5315 8057/8299/4919 +f 8532/8773/5309 8536/8777/5309 8553/8794/5314 +f 8532/8773/5309 8553/8794/5314 8550/8791/5314 +f 8536/8777/5309 7992/8234/4858 7990/8232/4856 +f 8536/8777/5309 7990/8232/4856 8553/8794/5314 +f 8553/8794/5314 7990/8232/4856 7989/8231/4829 +f 8553/8794/5314 7989/8231/4829 8554/8795/5315 +f 8550/8791/5314 8553/8794/5314 8554/8795/5315 +f 8550/8791/5314 8554/8795/5315 8551/8792/5315 +f 8555/8796/5029 8556/8797/5316 8557/8798/5317 +f 8555/8796/5029 8557/8798/5317 8558/8799/5318 +f 8556/8797/5316 8559/8800/5319 8560/8801/5317 +f 8556/8797/5316 8560/8801/5317 8557/8798/5317 +f 8557/8798/5317 8560/8801/5317 8521/8762/5305 +f 8557/8798/5317 8521/8762/5305 8519/8760/5305 +f 8558/8799/5318 8557/8798/5317 8519/8760/5305 +f 8558/8799/5318 8519/8760/5305 8164/8406/5013 +f 8559/8800/5319 8561/8802/5320 8562/8803/5317 +f 8559/8800/5319 8562/8803/5317 8560/8801/5317 +f 8561/8802/5320 7979/8221/4846 8563/8804/5321 +f 8561/8802/5320 8563/8804/5321 8562/8803/5317 +f 8562/8803/5317 8563/8804/5321 8201/8443/5047 +f 8562/8803/5317 8201/8443/5047 8525/8766/5305 +f 8560/8801/5317 8562/8803/5317 8525/8766/5305 +f 8560/8801/5317 8525/8766/5305 8521/8762/5305 +f 8263/8505/5103 8564/8805/5322 8565/8806/5323 +f 8263/8505/5103 8565/8806/5323 8291/8533/5125 +f 8564/8805/5322 8566/8807/5322 8567/8808/5323 +f 8564/8805/5322 8567/8808/5323 8565/8806/5323 +f 8568/8809/5323 8569/8810/5323 8570/8811/5324 +f 8568/8809/5323 8570/8811/5324 8571/8812/5324 +f 8286/8528/5125 8568/8809/5323 8571/8812/5324 +f 8286/8528/5125 8571/8812/5324 8283/8525/5122 +f 8566/8807/5322 8572/8813/5322 8573/8814/5323 +f 8566/8807/5322 8573/8814/5323 8567/8808/5323 +f 8572/8813/5322 7742/7984/4628 7741/7983/4627 +f 8572/8813/5322 7741/7983/4627 8573/8814/5323 +f 8574/8815/5323 7738/7980/4627 7737/7979/4626 +f 8574/8815/5323 7737/7979/4626 8575/8816/5324 +f 8569/8810/5323 8574/8815/5323 8575/8816/5324 +f 8569/8810/5323 8575/8816/5324 8570/8811/5324 +f 8332/8573/4919 8576/8817/5315 8577/8818/5325 +f 8332/8573/4919 8577/8818/5325 8326/8567/5160 +f 8576/8817/5315 8578/8819/5315 8579/8820/5326 +f 8576/8817/5315 8579/8820/5326 8577/8818/5325 +f 8577/8818/5325 8579/8820/5326 8580/8821/5327 +f 8577/8818/5325 8580/8821/5327 8581/8822/5327 +f 8326/8567/5160 8577/8818/5325 8581/8822/5327 +f 8326/8567/5160 8581/8822/5327 8323/8564/5157 +f 8578/8819/5315 8582/8823/5315 8583/8824/5328 +f 8578/8819/5315 8583/8824/5328 8579/8820/5326 +f 8582/8823/5315 7962/8204/4829 7960/8202/4828 +f 8582/8823/5315 7960/8202/4828 8583/8824/5328 +f 8583/8824/5328 7960/8202/4828 7602/7844/4501 +f 8583/8824/5328 7602/7844/4501 8584/8825/5327 +f 8579/8820/5326 8583/8824/5328 8584/8825/5327 +f 8579/8820/5326 8584/8825/5327 8580/8821/5327 +f 7933/8175/4801 8545/8786/5313 8585/8826/5329 +f 7933/8175/4801 8585/8826/5329 7930/8172/4795 +f 8545/8786/5313 8544/8785/5313 8586/8827/5329 +f 8545/8786/5313 8586/8827/5329 8585/8826/5329 +f 8587/8828/5329 8588/8829/5329 8589/8830/5330 +f 8587/8828/5329 8589/8830/5330 8590/8831/5330 +f 7923/8165/4795 8587/8828/5329 8590/8831/5330 +f 7923/8165/4795 8590/8831/5330 7920/8162/4792 +f 8544/8785/5313 8548/8789/5313 8591/8832/5329 +f 8544/8785/5313 8591/8832/5329 8586/8827/5329 +f 8548/8789/5313 7652/7894/4544 7651/7893/4543 +f 8548/8789/5313 7651/7893/4543 8591/8832/5329 +f 8592/8833/5329 7648/7890/4543 7647/7889/4542 +f 8592/8833/5329 7647/7889/4542 8593/8834/5330 +f 8588/8829/5329 8592/8833/5329 8593/8834/5330 +f 8588/8829/5329 8593/8834/5330 8589/8830/5330 +f 8004/8246/4869 8464/8705/5275 8594/8835/5331 +f 8004/8246/4869 8594/8835/5331 7999/8241/4865 +f 8464/8705/5275 8463/8704/5275 8595/8836/5331 +f 8464/8705/5275 8595/8836/5331 8594/8835/5331 +f 8594/8835/5331 8595/8836/5331 8596/8837/5332 +f 8594/8835/5331 8596/8837/5332 8597/8838/5332 +f 7999/8241/4865 8594/8835/5331 8597/8838/5332 +f 7999/8241/4865 8597/8838/5332 7996/8238/4862 +f 8463/8704/5275 8467/8708/5275 8598/8839/5331 +f 8463/8704/5275 8598/8839/5331 8595/8836/5331 +f 8467/8708/5275 7946/8188/4814 7944/8186/4812 +f 8467/8708/5275 7944/8186/4812 8598/8839/5331 +f 8598/8839/5331 7944/8186/4812 7852/8094/4728 +f 8598/8839/5331 7852/8094/4728 8599/8840/5332 +f 8595/8836/5331 8598/8839/5331 8599/8840/5332 +f 8595/8836/5331 8599/8840/5332 8596/8837/5332 +f 7831/8073/4708 8600/8841/5333 8601/8842/5334 +f 7831/8073/4708 8601/8842/5334 7823/8065/4702 +f 8600/8841/5333 8602/8843/5333 8603/8844/5334 +f 8600/8841/5333 8603/8844/5334 8601/8842/5334 +f 8601/8842/5334 8603/8844/5334 8604/8845/5335 +f 8601/8842/5334 8604/8845/5335 8605/8846/5335 +f 7823/8065/4702 8601/8842/5334 8605/8846/5335 +f 7823/8065/4702 8605/8846/5335 7820/8062/4699 +f 8602/8843/5333 8606/8847/5333 8607/8848/5334 +f 8602/8843/5333 8607/8848/5334 8603/8844/5334 +f 8606/8847/5333 7626/7868/4522 7624/7866/4521 +f 8606/8847/5333 7624/7866/4521 8607/8848/5334 +f 8607/8848/5334 7624/7866/4521 7623/7865/4520 +f 8607/8848/5334 7623/7865/4520 8608/8849/5335 +f 8603/8844/5334 8607/8848/5334 8608/8849/5335 +f 8603/8844/5334 8608/8849/5335 8604/8845/5335 +f 8252/8494/5094 8609/8850/5336 8610/8851/5337 +f 8252/8494/5094 8610/8851/5337 8244/8486/5087 +f 8609/8850/5336 8611/8852/5338 8612/8853/5339 +f 8609/8850/5336 8612/8853/5339 8610/8851/5337 +f 8610/8851/5337 8612/8853/5339 8495/8736/5291 +f 8610/8851/5337 8495/8736/5291 8613/8854/5340 +f 8244/8486/5087 8610/8851/5337 8613/8854/5340 +f 8244/8486/5087 8613/8854/5340 8241/8483/5084 +f 8611/8852/5338 8614/8855/5341 8615/8856/5342 +f 8611/8852/5338 8615/8856/5342 8612/8853/5339 +f 8614/8855/5341 7729/7971/4618 8387/8628/5213 +f 8614/8855/5341 8387/8628/5213 8615/8856/5342 +f 8615/8856/5342 8387/8628/5213 8129/8371/4983 +f 8615/8856/5342 8129/8371/4983 8496/8737/5292 +f 8612/8853/5339 8615/8856/5342 8496/8737/5292 +f 8612/8853/5339 8496/8737/5292 8495/8736/5291 +f 8262/8504/5102 8616/8857/5343 8617/8858/5344 +f 8262/8504/5102 8617/8858/5344 8256/8498/5096 +f 8616/8857/5343 8618/8859/5343 8619/8860/5344 +f 8616/8857/5343 8619/8860/5344 8617/8858/5344 +f 8617/8858/5344 8619/8860/5344 8620/8861/5345 +f 8617/8858/5344 8620/8861/5345 8621/8862/5345 +f 8256/8498/5096 8617/8858/5344 8621/8862/5345 +f 8256/8498/5096 8621/8862/5345 8253/8495/5063 +f 8618/8859/5343 8622/8863/5343 8623/8864/5344 +f 8618/8859/5343 8623/8864/5344 8619/8860/5344 +f 8622/8863/5343 8145/8387/4917 8143/8385/4996 +f 8622/8863/5343 8143/8385/4996 8623/8864/5344 +f 8623/8864/5344 8143/8385/4996 8142/8384/4995 +f 8623/8864/5344 8142/8384/4995 8624/8865/5345 +f 8619/8860/5344 8623/8864/5344 8624/8865/5345 +f 8619/8860/5344 8624/8865/5345 8620/8861/5345 +f 8274/8516/5113 8625/8866/5346 8626/8867/5347 +f 8274/8516/5113 8626/8867/5347 8266/8508/5106 +f 8625/8866/5346 8627/8868/5346 8628/8869/5347 +f 8625/8866/5346 8628/8869/5347 8626/8867/5347 +f 8626/8867/5347 8628/8869/5347 8566/8807/5322 +f 8626/8867/5347 8566/8807/5322 8564/8805/5322 +f 8266/8508/5106 8626/8867/5347 8564/8805/5322 +f 8266/8508/5106 8564/8805/5322 8263/8505/5103 +f 8627/8868/5346 8629/8870/5346 8630/8871/5347 +f 8627/8868/5346 8630/8871/5347 8628/8869/5347 +f 8629/8870/5346 8078/8320/4937 8123/8365/4978 +f 8629/8870/5346 8123/8365/4978 8630/8871/5347 +f 8630/8871/5347 8123/8365/4978 7742/7984/4628 +f 8630/8871/5347 7742/7984/4628 8572/8813/5322 +f 8628/8869/5347 8630/8871/5347 8572/8813/5322 +f 8628/8869/5347 8572/8813/5322 8566/8807/5322 +f 8081/8323/4939 8482/8723/5282 8631/8872/5348 +f 8081/8323/4939 8631/8872/5348 8276/8518/5115 +f 8482/8723/5282 8481/8722/5282 8632/8873/5348 +f 8482/8723/5282 8632/8873/5348 8631/8872/5348 +f 8631/8872/5348 8632/8873/5348 8602/8843/5333 +f 8631/8872/5348 8602/8843/5333 8600/8841/5333 +f 8276/8518/5115 8631/8872/5348 8600/8841/5333 +f 8276/8518/5115 8600/8841/5333 7831/8073/4708 +f 8481/8722/5282 8485/8726/5282 8633/8874/5348 +f 8481/8722/5282 8633/8874/5348 8632/8873/5348 +f 8485/8726/5282 7893/8135/4766 8071/8313/4931 +f 8485/8726/5282 8071/8313/4931 8633/8874/5348 +f 8633/8874/5348 8071/8313/4931 7626/7868/4522 +f 8633/8874/5348 7626/7868/4522 8606/8847/5333 +f 8632/8873/5348 8633/8874/5348 8606/8847/5333 +f 8632/8873/5348 8606/8847/5333 8602/8843/5333 +f 7908/8150/4780 8634/8875/5349 8635/8876/5350 +f 7908/8150/4780 8635/8876/5350 8280/8522/5119 +f 8634/8875/5349 8636/8877/5349 8637/8878/5350 +f 8634/8875/5349 8637/8878/5350 8635/8876/5350 +f 8635/8876/5350 8637/8878/5350 8461/8702/5273 +f 8635/8876/5350 8461/8702/5273 8459/8700/5273 +f 8280/8522/5119 8635/8876/5350 8459/8700/5273 +f 8280/8522/5119 8459/8700/5273 8120/8362/4975 +f 8636/8877/5349 8638/8879/5349 8639/8880/5350 +f 8636/8877/5349 8639/8880/5350 8637/8878/5350 +f 8638/8879/5349 7673/7915/4563 8413/8654/5237 +f 8638/8879/5349 8413/8654/5237 8639/8880/5350 +f 8639/8880/5350 8413/8654/5237 8229/8471/5073 +f 8639/8880/5350 8229/8471/5073 8465/8706/5273 +f 8637/8878/5350 8639/8880/5350 8465/8706/5273 +f 8637/8878/5350 8465/8706/5273 8461/8702/5273 +f 7907/8149/4779 8640/8881/5351 8641/8882/5352 +f 7907/8149/4779 8641/8882/5352 7901/8143/4773 +f 8640/8881/5351 8642/8883/5351 8643/8884/5352 +f 8640/8881/5351 8643/8884/5352 8641/8882/5352 +f 8641/8882/5352 8643/8884/5352 8644/8885/5353 +f 8641/8882/5352 8644/8885/5353 8645/8886/5353 +f 7901/8143/4773 8641/8882/5352 8645/8886/5353 +f 7901/8143/4773 8645/8886/5353 7843/8085/4719 +f 8642/8883/5351 8646/8887/5351 8647/8888/5352 +f 8642/8883/5351 8647/8888/5352 8643/8884/5352 +f 8646/8887/5351 7861/8103/4737 7874/8116/4749 +f 8646/8887/5351 7874/8116/4749 8647/8888/5352 +f 8647/8888/5352 7874/8116/4749 7614/7856/4511 +f 8647/8888/5352 7614/7856/4511 8648/8889/5353 +f 8643/8884/5352 8647/8888/5352 8648/8889/5353 +f 8643/8884/5352 8648/8889/5353 8644/8885/5353 +f 7996/8238/4862 8597/8838/5332 8649/8890/5354 +f 7996/8238/4862 8649/8890/5354 8300/8542/5137 +f 8597/8838/5332 8596/8837/5332 8650/8891/5354 +f 8597/8838/5332 8650/8891/5354 8649/8890/5354 +f 8649/8890/5354 8650/8891/5354 8651/8892/5355 +f 8649/8890/5354 8651/8892/5355 8652/8893/5355 +f 8300/8542/5137 8649/8890/5354 8652/8893/5355 +f 8300/8542/5137 8652/8893/5355 8297/8539/5134 +f 8596/8837/5332 8599/8840/5332 8653/8894/5354 +f 8596/8837/5332 8653/8894/5354 8650/8891/5354 +f 8599/8840/5332 7852/8094/4728 7850/8092/4726 +f 8599/8840/5332 7850/8092/4726 8653/8894/5354 +f 8653/8894/5354 7850/8092/4726 7849/8091/4725 +f 8653/8894/5354 7849/8091/4725 8654/8895/5355 +f 8650/8891/5354 8653/8894/5354 8654/8895/5355 +f 8650/8891/5354 8654/8895/5355 8651/8892/5355 +f 8348/8589/5179 8655/8896/5356 8656/8897/5357 +f 8348/8589/5179 8656/8897/5357 8342/8583/5174 +f 8655/8896/5356 8657/8898/5358 8658/8899/5359 +f 8655/8896/5356 8658/8899/5359 8656/8897/5357 +f 8656/8897/5357 8658/8899/5359 8659/8900/5360 +f 8656/8897/5357 8659/8900/5360 8660/8901/5361 +f 8342/8583/5174 8656/8897/5357 8660/8901/5361 +f 8342/8583/5174 8660/8901/5361 8340/8581/5172 +f 8657/8898/5358 8661/8902/5362 8662/8903/5363 +f 8657/8898/5358 8662/8903/5363 8658/8899/5359 +f 8661/8902/5362 7808/8050/4688 7806/8048/4686 +f 8661/8902/5362 7806/8048/4686 8662/8903/5363 +f 8662/8903/5363 7806/8048/4686 7805/8047/4685 +f 8662/8903/5363 7805/8047/4685 8663/8904/5364 +f 8658/8899/5359 8662/8903/5363 8663/8904/5364 +f 8658/8899/5359 8663/8904/5364 8659/8900/5360 +f 8297/8539/5134 8652/8893/5355 8664/8905/5365 +f 8297/8539/5134 8664/8905/5365 8304/8546/5139 +f 8652/8893/5355 8651/8892/5355 8665/8906/5365 +f 8652/8893/5355 8665/8906/5365 8664/8905/5365 +f 8664/8905/5365 8665/8906/5365 8542/8783/5311 +f 8664/8905/5365 8542/8783/5311 8540/8781/5311 +f 8304/8546/5139 8664/8905/5365 8540/8781/5311 +f 8304/8546/5139 8540/8781/5311 8180/8422/5028 +f 8651/8892/5355 8654/8895/5355 8666/8907/5365 +f 8651/8892/5355 8666/8907/5365 8665/8906/5365 +f 8654/8895/5355 7849/8091/4725 7870/8112/4745 +f 8654/8895/5355 7870/8112/4745 8666/8907/5365 +f 8666/8907/5365 7870/8112/4745 7869/8111/4744 +f 8666/8907/5365 7869/8111/4744 8546/8787/5311 +f 8665/8906/5365 8666/8907/5365 8546/8787/5311 +f 8665/8906/5365 8546/8787/5311 8542/8783/5311 +f 8439/8680/5259 8667/8908/5366 8668/8909/5367 +f 8439/8680/5259 8668/8909/5367 8669/8910/5368 +f 8667/8908/5366 8670/8911/5369 8671/8912/5370 +f 8667/8908/5366 8671/8912/5370 8668/8909/5367 +f 8668/8909/5367 8671/8912/5370 8657/8898/5358 +f 8668/8909/5367 8657/8898/5358 8655/8896/5356 +f 8669/8910/5368 8668/8909/5367 8655/8896/5356 +f 8669/8910/5368 8655/8896/5356 8348/8589/5179 +f 8670/8911/5369 8672/8913/5371 8673/8914/5372 +f 8670/8911/5369 8673/8914/5372 8671/8912/5370 +f 8672/8913/5371 7775/8017/4660 8363/8604/5193 +f 8672/8913/5371 8363/8604/5193 8673/8914/5372 +f 8673/8914/5372 8363/8604/5193 7808/8050/4688 +f 8673/8914/5372 7808/8050/4688 8661/8902/5362 +f 8671/8912/5370 8673/8914/5372 8661/8902/5362 +f 8671/8912/5370 8661/8902/5362 8657/8898/5358 +f 8322/8563/5156 8674/8915/5373 8675/8916/5374 +f 8322/8563/5156 8675/8916/5374 8319/8560/5153 +f 8674/8915/5373 8676/8917/5373 8677/8918/5375 +f 8674/8915/5373 8677/8918/5375 8675/8916/5374 +f 8678/8919/5376 8679/8920/5374 8680/8921/5377 +f 8678/8919/5376 8680/8921/5377 8681/8922/5377 +f 8314/8555/5148 8678/8919/5376 8681/8922/5377 +f 8314/8555/5148 8681/8922/5377 7919/8161/4791 +f 8676/8917/5373 8682/8923/5373 8683/8924/5375 +f 8676/8917/5373 8683/8924/5375 8677/8918/5375 +f 8682/8923/5373 7721/7963/4610 8394/8635/5217 +f 8682/8923/5373 8394/8635/5217 8683/8924/5375 +f 8684/8925/5375 8391/8632/5217 7676/7918/4566 +f 8684/8925/5375 7676/7918/4566 8685/8926/5377 +f 8679/8920/5374 8684/8925/5375 8685/8926/5377 +f 8679/8920/5374 8685/8926/5377 8680/8921/5377 +f 8101/8343/4957 8455/8696/5272 8686/8927/5378 +f 8101/8343/4957 8686/8927/5378 8352/8593/5183 +f 8455/8696/5272 8454/8695/5272 8687/8928/5378 +f 8455/8696/5272 8687/8928/5378 8686/8927/5378 +f 8686/8927/5378 8687/8928/5378 8688/8929/5379 +f 8686/8927/5378 8688/8929/5379 8689/8930/5379 +f 8352/8593/5183 8686/8927/5378 8689/8930/5379 +f 8352/8593/5183 8689/8930/5379 8349/8590/5180 +f 8454/8695/5272 8458/8699/5272 8690/8931/5378 +f 8454/8695/5272 8690/8931/5378 8687/8928/5378 +f 8458/8699/5272 7766/8008/4651 7764/8006/4649 +f 8458/8699/5272 7764/8006/4649 8690/8931/5378 +f 8690/8931/5378 7764/8006/4649 7763/8005/4648 +f 8690/8931/5378 7763/8005/4648 8691/8932/5379 +f 8687/8928/5378 8690/8931/5378 8691/8932/5379 +f 8687/8928/5378 8691/8932/5379 8688/8929/5379 +f 8340/8581/5172 8660/8901/5361 8692/8933/5380 +f 8340/8581/5172 8692/8933/5380 8334/8575/5166 +f 8660/8901/5361 8659/8900/5360 8693/8934/5380 +f 8660/8901/5361 8693/8934/5380 8692/8933/5380 +f 8692/8933/5380 8693/8934/5380 8642/8883/5351 +f 8692/8933/5380 8642/8883/5351 8640/8881/5351 +f 8334/8575/5166 8692/8933/5380 8640/8881/5351 +f 8334/8575/5166 8640/8881/5351 7907/8149/4779 +f 8659/8900/5360 8663/8904/5364 8694/8935/5380 +f 8659/8900/5360 8694/8935/5380 8693/8934/5380 +f 8663/8904/5364 7805/8047/4685 7862/8104/4738 +f 8663/8904/5364 7862/8104/4738 8694/8935/5380 +f 8694/8935/5380 7862/8104/4738 7861/8103/4737 +f 8694/8935/5380 7861/8103/4737 8646/8887/5351 +f 8693/8934/5380 8694/8935/5380 8646/8887/5351 +f 8693/8934/5380 8646/8887/5351 8642/8883/5351 +f 8253/8495/5063 8621/8862/5345 8695/8936/5381 +f 8253/8495/5063 8695/8936/5381 8696/8937/5058 +f 8621/8862/5345 8620/8861/5345 8697/8938/5381 +f 8621/8862/5345 8697/8938/5381 8695/8936/5381 +f 8698/8939/5381 8699/8940/5381 8700/8941/5382 +f 8698/8939/5381 8700/8941/5382 8701/8942/5382 +f 8212/8454/5058 8698/8939/5381 8701/8942/5382 +f 8212/8454/5058 8701/8942/5382 8209/8451/5055 +f 8620/8861/5345 8624/8865/5345 8702/8943/5381 +f 8620/8861/5345 8702/8943/5381 8697/8938/5381 +f 8624/8865/5345 8142/8384/4995 8703/8944/5383 +f 8624/8865/5345 8703/8944/5383 8702/8943/5381 +f 8704/8945/5381 7794/8036/4676 7793/8035/4675 +f 8704/8945/5381 7793/8035/4675 8705/8946/5382 +f 8699/8940/5381 8704/8945/5381 8705/8946/5382 +f 8699/8940/5381 8705/8946/5382 8700/8941/5382 +f 8048/8290/4911 8706/8947/5382 8707/8948/5384 +f 8048/8290/4911 8707/8948/5384 8040/8282/4904 +f 8706/8947/5382 8708/8949/5382 8709/8950/5384 +f 8706/8947/5382 8709/8950/5384 8707/8948/5384 +f 8707/8948/5384 8709/8950/5384 8710/8951/5385 +f 8707/8948/5384 8710/8951/5385 8711/8952/5385 +f 8040/8282/4904 8707/8948/5384 8711/8952/5385 +f 8040/8282/4904 8711/8952/5385 8037/8279/4901 +f 8708/8949/5382 8712/8953/5382 8713/8954/5384 +f 8708/8949/5382 8713/8954/5384 8709/8950/5384 +f 8712/8953/5382 7754/7996/4639 7752/7994/4638 +f 8712/8953/5382 7752/7994/4638 8713/8954/5384 +f 8713/8954/5384 7752/7994/4638 7751/7993/4637 +f 8713/8954/5384 7751/7993/4637 8714/8955/5385 +f 8709/8950/5384 8713/8954/5384 8714/8955/5385 +f 8709/8950/5384 8714/8955/5385 8710/8951/5385 +f 7887/8129/4761 8715/8956/5386 8716/8957/5387 +f 7887/8129/4761 8716/8957/5387 7879/8121/4754 +f 8715/8956/5386 8717/8958/5386 8718/8959/5387 +f 8715/8956/5386 8718/8959/5387 8716/8957/5387 +f 8716/8957/5387 8718/8959/5387 8719/8960/5388 +f 8716/8957/5387 8719/8960/5388 8720/8961/5388 +f 7879/8121/4754 8716/8957/5387 8720/8961/5388 +f 7879/8121/4754 8720/8961/5388 7876/8118/4751 +f 8717/8958/5386 8721/8962/5386 8722/8963/5387 +f 8717/8958/5386 8722/8963/5387 8718/8959/5387 +f 8721/8962/5386 7688/7930/4578 7686/7928/4576 +f 8721/8962/5386 7686/7928/4576 8722/8963/5387 +f 8722/8963/5387 7686/7928/4576 7685/7927/4575 +f 8722/8963/5387 7685/7927/4575 8723/8964/5388 +f 8718/8959/5387 8722/8963/5387 8723/8964/5388 +f 8718/8959/5387 8723/8964/5388 8719/8960/5388 +f 8323/8564/5157 8581/8822/5327 8724/8965/5389 +f 8323/8564/5157 8724/8965/5389 8725/8966/5390 +f 8581/8822/5327 8580/8821/5327 8726/8967/5389 +f 8581/8822/5327 8726/8967/5389 8724/8965/5389 +f 8724/8965/5389 8726/8967/5389 8727/8968/5391 +f 8724/8965/5389 8727/8968/5391 8728/8969/5391 +f 8725/8966/5390 8724/8965/5389 8728/8969/5391 +f 8725/8966/5390 8728/8969/5391 8449/8690/5268 +f 8580/8821/5327 8584/8825/5327 8729/8970/5389 +f 8580/8821/5327 8729/8970/5389 8726/8967/5389 +f 8584/8825/5327 7602/7844/4501 7600/7842/4499 +f 8584/8825/5327 7600/7842/4499 8729/8970/5389 +f 8729/8970/5389 7600/7842/4499 7599/7841/4498 +f 8729/8970/5389 7599/7841/4498 8730/8971/5391 +f 8726/8967/5389 8729/8970/5389 8730/8971/5391 +f 8726/8967/5389 8730/8971/5391 8727/8968/5391 +f 8365/8606/5195 8731/8972/5392 8732/8973/5393 +f 8365/8606/5195 8732/8973/5393 8733/8974/5394 +f 8731/8972/5392 8734/8975/5392 8735/8976/5393 +f 8731/8972/5392 8735/8976/5393 8732/8973/5393 +f 8736/8977/5393 8737/8978/5393 8717/8958/5386 +f 8736/8977/5393 8717/8958/5386 8715/8956/5386 +f 8738/8979/5394 8736/8977/5393 8715/8956/5386 +f 8738/8979/5394 8715/8956/5386 7887/8129/4761 +f 8734/8975/5392 8739/8980/5392 8740/8981/5393 +f 8734/8975/5392 8740/8981/5393 8735/8976/5393 +f 8739/8980/5392 7817/8059/4696 8741/8982/5395 +f 8739/8980/5392 8741/8982/5395 8740/8981/5393 +f 8742/8983/5393 8743/8984/5396 7688/7930/4578 +f 8742/8983/5393 7688/7930/4578 8721/8962/5386 +f 8737/8978/5393 8742/8983/5393 8721/8962/5386 +f 8737/8978/5393 8721/8962/5386 8717/8958/5386 +f 8380/8621/4901 8744/8985/5385 8745/8986/5397 +f 8380/8621/4901 8745/8986/5397 8377/8618/5204 +f 8744/8985/5385 8746/8987/5385 8747/8988/5397 +f 8744/8985/5385 8747/8988/5397 8745/8986/5397 +f 8748/8989/5397 8749/8990/5397 8470/8711/5277 +f 8748/8989/5397 8470/8711/5277 8468/8709/5277 +f 8374/8615/5204 8748/8989/5397 8468/8709/5277 +f 8374/8615/5204 8468/8709/5277 8024/8266/4888 +f 8746/8987/5385 8750/8991/5385 8751/8992/5397 +f 8746/8987/5385 8751/8992/5397 8747/8988/5397 +f 8750/8991/5385 7788/8030/4637 7787/8029/4669 +f 8750/8991/5385 7787/8029/4669 8751/8992/5397 +f 8752/8993/5397 7784/8026/4669 7712/7954/4601 +f 8752/8993/5397 7712/7954/4601 8474/8715/5277 +f 8749/8990/5397 8752/8993/5397 8474/8715/5277 +f 8749/8990/5397 8474/8715/5277 8470/8711/5277 +f 8283/8525/5122 8571/8812/5324 8753/8994/5398 +f 8283/8525/5122 8753/8994/5398 8382/8623/5208 +f 8571/8812/5324 8570/8811/5324 8754/8995/5398 +f 8571/8812/5324 8754/8995/5398 8753/8994/5398 +f 8753/8994/5398 8754/8995/5398 8512/8753/5302 +f 8753/8994/5398 8512/8753/5302 8510/8751/5302 +f 8382/8623/5208 8753/8994/5398 8510/8751/5302 +f 8382/8623/5208 8510/8751/5302 8154/8396/5006 +f 8570/8811/5324 8575/8816/5324 8755/8996/5398 +f 8570/8811/5324 8755/8996/5398 8754/8995/5398 +f 8575/8816/5324 7737/7979/4626 7972/8214/4839 +f 8575/8816/5324 7972/8214/4839 8755/8996/5398 +f 8755/8996/5398 7972/8214/4839 7971/8213/4838 +f 8755/8996/5398 7971/8213/4838 8516/8757/5302 +f 8754/8995/5398 8755/8996/5398 8516/8757/5302 +f 8754/8995/5398 8516/8757/5302 8512/8753/5302 +f 7703/7945/4593 8756/8997/5399 8757/8998/5400 +f 7703/7945/4593 8757/8998/5400 7695/7937/4585 +f 8756/8997/5399 8758/8999/5399 8759/9000/5400 +f 8756/8997/5399 8759/9000/5400 8757/8998/5400 +f 8757/8998/5400 8759/9000/5400 8760/9001/5401 +f 8757/8998/5400 8760/9001/5401 8761/9002/5401 +f 7695/7937/4585 8757/8998/5400 8761/9002/5401 +f 7695/7937/4585 8761/9002/5401 7692/7934/4582 +f 8758/8999/5399 8762/9003/5399 8763/9004/5400 +f 8758/8999/5399 8763/9004/5400 8759/9000/5400 +f 8762/9003/5399 7638/7880/4533 7636/7878/4531 +f 8762/9003/5399 7636/7878/4531 8763/9004/5400 +f 8763/9004/5400 7636/7878/4531 7635/7877/4530 +f 8763/9004/5400 7635/7877/4530 8764/9005/5401 +f 8759/9000/5400 8763/9004/5400 8764/9005/5401 +f 8759/9000/5400 8764/9005/5401 8760/9001/5401 +f 7843/8085/4719 8645/8886/5353 8765/9006/5402 +f 7843/8085/4719 8765/9006/5402 7835/8077/4712 +f 8645/8886/5353 8644/8885/5353 8766/9007/5402 +f 8645/8886/5353 8766/9007/5402 8765/9006/5402 +f 8765/9006/5402 8766/9007/5402 8767/9008/5403 +f 8765/9006/5402 8767/9008/5403 8768/9009/5403 +f 7835/8077/4712 8765/9006/5402 8768/9009/5403 +f 7835/8077/4712 8768/9009/5403 7832/8074/4709 +f 8644/8885/5353 8648/8889/5353 8769/9010/5402 +f 8644/8885/5353 8769/9010/5402 8766/9007/5402 +f 8648/8889/5353 7614/7856/4511 7612/7854/4509 +f 8648/8889/5353 7612/7854/4509 8769/9010/5402 +f 8769/9010/5402 7612/7854/4509 7611/7853/4508 +f 8769/9010/5402 7611/7853/4508 8770/9011/5403 +f 8766/9007/5402 8769/9010/5402 8770/9011/5403 +f 8766/9007/5402 8770/9011/5403 8767/9008/5403 +f 8013/8255/4878 8473/8714/5279 8771/9012/5404 +f 8013/8255/4878 8771/9012/5404 8396/8637/5221 +f 8473/8714/5279 8472/8713/5279 8772/9013/5404 +f 8473/8714/5279 8772/9013/5404 8771/9012/5404 +f 8771/9012/5404 8772/9013/5404 8627/8868/5346 +f 8771/9012/5404 8627/8868/5346 8625/8866/5346 +f 8396/8637/5221 8771/9012/5404 8625/8866/5346 +f 8396/8637/5221 8625/8866/5346 8274/8516/5113 +f 8472/8713/5279 8476/8717/5279 8773/9014/5404 +f 8472/8713/5279 8773/9014/5404 8772/9013/5404 +f 8476/8717/5279 7709/7951/4598 8079/8321/4938 +f 8476/8717/5279 8079/8321/4938 8773/9014/5404 +f 8773/9014/5404 8079/8321/4938 8078/8320/4937 +f 8773/9014/5404 8078/8320/4937 8629/8870/5346 +f 8772/9013/5404 8773/9014/5404 8629/8870/5346 +f 8772/9013/5404 8629/8870/5346 8627/8868/5346 +f 8406/8647/5230 8774/9015/5405 8775/9016/5406 +f 8406/8647/5230 8775/9016/5406 8400/8641/5224 +f 8774/9015/5405 8776/9017/5405 8777/9018/5406 +f 8774/9015/5405 8777/9018/5406 8775/9016/5406 +f 8775/9016/5406 8777/9018/5406 8530/8771/5307 +f 8775/9016/5406 8530/8771/5307 8528/8769/5307 +f 8400/8641/5224 8775/9016/5406 8528/8769/5307 +f 8400/8641/5224 8528/8769/5307 8172/8414/5020 +f 8776/9017/5405 8778/9019/5405 8779/9020/5406 +f 8776/9017/5405 8779/9020/5406 8777/9018/5406 +f 8778/9019/5405 7939/8181/4807 8239/8481/5082 +f 8778/9019/5405 8239/8481/5082 8779/9020/5406 +f 8779/9020/5406 8239/8481/5082 8238/8480/5081 +f 8779/9020/5406 8238/8480/5081 8534/8775/5307 +f 8777/9018/5406 8779/9020/5406 8534/8775/5307 +f 8777/9018/5406 8534/8775/5307 8530/8771/5307 +f 7876/8118/4751 8720/8961/5388 8780/9021/5407 +f 7876/8118/4751 8780/9021/5407 8408/8649/5232 +f 8720/8961/5388 8719/8960/5388 8781/9022/5407 +f 8720/8961/5388 8781/9022/5407 8780/9021/5407 +f 8780/9021/5407 8781/9022/5407 8758/8999/5399 +f 8780/9021/5407 8758/8999/5399 8756/8997/5399 +f 8408/8649/5232 8780/9021/5407 8756/8997/5399 +f 8408/8649/5232 8756/8997/5399 7703/7945/4593 +f 8719/8960/5388 8723/8964/5388 8782/9023/5407 +f 8719/8960/5388 8782/9023/5407 8781/9022/5407 +f 8723/8964/5388 7685/7927/4575 7780/8022/4665 +f 8723/8964/5388 7780/8022/4665 8782/9023/5407 +f 8782/9023/5407 7780/8022/4665 7638/7880/4533 +f 8782/9023/5407 7638/7880/4533 8762/9003/5399 +f 8781/9022/5407 8782/9023/5407 8762/9003/5399 +f 8781/9022/5407 8762/9003/5399 8758/8999/5399 +f 7919/8161/4791 8681/8922/5377 8783/9024/5408 +f 7919/8161/4791 8783/9024/5408 7911/8153/4783 +f 8681/8922/5377 8680/8921/5377 8784/9025/5408 +f 8681/8922/5377 8784/9025/5408 8783/9024/5408 +f 8783/9024/5408 8784/9025/5408 8636/8877/5349 +f 8783/9024/5408 8636/8877/5349 8634/8875/5349 +f 7911/8153/4783 8783/9024/5408 8634/8875/5349 +f 7911/8153/4783 8634/8875/5349 7908/8150/4780 +f 8680/8921/5377 8685/8926/5377 8785/9026/5408 +f 8680/8921/5377 8785/9026/5408 8784/9025/5408 +f 8685/8926/5377 7676/7918/4566 7674/7916/4564 +f 8685/8926/5377 7674/7916/4564 8785/9026/5408 +f 8785/9026/5408 7674/7916/4564 7673/7915/4563 +f 8785/9026/5408 7673/7915/4563 8638/8879/5349 +f 8784/9025/5408 8785/9026/5408 8638/8879/5349 +f 8784/9025/5408 8638/8879/5349 8636/8877/5349 +f 8089/8331/4946 8506/8747/5300 8786/9027/5409 +f 8089/8331/4946 8786/9027/5409 8418/8659/5241 +f 8506/8747/5300 8505/8746/5300 8787/9028/5409 +f 8506/8747/5300 8787/9028/5409 8786/9027/5409 +f 8786/9027/5409 8787/9028/5409 8788/9029/5343 +f 8786/9027/5409 8788/9029/5343 8789/9030/5343 +f 8418/8659/5241 8786/9027/5409 8789/9030/5343 +f 8418/8659/5241 8789/9030/5343 8415/8656/5102 +f 8505/8746/5300 8509/8750/5301 8790/9031/5409 +f 8505/8746/5300 8790/9031/5409 8787/9028/5409 +f 8509/8750/5301 7661/7903/4552 8055/8297/4918 +f 8509/8750/5301 8055/8297/4918 8790/9031/5409 +f 8790/9031/5409 8055/8297/4918 8054/8296/4917 +f 8790/9031/5409 8054/8296/4917 8791/9032/5343 +f 8787/9028/5409 8790/9031/5409 8791/9032/5343 +f 8787/9028/5409 8791/9032/5343 8788/9029/5343 +f 7920/8162/4792 8590/8831/5330 8792/9033/5410 +f 7920/8162/4792 8792/9033/5410 8424/8665/5246 +f 8590/8831/5330 8589/8830/5330 8793/9034/5410 +f 8590/8831/5330 8793/9034/5410 8792/9033/5410 +f 8792/9033/5410 8793/9034/5410 8794/9035/5271 +f 8792/9033/5410 8794/9035/5271 8795/9036/5271 +f 8424/8665/5246 8792/9033/5410 8795/9036/5271 +f 8424/8665/5246 8795/9036/5271 8421/8662/4967 +f 8589/8830/5330 8593/8834/5330 8796/9037/5410 +f 8589/8830/5330 8796/9037/5410 8793/9034/5410 +f 8593/8834/5330 7647/7889/4542 7956/8198/4824 +f 8593/8834/5330 7956/8198/4824 8796/9037/5410 +f 8796/9037/5410 7956/8198/4824 7955/8197/4823 +f 8796/9037/5410 7955/8197/4823 8797/9038/5271 +f 8793/9034/5410 8796/9037/5410 8797/9038/5271 +f 8793/9034/5410 8797/9038/5271 8794/9035/5271 +f 7692/7934/4582 8761/9002/5401 8798/9039/5411 +f 7692/7934/4582 8798/9039/5411 8428/8669/5249 +f 8761/9002/5401 8760/9001/5401 8799/9040/5411 +f 8761/9002/5401 8799/9040/5411 8798/9039/5411 +f 8798/9039/5411 8799/9040/5411 8611/8852/5338 +f 8798/9039/5411 8611/8852/5338 8609/8850/5336 +f 8428/8669/5249 8798/9039/5411 8609/8850/5336 +f 8428/8669/5249 8609/8850/5336 8252/8494/5094 +f 8760/9001/5401 8764/9005/5401 8800/9041/5411 +f 8760/9001/5401 8800/9041/5411 8799/9040/5411 +f 8764/9005/5401 7635/7877/4530 7730/7972/4619 +f 8764/9005/5401 7730/7972/4619 8800/9041/5411 +f 8800/9041/5411 7730/7972/4619 7729/7971/4618 +f 8800/9041/5411 7729/7971/4618 8614/8855/5341 +f 8799/9040/5411 8800/9041/5411 8614/8855/5341 +f 8799/9040/5411 8614/8855/5341 8611/8852/5338 +f 7820/8062/4699 8605/8846/5335 8801/9042/5412 +f 7820/8062/4699 8801/9042/5412 8432/8673/5253 +f 8605/8846/5335 8604/8845/5335 8802/9043/5412 +f 8605/8846/5335 8802/9043/5412 8801/9042/5412 +f 8801/9042/5412 8802/9043/5412 8776/9017/5405 +f 8801/9042/5412 8776/9017/5405 8774/9015/5405 +f 8432/8673/5253 8801/9042/5412 8774/9015/5405 +f 8432/8673/5253 8774/9015/5405 8406/8647/5230 +f 8604/8845/5335 8608/8849/5335 8803/9044/5412 +f 8604/8845/5335 8803/9044/5412 8802/9043/5412 +f 8608/8849/5335 7623/7865/4520 7940/8182/4808 +f 8608/8849/5335 7940/8182/4808 8803/9044/5412 +f 8803/9044/5412 7940/8182/4808 7939/8181/4807 +f 8803/9044/5412 7939/8181/4807 8778/9019/5405 +f 8802/9043/5412 8803/9044/5412 8778/9019/5405 +f 8802/9043/5412 8778/9019/5405 8776/9017/5405 +f 7832/8074/4709 8768/9009/5403 8804/9045/5413 +f 7832/8074/4709 8804/9045/5413 8436/8677/5257 +f 8768/9009/5403 8767/9008/5403 8805/9046/5413 +f 8768/9009/5403 8805/9046/5413 8804/9045/5413 +f 8804/9045/5413 8805/9046/5413 8676/8917/5373 +f 8804/9045/5413 8676/8917/5373 8674/8915/5373 +f 8436/8677/5257 8804/9045/5413 8674/8915/5373 +f 8436/8677/5257 8674/8915/5373 8322/8563/5156 +f 8767/9008/5403 8770/9011/5403 8806/9047/5413 +f 8767/9008/5403 8806/9047/5413 8805/9046/5413 +f 8770/9011/5403 7611/7853/4508 7722/7964/4611 +f 8770/9011/5403 7722/7964/4611 8806/9047/5413 +f 8806/9047/5413 7722/7964/4611 7721/7963/4610 +f 8806/9047/5413 7721/7963/4610 8682/8923/5373 +f 8805/9046/5413 8806/9047/5413 8682/8923/5373 +f 8805/9046/5413 8682/8923/5373 8676/8917/5373 +f 8449/8690/5268 8728/8969/5391 8807/9048/5414 +f 8449/8690/5268 8807/9048/5414 8442/8683/5262 +f 8728/8969/5391 8727/8968/5391 8808/9049/5415 +f 8728/8969/5391 8808/9049/5415 8807/9048/5414 +f 8807/9048/5414 8808/9049/5415 8670/8911/5369 +f 8807/9048/5414 8670/8911/5369 8667/8908/5366 +f 8442/8683/5262 8807/9048/5414 8667/8908/5366 +f 8442/8683/5262 8667/8908/5366 8439/8680/5259 +f 8727/8968/5391 8730/8971/5391 8809/9050/5416 +f 8727/8968/5391 8809/9050/5416 8808/9049/5415 +f 8730/8971/5391 7599/7841/4498 7776/8018/4661 +f 8730/8971/5391 7776/8018/4661 8809/9050/5416 +f 8809/9050/5416 7776/8018/4661 7775/8017/4660 +f 8809/9050/5416 7775/8017/4660 8672/8913/5371 +f 8808/9049/5415 8809/9050/5416 8672/8913/5371 +f 8808/9049/5415 8672/8913/5371 8670/8911/5369 +f 8449/8690/5268 8448/8689/5267 8810/9051/5417 +f 8449/8690/5268 8810/9051/5417 8725/8966/5390 +f 8447/8688/5266 8446/8687/5265 8811/9052/5418 +f 8447/8688/5266 8811/9052/5418 8812/9053/5419 +f 8812/9053/5419 8811/9052/5418 8328/8569/5161 +f 8812/9053/5419 8328/8569/5161 8327/8568/5158 +f 8725/8966/5390 8810/9051/5417 8324/8565/5158 +f 8725/8966/5390 8324/8565/5158 8323/8564/5157 +f 6887/6838/4395 8813/9054/5420 8814/9055/5421 +f 6887/6838/4395 8814/9055/5421 6883/6837/4394 +f 8813/9054/5420 7950/8192/4818 7953/8195/4821 +f 8813/9054/5420 7953/8195/4821 8814/9055/5421 +f 8814/9055/5421 7953/8195/4821 7642/7884/4537 +f 8814/9055/5421 7642/7884/4537 8815/9056/5422 +f 6883/6837/4394 8814/9055/5421 8815/9056/5422 +f 6883/6837/4394 8815/9056/5422 6602/6832/4356 +f 6543/7763/4348 8819/9057/5423 8820/9058/5424 +f 6543/7763/4348 8820/9058/5424 6880/7794/4392 +f 8819/9057/5423 7680/7922/4570 7683/7925/4573 +f 8819/9057/5423 7683/7925/4573 8820/9058/5424 +f 8820/9058/5424 7683/7925/4573 7691/7933/4581 +f 8820/9058/5424 7691/7933/4581 8821/9059/5425 +f 6880/7794/4392 8820/9058/5424 8821/9059/5425 +f 6880/7794/4392 8821/9059/5425 6881/7795/4393 +f 6875/7743/4172 8822/9060/5426 8823/9061/5427 +f 6875/7743/4172 8823/9061/5427 6870/6828/4389 +f 8822/9060/5426 7758/8000/4643 7761/8003/4646 +f 8822/9060/5426 7761/8003/4646 8823/9061/5427 +f 8823/9061/5427 7761/8003/4646 7769/8011/4654 +f 8823/9061/5427 7769/8011/4654 8824/9062/5428 +f 6870/6828/4389 8823/9061/5427 8824/9062/5428 +f 6870/6828/4389 8824/9062/5428 6867/6821/4388 +f 6564/7766/4353 8825/9063/5429 8826/9064/5430 +f 6564/7766/4353 8826/9064/5430 6837/7789/4384 +f 8825/9063/5429 8132/8374/4985 8386/8627/5212 +f 8825/9063/5429 8386/8627/5212 8826/9064/5430 +f 8826/9064/5430 8386/8627/5212 7724/7966/4613 +f 8826/9064/5430 7724/7966/4613 8827/9065/5431 +f 6837/7789/4384 8826/9064/5430 8827/9065/5431 +f 6837/7789/4384 8827/9065/5431 6472/7758/4340 +f 6867/6821/4388 8824/9062/5428 8828/9066/5432 +f 6867/6821/4388 8828/9066/5432 6889/6841/4396 +f 8824/9062/5428 7769/8011/4654 8220/8462/5065 +f 8824/9062/5428 8220/8462/5065 8828/9066/5432 +f 8828/9066/5432 8220/8462/5065 7950/8192/4818 +f 8828/9066/5432 7950/8192/4818 8813/9054/5420 +f 6889/6841/4396 8828/9066/5432 8813/9054/5420 +f 6889/6841/4396 8813/9054/5420 6887/6838/4395 +f 6474/7760/4342 8831/9067/5433 8832/9068/5434 +f 6474/7760/4342 8832/9068/5434 6859/7791/4386 +f 8831/9067/5433 7630/7872/4526 7633/7875/4529 +f 8831/9067/5433 7633/7875/4529 8832/9068/5434 +f 8832/9068/5434 7633/7875/4529 7641/7883/4536 +f 8832/9068/5434 7641/7883/4536 8833/9069/5435 +f 6859/7791/4386 8832/9068/5434 8833/9069/5435 +f 6859/7791/4386 8833/9069/5435 6541/7761/4346 +f 6876/6829/4390 8834/9070/5436 8835/9071/5437 +f 6876/6829/4390 8835/9071/5437 8836/7746/5438 +f 8834/9070/5436 7812/8054/4691 7815/8057/4694 +f 8834/9070/5436 7815/8057/4694 8835/9071/5437 +f 8835/9071/5437 7815/8057/4694 7758/8000/4643 +f 8835/9071/5437 7758/8000/4643 8822/9060/5426 +f 8836/7746/5438 8835/9071/5437 8822/9060/5426 +f 8836/7746/5438 8822/9060/5426 6875/7743/4172 +f 6497/6503/4152 8837/9072/5439 8838/9073/5440 +f 6497/6503/4152 8838/9073/5440 6498/6493/4343 +f 8837/9072/5439 7656/7898/4548 7659/7901/4551 +f 8837/9072/5439 7659/7901/4551 8838/9073/5440 +f 8838/9073/5440 7659/7901/4551 7667/7909/4557 +f 8838/9073/5440 7667/7909/4557 8839/9074/5441 +f 6498/6493/4343 8838/9073/5440 8839/9074/5441 +f 6498/6493/4343 8839/9074/5441 6499/6494/4344 +f 6512/6508/4260 8840/7521/5442 8841/9075/5443 +f 6512/6508/4260 8841/9075/5443 6513/6509/4345 +f 8840/7521/5442 8049/8291/4912 8052/8294/4915 +f 8840/7521/5442 8052/8294/4915 8841/9075/5443 +f 8841/9075/5443 8052/8294/4915 7656/7898/4548 +f 8841/9075/5443 7656/7898/4548 8837/9072/5439 +f 6513/6509/4345 8841/9075/5443 8837/9072/5439 +f 6513/6509/4345 8837/9072/5439 6497/6503/4152 +f 6560/7755/4349 8848/9076/5444 8849/9077/5445 +f 6560/7755/4349 8849/9077/5445 6561/6553/4350 +f 8848/9076/5444 7974/8216/4841 7977/8219/4844 +f 8848/9076/5444 7977/8219/4844 8849/9077/5445 +f 8849/9077/5445 7977/8219/4844 7985/8227/4852 +f 8849/9077/5445 7985/8227/4852 8850/9078/5446 +f 6561/6553/4350 8849/9077/5445 8850/9078/5446 +f 6561/6553/4350 8850/9078/5446 6562/7764/4351 +f 6499/6494/4344 8839/9074/5441 8851/9079/5447 +f 6499/6494/4344 8851/9079/5447 6567/6556/4354 +f 8839/9074/5441 7667/7909/4557 8196/8438/5044 +f 8839/9074/5441 8196/8438/5044 8851/9079/5447 +f 8851/9079/5447 8196/8438/5044 8852/9080/5448 +f 8851/9079/5447 8852/9080/5448 8853/9081/5449 +f 6567/6556/4354 8851/9079/5447 8853/9081/5449 +f 6567/6556/4354 8853/9081/5449 6568/6557/4355 +f 6602/6832/4356 8815/9056/5422 8859/9082/5450 +f 6602/6832/4356 8859/9082/5450 6603/6591/4357 +f 8815/9056/5422 7642/7884/4537 7645/7887/4540 +f 8815/9056/5422 7645/7887/4540 8859/9082/5450 +f 8859/9082/5450 7645/7887/4540 7655/7897/4547 +f 8859/9082/5450 7655/7897/4547 8860/9083/5451 +f 6603/6591/4357 8859/9082/5450 8860/9083/5451 +f 6603/6591/4357 8860/9083/5451 6461/6592/4158 +f 6461/6592/4158 8860/9083/5451 8861/9084/5452 +f 6461/6592/4158 8861/9084/5452 6462/6461/4174 +f 8860/9083/5451 7655/7897/4547 8294/8536/5131 +f 8860/9083/5451 8294/8536/5131 8861/9084/5452 +f 8861/9084/5452 8294/8536/5131 7864/8106/4739 +f 8861/9084/5452 7864/8106/4739 8862/9085/5453 +f 6462/6461/4174 8861/9084/5452 8862/9085/5453 +f 6462/6461/4174 8862/9085/5453 6463/6462/4339 +f 6636/7773/4366 8863/9086/5454 8864/9087/5455 +f 6636/7773/4366 8864/9087/5455 6862/7792/4387 +f 8863/9086/5454 7949/8191/4817 8226/8468/5070 +f 8863/9086/5454 8226/8468/5070 8864/9087/5455 +f 8864/9087/5455 8226/8468/5070 8232/8474/5076 +f 8864/9087/5455 8232/8474/5076 8865/9088/5456 +f 6862/7792/4387 8864/9087/5455 8865/9088/5456 +f 6862/7792/4387 8865/9088/5456 6625/7770/4360 +f 6618/7769/4359 8866/9089/5457 8867/9090/5458 +f 6618/7769/4359 8867/9090/5458 6823/7788/4359 +f 8866/9089/5457 7716/7958/4605 7719/7961/4608 +f 8866/9089/5457 7719/7961/4608 8867/9090/5458 +f 8867/9090/5458 7719/7961/4608 7606/7848/4504 +f 8867/9090/5458 7606/7848/4504 8868/9091/5459 +f 6823/7788/4359 8867/9090/5458 8868/9091/5459 +f 6823/7788/4359 8868/9091/5459 6643/7774/4359 +f 6627/7539/4361 8869/7538/5460 8870/9092/5461 +f 6627/7539/4361 8870/9092/5461 6846/7790/4385 +f 8869/7538/5460 7668/7910/4558 7671/7913/4561 +f 8869/7538/5460 7671/7913/4561 8870/9092/5461 +f 8870/9092/5461 7671/7913/4561 7679/7921/4569 +f 8870/9092/5461 7679/7921/4569 8871/9093/5462 +f 6846/7790/4385 8870/9092/5461 8871/9093/5462 +f 6846/7790/4385 8871/9093/5462 6616/7767/4358 +f 6643/7774/4359 8868/9091/5459 8872/9094/5463 +f 6643/7774/4359 8872/9094/5463 6644/7775/4168 +f 8868/9091/5459 7606/7848/4504 7609/7851/4507 +f 8868/9091/5459 7609/7851/4507 8872/9094/5463 +f 8872/9094/5463 7609/7851/4507 7617/7859/4514 +f 8872/9094/5463 7617/7859/4514 8873/9095/5464 +f 6644/7775/4168 8872/9094/5463 8873/9095/5464 +f 6644/7775/4168 8873/9095/5464 6645/7776/4168 +f 6632/6889/4362 8874/9096/5465 8875/9097/5466 +f 6632/6889/4362 8875/9097/5466 6633/6615/4363 +f 8874/9096/5465 7844/8086/4720 7847/8089/4723 +f 8874/9096/5465 7847/8089/4723 8875/9097/5466 +f 8875/9097/5466 7847/8089/4723 7855/8097/4731 +f 8875/9097/5466 7855/8097/4731 8876/9098/5467 +f 6633/6615/4363 8875/9097/5466 8876/9098/5467 +f 6633/6615/4363 8876/9098/5467 6634/7771/4364 +f 6781/6947/4377 8877/9099/5468 8878/9100/5469 +f 6781/6947/4377 8878/9100/5469 6993/6948/4377 +f 8877/9099/5468 7618/7860/4515 7621/7863/4518 +f 8877/9099/5468 7621/7863/4518 8878/9100/5469 +f 8878/9100/5469 7621/7863/4518 7629/7871/4525 +f 8878/9100/5469 7629/7871/4525 8879/9101/5470 +f 6993/6948/4377 8878/9100/5469 8879/9101/5470 +f 6993/6948/4377 8879/9101/5470 6995/6950/4190 +f 6991/7797/4403 8882/9102/5440 8883/9103/5471 +f 6991/7797/4403 8883/9103/5471 6992/6945/4344 +f 8882/9102/5440 8012/8254/4877 8206/8448/5052 +f 8882/9102/5440 8206/8448/5052 8883/9103/5471 +f 8883/9103/5471 8206/8448/5052 7966/8208/4833 +f 8883/9103/5471 7966/8208/4833 8884/9104/5472 +f 6992/6945/4344 8883/9103/5471 8884/9104/5472 +f 6992/6945/4344 8884/9104/5472 6722/6946/4404 +f 6981/6935/5473 8885/9105/5474 8886/9106/5475 +f 6981/6935/5473 8886/9106/5475 6982/6936/5476 +f 8885/9105/5474 7888/8130/4762 7891/8133/4765 +f 8885/9105/5474 7891/8133/4765 8886/9106/5475 +f 8886/9106/5475 7891/8133/4765 7899/8141/4771 +f 8886/9106/5475 7899/8141/4771 8887/9107/5477 +f 6982/6936/5476 8886/9106/5475 8887/9107/5477 +f 6982/6936/5476 8887/9107/5477 6985/6939/4183 +f 6661/6634/4399 8888/7600/4277 8889/9108/5478 +f 6661/6634/4399 8889/9108/5478 6961/6913/4400 +f 8888/7600/4277 8073/8315/4932 8076/8318/4935 +f 8888/7600/4277 8076/8318/4935 8889/9108/5478 +f 8889/9108/5478 8076/8318/4935 7704/7946/4594 +f 8889/9108/5478 7704/7946/4594 8890/9109/5479 +f 6961/6913/4400 8889/9108/5478 8890/9109/5479 +f 6961/6913/4400 8890/9109/5479 6743/6914/4401 +f 6995/6950/4190 8879/9101/5470 8891/9110/5480 +f 6995/6950/4190 8891/9110/5480 6999/6954/5481 +f 8879/9101/5470 7629/7871/4525 8070/8312/4930 +f 8879/9101/5470 8070/8312/4930 8891/9110/5480 +f 8891/9110/5480 8070/8312/4930 7888/8130/4762 +f 8891/9110/5480 7888/8130/4762 8885/9105/5474 +f 6999/6954/5481 8891/9110/5480 8885/9105/5474 +f 6999/6954/5481 8885/9105/5474 6981/6935/5473 +f 6724/6696/4344 8894/9111/5482 8895/7518/5483 +f 8894/9111/5482 7732/7974/4621 7735/7977/4624 +f 8894/9111/5482 7735/7977/4624 8895/7518/5483 +f 8895/7518/5483 7735/7977/4624 7745/7987/4631 +f 8895/7518/5483 7745/7987/4631 8896/7519/4257 +f 7021/6977/4156 8895/7518/5483 8896/7519/4257 +f 6985/6939/4183 8887/9107/5477 8897/9112/5484 +f 6985/6939/4183 8897/9112/5484 6989/6943/4181 +f 8887/9107/5477 7899/8141/4771 8006/8248/4871 +f 8887/9107/5477 8006/8248/4871 8897/9112/5484 +f 8897/9112/5484 8006/8248/4871 8012/8254/4877 +f 8897/9112/5484 8012/8254/4877 8882/9102/5440 +f 6989/6943/4181 8897/9112/5484 8882/9102/5440 +f 6989/6943/4181 8882/9102/5440 6991/7797/4403 +f 6685/6658/4370 8898/9113/5485 8899/9114/5486 +f 6685/6658/4370 8899/9114/5486 6686/6659/4161 +f 8898/9113/5485 7757/7999/4642 7791/8033/4674 +f 8898/9113/5485 7791/8033/4674 8899/9114/5486 +f 8899/9114/5486 7791/8033/4674 7799/8041/4679 +f 8899/9114/5486 7799/8041/4679 8900/9115/5487 +f 6686/6659/4161 8899/9114/5486 8900/9115/5487 +f 6686/6659/4161 8900/9115/5487 6687/6660/5488 +f 6687/6660/5488 8900/9115/5487 8901/7520/5489 +f 8900/9115/5487 7799/8041/4679 8140/8382/4993 +f 8900/9115/5487 8140/8382/4993 8901/7520/5489 +f 8901/7520/5489 8140/8382/4993 8049/8291/4912 +f 8901/7520/5489 8049/8291/4912 8840/7521/5442 +f 6696/6669/4193 8901/7520/5489 8840/7521/5442 +f 6745/7780/4373 8905/9116/5490 8906/9117/5491 +f 6745/7780/4373 8906/9117/5491 6746/7781/4374 +f 8905/9116/5490 7715/7957/4604 7783/8025/4668 +f 8905/9116/5490 7783/8025/4668 8906/9117/5491 +f 8906/9117/5491 7783/8025/4668 7746/7988/4632 +f 8906/9117/5491 7746/7988/4632 8907/9118/5492 +f 6746/7781/4374 8906/9117/5491 8907/9118/5492 +f 6746/7781/4374 8907/9118/5492 6747/7782/4357 +f 6747/7782/4357 8907/9118/5492 8908/9119/5493 +f 6747/7782/4357 8908/9119/5493 6750/7783/4375 +f 8907/9118/5492 7746/7988/4632 7749/7991/4635 +f 8907/9118/5492 7749/7991/4635 8908/9119/5493 +f 8908/9119/5493 7749/7991/4635 7757/7999/4642 +f 8908/9119/5493 7757/7999/4642 8898/9113/5485 +f 6750/7783/4375 8908/9119/5493 8898/9113/5485 +f 6750/7783/4375 8898/9113/5485 6685/6658/4370 +f 6654/7779/4369 8912/9120/5494 8913/9121/5495 +f 6654/7779/4369 8913/9121/5495 6780/7784/4376 +f 8912/9120/5494 7934/8176/4802 7937/8179/4805 +f 8912/9120/5494 7937/8179/4805 8913/9121/5495 +f 8913/9121/5495 7937/8179/4805 7618/7860/4515 +f 8913/9121/5495 7618/7860/4515 8877/9099/5468 +f 6780/7784/4376 8913/9121/5495 8877/9099/5468 +f 6780/7784/4376 8877/9099/5468 6781/6947/4377 +f 6652/7777/4367 8914/9122/5496 8915/9123/5497 +f 6652/7777/4367 8915/9123/5497 6653/7778/4368 +f 8914/9122/5496 8233/8475/5077 8236/8478/5080 +f 8914/9122/5496 8236/8478/5080 8915/9123/5497 +f 8915/9123/5497 8236/8478/5080 7934/8176/4802 +f 8915/9123/5497 7934/8176/4802 8912/9120/5494 +f 6653/7778/4368 8915/9123/5497 8912/9120/5494 +f 6653/7778/4368 8912/9120/5494 6654/7779/4369 +f 6803/6766/4179 8916/9124/5498 8917/9125/5499 +f 6803/6766/4179 8917/9125/5499 6976/6929/4402 +f 8916/9124/5498 7594/7836/4493 7597/7839/4496 +f 8916/9124/5498 7597/7839/4496 8917/9125/5499 +f 8917/9125/5499 7597/7839/4496 7605/7847/4503 +f 8917/9125/5499 7605/7847/4503 8918/9126/5500 +f 6976/6929/4402 8917/9125/5499 8918/9126/5500 +f 6976/6929/4402 8918/9126/5500 6810/6930/4379 +f 6818/6777/4169 8919/9127/5501 8920/7528/4262 +f 8919/9127/5501 7856/8098/4732 7859/8101/4735 +f 8919/9127/5501 7859/8101/4735 8920/7528/4262 +f 8920/7528/4262 7859/8101/4735 7800/8042/4680 +f 8920/7528/4262 7800/8042/4680 8921/9128/5502 +f 6948/6899/4398 8920/7528/4262 8921/9128/5502 +f 6948/6899/4398 8921/9128/5502 6792/6900/4271 +f 6794/6758/5503 8922/7576/4272 8923/7529/4264 +f 8922/7576/4272 7811/8053/4690 8362/8603/5192 +f 8922/7576/4272 8362/8603/5192 8923/7529/4264 +f 8923/7529/4264 8362/8603/5192 7770/8012/4655 +f 8923/7529/4264 7770/8012/4655 8924/9129/5504 +f 7009/6964/4405 8923/7529/4264 8924/9129/5504 +f 7009/6964/4405 8924/9129/5504 6801/6965/4165 +f 6645/7776/4168 8873/9095/5464 8925/9130/5505 +f 6645/7776/4168 8925/9130/5505 6817/6776/4383 +f 8873/9095/5464 7617/7859/4514 7873/8115/4748 +f 8873/9095/5464 7873/8115/4748 8925/9130/5505 +f 8925/9130/5505 7873/8115/4748 7856/8098/4732 +f 8925/9130/5505 7856/8098/4732 8919/9127/5501 +f 6817/6776/4383 8925/9130/5505 8919/9127/5501 +f 6817/6776/4383 8919/9127/5501 6818/6777/4169 +f 6812/7785/4380 8926/9131/5506 8927/9132/5507 +f 6812/7785/4380 8927/9132/5507 6813/7786/4381 +f 8926/9131/5506 7965/8207/4832 7987/8229/4854 +f 8926/9131/5506 7987/8229/4854 8927/9132/5507 +f 8927/9132/5507 7987/8229/4854 7995/8237/4861 +f 8927/9132/5507 7995/8237/4861 8928/9133/5508 +f 6813/7786/4381 8927/9132/5507 8928/9133/5508 +f 6813/7786/4381 8928/9133/5508 6814/7787/4382 +f 6562/7764/4351 8850/9078/5446 8929/9134/5509 +f 6562/7764/4351 8929/9134/5509 6563/7765/4352 +f 8850/9078/5446 7985/8227/4852 8126/8368/4980 +f 8850/9078/5446 8126/8368/4980 8929/9134/5509 +f 8929/9134/5509 8126/8368/4980 8132/8374/4985 +f 8929/9134/5509 8132/8374/4985 8825/9063/5429 +f 6563/7765/4352 8929/9134/5509 8825/9063/5429 +f 6563/7765/4352 8825/9063/5429 6564/7766/4353 +f 6616/7767/4358 8871/9093/5462 8930/9135/5510 +f 6616/7767/4358 8930/9135/5510 6617/7768/4358 +f 8871/9093/5462 7679/7921/4569 8390/8631/5216 +f 8871/9093/5462 8390/8631/5216 8930/9135/5510 +f 8930/9135/5510 8390/8631/5216 7716/7958/4605 +f 8930/9135/5510 7716/7958/4605 8866/9089/5457 +f 6617/7768/4358 8930/9135/5510 8866/9089/5457 +f 6617/7768/4358 8866/9089/5457 6618/7769/4359 +f 6472/7758/4340 8827/9065/5431 8936/9136/5511 +f 6472/7758/4340 8936/9136/5511 6473/7759/4341 +f 8827/9065/5431 7724/7966/4613 7727/7969/4616 +f 8827/9065/5431 7727/7969/4616 8936/9136/5511 +f 8936/9136/5511 7727/7969/4616 7630/7872/4526 +f 8936/9136/5511 7630/7872/4526 8831/9067/5433 +f 6473/7759/4341 8936/9136/5511 8831/9067/5433 +f 6473/7759/4341 8831/9067/5433 6474/7760/4342 +f 6625/7770/4360 8865/9088/5456 8939/9137/5512 +f 6625/7770/4360 8939/9137/5512 6626/7537/4266 +f 8865/9088/5456 8232/8474/5076 8412/8653/5236 +f 8865/9088/5456 8412/8653/5236 8939/9137/5512 +f 8939/9137/5512 8412/8653/5236 7668/7910/4558 +f 8939/9137/5512 7668/7910/4558 8869/7538/5460 +f 6626/7537/4266 8939/9137/5512 8869/7538/5460 +f 6541/7761/4346 8833/9069/5435 8940/9138/5513 +f 6541/7761/4346 8940/9138/5513 6542/7762/4347 +f 8833/9069/5435 7641/7883/4536 7779/8021/4664 +f 8833/9069/5435 7779/8021/4664 8940/9138/5513 +f 8940/9138/5513 7779/8021/4664 7680/7922/4570 +f 8940/9138/5513 7680/7922/4570 8819/9057/5423 +f 6542/7762/4347 8940/9138/5513 8819/9057/5423 +f 6542/7762/4347 8819/9057/5423 6543/7763/4348 +f 6634/7771/4364 8876/9098/5467 8944/9139/5514 +f 6634/7771/4364 8944/9139/5514 6635/7772/4365 +f 8876/9098/5467 7855/8097/4731 7943/8185/4811 +f 8876/9098/5467 7943/8185/4811 8944/9139/5514 +f 8944/9139/5514 7943/8185/4811 7949/8191/4817 +f 8944/9139/5514 7949/8191/4817 8863/9086/5454 +f 6635/7772/4365 8944/9139/5514 8863/9086/5454 +f 6635/7772/4365 8863/9086/5454 6636/7773/4366 +f 6463/6462/4339 8862/9085/5453 8955/9140/5515 +f 6463/6462/4339 8955/9140/5515 6938/6888/4176 +f 8862/9085/5453 7864/8106/4739 7867/8109/4742 +f 8862/9085/5453 7867/8109/4742 8955/9140/5515 +f 8955/9140/5515 7867/8109/4742 7844/8086/4720 +f 8955/9140/5515 7844/8086/4720 8874/9096/5465 +f 6938/6888/4176 8955/9140/5515 8874/9096/5465 +f 6938/6888/4176 8874/9096/5465 6632/6889/4362 +f 6814/7787/4382 8928/9133/5508 8956/9141/5516 +f 6814/7787/4382 8956/9141/5516 6921/7796/4397 +f 8928/9133/5508 7995/8237/4861 8358/8599/5189 +f 8928/9133/5508 8358/8599/5189 8956/9141/5516 +f 8956/9141/5516 8358/8599/5189 8233/8475/5077 +f 8956/9141/5516 8233/8475/5077 8914/9122/5496 +f 6921/7796/4397 8956/9141/5516 8914/9122/5496 +f 6921/7796/4397 8914/9122/5496 6652/7777/4367 +f 6743/6914/4401 8890/9109/5479 8979/7575/4269 +f 8890/9109/5479 7704/7946/4594 7707/7949/4597 +f 8890/9109/5479 7707/7949/4597 8979/7575/4269 +f 8979/7575/4269 7707/7949/4597 7715/7957/4604 +f 8979/7575/4269 7715/7957/4604 8905/9116/5490 +f 6744/6715/4372 8979/7575/4269 8905/9116/5490 +f 6744/6715/4372 8905/9116/5490 6745/7780/4373 +f 6792/6900/4271 8921/9128/5502 8980/9142/5517 +f 6792/6900/4271 8980/9142/5517 6793/6757/4378 +f 8921/9128/5502 7800/8042/4680 7803/8045/4683 +f 8921/9128/5502 7803/8045/4683 8980/9142/5517 +f 8980/9142/5517 7803/8045/4683 7811/8053/4690 +f 8980/9142/5517 7811/8053/4690 8922/7576/4272 +f 6793/6757/4378 8980/9142/5517 8922/7576/4272 +f 6722/6946/4404 8884/9104/5472 8987/7583/4274 +f 8884/9104/5472 7966/8208/4833 7969/8211/4836 +f 8884/9104/5472 7969/8211/4836 8987/7583/4274 +f 8987/7583/4274 7969/8211/4836 7732/7974/4621 +f 8987/7583/4274 7732/7974/4621 8894/9111/5482 +f 6723/6695/4371 8987/7583/4274 8894/9111/5482 +f 6723/6695/4371 8894/9111/5482 6724/6696/4344 +f 6810/6930/4379 8918/9126/5500 8990/9143/5518 +f 6810/6930/4379 8990/9143/5518 6811/6773/4167 +f 8918/9126/5500 7605/7847/4503 7959/8201/4827 +f 8918/9126/5500 7959/8201/4827 8990/9143/5518 +f 8990/9143/5518 7959/8201/4827 7965/8207/4832 +f 8990/9143/5518 7965/8207/4832 8926/9131/5506 +f 6811/6773/4167 8990/9143/5518 8926/9131/5506 +f 6811/6773/4167 8926/9131/5506 6812/7785/4380 +f 6659/6632/5519 8896/7519/4257 9004/7599/5520 +f 8896/7519/4257 7745/7987/4631 8122/8364/4977 +f 8896/7519/4257 8122/8364/4977 9004/7599/5520 +f 9004/7599/5520 8122/8364/4977 8073/8315/4932 +f 9004/7599/5520 8073/8315/4932 8888/7600/4277 +f 6660/6633/4278 9004/7599/5520 8888/7600/4277 +f 6801/6965/4165 8924/9129/5504 9006/9144/5521 +f 6801/6965/4165 9006/9144/5521 6802/6765/4165 +f 8924/9129/5504 7770/8012/4655 7773/8015/4658 +f 8924/9129/5504 7773/8015/4658 9006/9144/5521 +f 9006/9144/5521 7773/8015/4658 7594/7836/4493 +f 9006/9144/5521 7594/7836/4493 8916/9124/5498 +f 6802/6765/4165 9006/9144/5521 8916/9124/5498 +f 6802/6765/4165 8916/9124/5498 6803/6766/4179 +f 7168/7361/4426 9008/9145/5522 9009/9146/5523 +f 7168/7361/4426 9009/9146/5523 7452/7362/4241 +f 9008/9145/5522 7925/8167/4796 8425/8666/5247 +f 9008/9145/5522 8425/8666/5247 9009/9146/5523 +f 9009/9146/5523 8425/8666/5247 8109/8351/4965 +f 9009/9146/5523 8109/8351/4965 9010/9147/5524 +f 7452/7362/4241 9009/9146/5523 9010/9147/5524 +f 7452/7362/4241 9010/9147/5524 7454/7364/4240 +f 7450/7828/4475 9014/9148/5525 9015/9149/5526 +f 7450/7828/4475 9015/9149/5526 7451/7359/4476 +f 9014/9148/5525 7884/8126/4758 7882/8124/4756 +f 9014/9148/5525 7882/8124/4756 9015/9149/5526 +f 9015/9149/5526 7882/8124/4756 7881/8123/4755 +f 9015/9149/5526 7881/8123/4755 9016/9150/5527 +f 7451/7359/4476 9015/9149/5526 9016/9150/5527 +f 7451/7359/4476 9016/9150/5527 7104/7360/4413 +f 7437/7346/5528 9017/9151/5529 9018/9152/5530 +f 7437/7346/5528 9018/9152/5530 7438/7347/5531 +f 9017/9151/5529 8106/8348/4962 8355/8596/5186 +f 9017/9151/5529 8355/8596/5186 9018/9152/5530 +f 9018/9152/5530 8355/8596/5186 8354/8595/5185 +f 9018/9152/5530 8354/8595/5185 9019/9153/5532 +f 7438/7347/5531 9018/9152/5530 9019/9153/5532 +f 7438/7347/5531 9019/9153/5532 7441/7350/5533 +f 7037/6989/4411 9020/9154/5534 9021/7606/5535 +f 9020/9154/5534 8249/8491/5091 8247/8489/5089 +f 9020/9154/5534 8247/8489/5089 9021/7606/5535 +f 9021/7606/5535 8247/8489/5089 8246/8488/5088 +f 9021/7606/5535 8246/8488/5088 9022/9155/5536 +f 7402/7607/4469 9021/7606/5535 9022/9155/5536 +f 7402/7607/4469 9022/9155/5536 7125/7804/4419 +f 7454/7364/4240 9010/9147/5524 9026/9156/5537 +f 7454/7364/4240 9026/9156/5537 7458/7368/4242 +f 9010/9147/5524 8109/8351/4965 8107/8349/4963 +f 9010/9147/5524 8107/8349/4963 9026/9156/5537 +f 9026/9156/5537 8107/8349/4963 8106/8348/4962 +f 9026/9156/5537 8106/8348/4962 9017/9151/5529 +f 7458/7368/4242 9026/9156/5537 9017/9151/5529 +f 7458/7368/4242 9017/9151/5529 7437/7346/5528 +f 7106/7055/4415 9029/9157/5538 9030/9158/5539 +f 7106/7055/4415 9030/9158/5539 7426/7334/4471 +f 9029/9157/5538 7700/7942/4590 7698/7940/4588 +f 9029/9157/5538 7698/7940/4588 9030/9158/5539 +f 9030/9158/5539 7698/7940/4588 7697/7939/4587 +f 9030/9158/5539 7697/7939/4587 9031/9159/5540 +f 7426/7334/4471 9030/9158/5539 9031/9159/5540 +f 7426/7334/4471 9031/9159/5540 7035/7335/4409 +f 7446/7355/5541 9032/9160/5542 9033/9161/5543 +f 7446/7355/5541 9033/9161/5543 7447/7356/4235 +f 9032/9160/5542 8370/8611/5200 9034/9162/5544 +f 9032/9160/5542 9034/9162/5544 9033/9161/5543 +f 9033/9161/5543 9034/9162/5544 7884/8126/4758 +f 9033/9161/5543 7884/8126/4758 9014/9148/5525 +f 7447/7356/4235 9033/9161/5543 9014/9148/5525 +f 7447/7356/4235 9014/9148/5525 7450/7828/4475 +f 7064/7801/4412 9037/9163/5545 9038/9164/5546 +f 7064/7801/4412 9038/9164/5546 7065/7802/4217 +f 9037/9163/5545 8097/8339/4953 8095/8337/4952 +f 9037/9163/5545 8095/8337/4952 9038/9164/5546 +f 9038/9164/5546 8095/8337/4952 8094/8336/4951 +f 9038/9164/5546 8094/8336/4951 9039/9165/5547 +f 7065/7802/4217 9038/9164/5546 9039/9165/5547 +f 7065/7802/4217 9039/9165/5547 7066/7020/4198 +f 7066/7020/4198 9039/9165/5547 9040/9166/5548 +f 7066/7020/4198 9040/9166/5548 7075/7025/5549 +f 9039/9165/5547 8094/8336/4951 8419/8660/5242 +f 9039/9165/5547 8419/8660/5242 9040/9166/5548 +f 9040/9166/5548 8419/8660/5242 8259/8501/5099 +f 9040/9166/5548 8259/8501/5099 9041/9167/5550 +f 7075/7025/5549 9040/9166/5548 9041/9167/5550 +f 7075/7025/5549 9041/9167/5550 7076/7026/4299 +f 7129/7808/4423 9048/9168/5551 9049/9169/5552 +f 7129/7808/4423 9049/9169/5552 9050/9170/5553 +f 9048/9168/5551 9051/9171/5554 9052/9172/5555 +f 9048/9168/5551 9052/9172/5555 9049/9169/5552 +f 9049/9169/5552 9052/9172/5555 9053/9173/5556 +f 9049/9169/5552 9053/9173/5556 9054/9174/5557 +f 9050/9170/5553 9049/9169/5552 9054/9174/5557 +f 9050/9170/5553 9054/9174/5557 7134/7809/4424 +f 7134/7809/4424 9054/9174/5557 9055/9175/5558 +f 7134/7809/4424 9055/9175/5558 7135/7810/4294 +f 9054/9174/5557 9053/9173/5556 8159/8401/5009 +f 9054/9174/5557 8159/8401/5009 9055/9175/5558 +f 9055/9175/5558 8159/8401/5009 8097/8339/4953 +f 9055/9175/5558 8097/8339/4953 9037/9163/5545 +f 7135/7810/4294 9055/9175/5558 9037/9163/5545 +f 7135/7810/4294 9037/9163/5545 7064/7801/4412 +f 7030/7800/4408 9056/9176/5559 9057/9177/5560 +f 7030/7800/4408 9057/9177/5560 7167/7811/4425 +f 9056/9176/5559 7928/8170/4799 7926/8168/4797 +f 9056/9176/5559 7926/8168/4797 9057/9177/5560 +f 9057/9177/5560 7926/8168/4797 7925/8167/4796 +f 9057/9177/5560 7925/8167/4796 9008/9145/5522 +f 7167/7811/4425 9057/9177/5560 9008/9145/5522 +f 7167/7811/4425 9008/9145/5522 7168/7361/4426 +f 7028/7798/4406 9058/9178/5561 9059/9179/5562 +f 7028/7798/4406 9059/9179/5562 7029/7799/4407 +f 9058/9178/5561 8177/8419/5025 8175/8417/5023 +f 9058/9178/5561 8175/8417/5023 9059/9179/5562 +f 9059/9179/5562 8175/8417/5023 7928/8170/4799 +f 9059/9179/5562 7928/8170/4799 9056/9176/5559 +f 7029/7799/4407 9059/9179/5562 9056/9176/5559 +f 7029/7799/4407 9056/9176/5559 7030/7800/4408 +f 7190/7124/4472 9060/7655/5563 9061/9180/5564 +f 7190/7124/4472 9061/9180/5564 7429/7338/4473 +f 9060/7655/5563 8117/8359/4972 8115/8357/4970 +f 9060/7655/5563 8115/8357/4970 9061/9180/5564 +f 9061/9180/5564 8115/8357/4970 7197/7815/4435 +f 9061/9180/5564 7197/7815/4435 9062/9181/5565 +f 7429/7338/4473 9061/9180/5564 9062/9181/5565 +f 7429/7338/4473 9062/9181/5565 7430/7339/4474 +f 7208/7132/4441 9063/9182/5566 9064/9183/5567 +f 7208/7132/4441 9064/9183/5567 7388/7293/4465 +f 9063/9182/5566 7837/8079/4713 8437/8678/5258 +f 9063/9182/5566 8437/8678/5258 9064/9183/5567 +f 9064/9183/5567 8437/8678/5258 8317/8558/5151 +f 9064/9183/5567 8317/8558/5151 9065/7621/5568 +f 7388/7293/4465 9064/9183/5567 9065/7621/5568 +f 7181/7116/4428 9066/9184/5569 9067/9185/5570 +f 7181/7116/4428 9067/9185/5570 7413/7320/4429 +f 9066/9184/5569 7916/8158/4788 7914/8156/4786 +f 9066/9184/5569 7914/8156/4786 9067/9185/5570 +f 9067/9185/5570 7914/8156/4786 7913/8155/4785 +f 9067/9185/5570 7913/8155/4785 9068/7622/4284 +f 7413/7320/4429 9067/9185/5570 9068/7622/4284 +f 7206/7623/4207 9069/7648/4305 9070/7624/4287 +f 9069/7648/4305 7840/8082/4716 7838/8080/4714 +f 9069/7648/4305 7838/8080/4714 9070/7624/4287 +f 9070/7624/4287 7838/8080/4714 7837/8079/4713 +f 9070/7624/4287 7837/8079/4713 9063/9182/5566 +f 7207/7131/4207 9070/7624/4287 9063/9182/5566 +f 7207/7131/4207 9063/9182/5566 7208/7132/4441 +f 7570/7475/4490 9071/9186/5571 9072/9187/5572 +f 7570/7475/4490 9072/9187/5572 7566/7474/4489 +f 9071/9186/5571 7828/8070/4706 7826/8068/4705 +f 9071/9186/5571 7826/8068/4705 9072/9187/5572 +f 9072/9187/5572 7826/8068/4705 7825/8067/4704 +f 9072/9187/5572 7825/8067/4704 9073/9188/5573 +f 7566/7474/4489 9072/9187/5572 9073/9188/5573 +f 7566/7474/4489 9073/9188/5573 7345/7469/4250 +f 7291/7820/4322 9076/9189/5574 9077/9190/5575 +f 7291/7820/4322 9077/9190/5575 7563/7833/4324 +f 9076/9189/5574 8151/8393/5003 8149/8391/5001 +f 9076/9189/5574 8149/8391/5001 9077/9190/5575 +f 9077/9190/5575 8149/8391/5001 8033/8275/4897 +f 9077/9190/5575 8033/8275/4897 9078/9191/5576 +f 7563/7833/4324 9077/9190/5575 9078/9191/5576 +f 7563/7833/4324 9078/9191/5576 7564/7834/4488 +f 7560/7467/4486 9079/9192/5577 9080/9193/5578 +f 7560/7467/4486 9080/9193/5578 7556/7466/4485 +f 9079/9192/5577 8030/8272/4894 8087/8329/4944 +f 9079/9192/5577 8087/8329/4944 9080/9193/5578 +f 9080/9193/5578 8087/8329/4944 8086/8328/4943 +f 9080/9193/5578 8086/8328/4943 9081/9194/5579 +f 7556/7466/4485 9080/9193/5578 9081/9194/5579 +f 7556/7466/4485 9081/9194/5579 7553/7460/4484 +f 7312/7627/4293 9082/7697/5580 9083/7628/4289 +f 9082/7697/5580 8018/8260/4883 8397/8638/5222 +f 9082/7697/5580 8397/8638/5222 9083/7628/4289 +f 9083/7628/4289 8397/8638/5222 8271/8513/5111 +f 9083/7628/4289 8271/8513/5111 9084/7630/4292 +f 7533/7629/5581 9083/7628/4289 9084/7630/4292 +f 7553/7460/4484 9081/9194/5579 9085/9195/5582 +f 7553/7460/4484 9085/9195/5582 7572/7478/4491 +f 9081/9194/5579 8086/8328/4943 8277/8519/5116 +f 9081/9194/5579 8277/8519/5116 9085/9195/5582 +f 9085/9195/5582 8277/8519/5116 7828/8070/4706 +f 9085/9195/5582 7828/8070/4706 9071/9186/5571 +f 7572/7478/4491 9085/9195/5582 9071/9186/5571 +f 7572/7478/4491 9071/9186/5571 7570/7475/4490 +f 7228/7151/4294 9088/7725/5583 9089/7633/4295 +f 9088/7725/5583 8268/8510/5108 8289/8531/5128 +f 9088/7725/5583 8289/8531/5128 9089/7633/4295 +f 9089/7633/4295 8289/8531/5128 8288/8530/5127 +f 9089/7633/4295 8288/8530/5127 9090/7634/5584 +f 7593/7497/5585 9089/7633/4295 9090/7634/5584 +f 7564/7834/4488 9078/9191/5576 9091/9196/5586 +f 7564/7834/4488 9091/9196/5586 7562/7832/4487 +f 9078/9191/5576 8033/8275/4897 8031/8273/4895 +f 9078/9191/5576 8031/8273/4895 9091/9196/5586 +f 9091/9196/5586 8031/8273/4895 8030/8272/4894 +f 9091/9196/5586 8030/8272/4894 9079/9192/5577 +f 7562/7832/4487 9091/9196/5586 9079/9192/5577 +f 7562/7832/4487 9079/9192/5577 7560/7467/4486 +f 7248/7171/4195 9092/7637/5587 9093/9197/5588 +f 7248/7171/4195 9093/9197/5588 7249/7172/4445 +f 9092/7637/5587 8215/8457/5060 8213/8455/5059 +f 9092/7637/5587 8213/8455/5059 9093/9197/5588 +f 9093/9197/5588 8213/8455/5059 8045/8287/4909 +f 9093/9197/5588 8045/8287/4909 9094/9198/5589 +f 7249/7172/4445 9093/9197/5588 9094/9198/5589 +f 7249/7172/4445 9094/9198/5589 7250/7173/4446 +f 7076/7026/4299 9041/9167/5550 9095/7636/5590 +f 9041/9167/5550 8259/8501/5099 8257/8499/5097 +f 9041/9167/5550 8257/8499/5097 9095/7636/5590 +f 9095/7636/5590 8257/8499/5097 8215/8457/5060 +f 9095/7636/5590 8215/8457/5060 9092/7637/5587 +f 7261/7184/5591 9095/7636/5590 9092/7637/5587 +f 7308/7232/4448 9099/9199/5592 9100/9200/5593 +f 7308/7232/4448 9100/9200/5593 7309/7228/4408 +f 9099/9199/5592 8042/8284/4906 8375/8616/5205 +f 9099/9199/5592 8375/8616/5205 9100/9200/5593 +f 9100/9200/5593 8375/8616/5205 8021/8263/4886 +f 9100/9200/5593 8021/8263/4886 9101/9201/5594 +f 7309/7228/4408 9100/9200/5593 9101/9201/5594 +f 7309/7228/4408 9101/9201/5594 7310/7694/4449 +f 7250/7173/4446 9094/9198/5589 9102/9202/5595 +f 7250/7173/4446 9102/9202/5595 7315/7231/4451 +f 9094/9198/5589 8045/8287/4909 8043/8285/4907 +f 9094/9198/5589 8043/8285/4907 9102/9202/5595 +f 9102/9202/5595 8043/8285/4907 8042/8284/4906 +f 9102/9202/5595 8042/8284/4906 9099/9199/5592 +f 7315/7231/4451 9102/9202/5595 9099/9199/5592 +f 7315/7231/4451 9099/9199/5592 7308/7232/4448 +f 7345/7469/4250 9073/9188/5573 9106/9203/5596 +f 7345/7469/4250 9106/9203/5596 7346/7262/4452 +f 9073/9188/5573 7825/8067/4704 8433/8674/5254 +f 9073/9188/5573 8433/8674/5254 9106/9203/5596 +f 9106/9203/5596 8433/8674/5254 8403/8644/5227 +f 9106/9203/5596 8403/8644/5227 9107/9204/5597 +f 7346/7262/4452 9106/9203/5596 9107/9204/5597 +f 7346/7262/4452 9107/9204/5597 7215/7263/4442 +f 7215/7263/4442 9107/9204/5597 9108/9205/5598 +f 7215/7263/4442 9108/9205/5598 7216/7139/4443 +f 9107/9204/5597 8403/8644/5227 8401/8642/5225 +f 9107/9204/5597 8401/8642/5225 9108/9205/5598 +f 9108/9205/5598 8401/8642/5225 8169/8411/5017 +f 9108/9205/5598 8169/8411/5017 9109/9206/5599 +f 7216/7139/4443 9108/9205/5598 9109/9206/5599 +f 7216/7139/4443 9109/9206/5599 7217/7140/4252 +f 7379/7826/4463 9110/9207/5600 9111/9208/5601 +f 7379/7826/4463 9111/9208/5601 7548/7831/4483 +f 9110/9207/5600 8328/8569/5161 8811/9052/5418 +f 9110/9207/5600 8811/9052/5418 9111/9208/5601 +f 9111/9208/5601 8811/9052/5418 8446/8687/5265 +f 9111/9208/5601 8446/8687/5265 9112/9209/5602 +f 7548/7831/4483 9111/9208/5601 9112/9209/5602 +f 7548/7831/4483 9112/9209/5602 7368/7821/4457 +f 7361/7644/4456 9113/9210/5603 9114/7645/4303 +f 9113/9210/5603 8337/8578/5169 8335/8576/5167 +f 9113/9210/5603 8335/8576/5167 9114/7645/4303 +f 9114/7645/4303 8335/8576/5167 7904/8146/4776 +f 9114/7645/4303 7904/8146/4776 9115/9211/5604 +f 7520/7646/4481 9114/7645/4303 9115/9211/5604 +f 7520/7646/4481 9115/9211/5604 7384/7827/4464 +f 7384/7827/4464 9115/9211/5604 9116/9212/5605 +f 7384/7827/4464 9116/9212/5605 7385/7647/4207 +f 9115/9211/5604 7904/8146/4776 7902/8144/4774 +f 9115/9211/5604 7902/8144/4774 9116/9212/5605 +f 9116/9212/5605 7902/8144/4774 7840/8082/4716 +f 9116/9212/5605 7840/8082/4716 9069/7648/4305 +f 7385/7647/4207 9116/9212/5605 9069/7648/4305 +f 7375/7402/4245 9117/9213/5606 9118/9214/5607 +f 7375/7402/4245 9118/9214/5607 7376/7286/4460 +f 9117/9213/5606 8065/8307/4926 8063/8305/4925 +f 9117/9213/5606 8063/8305/4925 9118/9214/5607 +f 9118/9214/5607 8063/8305/4925 8062/8304/4924 +f 9118/9214/5607 8062/8304/4924 9119/9215/5608 +f 7376/7286/4460 9118/9214/5607 9119/9215/5608 +f 7376/7286/4460 9119/9215/5608 7377/7824/4461 +f 7179/7294/4219 9065/7621/5568 9120/7649/4306 +f 9065/7621/5568 8317/8558/5151 8315/8556/5149 +f 9065/7621/5568 8315/8556/5149 9120/7649/4306 +f 9120/7649/4306 8315/8556/5149 7916/8158/4788 +f 9120/7649/4306 7916/8158/4788 9066/9184/5569 +f 7180/7115/4427 9120/7649/4306 9066/9184/5569 +f 7180/7115/4427 9066/9184/5569 7181/7116/4428 +f 7035/7335/4409 9031/9159/5540 9124/9216/5609 +f 7035/7335/4409 9124/9216/5609 7036/6988/4410 +f 9031/9159/5540 7697/7939/4587 8429/8670/5250 +f 9031/9159/5540 8429/8670/5250 9124/9216/5609 +f 9124/9216/5609 8429/8670/5250 8249/8491/5091 +f 9124/9216/5609 8249/8491/5091 9020/9154/5534 +f 7036/6988/4410 9124/9216/5609 9020/9154/5534 +f 7036/6988/4410 9020/9154/5534 7037/6989/4411 +f 7188/7321/4429 9068/7622/4284 9127/9217/5610 +f 7188/7321/4429 9127/9217/5610 7189/7123/4430 +f 9068/7622/4284 7913/8155/4785 8281/8523/5120 +f 9068/7622/4284 8281/8523/5120 9127/9217/5610 +f 9127/9217/5610 8281/8523/5120 8117/8359/4972 +f 9127/9217/5610 8117/8359/4972 9060/7655/5563 +f 7189/7123/4430 9127/9217/5610 9060/7655/5563 +f 7104/7360/4413 9016/9150/5527 9128/9218/5611 +f 7104/7360/4413 9128/9218/5611 7105/7054/4414 +f 9016/9150/5527 7881/8123/4755 8409/8650/5233 +f 9016/9150/5527 8409/8650/5233 9128/9218/5611 +f 9128/9218/5611 8409/8650/5233 7700/7942/4590 +f 9128/9218/5611 7700/7942/4590 9029/9157/5538 +f 7105/7054/4414 9128/9218/5611 9029/9157/5538 +f 7105/7054/4414 9029/9157/5538 7106/7055/4415 +f 7430/7339/4474 9062/9181/5565 9132/7659/4310 +f 9062/9181/5565 7197/7815/4435 7194/7812/4432 +f 9062/9181/5565 7194/7812/4432 9132/7659/4310 +f 9132/7659/4310 7194/7812/4432 7193/7379/4431 +f 7509/7829/4479 9144/9219/5612 9145/9220/5613 +f 7509/7829/4479 9145/9220/5613 7510/7830/4480 +f 9144/9219/5612 7201/7819/4439 8305/8547/5140 +f 9144/9219/5612 8305/8547/5140 9145/9220/5613 +f 9145/9220/5613 8305/8547/5140 8177/8419/5025 +f 9145/9220/5613 8177/8419/5025 9058/9178/5561 +f 7510/7830/4480 9145/9220/5613 9058/9178/5561 +f 7510/7830/4480 9058/9178/5561 7028/7798/4406 +f 7217/7140/4252 9109/9206/5599 9146/9221/5614 +f 7217/7140/4252 9146/9221/5614 7490/7401/4478 +f 9109/9206/5599 8169/8411/5017 8167/8409/5016 +f 9109/9206/5599 8167/8409/5016 9146/9221/5614 +f 9146/9221/5614 8167/8409/5016 8065/8307/4926 +f 9146/9221/5614 8065/8307/4926 9117/9213/5606 +f 7490/7401/4478 9146/9221/5614 9117/9213/5606 +f 7490/7401/4478 9117/9213/5606 7375/7402/4245 +f 9147/7671/4195 7469/7380/4195 7193/7379/4477 +f 7507/7419/4312 9148/7672/4299 9167/7691/5615 +f 9148/7672/4299 7193/7379/4431 7196/7814/4434 +f 9148/7672/4299 7196/7814/4434 9167/7691/5615 +f 9167/7691/5615 7196/7814/4434 7201/7819/4439 +f 9167/7691/5615 7201/7819/4439 9144/9219/5612 +f 7508/7420/4477 9167/7691/5615 9144/9219/5612 +f 7508/7420/4477 9144/9219/5612 7509/7829/4479 +f 7310/7694/4449 9101/9201/5594 9170/7695/4316 +f 9101/9201/5594 8021/8263/4886 8019/8261/4884 +f 9101/9201/5594 8019/8261/4884 9170/7695/4316 +f 9170/7695/4316 8019/8261/4884 8018/8260/4883 +f 9170/7695/4316 8018/8260/4883 9082/7697/5580 +f 7311/7696/5616 9170/7695/4316 9082/7697/5580 +f 7359/7698/5617 9171/7729/4331 9172/7699/5618 +f 9171/7729/4331 8345/8586/5176 8343/8584/5175 +f 9171/7729/4331 8343/8584/5175 9172/7699/5618 +f 9172/7699/5618 8343/8584/5175 8337/8578/5169 +f 9172/7699/5618 8337/8578/5169 9113/9210/5603 +f 7360/7700/4455 9172/7699/5618 9113/9210/5603 +f 7360/7700/4455 9113/9210/5603 7361/7644/4456 +f 7289/7635/5619 9090/7634/5584 9179/7707/5620 +f 9090/7634/5584 8288/8530/5127 8383/8624/5209 +f 9090/7634/5584 8383/8624/5209 9179/7707/5620 +f 9179/7707/5620 8383/8624/5209 8151/8393/5003 +f 9179/7707/5620 8151/8393/5003 9076/9189/5574 +f 7290/7708/4447 9179/7707/5620 9076/9189/5574 +f 7290/7708/4447 9076/9189/5574 7291/7820/4322 +f 7377/7824/4461 9119/9215/5608 9182/9222/5621 +f 7377/7824/4461 9182/9222/5621 7378/7825/4462 +f 9119/9215/5608 8062/8304/4924 8329/8570/5162 +f 9119/9215/5608 8329/8570/5162 9182/9222/5621 +f 9182/9222/5621 8329/8570/5162 8328/8569/5161 +f 9182/9222/5621 8328/8569/5161 9110/9207/5600 +f 7378/7825/4462 9182/9222/5621 9110/9207/5600 +f 7378/7825/4462 9110/9207/5600 7379/7826/4463 +f 7226/7149/5622 9084/7630/4292 9196/7724/5623 +f 9084/7630/4292 8271/8513/5111 8269/8511/5109 +f 9084/7630/4292 8269/8511/5109 9196/7724/5623 +f 9196/7724/5623 8269/8511/5109 8268/8510/5108 +f 9196/7724/5623 8268/8510/5108 9088/7725/5583 +f 7227/7150/4327 9196/7724/5623 9088/7725/5583 +f 7368/7821/4457 9112/9209/5602 9198/9223/5624 +f 7368/7821/4457 9198/9223/5624 7369/7822/4458 +f 9112/9209/5602 8446/8687/5265 8444/8685/5264 +f 9112/9209/5602 8444/8685/5264 9198/9223/5624 +f 9198/9223/5624 8444/8685/5264 8312/8553/5146 +f 9198/9223/5624 8312/8553/5146 8311/8552/5145 +f 7369/7822/4458 9198/9223/5624 8311/8552/5145 +f 7369/7822/4458 8311/8552/5145 7370/7823/4459 +f 8486/8727/4991 9200/9224/5625 9201/9225/5626 +f 8486/8727/4991 9201/9225/5626 8487/8728/5283 +f 9200/9224/5625 8241/8483/5084 8613/8854/5340 +f 9200/9224/5625 8613/8854/5340 9201/9225/5626 +f 9201/9225/5626 8613/8854/5340 8495/8736/5291 +f 9201/9225/5626 8495/8736/5291 9202/9226/5627 +f 8487/8728/5283 9201/9225/5626 9202/9226/5627 +f 8487/8728/5283 9202/9226/5627 8490/8731/5286 +f 8492/8733/5288 9203/9227/5628 9204/9228/5629 +f 8492/8733/5288 9204/9228/5629 8493/8734/5289 +f 9203/9227/5628 8500/8741/5296 9205/9229/5630 +f 9203/9227/5628 9205/9229/5630 9204/9228/5629 +f 9206/9230/5631 9207/9231/5630 8194/8436/5042 +f 9206/9230/5631 8194/8436/5042 9208/9232/5632 +f 8493/8734/5289 9204/9228/5629 9209/9233/5633 +f 8493/8734/5289 9209/9233/5633 8494/8735/5290 +f 8490/8731/5286 9202/9226/5627 9210/9234/5634 +f 8490/8731/5286 9210/9234/5634 8491/8732/5287 +f 9202/9226/5627 8495/8736/5291 8498/8739/5294 +f 9202/9226/5627 8498/8739/5294 9210/9234/5634 +f 9210/9234/5634 8498/8739/5294 8500/8741/5296 +f 9210/9234/5634 8500/8741/5296 9203/9227/5628 +f 8491/8732/5287 9210/9234/5634 9203/9227/5628 +f 8491/8732/5287 9203/9227/5628 8492/8733/5288 +f 8312/8553/5146 8443/8684/5263 9211/9235/5635 +f 8312/8553/5146 9211/9235/5635 8310/8551/5144 +f 8440/8681/5260 8439/8680/5259 8669/8910/5368 +f 8440/8681/5260 8669/8910/5368 9212/9236/5636 +f 9212/9236/5636 8669/8910/5368 8348/8589/5179 +f 9212/9236/5636 8348/8589/5179 9213/9237/5637 +f 8310/8551/5144 9211/9235/5635 9214/9238/5638 +f 8310/8551/5144 9214/9238/5638 8307/8549/5141 +f 8307/8549/5141 9214/9238/5638 9215/9239/5639 +f 8307/8549/5141 9215/9239/5639 8308/7728/5142 +f 9213/9237/5637 8348/8589/5179 8347/8588/5178 +f 9213/9237/5637 8347/8588/5178 9216/9240/5639 +f 9215/9239/5639 8346/8587/5177 8345/8586/5176 +f 9215/9239/5639 8345/8586/5176 9171/7729/4331 +f 8308/7728/5142 9215/9239/5639 9171/7729/4331 +f 7125/7804/4419 9022/9155/5536 9217/9241/5640 +f 7125/7804/4419 9217/9241/5640 8137/8379/4990 +f 9022/9155/5536 8246/8488/5088 8245/8487/5085 +f 9022/9155/5536 8245/8487/5085 9217/9241/5640 +f 9218/9242/5641 8242/8484/5085 8241/8483/5084 +f 9218/9242/5641 8241/8483/5084 9200/9224/5625 +f 8137/8379/4990 9217/9241/5640 9219/9243/5625 +f 8137/8379/4990 9219/9243/5625 8138/8380/4991 +f 8494/8735/5290 9209/9233/5633 9220/9244/5642 +f 8494/8735/5290 9220/9244/5642 9221/9245/5643 +f 9208/9232/5632 8194/8436/5042 8193/8435/5041 +f 9208/9232/5632 8193/8435/5041 9222/9246/5644 +f 9223/9247/5642 8192/8434/5040 8191/8433/5039 +f 9223/9247/5642 8191/8433/5039 9224/9248/5645 +f 8134/8376/4987 9223/9247/5642 9224/9248/5645 +f 8134/8376/4987 9224/9248/5645 7127/7806/4421 +f 7127/7806/4421 9224/9248/5645 9225/9249/5646 +f 7127/7806/4421 9225/9249/5646 7128/7807/4422 +f 9224/9248/5645 8191/8433/5039 8190/8432/5038 +f 9224/9248/5645 8190/8432/5038 9225/9249/5646 +f 9225/9249/5646 8190/8432/5038 9051/9171/5554 +f 9225/9249/5646 9051/9171/5554 9048/9168/5551 +f 7128/7807/4422 9225/9249/5646 9048/9168/5551 +f 7128/7807/4422 9048/9168/5551 7129/7808/4423 +f 7441/7350/5533 9019/9153/5532 9226/9250/5647 +f 7441/7350/5533 9226/9250/5647 9227/7730/5648 +f 9019/9153/5532 8354/8595/5185 8371/8612/5201 +f 9019/9153/5532 8371/8612/5201 9226/9250/5647 +f 9226/9250/5647 8371/8612/5201 8370/8611/5200 +f 9226/9250/5647 8370/8611/5200 9032/9160/5542 +f 9227/7730/5648 9226/9250/5647 9032/9160/5542 +f 9227/7730/5648 9032/9160/5542 7446/7355/5541 +f 6568/6557/4355 8853/9081/5449 9228/9251/5649 +f 6568/6557/4355 9228/9251/5649 9229/7754/5650 +f 8853/9081/5449 8852/9080/5448 9230/9252/5651 +f 8853/9081/5449 9230/9252/5651 9228/9251/5649 +f 9228/9251/5649 9230/9252/5651 7974/8216/4841 +f 9228/9251/5649 7974/8216/4841 8848/9076/5444 +f 9229/7754/5650 9228/9251/5649 8848/9076/5444 +f 9229/7754/5650 8848/9076/5444 6560/7755/4349 +f 6881/7795/4393 8821/9059/5425 9231/9253/5652 +f 6881/7795/4393 9231/9253/5652 6879/7793/4391 +f 8821/9059/5425 7691/7933/4581 9232/9254/5653 +f 8821/9059/5425 9232/9254/5653 9231/9253/5652 +f 9231/9253/5652 9232/9254/5653 7812/8054/4691 +f 9231/9253/5652 7812/8054/4691 8834/9070/5436 +f 6879/7793/4391 9231/9253/5652 8834/9070/5436 +f 6879/7793/4391 8834/9070/5436 6876/6829/4390 +f 8688/8929/5379 8691/8932/5379 9233/9255/5654 +f 8688/8929/5379 9233/9255/5654 9234/9256/5654 +f 8691/8932/5379 7763/8005/4648 7818/8060/4697 +f 8691/8932/5379 7818/8060/4697 9233/9255/5654 +f 9233/9255/5654 7818/8060/4697 7817/8059/4696 +f 9233/9255/5654 7817/8059/4696 8739/8980/5392 +f 9234/9256/5654 9233/9255/5654 8739/8980/5392 +f 9234/9256/5654 8739/8980/5392 8734/8975/5392 +f 8349/8590/5180 8689/8930/5379 9235/9257/5654 +f 8349/8590/5180 9235/9257/5654 8368/8609/5198 +f 8689/8930/5379 8688/8929/5379 9234/9256/5654 +f 8689/8930/5379 9234/9256/5654 9235/9257/5654 +f 9235/9257/5654 9234/9256/5654 8734/8975/5392 +f 9235/9257/5654 8734/8975/5392 8731/8972/5392 +f 8368/8609/5198 9235/9257/5654 8731/8972/5392 +f 8368/8609/5198 8731/8972/5392 8365/8606/5195 +f 8500/8741/5296 8499/8740/5295 9236/9258/5655 +f 8500/8741/5296 9236/9258/5655 9237/9259/5656 +f 8499/8740/5295 7982/8224/4849 7980/8222/4847 +f 8499/8740/5295 7980/8222/4847 9236/9258/5655 +f 9236/9258/5655 7980/8222/4847 7979/8221/4846 +f 9236/9258/5655 7979/8221/4846 8561/8802/5320 +f 9237/9259/5656 9236/9258/5655 8561/8802/5320 +f 9237/9259/5656 8561/8802/5320 8559/8800/5319 +f 8194/8436/5042 9207/9231/5630 9238/9260/5657 +f 8194/8436/5042 9238/9260/5657 8184/8426/5032 +f 9207/9231/5630 9239/9261/5658 9240/9262/5659 +f 9207/9231/5630 9240/9262/5659 9238/9260/5657 +f 9241/9263/5660 9237/9259/5656 8559/8800/5319 +f 9241/9263/5660 8559/8800/5319 8556/8797/5316 +f 9242/9264/5032 9241/9263/5660 8556/8797/5316 +f 9242/9264/5032 8556/8797/5316 8555/8796/5029 +f 7887/8129/4761 7886/8128/4760 9243/9265/5661 +f 7887/8129/4761 9243/9265/5661 8738/8979/5394 +f 7885/8127/4759 7884/8126/4758 9034/9162/5544 +f 7885/8127/4759 9034/9162/5544 9244/9266/5662 +f 9244/9266/5662 9034/9162/5544 8370/8611/5200 +f 9244/9266/5662 8370/8611/5200 8369/8610/5199 +f 8733/8974/5394 9245/9267/5663 8366/8607/5196 +f 8733/8974/5394 8366/8607/5196 8365/8606/5195 +f 8164/8406/5013 8163/8405/5012 9246/9268/5664 +f 8164/8406/5013 9246/9268/5664 8558/8799/5318 +f 8163/8405/5012 8162/8404/5011 9247/9269/5665 +f 8163/8405/5012 9247/9269/5665 9246/9268/5664 +f 9246/9268/5664 9247/9269/5665 8186/8428/5034 +f 9246/9268/5664 8186/8428/5034 8185/8427/5033 +f 8558/8799/5318 9246/9268/5664 8185/8427/5033 +f 8558/8799/5318 8185/8427/5033 8555/8796/5029 +f 8204/8446/5050 8202/8444/5048 9248/9270/5666 +f 8204/8446/5050 9248/9270/5666 9249/9271/5667 +f 8202/8444/5048 8201/8443/5047 8563/8804/5321 +f 8202/8444/5048 8563/8804/5321 9248/9270/5666 +f 9248/9270/5666 8563/8804/5321 7979/8221/4846 +f 9248/9270/5666 7979/8221/4846 7978/8220/4845 +f 9249/9271/5667 9248/9270/5666 7978/8220/4845 +f 9249/9271/5667 7978/8220/4845 9250/9272/4841 +f 7691/7933/4581 7690/7932/4580 9251/9273/5668 +f 7691/7933/4581 9251/9273/5668 9232/9254/5653 +f 7689/7931/4579 7688/7930/4578 8743/8984/5396 +f 7689/7931/4579 8743/8984/5396 9252/9274/5669 +f 9253/9275/5670 8741/8982/5395 7817/8059/4696 +f 9253/9275/5670 7817/8059/4696 7816/8058/4695 +f 9232/9254/5653 9251/9273/5668 7813/8055/4692 +f 9232/9254/5653 7813/8055/4692 7812/8054/4691 +f 9260/7737/4195 7401/7307/4195 7121/7309/4334 +f 9261/7738/4195 7121/7309/4416 7124/7740/4418 +f 9262/7739/4195 7124/7740/4418 7129/7808/4423 +f 9262/7739/4195 7129/7808/4423 9050/9170/5553 +f 7133/7073/4195 9262/7739/4195 9050/9170/5553 +f 7133/7073/4195 9050/9170/5553 7134/7809/4424 +f 6875/7743/4172 9265/7744/4149 8836/7746/5438 +f 8836/7746/5438 6877/6830/4149 6876/6829/4390 +f 6569/6558/4149 6568/6557/4355 9229/7754/5650 +f 9273/7753/4149 9229/7754/5650 6560/7755/4349 +o Plane.011__0 +v 0.821226 1.368190 -0.915690 +v 0.862995 1.365623 -0.916212 +v 0.875007 1.257687 -0.929703 +v 0.831417 1.261421 -0.927736 +v 0.877721 1.364372 -0.915224 +v 0.890390 1.256202 -0.928854 +v 0.894757 1.148445 -0.931066 +v 0.879045 1.149784 -0.931755 +v 0.834543 1.153428 -0.928355 +v -0.845889 1.345648 -0.913647 +v -0.887847 1.350423 -0.913230 +v -0.870382 1.474179 -0.874206 +v -0.834223 1.461875 -0.875898 +v -0.902979 1.358199 -0.912153 +v -0.884359 1.480413 -0.873261 +v -0.866868 1.576972 -0.825767 +v -0.854071 1.572351 -0.826285 +v -0.822877 1.555343 -0.828207 +v -0.822877 1.555343 -0.828207 +v -0.854071 1.572351 -0.826285 +v -0.849324 1.610795 -0.779442 +v -0.816706 1.600573 -0.779727 +v -0.866868 1.576972 -0.825767 +v -0.862185 1.613576 -0.779677 +v -0.868950 1.614101 -0.707091 +v -0.855240 1.613039 -0.706330 +v -0.817981 1.614129 -0.705034 +v -0.869390 1.608751 -0.584719 +v -0.828671 1.616792 -0.583925 +v -0.883927 1.608674 -0.585238 +v -0.909405 1.594252 -0.449781 +v -0.894532 1.594525 -0.450171 +v -0.852104 1.604170 -0.451649 +v -0.835432 0.967184 -0.051747 +v -0.872185 0.957152 -0.052371 +v -0.852128 0.944093 -0.047577 +v -0.818634 0.952003 -0.046496 +v -0.884936 0.953444 -0.054077 +v -0.863650 0.941262 -0.049410 +v -0.853992 0.936799 -0.048002 +v -0.842902 0.938038 -0.046474 +v -0.810819 0.944753 -0.045176 +v 0.464512 1.006627 -0.046531 +v 0.392706 1.001837 -0.055802 +v 0.391894 0.962104 -0.047498 +v 0.463238 0.970937 -0.036556 +v 0.318286 0.999771 -0.062290 +v 0.318018 0.959027 -0.054613 +v 0.317997 0.947299 -0.052114 +v 0.391688 0.950533 -0.044715 +v 0.462870 0.959453 -0.033198 +v -0.490243 1.617728 -0.284863 +v -0.587667 1.599047 -0.289471 +v -0.579901 1.556746 -0.228457 +v -0.487508 1.570732 -0.226067 +v -0.706937 1.575644 -0.289838 +v -0.697061 1.542276 -0.228158 +v -0.677807 1.513275 -0.176014 +v -0.567012 1.517763 -0.176137 +v -0.483218 1.524424 -0.175707 +v 0.347475 1.650487 -0.276160 +v 0.246161 1.655852 -0.280466 +v 0.246165 1.611503 -0.234319 +v 0.347512 1.604785 -0.226551 +v 0.121689 1.657638 -0.281837 +v 0.121689 1.616095 -0.237134 +v 0.121689 1.570082 -0.202704 +v 0.246173 1.563653 -0.197685 +v 0.347574 1.556756 -0.185853 +v 0.833521 1.577202 -0.291347 +v 0.748214 1.585786 -0.287924 +v 0.750409 1.541709 -0.221687 +v 0.836711 1.533165 -0.223729 +v 0.643659 1.598604 -0.283725 +v 0.644834 1.554381 -0.220101 +v 0.646641 1.509897 -0.164175 +v 0.753607 1.497029 -0.162839 +v 0.841244 1.488047 -0.163274 +v -0.134972 1.648805 -0.269566 +v -0.259392 1.639594 -0.271153 +v -0.259392 1.598801 -0.216798 +v -0.134972 1.611902 -0.217882 +v -0.360349 1.631392 -0.276654 +v -0.360354 1.585399 -0.220864 +v -0.360398 1.538073 -0.173939 +v -0.259398 1.555342 -0.172444 +v -0.134972 1.570937 -0.177163 +v -0.914902 1.542631 -0.272090 +v -0.959157 1.540654 -0.266492 +v -0.964876 1.537317 -0.212698 +v -0.917642 1.533817 -0.216343 +v -0.973254 1.542812 -0.264365 +v -0.979018 1.540871 -0.211310 +v -0.970019 1.532766 -0.172663 +v -0.955664 1.528615 -0.172781 +v -0.905912 1.522036 -0.173517 +v 0.468972 1.630155 -0.276694 +v 0.412596 1.642116 -0.274968 +v 0.412721 1.596399 -0.222454 +v 0.469256 1.585057 -0.221161 +v 0.347512 1.604785 -0.226551 +v 0.347574 1.556756 -0.185853 +v 0.412928 1.549235 -0.178509 +v 0.469731 1.539128 -0.173963 +v 0.121689 1.657638 -0.281837 +v -0.006641 1.655203 -0.275691 +v -0.006641 1.617240 -0.228245 +v 0.121689 1.616095 -0.237134 +v -0.134972 1.648805 -0.269566 +v -0.134972 1.611902 -0.217882 +v -0.134972 1.570937 -0.177163 +v -0.006641 1.574572 -0.191740 +v 0.121689 1.570082 -0.202704 +v 0.347808 1.466509 -0.128444 +v 0.246202 1.471931 -0.148552 +v 0.246218 1.427447 -0.128284 +v 0.347939 1.423084 -0.104342 +v 0.121689 1.478675 -0.159726 +v 0.121689 1.433651 -0.142585 +v 0.121689 1.390601 -0.129073 +v 0.246234 1.386076 -0.112845 +v 0.348060 1.383264 -0.086833 +v -0.885265 1.423934 -0.106203 +v -0.933644 1.424736 -0.107285 +v -0.927806 1.358767 -0.078959 +v -0.879958 1.363263 -0.077525 +v -0.948274 1.426381 -0.108593 +v -0.943249 1.357963 -0.080578 +v -0.945097 1.288684 -0.061566 +v -0.928672 1.292023 -0.059816 +v -0.880482 1.302106 -0.058288 +v -0.134972 1.484603 -0.127053 +v -0.259429 1.470205 -0.115626 +v -0.259449 1.428291 -0.093176 +v -0.134972 1.440963 -0.107550 +v -0.360651 1.452993 -0.111693 +v -0.360810 1.412559 -0.086745 +v -0.361014 1.374740 -0.070194 +v -0.259475 1.387631 -0.077927 +v -0.134972 1.397534 -0.093679 +v 0.471505 1.455502 -0.108360 +v 0.413703 1.461636 -0.116126 +v 0.414140 1.419566 -0.090004 +v 0.472505 1.415412 -0.081365 +v 0.414542 1.380661 -0.071640 +v 0.473424 1.377155 -0.063195 +v 0.856123 1.410925 -0.087011 +v 0.764349 1.421798 -0.087497 +v 0.770274 1.386117 -0.058339 +v 0.864286 1.374122 -0.057652 +v 0.652995 1.434843 -0.090963 +v 0.656533 1.399333 -0.062272 +v 0.659715 1.361927 -0.044997 +v 0.775506 1.347709 -0.040366 +v 0.871425 1.334388 -0.038671 +v -0.482704 1.440321 -0.107858 +v -0.562865 1.436215 -0.105429 +v -0.564867 1.394982 -0.076943 +v -0.483935 1.400078 -0.080528 +v -0.668059 1.431284 -0.103913 +v -0.669299 1.386410 -0.074617 +v -0.672379 1.342417 -0.055587 +v -0.567619 1.355525 -0.058473 +v -0.485512 1.362404 -0.062699 +v -0.006641 1.485556 -0.147582 +v -0.006641 1.440808 -0.130391 +v -0.006641 1.396733 -0.117317 +v -0.006641 1.353850 -0.110812 +v 0.121689 1.350727 -0.121319 +v -0.134972 1.354638 -0.088911 +v -0.134972 1.313032 -0.088060 +v -0.006641 1.312066 -0.106662 +v 0.121689 1.312156 -0.115462 +v 0.414864 1.346744 -0.066113 +v 0.474161 1.341777 -0.059684 +v 0.348156 1.349132 -0.080154 +v 0.348205 1.316687 -0.079122 +v 0.415025 1.314258 -0.067775 +v 0.474530 1.307192 -0.064698 +v -0.936956 1.225154 -0.054777 +v -0.887909 1.240609 -0.053722 +v -0.954051 1.219741 -0.056494 +v -0.964055 1.158771 -0.059066 +v -0.946611 1.165461 -0.057450 +v -0.896733 1.184684 -0.057035 +v -0.571403 1.318943 -0.056326 +v -0.487578 1.328948 -0.060359 +v -0.677849 1.299838 -0.053174 +v -0.683294 1.258763 -0.059008 +v -0.574920 1.283761 -0.062090 +v -0.489468 1.297662 -0.065426 +v 0.779350 1.304968 -0.040536 +v 0.876552 1.289990 -0.036140 +v 0.662150 1.321507 -0.046579 +v 0.663312 1.280082 -0.058561 +v 0.781101 1.260768 -0.048889 +v 0.878823 1.243969 -0.038924 +v 0.246246 1.349639 -0.105221 +v 0.246252 1.314782 -0.101022 +v -0.259508 1.349191 -0.074375 +v -0.361282 1.341296 -0.067307 +v -0.361527 1.310568 -0.070831 +v -0.259539 1.312778 -0.076201 +v -0.951548 1.119067 -0.060382 +v -0.901330 1.139372 -0.060342 +v -0.969121 1.112042 -0.061916 +v -0.969808 1.073912 -0.064621 +v -0.952273 1.080738 -0.063179 +v -0.902170 1.100471 -0.063401 +v 0.780311 1.218058 -0.053649 +v 0.877715 1.199502 -0.034818 +v 0.662871 1.239704 -0.070147 +v 0.661407 1.199473 -0.077078 +v 0.777555 1.175619 -0.052680 +v 0.873835 1.155508 -0.024568 +v -0.576897 1.248110 -0.066228 +v -0.490535 1.265887 -0.068776 +v -0.686297 1.218974 -0.063540 +v -0.687390 1.179465 -0.067227 +v -0.577738 1.211121 -0.069411 +v -0.491004 1.232189 -0.071179 +v 0.245809 1.278231 -0.095729 +v 0.347592 1.282246 -0.078072 +v 0.121535 1.272817 -0.107692 +v 0.120455 1.232922 -0.100427 +v 0.242715 1.242188 -0.091695 +v 0.343360 1.249497 -0.078835 +v -0.259556 1.277641 -0.076499 +v -0.134972 1.273116 -0.085656 +v -0.361665 1.280144 -0.072679 +v -0.361726 1.248004 -0.073930 +v -0.259563 1.241942 -0.076819 +v -0.134972 1.233423 -0.083739 +v 0.414586 1.279964 -0.070073 +v 0.474333 1.271490 -0.070654 +v 0.411708 1.247255 -0.073572 +v 0.473397 1.236597 -0.076156 +v -0.006660 1.270996 -0.100623 +v -0.006795 1.229700 -0.095015 +v -0.007104 1.186849 -0.092056 +v 0.117987 1.191385 -0.095939 +v -0.134972 1.192559 -0.084357 +v -0.134972 1.151269 -0.082077 +v -0.007413 1.140117 -0.087008 +v 0.115518 1.139653 -0.089719 +v 0.405271 1.216006 -0.078809 +v 0.471636 1.201746 -0.080189 +v 0.333726 1.218496 -0.082980 +v 0.323953 1.167409 -0.083539 +v 0.398430 1.165375 -0.079105 +v 0.469281 1.151535 -0.077093 +v 0.773090 1.131896 -0.045937 +v 0.867201 1.110913 -0.011558 +v 0.659378 1.157579 -0.076529 +v 0.655852 1.111512 -0.064872 +v 0.764866 1.088160 -0.032102 +v 0.854346 1.068908 0.003203 +v -0.577991 1.171937 -0.073213 +v -0.491184 1.195293 -0.074252 +v -0.687252 1.138973 -0.071458 +v -0.684206 1.096003 -0.071339 +v -0.577064 1.128735 -0.072629 +v -0.490820 1.153327 -0.073102 +v 0.235647 1.206211 -0.091024 +v 0.228562 1.153790 -0.087975 +v 0.224922 0.999871 -0.065107 +v 0.224893 0.960404 -0.057467 +v 0.114284 1.007506 -0.065066 +v 0.114283 0.961823 -0.057338 +v 0.114279 0.936154 -0.054887 +v 0.224922 0.946740 -0.055022 +v -0.494397 1.066500 -0.051930 +v -0.575939 1.041733 -0.051897 +v -0.582665 1.017661 -0.044648 +v -0.505456 1.042299 -0.044618 +v -0.670867 1.013275 -0.051808 +v -0.668996 0.990695 -0.044919 +v -0.669622 0.979963 -0.042814 +v -0.590233 1.006208 -0.042361 +v -0.516828 1.030792 -0.042300 +v -0.259566 1.204097 -0.079014 +v -0.361749 1.212411 -0.076285 +v -0.361701 1.172359 -0.074769 +v -0.259561 1.164615 -0.077695 +v -0.949056 1.044105 -0.066248 +v -0.899640 1.062775 -0.066797 +v -0.966338 1.037610 -0.067568 +v -0.951038 1.003765 -0.067437 +v -0.934642 1.009639 -0.066142 +v -0.887679 1.026328 -0.066743 +v -0.007567 1.026876 -0.063258 +v -0.007571 0.962051 -0.055661 +v -0.134972 1.051594 -0.060207 +v -0.134976 0.975691 -0.052818 +v -0.135007 0.909735 -0.050551 +v -0.007598 0.911084 -0.053292 +v -0.259708 1.073110 -0.056482 +v -0.260068 1.012637 -0.049176 +v -0.362880 1.084798 -0.053425 +v -0.365741 1.048116 -0.046115 +v -0.368638 1.023181 -0.043854 +v -0.260449 0.962167 -0.046938 +v 0.812383 1.007514 0.031581 +v 0.738698 1.014932 0.008140 +v 0.730712 0.996080 0.019033 +v 0.799498 0.992441 0.038772 +v 0.644599 1.019055 -0.017160 +v 0.641181 0.994956 -0.003642 +v 0.639858 0.984340 0.000647 +v 0.727289 0.986997 0.022401 +v 0.793821 0.984948 0.040905 +v 0.788855 1.603595 -0.680958 +v 0.716844 1.612793 -0.682302 +v 0.728505 1.638662 -0.561558 +v 0.805259 1.628743 -0.561731 +v 0.626099 1.625709 -0.684267 +v 0.632788 1.653467 -0.561275 +v 0.638993 1.655797 -0.438774 +v 0.739645 1.641239 -0.441948 +v 0.821161 1.631567 -0.444144 +v 0.464423 1.653934 -0.688843 +v 0.410609 1.662976 -0.690127 +v 0.411393 1.700514 -0.560141 +v 0.466217 1.688942 -0.560512 +v 0.346878 1.667743 -0.689462 +v 0.347113 1.705819 -0.559210 +v 0.347323 1.709114 -0.428147 +v 0.412090 1.703215 -0.429187 +v 0.467812 1.691269 -0.431515 +v 0.246086 1.669692 -0.686044 +v 0.246115 1.705850 -0.557108 +v 0.121689 1.672727 -0.680285 +v 0.121689 1.704419 -0.553593 +v 0.121689 1.706774 -0.427108 +v 0.246142 1.709578 -0.428017 +v -0.006641 1.679128 -0.673599 +v -0.006641 1.704626 -0.549174 +v -0.134972 1.682238 -0.670200 +v -0.134972 1.703908 -0.546991 +v -0.134972 1.699008 -0.422799 +v -0.006641 1.702938 -0.424391 +v -0.259346 1.676131 -0.673272 +v -0.259367 1.699583 -0.549588 +v -0.359983 1.666754 -0.679070 +v -0.360154 1.694167 -0.554489 +v -0.360287 1.692858 -0.429575 +v -0.259384 1.695539 -0.425117 +v -0.480016 1.654768 -0.687548 +v -0.559206 1.645118 -0.693101 +v -0.556500 1.680148 -0.571360 +v -0.479486 1.686785 -0.564152 +v -0.653801 1.633069 -0.698713 +v -0.651463 1.665137 -0.578201 +v -0.665189 1.660743 -0.453583 +v -0.564153 1.678937 -0.447679 +v -0.482365 1.687158 -0.439851 +v 0.784229 1.504143 -0.833292 +v 0.713323 1.509028 -0.833930 +v 0.710460 1.566032 -0.771022 +v 0.780229 1.558849 -0.769674 +v 0.623812 1.512041 -0.834860 +v 0.622147 1.574165 -0.773000 +v 0.463712 1.505042 -0.837010 +v 0.410298 1.502251 -0.837600 +v 0.410100 1.588177 -0.778929 +v 0.463257 1.585032 -0.777622 +v 0.346784 1.505481 -0.837196 +v 0.346725 1.591856 -0.778320 +v 0.346878 1.667743 -0.689462 +v 0.410609 1.662976 -0.690127 +v 0.464423 1.653934 -0.688843 +v 0.246074 1.517204 -0.835165 +v 0.246067 1.598026 -0.774966 +v 0.121689 1.533655 -0.830729 +v 0.121689 1.607921 -0.768989 +v 0.121689 1.672727 -0.680285 +v 0.246086 1.669692 -0.686044 +v -0.006641 1.549119 -0.824191 +v -0.006641 1.620600 -0.761640 +v -0.134972 1.556321 -0.820331 +v -0.134972 1.627141 -0.757748 +v -0.134972 1.682238 -0.670200 +v -0.006641 1.679128 -0.673599 +v -0.259321 1.550773 -0.823065 +v -0.259327 1.620503 -0.761019 +v -0.359785 1.540696 -0.828376 +v -0.359835 1.609162 -0.767106 +v -0.359983 1.666754 -0.679070 +v -0.259346 1.676131 -0.673272 +v -0.485887 1.523615 -0.833696 +v -0.577749 1.505682 -0.835901 +v -0.570367 1.578490 -0.777935 +v -0.483501 1.593209 -0.774174 +v -0.679894 1.500053 -0.836117 +v -0.668901 1.571000 -0.780712 +v -0.653801 1.633069 -0.698713 +v -0.559206 1.645118 -0.693101 +v -0.480016 1.654768 -0.687548 +v 0.740808 1.372576 -0.914179 +v 0.726444 1.449170 -0.883035 +v 0.801740 1.445579 -0.883019 +v 0.640939 1.375391 -0.913002 +v 0.632111 1.449802 -0.883188 +v 0.623812 1.512041 -0.834860 +v 0.713323 1.509028 -0.833930 +v 0.784229 1.504143 -0.833292 +v 0.468803 1.369733 -0.914406 +v 0.412523 1.368174 -0.915647 +v 0.411394 1.430727 -0.884460 +v 0.466221 1.435611 -0.884069 +v 0.347453 1.376172 -0.917131 +v 0.347114 1.435436 -0.884810 +v 0.347453 1.376172 -0.917131 +v 0.246158 1.397264 -0.918745 +v 0.246115 1.452727 -0.884849 +v 0.347114 1.435436 -0.884810 +v 0.121689 1.417518 -0.918469 +v 0.121689 1.472779 -0.882813 +v 0.121689 1.533655 -0.830729 +v 0.246074 1.517204 -0.835165 +v 0.346784 1.505481 -0.837196 +v -0.006641 1.423060 -0.915000 +v -0.006641 1.484932 -0.877835 +v -0.134972 1.417711 -0.911817 +v -0.134972 1.487976 -0.874123 +v -0.134972 1.556321 -0.820331 +v -0.006641 1.549119 -0.824191 +v -0.134972 1.417711 -0.911817 +v -0.259384 1.408878 -0.912220 +v -0.259336 1.483805 -0.875471 +v -0.134972 1.487976 -0.874123 +v -0.360289 1.400613 -0.914009 +v -0.359910 1.477286 -0.878940 +v -0.482378 1.388001 -0.914220 +v -0.564011 1.376797 -0.914411 +v -0.571795 1.446407 -0.883043 +v -0.484074 1.462625 -0.881987 +v -0.663898 1.363200 -0.914601 +v -0.673442 1.436583 -0.882611 +v -0.679894 1.500053 -0.836117 +v -0.577749 1.505682 -0.835901 +v -0.485887 1.523615 -0.833696 +v -0.845889 1.345648 -0.913647 +v -0.765488 1.350999 -0.914217 +v -0.770333 1.247225 -0.927197 +v -0.852927 1.236503 -0.929065 +v -0.663898 1.363200 -0.914601 +v -0.666770 1.263278 -0.925198 +v -0.674492 1.156960 -0.925591 +v -0.774651 1.146459 -0.928577 +v -0.852605 1.139686 -0.931401 +v -0.482378 1.388001 -0.914220 +v -0.424782 1.394801 -0.914458 +v -0.426639 1.283856 -0.926506 +v -0.485135 1.279515 -0.924690 +v -0.360289 1.400613 -0.914009 +v -0.360926 1.294211 -0.927482 +v -0.361512 1.183274 -0.928875 +v -0.428561 1.166747 -0.927455 +v -0.489358 1.163868 -0.924882 +v -0.259384 1.408878 -0.912220 +v -0.259483 1.315448 -0.926053 +v -0.135126 1.339573 -0.925041 +v -0.136206 1.263952 -0.924633 +v -0.259691 1.221273 -0.926855 +v -0.006641 1.423060 -0.915000 +v -0.007084 1.356016 -0.927088 +v 0.121689 1.417518 -0.918469 +v 0.121073 1.356767 -0.929719 +v 0.116752 1.296735 -0.927870 +v -0.010190 1.291509 -0.925555 +v 0.246158 1.397264 -0.918745 +v 0.245726 1.338798 -0.929999 +v 0.347396 1.316447 -0.928251 +v 0.346274 1.254614 -0.927516 +v 0.242616 1.279400 -0.928917 +v 0.468803 1.369733 -0.914406 +v 0.545816 1.373632 -0.913269 +v 0.547356 1.288143 -0.919342 +v 0.469549 1.296717 -0.922261 +v 0.640939 1.375391 -0.913002 +v 0.644376 1.278174 -0.919078 +v 0.644358 1.175748 -0.913548 +v 0.546876 1.197600 -0.913387 +v 0.469228 1.219777 -0.917841 +v -0.361512 1.183274 -0.928875 +v -0.259691 1.221273 -0.926855 +v -0.260032 1.147632 -0.926162 +v -0.361766 1.097815 -0.929039 +v -0.136206 1.263952 -0.924633 +v -0.138674 1.203685 -0.923312 +v -0.141142 1.165051 -0.922104 +v -0.260346 1.101579 -0.924988 +v -0.361806 1.045458 -0.928549 +v 0.116752 1.296735 -0.927870 +v 0.242616 1.279400 -0.928917 +v 0.235512 1.225566 -0.927376 +v 0.106877 1.247132 -0.926027 +v 0.346274 1.254614 -0.927516 +v 0.343771 1.194084 -0.925673 +v 0.341256 1.148898 -0.923837 +v 0.228391 1.187409 -0.926367 +v 0.096998 1.214387 -0.925221 +v 0.834543 1.153428 -0.928355 +v 0.879045 1.149784 -0.931755 +v 0.880143 1.074816 -0.931653 +v 0.835399 1.075162 -0.927622 +v 0.894757 1.148445 -0.931066 +v 0.895591 1.075387 -0.931084 +v 0.893503 1.042444 -0.930540 +v 0.880058 1.034475 -0.930510 +v 0.835543 1.030050 -0.926341 +v -0.489358 1.163868 -0.924882 +v -0.428561 1.166747 -0.927455 +v -0.429408 1.076531 -0.928710 +v -0.491314 1.073612 -0.927077 +v -0.429534 1.021369 -0.929707 +v -0.491600 1.017777 -0.929540 +v -0.852605 1.139686 -0.931401 +v -0.774651 1.146459 -0.928577 +v -0.772138 1.062424 -0.930315 +v -0.844496 1.056805 -0.932471 +v -0.674492 1.156960 -0.925591 +v -0.676779 1.069984 -0.927990 +v -0.675521 1.013673 -0.930603 +v -0.766991 1.006340 -0.931748 +v -0.835182 0.999506 -0.932735 +v -0.010190 1.291509 -0.925555 +v -0.017287 1.239847 -0.923787 +v -0.024381 1.206547 -0.922813 +v 0.546516 1.117151 -0.908273 +v 0.469004 1.147342 -0.912810 +v 0.644099 1.090263 -0.909603 +v 0.644071 1.033860 -0.907306 +v 0.546449 1.061286 -0.904765 +v 0.468933 1.094800 -0.908688 +v 0.121689 1.706774 -0.427108 +v -0.006641 1.702938 -0.424391 +v -0.006641 1.684875 -0.335871 +v 0.121689 1.689381 -0.339465 +v -0.134972 1.699008 -0.422799 +v -0.134972 1.678949 -0.332899 +v -0.006641 1.655203 -0.275691 +v 0.121689 1.657638 -0.281837 +v 0.467812 1.691269 -0.431515 +v 0.412090 1.703215 -0.429187 +v 0.412450 1.680609 -0.337608 +v 0.468638 1.668557 -0.340569 +v 0.347323 1.709114 -0.428147 +v 0.347431 1.687828 -0.337134 +v 0.347475 1.650487 -0.276160 +v 0.412596 1.642116 -0.274968 +v 0.468972 1.630155 -0.276694 +v -0.852104 1.604170 -0.451649 +v -0.894532 1.594525 -0.450171 +v -0.930363 1.565069 -0.343219 +v -0.887329 1.572116 -0.347576 +v -0.909405 1.594252 -0.449781 +v -0.944892 1.565718 -0.341648 +v -0.259384 1.695539 -0.425117 +v -0.259391 1.673515 -0.335276 +v -0.360287 1.692858 -0.429575 +v -0.360342 1.669564 -0.340420 +v 0.821161 1.631567 -0.444144 +v 0.739645 1.641239 -0.441948 +v 0.745622 1.621513 -0.355195 +v 0.829751 1.612439 -0.358652 +v 0.638993 1.655797 -0.438774 +v 0.642273 1.635127 -0.350466 +v 0.246155 1.690607 -0.338982 +v 0.121689 1.689381 -0.339465 +v 0.246161 1.655852 -0.280466 +v 0.347475 1.650487 -0.276160 +v -0.482365 1.687158 -0.439851 +v -0.564153 1.678937 -0.447679 +v -0.578964 1.645667 -0.357036 +v -0.487414 1.660357 -0.350310 +v -0.665189 1.660743 -0.453583 +v -0.690698 1.622623 -0.360080 +v -0.006641 1.530328 -0.166511 +v 0.121689 1.524115 -0.178408 +v -0.134972 1.528151 -0.148649 +v -0.134972 1.484603 -0.127053 +v 0.121689 1.478675 -0.159726 +v -0.483218 1.524424 -0.175707 +v -0.567012 1.517763 -0.176137 +v -0.562009 1.477570 -0.136899 +v -0.481888 1.481337 -0.138026 +v -0.677807 1.513275 -0.176014 +v -0.668856 1.475420 -0.136298 +v -0.668059 1.431284 -0.103913 +v -0.562865 1.436215 -0.105429 +v -0.482704 1.440321 -0.107858 +v 0.841244 1.488047 -0.163274 +v 0.753607 1.497029 -0.162839 +v 0.758477 1.457622 -0.120182 +v 0.848013 1.447802 -0.119859 +v 0.646641 1.509897 -0.164175 +v 0.649502 1.470620 -0.123060 +v 0.413274 1.504534 -0.144486 +v 0.470523 1.496251 -0.137910 +v 0.347679 1.510810 -0.154521 +v 0.347808 1.466509 -0.128444 +v 0.413703 1.461636 -0.116126 +v 0.471505 1.455502 -0.108360 +v -0.259398 1.555342 -0.172444 +v -0.259411 1.512440 -0.140466 +v -0.360398 1.538073 -0.173939 +v -0.360505 1.494281 -0.139235 +v -0.360651 1.452993 -0.111693 +v -0.259429 1.470205 -0.115626 +v -0.905912 1.522036 -0.173517 +v -0.955664 1.528615 -0.172781 +v -0.943763 1.487222 -0.138580 +v -0.894115 1.482044 -0.137906 +v -0.970019 1.532766 -0.172663 +v -0.958155 1.490662 -0.139366 +v 0.246186 1.517149 -0.170498 +v 0.121689 1.524115 -0.178408 +v 0.646641 1.509897 -0.164175 +v 0.547910 1.525070 -0.168610 +v 0.549446 1.484356 -0.129979 +v 0.649502 1.470620 -0.123060 +v 0.551344 1.446497 -0.099090 +v 0.544097 1.673987 -0.434995 +v 0.545736 1.652125 -0.345224 +v 0.642273 1.635127 -0.350466 +v 0.546407 1.614561 -0.279813 +v 0.412554 1.236483 -0.923318 +v 0.412143 1.170264 -0.919861 +v 0.411772 1.120742 -0.916611 +v 0.412523 1.368174 -0.915647 +v 0.412829 1.303818 -0.925495 +v 0.469549 1.296717 -0.922261 +v 0.469228 1.219777 -0.917841 +v 0.412554 1.236483 -0.923318 +v 0.545816 1.373632 -0.913269 +v 0.540868 1.443948 -0.883587 +v 0.536097 1.509759 -0.835977 +v 0.535211 1.580580 -0.775396 +v 0.622147 1.574165 -0.773000 +v 0.537441 1.640530 -0.686641 +v 0.626099 1.625709 -0.684267 +v 0.537441 1.640530 -0.686641 +v 0.540947 1.671768 -0.560889 +v 0.556362 1.220363 -0.081805 +v 0.555855 1.181583 -0.084409 +v 0.554687 1.133066 -0.076746 +v 0.557137 1.295867 -0.063115 +v 0.556932 1.257969 -0.073798 +v 0.555041 1.371549 -0.053683 +v 0.556442 1.333780 -0.053348 +v 0.551344 1.446497 -0.099090 +v 0.553275 1.409091 -0.071215 +v 0.546977 1.570005 -0.220193 +v 0.644834 1.554381 -0.220101 +v 0.469256 1.585057 -0.221161 +v 0.469731 1.539128 -0.173963 +v 0.547910 1.525070 -0.168610 +v 0.646641 1.509897 -0.164175 +v 0.549656 1.014494 -0.034822 +v 0.548072 0.984423 -0.022271 +v 0.547586 0.973102 -0.018167 +v -0.425146 1.529275 -0.175199 +v -0.425234 1.485084 -0.138844 +v -0.425683 1.444086 -0.109756 +v -0.424777 1.690759 -0.434088 +v -0.425538 1.666759 -0.345040 +v -0.425908 1.626409 -0.280915 +v -0.573656 1.162386 -0.924153 +v -0.576876 1.073303 -0.926745 +v -0.577143 1.017083 -0.929779 +v -0.564011 1.376797 -0.914411 +v -0.566621 1.273947 -0.924198 +v -0.573656 1.162386 -0.924153 +v -0.424782 1.394801 -0.914458 +v -0.424093 1.471900 -0.880936 +v -0.484074 1.462625 -0.881987 +v -0.424024 1.533871 -0.831636 +v -0.423845 1.601897 -0.771133 +v -0.423760 1.660635 -0.683442 +v -0.423760 1.660635 -0.683442 +v -0.424100 1.690409 -0.558949 +v -0.432438 1.082062 -0.052130 +v -0.440613 1.056360 -0.044812 +v -0.448903 1.043253 -0.042515 +v -0.429274 1.244776 -0.072457 +v -0.429351 1.209389 -0.075011 +v -0.429193 1.168477 -0.073495 +v -0.428608 1.305900 -0.067958 +v -0.429070 1.276400 -0.070651 +v -0.426897 1.367157 -0.066081 +v -0.427791 1.335156 -0.063524 +v -0.425683 1.444086 -0.109756 +v -0.426215 1.404119 -0.083390 +v -0.360349 1.631392 -0.276654 +v -0.425908 1.626409 -0.280915 +v -0.425579 1.578151 -0.223856 +v -0.360354 1.585399 -0.220864 +v -0.490243 1.617728 -0.284863 +v -0.487508 1.570732 -0.226067 +v -0.429249 1.122638 -0.063930 +v -0.361744 1.128174 -0.065220 +v -0.490459 1.106821 -0.063695 +v 0.552263 1.070603 -0.056644 +v 0.650224 1.061456 -0.041306 +v 0.466704 1.076634 -0.063086 +v 0.751762 1.047185 -0.011443 +v 0.833401 1.033479 0.018708 +v -0.259566 1.123060 -0.068260 +v -0.134972 1.108220 -0.072169 +v -0.007548 1.087201 -0.075709 +v 0.114438 1.072753 -0.077786 +v -0.575056 1.081916 -0.063531 +v -0.677303 1.051108 -0.062857 +v 0.225421 1.074695 -0.077490 +v 0.319341 1.081929 -0.074508 +v 0.394444 1.081837 -0.069084 +v -0.904458 0.979673 -0.060153 +v -0.862449 0.993056 -0.060234 +v -0.919083 0.974864 -0.061619 +v -0.884936 0.953444 -0.054077 +v -0.796924 1.058241 -0.068945 +v -0.780866 1.018898 -0.061467 +v -0.763726 0.986856 -0.051676 +v -0.677807 1.513275 -0.176014 +v -0.803043 1.515572 -0.174882 +v -0.791943 1.477354 -0.136883 +v -0.668856 1.475420 -0.136298 +v -0.787043 1.426535 -0.104606 +v -0.769376 1.630835 -0.453975 +v -0.801634 1.594349 -0.355187 +v -0.690698 1.622623 -0.360080 +v -0.824725 1.555102 -0.282059 +v -0.706937 1.575644 -0.289838 +v -0.906655 1.152750 -0.931364 +v -0.892649 1.144213 -0.932422 +v -0.881485 1.059165 -0.933218 +v -0.894433 1.065528 -0.932162 +v -0.844496 1.056805 -0.932471 +v -0.835182 0.999506 -0.932735 +v -0.870136 1.000133 -0.933014 +v -0.883066 1.013694 -0.932325 +v -0.902979 1.358199 -0.912153 +v -0.887847 1.350423 -0.913230 +v -0.895646 1.240117 -0.929684 +v -0.910643 1.249242 -0.928604 +v -0.852927 1.236503 -0.929065 +v -0.906655 1.152750 -0.931364 +v -0.805644 1.137804 -0.064986 +v -0.804364 1.098274 -0.068937 +v -0.800685 1.220685 -0.057412 +v -0.804610 1.177577 -0.061471 +v -0.786753 1.321711 -0.056158 +v -0.793350 1.269569 -0.052707 +v -0.784959 1.374079 -0.075411 +v -0.820202 1.534664 -0.222865 +v -0.697061 1.542276 -0.228158 +v -0.803043 1.515572 -0.174882 +v -0.677807 1.513275 -0.176014 +v -0.753323 0.967868 -0.045588 +v -0.748641 0.958827 -0.043868 +v -0.746387 1.621537 -0.702668 +v -0.749980 1.639645 -0.582177 +v -0.651463 1.665137 -0.578201 +v -0.769376 1.630835 -0.453975 +v -0.764436 1.523452 -0.832545 +v -0.754910 1.582459 -0.780779 +v -0.816706 1.600573 -0.779727 +v -0.817981 1.614129 -0.705034 +v -0.746387 1.621537 -0.702668 +v -0.765854 1.445090 -0.879467 +v -0.673442 1.436583 -0.882611 +v 0.917720 1.054711 0.026172 +v 0.901043 1.058783 0.021492 +v 0.875823 1.026028 0.034369 +v 0.891000 1.022845 0.038469 +v 0.850455 1.003112 0.043781 +v 0.864104 1.000958 0.047002 +v 0.902953 1.480898 -0.164733 +v 0.886919 1.483406 -0.163784 +v 0.894707 1.442652 -0.120041 +v 0.911106 1.440025 -0.120941 +v 0.904018 1.405133 -0.087150 +v 0.920856 1.402396 -0.088091 +v 0.878371 1.623806 -0.445844 +v 0.863536 1.626613 -0.445271 +v 0.873533 1.607782 -0.360467 +v 0.888870 1.605102 -0.361507 +v 0.877940 1.572789 -0.293215 +v 0.893511 1.570241 -0.294438 +v 0.749104 1.161256 -0.920361 +v 0.749361 1.077902 -0.918145 +v 0.835399 1.075162 -0.927622 +v 0.835543 1.030050 -0.926341 +v 0.749419 1.026382 -0.916583 +v 0.862995 1.365623 -0.916212 +v 0.840770 1.443283 -0.882862 +v 0.854508 1.441904 -0.881858 +v 0.821226 1.368190 -0.915690 +v 0.801740 1.445579 -0.883019 +v 0.784229 1.504143 -0.833292 +v 0.820917 1.501213 -0.832852 +v 0.833801 1.499399 -0.831895 +v 0.833801 1.499399 -0.831895 +v 0.820917 1.501213 -0.832852 +v 0.816303 1.554907 -0.768908 +v 0.828944 1.552591 -0.768014 +v 0.780229 1.558849 -0.769674 +v 0.826123 1.598800 -0.680229 +v 0.839165 1.596099 -0.679582 +v 0.845073 1.623656 -0.561799 +v 0.859004 1.620810 -0.561717 +v 0.805259 1.628743 -0.561731 +v 0.864104 1.000958 0.047002 +v 0.850455 1.003112 0.043781 +v 0.834871 0.989990 0.049003 +v 0.847434 0.988631 0.051606 +v 0.812383 1.007514 0.031581 +v 0.799498 0.992441 0.038772 +v 0.827960 0.983541 0.050391 +v 0.839581 0.983685 0.052501 +v 0.942093 1.140789 -0.006772 +v 0.924176 1.144905 -0.010072 +v 0.916396 1.099913 0.006204 +v 0.933935 1.095586 0.010555 +v 0.948034 1.231746 -0.033232 +v 0.929916 1.235075 -0.033839 +v 0.928645 1.189696 -0.025112 +v 0.946738 1.185962 -0.023194 +v 0.939251 1.324410 -0.038973 +v 0.921550 1.327218 -0.038166 +v 0.927365 1.281996 -0.034085 +v 0.945348 1.278995 -0.034394 +v 0.913385 1.367668 -0.057715 +v 0.930681 1.364907 -0.058680 +v 0.881669 1.528774 -0.224978 +v 0.897440 1.526293 -0.226102 +v 0.886919 1.483406 -0.163784 +v 0.902953 1.480898 -0.164733 +v 0.740808 1.372576 -0.914179 +v 0.747634 1.268655 -0.922984 +v 0.820723 1.356060 -0.882833 +v 0.831433 1.255230 -0.893016 +v 0.874862 1.251811 -0.895201 +v 0.862336 1.353995 -0.883557 +v 0.834891 1.151559 -0.892776 +v 0.879215 1.147939 -0.896471 +v 0.894721 1.146785 -0.898103 +v 0.890122 1.250989 -0.896518 +v 0.877034 1.353926 -0.884571 +v -0.846482 1.356342 -0.880457 +v -0.836365 1.457490 -0.847137 +v -0.872820 1.465614 -0.847142 +v -0.888536 1.353704 -0.880606 +v -0.826130 1.534983 -0.806471 +v -0.858167 1.549552 -0.807745 +v -0.871085 1.552375 -0.810244 +v -0.886642 1.465889 -0.848862 +v -0.903535 1.350025 -0.881892 +v -0.826130 1.534983 -0.806471 +v -0.819354 1.570437 -0.767085 +v -0.853872 1.579735 -0.771216 +v -0.858167 1.549552 -0.807745 +v -0.818777 1.576534 -0.701033 +v -0.859259 1.576459 -0.706793 +v -0.875018 1.580769 -0.710257 +v -0.867637 1.583490 -0.774594 +v -0.871085 1.552375 -0.810244 +v -0.827425 1.569963 -0.585546 +v -0.872600 1.565393 -0.589100 +v -0.850304 1.552391 -0.455124 +v -0.897921 1.547631 -0.453844 +v -0.916646 1.554269 -0.453466 +v -0.890379 1.570977 -0.591124 +v -0.832457 0.959559 -0.086594 +v -0.815288 0.943335 -0.080797 +v -0.848606 0.936480 -0.081779 +v -0.869078 0.950399 -0.087053 +v -0.807642 0.936435 -0.077085 +v -0.839521 0.930809 -0.078385 +v -0.850535 0.930322 -0.078884 +v -0.860146 0.934695 -0.081437 +v -0.881890 0.947598 -0.086454 +v 0.469886 0.995038 -0.079796 +v 0.469322 0.957022 -0.068568 +v 0.396607 0.949148 -0.080100 +v 0.396942 0.991338 -0.089592 +v 0.469029 0.945226 -0.062446 +v 0.396422 0.937090 -0.074539 +v 0.320931 0.935257 -0.082679 +v 0.320983 0.947393 -0.087877 +v 0.321048 0.990287 -0.096559 +v -0.485968 1.588178 -0.303418 +v -0.484029 1.543609 -0.248487 +v -0.575830 1.528260 -0.248195 +v -0.582096 1.568115 -0.304840 +v -0.480820 1.499644 -0.201130 +v -0.564568 1.491955 -0.200035 +v -0.676353 1.486262 -0.197662 +v -0.693841 1.512030 -0.244110 +v -0.701639 1.542239 -0.300835 +v 0.344784 1.622906 -0.296801 +v 0.345898 1.580449 -0.251719 +v 0.245201 1.587030 -0.259659 +v 0.244792 1.627613 -0.300998 +v 0.347322 1.535207 -0.214015 +v 0.245834 1.542700 -0.226346 +v 0.120908 1.549322 -0.231451 +v 0.121051 1.591455 -0.262277 +v 0.121286 1.629022 -0.301993 +v 0.829660 1.546591 -0.308832 +v 0.833311 1.504547 -0.244778 +v 0.746771 1.513456 -0.243086 +v 0.743865 1.555536 -0.305721 +v 0.838247 1.461247 -0.186792 +v 0.750675 1.470545 -0.186686 +v 0.643806 1.484135 -0.188633 +v 0.640885 1.527055 -0.242090 +v 0.638663 1.569337 -0.302020 +v -0.133997 1.619655 -0.289153 +v -0.134509 1.586412 -0.242247 +v -0.257902 1.572985 -0.240922 +v -0.257596 1.610427 -0.290796 +v -0.135242 1.549121 -0.205116 +v -0.258496 1.532801 -0.199881 +v -0.358420 1.514825 -0.200860 +v -0.357910 1.559334 -0.244824 +v -0.357739 1.602315 -0.296477 +v -0.918206 1.504420 -0.274067 +v -0.922932 1.500858 -0.223014 +v -0.974497 1.504803 -0.214281 +v -0.967214 1.504366 -0.264488 +v -0.911399 1.492821 -0.188060 +v -0.964870 1.499280 -0.182449 +v -0.981329 1.504852 -0.178062 +v -0.990964 1.510526 -0.209167 +v -0.983999 1.510237 -0.259838 +v 0.463534 1.603831 -0.296317 +v 0.465363 1.560610 -0.244811 +v 0.409905 1.572273 -0.246989 +v 0.408314 1.615513 -0.295244 +v 0.467600 1.515760 -0.200243 +v 0.411854 1.526890 -0.205813 +v 0.345898 1.580449 -0.251719 +v 0.344784 1.622906 -0.296801 +v -0.006873 1.592206 -0.252998 +v -0.006341 1.626265 -0.295477 +v -0.007484 1.553444 -0.220191 +v 0.350496 1.450452 -0.159900 +v 0.351832 1.411565 -0.137617 +v 0.248461 1.416305 -0.161919 +v 0.247617 1.456932 -0.180701 +v 0.352684 1.376731 -0.123045 +v 0.249027 1.378927 -0.148528 +v 0.121799 1.382939 -0.164171 +v 0.121530 1.422638 -0.176414 +v 0.121219 1.464237 -0.192266 +v -0.886933 1.406383 -0.135529 +v -0.880315 1.351631 -0.110647 +v -0.928852 1.347847 -0.111828 +v -0.936909 1.407803 -0.135546 +v -0.880406 1.295780 -0.093122 +v -0.928668 1.286145 -0.094425 +v -0.945231 1.283531 -0.093814 +v -0.944833 1.348189 -0.111099 +v -0.952606 1.410788 -0.134125 +v -0.136911 1.469317 -0.159109 +v -0.137657 1.429449 -0.141041 +v -0.261322 1.416381 -0.126366 +v -0.260314 1.453915 -0.147096 +v -0.138181 1.389877 -0.128275 +v -0.262136 1.380461 -0.112505 +v -0.362662 1.368061 -0.104772 +v -0.361565 1.400232 -0.119625 +v -0.360357 1.435659 -0.142540 +v 0.472783 1.436876 -0.138201 +v 0.475220 1.402562 -0.113777 +v 0.417948 1.407479 -0.122876 +v 0.416110 1.444308 -0.146786 +v 0.477098 1.371070 -0.099224 +v 0.419205 1.374571 -0.108017 +v 0.854011 1.389418 -0.114805 +v 0.863187 1.358445 -0.088595 +v 0.769846 1.370724 -0.089406 +v 0.762832 1.400511 -0.115487 +v 0.871649 1.325139 -0.072461 +v 0.776340 1.339107 -0.074243 +v 0.661413 1.354296 -0.079308 +v 0.657060 1.384619 -0.093657 +v 0.652305 1.414129 -0.119381 +v -0.482296 1.421619 -0.137792 +v -0.484436 1.387058 -0.112937 +v -0.565167 1.381902 -0.109365 +v -0.562438 1.417383 -0.135224 +v -0.486752 1.355924 -0.097143 +v -0.568546 1.348914 -0.092919 +v -0.672843 1.335722 -0.090114 +v -0.669322 1.373563 -0.107218 +v -0.667752 1.412676 -0.133686 +v -0.008681 1.429635 -0.164138 +v -0.008413 1.470972 -0.180053 +v -0.008809 1.388889 -0.152056 +v 0.121937 1.345759 -0.157694 +v -0.008793 1.348787 -0.146217 +v 0.121969 1.308880 -0.152820 +v -0.008615 1.308862 -0.142450 +v -0.138171 1.310978 -0.123608 +v -0.138364 1.350316 -0.124147 +v 0.478118 1.341451 -0.100060 +v 0.419656 1.345684 -0.107307 +v 0.478318 1.310110 -0.108065 +v 0.419449 1.316111 -0.112750 +v 0.352561 1.316677 -0.123236 +v 0.352881 1.346701 -0.120619 +v -0.887965 1.238889 -0.089248 +v -0.936756 1.223456 -0.090023 +v -0.897173 1.186226 -0.092759 +v -0.946671 1.166710 -0.092871 +v -0.963891 1.159836 -0.092037 +v -0.953747 1.218255 -0.089321 +v -0.489264 1.328243 -0.095688 +v -0.572812 1.318130 -0.091650 +v -0.491298 1.300627 -0.100947 +v -0.576604 1.286736 -0.097611 +v -0.684664 1.261375 -0.094577 +v -0.678810 1.298696 -0.088539 +v 0.878171 1.285444 -0.071294 +v 0.781415 1.301845 -0.075804 +v 0.881729 1.241028 -0.074252 +v 0.784221 1.260057 -0.084449 +v 0.666600 1.281463 -0.095484 +v 0.664779 1.319874 -0.082753 +v 0.249177 1.345705 -0.143663 +v 0.248990 1.312785 -0.141855 +v -0.262548 1.346137 -0.109676 +v -0.262508 1.312428 -0.111785 +v -0.363731 1.311880 -0.106445 +v -0.363424 1.339510 -0.102686 +v -0.902094 1.142246 -0.096108 +v -0.951925 1.121655 -0.095830 +v -0.902909 1.102916 -0.099180 +v -0.952683 1.083122 -0.098628 +v -0.969977 1.076142 -0.097625 +v -0.969228 1.114338 -0.094908 +v 0.881677 1.194557 -0.069718 +v 0.784232 1.215781 -0.088990 +v 0.878675 1.146974 -0.058720 +v 0.782142 1.169819 -0.087487 +v 0.665502 1.196592 -0.113163 +v 0.666587 1.240033 -0.106925 +v -0.492221 1.269568 -0.104410 +v -0.578578 1.251961 -0.101851 +v -0.492242 1.234503 -0.106921 +v -0.579061 1.213708 -0.105132 +v -0.688686 1.182123 -0.102953 +v -0.687824 1.222656 -0.099194 +v 0.351353 1.282623 -0.123276 +v 0.248156 1.276692 -0.137447 +v 0.346516 1.249071 -0.122559 +v 0.244605 1.240222 -0.132634 +v 0.120579 1.229936 -0.137918 +v 0.121777 1.270079 -0.145431 +v -0.137653 1.271881 -0.121359 +v -0.262059 1.278069 -0.112226 +v -0.137102 1.231755 -0.119479 +v -0.261495 1.241642 -0.112598 +v -0.363125 1.248951 -0.109731 +v -0.363554 1.282135 -0.108411 +v 0.477811 1.274313 -0.113860 +v 0.418460 1.282029 -0.115571 +v 0.476666 1.237413 -0.117153 +v 0.415099 1.247966 -0.116957 +v -0.008317 1.268492 -0.136577 +v -0.008173 1.226938 -0.130955 +v 0.117916 1.187764 -0.132674 +v -0.008396 1.183182 -0.127839 +v 0.115268 1.134995 -0.125611 +v -0.008726 1.135198 -0.122561 +v -0.136652 1.146574 -0.117574 +v -0.136790 1.189575 -0.120024 +v 0.474991 1.200201 -0.118546 +v 0.408443 1.214983 -0.118809 +v 0.473061 1.147128 -0.113128 +v 0.401704 1.161924 -0.115902 +v 0.326481 1.163972 -0.120587 +v 0.336451 1.216923 -0.123394 +v 0.872808 1.099339 -0.044819 +v 0.778329 1.122850 -0.079980 +v 0.860540 1.054891 -0.029063 +v 0.770694 1.076307 -0.065188 +v 0.661041 1.102364 -0.098970 +v 0.663971 1.151483 -0.111694 +v -0.491667 1.195236 -0.110011 +v -0.578549 1.172124 -0.108960 +v -0.490333 1.150098 -0.108603 +v -0.576540 1.125643 -0.108122 +v -0.683708 1.093170 -0.106866 +v -0.687846 1.139348 -0.107208 +v 0.237133 1.203508 -0.129842 +v 0.229775 1.149780 -0.124549 +v 0.226110 0.950761 -0.091470 +v 0.226068 0.991580 -0.099842 +v 0.226129 0.937064 -0.086473 +v 0.114151 0.929146 -0.087121 +v 0.114069 0.954258 -0.091961 +v 0.113988 1.000266 -0.100150 +v -0.491868 1.056247 -0.086030 +v -0.502222 1.030407 -0.077855 +v -0.579047 1.005646 -0.077868 +v -0.573040 1.031420 -0.085968 +v -0.513400 1.019102 -0.073012 +v -0.586490 0.994369 -0.073072 +v -0.666139 0.969095 -0.073918 +v -0.665491 0.979525 -0.078456 +v -0.667939 1.003568 -0.086070 +v -0.261093 1.202162 -0.114740 +v -0.260812 1.160545 -0.113234 +v -0.362176 1.168890 -0.110343 +v -0.362676 1.211460 -0.112066 +v -0.899802 1.063418 -0.102586 +v -0.948977 1.044963 -0.101708 +v -0.886838 1.024247 -0.102396 +v -0.933638 1.008033 -0.101495 +v -0.950006 1.002603 -0.100391 +v -0.966115 1.038598 -0.100602 +v -0.008630 0.955926 -0.090598 +v -0.008798 1.020166 -0.098473 +v -0.008441 0.906166 -0.085965 +v -0.135952 0.905613 -0.083341 +v -0.136182 0.969946 -0.087795 +v -0.136406 1.044843 -0.095386 +v -0.260696 1.006009 -0.083985 +v -0.260512 1.065793 -0.091525 +v -0.260931 0.957104 -0.079578 +v -0.368053 1.015935 -0.076005 +v -0.365199 1.039721 -0.080505 +v -0.362538 1.076515 -0.088208 +v 0.819201 0.989756 0.001203 +v 0.806546 0.974164 0.009099 +v 0.737834 0.978840 -0.011209 +v 0.745433 0.998531 -0.022944 +v 0.800625 0.967759 0.013350 +v 0.734261 0.970596 -0.005578 +v 0.646894 0.968718 -0.027746 +v 0.648248 0.978881 -0.034504 +v 0.651085 1.004323 -0.049059 +v 0.784890 1.571959 -0.667973 +v 0.800829 1.595265 -0.557763 +v 0.723543 1.605462 -0.557261 +v 0.712612 1.581556 -0.668731 +v 0.816643 1.597758 -0.449282 +v 0.734461 1.607657 -0.447061 +v 0.632919 1.622660 -0.443947 +v 0.627112 1.620673 -0.556623 +v 0.621502 1.595026 -0.669974 +v 0.459663 1.624373 -0.673079 +v 0.459985 1.656941 -0.555131 +v 0.406355 1.668477 -0.554573 +v 0.406738 1.633530 -0.674009 +v 0.460973 1.659151 -0.436860 +v 0.406551 1.670867 -0.434621 +v 0.343785 1.676252 -0.433582 +v 0.343879 1.673534 -0.553579 +v 0.344295 1.638135 -0.673295 +v 0.244615 1.673290 -0.551517 +v 0.244740 1.639784 -0.670092 +v 0.244537 1.676327 -0.433323 +v 0.121544 1.673278 -0.432342 +v 0.121487 1.671571 -0.548266 +v 0.121300 1.642418 -0.664844 +v -0.006153 1.671484 -0.544395 +v -0.006458 1.648370 -0.658923 +v -0.005992 1.669281 -0.429784 +v -0.133867 1.665308 -0.428493 +v -0.134105 1.670596 -0.542732 +v -0.134421 1.651177 -0.656121 +v -0.258103 1.666342 -0.545511 +v -0.258429 1.645081 -0.659244 +v -0.257795 1.661946 -0.431114 +v -0.358153 1.659455 -0.435825 +v -0.358453 1.661147 -0.550350 +v -0.358686 1.635918 -0.664736 +v -0.477531 1.624470 -0.672596 +v -0.476171 1.654238 -0.559674 +v -0.551377 1.647348 -0.566806 +v -0.555574 1.614831 -0.678338 +v -0.478275 1.654052 -0.445885 +v -0.558007 1.645243 -0.452762 +v -0.657934 1.622937 -0.457639 +v -0.645370 1.629317 -0.574462 +v -0.649882 1.601372 -0.685662 +v 0.782075 1.480143 -0.807981 +v 0.777093 1.530382 -0.749687 +v 0.707382 1.538079 -0.750378 +v 0.711476 1.485504 -0.808081 +v 0.619150 1.546944 -0.751501 +v 0.622384 1.489278 -0.808267 +v 0.462908 1.483901 -0.808981 +v 0.460567 1.559325 -0.754437 +v 0.407804 1.562682 -0.755393 +v 0.409417 1.481354 -0.809291 +v 0.459663 1.624373 -0.673079 +v 0.406738 1.633530 -0.674009 +v 0.344295 1.638135 -0.673295 +v 0.344949 1.566194 -0.754783 +v 0.345722 1.484362 -0.808759 +v 0.244850 1.571970 -0.751683 +v 0.244961 1.495528 -0.806577 +v 0.244740 1.639784 -0.670092 +v 0.121300 1.642418 -0.664844 +v 0.121017 1.581378 -0.746202 +v 0.120762 1.511404 -0.802272 +v 0.120762 1.511404 -0.802272 +v 0.121017 1.581378 -0.746202 +v -0.006823 1.593605 -0.739531 +v -0.007126 1.526546 -0.796396 +v 0.121300 1.642418 -0.664844 +v -0.006458 1.648370 -0.658923 +v -0.134421 1.651177 -0.656121 +v -0.134724 1.599842 -0.736164 +v -0.134950 1.533591 -0.793279 +v -0.258702 1.593129 -0.739516 +v -0.258901 1.527912 -0.796351 +v -0.258429 1.645081 -0.659244 +v -0.358686 1.635918 -0.664736 +v -0.358820 1.581884 -0.745383 +v -0.358948 1.517764 -0.801687 +v -0.484274 1.501053 -0.806671 +v -0.481593 1.566433 -0.751873 +v -0.568217 1.552015 -0.755646 +v -0.576543 1.483724 -0.808630 +v -0.477531 1.624470 -0.672596 +v -0.555574 1.614831 -0.678338 +v -0.649882 1.601372 -0.685662 +v -0.667340 1.544159 -0.759806 +v -0.679826 1.479029 -0.809392 +v 0.820723 1.356060 -0.882833 +v 0.800498 1.427228 -0.853370 +v 0.725557 1.431030 -0.853102 +v 0.740561 1.360419 -0.881272 +v 0.631698 1.432196 -0.852799 +v 0.640987 1.363497 -0.879928 +v 0.469099 1.358541 -0.881122 +v 0.466399 1.419261 -0.852791 +v 0.411258 1.414577 -0.852987 +v 0.412499 1.357067 -0.882527 +v 0.346468 1.418988 -0.852833 +v 0.346970 1.364709 -0.883538 +v 0.346970 1.364709 -0.883538 +v 0.346468 1.418988 -0.852833 +v 0.245110 1.435511 -0.851787 +v 0.245329 1.384962 -0.883593 +v 0.345722 1.484362 -0.808759 +v 0.244961 1.495528 -0.806577 +v 0.120762 1.511404 -0.802272 +v 0.120671 1.454878 -0.849241 +v 0.120815 1.404533 -0.882506 +v 0.120815 1.404533 -0.882506 +v 0.120671 1.454878 -0.849241 +v -0.007256 1.466906 -0.845314 +v -0.007179 1.410104 -0.880537 +v 0.120762 1.511404 -0.802272 +v -0.007126 1.526546 -0.796396 +v -0.134950 1.533591 -0.793279 +v -0.135054 1.470038 -0.843113 +v -0.135057 1.405021 -0.879342 +v -0.259029 1.465754 -0.845175 +v -0.259157 1.396136 -0.880219 +v -0.258901 1.527912 -0.796351 +v -0.358948 1.517764 -0.801687 +v -0.359201 1.459041 -0.848763 +v -0.359750 1.387656 -0.881609 +v -0.481087 1.375038 -0.881495 +v -0.482564 1.444544 -0.851649 +v -0.570696 1.429198 -0.852427 +v -0.562846 1.364845 -0.881518 +v -0.484274 1.501053 -0.806671 +v -0.576543 1.483724 -0.808630 +v -0.679826 1.479029 -0.809392 +v -0.673327 1.422652 -0.851990 +v -0.663239 1.356653 -0.881504 +v -0.846482 1.356342 -0.880457 +v -0.852852 1.253640 -0.893869 +v -0.770032 1.259085 -0.892254 +v -0.765535 1.355486 -0.880985 +v -0.852482 1.155308 -0.895635 +v -0.774495 1.159461 -0.892920 +v -0.674300 1.160133 -0.890041 +v -0.666183 1.263007 -0.890526 +v -0.663239 1.356653 -0.881504 +v -0.481087 1.375038 -0.881495 +v -0.484406 1.272398 -0.890263 +v -0.426121 1.276711 -0.892211 +v -0.423798 1.381743 -0.881824 +v -0.489218 1.161502 -0.889415 +v -0.428490 1.164382 -0.892197 +v -0.361491 1.180921 -0.895049 +v -0.360653 1.287136 -0.894015 +v -0.359750 1.387656 -0.881609 +v -0.259361 1.308496 -0.894351 +v -0.259157 1.396136 -0.880219 +v -0.259667 1.218932 -0.896190 +v -0.136173 1.261565 -0.896394 +v -0.135154 1.332611 -0.894232 +v -0.135057 1.405021 -0.879342 +v -0.007361 1.348815 -0.894861 +v -0.007179 1.410104 -0.880537 +v -0.010200 1.289006 -0.896796 +v 0.116609 1.294220 -0.897400 +v 0.120574 1.349506 -0.895854 +v 0.120815 1.404533 -0.882506 +v 0.120815 1.404533 -0.882506 +v 0.245167 1.332009 -0.896371 +v 0.245329 1.384962 -0.883593 +v 0.116609 1.294220 -0.897400 +v 0.242239 1.277136 -0.897610 +v 0.345636 1.252732 -0.895557 +v 0.346908 1.310294 -0.895348 +v 0.469099 1.358541 -0.881122 +v 0.469372 1.291005 -0.887956 +v 0.547354 1.282322 -0.884629 +v 0.546099 1.362118 -0.880004 +v 0.468459 1.218424 -0.883003 +v 0.546482 1.196238 -0.877909 +v 0.644418 1.174231 -0.877983 +v 0.644490 1.272157 -0.884355 +v 0.640987 1.363497 -0.879928 +v -0.361859 1.097473 -0.895410 +v -0.260056 1.147265 -0.896227 +v -0.361916 1.045437 -0.897021 +v -0.260383 1.101544 -0.896678 +v -0.141095 1.164996 -0.896465 +v -0.138621 1.203279 -0.896418 +v 0.106840 1.246740 -0.897058 +v 0.235083 1.225386 -0.896585 +v 0.242239 1.277136 -0.897610 +v 0.096930 1.214418 -0.897586 +v 0.227855 1.187697 -0.896600 +v 0.340213 1.149514 -0.892348 +v 0.342884 1.194216 -0.893315 +v 0.345636 1.252732 -0.895557 +v 0.834891 1.151559 -0.892776 +v 0.835934 1.075044 -0.892083 +v 0.880466 1.074604 -0.896437 +v 0.836129 1.030153 -0.893161 +v 0.880419 1.034489 -0.897563 +v 0.893651 1.042436 -0.898726 +v 0.895664 1.075166 -0.898160 +v -0.491441 1.073265 -0.891547 +v -0.429538 1.076198 -0.893418 +v -0.491765 1.017741 -0.896356 +v -0.429692 1.021352 -0.896730 +v -0.852482 1.155308 -0.895635 +v -0.844400 1.066111 -0.896904 +v -0.772088 1.070840 -0.894762 +v -0.774495 1.159461 -0.892920 +v -0.835098 1.002367 -0.899550 +v -0.766965 1.009034 -0.898564 +v -0.675569 1.014588 -0.897419 +v -0.676792 1.072782 -0.892450 +v -0.674300 1.160133 -0.890041 +v -0.017193 1.239403 -0.896756 +v -0.024290 1.206486 -0.897072 +v 0.468459 1.218424 -0.883003 +v 0.467936 1.147957 -0.877832 +v 0.545988 1.117709 -0.872821 +v 0.546482 1.196238 -0.877909 +v 0.467854 1.095787 -0.875727 +v 0.545979 1.062131 -0.871631 +v 0.644269 1.034432 -0.874135 +v 0.644212 1.090609 -0.874073 +v 0.644418 1.174231 -0.877983 +v 0.121468 1.657513 -0.353176 +v -0.006043 1.652807 -0.349406 +v 0.121286 1.629022 -0.301993 +v -0.006341 1.626265 -0.295477 +v -0.133997 1.619655 -0.289153 +v -0.133801 1.646824 -0.346477 +v 0.460973 1.659151 -0.436860 +v 0.462130 1.639010 -0.354277 +v 0.407200 1.650661 -0.351695 +v 0.406551 1.670867 -0.434621 +v 0.463534 1.603831 -0.296317 +v 0.408314 1.615513 -0.295244 +v 0.344784 1.622906 -0.296801 +v 0.344077 1.656941 -0.351366 +v 0.343785 1.676252 -0.433582 +v -0.850304 1.552391 -0.455124 +v -0.887595 1.525295 -0.349750 +v -0.935796 1.522191 -0.343245 +v -0.897921 1.547631 -0.453844 +v -0.953763 1.528663 -0.340375 +v -0.916646 1.554269 -0.453466 +v -0.257590 1.641495 -0.349112 +v -0.257596 1.610427 -0.290796 +v -0.357739 1.602315 -0.296477 +v -0.357867 1.637738 -0.354599 +v 0.816643 1.597758 -0.449282 +v 0.825469 1.579836 -0.370970 +v 0.740696 1.589194 -0.367707 +v 0.734461 1.607657 -0.447061 +v 0.636491 1.603540 -0.363317 +v 0.632919 1.622660 -0.443947 +v 0.344077 1.656941 -0.351366 +v 0.244582 1.659079 -0.353013 +v 0.344784 1.622906 -0.296801 +v 0.244792 1.627613 -0.300998 +v -0.478275 1.654052 -0.445885 +v -0.482948 1.628520 -0.363825 +v -0.572652 1.612786 -0.368226 +v -0.558007 1.645243 -0.452762 +v -0.683835 1.586122 -0.368114 +v -0.657934 1.622937 -0.457639 +v 0.120980 1.506597 -0.209442 +v -0.008011 1.512563 -0.197376 +v -0.136074 1.509585 -0.179009 +v -0.480820 1.499644 -0.201130 +v -0.480521 1.458994 -0.165761 +v -0.560743 1.454704 -0.164007 +v -0.564568 1.491955 -0.200035 +v -0.482296 1.421619 -0.137792 +v -0.562438 1.417383 -0.135224 +v -0.667752 1.412676 -0.133686 +v -0.668237 1.452149 -0.162541 +v -0.676353 1.486262 -0.197662 +v 0.838247 1.461247 -0.186792 +v 0.845352 1.422909 -0.145345 +v 0.756186 1.432984 -0.145938 +v 0.750675 1.470545 -0.186686 +v 0.647721 1.446572 -0.149365 +v 0.643806 1.484135 -0.188633 +v 0.470150 1.474380 -0.165971 +v 0.413996 1.484051 -0.173566 +v 0.472783 1.436876 -0.138201 +v 0.416110 1.444308 -0.146786 +v 0.350496 1.450452 -0.159900 +v 0.348920 1.491678 -0.184538 +v -0.259330 1.492826 -0.170171 +v -0.359265 1.473593 -0.168245 +v -0.911399 1.492821 -0.188060 +v -0.897947 1.458187 -0.160639 +v -0.950313 1.463507 -0.158248 +v -0.964870 1.499280 -0.182449 +v -0.966355 1.468242 -0.155370 +v -0.981329 1.504852 -0.178062 +v 0.348920 1.491678 -0.184538 +v 0.246684 1.499106 -0.201218 +v 0.647721 1.446572 -0.149365 +v 0.548245 1.461257 -0.157080 +v 0.545240 1.500455 -0.193905 +v 0.652305 1.414129 -0.119381 +v 0.551563 1.426701 -0.128154 +v 0.636491 1.603540 -0.363317 +v 0.539208 1.621769 -0.358493 +v 0.537245 1.641484 -0.440249 +v 0.540861 1.586999 -0.298739 +v 0.410980 1.170705 -0.886008 +v 0.411733 1.234939 -0.889941 +v 0.410502 1.121630 -0.884113 +v 0.412479 1.298028 -0.892131 +v 0.411733 1.234939 -0.889941 +v 0.631698 1.432196 -0.852799 +v 0.540896 1.427027 -0.852690 +v 0.546099 1.362118 -0.880004 +v 0.622384 1.489278 -0.808267 +v 0.535074 1.487899 -0.808577 +v 0.619150 1.546944 -0.751501 +v 0.532314 1.554208 -0.752965 +v 0.621502 1.595026 -0.669974 +v 0.532537 1.610487 -0.671549 +v 0.534648 1.639451 -0.555844 +v 0.532537 1.610487 -0.671549 +v 0.459985 1.656941 -0.555131 +v 0.559725 1.178197 -0.121044 +v 0.559910 1.219871 -0.120094 +v 0.559130 1.126603 -0.111850 +v 0.560395 1.260146 -0.113580 +v 0.560564 1.298579 -0.103172 +v 0.559660 1.333199 -0.091617 +v 0.557678 1.364871 -0.088865 +v 0.554847 1.395298 -0.103092 +v 0.551563 1.426701 -0.128154 +v 0.542797 1.544232 -0.242957 +v 0.643806 1.484135 -0.188633 +v 0.545240 1.500455 -0.193905 +v 0.467600 1.515760 -0.200243 +v 0.465363 1.560610 -0.244811 +v 0.554878 0.969481 -0.053717 +v 0.555737 1.001450 -0.067461 +v 0.554448 0.958195 -0.046963 +v -0.358420 1.514825 -0.200860 +v -0.359265 1.473593 -0.168245 +v -0.423712 1.463469 -0.167196 +v -0.422801 1.505316 -0.201539 +v -0.360357 1.435659 -0.142540 +v -0.425115 1.425906 -0.140058 +v -0.357867 1.637738 -0.354599 +v -0.422327 1.635082 -0.359364 +v -0.421976 1.657543 -0.440453 +v -0.357739 1.602315 -0.296477 +v -0.422605 1.597341 -0.300702 +v -0.576957 1.073323 -0.891213 +v -0.573469 1.160722 -0.888664 +v -0.577263 1.017134 -0.896595 +v -0.565869 1.267773 -0.889697 +v -0.562846 1.364845 -0.881518 +v -0.489218 1.161502 -0.889415 +v -0.484406 1.272398 -0.890263 +v -0.422849 1.453610 -0.850743 +v -0.423798 1.381743 -0.881824 +v -0.422667 1.511010 -0.804846 +v -0.484274 1.501053 -0.806671 +v -0.482564 1.444544 -0.851649 +v -0.422382 1.574817 -0.749111 +v -0.422667 1.511010 -0.804846 +v -0.422040 1.630069 -0.668742 +v -0.477531 1.624470 -0.672596 +v -0.481593 1.566433 -0.751873 +v -0.484274 1.501053 -0.806671 +v -0.421874 1.657632 -0.554663 +v -0.422040 1.630069 -0.668742 +v -0.421976 1.657543 -0.440453 +v -0.438575 1.045911 -0.078553 +v -0.430852 1.072633 -0.086531 +v -0.446755 1.033400 -0.073858 +v -0.429918 1.209020 -0.110794 +v -0.430462 1.246578 -0.108238 +v -0.429039 1.165218 -0.109042 +v -0.430726 1.279483 -0.106338 +v -0.430488 1.308335 -0.103532 +v -0.429565 1.334162 -0.098897 +v -0.428190 1.360695 -0.100595 +v -0.426658 1.391388 -0.115979 +v -0.425115 1.425906 -0.140058 +v -0.357910 1.559334 -0.244824 +v -0.422597 1.551755 -0.247487 +v -0.422605 1.597341 -0.300702 +v -0.484029 1.543609 -0.248487 +v -0.485968 1.588178 -0.303418 +v -0.361769 1.121868 -0.100370 +v -0.428337 1.115971 -0.098922 +v -0.488911 1.099825 -0.098549 +v 0.656048 1.049256 -0.074250 +v 0.557484 1.060683 -0.090410 +v 0.471218 1.068583 -0.097499 +v 0.839953 1.017299 -0.012512 +v 0.758064 1.032755 -0.043456 +v -0.136550 1.101994 -0.107448 +v -0.260581 1.116848 -0.103495 +v 0.114117 1.066684 -0.113139 +v -0.008859 1.081051 -0.111037 +v -0.573285 1.074950 -0.098364 +v -0.675500 1.044538 -0.097784 +v 0.321910 1.075554 -0.109670 +v 0.226537 1.068575 -0.112800 +v 0.398124 1.074907 -0.103956 +v -0.860426 0.987902 -0.095499 +v -0.902311 0.975202 -0.095179 +v -0.832457 0.959559 -0.086594 +v -0.869078 0.950399 -0.087053 +v -0.916983 0.971090 -0.094291 +v -0.778983 1.012995 -0.096563 +v -0.796296 1.055747 -0.104534 +v -0.760811 0.978163 -0.086238 +v -0.676353 1.486262 -0.197662 +v -0.668237 1.452149 -0.162541 +v -0.793146 1.453727 -0.161757 +v -0.804529 1.487297 -0.193467 +v -0.787435 1.408415 -0.134303 +v -0.683835 1.586122 -0.368114 +v -0.797250 1.551249 -0.360104 +v -0.763655 1.584309 -0.457502 +v -0.701639 1.542239 -0.300835 +v -0.822872 1.518492 -0.288481 +v -0.906501 1.135542 -0.898229 +v -0.894313 1.052492 -0.899215 +v -0.881366 1.058567 -0.897973 +v -0.892514 1.145456 -0.896930 +v -0.882953 1.006806 -0.900509 +v -0.870026 0.999118 -0.900064 +v -0.835098 1.002367 -0.899550 +v -0.844400 1.066111 -0.896904 +v -0.903535 1.350025 -0.881892 +v -0.910520 1.236894 -0.895912 +v -0.895589 1.244910 -0.894694 +v -0.906501 1.135542 -0.898229 +v -0.892514 1.145456 -0.896930 +v -0.852852 1.253640 -0.893869 +v -0.846482 1.356342 -0.880457 +v -0.804797 1.098773 -0.104704 +v -0.806718 1.140373 -0.100735 +v -0.805798 1.180866 -0.097181 +v -0.801601 1.222742 -0.093058 +v -0.793822 1.268071 -0.088147 +v -0.786844 1.315110 -0.090832 +v -0.784962 1.361773 -0.108294 +v -0.693841 1.512030 -0.244110 +v -0.820567 1.502689 -0.234428 +v -0.676353 1.486262 -0.197662 +v -0.804529 1.487297 -0.193467 +v -0.749974 0.957939 -0.079530 +v -0.745424 0.949238 -0.075412 +v -0.815288 0.943335 -0.080797 +v -0.649882 1.601372 -0.685662 +v -0.645370 1.629317 -0.574462 +v -0.745282 1.597085 -0.580742 +v -0.744157 1.586462 -0.693618 +v -0.763655 1.584309 -0.457502 +v -0.755202 1.554113 -0.763439 +v -0.766084 1.503422 -0.807837 +v -0.744157 1.586462 -0.693618 +v -0.818777 1.576534 -0.701033 +v -0.819354 1.570437 -0.767085 +v -0.673327 1.422652 -0.851990 +v -0.767000 1.437350 -0.849497 +v -0.765535 1.355486 -0.880985 +v 0.923326 1.040122 -0.003081 +v 0.896894 1.006625 0.010154 +v 0.882278 1.009046 0.003875 +v 0.907187 1.043682 -0.010017 +v 0.870173 0.983429 0.019488 +v 0.857106 0.984713 0.014111 +v 0.900181 1.456242 -0.186448 +v 0.908509 1.417195 -0.144506 +v 0.891929 1.418012 -0.145268 +v 0.883934 1.456837 -0.187032 +v 0.918685 1.382808 -0.113844 +v 0.901701 1.383913 -0.114690 +v 0.874487 1.592448 -0.450880 +v 0.885201 1.574890 -0.372919 +v 0.869558 1.575400 -0.372654 +v 0.859335 1.593040 -0.450507 +v 0.890170 1.541895 -0.310462 +v 0.874320 1.542369 -0.310424 +v 0.749847 1.077992 -0.882610 +v 0.749429 1.159530 -0.884798 +v 0.749981 1.026682 -0.883405 +v 0.836129 1.030153 -0.893161 +v 0.835934 1.075044 -0.892083 +v 0.877034 1.353926 -0.884571 +v 0.853188 1.425390 -0.854436 +v 0.839385 1.425279 -0.853543 +v 0.862336 1.353995 -0.883557 +v 0.831704 1.477156 -0.808856 +v 0.818671 1.477303 -0.808044 +v 0.800498 1.427228 -0.853370 +v 0.826040 1.525978 -0.750131 +v 0.813182 1.526450 -0.749512 +v 0.835614 1.566553 -0.668222 +v 0.822304 1.567237 -0.667788 +v 0.784890 1.571959 -0.667973 +v 0.777093 1.530382 -0.749687 +v 0.855134 1.589661 -0.558571 +v 0.840899 1.590351 -0.558186 +v 0.800829 1.595265 -0.557763 +v 0.870173 0.983429 0.019488 +v 0.853681 0.970602 0.024718 +v 0.841697 0.971137 0.020019 +v 0.857106 0.984713 0.014111 +v 0.845788 0.966202 0.026623 +v 0.834534 0.965793 0.023408 +v 0.800625 0.967759 0.013350 +v 0.806546 0.974164 0.009099 +v 0.819201 0.989756 0.001203 +v 0.946351 1.130102 -0.037770 +v 0.938975 1.082675 -0.019565 +v 0.921946 1.086873 -0.026275 +v 0.928909 1.134543 -0.043487 +v 0.950391 1.226356 -0.065912 +v 0.950099 1.178292 -0.055143 +v 0.932424 1.182751 -0.059432 +v 0.932586 1.230413 -0.068772 +v 0.939268 1.315874 -0.070536 +v 0.946585 1.273473 -0.067150 +v 0.928751 1.276574 -0.068958 +v 0.921558 1.317946 -0.071718 +v 0.929461 1.350842 -0.087495 +v 0.912064 1.352291 -0.088418 +v 0.894424 1.499866 -0.245445 +v 0.878406 1.500356 -0.245728 +v 0.900181 1.456242 -0.186448 +v 0.883934 1.456837 -0.187032 +v 0.747750 1.262464 -0.888293 +v 0.740561 1.360419 -0.881272 +v 0.749429 1.159530 -0.884798 +v 0.831433 1.255230 -0.893016 +v 0.877721 1.364372 -0.915224 +v 0.854508 1.441904 -0.881858 +v 0.858579 1.440200 -0.879441 +v 0.882142 1.363211 -0.912573 +v 0.833801 1.499399 -0.831895 +v 0.837552 1.497087 -0.829794 +v 0.837850 1.494231 -0.826886 +v 0.859010 1.438104 -0.876017 +v 0.882692 1.361902 -0.908773 +v -0.902979 1.358199 -0.912153 +v -0.910643 1.249242 -0.928604 +v -0.915167 1.253066 -0.925721 +v -0.907654 1.361268 -0.909602 +v -0.906655 1.152750 -0.931364 +v -0.910872 1.156168 -0.928413 +v -0.911456 1.152856 -0.924259 +v -0.915792 1.250653 -0.921639 +v -0.908360 1.359983 -0.905909 +v 0.894757 1.148445 -0.931066 +v 0.890390 1.256202 -0.928854 +v 0.895041 1.255374 -0.926039 +v 0.899521 1.147918 -0.928154 +v 0.895667 1.254696 -0.922020 +v 0.900186 1.147664 -0.924033 +v -0.868950 1.614101 -0.707091 +v -0.862185 1.613576 -0.779677 +v -0.866720 1.612584 -0.779768 +v -0.873702 1.612756 -0.707764 +v -0.866868 1.576972 -0.825767 +v -0.871337 1.576846 -0.824928 +v -0.872398 1.574297 -0.823392 +v -0.867993 1.609360 -0.779514 +v -0.875169 1.609220 -0.708417 +v 0.828944 1.552591 -0.768014 +v 0.832560 1.549797 -0.766334 +v 0.839165 1.596099 -0.679582 +v 0.842855 1.592992 -0.678504 +v 0.842983 1.589221 -0.677078 +v 0.832749 1.546382 -0.764072 +v -0.909405 1.594252 -0.449781 +v -0.883927 1.608674 -0.585238 +v -0.888930 1.607141 -0.585912 +v -0.914520 1.592767 -0.449956 +v -0.890557 1.603487 -0.586767 +v -0.916278 1.589150 -0.450409 +v 0.859004 1.620810 -0.561717 +v 0.862942 1.617559 -0.561455 +v 0.878371 1.623806 -0.445844 +v 0.882583 1.620551 -0.446414 +v 0.882749 1.616573 -0.447073 +v 0.863071 1.613604 -0.561074 +v -0.886924 0.947829 -0.079727 +v -0.922473 0.970450 -0.087412 +v -0.921573 0.970175 -0.091517 +v -0.885984 0.947240 -0.083787 +v -0.955865 1.000978 -0.093382 +v -0.955026 1.001084 -0.097530 +v -0.950006 1.002603 -0.100391 +v -0.916983 0.971090 -0.094291 +v -0.881890 0.947598 -0.086454 +v 0.114279 0.936154 -0.054887 +v -0.007598 0.911084 -0.053292 +v -0.007667 0.889480 -0.054968 +v 0.114271 0.925891 -0.056486 +v -0.135007 0.909735 -0.050551 +v -0.135083 0.881363 -0.052277 +v -0.135190 0.876926 -0.056246 +v -0.007763 0.885891 -0.058910 +v 0.114260 0.923641 -0.060354 +v 0.951550 1.130670 -0.029860 +v 0.943871 1.083790 -0.011480 +v 0.943742 1.082356 -0.015421 +v 0.951306 1.129510 -0.033852 +v 0.927799 1.041806 0.004950 +v 0.927781 1.040148 0.001092 +v 0.923326 1.040122 -0.003081 +v 0.938975 1.082675 -0.019565 +v 0.946351 1.130102 -0.037770 +v 0.114210 0.919677 -0.078725 +v -0.008197 0.883355 -0.077551 +v -0.008303 0.885767 -0.081843 +v 0.114194 0.920175 -0.082959 +v -0.135671 0.874987 -0.074973 +v -0.135790 0.878479 -0.079276 +v -0.135952 0.905613 -0.083341 +v -0.008441 0.906166 -0.085965 +v 0.114151 0.929146 -0.087121 +v 0.948034 1.231746 -0.033232 +v 0.946738 1.185962 -0.023194 +v 0.952480 1.184211 -0.025062 +v 0.953708 1.230304 -0.035440 +v 0.942093 1.140789 -0.006772 +v 0.947852 1.138693 -0.008255 +v 0.949138 1.137149 -0.011899 +v 0.953662 1.183045 -0.028843 +v 0.954769 1.229451 -0.039326 +v 0.939251 1.324410 -0.038973 +v 0.945348 1.278995 -0.034394 +v 0.950902 1.277672 -0.036823 +v 0.944630 1.322926 -0.041480 +v 0.951827 1.276859 -0.040732 +v 0.945401 1.321779 -0.045282 +v -0.956712 1.415277 -0.128217 +v -0.969859 1.474311 -0.150893 +v -0.970234 1.471535 -0.152956 +v -0.956665 1.413232 -0.131506 +v -0.984495 1.512007 -0.175233 +v -0.985191 1.508675 -0.175951 +v -0.981329 1.504852 -0.178062 +v -0.966355 1.468242 -0.155370 +v -0.952606 1.410788 -0.134125 +v -0.945097 1.288684 -0.061566 +v -0.943249 1.357963 -0.080578 +v -0.947781 1.357177 -0.083565 +v -0.949985 1.287345 -0.064712 +v -0.948274 1.426381 -0.108593 +v -0.952523 1.426137 -0.111074 +v -0.953663 1.424407 -0.114344 +v -0.948647 1.355967 -0.087506 +v -0.950710 1.286579 -0.068858 +v 0.873486 0.986496 0.026814 +v 0.856290 0.973807 0.031750 +v 0.856597 0.971626 0.028220 +v 0.873659 0.984376 0.023206 +v 0.845155 0.968333 0.032961 +v 0.845845 0.966325 0.029475 +v 0.845788 0.966202 0.026623 +v 0.853681 0.970602 0.024718 +v 0.870173 0.983429 0.019488 +v 0.888870 1.605102 -0.361507 +v 0.893247 1.601941 -0.362724 +v 0.893511 1.570241 -0.294438 +v 0.897980 1.567230 -0.296082 +v 0.898240 1.563584 -0.298141 +v 0.893460 1.598086 -0.364195 +v -0.911358 1.130776 -0.905281 +v -0.898235 1.047271 -0.906222 +v -0.897782 1.048086 -0.902077 +v -0.910734 1.131271 -0.901134 +v -0.882035 0.992336 -0.907169 +v -0.882185 0.994748 -0.903054 +v -0.882953 1.006806 -0.900509 +v -0.894313 1.052492 -0.899215 +v -0.906501 1.135542 -0.898229 +v -0.964055 1.158771 -0.059066 +v -0.954051 1.219741 -0.056494 +v -0.959174 1.218002 -0.059690 +v -0.969302 1.156833 -0.062269 +v -0.959865 1.217590 -0.063902 +v -0.970019 1.156674 -0.066497 +v -0.969808 1.073912 -0.064621 +v -0.969121 1.112042 -0.061916 +v -0.974426 1.110101 -0.065099 +v -0.975108 1.072030 -0.067765 +v -0.975183 1.110080 -0.069324 +v -0.975873 1.072017 -0.071976 +v -0.975905 1.073279 -0.090591 +v -0.975173 1.111342 -0.087878 +v -0.974428 1.111941 -0.092055 +v -0.975171 1.073860 -0.094762 +v -0.969865 1.157249 -0.085019 +v -0.969091 1.157676 -0.089196 +v -0.963891 1.159836 -0.092037 +v -0.969228 1.114338 -0.094908 +v -0.969977 1.076142 -0.097625 +v -0.368638 1.023181 -0.043854 +v -0.448903 1.043253 -0.042515 +v -0.452376 1.037741 -0.044091 +v -0.369864 1.012645 -0.045514 +v -0.516828 1.030792 -0.042300 +v -0.521568 1.025838 -0.043816 +v -0.521835 1.023785 -0.047483 +v -0.452617 1.035845 -0.047847 +v -0.369970 1.010366 -0.049387 +v -0.519762 1.016974 -0.064942 +v -0.591091 0.992285 -0.065016 +v -0.590128 0.991349 -0.069045 +v -0.518608 1.016062 -0.068970 +v -0.667415 0.967155 -0.065878 +v -0.666902 0.966307 -0.069952 +v -0.666139 0.969095 -0.073918 +v -0.586490 0.994369 -0.073072 +v -0.513400 1.019102 -0.073012 +v 0.917720 1.054711 0.026172 +v 0.891000 1.022845 0.038469 +v 0.896058 1.020624 0.037455 +v 0.923210 1.052345 0.025207 +v 0.864104 1.000958 0.047002 +v 0.868712 0.998945 0.045841 +v 0.870042 0.996673 0.042599 +v 0.897432 1.018473 0.034148 +v 0.924611 1.050352 0.021807 +v -0.260969 0.934409 -0.071273 +v -0.261007 0.936812 -0.075551 +v -0.369617 1.006454 -0.067777 +v -0.369360 1.006962 -0.071987 +v -0.368053 1.015935 -0.076005 +v -0.260931 0.957104 -0.079578 +v 0.317997 0.947299 -0.052114 +v 0.224922 0.946740 -0.055022 +v 0.225026 0.941937 -0.056547 +v 0.318219 0.943394 -0.053540 +v 0.225181 0.940125 -0.060298 +v 0.318591 0.941413 -0.057161 +v -0.906655 1.152750 -0.931364 +v -0.894433 1.065528 -0.932162 +v -0.897885 1.065946 -0.929331 +v -0.910872 1.156168 -0.928413 +v -0.883066 1.013694 -0.932325 +v -0.882282 1.001503 -0.930173 +v -0.882103 0.997992 -0.926141 +v -0.898307 1.063013 -0.925200 +v -0.911456 1.152856 -0.924259 +v -0.883066 1.013694 -0.932325 +v -0.870136 1.000133 -0.933014 +v -0.865452 0.976191 -0.930578 +v -0.882282 1.001503 -0.930173 +v -0.835182 0.999506 -0.932735 +v -0.831013 0.976275 -0.930445 +v -0.830409 0.972913 -0.926375 +v -0.864807 0.972594 -0.926497 +v -0.882103 0.997992 -0.926141 +v 0.091983 1.199501 -0.903191 +v 0.224355 1.169946 -0.902972 +v 0.224731 1.172205 -0.898964 +v 0.092592 1.201376 -0.899712 +v 0.339109 1.128167 -0.898388 +v 0.339132 1.130911 -0.894362 +v 0.340213 1.149514 -0.892348 +v 0.227855 1.187697 -0.896600 +v 0.096930 1.214418 -0.897586 +v -0.142343 1.147525 -0.898287 +v -0.027864 1.191420 -0.900360 +v -0.027409 1.193302 -0.898100 +v -0.142182 1.149707 -0.896769 +v -0.024290 1.206486 -0.897072 +v -0.141095 1.164996 -0.896465 +v 0.341256 1.148898 -0.923837 +v 0.411772 1.120742 -0.916611 +v 0.411516 1.100366 -0.912898 +v 0.340073 1.130302 -0.920980 +v 0.468933 1.094800 -0.908688 +v 0.468835 1.073340 -0.904608 +v 0.468696 1.070397 -0.900288 +v 0.411327 1.097571 -0.908670 +v 0.339773 1.127732 -0.917151 +v -0.141142 1.165051 -0.922104 +v -0.024381 1.206547 -0.922813 +v -0.027479 1.193317 -0.920927 +v -0.142218 1.149725 -0.919523 +v 0.096998 1.214387 -0.925221 +v 0.092669 1.201297 -0.923753 +v 0.092040 1.199439 -0.921069 +v -0.027912 1.191426 -0.917825 +v -0.142367 1.147534 -0.915727 +v -0.361806 1.045458 -0.928549 +v -0.260346 1.101579 -0.924988 +v -0.260485 1.083442 -0.922126 +v -0.361817 1.024965 -0.925938 +v -0.260509 1.080851 -0.918012 +v -0.361831 1.022038 -0.921821 +v -0.884359 1.480413 -0.873261 +v -0.888946 1.481886 -0.871452 +v -0.889806 1.480326 -0.868668 +v 0.893503 1.042444 -0.930540 +v 0.895591 1.075387 -0.931084 +v 0.900208 1.074444 -0.928230 +v 0.895790 1.035334 -0.928186 +v 0.894757 1.148445 -0.931066 +v 0.899521 1.147918 -0.928154 +v 0.900186 1.147664 -0.924033 +v 0.900862 1.074124 -0.924094 +v 0.896271 1.033869 -0.924111 +v 0.902953 1.480898 -0.164733 +v 0.911106 1.440025 -0.120941 +v 0.915883 1.437405 -0.123101 +v 0.907606 1.478175 -0.166757 +v 0.920856 1.402396 -0.088091 +v 0.925799 1.400005 -0.090397 +v 0.926258 1.397440 -0.093644 +v 0.916269 1.434432 -0.126103 +v 0.907956 1.474983 -0.169527 +v -0.973254 1.542812 -0.264365 +v -0.944892 1.565718 -0.341648 +v -0.949855 1.564620 -0.341063 +v -0.977952 1.542264 -0.263330 +v -0.951730 1.561173 -0.340786 +v -0.979916 1.539029 -0.262561 +v 0.930681 1.364907 -0.058680 +v 0.935841 1.362978 -0.061125 +v 0.936441 1.361130 -0.064671 +v -0.970019 1.532766 -0.172663 +v -0.979018 1.540871 -0.211310 +v -0.983512 1.540804 -0.210625 +v -0.974359 1.532954 -0.172938 +v -0.985505 1.537763 -0.210103 +v -0.976226 1.530195 -0.173394 +v 0.462870 0.959453 -0.033198 +v 0.391688 0.950533 -0.044715 +v 0.391988 0.946529 -0.045985 +v 0.463228 0.955146 -0.034256 +v 0.392585 0.944367 -0.049493 +v 0.464002 0.952859 -0.037669 +v 0.644071 1.033860 -0.907306 +v 0.749419 1.026382 -0.916583 +v 0.749474 1.006183 -0.913600 +v 0.644094 1.011345 -0.904075 +v 0.835543 1.030050 -0.926341 +v 0.835599 1.012738 -0.923394 +v 0.835677 1.010274 -0.919231 +v 0.749552 1.003329 -0.909432 +v 0.644125 1.008193 -0.899873 +v -0.669622 0.979963 -0.042814 +v -0.748641 0.958827 -0.043868 +v -0.746780 0.954908 -0.045676 +v -0.669825 0.975348 -0.044446 +v -0.810819 0.944753 -0.045176 +v -0.807828 0.941562 -0.047159 +v -0.807041 0.940159 -0.051051 +v -0.746148 0.953252 -0.049498 +v -0.669450 0.973442 -0.048187 +v -0.491600 1.017777 -0.929540 +v -0.429534 1.021369 -0.929707 +v -0.429549 0.999792 -0.927775 +v -0.491615 0.995858 -0.928287 +v -0.429569 0.996709 -0.923754 +v -0.491637 0.992724 -0.924364 +v 0.839581 0.983685 0.052501 +v 0.827960 0.983541 0.050391 +v 0.826330 0.979974 0.048955 +v 0.840534 0.981350 0.051489 +v 0.793821 0.984948 0.040905 +v 0.792350 0.981010 0.039533 +v 0.792919 0.978510 0.036240 +v 0.826889 0.977451 0.045719 +v 0.841430 0.978887 0.048383 +v -0.951038 1.003765 -0.067437 +v -0.966338 1.037610 -0.067568 +v -0.971535 1.035736 -0.070661 +v -0.955905 1.001913 -0.070504 +v -0.972244 1.035594 -0.074858 +v -0.956478 1.001537 -0.074681 +v -0.853992 0.936799 -0.048002 +v -0.863650 0.941262 -0.049410 +v -0.866550 0.939790 -0.052451 +v -0.853742 0.935019 -0.050087 +v -0.884936 0.953444 -0.054077 +v -0.888539 0.951878 -0.057230 +v -0.888698 0.951016 -0.061359 +v -0.866515 0.938840 -0.056536 +v -0.853283 0.933940 -0.054027 +v -0.675521 1.013673 -0.930603 +v -0.577143 1.017083 -0.929779 +v -0.577053 0.994878 -0.928790 +v -0.674716 0.991262 -0.929414 +v -0.577055 0.991697 -0.924904 +v -0.674607 0.988043 -0.925500 +v 0.639858 0.984340 0.000647 +v 0.547586 0.973102 -0.018167 +v 0.547957 0.968431 -0.019004 +v 0.639946 0.979557 -0.000140 +v 0.548814 0.966031 -0.022339 +v 0.640777 0.977082 -0.003431 +v 0.880058 1.034475 -0.930510 +v 0.880359 1.019391 -0.927659 +v 0.835599 1.012738 -0.923394 +v 0.893503 1.042444 -0.930540 +v 0.895790 1.035334 -0.928186 +v 0.896271 1.033869 -0.924111 +v 0.880495 1.017235 -0.923518 +v 0.835677 1.010274 -0.919231 +v 0.468064 1.071017 -0.881345 +v 0.546100 1.036083 -0.877780 +v 0.546041 1.039426 -0.873740 +v 0.467929 1.074220 -0.877373 +v 0.644270 1.008519 -0.880919 +v 0.644295 1.011815 -0.876798 +v 0.644269 1.034432 -0.874135 +v 0.545979 1.062131 -0.871631 +v 0.467854 1.095787 -0.875727 +v 0.644936 0.967984 -0.019563 +v 0.552889 0.957247 -0.038648 +v 0.553787 0.955850 -0.042502 +v 0.645897 0.966508 -0.023367 +v 0.467665 0.944383 -0.054212 +v 0.468468 0.943025 -0.058096 +v 0.469029 0.945226 -0.062446 +v 0.554448 0.958195 -0.046963 +v 0.646894 0.968718 -0.027746 +v -0.674638 0.987951 -0.906544 +v -0.577127 0.991655 -0.905951 +v -0.577157 0.994832 -0.901505 +v -0.674759 0.991265 -0.902128 +v -0.491735 0.992710 -0.905413 +v -0.491755 0.995837 -0.901004 +v -0.491765 1.017741 -0.896356 +v -0.577263 1.017134 -0.896595 +v -0.675569 1.014588 -0.897419 +v -0.851169 0.930230 -0.072339 +v -0.864439 0.935250 -0.074849 +v -0.863571 0.934571 -0.078880 +v -0.850727 0.929654 -0.076367 +v -0.886924 0.947829 -0.079727 +v -0.885984 0.947240 -0.083787 +v -0.860146 0.934695 -0.081437 +v -0.850535 0.930322 -0.078884 +v -0.955865 1.000978 -0.093382 +v -0.972073 1.036207 -0.093557 +v -0.971300 1.036616 -0.097723 +v -0.955026 1.001084 -0.097530 +v -0.966115 1.038598 -0.100602 +v -0.950006 1.002603 -0.100391 +v 0.830739 0.967174 0.030172 +v 0.831841 0.965245 0.026652 +v 0.796888 0.968645 0.020480 +v 0.798037 0.966839 0.016880 +v 0.800625 0.967759 0.013350 +v 0.834534 0.965793 0.023408 +v -0.830361 0.972692 -0.907412 +v -0.764181 0.980418 -0.907054 +v -0.764527 0.983968 -0.902717 +v -0.830945 0.976364 -0.903155 +v -0.766965 1.009034 -0.898564 +v -0.835098 1.002367 -0.899550 +v -0.744303 0.947731 -0.067444 +v -0.744122 0.946960 -0.071558 +v -0.805233 0.935392 -0.069195 +v -0.805219 0.934693 -0.073339 +v -0.807642 0.936435 -0.077085 +v -0.745424 0.949238 -0.075412 +v 0.749905 1.003491 -0.890475 +v 0.749975 1.006418 -0.886318 +v 0.836035 1.010325 -0.900272 +v 0.836109 1.012812 -0.896109 +v 0.836129 1.030153 -0.893161 +v 0.749981 1.026682 -0.883405 +v 0.796888 0.968645 0.020480 +v 0.731429 0.970619 0.002114 +v 0.732487 0.968988 -0.001595 +v 0.798037 0.966839 0.016880 +v 0.734261 0.970596 -0.005578 +v 0.800625 0.967759 0.013350 +v -0.984495 1.512007 -0.175233 +v -0.994100 1.518090 -0.207612 +v -0.994890 1.514593 -0.207435 +v -0.987580 1.516186 -0.258954 +v -0.988264 1.513486 -0.258521 +v -0.983999 1.510237 -0.259838 +v -0.990964 1.510526 -0.209167 +v 0.896346 1.547509 -0.307208 +v 0.900601 1.505114 -0.241397 +v 0.899529 1.501829 -0.243833 +v 0.895243 1.543994 -0.309210 +v 0.906395 1.461101 -0.181805 +v 0.905342 1.458040 -0.184556 +v 0.900181 1.456242 -0.186448 +v 0.894424 1.499866 -0.245445 +v 0.890170 1.541895 -0.310462 +v 0.880512 1.598505 -0.450007 +v 0.891361 1.580803 -0.370701 +v 0.890229 1.577085 -0.372114 +v 0.879378 1.594674 -0.450620 +v 0.885201 1.574890 -0.372919 +v 0.874487 1.592448 -0.450880 +v 0.914811 1.421616 -0.139415 +v 0.913764 1.418790 -0.142409 +v 0.925047 1.386464 -0.108346 +v 0.924036 1.384061 -0.111586 +v 0.918685 1.382808 -0.113844 +v 0.908509 1.417195 -0.144506 +v -0.879510 1.586195 -0.710808 +v -0.871766 1.589556 -0.776545 +v -0.871797 1.586202 -0.776067 +v -0.879639 1.583397 -0.711226 +v -0.875287 1.556761 -0.813828 +v -0.875132 1.553998 -0.812141 +v -0.871085 1.552375 -0.810244 +v -0.867637 1.583490 -0.774594 +v -0.875018 1.580769 -0.710257 +v 0.882278 1.356012 -0.890933 +v 0.858258 1.428805 -0.860212 +v 0.857492 1.426757 -0.856796 +v 0.881552 1.354751 -0.887144 +v 0.836666 1.481661 -0.813813 +v 0.835838 1.478889 -0.810911 +v 0.831704 1.477156 -0.808856 +v 0.853188 1.425390 -0.854436 +v 0.877034 1.353926 -0.884571 +v -0.835182 0.999506 -0.932735 +v -0.766991 1.006340 -0.931748 +v -0.764545 0.983822 -0.930005 +v -0.831013 0.976275 -0.930445 +v -0.764194 0.980574 -0.926013 +v -0.830409 0.972913 -0.926375 +v -0.429663 0.996708 -0.904845 +v -0.429683 0.999788 -0.900617 +v -0.361897 1.022037 -0.903202 +v -0.361910 1.024961 -0.899649 +v -0.361916 1.045437 -0.897021 +v -0.429692 1.021352 -0.896730 +v -0.260532 1.080847 -0.900038 +v -0.260518 1.083433 -0.897768 +v -0.260383 1.101544 -0.896678 +v 0.410550 1.098157 -0.889749 +v 0.410410 1.101192 -0.885775 +v 0.410502 1.121630 -0.884113 +v 0.228391 1.187409 -0.926367 +v 0.225231 1.171887 -0.924449 +v 0.224710 1.169715 -0.921347 +v 0.546449 1.061286 -0.904765 +v 0.546410 1.038700 -0.901004 +v 0.546354 1.035574 -0.896727 +v 0.836035 1.010325 -0.900272 +v 0.880706 1.017241 -0.904554 +v 0.880664 1.019399 -0.900414 +v 0.836109 1.012812 -0.896109 +v 0.896317 1.033864 -0.905142 +v 0.895868 1.035326 -0.901070 +v 0.893651 1.042436 -0.898726 +v 0.880419 1.034489 -0.897563 +v 0.836129 1.030153 -0.893161 +v -0.882035 0.992336 -0.907169 +v -0.864743 0.971652 -0.907531 +v -0.865361 0.975056 -0.903330 +v -0.882185 0.994748 -0.903054 +v -0.830361 0.972692 -0.907412 +v -0.830945 0.976364 -0.903155 +v -0.870026 0.999118 -0.900064 +v -0.882953 1.006806 -0.900509 +v 0.395392 0.936300 -0.066378 +v 0.396005 0.935008 -0.070309 +v 0.320321 0.934191 -0.074506 +v 0.320695 0.933080 -0.078518 +v 0.320931 0.935257 -0.082679 +v 0.396422 0.937090 -0.074539 +v -0.590233 1.006208 -0.042361 +v -0.593328 1.001259 -0.043892 +v -0.593327 0.999186 -0.047565 +v 0.927799 1.041806 0.004950 +v 0.900781 1.009037 0.017860 +v 0.900865 1.007131 0.014129 +v 0.927781 1.040148 0.001092 +v 0.873486 0.986496 0.026814 +v 0.873659 0.984376 0.023206 +v 0.870173 0.983429 0.019488 +v 0.896894 1.006625 0.010154 +v 0.923326 1.040122 -0.003081 +v 0.864104 1.000958 0.047002 +v 0.847434 0.988631 0.051606 +v 0.851466 0.986707 0.050421 +v 0.868712 0.998945 0.045841 +v 0.852713 0.984354 0.047241 +v 0.870042 0.996673 0.042599 +v -0.451322 1.030232 -0.065721 +v -0.450527 1.029658 -0.069828 +v -0.446755 1.033400 -0.073858 +v -0.884936 0.953444 -0.054077 +v -0.919083 0.974864 -0.061619 +v -0.923330 0.973129 -0.064717 +v -0.888539 0.951878 -0.057230 +v -0.951038 1.003765 -0.067437 +v -0.955905 1.001913 -0.070504 +v -0.956478 1.001537 -0.074681 +v -0.923692 0.972475 -0.068868 +v -0.888698 0.951016 -0.061359 +v 0.956114 1.225969 -0.058677 +v 0.955568 1.178231 -0.047539 +v 0.955200 1.177438 -0.051564 +v 0.955618 1.225451 -0.062705 +v 0.950099 1.178292 -0.055143 +v 0.950391 1.226356 -0.065912 +v -0.950823 1.283807 -0.086950 +v -0.949734 1.350605 -0.104473 +v -0.949312 1.349342 -0.108377 +v -0.950148 1.283269 -0.091043 +v -0.944833 1.348189 -0.111099 +v -0.945231 1.283531 -0.093814 +v -0.958155 1.490662 -0.139366 +v -0.962371 1.490777 -0.140838 +v -0.963902 1.488488 -0.142766 +v -0.805233 0.935392 -0.069195 +v -0.836926 0.930013 -0.070705 +v -0.836881 0.929401 -0.074841 +v -0.805219 0.934693 -0.073339 +v -0.839521 0.930809 -0.078385 +v -0.842902 0.938038 -0.046474 +v -0.839698 0.935337 -0.048512 +v -0.807828 0.941562 -0.047159 +v -0.838885 0.934125 -0.052439 +v -0.807041 0.940159 -0.051051 +v 0.935776 1.353213 -0.081539 +v 0.934866 1.351541 -0.085081 +v 0.945439 1.316854 -0.064111 +v 0.944669 1.315914 -0.067928 +v 0.939268 1.315874 -0.070536 +v 0.929461 1.350842 -0.087495 +v 0.897440 1.526293 -0.226102 +v 0.901995 1.523441 -0.227985 +v 0.902303 1.520028 -0.230458 +v -0.959663 1.216789 -0.082353 +v -0.958888 1.216830 -0.086510 +v -0.953747 1.218255 -0.089321 +v 0.952549 1.273453 -0.060304 +v 0.951920 1.272910 -0.064276 +v 0.946585 1.273473 -0.067150 +v -0.260449 0.962167 -0.046938 +v -0.260648 0.940504 -0.048657 +v -0.260725 0.936914 -0.052604 +v 0.727289 0.986997 0.022401 +v 0.726628 0.982571 0.021360 +v 0.792350 0.981010 0.039533 +v 0.727338 0.980078 0.018072 +v 0.792919 0.978510 0.036240 +v 0.225895 0.934409 -0.078190 +v 0.226047 0.933755 -0.082316 +v 0.226129 0.937064 -0.086473 +v 0.933935 1.095586 0.010555 +v 0.939642 1.093264 0.009411 +v 0.917720 1.054711 0.026172 +v 0.923210 1.052345 0.025207 +v 0.924611 1.050352 0.021807 +v 0.941010 1.091454 0.005898 +v -0.987580 1.516186 -0.258954 +v -0.958279 1.530484 -0.339552 +v -0.958735 1.529694 -0.339486 +v -0.988264 1.513486 -0.258521 +v -0.921867 1.553537 -0.452621 +v -0.922113 1.553874 -0.453101 +v -0.916646 1.554269 -0.453466 +v -0.953763 1.528663 -0.340375 +v -0.983999 1.510237 -0.259838 +v 0.840945 1.572249 -0.670677 +v 0.860839 1.595636 -0.559350 +v 0.859747 1.591835 -0.558952 +v 0.839929 1.568626 -0.669257 +v 0.855134 1.589661 -0.558571 +v 0.835614 1.566553 -0.668222 +v -0.895442 1.572702 -0.590715 +v -0.895607 1.571798 -0.591430 +v -0.879510 1.586195 -0.710808 +v -0.879639 1.583397 -0.711226 +v -0.875018 1.580769 -0.710257 +v -0.890379 1.570977 -0.591124 +v 0.831095 1.531216 -0.753991 +v 0.830177 1.527923 -0.751739 +v 0.826040 1.525978 -0.750131 +v 0.896317 1.033864 -0.905142 +v 0.900829 1.073992 -0.905125 +v 0.900177 1.074256 -0.900992 +v 0.895868 1.035326 -0.901070 +v 0.900101 1.146715 -0.905095 +v 0.899415 1.146568 -0.900978 +v 0.894721 1.146785 -0.898103 +v 0.895664 1.075166 -0.898160 +v 0.893651 1.042436 -0.898726 +v -0.875287 1.556761 -0.813828 +v -0.891359 1.467937 -0.854048 +v -0.890947 1.466232 -0.851191 +v -0.875132 1.553998 -0.812141 +v -0.908730 1.349378 -0.888281 +v -0.908113 1.348757 -0.884570 +v -0.903535 1.350025 -0.881892 +v -0.886642 1.465889 -0.848862 +v -0.871085 1.552375 -0.810244 +v 0.900101 1.146715 -0.905095 +v 0.895469 1.251747 -0.903279 +v 0.894768 1.251162 -0.899268 +v 0.899415 1.146568 -0.900978 +v 0.890122 1.250989 -0.896518 +v 0.896317 1.033864 -0.905142 +v 0.880706 1.017241 -0.904554 +v 0.880655 1.017239 -0.909201 +v 0.896306 1.033864 -0.909791 +v 0.835948 1.010313 -0.904918 +v 0.835856 1.010299 -0.909751 +v 0.880601 1.017238 -0.914036 +v 0.896294 1.033866 -0.914627 +v 0.880547 1.017236 -0.918870 +v 0.896283 1.033868 -0.919463 +v 0.835765 1.010286 -0.914585 +v 0.835677 1.010274 -0.919231 +v 0.880495 1.017235 -0.923518 +v 0.896271 1.033869 -0.924111 +v 0.731429 0.970619 0.002114 +v 0.730427 0.972936 0.006022 +v 0.643917 0.970212 -0.015612 +v 0.796888 0.968645 0.020480 +v 0.795916 0.971060 0.024338 +v 0.794904 0.973578 0.028360 +v 0.729383 0.975348 0.010093 +v 0.642856 0.972533 -0.011497 +v 0.728340 0.977762 0.014164 +v 0.641796 0.974853 -0.007382 +v 0.793891 0.976095 0.032382 +v 0.792919 0.978510 0.036240 +v 0.727338 0.980078 0.018072 +v 0.640777 0.977082 -0.003431 +v -0.674638 0.987951 -0.906544 +v -0.764184 0.980457 -0.911700 +v -0.674630 0.987974 -0.911190 +v -0.830361 0.972692 -0.907412 +v -0.830373 0.972746 -0.912060 +v -0.830385 0.972802 -0.916894 +v -0.764187 0.980496 -0.916534 +v -0.674623 0.987997 -0.916022 +v -0.764191 0.980536 -0.921366 +v -0.674614 0.988020 -0.920854 +v -0.830397 0.972859 -0.921728 +v -0.830409 0.972913 -0.926375 +v -0.764194 0.980574 -0.926013 +v -0.674607 0.988043 -0.925500 +v -0.851169 0.930230 -0.072339 +v -0.836926 0.930013 -0.070705 +v -0.837407 0.931023 -0.066218 +v -0.851688 0.931141 -0.067838 +v -0.805233 0.935392 -0.069195 +v -0.805677 0.936562 -0.064740 +v -0.806137 0.937775 -0.060123 +v -0.837905 0.932069 -0.061572 +v -0.852226 0.932085 -0.063183 +v -0.838403 0.933115 -0.056926 +v -0.852763 0.933028 -0.058527 +v -0.806597 0.938988 -0.055506 +v -0.807041 0.940159 -0.051051 +v -0.838885 0.934125 -0.052439 +v -0.853283 0.933940 -0.054027 +v -0.955865 1.000978 -0.093382 +v -0.922473 0.970450 -0.087412 +v -0.922773 0.970948 -0.082854 +v -0.956016 1.001115 -0.088785 +v -0.886924 0.947829 -0.079727 +v -0.887361 0.948613 -0.075210 +v -0.887811 0.949422 -0.070543 +v -0.923083 0.971462 -0.078140 +v -0.956172 1.001258 -0.084032 +v -0.923392 0.971977 -0.073427 +v -0.956327 1.001400 -0.079278 +v -0.888262 0.950232 -0.065876 +v -0.923692 0.972475 -0.068868 +v 0.845155 0.968333 0.032961 +v 0.856290 0.973807 0.031750 +v 0.855415 0.976386 0.035538 +v 0.844244 0.970914 0.036733 +v 0.873486 0.986496 0.026814 +v 0.872644 0.988983 0.030671 +v 0.871764 0.991585 0.034707 +v 0.854501 0.979081 0.039495 +v 0.843293 0.973610 0.040672 +v 0.853588 0.981776 0.043453 +v 0.842341 0.976305 0.044610 +v 0.870883 0.994186 0.038742 +v 0.852713 0.984354 0.047241 +v -0.361897 1.022037 -0.903202 +v -0.429663 0.996708 -0.904845 +v -0.429640 0.996708 -0.909455 +v -0.361881 1.022037 -0.907557 +v -0.491735 0.992710 -0.905413 +v -0.491711 0.992714 -0.910058 +v -0.491685 0.992717 -0.914889 +v -0.429616 0.996709 -0.914279 +v -0.361864 1.022037 -0.912346 +v -0.429593 0.996709 -0.919109 +v -0.361847 1.022037 -0.917176 +v -0.491661 0.992721 -0.919719 +v -0.491637 0.992724 -0.924364 +v -0.429569 0.996709 -0.923754 +v -0.591639 0.993977 -0.060736 +v -0.667914 0.968697 -0.061538 +v -0.520270 1.018643 -0.060662 +v -0.520798 1.020379 -0.056212 +v -0.592209 0.995735 -0.056291 +v -0.668432 0.970298 -0.057032 +v -0.592779 0.997494 -0.051845 +v -0.668951 0.971900 -0.052527 +v -0.521327 1.022115 -0.051763 +v -0.521835 1.023785 -0.047483 +v -0.593327 0.999186 -0.047565 +v -0.669450 0.973442 -0.048187 +v 0.644270 1.008519 -0.880919 +v 0.546100 1.036083 -0.877780 +v 0.546162 1.035958 -0.882423 +v 0.644235 1.008439 -0.885564 +v 0.468064 1.071017 -0.881345 +v 0.468219 1.070865 -0.885987 +v 0.468380 1.070707 -0.890817 +v 0.546227 1.035828 -0.887253 +v 0.644198 1.008356 -0.890396 +v 0.546292 1.035699 -0.892084 +v 0.644161 1.008273 -0.895228 +v 0.468541 1.070549 -0.895646 +v 0.468696 1.070397 -0.900288 +v 0.644125 1.008193 -0.899873 +v 0.320321 0.934191 -0.074506 +v 0.395392 0.936300 -0.066378 +v 0.394704 0.938277 -0.062242 +v 0.319897 0.935960 -0.070257 +v 0.467665 0.944383 -0.054212 +v 0.466767 0.946460 -0.050159 +v 0.465833 0.948621 -0.045941 +v 0.393989 0.940333 -0.057935 +v 0.319456 0.937802 -0.065833 +v 0.393273 0.942391 -0.053629 +v 0.319015 0.939644 -0.061410 +v 0.464900 0.950782 -0.041723 +v 0.464002 0.952859 -0.037669 +v 0.392585 0.944367 -0.049493 +v 0.318591 0.941413 -0.057161 +v -0.984495 1.512007 -0.175233 +v -0.969859 1.474311 -0.150893 +v -0.968471 1.477642 -0.148868 +v -0.982581 1.516230 -0.174767 +v -0.956712 1.415277 -0.128217 +v -0.955984 1.417483 -0.124766 +v -0.955187 1.419842 -0.121280 +v -0.966881 1.481400 -0.146830 +v -0.980361 1.521101 -0.174314 +v -0.965290 1.485157 -0.144791 +v -0.978141 1.525972 -0.173861 +v -0.954391 1.422201 -0.117795 +v -0.953663 1.424407 -0.114344 +v -0.963902 1.488488 -0.142766 +v -0.976226 1.530195 -0.173394 +v 0.945439 1.316854 -0.064111 +v 0.935940 1.355156 -0.077444 +v 0.945431 1.318051 -0.059577 +v 0.925047 1.386464 -0.108346 +v 0.925347 1.389170 -0.104738 +v 0.925653 1.391952 -0.100995 +v 0.936108 1.357172 -0.073105 +v 0.945420 1.319317 -0.054697 +v 0.936276 1.359187 -0.068766 +v 0.945408 1.320583 -0.049817 +v 0.925959 1.394733 -0.097251 +v 0.926258 1.397440 -0.093644 +v 0.945401 1.321779 -0.045282 +v -0.921867 1.553537 -0.452621 +v -0.958279 1.530484 -0.339552 +v -0.956711 1.538356 -0.339839 +v -0.920519 1.562819 -0.452081 +v -0.985765 1.521792 -0.259812 +v -0.983748 1.528682 -0.260757 +v -0.955005 1.548918 -0.340169 +v -0.919073 1.575643 -0.451515 +v -0.919073 1.575643 -0.451515 +v -0.955005 1.548918 -0.340169 +v -0.953298 1.556390 -0.340499 +v -0.917625 1.584167 -0.450949 +v -0.983748 1.528682 -0.260757 +v -0.981730 1.534497 -0.261703 +v -0.979916 1.539029 -0.262561 +v -0.951730 1.561173 -0.340786 +v -0.916278 1.589150 -0.450409 +v 0.906395 1.461101 -0.181805 +v 0.900601 1.505114 -0.241397 +v 0.901020 1.508787 -0.238703 +v 0.906780 1.464521 -0.178779 +v 0.896346 1.547509 -0.307208 +v 0.896812 1.551461 -0.304976 +v 0.897293 1.555547 -0.302674 +v 0.901452 1.512571 -0.235928 +v 0.907175 1.468042 -0.175666 +v 0.901884 1.516356 -0.233153 +v 0.907571 1.471562 -0.172552 +v 0.897774 1.559632 -0.300373 +v 0.898240 1.563584 -0.298141 +v 0.902303 1.520028 -0.230458 +v 0.900101 1.146715 -0.905095 +v 0.900829 1.073992 -0.905125 +v 0.900837 1.074024 -0.909772 +v 0.900122 1.146945 -0.909727 +v 0.896317 1.033864 -0.905142 +v 0.896306 1.033864 -0.909791 +v 0.896294 1.033866 -0.914627 +v 0.900846 1.074059 -0.914610 +v 0.900143 1.147190 -0.914564 +v 0.900854 1.074092 -0.919447 +v 0.900165 1.147434 -0.919401 +v 0.896283 1.033868 -0.919463 +v 0.896271 1.033869 -0.924111 +v 0.900862 1.074124 -0.924094 +v 0.900186 1.147664 -0.924033 +v -0.911358 1.130776 -0.905281 +v -0.915706 1.233468 -0.902836 +v -0.915728 1.234270 -0.907432 +v -0.911382 1.131456 -0.909928 +v -0.908730 1.349378 -0.888281 +v -0.908649 1.350727 -0.892557 +v -0.908545 1.353068 -0.897095 +v -0.915749 1.237425 -0.912238 +v -0.911407 1.135368 -0.914770 +v -0.915770 1.244057 -0.917043 +v -0.911432 1.144115 -0.919612 +v -0.908441 1.356619 -0.901633 +v -0.908360 1.359983 -0.905909 +v -0.915792 1.250653 -0.921639 +v -0.911456 1.152856 -0.924259 +v -0.577127 0.991655 -0.905951 +v -0.577109 0.991665 -0.910596 +v -0.577091 0.991676 -0.915427 +v -0.577072 0.991687 -0.920258 +v -0.577055 0.991697 -0.924904 +v -0.142343 1.147525 -0.898287 +v -0.260532 1.080847 -0.900038 +v -0.260527 1.080848 -0.903851 +v -0.142349 1.147527 -0.901774 +v -0.260521 1.080849 -0.908561 +v -0.142355 1.147529 -0.906438 +v -0.260515 1.080850 -0.913387 +v -0.142361 1.147532 -0.911244 +v -0.260509 1.080851 -0.918012 +v -0.142367 1.147534 -0.915727 +v 0.091983 1.199501 -0.903191 +v -0.027876 1.191422 -0.904173 +v 0.091997 1.199486 -0.907547 +v -0.027888 1.191423 -0.908883 +v 0.092011 1.199470 -0.912335 +v -0.027900 1.191425 -0.913646 +v 0.092026 1.199454 -0.917073 +v -0.027912 1.191426 -0.917825 +v 0.092040 1.199439 -0.921069 +v 0.339109 1.128167 -0.898388 +v 0.224355 1.169946 -0.902972 +v 0.224442 1.169890 -0.907579 +v 0.339272 1.128060 -0.903031 +v 0.224532 1.169831 -0.912405 +v 0.339441 1.127949 -0.907862 +v 0.224622 1.169772 -0.917169 +v 0.339610 1.127838 -0.912670 +v 0.224710 1.169715 -0.921347 +v 0.339773 1.127732 -0.917151 +v 0.410550 1.098157 -0.889749 +v 0.410740 1.098013 -0.894391 +v 0.410938 1.097864 -0.899221 +v 0.411136 1.097715 -0.904048 +v 0.411327 1.097571 -0.908670 +v 0.749905 1.003491 -0.890475 +v 0.749818 1.003452 -0.895121 +v 0.749728 1.003410 -0.899954 +v 0.749638 1.003369 -0.904787 +v 0.749552 1.003329 -0.909432 +v -0.864743 0.971652 -0.907531 +v -0.864759 0.971735 -0.912179 +v -0.882035 0.992336 -0.907169 +v -0.882052 0.992539 -0.911817 +v -0.882069 0.993552 -0.916655 +v -0.864775 0.971922 -0.917014 +v -0.864791 0.972259 -0.921850 +v -0.882087 0.995773 -0.921492 +v -0.864807 0.972594 -0.926497 +v -0.882035 0.992336 -0.907169 +v -0.898235 1.047271 -0.906222 +v -0.898253 1.047729 -0.910871 +v -0.882052 0.992539 -0.911817 +v -0.898272 1.050508 -0.915711 +v -0.882069 0.993552 -0.916655 +v -0.898290 1.056762 -0.920551 +v -0.882087 0.995773 -0.921492 +v -0.898307 1.063013 -0.925200 +v 0.114210 0.919677 -0.078725 +v 0.225895 0.934409 -0.078190 +v 0.225721 0.935809 -0.073805 +v 0.114223 0.920649 -0.074219 +v 0.225538 0.937267 -0.069244 +v 0.114235 0.921659 -0.069540 +v 0.225356 0.938724 -0.064683 +v 0.114248 0.922670 -0.064860 +v 0.114260 0.923641 -0.060354 +v -0.744303 0.947731 -0.067444 +v -0.744755 0.949085 -0.063040 +v -0.745225 0.950491 -0.058471 +v -0.745695 0.951897 -0.053902 +v -0.746148 0.953252 -0.049498 +v 0.943871 1.083790 -0.011480 +v 0.943173 1.085658 -0.007245 +v 0.927022 1.043891 0.009062 +v 0.951550 1.130670 -0.029860 +v 0.950963 1.132248 -0.025491 +v 0.950344 1.133909 -0.020880 +v 0.942440 1.087622 -0.002791 +v 0.926205 1.046079 0.013379 +v 0.941707 1.089585 0.001662 +v 0.925389 1.048267 0.017695 +v 0.949725 1.135571 -0.016268 +v 0.949138 1.137149 -0.011899 +v 0.924611 1.050352 0.021807 +v 0.830739 0.967174 0.030172 +v 0.829797 0.969688 0.033976 +v 0.828814 0.972312 0.037945 +v 0.827831 0.974936 0.041914 +v -0.369617 1.006454 -0.067777 +v -0.260909 0.935023 -0.066693 +v -0.369703 1.007413 -0.063269 +v -0.135671 0.874987 -0.074973 +v -0.135552 0.875463 -0.070376 +v -0.135430 0.875956 -0.065609 +v -0.260847 0.935662 -0.061939 +v -0.369793 1.008410 -0.058583 +v -0.260785 0.936300 -0.057185 +v -0.369883 1.009408 -0.053896 +v -0.135308 0.876450 -0.060843 +v -0.135190 0.876926 -0.056246 +v -0.260725 0.936914 -0.052604 +v -0.369970 1.010366 -0.049387 +v -0.975905 1.073279 -0.090591 +v -0.972073 1.036207 -0.093557 +v -0.972115 1.036056 -0.088955 +v -0.975897 1.072968 -0.086004 +v -0.955865 1.000978 -0.093382 +v -0.956016 1.001115 -0.088785 +v -0.956172 1.001258 -0.084032 +v -0.972158 1.035901 -0.084207 +v -0.975889 1.072648 -0.081284 +v -0.972201 1.035745 -0.079459 +v -0.975881 1.072328 -0.076564 +v -0.956327 1.001400 -0.079278 +v -0.956478 1.001537 -0.074681 +v -0.972244 1.035594 -0.074858 +v -0.975873 1.072017 -0.071976 +v -0.969865 1.157249 -0.085019 +v -0.975173 1.111342 -0.087878 +v -0.975175 1.111031 -0.083299 +v -0.969904 1.157107 -0.080446 +v -0.975178 1.110711 -0.078601 +v -0.969943 1.156962 -0.075758 +v -0.975180 1.110391 -0.073902 +v -0.969982 1.156816 -0.071070 +v -0.975183 1.110080 -0.069324 +v -0.970019 1.156674 -0.066497 +v -0.959663 1.216789 -0.082353 +v -0.959713 1.216987 -0.077798 +v -0.950794 1.284494 -0.082480 +v -0.959764 1.217190 -0.073128 +v -0.950767 1.285193 -0.077904 +v -0.959816 1.217392 -0.068457 +v -0.950739 1.285892 -0.073329 +v -0.959865 1.217590 -0.063902 +v -0.950710 1.286579 -0.068858 +v -0.994100 1.518090 -0.207612 +v -0.992094 1.522713 -0.208203 +v -0.984495 1.512007 -0.175233 +v -0.982581 1.516230 -0.174767 +v -0.980361 1.521101 -0.174314 +v -0.989802 1.528061 -0.208858 +v -0.989802 1.528061 -0.208858 +v -0.987510 1.533274 -0.209512 +v 0.891361 1.580803 -0.370701 +v 0.891875 1.585036 -0.369103 +v 0.880512 1.598505 -0.450007 +v 0.881058 1.602917 -0.449288 +v 0.881630 1.607539 -0.448540 +v 0.892410 1.589444 -0.367448 +v 0.892946 1.593853 -0.365793 +v 0.882203 1.612160 -0.447791 +v 0.882749 1.616573 -0.447073 +v 0.893460 1.598086 -0.364195 +v -0.864439 0.935250 -0.074849 +v -0.864949 0.936133 -0.070345 +v -0.865477 0.937045 -0.065692 +v -0.866004 0.937958 -0.061039 +v -0.866515 0.938840 -0.056536 +v -0.949734 1.350605 -0.104473 +v -0.949466 1.351931 -0.100267 +v -0.949190 1.353286 -0.095989 +v -0.948914 1.354641 -0.091712 +v -0.948647 1.355967 -0.087506 +v 0.914811 1.421616 -0.139415 +v 0.915171 1.424777 -0.136134 +v 0.915540 1.428024 -0.132759 +v 0.915910 1.431271 -0.129385 +v 0.916269 1.434432 -0.126103 +v 0.952549 1.273453 -0.060304 +v 0.952375 1.274274 -0.055595 +v 0.955789 1.226810 -0.054007 +v 0.952188 1.275156 -0.050518 +v 0.955441 1.227710 -0.049001 +v 0.952001 1.276038 -0.045440 +v 0.955095 1.228609 -0.043995 +v 0.951827 1.276859 -0.040732 +v 0.954769 1.229451 -0.039326 +v 0.955568 1.178231 -0.047539 +v 0.955105 1.179401 -0.043008 +v 0.954615 1.180638 -0.038191 +v 0.954125 1.181875 -0.033374 +v -0.451322 1.030232 -0.065721 +v -0.451639 1.031608 -0.061340 +v -0.451970 1.033039 -0.056784 +v -0.452299 1.034469 -0.052228 +v -0.452617 1.035845 -0.047847 +v 0.551890 0.959399 -0.034652 +v 0.550851 0.961640 -0.030494 +v 0.549812 0.963879 -0.026335 +v -0.008197 0.883355 -0.077551 +v -0.008090 0.883978 -0.072976 +v -0.007980 0.884623 -0.068231 +v -0.007870 0.885269 -0.063486 +v 0.900781 1.009037 0.017860 +v 0.899963 1.011341 0.021836 +v 0.927799 1.041806 0.004950 +v 0.927022 1.043891 0.009062 +v 0.926205 1.046079 0.013379 +v 0.899106 1.013755 0.026004 +v 0.898249 1.016169 0.030171 +v 0.925389 1.048267 0.017695 +v 0.897432 1.018473 0.034148 +v 0.860839 1.595636 -0.559350 +v 0.861384 1.600024 -0.559773 +v 0.840945 1.572249 -0.670677 +v 0.841443 1.576401 -0.672248 +v 0.841964 1.580735 -0.673878 +v 0.861955 1.604620 -0.560212 +v 0.862526 1.609217 -0.560651 +v 0.842484 1.585068 -0.675507 +v 0.863071 1.613604 -0.561074 +v -0.895442 1.572702 -0.590715 +v -0.894261 1.580635 -0.589753 +v -0.878466 1.591891 -0.710197 +v -0.893000 1.591184 -0.588741 +v -0.877339 1.598782 -0.709612 +v -0.877339 1.598782 -0.709612 +v -0.893000 1.591184 -0.588741 +v -0.891739 1.598644 -0.587729 +v -0.876214 1.604599 -0.709027 +v -0.890557 1.603487 -0.586767 +v -0.875169 1.609220 -0.708417 +v 0.831095 1.531216 -0.753991 +v 0.831501 1.534940 -0.756471 +v 0.836666 1.481661 -0.813813 +v 0.836957 1.484755 -0.817025 +v 0.837258 1.487946 -0.820349 +v 0.831922 1.538799 -0.759032 +v 0.832343 1.542659 -0.761592 +v 0.837559 1.491138 -0.823674 +v 0.837850 1.494231 -0.826886 +v 0.832749 1.546382 -0.764072 +v -0.875287 1.556761 -0.813828 +v -0.871766 1.589556 -0.776545 +v -0.870876 1.594219 -0.777179 +v -0.874622 1.560787 -0.816035 +v -0.869880 1.599592 -0.778029 +v -0.873843 1.565529 -0.818610 +v -0.873843 1.565529 -0.818610 +v -0.869880 1.599592 -0.778029 +v -0.868883 1.604832 -0.778879 +v -0.873064 1.570271 -0.821186 +v -0.867993 1.609360 -0.779514 +v -0.872398 1.574297 -0.823392 +v 0.858258 1.428805 -0.860212 +v 0.858443 1.431089 -0.864074 +v 0.882278 1.356012 -0.890933 +v 0.882380 1.357450 -0.895276 +v 0.882485 1.358957 -0.899853 +v 0.858634 1.433454 -0.868114 +v 0.858825 1.435820 -0.872155 +v 0.882591 1.360464 -0.904430 +v 0.882692 1.361902 -0.908773 +v 0.859010 1.438104 -0.876017 +v -0.891359 1.467937 -0.854048 +v -0.891008 1.470633 -0.857526 +v -0.875287 1.556761 -0.813828 +v -0.890582 1.473930 -0.861358 +v -0.890156 1.477377 -0.865190 +v -0.889806 1.480326 -0.868668 +v 0.895469 1.251747 -0.903279 +v 0.895517 1.252463 -0.907847 +v 0.895568 1.253222 -0.912649 +v 0.895619 1.253980 -0.917451 +v 0.895667 1.254696 -0.922020 +v -0.915706 1.233468 -0.902836 +v -0.915039 1.233624 -0.898760 +v -0.910734 1.131271 -0.901134 +v -0.910520 1.236894 -0.895912 +vt 0.779334 0.765797 +vt 0.779559 0.768928 +vt 0.787462 0.769680 +vt 0.787154 0.766416 +vt 0.779662 0.770348 +vt 0.787606 0.771162 +vt 0.795555 0.771373 +vt 0.795415 0.769861 +vt 0.795119 0.766530 +vt 0.779430 0.642541 +vt 0.778998 0.639397 +vt 0.769621 0.640954 +vt 0.770579 0.643528 +vt 0.778116 0.637946 +vt 0.768979 0.639644 +vt 0.759091 0.641905 +vt 0.759324 0.642878 +vt 0.759703 0.643534 +vt 0.743656 0.545054 +vt 0.743654 0.546090 +vt 0.746588 0.546339 +vt 0.746234 0.544999 +vt 0.743653 0.547126 +vt 0.746625 0.547442 +vt 0.751955 0.548013 +vt 0.751696 0.546665 +vt 0.748255 0.543041 +vt 0.760942 0.547694 +vt 0.760657 0.544598 +vt 0.760994 0.549089 +vt 0.771075 0.550906 +vt 0.771025 0.549504 +vt 0.770863 0.546352 +vt 0.445546 0.283222 +vt 0.444976 0.280419 +vt 0.443864 0.281879 +vt 0.444289 0.284423 +vt 0.444723 0.279160 +vt 0.443677 0.280737 +vt 0.443043 0.281692 +vt 0.443190 0.282764 +vt 0.443527 0.285150 +vt 0.442442 0.379328 +vt 0.442489 0.373994 +vt 0.439487 0.373753 +vt 0.439724 0.379072 +vt 0.442727 0.368484 +vt 0.439652 0.368279 +vt 0.438584 0.368206 +vt 0.438435 0.373656 +vt 0.438660 0.378954 +vt 0.784711 0.516560 +vt 0.782915 0.526461 +vt 0.787567 0.525730 +vt 0.787850 0.517188 +vt 0.782874 0.535514 +vt 0.787635 0.534587 +vt 0.792180 0.532414 +vt 0.792195 0.524240 +vt 0.792160 0.517140 +vt 0.492337 0.373462 +vt 0.493301 0.366013 +vt 0.489326 0.365834 +vt 0.488300 0.373289 +vt 0.494030 0.356838 +vt 0.490257 0.356668 +vt 0.486565 0.356492 +vt 0.485484 0.365653 +vt 0.484424 0.373119 +vt 0.782237 0.421684 +vt 0.782487 0.428011 +vt 0.787668 0.427726 +vt 0.787527 0.421330 +vt 0.782785 0.435771 +vt 0.787762 0.435557 +vt 0.792851 0.435333 +vt 0.793056 0.427429 +vt 0.793085 0.420963 +vt 0.785768 0.490267 +vt 0.784145 0.502655 +vt 0.788244 0.502730 +vt 0.788734 0.492952 +vt 0.784884 0.513165 +vt 0.787990 0.512310 +vt 0.792128 0.512053 +vt 0.792257 0.502649 +vt 0.792385 0.493245 +vt 0.784378 0.550789 +vt 0.784817 0.554090 +vt 0.788817 0.554505 +vt 0.788559 0.550948 +vt 0.784993 0.555397 +vt 0.788914 0.555809 +vt 0.791839 0.555225 +vt 0.791888 0.553891 +vt 0.791966 0.549978 +vt 0.490461 0.380915 +vt 0.491383 0.378047 +vt 0.487396 0.377938 +vt 0.486613 0.381066 +vt 0.488300 0.373289 +vt 0.484424 0.373119 +vt 0.483591 0.377961 +vt 0.483281 0.382964 +vt 0.494030 0.356838 +vt 0.494318 0.347363 +vt 0.490918 0.347157 +vt 0.490257 0.356668 +vt 0.494337 0.337881 +vt 0.491450 0.337387 +vt 0.488914 0.334513 +vt 0.487522 0.346805 +vt 0.486565 0.356492 +vt 0.477366 0.372787 +vt 0.478380 0.365288 +vt 0.474961 0.365107 +vt 0.473995 0.372624 +vt 0.479530 0.356118 +vt 0.476095 0.355928 +vt 0.472832 0.355742 +vt 0.471807 0.364933 +vt 0.470939 0.372468 +vt 0.479728 0.281639 +vt 0.480035 0.278034 +vt 0.474939 0.278184 +vt 0.475033 0.281782 +vt 0.480357 0.276695 +vt 0.475009 0.276725 +vt 0.469694 0.276232 +vt 0.469887 0.277823 +vt 0.470400 0.281480 +vt 0.480898 0.337255 +vt 0.480326 0.328020 +vt 0.477080 0.327851 +vt 0.477547 0.337075 +vt 0.479497 0.320475 +vt 0.476341 0.320306 +vt 0.473441 0.320135 +vt 0.473980 0.327677 +vt 0.474254 0.336888 +vt 0.475840 0.381889 +vt 0.476613 0.377643 +vt 0.473326 0.377512 +vt 0.472689 0.381810 +vt 0.470330 0.377382 +vt 0.469739 0.381722 +vt 0.470642 0.410085 +vt 0.471865 0.403365 +vt 0.468999 0.403673 +vt 0.467682 0.410553 +vt 0.473360 0.395206 +vt 0.470521 0.395339 +vt 0.467630 0.395420 +vt 0.466020 0.403902 +vt 0.464589 0.410918 +vt 0.479097 0.311415 +vt 0.479145 0.305485 +vt 0.475913 0.305181 +vt 0.475943 0.311171 +vt 0.479254 0.297702 +vt 0.475745 0.297439 +vt 0.472386 0.297029 +vt 0.472890 0.304816 +vt 0.473050 0.310901 +vt 0.480533 0.346699 +vt 0.477118 0.346511 +vt 0.473783 0.346320 +vt 0.470585 0.346125 +vt 0.469846 0.355564 +vt 0.471068 0.336691 +vt 0.468006 0.336495 +vt 0.467485 0.345932 +vt 0.466969 0.355389 +vt 0.467796 0.377253 +vt 0.467111 0.381613 +vt 0.468382 0.372323 +vt 0.465991 0.372174 +vt 0.465422 0.377108 +vt 0.464607 0.381469 +vt 0.464967 0.276897 +vt 0.465883 0.280646 +vt 0.464562 0.275220 +vt 0.460107 0.274177 +vt 0.460642 0.275896 +vt 0.461841 0.279725 +vt 0.470204 0.304367 +vt 0.470585 0.310593 +vt 0.469266 0.296426 +vt 0.466318 0.295822 +vt 0.467680 0.303932 +vt 0.468334 0.310298 +vt 0.462865 0.403982 +vt 0.461286 0.411089 +vt 0.464662 0.395405 +vt 0.461704 0.395277 +vt 0.459673 0.403890 +vt 0.457916 0.411034 +vt 0.469074 0.364771 +vt 0.466483 0.364612 +vt 0.471130 0.327497 +vt 0.470964 0.319960 +vt 0.468735 0.319791 +vt 0.468470 0.327319 +vt 0.457277 0.275307 +vt 0.458559 0.279166 +vt 0.456706 0.273574 +vt 0.453934 0.273340 +vt 0.454487 0.275067 +vt 0.455729 0.278915 +vt 0.456575 0.403622 +vt 0.454625 0.410747 +vt 0.458827 0.395037 +vt 0.455931 0.394728 +vt 0.453464 0.403218 +vt 0.451335 0.410266 +vt 0.465101 0.303611 +vt 0.466030 0.310064 +vt 0.463443 0.295405 +vt 0.460574 0.295131 +vt 0.462412 0.303369 +vt 0.463575 0.309866 +vt 0.463761 0.364413 +vt 0.463457 0.371966 +vt 0.464023 0.355201 +vt 0.461043 0.354942 +vt 0.461098 0.364019 +vt 0.461077 0.371497 +vt 0.465891 0.327151 +vt 0.465056 0.336308 +vt 0.466515 0.319634 +vt 0.464164 0.319475 +vt 0.463272 0.326980 +vt 0.462127 0.336122 +vt 0.462922 0.376909 +vt 0.462030 0.381277 +vt 0.460559 0.376537 +vt 0.459513 0.381034 +vt 0.464424 0.345744 +vt 0.461350 0.345546 +vt 0.458182 0.345324 +vt 0.457970 0.354569 +vt 0.459130 0.335927 +vt 0.456081 0.335735 +vt 0.454713 0.345086 +vt 0.454136 0.354150 +vt 0.458333 0.375906 +vt 0.456991 0.380733 +vt 0.458875 0.370634 +vt 0.455172 0.369669 +vt 0.454648 0.375161 +vt 0.453291 0.380325 +vt 0.450223 0.402691 +vt 0.447993 0.409582 +vt 0.452859 0.394380 +vt 0.449405 0.393918 +vt 0.446945 0.401895 +vt 0.444856 0.408455 +vt 0.459564 0.303159 +vt 0.460889 0.309673 +vt 0.457631 0.294943 +vt 0.454460 0.294964 +vt 0.456383 0.303023 +vt 0.457797 0.309502 +vt 0.458483 0.363328 +vt 0.454643 0.362560 +vt 0.443184 0.361593 +vt 0.440188 0.361411 +vt 0.444252 0.353466 +vt 0.440738 0.353254 +vt 0.438126 0.353094 +vt 0.438888 0.361334 +vt 0.451278 0.308855 +vt 0.449833 0.302721 +vt 0.448005 0.302081 +vt 0.449461 0.307878 +vt 0.448177 0.295582 +vt 0.446423 0.295614 +vt 0.445371 0.295460 +vt 0.446929 0.301194 +vt 0.448403 0.306591 +vt 0.460509 0.326797 +vt 0.461568 0.319301 +vt 0.458615 0.319117 +vt 0.457599 0.326612 +vt 0.451807 0.275127 +vt 0.452974 0.278918 +vt 0.451286 0.273425 +vt 0.448752 0.274415 +vt 0.449211 0.276030 +vt 0.450242 0.279627 +vt 0.446220 0.344570 +vt 0.441178 0.344259 +vt 0.448597 0.335292 +vt 0.442671 0.334923 +vt 0.435739 0.334484 +vt 0.435853 0.343924 +vt 0.450721 0.326196 +vt 0.446003 0.325877 +vt 0.452030 0.318644 +vt 0.449191 0.318249 +vt 0.446633 0.317781 +vt 0.440713 0.325505 +vt 0.440327 0.405107 +vt 0.441386 0.399673 +vt 0.439930 0.398992 +vt 0.439206 0.404069 +vt 0.442309 0.392715 +vt 0.440422 0.392357 +vt 0.439394 0.392145 +vt 0.439068 0.398579 +vt 0.438529 0.403440 +vt 0.753373 0.425135 +vt 0.752944 0.430694 +vt 0.762003 0.429718 +vt 0.762081 0.423967 +vt 0.749250 0.439758 +vt 0.761709 0.436992 +vt 0.771120 0.436303 +vt 0.770905 0.428826 +vt 0.770752 0.422776 +vt 0.750062 0.449356 +vt 0.749832 0.453349 +vt 0.761718 0.453280 +vt 0.761730 0.449198 +vt 0.749864 0.458065 +vt 0.761786 0.458043 +vt 0.771805 0.457999 +vt 0.771728 0.453197 +vt 0.771582 0.449047 +vt 0.750227 0.465510 +vt 0.761986 0.465505 +vt 0.750814 0.474703 +vt 0.762309 0.474695 +vt 0.771966 0.474666 +vt 0.771847 0.465477 +vt 0.751436 0.484201 +vt 0.762692 0.484177 +vt 0.751773 0.493692 +vt 0.762906 0.493658 +vt 0.772400 0.493610 +vt 0.772224 0.484138 +vt 0.751601 0.502864 +vt 0.762771 0.502839 +vt 0.751211 0.510271 +vt 0.762459 0.510272 +vt 0.771998 0.510245 +vt 0.772284 0.502795 +vt 0.750666 0.518919 +vt 0.750310 0.524396 +vt 0.761329 0.524679 +vt 0.761812 0.519049 +vt 0.749884 0.531098 +vt 0.760901 0.531625 +vt 0.770447 0.532694 +vt 0.770781 0.525276 +vt 0.771301 0.519253 +vt 0.741991 0.426054 +vt 0.741976 0.431134 +vt 0.746748 0.430989 +vt 0.746926 0.425771 +vt 0.741955 0.437667 +vt 0.746219 0.437882 +vt 0.769328 0.739645 +vt 0.769720 0.735666 +vt 0.763219 0.735842 +vt 0.763481 0.739787 +vt 0.771836 0.730102 +vt 0.763076 0.731107 +vt 0.755588 0.731394 +vt 0.756047 0.736090 +vt 0.757000 0.740043 +vt 0.769610 0.723441 +vt 0.762492 0.723733 +vt 0.767950 0.714384 +vt 0.761644 0.714578 +vt 0.755339 0.714772 +vt 0.755497 0.723954 +vt 0.766514 0.705321 +vt 0.760612 0.705184 +vt 0.766694 0.698581 +vt 0.760063 0.695906 +vt 0.754480 0.695830 +vt 0.754812 0.705306 +vt 0.765468 0.686529 +vt 0.760318 0.686507 +vt 0.765966 0.678823 +vt 0.761009 0.678990 +vt 0.755564 0.679163 +vt 0.754879 0.686623 +vt 0.769132 0.668283 +vt 0.769959 0.661897 +vt 0.763233 0.663357 +vt 0.762229 0.669731 +vt 0.772099 0.656170 +vt 0.763810 0.656231 +vt 0.757751 0.658167 +vt 0.756832 0.664934 +vt 0.756339 0.670451 +vt 0.778943 0.759859 +vt 0.773423 0.758897 +vt 0.773787 0.764389 +vt 0.778647 0.752482 +vt 0.773189 0.752098 +vt 0.767513 0.753319 +vt 0.769153 0.757746 +vt 0.769740 0.762511 +vt 0.778894 0.739749 +vt 0.778847 0.735561 +vt 0.774599 0.735775 +vt 0.774197 0.739678 +vt 0.776804 0.729921 +vt 0.774869 0.732376 +vt 0.942464 0.732717 +vt 0.941609 0.742270 +vt 0.945036 0.742558 +vt 0.945563 0.733015 +vt 0.941006 0.751802 +vt 0.944690 0.752095 +vt 0.948373 0.752388 +vt 0.948463 0.742845 +vt 0.948662 0.733312 +vt 0.940824 0.761298 +vt 0.944644 0.761621 +vt 0.940894 0.770773 +vt 0.944778 0.771142 +vt 0.948662 0.771510 +vt 0.948463 0.761945 +vt 0.772587 0.698367 +vt 0.775148 0.686232 +vt 0.769962 0.686243 +vt 0.769487 0.696108 +vt 0.775833 0.678495 +vt 0.770369 0.678663 +vt 0.072165 0.251051 +vt 0.072261 0.257778 +vt 0.075511 0.259293 +vt 0.075463 0.251079 +vt 0.072357 0.264506 +vt 0.075559 0.267508 +vt 0.078762 0.270510 +vt 0.078762 0.260808 +vt 0.078762 0.251107 +vt 0.779430 0.642541 +vt 0.778845 0.648734 +vt 0.786616 0.648063 +vt 0.787391 0.641879 +vt 0.774996 0.658950 +vt 0.785274 0.655948 +vt 0.793445 0.654990 +vt 0.794109 0.647570 +vt 0.794519 0.641795 +vt 0.773241 0.669014 +vt 0.775905 0.673720 +vt 0.784244 0.673435 +vt 0.784258 0.669095 +vt 0.775833 0.678495 +vt 0.783608 0.678312 +vt 0.791783 0.678148 +vt 0.792946 0.673176 +vt 0.793115 0.668683 +vt 0.775148 0.686232 +vt 0.782102 0.685903 +vt 0.780304 0.695322 +vt 0.786068 0.694896 +vt 0.789087 0.685719 +vt 0.773768 0.705035 +vt 0.779286 0.704599 +vt 0.774430 0.714109 +vt 0.779364 0.714002 +vt 0.783872 0.713625 +vt 0.784150 0.704239 +vt 0.776054 0.723184 +vt 0.780802 0.723180 +vt 0.782506 0.730622 +vt 0.787198 0.730547 +vt 0.785264 0.722908 +vt 0.778894 0.739749 +vt 0.778685 0.745448 +vt 0.784959 0.745460 +vt 0.784238 0.739713 +vt 0.778647 0.752482 +vt 0.785788 0.752622 +vt 0.793373 0.752520 +vt 0.791670 0.745338 +vt 0.789936 0.739614 +vt 0.791783 0.678148 +vt 0.789087 0.685719 +vt 0.794713 0.685611 +vt 0.798300 0.678034 +vt 0.786068 0.694896 +vt 0.790679 0.694637 +vt 0.794656 0.694318 +vt 0.799447 0.685510 +vt 0.803668 0.677952 +vt 0.783872 0.713625 +vt 0.785264 0.722908 +vt 0.789400 0.722293 +vt 0.787668 0.712797 +vt 0.787198 0.730547 +vt 0.791867 0.730286 +vt 0.796581 0.729957 +vt 0.793355 0.721482 +vt 0.791038 0.711699 +vt 0.795119 0.766530 +vt 0.795415 0.769861 +vt 0.801128 0.769866 +vt 0.801079 0.766508 +vt 0.795555 0.771373 +vt 0.801157 0.771391 +vt 0.805193 0.771347 +vt 0.805341 0.769817 +vt 0.805684 0.766450 +vt 0.793115 0.668683 +vt 0.792946 0.673176 +vt 0.799819 0.673012 +vt 0.799987 0.668435 +vt 0.805461 0.672915 +vt 0.805693 0.668322 +vt 0.794519 0.641795 +vt 0.794109 0.647570 +vt 0.800536 0.647685 +vt 0.800878 0.642344 +vt 0.793445 0.654990 +vt 0.800079 0.654728 +vt 0.805856 0.654788 +vt 0.806317 0.648155 +vt 0.806816 0.643251 +vt 0.784150 0.704239 +vt 0.788102 0.703627 +vt 0.791525 0.702824 +vt 0.797870 0.745230 +vt 0.795534 0.739526 +vt 0.799937 0.752412 +vt 0.805771 0.752327 +vt 0.803682 0.745147 +vt 0.801024 0.739451 +vt 0.771966 0.474666 +vt 0.772224 0.484138 +vt 0.778916 0.484007 +vt 0.778559 0.474603 +vt 0.772400 0.493610 +vt 0.779281 0.493273 +vt 0.784008 0.483594 +vt 0.783314 0.474520 +vt 0.771582 0.449047 +vt 0.771728 0.453197 +vt 0.778642 0.453139 +vt 0.778530 0.449096 +vt 0.771805 0.457999 +vt 0.778650 0.457916 +vt 0.783590 0.457811 +vt 0.783806 0.453256 +vt 0.784918 0.451037 +vt 0.770863 0.546352 +vt 0.771025 0.549504 +vt 0.779048 0.552047 +vt 0.778683 0.548847 +vt 0.771075 0.550906 +vt 0.779190 0.553407 +vt 0.772283 0.502795 +vt 0.779069 0.502716 +vt 0.771998 0.510245 +vt 0.778785 0.510427 +vt 0.770752 0.422776 +vt 0.770905 0.428826 +vt 0.777385 0.428313 +vt 0.777135 0.422072 +vt 0.771120 0.436303 +vt 0.777719 0.435986 +vt 0.778544 0.465409 +vt 0.778559 0.474603 +vt 0.783343 0.465316 +vt 0.783590 0.457811 +vt 0.771301 0.519253 +vt 0.770781 0.525276 +vt 0.777641 0.526196 +vt 0.778160 0.519273 +vt 0.770447 0.532694 +vt 0.777505 0.534456 +vt 0.483991 0.346821 +vt 0.483007 0.356308 +vt 0.484367 0.337175 +vt 0.480898 0.337255 +vt 0.479530 0.356118 +vt 0.486998 0.311104 +vt 0.485873 0.305964 +vt 0.482446 0.305759 +vt 0.482429 0.311589 +vt 0.486367 0.298101 +vt 0.482805 0.297912 +vt 0.479254 0.297702 +vt 0.479145 0.305485 +vt 0.479097 0.311415 +vt 0.476518 0.409113 +vt 0.477559 0.402722 +vt 0.474712 0.403043 +vt 0.473580 0.409599 +vt 0.479020 0.394924 +vt 0.476190 0.395065 +vt 0.479995 0.377794 +vt 0.479118 0.382043 +vt 0.480815 0.372952 +vt 0.477366 0.372787 +vt 0.476613 0.377643 +vt 0.475840 0.381889 +vt 0.487209 0.328083 +vt 0.483654 0.328143 +vt 0.487333 0.321722 +vt 0.482824 0.320720 +vt 0.479497 0.320475 +vt 0.480326 0.328020 +vt 0.489303 0.280747 +vt 0.490327 0.276919 +vt 0.485170 0.277557 +vt 0.484495 0.281250 +vt 0.491002 0.275647 +vt 0.485687 0.276273 +vt 0.481865 0.365471 +vt 0.483007 0.356308 +vt 0.479020 0.394924 +vt 0.480829 0.387849 +vt 0.477741 0.387761 +vt 0.476190 0.395065 +vt 0.474743 0.387750 +vt 0.771363 0.443364 +vt 0.778110 0.443213 +vt 0.777719 0.435986 +vt 0.783187 0.443220 +vt 0.788621 0.735434 +vt 0.793739 0.735334 +vt 0.798920 0.735230 +vt 0.778847 0.735561 +vt 0.783613 0.735505 +vt 0.784238 0.739713 +vt 0.789937 0.739614 +vt 0.788621 0.735434 +vt 0.778685 0.745448 +vt 0.773624 0.745244 +vt 0.768928 0.745153 +vt 0.763897 0.745125 +vt 0.764302 0.751627 +vt 0.758445 0.745380 +vt 0.760161 0.751722 +vt 0.750237 0.444235 +vt 0.761731 0.443680 +vt 0.457982 0.387070 +vt 0.455156 0.386845 +vt 0.451541 0.386539 +vt 0.463384 0.387512 +vt 0.460682 0.387302 +vt 0.468882 0.387730 +vt 0.466099 0.387655 +vt 0.474743 0.387750 +vt 0.471778 0.387754 +vt 0.787744 0.443025 +vt 0.787762 0.435557 +vt 0.787769 0.450149 +vt 0.791679 0.449888 +vt 0.792353 0.442827 +vt 0.792851 0.435333 +vt 0.442542 0.385663 +vt 0.440215 0.385414 +vt 0.439135 0.385283 +vt 0.486061 0.316008 +vt 0.482401 0.315831 +vt 0.479127 0.315638 +vt 0.771694 0.515006 +vt 0.778432 0.514979 +vt 0.783695 0.514902 +vt 0.793148 0.662452 +vt 0.799934 0.662111 +vt 0.805684 0.662005 +vt 0.774775 0.664311 +vt 0.784585 0.663210 +vt 0.793148 0.662452 +vt 0.775905 0.673720 +vt 0.770620 0.674039 +vt 0.770744 0.670727 +vt 0.766545 0.674011 +vt 0.761513 0.674224 +vt 0.756010 0.674458 +vt 0.750923 0.514940 +vt 0.762164 0.514985 +vt 0.452138 0.313500 +vt 0.450188 0.312743 +vt 0.448932 0.311778 +vt 0.464226 0.314478 +vt 0.461646 0.314301 +vt 0.458630 0.314120 +vt 0.468678 0.314824 +vt 0.466534 0.314646 +vt 0.473155 0.315244 +vt 0.470790 0.315029 +vt 0.479127 0.315638 +vt 0.475996 0.315445 +vt 0.494105 0.318815 +vt 0.494246 0.316265 +vt 0.489937 0.316107 +vt 0.489980 0.319044 +vt 0.494388 0.313715 +vt 0.490118 0.313254 +vt 0.455192 0.313912 +vt 0.455298 0.318917 +vt 0.454309 0.309321 +vt 0.446814 0.386092 +vt 0.445578 0.393297 +vt 0.447697 0.379799 +vt 0.443841 0.400763 +vt 0.442234 0.406763 +vt 0.454477 0.326427 +vt 0.452845 0.335544 +vt 0.450743 0.344841 +vt 0.449138 0.353769 +vt 0.452867 0.302961 +vt 0.451068 0.295272 +vt 0.448769 0.361967 +vt 0.448848 0.368935 +vt 0.448456 0.374484 +vt 0.446832 0.278128 +vt 0.447634 0.281340 +vt 0.446475 0.276686 +vt 0.444723 0.279160 +vt 0.452186 0.286471 +vt 0.449167 0.287480 +vt 0.446662 0.288606 +vt 0.486367 0.298101 +vt 0.487775 0.288663 +vt 0.483600 0.288812 +vt 0.482805 0.297912 +vt 0.479456 0.288900 +vt 0.770564 0.540311 +vt 0.778009 0.542576 +vt 0.777505 0.534456 +vt 0.783565 0.544161 +vt 0.782874 0.535514 +vt 0.793149 0.637459 +vt 0.794098 0.638794 +vt 0.800697 0.639582 +vt 0.800179 0.638349 +vt 0.800878 0.642344 +vt 0.806816 0.643251 +vt 0.807092 0.640723 +vt 0.807216 0.639589 +vt 0.778116 0.637946 +vt 0.778998 0.639397 +vt 0.787031 0.638676 +vt 0.786005 0.637246 +vt 0.787391 0.641879 +vt 0.793149 0.637459 +vt 0.458040 0.286212 +vt 0.455160 0.286113 +vt 0.464048 0.286982 +vt 0.460930 0.286482 +vt 0.471394 0.288491 +vt 0.467569 0.287762 +vt 0.475376 0.288845 +vt 0.788070 0.543699 +vt 0.787635 0.534587 +vt 0.792084 0.541949 +vt 0.792180 0.532415 +vt 0.445142 0.289306 +vt 0.444223 0.289708 +vt 0.749349 0.537937 +vt 0.760691 0.538838 +vt 0.760901 0.531625 +vt 0.770564 0.540311 +vt 0.766742 0.648833 +vt 0.762559 0.649641 +vt 0.760324 0.643662 +vt 0.761091 0.643473 +vt 0.759251 0.650913 +vt 0.772360 0.648632 +vt 0.773990 0.655481 +vt 0.443257 0.413503 +vt 0.443750 0.411929 +vt 0.441368 0.409926 +vt 0.440980 0.411359 +vt 0.439735 0.407954 +vt 0.439468 0.409244 +vt 0.475742 0.414032 +vt 0.475984 0.412497 +vt 0.472989 0.413072 +vt 0.472722 0.414647 +vt 0.469995 0.413646 +vt 0.469701 0.415262 +vt 0.770637 0.418134 +vt 0.770673 0.419582 +vt 0.777006 0.418774 +vt 0.776947 0.417278 +vt 0.782104 0.418339 +vt 0.782044 0.416822 +vt 0.794504 0.760236 +vt 0.800877 0.760166 +vt 0.801079 0.766508 +vt 0.805685 0.766450 +vt 0.806172 0.760093 +vt 0.779559 0.768928 +vt 0.773988 0.767303 +vt 0.774079 0.768626 +vt 0.779334 0.765797 +vt 0.773787 0.764389 +vt 0.769740 0.762511 +vt 0.769965 0.765161 +vt 0.770068 0.766363 +vt 0.742003 0.422190 +vt 0.742000 0.423396 +vt 0.746977 0.423065 +vt 0.747000 0.421838 +vt 0.746926 0.425771 +vt 0.753428 0.422324 +vt 0.753453 0.421050 +vt 0.762080 0.420965 +vt 0.762079 0.419603 +vt 0.762081 0.423967 +vt 0.439468 0.409244 +vt 0.439735 0.407954 +vt 0.438788 0.406717 +vt 0.438598 0.407918 +vt 0.440327 0.405107 +vt 0.439206 0.404070 +vt 0.438214 0.405968 +vt 0.438071 0.407114 +vt 0.449699 0.415699 +vt 0.450203 0.414005 +vt 0.446813 0.413239 +vt 0.446288 0.414895 +vt 0.456554 0.416544 +vt 0.456978 0.414825 +vt 0.453585 0.414527 +vt 0.453119 0.416241 +vt 0.463470 0.416327 +vt 0.463819 0.414639 +vt 0.460438 0.414860 +vt 0.460054 0.416570 +vt 0.466977 0.414201 +vt 0.466657 0.415856 +vt 0.787445 0.417947 +vt 0.787408 0.416412 +vt 0.793085 0.417541 +vt 0.793085 0.415989 +vt 0.778943 0.759859 +vt 0.786567 0.760238 +vt 0.779627 0.869221 +vt 0.788755 0.869122 +vt 0.789027 0.865863 +vt 0.779731 0.866036 +vt 0.796642 0.869064 +vt 0.796930 0.865749 +vt 0.797061 0.864260 +vt 0.789130 0.864392 +vt 0.779729 0.864592 +vt 0.780050 0.993091 +vt 0.772436 0.992243 +vt 0.771813 0.994844 +vt 0.780224 0.996252 +vt 0.763379 0.992439 +vt 0.763019 0.993129 +vt 0.762930 0.994097 +vt 0.771863 0.996152 +vt 0.780619 0.997707 +vt 0.539518 0.280212 +vt 0.541198 0.280417 +vt 0.541202 0.278962 +vt 0.539246 0.279205 +vt 0.542813 0.282565 +vt 0.545562 0.278646 +vt 0.545518 0.277034 +vt 0.540928 0.277745 +vt 0.538973 0.278198 +vt 0.554412 0.281078 +vt 0.554369 0.277609 +vt 0.564226 0.279281 +vt 0.564273 0.275694 +vt 0.564388 0.273810 +vt 0.554282 0.275806 +vt 0.014543 0.405624 +vt 0.013208 0.404397 +vt 0.012856 0.406918 +vt 0.014030 0.408410 +vt 0.012427 0.403665 +vt 0.012182 0.406021 +vt 0.012121 0.407047 +vt 0.012732 0.408027 +vt 0.013825 0.409647 +vt 0.011191 0.309354 +vt 0.008290 0.309557 +vt 0.008107 0.314976 +vt 0.011304 0.314767 +vt 0.007085 0.309626 +vt 0.006902 0.315040 +vt 0.007165 0.320635 +vt 0.008365 0.320575 +vt 0.011611 0.320381 +vt 0.577229 0.309129 +vt 0.579804 0.308377 +vt 0.579512 0.299868 +vt 0.575627 0.299349 +vt 0.583368 0.308241 +vt 0.583392 0.301120 +vt 0.583461 0.292846 +vt 0.579614 0.290920 +vt 0.575568 0.290239 +vt 0.059564 0.315946 +vt 0.055847 0.316008 +vt 0.056838 0.323416 +vt 0.060428 0.323292 +vt 0.052254 0.316063 +vt 0.053335 0.323533 +vt 0.054420 0.332727 +vt 0.057744 0.332558 +vt 0.061100 0.332385 +vt 0.575611 0.403459 +vt 0.580146 0.403740 +vt 0.580293 0.397335 +vt 0.575871 0.397104 +vt 0.584958 0.404025 +vt 0.584937 0.397574 +vt 0.584752 0.389694 +vt 0.580411 0.389496 +vt 0.576202 0.389310 +vt 0.061339 0.351245 +vt 0.058405 0.351410 +vt 0.057974 0.360576 +vt 0.061255 0.360413 +vt 0.055426 0.351592 +vt 0.054757 0.360756 +vt 0.053893 0.368214 +vt 0.057455 0.368024 +vt 0.061218 0.367847 +vt 0.577179 0.274259 +vt 0.580972 0.273899 +vt 0.581649 0.270000 +vt 0.577888 0.270574 +vt 0.583925 0.274753 +vt 0.584396 0.270535 +vt 0.584965 0.268901 +vt 0.582239 0.268385 +vt 0.578429 0.268912 +vt 0.058015 0.308739 +vt 0.054239 0.308448 +vt 0.054983 0.311452 +vt 0.058759 0.311480 +vt 0.050942 0.306448 +vt 0.051373 0.311291 +vt 0.055847 0.316008 +vt 0.059564 0.315946 +vt 0.058319 0.341980 +vt 0.061357 0.341802 +vt 0.055246 0.342166 +vt 0.045703 0.316149 +vt 0.042711 0.316201 +vt 0.043664 0.323840 +vt 0.046762 0.323739 +vt 0.040063 0.316281 +vt 0.040836 0.323954 +vt 0.041796 0.333345 +vt 0.044788 0.333197 +vt 0.047939 0.333047 +vt 0.047956 0.407627 +vt 0.043758 0.407360 +vt 0.043710 0.411011 +vt 0.048298 0.411356 +vt 0.039550 0.407603 +vt 0.039062 0.411264 +vt 0.038905 0.412869 +vt 0.043826 0.412538 +vt 0.048654 0.412836 +vt 0.049305 0.352024 +vt 0.046274 0.352241 +vt 0.045794 0.361406 +vt 0.048667 0.361185 +vt 0.043293 0.352446 +vt 0.043077 0.361615 +vt 0.042579 0.369079 +vt 0.045025 0.368869 +vt 0.047753 0.368646 +vt 0.044027 0.307159 +vt 0.041356 0.307106 +vt 0.042028 0.311322 +vt 0.044880 0.311319 +vt 0.038949 0.307094 +vt 0.039518 0.311362 +vt 0.038670 0.279219 +vt 0.036204 0.278650 +vt 0.037537 0.285482 +vt 0.039905 0.285896 +vt 0.033624 0.278159 +vt 0.035096 0.285129 +vt 0.036765 0.293545 +vt 0.039097 0.293745 +vt 0.041432 0.293993 +vt 0.047248 0.377702 +vt 0.044577 0.377987 +vt 0.044545 0.383963 +vt 0.047287 0.383632 +vt 0.042209 0.378282 +vt 0.042042 0.384344 +vt 0.041530 0.392097 +vt 0.044394 0.391684 +vt 0.047411 0.391423 +vt 0.045828 0.342755 +vt 0.048957 0.342564 +vt 0.042762 0.342938 +vt 0.039023 0.333499 +vt 0.039778 0.343116 +vt 0.036281 0.333662 +vt 0.036817 0.343283 +vt 0.037459 0.352807 +vt 0.040359 0.352638 +vt 0.036768 0.307158 +vt 0.037386 0.311462 +vt 0.034504 0.307301 +vt 0.035239 0.311623 +vt 0.035643 0.316570 +vt 0.037837 0.316403 +vt 0.035375 0.408421 +vt 0.034453 0.412149 +vt 0.031559 0.409351 +vt 0.030331 0.413150 +vt 0.029781 0.414844 +vt 0.034056 0.413811 +vt 0.040174 0.378594 +vt 0.039788 0.384800 +vt 0.038179 0.378880 +vt 0.037526 0.385235 +vt 0.036135 0.393322 +vt 0.038822 0.392708 +vt 0.030666 0.277861 +vt 0.032339 0.284930 +vt 0.027396 0.277810 +vt 0.029297 0.284930 +vt 0.031469 0.293524 +vt 0.034235 0.293462 +vt 0.038363 0.324092 +vt 0.035930 0.324256 +vt 0.040537 0.361801 +vt 0.038066 0.361958 +vt 0.038457 0.369422 +vt 0.040469 0.369266 +vt 0.028362 0.409923 +vt 0.027054 0.413752 +vt 0.025487 0.410171 +vt 0.024237 0.413992 +vt 0.023681 0.415694 +vt 0.026465 0.415457 +vt 0.023950 0.278024 +vt 0.026062 0.285142 +vt 0.020400 0.278453 +vt 0.022680 0.285509 +vt 0.025323 0.294026 +vt 0.028482 0.293734 +vt 0.035916 0.379098 +vt 0.034999 0.385548 +vt 0.033348 0.379266 +vt 0.032203 0.385767 +vt 0.030364 0.394000 +vt 0.033324 0.393742 +vt 0.033142 0.316818 +vt 0.033253 0.324480 +vt 0.030690 0.317331 +vt 0.030557 0.324906 +vt 0.030393 0.334112 +vt 0.033385 0.333847 +vt 0.034566 0.352948 +vt 0.035537 0.362086 +vt 0.031599 0.353092 +vt 0.032855 0.362215 +vt 0.033840 0.369676 +vt 0.036278 0.369551 +vt 0.031903 0.307513 +vt 0.032750 0.311859 +vt 0.029209 0.307774 +vt 0.030265 0.312268 +vt 0.033811 0.343442 +vt 0.030720 0.343617 +vt 0.027272 0.334498 +vt 0.027483 0.343833 +vt 0.023360 0.334930 +vt 0.023923 0.344074 +vt 0.025315 0.353453 +vt 0.028495 0.353266 +vt 0.026485 0.308074 +vt 0.027877 0.312915 +vt 0.022557 0.308456 +vt 0.023986 0.313656 +vt 0.024505 0.319203 +vt 0.028373 0.318225 +vt 0.016844 0.279089 +vt 0.019198 0.285999 +vt 0.013541 0.280179 +vt 0.015725 0.286759 +vt 0.018328 0.294775 +vt 0.022000 0.294347 +vt 0.030472 0.379411 +vt 0.029160 0.385928 +vt 0.027135 0.379522 +vt 0.025724 0.385996 +vt 0.023814 0.394053 +vt 0.027235 0.394144 +vt 0.027873 0.325624 +vt 0.023922 0.326411 +vt 0.009057 0.327566 +vt 0.012156 0.327388 +vt 0.007683 0.327637 +vt 0.007170 0.335969 +vt 0.009771 0.335821 +vt 0.013307 0.335618 +vt 0.020108 0.380041 +vt 0.018163 0.380968 +vt 0.016689 0.386735 +vt 0.018650 0.386147 +vt 0.017042 0.382210 +vt 0.015546 0.387583 +vt 0.014069 0.393339 +vt 0.015165 0.393206 +vt 0.017032 0.393279 +vt 0.029958 0.362372 +vt 0.026885 0.362544 +vt 0.027945 0.369980 +vt 0.031090 0.369821 +vt 0.022584 0.410131 +vt 0.021429 0.413900 +vt 0.019640 0.409357 +vt 0.018641 0.412937 +vt 0.018218 0.414539 +vt 0.020928 0.415583 +vt 0.010328 0.344873 +vt 0.015322 0.344583 +vt 0.005095 0.345179 +vt 0.005065 0.354621 +vt 0.011856 0.354219 +vt 0.017702 0.353879 +vt 0.015127 0.363231 +vt 0.019788 0.362933 +vt 0.009971 0.363577 +vt 0.015701 0.371236 +vt 0.018182 0.370784 +vt 0.021024 0.370407 +vt 0.008767 0.283492 +vt 0.007602 0.284508 +vt 0.008363 0.289575 +vt 0.009881 0.288927 +vt 0.006916 0.285110 +vt 0.007473 0.289951 +vt 0.007804 0.296372 +vt 0.008896 0.296209 +vt 0.010881 0.295898 +vt 0.549341 0.400225 +vt 0.557628 0.401346 +vt 0.557635 0.395569 +vt 0.549032 0.394660 +vt 0.565638 0.402481 +vt 0.565841 0.396394 +vt 0.566139 0.388869 +vt 0.557491 0.388265 +vt 0.545759 0.385616 +vt 0.547042 0.376040 +vt 0.557863 0.376067 +vt 0.557957 0.372092 +vt 0.546944 0.372142 +vt 0.566857 0.376114 +vt 0.567085 0.372077 +vt 0.567176 0.367430 +vt 0.558041 0.367470 +vt 0.546995 0.367544 +vt 0.558159 0.360133 +vt 0.547265 0.360196 +vt 0.567156 0.360092 +vt 0.567158 0.351001 +vt 0.558350 0.351030 +vt 0.547717 0.351070 +vt 0.558594 0.341592 +vt 0.548229 0.341613 +vt 0.567268 0.341575 +vt 0.567284 0.332124 +vt 0.558665 0.332131 +vt 0.548446 0.332144 +vt 0.558380 0.322968 +vt 0.548111 0.322981 +vt 0.567018 0.322965 +vt 0.566614 0.315549 +vt 0.557943 0.315555 +vt 0.547574 0.315578 +vt 0.546880 0.306987 +vt 0.557163 0.306884 +vt 0.556557 0.301379 +vt 0.546346 0.301597 +vt 0.565787 0.306676 +vt 0.565186 0.300792 +vt 0.564626 0.293429 +vt 0.555804 0.294484 +vt 0.545496 0.294906 +vt 0.538369 0.400156 +vt 0.543022 0.399716 +vt 0.542929 0.394487 +vt 0.538378 0.394908 +vt 0.542533 0.387585 +vt 0.538390 0.388161 +vt 0.772449 0.896034 +vt 0.767034 0.896036 +vt 0.766752 0.899949 +vt 0.772809 0.900018 +vt 0.760986 0.895966 +vt 0.760021 0.899840 +vt 0.759574 0.904424 +vt 0.766614 0.904643 +vt 0.774805 0.905588 +vt 0.766072 0.911975 +vt 0.772744 0.912261 +vt 0.759510 0.911762 +vt 0.759392 0.920869 +vt 0.765271 0.921090 +vt 0.771150 0.921310 +vt 0.771150 0.921310 +vt 0.765271 0.921090 +vt 0.764259 0.930513 +vt 0.769602 0.930729 +vt 0.759392 0.920869 +vt 0.758917 0.930296 +vt 0.758617 0.939750 +vt 0.763671 0.939953 +vt 0.768725 0.940156 +vt 0.764041 0.949131 +vt 0.769077 0.949330 +vt 0.759005 0.948933 +vt 0.759656 0.956369 +vt 0.764767 0.956555 +vt 0.769878 0.956741 +vt 0.771169 0.966353 +vt 0.765771 0.965677 +vt 0.766796 0.972090 +vt 0.772951 0.973563 +vt 0.760373 0.965000 +vt 0.760852 0.970419 +vt 0.761787 0.977160 +vt 0.767390 0.979277 +vt 0.775076 0.979452 +vt 0.531074 0.403781 +vt 0.534540 0.401664 +vt 0.534545 0.396072 +vt 0.531051 0.397688 +vt 0.534558 0.388881 +vt 0.531034 0.389853 +vt 0.781146 0.895846 +vt 0.776885 0.895926 +vt 0.777268 0.899854 +vt 0.781099 0.900060 +vt 0.777538 0.903298 +vt 0.779227 0.905748 +vt 0.969896 0.736135 +vt 0.966366 0.736215 +vt 0.966095 0.745754 +vt 0.969692 0.745694 +vt 0.962836 0.736296 +vt 0.962498 0.745813 +vt 0.962028 0.755316 +vt 0.965778 0.755267 +vt 0.969528 0.755218 +vt 0.969528 0.755218 +vt 0.965778 0.755267 +vt 0.965422 0.764739 +vt 0.969435 0.764683 +vt 0.962028 0.755316 +vt 0.961409 0.764794 +vt 0.961089 0.774255 +vt 0.965255 0.774191 +vt 0.969422 0.774128 +vt 0.965456 0.783353 +vt 0.969480 0.783296 +vt 0.961433 0.783409 +vt 0.962010 0.790783 +vt 0.965787 0.790749 +vt 0.969564 0.790716 +vt 0.969702 0.799368 +vt 0.966139 0.799856 +vt 0.966360 0.806452 +vt 0.969792 0.804870 +vt 0.962576 0.800344 +vt 0.962928 0.808034 +vt 0.963372 0.817613 +vt 0.966634 0.814536 +vt 0.969896 0.811458 +vt 0.780050 0.993091 +vt 0.787502 0.993703 +vt 0.787133 0.987507 +vt 0.779979 0.986863 +vt 0.794725 0.993791 +vt 0.794515 0.988017 +vt 0.794583 0.980605 +vt 0.786730 0.979612 +vt 0.777477 0.976580 +vt 0.776718 0.965726 +vt 0.786215 0.966399 +vt 0.785939 0.962119 +vt 0.776282 0.961725 +vt 0.794664 0.966922 +vt 0.794490 0.962434 +vt 0.793316 0.957468 +vt 0.785254 0.957280 +vt 0.776166 0.957055 +vt 0.783865 0.949773 +vt 0.776353 0.949638 +vt 0.790608 0.949900 +vt 0.787588 0.940724 +vt 0.782293 0.940566 +vt 0.776490 0.940472 +vt 0.781239 0.931104 +vt 0.776393 0.931026 +vt 0.785687 0.931381 +vt 0.785420 0.922003 +vt 0.781300 0.921649 +vt 0.776883 0.921576 +vt 0.776883 0.921576 +vt 0.782700 0.912477 +vt 0.778450 0.912497 +vt 0.785420 0.922003 +vt 0.786796 0.912737 +vt 0.788707 0.905118 +vt 0.784359 0.905032 +vt 0.781146 0.895846 +vt 0.786065 0.895915 +vt 0.786740 0.890104 +vt 0.780701 0.889951 +vt 0.791442 0.896057 +vt 0.793187 0.890306 +vt 0.794900 0.883092 +vt 0.787353 0.882772 +vt 0.777935 0.880697 +vt 0.799670 0.957594 +vt 0.796072 0.950015 +vt 0.804998 0.957684 +vt 0.800768 0.950123 +vt 0.795974 0.941309 +vt 0.792035 0.940985 +vt 0.789045 0.922827 +vt 0.790769 0.913359 +vt 0.786796 0.912737 +vt 0.792372 0.923932 +vt 0.794681 0.914188 +vt 0.797894 0.905755 +vt 0.793223 0.905400 +vt 0.788707 0.905118 +vt 0.796642 0.869064 +vt 0.802462 0.869075 +vt 0.802510 0.865736 +vt 0.807042 0.869128 +vt 0.806698 0.865783 +vt 0.806549 0.864287 +vt 0.802541 0.864240 +vt 0.801369 0.967194 +vt 0.801196 0.962618 +vt 0.807028 0.967317 +vt 0.806796 0.962723 +vt 0.794725 0.993791 +vt 0.801563 0.993258 +vt 0.801289 0.987922 +vt 0.794515 0.988017 +vt 0.808168 0.992369 +vt 0.807663 0.987468 +vt 0.807197 0.980842 +vt 0.801236 0.980888 +vt 0.794583 0.980605 +vt 0.789469 0.931990 +vt 0.792852 0.932797 +vt 0.791442 0.896057 +vt 0.796893 0.896170 +vt 0.799243 0.890426 +vt 0.793187 0.890306 +vt 0.802344 0.896257 +vt 0.805019 0.890510 +vt 0.807125 0.883277 +vt 0.801321 0.883198 +vt 0.794900 0.883092 +vt 0.572926 0.350989 +vt 0.573120 0.341566 +vt 0.576870 0.350987 +vt 0.577279 0.341563 +vt 0.577583 0.332135 +vt 0.573234 0.332126 +vt 0.566857 0.376114 +vt 0.572914 0.376006 +vt 0.573099 0.372072 +vt 0.567085 0.372077 +vt 0.578212 0.374034 +vt 0.577335 0.371913 +vt 0.577167 0.367494 +vt 0.573127 0.367445 +vt 0.567176 0.367430 +vt 0.564226 0.279281 +vt 0.571772 0.276522 +vt 0.572226 0.272894 +vt 0.564273 0.275694 +vt 0.572597 0.271094 +vt 0.564388 0.273810 +vt 0.572938 0.322980 +vt 0.577227 0.323005 +vt 0.576593 0.315611 +vt 0.572453 0.315571 +vt 0.565638 0.402481 +vt 0.571276 0.403131 +vt 0.571551 0.396852 +vt 0.565841 0.396394 +vt 0.571937 0.389130 +vt 0.566139 0.388869 +vt 0.573127 0.367445 +vt 0.572991 0.360088 +vt 0.577167 0.367494 +vt 0.576929 0.360107 +vt 0.565787 0.306676 +vt 0.571762 0.306591 +vt 0.571198 0.299784 +vt 0.565186 0.300792 +vt 0.570940 0.291528 +vt 0.564626 0.293429 +vt 0.051153 0.332891 +vt 0.052113 0.342364 +vt 0.052375 0.351802 +vt 0.054464 0.377890 +vt 0.050237 0.377475 +vt 0.050218 0.383318 +vt 0.053344 0.383065 +vt 0.047248 0.377702 +vt 0.047287 0.383632 +vt 0.047411 0.391423 +vt 0.050542 0.391218 +vt 0.053731 0.391035 +vt 0.044036 0.280273 +vt 0.041294 0.279760 +vt 0.042443 0.286289 +vt 0.045101 0.286661 +vt 0.043956 0.294229 +vt 0.046606 0.294451 +vt 0.047008 0.307150 +vt 0.047978 0.311309 +vt 0.044027 0.307160 +vt 0.044880 0.311318 +vt 0.045703 0.316149 +vt 0.048880 0.316107 +vt 0.051654 0.360963 +vt 0.050682 0.368424 +vt 0.056386 0.408960 +vt 0.052166 0.408215 +vt 0.052826 0.412123 +vt 0.057320 0.413104 +vt 0.053337 0.413628 +vt 0.057934 0.414680 +vt 0.048880 0.316107 +vt 0.049984 0.323639 +vt 0.043956 0.294229 +vt 0.045561 0.301491 +vt 0.048467 0.301526 +vt 0.041432 0.293993 +vt 0.042864 0.301380 +vt 0.571937 0.389130 +vt 0.572415 0.381869 +vt 0.566509 0.381774 +vt 0.576651 0.381837 +vt 0.795092 0.900370 +vt 0.790121 0.900243 +vt 0.800230 0.900497 +vt 0.785436 0.900138 +vt 0.790121 0.900243 +vt 0.775345 0.883596 +vt 0.776278 0.890384 +vt 0.780701 0.889951 +vt 0.771882 0.884406 +vt 0.772186 0.890715 +vt 0.768112 0.884473 +vt 0.767522 0.890757 +vt 0.764234 0.884276 +vt 0.762467 0.890643 +vt 0.557694 0.381555 +vt 0.547000 0.381124 +vt 0.557863 0.376067 +vt 0.024493 0.301927 +vt 0.027555 0.301718 +vt 0.020647 0.302199 +vt 0.030482 0.301485 +vt 0.033254 0.301279 +vt 0.035743 0.301169 +vt 0.038069 0.301163 +vt 0.040400 0.301250 +vt 0.042864 0.301380 +vt 0.580445 0.382027 +vt 0.584752 0.389694 +vt 0.584303 0.382232 +vt 0.583697 0.375206 +vt 0.580518 0.374908 +vt 0.008733 0.303166 +vt 0.011204 0.302972 +vt 0.007548 0.303243 +vt 0.053893 0.368214 +vt 0.050682 0.368424 +vt 0.050247 0.373238 +vt 0.053590 0.373020 +vt 0.047753 0.368646 +vt 0.047316 0.373466 +vt 0.572453 0.315571 +vt 0.572079 0.310874 +vt 0.566234 0.310833 +vt 0.576593 0.315611 +vt 0.576332 0.311198 +vt 0.801289 0.973514 +vt 0.794646 0.973149 +vt 0.807020 0.973630 +vt 0.786467 0.972327 +vt 0.777308 0.971089 +vt 0.794664 0.966922 +vt 0.786215 0.966399 +vt 0.965989 0.795444 +vt 0.969633 0.795381 +vt 0.962346 0.795507 +vt 0.962576 0.800344 +vt 0.966139 0.799856 +vt 0.765216 0.961269 +vt 0.770364 0.961488 +vt 0.760069 0.961050 +vt 0.760373 0.965000 +vt 0.765771 0.965677 +vt 0.771169 0.966353 +vt 0.557575 0.310873 +vt 0.547210 0.310919 +vt 0.566234 0.310833 +vt 0.019014 0.376187 +vt 0.021040 0.375464 +vt 0.017753 0.377123 +vt 0.031210 0.374792 +vt 0.033963 0.374653 +vt 0.027971 0.374929 +vt 0.036377 0.374517 +vt 0.038484 0.374361 +vt 0.040356 0.374166 +vt 0.042312 0.373943 +vt 0.044650 0.373708 +vt 0.047316 0.373466 +vt 0.057455 0.368024 +vt 0.057283 0.372633 +vt 0.061293 0.372379 +vt 0.057422 0.375693 +vt 0.061437 0.375171 +vt 0.024426 0.370156 +vt 0.024287 0.375093 +vt 0.023372 0.379637 +vt 0.014305 0.295357 +vt 0.015683 0.302599 +vt 0.016697 0.308937 +vt 0.010776 0.281851 +vt 0.012456 0.287864 +vt 0.021977 0.353640 +vt 0.023613 0.362717 +vt 0.018268 0.335316 +vt 0.019874 0.344321 +vt 0.021924 0.385979 +vt 0.020147 0.393662 +vt 0.017956 0.319938 +vt 0.017894 0.327012 +vt 0.017530 0.314310 +vt 0.016806 0.407568 +vt 0.016049 0.410764 +vt 0.014543 0.405624 +vt 0.014030 0.408410 +vt 0.015735 0.412191 +vt 0.018289 0.401443 +vt 0.021559 0.402532 +vt 0.015585 0.400250 +vt 0.053731 0.391035 +vt 0.050542 0.391218 +vt 0.051301 0.400456 +vt 0.054993 0.400722 +vt 0.047646 0.400274 +vt 0.570940 0.291528 +vt 0.571233 0.283177 +vt 0.564315 0.285654 +vt 0.575568 0.290239 +vt 0.576258 0.281297 +vt 0.796484 0.998170 +vt 0.802864 0.997281 +vt 0.802128 0.996030 +vt 0.795449 0.996808 +vt 0.808580 0.996027 +vt 0.808450 0.994894 +vt 0.808168 0.992369 +vt 0.801563 0.993258 +vt 0.780619 0.997707 +vt 0.788971 0.998370 +vt 0.788136 0.996921 +vt 0.796484 0.998170 +vt 0.795449 0.996808 +vt 0.787502 0.993703 +vt 0.780050 0.993091 +vt 0.024766 0.402959 +vt 0.027815 0.402901 +vt 0.030773 0.402640 +vt 0.033814 0.402129 +vt 0.037089 0.401337 +vt 0.040535 0.400606 +vt 0.044058 0.400274 +vt 0.579615 0.290920 +vt 0.580197 0.281522 +vt 0.583461 0.292846 +vt 0.583622 0.283084 +vt 0.013972 0.399520 +vt 0.013023 0.399110 +vt 0.013208 0.404397 +vt 0.545496 0.294906 +vt 0.555804 0.294484 +vt 0.555007 0.287129 +vt 0.544286 0.287904 +vt 0.564315 0.285654 +vt 0.766232 0.986015 +vt 0.769802 0.986918 +vt 0.763347 0.984565 +vt 0.765274 0.992264 +vt 0.764191 0.992213 +vt 0.776704 0.980113 +vt 0.774440 0.987059 +vt 0.779979 0.986863 +vt 0.011844 0.275156 +vt 0.009452 0.277280 +vt 0.009866 0.278696 +vt 0.012376 0.276711 +vt 0.007841 0.279385 +vt 0.008136 0.280657 +vt 0.043275 0.275352 +vt 0.040452 0.274722 +vt 0.040706 0.276297 +vt 0.043503 0.276889 +vt 0.037758 0.274057 +vt 0.038031 0.275673 +vt 0.565461 0.407140 +vt 0.571055 0.407942 +vt 0.571129 0.406444 +vt 0.565525 0.405690 +vt 0.575404 0.408333 +vt 0.575471 0.406815 +vt 0.802263 0.875419 +vt 0.796032 0.875358 +vt 0.807531 0.875485 +vt 0.807042 0.869128 +vt 0.802462 0.869075 +vt 0.531141 0.408411 +vt 0.534563 0.405924 +vt 0.534547 0.404593 +vt 0.531105 0.406968 +vt 0.538367 0.404156 +vt 0.538367 0.402905 +vt 0.534540 0.401664 +vt 0.543022 0.403661 +vt 0.543026 0.402429 +vt 0.549324 0.404310 +vt 0.549337 0.403037 +vt 0.549341 0.400225 +vt 0.543022 0.399716 +vt 0.557538 0.405719 +vt 0.557576 0.404358 +vt 0.557628 0.401346 +vt 0.007841 0.279385 +vt 0.006916 0.280693 +vt 0.007145 0.281876 +vt 0.008136 0.280657 +vt 0.006362 0.281474 +vt 0.006560 0.282602 +vt 0.006916 0.285110 +vt 0.007602 0.284508 +vt 0.008767 0.283492 +vt 0.018542 0.273059 +vt 0.014983 0.273806 +vt 0.015576 0.275440 +vt 0.019149 0.274727 +vt 0.025798 0.272347 +vt 0.022179 0.272579 +vt 0.022771 0.274264 +vt 0.026333 0.274043 +vt 0.032521 0.272762 +vt 0.029325 0.272410 +vt 0.029754 0.274111 +vt 0.032851 0.274453 +vt 0.035227 0.273359 +vt 0.035514 0.275018 +vt 0.580009 0.408661 +vt 0.580056 0.407126 +vt 0.584923 0.408993 +vt 0.584943 0.407441 +vt 0.788166 0.875263 +vt 0.779217 0.875002 +vt 0.796032 0.875358 +vt 0.788755 0.869122 +vt 0.708067 0.153600 +vt 0.702290 0.156165 +vt 0.702446 0.156413 +vt 0.708163 0.153874 +vt 0.698027 0.159939 +vt 0.698239 0.160151 +vt 0.698457 0.160372 +vt 0.702608 0.156674 +vt 0.708265 0.154165 +vt 0.837209 0.587558 +vt 0.829171 0.586423 +vt 0.829122 0.586722 +vt 0.837150 0.587824 +vt 0.822056 0.586281 +vt 0.822011 0.586586 +vt 0.821729 0.586909 +vt 0.828901 0.587038 +vt 0.837017 0.588109 +vt 0.724091 0.152189 +vt 0.716107 0.152470 +vt 0.716156 0.152761 +vt 0.724109 0.152491 +vt 0.716208 0.153069 +vt 0.724129 0.152808 +vt 0.856325 0.602561 +vt 0.856251 0.597171 +vt 0.856035 0.597179 +vt 0.856064 0.602515 +vt 0.853489 0.593780 +vt 0.853332 0.593872 +vt 0.853121 0.593992 +vt 0.855773 0.597203 +vt 0.855775 0.602471 +vt 0.694146 0.164738 +vt 0.694396 0.164903 +vt 0.691050 0.171340 +vt 0.691322 0.171441 +vt 0.691607 0.171546 +vt 0.694656 0.165072 +vt 0.854808 0.621689 +vt 0.855929 0.611611 +vt 0.855652 0.611554 +vt 0.854535 0.621659 +vt 0.855353 0.611494 +vt 0.854238 0.621628 +vt 0.689397 0.180092 +vt 0.689679 0.180117 +vt 0.689345 0.188672 +vt 0.689629 0.188621 +vt 0.689927 0.188568 +vt 0.689977 0.180142 +vt 0.938186 0.157514 +vt 0.937910 0.154702 +vt 0.937589 0.154703 +vt 0.937865 0.157524 +vt 0.937567 0.151220 +vt 0.937246 0.151208 +vt 0.936938 0.151196 +vt 0.937280 0.154704 +vt 0.937556 0.157535 +vt 0.935450 0.231542 +vt 0.935848 0.222579 +vt 0.935541 0.222553 +vt 0.935147 0.231522 +vt 0.936565 0.213195 +vt 0.936258 0.213168 +vt 0.935938 0.213140 +vt 0.935222 0.222526 +vt 0.934830 0.231502 +vt 0.726454 0.218887 +vt 0.729985 0.220222 +vt 0.730109 0.219934 +vt 0.726558 0.218592 +vt 0.733521 0.221554 +vt 0.733659 0.221272 +vt 0.733789 0.221005 +vt 0.730225 0.219662 +vt 0.726656 0.218316 +vt 0.933452 0.231415 +vt 0.933836 0.222408 +vt 0.933517 0.222381 +vt 0.933136 0.231395 +vt 0.934551 0.213018 +vt 0.934231 0.212990 +vt 0.933924 0.212963 +vt 0.933211 0.222355 +vt 0.932832 0.231376 +vt 0.719052 0.218874 +vt 0.722445 0.219597 +vt 0.722515 0.219317 +vt 0.719100 0.218594 +vt 0.725788 0.220794 +vt 0.725885 0.220518 +vt 0.725989 0.220223 +vt 0.722590 0.219016 +vt 0.719151 0.218289 +vt 0.712151 0.218510 +vt 0.715544 0.218815 +vt 0.715589 0.218539 +vt 0.712221 0.218242 +vt 0.715638 0.218235 +vt 0.712297 0.217948 +vt 0.841437 0.645640 +vt 0.845672 0.643942 +vt 0.845470 0.643798 +vt 0.841286 0.645391 +vt 0.848323 0.642140 +vt 0.848082 0.642109 +vt 0.847890 0.642075 +vt 0.845301 0.643654 +vt 0.841147 0.645145 +vt 0.832162 0.650738 +vt 0.837359 0.649276 +vt 0.837262 0.648980 +vt 0.832109 0.650429 +vt 0.842434 0.647148 +vt 0.842294 0.646902 +vt 0.842143 0.646654 +vt 0.837163 0.648679 +vt 0.832056 0.650112 +vt 0.938202 0.287901 +vt 0.938551 0.286663 +vt 0.938272 0.286707 +vt 0.937920 0.287943 +vt 0.938651 0.285850 +vt 0.938373 0.285897 +vt 0.938108 0.285942 +vt 0.938007 0.286750 +vt 0.937652 0.287983 +vt 0.690843 0.194899 +vt 0.691119 0.194788 +vt 0.693504 0.199834 +vt 0.693767 0.199679 +vt 0.694039 0.199519 +vt 0.691408 0.194673 +vt 0.820120 0.588328 +vt 0.813827 0.588294 +vt 0.813826 0.588614 +vt 0.820114 0.588647 +vt 0.808242 0.588218 +vt 0.808240 0.588538 +vt 0.808239 0.588844 +vt 0.813825 0.588920 +vt 0.820109 0.588952 +vt 0.822346 0.651053 +vt 0.826951 0.651180 +vt 0.826934 0.650866 +vt 0.822352 0.650737 +vt 0.826917 0.650544 +vt 0.822358 0.650413 +vt 0.816044 0.650716 +vt 0.818853 0.650886 +vt 0.818871 0.650571 +vt 0.816061 0.650403 +vt 0.818889 0.650247 +vt 0.816079 0.650080 +vt 0.816155 0.648703 +vt 0.818966 0.648874 +vt 0.818984 0.648551 +vt 0.816173 0.648380 +vt 0.822385 0.649043 +vt 0.822392 0.648719 +vt 0.822398 0.648404 +vt 0.819001 0.648236 +vt 0.816191 0.648067 +vt 0.939114 0.195794 +vt 0.939783 0.189655 +vt 0.939485 0.189658 +vt 0.938811 0.195781 +vt 0.940032 0.184528 +vt 0.939738 0.184545 +vt 0.939430 0.184562 +vt 0.939173 0.189661 +vt 0.938494 0.195768 +vt 0.938089 0.184638 +vt 0.938231 0.179388 +vt 0.937923 0.179408 +vt 0.937781 0.184655 +vt 0.938335 0.173766 +vt 0.938024 0.173782 +vt 0.937726 0.173798 +vt 0.937628 0.179427 +vt 0.937487 0.184671 +vt 0.938738 0.292246 +vt 0.939436 0.289695 +vt 0.939164 0.289732 +vt 0.938459 0.292283 +vt 0.940001 0.287633 +vt 0.939733 0.287673 +vt 0.939451 0.287715 +vt 0.938876 0.289772 +vt 0.938163 0.292321 +vt 0.935832 0.203754 +vt 0.935513 0.203730 +vt 0.937113 0.195711 +vt 0.936797 0.195697 +vt 0.936494 0.195685 +vt 0.935207 0.203707 +vt 0.934851 0.246563 +vt 0.935053 0.239691 +vt 0.934756 0.239685 +vt 0.934560 0.246574 +vt 0.934445 0.239678 +vt 0.934255 0.246586 +vt 0.822056 0.586281 +vt 0.815139 0.586252 +vt 0.815111 0.586558 +vt 0.822011 0.586586 +vt 0.808251 0.586188 +vt 0.808250 0.586495 +vt 0.808248 0.586815 +vt 0.814920 0.586880 +vt 0.821729 0.586909 +vt 0.590839 0.409090 +vt 0.590824 0.407960 +vt 0.590519 0.407957 +vt 0.590534 0.409088 +vt 0.590790 0.405441 +vt 0.590485 0.405439 +vt 0.590166 0.405436 +vt 0.590200 0.407954 +vt 0.590216 0.409085 +vt 0.587094 0.337455 +vt 0.587331 0.327637 +vt 0.587018 0.327642 +vt 0.586826 0.337454 +vt 0.587331 0.319108 +vt 0.587011 0.319118 +vt 0.586705 0.319127 +vt 0.586721 0.327646 +vt 0.586590 0.337454 +vt 0.587039 0.354726 +vt 0.586908 0.346307 +vt 0.586737 0.346305 +vt 0.586927 0.354725 +vt 0.586633 0.346304 +vt 0.586901 0.354724 +vt 0.589272 0.319047 +vt 0.588947 0.313720 +vt 0.588647 0.313731 +vt 0.589006 0.319057 +vt 0.588553 0.309452 +vt 0.588247 0.309460 +vt 0.587927 0.309470 +vt 0.588331 0.313742 +vt 0.588715 0.319067 +vt 0.588880 0.354739 +vt 0.588623 0.346321 +vt 0.588429 0.346319 +vt 0.588613 0.354737 +vt 0.588762 0.337457 +vt 0.588613 0.337458 +vt 0.588410 0.337457 +vt 0.588193 0.346317 +vt 0.588323 0.354735 +vt 0.590240 0.370839 +vt 0.589555 0.363406 +vt 0.589254 0.363405 +vt 0.589934 0.370838 +vt 0.588939 0.363404 +vt 0.589615 0.370838 +vt 0.846284 0.590339 +vt 0.846184 0.590528 +vt 0.846040 0.590743 +vt 0.733752 0.152039 +vt 0.729707 0.152098 +vt 0.729713 0.152404 +vt 0.733756 0.152346 +vt 0.724091 0.152189 +vt 0.724109 0.152491 +vt 0.724129 0.152808 +vt 0.729720 0.152724 +vt 0.733761 0.152667 +vt 0.700282 0.209359 +vt 0.703380 0.212561 +vt 0.703593 0.212333 +vt 0.700511 0.209149 +vt 0.706238 0.214952 +vt 0.706419 0.214710 +vt 0.706605 0.214457 +vt 0.703812 0.212099 +vt 0.700748 0.208933 +vt 0.850781 0.635549 +vt 0.852573 0.629773 +vt 0.852314 0.629790 +vt 0.850543 0.635599 +vt 0.852026 0.629811 +vt 0.850268 0.635657 +vt 0.709090 0.217089 +vt 0.709215 0.216833 +vt 0.709345 0.216558 +vt 0.850155 0.642314 +vt 0.850660 0.639469 +vt 0.850445 0.639504 +vt 0.849964 0.642280 +vt 0.850182 0.639545 +vt 0.849722 0.642249 +vt 0.935680 0.257312 +vt 0.935085 0.252021 +vt 0.934799 0.252050 +vt 0.935398 0.257356 +vt 0.934500 0.252080 +vt 0.935102 0.257401 +vt 0.589025 0.296444 +vt 0.589795 0.288654 +vt 0.589490 0.288647 +vt 0.588719 0.296440 +vt 0.590492 0.282297 +vt 0.590186 0.282290 +vt 0.589867 0.282282 +vt 0.589171 0.288639 +vt 0.588400 0.296436 +vt 0.940300 0.173663 +vt 0.940416 0.168016 +vt 0.940114 0.168028 +vt 0.940001 0.173678 +vt 0.940492 0.163524 +vt 0.940187 0.163535 +vt 0.939870 0.163547 +vt 0.939799 0.168041 +vt 0.939690 0.173695 +vt 0.590601 0.380407 +vt 0.590546 0.375822 +vt 0.590240 0.375821 +vt 0.590295 0.380407 +vt 0.589921 0.375821 +vt 0.589976 0.380407 +vt 0.940421 0.285548 +vt 0.940287 0.284460 +vt 0.940019 0.284507 +vt 0.940156 0.285594 +vt 0.939761 0.281904 +vt 0.939490 0.281953 +vt 0.939206 0.282004 +vt 0.939739 0.284556 +vt 0.939878 0.285641 +vt 0.810687 0.650199 +vt 0.813361 0.650480 +vt 0.813369 0.650168 +vt 0.810680 0.649889 +vt 0.813376 0.649846 +vt 0.810671 0.649567 +vt 0.940447 0.160091 +vt 0.940361 0.159102 +vt 0.940051 0.159117 +vt 0.940139 0.160108 +vt 0.940197 0.157445 +vt 0.939888 0.157456 +vt 0.939567 0.157467 +vt 0.939731 0.159133 +vt 0.939819 0.160125 +vt 0.590663 0.393933 +vt 0.590622 0.386723 +vt 0.590317 0.386722 +vt 0.590358 0.393932 +vt 0.589998 0.386722 +vt 0.590039 0.393931 +vt 0.937548 0.270487 +vt 0.936507 0.263621 +vt 0.936227 0.263671 +vt 0.937271 0.270538 +vt 0.935934 0.263724 +vt 0.936981 0.270592 +vt 0.590785 0.278935 +vt 0.590480 0.278930 +vt 0.590186 0.282290 +vt 0.590818 0.277409 +vt 0.590513 0.277408 +vt 0.590193 0.277407 +vt 0.590161 0.278925 +vt 0.589867 0.282282 +vt 0.586528 0.309509 +vt 0.586542 0.303703 +vt 0.586223 0.303706 +vt 0.586209 0.309518 +vt 0.587003 0.296418 +vt 0.586683 0.296414 +vt 0.586377 0.296410 +vt 0.585917 0.303708 +vt 0.585903 0.309527 +vt 0.935710 0.270829 +vt 0.934653 0.263953 +vt 0.934361 0.264006 +vt 0.935421 0.270883 +vt 0.933808 0.257599 +vt 0.933512 0.257644 +vt 0.933230 0.257687 +vt 0.934081 0.264056 +vt 0.935144 0.270935 +vt 0.588644 0.393926 +vt 0.588603 0.386719 +vt 0.588283 0.386719 +vt 0.588325 0.393924 +vt 0.588581 0.380406 +vt 0.588262 0.380406 +vt 0.587956 0.380406 +vt 0.587978 0.386718 +vt 0.588020 0.393923 +vt 0.938436 0.160197 +vt 0.938350 0.159203 +vt 0.938029 0.159219 +vt 0.938116 0.160214 +vt 0.938186 0.157513 +vt 0.937865 0.157524 +vt 0.937720 0.159235 +vt 0.937807 0.160230 +vt 0.810636 0.648174 +vt 0.813408 0.648461 +vt 0.813416 0.648139 +vt 0.810628 0.647852 +vt 0.813424 0.647828 +vt 0.810620 0.647543 +vt 0.938504 0.284774 +vt 0.938224 0.284823 +vt 0.937958 0.282229 +vt 0.937674 0.282281 +vt 0.937404 0.282329 +vt 0.937956 0.284870 +vt 0.588772 0.405425 +vt 0.588709 0.400539 +vt 0.588391 0.400537 +vt 0.588453 0.405422 +vt 0.588085 0.400535 +vt 0.588148 0.405420 +vt 0.938432 0.168096 +vt 0.938118 0.168109 +vt 0.938494 0.163599 +vt 0.938177 0.163610 +vt 0.937872 0.163622 +vt 0.937816 0.168121 +vt 0.587774 0.288606 +vt 0.587455 0.288598 +vt 0.588471 0.282248 +vt 0.588152 0.282241 +vt 0.587847 0.282233 +vt 0.587149 0.288591 +vt 0.937958 0.282229 +vt 0.936925 0.277312 +vt 0.936637 0.277365 +vt 0.937675 0.282281 +vt 0.936363 0.277415 +vt 0.937404 0.282329 +vt 0.848323 0.642140 +vt 0.848585 0.639727 +vt 0.848261 0.639952 +vt 0.847751 0.635172 +vt 0.847029 0.637330 +vt 0.846724 0.637712 +vt 0.848035 0.640040 +vt 0.695213 0.198833 +vt 0.698427 0.203653 +vt 0.698681 0.203460 +vt 0.695485 0.198672 +vt 0.701757 0.208012 +vt 0.701994 0.207795 +vt 0.702223 0.207586 +vt 0.698927 0.203274 +vt 0.695748 0.198518 +vt 0.691254 0.188333 +vt 0.692673 0.194174 +vt 0.692961 0.194059 +vt 0.691552 0.188279 +vt 0.693237 0.193948 +vt 0.691835 0.188228 +vt 0.704741 0.211102 +vt 0.704960 0.210868 +vt 0.707398 0.213359 +vt 0.707585 0.213107 +vt 0.707766 0.212864 +vt 0.705173 0.210640 +vt 0.853612 0.602880 +vt 0.854261 0.597417 +vt 0.854042 0.597114 +vt 0.853888 0.599281 +vt 0.851818 0.594717 +vt 0.851608 0.594838 +vt 0.851451 0.594930 +vt 0.853836 0.597034 +vt 0.853689 0.598701 +vt 0.708718 0.155478 +vt 0.703310 0.157833 +vt 0.703472 0.158094 +vt 0.708820 0.155769 +vt 0.699397 0.161326 +vt 0.699617 0.161546 +vt 0.699828 0.161759 +vt 0.703628 0.158342 +vt 0.708916 0.156042 +vt 0.590790 0.405441 +vt 0.590728 0.400552 +vt 0.590423 0.400550 +vt 0.590485 0.405438 +vt 0.590104 0.400548 +vt 0.590166 0.405436 +vt 0.588529 0.375821 +vt 0.588216 0.375821 +vt 0.588244 0.370835 +vt 0.587977 0.370835 +vt 0.587741 0.370834 +vt 0.587919 0.375821 +vt 0.587616 0.363398 +vt 0.587445 0.363398 +vt 0.587341 0.363398 +vt 0.586933 0.313793 +vt 0.586614 0.313804 +vt 0.586308 0.313815 +vt 0.589114 0.327609 +vt 0.588921 0.327613 +vt 0.588685 0.327618 +vt 0.588566 0.303686 +vt 0.588261 0.303688 +vt 0.587941 0.303691 +vt 0.588471 0.282248 +vt 0.588765 0.278902 +vt 0.588446 0.278897 +vt 0.588152 0.282241 +vt 0.588797 0.277402 +vt 0.588478 0.277401 +vt 0.588173 0.277400 +vt 0.588140 0.278892 +vt 0.587847 0.282233 +vt 0.588822 0.409071 +vt 0.588806 0.407942 +vt 0.588488 0.407939 +vt 0.588503 0.409068 +vt 0.588772 0.405425 +vt 0.588453 0.405422 +vt 0.588183 0.407936 +vt 0.588199 0.409065 +vt 0.933188 0.252213 +vt 0.932888 0.252244 +vt 0.932920 0.246636 +vt 0.932616 0.246648 +vt 0.932325 0.246659 +vt 0.932602 0.252273 +vt 0.940177 0.179261 +vt 0.939882 0.179280 +vt 0.939574 0.179300 +vt 0.936843 0.292492 +vt 0.937594 0.289950 +vt 0.937307 0.289990 +vt 0.936548 0.292530 +vt 0.938202 0.287901 +vt 0.937920 0.287943 +vt 0.937652 0.287983 +vt 0.937034 0.290028 +vt 0.936269 0.292566 +vt 0.940001 0.287633 +vt 0.940326 0.286378 +vt 0.940061 0.286420 +vt 0.939733 0.287673 +vt 0.939782 0.286465 +vt 0.939451 0.287715 +vt 0.937813 0.189677 +vt 0.937502 0.189680 +vt 0.937204 0.189683 +vt 0.940198 0.157445 +vt 0.939924 0.154697 +vt 0.939614 0.154698 +vt 0.939888 0.157456 +vt 0.939585 0.151296 +vt 0.939276 0.151285 +vt 0.938955 0.151272 +vt 0.939294 0.154699 +vt 0.939567 0.157467 +vt 0.719392 0.216854 +vt 0.722930 0.217628 +vt 0.723005 0.217327 +vt 0.719443 0.216550 +vt 0.723076 0.217048 +vt 0.719491 0.216270 +vt 0.831835 0.648776 +vt 0.836746 0.647431 +vt 0.836646 0.647130 +vt 0.831782 0.648459 +vt 0.836549 0.646834 +vt 0.831730 0.648150 +vt 0.847136 0.644811 +vt 0.846966 0.644667 +vt 0.846765 0.644523 +vt 0.938494 0.163599 +vt 0.938489 0.161256 +vt 0.938170 0.161270 +vt 0.938177 0.163610 +vt 0.937863 0.161284 +vt 0.940497 0.161166 +vt 0.940189 0.161180 +vt 0.940187 0.163535 +vt 0.939870 0.161194 +vt 0.939870 0.163547 +vt 0.709911 0.215303 +vt 0.710042 0.215028 +vt 0.712641 0.216551 +vt 0.712717 0.216257 +vt 0.712788 0.215988 +vt 0.710167 0.214772 +vt 0.696840 0.204856 +vt 0.697086 0.204670 +vt 0.697340 0.204477 +vt 0.826843 0.649180 +vt 0.826826 0.648858 +vt 0.826809 0.648544 +vt 0.715871 0.216785 +vt 0.715920 0.216481 +vt 0.715965 0.216205 +vt 0.937846 0.203905 +vt 0.937539 0.203882 +vt 0.937220 0.203858 +vt 0.938746 0.276975 +vt 0.938472 0.277026 +vt 0.939490 0.281953 +vt 0.938185 0.277079 +vt 0.939206 0.282004 +vt 0.933085 0.239651 +vt 0.932774 0.239644 +vt 0.932477 0.239638 +vt 0.729190 0.222077 +vt 0.729307 0.221805 +vt 0.732637 0.223364 +vt 0.732767 0.223097 +vt 0.732905 0.222815 +vt 0.729430 0.221517 +vt 0.945455 0.087172 +vt 0.945079 0.079697 +vt 0.944670 0.079650 +vt 0.945664 0.087287 +vt 0.944889 0.070987 +vt 0.944209 0.070844 +vt 0.943530 0.070701 +vt 0.944262 0.079602 +vt 0.945873 0.087403 +vt 0.692863 0.172002 +vt 0.691301 0.180251 +vt 0.691599 0.180277 +vt 0.693148 0.172107 +vt 0.691881 0.180301 +vt 0.693420 0.172208 +vt 0.945009 0.060217 +vt 0.944635 0.060093 +vt 0.945315 0.048211 +vt 0.945594 0.048174 +vt 0.945873 0.048136 +vt 0.944262 0.059968 +vt 0.695784 0.165803 +vt 0.696043 0.165972 +vt 0.696293 0.166136 +vt 0.733780 0.154069 +vt 0.729749 0.154127 +vt 0.729756 0.154447 +vt 0.733785 0.154390 +vt 0.724218 0.154207 +vt 0.724238 0.154524 +vt 0.724257 0.154826 +vt 0.729762 0.154752 +vt 0.733789 0.154696 +vt 0.851819 0.594717 +vt 0.845130 0.591835 +vt 0.844995 0.592051 +vt 0.851608 0.594838 +vt 0.836249 0.589420 +vt 0.836186 0.589705 +vt 0.836136 0.589970 +vt 0.844897 0.592239 +vt 0.851450 0.594930 +vt 0.724219 0.154207 +vt 0.716445 0.154452 +vt 0.716497 0.154761 +vt 0.724238 0.154524 +vt 0.716546 0.155052 +vt 0.588797 0.277402 +vt 0.588765 0.278902 +vt 0.589107 0.278908 +vt 0.589139 0.277403 +vt 0.588813 0.282257 +vt 0.589169 0.282265 +vt 0.589463 0.278913 +vt 0.589495 0.277404 +vt 0.589818 0.278919 +vt 0.589851 0.277406 +vt 0.589525 0.282274 +vt 0.589867 0.282282 +vt 0.590161 0.278925 +vt 0.590193 0.277407 +vt 0.936924 0.277312 +vt 0.937233 0.277255 +vt 0.936022 0.270771 +vt 0.937958 0.282229 +vt 0.938264 0.282174 +vt 0.938582 0.282117 +vt 0.937554 0.277195 +vt 0.936346 0.270711 +vt 0.937876 0.277136 +vt 0.936670 0.270650 +vt 0.938901 0.282060 +vt 0.939206 0.282004 +vt 0.938185 0.277079 +vt 0.936981 0.270592 +vt 0.588644 0.393926 +vt 0.589051 0.400541 +vt 0.588986 0.393927 +vt 0.588772 0.405425 +vt 0.589114 0.405428 +vt 0.589469 0.405430 +vt 0.589407 0.400543 +vt 0.589341 0.393928 +vt 0.589762 0.400546 +vt 0.589697 0.393930 +vt 0.589825 0.405433 +vt 0.590166 0.405436 +vt 0.590104 0.400548 +vt 0.590039 0.393931 +vt 0.938436 0.160197 +vt 0.938489 0.161256 +vt 0.938829 0.161241 +vt 0.938776 0.160179 +vt 0.938494 0.163599 +vt 0.938832 0.163586 +vt 0.939182 0.163573 +vt 0.939180 0.161225 +vt 0.939127 0.160161 +vt 0.939531 0.161209 +vt 0.939479 0.160142 +vt 0.939532 0.163560 +vt 0.939870 0.163547 +vt 0.939870 0.161194 +vt 0.939818 0.160124 +vt 0.937567 0.151220 +vt 0.937910 0.154702 +vt 0.938250 0.154701 +vt 0.937908 0.151233 +vt 0.938186 0.157514 +vt 0.938526 0.157502 +vt 0.938877 0.157490 +vt 0.938602 0.154701 +vt 0.938261 0.151246 +vt 0.938953 0.154700 +vt 0.938614 0.151260 +vt 0.939228 0.157478 +vt 0.939294 0.154699 +vt 0.938651 0.285850 +vt 0.938551 0.286663 +vt 0.938852 0.286614 +vt 0.938951 0.285799 +vt 0.938202 0.287901 +vt 0.938507 0.287856 +vt 0.938827 0.287808 +vt 0.939166 0.286564 +vt 0.939265 0.285745 +vt 0.939481 0.286513 +vt 0.939578 0.285692 +vt 0.939146 0.287760 +vt 0.939782 0.286465 +vt 0.588244 0.370835 +vt 0.588529 0.375821 +vt 0.588868 0.375821 +vt 0.588565 0.370836 +vt 0.588581 0.380406 +vt 0.588923 0.380406 +vt 0.589278 0.380407 +vt 0.589223 0.375821 +vt 0.588918 0.370836 +vt 0.589579 0.375821 +vt 0.589273 0.370837 +vt 0.589634 0.380407 +vt 0.589976 0.380407 +vt 0.589921 0.375821 +vt 0.938560 0.179366 +vt 0.938668 0.173749 +vt 0.938418 0.184619 +vt 0.938760 0.184600 +vt 0.938902 0.179344 +vt 0.939013 0.173730 +vt 0.939244 0.179322 +vt 0.939358 0.173712 +vt 0.939101 0.184581 +vt 0.939430 0.184562 +vt 0.939574 0.179300 +vt 0.939690 0.173695 +vt 0.587003 0.296418 +vt 0.586542 0.303703 +vt 0.586885 0.303700 +vt 0.587345 0.296422 +vt 0.586529 0.309509 +vt 0.586871 0.309500 +vt 0.587228 0.309489 +vt 0.587242 0.303697 +vt 0.587701 0.296427 +vt 0.587598 0.303694 +vt 0.588058 0.296431 +vt 0.587585 0.309479 +vt 0.587928 0.309470 +vt 0.588400 0.296436 +vt 0.932920 0.246636 +vt 0.933188 0.252213 +vt 0.933509 0.252181 +vt 0.933247 0.246624 +vt 0.933808 0.257599 +vt 0.934125 0.257550 +vt 0.934455 0.257500 +vt 0.933844 0.252147 +vt 0.933588 0.246611 +vt 0.934178 0.252113 +vt 0.933928 0.246598 +vt 0.934785 0.257449 +vt 0.935102 0.257401 +vt 0.934500 0.252080 +vt 0.934255 0.246586 +vt 0.848323 0.642140 +vt 0.845672 0.643942 +vt 0.845929 0.644087 +vt 0.848648 0.642168 +vt 0.841437 0.645640 +vt 0.841608 0.645892 +vt 0.841790 0.646147 +vt 0.846218 0.644233 +vt 0.849023 0.642195 +vt 0.846508 0.644378 +vt 0.849397 0.642221 +vt 0.841973 0.646401 +vt 0.842143 0.646654 +vt 0.846765 0.644523 +vt 0.849722 0.642249 +vt 0.712641 0.216551 +vt 0.709772 0.215608 +vt 0.712558 0.216887 +vt 0.707398 0.213359 +vt 0.707203 0.213629 +vt 0.707002 0.213908 +vt 0.709628 0.215931 +vt 0.712469 0.217249 +vt 0.709484 0.216254 +vt 0.712380 0.217611 +vt 0.706801 0.214188 +vt 0.706605 0.214457 +vt 0.712297 0.217948 +vt 0.850909 0.621503 +vt 0.849157 0.629846 +vt 0.850239 0.629891 +vt 0.852185 0.621531 +vt 0.848887 0.635818 +vt 0.849481 0.635804 +vt 0.851102 0.629871 +vt 0.853223 0.621560 +vt 0.853222 0.621560 +vt 0.851102 0.629871 +vt 0.851663 0.629838 +vt 0.853861 0.621593 +vt 0.849481 0.635804 +vt 0.849922 0.635727 +vt 0.850268 0.635657 +vt 0.852026 0.629811 +vt 0.854238 0.621628 +vt 0.701757 0.208012 +vt 0.698427 0.203653 +vt 0.698159 0.203856 +vt 0.701509 0.208239 +vt 0.695213 0.198833 +vt 0.694924 0.199002 +vt 0.694626 0.199176 +vt 0.697883 0.204065 +vt 0.701252 0.208472 +vt 0.697608 0.204274 +vt 0.700997 0.208706 +vt 0.694328 0.199350 +vt 0.694039 0.199519 +vt 0.697340 0.204477 +vt 0.724218 0.154207 +vt 0.729749 0.154127 +vt 0.729742 0.153783 +vt 0.724197 0.153865 +vt 0.733780 0.154069 +vt 0.733775 0.153725 +vt 0.733770 0.153368 +vt 0.729735 0.153425 +vt 0.724174 0.153507 +vt 0.729727 0.153068 +vt 0.724150 0.153150 +vt 0.733765 0.153010 +vt 0.733760 0.152667 +vt 0.729720 0.152724 +vt 0.724129 0.152808 +vt 0.820120 0.588328 +vt 0.827653 0.588441 +vt 0.827708 0.588100 +vt 0.820166 0.587983 +vt 0.836249 0.589420 +vt 0.836345 0.589103 +vt 0.836514 0.588766 +vt 0.827936 0.587743 +vt 0.820450 0.587623 +vt 0.828420 0.587383 +vt 0.821089 0.587258 +vt 0.836772 0.588428 +vt 0.837017 0.588109 +vt 0.828901 0.587038 +vt 0.821729 0.586909 +vt 0.588603 0.386719 +vt 0.588945 0.386720 +vt 0.589300 0.386721 +vt 0.589656 0.386721 +vt 0.589998 0.386722 +vt 0.587039 0.354726 +vt 0.587616 0.363398 +vt 0.587896 0.363399 +vt 0.587296 0.354728 +vt 0.588243 0.363401 +vt 0.587639 0.354730 +vt 0.588598 0.363402 +vt 0.587993 0.354733 +vt 0.588939 0.363404 +vt 0.588323 0.354735 +vt 0.587094 0.337455 +vt 0.587189 0.346309 +vt 0.587414 0.337455 +vt 0.587535 0.346312 +vt 0.587767 0.337456 +vt 0.587886 0.346315 +vt 0.588116 0.337457 +vt 0.588194 0.346317 +vt 0.588410 0.337457 +vt 0.587330 0.319109 +vt 0.587331 0.327637 +vt 0.587671 0.327633 +vt 0.587673 0.319098 +vt 0.588026 0.327628 +vt 0.588030 0.319088 +vt 0.588377 0.327623 +vt 0.588384 0.319077 +vt 0.588685 0.327618 +vt 0.588715 0.319066 +vt 0.586933 0.313793 +vt 0.587276 0.313780 +vt 0.587633 0.313767 +vt 0.587989 0.313754 +vt 0.588331 0.313742 +vt 0.587774 0.288606 +vt 0.588116 0.288614 +vt 0.588472 0.288623 +vt 0.588828 0.288631 +vt 0.589170 0.288639 +vt 0.588806 0.407942 +vt 0.589148 0.407945 +vt 0.588822 0.409071 +vt 0.589163 0.409075 +vt 0.589519 0.409078 +vt 0.589503 0.407948 +vt 0.589859 0.407951 +vt 0.589874 0.409081 +vt 0.590200 0.407954 +vt 0.808242 0.588218 +vt 0.813827 0.588294 +vt 0.813855 0.587950 +vt 0.808243 0.587874 +vt 0.814047 0.587590 +vt 0.808245 0.587516 +vt 0.814483 0.587228 +vt 0.808247 0.587159 +vt 0.814920 0.586880 +vt 0.933452 0.231415 +vt 0.933085 0.239651 +vt 0.933419 0.239658 +vt 0.933790 0.231436 +vt 0.933765 0.239665 +vt 0.934141 0.231459 +vt 0.934111 0.239672 +vt 0.934492 0.231481 +vt 0.934830 0.231502 +vt 0.938432 0.168096 +vt 0.938768 0.168082 +vt 0.939116 0.168068 +vt 0.939464 0.168054 +vt 0.939799 0.168040 +vt 0.729985 0.220222 +vt 0.729850 0.220538 +vt 0.733371 0.221861 +vt 0.726455 0.218887 +vt 0.726341 0.219212 +vt 0.726222 0.219555 +vt 0.729708 0.220869 +vt 0.733213 0.222184 +vt 0.729566 0.221201 +vt 0.733055 0.222507 +vt 0.726102 0.219898 +vt 0.725988 0.220223 +vt 0.732905 0.222815 +vt 0.938504 0.284774 +vt 0.938806 0.284721 +vt 0.939121 0.284665 +vt 0.939437 0.284609 +vt 0.937113 0.195711 +vt 0.936172 0.203780 +vt 0.937452 0.195725 +vt 0.934551 0.213018 +vt 0.934891 0.213048 +vt 0.935245 0.213079 +vt 0.936526 0.203806 +vt 0.937804 0.195739 +vt 0.936880 0.203833 +vt 0.938156 0.195754 +vt 0.935598 0.213110 +vt 0.935938 0.213140 +vt 0.937220 0.203858 +vt 0.938494 0.195768 +vt 0.816156 0.648703 +vt 0.813408 0.648461 +vt 0.813400 0.648802 +vt 0.816137 0.649042 +vt 0.810636 0.648174 +vt 0.810645 0.648516 +vt 0.810654 0.648871 +vt 0.813392 0.649154 +vt 0.816117 0.649391 +vt 0.813384 0.649505 +vt 0.816098 0.649740 +vt 0.810663 0.649225 +vt 0.810671 0.649567 +vt 0.813376 0.649846 +vt 0.816079 0.650080 +vt 0.822385 0.649043 +vt 0.818966 0.648874 +vt 0.818947 0.649213 +vt 0.822379 0.649382 +vt 0.818927 0.649561 +vt 0.822372 0.649728 +vt 0.818908 0.649908 +vt 0.822365 0.650075 +vt 0.818889 0.650247 +vt 0.822358 0.650413 +vt 0.826843 0.649180 +vt 0.826861 0.649517 +vt 0.831890 0.649106 +vt 0.826880 0.649862 +vt 0.831946 0.649444 +vt 0.826899 0.650207 +vt 0.832002 0.649782 +vt 0.826917 0.650544 +vt 0.832056 0.650112 +vt 0.848585 0.639727 +vt 0.849014 0.639691 +vt 0.848323 0.642140 +vt 0.848648 0.642168 +vt 0.849023 0.642195 +vt 0.849438 0.639652 +vt 0.849438 0.639652 +vt 0.849838 0.639596 +vt 0.692673 0.194174 +vt 0.692363 0.194297 +vt 0.691254 0.188333 +vt 0.690930 0.188390 +vt 0.690590 0.188450 +vt 0.692040 0.194423 +vt 0.691717 0.194550 +vt 0.690251 0.188510 +vt 0.689927 0.188568 +vt 0.691407 0.194673 +vt 0.938350 0.159203 +vt 0.938689 0.159186 +vt 0.939040 0.159168 +vt 0.939391 0.159150 +vt 0.939731 0.159133 +vt 0.836746 0.647431 +vt 0.836849 0.647740 +vt 0.836954 0.648055 +vt 0.837060 0.648370 +vt 0.837163 0.648679 +vt 0.704742 0.211102 +vt 0.704512 0.211348 +vt 0.704277 0.211600 +vt 0.704041 0.211853 +vt 0.703812 0.212099 +vt 0.715871 0.216785 +vt 0.715815 0.217134 +vt 0.719333 0.217201 +vt 0.715755 0.217510 +vt 0.719271 0.217572 +vt 0.715694 0.217886 +vt 0.719209 0.217943 +vt 0.715638 0.218236 +vt 0.719151 0.218289 +vt 0.722930 0.217628 +vt 0.722848 0.217965 +vt 0.722760 0.218322 +vt 0.722672 0.218680 +vt 0.937813 0.189677 +vt 0.938147 0.189673 +vt 0.938493 0.189669 +vt 0.938840 0.189665 +vt 0.939173 0.189661 +vt 0.934967 0.263897 +vt 0.935294 0.263839 +vt 0.935620 0.263780 +vt 0.933836 0.222408 +vt 0.934176 0.222437 +vt 0.934529 0.222467 +vt 0.934882 0.222497 +vt 0.937595 0.289950 +vt 0.937907 0.289907 +vt 0.936843 0.292492 +vt 0.937165 0.292450 +vt 0.937503 0.292406 +vt 0.938235 0.289861 +vt 0.938563 0.289816 +vt 0.937841 0.292363 +vt 0.938876 0.289772 +vt 0.691301 0.180251 +vt 0.690978 0.180224 +vt 0.692863 0.172002 +vt 0.692556 0.171890 +vt 0.692235 0.171774 +vt 0.690639 0.180197 +vt 0.690300 0.180169 +vt 0.691914 0.171658 +vt 0.689977 0.180142 +vt 0.852533 0.611302 +vt 0.853576 0.611308 +vt 0.854431 0.602404 +vt 0.854428 0.611361 +vt 0.854990 0.602394 +vt 0.854990 0.602394 +vt 0.854428 0.611361 +vt 0.854987 0.611428 +vt 0.855427 0.602431 +vt 0.855353 0.611494 +vt 0.855775 0.602471 +vt 0.695783 0.165802 +vt 0.695507 0.165623 +vt 0.699398 0.161326 +vt 0.699166 0.161092 +vt 0.698928 0.160849 +vt 0.695220 0.165437 +vt 0.694933 0.165252 +vt 0.698689 0.160606 +vt 0.698457 0.160372 +vt 0.694656 0.165072 +vt 0.851818 0.594717 +vt 0.854261 0.597417 +vt 0.854632 0.597403 +vt 0.852118 0.594550 +vt 0.855042 0.597323 +vt 0.852470 0.594355 +vt 0.852470 0.594355 +vt 0.855042 0.597323 +vt 0.855434 0.597255 +vt 0.852822 0.594160 +vt 0.855773 0.597203 +vt 0.853121 0.593992 +vt 0.703310 0.157833 +vt 0.703137 0.157550 +vt 0.708718 0.155478 +vt 0.708608 0.155158 +vt 0.708492 0.154821 +vt 0.702959 0.157253 +vt 0.702780 0.156957 +vt 0.708376 0.154484 +vt 0.708265 0.154165 +vt 0.702608 0.156674 +vt 0.845130 0.591835 +vt 0.845328 0.591576 +vt 0.851819 0.594717 +vt 0.845571 0.591289 +vt 0.845824 0.591003 +vt 0.846040 0.590743 +vt 0.716445 0.154452 +vt 0.716388 0.154115 +vt 0.716327 0.153761 +vt 0.716266 0.153407 +vt 0.716208 0.153069 +vt 0.827653 0.588441 +vt 0.827631 0.588755 +vt 0.820115 0.588647 +vt 0.827611 0.589053 +vn -0.0051 0.2513 -0.9679 +vn 0.0454 0.2696 -0.9619 +vn 0.0116 0.0707 -0.9974 +vn -0.0469 0.0531 -0.9975 +vn 0.3380 0.3102 -0.8885 +vn 0.3085 0.0939 -0.9466 +vn 0.2956 0.0174 -0.9551 +vn -0.0126 0.0066 -0.9999 +vn -0.0805 -0.0063 -0.9967 +vn 0.0125 0.2210 -0.9752 +vn 0.0322 0.2128 -0.9766 +vn 0.0942 0.3585 -0.9288 +vn 0.0755 0.3814 -0.9213 +vn -0.1624 0.2338 -0.9586 +vn -0.0669 0.3813 -0.9220 +vn 0.0063 0.6370 -0.7708 +vn 0.1951 0.5929 -0.7813 +vn 0.1974 0.5675 -0.7993 +vn 0.1974 0.5676 -0.7993 +vn 0.1994 0.9107 -0.3618 +vn 0.1905 0.8608 -0.4719 +vn -0.0007 0.9452 -0.3265 +vn -0.0881 0.9961 0.0053 +vn 0.0457 0.9988 -0.0167 +vn -0.0263 0.9903 -0.1361 +vn -0.0794 0.9956 0.0507 +vn -0.2050 0.9788 -0.0024 +vn -0.1372 0.9891 0.0526 +vn -0.1230 0.9804 0.1541 +vn -0.0959 0.9816 0.1648 +vn -0.2365 0.9617 0.1384 +vn -0.0756 0.2448 0.9666 +vn -0.1213 0.1662 0.9786 +vn -0.1142 0.1056 0.9878 +vn -0.0672 0.1852 0.9804 +vn -0.3238 -0.2088 0.9228 +vn -0.3131 -0.3119 0.8971 +vn -0.2050 -0.4358 0.8764 +vn -0.0469 -0.3118 0.9490 +vn 0.0091 -0.1863 0.9825 +vn -0.1377 0.2636 0.9548 +vn -0.1099 0.1965 0.9743 +vn -0.1355 0.2278 0.9642 +vn -0.1835 0.2822 0.9416 +vn -0.0604 0.1737 0.9829 +vn -0.0648 0.1989 0.9779 +vn -0.0626 -0.0649 0.9959 +vn -0.1261 -0.0394 0.9912 +vn -0.1684 0.0169 0.9856 +vn -0.1512 0.8037 0.5755 +vn -0.1610 0.8192 0.5504 +vn -0.1143 0.8036 0.5842 +vn -0.1188 0.7568 0.6427 +vn -0.1372 0.8626 0.4870 +vn -0.0718 0.8722 0.4838 +vn -0.0224 0.7912 0.6112 +vn -0.0572 0.7436 0.6662 +vn -0.0687 0.7001 0.7107 +vn 0.0476 0.7987 0.5998 +vn 0.0069 0.8008 0.5989 +vn -0.0049 0.6744 0.7384 +vn 0.0140 0.6931 0.7207 +vn 0.0080 0.8168 0.5769 +vn 0.0292 0.6822 0.7306 +vn 0.0389 0.5519 0.8330 +vn -0.0322 0.5648 0.8246 +vn -0.0355 0.6040 0.7962 +vn 0.1056 0.8601 0.4992 +vn 0.1144 0.8539 0.5076 +vn 0.0999 0.8109 0.5766 +vn 0.0954 0.8182 0.5669 +vn 0.1393 0.8417 0.5216 +vn 0.1141 0.7956 0.5950 +vn 0.0837 0.7482 0.6582 +vn 0.0841 0.7642 0.6395 +vn 0.0855 0.7697 0.6326 +vn -0.0393 0.8517 0.5226 +vn -0.0812 0.8390 0.5381 +vn -0.0943 0.7507 0.6539 +vn -0.0217 0.7502 0.6609 +vn -0.0962 0.8176 0.5677 +vn -0.1141 0.7376 0.6656 +vn -0.1089 0.6594 0.7439 +vn -0.0821 0.6504 0.7552 +vn 0.0119 0.6258 0.7799 +vn -0.0524 0.9636 0.2622 +vn 0.0854 0.9733 0.2131 +vn 0.1626 0.9778 0.1321 +vn 0.0364 0.9757 0.2161 +vn 0.0295 0.9853 0.1682 +vn 0.0937 0.9897 0.1085 +vn 0.0757 0.8576 0.5087 +vn 0.1583 0.8522 0.4988 +vn 0.0680 0.8480 0.5257 +vn 0.1805 0.8064 0.5631 +vn 0.1319 0.8000 0.5853 +vn 0.0850 0.7171 0.6918 +vn 0.1312 0.7419 0.6575 +vn 0.0228 0.6446 0.7642 +vn 0.0689 0.6813 0.7287 +vn 0.0006 0.8406 0.5416 +vn 0.0394 0.7184 0.6945 +vn -0.0216 0.7502 0.6609 +vn 0.0784 0.5803 0.8106 +vn -0.1342 0.4855 0.8639 +vn -0.1044 0.4273 0.8981 +vn -0.1384 0.3817 0.9139 +vn -0.1752 0.4310 0.8852 +vn 0.0233 0.3844 0.9229 +vn 0.0093 0.3406 0.9402 +vn -0.0071 0.2470 0.9690 +vn -0.1682 0.2724 0.9474 +vn -0.2087 0.2876 0.9347 +vn -0.0210 0.4579 0.8887 +vn -0.0257 0.4229 0.9058 +vn -0.0817 0.3361 0.9383 +vn -0.0588 0.3682 0.9279 +vn -0.2536 0.3739 0.8921 +vn -0.3291 0.3014 0.8949 +vn -0.3460 0.1822 0.9204 +vn -0.0939 0.1812 0.9790 +vn -0.0572 0.1909 0.9799 +vn 0.0846 0.4286 0.8995 +vn -0.0129 0.4870 0.8733 +vn 0.0257 0.4123 0.9107 +vn 0.1130 0.3615 0.9255 +vn -0.0520 0.5332 0.8444 +vn -0.0148 0.4570 0.8894 +vn 0.0324 0.2432 0.9694 +vn 0.0681 0.2277 0.9713 +vn 0.1360 0.2155 0.9670 +vn -0.0378 0.5743 0.8178 +vn -0.0854 0.5349 0.8406 +vn -0.1241 0.4698 0.8740 +vn -0.0741 0.4934 0.8666 +vn -0.1522 0.2862 0.9460 +vn -0.0985 0.2611 0.9603 +vn 0.0771 0.6529 0.7535 +vn 0.0632 0.6548 0.7532 +vn 0.0464 0.5350 0.8436 +vn 0.0647 0.5380 0.8404 +vn 0.0320 0.6432 0.7650 +vn 0.0063 0.5265 0.8502 +vn -0.0361 0.2066 0.9778 +vn -0.0029 0.2189 0.9757 +vn 0.0154 0.2465 0.9690 +vn -0.0088 0.5767 0.8169 +vn -0.0112 0.5803 0.8143 +vn -0.0071 0.4917 0.8707 +vn 0.0061 0.4944 0.8692 +vn -0.0215 0.5587 0.8291 +vn -0.0351 0.4656 0.8843 +vn -0.0186 0.2294 0.9732 +vn 0.0139 0.2439 0.9697 +vn 0.0308 0.2504 0.9676 +vn 0.1238 0.3832 0.9154 +vn 0.1341 0.3300 0.9344 +vn 0.1359 0.2214 0.9657 +vn 0.1246 0.1204 0.9849 +vn -0.0192 0.1569 0.9874 +vn 0.1376 0.0699 0.9880 +vn 0.1193 0.0444 0.9919 +vn 0.1055 0.1137 0.9879 +vn -0.0240 0.1496 0.9885 +vn -0.1498 0.0491 0.9875 +vn -0.0923 -0.0305 0.9953 +vn -0.2137 0.1085 0.9709 +vn -0.1874 0.0346 0.9817 +vn -0.1148 -0.0606 0.9915 +vn -0.0550 -0.1596 0.9857 +vn -0.0627 0.0210 0.9978 +vn -0.0134 0.0042 0.9999 +vn -0.3313 0.0593 0.9417 +vn -0.3155 -0.0047 0.9489 +vn -0.0325 -0.0508 0.9982 +vn 0.0226 -0.0712 0.9972 +vn 0.0469 -0.0506 0.9976 +vn 0.0558 -0.0476 0.9973 +vn 0.0264 -0.0394 0.9989 +vn 0.0523 -0.1249 0.9908 +vn 0.0591 -0.1382 0.9886 +vn 0.0593 -0.1340 0.9892 +vn -0.0673 -0.0912 0.9936 +vn -0.0529 -0.0163 0.9985 +vn -0.0771 -0.1365 0.9876 +vn -0.1014 -0.2409 0.9652 +vn -0.1204 -0.1396 0.9829 +vn -0.1084 -0.0049 0.9941 +vn -0.1766 0.1505 0.9727 +vn -0.1623 0.1174 0.9797 +vn 0.0870 0.0257 0.9959 +vn 0.0598 -0.0093 0.9982 +vn 0.0528 -0.0807 0.9953 +vn 0.0751 -0.0244 0.9969 +vn -0.0189 -0.0665 0.9976 +vn 0.0355 -0.0786 0.9963 +vn -0.3002 -0.0414 0.9530 +vn -0.2843 -0.0814 0.9553 +vn -0.0093 -0.0786 0.9969 +vn 0.0430 -0.0838 0.9956 +vn -0.1703 -0.0282 0.9850 +vn -0.1602 0.1431 0.9767 +vn -0.1193 -0.1783 0.9767 +vn -0.1333 -0.0432 0.9901 +vn -0.2149 0.1071 0.9707 +vn -0.2136 0.2535 0.9435 +vn 0.0500 -0.1002 0.9937 +vn 0.0468 -0.0892 0.9949 +vn 0.0508 -0.1014 0.9935 +vn 0.0499 -0.0957 0.9942 +vn 0.0441 -0.0902 0.9950 +vn 0.0381 -0.0779 0.9962 +vn -0.1373 0.1177 0.9835 +vn -0.1467 0.0191 0.9890 +vn -0.0245 0.1618 0.9865 +vn -0.0192 0.1168 0.9930 +vn -0.1030 0.0638 0.9926 +vn -0.1068 -0.0383 0.9935 +vn 0.0568 -0.0016 0.9984 +vn 0.0959 0.0609 0.9935 +vn 0.0367 -0.0453 0.9983 +vn 0.0268 -0.0500 0.9984 +vn 0.0418 -0.0247 0.9988 +vn 0.0725 0.0259 0.9970 +vn -0.0681 -0.0806 0.9944 +vn -0.0091 -0.1648 0.9863 +vn -0.0394 -0.1135 0.9928 +vn 0.0162 -0.1391 0.9901 +vn 0.0846 0.1299 0.9879 +vn 0.0643 0.0900 0.9939 +vn 0.0469 0.0780 0.9958 +vn -0.0105 0.0917 0.9957 +vn 0.0549 0.0306 0.9980 +vn 0.0542 0.1433 0.9882 +vn 0.0425 0.1521 0.9874 +vn -0.0005 0.1383 0.9904 +vn -0.0324 -0.0647 0.9974 +vn 0.0224 -0.0256 0.9994 +vn -0.0773 -0.0280 0.9966 +vn -0.0617 0.0665 0.9959 +vn -0.0392 0.0704 0.9967 +vn 0.0026 0.1313 0.9913 +vn -0.2333 0.2518 0.9393 +vn -0.2454 0.3380 0.9086 +vn -0.1329 0.1441 0.9806 +vn -0.1269 0.3304 0.9353 +vn -0.2177 0.4046 0.8882 +vn -0.2377 0.4412 0.8654 +vn 0.0255 -0.0409 0.9988 +vn 0.0197 -0.0296 0.9994 +vn 0.0339 -0.0477 0.9983 +vn -0.0133 0.0926 0.9956 +vn -0.0207 0.1013 0.9946 +vn -0.0228 0.1110 0.9936 +vn -0.0683 0.0467 0.9966 +vn -0.0450 0.1017 0.9938 +vn -0.0131 0.1741 0.9846 +vn -0.0135 0.1699 0.9854 +vn 0.0194 0.1706 0.9852 +vn 0.0091 0.1255 0.9920 +vn 0.0163 -0.0296 0.9994 +vn -0.0092 -0.0491 0.9987 +vn -0.0775 0.2963 0.9519 +vn -0.0888 0.2951 0.9513 +vn -0.0895 0.2797 0.9559 +vn -0.0698 0.2713 0.9600 +vn -0.0805 0.2779 0.9572 +vn -0.0766 0.2441 0.9667 +vn 0.0192 -0.0868 0.9960 +vn 0.0249 -0.0769 0.9967 +vn -0.0059 -0.0297 0.9995 +vn 0.0360 -0.0043 0.9993 +vn 0.0234 -0.0164 0.9996 +vn 0.0235 0.1209 0.9924 +vn 0.0435 0.1294 0.9906 +vn -0.0197 -0.0478 0.9987 +vn 0.0311 -0.0405 0.9987 +vn -0.2907 -0.1143 0.9500 +vn -0.2994 -0.1527 0.9418 +vn -0.0589 0.0482 0.9971 +vn -0.0130 0.0835 0.9964 +vn 0.0420 0.1595 0.9863 +vn 0.0235 0.0853 0.9961 +vn 0.0547 0.1586 0.9858 +vn 0.0397 0.0707 0.9967 +vn 0.0193 -0.0216 0.9996 +vn 0.0243 -0.0221 0.9995 +vn 0.0571 0.1800 0.9820 +vn 0.0535 0.0858 0.9949 +vn 0.0346 0.2226 0.9743 +vn 0.0453 0.1368 0.9896 +vn 0.0095 -0.0275 0.9996 +vn 0.0108 -0.0253 0.9996 +vn -0.1983 0.5573 0.8062 +vn -0.1975 0.5436 0.8158 +vn -0.2182 0.4768 0.8515 +vn -0.2138 0.4900 0.8451 +vn -0.1838 0.4817 0.8568 +vn -0.2171 0.4345 0.8741 +vn -0.2265 0.1156 0.9671 +vn -0.2529 0.1195 0.9601 +vn -0.2623 0.1041 0.9594 +vn 0.1202 0.9318 -0.3424 +vn 0.1250 0.9278 -0.3515 +vn 0.1361 0.9824 -0.1282 +vn 0.1242 0.9836 -0.1308 +vn 0.1398 0.9170 -0.3735 +vn 0.1666 0.9776 -0.1290 +vn 0.1682 0.9810 0.0964 +vn 0.1331 0.9870 0.0900 +vn 0.1197 0.9892 0.0842 +vn 0.1531 0.8841 -0.4415 +vn 0.1024 0.8796 -0.4645 +vn 0.1376 0.9793 -0.1486 +vn 0.2040 0.9687 -0.1414 +vn 0.0327 0.8822 -0.4697 +vn 0.0408 0.9875 -0.1520 +vn 0.0509 0.9936 0.1012 +vn 0.1530 0.9824 0.1072 +vn 0.2178 0.9702 0.1066 +vn 0.0053 0.8905 -0.4549 +vn -0.0041 0.9891 -0.1469 +vn 0.0139 0.9056 -0.4239 +vn -0.0048 0.9918 -0.1273 +vn -0.0186 0.9955 0.0932 +vn -0.0043 0.9957 0.0926 +vn 0.0168 0.9222 -0.3864 +vn -0.0028 0.9954 -0.0961 +vn -0.0117 0.9315 -0.3636 +vn -0.0206 0.9970 -0.0752 +vn -0.0308 0.9915 0.1262 +vn -0.0233 0.9939 0.1082 +vn -0.0464 0.9288 -0.3677 +vn -0.0429 0.9959 -0.0801 +vn -0.0576 0.9212 -0.3848 +vn -0.0522 0.9937 -0.0995 +vn -0.0466 0.9899 0.1337 +vn -0.0391 0.9902 0.1343 +vn -0.0745 0.9037 -0.4216 +vn -0.0876 0.8947 -0.4380 +vn -0.1152 0.9847 -0.1311 +vn -0.0750 0.9890 -0.1274 +vn -0.0903 0.9065 -0.4123 +vn -0.1816 0.9768 -0.1133 +vn -0.2187 0.9631 0.1571 +vn -0.1514 0.9763 0.1548 +vn -0.1036 0.9845 0.1418 +vn 0.0620 0.7061 -0.7054 +vn 0.0467 0.6882 -0.7240 +vn 0.0888 0.8107 -0.5787 +vn 0.0958 0.8242 -0.5582 +vn 0.0208 0.6580 -0.7527 +vn 0.0796 0.7837 -0.6160 +vn -0.0104 0.5820 -0.8131 +vn 0.0105 0.5629 -0.8265 +vn 0.0476 0.6752 -0.7361 +vn 0.0638 0.7015 -0.7098 +vn 0.0417 0.5710 -0.8199 +vn 0.0275 0.6741 -0.7382 +vn 0.1531 0.8841 -0.4414 +vn 0.0526 0.6032 -0.7959 +vn 0.0213 0.6952 -0.7185 +vn 0.0418 0.6349 -0.7714 +vn 0.0261 0.7251 -0.6881 +vn 0.0138 0.9056 -0.4239 +vn 0.0198 0.6458 -0.7632 +vn 0.0222 0.7499 -0.6611 +vn -0.0026 0.6436 -0.7654 +vn -0.0039 0.7628 -0.6467 +vn -0.0180 0.6422 -0.7663 +vn -0.0325 0.7624 -0.6463 +vn -0.0256 0.6437 -0.7648 +vn -0.0415 0.7573 -0.6517 +vn -0.0576 0.9212 -0.3849 +vn -0.0860 0.6316 -0.7705 +vn -0.0660 0.6185 -0.7830 +vn -0.0659 0.7175 -0.6934 +vn -0.0790 0.7350 -0.6735 +vn 0.0283 0.5973 -0.8015 +vn 0.0108 0.7260 -0.6876 +vn -0.0902 0.9065 -0.4124 +vn -0.0092 0.2360 -0.9717 +vn 0.0183 0.5155 -0.8567 +vn 0.0312 0.5285 -0.8484 +vn -0.0059 0.2284 -0.9736 +vn -0.0031 0.5018 -0.8650 +vn 0.0102 0.2649 -0.9642 +vn 0.0382 0.2942 -0.9550 +vn 0.0127 0.4995 -0.8662 +vn -0.0272 0.4906 -0.8709 +vn 0.0680 0.3281 -0.9422 +vn 0.0679 0.5247 -0.8486 +vn 0.0665 0.3563 -0.9320 +vn 0.0816 0.5610 -0.8238 +vn 0.0246 0.3679 -0.9295 +vn 0.0479 0.5849 -0.8097 +vn 0.0527 0.6032 -0.7959 +vn 0.0417 0.5711 -0.8199 +vn -0.0185 0.3531 -0.9354 +vn 0.0048 0.5770 -0.8168 +vn -0.0242 0.3252 -0.9453 +vn -0.0135 0.5530 -0.8331 +vn -0.0113 0.2981 -0.9545 +vn -0.0135 0.5347 -0.8450 +vn -0.0134 0.5529 -0.8331 +vn -0.0122 0.2753 -0.9613 +vn -0.0176 0.5241 -0.8515 +vn -0.0373 0.2529 -0.9668 +vn -0.0313 0.2518 -0.9673 +vn -0.0636 0.5053 -0.8606 +vn -0.0729 0.5124 -0.8556 +vn -0.0216 0.2476 -0.9686 +vn -0.0152 0.4789 -0.8777 +vn 0.0283 0.5973 -0.8016 +vn 0.0124 0.2209 -0.9752 +vn -0.0094 0.2344 -0.9721 +vn 0.0096 0.0683 -0.9976 +vn 0.0162 0.0764 -0.9969 +vn -0.0215 0.2476 -0.9686 +vn 0.0048 0.0570 -0.9984 +vn 0.0182 0.0150 -0.9997 +vn 0.0268 0.0174 -0.9995 +vn 0.0263 0.0191 -0.9995 +vn -0.0287 0.2601 -0.9651 +vn -0.0257 0.0575 -0.9980 +vn -0.0213 0.0512 -0.9985 +vn -0.0066 0.0669 -0.9977 +vn 0.0014 0.0057 -1.0000 +vn -0.0268 0.0108 -0.9996 +vn -0.0215 0.0133 -0.9997 +vn 0.0021 0.0756 -0.9971 +vn -0.0121 0.0802 -0.9967 +vn 0.0074 -0.0133 -0.9999 +vn 0.0198 -0.0017 -0.9998 +vn -0.0214 0.0819 -0.9964 +vn -0.0045 0.0841 -0.9964 +vn -0.0144 -0.0281 -0.9995 +vn -0.0115 -0.0245 -0.9996 +vn 0.0223 0.0855 -0.9961 +vn 0.0680 0.3280 -0.9422 +vn 0.0424 0.0775 -0.9961 +vn 0.0311 -0.0276 -0.9991 +vn -0.0007 -0.0246 -0.9997 +vn -0.0003 0.2386 -0.9711 +vn 0.0154 0.0080 -0.9999 +vn 0.0445 0.0263 -0.9987 +vn -0.0059 0.2283 -0.9736 +vn -0.0200 0.0098 -0.9998 +vn -0.0410 -0.0472 -0.9980 +vn 0.0104 -0.0609 -0.9981 +vn 0.0574 -0.0594 -0.9966 +vn 0.0325 -0.0165 -0.9993 +vn 0.0132 -0.0030 -0.9999 +vn 0.0172 -0.0251 -0.9995 +vn 0.0481 -0.0933 -0.9945 +vn 0.0764 -0.0882 -0.9932 +vn 0.0582 -0.0687 -0.9959 +vn -0.0031 -0.0293 -0.9996 +vn -0.0154 -0.0274 -0.9995 +vn 0.0366 -0.0407 -0.9985 +vn 0.0248 -0.0972 -0.9950 +vn -0.0138 -0.0738 -0.9972 +vn -0.0193 -0.0648 -0.9977 +vn -0.0127 0.0065 -0.9999 +vn -0.0264 -0.0146 -0.9995 +vn -0.0967 -0.0208 -0.9951 +vn 0.2956 0.0174 -0.9552 +vn 0.3026 -0.0177 -0.9530 +vn 0.2939 -0.0816 -0.9524 +vn 0.0146 -0.1234 -0.9922 +vn -0.0935 -0.0992 -0.9907 +vn -0.0269 0.0108 -0.9996 +vn -0.0148 0.0155 -0.9998 +vn -0.0143 0.0318 -0.9994 +vn 0.0170 -0.0412 -0.9990 +vn -0.0010 -0.0117 -0.9999 +vn 0.0233 0.0243 -0.9994 +vn 0.0224 0.0129 -0.9997 +vn 0.0182 0.0151 -0.9997 +vn 0.0155 0.0347 -0.9993 +vn 0.0121 -0.0057 -0.9999 +vn 0.0177 -0.0234 -0.9996 +vn 0.0147 -0.0427 -0.9990 +vn -0.0114 -0.0246 -0.9996 +vn -0.0074 -0.0279 -0.9996 +vn 0.0022 -0.0774 -0.9970 +vn 0.0013 -0.0611 -0.9981 +vn 0.0635 -0.0679 -0.9957 +vn -0.0555 -0.0445 -0.9975 +vn -0.0740 -0.0993 -0.9923 +vn -0.0293 -0.1152 -0.9929 +vn 0.0380 -0.1263 -0.9913 +vn -0.0238 0.9440 0.3291 +vn -0.0129 0.9397 0.3418 +vn -0.0403 0.9417 0.3340 +vn 0.0006 0.8407 0.5416 +vn 0.1547 0.9124 0.3789 +vn 0.2110 0.9041 0.3715 +vn 0.0585 0.9245 0.3765 +vn -0.0173 0.9572 0.2888 +vn -0.1596 0.9435 0.2905 +vn -0.1231 0.9804 0.1541 +vn -0.0506 0.9650 0.2572 +vn -0.0556 0.9325 0.3568 +vn -0.0662 0.9216 0.3825 +vn 0.1263 0.9315 0.3411 +vn 0.1142 0.9353 0.3348 +vn 0.1587 0.9231 0.3502 +vn 0.0038 0.9323 0.3617 +vn 0.0585 0.9246 0.3765 +vn -0.0129 0.9397 0.3417 +vn -0.1036 0.9845 0.1417 +vn -0.1762 0.8888 0.4230 +vn -0.1439 0.8998 0.4119 +vn -0.1983 0.8928 0.4043 +vn 0.1069 0.4518 0.8857 +vn 0.0347 0.4416 0.8966 +vn 0.0513 0.5004 0.8643 +vn 0.1238 0.3833 0.9153 +vn -0.0572 0.7435 0.6662 +vn -0.0209 0.6465 0.7626 +vn -0.0293 0.6273 0.7782 +vn -0.0224 0.7911 0.6112 +vn -0.0080 0.6482 0.7614 +vn -0.0215 0.5588 0.8291 +vn 0.0709 0.7048 0.7059 +vn 0.0785 0.7059 0.7039 +vn 0.0837 0.7481 0.6583 +vn 0.0542 0.6907 0.7211 +vn -0.0378 0.5774 0.8156 +vn 0.0085 0.6181 0.7860 +vn -0.0882 0.5291 0.8440 +vn -0.1342 0.4855 0.8638 +vn -0.0821 0.6504 0.7551 +vn -0.0492 0.5484 0.8347 +vn -0.0835 0.5820 0.8089 +vn 0.0584 0.5547 0.8300 +vn 0.0296 0.5840 0.8112 +vn -0.0989 0.5211 0.8477 +vn -0.0684 0.4755 0.8770 +vn 0.0346 0.4415 0.8966 +vn 0.0804 0.7185 0.6909 +vn 0.0316 0.6589 0.7516 +vn 0.0543 0.6907 0.7211 +vn -0.0069 0.6129 0.7901 +vn 0.2069 0.9730 0.1027 +vn 0.1962 0.9116 0.3613 +vn 0.1685 0.8238 0.5412 +vn 0.0654 -0.0435 -0.9969 +vn 0.0803 -0.0581 -0.9951 +vn 0.0671 -0.1190 -0.9906 +vn 0.0540 0.0543 -0.9971 +vn 0.0574 -0.0593 -0.9966 +vn -0.0247 0.4920 -0.8702 +vn -0.0037 0.6184 -0.7859 +vn 0.0708 0.7431 -0.6654 +vn 0.0796 0.7837 -0.6161 +vn 0.1549 0.9000 -0.4074 +vn 0.1549 0.9000 -0.4073 +vn 0.1989 0.9708 -0.1340 +vn -0.0198 -0.1232 0.9922 +vn -0.0077 0.0482 0.9988 +vn -0.0202 0.2288 0.9733 +vn -0.0647 -0.2402 0.9686 +vn -0.0390 -0.2170 0.9754 +vn -0.0715 0.2249 0.9718 +vn -0.0811 -0.1095 0.9907 +vn -0.0069 0.6130 0.7901 +vn -0.0406 0.5116 0.8583 +vn 0.1293 0.7709 0.6237 +vn 0.0689 0.6813 0.7288 +vn -0.1581 0.3726 0.9144 +vn -0.2055 0.3602 0.9100 +vn -0.1956 0.0772 0.9776 +vn -0.0846 0.6726 0.7351 +vn -0.0553 0.6060 0.7935 +vn -0.0307 0.5615 0.8269 +vn -0.0682 0.9887 0.1337 +vn -0.0970 0.9121 0.3983 +vn -0.1152 0.8055 0.5813 +vn 0.0027 0.0140 -0.9999 +vn 0.0035 0.0384 -0.9993 +vn 0.0055 0.0004 -1.0000 +vn -0.0314 0.2518 -0.9673 +vn -0.0037 0.0502 -0.9987 +vn -0.0439 0.5179 -0.8543 +vn -0.0518 0.6414 -0.7655 +vn -0.0552 0.7504 -0.6586 +vn -0.0610 0.9138 -0.4015 +vn -0.0583 0.9915 -0.1159 +vn -0.0237 0.2666 0.9635 +vn -0.0102 0.2131 0.9770 +vn -0.0098 0.0001 1.0000 +vn 0.0307 -0.0645 0.9974 +vn 0.0199 -0.0224 0.9996 +vn -0.0041 0.1152 0.9933 +vn 0.0545 -0.1170 0.9916 +vn 0.0398 -0.0727 0.9966 +vn 0.0305 0.2505 0.9676 +vn 0.0563 -0.0334 0.9979 +vn -0.0051 0.4835 0.8753 +vn -0.1152 0.8054 0.5814 +vn -0.1088 0.7367 0.6674 +vn -0.1140 0.7375 0.6656 +vn -0.0255 0.2386 0.9708 +vn 0.0243 0.2335 0.9720 +vn -0.0620 0.2399 0.9688 +vn -0.0803 0.3328 0.9396 +vn -0.1442 0.4462 0.8832 +vn -0.0614 0.2209 0.9734 +vn -0.1967 0.5129 0.8356 +vn -0.2110 0.5286 0.8222 +vn 0.0524 0.2252 0.9729 +vn 0.0601 0.2149 0.9748 +vn 0.0485 0.2011 0.9784 +vn 0.0146 0.1791 0.9837 +vn -0.0655 0.2338 0.9701 +vn -0.0587 0.2236 0.9729 +vn -0.0260 0.1515 0.9881 +vn -0.0583 0.1362 0.9890 +vn -0.0700 0.1542 0.9856 +vn -0.0989 0.1398 0.9852 +vn -0.0566 0.2017 0.9778 +vn -0.3063 -0.1764 0.9354 +vn -0.0086 0.0884 0.9960 +vn -0.0538 0.2150 0.9751 +vn -0.0731 0.2627 0.9621 +vn 0.0198 0.8273 0.5614 +vn 0.0079 0.6221 0.7829 +vn -0.0273 0.5096 0.8600 +vn -0.2672 0.9527 0.1445 +vn -0.2053 0.9152 0.3467 +vn -0.1983 0.8928 0.4044 +vn -0.1082 0.9207 0.3750 +vn -0.3574 -0.0216 -0.9337 +vn -0.0261 0.0139 -0.9996 +vn -0.0309 -0.0016 -0.9995 +vn -0.3944 -0.0684 -0.9164 +vn -0.1018 -0.0874 -0.9910 +vn -0.3993 -0.1013 -0.9112 +vn -0.1624 0.2337 -0.9586 +vn -0.0082 0.0770 -0.9970 +vn -0.2779 0.0806 -0.9572 +vn -0.3574 -0.0217 -0.9337 +vn 0.0516 -0.0922 0.9944 +vn 0.0378 -0.0457 0.9982 +vn 0.0394 -0.0973 0.9945 +vn 0.0470 -0.0916 0.9947 +vn -0.0456 0.2087 0.9769 +vn 0.0042 -0.0171 0.9998 +vn -0.0558 0.4167 0.9073 +vn -0.0232 0.9371 0.3482 +vn -0.0658 0.2141 0.9746 +vn 0.0127 -0.1256 0.9920 +vn -0.0735 0.9501 -0.3032 +vn -0.2326 0.9704 -0.0644 +vn 0.1336 0.5685 -0.8118 +vn 0.1166 0.7830 -0.6110 +vn 0.0393 0.4291 -0.9024 +vn 0.0819 0.3075 0.9480 +vn -0.1832 0.4369 0.8806 +vn -0.1702 0.4987 0.8499 +vn 0.0699 0.2848 0.9560 +vn -0.1613 0.5241 0.8363 +vn 0.0713 0.2671 0.9610 +vn 0.3780 0.7351 0.5627 +vn 0.1224 0.7704 0.6257 +vn 0.1163 0.7052 0.6994 +vn 0.3685 0.6876 0.6256 +vn 0.1139 0.6521 0.7495 +vn 0.3576 0.6490 0.6715 +vn 0.4111 0.9110 0.0316 +vn 0.1546 0.9851 0.0751 +vn 0.1496 0.9332 0.3267 +vn 0.4074 0.8697 0.2786 +vn 0.1418 0.8593 0.4915 +vn 0.4019 0.8027 0.4406 +vn -0.0781 -0.0261 -0.9966 +vn -0.0949 -0.0301 -0.9950 +vn -0.0934 -0.0992 -0.9907 +vn -0.0995 -0.0933 -0.9907 +vn 0.0453 0.2696 -0.9619 +vn 0.0775 0.5442 -0.8354 +vn 0.3602 0.5704 -0.7382 +vn 0.1069 0.7166 -0.6893 +vn 0.3860 0.6969 -0.6044 +vn 0.1391 0.8254 -0.5472 +vn 0.4180 0.7554 -0.5046 +vn 0.0957 0.8242 -0.5582 +vn 0.1600 0.9258 -0.3425 +vn 0.4320 0.8329 -0.3460 +vn 0.1605 0.9772 -0.1388 +vn 0.4229 0.8897 -0.1719 +vn -0.1613 0.5240 0.8363 +vn -0.1769 0.4685 0.8656 +vn 0.0607 0.1601 0.9852 +vn -0.1984 0.5574 0.8062 +vn -0.2622 0.1041 0.9594 +vn -0.2129 0.0440 0.9761 +vn -0.0508 -0.0143 0.9986 +vn 0.1321 0.3278 0.9355 +vn -0.1415 0.3316 0.9327 +vn -0.1779 0.3760 0.9094 +vn 0.1004 0.3298 0.9387 +vn 0.1954 0.1183 0.9736 +vn -0.0563 0.0828 0.9950 +vn -0.0941 0.2432 0.9654 +vn 0.1695 0.2618 0.9501 +vn 0.2822 0.3007 0.9110 +vn 0.0531 0.2713 0.9610 +vn -0.0114 0.0392 0.9992 +vn 0.2267 0.0815 0.9706 +vn 0.1006 0.5427 0.8339 +vn 0.3294 0.5520 0.7660 +vn 0.1319 0.8189 0.5586 +vn 0.3916 0.7699 0.5038 +vn -0.0461 0.0299 -0.9985 +vn 0.0106 -0.2408 0.9705 +vn 0.0509 -0.0425 0.9978 +vn 0.0668 -0.0548 0.9963 +vn 0.0419 -0.2418 0.9694 +vn 0.0841 0.0105 0.9964 +vn 0.0904 -0.0011 0.9959 +vn 0.3221 0.0021 0.9467 +vn 0.3131 -0.0338 0.9491 +vn 0.3167 -0.1677 0.9336 +vn -0.0124 -0.2228 0.9748 +vn -0.0956 -0.3863 0.9174 +vn -0.1135 -0.3475 0.9308 +vn -0.0316 -0.2094 0.9773 +vn -0.2249 -0.5672 0.7923 +vn -0.2515 -0.5760 0.7778 +vn -0.4019 -0.5081 0.7618 +vn -0.3096 -0.2834 0.9077 +vn -0.2771 -0.1640 0.9467 +vn -0.2249 -0.5672 0.7922 +vn -0.1999 -0.8783 0.4342 +vn -0.2663 -0.9100 0.3178 +vn 0.0269 -0.9973 0.0678 +vn -0.1456 -0.9875 -0.0603 +vn -0.3292 -0.9387 -0.1020 +vn -0.4461 -0.8474 0.2880 +vn -0.4020 -0.5080 0.7618 +vn 0.1865 -0.9810 -0.0535 +vn -0.0987 -0.9878 -0.1208 +vn 0.2055 -0.9683 -0.1418 +vn -0.1166 -0.9709 -0.2090 +vn -0.2000 -0.9550 -0.2190 +vn -0.2367 -0.9617 -0.1384 +vn 0.0721 -0.2514 -0.9652 +vn 0.0911 -0.3239 -0.9417 +vn 0.0644 -0.3502 -0.9345 +vn 0.0465 -0.2778 -0.9595 +vn 0.1465 -0.6490 -0.7465 +vn 0.0922 -0.7146 -0.6934 +vn -0.0613 -0.7706 -0.6343 +vn -0.1522 -0.6639 -0.7321 +vn -0.1616 -0.5589 -0.8133 +vn 0.1387 -0.2695 -0.9530 +vn 0.1901 -0.3763 -0.9068 +vn 0.1395 -0.3279 -0.9344 +vn 0.1116 -0.2049 -0.9724 +vn 0.2083 -0.7063 -0.6766 +vn 0.1420 -0.6963 -0.7036 +vn 0.0565 -0.6590 -0.7500 +vn 0.0653 -0.2975 -0.9525 +vn 0.0623 -0.1821 -0.9813 +vn 0.1476 -0.7997 -0.5820 +vn 0.1145 -0.7543 -0.6464 +vn 0.1094 -0.8026 -0.5864 +vn 0.1597 -0.8185 -0.5519 +vn 0.0656 -0.6984 -0.7127 +vn 0.0525 -0.7413 -0.6691 +vn 0.0173 -0.7887 -0.6146 +vn 0.0703 -0.8769 -0.4756 +vn 0.1468 -0.8725 -0.4661 +vn -0.0392 -0.7936 -0.6072 +vn -0.0076 -0.6856 -0.7280 +vn 0.0065 -0.6671 -0.7450 +vn -0.0043 -0.7955 -0.6059 +vn 0.0389 -0.5976 -0.8008 +vn 0.0331 -0.5578 -0.8293 +vn -0.0390 -0.5442 -0.8381 +vn -0.0293 -0.6761 -0.7362 +vn -0.0075 -0.8134 -0.5816 +vn -0.1025 -0.8574 -0.5043 +vn -0.0921 -0.8176 -0.5683 +vn -0.1018 -0.8096 -0.5780 +vn -0.1168 -0.8508 -0.5124 +vn -0.0821 -0.7705 -0.6321 +vn -0.0852 -0.7646 -0.6388 +vn -0.0860 -0.7469 -0.6594 +vn -0.1186 -0.7924 -0.5983 +vn -0.1455 -0.8380 -0.5260 +vn 0.0401 -0.8521 -0.5218 +vn 0.0224 -0.7504 -0.6606 +vn 0.0958 -0.7507 -0.6536 +vn 0.0822 -0.8380 -0.5394 +vn -0.0119 -0.6236 -0.7817 +vn 0.0834 -0.6502 -0.7552 +vn 0.1105 -0.6592 -0.7438 +vn 0.1157 -0.7360 -0.6670 +vn 0.0971 -0.8145 -0.5720 +vn 0.0310 -0.9812 -0.1906 +vn -0.0427 -0.9868 -0.1561 +vn -0.2330 -0.9697 -0.0738 +vn -0.2137 -0.9602 -0.1796 +vn -0.0902 -0.8474 -0.5233 +vn -0.2624 -0.8499 -0.4570 +vn -0.6014 -0.7518 -0.2703 +vn -0.5495 -0.8350 -0.0285 +vn -0.4616 -0.8640 -0.2010 +vn -0.1807 -0.8027 -0.5683 +vn -0.1305 -0.7343 -0.6661 +vn -0.0776 -0.7097 -0.7003 +vn -0.1227 -0.7966 -0.5919 +vn -0.0683 -0.6750 -0.7346 +vn -0.0190 -0.6381 -0.7697 +vn 0.0388 -0.5977 -0.8008 +vn -0.0394 -0.7158 -0.6972 +vn -0.0001 -0.8400 -0.5426 +vn -0.0788 -0.5744 -0.8147 +vn 0.1335 -0.4905 -0.8612 +vn 0.1751 -0.4264 -0.8874 +vn 0.1374 -0.3767 -0.9161 +vn 0.1039 -0.4286 -0.8975 +vn 0.2083 -0.2283 -0.9510 +vn 0.1630 -0.2359 -0.9580 +vn 0.0034 -0.2318 -0.9728 +vn -0.0095 -0.3383 -0.9410 +vn -0.0229 -0.3831 -0.9234 +vn 0.0041 -0.4323 -0.9017 +vn 0.0511 -0.3613 -0.9311 +vn -0.0066 -0.3260 -0.9454 +vn -0.0812 -0.3927 -0.9161 +vn 0.0532 -0.1870 -0.9809 +vn 0.0158 -0.1723 -0.9849 +vn -0.2651 -0.1409 -0.9539 +vn -0.3113 -0.3069 -0.8994 +vn -0.4064 -0.3847 -0.8287 +vn -0.0850 -0.4295 -0.8990 +vn -0.1133 -0.3648 -0.9242 +vn -0.0250 -0.4224 -0.9061 +vn 0.0141 -0.4941 -0.8693 +vn -0.1367 -0.2129 -0.9675 +vn -0.0692 -0.2275 -0.9713 +vn -0.0333 -0.2458 -0.9687 +vn 0.0169 -0.4745 -0.8801 +vn 0.0546 -0.5454 -0.8364 +vn 0.0351 -0.5880 -0.8081 +vn 0.0757 -0.4986 -0.8635 +vn 0.1261 -0.4689 -0.8742 +vn 0.0843 -0.5444 -0.8346 +vn 0.1156 -0.1955 -0.9739 +vn 0.1618 -0.2159 -0.9629 +vn -0.0759 -0.6708 -0.7377 +vn -0.0644 -0.5554 -0.8291 +vn -0.0500 -0.5547 -0.8306 +vn -0.0667 -0.6745 -0.7353 +vn -0.0108 -0.2346 -0.9720 +vn 0.0071 -0.2020 -0.9794 +vn 0.0459 -0.1769 -0.9832 +vn -0.0089 -0.5449 -0.8385 +vn -0.0362 -0.6631 -0.7476 +vn 0.0096 -0.5908 -0.8068 +vn -0.0036 -0.5176 -0.8556 +vn 0.0091 -0.5120 -0.8589 +vn 0.0108 -0.5919 -0.8059 +vn -0.0309 -0.2546 -0.9665 +vn -0.0135 -0.2464 -0.9691 +vn 0.0190 -0.2296 -0.9731 +vn 0.0362 -0.4790 -0.8771 +vn 0.0193 -0.5631 -0.8262 +vn -0.1338 -0.3299 -0.9345 +vn -0.1237 -0.3811 -0.9162 +vn -0.1366 -0.2162 -0.9667 +vn 0.0083 -0.1311 -0.9913 +vn -0.1276 -0.1114 -0.9855 +vn 0.0059 -0.1325 -0.9912 +vn -0.1111 -0.1085 -0.9879 +vn -0.1198 -0.0402 -0.9920 +vn -0.1380 -0.0625 -0.9885 +vn 0.1222 0.1422 -0.9823 +vn 0.1596 0.0741 -0.9844 +vn 0.0906 0.2086 -0.9738 +vn 0.1247 0.1276 -0.9840 +vn 0.1672 0.0289 -0.9855 +vn 0.2019 -0.0045 -0.9794 +vn 0.0084 0.0038 -1.0000 +vn -0.0157 -0.0044 -0.9999 +vn -0.0280 0.0776 -0.9966 +vn -0.0484 0.0667 -0.9966 +vn -0.3057 0.0987 -0.9470 +vn -0.2803 0.0335 -0.9593 +vn -0.0592 0.0707 -0.9957 +vn -0.0501 0.0724 -0.9961 +vn -0.0615 0.1509 -0.9866 +vn -0.0621 0.1539 -0.9861 +vn -0.0557 0.1374 -0.9889 +vn -0.0294 0.0565 -0.9980 +vn 0.0606 0.0369 -0.9975 +vn 0.0783 0.1236 -0.9892 +vn 0.1142 0.0088 -0.9934 +vn 0.1305 0.1472 -0.9805 +vn 0.1247 0.2563 -0.9585 +vn 0.0988 0.1899 -0.9768 +vn 0.1593 -0.0881 -0.9833 +vn 0.1342 -0.0767 -0.9880 +vn -0.0876 -0.0142 -0.9961 +vn -0.0747 0.0322 -0.9967 +vn -0.0525 0.0932 -0.9943 +vn -0.0610 0.0262 -0.9978 +vn -0.0398 0.0802 -0.9960 +vn -0.0602 0.0738 -0.9955 +vn -0.0456 0.0814 -0.9956 +vn -0.0653 0.0748 -0.9951 +vn -0.3079 0.0616 -0.9494 +vn -0.3119 0.0881 -0.9460 +vn 0.1632 -0.1424 -0.9763 +vn 0.1765 0.0212 -0.9841 +vn 0.2161 -0.2494 -0.9440 +vn 0.2181 -0.1123 -0.9695 +vn 0.1435 0.0199 -0.9895 +vn 0.1370 0.1600 -0.9776 +vn -0.0473 0.0920 -0.9946 +vn -0.0506 0.1028 -0.9934 +vn -0.0375 0.0753 -0.9965 +vn -0.0431 0.0871 -0.9953 +vn -0.0488 0.0925 -0.9945 +vn -0.0516 0.1038 -0.9933 +vn 0.1289 -0.0292 -0.9912 +vn 0.1072 -0.1189 -0.9871 +vn 0.0958 -0.0299 -0.9950 +vn 0.0800 -0.1027 -0.9915 +vn 0.0018 -0.1305 -0.9914 +vn 0.0038 -0.1607 -0.9870 +vn -0.0969 -0.0601 -0.9935 +vn -0.0566 0.0035 -0.9984 +vn -0.0732 -0.0272 -0.9969 +vn -0.0416 0.0230 -0.9989 +vn -0.0263 0.0484 -0.9985 +vn -0.0364 0.0479 -0.9982 +vn 0.0410 0.1322 -0.9904 +vn 0.0808 0.0569 -0.9951 +vn 0.0042 0.0687 -0.9976 +vn 0.0500 0.0327 -0.9982 +vn -0.0915 -0.1293 -0.9874 +vn -0.0703 -0.0933 -0.9932 +vn 0.0003 -0.1103 -0.9939 +vn -0.0507 -0.0832 -0.9952 +vn -0.0034 -0.1486 -0.9889 +vn -0.0442 -0.1546 -0.9870 +vn -0.0547 -0.1430 -0.9882 +vn -0.0555 -0.0331 -0.9979 +vn -0.0125 -0.0330 -0.9994 +vn 0.0381 -0.0157 -0.9991 +vn 0.0016 -0.1565 -0.9877 +vn 0.0425 -0.1073 -0.9933 +vn 0.0613 -0.1032 -0.9928 +vn 0.0726 -0.0461 -0.9963 +vn 0.2477 -0.3342 -0.9094 +vn 0.2341 -0.2519 -0.9390 +vn 0.2397 -0.4370 -0.8669 +vn 0.2171 -0.3997 -0.8906 +vn 0.1275 -0.3309 -0.9350 +vn 0.1370 -0.1565 -0.9781 +vn -0.0187 0.0250 -0.9995 +vn -0.0241 0.0359 -0.9991 +vn 0.0225 -0.1114 -0.9935 +vn 0.0212 -0.1017 -0.9946 +vn 0.0138 -0.0935 -0.9955 +vn -0.0321 0.0426 -0.9986 +vn 0.0564 -0.0921 -0.9942 +vn 0.0410 -0.1256 -0.9912 +vn 0.0151 -0.2497 -0.9682 +vn 0.0148 -0.1810 -0.9834 +vn 0.0271 -0.5169 -0.8556 +vn 0.0303 -0.3041 -0.9522 +vn -0.0053 -0.1755 -0.9845 +vn -0.0186 -0.1753 -0.9843 +vn 0.0785 -0.2983 -0.9513 +vn 0.0978 -0.3839 -0.9182 +vn 0.1294 -0.4013 -0.9068 +vn 0.0894 -0.2960 -0.9510 +vn 0.1786 -0.6902 -0.7012 +vn 0.2380 -0.7100 -0.6627 +vn 0.1984 -0.6541 -0.7299 +vn 0.1097 -0.3573 -0.9275 +vn 0.0809 -0.2790 -0.9569 +vn -0.0359 0.0010 -0.9994 +vn -0.0439 -0.1290 -0.9907 +vn -0.0241 -0.1209 -0.9924 +vn -0.0232 0.0128 -0.9996 +vn -0.0330 0.0363 -0.9988 +vn -0.0529 0.0268 -0.9982 +vn 0.0100 -0.0856 -0.9963 +vn -0.0112 -0.1005 -0.9949 +vn -0.2311 -0.2598 -0.9376 +vn -0.2905 -0.0396 -0.9561 +vn -0.0221 -0.1145 -0.9932 +vn -0.0421 -0.1625 -0.9858 +vn 0.0053 -0.1660 -0.9861 +vn -0.0530 -0.1295 -0.9902 +vn -0.0450 -0.0939 -0.9946 +vn -0.0555 -0.1609 -0.9854 +vn -0.0668 -0.1149 -0.9911 +vn -0.0587 -0.1825 -0.9815 +vn -0.1121 -0.1595 -0.9808 +vn -0.1158 -0.2689 -0.9562 +vn -0.0596 -0.1842 -0.9811 +vn -0.0365 -0.2255 -0.9736 +vn 0.1993 -0.5599 -0.8042 +vn 0.1878 -0.6084 -0.7711 +vn 0.1985 -0.5756 -0.7932 +vn 0.1957 -0.5415 -0.8176 +vn 0.1078 -0.8473 -0.5200 +vn 0.1457 -0.8012 -0.5804 +vn 0.1932 -0.7529 -0.6292 +vn 0.2103 -0.5214 -0.8270 +vn 0.1824 -0.4796 -0.8583 +vn -0.1176 -0.9315 0.3443 +vn -0.1223 -0.9838 0.1311 +vn -0.1386 -0.9820 0.1283 +vn -0.1270 -0.9267 0.3537 +vn -0.1177 -0.9893 -0.0862 +vn -0.1359 -0.9865 -0.0917 +vn -0.1728 -0.9802 -0.0970 +vn -0.1699 -0.9770 0.1287 +vn -0.1420 -0.9155 0.3763 +vn -0.1546 -0.8810 0.4472 +vn -0.2072 -0.9680 0.1415 +vn -0.1375 -0.9792 0.1489 +vn -0.1020 -0.8759 0.4716 +vn -0.2206 -0.9698 -0.1043 +vn -0.1501 -0.9829 -0.1063 +vn -0.0460 -0.9937 -0.1024 +vn -0.0380 -0.9876 0.1522 +vn -0.0306 -0.8780 0.4776 +vn 0.0067 -0.9892 0.1461 +vn -0.0034 -0.8868 0.4622 +vn 0.0073 -0.9955 -0.0948 +vn 0.0205 -0.9952 -0.0958 +vn 0.0067 -0.9921 0.1251 +vn -0.0125 -0.9030 0.4295 +vn 0.0041 -0.9957 0.0921 +vn -0.0161 -0.9206 0.3901 +vn 0.0245 -0.9935 -0.1116 +vn 0.0311 -0.9910 -0.1305 +vn 0.0208 -0.9973 0.0703 +vn 0.0117 -0.9304 0.3663 +vn 0.0420 -0.9962 0.0760 +vn 0.0457 -0.9275 0.3711 +vn 0.0384 -0.9895 -0.1393 +vn 0.0452 -0.9893 -0.1389 +vn 0.0502 -0.9940 0.0973 +vn 0.0562 -0.9191 0.3899 +vn 0.0732 -0.9006 0.4285 +vn 0.0768 -0.9891 0.1259 +vn 0.1323 -0.9833 0.1251 +vn 0.0927 -0.8925 0.4414 +vn 0.1071 -0.9830 -0.1491 +vn 0.1711 -0.9719 -0.1615 +vn 0.2635 -0.9518 -0.1569 +vn 0.2222 -0.9704 0.0948 +vn 0.1087 -0.9092 0.4020 +vn -0.0565 -0.7080 0.7040 +vn -0.0915 -0.8236 0.5598 +vn -0.0894 -0.8089 0.5812 +vn -0.0462 -0.6891 0.7232 +vn -0.0800 -0.7801 0.6205 +vn -0.0203 -0.6569 0.7537 +vn 0.0117 -0.5770 0.8166 +vn -0.0628 -0.6931 0.7181 +vn -0.0454 -0.6651 0.7454 +vn -0.0073 -0.5569 0.8305 +vn -0.0247 -0.6627 0.7485 +vn -0.0359 -0.5631 0.8256 +vn -0.0190 -0.6837 0.7295 +vn -0.0473 -0.5925 0.8042 +vn -0.0143 -0.9030 0.4295 +vn -0.0252 -0.7147 0.6990 +vn -0.0406 -0.6235 0.7808 +vn -0.0227 -0.7413 0.6707 +vn -0.0226 -0.6366 0.7709 +vn 0.0030 -0.7557 0.6550 +vn -0.0004 -0.6376 0.7704 +vn 0.0317 -0.7558 0.6541 +vn 0.0170 -0.6385 0.7694 +vn 0.0562 -0.9191 0.3900 +vn 0.0410 -0.7506 0.6595 +vn 0.0260 -0.6409 0.7672 +vn 0.0842 -0.6290 0.7728 +vn 0.0764 -0.7273 0.6820 +vn 0.0608 -0.7096 0.7020 +vn 0.0577 -0.6172 0.7847 +vn 0.1086 -0.9091 0.4021 +vn -0.0178 -0.7220 0.6916 +vn -0.0505 -0.5992 0.7990 +vn 0.0106 -0.2407 0.9705 +vn -0.0248 -0.5270 0.8495 +vn -0.0173 -0.5147 0.8572 +vn 0.0108 -0.2263 0.9740 +vn 0.0040 -0.5009 0.8655 +vn 0.0074 -0.2193 0.9756 +vn -0.0132 -0.2651 0.9641 +vn 0.0276 -0.4928 0.8697 +vn -0.0086 -0.5041 0.8636 +vn -0.0391 -0.3045 0.9517 +vn -0.0583 -0.5293 0.8464 +vn -0.0617 -0.3489 0.9351 +vn -0.0730 -0.5628 0.8233 +vn -0.0609 -0.3835 0.9215 +vn -0.0472 -0.5925 0.8042 +vn -0.0481 -0.5849 0.8097 +vn -0.0292 -0.3970 0.9174 +vn -0.0292 -0.3969 0.9174 +vn -0.0124 -0.5788 0.8154 +vn 0.0071 -0.3812 0.9245 +vn 0.0072 -0.5577 0.8300 +vn 0.0188 -0.3473 0.9376 +vn 0.0128 -0.5393 0.8420 +vn 0.0152 -0.3093 0.9508 +vn 0.0193 -0.5265 0.8499 +vn 0.0183 -0.2765 0.9608 +vn 0.0370 -0.2468 0.9684 +vn 0.0720 -0.5130 0.8554 +vn 0.0547 -0.5095 0.8587 +vn 0.0253 -0.2462 0.9689 +vn 0.0578 -0.6173 0.7846 +vn -0.0506 -0.5993 0.7990 +vn -0.0103 -0.4900 0.8717 +vn 0.0052 -0.2460 0.9693 +vn -0.0104 -0.0736 0.9972 +vn -0.0136 -0.0607 0.9981 +vn -0.0117 -0.2370 0.9714 +vn -0.0261 -0.0171 0.9995 +vn -0.0266 -0.0137 0.9996 +vn -0.0183 -0.0110 0.9998 +vn -0.0085 -0.0468 0.9989 +vn 0.0220 -0.0414 0.9989 +vn 0.0327 -0.0499 0.9982 +vn 0.0318 -0.2557 0.9662 +vn 0.0230 -0.0090 0.9997 +vn 0.0384 -0.0079 0.9992 +vn 0.0242 -0.0071 0.9997 +vn 0.0220 -0.0662 0.9976 +vn 0.0132 -0.0891 0.9959 +vn 0.0075 -0.0101 0.9999 +vn 0.0054 -0.0145 0.9999 +vn 0.0152 -0.1138 0.9934 +vn 0.0124 -0.1307 0.9913 +vn 0.0059 -0.0156 0.9999 +vn 0.0027 -0.0105 0.9999 +vn -0.0045 -0.1360 0.9907 +vn -0.0253 -0.1267 0.9916 +vn -0.0088 0.0013 1.0000 +vn -0.0439 0.0224 0.9988 +vn -0.0471 -0.1000 0.9939 +vn -0.0535 -0.0190 0.9984 +vn -0.0166 0.0042 0.9999 +vn 0.0004 -0.2324 0.9726 +vn -0.0697 0.0669 0.9953 +vn -0.0128 0.0676 0.9976 +vn 0.0414 0.0529 0.9977 +vn 0.0215 0.0025 0.9998 +vn 0.0243 -0.0194 0.9995 +vn 0.0071 -0.0066 1.0000 +vn 0.0363 -0.0794 0.9962 +vn 0.0181 -0.0381 0.9991 +vn 0.0135 -0.0259 0.9996 +vn 0.0035 -0.0030 1.0000 +vn 0.0002 -0.0001 1.0000 +vn -0.0131 0.0138 0.9998 +vn -0.0072 -0.0685 0.9976 +vn -0.0375 -0.0610 0.9974 +vn -0.0901 -0.0388 0.9952 +vn -0.0561 0.0333 0.9979 +vn 0.1008 -0.0050 0.9949 +vn 0.1019 -0.0112 0.9947 +vn 0.1123 -0.0945 0.9892 +vn 0.1480 -0.1187 0.9818 +vn 0.3408 -0.0795 0.9368 +vn 0.3403 -0.0178 0.9401 +vn 0.0168 -0.0531 0.9984 +vn 0.0327 -0.0386 0.9987 +vn 0.0079 -0.1433 0.9896 +vn 0.0302 -0.1212 0.9922 +vn -0.0232 -0.0318 0.9992 +vn -0.0228 -0.0422 0.9988 +vn -0.0074 -0.0951 0.9954 +vn -0.0063 -0.1136 0.9935 +vn -0.0056 -0.1371 0.9905 +vn -0.0160 -0.0538 0.9984 +vn 0.0039 -0.0045 1.0000 +vn 0.0122 -0.0499 0.9987 +vn -0.0814 0.0525 0.9953 +vn -0.0114 0.0411 0.9991 +vn -0.1104 -0.0232 0.9936 +vn -0.0295 -0.0396 0.9988 +vn 0.0450 -0.0614 0.9971 +vn 0.0504 0.0222 0.9985 +vn 0.0144 -0.9388 -0.3442 +vn 0.0248 -0.9437 -0.3299 +vn -0.0075 -0.8135 -0.5816 +vn 0.0408 -0.9413 -0.3350 +vn -0.2126 -0.9045 -0.3697 +vn -0.1476 -0.9133 -0.3795 +vn -0.1228 -0.7966 -0.5919 +vn -0.0509 -0.9236 -0.3799 +vn 0.2056 -0.9683 -0.1418 +vn 0.1257 -0.9633 -0.2371 +vn -0.1714 -0.9427 -0.2862 +vn -0.2983 -0.9027 -0.3100 +vn 0.0558 -0.9312 -0.3602 +vn 0.0661 -0.9191 -0.3885 +vn -0.1117 -0.9336 -0.3404 +vn -0.1289 -0.9294 -0.3459 +vn -0.1648 -0.9210 -0.3530 +vn -0.0006 -0.9308 -0.3656 +vn 0.1446 -0.8958 -0.4204 +vn 0.1867 -0.8854 -0.4257 +vn 0.2287 -0.8951 -0.3826 +vn -0.0345 -0.4356 -0.8995 +vn -0.1073 -0.4455 -0.8888 +vn -0.0519 -0.4973 -0.8660 +vn 0.0278 -0.6298 -0.7763 +vn 0.0177 -0.6468 -0.7625 +vn 0.0028 -0.6427 -0.7661 +vn 0.0173 -0.7886 -0.6146 +vn -0.0756 -0.7113 -0.6988 +vn -0.0723 -0.7110 -0.6995 +vn -0.0852 -0.7646 -0.6389 +vn -0.0562 -0.6964 -0.7155 +vn -0.0860 -0.7469 -0.6593 +vn -0.0092 -0.6198 -0.7847 +vn 0.0386 -0.5775 -0.8155 +vn 0.0892 -0.5275 -0.8449 +vn 0.0501 -0.5495 -0.8340 +vn 0.0851 -0.5853 -0.8063 +vn -0.0568 -0.5481 -0.8345 +vn -0.1820 -0.5135 -0.8386 +vn -0.5200 -0.5051 -0.6889 +vn -0.6013 -0.7518 -0.2704 +vn 0.0687 -0.4718 -0.8790 +vn -0.0334 -0.6626 -0.7483 +vn -0.0826 -0.7143 -0.6950 +vn -0.0362 -0.6631 -0.7477 +vn 0.0028 -0.6304 -0.7763 +vn -0.2037 -0.9101 -0.3608 +vn -0.2127 -0.9718 -0.1018 +vn -0.1759 -0.8194 -0.5456 +vn -0.1035 0.0492 0.9934 +vn -0.0840 0.0486 0.9953 +vn -0.1394 -0.0224 0.9900 +vn -0.0658 -0.0586 0.9961 +vn -0.0841 0.0486 0.9953 +vn 0.0040 -0.5010 0.8655 +vn 0.0253 -0.4920 0.8702 +vn 0.0045 -0.6151 0.7885 +vn -0.0703 -0.7371 0.6721 +vn -0.1571 -0.8977 0.4116 +vn -0.2028 -0.9700 0.1338 +vn 0.0158 -0.0809 -0.9966 +vn 0.0374 0.0764 -0.9964 +vn 0.0229 -0.2402 -0.9704 +vn 0.0682 0.1883 -0.9797 +vn 0.1009 0.2692 -0.9578 +vn 0.1126 0.1922 -0.9749 +vn 0.0877 -0.1762 -0.9805 +vn 0.0400 -0.5241 -0.8507 +vn -0.1343 -0.7648 -0.6301 +vn -0.0826 -0.7143 -0.6949 +vn -0.1306 -0.7344 -0.6661 +vn 0.2089 -0.4474 -0.8696 +vn 0.1577 -0.3740 -0.9139 +vn 0.2207 -0.7209 -0.6569 +vn 0.0851 -0.5854 -0.8063 +vn 0.0557 -0.6095 -0.7908 +vn 0.0842 -0.6717 -0.7360 +vn 0.0326 -0.5758 -0.8170 +vn 0.0962 -0.9090 -0.4056 +vn 0.0671 -0.9880 -0.1394 +vn 0.1141 -0.8013 -0.5873 +vn -0.0037 -0.0589 0.9983 +vn -0.0025 -0.0096 1.0000 +vn -0.0028 -0.1496 0.9887 +vn 0.0026 -0.0395 0.9992 +vn 0.0451 -0.5186 0.8538 +vn 0.0519 -0.6388 0.7676 +vn 0.0842 -0.6290 0.7729 +vn 0.0540 -0.7434 0.6666 +vn 0.0589 -0.9112 0.4078 +vn 0.0733 -0.9006 0.4285 +vn 0.0764 -0.7273 0.6821 +vn 0.0561 -0.9918 0.1148 +vn 0.0084 -0.2852 -0.9584 +vn 0.0228 -0.2692 -0.9628 +vn -0.0047 -0.4774 -0.8786 +vn -0.0194 0.0185 -0.9996 +vn -0.0304 0.0624 -0.9976 +vn 0.0034 -0.1152 -0.9933 +vn -0.0399 0.0756 -0.9963 +vn -0.0554 0.1331 -0.9895 +vn -0.0585 0.0546 -0.9968 +vn -0.0312 -0.2548 -0.9665 +vn 0.0072 -0.5054 -0.8628 +vn 0.0325 -0.5757 -0.8170 +vn 0.1156 -0.7360 -0.6671 +vn 0.1079 -0.7343 -0.6702 +vn -0.0254 -0.2304 -0.9728 +vn 0.0242 -0.2346 -0.9718 +vn 0.0607 -0.2356 -0.9700 +vn 0.1434 -0.4403 -0.8863 +vn 0.0805 -0.3327 -0.9396 +vn 0.0632 -0.2272 -0.9718 +vn 0.2134 -0.5234 -0.8250 +vn 0.1960 -0.5049 -0.8406 +vn -0.0604 -0.2136 -0.9750 +vn -0.0531 -0.2229 -0.9734 +vn -0.0151 -0.1820 -0.9832 +vn -0.0488 -0.2013 -0.9783 +vn 0.0638 -0.2289 -0.9714 +vn 0.0575 -0.2193 -0.9740 +vn 0.0594 -0.1463 -0.9875 +vn 0.0259 -0.1583 -0.9870 +vn 0.0722 -0.1642 -0.9838 +vn 0.0516 -0.2004 -0.9784 +vn 0.0285 -0.2207 -0.9749 +vn -0.1719 -0.4538 -0.8744 +vn 0.0525 -0.2101 -0.9763 +vn 0.0091 -0.0888 -0.9960 +vn 0.0735 -0.2643 -0.9616 +vn -0.0176 -0.6039 -0.7968 +vn -0.0268 -0.8250 -0.5645 +vn 0.0219 -0.5003 -0.8656 +vn 0.2287 -0.8951 -0.3827 +vn 0.2395 -0.9260 -0.2918 +vn 0.3147 -0.9396 -0.1348 +vn 0.1238 -0.9411 -0.3145 +vn -0.3179 -0.0415 0.9472 +vn -0.3237 -0.0795 0.9428 +vn -0.0488 -0.0309 0.9983 +vn -0.0501 -0.0213 0.9985 +vn -0.3263 -0.1310 0.9362 +vn -0.0769 -0.1160 0.9903 +vn -0.0074 -0.0952 0.9954 +vn -0.2962 -0.0638 0.9530 +vn -0.0289 -0.0789 0.9965 +vn -0.0359 0.0412 -0.9985 +vn -0.0504 0.0892 -0.9947 +vn -0.0477 0.0935 -0.9945 +vn -0.0421 0.1059 -0.9935 +vn -0.0067 0.0287 -0.9996 +vn 0.0457 -0.2069 -0.9773 +vn 0.0551 -0.4198 -0.9060 +vn 0.0703 -0.8769 -0.4755 +vn 0.0257 -0.9492 -0.3135 +vn 0.0939 -0.3327 -0.9384 +vn 0.1605 -0.6345 -0.7560 +vn 0.2222 -0.9704 0.0949 +vn 0.2778 -0.9603 0.0266 +vn 0.0990 -0.9589 0.2658 +vn -0.1230 -0.7918 0.5983 +vn -0.1653 -0.5703 0.8046 +vn -0.0753 -0.4416 0.8941 +vn 0.4338 -0.5345 -0.7254 +vn 0.4144 -0.6579 -0.6289 +vn 0.2338 -0.5399 -0.8086 +vn 0.2472 -0.4601 -0.8528 +vn 0.4105 -0.7273 -0.5501 +vn 0.2269 -0.5843 -0.7792 +vn 0.2244 -0.7334 -0.6417 +vn 0.2241 -0.6522 -0.7241 +vn -0.0396 -0.7058 -0.7073 +vn -0.0444 -0.7711 -0.6351 +vn 0.2174 -0.5953 -0.7735 +vn -0.0406 -0.6608 -0.7495 +vn 0.2018 -0.9711 -0.1277 +vn 0.2077 -0.9098 -0.3594 +vn -0.0709 -0.9373 -0.3411 +vn -0.0768 -0.9932 -0.0880 +vn 0.2111 -0.8364 -0.5059 +vn -0.0625 -0.8618 -0.5034 +vn 0.0937 0.0067 0.9956 +vn 0.0785 0.0310 0.9964 +vn 0.0987 -0.0793 0.9919 +vn 0.3167 -0.1678 0.9336 +vn 0.3126 -0.4158 0.8540 +vn 0.0165 -0.5236 0.8518 +vn 0.2831 -0.6493 0.7059 +vn -0.0148 -0.7137 0.7003 +vn -0.0565 -0.7080 0.7039 +vn -0.0247 -0.5270 0.8495 +vn 0.2569 -0.8115 0.5248 +vn -0.0486 -0.8330 0.5511 +vn 0.2252 -0.9307 0.2884 +vn -0.0741 -0.9384 0.3375 +vn 0.2034 -0.9761 0.0772 +vn -0.0804 -0.9885 0.1282 +vn 0.4105 -0.7273 -0.5500 +vn 0.3931 -0.8063 -0.4420 +vn 0.2124 -0.6420 -0.7367 +vn 0.2594 -0.9111 -0.3203 +vn 0.1237 -0.8947 -0.4293 +vn 0.1079 -0.8473 -0.5200 +vn 0.1994 -0.5599 -0.8042 +vn 0.3899 -0.3572 -0.8488 +vn 0.4279 -0.4184 -0.8012 +vn 0.2418 -0.3819 -0.8920 +vn 0.2032 -0.3289 -0.9222 +vn 0.3321 -0.1003 -0.9379 +vn 0.3527 -0.2701 -0.8959 +vn 0.1556 -0.2407 -0.9581 +vn 0.1215 -0.0786 -0.9895 +vn 0.2603 -0.1957 -0.9455 +vn 0.3025 -0.0088 -0.9531 +vn 0.0790 -0.0171 -0.9967 +vn 0.0159 -0.2495 -0.9682 +vn 0.2220 -0.4766 -0.8506 +vn -0.0316 -0.5478 -0.8360 +vn 0.2189 -0.7938 -0.5674 +vn -0.0527 -0.8217 -0.5674 +vn 0.2244 -0.7334 -0.6416 +vn -0.0444 -0.7712 -0.6351 +vn 0.0472 -0.0185 0.9987 +vn 0.0509 -0.0426 0.9978 +vn 0.0107 -0.2407 0.9705 +vn 0.3601 0.5704 -0.7382 +vn 0.8268 0.4595 -0.3245 +vn 0.8336 0.2860 -0.4725 +vn 0.8582 0.4519 -0.2434 +vn 0.9856 0.1347 0.1024 +vn 0.9619 0.2511 0.1080 +vn 0.9805 0.1963 0.0127 +vn -0.8087 0.0896 -0.5814 +vn -0.7467 0.2463 -0.6179 +vn -0.8418 -0.0498 -0.5375 +vn -0.9853 -0.0836 -0.1492 +vn -0.9977 0.0214 -0.0651 +vn -0.9913 0.1238 -0.0455 +vn 0.8336 0.1034 -0.5427 +vn 0.8324 0.0267 -0.5535 +vn 0.9950 0.0836 -0.0553 +vn 0.9969 0.0263 -0.0740 +vn -0.0880 0.9961 0.0053 +vn -0.0008 0.9452 -0.3265 +vn -0.5789 0.7650 -0.2821 +vn -0.6476 0.7599 -0.0566 +vn -0.6040 0.5599 -0.5671 +vn -0.9661 0.2366 -0.1037 +vn -0.9513 0.2880 -0.1097 +vn -0.9447 0.3124 -0.0995 +vn 0.8821 0.3837 -0.2733 +vn 0.4320 0.8329 -0.3459 +vn 0.8822 0.3936 -0.2584 +vn 0.9903 -0.0722 -0.1187 +vn 0.9997 -0.0173 -0.0156 +vn -0.1373 0.9891 0.0526 +vn -0.6422 0.7654 -0.0425 +vn -0.6138 0.7895 -0.0049 +vn -0.9314 0.3435 -0.1201 +vn -0.9151 0.3672 -0.1664 +vn 0.8761 0.4404 -0.1963 +vn 0.4111 0.9111 0.0316 +vn 0.8697 0.4876 -0.0769 +vn 0.9888 -0.0131 -0.1485 +vn 0.9853 -0.0538 -0.1621 +vn -0.5204 -0.8529 0.0427 +vn -0.6088 -0.7931 -0.0180 +vn -0.5016 -0.7432 -0.4428 +vn -0.4398 -0.8357 -0.3288 +vn -0.8043 -0.5880 -0.0857 +vn -0.6595 -0.5129 -0.5495 +vn -0.1616 -0.5589 -0.8134 +vn 0.0243 -0.0222 0.9995 +vn 0.1074 -0.4704 0.8759 +vn 0.1161 -0.5273 0.8417 +vn -0.0749 -0.4520 0.8889 +vn -0.1548 -0.8951 0.4181 +vn 0.1732 -0.8974 0.4057 +vn 0.2056 -0.9025 0.3784 +vn 0.9930 -0.0980 0.0664 +vn 0.9678 -0.2055 0.1454 +vn 0.8642 -0.3667 -0.3445 +vn 0.8623 -0.2673 -0.4301 +vn 0.8746 -0.4033 0.2690 +vn 0.8077 -0.5495 -0.2138 +vn 0.4337 -0.5345 -0.7254 +vn 0.2064 -0.9780 0.0299 +vn 0.1685 -0.9726 -0.1603 +vn 0.0995 -0.6252 -0.7741 +vn 0.1416 -0.7739 -0.6173 +vn -0.1792 -0.9589 -0.2202 +vn -0.1386 -0.5732 -0.8076 +vn 0.1955 0.1183 0.9736 +vn 0.1696 0.2618 0.9501 +vn 0.7487 0.1464 0.6466 +vn 0.7717 0.0985 0.6283 +vn 0.1321 0.3277 0.9355 +vn 0.7173 0.1561 0.6790 +vn 0.9682 -0.0397 0.2470 +vn 0.9805 0.0000 0.1967 +vn 0.9874 0.0409 0.1530 +vn 0.2267 0.0816 0.9705 +vn 0.7749 0.1147 0.6216 +vn 0.7814 0.2765 0.5594 +vn 0.9879 0.1068 0.1124 +vn 0.9812 0.1864 0.0493 +vn -0.9788 -0.0898 0.1840 +vn -0.8990 -0.0299 0.4370 +vn -0.9390 -0.3341 -0.0816 +vn -0.9021 -0.2784 -0.3297 +vn -0.8687 0.1838 0.4599 +vn -0.9380 -0.2610 0.2280 +vn -0.6014 -0.7518 -0.2704 +vn -0.5199 -0.5051 -0.6889 +vn -0.3461 0.1822 0.9203 +vn -0.8113 0.1744 0.5579 +vn -0.8228 0.1567 0.5464 +vn -0.7439 0.1966 0.6387 +vn -0.9534 0.0166 0.3012 +vn -0.9879 0.0316 0.1519 +vn -0.9914 0.0974 0.0878 +vn 0.6307 -0.6244 0.4608 +vn 0.5168 -0.6822 0.5172 +vn 0.5489 -0.8201 0.1620 +vn 0.6318 -0.7738 0.0457 +vn 0.1991 -0.8134 0.5465 +vn 0.2492 -0.9336 0.2575 +vn 0.4075 0.8697 0.2786 +vn 0.8722 0.4805 0.0920 +vn 0.4018 0.8028 0.4406 +vn 0.8770 0.4378 0.1982 +vn 0.9982 0.0117 -0.0589 +vn 0.9953 0.0078 -0.0968 +vn -0.9919 -0.1041 0.0728 +vn -0.9722 -0.2246 0.0662 +vn -0.8318 -0.1959 0.5194 +vn -0.8351 -0.0943 0.5419 +vn -0.8573 -0.4964 0.1368 +vn -0.6679 -0.3504 0.6566 +vn -0.3262 -0.1309 0.9362 +vn -0.3238 -0.0795 0.9428 +vn -0.3178 -0.0415 0.9472 +vn -0.3156 -0.0047 0.9489 +vn -0.8260 0.1252 0.5495 +vn -0.8284 0.0831 0.5540 +vn -0.9863 0.1486 0.0716 +vn -0.9881 0.1320 0.0788 +vn -0.2844 -0.0814 0.9553 +vn -0.8243 0.0133 0.5660 +vn -0.8167 -0.0775 0.5718 +vn -0.9945 0.0570 0.0880 +vn -0.9951 -0.0480 0.0865 +vn -0.9952 -0.0359 -0.0912 +vn -0.9941 0.0711 -0.0825 +vn -0.8258 0.0918 -0.5564 +vn -0.8226 0.0070 -0.5686 +vn -0.9858 0.1450 -0.0852 +vn -0.8197 0.1477 -0.5534 +vn -0.0092 -0.5899 0.8074 +vn -0.1966 -0.4899 0.8493 +vn 0.1728 -0.6467 0.7429 +vn 0.2320 -0.8808 0.4128 +vn -0.0460 -0.9182 0.3934 +vn -0.3941 -0.8434 0.3652 +vn 0.2510 -0.9162 0.3124 +vn 0.3004 -0.8974 0.3232 +vn 0.3155 -0.9454 -0.0816 +vn 0.2750 -0.9593 -0.0640 +vn 0.2623 -0.9206 0.2894 +vn 0.2738 -0.9505 -0.1466 +vn 0.2379 -0.7100 -0.6628 +vn 0.1787 -0.6902 -0.7012 +vn 0.0700 0.2848 0.9560 +vn 0.5087 -0.2018 0.8369 +vn 0.6137 -0.0676 0.7866 +vn 0.0714 0.2671 0.9610 +vn 0.4504 -0.2698 0.8511 +vn 0.5949 -0.5717 0.5651 +vn 0.6881 -0.5068 0.5193 +vn 0.8377 -0.3375 0.4295 +vn -0.4839 -0.8619 -0.1514 +vn -0.3404 -0.5621 -0.7538 +vn -0.4222 -0.9063 0.0155 +vn -0.3243 -0.6965 -0.6400 +vn -0.1158 -0.2690 -0.9562 +vn -0.0092 -0.0491 0.9988 +vn 0.0337 -0.6172 0.7861 +vn -0.0333 -0.6505 0.7588 +vn 0.0670 -0.9204 0.3851 +vn -0.0065 -0.9042 0.4271 +vn -0.3575 -0.0217 -0.9337 +vn -0.3944 -0.0685 -0.9164 +vn -0.8497 -0.1469 -0.5064 +vn -0.6981 -0.2777 -0.6600 +vn -0.8761 -0.4050 -0.2615 +vn -0.9590 -0.1818 -0.2176 +vn -0.9853 -0.0836 -0.1491 +vn -0.1017 -0.0875 -0.9910 +vn -0.3608 -0.4996 -0.7875 +vn -0.6981 -0.2777 -0.6599 +vn 0.0329 -0.4718 -0.8811 +vn 0.0613 -0.9341 -0.3517 +vn -0.3981 -0.8477 -0.3505 +vn -0.0667 -0.9586 0.2767 +vn -0.2760 -0.9240 0.2645 +vn -0.1689 -0.5216 0.8363 +vn -0.0410 -0.5197 0.8534 +vn -0.3713 -0.8872 0.2737 +vn -0.2572 -0.4854 0.8356 +vn -0.0072 -0.0686 0.9976 +vn 0.3951 -0.8275 0.3989 +vn 0.2132 -0.9143 0.3444 +vn 0.0896 -0.4404 0.8933 +vn 0.1604 -0.3577 0.9200 +vn -0.1246 -0.5267 -0.8409 +vn -0.1351 -0.5072 -0.8512 +vn -0.1691 -0.5304 -0.8307 +vn -0.3829 -0.8835 -0.2700 +vn -0.3614 -0.8893 -0.2804 +vn -0.3303 -0.8973 -0.2928 +vn 0.0960 -0.5210 -0.8482 +vn 0.2498 -0.5285 -0.8113 +vn -0.0529 -0.4839 -0.8735 +vn -0.0709 -0.9503 -0.3031 +vn 0.2125 -0.9407 -0.2644 +vn 0.4188 -0.8764 -0.2379 +vn 0.3099 -0.5027 -0.8070 +vn 0.2640 -0.4961 -0.8271 +vn 0.4870 -0.8379 -0.2464 +vn 0.4129 -0.8680 -0.2759 +vn -0.6819 0.3773 -0.6267 +vn -0.9791 0.1927 -0.0652 +vn 0.2939 -0.0815 -0.9524 +vn 0.8412 -0.0422 -0.5391 +vn 0.6919 -0.3208 -0.6468 +vn 0.2957 0.0174 -0.9551 +vn 0.9969 0.0262 -0.0740 +vn 0.9955 -0.0529 -0.0789 +vn 0.8860 -0.4418 -0.1405 +vn 0.3780 0.7352 0.5627 +vn 0.8480 0.4565 0.2692 +vn 0.8590 0.4448 0.2533 +vn 0.3577 0.6490 0.6715 +vn 0.8325 0.4677 0.2971 +vn 0.9777 0.1840 -0.1009 +vn 0.9856 0.1305 -0.1077 +vn 0.9943 0.0724 -0.0783 +vn 0.0294 0.9853 0.1682 +vn -0.5845 0.8110 0.0267 +vn -0.5780 0.8153 -0.0364 +vn -0.9018 0.3801 -0.2055 +vn -0.8982 0.4118 -0.1539 +vn 0.8030 0.4372 0.4051 +vn 0.9755 0.2167 -0.0386 +vn 0.0756 0.8576 0.5087 +vn -0.5126 0.8504 0.1186 +vn -0.4404 0.7363 0.5136 +vn -0.8780 0.4651 0.1130 +vn -0.8207 0.3485 0.4527 +vn -0.0535 -0.6257 0.7782 +vn -0.0591 -0.5809 0.8118 +vn 0.0050 -0.8805 0.4740 +vn 0.0293 -0.8597 0.5100 +vn -0.0754 -0.5463 -0.8342 +vn -0.1393 -0.5341 -0.8339 +vn -0.0206 -0.5705 -0.8210 +vn 0.0836 -0.9602 -0.2664 +vn -0.0122 -0.9587 -0.2841 +vn -0.1662 -0.9439 -0.2853 +vn 0.0192 -0.0867 0.9960 +vn 0.1520 -0.6858 0.7117 +vn 0.1861 -0.6501 0.7367 +vn 0.0091 -0.1862 0.9825 +vn 0.1316 -0.7325 0.6679 +vn 0.1778 -0.9309 0.3192 +vn 0.2094 -0.9081 0.3626 +vn 0.2581 -0.8793 0.4003 +vn 0.1261 -0.5030 -0.8550 +vn 0.0224 -0.4669 -0.8840 +vn 0.1999 -0.9304 -0.3071 +vn 0.0382 -0.9437 -0.3285 +vn -0.0508 -0.0142 0.9986 +vn -0.1748 -0.5703 0.8027 +vn 0.1230 -0.5524 0.8245 +vn -0.2622 0.1040 0.9594 +vn -0.2391 -0.5397 0.8072 +vn -0.1720 -0.8268 0.5356 +vn -0.1043 -0.8190 0.5642 +vn 0.1892 -0.7678 0.6122 +vn -0.2993 -0.1527 0.9419 +vn -0.8017 -0.2396 0.5476 +vn -0.7012 -0.4790 0.5282 +vn -0.9610 -0.2661 0.0751 +vn -0.8056 -0.5872 0.0795 +vn -0.4545 -0.7589 0.4663 +vn -0.2103 -0.8553 0.4735 +vn -0.5150 -0.6912 0.5070 +vn -0.5208 -0.8422 0.1398 +vn -0.4390 -0.8838 0.1619 +vn -0.1952 -0.9576 0.2117 +vn 0.0162 -0.4487 -0.8936 +vn 0.0337 -0.4473 -0.8937 +vn 0.0253 -0.9411 -0.3373 +vn 0.0588 -0.9383 -0.3407 +vn -0.1956 0.0771 0.9777 +vn -0.0848 -0.5424 0.8358 +vn -0.1485 -0.5248 0.8382 +vn 0.0142 -0.8471 0.5312 +vn -0.0561 -0.8427 0.5354 +vn 0.2801 -0.5920 -0.7557 +vn 0.4256 -0.8762 -0.2262 +vn -0.4182 -0.8524 0.3141 +vn -0.3175 -0.8885 0.3312 +vn -0.1778 -0.4685 0.8654 +vn -0.2787 -0.4388 0.8543 +vn -0.1285 -0.9352 0.3299 +vn -0.0338 -0.5062 0.8618 +vn -0.0303 -0.9054 0.4234 +vn 0.0403 -0.9081 0.4168 +vn 0.1398 -0.9893 -0.0410 +vn 0.0771 -0.9967 -0.0263 +vn 0.0499 -0.9151 0.4001 +vn 0.1375 -0.9893 -0.0478 +vn 0.2083 -0.7062 -0.6766 +vn 0.2208 -0.7210 -0.6569 +vn 0.1932 -0.7529 -0.6291 +vn 0.0552 -0.9464 0.3181 +vn 0.0218 -0.9514 0.3073 +vn 0.0078 -0.5441 0.8390 +vn 0.0237 -0.5252 0.8507 +vn 0.0341 -0.9523 0.3034 +vn 0.0171 -0.5493 0.8355 +vn -0.2045 -0.9680 0.1456 +vn -0.4373 -0.8949 0.0885 +vn -0.3901 -0.8939 -0.2206 +vn -0.1665 -0.9797 -0.1119 +vn -0.5204 -0.8529 0.0428 +vn -0.1522 -0.6639 -0.7322 +vn -0.0613 -0.7706 -0.6344 +vn -0.9599 -0.2594 -0.1067 +vn -0.7886 -0.1948 -0.5833 +vn -0.6595 -0.5129 -0.5496 +vn -0.1024 -0.8656 0.4901 +vn -0.0339 -0.9854 0.1670 +vn -0.1594 -0.8798 0.4477 +vn -0.0624 -0.9951 0.0762 +vn 0.0682 -0.9399 0.3345 +vn 0.0915 -0.9386 0.3328 +vn 0.0407 -0.4974 0.8665 +vn 0.0300 -0.4908 0.8707 +vn -0.0073 -0.0951 0.9954 +vn 0.2093 -0.9452 0.2505 +vn 0.2222 -0.9577 -0.1830 +vn 0.1714 -0.9608 0.2177 +vn 0.1870 -0.9651 -0.1832 +vn 0.1465 -0.6490 -0.7466 +vn 0.1605 -0.6345 -0.7561 +vn 0.0447 -0.9524 0.3017 +vn 0.0911 -0.5315 0.8422 +vn 0.1375 -0.9551 0.2624 +vn 0.1483 -0.5620 0.8137 +vn 0.0987 -0.0794 0.9919 +vn -0.1594 -0.8799 0.4477 +vn -0.1140 -0.8954 0.4303 +vn -0.0074 -0.9998 0.0165 +vn 0.1457 -0.8011 -0.5805 +vn -0.8688 0.1838 0.4599 +vn -0.9512 0.2910 0.1025 +vn -0.9634 -0.2577 0.0731 +vn -0.9420 0.2615 -0.2104 +vn -0.9146 -0.3370 -0.2236 +vn 0.9813 -0.1274 -0.1441 +vn 0.9833 -0.1031 -0.1502 +vn 0.7770 -0.4862 -0.3999 +vn 0.7730 -0.5215 -0.3613 +vn 0.9812 -0.0522 -0.1858 +vn 0.7807 -0.4185 -0.4642 +vn 0.2190 -0.7938 -0.5673 +vn 0.2111 -0.8364 -0.5058 +vn 0.9708 -0.1705 -0.1686 +vn 0.9774 -0.1420 -0.1567 +vn 0.7789 -0.5552 -0.2918 +vn 0.7715 -0.6085 -0.1857 +vn 0.2019 -0.9710 -0.1278 +vn 0.9725 0.0202 -0.2321 +vn 0.7729 -0.3284 -0.5430 +vn 0.9656 0.0895 -0.2442 +vn 0.7653 -0.2604 -0.5887 +vn -0.9856 0.1258 -0.1134 +vn -0.9918 0.1140 -0.0580 +vn -0.9306 -0.3450 0.1225 +vn -0.8555 -0.4989 -0.1384 +vn -0.9924 0.1103 0.0541 +vn -0.8666 -0.1900 0.4614 +vn -0.4019 -0.5080 0.7618 +vn 0.9723 0.1677 0.1630 +vn 0.9525 0.1922 0.2361 +vn 0.8146 -0.0542 0.5775 +vn 0.8237 0.0370 0.5658 +vn 0.9770 0.0463 0.2080 +vn 0.8177 -0.2852 0.5001 +vn 0.3127 -0.4158 0.8540 +vn 0.0524 -0.4547 -0.8891 +vn 0.0330 -0.4718 -0.8811 +vn 0.0948 -0.9346 -0.3428 +vn 0.1909 -0.9343 0.3011 +vn 0.1120 -0.5434 0.8320 +vn 0.3932 -0.8630 0.3173 +vn 0.2115 -0.4679 0.8581 +vn 0.0363 -0.0793 0.9962 +vn 0.4574 -0.8115 0.3638 +vn 0.2016 -0.3739 0.9053 +vn -0.4229 -0.8586 0.2897 +vn -0.3100 -0.4471 0.8391 +vn -0.1307 -0.4834 -0.8656 +vn -0.2643 -0.9147 -0.3058 +vn -0.1896 -0.5246 -0.8300 +vn -0.3229 -0.9048 -0.2775 +vn 0.4533 -0.8675 0.2050 +vn 0.3749 -0.5794 0.7237 +vn 0.8908 -0.4358 0.1289 +vn 0.7185 -0.3108 0.6222 +vn 0.1480 -0.1188 0.9818 +vn -0.8573 -0.4964 0.1367 +vn -0.3629 -0.8906 0.2743 +vn -0.3136 -0.5463 0.7767 +vn -0.6679 -0.3505 0.6566 +vn -0.0769 -0.1159 0.9903 +vn 0.0134 -0.9301 0.3670 +vn 0.0778 -0.9942 -0.0749 +vn -0.0122 -0.9501 0.3118 +vn 0.0177 -0.9897 -0.1419 +vn 0.0566 -0.6588 -0.7501 +vn 0.1419 -0.6963 -0.7036 +vn 0.2125 -0.6364 0.7415 +vn 0.2910 -0.8600 0.4192 +vn 0.8746 -0.4033 0.2691 +vn 0.7256 -0.5682 0.3882 +vn 0.6998 -0.7108 -0.0706 +vn 0.4144 -0.6579 -0.6288 +vn 0.0608 0.1600 0.9852 +vn 0.3858 -0.3688 0.8456 +vn 0.4876 -0.6365 0.5976 +vn 0.5949 -0.5717 0.5650 +vn -0.0361 -0.9772 0.2090 +vn -0.0024 -0.9452 -0.3266 +vn -0.0047 -0.4775 -0.8786 +vn -0.3063 -0.1764 0.9355 +vn -0.5708 -0.6281 0.5289 +vn -0.5150 -0.6911 0.5070 +vn -0.7012 -0.4789 0.5282 +vn -0.6084 -0.7860 0.1100 +vn -0.5208 -0.8422 0.1399 +vn 0.9989 0.0283 -0.0369 +vn 0.9990 -0.0434 0.0118 +vn 0.8445 -0.1907 -0.5005 +vn 0.8288 -0.0512 -0.5573 +vn 0.3321 -0.1004 -0.9379 +vn -0.9954 0.0649 -0.0703 +vn -0.9992 -0.0387 0.0114 +vn -0.8611 -0.1924 -0.4706 +vn -0.8319 -0.0242 -0.5545 +vn -0.5632 0.3595 0.7440 +vn -0.8561 0.1192 0.5029 +vn 0.0636 -0.9798 0.1896 +vn 0.0983 -0.9842 -0.1475 +vn 0.1870 -0.9651 -0.1833 +vn 0.0555 -0.8037 0.5924 +vn 0.1316 -0.7326 0.6679 +vn 0.0785 -0.9590 0.2722 +vn 0.9676 0.1498 -0.2030 +vn 0.7831 -0.1418 -0.6055 +vn 0.9774 0.1640 -0.1337 +vn 0.8091 0.0245 -0.5872 +vn 0.2604 -0.1957 -0.9455 +vn 0.2221 -0.4766 -0.8506 +vn 0.3915 0.7700 0.5038 +vn 0.8714 0.4316 0.2332 +vn 0.9980 0.0301 -0.0549 +vn -0.9847 0.1486 -0.0913 +vn -0.8172 0.1246 -0.5627 +vn 0.9906 0.1115 -0.0795 +vn 0.8172 0.0657 -0.5726 +vn -0.2311 -0.4372 0.8692 +vn -0.4440 -0.8064 0.3906 +vn -0.2124 -0.5284 0.8220 +vn -0.1349 -0.8364 0.5313 +vn 0.0573 -0.9760 0.2101 +vn 0.0512 -0.9419 -0.3321 +vn 0.1003 0.3298 0.9387 +vn 0.6842 0.0843 0.7244 +vn 0.8377 -0.3375 0.4294 +vn 0.9363 -0.1423 0.3212 +vn -0.9420 0.2615 -0.2103 +vn -0.8734 0.4385 -0.2119 +vn -0.8679 -0.3156 -0.3837 +vn -0.9146 -0.3370 -0.2235 +vn -0.8481 0.5136 -0.1304 +vn -0.8964 -0.3411 -0.2832 +vn -0.4615 -0.8641 -0.2010 +vn 0.9753 -0.2082 -0.0731 +vn 0.9674 -0.2056 -0.1479 +vn 0.7677 -0.6374 -0.0657 +vn 0.7911 -0.6052 0.0886 +vn 0.2033 -0.9761 0.0772 +vn -0.9371 0.3305 -0.1120 +vn -0.8358 -0.5201 -0.1759 +vn -0.9856 0.1258 -0.1133 +vn -0.8555 -0.4990 -0.1384 +vn 0.9894 -0.1308 0.0635 +vn 0.8180 -0.4891 0.3029 +vn 0.9955 -0.0518 0.0795 +vn 0.8431 -0.0418 0.5362 +vn 0.9959 0.0260 0.0866 +vn 0.8308 0.0180 0.5563 +vn 0.3220 0.0021 0.9467 +vn 0.3404 -0.0178 0.9401 +vn 0.3407 -0.0795 0.9368 +vn -0.9924 0.1104 0.0541 +vn -0.9871 0.1212 0.1045 +vn -0.8200 -0.0686 0.5682 +vn -0.8666 -0.1899 0.4615 +vn -0.9926 0.0816 0.0898 +vn -0.8275 -0.0220 0.5611 +vn 0.9915 0.0759 0.1053 +vn 0.8277 0.0329 0.5602 +vn 0.8308 0.0180 0.5562 +vn 0.8907 -0.4359 0.1289 +vn 0.4533 -0.8674 0.2050 +vn 0.4658 -0.8849 -0.0030 +vn 0.9074 -0.4204 -0.0030 +vn 0.1375 -0.9551 0.2623 +vn 0.1165 -0.9932 0.0015 +vn 0.1167 -0.9932 0.0015 +vn 0.4653 -0.8851 -0.0030 +vn 0.9070 -0.4211 -0.0030 +vn 0.4648 -0.8854 -0.0031 +vn 0.9067 -0.4218 -0.0030 +vn 0.1170 -0.9931 0.0017 +vn -0.1140 -0.8954 0.4304 +vn -0.1263 -0.8669 0.4823 +vn -0.0448 -0.8751 0.4819 +vn -0.1680 -0.8539 0.4925 +vn -0.1655 -0.8540 0.4932 +vn -0.1249 -0.8669 0.4825 +vn -0.0439 -0.8747 0.4827 +vn -0.1235 -0.8669 0.4830 +vn -0.0429 -0.8747 0.4828 +vn -0.1635 -0.8542 0.4936 +vn -0.1349 -0.8364 0.5312 +vn -0.0561 -0.8427 0.5355 +vn 0.0915 -0.9386 0.3327 +vn 0.0997 -0.9950 -0.0082 +vn 0.0608 -0.9981 -0.0047 +vn 0.0682 -0.9400 0.3343 +vn 0.0723 -0.9973 -0.0150 +vn 0.0701 -0.9973 -0.0215 +vn 0.0995 -0.9950 -0.0082 +vn 0.0606 -0.9982 -0.0047 +vn 0.0993 -0.9950 -0.0083 +vn 0.0604 -0.9982 -0.0051 +vn 0.0665 -0.9975 -0.0257 +vn 0.0948 -0.9345 -0.3430 +vn 0.0589 -0.9383 -0.3408 +vn -0.2045 -0.9680 0.1453 +vn 0.0623 -0.9716 0.2285 +vn -0.2048 -0.9629 0.1758 +vn 0.1703 -0.9483 0.2680 +vn 0.1743 -0.9475 0.2682 +vn 0.0682 -0.9710 0.2291 +vn -0.2006 -0.9637 0.1765 +vn 0.0742 -0.9705 0.2295 +vn -0.1963 -0.9644 0.1770 +vn 0.1782 -0.9467 0.2683 +vn 0.1778 -0.9309 0.3190 +vn 0.0785 -0.9591 0.2721 +vn -0.1953 -0.9576 0.2117 +vn -0.8043 -0.5881 -0.0857 +vn -0.6089 -0.7931 -0.0178 +vn -0.6106 -0.7906 0.0462 +vn -0.8071 -0.5905 -0.0007 +vn -0.5203 -0.8529 0.0427 +vn -0.5225 -0.8479 0.0901 +vn -0.5200 -0.8494 0.0905 +vn -0.6072 -0.7931 0.0467 +vn -0.8058 -0.5922 -0.0006 +vn -0.6041 -0.7955 0.0472 +vn -0.8044 -0.5940 -0.0005 +vn -0.5174 -0.8509 0.0910 +vn -0.5208 -0.8421 0.1399 +vn -0.8055 -0.5872 0.0795 +vn 0.5169 -0.6822 0.5171 +vn 0.5030 -0.6591 0.5592 +vn 0.1918 -0.7910 0.5809 +vn 0.6167 -0.5960 0.5143 +vn 0.6127 -0.5991 0.5154 +vn 0.4998 -0.6610 0.5597 +vn 0.1933 -0.7906 0.5810 +vn 0.4967 -0.6629 0.5603 +vn 0.1947 -0.7902 0.5811 +vn 0.6086 -0.6023 0.5166 +vn 0.4876 -0.6365 0.5975 +vn 0.2094 -0.9778 0.0009 +vn 0.4275 -0.9040 0.0015 +vn 0.0341 -0.9523 0.3033 +vn 0.0383 -0.9993 -0.0005 +vn 0.0382 -0.9993 -0.0009 +vn 0.4275 -0.9040 0.0014 +vn 0.2094 -0.9778 0.0010 +vn 0.4276 -0.9040 0.0014 +vn 0.0381 -0.9993 -0.0005 +vn 0.1999 -0.9305 -0.3071 +vn 0.4129 -0.8679 -0.2760 +vn 0.2954 -0.8792 0.3738 +vn 0.2586 -0.9011 0.3481 +vn 0.2402 -0.9007 0.3619 +vn 0.2376 -0.9014 0.3619 +vn 0.2963 -0.8789 0.3739 +vn 0.2609 -0.9004 0.3481 +vn 0.2971 -0.8786 0.3738 +vn 0.2632 -0.8997 0.3482 +vn 0.2350 -0.9021 0.3619 +vn 0.2319 -0.8808 0.4128 +vn 0.2910 -0.8600 0.4191 +vn 0.2581 -0.8792 0.4005 +vn -0.1286 -0.9352 0.3299 +vn -0.3175 -0.8886 0.3311 +vn -0.3403 -0.9401 0.0190 +vn -0.1587 -0.9872 0.0171 +vn -0.4181 -0.8523 0.3141 +vn -0.4190 -0.9079 0.0152 +vn -0.4193 -0.9077 0.0154 +vn -0.3403 -0.9401 0.0191 +vn -0.1585 -0.9872 0.0172 +vn -0.1582 -0.9873 0.0173 +vn -0.4196 -0.9076 0.0157 +vn -0.3229 -0.9048 -0.2776 +vn 0.0134 -0.9301 0.3672 +vn 0.0056 -0.9042 0.4270 +vn -0.0133 -0.9269 0.3752 +vn 0.0500 -0.9151 0.4001 +vn 0.0370 -0.8869 0.4605 +vn 0.0385 -0.8867 0.4607 +vn 0.0081 -0.9041 0.4273 +vn -0.0096 -0.9267 0.3756 +vn 0.0106 -0.9039 0.4277 +vn -0.0059 -0.9267 0.3759 +vn 0.0399 -0.8865 0.4610 +vn -0.0064 -0.9042 0.4270 +vn -0.8688 0.1838 0.4598 +vn -0.8990 -0.0299 0.4369 +vn -0.8509 0.0576 0.5221 +vn -0.8312 0.2726 0.4845 +vn -0.9788 -0.0897 0.1843 +vn -0.9597 -0.0352 0.2786 +vn -0.9598 -0.0194 0.2799 +vn -0.8535 0.0798 0.5149 +vn -0.8351 0.2834 0.4714 +vn -0.8688 0.0864 0.4876 +vn -0.8459 0.2853 0.4506 +vn -0.9644 -0.0118 0.2643 +vn -0.8562 0.1192 0.5028 +vn 0.9677 0.1498 -0.2030 +vn 0.9738 0.1891 -0.1262 +vn 0.9822 0.1802 -0.0525 +vn 0.9656 0.0896 -0.2441 +vn 0.9741 0.1428 -0.1751 +vn 0.9754 0.1387 -0.1712 +vn 0.9757 0.1825 -0.1216 +vn 0.9835 0.1739 -0.0498 +vn 0.9773 0.1747 -0.1195 +vn 0.9847 0.1672 -0.0487 +vn 0.9765 0.1336 -0.1689 +vn 0.9755 0.2166 -0.0387 +vn -0.8481 0.5135 -0.1304 +vn -0.8734 0.4384 -0.2120 +vn -0.9429 0.1709 -0.2860 +vn -0.9644 0.1443 -0.2215 +vn -0.9419 0.2615 -0.2106 +vn -0.9424 0.2691 -0.1985 +vn -0.9430 0.1841 -0.2772 +vn -0.9632 0.1583 -0.2175 +vn -0.9631 0.1583 -0.2174 +vn -0.9340 0.2527 -0.2526 +vn -0.9515 0.2335 -0.2001 +vn -0.9424 0.2692 -0.1985 +vn -0.9324 0.3134 -0.1802 +vn -0.8982 0.4117 -0.1539 +vn -0.9018 0.3802 -0.2055 +vn 0.9938 -0.0372 -0.1044 +vn 0.9908 0.0085 -0.1347 +vn 0.9928 -0.0596 -0.1041 +vn 0.9928 -0.0604 -0.1031 +vn 0.9939 -0.0378 -0.1037 +vn 0.9910 0.0078 -0.1339 +vn 0.9940 -0.0383 -0.1029 +vn 0.9910 0.0070 -0.1334 +vn 0.9929 -0.0607 -0.1020 +vn 0.9982 0.0118 -0.0588 +vn 0.9959 0.0260 0.0865 +vn 0.9987 -0.0513 0.0013 +vn 0.9996 0.0266 0.0076 +vn 0.8907 -0.4358 0.1290 +vn 0.9073 -0.4204 -0.0030 +vn 0.9987 -0.0516 0.0014 +vn 0.9996 0.0262 0.0077 +vn 0.9987 -0.0519 0.0014 +vn 0.9996 0.0259 0.0075 +vn 0.9066 -0.4219 -0.0030 +vn 0.9955 -0.0529 -0.0787 +vn -0.9919 -0.1041 0.0727 +vn -0.9968 -0.0002 0.0796 +vn -1.0000 0.0019 -0.0026 +vn -0.9933 -0.1072 -0.0434 +vn -0.9951 0.0967 0.0206 +vn -0.9947 0.0943 0.0403 +vn -0.9999 0.0024 -0.0139 +vn -0.9875 -0.1010 -0.1209 +vn -1.0000 0.0072 -0.0053 +vn -0.9854 -0.0921 -0.1431 +vn -0.9939 0.0957 0.0539 +vn -0.9976 0.0214 -0.0652 +vn 0.0251 -0.9997 -0.0021 +vn 0.0249 -0.9997 -0.0021 +vn 0.0248 -0.9997 -0.0021 +vn 0.0254 -0.9411 -0.3372 +vn 0.4573 -0.8114 0.3639 +vn 0.4966 -0.8680 0.0005 +vn 0.4259 -0.9048 -0.0006 +vn 0.4967 -0.8679 0.0004 +vn 0.4259 -0.9048 -0.0010 +vn 0.4870 -0.8379 -0.2465 +vn 0.2132 -0.9143 0.3445 +vn 0.2150 -0.9766 0.0002 +vn -0.0762 -0.9971 0.0031 +vn 0.2149 -0.9766 0.0002 +vn -0.0764 -0.9971 0.0035 +vn 0.2148 -0.9767 0.0002 +vn -0.0765 -0.9971 0.0033 +vn 0.2126 -0.9407 -0.2644 +vn -0.0709 -0.9503 -0.3032 +vn -0.3714 -0.8872 0.2737 +vn -0.2809 -0.9597 0.0065 +vn -0.3656 -0.9308 0.0086 +vn -0.2810 -0.9597 0.0065 +vn -0.3658 -0.9307 0.0086 +vn -0.2812 -0.9596 0.0069 +vn -0.3660 -0.9306 0.0088 +vn -0.3303 -0.8973 -0.2929 +vn -0.4087 -0.9126 0.0115 +vn -0.4090 -0.9125 0.0115 +vn -0.4093 -0.9123 0.0115 +vn 0.0447 -0.9524 0.3016 +vn 0.0170 -0.9998 0.0087 +vn 0.0173 -0.9998 0.0088 +vn 0.0177 -0.9998 0.0086 +vn -0.3628 -0.8906 0.2743 +vn -0.4121 -0.9104 -0.0367 +vn -0.8573 -0.4964 0.1366 +vn -0.8787 -0.4744 -0.0534 +vn -0.8775 -0.4593 -0.1377 +vn -0.4205 -0.9035 -0.0825 +vn -0.4384 -0.8920 -0.1103 +vn -0.8860 -0.4232 -0.1894 +vn -0.8761 -0.4050 -0.2616 +vn -0.3981 -0.8477 -0.3506 +vn -0.9722 -0.2246 0.0663 +vn -0.9727 -0.2245 -0.0591 +vn -0.8787 -0.4744 -0.0533 +vn -0.9637 -0.2131 -0.1609 +vn -0.9562 -0.1943 -0.2188 +vn -0.9589 -0.1818 -0.2178 +vn 0.0591 -0.9515 0.3019 +vn 0.2080 -0.9551 0.2109 +vn 0.0634 -0.9511 0.3022 +vn 0.2115 -0.9544 0.2109 +vn 0.0677 -0.9508 0.3022 +vn 0.2150 -0.9536 0.2107 +vn 0.2093 -0.9453 0.2503 +vn 0.2065 -0.9288 0.3078 +vn 0.2093 -0.9281 0.3080 +vn 0.2121 -0.9275 0.3078 +vn 0.2095 -0.9081 0.3625 +vn 0.9573 -0.1710 0.2333 +vn 0.8604 -0.3690 0.3515 +vn 0.9855 -0.0659 0.1561 +vn 0.9852 -0.0691 0.1571 +vn 0.9564 -0.1744 0.2344 +vn 0.8584 -0.3723 0.3528 +vn 0.9555 -0.1775 0.2357 +vn 0.8564 -0.3756 0.3542 +vn 0.9847 -0.0722 0.1583 +vn 0.9363 -0.1423 0.3211 +vn -0.1023 -0.8657 0.4900 +vn -0.1060 -0.8426 0.5280 +vn -0.1018 -0.8425 0.5290 +vn -0.0976 -0.8424 0.5299 +vn -0.4223 -0.9063 0.0156 +vn -0.4839 -0.8619 -0.1516 +vn -0.4857 -0.8646 0.1285 +vn -0.4128 -0.8909 0.1896 +vn -0.1833 -0.9757 0.1198 +vn -0.1831 -0.9758 0.1199 +vn -0.4867 -0.8640 0.1285 +vn -0.4155 -0.8897 0.1892 +vn -0.4878 -0.8634 0.1284 +vn -0.4182 -0.8885 0.1888 +vn -0.1829 -0.9758 0.1198 +vn -0.1548 -0.8951 0.4182 +vn -0.4440 -0.8063 0.3908 +vn -0.3942 -0.8435 0.3650 +vn -0.9598 -0.2594 -0.1068 +vn -0.9646 -0.2634 -0.0143 +vn -0.9991 -0.0413 -0.0034 +vn -0.8043 -0.5880 -0.0858 +vn -0.8071 -0.5904 -0.0007 +vn -0.9646 -0.2633 -0.0143 +vn -0.9992 -0.0409 -0.0034 +vn -0.9647 -0.2631 -0.0144 +vn -0.9992 -0.0406 -0.0034 +vn -0.8045 -0.5940 -0.0004 +vn -0.9610 -0.2661 0.0749 +vn -0.9951 -0.0479 0.0864 +vn -0.9857 0.1450 -0.0853 +vn -0.9978 0.0663 0.0016 +vn -0.9900 0.1409 -0.0046 +vn -0.9978 0.0655 0.0016 +vn -0.9902 0.1398 -0.0045 +vn -0.9979 0.0648 0.0015 +vn -0.9903 0.1386 -0.0045 +vn -0.9945 0.0570 0.0878 +vn -0.9881 0.1320 0.0790 +vn -0.9954 0.0649 -0.0702 +vn -0.9847 0.1486 -0.0912 +vn -0.9887 0.1491 -0.0129 +vn -0.9969 0.0786 0.0064 +vn -0.9888 0.1486 -0.0129 +vn -0.9967 0.0804 0.0060 +vn -0.9889 0.1481 -0.0128 +vn -0.9966 0.0821 0.0056 +vn -0.9914 0.0974 0.0879 +vn -0.9251 0.3656 0.1027 +vn -0.8312 0.2726 0.4846 +vn -0.9230 0.3700 0.1061 +vn -0.9162 0.3858 0.1084 +vn -0.8780 0.4652 0.1130 +vn 0.9886 -0.0737 -0.1310 +vn 0.9708 -0.1704 -0.1686 +vn 0.9821 -0.0981 -0.1610 +vn 0.9823 -0.0985 -0.1592 +vn 0.9888 -0.0743 -0.1296 +vn 0.9890 -0.0747 -0.1280 +vn 0.9826 -0.0987 -0.1575 +vn 0.9888 -0.0130 -0.1485 +vn -0.4374 -0.8949 0.0886 +vn -0.4378 -0.8906 0.1236 +vn -0.4361 -0.8913 0.1238 +vn -0.4345 -0.8921 0.1243 +vn -0.9992 -0.0388 0.0113 +vn -0.9959 -0.0069 0.0901 +vn -0.9960 -0.0004 0.0896 +vn -0.9963 0.0044 0.0854 +vn 0.9725 0.0202 -0.2322 +vn 0.9820 0.0759 -0.1731 +vn 0.9824 0.0743 -0.1713 +vn 0.9828 0.0723 -0.1699 +vn 0.9989 0.0284 -0.0368 +vn 0.9906 0.1115 -0.0793 +vn 0.9934 0.1143 0.0129 +vn 0.9973 0.0390 0.0621 +vn 0.9938 0.1101 0.0139 +vn 0.9974 0.0359 0.0625 +vn 0.9943 0.1059 0.0147 +vn 0.9975 0.0326 0.0633 +vn 0.9879 0.1068 0.1126 +vn 0.9990 -0.0434 0.0119 +vn 0.9942 -0.0169 0.1065 +vn 0.9941 -0.0202 0.1070 +vn 0.9939 -0.0234 0.1081 +vn -0.0360 -0.9772 0.2091 +vn -0.0477 -0.9542 0.2953 +vn -0.0523 -0.9541 0.2949 +vn -0.0570 -0.9539 0.2945 +vn -0.0459 -0.9182 0.3935 +vn 0.0251 -0.8777 0.4786 +vn 0.0261 -0.8774 0.4791 +vn 0.0273 -0.8775 0.4788 +vn 0.0142 -0.8472 0.5311 +vn 0.1686 -0.9726 -0.1603 +vn 0.1779 -0.9740 0.1405 +vn 0.1799 -0.9736 0.1404 +vn 0.1819 -0.9733 0.1403 +vn 0.1732 -0.8974 0.4058 +vn 0.7255 -0.5682 0.3883 +vn 0.7101 -0.5363 0.4563 +vn 0.8604 -0.3690 0.3516 +vn 0.8584 -0.3724 0.3529 +vn 0.7069 -0.5397 0.4572 +vn 0.7034 -0.5430 0.4586 +vn 0.6881 -0.5069 0.5192 +vn 0.9786 -0.1341 -0.1563 +vn 0.9753 -0.2083 -0.0731 +vn 0.9848 -0.1456 -0.0950 +vn 0.9849 -0.1454 -0.0943 +vn 0.9788 -0.1339 -0.1548 +vn 0.9791 -0.1338 -0.1533 +vn 0.9849 -0.1453 -0.0937 +vn 0.9903 -0.0723 -0.1186 +vn 0.9853 -0.0536 -0.1621 +vn -0.9786 0.1497 -0.1412 +vn -0.9799 0.1667 -0.1096 +vn -0.9768 0.1605 -0.1415 +vn -0.9790 0.1718 -0.1100 +vn -0.9658 0.2214 -0.1351 +vn -0.9727 0.2061 -0.1071 +vn -0.9315 0.3434 -0.1202 +vn -0.9447 0.3125 -0.0995 +vn 0.9966 -0.0776 0.0273 +vn 0.9770 0.0463 0.2081 +vn 0.9831 0.0908 0.1590 +vn 0.9838 0.0882 0.1562 +vn 0.9966 -0.0783 0.0264 +vn 0.9965 -0.0790 0.0255 +vn 0.9844 0.0851 0.1541 +vn 0.9856 0.1347 0.1025 +vn -0.9918 0.1141 -0.0581 +vn -0.9832 0.1672 -0.0737 +vn -0.9864 0.1644 -0.0094 +vn -0.9829 0.1696 -0.0713 +vn -0.9864 0.1643 -0.0057 +vn -0.9864 0.1642 -0.0057 +vn -0.9811 0.1810 -0.0689 +vn -0.9861 0.1661 -0.0040 +vn -0.9513 0.2881 -0.1098 +vn -0.9660 0.2366 -0.1038 +vn 0.9582 0.2229 0.1794 +vn 0.9781 0.1846 0.0958 +vn 0.9787 0.1821 0.0944 +vn 0.9596 0.2192 0.1764 +vn 0.9609 0.2149 0.1746 +vn 0.9793 0.1793 0.0938 +vn 0.9805 0.1964 0.0127 +vn -0.9871 0.1212 0.1043 +vn -0.9879 0.1531 0.0247 +vn -0.9879 0.1513 0.0345 +vn -0.9877 0.1510 0.0407 +vn -0.9791 0.1927 -0.0651 +vn 0.9963 0.0811 0.0286 +vn 0.9964 0.0802 0.0284 +vn 0.9965 0.0793 0.0283 +vn 0.9950 0.0836 -0.0554 +vn -0.9968 -0.0002 0.0797 +vn -0.8373 -0.0278 0.5460 +usemtl Scene_-_Root +s 1 +f 9276/9276/5671 9277/9277/5672 9278/9278/5673 +f 9276/9276/5671 9278/9278/5673 9279/9279/5674 +f 9277/9277/5672 9280/9280/5675 9281/9281/5676 +f 9277/9277/5672 9281/9281/5676 9278/9278/5673 +f 9278/9278/5673 9281/9281/5676 9282/9282/5677 +f 9278/9278/5673 9282/9282/5677 9283/9283/5678 +f 9279/9279/5674 9278/9278/5673 9283/9283/5678 +f 9279/9279/5674 9283/9283/5678 9284/9284/5679 +f 9285/9285/5680 9286/9286/5681 9287/9287/5682 +f 9285/9285/5680 9287/9287/5682 9288/9288/5683 +f 9286/9286/5681 9289/9289/5684 9290/9290/5685 +f 9286/9286/5681 9290/9290/5685 9287/9287/5682 +f 9287/9287/5682 9290/9290/5685 9291/9291/5686 +f 9287/9287/5682 9291/9291/5686 9292/9292/5687 +f 9288/9288/5683 9287/9287/5682 9292/9292/5687 +f 9288/9288/5683 9292/9292/5687 9293/9293/5688 +f 9294/9294/5689 9295/9295/5687 9296/9296/5690 +f 9294/9294/5689 9296/9296/5690 9297/9297/5691 +f 9295/9295/5687 9298/9298/5686 9299/9299/5692 +f 9295/9295/5687 9299/9299/5692 9296/9296/5690 +f 9296/9296/5690 9299/9299/5692 9300/9300/5693 +f 9296/9296/5690 9300/9300/5693 9301/9301/5694 +f 9297/9297/5691 9296/9296/5690 9301/9301/5694 +f 9297/9297/5691 9301/9301/5694 9302/9302/5695 +f 9302/9302/5695 9301/9301/5694 9303/9303/5696 +f 9302/9302/5695 9303/9303/5696 9304/9304/5697 +f 9301/9301/5694 9300/9300/5693 9305/9305/5698 +f 9301/9301/5694 9305/9305/5698 9303/9303/5696 +f 9303/9303/5696 9305/9305/5698 9306/9306/5699 +f 9303/9303/5696 9306/9306/5699 9307/9307/5700 +f 9304/9304/5697 9303/9303/5696 9307/9307/5700 +f 9304/9304/5697 9307/9307/5700 9308/9308/5701 +f 9309/9309/5702 9310/9310/5703 9311/9311/5704 +f 9309/9309/5702 9311/9311/5704 9312/9312/5705 +f 9310/9310/5703 9313/9313/5706 9314/9314/5707 +f 9310/9310/5703 9314/9314/5707 9311/9311/5704 +f 9311/9311/5704 9314/9314/5707 9315/9315/5708 +f 9311/9311/5704 9315/9315/5708 9316/9316/5709 +f 9312/9312/5705 9311/9311/5704 9316/9316/5709 +f 9312/9312/5705 9316/9316/5709 9317/9317/5710 +f 9318/9318/5711 9319/9319/5712 9320/9320/5713 +f 9318/9318/5711 9320/9320/5713 9321/9321/5714 +f 9319/9319/5712 9322/9322/5715 9323/9323/5716 +f 9319/9319/5712 9323/9323/5716 9320/9320/5713 +f 9320/9320/5713 9323/9323/5716 9324/9324/5717 +f 9320/9320/5713 9324/9324/5717 9325/9325/5718 +f 9321/9321/5714 9320/9320/5713 9325/9325/5718 +f 9321/9321/5714 9325/9325/5718 9326/9326/5719 +f 9327/9327/5720 9328/9328/5721 9329/9329/5722 +f 9327/9327/5720 9329/9329/5722 9330/9330/5723 +f 9328/9328/5721 9331/9331/5724 9332/9332/5725 +f 9328/9328/5721 9332/9332/5725 9329/9329/5722 +f 9329/9329/5722 9332/9332/5725 9333/9333/5726 +f 9329/9329/5722 9333/9333/5726 9334/9334/5727 +f 9330/9330/5723 9329/9329/5722 9334/9334/5727 +f 9330/9330/5723 9334/9334/5727 9335/9335/5728 +f 9336/9336/5729 9337/9337/5730 9338/9338/5731 +f 9336/9336/5729 9338/9338/5731 9339/9339/5732 +f 9337/9337/5730 9340/9340/5733 9341/9341/5734 +f 9337/9337/5730 9341/9341/5734 9338/9338/5731 +f 9338/9338/5731 9341/9341/5734 9342/9342/5735 +f 9338/9338/5731 9342/9342/5735 9343/9343/5736 +f 9339/9339/5732 9338/9338/5731 9343/9343/5736 +f 9339/9339/5732 9343/9343/5736 9344/9344/5737 +f 9345/9345/5738 9346/9346/5739 9347/9347/5740 +f 9345/9345/5738 9347/9347/5740 9348/9348/5741 +f 9346/9346/5739 9349/9349/5742 9350/9350/5743 +f 9346/9346/5739 9350/9350/5743 9347/9347/5740 +f 9347/9347/5740 9350/9350/5743 9351/9351/5744 +f 9347/9347/5740 9351/9351/5744 9352/9352/5745 +f 9348/9348/5741 9347/9347/5740 9352/9352/5745 +f 9348/9348/5741 9352/9352/5745 9353/9353/5746 +f 9354/9354/5747 9355/9355/5748 9356/9356/5749 +f 9354/9354/5747 9356/9356/5749 9357/9357/5750 +f 9355/9355/5748 9358/9358/5751 9359/9359/5752 +f 9355/9355/5748 9359/9359/5752 9356/9356/5749 +f 9356/9356/5749 9359/9359/5752 9360/9360/5753 +f 9356/9356/5749 9360/9360/5753 9361/9361/5754 +f 9357/9357/5750 9356/9356/5749 9361/9361/5754 +f 9357/9357/5750 9361/9361/5754 9362/9362/5755 +f 9363/9363/5756 9364/9364/5757 9365/9365/5758 +f 9363/9363/5756 9365/9365/5758 9366/9366/5759 +f 9364/9364/5757 9367/9367/5760 9368/9368/5761 +f 9364/9364/5757 9368/9368/5761 9365/9365/5758 +f 9365/9365/5758 9368/9368/5761 9369/9369/5762 +f 9365/9365/5758 9369/9369/5762 9370/9370/5763 +f 9366/9366/5759 9365/9365/5758 9370/9370/5763 +f 9366/9366/5759 9370/9370/5763 9371/9371/5764 +f 9372/9372/5765 9373/9373/5766 9374/9374/5767 +f 9372/9372/5765 9374/9374/5767 9375/9375/5768 +f 9373/9373/5766 9336/9336/5729 9376/9376/5732 +f 9373/9373/5766 9376/9376/5732 9374/9374/5767 +f 9374/9374/5767 9376/9376/5732 9377/9377/5737 +f 9374/9374/5767 9377/9377/5737 9378/9378/5769 +f 9375/9375/5768 9374/9374/5767 9378/9378/5769 +f 9375/9375/5768 9378/9378/5769 9379/9379/5770 +f 9380/9380/5733 9381/9381/5771 9382/9382/5772 +f 9380/9380/5733 9382/9382/5772 9383/9383/5734 +f 9381/9381/5771 9384/9384/5747 9385/9385/5773 +f 9381/9381/5771 9385/9385/5773 9382/9382/5772 +f 9382/9382/5772 9385/9385/5773 9386/9386/5755 +f 9382/9382/5772 9386/9386/5755 9387/9387/5774 +f 9383/9383/5734 9382/9382/5772 9387/9387/5774 +f 9383/9383/5734 9387/9387/5774 9388/9388/5735 +f 9389/9389/5775 9390/9390/5776 9391/9391/5777 +f 9389/9389/5775 9391/9391/5777 9392/9392/5778 +f 9390/9390/5776 9393/9393/5779 9394/9394/5780 +f 9390/9390/5776 9394/9394/5780 9391/9391/5777 +f 9391/9391/5777 9394/9394/5780 9395/9395/5781 +f 9391/9391/5777 9395/9395/5781 9396/9396/5782 +f 9392/9392/5778 9391/9391/5777 9396/9396/5782 +f 9392/9392/5778 9396/9396/5782 9397/9397/5783 +f 9398/9398/5784 9399/9399/5785 9400/9400/5786 +f 9398/9398/5784 9400/9400/5786 9401/9401/5787 +f 9399/9399/5785 9402/9402/5788 9403/9403/5789 +f 9399/9399/5785 9403/9403/5789 9400/9400/5786 +f 9400/9400/5786 9403/9403/5789 9404/9404/5790 +f 9400/9400/5786 9404/9404/5790 9405/9405/5791 +f 9401/9401/5787 9400/9400/5786 9405/9405/5791 +f 9401/9401/5787 9405/9405/5791 9406/9406/5792 +f 9407/9407/5793 9408/9408/5794 9409/9409/5795 +f 9407/9407/5793 9409/9409/5795 9410/9410/5796 +f 9408/9408/5794 9411/9411/5797 9412/9412/5798 +f 9408/9408/5794 9412/9412/5798 9409/9409/5795 +f 9409/9409/5795 9412/9412/5798 9413/9413/5799 +f 9409/9409/5795 9413/9413/5799 9414/9414/5800 +f 9410/9410/5796 9409/9409/5795 9414/9414/5800 +f 9410/9410/5796 9414/9414/5800 9415/9415/5801 +f 9416/9416/5802 9417/9417/5803 9418/9418/5804 +f 9416/9416/5802 9418/9418/5804 9419/9419/5805 +f 9417/9417/5803 9389/9389/5775 9392/9392/5778 +f 9417/9417/5803 9392/9392/5778 9418/9418/5804 +f 9418/9418/5804 9392/9392/5778 9397/9397/5783 +f 9418/9418/5804 9397/9397/5783 9420/9420/5806 +f 9419/9419/5805 9418/9418/5804 9420/9420/5806 +f 9419/9419/5805 9420/9420/5806 9421/9421/5807 +f 9422/9422/5808 9423/9423/5809 9424/9424/5810 +f 9422/9422/5808 9424/9424/5810 9425/9425/5811 +f 9423/9423/5809 9426/9426/5812 9427/9427/5813 +f 9423/9423/5809 9427/9427/5813 9424/9424/5810 +f 9424/9424/5810 9427/9427/5813 9428/9428/5814 +f 9424/9424/5810 9428/9428/5814 9429/9429/5815 +f 9425/9425/5811 9424/9424/5810 9429/9429/5815 +f 9425/9425/5811 9429/9429/5815 9430/9430/5816 +f 9431/9431/5817 9432/9432/5818 9433/9433/5819 +f 9431/9431/5817 9433/9433/5819 9434/9434/5820 +f 9432/9432/5818 9435/9435/5821 9436/9436/5822 +f 9432/9432/5818 9436/9436/5822 9433/9433/5819 +f 9433/9433/5819 9436/9436/5822 9437/9437/5823 +f 9433/9433/5819 9437/9437/5823 9438/9438/5824 +f 9434/9434/5820 9433/9433/5819 9438/9438/5824 +f 9434/9434/5820 9438/9438/5824 9439/9439/5825 +f 9393/9393/5779 9440/9440/5826 9441/9441/5827 +f 9393/9393/5779 9441/9441/5827 9394/9394/5780 +f 9440/9440/5826 9407/9407/5793 9410/9410/5796 +f 9440/9440/5826 9410/9410/5796 9441/9441/5827 +f 9441/9441/5827 9410/9410/5796 9415/9415/5801 +f 9441/9441/5827 9415/9415/5801 9442/9442/5828 +f 9394/9394/5780 9441/9441/5827 9442/9442/5828 +f 9394/9394/5780 9442/9442/5828 9395/9395/5781 +f 9395/9395/5781 9442/9442/5828 9443/9443/5829 +f 9395/9395/5781 9443/9443/5829 9444/9444/5830 +f 9442/9442/5828 9415/9415/5801 9445/9445/5831 +f 9442/9442/5828 9445/9445/5831 9443/9443/5829 +f 9443/9443/5829 9445/9445/5831 9446/9446/5832 +f 9443/9443/5829 9446/9446/5832 9447/9447/5833 +f 9444/9444/5830 9443/9443/5829 9447/9447/5833 +f 9444/9444/5830 9447/9447/5833 9448/9448/5834 +f 9421/9421/5807 9420/9420/5806 9449/9449/5835 +f 9421/9421/5807 9449/9449/5835 9450/9450/5836 +f 9420/9420/5806 9397/9397/5783 9451/9451/5837 +f 9420/9420/5806 9451/9451/5837 9449/9449/5835 +f 9449/9449/5835 9451/9451/5837 9452/9452/5838 +f 9449/9449/5835 9452/9452/5838 9453/9453/5839 +f 9450/9450/5836 9449/9449/5835 9453/9453/5839 +f 9450/9450/5836 9453/9453/5839 9454/9454/5840 +f 9406/9406/5792 9405/9405/5791 9455/9455/5841 +f 9406/9406/5792 9455/9455/5841 9456/9456/5842 +f 9405/9405/5791 9404/9404/5790 9457/9457/5843 +f 9405/9405/5791 9457/9457/5843 9455/9455/5841 +f 9455/9455/5841 9457/9457/5843 9458/9458/5844 +f 9455/9455/5841 9458/9458/5844 9459/9459/5845 +f 9456/9456/5842 9455/9455/5841 9459/9459/5845 +f 9456/9456/5842 9459/9459/5845 9460/9460/5846 +f 9439/9439/5825 9438/9438/5824 9461/9461/5847 +f 9439/9439/5825 9461/9461/5847 9462/9462/5848 +f 9438/9438/5824 9437/9437/5823 9463/9463/5849 +f 9438/9438/5824 9463/9463/5849 9461/9461/5847 +f 9461/9461/5847 9463/9463/5849 9464/9464/5850 +f 9461/9461/5847 9464/9464/5850 9465/9465/5851 +f 9462/9462/5848 9461/9461/5847 9465/9465/5851 +f 9462/9462/5848 9465/9465/5851 9466/9466/5852 +f 9430/9430/5816 9429/9429/5815 9467/9467/5853 +f 9430/9430/5816 9467/9467/5853 9468/9468/5854 +f 9429/9429/5815 9428/9428/5814 9469/9469/5855 +f 9429/9429/5815 9469/9469/5855 9467/9467/5853 +f 9467/9467/5853 9469/9469/5855 9470/9470/5856 +f 9467/9467/5853 9470/9470/5856 9471/9471/5857 +f 9468/9468/5854 9467/9467/5853 9471/9471/5857 +f 9468/9468/5854 9471/9471/5857 9472/9472/5858 +f 9397/9397/5783 9396/9396/5782 9473/9473/5859 +f 9397/9397/5783 9473/9473/5859 9451/9451/5837 +f 9396/9396/5782 9395/9395/5781 9444/9444/5830 +f 9396/9396/5782 9444/9444/5830 9473/9473/5859 +f 9473/9473/5859 9444/9444/5830 9448/9448/5834 +f 9473/9473/5859 9448/9448/5834 9474/9474/5860 +f 9451/9451/5837 9473/9473/5859 9474/9474/5860 +f 9451/9451/5837 9474/9474/5860 9452/9452/5838 +f 9415/9415/5801 9414/9414/5800 9475/9475/5861 +f 9415/9415/5801 9475/9475/5861 9445/9445/5831 +f 9414/9414/5800 9413/9413/5799 9476/9476/5862 +f 9414/9414/5800 9476/9476/5862 9475/9475/5861 +f 9475/9475/5861 9476/9476/5862 9477/9477/5863 +f 9475/9475/5861 9477/9477/5863 9478/9478/5864 +f 9445/9445/5831 9475/9475/5861 9478/9478/5864 +f 9445/9445/5831 9478/9478/5864 9446/9446/5832 +f 9460/9460/5846 9459/9459/5845 9479/9479/5865 +f 9460/9460/5846 9479/9479/5865 9480/9480/5866 +f 9459/9459/5845 9458/9458/5844 9481/9481/5867 +f 9459/9459/5845 9481/9481/5867 9479/9479/5865 +f 9479/9479/5865 9481/9481/5867 9482/9482/5868 +f 9479/9479/5865 9482/9482/5868 9483/9483/5869 +f 9480/9480/5866 9479/9479/5865 9483/9483/5869 +f 9480/9480/5866 9483/9483/5869 9484/9484/5870 +f 9472/9472/5858 9471/9471/5857 9485/9485/5871 +f 9472/9472/5858 9485/9485/5871 9486/9486/5872 +f 9471/9471/5857 9470/9470/5856 9487/9487/5873 +f 9471/9471/5857 9487/9487/5873 9485/9485/5871 +f 9485/9485/5871 9487/9487/5873 9488/9488/5874 +f 9485/9485/5871 9488/9488/5874 9489/9489/5875 +f 9486/9486/5872 9485/9485/5871 9489/9489/5875 +f 9486/9486/5872 9489/9489/5875 9490/9490/5876 +f 9466/9466/5852 9465/9465/5851 9491/9491/5877 +f 9466/9466/5852 9491/9491/5877 9492/9492/5878 +f 9465/9465/5851 9464/9464/5850 9493/9493/5879 +f 9465/9465/5851 9493/9493/5879 9491/9491/5877 +f 9491/9491/5877 9493/9493/5879 9494/9494/5880 +f 9491/9491/5877 9494/9494/5880 9495/9495/5881 +f 9492/9492/5878 9491/9491/5877 9495/9495/5881 +f 9492/9492/5878 9495/9495/5881 9496/9496/5882 +f 9452/9452/5838 9474/9474/5860 9497/9497/5883 +f 9452/9452/5838 9497/9497/5883 9498/9498/5884 +f 9474/9474/5860 9448/9448/5834 9499/9499/5885 +f 9474/9474/5860 9499/9499/5885 9497/9497/5883 +f 9497/9497/5883 9499/9499/5885 9500/9500/5886 +f 9497/9497/5883 9500/9500/5886 9501/9501/5887 +f 9498/9498/5884 9497/9497/5883 9501/9501/5887 +f 9498/9498/5884 9501/9501/5887 9502/9502/5888 +f 9446/9446/5832 9478/9478/5864 9503/9503/5889 +f 9446/9446/5832 9503/9503/5889 9504/9504/5890 +f 9478/9478/5864 9477/9477/5863 9505/9505/5891 +f 9478/9478/5864 9505/9505/5891 9503/9503/5889 +f 9503/9503/5889 9505/9505/5891 9506/9506/5892 +f 9503/9503/5889 9506/9506/5892 9507/9507/5893 +f 9504/9504/5890 9503/9503/5889 9507/9507/5893 +f 9504/9504/5890 9507/9507/5893 9508/9508/5894 +f 9454/9454/5840 9453/9453/5839 9509/9509/5895 +f 9454/9454/5840 9509/9509/5895 9510/9510/5896 +f 9453/9453/5839 9452/9452/5838 9498/9498/5884 +f 9453/9453/5839 9498/9498/5884 9509/9509/5895 +f 9509/9509/5895 9498/9498/5884 9502/9502/5888 +f 9509/9509/5895 9502/9502/5888 9511/9511/5897 +f 9510/9510/5896 9509/9509/5895 9511/9511/5897 +f 9510/9510/5896 9511/9511/5897 9512/9512/5898 +f 9448/9448/5834 9447/9447/5833 9513/9513/5899 +f 9448/9448/5834 9513/9513/5899 9499/9499/5885 +f 9447/9447/5833 9446/9446/5832 9504/9504/5890 +f 9447/9447/5833 9504/9504/5890 9513/9513/5899 +f 9513/9513/5899 9504/9504/5890 9508/9508/5894 +f 9513/9513/5899 9508/9508/5894 9514/9514/5900 +f 9499/9499/5885 9513/9513/5899 9514/9514/5900 +f 9499/9499/5885 9514/9514/5900 9500/9500/5886 +f 9500/9500/5886 9514/9514/5900 9515/9515/5901 +f 9500/9500/5886 9515/9515/5901 9516/9516/5902 +f 9514/9514/5900 9508/9508/5894 9517/9517/5903 +f 9514/9514/5900 9517/9517/5903 9515/9515/5901 +f 9515/9515/5901 9517/9517/5903 9518/9518/5904 +f 9515/9515/5901 9518/9518/5904 9519/9519/5905 +f 9516/9516/5902 9515/9515/5901 9519/9519/5905 +f 9516/9516/5902 9519/9519/5905 9520/9520/5906 +f 9512/9512/5898 9511/9511/5897 9521/9521/5907 +f 9512/9512/5898 9521/9521/5907 9522/9522/5908 +f 9511/9511/5897 9502/9502/5888 9523/9523/5909 +f 9511/9511/5897 9523/9523/5909 9521/9521/5907 +f 9521/9521/5907 9523/9523/5909 9524/9524/5910 +f 9521/9521/5907 9524/9524/5910 9525/9525/5911 +f 9522/9522/5908 9521/9521/5907 9525/9525/5911 +f 9522/9522/5908 9525/9525/5911 9526/9526/5912 +f 9490/9490/5876 9489/9489/5875 9527/9527/5913 +f 9490/9490/5876 9527/9527/5913 9528/9528/5914 +f 9489/9489/5875 9488/9488/5874 9529/9529/5915 +f 9489/9489/5875 9529/9529/5915 9527/9527/5913 +f 9527/9527/5913 9529/9529/5915 9530/9530/5916 +f 9527/9527/5913 9530/9530/5916 9531/9531/5917 +f 9528/9528/5914 9527/9527/5913 9531/9531/5917 +f 9528/9528/5914 9531/9531/5917 9532/9532/5918 +f 9496/9496/5882 9495/9495/5881 9533/9533/5919 +f 9496/9496/5882 9533/9533/5919 9534/9534/5920 +f 9495/9495/5881 9494/9494/5880 9535/9535/5921 +f 9495/9495/5881 9535/9535/5921 9533/9533/5919 +f 9533/9533/5919 9535/9535/5921 9536/9536/5922 +f 9533/9533/5919 9536/9536/5922 9537/9537/5923 +f 9534/9534/5920 9533/9533/5919 9537/9537/5923 +f 9534/9534/5920 9537/9537/5923 9538/9538/5924 +f 9502/9502/5888 9501/9501/5887 9539/9539/5925 +f 9502/9502/5888 9539/9539/5925 9523/9523/5909 +f 9501/9501/5887 9500/9500/5886 9516/9516/5902 +f 9501/9501/5887 9516/9516/5902 9539/9539/5925 +f 9539/9539/5925 9516/9516/5902 9520/9520/5906 +f 9539/9539/5925 9520/9520/5906 9540/9540/5926 +f 9523/9523/5909 9539/9539/5925 9540/9540/5926 +f 9523/9523/5909 9540/9540/5926 9524/9524/5910 +f 9322/9322/5715 9541/9541/5927 9542/9542/5928 +f 9322/9322/5715 9542/9542/5928 9323/9323/5716 +f 9541/9541/5927 9543/9543/5929 9544/9544/5930 +f 9541/9541/5927 9544/9544/5930 9542/9542/5928 +f 9542/9542/5928 9544/9544/5930 9545/9545/5931 +f 9542/9542/5928 9545/9545/5931 9546/9546/5932 +f 9323/9323/5716 9542/9542/5928 9546/9546/5932 +f 9323/9323/5716 9546/9546/5932 9324/9324/5717 +f 9547/9547/5933 9548/9548/5934 9549/9549/5935 +f 9547/9547/5933 9549/9549/5935 9550/9550/5936 +f 9548/9548/5934 9551/9551/5937 9552/9552/5938 +f 9548/9548/5934 9552/9552/5938 9549/9549/5935 +f 9549/9549/5935 9552/9552/5938 9553/9553/5939 +f 9549/9549/5935 9553/9553/5939 9554/9554/5940 +f 9550/9550/5936 9549/9549/5935 9554/9554/5940 +f 9550/9550/5936 9554/9554/5940 9555/9555/5941 +f 9508/9508/5894 9507/9507/5893 9556/9556/5942 +f 9508/9508/5894 9556/9556/5942 9517/9517/5903 +f 9507/9507/5893 9506/9506/5892 9557/9557/5943 +f 9507/9507/5893 9557/9557/5943 9556/9556/5942 +f 9556/9556/5942 9557/9557/5943 9558/9558/5944 +f 9556/9556/5942 9558/9558/5944 9559/9559/5945 +f 9517/9517/5903 9556/9556/5942 9559/9559/5945 +f 9517/9517/5903 9559/9559/5945 9518/9518/5904 +f 9484/9484/5870 9483/9483/5869 9560/9560/5946 +f 9484/9484/5870 9560/9560/5946 9561/9561/5947 +f 9483/9483/5869 9482/9482/5868 9562/9562/5948 +f 9483/9483/5869 9562/9562/5948 9560/9560/5946 +f 9560/9560/5946 9562/9562/5948 9563/9563/5949 +f 9560/9560/5946 9563/9563/5949 9564/9564/5950 +f 9561/9561/5947 9560/9560/5946 9564/9564/5950 +f 9561/9561/5947 9564/9564/5950 9565/9565/5951 +f 9543/9543/5929 9566/9566/5952 9567/9567/5953 +f 9543/9543/5929 9567/9567/5953 9544/9544/5930 +f 9566/9566/5952 9568/9568/5954 9569/9569/5955 +f 9566/9566/5952 9569/9569/5955 9567/9567/5953 +f 9567/9567/5953 9569/9569/5955 9570/9570/5956 +f 9567/9567/5953 9570/9570/5956 9571/9571/5957 +f 9544/9544/5930 9567/9567/5953 9571/9571/5957 +f 9544/9544/5930 9571/9571/5957 9545/9545/5931 +f 9568/9568/5954 9572/9572/5958 9573/9573/5959 +f 9568/9568/5954 9573/9573/5959 9569/9569/5955 +f 9572/9572/5958 9574/9574/5960 9575/9575/5961 +f 9572/9572/5958 9575/9575/5961 9573/9573/5959 +f 9573/9573/5959 9575/9575/5961 9576/9576/5962 +f 9573/9573/5959 9576/9576/5962 9577/9577/5963 +f 9569/9569/5955 9573/9573/5959 9577/9577/5963 +f 9569/9569/5955 9577/9577/5963 9570/9570/5956 +f 9578/9578/5964 9579/9579/5965 9580/9580/5966 +f 9578/9578/5964 9580/9580/5966 9581/9581/5967 +f 9579/9579/5965 9582/9582/5968 9583/9583/5969 +f 9579/9579/5965 9583/9583/5969 9580/9580/5966 +f 9580/9580/5966 9583/9583/5969 9584/9584/5970 +f 9580/9580/5966 9584/9584/5970 9585/9585/5971 +f 9581/9581/5967 9580/9580/5966 9585/9585/5971 +f 9581/9581/5967 9585/9585/5971 9586/9586/5972 +f 9587/9587/5973 9588/9588/5974 9589/9589/5975 +f 9587/9587/5973 9589/9589/5975 9590/9590/5976 +f 9588/9588/5974 9591/9591/5977 9592/9592/5978 +f 9588/9588/5974 9592/9592/5978 9589/9589/5975 +f 9589/9589/5975 9592/9592/5978 9593/9593/5979 +f 9589/9589/5975 9593/9593/5979 9594/9594/5980 +f 9590/9590/5976 9589/9589/5975 9594/9594/5980 +f 9590/9590/5976 9594/9594/5980 9595/9595/5981 +f 9596/9596/5982 9597/9597/5983 9598/9598/5984 +f 9596/9596/5982 9598/9598/5984 9599/9599/5985 +f 9597/9597/5983 9600/9600/5986 9601/9601/5987 +f 9597/9597/5983 9601/9601/5987 9598/9598/5984 +f 9598/9598/5984 9601/9601/5987 9602/9602/5988 +f 9598/9598/5984 9602/9602/5988 9603/9603/5989 +f 9599/9599/5985 9598/9598/5984 9603/9603/5989 +f 9599/9599/5985 9603/9603/5989 9604/9604/5990 +f 9600/9600/5986 9605/9605/5991 9606/9606/5992 +f 9600/9600/5986 9606/9606/5992 9601/9601/5987 +f 9605/9605/5991 9607/9607/5993 9608/9608/5994 +f 9605/9605/5991 9608/9608/5994 9606/9606/5992 +f 9606/9606/5992 9608/9608/5994 9609/9609/5995 +f 9606/9606/5992 9609/9609/5995 9610/9610/5996 +f 9601/9601/5987 9606/9606/5992 9610/9610/5996 +f 9601/9601/5987 9610/9610/5996 9602/9602/5988 +f 9607/9607/5993 9611/9611/5997 9612/9612/5998 +f 9607/9607/5993 9612/9612/5998 9608/9608/5994 +f 9611/9611/5997 9613/9613/5999 9614/9614/6000 +f 9611/9611/5997 9614/9614/6000 9612/9612/5998 +f 9612/9612/5998 9614/9614/6000 9615/9615/6001 +f 9612/9612/5998 9615/9615/6001 9616/9616/6002 +f 9608/9608/5994 9612/9612/5998 9616/9616/6002 +f 9608/9608/5994 9616/9616/6002 9609/9609/5995 +f 9613/9613/5999 9617/9617/6003 9618/9618/6004 +f 9613/9613/5999 9618/9618/6004 9614/9614/6000 +f 9617/9617/6003 9619/9619/6005 9620/9620/6006 +f 9617/9617/6003 9620/9620/6006 9618/9618/6004 +f 9618/9618/6004 9620/9620/6006 9621/9621/6007 +f 9618/9618/6004 9621/9621/6007 9622/9622/6008 +f 9614/9614/6000 9618/9618/6004 9622/9622/6008 +f 9614/9614/6000 9622/9622/6008 9615/9615/6001 +f 9623/9623/6009 9624/9624/6010 9625/9625/6011 +f 9623/9623/6009 9625/9625/6011 9626/9626/6012 +f 9624/9624/6010 9627/9627/6013 9628/9628/6014 +f 9624/9624/6010 9628/9628/6014 9625/9625/6011 +f 9625/9625/6011 9628/9628/6014 9629/9629/6015 +f 9625/9625/6011 9629/9629/6015 9630/9630/6016 +f 9626/9626/6012 9625/9625/6011 9630/9630/6016 +f 9626/9626/6012 9630/9630/6016 9631/9631/6017 +f 9632/9632/6018 9633/9633/6019 9634/9634/6020 +f 9632/9632/6018 9634/9634/6020 9635/9635/6021 +f 9633/9633/6019 9636/9636/6022 9637/9637/6023 +f 9633/9633/6019 9637/9637/6023 9634/9634/6020 +f 9634/9634/6020 9637/9637/6023 9591/9591/5977 +f 9634/9634/6020 9591/9591/5977 9588/9588/5974 +f 9635/9635/6021 9634/9634/6020 9588/9588/5974 +f 9635/9635/6021 9588/9588/5974 9587/9587/5973 +f 9638/9638/6024 9639/9639/6025 9640/9640/6026 +f 9638/9638/6024 9640/9640/6026 9641/9641/6027 +f 9639/9639/6025 9642/9642/6028 9643/9643/6029 +f 9639/9639/6025 9643/9643/6029 9640/9640/6026 +f 9640/9640/6026 9643/9643/6029 9644/9644/5986 +f 9640/9640/6026 9644/9644/5986 9645/9645/5983 +f 9641/9641/6027 9640/9640/6026 9645/9645/5983 +f 9641/9641/6027 9645/9645/5983 9646/9646/6030 +f 9642/9642/6028 9647/9647/6031 9648/9648/6032 +f 9642/9642/6028 9648/9648/6032 9643/9643/6029 +f 9647/9647/6031 9649/9649/6033 9650/9650/6034 +f 9647/9647/6031 9650/9650/6034 9648/9648/6032 +f 9648/9648/6032 9650/9650/6034 9651/9651/6035 +f 9648/9648/6032 9651/9651/6035 9652/9652/5991 +f 9643/9643/6029 9648/9648/6032 9652/9652/5991 +f 9643/9643/6029 9652/9652/5991 9644/9644/5986 +f 9649/9649/6033 9653/9653/6036 9654/9654/6037 +f 9649/9649/6033 9654/9654/6037 9650/9650/6034 +f 9653/9653/6036 9655/9655/6038 9656/9656/6039 +f 9653/9653/6036 9656/9656/6039 9654/9654/6037 +f 9654/9654/6037 9656/9656/6039 9657/9657/5999 +f 9654/9654/6037 9657/9657/5999 9658/9658/5997 +f 9650/9650/6034 9654/9654/6037 9658/9658/5997 +f 9650/9650/6034 9658/9658/5997 9651/9651/6035 +f 9655/9655/6038 9659/9659/6040 9660/9660/6041 +f 9655/9655/6038 9660/9660/6041 9656/9656/6039 +f 9659/9659/6040 9661/9661/6042 9662/9662/6043 +f 9659/9659/6040 9662/9662/6043 9660/9660/6041 +f 9660/9660/6041 9662/9662/6043 9663/9663/6044 +f 9660/9660/6041 9663/9663/6044 9664/9664/6003 +f 9656/9656/6039 9660/9660/6041 9664/9664/6003 +f 9656/9656/6039 9664/9664/6003 9657/9657/5999 +f 9665/9665/6045 9666/9666/6046 9667/9667/6047 +f 9665/9665/6045 9667/9667/6047 9668/9668/6048 +f 9666/9666/6046 9669/9669/6049 9670/9670/6050 +f 9666/9666/6046 9670/9670/6050 9667/9667/6047 +f 9667/9667/6047 9670/9670/6050 9671/9671/6051 +f 9667/9667/6047 9671/9671/6051 9672/9672/6010 +f 9668/9668/6048 9667/9667/6047 9672/9672/6010 +f 9668/9668/6048 9672/9672/6010 9673/9673/6009 +f 9276/9276/5671 9674/9674/6052 9675/9675/6053 +f 9276/9276/5671 9675/9675/6053 9676/9676/6054 +f 9674/9674/6052 9677/9677/6055 9678/9678/6056 +f 9674/9674/6052 9678/9678/6056 9675/9675/6053 +f 9675/9675/6053 9678/9678/6056 9679/9679/6022 +f 9675/9675/6053 9679/9679/6022 9680/9680/6019 +f 9676/9676/6054 9675/9675/6053 9680/9680/6019 +f 9676/9676/6054 9680/9680/6019 9681/9681/6018 +f 9682/9682/6057 9683/9683/6058 9684/9684/6059 +f 9682/9682/6057 9684/9684/6059 9685/9685/6060 +f 9683/9683/6058 9686/9686/6061 9687/9687/6062 +f 9683/9683/6058 9687/9687/6062 9684/9684/6059 +f 9684/9684/6059 9687/9687/6062 9642/9642/6028 +f 9684/9684/6059 9642/9642/6028 9639/9639/6025 +f 9685/9685/6060 9684/9684/6059 9639/9639/6025 +f 9685/9685/6060 9639/9639/6025 9638/9638/6024 +f 9688/9688/6061 9689/9689/6063 9690/9690/6064 +f 9688/9688/6061 9690/9690/6064 9691/9691/6062 +f 9689/9689/6063 9692/9692/6065 9693/9693/6066 +f 9689/9689/6063 9693/9693/6066 9690/9690/6064 +f 9690/9690/6064 9693/9693/6066 9694/9694/6033 +f 9690/9690/6064 9694/9694/6033 9695/9695/6067 +f 9691/9691/6062 9690/9690/6064 9695/9695/6067 +f 9691/9691/6062 9695/9695/6067 9696/9696/6068 +f 9692/9692/6065 9697/9697/6069 9698/9698/6070 +f 9692/9692/6065 9698/9698/6070 9693/9693/6066 +f 9697/9697/6069 9699/9699/6071 9700/9700/6072 +f 9697/9697/6069 9700/9700/6072 9698/9698/6070 +f 9698/9698/6070 9700/9700/6072 9701/9701/6038 +f 9698/9698/6070 9701/9701/6038 9702/9702/6036 +f 9693/9693/6066 9698/9698/6070 9702/9702/6036 +f 9693/9693/6066 9702/9702/6036 9694/9694/6033 +f 9703/9703/6071 9704/9704/6073 9705/9705/6074 +f 9703/9703/6071 9705/9705/6074 9706/9706/6075 +f 9704/9704/6073 9707/9707/6076 9708/9708/6077 +f 9704/9704/6073 9708/9708/6077 9705/9705/6074 +f 9705/9705/6074 9708/9708/6077 9661/9661/6042 +f 9705/9705/6074 9661/9661/6042 9659/9659/6040 +f 9706/9706/6075 9705/9705/6074 9659/9659/6040 +f 9706/9706/6075 9659/9659/6040 9655/9655/6038 +f 9709/9709/6078 9710/9710/6079 9711/9711/6080 +f 9709/9709/6078 9711/9711/6080 9712/9712/6081 +f 9710/9710/6079 9713/9713/6082 9714/9714/6083 +f 9710/9710/6079 9714/9714/6083 9711/9711/6080 +f 9711/9711/6080 9714/9714/6083 9715/9715/6084 +f 9711/9711/6080 9715/9715/6084 9716/9716/6046 +f 9712/9712/6081 9711/9711/6080 9716/9716/6046 +f 9712/9712/6081 9716/9716/6046 9717/9717/6045 +f 9718/9718/6085 9719/9719/6086 9720/9720/6087 +f 9718/9718/6085 9720/9720/6087 9721/9721/6088 +f 9719/9719/6086 9722/9722/6089 9723/9723/6090 +f 9719/9719/6086 9723/9723/6090 9720/9720/6087 +f 9720/9720/6087 9723/9723/6090 9724/9724/6091 +f 9720/9720/6087 9724/9724/6091 9725/9725/6092 +f 9721/9721/6088 9720/9720/6087 9725/9725/6092 +f 9721/9721/6088 9725/9725/6092 9726/9726/6093 +f 9727/9727/6078 9728/9728/6094 9729/9729/6095 +f 9727/9727/6078 9729/9729/6095 9730/9730/6096 +f 9728/9728/6094 9731/9731/6076 9732/9732/6097 +f 9728/9728/6094 9732/9732/6097 9729/9729/6095 +f 9729/9729/6095 9732/9732/6097 9733/9733/6098 +f 9729/9729/6095 9733/9733/6098 9734/9734/6099 +f 9730/9730/6096 9729/9729/6095 9734/9734/6099 +f 9730/9730/6096 9734/9734/6099 9735/9735/6100 +f 9731/9731/6076 9736/9736/6073 9737/9737/6101 +f 9731/9731/6076 9737/9737/6101 9732/9732/6097 +f 9736/9736/6073 9703/9703/6071 9738/9738/6102 +f 9736/9736/6073 9738/9738/6102 9737/9737/6101 +f 9737/9737/6101 9738/9738/6102 9739/9739/6103 +f 9737/9737/6101 9739/9739/6103 9740/9740/6104 +f 9732/9732/6097 9737/9737/6101 9740/9740/6104 +f 9732/9732/6097 9740/9740/6104 9733/9733/6098 +f 9703/9703/6071 9741/9741/6069 9742/9742/6105 +f 9703/9703/6071 9742/9742/6105 9738/9738/6102 +f 9741/9741/6069 9743/9743/6065 9744/9744/6106 +f 9741/9741/6069 9744/9744/6106 9742/9742/6105 +f 9742/9742/6105 9744/9744/6106 9745/9745/6107 +f 9742/9742/6105 9745/9745/6107 9746/9746/6108 +f 9738/9738/6102 9742/9742/6105 9746/9746/6108 +f 9738/9738/6102 9746/9746/6108 9739/9739/6103 +f 9743/9743/6065 9747/9747/6063 9748/9748/6109 +f 9743/9743/6065 9748/9748/6109 9744/9744/6106 +f 9747/9747/6063 9686/9686/6110 9749/9749/6111 +f 9747/9747/6063 9749/9749/6111 9748/9748/6109 +f 9748/9748/6109 9749/9749/6111 9750/9750/6112 +f 9748/9748/6109 9750/9750/6112 9751/9751/6113 +f 9744/9744/6106 9748/9748/6109 9751/9751/6113 +f 9744/9744/6106 9751/9751/6113 9745/9745/6107 +f 9752/9752/6057 9753/9753/6114 9754/9754/6115 +f 9752/9752/6057 9754/9754/6115 9755/9755/6116 +f 9753/9753/6114 9756/9756/6117 9757/9757/6118 +f 9753/9753/6114 9757/9757/6118 9754/9754/6115 +f 9754/9754/6115 9757/9757/6118 9758/9758/6119 +f 9754/9754/6115 9758/9758/6119 9759/9759/6120 +f 9755/9755/6116 9754/9754/6115 9759/9759/6120 +f 9755/9755/6116 9759/9759/6120 9760/9760/6121 +f 9761/9761/6098 9762/9762/6104 9763/9763/6122 +f 9761/9761/6098 9763/9763/6122 9764/9764/6123 +f 9762/9762/6104 9765/9765/6103 9766/9766/6124 +f 9762/9762/6104 9766/9766/6124 9763/9763/6122 +f 9763/9763/6122 9766/9766/6124 9767/9767/6125 +f 9763/9763/6122 9767/9767/6125 9768/9768/6126 +f 9764/9764/6123 9763/9763/6122 9768/9768/6126 +f 9764/9764/6123 9768/9768/6126 9769/9769/6127 +f 9770/9770/6107 9771/9771/6113 9772/9772/6128 +f 9770/9770/6107 9772/9772/6128 9773/9773/6129 +f 9771/9771/6113 9774/9774/6112 9775/9775/6130 +f 9771/9771/6113 9775/9775/6130 9772/9772/6128 +f 9772/9772/6128 9775/9775/6130 9776/9776/6131 +f 9772/9772/6128 9776/9776/6131 9777/9777/6132 +f 9773/9773/6129 9772/9772/6128 9777/9777/6132 +f 9773/9773/6129 9777/9777/6132 9778/9778/6133 +f 9779/9779/5679 9780/9780/6134 9781/9781/6135 +f 9779/9779/5679 9781/9781/6135 9782/9782/6136 +f 9780/9780/6134 9783/9783/6137 9784/9784/6138 +f 9780/9780/6134 9784/9784/6138 9781/9781/6135 +f 9781/9781/6135 9784/9784/6138 9785/9785/6139 +f 9781/9781/6135 9785/9785/6139 9786/9786/6140 +f 9782/9782/6136 9781/9781/6135 9786/9786/6140 +f 9782/9782/6136 9786/9786/6140 9787/9787/6141 +f 9788/9788/6100 9789/9789/6142 9790/9790/6143 +f 9788/9788/6100 9790/9790/6143 9791/9791/6144 +f 9789/9789/6142 9761/9761/6098 9764/9764/6123 +f 9789/9789/6142 9764/9764/6123 9790/9790/6143 +f 9790/9790/6143 9764/9764/6123 9769/9769/6127 +f 9790/9790/6143 9769/9769/6127 9792/9792/6145 +f 9791/9791/6144 9790/9790/6143 9792/9792/6145 +f 9791/9791/6144 9792/9792/6145 9793/9793/6146 +f 9794/9794/6093 9795/9795/6092 9796/9796/6147 +f 9794/9794/6093 9796/9796/6147 9797/9797/6148 +f 9795/9795/6092 9798/9798/6149 9799/9799/6150 +f 9795/9795/6092 9799/9799/6150 9796/9796/6147 +f 9796/9796/6147 9799/9799/6150 9800/9800/6151 +f 9796/9796/6147 9800/9800/6151 9801/9801/6152 +f 9797/9797/6148 9796/9796/6147 9801/9801/6152 +f 9797/9797/6148 9801/9801/6152 9802/9802/6153 +f 9765/9765/6103 9803/9803/6154 9804/9804/6155 +f 9765/9765/6103 9804/9804/6155 9766/9766/6124 +f 9803/9803/6154 9770/9770/6107 9773/9773/6129 +f 9803/9803/6154 9773/9773/6129 9804/9804/6155 +f 9804/9804/6155 9773/9773/6129 9778/9778/6133 +f 9804/9804/6155 9778/9778/6133 9805/9805/6156 +f 9766/9766/6124 9804/9804/6155 9805/9805/6156 +f 9766/9766/6124 9805/9805/6156 9767/9767/6125 +f 9760/9760/6121 9759/9759/6120 9806/9806/6157 +f 9760/9760/6121 9806/9806/6157 9807/9807/6158 +f 9759/9759/6120 9758/9758/6119 9808/9808/6159 +f 9759/9759/6120 9808/9808/6159 9806/9806/6157 +f 9806/9806/6157 9808/9808/6159 9809/9809/6160 +f 9806/9806/6157 9809/9809/6160 9810/9810/6161 +f 9807/9807/6158 9806/9806/6157 9810/9810/6161 +f 9807/9807/6158 9810/9810/6161 9811/9811/6162 +f 9812/9812/5995 9813/9813/6002 9814/9814/6163 +f 9812/9812/5995 9814/9814/6163 9815/9815/6164 +f 9813/9813/6002 9816/9816/6001 9817/9817/6165 +f 9813/9813/6002 9817/9817/6165 9814/9814/6163 +f 9814/9814/6163 9817/9817/6165 9354/9354/5747 +f 9814/9814/6163 9354/9354/5747 9818/9818/6166 +f 9815/9815/6164 9814/9814/6163 9818/9818/6166 +f 9815/9815/6164 9818/9818/6166 9819/9819/5733 +f 9820/9820/5990 9821/9821/5989 9822/9822/6167 +f 9820/9820/5990 9822/9822/6167 9823/9823/6168 +f 9821/9821/5989 9824/9824/5988 9825/9825/6169 +f 9821/9821/5989 9825/9825/6169 9822/9822/6167 +f 9822/9822/6167 9825/9825/6169 9826/9826/5729 +f 9822/9822/6167 9826/9826/5729 9827/9827/5766 +f 9823/9823/6168 9822/9822/6167 9827/9827/5766 +f 9823/9823/6168 9827/9827/5766 9828/9828/5765 +f 9829/9829/5701 9830/9830/5700 9831/9831/6170 +f 9829/9829/5701 9831/9831/6170 9832/9832/6171 +f 9830/9830/5700 9833/9833/6172 9834/9834/6173 +f 9830/9830/5700 9834/9834/6173 9831/9831/6170 +f 9831/9831/6170 9834/9834/6173 9367/9367/5760 +f 9831/9831/6170 9367/9367/5760 9364/9364/5757 +f 9832/9832/6171 9831/9831/6170 9364/9364/5757 +f 9832/9832/6171 9364/9364/5757 9363/9363/5756 +f 9816/9816/6001 9835/9835/6008 9836/9836/6174 +f 9816/9816/6001 9836/9836/6174 9817/9817/6165 +f 9835/9835/6008 9837/9837/6007 9838/9838/6175 +f 9835/9835/6008 9838/9838/6175 9836/9836/6174 +f 9836/9836/6174 9838/9838/6175 9358/9358/5751 +f 9836/9836/6174 9358/9358/5751 9355/9355/5748 +f 9817/9817/6165 9836/9836/6174 9355/9355/5748 +f 9817/9817/6165 9355/9355/5748 9354/9354/5747 +f 9839/9839/5981 9840/9840/5980 9841/9841/6176 +f 9839/9839/5981 9841/9841/6176 9842/9842/6177 +f 9840/9840/5980 9843/9843/5979 9844/9844/6178 +f 9840/9840/5980 9844/9844/6178 9841/9841/6176 +f 9841/9841/6176 9844/9844/6178 9349/9349/5742 +f 9841/9841/6176 9349/9349/5742 9346/9346/5739 +f 9842/9842/6177 9841/9841/6176 9346/9346/5739 +f 9842/9842/6177 9346/9346/5739 9345/9345/5738 +f 9602/9602/5988 9610/9610/5996 9845/9845/6179 +f 9602/9602/5988 9845/9845/6179 9825/9825/6180 +f 9610/9610/5996 9609/9609/5995 9846/9846/6181 +f 9610/9610/5996 9846/9846/6181 9845/9845/6179 +f 9845/9845/6179 9846/9846/6181 9819/9819/5733 +f 9845/9845/6179 9819/9819/5733 9847/9847/5730 +f 9825/9825/6180 9845/9845/6179 9847/9847/5730 +f 9825/9825/6180 9847/9847/5730 9848/9848/5729 +f 9849/9849/6182 9850/9850/6016 9851/9851/6183 +f 9849/9849/6182 9851/9851/6183 9852/9852/6184 +f 9850/9850/6016 9853/9853/6015 9854/9854/6185 +f 9850/9850/6016 9854/9854/6185 9851/9851/6183 +f 9851/9851/6183 9854/9854/6185 9331/9331/5724 +f 9851/9851/6183 9331/9331/5724 9328/9328/5721 +f 9852/9852/6184 9851/9851/6183 9328/9328/5721 +f 9852/9852/6184 9328/9328/5721 9327/9327/5720 +f 9388/9388/5735 9387/9387/5774 9855/9855/6186 +f 9388/9388/5735 9855/9855/6186 9856/9856/6187 +f 9387/9387/5774 9386/9386/5755 9857/9857/6188 +f 9387/9387/5774 9857/9857/6188 9855/9855/6186 +f 9855/9855/6186 9857/9857/6188 9858/9858/5793 +f 9855/9855/6186 9858/9858/5793 9440/9440/6189 +f 9856/9856/6187 9855/9855/6186 9440/9440/6189 +f 9856/9856/6187 9440/9440/6189 9859/9859/5779 +f 9860/9860/5728 9861/9861/6190 9862/9862/6191 +f 9860/9860/5728 9862/9862/6191 9863/9863/6192 +f 9861/9861/6190 9864/9864/6193 9865/9865/6194 +f 9861/9861/6190 9865/9865/6194 9862/9862/6191 +f 9862/9862/6191 9865/9865/6194 9866/9866/6195 +f 9862/9862/6191 9866/9866/6195 9867/9867/5818 +f 9863/9863/6192 9862/9862/6191 9867/9867/5818 +f 9863/9863/6192 9867/9867/5818 9868/9868/5817 +f 9869/9869/5746 9870/9870/5745 9871/9871/6196 +f 9869/9869/5746 9871/9871/6196 9872/9872/6197 +f 9870/9870/5745 9873/9873/6198 9874/9874/6199 +f 9870/9870/5745 9874/9874/6199 9871/9871/6196 +f 9871/9871/6196 9874/9874/6199 9426/9426/5812 +f 9871/9871/6196 9426/9426/5812 9423/9423/5809 +f 9872/9872/6197 9871/9871/6196 9423/9423/5809 +f 9872/9872/6197 9423/9423/5809 9422/9422/5808 +f 9379/9379/5770 9378/9378/5769 9875/9875/6200 +f 9379/9379/5770 9875/9875/6200 9876/9876/6201 +f 9378/9378/5769 9377/9377/5737 9877/9877/6202 +f 9378/9378/5769 9877/9877/6202 9875/9875/6200 +f 9875/9875/6200 9877/9877/6202 9878/9878/6203 +f 9875/9875/6200 9878/9878/6203 9879/9879/5803 +f 9876/9876/6201 9875/9875/6200 9879/9879/5803 +f 9876/9876/6201 9879/9879/5803 9880/9880/5802 +f 9386/9386/5755 9881/9881/6204 9882/9882/6205 +f 9386/9386/5755 9882/9882/6205 9857/9857/6188 +f 9881/9881/6204 9883/9883/5753 9884/9884/6206 +f 9881/9881/6204 9884/9884/6206 9882/9882/6205 +f 9882/9882/6205 9884/9884/6206 9885/9885/5797 +f 9882/9882/6205 9885/9885/5797 9886/9886/5794 +f 9857/9857/6188 9882/9882/6205 9886/9886/5794 +f 9857/9857/6188 9886/9886/5794 9858/9858/5793 +f 9887/9887/5764 9888/9888/5763 9889/9889/6207 +f 9887/9887/5764 9889/9889/6207 9890/9890/6208 +f 9888/9888/5763 9891/9891/5762 9892/9892/6209 +f 9888/9888/5763 9892/9892/6209 9889/9889/6207 +f 9889/9889/6207 9892/9892/6209 9402/9402/5788 +f 9889/9889/6207 9402/9402/5788 9399/9399/5785 +f 9890/9890/6208 9889/9889/6207 9399/9399/5785 +f 9890/9890/6208 9399/9399/5785 9398/9398/5784 +f 9344/9344/5737 9343/9343/5736 9893/9893/6210 +f 9344/9344/5737 9893/9893/6210 9877/9877/6202 +f 9343/9343/5736 9342/9342/5735 9894/9894/6211 +f 9343/9343/5736 9894/9894/6211 9893/9893/6210 +f 9893/9893/6210 9894/9894/6211 9393/9393/5779 +f 9893/9893/6210 9393/9393/5779 9390/9390/5776 +f 9877/9877/6202 9893/9893/6210 9390/9390/5776 +f 9877/9877/6202 9390/9390/5776 9389/9389/5775 +f 9895/9895/5744 9896/9896/6212 9897/9897/6213 +f 9895/9895/5744 9897/9897/6213 9898/9898/6214 +f 9896/9896/6212 9379/9379/5770 9876/9876/6201 +f 9896/9896/6212 9876/9876/6201 9897/9897/6213 +f 9897/9897/6213 9876/9876/6201 9880/9880/5802 +f 9897/9897/6213 9880/9880/5802 9899/9899/6215 +f 9898/9898/6214 9897/9897/6213 9899/9899/6215 +f 9898/9898/6214 9899/9899/6215 9426/9426/5812 +f 9593/9593/5979 9900/9900/6216 9901/9901/6217 +f 9593/9593/5979 9901/9901/6217 9902/9902/6178 +f 9900/9900/6216 9820/9820/5990 9823/9823/6168 +f 9900/9900/6216 9823/9823/6168 9901/9901/6217 +f 9901/9901/6217 9823/9823/6168 9828/9828/5765 +f 9901/9901/6217 9828/9828/5765 9903/9903/6218 +f 9902/9902/6178 9901/9901/6217 9903/9903/6218 +f 9902/9902/6178 9903/9903/6218 9349/9349/5742 +f 9774/9774/6112 9904/9904/6219 9905/9905/6220 +f 9774/9774/6112 9905/9905/6220 9775/9775/6130 +f 9904/9904/6219 9760/9760/6121 9807/9807/6158 +f 9904/9904/6219 9807/9807/6158 9905/9905/6220 +f 9905/9905/6220 9807/9807/6158 9811/9811/6162 +f 9905/9905/6220 9811/9811/6162 9906/9906/6221 +f 9775/9775/6130 9905/9905/6220 9906/9906/6221 +f 9775/9775/6130 9906/9906/6221 9776/9776/6131 +f 9686/9686/6110 9907/9907/6058 9908/9908/6222 +f 9686/9686/6110 9908/9908/6222 9749/9749/6111 +f 9907/9907/6058 9752/9752/6057 9909/9909/6116 +f 9907/9907/6058 9909/9909/6116 9908/9908/6222 +f 9908/9908/6222 9909/9909/6116 9910/9910/6223 +f 9908/9908/6222 9910/9910/6223 9911/9911/6219 +f 9749/9749/6111 9908/9908/6222 9911/9911/6219 +f 9749/9749/6111 9911/9911/6219 9750/9750/6112 +f 9677/9677/6055 9912/9912/6114 9913/9913/6224 +f 9677/9677/6055 9913/9913/6224 9678/9678/6056 +f 9912/9912/6114 9682/9682/6057 9685/9685/6060 +f 9912/9912/6114 9685/9685/6060 9913/9913/6224 +f 9913/9913/6224 9685/9685/6060 9638/9638/6024 +f 9913/9913/6224 9638/9638/6024 9914/9914/6225 +f 9678/9678/6056 9913/9913/6224 9914/9914/6225 +f 9678/9678/6056 9914/9914/6225 9679/9679/6022 +f 9679/9679/6022 9914/9914/6225 9915/9915/6226 +f 9679/9679/6022 9915/9915/6226 9916/9916/6227 +f 9914/9914/6225 9638/9638/6024 9641/9641/6027 +f 9914/9914/6225 9641/9641/6027 9915/9915/6226 +f 9915/9915/6226 9641/9641/6027 9646/9646/6030 +f 9915/9915/6226 9646/9646/6030 9917/9917/6228 +f 9916/9916/6227 9915/9915/6226 9917/9917/6228 +f 9916/9916/6227 9917/9917/6228 9918/9918/5977 +f 9591/9591/5977 9919/9919/6229 9920/9920/6230 +f 9591/9591/5977 9920/9920/6230 9592/9592/5978 +f 9919/9919/6229 9596/9596/5982 9599/9599/5985 +f 9919/9919/6229 9599/9599/5985 9920/9920/6230 +f 9920/9920/6230 9599/9599/5985 9820/9820/5990 +f 9920/9920/6230 9820/9820/5990 9900/9900/6216 +f 9592/9592/5978 9920/9920/6230 9900/9900/6216 +f 9592/9592/5978 9900/9900/6216 9593/9593/5979 +f 9488/9488/5874 9921/9921/6231 9922/9922/6232 +f 9488/9488/5874 9922/9922/6232 9529/9529/5915 +f 9921/9921/6231 9512/9512/5898 9522/9522/5908 +f 9921/9921/6231 9522/9522/5908 9922/9922/6232 +f 9922/9922/6232 9522/9522/5908 9526/9526/5912 +f 9922/9922/6232 9526/9526/5912 9923/9923/6233 +f 9529/9529/5915 9922/9922/6232 9923/9923/6233 +f 9529/9529/5915 9923/9923/6233 9530/9530/5916 +f 9470/9470/5856 9924/9924/6234 9925/9925/6235 +f 9470/9470/5856 9925/9925/6235 9487/9487/5873 +f 9924/9924/6234 9454/9454/5840 9510/9510/5896 +f 9924/9924/6234 9510/9510/5896 9925/9925/6235 +f 9925/9925/6235 9510/9510/5896 9512/9512/5898 +f 9925/9925/6235 9512/9512/5898 9921/9921/6231 +f 9487/9487/5873 9925/9925/6235 9921/9921/6231 +f 9487/9487/5873 9921/9921/6231 9488/9488/5874 +f 9428/9428/5814 9926/9926/6236 9927/9927/6237 +f 9428/9428/5814 9927/9927/6237 9469/9469/5855 +f 9926/9926/6236 9421/9421/5807 9450/9450/5836 +f 9926/9926/6236 9450/9450/5836 9927/9927/6237 +f 9927/9927/6237 9450/9450/5836 9454/9454/5840 +f 9927/9927/6237 9454/9454/5840 9924/9924/6234 +f 9469/9469/5855 9927/9927/6237 9924/9924/6234 +f 9469/9469/5855 9924/9924/6234 9470/9470/5856 +f 9426/9426/5812 9928/9928/6238 9929/9929/6239 +f 9426/9426/5812 9929/9929/6239 9427/9427/5813 +f 9928/9928/6238 9416/9416/5802 9419/9419/5805 +f 9928/9928/6238 9419/9419/5805 9929/9929/6239 +f 9929/9929/6239 9419/9419/5805 9421/9421/5807 +f 9929/9929/6239 9421/9421/5807 9926/9926/6236 +f 9427/9427/5813 9929/9929/6239 9926/9926/6236 +f 9427/9427/5813 9926/9926/6236 9428/9428/5814 +f 9349/9349/5742 9903/9903/6218 9930/9930/6240 +f 9349/9349/5742 9930/9930/6240 9931/9931/5743 +f 9903/9903/6218 9828/9828/5765 9932/9932/5768 +f 9903/9903/6218 9932/9932/5768 9930/9930/6240 +f 9930/9930/6240 9932/9932/5768 9933/9933/6241 +f 9930/9930/6240 9933/9933/6241 9934/9934/6212 +f 9931/9931/5743 9930/9930/6240 9934/9934/6212 +f 9931/9931/5743 9934/9934/6212 9935/9935/5744 +f 9582/9582/5968 9936/9936/6242 9937/9937/6243 +f 9582/9582/5968 9937/9937/6243 9583/9583/5969 +f 9936/9936/6242 9318/9318/5711 9321/9321/5714 +f 9936/9936/6242 9321/9321/5714 9937/9937/6243 +f 9937/9937/6243 9321/9321/5714 9326/9326/5719 +f 9937/9937/6243 9326/9326/5719 9938/9938/6244 +f 9583/9583/5969 9937/9937/6243 9938/9938/6244 +f 9583/9583/5969 9938/9938/6244 9584/9584/5970 +f 9883/9883/5753 9939/9939/6245 9940/9940/6246 +f 9883/9883/5753 9940/9940/6246 9884/9884/6206 +f 9939/9939/6245 9860/9860/5728 9863/9863/6192 +f 9939/9939/6245 9863/9863/6192 9940/9940/6246 +f 9940/9940/6246 9863/9863/6192 9868/9868/5817 +f 9940/9940/6246 9868/9868/5817 9941/9941/6247 +f 9884/9884/6206 9940/9940/6246 9941/9941/6247 +f 9884/9884/6206 9941/9941/6247 9885/9885/5797 +f 9837/9837/6007 9942/9942/6248 9943/9943/6249 +f 9837/9837/6007 9943/9943/6249 9838/9838/6175 +f 9942/9942/6248 9849/9849/6182 9852/9852/6184 +f 9942/9942/6248 9852/9852/6184 9943/9943/6249 +f 9943/9943/6249 9852/9852/6184 9327/9327/5720 +f 9943/9943/6249 9327/9327/5720 9944/9944/6250 +f 9838/9838/6175 9943/9943/6249 9944/9944/6250 +f 9838/9838/6175 9944/9944/6250 9358/9358/5751 +f 9798/9798/6149 9945/9945/6251 9946/9946/6252 +f 9798/9798/6149 9946/9946/6252 9799/9799/6150 +f 9945/9945/6251 9788/9788/6100 9791/9791/6144 +f 9945/9945/6251 9791/9791/6144 9946/9946/6252 +f 9946/9946/6252 9791/9791/6144 9793/9793/6146 +f 9946/9946/6252 9793/9793/6146 9947/9947/6253 +f 9799/9799/6150 9946/9946/6252 9947/9947/6253 +f 9799/9799/6150 9947/9947/6253 9800/9800/6151 +f 9722/9722/6089 9948/9948/6254 9949/9949/6255 +f 9722/9722/6089 9949/9949/6255 9723/9723/6090 +f 9948/9948/6254 9727/9727/6078 9730/9730/6096 +f 9948/9948/6254 9730/9730/6096 9949/9949/6255 +f 9949/9949/6255 9730/9730/6096 9735/9735/6100 +f 9949/9949/6255 9735/9735/6100 9950/9950/6251 +f 9723/9723/6090 9949/9949/6255 9950/9950/6251 +f 9723/9723/6090 9950/9950/6251 9724/9724/6091 +f 9707/9707/6076 9951/9951/6094 9952/9952/6256 +f 9707/9707/6076 9952/9952/6256 9708/9708/6077 +f 9951/9951/6094 9727/9727/6078 9953/9953/6081 +f 9951/9951/6094 9953/9953/6081 9952/9952/6256 +f 9952/9952/6256 9953/9953/6081 9665/9665/6045 +f 9952/9952/6256 9665/9665/6045 9954/9954/6257 +f 9708/9708/6077 9952/9952/6256 9954/9954/6257 +f 9708/9708/6077 9954/9954/6257 9661/9661/6042 +f 9661/9661/6042 9954/9954/6257 9955/9955/6258 +f 9661/9661/6042 9955/9955/6258 9662/9662/6043 +f 9954/9954/6257 9665/9665/6045 9668/9668/6048 +f 9954/9954/6257 9668/9668/6048 9955/9955/6258 +f 9955/9955/6258 9668/9668/6048 9673/9673/6009 +f 9955/9955/6258 9673/9673/6009 9956/9956/6259 +f 9662/9662/6043 9955/9955/6258 9956/9956/6259 +f 9662/9662/6043 9956/9956/6259 9663/9663/6044 +f 9619/9619/6005 9957/9957/6259 9958/9958/6260 +f 9619/9619/6005 9958/9958/6260 9620/9620/6006 +f 9957/9957/6259 9623/9623/6009 9626/9626/6012 +f 9957/9957/6259 9626/9626/6012 9958/9958/6260 +f 9958/9958/6260 9626/9626/6012 9631/9631/6017 +f 9958/9958/6260 9631/9631/6017 9942/9942/6248 +f 9620/9620/6006 9958/9958/6260 9942/9942/6248 +f 9620/9620/6006 9942/9942/6248 9621/9621/6007 +f 9574/9574/5960 9959/9959/6261 9960/9960/6262 +f 9574/9574/5960 9960/9960/6262 9575/9575/5961 +f 9959/9959/6261 9547/9547/5933 9550/9550/5936 +f 9959/9959/6261 9550/9550/5936 9960/9960/6262 +f 9960/9960/6262 9550/9550/5936 9555/9555/5941 +f 9960/9960/6262 9555/9555/5941 9961/9961/6263 +f 9575/9575/5961 9960/9960/6262 9961/9961/6263 +f 9575/9575/5961 9961/9961/6263 9576/9576/5962 +f 9506/9506/5892 9962/9962/6264 9963/9963/6265 +f 9506/9506/5892 9963/9963/6265 9557/9557/5943 +f 9962/9962/6264 9496/9496/5882 9534/9534/5920 +f 9962/9962/6264 9534/9534/5920 9963/9963/6265 +f 9963/9963/6265 9534/9534/5920 9538/9538/5924 +f 9963/9963/6265 9538/9538/5924 9964/9964/6266 +f 9557/9557/5943 9963/9963/6265 9964/9964/6266 +f 9557/9557/5943 9964/9964/6266 9558/9558/5944 +f 9477/9477/5863 9965/9965/6267 9966/9966/6268 +f 9477/9477/5863 9966/9966/6268 9505/9505/5891 +f 9965/9965/6267 9466/9466/5852 9492/9492/5878 +f 9965/9965/6267 9492/9492/5878 9966/9966/6268 +f 9966/9966/6268 9492/9492/5878 9496/9496/5882 +f 9966/9966/6268 9496/9496/5882 9962/9962/6264 +f 9505/9505/5891 9966/9966/6268 9962/9962/6264 +f 9505/9505/5891 9962/9962/6264 9506/9506/5892 +f 9413/9413/5799 9967/9967/6269 9968/9968/6270 +f 9413/9413/5799 9968/9968/6270 9476/9476/5862 +f 9967/9967/6269 9439/9439/5825 9462/9462/5848 +f 9967/9967/6269 9462/9462/5848 9968/9968/6270 +f 9968/9968/6270 9462/9462/5848 9466/9466/5852 +f 9968/9968/6270 9466/9466/5852 9965/9965/6267 +f 9476/9476/5862 9968/9968/6270 9965/9965/6267 +f 9476/9476/5862 9965/9965/6267 9477/9477/5863 +f 9411/9411/5797 9969/9969/6247 9970/9970/6271 +f 9411/9411/5797 9970/9970/6271 9412/9412/5798 +f 9969/9969/6247 9431/9431/5817 9434/9434/5820 +f 9969/9969/6247 9434/9434/5820 9970/9970/6271 +f 9970/9970/6271 9434/9434/5820 9439/9439/5825 +f 9970/9970/6271 9439/9439/5825 9967/9967/6269 +f 9412/9412/5798 9970/9970/6271 9967/9967/6269 +f 9412/9412/5798 9967/9967/6269 9413/9413/5799 +f 9971/9971/5751 9972/9972/6272 9973/9973/6273 +f 9971/9971/5751 9973/9973/6273 9974/9974/6274 +f 9972/9972/6272 9975/9975/5720 9976/9976/5723 +f 9972/9972/6272 9976/9976/5723 9973/9973/6273 +f 9973/9973/6273 9976/9976/5723 9860/9860/5728 +f 9973/9973/6273 9860/9860/5728 9939/9939/6245 +f 9974/9974/6274 9973/9973/6273 9939/9939/6245 +f 9974/9974/6274 9939/9939/6245 9883/9883/5753 +f 9558/9558/5944 9964/9964/6266 9977/9977/6275 +f 9558/9558/5944 9977/9977/6275 9978/9978/6276 +f 9964/9964/6266 9538/9538/5924 9979/9979/6277 +f 9964/9964/6266 9979/9979/6277 9977/9977/6275 +f 9977/9977/6275 9979/9979/6277 9547/9547/5933 +f 9977/9977/6275 9547/9547/5933 9959/9959/6261 +f 9978/9978/6276 9977/9977/6275 9959/9959/6261 +f 9978/9978/6276 9959/9959/6261 9574/9574/5960 +f 9530/9530/5916 9923/9923/6233 9980/9980/6278 +f 9530/9530/5916 9980/9980/6278 9981/9981/6279 +f 9923/9923/6233 9526/9526/5912 9982/9982/6280 +f 9923/9923/6233 9982/9982/6280 9980/9980/6278 +f 9980/9980/6278 9982/9982/6280 9318/9318/5711 +f 9980/9980/6278 9318/9318/5711 9936/9936/6242 +f 9981/9981/6279 9980/9980/6278 9936/9936/6242 +f 9981/9981/6279 9936/9936/6242 9582/9582/5968 +f 9532/9532/5918 9531/9531/5917 9983/9983/6281 +f 9532/9532/5918 9983/9983/6281 9984/9984/6282 +f 9531/9531/5917 9530/9530/5916 9981/9981/6279 +f 9531/9531/5917 9981/9981/6279 9983/9983/6281 +f 9983/9983/6281 9981/9981/6279 9582/9582/5968 +f 9983/9983/6281 9582/9582/5968 9579/9579/5965 +f 9984/9984/6282 9983/9983/6281 9579/9579/5965 +f 9984/9984/6282 9579/9579/5965 9578/9578/5964 +f 9518/9518/5904 9559/9559/5945 9985/9985/6283 +f 9518/9518/5904 9985/9985/6283 9986/9986/6284 +f 9559/9559/5945 9558/9558/5944 9978/9978/6276 +f 9559/9559/5945 9978/9978/6276 9985/9985/6283 +f 9985/9985/6283 9978/9978/6276 9574/9574/5960 +f 9985/9985/6283 9574/9574/5960 9572/9572/5958 +f 9986/9986/6284 9985/9985/6283 9572/9572/5958 +f 9986/9986/6284 9572/9572/5958 9568/9568/5954 +f 9520/9520/5906 9519/9519/5905 9987/9987/6285 +f 9520/9520/5906 9987/9987/6285 9988/9988/6286 +f 9519/9519/5905 9518/9518/5904 9986/9986/6284 +f 9519/9519/5905 9986/9986/6284 9987/9987/6285 +f 9987/9987/6285 9986/9986/6284 9568/9568/5954 +f 9987/9987/6285 9568/9568/5954 9566/9566/5952 +f 9988/9988/6286 9987/9987/6285 9566/9566/5952 +f 9988/9988/6286 9566/9566/5952 9543/9543/5929 +f 9538/9538/5924 9537/9537/5923 9989/9989/6287 +f 9538/9538/5924 9989/9989/6287 9979/9979/6277 +f 9537/9537/5923 9536/9536/5922 9990/9990/6288 +f 9537/9537/5923 9990/9990/6288 9989/9989/6287 +f 9989/9989/6287 9990/9990/6288 9551/9551/5937 +f 9989/9989/6287 9551/9551/5937 9548/9548/5934 +f 9979/9979/6277 9989/9989/6287 9548/9548/5934 +f 9979/9979/6277 9548/9548/5934 9547/9547/5933 +f 9524/9524/5910 9540/9540/5926 9991/9991/6289 +f 9524/9524/5910 9991/9991/6289 9992/9992/6290 +f 9540/9540/5926 9520/9520/5906 9988/9988/6286 +f 9540/9540/5926 9988/9988/6286 9991/9991/6289 +f 9991/9991/6289 9988/9988/6286 9543/9543/5929 +f 9991/9991/6289 9543/9543/5929 9541/9541/5927 +f 9992/9992/6290 9991/9991/6289 9541/9541/5927 +f 9992/9992/6290 9541/9541/5927 9322/9322/5715 +f 9526/9526/5912 9525/9525/5911 9993/9993/6291 +f 9526/9526/5912 9993/9993/6291 9982/9982/6280 +f 9525/9525/5911 9524/9524/5910 9992/9992/6290 +f 9525/9525/5911 9992/9992/6290 9993/9993/6291 +f 9993/9993/6291 9992/9992/6290 9322/9322/5715 +f 9993/9993/6291 9322/9322/5715 9319/9319/5712 +f 9982/9982/6280 9993/9993/6291 9319/9319/5712 +f 9982/9982/6280 9319/9319/5712 9318/9318/5711 +f 9565/9565/5951 9564/9564/5950 9994/9994/6292 +f 9565/9565/5951 9994/9994/6292 9995/9995/6293 +f 9564/9564/5950 9563/9563/5949 9996/9996/6294 +f 9564/9564/5950 9996/9996/6294 9994/9994/6292 +f 9994/9994/6292 9996/9996/6294 9997/9997/5706 +f 9994/9994/6292 9997/9997/5706 9310/9310/5703 +f 9995/9995/6293 9994/9994/6292 9310/9310/5703 +f 9995/9995/6293 9310/9310/5703 9309/9309/5702 +f 9536/9536/5922 9998/9998/6295 9999/9999/6296 +f 9536/9536/5922 9999/9999/6296 9990/9990/6288 +f 9998/9998/6295 9565/9565/5951 9995/9995/6293 +f 9998/9998/6295 9995/9995/6293 9999/9999/6296 +f 9999/9999/6296 9995/9995/6293 9309/9309/5702 +f 9999/9999/6296 9309/9309/5702 10000/10000/6297 +f 9990/9990/6288 9999/9999/6296 10000/10000/6297 +f 9990/9990/6288 10000/10000/6297 9551/9551/5937 +f 10001/10001/5726 10002/10002/6298 10003/10003/6299 +f 10001/10001/5726 10003/10003/6299 10004/10004/6194 +f 10002/10002/6298 9887/9887/5764 9890/9890/6208 +f 10002/10002/6298 9890/9890/6208 10003/10003/6299 +f 10003/10003/6299 9890/9890/6208 9398/9398/5784 +f 10003/10003/6299 9398/9398/5784 10005/10005/6300 +f 10004/10004/6194 10003/10003/6299 10005/10005/6300 +f 10004/10004/6194 10005/10005/6300 9435/9435/5821 +f 9629/9629/6015 10006/10006/6301 10007/10007/6302 +f 9629/9629/6015 10007/10007/6302 10008/10008/6303 +f 10006/10006/6301 9829/9829/5701 9832/9832/6171 +f 10006/10006/6301 9832/9832/6171 10007/10007/6302 +f 10007/10007/6302 9832/9832/6171 9363/9363/5756 +f 10007/10007/6302 9363/9363/5756 10009/10009/6304 +f 10008/10008/6303 10007/10007/6302 10009/10009/6304 +f 10008/10008/6303 10009/10009/6304 10010/10010/5724 +f 10011/10011/6305 10012/10012/6306 10013/10013/6307 +f 10011/10011/6305 10013/10013/6307 10014/10014/6308 +f 10012/10012/6306 9726/9726/6093 10015/10015/6148 +f 10012/10012/6306 10015/10015/6148 10013/10013/6307 +f 10013/10013/6307 10015/10015/6148 10016/10016/6153 +f 10013/10013/6307 10016/10016/6153 10017/10017/6309 +f 10014/10014/6308 10013/10013/6307 10017/10017/6309 +f 10014/10014/6308 10017/10017/6309 10018/10018/6310 +f 10019/10019/6311 10020/10020/5681 10021/10021/6312 +f 10019/10019/6311 10021/10021/6312 10022/10022/6313 +f 10020/10020/5681 9285/9285/5680 10023/10023/6088 +f 10020/10020/5681 10023/10023/6088 10021/10021/6312 +f 10021/10021/6312 10023/10023/6088 9794/9794/6093 +f 10021/10021/6312 9794/9794/6093 10012/10012/6306 +f 10022/10022/6313 10021/10021/6312 10012/10012/6306 +f 10022/10022/6313 10012/10012/6306 10024/10024/6314 +f 9494/9494/5880 10025/10025/6315 10026/10026/6316 +f 9494/9494/5880 10026/10026/6316 9535/9535/5921 +f 10025/10025/6315 9484/9484/5870 9561/9561/5947 +f 10025/10025/6315 9561/9561/5947 10026/10026/6316 +f 10026/10026/6316 9561/9561/5947 9565/9565/5951 +f 10026/10026/6316 9565/9565/5951 9998/9998/6295 +f 9535/9535/5921 10026/10026/6316 9998/9998/6295 +f 9535/9535/5921 9998/9998/6295 9536/9536/5922 +f 9464/9464/5850 10027/10027/6317 10028/10028/6318 +f 9464/9464/5850 10028/10028/6318 9493/9493/5879 +f 10027/10027/6317 9460/9460/5846 9480/9480/5866 +f 10027/10027/6317 9480/9480/5866 10028/10028/6318 +f 10028/10028/6318 9480/9480/5866 9484/9484/5870 +f 10028/10028/6318 9484/9484/5870 10025/10025/6315 +f 9493/9493/5879 10028/10028/6318 10025/10025/6315 +f 9493/9493/5879 10025/10025/6315 9494/9494/5880 +f 9437/9437/5823 10029/10029/6319 10030/10030/6320 +f 9437/9437/5823 10030/10030/6320 9463/9463/5849 +f 10029/10029/6319 9406/9406/5792 9456/9456/5842 +f 10029/10029/6319 9456/9456/5842 10030/10030/6320 +f 10030/10030/6320 9456/9456/5842 9460/9460/5846 +f 10030/10030/6320 9460/9460/5846 10027/10027/6317 +f 9463/9463/5849 10030/10030/6320 10027/10027/6317 +f 9463/9463/5849 10027/10027/6317 9464/9464/5850 +f 9435/9435/5821 10005/10005/6300 10031/10031/6321 +f 9435/9435/5821 10031/10031/6321 9436/9436/5822 +f 10005/10005/6300 9398/9398/5784 9401/9401/5787 +f 10005/10005/6300 9401/9401/5787 10031/10031/6321 +f 10031/10031/6321 9401/9401/5787 9406/9406/5792 +f 10031/10031/6321 9406/9406/5792 10029/10029/6319 +f 9436/9436/5822 10031/10031/6321 10029/10029/6319 +f 9436/9436/5822 10029/10029/6319 9437/9437/5823 +f 10010/10010/5724 10009/10009/6304 10032/10032/6322 +f 10010/10010/5724 10032/10032/6322 10033/10033/5725 +f 10009/10009/6304 9363/9363/5756 9366/9366/5759 +f 10009/10009/6304 9366/9366/5759 10032/10032/6322 +f 10032/10032/6322 9366/9366/5759 9371/9371/5764 +f 10032/10032/6322 9371/9371/5764 10034/10034/6298 +f 10033/10033/5725 10032/10032/6322 10034/10034/6298 +f 10033/10033/5725 10034/10034/6298 10035/10035/6193 +f 9551/9551/5937 10000/10000/6297 10036/10036/6323 +f 9551/9551/5937 10036/10036/6323 9552/9552/5938 +f 10000/10000/6297 9309/9309/5702 9312/9312/5705 +f 10000/10000/6297 9312/9312/5705 10036/10036/6323 +f 10036/10036/6323 9312/9312/5705 9317/9317/5710 +f 10036/10036/6323 9317/9317/5710 10037/10037/6324 +f 9552/9552/5938 10036/10036/6323 10037/10037/6324 +f 9552/9552/5938 10037/10037/6324 9553/9553/5939 +f 9627/9627/6013 10038/10038/6325 10039/10039/6326 +f 9627/9627/6013 10039/10039/6326 10040/10040/6014 +f 10038/10038/6325 9302/9302/5695 9304/9304/5697 +f 10038/10038/6325 9304/9304/5697 10039/10039/6326 +f 10039/10039/6326 9304/9304/5697 9308/9308/5701 +f 10039/10039/6326 9308/9308/5701 10041/10041/6301 +f 10040/10040/6014 10039/10039/6326 10041/10041/6301 +f 10040/10040/6014 10041/10041/6301 9853/9853/6015 +f 9669/9669/6049 10042/10042/6327 10043/10043/6328 +f 9669/9669/6049 10043/10043/6328 9670/9670/6050 +f 10042/10042/6327 9293/9293/5688 10044/10044/5691 +f 10042/10042/6327 10044/10044/5691 10043/10043/6328 +f 10043/10043/6328 10044/10044/5691 10045/10045/5695 +f 10043/10043/6328 10045/10045/5695 10046/10046/6325 +f 9670/9670/6050 10043/10043/6328 10046/10046/6325 +f 9670/9670/6050 10046/10046/6325 9671/9671/6051 +f 9722/9722/6089 9719/9719/6086 10047/10047/6329 +f 9722/9722/6089 10047/10047/6329 10048/10048/6083 +f 9719/9719/6086 9285/9285/5680 9288/9288/5683 +f 9719/9719/6086 9288/9288/5683 10047/10047/6329 +f 10047/10047/6329 9288/9288/5683 9293/9293/5688 +f 10047/10047/6329 9293/9293/5688 10042/10042/6327 +f 10048/10048/6083 10047/10047/6329 10042/10042/6327 +f 10048/10048/6083 10042/10042/6327 9669/9669/6049 +f 10049/10049/6330 10050/10050/6331 10051/10051/6332 +f 10049/10049/6330 10051/10051/6332 10052/10052/6333 +f 10050/10050/6331 9532/9532/5918 9984/9984/6282 +f 10050/10050/6331 9984/9984/6282 10051/10051/6332 +f 10051/10051/6332 9984/9984/6282 9578/9578/5964 +f 10051/10051/6332 9578/9578/5964 10053/10053/6334 +f 10052/10052/6333 10051/10051/6332 10053/10053/6334 +f 10052/10052/6333 10053/10053/6334 10054/10054/6335 +f 10055/10055/6336 10056/10056/6337 10057/10057/6338 +f 10055/10055/6336 10057/10057/6338 10058/10058/6339 +f 10056/10056/6337 9869/9869/5746 9872/9872/6197 +f 10056/10056/6337 9872/9872/6197 10057/10057/6338 +f 10057/10057/6338 9872/9872/6197 9422/9422/5808 +f 10057/10057/6338 9422/9422/5808 10059/10059/6340 +f 10058/10058/6339 10057/10057/6338 10059/10059/6340 +f 10058/10058/6339 10059/10059/6340 10060/10060/6341 +f 10061/10061/6342 10062/10062/6343 10063/10063/6344 +f 10061/10061/6342 10063/10063/6344 10064/10064/6345 +f 10062/10062/6343 9839/9839/5981 9842/9842/6177 +f 10062/10062/6343 9842/9842/6177 10063/10063/6344 +f 10063/10063/6344 9842/9842/6177 9345/9345/5738 +f 10063/10063/6344 9345/9345/5738 10065/10065/6346 +f 10064/10064/6345 10063/10063/6344 10065/10065/6346 +f 10064/10064/6345 10065/10065/6346 10066/10066/6347 +f 9758/9758/6119 10067/10067/6348 10068/10068/6349 +f 9758/9758/6119 10068/10068/6349 9808/9808/6159 +f 10067/10067/6348 9284/9284/5679 10069/10069/6136 +f 10067/10067/6348 10069/10069/6136 10068/10068/6349 +f 10068/10068/6349 10069/10069/6136 10070/10070/6350 +f 10068/10068/6349 10070/10070/6350 10071/10071/6351 +f 9808/9808/6159 10068/10068/6349 10071/10071/6351 +f 9808/9808/6159 10071/10071/6351 9809/9809/6160 +f 9280/9280/5675 10072/10072/6352 10073/10073/6353 +f 9280/9280/5675 10073/10073/6353 10074/10074/6354 +f 10072/10072/6352 10075/10075/5671 10076/10076/6054 +f 10072/10072/6352 10076/10076/6054 10073/10073/6353 +f 10073/10073/6353 10076/10076/6054 10077/10077/6018 +f 10073/10073/6353 10077/10077/6018 10078/10078/6355 +f 10074/10074/6354 10073/10073/6353 10078/10078/6355 +f 10074/10074/6354 10078/10078/6355 10079/10079/6356 +f 10080/10080/6356 10081/10081/6355 10082/10082/6357 +f 10080/10080/6356 10082/10082/6357 10083/10083/6358 +f 10081/10081/6355 9632/9632/6018 10084/10084/6359 +f 10081/10081/6355 10084/10084/6359 10082/10082/6357 +f 10082/10082/6357 10084/10084/6359 9587/9587/5973 +f 10082/10082/6357 9587/9587/5973 10085/10085/6360 +f 10083/10083/6358 10082/10082/6357 10085/10085/6360 +f 10083/10083/6358 10085/10085/6360 10086/10086/6361 +f 10086/10086/6361 10085/10085/6360 10087/10087/6362 +f 10086/10086/6361 10087/10087/6362 10088/10088/6363 +f 10085/10085/6360 9587/9587/5973 10089/10089/5976 +f 10085/10085/6360 10089/10089/5976 10087/10087/6362 +f 10087/10087/6362 10089/10089/5976 9839/9839/5981 +f 10087/10087/6362 9839/9839/5981 10062/10062/6343 +f 10088/10088/6363 10087/10087/6362 10062/10062/6343 +f 10088/10088/6363 10062/10062/6343 10061/10061/6342 +f 10090/10090/6335 10091/10091/6364 10092/10092/6365 +f 10090/10090/6335 10092/10092/6365 10093/10093/6366 +f 10091/10091/6364 10094/10094/6367 10095/10095/5967 +f 10091/10091/6364 10095/10095/5967 10092/10092/6365 +f 10092/10092/6365 10095/10095/5967 9586/9586/6368 +f 10092/10092/6365 9586/9586/6368 10096/10096/6369 +f 10093/10093/6366 10092/10092/6365 10096/10096/6369 +f 10093/10093/6366 10096/10096/6369 10097/10097/6370 +f 10098/10098/6371 10099/10099/6372 10100/10100/6373 +f 10098/10098/6371 10100/10100/6373 10101/10101/6374 +f 10099/10099/6372 9490/9490/5876 9528/9528/5914 +f 10099/10099/6372 9528/9528/5914 10100/10100/6373 +f 10100/10100/6373 9528/9528/5914 9532/9532/5918 +f 10100/10100/6373 9532/9532/5918 10050/10050/6331 +f 10101/10101/6374 10100/10100/6373 10050/10050/6331 +f 10101/10101/6374 10050/10050/6331 10049/10049/6330 +f 10102/10102/6375 10103/10103/6376 10104/10104/6377 +f 10102/10102/6375 10104/10104/6377 10105/10105/6378 +f 10103/10103/6376 9472/9472/5858 9486/9486/5872 +f 10103/10103/6376 9486/9486/5872 10104/10104/6377 +f 10104/10104/6377 9486/9486/5872 9490/9490/5876 +f 10104/10104/6377 9490/9490/5876 10099/10099/6372 +f 10105/10105/6378 10104/10104/6377 10099/10099/6372 +f 10105/10105/6378 10099/10099/6372 10098/10098/6371 +f 10106/10106/6379 10107/10107/6380 10108/10108/6381 +f 10106/10106/6379 10108/10108/6381 10109/10109/6382 +f 10107/10107/6380 9430/9430/5816 9468/9468/5854 +f 10107/10107/6380 9468/9468/5854 10108/10108/6381 +f 10108/10108/6381 9468/9468/5854 9472/9472/5858 +f 10108/10108/6381 9472/9472/5858 10103/10103/6376 +f 10109/10109/6382 10108/10108/6381 10103/10103/6376 +f 10109/10109/6382 10103/10103/6376 10102/10102/6375 +f 10060/10060/6341 10059/10059/6340 10110/10110/6383 +f 10060/10060/6341 10110/10110/6383 10111/10111/6384 +f 10059/10059/6340 9422/9422/5808 9425/9425/5811 +f 10059/10059/6340 9425/9425/5811 10110/10110/6383 +f 10110/10110/6383 9425/9425/5811 9430/9430/5816 +f 10110/10110/6383 9430/9430/5816 10107/10107/6380 +f 10111/10111/6384 10110/10110/6383 10107/10107/6380 +f 10111/10111/6384 10107/10107/6380 10106/10106/6379 +f 10066/10066/6347 10065/10065/6346 10112/10112/6385 +f 10066/10066/6347 10112/10112/6385 10113/10113/6386 +f 10065/10065/6346 9345/9345/5738 9348/9348/5741 +f 10065/10065/6346 9348/9348/5741 10112/10112/6385 +f 10112/10112/6385 9348/9348/5741 9353/9353/5746 +f 10112/10112/6385 9353/9353/5746 10114/10114/6337 +f 10113/10113/6386 10112/10112/6385 10114/10114/6337 +f 10113/10113/6386 10114/10114/6337 10115/10115/6336 +f 9756/9756/6117 10116/10116/6052 10117/10117/6387 +f 9756/9756/6117 10117/10117/6387 9757/9757/6118 +f 10116/10116/6052 9276/9276/5671 9279/9279/5674 +f 10116/10116/6052 9279/9279/5674 10117/10117/6387 +f 10117/10117/6387 9279/9279/5674 9284/9284/5679 +f 10117/10117/6387 9284/9284/5679 10067/10067/6348 +f 9757/9757/6118 10117/10117/6387 10067/10067/6348 +f 9757/9757/6118 10067/10067/6348 9758/9758/6119 +f 10118/10118/6388 10119/10119/6389 10120/10120/6390 +f 10118/10118/6388 10120/10120/6390 10121/10121/6391 +f 10119/10119/6389 10122/10122/6392 10123/10123/6393 +f 10119/10119/6389 10123/10123/6393 10120/10120/6390 +f 10120/10120/6390 10123/10123/6393 10124/10124/6394 +f 10120/10120/6390 10124/10124/6394 10125/10125/6395 +f 10121/10121/6391 10120/10120/6390 10125/10125/6395 +f 10121/10121/6391 10125/10125/6395 10126/10126/6396 +f 10127/10127/6397 10128/10128/6398 10129/10129/6399 +f 10127/10127/6397 10129/10129/6399 10130/10130/6400 +f 10128/10128/6398 10131/10131/6401 10132/10132/6402 +f 10128/10128/6398 10132/10132/6402 10129/10129/6399 +f 10129/10129/6399 10132/10132/6402 10133/10133/6403 +f 10129/10129/6399 10133/10133/6403 10134/10134/6404 +f 10130/10130/6400 10129/10129/6399 10134/10134/6404 +f 10130/10130/6400 10134/10134/6404 10135/10135/6405 +f 10136/10136/6406 10137/10137/6407 10138/10138/6408 +f 10136/10136/6406 10138/10138/6408 10139/10139/6402 +f 10137/10137/6407 10140/10140/6409 10141/10141/6410 +f 10137/10137/6407 10141/10141/6410 10138/10138/6408 +f 10138/10138/6408 10141/10141/6410 10142/10142/6411 +f 10138/10138/6408 10142/10142/6411 10143/10143/6412 +f 10139/10139/6402 10138/10138/6408 10143/10143/6412 +f 10139/10139/6402 10143/10143/6412 10144/10144/6413 +f 10140/10140/6409 10145/10145/6414 10146/10146/6415 +f 10140/10140/6409 10146/10146/6415 10141/10141/6410 +f 10145/10145/6414 10147/10147/6416 10148/10148/6417 +f 10145/10145/6414 10148/10148/6417 10146/10146/6415 +f 10146/10146/6415 10148/10148/6417 10149/10149/6418 +f 10146/10146/6415 10149/10149/6418 10150/10150/6419 +f 10141/10141/6410 10146/10146/6415 10150/10150/6419 +f 10141/10141/6410 10150/10150/6419 10142/10142/6411 +f 10151/10151/6420 10152/10152/6421 10153/10153/6422 +f 10151/10151/6420 10153/10153/6422 10154/10154/6423 +f 10152/10152/6421 10155/10155/6424 10156/10156/6425 +f 10152/10152/6421 10156/10156/6425 10153/10153/6422 +f 10153/10153/6422 10156/10156/6425 10157/10157/6426 +f 10153/10153/6422 10157/10157/6426 10158/10158/6427 +f 10154/10154/6423 10153/10153/6422 10158/10158/6427 +f 10154/10154/6423 10158/10158/6427 10159/10159/6428 +f 10160/10160/6429 10161/10161/6430 10162/10162/6431 +f 10160/10160/6429 10162/10162/6431 10163/10163/6432 +f 10161/10161/6430 10164/10164/6433 10165/10165/6434 +f 10161/10161/6430 10165/10165/6434 10162/10162/6431 +f 10162/10162/6431 10165/10165/6434 10166/10166/6435 +f 10162/10162/6431 10166/10166/6435 10167/10167/6436 +f 10163/10163/6432 10162/10162/6431 10167/10167/6436 +f 10163/10163/6432 10167/10167/6436 10168/10168/6437 +f 10169/10169/6438 10170/10170/6439 10171/10171/6440 +f 10169/10169/6438 10171/10171/6440 10172/10172/6441 +f 10170/10170/6439 10173/10173/6442 10174/10174/6443 +f 10170/10170/6439 10174/10174/6443 10171/10171/6440 +f 10171/10171/6440 10174/10174/6443 10175/10175/6444 +f 10171/10171/6440 10175/10175/6444 10176/10176/6445 +f 10172/10172/6441 10171/10171/6440 10176/10176/6445 +f 10172/10172/6441 10176/10176/6445 10177/10177/6446 +f 10178/10178/6447 10179/10179/6448 10180/10180/6449 +f 10178/10178/6447 10180/10180/6449 10181/10181/6450 +f 10179/10179/6448 10182/10182/6451 10183/10183/6452 +f 10179/10179/6448 10183/10183/6452 10180/10180/6449 +f 10180/10180/6449 10183/10183/6452 10184/10184/6453 +f 10180/10180/6449 10184/10184/6453 10185/10185/6454 +f 10181/10181/6450 10180/10180/6449 10185/10185/6454 +f 10181/10181/6450 10185/10185/6454 10186/10186/6455 +f 10187/10187/6456 10188/10188/6457 10189/10189/6458 +f 10187/10187/6456 10189/10189/6458 10190/10190/6459 +f 10188/10188/6457 10191/10191/6460 10192/10192/6461 +f 10188/10188/6457 10192/10192/6461 10189/10189/6458 +f 10189/10189/6458 10192/10192/6461 10193/10193/6462 +f 10189/10189/6458 10193/10193/6462 10194/10194/6463 +f 10190/10190/6459 10189/10189/6458 10194/10194/6463 +f 10190/10190/6459 10194/10194/6463 10195/10195/6464 +f 10196/10196/6465 10197/10197/6466 10198/10198/6467 +f 10196/10196/6465 10198/10198/6467 10199/10199/6468 +f 10197/10197/6466 10200/10200/6469 10201/10201/6470 +f 10197/10197/6466 10201/10201/6470 10198/10198/6467 +f 10198/10198/6467 10201/10201/6470 10202/10202/6471 +f 10198/10198/6467 10202/10202/6471 10203/10203/6472 +f 10199/10199/6468 10198/10198/6467 10203/10203/6472 +f 10199/10199/6468 10203/10203/6472 10204/10204/6473 +f 10205/10205/6474 10206/10206/6475 10207/10207/6476 +f 10205/10205/6474 10207/10207/6476 10208/10208/6477 +f 10206/10206/6475 10209/10209/6478 10210/10210/6479 +f 10206/10206/6475 10210/10210/6479 10207/10207/6476 +f 10207/10207/6476 10210/10210/6479 10211/10211/6480 +f 10207/10207/6476 10211/10211/6480 10212/10212/6481 +f 10208/10208/6477 10207/10207/6476 10212/10212/6481 +f 10208/10208/6477 10212/10212/6481 10213/10213/6482 +f 10214/10214/6483 10215/10215/6484 10216/10216/6485 +f 10214/10214/6483 10216/10216/6485 10217/10217/6486 +f 10215/10215/6484 10218/10218/6487 10219/10219/6488 +f 10215/10215/6484 10219/10219/6488 10216/10216/6485 +f 10216/10216/6485 10219/10219/6488 10182/10182/6489 +f 10216/10216/6485 10182/10182/6489 10220/10220/6448 +f 10217/10217/6486 10216/10216/6485 10220/10220/6448 +f 10217/10217/6486 10220/10220/6448 10221/10221/6447 +f 10186/10186/6455 10185/10185/6454 10222/10222/6490 +f 10186/10186/6455 10222/10222/6490 10223/10223/6491 +f 10185/10185/6454 10184/10184/6453 10224/10224/6492 +f 10185/10185/6454 10224/10224/6492 10222/10222/6490 +f 10222/10222/6490 10224/10224/6492 10200/10200/6469 +f 10222/10222/6490 10200/10200/6469 10197/10197/6466 +f 10223/10223/6491 10222/10222/6490 10197/10197/6466 +f 10223/10223/6491 10197/10197/6466 10196/10196/6465 +f 10225/10225/6493 10226/10226/6494 10227/10227/6495 +f 10225/10225/6493 10227/10227/6495 10228/10228/6496 +f 10226/10226/6494 10229/10229/6497 10230/10230/6498 +f 10226/10226/6494 10230/10230/6498 10227/10227/6495 +f 10227/10227/6495 10230/10230/6498 10231/10231/6499 +f 10227/10227/6495 10231/10231/6499 10232/10232/6500 +f 10228/10228/6496 10227/10227/6495 10232/10232/6500 +f 10228/10228/6496 10232/10232/6500 10233/10233/6501 +f 10234/10234/6502 10235/10235/6503 10236/10236/6504 +f 10234/10234/6502 10236/10236/6504 10237/10237/6505 +f 10235/10235/6503 10238/10238/6506 10239/10239/6507 +f 10235/10235/6503 10239/10239/6507 10236/10236/6504 +f 10236/10236/6504 10239/10239/6507 10240/10240/6508 +f 10236/10236/6504 10240/10240/6508 10241/10241/6509 +f 10237/10237/6505 10236/10236/6504 10241/10241/6509 +f 10237/10237/6505 10241/10241/6509 10242/10242/6510 +f 10243/10243/6511 10244/10244/6512 10245/10245/6513 +f 10243/10243/6511 10245/10245/6513 10246/10246/6514 +f 10244/10244/6512 10247/10247/6515 10248/10248/6516 +f 10244/10244/6512 10248/10248/6516 10245/10245/6513 +f 10245/10245/6513 10248/10248/6516 10249/10249/6517 +f 10245/10245/6513 10249/10249/6517 10250/10250/6518 +f 10246/10246/6514 10245/10245/6513 10250/10250/6518 +f 10246/10246/6514 10250/10250/6518 10251/10251/6519 +f 10252/10252/6520 10253/10253/6521 10254/10254/6522 +f 10252/10252/6520 10254/10254/6522 10255/10255/6523 +f 10253/10253/6521 10256/10256/6524 10257/10257/6525 +f 10253/10253/6521 10257/10257/6525 10254/10254/6522 +f 10254/10254/6522 10257/10257/6525 10229/10229/6497 +f 10254/10254/6522 10229/10229/6497 10226/10226/6494 +f 10255/10255/6523 10254/10254/6522 10226/10226/6494 +f 10255/10255/6523 10226/10226/6494 10225/10225/6493 +f 10258/10258/6526 10259/10259/6527 10260/10260/6528 +f 10258/10258/6526 10260/10260/6528 10261/10261/6529 +f 10259/10259/6527 10262/10262/6530 10263/10263/6531 +f 10259/10259/6527 10263/10263/6531 10260/10260/6528 +f 10260/10260/6528 10263/10263/6531 10264/10264/6532 +f 10260/10260/6528 10264/10264/6532 10265/10265/6533 +f 10261/10261/6529 10260/10260/6528 10265/10265/6533 +f 10261/10261/6529 10265/10265/6533 10266/10266/6534 +f 10267/10267/6535 10268/10268/6536 10269/10269/6537 +f 10267/10267/6535 10269/10269/6537 10270/10270/6538 +f 10268/10268/6536 10271/10271/6539 10272/10272/6540 +f 10268/10268/6536 10272/10272/6540 10269/10269/6537 +f 10269/10269/6537 10272/10272/6540 10273/10273/6541 +f 10269/10269/6537 10273/10273/6541 10274/10274/6542 +f 10270/10270/6538 10269/10269/6537 10274/10274/6542 +f 10270/10270/6538 10274/10274/6542 10275/10275/6543 +f 10233/10233/6501 10232/10232/6500 10276/10276/6544 +f 10233/10233/6501 10276/10276/6544 10277/10277/6545 +f 10232/10232/6500 10231/10231/6499 10278/10278/6546 +f 10232/10232/6500 10278/10278/6546 10276/10276/6544 +f 10276/10276/6544 10278/10278/6546 10247/10247/6515 +f 10276/10276/6544 10247/10247/6515 10244/10244/6512 +f 10277/10277/6545 10276/10276/6544 10244/10244/6512 +f 10277/10277/6545 10244/10244/6512 10243/10243/6511 +f 10231/10231/6499 10279/10279/6547 10280/10280/6548 +f 10231/10231/6499 10280/10280/6548 10278/10278/6546 +f 10279/10279/6547 10281/10281/6549 10282/10282/6550 +f 10279/10279/6547 10282/10282/6550 10280/10280/6548 +f 10280/10280/6548 10282/10282/6550 10283/10283/6551 +f 10280/10280/6548 10283/10283/6551 10284/10284/6552 +f 10278/10278/6546 10280/10280/6548 10284/10284/6552 +f 10278/10278/6546 10284/10284/6552 10247/10247/6515 +f 10256/10256/6524 10285/10285/6553 10286/10286/6554 +f 10256/10256/6524 10286/10286/6554 10257/10257/6525 +f 10285/10285/6553 10287/10287/6555 10288/10288/6556 +f 10285/10285/6553 10288/10288/6556 10286/10286/6554 +f 10286/10286/6554 10288/10288/6556 10289/10289/6557 +f 10286/10286/6554 10289/10289/6557 10290/10290/6558 +f 10257/10257/6525 10286/10286/6554 10290/10290/6558 +f 10257/10257/6525 10290/10290/6558 10229/10229/6497 +f 10238/10238/6506 10291/10291/6559 10292/10292/6560 +f 10238/10238/6506 10292/10292/6560 10239/10239/6507 +f 10291/10291/6559 10293/10293/6561 10294/10294/6562 +f 10291/10291/6559 10294/10294/6562 10292/10292/6560 +f 10292/10292/6560 10294/10294/6562 10295/10295/6563 +f 10292/10292/6560 10295/10295/6563 10296/10296/6564 +f 10239/10239/6507 10292/10292/6560 10296/10296/6564 +f 10239/10239/6507 10296/10296/6564 10240/10240/6508 +f 10271/10271/6539 10297/10297/6565 10298/10298/6566 +f 10271/10271/6539 10298/10298/6566 10272/10272/6540 +f 10297/10297/6565 10299/10299/6567 10300/10300/6568 +f 10297/10297/6565 10300/10300/6568 10298/10298/6566 +f 10298/10298/6566 10300/10300/6568 10301/10301/6569 +f 10298/10298/6566 10301/10301/6569 10302/10302/6570 +f 10272/10272/6540 10298/10298/6566 10302/10302/6570 +f 10272/10272/6540 10302/10302/6570 10273/10273/6541 +f 10262/10262/6530 10303/10303/6571 10304/10304/6572 +f 10262/10262/6530 10304/10304/6572 10263/10263/6531 +f 10303/10303/6571 10305/10305/6573 10306/10306/6574 +f 10303/10303/6571 10306/10306/6574 10304/10304/6572 +f 10304/10304/6572 10306/10306/6574 10307/10307/6575 +f 10304/10304/6572 10307/10307/6575 10308/10308/6576 +f 10263/10263/6531 10304/10304/6572 10308/10308/6576 +f 10263/10263/6531 10308/10308/6576 10264/10264/6532 +f 10229/10229/6497 10290/10290/6558 10309/10309/6577 +f 10229/10229/6497 10309/10309/6577 10230/10230/6498 +f 10290/10290/6558 10289/10289/6557 10310/10310/6578 +f 10290/10290/6558 10310/10310/6578 10309/10309/6577 +f 10309/10309/6577 10310/10310/6578 10281/10281/6549 +f 10309/10309/6577 10281/10281/6549 10279/10279/6547 +f 10230/10230/6498 10309/10309/6577 10279/10279/6547 +f 10230/10230/6498 10279/10279/6547 10231/10231/6499 +f 10247/10247/6515 10284/10284/6552 10311/10311/6579 +f 10247/10247/6515 10311/10311/6579 10248/10248/6516 +f 10284/10284/6552 10283/10283/6551 10312/10312/6580 +f 10284/10284/6552 10312/10312/6580 10311/10311/6579 +f 10311/10311/6579 10312/10312/6580 10313/10313/6581 +f 10311/10311/6579 10313/10313/6581 10314/10314/6582 +f 10248/10248/6516 10311/10311/6579 10314/10314/6582 +f 10248/10248/6516 10314/10314/6582 10249/10249/6517 +f 10293/10293/6561 10315/10315/6583 10316/10316/6584 +f 10293/10293/6561 10316/10316/6584 10294/10294/6562 +f 10315/10315/6583 10317/10317/6585 10318/10318/6586 +f 10315/10315/6583 10318/10318/6586 10316/10316/6584 +f 10316/10316/6584 10318/10318/6586 10319/10319/6587 +f 10316/10316/6584 10319/10319/6587 10320/10320/6588 +f 10294/10294/6562 10316/10316/6584 10320/10320/6588 +f 10294/10294/6562 10320/10320/6588 10295/10295/6563 +f 10305/10305/6573 10321/10321/6589 10322/10322/6590 +f 10305/10305/6573 10322/10322/6590 10306/10306/6574 +f 10321/10321/6589 10323/10323/6591 10324/10324/6592 +f 10321/10321/6589 10324/10324/6592 10322/10322/6590 +f 10322/10322/6590 10324/10324/6592 10325/10325/6593 +f 10322/10322/6590 10325/10325/6593 10326/10326/6594 +f 10306/10306/6574 10322/10322/6590 10326/10326/6594 +f 10306/10306/6574 10326/10326/6594 10307/10307/6575 +f 10299/10299/6567 10327/10327/6595 10328/10328/6596 +f 10299/10299/6567 10328/10328/6596 10300/10300/6568 +f 10327/10327/6595 10329/10329/6597 10330/10330/6598 +f 10327/10327/6595 10330/10330/6598 10328/10328/6596 +f 10328/10328/6596 10330/10330/6598 10331/10331/6599 +f 10328/10328/6596 10331/10331/6599 10332/10332/6600 +f 10300/10300/6568 10328/10328/6596 10332/10332/6600 +f 10300/10300/6568 10332/10332/6600 10301/10301/6569 +f 10289/10289/6557 10333/10333/6601 10334/10334/6602 +f 10289/10289/6557 10334/10334/6602 10310/10310/6578 +f 10333/10333/6601 10335/10335/6603 10336/10336/6604 +f 10333/10333/6601 10336/10336/6604 10334/10334/6602 +f 10334/10334/6602 10336/10336/6604 10337/10337/6605 +f 10334/10334/6602 10337/10337/6605 10338/10338/6606 +f 10310/10310/6578 10334/10334/6602 10338/10338/6606 +f 10310/10310/6578 10338/10338/6606 10281/10281/6549 +f 10283/10283/6551 10339/10339/6607 10340/10340/6608 +f 10283/10283/6551 10340/10340/6608 10312/10312/6580 +f 10339/10339/6607 10341/10341/6609 10342/10342/6610 +f 10339/10339/6607 10342/10342/6610 10340/10340/6608 +f 10340/10340/6608 10342/10342/6610 10343/10343/6611 +f 10340/10340/6608 10343/10343/6611 10344/10344/6612 +f 10312/10312/6580 10340/10340/6608 10344/10344/6612 +f 10312/10312/6580 10344/10344/6612 10313/10313/6581 +f 10287/10287/6555 10345/10345/6613 10346/10346/6614 +f 10287/10287/6555 10346/10346/6614 10288/10288/6556 +f 10345/10345/6613 10347/10347/6615 10348/10348/6616 +f 10345/10345/6613 10348/10348/6616 10346/10346/6614 +f 10346/10346/6614 10348/10348/6616 10335/10335/6603 +f 10346/10346/6614 10335/10335/6603 10333/10333/6601 +f 10288/10288/6556 10346/10346/6614 10333/10333/6601 +f 10288/10288/6556 10333/10333/6601 10289/10289/6557 +f 10281/10281/6549 10338/10338/6606 10349/10349/6617 +f 10281/10281/6549 10349/10349/6617 10282/10282/6550 +f 10338/10338/6606 10337/10337/6605 10350/10350/6618 +f 10338/10338/6606 10350/10350/6618 10349/10349/6617 +f 10349/10349/6617 10350/10350/6618 10341/10341/6609 +f 10349/10349/6617 10341/10341/6609 10339/10339/6607 +f 10282/10282/6550 10349/10349/6617 10339/10339/6607 +f 10282/10282/6550 10339/10339/6607 10283/10283/6551 +f 10337/10337/6605 10351/10351/6619 10352/10352/6620 +f 10337/10337/6605 10352/10352/6620 10350/10350/6618 +f 10351/10351/6619 10353/10353/6621 10354/10354/6622 +f 10351/10351/6619 10354/10354/6622 10352/10352/6620 +f 10352/10352/6620 10354/10354/6622 10355/10355/6623 +f 10352/10352/6620 10355/10355/6623 10356/10356/6624 +f 10350/10350/6618 10352/10352/6620 10356/10356/6624 +f 10350/10350/6618 10356/10356/6624 10341/10341/6609 +f 10347/10347/6615 10357/10357/6625 10358/10358/6626 +f 10347/10347/6615 10358/10358/6626 10348/10348/6616 +f 10357/10357/6625 10359/10359/6627 10360/10360/6628 +f 10357/10357/6625 10360/10360/6628 10358/10358/6626 +f 10358/10358/6626 10360/10360/6628 10361/10361/6629 +f 10358/10358/6626 10361/10361/6629 10362/10362/6630 +f 10348/10348/6616 10358/10358/6626 10362/10362/6630 +f 10348/10348/6616 10362/10362/6630 10335/10335/6603 +f 10323/10323/6591 10363/10363/6631 10364/10364/6632 +f 10323/10323/6591 10364/10364/6632 10324/10324/6592 +f 10363/10363/6631 10365/10365/6633 10366/10366/6634 +f 10363/10363/6631 10366/10366/6634 10364/10364/6632 +f 10364/10364/6632 10366/10366/6634 10367/10367/6635 +f 10364/10364/6632 10367/10367/6635 10368/10368/6636 +f 10324/10324/6592 10364/10364/6632 10368/10368/6636 +f 10324/10324/6592 10368/10368/6636 10325/10325/6593 +f 10329/10329/6597 10369/10369/6637 10370/10370/6638 +f 10329/10329/6597 10370/10370/6638 10330/10330/6598 +f 10369/10369/6637 10371/10371/6639 10372/10372/6640 +f 10369/10369/6637 10372/10372/6640 10370/10370/6638 +f 10370/10370/6638 10372/10372/6640 10373/10373/6641 +f 10370/10370/6638 10373/10373/6641 10374/10374/6642 +f 10330/10330/6598 10370/10370/6638 10374/10374/6642 +f 10330/10330/6598 10374/10374/6642 10331/10331/6599 +f 10335/10335/6603 10362/10362/6630 10375/10375/6643 +f 10335/10335/6603 10375/10375/6643 10336/10336/6604 +f 10362/10362/6630 10361/10361/6629 10376/10376/6644 +f 10362/10362/6630 10376/10376/6644 10375/10375/6643 +f 10375/10375/6643 10376/10376/6644 10353/10353/6621 +f 10375/10375/6643 10353/10353/6621 10351/10351/6619 +f 10336/10336/6604 10375/10375/6643 10351/10351/6619 +f 10336/10336/6604 10351/10351/6619 10337/10337/6605 +f 10168/10168/6437 10167/10167/6436 10377/10377/6645 +f 10168/10168/6437 10377/10377/6645 10378/10378/6646 +f 10167/10167/6436 10166/10166/6435 10379/10379/6647 +f 10167/10167/6436 10379/10379/6647 10377/10377/6645 +f 10377/10377/6645 10379/10379/6647 10380/10380/6648 +f 10377/10377/6645 10380/10380/6648 10381/10381/6649 +f 10378/10378/6646 10377/10377/6645 10381/10381/6649 +f 10378/10378/6646 10381/10381/6649 10382/10382/6650 +f 10383/10383/6651 10384/10384/6652 10385/10385/6653 +f 10383/10383/6651 10385/10385/6653 10386/10386/6654 +f 10384/10384/6652 10387/10387/6655 10388/10388/6656 +f 10384/10384/6652 10388/10388/6656 10385/10385/6653 +f 10385/10385/6653 10388/10388/6656 10389/10389/6657 +f 10385/10385/6653 10389/10389/6657 10390/10390/6658 +f 10386/10386/6654 10385/10385/6653 10390/10390/6658 +f 10386/10386/6654 10390/10390/6658 10391/10391/6659 +f 10341/10341/6609 10356/10356/6624 10392/10392/6660 +f 10341/10341/6609 10392/10392/6660 10342/10342/6610 +f 10356/10356/6624 10355/10355/6623 10393/10393/6661 +f 10356/10356/6624 10393/10393/6661 10392/10392/6660 +f 10392/10392/6660 10393/10393/6661 10394/10394/6662 +f 10392/10392/6660 10394/10394/6662 10395/10395/6663 +f 10342/10342/6610 10392/10392/6660 10395/10395/6663 +f 10342/10342/6610 10395/10395/6663 10343/10343/6611 +f 10317/10317/6585 10396/10396/6664 10397/10397/6665 +f 10317/10317/6585 10397/10397/6665 10318/10318/6586 +f 10396/10396/6664 10398/10398/6666 10399/10399/6667 +f 10396/10396/6664 10399/10399/6667 10397/10397/6665 +f 10397/10397/6665 10399/10399/6667 10400/10400/6668 +f 10397/10397/6665 10400/10400/6668 10401/10401/6669 +f 10318/10318/6586 10397/10397/6665 10401/10401/6669 +f 10318/10318/6586 10401/10401/6669 10319/10319/6587 +f 10382/10382/6650 10381/10381/6649 10402/10402/6670 +f 10382/10382/6650 10402/10402/6670 10403/10403/6671 +f 10381/10381/6649 10380/10380/6648 10404/10404/6672 +f 10381/10381/6649 10404/10404/6672 10402/10402/6670 +f 10402/10402/6670 10404/10404/6672 10405/10405/6673 +f 10402/10402/6670 10405/10405/6673 10406/10406/6674 +f 10403/10403/6671 10402/10402/6670 10406/10406/6674 +f 10403/10403/6671 10406/10406/6674 10407/10407/6675 +f 10407/10407/6675 10406/10406/6674 10408/10408/6676 +f 10407/10407/6675 10408/10408/6676 10409/10409/6677 +f 10406/10406/6674 10405/10405/6673 10410/10410/6678 +f 10406/10406/6674 10410/10410/6678 10408/10408/6676 +f 10408/10408/6676 10410/10410/6678 10411/10411/6679 +f 10408/10408/6676 10411/10411/6679 10412/10412/6680 +f 10409/10409/6677 10408/10408/6676 10412/10412/6680 +f 10409/10409/6677 10412/10412/6680 10413/10413/6681 +f 10414/10414/6682 10415/10415/6683 10416/10416/6684 +f 10414/10414/6682 10416/10416/6684 10417/10417/6685 +f 10415/10415/6683 10418/10418/6686 10419/10419/6687 +f 10415/10415/6683 10419/10419/6687 10416/10416/6684 +f 10416/10416/6684 10419/10419/6687 10420/10420/6688 +f 10416/10416/6684 10420/10420/6688 10421/10421/6689 +f 10417/10417/6685 10416/10416/6684 10421/10421/6689 +f 10417/10417/6685 10421/10421/6689 10422/10422/6690 +f 10423/10423/6691 10424/10424/6692 10425/10425/6693 +f 10423/10423/6691 10425/10425/6693 10426/10426/6694 +f 10424/10424/6692 10427/10427/6695 10428/10428/6696 +f 10424/10424/6692 10428/10428/6696 10425/10425/6693 +f 10425/10425/6693 10428/10428/6696 10429/10429/6697 +f 10425/10425/6693 10429/10429/6697 10430/10430/6698 +f 10426/10426/6694 10425/10425/6693 10430/10430/6698 +f 10426/10426/6694 10430/10430/6698 10431/10431/6699 +f 10432/10432/6700 10433/10433/6701 10434/10434/6702 +f 10432/10432/6700 10434/10434/6702 10435/10435/6703 +f 10433/10433/6701 10436/10436/6704 10437/10437/6705 +f 10433/10433/6701 10437/10437/6705 10434/10434/6702 +f 10434/10434/6702 10437/10437/6705 10438/10438/6706 +f 10434/10434/6702 10438/10438/6706 10439/10439/6707 +f 10435/10435/6703 10434/10434/6702 10439/10439/6707 +f 10435/10435/6703 10439/10439/6707 10440/10440/6708 +f 10440/10440/6708 10439/10439/6707 10441/10441/6709 +f 10440/10440/6708 10441/10441/6709 10442/10442/6710 +f 10439/10439/6707 10438/10438/6706 10443/10443/6711 +f 10439/10439/6707 10443/10443/6711 10441/10441/6709 +f 10441/10441/6709 10443/10443/6711 10444/10444/6712 +f 10441/10441/6709 10444/10444/6712 10445/10445/6713 +f 10442/10442/6710 10441/10441/6709 10445/10445/6713 +f 10442/10442/6710 10445/10445/6713 10446/10446/6714 +f 10446/10446/6714 10445/10445/6713 10447/10447/6715 +f 10446/10446/6714 10447/10447/6715 10448/10448/6716 +f 10445/10445/6713 10444/10444/6712 10449/10449/6717 +f 10445/10445/6713 10449/10449/6717 10447/10447/6715 +f 10447/10447/6715 10449/10449/6717 10450/10450/6718 +f 10447/10447/6715 10450/10450/6718 10451/10451/6719 +f 10448/10448/6716 10447/10447/6715 10451/10451/6719 +f 10448/10448/6716 10451/10451/6719 10452/10452/6720 +f 10452/10452/6720 10451/10451/6719 10453/10453/6721 +f 10452/10452/6720 10453/10453/6721 10454/10454/6722 +f 10451/10451/6719 10450/10450/6718 10455/10455/6723 +f 10451/10451/6719 10455/10455/6723 10453/10453/6721 +f 10453/10453/6721 10455/10455/6723 10456/10456/6724 +f 10453/10453/6721 10456/10456/6724 10457/10457/6725 +f 10454/10454/6722 10453/10453/6721 10457/10457/6725 +f 10454/10454/6722 10457/10457/6725 10458/10458/6726 +f 10459/10459/6727 10460/10460/6728 10461/10461/6729 +f 10459/10459/6727 10461/10461/6729 10462/10462/6730 +f 10460/10460/6728 10463/10463/6731 10464/10464/6732 +f 10460/10460/6728 10464/10464/6732 10461/10461/6729 +f 10461/10461/6729 10464/10464/6732 10465/10465/6733 +f 10461/10461/6729 10465/10465/6733 10466/10466/6734 +f 10462/10462/6730 10461/10461/6729 10466/10466/6734 +f 10462/10462/6730 10466/10466/6734 10467/10467/6735 +f 10468/10468/6736 10469/10469/6737 10470/10470/6738 +f 10468/10468/6736 10470/10470/6738 10471/10471/6739 +f 10469/10469/6737 10423/10423/6691 10426/10426/6694 +f 10469/10469/6737 10426/10426/6694 10470/10470/6738 +f 10470/10470/6738 10426/10426/6694 10431/10431/6699 +f 10470/10470/6738 10431/10431/6699 10472/10472/6740 +f 10471/10471/6739 10470/10470/6738 10472/10472/6740 +f 10471/10471/6739 10472/10472/6740 10473/10473/6741 +f 10474/10474/6742 10475/10475/6743 10476/10476/6744 +f 10474/10474/6742 10476/10476/6744 10477/10477/6745 +f 10475/10475/6743 10478/10478/6700 10479/10479/6703 +f 10475/10475/6743 10479/10479/6703 10476/10476/6744 +f 10476/10476/6744 10479/10479/6703 10480/10480/6708 +f 10476/10476/6744 10480/10480/6708 10481/10481/6746 +f 10477/10477/6745 10476/10476/6744 10481/10481/6746 +f 10477/10477/6745 10481/10481/6746 10482/10482/6747 +f 10482/10482/6747 10481/10481/6746 10483/10483/6748 +f 10482/10482/6747 10483/10483/6748 10484/10484/6749 +f 10481/10481/6746 10480/10480/6708 10485/10485/6710 +f 10481/10481/6746 10485/10485/6710 10483/10483/6748 +f 10483/10483/6748 10485/10485/6710 10486/10486/6750 +f 10483/10483/6748 10486/10486/6750 10487/10487/6751 +f 10484/10484/6749 10483/10483/6748 10487/10487/6751 +f 10484/10484/6749 10487/10487/6751 10488/10488/6752 +f 10489/10489/6752 10490/10490/6751 10491/10491/6753 +f 10489/10489/6752 10491/10491/6753 10492/10492/6754 +f 10490/10490/6751 10493/10493/6714 10494/10494/6716 +f 10490/10490/6751 10494/10494/6716 10491/10491/6753 +f 10491/10491/6753 10494/10494/6716 10495/10495/6720 +f 10491/10491/6753 10495/10495/6720 10496/10496/6755 +f 10492/10492/6754 10491/10491/6753 10496/10496/6755 +f 10492/10492/6754 10496/10496/6755 10497/10497/6756 +f 10497/10497/6756 10496/10496/6755 10498/10498/6757 +f 10497/10497/6756 10498/10498/6757 10499/10499/6758 +f 10496/10496/6755 10495/10495/6720 10500/10500/6722 +f 10496/10496/6755 10500/10500/6722 10498/10498/6757 +f 10498/10498/6757 10500/10500/6722 10501/10501/6759 +f 10498/10498/6757 10501/10501/6759 10502/10502/6760 +f 10499/10499/6758 10498/10498/6757 10502/10502/6760 +f 10499/10499/6758 10502/10502/6760 10503/10503/6761 +f 10504/10504/6762 10505/10505/6763 10506/10506/6764 +f 10504/10504/6762 10506/10506/6764 10507/10507/6765 +f 10505/10505/6763 10508/10508/6727 10509/10509/6730 +f 10505/10505/6763 10509/10509/6730 10506/10506/6764 +f 10506/10506/6764 10509/10509/6730 10510/10510/6766 +f 10506/10506/6764 10510/10510/6766 10511/10511/6767 +f 10507/10507/6765 10506/10506/6764 10511/10511/6767 +f 10507/10507/6765 10511/10511/6767 10512/10512/6768 +f 10513/10513/6769 10514/10514/6770 10515/10515/6771 +f 10513/10513/6769 10515/10515/6771 10516/10516/6772 +f 10514/10514/6770 10468/10468/6736 10471/10471/6739 +f 10514/10514/6770 10471/10471/6739 10515/10515/6771 +f 10515/10515/6771 10471/10471/6739 10473/10473/6741 +f 10515/10515/6771 10473/10473/6741 10517/10517/6773 +f 10516/10516/6772 10515/10515/6771 10517/10517/6773 +f 10516/10516/6772 10517/10517/6773 10518/10518/6774 +f 10519/10519/6775 10520/10520/6776 10521/10521/6777 +f 10519/10519/6775 10521/10521/6777 10522/10522/6778 +f 10520/10520/6776 10474/10474/6742 10477/10477/6745 +f 10520/10520/6776 10477/10477/6745 10521/10521/6777 +f 10521/10521/6777 10477/10477/6745 10482/10482/6747 +f 10521/10521/6777 10482/10482/6747 10523/10523/6779 +f 10522/10522/6778 10521/10521/6777 10523/10523/6779 +f 10522/10522/6778 10523/10523/6779 10524/10524/6780 +f 10525/10525/6780 10526/10526/6779 10527/10527/6781 +f 10525/10525/6780 10527/10527/6781 10528/10528/6782 +f 10526/10526/6779 10529/10529/6747 10530/10530/6783 +f 10526/10526/6779 10530/10530/6783 10527/10527/6781 +f 10527/10527/6781 10530/10530/6783 10531/10531/6752 +f 10527/10527/6781 10531/10531/6752 10532/10532/6784 +f 10528/10528/6782 10527/10527/6781 10532/10532/6784 +f 10528/10528/6782 10532/10532/6784 10533/10533/6785 +f 10534/10534/6786 10535/10535/6784 10536/10536/6787 +f 10534/10534/6786 10536/10536/6787 10537/10537/6788 +f 10535/10535/6784 10538/10538/6752 10539/10539/6754 +f 10535/10535/6784 10539/10539/6754 10536/10536/6787 +f 10536/10536/6787 10539/10539/6754 10540/10540/6756 +f 10536/10536/6787 10540/10540/6756 10541/10541/6789 +f 10537/10537/6788 10536/10536/6787 10541/10541/6789 +f 10537/10537/6788 10541/10541/6789 10542/10542/6790 +f 10542/10542/6790 10541/10541/6789 10543/10543/6791 +f 10542/10542/6790 10543/10543/6791 10544/10544/6792 +f 10541/10541/6789 10540/10540/6756 10545/10545/6758 +f 10541/10541/6789 10545/10545/6758 10543/10543/6791 +f 10543/10543/6791 10545/10545/6758 10546/10546/6761 +f 10543/10543/6791 10546/10546/6761 10547/10547/6793 +f 10544/10544/6792 10543/10543/6791 10547/10547/6793 +f 10544/10544/6792 10547/10547/6793 10548/10548/6794 +f 10549/10549/6795 10550/10550/6796 10551/10551/6797 +f 10549/10549/6795 10551/10551/6797 10552/10552/6798 +f 10550/10550/6796 10553/10553/6762 10554/10554/6799 +f 10550/10550/6796 10554/10554/6799 10551/10551/6797 +f 10551/10551/6797 10554/10554/6799 10555/10555/6800 +f 10551/10551/6797 10555/10555/6800 10556/10556/6801 +f 10552/10552/6798 10551/10551/6797 10556/10556/6801 +f 10552/10552/6798 10556/10556/6801 10557/10557/6802 +f 10558/10558/6397 10559/10559/6803 10560/10560/6804 +f 10558/10558/6397 10560/10560/6804 10561/10561/6805 +f 10559/10559/6803 10562/10562/6806 10563/10563/6807 +f 10559/10559/6803 10563/10563/6807 10560/10560/6804 +f 10560/10560/6804 10563/10563/6807 10564/10564/6808 +f 10560/10560/6804 10564/10564/6808 10565/10565/6809 +f 10561/10561/6805 10560/10560/6804 10565/10565/6809 +f 10561/10561/6805 10565/10565/6809 10566/10566/6802 +f 10567/10567/6795 10568/10568/6810 10569/10569/6811 +f 10567/10567/6795 10569/10569/6811 10570/10570/6812 +f 10568/10568/6810 10571/10571/6813 10572/10572/6814 +f 10568/10568/6810 10572/10572/6814 10569/10569/6811 +f 10569/10569/6811 10572/10572/6814 10573/10573/6815 +f 10569/10569/6811 10573/10573/6815 10574/10574/6816 +f 10570/10570/6812 10569/10569/6811 10574/10574/6816 +f 10570/10570/6812 10574/10574/6816 10575/10575/6794 +f 10575/10575/6794 10574/10574/6816 10576/10576/6817 +f 10575/10575/6794 10576/10576/6817 10577/10577/6792 +f 10574/10574/6816 10573/10573/6815 10578/10578/6818 +f 10574/10574/6816 10578/10578/6818 10576/10576/6817 +f 10576/10576/6817 10578/10578/6818 10579/10579/6819 +f 10576/10576/6817 10579/10579/6819 10580/10580/6820 +f 10577/10577/6792 10576/10576/6817 10580/10580/6820 +f 10577/10577/6792 10580/10580/6820 10581/10581/6790 +f 10581/10581/6790 10580/10580/6820 10582/10582/6821 +f 10581/10581/6790 10582/10582/6821 10583/10583/6788 +f 10580/10580/6820 10579/10579/6819 10584/10584/6822 +f 10580/10580/6820 10584/10584/6822 10582/10582/6821 +f 10582/10582/6821 10584/10584/6822 10585/10585/6823 +f 10582/10582/6821 10585/10585/6823 10586/10586/6824 +f 10583/10583/6788 10582/10582/6821 10586/10586/6824 +f 10583/10583/6788 10586/10586/6824 10587/10587/6785 +f 10588/10588/6785 10586/10586/6824 10589/10589/6825 +f 10588/10588/6785 10589/10589/6825 10590/10590/6782 +f 10586/10586/6824 10591/10591/6823 10592/10592/6826 +f 10586/10586/6824 10592/10592/6826 10589/10589/6825 +f 10589/10589/6825 10592/10592/6826 10593/10593/6827 +f 10589/10589/6825 10593/10593/6827 10594/10594/6828 +f 10590/10590/6782 10589/10589/6825 10594/10594/6828 +f 10590/10590/6782 10594/10594/6828 10524/10524/6780 +f 10595/10595/6775 10596/10596/6829 10597/10597/6830 +f 10595/10595/6775 10597/10597/6830 10598/10598/6831 +f 10596/10596/6829 10599/10599/6832 10600/10600/6833 +f 10596/10596/6829 10600/10600/6833 10597/10597/6830 +f 10597/10597/6830 10600/10600/6833 10601/10601/6834 +f 10597/10597/6830 10601/10601/6834 10602/10602/6835 +f 10598/10598/6831 10597/10597/6830 10602/10602/6835 +f 10598/10598/6831 10602/10602/6835 10603/10603/6774 +f 10573/10573/6815 10604/10604/6836 10605/10605/6837 +f 10573/10573/6815 10605/10605/6837 10578/10578/6818 +f 10604/10604/6836 10606/10606/6838 10607/10607/6839 +f 10604/10604/6836 10607/10607/6839 10605/10605/6837 +f 10605/10605/6837 10607/10607/6839 10608/10608/6840 +f 10605/10605/6837 10608/10608/6840 10609/10609/6841 +f 10578/10578/6818 10605/10605/6837 10609/10609/6841 +f 10578/10578/6818 10609/10609/6841 10579/10579/6819 +f 10585/10585/6823 10610/10610/6842 10611/10611/6843 +f 10585/10585/6823 10611/10611/6843 10612/10612/6826 +f 10610/10610/6842 10613/10613/6844 10614/10614/6845 +f 10610/10610/6842 10614/10614/6845 10611/10611/6843 +f 10611/10611/6843 10614/10614/6845 10615/10615/6846 +f 10611/10611/6843 10615/10615/6846 10616/10616/6847 +f 10612/10612/6826 10611/10611/6843 10616/10616/6847 +f 10612/10612/6826 10616/10616/6847 10617/10617/6827 +f 10618/10618/6392 10619/10619/6848 10620/10620/6849 +f 10618/10618/6392 10620/10620/6849 10123/10123/6393 +f 10619/10619/6848 10621/10621/6850 10622/10622/6851 +f 10619/10619/6848 10622/10622/6851 10620/10620/6849 +f 10620/10620/6849 10622/10622/6851 10623/10623/6852 +f 10620/10620/6849 10623/10623/6852 10624/10624/6853 +f 10123/10123/6393 10620/10620/6849 10624/10624/6853 +f 10123/10123/6393 10624/10624/6853 10124/10124/6394 +f 10571/10571/6813 10625/10625/6854 10626/10626/6855 +f 10571/10571/6813 10626/10626/6855 10572/10572/6814 +f 10625/10625/6854 10627/10627/6856 10628/10628/6857 +f 10625/10625/6854 10628/10628/6857 10626/10626/6855 +f 10626/10626/6855 10628/10628/6857 10606/10606/6838 +f 10626/10626/6855 10606/10606/6838 10604/10604/6836 +f 10572/10572/6814 10626/10626/6855 10604/10604/6836 +f 10572/10572/6814 10604/10604/6836 10573/10573/6815 +f 10629/10629/6806 10630/10630/6858 10631/10631/6859 +f 10629/10629/6806 10631/10631/6859 10632/10632/6807 +f 10630/10630/6858 10633/10633/6860 10634/10634/6861 +f 10630/10630/6858 10634/10634/6861 10631/10631/6859 +f 10631/10631/6859 10634/10634/6861 10635/10635/6862 +f 10631/10631/6859 10635/10635/6862 10636/10636/6863 +f 10632/10632/6807 10631/10631/6859 10636/10636/6863 +f 10632/10632/6807 10636/10636/6863 10637/10637/6808 +f 10579/10579/6819 10609/10609/6841 10638/10638/6864 +f 10579/10579/6819 10638/10638/6864 10584/10584/6822 +f 10609/10609/6841 10608/10608/6840 10639/10639/6865 +f 10609/10609/6841 10639/10639/6865 10638/10638/6864 +f 10638/10638/6864 10639/10639/6865 10613/10613/6844 +f 10638/10638/6864 10613/10613/6844 10610/10610/6842 +f 10584/10584/6822 10638/10638/6864 10610/10610/6842 +f 10584/10584/6822 10610/10610/6842 10585/10585/6823 +f 10640/10640/6832 10641/10641/6866 10642/10642/6867 +f 10640/10640/6832 10642/10642/6867 10643/10643/6833 +f 10641/10641/6866 10644/10644/6868 10645/10645/6869 +f 10641/10641/6866 10645/10645/6869 10642/10642/6867 +f 10642/10642/6867 10645/10645/6869 10646/10646/6870 +f 10642/10642/6867 10646/10646/6870 10647/10647/6871 +f 10643/10643/6833 10642/10642/6867 10647/10647/6871 +f 10643/10643/6833 10647/10647/6871 10648/10648/6834 +f 10444/10444/6712 10649/10649/6872 10650/10650/6873 +f 10444/10444/6712 10650/10650/6873 10449/10449/6717 +f 10649/10649/6872 10651/10651/6874 10652/10652/6491 +f 10649/10649/6872 10652/10652/6491 10650/10650/6873 +f 10650/10650/6873 10652/10652/6491 10653/10653/6465 +f 10650/10650/6873 10653/10653/6465 10654/10654/6875 +f 10449/10449/6717 10650/10650/6873 10654/10654/6875 +f 10449/10449/6717 10654/10654/6875 10450/10450/6718 +f 10655/10655/6704 10656/10656/6876 10657/10657/6877 +f 10655/10655/6704 10657/10657/6877 10658/10658/6705 +f 10656/10656/6876 10659/10659/6483 10660/10660/6878 +f 10656/10656/6876 10660/10660/6878 10657/10657/6877 +f 10657/10657/6877 10660/10660/6878 10661/10661/6447 +f 10657/10657/6877 10661/10661/6447 10662/10662/6879 +f 10658/10658/6705 10657/10657/6877 10662/10662/6879 +f 10658/10658/6705 10662/10662/6879 10663/10663/6706 +f 10664/10664/6880 10665/10665/6881 10666/10666/6882 +f 10664/10664/6880 10666/10666/6882 10667/10667/6417 +f 10665/10665/6881 10205/10205/6474 10208/10208/6477 +f 10665/10665/6881 10208/10208/6477 10666/10666/6882 +f 10666/10666/6882 10208/10208/6477 10213/10213/6482 +f 10666/10666/6882 10213/10213/6482 10668/10668/6883 +f 10667/10667/6417 10666/10666/6882 10668/10668/6883 +f 10667/10667/6417 10668/10668/6883 10669/10669/6418 +f 10450/10450/6718 10654/10654/6875 10670/10670/6884 +f 10450/10450/6718 10670/10670/6884 10455/10455/6723 +f 10654/10654/6875 10653/10653/6465 10671/10671/6468 +f 10654/10654/6875 10671/10671/6468 10670/10670/6884 +f 10670/10670/6884 10671/10671/6468 10672/10672/6473 +f 10670/10670/6884 10672/10672/6473 10673/10673/6885 +f 10455/10455/6723 10670/10670/6884 10673/10673/6885 +f 10455/10455/6723 10673/10673/6885 10456/10456/6724 +f 10674/10674/6695 10675/10675/6886 10676/10676/6887 +f 10674/10674/6695 10676/10676/6887 10677/10677/6696 +f 10675/10675/6886 10187/10187/6456 10190/10190/6459 +f 10675/10675/6886 10190/10190/6459 10676/10676/6887 +f 10676/10676/6887 10190/10190/6459 10195/10195/6464 +f 10676/10676/6887 10195/10195/6464 10678/10678/6888 +f 10677/10677/6696 10676/10676/6887 10678/10678/6888 +f 10677/10677/6696 10678/10678/6888 10679/10679/6697 +f 10438/10438/6706 10680/10680/6879 10681/10681/6889 +f 10438/10438/6706 10681/10681/6889 10443/10443/6711 +f 10680/10680/6879 10682/10682/6447 10683/10683/6450 +f 10680/10680/6879 10683/10683/6450 10681/10681/6889 +f 10681/10681/6889 10683/10683/6450 10651/10651/6874 +f 10681/10681/6889 10651/10651/6874 10649/10649/6872 +f 10443/10443/6711 10681/10681/6889 10649/10649/6872 +f 10443/10443/6711 10649/10649/6872 10444/10444/6712 +f 10684/10684/6731 10685/10685/6890 10686/10686/6891 +f 10684/10684/6731 10686/10686/6891 10687/10687/6732 +f 10685/10685/6890 10169/10169/6438 10172/10172/6441 +f 10685/10685/6890 10172/10172/6441 10686/10686/6891 +f 10686/10686/6891 10172/10172/6441 10177/10177/6446 +f 10686/10686/6891 10177/10177/6446 10688/10688/6892 +f 10687/10687/6732 10686/10686/6891 10688/10688/6892 +f 10687/10687/6732 10688/10688/6892 10689/10689/6733 +f 10184/10184/6453 10690/10690/6893 10691/10691/6894 +f 10184/10184/6453 10691/10691/6894 10224/10224/6492 +f 10690/10690/6893 10233/10233/6501 10277/10277/6545 +f 10690/10690/6893 10277/10277/6545 10691/10691/6894 +f 10691/10691/6894 10277/10277/6545 10243/10243/6511 +f 10691/10691/6894 10243/10243/6511 10692/10692/6895 +f 10224/10224/6492 10691/10691/6894 10692/10692/6895 +f 10224/10224/6492 10692/10692/6895 10200/10200/6469 +f 10693/10693/6442 10694/10694/6896 10695/10695/6897 +f 10693/10693/6442 10695/10695/6897 10696/10696/6443 +f 10694/10694/6896 10697/10697/6535 10698/10698/6538 +f 10694/10694/6896 10698/10698/6538 10695/10695/6897 +f 10695/10695/6897 10698/10698/6538 10699/10699/6543 +f 10695/10695/6897 10699/10699/6543 10700/10700/6898 +f 10696/10696/6443 10695/10695/6897 10700/10700/6898 +f 10696/10696/6443 10700/10700/6898 10701/10701/6899 +f 10702/10702/6460 10703/10703/6900 10704/10704/6901 +f 10702/10702/6460 10704/10704/6901 10705/10705/6902 +f 10703/10703/6900 10258/10258/6526 10261/10261/6529 +f 10703/10703/6900 10261/10261/6529 10704/10704/6901 +f 10704/10704/6901 10261/10261/6529 10266/10266/6534 +f 10704/10704/6901 10266/10266/6534 10706/10706/6903 +f 10705/10705/6902 10704/10704/6901 10706/10706/6903 +f 10705/10705/6902 10706/10706/6903 10707/10707/6904 +f 10218/10218/6487 10708/10708/6905 10709/10709/6906 +f 10218/10218/6487 10709/10709/6906 10219/10219/6488 +f 10708/10708/6905 10710/10710/6520 10711/10711/6523 +f 10708/10708/6905 10711/10711/6523 10709/10709/6906 +f 10709/10709/6906 10711/10711/6523 10712/10712/6493 +f 10709/10709/6906 10712/10712/6493 10713/10713/6907 +f 10219/10219/6488 10709/10709/6906 10713/10713/6907 +f 10219/10219/6488 10713/10713/6907 10182/10182/6489 +f 10200/10200/6469 10692/10692/6895 10714/10714/6908 +f 10200/10200/6469 10714/10714/6908 10201/10201/6470 +f 10692/10692/6895 10243/10243/6511 10246/10246/6514 +f 10692/10692/6895 10246/10246/6514 10714/10714/6908 +f 10714/10714/6908 10246/10246/6514 10251/10251/6519 +f 10714/10714/6908 10251/10251/6519 10715/10715/6909 +f 10201/10201/6470 10714/10714/6908 10715/10715/6909 +f 10201/10201/6470 10715/10715/6909 10202/10202/6471 +f 10716/10716/6478 10717/10717/6910 10718/10718/6911 +f 10716/10716/6478 10718/10718/6911 10719/10719/6479 +f 10717/10717/6910 10234/10234/6502 10237/10237/6505 +f 10717/10717/6910 10237/10237/6505 10718/10718/6911 +f 10718/10718/6911 10237/10237/6505 10242/10242/6510 +f 10718/10718/6911 10242/10242/6510 10720/10720/6912 +f 10719/10719/6479 10718/10718/6911 10720/10720/6912 +f 10719/10719/6479 10720/10720/6912 10721/10721/6913 +f 10182/10182/6451 10722/10722/6907 10723/10723/6914 +f 10182/10182/6451 10723/10723/6914 10183/10183/6452 +f 10722/10722/6907 10225/10225/6493 10228/10228/6496 +f 10722/10722/6907 10228/10228/6496 10723/10723/6914 +f 10723/10723/6914 10228/10228/6496 10233/10233/6501 +f 10723/10723/6914 10233/10233/6501 10690/10690/6893 +f 10183/10183/6452 10723/10723/6914 10690/10690/6893 +f 10183/10183/6452 10690/10690/6893 10184/10184/6453 +f 10707/10707/6462 10724/10724/6903 10725/10725/6915 +f 10707/10707/6462 10725/10725/6915 10726/10726/6916 +f 10724/10724/6903 10727/10727/6917 10728/10728/6918 +f 10724/10724/6903 10728/10728/6918 10725/10725/6915 +f 10725/10725/6915 10728/10728/6918 10710/10710/6520 +f 10725/10725/6915 10710/10710/6520 10708/10708/6905 +f 10726/10726/6916 10725/10725/6915 10708/10708/6905 +f 10726/10726/6916 10708/10708/6905 10218/10218/6487 +f 10429/10429/6697 10729/10729/6888 10730/10730/6919 +f 10429/10429/6697 10730/10730/6919 10731/10731/6920 +f 10729/10729/6888 10195/10195/6464 10732/10732/6921 +f 10729/10729/6888 10732/10732/6921 10730/10730/6919 +f 10730/10730/6919 10732/10732/6921 10659/10659/6483 +f 10730/10730/6919 10659/10659/6483 10656/10656/6876 +f 10731/10731/6920 10730/10730/6919 10656/10656/6876 +f 10731/10731/6920 10656/10656/6876 10655/10655/6704 +f 10617/10617/6827 10616/10616/6847 10733/10733/6922 +f 10617/10617/6827 10733/10733/6922 10734/10734/6923 +f 10616/10616/6847 10615/10615/6846 10735/10735/6924 +f 10616/10616/6847 10735/10735/6924 10733/10733/6922 +f 10733/10733/6922 10735/10735/6924 10644/10644/6868 +f 10733/10733/6922 10644/10644/6868 10641/10641/6866 +f 10734/10734/6923 10733/10733/6922 10641/10641/6866 +f 10734/10734/6923 10641/10641/6866 10640/10640/6832 +f 10524/10524/6780 10594/10594/6828 10736/10736/6925 +f 10524/10524/6780 10736/10736/6925 10522/10522/6778 +f 10594/10594/6828 10593/10593/6827 10737/10737/6926 +f 10594/10594/6828 10737/10737/6926 10736/10736/6925 +f 10736/10736/6925 10737/10737/6926 10599/10599/6832 +f 10736/10736/6925 10599/10599/6832 10596/10596/6829 +f 10522/10522/6778 10736/10736/6925 10596/10596/6829 +f 10522/10522/6778 10596/10596/6829 10595/10595/6775 +f 10603/10603/6774 10738/10738/6927 10739/10739/6928 +f 10603/10603/6774 10739/10739/6928 10740/10740/6831 +f 10738/10738/6927 10741/10741/6741 10742/10742/6929 +f 10738/10738/6927 10742/10742/6929 10739/10739/6928 +f 10739/10739/6928 10742/10742/6929 10474/10474/6742 +f 10739/10739/6928 10474/10474/6742 10520/10520/6776 +f 10740/10740/6831 10739/10739/6928 10520/10520/6776 +f 10740/10740/6831 10520/10520/6776 10519/10519/6775 +f 10741/10741/6741 10743/10743/6740 10744/10744/6930 +f 10741/10741/6741 10744/10744/6930 10742/10742/6929 +f 10743/10743/6740 10745/10745/6699 10746/10746/6931 +f 10743/10743/6740 10746/10746/6931 10744/10744/6930 +f 10744/10744/6930 10746/10746/6931 10478/10478/6700 +f 10744/10744/6930 10478/10478/6700 10475/10475/6743 +f 10742/10742/6929 10744/10744/6930 10475/10475/6743 +f 10742/10742/6929 10475/10475/6743 10474/10474/6742 +f 10431/10431/6699 10430/10430/6698 10747/10747/6932 +f 10431/10431/6699 10747/10747/6932 10748/10748/6931 +f 10430/10430/6698 10429/10429/6697 10731/10731/6920 +f 10430/10430/6698 10731/10731/6920 10747/10747/6932 +f 10747/10747/6932 10731/10731/6920 10655/10655/6704 +f 10747/10747/6932 10655/10655/6704 10749/10749/6701 +f 10748/10748/6931 10747/10747/6932 10749/10749/6701 +f 10748/10748/6931 10749/10749/6701 10432/10432/6700 +f 10325/10325/6593 10368/10368/6636 10750/10750/6933 +f 10325/10325/6593 10750/10750/6933 10751/10751/6934 +f 10368/10368/6636 10367/10367/6635 10752/10752/6935 +f 10368/10368/6636 10752/10752/6935 10750/10750/6933 +f 10750/10750/6933 10752/10752/6935 10359/10359/6627 +f 10750/10750/6933 10359/10359/6627 10357/10357/6625 +f 10751/10751/6934 10750/10750/6933 10357/10357/6625 +f 10751/10751/6934 10357/10357/6625 10347/10347/6615 +f 10307/10307/6575 10326/10326/6594 10753/10753/6936 +f 10307/10307/6575 10753/10753/6936 10754/10754/6937 +f 10326/10326/6594 10325/10325/6593 10751/10751/6934 +f 10326/10326/6594 10751/10751/6934 10753/10753/6936 +f 10753/10753/6936 10751/10751/6934 10347/10347/6615 +f 10753/10753/6936 10347/10347/6615 10345/10345/6613 +f 10754/10754/6937 10753/10753/6936 10345/10345/6613 +f 10754/10754/6937 10345/10345/6613 10287/10287/6555 +f 10264/10264/6532 10308/10308/6576 10755/10755/6938 +f 10264/10264/6532 10755/10755/6938 10756/10756/6939 +f 10308/10308/6576 10307/10307/6575 10754/10754/6937 +f 10308/10308/6576 10754/10754/6937 10755/10755/6938 +f 10755/10755/6938 10754/10754/6937 10287/10287/6555 +f 10755/10755/6938 10287/10287/6555 10285/10285/6553 +f 10756/10756/6939 10755/10755/6938 10285/10285/6553 +f 10756/10756/6939 10285/10285/6553 10256/10256/6524 +f 10266/10266/6534 10265/10265/6533 10757/10757/6940 +f 10266/10266/6534 10757/10757/6940 10758/10758/6918 +f 10265/10265/6533 10264/10264/6532 10756/10756/6939 +f 10265/10265/6533 10756/10756/6939 10757/10757/6940 +f 10757/10757/6940 10756/10756/6939 10256/10256/6524 +f 10757/10757/6940 10256/10256/6524 10253/10253/6521 +f 10758/10758/6918 10757/10757/6940 10253/10253/6521 +f 10758/10758/6918 10253/10253/6521 10252/10252/6520 +f 10195/10195/6464 10194/10194/6463 10759/10759/6941 +f 10195/10195/6464 10759/10759/6941 10732/10732/6921 +f 10194/10194/6463 10760/10760/6462 10761/10761/6942 +f 10194/10194/6463 10761/10761/6942 10759/10759/6941 +f 10759/10759/6941 10761/10761/6942 10762/10762/6487 +f 10759/10759/6941 10762/10762/6487 10763/10763/6943 +f 10732/10732/6921 10759/10759/6941 10763/10763/6943 +f 10732/10732/6921 10763/10763/6943 10659/10659/6483 +f 10422/10422/6690 10421/10421/6689 10764/10764/6944 +f 10422/10422/6690 10764/10764/6944 10765/10765/6945 +f 10421/10421/6689 10420/10420/6688 10766/10766/6946 +f 10421/10421/6689 10766/10766/6946 10764/10764/6944 +f 10764/10764/6944 10766/10766/6946 10164/10164/6433 +f 10764/10764/6944 10164/10164/6433 10161/10161/6430 +f 10765/10765/6945 10764/10764/6944 10161/10161/6430 +f 10765/10765/6945 10161/10161/6430 10160/10160/6429 +f 10767/10767/6471 10768/10768/6947 10769/10769/6948 +f 10767/10767/6471 10769/10769/6948 10770/10770/6949 +f 10768/10768/6947 10771/10771/6519 10772/10772/6950 +f 10768/10768/6947 10772/10772/6950 10769/10769/6948 +f 10769/10769/6948 10772/10772/6950 10697/10697/6535 +f 10769/10769/6948 10697/10697/6535 10694/10694/6896 +f 10770/10770/6949 10769/10769/6948 10694/10694/6896 +f 10770/10770/6949 10694/10694/6896 10693/10693/6442 +f 10456/10456/6724 10773/10773/6885 10774/10774/6951 +f 10456/10456/6724 10774/10774/6951 10775/10775/6952 +f 10773/10773/6885 10776/10776/6473 10777/10777/6953 +f 10773/10773/6885 10777/10777/6953 10774/10774/6951 +f 10774/10774/6951 10777/10777/6953 10169/10169/6438 +f 10774/10774/6951 10169/10169/6438 10685/10685/6890 +f 10775/10775/6952 10774/10774/6951 10685/10685/6890 +f 10775/10775/6952 10685/10685/6890 10684/10684/6731 +f 10637/10637/6808 10636/10636/6863 10778/10778/6954 +f 10637/10637/6808 10778/10778/6954 10779/10779/6955 +f 10636/10636/6863 10635/10635/6862 10780/10780/6956 +f 10636/10636/6863 10780/10780/6956 10778/10778/6954 +f 10778/10778/6954 10780/10780/6956 10627/10627/6856 +f 10778/10778/6954 10627/10627/6856 10625/10625/6854 +f 10779/10779/6955 10778/10778/6954 10625/10625/6854 +f 10779/10779/6955 10625/10625/6854 10571/10571/6813 +f 10566/10566/6802 10565/10565/6809 10781/10781/6957 +f 10566/10566/6802 10781/10781/6957 10782/10782/6798 +f 10565/10565/6809 10564/10564/6808 10779/10779/6955 +f 10565/10565/6809 10779/10779/6955 10781/10781/6957 +f 10781/10781/6957 10779/10779/6955 10783/10783/6813 +f 10781/10781/6957 10783/10783/6813 10784/10784/6810 +f 10782/10782/6798 10781/10781/6957 10784/10784/6810 +f 10782/10782/6798 10784/10784/6810 10567/10567/6795 +f 10548/10548/6794 10547/10547/6793 10785/10785/6958 +f 10548/10548/6794 10785/10785/6958 10786/10786/6812 +f 10547/10547/6793 10546/10546/6761 10787/10787/6959 +f 10547/10547/6793 10787/10787/6959 10785/10785/6958 +f 10785/10785/6958 10787/10787/6959 10788/10788/6960 +f 10785/10785/6958 10788/10788/6960 10789/10789/6796 +f 10786/10786/6812 10785/10785/6958 10789/10789/6796 +f 10786/10786/6812 10789/10789/6796 10549/10549/6795 +f 10503/10503/6761 10502/10502/6760 10790/10790/6961 +f 10503/10503/6761 10790/10790/6961 10791/10791/6959 +f 10502/10502/6760 10501/10501/6759 10792/10792/6962 +f 10502/10502/6760 10792/10792/6962 10790/10790/6961 +f 10790/10790/6961 10792/10792/6962 10793/10793/6963 +f 10790/10790/6961 10793/10793/6963 10794/10794/6964 +f 10791/10791/6959 10790/10790/6961 10794/10794/6964 +f 10791/10791/6959 10794/10794/6964 10795/10795/6960 +f 10458/10458/6726 10457/10457/6725 10796/10796/6965 +f 10458/10458/6726 10796/10796/6965 10797/10797/6962 +f 10457/10457/6725 10456/10456/6724 10798/10798/6952 +f 10457/10457/6725 10798/10798/6952 10796/10796/6965 +f 10796/10796/6965 10798/10798/6952 10463/10463/6731 +f 10796/10796/6965 10463/10463/6731 10460/10460/6728 +f 10797/10797/6962 10796/10796/6965 10460/10460/6728 +f 10797/10797/6962 10460/10460/6728 10459/10459/6727 +f 10413/10413/6681 10412/10412/6680 10799/10799/6966 +f 10413/10413/6681 10799/10799/6966 10800/10800/6967 +f 10412/10412/6680 10411/10411/6679 10801/10801/6968 +f 10412/10412/6680 10801/10801/6968 10799/10799/6966 +f 10799/10799/6966 10801/10801/6968 10387/10387/6655 +f 10799/10799/6966 10387/10387/6655 10384/10384/6652 +f 10800/10800/6967 10799/10799/6966 10384/10384/6652 +f 10800/10800/6967 10384/10384/6652 10383/10383/6651 +f 10343/10343/6611 10395/10395/6663 10802/10802/6969 +f 10343/10343/6611 10802/10802/6969 10803/10803/6970 +f 10395/10395/6663 10394/10394/6662 10804/10804/6971 +f 10395/10395/6663 10804/10804/6971 10802/10802/6969 +f 10802/10802/6969 10804/10804/6971 10371/10371/6639 +f 10802/10802/6969 10371/10371/6639 10369/10369/6637 +f 10803/10803/6970 10802/10802/6969 10369/10369/6637 +f 10803/10803/6970 10369/10369/6637 10329/10329/6597 +f 10313/10313/6581 10344/10344/6612 10805/10805/6972 +f 10313/10313/6581 10805/10805/6972 10806/10806/6973 +f 10344/10344/6612 10343/10343/6611 10803/10803/6970 +f 10344/10344/6612 10803/10803/6970 10805/10805/6972 +f 10805/10805/6972 10803/10803/6970 10329/10329/6597 +f 10805/10805/6972 10329/10329/6597 10327/10327/6595 +f 10806/10806/6973 10805/10805/6972 10327/10327/6595 +f 10806/10806/6973 10327/10327/6595 10299/10299/6567 +f 10249/10249/6517 10314/10314/6582 10807/10807/6974 +f 10249/10249/6517 10807/10807/6974 10808/10808/6975 +f 10314/10314/6582 10313/10313/6581 10806/10806/6973 +f 10314/10314/6582 10806/10806/6973 10807/10807/6974 +f 10807/10807/6974 10806/10806/6973 10299/10299/6567 +f 10807/10807/6974 10299/10299/6567 10297/10297/6565 +f 10808/10808/6975 10807/10807/6974 10297/10297/6565 +f 10808/10808/6975 10297/10297/6565 10271/10271/6539 +f 10251/10251/6519 10250/10250/6518 10809/10809/6976 +f 10251/10251/6519 10809/10809/6976 10810/10810/6977 +f 10250/10250/6518 10249/10249/6517 10808/10808/6975 +f 10250/10250/6518 10808/10808/6975 10809/10809/6976 +f 10809/10809/6976 10808/10808/6975 10271/10271/6539 +f 10809/10809/6976 10271/10271/6539 10268/10268/6536 +f 10810/10810/6977 10809/10809/6976 10268/10268/6536 +f 10810/10810/6977 10268/10268/6536 10267/10267/6535 +f 10204/10204/6473 10811/10811/6978 10812/10812/6979 +f 10204/10204/6473 10812/10812/6979 10813/10813/6953 +f 10811/10811/6978 10767/10767/6471 10770/10770/6949 +f 10811/10811/6978 10770/10770/6949 10812/10812/6979 +f 10812/10812/6979 10770/10770/6949 10693/10693/6442 +f 10812/10812/6979 10693/10693/6442 10814/10814/6439 +f 10813/10813/6953 10812/10812/6979 10814/10814/6439 +f 10813/10813/6953 10814/10814/6439 10815/10815/6438 +f 10394/10394/6662 10816/10816/6980 10817/10817/6981 +f 10394/10394/6662 10817/10817/6981 10804/10804/6971 +f 10816/10816/6980 10413/10413/6681 10800/10800/6967 +f 10816/10816/6980 10800/10800/6967 10817/10817/6981 +f 10817/10817/6981 10800/10800/6967 10383/10383/6651 +f 10817/10817/6981 10383/10383/6651 10818/10818/6982 +f 10804/10804/6971 10817/10817/6981 10818/10818/6982 +f 10804/10804/6971 10818/10818/6982 10371/10371/6639 +f 10367/10367/6635 10819/10819/6983 10820/10820/6984 +f 10367/10367/6635 10820/10820/6984 10752/10752/6935 +f 10819/10819/6983 10422/10422/6690 10765/10765/6945 +f 10819/10819/6983 10765/10765/6945 10820/10820/6984 +f 10820/10820/6984 10765/10765/6945 10160/10160/6429 +f 10820/10820/6984 10160/10160/6429 10821/10821/6985 +f 10752/10752/6935 10820/10820/6984 10821/10821/6985 +f 10752/10752/6935 10821/10821/6985 10359/10359/6627 +f 10365/10365/6633 10822/10822/6986 10823/10823/6987 +f 10365/10365/6633 10823/10823/6987 10366/10366/6634 +f 10822/10822/6986 10414/10414/6682 10417/10417/6685 +f 10822/10822/6986 10417/10417/6685 10823/10823/6987 +f 10823/10823/6987 10417/10417/6685 10422/10422/6690 +f 10823/10823/6987 10422/10422/6690 10819/10819/6983 +f 10366/10366/6634 10823/10823/6987 10819/10819/6983 +f 10366/10366/6634 10819/10819/6983 10367/10367/6635 +f 10355/10355/6623 10824/10824/6988 10825/10825/6989 +f 10355/10355/6623 10825/10825/6989 10393/10393/6661 +f 10824/10824/6988 10407/10407/6675 10409/10409/6677 +f 10824/10824/6988 10409/10409/6677 10825/10825/6989 +f 10825/10825/6989 10409/10409/6677 10413/10413/6681 +f 10825/10825/6989 10413/10413/6681 10816/10816/6980 +f 10393/10393/6661 10825/10825/6989 10816/10816/6980 +f 10393/10393/6661 10816/10816/6980 10394/10394/6662 +f 10353/10353/6621 10826/10826/6990 10827/10827/6991 +f 10353/10353/6621 10827/10827/6991 10354/10354/6622 +f 10826/10826/6990 10382/10382/6650 10403/10403/6671 +f 10826/10826/6990 10403/10403/6671 10827/10827/6991 +f 10827/10827/6991 10403/10403/6671 10407/10407/6675 +f 10827/10827/6991 10407/10407/6675 10824/10824/6988 +f 10354/10354/6622 10827/10827/6991 10824/10824/6988 +f 10354/10354/6622 10824/10824/6988 10355/10355/6623 +f 10371/10371/6639 10818/10818/6982 10828/10828/6992 +f 10371/10371/6639 10828/10828/6992 10372/10372/6640 +f 10818/10818/6982 10383/10383/6651 10386/10386/6654 +f 10818/10818/6982 10386/10386/6654 10828/10828/6992 +f 10828/10828/6992 10386/10386/6654 10391/10391/6659 +f 10828/10828/6992 10391/10391/6659 10829/10829/6993 +f 10372/10372/6640 10828/10828/6992 10829/10829/6993 +f 10372/10372/6640 10829/10829/6993 10373/10373/6641 +f 10361/10361/6629 10830/10830/6994 10831/10831/6995 +f 10361/10361/6629 10831/10831/6995 10376/10376/6644 +f 10830/10830/6994 10168/10168/6437 10378/10378/6646 +f 10830/10830/6994 10378/10378/6646 10831/10831/6995 +f 10831/10831/6995 10378/10378/6646 10382/10382/6650 +f 10831/10831/6995 10382/10382/6650 10826/10826/6990 +f 10376/10376/6644 10831/10831/6995 10826/10826/6990 +f 10376/10376/6644 10826/10826/6990 10353/10353/6621 +f 10359/10359/6627 10821/10821/6985 10832/10832/6996 +f 10359/10359/6627 10832/10832/6996 10360/10360/6628 +f 10821/10821/6985 10160/10160/6429 10163/10163/6432 +f 10821/10821/6985 10163/10163/6432 10832/10832/6996 +f 10832/10832/6996 10163/10163/6432 10168/10168/6437 +f 10832/10832/6996 10168/10168/6437 10830/10830/6994 +f 10360/10360/6628 10832/10832/6996 10830/10830/6994 +f 10360/10360/6628 10830/10830/6994 10361/10361/6629 +f 10398/10398/6666 10833/10833/6997 10834/10834/6998 +f 10398/10398/6666 10834/10834/6998 10399/10399/6667 +f 10833/10833/6997 10835/10835/6420 10836/10836/6423 +f 10833/10833/6997 10836/10836/6423 10834/10834/6998 +f 10834/10834/6998 10836/10836/6423 10159/10159/6428 +f 10834/10834/6998 10159/10159/6428 10837/10837/6999 +f 10399/10399/6667 10834/10834/6998 10837/10837/6999 +f 10399/10399/6667 10837/10837/6999 10400/10400/6668 +f 10373/10373/6641 10829/10829/6993 10838/10838/7000 +f 10373/10373/6641 10838/10838/7000 10839/10839/7001 +f 10829/10829/6993 10391/10391/6659 10840/10840/7002 +f 10829/10829/6993 10840/10840/7002 10838/10838/7000 +f 10838/10838/7000 10840/10840/7002 10835/10835/6420 +f 10838/10838/7000 10835/10835/6420 10833/10833/6997 +f 10839/10839/7001 10838/10838/7000 10833/10833/6997 +f 10839/10839/7001 10833/10833/6997 10398/10398/6666 +f 10841/10841/6444 10842/10842/6898 10843/10843/7003 +f 10841/10841/6444 10843/10843/7003 10844/10844/7004 +f 10842/10842/6898 10275/10275/6543 10845/10845/7005 +f 10842/10842/6898 10845/10845/7005 10843/10843/7003 +f 10843/10843/7003 10845/10845/7005 10234/10234/6502 +f 10843/10843/7003 10234/10234/6502 10717/10717/6910 +f 10844/10844/7004 10843/10843/7003 10717/10717/6910 +f 10844/10844/7004 10717/10717/6910 10716/10716/6478 +f 10465/10465/6733 10846/10846/7006 10847/10847/7007 +f 10465/10465/6733 10847/10847/7007 10848/10848/7008 +f 10846/10846/7006 10849/10849/6446 10850/10850/7009 +f 10846/10846/7006 10850/10850/7009 10847/10847/7007 +f 10847/10847/7007 10850/10850/7009 10205/10205/6474 +f 10847/10847/7007 10205/10205/6474 10665/10665/6881 +f 10848/10848/7008 10847/10847/7007 10665/10665/6881 +f 10848/10848/7008 10665/10665/6881 10664/10664/6880 +f 10851/10851/7010 10852/10852/7011 10853/10853/7012 +f 10851/10851/7010 10853/10853/7012 10854/10854/7013 +f 10852/10852/7011 10855/10855/7014 10856/10856/7015 +f 10852/10852/7011 10856/10856/7015 10853/10853/7012 +f 10853/10853/7012 10856/10856/7015 10857/10857/7016 +f 10853/10853/7012 10857/10857/7016 10858/10858/6858 +f 10854/10854/7013 10853/10853/7012 10858/10858/6858 +f 10854/10854/7013 10858/10858/6858 10562/10562/6806 +f 10859/10859/6405 10860/10860/7017 10861/10861/7018 +f 10859/10859/6405 10861/10861/7018 10130/10130/6400 +f 10860/10860/7017 10862/10862/7010 10863/10863/7013 +f 10860/10860/7017 10863/10863/7013 10861/10861/7018 +f 10861/10861/7018 10863/10863/7013 10629/10629/6806 +f 10861/10861/7018 10629/10629/6806 10864/10864/6803 +f 10130/10130/6400 10861/10861/7018 10864/10864/6803 +f 10130/10130/6400 10864/10864/6803 10865/10865/6397 +f 10331/10331/6599 10374/10374/6642 10866/10866/7019 +f 10331/10331/6599 10866/10866/7019 10867/10867/7020 +f 10374/10374/6642 10373/10373/6641 10839/10839/7001 +f 10374/10374/6642 10839/10839/7001 10866/10866/7019 +f 10866/10866/7019 10839/10839/7001 10398/10398/6666 +f 10866/10866/7019 10398/10398/6666 10396/10396/6664 +f 10867/10867/7020 10866/10866/7019 10396/10396/6664 +f 10867/10867/7020 10396/10396/6664 10317/10317/6585 +f 10301/10301/6569 10332/10332/6600 10868/10868/7021 +f 10301/10301/6569 10868/10868/7021 10869/10869/7022 +f 10332/10332/6600 10331/10331/6599 10867/10867/7020 +f 10332/10332/6600 10867/10867/7020 10868/10868/7021 +f 10868/10868/7021 10867/10867/7020 10317/10317/6585 +f 10868/10868/7021 10317/10317/6585 10315/10315/6583 +f 10869/10869/7022 10868/10868/7021 10315/10315/6583 +f 10869/10869/7022 10315/10315/6583 10293/10293/6561 +f 10273/10273/6541 10302/10302/6570 10870/10870/7023 +f 10273/10273/6541 10870/10870/7023 10871/10871/7024 +f 10302/10302/6570 10301/10301/6569 10869/10869/7022 +f 10302/10302/6570 10869/10869/7022 10870/10870/7023 +f 10870/10870/7023 10869/10869/7022 10293/10293/6561 +f 10870/10870/7023 10293/10293/6561 10291/10291/6559 +f 10871/10871/7024 10870/10870/7023 10291/10291/6559 +f 10871/10871/7024 10291/10291/6559 10238/10238/6506 +f 10275/10275/6543 10274/10274/6542 10872/10872/7025 +f 10275/10275/6543 10872/10872/7025 10845/10845/7005 +f 10274/10274/6542 10273/10273/6541 10871/10871/7024 +f 10274/10274/6542 10871/10871/7024 10872/10872/7025 +f 10872/10872/7025 10871/10871/7024 10238/10238/6506 +f 10872/10872/7025 10238/10238/6506 10235/10235/6503 +f 10845/10845/7005 10872/10872/7025 10235/10235/6503 +f 10845/10845/7005 10235/10235/6503 10234/10234/6502 +f 10849/10849/6446 10873/10873/7026 10874/10874/7027 +f 10849/10849/6446 10874/10874/7027 10850/10850/7009 +f 10873/10873/7026 10875/10875/6444 10876/10876/7004 +f 10873/10873/7026 10876/10876/7004 10874/10874/7027 +f 10874/10874/7027 10876/10876/7004 10209/10209/6478 +f 10874/10874/7027 10209/10209/6478 10206/10206/6475 +f 10850/10850/7009 10874/10874/7027 10206/10206/6475 +f 10850/10850/7009 10206/10206/6475 10205/10205/6474 +f 10391/10391/6659 10390/10390/6658 10877/10877/7028 +f 10391/10391/6659 10877/10877/7028 10840/10840/7002 +f 10390/10390/6658 10389/10389/6657 10878/10878/7029 +f 10390/10390/6658 10878/10878/7029 10877/10877/7028 +f 10877/10877/7028 10878/10878/7029 10155/10155/6424 +f 10877/10877/7028 10155/10155/6424 10879/10879/6421 +f 10840/10840/7002 10877/10877/7028 10879/10879/6421 +f 10840/10840/7002 10879/10879/6421 10835/10835/6420 +f 10880/10880/6766 10881/10881/7030 10882/10882/7031 +f 10880/10880/6766 10882/10882/7031 10883/10883/7032 +f 10881/10881/7030 10689/10689/6733 10884/10884/7008 +f 10881/10881/7030 10884/10884/7008 10882/10882/7031 +f 10882/10882/7031 10884/10884/7008 10147/10147/6416 +f 10882/10882/7031 10147/10147/6416 10145/10145/6414 +f 10883/10883/7032 10882/10882/7031 10145/10145/6414 +f 10883/10883/7032 10145/10145/6414 10140/10140/6409 +f 10512/10512/6768 10511/10511/6767 10885/10885/7033 +f 10512/10512/6768 10885/10885/7033 10886/10886/7034 +f 10511/10511/6767 10510/10510/6766 10887/10887/7032 +f 10511/10511/6767 10887/10887/7032 10885/10885/7033 +f 10885/10885/7033 10887/10887/7032 10888/10888/6409 +f 10885/10885/7033 10888/10888/6409 10889/10889/6407 +f 10886/10886/7034 10885/10885/7033 10889/10889/6407 +f 10886/10886/7034 10889/10889/6407 10131/10131/6401 +f 10566/10566/6802 10890/10890/6801 10891/10891/7035 +f 10566/10566/6802 10891/10891/7035 10892/10892/6805 +f 10890/10890/6801 10512/10512/6768 10886/10886/7034 +f 10890/10890/6801 10886/10886/7034 10891/10891/7035 +f 10891/10891/7035 10886/10886/7034 10131/10131/6401 +f 10891/10891/7035 10131/10131/6401 10128/10128/6398 +f 10892/10892/6805 10891/10891/7035 10128/10128/6398 +f 10892/10892/6805 10128/10128/6398 10127/10127/6397 +f 10893/10893/7036 10894/10894/7037 10895/10895/7038 +f 10893/10893/7036 10895/10895/7038 10896/10896/7039 +f 10894/10894/7037 10897/10897/7040 10898/10898/7041 +f 10894/10894/7037 10898/10898/7041 10895/10895/7038 +f 10895/10895/7038 10898/10898/7041 10414/10414/6682 +f 10895/10895/7038 10414/10414/6682 10822/10822/6986 +f 10896/10896/7039 10895/10895/7038 10822/10822/6986 +f 10896/10896/7039 10822/10822/6986 10365/10365/6633 +f 10899/10899/7042 10900/10900/7043 10901/10901/7044 +f 10899/10899/7042 10901/10901/7044 10902/10902/7045 +f 10900/10900/7043 10903/10903/7046 10904/10904/7047 +f 10900/10900/7043 10904/10904/7047 10901/10901/7044 +f 10901/10901/7044 10904/10904/7047 10258/10258/6526 +f 10901/10901/7044 10258/10258/6526 10703/10703/6900 +f 10902/10902/7045 10901/10901/7044 10703/10703/6900 +f 10902/10902/7045 10703/10703/6900 10702/10702/6460 +f 10905/10905/7048 10906/10906/7049 10907/10907/7050 +f 10905/10905/7048 10907/10907/7050 10908/10908/7051 +f 10906/10906/7049 10909/10909/7052 10910/10910/7053 +f 10906/10906/7049 10910/10910/7053 10907/10907/7050 +f 10907/10907/7050 10910/10910/7053 10187/10187/6456 +f 10907/10907/7050 10187/10187/6456 10675/10675/6886 +f 10908/10908/7051 10907/10907/7050 10675/10675/6886 +f 10908/10908/7051 10675/10675/6886 10674/10674/6695 +f 10648/10648/6834 10647/10647/6871 10911/10911/7054 +f 10648/10648/6834 10911/10911/7054 10912/10912/7055 +f 10647/10647/6871 10646/10646/6870 10913/10913/7056 +f 10647/10647/6871 10913/10913/7056 10911/10911/7054 +f 10911/10911/7054 10913/10913/7056 10914/10914/6850 +f 10911/10911/7054 10914/10914/6850 10915/10915/6848 +f 10912/10912/7055 10911/10911/7054 10915/10915/6848 +f 10912/10912/7055 10915/10915/6848 10122/10122/6392 +f 10916/10916/7057 10917/10917/7058 10918/10918/7059 +f 10916/10916/7057 10918/10918/7059 10919/10919/6391 +f 10917/10917/7058 10920/10920/7060 10921/10921/7061 +f 10917/10917/7058 10921/10921/7061 10918/10918/7059 +f 10918/10918/7059 10921/10921/7061 10468/10468/7062 +f 10918/10918/7059 10468/10468/7062 10922/10922/7063 +f 10919/10919/6391 10918/10918/7059 10922/10922/7063 +f 10919/10919/6391 10922/10922/7063 10513/10513/6388 +f 10920/10920/7060 10923/10923/7064 10924/10924/7065 +f 10920/10920/7060 10924/10924/7065 10921/10921/7061 +f 10923/10923/7064 10925/10925/7066 10926/10926/7067 +f 10923/10923/7064 10926/10926/7067 10924/10924/7065 +f 10924/10924/7065 10926/10926/7067 10927/10927/6691 +f 10924/10924/7065 10927/10927/6691 10928/10928/6737 +f 10921/10921/7061 10924/10924/7065 10928/10928/6737 +f 10921/10921/7061 10928/10928/6737 10468/10468/7062 +f 10925/10925/7066 10929/10929/7068 10930/10930/7069 +f 10925/10925/7066 10930/10930/7069 10926/10926/7067 +f 10929/10929/7068 10905/10905/7048 10908/10908/7051 +f 10929/10929/7068 10908/10908/7051 10930/10930/7069 +f 10930/10930/7069 10908/10908/7051 10674/10674/6695 +f 10930/10930/7069 10674/10674/6695 10931/10931/6692 +f 10926/10926/7067 10930/10930/7069 10931/10931/6692 +f 10926/10926/7067 10931/10931/6692 10927/10927/6691 +f 10932/10932/7070 10933/10933/7071 10934/10934/7072 +f 10932/10932/7070 10934/10934/7072 10935/10935/7041 +f 10933/10933/7071 10936/10936/7073 10937/10937/7074 +f 10933/10933/7071 10937/10937/7074 10934/10934/7072 +f 10934/10934/7072 10937/10937/7074 10938/10938/7075 +f 10934/10934/7072 10938/10938/7075 10939/10939/6683 +f 10935/10935/7041 10934/10934/7072 10939/10939/6683 +f 10935/10935/7041 10939/10939/6683 10940/10940/7076 +f 10941/10941/7077 10942/10942/7078 10943/10943/7079 +f 10941/10941/7077 10943/10943/7079 10944/10944/7080 +f 10942/10942/7078 10893/10893/7036 10896/10896/7039 +f 10942/10942/7078 10896/10896/7039 10943/10943/7079 +f 10943/10943/7079 10896/10896/7039 10365/10365/6633 +f 10943/10943/7079 10365/10365/6633 10363/10363/6631 +f 10944/10944/7080 10943/10943/7079 10363/10363/6631 +f 10944/10944/7080 10363/10363/6631 10323/10323/6591 +f 10945/10945/7081 10946/10946/7082 10947/10947/7083 +f 10945/10945/7081 10947/10947/7083 10948/10948/7084 +f 10946/10946/7082 10941/10941/7077 10944/10944/7080 +f 10946/10946/7082 10944/10944/7080 10947/10947/7083 +f 10947/10947/7083 10944/10944/7080 10323/10323/6591 +f 10947/10947/7083 10323/10323/6591 10321/10321/6589 +f 10948/10948/7084 10947/10947/7083 10321/10321/6589 +f 10948/10948/7084 10321/10321/6589 10305/10305/6573 +f 10949/10949/7085 10950/10950/7086 10951/10951/7087 +f 10949/10949/7085 10951/10951/7087 10952/10952/7088 +f 10950/10950/7086 10945/10945/7081 10948/10948/7084 +f 10950/10950/7086 10948/10948/7084 10951/10951/7087 +f 10951/10951/7087 10948/10948/7084 10305/10305/6573 +f 10951/10951/7087 10305/10305/6573 10303/10303/6571 +f 10952/10952/7088 10951/10951/7087 10303/10303/6571 +f 10952/10952/7088 10303/10303/6571 10262/10262/6530 +f 10903/10903/7046 10953/10953/7089 10954/10954/7090 +f 10903/10903/7046 10954/10954/7090 10904/10904/7047 +f 10953/10953/7089 10949/10949/7085 10952/10952/7088 +f 10953/10953/7089 10952/10952/7088 10954/10954/7090 +f 10954/10954/7090 10952/10952/7088 10262/10262/6530 +f 10954/10954/7090 10262/10262/6530 10259/10259/6527 +f 10904/10904/7047 10954/10954/7090 10259/10259/6527 +f 10904/10904/7047 10259/10259/6527 10258/10258/6526 +f 10909/10909/7052 10955/10955/7091 10956/10956/7092 +f 10909/10909/7052 10956/10956/7092 10910/10910/7053 +f 10955/10955/7091 10957/10957/7093 10958/10958/7094 +f 10955/10955/7091 10958/10958/7094 10956/10956/7092 +f 10956/10956/7092 10958/10958/7094 10191/10191/6460 +f 10956/10956/7092 10191/10191/6460 10188/10188/6457 +f 10910/10910/7053 10956/10956/7092 10188/10188/6457 +f 10910/10910/7053 10188/10188/6457 10187/10187/6456 +f 10603/10603/6774 10602/10602/6835 10959/10959/7095 +f 10603/10603/6774 10959/10959/7095 10960/10960/6772 +f 10602/10602/6835 10601/10601/6834 10961/10961/7055 +f 10602/10602/6835 10961/10961/7055 10959/10959/7095 +f 10959/10959/7095 10961/10961/7055 10618/10618/6392 +f 10959/10959/7095 10618/10618/6392 10962/10962/7096 +f 10960/10960/6772 10959/10959/7095 10962/10962/7096 +f 10960/10960/6772 10962/10962/7096 10118/10118/7097 +f 10963/10963/5675 10964/10964/7098 10965/10965/7099 +f 10963/10963/5675 10965/10965/7099 10966/10966/7100 +f 10964/10964/7098 10967/10967/6356 10968/10968/7101 +f 10964/10964/7098 10968/10968/7101 10965/10965/7099 +f 10965/10965/7099 10968/10968/7101 10969/10969/7102 +f 10965/10965/7099 10969/10969/7102 10970/10970/7103 +f 10966/10966/7100 10965/10965/7099 10970/10970/7103 +f 10966/10966/7100 10970/10970/7103 10971/10971/7104 +f 10972/10972/6311 10973/10973/6313 10974/10974/7105 +f 10972/10972/6311 10974/10974/7105 10975/10975/7106 +f 10973/10973/6313 10976/10976/6314 10977/10977/7107 +f 10973/10973/6313 10977/10977/7107 10974/10974/7105 +f 10974/10974/7105 10977/10977/7107 10978/10978/7108 +f 10974/10974/7105 10978/10978/7108 10979/10979/7109 +f 10975/10975/7106 10974/10974/7105 10979/10979/7109 +f 10975/10975/7106 10979/10979/7109 10980/10980/7110 +f 10981/10981/5677 10982/10982/5676 10983/10983/7111 +f 10981/10981/5677 10983/10983/7111 10984/10984/7112 +f 10982/10982/5676 10963/10963/5675 10966/10966/7100 +f 10982/10982/5676 10966/10966/7100 10983/10983/7111 +f 10983/10983/7111 10966/10966/7100 10971/10971/7104 +f 10983/10983/7111 10971/10971/7104 10985/10985/7113 +f 10984/10984/7112 10983/10983/7111 10985/10985/7113 +f 10984/10984/7112 10985/10985/7113 10986/10986/7114 +f 10987/10987/7115 10988/10988/7116 10989/10989/7117 +f 10987/10987/7115 10989/10989/7117 10990/10990/7118 +f 10988/10988/7116 10991/10991/5686 10992/10992/7119 +f 10988/10988/7116 10992/10992/7119 10989/10989/7117 +f 10989/10989/7117 10992/10992/7119 10993/10993/7120 +f 10989/10989/7117 10993/10993/7120 10994/10994/7121 +f 10990/10990/7118 10989/10989/7117 10994/10994/7121 +f 10990/10990/7118 10994/10994/7121 10995/10995/7122 +f 10967/10967/6356 10996/10996/6358 10997/10997/7123 +f 10967/10967/6356 10997/10997/7123 10968/10968/7101 +f 10996/10996/6358 10998/10998/7124 10999/10999/7125 +f 10996/10996/6358 10999/10999/7125 10997/10997/7123 +f 10997/10997/7123 10999/10999/7125 11000/11000/7126 +f 10997/10997/7123 11000/11000/7126 11001/11001/7127 +f 10968/10968/7101 10997/10997/7123 11001/11001/7127 +f 10968/10968/7101 11001/11001/7127 10969/10969/7102 +f 11002/11002/5699 11003/11003/7128 11004/11004/7129 +f 11002/11002/5699 11004/11004/7129 11005/11005/7130 +f 11003/11003/7128 10987/10987/7115 10990/10990/7118 +f 11003/11003/7128 10990/10990/7118 11004/11004/7129 +f 11004/11004/7129 10990/10990/7118 10995/10995/7122 +f 11004/11004/7129 10995/10995/7122 11006/11006/7131 +f 11005/11005/7130 11004/11004/7129 11006/11006/7131 +f 11005/11005/7130 11006/11006/7131 11007/11007/7132 +f 10998/10998/7124 11008/11008/6363 11009/11009/7133 +f 10998/10998/7124 11009/11009/7133 10999/10999/7125 +f 11008/11008/6363 11010/11010/7134 11011/11011/7135 +f 11008/11008/6363 11011/11011/7135 11009/11009/7133 +f 11009/11009/7133 11011/11011/7135 11012/11012/7136 +f 11009/11009/7133 11012/11012/7136 11013/11013/7137 +f 10999/10999/7125 11009/11009/7133 11013/11013/7137 +f 10999/10999/7125 11013/11013/7137 11000/11000/7126 +f 11014/11014/7138 11015/11015/7139 11016/11016/7140 +f 11014/11014/7138 11016/11016/7140 11017/11017/7141 +f 11015/11015/7139 11018/11018/7142 11019/11019/7143 +f 11015/11015/7139 11019/11019/7143 11016/11016/7140 +f 11016/11016/7140 11019/11019/7143 11020/11020/6668 +f 11016/11016/7140 11020/11020/6668 11021/11021/6999 +f 11017/11017/7141 11016/11016/7140 11021/11021/6999 +f 11017/11017/7141 11021/11021/6999 11022/11022/7144 +f 11023/11023/5931 11024/11024/7145 11025/11025/7146 +f 11023/11023/5931 11025/11025/7146 11026/11026/7147 +f 11024/11024/7145 11027/11027/5956 11028/11028/7148 +f 11024/11024/7145 11028/11028/7148 11025/11025/7146 +f 11025/11025/7146 11028/11028/7148 11029/11029/7149 +f 11025/11025/7146 11029/11029/7149 11030/11030/7150 +f 11026/11026/7147 11025/11025/7146 11030/11030/7150 +f 11026/11026/7147 11030/11030/7150 11031/11031/7151 +f 11032/11032/7152 11033/11033/7153 11034/11034/7154 +f 11032/11032/7152 11034/11034/7154 11035/11035/7155 +f 11033/11033/7153 11036/11036/7156 11037/11037/7157 +f 11033/11033/7153 11037/11037/7157 11034/11034/7154 +f 11034/11034/7154 11037/11037/7157 11038/11038/7158 +f 11034/11034/7154 11038/11038/7158 11039/11039/7078 +f 11035/11035/7155 11034/11034/7154 11039/11039/7078 +f 11035/11035/7155 11039/11039/7078 11040/11040/7077 +f 11041/11041/7159 11042/11042/7160 11043/11043/7161 +f 11041/11041/7159 11043/11043/7161 11044/11044/7162 +f 11042/11042/7160 11045/11045/7163 11046/11046/7164 +f 11042/11042/7160 11046/11046/7164 11043/11043/7161 +f 11043/11043/7161 11046/11046/7164 11047/11047/6673 +f 11043/11043/7161 11047/11047/6673 11048/11048/6672 +f 11044/11044/7162 11043/11043/7161 11048/11048/6672 +f 11044/11044/7162 11048/11048/6672 11049/11049/6648 +f 11050/11050/7165 11051/11051/7166 11052/11052/7167 +f 11050/11050/7165 11052/11052/7167 11053/11053/7168 +f 11051/11051/7166 11054/11054/7169 11055/11055/7170 +f 11051/11051/7166 11055/11055/7170 11052/11052/7167 +f 11052/11052/7167 11055/11055/7170 11056/11056/7171 +f 11052/11052/7167 11056/11056/7171 11057/11057/7172 +f 11053/11053/7168 11052/11052/7167 11057/11057/7172 +f 11053/11053/7168 11057/11057/7172 11058/11058/7173 +f 11059/11059/6379 11060/11060/7174 11061/11061/7175 +f 11059/11059/6379 11061/11061/7175 11062/11062/7176 +f 11060/11060/7174 11050/11050/7165 11053/11053/7168 +f 11060/11060/7174 11053/11053/7168 11061/11061/7175 +f 11061/11061/7175 11053/11053/7168 11058/11058/7173 +f 11061/11061/7175 11058/11058/7173 11063/11063/7177 +f 11062/11062/7176 11061/11061/7175 11063/11063/7177 +f 11062/11062/7176 11063/11063/7177 11064/11064/7178 +f 11065/11065/7179 11066/11066/7180 11067/11067/7181 +f 11065/11065/7179 11067/11067/7181 11068/11068/7182 +f 11066/11066/7180 11069/11069/7183 11070/11070/7184 +f 11066/11066/7180 11070/11070/7184 11067/11067/7181 +f 11067/11067/7181 11070/11070/7184 11071/11071/7185 +f 11067/11067/7181 11071/11071/7185 11072/11072/7186 +f 11068/11068/7182 11067/11067/7181 11072/11072/7186 +f 11068/11068/7182 11072/11072/7186 11073/11073/6510 +f 11074/11074/7187 11075/11075/5789 11076/11076/7188 +f 11074/11074/7187 11076/11076/7188 11077/11077/7189 +f 11075/11075/5789 11078/11078/5788 11079/11079/7190 +f 11075/11075/5789 11079/11079/7190 11076/11076/7188 +f 11076/11076/7188 11079/11079/7190 11080/11080/7191 +f 11076/11076/7188 11080/11080/7191 11081/11081/7192 +f 11077/11077/7189 11076/11076/7188 11081/11081/7192 +f 11077/11077/7189 11081/11081/7192 11082/11082/7193 +f 11083/11083/7194 11084/11084/7195 11085/11085/7196 +f 11083/11083/7194 11085/11085/7196 11086/11086/7197 +f 11084/11084/7195 11087/11087/7198 11088/11088/7199 +f 11084/11084/7195 11088/11088/7199 11085/11085/7196 +f 11085/11085/7196 11088/11088/7199 11089/11089/7073 +f 11085/11085/7196 11089/11089/7073 11090/11090/7071 +f 11086/11086/7197 11085/11085/7196 11090/11090/7071 +f 11086/11086/7197 11090/11090/7071 11091/11091/7070 +f 11010/11010/7134 11092/11092/7200 11093/11093/7201 +f 11010/11010/7134 11093/11093/7201 11011/11011/7135 +f 11092/11092/7200 11094/11094/7202 11095/11095/7203 +f 11092/11092/7200 11095/11095/7203 11093/11093/7201 +f 11093/11093/7201 11095/11095/7203 11096/11096/7204 +f 11093/11093/7201 11096/11096/7204 11097/11097/7205 +f 11011/11011/7135 11093/11093/7201 11097/11097/7205 +f 11011/11011/7135 11097/11097/7205 11012/11012/7136 +f 11098/11098/7206 11099/11099/7207 11100/11100/7208 +f 11098/11098/7206 11100/11100/7208 11101/11101/7209 +f 11099/11099/7207 11102/11102/7210 11103/11103/7211 +f 11099/11099/7207 11103/11103/7211 11100/11100/7208 +f 11100/11100/7208 11103/11103/7211 11104/11104/7212 +f 11100/11100/7208 11104/11104/7212 11105/11105/7213 +f 11101/11101/7209 11100/11100/7208 11105/11105/7213 +f 11101/11101/7209 11105/11105/7213 11106/11106/7214 +f 11107/11107/7215 11108/11108/5843 11109/11109/7216 +f 11107/11107/7215 11109/11109/7216 11110/11110/7217 +f 11108/11108/5843 11074/11074/7187 11077/11077/7189 +f 11108/11108/5843 11077/11077/7189 11109/11109/7216 +f 11109/11109/7216 11077/11077/7189 11082/11082/7193 +f 11109/11109/7216 11082/11082/7193 11111/11111/7218 +f 11110/11110/7217 11109/11109/7216 11111/11111/7218 +f 11110/11110/7217 11111/11111/7218 11112/11112/7219 +f 11113/11113/7220 11114/11114/5867 11115/11115/7221 +f 11113/11113/7220 11115/11115/7221 11116/11116/7222 +f 11114/11114/5867 11107/11107/7215 11110/11110/7217 +f 11114/11114/5867 11110/11110/7217 11115/11115/7221 +f 11115/11115/7221 11110/11110/7217 11112/11112/7219 +f 11115/11115/7221 11112/11112/7219 11117/11117/7223 +f 11116/11116/7222 11115/11115/7221 11117/11117/7223 +f 11116/11116/7222 11117/11117/7223 11118/11118/7224 +f 11119/11119/7225 11120/11120/7226 11121/11121/7227 +f 11119/11119/7225 11121/11121/7227 11122/11122/7228 +f 11120/11120/7226 11123/11123/7229 11124/11124/7230 +f 11120/11120/7226 11124/11124/7230 11121/11121/7227 +f 11121/11121/7227 11124/11124/7230 11125/11125/6563 +f 11121/11121/7227 11125/11125/6563 11126/11126/6588 +f 11122/11122/7228 11121/11121/7227 11126/11126/6588 +f 11122/11122/7228 11126/11126/6588 11127/11127/6587 +f 11128/11128/5962 11129/11129/6263 11130/11130/7231 +f 11128/11128/5962 11130/11130/7231 11131/11131/7232 +f 11129/11129/6263 11132/11132/5941 11133/11133/7233 +f 11129/11129/6263 11133/11133/7233 11130/11130/7231 +f 11130/11130/7231 11133/11133/7233 11134/11134/7234 +f 11130/11130/7231 11134/11134/7234 11135/11135/7235 +f 11131/11131/7232 11130/11130/7231 11135/11135/7235 +f 11131/11131/7232 11135/11135/7235 11136/11136/7236 +f 11137/11137/7237 11138/11138/7238 11139/11139/7239 +f 11137/11137/7237 11139/11139/7239 11140/11140/7240 +f 11138/11138/7238 11141/11141/7241 11142/11142/7242 +f 11138/11138/7238 11142/11142/7242 11139/11139/7239 +f 11139/11139/7239 11142/11142/7242 11143/11143/6657 +f 11139/11139/7239 11143/11143/6657 11144/11144/7243 +f 11140/11140/7240 11139/11139/7239 11144/11144/7243 +f 11140/11140/7240 11144/11144/7243 11145/11145/7244 +f 11146/11146/6330 11147/11147/7245 11148/11148/7246 +f 11146/11146/6330 11148/11148/7246 11149/11149/7247 +f 11147/11147/7245 11150/11150/7248 11151/11151/7249 +f 11147/11147/7245 11151/11151/7249 11148/11148/7246 +f 11148/11148/7246 11151/11151/7249 11152/11152/7250 +f 11148/11148/7246 11152/11152/7250 11153/11153/7251 +f 11149/11149/7247 11148/11148/7246 11153/11153/7251 +f 11149/11149/7247 11153/11153/7251 11154/11154/7252 +f 11045/11045/7163 11155/11155/7253 11156/11156/7254 +f 11045/11045/7163 11156/11156/7254 11046/11046/7164 +f 11155/11155/7253 11157/11157/7255 11158/11158/7256 +f 11155/11155/7253 11158/11158/7256 11156/11156/7254 +f 11156/11156/7254 11158/11158/7256 11159/11159/7257 +f 11156/11156/7254 11159/11159/7257 11160/11160/6678 +f 11046/11046/7164 11156/11156/7254 11160/11160/6678 +f 11046/11046/7164 11160/11160/6678 11047/11047/6673 +f 11161/11161/5717 11162/11162/7258 11163/11163/7259 +f 11161/11161/5717 11163/11163/7259 11164/11164/7260 +f 11162/11162/7258 11023/11023/5931 11026/11026/7147 +f 11162/11162/7258 11026/11026/7147 11163/11163/7259 +f 11163/11163/7259 11026/11026/7147 11031/11031/7151 +f 11163/11163/7259 11031/11031/7151 11165/11165/7261 +f 11164/11164/7260 11163/11163/7259 11165/11165/7261 +f 11164/11164/7260 11165/11165/7261 11166/11166/7262 +f 11167/11167/7263 11168/11168/7264 11169/11169/7265 +f 11167/11167/7263 11169/11169/7265 11170/11170/7107 +f 11168/11168/7264 11171/11171/6310 11172/11172/7266 +f 11168/11168/7264 11172/11172/7266 11169/11169/7265 +f 11169/11169/7265 11172/11172/7266 11173/11173/7267 +f 11169/11169/7265 11173/11173/7267 11174/11174/7268 +f 11170/11170/7107 11169/11169/7265 11174/11174/7268 +f 11170/11170/7107 11174/11174/7268 11175/11175/7269 +f 11176/11176/6310 11177/11177/7270 11178/11178/7271 +f 11176/11176/6310 11178/11178/7271 11179/11179/7272 +f 11177/11177/7270 11180/11180/6153 11181/11181/7273 +f 11177/11177/7270 11181/11181/7273 11178/11178/7271 +f 11178/11178/7271 11181/11181/7273 11182/11182/7274 +f 11178/11178/7271 11182/11182/7274 11183/11183/7275 +f 11179/11179/7272 11178/11178/7271 11183/11183/7275 +f 11179/11179/7272 11183/11183/7275 11184/11184/7267 +f 11185/11185/7276 11186/11186/7277 11187/11187/7278 +f 11185/11185/7276 11187/11187/7278 11188/11188/7279 +f 11186/11186/7277 11189/11189/7280 11190/11190/7281 +f 11186/11186/7277 11190/11190/7281 11187/11187/7278 +f 11187/11187/7278 11190/11190/7281 11191/11191/6846 +f 11187/11187/7278 11191/11191/6846 11192/11192/6845 +f 11188/11188/7279 11187/11187/7278 11192/11192/6845 +f 11188/11188/7279 11192/11192/6845 11193/11193/7282 +f 11194/11194/7283 11195/11195/7284 11196/11196/7285 +f 11194/11194/7283 11196/11196/7285 11197/11197/7286 +f 11195/11195/7284 11185/11185/7276 11188/11188/7279 +f 11195/11195/7284 11188/11188/7279 11196/11196/7285 +f 11196/11196/7285 11188/11188/7279 11193/11193/7282 +f 11196/11196/7285 11193/11193/7282 11198/11198/6865 +f 11197/11197/7286 11196/11196/7285 11198/11198/6865 +f 11197/11197/7286 11198/11198/6865 11199/11199/6840 +f 11200/11200/6131 11201/11201/6221 11202/11202/7287 +f 11200/11200/6131 11202/11202/7287 11203/11203/7288 +f 11201/11201/6221 11204/11204/6162 11205/11205/7289 +f 11201/11201/6221 11205/11205/7289 11202/11202/7287 +f 11202/11202/7287 11205/11205/7289 11206/11206/7290 +f 11202/11202/7287 11206/11206/7290 11207/11207/7291 +f 11203/11203/7288 11202/11202/7287 11207/11207/7291 +f 11203/11203/7288 11207/11207/7291 11208/11208/7292 +f 11209/11209/6125 11210/11210/6156 11211/11211/7293 +f 11209/11209/6125 11211/11211/7293 11212/11212/7294 +f 11210/11210/6156 11213/11213/6133 11214/11214/7295 +f 11210/11210/6156 11214/11214/7295 11211/11211/7293 +f 11211/11211/7293 11214/11214/7295 11215/11215/7296 +f 11211/11211/7293 11215/11215/7296 11216/11216/7297 +f 11212/11212/7294 11211/11211/7293 11216/11216/7297 +f 11212/11212/7294 11216/11216/7297 11217/11217/7298 +f 11218/11218/6127 11219/11219/6126 11220/11220/7299 +f 11218/11218/6127 11220/11220/7299 11221/11221/7300 +f 11219/11219/6126 11209/11209/6125 11212/11212/7294 +f 11219/11219/6126 11212/11212/7294 11220/11220/7299 +f 11220/11220/7299 11212/11212/7294 11217/11217/7298 +f 11220/11220/7299 11217/11217/7298 11222/11222/7301 +f 11221/11221/7300 11220/11220/7299 11222/11222/7301 +f 11221/11221/7300 11222/11222/7301 11223/11223/7302 +f 10991/10991/5686 11224/11224/5685 11225/11225/7303 +f 10991/10991/5686 11225/11225/7303 10992/10992/7119 +f 11224/11224/5685 10972/10972/6311 10975/10975/7106 +f 11224/11224/5685 10975/10975/7106 11225/11225/7303 +f 11225/11225/7303 10975/10975/7106 10980/10980/7110 +f 11225/11225/7303 10980/10980/7110 11226/11226/7304 +f 10992/10992/7119 11225/11225/7303 11226/11226/7304 +f 10992/10992/7119 11226/11226/7304 10993/10993/7120 +f 11227/11227/7305 11228/11228/6138 11229/11229/7306 +f 11227/11227/7305 11229/11229/7306 11230/11230/7307 +f 11228/11228/6138 11231/11231/7308 11232/11232/7112 +f 11228/11228/6138 11232/11232/7112 11229/11229/7306 +f 11229/11229/7306 11232/11232/7112 11233/11233/7309 +f 11229/11229/7306 11233/11233/7309 11234/11234/7310 +f 11230/11230/7307 11229/11229/7306 11234/11234/7310 +f 11230/11230/7307 11234/11234/7310 11235/11235/7311 +f 11236/11236/7312 11237/11237/6339 11238/11238/7313 +f 11236/11236/7312 11238/11238/7313 11239/11239/7314 +f 11237/11237/6339 11240/11240/7315 11241/11241/7316 +f 11237/11237/6339 11241/11241/7316 11238/11238/7313 +f 11238/11238/7313 11241/11241/7316 11242/11242/7317 +f 11238/11238/7313 11242/11242/7317 11243/11243/7318 +f 11239/11239/7314 11238/11238/7313 11243/11243/7318 +f 11239/11239/7314 11243/11243/7318 11244/11244/7319 +f 11245/11245/7320 11246/11246/6173 11247/11247/7321 +f 11245/11245/7320 11247/11247/7321 11248/11248/7322 +f 11246/11246/6173 11002/11002/5699 11005/11005/7130 +f 11246/11246/6173 11005/11005/7130 11247/11247/7321 +f 11247/11247/7321 11005/11005/7130 11007/11007/7132 +f 11247/11247/7321 11007/11007/7132 11249/11249/7323 +f 11248/11248/7322 11247/11247/7321 11249/11249/7323 +f 11248/11248/7322 11249/11249/7323 11250/11250/7324 +f 11240/11240/7315 11251/11251/6384 11252/11252/7325 +f 11240/11240/7315 11252/11252/7325 11241/11241/7316 +f 11251/11251/6384 11059/11059/6379 11062/11062/7176 +f 11251/11251/6384 11062/11062/7176 11252/11252/7325 +f 11252/11252/7325 11062/11062/7176 11064/11064/7178 +f 11252/11252/7325 11064/11064/7178 11253/11253/7326 +f 11241/11241/7316 11252/11252/7325 11253/11253/7326 +f 11241/11241/7316 11253/11253/7326 11242/11242/7317 +f 11254/11254/7327 11255/11255/5761 11256/11256/7328 +f 11254/11254/7327 11256/11256/7328 11257/11257/7329 +f 11255/11255/5761 11245/11245/7320 11248/11248/7322 +f 11255/11255/5761 11248/11248/7322 11256/11256/7328 +f 11256/11256/7328 11248/11248/7322 11250/11250/7324 +f 11256/11256/7328 11250/11250/7324 11258/11258/7330 +f 11257/11257/7329 11256/11256/7328 11258/11258/7330 +f 11257/11257/7329 11258/11258/7330 11259/11259/7331 +f 11260/11260/5719 11261/11261/5718 11262/11262/7332 +f 11260/11260/5719 11262/11262/7332 11263/11263/7333 +f 11261/11261/5718 11161/11161/5717 11164/11164/7260 +f 11261/11261/5718 11164/11164/7260 11262/11262/7332 +f 11262/11262/7332 11164/11164/7260 11166/11166/7262 +f 11262/11262/7332 11166/11166/7262 11264/11264/7334 +f 11263/11263/7333 11262/11262/7332 11264/11264/7334 +f 11263/11263/7333 11264/11264/7334 11265/11265/7335 +f 11266/11266/6160 11267/11267/6351 11268/11268/7336 +f 11266/11266/6160 11268/11268/7336 11269/11269/7337 +f 11267/11267/6351 11270/11270/6350 11271/11271/7338 +f 11267/11267/6351 11271/11271/7338 11268/11268/7336 +f 11268/11268/7336 11271/11271/7338 11272/11272/7339 +f 11268/11268/7336 11272/11272/7339 11273/11273/7340 +f 11269/11269/7337 11268/11268/7336 11273/11273/7340 +f 11269/11269/7337 11273/11273/7340 11274/11274/7341 +f 11275/11275/7342 11276/11276/6324 11277/11277/7343 +f 11275/11275/7342 11277/11277/7343 11278/11278/7344 +f 11276/11276/6324 11279/11279/7345 11280/11280/7346 +f 11276/11276/6324 11280/11280/7346 11277/11277/7343 +f 11277/11277/7343 11280/11280/7346 11281/11281/7347 +f 11277/11277/7343 11281/11281/7347 11282/11282/7348 +f 11278/11278/7344 11277/11277/7343 11282/11282/7348 +f 11278/11278/7344 11282/11282/7348 11283/11283/7349 +f 11284/11284/6146 11285/11285/6145 11286/11286/7350 +f 11284/11284/6146 11286/11286/7350 11287/11287/7351 +f 11285/11285/6145 11218/11218/6127 11221/11221/7300 +f 11285/11285/6145 11221/11221/7300 11286/11286/7350 +f 11286/11286/7350 11221/11221/7300 11223/11223/7302 +f 11286/11286/7350 11223/11223/7302 11288/11288/7352 +f 11287/11287/7351 11286/11286/7350 11288/11288/7352 +f 11287/11287/7351 11288/11288/7352 11289/11289/7353 +f 11290/11290/7354 11291/11291/6369 11292/11292/7355 +f 11290/11290/7354 11292/11292/7355 11293/11293/7356 +f 11291/11291/6369 11294/11294/7357 11295/11295/7358 +f 11291/11291/6369 11295/11295/7358 11292/11292/7355 +f 11292/11292/7355 11295/11295/7358 11296/11296/7359 +f 11292/11292/7355 11296/11296/7359 11297/11297/7360 +f 11293/11293/7356 11292/11292/7355 11297/11297/7360 +f 11293/11293/7356 11297/11297/7360 11298/11298/7361 +f 11299/11299/7362 11300/11300/5948 11301/11301/7363 +f 11299/11299/7362 11301/11301/7363 11302/11302/7364 +f 11300/11300/5948 11113/11113/7220 11116/11116/7222 +f 11300/11300/5948 11116/11116/7222 11301/11301/7363 +f 11301/11301/7363 11116/11116/7222 11118/11118/7224 +f 11301/11301/7363 11118/11118/7224 11303/11303/7365 +f 11302/11302/7364 11301/11301/7363 11303/11303/7365 +f 11302/11302/7364 11303/11303/7365 11304/11304/7366 +f 11305/11305/5708 11306/11306/5707 11307/11307/7367 +f 11305/11305/5708 11307/11307/7367 11308/11308/7368 +f 11306/11306/5707 11309/11309/5706 11310/11310/7369 +f 11306/11306/5707 11310/11310/7369 11307/11307/7367 +f 11307/11307/7367 11310/11310/7369 11311/11311/7370 +f 11307/11307/7367 11311/11311/7370 11312/11312/7371 +f 11308/11308/7368 11307/11307/7367 11312/11312/7371 +f 11308/11308/7368 11312/11312/7371 11313/11313/7372 +f 11314/11314/6151 11315/11315/6253 11316/11316/7373 +f 11314/11314/6151 11316/11316/7373 11317/11317/7374 +f 11315/11315/6253 11284/11284/6146 11287/11287/7351 +f 11315/11315/6253 11287/11287/7351 11316/11316/7373 +f 11316/11316/7373 11287/11287/7351 11289/11289/7353 +f 11316/11316/7373 11289/11289/7353 11318/11318/7375 +f 11317/11317/7374 11316/11316/7373 11318/11318/7375 +f 11317/11317/7374 11318/11318/7375 11319/11319/7376 +f 11320/11320/5970 11321/11321/7377 11322/11322/7378 +f 11320/11320/5970 11322/11322/7378 11323/11323/7379 +f 11321/11321/7377 11260/11260/5719 11263/11263/7333 +f 11321/11321/7377 11263/11263/7333 11322/11322/7378 +f 11322/11322/7378 11263/11263/7333 11265/11265/7335 +f 11322/11322/7378 11265/11265/7335 11324/11324/7380 +f 11323/11323/7379 11322/11322/7378 11324/11324/7380 +f 11323/11323/7379 11324/11324/7380 11325/11325/7381 +f 11270/11270/6350 11326/11326/6140 11327/11327/7382 +f 11270/11270/6350 11327/11327/7382 11328/11328/7338 +f 11326/11326/6140 11329/11329/7305 11330/11330/7307 +f 11326/11326/6140 11330/11330/7307 11327/11327/7382 +f 11327/11327/7382 11330/11330/7307 11331/11331/7311 +f 11327/11327/7382 11331/11331/7311 11332/11332/7383 +f 11328/11328/7338 11327/11327/7382 11332/11332/7383 +f 11328/11328/7338 11332/11332/7383 11333/11333/7339 +f 11334/11334/7384 11335/11335/7385 11336/11336/7386 +f 11334/11334/7384 11336/11336/7386 11337/11337/7387 +f 11335/11335/7385 11338/11338/7388 11339/11339/7389 +f 11335/11335/7385 11339/11339/7389 11336/11336/7386 +f 11336/11336/7386 11339/11339/7389 11340/11340/6870 +f 11336/11336/7386 11340/11340/6870 11341/11341/6869 +f 11337/11337/7387 11336/11336/7386 11341/11341/6869 +f 11337/11337/7387 11341/11341/6869 11342/11342/6868 +f 11343/11343/7390 11344/11344/7391 11345/11345/7392 +f 11343/11343/7390 11345/11345/7392 11346/11346/7393 +f 11344/11344/7391 11347/11347/7394 11348/11348/7395 +f 11344/11344/7391 11348/11348/7395 11345/11345/7392 +f 11345/11345/7392 11348/11348/7395 11349/11349/7396 +f 11345/11345/7392 11349/11349/7396 11350/11350/7397 +f 11346/11346/7393 11345/11345/7392 11350/11350/7397 +f 11346/11346/7393 11350/11350/7397 11351/11351/7398 +f 11352/11352/7399 11353/11353/7400 11354/11354/7401 +f 11352/11352/7399 11354/11354/7401 11355/11355/7402 +f 11353/11353/7400 11356/11356/7403 11357/11357/7404 +f 11353/11353/7400 11357/11357/7404 11354/11354/7401 +f 11354/11354/7401 11357/11357/7404 11358/11358/6856 +f 11354/11354/7401 11358/11358/6856 11359/11359/6956 +f 11355/11355/7402 11354/11354/7401 11359/11359/6956 +f 11355/11355/7402 11359/11359/6956 11360/11360/6862 +f 11361/11361/7405 11362/11362/7406 11363/11363/7407 +f 11361/11361/7405 11363/11363/7407 11364/11364/7408 +f 11362/11362/7406 11365/11365/7409 11366/11366/7141 +f 11362/11362/7406 11366/11366/7141 11363/11363/7407 +f 11363/11363/7407 11366/11366/7141 11022/11022/7144 +f 11363/11363/7407 11022/11022/7144 11367/11367/7410 +f 11364/11364/7408 11363/11363/7407 11367/11367/7410 +f 11364/11364/7408 11367/11367/7410 11368/11368/7411 +f 11369/11369/7142 11370/11370/7412 11371/11371/7413 +f 11369/11369/7142 11371/11371/7413 11372/11372/7414 +f 11370/11370/7412 11119/11119/7225 11122/11122/7228 +f 11370/11370/7412 11122/11122/7228 11371/11371/7413 +f 11371/11371/7413 11122/11122/7228 11127/11127/6587 +f 11371/11371/7413 11127/11127/6587 11373/11373/6669 +f 11372/11372/7414 11371/11371/7413 11373/11373/6669 +f 11372/11372/7414 11373/11373/6669 11374/11374/6668 +f 11087/11087/7198 11375/11375/7415 11376/11376/7416 +f 11087/11087/7198 11376/11376/7416 11088/11088/7199 +f 11375/11375/7415 11377/11377/7417 11378/11378/7418 +f 11375/11375/7415 11378/11378/7418 11376/11376/7416 +f 11376/11376/7416 11378/11378/7418 11379/11379/6686 +f 11376/11376/7416 11379/11379/6686 11380/11380/7074 +f 11088/11088/7199 11376/11376/7416 11380/11380/7074 +f 11088/11088/7199 11380/11380/7074 11089/11089/7073 +f 11381/11381/7419 11382/11382/7420 11383/11383/7421 +f 11381/11381/7419 11383/11383/7421 11384/11384/7422 +f 11382/11382/7420 11352/11352/7399 11355/11355/7402 +f 11382/11382/7420 11355/11355/7402 11383/11383/7421 +f 11383/11383/7421 11355/11355/7402 11360/11360/6862 +f 11383/11383/7421 11360/11360/6862 11385/11385/6861 +f 11384/11384/7422 11383/11383/7421 11385/11385/6861 +f 11384/11384/7422 11385/11385/6861 11386/11386/7423 +f 11141/11141/7241 11387/11387/7424 11388/11388/7425 +f 11141/11141/7241 11388/11388/7425 11142/11142/7242 +f 11387/11387/7424 11389/11389/7426 11390/11390/7427 +f 11387/11387/7424 11390/11390/7427 11388/11388/7425 +f 11388/11388/7425 11390/11390/7427 11391/11391/7428 +f 11388/11388/7425 11391/11391/7428 11392/11392/7429 +f 11142/11142/7242 11388/11388/7425 11392/11392/7429 +f 11142/11142/7242 11392/11392/7429 11143/11143/6657 +f 11338/11338/7388 11393/11393/7430 11394/11394/7431 +f 11338/11338/7388 11394/11394/7431 11339/11339/7389 +f 11393/11393/7430 11395/11395/7432 11396/11396/7433 +f 11393/11393/7430 11396/11396/7433 11394/11394/7431 +f 11394/11394/7431 11396/11396/7433 11397/11397/6850 +f 11394/11394/7431 11397/11397/6850 11398/11398/7434 +f 11339/11339/7389 11394/11394/7431 11398/11398/7434 +f 11339/11339/7389 11398/11398/7434 11340/11340/6870 +f 11399/11399/7435 11400/11400/7436 11401/11401/7437 +f 11399/11399/7435 11401/11401/7437 11402/11402/7418 +f 11400/11400/7436 11343/11343/7390 11346/11346/7393 +f 11400/11400/7436 11346/11346/7393 11401/11401/7437 +f 11401/11401/7437 11346/11346/7393 11351/11351/7398 +f 11401/11401/7437 11351/11351/7398 11403/11403/7438 +f 11402/11402/7418 11401/11401/7437 11403/11403/7438 +f 11402/11402/7418 11403/11403/7438 11404/11404/6686 +f 11405/11405/7439 11406/11406/7440 11407/11407/7441 +f 11405/11405/7439 11407/11407/7441 11070/11070/7184 +f 11406/11406/7440 11408/11408/7442 11409/11409/7443 +f 11406/11406/7440 11409/11409/7443 11407/11407/7441 +f 11407/11407/7441 11409/11409/7443 11410/11410/6482 +f 11407/11407/7441 11410/11410/6482 11411/11411/6481 +f 11070/11070/7184 11407/11407/7441 11411/11411/6481 +f 11070/11070/7184 11411/11411/6481 11071/11071/7185 +f 11412/11412/7444 11413/11413/7445 11414/11414/7446 +f 11412/11412/7444 11414/11414/7446 11415/11415/7447 +f 11413/11413/7445 11416/11416/7448 11417/11417/7449 +f 11413/11413/7445 11417/11417/7449 11414/11414/7446 +f 11414/11414/7446 11417/11417/7449 11418/11418/7042 +f 11414/11414/7446 11418/11418/7042 11419/11419/7450 +f 11415/11415/7447 11414/11414/7446 11419/11419/7450 +f 11415/11415/7447 11419/11419/7450 11420/11420/7451 +f 11421/11421/7452 11422/11422/7453 11423/11423/7454 +f 11421/11421/7452 11423/11423/7454 11424/11424/7455 +f 11422/11422/7453 11412/11412/7444 11415/11415/7447 +f 11422/11422/7453 11415/11415/7447 11423/11423/7454 +f 11423/11423/7454 11415/11415/7447 11420/11420/7451 +f 11423/11423/7454 11420/11420/7451 11425/11425/7049 +f 11424/11424/7455 11423/11423/7454 11425/11425/7049 +f 11424/11424/7455 11425/11425/7049 11426/11426/7456 +f 11416/11416/7448 11427/11427/7457 11428/11428/7458 +f 11416/11416/7448 11428/11428/7458 11417/11417/7449 +f 11427/11427/7457 11429/11429/7459 11430/11430/7460 +f 11427/11427/7457 11430/11430/7460 11428/11428/7458 +f 11428/11428/7458 11430/11430/7460 11431/11431/7046 +f 11428/11428/7458 11431/11431/7046 11432/11432/7043 +f 11417/11417/7449 11428/11428/7458 11432/11432/7043 +f 11417/11417/7449 11432/11432/7043 11418/11418/7042 +f 11433/11433/7461 11434/11434/7462 11435/11435/7463 +f 11433/11433/7461 11435/11435/7463 11436/11436/7464 +f 11434/11434/7462 11437/11437/7465 11438/11438/7466 +f 11434/11434/7462 11438/11438/7466 11435/11435/7463 +f 11435/11435/7463 11438/11438/7466 11439/11439/7467 +f 11435/11435/7463 11439/11439/7467 11440/11440/6412 +f 11436/11436/7464 11435/11435/7463 11440/11440/6412 +f 11436/11436/7464 11440/11440/6412 11441/11441/6411 +f 11442/11442/7468 11443/11443/7469 11444/11444/7470 +f 11442/11442/7468 11444/11444/7470 11445/11445/7471 +f 11443/11443/7469 11446/11446/7472 11447/11447/7473 +f 11443/11443/7469 11447/11447/7473 11444/11444/7470 +f 11444/11444/7470 11447/11447/7473 11448/11448/7060 +f 11444/11444/7470 11448/11448/7060 11449/11449/7474 +f 11445/11445/7471 11444/11444/7470 11449/11449/7474 +f 11445/11445/7471 11449/11449/7474 11450/11450/7057 +f 11451/11451/6153 11452/11452/6152 11453/11453/7475 +f 11451/11451/6153 11453/11453/7475 11454/11454/7476 +f 11452/11452/6152 11314/11314/6151 11317/11317/7374 +f 11452/11452/6152 11317/11317/7374 11453/11453/7475 +f 11453/11453/7475 11317/11317/7374 11319/11319/7376 +f 11453/11453/7475 11319/11319/7376 11455/11455/7477 +f 11454/11454/7476 11453/11453/7475 11455/11455/7477 +f 11454/11454/7476 11455/11455/7477 11456/11456/7274 +f 11356/11356/7403 11457/11457/7478 11458/11458/7479 +f 11356/11356/7403 11458/11458/7479 11357/11357/7404 +f 11457/11457/7478 11459/11459/7480 11460/11460/7481 +f 11457/11457/7478 11460/11460/7481 11458/11458/7479 +f 11458/11458/7479 11460/11460/7481 11461/11461/7482 +f 11458/11458/7479 11461/11461/7482 11462/11462/6857 +f 11357/11357/7404 11458/11458/7479 11462/11462/6857 +f 11357/11357/7404 11462/11462/6857 11358/11358/6856 +f 11459/11459/7480 11463/11463/7483 11464/11464/7484 +f 11459/11459/7480 11464/11464/7484 11460/11460/7481 +f 11463/11463/7483 11194/11194/7283 11197/11197/7286 +f 11463/11463/7483 11197/11197/7286 11464/11464/7484 +f 11464/11464/7484 11197/11197/7286 11199/11199/6840 +f 11464/11464/7484 11199/11199/6840 11465/11465/6839 +f 11460/11460/7481 11464/11464/7484 11465/11465/6839 +f 11460/11460/7481 11465/11465/6839 11461/11461/7482 +f 11189/11189/7280 11466/11466/7485 11467/11467/7486 +f 11189/11189/7280 11467/11467/7486 11190/11190/7281 +f 11466/11466/7485 11334/11334/7384 11337/11337/7387 +f 11466/11466/7485 11337/11337/7387 11467/11467/7486 +f 11467/11467/7486 11337/11337/7387 11342/11342/6868 +f 11467/11467/7486 11342/11342/6868 11468/11468/6924 +f 11190/11190/7281 11467/11467/7486 11468/11468/6924 +f 11190/11190/7281 11468/11468/6924 11191/11191/6846 +f 11213/11213/6133 11469/11469/6132 11470/11470/7487 +f 11213/11213/6133 11470/11470/7487 11214/11214/7295 +f 11469/11469/6132 11200/11200/6131 11203/11203/7288 +f 11469/11469/6132 11203/11203/7288 11470/11470/7487 +f 11470/11470/7487 11203/11203/7288 11208/11208/7292 +f 11470/11470/7487 11208/11208/7292 11471/11471/7488 +f 11214/11214/7295 11470/11470/7487 11471/11471/7488 +f 11214/11214/7295 11471/11471/7488 11215/11215/7296 +f 11204/11204/6162 11472/11472/6161 11473/11473/7489 +f 11204/11204/6162 11473/11473/7489 11205/11205/7289 +f 11472/11472/6161 11266/11266/6160 11269/11269/7337 +f 11472/11472/6161 11269/11269/7337 11473/11473/7489 +f 11473/11473/7489 11269/11269/7337 11274/11274/7341 +f 11473/11473/7489 11274/11274/7341 11474/11474/7490 +f 11205/11205/7289 11473/11473/7489 11474/11474/7490 +f 11205/11205/7289 11474/11474/7490 11206/11206/7290 +f 11475/11475/7432 11476/11476/7491 11477/11477/7492 +f 11475/11475/7432 11477/11477/7492 11478/11478/7433 +f 11476/11476/7491 11479/11479/7493 11480/11480/7494 +f 11476/11476/7491 11480/11480/7494 11477/11477/7492 +f 11477/11477/7492 11480/11480/7494 11481/11481/6852 +f 11477/11477/7492 11481/11481/6852 11482/11482/7495 +f 11478/11478/7433 11477/11477/7492 11482/11482/7495 +f 11478/11478/7433 11482/11482/7495 11483/11483/6850 +f 11484/11484/7496 11485/11485/7497 11486/11486/7498 +f 11484/11484/7496 11486/11486/7498 11487/11487/7499 +f 11485/11485/7497 11488/11488/7419 11489/11489/7422 +f 11485/11485/7497 11489/11489/7422 11486/11486/7498 +f 11486/11486/7498 11489/11489/7422 11386/11386/7016 +f 11486/11486/7498 11386/11386/7016 11490/11490/7500 +f 11487/11487/7499 11486/11486/7498 11490/11490/7500 +f 11487/11487/7499 11490/11490/7500 11491/11491/7212 +f 11347/11347/7394 11492/11492/7501 11493/11493/7502 +f 11347/11347/7394 11493/11493/7502 11348/11348/7395 +f 11492/11492/7501 11494/11494/7503 11495/11495/7504 +f 11492/11492/7501 11495/11495/7504 11493/11493/7502 +f 11493/11493/7502 11495/11495/7504 11496/11496/7505 +f 11493/11493/7502 11496/11496/7505 11497/11497/7506 +f 11348/11348/7395 11493/11493/7502 11497/11497/7506 +f 11348/11348/7395 11497/11497/7506 11349/11349/7396 +f 11132/11132/5941 11498/11498/5940 11499/11499/7507 +f 11132/11132/5941 11499/11499/7507 11133/11133/7233 +f 11498/11498/5940 11275/11275/7342 11278/11278/7344 +f 11498/11498/5940 11278/11278/7344 11499/11499/7507 +f 11499/11499/7507 11278/11278/7344 11283/11283/7349 +f 11499/11499/7507 11283/11283/7349 11500/11500/7508 +f 11133/11133/7233 11499/11499/7507 11500/11500/7508 +f 11133/11133/7233 11500/11500/7508 11134/11134/7234 +f 11501/11501/7509 11502/11502/7510 11503/11503/7511 +f 11501/11501/7509 11503/11503/7511 11504/11504/7157 +f 11502/11502/7510 11505/11505/7194 11506/11506/7197 +f 11502/11502/7510 11506/11506/7197 11503/11503/7511 +f 11503/11503/7511 11506/11506/7197 11507/11507/7070 +f 11503/11503/7511 11507/11507/7070 11508/11508/7512 +f 11504/11504/7157 11503/11503/7511 11508/11508/7512 +f 11504/11504/7157 11508/11508/7512 11509/11509/7158 +f 11510/11510/7248 11511/11511/7513 11512/11512/7514 +f 11510/11510/7248 11512/11512/7514 11513/11513/7249 +f 11511/11511/7513 11290/11290/7354 11293/11293/7356 +f 11511/11511/7513 11293/11293/7356 11512/11512/7514 +f 11512/11512/7514 11293/11293/7356 11298/11298/7361 +f 11512/11512/7514 11298/11298/7361 11514/11514/7515 +f 11513/11513/7249 11512/11512/7514 11514/11514/7515 +f 11513/11513/7249 11514/11514/7515 11515/11515/7516 +f 11157/11157/7255 11516/11516/7517 11517/11517/7518 +f 11157/11157/7255 11517/11517/7518 11158/11158/7256 +f 11516/11516/7517 11137/11137/7237 11140/11140/7240 +f 11516/11516/7517 11140/11140/7240 11517/11517/7518 +f 11517/11517/7518 11140/11140/7240 11145/11145/7244 +f 11517/11517/7518 11145/11145/7244 11518/11518/7519 +f 11158/11158/7256 11517/11517/7518 11518/11518/7519 +f 11158/11158/7256 11518/11518/7519 11159/11159/7257 +f 11519/11519/5706 11520/11520/7520 11521/11521/7521 +f 11519/11519/5706 11521/11521/7521 11522/11522/7522 +f 11520/11520/7520 11523/11523/7362 11524/11524/7523 +f 11520/11520/7520 11524/11524/7523 11521/11521/7521 +f 11521/11521/7521 11524/11524/7523 11525/11525/7366 +f 11521/11521/7521 11525/11525/7366 11526/11526/7524 +f 11522/11522/7522 11521/11521/7521 11526/11526/7524 +f 11522/11522/7522 11526/11526/7524 11527/11527/7525 +f 11528/11528/7526 11529/11529/7527 11530/11530/7528 +f 11528/11528/7526 11530/11530/7528 11531/11531/7529 +f 11529/11529/7527 11032/11032/7152 11035/11035/7155 +f 11529/11529/7527 11035/11035/7155 11530/11530/7528 +f 11530/11530/7528 11035/11035/7155 11040/11040/7077 +f 11530/11530/7528 11040/11040/7077 11532/11532/7082 +f 11531/11531/7529 11530/11530/7528 11532/11532/7082 +f 11531/11531/7529 11532/11532/7082 11533/11533/7530 +f 11534/11534/7531 11535/11535/7532 11536/11536/7533 +f 11534/11534/7531 11536/11536/7533 11537/11537/7534 +f 11535/11535/7532 11065/11065/7179 11068/11068/7182 +f 11535/11535/7532 11068/11068/7182 11536/11536/7533 +f 11536/11536/7533 11068/11068/7182 11073/11073/6510 +f 11536/11536/7533 11073/11073/6510 11538/11538/6509 +f 11537/11537/7534 11536/11536/7533 11538/11538/6509 +f 11537/11537/7534 11538/11538/6509 11539/11539/6508 +f 11078/11078/5788 11540/11540/6209 11541/11541/7535 +f 11078/11078/5788 11541/11541/7535 11079/11079/7190 +f 11540/11540/6209 11254/11254/7327 11257/11257/7329 +f 11540/11540/6209 11257/11257/7329 11541/11541/7535 +f 11541/11541/7535 11257/11257/7329 11259/11259/7331 +f 11541/11541/7535 11259/11259/7331 11542/11542/7536 +f 11079/11079/7190 11541/11541/7535 11542/11542/7536 +f 11079/11079/7190 11542/11542/7536 11080/11080/7191 +f 11543/11543/7426 11544/11544/7537 11545/11545/7538 +f 11543/11543/7426 11545/11545/7538 11546/11546/7539 +f 11544/11544/7537 11361/11361/7405 11364/11364/7408 +f 11544/11544/7537 11364/11364/7408 11545/11545/7538 +f 11545/11545/7538 11364/11364/7408 11368/11368/7411 +f 11545/11545/7538 11368/11368/7411 11547/11547/6425 +f 11546/11546/7539 11545/11545/7538 11547/11547/6425 +f 11546/11546/7539 11547/11547/6425 11391/11391/6424 +f 11279/11279/5710 11548/11548/5709 11549/11549/7540 +f 11279/11279/5710 11549/11549/7540 11550/11550/7541 +f 11548/11548/5709 11305/11305/5708 11308/11308/7368 +f 11548/11548/5709 11308/11308/7368 11549/11549/7540 +f 11549/11549/7540 11308/11308/7368 11313/11313/7372 +f 11549/11549/7540 11313/11313/7372 11551/11551/7542 +f 11550/11550/7541 11549/11549/7540 11551/11551/7542 +f 11550/11550/7541 11551/11551/7542 11552/11552/7347 +f 11429/11429/7459 11553/11553/7543 11554/11554/7544 +f 11429/11429/7459 11554/11554/7544 11430/11430/7460 +f 11553/11553/7543 11555/11555/7545 11556/11556/7546 +f 11553/11553/7543 11556/11556/7546 11554/11554/7544 +f 11554/11554/7544 11556/11556/7546 11557/11557/7547 +f 11554/11554/7544 11557/11557/7547 11558/11558/7548 +f 11430/11430/7460 11554/11554/7544 11558/11558/7548 +f 11430/11430/7460 11558/11558/7548 11431/11431/7046 +f 11094/11094/7202 11559/11559/7549 11560/11560/7550 +f 11094/11094/7202 11560/11560/7550 11095/11095/7203 +f 11559/11559/7549 11236/11236/7312 11239/11239/7314 +f 11559/11559/7549 11239/11239/7314 11560/11560/7550 +f 11560/11560/7550 11239/11239/7314 11244/11244/7319 +f 11560/11560/7550 11244/11244/7319 11561/11561/7551 +f 11095/11095/7203 11560/11560/7550 11561/11561/7551 +f 11095/11095/7203 11561/11561/7551 11096/11096/7204 +f 11123/11123/7229 11562/11562/7552 11563/11563/7553 +f 11123/11123/7229 11563/11563/7553 11124/11124/7230 +f 11562/11562/7552 11534/11534/7531 11537/11537/7534 +f 11562/11562/7552 11537/11537/7534 11563/11563/7553 +f 11563/11563/7553 11537/11537/7534 11539/11539/6508 +f 11563/11563/7553 11539/11539/6508 11564/11564/6564 +f 11124/11124/7230 11563/11563/7553 11564/11564/6564 +f 11124/11124/7230 11564/11564/6564 11125/11125/6563 +f 11555/11555/7545 11565/11565/7554 11566/11566/7555 +f 11555/11555/7545 11566/11566/7555 11556/11556/7546 +f 11565/11565/7554 11528/11528/7526 11531/11531/7529 +f 11565/11565/7554 11531/11531/7529 11566/11566/7555 +f 11566/11566/7555 11531/11531/7529 11533/11533/7530 +f 11566/11566/7555 11533/11533/7530 11567/11567/7086 +f 11556/11556/7546 11566/11566/7555 11567/11567/7086 +f 11556/11556/7546 11567/11567/7086 11557/11557/7547 +f 11027/11027/5956 11568/11568/5963 11569/11569/7556 +f 11027/11027/5956 11569/11569/7556 11028/11028/7148 +f 11568/11568/5963 11128/11128/5962 11131/11131/7232 +f 11568/11568/5963 11131/11131/7232 11569/11569/7556 +f 11569/11569/7556 11131/11131/7232 11136/11136/7236 +f 11569/11569/7556 11136/11136/7236 11570/11570/7557 +f 11028/11028/7148 11569/11569/7556 11570/11570/7557 +f 11028/11028/7148 11570/11570/7557 11029/11029/7149 +f 11294/11294/5972 11571/11571/5971 11572/11572/7558 +f 11294/11294/5972 11572/11572/7558 11573/11573/7358 +f 11571/11571/5971 11320/11320/5970 11323/11323/7379 +f 11571/11571/5971 11323/11323/7379 11572/11572/7558 +f 11572/11572/7558 11323/11323/7379 11325/11325/7381 +f 11572/11572/7558 11325/11325/7381 11574/11574/7559 +f 11573/11573/7358 11572/11572/7558 11574/11574/7559 +f 11573/11573/7358 11574/11574/7559 11575/11575/7359 +f 11494/11494/7503 11576/11576/7560 11577/11577/7561 +f 11494/11494/7503 11577/11577/7561 11495/11495/7504 +f 11576/11576/7560 11041/11041/7159 11044/11044/7162 +f 11576/11576/7560 11044/11044/7162 11577/11577/7561 +f 11577/11577/7561 11044/11044/7162 11049/11049/6648 +f 11577/11577/7561 11049/11049/6648 11578/11578/6647 +f 11495/11495/7504 11577/11577/7561 11578/11578/6647 +f 11495/11495/7504 11578/11578/6647 11496/11496/7505 +f 11054/11054/7169 11579/11579/7562 11580/11580/7563 +f 11054/11054/7169 11580/11580/7563 11055/11055/7170 +f 11579/11579/7562 11581/11581/6330 11582/11582/7247 +f 11579/11579/7562 11582/11582/7247 11580/11580/7563 +f 11580/11580/7563 11582/11582/7247 11583/11583/7564 +f 11580/11580/7563 11583/11583/7564 11584/11584/7565 +f 11055/11055/7170 11580/11580/7563 11584/11584/7565 +f 11055/11055/7170 11584/11584/7565 11056/11056/7171 +f 11585/11585/7566 11586/11586/7567 11587/11587/7568 +f 11585/11585/7566 11587/11587/7568 11588/11588/7569 +f 11586/11586/7567 11589/11589/7570 11590/11590/7571 +f 11586/11586/7567 11590/11590/7571 11587/11587/7568 +f 11587/11587/7568 11590/11590/7571 11591/11591/6418 +f 11587/11587/7568 11591/11591/6418 11592/11592/6883 +f 11588/11588/7569 11587/11587/7568 11592/11592/6883 +f 11588/11588/7569 11592/11592/6883 11593/11593/7572 +f 11594/11594/7573 11595/11595/7574 11596/11596/7575 +f 11594/11594/7573 11596/11596/7575 11597/11597/7576 +f 11595/11595/7574 11421/11421/7452 11424/11424/7455 +f 11595/11595/7574 11424/11424/7455 11596/11596/7575 +f 11596/11596/7575 11424/11424/7455 11426/11426/7456 +f 11596/11596/7575 11426/11426/7456 11598/11598/7577 +f 11597/11597/7576 11596/11596/7575 11598/11598/7577 +f 11597/11597/7576 11598/11598/7577 11599/11599/7066 +f 11589/11589/7570 11600/11600/7578 11601/11601/7579 +f 11589/11589/7570 11601/11601/7579 11590/11590/7571 +f 11600/11600/7578 11602/11602/7580 11603/11603/7581 +f 11600/11600/7578 11603/11603/7581 11601/11601/7579 +f 11601/11601/7579 11603/11603/7581 11604/11604/6411 +f 11601/11601/7579 11604/11604/6411 11605/11605/6419 +f 11590/11590/7571 11601/11601/7579 11605/11605/6419 +f 11590/11590/7571 11605/11605/6419 11591/11591/6418 +f 11446/11446/7472 11606/11606/7582 11607/11607/7583 +f 11446/11446/7472 11607/11607/7583 11447/11447/7473 +f 11606/11606/7582 11594/11594/7573 11597/11597/7576 +f 11606/11606/7582 11597/11597/7576 11607/11607/7583 +f 11607/11607/7583 11597/11597/7576 11599/11599/7066 +f 11607/11607/7583 11599/11599/7066 11608/11608/7064 +f 11447/11447/7473 11607/11607/7583 11608/11608/7064 +f 11447/11447/7473 11608/11608/7064 11448/11448/7060 +f 11609/11609/7493 11610/11610/7584 11611/11611/7585 +f 11609/11609/7493 11611/11611/7585 11612/11612/7494 +f 11610/11610/7584 11613/11613/7586 11614/11614/7587 +f 11610/11610/7584 11614/11614/7587 11611/11611/7585 +f 11611/11611/7585 11614/11614/7587 11615/11615/7588 +f 11611/11611/7585 11615/11615/7588 11616/11616/7589 +f 11612/11612/7494 11611/11611/7585 11616/11616/7589 +f 11612/11612/7494 11616/11616/7589 11617/11617/7590 +f 11618/11618/7591 11619/11619/7592 11620/11620/7593 +f 11618/11618/7591 11620/11620/7593 11621/11621/7594 +f 11619/11619/7592 11622/11622/7595 11623/11623/7596 +f 11619/11619/7592 11623/11623/7596 11620/11620/7593 +f 11620/11620/7593 11623/11623/7596 11624/11624/6405 +f 11620/11620/7593 11624/11624/6405 11625/11625/6404 +f 11621/11621/7594 11620/11620/7593 11625/11625/6404 +f 11621/11621/7594 11625/11625/6404 11626/11626/6403 +f 11627/11627/7586 11628/11628/7597 11629/11629/7598 +f 11627/11627/7586 11629/11629/7598 11630/11630/7599 +f 11628/11628/7597 11442/11442/7468 11445/11445/7471 +f 11628/11628/7597 11445/11445/7471 11629/11629/7598 +f 11629/11629/7598 11445/11445/7471 11450/11450/7057 +f 11629/11629/7598 11450/11450/7057 11631/11631/6395 +f 11630/11630/7599 11629/11629/7598 11631/11631/6395 +f 11630/11630/7599 11631/11631/6395 11615/11615/7588 +f 11632/11632/7600 11633/11633/7601 11634/11634/7602 +f 11632/11632/7600 11634/11634/7602 11635/11635/7603 +f 11633/11633/7601 11395/11395/7604 11636/11636/7605 +f 11633/11633/7601 11636/11636/7605 11634/11634/7602 +f 11634/11634/7602 11636/11636/7605 11637/11637/7606 +f 11634/11634/7602 11637/11637/7606 11638/11638/7607 +f 11635/11635/7603 11634/11634/7602 11638/11638/7607 +f 11635/11635/7603 11638/11638/7607 11639/11639/7608 +f 11639/11639/7608 11638/11638/7607 11640/11640/7609 +f 11639/11639/7608 11640/11640/7609 11641/11641/7610 +f 11638/11638/7607 11637/11637/7606 11642/11642/7611 +f 11638/11638/7607 11642/11642/7611 11640/11640/7609 +f 11640/11640/7609 11642/11642/7611 11643/11643/7339 +f 11640/11640/7609 11643/11643/7339 11644/11644/7383 +f 11641/11641/7610 11640/11640/7609 11644/11644/7383 +f 11641/11641/7610 11644/11644/7383 11645/11645/7311 +f 11343/11343/7390 11646/11646/7612 11647/11647/7613 +f 11343/11343/7390 11647/11647/7613 11648/11648/7614 +f 11646/11646/7612 11649/11649/7435 11650/11650/7615 +f 11646/11646/7612 11650/11650/7615 11647/11647/7613 +f 11647/11647/7613 11650/11650/7615 11651/11651/7616 +f 11647/11647/7613 11651/11651/7616 11652/11652/7617 +f 11648/11648/7614 11647/11647/7613 11652/11652/7617 +f 11648/11648/7614 11652/11652/7617 11653/11653/7618 +f 11653/11653/7618 11652/11652/7617 11654/11654/7619 +f 11653/11653/7618 11654/11654/7619 11655/11655/7620 +f 11652/11652/7617 11651/11651/7616 11656/11656/7621 +f 11652/11652/7617 11656/11656/7621 11654/11654/7619 +f 11654/11654/7619 11656/11656/7621 11657/11657/7359 +f 11654/11654/7619 11657/11657/7359 11658/11658/7622 +f 11655/11655/7620 11654/11654/7619 11658/11658/7622 +f 11655/11655/7620 11658/11658/7622 11659/11659/7623 +f 11660/11660/7399 11382/11382/7624 11661/11661/7625 +f 11660/11660/7399 11661/11661/7625 11662/11662/7626 +f 11382/11382/7624 11663/11663/7627 11664/11664/7628 +f 11382/11382/7624 11664/11664/7628 11661/11661/7625 +f 11661/11661/7625 11664/11664/7628 11665/11665/7629 +f 11661/11661/7625 11665/11665/7629 11666/11666/7630 +f 11662/11662/7626 11661/11661/7625 11666/11666/7630 +f 11662/11662/7626 11666/11666/7630 11667/11667/7631 +f 11667/11667/7631 11666/11666/7630 11668/11668/7632 +f 11667/11667/7631 11668/11668/7632 11669/11669/7633 +f 11666/11666/7630 11665/11665/7629 11670/11670/7634 +f 11666/11666/7630 11670/11670/7634 11668/11668/7632 +f 11668/11668/7632 11670/11670/7634 11671/11671/7274 +f 11668/11668/7632 11671/11671/7274 11672/11672/7635 +f 11669/11669/7633 11668/11668/7632 11672/11672/7635 +f 11669/11669/7633 11672/11672/7635 11673/11673/7636 +f 11674/11674/7637 11675/11675/7537 11676/11676/7638 +f 11674/11674/7637 11676/11676/7638 11677/11677/7639 +f 11675/11675/7537 11678/11678/7426 11679/11679/7640 +f 11675/11675/7537 11679/11679/7640 11676/11676/7638 +f 11676/11676/7638 11679/11679/7640 11680/11680/7641 +f 11676/11676/7638 11680/11680/7641 11681/11681/7642 +f 11677/11677/7639 11676/11676/7638 11681/11681/7642 +f 11677/11677/7639 11681/11681/7642 11682/11682/7643 +f 11682/11682/7643 11681/11681/7642 11683/11683/7644 +f 11682/11682/7643 11683/11683/7644 11684/11684/7645 +f 11681/11681/7642 11680/11680/7641 11685/11685/7646 +f 11681/11681/7642 11685/11685/7646 11683/11683/7644 +f 11683/11683/7644 11685/11685/7646 11686/11686/7647 +f 11683/11683/7644 11686/11686/7647 11687/11687/7648 +f 11684/11684/7645 11683/11683/7644 11687/11687/7648 +f 11684/11684/7645 11687/11687/7648 11688/11688/7649 +f 11689/11689/7650 11690/11690/7651 11691/11691/7652 +f 11689/11689/7650 11691/11691/7652 11692/11692/7653 +f 11690/11690/7651 11693/11693/7654 11694/11694/7655 +f 11690/11690/7651 11694/11694/7655 11691/11691/7652 +f 11691/11691/7652 11694/11694/7655 11695/11695/7656 +f 11691/11691/7652 11695/11695/7656 11696/11696/7657 +f 11692/11692/7653 11691/11691/7652 11696/11696/7657 +f 11692/11692/7653 11696/11696/7657 11697/11697/7658 +f 11697/11697/7658 11696/11696/7657 11698/11698/7659 +f 11697/11697/7658 11698/11698/7659 11699/11699/7660 +f 11696/11696/7657 11695/11695/7656 11700/11700/7661 +f 11696/11696/7657 11700/11700/7661 11698/11698/7659 +f 11698/11698/7659 11700/11700/7661 11527/11527/7662 +f 11698/11698/7659 11527/11527/7662 11701/11701/7524 +f 11699/11699/7660 11698/11698/7659 11701/11701/7524 +f 11699/11699/7660 11701/11701/7524 11525/11525/7663 +f 11702/11702/7198 11703/11703/7664 11704/11704/7665 +f 11702/11702/7198 11704/11704/7665 11705/11705/7666 +f 11703/11703/7664 11706/11706/7194 11707/11707/7667 +f 11703/11703/7664 11707/11707/7667 11704/11704/7665 +f 11704/11704/7665 11707/11707/7667 11708/11708/7668 +f 11704/11704/7665 11708/11708/7668 11709/11709/7669 +f 11705/11705/7666 11704/11704/7665 11709/11709/7669 +f 11705/11705/7666 11709/11709/7669 11710/11710/7670 +f 11710/11710/7670 11709/11709/7669 11711/11711/7671 +f 11710/11710/7670 11711/11711/7671 11712/11712/7672 +f 11709/11709/7669 11708/11708/7668 11713/11713/7673 +f 11709/11709/7669 11713/11713/7673 11711/11711/7671 +f 11711/11711/7671 11713/11713/7673 11152/11152/7516 +f 11711/11711/7671 11152/11152/7516 11714/11714/7674 +f 11712/11712/7672 11711/11711/7671 11714/11714/7674 +f 11712/11712/7672 11714/11714/7674 11298/11298/7361 +f 11715/11715/7480 11716/11716/7478 11717/11717/7675 +f 11715/11715/7480 11717/11717/7675 11718/11718/7676 +f 11716/11716/7478 11719/11719/7677 11720/11720/7678 +f 11716/11716/7478 11720/11720/7678 11717/11717/7675 +f 11717/11717/7675 11720/11720/7678 11721/11721/7679 +f 11717/11717/7675 11721/11721/7679 11722/11722/7675 +f 11718/11718/7676 11717/11717/7675 11722/11722/7675 +f 11718/11718/7676 11722/11722/7675 11723/11723/7680 +f 11723/11723/7680 11722/11722/7675 11724/11724/7681 +f 11723/11723/7680 11724/11724/7681 11725/11725/7682 +f 11722/11722/7675 11721/11721/7679 11726/11726/7683 +f 11722/11722/7675 11726/11726/7683 11724/11724/7681 +f 11724/11724/7681 11726/11726/7683 11727/11727/7353 +f 11724/11724/7681 11727/11727/7353 11728/11728/7684 +f 11725/11725/7682 11724/11724/7681 11728/11728/7684 +f 11725/11725/7682 11728/11728/7684 11223/11223/7685 +f 11141/11141/7241 11138/11138/7238 11729/11729/7686 +f 11141/11141/7241 11729/11729/7686 11730/11730/7687 +f 11138/11138/7238 11137/11137/7237 11731/11731/7688 +f 11138/11138/7238 11731/11731/7688 11729/11729/7686 +f 11729/11729/7686 11731/11731/7688 11732/11732/7689 +f 11729/11729/7686 11732/11732/7689 11733/11733/7690 +f 11730/11730/7687 11729/11729/7686 11733/11733/7690 +f 11730/11730/7687 11733/11733/7690 11734/11734/7691 +f 11734/11734/7691 11733/11733/7690 11735/11735/7692 +f 11734/11734/7691 11735/11735/7692 11736/11736/7693 +f 11733/11733/7690 11732/11732/7689 11737/11737/7694 +f 11733/11733/7690 11737/11737/7694 11735/11735/7692 +f 11735/11735/7692 11737/11737/7694 11738/11738/7695 +f 11735/11735/7692 11738/11738/7695 11739/11739/7696 +f 11736/11736/7693 11735/11735/7692 11739/11739/7696 +f 11736/11736/7693 11739/11739/7696 11740/11740/7697 +f 11741/11741/7698 11742/11742/7699 11743/11743/7700 +f 11741/11741/7698 11743/11743/7700 11744/11744/7701 +f 11742/11742/7699 11745/11745/7702 11746/11746/7703 +f 11742/11742/7699 11746/11746/7703 11743/11743/7700 +f 11743/11743/7700 11746/11746/7703 11747/11747/7704 +f 11743/11743/7700 11747/11747/7704 11748/11748/7705 +f 11744/11744/7701 11743/11743/7700 11748/11748/7705 +f 11744/11744/7701 11748/11748/7705 11749/11749/7706 +f 11749/11749/7706 11748/11748/7705 11750/11750/7700 +f 11749/11749/7706 11750/11750/7700 11751/11751/7707 +f 11748/11748/7705 11747/11747/7704 11752/11752/7708 +f 11748/11748/7705 11752/11752/7708 11750/11750/7700 +f 11750/11750/7700 11752/11752/7708 11753/11753/7290 +f 11750/11750/7700 11753/11753/7290 11474/11474/7709 +f 11751/11751/7707 11750/11750/7700 11474/11474/7709 +f 11751/11751/7707 11474/11474/7709 11754/11754/7341 +f 11755/11755/7503 11756/11756/7710 11757/11757/7711 +f 11755/11755/7503 11757/11757/7711 11758/11758/7712 +f 11756/11756/7710 11759/11759/7713 11760/11760/7714 +f 11756/11756/7710 11760/11760/7714 11757/11757/7711 +f 11757/11757/7711 11760/11760/7714 11761/11761/7715 +f 11757/11757/7711 11761/11761/7715 11762/11762/7716 +f 11758/11758/7712 11757/11757/7711 11762/11762/7716 +f 11758/11758/7712 11762/11762/7716 11763/11763/7717 +f 11763/11763/7717 11762/11762/7716 11764/11764/7718 +f 11763/11763/7717 11764/11764/7718 11765/11765/7719 +f 11762/11762/7716 11761/11761/7715 11766/11766/7720 +f 11762/11762/7716 11766/11766/7720 11764/11764/7718 +f 11764/11764/7718 11766/11766/7720 11767/11767/7335 +f 11764/11764/7718 11767/11767/7335 11768/11768/7334 +f 11765/11765/7719 11764/11764/7718 11768/11768/7334 +f 11765/11765/7719 11768/11768/7334 11769/11769/7721 +f 11770/11770/7722 11771/11771/7723 11772/11772/7724 +f 11770/11770/7722 11772/11772/7724 11773/11773/7725 +f 11771/11771/7723 11774/11774/7726 11775/11775/7727 +f 11771/11771/7723 11775/11775/7727 11772/11772/7724 +f 11772/11772/7724 11775/11775/7727 11776/11776/7728 +f 11772/11772/7724 11776/11776/7728 11777/11777/7729 +f 11773/11773/7725 11772/11772/7724 11777/11777/7729 +f 11773/11773/7725 11777/11777/7729 11778/11778/7730 +f 11778/11778/7730 11777/11777/7729 11779/11779/7731 +f 11778/11778/7730 11779/11779/7731 11780/11780/7732 +f 11777/11777/7729 11776/11776/7728 11781/11781/7733 +f 11777/11777/7729 11781/11781/7733 11779/11779/7731 +f 11779/11779/7731 11781/11781/7733 11782/11782/7191 +f 11779/11779/7731 11782/11782/7191 11783/11783/7734 +f 11780/11780/7732 11779/11779/7731 11783/11783/7734 +f 11780/11780/7732 11783/11783/7734 11784/11784/7331 +f 11785/11785/7545 11553/11553/7735 11786/11786/7736 +f 11785/11785/7545 11786/11786/7736 11787/11787/7737 +f 11553/11553/7735 11788/11788/7738 11789/11789/7739 +f 11553/11553/7735 11789/11789/7739 11786/11786/7736 +f 11786/11786/7736 11789/11789/7739 11790/11790/7740 +f 11786/11786/7736 11790/11790/7740 11791/11791/7741 +f 11787/11787/7737 11786/11786/7736 11791/11791/7741 +f 11787/11787/7737 11791/11791/7741 11792/11792/7742 +f 11792/11792/7742 11791/11791/7741 11793/11793/7743 +f 11792/11792/7742 11793/11793/7743 11794/11794/7744 +f 11791/11791/7741 11790/11790/7740 11795/11795/7745 +f 11791/11791/7741 11795/11795/7745 11793/11793/7743 +f 11793/11793/7743 11795/11795/7745 11796/11796/7317 +f 11793/11793/7743 11796/11796/7317 11253/11253/7746 +f 11794/11794/7744 11793/11793/7743 11253/11253/7746 +f 11794/11794/7744 11253/11253/7746 11797/11797/7178 +f 11798/11798/7747 11799/11799/7748 11800/11800/7749 +f 11798/11798/7747 11800/11800/7749 11801/11801/7750 +f 11799/11799/7748 11408/11408/7566 11802/11802/7751 +f 11799/11799/7748 11802/11802/7751 11800/11800/7749 +f 11800/11800/7749 11802/11802/7751 11803/11803/7752 +f 11800/11800/7749 11803/11803/7752 11804/11804/7753 +f 11801/11801/7750 11800/11800/7749 11804/11804/7753 +f 11801/11801/7750 11804/11804/7753 11805/11805/7754 +f 11806/11806/7755 11807/11807/7753 11808/11808/7756 +f 11806/11806/7755 11808/11808/7756 11809/11809/7757 +f 11807/11807/7753 11810/11810/7758 11811/11811/7759 +f 11807/11807/7753 11811/11811/7759 11808/11808/7756 +f 11808/11808/7756 11811/11811/7759 11812/11812/7760 +f 11808/11808/7756 11812/11812/7760 11813/11813/7761 +f 11809/11809/7757 11808/11808/7756 11813/11813/7761 +f 11809/11809/7757 11813/11813/7761 11814/11814/7132 +f 11815/11815/7448 11816/11816/7445 11817/11817/7762 +f 11815/11815/7448 11817/11817/7762 11818/11818/7763 +f 11816/11816/7445 11819/11819/7444 11820/11820/7764 +f 11816/11816/7445 11820/11820/7764 11817/11817/7762 +f 11817/11817/7762 11820/11820/7764 11821/11821/7765 +f 11817/11817/7762 11821/11821/7765 11822/11822/7766 +f 11818/11818/7763 11817/11817/7762 11822/11822/7766 +f 11818/11818/7763 11822/11822/7766 11823/11823/7767 +f 11823/11823/7767 11822/11822/7766 11824/11824/7768 +f 11823/11823/7767 11824/11824/7768 11825/11825/7769 +f 11822/11822/7766 11821/11821/7765 11826/11826/7770 +f 11822/11822/7766 11826/11826/7770 11824/11824/7768 +f 11824/11824/7768 11826/11826/7770 11827/11827/7771 +f 11824/11824/7768 11827/11827/7771 11828/11828/7551 +f 11825/11825/7769 11824/11824/7768 11828/11828/7551 +f 11825/11825/7769 11828/11828/7551 11244/11244/7319 +f 11829/11829/7772 11830/11830/7584 11831/11831/7773 +f 11829/11829/7772 11831/11831/7773 11832/11832/7774 +f 11830/11830/7584 11833/11833/7775 11834/11834/7776 +f 11830/11830/7584 11834/11834/7776 11831/11831/7773 +f 11831/11831/7773 11834/11834/7776 11835/11835/7608 +f 11831/11831/7773 11835/11835/7608 11836/11836/7777 +f 11832/11832/7774 11831/11831/7773 11836/11836/7777 +f 11832/11832/7774 11836/11836/7777 11837/11837/7778 +f 11837/11837/7778 11836/11836/7777 11838/11838/7779 +f 11837/11837/7778 11838/11838/7779 11839/11839/7780 +f 11836/11836/7777 11835/11835/7608 11840/11840/7781 +f 11836/11836/7777 11840/11840/7781 11838/11838/7779 +f 11838/11838/7779 11840/11840/7781 11841/11841/7311 +f 11838/11838/7779 11841/11841/7311 11842/11842/7782 +f 11839/11839/7780 11838/11838/7779 11842/11842/7782 +f 11839/11839/7780 11842/11842/7782 11843/11843/7309 +f 11844/11844/7783 11845/11845/7784 11846/11846/7785 +f 11844/11844/7783 11846/11846/7785 11847/11847/7786 +f 11845/11845/7784 11848/11848/7595 11849/11849/7787 +f 11845/11845/7784 11849/11849/7787 11846/11846/7785 +f 11846/11846/7785 11849/11849/7787 11850/11850/7788 +f 11846/11846/7785 11850/11850/7788 11851/11851/7789 +f 11847/11847/7786 11846/11846/7785 11851/11851/7789 +f 11847/11847/7786 11851/11851/7789 11852/11852/7790 +f 11852/11852/7790 11851/11851/7789 11853/11853/7791 +f 11852/11852/7790 11853/11853/7791 11854/11854/7792 +f 11851/11851/7789 11850/11850/7788 11855/11855/7793 +f 11851/11851/7789 11855/11855/7793 11853/11853/7791 +f 11853/11853/7791 11855/11855/7793 11856/11856/7110 +f 11853/11853/7791 11856/11856/7110 11857/11857/7794 +f 11854/11854/7792 11853/11853/7791 11857/11857/7794 +f 11854/11854/7792 11857/11857/7794 11858/11858/7269 +f 11719/11719/7677 11859/11859/7400 11860/11860/7795 +f 11719/11719/7677 11860/11860/7795 11720/11720/7678 +f 11859/11859/7400 11660/11660/7399 11662/11662/7626 +f 11859/11859/7400 11662/11662/7626 11860/11860/7795 +f 11860/11860/7795 11662/11662/7626 11667/11667/7631 +f 11860/11860/7795 11667/11667/7631 11861/11861/7796 +f 11720/11720/7678 11860/11860/7795 11861/11861/7796 +f 11720/11720/7678 11861/11861/7796 11721/11721/7679 +f 11721/11721/7679 11861/11861/7796 11862/11862/7797 +f 11721/11721/7679 11862/11862/7797 11726/11726/7683 +f 11861/11861/7796 11667/11667/7631 11669/11669/7633 +f 11861/11861/7796 11669/11669/7633 11862/11862/7797 +f 11862/11862/7797 11669/11669/7633 11673/11673/7636 +f 11862/11862/7797 11673/11673/7636 11863/11863/7798 +f 11726/11726/7683 11862/11862/7797 11863/11863/7798 +f 11726/11726/7683 11863/11863/7798 11727/11727/7353 +f 11864/11864/7283 11865/11865/7799 11866/11866/7800 +f 11864/11864/7283 11866/11866/7800 11867/11867/7801 +f 11865/11865/7799 11715/11715/7480 11718/11718/7676 +f 11865/11865/7799 11718/11718/7676 11866/11866/7800 +f 11866/11866/7800 11718/11718/7676 11723/11723/7680 +f 11866/11866/7800 11723/11723/7680 11868/11868/7802 +f 11867/11867/7801 11866/11866/7800 11868/11868/7802 +f 11867/11867/7801 11868/11868/7802 11869/11869/7803 +f 11869/11869/7803 11868/11868/7802 11870/11870/7802 +f 11869/11869/7803 11870/11870/7802 11871/11871/7803 +f 11868/11868/7802 11723/11723/7680 11725/11725/7682 +f 11868/11868/7802 11725/11725/7682 11870/11870/7802 +f 11870/11870/7802 11725/11725/7682 11223/11223/7685 +f 11870/11870/7802 11223/11223/7685 11872/11872/7804 +f 11871/11871/7803 11870/11870/7802 11872/11872/7804 +f 11871/11871/7803 11872/11872/7804 11873/11873/7298 +f 11874/11874/7276 11195/11195/7805 11875/11875/7806 +f 11874/11874/7276 11875/11875/7806 11876/11876/7807 +f 11195/11195/7805 11864/11864/7283 11867/11867/7801 +f 11195/11195/7805 11867/11867/7801 11875/11875/7806 +f 11875/11875/7806 11867/11867/7801 11869/11869/7803 +f 11875/11875/7806 11869/11869/7803 11877/11877/7808 +f 11876/11876/7807 11875/11875/7806 11877/11877/7808 +f 11876/11876/7807 11877/11877/7808 11878/11878/7809 +f 11878/11878/7809 11877/11877/7808 11879/11879/7810 +f 11878/11878/7809 11879/11879/7810 11880/11880/7811 +f 11877/11877/7808 11869/11869/7803 11871/11871/7803 +f 11877/11877/7808 11871/11871/7803 11879/11879/7810 +f 11879/11879/7810 11871/11871/7803 11873/11873/7298 +f 11879/11879/7810 11873/11873/7298 11881/11881/7812 +f 11880/11880/7811 11879/11879/7810 11881/11881/7812 +f 11880/11880/7811 11881/11881/7812 11882/11882/7813 +f 11883/11883/7814 11884/11884/7277 11885/11885/7815 +f 11883/11883/7814 11885/11885/7815 11886/11886/7816 +f 11884/11884/7277 11874/11874/7276 11876/11876/7807 +f 11884/11884/7277 11876/11876/7807 11885/11885/7815 +f 11885/11885/7815 11876/11876/7807 11878/11878/7809 +f 11885/11885/7815 11878/11878/7809 11887/11887/7817 +f 11886/11886/7816 11885/11885/7815 11887/11887/7817 +f 11886/11886/7816 11887/11887/7817 11888/11888/7818 +f 11888/11888/7818 11887/11887/7817 11889/11889/7819 +f 11888/11888/7818 11889/11889/7819 11890/11890/7820 +f 11887/11887/7817 11878/11878/7809 11880/11880/7811 +f 11887/11887/7817 11880/11880/7811 11889/11889/7819 +f 11889/11889/7819 11880/11880/7811 11882/11882/7813 +f 11889/11889/7819 11882/11882/7813 11891/11891/7488 +f 11890/11890/7820 11889/11889/7819 11891/11891/7488 +f 11890/11890/7820 11891/11891/7488 11892/11892/7821 +f 11745/11745/7702 11893/11893/7485 11894/11894/7822 +f 11745/11745/7702 11894/11894/7822 11746/11746/7703 +f 11893/11893/7485 11883/11883/7814 11886/11886/7816 +f 11893/11893/7485 11886/11886/7816 11894/11894/7822 +f 11894/11894/7822 11886/11886/7816 11888/11888/7818 +f 11894/11894/7822 11888/11888/7818 11895/11895/7823 +f 11746/11746/7703 11894/11894/7822 11895/11895/7823 +f 11746/11746/7703 11895/11895/7823 11747/11747/7704 +f 11747/11747/7704 11895/11895/7823 11896/11896/7824 +f 11747/11747/7704 11896/11896/7824 11752/11752/7708 +f 11895/11895/7823 11888/11888/7818 11890/11890/7820 +f 11895/11895/7823 11890/11890/7820 11896/11896/7824 +f 11896/11896/7824 11890/11890/7820 11892/11892/7821 +f 11896/11896/7824 11892/11892/7821 11897/11897/7291 +f 11752/11752/7708 11896/11896/7824 11897/11897/7291 +f 11752/11752/7708 11897/11897/7291 11753/11753/7290 +f 11395/11395/7604 11898/11898/7825 11899/11899/7826 +f 11395/11395/7604 11899/11899/7826 11636/11636/7605 +f 11898/11898/7825 11741/11741/7698 11744/11744/7701 +f 11898/11898/7825 11744/11744/7701 11899/11899/7826 +f 11899/11899/7826 11744/11744/7701 11749/11749/7706 +f 11899/11899/7826 11749/11749/7706 11900/11900/7827 +f 11636/11636/7605 11899/11899/7826 11900/11900/7827 +f 11636/11636/7605 11900/11900/7827 11637/11637/7606 +f 11637/11637/7606 11900/11900/7827 11901/11901/7828 +f 11637/11637/7606 11901/11901/7828 11642/11642/7611 +f 11900/11900/7827 11749/11749/7706 11751/11751/7707 +f 11900/11900/7827 11751/11751/7707 11901/11901/7828 +f 11901/11901/7828 11751/11751/7707 11754/11754/7341 +f 11901/11901/7828 11754/11754/7341 11902/11902/7340 +f 11642/11642/7611 11901/11901/7828 11902/11902/7340 +f 11642/11642/7611 11902/11902/7340 11643/11643/7339 +f 11663/11663/7627 11903/11903/7829 11904/11904/7830 +f 11663/11663/7627 11904/11904/7830 11664/11664/7628 +f 11903/11903/7829 11905/11905/7831 11906/11906/7832 +f 11903/11903/7829 11906/11906/7832 11904/11904/7830 +f 11904/11904/7830 11906/11906/7832 11907/11907/7833 +f 11904/11904/7830 11907/11907/7833 11908/11908/7834 +f 11664/11664/7628 11904/11904/7830 11908/11908/7834 +f 11664/11664/7628 11908/11908/7834 11665/11665/7629 +f 11665/11665/7629 11908/11908/7834 11909/11909/7835 +f 11665/11665/7629 11909/11909/7835 11670/11670/7634 +f 11908/11908/7834 11907/11907/7833 11910/11910/7836 +f 11908/11908/7834 11910/11910/7836 11909/11909/7835 +f 11909/11909/7835 11910/11910/7836 11184/11184/7837 +f 11909/11909/7835 11184/11184/7837 11911/11911/7838 +f 11670/11670/7634 11909/11909/7835 11911/11911/7838 +f 11670/11670/7634 11911/11911/7838 11671/11671/7274 +f 11912/11912/7496 11913/11913/7839 11914/11914/7840 +f 11912/11912/7496 11914/11914/7840 11915/11915/7841 +f 11913/11913/7839 11844/11844/7783 11847/11847/7786 +f 11913/11913/7839 11847/11847/7786 11914/11914/7840 +f 11914/11914/7840 11847/11847/7786 11852/11852/7790 +f 11914/11914/7840 11852/11852/7790 11916/11916/7842 +f 11915/11915/7841 11914/11914/7840 11916/11916/7842 +f 11915/11915/7841 11916/11916/7842 11917/11917/7833 +f 11917/11917/7833 11916/11916/7842 11918/11918/7843 +f 11917/11917/7833 11918/11918/7843 11919/11919/7836 +f 11916/11916/7842 11852/11852/7790 11854/11854/7792 +f 11916/11916/7842 11854/11854/7792 11918/11918/7843 +f 11918/11918/7843 11854/11854/7792 11858/11858/7269 +f 11918/11918/7843 11858/11858/7269 11920/11920/7844 +f 11919/11919/7836 11918/11918/7843 11920/11920/7844 +f 11919/11919/7836 11920/11920/7844 11173/11173/7837 +f 11921/11921/7159 11922/11922/7560 11923/11923/7845 +f 11921/11921/7159 11923/11923/7845 11924/11924/7846 +f 11922/11922/7560 11755/11755/7503 11758/11758/7712 +f 11922/11922/7560 11758/11758/7712 11923/11923/7845 +f 11923/11923/7845 11758/11758/7712 11763/11763/7717 +f 11923/11923/7845 11763/11763/7717 11925/11925/7847 +f 11924/11924/7846 11923/11923/7845 11925/11925/7847 +f 11924/11924/7846 11925/11925/7847 11926/11926/7848 +f 11926/11926/7848 11925/11925/7847 11927/11927/7849 +f 11926/11926/7848 11927/11927/7849 11928/11928/7850 +f 11925/11925/7847 11763/11763/7717 11765/11765/7719 +f 11925/11925/7847 11765/11765/7719 11927/11927/7849 +f 11927/11927/7849 11765/11765/7719 11769/11769/7721 +f 11927/11927/7849 11769/11769/7721 11165/11165/7261 +f 11928/11928/7850 11927/11927/7849 11165/11165/7261 +f 11928/11928/7850 11165/11165/7261 11929/11929/7151 +f 11678/11678/7426 11930/11930/7851 11931/11931/7852 +f 11678/11678/7426 11931/11931/7852 11679/11679/7640 +f 11930/11930/7851 11141/11141/7241 11730/11730/7687 +f 11930/11930/7851 11730/11730/7687 11931/11931/7852 +f 11931/11931/7852 11730/11730/7687 11734/11734/7691 +f 11931/11931/7852 11734/11734/7691 11932/11932/7853 +f 11679/11679/7640 11931/11931/7852 11932/11932/7853 +f 11679/11679/7640 11932/11932/7853 11680/11680/7641 +f 11680/11680/7641 11932/11932/7853 11933/11933/7854 +f 11680/11680/7641 11933/11933/7854 11685/11685/7646 +f 11932/11932/7853 11734/11734/7691 11736/11736/7693 +f 11932/11932/7853 11736/11736/7693 11933/11933/7854 +f 11933/11933/7854 11736/11736/7693 11740/11740/7697 +f 11933/11933/7854 11740/11740/7697 11934/11934/7855 +f 11685/11685/7646 11933/11933/7854 11934/11934/7855 +f 11685/11685/7646 11934/11934/7855 11686/11686/7647 +f 11036/11036/7156 11935/11935/7153 11936/11936/7856 +f 11036/11036/7156 11936/11936/7856 11937/11937/7857 +f 11935/11935/7153 11938/11938/7152 11939/11939/7858 +f 11935/11935/7153 11939/11939/7858 11936/11936/7856 +f 11936/11936/7856 11939/11939/7858 11940/11940/7859 +f 11936/11936/7856 11940/11940/7859 11941/11941/7860 +f 11937/11937/7857 11936/11936/7856 11941/11941/7860 +f 11937/11937/7857 11941/11941/7860 11942/11942/7861 +f 11942/11942/7861 11941/11941/7860 11943/11943/7862 +f 11942/11942/7861 11943/11943/7862 11944/11944/7863 +f 11941/11941/7860 11940/11940/7859 11945/11945/7864 +f 11941/11941/7860 11945/11945/7864 11943/11943/7862 +f 11943/11943/7862 11945/11945/7864 11946/11946/7171 +f 11943/11943/7862 11946/11946/7171 11584/11584/7865 +f 11944/11944/7863 11943/11943/7862 11584/11584/7865 +f 11944/11944/7863 11584/11584/7865 11947/11947/7564 +f 11649/11649/7435 11948/11948/7866 11949/11949/7867 +f 11649/11649/7435 11949/11949/7867 11650/11650/7615 +f 11948/11948/7866 11702/11702/7198 11705/11705/7666 +f 11948/11948/7866 11705/11705/7666 11949/11949/7867 +f 11949/11949/7867 11705/11705/7666 11710/11710/7670 +f 11949/11949/7867 11710/11710/7670 11950/11950/7868 +f 11650/11650/7615 11949/11949/7867 11950/11950/7868 +f 11650/11650/7615 11950/11950/7868 11651/11651/7616 +f 11651/11651/7616 11950/11950/7868 11951/11951/7869 +f 11651/11651/7616 11951/11951/7869 11656/11656/7621 +f 11950/11950/7868 11710/11710/7670 11712/11712/7672 +f 11950/11950/7868 11712/11712/7672 11951/11951/7869 +f 11951/11951/7869 11712/11712/7672 11298/11298/7361 +f 11951/11951/7869 11298/11298/7361 11297/11297/7360 +f 11656/11656/7621 11951/11951/7869 11297/11297/7360 +f 11656/11656/7621 11297/11297/7360 11657/11657/7359 +f 11952/11952/7870 11155/11155/7871 11953/11953/7872 +f 11952/11952/7870 11953/11953/7872 11954/11954/7873 +f 11155/11155/7871 11955/11955/7163 11956/11956/7874 +f 11155/11155/7871 11956/11956/7874 11953/11953/7872 +f 11953/11953/7872 11956/11956/7874 11957/11957/7875 +f 11953/11953/7872 11957/11957/7875 11958/11958/7876 +f 11954/11954/7873 11953/11953/7872 11958/11958/7876 +f 11954/11954/7873 11958/11958/7876 11959/11959/7877 +f 11959/11959/7877 11958/11958/7876 11960/11960/7878 +f 11959/11959/7877 11960/11960/7878 11961/11961/7879 +f 11958/11958/7876 11957/11957/7875 11962/11962/7880 +f 11958/11958/7876 11962/11962/7880 11960/11960/7878 +f 11960/11960/7878 11962/11962/7880 11963/11963/7881 +f 11960/11960/7878 11963/11963/7881 11964/11964/7882 +f 11961/11961/7879 11960/11960/7878 11964/11964/7882 +f 11961/11961/7879 11964/11964/7882 11965/11965/7883 +f 11966/11966/7225 11967/11967/7884 11968/11968/7885 +f 11966/11966/7225 11968/11968/7885 11969/11969/7886 +f 11967/11967/7884 11970/11970/7887 11971/11971/7888 +f 11967/11967/7884 11971/11971/7888 11968/11968/7885 +f 11968/11968/7885 11971/11971/7888 11972/11972/7658 +f 11968/11968/7885 11972/11972/7658 11973/11973/7889 +f 11969/11969/7886 11968/11968/7885 11973/11973/7889 +f 11969/11969/7886 11973/11973/7889 11974/11974/7890 +f 11974/11974/7890 11973/11973/7889 11975/11975/7891 +f 11974/11974/7890 11975/11975/7891 11976/11976/7892 +f 11973/11973/7889 11972/11972/7658 11977/11977/7893 +f 11973/11973/7889 11977/11977/7893 11975/11975/7891 +f 11975/11975/7891 11977/11977/7893 11978/11978/7366 +f 11975/11975/7891 11978/11978/7366 11979/11979/7894 +f 11976/11976/7892 11975/11975/7891 11979/11979/7894 +f 11976/11976/7892 11979/11979/7894 11980/11980/7895 +f 11981/11981/7896 11982/11982/7226 11983/11983/7897 +f 11981/11981/7896 11983/11983/7897 11984/11984/7898 +f 11982/11982/7226 11966/11966/7225 11969/11969/7886 +f 11982/11982/7226 11969/11969/7886 11983/11983/7897 +f 11983/11983/7897 11969/11969/7886 11974/11974/7890 +f 11983/11983/7897 11974/11974/7890 11985/11985/7899 +f 11984/11984/7898 11983/11983/7897 11985/11985/7899 +f 11984/11984/7898 11985/11985/7899 11986/11986/7900 +f 11986/11986/7900 11985/11985/7899 11987/11987/7901 +f 11986/11986/7900 11987/11987/7901 11988/11988/7902 +f 11985/11985/7899 11974/11974/7890 11976/11976/7892 +f 11985/11985/7899 11976/11976/7892 11987/11987/7901 +f 11987/11987/7901 11976/11976/7892 11980/11980/7895 +f 11987/11987/7901 11980/11980/7895 11989/11989/7903 +f 11988/11988/7902 11987/11987/7901 11989/11989/7903 +f 11988/11988/7902 11989/11989/7903 11990/11990/7904 +f 11534/11534/7905 11991/11991/7906 11992/11992/7907 +f 11534/11534/7905 11992/11992/7907 11993/11993/7908 +f 11991/11991/7906 11981/11981/7896 11984/11984/7898 +f 11991/11991/7906 11984/11984/7898 11992/11992/7907 +f 11992/11992/7907 11984/11984/7898 11986/11986/7900 +f 11992/11992/7907 11986/11986/7900 11994/11994/7909 +f 11993/11993/7908 11992/11992/7907 11994/11994/7909 +f 11993/11993/7908 11994/11994/7909 11995/11995/7910 +f 11995/11995/7910 11994/11994/7909 11996/11996/7911 +f 11995/11995/7910 11996/11996/7911 11997/11997/7912 +f 11994/11994/7909 11986/11986/7900 11988/11988/7902 +f 11994/11994/7909 11988/11988/7902 11996/11996/7911 +f 11996/11996/7911 11988/11988/7902 11990/11990/7904 +f 11996/11996/7911 11990/11990/7904 11998/11998/7218 +f 11997/11997/7912 11996/11996/7911 11998/11998/7218 +f 11997/11997/7912 11998/11998/7218 11999/11999/7913 +f 11408/11408/7566 12000/12000/7440 12001/12001/7914 +f 11408/11408/7566 12001/12001/7914 11802/11802/7751 +f 12000/12000/7440 12002/12002/7439 12003/12003/7915 +f 12000/12000/7440 12003/12003/7915 12001/12001/7914 +f 12001/12001/7914 12003/12003/7915 12004/12004/7730 +f 12001/12001/7914 12004/12004/7730 12005/12005/7916 +f 11802/11802/7751 12001/12001/7914 12005/12005/7916 +f 11802/11802/7751 12005/12005/7916 11803/11803/7752 +f 11810/11810/7758 12006/12006/7916 12007/12007/7917 +f 11810/11810/7758 12007/12007/7917 11811/11811/7759 +f 12006/12006/7916 11778/11778/7730 11780/11780/7732 +f 12006/12006/7916 11780/11780/7732 12007/12007/7917 +f 12007/12007/7917 11780/11780/7732 11784/11784/7331 +f 12007/12007/7917 11784/11784/7331 11258/11258/7918 +f 11811/11811/7759 12007/12007/7917 11258/11258/7918 +f 11811/11811/7759 11258/11258/7918 11812/11812/7760 +f 11819/11819/7444 12008/12008/7453 12009/12009/7919 +f 11819/11819/7444 12009/12009/7919 11820/11820/7764 +f 12008/12008/7453 12010/12010/7920 12011/12011/7921 +f 12008/12008/7453 12011/12011/7921 12009/12009/7919 +f 12009/12009/7919 12011/12011/7921 12012/12012/7922 +f 12009/12009/7919 12012/12012/7922 12013/12013/7923 +f 11820/11820/7764 12009/12009/7919 12013/12013/7923 +f 11820/11820/7764 12013/12013/7923 11821/11821/7765 +f 11821/11821/7765 12013/12013/7923 12014/12014/7924 +f 11821/11821/7765 12014/12014/7924 11826/11826/7770 +f 12013/12013/7923 12012/12012/7922 12015/12015/7925 +f 12013/12013/7923 12015/12015/7925 12014/12014/7924 +f 12014/12014/7924 12015/12015/7925 12016/12016/7926 +f 12014/12014/7924 12016/12016/7926 12017/12017/7205 +f 11826/11826/7770 12014/12014/7924 12017/12017/7205 +f 11826/11826/7770 12017/12017/7205 11827/11827/7771 +f 11693/11693/7654 12018/12018/7927 12019/12019/7928 +f 11693/11693/7654 12019/12019/7928 11694/11694/7655 +f 12018/12018/7927 11674/11674/7637 11677/11677/7639 +f 12018/12018/7927 11677/11677/7639 12019/12019/7928 +f 12019/12019/7928 11677/11677/7639 11682/11682/7643 +f 12019/12019/7928 11682/11682/7643 12020/12020/7929 +f 11694/11694/7655 12019/12019/7928 12020/12020/7929 +f 11694/11694/7655 12020/12020/7929 11695/11695/7656 +f 11695/11695/7656 12020/12020/7929 12021/12021/7930 +f 11695/11695/7656 12021/12021/7930 11700/11700/7661 +f 12020/12020/7929 11682/11682/7643 11684/11684/7645 +f 12020/12020/7929 11684/11684/7645 12021/12021/7930 +f 12021/12021/7930 11684/11684/7645 11688/11688/7649 +f 12021/12021/7930 11688/11688/7649 12022/12022/7371 +f 11700/11700/7661 12021/12021/7930 12022/12022/7371 +f 11700/11700/7661 12022/12022/7371 11527/11527/7662 +f 11774/11774/7726 12023/12023/7931 12024/12024/7932 +f 11774/11774/7726 12024/12024/7932 11775/11775/7727 +f 12023/12023/7931 11534/11534/7905 11993/11993/7908 +f 12023/12023/7931 11993/11993/7908 12024/12024/7932 +f 12024/12024/7932 11993/11993/7908 11995/11995/7910 +f 12024/12024/7932 11995/11995/7910 12025/12025/7933 +f 11775/11775/7727 12024/12024/7932 12025/12025/7933 +f 11775/11775/7727 12025/12025/7933 11776/11776/7728 +f 11776/11776/7728 12025/12025/7933 12026/12026/7934 +f 11776/11776/7728 12026/12026/7934 11781/11781/7733 +f 12025/12025/7933 11995/11995/7910 11997/11997/7912 +f 12025/12025/7933 11997/11997/7912 12026/12026/7934 +f 12026/12026/7934 11997/11997/7912 11999/11999/7913 +f 12026/12026/7934 11999/11999/7913 12027/12027/7192 +f 11781/11781/7733 12026/12026/7934 12027/12027/7192 +f 11781/11781/7733 12027/12027/7192 11782/11782/7191 +f 11788/11788/7738 12028/12028/7935 12029/12029/7936 +f 11788/11788/7738 12029/12029/7936 11789/11789/7739 +f 12028/12028/7935 11815/11815/7448 11818/11818/7763 +f 12028/12028/7935 11818/11818/7763 12029/12029/7936 +f 12029/12029/7936 11818/11818/7763 11823/11823/7767 +f 12029/12029/7936 11823/11823/7767 12030/12030/7937 +f 11789/11789/7739 12029/12029/7936 12030/12030/7937 +f 11789/11789/7739 12030/12030/7937 11790/11790/7740 +f 11790/11790/7740 12030/12030/7937 12031/12031/7938 +f 11790/11790/7740 12031/12031/7938 11795/11795/7745 +f 12030/12030/7937 11823/11823/7767 11825/11825/7769 +f 12030/12030/7937 11825/11825/7769 12031/12031/7938 +f 12031/12031/7938 11825/11825/7769 11244/11244/7319 +f 12031/12031/7938 11244/11244/7319 12032/12032/7318 +f 11795/11795/7745 12031/12031/7938 12032/12032/7318 +f 11795/11795/7745 12032/12032/7318 11796/11796/7317 +f 11528/11528/7939 12033/12033/7940 12034/12034/7941 +f 11528/11528/7939 12034/12034/7941 12035/12035/7942 +f 12033/12033/7940 11785/11785/7545 11787/11787/7737 +f 12033/12033/7940 11787/11787/7737 12034/12034/7941 +f 12034/12034/7941 11787/11787/7737 11792/11792/7742 +f 12034/12034/7941 11792/11792/7742 12036/12036/7943 +f 12035/12035/7942 12034/12034/7941 12036/12036/7943 +f 12035/12035/7942 12036/12036/7943 12037/12037/7944 +f 12037/12037/7944 12036/12036/7943 12038/12038/7945 +f 12037/12037/7944 12038/12038/7945 12039/12039/7946 +f 12036/12036/7943 11792/11792/7742 11794/11794/7744 +f 12036/12036/7943 11794/11794/7744 12038/12038/7945 +f 12038/12038/7945 11794/11794/7744 11797/11797/7178 +f 12038/12038/7945 11797/11797/7178 12040/12040/7947 +f 12039/12039/7946 12038/12038/7945 12040/12040/7947 +f 12039/12039/7946 12040/12040/7947 12041/12041/7173 +f 11938/11938/7152 12042/12042/7948 12043/12043/7949 +f 11938/11938/7152 12043/12043/7949 11939/11939/7858 +f 12042/12042/7948 11528/11528/7939 12035/12035/7942 +f 12042/12042/7948 12035/12035/7942 12043/12043/7949 +f 12043/12043/7949 12035/12035/7942 12037/12037/7944 +f 12043/12043/7949 12037/12037/7944 12044/12044/7950 +f 11939/11939/7858 12043/12043/7949 12044/12044/7950 +f 11939/11939/7858 12044/12044/7950 11940/11940/7859 +f 11940/11940/7859 12044/12044/7950 12045/12045/7951 +f 11940/11940/7859 12045/12045/7951 11945/11945/7864 +f 12044/12044/7950 12037/12037/7944 12039/12039/7946 +f 12044/12044/7950 12039/12039/7946 12045/12045/7951 +f 12045/12045/7951 12039/12039/7946 12041/12041/7173 +f 12045/12045/7951 12041/12041/7173 11057/11057/7172 +f 11945/11945/7864 12045/12045/7951 11057/11057/7172 +f 11945/11945/7864 11057/11057/7172 11946/11946/7171 +f 11137/11137/7237 12046/12046/7952 12047/12047/7953 +f 11137/11137/7237 12047/12047/7953 11731/11731/7688 +f 12046/12046/7952 11952/11952/7870 11954/11954/7873 +f 12046/12046/7952 11954/11954/7873 12047/12047/7953 +f 12047/12047/7953 11954/11954/7873 11959/11959/7877 +f 12047/12047/7953 11959/11959/7877 12048/12048/7954 +f 11731/11731/7688 12047/12047/7953 12048/12048/7954 +f 11731/11731/7688 12048/12048/7954 11732/11732/7689 +f 11732/11732/7689 12048/12048/7954 12049/12049/7955 +f 11732/11732/7689 12049/12049/7955 11737/11737/7694 +f 12048/12048/7954 11959/11959/7877 11961/11961/7879 +f 12048/12048/7954 11961/11961/7879 12049/12049/7955 +f 12049/12049/7955 11961/11961/7879 11965/11965/7883 +f 12049/12049/7955 11965/11965/7883 12050/12050/7956 +f 11737/11737/7694 12049/12049/7955 12050/12050/7956 +f 11737/11737/7694 12050/12050/7956 11738/11738/7695 +f 11759/11759/7713 11344/11344/7391 12051/12051/7957 +f 11759/11759/7713 12051/12051/7957 11760/11760/7714 +f 11344/11344/7391 11343/11343/7390 11648/11648/7614 +f 11344/11344/7391 11648/11648/7614 12051/12051/7957 +f 12051/12051/7957 11648/11648/7614 11653/11653/7618 +f 12051/12051/7957 11653/11653/7618 12052/12052/7958 +f 11760/11760/7714 12051/12051/7957 12052/12052/7958 +f 11760/11760/7714 12052/12052/7958 11761/11761/7715 +f 11761/11761/7715 12052/12052/7958 12053/12053/7959 +f 11761/11761/7715 12053/12053/7959 11766/11766/7720 +f 12052/12052/7958 11653/11653/7618 11655/11655/7620 +f 12052/12052/7958 11655/11655/7620 12053/12053/7959 +f 12053/12053/7959 11655/11655/7620 11659/11659/7623 +f 12053/12053/7959 11659/11659/7623 11324/11324/7960 +f 11766/11766/7720 12053/12053/7959 11324/11324/7960 +f 11766/11766/7720 11324/11324/7960 11767/11767/7335 +f 11955/11955/7163 12054/12054/7961 12055/12055/7962 +f 11955/11955/7163 12055/12055/7962 11956/11956/7874 +f 12054/12054/7961 11921/11921/7159 11924/11924/7846 +f 12054/12054/7961 11924/11924/7846 12055/12055/7962 +f 12055/12055/7962 11924/11924/7846 11926/11926/7848 +f 12055/12055/7962 11926/11926/7848 12056/12056/7963 +f 11956/11956/7874 12055/12055/7962 12056/12056/7963 +f 11956/11956/7874 12056/12056/7963 11957/11957/7875 +f 11957/11957/7875 12056/12056/7963 12057/12057/7964 +f 11957/11957/7875 12057/12057/7964 11962/11962/7880 +f 12056/12056/7963 11926/11926/7848 11928/11928/7850 +f 12056/12056/7963 11928/11928/7850 12057/12057/7964 +f 12057/12057/7964 11928/11928/7850 11929/11929/7151 +f 12057/12057/7964 11929/11929/7151 11030/11030/7965 +f 11962/11962/7880 12057/12057/7964 11030/11030/7965 +f 11962/11962/7880 11030/11030/7965 11963/11963/7881 +f 11706/11706/7194 12058/12058/7966 12059/12059/7967 +f 11706/11706/7194 12059/12059/7967 11707/11707/7667 +f 12058/12058/7966 12060/12060/7156 12061/12061/7968 +f 12058/12058/7966 12061/12061/7968 12059/12059/7967 +f 12059/12059/7967 12061/12061/7968 12062/12062/7969 +f 12059/12059/7967 12062/12062/7969 12063/12063/7970 +f 11707/11707/7667 12059/12059/7967 12063/12063/7970 +f 11707/11707/7667 12063/12063/7970 11708/11708/7668 +f 11708/11708/7668 12063/12063/7970 12064/12064/7971 +f 11708/11708/7668 12064/12064/7971 11713/11713/7673 +f 12063/12063/7970 12062/12062/7969 12065/12065/7863 +f 12063/12063/7970 12065/12065/7863 12064/12064/7971 +f 12064/12064/7971 12065/12065/7863 11154/11154/7564 +f 12064/12064/7971 11154/11154/7564 12066/12066/7972 +f 11713/11713/7673 12064/12064/7971 12066/12066/7972 +f 11713/11713/7673 12066/12066/7972 11152/11152/7516 +f 12010/12010/7920 12067/12067/7574 12068/12068/7973 +f 12010/12010/7920 12068/12068/7973 12011/12011/7921 +f 12067/12067/7574 12069/12069/7974 12070/12070/7975 +f 12067/12067/7574 12070/12070/7975 12068/12068/7973 +f 12068/12068/7973 12070/12070/7975 12071/12071/7976 +f 12068/12068/7973 12071/12071/7976 12072/12072/7977 +f 12011/12011/7921 12068/12068/7973 12072/12072/7977 +f 12011/12011/7921 12072/12072/7977 12012/12012/7922 +f 12012/12012/7922 12072/12072/7977 12073/12073/7978 +f 12012/12012/7922 12073/12073/7978 12015/12015/7925 +f 12072/12072/7977 12071/12071/7976 12074/12074/7979 +f 12072/12072/7977 12074/12074/7979 12073/12073/7978 +f 12073/12073/7978 12074/12074/7979 11000/11000/7980 +f 12073/12073/7978 11000/11000/7980 12075/12075/7981 +f 12015/12015/7925 12073/12073/7978 12075/12075/7981 +f 12015/12015/7925 12075/12075/7981 12016/12016/7926 +f 11433/11433/7461 12076/12076/7578 12077/12077/7982 +f 11433/11433/7461 12077/12077/7982 12078/12078/7983 +f 12076/12076/7578 11798/11798/7747 11801/11801/7750 +f 12076/12076/7578 11801/11801/7750 12077/12077/7982 +f 12077/12077/7982 11801/11801/7750 11805/11805/7754 +f 12077/12077/7982 11805/11805/7754 12079/12079/7984 +f 12078/12078/7983 12077/12077/7982 12079/12079/7984 +f 12078/12078/7983 12079/12079/7984 12080/12080/7985 +f 12081/12081/7985 12082/12082/7984 12083/12083/7986 +f 12081/12081/7985 12083/12083/7986 12084/12084/7987 +f 12082/12082/7984 11806/11806/7755 11809/11809/7757 +f 12082/12082/7984 11809/11809/7757 12083/12083/7986 +f 12083/12083/7986 11809/11809/7757 11814/11814/7132 +f 12083/12083/7986 11814/11814/7132 12085/12085/7988 +f 12084/12084/7987 12083/12083/7986 12085/12085/7988 +f 12084/12084/7987 12085/12085/7988 12086/12086/7989 +f 12069/12069/7974 12087/12087/7582 12088/12088/7990 +f 12069/12069/7974 12088/12088/7990 12070/12070/7975 +f 12087/12087/7582 12089/12089/7991 12090/12090/7992 +f 12087/12087/7582 12090/12090/7992 12088/12088/7990 +f 12088/12088/7990 12090/12090/7992 12091/12091/7993 +f 12088/12088/7990 12091/12091/7993 12092/12092/7994 +f 12070/12070/7975 12088/12088/7990 12092/12092/7994 +f 12070/12070/7975 12092/12092/7994 12071/12071/7976 +f 12071/12071/7976 12092/12092/7994 12093/12093/7995 +f 12071/12071/7976 12093/12093/7995 12074/12074/7979 +f 12092/12092/7994 12091/12091/7993 12094/12094/7996 +f 12092/12092/7994 12094/12094/7996 12093/12093/7995 +f 12093/12093/7995 12094/12094/7996 12095/12095/7997 +f 12093/12093/7995 12095/12095/7997 12096/12096/7127 +f 12074/12074/7979 12093/12093/7995 12096/12096/7127 +f 12074/12074/7979 12096/12096/7127 11000/11000/7980 +f 12097/12097/7591 12098/12098/7998 12099/12099/7999 +f 12097/12097/7591 12099/12099/7999 12100/12100/8000 +f 12098/12098/7998 11433/11433/7461 12078/12078/7983 +f 12098/12098/7998 12078/12078/7983 12099/12099/7999 +f 12099/12099/7999 12078/12078/7983 12080/12080/7985 +f 12099/12099/7999 12080/12080/7985 12101/12101/8001 +f 12100/12100/8000 12099/12099/7999 12101/12101/8001 +f 12100/12100/8000 12101/12101/8001 12102/12102/8002 +f 12103/12103/8003 12104/12104/8001 12105/12105/8004 +f 12103/12103/8003 12105/12105/8004 12106/12106/8005 +f 12104/12104/8001 12081/12081/7985 12084/12084/7987 +f 12104/12104/8001 12084/12084/7987 12105/12105/8004 +f 12105/12105/8004 12084/12084/7987 12086/12086/7989 +f 12105/12105/8004 12086/12086/7989 12107/12107/8006 +f 12106/12106/8005 12105/12105/8004 12107/12107/8006 +f 12106/12106/8005 12107/12107/8006 12108/12108/8007 +f 12089/12089/7991 12109/12109/7469 12110/12110/8008 +f 12089/12089/7991 12110/12110/8008 12090/12090/7992 +f 12109/12109/7469 12111/12111/7468 12112/12112/8009 +f 12109/12109/7469 12112/12112/8009 12110/12110/8008 +f 12110/12110/8008 12112/12112/8009 12113/12113/8010 +f 12110/12110/8008 12113/12113/8010 12114/12114/8011 +f 12090/12090/7992 12110/12110/8008 12114/12114/8011 +f 12090/12090/7992 12114/12114/8011 12091/12091/7993 +f 12091/12091/7993 12114/12114/8011 12115/12115/8012 +f 12091/12091/7993 12115/12115/8012 12094/12094/7996 +f 12114/12114/8011 12113/12113/8010 12116/12116/8013 +f 12114/12114/8011 12116/12116/8013 12115/12115/8012 +f 12115/12115/8012 12116/12116/8013 12117/12117/8014 +f 12115/12115/8012 12117/12117/8014 12118/12118/7103 +f 12094/12094/7996 12115/12115/8012 12118/12118/7103 +f 12094/12094/7996 12118/12118/7103 12095/12095/7997 +f 11848/11848/7595 12119/12119/8015 12120/12120/8016 +f 11848/11848/7595 12120/12120/8016 11849/11849/7787 +f 12119/12119/8015 12121/12121/7591 12100/12100/8000 +f 12119/12119/8015 12100/12100/8000 12120/12120/8016 +f 12120/12120/8016 12100/12100/8000 12103/12103/8003 +f 12120/12120/8016 12103/12103/8003 12122/12122/8017 +f 11849/11849/7787 12120/12120/8016 12122/12122/8017 +f 11849/11849/7787 12122/12122/8017 11850/11850/7788 +f 11850/11850/7788 12122/12122/8017 12123/12123/8018 +f 11850/11850/7788 12123/12123/8018 11855/11855/7793 +f 12122/12122/8017 12103/12103/8003 12106/12106/8005 +f 12122/12122/8017 12106/12106/8005 12123/12123/8018 +f 12123/12123/8018 12106/12106/8005 12108/12108/8007 +f 12123/12123/8018 12108/12108/8007 12124/12124/8019 +f 11855/11855/7793 12123/12123/8018 12124/12124/8019 +f 11855/11855/7793 12124/12124/8019 11856/11856/7110 +f 12111/12111/7468 12125/12125/7597 12126/12126/8020 +f 12111/12111/7468 12126/12126/8020 12112/12112/8009 +f 12125/12125/7597 11829/11829/7772 11832/11832/7774 +f 12125/12125/7597 11832/11832/7774 12126/12126/8020 +f 12126/12126/8020 11832/11832/7774 11837/11837/7778 +f 12126/12126/8020 11837/11837/7778 12127/12127/8021 +f 12112/12112/8009 12126/12126/8020 12127/12127/8021 +f 12112/12112/8009 12127/12127/8021 12113/12113/8010 +f 12113/12113/8010 12127/12127/8021 12128/12128/8022 +f 12113/12113/8010 12128/12128/8022 12116/12116/8013 +f 12127/12127/8021 11837/11837/7778 11839/11839/7780 +f 12127/12127/8021 11839/11839/7780 12128/12128/8022 +f 12128/12128/8022 11839/11839/7780 11843/11843/7309 +f 12128/12128/8022 11843/11843/7309 12129/12129/8023 +f 12116/12116/8013 12128/12128/8022 12129/12129/8023 +f 12116/12116/8013 12129/12129/8023 12117/12117/8014 +f 11622/11622/7595 12130/12130/8024 12131/12131/8025 +f 11622/11622/7595 12131/12131/8025 11623/11623/7596 +f 12130/12130/8024 11844/11844/7783 12132/12132/7209 +f 12130/12130/8024 12132/12132/7209 12131/12131/8025 +f 12131/12131/8025 12132/12132/7209 11106/11106/7214 +f 12131/12131/8025 11106/11106/7214 12133/12133/7017 +f 11623/11623/7596 12131/12131/8025 12133/12133/7017 +f 11623/11623/7596 12133/12133/7017 11624/11624/6405 +o Cylinder.029__0 +v -1.582944 2.840136 0.040562 +v -1.532300 2.855240 0.065975 +v -1.515311 2.865280 0.049087 +v -1.583123 2.845056 0.015059 +v -1.498393 2.821164 0.114342 +v -1.519681 2.823409 0.059746 +v -1.502692 2.833449 0.042858 +v -1.474188 2.830443 0.115962 +v -1.633280 2.816531 0.059218 +v -1.650522 2.813448 0.040039 +v -1.511012 2.852996 0.120571 +v -1.531552 2.834717 0.172367 +v -1.514310 2.837800 0.191546 +v -1.486807 2.862275 0.122191 +v -1.518933 2.802886 0.166138 +v -1.501691 2.805968 0.185317 +v -1.581887 2.811112 0.191023 +v -1.632531 2.796008 0.165610 +v -1.649521 2.785968 0.182498 +v -1.581708 2.806192 0.216526 +v -1.628834 2.817326 0.064163 +v -1.647577 2.800645 0.111432 +v -1.660321 2.832792 0.117723 +v -1.641578 2.849473 0.070454 +v -1.569268 2.779281 0.184794 +v -1.569089 2.774361 0.210297 +v -1.619912 2.764176 0.159381 +v -1.636902 2.754137 0.176269 +v -1.615158 2.770821 0.050273 +v -1.620661 2.784699 0.052989 +v -1.570325 2.808305 0.034333 +v -1.564823 2.794426 0.031617 +v -1.635698 2.752542 0.102070 +v -1.641200 2.766421 0.104785 +v -1.620661 2.784699 0.052989 +v -1.615158 2.770821 0.050273 +v -1.614410 2.750298 0.156665 +v -1.619912 2.764176 0.159381 +v -1.563766 2.765402 0.182078 +v -1.569268 2.779281 0.184794 +v -1.619912 2.764176 0.159381 +v -1.614410 2.750298 0.156665 +v -1.513430 2.789007 0.163423 +v -1.518933 2.802886 0.166138 +v -1.569268 2.779281 0.184794 +v -1.563766 2.765402 0.182078 +v -1.492891 2.807286 0.111626 +v -1.498393 2.821164 0.114342 +v -1.514179 2.809530 0.057030 +v -1.519681 2.823409 0.059746 +v -1.498393 2.821164 0.114342 +v -1.492891 2.807286 0.111626 +v -1.570504 2.813224 0.008830 +v -1.583123 2.845056 0.015059 +v -1.515311 2.865280 0.049087 +v -1.502692 2.833449 0.042858 +v -1.502692 2.833449 0.042858 +v -1.515311 2.865280 0.049087 +v -1.486807 2.862275 0.122191 +v -1.474188 2.830443 0.115962 +v -1.514310 2.837800 0.191546 +v -1.501691 2.805968 0.185317 +v -1.581708 2.806192 0.216526 +v -1.569089 2.774361 0.210297 +v -1.569089 2.774361 0.210297 +v -1.581708 2.806192 0.216526 +v -1.649521 2.785968 0.182498 +v -1.636902 2.754137 0.176269 +v -1.636902 2.754137 0.176269 +v -1.649521 2.785968 0.182498 +v -1.678024 2.788973 0.109395 +v -1.665405 2.757142 0.103166 +v -1.650522 2.813448 0.040039 +v -1.637902 2.781617 0.033810 +v -1.637902 2.781617 0.033810 +v -1.650522 2.813448 0.040039 +v -1.570325 2.808305 0.034333 +v -1.570504 2.813224 0.008830 +v -1.653819 2.798252 0.111014 +v -1.678024 2.788973 0.109395 +v -1.620661 2.784699 0.052989 +v -1.637902 2.781617 0.033810 +v -1.641200 2.766421 0.104785 +v -1.665405 2.757142 0.103166 +v -1.582898 2.838867 0.047138 +v -1.536680 2.852651 0.070330 +v -1.517254 2.850603 0.120153 +v -1.535998 2.833922 0.167422 +v -1.581933 2.812380 0.184447 +v -1.628151 2.798596 0.161255 +v -1.647577 2.800645 0.111432 +v -1.628834 2.817326 0.064163 +v -1.628151 2.798596 0.161255 +v -1.581933 2.812380 0.184447 +v -1.594678 2.844528 0.190738 +v -1.640896 2.830744 0.167546 +v -1.535998 2.833922 0.167422 +v -1.517254 2.850603 0.120153 +v -1.529998 2.882751 0.126444 +v -1.548743 2.866070 0.173713 +v -1.536680 2.852651 0.070330 +v -1.582898 2.838867 0.047138 +v -1.595642 2.871015 0.053429 +v -1.549425 2.884799 0.076621 +v -1.628834 2.817326 0.064163 +v -1.641578 2.849473 0.070454 +v -1.628151 2.798596 0.161255 +v -1.640896 2.830744 0.167546 +v -1.581933 2.812380 0.184447 +v -1.594678 2.844528 0.190738 +v -1.517254 2.850603 0.120153 +v -1.529998 2.882751 0.126444 +v -1.595521 2.867677 0.070734 +v -1.560953 2.877986 0.088080 +v -1.549425 2.884799 0.076621 +v -1.595642 2.871015 0.053429 +v -1.546423 2.876454 0.125345 +v -1.529998 2.882751 0.126444 +v -1.560442 2.863978 0.160699 +v -1.548743 2.866070 0.173713 +v -1.594799 2.847866 0.173433 +v -1.594678 2.844528 0.190738 +v -1.629367 2.837557 0.156087 +v -1.640896 2.830744 0.167546 +v -1.643897 2.839088 0.118822 +v -1.660321 2.832792 0.117723 +v -1.629878 2.851565 0.083468 +v -1.641578 2.849473 0.070454 +v -1.258877 2.165534 -0.068991 +v -1.237589 2.163290 -0.014395 +v 0.137933 -1.500753 -0.808891 +v -1.297429 2.119928 -0.100373 +v -1.246784 2.135032 -0.074960 +v 0.188577 -1.485649 -0.783478 +v -1.237589 2.163290 -0.014395 +v -1.258128 2.145011 0.037401 +v -1.308464 2.121406 0.056057 +v -1.308464 2.121406 0.056057 +v -1.359108 2.106302 0.030644 +v -1.359108 2.106302 0.030644 +v -1.380396 2.108546 -0.023952 +v -1.359856 2.126825 -0.075748 +v -1.564823 2.794426 0.031617 +v -1.309521 2.150430 -0.094404 +v 0.209865 -1.487893 -0.728882 +v -1.225497 2.132787 -0.020364 +v -1.246036 2.114509 0.031432 +v 0.189325 -1.506172 -0.677086 +v -1.309521 2.150430 -0.094404 +v -1.296372 2.090904 0.050088 +v 0.138990 -1.529777 -0.658430 +v 0.138990 -1.529777 -0.658430 +v -1.296372 2.090904 0.050088 +v -1.347016 2.075799 0.024675 +v 0.088345 -1.544881 -0.683843 +v -1.368304 2.078044 -0.029921 +v 0.067058 -1.542637 -0.738439 +v 0.067058 -1.542637 -0.738439 +v -1.368304 2.078044 -0.029921 +v -1.347764 2.096322 -0.081717 +v 0.087597 -1.524358 -0.790235 +v -1.297429 2.119928 -0.100373 +v 0.137933 -1.500753 -0.808891 +v -1.309763 2.157073 -0.128839 +v -1.235937 2.179090 -0.091793 +v -1.223845 2.148588 -0.097762 +v -1.297671 2.126570 -0.134808 +v -1.359856 2.126825 -0.075748 +v -1.309521 2.150430 -0.094404 +v -1.309763 2.157073 -0.128839 +v -1.383137 2.122663 -0.101644 +v -1.237589 2.163290 -0.014395 +v -1.258128 2.145011 0.037401 +v -1.234847 2.149174 0.063297 +v -1.204906 2.175818 -0.012208 +v -1.347764 2.096322 -0.081717 +v -1.368304 2.078044 -0.029921 +v -1.400986 2.065515 -0.032108 +v -1.371045 2.092160 -0.107613 +v -1.225497 2.132787 -0.020364 +v -1.246784 2.135032 -0.074960 +v -1.223845 2.148588 -0.097762 +v -1.192814 2.145316 -0.018177 +v -1.308464 2.121406 0.056057 +v -1.359108 2.106302 0.030644 +v -1.382048 2.092746 0.053447 +v -1.308222 2.114764 0.090492 +v -1.296372 2.090904 0.050088 +v -1.246036 2.114509 0.031432 +v -1.222755 2.118671 0.057328 +v -1.296129 2.084261 0.084523 +v -1.380396 2.108546 -0.023952 +v -1.413079 2.096018 -0.026139 +v -1.258877 2.165534 -0.068991 +v -1.235937 2.179090 -0.091793 +v -1.225497 2.132787 -0.020364 +v 0.209865 -1.487893 -0.728882 +v -1.204906 2.175818 -0.012208 +v -1.192814 2.145316 -0.018177 +v -1.204906 2.175818 -0.012208 +v -1.234847 2.149174 0.063297 +v -1.222755 2.118671 0.057328 +v -1.192814 2.145316 -0.018177 +v -1.308222 2.114764 0.090492 +v -1.296129 2.084261 0.084523 +v -1.308222 2.114764 0.090492 +v -1.382048 2.092746 0.053447 +v -1.369956 2.062243 0.047477 +v -1.296129 2.084261 0.084523 +v -1.382048 2.092746 0.053447 +v -1.413079 2.096018 -0.026139 +v -1.400986 2.065515 -0.032108 +v -1.369956 2.062243 0.047477 +v -1.383137 2.122663 -0.101644 +v -1.371045 2.092160 -0.107613 +v -1.383137 2.122663 -0.101644 +v -1.371045 2.092160 -0.107613 +v -1.347016 2.075799 0.024675 +v -1.369956 2.062243 0.047477 +v -1.297429 2.119928 -0.100373 +v -1.297671 2.126570 -0.134808 +v 0.137933 -1.500753 -0.808891 +v 0.188577 -1.485649 -0.783478 +v 0.209865 -1.487893 -0.728882 +v 0.189325 -1.506172 -0.677086 +v 0.138990 -1.529777 -0.658430 +v 0.088345 -1.544881 -0.683843 +v 0.067058 -1.542637 -0.738439 +v 0.087597 -1.524358 -0.790235 +vt 0.818405 0.867038 +vt 0.821473 0.870105 +vt 0.823247 0.869370 +vt 0.819141 0.865264 +vt 0.842787 0.405755 +vt 0.838449 0.405755 +vt 0.837714 0.407529 +vt 0.843522 0.407529 +vt 0.814068 0.867038 +vt 0.813333 0.865264 +vt 0.821473 0.874441 +vt 0.818405 0.877507 +vt 0.819141 0.879282 +vt 0.823247 0.875176 +vt 0.845854 0.402689 +vt 0.847629 0.403424 +vt 0.814068 0.877507 +vt 0.811001 0.874441 +vt 0.809226 0.875176 +vt 0.813333 0.879282 +vt 0.845854 0.398352 +vt 0.847629 0.397617 +vt 0.842787 0.395286 +vt 0.843522 0.393511 +vt 0.835382 0.402689 +vt 0.833607 0.403424 +vt 0.811001 0.870105 +vt 0.809226 0.869370 +vt 0.835382 0.398352 +vt 0.833607 0.397617 +vt 0.838449 0.395286 +vt 0.837714 0.393511 +vt 0.818216 0.867496 +vt 0.821015 0.870294 +vt 0.821015 0.874251 +vt 0.818216 0.877050 +vt 0.814258 0.877050 +vt 0.811459 0.874251 +vt 0.811459 0.870294 +vt 0.814258 0.867496 +vt 0.494893 0.776826 +vt 0.497854 0.776826 +vt 0.498353 0.775622 +vt 0.494394 0.775622 +vt 0.499947 0.778919 +vt 0.501152 0.778421 +vt 0.499947 0.781879 +vt 0.501152 0.782378 +vt 0.497854 0.783972 +vt 0.498353 0.785176 +vt 0.494893 0.783972 +vt 0.494394 0.785176 +vt 0.492800 0.781879 +vt 0.491595 0.782378 +vt 0.492800 0.778919 +vt 0.491595 0.778421 +vt 0.800364 0.788292 +vt 0.796026 0.788292 +vt 0.795033 0.790688 +vt 0.801356 0.790688 +vt 0.792959 0.780890 +vt 0.796026 0.777823 +vt 0.795033 0.775427 +vt 0.790562 0.779897 +vt 0.808529 0.785226 +vt 0.808529 0.780890 +vt 0.806132 0.779897 +vt 0.806132 0.786219 +vt 0.819001 0.785226 +vt 0.815934 0.788292 +vt 0.816926 0.790688 +vt 0.821397 0.786219 +vt 0.800364 0.777823 +vt 0.803431 0.780890 +vt 0.805827 0.779897 +vt 0.801356 0.775427 +vt 0.815934 0.777823 +vt 0.819001 0.780890 +vt 0.821397 0.779897 +vt 0.816926 0.775427 +vt 0.803431 0.785226 +vt 0.805827 0.786219 +vt 0.792959 0.785226 +vt 0.790562 0.786219 +vt 0.811596 0.777823 +vt 0.810603 0.775427 +vt 0.811596 0.788292 +vt 0.810603 0.790688 +vt 0.452583 0.777764 +vt 0.449516 0.785167 +vt 0.452583 0.782101 +vt 0.449516 0.774698 +vt 0.445178 0.785167 +vt 0.442111 0.782101 +vt 0.445178 0.774698 +vt 0.442111 0.777764 +vt 0.928956 0.418086 +vt 0.928956 0.414128 +vt 0.926356 0.414128 +vt 0.926356 0.418086 +vt 0.419496 0.168347 +vt 0.419496 0.169469 +vt 0.422563 0.169469 +vt 0.422563 0.168347 +vt 0.983150 0.091883 +vt 0.983150 0.090761 +vt 0.978812 0.090761 +vt 0.978812 0.091883 +vt 0.986217 0.091883 +vt 0.986217 0.090761 +vt 0.731136 0.149672 +vt 0.731136 0.150794 +vt 0.735473 0.150794 +vt 0.735473 0.149672 +vt 0.707085 0.851313 +vt 0.707085 0.852435 +vt 0.710152 0.852435 +vt 0.710152 0.851313 +vt 0.702748 0.851313 +vt 0.702747 0.852435 +vt 0.426901 0.168347 +vt 0.426901 0.169469 +vt 0.429968 0.169469 +vt 0.429968 0.168347 +vt 0.141381 0.095056 +vt 0.143955 0.095056 +vt 0.143955 0.089249 +vt 0.141381 0.089249 +vt 0.754336 0.015008 +vt 0.756910 0.015008 +vt 0.756910 0.010903 +vt 0.754336 0.010903 +vt 0.756910 0.005096 +vt 0.754336 0.005096 +vt 0.756910 0.000990 +vt 0.754336 0.000990 +vt 0.801516 0.590039 +vt 0.804090 0.590039 +vt 0.804090 0.584232 +vt 0.801516 0.584232 +vt 0.297381 0.091326 +vt 0.299955 0.091326 +vt 0.299955 0.087221 +vt 0.297381 0.087221 +vt 0.299955 0.081414 +vt 0.297381 0.081414 +vt 0.141381 0.099162 +vt 0.143955 0.099162 +vt 0.071677 0.115655 +vt 0.071677 0.111698 +vt 0.069078 0.111698 +vt 0.069078 0.115655 +vt 0.924826 0.537764 +vt 0.924826 0.541722 +vt 0.927426 0.541722 +vt 0.927426 0.537764 +vt 0.885376 0.586846 +vt 0.885376 0.590804 +vt 0.887976 0.590804 +vt 0.887976 0.586846 +vt 0.885376 0.593602 +vt 0.887976 0.593602 +vt 0.928956 0.411330 +vt 0.926356 0.411330 +vt 0.924826 0.534966 +vt 0.927426 0.534966 +vt 0.885376 0.584048 +vt 0.887976 0.584048 +vt 0.426901 0.116279 +vt 0.429968 0.116279 +vt 0.888076 0.434742 +vt 0.888076 0.727478 +vt 0.892413 0.727478 +vt 0.892413 0.434742 +vt 0.702748 0.799245 +vt 0.707085 0.799245 +vt 0.710152 0.799245 +vt 0.731136 0.097605 +vt 0.735473 0.097605 +vt 0.986217 0.143951 +vt 0.983150 0.143951 +vt 0.978812 0.143951 +vt 0.975745 0.091883 +vt 0.975745 0.143951 +vt 0.897664 0.403727 +vt 0.897664 0.110991 +vt 0.893326 0.110991 +vt 0.893326 0.403727 +vt 0.422563 0.116280 +vt 0.890259 0.110991 +vt 0.890259 0.403727 +vt 0.882707 0.110991 +vt 0.882706 0.403727 +vt 0.887044 0.403727 +vt 0.887044 0.110991 +vt 0.890111 0.403727 +vt 0.890111 0.110991 +vt 0.681661 0.407630 +vt 0.681661 0.114894 +vt 0.677324 0.114894 +vt 0.677324 0.407630 +vt 0.674256 0.114894 +vt 0.674256 0.407630 +vt 0.997051 0.281695 +vt 0.997051 0.288017 +vt 0.999518 0.288017 +vt 0.999518 0.281695 +vt 0.895480 0.727478 +vt 0.895480 0.434742 +vt 0.997051 0.292486 +vt 0.999518 0.292486 +vt 0.735492 0.096965 +vt 0.735492 0.090644 +vt 0.733025 0.090644 +vt 0.733025 0.096965 +vt 0.735492 0.086174 +vt 0.733025 0.086174 +vt 0.939715 0.541726 +vt 0.939715 0.535405 +vt 0.937248 0.535405 +vt 0.937248 0.541726 +vt 0.918870 0.407254 +vt 0.918870 0.411724 +vt 0.921336 0.411724 +vt 0.921336 0.407254 +vt 0.918870 0.418045 +vt 0.921336 0.418045 +vt 0.997051 0.277226 +vt 0.999518 0.277226 +vn -0.3626 0.9146 0.1790 +vn 0.3626 -0.9146 -0.1790 +vn -0.3626 0.9146 0.1789 +vn -0.6639 -0.1187 -0.7384 +vn -0.9319 -0.3572 -0.0624 +vn -0.6638 -0.1187 -0.7384 +vn -0.0069 0.1894 -0.9819 +vn -0.9319 -0.3573 -0.0624 +vn -0.6541 -0.3866 0.6502 +vn 0.0069 -0.1894 0.9819 +vn -0.6541 -0.3865 0.6502 +vn 0.6638 0.1187 0.7384 +vn 0.9319 0.3572 0.0623 +vn 0.9319 0.3572 0.0624 +vn 0.6541 0.3865 -0.6502 +vn 0.9319 0.3573 0.0624 +vn 0.6541 0.3866 -0.6502 +vn 0.6639 0.1187 0.7384 +vn -0.6540 -0.3867 0.6502 +vn -0.6541 -0.3864 0.6502 +vn 0.0068 -0.1893 0.9819 +vn -0.9319 -0.3572 -0.0623 +vn -0.9319 -0.3574 -0.0624 +vn 0.9319 0.3574 0.0624 +usemtl Scene_-_Root +s off +f 12134/12134/8026 12135/12135/8026 12136/12136/8026 +f 12134/12134/8026 12136/12136/8026 12137/12137/8026 +f 12138/12138/8027 12139/12139/8027 12140/12140/8027 +f 12138/12138/8027 12140/12140/8027 12141/12141/8027 +f 12142/12142/8026 12134/12134/8026 12137/12137/8026 +f 12142/12142/8026 12137/12137/8026 12143/12143/8026 +f 12144/12144/8026 12145/12145/8026 12146/12146/8026 +f 12144/12144/8026 12146/12146/8026 12147/12147/8026 +f 12148/12148/8027 12138/12138/8027 12141/12141/8027 +f 12148/12148/8027 12141/12141/8027 12149/12149/8027 +f 12150/12150/8026 12151/12151/8026 12152/12152/8026 +f 12150/12150/8026 12152/12152/8026 12153/12153/8026 +f 12158/12154/8027 12148/12148/8027 12149/12149/8027 +f 12158/12154/8027 12149/12149/8027 12159/12155/8027 +f 12160/12156/8027 12158/12154/8027 12159/12155/8027 +f 12160/12156/8027 12159/12155/8027 12161/12157/8027 +f 12139/12139/8027 12210/12158/8027 12211/12159/8027 +f 12139/12139/8027 12211/12159/8027 12140/12140/8027 +f 12151/12151/8026 12212/12160/8026 12213/12161/8026 +f 12151/12151/8026 12213/12161/8026 12152/12152/8026 +f 12210/12158/8027 12214/12162/8027 12215/12163/8027 +f 12210/12158/8027 12215/12163/8027 12211/12159/8027 +f 12214/12162/8027 12216/12164/8027 12217/12165/8027 +f 12214/12162/8027 12217/12165/8027 12215/12163/8027 +f 12145/12145/8026 12150/12150/8026 12153/12153/8026 +f 12145/12145/8026 12153/12153/8026 12146/12146/8026 +f 12216/12164/8027 12160/12156/8027 12161/12157/8027 +f 12216/12164/8027 12161/12157/8027 12217/12165/8027 +f 12135/12135/8026 12144/12144/8026 12147/12147/8026 +f 12135/12135/8026 12147/12147/8026 12136/12136/8026 +f 12212/12160/8026 12142/12142/8026 12143/12143/8026 +f 12212/12160/8026 12143/12143/8026 12213/12161/8026 +f 12218/12166/8026 12219/12167/8026 12135/12135/8026 +f 12218/12166/8026 12135/12135/8026 12134/12134/8026 +f 12219/12167/8026 12220/12168/8026 12144/12144/8026 +f 12219/12167/8026 12144/12144/8026 12135/12135/8026 +f 12220/12168/8026 12221/12169/8026 12145/12145/8026 +f 12220/12168/8026 12145/12145/8026 12144/12144/8026 +f 12221/12169/8026 12222/12170/8026 12150/12150/8026 +f 12221/12169/8026 12150/12150/8026 12145/12145/8026 +f 12222/12170/8026 12223/12171/8026 12151/12151/8026 +f 12222/12170/8026 12151/12151/8026 12150/12150/8026 +f 12223/12171/8026 12224/12172/8026 12212/12160/8026 +f 12223/12171/8026 12212/12160/8026 12151/12151/8026 +f 12224/12172/8026 12225/12173/8026 12142/12142/8026 +f 12224/12172/8026 12142/12142/8026 12212/12160/8026 +f 12225/12173/8026 12218/12166/8026 12134/12134/8026 +f 12225/12173/8026 12134/12134/8026 12142/12142/8026 +f 12246/12174/8026 12247/12175/8026 12248/12176/8026 +f 12246/12174/8026 12248/12176/8026 12249/12177/8026 +f 12247/12175/8026 12250/12178/8026 12251/12179/8026 +f 12247/12175/8026 12251/12179/8026 12248/12176/8026 +f 12250/12178/8026 12252/12180/8026 12253/12181/8026 +f 12250/12178/8026 12253/12181/8026 12251/12179/8026 +f 12252/12180/8026 12254/12182/8026 12255/12183/8026 +f 12252/12180/8026 12255/12183/8026 12253/12181/8026 +f 12254/12182/8026 12256/12184/8026 12257/12185/8026 +f 12254/12182/8028 12257/12185/8028 12255/12183/8028 +f 12256/12184/8026 12258/12186/8026 12259/12187/8026 +f 12256/12184/8026 12259/12187/8026 12257/12185/8026 +f 12258/12186/8026 12260/12188/8026 12261/12189/8026 +f 12258/12186/8026 12261/12189/8026 12259/12187/8026 +f 12260/12188/8026 12246/12174/8026 12249/12177/8026 +f 12260/12188/8028 12249/12177/8028 12261/12189/8028 +f 12301/12190/8026 12302/12191/8026 12303/12192/8026 +f 12301/12190/8026 12303/12192/8026 12304/12193/8026 +f 12305/12194/8026 12306/12195/8026 12307/12196/8026 +f 12305/12194/8026 12307/12196/8026 12308/12197/8026 +f 12309/12198/8027 12310/12199/8027 12311/12200/8027 +f 12309/12198/8027 12311/12200/8027 12312/12201/8027 +f 12313/12202/8027 12314/12203/8027 12315/12204/8027 +f 12313/12202/8027 12315/12204/8027 12316/12205/8027 +f 12317/12206/8028 12318/12207/8028 12319/12208/8028 +f 12317/12206/8026 12319/12208/8026 12320/12209/8026 +f 12321/12210/8027 12322/12211/8027 12323/12212/8027 +f 12321/12210/8027 12323/12212/8027 12324/12213/8027 +f 12325/12214/8026 12301/12190/8026 12304/12193/8026 +f 12325/12214/8026 12304/12193/8026 12326/12215/8026 +f 12327/12216/8026 12305/12194/8026 12308/12197/8026 +f 12327/12216/8026 12308/12197/8026 12328/12217/8026 +f 12351/12218/8027 12321/12210/8027 12324/12213/8027 +f 12351/12218/8027 12324/12213/8027 12352/12219/8027 +f 12353/12220/8027 12309/12198/8027 12312/12201/8027 +f 12353/12220/8027 12312/12201/8027 12354/12221/8027 +f 12302/12191/8026 12327/12216/8026 12328/12217/8026 +f 12302/12191/8026 12328/12217/8026 12303/12192/8026 +f 12318/12207/8026 12325/12214/8026 12326/12215/8026 +f 12318/12207/8026 12326/12215/8026 12319/12208/8026 +f 12322/12211/8027 12313/12202/8027 12316/12205/8027 +f 12322/12211/8027 12316/12205/8027 12323/12212/8027 +f 12306/12195/8026 12317/12206/8026 12320/12209/8026 +f 12306/12195/8026 12320/12209/8026 12307/12196/8026 +f 12314/12203/8027 12353/12220/8027 12354/12221/8027 +f 12314/12203/8027 12354/12221/8027 12315/12204/8027 +f 12310/12199/8027 12351/12218/8027 12352/12219/8027 +f 12310/12199/8027 12352/12219/8027 12311/12200/8027 +f 12362/12222/8027 12360/12223/8027 12361/12224/8027 +f 12360/12223/8027 12362/12222/8027 12355/12225/8027 +f 12360/12223/8027 12355/12225/8027 12359/12226/8027 +f 12359/12226/8027 12355/12225/8027 12358/12227/8027 +f 12358/12227/8027 12355/12225/8027 12356/12228/8027 +f 12358/12227/8027 12356/12228/8027 12357/12229/8027 +f 12256/12184/8026 12260/12188/8026 12258/12186/8026 +f 12260/12188/8026 12256/12184/8026 12254/12182/8026 +f 12260/12188/8026 12254/12182/8026 12246/12174/8026 +f 12246/12174/8026 12254/12182/8026 12252/12180/8026 +f 12246/12174/8026 12252/12180/8026 12247/12175/8026 +f 12247/12175/8026 12252/12180/8026 12250/12178/8026 +s 1 +f 12154/12230/8029 12155/12231/8030 12156/12232/8030 +f 12154/12230/8029 12156/12232/8030 12157/12233/8031 +f 12162/12234/8029 12163/12235/8031 12164/12236/8032 +f 12162/12234/8029 12164/12236/8032 12165/12237/8032 +f 12166/12238/8033 12167/12239/8033 12168/12240/8031 +f 12166/12238/8033 12168/12240/8031 12169/12241/8031 +f 12170/12242/8034 12171/12243/8034 12167/12239/8033 +f 12170/12242/8034 12167/12239/8033 12166/12238/8033 +f 12172/12244/8035 12173/12245/8035 12174/12246/8034 +f 12172/12244/8035 12174/12246/8034 12175/12247/8036 +f 12176/12248/8037 12177/12249/8037 12178/12250/8035 +f 12176/12248/8037 12178/12250/8035 12179/12251/8035 +f 12180/12252/8038 12181/12253/8039 12177/12249/8037 +f 12180/12252/8038 12177/12249/8037 12176/12248/8037 +f 12182/12254/8040 12183/12255/8040 12184/12256/8039 +f 12182/12254/8040 12184/12256/8039 12185/12257/8041 +f 12165/12237/8032 12164/12236/8032 12183/12255/8040 +f 12165/12237/8032 12183/12255/8040 12182/12254/8040 +f 12186/12258/8032 12187/12259/8032 12188/12260/8040 +f 12186/12258/8032 12188/12260/8040 12189/12261/8042 +f 12190/12262/8042 12191/12263/8040 12192/12264/8039 +f 12190/12262/8042 12192/12264/8039 12193/12265/8039 +f 12193/12265/8039 12192/12264/8039 12194/12266/8043 +f 12193/12265/8039 12194/12266/8043 12195/12267/8043 +f 12195/12267/8043 12194/12266/8043 12196/12268/8035 +f 12195/12267/8043 12196/12268/8035 12197/12269/8035 +f 12198/12270/8035 12199/12271/8035 12200/12272/8034 +f 12198/12270/8035 12200/12272/8034 12201/12273/8036 +f 12202/12274/8036 12203/12275/8044 12204/12276/8030 +f 12202/12274/8036 12204/12276/8030 12205/12277/8030 +f 12205/12277/8030 12204/12276/8030 12206/12278/8031 +f 12205/12277/8030 12206/12278/8031 12207/12279/8031 +f 12208/12280/8029 12209/12281/8029 12187/12259/8032 +f 12208/12280/8029 12187/12259/8032 12186/12258/8032 +f 12226/12282/8045 12227/12283/8035 12228/12284/8035 +f 12226/12282/8045 12228/12284/8035 12229/12285/8034 +f 12230/12286/8037 12231/12287/8041 12232/12288/8038 +f 12230/12286/8037 12232/12288/8038 12233/12289/8037 +f 12234/12290/8040 12235/12291/8032 12236/12292/8032 +f 12234/12290/8040 12236/12292/8032 12237/12293/8040 +f 12235/12291/8032 12238/12294/8029 12239/12295/8029 +f 12235/12291/8032 12239/12295/8029 12236/12292/8032 +f 12155/12231/8030 12240/12296/8036 12241/12297/8034 +f 12155/12231/8030 12241/12297/8034 12156/12232/8030 +f 12242/12298/8035 12230/12286/8037 12233/12289/8037 +f 12242/12298/8035 12233/12289/8037 12243/12299/8035 +f 12244/12300/8041 12234/12290/8040 12237/12293/8040 +f 12244/12300/8041 12237/12293/8040 12245/12301/8039 +f 12262/12302/8040 12182/12254/8040 12185/12257/8041 +f 12262/12302/8040 12185/12257/8041 12263/12303/8041 +f 12264/12304/8032 12265/12305/8032 12266/12306/8040 +f 12264/12304/8032 12266/12306/8040 12267/12307/8040 +f 12268/12308/8041 12180/12252/8038 12176/12248/8037 +f 12268/12308/8041 12176/12248/8037 12269/12309/8037 +f 12269/12309/8037 12176/12248/8037 12179/12251/8035 +f 12269/12309/8037 12179/12251/8035 12270/12310/8035 +f 12271/12311/8035 12172/12244/8035 12175/12247/8036 +f 12271/12311/8035 12175/12247/8036 12272/12312/8036 +f 12273/12313/8036 12170/12242/8034 12166/12238/8033 +f 12273/12313/8036 12166/12238/8033 12274/12314/8030 +f 12274/12314/8030 12166/12238/8033 12169/12241/8031 +f 12274/12314/8030 12169/12241/8031 12275/12315/8029 +f 12275/12315/8029 12169/12241/8031 12276/12316/8032 +f 12275/12315/8029 12276/12316/8032 12277/12317/8032 +f 12278/12318/8041 12279/12319/8038 12280/12320/8037 +f 12278/12318/8041 12280/12320/8037 12281/12321/8043 +f 12282/12322/8032 12165/12237/8032 12182/12254/8040 +f 12282/12322/8032 12182/12254/8040 12262/12302/8040 +f 12281/12321/8043 12280/12320/8037 12283/12323/8035 +f 12281/12321/8043 12283/12323/8035 12284/12324/8046 +f 12285/12325/8035 12286/12326/8035 12287/12327/8036 +f 12285/12325/8035 12287/12327/8036 12288/12328/8036 +f 12288/12328/8036 12287/12327/8036 12289/12329/8033 +f 12288/12328/8036 12289/12329/8033 12290/12330/8030 +f 12291/12331/8047 12292/12332/8048 12293/12333/8029 +f 12291/12331/8047 12293/12333/8029 12294/12334/8029 +f 12294/12334/8029 12293/12333/8029 12295/12335/8032 +f 12294/12334/8029 12295/12335/8032 12296/12336/8032 +f 12297/12337/8032 12298/12338/8040 12299/12339/8040 +f 12297/12337/8032 12299/12339/8040 12300/12340/8032 +f 12267/12307/8040 12266/12306/8040 12329/12341/8039 +f 12267/12307/8040 12329/12341/8039 12330/12342/8049 +f 12298/12338/8040 12331/12343/8039 12332/12344/8041 +f 12298/12338/8040 12332/12344/8041 12299/12339/8040 +f 12333/12345/8039 12334/12346/8043 12335/12347/8043 +f 12333/12345/8039 12335/12347/8043 12336/12348/8041 +f 12334/12346/8043 12337/12349/8035 12338/12350/8035 +f 12334/12346/8043 12338/12350/8035 12335/12347/8043 +f 12339/12351/8035 12340/12352/8034 12341/12353/8036 +f 12339/12351/8035 12341/12353/8036 12342/12354/8035 +f 12343/12355/8036 12344/12356/8030 12345/12357/8030 +f 12343/12355/8036 12345/12357/8030 12346/12358/8036 +f 12344/12356/8030 12347/12359/8031 12348/12360/8029 +f 12344/12356/8030 12348/12360/8029 12345/12357/8030 +f 12349/12361/8029 12297/12337/8032 12300/12340/8032 +f 12349/12361/8029 12300/12340/8032 12350/12362/8029 +o Cube.030__0 +v -0.806067 0.927703 -0.914348 +v -0.806067 1.204579 -0.944539 +v -0.806067 1.189200 -0.997255 +v -0.806067 0.917794 -0.978620 +v 0.733017 0.646389 -0.959986 +v 0.754204 0.842687 -0.973464 +v 0.754204 0.847126 -0.908815 +v 0.733017 0.650828 -0.895338 +v -0.806067 0.646389 -0.959986 +v 0.733017 0.646389 -0.959986 +v 0.733017 0.650828 -0.895338 +v -0.806067 0.650828 -0.895338 +v 0.792784 1.200141 -0.998006 +v -0.806067 1.189200 -0.997255 +v -0.806067 1.204579 -0.944539 +v 0.792784 1.204579 -0.944539 +v 0.712600 0.923911 -0.969582 +v 0.771598 1.003843 -0.984528 +v 0.768895 1.004561 -0.920058 +v 0.712600 0.927057 -0.923761 +v -0.806067 0.650828 -0.895338 +v -0.806067 0.927703 -0.914348 +v -0.806067 0.917794 -0.978620 +v -0.806067 0.646389 -0.959986 +v 0.530097 0.922453 -0.978940 +v 0.771598 1.003843 -0.984528 +v 0.712600 0.923911 -0.969582 +v 0.754204 0.842687 -0.973464 +v 0.754204 0.847126 -0.908815 +v 0.754204 0.842687 -0.973464 +v 0.712600 0.923911 -0.969582 +v 0.712600 0.927057 -0.923761 +v 0.733017 0.650828 -0.895338 +v 0.754204 0.847126 -0.908815 +v 0.530086 0.927703 -0.914348 +v -0.806067 0.927703 -0.914348 +v -0.806067 0.650828 -0.895338 +v 0.530086 0.927703 -0.914348 +v 0.771598 1.008281 -0.919880 +v 0.792784 1.204579 -0.944539 +v -0.806067 1.204579 -0.944539 +v -0.806067 0.927703 -0.914348 +v -0.806067 0.917794 -0.978620 +v -0.806067 1.189200 -0.997255 +v 0.792784 1.200141 -0.998006 +v 0.771598 1.003843 -0.984528 +v 0.530097 0.922453 -0.978940 +v -0.806067 0.646389 -0.959986 +v -0.806067 0.917794 -0.978620 +v 0.530097 0.922453 -0.978940 +v 0.754204 0.842687 -0.973464 +v 0.733017 0.646389 -0.959986 +v 0.768895 1.004561 -0.920058 +v 0.771598 1.003843 -0.984528 +v 0.792784 1.200141 -0.998006 +v 0.792784 1.204579 -0.944539 +v 0.771598 1.008281 -0.919880 +vt 0.990843 0.787087 +vt 0.991668 0.807666 +vt 0.995636 0.806799 +vt 0.995636 0.786682 +vt 0.416640 0.020424 +vt 0.416640 0.008207 +vt 0.411847 0.008207 +vt 0.411847 0.020424 +vt 0.984861 0.228779 +vt 0.984861 0.342590 +vt 0.989654 0.342590 +vt 0.989654 0.228779 +vt 0.740623 0.607030 +vt 0.744954 0.607910 +vt 0.744954 0.603146 +vt 0.740766 0.603637 +vt 0.990843 0.766565 +vt 0.990843 0.787087 +vt 0.995636 0.786682 +vt 0.995636 0.766565 +vt 0.411847 0.008207 +vt 0.416640 0.008207 +vt 0.415942 0.001489 +vt 0.412545 0.001489 +vt 0.822711 0.768766 +vt 0.808161 0.653388 +vt 0.808161 0.767199 +vt 0.828684 0.653389 +vt 0.828684 0.752193 +vt 0.810307 0.880605 +vt 0.830084 0.979395 +vt 0.830429 0.880605 +vt 0.824050 0.997251 +vt 0.809496 0.998818 +vt 0.830429 0.880605 +vt 0.850551 0.994398 +vt 0.850551 0.880604 +vt 0.835998 0.995965 +vt 0.830084 0.979395 +vt 0.986003 0.945197 +vt 0.986666 0.998612 +vt 0.990644 0.999334 +vt 0.989971 0.945198 +vt 0.830084 0.979395 +vt 0.824050 0.997251 +vt 0.830025 0.992901 +vt 0.835998 0.995965 +vt 0.834657 0.770052 +vt 0.828684 0.653389 +vt 0.828684 0.752193 +vt 0.849281 0.653388 +vt 0.849281 0.771618 +vt 0.990610 0.932770 +vt 0.989971 0.945198 +vt 0.990644 0.932921 +vt 0.985851 0.932981 +vt 0.986003 0.945197 +vn -1.0000 0.0000 0.0000 +vn 0.9943 -0.1068 0.0073 +vn 0.0000 -0.9977 0.0685 +vn 0.8075 -0.5885 0.0404 +vn 0.8890 0.4568 -0.0314 +vn 0.0000 0.0685 0.9977 +vn -0.0000 -0.0685 -0.9977 +vn -0.0034 0.9830 -0.1835 +vn -0.0034 0.9830 -0.1834 +vn 0.0517 -0.0740 -0.9959 +vn 0.0516 -0.0740 -0.9959 +vn 0.0517 -0.0739 -0.9959 +vn -0.0010 0.1094 0.9940 +vn -0.0012 0.1094 0.9940 +vn 0.9936 -0.1127 0.0084 +vn 0.9936 -0.1128 0.0083 +usemtl Scene_-_Root +s off +f 12363/12363/8050 12364/12364/8050 12365/12365/8050 +f 12363/12363/8050 12365/12365/8050 12366/12366/8050 +f 12367/12367/8051 12368/12368/8051 12369/12369/8051 +f 12367/12367/8051 12369/12369/8051 12370/12370/8051 +f 12371/12371/8052 12372/12372/8052 12373/12373/8052 +f 12371/12371/8052 12373/12373/8052 12374/12374/8052 +f 12379/12375/8053 12380/12376/8053 12381/12377/8053 +f 12379/12375/8053 12381/12377/8053 12382/12378/8053 +f 12383/12379/8050 12384/12380/8050 12385/12381/8050 +f 12383/12379/8050 12385/12381/8050 12386/12382/8050 +f 12391/12383/8054 12392/12384/8054 12393/12385/8054 +f 12391/12383/8054 12393/12385/8054 12394/12386/8054 +f 12396/12387/8055 12399/12388/8055 12395/12389/8055 +f 12399/12388/8055 12396/12387/8055 12398/12390/8055 +f 12398/12390/8055 12396/12387/8055 12397/12391/8055 +f 12406/12392/8056 12409/12393/8056 12405/12394/8056 +f 12409/12393/8056 12406/12392/8056 12408/12395/8056 +f 12408/12395/8056 12406/12392/8056 12407/12396/8056 +f 12411/12397/8056 12414/12398/8056 12410/12399/8056 +f 12414/12398/8056 12411/12397/8056 12413/12400/8056 +f 12413/12400/8056 12411/12397/8056 12412/12401/8056 +s 1 +f 12375/12402/8057 12376/12403/8057 12377/12404/8057 +f 12375/12402/8057 12377/12404/8057 12378/12405/8058 +f 12387/12406/8059 12388/12407/8060 12389/12408/8061 +f 12387/12406/8059 12389/12408/8061 12390/12409/8060 +f 12401/12410/8062 12404/12411/8062 12400/12412/8062 +f 12404/12411/8062 12401/12410/8062 12403/12413/8063 +f 12403/12413/8063 12401/12410/8062 12402/12414/8062 +f 12415/12415/8064 12418/12416/8064 12419/12417/8065 +f 12418/12416/8064 12415/12415/8064 12416/12418/8064 +f 12418/12416/8064 12416/12418/8064 12417/12419/8064 +o Plane.012__0 +v 0.893830 0.741952 -0.263109 +v 0.896044 0.746338 -0.191643 +v 0.913494 0.842913 -0.193027 +v 0.913282 0.844068 -0.266533 +v 0.907619 0.662134 -0.262796 +v 0.909718 0.664767 -0.189588 +v 0.908408 0.662168 -0.154392 +v 0.909373 0.805677 -0.148874 +v 0.902972 0.817770 -0.140578 +v 0.905742 0.816476 -0.141298 +v 0.903598 0.662281 -0.147286 +v 0.900755 0.662627 -0.146610 +v 0.907931 0.813724 -0.143127 +v 0.906051 0.662072 -0.149002 +v 0.907931 0.813724 -0.143127 +v 0.909205 0.809932 -0.145787 +v 0.907740 0.662032 -0.151498 +v 0.906051 0.662072 -0.149002 +v 0.904981 0.845032 -0.139343 +v 0.907845 0.844654 -0.140020 +v 0.910296 0.844415 -0.141735 +v 0.910296 0.844415 -0.141735 +v 0.911961 0.844352 -0.144226 +v 0.912586 0.844476 -0.147114 +v 0.901309 0.741076 -0.263273 +v 0.920765 0.843225 -0.266684 +v 0.920988 0.842165 -0.193097 +v 0.909706 0.745467 -0.191630 +v 0.906144 0.701087 -0.263124 +v 0.911016 0.704596 -0.190600 +v 0.916807 0.804850 -0.147998 +v 0.911688 0.732954 -0.150709 +v 0.895142 0.739644 -0.136140 +v 0.901658 0.661911 -0.139169 +v 0.906598 0.661318 -0.140446 +v 0.900073 0.738606 -0.137441 +v 0.911291 0.660919 -0.143737 +v 0.904665 0.736949 -0.140809 +v 0.904665 0.736949 -0.140809 +v 0.911291 0.660919 -0.143737 +v 0.914512 0.660844 -0.148510 +v 0.907686 0.734980 -0.145694 +v 0.915743 0.661060 -0.153419 +v 0.905824 0.844655 -0.131868 +v 0.903870 0.817377 -0.133110 +v 0.908792 0.815894 -0.134436 +v 0.910849 0.844115 -0.133134 +v 0.913285 0.812979 -0.137882 +v 0.915670 0.843761 -0.136499 +v 0.915670 0.843761 -0.136499 +v 0.913285 0.812979 -0.137882 +v 0.916105 0.809116 -0.142879 +v 0.918912 0.843667 -0.141408 +v 0.920052 0.843791 -0.146383 +v 0.906051 0.662072 -0.149002 +v 0.907740 0.662032 -0.151498 +v 0.914512 0.660844 -0.148510 +v 0.911291 0.660919 -0.143737 +v 0.913494 0.842913 -0.193027 +v 0.912586 0.844476 -0.147114 +v 0.920052 0.843791 -0.146383 +v 0.920988 0.842165 -0.193097 +v 0.913282 0.844068 -0.266533 +v 0.920765 0.843225 -0.266684 +v 0.910296 0.844415 -0.141735 +v 0.907845 0.844654 -0.140020 +v 0.910849 0.844115 -0.133134 +v 0.915670 0.843761 -0.136499 +v 0.890042 0.746853 -0.592025 +v 0.905326 0.844068 -0.575176 +v 0.912804 0.843188 -0.575371 +v 0.897520 0.745974 -0.592220 +v 0.909718 0.664767 -0.189588 +v 0.907619 0.662134 -0.262796 +v 0.915021 0.661098 -0.262976 +v 0.917120 0.663726 -0.189569 +v 0.900755 0.662627 -0.146610 +v 0.903598 0.662281 -0.147286 +v 0.906598 0.661318 -0.140446 +v 0.901658 0.661911 -0.139169 +v 0.887763 0.663156 -0.576061 +v 0.890884 0.694808 -0.591831 +v 0.898361 0.693922 -0.592023 +v 0.895168 0.662119 -0.576254 +v 0.904981 0.845032 -0.139343 +v 0.804480 0.860061 -0.129209 +v 0.804548 0.859760 -0.121683 +v 0.905824 0.844655 -0.131868 +v 0.911961 0.844352 -0.144226 +v 0.918912 0.843667 -0.141408 +v 0.791491 0.836212 -0.129889 +v 0.732925 0.837715 -0.127986 +v 0.733027 0.837412 -0.120461 +v 0.791576 0.835910 -0.122364 +v 0.908408 0.662168 -0.154392 +v 0.915743 0.661060 -0.153419 +v 0.750338 0.679687 -0.139779 +v 0.750439 0.679384 -0.132254 +v 0.905326 0.844068 -0.575176 +v 0.912804 0.843188 -0.575371 +v 0.734778 0.853523 -0.127323 +v 0.791491 0.836212 -0.129889 +v 0.791576 0.835910 -0.122364 +v 0.734845 0.853223 -0.119798 +v 0.732925 0.837715 -0.127986 +v 0.750338 0.679687 -0.139779 +v 0.750439 0.679384 -0.132254 +v 0.733027 0.837412 -0.120461 +v 0.891409 0.740567 -0.512717 +v 0.890042 0.746853 -0.592025 +v 0.897520 0.745974 -0.592220 +v 0.898886 0.739685 -0.512911 +v 0.887763 0.663156 -0.576061 +v 0.895168 0.662119 -0.576254 +v 0.734778 0.853523 -0.127323 +v 0.734845 0.853223 -0.119798 +v 0.890884 0.694808 -0.591831 +v 0.891409 0.740567 -0.512717 +v 0.898886 0.739685 -0.512911 +v 0.898361 0.693922 -0.592023 +v 0.917120 0.663726 -0.189569 +v 0.915021 0.661098 -0.262976 +v 0.791491 0.836212 -0.129889 +v 0.734778 0.853523 -0.127323 +v 0.804480 0.860061 -0.129209 +v 0.750338 0.679687 -0.139779 +v 0.732925 0.837715 -0.127986 +v 0.891409 0.740567 -0.512717 +v 0.890884 0.694808 -0.591831 +v 0.887763 0.663156 -0.576061 +v 0.905326 0.844068 -0.575176 +v 0.890042 0.746853 -0.592025 +v 0.804548 0.859760 -0.121683 +v 0.734845 0.853223 -0.119798 +v 0.791576 0.835910 -0.122364 +v 0.733027 0.837412 -0.120461 +v 0.750439 0.679384 -0.132254 +v 0.895168 0.662119 -0.576254 +v 0.898361 0.693922 -0.592023 +v 0.898886 0.739685 -0.512911 +v 0.897520 0.745974 -0.592220 +v 0.912804 0.843188 -0.575371 +vt 0.516848 0.037089 +vt 0.516782 0.036876 +vt 0.516231 0.036943 +vt 0.516357 0.037350 +vt 0.211747 0.361411 +vt 0.211747 0.354253 +vt 0.211191 0.354242 +vt 0.211191 0.361399 +vt 0.517174 0.037371 +vt 0.516985 0.037263 +vt 0.516620 0.037683 +vt 0.211747 0.327775 +vt 0.211747 0.323447 +vt 0.211190 0.323438 +vt 0.211191 0.327764 +vt 0.516797 0.036657 +vt 0.516251 0.036569 +vt 0.280125 0.328267 +vt 0.280125 0.323926 +vt 0.279569 0.323934 +vt 0.279569 0.328276 +vt 0.516947 0.033979 +vt 0.211197 0.407512 +vt 0.211197 0.419202 +vt 0.211750 0.419175 +vt 0.211750 0.407485 +vt 0.280125 0.343194 +vt 0.280125 0.337327 +vt 0.279569 0.337328 +vt 0.279569 0.343196 +vt 0.519681 0.027563 +vt 0.527945 0.005872 +vt 0.527421 0.005695 +vt 0.876962 0.015437 +vt 0.881680 0.013496 +vt 0.881476 0.012978 +vt 0.211747 0.347282 +vt 0.211747 0.341195 +vt 0.211192 0.341232 +vt 0.211192 0.347319 +vt 0.824275 0.039232 +vt 0.824345 0.045510 +vt 0.831843 0.044789 +vt 0.831856 0.038864 +vt 0.818393 0.039131 +vt 0.818363 0.046010 +vt 0.818370 0.048616 +vt 0.828984 0.048221 +vt 0.814460 0.017946 +vt 0.814671 0.017854 +vt 0.814776 0.006446 +vt 0.814562 0.006468 +vt 0.814849 0.017652 +vt 0.814969 0.006433 +vt 0.829608 0.048609 +vt 0.829315 0.048425 +vt 0.818376 0.048834 +vt 0.818390 0.049030 +vt 0.814560 0.019965 +vt 0.814776 0.019941 +vt 0.814969 0.019926 +vt 0.831882 0.048524 +vt 0.831866 0.048329 +vt 0.831859 0.048112 +vt 0.487278 0.025528 +vt 0.494848 0.025867 +vt 0.494834 0.019921 +vt 0.487344 0.019254 +vt 0.484324 0.025557 +vt 0.484336 0.018960 +vt 0.491973 0.016418 +vt 0.486652 0.016189 +vt 0.456755 0.016007 +vt 0.457367 0.021746 +vt 0.457744 0.021785 +vt 0.457132 0.016079 +vt 0.458124 0.021816 +vt 0.457507 0.016204 +vt 0.486997 0.015442 +vt 0.481378 0.015275 +vt 0.481348 0.015644 +vt 0.486827 0.015808 +vt 0.481337 0.016014 +vt 0.457351 0.008218 +vt 0.457258 0.010240 +vt 0.457634 0.010345 +vt 0.457733 0.008253 +vt 0.458005 0.010564 +vt 0.458124 0.008282 +vt 0.494906 0.015782 +vt 0.492627 0.015699 +vt 0.492316 0.016062 +vt 0.494874 0.016162 +vt 0.494856 0.016535 +vt 0.870775 0.021999 +vt 0.869641 0.018873 +vt 0.869104 0.019019 +vt 0.870256 0.022201 +vt 0.872930 0.027535 +vt 0.872416 0.027747 +vt 0.869658 0.018441 +vt 0.869783 0.018258 +vt 0.869393 0.017861 +vt 0.869147 0.018221 +vt 0.517478 0.034135 +vt 0.519157 0.027387 +vt 0.516946 0.037879 +vt 0.211182 0.318371 +vt 0.211178 0.320805 +vt 0.211734 0.320815 +vt 0.211734 0.318370 +vt 0.869965 0.018136 +vt 0.876758 0.014919 +vt 0.869709 0.017641 +vt 0.869608 0.018657 +vt 0.869051 0.018645 +vt 0.527945 0.040404 +vt 0.527776 0.040935 +vt 0.881680 0.048561 +vt 0.881166 0.048776 +vt 0.481332 0.018694 +vt 0.481372 0.025609 +vt 0.807134 0.020924 +vt 0.806217 0.019140 +vt 0.801998 0.020336 +vt 0.803480 0.007498 +vt 0.801889 0.019164 +vt 0.820825 0.015057 +vt 0.824199 0.020886 +vt 0.818477 0.016231 +vt 0.831882 0.016216 +vt 0.824672 0.015063 +vt 0.449008 0.009072 +vt 0.449918 0.007285 +vt 0.444809 0.007889 +vt 0.446315 0.020740 +vt 0.444704 0.009062 +vt 0.483860 0.049756 +vt 0.487228 0.043915 +vt 0.481502 0.048583 +vt 0.494906 0.048573 +vt 0.487709 0.049751 +vn -0.1387 -0.9873 -0.0781 +vn -0.0055 0.1716 -0.9852 +vn -0.1276 -0.9894 -0.0688 +vn -0.1388 -0.9872 -0.0780 +vn 0.0269 0.9988 0.0398 +vn -0.1387 -0.9872 -0.0782 +vn -0.2932 -0.9554 -0.0350 +vn -0.2932 -0.9554 -0.0355 +vn -0.1388 -0.9901 -0.0193 +vn -0.1387 -0.9873 -0.0782 +vn -0.9939 -0.1102 0.0090 +vn -0.1183 -0.9900 -0.0764 +vn -0.1188 -0.9900 -0.0765 +vn -0.1386 -0.9901 0.0223 +vn -0.1386 -0.9903 0.0056 +vn 0.0337 0.9987 0.0382 +vn -0.0922 0.9949 0.0405 +vn 0.0891 0.8619 -0.4992 +vn 0.0893 0.8619 -0.4992 +vn -0.9993 0.0249 0.0263 +vn -0.9957 -0.0010 0.0924 +vn -0.9857 0.1669 0.0236 +vn -0.9848 0.1732 0.0159 +vn -0.9923 -0.1182 0.0359 +vn -0.9867 -0.1118 0.1180 +vn -0.9995 -0.0220 0.0207 +vn -0.9965 0.0701 -0.0454 +vn -0.1438 0.0571 -0.9880 +vn -0.4068 0.0601 -0.9115 +vn -0.4300 0.0408 -0.9019 +vn -0.1482 0.0507 -0.9877 +vn -0.7237 0.0649 -0.6871 +vn -0.7436 0.0347 -0.6678 +vn -0.7238 0.0649 -0.6869 +vn -0.9316 0.0592 -0.3586 +vn -0.9417 0.0221 -0.3358 +vn -0.7437 0.0348 -0.6676 +vn -0.1463 0.0601 -0.9874 +vn -0.3987 0.0715 -0.9143 +vn -0.7134 0.0869 -0.6953 +vn -0.7137 0.0860 -0.6952 +vn -0.9229 0.0910 -0.3740 +vn -0.9895 0.1197 -0.0808 +vn 0.9978 -0.0420 -0.0509 +vn 0.9866 -0.1590 -0.0367 +vn 0.9911 -0.1304 -0.0256 +vn 0.9971 -0.0458 -0.0604 +vn 0.9937 0.0991 -0.0530 +vn 0.9945 0.0897 -0.0542 +vn 0.9748 -0.0970 0.2010 +vn 0.9757 -0.0037 0.2190 +vn 0.1509 -0.0531 0.9871 +vn 0.1660 -0.0365 0.9855 +vn 0.4453 0.0033 0.8954 +vn 0.4081 -0.0443 0.9119 +vn 0.7388 0.0392 0.6728 +vn 0.7133 -0.0392 0.6998 +vn 0.7132 -0.0392 0.6998 +vn 0.8671 0.0519 0.4954 +vn 0.8615 -0.0258 0.5071 +vn 0.9710 0.0714 0.2280 +vn 0.1549 -0.0606 0.9861 +vn 0.1544 -0.0621 0.9861 +vn 0.4135 -0.0761 0.9073 +vn 0.4079 -0.0719 0.9102 +vn 0.7128 -0.0957 0.6948 +vn 0.7130 -0.0866 0.6958 +vn 0.9003 -0.1008 0.4234 +vn 0.9178 -0.0911 0.3865 +vn 0.9888 -0.0981 0.1121 +vn 0.1013 0.9948 -0.0091 +vn 0.0895 0.9959 0.0093 +vn 0.0897 0.9959 0.0080 +vn 0.1014 0.9948 -0.0086 +vn 0.1100 0.9939 0.0059 +vn 0.1101 0.9939 0.0058 +vn 0.0930 0.9952 0.0317 +vn 0.1119 0.9933 0.0292 +vn 0.1120 0.9933 0.0292 +vn 0.0929 0.9952 0.0318 +vn -0.1392 -0.9901 -0.0193 +vn -0.1385 -0.9901 0.0223 +vn -0.1386 -0.9901 0.0227 +vn -0.1388 -0.9901 -0.0194 +vn -0.1275 -0.9894 -0.0689 +vn -0.1387 -0.9872 -0.0781 +vn -0.1274 -0.9895 -0.0688 +vn -0.0797 -0.4373 -0.8958 +vn 0.1367 0.9901 0.0328 +vn 0.0254 0.9989 0.0383 +vn 0.1376 0.9899 0.0329 +vn 0.0837 0.9956 0.0426 +vn 0.0837 0.9956 0.0429 +vn -0.1162 -0.9914 -0.0596 +vn 0.1143 0.9934 -0.0030 +vn -0.1385 -0.9903 0.0056 +vn 0.9902 0.1345 -0.0375 +vn 0.9913 0.1248 -0.0427 +vn -0.0755 0.0592 -0.9954 +vn -0.0646 0.0602 -0.9961 +vn -0.0535 0.0612 -0.9967 +vn -0.0536 0.0612 -0.9967 +vn -0.9970 -0.0694 0.0342 +vn -0.9980 0.0566 0.0263 +vn -0.9970 -0.0693 0.0342 +vn -0.9863 0.1639 0.0192 +vn 0.0652 -0.0605 0.9960 +vn 0.0754 -0.0592 0.9954 +vn 0.0755 -0.0590 0.9954 +vn 0.0549 -0.0618 0.9966 +vn 0.9972 0.0682 -0.0307 +vn 0.9981 -0.0571 -0.0247 +vn 0.9863 -0.1639 -0.0192 +usemtl Scene_-_Root +s off +f 12474/12420/8066 12475/12421/8066 12476/12422/8066 +f 12474/12420/8066 12476/12422/8066 12477/12423/8066 +f 12488/12424/8067 12489/12425/8067 12490/12426/8067 +f 12488/12424/8067 12490/12426/8067 12491/12427/8067 +f 12496/12428/8068 12497/12429/8069 12498/12430/8069 +f 12510/12431/8070 12511/12432/8070 12512/12433/8070 +f 12510/12431/8070 12512/12433/8070 12513/12434/8070 +f 12475/12421/8071 12514/12435/8071 12515/12436/8071 +f 12475/12421/8066 12515/12436/8066 12476/12422/8066 +f 12520/12437/8072 12521/12438/8072 12522/12439/8072 +f 12520/12437/8073 12522/12439/8073 12523/12440/8073 +f 12514/12435/8066 12495/12441/8074 12515/12436/8066 +f 12497/12429/8075 12474/12420/8075 12477/12423/8075 +f 12497/12429/8066 12477/12423/8066 12498/12430/8066 +f 12524/12442/8076 12525/12443/8076 12526/12444/8076 +f 12524/12442/8076 12526/12444/8076 12527/12445/8076 +f 12528/12446/8077 12529/12447/8077 12530/12448/8077 +f 12528/12446/8078 12530/12448/8078 12531/12449/8078 +f 12493/12450/8079 12532/12451/8080 12533/12452/8080 +f 12505/12453/8081 12534/12454/8082 12535/12455/8082 +f 12536/12456/8083 12537/12457/8083 12538/12458/8083 +f 12536/12456/8084 12538/12458/8084 12539/12459/8084 +s 1 +f 12420/12460/8085 12421/12461/8086 12422/12462/8087 +f 12420/12460/8085 12422/12462/8087 12423/12463/8088 +f 12424/12464/8089 12425/12465/8090 12421/12461/8086 +f 12424/12464/8089 12421/12461/8086 12420/12460/8085 +f 12425/12465/8090 12426/12466/8091 12427/12467/8092 +f 12425/12465/8090 12427/12467/8092 12421/12461/8086 +f 12428/12468/8093 12429/12469/8094 12430/12470/8095 +f 12428/12468/8093 12430/12470/8095 12431/12471/8096 +f 12429/12469/8094 12432/12472/8097 12433/12473/8098 +f 12429/12469/8094 12433/12473/8098 12430/12470/8095 +f 12434/12474/8099 12435/12475/8100 12436/12476/8101 +f 12434/12474/8099 12436/12476/8101 12437/12477/8102 +f 12435/12475/8100 12427/12467/8092 12426/12466/8091 +f 12435/12475/8100 12426/12466/8091 12436/12476/8101 +f 12438/12478/8103 12439/12479/8104 12429/12469/8094 +f 12438/12478/8103 12429/12469/8094 12428/12468/8093 +f 12439/12479/8104 12440/12480/8105 12432/12472/8097 +f 12439/12479/8104 12432/12472/8097 12429/12469/8094 +f 12441/12481/8106 12442/12482/8107 12435/12475/8100 +f 12441/12481/8106 12435/12475/8100 12434/12474/8099 +f 12442/12482/8107 12443/12483/8108 12427/12467/8092 +f 12442/12482/8107 12427/12467/8092 12435/12475/8100 +f 12421/12461/8086 12427/12467/8092 12443/12483/8108 +f 12421/12461/8086 12443/12483/8108 12422/12462/8087 +f 12444/12484/8109 12445/12485/8110 12446/12486/8111 +f 12444/12484/8109 12446/12486/8111 12447/12487/8112 +f 12448/12488/8113 12444/12484/8109 12447/12487/8112 +f 12448/12488/8113 12447/12487/8112 12449/12489/8114 +f 12449/12489/8114 12447/12487/8112 12450/12490/8115 +f 12449/12489/8114 12450/12490/8115 12451/12491/8116 +f 12452/12492/8117 12453/12493/8118 12454/12494/8119 +f 12452/12492/8117 12454/12494/8119 12455/12495/8120 +f 12455/12495/8120 12454/12494/8119 12456/12496/8121 +f 12455/12495/8120 12456/12496/8121 12457/12497/8122 +f 12458/12498/8123 12459/12499/8121 12460/12500/8124 +f 12458/12498/8123 12460/12500/8124 12461/12501/8125 +f 12461/12501/8125 12460/12500/8124 12462/12502/8126 +f 12461/12501/8125 12462/12502/8126 12451/12491/8116 +f 12463/12503/8127 12464/12504/8128 12465/12505/8129 +f 12463/12503/8127 12465/12505/8129 12466/12506/8130 +f 12466/12506/8130 12465/12505/8129 12467/12507/8131 +f 12466/12506/8130 12467/12507/8131 12468/12508/8132 +f 12469/12509/8132 12470/12510/8131 12471/12511/8133 +f 12469/12509/8132 12471/12511/8133 12472/12512/8134 +f 12472/12512/8134 12471/12511/8133 12450/12490/8115 +f 12472/12512/8134 12450/12490/8115 12473/12513/8135 +f 12447/12487/8112 12446/12486/8111 12473/12513/8135 +f 12447/12487/8112 12473/12513/8135 12450/12490/8115 +f 12478/12514/8136 12479/12515/8137 12480/12516/8138 +f 12478/12514/8136 12480/12516/8138 12481/12517/8139 +f 12482/12518/8140 12478/12514/8136 12481/12517/8139 +f 12482/12518/8140 12481/12517/8139 12483/12519/8141 +f 12484/12520/8142 12485/12521/8143 12486/12522/8144 +f 12484/12520/8142 12486/12522/8144 12487/12523/8145 +f 12492/12524/8146 12493/12450/8147 12494/12525/8148 +f 12492/12524/8146 12494/12525/8148 12495/12441/8149 +f 12496/12428/8150 12498/12430/8151 12499/12526/8152 +f 12500/12527/8153 12501/12528/8153 12502/12529/8153 +f 12500/12527/8153 12502/12529/8153 12503/12530/8153 +f 12504/12531/8154 12505/12453/8081 12506/12532/8155 +f 12504/12531/8154 12506/12532/8155 12507/12533/8156 +f 12508/12534/8157 12484/12520/8142 12487/12523/8145 +f 12508/12534/8157 12487/12523/8145 12509/12535/8158 +f 12516/12536/8159 12496/12428/8150 12499/12526/8152 +f 12516/12536/8159 12499/12526/8152 12517/12537/8159 +f 12518/12538/8160 12482/12518/8140 12483/12519/8141 +f 12518/12538/8160 12483/12519/8141 12519/12539/8160 +f 12514/12435/8066 12492/12524/8146 12495/12441/8149 +f 12479/12515/8137 12508/12534/8157 12509/12535/8158 +f 12479/12515/8137 12509/12535/8158 12480/12516/8138 +f 12485/12521/8143 12504/12531/8154 12507/12533/8156 +f 12485/12521/8143 12507/12533/8156 12486/12522/8144 +f 12493/12450/8147 12533/12452/8161 12494/12525/8148 +f 12505/12453/8081 12535/12455/8082 12506/12532/8155 +f 12471/12511/8133 12461/12501/8125 12451/12491/8116 +f 12471/12511/8133 12451/12491/8116 12450/12490/8115 +f 12470/12510/8131 12458/12498/8123 12461/12501/8125 +f 12470/12510/8131 12461/12501/8125 12471/12511/8133 +f 12465/12505/8129 12455/12495/8120 12457/12497/8122 +f 12465/12505/8129 12457/12497/8122 12467/12507/8131 +f 12464/12504/8128 12452/12492/8117 12455/12495/8120 +f 12464/12504/8128 12455/12495/8120 12465/12505/8129 +f 12540/12540/8162 12449/12489/8114 12451/12491/8116 +f 12540/12540/8162 12451/12491/8116 12462/12502/8126 +f 12541/12541/8163 12448/12488/8113 12449/12489/8114 +f 12541/12541/8163 12449/12489/8114 12540/12540/8162 +f 12544/12542/8164 12542/12543/8165 12543/12544/8164 +f 12542/12543/8165 12544/12542/8164 12428/12468/8093 +f 12428/12468/8093 12544/12542/8164 12438/12478/8103 +f 12542/12543/8165 12545/12545/8166 12546/12546/8167 +f 12545/12545/8166 12542/12543/8165 12428/12468/8093 +f 12545/12545/8166 12428/12468/8093 12431/12471/8096 +f 12548/12547/8168 12420/12460/8085 12547/12548/8169 +f 12420/12460/8085 12548/12547/8168 12424/12464/8089 +f 12424/12464/8089 12548/12547/8168 12549/12549/8170 +f 12550/12550/8171 12420/12460/8085 12423/12463/8088 +f 12420/12460/8085 12550/12550/8171 12551/12551/8171 +f 12420/12460/8085 12551/12551/8171 12547/12548/8169 +f 12554/12552/8172 12552/12553/8173 12553/12554/8174 +f 12552/12553/8173 12554/12552/8172 12464/12504/8128 +f 12552/12553/8173 12464/12504/8128 12463/12503/8127 +f 12556/12555/8175 12554/12552/8172 12555/12556/8175 +f 12554/12552/8172 12556/12555/8175 12464/12504/8128 +f 12464/12504/8128 12556/12555/8175 12452/12492/8117 +f 12452/12492/8117 12556/12555/8175 12453/12493/8118 +f 12444/12484/8109 12558/12557/8176 12559/12558/8177 +f 12558/12557/8176 12444/12484/8109 12448/12488/8113 +f 12558/12557/8176 12448/12488/8113 12541/12541/8163 +f 12558/12557/8176 12541/12541/8163 12557/12559/8176 +f 12444/12484/8109 12561/12560/8178 12445/12485/8110 +f 12561/12560/8178 12444/12484/8109 12560/12561/8178 +f 12560/12561/8178 12444/12484/8109 12559/12558/8177 +o Plane.013__0 +v -0.975702 0.477702 -0.269051 +v -0.977463 0.476705 -0.171197 +v -1.029211 0.390977 -0.179360 +v -1.031011 0.391465 -0.269051 +v -0.937744 0.568590 -0.269051 +v -0.937928 0.566914 -0.163035 +v -0.936518 0.563802 -0.127790 +v -1.005732 0.425405 -0.133109 +v -1.003003 0.411354 -0.125960 +v -1.005294 0.413431 -0.126504 +v -0.932045 0.561159 -0.120842 +v -0.929422 0.559851 -0.120270 +v -1.006618 0.416831 -0.128054 +v -0.934315 0.562370 -0.122472 +v -1.006618 0.416831 -0.128054 +v -1.006771 0.421036 -0.130373 +v -0.935886 0.563298 -0.124912 +v -0.934315 0.562370 -0.122472 +v -1.020161 0.386770 -0.126827 +v -1.022801 0.387998 -0.127398 +v -1.025089 0.389060 -0.129024 +v -1.025089 0.389060 -0.129024 +v -1.026673 0.389796 -0.131459 +v -1.027315 0.390095 -0.134331 +v -0.982806 0.481394 -0.269045 +v -1.037784 0.395732 -0.269039 +v -1.036036 0.395156 -0.179147 +v -0.984596 0.480338 -0.171189 +v -0.945127 0.571685 -0.269050 +v -0.945220 0.570216 -0.163096 +v -1.012657 0.429165 -0.131693 +v -0.943658 0.567236 -0.126642 +v -1.003643 0.411446 -0.117981 +v -0.930203 0.559815 -0.112303 +v -0.934774 0.562228 -0.113393 +v -1.007797 0.414672 -0.119002 +v -0.939196 0.564567 -0.116520 +v -1.011188 0.419280 -0.121955 +v -1.011188 0.419280 -0.121955 +v -0.939196 0.564567 -0.116520 +v -0.942290 0.566347 -0.121201 +v -1.012898 0.424363 -0.126439 +v -1.020844 0.387045 -0.118855 +v -1.025357 0.389474 -0.119956 +v -1.029544 0.391787 -0.122958 +v -1.029544 0.391787 -0.122958 +v -1.032592 0.393414 -0.127461 +v -1.034030 0.394154 -0.132745 +v -1.031011 0.391465 -0.529067 +v -1.031011 0.391465 -0.269051 +v -1.037784 0.395732 -0.269039 +v -1.037760 0.395770 -0.529078 +v -0.696863 0.260638 -0.136762 +v -0.794066 0.378533 -0.130212 +v -0.794023 0.378160 -0.122215 +v -0.696728 0.260443 -0.128761 +v -0.936518 0.563802 -0.127790 +v -0.937928 0.566914 -0.163035 +v -0.945220 0.570216 -0.163096 +v -0.943658 0.567236 -0.126642 +v -0.932045 0.561159 -0.120842 +v -0.934315 0.562370 -0.122472 +v -0.939196 0.564567 -0.116520 +v -0.934774 0.562228 -0.113393 +v -1.027315 0.390095 -0.134331 +v -1.026673 0.389796 -0.131459 +v -1.032592 0.393414 -0.127461 +v -1.034030 0.394154 -0.132745 +v -0.738325 0.360399 -0.129943 +v -0.659107 0.393138 -0.128166 +v -0.659145 0.392611 -0.120178 +v -0.738363 0.359872 -0.121955 +v -1.022801 0.387998 -0.127398 +v -1.020161 0.386770 -0.126827 +v -1.020844 0.387045 -0.118855 +v -1.025357 0.389474 -0.119956 +v -0.975064 0.478958 -0.651260 +v -0.981429 0.466941 -0.715329 +v -0.988178 0.471246 -0.715339 +v -0.981910 0.483107 -0.651266 +v -0.937744 0.568590 -0.269051 +v -0.938105 0.569014 -0.563059 +v -0.945510 0.572054 -0.563028 +v -0.945127 0.571685 -0.269050 +v -0.751457 0.224857 -0.137360 +v -0.696863 0.260638 -0.136762 +v -0.696728 0.260443 -0.128761 +v -0.751321 0.224663 -0.129359 +v -0.963167 0.513362 -0.571836 +v -0.970572 0.516402 -0.571805 +v -0.935886 0.563298 -0.124912 +v -0.942290 0.566347 -0.121201 +v -1.029211 0.390977 -0.179360 +v -1.036036 0.395156 -0.179147 +v -1.025089 0.389060 -0.129024 +v -1.029544 0.391787 -0.122958 +v -0.981429 0.466941 -0.715329 +v -0.988178 0.471246 -0.715339 +v -0.929422 0.559851 -0.120270 +v -0.930203 0.559815 -0.112303 +v -0.938105 0.569014 -0.563059 +v -0.963167 0.513362 -0.571836 +v -0.970572 0.516402 -0.571805 +v -0.945510 0.572054 -0.563028 +v -0.751457 0.224857 -0.137360 +v -0.751321 0.224663 -0.129359 +v -0.794066 0.378533 -0.130212 +v -0.738325 0.360399 -0.129943 +v -0.738363 0.359872 -0.121955 +v -0.794023 0.378160 -0.122215 +v -0.659107 0.393138 -0.128166 +v -0.659145 0.392611 -0.120178 +v -0.794066 0.378533 -0.130212 +v -0.696863 0.260638 -0.136762 +v -0.751457 0.224857 -0.137360 +v -0.659107 0.393138 -0.128166 +v -0.738325 0.360399 -0.129943 +v -0.975064 0.478958 -0.651260 +v -0.963167 0.513362 -0.571836 +v -0.938105 0.569014 -0.563059 +v -1.031011 0.391465 -0.529067 +v -0.981429 0.466941 -0.715329 +v -0.751321 0.224663 -0.129359 +v -0.696728 0.260443 -0.128761 +v -0.794023 0.378160 -0.122215 +v -0.738363 0.359872 -0.121955 +v -0.659145 0.392611 -0.120178 +v -0.945510 0.572054 -0.563028 +v -0.970572 0.516402 -0.571805 +v -0.981910 0.483107 -0.651266 +v -0.988178 0.471246 -0.715339 +v -1.037760 0.395770 -0.529078 +vt 0.583232 0.773340 +vt 0.583232 0.778457 +vt 0.583823 0.778473 +vt 0.583823 0.773356 +vt 0.211747 0.336590 +vt 0.211747 0.332234 +vt 0.211156 0.332212 +vt 0.211156 0.336568 +vt 0.840030 0.099443 +vt 0.832353 0.087647 +vt 0.839512 0.099729 +vt 0.609123 0.773957 +vt 0.609123 0.778489 +vt 0.609709 0.778518 +vt 0.609709 0.773986 +vt 0.769320 0.034878 +vt 0.769194 0.027673 +vt 0.761787 0.028270 +vt 0.761745 0.034891 +vt 0.776527 0.034970 +vt 0.776418 0.027153 +vt 0.776276 0.024538 +vt 0.764866 0.024849 +vt 0.556992 0.010801 +vt 0.556950 0.010573 +vt 0.544788 0.009569 +vt 0.544769 0.009789 +vt 0.556791 0.010345 +vt 0.544803 0.009365 +vt 0.764290 0.024454 +vt 0.764550 0.024639 +vt 0.776269 0.024321 +vt 0.776270 0.024130 +vt 0.559205 0.010658 +vt 0.559230 0.010440 +vt 0.559256 0.010241 +vt 0.761825 0.024533 +vt 0.761811 0.024723 +vt 0.761805 0.024939 +vt 0.256968 0.057225 +vt 0.249465 0.057173 +vt 0.249491 0.063806 +vt 0.256841 0.064425 +vt 0.264174 0.057161 +vt 0.264079 0.064969 +vt 0.252526 0.067330 +vt 0.263939 0.067672 +vt 0.199643 0.034206 +vt 0.187432 0.035178 +vt 0.187456 0.035568 +vt 0.199599 0.034600 +vt 0.187482 0.035971 +vt 0.199442 0.035023 +vt 0.251931 0.068087 +vt 0.263920 0.068452 +vt 0.263929 0.068084 +vt 0.252204 0.067731 +vt 0.201846 0.034364 +vt 0.201867 0.034751 +vt 0.201886 0.035138 +vt 0.249498 0.067992 +vt 0.249499 0.067638 +vt 0.249497 0.067238 +vt 0.832870 0.087361 +vt 0.823627 0.070519 +vt 0.823108 0.070803 +vt 0.279513 0.398112 +vt 0.279514 0.408480 +vt 0.280105 0.408500 +vt 0.280105 0.398132 +vt 0.922928 0.072492 +vt 0.924341 0.070300 +vt 0.923872 0.069939 +vt 0.922410 0.072206 +vt 0.922924 0.073132 +vt 0.922845 0.072921 +vt 0.922265 0.073033 +vt 0.922420 0.073440 +vt 0.819091 0.061655 +vt 0.819035 0.061444 +vt 0.818443 0.061432 +vt 0.818526 0.061832 +vt 0.819167 0.061031 +vt 0.819335 0.060891 +vt 0.819004 0.060400 +vt 0.818711 0.060653 +vt 0.407312 0.447356 +vt 0.407485 0.452120 +vt 0.408074 0.452100 +vt 0.407902 0.447336 +vt 0.929035 0.064030 +vt 0.942124 0.046683 +vt 0.941653 0.046327 +vt 0.928565 0.063672 +vt 0.407484 0.441392 +vt 0.408074 0.441372 +vt 0.922847 0.072697 +vt 0.922263 0.072598 +vt 0.820556 0.064646 +vt 0.820030 0.064917 +vt 0.819061 0.061225 +vt 0.818507 0.061018 +vt 0.923072 0.073297 +vt 0.922676 0.073735 +vt 0.840030 0.050394 +vt 0.839759 0.049868 +vt 0.211155 0.327861 +vt 0.211155 0.332111 +vt 0.211747 0.332126 +vt 0.211747 0.327875 +vt 0.942124 0.086906 +vt 0.941780 0.087385 +vt 0.559256 0.033540 +vt 0.551126 0.025078 +vt 0.554909 0.035594 +vt 0.550149 0.029259 +vt 0.545052 0.032981 +vt 0.769407 0.063047 +vt 0.772044 0.057241 +vt 0.776527 0.056641 +vt 0.761733 0.054054 +vt 0.768400 0.067764 +vt 0.193773 0.019958 +vt 0.201886 0.011584 +vt 0.197537 0.009533 +vt 0.192810 0.015799 +vt 0.187713 0.012086 +vt 0.257097 0.029073 +vt 0.259669 0.034888 +vt 0.264174 0.035506 +vt 0.249459 0.038021 +vt 0.256102 0.024355 +vn 0.3824 -0.9221 -0.0590 +vn 0.5481 -0.8359 -0.0296 +vn -0.4835 -0.7589 -0.4362 +vn -0.5227 -0.8226 -0.2236 +vn 0.0506 0.1333 -0.9898 +vn 0.8873 -0.4612 -0.0008 +vn 0.8910 -0.4539 -0.0010 +vn 0.8525 -0.5220 -0.0266 +vn 0.8461 -0.5331 -0.0015 +vn 0.9222 -0.3867 -0.0001 +vn 0.9110 -0.4124 0.0077 +vn 0.8919 -0.4289 -0.1434 +vn 0.8650 -0.4696 -0.1770 +vn 0.0789 -0.0093 -0.9968 +vn 0.3126 -0.1549 -0.9372 +vn 0.3409 -0.1335 -0.9306 +vn 0.0946 -0.0035 -0.9955 +vn 0.5709 -0.3059 -0.7619 +vn 0.6095 -0.2749 -0.7436 +vn 0.5710 -0.3060 -0.7618 +vn 0.7654 -0.4156 -0.4914 +vn 0.8000 -0.3810 -0.4636 +vn 0.6097 -0.2745 -0.7436 +vn 0.0841 -0.0242 -0.9962 +vn 0.3191 -0.1844 -0.9296 +vn 0.5565 -0.3406 -0.7579 +vn 0.5566 -0.3407 -0.7577 +vn 0.7392 -0.4518 -0.4994 +vn 0.8388 -0.5071 -0.1981 +vn -0.8874 0.4611 0.0008 +vn -0.8460 0.5332 0.0015 +vn -0.8525 0.5221 0.0273 +vn -0.8910 0.4541 0.0025 +vn -0.9224 0.3863 0.0001 +vn -0.9111 0.4122 -0.0062 +vn -0.8619 0.4726 0.1838 +vn -0.8909 0.4280 0.1520 +vn -0.0853 0.0126 0.9963 +vn -0.1018 0.0072 0.9948 +vn -0.3452 0.1357 0.9287 +vn -0.3201 0.1567 0.9343 +vn -0.6060 0.2725 0.7474 +vn -0.5724 0.3056 0.7609 +vn -0.6060 0.2725 0.7473 +vn -0.7960 0.3786 0.4723 +vn -0.7648 0.4156 0.4923 +vn -0.0900 0.0281 0.9955 +vn -0.3212 0.1862 0.9285 +vn -0.5567 0.3415 0.7573 +vn -0.5566 0.3415 0.7573 +vn -0.7398 0.4530 0.4975 +vn -0.8386 0.5072 0.1989 +vn -0.5227 -0.8225 -0.2241 +vn -0.5315 -0.8471 0.0027 +vn -0.5315 -0.8471 0.0026 +vn -0.5227 -0.8227 -0.2236 +vn 0.7715 0.6361 0.0140 +vn 0.4351 0.8990 0.0510 +vn 0.4132 0.9099 0.0373 +vn 0.4124 0.9103 0.0359 +vn 0.4347 0.8991 0.0513 +vn 0.4495 0.8924 0.0398 +vn 0.4497 0.8923 0.0401 +vn 0.4497 0.8923 0.0399 +vn 0.4496 0.8924 0.0399 +vn -0.5159 -0.8566 0.0127 +vn -0.5046 -0.8629 0.0281 +vn -0.5039 -0.8633 0.0288 +vn -0.5156 -0.8567 0.0129 +vn -0.4665 -0.8844 0.0157 +vn -0.4868 -0.8735 -0.0041 +vn -0.4865 -0.8737 -0.0041 +vn -0.4664 -0.8844 0.0156 +vn 0.4686 0.8289 -0.3054 +vn 0.5170 0.8309 -0.2058 +vn 0.4653 0.8284 -0.3118 +vn 0.3914 0.9202 0.0075 +vn 0.3832 0.9237 0.0008 +vn 0.3913 0.9202 0.0074 +vn 0.4107 0.8156 -0.4076 +vn 0.4108 0.8156 -0.4076 +vn 0.4476 0.8932 0.0432 +vn 0.4477 0.8931 0.0432 +vn -0.5234 -0.8521 0.0050 +vn -0.5235 -0.8520 0.0050 +vn -0.4867 -0.8730 0.0310 +vn -0.4862 -0.8733 0.0308 +vn -0.4834 -0.7590 -0.4362 +vn 0.4887 0.8710 0.0500 +vn 0.4890 0.8709 0.0501 +vn -0.5164 -0.8562 -0.0134 +vn -0.5164 -0.8562 -0.0135 +vn -0.3101 -0.9492 -0.0534 +vn -0.3101 -0.9492 -0.0533 +vn 0.5253 0.8490 0.0569 +vn -0.0141 0.0428 -0.9990 +vn -0.0078 0.0471 -0.9989 +vn -0.0140 0.0428 -0.9990 +vn -0.0028 0.0506 -0.9987 +vn 0.8552 -0.5184 0.0007 +vn 0.9251 -0.3798 -0.0039 +vn 0.8431 -0.5378 0.0014 +vn 0.0077 -0.0470 0.9989 +vn 0.0138 -0.0429 0.9990 +vn 0.0027 -0.0504 0.9987 +vn -0.8548 0.5189 -0.0007 +vn -0.9253 0.3792 0.0038 +vn -0.9253 0.3791 0.0038 +vn -0.8430 0.5380 -0.0013 +vn -0.8430 0.5379 -0.0013 +usemtl Scene_-_Root +s off +f 12630/12562/8179 12631/12563/8179 12632/12564/8179 +f 12630/12562/8179 12632/12564/8179 12633/12565/8179 +f 12646/12566/8180 12647/12567/8180 12648/12568/8180 +f 12646/12566/8180 12648/12568/8180 12649/12569/8180 +f 12658/12570/8181 12613/12571/8182 12659/12572/8181 +f 12662/12573/8183 12663/12574/8183 12664/12575/8183 +f 12662/12573/8183 12664/12575/8183 12665/12576/8183 +s 1 +f 12562/12577/8184 12563/12578/8185 12564/12579/8186 +f 12562/12577/8184 12564/12579/8186 12565/12580/8187 +f 12566/12581/8188 12567/12582/8189 12563/12578/8185 +f 12566/12581/8188 12563/12578/8185 12562/12577/8184 +f 12567/12582/8189 12568/12583/8190 12569/12584/8191 +f 12567/12582/8189 12569/12584/8191 12563/12578/8185 +f 12570/12585/8192 12571/12586/8193 12572/12587/8194 +f 12570/12585/8192 12572/12587/8194 12573/12588/8195 +f 12571/12586/8193 12574/12589/8196 12575/12590/8197 +f 12571/12586/8193 12575/12590/8197 12572/12587/8194 +f 12576/12591/8198 12577/12592/8199 12578/12593/8200 +f 12576/12591/8198 12578/12593/8200 12579/12594/8201 +f 12577/12592/8199 12569/12584/8191 12568/12583/8190 +f 12577/12592/8199 12568/12583/8190 12578/12593/8200 +f 12580/12595/8202 12581/12596/8203 12571/12586/8193 +f 12580/12595/8202 12571/12586/8193 12570/12585/8192 +f 12581/12596/8203 12582/12597/8204 12574/12589/8196 +f 12581/12596/8203 12574/12589/8196 12571/12586/8193 +f 12583/12598/8205 12584/12599/8206 12577/12592/8199 +f 12583/12598/8205 12577/12592/8199 12576/12591/8198 +f 12584/12599/8206 12585/12600/8207 12569/12584/8191 +f 12584/12599/8206 12569/12584/8191 12577/12592/8199 +f 12563/12578/8185 12569/12584/8191 12585/12600/8207 +f 12563/12578/8185 12585/12600/8207 12564/12579/8186 +f 12586/12601/8208 12587/12602/8209 12588/12603/8210 +f 12586/12601/8208 12588/12603/8210 12589/12604/8211 +f 12590/12605/8212 12586/12601/8208 12589/12604/8211 +f 12590/12605/8212 12589/12604/8211 12591/12606/8213 +f 12591/12606/8213 12589/12604/8211 12592/12607/8214 +f 12591/12606/8213 12592/12607/8214 12593/12608/8215 +f 12594/12609/8216 12595/12610/8217 12596/12611/8218 +f 12594/12609/8216 12596/12611/8218 12597/12612/8219 +f 12597/12612/8219 12596/12611/8218 12598/12613/8220 +f 12597/12612/8219 12598/12613/8220 12599/12614/8221 +f 12600/12615/8221 12601/12616/8222 12602/12617/8223 +f 12600/12615/8221 12602/12617/8223 12603/12618/8224 +f 12603/12618/8224 12602/12617/8223 12593/12608/8215 +f 12603/12618/8224 12593/12608/8215 12592/12607/8214 +f 12604/12619/8225 12594/12609/8216 12597/12612/8219 +f 12604/12619/8225 12597/12612/8219 12605/12620/8226 +f 12605/12620/8226 12597/12612/8219 12599/12614/8221 +f 12605/12620/8226 12599/12614/8221 12606/12621/8227 +f 12607/12622/8228 12600/12615/8221 12603/12618/8224 +f 12607/12622/8228 12603/12618/8224 12608/12623/8229 +f 12608/12623/8229 12603/12618/8224 12592/12607/8214 +f 12608/12623/8229 12592/12607/8214 12609/12624/8230 +f 12589/12604/8211 12588/12603/8210 12609/12624/8230 +f 12589/12604/8211 12609/12624/8230 12592/12607/8214 +f 12610/12625/8231 12611/12626/8232 12612/12627/8233 +f 12610/12625/8231 12612/12627/8233 12613/12571/8234 +f 12614/12628/8235 12615/12629/8235 12616/12630/8235 +f 12614/12628/8235 12616/12630/8235 12617/12631/8235 +f 12618/12632/8236 12619/12633/8237 12620/12634/8238 +f 12618/12632/8236 12620/12634/8238 12621/12635/8239 +f 12622/12636/8240 12623/12637/8241 12624/12638/8242 +f 12622/12636/8240 12624/12638/8242 12625/12639/8243 +f 12626/12640/8244 12627/12641/8245 12628/12642/8246 +f 12626/12640/8244 12628/12642/8246 12629/12643/8247 +f 12634/12644/8248 12635/12645/8249 12636/12646/8250 +f 12634/12644/8248 12636/12646/8250 12637/12647/8251 +f 12638/12648/8252 12639/12649/8253 12640/12650/8253 +f 12638/12648/8252 12640/12650/8253 12641/12651/8254 +f 12642/12652/8255 12643/12653/8256 12644/12654/8256 +f 12642/12652/8255 12644/12654/8256 12645/12655/8257 +f 12650/12656/8258 12638/12648/8252 12641/12651/8254 +f 12650/12656/8258 12641/12651/8254 12651/12657/8259 +f 12623/12637/8241 12652/12658/8260 12653/12659/8261 +f 12623/12637/8241 12653/12659/8261 12624/12638/8242 +f 12654/12660/8262 12626/12640/8244 12629/12643/8247 +f 12654/12660/8262 12629/12643/8247 12655/12661/8263 +f 12611/12626/8232 12654/12660/8262 12655/12661/8263 +f 12611/12626/8232 12655/12661/8263 12612/12627/8233 +f 12656/12662/8264 12634/12644/8248 12637/12647/8251 +f 12656/12662/8264 12637/12647/8251 12657/12663/8265 +f 12658/12570/8266 12610/12625/8231 12613/12571/8234 +f 12619/12633/8237 12642/12652/8255 12645/12655/8257 +f 12619/12633/8237 12645/12655/8257 12620/12634/8238 +f 12660/12664/8267 12622/12636/8240 12625/12639/8243 +f 12660/12664/8267 12625/12639/8243 12661/12665/8268 +f 12635/12645/8249 12666/12666/8269 12667/12667/8270 +f 12635/12645/8249 12667/12667/8270 12636/12646/8250 +f 12627/12641/8245 12656/12662/8264 12657/12663/8265 +f 12627/12641/8245 12657/12663/8265 12628/12642/8246 +f 12668/12668/8271 12669/12669/8272 12670/12670/8272 +f 12668/12668/8271 12670/12670/8272 12671/12671/8271 +f 12652/12658/8260 12618/12632/8236 12621/12635/8239 +f 12652/12658/8260 12621/12635/8239 12653/12659/8261 +f 12672/12672/8273 12660/12664/8267 12661/12665/8268 +f 12672/12672/8273 12661/12665/8268 12673/12673/8273 +f 12676/12674/8274 12674/12675/8275 12675/12676/8276 +f 12674/12675/8275 12676/12674/8274 12580/12595/8202 +f 12674/12675/8275 12580/12595/8202 12570/12585/8192 +f 12678/12677/8277 12573/12588/8195 12677/12678/8277 +f 12573/12588/8195 12678/12677/8277 12674/12675/8275 +f 12573/12588/8195 12674/12675/8275 12570/12585/8192 +f 12679/12679/8278 12566/12581/8188 12562/12577/8184 +f 12566/12581/8188 12679/12679/8278 12680/12680/8279 +f 12566/12581/8188 12680/12680/8279 12681/12681/8279 +f 12682/12682/8280 12562/12577/8184 12565/12580/8187 +f 12562/12577/8184 12682/12682/8280 12683/12683/8280 +f 12562/12577/8184 12683/12683/8280 12679/12679/8278 +f 12686/12684/8281 12684/12685/8282 12685/12686/8282 +f 12684/12685/8282 12686/12684/8281 12604/12619/8225 +f 12604/12619/8225 12686/12684/8281 12594/12609/8216 +f 12595/12610/8217 12687/12687/8283 12688/12688/8283 +f 12687/12687/8283 12595/12610/8217 12686/12684/8281 +f 12686/12684/8281 12595/12610/8217 12594/12609/8216 +f 12590/12605/8212 12691/12689/8284 12586/12601/8208 +f 12691/12689/8284 12590/12605/8212 12690/12690/8285 +f 12690/12690/8285 12590/12605/8212 12689/12691/8286 +f 12586/12601/8208 12693/12692/8287 12587/12602/8209 +f 12693/12692/8287 12586/12601/8208 12692/12693/8288 +f 12692/12693/8288 12586/12601/8208 12691/12689/8284 +o Cylinder.030__0 +v -0.113946 -1.230260 0.658087 +v -0.108768 -1.219355 0.657988 +v -0.114614 -1.220955 0.658307 +v 0.114062 -1.230463 0.654317 +v 0.114753 -1.221159 0.654515 +v 0.108903 -1.219549 0.654389 +v -0.781805 -1.253157 0.139491 +v -0.781355 -1.210788 0.134197 +v -0.904623 -1.169269 -0.037368 +v -0.903407 -1.275118 -0.024338 +v -0.783973 -1.294358 0.168931 +v -0.905019 -1.352008 0.030288 +v -0.788924 -1.312199 0.210609 +v -0.904585 -1.397945 0.088567 +v -0.786637 -1.304572 0.257108 +v -0.902320 -1.422835 0.182528 +v -0.780812 -1.292963 0.297235 +v -0.895986 -1.415067 0.304996 +v -0.778320 -1.266835 0.330312 +v -0.896240 -1.397874 0.394965 +v -0.778049 -1.250420 0.339717 +v -0.897001 -1.351076 0.457486 +v -0.777771 -1.232907 0.346792 +v -0.891430 -1.288967 0.495195 +v -0.777431 -1.197344 0.349631 +v -0.777557 -1.218675 0.350880 +v -0.882282 -1.210067 0.494655 +v -0.880208 -1.180627 0.482260 +v -0.778712 -1.164490 0.315719 +v -0.777527 -1.185853 0.342798 +v -0.877039 -1.136605 0.455419 +v -0.874658 -1.104414 0.427707 +v -0.782772 -1.143855 0.276043 +v -0.879010 -1.043682 0.335955 +v -0.790718 -1.124690 0.233427 +v -0.882982 -1.010842 0.249534 +v -0.789347 -1.128369 0.197286 +v -0.888316 -0.999703 0.129570 +v -0.786827 -1.139248 0.148573 +v -0.897864 -1.016744 0.042210 +v -0.783349 -1.182151 0.137493 +v -0.905367 -1.105348 -0.021857 +v -0.781683 -1.234130 0.194813 +v -0.781574 -1.212293 0.192095 +v -0.782766 -1.254679 0.209528 +v -0.785162 -1.263266 0.229619 +v -0.784337 -1.259307 0.253893 +v -0.781173 -1.253149 0.275244 +v -0.779904 -1.239872 0.292083 +v -0.779766 -1.229672 0.297948 +v -0.779619 -1.219095 0.302136 +v -0.779619 -1.205707 0.300311 +v -0.779550 -1.214136 0.303324 +v -0.780210 -1.190699 0.283766 +v -0.779824 -1.198740 0.293938 +v -0.781406 -1.182440 0.268545 +v -0.786702 -1.169831 0.240635 +v -0.785518 -1.171956 0.219726 +v -0.783411 -1.186101 0.196193 +v -0.782219 -1.202598 0.193209 +v -0.190407 -0.977685 -0.161382 +v -0.013166 -0.975363 -0.157306 +v -0.013587 -1.175081 -0.171976 +v -0.189860 -1.177478 -0.176119 +v -0.178498 -1.335239 0.647226 +v -0.000406 -1.337287 0.633876 +v -0.000327 -1.313850 0.637424 +v -0.178386 -1.312579 0.651879 +v -0.181674 -1.534256 0.548482 +v -0.002118 -1.529087 0.540697 +v -0.000582 -1.389159 0.626022 +v -0.178782 -1.392000 0.635154 +v -0.178299 -1.620323 0.405483 +v -0.004513 -1.612887 0.400356 +v -0.002118 -1.529087 0.540697 +v -0.181674 -1.534256 0.548482 +v -0.174532 -1.648092 0.228593 +v -0.007413 -1.639175 0.226396 +v -0.187659 -1.601874 0.009913 +v -0.010934 -1.595058 0.011085 +v -0.192856 -1.499557 -0.121125 +v -0.012975 -1.494957 -0.117717 +v -0.192039 -1.342340 -0.176068 +v -0.013730 -1.339518 -0.171760 +v -0.012975 -1.494957 -0.117717 +v -0.192856 -1.499557 -0.121125 +v -0.178323 -1.312078 0.655813 +v -0.000262 -1.313388 0.641287 +v -0.000070 -1.311991 0.652869 +v -0.178125 -1.310564 0.667593 +v -0.178355 -1.312328 0.653846 +v -0.000295 -1.313619 0.639356 +v -0.187001 -0.854508 -0.062226 +v -0.011440 -0.851363 -0.059563 +v -0.013350 -0.964914 -0.168958 +v -0.190835 -0.966989 -0.173238 +v -0.183337 -0.812669 0.089175 +v -0.008939 -0.808604 0.089397 +v -0.011440 -0.851363 -0.059563 +v -0.187001 -0.854508 -0.062226 +v -0.735578 -0.949478 -0.192977 +v -0.929075 -0.940678 -0.194026 +v -0.929167 -0.939221 -0.195663 +v -0.735666 -0.948024 -0.194602 +v -0.929711 -0.930464 -0.205471 +v -0.736205 -0.939297 -0.204315 +v -0.190512 -0.975017 -0.164346 +v -0.378758 -0.973509 -0.175524 +v -0.379274 -0.965148 -0.184732 +v -0.190835 -0.966989 -0.173238 +v -0.190459 -0.976351 -0.162865 +v -0.378675 -0.974898 -0.173989 +v -0.537244 -1.294722 0.709505 +v -0.366828 -1.295584 0.689614 +v -0.366203 -1.092940 0.686978 +v -0.536421 -1.085910 0.704783 +v -0.536421 -1.085910 0.704783 +v -0.366203 -1.092940 0.686978 +v -0.365198 -0.977583 0.589086 +v -0.534263 -0.963683 0.603662 +v -0.366421 -0.874983 0.444213 +v -0.534921 -0.855552 0.453663 +v -0.363209 -0.837718 0.272443 +v -0.528732 -0.817232 0.275710 +v -0.366509 -0.810259 0.086042 +v -0.532147 -0.789599 0.082532 +v -0.372949 -0.851900 -0.070395 +v -0.540545 -0.833097 -0.079416 +v -0.540545 -0.833097 -0.079416 +v -0.372949 -0.851900 -0.070395 +v -0.379274 -0.965148 -0.184732 +v -0.549205 -0.951133 -0.197342 +v -0.537480 -1.312297 0.695209 +v -0.367057 -1.312691 0.675620 +v -0.367036 -1.312412 0.677640 +v -0.537452 -1.312020 0.697305 +v -0.366874 -1.310746 0.689812 +v -0.537304 -1.310346 0.709858 +v -0.545556 -1.174886 -0.200776 +v -0.376683 -1.179439 -0.187694 +v -0.381204 -1.347487 -0.187839 +v -0.552051 -1.351497 -0.201060 +v -0.384026 -1.509117 -0.130882 +v -0.556488 -1.519448 -0.141823 +v -0.556488 -1.519448 -0.141823 +v -0.384026 -1.509117 -0.130882 +v -0.375012 -1.615542 0.004557 +v -0.544257 -1.630556 -0.001937 +v -0.350110 -1.665188 0.230331 +v -0.509482 -1.684634 0.231582 +v -0.362003 -1.635065 0.413321 +v -0.528134 -1.651507 0.421376 +v -0.528134 -1.651507 0.421376 +v -0.362003 -1.635065 0.413321 +v -0.372296 -1.544988 0.561381 +v -0.544226 -1.556571 0.574533 +v -0.367693 -1.398012 0.650956 +v -0.538967 -1.415768 0.660377 +v -0.537789 -1.337832 0.685385 +v -0.367219 -1.335192 0.667712 +v -0.367076 -1.312970 0.673599 +v -0.537507 -1.312575 0.693114 +v -0.548506 -0.962599 -0.184635 +v -0.378591 -0.976286 -0.172453 +v -0.727359 -1.433138 0.664305 +v -0.725616 -1.338692 0.698477 +v -0.735490 -0.950931 -0.191353 +v -0.731815 -1.170229 -0.207899 +v -0.725199 -1.310297 0.708212 +v -0.733237 -1.564231 0.584421 +v -0.711666 -1.662869 0.427819 +v -0.686810 -1.698867 0.233502 +v -0.711666 -1.662869 0.427819 +v -0.730633 -1.640751 -0.005016 +v -0.745898 -1.526283 -0.147860 +v -0.740019 -1.353751 -0.208440 +v -0.745898 -1.526283 -0.147860 +v -0.725139 -1.309752 0.712487 +v -0.724917 -1.308127 0.725371 +v -0.724697 -1.304427 0.710063 +v -0.725350 -0.817744 -0.084045 +v -0.736205 -0.939297 -0.204315 +v -0.715177 -0.772898 0.081518 +v -0.725350 -0.817744 -0.084045 +v -0.711662 -0.800228 0.279173 +v -0.720744 -0.839093 0.461175 +v -0.720812 -0.951871 0.614382 +v -0.723932 -1.079891 0.717641 +v -0.724849 -1.292239 0.724833 +v -0.723932 -1.079891 0.717641 +v -0.548676 -0.959736 -0.187818 +v -0.549205 -0.951133 -0.197342 +v -0.548590 -0.961167 -0.186226 +v -0.013190 -0.974059 -0.158764 +v -0.013212 -0.972755 -0.160222 +v -0.013350 -0.964914 -0.168958 +v -0.178093 -1.295497 0.667768 +v -0.177662 -1.094131 0.670102 +v -0.177662 -1.094131 0.670102 +v -0.178015 -0.980545 0.575496 +v -0.179706 -0.878612 0.435503 +v -0.179666 -0.840142 0.269492 +v -0.178299 -1.620323 0.405483 +v -0.918595 -1.287155 0.773391 +v -0.918141 -1.075192 0.725346 +v -0.918141 -1.075192 0.725346 +v -0.913853 -0.942881 0.621062 +v -0.912997 -0.826771 0.466508 +v -0.900639 -0.761482 0.281714 +v -0.904168 -0.734869 0.082153 +v -0.916398 -0.806982 -0.084078 +v -0.916398 -0.806982 -0.084078 +v -0.929711 -0.930464 -0.205471 +v -0.959394 -1.080103 0.713907 +v -0.946043 -1.080955 0.711664 +v -0.915255 -1.081003 0.711155 +v -0.915216 -1.080172 0.713177 +v -0.918989 -1.304874 0.755821 +v -0.918628 -1.303015 0.776985 +v -0.924374 -1.165860 -0.208928 +v -0.934551 -1.354151 -0.209889 +v -0.942152 -1.529281 -0.148835 +v -0.942152 -1.529281 -0.148835 +v -0.923456 -1.645543 -0.004564 +v -0.869184 -1.706006 0.236056 +v -0.901328 -1.668311 0.432362 +v -0.901328 -1.668311 0.432362 +v -0.929218 -1.567600 0.590765 +v -0.922590 -1.448138 0.663441 +v -0.920213 -1.337824 0.706598 +v -0.919436 -1.306188 0.729078 +v -0.928985 -0.942137 -0.192388 +v -1.050273 -0.830338 0.278091 +v -1.054795 -0.805354 0.090465 +v -1.027924 -0.805948 0.089999 +v -1.022455 -0.830894 0.277611 +v -1.087551 -1.342731 -0.177618 +v -1.074536 -1.166585 -0.174861 +v -1.085502 -1.165428 -0.206253 +v -1.097339 -1.353879 -0.207192 +v -1.097510 -1.507316 -0.123046 +v -1.106372 -1.529047 -0.146116 +v -1.075034 -1.617287 0.011129 +v -1.084905 -1.645954 -0.001915 +v -1.016500 -1.676070 0.239624 +v -1.022133 -1.708260 0.238494 +v -1.050969 -1.639532 0.423808 +v -1.060258 -1.669185 0.434952 +v -1.085030 -1.543857 0.571988 +v -1.093313 -1.567363 0.593482 +v -1.077152 -1.431582 0.639286 +v -1.085787 -1.447877 0.666144 +v -1.073733 -1.320905 0.680932 +v -1.082505 -1.328343 0.711271 +v -1.072578 -1.175479 0.691846 +v -1.072863 -1.249818 0.700151 +v -1.081659 -1.251034 0.732174 +v -1.081405 -1.169814 0.722448 +v -1.066589 -0.975159 0.589377 +v -1.072268 -1.094701 0.682822 +v -1.081130 -1.081560 0.711880 +v -1.075748 -0.953046 0.611418 +v -1.064114 -0.866729 0.448761 +v -1.073861 -0.837438 0.461665 +v -1.050273 -0.830338 0.278091 +v -1.058154 -0.799757 0.282140 +v -1.054795 -0.805354 0.090465 +v -1.061229 -0.774226 0.087111 +v -1.067294 -0.845049 -0.054356 +v -1.075335 -0.817766 -0.071837 +v -1.080584 -0.954992 -0.161295 +v -1.090968 -0.940116 -0.189638 +v -0.954148 -1.569240 0.038610 +v -0.916474 -1.618742 0.241843 +v -1.050969 -1.639532 0.423808 +v -1.085030 -1.543857 0.571988 +v -1.056806 -1.543777 0.571526 +v -1.024226 -1.639191 0.423380 +v -1.067294 -0.845049 -0.054356 +v -1.040279 -0.845462 -0.054818 +v -1.077152 -1.431582 0.639286 +v -1.048496 -1.431499 0.638817 +v -1.067294 -0.845049 -0.054356 +v -1.080584 -0.954992 -0.161295 +v -1.052948 -0.954918 -0.161748 +v -1.040279 -0.845462 -0.054818 +v -1.073733 -1.320905 0.680932 +v -1.072863 -1.249818 0.700151 +v -1.044014 -1.249732 0.699678 +v -1.044912 -1.320820 0.680460 +v -1.074536 -1.166585 -0.174861 +v -1.087551 -1.342731 -0.177618 +v -1.058705 -1.342646 -0.178091 +v -1.045263 -1.166425 -0.175338 +v -1.072578 -1.175479 0.691846 +v -1.072268 -1.094701 0.682822 +v -1.043377 -1.094614 0.682348 +v -1.043709 -1.175392 0.691373 +v -1.097510 -1.507316 -0.123046 +v -1.069298 -1.507247 -0.123509 +v -1.072268 -1.094701 0.682822 +v -1.066589 -0.975159 0.589377 +v -1.037306 -0.975071 0.588897 +v -1.043377 -1.094614 0.682348 +v -1.097510 -1.507316 -0.123046 +v -1.075034 -1.617287 0.011129 +v -1.047954 -1.617034 0.010692 +v -1.069298 -1.507247 -0.123509 +v -1.064114 -0.866729 0.448761 +v -1.035592 -0.867067 0.448278 +v -1.016500 -1.676070 0.239624 +v -0.990761 -1.675621 0.239216 +v -1.050969 -1.639532 0.423808 +v -1.024226 -1.639191 0.423380 +v -0.934737 -0.912011 0.426113 +v -0.927150 -0.879513 0.274621 +v -0.936614 -1.588168 0.404500 +v -0.935619 -0.856756 0.107494 +v -0.952739 -1.506362 0.535074 +v -0.945065 -0.891259 -0.019473 +v -0.944238 -1.406981 0.594349 +v -0.953038 -0.984147 -0.105704 +v -0.941523 -1.333980 0.621782 +v -0.941471 -1.165584 -0.187831 +v -0.955225 -1.346247 -0.189927 +v -0.930021 -1.343117 -0.182081 +v -0.916116 -1.166031 -0.179484 +v -0.939538 -1.208067 0.643640 +v -0.939274 -1.155600 0.637908 +v -0.940001 -1.170422 -0.117252 +v -0.981447 -1.345615 -0.192005 +v -0.967093 -1.164207 -0.188896 +v -0.936674 -1.072334 0.602504 +v -0.932626 -1.006766 0.550498 +v -0.963933 -1.473904 -0.080032 +v -0.980171 -0.947574 -0.174872 +v -0.993744 -1.514887 -0.135835 +v -0.979332 -1.626310 0.002273 +v -0.993744 -1.514887 -0.135835 +v -0.930610 -1.684664 0.237387 +v -0.957741 -1.648474 0.426502 +v -1.056806 -1.543777 0.571526 +v -0.980807 -1.552423 0.578516 +v -0.971361 -1.437004 0.647664 +v -0.980807 -1.552423 0.578516 +v -0.966340 -1.250177 0.710210 +v -0.967324 -1.323241 0.690459 +v -0.965591 -1.090744 0.692397 +v -0.965981 -1.173769 0.701674 +v -0.958475 -0.968869 0.596297 +v -0.965591 -1.090744 0.692397 +v -0.959842 -0.858700 0.451789 +v -0.949414 -0.821509 0.276429 +v -0.957923 -0.795596 0.083661 +v -0.969577 -0.836008 -0.065191 +v -0.969577 -0.836008 -0.065191 +v -0.952731 -1.326345 -0.129204 +v -0.916562 -1.637117 0.422450 +v -0.929824 -1.545091 0.570803 +v -0.928992 -0.821527 0.276092 +v -0.939421 -0.858719 0.451451 +v -0.958910 -1.626328 0.001936 +v -0.973322 -1.514905 -0.136173 +v -0.914367 -1.093696 0.681949 +v -0.907470 -0.975563 0.588187 +v -0.916116 -1.166031 -0.179484 +v -0.930021 -1.343117 -0.182081 +v -0.954442 -1.551654 0.577140 +v -0.936613 -1.646352 0.425797 +v -0.916191 -1.646370 0.425459 +v -0.934020 -1.551672 0.576803 +v -0.946671 -1.164225 -0.189234 +v -0.959750 -0.947592 -0.175210 +v -0.913238 -0.805921 0.087807 +v -0.923369 -0.845842 -0.057741 +v -0.896558 -1.671236 0.237829 +v -0.945192 -1.437229 0.646051 +v -0.924770 -1.437247 0.645713 +v -0.950939 -1.437022 0.647326 +v -0.960385 -1.552441 0.578178 +v -0.915111 -1.249573 0.699447 +v -0.914755 -1.174870 0.691061 +v -0.940040 -1.249944 0.708712 +v -0.941101 -1.323165 0.689001 +v -0.920679 -1.323183 0.688663 +v -0.919619 -1.249962 0.708375 +v -0.938053 -0.968887 0.595959 +v -0.903565 -0.831301 0.275834 +v -0.934826 -1.616066 0.008093 +v -0.967270 -1.514511 -0.133107 +v -0.942483 -1.508445 -0.127067 +v -0.967270 -1.514511 -0.133107 +v -0.956518 -1.624725 0.004756 +v -0.934826 -1.616066 0.008093 +v -0.942483 -1.508445 -0.127067 +v -0.912402 -1.681791 0.237689 +v -0.896558 -1.671236 0.237829 +v -0.936613 -1.646352 0.425797 +v -0.916562 -1.637117 0.422450 +v -0.936613 -1.646352 0.425797 +v -0.954442 -1.551654 0.577140 +v -0.929824 -1.545091 0.570803 +v -0.916562 -1.637117 0.422450 +v -0.945192 -1.437229 0.646051 +v -0.920333 -1.432327 0.638427 +v -0.941101 -1.323165 0.689001 +v -0.940040 -1.249944 0.708712 +v -0.915111 -1.249573 0.699447 +v -0.916186 -1.321066 0.680203 +v -0.939698 -1.173281 0.699934 +v -0.939326 -1.089979 0.690395 +v -0.914367 -1.093696 0.681949 +v -0.914755 -1.174870 0.691061 +v -0.939326 -1.089979 0.690395 +v -0.932603 -0.968711 0.594709 +v -0.907470 -0.975563 0.588187 +v -0.914367 -1.093696 0.681949 +v -0.934947 -0.859545 0.450825 +v -0.910831 -0.868396 0.446861 +v -0.925899 -0.822389 0.277307 +v -0.903565 -0.831301 0.275834 +v -0.934467 -0.797079 0.087204 +v -0.913238 -0.805921 0.087807 +v -0.945461 -0.838009 -0.062260 +v -0.923369 -0.845842 -0.057741 +v -0.945461 -0.838009 -0.062260 +v -0.955681 -0.950373 -0.172949 +v -0.932085 -0.954793 -0.165428 +v -0.923369 -0.845842 -0.057741 +v -0.932085 -0.954793 -0.165428 +v -0.973322 -1.514905 -0.136173 +v -0.961025 -1.345633 -0.192343 +v -0.939698 -1.173281 0.699934 +v -0.919569 -1.238826 0.707100 +v -0.942483 -1.508445 -0.127067 +v -0.910831 -0.868396 0.446861 +v -0.949155 -0.836026 -0.065528 +v -0.932603 -0.968711 0.594709 +v -0.939326 -1.089979 0.690395 +v -0.918904 -1.089997 0.690057 +v -0.912182 -0.968730 0.594372 +v -0.920333 -1.432327 0.638427 +v -0.957741 -1.648474 0.426502 +v -0.937319 -1.648492 0.426164 +v -0.934947 -0.859545 0.450825 +v -0.914525 -0.859563 0.450488 +v -0.945169 -1.090762 0.692060 +v -0.916186 -1.321066 0.680203 +v -0.946902 -1.323259 0.690121 +v -0.953440 -0.838747 0.460515 +v -0.954812 -0.952669 0.610929 +v -0.954785 -0.951120 0.612479 +v -0.953464 -0.836779 0.461478 +v -0.954812 -0.952669 0.610929 +v -0.954785 -0.951120 0.612479 +v -0.959470 -1.238101 0.753918 +v -0.959394 -1.080103 0.713907 +v -0.915216 -1.080172 0.713177 +v -0.915801 -1.229037 0.753079 +v -1.085502 -1.165428 -0.206253 +v -0.965005 -1.165629 -0.208249 +v -0.975600 -1.354083 -0.209209 +v -1.097339 -1.353879 -0.207192 +v -0.983562 -1.529222 -0.148149 +v -1.106372 -1.529047 -0.146116 +v -1.106372 -1.529047 -0.146116 +v -0.983562 -1.529222 -0.148149 +v -0.964167 -1.645647 -0.003896 +v -1.084905 -1.645954 -0.001915 +v -0.907751 -1.706575 0.236670 +v -1.022133 -1.708260 0.238494 +v -0.941404 -1.668532 0.433015 +v -1.060258 -1.669185 0.434952 +v -1.060258 -1.669185 0.434952 +v -0.941404 -1.668532 0.433015 +v -0.970596 -1.567540 0.591450 +v -1.093313 -1.567363 0.593482 +v -0.963742 -1.448072 0.664123 +v -1.085787 -1.447877 0.666144 +v -1.082505 -1.328343 0.711271 +v -0.961532 -1.335290 0.702111 +v -0.959923 -1.251238 0.730158 +v -1.081659 -1.251034 0.732174 +v -1.081405 -1.169814 0.722448 +v -0.959707 -1.170019 0.720432 +v -0.959471 -1.081765 0.709864 +v -1.081130 -1.081560 0.711880 +v -1.081130 -1.081560 0.711880 +v -0.959471 -1.081765 0.709864 +v -0.954839 -0.954218 0.609379 +v -1.075748 -0.953046 0.611418 +v -0.953416 -0.840715 0.459553 +v -1.073861 -0.837438 0.461665 +v -0.939724 -0.803455 0.280045 +v -1.058154 -0.799757 0.282140 +v -0.942812 -0.777331 0.085039 +v -1.061229 -0.774226 0.087111 +v -0.955681 -0.820253 -0.073906 +v -1.075335 -0.817766 -0.071837 +v -1.075335 -0.817766 -0.071837 +v -0.955681 -0.820253 -0.073906 +v -0.969830 -0.941078 -0.191674 +v -1.090968 -0.940116 -0.189638 +v -0.959470 -1.238101 0.753918 +v -0.959476 -1.249923 0.756912 +v -0.959250 -1.248353 0.769921 +v -0.959244 -1.236293 0.766865 +v -0.970012 -0.938168 -0.194949 +v -0.970556 -0.929433 -0.204757 +v -0.970012 -0.938168 -0.194949 +v -0.955946 -0.816562 -0.076272 +v -0.956743 -0.805484 -0.083361 +v -0.970556 -0.929433 -0.204757 +v -0.939822 -0.774769 0.279522 +v -0.939929 -0.772487 0.279935 +v -0.942965 -0.748610 0.083945 +v -0.943127 -0.746292 0.083789 +v -0.969921 -0.939623 -0.193311 +v -0.955814 -0.818407 -0.075089 +v -0.969921 -0.939623 -0.193311 +v -0.959394 -1.080103 0.713907 +v -0.959162 -1.075119 0.726026 +v -0.954622 -0.941831 0.621775 +v -0.953608 -0.824970 0.467249 +v -0.940571 -0.759602 0.282445 +v -0.944096 -0.733191 0.082874 +v -0.959244 -1.236293 0.766865 +v -0.959162 -1.075119 0.726026 +v -0.959162 -1.075119 0.726026 +v -0.954622 -0.941831 0.621775 +v -0.953608 -0.824970 0.467249 +v -0.940571 -0.759602 0.282445 +v -0.944096 -0.733191 0.082874 +v -0.956743 -0.805484 -0.083361 +v -0.956743 -0.805484 -0.083361 +v -0.970556 -0.929433 -0.204757 +v -0.946641 -1.250163 0.732073 +v -0.911878 -1.301300 0.730894 +v -0.894584 -1.284253 0.730093 +v -0.916189 -1.241885 0.731488 +v -0.918989 -1.304874 0.755821 +v -0.918628 -1.303015 0.776985 +v -0.000017 -1.277498 0.654202 +v 0.000193 -1.290566 0.667612 +v -0.178125 -1.310564 0.667593 +v -0.000070 -1.311991 0.652869 +v -0.140369 -0.814516 0.106879 +v -0.008713 -0.810773 0.103183 +v -0.128540 -1.230349 0.662866 +v -0.136826 -1.094468 0.668046 +v -0.136826 -1.094468 0.668046 +v -0.132995 -0.981042 0.574321 +v -0.134324 -0.878469 0.434819 +v -0.135588 -0.839361 0.268961 +v -0.123114 -0.845451 0.267558 +v -0.126150 -0.821431 0.111369 +v -0.128540 -1.230349 0.662866 +v 0.000193 -1.290566 0.667612 +v -0.113946 -1.230260 0.658087 +v -0.114614 -1.220955 0.658307 +v -0.123705 -0.884239 0.431886 +v -0.008581 -0.818589 0.111548 +v -0.122775 -0.985789 0.569586 +v -0.117128 -0.845339 0.267489 +v -0.006056 -0.842833 0.265594 +v -0.008541 -0.818980 0.114028 +v -0.120118 -0.821686 0.113857 +v -0.117711 -0.884220 0.431799 +v -0.003417 -0.882671 0.427331 +v -0.116786 -0.985860 0.569433 +v -0.001261 -0.984407 0.563210 +v -0.117556 -1.096590 0.660946 +v 0.000149 -1.095614 0.654489 +v -0.000038 -1.249284 0.651400 +v 0.000149 -1.095614 0.654489 +v -0.117556 -1.096590 0.660946 +v -0.123535 -1.096578 0.661246 +v -0.000052 -1.260782 0.651169 +v -0.123535 -1.096578 0.661246 +v -0.903991 -1.437266 0.645370 +v -0.899900 -1.323202 0.688319 +v -0.910189 -1.684682 0.237049 +v -0.889409 -1.684700 0.236706 +v -0.938131 -1.626347 0.001592 +v -0.898840 -1.249980 0.708031 +v -0.918641 -0.858737 0.451107 +v -0.917274 -0.968906 0.595615 +v -0.898790 -1.238844 0.706756 +v -0.952543 -1.514924 -0.136516 +v -0.898125 -1.090015 0.689714 +v -0.891402 -0.968748 0.594028 +v -0.924390 -1.090781 0.691716 +v -0.893746 -0.859582 0.450144 +v -0.952543 -1.514924 -0.136516 +v -0.940246 -1.345652 -0.192687 +v -0.905477 -0.822407 0.276969 +v -0.884698 -0.822426 0.276626 +v -0.925892 -1.164243 -0.189577 +v -0.945559 -1.173787 0.701336 +v -0.945169 -1.090762 0.692060 +v -0.924390 -1.090781 0.691716 +v -0.925087 -1.239114 0.708289 +v -0.914045 -0.797097 0.086866 +v -0.893265 -0.797115 0.086522 +v -0.934803 -1.346265 -0.190264 +v -0.921049 -1.165602 -0.188169 +v -0.900270 -1.165621 -0.188512 +v -0.914024 -1.346284 -0.190608 +v -0.925039 -0.838027 -0.062598 +v -0.904260 -0.838045 -0.062941 +v -0.935259 -0.950391 -0.173287 +v -0.914479 -0.950409 -0.173630 +v -0.936613 -1.646352 0.425797 +v -0.912402 -1.681791 0.237689 +v -0.891980 -1.681810 0.237351 +v -0.916191 -1.646370 0.425459 +v -0.956518 -1.624725 0.004756 +v -0.936096 -1.624743 0.004418 +v -0.945918 -1.250195 0.709873 +v -0.967270 -1.514511 -0.133107 +v -0.946849 -1.514529 -0.133445 +v -0.937501 -0.795615 0.083323 +v -0.955225 -1.346247 -0.189927 +v -0.941471 -1.165584 -0.187831 +v -0.967270 -1.514511 -0.133107 +v -0.946849 -1.514529 -0.133445 +v -0.955681 -0.950373 -0.172949 +v -0.945461 -0.838009 -0.062260 +v -0.925039 -0.838027 -0.062598 +v -0.945461 -0.838009 -0.062260 +v -0.934467 -0.797079 0.087204 +v -0.937319 -1.648492 0.426164 +v -0.925899 -0.822389 0.277307 +v -0.949155 -0.836026 -0.065528 +v -0.893746 -0.859582 0.450144 +v -0.891402 -0.968748 0.594028 +v -0.926069 -1.514547 -0.133789 +v -0.914024 -1.346284 -0.190608 +v -0.928376 -0.836044 -0.065872 +v -0.938971 -0.947610 -0.175553 +v -0.914479 -0.950409 -0.173630 +v -0.904260 -0.838045 -0.062941 +v -0.916539 -1.648511 0.425820 +v -0.939606 -1.552459 0.577835 +v -0.913242 -1.551690 0.576459 +v -0.895412 -1.646388 0.425115 +v -0.898125 -1.090015 0.689714 +v -0.900270 -1.165621 -0.188512 +v -0.916723 -0.795633 0.082980 +v -0.928376 -0.836044 -0.065872 +v -0.904260 -0.838045 -0.062941 +v -0.893265 -0.797115 0.086522 +v -0.916539 -1.648511 0.425820 +v -0.895412 -1.646388 0.425115 +v -0.871201 -1.681828 0.237008 +v -0.930160 -1.437041 0.646982 +v -0.903991 -1.437266 0.645370 +v -0.915317 -1.624761 0.004075 +v -0.926069 -1.514547 -0.133789 +v -0.908213 -0.821545 0.275748 +v -0.884698 -0.822426 0.276626 +v -0.926123 -1.323278 0.689778 +v -0.925139 -1.250213 0.709529 +v -0.898840 -1.249980 0.708031 +v -0.899900 -1.323202 0.688319 +v -0.898125 -1.090015 0.689714 +v -0.898790 -1.238844 0.706756 +v -0.913242 -1.551690 0.576459 +v -0.895412 -1.646388 0.425115 +v -0.871201 -1.681828 0.237008 +v -0.895412 -1.646388 0.425115 +v -0.915317 -1.624761 0.004075 +v -0.926069 -1.514547 -0.133789 +v -0.926069 -1.514547 -0.133789 +v -0.904260 -0.838045 -0.062941 +v -0.969830 -0.941078 -0.191674 +v -0.955681 -0.820253 -0.073906 +v -0.955814 -0.818407 -0.075089 +v -0.955681 -0.820253 -0.073906 +v -0.888695 -0.820264 -0.075783 +v -0.888828 -0.818418 -0.076966 +v -0.928985 -0.942137 -0.192388 +v -0.969830 -0.941078 -0.191674 +v -0.939822 -0.774769 0.279522 +v -0.942965 -0.748610 0.083945 +v -0.875952 -0.748616 0.082490 +v -0.872800 -0.774777 0.278874 +v -0.872706 -0.803465 0.279555 +v -0.875800 -0.777338 0.083547 +v -0.946600 -1.238384 0.730652 +v -0.946043 -1.080955 0.711664 +v -0.954812 -0.952669 0.610929 +v -0.953416 -0.840715 0.459553 +v -0.954839 -0.954218 0.609379 +v -0.548506 -0.962599 -0.184635 +v -0.735490 -0.950931 -0.191353 +v -0.724697 -1.304427 0.710063 +v -0.367076 -1.312970 0.673599 +v -0.178386 -1.312579 0.651879 +v -0.013166 -0.975363 -0.157306 +v -0.190407 -0.977685 -0.161382 +v -0.378591 -0.976286 -0.172453 +v -0.537480 -1.312297 0.695209 +v -0.537507 -1.312575 0.693114 +v -0.000327 -1.313850 0.637424 +v -0.888695 -0.820264 -0.075783 +v -0.875800 -0.777338 0.083547 +v -0.875952 -0.748616 0.082490 +v -0.888828 -0.818418 -0.076966 +v -0.872706 -0.803465 0.279555 +v -0.872800 -0.774777 0.278874 +v -0.886425 -0.840730 0.459541 +v -0.886449 -0.838762 0.460503 +v -0.955814 -0.818407 -0.075089 +v -0.888828 -0.818418 -0.076966 +v -0.953416 -0.840715 0.459553 +v -0.953440 -0.838747 0.460515 +v -0.886449 -0.838762 0.460503 +v -0.886425 -0.840730 0.459541 +v -0.888695 -0.820264 -0.075783 +v -0.953440 -0.838747 0.460515 +v -0.886449 -0.838762 0.460503 +v -0.886425 -0.840730 0.459541 +v -0.894584 -1.284253 0.730093 +v -0.723611 -1.291554 0.709406 +v -0.723581 -1.291282 0.711543 +v -0.887792 -1.285408 0.754681 +v -0.916124 -1.230240 0.730072 +v -0.916189 -1.241885 0.731488 +v -0.915845 -1.240655 0.756065 +v -0.915801 -1.229037 0.753079 +v -0.894584 -1.284253 0.730093 +v -0.887792 -1.285408 0.754681 +v -0.724697 -1.304427 0.710063 +v -0.725139 -1.309752 0.712487 +v -0.723581 -1.291282 0.711543 +v -0.723611 -1.291554 0.709406 +v -0.723611 -1.291554 0.709406 +v -0.918989 -1.304874 0.755821 +v -0.959476 -1.249923 0.756912 +v -0.915845 -1.240655 0.756065 +v -0.887792 -1.285408 0.754681 +v -0.916124 -1.230240 0.730072 +v -0.725139 -1.309752 0.712487 +v -0.723581 -1.291282 0.711543 +v -0.946043 -1.080955 0.711664 +v -0.915255 -1.081003 0.711155 +v -0.915255 -1.081003 0.711155 +v -0.915216 -1.080172 0.713177 +v -0.918904 -1.089997 0.690057 +v -0.898125 -1.090015 0.689714 +v -0.959250 -1.248353 0.769921 +v -0.918628 -1.303015 0.776985 +v -0.939326 -1.089979 0.690395 +v -0.724917 -1.308127 0.725371 +v -0.366874 -1.310746 0.689812 +v -0.537304 -1.310346 0.709858 +v 0.764368 -1.254533 0.113924 +v 0.880448 -1.276706 -0.053834 +v 0.881420 -1.170859 -0.066901 +v 0.763818 -1.212163 0.108647 +v 0.767434 -1.295739 0.143278 +v 0.883728 -1.353600 0.000711 +v 0.773730 -1.313589 0.184770 +v 0.885139 -1.399538 0.058974 +v 0.772994 -1.305960 0.231319 +v 0.885937 -1.424427 0.152959 +v 0.768520 -1.294341 0.271616 +v 0.883670 -1.416651 0.275569 +v 0.767169 -1.268210 0.304757 +v 0.886928 -1.399461 0.365480 +v 0.767239 -1.251795 0.314165 +v 0.889840 -1.352666 0.427940 +v 0.767226 -1.234282 0.321245 +v 0.885629 -1.290549 0.465810 +v 0.767043 -1.198718 0.324092 +v 0.874178 -1.182189 0.453250 +v 0.876608 -1.211632 0.465571 +v 0.767173 -1.220050 0.325337 +v 0.767261 -1.165866 0.290156 +v 0.866964 -1.105964 0.398909 +v 0.870203 -1.138160 0.426528 +v 0.766934 -1.187227 0.317260 +v 0.770044 -1.145237 0.250367 +v 0.868388 -1.045237 0.307061 +v 0.776611 -1.126084 0.207510 +v 0.869559 -1.012401 0.220555 +v 0.774039 -1.129760 0.171435 +v 0.870944 -1.001269 0.100481 +v 0.769890 -1.140633 0.122832 +v 0.877568 -1.018324 0.012852 +v 0.765971 -1.183530 0.111875 +v 0.882791 -1.106939 -0.051425 +v 0.766109 -1.235508 0.169220 +v 0.765949 -1.213670 0.166506 +v 0.767641 -1.256059 0.183891 +v 0.770685 -1.264651 0.203892 +v 0.770670 -1.260691 0.228181 +v 0.768225 -1.254528 0.249624 +v 0.767536 -1.241249 0.266496 +v 0.767611 -1.231049 0.272362 +v 0.767621 -1.220472 0.276552 +v 0.767584 -1.207084 0.274727 +v 0.767600 -1.215513 0.277741 +v 0.767656 -1.192076 0.258172 +v 0.767592 -1.200117 0.268351 +v 0.768362 -1.183819 0.242919 +v 0.772754 -1.171219 0.214849 +v 0.770877 -1.173341 0.193990 +v 0.767967 -1.187482 0.170540 +v 0.766648 -1.203976 0.167598 +v 0.163837 -0.978000 -0.167240 +v 0.162447 -1.177791 -0.181944 +v 0.178032 -1.335556 0.641330 +v 0.178114 -1.312896 0.645984 +v 0.177588 -1.534576 0.542541 +v 0.177815 -1.392318 0.629257 +v 0.169334 -1.620633 0.399735 +v 0.177588 -1.534576 0.542541 +v 0.159671 -1.648389 0.223067 +v 0.165643 -1.602189 0.004071 +v 0.166687 -1.499877 -0.127070 +v 0.164334 -1.342657 -0.181960 +v 0.166687 -1.499877 -0.127070 +v 0.178182 -1.312395 0.649919 +v 0.178376 -1.310881 0.661698 +v 0.178148 -1.312646 0.647951 +v 0.163930 -0.854820 -0.068029 +v 0.163892 -0.967304 -0.179103 +v 0.165349 -0.812979 0.083409 +v 0.163930 -0.854820 -0.068029 +v 0.707715 -0.950762 -0.216843 +v 0.707752 -0.949309 -0.218470 +v 0.901127 -0.940849 -0.225928 +v 0.901087 -0.942307 -0.224288 +v 0.707985 -0.940582 -0.228195 +v 0.901362 -0.932094 -0.235749 +v 0.163849 -0.975332 -0.170206 +v 0.163892 -0.967304 -0.179103 +v 0.351851 -0.965799 -0.196822 +v 0.351624 -0.974159 -0.187601 +v 0.163843 -0.976666 -0.168723 +v 0.351590 -0.975547 -0.186064 +v 0.538712 -1.295680 0.691713 +v 0.538106 -1.086867 0.687016 +v 0.367379 -1.093593 0.674848 +v 0.367730 -1.296237 0.677468 +v 0.538106 -1.086867 0.687016 +v 0.532823 -0.964633 0.586017 +v 0.363345 -0.978231 0.577039 +v 0.367379 -1.093593 0.674848 +v 0.528714 -0.856499 0.436075 +v 0.359959 -0.875630 0.432202 +v 0.516714 -0.818163 0.258424 +v 0.351137 -0.838354 0.260631 +v 0.513789 -0.790529 0.065237 +v 0.348321 -0.810895 0.074222 +v 0.516751 -0.834038 -0.096898 +v 0.349511 -0.852543 -0.082341 +v 0.516751 -0.834038 -0.096898 +v 0.521297 -0.952086 -0.215044 +v 0.351851 -0.965799 -0.196822 +v 0.349511 -0.852543 -0.082341 +v 0.538444 -1.313255 0.677418 +v 0.538486 -1.312977 0.679514 +v 0.367514 -1.313065 0.665494 +v 0.367466 -1.313344 0.663474 +v 0.538757 -1.311304 0.692065 +v 0.367756 -1.311400 0.677664 +v 0.517138 -1.175831 -0.218348 +v 0.523306 -1.352454 -0.218841 +v 0.352997 -1.348141 -0.199979 +v 0.348782 -1.180085 -0.199690 +v 0.529401 -1.520415 -0.159778 +v 0.357413 -1.509776 -0.143142 +v 0.529401 -1.520415 -0.159778 +v 0.521603 -1.631505 -0.019562 +v 0.352691 -1.616189 -0.007475 +v 0.357413 -1.509776 -0.143142 +v 0.494471 -1.685528 0.214982 +v 0.335180 -1.665798 0.218999 +v 0.519446 -1.652440 0.404053 +v 0.353170 -1.635702 0.401495 +v 0.519446 -1.652440 0.404053 +v 0.540762 -1.557537 0.556592 +v 0.368511 -1.545647 0.549131 +v 0.353170 -1.635702 0.401495 +v 0.538594 -1.416727 0.642559 +v 0.367135 -1.398666 0.638805 +v 0.538383 -1.338790 0.667590 +v 0.538402 -1.313532 0.675323 +v 0.367418 -1.313624 0.661454 +v 0.367327 -1.335845 0.655566 +v 0.520997 -0.963550 -0.202319 +v 0.351555 -0.976935 -0.184527 +v 0.726982 -1.434432 0.640257 +v 0.726539 -1.339985 0.674465 +v 0.707678 -0.952216 -0.215216 +v 0.703067 -1.171506 -0.231625 +v 0.726494 -1.311589 0.684208 +v 0.729983 -1.565533 0.560226 +v 0.703071 -1.664128 0.404426 +v 0.671741 -1.700076 0.211038 +v 0.703071 -1.664128 0.404426 +v 0.707757 -1.642031 -0.028800 +v 0.718494 -1.527586 -0.172074 +v 0.710923 -1.355042 -0.232431 +v 0.718494 -1.527586 -0.172074 +v 0.726577 -1.311044 0.688482 +v 0.726784 -1.309419 0.701367 +v 0.726064 -1.305718 0.686074 +v 0.701329 -0.819013 -0.107636 +v 0.707985 -0.940582 -0.228195 +v 0.696715 -0.774154 0.058172 +v 0.701329 -0.819013 -0.107636 +v 0.699688 -0.801484 0.255836 +v 0.714712 -0.840370 0.437439 +v 0.719645 -0.953153 0.590563 +v 0.725949 -1.081182 0.693667 +v 0.726726 -1.293531 0.700831 +v 0.725949 -1.081182 0.693667 +v 0.521297 -0.952086 -0.215044 +v 0.521068 -0.960688 -0.205507 +v 0.521032 -0.962119 -0.203913 +v 0.178382 -1.094447 0.664215 +v 0.178377 -1.295814 0.661873 +v 0.175809 -0.980860 0.569646 +v 0.178382 -1.094447 0.664215 +v 0.173052 -0.878926 0.429671 +v 0.167592 -0.840451 0.263750 +v 0.169334 -1.620633 0.399735 +v 0.921979 -1.288793 0.742956 +v 0.920314 -1.076828 0.694947 +v 0.920314 -1.076828 0.694947 +v 0.912818 -0.944507 0.590858 +v 0.907058 -0.828391 0.436413 +v 0.888713 -0.763075 0.252126 +v 0.885691 -0.736462 0.052557 +v 0.892290 -0.808592 -0.113985 +v 0.892290 -0.808592 -0.113985 +v 0.901362 -0.932094 -0.235749 +v 0.961159 -1.081813 0.682150 +v 0.916981 -1.081802 0.682881 +v 0.916951 -1.082633 0.680859 +v 0.947739 -1.082641 0.680350 +v 0.921762 -1.306512 0.725383 +v 0.922104 -1.304653 0.746548 +v 0.895495 -1.167479 -0.239020 +v 0.905300 -1.355788 -0.240312 +v 0.914603 -1.530934 -0.179537 +v 0.914603 -1.530934 -0.179537 +v 0.900481 -1.647166 -0.034723 +v 0.854085 -1.707540 0.207561 +v 0.892769 -1.669908 0.402696 +v 0.892769 -1.669908 0.402696 +v 0.926059 -1.569251 0.560087 +v 0.922052 -1.449780 0.632939 +v 0.921299 -1.339462 0.676148 +v 0.921322 -1.307826 0.698640 +v 0.901048 -0.943765 -0.222648 +v 1.038023 -0.832197 0.243560 +v 1.010204 -0.832703 0.244000 +v 1.009512 -0.807762 0.056309 +v 1.036385 -0.807215 0.055887 +v 1.059303 -1.344642 -0.213117 +v 1.068088 -1.355806 -0.242999 +v 1.056624 -1.167334 -0.241673 +v 1.046700 -1.168472 -0.209937 +v 1.070767 -1.509245 -0.158899 +v 1.078824 -1.530992 -0.182249 +v 1.052545 -1.619181 -0.024051 +v 1.061928 -1.647864 -0.037414 +v 1.001493 -1.677866 0.206256 +v 1.007027 -1.710066 0.204941 +v 1.042097 -1.641395 0.389199 +v 1.051696 -1.671064 0.400030 +v 1.081208 -1.545785 0.536169 +v 1.090155 -1.569306 0.557377 +v 1.075759 -1.433498 0.603687 +v 1.085249 -1.449809 0.630245 +v 1.073916 -1.322816 0.645420 +v 1.083673 -1.330270 0.675452 +v 1.073381 -1.177389 0.656362 +v 1.083225 -1.171741 0.686655 +v 1.083656 -1.252961 0.696370 +v 1.073808 -1.251729 0.664655 +v 1.064365 -0.977056 0.554141 +v 1.074286 -0.954960 0.575867 +v 1.082758 -1.083485 0.676099 +v 1.072917 -1.096610 0.647350 +v 1.057435 -0.868617 0.413681 +v 1.067655 -0.839344 0.426255 +v 1.038023 -0.832197 0.243560 +v 1.046089 -0.801629 0.247346 +v 1.036385 -0.807215 0.055887 +v 1.042759 -0.776098 0.052321 +v 1.044018 -0.846928 -0.089267 +v 1.051525 -0.819659 -0.107006 +v 1.053569 -0.956891 -0.196584 +v 1.063037 -0.942033 -0.225255 +v 0.901696 -1.620360 0.211779 +v 0.932719 -1.570919 0.007410 +v 1.042097 -1.641395 0.389199 +v 1.015356 -1.641006 0.389655 +v 1.052984 -1.545655 0.536639 +v 1.081208 -1.545785 0.536169 +v 1.017001 -0.847293 -0.088835 +v 1.044018 -0.846928 -0.089267 +v 1.047104 -1.433364 0.604165 +v 1.075759 -1.433498 0.603687 +v 1.044018 -0.846928 -0.089267 +v 1.017001 -0.847293 -0.088835 +v 1.025934 -0.956768 -0.196123 +v 1.053569 -0.956891 -0.196584 +v 1.073916 -1.322816 0.645420 +v 1.045095 -1.322680 0.645901 +v 1.044960 -1.251591 0.665136 +v 1.073808 -1.251729 0.664655 +v 1.046700 -1.168472 -0.209937 +v 1.017427 -1.168260 -0.209446 +v 1.030457 -1.344505 -0.212636 +v 1.059303 -1.344642 -0.213117 +v 1.073381 -1.177389 0.656362 +v 1.044512 -1.177251 0.656843 +v 1.044026 -1.096472 0.647832 +v 1.072917 -1.096610 0.647350 +v 1.042556 -1.509127 -0.158429 +v 1.070767 -1.509245 -0.158899 +v 1.072917 -1.096610 0.647350 +v 1.044026 -1.096472 0.647832 +v 1.035082 -0.976915 0.554630 +v 1.064365 -0.977056 0.554141 +v 1.070767 -1.509245 -0.158899 +v 1.042556 -1.509127 -0.158429 +v 1.025465 -1.618879 -0.023593 +v 1.052545 -1.619181 -0.024051 +v 1.028912 -0.868904 0.414140 +v 1.057435 -0.868617 0.413681 +v 0.975754 -1.677371 0.206699 +v 1.001493 -1.677866 0.206256 +v 1.015356 -1.641006 0.389655 +v 1.042097 -1.641395 0.389199 +v 0.914766 -0.881152 0.244164 +v 0.927300 -0.913668 0.395323 +v 0.927258 -1.589827 0.373681 +v 0.917746 -0.858405 0.076848 +v 0.947836 -1.508053 0.503648 +v 0.922927 -0.892921 -0.050361 +v 0.941476 -1.408660 0.563168 +v 0.927879 -0.985821 -0.136806 +v 0.939800 -1.335654 0.590674 +v 0.913280 -1.167234 -0.218500 +v 0.888215 -1.167637 -0.209319 +v 0.901711 -1.344747 -0.212369 +v 0.926636 -1.347922 -0.221044 +v 0.938403 -1.157271 0.606860 +v 0.938762 -1.209738 0.612581 +v 0.914136 -1.172073 -0.147911 +v 0.938856 -1.165903 -0.220412 +v 0.952777 -1.347336 -0.223988 +v 0.929132 -1.008423 0.519713 +v 0.934781 -1.074000 0.571559 +v 0.938745 -1.475597 -0.111494 +v 0.952777 -0.949294 -0.206834 +v 0.966622 -1.516631 -0.168250 +v 0.966622 -1.516631 -0.168250 +v 0.956586 -1.628033 -0.029738 +v 0.915561 -1.686307 0.206860 +v 0.948992 -1.650171 0.394973 +v 0.977243 -1.554165 0.546139 +v 1.052984 -1.545655 0.536639 +v 0.977243 -1.554165 0.546139 +v 0.970294 -1.438732 0.615558 +v 0.967876 -1.324963 0.658460 +v 0.967675 -1.251898 0.678231 +v 0.967170 -1.175489 0.669708 +v 0.966622 -1.092464 0.660447 +v 0.966622 -1.092464 0.660447 +v 0.956550 -0.970573 0.564631 +v 0.953335 -0.860403 0.420154 +v 0.937181 -0.823188 0.245234 +v 0.939358 -0.797285 0.052289 +v 0.946012 -0.837713 -0.096866 +v 0.946012 -0.837713 -0.096866 +v 0.926187 -1.328017 -0.160273 +v 0.926046 -1.546742 0.540115 +v 0.907723 -1.638740 0.392285 +v 0.932913 -0.860385 0.420491 +v 0.916759 -0.823170 0.245571 +v 0.946201 -1.516613 -0.167912 +v 0.936164 -1.628015 -0.029400 +v 0.905293 -0.977177 0.558212 +v 0.915076 -1.095324 0.651699 +v 0.901711 -1.344747 -0.212369 +v 0.888215 -1.167637 -0.209319 +v 0.950849 -1.553349 0.545636 +v 0.930427 -1.553331 0.545974 +v 0.907435 -1.647993 0.395304 +v 0.927857 -1.648011 0.394967 +v 0.932355 -0.949276 -0.206496 +v 0.918434 -1.165884 -0.220074 +v 0.900058 -0.847464 -0.087892 +v 0.894816 -0.807530 0.057910 +v 0.881566 -1.672819 0.208427 +v 0.944085 -1.438910 0.614811 +v 0.923663 -1.438892 0.615149 +v 0.956821 -1.554147 0.546477 +v 0.949872 -1.438714 0.615896 +v 0.915620 -1.176499 0.660795 +v 0.916120 -1.251202 0.669167 +v 0.941342 -1.251618 0.677603 +v 0.920920 -1.251600 0.677941 +v 0.921198 -1.324822 0.658207 +v 0.941619 -1.324840 0.657869 +v 0.936128 -0.970555 0.564969 +v 0.891320 -0.832898 0.246155 +v 0.912314 -1.617710 -0.022450 +v 0.915691 -1.510099 -0.157792 +v 0.940254 -1.516209 -0.164649 +v 0.940254 -1.516209 -0.164649 +v 0.915691 -1.510099 -0.157792 +v 0.912314 -1.617710 -0.022450 +v 0.933870 -1.626407 -0.026502 +v 0.881566 -1.672819 0.208427 +v 0.897377 -1.683402 0.207764 +v 0.907723 -1.638740 0.392285 +v 0.927857 -1.648011 0.394967 +v 0.927857 -1.648011 0.394967 +v 0.907723 -1.638740 0.392285 +v 0.926046 -1.546742 0.540115 +v 0.950849 -1.553349 0.545636 +v 0.918996 -1.433964 0.608014 +v 0.944085 -1.438910 0.614811 +v 0.941619 -1.324840 0.657869 +v 0.916431 -1.322697 0.649900 +v 0.916120 -1.251202 0.669167 +v 0.941342 -1.251618 0.677603 +v 0.940845 -1.174954 0.668839 +v 0.915620 -1.176499 0.660795 +v 0.915076 -1.095324 0.651699 +v 0.940307 -1.091652 0.659315 +v 0.940307 -1.091652 0.659315 +v 0.915076 -1.095324 0.651699 +v 0.905293 -0.977177 0.558212 +v 0.930640 -0.970370 0.563900 +v 0.904171 -0.870011 0.416849 +v 0.928419 -0.861203 0.420014 +v 0.891320 -0.832898 0.246155 +v 0.913706 -0.824026 0.246889 +v 0.894816 -0.807530 0.057910 +v 0.916028 -0.798725 0.056605 +v 0.900058 -0.847464 -0.087892 +v 0.922002 -0.839671 -0.093139 +v 0.922002 -0.839671 -0.093139 +v 0.900058 -0.847464 -0.087892 +v 0.905015 -0.956428 -0.195805 +v 0.928357 -0.952049 -0.204102 +v 0.905015 -0.956428 -0.195805 +v 0.932355 -1.347318 -0.223651 +v 0.946201 -1.516613 -0.167912 +v 0.940845 -1.174954 0.668839 +v 0.920848 -1.240464 0.676668 +v 0.915691 -1.510099 -0.157792 +v 0.904171 -0.870011 0.416849 +v 0.925590 -0.837694 -0.096528 +v 0.930640 -0.970370 0.563900 +v 0.910218 -0.970352 0.564238 +v 0.919885 -1.091633 0.659652 +v 0.940307 -1.091652 0.659315 +v 0.918996 -1.433964 0.608014 +v 0.948992 -1.650171 0.394973 +v 0.928571 -1.650153 0.395311 +v 0.928419 -0.861203 0.420014 +v 0.907997 -0.861185 0.420352 +v 0.946201 -1.092445 0.660785 +v 0.916431 -1.322697 0.649900 +v 0.947455 -1.324945 0.658797 +v 0.947260 -0.840438 0.429087 +v 0.947320 -0.838470 0.430048 +v 0.953428 -0.952818 0.580926 +v 0.953401 -0.954367 0.579376 +v 0.953401 -0.954367 0.579376 +v 0.953428 -0.952818 0.580926 +v 0.962276 -1.239811 0.722141 +v 0.918620 -1.230670 0.722746 +v 0.916981 -1.081802 0.682881 +v 0.961159 -1.081813 0.682150 +v 1.056624 -1.167334 -0.241673 +v 1.068088 -1.355806 -0.242999 +v 0.946349 -1.355793 -0.240989 +v 0.936126 -1.167320 -0.239685 +v 1.078824 -1.530992 -0.182249 +v 0.956014 -1.530948 -0.180221 +v 1.078824 -1.530992 -0.182249 +v 1.061928 -1.647864 -0.037414 +v 0.941191 -1.647342 -0.035401 +v 0.956014 -1.530948 -0.180221 +v 1.007027 -1.710066 0.204941 +v 0.892651 -1.708177 0.206900 +v 1.051696 -1.671064 0.400030 +v 0.932844 -1.670200 0.402024 +v 1.051696 -1.671064 0.400030 +v 1.090155 -1.569306 0.557377 +v 0.967438 -1.569265 0.559404 +v 0.932844 -1.670200 0.402024 +v 1.085249 -1.449809 0.630245 +v 0.963204 -1.449787 0.632260 +v 1.083673 -1.330270 0.675452 +v 1.083656 -1.252961 0.696370 +v 0.961919 -1.252948 0.698379 +v 0.962452 -1.337002 0.670297 +v 1.083225 -1.171741 0.686655 +v 1.082758 -1.083485 0.676099 +v 0.961099 -1.083475 0.678107 +v 0.961526 -1.171728 0.688663 +v 1.082758 -1.083485 0.676099 +v 1.074286 -0.954960 0.575867 +v 0.953374 -0.955916 0.577826 +v 0.961099 -1.083475 0.678107 +v 1.067655 -0.839344 0.426255 +v 0.947201 -0.842407 0.428126 +v 1.046089 -0.801629 0.247346 +v 0.927647 -0.805117 0.249168 +v 1.042759 -0.776098 0.052321 +v 0.924333 -0.778993 0.054165 +v 1.051525 -0.819659 -0.107006 +v 0.931864 -0.821932 -0.105118 +v 1.051525 -0.819659 -0.107006 +v 1.063037 -0.942033 -0.225255 +v 0.941897 -0.942779 -0.223285 +v 0.931864 -0.821932 -0.105118 +v 0.962276 -1.239811 0.722141 +v 0.962481 -1.238004 0.735089 +v 0.962567 -1.250063 0.738143 +v 0.962360 -1.251633 0.725133 +v 0.942211 -0.931135 -0.236386 +v 0.941975 -0.939869 -0.226564 +v 0.941975 -0.939869 -0.226564 +v 0.942211 -0.931135 -0.236386 +v 0.932638 -0.807166 -0.114603 +v 0.932057 -0.818242 -0.107491 +v 0.927780 -0.776431 0.248640 +v 0.927905 -0.774149 0.249050 +v 0.924502 -0.750272 0.053066 +v 0.924662 -0.747954 0.052904 +v 0.941936 -0.941325 -0.224924 +v 0.931960 -0.820087 -0.106304 +v 0.941936 -0.941325 -0.224924 +v 0.953589 -0.943529 0.590222 +v 0.961336 -1.076828 0.694270 +v 0.961159 -1.081813 0.682150 +v 0.947675 -0.826662 0.435811 +v 0.928651 -0.761266 0.251537 +v 0.925624 -0.734855 0.051958 +v 0.962481 -1.238004 0.735089 +v 0.961336 -1.076828 0.694270 +v 0.961336 -1.076828 0.694270 +v 0.953589 -0.943529 0.590222 +v 0.947675 -0.826662 0.435811 +v 0.928651 -0.761266 0.251537 +v 0.925624 -0.734855 0.051958 +v 0.932638 -0.807166 -0.114603 +v 0.932638 -0.807166 -0.114603 +v 0.942211 -0.931135 -0.236386 +v 0.948711 -1.251850 0.700733 +v 0.918271 -1.243518 0.701154 +v 0.896556 -1.285847 0.700476 +v 0.913836 -1.302925 0.700705 +v 0.922104 -1.304653 0.746548 +v 0.921762 -1.306512 0.725383 +v 0.178376 -1.310881 0.661698 +v 0.122986 -0.814750 0.102524 +v 0.128805 -1.230578 0.658611 +v 0.137499 -1.094712 0.663510 +v 0.137499 -1.094712 0.663510 +v 0.130775 -0.981276 0.569959 +v 0.127673 -0.878702 0.430487 +v 0.123522 -0.839591 0.264676 +v 0.108911 -0.821640 0.107482 +v 0.110998 -0.845660 0.263687 +v 0.128805 -1.230578 0.658611 +v 0.114753 -1.221159 0.654515 +v 0.114062 -1.230463 0.654317 +v 0.000193 -1.290566 0.667612 +v 0.116953 -0.884453 0.427907 +v 0.120394 -0.986005 0.565565 +v 0.105013 -0.845537 0.263816 +v 0.102964 -0.821885 0.110168 +v 0.110959 -0.884423 0.428018 +v 0.114404 -0.986066 0.565610 +v 0.118001 -1.096799 0.657051 +v 0.118001 -1.096799 0.657051 +v 0.123987 -1.096799 0.657153 +v 0.123987 -1.096799 0.657153 +v 0.900419 -1.324804 0.658550 +v 0.902884 -1.438874 0.615492 +v 0.915385 -1.627996 -0.029056 +v 0.874360 -1.686270 0.207541 +v 0.895139 -1.686288 0.207198 +v 0.900141 -1.251581 0.678284 +v 0.915349 -0.970537 0.565312 +v 0.912134 -0.860366 0.420835 +v 0.900069 -1.240445 0.677011 +v 0.925421 -1.516595 -0.167569 +v 0.889439 -0.970333 0.564581 +v 0.899106 -1.091615 0.659996 +v 0.925421 -1.092427 0.661129 +v 0.887218 -0.861167 0.420696 +v 0.911576 -1.347299 -0.223307 +v 0.925421 -1.516595 -0.167569 +v 0.893284 -0.824008 0.247226 +v 0.872505 -0.823990 0.247570 +v 0.897655 -1.165866 -0.219730 +v 0.946749 -1.175471 0.670046 +v 0.926401 -1.240762 0.677674 +v 0.925421 -1.092427 0.661129 +v 0.946201 -1.092445 0.660785 +v 0.895607 -0.798707 0.056943 +v 0.874828 -0.798689 0.057286 +v 0.906215 -1.347904 -0.220706 +v 0.885435 -1.347885 -0.220363 +v 0.872080 -1.167198 -0.217819 +v 0.892859 -1.167216 -0.218162 +v 0.901580 -0.839652 -0.092801 +v 0.880801 -0.839634 -0.092458 +v 0.887156 -0.952013 -0.203421 +v 0.907935 -0.952031 -0.203764 +v 0.927857 -1.648011 0.394967 +v 0.907435 -1.647993 0.395304 +v 0.876956 -1.683384 0.208102 +v 0.897377 -1.683402 0.207764 +v 0.913448 -1.626388 -0.026165 +v 0.933870 -1.626407 -0.026502 +v 0.947253 -1.251880 0.678569 +v 0.919832 -1.516190 -0.164311 +v 0.940254 -1.516209 -0.164649 +v 0.918936 -0.797267 0.052626 +v 0.926636 -1.347922 -0.221044 +v 0.913280 -1.167234 -0.218500 +v 0.940254 -1.516209 -0.164649 +v 0.919832 -1.516190 -0.164311 +v 0.928357 -0.952049 -0.204102 +v 0.901580 -0.839652 -0.092801 +v 0.922002 -0.839671 -0.093139 +v 0.922002 -0.839671 -0.093139 +v 0.916028 -0.798725 0.056605 +v 0.928571 -1.650153 0.395311 +v 0.913706 -0.824026 0.246889 +v 0.925590 -0.837694 -0.096528 +v 0.889439 -0.970333 0.564581 +v 0.887218 -0.861167 0.420696 +v 0.885435 -1.347885 -0.220363 +v 0.899053 -1.516172 -0.163968 +v 0.904811 -0.837676 -0.096184 +v 0.880801 -0.839634 -0.092458 +v 0.887156 -0.952013 -0.203421 +v 0.911576 -0.949257 -0.206152 +v 0.907791 -1.650134 0.395654 +v 0.886656 -1.647974 0.395648 +v 0.909647 -1.553312 0.546317 +v 0.936042 -1.554129 0.546820 +v 0.899106 -1.091615 0.659996 +v 0.872080 -1.167198 -0.217819 +v 0.898157 -0.797248 0.052970 +v 0.874828 -0.798689 0.057286 +v 0.880801 -0.839634 -0.092458 +v 0.904811 -0.837676 -0.096184 +v 0.856176 -1.683365 0.208445 +v 0.886656 -1.647974 0.395648 +v 0.907791 -1.650134 0.395654 +v 0.902884 -1.438874 0.615492 +v 0.929093 -1.438696 0.616239 +v 0.899053 -1.516172 -0.163968 +v 0.892669 -1.626370 -0.025821 +v 0.872505 -0.823990 0.247570 +v 0.895980 -0.823151 0.245915 +v 0.926675 -1.324927 0.659141 +v 0.900419 -1.324804 0.658550 +v 0.900141 -1.251581 0.678284 +v 0.926475 -1.251861 0.678912 +v 0.900069 -1.240445 0.677011 +v 0.899106 -1.091615 0.659996 +v 0.909647 -1.553312 0.546317 +v 0.886656 -1.647974 0.395648 +v 0.886656 -1.647974 0.395648 +v 0.856176 -1.683365 0.208445 +v 0.892669 -1.626370 -0.025821 +v 0.899053 -1.516172 -0.163968 +v 0.899053 -1.516172 -0.163968 +v 0.880801 -0.839634 -0.092458 +v 0.941897 -0.942779 -0.223285 +v 0.931864 -0.821932 -0.105118 +v 0.931960 -0.820087 -0.106304 +v 0.864949 -0.819979 -0.105965 +v 0.864852 -0.821824 -0.104779 +v 0.931864 -0.821932 -0.105118 +v 0.901048 -0.943765 -0.222648 +v 0.941897 -0.942779 -0.223285 +v 0.927780 -0.776431 0.248640 +v 0.860773 -0.776320 0.250209 +v 0.857477 -0.750158 0.053827 +v 0.924502 -0.750272 0.053066 +v 0.857309 -0.778881 0.054889 +v 0.860650 -0.805007 0.250893 +v 0.948643 -1.240070 0.699314 +v 0.953401 -0.954367 0.579376 +v 0.947739 -1.082641 0.680350 +v 0.947201 -0.842407 0.428126 +v 0.953374 -0.955916 0.577826 +v 0.520997 -0.963550 -0.202319 +v 0.707678 -0.952216 -0.215216 +v 0.726064 -1.305718 0.686074 +v 0.367418 -1.313624 0.661454 +v 0.178114 -1.312896 0.645984 +v 0.163837 -0.978000 -0.167240 +v 0.351555 -0.976935 -0.184527 +v 0.538444 -1.313255 0.677418 +v 0.538402 -1.313532 0.675323 +v 0.864852 -0.821824 -0.104779 +v 0.864949 -0.819979 -0.105965 +v 0.857477 -0.750158 0.053827 +v 0.857309 -0.778881 0.054889 +v 0.860773 -0.776320 0.250209 +v 0.860650 -0.805007 0.250893 +v 0.880305 -0.840334 0.431289 +v 0.880246 -0.842302 0.430329 +v 0.864949 -0.819979 -0.105965 +v 0.931960 -0.820087 -0.106304 +v 0.947201 -0.842407 0.428126 +v 0.880246 -0.842302 0.430329 +v 0.880305 -0.840334 0.431289 +v 0.947260 -0.840438 0.429087 +v 0.864852 -0.821824 -0.104779 +v 0.947260 -0.840438 0.429087 +v 0.880305 -0.840334 0.431289 +v 0.880246 -0.842302 0.430329 +v 0.896556 -1.285847 0.700476 +v 0.890578 -1.286991 0.725275 +v 0.725020 -1.292571 0.687590 +v 0.724979 -1.292843 0.685453 +v 0.918180 -1.231872 0.699741 +v 0.918620 -1.230670 0.722746 +v 0.918741 -1.242288 0.725729 +v 0.918271 -1.243518 0.701154 +v 0.890578 -1.286991 0.725275 +v 0.896556 -1.285847 0.700476 +v 0.726064 -1.305718 0.686074 +v 0.724979 -1.292843 0.685453 +v 0.725020 -1.292571 0.687590 +v 0.726577 -1.311044 0.688482 +v 0.724979 -1.292843 0.685453 +v 0.921762 -1.306512 0.725383 +v 0.890578 -1.286991 0.725275 +v 0.918741 -1.242288 0.725729 +v 0.962360 -1.251633 0.725133 +v 0.918180 -1.231872 0.699741 +v 0.726577 -1.311044 0.688482 +v 0.725020 -1.292571 0.687590 +v 0.947739 -1.082641 0.680350 +v 0.916951 -1.082633 0.680859 +v 0.916951 -1.082633 0.680859 +v 0.916981 -1.081802 0.682881 +v 0.919885 -1.091633 0.659652 +v 0.899106 -1.091615 0.659996 +v 0.962567 -1.250063 0.738143 +v 0.922104 -1.304653 0.746548 +v 0.940307 -1.091652 0.659315 +v 0.726784 -1.309419 0.701367 +v 0.367756 -1.311400 0.677664 +v 0.538757 -1.311304 0.692065 +vt 0.992126 0.727517 +vt 0.993537 0.732984 +vt 0.993551 0.732193 +vt 0.979981 0.452094 +vt 0.981600 0.457927 +vt 0.981492 0.452075 +vt 0.686030 0.406084 +vt 0.686195 0.409109 +vt 0.686177 0.406089 +vt 0.685549 0.391778 +vt 0.979881 0.446708 +vt 0.992235 0.721599 +vt 0.685695 0.285041 +vt 0.686323 0.270730 +vt 0.686177 0.270735 +vt 0.685841 0.285036 +vt 0.687203 0.270702 +vt 0.979672 0.696672 +vt 0.981183 0.696691 +vt 0.981283 0.691306 +vt 0.982734 0.695928 +vt 0.993746 0.720697 +vt 0.995088 0.710103 +vt 0.993551 0.710122 +vt 0.992235 0.720716 +vt 0.865871 0.213784 +vt 0.866663 0.214166 +vt 0.866550 0.213734 +vt 0.865871 0.230647 +vt 0.866550 0.230697 +vt 0.866663 0.230265 +vt 0.639483 0.190807 +vt 0.642536 0.190001 +vt 0.643903 0.176846 +vt 0.636273 0.178850 +vt 0.636755 0.193369 +vt 0.631179 0.183611 +vt 0.635861 0.196592 +vt 0.628389 0.188336 +vt 0.636880 0.199927 +vt 0.627494 0.195470 +vt 0.638128 0.202760 +vt 0.629275 0.204375 +vt 0.640370 0.204929 +vt 0.631427 0.210796 +vt 0.641666 0.205456 +vt 0.635476 0.214913 +vt 0.643020 0.205801 +vt 0.640401 0.217069 +vt 0.645655 0.205658 +vt 0.644103 0.205960 +vt 0.646178 0.216261 +vt 0.648212 0.215065 +vt 0.647727 0.202846 +vt 0.646429 0.205043 +vt 0.651173 0.212667 +vt 0.653257 0.210321 +vt 0.648848 0.199729 +vt 0.656801 0.202992 +vt 0.649832 0.196406 +vt 0.658353 0.196329 +vt 0.649204 0.193796 +vt 0.657983 0.187422 +vt 0.647924 0.190338 +vt 0.655870 0.181176 +vt 0.644668 0.189956 +vt 0.648742 0.177349 +vt 0.641426 0.194672 +vt 0.642999 0.194257 +vt 0.640065 0.195952 +vt 0.639635 0.197506 +vt 0.640166 0.199246 +vt 0.640828 0.200754 +vt 0.641968 0.201858 +vt 0.642774 0.202187 +vt 0.643590 0.202390 +vt 0.644554 0.202124 +vt 0.643965 0.202428 +vt 0.645490 0.200762 +vt 0.645001 0.201587 +vt 0.645945 0.199563 +vt 0.646594 0.197386 +vt 0.646231 0.195877 +vt 0.644960 0.194296 +vt 0.643721 0.194242 +vt 0.728238 0.488811 +vt 0.728528 0.475711 +vt 0.713863 0.475711 +vt 0.713567 0.488739 +vt 0.334656 0.340183 +vt 0.334937 0.326999 +vt 0.333185 0.326999 +vt 0.332945 0.340181 +vt 0.350483 0.340284 +vt 0.350162 0.326999 +vt 0.338815 0.326999 +vt 0.338947 0.340185 +vt 0.710681 0.703234 +vt 0.711000 0.690379 +vt 0.702792 0.690379 +vt 0.702339 0.703664 +vt 0.722646 0.702738 +vt 0.722795 0.690379 +vt 0.739141 0.703444 +vt 0.738996 0.690379 +vt 0.750581 0.703675 +vt 0.750228 0.690379 +vt 0.701653 0.488889 +vt 0.701982 0.475711 +vt 0.691599 0.475711 +vt 0.691155 0.489007 +vt 0.842325 0.118772 +vt 0.841527 0.131955 +vt 0.842320 0.131955 +vt 0.843129 0.118772 +vt 0.842190 0.118772 +vt 0.841395 0.131955 +vt 0.404205 0.498029 +vt 0.404531 0.485052 +vt 0.394602 0.485052 +vt 0.394327 0.498169 +vt 0.229504 0.358464 +vt 0.229656 0.345570 +vt 0.219650 0.345570 +vt 0.219305 0.358547 +vt 0.685695 0.391783 +vt 0.686323 0.406093 +vt 0.685841 0.391787 +vt 0.687203 0.406122 +vt 0.686713 0.391816 +vt 0.682501 0.351516 +vt 0.683543 0.365420 +vt 0.684371 0.365448 +vt 0.683300 0.351529 +vt 0.682368 0.351513 +vt 0.683405 0.365416 +vt 0.861773 0.182428 +vt 0.861486 0.195053 +vt 0.876174 0.195089 +vt 0.876881 0.182481 +vt 0.278028 0.385304 +vt 0.277065 0.372697 +vt 0.268070 0.372510 +vt 0.268686 0.385029 +vt 0.255905 0.372430 +vt 0.256059 0.384901 +vt 0.242911 0.371985 +vt 0.242606 0.384229 +vt 0.229022 0.372003 +vt 0.228226 0.384247 +vt 0.218454 0.372285 +vt 0.217290 0.384667 +vt 0.405367 0.524149 +vt 0.404205 0.511767 +vt 0.394218 0.512088 +vt 0.394977 0.524637 +vt 0.844709 0.092169 +vt 0.843525 0.104794 +vt 0.843662 0.104793 +vt 0.844852 0.092169 +vt 0.844491 0.104790 +vt 0.845708 0.092164 +vt 0.713251 0.515008 +vt 0.713183 0.502538 +vt 0.701034 0.502861 +vt 0.700480 0.515476 +vt 0.690248 0.503128 +vt 0.689274 0.515866 +vt 0.752053 0.730534 +vt 0.751294 0.717797 +vt 0.739451 0.717289 +vt 0.739794 0.729793 +vt 0.722368 0.715720 +vt 0.722057 0.727504 +vt 0.710029 0.716825 +vt 0.709306 0.729117 +vt 0.360860 0.365737 +vt 0.359728 0.353445 +vt 0.351140 0.354393 +vt 0.351850 0.367120 +vt 0.339221 0.354171 +vt 0.340431 0.366845 +vt 0.334423 0.366794 +vt 0.334425 0.354161 +vt 0.332729 0.354159 +vt 0.332480 0.366784 +vt 0.728846 0.515260 +vt 0.728104 0.502711 +vt 0.341695 0.380778 +vt 0.334359 0.380697 +vt 0.729523 0.529077 +vt 0.713415 0.528771 +vt 0.332161 0.380680 +vt 0.352326 0.381106 +vt 0.361651 0.379313 +vt 0.721828 0.740616 +vt 0.708823 0.742694 +vt 0.740014 0.743569 +vt 0.752558 0.744530 +vt 0.700140 0.529365 +vt 0.688623 0.529862 +vt 0.845665 0.078273 +vt 0.846546 0.078273 +vt 0.845383 0.078308 +vt 0.406344 0.537808 +vt 0.395662 0.538456 +vt 0.227656 0.397779 +vt 0.216480 0.398326 +vt 0.242353 0.397759 +vt 0.256104 0.398651 +vt 0.269039 0.398836 +vt 0.278632 0.399184 +vt 0.862110 0.168538 +vt 0.877441 0.168601 +vt 0.684899 0.377969 +vt 0.685755 0.377997 +vt 0.684756 0.377965 +vt 0.681920 0.338412 +vt 0.682051 0.338412 +vt 0.682835 0.338412 +vt 0.861245 0.209034 +vt 0.875910 0.209049 +vt 0.276092 0.358736 +vt 0.267361 0.358654 +vt 0.255558 0.358614 +vt 0.242956 0.358411 +vt 0.358712 0.339854 +vt 0.863094 0.154154 +vt 0.877832 0.154232 +vt 0.278879 0.413553 +vt 0.269141 0.413117 +vt 0.256054 0.412873 +vt 0.241660 0.411737 +vt 0.226837 0.411756 +vt 0.216071 0.412452 +vt 0.407059 0.551934 +vt 0.396220 0.552762 +vt 0.660165 0.234199 +vt 0.661155 0.234325 +vt 0.663433 0.234325 +vt 0.663433 0.234199 +vt 0.848414 0.063887 +vt 0.849877 0.063888 +vt 0.713652 0.543007 +vt 0.700025 0.543746 +vt 0.688327 0.544371 +vt 0.752791 0.759039 +vt 0.740104 0.757826 +vt 0.721708 0.754103 +vt 0.708606 0.756722 +vt 0.362039 0.393342 +vt 0.352540 0.395604 +vt 0.342854 0.395211 +vt 0.334241 0.395095 +vt 0.331631 0.395067 +vt 0.730079 0.543383 +vt 0.969563 0.371274 +vt 0.969971 0.357445 +vt 0.967983 0.357412 +vt 0.967505 0.371239 +vt 0.657771 0.786438 +vt 0.670714 0.784968 +vt 0.670500 0.782640 +vt 0.656672 0.784363 +vt 0.646227 0.792004 +vt 0.644413 0.790509 +vt 0.639446 0.802927 +vt 0.637220 0.802232 +vt 0.637318 0.820324 +vt 0.634948 0.820542 +vt 0.641773 0.833427 +vt 0.639707 0.834515 +vt 0.650220 0.843324 +vt 0.648704 0.845113 +vt 0.659099 0.847191 +vt 0.658163 0.849304 +vt 0.667615 0.849186 +vt 0.667362 0.851470 +vt 0.678385 0.848593 +vt 0.673013 0.849914 +vt 0.673233 0.852261 +vt 0.679096 0.850769 +vt 0.692091 0.839167 +vt 0.684223 0.847156 +vt 0.685467 0.849148 +vt 0.693926 0.840558 +vt 0.698693 0.827822 +vt 0.700966 0.828473 +vt 0.699720 0.814981 +vt 0.702003 0.814973 +vt 0.699751 0.800980 +vt 0.702003 0.800426 +vt 0.695451 0.790727 +vt 0.697286 0.789172 +vt 0.686364 0.783924 +vt 0.687184 0.781688 +vt 0.615347 0.186301 +vt 0.613724 0.201734 +vt 0.973586 0.414119 +vt 0.970996 0.423386 +vt 0.973084 0.423367 +vt 0.975564 0.414120 +vt 0.970921 0.348007 +vt 0.968923 0.347970 +vt 0.971605 0.432553 +vt 0.973725 0.432534 +vt 0.977708 0.075922 +vt 0.978251 0.066432 +vt 0.976208 0.066505 +vt 0.975710 0.075957 +vt 0.971909 0.441203 +vt 0.972014 0.446641 +vt 0.974148 0.446622 +vt 0.974041 0.441184 +vt 0.977278 0.050899 +vt 0.977816 0.038037 +vt 0.975683 0.038113 +vt 0.975114 0.050981 +vt 0.972106 0.451880 +vt 0.972207 0.457574 +vt 0.974344 0.457555 +vt 0.974242 0.451862 +vt 0.978251 0.026812 +vt 0.976165 0.026886 +vt 0.970921 0.405515 +vt 0.970594 0.396387 +vt 0.968428 0.396338 +vt 0.968785 0.405466 +vt 0.974345 0.657885 +vt 0.973334 0.646290 +vt 0.971332 0.646209 +vt 0.972260 0.657797 +vt 0.970513 0.384147 +vt 0.968403 0.384106 +vt 0.970031 0.628624 +vt 0.968128 0.628549 +vt 0.973343 0.616153 +vt 0.971366 0.616073 +vt 0.667356 0.208216 +vt 0.668236 0.196806 +vt 0.617580 0.213321 +vt 0.668251 0.184323 +vt 0.624872 0.222055 +vt 0.664466 0.175349 +vt 0.632742 0.225427 +vt 0.656805 0.169939 +vt 0.638365 0.226718 +vt 0.026387 0.065979 +vt 0.027107 0.052804 +vt 0.025261 0.053186 +vt 0.024524 0.066109 +vt 0.647810 0.227077 +vt 0.651599 0.226138 +vt 0.643034 0.170954 +vt 0.969943 0.037911 +vt 0.969319 0.051163 +vt 0.657351 0.222724 +vt 0.661642 0.218270 +vt 0.621162 0.176651 +vt 0.970825 0.067050 +vt 0.970542 0.026361 +vt 0.966235 0.646360 +vt 0.966634 0.658227 +vt 0.963685 0.628268 +vt 0.966477 0.615405 +vt 0.974345 0.607177 +vt 0.968769 0.606200 +vt 0.979415 0.432228 +vt 0.978690 0.422806 +vt 0.979766 0.441119 +vt 0.980090 0.457946 +vt 0.962598 0.396697 +vt 0.963030 0.406063 +vt 0.962803 0.384146 +vt 0.962108 0.370926 +vt 0.962813 0.356714 +vt 0.963702 0.347005 +vt 0.970489 0.076688 +vt 0.631489 0.171604 +vt 0.614166 0.215149 +vt 0.622383 0.225089 +vt 0.960598 0.370893 +vt 0.961293 0.384113 +vt 0.964726 0.646296 +vt 0.965124 0.658163 +vt 0.656568 0.228787 +vt 0.664298 0.220758 +vt 0.642735 0.166385 +vt 0.629732 0.167927 +vt 0.990840 0.756691 +vt 0.992235 0.765674 +vt 0.993746 0.765693 +vt 0.992350 0.756710 +vt 0.967809 0.051211 +vt 0.969315 0.067098 +vt 0.671778 0.182409 +vt 0.667412 0.172126 +vt 0.609833 0.201988 +vt 0.991550 0.747432 +vt 0.993061 0.747451 +vt 0.980926 0.432209 +vt 0.980200 0.422787 +vt 0.645316 0.231611 +vt 0.650709 0.230258 +vt 0.992026 0.732965 +vt 0.991906 0.738555 +vt 0.993416 0.738574 +vt 0.961088 0.396664 +vt 0.671778 0.196451 +vt 0.611609 0.184555 +vt 0.027810 0.041344 +vt 0.025997 0.041914 +vt 0.997922 0.410970 +vt 0.997731 0.399157 +vt 0.996137 0.398978 +vt 0.996112 0.410540 +vt 0.995417 0.381275 +vt 0.994241 0.381381 +vt 0.997922 0.368446 +vt 0.996423 0.368763 +vt 0.496541 0.005293 +vt 0.495072 0.014517 +vt 0.496901 0.014892 +vt 0.498030 0.005907 +vt 0.495705 0.023870 +vt 0.497554 0.024104 +vt 0.495987 0.032787 +vt 0.496061 0.038388 +vt 0.497916 0.038269 +vt 0.497840 0.032800 +vt 0.496116 0.043788 +vt 0.496175 0.049657 +vt 0.498030 0.049255 +vt 0.497970 0.043534 +vt 0.852859 0.155255 +vt 0.852325 0.145938 +vt 0.850460 0.145633 +vt 0.851007 0.154748 +vt 0.852425 0.133450 +vt 0.850637 0.133368 +vt 0.851647 0.120371 +vt 0.849992 0.120466 +vt 0.852157 0.106353 +vt 0.850585 0.106593 +vt 0.852859 0.096600 +vt 0.851227 0.097097 +vt 0.027405 0.091493 +vt 0.027810 0.081788 +vt 0.026070 0.081615 +vt 0.025766 0.091028 +vt 0.658361 0.165302 +vt 0.969032 0.026410 +vt 0.968433 0.037959 +vt 0.618160 0.173577 +vt 0.670754 0.209338 +vt 0.968979 0.076736 +vt 0.361822 0.104413 +vt 0.362359 0.095482 +vt 0.360848 0.095493 +vt 0.360311 0.104425 +vt 0.631317 0.228941 +vt 0.980470 0.413458 +vt 0.981980 0.413439 +vt 0.361920 0.116616 +vt 0.360409 0.116627 +vt 0.961520 0.406030 +vt 0.639885 0.230907 +vt 0.981277 0.441100 +vt 0.636593 0.120322 +vt 0.640473 0.106923 +vt 0.640325 0.106857 +vt 0.636432 0.120307 +vt 0.660620 0.244160 +vt 0.660620 0.244082 +vt 0.113371 0.019425 +vt 0.120760 0.027284 +vt 0.123149 0.025055 +vt 0.116181 0.017703 +vt 0.713673 0.554924 +vt 0.713666 0.546012 +vt 0.700028 0.546782 +vt 0.700035 0.555785 +vt 0.688329 0.547434 +vt 0.688334 0.556516 +vt 0.752792 0.771185 +vt 0.752791 0.762102 +vt 0.740102 0.760837 +vt 0.740094 0.769766 +vt 0.721697 0.756955 +vt 0.721664 0.765415 +vt 0.708601 0.759686 +vt 0.708588 0.768476 +vt 0.362113 0.405095 +vt 0.362058 0.396306 +vt 0.352539 0.398664 +vt 0.352534 0.407740 +vt 0.342852 0.398254 +vt 0.342845 0.407280 +vt 0.333535 0.407101 +vt 0.334131 0.398145 +vt 0.327635 0.398065 +vt 0.327628 0.407069 +vt 0.321861 0.407043 +vt 0.321868 0.398043 +vt 0.315601 0.398018 +vt 0.315594 0.407016 +vt 0.897587 0.046241 +vt 0.888589 0.046442 +vt 0.888343 0.055831 +vt 0.897286 0.055645 +vt 0.888348 0.068533 +vt 0.897257 0.068378 +vt 0.887423 0.082092 +vt 0.896183 0.081946 +vt 0.887740 0.096571 +vt 0.896500 0.096416 +vt 0.888736 0.107283 +vt 0.897587 0.107118 +vt 0.740918 0.554359 +vt 0.740745 0.545510 +vt 0.730154 0.546404 +vt 0.730216 0.555363 +vt 0.656394 0.089497 +vt 0.657131 0.088977 +vt 0.656678 0.088121 +vt 0.655926 0.088651 +vt 0.686342 0.409114 +vt 0.687221 0.409143 +vt 0.660835 0.162952 +vt 0.649290 0.157963 +vt 0.648713 0.158747 +vt 0.660491 0.163862 +vt 0.636971 0.134490 +vt 0.636802 0.134522 +vt 0.640349 0.148687 +vt 0.640193 0.148759 +vt 0.649386 0.157832 +vt 0.660892 0.162801 +vt 0.646544 0.096445 +vt 0.645879 0.095740 +vt 0.639437 0.106461 +vt 0.635463 0.120222 +vt 0.635846 0.134691 +vt 0.639313 0.149171 +vt 0.866688 0.151153 +vt 0.877835 0.151198 +vt 0.278879 0.416587 +vt 0.269127 0.416133 +vt 0.256029 0.415876 +vt 0.241634 0.414691 +vt 0.226814 0.414709 +vt 0.216050 0.415436 +vt 0.407165 0.554918 +vt 0.396292 0.555783 +vt 0.327527 0.397086 +vt 0.331249 0.394511 +vt 0.330016 0.393232 +vt 0.326925 0.394834 +vt 0.660949 0.087539 +vt 0.660259 0.086127 +vt 0.862418 0.222215 +vt 0.861654 0.222215 +vt 0.860148 0.209033 +vt 0.859893 0.222215 +vt 0.230860 0.355308 +vt 0.230686 0.345570 +vt 0.865926 0.212699 +vt 0.875869 0.212071 +vt 0.275997 0.355714 +vt 0.267338 0.355324 +vt 0.255560 0.355258 +vt 0.242956 0.355151 +vt 0.242972 0.354227 +vt 0.231317 0.354262 +vt 0.280141 0.397911 +vt 0.280141 0.388276 +vt 0.279646 0.396891 +vt 0.279514 0.396963 +vt 0.255459 0.354469 +vt 0.231420 0.345570 +vt 0.267089 0.354562 +vt 0.242973 0.353784 +vt 0.242924 0.345570 +vt 0.231605 0.345570 +vt 0.231508 0.353819 +vt 0.255459 0.354026 +vt 0.255246 0.345570 +vt 0.267087 0.354119 +vt 0.266750 0.345570 +vt 0.275545 0.354280 +vt 0.275202 0.345570 +vt 0.864429 0.222215 +vt 0.875638 0.222215 +vt 0.875622 0.213505 +vt 0.275559 0.354723 +vt 0.863591 0.222215 +vt 0.875625 0.213062 +vt 0.994598 0.747471 +vt 0.994953 0.738594 +vt 0.962176 0.628204 +vt 0.960640 0.628138 +vt 0.963190 0.646230 +vt 0.995074 0.733003 +vt 0.959756 0.384080 +vt 0.959551 0.396631 +vt 0.995088 0.732212 +vt 0.963588 0.658097 +vt 0.359311 0.095505 +vt 0.358774 0.104437 +vt 0.959983 0.405996 +vt 0.358872 0.116639 +vt 0.967496 0.026458 +vt 0.966897 0.038008 +vt 0.359632 0.129741 +vt 0.358094 0.129753 +vt 0.966273 0.051260 +vt 0.983137 0.457907 +vt 0.982943 0.447452 +vt 0.360143 0.143859 +vt 0.358606 0.143871 +vt 0.729567 0.056161 +vt 0.728847 0.043052 +vt 0.727311 0.043019 +vt 0.728030 0.056128 +vt 0.360848 0.153935 +vt 0.359311 0.153947 +vt 0.730272 0.027300 +vt 0.728735 0.027267 +vt 0.465411 0.068778 +vt 0.462918 0.056290 +vt 0.461408 0.056347 +vt 0.463901 0.068835 +vt 0.465231 0.038427 +vt 0.463722 0.038483 +vt 0.981392 0.446689 +vt 0.465411 0.026319 +vt 0.463901 0.026375 +vt 0.961303 0.356681 +vt 0.731077 0.056194 +vt 0.730358 0.043085 +vt 0.731782 0.067479 +vt 0.730272 0.067446 +vt 0.731782 0.027333 +vt 0.731383 0.017458 +vt 0.729872 0.017425 +vt 0.362359 0.153924 +vt 0.361654 0.143848 +vt 0.964967 0.615340 +vt 0.361142 0.129729 +vt 0.962192 0.346972 +vt 0.957915 0.384018 +vt 0.957638 0.396503 +vt 0.965545 0.026593 +vt 0.964961 0.038060 +vt 0.967443 0.076785 +vt 0.967778 0.067147 +vt 0.965965 0.067035 +vt 0.965661 0.076744 +vt 0.983517 0.413420 +vt 0.981737 0.422768 +vt 0.983689 0.422786 +vt 0.985083 0.413549 +vt 0.958041 0.405826 +vt 0.964378 0.051242 +vt 0.959766 0.356648 +vt 0.960655 0.346939 +vt 0.958869 0.347177 +vt 0.958029 0.356920 +vt 0.963431 0.615275 +vt 0.961867 0.615270 +vt 0.959295 0.628086 +vt 0.982463 0.432190 +vt 0.984400 0.432132 +vt 0.961515 0.645980 +vt 0.961645 0.657793 +vt 0.959061 0.370859 +vt 0.957321 0.370929 +vt 0.982814 0.441080 +vt 0.982929 0.446670 +vt 0.984875 0.446647 +vt 0.984755 0.441047 +vt 0.985083 0.457915 +vt 0.984890 0.447431 +vt 0.993887 0.756729 +vt 0.995283 0.765713 +vt 0.459872 0.056404 +vt 0.462365 0.068893 +vt 0.462185 0.038541 +vt 0.462365 0.026433 +vt 0.728735 0.067413 +vt 0.728335 0.017392 +vt 0.660949 0.162649 +vt 0.649482 0.157702 +vt 0.215014 0.737194 +vt 0.215132 0.737185 +vt 0.215132 0.732230 +vt 0.215014 0.732239 +vt 0.686049 0.409105 +vt 0.991610 0.558248 +vt 0.991785 0.543828 +vt 0.986828 0.543740 +vt 0.986653 0.558218 +vt 0.882466 0.082160 +vt 0.882785 0.096711 +vt 0.326691 0.397082 +vt 0.887595 0.046333 +vt 0.888341 0.055745 +vt 0.636755 0.120336 +vt 0.640621 0.106989 +vt 0.684613 0.377960 +vt 0.331709 0.380646 +vt 0.843387 0.104795 +vt 0.842056 0.118772 +vt 0.681789 0.338412 +vt 0.682235 0.351511 +vt 0.683267 0.365412 +vt 0.332431 0.366785 +vt 0.844567 0.092170 +vt 0.841263 0.131955 +vt 0.945418 0.045426 +vt 0.941799 0.033758 +vt 0.939680 0.033917 +vt 0.945285 0.045519 +vt 0.943177 0.019199 +vt 0.941059 0.019330 +vt 0.945418 0.005816 +vt 0.945270 0.005750 +vt 0.992658 0.534002 +vt 0.987703 0.533884 +vt 0.215293 0.713782 +vt 0.215135 0.713779 +vt 0.215135 0.718732 +vt 0.215293 0.718735 +vt 0.883782 0.107451 +vt 0.992658 0.572420 +vt 0.987703 0.572435 +vt 0.883393 0.068567 +vt 0.821912 0.014590 +vt 0.821912 0.001874 +vt 0.821766 0.001887 +vt 0.820101 0.014275 +vt 0.298042 0.017660 +vt 0.298019 0.016793 +vt 0.296201 0.016712 +vt 0.296339 0.017588 +vt 0.298389 0.013673 +vt 0.296578 0.013413 +vt 0.215290 0.695059 +vt 0.215131 0.694657 +vt 0.215131 0.696024 +vt 0.215290 0.696012 +vt 0.330782 0.380565 +vt 0.112301 0.013885 +vt 0.112818 0.018837 +vt 0.115636 0.017127 +vt 0.114943 0.013335 +vt 0.326098 0.394828 +vt 0.122164 0.003365 +vt 0.123149 0.004252 +vt 0.315514 0.397028 +vt 0.315515 0.394751 +vt 0.298389 0.028778 +vt 0.298235 0.028825 +vt 0.993746 0.721618 +vt 0.995283 0.721637 +vt 0.865853 0.151149 +vt 0.861991 0.154148 +vt 0.860963 0.168534 +vt 0.860386 0.195050 +vt 0.860643 0.182424 +vt 0.392849 0.211468 +vt 0.389639 0.223425 +vt 0.397269 0.225429 +vt 0.395902 0.212274 +vt 0.390121 0.208906 +vt 0.384544 0.218665 +vt 0.389227 0.205683 +vt 0.381754 0.213939 +vt 0.390246 0.202348 +vt 0.380860 0.206805 +vt 0.391493 0.199515 +vt 0.382641 0.197900 +vt 0.393736 0.197346 +vt 0.384792 0.191479 +vt 0.395032 0.196819 +vt 0.388842 0.187362 +vt 0.396386 0.196474 +vt 0.393767 0.185206 +vt 0.399021 0.196617 +vt 0.401578 0.187210 +vt 0.399543 0.186014 +vt 0.397469 0.196315 +vt 0.401093 0.199429 +vt 0.406623 0.191954 +vt 0.404539 0.189608 +vt 0.399795 0.197232 +vt 0.402213 0.202546 +vt 0.410167 0.199283 +vt 0.403198 0.205869 +vt 0.411719 0.205946 +vt 0.402570 0.208479 +vt 0.411349 0.214853 +vt 0.401289 0.211937 +vt 0.409236 0.221099 +vt 0.398034 0.212319 +vt 0.402108 0.224926 +vt 0.394792 0.207603 +vt 0.396365 0.208018 +vt 0.393431 0.206323 +vt 0.393001 0.204769 +vt 0.393532 0.203028 +vt 0.394194 0.201521 +vt 0.395334 0.200416 +vt 0.396140 0.200087 +vt 0.396956 0.199885 +vt 0.397919 0.200151 +vt 0.397331 0.199847 +vt 0.398856 0.201513 +vt 0.398367 0.200687 +vt 0.399311 0.202711 +vt 0.399960 0.204889 +vt 0.399596 0.206398 +vt 0.398326 0.207979 +vt 0.397087 0.208033 +vt 0.728238 0.462612 +vt 0.713567 0.462683 +vt 0.334656 0.313815 +vt 0.332945 0.313816 +vt 0.350483 0.313714 +vt 0.338947 0.313812 +vt 0.710681 0.677524 +vt 0.702339 0.677094 +vt 0.722646 0.678021 +vt 0.739141 0.677315 +vt 0.750581 0.677084 +vt 0.701653 0.462533 +vt 0.691155 0.462416 +vt 0.842325 0.145138 +vt 0.843129 0.145138 +vt 0.842190 0.145138 +vt 0.404205 0.472075 +vt 0.394327 0.471934 +vt 0.229504 0.332676 +vt 0.219305 0.332593 +vt 0.686713 0.285008 +vt 0.682501 0.325308 +vt 0.683300 0.325295 +vt 0.684371 0.311376 +vt 0.683543 0.311403 +vt 0.682368 0.325310 +vt 0.683405 0.311408 +vt 0.861773 0.262003 +vt 0.876881 0.261950 +vt 0.876174 0.249342 +vt 0.861486 0.249378 +vt 0.278028 0.305835 +vt 0.268686 0.306111 +vt 0.268070 0.318629 +vt 0.277065 0.318443 +vt 0.256059 0.306238 +vt 0.255905 0.318709 +vt 0.242606 0.306911 +vt 0.242911 0.319154 +vt 0.228226 0.306893 +vt 0.229022 0.319137 +vt 0.217290 0.306473 +vt 0.218454 0.318854 +vt 0.405367 0.445954 +vt 0.394977 0.445466 +vt 0.394218 0.458016 +vt 0.404205 0.458336 +vt 0.844709 0.171741 +vt 0.844852 0.171742 +vt 0.843662 0.159118 +vt 0.843525 0.159117 +vt 0.845708 0.171746 +vt 0.844491 0.159121 +vt 0.713251 0.436414 +vt 0.700480 0.435946 +vt 0.701034 0.448561 +vt 0.713183 0.448884 +vt 0.689274 0.435557 +vt 0.690248 0.448294 +vt 0.752053 0.650225 +vt 0.739794 0.650965 +vt 0.739451 0.663470 +vt 0.751294 0.662962 +vt 0.722057 0.653255 +vt 0.722368 0.665038 +vt 0.709306 0.651641 +vt 0.710029 0.663933 +vt 0.360860 0.288261 +vt 0.351850 0.286877 +vt 0.351140 0.299605 +vt 0.359728 0.300553 +vt 0.340431 0.287152 +vt 0.339221 0.299826 +vt 0.334423 0.287203 +vt 0.332480 0.287213 +vt 0.332729 0.299838 +vt 0.334425 0.299836 +vt 0.728846 0.436163 +vt 0.728104 0.448711 +vt 0.341695 0.273219 +vt 0.334359 0.273300 +vt 0.729523 0.422345 +vt 0.713415 0.422651 +vt 0.332161 0.273317 +vt 0.352326 0.272891 +vt 0.361651 0.274684 +vt 0.721828 0.640142 +vt 0.708823 0.638064 +vt 0.740014 0.637190 +vt 0.752558 0.636228 +vt 0.700140 0.422057 +vt 0.688623 0.421560 +vt 0.845665 0.185637 +vt 0.846546 0.185637 +vt 0.845383 0.185602 +vt 0.406344 0.432295 +vt 0.395662 0.431648 +vt 0.227656 0.293360 +vt 0.216480 0.292813 +vt 0.242353 0.293380 +vt 0.256104 0.292489 +vt 0.269039 0.292304 +vt 0.278632 0.291955 +vt 0.862110 0.275892 +vt 0.877441 0.275830 +vt 0.685755 0.298826 +vt 0.684899 0.298854 +vt 0.684756 0.298859 +vt 0.875910 0.235381 +vt 0.861245 0.235397 +vt 0.267361 0.332486 +vt 0.276092 0.332404 +vt 0.255558 0.332525 +vt 0.242956 0.332729 +vt 0.358712 0.314144 +vt 0.863094 0.290277 +vt 0.877832 0.290199 +vt 0.278879 0.277587 +vt 0.269141 0.278022 +vt 0.256054 0.278267 +vt 0.241660 0.279402 +vt 0.226837 0.279384 +vt 0.216071 0.278687 +vt 0.407059 0.418169 +vt 0.396220 0.417341 +vt 0.666767 0.234199 +vt 0.663499 0.234199 +vt 0.663499 0.234325 +vt 0.665777 0.234325 +vt 0.848414 0.200023 +vt 0.849877 0.200023 +vt 0.713652 0.408415 +vt 0.700025 0.407676 +vt 0.688327 0.407051 +vt 0.752791 0.621719 +vt 0.740104 0.622933 +vt 0.721708 0.626655 +vt 0.708606 0.624036 +vt 0.362039 0.260656 +vt 0.352540 0.258393 +vt 0.342854 0.258786 +vt 0.334241 0.258902 +vt 0.331631 0.258930 +vt 0.730079 0.408039 +vt 0.966949 0.197772 +vt 0.964892 0.197807 +vt 0.965370 0.211634 +vt 0.967357 0.211601 +vt 0.780992 0.857370 +vt 0.779892 0.859445 +vt 0.793720 0.861168 +vt 0.793934 0.858840 +vt 0.769447 0.851804 +vt 0.767634 0.853299 +vt 0.762666 0.840881 +vt 0.760441 0.841576 +vt 0.760539 0.823484 +vt 0.758168 0.823266 +vt 0.764994 0.810381 +vt 0.762928 0.809293 +vt 0.773440 0.800484 +vt 0.771924 0.798695 +vt 0.782319 0.796617 +vt 0.781384 0.794504 +vt 0.790835 0.794621 +vt 0.790583 0.792338 +vt 0.801606 0.795215 +vt 0.802316 0.793039 +vt 0.796453 0.791547 +vt 0.796233 0.793893 +vt 0.815312 0.804641 +vt 0.817147 0.803250 +vt 0.808688 0.794660 +vt 0.807443 0.796652 +vt 0.821913 0.815986 +vt 0.824187 0.815335 +vt 0.822940 0.828827 +vt 0.825223 0.828835 +vt 0.822971 0.842828 +vt 0.825223 0.843382 +vt 0.818672 0.853081 +vt 0.820506 0.854636 +vt 0.809584 0.859884 +vt 0.810405 0.862120 +vt 0.367090 0.200541 +vt 0.368713 0.215974 +vt 0.973377 0.729262 +vt 0.975355 0.729260 +vt 0.972875 0.720013 +vt 0.970787 0.719994 +vt 0.966310 0.221076 +vt 0.968308 0.221039 +vt 0.973516 0.710846 +vt 0.971396 0.710828 +vt 0.979336 0.554062 +vt 0.977338 0.554027 +vt 0.977836 0.563480 +vt 0.979879 0.563552 +vt 0.971700 0.702178 +vt 0.973832 0.702196 +vt 0.973939 0.696759 +vt 0.971805 0.696740 +vt 0.978906 0.579086 +vt 0.976742 0.579003 +vt 0.977311 0.591871 +vt 0.979444 0.591947 +vt 0.971897 0.691500 +vt 0.974033 0.691519 +vt 0.974135 0.685825 +vt 0.971998 0.685806 +vt 0.977793 0.603099 +vt 0.979879 0.603172 +vt 0.968308 0.163531 +vt 0.966171 0.163580 +vt 0.965815 0.172708 +vt 0.967980 0.172659 +vt 0.975490 0.092278 +vt 0.973405 0.092365 +vt 0.972477 0.103954 +vt 0.974478 0.103872 +vt 0.965790 0.184940 +vt 0.967899 0.184899 +vt 0.969273 0.121613 +vt 0.971176 0.121539 +vt 0.972511 0.134089 +vt 0.974487 0.134010 +vt 0.421602 0.205470 +vt 0.420722 0.194059 +vt 0.370946 0.188954 +vt 0.421617 0.217952 +vt 0.378238 0.180220 +vt 0.417832 0.226926 +vt 0.386108 0.176848 +vt 0.410171 0.232336 +vt 0.391730 0.175557 +vt 0.952787 0.577042 +vt 0.950924 0.576912 +vt 0.951660 0.589835 +vt 0.953506 0.590217 +vt 0.404965 0.176137 +vt 0.401176 0.175198 +vt 0.396400 0.231321 +vt 0.970947 0.578822 +vt 0.971571 0.592074 +vt 0.415008 0.184005 +vt 0.410717 0.179551 +vt 0.374528 0.225624 +vt 0.972453 0.562935 +vt 0.972171 0.603623 +vt 0.967778 0.091935 +vt 0.967380 0.103802 +vt 0.964830 0.121894 +vt 0.967621 0.134758 +vt 0.969914 0.143963 +vt 0.975490 0.142986 +vt 0.978481 0.720574 +vt 0.979206 0.711152 +vt 0.979558 0.702261 +vt 0.979772 0.691286 +vt 0.979881 0.685435 +vt 0.960417 0.162983 +vt 0.959985 0.172349 +vt 0.960190 0.184900 +vt 0.959495 0.198120 +vt 0.960200 0.212332 +vt 0.961089 0.222041 +vt 0.972118 0.553296 +vt 0.384855 0.230671 +vt 0.375749 0.177186 +vt 0.367532 0.187126 +vt 0.958680 0.184933 +vt 0.957984 0.198153 +vt 0.966269 0.092000 +vt 0.965870 0.103867 +vt 0.417663 0.181517 +vt 0.409934 0.173488 +vt 0.383098 0.234348 +vt 0.396101 0.235890 +vt 0.990840 0.685624 +vt 0.992350 0.685605 +vt 0.993746 0.676622 +vt 0.992235 0.676641 +vt 0.970943 0.562887 +vt 0.969437 0.578774 +vt 0.420778 0.230149 +vt 0.425144 0.219866 +vt 0.363199 0.200288 +vt 0.991550 0.694883 +vt 0.993061 0.694864 +vt 0.979991 0.720593 +vt 0.980717 0.711171 +vt 0.404074 0.172018 +vt 0.398682 0.170664 +vt 0.992026 0.709350 +vt 0.993537 0.709331 +vt 0.993416 0.703740 +vt 0.991905 0.703760 +vt 0.958475 0.172382 +vt 0.425144 0.205824 +vt 0.364975 0.217720 +vt 0.952396 0.601107 +vt 0.954210 0.601677 +vt 0.589063 0.041425 +vt 0.587253 0.041854 +vt 0.587277 0.053416 +vt 0.588872 0.053237 +vt 0.585382 0.071013 +vt 0.586558 0.071119 +vt 0.587564 0.083631 +vt 0.589063 0.083948 +vt 0.995761 0.343284 +vt 0.997250 0.342669 +vt 0.996122 0.333685 +vt 0.994292 0.334059 +vt 0.996774 0.324473 +vt 0.994926 0.324707 +vt 0.995207 0.315790 +vt 0.997061 0.315777 +vt 0.997136 0.310308 +vt 0.995282 0.310189 +vt 0.995336 0.304788 +vt 0.997191 0.305043 +vt 0.997250 0.299321 +vt 0.995396 0.298920 +vt 0.283148 0.274289 +vt 0.281295 0.274795 +vt 0.280748 0.283910 +vt 0.282613 0.283605 +vt 0.280925 0.296175 +vt 0.282713 0.296093 +vt 0.280280 0.309077 +vt 0.281935 0.309172 +vt 0.280874 0.322950 +vt 0.282445 0.323190 +vt 0.281515 0.332446 +vt 0.283148 0.332943 +vt 0.953805 0.551528 +vt 0.952166 0.551993 +vt 0.952469 0.561406 +vt 0.954210 0.561233 +vt 0.411727 0.236973 +vt 0.970061 0.592026 +vt 0.970661 0.603575 +vt 0.992126 0.714797 +vt 0.371526 0.228698 +vt 0.424120 0.192937 +vt 0.970608 0.553248 +vt 0.429854 0.231443 +vt 0.428344 0.231431 +vt 0.428881 0.240362 +vt 0.430392 0.240374 +vt 0.384682 0.173334 +vt 0.980261 0.729922 +vt 0.981772 0.729941 +vt 0.429953 0.219240 +vt 0.428442 0.219229 +vt 0.958906 0.163016 +vt 0.393251 0.171368 +vt 0.981068 0.702280 +vt 0.610598 0.129667 +vt 0.610437 0.129681 +vt 0.614330 0.143132 +vt 0.614478 0.143066 +vt 0.666312 0.244160 +vt 0.666312 0.244082 +vt 0.986981 0.915805 +vt 0.989791 0.917528 +vt 0.996759 0.910175 +vt 0.994370 0.907946 +vt 0.713673 0.396499 +vt 0.700035 0.395637 +vt 0.700028 0.404640 +vt 0.713666 0.405410 +vt 0.688334 0.394906 +vt 0.688329 0.403989 +vt 0.752792 0.609574 +vt 0.740094 0.610993 +vt 0.740102 0.619922 +vt 0.752791 0.618657 +vt 0.721664 0.615344 +vt 0.721697 0.623803 +vt 0.708588 0.612282 +vt 0.708601 0.621072 +vt 0.362113 0.248902 +vt 0.352534 0.246257 +vt 0.352539 0.255333 +vt 0.362058 0.257692 +vt 0.342845 0.246717 +vt 0.342852 0.255743 +vt 0.333535 0.246897 +vt 0.327628 0.246929 +vt 0.327635 0.255932 +vt 0.334131 0.255853 +vt 0.321861 0.246954 +vt 0.315594 0.246981 +vt 0.315601 0.255979 +vt 0.321868 0.255954 +vt 0.958993 0.729794 +vt 0.958692 0.720390 +vt 0.949750 0.720204 +vt 0.949996 0.729593 +vt 0.958664 0.707657 +vt 0.949754 0.707501 +vt 0.957590 0.694089 +vt 0.948830 0.693942 +vt 0.957906 0.679618 +vt 0.949147 0.679464 +vt 0.958993 0.668916 +vt 0.950143 0.668751 +vt 0.740918 0.397063 +vt 0.730216 0.396059 +vt 0.730154 0.405018 +vt 0.740745 0.405913 +vt 0.630399 0.160492 +vt 0.629931 0.161338 +vt 0.630683 0.161868 +vt 0.631136 0.161011 +vt 0.687221 0.267681 +vt 0.686342 0.267709 +vt 0.634840 0.087037 +vt 0.634496 0.086127 +vt 0.622718 0.091242 +vt 0.623295 0.092026 +vt 0.610976 0.115499 +vt 0.610807 0.115467 +vt 0.614354 0.101302 +vt 0.614198 0.101230 +vt 0.686195 0.267714 +vt 0.623391 0.092156 +vt 0.634897 0.087188 +vt 0.613442 0.143527 +vt 0.619884 0.154248 +vt 0.620549 0.153544 +vt 0.609468 0.129767 +vt 0.609851 0.115298 +vt 0.613317 0.100818 +vt 0.866688 0.293278 +vt 0.877835 0.293233 +vt 0.278879 0.274553 +vt 0.269127 0.275007 +vt 0.256029 0.275263 +vt 0.241634 0.276449 +vt 0.226814 0.276430 +vt 0.216050 0.275703 +vt 0.407165 0.415185 +vt 0.396292 0.414320 +vt 0.327527 0.256911 +vt 0.326925 0.259163 +vt 0.330016 0.260765 +vt 0.331249 0.259486 +vt 0.634264 0.163862 +vt 0.634954 0.162449 +vt 0.860148 0.235398 +vt 0.230860 0.335831 +vt 0.865926 0.231732 +vt 0.875869 0.232360 +vt 0.275997 0.335426 +vt 0.267338 0.335816 +vt 0.255560 0.335882 +vt 0.242956 0.335988 +vt 0.231317 0.336878 +vt 0.242972 0.336913 +vt 0.211749 0.397637 +vt 0.211122 0.398585 +vt 0.211255 0.398657 +vt 0.211749 0.407272 +vt 0.255459 0.336671 +vt 0.267089 0.336578 +vt 0.242973 0.337355 +vt 0.231508 0.337321 +vt 0.255459 0.337114 +vt 0.267087 0.337021 +vt 0.275545 0.336859 +vt 0.875622 0.230926 +vt 0.275559 0.336417 +vt 0.875625 0.231368 +vt 0.994953 0.703721 +vt 0.994598 0.694844 +vt 0.964335 0.103932 +vt 0.961785 0.122024 +vt 0.963320 0.121959 +vt 0.995074 0.709312 +vt 0.956938 0.172415 +vt 0.957143 0.184966 +vt 0.964733 0.092065 +vt 0.426807 0.231419 +vt 0.427344 0.240351 +vt 0.957370 0.163050 +vt 0.426905 0.219217 +vt 0.968525 0.591977 +vt 0.969124 0.603526 +vt 0.427664 0.206115 +vt 0.426127 0.206103 +vt 0.967901 0.578725 +vt 0.982928 0.685473 +vt 0.981391 0.685454 +vt 0.428176 0.191997 +vt 0.426639 0.191985 +vt 0.992002 0.304458 +vt 0.990466 0.304491 +vt 0.989746 0.317600 +vt 0.991283 0.317567 +vt 0.428881 0.181921 +vt 0.427344 0.181909 +vt 0.991171 0.333352 +vt 0.992707 0.333319 +vt 0.399745 0.011767 +vt 0.398236 0.011710 +vt 0.395743 0.024199 +vt 0.397252 0.024255 +vt 0.398056 0.042062 +vt 0.399566 0.042119 +vt 0.398236 0.054170 +vt 0.399745 0.054227 +vt 0.958689 0.212365 +vt 0.993513 0.304425 +vt 0.992793 0.317534 +vt 0.994218 0.293140 +vt 0.992708 0.293173 +vt 0.994218 0.333286 +vt 0.992308 0.343194 +vt 0.993818 0.343161 +vt 0.430392 0.181932 +vt 0.429686 0.192008 +vt 0.966112 0.134822 +vt 0.429175 0.206127 +vt 0.959578 0.222074 +vt 0.955025 0.172543 +vt 0.955301 0.185028 +vt 0.966589 0.591925 +vt 0.967173 0.603391 +vt 0.969071 0.553199 +vt 0.967289 0.553240 +vt 0.967593 0.562949 +vt 0.969406 0.562838 +vt 0.983309 0.729960 +vt 0.984874 0.729831 +vt 0.983480 0.720595 +vt 0.981528 0.720613 +vt 0.955428 0.163220 +vt 0.966006 0.578742 +vt 0.957153 0.212398 +vt 0.955416 0.212127 +vt 0.956256 0.221869 +vt 0.958041 0.222107 +vt 0.960440 0.122077 +vt 0.963012 0.134893 +vt 0.964576 0.134888 +vt 0.984191 0.711248 +vt 0.982254 0.711190 +vt 0.962790 0.092369 +vt 0.962660 0.104183 +vt 0.954707 0.198117 +vt 0.956447 0.198187 +vt 0.982605 0.702300 +vt 0.984546 0.702333 +vt 0.984666 0.696733 +vt 0.982720 0.696711 +vt 0.984681 0.695949 +vt 0.984874 0.685465 +vt 0.993887 0.685585 +vt 0.995283 0.676602 +vt 0.396700 0.011653 +vt 0.394207 0.024141 +vt 0.396520 0.042004 +vt 0.396700 0.054113 +vt 0.991171 0.293206 +vt 0.990771 0.343227 +vt 0.634954 0.087340 +vt 0.623487 0.092287 +vt 0.215014 0.727167 +vt 0.215014 0.732122 +vt 0.215132 0.732131 +vt 0.215132 0.727176 +vt 0.686030 0.270740 +vt 0.686049 0.267719 +vt 0.991551 0.871796 +vt 0.986593 0.871826 +vt 0.986768 0.886304 +vt 0.991725 0.886216 +vt 0.944191 0.679324 +vt 0.943873 0.693874 +vt 0.326691 0.256915 +vt 0.949748 0.720289 +vt 0.949002 0.729702 +vt 0.610760 0.129653 +vt 0.614626 0.143000 +vt 0.684613 0.298863 +vt 0.685549 0.285046 +vt 0.331709 0.273352 +vt 0.843387 0.159116 +vt 0.842056 0.145138 +vt 0.682235 0.325312 +vt 0.683267 0.311412 +vt 0.332431 0.287213 +vt 0.844567 0.171741 +vt 0.424322 0.006624 +vt 0.424189 0.006531 +vt 0.418584 0.018133 +vt 0.420703 0.018292 +vt 0.419963 0.032719 +vt 0.422081 0.032851 +vt 0.424174 0.046300 +vt 0.424322 0.046234 +vt 0.987644 0.896159 +vt 0.992599 0.896042 +vt 0.215135 0.718836 +vt 0.215135 0.723790 +vt 0.215293 0.723787 +vt 0.215293 0.718834 +vt 0.945189 0.668584 +vt 0.992599 0.857624 +vt 0.987644 0.857609 +vt 0.944800 0.707468 +vt 0.823759 0.001874 +vt 0.821948 0.002188 +vt 0.823613 0.014576 +vt 0.823759 0.014590 +vt 0.362129 0.015865 +vt 0.360426 0.015938 +vt 0.360288 0.016814 +vt 0.362106 0.016732 +vt 0.360665 0.020113 +vt 0.362477 0.019852 +vt 0.215131 0.693665 +vt 0.215131 0.694618 +vt 0.215290 0.694630 +vt 0.215290 0.693263 +vt 0.330782 0.273432 +vt 0.985911 0.921345 +vt 0.988553 0.921895 +vt 0.989246 0.918103 +vt 0.986428 0.916393 +vt 0.326098 0.259169 +vt 0.995774 0.931865 +vt 0.996759 0.930978 +vt 0.315514 0.256969 +vt 0.315515 0.259246 +vt 0.362477 0.004748 +vt 0.362322 0.004701 +vt 0.995283 0.720677 +vt 0.865853 0.293281 +vt 0.861991 0.290283 +vt 0.860963 0.275897 +vt 0.860386 0.249381 +vt 0.860643 0.262007 +vn -0.9836 0.0281 0.1781 +vn 0.0163 -0.0746 0.9971 +vn 0.0164 0.1136 0.9934 +vn 0.0583 -0.1111 -0.9921 +vn -0.0172 -0.3793 -0.9251 +vn -0.0165 -0.1109 -0.9937 +vn -0.0196 -0.3790 -0.9252 +vn -0.7438 -0.5290 -0.4084 +vn -0.0307 -0.7472 -0.6639 +vn -0.0018 -0.3774 -0.9260 +vn -0.0196 -0.3789 -0.9252 +vn -0.0306 -0.7471 -0.6640 +vn 0.0585 0.0753 -0.9954 +vn 0.0583 -0.1107 -0.9921 +vn -0.9424 0.1409 0.3033 +vn -0.9836 0.0281 0.1782 +vn 0.0165 0.1137 0.9934 +vn 0.0031 -0.7458 -0.6662 +vn 0.0072 -0.7467 -0.6651 +vn 0.0071 -0.7474 -0.6643 +vn 0.0029 -0.7450 -0.6670 +vn -0.0280 -0.0286 -0.9992 +vn 0.0072 -0.7467 -0.6652 +vn -0.0912 0.0755 -0.9930 +vn -0.0175 0.0764 -0.9969 +vn -0.0164 0.0764 -0.9969 +vn 0.0053 -0.1115 -0.9938 +vn 0.0156 0.3808 0.9245 +vn 0.9993 0.0381 0.0013 +vn 0.9522 0.1393 0.2719 +vn 0.1759 0.3000 0.9376 +vn 0.0558 -0.0196 0.9983 +vn 0.2076 0.0839 0.9746 +vn -0.1442 0.3003 0.9429 +vn -0.1751 0.0842 0.9809 +vn -0.0228 -0.0195 0.9996 +vn -0.9308 0.1599 0.3286 +vn -0.9468 -0.0268 0.3208 +vn -0.8753 -0.0362 0.4823 +vn -0.8772 0.1583 0.4533 +vn -0.9102 0.3423 0.2331 +vn -0.8710 0.3358 0.3587 +vn -0.8867 0.4506 0.1036 +vn -0.8837 0.4037 0.2370 +vn -0.9069 0.4188 0.0459 +vn -0.9037 0.4217 0.0744 +vn -0.9132 0.4058 -0.0370 +vn -0.9009 0.4192 -0.1129 +vn -0.9318 0.3186 -0.1742 +vn -0.8969 0.3672 -0.2465 +vn -0.9474 0.2165 -0.2357 +vn -0.8898 0.3024 -0.3418 +vn -0.9538 0.1202 -0.2755 +vn -0.8924 0.1791 -0.4141 +vn -0.9363 -0.1263 -0.3276 +vn -0.9469 0.0019 -0.3215 +vn -0.8863 0.0068 -0.4632 +vn -0.8767 -0.1419 -0.4597 +vn -0.9368 -0.3022 -0.1761 +vn -0.9364 -0.2198 -0.2737 +vn -0.8722 -0.2579 -0.4156 +vn -0.8730 -0.3710 -0.3165 +vn -0.9346 -0.3494 -0.0664 +vn -0.8725 -0.4493 -0.1919 +vn -0.9081 -0.4165 -0.0424 +vn -0.8835 -0.4636 -0.0676 +vn -0.9278 -0.3727 0.0178 +vn -0.8932 -0.4413 0.0867 +vn -0.9186 -0.3188 0.2335 +vn -0.9085 -0.3014 0.2896 +vn -0.9464 -0.1415 0.2905 +vn -0.8821 -0.1595 0.4432 +vn -0.9999 0.0115 0.0048 +vn -0.9998 -0.0198 0.0081 +vn -0.9990 0.0410 -0.0173 +vn -0.9991 0.0430 0.0016 +vn -0.9981 0.0269 0.0550 +vn -0.9979 0.0196 0.0619 +vn -0.9993 0.0011 0.0365 +vn -0.9995 -0.0062 0.0309 +vn -0.9995 -0.0038 0.0321 +vn -0.9994 0.0027 0.0335 +vn -0.9994 -0.0002 0.0341 +vn -0.9989 -0.0166 0.0428 +vn -0.9994 -0.0004 0.0336 +vn -0.9973 -0.0309 0.0662 +vn -0.9972 -0.0501 0.0548 +vn -0.9981 -0.0612 -0.0087 +vn -0.9982 -0.0593 -0.0024 +vn -0.9991 -0.0411 0.0078 +vn 0.0393 -0.3681 -0.9290 +vn -0.0157 -0.3732 -0.9276 +vn -0.0165 0.0368 -0.9992 +vn 0.0420 0.0365 -0.9985 +vn 0.0857 -0.2044 0.9751 +vn 0.0161 -0.1779 0.9839 +vn 0.0110 -0.7128 0.7013 +vn 0.0626 -0.7312 0.6793 +vn 0.0712 -0.7068 0.7038 +vn 0.0110 -0.7093 0.7048 +vn 0.0151 -0.3561 0.9343 +vn 0.0757 -0.3690 0.9263 +vn 0.0710 -0.9366 0.3432 +vn 0.0048 -0.9402 0.3406 +vn 0.0685 -0.9973 -0.0273 +vn -0.0013 -0.9997 -0.0259 +vn 0.0605 -0.9035 -0.4242 +vn -0.0078 -0.9075 -0.4199 +vn 0.0523 -0.5811 -0.8121 +vn -0.0140 -0.5826 -0.8126 +vn 0.0456 -0.1676 -0.9848 +vn -0.0165 -0.1665 -0.9859 +vn -0.0139 -0.5827 -0.8126 +vn 0.0096 -0.9919 0.1266 +vn 0.0012 -0.9924 0.1231 +vn 0.0076 -0.8615 0.5078 +vn 0.0500 -0.6631 0.7468 +vn 0.0099 -0.9919 0.1268 +vn 0.0011 -0.9924 0.1227 +vn 0.0137 0.8624 -0.5060 +vn -0.0076 0.8627 -0.5056 +vn -0.0165 -0.0271 -0.9995 +vn 0.0397 -0.0338 -0.9986 +vn -0.0008 0.9983 -0.0585 +vn -0.0000 0.9985 -0.0554 +vn 0.0136 0.8624 -0.5060 +vn -0.0264 -0.7457 -0.6657 +vn -0.0306 -0.7474 -0.6637 +vn -0.0305 -0.7466 -0.6645 +vn -0.0263 -0.7450 -0.6665 +vn -0.0051 -0.0287 -0.9996 +vn 0.0210 -0.0279 -0.9994 +vn 0.0294 -0.7419 -0.6699 +vn 0.0111 -0.7416 -0.6707 +vn 0.0644 -0.0443 -0.9969 +vn 0.0397 -0.0339 -0.9986 +vn 0.0295 -0.7424 -0.6693 +vn 0.0110 -0.7424 -0.6699 +vn 0.0961 0.0226 0.9951 +vn 0.1113 0.0089 0.9937 +vn 0.1050 0.3416 0.9340 +vn 0.0992 0.3466 0.9328 +vn 0.0992 0.3466 0.9327 +vn 0.1049 0.3416 0.9340 +vn 0.0886 0.7298 0.6778 +vn 0.1012 0.7257 0.6805 +vn 0.0818 0.9094 0.4079 +vn 0.1091 0.9074 0.4057 +vn 0.0700 0.9811 0.1806 +vn 0.1083 0.9784 0.1758 +vn 0.0714 0.9956 -0.0606 +vn 0.1081 0.9921 -0.0644 +vn 0.0794 0.8598 -0.5044 +vn 0.1025 0.8582 -0.5029 +vn 0.0643 -0.0444 -0.9969 +vn 0.0551 -0.0260 -0.9981 +vn 0.0021 -0.9909 0.1344 +vn 0.0151 -0.9911 0.1326 +vn 0.0150 -0.9911 0.1325 +vn -0.0153 -0.9942 -0.1065 +vn 0.0874 -0.6553 0.7503 +vn 0.0707 -0.6482 0.7582 +vn 0.0590 0.0380 -0.9975 +vn 0.0693 0.0367 -0.9969 +vn 0.0726 -0.1692 -0.9829 +vn 0.0599 -0.1694 -0.9837 +vn 0.0804 -0.5787 -0.8116 +vn 0.0671 -0.5778 -0.8134 +vn 0.0804 -0.5787 -0.8115 +vn 0.0905 -0.8970 -0.4327 +vn 0.0789 -0.8940 -0.4411 +vn 0.1000 -0.9946 -0.0284 +vn 0.0927 -0.9953 -0.0291 +vn 0.1004 -0.9305 0.3523 +vn 0.0903 -0.9278 0.3620 +vn 0.1004 -0.9305 0.3524 +vn 0.0972 -0.7023 0.7052 +vn 0.0851 -0.7003 0.7088 +vn 0.0950 -0.3909 0.9155 +vn 0.0798 -0.4162 0.9057 +vn 0.0818 -0.2986 0.9509 +vn 0.1010 -0.2553 0.9616 +vn 0.0738 -0.7482 0.6593 +vn 0.0668 -0.6026 0.7952 +vn 0.0228 -0.3763 -0.9262 +vn 0.0464 -0.3621 -0.9310 +vn 0.0480 -0.4330 0.9001 +vn 0.0547 -0.3661 0.9289 +vn -0.0018 -0.3775 -0.9260 +vn 0.0233 0.0385 -0.9990 +vn 0.0692 -0.4288 0.9007 +vn 0.0511 -0.6998 0.7125 +vn 0.0536 -0.9281 0.3686 +vn 0.0542 -0.9981 -0.0288 +vn 0.0535 -0.9281 0.3685 +vn 0.0406 -0.8942 -0.4457 +vn 0.0297 -0.5772 -0.8161 +vn 0.0240 -0.1675 -0.9856 +vn -0.1946 -0.8295 -0.5234 +vn 0.1117 -0.6602 0.7428 +vn -0.5316 -0.5037 0.6810 +vn 0.0824 0.8484 -0.5229 +vn 0.0211 -0.0279 -0.9994 +vn 0.1280 0.9880 -0.0870 +vn 0.1295 0.9732 0.1900 +vn 0.0973 0.8990 0.4269 +vn 0.0712 0.7201 0.6902 +vn 0.0920 0.3684 0.9251 +vn 0.1394 0.0770 0.9872 +vn -0.0170 -0.7432 -0.6689 +vn 0.0550 -0.0260 -0.9981 +vn -0.0172 -0.7439 -0.6681 +vn -0.0117 -0.7444 -0.6676 +vn -0.0117 -0.7438 -0.6683 +vn -0.0166 -0.0271 -0.9995 +vn 0.0637 0.0217 0.9977 +vn 0.0793 0.3373 0.9381 +vn 0.0424 0.7312 0.6809 +vn 0.0205 0.9109 0.4121 +vn 0.0027 0.9824 0.1866 +vn 0.1619 0.1782 0.9706 +vn 0.0752 0.4127 0.9077 +vn 0.0752 0.4128 0.9077 +vn 0.0441 0.7154 0.6973 +vn 0.0711 0.8851 0.4599 +vn 0.1086 0.9699 0.2181 +vn 0.1015 0.9872 -0.1231 +vn 0.0495 0.8308 -0.5543 +vn 0.0496 0.8308 -0.5543 +vn -0.8123 -0.2742 -0.5147 +vn -0.2292 -0.4931 0.8393 +vn -0.5882 -0.4025 0.7015 +vn -0.5714 -0.7372 -0.3606 +vn -0.3971 -0.7303 -0.5559 +vn -0.2434 -0.6079 0.7558 +vn -0.0046 0.0394 -0.9992 +vn -0.0042 -0.1645 -0.9864 +vn -0.0008 -0.5765 -0.8171 +vn -0.0008 -0.5764 -0.8171 +vn 0.0096 -0.8946 -0.4469 +vn 0.0226 -0.9993 -0.0281 +vn 0.0240 -0.9282 0.3712 +vn 0.0240 -0.9283 0.3712 +vn 0.0234 -0.6996 0.7141 +vn 0.0066 -0.4382 0.8988 +vn -0.0682 -0.3906 0.9180 +vn -0.1286 -0.3407 0.9313 +vn -0.0197 -0.3790 -0.9252 +vn -0.6171 -0.7716 -0.1542 +vn -0.6678 -0.7394 0.0850 +vn 0.0675 -0.9960 0.0588 +vn 0.0538 -0.9841 -0.1693 +vn -0.6195 0.1561 0.7694 +vn -0.5679 -0.0210 0.8228 +vn -0.8005 0.0400 -0.5980 +vn -0.7690 -0.0635 -0.6361 +vn -0.6648 0.4045 0.6280 +vn -0.7640 -0.3882 -0.5155 +vn -0.6464 0.6086 0.4602 +vn -0.7526 -0.6327 -0.1825 +vn -0.6332 0.7730 0.0400 +vn -0.6606 -0.7508 -0.0007 +vn -0.6433 0.6491 -0.4059 +vn -0.7342 -0.6644 0.1399 +vn -0.6764 0.4789 -0.5596 +vn -0.7666 -0.4749 0.4322 +vn -0.6271 0.3620 -0.6897 +vn -0.7604 -0.2491 0.5998 +vn -0.6174 0.2535 -0.7447 +vn -0.7728 -0.1863 0.6067 +vn -0.6089 -0.0866 -0.7885 +vn -0.6483 0.0639 -0.7587 +vn -0.7421 -0.0576 0.6678 +vn -0.7931 0.0760 0.6044 +vn -0.6251 -0.5427 -0.5609 +vn -0.6685 -0.2664 -0.6944 +vn -0.7326 0.2691 0.6252 +vn -0.7613 0.4725 0.4440 +vn -0.6570 -0.6681 -0.3493 +vn -0.7458 0.6178 0.2494 +vn -0.6172 -0.7716 -0.1542 +vn -0.7584 0.6459 0.0871 +vn -0.6679 -0.7394 0.0850 +vn -0.7154 0.6986 -0.0116 +vn -0.6683 -0.6044 0.4336 +vn -0.7212 0.6244 -0.3001 +vn -0.6687 -0.2744 0.6911 +vn -0.7450 0.2935 -0.5990 +vn -0.9912 -0.1167 0.0620 +vn -0.9866 -0.1617 0.0205 +vn -0.6434 0.6491 -0.4059 +vn 0.0582 0.6962 -0.7155 +vn 0.0652 0.9297 -0.3625 +vn 0.0930 -0.8635 0.4957 +vn 0.0599 0.4310 -0.9003 +vn 0.1048 -0.4035 0.9089 +vn -0.6483 0.0638 -0.7587 +vn 0.0598 0.0759 -0.9953 +vn 0.0580 0.3054 -0.9505 +vn -0.5679 -0.0209 0.8228 +vn -0.6195 0.1560 0.7694 +vn 0.0993 0.1431 0.9847 +vn 0.0992 -0.0414 0.9942 +vn 0.0604 -0.3798 -0.9231 +vn 0.0586 -0.1111 -0.9921 +vn 0.0960 0.5659 0.8189 +vn -0.6251 -0.5427 -0.5610 +vn 0.0564 -0.7110 -0.7009 +vn -0.6648 0.4044 0.6281 +vn 0.0827 0.8964 0.4354 +vn -0.6569 -0.6682 -0.3493 +vn 0.0511 -0.9078 -0.4163 +vn 0.0807 0.9965 0.0232 +vn -0.6434 0.6491 -0.4058 +vn -0.9940 0.1036 0.0360 +vn -0.9967 0.0785 0.0186 +vn -0.9899 -0.1396 -0.0253 +vn -0.9919 0.1090 0.0659 +vn -0.9952 -0.0610 0.0768 +vn -0.9940 0.1059 0.0284 +vn -0.9940 0.0266 0.1057 +vn -0.9992 0.0060 -0.0404 +vn -0.9973 0.0139 0.0728 +vn -0.9846 0.0091 -0.1748 +vn -0.9649 0.0431 -0.2589 +vn -0.8744 0.1283 0.4679 +vn -0.9073 -0.0118 0.4203 +vn -0.9974 0.0156 0.0702 +vn -0.9983 0.0136 0.0569 +vn -0.9998 0.0001 0.0198 +vn 0.0980 0.1444 0.9847 +vn 0.0927 -0.0418 0.9948 +vn -0.9960 0.0789 0.0416 +vn -0.9952 0.0798 0.0571 +vn -0.9982 -0.0175 -0.0579 +vn 0.1088 -0.4093 0.9059 +vn 0.1039 0.5672 0.8170 +vn 0.0914 0.8962 0.4341 +vn 0.0671 0.9974 0.0252 +vn 0.0698 0.9308 -0.3587 +vn 0.0702 0.6990 -0.7117 +vn 0.0585 0.4316 -0.9001 +vn 0.0702 0.6989 -0.7117 +vn 0.0575 0.3050 -0.9506 +vn 0.0598 -0.3791 -0.9234 +vn 0.0538 -0.7113 -0.7008 +vn 0.0575 -0.9077 -0.4156 +vn 0.0578 -0.9839 -0.1692 +vn 0.0736 -0.9951 0.0653 +vn 0.0957 -0.8607 0.5001 +vn -0.9948 0.0793 -0.0641 +vn -0.8990 0.3673 -0.2384 +vn -0.8731 0.3340 -0.3551 +vn -0.0037 -0.9853 -0.1705 +vn -0.0077 -0.9088 -0.4171 +vn 0.0081 0.8960 0.4441 +vn 0.0141 0.5696 0.8218 +vn -0.8689 -0.1714 -0.4643 +vn -0.9154 -0.2789 -0.2901 +vn -0.9534 -0.2163 0.2102 +vn -0.9395 -0.3406 0.0374 +vn 0.0052 -0.9311 0.3646 +vn 0.0112 -0.7011 0.7130 +vn 0.0165 -0.0410 0.9990 +vn 0.0147 -0.4083 0.9127 +vn -0.8964 -0.4374 0.0715 +vn -0.8693 -0.4016 0.2882 +vn -0.9218 0.3862 0.0341 +vn -0.9698 -0.0523 0.2383 +vn 0.0145 -0.4366 0.8996 +vn -0.0145 0.4354 -0.9001 +vn -0.0112 0.6986 -0.7154 +vn -0.8888 0.0380 -0.4568 +vn -0.9208 -0.0215 -0.3894 +vn -0.9558 -0.0151 0.2935 +vn -0.9774 -0.0446 0.2068 +vn 0.0155 -0.3068 0.9516 +vn 0.0164 -0.0745 0.9971 +vn -0.0122 -0.7126 -0.7014 +vn -0.9322 -0.3572 -0.0584 +vn -0.8763 0.3829 0.2925 +vn -0.9520 -0.1594 -0.2613 +vn -0.8461 0.3040 0.4378 +vn -0.9520 -0.1594 -0.2614 +vn -0.9446 -0.3253 -0.0433 +vn -0.8763 0.3829 0.2924 +vn -0.9062 -0.4225 0.0149 +vn -0.9218 0.3862 0.0340 +vn -0.8991 0.3672 -0.2384 +vn -0.9103 0.2193 -0.3511 +vn -0.9774 -0.0445 0.2068 +vn -0.9558 -0.0151 0.2936 +vn -0.8888 0.0379 -0.4568 +vn -0.9111 0.1591 -0.3802 +vn -0.9424 0.1410 0.3033 +vn -0.9208 -0.0215 -0.3893 +vn -0.9643 0.1943 0.1797 +vn -0.9155 -0.2789 -0.2900 +vn -0.9506 0.2859 0.1206 +vn -0.8947 -0.4010 -0.1969 +vn -0.9749 0.2196 0.0378 +vn -0.9322 -0.3572 -0.0583 +vn -0.9485 0.3148 0.0359 +vn -0.9405 0.3196 -0.1150 +vn -0.9405 0.3197 -0.1150 +vn -0.9382 0.1319 -0.3198 +vn -0.8290 -0.2263 0.5114 +vn -0.8693 -0.4016 0.2883 +vn -0.8290 -0.2262 0.5114 +vn 0.0165 0.1498 0.9886 +vn 0.0076 -0.8633 0.5046 +vn -0.9643 0.1944 0.1797 +vn 0.0122 0.7136 0.7005 +vn -0.9103 0.2193 -0.3512 +vn -0.0052 0.9298 -0.3681 +vn 0.0077 0.9089 0.4169 +vn -0.0156 -0.3794 -0.9251 +vn -0.9111 0.1592 -0.3802 +vn -0.0155 0.3072 -0.9515 +vn -0.9120 -0.1368 -0.3868 +vn -0.9986 -0.0305 -0.0432 +vn -0.9689 -0.1440 -0.2013 +vn -0.9992 -0.0009 -0.0403 +vn -0.9986 -0.0305 -0.0431 +vn -0.9689 -0.1440 -0.2014 +vn -0.7054 -0.1765 -0.6865 +vn -0.8123 -0.2743 -0.5147 +vn -0.5713 -0.7373 -0.3606 +vn -0.7045 -0.1746 -0.6879 +vn -0.0165 0.0397 -0.9991 +vn -0.0166 -0.1636 -0.9864 +vn -0.7690 -0.0636 -0.6361 +vn -0.0136 -0.5757 -0.8175 +vn -0.7639 -0.3882 -0.5155 +vn -0.7640 -0.3881 -0.5154 +vn -0.0030 -0.8942 -0.4477 +vn 0.0088 -0.9996 -0.0278 +vn -0.6605 -0.7508 -0.0007 +vn 0.0119 -0.9278 0.3728 +vn 0.0119 -0.9278 0.3729 +vn 0.0122 -0.6990 0.7150 +vn 0.0017 -0.4319 0.9019 +vn -0.7728 -0.1864 0.6067 +vn -0.0726 -0.3402 0.9375 +vn -0.0812 -0.0774 0.9937 +vn -0.7422 -0.0575 0.6678 +vn -0.7930 0.0760 0.6044 +vn -0.0636 0.1191 0.9908 +vn -0.1047 0.3776 0.9200 +vn -0.4131 0.6215 0.6656 +vn -0.3149 0.9486 0.0314 +vn -0.7458 0.6178 0.2493 +vn 0.0160 0.9856 0.1683 +vn 0.0113 0.9977 -0.0662 +vn -0.3262 0.9427 -0.0703 +vn -0.7212 0.6243 -0.3001 +vn -0.3131 0.0345 -0.9491 +vn -0.7054 -0.1764 -0.6865 +vn -0.7517 -0.3252 -0.5738 +vn -0.6789 -0.1024 0.7271 +vn -0.6689 0.1728 0.7230 +vn -0.7432 -0.5292 -0.4093 +vn -0.6209 -0.0198 -0.7836 +vn -0.7432 -0.5291 -0.4094 +vn -0.9952 -0.0114 0.0977 +vn -0.6781 0.6304 -0.3779 +vn -0.6209 -0.0197 -0.7837 +vn -0.7071 -0.6823 -0.1856 +vn -0.9989 -0.0336 -0.0334 +vn -0.7430 -0.6564 0.1306 +vn -0.9973 -0.0506 0.0524 +vn -0.7438 -0.5290 -0.4086 +vn -0.8909 -0.1079 0.4413 +vn -0.7438 -0.5291 -0.4084 +vn -0.6424 0.3391 0.6872 +vn -0.6616 0.5422 0.5180 +vn -0.6719 0.6622 0.3316 +vn -0.6707 0.7242 0.1601 +vn -0.6492 0.7564 -0.0808 +vn -0.6689 0.1727 0.7230 +vn -0.6424 0.3392 0.6872 +vn -0.6719 0.6623 0.3316 +vn -0.6491 0.7564 -0.0807 +vn -0.6780 0.6304 -0.3779 +vn -0.6209 -0.0197 -0.7836 +vn -0.0832 0.0143 0.9964 +vn 0.0244 -0.1911 0.9813 +vn -0.2359 -0.4573 0.8575 +vn -0.6140 -0.1201 0.7801 +vn -0.2435 -0.6079 0.7558 +vn 0.0162 0.2466 0.9690 +vn 0.0164 -0.1006 0.9948 +vn 0.0077 -0.8615 0.5078 +vn 0.0649 0.9756 0.2097 +vn 0.0088 0.8762 0.4820 +vn 0.1481 0.1015 0.9837 +vn 0.2535 0.3158 0.9143 +vn 0.2756 0.6981 0.6608 +vn 0.2588 0.8783 0.4020 +vn 0.2256 0.9570 0.1822 +vn 0.2245 0.9571 0.1831 +vn 0.1371 0.8883 0.4383 +vn 0.0163 -0.1006 0.9948 +vn 0.1758 0.3000 0.9376 +vn 0.2768 0.8733 0.4009 +vn 0.0088 0.8743 0.4854 +vn 0.2835 0.6955 0.6602 +vn -0.0149 0.9811 0.1930 +vn 0.0041 0.9809 0.1944 +vn 0.0034 0.9878 0.1555 +vn -0.0219 0.9877 0.1551 +vn 0.0038 0.9057 0.4238 +vn 0.0078 0.9070 0.4211 +vn 0.0257 0.7242 0.6891 +vn 0.0120 0.7262 0.6874 +vn 0.0477 0.3273 0.9437 +vn 0.0159 0.3326 0.9429 +vn 0.0165 -0.0194 0.9997 +vn 0.0476 0.3273 0.9437 +vn 0.2778 0.3140 0.9079 +vn 0.0161 0.2798 0.9599 +vn -0.9970 0.0756 0.0141 +vn -0.9994 0.0313 0.0151 +vn 0.0013 0.9996 0.0265 +vn -0.0691 0.9971 0.0308 +vn -0.0487 0.8896 0.4541 +vn -0.9963 0.0189 -0.0842 +vn -0.0231 -0.9083 -0.4176 +vn -0.0275 -0.7114 -0.7022 +vn -0.9986 0.0399 0.0343 +vn -0.0372 0.5659 0.8236 +vn -0.9735 -0.2175 -0.0702 +vn -0.9972 -0.0735 0.0127 +vn -0.0357 -0.3752 -0.9263 +vn -0.9897 -0.1313 -0.0577 +vn -0.0286 0.1522 0.9879 +vn 0.0037 0.9853 0.1709 +vn -0.9990 0.0071 -0.0445 +vn -0.0251 -0.0411 0.9988 +vn -0.0156 -0.3793 -0.9251 +vn -0.0383 -0.1114 -0.9930 +vn -0.0002 0.9977 -0.0674 +vn -0.9671 -0.0989 -0.2346 +vn -0.0165 -0.1552 -0.9877 +vn -0.0165 0.0404 -0.9990 +vn -0.9999 0.0146 -0.0089 +vn -0.9935 0.0949 0.0627 +vn -0.0076 0.8630 -0.5052 +vn -0.9934 -0.1106 0.0289 +vn -0.0147 0.4107 -0.9116 +vn -0.9710 0.0530 0.2331 +vn -0.9062 -0.4225 0.0150 +vn -0.0013 -0.9996 -0.0264 +vn 0.0052 -0.9312 0.3646 +vn -0.0081 -0.8975 -0.4408 +vn -0.0141 -0.5735 -0.8191 +vn 0.0002 -0.9978 0.0656 +vn -0.9650 0.0430 -0.2588 +vn -0.9846 0.0091 -0.1747 +vn -0.0140 -0.5735 -0.8191 +vn -0.9382 0.1319 -0.3199 +vn -0.9405 0.3196 -0.1151 +vn -0.0053 0.9298 -0.3681 +vn 0.0076 -0.8633 0.5047 +vn -0.9897 -0.1312 -0.0577 +vn -0.9972 -0.0735 0.0126 +vn -0.9879 0.1299 0.0847 +vn -0.0599 -0.8563 0.5130 +vn -0.0447 -0.4133 0.9095 +vn -0.9710 0.0531 0.2330 +vn -0.0519 0.9272 -0.3711 +vn -0.0365 0.6978 -0.7154 +vn -0.9922 0.0214 -0.1224 +vn -0.9827 0.0006 -0.1850 +vn -0.9735 -0.2174 -0.0702 +vn -0.0391 -0.9961 0.0786 +vn -0.9670 -0.0990 -0.2346 +vn -0.0519 0.9272 -0.3710 +vn -0.9959 0.0905 -0.0028 +vn -0.0345 0.4357 -0.8994 +vn -0.9970 0.0755 0.0141 +vn -0.9933 0.0494 0.1041 +vn -0.9879 0.1299 0.0848 +vn -0.0205 -0.9853 -0.1699 +vn -0.0349 0.3071 -0.9510 +vn -0.0365 0.0764 -0.9964 +vn -0.9923 0.0214 -0.1223 +vn -0.9959 0.0905 -0.0029 +vn -0.9827 0.0006 -0.1851 +vn -0.3262 0.9427 -0.0701 +vn -0.8908 -0.1081 0.4413 +vn -0.5809 0.7490 0.3188 +vn -0.5214 -0.2370 0.8197 +vn -0.6529 -0.7459 0.1315 +vn -0.6921 -0.6987 -0.1811 +vn -0.7273 0.6804 0.0895 +vn -0.7625 0.6469 -0.0028 +vn -0.0788 0.1199 0.9896 +vn -0.2292 -0.4930 0.8393 +vn -0.9986 -0.0307 -0.0433 +vn -0.3150 0.9486 0.0314 +vn -0.4133 0.6214 0.6657 +vn -0.5317 -0.5036 0.6810 +vn 0.0626 -0.7311 0.6794 +vn -0.0157 -0.3733 -0.9276 +vn 0.0464 -0.3622 -0.9309 +vn 0.0021 -0.9909 0.1346 +vn 0.0668 -0.6026 0.7953 +vn -0.5810 0.7489 0.3188 +vn -0.6529 -0.7460 0.1315 +vn -0.5214 -0.2371 0.8197 +vn -0.7273 0.6804 0.0894 +vn -0.5741 0.7244 -0.3815 +vn -0.5427 -0.3204 -0.7764 +vn -0.8909 -0.1079 0.4412 +vn -0.5215 -0.2370 0.8197 +vn -0.9119 -0.1369 -0.3869 +vn -0.5741 0.7245 -0.3815 +vn -0.5808 0.7490 0.3188 +vn -0.5427 -0.3203 -0.7764 +vn -0.5740 0.7245 -0.3815 +vn -0.2359 -0.4572 0.8575 +vn -0.6059 -0.5356 0.5883 +vn -0.6745 -0.5184 -0.5256 +vn -0.4055 -0.4071 -0.8184 +vn -0.7042 0.0903 0.7043 +vn -0.6140 -0.1200 0.7801 +vn -0.5915 -0.2591 -0.7636 +vn -0.7045 -0.1748 -0.6879 +vn -0.5316 -0.5036 0.6810 +vn -0.1946 -0.8295 -0.5235 +vn -0.6744 -0.5185 -0.5256 +vn -0.6059 -0.5355 0.5883 +vn -0.6058 -0.5355 0.5884 +vn -0.7517 -0.3251 -0.5738 +vn -0.7042 0.0904 0.7042 +vn -0.1946 -0.8296 -0.5234 +vn -0.6745 -0.5185 -0.5255 +vn -0.2291 -0.4930 0.8393 +vn -0.5882 -0.4025 0.7014 +vn -0.5881 -0.4025 0.7015 +vn -0.5714 -0.7372 -0.3605 +vn -0.6789 -0.1024 0.7270 +vn 0.1117 -0.6602 0.7427 +vn 0.0873 -0.6553 0.7503 +vn 0.9415 0.1582 0.2976 +vn 0.8920 0.1567 0.4240 +vn 0.8907 -0.0377 0.4531 +vn 0.9568 -0.0285 0.2893 +vn 0.9180 0.3407 0.2029 +vn 0.8829 0.3342 0.3297 +vn 0.8904 0.4491 0.0743 +vn 0.8917 0.4021 0.2076 +vn 0.9087 0.4172 0.0159 +vn 0.9064 0.4201 0.0445 +vn 0.9122 0.4042 -0.0672 +vn 0.8974 0.4175 -0.1426 +vn 0.9261 0.3169 -0.2049 +vn 0.8889 0.3656 -0.2760 +vn 0.9395 0.2148 -0.2669 +vn 0.8785 0.3009 -0.3710 +vn 0.9443 0.1185 -0.3069 +vn 0.8786 0.1775 -0.4434 +vn 0.9248 -0.1279 -0.3583 +vn 0.8607 -0.1435 -0.4884 +vn 0.8705 0.0053 -0.4922 +vn 0.9357 0.0002 -0.3527 +vn 0.9300 -0.3039 -0.2070 +vn 0.8614 -0.3725 -0.3452 +vn 0.8575 -0.2595 -0.4442 +vn 0.9264 -0.2215 -0.3045 +vn 0.9313 -0.3511 -0.0972 +vn 0.8649 -0.4509 -0.2206 +vn 0.9055 -0.4181 -0.0724 +vn 0.8799 -0.4651 -0.0967 +vn 0.9272 -0.3744 -0.0129 +vn 0.8948 -0.4429 0.0571 +vn 0.9252 -0.3205 0.2030 +vn 0.9170 -0.3030 0.2594 +vn 0.9552 -0.1432 0.2590 +vn 0.8960 -0.1611 0.4138 +vn 0.9996 0.0098 -0.0283 +vn 0.9995 -0.0216 -0.0249 +vn 0.9980 0.0393 -0.0504 +vn 0.9987 0.0412 -0.0314 +vn 0.9994 0.0251 0.0220 +vn 0.9994 0.0178 0.0288 +vn 1.0000 -0.0006 0.0034 +vn 1.0000 -0.0079 -0.0022 +vn 1.0000 -0.0055 -0.0010 +vn 1.0000 0.0009 0.0005 +vn 1.0000 -0.0020 0.0010 +vn 0.9998 -0.0184 0.0098 +vn 1.0000 -0.0022 0.0006 +vn 0.9989 -0.0326 0.0332 +vn 0.9984 -0.0519 0.0218 +vn 0.9971 -0.0629 -0.0417 +vn 0.9975 -0.0611 -0.0354 +vn 0.9988 -0.0429 -0.0252 +vn -0.0706 -0.3680 -0.9271 +vn -0.0749 0.0366 -0.9965 +vn -0.0538 -0.2043 0.9774 +vn -0.0414 -0.7311 0.6811 +vn -0.0491 -0.7067 0.7058 +vn -0.0457 -0.3689 0.9284 +vn -0.0613 -0.9365 0.3454 +vn -0.0492 -0.7067 0.7058 +vn -0.0712 -0.9971 -0.0250 +vn -0.0761 -0.9034 -0.4219 +vn -0.0801 -0.5810 -0.8099 +vn -0.0784 -0.1675 -0.9828 +vn -0.0072 -0.9919 0.1268 +vn -0.0264 -0.6631 0.7481 +vn -0.0074 -0.9919 0.1270 +vn -0.0288 0.8625 -0.5053 +vn -0.0727 -0.0337 -0.9968 +vn 0.0006 0.9983 -0.0585 +vn 0.0031 -0.7457 -0.6663 +vn -0.0541 -0.0278 -0.9981 +vn -0.0529 -0.7418 -0.6685 +vn -0.0974 -0.0442 -0.9943 +vn -0.0346 -0.7416 -0.6700 +vn -0.0529 -0.7424 -0.6678 +vn -0.0345 -0.7424 -0.6691 +vn -0.0632 0.0227 0.9977 +vn -0.0677 0.3467 0.9355 +vn -0.0734 0.3417 0.9369 +vn -0.0784 0.0091 0.9969 +vn -0.0677 0.3468 0.9355 +vn -0.0773 0.7258 0.6835 +vn -0.0649 0.7300 0.6804 +vn -0.0941 0.9076 0.4091 +vn -0.0667 0.9095 0.4103 +vn -0.1008 0.9786 0.1793 +vn -0.0623 0.9812 0.1828 +vn -0.1084 0.9922 -0.0608 +vn -0.0716 0.9957 -0.0582 +vn -0.1176 0.8584 -0.4993 +vn -0.0945 0.8600 -0.5015 +vn -0.0881 -0.0258 -0.9958 +vn -0.0973 -0.0442 -0.9943 +vn 0.0006 -0.9909 0.1344 +vn 0.0101 -0.9942 -0.1070 +vn -0.0124 -0.9910 0.1329 +vn -0.0124 -0.9910 0.1331 +vn -0.0467 -0.6481 0.7601 +vn -0.0636 -0.6551 0.7528 +vn -0.0919 0.0381 -0.9950 +vn -0.0927 -0.1693 -0.9812 +vn -0.1053 -0.1690 -0.9800 +vn -0.1022 0.0368 -0.9941 +vn -0.0950 -0.5776 -0.8108 +vn -0.1083 -0.5785 -0.8084 +vn -0.0950 -0.8938 -0.4382 +vn -0.1063 -0.8968 -0.4294 +vn -0.1083 -0.5786 -0.8084 +vn -0.0954 -0.9951 -0.0260 +vn -0.1026 -0.9944 -0.0250 +vn -0.0800 -0.9277 0.3648 +vn -0.0904 -0.9303 0.3555 +vn -0.0628 -0.7002 0.7112 +vn -0.0750 -0.7022 0.7080 +vn -0.0506 -0.4161 0.9079 +vn -0.0654 -0.3907 0.9182 +vn -0.0509 -0.2984 0.9531 +vn -0.0415 -0.6025 0.7970 +vn -0.0533 -0.7481 0.6614 +vn -0.0696 -0.2551 0.9644 +vn -0.0541 -0.3762 -0.9249 +vn -0.0778 -0.3620 -0.9289 +vn -0.0190 -0.4330 0.9012 +vn -0.0246 -0.3661 0.9303 +vn -0.0295 -0.3774 -0.9256 +vn -0.0563 0.0386 -0.9977 +vn -0.0402 -0.4287 0.9025 +vn -0.0288 -0.6998 0.7138 +vn -0.0430 -0.9280 0.3702 +vn -0.0569 -0.9980 -0.0269 +vn -0.0430 -0.9280 0.3701 +vn -0.0569 -0.8942 -0.4441 +vn -0.0577 -0.5771 -0.8146 +vn -0.0568 -0.1675 -0.9842 +vn 0.1757 -0.8299 -0.5296 +vn -0.0883 -0.6600 0.7461 +vn 0.5530 -0.5046 0.6630 +vn -0.0981 0.8485 -0.5199 +vn -0.0541 -0.0279 -0.9981 +vn -0.1290 0.9882 -0.0828 +vn -0.0981 0.8485 -0.5200 +vn -0.1214 0.9734 0.1941 +vn -0.0815 0.8992 0.4299 +vn -0.0471 0.7202 0.6922 +vn -0.0607 0.3685 0.9276 +vn -0.1065 0.0772 0.9913 +vn -0.0880 -0.0258 -0.9958 +vn -0.0064 -0.7432 -0.6691 +vn -0.0062 -0.7439 -0.6683 +vn -0.0476 0.3374 0.9402 +vn -0.0307 0.0218 0.9993 +vn -0.0185 0.7312 0.6819 +vn -0.0052 0.9109 0.4125 +vn 0.0053 0.9824 0.1867 +vn -0.1294 0.1785 0.9754 +vn -0.0444 0.4128 0.9097 +vn -0.0444 0.4129 0.9097 +vn -0.0197 0.7155 0.6984 +vn -0.0543 0.8852 0.4620 +vn -0.0996 0.9700 0.2216 +vn -0.1037 0.9874 -0.1197 +vn -0.0663 0.8309 -0.5524 +vn -0.0664 0.8309 -0.5524 +vn -0.0280 -0.0287 -0.9992 +vn 0.7944 -0.2756 -0.5413 +vn 0.5577 -0.7383 -0.3793 +vn 0.6104 -0.4036 0.6816 +vn 0.2559 -0.4935 0.8312 +vn 0.3772 -0.7310 -0.5686 +vn 0.2672 -0.6083 0.7474 +vn -0.0284 0.0394 -0.9988 +vn -0.0287 -0.1644 -0.9860 +vn -0.0272 -0.5764 -0.8167 +vn -0.0260 -0.8945 -0.4463 +vn -0.0253 -0.9993 -0.0274 +vn -0.0134 -0.9282 0.3718 +vn -0.0010 -0.6996 0.7145 +vn 0.0224 -0.4383 0.8986 +vn 0.0978 -0.3907 0.9153 +vn 0.1587 -0.3409 0.9266 +vn -0.0116 -0.3790 -0.9253 +vn 0.6103 -0.7727 -0.1745 +vn -0.0613 -0.9840 -0.1674 +vn -0.0673 -0.9959 0.0611 +vn 0.6690 -0.7406 0.0629 +vn 0.6448 0.1549 0.7485 +vn 0.7474 -0.0649 -0.6612 +vn 0.7803 0.0386 -0.6242 +vn 0.5947 -0.0220 0.8036 +vn 0.6859 0.4033 0.6057 +vn 0.7458 -0.3895 -0.5404 +vn 0.6623 0.6075 0.4385 +vn 0.7450 -0.6341 -0.2072 +vn 0.6356 0.7718 0.0190 +vn 0.6588 -0.7520 -0.0225 +vn 0.6307 0.6480 -0.4269 +vn 0.7372 -0.6657 0.1156 +vn 0.6584 0.4777 -0.5817 +vn 0.7796 -0.4763 0.4067 +vn 0.6046 0.3609 -0.7101 +vn 0.7794 -0.2505 0.5743 +vn 0.5929 0.2524 -0.7647 +vn 0.7921 -0.1877 0.5809 +vn 0.5824 -0.0877 -0.8082 +vn 0.8127 0.0745 0.5778 +vn 0.7637 -0.0589 0.6429 +vn 0.6229 0.0627 -0.7798 +vn 0.6053 -0.5438 -0.5813 +vn 0.7764 0.4712 0.4185 +vn 0.7533 0.2678 0.6006 +vn 0.6447 -0.2675 -0.7161 +vn 0.6439 -0.6693 -0.3708 +vn 0.7547 0.6165 0.2246 +vn 0.7620 0.6446 0.0619 +vn 0.7158 0.6974 -0.0353 +vn 0.6812 -0.6056 0.4112 +vn 0.7120 0.6231 -0.3238 +vn 0.6907 -0.2756 0.6686 +vn 0.7253 0.2922 -0.6233 +vn 0.9865 -0.1635 -0.0121 +vn 0.9925 -0.1185 0.0292 +vn 0.6308 0.6480 -0.4269 +vn -0.0754 0.9298 -0.3602 +vn -0.0806 0.6963 -0.7132 +vn -0.0781 -0.8633 0.4986 +vn 0.6812 -0.6056 0.4113 +vn -0.0889 0.4312 -0.8979 +vn 0.6046 0.3609 -0.7100 +vn -0.0754 -0.4034 0.9119 +vn -0.0889 0.3055 -0.9480 +vn -0.0925 0.0760 -0.9928 +vn 0.6230 0.0628 -0.7797 +vn -0.0664 -0.0412 0.9969 +vn -0.0664 0.1433 0.9875 +vn -0.0916 -0.1110 -0.9896 +vn -0.0916 -0.3797 -0.9206 +vn 0.6447 -0.2676 -0.7161 +vn -0.0679 0.5660 0.8216 +vn -0.0808 -0.7109 -0.6986 +vn 0.6859 0.4032 0.6058 +vn -0.0666 0.8965 0.4379 +vn 0.6623 0.6075 0.4386 +vn -0.0665 -0.9077 -0.4143 +vn 0.6438 -0.6693 -0.3708 +vn -0.0782 0.9966 0.0258 +vn 0.6355 0.7718 0.0190 +vn -0.0755 0.9298 -0.3602 +vn 0.9970 0.0767 -0.0143 +vn 0.9948 0.1019 0.0031 +vn 0.9883 -0.1414 -0.0580 +vn 0.9937 0.1072 0.0330 +vn 0.9971 -0.0627 0.0438 +vn 0.9946 0.1041 -0.0044 +vn 0.9970 0.0248 0.0728 +vn 0.9973 0.0042 -0.0734 +vn 0.9991 0.0121 0.0398 +vn 0.9783 0.0073 -0.2072 +vn 0.9207 -0.0134 0.3900 +vn 0.8896 0.1267 0.4387 +vn 0.9559 0.0414 -0.2907 +vn 0.9996 0.0118 0.0238 +vn 0.9992 0.0138 0.0372 +vn 0.9999 -0.0017 -0.0133 +vn -0.0598 -0.0417 0.9973 +vn -0.0651 0.1445 0.9874 +vn 0.9967 0.0780 0.0242 +vn 0.9970 0.0772 0.0087 +vn 0.9957 -0.0193 -0.0909 +vn -0.0795 -0.4092 0.9090 +vn -0.0758 0.5673 0.8200 +vn -0.0758 0.5674 0.8200 +vn -0.0753 0.8964 0.4369 +vn -0.0648 0.9975 0.0273 +vn -0.0800 0.9310 -0.3562 +vn -0.0924 0.6991 -0.7090 +vn -0.0874 0.4318 -0.8977 +vn -0.0883 0.3051 -0.9482 +vn -0.0912 0.0754 -0.9930 +vn -0.0913 -0.1110 -0.9896 +vn -0.0910 -0.3790 -0.9209 +vn -0.0782 -0.7112 -0.6986 +vn -0.0728 -0.9076 -0.4135 +vn -0.0649 -0.9838 -0.1672 +vn -0.0732 -0.9950 0.0677 +vn -0.0806 -0.8605 0.5030 +vn 0.9923 0.0776 -0.0969 +vn 0.8615 0.3325 -0.3838 +vn 0.8913 0.3657 -0.2680 +vn 0.0081 0.8960 0.4440 +vn 0.9049 -0.2806 -0.3202 +vn 0.8528 -0.1729 -0.4928 +vn 0.9595 -0.2180 0.1786 +vn 0.9396 -0.3422 0.0064 +vn 0.8776 -0.4032 0.2593 +vn 0.8975 -0.4390 0.0419 +vn 0.9231 0.3846 0.0035 +vn 0.9770 -0.0541 0.2061 +vn 0.9074 -0.0231 -0.4196 +vn 0.8732 0.0364 -0.4859 +vn 0.9650 -0.0168 0.2617 +vn 0.0164 -0.0746 0.9971 +vn 0.9836 -0.0463 0.1744 +vn 0.9291 -0.3588 -0.0892 +vn 0.8862 0.3813 0.2633 +vn 0.8607 0.3025 0.4096 +vn 0.9426 -0.1611 -0.2927 +vn 0.9425 -0.1610 -0.2927 +vn 0.8607 0.3025 0.4095 +vn 0.9421 -0.3270 -0.0744 +vn 0.9055 -0.4242 -0.0150 +vn 0.9396 -0.3422 0.0063 +vn 0.8986 0.2177 -0.3811 +vn 0.9770 -0.0540 0.2061 +vn 0.8983 0.1575 -0.4101 +vn 0.8732 0.0364 -0.4860 +vn 0.9650 -0.0168 0.2618 +vn 0.9890 0.0264 0.1456 +vn 0.8528 -0.1730 -0.4928 +vn 0.9522 0.1393 0.2720 +vn 0.9701 0.1926 0.1477 +vn 0.8870 -0.4026 -0.2263 +vn 0.9546 0.2842 0.0891 +vn 0.9291 -0.3588 -0.0891 +vn 0.9760 0.2179 0.0055 +vn 0.9497 0.3131 0.0045 +vn 0.8776 -0.4032 0.2594 +vn 0.9368 0.3179 -0.1460 +vn 0.9368 0.3180 -0.1460 +vn 0.8451 -0.2278 0.4837 +vn 0.9274 0.1302 -0.3507 +vn 0.8451 -0.2277 0.4838 +vn 0.9890 0.0263 0.1455 +vn 0.0166 0.1137 0.9934 +vn 0.9701 0.1927 0.1478 +vn 0.8985 0.2177 -0.3811 +vn 0.8984 -0.1385 -0.4167 +vn 0.9973 -0.0027 -0.0733 +vn 0.9615 -0.1457 -0.2332 +vn 0.9966 -0.0320 -0.0762 +vn 0.9966 -0.0322 -0.0760 +vn 0.9615 -0.1456 -0.2332 +vn 0.6820 -0.1777 -0.7094 +vn 0.6811 -0.1762 -0.7107 +vn 0.5578 -0.7383 -0.3793 +vn 0.7944 -0.2757 -0.5413 +vn -0.0163 -0.1636 -0.9864 +vn -0.0145 -0.5757 -0.8175 +vn -0.0134 -0.8942 -0.4476 +vn -0.0115 -0.9996 -0.0274 +vn -0.0013 -0.9278 0.3731 +vn 0.7372 -0.6657 0.1155 +vn 0.7796 -0.4763 0.4066 +vn 0.0103 -0.6990 0.7151 +vn -0.0012 -0.9278 0.3731 +vn 0.7794 -0.2504 0.5743 +vn 0.0273 -0.4319 0.9015 +vn 0.7921 -0.1878 0.5808 +vn 0.1139 -0.0776 0.9905 +vn 0.1029 -0.3404 0.9346 +vn 0.8127 0.0745 0.5779 +vn 0.7534 0.2678 0.6006 +vn 0.1357 0.3774 0.9161 +vn 0.0966 0.1190 0.9882 +vn 0.7764 0.4711 0.4186 +vn 0.4360 0.6208 0.6516 +vn 0.1357 0.3774 0.9160 +vn 0.7547 0.6165 0.2245 +vn 0.3174 0.9480 0.0209 +vn 0.7620 0.6446 0.0620 +vn -0.0087 0.9856 0.1687 +vn 0.7158 0.6974 -0.0352 +vn -0.0117 0.9978 -0.0658 +vn 0.3253 0.9421 -0.0810 +vn 0.7120 0.6230 -0.3238 +vn 0.2817 0.0340 -0.9589 +vn 0.6820 -0.1776 -0.7095 +vn 0.6928 0.1714 0.7005 +vn 0.7024 -0.1036 0.7042 +vn 0.7317 -0.3265 -0.5984 +vn 0.5946 -0.0209 -0.8037 +vn 0.7284 -0.5304 -0.4338 +vn 0.7284 -0.5305 -0.4337 +vn 0.5946 -0.0208 -0.8038 +vn 0.6663 0.6292 -0.4001 +vn 0.9978 -0.0132 0.0648 +vn 0.6995 -0.6835 -0.2088 +vn 0.9972 -0.0353 -0.0664 +vn 0.7458 -0.6577 0.1060 +vn 0.9984 -0.0523 0.0194 +vn 0.0073 -0.7472 -0.6646 +vn 0.7290 -0.5303 -0.4328 +vn 0.9048 -0.1095 0.4116 +vn 0.7290 -0.5303 -0.4329 +vn 0.6793 0.5410 0.4959 +vn 0.6654 0.3380 0.6656 +vn 0.6837 0.6611 0.3092 +vn 0.6769 0.7230 0.1379 +vn 0.6474 0.7552 -0.1022 +vn 0.6927 0.1715 0.7005 +vn 0.6793 0.5410 0.4958 +vn 0.6837 0.6610 0.3092 +vn 0.6769 0.7230 0.1378 +vn 0.6475 0.7552 -0.1022 +vn 0.6663 0.6292 -0.4002 +vn 0.5946 -0.0208 -0.8037 +vn 0.1161 0.0141 0.9931 +vn 0.6392 -0.1212 0.7594 +vn 0.2633 -0.4577 0.8492 +vn 0.0077 -0.1911 0.9815 +vn 0.2672 -0.6084 0.7473 +vn 0.3772 -0.7310 -0.5687 +vn -0.0265 -0.6631 0.7481 +vn -0.0562 0.9757 0.2117 +vn -0.1153 0.1018 0.9881 +vn -0.2226 0.3162 0.9222 +vn -0.2523 0.6986 0.6695 +vn -0.2438 0.8787 0.4103 +vn -0.2178 0.9574 0.1896 +vn -0.1210 0.8885 0.4426 +vn -0.2166 0.9575 0.1904 +vn -0.1154 0.1018 0.9881 +vn -0.1442 0.3002 0.9429 +vn 0.0164 -0.1007 0.9948 +vn -0.2618 0.8738 0.4098 +vn -0.2603 0.6960 0.6692 +vn 0.0230 0.9810 0.1924 +vn 0.0288 0.9876 0.1543 +vn 0.0119 0.9057 0.4237 +vn -0.0018 0.7243 0.6895 +vn -0.0159 0.3274 0.9448 +vn -0.2471 0.3145 0.9165 +vn 0.0161 0.2799 0.9599 +vn 0.0162 0.2467 0.9690 +vn -0.2471 0.3144 0.9166 +vn 0.9994 0.0295 -0.0179 +vn 0.9971 0.0738 -0.0188 +vn 0.0653 0.8895 0.4522 +vn 0.0719 0.9970 0.0285 +vn 0.9930 0.0171 -0.1171 +vn 0.0030 -0.7114 -0.7027 +vn 0.0076 -0.9084 -0.4181 +vn 0.0654 0.5658 0.8219 +vn 0.9970 -0.0753 -0.0203 +vn 0.9703 -0.2192 -0.1024 +vn 0.0044 -0.3752 -0.9269 +vn 0.9870 -0.1330 -0.0904 +vn 0.0615 0.1521 0.9864 +vn 0.9970 0.0053 -0.0775 +vn 0.0580 -0.0412 0.9975 +vn 0.9586 -0.1007 -0.2665 +vn 0.9952 0.0931 0.0298 +vn 0.9990 0.0128 -0.0419 +vn 0.9937 -0.1123 -0.0039 +vn 0.9783 0.0513 0.2008 +vn 0.9055 -0.4241 -0.0150 +vn 0.9425 -0.1611 -0.2927 +vn 0.9559 0.0414 -0.2906 +vn 0.9274 0.1303 -0.3507 +vn 0.9368 0.3179 -0.1461 +vn 0.9760 0.2178 0.0055 +vn 0.9970 -0.0752 -0.0204 +vn 0.9870 -0.1330 -0.0903 +vn 0.9904 0.1282 0.0520 +vn 0.0753 -0.8564 0.5107 +vn 0.9937 -0.1124 -0.0039 +vn 0.0740 -0.4134 0.9075 +vn 0.0412 0.9271 -0.3726 +vn 0.9761 -0.0012 -0.2174 +vn 0.9877 0.0196 -0.1552 +vn 0.0141 0.6977 -0.7162 +vn 0.9703 -0.2192 -0.1023 +vn 0.0399 -0.9962 0.0773 +vn 0.9586 -0.1007 -0.2664 +vn 0.9954 0.0887 -0.0358 +vn 0.0054 0.4357 -0.9001 +vn 0.9904 0.1281 0.0520 +vn 0.9963 0.0476 0.0712 +vn 0.0131 -0.9853 -0.1704 +vn 0.0039 0.3071 -0.9517 +vn 0.0037 0.0763 -0.9971 +vn 0.9877 0.0196 -0.1551 +vn 0.9761 -0.0011 -0.2174 +vn 0.9963 0.0477 0.0712 +vn 0.9048 -0.1096 0.4115 +vn 0.5479 -0.2379 0.8020 +vn 0.5924 0.7480 0.2994 +vn 0.3253 0.9422 -0.0810 +vn -0.0116 -0.3789 -0.9254 +vn 0.6994 -0.6835 -0.2088 +vn 0.6845 -0.6999 -0.2038 +vn 0.6556 -0.7471 0.1099 +vn 0.7457 -0.6578 0.1060 +vn 0.7632 0.6456 -0.0280 +vn 0.7311 0.6791 0.0653 +vn 0.1117 0.1198 0.9865 +vn 0.9966 -0.0324 -0.0761 +vn 0.2560 -0.4935 0.8313 +vn 0.3177 0.9480 0.0209 +vn 0.4360 0.6207 0.6516 +vn -0.0295 -0.3773 -0.9256 +vn 0.5530 -0.5045 0.6631 +vn -0.0414 -0.7310 0.6811 +vn -0.0706 -0.3681 -0.9271 +vn -0.0778 -0.3621 -0.9289 +vn 0.0006 -0.9909 0.1345 +vn -0.0416 -0.6024 0.7971 +vn 0.5924 0.7479 0.2994 +vn 0.5479 -0.2380 0.8020 +vn 0.6555 -0.7471 0.1099 +vn 0.6845 -0.7000 -0.2039 +vn 0.5162 -0.3213 -0.7939 +vn 0.5625 0.7235 -0.4003 +vn 0.3176 0.9480 0.0208 +vn 0.5624 0.7235 -0.4003 +vn 0.5161 -0.3213 -0.7939 +vn 0.8984 -0.1386 -0.4168 +vn 0.8984 -0.1384 -0.4167 +vn 0.3775 -0.4078 -0.8314 +vn 0.6559 -0.5196 -0.5475 +vn 0.6240 -0.5367 0.5680 +vn 0.7272 0.0891 0.6806 +vn 0.6810 -0.1760 -0.7108 +vn 0.5654 -0.2601 -0.7827 +vn 0.6240 -0.5366 0.5681 +vn 0.6559 -0.5197 -0.5475 +vn 0.5655 -0.2601 -0.7827 +vn 0.7272 0.0890 0.6806 +vn 0.2559 -0.4935 0.8313 +vn 0.2672 -0.6083 0.7473 +vn 0.9522 0.1392 0.2719 +vn -0.0637 -0.6552 0.7528 +usemtl Scene_-_Root +s off +f 13126/12694/8289 13079/12695/8290 13127/12696/8291 +f 13042/12697/8292 13293/12698/8293 13292/12699/8294 +f 13375/12700/8295 13211/12701/8296 12795/12702/8297 +f 13389/12703/8298 13375/12700/8299 12795/12702/8300 +f 13039/12704/8301 13042/12697/8302 13292/12699/8294 +f 13447/12705/8303 13126/12694/8304 13127/12696/8305 +f 13525/12706/8306 13527/12707/8307 13528/12708/8308 +f 13526/12709/8309 13530/12710/8310 13527/12707/8311 +f 13768/12711/8312 14027/12712/8313 14007/12713/8294 +f 14027/12712/8314 14008/12714/8315 14007/12713/8294 +f 14156/12715/8316 13996/12716/8317 13855/12717/8305 +f 14160/12718/8318 14156/12715/8316 13855/12717/8305 +s 1 +f 12694/12719/8319 12695/12720/8320 12696/12721/8321 +f 12697/12722/8322 12698/12723/8323 12699/12724/8324 +f 12700/12725/8325 12701/12726/8326 12702/12727/8327 +f 12700/12725/8325 12702/12727/8327 12703/12728/8328 +f 12704/12729/8329 12700/12725/8325 12703/12728/8328 +f 12704/12729/8329 12703/12728/8328 12705/12730/8330 +f 12706/12731/8331 12704/12729/8329 12705/12730/8330 +f 12706/12731/8331 12705/12730/8330 12707/12732/8332 +f 12708/12733/8333 12706/12731/8331 12707/12732/8332 +f 12708/12733/8333 12707/12732/8332 12709/12734/8334 +f 12710/12735/8335 12708/12733/8333 12709/12734/8334 +f 12710/12735/8335 12709/12734/8334 12711/12736/8336 +f 12712/12737/8337 12710/12735/8335 12711/12736/8336 +f 12712/12737/8337 12711/12736/8336 12713/12738/8338 +f 12714/12739/8339 12712/12737/8337 12713/12738/8338 +f 12714/12739/8339 12713/12738/8338 12715/12740/8340 +f 12716/12741/8341 12714/12739/8339 12715/12740/8340 +f 12716/12741/8341 12715/12740/8340 12717/12742/8342 +f 12718/12743/8343 12719/12744/8344 12720/12745/8345 +f 12718/12743/8343 12720/12745/8345 12721/12746/8346 +f 12722/12747/8347 12723/12748/8348 12724/12749/8349 +f 12722/12747/8347 12724/12749/8349 12725/12750/8350 +f 12726/12751/8351 12722/12747/8347 12725/12750/8350 +f 12726/12751/8351 12725/12750/8350 12727/12752/8352 +f 12728/12753/8353 12726/12751/8351 12727/12752/8352 +f 12728/12753/8353 12727/12752/8352 12729/12754/8354 +f 12730/12755/8355 12728/12753/8353 12729/12754/8354 +f 12730/12755/8355 12729/12754/8354 12731/12756/8356 +f 12732/12757/8357 12730/12755/8355 12731/12756/8356 +f 12732/12757/8357 12731/12756/8356 12733/12758/8358 +f 12734/12759/8359 12732/12757/8357 12733/12758/8358 +f 12734/12759/8359 12733/12758/8358 12735/12760/8360 +f 12701/12726/8326 12734/12759/8359 12735/12760/8360 +f 12701/12726/8326 12735/12760/8360 12702/12727/8327 +f 12736/12761/8361 12737/12762/8362 12701/12726/8326 +f 12736/12761/8361 12701/12726/8326 12700/12725/8325 +f 12738/12763/8363 12736/12761/8361 12700/12725/8325 +f 12738/12763/8363 12700/12725/8325 12704/12729/8329 +f 12739/12764/8364 12738/12763/8363 12704/12729/8329 +f 12739/12764/8364 12704/12729/8329 12706/12731/8331 +f 12740/12765/8365 12739/12764/8364 12706/12731/8331 +f 12740/12765/8365 12706/12731/8331 12708/12733/8333 +f 12741/12766/8366 12740/12765/8365 12708/12733/8333 +f 12741/12766/8366 12708/12733/8333 12710/12735/8335 +f 12742/12767/8367 12741/12766/8366 12710/12735/8335 +f 12742/12767/8367 12710/12735/8335 12712/12737/8337 +f 12743/12768/8368 12742/12767/8367 12712/12737/8337 +f 12743/12768/8368 12712/12737/8337 12714/12739/8339 +f 12744/12769/8369 12743/12768/8368 12714/12739/8339 +f 12744/12769/8369 12714/12739/8339 12716/12741/8341 +f 12745/12770/8370 12746/12771/8371 12719/12744/8344 +f 12745/12770/8370 12719/12744/8344 12718/12743/8343 +f 12747/12772/8372 12748/12773/8373 12723/12748/8348 +f 12747/12772/8372 12723/12748/8348 12722/12747/8347 +f 12749/12774/8374 12747/12772/8372 12722/12747/8347 +f 12749/12774/8374 12722/12747/8347 12726/12751/8351 +f 12750/12775/8375 12749/12774/8374 12726/12751/8351 +f 12750/12775/8375 12726/12751/8351 12728/12753/8353 +f 12751/12776/8376 12750/12775/8375 12728/12753/8353 +f 12751/12776/8376 12728/12753/8353 12730/12755/8355 +f 12752/12777/8377 12751/12776/8376 12730/12755/8355 +f 12752/12777/8377 12730/12755/8355 12732/12757/8357 +f 12753/12778/8378 12752/12777/8377 12732/12757/8357 +f 12753/12778/8378 12732/12757/8357 12734/12759/8359 +f 12737/12762/8362 12753/12778/8378 12734/12759/8359 +f 12737/12762/8362 12734/12759/8359 12701/12726/8326 +f 12754/12779/8379 12755/12780/8380 12756/12781/8381 +f 12754/12779/8379 12756/12781/8381 12757/12782/8382 +f 12758/12783/8383 12759/12784/8384 12760/12785/8385 +f 12758/12783/8383 12760/12785/8385 12761/12786/8386 +f 12762/12787/8387 12763/12788/8388 12764/12789/8389 +f 12762/12787/8387 12764/12789/8389 12765/12790/8390 +f 12766/12791/8391 12767/12792/8392 12768/12793/8388 +f 12766/12791/8391 12768/12793/8388 12769/12794/8387 +f 12770/12795/8393 12771/12796/8394 12767/12792/8392 +f 12770/12795/8393 12767/12792/8392 12766/12791/8391 +f 12772/12797/8395 12773/12798/8396 12771/12796/8394 +f 12772/12797/8395 12771/12796/8394 12770/12795/8393 +f 12774/12799/8397 12775/12800/8398 12773/12798/8396 +f 12774/12799/8397 12773/12798/8396 12772/12797/8395 +f 12776/12801/8399 12777/12802/8400 12778/12803/8401 +f 12776/12801/8399 12778/12803/8401 12779/12804/8397 +f 12757/12782/8382 12756/12781/8381 12777/12802/8400 +f 12757/12782/8382 12777/12802/8400 12776/12801/8399 +f 12780/12805/8402 12781/12806/8403 12782/12807/8404 +f 12780/12805/8402 12782/12807/8404 12783/12808/8405 +f 12784/12809/8406 12785/12810/8407 12781/12806/8403 +f 12784/12809/8406 12781/12806/8403 12780/12805/8402 +f 12786/12811/8408 12787/12812/8409 12788/12813/8410 +f 12786/12811/8408 12788/12813/8410 12789/12814/8411 +f 12790/12815/8412 12791/12816/8413 12792/12817/8409 +f 12790/12815/8412 12792/12817/8409 12793/12818/8414 +f 12794/12819/8415 12795/12702/8416 12796/12820/8417 +f 12794/12819/8415 12796/12820/8417 12797/12821/8418 +f 12797/12821/8418 12796/12820/8417 12798/12822/8419 +f 12797/12821/8418 12798/12822/8419 12799/12823/8420 +f 12800/12824/8421 12801/12825/8422 12802/12826/8423 +f 12800/12824/8421 12802/12826/8423 12803/12827/8424 +f 12804/12828/8425 12805/12829/8426 12801/12825/8422 +f 12804/12828/8425 12801/12825/8422 12800/12824/8421 +f 12806/12830/8427 12807/12831/8428 12808/12832/8429 +f 12806/12830/8427 12808/12832/8429 12809/12833/8430 +f 12810/12834/8431 12811/12835/8432 12812/12836/8433 +f 12810/12834/8431 12812/12836/8433 12813/12837/8434 +f 12813/12837/8434 12812/12836/8433 12814/12838/8435 +f 12813/12837/8434 12814/12838/8435 12815/12839/8436 +f 12815/12839/8436 12814/12838/8435 12816/12840/8437 +f 12815/12839/8436 12816/12840/8437 12817/12841/8438 +f 12817/12841/8438 12816/12840/8437 12818/12842/8439 +f 12817/12841/8438 12818/12842/8439 12819/12843/8440 +f 12819/12843/8440 12818/12842/8439 12820/12844/8441 +f 12819/12843/8440 12820/12844/8441 12821/12845/8442 +f 12822/12846/8442 12823/12847/8441 12824/12848/8443 +f 12822/12846/8442 12824/12848/8443 12825/12849/8444 +f 12826/12850/8445 12827/12851/8446 12828/12852/8447 +f 12826/12850/8445 12828/12852/8447 12829/12853/8448 +f 12829/12853/8448 12828/12852/8447 12830/12854/8449 +f 12829/12853/8448 12830/12854/8449 12831/12855/8450 +f 12832/12856/8451 12833/12857/8452 12834/12858/8453 +f 12832/12856/8451 12834/12858/8453 12835/12859/8454 +f 12835/12859/8454 12834/12858/8453 12836/12860/8455 +f 12835/12859/8454 12836/12860/8455 12837/12861/8456 +f 12838/12862/8456 12839/12863/8457 12840/12864/8458 +f 12838/12862/8456 12840/12864/8458 12841/12865/8459 +f 12841/12865/8459 12840/12864/8458 12842/12866/8460 +f 12841/12865/8459 12842/12866/8460 12843/12867/8461 +f 12843/12867/8461 12842/12866/8460 12844/12868/8462 +f 12843/12867/8461 12844/12868/8462 12845/12869/8463 +f 12846/12870/8463 12847/12871/8464 12848/12872/8465 +f 12846/12870/8463 12848/12872/8465 12849/12873/8466 +f 12849/12873/8466 12848/12872/8465 12850/12874/8467 +f 12849/12873/8466 12850/12874/8467 12851/12875/8468 +f 12852/12876/8469 12853/12877/8470 12854/12878/8471 +f 12852/12876/8469 12854/12878/8471 12855/12879/8472 +f 12856/12880/8473 12857/12881/8474 12833/12857/8452 +f 12856/12880/8473 12833/12857/8452 12832/12856/8451 +f 12851/12875/8468 12850/12874/8467 12853/12877/8470 +f 12851/12875/8468 12853/12877/8470 12852/12876/8469 +f 12765/12790/8390 12764/12789/8389 12759/12784/8384 +f 12765/12790/8390 12759/12784/8384 12758/12783/8383 +f 12746/12771/8371 12744/12769/8369 12716/12741/8341 +f 12746/12771/8371 12716/12741/8341 12719/12744/8344 +f 12719/12744/8344 12716/12741/8341 12717/12742/8342 +f 12719/12744/8344 12717/12742/8342 12720/12745/8345 +f 12858/12882/8475 12851/12875/8468 12852/12876/8469 +f 12858/12882/8475 12852/12876/8469 12859/12883/8476 +f 12860/12884/8477 12856/12880/8473 12832/12856/8451 +f 12860/12884/8477 12832/12856/8451 12861/12885/8478 +f 12859/12883/8476 12852/12876/8469 12855/12879/8472 +f 12859/12883/8476 12855/12879/8472 12862/12886/8479 +f 12863/12887/8480 12849/12873/8466 12851/12875/8468 +f 12863/12887/8480 12851/12875/8468 12858/12882/8475 +f 12864/12888/8481 12846/12870/8463 12849/12873/8466 +f 12864/12888/8481 12849/12873/8466 12863/12887/8480 +f 12865/12889/8482 12843/12867/8461 12845/12869/8463 +f 12865/12889/8482 12845/12869/8463 12866/12890/8483 +f 12867/12891/8484 12841/12865/8459 12843/12867/8461 +f 12867/12891/8484 12843/12867/8461 12865/12889/8482 +f 12868/12892/8485 12838/12862/8456 12841/12865/8459 +f 12868/12892/8485 12841/12865/8459 12867/12891/8484 +f 12869/12893/8486 12835/12859/8454 12837/12861/8456 +f 12869/12893/8486 12837/12861/8456 12870/12894/8485 +f 12861/12885/8478 12832/12856/8451 12835/12859/8454 +f 12861/12885/8478 12835/12859/8454 12869/12893/8486 +f 12871/12895/8487 12829/12853/8448 12831/12855/8450 +f 12871/12895/8487 12831/12855/8450 12872/12896/8488 +f 12873/12897/8489 12826/12850/8445 12829/12853/8448 +f 12873/12897/8489 12829/12853/8448 12871/12895/8487 +f 12874/12898/8490 12822/12846/8442 12825/12849/8444 +f 12874/12898/8490 12825/12849/8444 12875/12899/8491 +f 12876/12900/8492 12819/12843/8440 12821/12845/8442 +f 12876/12900/8492 12821/12845/8442 12877/12901/8490 +f 12878/12902/8493 12817/12841/8438 12819/12843/8440 +f 12878/12902/8493 12819/12843/8440 12876/12900/8492 +f 12879/12903/8494 12815/12839/8436 12817/12841/8438 +f 12879/12903/8494 12817/12841/8438 12878/12902/8493 +f 12880/12904/8495 12813/12837/8434 12815/12839/8436 +f 12880/12904/8495 12815/12839/8436 12879/12903/8494 +f 12881/12905/8496 12810/12834/8431 12813/12837/8434 +f 12881/12905/8496 12813/12837/8434 12880/12904/8495 +f 12882/12906/8497 12806/12830/8427 12809/12833/8430 +f 12882/12906/8497 12809/12833/8430 12883/12907/8496 +f 12801/12825/8422 12884/12908/8498 12885/12909/8499 +f 12801/12825/8422 12885/12909/8499 12802/12826/8423 +f 12805/12829/8426 12886/12910/8500 12884/12908/8498 +f 12805/12829/8426 12884/12908/8498 12801/12825/8422 +f 12850/12874/8467 12765/12790/8390 12758/12783/8383 +f 12850/12874/8467 12758/12783/8383 12853/12877/8470 +f 12887/12911/8501 12804/12828/8425 12800/12824/8421 +f 12887/12911/8501 12800/12824/8421 12888/12912/8502 +f 12888/12912/8502 12800/12824/8421 12803/12827/8424 +f 12888/12912/8502 12803/12827/8424 12889/12913/8503 +f 12807/12831/8428 12890/12914/8504 12891/12915/8505 +f 12807/12831/8428 12891/12915/8505 12808/12832/8429 +f 12811/12835/8432 12892/12916/8505 12893/12917/8506 +f 12811/12835/8432 12893/12917/8506 12812/12836/8433 +f 12812/12836/8433 12893/12917/8506 12894/12918/8507 +f 12812/12836/8433 12894/12918/8507 12814/12838/8435 +f 12814/12838/8435 12894/12918/8507 12895/12919/8508 +f 12814/12838/8435 12895/12919/8508 12816/12840/8437 +f 12816/12840/8437 12895/12919/8508 12790/12815/8412 +f 12816/12840/8437 12790/12815/8412 12818/12842/8439 +f 12818/12842/8439 12790/12815/8412 12793/12818/8414 +f 12818/12842/8439 12793/12818/8414 12820/12844/8441 +f 12823/12847/8441 12786/12811/8408 12789/12814/8411 +f 12823/12847/8441 12789/12814/8411 12824/12848/8443 +f 12827/12851/8446 12784/12809/8406 12780/12805/8402 +f 12827/12851/8446 12780/12805/8402 12828/12852/8447 +f 12828/12852/8447 12780/12805/8402 12783/12808/8405 +f 12828/12852/8447 12783/12808/8405 12830/12854/8449 +f 12833/12857/8452 12757/12782/8382 12776/12801/8399 +f 12833/12857/8452 12776/12801/8399 12834/12858/8453 +f 12834/12858/8453 12776/12801/8399 12779/12804/8397 +f 12834/12858/8453 12779/12804/8397 12836/12860/8455 +f 12839/12863/8457 12774/12799/8397 12772/12797/8395 +f 12839/12863/8457 12772/12797/8395 12840/12864/8458 +f 12840/12864/8458 12772/12797/8395 12770/12795/8393 +f 12840/12864/8458 12770/12795/8393 12842/12866/8460 +f 12842/12866/8460 12770/12795/8393 12766/12791/8391 +f 12842/12866/8460 12766/12791/8391 12844/12868/8462 +f 12847/12871/8464 12896/12920/8391 12762/12787/8387 +f 12847/12871/8464 12762/12787/8387 12848/12872/8465 +f 12848/12872/8465 12762/12787/8387 12765/12790/8390 +f 12848/12872/8465 12765/12790/8390 12850/12874/8467 +f 12853/12877/8470 12758/12783/8383 12761/12786/8386 +f 12853/12877/8470 12761/12786/8386 12854/12878/8471 +f 12857/12881/8474 12754/12779/8379 12757/12782/8382 +f 12857/12881/8474 12757/12782/8382 12833/12857/8452 +f 12897/12921/8509 12882/12906/8497 12883/12907/8496 +f 12897/12921/8509 12883/12907/8496 12898/12922/8510 +f 12899/12923/8511 12881/12905/8496 12880/12904/8495 +f 12899/12923/8511 12880/12904/8495 12900/12924/8512 +f 12900/12924/8512 12880/12904/8495 12879/12903/8494 +f 12900/12924/8512 12879/12903/8494 12901/12925/8513 +f 12901/12925/8513 12879/12903/8494 12878/12902/8493 +f 12901/12925/8513 12878/12902/8493 12902/12926/8514 +f 12902/12926/8514 12878/12902/8493 12876/12900/8492 +f 12902/12926/8514 12876/12900/8492 12903/12927/8515 +f 12903/12927/8515 12876/12900/8492 12877/12901/8490 +f 12903/12927/8515 12877/12901/8490 12904/12928/8516 +f 12905/12929/8517 12874/12898/8490 12875/12899/8491 +f 12905/12929/8517 12875/12899/8491 12906/12930/8419 +f 12907/12931/8518 12908/12932/8519 12909/12933/8520 +f 12907/12931/8518 12909/12933/8520 12910/12934/8521 +f 12911/12935/8522 12871/12895/8487 12872/12896/8488 +f 12911/12935/8522 12872/12896/8488 12912/12936/8523 +f 12913/12937/8524 12861/12885/8478 12869/12893/8486 +f 12913/12937/8524 12869/12893/8486 12914/12938/8525 +f 12914/12938/8525 12869/12893/8486 12870/12894/8485 +f 12914/12938/8525 12870/12894/8485 12915/12939/8526 +f 12916/12940/8527 12868/12892/8485 12867/12891/8484 +f 12916/12940/8527 12867/12891/8484 12917/12941/8528 +f 12917/12941/8528 12867/12891/8484 12865/12889/8482 +f 12917/12941/8528 12865/12889/8482 12918/12942/8529 +f 12918/12942/8529 12865/12889/8482 12866/12890/8483 +f 12918/12942/8529 12866/12890/8483 12919/12943/8530 +f 12920/12944/8531 12864/12888/8481 12863/12887/8480 +f 12920/12944/8531 12863/12887/8480 12921/12945/8532 +f 12921/12945/8532 12863/12887/8480 12858/12882/8475 +f 12921/12945/8532 12858/12882/8475 12922/12946/8533 +f 12923/12947/8534 12859/12883/8476 12862/12886/8479 +f 12923/12947/8534 12862/12886/8479 12924/12948/8535 +f 12925/12949/8536 12860/12884/8477 12861/12885/8478 +f 12925/12949/8536 12861/12885/8478 12913/12937/8524 +f 12922/12946/8533 12858/12882/8475 12859/12883/8476 +f 12922/12946/8533 12859/12883/8476 12923/12947/8534 +f 12884/12908/8498 12797/12821/8418 12799/12823/8420 +f 12884/12908/8498 12799/12823/8420 12885/12909/8499 +f 12886/12910/8500 12794/12819/8415 12797/12821/8418 +f 12886/12910/8500 12797/12821/8418 12884/12908/8498 +f 12926/12950/8537 12927/12951/8538 12928/12952/8539 +f 12926/12950/8537 12928/12952/8539 12929/12953/8540 +f 12930/12954/8541 12931/12955/8542 12932/12956/8543 +f 12930/12954/8541 12932/12956/8543 12933/12957/8544 +f 12934/12958/8545 12930/12954/8541 12933/12957/8544 +f 12934/12958/8545 12933/12957/8544 12935/12959/8546 +f 12936/12960/8547 12934/12958/8545 12935/12959/8546 +f 12936/12960/8547 12935/12959/8546 12937/12961/8548 +f 12938/12962/8549 12936/12960/8547 12937/12961/8548 +f 12938/12962/8549 12937/12961/8548 12939/12963/8550 +f 12940/12964/8551 12938/12962/8549 12939/12963/8550 +f 12940/12964/8551 12939/12963/8550 12941/12965/8552 +f 12942/12966/8553 12940/12964/8551 12941/12965/8552 +f 12942/12966/8553 12941/12965/8552 12943/12967/8554 +f 12944/12968/8555 12942/12966/8553 12943/12967/8554 +f 12944/12968/8555 12943/12967/8554 12945/12969/8556 +f 12946/12970/8557 12944/12968/8555 12945/12969/8556 +f 12946/12970/8557 12945/12969/8556 12947/12971/8558 +f 12948/12972/8559 12949/12973/8560 12950/12974/8561 +f 12948/12972/8559 12950/12974/8561 12951/12975/8562 +f 12952/12976/8563 12953/12977/8564 12954/12978/8565 +f 12952/12976/8563 12954/12978/8565 12955/12979/8566 +f 12956/12980/8567 12952/12976/8563 12955/12979/8566 +f 12956/12980/8567 12955/12979/8566 12957/12981/8568 +f 12958/12982/8569 12956/12980/8567 12957/12981/8568 +f 12958/12982/8569 12957/12981/8568 12959/12983/8570 +f 12960/12984/8571 12958/12982/8569 12959/12983/8570 +f 12960/12984/8571 12959/12983/8570 12961/12985/8572 +f 12962/12986/8573 12960/12984/8571 12961/12985/8572 +f 12962/12986/8573 12961/12985/8572 12963/12987/8574 +f 12964/12988/8575 12962/12986/8573 12963/12987/8574 +f 12964/12988/8575 12963/12987/8574 12965/12989/8576 +f 12931/12955/8542 12964/12988/8575 12965/12989/8576 +f 12931/12955/8542 12965/12989/8576 12932/12956/8543 +f 12709/12734/8334 12707/12732/8332 12966/12990/8577 +f 12709/12734/8334 12966/12990/8577 12967/12991/8578 +f 12968/12992/8579 12969/12993/8553 12970/12994/8580 +f 12968/12992/8579 12970/12994/8580 12971/12995/8581 +f 12927/12951/8538 12972/12996/8573 12973/12997/8582 +f 12927/12951/8538 12973/12997/8582 12928/12952/8539 +f 12969/12993/8553 12974/12998/8555 12975/12999/8583 +f 12969/12993/8553 12975/12999/8583 12970/12994/8580 +f 12976/13000/8573 12977/13001/8575 12978/13002/8584 +f 12976/13000/8573 12978/13002/8584 12979/13003/8582 +f 12980/13004/8557 12981/13005/8585 12982/13006/8586 +f 12980/13004/8557 12982/13006/8586 12983/13007/8587 +f 12984/13008/8588 12985/13009/8589 12986/13010/8590 +f 12984/13008/8588 12986/13010/8590 12987/13011/8591 +f 12977/13001/8575 12984/13008/8588 12987/13011/8591 +f 12977/13001/8575 12987/13011/8591 12978/13002/8584 +f 12988/13012/8559 12989/13013/8564 12990/13014/8592 +f 12988/13012/8559 12990/13014/8592 12991/13015/8593 +f 12985/13009/8589 12992/13016/8545 12993/13017/8594 +f 12985/13009/8589 12993/13017/8594 12986/13010/8590 +f 12994/13018/8564 12995/13019/8595 12996/13020/8596 +f 12994/13018/8564 12996/13020/8596 12997/13021/8592 +f 12998/13022/8597 12999/13023/8547 13000/13024/8598 +f 12998/13022/8597 13000/13024/8598 13001/13025/8594 +f 12995/13019/8595 13002/13026/8599 13003/13027/8600 +f 12995/13019/8595 13003/13027/8600 12996/13020/8596 +f 12999/13023/8547 13004/13028/8549 13005/13029/8601 +f 12999/13023/8547 13005/13029/8601 13000/13024/8598 +f 13002/13026/8599 12926/12950/8537 12929/12953/8540 +f 13002/13026/8599 12929/12953/8540 13003/13027/8600 +f 13004/13028/8549 13006/13030/8602 13007/13031/8581 +f 13004/13028/8549 13007/13031/8581 13005/13029/8601 +f 12729/12754/8354 12727/12752/8352 13008/13032/8603 +f 12729/12754/8354 13008/13032/8603 13009/13033/8604 +f 12711/12736/8336 12709/12734/8334 12967/12991/8578 +f 12711/12736/8336 12967/12991/8578 13010/13034/8605 +f 12731/12756/8356 12729/12754/8354 13009/13033/8604 +f 12731/12756/8356 13009/13033/8604 13011/13035/8606 +f 12713/12738/8338 12711/12736/8336 13010/13034/8605 +f 12713/12738/8338 13010/13034/8605 13012/13036/8607 +f 12733/12758/8358 12731/12756/8356 13011/13035/8606 +f 12733/12758/8358 13011/13035/8606 13013/13037/8608 +f 12715/12740/8340 12713/12738/8338 13012/13036/8607 +f 12715/12740/8340 13012/13036/8607 13014/13038/8609 +f 12735/12760/8360 12733/12758/8358 13013/13037/8608 +f 12735/12760/8360 13013/13037/8608 13015/13039/8610 +f 12717/12742/8342 12715/12740/8340 13014/13038/8609 +f 12717/12742/8342 13014/13038/8609 13016/13040/8611 +f 13017/13041/8612 13018/13042/8613 13019/13043/8614 +f 13017/13041/8612 13019/13043/8614 13020/13044/8615 +f 12721/12746/8346 12720/12745/8345 13021/13045/8616 +f 12721/12746/8346 13021/13045/8616 13022/13046/8617 +f 12702/12727/8327 12735/12760/8360 13015/13039/8610 +f 12702/12727/8327 13015/13039/8610 13023/13047/8618 +f 12987/13011/8591 12986/13010/8590 13024/13048/8619 +f 12987/13011/8591 13024/13048/8619 13025/13049/8620 +f 12725/12750/8350 12724/12749/8349 13026/13050/8621 +f 12725/12750/8350 13026/13050/8621 13027/13051/8622 +f 12707/12732/8332 12705/12730/8330 13028/13052/8623 +f 12707/12732/8332 13028/13052/8623 12966/12990/8577 +f 12727/12752/8352 12725/12750/8350 13027/13051/8622 +f 12727/12752/8352 13027/13051/8622 13008/13032/8603 +f 12978/13002/8584 12987/13011/8591 13025/13049/8620 +f 12978/13002/8584 13025/13049/8620 13029/13053/8624 +f 12986/13010/8590 12993/13017/8594 13030/13054/8625 +f 12986/13010/8590 13030/13054/8625 13024/13048/8619 +f 13001/13025/8594 13000/13024/8598 13031/13055/8626 +f 13001/13025/8594 13031/13055/8626 13032/13056/8625 +f 13000/13024/8598 13005/13029/8601 13033/13057/8627 +f 13000/13024/8598 13033/13057/8627 13031/13055/8626 +f 13005/13029/8601 13007/13031/8581 13034/13058/8628 +f 13005/13029/8601 13034/13058/8628 13033/13057/8627 +f 13007/13031/8581 13035/13059/8580 13036/13060/8629 +f 13007/13031/8581 13036/13060/8629 13034/13058/8628 +f 12970/12994/8580 12975/12999/8583 13037/13061/8630 +f 12970/12994/8580 13037/13061/8630 13038/13062/8631 +f 12983/13007/8587 12982/13006/8586 13039/12704/8301 +f 12983/13007/8587 13039/12704/8301 13040/13063/8632 +f 12991/13015/8593 12990/13014/8592 13041/13064/8633 +f 12991/13015/8593 13041/13064/8633 13042/12697/8292 +f 12997/13021/8592 12996/13020/8596 13043/13065/8634 +f 12997/13021/8592 13043/13065/8634 13044/13066/8633 +f 12996/13020/8596 13003/13027/8600 13045/13067/8635 +f 12996/13020/8596 13045/13067/8635 13043/13065/8634 +f 13003/13027/8600 12929/12953/8540 13046/13068/8636 +f 13003/13027/8600 13046/13068/8636 13045/13067/8635 +f 12929/12953/8540 12928/12952/8539 13047/13069/8637 +f 12929/12953/8540 13047/13069/8637 13046/13068/8636 +f 12928/12952/8539 12973/12997/8582 13048/13070/8638 +f 12928/12952/8539 13048/13070/8638 13047/13069/8637 +f 12979/13003/8582 12978/13002/8584 13029/13053/8624 +f 12979/13003/8582 13029/13053/8624 13049/13071/8638 +f 12705/12730/8330 12703/12728/8328 13050/13072/8639 +f 12705/12730/8330 13050/13072/8639 13028/13052/8623 +f 13012/13036/8607 13010/13034/8605 13051/13073/8640 +f 13012/13036/8607 13051/13073/8640 13052/13074/8641 +f 13045/13067/8635 13046/13068/8636 13053/13075/8642 +f 13045/13067/8635 13053/13075/8642 13054/13076/8643 +f 13032/13056/8625 13031/13055/8626 13055/13077/8644 +f 13032/13056/8625 13055/13077/8644 13056/13078/8645 +f 13027/13051/8622 13026/13050/8621 13057/13079/8646 +f 13027/13051/8622 13057/13079/8646 13058/13080/8647 +f 13050/13072/8639 13023/13047/8618 13059/13081/8615 +f 13050/13072/8639 13059/13081/8615 13060/13082/8614 +f 13061/13083/8648 13062/13084/8649 13063/13085/8650 +f 13061/13083/8648 13063/13085/8650 13064/13086/8651 +f 13029/13053/8624 13025/13049/8620 13065/13087/8652 +f 13029/13053/8624 13065/13087/8652 13066/13088/8653 +f 13013/13037/8608 13011/13035/8606 13067/13089/8654 +f 13013/13037/8608 13067/13089/8654 13068/13090/8655 +f 13010/13034/8605 12967/12991/8578 13069/13091/8656 +f 13010/13034/8605 13069/13091/8656 13051/13073/8640 +f 13070/13092/8657 13061/13083/8648 13064/13086/8651 +f 13070/13092/8657 13064/13086/8651 13071/13093/8658 +f 13038/13062/8631 13037/13061/8630 13072/13094/8659 +f 13038/13062/8631 13072/13094/8659 13073/13095/8660 +f 13022/13046/8617 13021/13045/8616 13074/13096/8661 +f 13022/13046/8617 13074/13096/8661 13075/13097/8662 +f 13076/13098/8663 13077/13099/8664 13078/13100/8665 +f 13076/13098/8663 13078/13100/8665 13079/12695/8666 +f 13043/13065/8634 13045/13067/8635 13054/13076/8643 +f 13043/13065/8634 13054/13076/8643 13080/13101/8667 +f 13011/13035/8606 13009/13033/8604 13081/13102/8668 +f 13011/13035/8606 13081/13102/8668 13067/13089/8654 +f 12967/12991/8578 12966/12990/8577 13082/13103/8669 +f 12967/12991/8578 13082/13103/8669 13069/13091/8656 +f 12703/12728/8328 12702/12727/8327 13023/13047/8618 +f 12703/12728/8328 13023/13047/8618 13050/13072/8639 +f 13018/13042/8613 13083/13104/8670 13084/13105/8671 +f 13018/13042/8613 13084/13105/8671 13019/13043/8614 +f 13085/13106/8672 13086/13107/8673 13087/13108/8674 +f 13085/13106/8672 13087/13108/8674 13088/13109/8671 +f 13086/13107/8673 13089/13110/8675 13090/13111/8676 +f 13086/13107/8673 13090/13111/8676 13087/13108/8674 +f 13089/13110/8675 13091/13112/8649 13092/13113/8640 +f 13089/13110/8675 13092/13113/8640 13090/13111/8676 +f 13093/13114/8649 13094/13115/8648 13095/13116/8641 +f 13093/13114/8649 13095/13116/8641 13096/13117/8677 +f 13094/13115/8648 13097/13118/8657 13098/13119/8678 +f 13094/13115/8648 13098/13119/8678 13095/13116/8641 +f 13099/13120/8679 13100/13121/8680 13101/13122/8681 +f 13099/13120/8679 13101/13122/8681 13102/13123/8682 +f 13103/13124/8304 13104/13125/8683 13105/13126/8646 +f 13103/13124/8304 13105/13126/8646 13106/13127/8684 +f 13107/13128/8303 13108/13129/8685 13109/13130/8686 +f 13107/13128/8303 13109/13130/8686 13110/13131/8646 +f 13108/13129/8685 13111/13132/8687 13112/13133/8688 +f 13108/13129/8685 13112/13133/8688 13109/13130/8686 +f 13111/13132/8687 13113/13134/8689 13114/13135/8690 +f 13111/13132/8687 13114/13135/8690 13112/13133/8688 +f 13113/13134/8689 13115/13136/8691 13116/13137/8654 +f 13113/13134/8689 13116/13137/8654 13114/13135/8690 +f 13115/13136/8691 13117/13138/8692 13118/13139/8655 +f 13115/13136/8691 13118/13139/8655 13116/13137/8654 +f 13119/13140/8693 13120/13141/8694 13121/13142/8695 +f 13119/13140/8693 13121/13142/8695 13122/13143/8696 +f 13120/13141/8694 13017/13041/8612 13020/13044/8615 +f 13120/13141/8694 13020/13044/8615 13121/13142/8695 +f 13015/13039/8610 13013/13037/8608 13068/13090/8655 +f 13015/13039/8610 13068/13090/8655 13123/13144/8697 +f 13024/13048/8619 13030/13054/8625 13124/13145/8645 +f 13024/13048/8619 13124/13145/8645 13125/13146/8698 +f 13126/12694/8304 13076/13098/8663 13079/12695/8666 +f 13028/13052/8623 13050/13072/8639 13060/13082/8614 +f 13028/13052/8623 13060/13082/8614 13128/13147/8671 +f 13008/13032/8603 13027/13051/8622 13058/13080/8647 +f 13008/13032/8603 13058/13080/8647 13129/13148/8688 +f 13023/13047/8618 13015/13039/8610 13123/13144/8697 +f 13023/13047/8618 13123/13144/8697 13059/13081/8615 +f 13049/13071/8638 13029/13053/8624 13066/13088/8653 +f 13049/13071/8638 13066/13088/8653 13130/13149/8699 +f 13131/13150/8700 13132/13151/8303 13133/13152/8316 +f 13131/13150/8700 13133/13152/8316 13134/13153/8701 +f 13014/13038/8609 13012/13036/8607 13052/13074/8641 +f 13014/13038/8609 13052/13074/8641 13135/13154/8702 +f 13136/13155/8628 13038/13062/8631 13073/13095/8660 +f 13136/13155/8628 13073/13095/8660 13137/13156/8703 +f 12966/12990/8577 13028/13052/8623 13128/13147/8671 +f 12966/12990/8577 13128/13147/8671 13082/13103/8669 +f 13009/13033/8604 13008/13032/8603 13129/13148/8688 +f 13009/13033/8604 13129/13148/8688 13081/13102/8668 +f 13138/13157/8687 13131/13150/8700 13134/13153/8701 +f 13138/13157/8687 13134/13153/8701 13139/13158/8704 +f 13044/13066/8633 13043/13065/8634 13080/13101/8667 +f 13044/13066/8633 13080/13101/8667 13140/13159/8705 +f 13016/13040/8611 13014/13038/8609 13135/13154/8702 +f 13016/13040/8611 13135/13154/8702 13141/13160/8706 +f 13037/13061/8630 13040/13063/8632 13142/13161/8707 +f 13037/13061/8630 13142/13161/8707 13072/13094/8659 +f 13143/13162/8708 13144/13163/8709 13145/13164/8710 +f 13143/13162/8708 13145/13164/8710 13146/13165/8711 +f 13147/13166/8712 12908/12932/8519 12907/12931/8518 +f 13147/13166/8712 12907/12931/8518 13148/13167/8713 +f 13149/13168/8714 13150/13169/8715 13151/13170/8716 +f 13149/13168/8714 13151/13170/8716 13152/13171/8717 +f 13153/13172/8543 13154/13173/8718 13155/13174/8719 +f 13153/13172/8543 13155/13174/8719 13156/13175/8720 +f 13156/13175/8720 13155/13174/8719 13157/13176/8721 +f 13156/13175/8720 13157/13176/8721 13158/13177/8722 +f 13159/13178/8723 13160/13179/8721 13161/13180/8724 +f 13159/13178/8723 13161/13180/8724 13162/13181/8548 +f 13162/13181/8548 13161/13180/8724 13163/13182/8725 +f 13162/13181/8548 13163/13182/8725 13164/13183/8726 +f 13164/13183/8726 13163/13182/8725 13165/13184/8727 +f 13164/13183/8726 13165/13184/8727 13166/13185/8552 +f 13167/13186/8552 13168/13187/8728 13169/13188/8729 +f 13167/13186/8552 13169/13188/8729 13170/13189/8554 +f 13170/13189/8554 13169/13188/8729 13171/13190/8730 +f 13170/13189/8554 13171/13190/8730 13172/13191/8556 +f 13173/13192/8731 13174/13193/8732 13175/13194/8733 +f 13173/13192/8731 13175/13194/8733 13176/13195/8734 +f 13177/13196/8735 13178/13197/8736 13179/13198/8737 +f 13177/13196/8735 13179/13198/8737 13180/13199/8565 +f 13181/13200/8565 13182/13201/8737 13183/13202/8738 +f 13181/13200/8565 13183/13202/8738 13184/13203/8566 +f 13184/13203/8566 13183/13202/8738 13185/13204/8739 +f 13184/13203/8566 13185/13204/8739 13186/13205/8740 +f 13186/13205/8740 13185/13204/8739 13187/13206/8741 +f 13186/13205/8740 13187/13206/8741 13188/13207/8570 +f 13188/13207/8570 13187/13206/8741 13189/13208/8742 +f 13188/13207/8570 13189/13208/8742 13190/13209/8572 +f 13190/13209/8572 13189/13208/8742 13191/13210/8743 +f 13190/13209/8572 13191/13210/8743 13192/13211/8574 +f 13193/13212/8744 13194/13213/8743 13195/13214/8745 +f 13193/13212/8744 13195/13214/8745 13196/13215/8576 +f 13196/13215/8576 13195/13214/8745 13154/13173/8718 +f 13196/13215/8576 13154/13173/8718 13153/13172/8543 +f 13197/13216/8746 13198/13217/8747 13199/13218/8748 +f 13197/13216/8746 13199/13218/8748 13200/13219/8749 +f 12796/12820/8417 13201/13220/8750 13202/13221/8751 +f 12796/12820/8417 13202/13221/8751 12798/12822/8419 +f 13203/13222/8752 13204/13223/8753 13205/13224/8754 +f 13203/13222/8752 13205/13224/8754 13206/13225/8755 +f 13207/13226/8756 13143/13162/8708 13146/13165/8711 +f 13207/13226/8756 13146/13165/8711 13208/13227/8757 +f 13209/13228/8758 13207/13226/8756 13208/13227/8757 +f 13209/13228/8758 13208/13227/8757 13210/13229/8759 +f 12795/12702/8416 13211/12701/8760 13201/13220/8750 +f 12795/12702/8416 13201/13220/8750 12796/12820/8417 +f 13212/13230/8761 13209/13228/8758 13210/13229/8759 +f 13212/13230/8761 13210/13229/8759 13204/13223/8753 +f 13213/13231/8762 13212/13230/8761 13204/13223/8753 +f 13213/13231/8762 13204/13223/8753 13203/13222/8752 +f 13145/13164/8710 13214/13232/8518 13215/13233/8763 +f 13145/13164/8710 13215/13233/8763 13216/13234/8764 +f 13146/13165/8711 13145/13164/8710 13216/13234/8764 +f 13146/13165/8711 13216/13234/8764 13217/13235/8765 +f 13208/13227/8757 13146/13165/8711 13217/13235/8765 +f 13208/13227/8757 13217/13235/8765 13218/13236/8766 +f 13210/13229/8759 13208/13227/8757 13218/13236/8766 +f 13210/13229/8759 13218/13236/8766 13219/13237/8767 +f 13204/13223/8753 13210/13229/8759 13219/13237/8767 +f 13204/13223/8753 13219/13237/8767 13205/13224/8754 +f 13220/13238/8768 12897/12921/8509 12898/12922/8510 +f 13220/13238/8768 12898/12922/8510 13221/13239/8769 +f 13222/13240/8769 12899/12923/8511 12900/12924/8512 +f 13222/13240/8769 12900/12924/8512 13223/13241/8764 +f 13223/13241/8764 12900/12924/8512 12901/12925/8513 +f 13223/13241/8764 12901/12925/8513 13224/13242/8770 +f 13224/13242/8770 12901/12925/8513 12902/12926/8514 +f 13224/13242/8770 12902/12926/8514 13225/13243/8766 +f 13225/13243/8766 12902/12926/8514 12903/12927/8515 +f 13225/13243/8766 12903/12927/8515 13226/13244/8771 +f 13226/13244/8771 12903/12927/8515 12904/12928/8516 +f 13226/13244/8771 12904/12928/8516 13227/13245/8772 +f 13228/13246/8772 12905/12929/8517 12906/12930/8419 +f 13228/13246/8772 12906/12930/8419 13229/13247/8773 +f 13230/13248/8774 13231/13249/8775 13232/13250/8776 +f 13230/13248/8774 13232/13250/8776 13233/13251/8777 +f 13198/13217/8747 13234/13252/8522 13235/13253/8778 +f 13198/13217/8747 13235/13253/8778 13199/13218/8748 +f 13154/13173/8718 12913/12937/8524 12914/12938/8525 +f 13154/13173/8718 12914/12938/8525 13155/13174/8719 +f 13155/13174/8719 12914/12938/8525 12915/12939/8526 +f 13155/13174/8719 12915/12939/8526 13157/13176/8721 +f 13160/13179/8721 12916/12940/8527 12917/12941/8528 +f 13160/13179/8721 12917/12941/8528 13161/13180/8724 +f 13161/13180/8724 12917/12941/8528 12918/12942/8529 +f 13161/13180/8724 12918/12942/8529 13163/13182/8725 +f 13163/13182/8725 12918/12942/8529 12919/12943/8530 +f 13163/13182/8725 12919/12943/8530 13165/13184/8727 +f 13168/13187/8728 12920/12944/8531 12921/12945/8532 +f 13168/13187/8728 12921/12945/8532 13169/13188/8729 +f 13169/13188/8729 12921/12945/8532 12922/12946/8533 +f 13169/13188/8729 12922/12946/8533 13171/13190/8730 +f 13174/13193/8732 12923/12947/8534 12924/12948/8535 +f 13174/13193/8732 12924/12948/8535 13175/13194/8733 +f 13195/13214/8745 12925/12949/8536 12913/12937/8524 +f 13195/13214/8745 12913/12937/8524 13154/13173/8718 +f 13171/13190/8730 12922/12946/8533 12923/12947/8534 +f 13171/13190/8730 12923/12947/8534 13174/13193/8732 +f 13172/13191/8556 13171/13190/8730 13174/13193/8732 +f 13172/13191/8556 13174/13193/8732 13173/13192/8731 +f 13021/13045/8616 13016/13040/8611 13141/13160/8706 +f 13021/13045/8616 13141/13160/8706 13074/13096/8661 +f 13025/13049/8620 13024/13048/8619 13125/13146/8698 +f 13025/13049/8620 13125/13146/8698 13065/13087/8652 +f 13097/13118/8657 13099/13120/8679 13102/13123/8682 +f 13097/13118/8657 13102/13123/8682 13098/13119/8678 +f 12975/12999/8583 12983/13007/8587 13040/13063/8632 +f 12975/12999/8583 13040/13063/8632 13037/13061/8630 +f 12720/12745/8345 12717/12742/8342 13016/13040/8611 +f 12720/12745/8345 13016/13040/8611 13021/13045/8616 +f 12974/12998/8555 12980/13004/8557 12983/13007/8587 +f 12974/12998/8555 12983/13007/8587 12975/12999/8583 +f 12949/12973/8560 12946/12970/8557 12947/12971/8558 +f 12949/12973/8560 12947/12971/8558 12950/12974/8561 +f 13236/13254/8779 13237/13255/8780 13238/13256/8405 +f 13236/13254/8779 13238/13256/8405 13239/13257/8781 +f 13240/13258/8782 13241/13259/8783 12791/12816/8413 +f 13240/13258/8782 12791/12816/8413 12790/12815/8412 +f 13242/13260/8784 13243/13261/8785 12891/12915/8505 +f 13242/13260/8784 12891/12915/8505 12890/12914/8504 +f 13244/13262/8785 13245/13263/8786 12893/12917/8506 +f 13244/13262/8785 12893/12917/8506 12892/12916/8505 +f 13245/13263/8786 13246/13264/8787 12894/12918/8507 +f 13245/13263/8786 12894/12918/8507 12893/12917/8506 +f 13246/13264/8787 13247/13265/8788 12895/12919/8508 +f 13246/13264/8787 12895/12919/8508 12894/12918/8507 +f 13247/13265/8788 13240/13258/8782 12790/12815/8412 +f 13247/13265/8788 12790/12815/8412 12895/12919/8508 +f 13240/13258/8782 13247/13265/8788 13248/13266/8789 +f 13240/13258/8782 13248/13266/8789 13249/13267/8790 +f 13250/13268/8784 13251/13269/8791 13252/13270/8792 +f 13250/13268/8784 13252/13270/8792 13253/13271/8321 +f 13247/13265/8788 13246/13264/8787 13254/13272/8793 +f 13247/13265/8788 13254/13272/8793 13248/13266/8789 +f 13241/13259/8783 13240/13258/8782 13249/13267/8790 +f 13241/13259/8783 13249/13267/8790 13255/13273/8794 +f 13246/13264/8787 13245/13263/8786 13256/13274/8795 +f 13246/13264/8787 13256/13274/8795 13254/13272/8793 +f 13257/13275/8796 13258/13276/8797 13259/13277/8798 +f 13257/13275/8796 13259/13277/8798 13260/13278/8799 +f 13261/13279/8800 13262/13280/8801 13258/13276/8797 +f 13261/13279/8800 13258/13276/8797 13257/13275/8796 +f 13263/13281/8802 13264/13282/8803 13262/13280/8801 +f 13263/13281/8802 13262/13280/8801 13261/13279/8800 +f 13265/13283/8804 13266/13284/8805 13264/13282/8803 +f 13265/13283/8804 13264/13282/8803 13263/13281/8802 +f 12695/12720/8320 13267/13285/8806 13268/13286/8805 +f 12695/12720/8320 13268/13286/8805 13269/13287/8807 +f 13245/13263/8786 13244/13262/8785 13270/13288/8808 +f 13245/13263/8786 13270/13288/8808 13256/13274/8795 +f 13237/13255/8791 13271/13289/8809 12694/12719/8319 +f 13260/13278/8799 13259/13277/8798 13255/13273/8794 +f 13260/13278/8799 13255/13273/8794 13249/13267/8790 +f 12695/12720/8320 13269/13287/8807 13272/13290/8808 +f 12695/12720/8320 13272/13290/8808 12696/12721/8321 +f 13265/13283/8804 13263/13281/8802 13256/13274/8795 +f 13265/13283/8804 13256/13274/8795 13270/13288/8808 +f 13263/13281/8802 13261/13279/8800 13254/13272/8793 +f 13263/13281/8802 13254/13272/8793 13256/13274/8795 +f 13261/13279/8800 13257/13275/8796 13248/13266/8789 +f 13261/13279/8800 13248/13266/8789 13254/13272/8793 +f 13257/13275/8796 13260/13278/8799 13249/13267/8790 +f 13257/13275/8796 13249/13267/8790 13248/13266/8789 +f 13078/13100/8665 13071/13093/8658 13273/13291/8810 +f 13078/13100/8665 13273/13291/8810 13274/13292/8811 +f 13055/13077/8644 13275/13293/8812 13276/13294/8813 +f 13055/13077/8644 13276/13294/8813 13277/13295/8814 +f 13079/12695/8666 13078/13100/8665 13274/13292/8811 +f 13079/12695/8666 13274/13292/8811 13278/13296/8815 +f 13080/13101/8667 13054/13076/8643 13279/13297/8816 +f 13080/13101/8667 13279/13297/8816 13280/13298/8817 +f 13127/12696/8305 13079/12695/8666 13278/13296/8815 +f 13127/12696/8305 13278/13296/8815 13281/13299/8818 +f 13056/13078/8645 13055/13077/8644 13277/13295/8814 +f 13056/13078/8645 13277/13295/8814 13282/13300/8819 +f 13134/13153/8701 13133/13152/8316 13283/13301/8820 +f 13134/13153/8701 13283/13301/8820 13284/13302/8821 +f 13140/13159/8705 13080/13101/8667 13280/13298/8817 +f 13140/13159/8705 13280/13298/8817 13285/13303/8822 +f 13139/13158/8704 13134/13153/8701 13284/13302/8821 +f 13139/13158/8704 13284/13302/8821 13286/13304/8823 +f 13125/13146/8698 13124/13145/8645 13287/13305/8819 +f 13125/13146/8698 13287/13305/8819 13288/13306/8824 +f 13289/13307/8825 13139/13158/8704 13286/13304/8823 +f 13289/13307/8825 13286/13304/8823 13290/13308/8826 +f 13065/13087/8652 13125/13146/8698 13288/13306/8824 +f 13065/13087/8652 13288/13306/8824 13291/13309/8827 +f 13292/12699/8294 13293/12698/8828 13294/13310/8822 +f 13292/12699/8294 13294/13310/8822 13295/13311/8829 +f 13296/13312/8830 13289/13307/8825 13290/13308/8826 +f 13296/13312/8830 13290/13308/8826 13297/13313/8831 +f 13298/13314/8832 13299/13315/8833 13300/13316/8834 +f 13298/13314/8832 13300/13316/8834 13301/13317/8835 +f 13302/13318/8836 13296/13312/8830 13297/13313/8831 +f 13302/13318/8836 13297/13313/8831 13303/13319/8837 +f 13299/13315/8833 13304/13320/8838 13305/13321/8839 +f 13299/13315/8833 13305/13321/8839 13300/13316/8834 +f 13306/13322/8649 13307/13323/8840 13308/13324/8841 +f 13306/13322/8649 13308/13324/8841 13309/13325/8842 +f 13307/13323/8840 13310/13326/8673 13311/13327/8843 +f 13307/13323/8840 13311/13327/8843 13308/13324/8841 +f 13040/13063/8632 13039/12704/8301 13312/13328/8314 +f 13040/13063/8632 13312/13328/8314 13142/13161/8707 +f 13310/13326/8673 13313/13329/8670 13314/13330/8844 +f 13310/13326/8673 13314/13330/8844 13311/13327/8843 +f 13031/13055/8626 13033/13057/8627 13275/13293/8812 +f 13031/13055/8626 13275/13293/8812 13055/13077/8644 +f 13046/13068/8636 13047/13069/8637 13315/13331/8845 +f 13046/13068/8636 13315/13331/8845 13053/13075/8642 +f 13316/13332/8846 13317/13333/8847 13299/13315/8833 +f 13316/13332/8846 13299/13315/8833 13298/13314/8832 +f 13318/13334/8672 13316/13332/8846 13298/13314/8832 +f 13318/13334/8672 13298/13314/8832 13319/13335/8848 +f 13320/13336/8849 13321/13337/8692 13322/13338/8836 +f 13320/13336/8849 13322/13338/8836 13304/13320/8838 +f 13077/13099/8664 13070/13092/8657 13071/13093/8658 +f 13077/13099/8664 13071/13093/8658 13078/13100/8665 +f 13042/12697/8292 13041/13064/8633 13293/12698/8828 +f 13317/13333/8847 13320/13336/8849 13304/13320/8838 +f 13317/13333/8847 13304/13320/8838 13299/13315/8833 +f 13323/13339/8850 13324/13340/8691 13296/13312/8830 +f 13323/13339/8850 13296/13312/8830 13302/13318/8836 +f 13033/13057/8627 13034/13058/8628 13325/13341/8851 +f 13033/13057/8627 13325/13341/8851 13275/13293/8812 +f 13324/13340/8691 13326/13342/8689 13289/13307/8825 +f 13324/13340/8691 13289/13307/8825 13296/13312/8830 +f 13047/13069/8637 13048/13070/8638 13327/13343/8852 +f 13047/13069/8637 13327/13343/8852 13315/13331/8845 +f 13326/13342/8689 13138/13157/8687 13139/13158/8704 +f 13326/13342/8689 13139/13158/8704 13289/13307/8825 +f 13280/13298/8817 13279/13297/8816 13328/13344/8853 +f 13280/13298/8817 13328/13344/8853 13329/13345/8854 +f 13288/13306/8824 13287/13305/8819 13330/13346/8855 +f 13288/13306/8824 13330/13346/8855 13331/13347/8835 +f 13332/13348/8856 13333/13349/8857 13334/13350/8858 +f 13332/13348/8856 13334/13350/8858 13335/13351/8837 +f 13336/13352/8859 13337/13353/8860 13338/13354/8861 +f 13336/13352/8859 13338/13354/8861 13339/13355/8862 +f 13285/13303/8822 13280/13298/8817 13329/13345/8854 +f 13285/13303/8822 13329/13345/8854 13340/13356/8863 +f 13291/13309/8827 13288/13306/8824 13331/13347/8835 +f 13291/13309/8827 13331/13347/8835 13341/13357/8834 +f 13342/13358/8864 13343/13359/8856 13344/13360/8837 +f 13342/13358/8864 13344/13360/8837 13345/13361/8865 +f 13276/13294/8813 13346/13362/8866 13347/13363/8862 +f 13276/13294/8813 13347/13363/8862 13348/13364/8867 +f 13337/13353/8860 13349/13365/8868 13350/13366/8869 +f 13337/13353/8860 13350/13366/8869 13338/13354/8861 +f 13333/13349/8857 13291/13309/8827 13341/13357/8834 +f 13333/13349/8857 13341/13357/8834 13334/13350/8858 +f 13282/13300/8819 13277/13295/8814 13351/13367/8870 +f 13282/13300/8819 13351/13367/8870 13352/13368/8871 +f 13279/13297/8816 13353/13369/8872 13354/13370/8826 +f 13279/13297/8816 13354/13370/8826 13328/13344/8853 +f 13355/13371/8873 13356/13372/8874 13357/13373/8815 +f 13355/13371/8873 13357/13373/8815 13358/13374/8811 +f 13277/13295/8814 13276/13294/8813 13348/13364/8867 +f 13277/13295/8814 13348/13364/8867 13351/13367/8870 +f 13353/13369/8872 13342/13358/8864 13345/13361/8865 +f 13353/13369/8872 13345/13361/8865 13354/13370/8826 +f 13295/13311/8829 13294/13310/8822 13359/13375/8820 +f 13295/13311/8829 13359/13375/8820 13360/13376/8818 +f 13349/13365/8868 13355/13371/8873 13358/13374/8811 +f 13349/13365/8868 13358/13374/8811 13350/13366/8869 +f 13071/13093/8658 13064/13086/8651 13361/13377/8875 +f 13071/13093/8658 13361/13377/8875 13273/13291/8810 +f 13054/13076/8643 13053/13075/8642 13353/13369/8872 +f 13054/13076/8643 13353/13369/8872 13279/13297/8816 +f 13072/13094/8659 13142/13161/8707 13355/13371/8873 +f 13072/13094/8659 13355/13371/8873 13349/13365/8868 +f 13064/13086/8651 13063/13085/8650 13362/13378/8862 +f 13064/13086/8651 13362/13378/8862 13361/13377/8875 +f 13053/13075/8642 13315/13331/8845 13342/13358/8864 +f 13053/13075/8642 13342/13358/8864 13353/13369/8872 +f 13275/13293/8812 13325/13341/8851 13346/13362/8866 +f 13275/13293/8812 13346/13362/8866 13276/13294/8813 +f 13309/13325/8842 13308/13324/8841 13363/13379/8876 +f 13309/13325/8842 13363/13379/8876 13364/13380/8877 +f 13315/13331/8845 13327/13343/8852 13343/13359/8856 +f 13315/13331/8845 13343/13359/8856 13342/13358/8864 +f 13308/13324/8841 13311/13327/8843 13365/13381/8870 +f 13308/13324/8841 13365/13381/8870 13363/13379/8876 +f 13130/13149/8699 13066/13088/8653 13333/13349/8857 +f 13130/13149/8699 13333/13349/8857 13332/13348/8856 +f 13137/13156/8703 13073/13095/8660 13337/13353/8860 +f 13137/13156/8703 13337/13353/8860 13336/13352/8859 +f 13311/13327/8843 13314/13330/8844 13366/13382/8855 +f 13311/13327/8843 13366/13382/8855 13365/13381/8870 +f 13066/13088/8653 13065/13087/8652 13291/13309/8827 +f 13066/13088/8653 13291/13309/8827 13333/13349/8857 +f 13073/13095/8660 13072/13094/8659 13349/13365/8868 +f 13073/13095/8660 13349/13365/8868 13337/13353/8860 +f 13319/13335/8848 13298/13314/8832 13301/13317/8835 +f 13319/13335/8848 13301/13317/8835 13367/13383/8855 +f 13304/13320/8838 13322/13338/8836 13368/13384/8837 +f 13304/13320/8838 13368/13384/8837 13305/13321/8839 +f 13142/13161/8707 13312/13328/8314 13356/13372/8874 +f 13142/13161/8707 13356/13372/8874 13355/13371/8873 +f 13175/13194/8733 12924/12948/8535 13231/13249/8775 +f 13175/13194/8733 13231/13249/8775 13230/13248/8774 +f 13369/13385/8745 13370/13386/8878 13212/13230/8761 +f 13369/13385/8745 13212/13230/8761 13213/13231/8762 +f 13371/13387/8879 13372/13388/8878 13373/13389/8880 +f 13371/13387/8879 13373/13389/8880 13374/13390/8881 +f 13375/12700/8295 13376/13391/8745 13211/12701/8296 +f 13377/13392/8756 13378/13393/8758 13379/13394/8882 +f 13377/13392/8756 13379/13394/8882 13380/13395/8883 +f 13189/13208/8742 13187/13206/8741 13381/13396/8884 +f 13189/13208/8742 13381/13396/8884 13382/13397/8885 +f 13178/13197/8736 13175/13194/8733 13230/13248/8774 +f 13178/13197/8736 13230/13248/8774 13383/13398/8886 +f 13183/13202/8738 13182/13201/8737 13384/13399/8887 +f 13183/13202/8738 13384/13399/8887 13385/13400/8888 +f 13386/13401/8889 13387/13402/8890 13144/13163/8709 +f 13386/13401/8889 13144/13163/8709 13143/13162/8708 +f 13388/13403/8473 13389/12703/8298 12794/12819/8415 +f 13388/13403/8473 12794/12819/8415 12886/12910/8500 +f 12924/12948/8535 12862/12886/8479 13390/13404/8891 +f 12924/12948/8535 13390/13404/8891 13231/13249/8775 +f 13391/13405/8471 13392/13406/8892 12784/12809/8406 +f 13391/13405/8471 12784/12809/8406 12827/12851/8446 +f 13393/13407/8893 13394/13408/8379 12804/12828/8425 +f 13393/13407/8893 12804/12828/8425 12887/12911/8501 +f 13395/13409/8894 13388/13403/8473 12886/12910/8500 +f 13395/13409/8894 12886/12910/8500 12805/12829/8426 +f 12862/12886/8479 12855/12879/8472 13396/13410/8895 +f 12862/12886/8479 13396/13410/8895 13390/13404/8891 +f 13397/13411/8896 13391/13405/8471 12827/12851/8446 +f 13397/13411/8896 12827/12851/8446 12826/12850/8445 +f 13394/13408/8379 13395/13409/8894 12805/12829/8426 +f 13394/13408/8379 12805/12829/8426 12804/12828/8425 +f 13389/12703/8298 12795/12702/8416 12794/12819/8415 +f 13392/13406/8892 13398/13412/8385 12785/12810/8407 +f 13392/13406/8892 12785/12810/8407 12784/12809/8406 +f 13399/13413/8897 13400/13414/8885 13401/13415/8898 +f 13399/13413/8897 13401/13415/8898 13402/13416/8899 +f 13400/13414/8885 13403/13417/8900 13404/13418/8883 +f 13400/13414/8885 13404/13418/8883 13401/13415/8898 +f 13403/13417/8900 13405/13419/8901 13406/13420/8902 +f 13403/13417/8900 13406/13420/8902 13404/13418/8883 +f 13378/13393/8758 13407/13421/8903 13408/13422/8904 +f 13378/13393/8758 13408/13422/8904 13379/13394/8882 +f 13409/13423/8889 13410/13424/8905 13411/13425/8902 +f 13409/13423/8889 13411/13425/8902 13412/13426/8906 +f 13191/13210/8743 13189/13208/8742 13382/13397/8885 +f 13191/13210/8743 13382/13397/8885 13413/13427/8907 +f 13414/13428/8708 13377/13392/8756 13380/13395/8883 +f 13414/13428/8708 13380/13395/8883 13415/13429/8908 +f 13187/13206/8741 13185/13204/8739 13416/13430/8909 +f 13187/13206/8741 13416/13430/8909 13381/13396/8884 +f 13417/13431/8910 13418/13432/8911 13419/13433/8912 +f 13417/13431/8910 13419/13433/8912 13420/13434/8913 +f 13421/13435/8914 13422/13436/8915 13423/13437/8916 +f 13421/13435/8914 13423/13437/8916 13424/13438/8917 +f 13422/13436/8915 13425/13439/8910 13426/13440/8913 +f 13422/13436/8915 13426/13440/8913 13423/13437/8916 +f 13427/13441/8918 13428/13442/8919 13429/13443/8920 +f 13427/13441/8918 13429/13443/8920 13430/13444/8921 +f 13231/13249/8775 13390/13404/8891 13431/13445/8922 +f 13231/13249/8775 13431/13445/8922 13232/13250/8776 +f 13432/13446/8522 13433/13447/8923 13434/13448/8916 +f 13432/13446/8522 13434/13448/8916 13435/13449/8913 +f 13383/13398/8886 13230/13248/8774 13233/13251/8777 +f 13383/13398/8886 13233/13251/8777 13436/13450/8924 +f 13437/13451/8925 13432/13446/8522 13435/13449/8913 +f 13437/13451/8925 13435/13449/8913 13438/13452/8926 +f 13439/13453/8927 13383/13398/8886 13436/13450/8924 +f 13439/13453/8927 13436/13450/8924 13440/13454/8928 +f 13441/13455/8929 13421/13435/8914 13424/13438/8917 +f 13441/13455/8929 13424/13438/8917 13442/13456/8930 +f 13179/13198/8737 13178/13197/8736 13383/13398/8886 +f 13179/13198/8737 13383/13398/8886 13439/13453/8927 +f 13356/13372/8874 13295/13311/8829 13360/13376/8818 +f 13356/13372/8874 13360/13376/8818 13357/13373/8815 +f 13039/12704/8301 13292/12699/8294 13312/13328/8314 +f 13312/13328/8314 13292/12699/8294 13295/13311/8829 +f 13312/13328/8314 13295/13311/8829 13356/13372/8874 +f 13443/13457/8316 13127/12696/8305 13281/13299/8818 +f 13443/13457/8316 13281/13299/8818 13444/13458/8820 +f 12694/12719/8319 13271/13289/8809 13267/13285/8806 +f 12694/12719/8319 13267/13285/8806 12695/12720/8320 +f 13243/13261/8785 13242/13260/8784 12696/12721/8321 +f 13243/13261/8785 12696/12721/8321 13272/13290/8808 +f 13237/13255/8780 13242/13260/8784 12890/12914/8504 +f 13237/13255/8780 12890/12914/8504 13238/13256/8405 +f 13445/13459/8931 13446/13460/8778 12897/12921/8509 +f 13445/13459/8931 12897/12921/8509 13220/13238/8768 +f 13214/13232/8518 13197/13216/8746 13200/13219/8749 +f 13214/13232/8518 13200/13219/8749 13215/13233/8763 +f 13176/13195/8734 13175/13194/8733 13178/13197/8736 +f 13176/13195/8734 13178/13197/8736 13177/13196/8735 +f 13433/13447/8923 13149/13168/8714 13152/13171/8717 +f 13433/13447/8923 13152/13171/8717 13434/13448/8916 +f 13447/12705/8683 13127/12696/8305 13443/13457/8316 +f 13100/13121/8680 13103/13124/8304 13106/13127/8684 +f 13100/13121/8680 13106/13127/8684 13101/13122/8681 +f 13026/13050/8621 13022/13046/8617 13075/13097/8662 +f 13026/13050/8621 13075/13097/8662 13057/13079/8646 +f 12982/13006/8586 12991/13015/8593 13042/12697/8292 +f 12982/13006/8586 13042/12697/8292 13039/12704/8301 +f 12724/12749/8349 12721/12746/8346 13022/13046/8617 +f 12724/12749/8349 13022/13046/8617 13026/13050/8621 +f 12981/13005/8585 12988/13012/8559 12991/13015/8593 +f 12981/13005/8585 12991/13015/8593 12982/13006/8586 +f 12953/12977/8564 12948/12972/8559 12951/12975/8562 +f 12953/12977/8564 12951/12975/8562 12954/12978/8565 +f 13446/13460/8778 13448/13461/8932 12882/12906/8497 +f 13446/13460/8778 12882/12906/8497 12897/12921/8509 +f 13449/13462/8933 13238/13256/8405 12890/12914/8504 +f 13449/13462/8933 12890/12914/8504 12807/12831/8428 +f 13448/13461/8932 13450/13463/8450 12806/12830/8427 +f 13448/13461/8932 12806/12830/8427 12882/12906/8497 +f 13450/13463/8450 13449/13462/8933 12807/12831/8428 +f 13450/13463/8450 12807/12831/8428 12806/12830/8427 +f 12748/12773/8373 12745/12770/8370 12718/12743/8343 +f 12748/12773/8373 12718/12743/8343 12723/12748/8348 +f 12723/12748/8348 12718/12743/8343 12721/12746/8346 +f 12723/12748/8348 12721/12746/8346 12724/12749/8349 +f 13451/13464/8934 13452/13465/8935 13453/13466/8936 +f 13451/13464/8934 13453/13466/8936 13454/13467/8937 +f 13455/13468/8938 13456/13469/8939 13452/13465/8935 +f 13455/13468/8938 13452/13465/8935 13451/13464/8934 +f 13457/13470/8940 13458/13471/8941 13456/13469/8939 +f 13457/13470/8940 13456/13469/8939 13455/13468/8938 +f 13459/13472/8942 13460/13473/8943 13458/13471/8941 +f 13459/13472/8942 13458/13471/8941 13457/13470/8940 +f 13461/13474/8944 13462/13475/8945 13460/13473/8943 +f 13461/13474/8944 13460/13473/8943 13459/13472/8942 +f 13463/13476/8946 13464/13477/8947 13462/13475/8945 +f 13463/13476/8946 13462/13475/8945 13461/13474/8944 +f 13465/13478/8948 13466/13479/8949 13464/13477/8947 +f 13465/13478/8948 13464/13477/8947 13463/13476/8946 +f 13467/13480/8950 13468/13481/8951 13466/13479/8949 +f 13467/13480/8950 13466/13479/8949 13465/13478/8948 +f 13469/13482/8952 13470/13483/8953 13471/13484/8954 +f 13469/13482/8952 13471/13484/8954 13472/13485/8955 +f 13473/13486/8956 13474/13487/8957 13475/13488/8958 +f 13473/13486/8956 13475/13488/8958 13476/13489/8959 +f 13477/13490/8960 13478/13491/8961 13474/13487/8957 +f 13477/13490/8960 13474/13487/8957 13473/13486/8956 +f 13479/13492/8962 13480/13493/8963 13478/13491/8961 +f 13479/13492/8962 13478/13491/8961 13477/13490/8960 +f 13481/13494/8964 13482/13495/8965 13480/13493/8963 +f 13481/13494/8964 13480/13493/8963 13479/13492/8962 +f 13483/13496/8966 13484/13497/8967 13482/13495/8965 +f 13483/13496/8966 13482/13495/8965 13481/13494/8964 +f 13485/13498/8968 13486/13499/8969 13484/13497/8967 +f 13485/13498/8968 13484/13497/8967 13483/13496/8966 +f 13454/13467/8937 13453/13466/8936 13486/13499/8969 +f 13454/13467/8937 13486/13499/8969 13485/13498/8968 +f 13487/13500/8970 13451/13464/8934 13454/13467/8937 +f 13487/13500/8970 13454/13467/8937 13488/13501/8971 +f 13489/13502/8972 13455/13468/8938 13451/13464/8934 +f 13489/13502/8972 13451/13464/8934 13487/13500/8970 +f 13490/13503/8973 13457/13470/8940 13455/13468/8938 +f 13490/13503/8973 13455/13468/8938 13489/13502/8972 +f 13491/13504/8974 13459/13472/8942 13457/13470/8940 +f 13491/13504/8974 13457/13470/8940 13490/13503/8973 +f 13492/13505/8975 13461/13474/8944 13459/13472/8942 +f 13492/13505/8975 13459/13472/8942 13491/13504/8974 +f 13493/13506/8976 13463/13476/8946 13461/13474/8944 +f 13493/13506/8976 13461/13474/8944 13492/13505/8975 +f 13494/13507/8977 13465/13478/8948 13463/13476/8946 +f 13494/13507/8977 13463/13476/8946 13493/13506/8976 +f 13495/13508/8978 13467/13480/8950 13465/13478/8948 +f 13495/13508/8978 13465/13478/8948 13494/13507/8977 +f 13496/13509/8979 13469/13482/8952 13472/13485/8955 +f 13496/13509/8979 13472/13485/8955 13497/13510/8980 +f 13498/13511/8981 13473/13486/8956 13476/13489/8959 +f 13498/13511/8981 13476/13489/8959 13499/13512/8982 +f 13500/13513/8983 13477/13490/8960 13473/13486/8956 +f 13500/13513/8983 13473/13486/8956 13498/13511/8981 +f 13501/13514/8984 13479/13492/8962 13477/13490/8960 +f 13501/13514/8984 13477/13490/8960 13500/13513/8983 +f 13502/13515/8985 13481/13494/8964 13479/13492/8962 +f 13502/13515/8985 13479/13492/8962 13501/13514/8984 +f 13503/13516/8986 13483/13496/8966 13481/13494/8964 +f 13503/13516/8986 13481/13494/8964 13502/13515/8985 +f 13504/13517/8987 13485/13498/8968 13483/13496/8966 +f 13504/13517/8987 13483/13496/8966 13503/13516/8986 +f 13488/13501/8971 13454/13467/8937 13485/13498/8968 +f 13488/13501/8971 13485/13498/8968 13504/13517/8987 +f 13505/13518/8988 13506/13519/8989 12756/12781/8381 +f 13505/13518/8988 12756/12781/8381 12755/12780/8380 +f 13507/13520/8990 13508/13521/8991 12760/12785/8385 +f 13507/13520/8990 12760/12785/8385 12759/12784/8384 +f 13509/13522/8992 13510/13523/8993 12764/12789/8389 +f 13509/13522/8992 12764/12789/8389 12763/12788/8388 +f 13511/13524/8994 13512/13525/8995 12768/12793/8388 +f 13511/13524/8994 12768/12793/8388 12767/12792/8392 +f 13513/13526/8996 13511/13524/8994 12767/12792/8392 +f 13513/13526/8996 12767/12792/8392 12771/12796/8394 +f 13514/13527/8997 13513/13526/8996 12771/12796/8394 +f 13514/13527/8997 12771/12796/8394 12773/12798/8396 +f 13515/13528/8998 13514/13527/8997 12773/12798/8396 +f 13515/13528/8998 12773/12798/8396 12775/12800/8398 +f 13516/13529/8999 13517/13530/8998 12778/12803/8401 +f 13516/13529/8999 12778/12803/8401 12777/12802/8400 +f 13506/13519/8989 13516/13529/8999 12777/12802/8400 +f 13506/13519/8989 12777/12802/8400 12756/12781/8381 +f 13518/13531/9000 13519/13532/9001 12782/12807/8404 +f 13518/13531/9000 12782/12807/8404 12781/12806/8403 +f 13520/13533/9002 13518/13531/9000 12781/12806/8403 +f 13520/13533/9002 12781/12806/8403 12785/12810/8407 +f 13521/13534/9003 13522/13535/9004 12788/12813/8410 +f 13521/13534/9003 12788/12813/8410 12787/12812/8409 +f 13523/13536/9005 13524/13537/9003 12792/12817/8409 +f 13523/13536/9005 12792/12817/8409 12791/12816/8413 +f 13525/12706/9006 13526/12709/8309 13527/12707/8307 +f 13526/12709/8309 13529/13538/9007 13530/12710/8310 +f 13531/13539/9008 13532/13540/9004 13533/13541/9009 +f 13531/13539/9008 13533/13541/9009 13534/13542/9010 +f 13535/13543/9011 13531/13539/9008 13534/13542/9010 +f 13535/13543/9011 13534/13542/9010 13536/13544/9012 +f 13537/13545/9013 13538/13546/9014 13539/13547/9015 +f 13537/13545/9013 13539/13547/9015 13540/13548/9016 +f 13541/13549/9017 13542/13550/9018 13543/13551/9019 +f 13541/13549/9017 13543/13551/9019 13544/13552/9015 +f 13542/13550/9018 13545/13553/9020 13546/13554/9021 +f 13542/13550/9018 13546/13554/9021 13543/13551/9019 +f 13545/13553/9020 13547/13555/9022 13548/13556/9023 +f 13545/13553/9020 13548/13556/9023 13546/13554/9021 +f 13547/13555/9022 13549/13557/9024 13550/13558/9025 +f 13547/13555/9022 13550/13558/9025 13548/13556/9023 +f 13549/13557/9024 13551/13559/9026 13552/13560/9027 +f 13549/13557/9024 13552/13560/9027 13550/13558/9025 +f 13553/13561/9026 13554/13562/9028 13555/13563/9029 +f 13553/13561/9026 13555/13563/9029 13556/13564/9027 +f 13557/13565/9030 13558/13566/9031 13559/13567/9032 +f 13557/13565/9030 13559/13567/9032 13560/13568/9033 +f 13558/13566/9031 13561/13569/9034 13562/13570/9035 +f 13558/13566/9031 13562/13570/9035 13559/13567/9032 +f 13563/13571/9036 13564/13572/9037 13565/13573/9038 +f 13563/13571/9036 13565/13573/9038 13566/13574/9039 +f 13564/13572/9037 13567/13575/9040 13568/13576/9041 +f 13564/13572/9037 13568/13576/9041 13565/13573/9038 +f 13569/13577/9040 13570/13578/9042 13571/13579/9043 +f 13569/13577/9040 13571/13579/9043 13572/13580/9044 +f 13570/13578/9042 13573/13581/9045 13574/13582/9046 +f 13570/13578/9042 13574/13582/9046 13571/13579/9043 +f 13573/13581/9045 13575/13583/9047 13576/13584/9048 +f 13573/13581/9045 13576/13584/9048 13574/13582/9046 +f 13577/13585/9047 13578/13586/9049 13579/13587/9050 +f 13577/13585/9047 13579/13587/9050 13580/13588/9048 +f 13578/13586/9049 13581/13589/9051 13582/13590/9052 +f 13578/13586/9049 13582/13590/9052 13579/13587/9050 +f 13583/13591/9053 13584/13592/9054 13585/13593/9055 +f 13583/13591/9053 13585/13593/9055 13586/13594/9056 +f 13587/13595/9057 13563/13571/9036 13566/13574/9039 +f 13587/13595/9057 13566/13574/9039 13588/13596/9058 +f 13581/13589/9051 13583/13591/9053 13586/13594/9056 +f 13581/13589/9051 13586/13594/9056 13582/13590/9052 +f 13510/13523/8993 13507/13520/8990 12759/12784/8384 +f 13510/13523/8993 12759/12784/8384 12764/12789/8389 +f 13497/13510/8980 13472/13485/8955 13467/13480/8950 +f 13497/13510/8980 13467/13480/8950 13495/13508/8978 +f 13472/13485/8955 13471/13484/8954 13468/13481/8951 +f 13472/13485/8955 13468/13481/8951 13467/13480/8950 +f 13589/13597/9059 13590/13598/9060 13583/13591/9053 +f 13589/13597/9059 13583/13591/9053 13581/13589/9051 +f 13591/13599/9061 13592/13600/9062 13563/13571/9036 +f 13591/13599/9061 13563/13571/9036 13587/13595/9057 +f 13590/13598/9060 13593/13601/9063 13584/13592/9054 +f 13590/13598/9060 13584/13592/9054 13583/13591/9053 +f 13594/13602/9064 13589/13597/9059 13581/13589/9051 +f 13594/13602/9064 13581/13589/9051 13578/13586/9049 +f 13595/13603/9065 13594/13602/9064 13578/13586/9049 +f 13595/13603/9065 13578/13586/9049 13577/13585/9047 +f 13596/13604/9066 13597/13605/9067 13575/13583/9047 +f 13596/13604/9066 13575/13583/9047 13573/13581/9045 +f 13598/13606/9068 13596/13604/9066 13573/13581/9045 +f 13598/13606/9068 13573/13581/9045 13570/13578/9042 +f 13599/13607/9069 13598/13606/9068 13570/13578/9042 +f 13599/13607/9069 13570/13578/9042 13569/13577/9040 +f 13600/13608/9070 13601/13609/9069 13567/13575/9040 +f 13600/13608/9070 13567/13575/9040 13564/13572/9037 +f 13592/13600/9062 13600/13608/9070 13564/13572/9037 +f 13592/13600/9062 13564/13572/9037 13563/13571/9036 +f 13602/13610/9071 13603/13611/9072 13561/13569/9034 +f 13602/13610/9071 13561/13569/9034 13558/13566/9031 +f 13604/13612/9073 13602/13610/9071 13558/13566/9031 +f 13604/13612/9073 13558/13566/9031 13557/13565/9030 +f 13605/13613/9074 13606/13614/9075 13554/13562/9028 +f 13605/13613/9074 13554/13562/9028 13553/13561/9026 +f 13607/13615/9076 13608/13616/9077 13551/13559/9026 +f 13607/13615/9076 13551/13559/9026 13549/13557/9024 +f 13609/13617/9078 13607/13615/9076 13549/13557/9024 +f 13609/13617/9078 13549/13557/9024 13547/13555/9022 +f 13610/13618/9079 13609/13617/9078 13547/13555/9022 +f 13610/13618/9079 13547/13555/9022 13545/13553/9020 +f 13611/13619/9080 13610/13618/9079 13545/13553/9020 +f 13611/13619/9080 13545/13553/9020 13542/13550/9018 +f 13612/13620/9081 13611/13619/9080 13542/13550/9018 +f 13612/13620/9081 13542/13550/9018 13541/13549/9017 +f 13613/13621/9082 13614/13622/9081 13538/13546/9014 +f 13613/13621/9082 13538/13546/9014 13537/13545/9013 +f 13534/13542/9010 13533/13541/9009 13615/13623/9083 +f 13534/13542/9010 13615/13623/9083 13616/13624/9084 +f 13536/13544/9012 13534/13542/9010 13616/13624/9084 +f 13536/13544/9012 13616/13624/9084 13617/13625/9085 +f 13582/13590/9052 13586/13594/9056 13507/13520/8990 +f 13582/13590/9052 13507/13520/8990 13510/13523/8993 +f 12887/12911/8501 12888/12912/8502 13531/13539/9008 +f 12887/12911/8501 13531/13539/9008 13535/13543/9011 +f 12888/12912/8502 12889/12913/8503 13532/13540/9004 +f 12888/12912/8502 13532/13540/9004 13531/13539/9008 +f 13540/13548/9016 13539/13547/9015 13618/13626/9086 +f 13540/13548/9016 13618/13626/9086 13619/13627/9087 +f 13544/13552/9015 13543/13551/9019 13620/13628/9088 +f 13544/13552/9015 13620/13628/9088 13621/13629/9086 +f 13543/13551/9019 13546/13554/9021 13622/13630/9089 +f 13543/13551/9019 13622/13630/9089 13620/13628/9088 +f 13546/13554/9021 13548/13556/9023 13623/13631/9090 +f 13546/13554/9021 13623/13631/9090 13622/13630/9089 +f 13548/13556/9023 13550/13558/9025 13523/13536/9005 +f 13548/13556/9023 13523/13536/9005 13623/13631/9090 +f 13550/13558/9025 13552/13560/9027 13524/13537/9003 +f 13550/13558/9025 13524/13537/9003 13523/13536/9005 +f 13556/13564/9027 13555/13563/9029 13522/13535/9004 +f 13556/13564/9027 13522/13535/9004 13521/13534/9003 +f 13560/13568/9033 13559/13567/9032 13518/13531/9000 +f 13560/13568/9033 13518/13531/9000 13520/13533/9002 +f 13559/13567/9032 13562/13570/9035 13519/13532/9001 +f 13559/13567/9032 13519/13532/9001 13518/13531/9000 +f 13566/13574/9039 13565/13573/9038 13516/13529/8999 +f 13566/13574/9039 13516/13529/8999 13506/13519/8989 +f 13565/13573/9038 13568/13576/9041 13517/13530/8998 +f 13565/13573/9038 13517/13530/8998 13516/13529/8999 +f 13572/13580/9044 13571/13579/9043 13514/13527/8997 +f 13572/13580/9044 13514/13527/8997 13515/13528/8998 +f 13571/13579/9043 13574/13582/9046 13513/13526/8996 +f 13571/13579/9043 13513/13526/8996 13514/13527/8997 +f 13574/13582/9046 13576/13584/9048 13511/13524/8994 +f 13574/13582/9046 13511/13524/8994 13513/13526/8996 +f 13580/13588/9048 13579/13587/9050 13509/13522/8992 +f 13580/13588/9048 13509/13522/8992 13624/13632/8994 +f 13579/13587/9050 13582/13590/9052 13510/13523/8993 +f 13579/13587/9050 13510/13523/8993 13509/13522/8992 +f 13586/13594/9056 13585/13593/9055 13508/13521/8991 +f 13586/13594/9056 13508/13521/8991 13507/13520/8990 +f 13588/13596/9058 13566/13574/9039 13506/13519/8989 +f 13588/13596/9058 13506/13519/8989 13505/13518/8988 +f 13625/13633/9091 13626/13634/9092 13614/13622/9081 +f 13625/13633/9091 13614/13622/9081 13613/13621/9082 +f 13627/13635/9093 13628/13636/9094 13611/13619/9080 +f 13627/13635/9093 13611/13619/9080 13612/13620/9081 +f 13628/13636/9094 13629/13637/9095 13610/13618/9079 +f 13628/13636/9094 13610/13618/9079 13611/13619/9080 +f 13629/13637/9095 13630/13638/9096 13609/13617/9078 +f 13629/13637/9095 13609/13617/9078 13610/13618/9079 +f 13630/13638/9096 13631/13639/9097 13607/13615/9076 +f 13630/13638/9096 13607/13615/9076 13609/13617/9078 +f 13631/13639/9097 13632/13640/9098 13608/13616/9077 +f 13631/13639/9097 13608/13616/9077 13607/13615/9076 +f 13633/13641/9099 13634/13642/9100 13606/13614/9075 +f 13633/13641/9099 13606/13614/9075 13605/13613/9074 +f 13635/13643/9101 13636/13644/9102 13637/13645/9103 +f 13635/13643/9101 13637/13645/9103 13638/13646/9104 +f 13639/13647/9105 13640/13648/9106 13603/13611/9072 +f 13639/13647/9105 13603/13611/9072 13602/13610/9071 +f 13641/13649/9107 13642/13650/9108 13600/13608/9070 +f 13641/13649/9107 13600/13608/9070 13592/13600/9062 +f 13642/13650/9108 13643/13651/9109 13601/13609/9069 +f 13642/13650/9108 13601/13609/9069 13600/13608/9070 +f 13644/13652/9109 13645/13653/9110 13598/13606/9068 +f 13644/13652/9109 13598/13606/9068 13599/13607/9069 +f 13645/13653/9110 13646/13654/9111 13596/13604/9066 +f 13645/13653/9110 13596/13604/9066 13598/13606/9068 +f 13646/13654/9111 13647/13655/9112 13597/13605/9067 +f 13646/13654/9111 13597/13605/9067 13596/13604/9066 +f 13648/13656/9112 13649/13657/9113 13594/13602/9064 +f 13648/13656/9112 13594/13602/9064 13595/13603/9065 +f 13649/13657/9113 13650/13658/9114 13589/13597/9059 +f 13649/13657/9113 13589/13597/9059 13594/13602/9064 +f 13651/13659/9115 13652/13660/9116 13593/13601/9063 +f 13651/13659/9115 13593/13601/9063 13590/13598/9060 +f 13653/13661/9117 13641/13649/9107 13592/13600/9062 +f 13653/13661/9117 13592/13600/9062 13591/13599/9061 +f 13650/13658/9114 13651/13659/9115 13590/13598/9060 +f 13650/13658/9114 13590/13598/9060 13589/13597/9059 +f 13616/13624/9084 13615/13623/9083 13529/13538/9007 +f 13616/13624/9084 13529/13538/9007 13526/12709/8309 +f 13617/13625/9085 13616/13624/9084 13526/12709/8309 +f 13617/13625/9085 13526/12709/8309 13525/12706/9006 +f 13654/13662/9118 13655/13663/9119 13656/13664/9120 +f 13654/13662/9118 13656/13664/9120 13657/13665/9121 +f 13658/13666/9122 13659/13667/9123 13660/13668/9124 +f 13658/13666/9122 13660/13668/9124 13661/13669/9125 +f 13662/13670/9126 13663/13671/9127 13659/13667/9123 +f 13662/13670/9126 13659/13667/9123 13658/13666/9122 +f 13664/13672/9128 13665/13673/9129 13663/13671/9127 +f 13664/13672/9128 13663/13671/9127 13662/13670/9126 +f 13666/13674/9130 13667/13675/9131 13665/13673/9129 +f 13666/13674/9130 13665/13673/9129 13664/13672/9128 +f 13668/13676/9132 13669/13677/9133 13667/13675/9131 +f 13668/13676/9132 13667/13675/9131 13666/13674/9130 +f 13670/13678/9134 13671/13679/9135 13669/13677/9133 +f 13670/13678/9134 13669/13677/9133 13668/13676/9132 +f 13672/13680/9136 13673/13681/9137 13671/13679/9135 +f 13672/13680/9136 13671/13679/9135 13670/13678/9134 +f 13674/13682/9138 13675/13683/9139 13673/13681/9137 +f 13674/13682/9138 13673/13681/9137 13672/13680/9136 +f 13676/13684/9140 13677/13685/9141 13678/13686/9142 +f 13676/13684/9140 13678/13686/9142 13679/13687/9143 +f 13680/13688/9144 13681/13689/9145 13682/13690/9146 +f 13680/13688/9144 13682/13690/9146 13683/13691/9147 +f 13684/13692/9148 13685/13693/9149 13681/13689/9145 +f 13684/13692/9148 13681/13689/9145 13680/13688/9144 +f 13686/13694/9118 13687/13695/9150 13685/13693/9149 +f 13686/13694/9118 13685/13693/9149 13684/13692/9148 +f 13688/13696/9121 13689/13697/9151 13687/13695/9150 +f 13688/13696/9121 13687/13695/9150 13686/13694/9118 +f 13690/13698/9152 13691/13699/9153 13689/13697/9151 +f 13690/13698/9152 13689/13697/9151 13688/13696/9121 +f 13692/13700/9154 13693/13701/9155 13691/13699/9153 +f 13692/13700/9154 13691/13699/9153 13690/13698/9152 +f 13661/13669/9125 13660/13668/9124 13693/13701/9155 +f 13661/13669/9125 13693/13701/9155 13692/13700/9154 +f 13460/13473/8943 13694/13702/9156 13695/13703/9157 +f 13460/13473/8943 13695/13703/9157 13458/13471/8941 +f 13696/13704/9158 13697/13705/9159 13698/13706/9160 +f 13696/13704/9158 13698/13706/9160 13699/13707/9134 +f 13657/13665/9121 13656/13664/9120 13700/13708/9161 +f 13657/13665/9121 13700/13708/9161 13701/13709/9162 +f 13699/13707/9134 13698/13706/9160 13702/13710/9163 +f 13699/13707/9134 13702/13710/9163 13703/13711/9164 +f 13704/13712/9162 13705/13713/9161 13706/13714/9165 +f 13704/13712/9162 13706/13714/9165 13707/13715/9154 +f 13708/13716/9138 13709/13717/9166 13710/13718/9167 +f 13708/13716/9138 13710/13718/9167 13711/13719/9168 +f 13712/13720/9125 13713/13721/9169 13714/13722/9170 +f 13712/13720/9125 13714/13722/9170 13715/13723/9122 +f 13707/13715/9154 13706/13714/9165 13713/13721/9169 +f 13707/13715/9154 13713/13721/9169 13712/13720/9125 +f 13716/13724/9140 13717/13725/9171 13718/13726/9172 +f 13716/13724/9140 13718/13726/9172 13719/13727/9173 +f 13715/13723/9122 13714/13722/9170 13720/13728/9174 +f 13715/13723/9122 13720/13728/9174 13721/13729/9126 +f 13722/13730/9147 13723/13731/9172 13724/13732/9175 +f 13722/13730/9147 13724/13732/9175 13725/13733/9144 +f 13726/13734/9176 13727/13735/9174 13728/13736/9177 +f 13726/13734/9176 13728/13736/9177 13729/13737/9178 +f 13725/13733/9144 13724/13732/9175 13730/13738/9179 +f 13725/13733/9144 13730/13738/9179 13731/13739/9180 +f 13729/13737/9178 13728/13736/9177 13732/13740/9181 +f 13729/13737/9178 13732/13740/9181 13733/13741/9182 +f 13731/13739/9180 13730/13738/9179 13655/13663/9119 +f 13731/13739/9180 13655/13663/9119 13654/13662/9118 +f 13733/13741/9182 13732/13740/9181 13734/13742/9183 +f 13733/13741/9182 13734/13742/9183 13735/13743/9132 +f 13480/13493/8963 13736/13744/9184 13737/13745/9185 +f 13480/13493/8963 13737/13745/9185 13478/13491/8961 +f 13462/13475/8945 13738/13746/9186 13694/13702/9156 +f 13462/13475/8945 13694/13702/9156 13460/13473/8943 +f 13482/13495/8965 13739/13747/9187 13736/13744/9184 +f 13482/13495/8965 13736/13744/9184 13480/13493/8963 +f 13464/13477/8947 13740/13748/9188 13738/13746/9186 +f 13464/13477/8947 13738/13746/9186 13462/13475/8945 +f 13484/13497/8967 13741/13749/9189 13739/13747/9187 +f 13484/13497/8967 13739/13747/9187 13482/13495/8965 +f 13466/13479/8949 13742/13750/9190 13740/13748/9188 +f 13466/13479/8949 13740/13748/9188 13464/13477/8947 +f 13486/13499/8969 13743/13751/9191 13741/13749/9189 +f 13486/13499/8969 13741/13749/9189 13484/13497/8967 +f 13468/13481/8951 13744/13752/9192 13742/13750/9190 +f 13468/13481/8951 13742/13750/9190 13466/13479/8949 +f 13745/13753/9193 13746/13754/9194 13747/13755/9195 +f 13745/13753/9193 13747/13755/9195 13748/13756/9196 +f 13470/13483/8953 13749/13757/9197 13750/13758/9198 +f 13470/13483/8953 13750/13758/9198 13471/13484/8954 +f 13453/13466/8936 13751/13759/9199 13743/13751/9191 +f 13453/13466/8936 13743/13751/9191 13486/13499/8969 +f 13713/13721/9169 13752/13760/9200 13753/13761/9201 +f 13713/13721/9169 13753/13761/9201 13714/13722/9170 +f 13474/13487/8957 13754/13762/9202 13755/13763/9203 +f 13474/13487/8957 13755/13763/9203 13475/13488/8958 +f 13458/13471/8941 13695/13703/9157 13756/13764/9204 +f 13458/13471/8941 13756/13764/9204 13456/13469/8939 +f 13478/13491/8961 13737/13745/9185 13754/13762/9202 +f 13478/13491/8961 13754/13762/9202 13474/13487/8957 +f 13706/13714/9165 13757/13765/9205 13752/13760/9200 +f 13706/13714/9165 13752/13760/9200 13713/13721/9169 +f 13714/13722/9170 13753/13761/9201 13758/13766/9206 +f 13714/13722/9170 13758/13766/9206 13720/13728/9174 +f 13727/13735/9174 13759/13767/9207 13760/13768/9208 +f 13727/13735/9174 13760/13768/9208 13728/13736/9177 +f 13728/13736/9177 13760/13768/9208 13761/13769/9209 +f 13728/13736/9177 13761/13769/9209 13732/13740/9181 +f 13732/13740/9181 13761/13769/9209 13762/13770/9210 +f 13732/13740/9181 13762/13770/9210 13734/13742/9183 +f 13734/13742/9183 13762/13770/9210 13763/13771/9211 +f 13734/13742/9183 13763/13771/9211 13764/13772/9160 +f 13698/13706/9160 13765/13773/9211 13766/13774/9212 +f 13698/13706/9160 13766/13774/9212 13702/13710/9163 +f 13709/13717/9166 13767/13775/9213 13768/12711/9214 +f 13709/13717/9166 13768/12711/9214 13710/13718/9167 +f 13717/13725/9171 13769/13776/9215 13770/13777/9216 +f 13717/13725/9171 13770/13777/9216 13718/13726/9172 +f 13723/13731/9172 13771/13778/9216 13772/13779/9217 +f 13723/13731/9172 13772/13779/9217 13724/13732/9175 +f 13724/13732/9175 13772/13779/9217 13773/13780/9218 +f 13724/13732/9175 13773/13780/9218 13730/13738/9179 +f 13730/13738/9179 13773/13780/9218 13774/13781/9219 +f 13730/13738/9179 13774/13781/9219 13655/13663/9119 +f 13655/13663/9119 13774/13781/9219 13775/13782/9220 +f 13655/13663/9119 13775/13782/9220 13656/13664/9120 +f 13656/13664/9120 13775/13782/9220 13776/13783/9221 +f 13656/13664/9120 13776/13783/9221 13700/13708/9161 +f 13705/13713/9161 13777/13784/9221 13757/13765/9205 +f 13705/13713/9161 13757/13765/9205 13706/13714/9165 +f 13456/13469/8939 13756/13764/9204 13778/13785/9222 +f 13456/13469/8939 13778/13785/9222 13452/13465/8935 +f 13740/13748/9188 13779/13786/9223 13780/13787/9224 +f 13740/13748/9188 13780/13787/9224 13738/13746/9186 +f 13773/13780/9218 13781/13788/8643 13782/13789/8642 +f 13773/13780/9218 13782/13789/8642 13774/13781/9219 +f 13759/13767/9207 13783/13790/8645 13784/13791/9225 +f 13759/13767/9207 13784/13791/9225 13760/13768/9208 +f 13754/13762/9202 13785/13792/9226 13786/13793/9227 +f 13754/13762/9202 13786/13793/9227 13755/13763/9203 +f 13778/13785/9222 13787/13794/9195 13788/13795/9194 +f 13778/13785/9222 13788/13795/9194 13751/13759/9199 +f 13789/13796/9228 13790/13797/8651 13791/13798/8650 +f 13789/13796/9228 13791/13798/8650 13792/13799/9229 +f 13757/13765/9205 13793/13800/8653 13794/13801/8652 +f 13757/13765/9205 13794/13801/8652 13752/13760/9200 +f 13741/13749/9189 13795/13802/9230 13796/13803/9231 +f 13741/13749/9189 13796/13803/9231 13739/13747/9187 +f 13738/13746/9186 13780/13787/9224 13797/13804/9232 +f 13738/13746/9186 13797/13804/9232 13694/13702/9156 +f 13798/13805/9233 13799/13806/8658 13790/13797/8651 +f 13798/13805/9233 13790/13797/8651 13789/13796/9228 +f 13765/13773/9211 13800/13807/8660 13801/13808/8659 +f 13765/13773/9211 13801/13808/8659 13766/13774/9212 +f 13749/13757/9197 13802/13809/9234 13803/13810/9235 +f 13749/13757/9197 13803/13810/9235 13750/13758/9198 +f 13804/13811/9236 13805/13812/9237 13806/13813/8665 +f 13804/13811/9236 13806/13813/8665 13807/13814/9238 +f 13772/13779/9217 13808/13815/8667 13781/13788/8643 +f 13772/13779/9217 13781/13788/8643 13773/13780/9218 +f 13739/13747/9187 13796/13803/9231 13809/13816/9239 +f 13739/13747/9187 13809/13816/9239 13736/13744/9184 +f 13694/13702/9156 13797/13804/9232 13810/13817/9240 +f 13694/13702/9156 13810/13817/9240 13695/13703/9157 +f 13452/13465/8935 13778/13785/9222 13751/13759/9199 +f 13452/13465/8935 13751/13759/9199 13453/13466/8936 +f 13748/13756/9196 13747/13755/9195 13811/13818/9241 +f 13748/13756/9196 13811/13818/9241 13812/13819/9242 +f 13813/13820/9243 13814/13821/9244 13815/13822/9240 +f 13813/13820/9243 13815/13822/9240 13816/13823/9245 +f 13816/13823/9245 13815/13822/9240 13817/13824/9232 +f 13816/13823/9245 13817/13824/9232 13818/13825/9246 +f 13818/13825/9246 13817/13824/9232 13819/13826/9224 +f 13818/13825/9246 13819/13826/9224 13820/13827/9247 +f 13821/13828/9229 13822/13829/9224 13823/13830/9223 +f 13821/13828/9229 13823/13830/9223 13824/13831/9228 +f 13824/13831/9228 13823/13830/9223 13825/13832/9248 +f 13824/13831/9228 13825/13832/9248 13826/13833/9249 +f 13827/13834/9238 13828/13835/9250 13829/13836/9251 +f 13827/13834/9238 13829/13836/9251 13830/13837/9252 +f 13831/13838/9253 13832/13839/9234 13833/13840/9254 +f 13831/13838/9253 13833/13840/9254 13834/13841/9255 +f 13835/13842/9255 13836/13843/9227 13837/13844/9226 +f 13835/13842/9255 13837/13844/9226 13838/13845/9256 +f 13838/13845/9256 13837/13844/9226 13839/13846/9257 +f 13838/13845/9256 13839/13846/9257 13840/13847/9258 +f 13840/13847/9258 13839/13846/9257 13841/13848/9259 +f 13840/13847/9258 13841/13848/9259 13842/13849/9260 +f 13842/13849/9260 13841/13848/9259 13843/13850/9231 +f 13842/13849/9260 13843/13850/9231 13844/13851/9261 +f 13844/13851/9261 13843/13850/9231 13845/13852/9262 +f 13844/13851/9261 13845/13852/9262 13846/13853/9263 +f 13847/13854/9264 13848/13855/9262 13849/13856/9265 +f 13847/13854/9264 13849/13856/9265 13850/13857/9266 +f 13850/13857/9266 13849/13856/9265 13746/13754/9194 +f 13850/13857/9266 13746/13754/9194 13745/13753/9193 +f 13743/13751/9191 13851/13858/9267 13795/13802/9230 +f 13743/13751/9191 13795/13802/9230 13741/13749/9189 +f 13753/13761/9201 13852/13859/8698 13853/13860/8645 +f 13753/13761/9201 13853/13860/8645 13758/13766/9206 +f 13854/13861/9268 13855/12717/9269 13805/13812/9237 +f 13854/13861/9268 13805/13812/9237 13804/13811/9236 +f 13756/13764/9204 13856/13862/9244 13787/13794/9195 +f 13756/13764/9204 13787/13794/9195 13778/13785/9222 +f 13737/13745/9185 13857/13863/9257 13785/13792/9226 +f 13737/13745/9185 13785/13792/9226 13754/13762/9202 +f 13751/13759/9199 13788/13795/9194 13851/13858/9267 +f 13751/13759/9199 13851/13858/9267 13743/13751/9191 +f 13777/13784/9221 13858/13864/8699 13793/13800/8653 +f 13777/13784/9221 13793/13800/8653 13757/13765/9205 +f 13859/13865/9270 13860/13866/8701 13861/13867/8316 +f 13859/13865/9270 13861/13867/8316 13862/13868/8318 +f 13742/13750/9190 13863/13869/9271 13779/13786/9223 +f 13742/13750/9190 13779/13786/9223 13740/13748/9188 +f 13864/13870/9210 13865/13871/8703 13800/13807/8660 +f 13864/13870/9210 13800/13807/8660 13765/13773/9211 +f 13695/13703/9157 13810/13817/9240 13856/13862/9244 +f 13695/13703/9157 13856/13862/9244 13756/13764/9204 +f 13736/13744/9184 13809/13816/9239 13857/13863/9257 +f 13736/13744/9184 13857/13863/9257 13737/13745/9185 +f 13866/13872/9258 13867/13873/8704 13860/13866/8701 +f 13866/13872/9258 13860/13866/8701 13859/13865/9270 +f 13771/13778/9216 13868/13874/8705 13808/13815/8667 +f 13771/13778/9216 13808/13815/8667 13772/13779/9217 +f 13744/13752/9192 13869/13875/9250 13863/13869/9271 +f 13744/13752/9192 13863/13869/9271 13742/13750/9190 +f 13766/13774/9212 13801/13808/8659 13870/13876/8707 +f 13766/13774/9212 13870/13876/8707 13767/13775/9213 +f 13871/13877/9272 13872/13878/9273 13873/13879/9274 +f 13871/13877/9272 13873/13879/9274 13874/13880/9275 +f 13875/13881/9276 13876/13882/9277 13635/13643/9101 +f 13875/13881/9276 13635/13643/9101 13638/13646/9104 +f 13877/13883/9278 13878/13884/9279 13879/13885/9280 +f 13877/13883/9278 13879/13885/9280 13880/13886/9281 +f 13881/13887/9124 13882/13888/9123 13883/13889/9282 +f 13881/13887/9124 13883/13889/9282 13884/13890/8718 +f 13882/13888/9123 13885/13891/9127 13886/13892/9283 +f 13882/13888/9123 13886/13892/9283 13883/13889/9282 +f 13887/13893/9127 13888/13894/9129 13889/13895/9284 +f 13887/13893/9127 13889/13895/9284 13890/13896/9283 +f 13888/13894/9129 13891/13897/9131 13892/13898/9285 +f 13888/13894/9129 13892/13898/9285 13889/13895/9284 +f 13891/13897/9131 13893/13899/9133 13894/13900/9286 +f 13891/13897/9131 13894/13900/9286 13892/13898/9285 +f 13895/13901/9287 13896/13902/9288 13897/13903/9289 +f 13895/13901/9287 13897/13903/9289 13898/13904/9290 +f 13896/13902/9288 13899/13905/9291 13900/13906/9292 +f 13896/13902/9288 13900/13906/9292 13897/13903/9289 +f 13901/13907/9293 13902/13908/9142 13903/13909/9294 +f 13901/13907/9293 13903/13909/9294 13904/13910/9295 +f 13905/13911/9296 13906/13912/9297 13907/13913/9298 +f 13905/13911/9296 13907/13913/9298 13908/13914/9299 +f 13909/13915/9297 13910/13916/9300 13911/13917/9301 +f 13909/13915/9297 13911/13917/9301 13912/13918/9302 +f 13910/13916/9300 13913/13919/9303 13914/13920/9304 +f 13910/13916/9300 13914/13920/9304 13911/13917/9301 +f 13913/13919/9303 13915/13921/9305 13916/13922/9306 +f 13913/13919/9303 13916/13922/9306 13914/13920/9304 +f 13915/13921/9305 13917/13923/9307 13918/13924/9308 +f 13915/13921/9305 13918/13924/9308 13916/13922/9306 +f 13917/13923/9307 13919/13925/9153 13920/13926/9309 +f 13917/13923/9307 13920/13926/9309 13918/13924/9308 +f 13921/13927/9310 13922/13928/9155 13923/13929/9311 +f 13921/13927/9310 13923/13929/9311 13924/13930/9309 +f 13922/13928/9155 13881/13887/9124 13884/13890/8718 +f 13922/13928/9155 13884/13890/8718 13923/13929/9311 +f 13925/13931/9312 13926/13932/9313 13927/13933/9314 +f 13925/13931/9312 13927/13933/9314 13928/13934/9315 +f 13527/12707/8307 13530/12710/8310 13929/13935/9316 +f 13527/12707/8307 13929/13935/9316 13930/13936/9317 +f 13931/13937/9318 13932/13938/9319 13933/13939/9320 +f 13931/13937/9318 13933/13939/9320 13934/13940/9321 +f 13935/13941/9322 13936/13942/9323 13872/13878/9273 +f 13935/13941/9322 13872/13878/9273 13871/13877/9272 +f 13937/13943/9324 13938/13944/9325 13936/13942/9323 +f 13937/13943/9324 13936/13942/9323 13935/13941/9322 +f 13528/12708/9326 13527/12707/8307 13930/13936/9317 +f 13528/12708/9326 13930/13936/9317 13939/13945/9327 +f 13940/13946/9328 13934/13940/9321 13938/13944/9325 +f 13940/13946/9328 13938/13944/9325 13937/13943/9324 +f 13941/13947/9329 13931/13937/9318 13934/13940/9321 +f 13941/13947/9329 13934/13940/9321 13940/13946/9328 +f 13873/13879/9274 13942/13948/9330 13943/13949/9331 +f 13873/13879/9274 13943/13949/9331 13944/13950/9281 +f 13872/13878/9273 13945/13951/9332 13942/13948/9330 +f 13872/13878/9273 13942/13948/9330 13873/13879/9274 +f 13936/13942/9323 13946/13952/9333 13945/13951/9332 +f 13936/13942/9323 13945/13951/9332 13872/13878/9273 +f 13938/13944/9325 13947/13953/9334 13946/13952/9333 +f 13938/13944/9325 13946/13952/9333 13936/13942/9323 +f 13934/13940/9321 13933/13939/9320 13947/13953/9334 +f 13934/13940/9321 13947/13953/9334 13938/13944/9325 +f 13948/13954/9335 13949/13955/9331 13626/13634/9092 +f 13948/13954/9335 13626/13634/9092 13625/13633/9091 +f 13950/13956/9331 13951/13957/9336 13628/13636/9094 +f 13950/13956/9331 13628/13636/9094 13627/13635/9093 +f 13951/13957/9336 13952/13958/9337 13629/13637/9095 +f 13951/13957/9336 13629/13637/9095 13628/13636/9094 +f 13952/13958/9337 13953/13959/9338 13630/13638/9096 +f 13952/13958/9337 13630/13638/9096 13629/13637/9095 +f 13953/13959/9338 13954/13960/9339 13631/13639/9097 +f 13953/13959/9338 13631/13639/9097 13630/13638/9096 +f 13954/13960/9339 13955/13961/9320 13632/13640/9098 +f 13954/13960/9339 13632/13640/9098 13631/13639/9097 +f 13956/13962/9340 13957/13963/9341 13634/13642/9100 +f 13956/13962/9340 13634/13642/9100 13633/13641/9099 +f 13958/13964/9342 13959/13965/9343 13960/13966/9344 +f 13958/13964/9342 13960/13966/9344 13961/13967/9345 +f 13928/13934/9315 13927/13933/9314 13962/13968/9346 +f 13928/13934/9315 13962/13968/9346 13963/13969/9347 +f 13884/13890/8718 13883/13889/9282 13642/13650/9108 +f 13884/13890/8718 13642/13650/9108 13641/13649/9107 +f 13883/13889/9282 13886/13892/9283 13643/13651/9109 +f 13883/13889/9282 13643/13651/9109 13642/13650/9108 +f 13890/13896/9283 13889/13895/9284 13645/13653/9110 +f 13890/13896/9283 13645/13653/9110 13644/13652/9109 +f 13889/13895/9284 13892/13898/9285 13646/13654/9111 +f 13889/13895/9284 13646/13654/9111 13645/13653/9110 +f 13892/13898/9285 13894/13900/9286 13647/13655/9112 +f 13892/13898/9285 13647/13655/9112 13646/13654/9111 +f 13898/13904/9290 13897/13903/9289 13649/13657/9113 +f 13898/13904/9290 13649/13657/9113 13648/13656/9112 +f 13897/13903/9289 13900/13906/9292 13650/13658/9114 +f 13897/13903/9289 13650/13658/9114 13649/13657/9113 +f 13904/13910/9295 13903/13909/9294 13652/13660/9116 +f 13904/13910/9295 13652/13660/9116 13651/13659/9115 +f 13923/13929/9311 13884/13890/8718 13641/13649/9107 +f 13923/13929/9311 13641/13649/9107 13653/13661/9117 +f 13900/13906/9292 13904/13910/9295 13651/13659/9115 +f 13900/13906/9292 13651/13659/9115 13650/13658/9114 +f 13899/13905/9291 13901/13907/9293 13904/13910/9295 +f 13899/13905/9291 13904/13910/9295 13900/13906/9292 +f 13750/13758/9198 13803/13810/9235 13869/13875/9250 +f 13750/13758/9198 13869/13875/9250 13744/13752/9192 +f 13752/13760/9200 13794/13801/8652 13852/13859/8698 +f 13752/13760/9200 13852/13859/8698 13753/13761/9201 +f 13826/13833/9249 13825/13832/9248 13828/13835/9250 +f 13826/13833/9249 13828/13835/9250 13827/13834/9238 +f 13702/13710/9163 13766/13774/9212 13767/13775/9213 +f 13702/13710/9163 13767/13775/9213 13709/13717/9166 +f 13471/13484/8954 13750/13758/9198 13744/13752/9192 +f 13471/13484/8954 13744/13752/9192 13468/13481/8951 +f 13703/13711/9164 13702/13710/9163 13709/13717/9166 +f 13703/13711/9164 13709/13717/9166 13708/13716/9138 +f 13679/13687/9143 13678/13686/9142 13675/13683/9139 +f 13679/13687/9143 13675/13683/9139 13674/13682/9138 +f 13236/13254/8779 13239/13257/8781 13964/13970/9348 +f 13236/13254/8779 13964/13970/9348 13237/13255/8791 +f 13965/13971/9349 13523/13536/9005 12791/12816/8413 +f 13965/13971/9349 12791/12816/8413 13241/13259/8783 +f 13966/13972/9350 13619/13627/9087 13618/13626/9086 +f 13966/13972/9350 13618/13626/9086 13967/13973/9351 +f 13968/13974/9351 13621/13629/9086 13620/13628/9088 +f 13968/13974/9351 13620/13628/9088 13969/13975/9352 +f 13969/13975/9352 13620/13628/9088 13622/13630/9089 +f 13969/13975/9352 13622/13630/9089 13970/13976/9353 +f 13970/13976/9353 13622/13630/9089 13623/13631/9090 +f 13970/13976/9353 13623/13631/9090 13971/13977/9354 +f 13971/13977/9354 13623/13631/9090 13523/13536/9005 +f 13971/13977/9354 13523/13536/9005 13965/13971/9349 +f 13965/13971/9349 13972/13978/9355 13973/13979/9356 +f 13965/13971/9349 13973/13979/9356 13971/13977/9354 +f 13974/13980/9357 13975/13981/8323 13976/13982/9358 +f 13974/13980/9357 13976/13982/9358 13977/13983/9359 +f 13971/13977/9354 13973/13979/9356 13978/13984/9360 +f 13971/13977/9354 13978/13984/9360 13970/13976/9353 +f 13241/13259/8783 13255/13273/8794 13972/13978/9355 +f 13241/13259/8783 13972/13978/9355 13965/13971/9349 +f 13970/13976/9353 13978/13984/9360 13979/13985/9361 +f 13970/13976/9353 13979/13985/9361 13969/13975/9352 +f 13980/13986/9362 13981/13987/9363 13259/13277/8798 +f 13980/13986/9362 13259/13277/8798 13258/13276/8797 +f 13982/13988/9364 13980/13986/9362 13258/13276/8797 +f 13982/13988/9364 13258/13276/8797 13262/13280/8801 +f 13983/13989/9365 13982/13988/9364 13262/13280/8801 +f 13983/13989/9365 13262/13280/8801 13264/13282/8803 +f 13984/13990/9366 13983/13989/9365 13264/13282/8803 +f 13984/13990/9366 13264/13282/8803 13266/13284/8805 +f 12699/12724/8324 13985/13991/9366 13268/13286/8805 +f 12699/12724/8324 13268/13286/8805 13267/13285/8806 +f 13969/13975/9352 13979/13985/9361 13986/13992/9367 +f 13969/13975/9352 13986/13992/9367 13968/13974/9351 +f 13237/13255/8780 12697/12722/8322 13271/13289/8809 +f 13237/13255/8780 13271/13289/9368 13236/13254/9369 +f 13981/13987/9363 13972/13978/9355 13255/13273/8794 +f 13981/13987/9363 13255/13273/8794 13259/13277/8798 +f 12699/12724/8324 12698/12723/8323 13987/13993/9370 +f 12699/12724/8324 13987/13993/9370 13985/13991/9366 +f 13984/13990/9366 13986/13992/9367 13979/13985/9361 +f 13984/13990/9366 13979/13985/9361 13983/13989/9365 +f 13983/13989/9365 13979/13985/9361 13978/13984/9360 +f 13983/13989/9365 13978/13984/9360 13982/13988/9364 +f 13982/13988/9364 13978/13984/9360 13973/13979/9356 +f 13982/13988/9364 13973/13979/9356 13980/13986/9362 +f 13980/13986/9362 13973/13979/9356 13972/13978/9355 +f 13980/13986/9362 13972/13978/9355 13981/13987/9363 +f 13806/13813/8665 13988/13994/9371 13989/13995/9372 +f 13806/13813/8665 13989/13995/9372 13799/13806/8658 +f 13784/13791/9225 13990/13996/9373 13991/13997/9374 +f 13784/13791/9225 13991/13997/9374 13992/13998/8812 +f 13805/13812/9237 13993/13999/9375 13988/13994/9371 +f 13805/13812/9237 13988/13994/9371 13806/13813/8665 +f 13808/13815/8667 13994/14000/9376 13995/14001/9377 +f 13808/13815/8667 13995/14001/9377 13781/13788/8643 +f 13855/12717/9269 13996/12716/8317 13993/13999/9375 +f 13855/12717/9269 13993/13999/9375 13805/13812/9237 +f 13783/13790/8645 13997/14002/9378 13990/13996/9373 +f 13783/13790/8645 13990/13996/9373 13784/13791/9225 +f 13860/13866/8701 13998/14003/9379 13999/14004/9380 +f 13860/13866/8701 13999/14004/9380 13861/13867/8316 +f 13868/13874/8705 14000/14005/9381 13994/14000/9376 +f 13868/13874/8705 13994/14000/9376 13808/13815/8667 +f 13867/13873/8704 14001/14006/9382 13998/14003/9379 +f 13867/13873/8704 13998/14003/9379 13860/13866/8701 +f 13852/13859/8698 14002/14007/9383 14003/14008/9378 +f 13852/13859/8698 14003/14008/9378 13853/13860/8645 +f 14004/14009/8825 14005/14010/9384 14001/14006/9382 +f 14004/14009/8825 14001/14006/9382 13867/13873/8704 +f 13794/13801/8652 14006/14011/9385 14002/14007/9383 +f 13794/13801/8652 14002/14007/9383 13852/13859/8698 +f 14007/12713/8294 14008/12714/8315 14009/14012/9381 +f 14007/12713/8294 14009/14012/9381 14010/14013/8828 +f 14011/14014/8830 14012/14015/9386 14005/14010/9384 +f 14011/14014/8830 14005/14010/9384 14004/14009/8825 +f 14013/14016/8832 14014/14017/9387 14015/14018/9388 +f 14013/14016/8832 14015/14018/9388 14016/14019/8833 +f 14017/14020/8836 14018/14021/9389 14012/14015/9386 +f 14017/14020/8836 14012/14015/9386 14011/14014/8830 +f 14016/14019/8833 14015/14018/9388 14019/14022/9390 +f 14016/14019/8833 14019/14022/9390 14020/14023/8838 +f 14021/14024/9247 14022/14025/8842 14023/14026/8841 +f 14021/14024/9247 14023/14026/8841 14024/14027/9391 +f 14024/14027/9391 14023/14026/8841 14025/14028/8843 +f 14024/14027/9391 14025/14028/8843 14026/14029/9245 +f 13767/13775/9213 13870/13876/8707 14027/12712/8314 +f 13767/13775/9213 14027/12712/8314 13768/12711/9214 +f 14026/14029/9245 14025/14028/8843 14028/14030/8844 +f 14026/14029/9245 14028/14030/8844 14029/14031/9392 +f 13760/13768/9208 13784/13791/9225 13992/13998/8812 +f 13760/13768/9208 13992/13998/8812 13761/13769/9209 +f 13774/13781/9219 13782/13789/8642 14030/14032/8845 +f 13774/13781/9219 14030/14032/8845 13775/13782/9220 +f 14031/14033/9393 14013/14016/8832 14016/14019/8833 +f 14031/14033/9393 14016/14019/8833 14032/14034/9193 +f 14033/14035/9243 14034/14036/8848 14013/14016/8832 +f 14033/14035/9243 14013/14016/8832 14031/14033/9393 +f 14035/14037/9394 14020/14023/8838 14036/14038/8836 +f 14035/14037/9394 14036/14038/8836 14037/14039/9264 +f 13807/13814/9238 13806/13813/8665 13799/13806/8658 +f 13807/13814/9238 13799/13806/8658 13798/13805/9233 +f 13769/13776/9215 14007/12713/8294 14010/14013/8828 +f 13769/13776/9215 14010/14013/8828 13770/13777/9216 +f 14032/14034/9193 14016/14019/8833 14020/14023/8838 +f 14032/14034/9193 14020/14023/8838 14035/14037/9394 +f 14038/14040/9395 14017/14020/8836 14011/14014/8830 +f 14038/14040/9395 14011/14014/8830 14039/14041/9261 +f 13761/13769/9209 13992/13998/8812 14040/14042/8851 +f 13761/13769/9209 14040/14042/8851 13762/13770/9210 +f 14039/14041/9261 14011/14014/8830 14004/14009/8825 +f 14039/14041/9261 14004/14009/8825 14041/14043/9396 +f 13775/13782/9220 14030/14032/8845 14042/14044/8852 +f 13775/13782/9220 14042/14044/8852 13776/13783/9221 +f 14041/14043/9396 14004/14009/8825 13867/13873/8704 +f 14041/14043/9396 13867/13873/8704 13866/13872/9258 +f 13994/14000/9376 14043/14045/9397 14044/14046/9398 +f 13994/14000/9376 14044/14046/9398 13995/14001/9377 +f 14002/14007/9383 14045/14047/9387 14046/14048/9399 +f 14002/14007/9383 14046/14048/9399 14003/14008/9378 +f 14047/14049/9400 14048/14050/9401 14049/14051/9390 +f 14047/14049/9400 14049/14051/9390 14050/14052/9402 +f 14051/14053/9403 14052/14054/9404 14053/14055/9405 +f 14051/14053/9403 14053/14055/9405 14054/14056/9406 +f 14000/14005/9381 14055/14057/9407 14043/14045/9397 +f 14000/14005/9381 14043/14045/9397 13994/14000/9376 +f 14006/14011/9385 14056/14058/9388 14045/14047/9387 +f 14006/14011/9385 14045/14047/9387 14002/14007/9383 +f 14057/14059/9408 14058/14060/9409 14059/14061/9401 +f 14057/14059/9408 14059/14061/9401 14060/14062/9400 +f 13991/13997/9374 14061/14063/9410 14062/14064/9404 +f 13991/13997/9374 14062/14064/9404 14063/14065/9403 +f 14054/14056/9406 14053/14055/9405 14064/14066/9372 +f 14054/14056/9406 14064/14066/9372 14065/14067/9411 +f 14050/14052/9402 14049/14051/9390 14056/14058/9388 +f 14050/14052/9402 14056/14058/9388 14006/14011/9385 +f 13997/14002/9378 14066/14068/9412 14067/14069/9413 +f 13997/14002/9378 14067/14069/9413 13990/13996/9373 +f 13995/14001/9377 14044/14046/9398 14068/14070/9384 +f 13995/14001/9377 14068/14070/9384 14069/14071/9414 +f 14070/14072/9415 14071/14073/9371 14072/14074/9375 +f 14070/14072/9415 14072/14074/9375 14073/14075/9416 +f 13990/13996/9373 14067/14069/9413 14061/14063/9410 +f 13990/13996/9373 14061/14063/9410 13991/13997/9374 +f 14069/14071/9414 14068/14070/9384 14058/14060/9409 +f 14069/14071/9414 14058/14060/9409 14057/14059/9408 +f 14008/12714/8315 14074/14076/8317 14075/14077/9380 +f 14008/12714/8315 14075/14077/9380 14009/14012/9381 +f 14065/14067/9411 14064/14066/9372 14071/14073/9371 +f 14065/14067/9411 14071/14073/9371 14070/14072/9415 +f 13799/13806/8658 13989/13995/9372 14076/14078/9417 +f 13799/13806/8658 14076/14078/9417 13790/13797/8651 +f 13781/13788/8643 13995/14001/9377 14069/14071/9414 +f 13781/13788/8643 14069/14071/9414 13782/13789/8642 +f 13801/13808/8659 14065/14067/9411 14070/14072/9415 +f 13801/13808/8659 14070/14072/9415 13870/13876/8707 +f 13790/13797/8651 14076/14078/9417 14077/14079/9418 +f 13790/13797/8651 14077/14079/9418 13791/13798/8650 +f 13782/13789/8642 14069/14071/9414 14057/14059/9408 +f 13782/13789/8642 14057/14059/9408 14030/14032/8845 +f 13992/13998/8812 13991/13997/9374 14063/14065/9403 +f 13992/13998/8812 14063/14065/9403 14040/14042/8851 +f 14022/14025/8842 14078/14080/9418 14079/14081/9410 +f 14022/14025/8842 14079/14081/9410 14023/14026/8841 +f 14030/14032/8845 14057/14059/9408 14060/14062/9400 +f 14030/14032/8845 14060/14062/9400 14042/14044/8852 +f 14023/14026/8841 14079/14081/9410 14080/14082/9419 +f 14023/14026/8841 14080/14082/9419 14025/14028/8843 +f 13858/13864/8699 14047/14049/9400 14050/14052/9402 +f 13858/13864/8699 14050/14052/9402 13793/13800/8653 +f 13865/13871/8703 14051/14053/9403 14054/14056/9406 +f 13865/13871/8703 14054/14056/9406 13800/13807/8660 +f 14025/14028/8843 14080/14082/9419 14081/14083/9412 +f 14025/14028/8843 14081/14083/9412 14028/14030/8844 +f 13793/13800/8653 14050/14052/9402 14006/14011/9385 +f 13793/13800/8653 14006/14011/9385 13794/13801/8652 +f 13800/13807/8660 14054/14056/9406 14065/14067/9411 +f 13800/13807/8660 14065/14067/9411 13801/13808/8659 +f 14034/14036/8848 14082/14084/9399 14014/14017/9387 +f 14034/14036/8848 14014/14017/9387 14013/14016/8832 +f 14020/14023/8838 14019/14022/9390 14083/14085/9401 +f 14020/14023/8838 14083/14085/9401 14036/14038/8836 +f 13870/13876/8707 14070/14072/9415 14073/14075/9416 +f 13870/13876/8707 14073/14075/9416 14027/12712/8314 +f 13903/13909/9294 13958/13964/9342 13961/13967/9345 +f 13903/13909/9294 13961/13967/9345 13652/13660/9116 +f 14084/14086/9311 13941/13947/9329 13940/13946/9328 +f 14084/14086/9311 13940/13946/9328 14085/14087/9309 +f 14086/14088/9420 14087/14089/9421 14088/14090/9422 +f 14086/14088/9420 14088/14090/9422 14089/14091/9423 +f 14090/14092/9424 13528/12708/9326 13939/13945/9327 +f 14090/14092/9424 13939/13945/9327 14091/14093/9311 +f 14092/14094/9425 14093/14095/9426 14094/14096/9427 +f 14092/14094/9425 14094/14096/9427 14095/14097/9428 +f 13918/13924/9308 14096/14098/9429 14097/14099/9430 +f 13918/13924/9308 14097/14099/9430 13916/13922/9306 +f 13908/13914/9299 14098/14100/9431 13958/13964/9342 +f 13908/13914/9299 13958/13964/9342 13903/13909/9294 +f 13911/13917/9301 14099/14101/9432 14100/14102/9433 +f 13911/13917/9301 14100/14102/9433 13912/13918/9302 +f 14101/14103/9434 13871/13877/9272 13874/13880/9275 +f 14101/14103/9434 13874/13880/9275 14102/14104/9435 +f 14103/14105/9057 13617/13625/9085 13525/12706/9006 +f 14103/14105/9057 13525/12706/9006 14104/14106/9436 +f 13652/13660/9116 13961/13967/9345 14105/14107/9437 +f 13652/13660/9116 14105/14107/9437 13593/13601/9063 +f 14106/14108/9055 13560/13568/9033 13520/13533/9002 +f 14106/14108/9055 13520/13533/9002 14107/14109/9438 +f 13393/13407/8893 12887/12911/8501 13535/13543/9011 +f 13393/13407/8893 13535/13543/9011 14108/14110/9439 +f 14109/14111/9440 13536/13544/9012 13617/13625/9085 +f 14109/14111/9440 13617/13625/9085 14103/14105/9057 +f 13593/13601/9063 14105/14107/9437 14110/14112/9441 +f 13593/13601/9063 14110/14112/9441 13584/13592/9054 +f 14111/14113/9442 13557/13565/9030 13560/13568/9033 +f 14111/14113/9442 13560/13568/9033 14106/14108/9055 +f 14108/14110/9439 13535/13543/9011 13536/13544/9012 +f 14108/14110/9439 13536/13544/9012 14109/14111/9440 +f 14104/14106/9436 13525/12706/9006 13528/12708/9326 +f 14104/14106/9436 13528/12708/9326 14090/14092/9424 +f 14107/14109/9438 13520/13533/9002 12785/12810/8407 +f 14107/14109/9438 12785/12810/8407 13398/13412/8385 +f 14112/14114/9443 14113/14115/9444 14114/14116/9445 +f 14112/14114/9443 14114/14116/9445 14115/14117/9429 +f 14115/14117/9429 14114/14116/9445 14116/14118/9446 +f 14115/14117/9429 14116/14118/9446 14117/14119/9430 +f 14117/14119/9430 14116/14118/9446 14118/14120/9447 +f 14117/14119/9430 14118/14120/9447 14119/14121/9448 +f 14095/14097/9428 14094/14096/9427 14120/14122/9421 +f 14095/14097/9428 14120/14122/9421 14121/14123/9328 +f 14122/14124/9449 14123/14125/9450 14124/14126/9451 +f 14122/14124/9449 14124/14126/9451 14125/14127/9452 +f 13920/13926/9309 14126/14128/9422 14096/14098/9429 +f 13920/13926/9309 14096/14098/9429 13918/13924/9308 +f 14127/14129/9453 14128/14130/9447 14093/14095/9426 +f 14127/14129/9453 14093/14095/9426 14092/14094/9425 +f 13916/13922/9306 14097/14099/9430 14129/14131/9450 +f 13916/13922/9306 14129/14131/9450 13914/13920/9304 +f 14130/14132/9344 14131/14133/9454 14132/14134/9455 +f 14130/14132/9344 14132/14134/9455 14133/14135/9456 +f 14134/14136/9457 14135/14137/9458 14136/14138/9459 +f 14134/14136/9457 14136/14138/9459 14137/14139/9343 +f 14137/14139/9343 14136/14138/9459 14138/14140/9454 +f 14137/14139/9343 14138/14140/9454 14139/14141/9344 +f 14140/14142/9073 14141/14143/9460 14142/14144/9461 +f 14140/14142/9073 14142/14144/9461 14143/14145/9071 +f 13961/13967/9345 13960/13966/9344 14144/14146/9460 +f 13961/13967/9345 14144/14146/9460 14105/14107/9437 +f 14145/14147/9347 14146/14148/9454 14147/14149/9462 +f 14145/14147/9347 14147/14149/9462 14148/14150/9315 +f 14098/14100/9431 14149/14151/9463 13959/13965/9343 +f 14098/14100/9431 13959/13965/9343 13958/13964/9342 +f 14150/14152/9071 14151/14153/9461 14146/14148/9454 +f 14150/14152/9071 14146/14148/9454 14145/14147/9347 +f 14152/14154/9464 14153/14155/9103 14149/14151/9463 +f 14152/14154/9464 14149/14151/9463 14098/14100/9431 +f 14154/14156/9103 14155/14157/9102 14135/14137/9458 +f 14154/14156/9103 14135/14137/9458 14134/14136/9457 +f 13907/13913/9298 14152/14154/9464 14098/14100/9431 +f 13907/13913/9298 14098/14100/9431 13908/13914/9299 +f 14073/14075/9416 14072/14074/9375 14074/14076/8317 +f 14073/14075/9416 14074/14076/8317 14008/12714/8315 +f 13768/12711/9214 14007/12713/8294 13769/13776/9215 +f 14027/12712/8314 14073/14075/9416 14008/12714/8315 +f 14156/12715/8316 14157/14158/9407 13996/12716/8317 +f 12697/12722/8322 12699/12724/8324 13267/13285/8806 +f 12697/12722/8322 13267/13285/8806 13271/13289/8809 +f 13967/13973/9351 13987/13993/9370 12698/12723/8323 +f 13967/13973/9351 12698/12723/8323 13966/13972/9350 +f 13237/13255/8791 13964/13970/9348 13619/13627/9087 +f 13237/13255/8791 13619/13627/9087 13966/13972/9350 +f 14158/14159/9314 13948/13954/9335 13625/13633/9091 +f 14158/14159/9314 13625/13633/9091 14159/14160/9465 +f 13944/13950/9281 13943/13949/9331 13926/13932/9313 +f 13944/13950/9281 13926/13932/9313 13925/13931/9312 +f 13902/13908/9142 13905/13911/9296 13908/13914/9299 +f 13902/13908/9142 13908/13914/9299 13903/13909/9294 +f 14148/14150/9315 14147/14149/9462 13878/13884/9279 +f 14148/14150/9315 13878/13884/9279 13877/13883/9278 +f 14160/12718/9466 13855/12717/9269 13854/13861/9268 +f 13830/13837/9252 13829/13836/9251 13832/13839/9234 +f 13830/13837/9252 13832/13839/9234 13831/13838/9253 +f 13755/13763/9203 13786/13793/9227 13802/13809/9234 +f 13755/13763/9203 13802/13809/9234 13749/13757/9197 +f 13710/13718/9167 13768/12711/9214 13769/13776/9215 +f 13710/13718/9167 13769/13776/9215 13717/13725/9171 +f 13475/13488/8958 13755/13763/9203 13749/13757/9197 +f 13475/13488/8958 13749/13757/9197 13470/13483/8953 +f 13711/13719/9168 13710/13718/9167 13717/13725/9171 +f 13711/13719/9168 13717/13725/9171 13716/13724/9140 +f 13683/13691/9147 13682/13690/9146 13677/13685/9141 +f 13683/13691/9147 13677/13685/9141 13676/13684/9140 +f 14159/14160/9465 13625/13633/9091 13613/13621/9082 +f 14159/14160/9465 13613/13621/9082 14161/14161/9072 +f 14162/14162/9467 13540/13548/9016 13619/13627/9087 +f 14162/14162/9467 13619/13627/9087 13964/13970/9348 +f 14161/14161/9072 13613/13621/9082 13537/13545/9013 +f 14161/14161/9072 13537/13545/9013 14163/14163/9034 +f 14163/14163/9034 13537/13545/9013 13540/13548/9016 +f 14163/14163/9034 13540/13548/9016 14162/14162/9467 +f 13499/13512/8982 13476/13489/8959 13469/13482/8952 +f 13499/13512/8982 13469/13482/8952 13496/13509/8979 +f 13476/13489/8959 13475/13488/8958 13470/13483/8953 +f 13476/13489/8959 13470/13483/8953 13469/13482/8952 +f 12751/12776/8376 12749/12774/8374 12750/12775/8375 +f 12749/12774/8374 12751/12776/8376 12752/12777/8377 +f 12749/12774/8374 12752/12777/8377 12747/12772/8372 +f 12747/12772/8372 12752/12777/8377 12753/12778/8378 +f 12747/12772/8372 12753/12778/8378 12748/12773/8373 +f 12748/12773/8373 12753/12778/8378 12745/12770/8370 +f 12745/12770/8370 12753/12778/8378 12746/12771/8371 +f 12746/12771/8371 12753/12778/8378 12737/12762/8362 +f 12746/12771/8371 12737/12762/8362 12744/12769/8369 +f 12744/12769/8369 12737/12762/8362 12736/12761/8361 +f 12744/12769/8369 12736/12761/8361 12743/12768/8368 +f 12743/12768/8368 12736/12761/8361 12742/12767/8367 +f 12742/12767/8367 12736/12761/8361 12738/12763/8363 +f 12742/12767/8367 12738/12763/8363 12741/12766/8366 +f 12741/12766/8366 12738/12763/8363 12740/12765/8365 +f 12740/12765/8365 12738/12763/8363 12739/12764/8364 +f 13500/13513/8983 13502/13515/8985 13501/13514/8984 +f 13502/13515/8985 13500/13513/8983 13503/13516/8986 +f 13503/13516/8986 13500/13513/8983 13498/13511/8981 +f 13503/13516/8986 13498/13511/8981 13504/13517/8987 +f 13504/13517/8987 13498/13511/8981 13499/13512/8982 +f 13504/13517/8987 13499/13512/8982 13496/13509/8979 +f 13504/13517/8987 13496/13509/8979 13497/13510/8980 +f 13504/13517/8987 13497/13510/8980 13488/13501/8971 +f 13488/13501/8971 13497/13510/8980 13495/13508/8978 +f 13488/13501/8971 13495/13508/8978 13487/13500/8970 +f 13487/13500/8970 13495/13508/8978 13494/13507/8977 +f 13487/13500/8970 13494/13507/8977 13493/13506/8976 +f 13487/13500/8970 13493/13506/8976 13489/13502/8972 +f 13489/13502/8972 13493/13506/8976 13492/13505/8975 +f 13489/13502/8972 13492/13505/8975 13491/13504/8974 +f 13489/13502/8972 13491/13504/8974 13490/13503/8973 +o Plane.014__0 +v 0.460040 0.674642 -0.061970 +v 0.459886 0.672821 -0.060492 +v 0.482849 0.674035 -0.061328 +v -0.554234 1.632303 -0.287192 +v -0.554341 1.582072 -0.227488 +v -0.599317 1.585778 -0.227603 +v -0.599188 1.636540 -0.288069 +v -0.554341 1.582072 -0.227488 +v -0.554998 1.529055 -0.177007 +v -0.600145 1.531251 -0.176746 +v -0.599317 1.585778 -0.227603 +v -0.633494 1.533252 -0.176260 +v -0.632534 1.588918 -0.227407 +v -0.632534 1.588918 -0.227407 +v -0.632391 1.640098 -0.288439 +v -0.558690 1.436041 -0.107882 +v -0.561021 1.394521 -0.079676 +v -0.607785 1.391930 -0.077309 +v -0.604828 1.434429 -0.106253 +v -0.563979 1.355960 -0.061407 +v -0.611540 1.352462 -0.058644 +v -0.646673 1.349946 -0.056169 +v -0.642334 1.390195 -0.075130 +v -0.638920 1.433520 -0.104636 +v -0.567805 1.320391 -0.059425 +v -0.616410 1.315255 -0.056821 +v -0.571282 1.285885 -0.065313 +v -0.620842 1.278559 -0.063189 +v -0.657446 1.273092 -0.061137 +v -0.652310 1.311450 -0.054443 +v -0.573225 1.250371 -0.069524 +v -0.623325 1.240715 -0.067913 +v -0.574043 1.213152 -0.072759 +v -0.624382 1.201423 -0.071646 +v -0.661570 1.192713 -0.070323 +v -0.660332 1.233518 -0.066225 +v -0.574777 1.172813 -0.076443 +v -0.625192 1.159575 -0.075804 +v -0.577405 1.123665 -0.074656 +v -0.627559 1.109471 -0.074372 +v -0.664641 1.099029 -0.073677 +v -0.662452 1.149791 -0.074838 +v -0.582998 1.061990 -0.062981 +v -0.632248 1.047218 -0.062990 +v -0.588066 0.996222 -0.050376 +v -0.635274 0.980747 -0.051350 +v -0.672130 0.970495 -0.051562 +v -0.668918 1.036527 -0.062510 +v -0.549071 1.656830 -0.693014 +v -0.551465 1.687143 -0.571205 +v -0.595662 1.686315 -0.575105 +v -0.592601 1.654313 -0.696238 +v -0.553332 1.691369 -0.446835 +v -0.598049 1.693038 -0.450606 +v -0.631095 1.694750 -0.453258 +v -0.628336 1.686183 -0.577996 +v -0.624788 1.652915 -0.698767 +v -0.546321 1.536401 -0.834536 +v -0.547008 1.602443 -0.777365 +v -0.589960 1.600069 -0.779753 +v -0.589077 1.534292 -0.836110 +v -0.547008 1.602443 -0.777365 +v -0.589960 1.600069 -0.779753 +v -0.621721 1.598738 -0.781748 +v -0.621721 1.598738 -0.781748 +v -0.620691 1.533091 -0.837563 +v -0.553518 1.384540 -0.910780 +v -0.548115 1.468112 -0.880744 +v -0.591359 1.464845 -0.881608 +v -0.598246 1.380536 -0.911185 +v -0.623331 1.462690 -0.882609 +v -0.631311 1.377731 -0.911919 +v -0.554114 1.671145 -0.355097 +v -0.599043 1.674659 -0.357526 +v -0.632235 1.677715 -0.359088 +v -0.556567 1.480397 -0.138867 +v -0.602135 1.480562 -0.138012 +v -0.635802 1.481028 -0.137029 +v -0.570908 1.162847 -0.914754 +v -0.574504 1.073771 -0.912413 +v -0.524289 1.074056 -0.912177 +v -0.521396 1.163342 -0.914557 +v -0.575015 1.017534 -0.912641 +v -0.525514 1.019813 -0.912383 +v -0.495747 1.030240 -0.912465 +v -0.488182 1.075181 -0.912500 +v -0.484800 1.163734 -0.914907 +v -0.562568 1.275275 -0.918413 +v -0.515352 1.277812 -0.918269 +v -0.508792 1.388598 -0.910510 +v -0.480456 1.279773 -0.918622 +v -0.475742 1.391771 -0.910715 +v -0.553096 1.651578 -0.274603 +v -0.598067 1.655690 -0.275585 +v -0.598136 1.604590 -0.214463 +v -0.553150 1.600998 -0.214239 +v -0.631331 1.658303 -0.276589 +v -0.631412 1.606844 -0.214910 +v -0.598136 1.604590 -0.214463 +v -0.631412 1.606844 -0.214910 +v -0.632555 1.550540 -0.163104 +v -0.599161 1.549370 -0.162920 +v -0.553150 1.600998 -0.214239 +v -0.554008 1.547278 -0.163068 +v -0.558147 1.448714 -0.089276 +v -0.604284 1.446939 -0.087778 +v -0.607037 1.400037 -0.056611 +v -0.560287 1.402920 -0.058872 +v -0.638396 1.445345 -0.087084 +v -0.641606 1.397725 -0.055370 +v -0.645631 1.353179 -0.034968 +v -0.610468 1.356081 -0.036517 +v -0.562923 1.359911 -0.039198 +v -0.615157 1.315177 -0.034152 +v -0.566549 1.320467 -0.036665 +v -0.651109 1.311276 -0.032748 +v -0.656240 1.270887 -0.039445 +v -0.619566 1.276219 -0.040446 +v -0.569985 1.283503 -0.042452 +v -0.622166 1.237932 -0.045121 +v -0.572044 1.247525 -0.046587 +v -0.659236 1.230902 -0.044535 +v -0.660793 1.190987 -0.048584 +v -0.623549 1.199581 -0.048785 +v -0.573186 1.211263 -0.049733 +v -0.624955 1.159467 -0.052919 +v -0.574484 1.172557 -0.053383 +v -0.662264 1.149793 -0.053069 +v -0.665174 1.101138 -0.052014 +v -0.628061 1.111507 -0.051608 +v -0.577832 1.125469 -0.051715 +v -0.633464 1.051428 -0.040540 +v -0.584166 1.066044 -0.040363 +v -0.670115 1.040660 -0.041152 +v -0.673781 0.976098 -0.030521 +v -0.636995 0.986594 -0.029221 +v -0.589780 1.002045 -0.028087 +v -0.549613 1.677995 -0.699668 +v -0.593143 1.675298 -0.702923 +v -0.595898 1.707719 -0.575565 +v -0.551688 1.708718 -0.571614 +v -0.625306 1.672842 -0.705183 +v -0.628570 1.706500 -0.578477 +v -0.630903 1.714788 -0.447640 +v -0.597830 1.714148 -0.444664 +v -0.553091 1.712634 -0.440822 +v -0.546974 1.553935 -0.848444 +v -0.589721 1.551600 -0.850012 +v -0.590628 1.619928 -0.790522 +v -0.547680 1.622487 -0.788125 +v -0.621303 1.549517 -0.850882 +v -0.622357 1.617612 -0.792065 +v -0.590628 1.619928 -0.790522 +v -0.622357 1.617612 -0.792065 +v -0.547680 1.622487 -0.788125 +v -0.553868 1.392768 -0.931449 +v -0.598576 1.388414 -0.931827 +v -0.591877 1.477723 -0.899096 +v -0.548650 1.481306 -0.898241 +v -0.631615 1.385041 -0.931671 +v -0.623818 1.474816 -0.899364 +v -0.598302 1.694765 -0.347229 +v -0.553350 1.691388 -0.344709 +v -0.631544 1.696804 -0.349326 +v -0.601449 1.496559 -0.122174 +v -0.555877 1.496499 -0.122901 +v -0.635148 1.496258 -0.121989 +v -0.570868 1.164149 -0.937729 +v -0.521362 1.164707 -0.937348 +v -0.524169 1.074251 -0.935016 +v -0.574384 1.073957 -0.935412 +v -0.484771 1.165092 -0.936569 +v -0.488070 1.075374 -0.934239 +v -0.495619 1.030254 -0.933686 +v -0.525381 1.019824 -0.934147 +v -0.574881 1.017544 -0.934518 +v -0.509159 1.397069 -0.930937 +v -0.515501 1.282046 -0.940411 +v -0.562704 1.279327 -0.940776 +v -0.476105 1.400073 -0.930153 +v -0.480608 1.283971 -0.939683 +v -0.649625 1.482167 -0.135668 +v -0.647170 1.535124 -0.175251 +v -0.652926 1.433910 -0.102850 +v -0.649625 1.482167 -0.135668 +v -0.652926 1.433910 -0.102850 +v -0.654848 1.435754 -0.099936 +v -0.651501 1.484631 -0.133198 +v -0.647170 1.535124 -0.175251 +v -0.648982 1.537999 -0.173121 +v -0.476452 1.525777 -0.177038 +v -0.476085 1.576220 -0.226868 +v -0.462317 1.576350 -0.225945 +v -0.462649 1.526273 -0.176212 +v -0.476085 1.576220 -0.226868 +v -0.476014 1.625580 -0.285246 +v -0.462252 1.625634 -0.284098 +v -0.462317 1.576350 -0.225945 +v -0.462317 1.576350 -0.225945 +v -0.462252 1.625634 -0.284098 +v -0.460120 1.628392 -0.282131 +v -0.460179 1.579068 -0.223915 +v -0.462649 1.526273 -0.176212 +v -0.460535 1.528943 -0.174097 +v -0.475556 1.689197 -0.440065 +v -0.474605 1.689316 -0.564428 +v -0.461166 1.691088 -0.563254 +v -0.461926 1.690200 -0.438481 +v -0.473383 1.661914 -0.687622 +v -0.460172 1.664157 -0.687087 +v -0.461166 1.691088 -0.563254 +v -0.460172 1.664157 -0.687087 +v -0.458361 1.667511 -0.687938 +v -0.459275 1.694428 -0.563128 +v -0.461926 1.690200 -0.438481 +v -0.459938 1.693381 -0.437388 +v -0.634839 1.599359 -0.783203 +v -0.633746 1.533592 -0.838969 +v -0.638073 1.653600 -0.700209 +v -0.634839 1.599359 -0.783203 +v -0.634839 1.599359 -0.783203 +v -0.638073 1.653600 -0.700209 +v -0.640050 1.656712 -0.701388 +v -0.636809 1.602296 -0.784973 +v -0.633746 1.533592 -0.838969 +v -0.635703 1.536136 -0.841182 +v -0.624515 1.019604 -0.913012 +v -0.625361 0.998108 -0.914605 +v -0.575004 0.995325 -0.914274 +v -0.654279 1.030211 -0.913474 +v -0.661570 1.019557 -0.914867 +v -0.625361 0.998108 -0.914605 +v -0.661570 1.019557 -0.914867 +v -0.663057 1.017355 -0.918380 +v -0.625624 0.995028 -0.918142 +v -0.575004 0.995325 -0.914274 +v -0.574982 0.992153 -0.917820 +v -0.574908 0.992153 -0.929339 +v -0.625551 0.995029 -0.929660 +v -0.625244 0.998111 -0.933194 +v -0.574886 0.995327 -0.932885 +v -0.662985 1.017359 -0.929898 +v -0.661456 1.019566 -0.933392 +v -0.625244 0.998111 -0.933194 +v -0.661456 1.019566 -0.933392 +v -0.654151 1.030225 -0.934692 +v -0.624382 1.019614 -0.934776 +v -0.574886 0.995327 -0.932885 +v -0.646142 1.591317 -0.226553 +v -0.645995 1.642723 -0.287837 +v -0.646142 1.591317 -0.226553 +v -0.646142 1.591317 -0.226553 +v -0.647917 1.594368 -0.224544 +v -0.645995 1.642723 -0.287837 +v -0.647779 1.645855 -0.285958 +v -0.660820 1.075661 -0.913583 +v -0.675570 1.074461 -0.915260 +v -0.657012 1.162026 -0.915881 +v -0.672078 1.161954 -0.917574 +v -0.675570 1.074461 -0.915260 +v -0.672078 1.161954 -0.917574 +v -0.674222 1.162107 -0.921105 +v -0.677665 1.074074 -0.918805 +v -0.661570 1.019557 -0.914867 +v -0.663057 1.017355 -0.918380 +v -0.472330 1.607232 -0.773558 +v -0.459304 1.609344 -0.773558 +v -0.472330 1.607232 -0.773558 +v -0.471986 1.540639 -0.832237 +v -0.459019 1.542495 -0.832685 +v -0.459304 1.609344 -0.773558 +v -0.459304 1.609344 -0.773558 +v -0.459019 1.542495 -0.832685 +v -0.457261 1.545298 -0.834710 +v -0.457539 1.612524 -0.775071 +v -0.473416 1.073938 -0.913988 +v -0.469729 1.163976 -0.916410 +v -0.488440 1.019861 -0.913765 +v -0.473416 1.073938 -0.913988 +v -0.488440 1.019861 -0.913765 +v -0.486909 1.017719 -0.917259 +v -0.471283 1.073558 -0.917505 +v -0.469729 1.163976 -0.916410 +v -0.467572 1.164218 -0.919899 +v -0.487667 1.031826 -0.031492 +v -0.480616 1.095471 -0.045810 +v -0.482938 1.095385 -0.042355 +v -0.490124 1.031930 -0.028135 +v -0.472936 1.154269 -0.057817 +v -0.475160 1.153859 -0.054300 +v -0.482938 1.095385 -0.042355 +v -0.475160 1.153859 -0.054300 +v -0.490467 1.149702 -0.052665 +v -0.498147 1.091116 -0.040821 +v -0.490124 1.031930 -0.028135 +v -0.505658 1.026974 -0.026932 +v -0.504074 1.021590 -0.047971 +v -0.497140 1.087595 -0.062210 +v -0.482096 1.092436 -0.060609 +v -0.488782 1.027369 -0.046045 +v -0.490192 1.148400 -0.074386 +v -0.474947 1.152812 -0.072870 +v -0.482096 1.092436 -0.060609 +v -0.474947 1.152812 -0.072870 +v -0.472806 1.153626 -0.069370 +v -0.480097 1.093651 -0.057145 +v -0.488782 1.027369 -0.046045 +v -0.486837 1.029006 -0.042584 +v -0.475951 1.665728 -0.350514 +v -0.462219 1.666097 -0.349032 +v -0.462219 1.666097 -0.349032 +v -0.460144 1.669039 -0.347332 +v -0.654564 1.441933 -0.090697 +v -0.658031 1.394953 -0.059139 +v -0.655882 1.396288 -0.056059 +v -0.652474 1.443925 -0.087919 +v -0.662405 1.351120 -0.038837 +v -0.660170 1.351791 -0.035563 +v -0.655882 1.396288 -0.056059 +v -0.660170 1.351791 -0.035563 +v -0.652474 1.443925 -0.087919 +v -0.650036 0.505689 0.029986 +v -0.664942 0.502020 0.026417 +v -0.660974 0.469011 0.054302 +v -0.646040 0.472423 0.056841 +v -0.664942 0.502020 0.026417 +v -0.666846 0.500240 0.022957 +v -0.662844 0.466702 0.051423 +v -0.660974 0.469011 0.054302 +v -0.655644 0.441797 0.079561 +v -0.653843 0.444570 0.081792 +v -0.653843 0.444570 0.081792 +v -0.639299 0.447678 0.083355 +v -0.469257 1.200018 -0.060271 +v -0.471390 1.199362 -0.056720 +v -0.468310 1.236147 -0.057641 +v -0.470363 1.235339 -0.054076 +v -0.471390 1.199362 -0.056720 +v -0.470363 1.235339 -0.054076 +v -0.485628 1.231644 -0.052162 +v -0.486722 1.195338 -0.054962 +v -0.487085 1.195820 -0.076783 +v -0.471713 1.199808 -0.075361 +v -0.486466 1.233486 -0.073916 +v -0.471082 1.236917 -0.072629 +v -0.471713 1.199808 -0.075361 +v -0.471082 1.236917 -0.072629 +v -0.468757 1.237126 -0.069154 +v -0.469459 1.200298 -0.071858 +v -0.675501 1.230390 -0.064168 +v -0.672445 1.270700 -0.058961 +v -0.676835 1.189018 -0.068411 +v -0.675501 1.230390 -0.064168 +v -0.676835 1.189018 -0.068411 +v -0.678899 1.188230 -0.064850 +v -0.677503 1.229550 -0.060594 +v -0.672445 1.270700 -0.058961 +v -0.674407 1.270026 -0.055374 +v -0.460018 1.538439 -0.166831 +v -0.459568 1.588772 -0.217102 +v -0.461341 1.591807 -0.215086 +v -0.461831 1.541295 -0.164698 +v -0.459540 1.638066 -0.275785 +v -0.461319 1.641186 -0.273898 +v -0.461341 1.591807 -0.215086 +v -0.461319 1.641186 -0.273898 +v -0.474925 1.643781 -0.273316 +v -0.474952 1.594158 -0.214267 +v -0.461831 1.541295 -0.164698 +v -0.475510 1.543097 -0.163748 +v -0.467754 1.268301 -0.055538 +v -0.469748 1.267435 -0.051971 +v -0.466848 1.299346 -0.052425 +v -0.468801 1.298656 -0.048859 +v -0.469748 1.267435 -0.051971 +v -0.468801 1.298656 -0.048859 +v -0.483800 1.296258 -0.046683 +v -0.484918 1.264307 -0.049910 +v -0.486053 1.267065 -0.071552 +v -0.470720 1.269795 -0.070428 +v -0.485047 1.298540 -0.068264 +v -0.469873 1.300589 -0.067344 +v -0.470720 1.269795 -0.070428 +v -0.469873 1.300589 -0.067344 +v -0.467516 1.300534 -0.063958 +v -0.468357 1.269765 -0.066994 +v -0.483237 1.329317 -0.063269 +v -0.468362 1.330882 -0.062589 +v -0.481234 1.362169 -0.065580 +v -0.466696 1.363518 -0.065041 +v -0.468362 1.330882 -0.062589 +v -0.466696 1.363518 -0.065041 +v -0.464475 1.364367 -0.061808 +v -0.466059 1.331163 -0.059257 +v -0.641805 1.687433 -0.579213 +v -0.644691 1.696750 -0.453985 +v -0.641805 1.687433 -0.579213 +v -0.644691 1.696750 -0.453985 +v -0.646605 1.700073 -0.453238 +v -0.643765 1.690688 -0.579462 +v -0.656518 1.389966 -0.073032 +v -0.661080 1.349104 -0.053917 +v -0.656518 1.389966 -0.073032 +v -0.661080 1.349104 -0.053917 +v -0.662981 1.349456 -0.050406 +v -0.658434 1.391063 -0.069751 +v -0.465416 1.331453 -0.047514 +v -0.467340 1.331281 -0.043959 +v -0.463943 1.366800 -0.050160 +v -0.465857 1.367330 -0.046690 +v -0.467340 1.331281 -0.043959 +v -0.465857 1.367330 -0.046690 +v -0.480265 1.366448 -0.044495 +v -0.482052 1.329673 -0.041722 +v -0.459795 1.703980 -0.434379 +v -0.459373 1.705247 -0.563304 +v -0.461325 1.708508 -0.563520 +v -0.461697 1.707300 -0.433616 +v -0.458631 1.678194 -0.691223 +v -0.460605 1.681321 -0.692355 +v -0.461325 1.708508 -0.563520 +v -0.460605 1.681321 -0.692355 +v -0.473890 1.681978 -0.693793 +v -0.474793 1.709723 -0.564736 +v -0.461697 1.707300 -0.433616 +v -0.475293 1.709271 -0.434350 +v -0.478433 1.439248 -0.110132 +v -0.477298 1.480599 -0.139855 +v -0.463386 1.481587 -0.139065 +v -0.464357 1.440587 -0.109402 +v -0.463386 1.481587 -0.139065 +v -0.461300 1.484026 -0.136667 +v -0.464357 1.440587 -0.109402 +v -0.462270 1.442611 -0.106641 +v -0.636526 1.462528 -0.884036 +v -0.644945 1.377011 -0.913428 +v -0.636526 1.462528 -0.884036 +v -0.638483 1.464321 -0.886771 +v -0.644945 1.377011 -0.913428 +v -0.646937 1.377994 -0.916630 +v -0.644686 1.270982 -0.919406 +v -0.659063 1.270455 -0.921018 +v -0.659063 1.270455 -0.921018 +v -0.661132 1.270895 -0.924465 +v -0.479674 1.399300 -0.083177 +v -0.465399 1.400673 -0.082579 +v -0.465399 1.400673 -0.082579 +v -0.463260 1.402139 -0.079531 +v -0.462891 1.406725 -0.068674 +v -0.464818 1.407953 -0.065425 +v -0.461991 1.449212 -0.097041 +v -0.463916 1.451088 -0.094144 +v -0.464818 1.407953 -0.065425 +v -0.463916 1.451088 -0.094144 +v -0.477924 1.451397 -0.092463 +v -0.479003 1.407660 -0.063419 +v -0.640326 1.667232 -0.704815 +v -0.643891 1.701360 -0.579743 +v -0.642007 1.704695 -0.579650 +v -0.638517 1.670571 -0.705713 +v -0.646508 1.710572 -0.450308 +v -0.644533 1.713757 -0.449230 +v -0.642007 1.704695 -0.579650 +v -0.644533 1.713757 -0.449230 +v -0.638517 1.670571 -0.705713 +v -0.472927 1.474221 -0.879781 +v -0.459803 1.476134 -0.880660 +v -0.462154 1.393571 -0.911943 +v -0.459803 1.476134 -0.880660 +v -0.462154 1.393571 -0.911943 +v -0.460269 1.395093 -0.915038 +v -0.458008 1.478362 -0.883253 +v -0.668290 1.309501 -0.036818 +v -0.665984 1.309691 -0.033450 +v -0.673764 1.268871 -0.043772 +v -0.671414 1.268832 -0.040365 +v -0.665984 1.309691 -0.033450 +v -0.671414 1.268832 -0.040365 +v -0.676925 1.228174 -0.049095 +v -0.674570 1.228171 -0.045655 +v -0.678492 1.187327 -0.053339 +v -0.676178 1.187557 -0.049868 +v -0.674570 1.228171 -0.045655 +v -0.676178 1.187557 -0.049868 +v -0.679860 1.145231 -0.057978 +v -0.677638 1.145808 -0.054487 +v -0.682515 1.095772 -0.057005 +v -0.680421 1.096733 -0.053519 +v -0.677638 1.145808 -0.054487 +v -0.680421 1.096733 -0.053519 +v -0.647341 1.693459 -0.352513 +v -0.645275 1.696409 -0.350820 +v -0.647222 1.655449 -0.279716 +v -0.645095 1.658218 -0.277756 +v -0.645275 1.696409 -0.350820 +v -0.645095 1.658218 -0.277756 +v -0.667021 1.309862 -0.052182 +v -0.667021 1.309862 -0.052182 +v -0.668942 1.309599 -0.048592 +v -0.677783 1.145762 -0.073085 +v -0.679945 1.094865 -0.072052 +v -0.677783 1.145762 -0.073085 +v -0.679945 1.094865 -0.072052 +v -0.682216 1.094601 -0.068549 +v -0.679947 1.145195 -0.069546 +v -0.687133 1.034695 -0.046185 +v -0.685167 1.035996 -0.042732 +v -0.691061 0.970208 -0.035820 +v -0.689121 0.971689 -0.032373 +v -0.685167 1.035996 -0.042732 +v -0.689121 0.971689 -0.032373 +v -0.684132 1.032422 -0.060983 +v -0.687708 0.966897 -0.050317 +v -0.684132 1.032422 -0.060983 +v -0.687708 0.966897 -0.050317 +v -0.690185 0.967235 -0.046956 +v -0.686489 1.032470 -0.057538 +v -0.662985 1.017359 -0.929898 +v -0.677604 1.074159 -0.930317 +v -0.675471 1.074597 -0.933836 +v -0.661456 1.019566 -0.933392 +v -0.674199 1.162692 -0.932588 +v -0.672038 1.162891 -0.936094 +v -0.675471 1.074597 -0.933836 +v -0.672038 1.162891 -0.936094 +v -0.656968 1.163140 -0.937610 +v -0.660705 1.075823 -0.935328 +v -0.636031 1.544927 -0.848356 +v -0.637148 1.612338 -0.790504 +v -0.635383 1.615490 -0.792066 +v -0.634270 1.547664 -0.850433 +v -0.635383 1.615490 -0.792066 +v -0.634270 1.547664 -0.850433 +v -0.635383 1.615490 -0.792066 +v -0.460122 0.537763 0.041846 +v -0.460513 0.539941 0.046964 +v -0.455815 0.498067 0.064982 +v -0.455358 0.494905 0.060617 +v -0.460905 0.542120 0.052083 +v -0.456271 0.501229 0.069347 +v -0.454338 0.468750 0.087492 +v -0.453858 0.464707 0.084008 +v -0.453380 0.460666 0.080524 +v -0.457880 1.622701 -0.780431 +v -0.459849 1.625667 -0.782152 +v -0.457596 1.554309 -0.841711 +v -0.459556 1.556919 -0.843872 +v -0.459849 1.625667 -0.782152 +v -0.459556 1.556919 -0.843872 +v -0.472611 1.557422 -0.845277 +v -0.472967 1.626278 -0.783609 +v -0.459849 1.625667 -0.782152 +v -0.472967 1.626278 -0.783609 +v -0.466096 1.280827 -0.920044 +v -0.466096 1.280827 -0.920044 +v -0.464068 1.281619 -0.923420 +v -0.458295 1.485349 -0.892146 +v -0.460260 1.487279 -0.894814 +v -0.460470 1.399658 -0.925558 +v -0.462472 1.400816 -0.928687 +v -0.460260 1.487279 -0.894814 +v -0.462472 1.400816 -0.928687 +v -0.473454 1.487109 -0.896216 +v -0.464155 1.283952 -0.934707 +v -0.466232 1.284516 -0.938105 +v -0.467559 1.164975 -0.931376 +v -0.469707 1.165171 -0.934890 +v -0.466232 1.284516 -0.938105 +v -0.469707 1.165171 -0.934890 +v -0.645857 1.680207 -0.359101 +v -0.645857 1.680207 -0.359101 +v -0.647700 1.683457 -0.357624 +v -0.661189 1.272736 -0.935786 +v -0.659153 1.273405 -0.939211 +v -0.647097 1.381871 -0.927232 +v -0.645200 1.383218 -0.930400 +v -0.659153 1.273405 -0.939211 +v -0.645200 1.383218 -0.930400 +v -0.644794 1.274478 -0.940668 +v -0.471224 1.073665 -0.929022 +v -0.473319 1.074107 -0.932565 +v -0.486839 1.017724 -0.928781 +v -0.488327 1.019870 -0.932294 +v -0.473319 1.074107 -0.932565 +v -0.488327 1.019870 -0.932294 +v -0.638742 1.470803 -0.895800 +v -0.636940 1.472893 -0.898461 +v -0.636940 1.472893 -0.898461 +v -0.459745 1.679111 -0.342143 +v -0.461577 1.682353 -0.340658 +v -0.461577 1.682353 -0.340658 +v -0.475201 1.684819 -0.340683 +v -0.460938 1.492401 -0.128400 +v -0.462815 1.494851 -0.125933 +v -0.462815 1.494851 -0.125933 +v -0.461831 1.541295 -0.164698 +v -0.475510 1.543097 -0.163748 +v -0.476642 1.495907 -0.124662 +v -0.647319 1.603932 -0.217892 +v -0.645183 1.606666 -0.215868 +v -0.648477 1.547284 -0.166101 +v -0.646363 1.549973 -0.163989 +v -0.645183 1.606666 -0.215868 +v -0.646363 1.549973 -0.163989 +v -0.645183 1.606666 -0.215868 +v -0.636978 1.607317 -0.787738 +v -0.640188 1.661972 -0.703102 +v -0.635867 1.540531 -0.844769 +v -0.459873 1.583920 -0.220508 +v -0.459831 1.633229 -0.278958 +v -0.460277 1.533691 -0.170464 +v -0.463075 1.404432 -0.074103 +v -0.462131 1.445911 -0.101841 +v -0.464209 1.365583 -0.055984 +v -0.643828 1.696024 -0.579602 +v -0.646557 1.705323 -0.451773 +v -0.658233 1.393008 -0.064445 +v -0.662693 1.350288 -0.044621 +v -0.654706 1.438843 -0.095317 +v -0.668616 1.309550 -0.042705 +v -0.674085 1.269449 -0.049573 +v -0.465738 1.331308 -0.053385 +v -0.467182 1.299940 -0.058191 +v -0.468055 1.269033 -0.061266 +v -0.468534 1.236637 -0.063397 +v -0.679904 1.145213 -0.063762 +v -0.682366 1.095187 -0.062777 +v -0.678695 1.187779 -0.059095 +v -0.647521 1.688457 -0.355068 +v -0.647500 1.650652 -0.282837 +v -0.677214 1.228862 -0.054845 +v -0.469358 1.200158 -0.066065 +v -0.472871 1.153948 -0.063593 +v -0.686811 1.033583 -0.051862 +v -0.690623 0.968721 -0.041388 +v -0.480356 1.094561 -0.051477 +v -0.487252 1.030416 -0.037038 +v -0.677634 1.074117 -0.924561 +v -0.674211 1.162400 -0.926847 +v -0.663021 1.017357 -0.924139 +v -0.459324 1.699837 -0.563216 +v -0.458496 1.672853 -0.689580 +v -0.459867 1.698681 -0.435884 +v -0.476930 0.532307 0.034799 +v -0.462025 0.535982 0.038384 +v -0.457228 0.492594 0.057736 +v -0.472160 0.489173 0.055183 +v -0.462025 0.535982 0.038384 +v -0.457228 0.492594 0.057736 +v -0.455181 0.457891 0.078291 +v -0.455181 0.457891 0.078291 +v -0.469723 0.454772 0.076718 +v -0.457709 1.617613 -0.777751 +v -0.457429 1.549803 -0.838210 +v -0.524267 0.995623 -0.929018 +v -0.524303 0.995623 -0.923258 +v -0.574945 0.992153 -0.923579 +v -0.486839 1.017724 -0.928781 +v -0.486874 1.017722 -0.923020 +v -0.486909 1.017719 -0.917259 +v -0.524340 0.995622 -0.917498 +v -0.458152 1.481856 -0.887700 +v -0.460370 1.397376 -0.920298 +v -0.464111 1.282786 -0.929064 +v -0.467565 1.164597 -0.925637 +v -0.651149 1.492734 -0.125270 +v -0.651325 1.488682 -0.129234 +v -0.648729 1.542642 -0.169611 +v -0.661161 1.271816 -0.930125 +v -0.647017 1.379933 -0.921931 +v -0.471253 1.073612 -0.923264 +v -0.486874 1.017722 -0.923020 +v -0.638613 1.467562 -0.891286 +v -0.459944 1.674075 -0.344737 +v -0.461119 1.488214 -0.132533 +v -0.647618 1.599150 -0.221218 +v -0.649063 1.495188 -0.122869 +v -0.649063 1.495188 -0.122869 +v -0.654682 0.433672 0.072557 +v -0.652290 0.431461 0.070492 +v -0.640934 0.414591 0.094146 +v -0.642992 0.416893 0.095955 +v -0.652290 0.431461 0.070492 +v -0.637476 0.432288 0.070088 +v -0.627878 0.415176 0.093292 +v -0.640934 0.414591 0.094146 +v -0.616493 0.408687 0.105478 +v -0.621290 0.407345 0.108743 +v -0.642992 0.416893 0.095955 +v -0.622414 0.409311 0.110785 +v -0.639299 0.447678 0.083355 +v -0.653843 0.444570 0.081792 +v -0.642190 0.428224 0.103302 +v -0.629361 0.431145 0.104037 +v -0.643768 0.425345 0.101628 +v -0.642190 0.428224 0.103302 +v -0.642190 0.428224 0.103302 +v -0.643768 0.425345 0.101628 +v -0.622945 0.417334 0.115677 +v -0.622166 0.420282 0.116662 +v -0.629361 0.431145 0.104037 +v -0.617598 0.423713 0.114816 +v -0.553545 0.443069 0.073006 +v -0.505323 0.449589 0.074960 +v -0.506538 0.428966 0.095666 +v -0.551048 0.423558 0.094885 +v -0.505323 0.449589 0.074960 +v -0.474344 0.433405 0.096231 +v -0.506538 0.428966 0.095666 +v -0.474344 0.433405 0.096231 +v -0.484252 0.424000 0.107637 +v -0.509803 0.419091 0.109880 +v -0.550202 0.414022 0.109763 +v -0.666452 0.498051 0.017812 +v -0.662385 0.463524 0.047035 +v -0.666059 0.495861 0.012668 +v -0.661926 0.460345 0.042647 +v -0.655163 0.437735 0.076059 +v -0.663672 0.494954 0.009815 +v -0.659492 0.458755 0.040143 +v -0.663672 0.494954 0.009815 +v -0.648546 0.497394 0.010497 +v -0.644301 0.460382 0.040220 +v -0.659492 0.458755 0.040143 +v -0.659492 0.458755 0.040143 +v -0.644301 0.460382 0.040220 +v -0.562694 0.514602 0.022065 +v -0.513359 0.524669 0.029123 +v -0.508694 0.482739 0.051566 +v -0.558178 0.474418 0.047204 +v -0.553545 0.443069 0.073006 +v -0.463291 0.543027 0.054937 +v -0.458705 0.502820 0.071854 +v -0.463291 0.543027 0.054937 +v -0.478419 0.540594 0.054271 +v -0.473898 0.501203 0.071790 +v -0.458705 0.502820 0.071854 +v -0.471545 0.470148 0.089972 +v -0.456730 0.470963 0.089559 +v -0.456730 0.470963 0.089559 +v -0.564272 0.523390 0.042712 +v -0.613606 0.513323 0.035655 +v -0.609505 0.478852 0.060452 +v -0.560021 0.487173 0.064813 +v -0.603699 0.452854 0.085107 +v -0.555477 0.459373 0.087061 +v -0.510409 0.416559 0.116161 +v -0.549999 0.411479 0.116290 +v -0.479333 0.423765 0.111085 +v -0.478480 0.425954 0.113164 +v -0.510486 0.418439 0.118378 +v -0.550086 0.413337 0.118527 +v -0.550488 0.421068 0.123066 +v -0.510904 0.426195 0.122954 +v -0.511114 0.429144 0.123630 +v -0.550682 0.424034 0.123708 +v -0.479009 0.433943 0.118035 +v -0.480206 0.436669 0.118984 +v -0.485355 0.439010 0.116965 +v -0.510838 0.434279 0.119188 +v -0.551222 0.429250 0.119067 +v -0.590195 0.417083 0.121626 +v -0.589986 0.413196 0.119332 +v -0.550287 0.417202 0.120797 +v -0.622680 0.413322 0.113231 +v -0.622414 0.409311 0.110785 +v -0.589777 0.409307 0.117038 +v -0.550086 0.413337 0.118527 +v -0.460269 0.442849 0.102298 +v -0.459883 0.438644 0.099476 +v -0.460655 0.447054 0.105120 +v -0.479009 0.433943 0.118035 +v -0.478745 0.429949 0.115599 +v -0.478480 0.425954 0.113164 +v -0.555477 0.459373 0.087061 +v -0.603699 0.452854 0.085107 +v -0.597124 0.435147 0.105218 +v -0.552601 0.440410 0.106205 +v -0.617598 0.423713 0.114816 +v -0.591694 0.424943 0.117859 +v -0.551222 0.429250 0.119067 +v -0.461474 0.435908 0.097594 +v -0.461474 0.435908 0.097594 +v -0.479333 0.423765 0.111085 +v -0.461474 0.435908 0.097594 +v -0.462727 0.449501 0.106724 +v -0.475825 0.449359 0.106966 +v -0.462727 0.449501 0.106724 +v -0.460655 0.447054 0.105120 +v -0.643380 0.421119 0.098792 +v -0.622414 0.409311 0.110785 +v -0.622680 0.413322 0.113231 +v -0.643380 0.421119 0.098792 +v -0.567698 0.605659 0.011693 +v -0.615312 0.595279 0.001838 +v -0.615393 0.554766 0.015098 +v -0.566458 0.565706 0.023984 +v -0.652260 0.586513 -0.006593 +v -0.651753 0.546408 0.007966 +v -0.465074 0.628907 0.026048 +v -0.467526 0.629441 0.029020 +v -0.465964 0.587727 0.039752 +v -0.463590 0.587135 0.036778 +v -0.467526 0.629441 0.029020 +v -0.483172 0.626424 0.027697 +v -0.481095 0.584858 0.038633 +v -0.465964 0.587727 0.039752 +v -0.566090 0.597661 -0.012238 +v -0.518639 0.610187 -0.002324 +v -0.516046 0.569744 0.010714 +v -0.564961 0.558535 0.001819 +v -0.481713 0.619721 0.006236 +v -0.479689 0.578201 0.017869 +v -0.668874 0.577347 -0.026374 +v -0.666425 0.576809 -0.029352 +v -0.665474 0.536874 -0.013945 +v -0.667848 0.537466 -0.010972 +v -0.666425 0.576809 -0.029352 +v -0.650800 0.579803 -0.028073 +v -0.650347 0.539744 -0.012817 +v -0.665474 0.536874 -0.013945 +v -0.669632 0.580711 -0.015349 +v -0.669253 0.579028 -0.020862 +v -0.668218 0.539213 -0.005506 +v -0.668588 0.540961 -0.000039 +v -0.466304 0.623986 0.011209 +v -0.464772 0.582098 0.022155 +v -0.466304 0.623986 0.011209 +v -0.464320 0.625560 0.015080 +v -0.462853 0.583657 0.025901 +v -0.464772 0.582098 0.022155 +v -0.464697 0.627234 0.020564 +v -0.463222 0.585396 0.031339 +v -0.667650 0.582280 -0.011489 +v -0.666670 0.542519 0.003704 +v -0.667650 0.582280 -0.011489 +v -0.666670 0.542519 0.003704 +v -0.670117 0.768257 -0.048061 +v -0.685361 0.762807 -0.053283 +v -0.684650 0.737859 -0.052131 +v -0.669903 0.742496 -0.046780 +v -0.685361 0.762807 -0.053283 +v -0.687282 0.761073 -0.057189 +v -0.686504 0.736240 -0.056056 +v -0.684650 0.737859 -0.052131 +v -0.686262 0.722986 -0.050056 +v -0.684412 0.724582 -0.046129 +v -0.684412 0.724582 -0.046129 +v -0.669723 0.729050 -0.040760 +v -0.483641 0.814402 -0.020132 +v -0.484087 0.816061 -0.014648 +v -0.483130 0.790268 -0.009699 +v -0.482692 0.788606 -0.015183 +v -0.484532 0.817721 -0.009164 +v -0.483568 0.791929 -0.004215 +v -0.483143 0.777818 0.002330 +v -0.482712 0.776156 -0.003155 +v -0.482281 0.774494 -0.008639 +v -0.500856 0.808763 -0.029214 +v -0.485568 0.812860 -0.024033 +v -0.484546 0.787010 -0.019109 +v -0.499298 0.782539 -0.024469 +v -0.485568 0.812860 -0.024033 +v -0.484546 0.787010 -0.019109 +v -0.484130 0.772896 -0.012568 +v -0.484130 0.772896 -0.012568 +v -0.498818 0.768424 -0.017954 +v -0.686833 0.759405 -0.062702 +v -0.686064 0.734571 -0.061568 +v -0.686385 0.757737 -0.068214 +v -0.685624 0.732900 -0.067080 +v -0.685396 0.719644 -0.061081 +v -0.685829 0.721315 -0.055568 +v -0.683914 0.757425 -0.071071 +v -0.683229 0.732472 -0.069919 +v -0.683914 0.757425 -0.071071 +v -0.668418 0.761937 -0.068943 +v -0.668235 0.736171 -0.067662 +v -0.683229 0.732472 -0.069919 +v -0.668082 0.722720 -0.061641 +v -0.683014 0.719190 -0.063916 +v -0.683014 0.719190 -0.063916 +v -0.584575 0.784813 -0.049718 +v -0.537525 0.799128 -0.038425 +v -0.535291 0.772580 -0.034225 +v -0.583715 0.759122 -0.046693 +v -0.534744 0.758545 -0.027787 +v -0.583401 0.745382 -0.040423 +v -0.487010 0.818227 -0.006297 +v -0.485963 0.792382 -0.001374 +v -0.487010 0.818227 -0.006297 +v -0.502553 0.815076 -0.008351 +v -0.500965 0.788858 -0.003606 +v -0.485963 0.792382 -0.001374 +v -0.500458 0.774748 0.002909 +v -0.485525 0.778273 0.005167 +v -0.485525 0.778273 0.005167 +v -0.586374 0.791507 -0.027596 +v -0.633502 0.779459 -0.038792 +v -0.633915 0.752649 -0.037025 +v -0.585482 0.765823 -0.024570 +v -0.633797 0.738926 -0.030935 +v -0.585140 0.752089 -0.018300 +v -0.601601 0.880244 -0.038091 +v -0.597268 0.872157 -0.037963 +v -0.597999 0.868860 -0.043552 +v -0.602678 0.878195 -0.043590 +v -0.597268 0.872157 -0.037963 +v -0.588287 0.870544 -0.036994 +v -0.587780 0.867262 -0.042366 +v -0.597999 0.868860 -0.043552 +v -0.597999 0.868860 -0.043552 +v -0.587780 0.867262 -0.042366 +v -0.587052 0.854310 -0.046782 +v -0.605937 0.855804 -0.049490 +v -0.602678 0.878195 -0.043590 +v -0.613061 0.873873 -0.048898 +v -0.488096 0.915515 -0.017817 +v -0.490533 0.915904 -0.014712 +v -0.488704 0.861889 -0.010632 +v -0.486132 0.861312 -0.013579 +v -0.490533 0.915904 -0.014712 +v -0.505692 0.911949 -0.015098 +v -0.504863 0.859235 -0.012128 +v -0.488704 0.861889 -0.010632 +v -0.538217 0.902467 -0.018993 +v -0.545319 0.852787 -0.019412 +v -0.564430 0.894219 -0.023946 +v -0.570192 0.872205 -0.025053 +v -0.588607 0.859879 -0.028346 +v -0.587728 0.830909 -0.027753 +v -0.539312 0.805775 -0.016459 +v -0.689395 0.852661 -0.055051 +v -0.686959 0.852271 -0.058154 +v -0.685168 0.799845 -0.066288 +v -0.687726 0.800009 -0.063361 +v -0.686959 0.852271 -0.058154 +v -0.671801 0.856224 -0.057752 +v -0.669109 0.805386 -0.064654 +v -0.685168 0.799845 -0.066288 +v -0.690339 0.855989 -0.044026 +v -0.689867 0.854325 -0.049539 +v -0.688185 0.801675 -0.057849 +v -0.688644 0.803341 -0.052336 +v -0.503906 0.905650 -0.035960 +v -0.489015 0.910549 -0.032448 +v -0.487226 0.856528 -0.028368 +v -0.503124 0.852929 -0.032990 +v -0.489015 0.910549 -0.032448 +v -0.487157 0.912204 -0.028785 +v -0.485219 0.857997 -0.024547 +v -0.487226 0.856528 -0.028368 +v -0.487627 0.913859 -0.023301 +v -0.485675 0.859655 -0.019063 +v -0.673588 0.862528 -0.036870 +v -0.688482 0.857641 -0.040366 +v -0.686650 0.805222 -0.048501 +v -0.670850 0.811698 -0.043772 +v -0.688482 0.857641 -0.040366 +v -0.686650 0.805222 -0.048501 +v -0.684254 0.714058 -0.037516 +v -0.669460 0.718461 -0.032099 +v -0.686124 0.712470 -0.041450 +v -0.684254 0.714058 -0.037516 +v -0.684435 0.696820 -0.033402 +v -0.682471 0.698408 -0.029420 +v -0.682471 0.698408 -0.029420 +v -0.667058 0.702800 -0.023670 +v -0.482358 0.764608 0.005332 +v -0.481936 0.762944 -0.000152 +v -0.482781 0.766272 0.010816 +v -0.480843 0.749470 0.018028 +v -0.480429 0.747804 0.012545 +v -0.480016 0.746138 0.007060 +v -0.483802 0.761350 -0.004088 +v -0.498570 0.756908 -0.009516 +v -0.483802 0.761350 -0.004088 +v -0.481953 0.744512 0.003082 +v -0.481953 0.744512 0.003082 +v -0.497177 0.739848 -0.002645 +v -0.685699 0.710796 -0.046962 +v -0.685274 0.709124 -0.052475 +v -0.683604 0.693470 -0.044427 +v -0.684019 0.695145 -0.038915 +v -0.682883 0.708656 -0.055314 +v -0.667849 0.712098 -0.053069 +v -0.682883 0.708656 -0.055314 +v -0.665464 0.696240 -0.045259 +v -0.681128 0.692976 -0.047297 +v -0.681128 0.692976 -0.047297 +v -0.534615 0.747191 -0.019419 +v -0.583158 0.734456 -0.032019 +v -0.533821 0.730194 -0.013038 +v -0.581250 0.719000 -0.025384 +v -0.485169 0.766735 0.013659 +v -0.500181 0.763267 0.011436 +v -0.485169 0.766735 0.013659 +v -0.498769 0.746402 0.018925 +v -0.483292 0.749927 0.020906 +v -0.483292 0.749927 0.020906 +v -0.633385 0.728220 -0.022199 +v -0.584872 0.741257 -0.009609 +v -0.630171 0.712805 -0.013239 +v -0.582984 0.726422 -0.000964 +v -0.658000 0.646884 -0.015763 +v -0.673047 0.642634 -0.021619 +v -0.669450 0.614164 -0.018689 +v -0.653516 0.618744 -0.013078 +v -0.673047 0.642634 -0.021619 +v -0.674968 0.641064 -0.025616 +v -0.671503 0.612547 -0.022651 +v -0.669450 0.614164 -0.018689 +v -0.470103 0.688146 0.010310 +v -0.470498 0.689816 0.015794 +v -0.466823 0.660292 0.016280 +v -0.466436 0.658621 0.010796 +v -0.470892 0.691486 0.021278 +v -0.467210 0.661964 0.021764 +v -0.486875 0.681934 0.000461 +v -0.472000 0.686528 0.006314 +v -0.468492 0.656987 0.006814 +v -0.484443 0.652293 0.001067 +v -0.472000 0.686528 0.006314 +v -0.468492 0.656987 0.006814 +v -0.674572 0.639386 -0.031128 +v -0.671114 0.610866 -0.028163 +v -0.674174 0.637707 -0.036641 +v -0.670725 0.609186 -0.033676 +v -0.671756 0.637115 -0.039680 +v -0.668187 0.608636 -0.036683 +v -0.671756 0.637115 -0.039680 +v -0.656425 0.639704 -0.038833 +v -0.651977 0.611527 -0.035615 +v -0.668187 0.608636 -0.036683 +v -0.532700 0.700606 -0.012048 +v -0.576830 0.696974 -0.023515 +v -0.493090 0.712571 -0.000175 +v -0.519134 0.672692 -0.009173 +v -0.544949 0.665037 -0.014873 +v -0.553509 0.680692 -0.017151 +v -0.573252 0.682234 -0.022503 +v -0.473286 0.692031 0.024323 +v -0.469751 0.662499 0.024757 +v -0.473286 0.692031 0.024323 +v -0.488449 0.689108 0.023512 +v -0.485981 0.659504 0.023585 +v -0.469751 0.662499 0.024757 +v -0.620772 0.686701 -0.005761 +v -0.578627 0.705642 0.004974 +v -0.661850 0.677066 -0.018151 +v -0.625132 0.654915 -0.006066 +v -0.597976 0.659859 -0.000164 +v -0.593231 0.678743 0.001271 +v -0.574894 0.690966 0.006184 +v 0.540409 1.626438 -0.289880 +v 0.585497 1.627286 -0.291804 +v 0.585740 1.581221 -0.229909 +v 0.540669 1.579037 -0.229041 +v 0.618822 1.628341 -0.292948 +v 0.619046 1.583236 -0.230270 +v 0.620141 1.534032 -0.175141 +v 0.586761 1.532374 -0.175433 +v 0.541581 1.530640 -0.175433 +v 0.545408 1.446825 -0.099070 +v 0.591547 1.445213 -0.097442 +v 0.594502 1.399681 -0.070976 +v 0.547739 1.402272 -0.073343 +v 0.625638 1.444304 -0.095825 +v 0.629052 1.397946 -0.068796 +v 0.633391 1.352642 -0.053966 +v 0.598258 1.355158 -0.056441 +v 0.550697 1.358656 -0.059204 +v 0.603128 1.315592 -0.056545 +v 0.554523 1.320728 -0.059150 +v 0.639028 1.311787 -0.054168 +v 0.644165 1.273092 -0.061137 +v 0.607560 1.278559 -0.063189 +v 0.558000 1.285885 -0.065313 +v 0.610044 1.240715 -0.067913 +v 0.559943 1.250371 -0.069524 +v 0.647050 1.233518 -0.066225 +v 0.648288 1.192713 -0.070323 +v 0.611099 1.201423 -0.071646 +v 0.560760 1.213152 -0.072759 +v 0.610621 1.160561 -0.075012 +v 0.560209 1.173667 -0.075816 +v 0.647877 1.150875 -0.073925 +v 0.641017 1.107704 -0.066375 +v 0.603964 1.117352 -0.068036 +v 0.553833 1.130493 -0.069638 +v 0.587927 1.070995 -0.043734 +v 0.538541 1.082564 -0.047664 +v 0.624421 1.062587 -0.040370 +v 0.605640 1.014147 -0.013164 +v 0.569633 1.021221 -0.017674 +v 0.520894 1.031078 -0.023174 +v 0.535789 1.633202 -0.688509 +v 0.579319 1.622047 -0.691733 +v 0.582367 1.659084 -0.572352 +v 0.538165 1.668928 -0.568420 +v 0.611506 1.614264 -0.694262 +v 0.615045 1.652288 -0.575268 +v 0.617742 1.669059 -0.453866 +v 0.584664 1.673369 -0.451021 +v 0.539915 1.679850 -0.446988 +v 0.533040 1.518393 -0.833366 +v 0.575794 1.510938 -0.834941 +v 0.576678 1.569419 -0.776412 +v 0.533725 1.579142 -0.774024 +v 0.607409 1.505785 -0.836394 +v 0.608439 1.562656 -0.778406 +v 0.576678 1.569419 -0.776412 +v 0.608439 1.562656 -0.778406 +v 0.533725 1.579142 -0.774024 +v 0.540236 1.381219 -0.912158 +v 0.584963 1.376262 -0.912563 +v 0.578076 1.451775 -0.881634 +v 0.534833 1.457972 -0.880770 +v 0.618029 1.372753 -0.913297 +v 0.610049 1.447455 -0.882636 +v 0.585467 1.660846 -0.360439 +v 0.540442 1.663273 -0.357257 +v 0.618747 1.659509 -0.362557 +v 0.541581 1.530640 -0.175433 +v 0.586761 1.532374 -0.175433 +v 0.588840 1.488117 -0.131790 +v 0.543268 1.488010 -0.132612 +v 0.620141 1.534032 -0.175141 +v 0.622511 1.488539 -0.130831 +v 0.557626 1.162847 -0.921645 +v 0.508115 1.163342 -0.921447 +v 0.511007 1.074056 -0.920273 +v 0.561222 1.073771 -0.920509 +v 0.471519 1.163734 -0.921797 +v 0.474900 1.075181 -0.920596 +v 0.482464 1.030240 -0.920734 +v 0.512232 1.019813 -0.920651 +v 0.561733 1.017534 -0.920909 +v 0.495510 1.386228 -0.911888 +v 0.502070 1.277515 -0.922403 +v 0.549286 1.274859 -0.922548 +v 0.462460 1.390105 -0.912092 +v 0.467174 1.279564 -0.922756 +v 0.540357 1.645736 -0.277277 +v 0.540258 1.597980 -0.215782 +v 0.585334 1.600050 -0.216760 +v 0.585453 1.646460 -0.279307 +v 0.540861 1.548869 -0.161490 +v 0.586046 1.550498 -0.161605 +v 0.619457 1.551326 -0.161982 +v 0.618659 1.601178 -0.217764 +v 0.618785 1.646568 -0.281085 +v 0.544865 1.459498 -0.080465 +v 0.547005 1.410671 -0.052539 +v 0.593755 1.407788 -0.050278 +v 0.591002 1.457723 -0.078967 +v 0.549641 1.362607 -0.036996 +v 0.597186 1.358777 -0.034314 +v 0.632349 1.355875 -0.032765 +v 0.628324 1.405476 -0.049037 +v 0.625114 1.456129 -0.078273 +v 0.553267 1.320804 -0.036390 +v 0.601875 1.315514 -0.033877 +v 0.556703 1.283503 -0.042452 +v 0.606284 1.276219 -0.040446 +v 0.642958 1.270887 -0.039445 +v 0.637827 1.311613 -0.032472 +v 0.558763 1.247525 -0.046587 +v 0.608884 1.237932 -0.045121 +v 0.559904 1.211263 -0.049733 +v 0.610268 1.199581 -0.048785 +v 0.647511 1.190987 -0.048584 +v 0.645955 1.230902 -0.044535 +v 0.559846 1.173500 -0.052803 +v 0.610315 1.160541 -0.052174 +v 0.553701 1.133012 -0.047072 +v 0.603911 1.120098 -0.045644 +v 0.641022 1.110488 -0.045065 +v 0.647624 1.150961 -0.052201 +v 0.538059 1.088769 -0.026162 +v 0.587506 1.077341 -0.022392 +v 0.520032 1.040527 -0.002704 +v 0.568797 1.030670 0.002649 +v 0.604859 1.023174 0.006161 +v 0.624061 1.068751 -0.020065 +v 0.536331 1.654367 -0.695162 +v 0.538423 1.690504 -0.568828 +v 0.582637 1.680489 -0.572812 +v 0.579861 1.643032 -0.698417 +v 0.539944 1.701121 -0.440972 +v 0.584715 1.694486 -0.445076 +v 0.617805 1.689102 -0.448246 +v 0.615310 1.672606 -0.575748 +v 0.612024 1.634191 -0.700677 +v 0.533692 1.535927 -0.847274 +v 0.534398 1.599187 -0.784783 +v 0.577345 1.589278 -0.787181 +v 0.576439 1.528247 -0.848842 +v 0.609075 1.581530 -0.788723 +v 0.608021 1.522212 -0.849712 +v 0.540586 1.389446 -0.932827 +v 0.535368 1.471166 -0.898267 +v 0.578595 1.464654 -0.899122 +v 0.585294 1.384140 -0.933205 +v 0.533692 1.535927 -0.847274 +v 0.576439 1.528247 -0.848842 +v 0.608021 1.522212 -0.849712 +v 0.610536 1.459581 -0.899391 +v 0.618332 1.380064 -0.933049 +v 0.540459 1.683533 -0.346859 +v 0.585500 1.680968 -0.350133 +v 0.618791 1.678614 -0.352787 +v 0.540861 1.548869 -0.161490 +v 0.542612 1.504112 -0.116646 +v 0.588188 1.504114 -0.115952 +v 0.586046 1.550498 -0.161605 +v 0.621888 1.503771 -0.115791 +v 0.619457 1.551326 -0.161982 +v 0.557586 1.164149 -0.944619 +v 0.561101 1.073957 -0.943508 +v 0.510887 1.074251 -0.943112 +v 0.508080 1.164707 -0.944238 +v 0.561599 1.017544 -0.942786 +v 0.512099 1.019824 -0.942416 +v 0.482337 1.030254 -0.941955 +v 0.474787 1.075374 -0.942335 +v 0.471489 1.165092 -0.943460 +v 0.549422 1.278911 -0.944910 +v 0.502218 1.281750 -0.944545 +v 0.495877 1.394699 -0.932315 +v 0.467326 1.283762 -0.943817 +v 0.462823 1.398407 -0.931531 +v 0.633845 1.535764 -0.174211 +v 0.636338 1.489661 -0.129481 +v 0.633845 1.535764 -0.174211 +v 0.635700 1.538620 -0.172092 +v 0.638219 1.492123 -0.127011 +v 0.636338 1.489661 -0.129481 +v 0.641566 1.446538 -0.091125 +v 0.639644 1.444694 -0.094039 +v 0.639644 1.444694 -0.094039 +v 0.462986 1.528167 -0.175008 +v 0.449192 1.528805 -0.174103 +v 0.448532 1.576428 -0.225960 +v 0.462274 1.575834 -0.227112 +v 0.449192 1.528805 -0.174103 +v 0.447118 1.531496 -0.171975 +v 0.446509 1.579215 -0.223895 +v 0.448532 1.576428 -0.225960 +v 0.446299 1.629603 -0.282629 +v 0.448270 1.626694 -0.284645 +v 0.448270 1.626694 -0.284645 +v 0.461995 1.625608 -0.286112 +v 0.462090 1.691850 -0.439763 +v 0.448469 1.695333 -0.438100 +v 0.447862 1.691297 -0.560402 +v 0.461300 1.686781 -0.561586 +v 0.448469 1.695333 -0.438100 +v 0.446521 1.698869 -0.436994 +v 0.445976 1.695029 -0.560275 +v 0.447862 1.691297 -0.560402 +v 0.445079 1.661912 -0.683433 +v 0.446890 1.658182 -0.682582 +v 0.446890 1.658182 -0.682582 +v 0.460101 1.653310 -0.683116 +v 0.607409 1.505785 -0.836394 +v 0.620464 1.504660 -0.837799 +v 0.621557 1.561040 -0.779862 +v 0.620464 1.504660 -0.837799 +v 0.622421 1.506971 -0.840013 +v 0.623527 1.563658 -0.781632 +v 0.621557 1.561040 -0.779862 +v 0.626768 1.615056 -0.696883 +v 0.624792 1.612320 -0.695704 +v 0.624792 1.612320 -0.695704 +v 0.561722 0.995325 -0.922542 +v 0.612079 0.998108 -0.922873 +v 0.611233 1.019604 -0.921280 +v 0.561722 0.995325 -0.922542 +v 0.561700 0.992153 -0.926088 +v 0.612342 0.995028 -0.926410 +v 0.612079 0.998108 -0.922873 +v 0.649774 1.017355 -0.926648 +v 0.648287 1.019557 -0.923135 +v 0.648287 1.019557 -0.923135 +v 0.640997 1.030211 -0.921742 +v 0.561626 0.992153 -0.937607 +v 0.561604 0.995327 -0.941154 +v 0.611962 0.998111 -0.941463 +v 0.612269 0.995029 -0.937929 +v 0.561604 0.995327 -0.941154 +v 0.611100 1.019614 -0.943044 +v 0.611962 0.998111 -0.941463 +v 0.640869 1.030225 -0.942961 +v 0.648174 1.019566 -0.941660 +v 0.648174 1.019566 -0.941660 +v 0.649704 1.017359 -0.938166 +v 0.632543 1.629936 -0.292664 +v 0.632738 1.585173 -0.229644 +v 0.632543 1.629936 -0.292664 +v 0.634499 1.632925 -0.290828 +v 0.634636 1.588160 -0.227666 +v 0.632738 1.585173 -0.229644 +v 0.633845 1.535764 -0.174211 +v 0.662288 1.074461 -0.923356 +v 0.647538 1.075661 -0.921679 +v 0.648287 1.019557 -0.923135 +v 0.649774 1.017355 -0.926648 +v 0.664383 1.074074 -0.926901 +v 0.662288 1.074461 -0.923356 +v 0.660941 1.162107 -0.927996 +v 0.658795 1.161954 -0.924464 +v 0.658795 1.161954 -0.924464 +v 0.643731 1.162026 -0.922771 +v 0.446021 1.601062 -0.770217 +v 0.459048 1.596713 -0.770217 +v 0.444257 1.604562 -0.771729 +v 0.446021 1.601062 -0.770217 +v 0.443979 1.538448 -0.833540 +v 0.445737 1.535413 -0.831515 +v 0.459048 1.596713 -0.770217 +v 0.446021 1.601062 -0.770217 +v 0.445737 1.535413 -0.831515 +v 0.458704 1.531930 -0.831067 +v 0.456447 1.163976 -0.923300 +v 0.460134 1.073938 -0.922084 +v 0.456447 1.163976 -0.923300 +v 0.454290 1.164218 -0.926789 +v 0.458001 1.073558 -0.925601 +v 0.460134 1.073938 -0.922084 +v 0.473628 1.017719 -0.925528 +v 0.475157 1.019861 -0.922034 +v 0.475157 1.019861 -0.922034 +v 0.418495 1.058682 -0.019169 +v 0.420477 1.059679 -0.015802 +v 0.437079 1.111501 -0.036101 +v 0.435021 1.111107 -0.039557 +v 0.420477 1.059679 -0.015802 +v 0.435254 1.057347 -0.012714 +v 0.452085 1.108439 -0.033441 +v 0.437079 1.111501 -0.036101 +v 0.466388 1.155398 -0.050306 +v 0.451128 1.159185 -0.052316 +v 0.451128 1.159185 -0.052316 +v 0.448991 1.159439 -0.055833 +v 0.436099 1.048542 -0.032038 +v 0.421201 1.052209 -0.032254 +v 0.437559 1.106827 -0.053461 +v 0.452633 1.102889 -0.053777 +v 0.421201 1.052209 -0.032254 +v 0.418943 1.054064 -0.029359 +v 0.435320 1.108221 -0.050339 +v 0.437559 1.106827 -0.053461 +v 0.449138 1.158442 -0.067200 +v 0.451363 1.157564 -0.070585 +v 0.451363 1.157564 -0.070585 +v 0.466641 1.153422 -0.071673 +v 0.448435 1.670369 -0.349653 +v 0.462139 1.668190 -0.351365 +v 0.446474 1.673572 -0.347919 +v 0.448435 1.670369 -0.349653 +v 0.641282 1.452717 -0.081886 +v 0.639192 1.454709 -0.079108 +v 0.642600 1.404039 -0.049726 +v 0.644750 1.402704 -0.052806 +v 0.639192 1.454709 -0.079108 +v 0.642600 1.404039 -0.049726 +v 0.646888 1.354487 -0.033360 +v 0.646888 1.354487 -0.033360 +v 0.649123 1.353816 -0.036634 +v 0.660194 0.551382 0.021522 +v 0.661728 0.513954 0.041550 +v 0.676239 0.514392 0.036165 +v 0.675712 0.552000 0.016355 +v 0.660332 0.481690 0.063546 +v 0.673967 0.481724 0.058000 +v 0.676239 0.514392 0.036165 +v 0.673967 0.481724 0.058000 +v 0.675567 0.478997 0.055844 +v 0.678103 0.512113 0.033395 +v 0.675712 0.552000 0.016355 +v 0.677888 0.550210 0.013030 +v 0.456764 1.200028 -0.056472 +v 0.454642 1.200664 -0.060023 +v 0.472090 1.196050 -0.054667 +v 0.456764 1.200028 -0.056472 +v 0.472345 1.231644 -0.052162 +v 0.457081 1.235339 -0.054076 +v 0.457081 1.235339 -0.054076 +v 0.455028 1.236147 -0.057641 +v 0.457143 1.200402 -0.075076 +v 0.472520 1.196447 -0.076444 +v 0.454878 1.200899 -0.071587 +v 0.457143 1.200402 -0.075076 +v 0.455475 1.237126 -0.069154 +v 0.457801 1.236916 -0.072629 +v 0.457801 1.236916 -0.072629 +v 0.473185 1.233486 -0.073916 +v 0.659163 1.270700 -0.058961 +v 0.662219 1.230390 -0.064168 +v 0.659163 1.270700 -0.058961 +v 0.661125 1.270026 -0.055374 +v 0.664221 1.229550 -0.060594 +v 0.662219 1.230390 -0.064168 +v 0.665617 1.188230 -0.064850 +v 0.663553 1.189018 -0.068411 +v 0.663553 1.189018 -0.068411 +v 0.446736 1.540994 -0.164708 +v 0.448591 1.543831 -0.162586 +v 0.448182 1.591899 -0.215093 +v 0.446285 1.588928 -0.217077 +v 0.448591 1.543831 -0.162586 +v 0.462299 1.545492 -0.161715 +v 0.461876 1.593788 -0.214502 +v 0.448182 1.591899 -0.215093 +v 0.461930 1.643831 -0.274170 +v 0.448208 1.642266 -0.274434 +v 0.448208 1.642266 -0.274434 +v 0.446258 1.639289 -0.276278 +v 0.456466 1.267435 -0.051971 +v 0.454472 1.268301 -0.055538 +v 0.471636 1.264307 -0.049910 +v 0.456466 1.267435 -0.051971 +v 0.470518 1.296258 -0.046683 +v 0.455519 1.298656 -0.048859 +v 0.455519 1.298656 -0.048859 +v 0.453566 1.299346 -0.052425 +v 0.457437 1.269795 -0.070428 +v 0.472770 1.267065 -0.071552 +v 0.455075 1.269765 -0.066994 +v 0.457437 1.269795 -0.070428 +v 0.454234 1.300534 -0.063958 +v 0.456591 1.300589 -0.067344 +v 0.456591 1.300589 -0.067344 +v 0.471766 1.298540 -0.068264 +v 0.455080 1.331219 -0.062313 +v 0.469954 1.329654 -0.062994 +v 0.452777 1.331500 -0.058981 +v 0.455080 1.331219 -0.062313 +v 0.451193 1.367063 -0.059606 +v 0.453414 1.366213 -0.062838 +v 0.453414 1.366213 -0.062838 +v 0.467952 1.364865 -0.063377 +v 0.628517 1.650794 -0.576495 +v 0.630483 1.653657 -0.576745 +v 0.628517 1.650794 -0.576495 +v 0.633323 1.671549 -0.453937 +v 0.631366 1.668579 -0.454673 +v 0.631366 1.668579 -0.454673 +v 0.643236 1.397717 -0.066700 +v 0.645152 1.398814 -0.063418 +v 0.643236 1.397717 -0.066700 +v 0.649698 1.352152 -0.048203 +v 0.647798 1.351800 -0.051714 +v 0.647798 1.351800 -0.051714 +v 0.454058 1.331618 -0.043684 +v 0.452135 1.331790 -0.047239 +v 0.468770 1.330010 -0.041446 +v 0.454058 1.331618 -0.043684 +v 0.466983 1.369144 -0.042292 +v 0.452575 1.370026 -0.044488 +v 0.452575 1.370026 -0.044488 +v 0.450661 1.369496 -0.047957 +v 0.446514 1.709472 -0.433983 +v 0.448458 1.712438 -0.433232 +v 0.448048 1.708717 -0.560668 +v 0.446091 1.705848 -0.560450 +v 0.448458 1.712438 -0.433232 +v 0.462082 1.711929 -0.434045 +v 0.461521 1.707190 -0.561893 +v 0.448048 1.708717 -0.560668 +v 0.460608 1.673374 -0.689287 +v 0.447323 1.675346 -0.687850 +v 0.447323 1.675346 -0.687850 +v 0.445349 1.672595 -0.686717 +v 0.465151 1.450032 -0.101321 +v 0.451075 1.451371 -0.100591 +v 0.450082 1.489317 -0.132744 +v 0.463993 1.488312 -0.133544 +v 0.451075 1.451371 -0.100591 +v 0.448988 1.453395 -0.097829 +v 0.448001 1.491760 -0.130344 +v 0.450082 1.489317 -0.132744 +v 0.463993 1.488312 -0.133544 +v 0.450082 1.489317 -0.132744 +v 0.631663 1.371743 -0.914807 +v 0.623244 1.446401 -0.884062 +v 0.631663 1.371743 -0.914807 +v 0.633655 1.372685 -0.918008 +v 0.625201 1.448066 -0.886797 +v 0.623244 1.446401 -0.884062 +v 0.620464 1.504660 -0.837799 +v 0.645781 1.269796 -0.925152 +v 0.631404 1.270360 -0.923540 +v 0.647851 1.270232 -0.928599 +v 0.645781 1.269796 -0.925152 +v 0.452117 1.408424 -0.076246 +v 0.466392 1.407051 -0.076844 +v 0.449978 1.409890 -0.073198 +v 0.452117 1.408424 -0.076246 +v 0.451536 1.415704 -0.059092 +v 0.449609 1.414476 -0.062341 +v 0.465721 1.415412 -0.057086 +v 0.451536 1.415704 -0.059092 +v 0.464643 1.462181 -0.083652 +v 0.450634 1.461872 -0.085333 +v 0.450634 1.461872 -0.085333 +v 0.448709 1.459996 -0.088230 +v 0.627044 1.625577 -0.700310 +v 0.625235 1.629291 -0.701207 +v 0.628747 1.668056 -0.576931 +v 0.630626 1.664329 -0.577026 +v 0.625235 1.629291 -0.701207 +v 0.628747 1.668056 -0.576931 +v 0.631425 1.685590 -0.449916 +v 0.631425 1.685590 -0.449916 +v 0.633361 1.682050 -0.451006 +v 0.446521 1.471982 -0.880686 +v 0.459645 1.469176 -0.879807 +v 0.444726 1.474337 -0.883279 +v 0.446521 1.471982 -0.880686 +v 0.446987 1.393759 -0.916416 +v 0.448872 1.392195 -0.913321 +v 0.448872 1.392195 -0.913321 +v 0.652702 1.310029 -0.033175 +v 0.655008 1.309838 -0.036543 +v 0.652702 1.310029 -0.033175 +v 0.658133 1.268832 -0.040365 +v 0.658133 1.268832 -0.040365 +v 0.660482 1.268871 -0.043772 +v 0.661288 1.228171 -0.045655 +v 0.663643 1.228174 -0.049095 +v 0.661288 1.228171 -0.045655 +v 0.662895 1.187557 -0.049868 +v 0.662895 1.187557 -0.049868 +v 0.665210 1.187327 -0.053339 +v 0.663001 1.147011 -0.053564 +v 0.665234 1.146426 -0.057041 +v 0.663001 1.147011 -0.053564 +v 0.656302 1.106353 -0.046144 +v 0.656302 1.106353 -0.046144 +v 0.658480 1.105328 -0.049515 +v 0.632495 1.676410 -0.354510 +v 0.634445 1.673198 -0.356237 +v 0.632495 1.676410 -0.354510 +v 0.632512 1.645451 -0.282572 +v 0.632512 1.645451 -0.282572 +v 0.634477 1.642530 -0.284580 +v 0.653739 1.310199 -0.051907 +v 0.655660 1.309936 -0.048317 +v 0.653739 1.310199 -0.051907 +v 0.663202 1.146893 -0.072125 +v 0.665355 1.146345 -0.068586 +v 0.663202 1.146893 -0.072125 +v 0.658460 1.103801 -0.060872 +v 0.656275 1.103910 -0.064375 +v 0.656275 1.103910 -0.064375 +v 0.639136 1.064821 -0.020369 +v 0.641341 1.063318 -0.023479 +v 0.639136 1.064821 -0.020369 +v 0.619758 1.019515 0.006391 +v 0.619758 1.019515 0.006391 +v 0.622003 1.017623 0.003501 +v 0.639426 1.059517 -0.037723 +v 0.641518 1.060021 -0.034277 +v 0.639426 1.059517 -0.037723 +v 0.622411 1.012841 -0.006729 +v 0.620417 1.011806 -0.010091 +v 0.620417 1.011806 -0.010091 +v 0.649704 1.017359 -0.938166 +v 0.648174 1.019566 -0.941660 +v 0.662189 1.074597 -0.941932 +v 0.664322 1.074159 -0.938414 +v 0.647423 1.075823 -0.943424 +v 0.662189 1.074597 -0.941932 +v 0.643686 1.163140 -0.944500 +v 0.658756 1.162891 -0.942984 +v 0.658756 1.162891 -0.942984 +v 0.660916 1.162692 -0.939478 +v 0.622749 1.515762 -0.847186 +v 0.620988 1.518731 -0.849263 +v 0.622101 1.577171 -0.788724 +v 0.623866 1.573699 -0.787163 +v 0.620988 1.518731 -0.849263 +v 0.622101 1.577171 -0.788724 +v 0.474116 0.519137 0.056829 +v 0.478138 0.481795 0.086758 +v 0.478502 0.485860 0.090230 +v 0.474187 0.522396 0.061319 +v 0.485035 0.450697 0.118013 +v 0.485638 0.455437 0.120378 +v 0.486241 0.460177 0.122744 +v 0.478866 0.489924 0.093703 +v 0.474258 0.525655 0.065809 +v 0.446567 1.617385 -0.778811 +v 0.444597 1.614739 -0.777090 +v 0.459685 1.615759 -0.780267 +v 0.446567 1.617385 -0.778811 +v 0.446567 1.617385 -0.778811 +v 0.459685 1.615759 -0.780267 +v 0.459329 1.548712 -0.844107 +v 0.446274 1.549836 -0.842703 +v 0.446274 1.549836 -0.842703 +v 0.444314 1.547459 -0.840541 +v 0.452814 1.280655 -0.924178 +v 0.450786 1.281452 -0.927554 +v 0.452814 1.280655 -0.924178 +v 0.446978 1.483127 -0.894840 +v 0.445013 1.481324 -0.892172 +v 0.460172 1.482064 -0.896242 +v 0.446978 1.483127 -0.894840 +v 0.449191 1.399441 -0.930065 +v 0.449191 1.399441 -0.930065 +v 0.447188 1.398324 -0.926936 +v 0.452950 1.284344 -0.942239 +v 0.450872 1.283785 -0.938841 +v 0.452950 1.284344 -0.942239 +v 0.456424 1.165171 -0.941781 +v 0.456424 1.165171 -0.941781 +v 0.454277 1.164975 -0.938267 +v 0.632453 1.660194 -0.362798 +v 0.634419 1.663188 -0.361352 +v 0.632453 1.660194 -0.362798 +v 0.645871 1.272747 -0.943345 +v 0.647907 1.272072 -0.939920 +v 0.631512 1.273856 -0.944802 +v 0.645871 1.272747 -0.943345 +v 0.631918 1.377951 -0.931778 +v 0.631918 1.377951 -0.931778 +v 0.633815 1.376563 -0.928610 +v 0.460037 1.074107 -0.940661 +v 0.457942 1.073665 -0.937118 +v 0.460037 1.074107 -0.940661 +v 0.475044 1.019870 -0.940562 +v 0.475044 1.019870 -0.940562 +v 0.473557 1.017724 -0.937049 +v 0.623659 1.456766 -0.898487 +v 0.625461 1.454549 -0.895826 +v 0.623659 1.456766 -0.898487 +v 0.620988 1.518731 -0.849263 +v 0.448418 1.686639 -0.341271 +v 0.446463 1.683653 -0.342725 +v 0.462126 1.687299 -0.341525 +v 0.448418 1.686639 -0.341271 +v 0.449538 1.502582 -0.119612 +v 0.447656 1.500135 -0.122077 +v 0.463368 1.503621 -0.118350 +v 0.449538 1.502582 -0.119612 +v 0.449538 1.502582 -0.119612 +v 0.463368 1.503621 -0.118350 +v 0.632402 1.600535 -0.218951 +v 0.634424 1.597733 -0.221009 +v 0.632402 1.600535 -0.218951 +v 0.633255 1.550618 -0.162947 +v 0.633255 1.550618 -0.162947 +v 0.635329 1.547908 -0.165070 +v 0.626906 1.620316 -0.698596 +v 0.623696 1.568679 -0.784397 +v 0.622585 1.511366 -0.843600 +v 0.446278 1.634446 -0.279454 +v 0.446397 1.584071 -0.220486 +v 0.446927 1.536245 -0.168342 +v 0.448848 1.456695 -0.093030 +v 0.449793 1.412183 -0.067770 +v 0.450927 1.368279 -0.053781 +v 0.633342 1.676800 -0.452471 +v 0.630555 1.658993 -0.576885 +v 0.649410 1.352984 -0.042419 +v 0.644951 1.400759 -0.058112 +v 0.641424 1.449628 -0.086505 +v 0.660803 1.269449 -0.049573 +v 0.655334 1.309887 -0.042430 +v 0.452456 1.331645 -0.053110 +v 0.453900 1.299940 -0.058191 +v 0.454773 1.269033 -0.061266 +v 0.455251 1.236637 -0.063397 +v 0.658470 1.104565 -0.055193 +v 0.665295 1.146385 -0.062814 +v 0.665413 1.187779 -0.059095 +v 0.634488 1.637728 -0.287704 +v 0.634432 1.668193 -0.358794 +v 0.663932 1.228862 -0.054845 +v 0.454760 1.200782 -0.065805 +v 0.449064 1.158941 -0.061517 +v 0.622207 1.015232 -0.001614 +v 0.641429 1.061669 -0.028878 +v 0.435170 1.109664 -0.044948 +v 0.418719 1.056373 -0.024264 +v 0.660928 1.162400 -0.933737 +v 0.664352 1.074117 -0.932657 +v 0.649739 1.017357 -0.932407 +v 0.445214 1.667253 -0.685075 +v 0.446033 1.700439 -0.560363 +v 0.446517 1.704171 -0.435489 +v 0.491640 0.518711 0.048100 +v 0.494490 0.480034 0.078564 +v 0.479999 0.479525 0.083983 +v 0.476271 0.517441 0.053474 +v 0.494490 0.480034 0.078564 +v 0.500268 0.447988 0.110303 +v 0.486635 0.447969 0.115857 +v 0.479999 0.479525 0.083983 +v 0.479999 0.479525 0.083983 +v 0.486635 0.447969 0.115857 +v 0.476271 0.517441 0.053474 +v 0.444147 1.542953 -0.837041 +v 0.444427 1.609650 -0.774410 +v 0.561663 0.992153 -0.931848 +v 0.511021 0.995623 -0.931526 +v 0.510985 0.995623 -0.937286 +v 0.511058 0.995622 -0.925766 +v 0.473628 1.017719 -0.925528 +v 0.473592 1.017722 -0.931288 +v 0.473557 1.017724 -0.937049 +v 0.447087 1.396041 -0.921676 +v 0.444870 1.477830 -0.887726 +v 0.454283 1.164597 -0.932528 +v 0.450830 1.282619 -0.933198 +v 0.638051 1.496174 -0.123048 +v 0.637884 1.500226 -0.119084 +v 0.635515 1.543264 -0.168581 +v 0.633735 1.374624 -0.923309 +v 0.647879 1.271152 -0.934260 +v 0.473592 1.017722 -0.931288 +v 0.457971 1.073612 -0.931360 +v 0.625331 1.451308 -0.891312 +v 0.446469 1.678612 -0.345322 +v 0.447829 1.495947 -0.126210 +v 0.634530 1.592947 -0.224338 +v 0.635802 1.502683 -0.116681 +v 0.633255 1.550618 -0.162947 +v 0.635802 1.502683 -0.116681 +v 0.674355 0.469469 0.051089 +v 0.669855 0.448215 0.073260 +v 0.667769 0.445175 0.072785 +v 0.672011 0.466351 0.050328 +v 0.656944 0.436797 0.092482 +v 0.655542 0.434288 0.091524 +v 0.667769 0.445175 0.072785 +v 0.655542 0.434288 0.091524 +v 0.649816 0.434239 0.090688 +v 0.655465 0.442788 0.076701 +v 0.672011 0.466351 0.050328 +v 0.658036 0.463643 0.054539 +v 0.657647 0.460841 0.083143 +v 0.669619 0.460582 0.078271 +v 0.657647 0.460841 0.083143 +v 0.651528 0.451042 0.096069 +v 0.656916 0.448722 0.096060 +v 0.669619 0.460582 0.078271 +v 0.669619 0.460582 0.078271 +v 0.656916 0.448722 0.096060 +v 0.657780 0.445745 0.095280 +v 0.670999 0.457767 0.076658 +v 0.579083 0.455275 0.082152 +v 0.584465 0.434556 0.104469 +v 0.543184 0.430352 0.120400 +v 0.533733 0.450840 0.098217 +v 0.590337 0.424810 0.118134 +v 0.552890 0.420740 0.132757 +v 0.527967 0.420131 0.139727 +v 0.513210 0.427916 0.131829 +v 0.677737 0.508027 0.029905 +v 0.677817 0.546935 0.008517 +v 0.674961 0.474233 0.053467 +v 0.677372 0.503942 0.026415 +v 0.677745 0.543659 0.004004 +v 0.675060 0.501209 0.024904 +v 0.675482 0.541430 0.001792 +v 0.675060 0.501209 0.024904 +v 0.672011 0.466351 0.050328 +v 0.658036 0.463643 0.054539 +v 0.660343 0.498478 0.028329 +v 0.675482 0.541430 0.001792 +v 0.659922 0.538973 0.004426 +v 0.575928 0.527788 0.025951 +v 0.577395 0.488708 0.053076 +v 0.529827 0.483596 0.067500 +v 0.528427 0.523085 0.038035 +v 0.579083 0.455275 0.082152 +v 0.533733 0.450840 0.098217 +v 0.500268 0.447988 0.110303 +v 0.481175 0.492670 0.095212 +v 0.476500 0.527980 0.067994 +v 0.488586 0.463297 0.123506 +v 0.481175 0.492670 0.095212 +v 0.488586 0.463297 0.123506 +v 0.502562 0.466019 0.119302 +v 0.495875 0.495496 0.091773 +v 0.476500 0.527980 0.067994 +v 0.491912 0.531108 0.065181 +v 0.576212 0.540933 0.044063 +v 0.578862 0.505103 0.067082 +v 0.626377 0.510449 0.052590 +v 0.623292 0.547512 0.031430 +v 0.581516 0.474395 0.091693 +v 0.626866 0.478831 0.075629 +v 0.593019 0.422348 0.123780 +v 0.556294 0.418195 0.138123 +v 0.593019 0.422348 0.123780 +v 0.593593 0.424460 0.125321 +v 0.556859 0.420290 0.139682 +v 0.556294 0.418195 0.138123 +v 0.524500 0.420883 0.146320 +v 0.524887 0.418685 0.144547 +v 0.524887 0.418685 0.144547 +v 0.594254 0.433036 0.127877 +v 0.594131 0.436288 0.127967 +v 0.557437 0.432178 0.142348 +v 0.557541 0.428900 0.142264 +v 0.591941 0.441798 0.123460 +v 0.554512 0.437690 0.138091 +v 0.529677 0.436915 0.145102 +v 0.526258 0.433084 0.149071 +v 0.525333 0.429792 0.149106 +v 0.593923 0.428749 0.126599 +v 0.629951 0.434042 0.110773 +v 0.630293 0.438357 0.112068 +v 0.629609 0.429725 0.109479 +v 0.656944 0.436797 0.092482 +v 0.657362 0.441271 0.093881 +v 0.657780 0.445745 0.095280 +v 0.500220 0.430414 0.139072 +v 0.500789 0.435166 0.140762 +v 0.500220 0.430414 0.139072 +v 0.524917 0.425337 0.147713 +v 0.500789 0.435166 0.140762 +v 0.501359 0.439919 0.142453 +v 0.501359 0.439919 0.142453 +v 0.586751 0.453601 0.111252 +v 0.627943 0.457955 0.095134 +v 0.586751 0.453601 0.111252 +v 0.591941 0.441798 0.123460 +v 0.628911 0.446653 0.107845 +v 0.627943 0.457955 0.095134 +v 0.501510 0.427745 0.137270 +v 0.501510 0.427745 0.137270 +v 0.501510 0.427745 0.137270 +v 0.486241 0.460177 0.122744 +v 0.503355 0.443108 0.142740 +v 0.488586 0.463297 0.123506 +v 0.515389 0.445953 0.138265 +v 0.488586 0.463297 0.123506 +v 0.503355 0.443108 0.142740 +v 0.515389 0.445953 0.138265 +v 0.502562 0.466019 0.119302 +v 0.670427 0.452991 0.074959 +v 0.657362 0.441271 0.093881 +v 0.559932 0.620915 0.002875 +v 0.551791 0.616200 0.006269 +v 0.550355 0.614187 0.001527 +v 0.559700 0.619166 -0.002240 +v 0.551791 0.616200 0.006269 +v 0.549649 0.607109 0.009848 +v 0.548100 0.604224 0.005414 +v 0.550355 0.614187 0.001527 +v 0.550355 0.614187 0.001527 +v 0.548100 0.604224 0.005414 +v 0.537180 0.601296 0.004547 +v 0.540289 0.617376 -0.001501 +v 0.559700 0.619166 -0.002240 +v 0.558090 0.624210 -0.007877 +v 0.459621 0.602642 0.037033 +v 0.467732 0.563707 0.048092 +v 0.470003 0.565851 0.050539 +v 0.461802 0.604581 0.039570 +v 0.470003 0.565851 0.050539 +v 0.486048 0.569160 0.047789 +v 0.461802 0.604581 0.039570 +v 0.477123 0.606642 0.037212 +v 0.543548 0.688208 -0.000030 +v 0.553519 0.653947 0.005326 +v 0.598749 0.648982 -0.003571 +v 0.589917 0.688787 -0.011207 +v 0.558139 0.633819 0.008878 +v 0.578431 0.629552 0.005756 +v 0.588401 0.615059 0.008667 +v 0.615263 0.618043 0.003438 +v 0.648408 0.620577 -0.005020 +v 0.639206 0.653585 -0.014899 +v 0.628361 0.688813 -0.021252 +v 0.665959 0.613698 -0.023844 +v 0.673309 0.580071 -0.011948 +v 0.670993 0.578130 -0.014451 +v 0.663778 0.611760 -0.026379 +v 0.670993 0.578130 -0.014451 +v 0.654633 0.576236 -0.012098 +v 0.663778 0.611760 -0.026379 +v 0.648457 0.609709 -0.024006 +v 0.665933 0.619435 -0.013820 +v 0.673237 0.585902 -0.002043 +v 0.673273 0.582986 -0.006995 +v 0.665946 0.616567 -0.018832 +v 0.477173 0.595784 0.018242 +v 0.486181 0.558127 0.029046 +v 0.470119 0.556472 0.034605 +v 0.461844 0.595351 0.023443 +v 0.470119 0.556472 0.034605 +v 0.467804 0.557907 0.038239 +v 0.461844 0.595351 0.023443 +v 0.459647 0.596934 0.027060 +v 0.467768 0.560807 0.043165 +v 0.459634 0.599788 0.032046 +v 0.654500 0.587279 0.006661 +v 0.670876 0.587536 0.001529 +v 0.663736 0.621018 -0.010206 +v 0.670876 0.587536 0.001529 +v 0.663736 0.621018 -0.010206 +v 0.587012 0.922882 0.013680 +v 0.586947 0.879784 0.006200 +v 0.602119 0.877244 0.003986 +v 0.601990 0.919549 0.012531 +v 0.589382 0.840025 -0.002307 +v 0.605128 0.838473 -0.005480 +v 0.602119 0.877244 0.003986 +v 0.605128 0.838473 -0.005480 +v 0.607418 0.836640 -0.008817 +v 0.604335 0.875274 0.000785 +v 0.601990 0.919549 0.012531 +v 0.604190 0.917470 0.009489 +v 0.399379 0.946845 -0.004074 +v 0.397755 0.894299 0.001687 +v 0.397670 0.897088 0.006692 +v 0.399276 0.949626 0.000918 +v 0.399879 0.846205 0.004820 +v 0.399808 0.849000 0.009825 +v 0.399737 0.851795 0.014830 +v 0.397586 0.899878 0.011697 +v 0.399172 0.952407 0.005911 +v 0.416558 0.941424 -0.008282 +v 0.415160 0.889672 -0.003761 +v 0.399973 0.892314 -0.001518 +v 0.401579 0.944765 -0.007118 +v 0.418050 0.841952 -0.001835 +v 0.402186 0.844263 0.001465 +v 0.399973 0.892314 -0.001518 +v 0.402186 0.844263 0.001465 +v 0.401579 0.944765 -0.007118 +v 0.604420 0.872470 -0.004246 +v 0.604294 0.914675 0.004471 +v 0.607490 0.833830 -0.013847 +v 0.607561 0.831020 -0.018878 +v 0.604505 0.869666 -0.009276 +v 0.604398 0.911879 -0.000548 +v 0.602392 0.868196 -0.012248 +v 0.602327 0.910528 -0.003663 +v 0.605357 0.829406 -0.021712 +v 0.602392 0.868196 -0.012248 +v 0.605357 0.829406 -0.021712 +v 0.589641 0.829378 -0.021363 +v 0.587267 0.869162 -0.012858 +v 0.602327 0.910528 -0.003663 +v 0.587407 0.912292 -0.005331 +v 0.501994 0.926541 -0.007376 +v 0.501220 0.879177 -0.008888 +v 0.451892 0.884986 -0.006226 +v 0.452873 0.934955 -0.008155 +v 0.503834 0.835974 -0.012227 +v 0.455729 0.838617 -0.006734 +v 0.399700 0.901336 0.014668 +v 0.401244 0.953759 0.009029 +v 0.401958 0.853304 0.017650 +v 0.399700 0.901336 0.014668 +v 0.401958 0.853304 0.017650 +v 0.417791 0.852590 0.017203 +v 0.414840 0.900285 0.015280 +v 0.401244 0.953759 0.009029 +v 0.416163 0.952003 0.010711 +v 0.501576 0.937760 0.012765 +v 0.500883 0.890432 0.011303 +v 0.550233 0.884384 0.008636 +v 0.550697 0.929346 0.013545 +v 0.503573 0.847257 0.007960 +v 0.551849 0.842705 0.002410 +v 0.507585 0.988977 0.009724 +v 0.556319 0.979668 0.013728 +v 0.592356 0.972548 0.016246 +v 0.406069 1.005575 -0.003845 +v 0.408076 1.006840 -0.000594 +v 0.408076 1.006840 -0.000594 +v 0.422855 1.004789 0.002066 +v 0.508313 0.978055 -0.010378 +v 0.459581 0.987372 -0.014382 +v 0.472149 1.041000 -0.028531 +v 0.423546 0.994503 -0.016893 +v 0.609827 0.961434 0.003166 +v 0.607818 0.960166 -0.000083 +v 0.607818 0.960166 -0.000083 +v 0.593039 0.962225 -0.002728 +v 0.609467 0.966886 0.013187 +v 0.609647 0.964160 0.008177 +v 0.408663 0.998097 -0.016714 +v 0.408663 0.998097 -0.016714 +v 0.406433 1.000168 -0.013817 +v 0.406251 1.002872 -0.008831 +v 0.607238 0.968961 0.016082 +v 0.607238 0.968961 0.016082 +v 0.593139 0.799836 -0.009594 +v 0.609450 0.798776 -0.013494 +v 0.601955 0.761443 -0.015838 +v 0.617529 0.759630 -0.020271 +v 0.609450 0.798776 -0.013494 +v 0.617529 0.759630 -0.020271 +v 0.619712 0.757736 -0.023779 +v 0.611782 0.797003 -0.016931 +v 0.404375 0.805105 0.006433 +v 0.404373 0.807919 0.011430 +v 0.412712 0.765540 0.007107 +v 0.412784 0.768378 0.012095 +v 0.412856 0.771214 0.017083 +v 0.404370 0.810733 0.016427 +v 0.423265 0.800462 -0.001201 +v 0.406737 0.803106 0.002959 +v 0.430162 0.762011 -0.000900 +v 0.414857 0.763669 0.003591 +v 0.406737 0.803106 0.002959 +v 0.414857 0.763669 0.003591 +v 0.611784 0.794175 -0.021953 +v 0.619640 0.754885 -0.028793 +v 0.619567 0.752033 -0.033806 +v 0.611786 0.791346 -0.026976 +v 0.609454 0.789648 -0.029701 +v 0.611786 0.791346 -0.026976 +v 0.619567 0.752033 -0.033806 +v 0.617294 0.750428 -0.036449 +v 0.609454 0.789648 -0.029701 +v 0.601667 0.750639 -0.034830 +v 0.593120 0.789115 -0.028619 +v 0.488599 0.759687 -0.011869 +v 0.499998 0.743081 -0.013912 +v 0.483745 0.722358 -0.010724 +v 0.463006 0.760078 -0.007840 +v 0.520779 0.736329 -0.018322 +v 0.529942 0.713068 -0.020949 +v 0.543268 0.676673 -0.020126 +v 0.496537 0.676074 -0.008257 +v 0.458379 0.675612 0.001574 +v 0.444110 0.720081 -0.001031 +v 0.406734 0.812207 0.019119 +v 0.415091 0.772844 0.019722 +v 0.406734 0.812207 0.019119 +v 0.415091 0.772844 0.019722 +v 0.430450 0.772804 0.018074 +v 0.423284 0.811172 0.017806 +v 0.539127 0.765290 -0.005104 +v 0.537702 0.750295 -0.005174 +v 0.570806 0.730297 -0.010587 +v 0.567905 0.763890 -0.009010 +v 0.521147 0.745895 -0.001571 +v 0.530323 0.724336 -0.001270 +v 0.613743 0.725210 -0.020516 +v 0.630599 0.722986 -0.025778 +v 0.644830 0.688108 -0.026825 +v 0.630599 0.722986 -0.025778 +v 0.644830 0.688108 -0.026825 +v 0.647143 0.686360 -0.030493 +v 0.632955 0.721025 -0.029401 +v 0.425852 0.722128 0.007681 +v 0.425944 0.724981 0.012664 +v 0.439868 0.677787 0.010531 +v 0.439937 0.680647 0.015512 +v 0.440006 0.683507 0.020494 +v 0.426035 0.727834 0.017647 +v 0.428088 0.720433 0.004080 +v 0.442147 0.676073 0.006899 +v 0.428088 0.720433 0.004080 +v 0.442147 0.676073 0.006899 +v 0.632863 0.718157 -0.034410 +v 0.647074 0.683485 -0.035500 +v 0.647005 0.680610 -0.040508 +v 0.632771 0.715290 -0.039418 +v 0.632771 0.715290 -0.039418 +v 0.630302 0.713734 -0.041940 +v 0.647005 0.680610 -0.040508 +v 0.644607 0.678832 -0.042984 +v 0.628099 0.677924 -0.040221 +v 0.613390 0.714349 -0.039489 +v 0.464922 0.805593 0.011177 +v 0.455472 0.849820 0.013309 +v 0.463339 0.771208 0.011715 +v 0.488953 0.769238 0.004890 +v 0.492075 0.784514 0.004181 +v 0.509991 0.788742 0.001012 +v 0.507382 0.810356 0.004472 +v 0.412856 0.771214 0.017083 +v 0.426035 0.727834 0.017647 +v 0.428385 0.729660 0.020195 +v 0.440006 0.683507 0.020494 +v 0.442370 0.685323 0.023010 +v 0.458640 0.686491 0.020526 +v 0.444462 0.730932 0.017925 +v 0.516862 0.750827 -0.009207 +v 0.523989 0.753702 -0.010672 +v 0.525568 0.749931 -0.015849 +v 0.517264 0.746866 -0.014116 +v 0.523989 0.753702 -0.010672 +v 0.525348 0.761596 -0.011018 +v 0.526935 0.758714 -0.016144 +v 0.525568 0.749931 -0.015849 +v 0.525568 0.749931 -0.015849 +v 0.526935 0.758714 -0.016144 +v 0.538773 0.755740 -0.021864 +v 0.537331 0.740731 -0.021926 +v 0.517264 0.746866 -0.014116 +v 0.637607 0.143731 -0.151035 +v 0.625807 0.116850 -0.150330 +v 0.621771 0.116776 -0.153395 +v 0.632942 0.143692 -0.154353 +v 0.625807 0.116850 -0.150330 +v 0.593729 0.096634 -0.149178 +v 0.591209 0.097111 -0.152025 +v 0.621771 0.116776 -0.153395 +v 0.605763 0.139961 -0.134673 +v 0.597765 0.113532 -0.135142 +v 0.623585 0.115860 -0.136964 +v 0.635207 0.142262 -0.136607 +v 0.581681 0.098487 -0.135503 +v 0.592582 0.096691 -0.136904 +v 0.623585 0.115860 -0.136964 +v 0.592582 0.096691 -0.136904 +v 0.594568 0.096391 -0.139811 +v 0.626929 0.116285 -0.140144 +v 0.626929 0.116285 -0.140144 +v 0.639011 0.142845 -0.140036 +v 0.579996 0.099095 -0.153136 +v 0.591209 0.097111 -0.152025 +v 0.535337 0.084945 -0.150715 +v 0.535465 0.091516 -0.152378 +v 0.535529 0.083966 -0.147883 +v 0.535337 0.084945 -0.150715 +v 0.477854 0.083384 -0.147135 +v 0.479911 0.084450 -0.150071 +v 0.479911 0.084450 -0.150071 +v 0.491160 0.089266 -0.151613 +v 0.536550 0.084711 -0.136041 +v 0.536262 0.083843 -0.138836 +v 0.537099 0.090991 -0.134639 +v 0.536550 0.084711 -0.136041 +v 0.492843 0.088658 -0.133996 +v 0.481282 0.084032 -0.134980 +v 0.481282 0.084032 -0.134980 +v 0.478690 0.083142 -0.137800 +v 0.478272 0.083262 -0.142468 +v 0.535895 0.083904 -0.143359 +v 0.594149 0.096512 -0.144495 +v 0.434357 0.128797 -0.148329 +v 0.446872 0.098905 -0.147458 +v 0.447430 0.098624 -0.142390 +v 0.435055 0.128356 -0.142858 +v 0.446872 0.098905 -0.147458 +v 0.447430 0.098624 -0.142390 +v 0.447988 0.098344 -0.137322 +v 0.447988 0.098344 -0.137322 +v 0.435754 0.127916 -0.137387 +v 0.470259 0.130007 -0.132897 +v 0.478222 0.101606 -0.133256 +v 0.538022 0.107291 -0.133788 +v 0.538071 0.134946 -0.133317 +v 0.450230 0.099589 -0.150645 +v 0.438160 0.129380 -0.151761 +v 0.450230 0.099589 -0.150645 +v 0.446872 0.098905 -0.147458 +v 0.434357 0.128797 -0.148329 +v 0.435754 0.127916 -0.137387 +v 0.447988 0.098344 -0.137322 +v 0.452038 0.098675 -0.134260 +v 0.440419 0.127955 -0.134067 +v 0.452038 0.098675 -0.134260 +v 0.639011 0.142845 -0.140036 +v 0.626929 0.116285 -0.140144 +v 0.626368 0.116568 -0.145237 +v 0.638309 0.143288 -0.145535 +v 0.626368 0.116568 -0.145237 +v 0.625807 0.116850 -0.150330 +v 0.637607 0.143731 -0.151035 +v 0.607734 0.177456 -0.134250 +v 0.536247 0.174859 -0.133068 +v 0.607584 0.239279 -0.133035 +v 0.534612 0.239048 -0.131953 +v 0.461509 0.238905 -0.131840 +v 0.464629 0.172349 -0.132852 +v 0.426649 0.172554 -0.148892 +v 0.430652 0.173028 -0.152421 +v 0.422760 0.240322 -0.148005 +v 0.426851 0.240654 -0.151543 +v 0.433109 0.171378 -0.134155 +v 0.429336 0.238971 -0.133195 +v 0.424297 0.239281 -0.136657 +v 0.428168 0.171533 -0.137596 +v 0.641301 0.180218 -0.151032 +v 0.642064 0.179705 -0.145355 +v 0.641867 0.240888 -0.149840 +v 0.642640 0.240364 -0.144137 +v 0.643412 0.239841 -0.138434 +v 0.642828 0.179192 -0.139678 +v 0.642828 0.179192 -0.139678 +v 0.638824 0.178718 -0.136151 +v 0.643412 0.239841 -0.138434 +v 0.639321 0.239508 -0.134899 +v 0.636360 0.180373 -0.154471 +v 0.636829 0.241197 -0.153300 +v 0.641867 0.240888 -0.149840 +v 0.641301 0.180218 -0.151032 +v 0.428168 0.171533 -0.137596 +v 0.427408 0.172043 -0.143244 +v 0.424297 0.239281 -0.136657 +v 0.423529 0.239801 -0.142331 +v 0.422760 0.240322 -0.148005 +v 0.426649 0.172554 -0.148892 +v 0.423974 0.338280 -0.144544 +v 0.428036 0.338556 -0.148092 +v 0.427973 0.446076 -0.137745 +v 0.431924 0.446436 -0.141316 +v 0.462508 0.336420 -0.128455 +v 0.430526 0.336882 -0.129744 +v 0.465672 0.444948 -0.121819 +v 0.434449 0.444827 -0.122965 +v 0.429538 0.445094 -0.126398 +v 0.425514 0.337246 -0.133197 +v 0.641769 0.336183 -0.146826 +v 0.642539 0.335639 -0.141123 +v 0.640575 0.448385 -0.140979 +v 0.641330 0.447687 -0.135269 +v 0.642111 0.447033 -0.129584 +v 0.643312 0.335099 -0.135422 +v 0.643312 0.335099 -0.135422 +v 0.639250 0.334814 -0.131879 +v 0.642111 0.447033 -0.129584 +v 0.638165 0.446600 -0.126031 +v 0.607385 0.446157 -0.123965 +v 0.607705 0.334978 -0.129950 +v 0.636765 0.336571 -0.150284 +v 0.635730 0.448844 -0.144459 +v 0.640575 0.448385 -0.140979 +v 0.641769 0.336183 -0.146826 +v 0.425514 0.337246 -0.133197 +v 0.424744 0.337763 -0.138871 +v 0.429538 0.445094 -0.126398 +v 0.428756 0.445585 -0.132072 +v 0.427973 0.446076 -0.137745 +v 0.423974 0.338280 -0.144544 +v 0.535172 0.335654 -0.128718 +v 0.536595 0.445504 -0.122408 +v 0.433619 0.538791 -0.115578 +v 0.432801 0.539302 -0.121214 +v 0.436776 0.605944 -0.100025 +v 0.435877 0.606948 -0.105401 +v 0.435005 0.607998 -0.110801 +v 0.431987 0.539820 -0.126854 +v 0.605891 0.548397 -0.114589 +v 0.537348 0.544303 -0.112473 +v 0.605513 0.621107 -0.103446 +v 0.538421 0.614564 -0.099685 +v 0.471174 0.608243 -0.096837 +v 0.468663 0.540334 -0.111315 +v 0.431987 0.539820 -0.126854 +v 0.435792 0.540458 -0.130449 +v 0.438733 0.609212 -0.114396 +v 0.435792 0.540458 -0.130449 +v 0.435792 0.540458 -0.130449 +v 0.438733 0.609212 -0.114396 +v 0.468056 0.612982 -0.117505 +v 0.465675 0.542779 -0.132829 +v 0.438412 0.538726 -0.112203 +v 0.441531 0.605729 -0.096918 +v 0.436776 0.605944 -0.100025 +v 0.433619 0.538791 -0.115578 +v 0.637930 0.553333 -0.131724 +v 0.638658 0.552225 -0.126036 +v 0.636654 0.629269 -0.120639 +v 0.637405 0.627396 -0.115185 +v 0.638288 0.625747 -0.109852 +v 0.639465 0.551251 -0.120421 +v 0.535439 0.620767 -0.121435 +v 0.534412 0.547738 -0.135056 +v 0.602819 0.628061 -0.124309 +v 0.603208 0.552434 -0.136249 +v 0.639465 0.551251 -0.120421 +v 0.635680 0.550417 -0.116881 +v 0.638288 0.625747 -0.109852 +v 0.634645 0.624358 -0.106386 +v 0.632233 0.630375 -0.124007 +v 0.633335 0.553967 -0.135247 +v 0.636654 0.629269 -0.120639 +v 0.637930 0.553333 -0.131724 +v 0.641229 0.656859 -0.100334 +v 0.637634 0.654856 -0.096985 +v 0.634645 0.624358 -0.106386 +v 0.641229 0.656859 -0.100334 +v 0.646619 0.661916 -0.094059 +v 0.642878 0.659153 -0.090598 +v 0.637634 0.654856 -0.096985 +v 0.612748 0.656638 -0.084645 +v 0.608352 0.651809 -0.092709 +v 0.637634 0.654856 -0.096985 +v 0.608352 0.651809 -0.092709 +v 0.605319 0.663419 -0.111608 +v 0.634871 0.664559 -0.112815 +v 0.605319 0.663419 -0.111608 +v 0.609402 0.673776 -0.102061 +v 0.639834 0.672774 -0.104677 +v 0.634871 0.664559 -0.112815 +v 0.639834 0.672774 -0.104677 +v 0.644557 0.669615 -0.102321 +v 0.639349 0.662552 -0.109949 +v 0.438419 0.641040 -0.080479 +v 0.437375 0.643306 -0.085275 +v 0.437743 0.654456 -0.063497 +v 0.436501 0.658176 -0.067825 +v 0.435512 0.662119 -0.072330 +v 0.436425 0.645707 -0.090151 +v 0.540865 0.646435 -0.085660 +v 0.543428 0.653781 -0.074056 +v 0.540865 0.646435 -0.085660 +v 0.473876 0.651831 -0.064394 +v 0.473195 0.641515 -0.079447 +v 0.473195 0.641515 -0.079447 +v 0.440243 0.647856 -0.093748 +v 0.439613 0.665370 -0.076187 +v 0.440243 0.647856 -0.093748 +v 0.439613 0.665370 -0.076187 +v 0.470196 0.668472 -0.082331 +v 0.469829 0.651536 -0.098274 +v 0.443312 0.639949 -0.077928 +v 0.443003 0.652115 -0.061356 +v 0.443312 0.639949 -0.077928 +v 0.437743 0.654456 -0.063497 +v 0.438419 0.641040 -0.080479 +v 0.438419 0.641040 -0.080479 +v 0.639349 0.662552 -0.109949 +v 0.640216 0.659574 -0.105076 +v 0.644557 0.669615 -0.102321 +v 0.645547 0.665632 -0.098164 +v 0.646619 0.661916 -0.094059 +v 0.537602 0.657903 -0.105465 +v 0.539852 0.671822 -0.092773 +v 0.609402 0.673776 -0.102061 +v 0.618038 0.694293 -0.077761 +v 0.645219 0.691557 -0.084256 +v 0.647386 0.692060 -0.085701 +v 0.619572 0.696357 -0.080376 +v 0.645219 0.691557 -0.084256 +v 0.648252 0.687414 -0.083941 +v 0.651186 0.686510 -0.084585 +v 0.647386 0.692060 -0.085701 +v 0.654346 0.685265 -0.085392 +v 0.650999 0.691750 -0.087591 +v 0.650999 0.691750 -0.087591 +v 0.629005 0.696868 -0.086023 +v 0.433085 0.663550 -0.059273 +v 0.432139 0.668519 -0.063935 +v 0.434547 0.658837 -0.054917 +v 0.431248 0.660012 -0.051871 +v 0.429644 0.665174 -0.056429 +v 0.428756 0.670585 -0.061385 +v 0.646619 0.661916 -0.094059 +v 0.645547 0.665632 -0.098164 +v 0.651023 0.666198 -0.095911 +v 0.651992 0.661996 -0.092225 +v 0.649985 0.670665 -0.099468 +v 0.654051 0.670934 -0.098828 +v 0.655146 0.666422 -0.095717 +v 0.656020 0.662177 -0.092324 +v 0.624812 0.675466 -0.059387 +v 0.555033 0.673916 -0.047204 +v 0.555183 0.670971 -0.046369 +v 0.627965 0.672827 -0.059651 +v 0.484964 0.673381 -0.035893 +v 0.482080 0.670883 -0.034148 +v 0.469952 0.666598 -0.032582 +v 0.554216 0.666169 -0.047704 +v 0.638620 0.668404 -0.063127 +v 0.480666 0.692588 -0.052942 +v 0.550067 0.694373 -0.065305 +v 0.548928 0.696867 -0.067847 +v 0.477105 0.694807 -0.054549 +v 0.547101 0.697149 -0.072244 +v 0.464472 0.695386 -0.056650 +v 0.544927 0.653916 -0.067482 +v 0.471664 0.653691 -0.055792 +v 0.617782 0.655533 -0.080662 +v 0.630994 0.655432 -0.078493 +v 0.546848 0.654423 -0.062166 +v 0.461752 0.654357 -0.048329 +v 0.656794 0.679987 -0.071015 +v 0.654853 0.677433 -0.066156 +v 0.658174 0.675771 -0.067109 +v 0.660143 0.678951 -0.072300 +v 0.654853 0.677433 -0.066156 +v 0.658174 0.675771 -0.067109 +v 0.662851 0.674053 -0.068701 +v 0.662851 0.674053 -0.068701 +v 0.663637 0.677834 -0.073753 +v 0.445941 0.686373 -0.042222 +v 0.450063 0.689954 -0.046066 +v 0.446481 0.691381 -0.046569 +v 0.442142 0.686937 -0.041816 +v 0.480666 0.692588 -0.052942 +v 0.477105 0.694807 -0.054549 +v 0.446481 0.691381 -0.046569 +v 0.441373 0.692285 -0.046844 +v 0.441373 0.692285 -0.046844 +v 0.438287 0.687304 -0.041414 +v 0.448323 0.677403 -0.033953 +v 0.452960 0.678427 -0.034473 +v 0.452555 0.682434 -0.038346 +v 0.446973 0.681785 -0.037991 +v 0.452960 0.678427 -0.034473 +v 0.467679 0.680021 -0.037193 +v 0.476405 0.683474 -0.041790 +v 0.452555 0.682434 -0.038346 +v 0.476405 0.683474 -0.041790 +v 0.465793 0.686463 -0.043246 +v 0.450662 0.686527 -0.042046 +v 0.621219 0.677305 -0.058566 +v 0.555158 0.675987 -0.047370 +v 0.606629 0.678967 -0.056854 +v 0.554686 0.678759 -0.048792 +v 0.503151 0.677351 -0.039833 +v 0.488922 0.675249 -0.036741 +v 0.484804 0.691519 -0.051689 +v 0.550634 0.692948 -0.063165 +v 0.499516 0.690573 -0.052152 +v 0.550928 0.690878 -0.060507 +v 0.600996 0.691827 -0.070969 +v 0.615029 0.693208 -0.075263 +v 0.641132 0.691373 -0.081866 +v 0.615029 0.693208 -0.075263 +v 0.600996 0.691827 -0.070969 +v 0.617322 0.689907 -0.074020 +v 0.641132 0.691373 -0.081866 +v 0.632267 0.688053 -0.076987 +v 0.644962 0.688178 -0.082116 +v 0.459091 0.676042 -0.033032 +v 0.453760 0.674508 -0.032079 +v 0.484535 0.678874 -0.038452 +v 0.467679 0.680021 -0.037193 +v 0.652920 0.681156 -0.069566 +v 0.650034 0.678953 -0.064806 +v 0.638150 0.682336 -0.067342 +v 0.623716 0.680977 -0.061753 +v 0.650034 0.678953 -0.064806 +v 0.623716 0.680977 -0.061753 +v 0.445941 0.686373 -0.042222 +v 0.450662 0.686527 -0.042046 +v 0.455509 0.689458 -0.045464 +v 0.450063 0.689954 -0.046066 +v 0.465793 0.686463 -0.043246 +v 0.481795 0.688466 -0.047435 +v 0.648252 0.687414 -0.083941 +v 0.644962 0.688178 -0.082116 +v 0.647419 0.684458 -0.076287 +v 0.651823 0.683377 -0.078057 +v 0.632267 0.688053 -0.076987 +v 0.625349 0.685112 -0.070571 +v 0.550928 0.690878 -0.060507 +v 0.552019 0.684829 -0.055014 +v 0.499516 0.690573 -0.052152 +v 0.481795 0.688466 -0.047435 +v 0.484535 0.678874 -0.038452 +v 0.552019 0.684829 -0.055014 +v 0.503151 0.677351 -0.039833 +v 0.554686 0.678759 -0.048792 +v 0.606629 0.678967 -0.056854 +v 0.617322 0.689907 -0.074020 +v 0.457160 0.681844 -0.071430 +v 0.468556 0.690268 -0.066374 +v 0.544612 0.691642 -0.079260 +v 0.542344 0.683981 -0.085225 +v 0.468556 0.690268 -0.066374 +v 0.544612 0.691642 -0.079260 +v 0.620408 0.691621 -0.091522 +v 0.620408 0.691621 -0.091522 +v 0.626971 0.682819 -0.098294 +v 0.657481 0.664375 -0.090217 +v 0.656380 0.668034 -0.093067 +v 0.653510 0.668298 -0.091248 +v 0.654665 0.665119 -0.088547 +v 0.656380 0.668034 -0.093067 +v 0.654966 0.672083 -0.095792 +v 0.652012 0.672064 -0.094074 +v 0.653510 0.668298 -0.091248 +v 0.652012 0.672064 -0.094074 +v 0.645163 0.671947 -0.090975 +v 0.646591 0.668768 -0.088087 +v 0.647650 0.666442 -0.085684 +v 0.627230 0.660469 -0.068455 +v 0.550697 0.659412 -0.054271 +v 0.638620 0.668404 -0.063127 +v 0.554216 0.666169 -0.047704 +v 0.469952 0.666598 -0.032582 +v 0.473931 0.659353 -0.040843 +v 0.435360 0.658543 -0.042468 +v 0.438584 0.661695 -0.036742 +v 0.441303 0.662807 -0.038774 +v 0.438349 0.659857 -0.044016 +v 0.440928 0.666423 -0.032036 +v 0.443499 0.667110 -0.034400 +v 0.451434 0.668963 -0.038715 +v 0.449425 0.665138 -0.042699 +v 0.446793 0.662414 -0.047379 +v 0.440928 0.666423 -0.032036 +v 0.440713 0.670576 -0.031316 +v 0.443367 0.670793 -0.033634 +v 0.443499 0.667110 -0.034400 +v 0.438979 0.674732 -0.033911 +v 0.441821 0.674481 -0.035942 +v 0.450106 0.675123 -0.039752 +v 0.451396 0.672111 -0.037899 +v 0.451434 0.668963 -0.038715 +v 0.664087 0.668613 -0.072333 +v 0.661371 0.663523 -0.076577 +v 0.658375 0.665149 -0.076383 +v 0.660908 0.669739 -0.072420 +v 0.661371 0.663523 -0.076577 +v 0.658921 0.660188 -0.082403 +v 0.656101 0.661950 -0.081675 +v 0.658375 0.665149 -0.076383 +v 0.648961 0.664834 -0.080111 +v 0.651020 0.667948 -0.075459 +v 0.651020 0.667948 -0.075459 +v 0.653302 0.671994 -0.071805 +v 0.438979 0.674732 -0.033911 +v 0.437278 0.679767 -0.038297 +v 0.440249 0.679061 -0.039990 +v 0.441821 0.674481 -0.035942 +v 0.436476 0.685036 -0.043198 +v 0.439475 0.683862 -0.044514 +v 0.440249 0.679061 -0.039990 +v 0.439475 0.683862 -0.044514 +v 0.448137 0.682631 -0.046782 +v 0.448785 0.678797 -0.043070 +v 0.657947 0.661037 -0.086913 +v 0.655170 0.662400 -0.085642 +v 0.648114 0.664673 -0.083365 +v 0.443031 0.681820 -0.037103 +v 0.444628 0.676914 -0.032748 +v 0.439074 0.681767 -0.036303 +v 0.440882 0.676424 -0.031688 +v 0.440112 0.655383 -0.052561 +v 0.434547 0.658837 -0.054917 +v 0.435735 0.655998 -0.048754 +v 0.431248 0.660012 -0.051871 +v 0.655182 0.682252 -0.078952 +v 0.651186 0.686510 -0.084585 +v 0.658750 0.680968 -0.080001 +v 0.654346 0.685265 -0.085392 +v 0.450467 0.673096 -0.030453 +v 0.445629 0.671687 -0.028952 +v 0.645219 0.675004 -0.101659 +v 0.614402 0.678061 -0.098636 +v 0.645219 0.675004 -0.101659 +v 0.614402 0.678061 -0.098636 +v 0.650628 0.676208 -0.101111 +v 0.436411 0.672836 -0.068390 +v 0.467627 0.676312 -0.075541 +v 0.436411 0.672836 -0.068390 +v 0.432139 0.668519 -0.063935 +v 0.428756 0.670585 -0.061385 +v 0.431830 0.675695 -0.066020 +v 0.648190 0.658327 -0.088248 +v 0.651992 0.661996 -0.092225 +v 0.656020 0.662177 -0.092324 +v 0.653624 0.657986 -0.087983 +v 0.541124 0.678318 -0.087736 +v 0.654966 0.672083 -0.095792 +v 0.656380 0.668034 -0.093067 +v 0.656906 0.667217 -0.094719 +v 0.655660 0.671535 -0.097539 +v 0.657481 0.664375 -0.090217 +v 0.657861 0.663192 -0.091625 +v 0.656906 0.667217 -0.094719 +v 0.657861 0.663192 -0.091625 +v 0.655660 0.671535 -0.097539 +v 0.431483 0.662504 -0.049637 +v 0.429987 0.667374 -0.053972 +v 0.428685 0.666417 -0.054785 +v 0.430277 0.661265 -0.050244 +v 0.429094 0.672452 -0.058659 +v 0.427803 0.671800 -0.059724 +v 0.435360 0.658543 -0.042468 +v 0.433089 0.659076 -0.046356 +v 0.432582 0.657439 -0.046743 +v 0.437395 0.656677 -0.042670 +v 0.432582 0.657439 -0.046743 +v 0.430277 0.661265 -0.050244 +v 0.437395 0.656677 -0.042670 +v 0.653397 0.682487 -0.098878 +v 0.653857 0.676977 -0.098255 +v 0.654245 0.676792 -0.099924 +v 0.651721 0.683098 -0.099869 +v 0.654245 0.676792 -0.099924 +v 0.651721 0.683098 -0.099869 +v 0.429445 0.676960 -0.062250 +v 0.428736 0.676806 -0.063785 +v 0.431237 0.681693 -0.062686 +v 0.432947 0.682300 -0.064761 +v 0.428736 0.676806 -0.063785 +v 0.432947 0.682300 -0.064761 +v 0.431830 0.675695 -0.066020 +v 0.657947 0.661037 -0.086913 +v 0.657735 0.659300 -0.087774 +v 0.658921 0.660188 -0.082403 +v 0.656563 0.658061 -0.082158 +v 0.657735 0.659300 -0.087774 +v 0.656563 0.658061 -0.082158 +v 0.657861 0.663192 -0.091625 +v 0.658921 0.660188 -0.082403 +v 0.661371 0.663523 -0.076577 +v 0.658150 0.661952 -0.075064 +v 0.664087 0.668613 -0.072333 +v 0.662521 0.668054 -0.070307 +v 0.440928 0.666423 -0.032036 +v 0.438584 0.661695 -0.036742 +v 0.442430 0.660389 -0.036134 +v 0.443882 0.665996 -0.030423 +v 0.438584 0.661695 -0.036742 +v 0.435360 0.658543 -0.042468 +v 0.442430 0.660389 -0.036134 +v 0.443882 0.665996 -0.030423 +v 0.654964 0.681700 -0.087960 +v 0.653612 0.686751 -0.090979 +v 0.654006 0.689342 -0.089665 +v 0.655705 0.683418 -0.086789 +v 0.653851 0.689821 -0.093250 +v 0.652257 0.692940 -0.091940 +v 0.654006 0.689342 -0.089665 +v 0.652257 0.692940 -0.091940 +v 0.650999 0.691750 -0.087591 +v 0.654346 0.685265 -0.085392 +v 0.663962 0.675606 -0.076406 +v 0.659411 0.678159 -0.082450 +v 0.660207 0.679426 -0.081429 +v 0.664919 0.676543 -0.075375 +v 0.658750 0.680968 -0.080001 +v 0.664919 0.676543 -0.075375 +v 0.660207 0.679426 -0.081429 +v 0.431237 0.681693 -0.062686 +v 0.434186 0.687070 -0.058703 +v 0.437607 0.688671 -0.060271 +v 0.432947 0.682300 -0.064761 +v 0.436513 0.690429 -0.052834 +v 0.439056 0.692627 -0.053210 +v 0.437607 0.688671 -0.060271 +v 0.653851 0.689821 -0.093250 +v 0.653652 0.687720 -0.096527 +v 0.650789 0.689781 -0.096169 +v 0.653652 0.687720 -0.096527 +v 0.653397 0.682487 -0.098878 +v 0.650789 0.689781 -0.096169 +v 0.664087 0.668613 -0.072333 +v 0.665399 0.672671 -0.072473 +v 0.666024 0.672999 -0.071036 +v 0.662521 0.668054 -0.070307 +v 0.663637 0.677834 -0.073753 +v 0.662851 0.674053 -0.068701 +v 0.662521 0.668054 -0.070307 +v 0.666024 0.672999 -0.071036 +v 0.436476 0.685036 -0.043198 +v 0.437278 0.679767 -0.038297 +v 0.437051 0.680901 -0.036879 +v 0.436272 0.686451 -0.042014 +v 0.438979 0.674732 -0.033911 +v 0.438864 0.675561 -0.032280 +v 0.437051 0.680901 -0.036879 +v 0.438864 0.675561 -0.032280 +v 0.436272 0.686451 -0.042014 +v 0.440713 0.670576 -0.031316 +v 0.441328 0.670878 -0.029440 +v 0.440928 0.666423 -0.032036 +v 0.443882 0.665996 -0.030423 +v 0.441328 0.670878 -0.029440 +v 0.443882 0.665996 -0.030423 +v 0.436513 0.690429 -0.052834 +v 0.436789 0.689294 -0.047792 +v 0.437167 0.691162 -0.047117 +v 0.439056 0.692627 -0.053210 +v 0.437167 0.691162 -0.047117 +v 0.436272 0.686451 -0.042014 +v 0.438287 0.687304 -0.041414 +v 0.643572 0.687096 -0.091905 +v 0.643478 0.684291 -0.089511 +v 0.631411 0.682278 -0.085786 +v 0.631410 0.684636 -0.088222 +v 0.644825 0.680162 -0.086124 +v 0.632560 0.679184 -0.082481 +v 0.631411 0.682278 -0.085786 +v 0.632560 0.679184 -0.082481 +v 0.617277 0.677939 -0.077787 +v 0.616415 0.679628 -0.080847 +v 0.631410 0.684636 -0.088222 +v 0.616297 0.681335 -0.083229 +v 0.448137 0.682631 -0.046782 +v 0.448351 0.685639 -0.050208 +v 0.464715 0.682536 -0.052859 +v 0.464573 0.680918 -0.050777 +v 0.448057 0.686188 -0.054088 +v 0.464426 0.682517 -0.055465 +v 0.485340 0.678048 -0.057128 +v 0.485612 0.678754 -0.056180 +v 0.485562 0.678892 -0.055818 +v 0.634375 0.670248 -0.082501 +v 0.635177 0.669363 -0.080772 +v 0.633198 0.672275 -0.085201 +v 0.618257 0.672910 -0.077796 +v 0.619078 0.672379 -0.075448 +v 0.619533 0.673287 -0.074625 +v 0.466636 0.674976 -0.045556 +v 0.466544 0.672831 -0.046367 +v 0.465817 0.676777 -0.046605 +v 0.485873 0.679007 -0.055287 +v 0.486085 0.678750 -0.055259 +v 0.485841 0.677913 -0.056026 +v 0.637774 0.672876 -0.074208 +v 0.639513 0.675849 -0.071277 +v 0.636186 0.670125 -0.077572 +v 0.637774 0.672876 -0.074208 +v 0.636186 0.670125 -0.077572 +v 0.620133 0.676897 -0.074475 +v 0.621085 0.679095 -0.072819 +v 0.622092 0.680644 -0.070886 +v 0.436476 0.685036 -0.043198 +v 0.436789 0.689294 -0.047792 +v 0.439729 0.687659 -0.048670 +v 0.439475 0.683862 -0.044514 +v 0.436789 0.689294 -0.047792 +v 0.436513 0.690429 -0.052834 +v 0.439448 0.688574 -0.053218 +v 0.439729 0.687659 -0.048670 +v 0.439475 0.683862 -0.044514 +v 0.653851 0.689821 -0.093250 +v 0.653612 0.686751 -0.090979 +v 0.650500 0.685394 -0.091121 +v 0.650660 0.688334 -0.093361 +v 0.654964 0.681700 -0.087960 +v 0.651896 0.680788 -0.087905 +v 0.429094 0.672452 -0.058659 +v 0.429987 0.667374 -0.053972 +v 0.433521 0.667689 -0.054479 +v 0.432657 0.672297 -0.058789 +v 0.431483 0.662504 -0.049637 +v 0.434902 0.663266 -0.050481 +v 0.443884 0.664963 -0.052825 +v 0.442729 0.668484 -0.056091 +v 0.441990 0.672150 -0.059614 +v 0.654964 0.681700 -0.087960 +v 0.659411 0.678159 -0.082450 +v 0.656295 0.677673 -0.082203 +v 0.651896 0.680788 -0.087905 +v 0.663962 0.675606 -0.076406 +v 0.660763 0.675567 -0.076146 +v 0.653080 0.676409 -0.074891 +v 0.648926 0.677740 -0.080561 +v 0.644825 0.680162 -0.086124 +v 0.433089 0.659076 -0.046356 +v 0.436323 0.660227 -0.047519 +v 0.433089 0.659076 -0.046356 +v 0.436323 0.660227 -0.047519 +v 0.445055 0.662556 -0.050397 +v 0.434902 0.663266 -0.050481 +v 0.443884 0.664963 -0.052825 +v 0.434186 0.687070 -0.058703 +v 0.437288 0.685433 -0.058588 +v 0.434186 0.687070 -0.058703 +v 0.431237 0.681693 -0.062686 +v 0.434570 0.680533 -0.062301 +v 0.437288 0.685433 -0.058588 +v 0.443655 0.678927 -0.062269 +v 0.446090 0.683260 -0.058852 +v 0.446090 0.683260 -0.058852 +v 0.653857 0.676977 -0.098255 +v 0.650773 0.676808 -0.096856 +v 0.653397 0.682487 -0.098878 +v 0.650199 0.682030 -0.097978 +v 0.643200 0.681400 -0.095871 +v 0.643878 0.676403 -0.094179 +v 0.645163 0.671947 -0.090975 +v 0.653652 0.687720 -0.096527 +v 0.650421 0.686676 -0.096218 +v 0.653652 0.687720 -0.096527 +v 0.653851 0.689821 -0.093250 +v 0.650660 0.688334 -0.093361 +v 0.650421 0.686676 -0.096218 +v 0.643572 0.687096 -0.091905 +v 0.643341 0.685686 -0.094576 +v 0.643341 0.685686 -0.094576 +v 0.429445 0.676960 -0.062250 +v 0.432941 0.676311 -0.062008 +v 0.442226 0.675374 -0.062209 +v 0.665399 0.672671 -0.072473 +v 0.662158 0.673194 -0.072434 +v 0.665399 0.672671 -0.072473 +v 0.662158 0.673194 -0.072434 +v 0.654406 0.674773 -0.071628 +v 0.654406 0.674773 -0.071628 +v 0.441990 0.672150 -0.059614 +v 0.442729 0.668484 -0.056091 +v 0.460371 0.670840 -0.058421 +v 0.459886 0.672821 -0.060492 +v 0.461100 0.668930 -0.056507 +v 0.460371 0.670840 -0.058421 +v 0.461100 0.668930 -0.056507 +v 0.483186 0.674307 -0.060914 +v 0.483006 0.674180 -0.061108 +v 0.482849 0.674035 -0.061328 +v 0.635854 0.678006 -0.077681 +v 0.639184 0.677936 -0.073136 +v 0.621645 0.679822 -0.071157 +v 0.619453 0.678342 -0.074129 +v 0.461820 0.667630 -0.055050 +v 0.463010 0.667815 -0.052964 +v 0.483804 0.674974 -0.059829 +v 0.483329 0.674401 -0.060696 +v 0.462898 0.680132 -0.058977 +v 0.461066 0.676956 -0.061693 +v 0.462898 0.680132 -0.058977 +v 0.483390 0.674790 -0.060714 +v 0.484410 0.676424 -0.058968 +v 0.484410 0.676424 -0.058968 +v 0.643878 0.676403 -0.094179 +v 0.631977 0.675896 -0.088723 +v 0.631211 0.680146 -0.091057 +v 0.631977 0.675896 -0.088723 +v 0.616318 0.678497 -0.084572 +v 0.617161 0.675349 -0.081556 +v 0.617161 0.675349 -0.081556 +v 0.631217 0.683627 -0.090469 +v 0.631217 0.683627 -0.090469 +v 0.616158 0.680850 -0.084868 +v 0.616158 0.680850 -0.084868 +v 0.640304 0.677478 -0.070827 +v 0.640304 0.677478 -0.070827 +v 0.622470 0.680815 -0.070115 +v 0.622470 0.680815 -0.070115 +v 0.635527 0.669105 -0.079522 +v 0.635527 0.669105 -0.079522 +v 0.635177 0.669363 -0.080772 +v 0.619533 0.673287 -0.074625 +v 0.619730 0.674875 -0.074746 +v 0.450106 0.675123 -0.039752 +v 0.448785 0.678797 -0.043070 +v 0.464973 0.678821 -0.048572 +v 0.465817 0.676777 -0.046605 +v 0.485644 0.678988 -0.055533 +v 0.485873 0.679007 -0.055287 +v -0.646055 0.134130 -0.131160 +v -0.641361 0.134089 -0.134437 +v -0.630199 0.107175 -0.133380 +v -0.634262 0.107248 -0.130350 +v -0.630199 0.107175 -0.133380 +v -0.604049 0.105019 -0.134153 +v -0.588428 0.089494 -0.132750 +v -0.599650 0.087509 -0.131738 +v -0.634262 0.107248 -0.130350 +v -0.630199 0.107175 -0.133380 +v -0.599650 0.087509 -0.131738 +v -0.602195 0.087033 -0.128914 +v -0.614357 0.130360 -0.114516 +v -0.643784 0.132661 -0.116711 +v -0.632158 0.106259 -0.116965 +v -0.606356 0.103930 -0.114914 +v -0.643784 0.132661 -0.116711 +v -0.647557 0.133244 -0.120174 +v -0.635474 0.106684 -0.120174 +v -0.632158 0.106259 -0.116965 +v -0.632158 0.106259 -0.116965 +v -0.635474 0.106684 -0.120174 +v -0.603118 0.086789 -0.119554 +v -0.601158 0.087090 -0.116630 +v -0.601158 0.087090 -0.116630 +v -0.590270 0.088885 -0.115133 +v -0.544230 0.098816 -0.133071 +v -0.484530 0.093093 -0.131189 +v -0.499609 0.079664 -0.130439 +v -0.543906 0.081915 -0.131597 +v -0.543793 0.075344 -0.129933 +v -0.488375 0.074848 -0.128797 +v -0.543793 0.075344 -0.129933 +v -0.488375 0.074848 -0.128797 +v -0.486343 0.073782 -0.125843 +v -0.544009 0.074364 -0.127103 +v -0.544822 0.074242 -0.118062 +v -0.545136 0.075109 -0.115270 +v -0.487262 0.073540 -0.116516 +v -0.489879 0.074430 -0.113719 +v -0.545136 0.075109 -0.115270 +v -0.489879 0.074430 -0.113719 +v -0.501448 0.079056 -0.112837 +v -0.545697 0.081391 -0.113873 +v -0.544416 0.074303 -0.122582 +v -0.486803 0.073661 -0.121179 +v -0.602657 0.086910 -0.124234 +v -0.442837 0.119196 -0.126651 +v -0.443584 0.118756 -0.121186 +v -0.455963 0.089023 -0.120828 +v -0.455359 0.089304 -0.125891 +v -0.444331 0.118314 -0.115721 +v -0.456566 0.088742 -0.115765 +v -0.455963 0.089023 -0.120828 +v -0.456566 0.088742 -0.115765 +v -0.455359 0.089304 -0.125891 +v -0.478875 0.120406 -0.111538 +v -0.546680 0.125344 -0.112560 +v -0.546628 0.097690 -0.113030 +v -0.486835 0.092005 -0.111968 +v -0.446610 0.119779 -0.130116 +v -0.442837 0.119196 -0.126651 +v -0.455359 0.089304 -0.125891 +v -0.458689 0.089988 -0.129108 +v -0.458689 0.089988 -0.129108 +v -0.458689 0.089988 -0.129108 +v -0.444331 0.118314 -0.115721 +v -0.449026 0.118354 -0.112442 +v -0.460642 0.089075 -0.112739 +v -0.456566 0.088742 -0.115765 +v -0.460642 0.089075 -0.112739 +v -0.646806 0.133686 -0.125667 +v -0.634868 0.106966 -0.125262 +v -0.646055 0.134130 -0.131160 +v -0.634262 0.107248 -0.130350 +v -0.634868 0.106966 -0.125262 +v -0.544859 0.165257 -0.112294 +v -0.616333 0.167855 -0.114110 +v -0.473246 0.162748 -0.111443 +v -0.470134 0.229304 -0.110404 +v -0.543234 0.229446 -0.111164 +v -0.616193 0.229678 -0.112894 +v -0.439096 0.163426 -0.130709 +v -0.435124 0.162952 -0.127145 +v -0.435303 0.231053 -0.129797 +v -0.431244 0.230720 -0.126223 +v -0.441715 0.161776 -0.112466 +v -0.436744 0.161931 -0.115863 +v -0.432881 0.229679 -0.114890 +v -0.437951 0.229370 -0.111472 +v -0.650563 0.170104 -0.125520 +v -0.649749 0.170617 -0.131190 +v -0.651377 0.169590 -0.119849 +v -0.651972 0.230239 -0.118612 +v -0.651149 0.230762 -0.124307 +v -0.650326 0.231286 -0.130002 +v -0.647557 0.133244 -0.120174 +v -0.647404 0.169116 -0.116288 +v -0.651377 0.169590 -0.119849 +v -0.647913 0.229907 -0.115040 +v -0.651972 0.230239 -0.118612 +v -0.649749 0.170617 -0.131190 +v -0.644778 0.170772 -0.134585 +v -0.650326 0.231286 -0.130002 +v -0.645257 0.231595 -0.133418 +v -0.435934 0.162441 -0.121504 +v -0.436744 0.161931 -0.115863 +v -0.435124 0.162952 -0.127145 +v -0.431244 0.230720 -0.126223 +v -0.432063 0.230200 -0.120557 +v -0.432881 0.229679 -0.114890 +v -0.436409 0.327464 -0.126795 +v -0.432374 0.327198 -0.123213 +v -0.439584 0.424907 -0.123115 +v -0.435637 0.424636 -0.119526 +v -0.439056 0.325780 -0.108469 +v -0.471066 0.325237 -0.107450 +v -0.434011 0.326158 -0.111880 +v -0.437274 0.423596 -0.108193 +v -0.442229 0.423222 -0.104787 +v -0.473610 0.422703 -0.103803 +v -0.651091 0.323973 -0.121638 +v -0.650270 0.324499 -0.127335 +v -0.651914 0.323449 -0.115942 +v -0.650865 0.421052 -0.112492 +v -0.650044 0.421577 -0.118190 +v -0.649243 0.422119 -0.123904 +v -0.647879 0.323185 -0.112363 +v -0.651914 0.323449 -0.115942 +v -0.616333 0.323433 -0.110168 +v -0.616003 0.421008 -0.106678 +v -0.646920 0.420784 -0.108908 +v -0.650865 0.421052 -0.112492 +v -0.650270 0.324499 -0.127335 +v -0.645232 0.324881 -0.130749 +v -0.649243 0.422119 -0.123904 +v -0.644333 0.422531 -0.127348 +v -0.433193 0.326678 -0.117547 +v -0.434011 0.326158 -0.111880 +v -0.432374 0.327198 -0.123213 +v -0.435637 0.424636 -0.119526 +v -0.436455 0.424117 -0.113860 +v -0.437274 0.423596 -0.108193 +v -0.543769 0.324291 -0.108324 +v -0.544876 0.421810 -0.104756 +v -0.440991 0.548986 -0.100410 +v -0.440172 0.549507 -0.106076 +v -0.441950 0.599832 -0.097697 +v -0.442757 0.599247 -0.092054 +v -0.439353 0.550026 -0.111742 +v -0.441147 0.600420 -0.103343 +v -0.446073 0.646807 -0.089648 +v -0.446761 0.645742 -0.084139 +v -0.447485 0.644708 -0.078663 +v -0.611179 0.550990 -0.097443 +v -0.543469 0.549956 -0.096102 +v -0.542589 0.601156 -0.087458 +v -0.608543 0.602863 -0.088590 +v -0.475619 0.549011 -0.095729 +v -0.476497 0.599549 -0.087291 +v -0.480229 0.643516 -0.074562 +v -0.544461 0.642903 -0.075758 +v -0.608568 0.642465 -0.077889 +v -0.439353 0.550026 -0.111742 +v -0.443103 0.550425 -0.115309 +v -0.444813 0.600916 -0.106899 +v -0.441147 0.600420 -0.103343 +v -0.472649 0.551115 -0.117414 +v -0.473662 0.601973 -0.108967 +v -0.477909 0.647822 -0.095783 +v -0.449756 0.647515 -0.093238 +v -0.444813 0.600916 -0.106899 +v -0.449756 0.647515 -0.093238 +v -0.445732 0.548727 -0.096967 +v -0.447381 0.598990 -0.088614 +v -0.440991 0.548986 -0.100410 +v -0.442757 0.599247 -0.092054 +v -0.447485 0.644708 -0.078663 +v -0.451947 0.644040 -0.075392 +v -0.642832 0.553123 -0.114487 +v -0.643528 0.552491 -0.108678 +v -0.640043 0.604827 -0.099682 +v -0.639419 0.605573 -0.105520 +v -0.644333 0.551953 -0.102967 +v -0.640828 0.604217 -0.093988 +v -0.639996 0.643128 -0.083640 +v -0.639295 0.644191 -0.089169 +v -0.638793 0.645422 -0.094874 +v -0.540630 0.552380 -0.119007 +v -0.540010 0.604017 -0.110460 +v -0.608641 0.553463 -0.119534 +v -0.606331 0.605820 -0.110841 +v -0.606897 0.647327 -0.099709 +v -0.542458 0.647762 -0.098318 +v -0.644333 0.551953 -0.102967 +v -0.640602 0.551570 -0.099419 +v -0.637200 0.603754 -0.090468 +v -0.640828 0.604217 -0.093988 +v -0.636436 0.642526 -0.080163 +v -0.637200 0.603754 -0.090468 +v -0.636436 0.642526 -0.080163 +v -0.638363 0.553612 -0.118168 +v -0.635197 0.606171 -0.109316 +v -0.642832 0.553123 -0.114487 +v -0.639419 0.605573 -0.105520 +v -0.638793 0.645422 -0.094874 +v -0.634836 0.646518 -0.098592 +v -0.639956 0.658785 -0.071008 +v -0.643539 0.659640 -0.074469 +v -0.612810 0.661266 -0.067520 +v -0.639956 0.658785 -0.071008 +v -0.639956 0.658785 -0.071008 +v -0.612810 0.661266 -0.067520 +v -0.618411 0.665701 -0.059596 +v -0.645461 0.660660 -0.064781 +v -0.643539 0.659640 -0.074469 +v -0.649296 0.661942 -0.068505 +v -0.639050 0.666236 -0.088262 +v -0.612063 0.670347 -0.088137 +v -0.634836 0.646518 -0.098592 +v -0.642728 0.664012 -0.084907 +v -0.639050 0.666236 -0.088262 +v -0.648958 0.668445 -0.077959 +v -0.645482 0.672091 -0.080987 +v -0.645482 0.672091 -0.080987 +v -0.618945 0.680076 -0.079703 +v -0.455862 0.683012 -0.065856 +v -0.456401 0.680923 -0.060737 +v -0.455445 0.685188 -0.071079 +v -0.463318 0.711581 -0.054760 +v -0.463399 0.708168 -0.049643 +v -0.463774 0.704863 -0.044742 +v -0.550499 0.668164 -0.062497 +v -0.488100 0.675444 -0.058377 +v -0.495106 0.694259 -0.043908 +v -0.556769 0.679589 -0.051218 +v -0.550499 0.668164 -0.062497 +v -0.556769 0.679589 -0.051218 +v -0.459333 0.686299 -0.074821 +v -0.486899 0.684162 -0.078670 +v -0.459333 0.686299 -0.074821 +v -0.495257 0.708537 -0.064449 +v -0.467632 0.713232 -0.058968 +v -0.467632 0.713232 -0.058968 +v -0.460652 0.679171 -0.057856 +v -0.456401 0.680923 -0.060737 +v -0.463774 0.704863 -0.044742 +v -0.467957 0.701720 -0.042076 +v -0.643031 0.661732 -0.079598 +v -0.649296 0.661942 -0.068505 +v -0.649052 0.665084 -0.073182 +v -0.549601 0.677583 -0.083996 +v -0.557312 0.694860 -0.072768 +v -0.634937 0.701629 -0.059431 +v -0.636734 0.702756 -0.062340 +v -0.659427 0.691300 -0.065790 +v -0.657327 0.691678 -0.064259 +v -0.644844 0.700027 -0.067704 +v -0.662553 0.689730 -0.067577 +v -0.659427 0.691300 -0.065790 +v -0.662553 0.689730 -0.067577 +v -0.663860 0.683138 -0.064197 +v -0.661242 0.685360 -0.063573 +v -0.657327 0.691678 -0.064259 +v -0.658732 0.687169 -0.063052 +v -0.464241 0.723926 -0.047086 +v -0.464041 0.719712 -0.041637 +v -0.462012 0.727839 -0.044818 +v -0.461656 0.723290 -0.039002 +v -0.462029 0.718704 -0.033633 +v -0.464386 0.715539 -0.036543 +v -0.654580 0.660760 -0.066796 +v -0.654600 0.664399 -0.071148 +v -0.649052 0.665084 -0.073182 +v -0.658479 0.659747 -0.066987 +v -0.658621 0.663447 -0.071060 +v -0.654600 0.664399 -0.071148 +v -0.658621 0.663447 -0.071060 +v -0.658646 0.667510 -0.074899 +v -0.654637 0.668330 -0.075418 +v -0.654637 0.668330 -0.075418 +v -0.648958 0.668445 -0.077959 +v -0.637298 0.684923 -0.038140 +v -0.639468 0.681531 -0.037934 +v -0.575784 0.699407 -0.026899 +v -0.576419 0.702091 -0.028236 +v -0.647494 0.674151 -0.040312 +v -0.573413 0.694941 -0.027354 +v -0.500199 0.718149 -0.015163 +v -0.512222 0.718867 -0.017215 +v -0.515491 0.720155 -0.019365 +v -0.515694 0.736718 -0.039456 +v -0.512892 0.739526 -0.041425 +v -0.575716 0.722119 -0.052495 +v -0.576266 0.719854 -0.049572 +v -0.501521 0.742941 -0.043829 +v -0.573760 0.722194 -0.056845 +v -0.495106 0.694259 -0.043908 +v -0.495749 0.701614 -0.035393 +v -0.559627 0.682529 -0.044559 +v -0.487860 0.706405 -0.028386 +v -0.562093 0.683630 -0.039412 +v -0.635522 0.661613 -0.053040 +v -0.623411 0.664631 -0.055429 +v -0.665652 0.679807 -0.049155 +v -0.668479 0.677649 -0.050290 +v -0.666360 0.675860 -0.044793 +v -0.663736 0.678533 -0.044108 +v -0.671412 0.675345 -0.051578 +v -0.670127 0.672702 -0.046055 +v -0.666360 0.675860 -0.044793 +v -0.670127 0.672702 -0.046055 +v -0.663736 0.678533 -0.044108 +v -0.484176 0.740884 -0.028995 +v -0.480727 0.742583 -0.028636 +v -0.485500 0.744948 -0.033960 +v -0.488536 0.742660 -0.033257 +v -0.477169 0.744112 -0.028245 +v -0.480969 0.747158 -0.034386 +v -0.484461 0.733090 -0.019316 +v -0.484143 0.736952 -0.024040 +v -0.489364 0.736070 -0.024414 +v -0.488935 0.732767 -0.019943 +v -0.488532 0.739831 -0.028786 +v -0.501749 0.735944 -0.029466 +v -0.510371 0.730796 -0.027186 +v -0.502127 0.730315 -0.022404 +v -0.577113 0.703979 -0.028766 +v -0.634670 0.687679 -0.037747 +v -0.519515 0.720785 -0.020442 +v -0.532376 0.718880 -0.023363 +v -0.577352 0.706497 -0.030646 +v -0.622437 0.693011 -0.036842 +v -0.576546 0.718696 -0.047225 +v -0.519197 0.734870 -0.037951 +v -0.632151 0.701732 -0.056882 +v -0.619760 0.704458 -0.052909 +v -0.576416 0.717095 -0.044249 +v -0.531830 0.730383 -0.037756 +v -0.653821 0.692886 -0.061997 +v -0.656136 0.689000 -0.061475 +v -0.653821 0.692886 -0.061997 +v -0.645455 0.692646 -0.056932 +v -0.633192 0.698354 -0.054927 +v -0.632151 0.701732 -0.056882 +v -0.619760 0.704458 -0.052909 +v -0.488621 0.729316 -0.016831 +v -0.493793 0.729257 -0.017935 +v -0.484461 0.733090 -0.019316 +v -0.488935 0.732767 -0.019943 +v -0.493793 0.729257 -0.017935 +v -0.516531 0.724998 -0.022882 +v -0.516531 0.724998 -0.022882 +v -0.665652 0.679807 -0.049155 +v -0.663736 0.678533 -0.044108 +v -0.659944 0.681388 -0.043159 +v -0.662588 0.682129 -0.048011 +v -0.659944 0.681388 -0.043159 +v -0.637589 0.690091 -0.041381 +v -0.637589 0.690091 -0.041381 +v -0.650099 0.687130 -0.046524 +v -0.493346 0.740908 -0.032474 +v -0.516033 0.733365 -0.033368 +v -0.658732 0.687169 -0.063052 +v -0.661393 0.683290 -0.056607 +v -0.657882 0.685693 -0.055161 +v -0.656136 0.689000 -0.061475 +v -0.639205 0.692422 -0.050478 +v -0.645455 0.692646 -0.056932 +v -0.576108 0.711974 -0.037796 +v -0.576416 0.717095 -0.044249 +v -0.576108 0.711974 -0.037796 +v -0.633192 0.698354 -0.054927 +v -0.622437 0.693011 -0.036842 +v -0.577352 0.706497 -0.030646 +v -0.532376 0.718880 -0.023363 +v -0.489727 0.729870 -0.055885 +v -0.564633 0.709029 -0.067235 +v -0.569360 0.716573 -0.062745 +v -0.502736 0.735733 -0.052186 +v -0.638121 0.685359 -0.077281 +v -0.635382 0.696275 -0.072440 +v -0.644844 0.700027 -0.067704 +v -0.573760 0.722194 -0.056845 +v -0.502736 0.735733 -0.052186 +v -0.569360 0.716573 -0.062745 +v -0.660637 0.661741 -0.065322 +v -0.658585 0.663320 -0.063951 +v -0.658202 0.666209 -0.067152 +v -0.660432 0.665044 -0.068754 +v -0.658585 0.663320 -0.063951 +v -0.654700 0.665582 -0.062558 +v -0.654185 0.667686 -0.065318 +v -0.658202 0.666209 -0.067152 +v -0.653525 0.670627 -0.068706 +v -0.657649 0.669732 -0.070573 +v -0.657649 0.669732 -0.070573 +v -0.660045 0.668825 -0.072126 +v -0.567704 0.688514 -0.032576 +v -0.634610 0.668702 -0.044364 +v -0.500808 0.709206 -0.021705 +v -0.567704 0.688514 -0.032576 +v -0.500808 0.709206 -0.021705 +v -0.634610 0.668702 -0.044364 +v -0.466164 0.717669 -0.024183 +v -0.469195 0.717733 -0.025987 +v -0.473208 0.720525 -0.021382 +v -0.470515 0.720644 -0.019150 +v -0.477078 0.716769 -0.029898 +v -0.480742 0.719400 -0.025739 +v -0.484074 0.723142 -0.022452 +v -0.476820 0.724671 -0.017857 +v -0.474404 0.725194 -0.015384 +v -0.474404 0.725194 -0.015384 +v -0.476820 0.724671 -0.017857 +v -0.477789 0.728312 -0.017745 +v -0.475420 0.729291 -0.015403 +v -0.484074 0.723142 -0.022452 +v -0.485004 0.726292 -0.022174 +v -0.484494 0.729216 -0.024511 +v -0.477201 0.731861 -0.020643 +v -0.475420 0.729291 -0.015403 +v -0.477789 0.728312 -0.017745 +v -0.477201 0.731861 -0.020643 +v -0.474766 0.733286 -0.018661 +v -0.669328 0.666753 -0.048566 +v -0.666924 0.668511 -0.048985 +v -0.662942 0.664268 -0.052041 +v -0.665011 0.662045 -0.051806 +v -0.662606 0.671478 -0.049952 +v -0.659032 0.667720 -0.052808 +v -0.655871 0.664612 -0.056812 +v -0.659514 0.661043 -0.056653 +v -0.661343 0.658655 -0.056917 +v -0.476726 0.735972 -0.025409 +v -0.474275 0.737809 -0.023837 +v -0.477201 0.731861 -0.020643 +v -0.484494 0.729216 -0.024511 +v -0.484041 0.732520 -0.028412 +v -0.476726 0.735972 -0.025409 +v -0.484257 0.735710 -0.032742 +v -0.477045 0.739982 -0.030695 +v -0.477045 0.739982 -0.030695 +v -0.474677 0.742207 -0.029575 +v -0.661343 0.658655 -0.056917 +v -0.659514 0.661043 -0.056653 +v -0.658491 0.661086 -0.060622 +v -0.660355 0.658999 -0.061491 +v -0.659514 0.661043 -0.056653 +v -0.655871 0.664612 -0.056812 +v -0.654799 0.664166 -0.059973 +v -0.658491 0.661086 -0.060622 +v -0.480865 0.733897 -0.017986 +v -0.480439 0.738273 -0.023111 +v -0.477211 0.734694 -0.016799 +v -0.476690 0.739501 -0.022254 +v -0.468567 0.711268 -0.033499 +v -0.467957 0.701720 -0.042076 +v -0.465186 0.714263 -0.029801 +v -0.468567 0.711268 -0.033499 +v -0.465186 0.714263 -0.029801 +v -0.468567 0.711268 -0.033499 +v -0.495749 0.701614 -0.035393 +v -0.661242 0.685360 -0.063573 +v -0.664230 0.681110 -0.057341 +v -0.663860 0.683138 -0.064197 +v -0.667213 0.678692 -0.058203 +v -0.671412 0.675345 -0.051578 +v -0.668479 0.677649 -0.050290 +v -0.485198 0.729191 -0.014945 +v -0.480388 0.729434 -0.013219 +v -0.485198 0.729191 -0.014945 +v -0.480388 0.729434 -0.013219 +v -0.488621 0.729316 -0.016831 +v -0.648958 0.668445 -0.077959 +v -0.651480 0.673221 -0.078467 +v -0.656917 0.672966 -0.078147 +v -0.625376 0.683920 -0.077029 +v -0.497008 0.720936 -0.058749 +v -0.468942 0.726262 -0.052093 +v -0.465889 0.731140 -0.050198 +v -0.468942 0.726262 -0.052093 +v -0.465889 0.731140 -0.050198 +v -0.650484 0.658830 -0.062381 +v -0.655491 0.657068 -0.062069 +v -0.561574 0.703358 -0.068727 +v -0.660440 0.667821 -0.073760 +v -0.660595 0.663849 -0.070245 +v -0.660440 0.667821 -0.073760 +v -0.660595 0.663849 -0.070245 +v -0.660595 0.663849 -0.070245 +v -0.660573 0.660285 -0.066506 +v -0.660573 0.660285 -0.066506 +v -0.463105 0.721354 -0.031875 +v -0.461560 0.720434 -0.032237 +v -0.461196 0.725010 -0.037587 +v -0.462767 0.725668 -0.036975 +v -0.461560 0.720434 -0.032237 +v -0.461196 0.725010 -0.037587 +v -0.461552 0.729533 -0.043381 +v -0.461552 0.729533 -0.043381 +v -0.463041 0.729948 -0.042468 +v -0.466164 0.717669 -0.024183 +v -0.467366 0.715420 -0.023957 +v -0.462877 0.716756 -0.028131 +v -0.463887 0.718192 -0.028068 +v -0.467366 0.715420 -0.023957 +v -0.462877 0.716756 -0.028131 +v -0.462877 0.716756 -0.028131 +v -0.463887 0.718192 -0.028068 +v -0.462877 0.716756 -0.028131 +v -0.461560 0.720434 -0.032237 +v -0.463105 0.721354 -0.031875 +v -0.661284 0.678584 -0.076969 +v -0.659993 0.679349 -0.078153 +v -0.660453 0.672774 -0.077033 +v -0.660206 0.673358 -0.075393 +v -0.659993 0.679349 -0.078153 +v -0.660453 0.672774 -0.077033 +v -0.463558 0.733341 -0.048250 +v -0.464417 0.733508 -0.046801 +v -0.463558 0.733341 -0.048250 +v -0.463558 0.733341 -0.048250 +v -0.468909 0.737250 -0.050137 +v -0.468909 0.737250 -0.050137 +v -0.467443 0.737380 -0.048089 +v -0.659641 0.657258 -0.062052 +v -0.659641 0.657258 -0.062052 +v -0.658705 0.657240 -0.056393 +v -0.660355 0.658999 -0.061491 +v -0.661343 0.658655 -0.056917 +v -0.661888 0.661547 -0.050181 +v -0.665011 0.662045 -0.051806 +v -0.661888 0.661547 -0.050181 +v -0.668009 0.666878 -0.046577 +v -0.668009 0.666878 -0.046577 +v -0.669328 0.666753 -0.048566 +v -0.474404 0.725194 -0.015384 +v -0.477011 0.724332 -0.013641 +v -0.473562 0.718596 -0.018193 +v -0.470515 0.720644 -0.019150 +v -0.473562 0.718596 -0.018193 +v -0.467366 0.715420 -0.023957 +v -0.466164 0.717669 -0.024183 +v -0.663276 0.679176 -0.066108 +v -0.664547 0.680773 -0.065268 +v -0.664445 0.686357 -0.069137 +v -0.663213 0.683837 -0.069946 +v -0.663860 0.683138 -0.064197 +v -0.662553 0.689730 -0.067577 +v -0.664445 0.686357 -0.069137 +v -0.663809 0.689775 -0.072086 +v -0.663809 0.689775 -0.072086 +v -0.664161 0.686291 -0.072725 +v -0.670919 0.672714 -0.053802 +v -0.672167 0.673490 -0.052967 +v -0.668078 0.676582 -0.059360 +v -0.666890 0.675451 -0.060130 +v -0.667213 0.678692 -0.058203 +v -0.475365 0.742707 -0.046848 +v -0.472046 0.742248 -0.045159 +v -0.475365 0.742707 -0.046848 +v -0.478433 0.747109 -0.040676 +v -0.475606 0.745702 -0.040008 +v -0.661333 0.686464 -0.075733 +v -0.663162 0.683830 -0.075577 +v -0.663809 0.689775 -0.072086 +v -0.661333 0.686464 -0.075733 +v -0.663162 0.683830 -0.075577 +v -0.661284 0.678584 -0.076969 +v -0.669328 0.666753 -0.048566 +v -0.668009 0.666878 -0.046577 +v -0.672544 0.670515 -0.048113 +v -0.671721 0.670175 -0.049437 +v -0.672544 0.670515 -0.048113 +v -0.474959 0.743794 -0.028655 +v -0.474471 0.739176 -0.022637 +v -0.474959 0.743794 -0.028655 +v -0.474471 0.739176 -0.022637 +v -0.474998 0.734369 -0.017200 +v -0.474998 0.734369 -0.017200 +v -0.476180 0.729728 -0.013596 +v -0.474998 0.734369 -0.017200 +v -0.477211 0.734694 -0.016799 +v -0.476180 0.729728 -0.013596 +v -0.477011 0.724332 -0.013641 +v -0.474404 0.725194 -0.015384 +v -0.476777 0.747165 -0.034496 +v -0.475880 0.745378 -0.034850 +v -0.475880 0.745378 -0.034850 +v -0.476777 0.747165 -0.034496 +v -0.656228 0.685246 -0.072284 +v -0.649628 0.683499 -0.071269 +v -0.649119 0.681660 -0.068428 +v -0.655500 0.683017 -0.069423 +v -0.641993 0.680772 -0.069912 +v -0.641774 0.679492 -0.067214 +v -0.642333 0.678123 -0.063848 +v -0.649567 0.678936 -0.064612 +v -0.655845 0.679283 -0.065374 +v -0.497827 0.728122 -0.036376 +v -0.498282 0.729236 -0.038757 +v -0.485086 0.737913 -0.036660 +v -0.515099 0.718549 -0.040965 +v -0.515079 0.718292 -0.041386 +v -0.514419 0.717352 -0.042405 +v -0.497757 0.728772 -0.041427 +v -0.484684 0.737849 -0.040607 +v -0.649417 0.669147 -0.061201 +v -0.648778 0.669922 -0.063053 +v -0.643405 0.673504 -0.059871 +v -0.642643 0.672627 -0.060528 +v -0.641838 0.672988 -0.062970 +v -0.648039 0.671735 -0.066075 +v -0.492060 0.715328 -0.036648 +v -0.494992 0.717572 -0.033393 +v -0.511234 0.713686 -0.045058 +v -0.513182 0.715387 -0.043006 +v -0.515069 0.717235 -0.041013 +v -0.497711 0.720503 -0.030649 +v -0.497711 0.720503 -0.030649 +v -0.498531 0.722749 -0.030145 +v -0.515069 0.717235 -0.041013 +v -0.515728 0.718304 -0.040247 +v -0.515561 0.718683 -0.040335 +v -0.498170 0.724554 -0.031491 +v -0.656074 0.675637 -0.053037 +v -0.653361 0.672841 -0.055390 +v -0.648280 0.680456 -0.057473 +v -0.646721 0.678939 -0.059122 +v -0.645044 0.676827 -0.060377 +v -0.650825 0.670134 -0.058206 +v -0.478090 0.742806 -0.035460 +v -0.478090 0.742806 -0.035460 +v -0.477780 0.743001 -0.040097 +v -0.477780 0.743001 -0.040097 +v -0.475606 0.745702 -0.040008 +v -0.664161 0.686291 -0.072725 +v -0.661003 0.685586 -0.072714 +v -0.660165 0.683226 -0.069988 +v -0.663213 0.683837 -0.069946 +v -0.660165 0.683226 -0.069988 +v -0.655500 0.683017 -0.069423 +v -0.655845 0.679283 -0.065374 +v -0.660408 0.679004 -0.066033 +v -0.663213 0.683837 -0.069946 +v -0.663276 0.679176 -0.066108 +v -0.466292 0.728688 -0.042634 +v -0.466099 0.724800 -0.037594 +v -0.474378 0.725299 -0.043636 +v -0.474288 0.722211 -0.039527 +v -0.474621 0.719095 -0.035704 +v -0.466432 0.720884 -0.032902 +v -0.663276 0.679176 -0.066108 +v -0.660408 0.679004 -0.066033 +v -0.664112 0.675726 -0.059939 +v -0.666890 0.675451 -0.060130 +v -0.659457 0.676723 -0.059523 +v -0.663436 0.675197 -0.053762 +v -0.668190 0.673439 -0.053674 +v -0.670919 0.672714 -0.053802 +v -0.467128 0.718093 -0.029473 +v -0.463887 0.718192 -0.028068 +v -0.475228 0.716887 -0.032900 +v -0.475606 0.745702 -0.040008 +v -0.477780 0.743001 -0.040097 +v -0.474464 0.739778 -0.044805 +v -0.472046 0.742248 -0.045159 +v -0.484684 0.737849 -0.040607 +v -0.481596 0.734808 -0.044819 +v -0.477748 0.730800 -0.047446 +v -0.470226 0.735327 -0.047565 +v -0.467443 0.737380 -0.048089 +v -0.660045 0.668825 -0.072126 +v -0.657649 0.669732 -0.070573 +v -0.657622 0.674109 -0.074127 +v -0.660206 0.673358 -0.075393 +v -0.653525 0.670627 -0.068706 +v -0.653345 0.674682 -0.072638 +v -0.653997 0.679323 -0.075184 +v -0.658477 0.679017 -0.076144 +v -0.661284 0.678584 -0.076969 +v -0.660118 0.683623 -0.075231 +v -0.663162 0.683830 -0.075577 +v -0.655431 0.683544 -0.074667 +v -0.660118 0.683623 -0.075231 +v -0.655431 0.683544 -0.074667 +v -0.663162 0.683830 -0.075577 +v -0.467488 0.731863 -0.046512 +v -0.464417 0.733508 -0.046801 +v -0.475348 0.727845 -0.046764 +v -0.467488 0.731863 -0.046512 +v -0.475348 0.727845 -0.046764 +v -0.669097 0.671405 -0.049625 +v -0.671721 0.670175 -0.049437 +v -0.664461 0.673808 -0.050280 +v -0.669097 0.671405 -0.049625 +v -0.664461 0.673808 -0.050280 +v -0.671721 0.670175 -0.049437 +v -0.489815 0.719602 -0.045070 +v -0.489883 0.717950 -0.042665 +v -0.509616 0.712603 -0.046698 +v -0.509877 0.712766 -0.046459 +v -0.510157 0.712890 -0.046249 +v -0.490197 0.716265 -0.040433 +v -0.652726 0.677661 -0.059693 +v -0.644821 0.678478 -0.060278 +v -0.647589 0.679752 -0.057591 +v -0.656220 0.677388 -0.055229 +v -0.490638 0.715081 -0.038754 +v -0.510381 0.712996 -0.046001 +v -0.497757 0.728772 -0.041427 +v -0.495187 0.726173 -0.044650 +v -0.514419 0.717352 -0.042405 +v -0.512558 0.715372 -0.044318 +v -0.510592 0.713435 -0.046111 +v -0.492143 0.723053 -0.046932 +v -0.647658 0.674949 -0.070206 +v -0.653345 0.674682 -0.072638 +v -0.641220 0.675032 -0.067170 +v -0.647658 0.674949 -0.070206 +v -0.641220 0.675032 -0.067170 +v -0.641103 0.677809 -0.070753 +v -0.647973 0.678826 -0.073277 +v -0.649007 0.682227 -0.073318 +v -0.641607 0.680071 -0.071471 +v -0.649007 0.682227 -0.073318 +v -0.641607 0.680071 -0.071471 +v -0.490388 0.721035 -0.046856 +v -0.509684 0.712626 -0.046782 +v -0.490388 0.721035 -0.046856 +v -0.509684 0.712626 -0.046782 +v -0.657327 0.677019 -0.052884 +v -0.648751 0.680638 -0.056735 +v -0.657327 0.677019 -0.052884 +v -0.648751 0.680638 -0.056735 +v -0.655871 0.664612 -0.056812 +v -0.650825 0.670134 -0.058206 +v -0.649767 0.669023 -0.059936 +v -0.654799 0.664166 -0.059973 +v -0.644048 0.674955 -0.060280 +v -0.649767 0.669023 -0.059936 +v -0.643405 0.673504 -0.059871 +v -0.649417 0.669147 -0.061201 +v -0.649767 0.669023 -0.059936 +v -0.498170 0.724554 -0.031491 +v -0.497778 0.726405 -0.033806 +v -0.515561 0.718683 -0.040335 +v -0.515256 0.718693 -0.040633 +v 0.464969 0.669992 -0.049465 +v 0.466544 0.672831 -0.046367 +v 0.485841 0.677913 -0.056026 +v 0.484862 0.676391 -0.057914 +v -0.623372 0.645919 -0.034070 +v -0.611342 0.620295 -0.029559 +v -0.596330 0.650547 -0.028334 +v -0.588108 0.635626 -0.025772 +v -0.568512 0.634292 -0.020738 +v -0.567454 0.623486 -0.019725 +v -0.613732 0.587631 -0.021704 +v -0.478708 0.723045 0.023956 +v -0.476193 0.722588 0.020993 +v -0.494680 0.719512 0.022574 +v -0.478708 0.723045 0.023956 +v -0.572361 0.680106 -0.007847 +v -0.562735 0.677289 -0.004834 +v -0.562173 0.681011 0.004299 +v -0.573064 0.683635 0.001038 +v -0.562735 0.677289 -0.004834 +v -0.557654 0.665885 -0.003198 +v -0.556665 0.669343 0.005790 +v -0.562173 0.681011 0.004299 +v -0.562173 0.681011 0.004299 +v -0.556665 0.669343 0.005790 +v -0.546595 0.674350 0.013297 +v -0.555146 0.689471 0.011383 +v -0.573064 0.683635 0.001038 +v -0.676650 0.667194 -0.042410 +v -0.679224 0.667737 -0.039463 +v -0.660258 0.670120 -0.040919 +v -0.676650 0.667194 -0.042410 +v -0.679630 0.669414 -0.033951 +v -0.680036 0.671091 -0.028438 +v -0.477396 0.717576 0.005985 +v -0.475386 0.719252 0.010025 +v -0.477396 0.717576 0.005985 +v -0.475790 0.720920 0.015509 +v -0.677967 0.672679 -0.024387 +v -0.677967 0.672679 -0.024387 +v -0.549984 0.646174 -0.016106 +v -0.524864 0.641865 -0.010094 +v -0.570214 0.645399 0.005827 +v -0.589783 0.646011 0.001327 +v -0.613089 0.629752 -0.002728 +v -0.569241 0.633778 0.007323 +v -0.535531 0.737446 0.010827 +v -0.534469 0.709078 0.015653 +v -0.520894 0.681687 0.018829 +v -0.628461 0.705552 -0.037107 +v -0.619003 0.678229 -0.033463 +v -0.591593 0.669964 -0.027263 +v -0.536470 0.765204 -0.005821 +v -0.536315 0.753930 0.002784 +v -0.632070 0.732267 -0.052903 +v -0.631685 0.721481 -0.044404 +v -0.540793 1.009467 -0.049343 +v -0.546453 0.942294 -0.042817 +v -0.589344 0.939746 -0.045727 +v -0.506364 0.960201 -0.039855 +v -0.536376 0.895974 -0.040498 +v -0.562851 0.888653 -0.042382 +v -0.570001 0.906877 -0.042954 +v -0.588861 0.908236 -0.044497 +v -0.633671 0.923049 -0.027289 +v -0.591218 0.946173 -0.024045 +v -0.673885 0.916414 -0.030303 +v -0.641117 0.872176 -0.032343 +v -0.614639 0.879438 -0.030462 +v -0.608853 0.901324 -0.028190 +v -0.590463 0.913799 -0.026061 +v -0.537046 0.779233 -0.012259 +v -0.631713 0.772812 -0.060760 +v -0.632161 0.745995 -0.058993 +v -0.613908 0.547683 -0.006883 +v -0.612039 0.504596 0.015153 +v -0.520218 0.617834 0.021215 +v -0.517531 0.576827 0.032693 +v -0.514927 0.533395 0.049623 +v -0.507241 0.465778 0.088915 +v -0.508084 0.445709 0.106918 +v -0.552601 0.440410 0.106205 +v -0.508084 0.445709 0.106918 +v -0.510838 0.434279 0.119188 +v -0.475825 0.449359 0.106966 +v -0.485355 0.439010 0.116965 +v -0.510695 0.422318 0.120666 +v -0.478745 0.429949 0.115599 +v -0.510486 0.418439 0.118378 +v -0.478480 0.425954 0.113164 +v -0.590375 0.420030 0.122306 +v -0.591694 0.424943 0.117859 +v -0.590659 0.409748 0.108547 +v -0.589668 0.407427 0.114826 +v -0.589777 0.409307 0.117038 +v -0.510523 0.495404 0.069051 +v -0.607676 0.466187 0.042966 +v -0.601781 0.436664 0.071151 +v -0.637476 0.432288 0.070088 +v -0.601781 0.436664 0.071151 +v -0.595579 0.418402 0.093964 +v -0.625587 0.995029 -0.923901 +v -0.663021 1.017357 -0.924139 +v -0.524530 0.998655 -0.932555 +v -0.488327 1.019870 -0.932294 +v -0.524530 0.998655 -0.932555 +v -0.524648 0.998653 -0.913964 +v -0.524648 0.998653 -0.913964 +v -0.488440 1.019861 -0.913765 +v -0.609907 1.276581 -0.940990 +v -0.620375 1.163582 -0.937951 +v -0.624599 1.074485 -0.935651 +v -0.508860 1.545071 -0.163305 +v -0.510309 1.496335 -0.123733 +v -0.512013 1.450402 -0.090898 +v -0.508353 1.710969 -0.437023 +v -0.508405 1.687867 -0.342262 +v -0.508134 1.647331 -0.273708 +v -0.505418 1.484802 -0.897274 +v -0.504223 1.556153 -0.846784 +v -0.504728 1.624911 -0.785655 +v -0.504728 1.624911 -0.785655 +v -0.506079 1.680546 -0.696368 +v -0.507476 1.709565 -0.567661 +v -0.527600 1.139419 -0.051979 +v -0.534849 1.080349 -0.040353 +v -0.542474 1.015184 -0.027206 +v -0.522829 1.222957 -0.050842 +v -0.524016 1.185649 -0.054005 +v -0.520413 1.290805 -0.044610 +v -0.521932 1.257137 -0.048212 +v -0.515384 1.363717 -0.042013 +v -0.517949 1.325759 -0.039321 +v -0.513542 1.405746 -0.061264 +v -0.508173 1.597282 -0.214102 +v -0.508173 1.597282 -0.214102 +v -0.474952 1.594158 -0.214267 +v -0.609785 1.272763 -0.918708 +v -0.620419 1.162361 -0.915112 +v -0.624719 1.074309 -0.912806 +v -0.510994 1.480337 -0.139615 +v -0.509845 1.526973 -0.177179 +v -0.512547 1.437739 -0.109385 +v -0.509180 1.667774 -0.352594 +v -0.508615 1.689852 -0.443020 +v -0.509272 1.628201 -0.286229 +v -0.504875 1.471464 -0.879993 +v -0.503571 1.538625 -0.833053 +v -0.504059 1.604952 -0.775049 +v -0.505544 1.659493 -0.689836 +v -0.504059 1.604952 -0.775049 +v -0.507267 1.688123 -0.567307 +v -0.533747 1.076508 -0.062828 +v -0.527255 1.137872 -0.074783 +v -0.524359 1.186049 -0.076925 +v -0.523698 1.224869 -0.073712 +v -0.523116 1.260007 -0.070976 +v -0.521713 1.293194 -0.067284 +v -0.519192 1.325525 -0.061887 +v -0.516411 1.359483 -0.064037 +v -0.514254 1.397168 -0.081912 +v -0.509358 1.578490 -0.227285 +v -0.509358 1.578490 -0.227285 +v -0.584475 0.657059 -0.011384 +v -0.581174 0.671221 -0.010462 +v -0.583068 0.674361 -0.001890 +v -0.586556 0.659808 -0.003055 +v -0.581174 0.671221 -0.010462 +v -0.583068 0.674361 -0.001890 +v -0.583068 0.674361 -0.001890 +v -0.586556 0.659808 -0.003055 +v -0.569781 0.643142 -0.007008 +v -0.579401 0.645808 -0.009885 +v -0.581108 0.648659 -0.001939 +v -0.570254 0.646507 0.000912 +v -0.579401 0.645808 -0.009885 +v -0.581108 0.648659 -0.001939 +v -0.581108 0.648659 -0.001939 +v -0.589783 0.646011 0.001327 +v -0.570214 0.645399 0.005827 +v -0.526611 0.651322 0.016735 +v -0.551659 0.656559 0.010993 +v -0.560961 0.651875 -0.004257 +v -0.560208 0.655288 0.004194 +v -0.560961 0.651875 -0.004257 +v -0.560208 0.655288 0.004194 +v -0.551659 0.656559 0.010993 +v -0.560208 0.655288 0.004194 +v -0.607498 0.861372 -0.031054 +v -0.630801 0.828260 -0.035391 +v -0.568631 0.866637 -0.043488 +v -0.543508 0.846235 -0.041089 +v -0.585927 0.824361 -0.049415 +v -0.689751 0.912584 -0.032807 +v -0.691744 0.911097 -0.036328 +v -0.689751 0.912584 -0.032807 +v -0.489091 0.970457 -0.028179 +v -0.488619 0.968833 -0.033671 +v -0.489563 0.972080 -0.022687 +v -0.490599 0.966936 -0.037212 +v -0.490599 0.966936 -0.037212 +v -0.691266 0.909456 -0.041847 +v -0.690788 0.907816 -0.047367 +v -0.688210 0.907291 -0.050614 +v -0.672079 0.910203 -0.051205 +v -0.688210 0.907291 -0.050614 +v -0.631793 0.916580 -0.048983 +v -0.607257 0.895760 -0.046626 +v -0.639276 0.865682 -0.053849 +v -0.492126 0.972186 -0.019455 +v -0.508161 0.966380 -0.018971 +v -0.492126 0.972186 -0.019455 +v -0.548327 0.948751 -0.021124 +v -0.571596 0.912440 -0.024518 +v -0.589203 0.897513 -0.035851 +v -0.597898 0.890698 -0.037177 +v -0.598711 0.890078 -0.042506 +v -0.588803 0.897601 -0.041080 +v -0.597898 0.890698 -0.037177 +v -0.598711 0.890078 -0.042506 +v -0.598711 0.890078 -0.042506 +v -0.588803 0.897601 -0.041080 +v -0.575889 0.887813 -0.034754 +v -0.580222 0.895901 -0.034883 +v -0.578588 0.896021 -0.040040 +v -0.573904 0.886666 -0.039855 +v -0.580222 0.895901 -0.034883 +v -0.578588 0.896021 -0.040040 +v -0.578588 0.896021 -0.040040 +v -0.573904 0.886666 -0.039855 +v -0.628989 0.821708 -0.057071 +v -0.579592 0.877360 -0.035668 +v -0.577868 0.874767 -0.040794 +v -0.579592 0.877360 -0.035668 +v -0.577868 0.874767 -0.040794 +v -0.577868 0.874767 -0.040794 +v 0.655470 0.654237 -0.020633 +v 0.655470 0.654237 -0.020633 +v 0.657776 0.652682 -0.024324 +v 0.450826 0.636343 0.017536 +v 0.450857 0.639203 0.022520 +v 0.450887 0.642062 0.027503 +v 0.469701 0.633955 0.008575 +v 0.453170 0.634603 0.013903 +v 0.453170 0.634603 0.013903 +v 0.657745 0.649808 -0.029334 +v 0.657714 0.646934 -0.034343 +v 0.657714 0.646934 -0.034343 +v 0.655370 0.644963 -0.036797 +v 0.655370 0.644963 -0.036797 +v 0.639093 0.642698 -0.033875 +v 0.613305 0.574394 -0.003567 +v 0.615314 0.606850 -0.016117 +v 0.623005 0.534458 0.013446 +v 0.571450 0.562385 0.009465 +v 0.567534 0.582550 0.004328 +v 0.585279 0.589910 -0.001934 +v 0.588444 0.605465 -0.008096 +v 0.453269 0.643850 0.030020 +v 0.442370 0.685323 0.023010 +v 0.453269 0.643850 0.030020 +v 0.469814 0.644831 0.027533 +v 0.526351 0.576597 0.037153 +v 0.510267 0.609504 0.029330 +v 0.528714 0.536138 0.056018 +v 0.571289 0.573841 0.028922 +v 0.567397 0.592130 0.021098 +v 0.547161 0.595873 0.024107 +v 0.537136 0.610890 0.021310 +v 0.585167 0.599493 0.014834 +v 0.613155 0.585805 0.015975 +v 0.547274 0.586289 0.007339 +v 0.526501 0.565187 0.017612 +v 0.510318 0.598313 0.009777 +v 0.552065 0.799611 -0.003128 +v 0.529459 0.781612 -0.002616 +v 0.507337 0.799232 -0.015264 +v 0.464830 0.794449 -0.008567 +v 0.509713 0.779218 -0.015761 +v 0.491779 0.774985 -0.012589 +v 0.484130 0.733627 0.008972 +v 0.496812 0.687526 0.011697 +v 0.500369 0.752644 0.002841 +v 0.570421 0.719027 -0.030285 +v 0.567572 0.752759 -0.028567 +v 0.589641 0.677333 -0.031163 +v 0.557039 0.968814 -0.006233 +v 0.551112 0.918207 -0.006454 +v 0.458856 0.998209 0.005578 +v 0.471273 1.050318 -0.008200 +v 0.452458 0.946094 0.011842 +v 0.451558 0.896160 0.013820 +v 0.550567 0.873209 -0.011413 +v 0.552105 0.831500 -0.017636 +v 0.598642 0.637680 -0.023272 +v 0.578407 0.619947 -0.011001 +v 0.553377 0.642648 -0.014356 +v 0.511694 0.644286 0.018234 +v 0.540314 0.626981 0.015256 +v 0.545459 0.449277 0.127144 +v 0.536149 0.469823 0.107690 +v 0.529677 0.436915 0.145102 +v 0.554512 0.437690 0.138091 +v 0.581516 0.474395 0.091693 +v 0.557200 0.424594 0.140973 +v 0.656916 0.448722 0.096060 +v 0.630187 0.441548 0.112231 +v 0.651528 0.451042 0.096069 +v 0.628911 0.446653 0.107845 +v 0.629042 0.427544 0.108000 +v 0.627289 0.429695 0.102508 +v 0.655542 0.434288 0.091524 +v 0.629042 0.427544 0.108000 +v 0.531284 0.499875 0.081406 +v 0.536149 0.469823 0.107690 +v 0.624919 0.494169 0.038682 +v 0.624450 0.459845 0.066154 +v 0.625667 0.439027 0.088389 +v 0.624450 0.459845 0.066154 +v 0.649739 1.017357 -0.932407 +v 0.612306 0.995029 -0.932169 +v 0.475044 1.019870 -0.940562 +v 0.511248 0.998655 -0.940823 +v 0.511248 0.998655 -0.940823 +v 0.511365 0.998653 -0.922232 +v 0.475157 1.019861 -0.922034 +v 0.511365 0.998653 -0.922232 +v 0.596625 1.276047 -0.945125 +v 0.607093 1.163582 -0.944841 +v 0.611316 1.074485 -0.943746 +v 0.497040 1.504006 -0.117446 +v 0.495681 1.547125 -0.161465 +v 0.498731 1.461187 -0.082087 +v 0.497040 1.504006 -0.117446 +v 0.542612 1.504112 -0.116646 +v 0.495417 1.685954 -0.343660 +v 0.495173 1.707604 -0.436911 +v 0.495261 1.644878 -0.275335 +v 0.492136 1.477593 -0.897300 +v 0.490941 1.543491 -0.845614 +v 0.491446 1.608960 -0.782314 +v 0.492797 1.665557 -0.691862 +v 0.491446 1.608960 -0.782314 +v 0.490941 1.543491 -0.845614 +v 0.494207 1.700367 -0.564842 +v 0.488616 1.100154 -0.030079 +v 0.503492 1.145909 -0.048654 +v 0.509380 1.186460 -0.053590 +v 0.509547 1.222957 -0.050842 +v 0.508650 1.257137 -0.048212 +v 0.507131 1.290805 -0.044610 +v 0.504667 1.326096 -0.039046 +v 0.502102 1.366413 -0.039810 +v 0.500260 1.413497 -0.054931 +v 0.495185 1.595787 -0.214892 +v 0.596503 1.272229 -0.922842 +v 0.607137 1.162361 -0.922003 +v 0.611437 1.074309 -0.920902 +v 0.462986 1.528167 -0.175008 +v 0.496396 1.529020 -0.175343 +v 0.497692 1.488007 -0.133328 +v 0.499265 1.448523 -0.100574 +v 0.495165 1.686481 -0.442911 +v 0.495418 1.665844 -0.354001 +v 0.495322 1.625723 -0.287869 +v 0.491593 1.464254 -0.880019 +v 0.490289 1.525964 -0.831883 +v 0.490777 1.589001 -0.771707 +v 0.490777 1.589001 -0.771707 +v 0.492262 1.644504 -0.685330 +v 0.493965 1.678924 -0.564489 +v 0.503701 1.143651 -0.071086 +v 0.489151 1.094177 -0.051447 +v 0.510416 1.224869 -0.073712 +v 0.509794 1.186772 -0.076463 +v 0.508431 1.293194 -0.067284 +v 0.509834 1.260007 -0.070976 +v 0.503129 1.362179 -0.061835 +v 0.505910 1.325862 -0.061612 +v 0.500972 1.404919 -0.075578 +v 0.495596 1.576978 -0.228085 +v 0.496396 1.529020 -0.175343 +v 0.575931 0.609247 0.003366 +v 0.569860 0.617669 0.001813 +v 0.570930 0.615793 -0.003560 +v 0.577505 0.606615 -0.001838 +v 0.569860 0.617669 0.001813 +v 0.570930 0.615793 -0.003560 +v 0.558090 0.624210 -0.007877 +v 0.578407 0.619947 -0.011001 +v 0.577505 0.606615 -0.001838 +v 0.570930 0.615793 -0.003560 +v 0.565648 0.595440 0.010339 +v 0.573790 0.600155 0.006945 +v 0.575243 0.596717 0.002063 +v 0.565906 0.591673 0.005815 +v 0.573790 0.600155 0.006945 +v 0.575243 0.596717 0.002063 +v 0.575243 0.596717 0.002063 +v 0.565906 0.591673 0.005815 +v 0.511587 0.632985 -0.001466 +v 0.555720 0.598686 0.011401 +v 0.554682 0.594979 0.007121 +v 0.555720 0.598686 0.011401 +v 0.554682 0.594979 0.007121 +v 0.554682 0.594979 0.007121 +v 0.500489 0.763960 -0.006019 +v 0.506898 0.755328 -0.007236 +v 0.505946 0.751647 -0.011840 +v 0.498911 0.761276 -0.010521 +v 0.506898 0.755328 -0.007236 +v 0.505946 0.751647 -0.011840 +v 0.505946 0.751647 -0.011840 +v 0.498911 0.761276 -0.010521 +v 0.510966 0.775227 -0.008234 +v 0.502844 0.772103 -0.006567 +v 0.501366 0.770312 -0.011090 +v 0.510713 0.773575 -0.012945 +v 0.502844 0.772103 -0.006567 +v 0.501366 0.770312 -0.011090 +v 0.501366 0.770312 -0.011090 +v 0.510713 0.773575 -0.012945 +v 0.551972 0.788465 -0.022872 +v 0.529162 0.772082 -0.019386 +v 0.519935 0.770478 -0.010003 +v 0.520993 0.768527 -0.014946 +v 0.519935 0.770478 -0.010003 +v 0.520993 0.768527 -0.014946 +v 0.520993 0.768527 -0.014946 +v 0.554633 0.600491 0.016762 +v 0.548075 0.609740 0.015052 +v 0.547161 0.595873 0.024107 +v 0.567397 0.592130 0.021098 +v 0.565845 0.597183 0.015457 +v 0.554633 0.600491 0.016762 +v 0.548075 0.609740 0.015052 +v 0.554633 0.600491 0.016762 +v 0.585167 0.599493 0.014834 +v 0.575194 0.602230 0.011704 +v 0.577480 0.612132 0.007801 +v 0.575194 0.602230 0.011704 +v 0.575194 0.602230 0.011704 +v 0.577480 0.612132 0.007801 +v 0.570930 0.621315 0.006077 +v 0.559710 0.624689 0.007396 +v 0.570930 0.621315 0.006077 +v 0.559710 0.624689 0.007396 +v 0.570930 0.621315 0.006077 +v 0.550354 0.619708 0.011163 +v 0.550354 0.619708 0.011163 +v 0.550354 0.619708 0.011163 +v 0.521220 0.774020 -0.005309 +v 0.527162 0.764208 -0.006508 +v 0.510940 0.779067 -0.003307 +v 0.521220 0.774020 -0.005309 +v 0.510940 0.779067 -0.003307 +v 0.527162 0.764208 -0.006508 +v 0.521220 0.774020 -0.005309 +v 0.501592 0.775805 -0.001452 +v 0.499139 0.766770 -0.000885 +v 0.501592 0.775805 -0.001452 +v 0.499139 0.766770 -0.000885 +v 0.501592 0.775805 -0.001452 +v 0.506171 0.757142 -0.002207 +v 0.517486 0.752360 -0.004483 +v 0.506171 0.757142 -0.002207 +v 0.517486 0.752360 -0.004483 +v 0.506171 0.757142 -0.002207 +v 0.525792 0.755426 -0.006216 +v 0.525792 0.755426 -0.006216 +v 0.525792 0.755426 -0.006216 +v -0.578770 0.877968 -0.030193 +v -0.588679 0.870463 -0.031765 +v -0.574812 0.889866 -0.029255 +v -0.578770 0.877968 -0.030193 +v -0.574812 0.889866 -0.029255 +v -0.588679 0.870463 -0.031765 +v -0.578770 0.877968 -0.030193 +v -0.579500 0.899220 -0.029439 +v -0.589718 0.900801 -0.030479 +v -0.579500 0.899220 -0.029439 +v -0.589718 0.900801 -0.030479 +v -0.579500 0.899220 -0.029439 +v -0.599625 0.893278 -0.031905 +v -0.603585 0.881396 -0.032990 +v -0.599625 0.893278 -0.031905 +v -0.603585 0.881396 -0.032990 +v -0.599625 0.893278 -0.031905 +v -0.598900 0.872061 -0.032951 +v -0.598900 0.872061 -0.032951 +v -0.598900 0.872061 -0.032951 +v -0.559193 0.648664 -0.012575 +v -0.555677 0.663494 -0.011686 +v -0.569222 0.639408 -0.015446 +v -0.559193 0.648664 -0.012575 +v -0.569222 0.639408 -0.015446 +v -0.555677 0.663494 -0.011686 +v -0.559193 0.648664 -0.012575 +v -0.580093 0.642035 -0.018708 +v -0.585568 0.653960 -0.020532 +v -0.580093 0.642035 -0.018708 +v -0.585568 0.653960 -0.020532 +v -0.580093 0.642035 -0.018708 +v -0.582089 0.668878 -0.019680 +v -0.572084 0.678201 -0.016810 +v -0.582089 0.668878 -0.019680 +v -0.572084 0.678201 -0.016810 +v -0.582089 0.668878 -0.019680 +v -0.573252 0.682234 -0.022503 +v -0.553509 0.680692 -0.017151 +v -0.561194 0.675529 -0.013491 +v -0.561194 0.675529 -0.013491 +v -0.561194 0.675529 -0.013491 +v -0.646541 0.495833 -0.120157 +v -0.641834 0.496281 -0.123699 +v -0.644272 0.494408 -0.105127 +v -0.648112 0.494723 -0.108699 +v -0.614091 0.494304 -0.102985 +v -0.647298 0.495255 -0.114403 +v -0.646541 0.495833 -0.120157 +v -0.648112 0.494723 -0.108699 +v -0.444422 0.494690 -0.101580 +v -0.475067 0.494499 -0.100508 +v -0.439572 0.495017 -0.104998 +v -0.441783 0.496381 -0.119913 +v -0.437934 0.496058 -0.116331 +v -0.544649 0.494357 -0.101262 +v -0.438753 0.495537 -0.110665 +v -0.439572 0.495017 -0.104998 +v -0.437934 0.496058 -0.116331 +vt 0.933204 0.898738 +vt 0.933329 0.898787 +vt 0.933729 0.897131 +vt 0.369521 0.017611 +vt 0.369536 0.013174 +vt 0.366209 0.013166 +vt 0.366195 0.017659 +vt 0.927844 0.728800 +vt 0.927792 0.724730 +vt 0.924454 0.724919 +vt 0.924520 0.729102 +vt 0.921989 0.725086 +vt 0.922065 0.729353 +vt 0.363752 0.013139 +vt 0.363739 0.017675 +vt 0.927501 0.717651 +vt 0.927319 0.714499 +vt 0.923860 0.714329 +vt 0.924088 0.717555 +vt 0.927086 0.711596 +vt 0.923568 0.711359 +vt 0.920969 0.711187 +vt 0.921305 0.714215 +vt 0.921567 0.717504 +vt 0.926782 0.708965 +vt 0.923185 0.708607 +vt 0.926499 0.706436 +vt 0.922831 0.705918 +vt 0.920121 0.705530 +vt 0.920529 0.708341 +vt 0.926331 0.703826 +vt 0.922620 0.703138 +vt 0.926245 0.701086 +vt 0.922515 0.700247 +vt 0.919760 0.699622 +vt 0.919880 0.702623 +vt 0.926163 0.698117 +vt 0.922426 0.697168 +vt 0.925938 0.694482 +vt 0.922220 0.693463 +vt 0.919471 0.692712 +vt 0.919665 0.696465 +vt 0.925493 0.689894 +vt 0.921841 0.688832 +vt 0.925084 0.685000 +vt 0.921582 0.683888 +vt 0.918849 0.683153 +vt 0.919122 0.688063 +vt 0.369737 0.047632 +vt 0.369611 0.038637 +vt 0.366340 0.038907 +vt 0.366516 0.047852 +vt 0.369524 0.029442 +vt 0.366215 0.029703 +vt 0.363769 0.029887 +vt 0.363922 0.039108 +vt 0.364134 0.048025 +vt 0.237576 0.062777 +vt 0.237822 0.067666 +vt 0.240989 0.067364 +vt 0.240730 0.062495 +vt 0.369854 0.053846 +vt 0.366676 0.054004 +vt 0.364326 0.054138 +vt 0.243333 0.067171 +vt 0.243063 0.062312 +vt 0.237660 0.051520 +vt 0.237507 0.057717 +vt 0.240694 0.057348 +vt 0.240954 0.051092 +vt 0.243051 0.057094 +vt 0.243390 0.050787 +vt 0.369503 0.022649 +vt 0.366179 0.022812 +vt 0.363723 0.022915 +vt 0.927667 0.721021 +vt 0.924298 0.721058 +vt 0.921809 0.721110 +vt 0.238292 0.035087 +vt 0.238295 0.028495 +vt 0.234584 0.028665 +vt 0.234634 0.035270 +vt 0.238166 0.024339 +vt 0.234515 0.024653 +vt 0.232345 0.025511 +vt 0.231919 0.028854 +vt 0.231930 0.035407 +vt 0.238007 0.043418 +vt 0.234525 0.043745 +vt 0.234367 0.051951 +vt 0.231951 0.043993 +vt 0.231933 0.052283 +vt 0.808814 0.059786 +vt 0.805479 0.059708 +vt 0.805592 0.064253 +vt 0.808927 0.064275 +vt 0.803014 0.059630 +vt 0.803127 0.064216 +vt 0.924043 0.542853 +vt 0.921583 0.542674 +vt 0.921479 0.546827 +vt 0.923948 0.546925 +vt 0.927369 0.543134 +vt 0.927287 0.547096 +vt 0.926947 0.554368 +vt 0.923534 0.554482 +vt 0.923314 0.557943 +vt 0.926773 0.557747 +vt 0.921010 0.554588 +vt 0.920756 0.558102 +vt 0.920443 0.561390 +vt 0.923045 0.561188 +vt 0.926563 0.560923 +vt 0.922684 0.564211 +vt 0.926281 0.563838 +vt 0.920023 0.564486 +vt 0.919629 0.567473 +vt 0.922343 0.567091 +vt 0.926013 0.566571 +vt 0.922138 0.569923 +vt 0.925848 0.569231 +vt 0.919393 0.570429 +vt 0.919264 0.573381 +vt 0.922022 0.572759 +vt 0.925751 0.571913 +vt 0.921903 0.575725 +vt 0.925641 0.574775 +vt 0.919140 0.576428 +vt 0.918908 0.580024 +vt 0.921657 0.579270 +vt 0.925377 0.578256 +vt 0.921236 0.583709 +vt 0.924887 0.582646 +vt 0.918521 0.584492 +vt 0.918227 0.589263 +vt 0.920952 0.588500 +vt 0.924449 0.587374 +vt 0.809047 0.028342 +vt 0.805836 0.028099 +vt 0.805541 0.037501 +vt 0.808807 0.037796 +vt 0.803465 0.027931 +vt 0.803129 0.037283 +vt 0.802924 0.046954 +vt 0.805371 0.047177 +vt 0.808681 0.047465 +vt 0.451476 0.027785 +vt 0.454630 0.028076 +vt 0.454848 0.023213 +vt 0.451680 0.022907 +vt 0.456959 0.028318 +vt 0.457188 0.023471 +vt 0.806165 0.021649 +vt 0.803825 0.021534 +vt 0.809333 0.021829 +vt 0.451586 0.039455 +vt 0.454879 0.039904 +vt 0.454614 0.033389 +vt 0.451429 0.033003 +vt 0.457311 0.040249 +vt 0.456967 0.033695 +vt 0.805374 0.054391 +vt 0.808705 0.054583 +vt 0.802911 0.054232 +vt 0.923761 0.550821 +vt 0.927132 0.550842 +vt 0.921268 0.550831 +vt 0.452195 0.056364 +vt 0.448537 0.056181 +vt 0.448485 0.062875 +vt 0.452196 0.063040 +vt 0.445834 0.056050 +vt 0.445819 0.062690 +vt 0.446248 0.066045 +vt 0.448418 0.066899 +vt 0.452071 0.067209 +vt 0.448294 0.039010 +vt 0.448441 0.047492 +vt 0.451923 0.047828 +vt 0.445859 0.038695 +vt 0.445867 0.047252 +vt 0.920788 0.721198 +vt 0.920979 0.725230 +vt 0.920532 0.717535 +vt 0.105996 0.236760 +vt 0.107837 0.232864 +vt 0.107608 0.232751 +vt 0.105745 0.236697 +vt 0.104109 0.241264 +vt 0.103844 0.241239 +vt 0.933599 0.724441 +vt 0.933628 0.728319 +vt 0.934647 0.728317 +vt 0.934621 0.724466 +vt 0.375324 0.013158 +vt 0.375307 0.017496 +vt 0.376325 0.017417 +vt 0.376343 0.013095 +vt 0.433781 0.206787 +vt 0.432748 0.201245 +vt 0.432497 0.201272 +vt 0.433530 0.206819 +vt 0.435173 0.211816 +vt 0.434922 0.211856 +vt 0.375279 0.028972 +vt 0.375299 0.038169 +vt 0.376293 0.038088 +vt 0.376288 0.028861 +vt 0.375338 0.047267 +vt 0.376315 0.047233 +vt 0.438783 0.180922 +vt 0.445054 0.173959 +vt 0.444868 0.173783 +vt 0.438562 0.180808 +vt 0.434264 0.188965 +vt 0.434018 0.188920 +vt 0.244304 0.067178 +vt 0.244029 0.062311 +vt 0.363151 0.048126 +vt 0.363355 0.054241 +vt 0.122844 0.282388 +vt 0.116270 0.279140 +vt 0.116114 0.279335 +vt 0.122722 0.282614 +vt 0.129130 0.283474 +vt 0.129049 0.283713 +vt 0.241831 0.024346 +vt 0.241830 0.022754 +vt 0.238100 0.022697 +vt 0.244062 0.025041 +vt 0.244569 0.024232 +vt 0.214005 0.097217 +vt 0.214017 0.099894 +vt 0.214275 0.100005 +vt 0.214265 0.097238 +vt 0.214003 0.093493 +vt 0.214264 0.093493 +vt 0.215116 0.093493 +vt 0.215117 0.097238 +vt 0.215380 0.097217 +vt 0.215380 0.093493 +vt 0.215127 0.100006 +vt 0.215387 0.099894 +vt 0.455736 0.068793 +vt 0.458474 0.067312 +vt 0.457966 0.066500 +vt 0.455735 0.067198 +vt 0.452006 0.068854 +vt 0.362746 0.013071 +vt 0.362733 0.017626 +vt 0.921061 0.729536 +vt 0.102454 0.246638 +vt 0.102183 0.246627 +vt 0.101479 0.252470 +vt 0.101207 0.252471 +vt 0.244680 0.028380 +vt 0.245766 0.028248 +vt 0.244653 0.034772 +vt 0.245766 0.034722 +vt 0.161216 0.271181 +vt 0.155730 0.274604 +vt 0.155851 0.274839 +vt 0.161372 0.271396 +vt 0.164713 0.269076 +vt 0.164983 0.269219 +vt 0.375379 0.053597 +vt 0.376343 0.053604 +vt 0.232317 0.068241 +vt 0.232095 0.063310 +vt 0.231142 0.063485 +vt 0.231360 0.068435 +vt 0.451745 0.170418 +vt 0.458207 0.169074 +vt 0.458100 0.168842 +vt 0.451595 0.170205 +vt 0.230824 0.028806 +vt 0.230817 0.035469 +vt 0.231775 0.024766 +vt 0.491295 0.181029 +vt 0.494772 0.183017 +vt 0.495036 0.182872 +vt 0.491446 0.180819 +vt 0.485597 0.177574 +vt 0.485708 0.177342 +vt 0.461642 0.239227 +vt 0.458074 0.235978 +vt 0.457954 0.236201 +vt 0.461514 0.239437 +vt 0.454731 0.233055 +vt 0.454631 0.233295 +vt 0.932385 0.580512 +vt 0.932981 0.576194 +vt 0.931847 0.576495 +vt 0.931258 0.580822 +vt 0.931831 0.585199 +vt 0.930680 0.585560 +vt 0.931313 0.686815 +vt 0.931859 0.691731 +vt 0.932976 0.692075 +vt 0.932449 0.687227 +vt 0.932405 0.696256 +vt 0.933536 0.696568 +vt 0.458813 0.235138 +vt 0.455379 0.232141 +vt 0.455196 0.232337 +vt 0.458606 0.235317 +vt 0.462463 0.238455 +vt 0.462229 0.238619 +vt 0.375286 0.022340 +vt 0.376302 0.022236 +vt 0.432531 0.195592 +vt 0.432278 0.195595 +vt 0.106868 0.232393 +vt 0.108675 0.228626 +vt 0.108476 0.228477 +vt 0.106639 0.232288 +vt 0.110702 0.225696 +vt 0.110539 0.225509 +vt 0.919700 0.558203 +vt 0.919367 0.561488 +vt 0.919968 0.554688 +vt 0.919817 0.624044 +vt 0.918713 0.624311 +vt 0.918995 0.626747 +vt 0.920101 0.626500 +vt 0.162364 0.189700 +vt 0.162606 0.189857 +vt 0.163678 0.186779 +vt 0.163425 0.186680 +vt 0.164216 0.184042 +vt 0.163957 0.184001 +vt 0.919514 0.628552 +vt 0.920591 0.628327 +vt 0.451880 0.231222 +vt 0.451794 0.231473 +vt 0.449462 0.230067 +vt 0.449385 0.230324 +vt 0.933276 0.572831 +vt 0.933365 0.570170 +vt 0.932234 0.570438 +vt 0.932140 0.573122 +vt 0.932663 0.699765 +vt 0.933803 0.700046 +vt 0.932734 0.702539 +vt 0.933875 0.702779 +vt 0.452449 0.230259 +vt 0.449965 0.229074 +vt 0.449822 0.229291 +vt 0.452287 0.230468 +vt 0.918757 0.702395 +vt 0.919011 0.705356 +vt 0.918630 0.699352 +vt 0.119335 0.222802 +vt 0.122130 0.221523 +vt 0.122045 0.221270 +vt 0.119253 0.222546 +vt 0.116574 0.223978 +vt 0.116480 0.223727 +vt 0.434045 0.211974 +vt 0.432656 0.206901 +vt 0.432389 0.206918 +vt 0.433785 0.212005 +vt 0.431643 0.201325 +vt 0.431375 0.201330 +vt 0.815736 0.064224 +vt 0.815623 0.059851 +vt 0.814611 0.059891 +vt 0.814724 0.064282 +vt 0.815818 0.067975 +vt 0.814802 0.068043 +vt 0.447320 0.229023 +vt 0.447246 0.229282 +vt 0.445211 0.228085 +vt 0.445126 0.228338 +vt 0.933421 0.567797 +vt 0.933503 0.565488 +vt 0.932392 0.565659 +vt 0.932298 0.568022 +vt 0.932787 0.705012 +vt 0.933924 0.705201 +vt 0.932884 0.707327 +vt 0.934008 0.707466 +vt 0.447772 0.228010 +vt 0.445681 0.227079 +vt 0.445558 0.227300 +vt 0.447646 0.228233 +vt 0.933040 0.709585 +vt 0.934142 0.709689 +vt 0.933208 0.712018 +vt 0.934284 0.712107 +vt 0.443559 0.226274 +vt 0.441552 0.224921 +vt 0.441377 0.225099 +vt 0.443417 0.226479 +vt 0.362926 0.039193 +vt 0.362764 0.029936 +vt 0.109569 0.272705 +vt 0.104272 0.265080 +vt 0.104031 0.265160 +vt 0.109369 0.272846 +vt 0.920257 0.714200 +vt 0.919905 0.711126 +vt 0.109515 0.229322 +vt 0.111398 0.226579 +vt 0.111242 0.226371 +vt 0.109320 0.229157 +vt 0.442967 0.227223 +vt 0.442850 0.227457 +vt 0.440793 0.225758 +vt 0.440633 0.225960 +vt 0.933622 0.563075 +vt 0.933745 0.560410 +vt 0.932679 0.560470 +vt 0.932534 0.563188 +vt 0.433227 0.188724 +vt 0.437874 0.180400 +vt 0.437674 0.180266 +vt 0.432987 0.188650 +vt 0.444303 0.173180 +vt 0.444145 0.172991 +vt 0.815487 0.038401 +vt 0.815618 0.028888 +vt 0.814635 0.028780 +vt 0.814488 0.038310 +vt 0.815450 0.048008 +vt 0.814440 0.047951 +vt 0.933437 0.717846 +vt 0.933530 0.720990 +vt 0.934560 0.721053 +vt 0.934480 0.717934 +vt 0.436681 0.215840 +vt 0.436435 0.215906 +vt 0.438227 0.219248 +vt 0.437994 0.219352 +vt 0.244025 0.057043 +vt 0.244395 0.050693 +vt 0.135347 0.283684 +vt 0.135334 0.283929 +vt 0.141893 0.282363 +vt 0.141949 0.282607 +vt 0.244063 0.042859 +vt 0.245124 0.042777 +vt 0.148956 0.278873 +vt 0.149055 0.279112 +vt 0.933336 0.714813 +vt 0.934393 0.714904 +vt 0.439808 0.222433 +vt 0.439600 0.222576 +vt 0.438907 0.223105 +vt 0.438711 0.223268 +vt 0.437218 0.219726 +vt 0.436993 0.219842 +vt 0.933836 0.557410 +vt 0.933918 0.554227 +vt 0.932882 0.554199 +vt 0.932787 0.557427 +vt 0.115572 0.279948 +vt 0.108699 0.273264 +vt 0.108485 0.273381 +vt 0.115394 0.280127 +vt 0.103252 0.265367 +vt 0.103010 0.265415 +vt 0.802141 0.037196 +vt 0.801919 0.046836 +vt 0.802494 0.027892 +vt 0.231969 0.058390 +vt 0.231004 0.058570 +vt 0.230935 0.052456 +vt 0.464229 0.168427 +vt 0.470681 0.169445 +vt 0.470696 0.169191 +vt 0.464180 0.168180 +vt 0.113274 0.224015 +vt 0.113137 0.223804 +vt 0.116119 0.222943 +vt 0.115996 0.222721 +vt 0.918922 0.564598 +vt 0.918506 0.567619 +vt 0.118909 0.221761 +vt 0.118783 0.221538 +vt 0.121671 0.220502 +vt 0.121528 0.220286 +vt 0.918258 0.570626 +vt 0.918125 0.573629 +vt 0.124526 0.219221 +vt 0.124360 0.219017 +vt 0.127639 0.217309 +vt 0.127449 0.217119 +vt 0.918002 0.576717 +vt 0.917778 0.580345 +vt 0.100671 0.258496 +vt 0.100422 0.258495 +vt 0.100362 0.252432 +vt 0.100113 0.252408 +vt 0.801897 0.054121 +vt 0.801997 0.059543 +vt 0.919441 0.708225 +vt 0.113828 0.225006 +vt 0.113709 0.224770 +vt 0.918529 0.696171 +vt 0.918338 0.692409 +vt 0.125061 0.220200 +vt 0.128264 0.218229 +vt 0.128147 0.218000 +vt 0.124963 0.219957 +vt 0.131122 0.214336 +vt 0.130911 0.214162 +vt 0.134839 0.211263 +vt 0.134617 0.211096 +vt 0.917406 0.584832 +vt 0.917091 0.589584 +vt 0.917995 0.687765 +vt 0.917695 0.682893 +vt 0.131825 0.215189 +vt 0.135597 0.212058 +vt 0.135447 0.211860 +vt 0.131690 0.214975 +vt 0.165416 0.269953 +vt 0.161798 0.272133 +vt 0.161904 0.272370 +vt 0.165407 0.270256 +vt 0.156244 0.275592 +vt 0.156365 0.275820 +vt 0.459667 0.063289 +vt 0.459667 0.056753 +vt 0.458555 0.056687 +vt 0.458581 0.063151 +vt 0.128757 0.284500 +vt 0.122289 0.283344 +vt 0.122148 0.283559 +vt 0.128663 0.284732 +vt 0.802867 0.021534 +vt 0.457911 0.028494 +vt 0.458144 0.023665 +vt 0.490661 0.262074 +vt 0.490333 0.262323 +vt 0.492358 0.265018 +vt 0.492721 0.264854 +vt 0.490006 0.262571 +vt 0.491995 0.265182 +vt 0.493414 0.267540 +vt 0.493801 0.267465 +vt 0.494188 0.267389 +vt 0.451138 0.169488 +vt 0.451012 0.169267 +vt 0.457778 0.168062 +vt 0.457691 0.167826 +vt 0.445193 0.022438 +vt 0.445020 0.027327 +vt 0.445988 0.027323 +vt 0.446165 0.022426 +vt 0.815818 0.022276 +vt 0.814847 0.022166 +vt 0.230893 0.044113 +vt 0.478223 0.173057 +vt 0.478294 0.172813 +vt 0.464058 0.167352 +vt 0.464033 0.167109 +vt 0.470788 0.168348 +vt 0.470830 0.168104 +vt 0.444911 0.032318 +vt 0.444853 0.038606 +vt 0.445887 0.032364 +vt 0.478558 0.172002 +vt 0.478649 0.171762 +vt 0.486080 0.176578 +vt 0.486199 0.176343 +vt 0.444805 0.047175 +vt 0.444719 0.056005 +vt 0.362716 0.022912 +vt 0.101765 0.258416 +vt 0.101500 0.258447 +vt 0.149363 0.279902 +vt 0.149451 0.280142 +vt 0.142099 0.283428 +vt 0.142134 0.283678 +vt 0.459033 0.048547 +vt 0.458309 0.040426 +vt 0.457976 0.048422 +vt 0.491862 0.180075 +vt 0.491965 0.179830 +vt 0.495459 0.182132 +vt 0.495451 0.181827 +vt 0.444725 0.062746 +vt 0.445679 0.066794 +vt 0.135260 0.284748 +vt 0.135228 0.284993 +vt 0.457931 0.033878 +vt 0.431441 0.195559 +vt 0.431180 0.195534 +vt 0.815511 0.054894 +vt 0.814497 0.054890 +vt 0.435593 0.216130 +vt 0.435347 0.216197 +vt 0.934014 0.550997 +vt 0.934103 0.547571 +vt 0.933092 0.547433 +vt 0.932992 0.550914 +vt 0.101324 0.246561 +vt 0.101076 0.246531 +vt 0.102990 0.241139 +vt 0.102741 0.241102 +vt 0.920564 0.542683 +vt 0.920457 0.546864 +vt 0.802110 0.064144 +vt 0.122505 0.282979 +vt 0.115843 0.279641 +vt 0.128903 0.284107 +vt 0.433093 0.206860 +vt 0.432070 0.201298 +vt 0.434484 0.211915 +vt 0.439254 0.222841 +vt 0.437606 0.219539 +vt 0.441085 0.225428 +vt 0.109034 0.273055 +vt 0.103641 0.265264 +vt 0.108998 0.228892 +vt 0.110972 0.226033 +vt 0.107238 0.232572 +vt 0.113491 0.224393 +vt 0.116300 0.223335 +vt 0.443192 0.226851 +vt 0.445384 0.227692 +vt 0.447483 0.228628 +vt 0.449642 0.229679 +vt 0.124744 0.219589 +vt 0.127893 0.217654 +vt 0.121858 0.220886 +vt 0.101086 0.258471 +vt 0.100784 0.252451 +vt 0.119081 0.222154 +vt 0.452084 0.230845 +vt 0.454964 0.232696 +vt 0.131406 0.214655 +vt 0.135143 0.211562 +vt 0.458340 0.235647 +vt 0.461936 0.238923 +vt 0.161585 0.271764 +vt 0.156047 0.275215 +vt 0.165200 0.269586 +vt 0.438218 0.180604 +vt 0.444585 0.173481 +vt 0.433622 0.188822 +vt 0.933060 0.650398 +vt 0.934167 0.650650 +vt 0.934506 0.647383 +vt 0.933398 0.647147 +vt 0.490904 0.261916 +vt 0.492976 0.264753 +vt 0.494450 0.267347 +vt 0.934647 0.644755 +vt 0.933569 0.644538 +vt 0.451366 0.169846 +vt 0.457939 0.168452 +vt 0.215117 0.089748 +vt 0.214691 0.089748 +vt 0.214690 0.093493 +vt 0.215127 0.086980 +vt 0.214701 0.086980 +vt 0.214275 0.086980 +vt 0.214265 0.089748 +vt 0.464119 0.167766 +vt 0.470742 0.168770 +vt 0.478426 0.172407 +vt 0.485894 0.176960 +vt 0.104931 0.236496 +vt 0.105338 0.236597 +vt 0.103417 0.241189 +vt 0.149209 0.279507 +vt 0.142024 0.283018 +vt 0.491654 0.180447 +vt 0.495248 0.182502 +vt 0.135297 0.284338 +vt 0.431859 0.195577 +vt 0.436014 0.216018 +vt 0.101754 0.246594 +vt 0.104687 0.236432 +vt 0.920239 0.550906 +vt 0.164997 0.184182 +vt 0.165218 0.184227 +vt 0.165416 0.182069 +vt 0.165199 0.182043 +vt 0.620322 0.015792 +vt 0.620617 0.014736 +vt 0.619117 0.013630 +vt 0.618821 0.014551 +vt 0.618445 0.012594 +vt 0.618124 0.012879 +vt 0.618655 0.014666 +vt 0.617958 0.012923 +vt 0.959808 0.002688 +vt 0.959866 0.001616 +vt 0.958317 0.002600 +vt 0.958313 0.003542 +vt 0.164447 0.182000 +vt 0.164202 0.181999 +vt 0.920371 0.629760 +vt 0.920253 0.629973 +vt 0.921790 0.630570 +vt 0.921849 0.630352 +vt 0.921320 0.629548 +vt 0.922188 0.630100 +vt 0.621920 0.008664 +vt 0.622650 0.005171 +vt 0.621133 0.004884 +vt 0.620387 0.008091 +vt 0.930932 0.644182 +vt 0.933225 0.642903 +vt 0.930841 0.642597 +vt 0.621673 0.002565 +vt 0.620673 0.003070 +vt 0.620050 0.004862 +vt 0.619331 0.007762 +vt 0.162939 0.190102 +vt 0.164046 0.186939 +vt 0.163272 0.190347 +vt 0.164414 0.187099 +vt 0.164607 0.184112 +vt 0.163439 0.190491 +vt 0.164611 0.187195 +vt 0.919210 0.647828 +vt 0.920331 0.647997 +vt 0.920639 0.645170 +vt 0.919514 0.645059 +vt 0.622381 0.016856 +vt 0.622650 0.015765 +vt 0.926698 0.649181 +vt 0.930358 0.649874 +vt 0.930689 0.646705 +vt 0.927022 0.646133 +vt 0.927360 0.643736 +vt 0.489845 0.262719 +vt 0.491803 0.265283 +vt 0.933643 0.621344 +vt 0.932523 0.621519 +vt 0.932844 0.624430 +vt 0.933968 0.624316 +vt 0.933007 0.626723 +vt 0.934103 0.626668 +vt 0.493198 0.267590 +vt 0.926167 0.622763 +vt 0.922514 0.623491 +vt 0.922806 0.626037 +vt 0.926469 0.625438 +vt 0.923226 0.627956 +vt 0.926795 0.627491 +vt 0.619588 0.004793 +vt 0.618865 0.007630 +vt 0.620513 0.002655 +vt 0.620381 0.002557 +vt 0.619428 0.004759 +vt 0.618704 0.007596 +vt 0.927151 0.630318 +vt 0.930081 0.629953 +vt 0.930066 0.629735 +vt 0.927138 0.630098 +vt 0.932442 0.629392 +vt 0.932355 0.629190 +vt 0.931975 0.629015 +vt 0.930088 0.629356 +vt 0.927100 0.629713 +vt 0.924213 0.630599 +vt 0.924227 0.630887 +vt 0.927164 0.630604 +vt 0.921808 0.630867 +vt 0.921827 0.631164 +vt 0.924241 0.631175 +vt 0.927178 0.630891 +vt 0.494539 0.269437 +vt 0.494913 0.269410 +vt 0.494166 0.269463 +vt 0.494550 0.270761 +vt 0.494895 0.270752 +vt 0.495241 0.270742 +vt 0.959866 0.008860 +vt 0.959819 0.005309 +vt 0.958353 0.005916 +vt 0.958456 0.009193 +vt 0.957560 0.004470 +vt 0.957437 0.006391 +vt 0.957507 0.009372 +vt 0.934179 0.643076 +vt 0.495159 0.269388 +vt 0.495459 0.270688 +vt 0.621808 0.001618 +vt 0.493952 0.269475 +vt 0.932683 0.628256 +vt 0.933652 0.628250 +vt 0.933805 0.628432 +vt 0.164823 0.182022 +vt 0.165144 0.180782 +vt 0.164797 0.180777 +vt 0.920280 0.630286 +vt 0.925942 0.616684 +vt 0.922417 0.617437 +vt 0.922397 0.620430 +vt 0.926020 0.619637 +vt 0.919681 0.618074 +vt 0.919704 0.621037 +vt 0.485390 0.257714 +vt 0.485249 0.257883 +vt 0.487533 0.260103 +vt 0.487678 0.259936 +vt 0.933360 0.614958 +vt 0.932202 0.615176 +vt 0.932341 0.618248 +vt 0.933461 0.618041 +vt 0.926479 0.655424 +vt 0.930003 0.656290 +vt 0.930177 0.653261 +vt 0.926546 0.652490 +vt 0.932745 0.656946 +vt 0.932875 0.653842 +vt 0.159541 0.195895 +vt 0.159690 0.196060 +vt 0.161657 0.193580 +vt 0.161506 0.193416 +vt 0.919035 0.653996 +vt 0.920193 0.654204 +vt 0.920211 0.651198 +vt 0.919089 0.650998 +vt 0.158912 0.195320 +vt 0.159227 0.195607 +vt 0.161189 0.193134 +vt 0.160872 0.192852 +vt 0.933890 0.657237 +vt 0.933983 0.654108 +vt 0.486252 0.256941 +vt 0.486007 0.257133 +vt 0.488300 0.259365 +vt 0.488539 0.259181 +vt 0.485699 0.257423 +vt 0.487989 0.259650 +vt 0.918541 0.618382 +vt 0.918599 0.621320 +vt 0.158669 0.195129 +vt 0.160634 0.192669 +vt 0.918424 0.604637 +vt 0.917295 0.605035 +vt 0.917338 0.606880 +vt 0.918431 0.606542 +vt 0.148717 0.204590 +vt 0.148972 0.204776 +vt 0.150513 0.203772 +vt 0.150264 0.203579 +vt 0.151133 0.202892 +vt 0.150885 0.202699 +vt 0.917351 0.607861 +vt 0.918439 0.607535 +vt 0.475186 0.247933 +vt 0.474879 0.248224 +vt 0.476353 0.249489 +vt 0.476661 0.249198 +vt 0.474572 0.248515 +vt 0.476046 0.249780 +vt 0.476712 0.250718 +vt 0.477019 0.250427 +vt 0.477327 0.250136 +vt 0.931428 0.671032 +vt 0.932564 0.671310 +vt 0.932626 0.669385 +vt 0.931529 0.669080 +vt 0.475430 0.247738 +vt 0.476909 0.249003 +vt 0.477575 0.249941 +vt 0.932652 0.668322 +vt 0.931560 0.668017 +vt 0.149286 0.205064 +vt 0.150827 0.204060 +vt 0.149600 0.205352 +vt 0.151141 0.204347 +vt 0.151760 0.203468 +vt 0.151447 0.203180 +vt 0.149729 0.205519 +vt 0.151277 0.204509 +vt 0.917831 0.667478 +vt 0.918981 0.667795 +vt 0.918979 0.665888 +vt 0.917867 0.665630 +vt 0.918986 0.664875 +vt 0.917878 0.664631 +vt 0.151898 0.203628 +vt 0.925208 0.669376 +vt 0.928704 0.670371 +vt 0.928855 0.668395 +vt 0.925258 0.667468 +vt 0.928890 0.667338 +vt 0.925276 0.666434 +vt 0.474436 0.248679 +vt 0.475914 0.249944 +vt 0.931986 0.600998 +vt 0.930835 0.601226 +vt 0.930943 0.603164 +vt 0.932054 0.602909 +vt 0.930976 0.604207 +vt 0.932082 0.603951 +vt 0.476580 0.250882 +vt 0.924627 0.602943 +vt 0.921136 0.603819 +vt 0.921096 0.605802 +vt 0.924683 0.604842 +vt 0.921100 0.606815 +vt 0.924704 0.605856 +vt 0.206070 0.418315 +vt 0.206113 0.417720 +vt 0.205711 0.417456 +vt 0.205670 0.418143 +vt 0.208558 0.419203 +vt 0.208539 0.418531 +vt 0.208141 0.418540 +vt 0.208156 0.419304 +vt 0.924272 0.675575 +vt 0.925028 0.675447 +vt 0.925071 0.674503 +vt 0.923674 0.674633 +vt 0.923932 0.676268 +vt 0.923158 0.675971 +vt 0.468611 0.244371 +vt 0.468474 0.244554 +vt 0.471792 0.246798 +vt 0.471935 0.246632 +vt 0.931760 0.593776 +vt 0.930637 0.594063 +vt 0.930680 0.597961 +vt 0.931876 0.597770 +vt 0.928228 0.594754 +vt 0.927685 0.598425 +vt 0.926286 0.595355 +vt 0.925852 0.596981 +vt 0.924486 0.597887 +vt 0.924540 0.600029 +vt 0.928113 0.601902 +vt 0.143053 0.208078 +vt 0.143197 0.208257 +vt 0.146845 0.206807 +vt 0.146722 0.206630 +vt 0.917674 0.674448 +vt 0.918798 0.674729 +vt 0.918960 0.670993 +vt 0.917768 0.670598 +vt 0.142427 0.207502 +vt 0.142740 0.207790 +vt 0.146409 0.206342 +vt 0.146095 0.206054 +vt 0.931259 0.678213 +vt 0.932366 0.678555 +vt 0.932466 0.674551 +vt 0.931286 0.674308 +vt 0.469467 0.243613 +vt 0.469225 0.243788 +vt 0.472550 0.246050 +vt 0.472786 0.245857 +vt 0.468918 0.244079 +vt 0.472242 0.246341 +vt 0.918201 0.597662 +vt 0.917097 0.598019 +vt 0.917214 0.601898 +vt 0.918385 0.601423 +vt 0.142186 0.207328 +vt 0.145833 0.205877 +vt 0.917359 0.608637 +vt 0.918455 0.608316 +vt 0.151480 0.201949 +vt 0.151233 0.201755 +vt 0.152177 0.200847 +vt 0.151928 0.200650 +vt 0.917486 0.609794 +vt 0.918627 0.609473 +vt 0.477449 0.251395 +vt 0.477757 0.251105 +vt 0.477142 0.251686 +vt 0.477955 0.252767 +vt 0.478262 0.252476 +vt 0.478570 0.252185 +vt 0.932674 0.667443 +vt 0.931576 0.667140 +vt 0.478005 0.250909 +vt 0.478822 0.251988 +vt 0.932804 0.666176 +vt 0.931672 0.665858 +vt 0.151794 0.202237 +vt 0.152108 0.202525 +vt 0.152805 0.201422 +vt 0.152491 0.201135 +vt 0.152246 0.202684 +vt 0.919001 0.664064 +vt 0.917886 0.663826 +vt 0.919172 0.662868 +vt 0.918011 0.662642 +vt 0.152946 0.201583 +vt 0.928898 0.666474 +vt 0.925292 0.665601 +vt 0.928949 0.665199 +vt 0.925427 0.664438 +vt 0.477010 0.251850 +vt 0.930992 0.605054 +vt 0.932104 0.604802 +vt 0.931091 0.606300 +vt 0.932237 0.606045 +vt 0.477822 0.252933 +vt 0.921127 0.607605 +vt 0.924720 0.606656 +vt 0.921359 0.608744 +vt 0.924855 0.607752 +vt 0.919278 0.613610 +vt 0.918163 0.613920 +vt 0.918419 0.616026 +vt 0.919599 0.615691 +vt 0.155198 0.198047 +vt 0.155447 0.198245 +vt 0.157156 0.196982 +vt 0.156906 0.196787 +vt 0.482167 0.254527 +vt 0.481859 0.254818 +vt 0.483734 0.255934 +vt 0.484043 0.255644 +vt 0.481551 0.255108 +vt 0.483426 0.256225 +vt 0.932399 0.661564 +vt 0.933506 0.661876 +vt 0.933747 0.659690 +vt 0.932561 0.659370 +vt 0.482419 0.254329 +vt 0.484295 0.255447 +vt 0.155761 0.198533 +vt 0.157470 0.197269 +vt 0.156075 0.198821 +vt 0.157785 0.197557 +vt 0.156229 0.198988 +vt 0.157935 0.197724 +vt 0.918673 0.658486 +vt 0.919809 0.658666 +vt 0.920122 0.656572 +vt 0.918921 0.656371 +vt 0.929014 0.663009 +vt 0.925741 0.662802 +vt 0.931958 0.663833 +vt 0.930002 0.660930 +vt 0.928084 0.660397 +vt 0.927460 0.661566 +vt 0.925997 0.661708 +vt 0.481406 0.255282 +vt 0.483284 0.256396 +vt 0.932956 0.610329 +vt 0.931834 0.610539 +vt 0.932006 0.612729 +vt 0.933207 0.612513 +vt 0.922045 0.610676 +vt 0.925169 0.609289 +vt 0.919003 0.611377 +vt 0.921712 0.613025 +vt 0.923722 0.612668 +vt 0.924080 0.611273 +vt 0.925440 0.610375 +vt 0.971207 0.267138 +vt 0.974543 0.267257 +vt 0.974527 0.262660 +vt 0.971193 0.262618 +vt 0.977009 0.267324 +vt 0.976991 0.262670 +vt 0.977041 0.258571 +vt 0.974572 0.258609 +vt 0.971231 0.258632 +vt 0.918214 0.837114 +vt 0.921625 0.836926 +vt 0.921793 0.833477 +vt 0.918337 0.833741 +vt 0.924145 0.836806 +vt 0.924347 0.833294 +vt 0.924612 0.829897 +vt 0.922016 0.830139 +vt 0.918502 0.830472 +vt 0.922320 0.827210 +vt 0.918731 0.827665 +vt 0.924970 0.826871 +vt 0.925291 0.824027 +vt 0.922591 0.824488 +vt 0.918935 0.825105 +vt 0.922718 0.821703 +vt 0.919026 0.822492 +vt 0.925445 0.821115 +vt 0.925477 0.818111 +vt 0.922738 0.818811 +vt 0.919032 0.819751 +vt 0.922643 0.815803 +vt 0.918933 0.816844 +vt 0.925385 0.815032 +vt 0.924820 0.811830 +vt 0.922093 0.812599 +vt 0.918404 0.813645 +vt 0.920855 0.809123 +vt 0.917217 0.810059 +vt 0.923543 0.808441 +vt 0.922101 0.804806 +vt 0.919446 0.805393 +vt 0.915852 0.806206 +vt 0.971074 0.296619 +vt 0.974295 0.296830 +vt 0.974459 0.288017 +vt 0.971188 0.287754 +vt 0.976677 0.296997 +vt 0.976878 0.288213 +vt 0.977014 0.279242 +vt 0.974566 0.279051 +vt 0.971255 0.278779 +vt 0.271179 0.029691 +vt 0.274316 0.030368 +vt 0.274555 0.026038 +vt 0.271410 0.025192 +vt 0.276638 0.030842 +vt 0.276883 0.026632 +vt 0.974142 0.303070 +vt 0.976492 0.303197 +vt 0.970964 0.302920 +vt 0.271304 0.039863 +vt 0.274595 0.040362 +vt 0.274310 0.034756 +vt 0.271132 0.034170 +vt 0.277029 0.040718 +vt 0.276660 0.035169 +vt 0.974578 0.272347 +vt 0.971246 0.272136 +vt 0.977040 0.272485 +vt 0.918008 0.843543 +vt 0.921351 0.843608 +vt 0.921466 0.840203 +vt 0.918096 0.840262 +vt 0.923822 0.843683 +vt 0.923957 0.840184 +vt 0.271945 0.056051 +vt 0.268287 0.055869 +vt 0.268238 0.062474 +vt 0.271948 0.062643 +vt 0.265584 0.055732 +vt 0.265573 0.062285 +vt 0.265999 0.065628 +vt 0.268168 0.066486 +vt 0.271820 0.066800 +vt 0.268014 0.039361 +vt 0.268177 0.047415 +vt 0.271659 0.047751 +vt 0.265582 0.038977 +vt 0.265604 0.047161 +vt 0.967639 0.884050 +vt 0.967673 0.888621 +vt 0.971001 0.888602 +vt 0.970973 0.883953 +vt 0.967771 0.892662 +vt 0.971107 0.892707 +vt 0.973575 0.892718 +vt 0.973463 0.888567 +vt 0.973439 0.883861 +vt 0.156588 0.104533 +vt 0.156673 0.108141 +vt 0.160126 0.108423 +vt 0.159997 0.104733 +vt 0.156797 0.111695 +vt 0.160307 0.112049 +vt 0.162903 0.112315 +vt 0.162679 0.108646 +vt 0.162517 0.104902 +vt 0.157003 0.114791 +vt 0.160589 0.115254 +vt 0.157201 0.117555 +vt 0.160857 0.118167 +vt 0.163561 0.118616 +vt 0.163242 0.115596 +vt 0.157300 0.120219 +vt 0.160992 0.121003 +vt 0.157330 0.122902 +vt 0.161037 0.123841 +vt 0.163778 0.124532 +vt 0.163723 0.121578 +vt 0.157269 0.125695 +vt 0.160982 0.126728 +vt 0.156754 0.128678 +vt 0.160448 0.129707 +vt 0.163178 0.130473 +vt 0.163727 0.127492 +vt 0.155532 0.131921 +vt 0.159171 0.132839 +vt 0.154127 0.135456 +vt 0.157719 0.136256 +vt 0.160374 0.136864 +vt 0.161862 0.133528 +vt 0.967825 0.853144 +vt 0.967740 0.862468 +vt 0.971037 0.862231 +vt 0.971074 0.852961 +vt 0.967672 0.871917 +vt 0.971002 0.871670 +vt 0.973465 0.871478 +vt 0.973475 0.862057 +vt 0.973476 0.852837 +vt 0.968101 0.841957 +vt 0.967925 0.846545 +vt 0.971126 0.846424 +vt 0.971281 0.841896 +vt 0.973492 0.846352 +vt 0.973632 0.841872 +vt 0.222442 0.051808 +vt 0.222309 0.057751 +vt 0.225484 0.057149 +vt 0.225731 0.051290 +vt 0.222397 0.062382 +vt 0.225533 0.061697 +vt 0.227849 0.061164 +vt 0.227830 0.056685 +vt 0.228161 0.050894 +vt 0.967639 0.878885 +vt 0.970978 0.878698 +vt 0.973448 0.878543 +vt 0.156424 0.097936 +vt 0.156487 0.101239 +vt 0.159858 0.101307 +vt 0.159768 0.097883 +vt 0.162349 0.101382 +vt 0.162240 0.097872 +vt 0.223044 0.035162 +vt 0.223044 0.028490 +vt 0.219334 0.028654 +vt 0.219386 0.035344 +vt 0.222919 0.024322 +vt 0.219267 0.024630 +vt 0.217098 0.025484 +vt 0.216670 0.028838 +vt 0.216684 0.035474 +vt 0.222770 0.043659 +vt 0.219290 0.044003 +vt 0.219153 0.052322 +vt 0.216717 0.044249 +vt 0.216721 0.052688 +vt 0.924839 0.843789 +vt 0.924982 0.840244 +vt 0.003753 0.212447 +vt 0.003490 0.212480 +vt 0.004838 0.217077 +vt 0.005088 0.217006 +vt 0.006461 0.221049 +vt 0.006688 0.220927 +vt 0.925183 0.836810 +vt 0.965417 0.258641 +vt 0.964396 0.258581 +vt 0.964376 0.262437 +vt 0.965393 0.262515 +vt 0.220344 0.227004 +vt 0.220092 0.226965 +vt 0.218848 0.232029 +vt 0.219104 0.232061 +vt 0.217674 0.237629 +vt 0.217936 0.237653 +vt 0.964389 0.266799 +vt 0.965405 0.266900 +vt 0.965495 0.278290 +vt 0.964487 0.278176 +vt 0.964506 0.287218 +vt 0.965500 0.287297 +vt 0.218953 0.250039 +vt 0.218683 0.250097 +vt 0.223323 0.257950 +vt 0.223571 0.257822 +vt 0.229855 0.264753 +vt 0.230068 0.264562 +vt 0.964496 0.296238 +vt 0.965474 0.296269 +vt 0.976444 0.307461 +vt 0.977410 0.307557 +vt 0.977463 0.303298 +vt 0.029947 0.170874 +vt 0.029878 0.170649 +vt 0.024101 0.172341 +vt 0.024206 0.172549 +vt 0.017702 0.175923 +vt 0.017837 0.176097 +vt 0.977660 0.297095 +vt 0.271754 0.068442 +vt 0.275484 0.068384 +vt 0.275485 0.066793 +vt 0.661217 0.103200 +vt 0.661478 0.103200 +vt 0.661480 0.099455 +vt 0.661220 0.099476 +vt 0.661490 0.096686 +vt 0.661231 0.096797 +vt 0.278223 0.066907 +vt 0.277716 0.066098 +vt 0.662330 0.103200 +vt 0.662594 0.103200 +vt 0.662594 0.099476 +vt 0.662332 0.099455 +vt 0.222856 0.022677 +vt 0.226583 0.024334 +vt 0.226586 0.022739 +vt 0.228814 0.025032 +vt 0.229324 0.024220 +vt 0.662602 0.096797 +vt 0.662342 0.096686 +vt 0.978023 0.267297 +vt 0.978003 0.262617 +vt 0.002009 0.201393 +vt 0.001748 0.201403 +vt 0.002328 0.207098 +vt 0.002594 0.207079 +vt 0.978054 0.258496 +vt 0.279420 0.062891 +vt 0.278333 0.062759 +vt 0.064256 0.183078 +vt 0.064524 0.182933 +vt 0.060871 0.180860 +vt 0.060718 0.181072 +vt 0.055247 0.177579 +vt 0.055130 0.177811 +vt 0.279420 0.056416 +vt 0.278306 0.056366 +vt 0.964476 0.302694 +vt 0.965439 0.302685 +vt 0.236717 0.268435 +vt 0.236892 0.268210 +vt 0.243204 0.270088 +vt 0.243330 0.269846 +vt 0.265942 0.023673 +vt 0.264992 0.023313 +vt 0.264776 0.028175 +vt 0.265725 0.028471 +vt 0.264471 0.055670 +vt 0.264477 0.062333 +vt 0.270685 0.262558 +vt 0.270792 0.262796 +vt 0.276629 0.259487 +vt 0.276481 0.259270 +vt 0.280261 0.257472 +vt 0.279999 0.257319 +vt 0.265428 0.066373 +vt 0.245269 0.200280 +vt 0.245086 0.200094 +vt 0.242466 0.203229 +vt 0.242613 0.203442 +vt 0.146793 0.133894 +vt 0.147882 0.134088 +vt 0.149203 0.130340 +vt 0.148098 0.130092 +vt 0.150331 0.126893 +vt 0.149208 0.126591 +vt 0.239966 0.205955 +vt 0.240073 0.206195 +vt 0.909601 0.807642 +vt 0.908505 0.807934 +vt 0.909780 0.812010 +vt 0.910889 0.811699 +vt 0.246157 0.200893 +vt 0.245932 0.200775 +vt 0.243184 0.204037 +vt 0.243388 0.204186 +vt 0.240542 0.206896 +vt 0.240722 0.207081 +vt 0.910864 0.815791 +vt 0.911987 0.815467 +vt 0.964437 0.271625 +vt 0.965451 0.271743 +vt 0.217150 0.243424 +vt 0.217421 0.243420 +vt 0.005727 0.221418 +vt 0.005499 0.221523 +vt 0.007687 0.225262 +vt 0.007883 0.225114 +vt 0.163556 0.105028 +vt 0.163733 0.108773 +vt 0.163976 0.112440 +vt 0.010276 0.228123 +vt 0.010437 0.227938 +vt 0.163762 0.171824 +vt 0.163820 0.174589 +vt 0.164894 0.174579 +vt 0.164911 0.171802 +vt 0.163669 0.176968 +vt 0.164677 0.176987 +vt 0.061788 0.263227 +vt 0.063097 0.265821 +vt 0.063349 0.265783 +vt 0.062034 0.263133 +vt 0.060090 0.260582 +vt 0.060324 0.260435 +vt 0.237472 0.207669 +vt 0.237555 0.207925 +vt 0.150813 0.123897 +vt 0.149686 0.123580 +vt 0.150885 0.121265 +vt 0.149762 0.120970 +vt 0.235098 0.208770 +vt 0.235171 0.209033 +vt 0.911350 0.818961 +vt 0.912480 0.818652 +vt 0.237952 0.208683 +vt 0.238111 0.208888 +vt 0.235518 0.209813 +vt 0.235658 0.210028 +vt 0.911452 0.821650 +vt 0.912584 0.821379 +vt 0.926398 0.823823 +vt 0.926564 0.820856 +vt 0.016592 0.229537 +vt 0.016503 0.229794 +vt 0.019295 0.230935 +vt 0.019373 0.230673 +vt 0.022109 0.232167 +vt 0.022190 0.231908 +vt 0.926601 0.817811 +vt 0.219217 0.226833 +vt 0.218960 0.226794 +vt 0.217714 0.231908 +vt 0.217975 0.231933 +vt 0.960964 0.892474 +vt 0.961972 0.892554 +vt 0.961888 0.888625 +vt 0.960881 0.888566 +vt 0.961843 0.884187 +vt 0.960833 0.884152 +vt 0.216563 0.237545 +vt 0.216820 0.237562 +vt 0.232942 0.209777 +vt 0.233011 0.210042 +vt 0.150881 0.118849 +vt 0.149764 0.118595 +vt 0.150846 0.116484 +vt 0.149741 0.116285 +vt 0.230807 0.210688 +vt 0.230887 0.210947 +vt 0.911473 0.824073 +vt 0.912602 0.823853 +vt 0.233325 0.210836 +vt 0.233448 0.211056 +vt 0.231222 0.211735 +vt 0.231341 0.211953 +vt 0.911456 0.826339 +vt 0.912574 0.826169 +vt 0.911390 0.828589 +vt 0.912488 0.828454 +vt 0.229036 0.212517 +vt 0.229175 0.212719 +vt 0.226752 0.213825 +vt 0.226924 0.214001 +vt 0.911317 0.831178 +vt 0.912390 0.831059 +vt 0.977875 0.288296 +vt 0.010836 0.182249 +vt 0.011013 0.182368 +vt 0.005207 0.189500 +vt 0.005427 0.189560 +vt 0.978022 0.279294 +vt 0.925397 0.833251 +vt 0.008520 0.224573 +vt 0.008712 0.224401 +vt 0.010965 0.227255 +vt 0.011117 0.227041 +vt 0.925677 0.829807 +vt 0.228485 0.211528 +vt 0.228598 0.211767 +vt 0.150768 0.113985 +vt 0.149682 0.113845 +vt 0.150694 0.111090 +vt 0.149630 0.111003 +vt 0.226022 0.212949 +vt 0.226179 0.213158 +vt 0.217888 0.250279 +vt 0.217671 0.250333 +vt 0.222451 0.258459 +vt 0.222628 0.258346 +vt 0.960873 0.872374 +vt 0.961882 0.872331 +vt 0.962007 0.862880 +vt 0.961006 0.862954 +vt 0.962175 0.853478 +vt 0.961187 0.853567 +vt 0.229144 0.265514 +vt 0.229280 0.265346 +vt 0.912282 0.837470 +vt 0.911244 0.837587 +vt 0.911206 0.840489 +vt 0.912233 0.840398 +vt 0.222747 0.219482 +vt 0.222515 0.219378 +vt 0.221186 0.222852 +vt 0.221432 0.222917 +vt 0.965468 0.255557 +vt 0.964439 0.255505 +vt 0.278033 0.040834 +vt 0.277632 0.035286 +vt 0.041299 0.170770 +vt 0.041353 0.170531 +vt 0.035371 0.169787 +vt 0.035380 0.170022 +vt 0.277599 0.030964 +vt 0.278776 0.048410 +vt 0.277715 0.048326 +vt 0.048321 0.173592 +vt 0.048225 0.173828 +vt 0.911273 0.834338 +vt 0.912327 0.834219 +vt 0.224459 0.216232 +vt 0.224664 0.216374 +vt 0.223581 0.215523 +vt 0.223774 0.215693 +vt 0.150669 0.107670 +vt 0.149621 0.107628 +vt 0.150659 0.104216 +vt 0.149623 0.104218 +vt 0.221522 0.218868 +vt 0.221745 0.218992 +vt 0.017149 0.175319 +vt 0.016944 0.175125 +vt 0.009918 0.181711 +vt 0.010160 0.181842 +vt 0.974465 0.852816 +vt 0.974480 0.861988 +vt 0.974482 0.871373 +vt 0.004159 0.189246 +vt 0.004424 0.189306 +vt 0.264646 0.032874 +vt 0.265608 0.033120 +vt 0.249132 0.271028 +vt 0.249194 0.270774 +vt 0.255537 0.270305 +vt 0.255530 0.270046 +vt 0.264584 0.038783 +vt 0.013126 0.229759 +vt 0.013259 0.229551 +vt 0.164340 0.115735 +vt 0.164680 0.118791 +vt 0.016035 0.230801 +vt 0.016155 0.230582 +vt 0.018842 0.231944 +vt 0.018965 0.231724 +vt 0.164852 0.121803 +vt 0.164911 0.124808 +vt 0.021608 0.233154 +vt 0.021748 0.232941 +vt 0.024353 0.234394 +vt 0.024515 0.234193 +vt 0.164858 0.127807 +vt 0.164302 0.130801 +vt 0.026705 0.236348 +vt 0.026892 0.236170 +vt 0.001272 0.195720 +vt 0.001540 0.195727 +vt 0.974468 0.878433 +vt 0.974458 0.883768 +vt 0.000643 0.201477 +vt 0.000902 0.201455 +vt 0.926057 0.826727 +vt 0.013681 0.228790 +vt 0.013797 0.228548 +vt 0.926513 0.814711 +vt 0.024941 0.233453 +vt 0.025036 0.233204 +vt 0.027404 0.235495 +vt 0.027526 0.235264 +vt 0.925944 0.811522 +vt 0.028453 0.239509 +vt 0.028661 0.239365 +vt 0.162971 0.133841 +vt 0.161471 0.137156 +vt 0.030410 0.242869 +vt 0.030635 0.242754 +vt 0.924650 0.808185 +vt 0.029266 0.238791 +vt 0.029426 0.238586 +vt 0.031315 0.242270 +vt 0.031506 0.242090 +vt 0.923192 0.804603 +vt 0.064944 0.182192 +vt 0.064930 0.181886 +vt 0.061387 0.179872 +vt 0.061285 0.180116 +vt 0.229430 0.028381 +vt 0.230518 0.028244 +vt 0.229404 0.034842 +vt 0.230518 0.034776 +vt 0.055745 0.176585 +vt 0.055628 0.176819 +vt 0.029573 0.169867 +vt 0.029459 0.169624 +vt 0.023491 0.171391 +vt 0.023656 0.171619 +vt 0.974598 0.841923 +vt 0.974465 0.846369 +vt 0.277586 0.176069 +vt 0.278944 0.172794 +vt 0.278558 0.172713 +vt 0.277215 0.175893 +vt 0.279853 0.169651 +vt 0.279462 0.169666 +vt 0.279072 0.169680 +vt 0.278171 0.172632 +vt 0.276844 0.175718 +vt 0.236140 0.269347 +vt 0.236249 0.269144 +vt 0.962356 0.846781 +vt 0.961381 0.846872 +vt 0.216226 0.068435 +vt 0.217190 0.068282 +vt 0.216939 0.063528 +vt 0.215978 0.063644 +vt 0.242794 0.271084 +vt 0.242869 0.270862 +vt 0.264546 0.047038 +vt 0.263217 0.267024 +vt 0.263150 0.266773 +vt 0.248976 0.272087 +vt 0.248996 0.271853 +vt 0.216783 0.058764 +vt 0.215812 0.058876 +vt 0.215717 0.052799 +vt 0.255657 0.271388 +vt 0.255616 0.271148 +vt 0.263554 0.268075 +vt 0.263468 0.267838 +vt 0.215657 0.044328 +vt 0.215571 0.035518 +vt 0.271266 0.263799 +vt 0.271151 0.263567 +vt 0.978054 0.272496 +vt 0.002371 0.195763 +vt 0.002618 0.195778 +vt 0.048698 0.172550 +vt 0.048615 0.172797 +vt 0.228823 0.043051 +vt 0.229882 0.042924 +vt 0.229159 0.050696 +vt 0.041518 0.169452 +vt 0.041490 0.169708 +vt 0.277132 0.260480 +vt 0.277032 0.260238 +vt 0.215577 0.028781 +vt 0.216530 0.024734 +vt 0.280658 0.258520 +vt 0.280671 0.258218 +vt 0.035239 0.168717 +vt 0.035283 0.168970 +vt 0.228792 0.056437 +vt 0.228798 0.060869 +vt 0.216068 0.243455 +vt 0.216311 0.243446 +vt 0.961833 0.879184 +vt 0.960821 0.879187 +vt 0.220103 0.222539 +vt 0.220348 0.222615 +vt 0.150626 0.101157 +vt 0.149602 0.101214 +vt 0.961082 0.895674 +vt 0.962101 0.895783 +vt 0.001216 0.207207 +vt 0.001469 0.207178 +vt 0.974482 0.888496 +vt 0.974598 0.892664 +vt 0.002387 0.212630 +vt 0.002637 0.212593 +vt 0.017426 0.175621 +vt 0.023878 0.171980 +vt 0.029725 0.170258 +vt 0.217247 0.237595 +vt 0.218412 0.231981 +vt 0.219655 0.226899 +vt 0.222130 0.219185 +vt 0.224117 0.215962 +vt 0.226465 0.213492 +vt 0.004816 0.189403 +vt 0.010498 0.182045 +vt 0.010701 0.227597 +vt 0.008202 0.224843 +vt 0.006094 0.221233 +vt 0.016329 0.230188 +vt 0.013470 0.229170 +vt 0.228817 0.212142 +vt 0.231055 0.211341 +vt 0.233168 0.210439 +vt 0.235344 0.209423 +vt 0.027148 0.235833 +vt 0.024728 0.233823 +vt 0.021928 0.232554 +vt 0.001325 0.201429 +vt 0.001955 0.195745 +vt 0.019130 0.231329 +vt 0.237754 0.208304 +vt 0.240308 0.206546 +vt 0.030975 0.242512 +vt 0.028964 0.239078 +vt 0.242898 0.203739 +vt 0.245600 0.200527 +vt 0.055438 0.177199 +vt 0.061078 0.180488 +vt 0.064734 0.182563 +vt 0.229568 0.265049 +vt 0.222975 0.258148 +vt 0.218286 0.250188 +vt 0.913000 0.768181 +vt 0.913172 0.765227 +vt 0.912103 0.765194 +vt 0.911864 0.768092 +vt 0.991843 0.491011 +vt 0.989444 0.490960 +vt 0.989196 0.492020 +vt 0.991615 0.492132 +vt 0.279192 0.172890 +vt 0.280109 0.169692 +vt 0.277818 0.176222 +vt 0.243036 0.270475 +vt 0.236483 0.268790 +vt 0.661904 0.103200 +vt 0.661906 0.106945 +vt 0.662332 0.106945 +vt 0.661480 0.106945 +vt 0.661489 0.109712 +vt 0.661915 0.109712 +vt 0.662342 0.109711 +vt 0.255576 0.270727 +vt 0.249064 0.271441 +vt 0.270971 0.263182 +vt 0.263342 0.267431 +vt 0.004433 0.217184 +vt 0.004028 0.217291 +vt 0.003063 0.212537 +vt 0.041422 0.170119 +vt 0.048468 0.173194 +vt 0.280466 0.257845 +vt 0.276831 0.259862 +vt 0.035327 0.169378 +vt 0.216731 0.243435 +vt 0.220767 0.222734 +vt 0.001898 0.207138 +vt 0.003784 0.217355 +vt 0.163259 0.097945 +vt 0.163377 0.101484 +vt 0.064137 0.265823 +vt 0.064701 0.268021 +vt 0.064915 0.268100 +vt 0.064367 0.265886 +vt 0.064746 0.269666 +vt 0.064944 0.269695 +vt 0.990243 0.478292 +vt 0.989011 0.479404 +vt 0.989138 0.479812 +vt 0.990098 0.479237 +vt 0.991843 0.477720 +vt 0.991696 0.478790 +vt 0.163440 0.178501 +vt 0.164324 0.178539 +vt 0.997244 0.424506 +vt 0.996476 0.423788 +vt 0.996344 0.424170 +vt 0.997296 0.425461 +vt 0.063722 0.267893 +vt 0.063848 0.269462 +vt 0.064067 0.269520 +vt 0.063961 0.267893 +vt 0.990590 0.484877 +vt 0.988889 0.484745 +vt 0.988202 0.487944 +vt 0.989940 0.488376 +vt 0.987818 0.484475 +vt 0.987182 0.487380 +vt 0.986962 0.489281 +vt 0.987713 0.490266 +vt 0.062425 0.263057 +vt 0.060700 0.260264 +vt 0.063743 0.265803 +vt 0.062815 0.262982 +vt 0.061075 0.260093 +vt 0.063048 0.262982 +vt 0.061301 0.260030 +vt 0.926526 0.766702 +vt 0.926265 0.764054 +vt 0.925230 0.763861 +vt 0.925435 0.766511 +vt 0.926601 0.769743 +vt 0.925449 0.769575 +vt 0.919233 0.768801 +vt 0.919301 0.765830 +vt 0.915784 0.765475 +vt 0.915721 0.768483 +vt 0.919395 0.763269 +vt 0.916044 0.762956 +vt 0.913572 0.762755 +vt 0.277941 0.172629 +vt 0.276618 0.175656 +vt 0.278844 0.169738 +vt 0.150437 0.175882 +vt 0.150942 0.178059 +vt 0.151979 0.177880 +vt 0.151528 0.175696 +vt 0.150144 0.173270 +vt 0.151288 0.173062 +vt 0.157536 0.172466 +vt 0.157679 0.175114 +vt 0.161201 0.174793 +vt 0.161028 0.172053 +vt 0.157830 0.177384 +vt 0.161190 0.177127 +vt 0.987374 0.484345 +vt 0.986750 0.487193 +vt 0.560099 0.010787 +vt 0.560259 0.010817 +vt 0.559749 0.008132 +vt 0.559591 0.008102 +vt 0.559614 0.005743 +vt 0.559453 0.005783 +vt 0.986645 0.489562 +vt 0.560896 0.010818 +vt 0.561135 0.010791 +vt 0.560630 0.008108 +vt 0.560388 0.008134 +vt 0.561528 0.010599 +vt 0.561019 0.007862 +vt 0.560825 0.006035 +vt 0.560524 0.005804 +vt 0.560276 0.005754 +vt 0.560577 0.010818 +vt 0.561165 0.013445 +vt 0.561486 0.013446 +vt 0.560845 0.013444 +vt 0.561516 0.015420 +vt 0.561848 0.015426 +vt 0.562181 0.015432 +vt 0.280432 0.167542 +vt 0.280065 0.167601 +vt 0.560180 0.003899 +vt 0.559945 0.005748 +vt 0.560534 0.003915 +vt 0.560888 0.003930 +vt 0.279697 0.167659 +vt 0.158186 0.178925 +vt 0.161239 0.178668 +vt 0.996978 0.418890 +vt 0.995984 0.418984 +vt 0.996192 0.421933 +vt 0.997118 0.422148 +vt 0.987451 0.491184 +vt 0.559990 0.004009 +vt 0.280671 0.167562 +vt 0.562293 0.002702 +vt 0.561134 0.004059 +vt 0.562537 0.002858 +vt 0.561410 0.004931 +vt 0.998497 0.411715 +vt 0.996771 0.412327 +vt 0.996798 0.413269 +vt 0.998458 0.412787 +vt 0.064331 0.267957 +vt 0.064407 0.269593 +vt 0.566953 0.773673 +vt 0.567054 0.773027 +vt 0.566689 0.773008 +vt 0.566583 0.773747 +vt 0.210803 0.417779 +vt 0.210741 0.418499 +vt 0.211118 0.418611 +vt 0.211183 0.417823 +vt 0.917452 0.775293 +vt 0.917273 0.774549 +vt 0.916461 0.774350 +vt 0.916710 0.775552 +vt 0.918148 0.775660 +vt 0.918033 0.776052 +vt 0.272865 0.180345 +vt 0.275003 0.178231 +vt 0.274779 0.178145 +vt 0.272651 0.180247 +vt 0.149719 0.170464 +vt 0.150911 0.170244 +vt 0.149171 0.167591 +vt 0.150307 0.167462 +vt 0.155340 0.161538 +vt 0.156026 0.164085 +vt 0.159364 0.164521 +vt 0.158770 0.161567 +vt 0.156338 0.165579 +vt 0.157832 0.165925 +vt 0.158548 0.167011 +vt 0.160539 0.166832 +vt 0.162994 0.166696 +vt 0.162362 0.164243 +vt 0.161613 0.161624 +vt 0.057592 0.255741 +vt 0.059316 0.257737 +vt 0.059535 0.257645 +vt 0.057811 0.255647 +vt 0.926312 0.772510 +vt 0.925101 0.772386 +vt 0.925820 0.775041 +vt 0.924686 0.774903 +vt 0.056857 0.256177 +vt 0.058580 0.258161 +vt 0.058948 0.257949 +vt 0.057225 0.255959 +vt 0.912023 0.773986 +vt 0.912641 0.771158 +vt 0.911454 0.771042 +vt 0.910892 0.773959 +vt 0.275954 0.178843 +vt 0.275730 0.178663 +vt 0.273824 0.180963 +vt 0.273590 0.180788 +vt 0.275366 0.178447 +vt 0.273228 0.180567 +vt 0.163395 0.169164 +vt 0.164606 0.169170 +vt 0.164128 0.166687 +vt 0.058347 0.258330 +vt 0.056626 0.256350 +vt 0.158905 0.144250 +vt 0.158836 0.147438 +vt 0.159954 0.147649 +vt 0.160008 0.144519 +vt 0.158956 0.150383 +vt 0.160118 0.150522 +vt 0.039669 0.247887 +vt 0.042507 0.248693 +vt 0.042744 0.248546 +vt 0.039910 0.247754 +vt 0.036635 0.246895 +vt 0.036878 0.246777 +vt 0.251962 0.195351 +vt 0.255161 0.193110 +vt 0.254802 0.192885 +vt 0.251604 0.195126 +vt 0.258169 0.191192 +vt 0.257809 0.190967 +vt 0.257450 0.190742 +vt 0.254443 0.192660 +vt 0.251246 0.194902 +vt 0.908017 0.799684 +vt 0.907843 0.795849 +vt 0.906725 0.796059 +vt 0.906915 0.799948 +vt 0.907990 0.792314 +vt 0.906822 0.792497 +vt 0.255406 0.193243 +vt 0.258416 0.191337 +vt 0.252207 0.195470 +vt 0.040274 0.247533 +vt 0.037240 0.246556 +vt 0.043108 0.248325 +vt 0.043472 0.248104 +vt 0.040638 0.247311 +vt 0.037603 0.246335 +vt 0.040842 0.247172 +vt 0.037805 0.246182 +vt 0.043682 0.247979 +vt 0.921653 0.794027 +vt 0.921812 0.791186 +vt 0.920650 0.791205 +vt 0.920536 0.794121 +vt 0.921714 0.797128 +vt 0.920612 0.797284 +vt 0.914315 0.798462 +vt 0.914189 0.794969 +vt 0.910551 0.795459 +vt 0.910694 0.799155 +vt 0.914319 0.791784 +vt 0.910769 0.792030 +vt 0.254244 0.192516 +vt 0.251049 0.194745 +vt 0.257254 0.190610 +vt 0.145021 0.145563 +vt 0.145116 0.149117 +vt 0.146286 0.149194 +vt 0.146139 0.145664 +vt 0.145213 0.141691 +vt 0.146314 0.141843 +vt 0.152609 0.143023 +vt 0.152487 0.146521 +vt 0.156127 0.147043 +vt 0.156229 0.143718 +vt 0.152621 0.149718 +vt 0.156185 0.150128 +vt 0.153130 0.139246 +vt 0.156720 0.140006 +vt 0.159374 0.140586 +vt 0.248153 0.197416 +vt 0.247958 0.197247 +vt 0.145797 0.137779 +vt 0.146887 0.137952 +vt 0.914854 0.802268 +vt 0.911261 0.803036 +vt 0.912259 0.807023 +vt 0.908605 0.803621 +vt 0.034274 0.244772 +vt 0.034475 0.244607 +vt 0.922192 0.800776 +vt 0.921101 0.800957 +vt 0.033558 0.245217 +vt 0.033916 0.244995 +vt 0.907509 0.803907 +vt 0.249099 0.197980 +vt 0.248859 0.197869 +vt 0.248506 0.197642 +vt 0.160469 0.140873 +vt 0.033321 0.245327 +vt 0.159174 0.153361 +vt 0.160379 0.153465 +vt 0.159768 0.156214 +vt 0.160917 0.156372 +vt 0.045350 0.249626 +vt 0.048110 0.250622 +vt 0.048358 0.250467 +vt 0.045587 0.249471 +vt 0.260780 0.189618 +vt 0.260419 0.189394 +vt 0.263328 0.188153 +vt 0.262967 0.187931 +vt 0.262605 0.187708 +vt 0.260059 0.189170 +vt 0.908317 0.789240 +vt 0.907100 0.789446 +vt 0.908772 0.786389 +vt 0.907645 0.786519 +vt 0.261035 0.189768 +vt 0.263577 0.188311 +vt 0.045952 0.249251 +vt 0.048724 0.250248 +vt 0.049090 0.250029 +vt 0.046318 0.249031 +vt 0.046528 0.248916 +vt 0.922230 0.788381 +vt 0.922746 0.785487 +vt 0.922574 0.785380 +vt 0.922054 0.788267 +vt 0.921420 0.785412 +vt 0.920846 0.788248 +vt 0.913084 0.786169 +vt 0.913902 0.784932 +vt 0.912673 0.783415 +vt 0.911194 0.786221 +vt 0.915427 0.784418 +vt 0.916070 0.782695 +vt 0.917004 0.779985 +vt 0.913554 0.779970 +vt 0.910737 0.779959 +vt 0.909744 0.783272 +vt 0.259870 0.189045 +vt 0.262408 0.187592 +vt 0.145408 0.152162 +vt 0.145967 0.155085 +vt 0.147103 0.155111 +vt 0.146630 0.152264 +vt 0.155128 0.155834 +vt 0.155000 0.156940 +vt 0.157419 0.158469 +vt 0.157254 0.155981 +vt 0.153770 0.157240 +vt 0.154416 0.158848 +vt 0.160586 0.158911 +vt 0.161829 0.159102 +vt 0.162829 0.161702 +vt 0.050658 0.251611 +vt 0.052929 0.252824 +vt 0.053173 0.252653 +vt 0.050914 0.251451 +vt 0.266134 0.186551 +vt 0.265772 0.186329 +vt 0.268920 0.184767 +vt 0.268557 0.184546 +vt 0.268194 0.184325 +vt 0.265409 0.186108 +vt 0.908562 0.783305 +vt 0.909541 0.780000 +vt 0.266374 0.186721 +vt 0.269162 0.184938 +vt 0.051281 0.251233 +vt 0.053541 0.252436 +vt 0.053908 0.252218 +vt 0.051649 0.251016 +vt 0.923667 0.782771 +vt 0.923481 0.782668 +vt 0.924670 0.780193 +vt 0.924489 0.780072 +vt 0.923268 0.780020 +vt 0.922233 0.782729 +vt 0.149701 0.152740 +vt 0.149068 0.149456 +vt 0.149533 0.155280 +vt 0.151424 0.155465 +vt 0.151677 0.154340 +vt 0.153009 0.154055 +vt 0.152848 0.152453 +vt 0.145799 0.155203 +vt 0.146709 0.158429 +vt 0.146886 0.158297 +vt 0.147676 0.161727 +vt 0.147854 0.161596 +vt 0.149059 0.161534 +vt 0.148077 0.158228 +vt 0.591894 0.773731 +vt 0.591898 0.774263 +vt 0.592246 0.774462 +vt 0.592240 0.773842 +vt 0.207800 0.419002 +vt 0.207749 0.418422 +vt 0.207382 0.418655 +vt 0.207432 0.419301 +vt 0.915802 0.785409 +vt 0.915915 0.786056 +vt 0.916783 0.785838 +vt 0.916655 0.784731 +vt 0.915184 0.785188 +vt 0.429267 0.066913 +vt 0.430153 0.068895 +vt 0.430453 0.068890 +vt 0.429614 0.066903 +vt 0.806624 0.598103 +vt 0.806679 0.595729 +vt 0.806465 0.595546 +vt 0.806392 0.597808 +vt 0.067725 0.064588 +vt 0.067132 0.066542 +vt 0.069042 0.066372 +vt 0.069903 0.064420 +vt 0.065941 0.067653 +vt 0.066747 0.067787 +vt 0.807610 0.597922 +vt 0.807586 0.595629 +vt 0.807373 0.595780 +vt 0.807379 0.598173 +vt 0.069289 0.066341 +vt 0.070185 0.064378 +vt 0.280196 0.380622 +vt 0.279955 0.379814 +vt 0.279514 0.384020 +vt 0.280001 0.383957 +vt 0.806710 0.591424 +vt 0.806500 0.591413 +vt 0.806696 0.587158 +vt 0.806481 0.587314 +vt 0.279929 0.388097 +vt 0.280196 0.387231 +vt 0.807587 0.591485 +vt 0.807380 0.591467 +vt 0.062643 0.068204 +vt 0.062602 0.068668 +vt 0.059369 0.068373 +vt 0.058514 0.068714 +vt 0.807599 0.587397 +vt 0.807387 0.587209 +vt 0.807042 0.587184 +vt 0.807045 0.591445 +vt 0.807026 0.595754 +vt 0.994516 0.997379 +vt 0.994962 0.999564 +vt 0.995336 0.999523 +vt 0.994921 0.997344 +vt 0.806628 0.584869 +vt 0.807003 0.584904 +vt 0.807379 0.584939 +vt 0.995710 0.999482 +vt 0.995326 0.997310 +vt 0.057702 0.065313 +vt 0.058289 0.067414 +vt 0.062712 0.066998 +vt 0.062718 0.064953 +vt 0.806396 0.585121 +vt 0.078144 0.280195 +vt 0.078966 0.277963 +vt 0.078717 0.277911 +vt 0.077863 0.280151 +vt 0.055149 0.065466 +vt 0.056052 0.067654 +vt 0.056352 0.067629 +vt 0.055494 0.065463 +vt 0.807610 0.585235 +vt 0.712228 0.813506 +vt 0.712375 0.811542 +vt 0.711997 0.811531 +vt 0.711819 0.813503 +vt 0.807001 0.598138 +vt 0.711619 0.811519 +vt 0.711410 0.813501 +vt 0.067874 0.061815 +vt 0.062586 0.062002 +vt 0.067868 0.057243 +vt 0.062470 0.057255 +vt 0.057063 0.057260 +vt 0.057289 0.062182 +vt 0.077398 0.283402 +vt 0.077694 0.283439 +vt 0.077274 0.288413 +vt 0.077575 0.288439 +vt 0.054957 0.062251 +vt 0.054683 0.057252 +vt 0.054311 0.057230 +vt 0.054592 0.062240 +vt 0.711185 0.816192 +vt 0.711608 0.816190 +vt 0.710894 0.820669 +vt 0.711318 0.820667 +vt 0.711743 0.820664 +vt 0.712030 0.816188 +vt 0.070470 0.061691 +vt 0.070174 0.061725 +vt 0.070518 0.057206 +vt 0.070215 0.057229 +vt 0.429344 0.064195 +vt 0.429278 0.059704 +vt 0.428904 0.059740 +vt 0.428976 0.064219 +vt 0.994764 0.994122 +vt 0.994345 0.994154 +vt 0.993992 0.989167 +vt 0.993571 0.989198 +vt 0.993150 0.989229 +vt 0.993926 0.994185 +vt 0.077600 0.295633 +vt 0.077899 0.295655 +vt 0.078158 0.303564 +vt 0.078449 0.303592 +vt 0.057144 0.050048 +vt 0.054779 0.050012 +vt 0.057387 0.042022 +vt 0.055077 0.042028 +vt 0.054714 0.042009 +vt 0.054408 0.049985 +vt 0.710520 0.827710 +vt 0.710944 0.827706 +vt 0.710247 0.836013 +vt 0.710673 0.835997 +vt 0.711097 0.835985 +vt 0.711368 0.827702 +vt 0.070518 0.050161 +vt 0.070217 0.050181 +vt 0.070438 0.041883 +vt 0.070146 0.041914 +vt 0.067869 0.041944 +vt 0.067884 0.050166 +vt 0.429234 0.052667 +vt 0.429251 0.044389 +vt 0.428891 0.044436 +vt 0.428862 0.052709 +vt 0.993037 0.981985 +vt 0.992616 0.982016 +vt 0.992206 0.974045 +vt 0.991786 0.974078 +vt 0.991365 0.974111 +vt 0.992195 0.982048 +vt 0.062519 0.050110 +vt 0.062633 0.041986 +vt 0.991844 0.967087 +vt 0.991425 0.967118 +vt 0.992153 0.962004 +vt 0.991747 0.961996 +vt 0.991340 0.961985 +vt 0.991007 0.967149 +vt 0.067766 0.034381 +vt 0.062696 0.034678 +vt 0.067744 0.029002 +vt 0.062781 0.029480 +vt 0.057807 0.029942 +vt 0.057616 0.034966 +vt 0.078685 0.310443 +vt 0.078966 0.310493 +vt 0.991067 0.961946 +vt 0.990741 0.967152 +vt 0.443986 0.037569 +vt 0.443724 0.032539 +vt 0.441556 0.032265 +vt 0.441776 0.037404 +vt 0.055378 0.035083 +vt 0.055614 0.030126 +vt 0.055262 0.030110 +vt 0.055023 0.035079 +vt 0.710270 0.843802 +vt 0.710697 0.843756 +vt 0.710611 0.849466 +vt 0.711025 0.849362 +vt 0.711429 0.849274 +vt 0.711118 0.843720 +vt 0.436570 0.031710 +vt 0.436691 0.037063 +vt 0.431585 0.031194 +vt 0.431601 0.036745 +vt 0.070250 0.034174 +vt 0.069970 0.034235 +vt 0.070169 0.028663 +vt 0.069899 0.028765 +vt 0.429408 0.031038 +vt 0.429371 0.036649 +vt 0.429080 0.031132 +vt 0.429029 0.036709 +vt 0.711939 0.851628 +vt 0.712195 0.851499 +vt 0.711690 0.849192 +vt 0.589126 0.024939 +vt 0.588627 0.024587 +vt 0.588398 0.024888 +vt 0.588904 0.025228 +vt 0.588177 0.027149 +vt 0.588800 0.027414 +vt 0.070123 0.026508 +vt 0.067957 0.026730 +vt 0.431375 0.028621 +vt 0.429189 0.028547 +vt 0.572440 0.773261 +vt 0.571728 0.773508 +vt 0.571828 0.775766 +vt 0.572440 0.775444 +vt 0.428813 0.027967 +vt 0.428464 0.028210 +vt 0.428858 0.028706 +vt 0.993147 0.959207 +vt 0.992768 0.959099 +vt 0.994219 0.958018 +vt 0.993856 0.957798 +vt 0.993478 0.957565 +vt 0.992382 0.958983 +vt 0.062965 0.027121 +vt 0.587898 0.032327 +vt 0.588768 0.032432 +vt 0.587690 0.037515 +vt 0.588798 0.037457 +vt 0.057959 0.027478 +vt 0.992097 0.958876 +vt 0.993161 0.957382 +vt 0.443581 0.029748 +vt 0.443609 0.028507 +vt 0.441349 0.028273 +vt 0.441394 0.029476 +vt 0.055749 0.027591 +vt 0.587690 0.039809 +vt 0.588902 0.039668 +vt 0.587887 0.040181 +vt 0.589126 0.040009 +vt 0.055387 0.027511 +vt 0.711193 0.851986 +vt 0.711571 0.851797 +vt 0.711716 0.852557 +vt 0.712048 0.852290 +vt 0.712375 0.852042 +vt 0.436383 0.029015 +vt 0.436202 0.028027 +vt 0.431062 0.027887 +vt 0.985201 0.682004 +vt 0.985386 0.684067 +vt 0.985470 0.684240 +vt 0.985378 0.682139 +vt 0.938510 0.733152 +vt 0.938817 0.732928 +vt 0.938884 0.732711 +vt 0.938473 0.732991 +vt 0.938976 0.732477 +vt 0.938497 0.732724 +vt 0.985570 0.684525 +vt 0.985692 0.682888 +vt 0.994409 0.957296 +vt 0.994007 0.956990 +vt 0.994787 0.957588 +vt 0.994991 0.957460 +vt 0.994593 0.957138 +vt 0.994164 0.956804 +vt 0.428311 0.028805 +vt 0.428391 0.028517 +vt 0.427984 0.028485 +vt 0.427912 0.028807 +vt 0.428061 0.028144 +vt 0.427759 0.028127 +vt 0.427679 0.028471 +vt 0.427614 0.028795 +vt 0.939693 0.734662 +vt 0.939800 0.739822 +vt 0.940017 0.739811 +vt 0.939889 0.734429 +vt 0.939831 0.745003 +vt 0.940015 0.745217 +vt 0.940331 0.746114 +vt 0.940373 0.739883 +vt 0.940218 0.733641 +vt 0.984837 0.671697 +vt 0.985009 0.676900 +vt 0.985209 0.676838 +vt 0.984994 0.671448 +vt 0.985550 0.676750 +vt 0.985282 0.670545 +vt 0.587404 0.032264 +vt 0.587073 0.037740 +vt 0.587847 0.026807 +vt 0.587592 0.025850 +vt 0.586999 0.032161 +vt 0.586596 0.038524 +vt 0.591240 0.293586 +vt 0.590920 0.293370 +vt 0.590932 0.293629 +vt 0.591276 0.293851 +vt 0.939552 0.732440 +vt 0.939675 0.732195 +vt 0.939803 0.731849 +vt 0.590966 0.293996 +vt 0.591320 0.294129 +vt 0.938868 0.747888 +vt 0.938604 0.747583 +vt 0.938498 0.747847 +vt 0.938826 0.748169 +vt 0.938413 0.745319 +vt 0.938249 0.745583 +vt 0.984731 0.669131 +vt 0.984806 0.668758 +vt 0.938431 0.748225 +vt 0.938798 0.748454 +vt 0.939530 0.747712 +vt 0.939455 0.747369 +vt 0.939159 0.747399 +vt 0.939206 0.747812 +vt 0.592033 0.278305 +vt 0.591983 0.279406 +vt 0.592171 0.280104 +vt 0.592323 0.278331 +vt 0.939085 0.745635 +vt 0.938863 0.746420 +vt 0.938857 0.747539 +vt 0.939557 0.734927 +vt 0.939646 0.739812 +vt 0.939432 0.736006 +vt 0.939442 0.739847 +vt 0.939540 0.743658 +vt 0.939693 0.744710 +vt 0.984700 0.671988 +vt 0.984845 0.676922 +vt 0.984578 0.673072 +vt 0.984645 0.676920 +vt 0.984882 0.680691 +vt 0.985049 0.681760 +vt 0.985255 0.683743 +vt 0.938383 0.735384 +vt 0.938483 0.736422 +vt 0.938628 0.735215 +vt 0.938523 0.733454 +vt 0.938766 0.734110 +vt 0.938759 0.733171 +vt 0.939631 0.746916 +vt 0.939744 0.747310 +vt 0.939425 0.745034 +vt 0.939339 0.746281 +vt 0.591202 0.293280 +vt 0.590906 0.292997 +vt 0.591292 0.292177 +vt 0.591130 0.291047 +vt 0.939439 0.732797 +vt 0.939286 0.734743 +vt 0.984414 0.669057 +vt 0.984351 0.669400 +vt 0.984553 0.669784 +vt 0.984655 0.669391 +vt 0.984279 0.670520 +vt 0.984418 0.671730 +vt 0.592323 0.293172 +vt 0.592247 0.292903 +vt 0.591782 0.292990 +vt 0.591835 0.293339 +vt 0.592091 0.291903 +vt 0.591742 0.291304 +vt 0.938547 0.740124 +vt 0.938994 0.740044 +vt 0.938564 0.743926 +vt 0.938717 0.745236 +vt 0.591789 0.280643 +vt 0.591854 0.285765 +vt 0.591574 0.282009 +vt 0.591355 0.285866 +vt 0.591063 0.289740 +vt 0.592130 0.290773 +vt 0.442300 0.027312 +vt 0.441450 0.026710 +vt 0.435832 0.026606 +vt 0.436007 0.027152 +vt 0.985946 0.670959 +vt 0.986086 0.676655 +vt 0.986181 0.682329 +vt 0.430233 0.026606 +vt 0.429756 0.027238 +vt 0.525017 0.773033 +vt 0.524797 0.773103 +vt 0.524911 0.773327 +vt 0.525120 0.773253 +vt 0.410241 0.238103 +vt 0.409931 0.238165 +vt 0.409902 0.238382 +vt 0.410193 0.238310 +vt 0.524691 0.773428 +vt 0.524873 0.773952 +vt 0.525098 0.773859 +vt 0.525283 0.773792 +vt 0.586882 0.026200 +vt 0.586392 0.031935 +vt 0.586411 0.025399 +vt 0.585886 0.031723 +vt 0.585383 0.038033 +vt 0.585959 0.037681 +vt 0.938775 0.535278 +vt 0.939256 0.535276 +vt 0.939217 0.535030 +vt 0.938777 0.535032 +vt 0.939637 0.535298 +vt 0.939572 0.535049 +vt 0.939568 0.534385 +vt 0.939244 0.534368 +vt 0.938851 0.534369 +vt 0.917493 0.410420 +vt 0.917795 0.410464 +vt 0.917836 0.410272 +vt 0.917569 0.410237 +vt 0.918096 0.410623 +vt 0.918104 0.410414 +vt 0.918220 0.409812 +vt 0.918002 0.409694 +vt 0.917773 0.409670 +vt 0.214933 0.298422 +vt 0.214538 0.298554 +vt 0.214615 0.298794 +vt 0.214971 0.298668 +vt 0.526048 0.772836 +vt 0.525605 0.772969 +vt 0.525638 0.773186 +vt 0.526041 0.773062 +vt 0.525704 0.773729 +vt 0.526058 0.773616 +vt 0.214714 0.299366 +vt 0.215029 0.299251 +vt 0.215168 0.692491 +vt 0.215133 0.692839 +vt 0.215377 0.692902 +vt 0.215411 0.692581 +vt 0.215171 0.693206 +vt 0.215411 0.693242 +vt 0.918442 0.410565 +vt 0.918803 0.410660 +vt 0.918780 0.410015 +vt 0.918491 0.409938 +vt 0.525266 0.773013 +vt 0.525340 0.773229 +vt 0.525458 0.773769 +vt 0.939203 0.748103 +vt 0.939566 0.747986 +vt 0.939207 0.748396 +vt 0.939601 0.748263 +vt 0.587065 0.040085 +vt 0.587280 0.040478 +vt 0.586817 0.040435 +vt 0.587080 0.040742 +vt 0.591841 0.293598 +vt 0.592319 0.293396 +vt 0.591856 0.293876 +vt 0.592322 0.293640 +vt 0.939848 0.747554 +vt 0.939951 0.747912 +vt 0.428412 0.027814 +vt 0.571462 0.773856 +vt 0.571590 0.776149 +vt 0.430688 0.027583 +vt 0.428011 0.027729 +vt 0.443837 0.027977 +vt 0.441531 0.027713 +vt 0.993634 0.956737 +vt 0.444153 0.028308 +vt 0.444400 0.028161 +vt 0.444173 0.027771 +vt 0.588186 0.024514 +vt 0.588453 0.024205 +vt 0.588431 0.023908 +vt 0.588127 0.024116 +vt 0.436101 0.027563 +vt 0.497895 0.372595 +vt 0.497880 0.372234 +vt 0.497746 0.372258 +vt 0.497768 0.372639 +vt 0.497889 0.371891 +vt 0.497753 0.371882 +vt 0.427548 0.028416 +vt 0.427477 0.028723 +vt 0.427639 0.028088 +vt 0.995123 0.957251 +vt 0.994745 0.956948 +vt 0.994696 0.957026 +vt 0.995093 0.957347 +vt 0.994340 0.956634 +vt 0.994269 0.956693 +vt 0.995699 0.957457 +vt 0.995406 0.957463 +vt 0.995398 0.957586 +vt 0.995710 0.957598 +vt 0.586692 0.040682 +vt 0.586968 0.040826 +vt 0.586357 0.040357 +vt 0.498169 0.373349 +vt 0.497964 0.372994 +vt 0.497857 0.373057 +vt 0.498136 0.373429 +vt 0.427743 0.027691 +vt 0.427926 0.027225 +vt 0.994023 0.956351 +vt 0.993912 0.956380 +vt 0.993934 0.956013 +vt 0.993778 0.955997 +vt 0.444400 0.027694 +vt 0.444087 0.027287 +vt 0.993766 0.956493 +vt 0.497938 0.371547 +vt 0.497810 0.371482 +vt 0.498169 0.371297 +vt 0.498087 0.371161 +vt 0.588083 0.023815 +vt 0.587677 0.023942 +vt 0.588367 0.023778 +vt 0.587679 0.023767 +vt 0.587234 0.023628 +vt 0.587145 0.023876 +vt 0.586904 0.023459 +vt 0.586766 0.023589 +vt 0.215303 0.689523 +vt 0.215355 0.689136 +vt 0.215054 0.689136 +vt 0.215086 0.689564 +vt 0.585914 0.040312 +vt 0.586358 0.040508 +vt 0.585841 0.040033 +vt 0.585413 0.039967 +vt 0.279534 0.320688 +vt 0.279655 0.321107 +vt 0.279862 0.321165 +vt 0.279686 0.320711 +vt 0.279708 0.321384 +vt 0.279941 0.321470 +vt 0.985688 0.684772 +vt 0.985876 0.684660 +vt 0.280094 0.321175 +vt 0.279856 0.320728 +vt 0.279792 0.319751 +vt 0.279623 0.320210 +vt 0.279743 0.320218 +vt 0.279896 0.319742 +vt 0.279897 0.320218 +vt 0.591414 0.294252 +vt 0.591933 0.294008 +vt 0.986064 0.668210 +vt 0.985745 0.668371 +vt 0.985825 0.668634 +vt 0.986198 0.668355 +vt 0.985294 0.668471 +vt 0.985296 0.668656 +vt 0.443736 0.026832 +vt 0.985952 0.684798 +vt 0.986192 0.684823 +vt 0.986198 0.684605 +vt 0.427779 0.026894 +vt 0.427802 0.027273 +vt 0.427990 0.026742 +vt 0.279617 0.319179 +vt 0.279832 0.319390 +vt 0.279922 0.319328 +vt 0.279687 0.319042 +vt 0.280046 0.319720 +vt 0.280094 0.319256 +vt 0.940247 0.731874 +vt 0.939882 0.731615 +vt 0.497899 0.375173 +vt 0.497881 0.374640 +vt 0.497746 0.374635 +vt 0.497765 0.375195 +vt 0.497880 0.374144 +vt 0.497748 0.374111 +vt 0.939271 0.748546 +vt 0.939665 0.748412 +vt 0.938861 0.748603 +vt 0.497936 0.373783 +vt 0.497817 0.373708 +vt 0.498177 0.373585 +vt 0.498109 0.373478 +vt 0.940011 0.748230 +vt 0.940373 0.748042 +vt 0.498177 0.375941 +vt 0.497950 0.375633 +vt 0.497822 0.375704 +vt 0.498093 0.376077 +vt 0.984869 0.668456 +vt 0.984501 0.668348 +vt 0.984437 0.668487 +vt 0.594116 0.774077 +vt 0.593908 0.774133 +vt 0.593961 0.775035 +vt 0.594138 0.774994 +vt 0.593578 0.774108 +vt 0.593709 0.775007 +vt 0.942567 0.532885 +vt 0.942818 0.532951 +vt 0.943080 0.531797 +vt 0.942848 0.531751 +vt 0.942386 0.532898 +vt 0.942671 0.531756 +vt 0.944231 0.428955 +vt 0.944486 0.428938 +vt 0.944673 0.427727 +vt 0.944518 0.427738 +vt 0.944773 0.428958 +vt 0.944866 0.427747 +vt 0.944977 0.426200 +vt 0.944907 0.426180 +vt 0.944881 0.426184 +vt 0.525426 0.774799 +vt 0.525560 0.774750 +vt 0.525218 0.774872 +vt 0.525663 0.776023 +vt 0.525842 0.775977 +vt 0.525905 0.775952 +vt 0.918343 0.408599 +vt 0.918186 0.408592 +vt 0.918472 0.408673 +vt 0.918803 0.407220 +vt 0.918785 0.407203 +vt 0.918724 0.407215 +vt 0.214887 0.300394 +vt 0.215118 0.300305 +vt 0.525801 0.774699 +vt 0.526058 0.774611 +vt 0.214675 0.300476 +vt 0.214937 0.301731 +vt 0.215105 0.301690 +vt 0.215226 0.301636 +vt 0.215288 0.688638 +vt 0.215288 0.688309 +vt 0.215064 0.688413 +vt 0.215062 0.688707 +vt 0.944314 0.429794 +vt 0.944688 0.429812 +vt 0.944714 0.429595 +vt 0.944377 0.429576 +vt 0.944068 0.429597 +vt 0.594138 0.773291 +vt 0.593914 0.773361 +vt 0.593871 0.773608 +vt 0.594087 0.773546 +vt 0.593519 0.773352 +vt 0.593506 0.773588 +vt 0.932701 0.900976 +vt 0.933079 0.901020 +vt 0.933132 0.900763 +vt 0.932787 0.900727 +vt 0.933455 0.901017 +vt 0.933473 0.900759 +vt 0.933544 0.900087 +vt 0.933271 0.900094 +vt 0.932996 0.900069 +vt 0.942538 0.534633 +vt 0.942971 0.534930 +vt 0.942972 0.534699 +vt 0.942526 0.534407 +vt 0.943443 0.535232 +vt 0.943445 0.534995 +vt 0.943494 0.534421 +vt 0.943052 0.534147 +vt 0.942618 0.533876 +vt 0.933731 0.900976 +vt 0.933718 0.900723 +vt 0.938441 0.535290 +vt 0.938477 0.535041 +vt 0.938594 0.534376 +vt 0.938230 0.535035 +vt 0.938390 0.534372 +vt 0.945122 0.429981 +vt 0.945111 0.429752 +vt 0.931773 0.900305 +vt 0.932092 0.900628 +vt 0.932245 0.900417 +vt 0.931955 0.900120 +vt 0.932552 0.899807 +vt 0.932296 0.899543 +vt 0.945125 0.429101 +vt 0.409562 0.238197 +vt 0.409543 0.238424 +vt 0.409153 0.238175 +vt 0.409154 0.238413 +vt 0.409129 0.238932 +vt 0.409502 0.238933 +vt 0.409840 0.238885 +vt 0.408772 0.238103 +vt 0.408816 0.238350 +vt 0.941896 0.534585 +vt 0.942138 0.534581 +vt 0.942113 0.534347 +vt 0.941902 0.534345 +vt 0.942181 0.533816 +vt 0.941984 0.533814 +vt 0.408816 0.238879 +vt 0.932390 0.900856 +vt 0.932510 0.900622 +vt 0.932773 0.899984 +vt 0.943743 0.535316 +vt 0.943727 0.535077 +vt 0.215246 0.298382 +vt 0.215239 0.298625 +vt 0.215245 0.299208 +vt 0.943743 0.534501 +vt 0.937871 0.534270 +vt 0.938132 0.534339 +vt 0.938597 0.533114 +vt 0.938442 0.533077 +vt 0.933630 0.898784 +vt 0.933479 0.898795 +vt 0.938750 0.533131 +vt 0.939231 0.531550 +vt 0.939213 0.531554 +vt 0.939193 0.531557 +vt 0.943191 0.533167 +vt 0.943545 0.533387 +vt 0.943592 0.532083 +vt 0.943361 0.531938 +vt 0.938872 0.533132 +vt 0.939049 0.533129 +vt 0.939322 0.531549 +vt 0.939250 0.531548 +vt 0.945125 0.427858 +vt 0.933061 0.898616 +vt 0.932875 0.898418 +vt 0.933689 0.897081 +vt 0.933594 0.896973 +vt 0.945113 0.426268 +vt 0.524625 0.774036 +vt 0.524948 0.774947 +vt 0.409098 0.239823 +vt 0.409417 0.239810 +vt 0.409066 0.240930 +vt 0.409305 0.240901 +vt 0.525377 0.776085 +vt 0.408843 0.239787 +vt 0.942220 0.532897 +vt 0.942550 0.531755 +vt 0.408892 0.240918 +vt 0.943722 0.533457 +vt 0.215246 0.300269 +vt 0.215242 0.301610 +vt 0.943673 0.532138 +vt 0.525654 0.774732 +vt 0.214597 0.300512 +vt 0.214615 0.300542 +vt 0.214667 0.301726 +vt 0.214786 0.301733 +vt 0.943707 0.428813 +vt 0.943955 0.428909 +vt 0.944354 0.427710 +vt 0.944207 0.427648 +vt 0.944860 0.426178 +vt 0.944841 0.426161 +vt 0.579226 0.080201 +vt 0.578881 0.080203 +vt 0.578107 0.082215 +vt 0.578406 0.082211 +vt 0.964138 0.014845 +vt 0.964175 0.012906 +vt 0.963145 0.011641 +vt 0.962913 0.012451 +vt 0.165353 0.166369 +vt 0.165122 0.166664 +vt 0.165195 0.168925 +vt 0.165409 0.168742 +vt 0.967983 0.415055 +vt 0.970158 0.415246 +vt 0.969318 0.413286 +vt 0.967411 0.413095 +vt 0.426986 0.044305 +vt 0.426724 0.044279 +vt 0.426906 0.046253 +vt 0.427148 0.046268 +vt 0.166340 0.166550 +vt 0.166108 0.166299 +vt 0.166103 0.168691 +vt 0.166315 0.168842 +vt 0.967039 0.411846 +vt 0.966232 0.411971 +vt 0.964159 0.008458 +vt 0.964175 0.004022 +vt 0.963074 0.005032 +vt 0.962914 0.008308 +vt 0.962427 0.008250 +vt 0.962798 0.004168 +vt 0.165229 0.173057 +vt 0.165210 0.177156 +vt 0.165425 0.177312 +vt 0.165440 0.173046 +vt 0.166110 0.173003 +vt 0.166316 0.172985 +vt 0.166117 0.177261 +vt 0.166328 0.177073 +vt 0.962904 0.410920 +vt 0.958817 0.410830 +vt 0.959670 0.411180 +vt 0.962941 0.411385 +vt 0.165775 0.173025 +vt 0.165771 0.177286 +vt 0.165756 0.168717 +vt 0.993222 0.246392 +vt 0.993626 0.246415 +vt 0.993945 0.244235 +vt 0.993571 0.244204 +vt 0.994030 0.246438 +vt 0.994318 0.244265 +vt 0.165733 0.179567 +vt 0.166108 0.179532 +vt 0.165357 0.179602 +vt 0.957970 0.414222 +vt 0.962981 0.414636 +vt 0.962998 0.412591 +vt 0.958579 0.412127 +vt 0.564506 0.081646 +vt 0.564227 0.081707 +vt 0.565210 0.083893 +vt 0.565457 0.083826 +vt 0.165125 0.179350 +vt 0.964132 0.002096 +vt 0.955417 0.414041 +vt 0.955764 0.414048 +vt 0.956644 0.411891 +vt 0.956343 0.411863 +vt 0.166340 0.179236 +vt 0.426317 0.044282 +vt 0.426530 0.046265 +vt 0.425910 0.044286 +vt 0.426153 0.046278 +vt 0.165731 0.166334 +vt 0.962818 0.417586 +vt 0.968102 0.417829 +vt 0.957523 0.417348 +vt 0.957244 0.422268 +vt 0.962651 0.422331 +vt 0.968047 0.422401 +vt 0.563866 0.078435 +vt 0.563572 0.078489 +vt 0.563454 0.073450 +vt 0.563153 0.073493 +vt 0.955191 0.417253 +vt 0.954824 0.417261 +vt 0.954489 0.422268 +vt 0.954864 0.422249 +vt 0.426091 0.041594 +vt 0.425671 0.041593 +vt 0.426511 0.041594 +vt 0.426214 0.037118 +vt 0.425792 0.037117 +vt 0.425370 0.037116 +vt 0.970437 0.415292 +vt 0.970400 0.417945 +vt 0.970693 0.417982 +vt 0.970393 0.422440 +vt 0.970693 0.422467 +vt 0.579428 0.077499 +vt 0.579062 0.077486 +vt 0.579352 0.073020 +vt 0.578979 0.072997 +vt 0.993164 0.249616 +vt 0.993581 0.249635 +vt 0.992746 0.249596 +vt 0.992125 0.254570 +vt 0.992544 0.254590 +vt 0.992964 0.254609 +vt 0.563347 0.066336 +vt 0.563047 0.066375 +vt 0.563391 0.059144 +vt 0.563098 0.059183 +vt 0.954876 0.429379 +vt 0.957244 0.429363 +vt 0.954502 0.429403 +vt 0.954673 0.436611 +vt 0.955040 0.436588 +vt 0.957361 0.436572 +vt 0.425393 0.030235 +vt 0.424970 0.030234 +vt 0.425815 0.030236 +vt 0.425446 0.023026 +vt 0.425024 0.023025 +vt 0.424600 0.023023 +vt 0.970323 0.429338 +vt 0.970621 0.429360 +vt 0.967989 0.429334 +vt 0.967894 0.436549 +vt 0.970181 0.436555 +vt 0.970473 0.436577 +vt 0.579166 0.066144 +vt 0.578794 0.066115 +vt 0.578899 0.058946 +vt 0.578537 0.058915 +vt 0.991779 0.261686 +vt 0.992198 0.261705 +vt 0.991359 0.261666 +vt 0.990631 0.268838 +vt 0.991051 0.268858 +vt 0.991470 0.268877 +vt 0.962622 0.429345 +vt 0.962633 0.436558 +vt 0.990756 0.278138 +vt 0.990337 0.278118 +vt 0.990435 0.281889 +vt 0.990854 0.281903 +vt 0.989917 0.278099 +vt 0.990016 0.281874 +vt 0.990541 0.285409 +vt 0.990955 0.285387 +vt 0.991366 0.285366 +vt 0.967443 0.446159 +vt 0.962436 0.446034 +vt 0.962333 0.449821 +vt 0.967210 0.449995 +vt 0.957418 0.445915 +vt 0.957446 0.449654 +vt 0.957690 0.452910 +vt 0.962441 0.452911 +vt 0.967183 0.452925 +vt 0.563125 0.049938 +vt 0.563403 0.049891 +vt 0.563427 0.046184 +vt 0.563155 0.046238 +vt 0.565588 0.049777 +vt 0.565559 0.046044 +vt 0.565777 0.042690 +vt 0.563695 0.042774 +vt 0.989747 0.281873 +vt 0.990268 0.285422 +vt 0.955208 0.445872 +vt 0.955293 0.449591 +vt 0.954857 0.445887 +vt 0.954951 0.449606 +vt 0.955267 0.452974 +vt 0.955598 0.452928 +vt 0.424462 0.013324 +vt 0.424894 0.013332 +vt 0.425225 0.009425 +vt 0.424791 0.009408 +vt 0.425317 0.013334 +vt 0.425648 0.009432 +vt 0.426163 0.006501 +vt 0.425749 0.006459 +vt 0.425321 0.006406 +vt 0.570612 0.049548 +vt 0.570462 0.045762 +vt 0.575639 0.049336 +vt 0.575362 0.045500 +vt 0.575317 0.042467 +vt 0.570551 0.042563 +vt 0.969894 0.446253 +vt 0.969619 0.446223 +vt 0.969329 0.450081 +vt 0.969597 0.450117 +vt 0.969244 0.452949 +vt 0.425914 0.009449 +vt 0.426426 0.006528 +vt 0.577836 0.049272 +vt 0.577495 0.045423 +vt 0.578165 0.049311 +vt 0.577806 0.045471 +vt 0.577677 0.042561 +vt 0.577384 0.042477 +vt 0.426993 0.005267 +vt 0.426729 0.005221 +vt 0.967483 0.454320 +vt 0.969493 0.454156 +vt 0.997391 0.843655 +vt 0.997352 0.845679 +vt 0.997990 0.845354 +vt 0.997905 0.843320 +vt 0.997176 0.843356 +vt 0.997673 0.842999 +vt 0.577652 0.041044 +vt 0.575648 0.040792 +vt 0.425045 0.006355 +vt 0.425933 0.004967 +vt 0.425675 0.004830 +vt 0.426410 0.004586 +vt 0.426167 0.004342 +vt 0.578112 0.040621 +vt 0.576134 0.040086 +vt 0.991905 0.288298 +vt 0.992301 0.288197 +vt 0.991501 0.288404 +vt 0.992420 0.290499 +vt 0.992829 0.290302 +vt 0.993222 0.290109 +vt 0.962869 0.454786 +vt 0.958249 0.455280 +vt 0.958753 0.456679 +vt 0.963325 0.455638 +vt 0.997045 0.850291 +vt 0.997933 0.849954 +vt 0.991212 0.288445 +vt 0.566362 0.040041 +vt 0.564318 0.039947 +vt 0.566925 0.038268 +vt 0.564871 0.037991 +vt 0.992091 0.290575 +vt 0.956216 0.455536 +vt 0.955900 0.455662 +vt 0.956428 0.457441 +vt 0.956740 0.457212 +vt 0.426338 0.005100 +vt 0.427148 0.005004 +vt 0.426784 0.004803 +vt 0.571014 0.040390 +vt 0.571544 0.039133 +vt 0.825385 0.866350 +vt 0.825582 0.866189 +vt 0.825625 0.864521 +vt 0.825532 0.864689 +vt 0.825901 0.865552 +vt 0.825727 0.864280 +vt 0.279672 0.356799 +vt 0.279710 0.357055 +vt 0.280143 0.357299 +vt 0.280047 0.357064 +vt 0.279694 0.356643 +vt 0.279978 0.356846 +vt 0.992855 0.291481 +vt 0.993297 0.291228 +vt 0.992983 0.291792 +vt 0.993456 0.291519 +vt 0.993896 0.291237 +vt 0.993713 0.290975 +vt 0.997855 0.842631 +vt 0.997536 0.842582 +vt 0.997327 0.842966 +vt 0.997884 0.842343 +vt 0.997586 0.842289 +vt 0.578796 0.041202 +vt 0.579095 0.041265 +vt 0.579091 0.040953 +vt 0.578793 0.040898 +vt 0.997222 0.842533 +vt 0.996975 0.842921 +vt 0.756200 0.786227 +vt 0.756399 0.786449 +vt 0.756392 0.781557 +vt 0.756188 0.781549 +vt 0.756765 0.787168 +vt 0.756757 0.781477 +vt 0.756560 0.775800 +vt 0.756270 0.776643 +vt 0.756113 0.776850 +vt 0.825019 0.875191 +vt 0.825190 0.875372 +vt 0.825423 0.870706 +vt 0.825203 0.870698 +vt 0.825471 0.876175 +vt 0.825760 0.870809 +vt 0.997797 0.854543 +vt 0.998424 0.854587 +vt 0.998450 0.849816 +vt 0.998850 0.855240 +vt 0.998853 0.849691 +vt 0.998656 0.844173 +vt 0.998350 0.845033 +vt 0.214453 0.296404 +vt 0.214630 0.296395 +vt 0.214528 0.295977 +vt 0.214336 0.296035 +vt 0.214823 0.296389 +vt 0.214772 0.295937 +vt 0.756268 0.788478 +vt 0.756418 0.788809 +vt 0.756130 0.788238 +vt 0.824541 0.877588 +vt 0.824547 0.877840 +vt 0.824894 0.877435 +vt 0.824814 0.877225 +vt 0.824551 0.878101 +vt 0.824967 0.877758 +vt 0.823827 0.877675 +vt 0.824177 0.877645 +vt 0.824156 0.877261 +vt 0.823832 0.877342 +vt 0.824486 0.877273 +vt 0.824413 0.876307 +vt 0.824166 0.875708 +vt 0.823891 0.876358 +vt 0.756040 0.781561 +vt 0.756056 0.785985 +vt 0.755989 0.777124 +vt 0.755869 0.778078 +vt 0.755856 0.781528 +vt 0.755920 0.785008 +vt 0.825028 0.870702 +vt 0.824876 0.874953 +vt 0.825223 0.866578 +vt 0.825046 0.867516 +vt 0.824810 0.870743 +vt 0.824745 0.874039 +vt 0.825398 0.864963 +vt 0.279909 0.356621 +vt 0.279690 0.356368 +vt 0.279899 0.355786 +vt 0.279782 0.354792 +vt 0.279569 0.354641 +vt 0.279663 0.353708 +vt 0.755996 0.774754 +vt 0.755897 0.775123 +vt 0.755810 0.774382 +vt 0.755744 0.774708 +vt 0.823639 0.877013 +vt 0.823793 0.875311 +vt 0.755748 0.776828 +vt 0.824345 0.864246 +vt 0.823992 0.864436 +vt 0.823957 0.864715 +vt 0.824289 0.864475 +vt 0.756002 0.787911 +vt 0.755827 0.786145 +vt 0.824033 0.866350 +vt 0.824296 0.865392 +vt 0.824712 0.876884 +vt 0.824568 0.875230 +vt 0.825429 0.864608 +vt 0.824931 0.864481 +vt 0.824858 0.864746 +vt 0.825338 0.864808 +vt 0.824687 0.866142 +vt 0.825103 0.865624 +vt 0.280143 0.350467 +vt 0.279777 0.350371 +vt 0.824338 0.870837 +vt 0.825069 0.866527 +vt 0.823840 0.867495 +vt 0.823801 0.870825 +vt 0.823681 0.874159 +vt 0.566470 0.036729 +vt 0.572055 0.038090 +vt 0.572388 0.037537 +vt 0.567419 0.036282 +vt 0.577540 0.039667 +vt 0.577314 0.038880 +vt 0.578004 0.038600 +vt 0.572699 0.037132 +vt 0.826072 0.876027 +vt 0.826232 0.871092 +vt 0.592397 0.774413 +vt 0.592551 0.774417 +vt 0.592558 0.774099 +vt 0.592416 0.774062 +vt 0.457568 0.773366 +vt 0.457277 0.773295 +vt 0.457266 0.773502 +vt 0.457573 0.773605 +vt 0.457252 0.773757 +vt 0.457568 0.773862 +vt 0.592589 0.773738 +vt 0.592464 0.773691 +vt 0.999411 0.849354 +vt 0.999278 0.844333 +vt 0.999477 0.854364 +vt 0.757330 0.781199 +vt 0.757186 0.776022 +vt 0.757410 0.786359 +vt 0.824349 0.879010 +vt 0.824453 0.878771 +vt 0.824079 0.878512 +vt 0.823940 0.878730 +vt 0.824668 0.878160 +vt 0.824330 0.877923 +vt 0.824058 0.877699 +vt 0.823788 0.878270 +vt 0.823629 0.878468 +vt 0.576228 0.776103 +vt 0.576227 0.775920 +vt 0.575950 0.775897 +vt 0.575917 0.776083 +vt 0.576228 0.775371 +vt 0.575988 0.775345 +vt 0.575775 0.775421 +vt 0.575691 0.775987 +vt 0.211490 0.323050 +vt 0.211652 0.322951 +vt 0.211563 0.322624 +vt 0.211390 0.322683 +vt 0.504224 0.773003 +vt 0.504237 0.773223 +vt 0.504658 0.773253 +vt 0.504686 0.773030 +vt 0.504271 0.773610 +vt 0.504645 0.773639 +vt 0.504960 0.773677 +vt 0.504991 0.773301 +vt 0.505039 0.773085 +vt 0.211522 0.322160 +vt 0.211341 0.322177 +vt 0.411535 0.240927 +vt 0.411527 0.240317 +vt 0.411253 0.240215 +vt 0.411203 0.240797 +vt 0.410974 0.240054 +vt 0.410864 0.240597 +vt 0.211509 0.321670 +vt 0.211325 0.321642 +vt 0.592632 0.775031 +vt 0.592777 0.774933 +vt 0.592587 0.774711 +vt 0.592429 0.774760 +vt 0.457573 0.772821 +vt 0.457315 0.772863 +vt 0.457260 0.773104 +vt 0.457529 0.773121 +vt 0.823762 0.877949 +vt 0.824143 0.877922 +vt 0.823709 0.878226 +vt 0.824115 0.878202 +vt 0.993975 0.290691 +vt 0.993445 0.289904 +vt 0.994219 0.290950 +vt 0.998266 0.856596 +vt 0.998499 0.856883 +vt 0.956778 0.457920 +vt 0.958795 0.457226 +vt 0.825444 0.864423 +vt 0.824959 0.864272 +vt 0.825466 0.864231 +vt 0.824994 0.864051 +vt 0.824469 0.863812 +vt 0.824402 0.864033 +vt 0.756072 0.774512 +vt 0.756151 0.774165 +vt 0.823498 0.877671 +vt 0.823416 0.878039 +vt 0.823605 0.877402 +vt 0.578375 0.040893 +vt 0.578552 0.040534 +vt 0.578954 0.040543 +vt 0.576600 0.039798 +vt 0.567027 0.037366 +vt 0.564938 0.037047 +vt 0.564702 0.036698 +vt 0.992460 0.291599 +vt 0.992552 0.291977 +vt 0.998135 0.842978 +vt 0.998213 0.842615 +vt 0.571841 0.038510 +vt 0.592329 0.773647 +vt 0.592277 0.774036 +vt 0.579223 0.040930 +vt 0.579240 0.041234 +vt 0.997667 0.842153 +vt 0.997941 0.842195 +vt 0.592259 0.774417 +vt 0.824942 0.879155 +vt 0.824983 0.879267 +vt 0.825380 0.879234 +vt 0.825320 0.879123 +vt 0.993981 0.291379 +vt 0.993542 0.291659 +vt 0.993071 0.291931 +vt 0.825802 0.879143 +vt 0.825722 0.879042 +vt 0.215289 0.688014 +vt 0.215126 0.687975 +vt 0.215183 0.688290 +vt 0.215289 0.688301 +vt 0.998949 0.856787 +vt 0.998595 0.857070 +vt 0.994318 0.291150 +vt 0.215297 0.691820 +vt 0.215403 0.691895 +vt 0.215403 0.691607 +vt 0.215272 0.691582 +vt 0.592777 0.772946 +vt 0.592762 0.772845 +vt 0.592448 0.773225 +vt 0.592560 0.773289 +vt 0.579169 0.040066 +vt 0.579216 0.040554 +vt 0.826142 0.878942 +vt 0.826028 0.878892 +vt 0.992674 0.292159 +vt 0.564524 0.036546 +vt 0.564914 0.036241 +vt 0.826232 0.878523 +vt 0.826095 0.878649 +vt 0.592304 0.774814 +vt 0.998259 0.842312 +vt 0.998663 0.842441 +vt 0.998307 0.842265 +vt 0.998652 0.842242 +vt 0.999150 0.842275 +vt 0.999064 0.842029 +vt 0.757378 0.788445 +vt 0.756875 0.788774 +vt 0.999477 0.841866 +vt 0.999346 0.841748 +vt 0.756572 0.773823 +vt 0.756581 0.774026 +vt 0.757060 0.773895 +vt 0.756975 0.773637 +vt 0.999436 0.856395 +vt 0.757410 0.773517 +vt 0.757274 0.773387 +vt 0.215162 0.297436 +vt 0.215028 0.297449 +vt 0.214831 0.297911 +vt 0.215022 0.297860 +vt 0.214839 0.297474 +vt 0.214560 0.297943 +vt 0.825823 0.864135 +vt 0.826046 0.864146 +vt 0.214734 0.298229 +vt 0.214977 0.298132 +vt 0.215076 0.296424 +vt 0.214993 0.296404 +vt 0.215055 0.296920 +vt 0.215157 0.296921 +vt 0.214878 0.296929 +vt 0.825933 0.878066 +vt 0.825839 0.878326 +vt 0.565378 0.035836 +vt 0.825452 0.877887 +vt 0.825429 0.878104 +vt 0.215087 0.298323 +vt 0.215244 0.298212 +vt 0.579428 0.039307 +vt 0.579253 0.039545 +vt 0.579394 0.039737 +vt 0.579266 0.040124 +vt 0.215244 0.295859 +vt 0.215159 0.295738 +vt 0.214988 0.295984 +vt 0.215062 0.296052 +vt 0.756526 0.789025 +vt 0.211190 0.321629 +vt 0.211208 0.322190 +vt 0.824601 0.878260 +vt 0.824163 0.878362 +vt 0.823758 0.878385 +vt 0.211262 0.322724 +vt 0.211386 0.323139 +vt 0.755907 0.773683 +vt 0.755840 0.773834 +vt 0.756214 0.773859 +vt 0.211713 0.323369 +vt 0.211734 0.323229 +vt 0.825014 0.878065 +vt 0.825048 0.878132 +vt 0.211363 0.321188 +vt 0.211242 0.321132 +vt 0.561080 0.773150 +vt 0.560588 0.773104 +vt 0.560500 0.773300 +vt 0.560976 0.773343 +vt 0.560016 0.773065 +vt 0.559951 0.773255 +vt 0.559931 0.773507 +vt 0.560463 0.773583 +vt 0.560928 0.773641 +vt 0.411195 0.239040 +vt 0.411053 0.238930 +vt 0.410743 0.239867 +vt 0.411478 0.237750 +vt 0.411450 0.237737 +vt 0.411361 0.237746 +vt 0.410860 0.238874 +vt 0.410470 0.239761 +vt 0.456887 0.773238 +vt 0.456856 0.773380 +vt 0.456445 0.773189 +vt 0.456392 0.773243 +vt 0.456353 0.773430 +vt 0.456831 0.773608 +vt 0.825026 0.877003 +vt 0.824760 0.876812 +vt 0.825467 0.875524 +vt 0.825299 0.875396 +vt 0.825135 0.875271 +vt 0.824535 0.876631 +vt 0.576215 0.774344 +vt 0.576043 0.774314 +vt 0.576192 0.773037 +vt 0.576108 0.773003 +vt 0.576083 0.773020 +vt 0.575912 0.774364 +vt 0.504336 0.774183 +vt 0.504617 0.774208 +vt 0.504420 0.774860 +vt 0.504575 0.774879 +vt 0.504771 0.774876 +vt 0.504883 0.774227 +vt 0.211546 0.321261 +vt 0.410585 0.240368 +vt 0.410269 0.240232 +vt 0.211734 0.320975 +vt 0.211566 0.320864 +vt 0.561657 0.773261 +vt 0.561430 0.773205 +vt 0.561321 0.773386 +vt 0.561539 0.773444 +vt 0.215383 0.692250 +vt 0.215393 0.691904 +vt 0.215104 0.691904 +vt 0.215059 0.692239 +vt 0.215410 0.692478 +vt 0.215055 0.692452 +vt 0.825704 0.878805 +vt 0.825335 0.878875 +vt 0.825703 0.878211 +vt 0.825401 0.878263 +vt 0.825117 0.878281 +vt 0.824987 0.878903 +vt 0.561474 0.773722 +vt 0.561267 0.773676 +vt 0.561422 0.774181 +vt 0.561625 0.774218 +vt 0.561081 0.774127 +vt 0.561262 0.774612 +vt 0.561602 0.774705 +vt 0.561800 0.774746 +vt 0.824728 0.878890 +vt 0.824655 0.879141 +vt 0.824905 0.878268 +vt 0.166339 0.154218 +vt 0.166273 0.153970 +vt 0.165935 0.154027 +vt 0.165977 0.154279 +vt 0.166266 0.153333 +vt 0.165949 0.153384 +vt 0.165542 0.153439 +vt 0.165484 0.154086 +vt 0.165485 0.154341 +vt 0.452699 0.772851 +vt 0.452729 0.773038 +vt 0.453045 0.773106 +vt 0.453029 0.772907 +vt 0.452732 0.773350 +vt 0.453022 0.773424 +vt 0.453368 0.773447 +vt 0.453413 0.773118 +vt 0.453424 0.772908 +vt 0.453771 0.773068 +vt 0.453832 0.772851 +vt 0.453695 0.773407 +vt 0.561412 0.773009 +vt 0.561066 0.772965 +vt 0.561637 0.773039 +vt 0.165158 0.154098 +vt 0.165122 0.154353 +vt 0.165261 0.153453 +vt 0.825978 0.878674 +vt 0.825924 0.878105 +vt 0.561594 0.775013 +vt 0.561778 0.775074 +vt 0.561273 0.774881 +vt 0.503968 0.773238 +vt 0.504050 0.773616 +vt 0.503914 0.773030 +vt 0.825665 0.877080 +vt 0.825488 0.877101 +vt 0.825602 0.875630 +vt 0.825582 0.875613 +vt 0.825564 0.875594 +vt 0.825321 0.877103 +vt 0.560601 0.773993 +vt 0.560045 0.773808 +vt 0.560195 0.774050 +vt 0.560771 0.774376 +vt 0.825193 0.877088 +vt 0.825544 0.875579 +vt 0.166295 0.152157 +vt 0.166027 0.152196 +vt 0.166339 0.150663 +vt 0.166140 0.150688 +vt 0.165938 0.150720 +vt 0.165707 0.152242 +vt 0.456844 0.773916 +vt 0.457280 0.774049 +vt 0.456346 0.773744 +vt 0.452956 0.773840 +vt 0.452866 0.774308 +vt 0.453065 0.774358 +vt 0.453241 0.773876 +vt 0.453503 0.773852 +vt 0.453236 0.774355 +vt 0.560581 0.772947 +vt 0.560016 0.772947 +vt 0.165510 0.152258 +vt 0.165850 0.150739 +vt 0.825791 0.877018 +vt 0.825607 0.875624 +vt 0.560808 0.774564 +vt 0.560263 0.774132 +vt 0.504198 0.774177 +vt 0.504389 0.774841 +vt 0.215288 0.689127 +vt 0.215288 0.688715 +vt 0.215145 0.688766 +vt 0.215053 0.689105 +vt 0.504925 0.774844 +vt 0.504991 0.774237 +vt 0.505039 0.774811 +vt 0.504997 0.774265 +vt 0.456902 0.773142 +vt 0.411530 0.239182 +vt 0.411363 0.239130 +vt 0.411535 0.237741 +vt 0.411505 0.237751 +vt 0.939342 0.533129 +vt 0.939595 0.533141 +vt 0.939637 0.531556 +vt 0.939482 0.531550 +vt 0.922260 0.659090 +vt 0.923137 0.657176 +vt 0.924267 0.659398 +vt 0.924867 0.658283 +vt 0.926318 0.658158 +vt 0.926390 0.657355 +vt 0.922944 0.654741 +vt 0.479432 0.254118 +vt 0.479568 0.253946 +vt 0.931384 0.608289 +vt 0.932566 0.608033 +vt 0.201446 0.418155 +vt 0.201460 0.418901 +vt 0.202094 0.419131 +vt 0.202089 0.418290 +vt 0.500550 0.775176 +vt 0.500454 0.774321 +vt 0.499780 0.774552 +vt 0.499865 0.775427 +vt 0.926378 0.611116 +vt 0.926781 0.611980 +vt 0.927528 0.611612 +vt 0.926901 0.610491 +vt 0.925573 0.610919 +vt 0.154410 0.200298 +vt 0.154263 0.200134 +vt 0.919543 0.660922 +vt 0.918328 0.660720 +vt 0.153949 0.199847 +vt 0.153634 0.199559 +vt 0.933126 0.664174 +vt 0.480184 0.253365 +vt 0.480442 0.253165 +vt 0.479876 0.253655 +vt 0.917810 0.611697 +vt 0.153383 0.199357 +vt 0.927699 0.659010 +vt 0.929558 0.658658 +vt 0.925770 0.613746 +vt 0.924323 0.613695 +vt 0.922593 0.614890 +vt 0.925838 0.614605 +vt 0.928368 0.606951 +vt 0.928437 0.609048 +vt 0.929431 0.611078 +vt 0.921920 0.663508 +vt 0.922604 0.661473 +vt 0.924630 0.660827 +vt 0.928309 0.604901 +vt 0.928316 0.605733 +vt 0.921660 0.665532 +vt 0.921687 0.664709 +vt 0.928589 0.685946 +vt 0.928132 0.680967 +vt 0.924956 0.680814 +vt 0.931110 0.682257 +vt 0.928849 0.677532 +vt 0.926885 0.677012 +vt 0.926368 0.678365 +vt 0.924973 0.678482 +vt 0.921175 0.593199 +vt 0.924323 0.591504 +vt 0.918198 0.593676 +vt 0.920606 0.596959 +vt 0.922567 0.596431 +vt 0.923003 0.594815 +vt 0.924368 0.593898 +vt 0.928271 0.603865 +vt 0.921708 0.668552 +vt 0.921659 0.666565 +vt 0.922914 0.651744 +vt 0.923038 0.648493 +vt 0.929459 0.615799 +vt 0.929643 0.618830 +vt 0.929820 0.622039 +vt 0.930365 0.627034 +vt 0.930296 0.628514 +vt 0.927001 0.628890 +vt 0.958579 0.012468 +vt 0.957658 0.012341 +vt 0.958703 0.014840 +vt 0.957923 0.014201 +vt 0.930095 0.630240 +vt 0.932461 0.629688 +vt 0.930109 0.630527 +vt 0.932479 0.629984 +vt 0.924200 0.630381 +vt 0.924105 0.630018 +vt 0.618689 0.010686 +vt 0.618255 0.010502 +vt 0.618095 0.010470 +vt 0.930133 0.624846 +vt 0.923353 0.645568 +vt 0.923787 0.643298 +vt 0.921144 0.642999 +vt 0.621184 0.012157 +vt 0.619651 0.011301 +vt 0.214691 0.097238 +vt 0.214701 0.100006 +vt 0.215380 0.089769 +vt 0.215387 0.087091 +vt 0.448294 0.068464 +vt 0.234388 0.023092 +vt 0.214005 0.089769 +vt 0.214017 0.087091 +vt 0.455403 0.048166 +vt 0.455852 0.056548 +vt 0.455909 0.063145 +vt 0.930626 0.547275 +vt 0.930502 0.550870 +vt 0.930360 0.554260 +vt 0.811992 0.047750 +vt 0.812036 0.054769 +vt 0.812148 0.059858 +vt 0.448243 0.032623 +vt 0.448322 0.027504 +vt 0.448510 0.022612 +vt 0.812503 0.022013 +vt 0.812259 0.028588 +vt 0.812073 0.038091 +vt 0.929097 0.577242 +vt 0.928540 0.581605 +vt 0.927953 0.586419 +vt 0.929480 0.571066 +vt 0.929379 0.573825 +vt 0.929682 0.566049 +vt 0.929558 0.568539 +vt 0.930080 0.560659 +vt 0.929877 0.563464 +vt 0.930231 0.557555 +vt 0.812261 0.064290 +vt 0.930695 0.543425 +vt 0.933151 0.543668 +vt 0.241489 0.043093 +vt 0.241949 0.034905 +vt 0.242007 0.028387 +vt 0.931037 0.720991 +vt 0.931130 0.724550 +vt 0.930914 0.717753 +vt 0.372827 0.022481 +vt 0.372833 0.029178 +vt 0.372846 0.017556 +vt 0.234322 0.058092 +vt 0.234423 0.063068 +vt 0.234655 0.067979 +vt 0.372958 0.047416 +vt 0.373031 0.053694 +vt 0.372882 0.038368 +vt 0.929145 0.690936 +vt 0.929657 0.695502 +vt 0.929900 0.699066 +vt 0.929975 0.701924 +vt 0.930042 0.704512 +vt 0.930169 0.706951 +vt 0.930379 0.709322 +vt 0.930605 0.711836 +vt 0.930778 0.714673 +vt 0.372863 0.013176 +vt 0.931169 0.728508 +vt 0.287480 0.249093 +vt 0.287550 0.250142 +vt 0.288182 0.250373 +vt 0.288094 0.249296 +vt 0.201448 0.417476 +vt 0.202094 0.417520 +vt 0.924830 0.611602 +vt 0.924567 0.612677 +vt 0.570474 0.774861 +vt 0.570443 0.775608 +vt 0.571045 0.775593 +vt 0.571051 0.774759 +vt 0.287596 0.248263 +vt 0.288182 0.248474 +vt 0.924966 0.613503 +vt 0.571436 0.776149 +vt 0.571402 0.774663 +vt 0.928998 0.613321 +vt 0.927147 0.612926 +vt 0.500571 0.773294 +vt 0.499937 0.773524 +vt 0.570512 0.774200 +vt 0.571104 0.774001 +vt 0.571436 0.773268 +vt 0.926514 0.613019 +vt 0.923089 0.597770 +vt 0.921354 0.600211 +vt 0.926443 0.675393 +vt 0.928290 0.673863 +vt 0.925134 0.672298 +vt 0.917023 0.593954 +vt 0.138624 0.209080 +vt 0.138399 0.208908 +vt 0.465463 0.241690 +vt 0.465769 0.241397 +vt 0.465158 0.241982 +vt 0.932282 0.682737 +vt 0.466022 0.241238 +vt 0.138936 0.209369 +vt 0.139249 0.209659 +vt 0.139406 0.209842 +vt 0.918815 0.678698 +vt 0.917620 0.678491 +vt 0.921800 0.679138 +vt 0.923603 0.677577 +vt 0.921211 0.675397 +vt 0.465035 0.242184 +vt 0.930474 0.590038 +vt 0.931662 0.589614 +vt 0.927497 0.591328 +vt 0.925763 0.594005 +vt 0.461503 0.773601 +vt 0.461520 0.774251 +vt 0.461904 0.774358 +vt 0.461890 0.773618 +vt 0.206103 0.419092 +vt 0.205711 0.419026 +vt 0.924234 0.677140 +vt 0.924972 0.677685 +vt 0.205239 0.418438 +vt 0.205274 0.419042 +vt 0.205654 0.419035 +vt 0.205612 0.418337 +vt 0.461510 0.772933 +vt 0.461904 0.772859 +vt 0.925727 0.677559 +vt 0.926068 0.676865 +vt 0.921942 0.672151 +vt 0.208548 0.417898 +vt 0.208156 0.417817 +vt 0.205283 0.417669 +vt 0.205654 0.417462 +vt 0.925767 0.675991 +vt 0.163566 0.164221 +vt 0.054874 0.254464 +vt 0.055107 0.254284 +vt 0.271367 0.182821 +vt 0.271004 0.182600 +vt 0.270641 0.182379 +vt 0.911519 0.776845 +vt 0.910301 0.776900 +vt 0.271611 0.182991 +vt 0.055475 0.254067 +vt 0.055842 0.253849 +vt 0.925417 0.777672 +vt 0.925240 0.777537 +vt 0.056060 0.253761 +vt 0.924034 0.777383 +vt 0.922047 0.772281 +vt 0.922235 0.774714 +vt 0.922717 0.769266 +vt 0.918942 0.771413 +vt 0.918678 0.772924 +vt 0.919998 0.773462 +vt 0.920250 0.774625 +vt 0.270438 0.182276 +vt 0.267989 0.184223 +vt 0.148598 0.164677 +vt 0.149823 0.164629 +vt 0.153902 0.169756 +vt 0.152762 0.167301 +vt 0.154017 0.172747 +vt 0.157221 0.170029 +vt 0.156961 0.168673 +vt 0.155470 0.168365 +vt 0.154751 0.167240 +vt 0.158286 0.168156 +vt 0.160335 0.169209 +vt 0.917187 0.773219 +vt 0.915627 0.771658 +vt 0.914473 0.774152 +vt 0.156136 0.153315 +vt 0.154438 0.154612 +vt 0.914524 0.789074 +vt 0.911378 0.788760 +vt 0.914671 0.787594 +vt 0.913341 0.787297 +vt 0.151014 0.158090 +vt 0.151883 0.161516 +vt 0.152243 0.156709 +vt 0.919067 0.783107 +vt 0.918905 0.785597 +vt 0.920428 0.780003 +vt 0.918446 0.801504 +vt 0.917936 0.797775 +vt 0.149540 0.138492 +vt 0.150536 0.134660 +vt 0.148989 0.142334 +vt 0.148848 0.146024 +vt 0.917829 0.794467 +vt 0.917879 0.791402 +vt 0.921042 0.777037 +vt 0.919527 0.775718 +vt 0.917707 0.777440 +vt 0.152919 0.164734 +vt 0.155010 0.166057 +vt 0.996855 0.415631 +vt 0.998466 0.415406 +vt 0.995964 0.414122 +vt 0.995857 0.416025 +vt 0.998497 0.418952 +vt 0.560069 0.008133 +vt 0.562396 0.015351 +vt 0.561721 0.013420 +vt 0.562537 0.014941 +vt 0.562089 0.013298 +vt 0.988111 0.481530 +vt 0.988534 0.481595 +vt 0.561322 0.015331 +vt 0.560681 0.013414 +vt 0.154153 0.175427 +vt 0.154468 0.177651 +vt 0.922816 0.766210 +vt 0.922747 0.763592 +vt 0.989588 0.481549 +vt 0.991235 0.481378 +vt 0.661916 0.096686 +vt 0.661906 0.099455 +vt 0.662602 0.109600 +vt 0.662595 0.106923 +vt 0.219144 0.023065 +vt 0.268042 0.068047 +vt 0.661231 0.109600 +vt 0.661220 0.106923 +vt 0.226251 0.043314 +vt 0.226701 0.034980 +vt 0.226757 0.028387 +vt 0.964587 0.895890 +vt 0.964436 0.892611 +vt 0.153179 0.104340 +vt 0.153117 0.101179 +vt 0.967955 0.896004 +vt 0.964300 0.879067 +vt 0.964342 0.872161 +vt 0.964305 0.884140 +vt 0.219132 0.058346 +vt 0.219260 0.063057 +vt 0.219517 0.067696 +vt 0.964576 0.853330 +vt 0.964723 0.846671 +vt 0.964921 0.842025 +vt 0.964443 0.862705 +vt 0.151892 0.131006 +vt 0.153061 0.127649 +vt 0.153556 0.124661 +vt 0.153623 0.121963 +vt 0.153608 0.119434 +vt 0.153546 0.116942 +vt 0.153416 0.114328 +vt 0.153287 0.111343 +vt 0.153221 0.107863 +vt 0.964346 0.888635 +vt 0.275141 0.048084 +vt 0.275603 0.056233 +vt 0.275661 0.062752 +vt 0.912192 0.843469 +vt 0.914664 0.843487 +vt 0.914725 0.840327 +vt 0.914803 0.837309 +vt 0.967943 0.278503 +vt 0.967914 0.271920 +vt 0.967871 0.267012 +vt 0.267955 0.033578 +vt 0.268041 0.029005 +vt 0.268264 0.024337 +vt 0.967787 0.302775 +vt 0.967853 0.296412 +vt 0.967917 0.287491 +vt 0.914714 0.814692 +vt 0.913579 0.810998 +vt 0.915325 0.820690 +vt 0.915223 0.817885 +vt 0.915279 0.825720 +vt 0.915333 0.823278 +vt 0.914988 0.830807 +vt 0.915142 0.828120 +vt 0.914882 0.834009 +vt 0.967858 0.262570 +vt 0.967888 0.258649 +vt 0.206922 0.418443 +vt 0.206987 0.417802 +vt 0.206566 0.417824 +vt 0.206498 0.418523 +vt 0.567055 0.774404 +vt 0.566689 0.774576 +vt 0.566147 0.773732 +vt 0.566286 0.775245 +vt 0.919447 0.774706 +vt 0.918972 0.775399 +vt 0.412367 0.239619 +vt 0.412471 0.240252 +vt 0.412792 0.240451 +vt 0.412683 0.239726 +vt 0.206984 0.419158 +vt 0.206566 0.419302 +vt 0.919267 0.773967 +vt 0.918572 0.773596 +vt 0.914610 0.776745 +vt 0.210801 0.419129 +vt 0.211183 0.419302 +vt 0.412470 0.238880 +vt 0.412792 0.238890 +vt 0.917747 0.773852 +vt 0.209911 0.418377 +vt 0.209971 0.419016 +vt 0.210302 0.419301 +vt 0.210238 0.418589 +vt 0.591902 0.772970 +vt 0.592246 0.772978 +vt 0.914356 0.785551 +vt 0.913850 0.786268 +vt 0.593134 0.774215 +vt 0.593141 0.773601 +vt 0.592792 0.773558 +vt 0.592789 0.774263 +vt 0.209972 0.417776 +vt 0.210302 0.417921 +vt 0.914044 0.786933 +vt 0.914739 0.787167 +vt 0.917805 0.788240 +vt 0.916097 0.787051 +vt 0.207789 0.417755 +vt 0.207432 0.417917 +vt 0.593135 0.774890 +vt 0.592792 0.775037 +vt 0.915491 0.786786 +vt 0.156029 0.168036 +vt 0.155558 0.167343 +vt 0.411707 0.238047 +vt 0.411560 0.239560 +vt 0.411998 0.239538 +vt 0.412107 0.238703 +vt 0.210319 0.418422 +vt 0.210384 0.419113 +vt 0.411702 0.240930 +vt 0.412107 0.240264 +vt 0.157736 0.167211 +vt 0.157552 0.167939 +vt 0.207366 0.419114 +vt 0.207298 0.418334 +vt 0.157265 0.166523 +vt 0.156441 0.166257 +vt 0.567378 0.774405 +vt 0.567272 0.773577 +vt 0.207366 0.417635 +vt 0.155741 0.166610 +vt 0.210384 0.417633 +vt 0.567378 0.772838 +vt 0.153817 0.155161 +vt 0.154242 0.155896 +vt 0.153064 0.154773 +vt 0.593493 0.774917 +vt 0.593490 0.774143 +vt 0.208076 0.418217 +vt 0.208126 0.417479 +vt 0.152368 0.154999 +vt 0.152173 0.155664 +vt 0.209605 0.417489 +vt 0.209541 0.418156 +vt 0.593493 0.773438 +vt 0.152679 0.156386 +vt 0.153509 0.156757 +vt 0.591550 0.772839 +vt 0.591544 0.773703 +vt 0.209605 0.418868 +vt 0.154127 0.156543 +vt 0.208126 0.418863 +vt 0.591550 0.774324 +vt 0.925220 0.596553 +vt 0.924484 0.597105 +vt 0.925517 0.595674 +vt 0.204879 0.417727 +vt 0.204837 0.418603 +vt 0.208926 0.418508 +vt 0.208941 0.417785 +vt 0.925173 0.594981 +vt 0.924418 0.594861 +vt 0.461119 0.772832 +vt 0.461105 0.773591 +vt 0.204879 0.419300 +vt 0.923683 0.595414 +vt 0.923385 0.596291 +vt 0.206482 0.419300 +vt 0.206441 0.418417 +vt 0.461119 0.774331 +vt 0.923729 0.596983 +vt 0.208941 0.419272 +vt 0.206482 0.417730 +vt 0.927022 0.659189 +vt 0.927292 0.660280 +vt 0.926272 0.658520 +vt 0.569883 0.774217 +vt 0.569859 0.774965 +vt 0.501086 0.774163 +vt 0.501193 0.773076 +vt 0.925468 0.658731 +vt 0.925070 0.659620 +vt 0.286943 0.247983 +vt 0.286802 0.248863 +vt 0.569823 0.775809 +vt 0.925337 0.660718 +vt 0.926084 0.661392 +vt 0.200814 0.417219 +vt 0.200805 0.417988 +vt 0.286868 0.249967 +vt 0.200423 0.417786 +vt 0.200392 0.419298 +vt 0.200814 0.418830 +vt 0.926890 0.661178 +vt 0.501193 0.775066 +vt 0.578554 0.053518 +vt 0.578207 0.053483 +vt 0.969932 0.441998 +vt 0.970215 0.442023 +vt 0.967699 0.441969 +vt 0.424834 0.017579 +vt 0.424407 0.017574 +vt 0.425257 0.017580 +vt 0.955150 0.441874 +vt 0.957417 0.441883 +vt 0.954791 0.441894 +vt 0.563413 0.053871 +vt 0.563127 0.053913 +vt 0.962563 0.441922 +vt 0.990553 0.274120 +vt 0.990973 0.274139 +vt 0.990134 0.274100 +vn -0.0161 0.2820 0.9593 +vn -0.0027 0.6860 0.7276 +vn -0.0457 0.3244 0.9448 +vn -0.0569 -0.8184 -0.5718 +vn -0.0517 -0.7273 -0.6844 +vn -0.0605 -0.7238 -0.6873 +vn -0.0670 -0.8229 -0.5642 +vn -0.0344 -0.6531 -0.7565 +vn -0.0430 -0.6443 -0.7636 +vn -0.0967 -0.6353 -0.7662 +vn -0.1160 -0.7175 -0.6868 +vn -0.1251 -0.8217 -0.5560 +vn -0.0101 -0.5668 -0.8238 +vn -0.0147 -0.4954 -0.8685 +vn -0.0228 -0.4948 -0.8687 +vn -0.0188 -0.5641 -0.8255 +vn -0.0357 -0.2433 -0.9693 +vn -0.0440 -0.2383 -0.9702 +vn -0.0953 -0.2288 -0.9688 +vn -0.0745 -0.4892 -0.8690 +vn -0.0726 -0.5583 -0.8264 +vn -0.0591 0.0624 -0.9963 +vn -0.0675 0.0690 -0.9953 +vn -0.0622 0.1475 -0.9871 +vn -0.0711 0.1532 -0.9856 +vn -0.1228 0.1605 -0.9794 +vn -0.1183 0.0793 -0.9898 +vn -0.0501 0.1039 -0.9933 +vn -0.0599 0.1114 -0.9920 +vn -0.0413 0.0895 -0.9951 +vn -0.0513 0.0973 -0.9939 +vn -0.1038 0.1036 -0.9892 +vn -0.1127 0.1182 -0.9866 +vn -0.0179 0.0275 -0.9995 +vn -0.0282 0.0352 -0.9990 +vn 0.0281 -0.1138 -0.9931 +vn 0.0180 -0.1064 -0.9942 +vn -0.0346 -0.0989 -0.9945 +vn -0.0801 0.0420 -0.9959 +vn 0.0608 -0.1911 -0.9797 +vn 0.0504 -0.1806 -0.9823 +vn 0.0665 -0.1351 -0.9886 +vn 0.0552 -0.1078 -0.9926 +vn -0.0073 -0.0874 -0.9961 +vn -0.0059 -0.1705 -0.9853 +vn 0.0168 -0.9175 0.3974 +vn 0.0043 -0.9903 0.1387 +vn -0.0062 -0.9880 0.1544 +vn 0.0068 -0.9143 0.4049 +vn -0.0254 -0.9955 -0.0915 +vn -0.0362 -0.9967 -0.0720 +vn -0.0932 -0.9940 -0.0576 +vn -0.0624 -0.9844 0.1647 +vn -0.0504 -0.9113 0.4087 +vn 0.0071 -0.6087 0.7933 +vn 0.0076 -0.7550 0.6557 +vn -0.0017 -0.7524 0.6587 +vn -0.0022 -0.6012 0.7991 +vn -0.0580 -0.7495 0.6594 +vn -0.0564 -0.5940 0.8025 +vn 0.0075 -0.2061 0.9785 +vn 0.0147 -0.4533 0.8912 +vn 0.0055 -0.4436 0.8962 +vn -0.0012 -0.2019 0.9794 +vn -0.0483 -0.4331 0.9000 +vn -0.0546 -0.1935 0.9796 +vn -0.0478 -0.9318 -0.3598 +vn -0.0587 -0.9378 -0.3422 +vn -0.1176 -0.9375 -0.3275 +vn -0.0178 -0.5946 -0.8038 +vn -0.0266 -0.5868 -0.8093 +vn -0.0810 -0.5781 -0.8119 +vn -0.0060 0.0298 0.9995 +vn -0.0063 0.0112 0.9999 +vn 0.0015 0.0117 0.9999 +vn 0.0023 0.0296 0.9996 +vn -0.0063 -0.0396 0.9992 +vn 0.0106 -0.0440 0.9990 +vn 0.0557 -0.0335 0.9979 +vn 0.0593 0.0062 0.9982 +vn 0.0541 0.0274 0.9982 +vn -0.0037 -0.0183 0.9998 +vn 0.0046 -0.0190 0.9998 +vn 0.0161 -0.2101 0.9776 +vn 0.0558 -0.0212 0.9982 +vn 0.0684 -0.2138 0.9745 +vn 0.0570 0.8200 0.5695 +vn 0.0483 0.8252 0.5627 +vn 0.0425 0.7255 0.6869 +vn 0.0516 0.7281 0.6836 +vn -0.0088 0.8298 0.5580 +vn -0.0132 0.7246 0.6890 +vn -0.0289 0.6427 0.7656 +vn 0.0254 0.6471 0.7620 +vn 0.0342 0.6548 0.7551 +vn 0.0091 0.5640 0.8257 +vn 0.0005 0.5618 0.8273 +vn 0.0057 0.4858 0.8741 +vn 0.0138 0.4853 0.8742 +vn -0.0535 0.5618 0.8255 +vn -0.0462 0.4891 0.8710 +vn -0.0219 0.2408 0.9703 +vn 0.0277 0.2386 0.9707 +vn 0.0352 0.2415 0.9698 +vn 0.0516 -0.0567 0.9971 +vn 0.0589 -0.0509 0.9970 +vn 0.0017 -0.0552 0.9985 +vn 0.0034 -0.1448 0.9895 +vn 0.0544 -0.1448 0.9880 +vn 0.0618 -0.1389 0.9884 +vn 0.0431 -0.1099 0.9930 +vn 0.0499 -0.1023 0.9935 +vn -0.0081 -0.1124 0.9936 +vn -0.0153 -0.1031 0.9946 +vn 0.0353 -0.0999 0.9944 +vn 0.0416 -0.0914 0.9949 +vn 0.0120 -0.0373 0.9992 +vn 0.0186 -0.0299 0.9994 +vn -0.0377 -0.0405 0.9985 +vn -0.0845 0.1058 0.9908 +vn -0.0347 0.1079 0.9936 +vn -0.0281 0.1146 0.9930 +vn -0.0672 0.1826 0.9809 +vn -0.0610 0.1927 0.9794 +vn -0.1144 0.1775 0.9774 +vn -0.1093 0.0892 0.9900 +vn -0.0694 0.1049 0.9921 +vn -0.0655 0.1317 0.9891 +vn -0.0177 0.9216 -0.3878 +vn -0.0262 0.9182 -0.3953 +vn -0.0127 0.9889 -0.1478 +vn -0.0050 0.9912 -0.1325 +vn -0.0818 0.9125 -0.4008 +vn -0.0665 0.9849 -0.1597 +vn -0.0370 0.9974 0.0611 +vn 0.0175 0.9970 0.0750 +vn 0.0251 0.9953 0.0937 +vn -0.0077 0.6144 -0.7890 +vn -0.0157 0.6071 -0.7945 +vn -0.0169 0.7589 -0.6510 +vn -0.0082 0.7616 -0.6480 +vn -0.0691 0.6008 -0.7964 +vn -0.0725 0.7547 -0.6521 +vn -0.0077 0.2189 -0.9757 +vn -0.0159 0.2161 -0.9762 +vn -0.0234 0.4534 -0.8910 +vn -0.0157 0.4621 -0.8867 +vn -0.0688 0.2181 -0.9735 +vn -0.0759 0.4482 -0.8907 +vn 0.0398 0.9389 0.3418 +vn 0.0478 0.9324 0.3584 +vn -0.0165 0.9438 0.3300 +vn 0.0086 0.5907 0.8069 +vn 0.0173 0.5977 0.8016 +vn -0.0457 0.5867 0.8085 +vn 0.0068 -0.0264 -0.9996 +vn 0.0149 -0.0267 -0.9995 +vn 0.0150 -0.0211 -0.9997 +vn 0.0063 -0.0209 -0.9998 +vn 0.0663 -0.0285 -0.9974 +vn 0.0704 -0.0275 -0.9971 +vn 0.0667 -0.0425 -0.9969 +vn 0.0239 -0.0499 -0.9985 +vn 0.0065 -0.0455 -0.9989 +vn 0.0002 0.2220 -0.9750 +vn 0.0127 0.0274 -0.9995 +vn 0.0045 0.0275 -0.9996 +vn 0.0516 0.2232 -0.9734 +vn 0.0630 0.0257 -0.9977 +vn -0.5638 -0.4573 -0.6877 +vn -0.5809 -0.5062 -0.6374 +vn -0.5561 -0.4385 -0.7060 +vn -0.5638 -0.4573 -0.6878 +vn -0.9700 -0.0831 -0.2283 +vn -0.9715 -0.0979 -0.2158 +vn -0.9765 -0.1177 -0.1804 +vn 0.0251 -0.6687 -0.7431 +vn 0.0105 -0.7333 -0.6798 +vn 0.5140 -0.6300 -0.5821 +vn 0.5217 -0.5759 -0.6295 +vn 0.0096 -0.8104 -0.5858 +vn 0.5199 -0.6897 -0.5040 +vn 0.5141 -0.6300 -0.5821 +vn 0.5198 -0.6898 -0.5040 +vn 0.9579 -0.2321 -0.1693 +vn 0.9556 -0.2187 -0.1973 +vn 0.5215 -0.5759 -0.6295 +vn 0.9573 -0.2018 -0.2068 +vn 0.0420 -0.9913 -0.1251 +vn 0.0705 -0.9913 0.1111 +vn 0.5674 -0.8187 0.0879 +vn 0.5489 -0.8287 -0.1097 +vn 0.0837 -0.9198 0.3834 +vn 0.5958 -0.7420 0.3073 +vn 0.5675 -0.8187 0.0879 +vn 0.9787 -0.1890 0.0803 +vn 0.9717 -0.2345 0.0267 +vn 0.9675 -0.2505 -0.0353 +vn -0.5614 -0.6248 0.5426 +vn -0.5424 -0.4903 0.6822 +vn -0.5601 -0.7602 0.3292 +vn -0.5615 -0.6248 0.5426 +vn -0.9680 -0.2397 0.0742 +vn -0.9679 -0.2039 0.1472 +vn -0.9628 -0.1534 0.2226 +vn -0.0232 -0.0436 0.9988 +vn -0.1610 -0.4747 0.8653 +vn -0.0031 -0.4563 0.8898 +vn -0.0692 -0.0320 0.9971 +vn -0.4749 -0.3137 0.8222 +vn -0.1610 -0.4746 0.8653 +vn -0.7575 -0.5845 0.2908 +vn -0.2720 -0.9042 0.3294 +vn 0.0031 -0.9371 0.3490 +vn 0.0076 -0.9371 -0.3491 +vn -0.2678 -0.9041 -0.3329 +vn -0.1500 -0.4746 -0.8673 +vn 0.0082 -0.4561 -0.8899 +vn -0.7533 -0.5854 -0.2999 +vn -0.4632 -0.3172 -0.8276 +vn -0.1500 -0.4746 -0.8674 +vn -0.0550 -0.0409 -0.9976 +vn -0.0111 -0.0493 -0.9987 +vn 0.0082 -0.4562 -0.8899 +vn -0.6019 -0.5730 -0.5562 +vn -0.6152 -0.6548 -0.4390 +vn -0.6020 -0.5730 -0.5562 +vn -0.9806 -0.1370 -0.1402 +vn -0.9820 -0.1570 -0.1054 +vn -0.0731 0.0093 0.9973 +vn -0.5694 -0.0449 0.8208 +vn -0.0679 0.0347 0.9971 +vn -0.5449 0.0672 0.8358 +vn -0.5693 -0.0448 0.8209 +vn -0.9594 0.0832 0.2695 +vn -0.9608 -0.1001 0.2587 +vn 0.0735 -0.7567 0.6496 +vn 0.5890 -0.6123 0.5274 +vn 0.0735 -0.7566 0.6497 +vn 0.0719 -0.6200 0.7813 +vn 0.5736 -0.5129 0.6387 +vn 0.9756 -0.1412 0.1684 +vn 0.9789 -0.1556 0.1326 +vn 0.5508 -0.0729 0.8314 +vn 0.5327 0.0054 0.8463 +vn 0.4595 -0.3227 0.8275 +vn 0.5508 -0.0730 0.8314 +vn 0.4596 -0.3227 0.8274 +vn 0.7481 -0.5932 0.2974 +vn 0.9519 -0.1472 0.2687 +vn 0.5327 0.0053 0.8463 +vn 0.9627 -0.0263 0.2695 +vn 0.9346 -0.0023 0.3557 +vn 0.9463 -0.0460 0.3200 +vn 0.4848 0.1250 0.8657 +vn 0.4462 0.1334 0.8849 +vn 0.9596 -0.0660 0.2736 +vn 0.5317 0.0442 0.8458 +vn 0.5318 0.0442 0.8457 +vn 0.0295 0.1210 0.9922 +vn -0.0086 0.2050 0.9787 +vn -0.0282 0.1700 0.9850 +vn 0.1462 -0.1759 -0.9735 +vn 0.1307 -0.2146 -0.9679 +vn 0.5817 -0.2287 -0.7806 +vn 0.5994 -0.1828 -0.7793 +vn 0.0928 -0.1312 -0.9870 +vn 0.5489 -0.1482 -0.8226 +vn 0.9592 -0.1208 -0.2557 +vn 0.9675 -0.1529 -0.2016 +vn 0.5995 -0.1828 -0.7793 +vn 0.9783 -0.1026 -0.1798 +vn 0.0210 -0.9203 -0.3906 +vn 0.5397 -0.7722 -0.3354 +vn 0.9645 -0.2413 -0.1077 +vn -0.9554 0.2087 0.2090 +vn -0.9440 0.2203 0.2457 +vn -0.5020 0.4502 0.7384 +vn -0.5275 0.5002 0.6867 +vn -0.9324 0.1859 0.3101 +vn -0.4729 0.2492 0.8451 +vn -0.4729 0.2492 0.8452 +vn -0.5276 0.5002 0.6866 +vn -0.2736 0.5142 0.8128 +vn -0.6726 0.3833 0.6330 +vn -0.6504 0.4549 0.6084 +vn -0.2310 0.6343 0.7378 +vn -0.6727 0.3832 0.6329 +vn -0.9837 0.0409 0.1748 +vn -0.9764 0.0167 0.2155 +vn -0.6503 0.4549 0.6084 +vn -0.9433 -0.0477 0.3284 +vn -0.6218 0.4581 0.6352 +vn -0.1905 0.7031 0.6851 +vn 0.9683 -0.0532 0.2440 +vn 0.5602 -0.0448 0.8272 +vn 0.9712 -0.0369 0.2353 +vn 0.5635 -0.0710 0.8230 +vn 0.5635 -0.0710 0.8231 +vn 0.0976 -0.0761 0.9923 +vn 0.0753 -0.0181 0.9970 +vn 0.0462 0.0106 -0.9989 +vn 0.5178 -0.0091 -0.8555 +vn 0.0220 0.0738 -0.9970 +vn 0.5013 0.0537 -0.8636 +vn 0.9512 0.0063 -0.3084 +vn 0.9546 -0.0369 -0.2956 +vn -0.5781 0.1242 -0.8065 +vn -0.5830 0.1807 -0.7922 +vn -0.5665 0.1016 -0.8178 +vn -0.5780 0.1242 -0.8065 +vn -0.5665 0.1016 -0.8177 +vn -0.9701 0.0534 -0.2366 +vn -0.9728 0.0779 -0.2183 +vn -0.5829 0.1807 -0.7922 +vn -0.9695 0.1332 -0.2059 +vn 0.9745 0.1424 0.1733 +vn 0.9773 0.1532 0.1466 +vn 0.5877 0.5942 0.5491 +vn 0.5727 0.5475 0.6101 +vn 0.9764 0.1754 0.1261 +vn 0.5876 0.6562 0.4734 +vn 0.1205 0.8069 0.5782 +vn 0.1142 0.7299 0.6740 +vn 0.5728 0.5474 0.6101 +vn 0.0946 0.6665 0.7394 +vn 0.9751 -0.0410 0.2180 +vn 0.5742 -0.0825 0.8145 +vn 0.9759 -0.0630 0.2090 +vn 0.5816 -0.1236 0.8040 +vn 0.5741 -0.0825 0.8146 +vn 0.5817 -0.1236 0.8040 +vn 0.1180 -0.1289 0.9846 +vn 0.1066 -0.0882 0.9904 +vn 0.0123 0.0878 -0.9961 +vn 0.4872 0.0653 -0.8708 +vn -0.0021 0.1329 -0.9911 +vn 0.4760 0.0966 -0.8741 +vn 0.4872 0.0652 -0.8709 +vn 0.4759 0.0967 -0.8742 +vn 0.9437 0.0069 -0.3307 +vn 0.9461 0.0079 -0.3239 +vn -0.0013 0.0461 -0.9989 +vn 0.4994 0.0087 -0.8663 +vn 0.0214 -0.2541 -0.9669 +vn 0.5283 -0.2420 -0.8138 +vn 0.9594 -0.1059 -0.2616 +vn 0.9528 -0.0352 -0.3014 +vn -0.5553 -0.8212 0.1314 +vn -0.5808 -0.8128 -0.0453 +vn -0.9734 -0.2274 -0.0291 +vn -0.9672 -0.2534 0.0182 +vn -0.5673 -0.3649 -0.7383 +vn -0.5974 -0.1127 -0.7940 +vn -0.5973 -0.1127 -0.7940 +vn -0.9765 0.0793 -0.2006 +vn -0.9745 -0.0316 -0.2220 +vn 0.9701 -0.0501 0.2374 +vn 0.5631 -0.0492 0.8249 +vn 0.9675 0.0364 0.2504 +vn 0.5463 0.1982 0.8138 +vn 0.5464 0.1981 0.8138 +vn 0.0901 0.2454 0.9652 +vn 0.1136 -0.0423 0.9926 +vn 0.9643 0.2625 0.0340 +vn 0.9591 0.2820 -0.0251 +vn 0.5267 0.8462 -0.0802 +vn 0.5472 0.8289 0.1159 +vn 0.9547 0.2782 -0.1061 +vn 0.5159 0.7983 -0.3107 +vn 0.5267 0.8463 -0.0802 +vn 0.5160 0.7983 -0.3107 +vn 0.0460 0.9263 -0.3739 +vn 0.0560 0.9929 -0.1052 +vn 0.5471 0.8290 0.1159 +vn 0.0861 0.9882 0.1268 +vn 0.0484 -0.5714 -0.8192 +vn 0.0413 -0.6090 -0.7921 +vn 0.5295 -0.5259 -0.6656 +vn 0.5289 -0.4943 -0.6899 +vn 0.9592 -0.1860 -0.2128 +vn 0.9586 -0.1779 -0.2221 +vn -0.5411 -0.3277 0.7745 +vn -0.5442 -0.0990 0.8331 +vn -0.5412 -0.3277 0.7744 +vn -0.9623 -0.0619 0.2650 +vn -0.9583 0.0515 0.2810 +vn -0.0652 -0.0109 0.9978 +vn -0.5392 0.0542 0.8404 +vn -0.5393 0.0542 0.8404 +vn -0.9537 0.1135 0.2785 +vn 0.0419 -0.4958 -0.8675 +vn 0.5277 -0.4335 -0.7305 +vn 0.5276 -0.4334 -0.7306 +vn 0.9580 -0.1603 -0.2378 +vn 0.9690 0.1044 0.2238 +vn 0.5445 0.4001 0.7371 +vn 0.9703 0.1228 0.2083 +vn 0.5508 0.4680 0.6911 +vn 0.5446 0.4001 0.7371 +vn 0.0673 0.5670 0.8210 +vn 0.0698 0.4842 0.8722 +vn -0.9658 0.2234 -0.1319 +vn -0.9624 0.2627 -0.0691 +vn -0.5359 0.8308 -0.1503 +vn -0.5477 0.7591 -0.3519 +vn -0.9555 0.2949 -0.0021 +vn -0.5127 0.8576 0.0414 +vn -0.5477 0.7590 -0.3519 +vn 0.0785 -0.4691 0.8797 +vn 0.5866 -0.3932 0.7081 +vn 0.5746 -0.1932 0.7953 +vn 0.9756 -0.0789 0.2047 +vn 0.9777 -0.1172 0.1743 +vn -0.9372 0.1048 0.3326 +vn -0.4757 0.0072 0.8796 +vn -0.9455 0.0518 0.3214 +vn -0.4930 -0.0748 0.8668 +vn -0.9482 0.0172 0.3171 +vn -0.4963 -0.0703 0.8653 +vn -0.9520 0.0003 0.3061 +vn -0.4978 -0.0740 0.8641 +vn -0.4962 -0.0703 0.8654 +vn -0.4977 -0.0740 0.8642 +vn -0.9627 0.0303 0.2689 +vn -0.5255 -0.0111 0.8507 +vn -0.9708 0.0854 0.2244 +vn -0.5644 0.1232 0.8163 +vn -0.5256 -0.0111 0.8507 +vn -0.9510 0.2948 0.0929 +vn -0.4998 0.8199 0.2792 +vn -0.9503 0.2591 0.1727 +vn -0.4980 0.7220 0.4803 +vn -0.4981 0.7220 0.4803 +vn -0.5942 0.1426 -0.7916 +vn -0.9694 0.1508 -0.1935 +vn -0.5339 0.0480 -0.8442 +vn -0.5000 -0.0654 -0.8636 +vn -0.5339 0.0479 -0.8442 +vn -0.5001 -0.0654 -0.8635 +vn -0.9500 0.0206 -0.3114 +vn -0.9600 0.0441 -0.2763 +vn -0.9738 0.1000 0.2041 +vn -0.5785 0.1752 0.7967 +vn -0.9748 0.0456 0.2184 +vn -0.5695 0.0816 0.8179 +vn -0.5784 0.1752 0.7967 +vn -0.5695 0.0816 0.8180 +vn -0.4906 -0.1163 -0.8636 +vn -0.4896 -0.0462 -0.8707 +vn -0.9416 0.0051 -0.3367 +vn -0.9454 0.0041 -0.3259 +vn -0.7533 -0.5853 -0.2999 +vn -0.9582 -0.1082 -0.2650 +vn -0.5595 -0.0703 -0.8259 +vn -0.9626 0.0681 -0.2622 +vn -0.5428 0.0209 -0.8396 +vn -0.5595 -0.0703 -0.8258 +vn -0.5429 0.0210 -0.8395 +vn -0.0551 -0.0223 -0.9982 +vn -0.0591 -0.0242 -0.9980 +vn -0.9704 0.1490 -0.1901 +vn -0.9671 0.1738 -0.1856 +vn -0.5453 0.6261 -0.5574 +vn -0.5494 0.5033 -0.6670 +vn -0.5494 0.5032 -0.6670 +vn 0.9755 -0.0042 -0.2197 +vn 0.9947 0.0976 0.0327 +vn 0.9943 0.1016 0.0318 +vn 0.9745 -0.0296 -0.2224 +vn 0.9310 0.1966 0.3075 +vn 0.9309 0.2241 0.2885 +vn 0.9268 0.1508 0.3440 +vn 0.9897 0.0001 0.1429 +vn 0.9811 -0.1653 -0.1006 +vn 0.9554 0.2271 -0.1886 +vn 0.5248 0.6584 -0.5395 +vn 0.9582 0.1773 -0.2245 +vn 0.5329 0.5334 -0.6569 +vn 0.5248 0.6584 -0.5396 +vn 0.5329 0.5333 -0.6570 +vn 0.0545 0.6262 -0.7778 +vn 0.0560 0.7656 -0.6409 +vn 0.5434 -0.0344 0.8388 +vn 0.5434 -0.0344 0.8387 +vn 0.9680 -0.0372 0.2482 +vn 0.9544 0.1283 -0.2694 +vn 0.5181 0.4091 -0.7512 +vn 0.9527 0.0399 -0.3013 +vn 0.5144 0.1868 -0.8369 +vn 0.5181 0.4091 -0.7511 +vn 0.5144 0.1868 -0.8370 +vn 0.0449 0.4771 -0.8777 +vn 0.9570 -0.0223 -0.2893 +vn 0.5261 0.0091 -0.8504 +vn 0.9615 -0.0403 -0.2717 +vn 0.5372 -0.0406 -0.8425 +vn -0.6114 -0.7493 -0.2542 +vn -0.6114 -0.7493 -0.2543 +vn -0.9802 -0.1853 -0.0697 +vn -0.9608 0.1222 -0.2489 +vn -0.5382 0.0856 -0.8385 +vn -0.9623 0.1495 -0.2273 +vn -0.5372 0.2256 -0.8128 +vn -0.5372 0.2256 -0.8127 +vn -0.0572 0.0336 -0.9978 +vn 0.9535 -0.1542 -0.2591 +vn 0.5581 -0.0985 -0.8239 +vn 0.7510 -0.5937 -0.2889 +vn 0.4682 -0.3259 -0.8214 +vn 0.4681 -0.3259 -0.8214 +vn -0.9672 0.1572 -0.1995 +vn -0.5449 0.3950 -0.7396 +vn -0.5448 0.3950 -0.7397 +vn 0.9704 0.2230 0.0925 +vn 0.5681 0.7554 0.3265 +vn 0.1105 0.9158 0.3862 +vn 0.9714 0.1315 0.1976 +vn 0.5582 0.5018 0.6607 +vn 0.5581 0.5018 0.6608 +vn 0.5728 0.5475 0.6101 +vn 0.0946 0.6665 0.7395 +vn 0.0764 0.6084 0.7900 +vn -0.9506 0.2290 0.2097 +vn -0.5006 0.6306 0.5931 +vn -0.9530 0.2113 0.2170 +vn -0.5092 0.5615 0.6522 +vn -0.5006 0.6305 0.5931 +vn -0.5093 0.5615 0.6522 +vn -0.9995 -0.0317 -0.0011 +vn -0.9994 -0.0296 -0.0188 +vn -0.9996 -0.0091 0.0285 +vn 0.9988 -0.0384 -0.0309 +vn 0.9989 -0.0375 -0.0282 +vn 0.9991 -0.0353 -0.0235 +vn 0.9991 -0.0369 -0.0205 +vn 0.9994 -0.0315 -0.0119 +vn 0.9984 -0.0447 -0.0358 +vn -0.9997 -0.0108 -0.0223 +vn -0.9998 0.0128 -0.0136 +vn -0.9957 0.0928 0.0064 +vn -0.9913 0.1282 0.0292 +vn -0.9977 0.0669 -0.0079 +vn -0.9895 0.1351 0.0519 +vn -0.9934 0.0968 0.0609 +vn 0.9978 -0.0424 -0.0511 +vn 0.9979 -0.0298 -0.0577 +vn 0.9985 -0.0170 -0.0523 +vn 0.9992 -0.0161 -0.0379 +vn -0.9993 0.0374 0.0053 +vn -0.9979 0.0559 -0.0311 +vn -0.9990 0.0286 0.0341 +vn -0.9995 0.0301 0.0067 +vn -0.9990 0.0375 0.0250 +vn -0.9973 0.0501 0.0531 +vn 0.9987 -0.0481 -0.0155 +vn 0.9952 -0.0963 0.0193 +vn -0.9964 0.0545 -0.0642 +vn -0.9962 0.0287 -0.0818 +vn 0.9929 -0.1030 0.0594 +vn 0.9952 -0.0536 0.0816 +vn -0.9943 -0.1064 -0.0046 +vn -0.9969 0.0788 0.0057 +vn -0.8006 -0.5992 -0.0054 +vn 1.0000 0.0075 0.0035 +vn 0.9998 0.0219 -0.0023 +vn 0.9999 -0.0132 -0.0007 +vn 0.2538 -0.3623 -0.8968 +vn 0.6353 -0.2428 -0.7331 +vn 0.6162 -0.3255 -0.7172 +vn 0.2113 -0.4604 -0.8622 +vn 0.6162 -0.3256 -0.7172 +vn 0.6331 -0.5035 -0.5880 +vn 0.1823 -0.6071 -0.7735 +vn 0.9996 0.0242 -0.0138 +vn 0.9996 0.0162 -0.0244 +vn 0.2757 -0.9039 -0.3271 +vn 0.2964 -0.9551 0.0018 +vn 0.0058 -1.0000 0.0000 +vn 0.7510 -0.5938 -0.2889 +vn 0.7930 -0.6091 0.0038 +vn 0.2714 -0.9041 0.3301 +vn 0.9995 -0.0015 -0.0309 +vn 0.9994 -0.0221 -0.0280 +vn 0.9994 -0.0301 -0.0151 +vn 0.9994 -0.0349 -0.0027 +vn -0.9565 0.2038 0.2086 +vn -0.9985 0.0539 -0.0058 +vn -0.9989 0.0449 0.0124 +vn -0.9920 0.1226 0.0284 +vn -0.9936 0.1003 0.0516 +vn 0.9878 -0.1558 0.0030 +vn 0.7930 -0.6092 0.0038 +vn -0.9977 0.0416 0.0526 +vn 0.9994 -0.0298 -0.0147 +vn 0.9994 -0.0323 -0.0139 +vn -0.9988 0.0403 0.0273 +vn -0.5236 0.5162 0.6778 +vn -0.8933 -0.4482 -0.0335 +vn -0.4228 -0.7745 -0.4705 +vn -0.4104 -0.8955 -0.1722 +vn -0.7689 -0.5681 0.2933 +vn -0.4227 -0.7745 -0.4706 +vn 0.0736 -0.7522 -0.6548 +vn 0.0449 -0.8357 -0.5474 +vn -0.4103 -0.8955 -0.1723 +vn 0.0621 -0.8966 -0.4385 +vn -0.1989 -0.9717 0.1275 +vn -0.7690 -0.5680 0.2933 +vn -0.3970 -0.6474 0.6506 +vn -0.5451 0.3351 0.7685 +vn -0.1709 0.7149 0.6781 +vn -0.7929 -0.2020 0.5749 +vn -0.5452 0.3350 0.7685 +vn -0.5451 0.3350 0.7685 +vn -0.4134 -0.3568 0.8377 +vn -0.3182 0.2078 0.9250 +vn -0.1709 0.7149 0.6780 +vn -0.1409 0.6896 0.7103 +vn 0.1279 -0.6777 -0.7242 +vn 0.1321 -0.6388 -0.7579 +vn 0.1159 -0.7710 -0.6262 +vn 0.1104 -0.7869 -0.6071 +vn 0.1831 -0.7723 -0.6083 +vn 0.1616 -0.8761 -0.4542 +vn 0.1265 -0.8850 -0.4480 +vn 0.1104 -0.8846 -0.4531 +vn -0.9946 -0.0993 -0.0308 +vn -0.9860 -0.1647 0.0253 +vn -0.9170 -0.2754 -0.2885 +vn -0.9100 -0.3635 -0.1995 +vn -0.9545 -0.2489 0.1643 +vn -0.3643 -0.5431 -0.7565 +vn -0.3847 -0.6714 -0.6333 +vn -0.3644 -0.5431 -0.7565 +vn 0.1602 -0.5362 -0.8287 +vn 0.1177 -0.6590 -0.7429 +vn -0.3849 -0.6714 -0.6333 +vn 0.1177 -0.6589 -0.7429 +vn 0.2092 -0.4525 -0.8669 +vn 0.2116 -0.4053 -0.8893 +vn 0.1684 -0.5085 -0.8444 +vn 0.1663 -0.5626 -0.8099 +vn 0.1279 -0.6776 -0.7242 +vn 0.3865 0.3602 0.8490 +vn 0.4170 0.4311 0.8002 +vn 0.3866 0.3602 0.8490 +vn -0.1391 0.3627 0.9215 +vn -0.0962 0.4540 0.8858 +vn 0.4171 0.4311 0.8001 +vn -0.0574 0.5755 0.8158 +vn 0.4563 0.4657 0.7582 +vn 0.4562 0.4657 0.7582 +vn -0.2078 0.4412 0.8730 +vn -0.2218 0.4883 0.8440 +vn -0.1790 0.6068 0.7744 +vn -0.1652 0.5516 0.8176 +vn -0.1375 0.6911 0.7095 +vn -0.1253 0.6521 0.7477 +vn 0.1858 -0.9642 0.1892 +vn 0.1095 -0.9796 0.1688 +vn 0.4065 -0.9067 0.1124 +vn 0.5154 -0.5713 0.6387 +vn 0.1743 -0.6284 0.7581 +vn 0.0610 -0.6426 0.7638 +vn 0.0266 -0.3661 0.9302 +vn 0.1386 -0.3649 0.9207 +vn 0.0339 0.2212 0.9746 +vn -0.0435 0.2410 0.9695 +vn 0.4689 -0.2863 0.8356 +vn 0.2433 0.2499 0.9372 +vn -0.0447 0.6867 0.7256 +vn -0.0759 0.6925 0.7174 +vn -0.0936 0.7018 0.7062 +vn -0.0811 -0.3806 0.9212 +vn -0.0702 -0.5127 0.8557 +vn 0.0436 -0.5049 0.8621 +vn -0.4017 -0.5030 0.7653 +vn -0.3969 -0.6477 0.6504 +vn -0.0529 -0.6451 0.7622 +vn 0.0610 -0.6425 0.7638 +vn 0.8638 -0.2236 0.4516 +vn 0.8834 -0.3939 0.2538 +vn 0.8172 -0.0568 0.5735 +vn 0.4886 -0.4319 0.7581 +vn 0.5154 -0.5713 0.6388 +vn -0.1376 0.6911 0.7095 +vn -0.1142 0.7363 0.6669 +vn -0.1042 0.7222 0.6838 +vn -0.1093 0.6955 0.7102 +vn -0.0936 0.7019 0.7061 +vn 0.6217 -0.7453 -0.2409 +vn 0.6218 -0.7452 -0.2409 +vn 0.4064 -0.9068 0.1123 +vn 0.6217 -0.7452 -0.2409 +vn 0.4356 0.3766 0.8175 +vn -0.0343 0.6726 0.7392 +vn 0.4357 0.3766 0.8175 +vn -0.7949 -0.3899 0.4648 +vn -0.4017 -0.5032 0.7652 +vn -0.7950 -0.3899 0.4647 +vn -0.2390 0.2019 0.9498 +vn -0.2552 0.2269 0.9399 +vn -0.2480 0.3622 0.8985 +vn -0.2344 0.3310 0.9141 +vn -0.3134 0.2445 0.9176 +vn -0.3013 0.3805 0.8743 +vn 0.9352 0.1124 0.3358 +vn 0.3901 0.1897 0.9010 +vn 0.3810 0.2819 0.8806 +vn 0.9340 0.1416 0.3280 +vn 0.3900 0.1897 0.9011 +vn -0.1570 0.1766 0.9717 +vn -0.1638 0.2850 0.9444 +vn 0.3809 0.2820 0.8806 +vn 0.2515 -0.2746 -0.9281 +vn 0.2693 -0.2320 -0.9347 +vn 0.2453 -0.3210 -0.9148 +vn 0.2381 -0.3568 -0.9033 +vn 0.3096 -0.1900 -0.9317 +vn 0.2888 -0.2859 -0.9137 +vn -0.9243 -0.1471 -0.3521 +vn -0.3582 -0.2898 -0.8875 +vn -0.3592 -0.4067 -0.8400 +vn -0.9242 -0.1909 -0.3308 +vn 0.1704 -0.2871 -0.9426 +vn 0.1800 -0.4066 -0.8957 +vn -0.3591 -0.4067 -0.8400 +vn -0.9830 0.0149 0.1832 +vn -0.9970 -0.0580 -0.0508 +vn -0.9971 -0.0577 -0.0497 +vn -0.9842 0.0460 0.1712 +vn 0.6635 -0.1141 -0.7394 +vn 0.6577 -0.1939 -0.7279 +vn 0.9771 0.0095 -0.2126 +vn 0.9789 -0.0154 -0.2035 +vn 0.6576 -0.1939 -0.7279 +vn 0.9970 0.0596 0.0504 +vn 0.9970 0.0614 0.0480 +vn -0.6822 0.1841 0.7076 +vn -0.6819 0.2908 0.6712 +vn -0.6822 0.1840 0.7076 +vn -0.6819 0.2908 0.6711 +vn -0.2695 -0.0240 0.9627 +vn -0.6554 -0.0401 0.7542 +vn -0.7205 0.1500 0.6770 +vn -0.3495 0.2135 0.9123 +vn -0.9824 -0.0321 0.1839 +vn -0.9894 0.0131 0.1444 +vn -0.7205 0.1501 0.6771 +vn -0.9892 0.0629 0.1325 +vn -0.7295 0.3559 0.5840 +vn -0.7296 0.3559 0.5840 +vn -0.3904 0.4790 0.7862 +vn 0.9801 0.0092 -0.1984 +vn 0.9967 0.0464 0.0670 +vn 0.9965 0.0538 0.0633 +vn 0.9815 -0.0266 -0.1896 +vn 0.9281 0.0876 0.3619 +vn 0.9327 0.1370 0.3336 +vn 0.9253 0.2098 0.3158 +vn 0.9962 0.0648 0.0586 +vn 0.9835 -0.0723 -0.1658 +vn 0.2987 -0.1031 -0.9487 +vn 0.6641 -0.0763 -0.7438 +vn 0.6875 -0.1933 -0.6999 +vn 0.3538 -0.2633 -0.8975 +vn 0.6641 -0.0763 -0.7437 +vn 0.6876 -0.1933 -0.6999 +vn 0.7050 -0.3424 -0.6211 +vn 0.3865 -0.4595 -0.7997 +vn -0.9970 -0.0287 -0.0724 +vn -0.9969 -0.0406 -0.0673 +vn -0.9185 -0.0127 -0.3952 +vn -0.9119 -0.1182 -0.3930 +vn -0.9065 -0.2399 -0.3473 +vn -0.9966 -0.0539 -0.0620 +vn -0.3516 0.0083 -0.9361 +vn -0.3088 -0.2387 -0.9207 +vn 0.1634 0.0220 -0.9863 +vn 0.2373 -0.2239 -0.9453 +vn 0.2840 -0.4961 -0.8205 +vn -0.2793 -0.5045 -0.8170 +vn -0.2792 -0.5045 -0.8170 +vn 0.2364 -0.0423 -0.9707 +vn 0.2509 -0.0774 -0.9649 +vn 0.3091 -0.2576 -0.9155 +vn 0.2988 -0.2449 -0.9224 +vn 0.3441 -0.4716 -0.8119 +vn 0.3373 -0.4779 -0.8111 +vn 0.3563 0.1404 0.9238 +vn 0.3405 0.2933 0.8933 +vn 0.3562 0.1405 0.9238 +vn -0.1912 0.1129 0.9750 +vn -0.2454 0.2783 0.9286 +vn -0.2831 0.4847 0.8276 +vn 0.3014 0.4958 0.8144 +vn 0.3014 0.4959 0.8144 +vn -0.2372 0.0462 0.9704 +vn -0.2311 0.0059 0.9729 +vn -0.3034 0.2282 0.9251 +vn -0.2988 0.2446 0.9225 +vn -0.3460 0.4857 0.8027 +vn -0.3381 0.4847 0.8067 +vn 0.9957 0.0547 0.0754 +vn 0.5916 0.7860 -0.1797 +vn 0.3907 0.4513 -0.8023 +vn 0.6985 0.1069 -0.7076 +vn 0.5916 0.7859 -0.1797 +vn -0.2116 0.9320 -0.2944 +vn -0.0167 0.5524 -0.8334 +vn 0.3908 0.4512 -0.8023 +vn 0.3908 0.4513 -0.8023 +vn -0.0167 0.5525 -0.8334 +vn 0.1228 0.1808 -0.9758 +vn 0.1957 0.1548 -0.9684 +vn 0.6986 0.1069 -0.7075 +vn 0.2607 0.0916 -0.9611 +vn 0.9292 0.0581 0.3650 +vn 0.4119 0.0817 0.9075 +vn 0.3797 0.0892 0.9208 +vn 0.9269 0.0667 0.3693 +vn 0.4121 0.0817 0.9075 +vn -0.0875 0.0556 0.9946 +vn -0.1419 0.0592 0.9881 +vn -0.1535 0.0241 0.9878 +vn -0.1966 0.0299 0.9800 +vn -0.2806 -0.0175 0.9597 +vn -0.2874 0.0806 0.9544 +vn -0.1952 0.1200 0.9734 +vn -0.1967 0.0008 0.9805 +vn -0.2376 0.0816 0.9679 +vn -0.9283 0.0277 -0.3708 +vn -0.4293 0.1155 -0.8958 +vn -0.3872 0.1030 -0.9162 +vn -0.9227 0.0231 -0.3847 +vn 0.0397 0.1248 -0.9914 +vn 0.0987 0.1130 -0.9887 +vn -0.3873 0.1030 -0.9162 +vn -0.9737 -0.0614 0.2192 +vn -0.9966 -0.0166 -0.0803 +vn -0.9968 -0.0214 -0.0765 +vn -0.9762 -0.0576 0.2092 +vn 0.1979 -0.0514 -0.9789 +vn 0.6199 -0.0397 -0.7836 +vn 0.6406 -0.0399 -0.7668 +vn 0.2481 -0.0531 -0.9673 +vn 0.6198 -0.0397 -0.7837 +vn 0.9795 0.0137 -0.2012 +vn 0.9794 0.0178 -0.2013 +vn 0.6407 -0.0399 -0.7668 +vn 0.9966 0.0370 0.0741 +vn 0.9966 0.0424 0.0702 +vn -0.1427 -0.1263 0.9817 +vn -0.5744 -0.1305 0.8081 +vn -0.6050 -0.1204 0.7871 +vn -0.1996 -0.1139 0.9732 +vn -0.6051 -0.1204 0.7870 +vn -0.7081 0.3498 0.6134 +vn -0.3901 0.4875 0.7811 +vn -0.9831 0.0553 0.1745 +vn -0.7081 0.3498 0.6133 +vn -0.9717 -0.0586 0.2287 +vn -0.6848 0.1498 0.7132 +vn -0.6847 0.1498 0.7132 +vn -0.3671 0.2657 0.8914 +vn 0.9939 0.1004 0.0461 +vn 0.9876 -0.0148 -0.1564 +vn 0.9024 0.2683 0.3372 +vn 0.9069 0.2247 0.3565 +vn 0.9882 0.1507 0.0287 +vn 0.9774 0.0892 -0.1917 +vn 0.7244 -0.3051 -0.6182 +vn 0.3871 -0.4331 -0.8140 +vn 0.7244 -0.3050 -0.6182 +vn 0.7034 -0.0831 -0.7059 +vn 0.3555 -0.1774 -0.9177 +vn -0.9945 -0.0932 -0.0484 +vn -0.9213 -0.2467 -0.3006 +vn -0.9250 -0.2327 -0.3004 +vn -0.9884 -0.1488 -0.0293 +vn -0.3082 -0.5331 -0.7879 +vn 0.2762 -0.4981 -0.8219 +vn -0.3081 -0.5331 -0.7880 +vn 0.2177 -0.2570 -0.9416 +vn -0.3522 -0.3422 -0.8711 +vn 0.3405 -0.4450 -0.8283 +vn 0.3330 -0.4552 -0.8258 +vn 0.3021 -0.1795 -0.9362 +vn 0.2879 -0.1887 -0.9389 +vn 0.2729 0.4962 0.8242 +vn -0.2738 0.4767 0.8353 +vn -0.2171 0.2502 0.9435 +vn 0.3136 0.2948 0.9026 +vn -0.3493 0.5037 0.7901 +vn -0.3380 0.5055 0.7938 +vn -0.3284 0.2929 0.8980 +vn -0.3089 0.3076 0.9000 +vn -0.3228 0.0315 0.9459 +vn -0.6610 -0.0261 0.7499 +vn -0.6717 0.0551 0.7388 +vn -0.3140 0.1018 0.9439 +vn -0.9662 -0.1178 0.2292 +vn -0.9772 -0.0530 0.2054 +vn 0.9627 0.1382 -0.2324 +vn 0.9889 0.1460 0.0268 +vn 0.9944 0.0972 0.0405 +vn 0.9706 0.0765 -0.2281 +vn 0.9312 0.1425 0.3356 +vn 0.9349 0.1156 0.3354 +vn 0.3148 0.0243 -0.9488 +vn 0.6547 0.0823 -0.7514 +vn 0.6579 -0.0001 -0.7531 +vn 0.3142 -0.0640 -0.9472 +vn -0.9889 -0.1459 -0.0268 +vn -0.9945 -0.0966 -0.0407 +vn -0.9268 -0.1662 -0.3368 +vn -0.9247 -0.1408 -0.3537 +vn -0.3883 -0.1428 -0.9104 +vn -0.3701 -0.1901 -0.9094 +vn -0.3883 -0.1429 -0.9104 +vn 0.1226 -0.0706 -0.9899 +vn 0.1406 -0.1617 -0.9768 +vn -0.3701 -0.1900 -0.9093 +vn 0.2612 -0.0067 -0.9653 +vn 0.2482 -0.0189 -0.9685 +vn 0.3211 0.0059 -0.9470 +vn 0.2567 0.0056 -0.9665 +vn 0.0314 -0.0299 -0.9991 +vn 0.1179 -0.1788 -0.9768 +vn 0.3169 -0.2753 -0.9076 +vn 0.4090 0.0746 0.9095 +vn 0.4062 0.0993 0.9084 +vn -0.1105 0.0004 0.9939 +vn -0.1262 0.0484 0.9908 +vn -0.2825 0.0859 0.9554 +vn -0.2680 0.1072 0.9575 +vn -0.3381 0.0818 0.9376 +vn -0.2551 0.0229 0.9666 +vn -0.0395 0.0199 0.9990 +vn -0.0760 -0.1143 0.9905 +vn -0.1988 -0.2064 0.9581 +vn -0.0193 -0.8356 -0.5490 +vn -0.0086 -0.8526 -0.5224 +vn 0.0245 -0.7731 -0.6338 +vn 0.0149 -0.7658 -0.6430 +vn 0.0502 -0.8637 -0.5015 +vn 0.0811 -0.7759 -0.6256 +vn 0.0854 -0.7183 -0.6905 +vn 0.0304 -0.7230 -0.6902 +vn 0.0216 -0.7252 -0.6881 +vn 0.0109 -0.5670 -0.8236 +vn 0.0197 -0.5644 -0.8253 +vn 0.0301 -0.4063 -0.9132 +vn 0.0221 -0.4050 -0.9140 +vn 0.0745 -0.5584 -0.8262 +vn 0.0822 -0.4022 -0.9118 +vn 0.1019 -0.1427 -0.9845 +vn 0.0513 -0.1505 -0.9873 +vn 0.0431 -0.1532 -0.9873 +vn 0.0702 0.0978 -0.9927 +vn 0.0620 0.0926 -0.9938 +vn 0.1206 0.1065 -0.9870 +vn 0.1231 0.1632 -0.9789 +vn 0.0713 0.1559 -0.9852 +vn 0.0628 0.1508 -0.9866 +vn 0.0599 0.1114 -0.9920 +vn 0.0503 0.1042 -0.9933 +vn 0.1127 0.1182 -0.9866 +vn 0.1025 0.0934 -0.9903 +vn 0.0501 0.0884 -0.9948 +vn 0.0401 0.0821 -0.9958 +vn 0.0180 -0.0375 -0.9991 +vn 0.0112 -0.0312 -0.9995 +vn 0.0681 -0.0456 -0.9966 +vn 0.0097 -0.3371 -0.9414 +vn -0.0329 -0.3053 -0.9517 +vn -0.0329 -0.2744 -0.9611 +vn -0.0315 -0.4529 -0.8910 +vn -0.0293 -0.4152 -0.9092 +vn 0.0067 -0.4927 -0.8702 +vn 0.0711 -0.3629 -0.9291 +vn 0.0252 -0.3458 -0.9380 +vn 0.0193 -0.3373 -0.9412 +vn -0.1872 -0.8925 0.4104 +vn -0.1781 -0.8930 0.4134 +vn -0.1784 -0.9620 0.2066 +vn -0.1892 -0.9638 0.1879 +vn -0.1233 -0.9005 0.4170 +vn -0.1239 -0.9674 0.2209 +vn -0.0773 -0.9969 0.0147 +vn -0.1331 -0.9910 -0.0108 +vn -0.1448 -0.9884 -0.0449 +vn -0.0927 -0.6566 0.7485 +vn -0.0853 -0.6622 0.7444 +vn -0.1316 -0.7742 0.6191 +vn -0.1390 -0.7680 0.6252 +vn -0.0314 -0.6678 0.7437 +vn -0.0771 -0.7835 0.6165 +vn -0.1316 -0.7743 0.6190 +vn -0.0771 -0.7836 0.6165 +vn -0.0196 -0.2416 0.9702 +vn -0.0111 -0.2419 0.9702 +vn -0.0490 -0.5054 0.8615 +vn -0.0574 -0.5036 0.8620 +vn 0.0430 -0.2366 0.9706 +vn 0.0052 -0.5044 0.8634 +vn -0.0682 -0.9534 -0.2938 +vn -0.0798 -0.9392 -0.3340 +vn -0.0095 -0.9647 -0.2631 +vn 0.0216 -0.7252 -0.6882 +vn 0.0229 -0.6641 -0.7473 +vn 0.0135 -0.6708 -0.7415 +vn 0.0783 -0.6556 -0.7510 +vn 0.0057 0.0107 0.9999 +vn -0.0026 0.0107 0.9999 +vn -0.0017 0.0033 1.0000 +vn 0.0063 0.0029 1.0000 +vn -0.0544 0.0088 0.9985 +vn -0.0592 -0.0024 0.9982 +vn -0.0553 -0.0358 0.9978 +vn -0.0108 -0.0455 0.9989 +vn 0.0063 -0.0411 0.9991 +vn -0.0278 -0.2409 0.9702 +vn -0.0068 -0.0443 0.9990 +vn 0.0020 -0.0447 0.9990 +vn -0.0798 -0.2410 0.9672 +vn -0.0575 -0.0461 0.9973 +vn 0.0193 0.8368 0.5472 +vn -0.0148 0.7660 0.6427 +vn -0.0063 0.7737 0.6335 +vn 0.0273 0.8531 0.5210 +vn -0.0214 0.7245 0.6889 +vn -0.0126 0.7229 0.6908 +vn 0.0422 0.7220 0.6906 +vn 0.0493 0.7787 0.6255 +vn 0.0833 0.8622 0.4997 +vn -0.0099 0.5646 0.8253 +vn -0.0209 0.4032 0.9149 +vn -0.0125 0.4054 0.9141 +vn -0.0012 0.5625 0.8268 +vn -0.0425 0.1599 0.9862 +vn -0.0348 0.1588 0.9867 +vn 0.0151 0.1625 0.9866 +vn 0.0401 0.4100 0.9112 +vn 0.0532 0.5626 0.8250 +vn -0.0614 -0.0785 0.9950 +vn -0.0542 -0.0834 0.9950 +vn -0.0619 -0.1416 0.9880 +vn -0.0549 -0.1479 0.9875 +vn -0.0037 -0.1474 0.9891 +vn -0.0044 -0.0813 0.9967 +vn -0.0499 -0.1023 0.9935 +vn -0.0430 -0.1099 0.9930 +vn -0.0401 -0.0840 0.9957 +vn -0.0334 -0.0910 0.9953 +vn 0.0171 -0.0944 0.9954 +vn 0.0080 -0.1124 0.9936 +vn -0.0117 0.0283 0.9995 +vn -0.0018 0.0339 0.9994 +vn 0.0333 0.2786 0.9598 +vn 0.0493 0.3079 0.9501 +vn 0.1039 0.3181 0.9423 +vn 0.0514 0.0352 0.9981 +vn 0.0303 0.4232 0.9055 +vn 0.0475 0.4575 0.8880 +vn -0.0190 0.3409 0.9399 +vn -0.0096 0.3455 0.9384 +vn 0.0382 0.3373 0.9406 +vn 0.0997 0.4679 0.8781 +vn 0.1890 0.8969 -0.3998 +vn 0.1904 0.9653 -0.1789 +vn 0.1965 0.9606 -0.1965 +vn 0.1971 0.8943 -0.4018 +vn 0.1451 0.9882 0.0496 +vn 0.1510 0.9884 0.0169 +vn 0.2001 0.9797 -0.0072 +vn 0.2447 0.9470 -0.2081 +vn 0.2480 0.8823 -0.4001 +vn 0.0937 0.6592 -0.7461 +vn 0.1405 0.7733 -0.6182 +vn 0.1507 0.7770 -0.6112 +vn 0.1035 0.6633 -0.7412 +vn 0.2051 0.7724 -0.6012 +vn 0.1577 0.6624 -0.7324 +vn 0.0202 0.2528 -0.9673 +vn 0.0583 0.5095 -0.8585 +vn 0.0674 0.5108 -0.8570 +vn 0.0289 0.2544 -0.9667 +vn 0.1577 0.6624 -0.7323 +vn 0.1207 0.5118 -0.8506 +vn 0.0824 0.2596 -0.9622 +vn 0.0798 0.9393 0.3338 +vn 0.0867 0.9516 0.2948 +vn 0.1401 0.9541 0.2646 +vn -0.0134 0.6694 0.7427 +vn -0.0045 0.6635 0.7482 +vn 0.0501 0.6602 0.7494 +vn -0.0062 -0.0078 -1.0000 +vn -0.0063 -0.0127 -0.9999 +vn -0.0147 -0.0128 -0.9998 +vn -0.0146 -0.0082 -0.9999 +vn -0.0065 -0.0440 -0.9990 +vn -0.0237 -0.0483 -0.9986 +vn -0.0671 -0.0402 -0.9969 +vn -0.0707 -0.0190 -0.9973 +vn -0.0661 -0.0101 -0.9978 +vn -0.0027 0.0532 -0.9986 +vn -0.0107 0.0521 -0.9986 +vn 0.0119 0.2515 -0.9678 +vn -0.0618 0.0497 -0.9969 +vn -0.0400 0.2495 -0.9676 +vn 0.5731 -0.5804 -0.5785 +vn 0.5690 -0.5199 -0.6372 +vn 0.9741 -0.1446 -0.1737 +vn 0.9732 -0.1130 -0.2002 +vn 0.5690 -0.5199 -0.6371 +vn 0.9729 -0.0761 -0.2184 +vn 0.5678 -0.4322 -0.7005 +vn 0.5678 -0.4322 -0.7006 +vn -0.0388 -0.7289 -0.6835 +vn -0.5303 -0.6231 -0.5749 +vn -0.5415 -0.6316 -0.5548 +vn -0.0485 -0.7513 -0.6582 +vn -0.5304 -0.6231 -0.5749 +vn -0.9603 -0.2115 -0.1822 +vn -0.9637 -0.2034 -0.1732 +vn -0.9691 -0.1965 -0.1493 +vn -0.5710 -0.6545 -0.4956 +vn -0.0864 -0.8013 -0.5920 +vn -0.2113 -0.9720 -0.1028 +vn -0.6414 -0.7619 -0.0896 +vn -0.6572 -0.7449 0.1146 +vn -0.2524 -0.9554 0.1535 +vn -0.6414 -0.7620 -0.0896 +vn -0.9761 -0.2154 -0.0286 +vn -0.9771 -0.2104 0.0331 +vn -0.6573 -0.7449 0.1146 +vn -0.9813 -0.1747 0.0807 +vn -0.6705 -0.6766 0.3043 +vn -0.6705 -0.6767 0.3043 +vn -0.2495 -0.8817 0.4005 +vn 0.4984 -0.5732 0.6505 +vn 0.4857 -0.6930 0.5327 +vn 0.4984 -0.5732 0.6504 +vn 0.9608 -0.1772 0.2130 +vn 0.9623 -0.2285 0.1477 +vn 0.4858 -0.6930 0.5327 +vn 0.9602 -0.2651 0.0876 +vn 0.4575 -0.8121 0.3623 +vn 0.0031 -0.4563 0.8898 +vn 0.1610 -0.4747 0.8653 +vn 0.0234 -0.0451 0.9987 +vn -0.0031 -0.9371 0.3489 +vn 0.2720 -0.9042 0.3294 +vn 0.7574 -0.5848 0.2906 +vn 0.4746 -0.3147 0.8220 +vn 0.0688 -0.0344 0.9970 +vn -0.0076 -0.9371 -0.3491 +vn -0.0082 -0.4562 -0.8899 +vn 0.1500 -0.4745 -0.8674 +vn 0.2679 -0.9041 -0.3329 +vn 0.0109 -0.0478 -0.9988 +vn 0.0555 -0.0386 -0.9977 +vn 0.4635 -0.3162 -0.8277 +vn 0.4635 -0.3161 -0.8278 +vn 0.7534 -0.5851 -0.3001 +vn 0.5635 -0.7196 -0.4056 +vn 0.5747 -0.6366 -0.5143 +vn 0.5635 -0.7197 -0.4056 +vn 0.9725 -0.2027 -0.1150 +vn 0.9739 -0.1734 -0.1467 +vn 0.5746 -0.6366 -0.5143 +vn 0.5693 -0.0516 0.8205 +vn 0.0727 0.0005 0.9974 +vn 0.9607 -0.1021 0.2580 +vn 0.5692 -0.0516 0.8206 +vn 0.9600 0.0783 0.2687 +vn 0.5461 0.0515 0.8361 +vn 0.5462 0.0515 0.8361 +vn 0.0678 0.0152 0.9976 +vn -0.6471 -0.5834 0.4908 +vn -0.1995 -0.7506 0.6300 +vn -0.9809 -0.1486 0.1256 +vn -0.6471 -0.5834 0.4907 +vn -0.9777 -0.1397 0.1569 +vn -0.6146 -0.5143 0.5982 +vn -0.6146 -0.5143 0.5981 +vn -0.1536 -0.6428 0.7505 +vn -0.5337 -0.0104 0.8456 +vn -0.5506 -0.0798 0.8310 +vn -0.5337 -0.0103 0.8456 +vn -0.9629 -0.0314 0.2680 +vn -0.9518 -0.1493 0.2679 +vn -0.5505 -0.0798 0.8310 +vn -0.7480 -0.5935 0.2972 +vn -0.4593 -0.3237 0.8272 +vn -0.4592 -0.3236 0.8273 +vn -0.9398 0.3072 0.1496 +vn -0.5356 0.4009 0.7432 +vn -0.4961 0.4313 0.7536 +vn -0.9237 0.3412 0.1741 +vn -0.5356 0.4009 0.7433 +vn -0.0796 0.3428 0.9360 +vn -0.0413 0.3728 0.9270 +vn -0.0348 0.2345 0.9715 +vn -0.4991 0.2887 0.8171 +vn -0.4991 0.2886 0.8170 +vn -0.9438 0.2432 0.2240 +vn -0.0350 -0.3127 -0.9492 +vn -0.4909 -0.1579 -0.8568 +vn -0.5024 -0.1674 -0.8483 +vn -0.0675 -0.3394 -0.9382 +vn -0.9193 0.1189 -0.3751 +vn -0.9236 0.1371 -0.3581 +vn -0.9354 0.1133 -0.3350 +vn -0.4952 -0.0897 -0.8641 +vn -0.4952 -0.0897 -0.8642 +vn -0.0727 -0.2116 -0.9747 +vn -0.6164 -0.7149 -0.3300 +vn -0.1487 -0.9047 -0.3993 +vn -0.9751 -0.2000 -0.0956 +vn 0.9530 0.2121 0.2163 +vn 0.5209 0.5011 0.6910 +vn 0.5007 0.3814 0.7771 +vn 0.9457 0.1918 0.2625 +vn 0.5209 0.5011 0.6911 +vn 0.4755 0.1822 0.8606 +vn 0.9371 0.1518 0.3144 +vn 0.2374 0.4369 0.8676 +vn 0.2509 0.5052 0.8257 +vn 0.6447 0.3778 0.6646 +vn 0.6304 0.3697 0.6826 +vn 0.2591 0.5951 0.7607 +vn 0.6627 0.4091 0.6273 +vn 0.6446 0.3778 0.6646 +vn 0.9784 0.0382 0.2033 +vn 0.9779 0.0845 0.1914 +vn 0.9708 0.1557 0.1823 +vn -0.5382 0.0520 0.8412 +vn -0.9671 0.0725 0.2437 +vn -0.0706 0.0229 0.9972 +vn -0.5382 0.0521 0.8412 +vn -0.0965 -0.0708 0.9928 +vn -0.5595 -0.0580 0.8268 +vn -0.5594 -0.0580 0.8268 +vn -0.9713 -0.0191 0.2372 +vn -0.4868 0.0258 -0.8731 +vn -0.0423 -0.0166 -0.9990 +vn -0.9460 0.0650 -0.3176 +vn -0.9503 0.0219 -0.3106 +vn -0.4958 0.0604 -0.8663 +vn -0.0216 0.0703 -0.9973 +vn 0.5825 0.1822 -0.7921 +vn 0.5780 0.1242 -0.8065 +vn 0.9694 0.1332 -0.2062 +vn 0.9728 0.0779 -0.2183 +vn 0.9704 0.0356 -0.2390 +vn 0.5669 0.0849 -0.8194 +vn -0.9729 0.1611 0.1660 +vn -0.5672 0.5965 0.5679 +vn -0.5620 0.6199 0.5475 +vn -0.9710 0.1769 0.1609 +vn -0.0818 0.7254 0.6835 +vn -0.0764 0.7508 0.6561 +vn -0.5621 0.6199 0.5475 +vn -0.0435 0.8062 0.5900 +vn -0.5372 0.6760 0.5045 +vn -0.5372 0.6759 0.5045 +vn -0.9661 0.2064 0.1548 +vn -0.5741 -0.0825 0.8146 +vn -0.9751 -0.0410 0.2180 +vn -0.1066 -0.0882 0.9904 +vn -0.1184 -0.1322 0.9841 +vn -0.5823 -0.1262 0.8031 +vn -0.9760 -0.0634 0.2084 +vn -0.4872 0.0652 -0.8708 +vn -0.0123 0.0878 -0.9961 +vn -0.9461 0.0078 -0.3238 +vn -0.4873 0.0652 -0.8708 +vn -0.9435 0.0085 -0.3311 +vn -0.4753 0.1001 -0.8741 +vn 0.0025 0.1358 -0.9907 +vn -0.4935 0.0400 -0.8688 +vn 0.0045 0.0791 -0.9969 +vn -0.9514 -0.0230 -0.3070 +vn -0.9580 -0.0806 -0.2751 +vn -0.5188 -0.1588 -0.8400 +vn -0.5189 -0.1588 -0.8400 +vn -0.0132 -0.1595 -0.9871 +vn 0.4447 -0.8743 0.1945 +vn 0.9582 -0.2836 0.0384 +vn 0.9639 -0.2661 -0.0136 +vn 0.4782 -0.8780 0.0204 +vn 0.5753 -0.2901 -0.7648 +vn 0.9749 -0.0145 -0.2220 +vn 0.5753 -0.2900 -0.7648 +vn 0.9748 0.0841 -0.2066 +vn 0.5922 -0.0492 -0.8043 +vn 0.5922 -0.0493 -0.8043 +vn -0.5666 -0.0745 0.8206 +vn -0.9708 -0.0564 0.2332 +vn -0.1163 -0.0720 0.9906 +vn -0.0976 0.1604 0.9822 +vn -0.5528 0.1258 0.8238 +vn -0.5528 0.1258 0.8237 +vn -0.9683 0.0122 0.2495 +vn -0.9522 0.3035 0.0343 +vn -0.4464 0.8878 0.1117 +vn -0.4185 0.8998 -0.1236 +vn -0.9491 0.3122 -0.0423 +vn 0.0858 0.9904 0.1079 +vn 0.1323 0.9800 -0.1488 +vn 0.1262 0.9083 -0.3987 +vn -0.4203 0.8364 -0.3517 +vn -0.4203 0.8365 -0.3517 +vn -0.9471 0.2962 -0.1232 +vn -0.0479 -0.5716 -0.8191 +vn -0.5403 -0.4915 -0.6830 +vn -0.5364 -0.5852 -0.6082 +vn -0.0458 -0.6826 -0.7294 +vn -0.9625 -0.1705 -0.2109 +vn -0.9612 -0.2014 -0.1885 +vn 0.5443 -0.1306 0.8287 +vn 0.5263 -0.3906 0.7552 +vn 0.5443 -0.1305 0.8287 +vn 0.9591 0.0491 0.2787 +vn 0.9634 -0.0725 0.2581 +vn 0.5264 -0.3906 0.7552 +vn 0.5409 0.0331 0.8404 +vn 0.0635 -0.0382 0.9972 +vn 0.9544 0.1092 0.2779 +vn -0.5300 -0.3533 -0.7708 +vn -0.0344 -0.4022 -0.9149 +vn -0.9603 -0.1317 -0.2461 +vn -0.5300 -0.3534 -0.7708 +vn -0.5460 0.3289 0.7705 +vn -0.9681 0.0839 0.2362 +vn -0.0777 0.3988 0.9137 +vn -0.0685 0.5674 0.8206 +vn -0.5432 0.4724 0.6941 +vn -0.5433 0.4724 0.6940 +vn -0.9677 0.1292 0.2163 +vn 0.9718 0.2011 -0.1234 +vn 0.6327 0.6983 -0.3346 +vn 0.6261 0.7579 -0.1830 +vn 0.9688 0.2347 -0.0790 +vn 0.6328 0.6983 -0.3346 +vn 0.6261 0.7580 -0.1830 +vn 0.5985 0.8008 -0.0212 +vn 0.9642 0.2640 -0.0262 +vn -0.6085 -0.4089 0.6801 +vn -0.1193 -0.4984 0.8587 +vn -0.9789 -0.1195 0.1660 +vn -0.6084 -0.4089 0.6801 +vn -0.9760 -0.0837 0.2009 +vn -0.5815 -0.2142 0.7848 +vn 0.4762 -0.0157 0.8792 +vn 0.9390 0.0933 0.3310 +vn 0.4930 -0.0772 0.8666 +vn 0.9457 0.0506 0.3210 +vn 0.4962 -0.0703 0.8654 +vn 0.9483 0.0172 0.3170 +vn 0.5020 -0.0723 0.8618 +vn 0.5021 -0.0723 0.8618 +vn 0.9524 -0.0121 0.3047 +vn 0.5495 -0.0019 0.8355 +vn 0.9604 -0.0674 0.2702 +vn 0.5496 -0.0019 0.8354 +vn 0.5787 0.1457 0.8024 +vn 0.9458 -0.1582 0.2838 +vn 0.5714 0.7943 0.2064 +vn 0.9627 0.2647 0.0561 +vn 0.5502 0.7271 0.4107 +vn 0.5502 0.7270 0.4107 +vn 0.9632 0.2350 0.1305 +vn 0.5900 0.1596 -0.7914 +vn 0.9687 0.1515 -0.1966 +vn 0.5900 0.1596 -0.7915 +vn 0.5308 -0.0841 -0.8433 +vn 0.9552 -0.0977 -0.2793 +vn 0.9081 -0.3376 -0.2477 +vn 0.4629 -0.4025 -0.7897 +vn 0.5315 0.2606 0.8060 +vn 0.9184 -0.1616 0.3612 +vn 0.5316 0.2606 0.8059 +vn 0.4528 0.1813 0.8730 +vn 0.4527 0.1813 0.8730 +vn 0.8959 -0.1393 0.4219 +vn 0.4431 -0.5754 -0.6875 +vn 0.8880 -0.4371 -0.1432 +vn 0.9344 -0.3414 -0.1016 +vn 0.5366 -0.4377 -0.7214 +vn 0.7534 -0.5851 -0.3002 +vn 0.4635 -0.3162 -0.8278 +vn 0.5597 -0.0636 -0.8263 +vn 0.9582 -0.1062 -0.2658 +vn 0.0596 -0.0155 -0.9981 +vn 0.0557 -0.0031 -0.9984 +vn 0.5426 0.0370 -0.8392 +vn 0.5427 0.0370 -0.8391 +vn 0.9622 0.0733 -0.2624 +vn 0.9735 0.1598 -0.1635 +vn 0.5968 0.5407 -0.5928 +vn 0.6157 0.6145 -0.4933 +vn 0.9727 0.1680 -0.1600 +vn 0.6157 0.6145 -0.4932 +vn -0.9593 -0.2307 -0.1627 +vn -0.9724 -0.2217 -0.0721 +vn -0.9882 -0.0353 0.1491 +vn -0.9924 -0.0839 0.0896 +vn -0.9454 -0.2831 0.1617 +vn -0.9280 -0.0726 0.3654 +vn -0.8415 0.1236 0.5259 +vn -0.9206 0.1514 0.3600 +vn -0.9400 0.0695 0.3340 +vn -0.4553 0.6948 -0.5567 +vn -0.9510 0.2403 -0.1948 +vn 0.0736 0.7713 -0.6322 +vn -0.4552 0.6948 -0.5568 +vn 0.0281 0.6541 -0.7559 +vn -0.4897 0.5707 -0.6592 +vn -0.9557 0.1896 -0.2253 +vn -0.5453 -0.0552 0.8364 +vn -0.9682 -0.0436 0.2464 +vn -0.4966 0.4395 -0.7485 +vn -0.9532 0.1388 -0.2685 +vn -0.0040 0.5073 -0.8618 +vn -0.4965 0.4396 -0.7485 +vn -0.5092 0.2092 -0.8349 +vn -0.5092 0.2092 -0.8348 +vn -0.9528 0.0478 -0.2998 +vn -0.5262 0.0293 -0.8499 +vn -0.9574 -0.0155 -0.2884 +vn -0.5372 -0.0252 -0.8431 +vn -0.9615 -0.0354 -0.2724 +vn 0.5327 -0.8205 -0.2075 +vn 0.9706 -0.2308 -0.0684 +vn 0.5326 -0.8205 -0.2075 +vn 0.5396 0.1097 -0.8347 +vn 0.9601 0.1319 -0.2465 +vn 0.0594 0.0608 -0.9964 +vn 0.5396 0.1097 -0.8348 +vn 0.5433 0.2613 -0.7978 +vn 0.5433 0.2614 -0.7978 +vn 0.9612 0.1666 -0.2199 +vn -0.5584 -0.0918 -0.8245 +vn -0.9536 -0.1523 -0.2597 +vn -0.5584 -0.0918 -0.8244 +vn -0.4685 -0.3249 -0.8216 +vn -0.4684 -0.3249 -0.8216 +vn -0.7511 -0.5935 -0.2891 +vn 0.5656 0.4443 -0.6947 +vn 0.9671 0.1778 -0.1818 +vn 0.5655 0.4444 -0.6948 +vn 0.5968 0.5407 -0.5929 +vn -0.4906 0.7933 0.3606 +vn -0.9582 0.2614 0.1167 +vn 0.0170 0.9161 0.4007 +vn -0.5543 0.5615 0.6144 +vn -0.9705 0.1516 0.1875 +vn -0.0728 0.6780 0.7314 +vn -0.5544 0.5615 0.6143 +vn -0.5544 0.5614 0.6144 +vn 0.5328 0.6640 0.5246 +vn 0.9610 0.2196 0.1683 +vn 0.5246 0.6231 0.5802 +vn 0.9582 0.2218 0.1806 +vn 0.9994 -0.0301 -0.0189 +vn 0.9995 -0.0328 -0.0030 +vn 0.9996 -0.0097 0.0274 +vn -1.0000 -0.0051 -0.0047 +vn -0.9998 -0.0168 -0.0089 +vn -0.9996 -0.0279 -0.0104 +vn -0.9994 -0.0311 -0.0115 +vn -0.9992 -0.0325 -0.0221 +vn -0.9986 -0.0387 -0.0371 +vn 0.9999 -0.0022 -0.0165 +vn 0.9996 -0.0147 -0.0220 +vn 0.9926 0.1174 0.0310 +vn 0.9963 0.0850 0.0087 +vn 0.9978 0.0659 -0.0081 +vn 0.9935 0.0961 0.0609 +vn 0.9902 0.1295 0.0522 +vn -0.9979 -0.0393 -0.0515 +vn -0.9979 -0.0293 -0.0577 +vn -0.9985 -0.0170 -0.0523 +vn -0.9993 0.0020 -0.0378 +vn 0.9689 -0.2430 0.0467 +vn 0.9965 -0.0819 0.0191 +vn 0.9993 0.0132 0.0342 +vn 1.0000 0.0043 0.0024 +vn 1.0000 0.0007 -0.0064 +vn 0.9973 0.0501 0.0530 +vn -0.9969 0.0743 -0.0249 +vn -0.9805 0.1921 -0.0422 +vn 0.9553 -0.2584 0.1435 +vn 0.9422 -0.3162 0.1107 +vn -0.9637 0.2501 -0.0934 +vn -0.9673 0.2187 -0.1281 +vn 0.9969 0.0790 0.0057 +vn 0.9943 -0.1064 -0.0047 +vn 0.8006 -0.5992 -0.0053 +vn -0.9998 0.0220 -0.0031 +vn -0.9999 0.0113 0.0028 +vn -1.0000 0.0020 0.0015 +vn -0.2077 -0.5317 -0.8211 +vn -0.2036 -0.6594 -0.7237 +vn -0.6139 -0.5783 -0.5373 +vn -0.5838 -0.4883 -0.6486 +vn -0.2101 -0.7404 -0.6385 +vn -0.6488 -0.6768 -0.3480 +vn -0.6139 -0.5784 -0.5373 +vn -0.6487 -0.6768 -0.3480 +vn -0.5837 -0.4884 -0.6487 +vn -0.9996 0.0167 -0.0238 +vn -0.9996 0.0243 -0.0138 +vn -0.0058 -1.0000 0.0000 +vn -0.2963 -0.9551 0.0018 +vn -0.2756 -0.9039 -0.3271 +vn -0.2715 -0.9040 0.3302 +vn -0.7930 -0.6091 0.0038 +vn -0.9994 -0.0219 -0.0280 +vn -0.9995 -0.0012 -0.0306 +vn -0.9994 -0.0349 -0.0027 +vn -0.9994 -0.0300 -0.0149 +vn 0.9985 0.0537 -0.0109 +vn 0.9560 0.2238 0.1896 +vn 0.9993 0.0367 -0.0006 +vn 0.9928 0.1065 0.0542 +vn 0.9917 0.1250 0.0290 +vn -0.9878 -0.1559 0.0030 +vn 0.9974 0.0458 0.0549 +vn -1.0000 -0.0005 -0.0019 +vn -0.9994 -0.0324 -0.0085 +vn 0.9998 0.0176 0.0057 +vn 0.5245 0.5774 0.6257 +vn 0.5246 0.5774 0.6256 +vn 0.9238 -0.3114 -0.2229 +vn 0.9158 -0.3966 0.0639 +vn 0.5000 -0.7936 -0.3468 +vn 0.3980 -0.6409 -0.6564 +vn 0.7337 -0.4350 0.5220 +vn 0.4525 -0.8897 0.0604 +vn 0.5000 -0.7936 -0.3467 +vn 0.4528 -0.8896 0.0606 +vn -0.0280 -0.8897 -0.4557 +vn -0.0704 -0.7950 -0.6025 +vn 0.3981 -0.6409 -0.6564 +vn -0.1284 -0.6602 -0.7401 +vn 0.2537 0.6780 0.6899 +vn 0.6588 0.3899 0.6434 +vn 0.2537 0.6779 0.6899 +vn 0.2383 0.6947 0.6786 +vn 0.5401 0.3304 0.7740 +vn 0.6588 0.3898 0.6434 +vn 0.7212 -0.1413 0.6782 +vn 0.9315 -0.0435 0.3612 +vn -0.1693 -0.6987 -0.6951 +vn -0.1433 -0.7895 -0.5968 +vn -0.1481 -0.7944 -0.5890 +vn -0.1672 -0.7220 -0.6714 +vn -0.0814 -0.8826 -0.4630 +vn -0.0985 -0.8834 -0.4582 +vn -0.1362 -0.8823 -0.4506 +vn -0.1963 -0.8187 -0.5397 +vn 0.9979 -0.0588 -0.0276 +vn 0.9980 0.0376 -0.0510 +vn 0.9922 -0.1225 0.0212 +vn 0.9293 -0.2252 -0.2926 +vn 0.9360 -0.1098 -0.3343 +vn 0.3868 -0.5196 -0.7619 +vn 0.4041 -0.3992 -0.8230 +vn -0.1317 -0.5522 -0.8232 +vn -0.1237 -0.4632 -0.8776 +vn -0.1691 -0.5007 -0.8489 +vn -0.1688 -0.6083 -0.7756 +vn -0.1659 -0.6392 -0.7510 +vn -0.1725 -0.5174 -0.8382 +vn -0.4137 0.5498 0.7257 +vn -0.4167 0.4229 0.8047 +vn -0.3704 0.5541 0.7455 +vn -0.4136 0.5498 0.7257 +vn 0.1073 0.7035 0.7025 +vn 0.0965 0.6442 0.7588 +vn 0.1056 0.5143 0.8511 +vn 0.1740 0.4823 0.8585 +vn 0.1773 0.5822 0.7935 +vn 0.1957 0.5417 0.8175 +vn 0.1841 0.4566 0.8704 +vn 0.1840 0.6623 0.7263 +vn 0.2033 0.6301 0.7494 +vn 0.2073 -0.9560 0.2077 +vn 0.1192 -0.9594 0.2556 +vn 0.2072 -0.9560 0.2076 +vn 0.3907 -0.4561 0.7996 +vn 0.2718 -0.4668 0.8416 +vn 0.1193 -0.9594 0.2555 +vn -0.1446 -0.4864 0.8617 +vn -0.1677 -0.9461 0.2770 +vn -0.1678 -0.9461 0.2769 +vn 0.3958 -0.1564 0.9049 +vn 0.3215 0.3449 0.8819 +vn 0.2624 0.3207 0.9101 +vn 0.2899 -0.1668 0.9424 +vn 0.1920 0.7057 0.6820 +vn 0.1811 0.6983 0.6926 +vn 0.1521 0.6924 0.7053 +vn 0.0529 0.3178 0.9467 +vn -0.0708 -0.1507 0.9860 +vn 0.3988 -0.2909 0.8697 +vn 0.4898 -0.2893 0.8224 +vn 0.4824 -0.1655 0.8602 +vn 0.4846 -0.4396 0.7562 +vn 0.7337 -0.4349 0.5220 +vn 0.7285 -0.2713 0.6290 +vn 0.7212 -0.1414 0.6782 +vn -0.7043 -0.4218 0.5710 +vn -0.6393 -0.1981 0.7430 +vn -0.0916 -0.2930 0.9517 +vn -0.5766 -0.0203 0.8168 +vn 0.1787 0.7213 0.6692 +vn 0.1923 0.7097 0.6778 +vn 0.1920 0.7058 0.6819 +vn 0.2098 0.6996 0.6830 +vn 0.1923 0.7097 0.6777 +vn -0.5403 -0.8411 0.0228 +vn -0.5403 -0.8412 0.0228 +vn -0.2309 0.4359 0.8699 +vn 0.1192 0.7126 0.6913 +vn -0.3705 0.5541 0.7455 +vn 0.1192 0.7127 0.6913 +vn 0.9450 -0.1992 0.2594 +vn 0.7285 -0.2714 0.6291 +vn 0.1938 -0.8502 0.4895 +vn 0.8213 -0.4951 0.2834 +vn 0.4869 -0.6825 -0.5451 +vn -0.0160 -0.9528 -0.3032 +vn 0.9777 0.1828 -0.1037 +vn 0.5265 -0.1074 -0.8433 +vn 0.4869 -0.6824 -0.5451 +vn 0.5266 -0.1073 -0.8433 +vn -0.0477 -0.2824 -0.9581 +vn -0.0755 -0.4062 -0.9107 +vn -0.0160 -0.9528 -0.3031 +vn -0.1741 -0.5265 -0.8321 +vn -0.9116 -0.0903 0.4011 +vn -0.9283 -0.0359 0.3701 +vn -0.3877 0.2513 0.8869 +vn -0.3618 0.1634 0.9178 +vn -0.3876 0.2513 0.8869 +vn 0.1336 0.3656 0.9211 +vn 0.1547 0.2873 0.9453 +vn 0.2293 0.1654 0.9592 +vn 0.2264 0.2248 0.9477 +vn 0.2089 0.2641 0.9416 +vn 0.2323 0.1613 0.9592 +vn 0.2397 0.1040 0.9653 +vn 0.1123 0.1720 0.9787 +vn 0.0380 0.3000 0.9532 +vn 0.1815 0.3325 0.9255 +vn 0.2490 0.3497 0.9032 +vn 0.2680 0.2957 0.9169 +vn 0.2813 0.1736 0.9438 +vn 0.9124 0.0786 -0.4018 +vn 0.9272 0.0099 -0.3745 +vn 0.3957 -0.2833 -0.8736 +vn 0.3753 -0.2138 -0.9019 +vn -0.1311 -0.3848 -0.9137 +vn -0.1455 -0.3373 -0.9301 +vn 0.9522 0.2693 0.1444 +vn 0.9592 0.2310 0.1628 +vn 0.9870 0.1378 -0.0829 +vn 0.9756 0.1907 -0.1083 +vn -0.2562 -0.3046 -0.9174 +vn -0.2317 -0.3855 -0.8931 +vn -0.5965 -0.3829 -0.7054 +vn -0.6220 -0.3245 -0.7126 +vn -0.9535 -0.2436 -0.1775 +vn -0.6221 -0.3245 -0.7126 +vn -0.9549 -0.2486 -0.1625 +vn -0.9843 -0.1508 0.0915 +vn -0.9775 -0.1835 0.1042 +vn 0.2365 0.3822 0.8933 +vn 0.6210 0.3738 0.6889 +vn 0.6235 0.3719 0.6877 +vn 0.6210 0.3739 0.6889 +vn 0.6236 0.3719 0.6876 +vn 0.0165 -0.1012 0.9947 +vn 0.0743 -0.1769 0.9814 +vn 0.4721 -0.1707 0.8649 +vn 0.4233 -0.1401 0.8951 +vn 0.1376 -0.1745 0.9750 +vn 0.5261 -0.1362 0.8394 +vn 0.5262 -0.1362 0.8394 +vn 0.9587 0.0287 0.2830 +vn 0.9434 -0.0402 0.3293 +vn 0.4232 -0.1401 0.8951 +vn 0.9168 -0.1099 0.3838 +vn -0.9454 0.0251 -0.3249 +vn -0.9575 -0.0344 -0.2863 +vn -0.9999 -0.0084 -0.0122 +vn -0.9956 0.0701 -0.0622 +vn -0.9631 -0.0896 -0.2536 +vn -0.9966 -0.0762 0.0312 +vn -0.9356 -0.0547 0.3488 +vn -0.9554 0.0188 0.2949 +vn -0.9653 0.1110 0.2363 +vn -0.0625 -0.1136 -0.9916 +vn -0.1158 -0.0598 -0.9915 +vn -0.5511 -0.0742 -0.8312 +vn -0.5199 -0.0803 -0.8504 +vn -0.1692 -0.0371 -0.9849 +vn -0.5787 -0.0847 -0.8111 +vn -0.5511 -0.0742 -0.8311 +vn -0.5788 -0.0847 -0.8111 +vn 0.9990 0.0433 -0.0072 +vn 0.9968 -0.0576 0.0551 +vn 0.9935 0.1036 -0.0465 +vn 0.9054 0.1742 -0.3871 +vn 0.9346 0.1155 -0.3364 +vn 0.9657 -0.0161 -0.2592 +vn 0.4275 0.2131 -0.8785 +vn 0.5074 0.0984 -0.8561 +vn 0.3674 0.2260 -0.9022 +vn 0.3673 0.2260 -0.9022 +vn -0.0515 0.1809 -0.9821 +vn 0.0154 0.1811 -0.9834 +vn 0.0792 0.0981 -0.9920 +vn 0.0129 -0.0162 -0.9998 +vn -0.0439 0.0521 -0.9977 +vn -0.0610 -0.0139 -0.9980 +vn -0.0053 -0.0758 -0.9971 +vn -0.1013 0.0704 -0.9924 +vn -0.1181 0.0096 -0.9930 +vn -0.4875 0.0709 0.8702 +vn -0.5358 0.1643 0.8282 +vn -0.4295 0.0097 0.9030 +vn -0.4876 0.0709 0.8702 +vn 0.0638 0.0275 0.9976 +vn 0.0031 0.0594 0.9982 +vn -0.5357 0.1643 0.8282 +vn -0.0543 0.1242 0.9908 +vn -0.0128 0.0171 0.9998 +vn 0.0438 -0.0515 0.9977 +vn 0.0419 -0.1222 0.9916 +vn -0.0163 -0.0483 0.9987 +vn 0.1010 -0.0743 0.9921 +vn 0.1018 -0.1337 0.9858 +vn -0.0427 0.1555 0.9869 +vn -0.0427 0.1159 0.9923 +vn -0.0036 0.0795 0.9968 +vn -0.9605 0.2139 0.1782 +vn -0.5565 0.2851 0.7804 +vn -0.0894 0.2278 0.9696 +vn 0.0426 -0.1550 -0.9870 +vn 0.0273 -0.1898 -0.9814 +vn 0.0131 -0.3291 -0.9442 +vn -0.0283 -0.2067 -0.9780 +vn 0.9697 -0.1829 -0.1622 +vn 0.5679 -0.1354 -0.8119 +vn 0.5680 -0.1354 -0.8118 +vn 0.1086 -0.0950 -0.9895 +vn 0.8935 -0.1430 0.4256 +vn 0.9798 -0.1622 0.1169 +vn -0.4929 -0.1109 -0.8630 +vn -0.4929 -0.1108 -0.8630 +vn -0.9285 0.0796 -0.3626 +vn -0.9822 0.1508 -0.1117 +vn 0.4104 -0.0143 0.9118 +vn 0.1848 -0.1315 0.9739 +vn 0.5627 -0.0695 0.8237 +vn 0.2247 -0.0748 0.9716 +vn 0.6057 0.0334 0.7950 +vn 0.9578 0.2441 0.1520 +vn 0.9659 0.1058 0.2365 +vn -0.9652 -0.1623 -0.2049 +vn -0.9837 -0.1566 0.0883 +vn -0.9578 -0.2476 -0.1458 +vn -0.9581 -0.2442 0.1500 +vn -0.8694 -0.2140 0.4454 +vn -0.9075 -0.1325 0.3985 +vn -0.2129 -0.0390 -0.9763 +vn -0.6135 -0.1212 -0.7803 +vn -0.2474 -0.0637 -0.9668 +vn -0.6391 -0.1778 -0.7483 +vn 0.9812 0.1680 -0.0946 +vn 0.9411 0.2891 -0.1754 +vn 0.8126 0.3141 -0.4910 +vn 0.8730 0.2205 -0.4350 +vn 0.3139 0.2177 -0.9242 +vn 0.8126 0.3141 -0.4909 +vn 0.2600 0.2207 -0.9401 +vn 0.3140 0.2177 -0.9242 +vn -0.1397 0.0985 -0.9853 +vn -0.1023 0.1440 -0.9843 +vn -0.0610 0.0115 -0.9981 +vn -0.1147 0.1084 -0.9875 +vn -0.2172 -0.0642 -0.9740 +vn -0.1894 -0.0319 -0.9814 +vn -0.2152 0.1326 -0.9675 +vn -0.2271 -0.0475 -0.9727 +vn -0.2290 -0.1663 -0.9591 +vn -0.2380 -0.1740 -0.9556 +vn -0.2719 -0.1860 -0.9442 +vn -0.2664 -0.1101 -0.9575 +vn -0.3783 -0.0368 0.9249 +vn -0.3357 -0.0737 0.9391 +vn 0.1466 0.0369 0.9885 +vn 0.1127 0.0221 0.9934 +vn 0.0345 -0.0753 0.9966 +vn 0.1103 0.0751 0.9911 +vn 0.2075 0.0369 0.9775 +vn 0.1613 -0.0697 0.9844 +vn 0.2056 0.2496 0.9463 +vn 0.2251 0.1057 0.9686 +vn 0.2625 0.0268 0.9646 +vn 0.6469 0.1830 0.7403 +vn 0.6564 0.2993 0.6925 +vn 0.9324 0.3540 0.0735 +vn 0.9303 0.3585 0.0769 +vn -0.9476 -0.2958 -0.1210 +vn -0.9420 -0.2845 0.1780 +vn -0.9477 -0.2876 -0.1381 +vn -0.9528 -0.2579 0.1602 +vn -0.8655 -0.1974 0.4604 +vn -0.8474 -0.2431 0.4720 +vn -0.6371 -0.2242 -0.7374 +vn -0.6266 -0.2632 -0.7336 +vn 0.9024 0.3676 -0.2249 +vn 0.9253 0.3235 -0.1979 +vn 0.8230 0.2595 -0.5053 +vn 0.7782 0.3499 -0.5216 +vn 0.2386 0.1629 -0.9573 +vn 0.2815 0.0126 -0.9595 +vn -0.1848 -0.1433 -0.9723 +vn -0.1736 0.0066 -0.9848 +vn 0.1679 -0.0190 0.9856 +vn 0.1043 -0.0137 0.9945 +vn 0.2197 0.0362 0.9749 +vn 0.3510 0.0441 0.9353 +vn 0.2687 -0.1050 0.9575 +vn 0.1567 -0.2262 0.9614 +vn 0.1410 -0.1001 0.9849 +vn -0.3007 -0.0631 0.9516 +vn -0.8654 -0.1974 0.4605 +vn -0.3023 0.0153 0.9531 +vn 0.1764 0.1603 0.9712 +vn 0.1707 0.0803 0.9820 +vn -0.0563 0.8683 -0.4928 +vn -0.7586 0.5696 -0.3165 +vn -0.4863 0.2881 -0.8250 +vn -0.1620 0.4997 -0.8509 +vn -0.7586 0.5695 -0.3164 +vn -0.9651 -0.2102 0.1559 +vn -0.7170 -0.0775 -0.6927 +vn -0.4862 0.2880 -0.8250 +vn -0.3052 0.0193 -0.9521 +vn -0.2686 0.0641 -0.9611 +vn -0.1621 0.4997 -0.8509 +vn 0.8402 -0.2179 -0.4966 +vn 0.6963 -0.5796 -0.4234 +vn 0.5026 -0.5792 -0.6419 +vn 0.5762 -0.1757 -0.7982 +vn 0.3781 -0.8852 -0.2710 +vn 0.2614 -0.8350 -0.4842 +vn 0.5025 -0.5792 -0.6419 +vn 0.0462 -0.0231 0.9987 +vn 0.0587 -0.0716 0.9957 +vn 0.3966 -0.4349 0.8084 +vn 0.4220 -0.1355 0.8964 +vn 0.0539 -0.1539 0.9866 +vn 0.2370 -0.6417 0.7294 +vn 0.2370 -0.6419 0.7293 +vn 0.3966 -0.9059 0.1483 +vn 0.7522 -0.6083 0.2534 +vn 0.9186 -0.2427 0.3120 +vn 0.0331 -0.2692 -0.9625 +vn 0.2614 -0.8352 -0.4839 +vn 0.0645 -0.6957 -0.7154 +vn 0.0150 -0.2673 -0.9635 +vn 0.1052 -0.9779 -0.1808 +vn -0.2527 -0.9364 -0.2435 +vn -0.1244 -0.8584 -0.4977 +vn -0.0063 -0.2650 -0.9642 +vn 0.0946 -0.7074 0.7005 +vn 0.1117 -0.9861 0.1231 +vn 0.0345 -0.1523 0.9877 +vn 0.0946 -0.7076 0.7003 +vn 0.0107 -0.1433 0.9896 +vn -0.0804 -0.6434 0.7613 +vn -0.0803 -0.6433 0.7614 +vn -0.2416 -0.9391 0.2443 +vn -0.2237 -0.9746 -0.0066 +vn 0.1113 -0.9934 -0.0292 +vn 0.3734 -0.9255 -0.0634 +vn -0.8987 -0.2629 -0.3509 +vn -0.7161 -0.6211 -0.3184 +vn -0.7298 -0.6819 0.0488 +vn -0.9555 -0.2777 0.0995 +vn -0.7161 -0.6211 -0.3185 +vn -0.6792 -0.6138 0.4025 +vn -0.8415 -0.2423 0.4829 +vn -0.0168 -0.0112 0.9998 +vn -0.0155 -0.0528 0.9985 +vn 0.0188 -0.0342 0.9992 +vn 0.0139 -0.0116 0.9998 +vn -0.4928 -0.5855 -0.6437 +vn -0.6388 -0.2068 -0.7410 +vn -0.8988 -0.2628 -0.3509 +vn -0.6792 -0.6138 0.4024 +vn -0.3060 -0.3886 0.8691 +vn -0.3360 -0.1021 0.9363 +vn 0.9186 -0.2428 0.3119 +vn 0.7522 -0.6083 0.2533 +vn 0.7469 -0.6546 -0.1167 +vn 0.9566 -0.2564 -0.1384 +vn 0.6963 -0.5796 -0.4233 +vn 0.0402 -0.0162 0.9991 +vn 0.0105 -0.0117 0.9999 +vn 0.0380 -0.0258 0.9989 +vn 0.0091 -0.0254 0.9996 +vn -0.0200 -0.0255 0.9995 +vn -0.0192 -0.0106 0.9998 +vn -0.9291 -0.1057 -0.3545 +vn -0.6542 -0.0756 -0.7526 +vn -0.9357 -0.0119 -0.3527 +vn -0.6568 0.0041 -0.7541 +vn -0.3282 -0.0440 0.9436 +vn -0.3234 -0.0308 0.9458 +vn -0.8564 -0.0324 0.5153 +vn -0.8569 -0.1020 0.5052 +vn 0.8541 -0.0404 -0.5186 +vn 0.9892 -0.0539 -0.1362 +vn 0.8521 0.0099 -0.5232 +vn 0.9910 -0.0007 -0.1339 +vn 0.9368 -0.0132 0.3496 +vn 0.9386 -0.0584 0.3399 +vn 0.9387 -0.0584 0.3399 +vn 0.3927 -0.0372 0.9189 +vn 0.9368 -0.0132 0.3495 +vn 0.3802 -0.0256 0.9245 +vn 0.5718 -0.0234 -0.8201 +vn 0.5686 0.0190 -0.8224 +vn 0.8522 0.0100 -0.5232 +vn -0.8570 -0.1020 0.5052 +vn -0.9860 -0.1145 0.1213 +vn -0.8564 -0.0324 0.5154 +vn -0.9909 -0.0254 0.1319 +vn -0.9291 -0.1057 -0.3544 +vn -0.9361 0.0401 -0.3494 +vn -0.6616 0.0533 -0.7480 +vn -0.9374 0.0673 -0.3417 +vn -0.6742 0.0922 -0.7328 +vn -0.0181 -0.0471 0.9987 +vn -0.3201 -0.0381 0.9466 +vn -0.0117 -0.0839 0.9964 +vn -0.3187 -0.0704 0.9453 +vn -0.8556 -0.0114 0.5176 +vn -0.8545 -0.0045 0.5194 +vn 0.8534 0.0265 -0.5205 +vn 0.9910 0.0114 -0.1331 +vn 0.8587 0.0506 -0.5100 +vn 0.9911 0.0270 -0.1304 +vn 0.9415 -0.0069 0.3369 +vn 0.9380 -0.0092 0.3466 +vn 0.9380 -0.0093 0.3466 +vn 0.3832 -0.0368 0.9229 +vn 0.3949 -0.0581 0.9169 +vn 0.0471 -0.0728 0.9962 +vn 0.0395 -0.0433 0.9983 +vn 0.5733 0.0376 -0.8185 +vn 0.5895 0.0668 -0.8050 +vn 0.8534 0.0266 -0.5205 +vn -0.8546 -0.0045 0.5193 +vn -0.9905 0.0178 0.1366 +vn -0.8556 -0.0115 0.5175 +vn -0.9898 0.0272 0.1401 +vn 0.0106 -0.0456 0.9989 +vn 0.0176 -0.0789 0.9967 +vn -0.8552 -0.0493 0.5159 +vn -0.9889 0.0176 0.1478 +vn -0.8510 -0.1504 0.5031 +vn -0.9871 -0.0202 0.1587 +vn -0.9398 0.1543 -0.3050 +vn -0.9395 0.0973 -0.3284 +vn 0.0649 -0.1234 0.9902 +vn 0.0362 -0.1404 0.9894 +vn 0.1034 -0.2537 0.9617 +vn 0.0764 -0.2961 0.9521 +vn 0.0488 -0.3349 0.9410 +vn 0.0071 -0.1569 0.9876 +vn -0.5288 0.1841 -0.8285 +vn -0.4414 0.3216 -0.8377 +vn -0.5289 0.1841 -0.8285 +vn -0.4415 0.3216 -0.8377 +vn -0.1171 0.3288 -0.9371 +vn -0.0893 0.2118 -0.9732 +vn -0.3074 -0.1452 0.9404 +vn -0.2714 -0.3319 0.9034 +vn -0.8510 -0.1504 0.5032 +vn -0.8552 -0.0492 0.5159 +vn 0.8637 0.0756 -0.4984 +vn 0.9908 0.0360 -0.1308 +vn 0.8523 0.0921 -0.5149 +vn 0.9876 0.0036 -0.1571 +vn 0.9588 -0.0978 0.2666 +vn 0.9468 -0.0179 0.3213 +vn -0.0814 0.2937 -0.9524 +vn -0.0540 0.1851 -0.9812 +vn -0.0418 0.2575 -0.9654 +vn -0.0172 0.1605 -0.9869 +vn 0.9468 -0.0179 0.3214 +vn 0.4124 -0.0979 0.9057 +vn 0.9588 -0.0978 0.2667 +vn 0.4422 -0.2182 0.8700 +vn 0.3049 0.2184 -0.9270 +vn 0.4243 0.1262 -0.8967 +vn 0.8523 0.0922 -0.5148 +vn 0.9136 -0.4053 -0.0330 +vn 0.4572 -0.6604 0.5956 +vn 0.4422 -0.2181 0.8700 +vn 0.4757 -0.7272 -0.4948 +vn 0.2419 -0.9602 -0.1398 +vn 0.4572 -0.6605 0.5956 +vn 0.0820 -0.9839 0.1588 +vn 0.1401 -0.6483 0.7484 +vn 0.4572 -0.6604 0.5957 +vn -0.0778 0.5325 -0.8428 +vn 0.2572 0.4580 -0.8509 +vn -0.0818 0.6841 -0.7248 +vn 0.2364 0.5593 -0.7945 +vn 0.6435 -0.0933 -0.7598 +vn 0.7969 0.1126 -0.5936 +vn -0.8355 -0.3552 0.4194 +vn -0.9846 -0.1121 0.1341 +vn -0.7823 -0.5959 0.1814 +vn -0.9603 -0.2788 -0.0108 +vn -0.9503 0.0717 -0.3031 +vn -0.9459 0.1985 -0.2567 +vn 0.1108 -0.6553 0.7472 +vn 0.0702 -0.9579 0.2785 +vn 0.0521 -0.9226 0.3823 +vn 0.0818 -0.6615 0.7455 +vn -0.4728 0.5202 -0.7112 +vn -0.5034 0.5538 -0.6633 +vn -0.1754 0.6530 -0.7367 +vn -0.1590 0.5671 -0.8082 +vn -0.2339 -0.6460 0.7266 +vn -0.2341 -0.8838 0.4051 +vn -0.8355 -0.3552 0.4193 +vn -0.8354 -0.3552 0.4194 +vn 0.7969 0.1125 -0.5935 +vn 0.9417 -0.1595 -0.2964 +vn 0.6576 -0.4619 -0.5951 +vn 0.4757 -0.7273 -0.4948 +vn -0.1203 0.5482 -0.8276 +vn -0.1296 0.6606 -0.7394 +vn 0.1688 0.7914 0.5875 +vn 0.3437 0.5806 0.7381 +vn 0.3173 0.6889 0.6518 +vn 0.1271 0.9008 0.4153 +vn 0.3437 0.5805 0.7382 +vn 0.4088 0.6436 0.6470 +vn 0.4137 0.6768 0.6090 +vn 0.3172 0.6888 0.6518 +vn 0.6437 0.6757 0.3594 +vn 0.4397 0.7270 0.5274 +vn 0.0919 0.9873 -0.1296 +vn -0.8116 -0.4975 -0.3063 +vn -0.8031 -0.2667 -0.5327 +vn -0.6536 -0.7279 -0.2072 +vn -0.6878 -0.6677 -0.2847 +vn -0.7941 -0.5019 -0.3429 +vn -0.7622 -0.3654 -0.5344 +vn 0.2196 -0.6071 -0.7637 +vn 0.1003 -0.7100 -0.6970 +vn 0.2794 -0.3991 -0.8733 +vn 0.3535 -0.3585 -0.8640 +vn 0.3479 -0.5121 -0.7854 +vn 0.2781 -0.6506 -0.7066 +vn 0.1981 0.0506 0.9789 +vn 0.1626 0.1621 0.9733 +vn 0.1730 0.0071 0.9849 +vn 0.2043 -0.0981 0.9740 +vn 0.1388 0.2861 0.9481 +vn 0.1589 0.1564 0.9748 +vn 0.1280 -0.3676 0.9211 +vn 0.1579 -0.5029 0.8498 +vn 0.2225 -0.4570 0.8612 +vn 0.0798 0.7847 0.6148 +vn 0.0995 0.7936 0.6002 +vn 0.0660 0.9077 0.4144 +vn 0.0598 0.8819 0.4677 +vn -0.0513 0.9680 -0.2457 +vn -0.0702 0.9944 -0.0794 +vn 0.0217 -0.9990 0.0380 +vn 0.0088 -0.9873 0.1586 +vn 0.0164 -0.9906 -0.1355 +vn 0.0817 -0.9879 0.1317 +vn 0.0567 -0.9591 0.2775 +vn -0.0002 -0.9613 0.2756 +vn 0.4051 0.8272 0.3894 +vn 0.3606 0.4249 0.8303 +vn 0.3943 0.2988 0.8691 +vn 0.4231 0.8180 0.3898 +vn 0.3606 0.4250 0.8303 +vn 0.3943 0.2987 0.8691 +vn 0.4869 0.2146 0.8467 +vn 0.5901 0.7577 0.2789 +vn 0.0932 0.6791 0.7281 +vn 0.0746 0.7042 0.7060 +vn 0.0892 0.7881 0.6091 +vn 0.1390 0.6787 0.7211 +vn 0.0798 0.7846 0.6148 +vn 0.0892 0.7880 0.6092 +vn -0.0786 0.9058 0.4164 +vn -0.0785 0.9058 0.4164 +vn -0.1682 0.7051 0.6889 +vn 0.0711 0.6590 0.7488 +vn 0.0068 0.6242 0.7812 +vn 0.0160 0.6846 0.7287 +vn 0.0614 0.6841 0.7268 +vn 0.0067 0.6242 0.7812 +vn 0.0791 0.6728 0.7356 +vn 0.1038 0.6958 0.7107 +vn 0.0745 0.7028 0.7075 +vn 0.0014 0.7119 0.7023 +vn 0.1709 0.2898 0.9417 +vn 0.1556 0.2340 0.9597 +vn 0.1248 0.5891 0.7984 +vn 0.1233 0.5899 0.7980 +vn 0.1230 0.5827 0.8033 +vn 0.1377 0.3206 0.9372 +vn 0.0705 0.8210 0.5666 +vn 0.0909 0.8280 0.5533 +vn 0.0978 0.7561 0.6471 +vn 0.1200 0.7273 0.6758 +vn 0.1445 0.6927 0.7066 +vn 0.1763 0.6972 0.6949 +vn 0.2729 0.6668 0.6935 +vn 0.1763 0.6971 0.6950 +vn 0.1978 0.6103 0.7671 +vn 0.2728 0.6668 0.6935 +vn 0.2238 0.6815 0.6968 +vn 0.3666 0.6740 0.6413 +vn 0.0976 0.4155 0.9043 +vn 0.0792 0.5337 0.8419 +vn 0.1106 0.6256 0.7723 +vn 0.2968 0.8615 0.4119 +vn 0.2506 0.4583 0.8527 +vn 0.1229 0.8926 0.4337 +vn 0.1206 0.7665 0.6308 +vn 0.2506 0.4585 0.8526 +vn 0.1206 0.7666 0.6307 +vn 0.0014 0.7120 0.7022 +vn 0.0450 0.8016 0.5962 +vn 0.0747 0.7041 0.7061 +vn 0.0745 0.7029 0.7074 +vn 0.0924 0.7369 0.6697 +vn 0.4088 0.6437 0.6469 +vn 0.3667 0.6740 0.6413 +vn 0.2443 0.8973 0.3676 +vn 0.3569 0.8884 0.2887 +vn 0.2238 0.6815 0.6967 +vn 0.1262 0.8362 0.5336 +vn 0.1200 0.7274 0.6757 +vn 0.1210 0.6932 0.7105 +vn 0.0924 0.7369 0.6696 +vn 0.1210 0.6931 0.7106 +vn 0.1233 0.5898 0.7981 +vn 0.1248 0.5892 0.7983 +vn 0.1979 0.6102 0.7672 +vn -0.2113 0.4778 -0.8527 +vn -0.1394 0.7526 -0.6436 +vn -0.1194 0.7222 -0.6813 +vn -0.1387 0.5183 -0.8439 +vn -0.1394 0.7525 -0.6436 +vn -0.0967 0.6904 -0.7169 +vn -0.0966 0.6904 -0.7170 +vn -0.0760 0.4266 -0.9012 +vn 0.8335 0.4465 0.3256 +vn 0.7509 0.5287 0.3958 +vn 0.3972 0.6652 0.6322 +vn 0.4450 0.6832 0.5790 +vn 0.7130 0.5044 0.4871 +vn 0.3569 0.6018 0.7144 +vn 0.3972 0.6652 0.6323 +vn 0.3144 0.6745 0.6680 +vn 0.3363 0.7428 0.5789 +vn 0.3707 0.7736 0.5138 +vn 0.1376 -0.7943 0.5918 +vn 0.1127 -0.7987 0.5911 +vn 0.0885 -0.8037 0.5884 +vn -0.7913 0.2010 0.5774 +vn -0.9094 0.0937 0.4052 +vn -0.4802 0.8054 -0.3475 +vn -0.3450 0.9386 0.0003 +vn -0.9636 -0.1418 0.2265 +vn -0.5859 0.4748 -0.6568 +vn -0.4919 0.5148 -0.7022 +vn -0.4213 0.8171 -0.3936 +vn -0.3203 0.9453 -0.0615 +vn -0.9636 -0.1418 0.2266 +vn -0.9278 -0.3696 -0.0516 +vn -0.5417 -0.2432 -0.8046 +vn -0.8264 -0.5092 -0.2403 +vn -0.3920 -0.6426 -0.6584 +vn -0.2657 -0.6445 -0.7170 +vn -0.4271 -0.1977 -0.8823 +vn -0.4919 0.5147 -0.7022 +vn 0.8286 -0.3457 -0.4403 +vn 0.9340 -0.1497 -0.3245 +vn 0.2295 0.6798 -0.6966 +vn 0.0765 0.3153 -0.9459 +vn 0.9932 -0.0281 -0.1134 +vn 0.3624 0.8760 -0.3184 +vn 0.2630 0.8769 -0.4024 +vn 0.1731 0.6971 -0.6957 +vn 0.1731 0.6972 -0.6957 +vn 0.0494 0.3772 -0.9248 +vn -0.8264 -0.5092 -0.2402 +vn -0.8270 -0.4744 -0.3018 +vn -0.3840 -0.6737 -0.6314 +vn -0.3921 -0.6426 -0.6583 +vn -0.8651 -0.3664 -0.3427 +vn -0.3988 -0.6636 -0.6329 +vn -0.3839 -0.6737 -0.6314 +vn -0.2546 -0.7089 -0.6577 +vn -0.2469 -0.6980 -0.6722 +vn 0.9587 0.2530 0.1300 +vn 0.4644 0.8395 0.2822 +vn 0.3691 0.9143 0.1670 +vn 0.1470 0.6836 0.7149 +vn 0.1247 0.6503 0.7494 +vn -0.1723 0.6334 0.7544 +vn -0.1381 0.5326 0.8350 +vn -0.2482 -0.9665 0.0661 +vn -0.3119 -0.9479 -0.0653 +vn -0.6878 -0.6677 -0.2848 +vn 0.3802 0.8851 0.2685 +vn 0.4137 0.6767 0.6090 +vn 0.5606 0.8258 0.0612 +vn 0.1335 0.4111 0.9018 +vn 0.0372 0.1461 0.9886 +vn 0.1605 0.1914 -0.9683 +vn -0.0852 0.5573 -0.8259 +vn 0.1264 -0.0269 -0.9916 +vn -0.4932 0.2637 -0.8290 +vn -0.1869 0.5054 -0.8424 +vn -0.4933 0.2636 -0.8290 +vn -0.8031 -0.2668 -0.5328 +vn -0.4875 0.0114 -0.8731 +vn 0.0521 -0.9021 -0.4283 +vn 0.1003 -0.7099 -0.6971 +vn 0.2782 -0.6506 -0.7067 +vn 0.1273 -0.9160 -0.3805 +vn -0.1391 0.5286 -0.8374 +vn 0.9278 -0.0220 -0.3724 +vn 0.9159 0.0517 -0.3981 +vn 0.8334 0.4465 0.3256 +vn 0.8903 -0.2441 -0.3845 +vn 0.9278 -0.0220 -0.3725 +vn 0.8903 -0.2441 -0.3844 +vn 0.9159 0.0516 -0.3980 +vn -0.3855 0.5310 0.7546 +vn -0.3577 0.5790 0.7326 +vn -0.9692 -0.0069 0.2463 +vn -0.9397 -0.1950 0.2810 +vn -0.3955 0.5967 0.6982 +vn -0.9967 0.0720 0.0383 +vn -0.7913 0.2012 0.5774 +vn -0.5891 0.3869 0.7094 +vn -0.7043 -0.6435 0.3000 +vn -0.2698 -0.8515 0.4496 +vn -0.7042 -0.6435 0.2999 +vn -0.9397 -0.1950 0.2809 +vn 0.9507 0.2139 0.2245 +vn 0.8007 0.3829 0.4606 +vn 0.7081 0.1431 -0.6914 +vn 0.2438 0.3750 -0.8944 +vn 0.7081 0.1431 -0.6915 +vn -0.5879 0.5418 0.6006 +vn -0.8553 0.2313 -0.4637 +vn -0.8087 0.4024 0.4291 +vn -0.4789 0.5293 -0.7004 +vn -0.4788 0.5293 -0.7004 +vn 0.9587 0.2531 0.1300 +vn 0.6732 -0.6917 -0.2614 +vn 0.9932 -0.0282 -0.1133 +vn 0.3999 -0.9025 0.1596 +vn 0.6733 -0.6917 -0.2613 +vn 0.4000 -0.9025 0.1597 +vn 0.8904 -0.2439 -0.3844 +vn 0.9932 -0.0281 -0.1133 +vn 0.3668 -0.7917 0.4885 +vn 0.8287 -0.3456 -0.4403 +vn 0.4909 -0.5483 0.6770 +vn -0.1413 -0.7508 0.6453 +vn -0.1675 -0.5085 0.8446 +vn -0.9094 0.0938 0.4052 +vn -0.7914 0.2012 0.5773 +vn -0.1413 -0.7508 0.6452 +vn 0.5267 -0.4278 -0.7346 +vn 0.6927 -0.2895 -0.6606 +vn 0.8870 0.4426 0.1318 +vn 0.9042 0.3192 -0.2837 +vn 0.9226 0.0497 -0.3824 +vn 0.4406 0.8746 -0.2024 +vn 0.8870 0.4427 0.1317 +vn 0.4407 0.8746 -0.2023 +vn 0.6437 0.6757 0.3593 +vn 0.5298 -0.5508 -0.6449 +vn 0.5211 -0.5435 -0.6580 +vn 0.8234 0.3813 -0.4203 +vn 0.9185 0.3414 -0.1996 +vn 0.5607 0.8258 0.0610 +vn 0.8234 0.3812 -0.4204 +vn -0.8086 0.4025 0.4291 +vn -0.9335 0.2005 0.2972 +vn -0.3582 0.7759 -0.5193 +vn -0.4789 0.5294 -0.7003 +vn -0.9974 0.0657 0.0305 +vn -0.3774 0.9105 -0.1691 +vn -0.3581 0.7759 -0.5193 +vn 0.9227 0.0497 -0.3824 +vn 0.9769 -0.0755 -0.2000 +vn 0.1791 0.6496 -0.7389 +vn 0.9769 -0.0754 -0.2000 +vn 0.9507 0.2140 0.2245 +vn 0.1790 0.6496 -0.7389 +vn 0.6993 -0.4712 -0.5374 +vn 0.8907 -0.0295 0.4537 +vn 0.4909 -0.5484 0.6770 +vn 0.5901 0.7577 0.2788 +vn 0.4870 0.2146 0.8466 +vn 0.4908 -0.5484 0.6770 +vn -0.8699 0.1946 0.4533 +vn -0.8496 0.3806 0.3652 +vn -0.7894 0.0964 0.6062 +vn -0.8495 0.3806 0.3653 +vn -0.9278 -0.3696 -0.0515 +vn -0.4882 -0.1024 0.8667 +vn -0.9636 -0.1419 0.2265 +vn -0.4883 -0.1025 0.8667 +vn -0.9974 0.0658 0.0305 +vn -0.9542 -0.1931 -0.2286 +vn -0.6347 0.7372 0.2318 +vn -0.3773 0.9105 -0.1691 +vn -0.6348 0.7371 0.2317 +vn -0.1682 0.7051 0.6888 +vn 0.1242 -0.9730 -0.1946 +vn -0.1015 -0.6585 -0.7457 +vn -0.0907 -0.7424 -0.6638 +vn 0.1288 -0.9713 -0.1999 +vn -0.0896 -0.8238 -0.5597 +vn -0.0636 -0.9018 -0.4274 +vn -0.0428 -0.9292 -0.3672 +vn -0.0727 -0.7902 -0.6085 +vn 0.1286 -0.9713 -0.2001 +vn 0.1045 -0.9567 -0.2717 +vn -0.2546 -0.7090 -0.6577 +vn -0.2587 -0.8827 -0.3923 +vn -0.2216 -0.9381 -0.2663 +vn -0.2238 -0.7622 -0.6074 +vn -0.2095 -0.9454 0.2497 +vn -0.1661 -0.9184 0.3590 +vn -0.1484 -0.8935 0.4238 +vn -0.2020 -0.9730 -0.1112 +vn -0.2123 -0.8074 -0.5505 +vn 0.2786 0.8997 0.3361 +vn 0.2532 0.9668 0.0348 +vn 0.2941 0.7856 0.5444 +vn 0.2657 0.8506 0.4537 +vn 0.2082 0.9692 0.1314 +vn 0.0480 0.8816 -0.4695 +vn -0.4319 -0.1175 -0.8942 +vn -0.4783 0.5817 -0.6579 +vn -0.2441 -0.6562 -0.7140 +vn -0.2495 -0.6391 -0.7275 +vn -0.4574 0.0245 -0.8889 +vn -0.4713 0.6184 -0.6289 +vn 0.1744 0.6782 -0.7139 +vn 0.1078 0.5122 -0.8521 +vn 0.1706 0.7473 -0.6422 +vn 0.1743 0.6782 -0.7139 +vn 0.1705 0.7474 -0.6422 +vn 0.1025 0.6281 -0.7714 +vn 0.1696 0.6644 -0.7278 +vn 0.1441 0.6103 -0.7789 +vn -0.4193 -0.8112 -0.4075 +vn -0.3988 -0.6637 -0.6328 +vn -0.9974 0.0658 0.0304 +vn -0.3684 -0.8995 0.2350 +vn -0.4193 -0.8113 -0.4075 +vn 0.9227 0.0496 -0.3824 +vn 0.6927 -0.2895 -0.6605 +vn 0.0622 -0.5913 -0.8041 +vn 0.2914 -0.9427 -0.1625 +vn 0.5266 -0.4278 -0.7346 +vn 0.0320 -0.7406 -0.6712 +vn -0.3954 0.5968 0.6982 +vn -0.3578 0.5790 0.7326 +vn 0.0554 0.6838 0.7276 +vn 0.0638 0.6559 0.7522 +vn 0.0403 0.6924 0.7204 +vn 0.0228 0.7020 0.7118 +vn 0.0355 0.6932 0.7198 +vn 0.0442 0.6624 0.7479 +vn 0.5266 -0.4279 -0.7346 +vn 0.0142 -0.9126 -0.4086 +vn 0.0319 -0.7406 -0.6712 +vn 0.5299 -0.5508 -0.6449 +vn -0.0771 -0.9098 -0.4077 +vn -0.1378 -0.9563 -0.2578 +vn -0.0722 -0.9662 -0.2476 +vn -0.0896 -0.8238 -0.5598 +vn -0.1040 0.8620 0.4962 +vn -0.5891 0.3868 0.7095 +vn -0.1040 0.8620 0.4961 +vn -0.1120 0.8810 0.4596 +vn 0.0403 0.6924 0.7203 +vn 0.0228 0.7021 0.7117 +vn -0.9335 0.2004 0.2972 +vn -0.2425 -0.6538 0.7168 +vn -0.1155 -0.2236 0.9678 +vn -0.2425 -0.6537 0.7169 +vn -0.0587 -0.2974 0.9529 +vn -0.1331 -0.7043 0.6973 +vn -0.1332 -0.7043 0.6973 +vn 0.8008 0.3829 0.4606 +vn 0.3293 0.3971 0.8567 +vn 0.9507 0.2140 0.2244 +vn 0.3014 -0.0570 0.9518 +vn 0.3344 0.0395 0.9416 +vn 0.3139 0.4934 0.8112 +vn 0.3144 0.6744 0.6681 +vn 0.9769 -0.0755 -0.2001 +vn 0.2899 -0.6135 0.7346 +vn 0.9769 -0.0756 -0.2000 +vn 0.9226 0.0496 -0.3825 +vn 0.2915 -0.9427 -0.1625 +vn 0.2899 -0.6135 0.7345 +vn 0.1243 -0.9730 -0.1945 +vn 0.3141 -0.6122 0.7256 +vn 0.3141 -0.6123 0.7256 +vn -0.5879 0.5419 0.6007 +vn 0.0217 0.3750 0.9268 +vn 0.0245 0.3415 0.9395 +vn 0.6993 -0.4712 -0.5375 +vn -0.0952 -0.4876 -0.8679 +vn 0.6993 -0.4713 -0.5375 +vn -0.1457 -0.5023 -0.8523 +vn -0.1457 -0.5023 -0.8524 +vn 0.0441 0.6624 0.7479 +vn -0.0164 0.7312 0.6820 +vn -0.0027 0.6858 0.7278 +vn -0.0351 0.7383 0.6735 +vn -0.0351 0.7384 0.6735 +vn -0.0673 0.7776 0.6251 +vn -0.0387 0.7615 0.6470 +vn -0.0449 0.3239 0.9450 +vn -0.0397 -0.9974 -0.0600 +vn -0.1050 -0.9942 0.0234 +vn -0.0662 -0.9746 0.2140 +vn -0.0094 -0.9997 0.0220 +vn -0.1794 0.9074 0.3800 +vn -0.3566 0.9231 -0.1443 +vn -0.3807 0.8965 -0.2267 +vn -0.2495 0.9455 0.2091 +vn -0.1178 -0.7113 0.6929 +vn -0.0728 -0.4010 0.9132 +vn -0.0859 -0.5130 0.8541 +vn -0.1153 -0.7178 0.6866 +vn -0.1153 -0.7180 0.6865 +vn 0.3093 0.6248 0.7169 +vn 0.3655 0.1978 0.9096 +vn 0.3093 0.6249 0.7169 +vn 0.3545 0.3265 0.8762 +vn 0.2882 0.7051 0.6480 +vn 0.2882 0.7051 0.6479 +vn 0.3759 -0.5770 0.7251 +vn 0.3954 -0.5598 0.7282 +vn 0.3953 -0.5599 0.7281 +vn -0.0989 -0.5307 -0.8418 +vn -0.0989 -0.5308 -0.8417 +vn -0.0423 -0.5830 -0.8114 +vn -0.0424 -0.5829 -0.8114 +vn 0.1952 0.8912 -0.4094 +vn 0.1952 0.8912 -0.4095 +vn 0.2532 0.9668 0.0345 +vn 0.0480 0.8815 -0.4697 +vn -0.0089 0.6180 -0.7861 +vn -0.2131 -0.7401 -0.6378 +vn -0.2441 -0.6561 -0.7141 +vn -0.1964 -0.7740 -0.6020 +vn -0.2500 -0.6390 -0.7274 +vn -0.8358 -0.2179 -0.5040 +vn -0.5692 -0.1758 -0.8032 +vn -0.4530 -0.5401 -0.7093 +vn -0.6925 -0.5796 -0.4295 +vn -0.0352 -0.1341 -0.9903 +vn -0.0142 -0.1764 -0.9842 +vn -0.1913 -0.6181 -0.7625 +vn -0.1913 -0.6182 -0.7624 +vn -0.3757 -0.8852 -0.2743 +vn -0.0551 -0.0233 0.9982 +vn -0.4301 -0.1356 0.8926 +vn -0.4038 -0.4349 0.8049 +vn -0.0674 -0.0716 0.9952 +vn -0.9213 -0.2427 0.3038 +vn -0.7544 -0.6083 0.2467 +vn -0.4038 -0.4349 0.8048 +vn -0.3979 -0.9059 0.1450 +vn -0.2434 -0.6416 0.7274 +vn -0.2434 -0.6417 0.7273 +vn -0.0626 -0.1540 0.9861 +vn 0.0160 -0.0837 -0.9964 +vn 0.0562 -0.1280 -0.9902 +vn 0.0277 -0.1756 -0.9841 +vn 0.0049 -0.1797 -0.9837 +vn -0.0582 -0.6957 -0.7159 +vn 0.1164 -0.6422 -0.7577 +vn -0.0582 -0.6956 -0.7161 +vn 0.1163 -0.6422 -0.7577 +vn 0.2548 -0.9364 -0.2412 +vn -0.1036 -0.9779 -0.1818 +vn -0.1127 -0.9861 0.1220 +vn -0.1009 -0.7076 0.6994 +vn 0.2394 -0.9392 0.2463 +vn 0.0735 -0.6433 0.7620 +vn -0.1009 -0.7075 0.6995 +vn 0.0735 -0.6434 0.7620 +vn -0.0195 -0.1432 0.9895 +vn -0.0433 -0.1523 0.9874 +vn -0.1111 -0.9934 -0.0302 +vn 0.2238 -0.9746 -0.0047 +vn -0.3728 -0.9255 -0.0668 +vn 0.9018 -0.2629 -0.3429 +vn 0.9546 -0.2778 0.1077 +vn 0.7293 -0.6819 0.0553 +vn 0.7189 -0.6211 -0.3121 +vn 0.8372 -0.2423 0.4902 +vn 0.6756 -0.6138 0.4084 +vn 0.7293 -0.6820 0.0553 +vn 0.6756 -0.6138 0.4085 +vn 0.0080 -0.0114 0.9999 +vn -0.0230 -0.0114 0.9997 +vn -0.0277 -0.0340 0.9990 +vn 0.0067 -0.0527 0.9986 +vn 0.6455 -0.2069 -0.7352 +vn 0.9019 -0.2628 -0.3429 +vn 0.4499 -0.5380 -0.7129 +vn 0.4499 -0.5379 -0.7129 +vn 0.8372 -0.2423 0.4903 +vn 0.3276 -0.1020 0.9393 +vn 0.2983 -0.3886 0.8718 +vn 0.6755 -0.6138 0.4085 +vn 0.2982 -0.3884 0.8719 +vn -0.9553 -0.2564 -0.1469 +vn -0.7459 -0.6546 -0.1232 +vn -0.8357 -0.2178 -0.5041 +vn -0.7459 -0.6546 -0.1233 +vn -0.0194 -0.0117 0.9997 +vn -0.0490 -0.0165 0.9987 +vn 0.0101 -0.0102 0.9999 +vn 0.0115 -0.0237 0.9997 +vn -0.0179 -0.0236 0.9996 +vn -0.0465 -0.0244 0.9986 +vn 0.6609 -0.0756 -0.7466 +vn 0.9322 -0.1057 -0.3462 +vn 0.6633 0.0023 -0.7484 +vn 0.9389 -0.0130 -0.3440 +vn 0.3198 -0.0440 0.9465 +vn 0.8524 -0.1020 0.5128 +vn 0.8515 -0.0318 0.5234 +vn 0.3151 -0.0291 0.9486 +vn -0.9880 -0.0538 -0.1450 +vn -0.8494 -0.0404 -0.5261 +vn -0.9416 -0.0584 0.3315 +vn -0.9397 -0.0127 0.3417 +vn -0.9897 -0.0010 -0.1431 +vn -0.8476 0.0091 -0.5306 +vn -0.9213 -0.2428 0.3038 +vn -0.4006 -0.0373 0.9155 +vn -0.9416 -0.0584 0.3316 +vn -0.3882 -0.0242 0.9212 +vn -0.8495 -0.0404 -0.5261 +vn -0.5645 -0.0234 -0.8251 +vn -0.8476 0.0091 -0.5305 +vn -0.5611 0.0177 -0.8275 +vn 0.9849 -0.1145 0.1300 +vn 0.9388 -0.0130 -0.3441 +vn 0.9897 -0.0256 0.1406 +vn 0.8515 -0.0318 0.5233 +vn 0.6663 0.0408 -0.7445 +vn 0.9397 0.0329 -0.3404 +vn 0.6736 0.0521 -0.7372 +vn 0.9408 0.0444 -0.3360 +vn 0.3113 -0.0258 0.9500 +vn 0.0106 -0.0338 0.9994 +vn 0.8488 0.0007 0.5288 +vn 0.8495 0.0059 0.5275 +vn 0.3129 -0.0292 0.9493 +vn 0.0103 -0.0412 0.9991 +vn -0.9899 0.0101 -0.1415 +vn -0.8493 0.0214 -0.5274 +vn -0.9400 -0.0058 0.3413 +vn -0.9418 0.0076 0.3360 +vn -0.9901 0.0296 -0.1374 +vn -0.8552 0.0420 -0.5166 +vn -0.3894 -0.0275 0.9207 +vn -0.9399 -0.0058 0.3414 +vn -0.0472 -0.0324 0.9984 +vn -0.0486 -0.0420 0.9979 +vn -0.3967 -0.0304 0.9174 +vn -0.5651 0.0293 -0.8245 +vn -0.8552 0.0420 -0.5167 +vn -0.5801 0.0483 -0.8131 +vn 0.9893 0.0174 0.1445 +vn 0.9408 0.0445 -0.3360 +vn 0.9890 0.0265 0.1453 +vn 0.8496 0.0059 0.5274 +vn -0.0183 -0.0334 0.9993 +vn -0.0193 -0.0420 0.9989 +vn 0.8610 -0.0369 0.5072 +vn 0.9895 0.0124 0.1437 +vn 0.9890 0.0363 0.1431 +vn 0.8680 -0.0507 0.4939 +vn 0.9412 0.0700 -0.3306 +vn 0.9383 0.1376 -0.3173 +vn 0.9223 0.2640 -0.2823 +vn 0.9824 0.1119 0.1494 +vn 0.8730 -0.0332 0.4865 +vn -0.0458 -0.1301 0.9904 +vn -0.0147 -0.1295 0.9915 +vn -0.0168 -0.2187 0.9757 +vn -0.0479 -0.2141 0.9756 +vn 0.0160 -0.1262 0.9919 +vn 0.0149 -0.2207 0.9752 +vn 0.0145 -0.3643 0.9312 +vn -0.0172 -0.3708 0.9286 +vn -0.0473 -0.3769 0.9251 +vn 0.9411 0.0701 -0.3307 +vn 0.5142 0.1358 -0.8468 +vn 0.4132 0.2277 -0.8817 +vn 0.0512 0.1645 -0.9850 +vn 0.0556 0.2228 -0.9733 +vn 0.0610 0.3611 -0.9305 +vn 0.4148 0.3816 -0.8260 +vn 0.4148 0.3815 -0.8261 +vn 0.3311 -0.1084 0.9373 +vn 0.3406 -0.1874 0.9213 +vn 0.8611 -0.0369 0.5072 +vn 0.8680 -0.0507 0.4940 +vn 0.8730 -0.0332 0.4866 +vn 0.3504 -0.2876 0.8914 +vn -0.8732 0.1185 -0.4727 +vn -0.9894 0.0813 -0.1199 +vn -0.9916 0.0662 -0.1107 +vn -0.8847 0.1325 -0.4469 +vn -0.9463 0.0194 0.3228 +vn -0.9487 -0.0263 0.3152 +vn -0.9445 -0.1954 0.2640 +vn -0.9919 -0.0448 -0.1192 +vn -0.8889 0.0963 -0.4480 +vn 0.0182 0.1631 -0.9864 +vn 0.0218 0.2167 -0.9760 +vn -0.0188 0.1654 -0.9860 +vn -0.0165 0.2133 -0.9768 +vn -0.0167 0.3541 -0.9351 +vn 0.0243 0.3551 -0.9345 +vn -0.4069 -0.0965 0.9084 +vn -0.4101 -0.1792 0.8943 +vn -0.9487 -0.0266 0.3151 +vn -0.3959 -0.3816 0.8353 +vn -0.4102 -0.1792 0.8942 +vn -0.3960 -0.3816 0.8352 +vn -0.4650 0.1570 -0.8713 +vn -0.3728 0.2091 -0.9040 +vn -0.8847 0.1326 -0.4469 +vn -0.8889 0.0963 -0.4479 +vn -0.3734 0.3045 -0.8763 +vn -0.2470 -0.8096 0.5325 +vn -0.7626 -0.6468 -0.0079 +vn 0.0046 -0.6669 0.7451 +vn -0.2470 -0.8095 0.5326 +vn -0.2470 -0.8096 0.5326 +vn 0.1310 -0.9204 0.3684 +vn 0.0372 -0.9983 -0.0453 +vn -0.1966 -0.8965 -0.3971 +vn -0.3823 0.4282 -0.8188 +vn -0.0453 0.5277 -0.8482 +vn -0.8481 -0.0525 -0.5273 +vn -0.5609 -0.4322 -0.7061 +vn -0.3750 0.3378 -0.8633 +vn -0.3749 0.3378 -0.8633 +vn -0.0704 0.5528 -0.8303 +vn 0.9716 0.1737 0.1606 +vn 0.8724 -0.0398 0.4871 +vn 0.9013 0.3668 -0.2304 +vn 0.9156 0.3135 -0.2518 +vn 0.9885 0.1058 0.1084 +vn 0.9010 -0.1442 0.4092 +vn 0.0161 -0.5840 0.8116 +vn 0.0389 -0.5282 0.8482 +vn 0.1087 -0.6863 0.7191 +vn 0.1084 -0.7978 0.5931 +vn 0.4045 0.5128 -0.7572 +vn 0.0529 0.4821 -0.8745 +vn 0.4044 0.5128 -0.7573 +vn 0.0540 0.4819 -0.8746 +vn 0.4169 0.5011 -0.7583 +vn 0.4170 0.5011 -0.7583 +vn 0.3670 -0.3990 0.8403 +vn 0.9009 -0.1443 0.4093 +vn 0.4193 -0.5278 0.7387 +vn -0.8920 -0.3726 -0.2558 +vn -0.1967 -0.8965 -0.3970 +vn -0.4580 -0.7242 -0.5156 +vn 0.0074 0.4940 -0.8694 +vn -0.0034 0.4997 -0.8662 +vn -0.3934 0.8098 0.4354 +vn -0.3774 0.8922 0.2480 +vn -0.5324 0.6758 0.5097 +vn -0.5284 0.5860 0.6143 +vn -0.3543 0.8836 -0.3061 +vn -0.6600 0.6475 0.3810 +vn -0.5324 0.6759 0.5096 +vn -0.6600 0.6474 0.3811 +vn -0.8318 0.5069 0.2261 +vn -0.6261 0.6203 0.4725 +vn -0.5284 0.5859 0.6144 +vn -0.6158 0.5985 0.5124 +vn 0.9019 -0.0254 -0.4312 +vn 0.9752 -0.1808 -0.1280 +vn 0.8820 -0.1786 -0.4360 +vn 0.9417 -0.2636 -0.2093 +vn 0.8883 -0.4441 -0.1172 +vn 0.9080 -0.4149 0.0591 +vn 0.1388 -0.8054 -0.5762 +vn 0.0116 -0.7613 -0.6484 +vn -0.4579 -0.7242 -0.5156 +vn -0.0454 -0.8044 -0.5924 +vn -0.1367 -0.7124 -0.6884 +vn 0.0115 -0.7612 -0.6484 +vn -0.1367 -0.7123 -0.6884 +vn -0.1900 -0.5909 -0.7841 +vn -0.1002 -0.6188 -0.7792 +vn -0.1002 -0.6187 -0.7792 +vn -0.2305 0.1456 0.9621 +vn -0.1992 0.0022 0.9800 +vn -0.1978 0.1309 0.9715 +vn -0.2269 0.2799 0.9328 +vn -0.1235 -0.3541 0.9270 +vn -0.0461 -0.3702 0.9278 +vn -0.0578 -0.2112 0.9757 +vn -0.2295 0.2963 0.9271 +vn -0.2401 0.4202 0.8751 +vn -0.3006 0.8177 0.4909 +vn -0.3062 0.8925 0.3313 +vn -0.3158 0.9127 0.2593 +vn -0.3218 0.8269 0.4611 +vn -0.1939 0.9511 -0.2405 +vn -0.2003 0.8911 -0.4073 +vn 0.2045 -0.8415 0.5000 +vn 0.2015 -0.9103 0.3615 +vn 0.2420 -0.8412 0.4836 +vn 0.1844 -0.8681 0.4608 +vn 0.1768 -0.9391 0.2946 +vn 0.2277 -0.9690 0.0957 +vn -0.6465 0.7267 0.2323 +vn -0.6618 0.7125 0.2332 +vn -0.5068 0.3082 0.8051 +vn -0.5038 0.4225 0.7534 +vn -0.7975 0.5891 0.1302 +vn -0.5782 0.2008 0.7908 +vn -0.5783 0.2008 0.7907 +vn -0.3120 0.7324 0.6052 +vn -0.3676 0.7139 0.5960 +vn -0.3274 0.8114 0.4842 +vn -0.2868 0.7497 0.5964 +vn -0.0752 0.8240 0.5617 +vn -0.1832 0.9468 0.2646 +vn -0.2861 0.7340 0.6159 +vn -0.2836 0.7499 0.5977 +vn -0.2161 0.7670 0.6042 +vn -0.1959 0.7260 0.6592 +vn -0.2106 0.7899 0.5759 +vn -0.2728 0.7671 0.5807 +vn -0.3004 0.7527 0.5858 +vn -0.2701 0.7417 0.6139 +vn -0.2372 0.3459 0.9078 +vn -0.2667 0.3836 0.8842 +vn -0.2421 0.4348 0.8674 +vn -0.2923 0.6553 0.6965 +vn -0.2945 0.6609 0.6903 +vn -0.2960 0.6591 0.6913 +vn -0.3208 0.8564 0.4045 +vn -0.2982 0.8552 0.4240 +vn -0.3780 0.7384 0.5585 +vn -0.3429 0.7416 0.5765 +vn -0.3259 0.7751 0.5413 +vn -0.3101 0.8027 0.5093 +vn -0.4751 0.6773 0.5618 +vn -0.5696 0.6419 0.5133 +vn -0.4751 0.6771 0.5619 +vn -0.4222 0.7040 0.5710 +vn -0.3776 0.6598 0.6497 +vn -0.3780 0.7384 0.5584 +vn -0.3429 0.7416 0.5766 +vn -0.2533 0.6498 0.7167 +vn -0.2279 0.5366 0.8124 +vn -0.2861 0.7340 0.6160 +vn -0.2280 0.5367 0.8124 +vn -0.2904 0.6952 0.6575 +vn -0.6465 0.7266 0.2323 +vn -0.5038 0.4226 0.7534 +vn -0.3999 0.5004 0.7679 +vn -0.5434 0.7996 0.2558 +vn -0.3367 0.7981 0.4996 +vn -0.3367 0.7981 0.4997 +vn -0.3711 0.8838 0.2849 +vn -0.2684 0.8450 0.4625 +vn -0.2996 0.7885 0.5372 +vn -0.6122 0.7812 0.1217 +vn -0.5003 0.8406 0.2077 +vn -0.5695 0.6420 0.5133 +vn -0.3605 0.8478 0.3890 +vn -0.4223 0.7040 0.5710 +vn -0.3185 0.7459 0.5850 +vn -0.3777 0.6598 0.6496 +vn -0.2960 0.6589 0.6915 +vn -0.2946 0.6608 0.6903 +vn -0.2923 0.6553 0.6966 +vn 0.1059 0.3703 -0.9229 +vn 0.0222 0.3790 -0.9251 +vn -0.0562 0.5993 -0.7986 +vn -0.0434 0.6422 -0.7653 +vn -0.0134 0.2547 -0.9669 +vn -0.0717 0.5547 -0.8290 +vn -0.3543 0.8837 -0.3060 +vn -0.0561 0.5993 -0.7986 +vn -0.9458 0.2321 0.2271 +vn -0.6454 0.6175 0.4497 +vn -0.5784 0.6304 0.5177 +vn -0.8939 0.3458 0.2853 +vn -0.6454 0.6175 0.4496 +vn -0.5792 0.7229 0.3767 +vn -0.4949 0.7297 0.4719 +vn -0.4134 0.6969 0.5861 +vn -0.5049 0.6015 0.6191 +vn -0.5048 0.6015 0.6192 +vn -0.8527 0.3519 0.3861 +vn 0.0850 -0.6862 0.7224 +vn 0.0570 -0.6904 0.7212 +vn 0.1119 -0.6829 0.7219 +vn 0.1119 -0.6828 0.7220 +vn 0.6531 0.5503 0.5202 +vn 0.0443 0.9832 -0.1770 +vn 0.2455 0.8396 -0.4846 +vn 0.8158 0.4434 0.3713 +vn 0.0096 0.9676 -0.2523 +vn 0.1800 0.8235 -0.5380 +vn 0.3680 0.5173 -0.7726 +vn 0.4716 0.5092 -0.7199 +vn 0.9500 0.2021 0.2382 +vn 0.9500 0.2020 0.2381 +vn 0.4716 0.5092 -0.7200 +vn 0.6572 -0.1992 -0.7269 +vn 0.9967 -0.0794 0.0176 +vn 0.5493 -0.1960 -0.8123 +vn 0.5232 -0.6358 -0.5675 +vn 0.6232 -0.5894 -0.5140 +vn 0.9967 -0.0793 0.0177 +vn 0.9526 -0.2748 -0.1304 +vn -0.6730 -0.6297 -0.3881 +vn -0.2087 0.0258 -0.9776 +vn -0.4585 0.3663 -0.8097 +vn -0.8289 -0.4675 -0.3072 +vn -0.3102 -0.0079 -0.9506 +vn -0.5071 0.3046 -0.8062 +vn -0.6243 0.5394 -0.5650 +vn -0.6392 0.5948 -0.4876 +vn -0.9334 -0.3311 -0.1380 +vn 0.6240 -0.6132 -0.4844 +vn 0.9483 -0.2501 -0.1952 +vn 0.5203 -0.6800 -0.5166 +vn 0.6239 -0.6132 -0.4845 +vn 0.5318 -0.6796 -0.5053 +vn 0.6357 -0.5959 -0.4907 +vn 0.6358 -0.5959 -0.4906 +vn 0.9559 -0.1457 -0.2551 +vn -0.6391 0.5948 -0.4875 +vn -0.7231 0.6825 0.1065 +vn -0.9984 -0.0113 0.0555 +vn -0.6392 0.5947 -0.4875 +vn -0.6244 0.5393 -0.5651 +vn -0.6827 0.7303 -0.0241 +vn -0.7231 0.6825 0.1064 +vn -0.3480 0.7081 0.6145 +vn -0.3807 0.7191 0.5813 +vn -0.0650 0.6849 0.7257 +vn -0.0636 0.7708 0.6339 +vn 0.5097 -0.7472 0.4265 +vn 0.4192 -0.5278 0.7387 +vn 0.5858 -0.7958 0.1534 +vn 0.5858 -0.7958 0.1535 +vn 0.2046 -0.8415 0.5000 +vn -0.6261 0.6203 0.4726 +vn -0.6317 0.7683 0.1033 +vn -0.8318 0.5070 0.2261 +vn -0.7740 0.6262 -0.0937 +vn -0.7974 0.5892 0.1302 +vn -0.2838 0.5279 0.8004 +vn -0.1154 0.3078 0.9444 +vn -0.1154 0.3079 0.9444 +vn -0.5609 -0.4323 -0.7061 +vn -0.1546 -0.0829 -0.9845 +vn -0.0774 -0.2489 -0.9654 +vn -0.0322 0.3757 -0.9262 +vn 0.0881 0.3446 -0.9346 +vn 0.4491 0.2442 -0.8595 +vn 0.5157 0.0285 -0.8563 +vn 0.4491 0.2442 -0.8594 +vn 0.2041 -0.9361 -0.2866 +vn 0.1368 -0.9629 -0.2325 +vn 0.0313 0.3589 -0.9329 +vn -0.8693 -0.2828 -0.4054 +vn -0.8572 -0.3508 -0.3771 +vn -0.8572 -0.3508 -0.3770 +vn -0.7634 -0.5432 -0.3495 +vn -0.7632 -0.5434 -0.3496 +vn 0.1561 0.7396 0.6546 +vn 0.9350 0.1406 0.3257 +vn 0.9133 0.3147 0.2585 +vn 0.1196 0.7709 0.6256 +vn 0.9350 0.1407 0.3256 +vn 0.9299 0.3649 0.0459 +vn 0.9299 0.3649 0.0460 +vn 0.1506 0.7914 0.5925 +vn 0.6531 0.5502 0.5203 +vn 0.4893 -0.6295 0.6036 +vn 0.8429 -0.3324 0.4230 +vn 0.3916 0.6734 0.6270 +vn 0.4894 -0.6295 0.6036 +vn 0.8430 -0.3323 0.4231 +vn 0.8430 -0.3323 0.4230 +vn 0.3917 0.6734 0.6270 +vn 0.8430 -0.3324 0.4229 +vn 0.9350 0.1406 0.3256 +vn 0.1564 0.7396 0.6546 +vn -0.9729 -0.0507 0.2256 +vn -0.3413 0.1178 -0.9326 +vn -0.7051 -0.1907 -0.6830 +vn -0.8910 0.2055 0.4048 +vn -0.3412 0.1178 -0.9326 +vn -0.7049 -0.1908 -0.6832 +vn 0.7883 0.3988 -0.4686 +vn 0.3578 0.7710 0.5268 +vn 0.7882 0.3987 -0.4687 +vn 0.7883 0.3988 -0.4687 +vn 0.3640 0.5310 -0.7652 +vn 0.3641 0.5311 -0.7651 +vn 0.6302 0.6680 0.3956 +vn -0.4572 -0.8758 -0.1545 +vn -0.4573 -0.8757 -0.1546 +vn -0.1724 -0.9392 0.2970 +vn -0.9984 -0.0114 0.0553 +vn -0.9334 -0.3312 -0.1380 +vn -0.1807 -0.7781 0.6015 +vn -0.8289 -0.4676 -0.3070 +vn -0.1808 -0.7782 0.6015 +vn -0.3719 -0.5572 0.7425 +vn -0.3719 -0.5571 0.7425 +vn -0.6730 -0.6297 -0.3880 +vn 0.9500 0.2021 0.2381 +vn 0.2844 -0.2731 0.9190 +vn 0.3324 -0.5397 0.7734 +vn 0.8158 0.4433 0.3713 +vn 0.3325 -0.5397 0.7734 +vn -0.3794 -0.6545 -0.6540 +vn -0.9364 -0.0119 -0.3506 +vn -0.9854 0.1669 0.0339 +vn -0.5751 -0.5740 -0.5828 +vn -0.6600 0.6474 0.3810 +vn -0.9854 0.1670 0.0340 +vn -0.6743 0.6456 -0.3585 +vn -0.6744 0.6456 -0.3584 +vn -0.8807 -0.2962 -0.3696 +vn -0.3273 -0.7677 -0.5509 +vn -0.9608 0.0195 -0.2766 +vn -0.8683 0.0519 -0.4934 +vn -0.3325 -0.7522 -0.5689 +vn -0.7740 0.6263 -0.0935 +vn 0.1755 0.7551 -0.6317 +vn 0.8210 0.4947 0.2852 +vn 0.1755 0.7550 -0.6318 +vn 0.1462 0.9387 -0.3123 +vn 0.9380 0.3436 0.0470 +vn -0.3534 0.4174 -0.8372 +vn -0.9005 -0.4056 -0.1567 +vn -0.6743 0.6456 -0.3584 +vn -0.9729 -0.0507 0.2255 +vn -0.8794 -0.2185 0.4231 +vn -0.5120 -0.7216 -0.4661 +vn -0.8794 -0.2185 0.4229 +vn 0.6876 0.6588 0.3052 +vn 0.7477 0.5099 0.4254 +vn 0.6876 0.6589 0.3052 +vn 0.6945 0.4187 0.5851 +vn 0.6945 0.4188 0.5851 +vn 0.4647 0.1969 0.8633 +vn 0.6945 0.4188 0.5850 +vn -0.0649 0.6850 0.7257 +vn 0.4648 0.1969 0.8633 +vn 0.2844 -0.2732 0.9190 +vn 0.4098 0.9051 0.1130 +vn 0.9845 0.0523 -0.1673 +vn 0.9845 0.0525 -0.1673 +vn 0.4101 0.9050 0.1129 +vn -0.1246 -0.9916 -0.0357 +vn -0.2622 -0.9636 -0.0520 +vn -0.1139 -0.8340 -0.5399 +vn -0.0087 -0.7750 -0.6319 +vn -0.3051 -0.9496 -0.0715 +vn -0.1482 -0.8615 -0.4857 +vn -0.0649 -0.9336 -0.3523 +vn -0.0211 -0.9229 -0.3844 +vn 0.0705 -0.8593 -0.5067 +vn 0.5243 -0.7336 -0.4324 +vn 0.5583 -0.8275 -0.0601 +vn 0.5773 -0.7886 -0.2118 +vn 0.5256 -0.7734 -0.3544 +vn 0.5358 -0.8347 0.1270 +vn 0.4122 -0.6711 0.6162 +vn 0.4481 -0.7095 0.5439 +vn 0.5044 -0.7491 0.4294 +vn -0.5551 0.8157 -0.1629 +vn -0.4687 0.8606 0.1993 +vn -0.3654 0.6673 -0.6490 +vn -0.4206 0.9072 -0.0098 +vn -0.3637 0.8632 0.3503 +vn -0.3841 0.8034 0.4549 +vn 0.0589 0.9394 -0.3376 +vn 0.1808 0.8204 -0.5424 +vn 0.0973 0.9076 -0.4085 +vn 0.1840 0.8166 -0.5471 +vn 0.2979 0.6360 -0.7119 +vn 0.3243 0.5907 -0.7388 +vn 0.3243 0.5907 -0.7389 +vn 0.5318 -0.1136 -0.8392 +vn 0.2979 0.6361 -0.7118 +vn 0.5039 0.0565 -0.8619 +vn 0.5144 -0.6403 -0.5704 +vn 0.5120 -0.6555 -0.5552 +vn -0.4625 0.0299 -0.8861 +vn -0.5663 0.2112 -0.7967 +vn -0.5449 0.1210 -0.8297 +vn -0.5728 0.1753 -0.8008 +vn -0.5050 0.1902 -0.8419 +vn -0.5786 0.3324 -0.7448 +vn 0.6871 -0.6844 -0.2438 +vn 0.6871 -0.6845 -0.2438 +vn 0.6231 -0.6733 0.3980 +vn 0.9380 0.3435 0.0470 +vn -0.8807 -0.2961 -0.3696 +vn -0.1404 -0.9901 -0.0089 +vn -0.0241 -0.7301 -0.6829 +vn -0.5752 -0.5740 -0.5827 +vn -0.0241 -0.7300 -0.6830 +vn -0.0087 -0.7750 -0.6320 +vn 0.0705 -0.8592 -0.5067 +vn 0.0660 -0.8142 -0.5768 +vn -0.5752 -0.5740 -0.5828 +vn -0.3795 -0.6545 -0.6540 +vn -0.3356 0.7094 0.6198 +vn -0.3350 0.7381 0.5856 +vn -0.3457 0.7126 0.6106 +vn -0.3452 0.7469 0.5682 +vn -0.3325 0.7628 0.5547 +vn -0.3212 0.7526 0.5748 +vn -0.3795 -0.6545 -0.6539 +vn 0.1704 -0.9374 -0.3037 +vn 0.1895 -0.9639 -0.1872 +vn 0.2993 -0.9411 -0.1576 +vn 0.2831 -0.9161 -0.2838 +vn -0.2114 0.9229 0.3217 +vn 0.3915 0.6735 0.6270 +vn -0.2291 0.9361 0.2667 +vn 0.6231 -0.6733 0.3979 +vn 0.3912 -0.4106 0.8236 +vn 0.8210 0.4946 0.2852 +vn 0.5044 -0.7491 0.4295 +vn 0.3162 -0.4821 0.8171 +vn 0.0849 -0.1113 0.9902 +vn 0.1135 -0.0230 0.9933 +vn 0.6303 0.6680 0.3956 +vn -0.4095 0.4415 0.7984 +vn -0.8911 0.2054 0.4046 +vn -0.4135 0.6969 0.5860 +vn -0.3340 0.5564 0.7608 +vn -0.2672 0.1199 0.9562 +vn -0.2653 0.0235 0.9639 +vn -0.9729 -0.0508 0.2255 +vn -0.1534 -0.5564 0.8166 +vn -0.9006 -0.4055 -0.1567 +vn -0.2168 -0.5631 0.7975 +vn -0.1535 -0.5564 0.8166 +vn -0.2131 0.4825 0.8496 +vn 0.3579 0.7710 0.5268 +vn -0.2233 0.4418 0.8689 +vn 0.1760 -0.6111 -0.7717 +vn -0.5118 -0.7216 -0.4662 +vn 0.1184 -0.6628 -0.7394 +vn -0.3173 0.7504 0.5798 +vn -0.3141 0.8014 0.5090 +vn -0.3117 0.7750 0.5498 +vn -0.3006 0.8384 0.4548 +vn -0.2659 0.8652 0.4252 +vn -0.2916 0.8185 0.4949 +vn 0.1429 -0.9897 0.0002 +vn 0.0651 -0.9978 0.0102 +vn 0.2901 -0.8855 0.3630 +vn 0.3222 -0.9313 0.1699 +vn -0.1672 0.9720 0.1649 +vn -0.0958 0.9954 -0.0064 +vn 0.4480 -0.7094 0.5441 +vn 0.3092 -0.4878 0.8164 +vn 0.4121 -0.6710 0.6163 +vn 0.3092 -0.4913 0.8142 +vn 0.1999 -0.3126 0.9286 +vn 0.1465 -0.2172 0.9651 +vn -0.3060 0.6889 0.6571 +vn -0.2892 0.7696 0.5692 +vn -0.3061 0.6888 0.6572 +vn -0.2893 0.7695 0.5693 +vn -0.2712 0.4744 0.8375 +vn -0.2909 0.2842 0.9136 +vn -0.3404 -0.5343 0.7737 +vn -0.3700 -0.3788 0.8483 +vn -0.3701 -0.3791 0.8481 +vn -0.1656 0.3924 0.9048 +vn -0.0590 0.1869 0.9806 +vn -0.0580 0.1844 0.9811 +vn -0.0020 -0.7396 -0.6731 +vn -0.0537 -0.8367 -0.5450 +vn -0.0022 -0.7394 -0.6732 +vn -0.0533 -0.8371 -0.5445 +vn -0.6243 0.5394 -0.5651 +vn -0.6041 0.5820 -0.5444 +vn -0.3566 0.2715 -0.8939 +vn -0.6042 0.5819 -0.5444 +vn -0.3653 0.6673 -0.6490 +vn -0.5551 0.8157 -0.1630 +vn -0.6041 0.5819 -0.5444 +vn 0.5121 -0.6553 -0.5553 +vn 0.5051 -0.7291 -0.4617 +vn 0.5141 -0.6417 -0.5691 +vn 0.4979 -0.7659 -0.4068 +vn -0.4238 0.8140 -0.3972 +vn -0.4783 0.5819 -0.6578 +vn -0.4713 0.6182 -0.6290 +vn -0.4264 0.8088 -0.4050 +vn 0.1842 -0.0486 -0.9817 +vn 0.2073 -0.1578 -0.9655 +vn 0.3630 -0.0071 -0.9318 +vn 0.3229 0.0589 -0.9446 +vn 0.1804 0.2385 -0.9542 +vn 0.2481 -0.1563 -0.9560 +vn 0.2257 -0.2879 -0.9307 +vn 0.3747 0.1301 0.9180 +vn 0.9223 0.1778 0.3432 +vn -0.1474 0.0639 0.9870 +vn 0.3747 0.1302 0.9180 +vn 0.1702 -0.9378 0.3027 +vn -0.6675 -0.7187 0.1946 +vn -0.5471 -0.5182 0.6575 +vn -0.0212 -0.7074 0.7065 +vn -0.9961 -0.0819 -0.0314 +vn -0.8138 -0.0909 0.5740 +vn -0.5471 -0.5182 0.6574 +vn -0.5470 -0.5182 0.6575 +vn -0.3575 -0.0449 0.9328 +vn -0.3142 -0.1033 0.9437 +vn -0.3759 -0.1830 -0.9084 +vn -0.9239 -0.2035 -0.3239 +vn 0.1517 -0.0812 -0.9851 +vn -0.3758 -0.1830 -0.9084 +vn -0.9852 -0.1700 -0.0208 +vn -0.9621 -0.1299 0.2400 +vn 0.6611 0.0706 -0.7470 +vn 0.9623 0.1494 -0.2273 +vn 0.9852 0.1700 0.0208 +vn -0.6625 -0.0035 0.7490 +vn -0.6626 -0.0035 0.7490 +vn 0.0335 0.1182 -0.9924 +vn 0.2625 -0.0924 -0.9605 +vn -0.3286 0.4462 0.8324 +vn -0.0747 0.2100 0.9749 +vn -0.2412 0.0878 0.9665 +vn -0.2359 0.0972 0.9669 +vn -0.2767 0.2808 0.9190 +vn -0.2194 0.0814 0.9722 +vn -0.1785 -0.0093 0.9839 +vn 0.2715 -0.2104 -0.9392 +vn 0.2150 -0.0340 -0.9760 +vn 0.3829 -0.0912 -0.9193 +vn -0.3297 0.4803 0.8128 +vn -0.3236 0.4895 0.8097 +vn 0.3302 -0.4833 -0.8108 +vn 0.3249 -0.4696 -0.8209 +vn 0.0823 -0.1559 -0.9843 +vn 0.0865 -0.0684 -0.9939 +vn 0.0739 -0.0551 -0.9957 +vn 0.1601 -0.0938 -0.9826 +vn 0.1177 -0.0274 -0.9927 +vn -0.0377 -0.0071 -0.9993 +vn 0.0221 -0.0907 -0.9956 +vn 0.1170 -0.1334 -0.9841 +vn -0.0602 -0.0371 0.9975 +vn -0.0626 0.0094 0.9980 +vn -0.1079 -0.0531 0.9927 +vn -0.0812 -0.0990 0.9918 +vn 0.0541 -0.0694 0.9961 +vn 0.0382 -0.1493 0.9880 +vn -0.0439 -0.1644 0.9854 +vn -0.2937 0.2596 0.9200 +vn 0.2166 -0.0035 -0.9763 +vn 0.2876 -0.2298 -0.9298 +vn 0.2291 -0.3852 -0.8940 +vn 0.2061 -0.4976 -0.8425 +vn -0.2211 0.1785 0.9588 +vn -0.2205 0.3004 0.9280 +vn -0.1934 0.3928 0.8991 +vn -0.1124 0.6091 0.7851 +vn -0.0932 0.7048 0.7033 +vn -0.0932 0.7048 0.7032 +vn -0.0447 0.6867 0.7255 +vn 0.1592 -0.4974 0.8528 +vn 0.1743 -0.6283 0.7582 +vn 0.5154 -0.5712 0.6388 +vn -0.1115 0.2099 0.9713 +vn 0.0954 -0.8929 -0.4400 +vn 0.0284 -0.9807 0.1937 +vn -0.0529 -0.6454 0.7620 +vn -0.1506 0.4931 0.8569 +vn 0.1636 -0.6142 -0.7720 +vn 0.1233 -0.7146 -0.6886 +vn 0.1045 -0.8006 -0.5901 +vn -0.2929 -0.9561 -0.0019 +vn 0.1629 -0.4763 -0.8641 +vn 0.1519 -0.4765 0.8660 +vn 0.1519 -0.4764 0.8660 +vn -0.0041 0.0279 -0.9996 +vn -0.0018 -0.0262 -0.9997 +vn -0.0027 -0.0208 -0.9998 +vn 0.0423 0.6631 0.7473 +vn 0.0253 0.6050 0.7958 +vn 0.0170 0.5666 0.8238 +vn 0.0324 0.9931 0.1126 +vn 0.0555 0.9253 0.3751 +vn 0.0654 0.8147 0.5762 +vn -0.0080 0.4712 -0.8820 +vn 0.0004 0.6217 -0.7833 +vn 0.0005 0.7643 -0.6448 +vn -0.0094 0.9248 -0.3804 +vn 0.0025 0.9931 -0.1171 +vn -0.0218 0.1214 0.9924 +vn -0.0562 0.2022 0.9777 +vn -0.0663 0.1531 0.9860 +vn 0.0477 -0.0824 0.9955 +vn 0.0246 -0.0213 0.9995 +vn 0.0686 -0.1320 0.9889 +vn 0.0566 -0.0941 0.9939 +vn 0.0424 0.2449 0.9686 +vn 0.0656 -0.0444 0.9969 +vn 0.0215 0.4853 0.8741 +vn 0.0604 0.7308 0.6800 +vn 0.0604 0.7308 0.6799 +vn -0.0122 -0.0174 0.9998 +vn -0.0145 0.0305 0.9994 +vn -0.0141 0.0117 0.9998 +vn -0.0097 -0.6026 -0.7980 +vn -0.0262 -0.6620 -0.7490 +vn -0.0020 -0.5694 -0.8220 +vn -0.0370 -0.9253 -0.3774 +vn -0.0147 -0.9937 -0.1111 +vn -0.0471 -0.8137 -0.5794 +vn 0.0241 -0.4628 0.8862 +vn 0.0165 -0.6161 0.7875 +vn 0.0169 -0.7574 0.6528 +vn 0.0266 -0.9205 0.3898 +vn 0.0145 -0.9923 0.1228 +vn 0.0734 -0.2018 -0.9767 +vn 0.0386 -0.1216 -0.9918 +vn -0.0077 0.0191 -0.9998 +vn -0.0308 0.0806 -0.9963 +vn -0.0403 0.0954 -0.9946 +vn -0.0531 0.1408 -0.9886 +vn -0.0508 0.0552 -0.9972 +vn -0.0275 -0.2484 -0.9683 +vn -0.0068 -0.4957 -0.8685 +vn -0.0433 -0.7306 -0.6814 +vn -0.0433 -0.7306 -0.6815 +vn 0.9953 0.0960 0.0130 +vn 0.8311 -0.5144 0.2113 +vn 0.4854 -0.4691 0.7378 +vn 0.6716 0.0577 0.7387 +vn -0.1499 0.9085 -0.3902 +vn 0.6530 0.7129 -0.2556 +vn 0.4384 0.8305 0.3435 +vn -0.2888 0.9557 0.0568 +vn 0.6529 0.7130 -0.2556 +vn 0.4385 0.8305 0.3436 +vn -0.0746 0.2099 0.9749 +vn -0.3286 0.4462 0.8325 +vn -0.2053 0.0372 0.9780 +vn -0.4058 0.0890 0.9096 +vn -0.8027 0.5297 -0.2741 +vn -0.8139 0.5065 0.2846 +vn -0.0619 0.0287 0.9977 +vn -0.1571 -0.0666 0.9853 +vn 0.0225 0.1128 -0.9934 +vn 0.1775 -0.0047 -0.9841 +vn 0.1852 0.0476 -0.9816 +vn -0.5601 -0.0584 0.8264 +vn -0.9734 -0.0286 0.2274 +vn -0.5601 -0.0583 0.8264 +vn 0.9967 0.0072 0.0804 +vn 0.9811 -0.0268 -0.1916 +vn 0.9297 0.0383 0.3663 +vn 0.6045 -0.0884 -0.7917 +vn -0.9965 -0.0012 -0.0837 +vn -0.9354 0.0157 -0.3532 +vn -0.4669 0.0619 -0.8821 +vn 0.0012 0.0523 -0.9986 +vn 0.0798 0.0123 -0.9967 +vn 0.2305 -0.0423 -0.9722 +vn 0.1168 0.1019 -0.9879 +vn 0.4277 0.1018 0.8982 +vn -0.0484 0.0945 0.9943 +vn -0.0879 0.0476 0.9950 +vn -0.1595 -0.0942 0.9827 +vn 0.2152 -0.9312 0.2942 +vn 0.7752 -0.5856 0.2369 +vn 0.6843 -0.3829 -0.6205 +vn 0.2657 -0.7011 -0.6616 +vn 0.6843 -0.3829 -0.6206 +vn -0.9957 -0.0551 -0.0751 +vn -0.5927 -0.7844 0.1830 +vn -0.3429 -0.5219 -0.7810 +vn -0.5661 0.0075 -0.8243 +vn -0.5927 -0.7843 0.1830 +vn -0.3429 -0.5219 -0.7811 +vn -0.3429 -0.5220 -0.7810 +vn -0.5662 0.0075 -0.8243 +vn 0.1596 0.0872 -0.9833 +vn -0.7750 0.5848 -0.2397 +vn -0.3887 0.3991 -0.8304 +vn -0.7749 0.5848 -0.2397 +vn -0.3887 0.3991 -0.8305 +vn -0.3888 0.3991 -0.8304 +vn 0.6395 0.3511 0.6839 +vn 0.6394 0.3511 0.6840 +vn 0.9474 0.2988 0.1143 +vn -0.9527 -0.2620 -0.1543 +vn -0.9695 -0.2100 0.1264 +vn -0.8951 -0.1293 0.4268 +vn -0.2668 -0.2599 -0.9280 +vn -0.6247 -0.2988 -0.7214 +vn -0.6247 -0.2987 -0.7215 +vn 0.9612 0.2368 -0.1414 +vn 0.8829 0.1396 -0.4483 +vn 0.3385 -0.1387 -0.9307 +vn -0.1689 -0.2765 -0.9461 +vn -0.1899 -0.3730 -0.9082 +vn -0.2128 -0.3387 -0.9165 +vn -0.1642 -0.4781 -0.8628 +vn -0.1862 -0.3662 -0.9117 +vn -0.2250 -0.1345 -0.9650 +vn -0.3089 -0.2377 -0.9209 +vn -0.3408 -0.3426 -0.8755 +vn -0.3322 0.1093 0.9369 +vn -0.3023 0.0154 0.9531 +vn 0.1700 0.2406 0.9556 +vn 0.1954 0.3834 0.9027 +vn 0.2242 0.3036 0.9260 +vn 0.1628 0.5009 0.8500 +vn 0.1760 0.4168 0.8918 +vn 0.1475 0.5470 0.8240 +vn 0.2885 0.4507 0.8448 +vn 0.3493 0.3217 0.8800 +vn 0.0477 0.4379 0.8978 +vn 0.1737 0.3860 0.9060 +vn -0.1089 -0.1868 -0.9763 +vn -0.1847 -0.3652 -0.9124 +vn -0.1918 -0.3019 -0.9339 +vn 0.1346 -0.1192 0.9837 +vn 0.0567 -0.1894 0.9803 +vn -0.1440 0.0405 -0.9887 +vn -0.1599 -0.0020 -0.9871 +vn -0.1744 -0.1769 -0.9687 +vn -0.0872 -0.0751 -0.9934 +vn 0.2323 0.0984 0.9677 +vn 0.2268 0.1704 0.9589 +vn 0.3397 0.2023 0.9185 +vn -0.2145 -0.0187 -0.9766 +vn -0.1918 0.0633 -0.9794 +vn -0.2204 -0.1589 -0.9624 +vn 0.0575 -0.1181 -0.9913 +vn 0.0301 0.0484 -0.9984 +vn -0.0437 0.1936 0.9801 +vn -0.0289 0.3363 0.9413 +vn -0.0108 0.0782 0.9969 +vn 0.0452 0.0140 0.9989 +vn -0.0288 0.1231 -0.9920 +vn -0.0905 0.1316 -0.9872 +vn -0.2205 -0.2956 -0.9295 +vn -0.3001 -0.4472 -0.8426 +vn -0.2174 -0.2932 -0.9310 +vn 0.2308 0.2479 0.9409 +vn 0.3245 0.2036 0.9237 +vn 0.1668 0.7293 0.6636 +vn 0.1647 0.6901 0.7047 +vn 0.1810 0.6983 0.6925 +vn 0.2840 -0.2988 0.9111 +vn 0.3840 0.3231 0.8650 +vn 0.2383 0.6948 0.6786 +vn 0.2098 0.6997 0.6830 +vn 0.2903 -0.9332 0.2119 +vn -0.0582 -0.8922 -0.4480 +vn 0.4526 -0.8897 0.0604 +vn 0.2903 -0.9332 0.2118 +vn 0.1570 0.6188 0.7697 +vn 0.1647 0.6902 0.7047 +vn -0.1707 -0.5743 -0.8007 +vn -0.1722 -0.6731 -0.7192 +vn -0.1412 -0.7823 -0.6067 +vn 0.2929 -0.9561 -0.0019 +vn -0.4685 -0.3249 -0.8215 +vn -0.1629 -0.4763 -0.8641 +vn -0.1519 -0.4765 0.8660 +vn -0.4592 -0.3237 0.8272 +vn -0.1519 -0.4764 0.8660 +vn 0.0063 0.0543 -0.9985 +vn 0.0024 -0.0072 -1.0000 +vn 0.0025 -0.0125 -0.9999 +vn -0.0215 0.6755 0.7370 +vn -0.0296 0.7263 0.6868 +vn -0.0179 0.5672 0.8234 +vn 0.0726 0.9254 0.3721 +vn 0.1390 0.9869 0.0825 +vn 0.0115 0.8198 0.5726 +vn 0.0496 0.5081 -0.8599 +vn 0.0839 0.6553 -0.7507 +vn 0.1302 0.7697 -0.6250 +vn 0.1808 0.8995 -0.3979 +vn 0.1841 0.9696 -0.1613 +vn 0.0129 0.3882 0.9215 +vn 0.0176 0.2487 0.9684 +vn -0.0211 0.0231 0.9995 +vn -0.0471 -0.0769 0.9959 +vn -0.0566 -0.0940 0.9940 +vn -0.0691 -0.1351 0.9884 +vn -0.0685 -0.0735 0.9949 +vn -0.0499 0.1613 0.9857 +vn -0.0288 0.4015 0.9154 +vn -0.0229 0.7583 0.6515 +vn 0.0106 -0.0445 0.9990 +vn 0.0143 0.0111 0.9998 +vn 0.0141 0.0034 0.9999 +vn 0.0133 -0.7275 -0.6860 +vn 0.0057 -0.6774 -0.7356 +vn 0.0029 -0.5696 -0.8219 +vn -0.1562 -0.9846 -0.0790 +vn -0.0911 -0.9233 -0.3732 +vn -0.0297 -0.8177 -0.5749 +vn -0.0657 -0.5017 0.8625 +vn -0.1003 -0.6510 0.7524 +vn -0.1463 -0.7619 0.6309 +vn -0.1964 -0.8920 0.4071 +vn -0.1999 -0.9651 0.1690 +vn -0.0325 -0.2433 -0.9694 +vn -0.0275 -0.3780 -0.9254 +vn 0.0304 0.0754 -0.9967 +vn 0.0049 -0.0248 -0.9997 +vn 0.0538 0.1441 -0.9881 +vn 0.0403 0.0954 -0.9946 +vn 0.0354 -0.1556 -0.9872 +vn 0.0536 0.0865 -0.9948 +vn 0.0146 -0.4031 -0.9150 +vn 0.0058 -0.7581 -0.6522 +vn -0.9775 -0.1835 0.1040 +vn -0.5257 -0.7353 0.4278 +vn -0.5289 -0.7665 -0.3642 +vn -0.7314 -0.3279 -0.5980 +vn -0.5258 -0.7352 0.4278 +vn -0.5289 -0.7665 -0.3643 +vn -0.1741 -0.5266 -0.8321 +vn -0.7313 -0.3279 -0.5980 +vn -0.1961 0.8495 -0.4897 +vn -0.8208 0.4940 -0.2867 +vn -0.6197 0.1067 -0.7775 +vn -0.2622 0.3635 -0.8939 +vn -0.6198 0.1067 -0.7775 +vn -0.6197 0.1066 -0.7775 +vn -0.2622 0.3634 -0.8940 +vn -0.2145 -0.2735 -0.9376 +vn 0.5270 0.7362 -0.4245 +vn 0.1951 0.3019 -0.9332 +vn 0.5271 0.7362 -0.4245 +vn 0.9690 0.1977 -0.1482 +vn 0.5058 0.7430 -0.4383 +vn 0.1774 0.4726 -0.8633 +vn 0.4456 0.1622 -0.8804 +vn 0.4455 0.1622 -0.8805 +vn 0.0320 -0.8682 0.4951 +vn 0.7206 -0.6062 0.3365 +vn 0.4578 -0.5332 -0.7114 +vn -0.1681 -0.8732 -0.4574 +vn 0.7207 -0.6062 0.3364 +vn 0.4579 -0.5332 -0.7114 +vn 0.4578 -0.5331 -0.7115 +vn -0.1517 0.0897 -0.9844 +vn -0.2795 -0.0717 -0.9575 +vn -0.5631 -0.7106 0.4219 +vn -0.6460 -0.5705 -0.5072 +vn -0.6460 -0.5705 -0.5071 +vn 0.5255 0.7608 0.3808 +vn 0.7317 0.3179 0.6030 +vn 0.2884 0.4507 0.8448 +vn 0.0017 0.9517 0.3071 +vn 0.5254 0.7609 0.3808 +vn 0.5254 0.7608 0.3808 +vn 0.0478 0.4378 0.8978 +vn -0.4985 0.6850 0.5312 +vn -0.5303 0.1165 0.8397 +vn -0.4986 0.6850 0.5312 +vn -0.5304 0.1165 0.8397 +vn -0.1948 -0.3002 0.9338 +vn 0.2628 -0.3639 0.8936 +vn -0.1948 -0.3001 0.9338 +vn 0.6205 -0.1099 0.7765 +vn 0.6204 -0.1099 0.7765 +vn -0.2243 -0.4816 0.8472 +vn -0.4568 -0.1878 0.8695 +vn 0.1231 -0.5441 0.8299 +vn -0.4569 -0.1878 0.8695 +vn 0.4930 -0.3456 0.7984 +vn 0.7424 0.1055 0.6616 +vn 0.4931 -0.3456 0.7984 +vn 0.7425 0.1055 0.6615 +vn 0.4931 -0.3457 0.7984 +vn 0.6263 0.6593 0.4159 +vn 0.1588 0.8899 0.4276 +vn 0.1588 0.8899 0.4275 +vn -0.4294 0.4546 0.7804 +vn -0.4293 0.4547 0.7804 +vn -0.6977 0.3957 0.5972 +vn -0.2988 0.6975 0.6513 +vn -0.7087 -0.0753 0.7015 +vn -0.7087 -0.0752 0.7015 +vn -0.6977 0.3956 0.5972 +vn -0.3777 -0.4318 0.8191 +vn 0.0535 -0.5501 0.8334 +vn -0.3776 -0.4318 0.8191 +vn 0.4132 -0.4142 0.8110 +vn 0.5713 -0.0425 0.8196 +vn 0.5714 -0.0425 0.8196 +vn 0.3291 0.5043 0.7984 +vn 0.3290 0.5043 0.7984 +vn -0.5260 0.5046 -0.6846 +vn -0.6939 -0.0610 -0.7175 +vn -0.0240 0.7566 -0.6535 +vn -0.6939 -0.0609 -0.7175 +vn 0.5396 0.5479 -0.6392 +vn 0.8132 0.0717 -0.5776 +vn 0.5396 0.5479 -0.6393 +vn 0.7985 -0.4286 -0.4226 +vn 0.3397 -0.8761 -0.3423 +vn 0.3396 -0.8761 -0.3423 +vn 0.3168 -0.2753 -0.9076 +vn 0.1180 -0.1788 -0.9768 +vn -0.4040 -0.7553 -0.5161 +vn -0.4040 -0.7553 -0.5160 +vn -0.8633 0.0797 -0.4983 +vn -0.6069 0.0892 -0.7897 +vn -0.4033 -0.0481 0.9138 +vn -0.9442 0.0236 0.3284 +vn -0.0476 -0.0712 0.9963 +vn -0.9897 0.0605 -0.1295 +vn -0.9443 0.0236 0.3284 +vn 0.3206 -0.0527 0.9457 +vn 0.0126 -0.0666 0.9977 +vn 0.8547 -0.0089 0.5191 +vn 0.6825 0.0668 -0.7278 +vn 0.9412 0.0486 -0.3344 +vn -0.0174 -0.0698 0.9974 +vn 0.9893 0.0195 0.1448 +vn 0.8546 -0.0089 0.5191 +usemtl Scene_-_Root +s 1 +f 14164/14164/9468 14165/14165/9469 14166/14166/9470 +f 14167/14167/9471 14168/14168/9472 14169/14169/9473 +f 14167/14167/9471 14169/14169/9473 14170/14170/9474 +f 14171/14171/9472 14172/14172/9475 14173/14173/9476 +f 14171/14171/9472 14173/14173/9476 14174/14174/9473 +f 14174/14174/9473 14173/14173/9476 14175/14175/9477 +f 14174/14174/9473 14175/14175/9477 14176/14176/9478 +f 14170/14170/9474 14169/14169/9473 14177/14177/9478 +f 14170/14170/9474 14177/14177/9478 14178/14178/9479 +f 14179/14179/9480 14180/14180/9481 14181/14181/9482 +f 14179/14179/9480 14181/14181/9482 14182/14182/9483 +f 14180/14180/9481 14183/14183/9484 14184/14184/9485 +f 14180/14180/9481 14184/14184/9485 14181/14181/9482 +f 14181/14181/9482 14184/14184/9485 14185/14185/9486 +f 14181/14181/9482 14185/14185/9486 14186/14186/9487 +f 14182/14182/9483 14181/14181/9482 14186/14186/9487 +f 14182/14182/9483 14186/14186/9487 14187/14187/9488 +f 14183/14183/9484 14188/14188/9489 14189/14189/9490 +f 14183/14183/9484 14189/14189/9490 14184/14184/9485 +f 14188/14188/9489 14190/14190/9491 14191/14191/9492 +f 14188/14188/9489 14191/14191/9492 14189/14189/9490 +f 14189/14189/9490 14191/14191/9492 14192/14192/9493 +f 14189/14189/9490 14192/14192/9493 14193/14193/9494 +f 14184/14184/9485 14189/14189/9490 14193/14193/9494 +f 14184/14184/9485 14193/14193/9494 14185/14185/9486 +f 14190/14190/9491 14194/14194/9495 14195/14195/9496 +f 14190/14190/9491 14195/14195/9496 14191/14191/9492 +f 14194/14194/9495 14196/14196/9497 14197/14197/9498 +f 14194/14194/9495 14197/14197/9498 14195/14195/9496 +f 14195/14195/9496 14197/14197/9498 14198/14198/9499 +f 14195/14195/9496 14198/14198/9499 14199/14199/9500 +f 14191/14191/9492 14195/14195/9496 14199/14199/9500 +f 14191/14191/9492 14199/14199/9500 14192/14192/9493 +f 14196/14196/9497 14200/14200/9501 14201/14201/9502 +f 14196/14196/9497 14201/14201/9502 14197/14197/9498 +f 14200/14200/9501 14202/14202/9503 14203/14203/9504 +f 14200/14200/9501 14203/14203/9504 14201/14201/9502 +f 14201/14201/9502 14203/14203/9504 14204/14204/9505 +f 14201/14201/9502 14204/14204/9505 14205/14205/9506 +f 14197/14197/9498 14201/14201/9502 14205/14205/9506 +f 14197/14197/9498 14205/14205/9506 14198/14198/9499 +f 14202/14202/9503 14206/14206/9507 14207/14207/9508 +f 14202/14202/9503 14207/14207/9508 14203/14203/9504 +f 14206/14206/9507 14208/14208/9509 14209/14209/9510 +f 14206/14206/9507 14209/14209/9510 14207/14207/9508 +f 14207/14207/9508 14209/14209/9510 14210/14210/9511 +f 14207/14207/9508 14210/14210/9511 14211/14211/9512 +f 14203/14203/9504 14207/14207/9508 14211/14211/9512 +f 14203/14203/9504 14211/14211/9512 14204/14204/9505 +f 14212/14212/9513 14213/14213/9514 14214/14214/9515 +f 14212/14212/9513 14214/14214/9515 14215/14215/9516 +f 14213/14213/9514 14216/14216/9517 14217/14217/9518 +f 14213/14213/9514 14217/14217/9518 14214/14214/9515 +f 14214/14214/9515 14217/14217/9518 14218/14218/9519 +f 14214/14214/9515 14218/14218/9519 14219/14219/9520 +f 14215/14215/9516 14214/14214/9515 14219/14219/9520 +f 14215/14215/9516 14219/14219/9520 14220/14220/9521 +f 14221/14221/9522 14222/14222/9523 14223/14223/9524 +f 14221/14221/9522 14223/14223/9524 14224/14224/9525 +f 14225/14225/9523 14212/14212/9513 14215/14215/9516 +f 14225/14225/9523 14215/14215/9516 14226/14226/9524 +f 14226/14226/9524 14215/14215/9516 14220/14220/9521 +f 14226/14226/9524 14220/14220/9521 14227/14227/9526 +f 14224/14224/9525 14223/14223/9524 14228/14228/9526 +f 14224/14224/9525 14228/14228/9526 14229/14229/9527 +f 14230/14230/9528 14231/14231/9529 14232/14232/9530 +f 14230/14230/9528 14232/14232/9530 14233/14233/9531 +f 14231/14231/9529 14221/14221/9522 14224/14224/9525 +f 14231/14231/9529 14224/14224/9525 14232/14232/9530 +f 14232/14232/9530 14224/14224/9525 14229/14229/9527 +f 14232/14232/9530 14229/14229/9527 14234/14234/9532 +f 14233/14233/9531 14232/14232/9530 14234/14234/9532 +f 14233/14233/9531 14234/14234/9532 14235/14235/9533 +f 14216/14216/9517 14236/14236/9534 14237/14237/9535 +f 14216/14216/9517 14237/14237/9535 14217/14217/9518 +f 14236/14236/9534 14167/14167/9471 14170/14170/9474 +f 14236/14236/9534 14170/14170/9474 14237/14237/9535 +f 14237/14237/9535 14170/14170/9474 14178/14178/9479 +f 14237/14237/9535 14178/14178/9479 14238/14238/9536 +f 14217/14217/9518 14237/14237/9535 14238/14238/9536 +f 14217/14217/9518 14238/14238/9536 14218/14218/9519 +f 14172/14172/9475 14239/14239/9537 14240/14240/9538 +f 14172/14172/9475 14240/14240/9538 14173/14173/9476 +f 14239/14239/9537 14179/14179/9480 14182/14182/9483 +f 14239/14239/9537 14182/14182/9483 14240/14240/9538 +f 14240/14240/9538 14182/14182/9483 14187/14187/9488 +f 14240/14240/9538 14187/14187/9488 14241/14241/9539 +f 14173/14173/9476 14240/14240/9538 14241/14241/9539 +f 14173/14173/9476 14241/14241/9539 14175/14175/9477 +f 14242/14242/9540 14243/14243/9541 14244/14244/9542 +f 14242/14242/9540 14244/14244/9542 14245/14245/9543 +f 14243/14243/9541 14246/14246/9544 14247/14247/9545 +f 14243/14243/9541 14247/14247/9545 14244/14244/9542 +f 14244/14244/9542 14247/14247/9545 14248/14248/9546 +f 14244/14244/9542 14248/14248/9546 14249/14249/9547 +f 14245/14245/9543 14244/14244/9542 14249/14249/9547 +f 14245/14245/9543 14249/14249/9547 14250/14250/9548 +f 14230/14230/9528 14251/14251/9549 14252/14252/9550 +f 14230/14230/9528 14252/14252/9550 14253/14253/9551 +f 14251/14251/9549 14242/14242/9540 14245/14245/9543 +f 14251/14251/9549 14245/14245/9543 14252/14252/9550 +f 14252/14252/9550 14245/14245/9543 14250/14250/9548 +f 14252/14252/9550 14250/14250/9548 14254/14254/9552 +f 14253/14253/9551 14252/14252/9550 14254/14254/9552 +f 14253/14253/9551 14254/14254/9552 14255/14255/9553 +f 14256/14256/9554 14257/14257/9555 14258/14258/9556 +f 14256/14256/9554 14258/14258/9556 14259/14259/9557 +f 14257/14257/9555 14260/14260/9558 14261/14261/9559 +f 14257/14257/9555 14261/14261/9559 14258/14258/9556 +f 14262/14262/9556 14263/14263/9559 14264/14264/9560 +f 14262/14262/9556 14264/14264/9560 14265/14265/9561 +f 14266/14266/9557 14262/14262/9556 14265/14265/9561 +f 14266/14266/9557 14265/14265/9561 14267/14267/9562 +f 14268/14268/9563 14269/14269/9564 14270/14270/9565 +f 14268/14268/9563 14270/14270/9565 14271/14271/9566 +f 14269/14269/9564 14272/14272/9567 14273/14273/9568 +f 14269/14269/9564 14273/14273/9568 14270/14270/9565 +f 14270/14270/9565 14273/14273/9568 14274/14274/9569 +f 14270/14270/9565 14274/14274/9569 14275/14275/9570 +f 14271/14271/9566 14270/14270/9565 14275/14275/9570 +f 14271/14271/9566 14275/14275/9570 14276/14276/9571 +f 14276/14276/9571 14275/14275/9570 14277/14277/9572 +f 14276/14276/9571 14277/14277/9572 14278/14278/9573 +f 14275/14275/9570 14274/14274/9569 14279/14279/9574 +f 14275/14275/9570 14279/14279/9574 14277/14277/9572 +f 14277/14277/9572 14279/14279/9574 14280/14280/9575 +f 14277/14277/9572 14280/14280/9575 14281/14281/9576 +f 14278/14278/9573 14277/14277/9572 14281/14281/9576 +f 14278/14278/9573 14281/14281/9576 14282/14282/9577 +f 14282/14282/9577 14281/14281/9576 14283/14283/9578 +f 14282/14282/9577 14283/14283/9578 14284/14284/9579 +f 14281/14281/9576 14280/14280/9575 14285/14285/9580 +f 14281/14281/9576 14285/14285/9580 14283/14283/9578 +f 14283/14283/9578 14285/14285/9580 14286/14286/9581 +f 14283/14283/9578 14286/14286/9581 14287/14287/9582 +f 14284/14284/9579 14283/14283/9578 14287/14287/9582 +f 14284/14284/9579 14287/14287/9582 14288/14288/9583 +f 14288/14288/9583 14287/14287/9582 14289/14289/9584 +f 14288/14288/9583 14289/14289/9584 14290/14290/9585 +f 14287/14287/9582 14286/14286/9581 14291/14291/9586 +f 14287/14287/9582 14291/14291/9586 14289/14289/9584 +f 14289/14289/9584 14291/14291/9586 14292/14292/9587 +f 14289/14289/9584 14292/14292/9587 14293/14293/9588 +f 14290/14290/9585 14289/14289/9584 14293/14293/9588 +f 14290/14290/9585 14293/14293/9588 14294/14294/9589 +f 14294/14294/9589 14293/14293/9588 14295/14295/9590 +f 14294/14294/9589 14295/14295/9590 14296/14296/9591 +f 14293/14293/9588 14292/14292/9587 14297/14297/9592 +f 14293/14293/9588 14297/14297/9592 14295/14295/9590 +f 14295/14295/9590 14297/14297/9592 14298/14298/9593 +f 14295/14295/9590 14298/14298/9593 14299/14299/9594 +f 14296/14296/9591 14295/14295/9590 14299/14299/9594 +f 14296/14296/9591 14299/14299/9594 14300/14300/9595 +f 14301/14301/9596 14302/14302/9597 14303/14303/9598 +f 14301/14301/9596 14303/14303/9598 14304/14304/9599 +f 14302/14302/9597 14305/14305/9600 14306/14306/9601 +f 14302/14302/9597 14306/14306/9601 14303/14303/9598 +f 14303/14303/9598 14306/14306/9601 14307/14307/9602 +f 14303/14303/9598 14307/14307/9602 14308/14308/9603 +f 14304/14304/9599 14303/14303/9598 14308/14308/9603 +f 14304/14304/9599 14308/14308/9603 14309/14309/9604 +f 14310/14310/9605 14311/14311/9606 14312/14312/9607 +f 14310/14310/9605 14312/14312/9607 14313/14313/9608 +f 14311/14311/9606 14314/14314/9609 14315/14315/9610 +f 14311/14311/9606 14315/14315/9610 14312/14312/9607 +f 14316/14316/9607 14317/14317/9610 14305/14305/9600 +f 14316/14316/9607 14305/14305/9600 14302/14302/9597 +f 14318/14318/9608 14316/14316/9607 14302/14302/9597 +f 14318/14318/9608 14302/14302/9597 14301/14301/9596 +f 14319/14319/9611 14320/14320/9612 14321/14321/9613 +f 14319/14319/9611 14321/14321/9613 14322/14322/9614 +f 14320/14320/9612 14323/14323/9615 14324/14324/9616 +f 14320/14320/9612 14324/14324/9616 14321/14321/9613 +f 14321/14321/9613 14324/14324/9616 14314/14314/9609 +f 14321/14321/9613 14314/14314/9609 14311/14311/9606 +f 14322/14322/9614 14321/14321/9613 14311/14311/9606 +f 14322/14322/9614 14311/14311/9606 14310/14310/9605 +f 14309/14309/9604 14308/14308/9603 14325/14325/9617 +f 14309/14309/9604 14325/14325/9617 14326/14326/9618 +f 14308/14308/9603 14307/14307/9602 14327/14327/9619 +f 14308/14308/9603 14327/14327/9619 14325/14325/9617 +f 14325/14325/9617 14327/14327/9619 14260/14260/9558 +f 14325/14325/9617 14260/14260/9558 14257/14257/9555 +f 14326/14326/9618 14325/14325/9617 14257/14257/9555 +f 14326/14326/9618 14257/14257/9555 14256/14256/9554 +f 14267/14267/9562 14265/14265/9561 14328/14328/9620 +f 14267/14267/9562 14328/14328/9620 14329/14329/9621 +f 14265/14265/9561 14264/14264/9560 14330/14330/9622 +f 14265/14265/9561 14330/14330/9622 14328/14328/9620 +f 14328/14328/9620 14330/14330/9622 14272/14272/9567 +f 14328/14328/9620 14272/14272/9567 14269/14269/9564 +f 14329/14329/9621 14328/14328/9620 14269/14269/9564 +f 14329/14329/9621 14269/14269/9564 14268/14268/9563 +f 14331/14331/9623 14332/14332/9624 14333/14333/9625 +f 14331/14331/9623 14333/14333/9625 14334/14334/9626 +f 14332/14332/9624 14335/14335/9627 14336/14336/9628 +f 14332/14332/9624 14336/14336/9628 14333/14333/9625 +f 14333/14333/9625 14336/14336/9628 14337/14337/9629 +f 14333/14333/9625 14337/14337/9629 14338/14338/9630 +f 14334/14334/9626 14333/14333/9625 14338/14338/9630 +f 14334/14334/9626 14338/14338/9630 14339/14339/9631 +f 14319/14319/9611 14340/14340/9632 14341/14341/9633 +f 14319/14319/9611 14341/14341/9633 14342/14342/9634 +f 14340/14340/9632 14343/14343/9635 14344/14344/9636 +f 14340/14340/9632 14344/14344/9636 14341/14341/9633 +f 14341/14341/9633 14344/14344/9636 14335/14335/9627 +f 14341/14341/9633 14335/14335/9627 14332/14332/9624 +f 14342/14342/9634 14341/14341/9633 14332/14332/9624 +f 14342/14342/9634 14332/14332/9624 14331/14331/9623 +f 14175/14175/9477 14241/14241/9539 14345/14345/9637 +f 14175/14175/9477 14345/14345/9637 14346/14346/9638 +f 14241/14241/9539 14187/14187/9488 14347/14347/9639 +f 14241/14241/9539 14347/14347/9639 14345/14345/9637 +f 14348/14348/9640 14349/14349/9639 14350/14350/9641 +f 14348/14348/9640 14350/14350/9641 14351/14351/9642 +f 14352/14352/9638 14348/14348/9640 14351/14351/9642 +f 14352/14352/9638 14351/14351/9642 14353/14353/9643 +f 14354/14354/9644 14355/14355/9645 14356/14356/9646 +f 14354/14354/9644 14356/14356/9646 14357/14357/9647 +f 14358/14358/9645 14359/14359/9648 14360/14360/9649 +f 14358/14358/9645 14360/14360/9649 14361/14361/9646 +f 14362/14362/9650 14363/14363/9651 14364/14364/9652 +f 14362/14362/9650 14364/14364/9652 14365/14365/9653 +f 14366/14366/9654 14362/14362/9650 14365/14365/9653 +f 14366/14366/9654 14365/14365/9653 14367/14367/9655 +f 14368/14368/9656 14369/14369/9657 14370/14370/9658 +f 14368/14368/9656 14370/14370/9658 14371/14371/9659 +f 14369/14369/9657 14372/14372/9660 14373/14373/9661 +f 14369/14369/9657 14373/14373/9661 14370/14370/9658 +f 14374/14374/9662 14375/14375/9661 14376/14376/9663 +f 14374/14374/9662 14376/14376/9663 14377/14377/9664 +f 14378/14378/9659 14374/14374/9662 14377/14377/9664 +f 14378/14378/9659 14377/14377/9664 14379/14379/9665 +f 14229/14229/9527 14228/14228/9526 14380/14380/9666 +f 14229/14229/9527 14380/14380/9666 14381/14381/9667 +f 14227/14227/9526 14220/14220/9521 14382/14382/9668 +f 14227/14227/9526 14382/14382/9668 14383/14383/9666 +f 14384/14384/9669 14385/14385/9668 14386/14386/9670 +f 14384/14384/9669 14386/14386/9670 14387/14387/9671 +f 14388/14388/9667 14384/14384/9669 14387/14387/9671 +f 14388/14388/9667 14387/14387/9671 14389/14389/9672 +f 14246/14246/9544 14390/14390/9673 14391/14391/9674 +f 14246/14246/9544 14391/14391/9674 14392/14392/9675 +f 14390/14390/9673 14393/14393/9676 14394/14394/9677 +f 14390/14390/9673 14394/14394/9677 14391/14391/9674 +f 14395/14395/9678 14396/14396/9677 14397/14397/9679 +f 14395/14395/9678 14397/14397/9679 14398/14398/9680 +f 14399/14399/9675 14395/14395/9678 14398/14398/9680 +f 14399/14399/9675 14398/14398/9680 14400/14400/9681 +f 14401/14401/9682 14402/14402/9683 14403/14403/9684 +f 14401/14401/9682 14403/14403/9684 14404/14404/9685 +f 14402/14402/9683 14405/14405/9686 14406/14406/9687 +f 14402/14402/9683 14406/14406/9687 14403/14403/9684 +f 14407/14407/9688 14408/14408/9687 14409/14409/9689 +f 14407/14407/9688 14409/14409/9689 14410/14410/9690 +f 14411/14411/9691 14407/14407/9688 14410/14410/9690 +f 14411/14411/9691 14410/14410/9690 14339/14339/9631 +f 14178/14178/9479 14177/14177/9478 14412/14412/9692 +f 14178/14178/9479 14412/14412/9692 14413/14413/9693 +f 14176/14176/9478 14175/14175/9477 14346/14346/9638 +f 14176/14176/9478 14346/14346/9638 14414/14414/9694 +f 14415/14415/9692 14352/14352/9638 14353/14353/9643 +f 14415/14415/9692 14353/14353/9643 14416/14416/9695 +f 14417/14417/9693 14415/14415/9692 14416/14416/9695 +f 14417/14417/9693 14416/14416/9695 14418/14418/9696 +f 14393/14393/9676 14419/14419/9697 14420/14420/9698 +f 14393/14393/9676 14420/14420/9698 14394/14394/9677 +f 14419/14419/9697 14421/14421/9699 14422/14422/9700 +f 14419/14419/9697 14422/14422/9700 14420/14420/9698 +f 14423/14423/9701 14424/14424/9700 14425/14425/9702 +f 14423/14423/9701 14425/14425/9702 14426/14426/9703 +f 14427/14427/9677 14423/14423/9701 14426/14426/9703 +f 14427/14427/9677 14426/14426/9703 14428/14428/9679 +f 14372/14372/9660 14429/14429/9704 14430/14430/9705 +f 14372/14372/9660 14430/14430/9705 14373/14373/9661 +f 14431/14431/9706 14432/14432/9707 14433/14433/9708 +f 14431/14431/9706 14433/14433/9708 14434/14434/9705 +f 14435/14435/9705 14436/14436/9708 14437/14437/9709 +f 14435/14435/9705 14437/14437/9709 14438/14438/9710 +f 14375/14375/9661 14435/14435/9705 14438/14438/9710 +f 14375/14375/9661 14438/14438/9710 14376/14376/9663 +f 14250/14250/9548 14249/14249/9547 14439/14439/9711 +f 14250/14250/9548 14439/14439/9711 14440/14440/9712 +f 14249/14249/9547 14248/14248/9546 14441/14441/9713 +f 14249/14249/9547 14441/14441/9713 14439/14439/9711 +f 14442/14442/9714 14443/14443/9715 14444/14444/9716 +f 14442/14442/9714 14444/14444/9716 14445/14445/9717 +f 14446/14446/9718 14442/14442/9714 14445/14445/9717 +f 14446/14446/9718 14445/14445/9717 14447/14447/9719 +f 14448/14448/9720 14449/14449/9721 14450/14450/9722 +f 14448/14448/9720 14450/14450/9722 14451/14451/9723 +f 14449/14449/9721 14452/14452/9724 14453/14453/9725 +f 14449/14449/9721 14453/14453/9725 14450/14450/9722 +f 14454/14454/9722 14455/14455/9726 14456/14456/9727 +f 14454/14454/9722 14456/14456/9727 14457/14457/9728 +f 14458/14458/9723 14454/14454/9722 14457/14457/9728 +f 14458/14458/9723 14457/14457/9728 14459/14459/9729 +f 14460/14460/9730 14461/14461/9731 14462/14462/9732 +f 14460/14460/9730 14462/14462/9732 14463/14463/9733 +f 14461/14461/9731 14464/14464/9734 14465/14465/9735 +f 14461/14461/9731 14465/14465/9735 14462/14462/9732 +f 14466/14466/9732 14467/14467/9735 14468/14468/9736 +f 14466/14466/9732 14468/14468/9736 14469/14469/9737 +f 14470/14470/9738 14466/14466/9732 14469/14469/9737 +f 14470/14470/9738 14469/14469/9737 14471/14471/9739 +f 14359/14359/9648 14472/14472/9740 14473/14473/9741 +f 14359/14359/9648 14473/14473/9741 14360/14360/9649 +f 14472/14472/9740 14368/14368/9656 14371/14371/9659 +f 14472/14472/9740 14371/14371/9659 14473/14473/9741 +f 14474/14474/9741 14378/14378/9659 14379/14379/9665 +f 14474/14474/9741 14379/14379/9665 14475/14475/9742 +f 14363/14363/9651 14474/14474/9741 14475/14475/9742 +f 14363/14363/9651 14475/14475/9742 14364/14364/9652 +f 14476/14476/9743 14477/14477/9744 14478/14478/9745 +f 14476/14476/9743 14478/14478/9745 14479/14479/9746 +f 14477/14477/9744 14480/14480/9747 14481/14481/9748 +f 14477/14477/9744 14481/14481/9748 14478/14478/9745 +f 14482/14482/9745 14483/14483/9749 14274/14274/9569 +f 14482/14482/9745 14274/14274/9569 14273/14273/9568 +f 14484/14484/9750 14482/14482/9745 14273/14273/9568 +f 14484/14484/9750 14273/14273/9568 14272/14272/9567 +f 14485/14485/9751 14486/14486/9752 14487/14487/9753 +f 14485/14485/9751 14487/14487/9753 14488/14488/9754 +f 14489/14489/9755 14490/14490/9756 14491/14491/9757 +f 14489/14489/9755 14491/14491/9757 14492/14492/9758 +f 14492/14492/9758 14491/14491/9757 14493/14493/9759 +f 14492/14492/9758 14493/14493/9759 14494/14494/9760 +f 14488/14488/9754 14487/14487/9753 14495/14495/9760 +f 14488/14488/9754 14495/14495/9760 14496/14496/9761 +f 14452/14452/9724 14497/14497/9762 14498/14498/9763 +f 14452/14452/9724 14498/14498/9763 14453/14453/9725 +f 14497/14497/9762 14499/14499/9764 14500/14500/9765 +f 14497/14497/9762 14500/14500/9765 14498/14498/9763 +f 14501/14501/9763 14502/14502/9766 14503/14503/9767 +f 14501/14501/9763 14503/14503/9767 14504/14504/9768 +f 14455/14455/9726 14501/14501/9763 14504/14504/9768 +f 14455/14455/9726 14504/14504/9768 14456/14456/9727 +f 14464/14464/9734 14505/14505/9769 14506/14506/9770 +f 14464/14464/9734 14506/14506/9770 14465/14465/9735 +f 14505/14505/9769 14507/14507/9771 14508/14508/9772 +f 14505/14505/9769 14508/14508/9772 14506/14506/9770 +f 14509/14509/9770 14510/14510/9772 14511/14511/9773 +f 14509/14509/9770 14511/14511/9773 14512/14512/9774 +f 14467/14467/9735 14509/14509/9770 14512/14512/9774 +f 14467/14467/9735 14512/14512/9774 14468/14468/9736 +f 14192/14192/9493 14199/14199/9500 14513/14513/9775 +f 14192/14192/9493 14513/14513/9775 14514/14514/9776 +f 14199/14199/9500 14198/14198/9499 14515/14515/9777 +f 14199/14199/9500 14515/14515/9777 14513/14513/9775 +f 14516/14516/9778 14517/14517/9779 14518/14518/9780 +f 14516/14516/9778 14518/14518/9780 14519/14519/9781 +f 14520/14520/9782 14516/14516/9778 14519/14519/9781 +f 14520/14520/9782 14519/14519/9781 14521/14521/9783 +f 14522/14522/9784 14523/14523/9785 14524/14524/9786 +f 14522/14522/9784 14524/14524/9786 14525/14525/9787 +f 14523/14523/9785 14526/14526/9788 14527/14527/9789 +f 14523/14523/9785 14527/14527/9789 14524/14524/9786 +f 14528/14528/9786 14529/14529/9789 14530/14530/9790 +f 14528/14528/9786 14530/14530/9790 14531/14531/9791 +f 14532/14532/9792 14528/14528/9786 14531/14531/9791 +f 14532/14532/9792 14531/14531/9791 14533/14533/9793 +f 14499/14499/9764 14534/14534/9794 14535/14535/9795 +f 14499/14499/9764 14535/14535/9795 14500/14500/9765 +f 14534/14534/9794 14536/14536/9796 14537/14537/9797 +f 14534/14534/9794 14537/14537/9797 14535/14535/9795 +f 14538/14538/9798 14539/14539/9799 14540/14540/9800 +f 14538/14538/9798 14540/14540/9800 14541/14541/9801 +f 14502/14502/9766 14538/14538/9798 14541/14541/9801 +f 14502/14502/9766 14541/14541/9801 14503/14503/9767 +f 14507/14507/9771 14542/14542/9802 14543/14543/9803 +f 14507/14507/9771 14543/14543/9803 14508/14508/9772 +f 14542/14542/9802 14544/14544/9804 14545/14545/9805 +f 14542/14542/9802 14545/14545/9805 14543/14543/9803 +f 14546/14546/9806 14547/14547/9807 14548/14548/9808 +f 14546/14546/9806 14548/14548/9808 14549/14549/9809 +f 14510/14510/9772 14546/14546/9806 14549/14549/9809 +f 14510/14510/9772 14549/14549/9809 14511/14511/9773 +f 14544/14544/9804 14550/14550/9810 14551/14551/9811 +f 14544/14544/9804 14551/14551/9811 14545/14545/9805 +f 14550/14550/9810 14552/14552/9812 14553/14553/9813 +f 14550/14550/9810 14553/14553/9813 14551/14551/9811 +f 14554/14554/9811 14555/14555/9813 14556/14556/9814 +f 14554/14554/9811 14556/14556/9814 14557/14557/9815 +f 14547/14547/9807 14554/14554/9811 14557/14557/9815 +f 14547/14547/9807 14557/14557/9815 14548/14548/9808 +f 14220/14220/9521 14219/14219/9520 14558/14558/9816 +f 14220/14220/9521 14558/14558/9816 14382/14382/9668 +f 14219/14219/9520 14218/14218/9519 14559/14559/9817 +f 14219/14219/9520 14559/14559/9817 14558/14558/9816 +f 14560/14560/9816 14561/14561/9817 14562/14562/9818 +f 14560/14560/9816 14562/14562/9818 14563/14563/9819 +f 14385/14385/9668 14560/14560/9816 14563/14563/9819 +f 14385/14385/9668 14563/14563/9819 14386/14386/9670 +f 14187/14187/9488 14186/14186/9487 14564/14564/9820 +f 14187/14187/9488 14564/14564/9820 14347/14347/9639 +f 14186/14186/9487 14185/14185/9486 14565/14565/9821 +f 14186/14186/9487 14565/14565/9821 14564/14564/9820 +f 14566/14566/9820 14567/14567/9822 14568/14568/9823 +f 14566/14566/9820 14568/14568/9823 14569/14569/9824 +f 14349/14349/9639 14566/14566/9820 14569/14569/9824 +f 14349/14349/9639 14569/14569/9824 14350/14350/9641 +f 14536/14536/9796 14570/14570/9825 14571/14571/9826 +f 14536/14536/9796 14571/14571/9826 14537/14537/9797 +f 14570/14570/9825 14572/14572/9827 14573/14573/9828 +f 14570/14570/9825 14573/14573/9828 14571/14571/9826 +f 14574/14574/9826 14575/14575/9829 14576/14576/9830 +f 14574/14574/9826 14576/14576/9830 14577/14577/9831 +f 14539/14539/9799 14574/14574/9826 14577/14577/9831 +f 14539/14539/9799 14577/14577/9831 14540/14540/9800 +f 14578/14578/9832 14579/14579/9833 14580/14580/9834 +f 14578/14578/9832 14580/14580/9834 14581/14581/9835 +f 14579/14579/9833 14582/14582/9836 14583/14583/9837 +f 14579/14579/9833 14583/14583/9837 14580/14580/9834 +f 14584/14584/9838 14585/14585/9839 14586/14586/9840 +f 14584/14584/9838 14586/14586/9840 14587/14587/9841 +f 14588/14588/9842 14584/14584/9838 14587/14587/9841 +f 14588/14588/9842 14587/14587/9841 14589/14589/9843 +f 14590/14590/9844 14591/14591/9845 14592/14592/9846 +f 14590/14590/9844 14592/14592/9846 14593/14593/9847 +f 14591/14591/9845 14354/14354/9644 14357/14357/9647 +f 14591/14591/9845 14357/14357/9647 14592/14592/9846 +f 14594/14594/9846 14366/14366/9654 14367/14367/9655 +f 14594/14594/9846 14367/14367/9655 14595/14595/9848 +f 14596/14596/9847 14594/14594/9846 14595/14595/9848 +f 14596/14596/9847 14595/14595/9848 14597/14597/9849 +f 14235/14235/9533 14234/14234/9532 14598/14598/9850 +f 14235/14235/9533 14598/14598/9850 14599/14599/9851 +f 14234/14234/9532 14229/14229/9527 14381/14381/9667 +f 14234/14234/9532 14381/14381/9667 14598/14598/9850 +f 14600/14600/9852 14388/14388/9667 14389/14389/9672 +f 14600/14600/9852 14389/14389/9672 14601/14601/9853 +f 14602/14602/9851 14600/14600/9852 14601/14601/9853 +f 14602/14602/9851 14601/14601/9853 14603/14603/9854 +f 14421/14421/9699 14604/14604/9855 14605/14605/9856 +f 14421/14421/9699 14605/14605/9856 14422/14422/9700 +f 14604/14604/9855 14235/14235/9533 14599/14599/9851 +f 14604/14604/9855 14599/14599/9851 14605/14605/9856 +f 14606/14606/9857 14602/14602/9851 14603/14603/9854 +f 14606/14606/9857 14603/14603/9854 14607/14607/9858 +f 14424/14424/9700 14606/14606/9857 14607/14607/9858 +f 14424/14424/9700 14607/14607/9858 14425/14425/9702 +f 14552/14552/9812 14608/14608/9859 14609/14609/9860 +f 14552/14552/9812 14609/14609/9860 14553/14553/9813 +f 14608/14608/9859 14590/14590/9844 14593/14593/9847 +f 14608/14608/9859 14593/14593/9847 14609/14609/9860 +f 14610/14610/9861 14596/14596/9847 14597/14597/9849 +f 14610/14610/9861 14597/14597/9849 14611/14611/9862 +f 14555/14555/9813 14610/14610/9861 14611/14611/9862 +f 14555/14555/9813 14611/14611/9862 14556/14556/9814 +f 14572/14572/9827 14612/14612/9863 14613/14613/9864 +f 14572/14572/9827 14613/14613/9864 14573/14573/9828 +f 14612/14612/9863 14614/14614/9865 14615/14615/9866 +f 14612/14612/9863 14615/14615/9866 14613/14613/9864 +f 14616/14616/9867 14617/14617/9866 14618/14618/9868 +f 14616/14616/9867 14618/14618/9868 14619/14619/9869 +f 14575/14575/9829 14616/14616/9867 14619/14619/9869 +f 14575/14575/9829 14619/14619/9869 14576/14576/9830 +f 14620/14620/9870 14621/14621/9871 14622/14622/9872 +f 14620/14620/9870 14622/14622/9872 14623/14623/9873 +f 14621/14621/9871 14624/14624/9874 14625/14625/9875 +f 14621/14621/9871 14625/14625/9875 14622/14622/9872 +f 14626/14626/9872 14627/14627/9875 14307/14307/9602 +f 14626/14626/9872 14307/14307/9602 14306/14306/9601 +f 14628/14628/9876 14626/14626/9872 14306/14306/9601 +f 14628/14628/9876 14306/14306/9601 14305/14305/9600 +f 14432/14432/9707 14629/14629/9877 14630/14630/9878 +f 14432/14432/9707 14630/14630/9878 14433/14433/9708 +f 14629/14629/9877 14255/14255/9553 14631/14631/9879 +f 14629/14629/9877 14631/14631/9879 14630/14630/9878 +f 14632/14632/9878 14633/14633/9879 14634/14634/9880 +f 14632/14632/9878 14634/14634/9880 14635/14635/9881 +f 14436/14436/9708 14632/14632/9878 14635/14635/9881 +f 14436/14436/9708 14635/14635/9881 14437/14437/9709 +f 14480/14480/9747 14636/14636/9882 14637/14637/9883 +f 14480/14480/9747 14637/14637/9883 14481/14481/9748 +f 14636/14636/9882 14638/14638/9884 14639/14639/9885 +f 14636/14636/9882 14639/14639/9885 14637/14637/9883 +f 14640/14640/9883 14641/14641/9885 14280/14280/9575 +f 14640/14640/9883 14280/14280/9575 14279/14279/9574 +f 14483/14483/9749 14640/14640/9883 14279/14279/9574 +f 14483/14483/9749 14279/14279/9574 14274/14274/9569 +f 14638/14638/9884 14642/14642/9886 14643/14643/9887 +f 14638/14638/9884 14643/14643/9887 14639/14639/9885 +f 14642/14642/9886 14644/14644/9888 14645/14645/9889 +f 14642/14642/9886 14645/14645/9889 14643/14643/9887 +f 14646/14646/9890 14647/14647/9891 14286/14286/9581 +f 14646/14646/9890 14286/14286/9581 14285/14285/9580 +f 14641/14641/9885 14646/14646/9890 14285/14285/9580 +f 14641/14641/9885 14285/14285/9580 14280/14280/9575 +f 14644/14644/9888 14648/14648/9892 14649/14649/9893 +f 14644/14644/9888 14649/14649/9893 14645/14645/9889 +f 14648/14648/9892 14650/14650/9894 14651/14651/9895 +f 14648/14648/9892 14651/14651/9895 14649/14649/9893 +f 14652/14652/9896 14653/14653/9895 14292/14292/9587 +f 14652/14652/9896 14292/14292/9587 14291/14291/9586 +f 14647/14647/9891 14652/14652/9896 14291/14291/9586 +f 14647/14647/9891 14291/14291/9586 14286/14286/9581 +f 14624/14624/9874 14654/14654/9897 14655/14655/9898 +f 14624/14624/9874 14655/14655/9898 14625/14625/9875 +f 14654/14654/9897 14656/14656/9899 14657/14657/9900 +f 14654/14654/9897 14657/14657/9900 14655/14655/9898 +f 14658/14658/9898 14659/14659/9901 14260/14260/9558 +f 14658/14658/9898 14260/14260/9558 14327/14327/9619 +f 14627/14627/9875 14658/14658/9898 14327/14327/9619 +f 14627/14627/9875 14327/14327/9619 14307/14307/9602 +f 14185/14185/9486 14193/14193/9494 14660/14660/9902 +f 14185/14185/9486 14660/14660/9902 14565/14565/9821 +f 14193/14193/9494 14192/14192/9493 14514/14514/9776 +f 14193/14193/9494 14514/14514/9776 14660/14660/9902 +f 14661/14661/9902 14520/14520/9782 14521/14521/9783 +f 14661/14661/9902 14521/14521/9783 14662/14662/9903 +f 14567/14567/9822 14661/14661/9902 14662/14662/9903 +f 14567/14567/9822 14662/14662/9903 14568/14568/9823 +f 14198/14198/9499 14205/14205/9506 14663/14663/9904 +f 14198/14198/9499 14663/14663/9904 14515/14515/9777 +f 14205/14205/9506 14204/14204/9505 14664/14664/9905 +f 14205/14205/9506 14664/14664/9905 14663/14663/9904 +f 14665/14665/9906 14666/14666/9907 14667/14667/9908 +f 14665/14665/9906 14667/14667/9908 14668/14668/9909 +f 14517/14517/9779 14665/14665/9906 14668/14668/9909 +f 14517/14517/9779 14668/14668/9909 14518/14518/9780 +f 14650/14650/9894 14669/14669/9910 14670/14670/9911 +f 14650/14650/9894 14670/14670/9911 14651/14651/9895 +f 14669/14669/9910 14671/14671/9912 14672/14672/9913 +f 14669/14669/9910 14672/14672/9913 14670/14670/9911 +f 14673/14673/9914 14674/14674/9915 14298/14298/9593 +f 14673/14673/9914 14298/14298/9593 14297/14297/9592 +f 14653/14653/9895 14673/14673/9914 14297/14297/9592 +f 14653/14653/9895 14297/14297/9592 14292/14292/9587 +f 14204/14204/9505 14211/14211/9512 14675/14675/9916 +f 14204/14204/9505 14675/14675/9916 14664/14664/9905 +f 14211/14211/9512 14210/14210/9511 14676/14676/9917 +f 14211/14211/9512 14676/14676/9917 14675/14675/9916 +f 14677/14677/9916 14678/14678/9917 14679/14679/9918 +f 14677/14677/9916 14679/14679/9918 14680/14680/9919 +f 14666/14666/9907 14677/14677/9916 14680/14680/9919 +f 14666/14666/9907 14680/14680/9919 14667/14667/9908 +f 14681/14681/9920 14682/14682/9921 14683/14683/9922 +f 14681/14681/9920 14683/14683/9922 14684/14684/9687 +f 14682/14682/9921 14685/14685/9923 14686/14686/9924 +f 14682/14682/9921 14686/14686/9924 14683/14683/9922 +f 14687/14687/9925 14688/14688/9926 14689/14689/9927 +f 14687/14687/9925 14689/14689/9927 14690/14690/9928 +f 14408/14408/9687 14687/14687/9925 14690/14690/9928 +f 14408/14408/9687 14690/14690/9928 14409/14409/9689 +f 14691/14691/9929 14692/14692/9930 14693/14693/9931 +f 14691/14691/9929 14693/14693/9931 14694/14694/9932 +f 14692/14692/9930 14620/14620/9870 14623/14623/9873 +f 14692/14692/9930 14623/14623/9873 14693/14693/9931 +f 14695/14695/9931 14628/14628/9876 14305/14305/9600 +f 14695/14695/9931 14305/14305/9600 14317/14317/9610 +f 14696/14696/9933 14697/14697/9931 14315/14315/9610 +f 14696/14696/9933 14315/14315/9610 14314/14314/9609 +f 14698/14698/9934 14699/14699/9935 14700/14700/9936 +f 14698/14698/9934 14700/14700/9936 14701/14701/9937 +f 14699/14699/9935 14702/14702/9938 14703/14703/9939 +f 14699/14699/9935 14703/14703/9939 14700/14700/9936 +f 14700/14700/9936 14703/14703/9939 14704/14704/9940 +f 14700/14700/9936 14704/14704/9940 14705/14705/9941 +f 14701/14701/9937 14700/14700/9936 14705/14705/9941 +f 14701/14701/9937 14705/14705/9941 14706/14706/9942 +f 14582/14582/9836 14707/14707/9943 14708/14708/9944 +f 14582/14582/9836 14708/14708/9944 14583/14583/9837 +f 14707/14707/9943 14709/14709/9945 14710/14710/9946 +f 14707/14707/9943 14710/14710/9946 14708/14708/9944 +f 14711/14711/9947 14712/14712/9948 14713/14713/9949 +f 14711/14711/9947 14713/14713/9949 14714/14714/9950 +f 14585/14585/9839 14715/14715/9944 14716/14716/9950 +f 14585/14585/9839 14716/14716/9950 14586/14586/9840 +f 14255/14255/9553 14254/14254/9552 14717/14717/9951 +f 14255/14255/9553 14717/14717/9951 14631/14631/9879 +f 14254/14254/9552 14250/14250/9548 14440/14440/9712 +f 14254/14254/9552 14440/14440/9712 14717/14717/9951 +f 14718/14718/9952 14446/14446/9718 14447/14447/9719 +f 14718/14718/9952 14447/14447/9719 14719/14719/9953 +f 14633/14633/9879 14718/14718/9952 14719/14719/9953 +f 14633/14633/9879 14719/14719/9953 14634/14634/9880 +f 14709/14709/9945 14720/14720/9954 14721/14721/9955 +f 14709/14709/9945 14721/14721/9955 14710/14710/9946 +f 14720/14720/9954 14722/14722/9956 14723/14723/9957 +f 14720/14720/9954 14723/14723/9957 14721/14721/9955 +f 14724/14724/9958 14725/14725/9959 14343/14343/9635 +f 14724/14724/9958 14343/14343/9635 14726/14726/9960 +f 14712/14712/9948 14724/14724/9958 14726/14726/9960 +f 14712/14712/9948 14726/14726/9960 14713/14713/9949 +f 14722/14722/9956 14727/14727/9961 14728/14728/9962 +f 14722/14722/9956 14728/14728/9962 14723/14723/9957 +f 14727/14727/9961 14729/14729/9963 14730/14730/9964 +f 14727/14727/9961 14730/14730/9964 14728/14728/9962 +f 14731/14731/9962 14732/14732/9964 14335/14335/9627 +f 14731/14731/9962 14335/14335/9627 14344/14344/9636 +f 14725/14725/9959 14731/14731/9962 14344/14344/9636 +f 14725/14725/9959 14344/14344/9636 14343/14343/9635 +f 14218/14218/9519 14238/14238/9536 14733/14733/9965 +f 14218/14218/9519 14733/14733/9965 14559/14559/9817 +f 14238/14238/9536 14178/14178/9479 14413/14413/9693 +f 14238/14238/9536 14413/14413/9693 14733/14733/9965 +f 14734/14734/9966 14417/14417/9693 14418/14418/9696 +f 14734/14734/9966 14418/14418/9696 14735/14735/9967 +f 14561/14561/9817 14734/14734/9966 14735/14735/9967 +f 14561/14561/9817 14735/14735/9967 14562/14562/9818 +f 14685/14685/9923 14736/14736/9968 14737/14737/9969 +f 14685/14685/9923 14737/14737/9969 14686/14686/9924 +f 14736/14736/9968 14738/14738/9970 14739/14739/9971 +f 14736/14736/9968 14739/14739/9971 14737/14737/9969 +f 14740/14740/9969 14741/14741/9972 14323/14323/9615 +f 14740/14740/9969 14323/14323/9615 14742/14742/9973 +f 14688/14688/9926 14740/14740/9969 14742/14742/9973 +f 14688/14688/9926 14742/14742/9973 14689/14689/9927 +f 14729/14729/9963 14743/14743/9974 14744/14744/9975 +f 14729/14729/9963 14744/14744/9975 14730/14730/9964 +f 14743/14743/9974 14745/14745/9976 14746/14746/9977 +f 14743/14743/9974 14746/14746/9977 14744/14744/9975 +f 14747/14747/9975 14748/14748/9978 14337/14337/9629 +f 14747/14747/9975 14337/14337/9629 14336/14336/9628 +f 14732/14732/9964 14747/14747/9975 14336/14336/9628 +f 14732/14732/9964 14336/14336/9628 14335/14335/9627 +f 14738/14738/9970 14749/14749/9979 14750/14750/9980 +f 14738/14738/9970 14750/14750/9980 14739/14739/9971 +f 14749/14749/9979 14691/14691/9929 14694/14694/9932 +f 14749/14749/9979 14694/14694/9932 14750/14750/9980 +f 14751/14751/9981 14696/14696/9933 14314/14314/9609 +f 14751/14751/9981 14314/14314/9609 14324/14324/9616 +f 14741/14741/9972 14751/14751/9981 14324/14324/9616 +f 14741/14741/9972 14324/14324/9616 14323/14323/9615 +f 14526/14526/9788 14752/14752/9982 14753/14753/9983 +f 14526/14526/9788 14753/14753/9983 14527/14527/9789 +f 14752/14752/9982 14578/14578/9832 14581/14581/9835 +f 14752/14752/9982 14581/14581/9835 14753/14753/9983 +f 14754/14754/9983 14588/14588/9842 14589/14589/9843 +f 14754/14754/9983 14589/14589/9843 14755/14755/9984 +f 14529/14529/9789 14754/14754/9983 14755/14755/9984 +f 14529/14529/9789 14755/14755/9984 14530/14530/9790 +f 14614/14614/9865 14756/14756/9985 14757/14757/9986 +f 14614/14614/9865 14757/14757/9986 14615/14615/9866 +f 14756/14756/9985 14522/14522/9784 14525/14525/9787 +f 14756/14756/9985 14525/14525/9787 14757/14757/9986 +f 14758/14758/9987 14759/14759/9988 14760/14760/9989 +f 14758/14758/9987 14760/14760/9989 14761/14761/9990 +f 14617/14617/9866 14758/14758/9987 14761/14761/9990 +f 14617/14617/9866 14761/14761/9990 14618/14618/9868 +f 14656/14656/9899 14762/14762/9991 14763/14763/9992 +f 14656/14656/9899 14763/14763/9992 14657/14657/9900 +f 14762/14762/9991 14764/14764/9993 14765/14765/9994 +f 14762/14762/9991 14765/14765/9994 14763/14763/9992 +f 14766/14766/9995 14767/14767/9996 14264/14264/9560 +f 14766/14766/9995 14264/14264/9560 14263/14263/9559 +f 14659/14659/9901 14768/14768/9992 14261/14261/9559 +f 14659/14659/9901 14261/14261/9559 14260/14260/9558 +f 14620/14620/9870 14692/14692/9930 14769/14769/9997 +f 14620/14620/9870 14769/14769/9997 14770/14770/9998 +f 14692/14692/9930 14691/14691/9929 14771/14771/9999 +f 14692/14692/9930 14771/14771/9999 14769/14769/9997 +f 14769/14769/9997 14771/14771/9999 14389/14389/9672 +f 14769/14769/9997 14389/14389/9672 14387/14387/9671 +f 14770/14770/9998 14769/14769/9997 14387/14387/9671 +f 14770/14770/9998 14387/14387/9671 14386/14386/9670 +f 14526/14526/9788 14523/14523/9785 14772/14772/10000 +f 14526/14526/9788 14772/14772/10000 14773/14773/10001 +f 14523/14523/9785 14522/14522/9784 14774/14774/10002 +f 14523/14523/9785 14774/14774/10002 14772/14772/10000 +f 14772/14772/10000 14774/14774/10002 14367/14367/9655 +f 14772/14772/10000 14367/14367/9655 14365/14365/9653 +f 14773/14773/10001 14772/14772/10000 14365/14365/9653 +f 14773/14773/10001 14365/14365/9653 14364/14364/9652 +f 14614/14614/9865 14612/14612/9863 14775/14775/10003 +f 14614/14614/9865 14775/14775/10003 14776/14776/10004 +f 14612/14612/9863 14572/14572/9827 14777/14777/10005 +f 14612/14612/9863 14777/14777/10005 14775/14775/10003 +f 14775/14775/10003 14777/14777/10005 14556/14556/9814 +f 14775/14775/10003 14556/14556/9814 14611/14611/9862 +f 14776/14776/10004 14775/14775/10003 14611/14611/9862 +f 14776/14776/10004 14611/14611/9862 14597/14597/9849 +f 14624/14624/9874 14621/14621/9871 14778/14778/10006 +f 14624/14624/9874 14778/14778/10006 14779/14779/10007 +f 14621/14621/9871 14620/14620/9870 14770/14770/9998 +f 14621/14621/9871 14770/14770/9998 14778/14778/10006 +f 14778/14778/10006 14770/14770/9998 14386/14386/9670 +f 14778/14778/10006 14386/14386/9670 14563/14563/9819 +f 14779/14779/10007 14778/14778/10006 14563/14563/9819 +f 14779/14779/10007 14563/14563/9819 14562/14562/9818 +f 14480/14480/9747 14477/14477/9744 14780/14780/10008 +f 14480/14480/9747 14780/14780/10008 14781/14781/10009 +f 14477/14477/9744 14476/14476/9743 14782/14782/10010 +f 14477/14477/9744 14782/14782/10010 14780/14780/10008 +f 14780/14780/10008 14782/14782/10010 14350/14350/9641 +f 14780/14780/10008 14350/14350/9641 14569/14569/9824 +f 14781/14781/10009 14780/14780/10008 14569/14569/9824 +f 14781/14781/10009 14569/14569/9824 14568/14568/9823 +f 14638/14638/9884 14636/14636/9882 14783/14783/10011 +f 14638/14638/9884 14783/14783/10011 14784/14784/10012 +f 14636/14636/9882 14480/14480/9747 14781/14781/10009 +f 14636/14636/9882 14781/14781/10009 14783/14783/10011 +f 14783/14783/10011 14781/14781/10009 14568/14568/9823 +f 14783/14783/10011 14568/14568/9823 14662/14662/9903 +f 14784/14784/10012 14783/14783/10011 14662/14662/9903 +f 14784/14784/10012 14662/14662/9903 14521/14521/9783 +f 14572/14572/9827 14570/14570/9825 14785/14785/10013 +f 14572/14572/9827 14785/14785/10013 14777/14777/10005 +f 14570/14570/9825 14536/14536/9796 14786/14786/10014 +f 14570/14570/9825 14786/14786/10014 14785/14785/10013 +f 14785/14785/10013 14786/14786/10014 14548/14548/9808 +f 14785/14785/10013 14548/14548/9808 14557/14557/9815 +f 14777/14777/10005 14785/14785/10013 14557/14557/9815 +f 14777/14777/10005 14557/14557/9815 14556/14556/9814 +f 14536/14536/9796 14534/14534/9794 14787/14787/10015 +f 14536/14536/9796 14787/14787/10015 14786/14786/10014 +f 14534/14534/9794 14499/14499/9764 14788/14788/10016 +f 14534/14534/9794 14788/14788/10016 14787/14787/10015 +f 14787/14787/10015 14788/14788/10016 14511/14511/9773 +f 14787/14787/10015 14511/14511/9773 14549/14549/9809 +f 14786/14786/10014 14787/14787/10015 14549/14549/9809 +f 14786/14786/10014 14549/14549/9809 14548/14548/9808 +f 14650/14650/9894 14648/14648/9892 14789/14789/10017 +f 14650/14650/9894 14789/14789/10017 14790/14790/10018 +f 14648/14648/9892 14644/14644/9888 14791/14791/10019 +f 14648/14648/9892 14791/14791/10019 14789/14789/10017 +f 14789/14789/10017 14791/14791/10019 14518/14518/9780 +f 14789/14789/10017 14518/14518/9780 14668/14668/9909 +f 14790/14790/10018 14789/14789/10017 14668/14668/9909 +f 14790/14790/10018 14668/14668/9909 14667/14667/9908 +f 14656/14656/9899 14654/14654/9897 14792/14792/10020 +f 14656/14656/9899 14792/14792/10020 14793/14793/10021 +f 14654/14654/9897 14624/14624/9874 14779/14779/10007 +f 14654/14654/9897 14779/14779/10007 14792/14792/10020 +f 14792/14792/10020 14779/14779/10007 14562/14562/9818 +f 14792/14792/10020 14562/14562/9818 14735/14735/9967 +f 14793/14793/10021 14792/14792/10020 14735/14735/9967 +f 14793/14793/10021 14735/14735/9967 14418/14418/9696 +f 14644/14644/9888 14642/14642/9886 14794/14794/10022 +f 14644/14644/9888 14794/14794/10022 14791/14791/10019 +f 14642/14642/9886 14638/14638/9884 14784/14784/10012 +f 14642/14642/9886 14784/14784/10012 14794/14794/10022 +f 14794/14794/10022 14784/14784/10012 14521/14521/9783 +f 14794/14794/10022 14521/14521/9783 14519/14519/9781 +f 14791/14791/10019 14794/14794/10022 14519/14519/9781 +f 14791/14791/10019 14519/14519/9781 14518/14518/9780 +f 14499/14499/9764 14497/14497/9762 14795/14795/10023 +f 14499/14499/9764 14795/14795/10023 14788/14788/10016 +f 14497/14497/9762 14452/14452/9724 14796/14796/10024 +f 14497/14497/9762 14796/14796/10024 14795/14795/10023 +f 14795/14795/10023 14796/14796/10024 14468/14468/9736 +f 14795/14795/10023 14468/14468/9736 14512/14512/9774 +f 14788/14788/10016 14795/14795/10023 14512/14512/9774 +f 14788/14788/10016 14512/14512/9774 14511/14511/9773 +f 14671/14671/9912 14669/14669/9910 14797/14797/10025 +f 14671/14671/9912 14797/14797/10025 14798/14798/10026 +f 14669/14669/9910 14650/14650/9894 14790/14790/10018 +f 14669/14669/9910 14790/14790/10018 14797/14797/10025 +f 14797/14797/10025 14790/14790/10018 14667/14667/9908 +f 14797/14797/10025 14667/14667/9908 14680/14680/9919 +f 14798/14798/10026 14797/14797/10025 14680/14680/9919 +f 14798/14798/10026 14680/14680/9919 14679/14679/9918 +f 14452/14452/9724 14449/14449/9721 14799/14799/10027 +f 14452/14452/9724 14799/14799/10027 14796/14796/10024 +f 14449/14449/9721 14448/14448/9720 14800/14800/10028 +f 14449/14449/9721 14800/14800/10028 14799/14799/10027 +f 14799/14799/10027 14800/14800/10028 14471/14471/9739 +f 14799/14799/10027 14471/14471/9739 14469/14469/9737 +f 14796/14796/10024 14799/14799/10027 14469/14469/9737 +f 14796/14796/10024 14469/14469/9737 14468/14468/9736 +f 14685/14685/9923 14682/14682/9921 14801/14801/10029 +f 14685/14685/9923 14801/14801/10029 14802/14802/10030 +f 14682/14682/9921 14681/14681/9920 14803/14803/10031 +f 14682/14682/9921 14803/14803/10031 14801/14801/10029 +f 14801/14801/10029 14803/14803/10031 14428/14428/9679 +f 14801/14801/10029 14428/14428/9679 14426/14426/9703 +f 14802/14802/10030 14801/14801/10029 14426/14426/9703 +f 14802/14802/10030 14426/14426/9703 14425/14425/9702 +f 14582/14582/9836 14579/14579/9833 14804/14804/10032 +f 14582/14582/9836 14804/14804/10032 14805/14805/10033 +f 14579/14579/9833 14578/14578/9832 14806/14806/10034 +f 14579/14579/9833 14806/14806/10034 14804/14804/10032 +f 14804/14804/10032 14806/14806/10034 14379/14379/9665 +f 14804/14804/10032 14379/14379/9665 14377/14377/9664 +f 14805/14805/10033 14804/14804/10032 14377/14377/9664 +f 14805/14805/10033 14377/14377/9664 14376/14376/9663 +f 14807/14807/10035 14808/14808/10036 14809/14809/10037 +f 14807/14807/10035 14809/14809/10037 14810/14810/10038 +f 14811/14811/10036 14698/14698/9934 14701/14701/9937 +f 14811/14811/10036 14701/14701/9937 14812/14812/10039 +f 14812/14812/10039 14701/14701/9937 14706/14706/9942 +f 14812/14812/10039 14706/14706/9942 14813/14813/10040 +f 14810/14810/10038 14809/14809/10037 14814/14814/10040 +f 14810/14810/10038 14814/14814/10040 14815/14815/10041 +f 14709/14709/9945 14707/14707/9943 14816/14816/10042 +f 14709/14709/9945 14816/14816/10042 14817/14817/10043 +f 14707/14707/9943 14582/14582/9836 14805/14805/10033 +f 14707/14707/9943 14805/14805/10033 14816/14816/10042 +f 14816/14816/10042 14805/14805/10033 14376/14376/9663 +f 14816/14816/10042 14376/14376/9663 14438/14438/9710 +f 14817/14817/10043 14816/14816/10042 14438/14438/9710 +f 14817/14817/10043 14438/14438/9710 14437/14437/9709 +f 14401/14401/9682 14818/14818/10044 14819/14819/10045 +f 14401/14401/9682 14819/14819/10045 14820/14820/10046 +f 14818/14818/10044 14821/14821/10047 14822/14822/10048 +f 14818/14818/10044 14822/14822/10048 14819/14819/10045 +f 14819/14819/10045 14822/14822/10048 14823/14823/9716 +f 14819/14819/10045 14823/14823/9716 14824/14824/10049 +f 14820/14820/10046 14819/14819/10045 14824/14824/10049 +f 14820/14820/10046 14824/14824/10049 14400/14400/9681 +f 14722/14722/9956 14720/14720/9954 14825/14825/10050 +f 14722/14722/9956 14825/14825/10050 14826/14826/10051 +f 14720/14720/9954 14709/14709/9945 14817/14817/10043 +f 14720/14720/9954 14817/14817/10043 14825/14825/10050 +f 14825/14825/10050 14817/14817/10043 14437/14437/9709 +f 14825/14825/10050 14437/14437/9709 14635/14635/9881 +f 14826/14826/10051 14825/14825/10050 14635/14635/9881 +f 14826/14826/10051 14635/14635/9881 14634/14634/9880 +f 14729/14729/9963 14727/14727/9961 14827/14827/10052 +f 14729/14729/9963 14827/14827/10052 14828/14828/10053 +f 14727/14727/9961 14722/14722/9956 14826/14826/10051 +f 14727/14727/9961 14826/14826/10051 14827/14827/10052 +f 14827/14827/10052 14826/14826/10051 14634/14634/9880 +f 14827/14827/10052 14634/14634/9880 14719/14719/9953 +f 14828/14828/10053 14827/14827/10052 14719/14719/9953 +f 14828/14828/10053 14719/14719/9953 14447/14447/9719 +f 14476/14476/9743 14829/14829/10054 14830/14830/10055 +f 14476/14476/9743 14830/14830/10055 14782/14782/10010 +f 14829/14829/10054 14764/14764/9993 14831/14831/10056 +f 14829/14829/10054 14831/14831/10056 14830/14830/10055 +f 14830/14830/10055 14831/14831/10056 14353/14353/9643 +f 14830/14830/10055 14353/14353/9643 14351/14351/9642 +f 14782/14782/10010 14830/14830/10055 14351/14351/9642 +f 14782/14782/10010 14351/14351/9642 14350/14350/9641 +f 14738/14738/9970 14736/14736/9968 14832/14832/10057 +f 14738/14738/9970 14832/14832/10057 14833/14833/10058 +f 14736/14736/9968 14685/14685/9923 14802/14802/10030 +f 14736/14736/9968 14802/14802/10030 14832/14832/10057 +f 14832/14832/10057 14802/14802/10030 14425/14425/9702 +f 14832/14832/10057 14425/14425/9702 14607/14607/9858 +f 14833/14833/10058 14832/14832/10057 14607/14607/9858 +f 14833/14833/10058 14607/14607/9858 14603/14603/9854 +f 14745/14745/9976 14743/14743/9974 14834/14834/10059 +f 14745/14745/9976 14834/14834/10059 14835/14835/10060 +f 14743/14743/9974 14729/14729/9963 14828/14828/10053 +f 14743/14743/9974 14828/14828/10053 14834/14834/10059 +f 14834/14834/10059 14828/14828/10053 14447/14447/9719 +f 14834/14834/10059 14447/14447/9719 14445/14445/9717 +f 14835/14835/10060 14834/14834/10059 14445/14445/9717 +f 14835/14835/10060 14445/14445/9717 14444/14444/9716 +f 14691/14691/9929 14749/14749/9979 14836/14836/10061 +f 14691/14691/9929 14836/14836/10061 14771/14771/9999 +f 14749/14749/9979 14738/14738/9970 14833/14833/10058 +f 14749/14749/9979 14833/14833/10058 14836/14836/10061 +f 14836/14836/10061 14833/14833/10058 14603/14603/9854 +f 14836/14836/10061 14603/14603/9854 14601/14601/9853 +f 14771/14771/9999 14836/14836/10061 14601/14601/9853 +f 14771/14771/9999 14601/14601/9853 14389/14389/9672 +f 14578/14578/9832 14752/14752/9982 14837/14837/10062 +f 14578/14578/9832 14837/14837/10062 14806/14806/10034 +f 14752/14752/9982 14526/14526/9788 14773/14773/10001 +f 14752/14752/9982 14773/14773/10001 14837/14837/10062 +f 14837/14837/10062 14773/14773/10001 14364/14364/9652 +f 14837/14837/10062 14364/14364/9652 14475/14475/9742 +f 14806/14806/10034 14837/14837/10062 14475/14475/9742 +f 14806/14806/10034 14475/14475/9742 14379/14379/9665 +f 14522/14522/9784 14756/14756/9985 14838/14838/10063 +f 14522/14522/9784 14838/14838/10063 14774/14774/10002 +f 14756/14756/9985 14614/14614/9865 14776/14776/10004 +f 14756/14756/9985 14776/14776/10004 14838/14838/10063 +f 14838/14838/10063 14776/14776/10004 14597/14597/9849 +f 14838/14838/10063 14597/14597/9849 14595/14595/9848 +f 14774/14774/10002 14838/14838/10063 14595/14595/9848 +f 14774/14774/10002 14595/14595/9848 14367/14367/9655 +f 14764/14764/9993 14762/14762/9991 14839/14839/10064 +f 14764/14764/9993 14839/14839/10064 14831/14831/10056 +f 14762/14762/9991 14656/14656/9899 14793/14793/10021 +f 14762/14762/9991 14793/14793/10021 14839/14839/10064 +f 14839/14839/10064 14793/14793/10021 14418/14418/9696 +f 14839/14839/10064 14418/14418/9696 14416/14416/9695 +f 14831/14831/10056 14839/14839/10064 14416/14416/9695 +f 14831/14831/10056 14416/14416/9695 14353/14353/9643 +f 14764/14764/9993 14829/14829/10054 14840/14840/10065 +f 14764/14764/9993 14840/14840/10065 14765/14765/9994 +f 14829/14829/10054 14476/14476/9743 14479/14479/9746 +f 14829/14829/10054 14479/14479/9746 14840/14840/10065 +f 14841/14841/10065 14484/14484/9750 14272/14272/9567 +f 14841/14841/10065 14272/14272/9567 14330/14330/9622 +f 14767/14767/9996 14841/14841/10065 14330/14330/9622 +f 14767/14767/9996 14330/14330/9622 14264/14264/9560 +f 14842/14842/10066 14843/14843/10067 14844/14844/10068 +f 14842/14842/10066 14844/14844/10068 14845/14845/10069 +f 14846/14846/10070 14847/14847/10071 14848/14848/10072 +f 14846/14846/10070 14848/14848/10072 14849/14849/10073 +f 14849/14849/10073 14848/14848/10072 14850/14850/10074 +f 14849/14849/10073 14850/14850/10074 14851/14851/10075 +f 14852/14852/10076 14849/14849/10073 14851/14851/10075 +f 14852/14852/10076 14851/14851/10075 14853/14853/10077 +f 14854/14854/9761 14855/14855/9760 14856/14856/10078 +f 14854/14854/9761 14856/14856/10078 14857/14857/10079 +f 14494/14494/9760 14493/14493/9759 14858/14858/10080 +f 14494/14494/9760 14858/14858/10080 14859/14859/10081 +f 14860/14860/10082 14861/14861/10080 14862/14862/10083 +f 14860/14860/10082 14862/14862/10083 14863/14863/10084 +f 14864/14864/10085 14860/14860/10082 14863/14863/10084 +f 14864/14864/10085 14863/14863/10084 14865/14865/10086 +f 14866/14866/10087 14867/14867/10088 14868/14868/10089 +f 14866/14866/10087 14868/14868/10089 14869/14869/10090 +f 14870/14870/10088 14815/14815/10041 14871/14871/10091 +f 14870/14870/10088 14871/14871/10091 14872/14872/10089 +f 14868/14868/10089 14873/14873/10091 14874/14874/10092 +f 14868/14868/10089 14874/14874/10092 14875/14875/10093 +f 14869/14869/10090 14868/14868/10089 14875/14875/10093 +f 14869/14869/10090 14875/14875/10093 14876/14876/10094 +f 14490/14490/9756 14877/14877/10095 14878/14878/10096 +f 14490/14490/9756 14878/14878/10096 14491/14491/9757 +f 14877/14877/10095 14879/14879/10097 14880/14880/10098 +f 14877/14877/10095 14880/14880/10098 14878/14878/10096 +f 14878/14878/10096 14880/14880/10098 14842/14842/10066 +f 14878/14878/10096 14842/14842/10066 14881/14881/10099 +f 14491/14491/9757 14878/14878/10096 14881/14881/10099 +f 14491/14491/9757 14881/14881/10099 14493/14493/9759 +f 14879/14879/10097 14882/14882/10100 14883/14883/10101 +f 14879/14879/10097 14883/14883/10101 14880/14880/10098 +f 14884/14884/10102 14885/14885/10103 14886/14886/10104 +f 14884/14884/10102 14886/14886/10104 14887/14887/10105 +f 14888/14888/10105 14889/14889/10106 14847/14847/10071 +f 14888/14888/10105 14847/14847/10071 14846/14846/10070 +f 14880/14880/10098 14883/14883/10101 14843/14843/10067 +f 14880/14880/10098 14843/14843/10067 14842/14842/10066 +f 14890/14890/10107 14891/14891/10108 14892/14892/10109 +f 14890/14890/10107 14892/14892/10109 14893/14893/10110 +f 14891/14891/10108 14807/14807/10035 14810/14810/10038 +f 14891/14891/10108 14810/14810/10038 14892/14892/10109 +f 14892/14892/10109 14810/14810/10038 14815/14815/10041 +f 14892/14892/10109 14815/14815/10041 14870/14870/10088 +f 14893/14893/10110 14892/14892/10109 14870/14870/10088 +f 14893/14893/10110 14870/14870/10088 14894/14894/10111 +f 14702/14702/9938 14895/14895/10112 14896/14896/10113 +f 14702/14702/9938 14896/14896/10113 14703/14703/9939 +f 14897/14897/10114 14898/14898/10115 14899/14899/10116 +f 14897/14897/10114 14899/14899/10116 14900/14900/10117 +f 14900/14900/10117 14899/14899/10116 14901/14901/10118 +f 14900/14900/10117 14901/14901/10118 14902/14902/10119 +f 14703/14703/9939 14896/14896/10113 14903/14903/10120 +f 14703/14703/9939 14903/14903/10120 14704/14704/9940 +f 14904/14904/10121 14905/14905/10122 14906/14906/10123 +f 14904/14904/10121 14906/14906/10123 14907/14907/10124 +f 14905/14905/10122 14485/14485/9751 14488/14488/9754 +f 14905/14905/10122 14488/14488/9754 14906/14906/10123 +f 14906/14906/10123 14488/14488/9754 14496/14496/9761 +f 14906/14906/10123 14496/14496/9761 14908/14908/10125 +f 14907/14907/10124 14906/14906/10123 14908/14908/10125 +f 14907/14907/10124 14908/14908/10125 14909/14909/10126 +f 14876/14876/10094 14875/14875/10093 14910/14910/10127 +f 14876/14876/10094 14910/14910/10127 14911/14911/10128 +f 14875/14875/10093 14874/14874/10092 14912/14912/10129 +f 14875/14875/10093 14912/14912/10129 14910/14910/10127 +f 14910/14910/10127 14912/14912/10129 14913/14913/10130 +f 14910/14910/10127 14913/14913/10130 14914/14914/10131 +f 14911/14911/10128 14910/14910/10127 14914/14914/10131 +f 14911/14911/10128 14914/14914/10131 14915/14915/10132 +f 14916/14916/10133 14917/14917/10134 14918/14918/10135 +f 14916/14916/10133 14918/14918/10135 14919/14919/10136 +f 14917/14917/10134 14920/14920/10137 14921/14921/10138 +f 14917/14917/10134 14921/14921/10138 14918/14918/10135 +f 14918/14918/10135 14921/14921/10138 14922/14922/10139 +f 14918/14918/10135 14922/14922/10139 14923/14923/10140 +f 14919/14919/10136 14918/14918/10135 14923/14923/10140 +f 14919/14919/10136 14923/14923/10140 14924/14924/10141 +f 14916/14916/10133 14925/14925/10142 14926/14926/10143 +f 14916/14916/10133 14926/14926/10143 14927/14927/10144 +f 14925/14925/10142 14862/14862/10083 14928/14928/10145 +f 14925/14925/10142 14928/14928/10145 14926/14926/10143 +f 14926/14926/10143 14928/14928/10145 14929/14929/10146 +f 14926/14926/10143 14929/14929/10146 14930/14930/10147 +f 14927/14927/10144 14926/14926/10143 14930/14930/10147 +f 14927/14927/10144 14930/14930/10147 14931/14931/10148 +f 14706/14706/9942 14705/14705/9941 14932/14932/10149 +f 14706/14706/9942 14932/14932/10149 14933/14933/10150 +f 14705/14705/9941 14704/14704/9940 14934/14934/10151 +f 14705/14705/9941 14934/14934/10151 14932/14932/10149 +f 14932/14932/10149 14934/14934/10151 14935/14935/10137 +f 14932/14932/10149 14935/14935/10137 14936/14936/10152 +f 14933/14933/10150 14932/14932/10149 14936/14936/10152 +f 14933/14933/10150 14936/14936/10152 14937/14937/10153 +f 14938/14938/10126 14939/14939/10154 14940/14940/10155 +f 14938/14938/10126 14940/14940/10155 14941/14941/10156 +f 14939/14939/10154 14854/14854/9761 14857/14857/10079 +f 14939/14939/10154 14857/14857/10079 14940/14940/10155 +f 14940/14940/10155 14857/14857/10079 14942/14942/10086 +f 14940/14940/10155 14942/14942/10086 14943/14943/10157 +f 14941/14941/10156 14940/14940/10155 14943/14943/10157 +f 14941/14941/10156 14943/14943/10157 14944/14944/10158 +f 14815/14815/10041 14814/14814/10040 14945/14945/10159 +f 14815/14815/10041 14945/14945/10159 14871/14871/10091 +f 14813/14813/10040 14706/14706/9942 14933/14933/10150 +f 14813/14813/10040 14933/14933/10150 14946/14946/10160 +f 14946/14946/10160 14933/14933/10150 14937/14937/10153 +f 14946/14946/10160 14937/14937/10153 14947/14947/10161 +f 14873/14873/10091 14948/14948/10162 14912/14912/10129 +f 14873/14873/10091 14912/14912/10129 14874/14874/10092 +f 14704/14704/9940 14903/14903/10120 14949/14949/10163 +f 14704/14704/9940 14949/14949/10163 14934/14934/10151 +f 14902/14902/10119 14901/14901/10118 14950/14950/10164 +f 14902/14902/10119 14950/14950/10164 14951/14951/10165 +f 14951/14951/10165 14950/14950/10164 14922/14922/10139 +f 14951/14951/10165 14922/14922/10139 14921/14921/10138 +f 14952/14952/10151 14951/14951/10165 14921/14921/10138 +f 14952/14952/10151 14921/14921/10138 14920/14920/10137 +f 14493/14493/9759 14881/14881/10099 14953/14953/10166 +f 14493/14493/9759 14953/14953/10166 14858/14858/10080 +f 14881/14881/10099 14842/14842/10066 14845/14845/10069 +f 14881/14881/10099 14845/14845/10069 14953/14953/10166 +f 14953/14953/10166 14845/14845/10069 14954/14954/10146 +f 14953/14953/10166 14954/14954/10146 14955/14955/10167 +f 14861/14861/10080 14956/14956/10168 14928/14928/10145 +f 14861/14861/10080 14928/14928/10145 14862/14862/10083 +f 14957/14957/10169 14958/14958/10170 14959/14959/10171 +f 14957/14957/10169 14959/14959/10171 14960/14960/10172 +f 14958/14958/10170 14961/14961/10173 14962/14962/10174 +f 14958/14958/10170 14962/14962/10174 14959/14959/10171 +f 14959/14959/10171 14962/14962/10174 14485/14485/9751 +f 14959/14959/10171 14485/14485/9751 14905/14905/10122 +f 14960/14960/10172 14959/14959/10171 14905/14905/10122 +f 14960/14960/10172 14905/14905/10122 14904/14904/10121 +f 14963/14963/10175 14964/14964/10176 14965/14965/10177 +f 14963/14963/10175 14965/14965/10177 14966/14966/10178 +f 14967/14967/10179 14968/14968/10180 14969/14969/10181 +f 14967/14967/10179 14969/14969/10181 14970/14970/10182 +f 14970/14970/10182 14969/14969/10181 14898/14898/10115 +f 14970/14970/10182 14898/14898/10115 14897/14897/10114 +f 14966/14966/10178 14965/14965/10177 14895/14895/10112 +f 14966/14966/10178 14895/14895/10112 14702/14702/9938 +f 14971/14971/10183 14972/14972/10184 14973/14973/10185 +f 14971/14971/10183 14973/14973/10185 14974/14974/10186 +f 14972/14972/10184 14975/14975/10187 14976/14976/10188 +f 14972/14972/10184 14976/14976/10188 14973/14973/10185 +f 14973/14973/10185 14976/14976/10188 14807/14807/10035 +f 14973/14973/10185 14807/14807/10035 14891/14891/10108 +f 14974/14974/10186 14973/14973/10185 14891/14891/10108 +f 14974/14974/10186 14891/14891/10108 14890/14890/10107 +f 14977/14977/10189 14978/14978/10190 14979/14979/10191 +f 14977/14977/10189 14979/14979/10191 14980/14980/10192 +f 14981/14981/10190 14982/14982/10193 14983/14983/10194 +f 14981/14981/10190 14983/14983/10194 14984/14984/10195 +f 14984/14984/10195 14983/14983/10194 14885/14885/10103 +f 14984/14984/10195 14885/14885/10103 14884/14884/10102 +f 14980/14980/10192 14979/14979/10191 14882/14882/10100 +f 14980/14980/10192 14882/14882/10100 14879/14879/10097 +f 14985/14985/10196 14986/14986/10197 14987/14987/10198 +f 14985/14985/10196 14987/14987/10198 14988/14988/10199 +f 14986/14986/10197 14977/14977/10189 14980/14980/10192 +f 14986/14986/10197 14980/14980/10192 14987/14987/10198 +f 14987/14987/10198 14980/14980/10192 14879/14879/10097 +f 14987/14987/10198 14879/14879/10097 14877/14877/10095 +f 14988/14988/10199 14987/14987/10198 14877/14877/10095 +f 14988/14988/10199 14877/14877/10095 14490/14490/9756 +f 14975/14975/10187 14989/14989/10200 14990/14990/10201 +f 14975/14975/10187 14990/14990/10201 14976/14976/10188 +f 14991/14991/10200 14992/14992/10202 14993/14993/10203 +f 14991/14991/10200 14993/14993/10203 14994/14994/10204 +f 14994/14994/10204 14993/14993/10203 14698/14698/9934 +f 14994/14994/10204 14698/14698/9934 14811/14811/10036 +f 14976/14976/10188 14990/14990/10201 14808/14808/10036 +f 14976/14976/10188 14808/14808/10036 14807/14807/10035 +f 14992/14992/10202 14995/14995/10205 14996/14996/10206 +f 14992/14992/10202 14996/14996/10206 14993/14993/10203 +f 14995/14995/10205 14963/14963/10175 14966/14966/10178 +f 14995/14995/10205 14966/14966/10178 14996/14996/10206 +f 14996/14996/10206 14966/14966/10178 14702/14702/9938 +f 14996/14996/10206 14702/14702/9938 14699/14699/9935 +f 14993/14993/10203 14996/14996/10206 14699/14699/9935 +f 14993/14993/10203 14699/14699/9935 14698/14698/9934 +f 14961/14961/10173 14997/14997/10207 14998/14998/10208 +f 14961/14961/10173 14998/14998/10208 14962/14962/10174 +f 14999/14999/10209 14985/14985/10196 14988/14988/10199 +f 14999/14999/10209 14988/14988/10199 15000/15000/10210 +f 15000/15000/10210 14988/14988/10199 14490/14490/9756 +f 15000/15000/10210 14490/14490/9756 14489/14489/9755 +f 14962/14962/10174 14998/14998/10208 14486/14486/9752 +f 14962/14962/10174 14486/14486/9752 14485/14485/9751 +f 15001/15001/10211 15002/15002/10212 15003/15003/10213 +f 15001/15001/10211 15003/15003/10213 15004/15004/10214 +f 15005/15005/10212 15006/15006/10215 15007/15007/10216 +f 15005/15005/10212 15007/15007/10216 15008/15008/10217 +f 15008/15008/10217 15007/15007/10216 15009/15009/10218 +f 15008/15008/10217 15009/15009/10218 15010/15010/10219 +f 15004/15004/10214 15003/15003/10213 15011/15011/10220 +f 15004/15004/10214 15011/15011/10220 15012/15012/10221 +f 15013/15013/10222 15014/15014/10223 15015/15015/10224 +f 15013/15013/10222 15015/15015/10224 15016/15016/10225 +f 15014/15014/10223 15017/15017/10226 15018/15018/10227 +f 15014/15014/10223 15018/15018/10227 15015/15015/10224 +f 15015/15015/10224 15018/15018/10227 15019/15019/10228 +f 15015/15015/10224 15019/15019/10228 15020/15020/10229 +f 15016/15016/10225 15015/15015/10224 15020/15020/10229 +f 15016/15016/10225 15020/15020/10229 15021/15021/10230 +f 15022/15022/10231 15023/15023/10232 15024/15024/10233 +f 15022/15022/10231 15024/15024/10233 15025/15025/10234 +f 15026/15026/10235 15013/15013/10222 15016/15016/10225 +f 15026/15026/10235 15016/15016/10225 15027/15027/10236 +f 15027/15027/10236 15016/15016/10225 15021/15021/10230 +f 15027/15027/10236 15021/15021/10230 15028/15028/10237 +f 15025/15025/10234 15024/15024/10233 15029/15029/10237 +f 15025/15025/10234 15029/15029/10237 15030/15030/10238 +f 15006/15006/10215 15031/15031/10239 15032/15032/10240 +f 15006/15006/10215 15032/15032/10240 15007/15007/10216 +f 15031/15031/10239 15033/15033/10241 15034/15034/10242 +f 15031/15031/10239 15034/15034/10242 15032/15032/10240 +f 15032/15032/10240 15034/15034/10242 15035/15035/10243 +f 15032/15032/10240 15035/15035/10243 15036/15036/10244 +f 15007/15007/10216 15032/15032/10240 15036/15036/10244 +f 15007/15007/10216 15036/15036/10244 15009/15009/10218 +f 15033/15033/10241 15037/15037/10245 15038/15038/10246 +f 15033/15033/10241 15038/15038/10246 15034/15034/10242 +f 15039/15039/10245 15040/15040/10247 15041/15041/10248 +f 15039/15039/10245 15041/15041/10248 15042/15042/10246 +f 15042/15042/10246 15041/15041/10248 15043/15043/10249 +f 15042/15042/10246 15043/15043/10249 15044/15044/10250 +f 15034/15034/10242 15038/15038/10246 15045/15045/10251 +f 15034/15034/10242 15045/15045/10251 15035/15035/10243 +f 15046/15046/10252 15047/15047/10253 15048/15048/10254 +f 15046/15046/10252 15048/15048/10254 15049/15049/10255 +f 15047/15047/10253 15022/15022/10231 15025/15025/10234 +f 15047/15047/10253 15025/15025/10234 15048/15048/10254 +f 15048/15048/10254 15025/15025/10234 15030/15030/10238 +f 15048/15048/10254 15030/15030/10238 15050/15050/10256 +f 15049/15049/10255 15048/15048/10254 15050/15050/10256 +f 15049/15049/10255 15050/15050/10256 15051/15051/10257 +f 15017/15017/10226 15052/15052/10258 15053/15053/10259 +f 15017/15017/10226 15053/15053/10259 15018/15018/10227 +f 15054/15054/10260 15055/15055/10261 15056/15056/10262 +f 15054/15054/10260 15056/15056/10262 15057/15057/10259 +f 15057/15057/10259 15056/15056/10262 15058/15058/10263 +f 15057/15057/10259 15058/15058/10263 15059/15059/10264 +f 15018/15018/10227 15053/15053/10259 15060/15060/10265 +f 15018/15018/10227 15060/15060/10265 15019/15019/10228 +f 15061/15061/10266 15062/15062/10267 15063/15063/10268 +f 15061/15061/10266 15063/15063/10268 15064/15064/10269 +f 15062/15062/10267 15001/15001/10211 15004/15004/10214 +f 15062/15062/10267 15004/15004/10214 15063/15063/10268 +f 15063/15063/10268 15004/15004/10214 15012/15012/10221 +f 15063/15063/10268 15012/15012/10221 15065/15065/10270 +f 15064/15064/10269 15063/15063/10268 15065/15065/10270 +f 15064/15064/10269 15065/15065/10270 15066/15066/10271 +f 15067/15067/10272 15068/15068/10273 15069/15069/10274 +f 15067/15067/10272 15069/15069/10274 15070/15070/10275 +f 15071/15071/10276 15072/15072/10277 15073/15073/10278 +f 15071/15071/10276 15073/15073/10278 15074/15074/10279 +f 15075/15075/10280 15076/15076/10281 15077/15077/10282 +f 15075/15075/10280 15077/15077/10282 15078/15078/10283 +f 15079/15079/10284 15075/15075/10280 15078/15078/10283 +f 15079/15079/10284 15078/15078/10283 15080/15080/10285 +f 15081/15081/10286 15082/15082/10287 15083/15083/10288 +f 15081/15081/10286 15083/15083/10288 15084/15084/10289 +f 15085/15085/10290 15086/15086/10291 15087/15087/10292 +f 15085/15085/10290 15087/15087/10292 15088/15088/10288 +f 15088/15088/10288 15087/15087/10292 15055/15055/10261 +f 15088/15088/10288 15055/15055/10261 15054/15054/10260 +f 15084/15084/10289 15083/15083/10288 15052/15052/10258 +f 15084/15084/10289 15052/15052/10258 15017/15017/10226 +f 15086/15086/10291 15089/15089/10293 15090/15090/10294 +f 15086/15086/10291 15090/15090/10294 15087/15087/10292 +f 15091/15091/10295 15092/15092/10296 15090/15090/10294 +f 15091/15091/10295 15090/15090/10294 15089/15089/10293 +f 15093/15093/10297 15094/15094/10298 15090/15090/10294 +f 15093/15093/10297 15090/15090/10294 15092/15092/10296 +f 15061/15061/10266 15095/15095/10299 15090/15090/10294 +f 15061/15061/10266 15090/15090/10294 15094/15094/10298 +f 15055/15055/10261 15087/15087/10292 15090/15090/10294 +f 15055/15055/10261 15090/15090/10294 15095/15095/10299 +f 15096/15096/10300 15097/15097/10301 15098/15098/10302 +f 15096/15096/10300 15098/15098/10302 15099/15099/10303 +f 15100/15100/10301 15101/15101/10304 15102/15102/10305 +f 15100/15100/10301 15102/15102/10305 15103/15103/10306 +f 15103/15103/10306 15102/15102/10305 15040/15040/10247 +f 15103/15103/10306 15040/15040/10247 15039/15039/10245 +f 15099/15099/10303 15098/15098/10302 15037/15037/10245 +f 15099/15099/10303 15037/15037/10245 15033/15033/10241 +f 15104/15104/10307 15105/15105/10308 15106/15106/10309 +f 15104/15104/10307 15106/15106/10309 15107/15107/10310 +f 15105/15105/10308 15096/15096/10300 15099/15099/10303 +f 15105/15105/10308 15099/15099/10303 15106/15106/10309 +f 15106/15106/10309 15099/15099/10303 15033/15033/10241 +f 15106/15106/10309 15033/15033/10241 15031/15031/10239 +f 15107/15107/10310 15106/15106/10309 15031/15031/10239 +f 15107/15107/10310 15031/15031/10239 15006/15006/10215 +f 15108/15108/10311 15109/15109/10312 15110/15110/10313 +f 15108/15108/10311 15110/15110/10313 15111/15111/10314 +f 15112/15112/10315 15113/15113/10316 15114/15114/10317 +f 15112/15112/10315 15114/15114/10317 15115/15115/10318 +f 15115/15115/10318 15114/15114/10317 15013/15013/10222 +f 15115/15115/10318 15013/15013/10222 15026/15026/10235 +f 15111/15111/10314 15110/15110/10313 15023/15023/10232 +f 15111/15111/10314 15023/15023/10232 15022/15022/10231 +f 15113/15113/10316 15116/15116/10319 15117/15117/10320 +f 15113/15113/10316 15117/15117/10320 15114/15114/10317 +f 15116/15116/10319 15081/15081/10286 15084/15084/10289 +f 15116/15116/10319 15084/15084/10289 15117/15117/10320 +f 15117/15117/10320 15084/15084/10289 15017/15017/10226 +f 15117/15117/10320 15017/15017/10226 15014/15014/10223 +f 15114/15114/10317 15117/15117/10320 15014/15014/10223 +f 15114/15114/10317 15014/15014/10223 15013/15013/10222 +f 15118/15118/10321 15119/15119/10322 15120/15120/10323 +f 15118/15118/10321 15120/15120/10323 15121/15121/10324 +f 15122/15122/10322 15104/15104/10307 15107/15107/10310 +f 15122/15122/10322 15107/15107/10310 15123/15123/10325 +f 15123/15123/10325 15107/15107/10310 15006/15006/10215 +f 15123/15123/10325 15006/15006/10215 15005/15005/10212 +f 15121/15121/10324 15120/15120/10323 15002/15002/10212 +f 15121/15121/10324 15002/15002/10212 15001/15001/10211 +f 15012/15012/10221 15011/15011/10220 15124/15124/10326 +f 15012/15012/10221 15124/15124/10326 15125/15125/10327 +f 15010/15010/10219 15009/15009/10218 15126/15126/10328 +f 15010/15010/10219 15126/15126/10328 15127/15127/10329 +f 15127/15127/10329 15126/15126/10328 15128/15128/10330 +f 15127/15127/10329 15128/15128/10330 15129/15129/10331 +f 15125/15125/10327 15124/15124/10326 15130/15130/10332 +f 15125/15125/10327 15130/15130/10332 15131/15131/10333 +f 15021/15021/10230 15020/15020/10229 15132/15132/10334 +f 15021/15021/10230 15132/15132/10334 15133/15133/10335 +f 15020/15020/10229 15019/15019/10228 15134/15134/10336 +f 15020/15020/10229 15134/15134/10336 15132/15132/10334 +f 15132/15132/10334 15134/15134/10336 15135/15135/10337 +f 15132/15132/10334 15135/15135/10337 15136/15136/10338 +f 15133/15133/10335 15132/15132/10334 15136/15136/10338 +f 15133/15133/10335 15136/15136/10338 15137/15137/10339 +f 15030/15030/10238 15029/15029/10237 15138/15138/10340 +f 15030/15030/10238 15138/15138/10340 15139/15139/10341 +f 15028/15028/10237 15021/15021/10230 15133/15133/10335 +f 15028/15028/10237 15133/15133/10335 15140/15140/10342 +f 15140/15140/10342 15133/15133/10335 15137/15137/10339 +f 15140/15140/10342 15137/15137/10339 15141/15141/10343 +f 15139/15139/10341 15138/15138/10340 15142/15142/10343 +f 15139/15139/10341 15142/15142/10343 15143/15143/10344 +f 15009/15009/10218 15036/15036/10244 15144/15144/10345 +f 15009/15009/10218 15144/15144/10345 15126/15126/10328 +f 15036/15036/10244 15035/15035/10243 15145/15145/10346 +f 15036/15036/10244 15145/15145/10346 15144/15144/10345 +f 15144/15144/10345 15145/15145/10346 15146/15146/10347 +f 15144/15144/10345 15146/15146/10347 15147/15147/10348 +f 15126/15126/10328 15144/15144/10345 15147/15147/10348 +f 15126/15126/10328 15147/15147/10348 15128/15128/10330 +f 15035/15035/10243 15045/15045/10251 15148/15148/10349 +f 15035/15035/10243 15148/15148/10349 15145/15145/10346 +f 15044/15044/10250 15043/15043/10249 15149/15149/10350 +f 15044/15044/10250 15149/15149/10350 15150/15150/10351 +f 15150/15150/10351 15149/15149/10350 15151/15151/10352 +f 15150/15150/10351 15151/15151/10352 15152/15152/10353 +f 15145/15145/10346 15148/15148/10349 15153/15153/10353 +f 15145/15145/10346 15153/15153/10353 15146/15146/10347 +f 15051/15051/10257 15050/15050/10256 15154/15154/10354 +f 15051/15051/10257 15154/15154/10354 15155/15155/10355 +f 15050/15050/10256 15030/15030/10238 15139/15139/10341 +f 15050/15050/10256 15139/15139/10341 15154/15154/10354 +f 15154/15154/10354 15139/15139/10341 15143/15143/10344 +f 15154/15154/10354 15143/15143/10344 15156/15156/10356 +f 15155/15155/10355 15154/15154/10354 15156/15156/10356 +f 15155/15155/10355 15156/15156/10356 15157/15157/10357 +f 15019/15019/10228 15060/15060/10265 15158/15158/10358 +f 15019/15019/10228 15158/15158/10358 15134/15134/10336 +f 15059/15059/10264 15058/15058/10263 15159/15159/10359 +f 15059/15059/10264 15159/15159/10359 15160/15160/10358 +f 15160/15160/10358 15159/15159/10359 15161/15161/10360 +f 15160/15160/10358 15161/15161/10360 15162/15162/10361 +f 15134/15134/10336 15158/15158/10358 15163/15163/10361 +f 15134/15134/10336 15163/15163/10361 15135/15135/10337 +f 15066/15066/10271 15065/15065/10270 15164/15164/10362 +f 15066/15066/10271 15164/15164/10362 15165/15165/10363 +f 15065/15065/10270 15012/15012/10221 15125/15125/10327 +f 15065/15065/10270 15125/15125/10327 15164/15164/10362 +f 15164/15164/10362 15125/15125/10327 15131/15131/10333 +f 15164/15164/10362 15131/15131/10333 15166/15166/10364 +f 15165/15165/10363 15164/15164/10362 15166/15166/10364 +f 15165/15165/10363 15166/15166/10364 15167/15167/10365 +f 15168/15168/10366 15169/15169/10367 15170/15170/10368 +f 15168/15168/10366 15170/15170/10368 15171/15171/10369 +f 15172/15172/10367 15173/15173/10370 15174/15174/10371 +f 15172/15172/10367 15174/15174/10371 15175/15175/10368 +f 15175/15175/10368 15174/15174/10371 14985/14985/10196 +f 15175/15175/10368 14985/14985/10196 14999/14999/10209 +f 15171/15171/10369 15170/15170/10368 14997/14997/10207 +f 15171/15171/10369 14997/14997/10207 14961/14961/10173 +f 15176/15176/10372 15177/15177/10373 15178/15178/10374 +f 15176/15176/10372 15178/15178/10374 15179/15179/10375 +f 15177/15177/10373 15180/15180/10376 15181/15181/10377 +f 15177/15177/10373 15181/15181/10377 15178/15178/10374 +f 15178/15178/10374 15181/15181/10377 14963/14963/10175 +f 15178/15178/10374 14963/14963/10175 14995/14995/10205 +f 15179/15179/10375 15178/15178/10374 14995/14995/10205 +f 15179/15179/10375 14995/14995/10205 14992/14992/10202 +f 15182/15182/10378 15183/15183/10379 15184/15184/10380 +f 15182/15182/10378 15184/15184/10380 15185/15185/10381 +f 15186/15186/10379 15176/15176/10372 15179/15179/10375 +f 15186/15186/10379 15179/15179/10375 15187/15187/10380 +f 15187/15187/10380 15179/15179/10375 14992/14992/10202 +f 15187/15187/10380 14992/14992/10202 14991/14991/10200 +f 15185/15185/10381 15184/15184/10380 14989/14989/10200 +f 15185/15185/10381 14989/14989/10200 14975/14975/10187 +f 15173/15173/10370 15188/15188/10382 15189/15189/10383 +f 15173/15173/10370 15189/15189/10383 15174/15174/10371 +f 15188/15188/10382 15190/15190/10384 15191/15191/10385 +f 15188/15188/10382 15191/15191/10385 15189/15189/10383 +f 15189/15189/10383 15191/15191/10385 14977/14977/10189 +f 15189/15189/10383 14977/14977/10189 14986/14986/10197 +f 15174/15174/10371 15189/15189/10383 14986/14986/10197 +f 15174/15174/10371 14986/14986/10197 14985/14985/10196 +f 15190/15190/10384 15192/15192/10386 15193/15193/10387 +f 15190/15190/10384 15193/15193/10387 15191/15191/10385 +f 15194/15194/10388 15195/15195/10389 15196/15196/10390 +f 15194/15194/10388 15196/15196/10390 15197/15197/10391 +f 15197/15197/10391 15196/15196/10390 14982/14982/10193 +f 15197/15197/10391 14982/14982/10193 14981/14981/10190 +f 15191/15191/10385 15193/15193/10387 14978/14978/10190 +f 15191/15191/10385 14978/14978/10190 14977/14977/10189 +f 15157/15157/10357 15156/15156/10356 15198/15198/10392 +f 15157/15157/10357 15198/15198/10392 15199/15199/10393 +f 15143/15143/10344 15200/15200/10394 15198/15198/10392 +f 15143/15143/10344 15198/15198/10392 15156/15156/10356 +f 15182/15182/10378 15201/15201/10395 15198/15198/10392 +f 15182/15182/10378 15198/15198/10392 15200/15200/10394 +f 15202/15202/10396 15203/15203/10397 15198/15198/10392 +f 15202/15202/10396 15198/15198/10392 15201/15201/10395 +f 15204/15204/10398 15199/15199/10393 15198/15198/10392 +f 15204/15204/10398 15198/15198/10392 15203/15203/10397 +f 15180/15180/10376 15205/15205/10399 15206/15206/10400 +f 15180/15180/10376 15206/15206/10400 15181/15181/10377 +f 15207/15207/10399 15208/15208/10401 15209/15209/10402 +f 15207/15207/10399 15209/15209/10402 15210/15210/10400 +f 15210/15210/10400 15209/15209/10402 14968/14968/10180 +f 15210/15210/10400 14968/14968/10180 14967/14967/10179 +f 15181/15181/10377 15206/15206/10400 14964/14964/10176 +f 15181/15181/10377 14964/14964/10176 14963/14963/10175 +f 15167/15167/10365 15166/15166/10364 15211/15211/10403 +f 15167/15167/10365 15211/15211/10403 15212/15212/10404 +f 15131/15131/10333 15213/15213/10405 15211/15211/10403 +f 15131/15131/10333 15211/15211/10403 15166/15166/10364 +f 15168/15168/10366 15214/15214/10406 15211/15211/10403 +f 15168/15168/10366 15211/15211/10403 15213/15213/10405 +f 15215/15215/10407 15216/15216/10408 15211/15211/10403 +f 15215/15215/10407 15211/15211/10403 15214/15214/10406 +f 15217/15217/10409 15212/15212/10404 15211/15211/10403 +f 15217/15217/10409 15211/15211/10403 15216/15216/10408 +f 15218/15218/10410 15219/15219/10411 15220/15220/10412 +f 15218/15218/10410 15220/15220/10412 15221/15221/10413 +f 15219/15219/10411 15222/15222/10414 15223/15223/10415 +f 15219/15219/10411 15223/15223/10415 15220/15220/10412 +f 15220/15220/10412 15223/15223/10415 15224/15224/10416 +f 15220/15220/10412 15224/15224/10416 15225/15225/10417 +f 15221/15221/10413 15220/15220/10412 15225/15225/10417 +f 15221/15221/10413 15225/15225/10417 15226/15226/10418 +f 15227/15227/10419 15228/15228/10420 15229/15229/10421 +f 15227/15227/10419 15229/15229/10421 15230/15230/10422 +f 15228/15228/10420 15231/15231/10423 15232/15232/10424 +f 15228/15228/10420 15232/15232/10424 15229/15229/10421 +f 15229/15229/10421 15232/15232/10424 15233/15233/10425 +f 15229/15229/10421 15233/15233/10425 15234/15234/10426 +f 15230/15230/10422 15229/15229/10421 15234/15234/10426 +f 15230/15230/10422 15234/15234/10426 15235/15235/10427 +f 15235/15235/10427 15234/15234/10426 15236/15236/10428 +f 15235/15235/10427 15236/15236/10428 15237/15237/10429 +f 15234/15234/10426 15233/15233/10425 15238/15238/10430 +f 15234/15234/10426 15238/15238/10430 15236/15236/10428 +f 15236/15236/10428 15238/15238/10430 15239/15239/10431 +f 15236/15236/10428 15239/15239/10431 15240/15240/10432 +f 15237/15237/10429 15236/15236/10428 15240/15240/10432 +f 15237/15237/10429 15240/15240/10432 15241/15241/10433 +f 15241/15241/10433 15240/15240/10432 15242/15242/10434 +f 15241/15241/10433 15242/15242/10434 15243/15243/10435 +f 15240/15240/10432 15239/15239/10431 15244/15244/10436 +f 15240/15240/10432 15244/15244/10436 15242/15242/10434 +f 15242/15242/10434 15244/15244/10436 15245/15245/10437 +f 15242/15242/10434 15245/15245/10437 15246/15246/10438 +f 15243/15243/10435 15242/15242/10434 15246/15246/10438 +f 15243/15243/10435 15246/15246/10438 15247/15247/10439 +f 15247/15247/10439 15246/15246/10438 15248/15248/10440 +f 15247/15247/10439 15248/15248/10440 15249/15249/10441 +f 15246/15246/10438 15245/15245/10437 15250/15250/10442 +f 15246/15246/10438 15250/15250/10442 15248/15248/10440 +f 15248/15248/10440 15250/15250/10442 15251/15251/10443 +f 15248/15248/10440 15251/15251/10443 15252/15252/10444 +f 15249/15249/10441 15248/15248/10440 15252/15252/10444 +f 15249/15249/10441 15252/15252/10444 15253/15253/10445 +f 15253/15253/10445 15252/15252/10444 15254/15254/10446 +f 15253/15253/10445 15254/15254/10446 15255/15255/10447 +f 15252/15252/10444 15251/15251/10443 15256/15256/10448 +f 15252/15252/10444 15256/15256/10448 15254/15254/10446 +f 15254/15254/10446 15256/15256/10448 15257/15257/10449 +f 15254/15254/10446 15257/15257/10449 15258/15258/10450 +f 15255/15255/10447 15254/15254/10446 15258/15258/10450 +f 15255/15255/10447 15258/15258/10450 15259/15259/10451 +f 15260/15260/10452 15261/15261/10453 15262/15262/10454 +f 15260/15260/10452 15262/15262/10454 15263/15263/10455 +f 15261/15261/10453 15264/15264/10456 15265/15265/10457 +f 15261/15261/10453 15265/15265/10457 15262/15262/10454 +f 15262/15262/10454 15265/15265/10457 15266/15266/10458 +f 15262/15262/10454 15266/15266/10458 15267/15267/10459 +f 15263/15263/10455 15262/15262/10454 15267/15267/10459 +f 15263/15263/10455 15267/15267/10459 15268/15268/10460 +f 15269/15269/10461 15270/15270/10462 15271/15271/10463 +f 15269/15269/10461 15271/15271/10463 15272/15272/10464 +f 15270/15270/10462 15273/15273/10465 15274/15274/10466 +f 15270/15270/10462 15274/15274/10466 15271/15271/10463 +f 15275/15275/10467 15276/15276/10468 15264/15264/10456 +f 15275/15275/10467 15264/15264/10456 15261/15261/10453 +f 15277/15277/10464 15275/15275/10467 15261/15261/10453 +f 15277/15277/10464 15261/15261/10453 15260/15260/10452 +f 15278/15278/10469 15279/15279/10470 15280/15280/10471 +f 15278/15278/10469 15280/15280/10471 15281/15281/10472 +f 15279/15279/10470 15282/15282/10473 15283/15283/10474 +f 15279/15279/10470 15283/15283/10474 15280/15280/10471 +f 15280/15280/10471 15283/15283/10474 15273/15273/10465 +f 15280/15280/10471 15273/15273/10465 15270/15270/10462 +f 15281/15281/10472 15280/15280/10471 15270/15270/10462 +f 15281/15281/10472 15270/15270/10462 15269/15269/10461 +f 15268/15268/10460 15267/15267/10459 15284/15284/10475 +f 15268/15268/10460 15284/15284/10475 15285/15285/10476 +f 15267/15267/10459 15266/15266/10458 15286/15286/10477 +f 15267/15267/10459 15286/15286/10477 15284/15284/10475 +f 15284/15284/10475 15286/15286/10477 15222/15222/10414 +f 15284/15284/10475 15222/15222/10414 15219/15219/10411 +f 15285/15285/10476 15284/15284/10475 15219/15219/10411 +f 15285/15285/10476 15219/15219/10411 15218/15218/10410 +f 15287/15287/10478 15288/15288/10417 15289/15289/10479 +f 15287/15287/10478 15289/15289/10479 15290/15290/10480 +f 15288/15288/10417 15291/15291/10416 15292/15292/10481 +f 15288/15288/10417 15292/15292/10481 15289/15289/10479 +f 15289/15289/10479 15292/15292/10481 15231/15231/10423 +f 15289/15289/10479 15231/15231/10423 15228/15228/10420 +f 15290/15290/10480 15289/15289/10479 15228/15228/10420 +f 15290/15290/10480 15228/15228/10420 15227/15227/10419 +f 15293/15293/10482 15294/15294/10483 15295/15295/10484 +f 15293/15293/10482 15295/15295/10484 15296/15296/10485 +f 15294/15294/10483 15297/15297/10486 15298/15298/10487 +f 15294/15294/10483 15298/15298/10487 15295/15295/10484 +f 15295/15295/10484 15298/15298/10487 15299/15299/10488 +f 15295/15295/10484 15299/15299/10488 15300/15300/10489 +f 15296/15296/10485 15295/15295/10484 15300/15300/10489 +f 15296/15296/10485 15300/15300/10489 15301/15301/10490 +f 15278/15278/10469 15302/15302/10491 15303/15303/10492 +f 15278/15278/10469 15303/15303/10492 15304/15304/10493 +f 15302/15302/10491 15305/15305/10494 15306/15306/10495 +f 15302/15302/10491 15306/15306/10495 15303/15303/10492 +f 15303/15303/10492 15306/15306/10495 15297/15297/10486 +f 15303/15303/10492 15297/15297/10486 15294/15294/10483 +f 15304/15304/10493 15303/15303/10492 15294/15294/10483 +f 15304/15304/10493 15294/15294/10483 15293/15293/10482 +f 15307/15307/10496 15308/15308/10497 15309/15309/10498 +f 15307/15307/10496 15309/15309/10498 15310/15310/10499 +f 15308/15308/10497 15311/15311/10500 15312/15312/10501 +f 15308/15308/10497 15312/15312/10501 15309/15309/10498 +f 15309/15309/10498 15312/15312/10501 15313/15313/10502 +f 15309/15309/10498 15313/15313/10502 15314/15314/10503 +f 15310/15310/10499 15309/15309/10498 15314/15314/10503 +f 15310/15310/10499 15314/15314/10503 15315/15315/10504 +f 15316/15316/10505 15317/15317/10506 15318/15318/10507 +f 15316/15316/10505 15318/15318/10507 15319/15319/10508 +f 15317/15317/10506 15320/15320/10509 15321/15321/10510 +f 15317/15317/10506 15321/15321/10510 15318/15318/10507 +f 15318/15318/10507 15321/15321/10510 15322/15322/10511 +f 15318/15318/10507 15322/15322/10511 15323/15323/10512 +f 15319/15319/10508 15318/15318/10507 15323/15323/10512 +f 15319/15319/10508 15323/15323/10512 15324/15324/10513 +f 15320/15320/10509 15325/15325/10514 15326/15326/10515 +f 15320/15320/10509 15326/15326/10515 15321/15321/10510 +f 15325/15325/10514 15327/15327/10516 15328/15328/10517 +f 15325/15325/10514 15328/15328/10517 15326/15326/10515 +f 15326/15326/10515 15328/15328/10517 15329/15329/10518 +f 15326/15326/10515 15329/15329/10518 15330/15330/10519 +f 15321/15321/10510 15326/15326/10515 15330/15330/10519 +f 15321/15321/10510 15330/15330/10519 15322/15322/10511 +f 15327/15327/10516 15331/15331/10520 15332/15332/10521 +f 15327/15327/10516 15332/15332/10521 15328/15328/10517 +f 15331/15331/10520 15333/15333/10522 15334/15334/10523 +f 15331/15331/10520 15334/15334/10523 15332/15332/10521 +f 15332/15332/10521 15334/15334/10523 15335/15335/10524 +f 15332/15332/10521 15335/15335/10524 15336/15336/10525 +f 15328/15328/10517 15332/15332/10521 15336/15336/10525 +f 15328/15328/10517 15336/15336/10525 15329/15329/10518 +f 15333/15333/10522 15337/15337/10526 15338/15338/10527 +f 15333/15333/10522 15338/15338/10527 15334/15334/10523 +f 15337/15337/10526 15339/15339/10528 15340/15340/10529 +f 15337/15337/10526 15340/15340/10529 15338/15338/10527 +f 15338/15338/10527 15340/15340/10529 15341/15341/10530 +f 15338/15338/10527 15341/15341/10530 15342/15342/10531 +f 15334/15334/10523 15338/15338/10527 15342/15342/10531 +f 15334/15334/10523 15342/15342/10531 15335/15335/10524 +f 15339/15339/10528 15343/15343/10532 15344/15344/10533 +f 15339/15339/10528 15344/15344/10533 15340/15340/10529 +f 15343/15343/10532 15345/15345/10534 15346/15346/10535 +f 15343/15343/10532 15346/15346/10535 15344/15344/10533 +f 15344/15344/10533 15346/15346/10535 15347/15347/10536 +f 15344/15344/10533 15347/15347/10536 15348/15348/10537 +f 15340/15340/10529 15344/15344/10533 15348/15348/10537 +f 15340/15340/10529 15348/15348/10537 15341/15341/10530 +f 15349/15349/10538 15350/15350/10539 15351/15351/10540 +f 15349/15349/10538 15351/15351/10540 15352/15352/10541 +f 15350/15350/10539 15353/15353/10542 15354/15354/10543 +f 15350/15350/10539 15354/15354/10543 15351/15351/10540 +f 15351/15351/10540 15354/15354/10543 15355/15355/10544 +f 15351/15351/10540 15355/15355/10544 15356/15356/10545 +f 15352/15352/10541 15351/15351/10540 15356/15356/10545 +f 15352/15352/10541 15356/15356/10545 15357/15357/10546 +f 15358/15358/10547 15359/15359/10548 15360/15360/10549 +f 15358/15358/10547 15360/15360/10549 15361/15361/10550 +f 15359/15359/10548 15349/15349/10538 15352/15352/10541 +f 15359/15359/10548 15352/15352/10541 15360/15360/10549 +f 15360/15360/10549 15352/15352/10541 15357/15357/10546 +f 15360/15360/10549 15357/15357/10546 15362/15362/10551 +f 15361/15361/10550 15360/15360/10549 15362/15362/10551 +f 15361/15361/10550 15362/15362/10551 15363/15363/10552 +f 15364/15364/10553 15365/15365/10554 15366/15366/10555 +f 15364/15364/10553 15366/15366/10555 15367/15367/10556 +f 15365/15365/10554 15368/15368/10547 15369/15369/10550 +f 15365/15365/10554 15369/15369/10550 15366/15366/10555 +f 15366/15366/10555 15369/15369/10550 15370/15370/10557 +f 15366/15366/10555 15370/15370/10557 15371/15371/10558 +f 15367/15367/10556 15366/15366/10555 15371/15371/10558 +f 15367/15367/10556 15371/15371/10558 15372/15372/10559 +f 15353/15353/10542 15373/15373/10560 15374/15374/10561 +f 15353/15353/10542 15374/15374/10561 15354/15354/10543 +f 15373/15373/10560 15307/15307/10496 15310/15310/10499 +f 15373/15373/10560 15310/15310/10499 15374/15374/10561 +f 15374/15374/10561 15310/15310/10499 15315/15315/10504 +f 15374/15374/10561 15315/15315/10504 15375/15375/10562 +f 15354/15354/10543 15374/15374/10561 15375/15375/10562 +f 15354/15354/10543 15375/15375/10562 15355/15355/10544 +f 15376/15376/10500 15377/15377/10563 15378/15378/10564 +f 15376/15376/10500 15378/15378/10564 15379/15379/10501 +f 15377/15377/10563 15316/15316/10505 15319/15319/10508 +f 15377/15377/10563 15319/15319/10508 15378/15378/10564 +f 15378/15378/10564 15319/15319/10508 15324/15324/10513 +f 15378/15378/10564 15324/15324/10513 15380/15380/10565 +f 15379/15379/10501 15378/15378/10564 15380/15380/10565 +f 15379/15379/10501 15380/15380/10565 15381/15381/10502 +f 15382/15382/10566 15383/15383/10567 15384/15384/10568 +f 15382/15382/10566 15384/15384/10568 15385/15385/10569 +f 15383/15383/10567 15386/15386/10570 15387/15387/10571 +f 15383/15383/10567 15387/15387/10571 15384/15384/10568 +f 15384/15384/10568 15387/15387/10571 15388/15388/10572 +f 15384/15384/10568 15388/15388/10572 15389/15389/10573 +f 15385/15385/10569 15384/15384/10568 15389/15389/10573 +f 15385/15385/10569 15389/15389/10573 15390/15390/10574 +f 15364/15364/10553 15391/15391/10575 15392/15392/10576 +f 15364/15364/10553 15392/15392/10576 15393/15393/10577 +f 15391/15391/10575 15382/15382/10566 15385/15385/10569 +f 15391/15391/10575 15385/15385/10569 15392/15392/10576 +f 15392/15392/10576 15385/15385/10569 15390/15390/10574 +f 15392/15392/10576 15390/15390/10574 15394/15394/10578 +f 15393/15393/10577 15392/15392/10576 15394/15394/10578 +f 15393/15393/10577 15394/15394/10578 15395/15395/10579 +f 15291/15291/10416 15396/15396/10580 15397/15397/10581 +f 15291/15291/10416 15397/15397/10581 15292/15292/10481 +f 15398/15398/10580 15399/15399/10582 15400/15400/10583 +f 15398/15398/10580 15400/15400/10583 15401/15401/10584 +f 15401/15401/10584 15400/15400/10583 15402/15402/10585 +f 15401/15401/10584 15402/15402/10585 15403/15403/10586 +f 15292/15292/10481 15397/15397/10581 15404/15404/10587 +f 15292/15292/10481 15404/15404/10587 15231/15231/10423 +f 15405/15405/10588 15406/15406/10589 15407/15407/10590 +f 15405/15405/10588 15407/15407/10590 15408/15408/10591 +f 15409/15409/10592 15410/15410/10593 15411/15411/10594 +f 15409/15409/10592 15411/15411/10594 15412/15412/10590 +f 15412/15412/10590 15411/15411/10594 15413/15413/10595 +f 15412/15412/10590 15413/15413/10595 15414/15414/10596 +f 15408/15408/10591 15407/15407/10590 15415/15415/10596 +f 15408/15408/10591 15415/15415/10596 15416/15416/10597 +f 15417/15417/10598 15418/15418/10599 15419/15419/10600 +f 15417/15417/10598 15419/15419/10600 15420/15420/10601 +f 15421/15421/10602 15422/15422/10603 15423/15423/10604 +f 15421/15421/10602 15423/15423/10604 15424/15424/10605 +f 15424/15424/10605 15423/15423/10604 15425/15425/10606 +f 15424/15424/10605 15425/15425/10606 15426/15426/10607 +f 15420/15420/10601 15419/15419/10600 15427/15427/10608 +f 15420/15420/10601 15427/15427/10608 15428/15428/10609 +f 15429/15429/10465 15430/15430/10610 15431/15431/10611 +f 15429/15429/10465 15431/15431/10611 15276/15276/10468 +f 15432/15432/10612 15433/15433/10613 15434/15434/10614 +f 15432/15432/10612 15434/15434/10614 15435/15435/10615 +f 15435/15435/10615 15434/15434/10614 15436/15436/10616 +f 15435/15435/10615 15436/15436/10616 15437/15437/10617 +f 15276/15276/10468 15431/15431/10611 15438/15438/10617 +f 15276/15276/10468 15438/15438/10617 15264/15264/10456 +f 15301/15301/10490 15439/15439/10618 15440/15440/10619 +f 15301/15301/10490 15440/15440/10619 15441/15441/10620 +f 15442/15442/10618 15443/15443/10621 15444/15444/10622 +f 15442/15442/10618 15444/15444/10622 15445/15445/10619 +f 15445/15445/10619 15444/15444/10622 15446/15446/10623 +f 15445/15445/10619 15446/15446/10623 15447/15447/10624 +f 15441/15441/10620 15440/15440/10619 15448/15448/10624 +f 15441/15441/10620 15448/15448/10624 15449/15449/10625 +f 15450/15450/10626 15451/15451/10627 15452/15452/10628 +f 15450/15450/10626 15452/15452/10628 15453/15453/10629 +f 15454/15454/10627 15386/15386/10570 15455/15455/10630 +f 15454/15454/10627 15455/15455/10630 15456/15456/10628 +f 15456/15456/10628 15455/15455/10630 15457/15457/10631 +f 15456/15456/10628 15457/15457/10631 15458/15458/10632 +f 15453/15453/10629 15452/15452/10628 15459/15459/10633 +f 15453/15453/10629 15459/15459/10633 15460/15460/10634 +f 15222/15222/10414 15461/15461/10635 15462/15462/10636 +f 15222/15222/10414 15462/15462/10636 15223/15223/10415 +f 15463/15463/10637 15464/15464/10638 15465/15465/10639 +f 15463/15463/10637 15465/15465/10639 15466/15466/10640 +f 15466/15466/10640 15465/15465/10639 15399/15399/10582 +f 15466/15466/10640 15399/15399/10582 15398/15398/10580 +f 15223/15223/10415 15462/15462/10636 15467/15467/10580 +f 15223/15223/10415 15467/15467/10580 15224/15224/10416 +f 15449/15449/10625 15448/15448/10624 15468/15468/10641 +f 15449/15449/10625 15468/15468/10641 15469/15469/10642 +f 15470/15470/10624 15471/15471/10623 15472/15472/10643 +f 15470/15470/10624 15472/15472/10643 15473/15473/10644 +f 15473/15473/10644 15472/15472/10643 15474/15474/10645 +f 15473/15473/10644 15474/15474/10645 15475/15475/10646 +f 15469/15469/10642 15468/15468/10641 15476/15476/10647 +f 15469/15469/10642 15476/15476/10647 15477/15477/10648 +f 15428/15428/10609 15427/15427/10608 15478/15478/10649 +f 15428/15428/10609 15478/15478/10649 15479/15479/10650 +f 15426/15426/10607 15425/15425/10606 15480/15480/10651 +f 15426/15426/10607 15480/15480/10651 15481/15481/10652 +f 15481/15481/10652 15480/15480/10651 15482/15482/10653 +f 15481/15481/10652 15482/15482/10653 15483/15483/10654 +f 15484/15484/10650 15485/15485/10652 15486/15486/10655 +f 15484/15484/10650 15486/15486/10655 15487/15487/10656 +f 15297/15297/10486 15488/15488/10657 15489/15489/10658 +f 15297/15297/10486 15489/15489/10658 15298/15298/10487 +f 15490/15490/10659 15491/15491/10660 15492/15492/10661 +f 15490/15490/10659 15492/15492/10661 15493/15493/10662 +f 15493/15493/10662 15492/15492/10661 15494/15494/10663 +f 15493/15493/10662 15494/15494/10663 15495/15495/10664 +f 15298/15298/10487 15489/15489/10658 15496/15496/10665 +f 15298/15298/10487 15496/15496/10665 15299/15299/10488 +f 15497/15497/10666 15498/15498/10667 15499/15499/10668 +f 15497/15497/10666 15499/15499/10668 15500/15500/10669 +f 15501/15501/10670 15502/15502/10671 15503/15503/10672 +f 15501/15501/10670 15503/15503/10672 15504/15504/10668 +f 15504/15504/10668 15503/15503/10672 15505/15505/10673 +f 15504/15504/10668 15505/15505/10673 15506/15506/10674 +f 15500/15500/10669 15499/15499/10668 15507/15507/10675 +f 15500/15500/10669 15507/15507/10675 15508/15508/10676 +f 15509/15509/10677 15510/15510/10678 15511/15511/10679 +f 15509/15509/10677 15511/15511/10679 15512/15512/10680 +f 15513/15513/10678 15514/15514/10681 15515/15515/10682 +f 15513/15513/10678 15515/15515/10682 15516/15516/10679 +f 15516/15516/10679 15515/15515/10682 15517/15517/10683 +f 15516/15516/10679 15517/15517/10683 15518/15518/10684 +f 15512/15512/10680 15511/15511/10679 15519/15519/10685 +f 15512/15512/10680 15519/15519/10685 15520/15520/10686 +f 15416/15416/10597 15415/15415/10596 15521/15521/10687 +f 15416/15416/10597 15521/15521/10687 15522/15522/10688 +f 15414/15414/10596 15413/15413/10595 15523/15523/10689 +f 15414/15414/10596 15523/15523/10689 15524/15524/10687 +f 15524/15524/10687 15523/15523/10689 15422/15422/10603 +f 15524/15524/10687 15422/15422/10603 15421/15421/10602 +f 15522/15522/10688 15521/15521/10687 15418/15418/10599 +f 15522/15522/10688 15418/15418/10599 15417/15417/10598 +f 15525/15525/10690 15526/15526/10691 15527/15527/10692 +f 15525/15525/10690 15527/15527/10692 15528/15528/10693 +f 15529/15529/10694 15324/15324/10513 15323/15323/10512 +f 15529/15529/10694 15323/15323/10512 15530/15530/10692 +f 15530/15530/10692 15323/15323/10512 15322/15322/10511 +f 15530/15530/10692 15322/15322/10511 15531/15531/10695 +f 15528/15528/10693 15527/15527/10692 15532/15532/10695 +f 15528/15528/10693 15532/15532/10695 15533/15533/10696 +f 15534/15534/10697 15535/15535/10698 15536/15536/10699 +f 15534/15534/10697 15536/15536/10699 15537/15537/10700 +f 15535/15535/10698 15538/15538/10701 15539/15539/10702 +f 15535/15535/10698 15539/15539/10702 15536/15536/10699 +f 15540/15540/10703 15541/15541/10702 15542/15542/10704 +f 15540/15540/10703 15542/15542/10704 15543/15543/10705 +f 15544/15544/10700 15540/15540/10703 15543/15543/10705 +f 15544/15544/10700 15543/15543/10705 15545/15545/10706 +f 15508/15508/10676 15507/15507/10675 15546/15546/10707 +f 15508/15508/10676 15546/15546/10707 15547/15547/10708 +f 15506/15506/10674 15505/15505/10673 15548/15548/10709 +f 15506/15506/10674 15548/15548/10709 15549/15549/10710 +f 15549/15549/10710 15548/15548/10709 15550/15550/10711 +f 15549/15549/10710 15550/15550/10711 15551/15551/10712 +f 15547/15547/10708 15546/15546/10707 15552/15552/10713 +f 15547/15547/10708 15552/15552/10713 15553/15553/10714 +f 15520/15520/10686 15519/15519/10685 15554/15554/10715 +f 15520/15520/10686 15554/15554/10715 15555/15555/10716 +f 15518/15518/10684 15517/15517/10683 15556/15556/10717 +f 15518/15518/10684 15556/15556/10717 15557/15557/10715 +f 15557/15557/10715 15556/15556/10717 15558/15558/10718 +f 15557/15557/10715 15558/15558/10718 15559/15559/10719 +f 15555/15555/10716 15554/15554/10715 15560/15560/10719 +f 15555/15555/10716 15560/15560/10719 15561/15561/10720 +f 15239/15239/10431 15562/15562/10721 15563/15563/10722 +f 15239/15239/10431 15563/15563/10722 15244/15244/10436 +f 15564/15564/10721 15565/15565/10723 15566/15566/10724 +f 15564/15564/10721 15566/15566/10724 15567/15567/10722 +f 15567/15567/10722 15566/15566/10724 15568/15568/10725 +f 15567/15567/10722 15568/15568/10725 15569/15569/10726 +f 15244/15244/10436 15563/15563/10722 15570/15570/10726 +f 15244/15244/10436 15570/15570/10726 15245/15245/10437 +f 15571/15571/10727 15572/15572/10728 15573/15573/10729 +f 15571/15571/10727 15573/15573/10729 15574/15574/10730 +f 15575/15575/10728 15576/15576/10731 15577/15577/10732 +f 15575/15575/10728 15577/15577/10732 15578/15578/10733 +f 15578/15578/10733 15577/15577/10732 15579/15579/10734 +f 15578/15578/10733 15579/15579/10734 15580/15580/10735 +f 15574/15574/10730 15573/15573/10729 15581/15581/10736 +f 15574/15574/10730 15581/15581/10736 15582/15582/10737 +f 15553/15553/10714 15552/15552/10713 15583/15583/10738 +f 15553/15553/10714 15583/15583/10738 15584/15584/10739 +f 15551/15551/10712 15550/15550/10711 15585/15585/10740 +f 15551/15551/10712 15585/15585/10740 15586/15586/10738 +f 15586/15586/10738 15585/15585/10740 15587/15587/10741 +f 15586/15586/10738 15587/15587/10741 15588/15588/10742 +f 15584/15584/10739 15583/15583/10738 15589/15589/10742 +f 15584/15584/10739 15589/15589/10742 15590/15590/10743 +f 15561/15561/10720 15560/15560/10719 15591/15591/10744 +f 15561/15561/10720 15591/15591/10744 15592/15592/10745 +f 15559/15559/10719 15558/15558/10718 15593/15593/10746 +f 15559/15559/10719 15593/15593/10746 15594/15594/10747 +f 15594/15594/10747 15593/15593/10746 15595/15595/10748 +f 15594/15594/10747 15595/15595/10748 15596/15596/10749 +f 15592/15592/10745 15591/15591/10744 15597/15597/10749 +f 15592/15592/10745 15597/15597/10749 15598/15598/10750 +f 15598/15598/10750 15597/15597/10749 15599/15599/10751 +f 15598/15598/10750 15599/15599/10751 15600/15600/10752 +f 15596/15596/10749 15595/15595/10748 15601/15601/10753 +f 15596/15596/10749 15601/15601/10753 15602/15602/10751 +f 15602/15602/10751 15601/15601/10753 15603/15603/10754 +f 15602/15602/10751 15603/15603/10754 15604/15604/10755 +f 15600/15600/10752 15599/15599/10751 15605/15605/10756 +f 15600/15600/10752 15605/15605/10756 15606/15606/10757 +f 15264/15264/10456 15438/15438/10617 15607/15607/10758 +f 15264/15264/10456 15607/15607/10758 15265/15265/10457 +f 15437/15437/10617 15436/15436/10616 15608/15608/10759 +f 15437/15437/10617 15608/15608/10759 15609/15609/10758 +f 15609/15609/10758 15608/15608/10759 15610/15610/10760 +f 15609/15609/10758 15610/15610/10760 15611/15611/10761 +f 15265/15265/10457 15607/15607/10758 15612/15612/10761 +f 15265/15265/10457 15612/15612/10761 15266/15266/10458 +f 15231/15231/10423 15404/15404/10587 15613/15613/10762 +f 15231/15231/10423 15613/15613/10762 15232/15232/10424 +f 15403/15403/10586 15402/15402/10585 15614/15614/10763 +f 15403/15403/10586 15614/15614/10763 15615/15615/10764 +f 15615/15615/10764 15614/15614/10763 15616/15616/10765 +f 15615/15615/10764 15616/15616/10765 15617/15617/10766 +f 15232/15232/10424 15613/15613/10762 15618/15618/10767 +f 15232/15232/10424 15618/15618/10767 15233/15233/10425 +f 15590/15590/10743 15589/15589/10742 15619/15619/10768 +f 15590/15590/10743 15619/15619/10768 15620/15620/10769 +f 15588/15588/10742 15587/15587/10741 15621/15621/10770 +f 15588/15588/10742 15621/15621/10770 15622/15622/10768 +f 15622/15622/10768 15621/15621/10770 15623/15623/10771 +f 15622/15622/10768 15623/15623/10771 15624/15624/10772 +f 15620/15620/10769 15619/15619/10768 15625/15625/10773 +f 15620/15620/10769 15625/15625/10773 15626/15626/10774 +f 15627/15627/10775 15628/15628/10776 15629/15629/10777 +f 15627/15627/10775 15629/15629/10777 15630/15630/10778 +f 15631/15631/10776 15632/15632/10779 15633/15633/10780 +f 15631/15631/10776 15633/15633/10780 15634/15634/10777 +f 15634/15634/10777 15633/15633/10780 15635/15635/10781 +f 15634/15634/10777 15635/15635/10781 15636/15636/10782 +f 15630/15630/10778 15629/15629/10777 15637/15637/10783 +f 15630/15630/10778 15637/15637/10783 15638/15638/10784 +f 15639/15639/10785 15640/15640/10786 15641/15641/10787 +f 15639/15639/10785 15641/15641/10787 15642/15642/10788 +f 15643/15643/10786 15644/15644/10789 15645/15645/10790 +f 15643/15643/10786 15645/15645/10790 15646/15646/10787 +f 15646/15646/10787 15645/15645/10790 15410/15410/10593 +f 15646/15646/10787 15410/15410/10593 15409/15409/10592 +f 15647/15647/10788 15648/15648/10787 15406/15406/10589 +f 15647/15647/10788 15406/15406/10589 15405/15405/10588 +f 15282/15282/10473 15649/15649/10791 15650/15650/10792 +f 15282/15282/10473 15650/15650/10792 15283/15283/10474 +f 15651/15651/10793 15652/15652/10794 15653/15653/10795 +f 15651/15651/10793 15653/15653/10795 15654/15654/10796 +f 15654/15654/10796 15653/15653/10795 15433/15433/10613 +f 15654/15654/10796 15433/15433/10613 15432/15432/10612 +f 15283/15283/10474 15650/15650/10792 15655/15655/10612 +f 15283/15283/10474 15655/15655/10612 15273/15273/10465 +f 15477/15477/10648 15476/15476/10647 15656/15656/10797 +f 15477/15477/10648 15656/15656/10797 15657/15657/10798 +f 15475/15475/10646 15474/15474/10645 15658/15658/10799 +f 15475/15475/10646 15658/15658/10799 15659/15659/10797 +f 15659/15659/10797 15658/15658/10799 15652/15652/10794 +f 15659/15659/10797 15652/15652/10794 15651/15651/10793 +f 15657/15657/10798 15656/15656/10797 15649/15649/10791 +f 15657/15657/10798 15649/15649/10791 15282/15282/10473 +f 15606/15606/10757 15605/15605/10756 15660/15660/10800 +f 15606/15606/10757 15660/15660/10800 15661/15661/10801 +f 15604/15604/10755 15603/15603/10754 15662/15662/10802 +f 15604/15604/10755 15662/15662/10802 15663/15663/10803 +f 15663/15663/10803 15662/15662/10802 15644/15644/10789 +f 15663/15663/10803 15644/15644/10789 15643/15643/10786 +f 15661/15661/10801 15660/15660/10800 15640/15640/10786 +f 15661/15661/10801 15640/15640/10786 15639/15639/10785 +f 15626/15626/10774 15625/15625/10773 15664/15664/10804 +f 15626/15626/10774 15664/15664/10804 15665/15665/10805 +f 15624/15624/10772 15623/15623/10771 15666/15666/10806 +f 15624/15624/10772 15666/15666/10806 15667/15667/10804 +f 15667/15667/10804 15666/15666/10806 15668/15668/10807 +f 15667/15667/10804 15668/15668/10807 15669/15669/10808 +f 15665/15665/10805 15664/15664/10804 15670/15670/10809 +f 15665/15665/10805 15670/15670/10809 15671/15671/10810 +f 15672/15672/10811 15673/15673/10812 15674/15674/10813 +f 15672/15672/10811 15674/15674/10813 15675/15675/10814 +f 15676/15676/10815 15357/15357/10546 15356/15356/10545 +f 15676/15676/10815 15356/15356/10545 15677/15677/10816 +f 15677/15677/10816 15356/15356/10545 15355/15355/10544 +f 15677/15677/10816 15355/15355/10544 15678/15678/10817 +f 15675/15675/10814 15674/15674/10813 15679/15679/10817 +f 15675/15675/10814 15679/15679/10817 15680/15680/10818 +f 15487/15487/10656 15486/15486/10655 15681/15681/10819 +f 15487/15487/10656 15681/15681/10819 15682/15682/10820 +f 15483/15483/10654 15482/15482/10653 15683/15683/10821 +f 15483/15483/10654 15683/15683/10821 15684/15684/10822 +f 15684/15684/10822 15683/15683/10821 15685/15685/10823 +f 15684/15684/10822 15685/15685/10823 15686/15686/10824 +f 15682/15682/10820 15681/15681/10819 15687/15687/10824 +f 15682/15682/10820 15687/15687/10824 15305/15305/10494 +f 15533/15533/10696 15532/15532/10695 15688/15688/10825 +f 15533/15533/10696 15688/15688/10825 15689/15689/10826 +f 15531/15531/10695 15322/15322/10511 15330/15330/10519 +f 15531/15531/10695 15330/15330/10519 15690/15690/10825 +f 15690/15690/10825 15330/15330/10519 15329/15329/10518 +f 15690/15690/10825 15329/15329/10518 15691/15691/10827 +f 15689/15689/10826 15688/15688/10825 15692/15692/10827 +f 15689/15689/10826 15692/15692/10827 15693/15693/10828 +f 15693/15693/10828 15692/15692/10827 15694/15694/10829 +f 15693/15693/10828 15694/15694/10829 15695/15695/10830 +f 15691/15691/10827 15329/15329/10518 15336/15336/10525 +f 15691/15691/10827 15336/15336/10525 15696/15696/10829 +f 15696/15696/10829 15336/15336/10525 15335/15335/10524 +f 15696/15696/10829 15335/15335/10524 15697/15697/10831 +f 15695/15695/10830 15694/15694/10829 15698/15698/10832 +f 15695/15695/10830 15698/15698/10832 15699/15699/10833 +f 15699/15699/10833 15698/15698/10832 15700/15700/10834 +f 15699/15699/10833 15700/15700/10834 15701/15701/10835 +f 15697/15697/10831 15335/15335/10524 15342/15342/10531 +f 15697/15697/10831 15342/15342/10531 15702/15702/10836 +f 15702/15702/10836 15342/15342/10531 15341/15341/10530 +f 15702/15702/10836 15341/15341/10530 15703/15703/10837 +f 15701/15701/10835 15700/15700/10834 15704/15704/10837 +f 15701/15701/10835 15704/15704/10837 15705/15705/10838 +f 15680/15680/10818 15679/15679/10817 15706/15706/10839 +f 15680/15680/10818 15706/15706/10839 15707/15707/10840 +f 15678/15678/10817 15355/15355/10544 15375/15375/10562 +f 15678/15678/10817 15375/15375/10562 15708/15708/10839 +f 15708/15708/10839 15375/15375/10562 15315/15315/10504 +f 15708/15708/10839 15315/15315/10504 15709/15709/10841 +f 15707/15707/10840 15706/15706/10839 15710/15710/10842 +f 15707/15707/10840 15710/15710/10842 15711/15711/10843 +f 15233/15233/10425 15618/15618/10767 15712/15712/10844 +f 15233/15233/10425 15712/15712/10844 15238/15238/10430 +f 15617/15617/10766 15616/15616/10765 15713/15713/10845 +f 15617/15617/10766 15713/15713/10845 15714/15714/10846 +f 15714/15714/10846 15713/15713/10845 15565/15565/10723 +f 15714/15714/10846 15565/15565/10723 15564/15564/10721 +f 15238/15238/10430 15712/15712/10844 15562/15562/10721 +f 15238/15238/10430 15562/15562/10721 15239/15239/10431 +f 15245/15245/10437 15570/15570/10726 15715/15715/10847 +f 15245/15245/10437 15715/15715/10847 15250/15250/10442 +f 15569/15569/10726 15568/15568/10725 15716/15716/10848 +f 15569/15569/10726 15716/15716/10848 15717/15717/10847 +f 15717/15717/10847 15716/15716/10848 15718/15718/10849 +f 15717/15717/10847 15718/15718/10849 15719/15719/10850 +f 15250/15250/10442 15715/15715/10847 15720/15720/10850 +f 15250/15250/10442 15720/15720/10850 15251/15251/10443 +f 15705/15705/10838 15704/15704/10837 15721/15721/10851 +f 15705/15705/10838 15721/15721/10851 15722/15722/10852 +f 15703/15703/10837 15341/15341/10530 15348/15348/10537 +f 15703/15703/10837 15348/15348/10537 15723/15723/10853 +f 15723/15723/10853 15348/15348/10537 15347/15347/10536 +f 15723/15723/10853 15347/15347/10536 15724/15724/10854 +f 15722/15722/10852 15721/15721/10851 15725/15725/10855 +f 15722/15722/10852 15725/15725/10855 15726/15726/10856 +f 15251/15251/10443 15720/15720/10850 15727/15727/10857 +f 15251/15251/10443 15727/15727/10857 15256/15256/10448 +f 15719/15719/10850 15718/15718/10849 15728/15728/10858 +f 15719/15719/10850 15728/15728/10858 15729/15729/10857 +f 15729/15729/10857 15728/15728/10858 15730/15730/10859 +f 15729/15729/10857 15730/15730/10859 15731/15731/10860 +f 15256/15256/10448 15727/15727/10857 15732/15732/10860 +f 15256/15256/10448 15732/15732/10860 15257/15257/10449 +f 15733/15733/10861 15734/15734/10862 15735/15735/10863 +f 15733/15733/10861 15735/15735/10863 15736/15736/10864 +f 15458/15458/10632 15457/15457/10631 15737/15737/10865 +f 15458/15458/10632 15737/15737/10865 15738/15738/10863 +f 15738/15738/10863 15737/15737/10865 15739/15739/10866 +f 15738/15738/10863 15739/15739/10866 15740/15740/10867 +f 15736/15736/10864 15735/15735/10863 15741/15741/10868 +f 15736/15736/10864 15741/15741/10868 15742/15742/10869 +f 15743/15743/10870 15744/15744/10871 15745/15745/10872 +f 15743/15743/10870 15745/15745/10872 15746/15746/10873 +f 15747/15747/10871 15363/15363/10552 15362/15362/10551 +f 15747/15747/10871 15362/15362/10551 15748/15748/10874 +f 15748/15748/10874 15362/15362/10551 15357/15357/10546 +f 15748/15748/10874 15357/15357/10546 15676/15676/10815 +f 15746/15746/10873 15745/15745/10872 15673/15673/10812 +f 15746/15746/10873 15673/15673/10812 15672/15672/10811 +f 15749/15749/10875 15750/15750/10876 15751/15751/10877 +f 15749/15749/10875 15751/15751/10877 15752/15752/10878 +f 15750/15750/10876 15753/15753/10879 15754/15754/10880 +f 15750/15750/10876 15754/15754/10880 15751/15751/10877 +f 15751/15751/10877 15754/15754/10880 15755/15755/10881 +f 15751/15751/10877 15755/15755/10881 15756/15756/10882 +f 15752/15752/10878 15751/15751/10877 15756/15756/10882 +f 15752/15752/10878 15756/15756/10882 15757/15757/10883 +f 15638/15638/10784 15637/15637/10783 15758/15758/10884 +f 15638/15638/10784 15758/15758/10884 15759/15759/10885 +f 15636/15636/10782 15635/15635/10781 15760/15760/10886 +f 15636/15636/10782 15760/15760/10886 15761/15761/10887 +f 15762/15762/10887 15763/15763/10886 15764/15764/10888 +f 15762/15762/10887 15764/15764/10888 15765/15765/10889 +f 15759/15759/10885 15758/15758/10884 15766/15766/10889 +f 15759/15759/10885 15766/15766/10889 15767/15767/10890 +f 15305/15305/10494 15687/15687/10824 15768/15768/10891 +f 15305/15305/10494 15768/15768/10891 15306/15306/10495 +f 15686/15686/10824 15685/15685/10823 15769/15769/10892 +f 15686/15686/10824 15769/15769/10892 15770/15770/10891 +f 15770/15770/10891 15769/15769/10892 15491/15491/10660 +f 15770/15770/10891 15491/15491/10660 15490/15490/10659 +f 15306/15306/10495 15768/15768/10891 15488/15488/10657 +f 15306/15306/10495 15488/15488/10657 15297/15297/10486 +f 15767/15767/10890 15766/15766/10889 15771/15771/10893 +f 15767/15767/10890 15771/15771/10893 15772/15772/10894 +f 15765/15765/10889 15764/15764/10888 15773/15773/10895 +f 15765/15765/10889 15773/15773/10895 15774/15774/10896 +f 15774/15774/10896 15773/15773/10895 15395/15395/10579 +f 15774/15774/10896 15395/15395/10579 15775/15775/10897 +f 15772/15772/10894 15771/15771/10893 15776/15776/10898 +f 15772/15772/10894 15776/15776/10898 15777/15777/10899 +f 15777/15777/10899 15776/15776/10898 15778/15778/10900 +f 15777/15777/10899 15778/15778/10900 15779/15779/10901 +f 15775/15775/10897 15395/15395/10579 15394/15394/10578 +f 15775/15775/10897 15394/15394/10578 15780/15780/10900 +f 15780/15780/10900 15394/15394/10578 15390/15390/10574 +f 15780/15780/10900 15390/15390/10574 15781/15781/10902 +f 15779/15779/10901 15778/15778/10900 15782/15782/10902 +f 15779/15779/10901 15782/15782/10902 15783/15783/10903 +f 15266/15266/10458 15612/15612/10761 15784/15784/10904 +f 15266/15266/10458 15784/15784/10904 15286/15286/10477 +f 15611/15611/10761 15610/15610/10760 15785/15785/10905 +f 15611/15611/10761 15785/15785/10905 15786/15786/10906 +f 15786/15786/10906 15785/15785/10905 15464/15464/10638 +f 15786/15786/10906 15464/15464/10638 15463/15463/10637 +f 15286/15286/10477 15784/15784/10904 15461/15461/10635 +f 15286/15286/10477 15461/15461/10635 15222/15222/10414 +f 15742/15742/10869 15741/15741/10868 15787/15787/10907 +f 15742/15742/10869 15787/15787/10907 15788/15788/10908 +f 15740/15740/10867 15739/15739/10866 15789/15789/10909 +f 15740/15740/10867 15789/15789/10909 15790/15790/10910 +f 15790/15790/10910 15789/15789/10909 15372/15372/10559 +f 15790/15790/10910 15372/15372/10559 15791/15791/10911 +f 15788/15788/10908 15787/15787/10907 15792/15792/10912 +f 15788/15788/10908 15792/15792/10912 15793/15793/10913 +f 15783/15783/10903 15782/15782/10902 15794/15794/10914 +f 15783/15783/10903 15794/15794/10914 15795/15795/10915 +f 15781/15781/10902 15390/15390/10574 15389/15389/10573 +f 15781/15781/10902 15389/15389/10573 15796/15796/10916 +f 15796/15796/10916 15389/15389/10573 15388/15388/10572 +f 15796/15796/10916 15388/15388/10572 15797/15797/10917 +f 15795/15795/10915 15794/15794/10914 15798/15798/10918 +f 15795/15795/10915 15798/15798/10918 15799/15799/10919 +f 15793/15793/10913 15792/15792/10912 15800/15800/10920 +f 15793/15793/10913 15800/15800/10920 15801/15801/10921 +f 15791/15791/10911 15372/15372/10559 15371/15371/10558 +f 15791/15791/10911 15371/15371/10558 15802/15802/10922 +f 15802/15802/10922 15371/15371/10558 15370/15370/10557 +f 15802/15802/10922 15370/15370/10557 15803/15803/10923 +f 15801/15801/10921 15800/15800/10920 15744/15744/10871 +f 15801/15801/10921 15744/15744/10871 15743/15743/10870 +f 15582/15582/10737 15581/15581/10736 15804/15804/10924 +f 15582/15582/10737 15804/15804/10924 15805/15805/10925 +f 15580/15580/10735 15579/15579/10734 15806/15806/10926 +f 15580/15580/10735 15806/15806/10926 15807/15807/10924 +f 15807/15807/10924 15806/15806/10926 15632/15632/10779 +f 15807/15807/10924 15632/15632/10779 15631/15631/10776 +f 15805/15805/10925 15804/15804/10924 15628/15628/10776 +f 15805/15805/10925 15628/15628/10776 15627/15627/10775 +f 15671/15671/10810 15670/15670/10809 15808/15808/10927 +f 15671/15671/10810 15808/15808/10927 15809/15809/10928 +f 15669/15669/10808 15668/15668/10807 15810/15810/10929 +f 15669/15669/10808 15810/15810/10929 15811/15811/10930 +f 15812/15812/10931 15813/15813/10929 15576/15576/10731 +f 15812/15812/10931 15576/15576/10731 15575/15575/10728 +f 15809/15809/10928 15808/15808/10927 15572/15572/10728 +f 15809/15809/10928 15572/15572/10728 15571/15571/10727 +f 15711/15711/10843 15710/15710/10842 15814/15814/10932 +f 15711/15711/10843 15814/15814/10932 15815/15815/10933 +f 15709/15709/10841 15315/15315/10504 15314/15314/10503 +f 15709/15709/10841 15314/15314/10503 15816/15816/10932 +f 15816/15816/10932 15314/15314/10503 15313/15313/10502 +f 15816/15816/10932 15313/15313/10502 15817/15817/10934 +f 15815/15815/10933 15814/15814/10932 15818/15818/10934 +f 15815/15815/10933 15818/15818/10934 15819/15819/10935 +f 15672/15672/10811 15820/15820/10936 15821/15821/10937 +f 15672/15672/10811 15821/15821/10937 15746/15746/10873 +f 15820/15820/10936 15436/15436/10616 15434/15434/10614 +f 15820/15820/10936 15434/15434/10614 15821/15821/10937 +f 15821/15821/10937 15434/15434/10614 15433/15433/10613 +f 15821/15821/10937 15433/15433/10613 15822/15822/10938 +f 15746/15746/10873 15821/15821/10937 15822/15822/10938 +f 15746/15746/10873 15822/15822/10938 15743/15743/10870 +f 15582/15582/10737 15823/15823/10939 15824/15824/10940 +f 15582/15582/10737 15824/15824/10940 15574/15574/10730 +f 15823/15823/10939 15413/15413/10595 15411/15411/10594 +f 15823/15823/10939 15411/15411/10594 15824/15824/10940 +f 15824/15824/10940 15411/15411/10594 15410/15410/10593 +f 15824/15824/10940 15410/15410/10593 15825/15825/10941 +f 15574/15574/10730 15824/15824/10940 15825/15825/10941 +f 15574/15574/10730 15825/15825/10941 15571/15571/10727 +f 15671/15671/10810 15826/15826/10942 15827/15827/10943 +f 15671/15671/10810 15827/15827/10943 15665/15665/10805 +f 15826/15826/10942 15644/15644/10789 15662/15662/10802 +f 15826/15826/10942 15662/15662/10802 15827/15827/10943 +f 15827/15827/10943 15662/15662/10802 15603/15603/10754 +f 15827/15827/10943 15603/15603/10754 15828/15828/10944 +f 15665/15665/10805 15827/15827/10943 15828/15828/10944 +f 15665/15665/10805 15828/15828/10944 15626/15626/10774 +f 15680/15680/10818 15829/15829/10945 15830/15830/10946 +f 15680/15680/10818 15830/15830/10946 15675/15675/10814 +f 15829/15829/10945 15610/15610/10760 15608/15608/10759 +f 15829/15829/10945 15608/15608/10759 15830/15830/10946 +f 15830/15830/10946 15608/15608/10759 15436/15436/10616 +f 15830/15830/10946 15436/15436/10616 15820/15820/10936 +f 15675/15675/10814 15830/15830/10946 15820/15820/10936 +f 15675/15675/10814 15820/15820/10936 15672/15672/10811 +f 15533/15533/10696 15831/15831/10947 15832/15832/10948 +f 15533/15533/10696 15832/15832/10948 15528/15528/10693 +f 15831/15831/10947 15616/15616/10765 15614/15614/10763 +f 15831/15831/10947 15614/15614/10763 15832/15832/10948 +f 15832/15832/10948 15614/15614/10763 15402/15402/10585 +f 15832/15832/10948 15402/15402/10585 15833/15833/10949 +f 15528/15528/10693 15832/15832/10948 15833/15833/10949 +f 15528/15528/10693 15833/15833/10949 15525/15525/10690 +f 15693/15693/10828 15834/15834/10950 15835/15835/10951 +f 15693/15693/10828 15835/15835/10951 15689/15689/10826 +f 15834/15834/10950 15565/15565/10723 15713/15713/10845 +f 15834/15834/10950 15713/15713/10845 15835/15835/10951 +f 15835/15835/10951 15713/15713/10845 15616/15616/10765 +f 15835/15835/10951 15616/15616/10765 15831/15831/10947 +f 15689/15689/10826 15835/15835/10951 15831/15831/10947 +f 15689/15689/10826 15831/15831/10947 15533/15533/10696 +f 15626/15626/10774 15828/15828/10944 15836/15836/10952 +f 15626/15626/10774 15836/15836/10952 15620/15620/10769 +f 15828/15828/10944 15603/15603/10754 15601/15601/10753 +f 15828/15828/10944 15601/15601/10753 15836/15836/10952 +f 15836/15836/10952 15601/15601/10753 15595/15595/10748 +f 15836/15836/10952 15595/15595/10748 15837/15837/10953 +f 15620/15620/10769 15836/15836/10952 15837/15837/10953 +f 15620/15620/10769 15837/15837/10953 15590/15590/10743 +f 15590/15590/10743 15837/15837/10953 15838/15838/10954 +f 15590/15590/10743 15838/15838/10954 15584/15584/10739 +f 15837/15837/10953 15595/15595/10748 15593/15593/10746 +f 15837/15837/10953 15593/15593/10746 15838/15838/10954 +f 15838/15838/10954 15593/15593/10746 15558/15558/10718 +f 15838/15838/10954 15558/15558/10718 15839/15839/10955 +f 15584/15584/10739 15838/15838/10954 15839/15839/10955 +f 15584/15584/10739 15839/15839/10955 15553/15553/10714 +f 15705/15705/10838 15840/15840/10956 15841/15841/10957 +f 15705/15705/10838 15841/15841/10957 15701/15701/10835 +f 15840/15840/10956 15718/15718/10849 15716/15716/10848 +f 15840/15840/10956 15716/15716/10848 15841/15841/10957 +f 15841/15841/10957 15716/15716/10848 15568/15568/10725 +f 15841/15841/10957 15568/15568/10725 15842/15842/10958 +f 15701/15701/10835 15841/15841/10957 15842/15842/10958 +f 15701/15701/10835 15842/15842/10958 15699/15699/10833 +f 15711/15711/10843 15843/15843/10959 15844/15844/10960 +f 15711/15711/10843 15844/15844/10960 15707/15707/10840 +f 15843/15843/10959 15464/15464/10638 15785/15785/10905 +f 15843/15843/10959 15785/15785/10905 15844/15844/10960 +f 15844/15844/10960 15785/15785/10905 15610/15610/10760 +f 15844/15844/10960 15610/15610/10760 15829/15829/10945 +f 15707/15707/10840 15844/15844/10960 15829/15829/10945 +f 15707/15707/10840 15829/15829/10945 15680/15680/10818 +f 15699/15699/10833 15842/15842/10958 15845/15845/10961 +f 15699/15699/10833 15845/15845/10961 15695/15695/10830 +f 15842/15842/10958 15568/15568/10725 15566/15566/10724 +f 15842/15842/10958 15566/15566/10724 15845/15845/10961 +f 15845/15845/10961 15566/15566/10724 15565/15565/10723 +f 15845/15845/10961 15565/15565/10723 15834/15834/10950 +f 15695/15695/10830 15845/15845/10961 15834/15834/10950 +f 15695/15695/10830 15834/15834/10950 15693/15693/10828 +f 15553/15553/10714 15839/15839/10955 15846/15846/10962 +f 15553/15553/10714 15846/15846/10962 15547/15547/10708 +f 15839/15839/10955 15558/15558/10718 15556/15556/10717 +f 15839/15839/10955 15556/15556/10717 15846/15846/10962 +f 15846/15846/10962 15556/15556/10717 15517/15517/10683 +f 15846/15846/10962 15517/15517/10683 15847/15847/10963 +f 15547/15547/10708 15846/15846/10962 15847/15847/10963 +f 15547/15547/10708 15847/15847/10963 15508/15508/10676 +f 15726/15726/10856 15848/15848/10964 15849/15849/10965 +f 15726/15726/10856 15849/15849/10965 15722/15722/10852 +f 15848/15848/10964 15730/15730/10859 15728/15728/10858 +f 15848/15848/10964 15728/15728/10858 15849/15849/10965 +f 15849/15849/10965 15728/15728/10858 15718/15718/10849 +f 15849/15849/10965 15718/15718/10849 15840/15840/10956 +f 15722/15722/10852 15849/15849/10965 15840/15840/10956 +f 15722/15722/10852 15840/15840/10956 15705/15705/10838 +f 15508/15508/10676 15847/15847/10963 15850/15850/10966 +f 15508/15508/10676 15850/15850/10966 15500/15500/10669 +f 15847/15847/10963 15517/15517/10683 15515/15515/10682 +f 15847/15847/10963 15515/15515/10682 15850/15850/10966 +f 15850/15850/10966 15515/15515/10682 15514/15514/10681 +f 15850/15850/10966 15514/15514/10681 15851/15851/10967 +f 15500/15500/10669 15850/15850/10966 15851/15851/10967 +f 15500/15500/10669 15851/15851/10967 15497/15497/10666 +f 15742/15742/10869 15852/15852/10968 15853/15853/10969 +f 15742/15742/10869 15853/15853/10969 15736/15736/10864 +f 15852/15852/10968 15474/15474/10645 15472/15472/10643 +f 15852/15852/10968 15472/15472/10643 15853/15853/10969 +f 15853/15853/10969 15472/15472/10643 15471/15471/10623 +f 15853/15853/10969 15471/15471/10623 15854/15854/10970 +f 15736/15736/10864 15853/15853/10969 15854/15854/10970 +f 15736/15736/10864 15854/15854/10970 15733/15733/10861 +f 15638/15638/10784 15855/15855/10971 15856/15856/10972 +f 15638/15638/10784 15856/15856/10972 15630/15630/10778 +f 15855/15855/10971 15425/15425/10606 15423/15423/10604 +f 15855/15855/10971 15423/15423/10604 15856/15856/10972 +f 15856/15856/10972 15423/15423/10604 15422/15422/10603 +f 15856/15856/10972 15422/15422/10603 15857/15857/10973 +f 15630/15630/10778 15856/15856/10972 15857/15857/10973 +f 15630/15630/10778 15857/15857/10973 15627/15627/10775 +f 15858/15858/10974 15859/15859/10975 15860/15860/10976 +f 15858/15858/10974 15860/15860/10976 15861/15861/10977 +f 15862/15862/10975 15863/15863/10978 15864/15864/10979 +f 15862/15862/10975 15864/15864/10979 15865/15865/10980 +f 15866/15866/10976 15867/15867/10981 15753/15753/10879 +f 15866/15866/10976 15753/15753/10879 15750/15750/10876 +f 15868/15868/10982 15866/15866/10976 15750/15750/10876 +f 15868/15868/10982 15750/15750/10876 15749/15749/10875 +f 15767/15767/10890 15869/15869/10983 15870/15870/10984 +f 15767/15767/10890 15870/15870/10984 15759/15759/10885 +f 15869/15869/10983 15482/15482/10653 15480/15480/10651 +f 15869/15869/10983 15480/15480/10651 15870/15870/10984 +f 15870/15870/10984 15480/15480/10651 15425/15425/10606 +f 15870/15870/10984 15425/15425/10606 15855/15855/10971 +f 15759/15759/10885 15870/15870/10984 15855/15855/10971 +f 15759/15759/10885 15855/15855/10971 15638/15638/10784 +f 15450/15450/10626 15871/15871/10985 15872/15872/10986 +f 15450/15450/10626 15872/15872/10986 15873/15873/10987 +f 15871/15871/10985 15443/15443/10621 15874/15874/10988 +f 15871/15871/10985 15874/15874/10988 15872/15872/10986 +f 15872/15872/10986 15874/15874/10988 15875/15875/10663 +f 15872/15872/10986 15875/15875/10663 15876/15876/10989 +f 15873/15873/10987 15872/15872/10986 15876/15876/10989 +f 15873/15873/10987 15876/15876/10989 15877/15877/10919 +f 15777/15777/10899 15878/15878/10990 15879/15879/10991 +f 15777/15777/10899 15879/15879/10991 15772/15772/10894 +f 15878/15878/10990 15685/15685/10823 15683/15683/10821 +f 15878/15878/10990 15683/15683/10821 15879/15879/10991 +f 15879/15879/10991 15683/15683/10821 15482/15482/10653 +f 15879/15879/10991 15482/15482/10653 15869/15869/10983 +f 15772/15772/10894 15879/15879/10991 15869/15869/10983 +f 15772/15772/10894 15869/15869/10983 15767/15767/10890 +f 15783/15783/10903 15880/15880/10992 15881/15881/10993 +f 15783/15783/10903 15881/15881/10993 15779/15779/10901 +f 15880/15880/10992 15491/15491/10660 15769/15769/10892 +f 15880/15880/10992 15769/15769/10892 15881/15881/10993 +f 15881/15881/10993 15769/15769/10892 15685/15685/10823 +f 15881/15881/10993 15685/15685/10823 15878/15878/10990 +f 15779/15779/10901 15881/15881/10993 15878/15878/10990 +f 15779/15779/10901 15878/15878/10990 15777/15777/10899 +f 15525/15525/10690 15833/15833/10949 15882/15882/10994 +f 15525/15525/10690 15882/15882/10994 15883/15883/10995 +f 15833/15833/10949 15402/15402/10585 15400/15400/10583 +f 15833/15833/10949 15400/15400/10583 15882/15882/10994 +f 15882/15882/10994 15400/15400/10583 15399/15399/10582 +f 15882/15882/10994 15399/15399/10582 15884/15884/10996 +f 15883/15883/10995 15882/15882/10994 15884/15884/10996 +f 15883/15883/10995 15884/15884/10996 15819/15819/10935 +f 15793/15793/10913 15885/15885/10997 15886/15886/10998 +f 15793/15793/10913 15886/15886/10998 15788/15788/10908 +f 15885/15885/10997 15652/15652/10794 15658/15658/10799 +f 15885/15885/10997 15658/15658/10799 15886/15886/10998 +f 15886/15886/10998 15658/15658/10799 15474/15474/10645 +f 15886/15886/10998 15474/15474/10645 15852/15852/10968 +f 15788/15788/10908 15886/15886/10998 15852/15852/10968 +f 15788/15788/10908 15852/15852/10968 15742/15742/10869 +f 15799/15799/10919 15887/15887/10989 15888/15888/10999 +f 15799/15799/10919 15888/15888/10999 15795/15795/10915 +f 15887/15887/10989 15494/15494/10663 15492/15492/10661 +f 15887/15887/10989 15492/15492/10661 15888/15888/10999 +f 15888/15888/10999 15492/15492/10661 15491/15491/10660 +f 15888/15888/10999 15491/15491/10660 15880/15880/10992 +f 15795/15795/10915 15888/15888/10999 15880/15880/10992 +f 15795/15795/10915 15880/15880/10992 15783/15783/10903 +f 15743/15743/10870 15822/15822/10938 15889/15889/11000 +f 15743/15743/10870 15889/15889/11000 15801/15801/10921 +f 15822/15822/10938 15433/15433/10613 15653/15653/10795 +f 15822/15822/10938 15653/15653/10795 15889/15889/11000 +f 15889/15889/11000 15653/15653/10795 15652/15652/10794 +f 15889/15889/11000 15652/15652/10794 15885/15885/10997 +f 15801/15801/10921 15889/15889/11000 15885/15885/10997 +f 15801/15801/10921 15885/15885/10997 15793/15793/10913 +f 15627/15627/10775 15857/15857/10973 15890/15890/11001 +f 15627/15627/10775 15890/15890/11001 15805/15805/10925 +f 15857/15857/10973 15422/15422/10603 15523/15523/10689 +f 15857/15857/10973 15523/15523/10689 15890/15890/11001 +f 15890/15890/11001 15523/15523/10689 15413/15413/10595 +f 15890/15890/11001 15413/15413/10595 15823/15823/10939 +f 15805/15805/10925 15890/15890/11001 15823/15823/10939 +f 15805/15805/10925 15823/15823/10939 15582/15582/10737 +f 15571/15571/10727 15825/15825/10941 15891/15891/11002 +f 15571/15571/10727 15891/15891/11002 15809/15809/10928 +f 15825/15825/10941 15410/15410/10593 15645/15645/10790 +f 15825/15825/10941 15645/15645/10790 15891/15891/11002 +f 15891/15891/11002 15645/15645/10790 15644/15644/10789 +f 15891/15891/11002 15644/15644/10789 15826/15826/10942 +f 15809/15809/10928 15891/15891/11002 15826/15826/10942 +f 15809/15809/10928 15826/15826/10942 15671/15671/10810 +f 15819/15819/10935 15884/15884/10996 15892/15892/11003 +f 15819/15819/10935 15892/15892/11003 15815/15815/10933 +f 15884/15884/10996 15399/15399/10582 15465/15465/10639 +f 15884/15884/10996 15465/15465/10639 15892/15892/11003 +f 15892/15892/11003 15465/15465/10639 15464/15464/10638 +f 15892/15892/11003 15464/15464/10638 15843/15843/10959 +f 15815/15815/10933 15892/15892/11003 15843/15843/10959 +f 15815/15815/10933 15843/15843/10959 15711/15711/10843 +f 15819/15819/10935 15818/15818/10934 15893/15893/11004 +f 15819/15819/10935 15893/15893/11004 15883/15883/10995 +f 15894/15894/10934 15381/15381/10502 15380/15380/10565 +f 15894/15894/10934 15380/15380/10565 15895/15895/11005 +f 15895/15895/11005 15380/15380/10565 15324/15324/10513 +f 15895/15895/11005 15324/15324/10513 15529/15529/10694 +f 15883/15883/10995 15893/15893/11004 15526/15526/10691 +f 15883/15883/10995 15526/15526/10691 15525/15525/10690 +f 15896/15896/11006 15897/15897/11007 15898/15898/11008 +f 15896/15896/11006 15898/15898/11008 15899/15899/11009 +f 15897/15897/11007 15900/15900/11010 15901/15901/11011 +f 15897/15897/11007 15901/15901/11011 15898/15898/11008 +f 15902/15902/11012 15903/15903/11013 15904/15904/11014 +f 15902/15902/11012 15904/15904/11014 15905/15905/11015 +f 15906/15906/11016 15902/15902/11012 15905/15905/11015 +f 15906/15906/11016 15905/15905/11015 15907/15907/11017 +f 15538/15538/10701 15908/15908/11018 15909/15909/11019 +f 15538/15538/10701 15909/15909/11019 15539/15539/10702 +f 15910/15910/11020 15911/15911/11021 15912/15912/11022 +f 15910/15910/11020 15912/15912/11022 15913/15913/11023 +f 15914/15914/11019 15915/15915/11022 15916/15916/11024 +f 15914/15914/11019 15916/15916/11024 15917/15917/11025 +f 15541/15541/10702 15914/15914/11019 15917/15917/11025 +f 15541/15541/10702 15917/15917/11025 15542/15542/10704 +f 15918/15918/11026 15919/15919/11027 15920/15920/11028 +f 15918/15918/11026 15920/15920/11028 15921/15921/11029 +f 15919/15919/11027 15922/15922/11030 15923/15923/11031 +f 15919/15919/11027 15923/15923/11031 15920/15920/11028 +f 15920/15920/11028 15923/15923/11031 15924/15924/11032 +f 15920/15920/11028 15924/15924/11032 15925/15925/11033 +f 15921/15921/11029 15920/15920/11028 15925/15925/11033 +f 15921/15921/11029 15925/15925/11033 15863/15863/10978 +f 15545/15545/10706 15543/15543/10705 15926/15926/11034 +f 15545/15545/10706 15926/15926/11034 15927/15927/11035 +f 15543/15543/10705 15542/15542/10704 15928/15928/11036 +f 15543/15543/10705 15928/15928/11036 15926/15926/11034 +f 15926/15926/11034 15928/15928/11036 15896/15896/11006 +f 15926/15926/11034 15896/15896/11006 15929/15929/11037 +f 15927/15927/11035 15926/15926/11034 15929/15929/11037 +f 15927/15927/11035 15929/15929/11037 15930/15930/11038 +f 15930/15930/11038 15929/15929/11037 15931/15931/11039 +f 15930/15930/11038 15931/15931/11039 15932/15932/11040 +f 15929/15929/11037 15896/15896/11006 15899/15899/11009 +f 15929/15929/11037 15899/15899/11009 15931/15931/11039 +f 15933/15933/11039 15934/15934/11016 15935/15935/11017 +f 15933/15933/11039 15935/15935/11017 15936/15936/11041 +f 15937/15937/11040 15933/15933/11039 15936/15936/11041 +f 15937/15937/11040 15936/15936/11041 15938/15938/11042 +f 15939/15939/11043 15940/15940/11044 15941/15941/11045 +f 15939/15939/11043 15941/15941/11045 15942/15942/11046 +f 15940/15940/11044 15943/15943/11026 15944/15944/11029 +f 15940/15940/11044 15944/15944/11029 15941/15941/11045 +f 15941/15941/11045 15944/15944/11029 15945/15945/10978 +f 15941/15941/11045 15945/15945/10978 15859/15859/10975 +f 15942/15942/11046 15941/15941/11045 15859/15859/10975 +f 15942/15942/11046 15859/15859/10975 15858/15858/10974 +f 15757/15757/10883 15756/15756/10882 15946/15946/11047 +f 15757/15757/10883 15946/15946/11047 15947/15947/11048 +f 15756/15756/10882 15755/15755/10881 15948/15948/11049 +f 15756/15756/10882 15948/15948/11049 15946/15946/11047 +f 15949/15949/11050 15950/15950/11049 15951/15951/11051 +f 15949/15949/11050 15951/15951/11051 15952/15952/11052 +f 15953/15953/11048 15949/15949/11050 15952/15952/11052 +f 15953/15953/11048 15952/15952/11052 15954/15954/11053 +f 15955/15955/11054 15956/15956/11055 15957/15957/11056 +f 15955/15955/11054 15957/15957/11056 15958/15958/11057 +f 15956/15956/11055 15959/15959/11058 15960/15960/11059 +f 15956/15956/11055 15960/15960/11059 15957/15957/11056 +f 15957/15957/11056 15960/15960/11059 15538/15538/10701 +f 15957/15957/11056 15538/15538/10701 15535/15535/10698 +f 15958/15958/11057 15957/15957/11056 15535/15535/10698 +f 15958/15958/11057 15535/15535/10698 15534/15534/10697 +f 15922/15922/11030 15961/15961/11060 15962/15962/11061 +f 15922/15922/11030 15962/15962/11061 15923/15923/11031 +f 15963/15963/11062 15964/15964/11063 15965/15965/11064 +f 15963/15963/11062 15965/15965/11064 15966/15966/11065 +f 15966/15966/11065 15965/15965/11064 15967/15967/11066 +f 15966/15966/11065 15967/15967/11066 15968/15968/11067 +f 15923/15923/11031 15962/15962/11061 15969/15969/11068 +f 15923/15923/11031 15969/15969/11068 15924/15924/11032 +f 15970/15970/11069 15971/15971/11070 15972/15972/11071 +f 15970/15970/11069 15972/15972/11071 15973/15973/11072 +f 15971/15971/11070 15974/15974/11073 15975/15975/11074 +f 15971/15971/11070 15975/15975/11074 15972/15972/11071 +f 15972/15972/11071 15975/15975/11074 15976/15976/11075 +f 15972/15972/11071 15976/15976/11075 15977/15977/11076 +f 15973/15973/11072 15972/15972/11071 15977/15977/11076 +f 15973/15973/11072 15977/15977/11076 15978/15978/11077 +f 15970/15970/11069 15979/15979/11078 15980/15980/11079 +f 15970/15970/11069 15980/15980/11079 15981/15981/11080 +f 15979/15979/11078 15964/15964/11063 15982/15982/11081 +f 15979/15979/11078 15982/15982/11081 15980/15980/11079 +f 15980/15980/11079 15982/15982/11081 15983/15983/11082 +f 15980/15980/11079 15983/15983/11082 15984/15984/11083 +f 15981/15981/11080 15980/15980/11079 15984/15984/11083 +f 15981/15981/11080 15984/15984/11083 15985/15985/11084 +f 15753/15753/10879 15986/15986/11085 15987/15987/11086 +f 15753/15753/10879 15987/15987/11086 15754/15754/10880 +f 15988/15988/11085 15967/15967/11066 15989/15989/11087 +f 15988/15988/11085 15989/15989/11087 15990/15990/11086 +f 15990/15990/11086 15989/15989/11087 15978/15978/11077 +f 15990/15990/11086 15978/15978/11077 15991/15991/11088 +f 15754/15754/10880 15987/15987/11086 15992/15992/11088 +f 15754/15754/10880 15992/15992/11088 15755/15755/10881 +f 15959/15959/11058 15993/15993/11089 15994/15994/11090 +f 15959/15959/11058 15994/15994/11090 15960/15960/11059 +f 15995/15995/11089 15996/15996/11091 15997/15997/11092 +f 15995/15995/11089 15997/15997/11092 15998/15998/11093 +f 15998/15998/11093 15997/15997/11092 15911/15911/11021 +f 15998/15998/11093 15911/15911/11021 15910/15910/11020 +f 15960/15960/11059 15994/15994/11090 15908/15908/11018 +f 15960/15960/11059 15908/15908/11018 15538/15538/10701 +f 15863/15863/10978 15925/15925/11033 15999/15999/11094 +f 15863/15863/10978 15999/15999/11094 15864/15864/10979 +f 15925/15925/11033 15924/15924/11032 15969/15969/11068 +f 15925/15925/11033 15969/15969/11068 15999/15999/11094 +f 16000/16000/11095 15968/15968/11067 15967/15967/11066 +f 16000/16000/11095 15967/15967/11066 15988/15988/11085 +f 15867/15867/10981 16001/16001/11094 15986/15986/11085 +f 15867/15867/10981 15986/15986/11085 15753/15753/10879 +f 16002/16002/10881 15991/15991/11088 16003/16003/11096 +f 16002/16002/10881 16003/16003/11096 16004/16004/11049 +f 15991/15991/11088 15978/15978/11077 15977/15977/11076 +f 15991/15991/11088 15977/15977/11076 16003/16003/11096 +f 16003/16003/11096 15977/15977/11076 15976/15976/11075 +f 16003/16003/11096 15976/15976/11075 16005/16005/11097 +f 16006/16006/11098 16007/16007/11096 16008/16008/11099 +f 16006/16006/11098 16008/16008/11099 16009/16009/11051 +f 15542/15542/10704 15917/15917/11025 16010/16010/11100 +f 15542/15542/10704 16010/16010/11100 15928/15928/11036 +f 15917/15917/11025 15916/15916/11024 16011/16011/11101 +f 15917/15917/11025 16011/16011/11101 16010/16010/11100 +f 16010/16010/11100 16011/16011/11101 15900/15900/11010 +f 16010/16010/11100 15900/15900/11010 15897/15897/11007 +f 15928/15928/11036 16010/16010/11100 15897/15897/11007 +f 15928/15928/11036 15897/15897/11007 15896/15896/11006 +f 16012/16012/11102 16013/16013/11103 16014/16014/11104 +f 16012/16012/11102 16014/16014/11104 16015/16015/11105 +f 16016/16016/11103 16017/16017/11106 16018/16018/11107 +f 16016/16016/11103 16018/16018/11107 16019/16019/11108 +f 16020/16020/11104 16021/16021/11109 16022/16022/11110 +f 16020/16020/11104 16022/16022/11110 16023/16023/11111 +f 16024/16024/11112 16020/16020/11104 16023/16023/11111 +f 16024/16024/11112 16023/16023/11111 16025/16025/11113 +f 16026/16026/11114 16027/16027/11115 16028/16028/11116 +f 16026/16026/11114 16028/16028/11116 16029/16029/11117 +f 16027/16027/11115 15757/15757/10883 15947/15947/11048 +f 16027/16027/11115 15947/15947/11048 16028/16028/11116 +f 16030/16030/11118 15953/15953/11048 15954/15954/11053 +f 16030/16030/11118 15954/15954/11053 16031/16031/11119 +f 16032/16032/11117 16030/16030/11118 16031/16031/11119 +f 16032/16032/11117 16031/16031/11119 16033/16033/11120 +f 16034/16034/11121 16035/16035/11122 16036/16036/11123 +f 16034/16034/11121 16036/16036/11123 16037/16037/11124 +f 16038/16038/11125 16039/16039/11126 16036/16036/11123 +f 16038/16038/11125 16036/16036/11123 16035/16035/11122 +f 16040/16040/11127 16041/16041/11128 16036/16036/11123 +f 16040/16040/11127 16036/16036/11123 16039/16039/11126 +f 16042/16042/11129 16043/16043/11130 16036/16036/11123 +f 16042/16042/11129 16036/16036/11123 16041/16041/11128 +f 16044/16044/11131 16037/16037/11124 16036/16036/11123 +f 16044/16044/11131 16036/16036/11123 16043/16043/11130 +f 16045/16045/11132 16046/16046/11133 16047/16047/11134 +f 16045/16045/11132 16047/16047/11134 16048/16048/11135 +f 16046/16046/11133 15930/15930/11038 15932/15932/11040 +f 16046/16046/11133 15932/15932/11040 16047/16047/11134 +f 16049/16049/11134 15937/15937/11040 15938/15938/11042 +f 16049/16049/11134 15938/15938/11042 16050/16050/11136 +f 16051/16051/11135 16049/16049/11134 16050/16050/11136 +f 16051/16051/11135 16050/16050/11136 16052/16052/11137 +f 16053/16053/11138 16054/16054/11139 16055/16055/11140 +f 16053/16053/11138 16055/16055/11140 16056/16056/11141 +f 16054/16054/11139 15545/15545/10706 15927/15927/11035 +f 16054/16054/11139 15927/15927/11035 16055/16055/11140 +f 16055/16055/11140 15927/15927/11035 15930/15930/11038 +f 16055/16055/11140 15930/15930/11038 16046/16046/11133 +f 16056/16056/11141 16055/16055/11140 16046/16046/11133 +f 16056/16056/11141 16046/16046/11133 16045/16045/11132 +f 16057/16057/11142 16058/16058/11143 16059/16059/11144 +f 16057/16057/11142 16059/16059/11144 16060/16060/11145 +f 16058/16058/11143 15858/15858/10974 15861/15861/10977 +f 16058/16058/11143 15861/15861/10977 16059/16059/11144 +f 16061/16061/11144 15868/15868/10982 15749/15749/10875 +f 16061/16061/11144 15749/15749/10875 16062/16062/11146 +f 16063/16063/11147 16061/16061/11144 16062/16062/11146 +f 16063/16063/11147 16062/16062/11146 16064/16064/11148 +f 16064/16064/11148 16062/16062/11146 16065/16065/11149 +f 16064/16064/11148 16065/16065/11149 16066/16066/11150 +f 16062/16062/11146 15749/15749/10875 15752/15752/10878 +f 16062/16062/11146 15752/15752/10878 16065/16065/11149 +f 16065/16065/11149 15752/15752/10878 15757/15757/10883 +f 16065/16065/11149 15757/15757/10883 16027/16027/11115 +f 16066/16066/11150 16065/16065/11149 16027/16027/11115 +f 16066/16066/11150 16027/16027/11115 16026/16026/11114 +f 16042/16042/11129 16067/16067/11151 16068/16068/11152 +f 16042/16042/11129 16068/16068/11152 16069/16069/11153 +f 16067/16067/11151 15534/15534/10697 15537/15537/10700 +f 16067/16067/11151 15537/15537/10700 16068/16068/11152 +f 16070/16070/11154 15544/15544/10700 15545/15545/10706 +f 16070/16070/11154 15545/15545/10706 16054/16054/11139 +f 16071/16071/11155 16070/16070/11154 16054/16054/11139 +f 16071/16071/11155 16054/16054/11139 16053/16053/11138 +f 16072/16072/11156 16073/16073/11157 16074/16074/11158 +f 16072/16072/11156 16074/16074/11158 16075/16075/11159 +f 16073/16073/11157 16076/16076/11160 16077/16077/11161 +f 16073/16073/11157 16077/16077/11161 16074/16074/11158 +f 16078/16078/11158 16079/16079/11162 16080/16080/11163 +f 16078/16078/11158 16080/16080/11163 16081/16081/11164 +f 16082/16082/11165 16078/16078/11158 16081/16081/11164 +f 16082/16082/11165 16081/16081/11164 16083/16083/11166 +f 16084/16084/11167 16085/16085/11168 16086/16086/11169 +f 16084/16084/11167 16086/16086/11169 16087/16087/11170 +f 16085/16085/11168 16088/16088/11171 16089/16089/11172 +f 16085/16085/11168 16089/16089/11172 16086/16086/11169 +f 16086/16086/11169 16089/16089/11172 16090/16090/11173 +f 16086/16086/11169 16090/16090/11173 16091/16091/11174 +f 16087/16087/11170 16086/16086/11169 16091/16091/11174 +f 16087/16087/11170 16091/16091/11174 16092/16092/11175 +f 16093/16093/11176 16094/16094/11177 16095/16095/11178 +f 16093/16093/11176 16095/16095/11178 16096/16096/11179 +f 16094/16094/11177 16097/16097/11180 16098/16098/11181 +f 16094/16094/11177 16098/16098/11181 16095/16095/11178 +f 16099/16099/11182 16100/16100/11183 16088/16088/11171 +f 16099/16099/11182 16088/16088/11171 16085/16085/11168 +f 16101/16101/11179 16099/16099/11182 16085/16085/11168 +f 16101/16101/11179 16085/16085/11168 16084/16084/11167 +f 16083/16083/11166 16081/16081/11164 16102/16102/11184 +f 16083/16083/11166 16102/16102/11184 16103/16103/11185 +f 16081/16081/11164 16080/16080/11163 16104/16104/11186 +f 16081/16081/11164 16104/16104/11186 16102/16102/11184 +f 16102/16102/11184 16104/16104/11186 16105/16105/11187 +f 16102/16102/11184 16105/16105/11187 16106/16106/11188 +f 16103/16103/11185 16102/16102/11184 16106/16106/11188 +f 16103/16103/11185 16106/16106/11188 16107/16107/11189 +f 16107/16107/11189 16106/16106/11188 16108/16108/11190 +f 16107/16107/11189 16108/16108/11190 16109/16109/11191 +f 16106/16106/11188 16105/16105/11187 16110/16110/11192 +f 16106/16106/11188 16110/16110/11192 16108/16108/11190 +f 16111/16111/11190 16112/16112/11193 16113/16113/11194 +f 16111/16111/11190 16113/16113/11194 16114/16114/11195 +f 16115/16115/11191 16111/16111/11190 16114/16114/11195 +f 16115/16115/11191 16114/16114/11195 16116/16116/11196 +f 16117/16117/11197 16118/16118/11198 16119/16119/11199 +f 16117/16117/11197 16119/16119/11199 16120/16120/11200 +f 16118/16118/11198 16121/16121/11201 16122/16122/11202 +f 16118/16118/11198 16122/16122/11202 16119/16119/11199 +f 16119/16119/11199 16122/16122/11202 16097/16097/11180 +f 16119/16119/11199 16097/16097/11180 16094/16094/11177 +f 16120/16120/11200 16119/16119/11199 16094/16094/11177 +f 16120/16120/11200 16094/16094/11177 16093/16093/11176 +f 16092/16092/11175 16091/16091/11174 16123/16123/11203 +f 16092/16092/11175 16123/16123/11203 16124/16124/11204 +f 16091/16091/11174 16090/16090/11173 16125/16125/11205 +f 16091/16091/11174 16125/16125/11205 16123/16123/11203 +f 16126/16126/11206 16127/16127/11205 16128/16128/11207 +f 16126/16126/11206 16128/16128/11207 16129/16129/11208 +f 16130/16130/11209 16126/16126/11206 16129/16129/11208 +f 16130/16130/11209 16129/16129/11208 16131/16131/11210 +f 16132/16132/11211 16133/16133/11212 16134/16134/11213 +f 16132/16132/11211 16134/16134/11213 16135/16135/11214 +f 16133/16133/11212 16136/16136/11215 16137/16137/11216 +f 16133/16133/11212 16137/16137/11216 16134/16134/11213 +f 16134/16134/11213 16137/16137/11216 16076/16076/11160 +f 16134/16134/11213 16076/16076/11160 16073/16073/11157 +f 16135/16135/11214 16134/16134/11213 16073/16073/11157 +f 16135/16135/11214 16073/16073/11157 16072/16072/11156 +f 15345/15345/10534 16138/16138/11217 16139/16139/11218 +f 15345/15345/10534 16139/16139/11218 15346/15346/10535 +f 16138/16138/11217 16132/16132/11211 16135/16135/11214 +f 16138/16138/11217 16135/16135/11214 16139/16139/11218 +f 16139/16139/11218 16135/16135/11214 16072/16072/11156 +f 16139/16139/11218 16072/16072/11156 16140/16140/11219 +f 15346/15346/10535 16139/16139/11218 16140/16140/11219 +f 15346/15346/10535 16140/16140/11219 15347/15347/10536 +f 15497/15497/10666 16141/16141/11220 16142/16142/11221 +f 15497/15497/10666 16142/16142/11221 15498/15498/10667 +f 16141/16141/11220 16092/16092/11175 16124/16124/11204 +f 16141/16141/11220 16124/16124/11204 16142/16142/11221 +f 16143/16143/11221 16130/16130/11209 16131/16131/11210 +f 16143/16143/11221 16131/16131/11210 16144/16144/11222 +f 15501/15501/10670 16143/16143/11221 16144/16144/11222 +f 15501/15501/10670 16144/16144/11222 15502/15502/10671 +f 15259/15259/10451 16145/16145/11223 16146/16146/11224 +f 15259/15259/10451 16146/16146/11224 16147/16147/11225 +f 16145/16145/11223 16117/16117/11197 16120/16120/11200 +f 16145/16145/11223 16120/16120/11200 16146/16146/11224 +f 16146/16146/11224 16120/16120/11200 16093/16093/11176 +f 16146/16146/11224 16093/16093/11176 16148/16148/11226 +f 16147/16147/11225 16146/16146/11224 16148/16148/11226 +f 16147/16147/11225 16148/16148/11226 15509/15509/10677 +f 15730/15730/10859 16149/16149/11227 16150/16150/11228 +f 15730/15730/10859 16150/16150/11228 15731/15731/10860 +f 16149/16149/11227 16107/16107/11189 16109/16109/11191 +f 16149/16149/11227 16109/16109/11191 16150/16150/11228 +f 16151/16151/11229 16115/16115/11191 16116/16116/11196 +f 16151/16151/11229 16116/16116/11196 16152/16152/11230 +f 15732/15732/10860 16151/16151/11229 16152/16152/11230 +f 15732/15732/10860 16152/16152/11230 15257/15257/10449 +f 15726/15726/10856 16153/16153/11231 16154/16154/11232 +f 15726/15726/10856 16154/16154/11232 15848/15848/10964 +f 16153/16153/11231 16083/16083/11166 16103/16103/11185 +f 16153/16153/11231 16103/16103/11185 16154/16154/11232 +f 16154/16154/11232 16103/16103/11185 16107/16107/11189 +f 16154/16154/11232 16107/16107/11189 16149/16149/11227 +f 15848/15848/10964 16154/16154/11232 16149/16149/11227 +f 15848/15848/10964 16149/16149/11227 15730/15730/10859 +f 15509/15509/10677 16148/16148/11226 16155/16155/11233 +f 15509/15509/10677 16155/16155/11233 15510/15510/10678 +f 16148/16148/11226 16093/16093/11176 16096/16096/11179 +f 16148/16148/11226 16096/16096/11179 16155/16155/11233 +f 16156/16156/11234 16101/16101/11179 16084/16084/11167 +f 16156/16156/11234 16084/16084/11167 16157/16157/11235 +f 15513/15513/10678 16156/16156/11234 16157/16157/11235 +f 15513/15513/10678 16157/16157/11235 15514/15514/10681 +f 15514/15514/10681 16157/16157/11235 16158/16158/11236 +f 15514/15514/10681 16158/16158/11236 15851/15851/10967 +f 16157/16157/11235 16084/16084/11167 16087/16087/11170 +f 16157/16157/11235 16087/16087/11170 16158/16158/11236 +f 16158/16158/11236 16087/16087/11170 16092/16092/11175 +f 16158/16158/11236 16092/16092/11175 16141/16141/11220 +f 15851/15851/10967 16158/16158/11236 16141/16141/11220 +f 15851/15851/10967 16141/16141/11220 15497/15497/10666 +f 15347/15347/10536 16140/16140/11219 16159/16159/11237 +f 15347/15347/10536 16159/16159/11237 15724/15724/10854 +f 16140/16140/11219 16072/16072/11156 16075/16075/11159 +f 16140/16140/11219 16075/16075/11159 16159/16159/11237 +f 16160/16160/11237 16082/16082/11165 16083/16083/11166 +f 16160/16160/11237 16083/16083/11166 16153/16153/11231 +f 15725/15725/10855 16160/16160/11237 16153/16153/11231 +f 15725/15725/10855 16153/16153/11231 15726/15726/10856 +f 16076/16076/11160 16161/16161/11238 16162/16162/11239 +f 16076/16076/11160 16162/16162/11239 16077/16077/11161 +f 16161/16161/11238 16163/16163/11240 16164/16164/11241 +f 16161/16161/11238 16164/16164/11241 16162/16162/11239 +f 16165/16165/11239 16166/16166/11241 16167/16167/11242 +f 16165/16165/11239 16167/16167/11242 16168/16168/11243 +f 16079/16079/11162 16165/16165/11239 16168/16168/11243 +f 16079/16079/11162 16168/16168/11243 16080/16080/11163 +f 16088/16088/11171 16169/16169/11244 16170/16170/11245 +f 16088/16088/11171 16170/16170/11245 16089/16089/11172 +f 16169/16169/11244 16171/16171/11246 16172/16172/11247 +f 16169/16169/11244 16172/16172/11247 16170/16170/11245 +f 16170/16170/11245 16172/16172/11247 16173/16173/11248 +f 16170/16170/11245 16173/16173/11248 16174/16174/11249 +f 16089/16089/11172 16170/16170/11245 16174/16174/11249 +f 16089/16089/11172 16174/16174/11249 16090/16090/11173 +f 16097/16097/11180 16175/16175/11250 16176/16176/11251 +f 16097/16097/11180 16176/16176/11251 16098/16098/11181 +f 16175/16175/11250 16177/16177/11252 16178/16178/11253 +f 16175/16175/11250 16178/16178/11253 16176/16176/11251 +f 16179/16179/11251 16180/16180/11253 16171/16171/11246 +f 16179/16179/11251 16171/16171/11246 16169/16169/11244 +f 16100/16100/11183 16179/16179/11251 16169/16169/11244 +f 16100/16100/11183 16169/16169/11244 16088/16088/11171 +f 16080/16080/11163 16168/16168/11243 16181/16181/11254 +f 16080/16080/11163 16181/16181/11254 16104/16104/11186 +f 16168/16168/11243 16167/16167/11242 16182/16182/11255 +f 16168/16168/11243 16182/16182/11255 16181/16181/11254 +f 16181/16181/11254 16182/16182/11255 16183/16183/11256 +f 16181/16181/11254 16183/16183/11256 16184/16184/11257 +f 16104/16104/11186 16181/16181/11254 16184/16184/11257 +f 16104/16104/11186 16184/16184/11257 16105/16105/11187 +f 16105/16105/11187 16184/16184/11257 16185/16185/11258 +f 16105/16105/11187 16185/16185/11258 16110/16110/11192 +f 16186/16186/11257 16187/16187/11259 16188/16188/11260 +f 16186/16186/11257 16188/16188/11260 16189/16189/11261 +f 16189/16189/11261 16188/16188/11260 16190/16190/11262 +f 16189/16189/11261 16190/16190/11262 16191/16191/11263 +f 16112/16112/11193 16189/16189/11261 16191/16191/11263 +f 16112/16112/11193 16191/16191/11263 16113/16113/11194 +f 16192/16192/11264 16193/16193/11265 16194/16194/11266 +f 16192/16192/11264 16194/16194/11266 16195/16195/11267 +f 16196/16196/11268 16197/16197/11269 16194/16194/11266 +f 16196/16196/11268 16194/16194/11266 16193/16193/11265 +f 16198/16198/11270 16199/16199/11271 16194/16194/11266 +f 16198/16198/11270 16194/16194/11266 16197/16197/11269 +f 16200/16200/11272 16201/16201/11273 16194/16194/11266 +f 16200/16200/11272 16194/16194/11266 16199/16199/11271 +f 16177/16177/11252 16195/16195/11267 16194/16194/11266 +f 16177/16177/11252 16194/16194/11266 16201/16201/11273 +f 16090/16090/11173 16174/16174/11249 16202/16202/11274 +f 16090/16090/11173 16202/16202/11274 16125/16125/11205 +f 16174/16174/11249 16173/16173/11248 16203/16203/11275 +f 16174/16174/11249 16203/16203/11275 16202/16202/11274 +f 16204/16204/11274 16205/16205/11275 16206/16206/11276 +f 16204/16204/11274 16206/16206/11276 16207/16207/11277 +f 16127/16127/11205 16204/16204/11274 16207/16207/11277 +f 16127/16127/11205 16207/16207/11277 16128/16128/11207 +f 16208/16208/11278 16209/16209/11279 16210/16210/11280 +f 16208/16208/11278 16210/16210/11280 16211/16211/11281 +f 16212/16212/11282 16213/16213/11283 16210/16210/11280 +f 16212/16212/11282 16210/16210/11280 16209/16209/11279 +f 16034/16034/11121 16037/16037/11124 16210/16210/11280 +f 16034/16034/11121 16210/16210/11280 16213/16213/11283 +f 16044/16044/11131 16214/16214/11284 16210/16210/11280 +f 16044/16044/11131 16210/16210/11280 16037/16037/11124 +f 16163/16163/11240 16211/16211/11281 16210/16210/11280 +f 16163/16163/11240 16210/16210/11280 16214/16214/11284 +f 16163/16163/11240 16214/16214/11284 16215/16215/11285 +f 16163/16163/11240 16215/16215/11285 16164/16164/11241 +f 16214/16214/11284 16044/16044/11131 16216/16216/11286 +f 16214/16214/11284 16216/16216/11286 16215/16215/11285 +f 16217/16217/11285 16218/16218/11286 16219/16219/11287 +f 16217/16217/11285 16219/16219/11287 16220/16220/11288 +f 16166/16166/11241 16217/16217/11285 16220/16220/11288 +f 16166/16166/11241 16220/16220/11288 16167/16167/11242 +f 16171/16171/11246 16221/16221/11289 16222/16222/11290 +f 16171/16171/11246 16222/16222/11290 16172/16172/11247 +f 16221/16221/11289 16223/16223/11291 16224/16224/11292 +f 16221/16221/11289 16224/16224/11292 16222/16222/11290 +f 16222/16222/11290 16224/16224/11292 16225/16225/11293 +f 16222/16222/11290 16225/16225/11293 16226/16226/11294 +f 16172/16172/11247 16222/16222/11290 16226/16226/11294 +f 16172/16172/11247 16226/16226/11294 16173/16173/11248 +f 16177/16177/11252 16201/16201/11273 16227/16227/11295 +f 16177/16177/11252 16227/16227/11295 16178/16178/11253 +f 16201/16201/11273 16200/16200/11272 16228/16228/11296 +f 16201/16201/11273 16228/16228/11296 16227/16227/11295 +f 16229/16229/11295 16230/16230/11296 16223/16223/11291 +f 16229/16229/11295 16223/16223/11291 16221/16221/11289 +f 16180/16180/11253 16229/16229/11295 16221/16221/11289 +f 16180/16180/11253 16221/16221/11289 16171/16171/11246 +f 16167/16167/11242 16220/16220/11288 16231/16231/11297 +f 16167/16167/11242 16231/16231/11297 16182/16182/11255 +f 16220/16220/11288 16219/16219/11287 16232/16232/11298 +f 16220/16220/11288 16232/16232/11298 16231/16231/11297 +f 16231/16231/11297 16232/16232/11298 16233/16233/11299 +f 16231/16231/11297 16233/16233/11299 16234/16234/11300 +f 16182/16182/11255 16231/16231/11297 16234/16234/11300 +f 16182/16182/11255 16234/16234/11300 16183/16183/11256 +f 16187/16187/11259 16235/16235/11300 16236/16236/11301 +f 16187/16187/11259 16236/16236/11301 16188/16188/11260 +f 16235/16235/11300 16237/16237/11299 16238/16238/11302 +f 16235/16235/11300 16238/16238/11302 16236/16236/11301 +f 16236/16236/11301 16238/16238/11302 16239/16239/11303 +f 16236/16236/11301 16239/16239/11303 16240/16240/11304 +f 16188/16188/11260 16236/16236/11301 16240/16240/11304 +f 16188/16188/11260 16240/16240/11304 16190/16190/11262 +f 16128/16128/11207 16207/16207/11277 16241/16241/11305 +f 16128/16128/11207 16241/16241/11305 16242/16242/11306 +f 16206/16206/11276 16243/16243/11307 16241/16241/11305 +f 16206/16206/11276 16241/16241/11305 16207/16207/11277 +f 16244/16244/11308 16245/16245/11309 16241/16241/11305 +f 16244/16244/11308 16241/16241/11305 16243/16243/11307 +f 16246/16246/11310 16247/16247/11311 16241/16241/11305 +f 16246/16246/11310 16241/16241/11305 16245/16245/11309 +f 16136/16136/11215 16242/16242/11306 16241/16241/11305 +f 16136/16136/11215 16241/16241/11305 16247/16247/11311 +f 16248/16248/11248 16249/16249/11294 16250/16250/11312 +f 16248/16248/11248 16250/16250/11312 16205/16205/11275 +f 16249/16249/11294 16251/16251/11313 16252/16252/11314 +f 16249/16249/11294 16252/16252/11314 16250/16250/11312 +f 16250/16250/11312 16252/16252/11314 16253/16253/11315 +f 16250/16250/11312 16253/16253/11315 16254/16254/11316 +f 16205/16205/11275 16250/16250/11312 16254/16254/11316 +f 16205/16205/11275 16254/16254/11316 16206/16206/11276 +f 16255/16255/11317 16256/16256/11318 16257/16257/11319 +f 16255/16255/11317 16257/16257/11319 16258/16258/11320 +f 16259/16259/11321 16260/16260/11322 16261/16261/11323 +f 16259/16259/11321 16261/16261/11323 16262/16262/11319 +f 16263/16263/11324 16264/16264/11323 16265/16265/11325 +f 16263/16263/11324 16265/16265/11325 16266/16266/11326 +f 16267/16267/11327 16263/16263/11324 16266/16266/11326 +f 16267/16267/11327 16266/16266/11326 16196/16196/11268 +f 16268/16268/11328 16269/16269/11329 16270/16270/11330 +f 16268/16268/11328 16270/16270/11330 16271/16271/11331 +f 16272/16272/11329 16273/16273/11332 16274/16274/11333 +f 16272/16272/11329 16274/16274/11333 16275/16275/11334 +f 16276/16276/11335 16277/16277/11336 16278/16278/11337 +f 16276/16276/11335 16278/16278/11337 16279/16279/11338 +f 16277/16277/11336 16280/16280/11339 16281/16281/11340 +f 16277/16277/11336 16281/16281/11340 16278/16278/11337 +f 16282/16282/11337 16283/16283/11341 16284/16284/11342 +f 16282/16282/11337 16284/16284/11342 16285/16285/11343 +f 16279/16279/11338 16278/16278/11337 16286/16286/11343 +f 16279/16279/11338 16286/16286/11343 16287/16287/11344 +f 16288/16288/11345 16289/16289/11346 16290/16290/11347 +f 16288/16288/11345 16290/16290/11347 16291/16291/11348 +f 16274/16274/11333 16273/16273/11332 16292/16292/11349 +f 16274/16274/11333 16292/16292/11349 16293/16293/11347 +f 16293/16293/11347 16292/16292/11349 16294/16294/11350 +f 16293/16293/11347 16294/16294/11350 16295/16295/11351 +f 16291/16291/11348 16290/16290/11347 16296/16296/11351 +f 16291/16291/11348 16296/16296/11351 16297/16297/11352 +f 16284/16284/11342 16283/16283/11341 16298/16298/11353 +f 16284/16284/11342 16298/16298/11353 16299/16299/11354 +f 16281/16281/11340 16280/16280/11339 16300/16300/11355 +f 16281/16281/11340 16300/16300/11355 16301/16301/11356 +f 16301/16301/11356 16300/16300/11355 16302/16302/11357 +f 16301/16301/11356 16302/16302/11357 16303/16303/11358 +f 16299/16299/11354 16298/16298/11353 16304/16304/11359 +f 16299/16299/11354 16304/16304/11359 16305/16305/11360 +f 16305/16305/11360 16306/16306/11361 16307/16307/11362 +f 16305/16305/11360 16307/16307/11362 16299/16299/11354 +f 16306/16306/11361 16294/16294/11350 16292/16292/11349 +f 16306/16306/11361 16292/16292/11349 16307/16307/11362 +f 16307/16307/11362 16292/16292/11349 16273/16273/11332 +f 16307/16307/11362 16273/16273/11332 16308/16308/11363 +f 16299/16299/11354 16307/16307/11362 16308/16308/11363 +f 16299/16299/11354 16308/16308/11363 16284/16284/11342 +f 16309/16309/11364 16310/16310/11365 16311/16311/11366 +f 16309/16309/11364 16311/16311/11366 16312/16312/11367 +f 16313/16313/11368 16294/16294/11350 16306/16306/11361 +f 16313/16313/11368 16306/16306/11361 16314/16314/11366 +f 16314/16314/11366 16306/16306/11361 16305/16305/11360 +f 16314/16314/11366 16305/16305/11360 16315/16315/11369 +f 16312/16312/11367 16311/16311/11366 16316/16316/11369 +f 16312/16312/11367 16316/16316/11369 16317/16317/11370 +f 16318/16318/11371 16319/16319/11372 16320/16320/11373 +f 16318/16318/11371 16320/16320/11373 16321/16321/11374 +f 16319/16319/11372 16302/16302/11357 16300/16300/11355 +f 16319/16319/11372 16300/16300/11355 16320/16320/11373 +f 16320/16320/11373 16300/16300/11355 16280/16280/11339 +f 16320/16320/11373 16280/16280/11339 16277/16277/11336 +f 16321/16321/11374 16320/16320/11373 16277/16277/11336 +f 16321/16321/11374 16277/16277/11336 16276/16276/11335 +f 16322/16322/11375 16295/16295/11351 16294/16294/11350 +f 16322/16322/11375 16294/16294/11350 16313/16313/11368 +f 16323/16323/11376 16324/16324/11375 16325/16325/11368 +f 16323/16323/11376 16325/16325/11368 16326/16326/11377 +f 16327/16327/11370 16328/16328/11378 16329/16329/11379 +f 16327/16327/11370 16329/16329/11379 16330/16330/11380 +f 16315/16315/11369 16305/16305/11360 16304/16304/11359 +f 16315/16315/11369 16304/16304/11359 16331/16331/11379 +f 16329/16329/11379 16303/16303/11358 16302/16302/11357 +f 16329/16329/11379 16302/16302/11357 16319/16319/11372 +f 16330/16330/11380 16329/16329/11379 16319/16319/11372 +f 16330/16330/11380 16319/16319/11372 16318/16318/11371 +f 16332/16332/11381 16333/16333/11382 16334/16334/11383 +f 16332/16332/11381 16334/16334/11383 16335/16335/11384 +f 16285/16285/11343 16284/16284/11342 16308/16308/11363 +f 16285/16285/11343 16308/16308/11363 16336/16336/11383 +f 16336/16336/11383 16308/16308/11363 16273/16273/11332 +f 16336/16336/11383 16273/16273/11332 16272/16272/11329 +f 16335/16335/11384 16334/16334/11383 16337/16337/11385 +f 16335/16335/11384 16337/16337/11385 16338/16338/11328 +f 16276/16276/11335 16339/16339/11386 16340/16340/11387 +f 16276/16276/11335 16340/16340/11387 16321/16321/11374 +f 16339/16339/11386 16341/16341/11388 16342/16342/11389 +f 16339/16339/11386 16342/16342/11389 16340/16340/11387 +f 16340/16340/11387 16342/16342/11389 16343/16343/11390 +f 16340/16340/11387 16343/16343/11390 16344/16344/11391 +f 16321/16321/11374 16340/16340/11387 16344/16344/11391 +f 16321/16321/11374 16344/16344/11391 16318/16318/11371 +f 16326/16326/11377 16345/16345/11392 16346/16346/11393 +f 16326/16326/11377 16346/16346/11393 16323/16323/11376 +f 16345/16345/11392 16347/16347/11394 16348/16348/11395 +f 16345/16345/11392 16348/16348/11395 16346/16346/11393 +f 16318/16318/11371 16344/16344/11391 16349/16349/11396 +f 16318/16318/11371 16349/16349/11396 16330/16330/11380 +f 16344/16344/11391 16343/16343/11390 16350/16350/11397 +f 16344/16344/11391 16350/16350/11397 16349/16349/11396 +f 16349/16349/11396 16350/16350/11397 16351/16351/11398 +f 16349/16349/11396 16351/16351/11398 16352/16352/11399 +f 16330/16330/11380 16349/16349/11396 16352/16352/11399 +f 16330/16330/11380 16352/16352/11399 16327/16327/11370 +f 16338/16338/11328 16353/16353/11400 16354/16354/11401 +f 16338/16338/11328 16354/16354/11401 16335/16335/11384 +f 16353/16353/11400 16355/16355/11402 16356/16356/11403 +f 16353/16353/11400 16356/16356/11403 16354/16354/11401 +f 16354/16354/11401 16356/16356/11403 16357/16357/11404 +f 16354/16354/11401 16357/16357/11404 16358/16358/11405 +f 16335/16335/11384 16354/16354/11401 16358/16358/11405 +f 16335/16335/11384 16358/16358/11405 16332/16332/11381 +f 16287/16287/11344 16359/16359/11406 16360/16360/11407 +f 16287/16287/11344 16360/16360/11407 16279/16279/11338 +f 16359/16359/11406 16361/16361/11408 16362/16362/11409 +f 16359/16359/11406 16362/16362/11409 16360/16360/11407 +f 16360/16360/11407 16362/16362/11409 16341/16341/11388 +f 16360/16360/11407 16341/16341/11388 16339/16339/11386 +f 16279/16279/11338 16360/16360/11407 16339/16339/11386 +f 16279/16279/11338 16339/16339/11386 16276/16276/11335 +f 16363/16363/11410 16364/16364/11411 16365/16365/11412 +f 16363/16363/11410 16365/16365/11412 16366/16366/11400 +f 16271/16271/11331 16363/16363/11410 16366/16366/11400 +f 16271/16271/11331 16366/16366/11400 16268/16268/11328 +f 16317/16317/11370 16367/16367/11413 16368/16368/11414 +f 16317/16317/11370 16368/16368/11414 16312/16312/11367 +f 16367/16367/11413 16369/16369/11415 16370/16370/11416 +f 16367/16367/11413 16370/16370/11416 16368/16368/11414 +f 16368/16368/11414 16370/16370/11416 16371/16371/11394 +f 16368/16368/11414 16371/16371/11394 16372/16372/11417 +f 16312/16312/11367 16368/16368/11414 16372/16372/11417 +f 16312/16312/11367 16372/16372/11417 16309/16309/11364 +f 16347/16347/11394 16373/16373/11418 16374/16374/11419 +f 16347/16347/11394 16374/16374/11419 16348/16348/11395 +f 16373/16373/11418 16375/16375/11420 16376/16376/11421 +f 16373/16373/11418 16376/16376/11421 16374/16374/11419 +f 16343/16343/11390 16377/16377/11422 16378/16378/11423 +f 16343/16343/11390 16378/16378/11423 16350/16350/11397 +f 16377/16377/11422 16379/16379/11424 16380/16380/11425 +f 16377/16377/11422 16380/16380/11425 16378/16378/11423 +f 16378/16378/11423 16380/16380/11425 16381/16381/11426 +f 16378/16378/11423 16381/16381/11426 16382/16382/11427 +f 16350/16350/11397 16378/16378/11423 16382/16382/11427 +f 16350/16350/11397 16382/16382/11427 16351/16351/11398 +f 16355/16355/11402 16383/16383/11428 16384/16384/11429 +f 16355/16355/11402 16384/16384/11429 16356/16356/11403 +f 16383/16383/11428 16385/16385/11430 16386/16386/11431 +f 16383/16383/11428 16386/16386/11431 16384/16384/11429 +f 16384/16384/11429 16386/16386/11431 16387/16387/11432 +f 16384/16384/11429 16387/16387/11432 16388/16388/11433 +f 16356/16356/11403 16384/16384/11429 16388/16388/11433 +f 16356/16356/11403 16388/16388/11433 16357/16357/11404 +f 16361/16361/11408 16389/16389/11434 16390/16390/11435 +f 16361/16361/11408 16390/16390/11435 16362/16362/11409 +f 16389/16389/11434 16391/16391/11432 16392/16392/11436 +f 16389/16389/11434 16392/16392/11436 16390/16390/11435 +f 16390/16390/11435 16392/16392/11436 16393/16393/11437 +f 16390/16390/11435 16393/16393/11437 16394/16394/11438 +f 16362/16362/11409 16390/16390/11435 16394/16394/11438 +f 16362/16362/11409 16394/16394/11438 16341/16341/11388 +f 16395/16395/11439 16396/16396/11440 16397/16397/11430 +f 16395/16395/11439 16397/16397/11430 16398/16398/11441 +f 16364/16364/11411 16395/16395/11439 16398/16398/11441 +f 16364/16364/11411 16398/16398/11441 16365/16365/11412 +f 16369/16369/11415 16399/16399/11442 16400/16400/11443 +f 16369/16369/11415 16400/16400/11443 16370/16370/11416 +f 16399/16399/11442 16401/16401/11444 16402/16402/11445 +f 16399/16399/11442 16402/16402/11445 16400/16400/11443 +f 16400/16400/11443 16402/16402/11445 16403/16403/11420 +f 16400/16400/11443 16403/16403/11420 16404/16404/11418 +f 16370/16370/11416 16400/16400/11443 16404/16404/11418 +f 16370/16370/11416 16404/16404/11418 16371/16371/11394 +f 16341/16341/11388 16394/16394/11438 16405/16405/11446 +f 16341/16341/11388 16405/16405/11446 16342/16342/11389 +f 16394/16394/11438 16393/16393/11437 16406/16406/11447 +f 16394/16394/11438 16406/16406/11447 16405/16405/11446 +f 16405/16405/11446 16406/16406/11447 16379/16379/11424 +f 16405/16405/11446 16379/16379/11424 16377/16377/11422 +f 16342/16342/11389 16405/16405/11446 16377/16377/11422 +f 16342/16342/11389 16377/16377/11422 16343/16343/11390 +f 16401/16401/11444 16407/16407/11448 16408/16408/11449 +f 16401/16401/11444 16408/16408/11449 16402/16402/11445 +f 16407/16407/11448 16409/16409/11450 16410/16410/11451 +f 16407/16407/11448 16410/16410/11451 16408/16408/11449 +f 16408/16408/11449 16410/16410/11451 16411/16411/11452 +f 16408/16408/11449 16411/16411/11452 16412/16412/11453 +f 16402/16402/11445 16408/16408/11449 16412/16412/11453 +f 16402/16402/11445 16412/16412/11453 16403/16403/11420 +f 16393/16393/11437 16413/16413/11454 16414/16414/11455 +f 16393/16393/11437 16414/16414/11455 16406/16406/11447 +f 16413/16413/11454 16415/16415/11456 16416/16416/11457 +f 16413/16413/11454 16416/16416/11457 16414/16414/11455 +f 16414/16414/11455 16416/16416/11457 16417/16417/11458 +f 16414/16414/11455 16417/16417/11458 16418/16418/11459 +f 16406/16406/11447 16414/16414/11455 16418/16418/11459 +f 16406/16406/11447 16418/16418/11459 16379/16379/11424 +f 16375/16375/11420 16419/16419/11453 16420/16420/11460 +f 16375/16375/11420 16420/16420/11460 16376/16376/11421 +f 16412/16412/11453 16411/16411/11452 16421/16421/11461 +f 16412/16412/11453 16421/16421/11461 16422/16422/11460 +f 16423/16423/11462 16424/16424/11463 16425/16425/11464 +f 16423/16423/11462 16425/16425/11464 16426/16426/11465 +f 16379/16379/11424 16418/16418/11459 16427/16427/11466 +f 16379/16379/11424 16427/16427/11466 16380/16380/11425 +f 16418/16418/11459 16417/16417/11458 16428/16428/11467 +f 16418/16418/11459 16428/16428/11467 16427/16427/11466 +f 16427/16427/11466 16428/16428/11467 16429/16429/11468 +f 16427/16427/11466 16429/16429/11468 16430/16430/11469 +f 16380/16380/11425 16427/16427/11466 16430/16430/11469 +f 16380/16380/11425 16430/16430/11469 16381/16381/11426 +f 16385/16385/11430 16431/16431/11470 16432/16432/11471 +f 16385/16385/11430 16432/16432/11471 16386/16386/11431 +f 16431/16431/11470 16433/16433/11472 16434/16434/11473 +f 16431/16431/11470 16434/16434/11473 16432/16432/11471 +f 16432/16432/11471 16434/16434/11473 16435/16435/11474 +f 16432/16432/11471 16435/16435/11474 16436/16436/11475 +f 16386/16386/11431 16432/16432/11471 16436/16436/11475 +f 16386/16386/11431 16436/16436/11475 16387/16387/11432 +f 16426/16426/11465 16425/16425/11464 16437/16437/11476 +f 16426/16426/11465 16437/16437/11476 16438/16438/11477 +f 16438/16438/11477 16437/16437/11476 16439/16439/11478 +f 16438/16438/11477 16439/16439/11478 16440/16440/11479 +f 16391/16391/11432 16441/16441/11480 16442/16442/11481 +f 16391/16391/11432 16442/16442/11481 16392/16392/11436 +f 16441/16441/11480 16443/16443/11482 16444/16444/11483 +f 16441/16441/11480 16444/16444/11483 16442/16442/11481 +f 16442/16442/11481 16444/16444/11483 16415/16415/11456 +f 16442/16442/11481 16415/16415/11456 16413/16413/11454 +f 16392/16392/11436 16442/16442/11481 16413/16413/11454 +f 16392/16392/11436 16413/16413/11454 16393/16393/11437 +f 16440/16440/11479 16439/16439/11478 16445/16445/11484 +f 16440/16440/11479 16445/16445/11484 16446/16446/11485 +f 16446/16446/11485 16445/16445/11484 16447/16447/11486 +f 16446/16446/11485 16447/16447/11486 16448/16448/11470 +f 16396/16396/11440 16446/16446/11485 16448/16448/11470 +f 16396/16396/11440 16448/16448/11470 16397/16397/11430 +f 16435/16435/11474 16449/16449/11487 16450/16450/11488 +f 16435/16435/11474 16450/16450/11488 16451/16451/11489 +f 16452/16452/11487 16453/16453/11490 16454/16454/11491 +f 16452/16452/11487 16454/16454/11491 16455/16455/11492 +f 16455/16455/11492 16454/16454/11491 16456/16456/11493 +f 16455/16455/11492 16456/16456/11493 16457/16457/11494 +f 16444/16444/11483 16458/16458/11495 16459/16459/11494 +f 16444/16444/11483 16459/16459/11494 16415/16415/11456 +f 16439/16439/11478 16460/16460/11496 16461/16461/11497 +f 16439/16439/11478 16461/16461/11497 16445/16445/11484 +f 16462/16462/11496 16463/16463/11498 16464/16464/11499 +f 16462/16462/11496 16464/16464/11499 16465/16465/11497 +f 16461/16461/11497 16466/16466/11499 16467/16467/11500 +f 16461/16461/11497 16467/16467/11500 16468/16468/11501 +f 16445/16445/11484 16461/16461/11497 16468/16468/11501 +f 16445/16445/11484 16468/16468/11501 16447/16447/11486 +f 16409/16409/11450 16469/16469/11502 16470/16470/11503 +f 16409/16409/11450 16470/16470/11503 16410/16410/11451 +f 16469/16469/11502 16471/16471/11504 16472/16472/11505 +f 16469/16469/11502 16472/16472/11505 16470/16470/11503 +f 16470/16470/11503 16472/16472/11505 16473/16473/11506 +f 16470/16470/11503 16473/16473/11506 16474/16474/11507 +f 16410/16410/11451 16470/16470/11503 16474/16474/11507 +f 16410/16410/11451 16474/16474/11507 16411/16411/11452 +f 16415/16415/11456 16459/16459/11494 16475/16475/11508 +f 16415/16415/11456 16475/16475/11508 16416/16416/11457 +f 16457/16457/11494 16456/16456/11493 16476/16476/11509 +f 16457/16457/11494 16476/16476/11509 16477/16477/11508 +f 16477/16477/11508 16476/16476/11509 16478/16478/11510 +f 16477/16477/11508 16478/16478/11510 16479/16479/11511 +f 16416/16416/11457 16475/16475/11508 16480/16480/11511 +f 16416/16416/11457 16480/16480/11511 16417/16417/11458 +f 16411/16411/11452 16474/16474/11507 16481/16481/11512 +f 16411/16411/11452 16481/16481/11512 16421/16421/11461 +f 16474/16474/11507 16473/16473/11506 16482/16482/11513 +f 16474/16474/11507 16482/16482/11513 16481/16481/11512 +f 16483/16483/11512 16484/16484/11513 16485/16485/11514 +f 16483/16483/11512 16485/16485/11514 16486/16486/11515 +f 16424/16424/11463 16483/16483/11512 16486/16486/11515 +f 16424/16424/11463 16486/16486/11515 16425/16425/11464 +f 16417/16417/11458 16480/16480/11511 16487/16487/11516 +f 16417/16417/11458 16487/16487/11516 16428/16428/11467 +f 16479/16479/11511 16478/16478/11510 16488/16488/11517 +f 16479/16479/11511 16488/16488/11517 16489/16489/11516 +f 16489/16489/11516 16488/16488/11517 16490/16490/11504 +f 16489/16489/11516 16490/16490/11504 16491/16491/11518 +f 16428/16428/11467 16487/16487/11516 16492/16492/11519 +f 16428/16428/11467 16492/16492/11519 16429/16429/11468 +f 16433/16433/11472 16493/16493/11520 16494/16494/11521 +f 16433/16433/11472 16494/16494/11521 16434/16434/11473 +f 16493/16493/11520 16495/16495/11500 16496/16496/11522 +f 16493/16493/11520 16496/16496/11522 16494/16494/11521 +f 16494/16494/11521 16496/16496/11522 16497/16497/11523 +f 16494/16494/11521 16497/16497/11523 16449/16449/11487 +f 16434/16434/11473 16494/16494/11521 16449/16449/11487 +f 16434/16434/11473 16449/16449/11487 16435/16435/11474 +f 16425/16425/11464 16486/16486/11515 16498/16498/11524 +f 16425/16425/11464 16498/16498/11524 16437/16437/11476 +f 16486/16486/11515 16485/16485/11514 16499/16499/11525 +f 16486/16486/11515 16499/16499/11525 16498/16498/11524 +f 16498/16498/11524 16499/16499/11525 16500/16500/11498 +f 16498/16498/11524 16500/16500/11498 16460/16460/11496 +f 16437/16437/11476 16498/16498/11524 16460/16460/11496 +f 16437/16437/11476 16460/16460/11496 16439/16439/11478 +f 16501/16501/11526 16502/16502/11527 16503/16503/11528 +f 16501/16501/11526 16503/16503/11528 16504/16504/11529 +f 16505/16505/11530 16506/16506/11531 16507/16507/11532 +f 16505/16505/11530 16507/16507/11532 16508/16508/11533 +f 16508/16508/11533 16507/16507/11532 16509/16509/11534 +f 16508/16508/11533 16509/16509/11534 16510/16510/11535 +f 16504/16504/11529 16503/16503/11528 16511/16511/11535 +f 16504/16504/11529 16511/16511/11535 16512/16512/11536 +f 16473/16473/11506 16472/16472/11505 16513/16513/11537 +f 16473/16473/11506 16513/16513/11537 16514/16514/11538 +f 16472/16472/11505 16471/16471/11504 16515/16515/11539 +f 16472/16472/11505 16515/16515/11539 16513/16513/11537 +f 16513/16513/11537 16515/16515/11539 16516/16516/11540 +f 16513/16513/11537 16516/16516/11540 16517/16517/11541 +f 16514/16514/11538 16513/16513/11537 16517/16517/11541 +f 16514/16514/11538 16517/16517/11541 16518/16518/11542 +f 16519/16519/11490 16520/16520/11522 16521/16521/11543 +f 16519/16519/11490 16521/16521/11543 16522/16522/11544 +f 16520/16520/11522 16467/16467/11500 16523/16523/11545 +f 16520/16520/11522 16523/16523/11545 16521/16521/11543 +f 16521/16521/11543 16523/16523/11545 16524/16524/11546 +f 16521/16521/11543 16524/16524/11546 16525/16525/11547 +f 16522/16522/11544 16521/16521/11543 16525/16525/11547 +f 16522/16522/11544 16525/16525/11547 16526/16526/11548 +f 16527/16527/11549 16528/16528/11550 16529/16529/11551 +f 16527/16527/11549 16529/16529/11551 16530/16530/11552 +f 16528/16528/11550 16531/16531/11553 16532/16532/11554 +f 16528/16528/11550 16532/16532/11554 16529/16529/11551 +f 16529/16529/11551 16532/16532/11554 16533/16533/11555 +f 16529/16529/11551 16533/16533/11555 16534/16534/11556 +f 16530/16530/11552 16529/16529/11551 16534/16534/11556 +f 16530/16530/11552 16534/16534/11556 16535/16535/11557 +f 16536/16536/11558 16537/16537/11559 16538/16538/11560 +f 16536/16536/11558 16538/16538/11560 16539/16539/11561 +f 16537/16537/11559 16501/16501/11526 16504/16504/11529 +f 16537/16537/11559 16504/16504/11529 16538/16538/11560 +f 16538/16538/11560 16504/16504/11529 16512/16512/11536 +f 16538/16538/11560 16512/16512/11536 16540/16540/11562 +f 16539/16539/11561 16538/16538/11560 16540/16540/11562 +f 16539/16539/11561 16540/16540/11562 16541/16541/11563 +f 16478/16478/11510 16476/16476/11509 16542/16542/11564 +f 16478/16478/11510 16542/16542/11564 16543/16543/11565 +f 16476/16476/11509 16456/16456/11493 16544/16544/11566 +f 16476/16476/11509 16544/16544/11566 16542/16542/11564 +f 16542/16542/11564 16544/16544/11566 16545/16545/11567 +f 16542/16542/11564 16545/16545/11567 16546/16546/11568 +f 16543/16543/11565 16542/16542/11564 16546/16546/11568 +f 16543/16543/11565 16546/16546/11568 16547/16547/11569 +f 16548/16548/11570 16549/16549/11571 16550/16550/11572 +f 16548/16548/11570 16550/16550/11572 16551/16551/11573 +f 16552/16552/11574 16527/16527/11549 16530/16530/11552 +f 16552/16552/11574 16530/16530/11552 16553/16553/11575 +f 16553/16553/11575 16530/16530/11552 16535/16535/11557 +f 16553/16553/11575 16535/16535/11557 16554/16554/11576 +f 16551/16551/11573 16550/16550/11572 16555/16555/11576 +f 16551/16551/11573 16555/16555/11576 16556/16556/11577 +f 16557/16557/11578 16558/16558/11579 16559/16559/11580 +f 16557/16557/11578 16559/16559/11580 16560/16560/11581 +f 16558/16558/11579 16561/16561/11582 16562/16562/11561 +f 16558/16558/11579 16562/16562/11561 16559/16559/11580 +f 16563/16563/11583 16539/16539/11561 16541/16541/11563 +f 16563/16563/11583 16541/16541/11563 16564/16564/11584 +f 16560/16560/11581 16559/16559/11580 16565/16565/11585 +f 16560/16560/11581 16565/16565/11585 16566/16566/11586 +f 16567/16567/11587 16568/16568/11588 16569/16569/11589 +f 16567/16567/11587 16569/16569/11589 16570/16570/11590 +f 16571/16571/11591 16572/16572/11592 16573/16573/11593 +f 16571/16571/11591 16573/16573/11593 16574/16574/11589 +f 16569/16569/11589 16575/16575/11593 16576/16576/11594 +f 16569/16569/11589 16576/16576/11594 16577/16577/11595 +f 16570/16570/11590 16569/16569/11589 16577/16577/11595 +f 16570/16570/11590 16577/16577/11595 16557/16557/11578 +f 16527/16527/11549 16578/16578/11596 16579/16579/11597 +f 16527/16527/11549 16579/16579/11597 16528/16528/11550 +f 16578/16578/11596 16580/16580/11598 16581/16581/11599 +f 16578/16578/11596 16581/16581/11599 16579/16579/11597 +f 16579/16579/11597 16581/16581/11599 16582/16582/11600 +f 16579/16579/11597 16582/16582/11600 16583/16583/11601 +f 16528/16528/11550 16579/16579/11597 16583/16583/11601 +f 16528/16528/11550 16583/16583/11601 16531/16531/11553 +f 16536/16536/11558 16584/16584/11602 16585/16585/11603 +f 16536/16536/11558 16585/16585/11603 16537/16537/11559 +f 16584/16584/11602 16586/16586/11604 16587/16587/11605 +f 16584/16584/11602 16587/16587/11605 16585/16585/11603 +f 16585/16585/11603 16587/16587/11605 16588/16588/11606 +f 16585/16585/11603 16588/16588/11606 16589/16589/11607 +f 16537/16537/11559 16585/16585/11603 16589/16589/11607 +f 16537/16537/11559 16589/16589/11607 16501/16501/11526 +f 16501/16501/11526 16589/16589/11607 16590/16590/11608 +f 16501/16501/11526 16590/16590/11608 16502/16502/11527 +f 16591/16591/11609 16592/16592/11606 16593/16593/11610 +f 16591/16591/11609 16593/16593/11610 16594/16594/11611 +f 16594/16594/11611 16593/16593/11610 16595/16595/11612 +f 16594/16594/11611 16595/16595/11612 16596/16596/11613 +f 16505/16505/11530 16594/16594/11611 16596/16596/11613 +f 16505/16505/11530 16596/16596/11613 16506/16506/11531 +f 16531/16531/11553 16583/16583/11601 16597/16597/11614 +f 16531/16531/11553 16597/16597/11614 16598/16598/11615 +f 16583/16583/11601 16582/16582/11600 16599/16599/11616 +f 16583/16583/11601 16599/16599/11616 16597/16597/11614 +f 16597/16597/11614 16599/16599/11616 16600/16600/11592 +f 16597/16597/11614 16600/16600/11592 16568/16568/11588 +f 16598/16598/11615 16597/16597/11614 16568/16568/11588 +f 16598/16598/11615 16568/16568/11588 16567/16567/11587 +f 16548/16548/11570 16601/16601/11617 16602/16602/11618 +f 16548/16548/11570 16602/16602/11618 16549/16549/11571 +f 16601/16601/11617 16603/16603/11619 16604/16604/11620 +f 16601/16601/11617 16604/16604/11620 16602/16602/11618 +f 16605/16605/11621 16606/16606/11622 16580/16580/11598 +f 16605/16605/11621 16580/16580/11598 16578/16578/11596 +f 16552/16552/11574 16605/16605/11621 16578/16578/11596 +f 16552/16552/11574 16578/16578/11596 16527/16527/11549 +f 16607/16607/11578 16608/16608/11623 16609/16609/11624 +f 16607/16607/11578 16609/16609/11624 16610/16610/11625 +f 16608/16608/11623 16611/16611/11626 16612/16612/11627 +f 16608/16608/11623 16612/16612/11627 16609/16609/11624 +f 16609/16609/11624 16612/16612/11627 16586/16586/11604 +f 16609/16609/11624 16586/16586/11604 16584/16584/11602 +f 16610/16610/11625 16609/16609/11624 16584/16584/11602 +f 16610/16610/11625 16584/16584/11602 16536/16536/11558 +f 16613/16613/11628 16614/16614/11629 16615/16615/11630 +f 16613/16613/11628 16615/16615/11630 16616/16616/11631 +f 16614/16614/11629 16617/16617/11632 16618/16618/11633 +f 16614/16614/11629 16618/16618/11633 16615/16615/11630 +f 16615/16615/11630 16618/16618/11633 16603/16603/11619 +f 16615/16615/11630 16603/16603/11619 16601/16601/11617 +f 16616/16616/11631 16615/16615/11630 16601/16601/11617 +f 16616/16616/11631 16601/16601/11617 16548/16548/11570 +f 16592/16592/11606 16619/16619/11634 16620/16620/11635 +f 16592/16592/11606 16620/16620/11635 16593/16593/11610 +f 16621/16621/11604 16622/16622/11636 16620/16620/11635 +f 16621/16621/11604 16620/16620/11635 16619/16619/11634 +f 16576/16576/11594 16575/16575/11593 16620/16620/11635 +f 16576/16576/11594 16620/16620/11635 16622/16622/11636 +f 16572/16572/11592 16623/16623/11616 16624/16624/11637 +f 16572/16572/11592 16624/16624/11637 16573/16573/11593 +f 16625/16625/11600 16626/16626/11638 16624/16624/11637 +f 16625/16625/11600 16624/16624/11637 16623/16623/11616 +f 16627/16627/11639 16604/16604/11620 16624/16624/11637 +f 16627/16627/11639 16624/16624/11637 16626/16626/11638 +f 16603/16603/11619 16618/16618/11633 16624/16624/11637 +f 16603/16603/11619 16624/16624/11637 16604/16604/11620 +f 16617/16617/11632 16628/16628/11640 16624/16624/11637 +f 16617/16617/11632 16624/16624/11637 16618/16618/11633 +f 16629/16629/11641 16630/16630/11642 16631/16631/11643 +f 16629/16629/11641 16631/16631/11643 16632/16632/11644 +f 16633/16633/11645 16541/16541/11563 16540/16540/11562 +f 16633/16633/11645 16540/16540/11562 16634/16634/11643 +f 16634/16634/11643 16540/16540/11562 16512/16512/11536 +f 16634/16634/11643 16512/16512/11536 16635/16635/11646 +f 16632/16632/11644 16631/16631/11643 16636/16636/11647 +f 16632/16632/11644 16636/16636/11647 16637/16637/11648 +f 16638/16638/11649 16639/16639/11650 16640/16640/11651 +f 16638/16638/11649 16640/16640/11651 16641/16641/11652 +f 16642/16642/11650 16643/16643/11653 16644/16644/11654 +f 16642/16642/11650 16644/16644/11654 16645/16645/11655 +f 16640/16640/11651 16646/16646/11654 16647/16647/11656 +f 16640/16640/11651 16647/16647/11656 16648/16648/11657 +f 16641/16641/11652 16640/16640/11651 16648/16648/11657 +f 16641/16641/11652 16648/16648/11657 16649/16649/11658 +f 16545/16545/11567 16650/16650/11659 16651/16651/11660 +f 16545/16545/11567 16651/16651/11660 16546/16546/11568 +f 16650/16650/11659 16652/16652/11557 16653/16653/11556 +f 16650/16650/11659 16653/16653/11556 16651/16651/11660 +f 16651/16651/11660 16653/16653/11556 16654/16654/11555 +f 16651/16651/11660 16654/16654/11555 16655/16655/11661 +f 16546/16546/11568 16651/16651/11660 16655/16655/11661 +f 16546/16546/11568 16655/16655/11661 16547/16547/11569 +f 16656/16656/11662 16657/16657/11663 16658/16658/11664 +f 16656/16656/11662 16658/16658/11664 16659/16659/11665 +f 16657/16657/11663 16660/16660/11666 16661/16661/11667 +f 16657/16657/11663 16661/16661/11667 16658/16658/11664 +f 16658/16658/11664 16661/16661/11667 16662/16662/11668 +f 16658/16658/11664 16662/16662/11668 16663/16663/11669 +f 16659/16659/11665 16658/16658/11664 16663/16663/11669 +f 16659/16659/11665 16663/16663/11669 16664/16664/11670 +f 16665/16665/11671 16666/16666/11672 16667/16667/11673 +f 16665/16665/11671 16667/16667/11673 16668/16668/11667 +f 16666/16666/11672 16669/16669/11674 16670/16670/11675 +f 16666/16666/11672 16670/16670/11675 16667/16667/11673 +f 16667/16667/11673 16670/16670/11675 16671/16671/11676 +f 16667/16667/11673 16671/16671/11676 16672/16672/11677 +f 16668/16668/11667 16667/16667/11673 16672/16672/11677 +f 16668/16668/11667 16672/16672/11677 16673/16673/11678 +f 16674/16674/11679 16675/16675/11680 16676/16676/11681 +f 16674/16674/11679 16676/16676/11681 16677/16677/11682 +f 16678/16678/11680 16679/16679/11683 16680/16680/11684 +f 16678/16678/11680 16680/16680/11684 16681/16681/11681 +f 16681/16681/11681 16680/16680/11684 16682/16682/11685 +f 16681/16681/11681 16682/16682/11685 16683/16683/11686 +f 16677/16677/11682 16676/16676/11681 16684/16684/11687 +f 16677/16677/11682 16684/16684/11687 16685/16685/11688 +f 16686/16686/11689 16687/16687/11690 16688/16688/11691 +f 16686/16686/11689 16688/16688/11691 16689/16689/11692 +f 16687/16687/11690 16690/16690/11693 16691/16691/11694 +f 16687/16687/11690 16691/16691/11694 16688/16688/11691 +f 16692/16692/11695 16693/16693/11694 16694/16694/11696 +f 16692/16692/11695 16694/16694/11696 16695/16695/11697 +f 16670/16670/11675 16692/16692/11695 16695/16695/11697 +f 16670/16670/11675 16695/16695/11697 16671/16671/11676 +f 16679/16679/11683 16696/16696/11698 16697/16697/11699 +f 16679/16679/11683 16697/16697/11699 16680/16680/11684 +f 16696/16696/11698 16638/16638/11649 16641/16641/11652 +f 16696/16696/11698 16641/16641/11652 16697/16697/11699 +f 16697/16697/11699 16641/16641/11652 16649/16649/11658 +f 16697/16697/11699 16649/16649/11658 16698/16698/11700 +f 16680/16680/11684 16697/16697/11699 16698/16698/11700 +f 16680/16680/11684 16698/16698/11700 16682/16682/11685 +f 16567/16567/11587 16570/16570/11590 16699/16699/11701 +f 16567/16567/11587 16699/16699/11701 16700/16700/11702 +f 16570/16570/11590 16557/16557/11578 16560/16560/11581 +f 16570/16570/11590 16560/16560/11581 16699/16699/11701 +f 16699/16699/11701 16560/16560/11581 16566/16566/11586 +f 16699/16699/11701 16566/16566/11586 16701/16701/11703 +f 16700/16700/11702 16699/16699/11701 16701/16701/11703 +f 16700/16700/11702 16701/16701/11703 16702/16702/11704 +f 16490/16490/11504 16488/16488/11517 16703/16703/11705 +f 16490/16490/11504 16703/16703/11705 16704/16704/11539 +f 16488/16488/11517 16478/16478/11510 16543/16543/11565 +f 16488/16488/11517 16543/16543/11565 16703/16703/11705 +f 16703/16703/11705 16543/16543/11565 16547/16547/11569 +f 16703/16703/11705 16547/16547/11569 16705/16705/11706 +f 16704/16704/11539 16703/16703/11705 16705/16705/11706 +f 16704/16704/11539 16705/16705/11706 16706/16706/11707 +f 16613/16613/11628 16616/16616/11631 16707/16707/11708 +f 16613/16613/11628 16707/16707/11708 16708/16708/11709 +f 16616/16616/11631 16548/16548/11570 16551/16551/11573 +f 16616/16616/11631 16551/16551/11573 16707/16707/11708 +f 16707/16707/11708 16551/16551/11573 16556/16556/11577 +f 16707/16707/11708 16556/16556/11577 16709/16709/11710 +f 16708/16708/11709 16707/16707/11708 16709/16709/11710 +f 16708/16708/11709 16709/16709/11710 16710/16710/11534 +f 16531/16531/11553 16598/16598/11615 16711/16711/11711 +f 16531/16531/11553 16711/16711/11711 16532/16532/11554 +f 16598/16598/11615 16567/16567/11587 16700/16700/11702 +f 16598/16598/11615 16700/16700/11702 16711/16711/11711 +f 16711/16711/11711 16700/16700/11702 16702/16702/11704 +f 16711/16711/11711 16702/16702/11704 16712/16712/11712 +f 16532/16532/11554 16711/16711/11711 16712/16712/11712 +f 16532/16532/11554 16712/16712/11712 16533/16533/11555 +f 16467/16467/11500 16466/16466/11499 16713/16713/11713 +f 16467/16467/11500 16713/16713/11713 16523/16523/11545 +f 16464/16464/11499 16463/16463/11498 16714/16714/11714 +f 16464/16464/11499 16714/16714/11714 16715/16715/11713 +f 16713/16713/11713 16716/16716/11714 16637/16637/11648 +f 16713/16713/11713 16637/16637/11648 16717/16717/11715 +f 16523/16523/11545 16713/16713/11713 16717/16717/11715 +f 16523/16523/11545 16717/16717/11715 16524/16524/11546 +f 16485/16485/11514 16484/16484/11513 16718/16718/11716 +f 16485/16485/11514 16718/16718/11716 16719/16719/11717 +f 16482/16482/11513 16473/16473/11506 16514/16514/11538 +f 16482/16482/11513 16514/16514/11538 16720/16720/11718 +f 16718/16718/11716 16721/16721/11719 16722/16722/11542 +f 16718/16718/11716 16722/16722/11542 16723/16723/11720 +f 16719/16719/11717 16718/16718/11716 16723/16723/11720 +f 16719/16719/11717 16723/16723/11720 16629/16629/11641 +f 16456/16456/11493 16454/16454/11491 16724/16724/11721 +f 16456/16456/11493 16724/16724/11721 16544/16544/11566 +f 16454/16454/11491 16453/16453/11490 16725/16725/11722 +f 16454/16454/11491 16725/16725/11722 16724/16724/11721 +f 16724/16724/11721 16725/16725/11722 16726/16726/11723 +f 16724/16724/11721 16726/16726/11723 16727/16727/11724 +f 16544/16544/11566 16724/16724/11721 16727/16727/11724 +f 16544/16544/11566 16727/16727/11724 16545/16545/11567 +f 16500/16500/11498 16499/16499/11525 16728/16728/11725 +f 16500/16500/11498 16728/16728/11725 16716/16716/11714 +f 16499/16499/11525 16485/16485/11514 16719/16719/11717 +f 16499/16499/11525 16719/16719/11717 16728/16728/11725 +f 16728/16728/11725 16719/16719/11717 16629/16629/11641 +f 16728/16728/11725 16629/16629/11641 16632/16632/11644 +f 16716/16716/11714 16728/16728/11725 16632/16632/11644 +f 16716/16716/11714 16632/16632/11644 16637/16637/11648 +f 16729/16729/11653 16730/16730/11650 16731/16731/11726 +f 16729/16729/11653 16731/16731/11726 16732/16732/11727 +f 16730/16730/11650 16733/16733/11728 16734/16734/11729 +f 16730/16730/11650 16734/16734/11729 16731/16731/11726 +f 16735/16735/11730 16736/16736/11731 16526/16526/11548 +f 16735/16735/11730 16526/16526/11548 16525/16525/11547 +f 16737/16737/11732 16735/16735/11730 16525/16525/11547 +f 16737/16737/11732 16525/16525/11547 16524/16524/11546 +f 16738/16738/11733 16739/16739/11734 16740/16740/11735 +f 16738/16738/11733 16740/16740/11735 16741/16741/11736 +f 16739/16739/11734 16742/16742/11737 16743/16743/11738 +f 16739/16739/11734 16743/16743/11738 16740/16740/11735 +f 16740/16740/11735 16743/16743/11738 16518/16518/11542 +f 16740/16740/11735 16518/16518/11542 16517/16517/11541 +f 16741/16741/11736 16740/16740/11735 16517/16517/11541 +f 16741/16741/11736 16517/16517/11541 16516/16516/11540 +f 16744/16744/11739 16745/16745/11740 16746/16746/11741 +f 16744/16744/11739 16746/16746/11741 16747/16747/11742 +f 16745/16745/11740 16738/16738/11733 16741/16741/11736 +f 16745/16745/11740 16741/16741/11736 16746/16746/11741 +f 16748/16748/11743 16749/16749/11744 16706/16706/11707 +f 16748/16748/11743 16706/16706/11707 16705/16705/11706 +f 16750/16750/11742 16748/16748/11743 16705/16705/11706 +f 16750/16750/11742 16705/16705/11706 16547/16547/11569 +f 16751/16751/11745 16752/16752/11746 16753/16753/11747 +f 16751/16751/11745 16753/16753/11747 16754/16754/11748 +f 16752/16752/11746 16729/16729/11653 16732/16732/11727 +f 16752/16752/11746 16732/16732/11727 16753/16753/11747 +f 16755/16755/11749 16737/16737/11732 16524/16524/11546 +f 16755/16755/11749 16524/16524/11546 16717/16717/11715 +f 16756/16756/11748 16755/16755/11749 16717/16717/11715 +f 16756/16756/11748 16717/16717/11715 16637/16637/11648 +f 16742/16742/11737 16757/16757/11750 16758/16758/11751 +f 16742/16742/11737 16758/16758/11751 16743/16743/11738 +f 16757/16757/11750 16759/16759/11752 16760/16760/11753 +f 16757/16757/11750 16760/16760/11753 16758/16758/11751 +f 16761/16761/11751 16762/16762/11754 16629/16629/11641 +f 16761/16761/11751 16629/16629/11641 16723/16723/11720 +f 16743/16743/11738 16758/16758/11751 16763/16763/11720 +f 16743/16743/11738 16763/16763/11720 16518/16518/11542 +f 16733/16733/11728 16764/16764/11755 16765/16765/11756 +f 16733/16733/11728 16765/16765/11756 16734/16734/11729 +f 16764/16764/11755 16766/16766/11757 16767/16767/11758 +f 16764/16764/11755 16767/16767/11758 16765/16765/11756 +f 16768/16768/11759 16769/16769/11760 16545/16545/11567 +f 16768/16768/11759 16545/16545/11567 16727/16727/11724 +f 16770/16770/11761 16768/16768/11759 16727/16727/11724 +f 16770/16770/11761 16727/16727/11724 16726/16726/11723 +f 16771/16771/11762 16772/16772/11680 16773/16773/11763 +f 16771/16771/11762 16773/16773/11763 16769/16769/11760 +f 16772/16772/11680 16774/16774/11764 16775/16775/11765 +f 16772/16772/11680 16775/16775/11765 16773/16773/11763 +f 16773/16773/11763 16775/16775/11765 16652/16652/11557 +f 16773/16773/11763 16652/16652/11557 16650/16650/11659 +f 16769/16769/11760 16773/16773/11763 16650/16650/11659 +f 16769/16769/11760 16650/16650/11659 16545/16545/11567 +f 16776/16776/11666 16777/16777/11663 16778/16778/11766 +f 16776/16776/11666 16778/16778/11766 16779/16779/11767 +f 16780/16780/11768 16781/16781/11769 16750/16750/11742 +f 16780/16780/11768 16750/16750/11742 16782/16782/11770 +f 16782/16782/11770 16750/16750/11742 16547/16547/11569 +f 16782/16782/11770 16547/16547/11569 16655/16655/11661 +f 16783/16783/11767 16782/16782/11770 16655/16655/11661 +f 16783/16783/11767 16655/16655/11661 16654/16654/11555 +f 16784/16784/11771 16785/16785/11772 16786/16786/11773 +f 16784/16784/11771 16786/16786/11773 16787/16787/11774 +f 16785/16785/11772 16788/16788/11775 16789/16789/11776 +f 16785/16785/11772 16789/16789/11776 16786/16786/11773 +f 16790/16790/11777 16791/16791/11778 16512/16512/11536 +f 16790/16790/11777 16512/16512/11536 16511/16511/11535 +f 16787/16787/11774 16786/16786/11773 16792/16792/11535 +f 16787/16787/11774 16792/16792/11535 16793/16793/11779 +f 16794/16794/11780 16795/16795/11781 16796/16796/11782 +f 16794/16794/11780 16796/16796/11782 16797/16797/11783 +f 16795/16795/11781 16784/16784/11771 16787/16787/11774 +f 16795/16795/11781 16787/16787/11774 16796/16796/11782 +f 16796/16796/11782 16787/16787/11774 16793/16793/11779 +f 16796/16796/11782 16793/16793/11779 16798/16798/11784 +f 16799/16799/11783 16800/16800/11785 16709/16709/11710 +f 16799/16799/11783 16709/16709/11710 16556/16556/11577 +f 16801/16801/11786 16802/16802/11787 16803/16803/11788 +f 16801/16801/11786 16803/16803/11788 16804/16804/11789 +f 16802/16802/11787 16805/16805/11790 16806/16806/11791 +f 16802/16802/11787 16806/16806/11791 16803/16803/11788 +f 16803/16803/11788 16806/16806/11791 16541/16541/11563 +f 16803/16803/11788 16541/16541/11563 16633/16633/11645 +f 16762/16762/11754 16807/16807/11792 16630/16630/11642 +f 16762/16762/11754 16630/16630/11642 16629/16629/11641 +f 16808/16808/11793 16809/16809/11794 16810/16810/11795 +f 16808/16808/11793 16810/16810/11795 16791/16791/11778 +f 16811/16811/11796 16812/16812/11797 16756/16756/11748 +f 16811/16811/11796 16756/16756/11748 16813/16813/11798 +f 16813/16813/11798 16756/16756/11748 16637/16637/11648 +f 16813/16813/11798 16637/16637/11648 16636/16636/11647 +f 16791/16791/11778 16810/16810/11795 16635/16635/11646 +f 16791/16791/11778 16635/16635/11646 16512/16512/11536 +f 16814/16814/11679 16815/16815/11799 16816/16816/11800 +f 16814/16814/11679 16816/16816/11800 16817/16817/11801 +f 16815/16815/11799 16794/16794/11780 16797/16797/11783 +f 16815/16815/11799 16797/16797/11783 16816/16816/11800 +f 16816/16816/11800 16797/16797/11783 16818/16818/11802 +f 16816/16816/11800 16818/16818/11802 16819/16819/11803 +f 16820/16820/11804 16821/16821/11800 16554/16554/11576 +f 16820/16820/11804 16554/16554/11576 16535/16535/11557 +f 16822/16822/11693 16823/16823/11690 16824/16824/11805 +f 16822/16822/11693 16824/16824/11805 16825/16825/11806 +f 16823/16823/11690 16826/16826/11674 16827/16827/11807 +f 16823/16823/11690 16827/16827/11807 16824/16824/11805 +f 16828/16828/11805 16829/16829/11807 16702/16702/11704 +f 16828/16828/11805 16702/16702/11704 16701/16701/11703 +f 16830/16830/11808 16828/16828/11805 16701/16701/11703 +f 16830/16830/11808 16701/16701/11703 16566/16566/11586 +f 16826/16826/11674 16831/16831/11809 16832/16832/11810 +f 16826/16826/11674 16832/16832/11810 16827/16827/11807 +f 16831/16831/11809 16833/16833/11811 16834/16834/11767 +f 16831/16831/11809 16834/16834/11767 16832/16832/11810 +f 16835/16835/11812 16836/16836/11767 16533/16533/11555 +f 16835/16835/11812 16533/16533/11555 16712/16712/11712 +f 16829/16829/11807 16835/16835/11812 16712/16712/11712 +f 16829/16829/11807 16712/16712/11712 16702/16702/11704 +f 16837/16837/11813 16838/16838/11814 16839/16839/11815 +f 16837/16837/11813 16839/16839/11815 16840/16840/11816 +f 16838/16838/11814 16822/16822/11693 16825/16825/11806 +f 16838/16838/11814 16825/16825/11806 16839/16839/11815 +f 16841/16841/11817 16842/16842/11806 16843/16843/11818 +f 16841/16841/11817 16843/16843/11818 16564/16564/11584 +f 16806/16806/11791 16841/16841/11817 16564/16564/11584 +f 16806/16806/11791 16564/16564/11584 16541/16541/11563 +f 16844/16844/11819 16845/16845/11820 16846/16846/11821 +f 16844/16844/11819 16846/16846/11821 16847/16847/11822 +f 16845/16845/11820 16848/16848/11823 16849/16849/11824 +f 16845/16845/11820 16849/16849/11824 16846/16846/11821 +f 16850/16850/11821 16851/16851/11824 16852/16852/11825 +f 16850/16850/11821 16852/16852/11825 16853/16853/11826 +f 16854/16854/11827 16850/16850/11821 16853/16853/11826 +f 16854/16854/11827 16853/16853/11826 16855/16855/11828 +f 16856/16856/11829 16857/16857/11830 16858/16858/11831 +f 16856/16856/11829 16858/16858/11831 16859/16859/11832 +f 16857/16857/11830 16860/16860/11833 16861/16861/11834 +f 16857/16857/11830 16861/16861/11834 16858/16858/11831 +f 16858/16858/11831 16861/16861/11834 16862/16862/11835 +f 16858/16858/11831 16862/16862/11835 16863/16863/11836 +f 16859/16859/11832 16858/16858/11831 16863/16863/11836 +f 16859/16859/11832 16863/16863/11836 16864/16864/11837 +f 16649/16649/11658 16648/16648/11657 16865/16865/11838 +f 16649/16649/11658 16865/16865/11838 16866/16866/11839 +f 16648/16648/11657 16647/16647/11656 16867/16867/11840 +f 16648/16648/11657 16867/16867/11840 16865/16865/11838 +f 16865/16865/11838 16867/16867/11840 16868/16868/11841 +f 16865/16865/11838 16868/16868/11841 16869/16869/11842 +f 16866/16866/11839 16865/16865/11838 16869/16869/11842 +f 16866/16866/11839 16869/16869/11842 16870/16870/11843 +f 16673/16673/11678 16672/16672/11677 16871/16871/11844 +f 16673/16673/11678 16871/16871/11844 16872/16872/11845 +f 16672/16672/11677 16671/16671/11676 16873/16873/11846 +f 16672/16672/11677 16873/16873/11846 16871/16871/11844 +f 16871/16871/11844 16873/16873/11846 16874/16874/11847 +f 16871/16871/11844 16874/16874/11847 16875/16875/11848 +f 16872/16872/11845 16871/16871/11844 16875/16875/11848 +f 16872/16872/11845 16875/16875/11848 16876/16876/11849 +f 16685/16685/11688 16684/16684/11687 16877/16877/11850 +f 16685/16685/11688 16877/16877/11850 16878/16878/11851 +f 16683/16683/11686 16682/16682/11685 16879/16879/11852 +f 16683/16683/11686 16879/16879/11852 16880/16880/11853 +f 16877/16877/11850 16881/16881/11854 16882/16882/11855 +f 16877/16877/11850 16882/16882/11855 16883/16883/11856 +f 16878/16878/11851 16877/16877/11850 16883/16883/11856 +f 16878/16878/11851 16883/16883/11856 16884/16884/11857 +f 16885/16885/11693 16886/16886/11814 16887/16887/11858 +f 16885/16885/11693 16887/16887/11858 16888/16888/11859 +f 16889/16889/11814 16890/16890/11860 16891/16891/11861 +f 16889/16889/11814 16891/16891/11861 16892/16892/11862 +f 16892/16892/11862 16891/16891/11861 16860/16860/11833 +f 16892/16892/11862 16860/16860/11833 16857/16857/11830 +f 16893/16893/11859 16892/16892/11862 16857/16857/11830 +f 16893/16893/11859 16857/16857/11830 16856/16856/11829 +f 16894/16894/11863 16895/16895/11864 16896/16896/11865 +f 16894/16894/11863 16896/16896/11865 16897/16897/11866 +f 16895/16895/11864 16898/16898/11867 16899/16899/11868 +f 16895/16895/11864 16899/16899/11868 16896/16896/11865 +f 16896/16896/11865 16899/16899/11868 16848/16848/11823 +f 16896/16896/11865 16848/16848/11823 16845/16845/11820 +f 16897/16897/11866 16896/16896/11865 16845/16845/11820 +f 16897/16897/11866 16845/16845/11820 16844/16844/11819 +f 16900/16900/11869 16901/16901/11870 16902/16902/11871 +f 16900/16900/11869 16902/16902/11871 16903/16903/11872 +f 16901/16901/11870 16904/16904/11733 16905/16905/11873 +f 16901/16901/11870 16905/16905/11873 16902/16902/11871 +f 16902/16902/11871 16905/16905/11873 16906/16906/11874 +f 16902/16902/11871 16906/16906/11874 16907/16907/11875 +f 16903/16903/11872 16902/16902/11871 16907/16907/11875 +f 16903/16903/11872 16907/16907/11875 16908/16908/11876 +f 16909/16909/11877 16910/16910/11781 16911/16911/11878 +f 16909/16909/11877 16911/16911/11878 16912/16912/11879 +f 16910/16910/11781 16913/16913/11880 16914/16914/11881 +f 16910/16910/11781 16914/16914/11881 16911/16911/11878 +f 16911/16911/11878 16914/16914/11881 16915/16915/11882 +f 16911/16911/11878 16915/16915/11882 16916/16916/11883 +f 16912/16912/11879 16911/16911/11878 16916/16916/11883 +f 16912/16912/11879 16916/16916/11883 16917/16917/11884 +f 16904/16904/11733 16918/16918/11740 16919/16919/11885 +f 16904/16904/11733 16919/16919/11885 16905/16905/11873 +f 16920/16920/11886 16656/16656/11662 16659/16659/11665 +f 16920/16920/11886 16659/16659/11665 16921/16921/11887 +f 16921/16921/11887 16659/16659/11665 16664/16664/11670 +f 16921/16921/11887 16664/16664/11670 16922/16922/11888 +f 16923/16923/11889 16921/16921/11887 16922/16922/11888 +f 16923/16923/11889 16922/16922/11888 16924/16924/11890 +f 16890/16890/11860 16925/16925/11891 16926/16926/11892 +f 16890/16890/11860 16926/16926/11892 16891/16891/11861 +f 16927/16927/11787 16928/16928/11786 16929/16929/11893 +f 16927/16927/11787 16929/16929/11893 16930/16930/11894 +f 16930/16930/11894 16929/16929/11893 16931/16931/11895 +f 16930/16930/11894 16931/16931/11895 16932/16932/11896 +f 16891/16891/11861 16926/16926/11892 16933/16933/11897 +f 16891/16891/11861 16933/16933/11897 16860/16860/11833 +f 16643/16643/11653 16934/16934/11898 16935/16935/11899 +f 16643/16643/11653 16935/16935/11899 16644/16644/11654 +f 16934/16934/11898 16936/16936/11900 16937/16937/11901 +f 16934/16934/11898 16937/16937/11901 16935/16935/11899 +f 16935/16935/11899 16937/16937/11901 16938/16938/11902 +f 16935/16935/11899 16938/16938/11902 16939/16939/11903 +f 16644/16644/11654 16935/16935/11899 16939/16939/11903 +f 16644/16644/11654 16939/16939/11903 16940/16940/11904 +f 16936/16936/11900 16941/16941/11905 16942/16942/11906 +f 16936/16936/11900 16942/16942/11906 16937/16937/11901 +f 16943/16943/11907 16944/16944/11908 16945/16945/11909 +f 16943/16943/11907 16945/16945/11909 16946/16946/11910 +f 16946/16946/11910 16945/16945/11909 16947/16947/11911 +f 16946/16946/11910 16947/16947/11911 16948/16948/11912 +f 16937/16937/11901 16942/16942/11906 16949/16949/11913 +f 16937/16937/11901 16949/16949/11913 16938/16938/11902 +f 16928/16928/11786 16950/16950/11914 16951/16951/11915 +f 16928/16928/11786 16951/16951/11915 16929/16929/11893 +f 16950/16950/11914 16900/16900/11869 16903/16903/11872 +f 16950/16950/11914 16903/16903/11872 16951/16951/11915 +f 16951/16951/11915 16903/16903/11872 16908/16908/11876 +f 16951/16951/11915 16908/16908/11876 16952/16952/11916 +f 16929/16929/11893 16951/16951/11915 16952/16952/11916 +f 16929/16929/11893 16952/16952/11916 16931/16931/11895 +f 16913/16913/11880 16953/16953/11917 16954/16954/11918 +f 16913/16913/11880 16954/16954/11918 16914/16914/11881 +f 16955/16955/11919 16674/16674/11679 16677/16677/11682 +f 16955/16955/11919 16677/16677/11682 16956/16956/11918 +f 16956/16956/11918 16677/16677/11682 16685/16685/11688 +f 16956/16956/11918 16685/16685/11688 16957/16957/11920 +f 16914/16914/11881 16954/16954/11918 16958/16958/11921 +f 16914/16914/11881 16958/16958/11921 16915/16915/11882 +f 16959/16959/11922 16960/16960/11875 16961/16961/11923 +f 16959/16959/11922 16961/16961/11923 16962/16962/11924 +f 16907/16907/11875 16906/16906/11874 16963/16963/11925 +f 16907/16907/11875 16963/16963/11925 16964/16964/11923 +f 16961/16961/11923 16965/16965/11926 16966/16966/11927 +f 16961/16961/11923 16966/16966/11927 16967/16967/11928 +f 16962/16962/11924 16961/16961/11923 16967/16967/11928 +f 16962/16962/11924 16967/16967/11928 16968/16968/11929 +f 16917/16917/11884 16916/16916/11883 16969/16969/11930 +f 16917/16917/11884 16969/16969/11930 16851/16851/11824 +f 16916/16916/11883 16915/16915/11882 16970/16970/11931 +f 16916/16916/11883 16970/16970/11931 16969/16969/11930 +f 16969/16969/11930 16970/16970/11931 16971/16971/11932 +f 16969/16969/11930 16971/16971/11932 16972/16972/11933 +f 16851/16851/11824 16969/16969/11930 16972/16972/11933 +f 16851/16851/11824 16972/16972/11933 16852/16852/11825 +f 16924/16924/11890 16922/16922/11888 16973/16973/11934 +f 16924/16924/11890 16973/16973/11934 16965/16965/11926 +f 16922/16922/11888 16664/16664/11670 16974/16974/11935 +f 16922/16922/11888 16974/16974/11935 16973/16973/11934 +f 16973/16973/11934 16974/16974/11935 16975/16975/11936 +f 16973/16973/11934 16975/16975/11936 16976/16976/11937 +f 16965/16965/11926 16973/16973/11934 16976/16976/11937 +f 16965/16965/11926 16976/16976/11937 16966/16966/11927 +f 16860/16860/11833 16933/16933/11897 16977/16977/11938 +f 16860/16860/11833 16977/16977/11938 16861/16861/11834 +f 16932/16932/11896 16931/16931/11895 16978/16978/11939 +f 16932/16932/11896 16978/16978/11939 16979/16979/11938 +f 16979/16979/11938 16978/16978/11939 16980/16980/11940 +f 16979/16979/11938 16980/16980/11940 16981/16981/11941 +f 16861/16861/11834 16977/16977/11938 16982/16982/11942 +f 16861/16861/11834 16982/16982/11942 16862/16862/11835 +f 16647/16647/11656 16983/16983/11903 16984/16984/11943 +f 16647/16647/11656 16984/16984/11943 16867/16867/11840 +f 16939/16939/11903 16938/16938/11902 16985/16985/11944 +f 16939/16939/11903 16985/16985/11944 16986/16986/11945 +f 16986/16986/11945 16985/16985/11944 16987/16987/11946 +f 16986/16986/11945 16987/16987/11946 16988/16988/11947 +f 16867/16867/11840 16984/16984/11943 16989/16989/11948 +f 16867/16867/11840 16989/16989/11948 16868/16868/11841 +f 16938/16938/11902 16949/16949/11913 16990/16990/11949 +f 16938/16938/11902 16990/16990/11949 16985/16985/11944 +f 16948/16948/11912 16947/16947/11911 16854/16854/11827 +f 16948/16948/11912 16854/16854/11827 16991/16991/11949 +f 16991/16991/11949 16854/16854/11827 16855/16855/11828 +f 16991/16991/11949 16855/16855/11828 16992/16992/11950 +f 16985/16985/11944 16990/16990/11949 16993/16993/11951 +f 16985/16985/11944 16993/16993/11951 16987/16987/11946 +f 16931/16931/11895 16952/16952/11916 14164/14164/9468 +f 16931/16931/11895 14164/14164/9468 16978/16978/11939 +f 16952/16952/11916 16908/16908/11876 14165/14165/9469 +f 16952/16952/11916 14165/14165/9469 14164/14164/9468 +f 16978/16978/11939 14164/14164/9468 14166/14166/9470 +f 16978/16978/11939 14166/14166/9470 16980/16980/11940 +f 16915/16915/11882 16958/16958/11921 16994/16994/11952 +f 16915/16915/11882 16994/16994/11952 16970/16970/11931 +f 16957/16957/11920 16685/16685/11688 16878/16878/11851 +f 16957/16957/11920 16878/16878/11851 16995/16995/11953 +f 16995/16995/11953 16878/16878/11851 16884/16884/11857 +f 16995/16995/11953 16884/16884/11857 16996/16996/11954 +f 16970/16970/11931 16994/16994/11952 16997/16997/11955 +f 16970/16970/11931 16997/16997/11955 16971/16971/11932 +f 16682/16682/11685 16698/16698/11700 16998/16998/11956 +f 16682/16682/11685 16998/16998/11956 16879/16879/11852 +f 16698/16698/11700 16649/16649/11658 16866/16866/11839 +f 16698/16698/11700 16866/16866/11839 16998/16998/11956 +f 16999/16999/11957 17000/17000/11958 17001/17001/11959 +f 16999/16999/11957 17001/17001/11959 17002/17002/11960 +f 16881/16881/11854 16999/16999/11957 17002/17002/11960 +f 16881/16881/11854 17002/17002/11960 16882/16882/11855 +f 17003/17003/11676 17004/17004/11697 17005/17005/11961 +f 17003/17003/11676 17005/17005/11961 17006/17006/11962 +f 17004/17004/11697 16856/16856/11829 16859/16859/11832 +f 17004/17004/11697 16859/16859/11832 17005/17005/11961 +f 17005/17005/11961 16859/16859/11832 16864/16864/11837 +f 17005/17005/11961 16864/16864/11837 17007/17007/11963 +f 17006/17006/11962 17005/17005/11961 17007/17007/11963 +f 17006/17006/11962 17007/17007/11963 17008/17008/11964 +f 17009/17009/11965 17010/17010/11966 17011/17011/11967 +f 17009/17009/11965 17011/17011/11967 17012/17012/11968 +f 17013/17013/11967 17014/17014/11969 17015/17015/11970 +f 17013/17013/11967 17015/17015/11970 17016/17016/11971 +f 17017/17017/11968 17018/17018/11967 17019/17019/11972 +f 17017/17017/11968 17019/17019/11972 17020/17020/11973 +f 17021/17021/11974 17022/17022/11975 17023/17023/11976 +f 17021/17021/11974 17023/17023/11976 17024/17024/11977 +f 17025/17025/11975 17026/17026/11978 17027/17027/11979 +f 17025/17025/11975 17027/17027/11979 17028/17028/11980 +f 17029/17029/11980 17030/17030/11979 17031/17031/11981 +f 17029/17029/11980 17031/17031/11981 17032/17032/11982 +f 17024/17024/11977 17023/17023/11976 17033/17033/11983 +f 17024/17024/11977 17033/17033/11983 17034/17034/11984 +f 17035/17035/11985 17036/17036/11986 17037/17037/11987 +f 17035/17035/11985 17037/17037/11987 17038/17038/11988 +f 17014/17014/11969 17035/17035/11985 17038/17038/11988 +f 17014/17014/11969 17038/17038/11988 17015/17015/11970 +f 17015/17015/11970 17038/17038/11988 17039/17039/11989 +f 17015/17015/11970 17039/17039/11989 17016/17016/11971 +f 17038/17038/11988 17037/17037/11987 17040/17040/11990 +f 17038/17038/11988 17040/17040/11990 17039/17039/11989 +f 17041/17041/11991 17042/17042/11992 17043/17043/11993 +f 17041/17041/11991 17043/17043/11993 17044/17044/11994 +f 17019/17019/11972 17041/17041/11991 17044/17044/11994 +f 17019/17019/11972 17044/17044/11994 17020/17020/11973 +f 17031/17031/11981 17045/17045/11995 17046/17046/11996 +f 17031/17031/11981 17046/17046/11996 17032/17032/11982 +f 17045/17045/11995 17047/17047/11997 17048/17048/11998 +f 17045/17045/11995 17048/17048/11998 17046/17046/11996 +f 17049/17049/11999 17050/17050/12000 17051/17051/12001 +f 17049/17049/11999 17051/17051/12001 17052/17052/12002 +f 17033/17033/11983 17049/17049/11999 17052/17052/12002 +f 17033/17033/11983 17052/17052/12002 17034/17034/11984 +f 17047/17047/11997 17045/17045/11995 17053/17053/12003 +f 17047/17047/11997 17053/17053/12003 17054/17054/12004 +f 17045/17045/11995 17031/17031/11981 17055/17055/12005 +f 17045/17045/11995 17055/17055/12005 17053/17053/12003 +f 17053/17053/12003 17055/17055/12005 17020/17020/11973 +f 17053/17053/12003 17020/17020/11973 17044/17044/11994 +f 17054/17054/12004 17053/17053/12003 17044/17044/11994 +f 17054/17054/12004 17044/17044/11994 17043/17043/11993 +f 17056/17056/12006 17057/17057/12007 17058/17058/12008 +f 17056/17056/12006 17058/17058/12008 17059/17059/12009 +f 17057/17057/12007 17060/17060/12010 17061/17061/12011 +f 17057/17057/12007 17061/17061/12011 17058/17058/12008 +f 17062/17062/12012 17063/17063/12013 17047/17047/11997 +f 17062/17062/12012 17047/17047/11997 17054/17054/12004 +f 17064/17064/12009 17062/17062/12012 17054/17054/12004 +f 17064/17064/12009 17054/17054/12004 17043/17043/11993 +f 17065/17065/12014 17066/17066/12015 17067/17067/12016 +f 17065/17065/12014 17067/17067/12016 17068/17068/12017 +f 17066/17066/12015 17021/17021/11974 17024/17024/11977 +f 17066/17066/12015 17024/17024/11977 17067/17067/12016 +f 17067/17067/12016 17024/17024/11977 17034/17034/11984 +f 17067/17067/12016 17034/17034/11984 17052/17052/12002 +f 17068/17068/12017 17067/17067/12016 17052/17052/12002 +f 17068/17068/12017 17052/17052/12002 17051/17051/12001 +f 17069/17069/12018 17070/17070/12019 17071/17071/12009 +f 17069/17069/12018 17071/17071/12009 17072/17072/12020 +f 17073/17073/12020 17064/17064/12009 17043/17043/11993 +f 17073/17073/12020 17043/17043/11993 17042/17042/11992 +f 17036/17036/11986 17074/17074/12021 17040/17040/11990 +f 17036/17036/11986 17040/17040/11990 17037/17037/11987 +f 17075/17075/12022 17076/17076/12023 17077/17077/12024 +f 17075/17075/12022 17077/17077/12024 17078/17078/12025 +f 17076/17076/12023 17065/17065/12014 17068/17068/12017 +f 17076/17076/12023 17068/17068/12017 17077/17077/12024 +f 17077/17077/12024 17068/17068/12017 17051/17051/12001 +f 17077/17077/12024 17051/17051/12001 17050/17050/12000 +f 17063/17063/12013 17079/17079/12026 17048/17048/11998 +f 17063/17063/12013 17048/17048/11998 17047/17047/11997 +f 17026/17026/11978 17080/17080/12027 17081/17081/12028 +f 17026/17026/11978 17081/17081/12028 17027/17027/11979 +f 17080/17080/12027 17082/17082/12029 17083/17083/11968 +f 17080/17080/12027 17083/17083/11968 17081/17081/12028 +f 17084/17084/12030 17017/17017/11968 17020/17020/11973 +f 17084/17084/12030 17020/17020/11973 17055/17055/12005 +f 17030/17030/11979 17084/17084/12030 17055/17055/12005 +f 17030/17030/11979 17055/17055/12005 17031/17031/11981 +f 17021/17021/11974 17066/17066/12015 17085/17085/12031 +f 17021/17021/11974 17085/17085/12031 17086/17086/12032 +f 17066/17066/12015 17065/17065/12014 17087/17087/12033 +f 17066/17066/12015 17087/17087/12033 17085/17085/12031 +f 17085/17085/12031 17087/17087/12033 17088/17088/12034 +f 17085/17085/12031 17088/17088/12034 17089/17089/12035 +f 17086/17086/12032 17085/17085/12031 17089/17089/12035 +f 17086/17086/12032 17089/17089/12035 17090/17090/12036 +f 17070/17070/12019 17069/17069/12018 17091/17091/12037 +f 17070/17070/12019 17091/17091/12037 17092/17092/12038 +f 17092/17092/12038 17091/17091/12037 17093/17093/12039 +f 17092/17092/12038 17093/17093/12039 17094/17094/12040 +f 17065/17065/12014 17076/17076/12023 17095/17095/12041 +f 17065/17065/12014 17095/17095/12041 17087/17087/12033 +f 17076/17076/12023 17075/17075/12022 17096/17096/12042 +f 17076/17076/12023 17096/17096/12042 17095/17095/12041 +f 17095/17095/12041 17096/17096/12042 17097/17097/12043 +f 17095/17095/12041 17097/17097/12043 17098/17098/12044 +f 17087/17087/12033 17095/17095/12041 17098/17098/12044 +f 17087/17087/12033 17098/17098/12044 17088/17088/12034 +f 17082/17082/12029 17080/17080/12027 17099/17099/12045 +f 17082/17082/12029 17099/17099/12045 17100/17100/12046 +f 17080/17080/12027 17026/17026/11978 17101/17101/12047 +f 17080/17080/12027 17101/17101/12047 17099/17099/12045 +f 17099/17099/12045 17101/17101/12047 17102/17102/12048 +f 17099/17099/12045 17102/17102/12048 17103/17103/12049 +f 17100/17100/12046 17099/17099/12045 17103/17103/12049 +f 17100/17100/12046 17103/17103/12049 17104/17104/12050 +f 17105/17105/12051 17022/17022/11975 17106/17106/12052 +f 17105/17105/12051 17106/17106/12052 17107/17107/12053 +f 17022/17022/11975 17021/17021/11974 17086/17086/12032 +f 17022/17022/11975 17086/17086/12032 17106/17106/12052 +f 17106/17106/12052 17086/17086/12032 17090/17090/12036 +f 17106/17106/12052 17090/17090/12036 17108/17108/12054 +f 17107/17107/12053 17106/17106/12052 17108/17108/12054 +f 17107/17107/12053 17108/17108/12054 17109/17109/12048 +f 17010/17010/11966 17009/17009/11965 17110/17110/12055 +f 17010/17010/11966 17110/17110/12055 17111/17111/12056 +f 17111/17111/12056 17110/17110/12055 17112/17112/12057 +f 17111/17111/12056 17112/17112/12057 17113/17113/12058 +f 17060/17060/12010 17057/17057/12007 17114/17114/12059 +f 17060/17060/12010 17114/17114/12059 17115/17115/12042 +f 17057/17057/12007 17056/17056/12006 17116/17116/12038 +f 17057/17057/12007 17116/17116/12038 17114/17114/12059 +f 17114/17114/12059 17116/17116/12038 17117/17117/12060 +f 17114/17114/12059 17117/17117/12060 17118/17118/12061 +f 17115/17115/12042 17114/17114/12059 17118/17118/12061 +f 17115/17115/12042 17118/17118/12061 17119/17119/12062 +f 17094/17094/12040 17093/17093/12039 17120/17120/12063 +f 17094/17094/12040 17120/17120/12063 17121/17121/12064 +f 17121/17121/12064 17120/17120/12063 17122/17122/12065 +f 17121/17121/12064 17122/17122/12065 17123/17123/12066 +f 17088/17088/12034 17098/17098/12044 17124/17124/12067 +f 17088/17088/12034 17124/17124/12067 17125/17125/12068 +f 17098/17098/12044 17097/17097/12043 17126/17126/12069 +f 17098/17098/12044 17126/17126/12069 17124/17124/12067 +f 17124/17124/12067 17126/17126/12069 17127/17127/12070 +f 17124/17124/12067 17127/17127/12070 17128/17128/12071 +f 17125/17125/12068 17124/17124/12067 17128/17128/12071 +f 17125/17125/12068 17128/17128/12071 17129/17129/12072 +f 17104/17104/12050 17103/17103/12049 17130/17130/12073 +f 17104/17104/12050 17130/17130/12073 17131/17131/12074 +f 17103/17103/12049 17102/17102/12048 17132/17132/12075 +f 17103/17103/12049 17132/17132/12075 17130/17130/12073 +f 17130/17130/12073 17132/17132/12075 17133/17133/12076 +f 17130/17130/12073 17133/17133/12076 17134/17134/12077 +f 17131/17131/12074 17130/17130/12073 17134/17134/12077 +f 17131/17131/12074 17134/17134/12077 17135/17135/12078 +f 17109/17109/12048 17108/17108/12054 17136/17136/12079 +f 17109/17109/12048 17136/17136/12079 17137/17137/12080 +f 17108/17108/12054 17090/17090/12036 17138/17138/12081 +f 17108/17108/12054 17138/17138/12081 17136/17136/12079 +f 17136/17136/12079 17138/17138/12081 17139/17139/12082 +f 17136/17136/12079 17139/17139/12082 17140/17140/12083 +f 17137/17137/12080 17136/17136/12079 17140/17140/12083 +f 17137/17137/12080 17140/17140/12083 17141/17141/12076 +f 17113/17113/12058 17112/17112/12057 17142/17142/12074 +f 17113/17113/12058 17142/17142/12074 17143/17143/12084 +f 17143/17143/12084 17142/17142/12074 17144/17144/12085 +f 17143/17143/12084 17144/17144/12085 17145/17145/12086 +f 17119/17119/12062 17118/17118/12061 17146/17146/12087 +f 17119/17119/12062 17146/17146/12087 17147/17147/12069 +f 17118/17118/12061 17117/17117/12060 17148/17148/12064 +f 17118/17118/12061 17148/17148/12064 17146/17146/12087 +f 17146/17146/12087 17148/17148/12064 17149/17149/12088 +f 17146/17146/12087 17149/17149/12088 17150/17150/12089 +f 17147/17147/12069 17146/17146/12087 17150/17150/12089 +f 17147/17147/12069 17150/17150/12089 17151/17151/12090 +f 17090/17090/12036 17089/17089/12035 17152/17152/12091 +f 17090/17090/12036 17152/17152/12091 17138/17138/12081 +f 17089/17089/12035 17088/17088/12034 17125/17125/12068 +f 17089/17089/12035 17125/17125/12068 17152/17152/12091 +f 17152/17152/12091 17125/17125/12068 17129/17129/12072 +f 17152/17152/12091 17129/17129/12072 17153/17153/12092 +f 17138/17138/12081 17152/17152/12091 17153/17153/12092 +f 17138/17138/12081 17153/17153/12092 17139/17139/12082 +f 17154/17154/12093 17155/17155/12094 17156/17156/12095 +f 17154/17154/12093 17156/17156/12095 17157/17157/12096 +f 17155/17155/12094 17158/17158/12097 17159/17159/12098 +f 17155/17155/12094 17159/17159/12098 17156/17156/12095 +f 17156/17156/12095 17159/17159/12098 17160/17160/12099 +f 17156/17156/12095 17160/17160/12099 17161/17161/12100 +f 17157/17157/12096 17156/17156/12095 17161/17161/12100 +f 17157/17157/12096 17161/17161/12100 17162/17162/12101 +f 17163/17163/12102 17164/17164/12103 17165/17165/12104 +f 17163/17163/12102 17165/17165/12104 17166/17166/12105 +f 17164/17164/12103 17167/17167/12106 17168/17168/12107 +f 17164/17164/12103 17168/17168/12107 17165/17165/12104 +f 17165/17165/12104 17168/17168/12107 17169/17169/12108 +f 17165/17165/12104 17169/17169/12108 17170/17170/12109 +f 17166/17166/12105 17165/17165/12104 17170/17170/12109 +f 17166/17166/12105 17170/17170/12109 17171/17171/12110 +f 17172/17172/12111 17173/17173/12112 17174/17174/12113 +f 17172/17172/12111 17174/17174/12113 17175/17175/12098 +f 17173/17173/12112 17176/17176/12114 17177/17177/12115 +f 17173/17173/12112 17177/17177/12115 17174/17174/12113 +f 17174/17174/12113 17177/17177/12115 17178/17178/12116 +f 17174/17174/12113 17178/17178/12116 17179/17179/12117 +f 17159/17159/12098 17180/17180/12113 17181/17181/12118 +f 17159/17159/12098 17181/17181/12118 17160/17160/12099 +f 17167/17167/12106 17182/17182/12119 17183/17183/12120 +f 17167/17167/12106 17183/17183/12120 17168/17168/12107 +f 17182/17182/12119 17184/17184/12121 17185/17185/12122 +f 17182/17182/12119 17185/17185/12122 17183/17183/12120 +f 17183/17183/12120 17185/17185/12122 17186/17186/12123 +f 17183/17183/12120 17186/17186/12123 17187/17187/12124 +f 17168/17168/12107 17183/17183/12120 17187/17187/12124 +f 17168/17168/12107 17187/17187/12124 17169/17169/12108 +f 17188/17188/12125 17189/17189/12126 17190/17190/12127 +f 17188/17188/12125 17190/17190/12127 17191/17191/12128 +f 17189/17189/12126 17192/17192/12129 17193/17193/12130 +f 17189/17189/12126 17193/17193/12130 17190/17190/12127 +f 17190/17190/12127 17193/17193/12130 17194/17194/12131 +f 17190/17190/12127 17194/17194/12131 17195/17195/12132 +f 17191/17191/12128 17190/17190/12127 17195/17195/12132 +f 17191/17191/12128 17195/17195/12132 17196/17196/12133 +f 17176/17176/12114 17197/17197/12134 17198/17198/12135 +f 17176/17176/12114 17198/17198/12135 17177/17177/12115 +f 17197/17197/12134 17199/17199/12136 17200/17200/12137 +f 17197/17197/12134 17200/17200/12137 17198/17198/12135 +f 17198/17198/12135 17200/17200/12137 17201/17201/12138 +f 17198/17198/12135 17201/17201/12138 17202/17202/12139 +f 17177/17177/12115 17198/17198/12135 17202/17202/12139 +f 17177/17177/12115 17202/17202/12139 17178/17178/12116 +f 17203/17203/12129 17204/17204/12140 17205/17205/12141 +f 17203/17203/12129 17205/17205/12141 17206/17206/12142 +f 17204/17204/12140 17163/17163/12102 17166/17166/12105 +f 17204/17204/12140 17166/17166/12105 17205/17205/12141 +f 17205/17205/12141 17166/17166/12105 17171/17171/12110 +f 17205/17205/12141 17171/17171/12110 17207/17207/12143 +f 17193/17193/12130 17208/17208/12144 17209/17209/12145 +f 17193/17193/12130 17209/17209/12145 17194/17194/12131 +f 17199/17199/12136 17210/17210/12146 17211/17211/12147 +f 17199/17199/12136 17211/17211/12147 17200/17200/12137 +f 17210/17210/12146 17212/17212/12125 17213/17213/12148 +f 17210/17210/12146 17213/17213/12148 17211/17211/12147 +f 17211/17211/12147 17213/17213/12148 17214/17214/12149 +f 17211/17211/12147 17214/17214/12149 17215/17215/12150 +f 17200/17200/12137 17211/17211/12147 17215/17215/12150 +f 17200/17200/12137 17215/17215/12150 17201/17201/12138 +f 17194/17194/12131 17209/17209/12145 17216/17216/12151 +f 17194/17194/12131 17216/17216/12151 17217/17217/12152 +f 17207/17207/12143 17171/17171/12110 17218/17218/12153 +f 17207/17207/12143 17218/17218/12153 17219/17219/12154 +f 17220/17220/12155 17221/17221/12153 17222/17222/12156 +f 17220/17220/12155 17222/17222/12156 17223/17223/12157 +f 17224/17224/12152 17220/17220/12155 17223/17223/12157 +f 17224/17224/12152 17223/17223/12157 17225/17225/12158 +f 17201/17201/12138 17215/17215/12150 17226/17226/12159 +f 17201/17201/12138 17226/17226/12159 17227/17227/12160 +f 17228/17228/12150 17196/17196/12133 17229/17229/12161 +f 17228/17228/12150 17229/17229/12161 17230/17230/12159 +f 17230/17230/12159 17229/17229/12161 17231/17231/12162 +f 17230/17230/12159 17231/17231/12162 17232/17232/12163 +f 17227/17227/12160 17226/17226/12159 17233/17233/12164 +f 17227/17227/12160 17233/17233/12164 17234/17234/12165 +f 17162/17162/12101 17161/17161/12100 17235/17235/12166 +f 17162/17162/12101 17235/17235/12166 17236/17236/12167 +f 17161/17161/12100 17160/17160/12099 17237/17237/12168 +f 17161/17161/12100 17237/17237/12168 17235/17235/12166 +f 17235/17235/12166 17237/17237/12168 17238/17238/12169 +f 17235/17235/12166 17238/17238/12169 17239/17239/12170 +f 17236/17236/12167 17235/17235/12166 17239/17239/12170 +f 17236/17236/12167 17239/17239/12170 17240/17240/12171 +f 17171/17171/12110 17170/17170/12109 17241/17241/12172 +f 17171/17171/12110 17241/17241/12172 17218/17218/12153 +f 17170/17170/12109 17169/17169/12108 17242/17242/12173 +f 17170/17170/12109 17242/17242/12173 17241/17241/12172 +f 17241/17241/12172 17242/17242/12173 17243/17243/12174 +f 17241/17241/12172 17243/17243/12174 17244/17244/12175 +f 17221/17221/12153 17245/17245/12172 17246/17246/12175 +f 17221/17221/12153 17246/17246/12175 17222/17222/12156 +f 17160/17160/12099 17181/17181/12118 17247/17247/12176 +f 17160/17160/12099 17247/17247/12176 17237/17237/12168 +f 17179/17179/12117 17178/17178/12116 17248/17248/12177 +f 17179/17179/12117 17248/17248/12177 17249/17249/12178 +f 17249/17249/12178 17248/17248/12177 17250/17250/12179 +f 17249/17249/12178 17250/17250/12179 17251/17251/12180 +f 17237/17237/12168 17247/17247/12176 17252/17252/12181 +f 17237/17237/12168 17252/17252/12181 17238/17238/12169 +f 17169/17169/12108 17187/17187/12124 17253/17253/12182 +f 17169/17169/12108 17253/17253/12182 17242/17242/12173 +f 17187/17187/12124 17186/17186/12123 17254/17254/12167 +f 17187/17187/12124 17254/17254/12167 17253/17253/12182 +f 17253/17253/12182 17254/17254/12167 17255/17255/12183 +f 17253/17253/12182 17255/17255/12183 17256/17256/12184 +f 17242/17242/12173 17253/17253/12182 17256/17256/12184 +f 17242/17242/12173 17256/17256/12184 17243/17243/12174 +f 17196/17196/12133 17195/17195/12132 17257/17257/12185 +f 17196/17196/12133 17257/17257/12185 17229/17229/12161 +f 17195/17195/12132 17194/17194/12131 17217/17217/12152 +f 17195/17195/12132 17217/17217/12152 17257/17257/12185 +f 17257/17257/12185 17217/17217/12152 17258/17258/12186 +f 17257/17257/12185 17258/17258/12186 17259/17259/12187 +f 17229/17229/12161 17257/17257/12185 17259/17259/12187 +f 17229/17229/12161 17259/17259/12187 17231/17231/12162 +f 17178/17178/12116 17202/17202/12139 17260/17260/12188 +f 17178/17178/12116 17260/17260/12188 17248/17248/12177 +f 17202/17202/12139 17201/17201/12138 17227/17227/12160 +f 17202/17202/12139 17227/17227/12160 17260/17260/12188 +f 17260/17260/12188 17227/17227/12160 17234/17234/12165 +f 17260/17260/12188 17234/17234/12165 17261/17261/12189 +f 17248/17248/12177 17260/17260/12188 17261/17261/12189 +f 17248/17248/12177 17261/17261/12189 17250/17250/12179 +f 17262/17262/12190 17263/17263/12191 17264/17264/12192 +f 17262/17262/12190 17264/17264/12192 17265/17265/12193 +f 17263/17263/12191 17266/17266/12194 17267/17267/12195 +f 17263/17263/12191 17267/17267/12195 17264/17264/12192 +f 17268/17268/12196 17269/17269/12197 17270/17270/12198 +f 17268/17268/12196 17270/17270/12198 17271/17271/12199 +f 17272/17272/12200 17268/17268/12196 17271/17271/12199 +f 17272/17272/12200 17271/17271/12199 17273/17273/12201 +f 17238/17238/12169 17274/17274/12202 17275/17275/12203 +f 17238/17238/12169 17275/17275/12203 17239/17239/12170 +f 17274/17274/12202 17276/17276/12204 17277/17277/12205 +f 17274/17274/12202 17277/17277/12205 17275/17275/12203 +f 17275/17275/12203 17277/17277/12205 17278/17278/12206 +f 17275/17275/12203 17278/17278/12206 17279/17279/12207 +f 17239/17239/12170 17275/17275/12203 17279/17279/12207 +f 17239/17239/12170 17279/17279/12207 17240/17240/12171 +f 17225/17225/12158 17280/17280/12208 17281/17281/12209 +f 17225/17225/12158 17281/17281/12209 17282/17282/12210 +f 17280/17280/12208 17283/17283/12211 17284/17284/12212 +f 17280/17280/12208 17284/17284/12212 17281/17281/12209 +f 17285/17285/12213 17286/17286/12214 17287/17287/12215 +f 17285/17285/12213 17287/17287/12215 17288/17288/12216 +f 17282/17282/12210 17281/17281/12209 17289/17289/12217 +f 17282/17282/12210 17289/17289/12217 17290/17290/12162 +f 17291/17291/12218 17292/17292/12219 17293/17293/12220 +f 17291/17291/12218 17293/17293/12220 17294/17294/12221 +f 17292/17292/12219 17295/17295/12222 17296/17296/12223 +f 17292/17292/12219 17296/17296/12223 17293/17293/12220 +f 17293/17293/12220 17296/17296/12223 17297/17297/12224 +f 17293/17293/12220 17297/17297/12224 17298/17298/12225 +f 17294/17294/12221 17293/17293/12220 17298/17298/12225 +f 17294/17294/12221 17298/17298/12225 17299/17299/12226 +f 17300/17300/12227 17301/17301/12228 17302/17302/12229 +f 17300/17300/12227 17302/17302/12229 17303/17303/12230 +f 17301/17301/12228 17304/17304/12231 17305/17305/12232 +f 17301/17301/12228 17305/17305/12232 17302/17302/12229 +f 17302/17302/12229 17305/17305/12232 17266/17266/12194 +f 17302/17302/12229 17266/17266/12194 17263/17263/12191 +f 17303/17303/12230 17302/17302/12229 17263/17263/12191 +f 17303/17303/12230 17263/17263/12191 17262/17262/12190 +f 17306/17306/12174 17307/17307/12233 17308/17308/12234 +f 17306/17306/12174 17308/17308/12234 17246/17246/12175 +f 17307/17307/12233 17309/17309/12235 17310/17310/12236 +f 17307/17307/12233 17310/17310/12236 17308/17308/12234 +f 17308/17308/12234 17310/17310/12236 17311/17311/12237 +f 17308/17308/12234 17311/17311/12237 17312/17312/12238 +f 17246/17246/12175 17308/17308/12234 17312/17312/12238 +f 17246/17246/12175 17312/17312/12238 17222/17222/12156 +f 17313/17313/12239 17314/17314/12240 17315/17315/12241 +f 17313/17313/12239 17315/17315/12241 17316/17316/12242 +f 17314/17314/12240 17317/17317/12243 17318/17318/12244 +f 17314/17314/12240 17318/17318/12244 17315/17315/12241 +f 17319/17319/12241 17320/17320/12245 17295/17295/12222 +f 17319/17319/12241 17295/17295/12222 17292/17292/12219 +f 17321/17321/12242 17319/17319/12241 17292/17292/12219 +f 17321/17321/12242 17292/17292/12219 17291/17291/12218 +f 17322/17322/12246 17323/17323/12247 17324/17324/12248 +f 17322/17322/12246 17324/17324/12248 17325/17325/12249 +f 17323/17323/12247 17326/17326/12250 17327/17327/12251 +f 17323/17323/12247 17327/17327/12251 17324/17324/12248 +f 17324/17324/12248 17327/17327/12251 17304/17304/12231 +f 17324/17324/12248 17304/17304/12231 17301/17301/12228 +f 17325/17325/12249 17324/17324/12248 17301/17301/12228 +f 17325/17325/12249 17301/17301/12228 17300/17300/12227 +f 17328/17328/12252 17329/17329/12253 17330/17330/12254 +f 17328/17328/12252 17330/17330/12254 17331/17331/12255 +f 17329/17329/12253 17322/17322/12246 17332/17332/12256 +f 17329/17329/12253 17332/17332/12256 17330/17330/12254 +f 17330/17330/12254 17332/17332/12256 17333/17333/12257 +f 17330/17330/12254 17333/17333/12257 17334/17334/12258 +f 17331/17331/12255 17330/17330/12254 17334/17334/12258 +f 17331/17331/12255 17334/17334/12258 17335/17335/12259 +f 17291/17291/12218 17294/17294/12221 17336/17336/12260 +f 17291/17291/12218 17336/17336/12260 17337/17337/12261 +f 17294/17294/12221 17299/17299/12226 17338/17338/12262 +f 17294/17294/12221 17338/17338/12262 17336/17336/12260 +f 17336/17336/12260 17338/17338/12262 17339/17339/12263 +f 17336/17336/12260 17339/17339/12263 17340/17340/12264 +f 17337/17337/12261 17336/17336/12260 17340/17340/12264 +f 17337/17337/12261 17340/17340/12264 17341/17341/12265 +f 17300/17300/12227 17303/17303/12230 17342/17342/12266 +f 17300/17300/12227 17342/17342/12266 17343/17343/12267 +f 17303/17303/12230 17262/17262/12190 17344/17344/12268 +f 17303/17303/12230 17344/17344/12268 17342/17342/12266 +f 17342/17342/12266 17344/17344/12268 17345/17345/12269 +f 17342/17342/12266 17345/17345/12269 17346/17346/12270 +f 17343/17343/12267 17342/17342/12266 17346/17346/12270 +f 17343/17343/12267 17346/17346/12270 17347/17347/12271 +f 17262/17262/12190 17265/17265/12193 17348/17348/12272 +f 17262/17262/12190 17348/17348/12272 17344/17344/12268 +f 17272/17272/12200 17273/17273/12201 17349/17349/12273 +f 17272/17272/12200 17349/17349/12273 17350/17350/12274 +f 17350/17350/12274 17349/17349/12273 17351/17351/12275 +f 17350/17350/12274 17351/17351/12275 17352/17352/12276 +f 17353/17353/12277 17350/17350/12274 17352/17352/12276 +f 17353/17353/12277 17352/17352/12276 17354/17354/12278 +f 17299/17299/12226 17355/17355/12279 17356/17356/12280 +f 17299/17299/12226 17356/17356/12280 17338/17338/12262 +f 17355/17355/12279 17357/17357/12281 17358/17358/12255 +f 17355/17355/12279 17358/17358/12255 17356/17356/12280 +f 17359/17359/12282 17331/17331/12255 17335/17335/12259 +f 17359/17359/12282 17335/17335/12259 17360/17360/12283 +f 17338/17338/12262 17356/17356/12280 17361/17361/12283 +f 17338/17338/12262 17361/17361/12283 17339/17339/12263 +f 17362/17362/12284 17363/17363/12285 17364/17364/12286 +f 17362/17362/12284 17364/17364/12286 17365/17365/12287 +f 17321/17321/12242 17291/17291/12218 17337/17337/12261 +f 17321/17321/12242 17337/17337/12261 17366/17366/12286 +f 17366/17366/12286 17337/17337/12261 17341/17341/12265 +f 17366/17366/12286 17341/17341/12265 17367/17367/12288 +f 17365/17365/12287 17364/17364/12286 17368/17368/12289 +f 17365/17365/12287 17368/17368/12289 17369/17369/12290 +f 17322/17322/12246 17325/17325/12249 17370/17370/12291 +f 17322/17322/12246 17370/17370/12291 17332/17332/12256 +f 17325/17325/12249 17300/17300/12227 17343/17343/12267 +f 17325/17325/12249 17343/17343/12267 17370/17370/12291 +f 17370/17370/12291 17343/17343/12267 17347/17347/12271 +f 17370/17370/12291 17347/17347/12271 17371/17371/12292 +f 17332/17332/12256 17370/17370/12291 17371/17371/12292 +f 17332/17332/12256 17371/17371/12292 17333/17333/12257 +f 17372/17372/12201 17373/17373/12293 17374/17374/12294 +f 17372/17372/12201 17374/17374/12294 17375/17375/12295 +f 17373/17373/12293 17362/17362/12284 17365/17365/12287 +f 17373/17373/12293 17365/17365/12287 17374/17374/12294 +f 17374/17374/12294 17365/17365/12287 17369/17369/12290 +f 17374/17374/12294 17369/17369/12290 17376/17376/12296 +f 17375/17375/12295 17374/17374/12294 17376/17376/12296 +f 17375/17375/12295 17376/17376/12296 17377/17377/12297 +f 17354/17354/12278 17352/17352/12276 17378/17378/12298 +f 17354/17354/12278 17378/17378/12298 17379/17379/12270 +f 17377/17377/12297 17376/17376/12296 17380/17380/12298 +f 17377/17377/12297 17380/17380/12298 17381/17381/12299 +f 17369/17369/12290 17368/17368/12289 17380/17380/12298 +f 17369/17369/12290 17380/17380/12298 17376/17376/12296 +f 17382/17382/12300 17383/17383/12301 17380/17380/12298 +f 17382/17382/12300 17380/17380/12298 17368/17368/12289 +f 17384/17384/12302 17360/17360/12283 17380/17380/12298 +f 17384/17384/12302 17380/17380/12298 17383/17383/12301 +f 17335/17335/12259 17334/17334/12258 17380/17380/12298 +f 17335/17335/12259 17380/17380/12298 17360/17360/12283 +f 17333/17333/12257 17371/17371/12292 17380/17380/12298 +f 17333/17333/12257 17380/17380/12298 17334/17334/12258 +f 17347/17347/12271 17346/17346/12270 17380/17380/12298 +f 17347/17347/12271 17380/17380/12298 17371/17371/12292 +f 17385/17385/12303 17386/17386/12304 17387/17387/12305 +f 17385/17385/12303 17387/17387/12305 17388/17388/12306 +f 17386/17386/12304 17389/17389/12307 17390/17390/12308 +f 17386/17386/12304 17390/17390/12308 17387/17387/12305 +f 17387/17387/12305 17390/17390/12308 17391/17391/12309 +f 17387/17387/12305 17391/17391/12309 17392/17392/12232 +f 17393/17393/12306 17394/17394/12310 17305/17305/12232 +f 17393/17393/12306 17305/17305/12232 17304/17304/12231 +f 17395/17395/12311 17396/17396/12312 17397/17397/12313 +f 17395/17395/12311 17397/17397/12313 17398/17398/12314 +f 17399/17399/12315 17400/17400/12316 17401/17401/12317 +f 17399/17399/12315 17401/17401/12317 17402/17402/12313 +f 17402/17402/12313 17401/17401/12317 17403/17403/12318 +f 17402/17402/12313 17403/17403/12318 17404/17404/12319 +f 17398/17398/12314 17397/17397/12313 17405/17405/12320 +f 17398/17398/12314 17405/17405/12320 17406/17406/12321 +f 17311/17311/12237 17310/17310/12236 17407/17407/12322 +f 17311/17311/12237 17407/17407/12322 17408/17408/12323 +f 17310/17310/12236 17309/17309/12235 17409/17409/12324 +f 17310/17310/12236 17409/17409/12324 17407/17407/12322 +f 17410/17410/12322 17411/17411/12325 17297/17297/12224 +f 17410/17410/12322 17297/17297/12224 17296/17296/12223 +f 17412/17412/12323 17410/17410/12322 17296/17296/12223 +f 17412/17412/12323 17296/17296/12223 17295/17295/12222 +f 17413/17413/12326 17414/17414/12327 17415/17415/12328 +f 17413/17413/12326 17415/17415/12328 17416/17416/12329 +f 17414/17414/12327 17417/17417/12330 17418/17418/12331 +f 17414/17414/12327 17418/17418/12331 17415/17415/12328 +f 17415/17415/12328 17418/17418/12331 17419/17419/12332 +f 17415/17415/12328 17419/17419/12332 17420/17420/12333 +f 17416/17416/12329 17415/17415/12328 17420/17420/12333 +f 17416/17416/12329 17420/17420/12333 17421/17421/12334 +f 17422/17422/12335 17423/17423/12336 17424/17424/12337 +f 17422/17422/12335 17424/17424/12337 17425/17425/12338 +f 17423/17423/12336 17426/17426/12332 17427/17427/12339 +f 17423/17423/12336 17427/17427/12339 17424/17424/12337 +f 17424/17424/12337 17427/17427/12339 17428/17428/12340 +f 17424/17424/12337 17428/17428/12340 17429/17429/12341 +f 17430/17430/12342 17431/17431/12337 17432/17432/12341 +f 17430/17430/12342 17432/17432/12341 17433/17433/12343 +f 17434/17434/12344 17435/17435/12345 17436/17436/12346 +f 17434/17434/12344 17436/17436/12346 17437/17437/12347 +f 17435/17435/12345 17438/17438/12348 17439/17439/12349 +f 17435/17435/12345 17439/17439/12349 17436/17436/12346 +f 17436/17436/12346 17439/17439/12349 17440/17440/12350 +f 17436/17436/12346 17440/17440/12350 17441/17441/12351 +f 17437/17437/12347 17436/17436/12346 17441/17441/12351 +f 17437/17437/12347 17441/17441/12351 17442/17442/12352 +f 17433/17433/12343 17432/17432/12341 17443/17443/12353 +f 17433/17433/12343 17443/17443/12353 17444/17444/12354 +f 17445/17445/12341 17446/17446/12340 17447/17447/12355 +f 17445/17445/12341 17447/17447/12355 17448/17448/12356 +f 17448/17448/12356 17447/17447/12355 17449/17449/12357 +f 17448/17448/12356 17449/17449/12357 17450/17450/12358 +f 17444/17444/12354 17443/17443/12353 17451/17451/12359 +f 17444/17444/12354 17451/17451/12359 17452/17452/12360 +f 17453/17453/12352 17454/17454/12361 17455/17455/12362 +f 17453/17453/12352 17455/17455/12362 17456/17456/12363 +f 17457/17457/12364 17458/17458/12365 17459/17459/12366 +f 17457/17457/12364 17459/17459/12366 17460/17460/12367 +f 17460/17460/12367 17459/17459/12366 17400/17400/12316 +f 17460/17460/12367 17400/17400/12316 17399/17399/12315 +f 17456/17456/12363 17455/17455/12362 17396/17396/12312 +f 17456/17456/12363 17396/17396/12312 17395/17395/12311 +f 17328/17328/12252 17461/17461/12368 17462/17462/12369 +f 17328/17328/12252 17462/17462/12369 17329/17329/12253 +f 17461/17461/12368 17463/17463/12370 17464/17464/12371 +f 17461/17461/12368 17464/17464/12371 17462/17462/12369 +f 17462/17462/12369 17464/17464/12371 17326/17326/12250 +f 17462/17462/12369 17326/17326/12250 17323/17323/12247 +f 17329/17329/12253 17462/17462/12369 17323/17323/12247 +f 17329/17329/12253 17323/17323/12247 17322/17322/12246 +f 17240/17240/12171 17279/17279/12207 17465/17465/12372 +f 17240/17240/12171 17465/17465/12372 17466/17466/12373 +f 17279/17279/12207 17278/17278/12206 17467/17467/12374 +f 17279/17279/12207 17467/17467/12374 17465/17465/12372 +f 17468/17468/12372 17469/17469/12375 17309/17309/12235 +f 17468/17468/12372 17309/17309/12235 17307/17307/12233 +f 17256/17256/12184 17470/17470/12372 17471/17471/12376 +f 17256/17256/12184 17471/17471/12376 17243/17243/12174 +f 17372/17372/12201 17472/17472/12377 17473/17473/12378 +f 17372/17372/12201 17473/17473/12378 17373/17373/12293 +f 17472/17472/12377 17474/17474/12379 17475/17475/12380 +f 17472/17472/12377 17475/17475/12380 17473/17473/12378 +f 17473/17473/12378 17475/17475/12380 17476/17476/12381 +f 17473/17473/12378 17476/17476/12381 17477/17477/12240 +f 17373/17373/12293 17473/17473/12378 17477/17477/12240 +f 17373/17373/12293 17477/17477/12240 17362/17362/12284 +f 17299/17299/12226 17298/17298/12225 17478/17478/12382 +f 17299/17299/12226 17478/17478/12382 17355/17355/12279 +f 17298/17298/12225 17297/17297/12224 17479/17479/12383 +f 17298/17298/12225 17479/17479/12383 17478/17478/12382 +f 17480/17480/12382 17481/17481/12384 17463/17463/12370 +f 17480/17480/12382 17463/17463/12370 17461/17461/12368 +f 17482/17482/12279 17480/17480/12382 17461/17461/12368 +f 17482/17482/12279 17461/17461/12368 17328/17328/12252 +f 17483/17483/12385 17288/17288/12216 17484/17484/12386 +f 17483/17483/12385 17484/17484/12386 17233/17233/12164 +f 17288/17288/12216 17287/17287/12215 17485/17485/12387 +f 17288/17288/12216 17485/17485/12387 17484/17484/12386 +f 17484/17484/12386 17485/17485/12387 17389/17389/12307 +f 17484/17484/12386 17389/17389/12307 17486/17486/12388 +f 17233/17233/12164 17484/17484/12386 17486/17486/12388 +f 17233/17233/12164 17486/17486/12388 17234/17234/12165 +f 17250/17250/12179 17487/17487/12389 17488/17488/12390 +f 17250/17250/12179 17488/17488/12390 17251/17251/12180 +f 17487/17487/12389 17385/17385/12303 17489/17489/12391 +f 17487/17487/12389 17489/17489/12391 17488/17488/12390 +f 17490/17490/12392 17491/17491/12391 17276/17276/12204 +f 17490/17490/12392 17276/17276/12204 17274/17274/12202 +f 17252/17252/12181 17490/17490/12392 17274/17274/12202 +f 17252/17252/12181 17274/17274/12202 17238/17238/12169 +f 17222/17222/12156 17312/17312/12238 17492/17492/12393 +f 17222/17222/12156 17492/17492/12393 17223/17223/12157 +f 17312/17312/12238 17311/17311/12237 17493/17493/12394 +f 17312/17312/12238 17493/17493/12394 17492/17492/12393 +f 17492/17492/12393 17493/17493/12394 17283/17283/12211 +f 17492/17492/12393 17283/17283/12211 17280/17280/12208 +f 17223/17223/12157 17492/17492/12393 17280/17280/12208 +f 17223/17223/12157 17280/17280/12208 17225/17225/12158 +f 17234/17234/12165 17486/17486/12388 17494/17494/12395 +f 17234/17234/12165 17494/17494/12395 17261/17261/12189 +f 17486/17486/12388 17389/17389/12307 17386/17386/12304 +f 17486/17486/12388 17386/17386/12304 17494/17494/12395 +f 17494/17494/12395 17386/17386/12304 17385/17385/12303 +f 17494/17494/12395 17385/17385/12303 17487/17487/12389 +f 17261/17261/12189 17494/17494/12395 17487/17487/12389 +f 17261/17261/12189 17487/17487/12389 17250/17250/12179 +f 17406/17406/12321 17495/17495/12396 17496/17496/12397 +f 17406/17406/12321 17496/17496/12397 17398/17398/12314 +f 17497/17497/12396 17287/17287/12215 17286/17286/12214 +f 17497/17497/12396 17286/17286/12214 17498/17498/12398 +f 17499/17499/12398 17284/17284/12212 17283/17283/12211 +f 17499/17499/12398 17283/17283/12211 17500/17500/12399 +f 17398/17398/12314 17496/17496/12397 17501/17501/12400 +f 17398/17398/12314 17501/17501/12400 17395/17395/12311 +f 17502/17502/12401 17503/17503/12402 17504/17504/12403 +f 17502/17502/12401 17504/17504/12403 17505/17505/12404 +f 17506/17506/12405 17278/17278/12206 17277/17277/12205 +f 17506/17506/12405 17277/17277/12205 17507/17507/12403 +f 17507/17507/12403 17277/17277/12205 17276/17276/12204 +f 17507/17507/12403 17276/17276/12204 17508/17508/12406 +f 17505/17505/12404 17504/17504/12403 17509/17509/12407 +f 17505/17505/12404 17509/17509/12407 17510/17510/12408 +f 17511/17511/12409 17512/17512/12410 17513/17513/12411 +f 17511/17511/12409 17513/17513/12411 17514/17514/12412 +f 17515/17515/12413 17309/17309/12235 17469/17469/12375 +f 17515/17515/12413 17469/17469/12375 17516/17516/12414 +f 17517/17517/12415 17467/17467/12374 17278/17278/12206 +f 17517/17517/12415 17278/17278/12206 17506/17506/12405 +f 17518/17518/12416 17519/17519/12417 17520/17520/12418 +f 17518/17518/12416 17520/17520/12418 17521/17521/12419 +f 17522/17522/12420 17523/17523/12421 17524/17524/12422 +f 17522/17522/12420 17524/17524/12422 17525/17525/12423 +f 17526/17526/12424 17389/17389/12307 17485/17485/12387 +f 17526/17526/12424 17485/17485/12387 17527/17527/12425 +f 17527/17527/12425 17485/17485/12387 17287/17287/12215 +f 17527/17527/12425 17287/17287/12215 17497/17497/12396 +f 17525/17525/12423 17524/17524/12422 17495/17495/12396 +f 17525/17525/12423 17495/17495/12396 17406/17406/12321 +f 17510/17510/12408 17509/17509/12407 17528/17528/12426 +f 17510/17510/12408 17528/17528/12426 17529/17529/12427 +f 17508/17508/12406 17276/17276/12204 17491/17491/12391 +f 17508/17508/12406 17491/17491/12391 17530/17530/12428 +f 17531/17531/12429 17489/17489/12391 17385/17385/12303 +f 17531/17531/12429 17385/17385/12303 17532/17532/12430 +f 17529/17529/12427 17528/17528/12426 17533/17533/12431 +f 17529/17529/12427 17533/17533/12431 17534/17534/12432 +f 17395/17395/12311 17501/17501/12400 17535/17535/12433 +f 17395/17395/12311 17535/17535/12433 17456/17456/12363 +f 17500/17500/12399 17283/17283/12211 17493/17493/12394 +f 17500/17500/12399 17493/17493/12394 17536/17536/12434 +f 17536/17536/12434 17493/17493/12394 17311/17311/12237 +f 17536/17536/12434 17311/17311/12237 17537/17537/12435 +f 17538/17538/12436 17536/17536/12434 17537/17537/12435 +f 17538/17538/12436 17537/17537/12435 17539/17539/12437 +f 17539/17539/12437 17537/17537/12435 17540/17540/12438 +f 17539/17539/12437 17540/17540/12438 17541/17541/12439 +f 17537/17537/12435 17311/17311/12237 17408/17408/12323 +f 17537/17537/12435 17408/17408/12323 17540/17540/12438 +f 17542/17542/12440 17412/17412/12323 17295/17295/12222 +f 17542/17542/12440 17295/17295/12222 17543/17543/12441 +f 17541/17541/12439 17540/17540/12438 17544/17544/12442 +f 17541/17541/12439 17544/17544/12442 17545/17545/12443 +f 17546/17546/12444 17547/17547/12445 17548/17548/12446 +f 17546/17546/12444 17548/17548/12446 17549/17549/12447 +f 17547/17547/12445 17297/17297/12224 17411/17411/12325 +f 17547/17547/12445 17411/17411/12325 17548/17548/12446 +f 17550/17550/12448 17409/17409/12324 17309/17309/12235 +f 17550/17550/12448 17309/17309/12235 17515/17515/12413 +f 17549/17549/12447 17548/17548/12446 17551/17551/12413 +f 17549/17549/12447 17551/17551/12413 17552/17552/12409 +f 17553/17553/12449 17554/17554/12450 17555/17555/12451 +f 17553/17553/12449 17555/17555/12451 17556/17556/12452 +f 17554/17554/12450 17557/17557/12379 17558/17558/12453 +f 17554/17554/12450 17558/17558/12453 17555/17555/12451 +f 17559/17559/12454 17267/17267/12195 17266/17266/12194 +f 17559/17559/12454 17266/17266/12194 17560/17560/12455 +f 17556/17556/12452 17555/17555/12451 17561/17561/12456 +f 17556/17556/12452 17561/17561/12456 17562/17562/12457 +f 17563/17563/12458 17564/17564/12459 17565/17565/12460 +f 17563/17563/12458 17565/17565/12460 17566/17566/12461 +f 17564/17564/12459 17317/17317/12243 17567/17567/12462 +f 17564/17564/12459 17567/17567/12462 17565/17565/12460 +f 17565/17565/12460 17567/17567/12462 17557/17557/12379 +f 17565/17565/12460 17557/17557/12379 17554/17554/12450 +f 17566/17566/12461 17565/17565/12460 17554/17554/12450 +f 17566/17566/12461 17554/17554/12450 17553/17553/12449 +f 17534/17534/12432 17533/17533/12431 17568/17568/12463 +f 17534/17534/12432 17568/17568/12463 17569/17569/12464 +f 17532/17532/12430 17385/17385/12303 17388/17388/12306 +f 17532/17532/12430 17388/17388/12306 17570/17570/12465 +f 17568/17568/12463 17393/17393/12306 17304/17304/12231 +f 17568/17568/12463 17304/17304/12231 17571/17571/12466 +f 17569/17569/12464 17568/17568/12463 17571/17571/12466 +f 17569/17569/12464 17571/17571/12466 17572/17572/12467 +f 17562/17562/12457 17561/17561/12456 17573/17573/12468 +f 17562/17562/12457 17573/17573/12468 17574/17574/12469 +f 17575/17575/12470 17391/17391/12309 17390/17390/12308 +f 17575/17575/12470 17390/17390/12308 17576/17576/12468 +f 17576/17576/12468 17390/17390/12308 17389/17389/12307 +f 17576/17576/12468 17389/17389/12307 17526/17526/12424 +f 17577/17577/12469 17576/17576/12468 17526/17526/12424 +f 17577/17577/12469 17526/17526/12424 17578/17578/12471 +f 17579/17579/12443 17580/17580/12442 17581/17581/12472 +f 17579/17579/12443 17581/17581/12472 17582/17582/12473 +f 17543/17543/12441 17295/17295/12222 17320/17320/12245 +f 17543/17543/12441 17320/17320/12245 17583/17583/12474 +f 17581/17581/12472 17318/17318/12244 17317/17317/12243 +f 17581/17581/12472 17317/17317/12243 17564/17564/12459 +f 17582/17582/12473 17581/17581/12472 17564/17564/12459 +f 17582/17582/12473 17564/17564/12459 17563/17563/12458 +f 17452/17452/12360 17584/17584/12475 17585/17585/12476 +f 17452/17452/12360 17585/17585/12476 17444/17444/12354 +f 17586/17586/12477 17326/17326/12250 17464/17464/12371 +f 17586/17586/12477 17464/17464/12371 17587/17587/12476 +f 17587/17587/12476 17464/17464/12371 17463/17463/12370 +f 17587/17587/12476 17463/17463/12370 17588/17588/12478 +f 17444/17444/12354 17585/17585/12476 17589/17589/12479 +f 17444/17444/12354 17589/17589/12479 17433/17433/12343 +f 17433/17433/12343 17589/17589/12479 17590/17590/12480 +f 17433/17433/12343 17590/17590/12480 17430/17430/12342 +f 17591/17591/12481 17592/17592/12482 17479/17479/12383 +f 17591/17591/12481 17479/17479/12383 17593/17593/12483 +f 17593/17593/12483 17479/17479/12383 17297/17297/12224 +f 17593/17593/12483 17297/17297/12224 17547/17547/12445 +f 17430/17430/12342 17590/17590/12480 17594/17594/12484 +f 17430/17430/12342 17594/17594/12484 17595/17595/12335 +f 17572/17572/12467 17571/17571/12466 17596/17596/12485 +f 17572/17572/12467 17596/17596/12485 17597/17597/12486 +f 17571/17571/12466 17304/17304/12231 17327/17327/12251 +f 17571/17571/12466 17327/17327/12251 17596/17596/12485 +f 17596/17596/12485 17327/17327/12251 17326/17326/12250 +f 17596/17596/12485 17326/17326/12250 17586/17586/12477 +f 17598/17598/12487 17599/17599/12488 17584/17584/12475 +f 17598/17598/12487 17584/17584/12475 17452/17452/12360 +f 17600/17600/12489 17601/17601/12490 17602/17602/12491 +f 17600/17600/12489 17602/17602/12491 17603/17603/12492 +f 17601/17601/12490 17604/17604/12493 17605/17605/12494 +f 17601/17601/12490 17605/17605/12494 17602/17602/12491 +f 17602/17602/12491 17605/17605/12494 17606/17606/12495 +f 17602/17602/12491 17606/17606/12495 17607/17607/12496 +f 17603/17603/12492 17602/17602/12491 17607/17607/12496 +f 17603/17603/12492 17607/17607/12496 17608/17608/12497 +f 17449/17449/12357 17609/17609/12498 17610/17610/12499 +f 17449/17449/12357 17610/17610/12499 17611/17611/12500 +f 17609/17609/12498 17612/17612/12501 17613/17613/12502 +f 17609/17609/12498 17613/17613/12502 17610/17610/12499 +f 17610/17610/12499 17613/17613/12502 17614/17614/12503 +f 17610/17610/12499 17614/17614/12503 17615/17615/12504 +f 17611/17611/12500 17610/17610/12499 17615/17615/12504 +f 17611/17611/12500 17615/17615/12504 17616/17616/12505 +f 17400/17400/12316 17617/17617/12506 17618/17618/12507 +f 17400/17400/12316 17618/17618/12507 17401/17401/12317 +f 17617/17617/12506 17619/17619/12508 17620/17620/12509 +f 17617/17617/12506 17620/17620/12509 17618/17618/12507 +f 17618/17618/12507 17620/17620/12509 17621/17621/12510 +f 17618/17618/12507 17621/17621/12510 17622/17622/12511 +f 17401/17401/12317 17618/17618/12507 17622/17622/12511 +f 17401/17401/12317 17622/17622/12511 17403/17403/12318 +f 17417/17417/12330 17623/17623/12512 17624/17624/12513 +f 17417/17417/12330 17624/17624/12513 17418/17418/12331 +f 17623/17623/12512 17625/17625/12514 17626/17626/12515 +f 17623/17623/12512 17626/17626/12515 17624/17624/12513 +f 17624/17624/12513 17626/17626/12515 17627/17627/12516 +f 17624/17624/12513 17627/17627/12516 17628/17628/12517 +f 17418/17418/12331 17624/17624/12513 17628/17628/12517 +f 17418/17418/12331 17628/17628/12517 17419/17419/12332 +f 17426/17426/12332 17629/17629/12518 17630/17630/12519 +f 17426/17426/12332 17630/17630/12519 17427/17427/12339 +f 17629/17629/12518 17631/17631/12520 17632/17632/12521 +f 17629/17629/12518 17632/17632/12521 17630/17630/12519 +f 17630/17630/12519 17632/17632/12521 17633/17633/12522 +f 17630/17630/12519 17633/17633/12522 17634/17634/12523 +f 17427/17427/12339 17630/17630/12519 17634/17634/12523 +f 17427/17427/12339 17634/17634/12523 17428/17428/12340 +f 17438/17438/12348 17635/17635/12524 17636/17636/12525 +f 17438/17438/12348 17636/17636/12525 17439/17439/12349 +f 17635/17635/12524 17637/17637/12526 17638/17638/12527 +f 17635/17635/12524 17638/17638/12527 17636/17636/12525 +f 17636/17636/12525 17638/17638/12527 17639/17639/12528 +f 17636/17636/12525 17639/17639/12528 17640/17640/12529 +f 17439/17439/12349 17636/17636/12525 17640/17640/12529 +f 17439/17439/12349 17640/17640/12529 17440/17440/12350 +f 17452/17452/12360 17451/17451/12359 17641/17641/12530 +f 17452/17452/12360 17641/17641/12530 17598/17598/12487 +f 17450/17450/12358 17449/17449/12357 17611/17611/12500 +f 17450/17450/12358 17611/17611/12500 17642/17642/12531 +f 17642/17642/12531 17611/17611/12500 17616/17616/12505 +f 17642/17642/12531 17616/17616/12505 17643/17643/12532 +f 17598/17598/12487 17641/17641/12530 17644/17644/12532 +f 17598/17598/12487 17644/17644/12532 17645/17645/12533 +f 17646/17646/12534 17647/17647/12535 17648/17648/12536 +f 17646/17646/12534 17648/17648/12536 17649/17649/12537 +f 17647/17647/12535 17600/17600/12489 17603/17603/12492 +f 17647/17647/12535 17603/17603/12492 17648/17648/12536 +f 17650/17650/12538 17651/17651/12539 17652/17652/12540 +f 17650/17650/12538 17652/17652/12540 17653/17653/12541 +f 17654/17654/12542 17650/17650/12538 17653/17653/12541 +f 17654/17654/12542 17653/17653/12541 17655/17655/12543 +f 17510/17510/12408 17656/17656/12544 17657/17657/12545 +f 17510/17510/12408 17657/17657/12545 17505/17505/12404 +f 17656/17656/12544 17658/17658/12546 17659/17659/12547 +f 17656/17656/12544 17659/17659/12547 17657/17657/12545 +f 17657/17657/12545 17659/17659/12547 17660/17660/12548 +f 17657/17657/12545 17660/17660/12548 17661/17661/12549 +f 17505/17505/12404 17657/17657/12545 17661/17661/12549 +f 17505/17505/12404 17661/17661/12549 17502/17502/12401 +f 17662/17662/12550 17663/17663/12541 17664/17664/12551 +f 17662/17662/12550 17664/17664/12551 17665/17665/12461 +f 17663/17663/12541 17608/17608/12497 17666/17666/12552 +f 17663/17663/12541 17666/17666/12552 17664/17664/12551 +f 17664/17664/12551 17666/17666/12552 17667/17667/12553 +f 17664/17664/12551 17667/17667/12553 17668/17668/12554 +f 17665/17665/12461 17664/17664/12551 17668/17668/12554 +f 17665/17665/12461 17668/17668/12554 17669/17669/12458 +f 17502/17502/12401 17661/17661/12549 17670/17670/12555 +f 17502/17502/12401 17670/17670/12555 17671/17671/12556 +f 17661/17661/12549 17660/17660/12548 17672/17672/12557 +f 17661/17661/12549 17672/17672/12557 17670/17670/12555 +f 17670/17670/12555 17672/17672/12557 17417/17417/12330 +f 17670/17670/12555 17417/17417/12330 17414/17414/12327 +f 17671/17671/12556 17670/17670/12555 17414/17414/12327 +f 17671/17671/12556 17414/17414/12327 17413/17413/12326 +f 17673/17673/12467 17674/17674/12558 17675/17675/12559 +f 17673/17673/12467 17675/17675/12559 17676/17676/12560 +f 17674/17674/12558 17677/17677/12561 17678/17678/12562 +f 17674/17674/12558 17678/17678/12562 17675/17675/12559 +f 17675/17675/12559 17678/17678/12562 17679/17679/12563 +f 17675/17675/12559 17679/17679/12563 17680/17680/12564 +f 17676/17676/12560 17675/17675/12559 17680/17680/12564 +f 17676/17676/12560 17680/17680/12564 17681/17681/12565 +f 17682/17682/12321 17683/17683/12320 17684/17684/12566 +f 17682/17682/12321 17684/17684/12566 17685/17685/12567 +f 17683/17683/12320 17686/17686/12568 17687/17687/12569 +f 17683/17683/12320 17687/17687/12569 17684/17684/12566 +f 17684/17684/12566 17687/17687/12569 17688/17688/12570 +f 17684/17684/12566 17688/17688/12570 17689/17689/12571 +f 17685/17685/12567 17684/17684/12566 17689/17689/12571 +f 17685/17685/12567 17689/17689/12571 17690/17690/12572 +f 17690/17690/12572 17689/17689/12571 17691/17691/12573 +f 17690/17690/12572 17691/17691/12573 17692/17692/12574 +f 17689/17689/12571 17688/17688/12570 17693/17693/12575 +f 17689/17689/12571 17693/17693/12575 17691/17691/12573 +f 17694/17694/12576 17695/17695/12575 17600/17600/12489 +f 17694/17694/12576 17600/17600/12489 17647/17647/12535 +f 17696/17696/12574 17694/17694/12576 17647/17647/12535 +f 17696/17696/12574 17647/17647/12535 17646/17646/12534 +f 17681/17681/12565 17680/17680/12564 17697/17697/12577 +f 17681/17681/12565 17697/17697/12577 17698/17698/12578 +f 17680/17680/12564 17679/17679/12563 17699/17699/12579 +f 17680/17680/12564 17699/17699/12579 17697/17697/12577 +f 17700/17700/12577 17701/17701/12579 17658/17658/12546 +f 17700/17700/12577 17658/17658/12546 17656/17656/12544 +f 17529/17529/12427 17700/17700/12577 17656/17656/12544 +f 17529/17529/12427 17656/17656/12544 17510/17510/12408 +f 17669/17669/12458 17668/17668/12554 17702/17702/12580 +f 17669/17669/12458 17702/17702/12580 17703/17703/12581 +f 17668/17668/12554 17667/17667/12553 17704/17704/12582 +f 17668/17668/12554 17704/17704/12582 17702/17702/12580 +f 17705/17705/12580 17706/17706/12582 17438/17438/12348 +f 17705/17705/12580 17438/17438/12348 17435/17435/12345 +f 17707/17707/12581 17705/17705/12580 17435/17435/12345 +f 17707/17707/12581 17435/17435/12345 17434/17434/12344 +f 17658/17658/12546 17708/17708/12583 17709/17709/12584 +f 17658/17658/12546 17709/17709/12584 17659/17659/12547 +f 17708/17708/12583 17710/17710/12585 17711/17711/12586 +f 17708/17708/12583 17711/17711/12586 17709/17709/12584 +f 17709/17709/12584 17711/17711/12586 17712/17712/12587 +f 17709/17709/12584 17712/17712/12587 17713/17713/12588 +f 17659/17659/12547 17709/17709/12584 17713/17713/12588 +f 17659/17659/12547 17713/17713/12588 17660/17660/12548 +f 17608/17608/12497 17607/17607/12496 17714/17714/12589 +f 17608/17608/12497 17714/17714/12589 17666/17666/12552 +f 17607/17607/12496 17606/17606/12495 17715/17715/12590 +f 17607/17607/12496 17715/17715/12590 17714/17714/12589 +f 17714/17714/12589 17715/17715/12590 17716/17716/12591 +f 17714/17714/12589 17716/17716/12591 17717/17717/12592 +f 17666/17666/12552 17714/17714/12589 17717/17717/12592 +f 17666/17666/12552 17717/17717/12592 17667/17667/12553 +f 17660/17660/12548 17713/17713/12588 17718/17718/12593 +f 17660/17660/12548 17718/17718/12593 17672/17672/12557 +f 17713/17713/12588 17712/17712/12587 17719/17719/12594 +f 17713/17713/12588 17719/17719/12594 17718/17718/12593 +f 17718/17718/12593 17719/17719/12594 17625/17625/12514 +f 17718/17718/12593 17625/17625/12514 17623/17623/12512 +f 17672/17672/12557 17718/17718/12593 17623/17623/12512 +f 17672/17672/12557 17623/17623/12512 17417/17417/12330 +f 17677/17677/12561 17720/17720/12595 17721/17721/12596 +f 17677/17677/12561 17721/17721/12596 17678/17678/12562 +f 17720/17720/12595 17722/17722/12597 17723/17723/12598 +f 17720/17720/12595 17723/17723/12598 17721/17721/12596 +f 17721/17721/12596 17723/17723/12598 17724/17724/12599 +f 17721/17721/12596 17724/17724/12599 17725/17725/12600 +f 17678/17678/12562 17721/17721/12596 17725/17725/12600 +f 17678/17678/12562 17725/17725/12600 17679/17679/12563 +f 17403/17403/12318 17622/17622/12511 17726/17726/12601 +f 17403/17403/12318 17726/17726/12601 17727/17727/12569 +f 17622/17622/12511 17621/17621/12510 17728/17728/12602 +f 17622/17622/12511 17728/17728/12602 17726/17726/12601 +f 17729/17729/12603 17730/17730/12604 17731/17731/12605 +f 17729/17729/12603 17731/17731/12605 17732/17732/12606 +f 17687/17687/12569 17729/17729/12603 17732/17732/12606 +f 17687/17687/12569 17732/17732/12606 17688/17688/12570 +f 17688/17688/12570 17732/17732/12606 17733/17733/12607 +f 17688/17688/12570 17733/17733/12607 17693/17693/12575 +f 17732/17732/12606 17731/17731/12605 17734/17734/12608 +f 17732/17732/12606 17734/17734/12608 17733/17733/12607 +f 17735/17735/12607 17736/17736/12609 17604/17604/12493 +f 17735/17735/12607 17604/17604/12493 17601/17601/12490 +f 17695/17695/12575 17735/17735/12607 17601/17601/12490 +f 17695/17695/12575 17601/17601/12490 17600/17600/12489 +f 17679/17679/12563 17725/17725/12600 17737/17737/12610 +f 17679/17679/12563 17737/17737/12610 17699/17699/12579 +f 17725/17725/12600 17724/17724/12599 17738/17738/12611 +f 17725/17725/12600 17738/17738/12611 17737/17737/12610 +f 17739/17739/12610 17740/17740/12612 17710/17710/12585 +f 17739/17739/12610 17710/17710/12585 17708/17708/12583 +f 17701/17701/12579 17739/17739/12610 17708/17708/12583 +f 17701/17701/12579 17708/17708/12583 17658/17658/12546 +f 17667/17667/12553 17717/17717/12592 17741/17741/12613 +f 17667/17667/12553 17741/17741/12613 17704/17704/12582 +f 17717/17717/12592 17716/17716/12591 17742/17742/12614 +f 17717/17717/12592 17742/17742/12614 17741/17741/12613 +f 17743/17743/12615 17744/17744/12616 17637/17637/12526 +f 17743/17743/12615 17637/17637/12526 17635/17635/12524 +f 17706/17706/12582 17743/17743/12615 17635/17635/12524 +f 17706/17706/12582 17635/17635/12524 17438/17438/12348 +f 17745/17745/12617 17746/17746/12529 17747/17747/12618 +f 17745/17745/12617 17747/17747/12618 17748/17748/12366 +f 17640/17640/12529 17639/17639/12528 17749/17749/12619 +f 17640/17640/12529 17749/17749/12619 17750/17750/12620 +f 17750/17750/12620 17749/17749/12619 17751/17751/12621 +f 17750/17750/12620 17751/17751/12621 17752/17752/12622 +f 17459/17459/12366 17753/17753/12623 17617/17617/12506 +f 17459/17459/12366 17617/17617/12506 17400/17400/12316 +f 17446/17446/12340 17754/17754/12624 17755/17755/12625 +f 17446/17446/12340 17755/17755/12625 17447/17447/12355 +f 17754/17754/12624 17756/17756/12626 17757/17757/12627 +f 17754/17754/12624 17757/17757/12627 17755/17755/12625 +f 17755/17755/12625 17757/17757/12627 17612/17612/12501 +f 17755/17755/12625 17612/17612/12501 17609/17609/12498 +f 17447/17447/12355 17755/17755/12625 17609/17609/12498 +f 17447/17447/12355 17609/17609/12498 17449/17449/12357 +f 16664/16664/11670 16663/16663/11669 17758/17758/12628 +f 16664/16664/11670 17758/17758/12628 16974/16974/11935 +f 16663/16663/11669 16662/16662/11668 17759/17759/12629 +f 16663/16663/11669 17759/17759/12629 17758/17758/12628 +f 17758/17758/12628 17759/17759/12629 17760/17760/12630 +f 17758/17758/12628 17760/17760/12630 17761/17761/12631 +f 16974/16974/11935 17758/17758/12628 17761/17761/12631 +f 16974/16974/11935 17761/17761/12631 16975/16975/11936 +f 15195/15195/10389 17762/17762/12632 17763/17763/12633 +f 15195/15195/10389 17763/17763/12633 15196/15196/10390 +f 17764/17764/12634 17765/17765/12635 17763/17763/12633 +f 17764/17764/12634 17763/17763/12633 17762/17762/12632 +f 17766/17766/12636 17767/17767/12637 17763/17763/12633 +f 17766/17766/12636 17763/17763/12633 17765/17765/12635 +f 14971/14971/10183 17768/17768/12638 17763/17763/12633 +f 14971/14971/10183 17763/17763/12633 17767/17767/12637 +f 14982/14982/10193 15196/15196/10390 17763/17763/12633 +f 14982/14982/10193 17763/17763/12633 17768/17768/12638 +f 15135/15135/10337 15163/15163/10361 17769/17769/12639 +f 15135/15135/10337 17769/17769/12639 17770/17770/12640 +f 15162/15162/10361 15161/15161/10360 17771/17771/12641 +f 15162/15162/10361 17771/17771/12641 17772/17772/12642 +f 17772/17772/12642 17771/17771/12641 15208/15208/10401 +f 17772/17772/12642 15208/15208/10401 15207/15207/10399 +f 17770/17770/12640 17769/17769/12639 15205/15205/10399 +f 17770/17770/12640 15205/15205/10399 15180/15180/10376 +f 17773/17773/12643 17774/17774/12644 17775/17775/12645 +f 17773/17773/12643 17775/17775/12645 17776/17776/12646 +f 17777/17777/12644 17778/17778/12647 17779/17779/12648 +f 17777/17777/12644 17779/17779/12648 17780/17780/12649 +f 17781/17781/12650 17782/17782/12648 17783/17783/12651 +f 17781/17781/12650 17783/17783/12651 17784/17784/12652 +f 17785/17785/12646 17781/17781/12650 17784/17784/12652 +f 17785/17785/12646 17784/17784/12652 15217/15217/10409 +f 15146/15146/10347 15153/15153/10353 17786/17786/12653 +f 15146/15146/10347 17786/17786/12653 17787/17787/12654 +f 15152/15152/10353 15151/15151/10352 17788/17788/12655 +f 15152/15152/10353 17788/17788/12655 17789/17789/12656 +f 17789/17789/12656 17788/17788/12655 15195/15195/10389 +f 17789/17789/12656 15195/15195/10389 15194/15194/10388 +f 17787/17787/12654 17786/17786/12653 15192/15192/10386 +f 17787/17787/12654 15192/15192/10386 15190/15190/10384 +f 15128/15128/10330 15147/15147/10348 17790/17790/12657 +f 15128/15128/10330 17790/17790/12657 17791/17791/12658 +f 15147/15147/10348 15146/15146/10347 17787/17787/12654 +f 15147/15147/10348 17787/17787/12654 17790/17790/12657 +f 17790/17790/12657 17787/17787/12654 15190/15190/10384 +f 17790/17790/12657 15190/15190/10384 15188/15188/10382 +f 17791/17791/12658 17790/17790/12657 15188/15188/10382 +f 17791/17791/12658 15188/15188/10382 15173/15173/10370 +f 15143/15143/10344 15142/15142/10343 17792/17792/12659 +f 15143/15143/10344 17792/17792/12659 15200/15200/10394 +f 15141/15141/10343 15137/15137/10339 17793/17793/12660 +f 15141/15141/10343 17793/17793/12660 17794/17794/12659 +f 17794/17794/12659 17793/17793/12660 15176/15176/10372 +f 17794/17794/12659 15176/15176/10372 15186/15186/10379 +f 15200/15200/10394 17792/17792/12659 15183/15183/10379 +f 15200/15200/10394 15183/15183/10379 15182/15182/10378 +f 15137/15137/10339 15136/15136/10338 17795/17795/12661 +f 15137/15137/10339 17795/17795/12661 17793/17793/12660 +f 15136/15136/10338 15135/15135/10337 17770/17770/12640 +f 15136/15136/10338 17770/17770/12640 17795/17795/12661 +f 17795/17795/12661 17770/17770/12640 15180/15180/10376 +f 17795/17795/12661 15180/15180/10376 15177/15177/10373 +f 17793/17793/12660 17795/17795/12661 15177/15177/10373 +f 17793/17793/12660 15177/15177/10373 15176/15176/10372 +f 15131/15131/10333 15130/15130/10332 17796/17796/12662 +f 15131/15131/10333 17796/17796/12662 15213/15213/10405 +f 15129/15129/10331 15128/15128/10330 17791/17791/12658 +f 15129/15129/10331 17791/17791/12658 17797/17797/12663 +f 17797/17797/12663 17791/17791/12658 15173/15173/10370 +f 17797/17797/12663 15173/15173/10370 15172/15172/10367 +f 15213/15213/10405 17796/17796/12662 15169/15169/10367 +f 15213/15213/10405 15169/15169/10367 15168/15168/10366 +f 17766/17766/12636 17798/17798/12664 17799/17799/12665 +f 17766/17766/12636 17799/17799/12665 17767/17767/12637 +f 15202/15202/10396 15201/15201/10395 17799/17799/12665 +f 15202/15202/10396 17799/17799/12665 17798/17798/12664 +f 15182/15182/10378 15185/15185/10381 17799/17799/12665 +f 15182/15182/10378 17799/17799/12665 15201/15201/10395 +f 14975/14975/10187 14972/14972/10184 17799/17799/12665 +f 14975/14975/10187 17799/17799/12665 15185/15185/10381 +f 14971/14971/10183 17767/17767/12637 17799/17799/12665 +f 14971/14971/10183 17799/17799/12665 14972/14972/10184 +f 17800/17800/12666 17801/17801/12667 17802/17802/12668 +f 17800/17800/12666 17802/17802/12668 17803/17803/12669 +f 15215/15215/10407 15214/15214/10406 17802/17802/12668 +f 15215/15215/10407 17802/17802/12668 17801/17801/12667 +f 15168/15168/10366 15171/15171/10369 17802/17802/12668 +f 15168/15168/10366 17802/17802/12668 15214/15214/10406 +f 14961/14961/10173 14958/14958/10170 17802/17802/12668 +f 14961/14961/10173 17802/17802/12668 15171/15171/10369 +f 14957/14957/10169 17803/17803/12669 17802/17802/12668 +f 14957/14957/10169 17802/17802/12668 14958/14958/10170 +f 15161/15161/10360 17804/17804/12670 17805/17805/12671 +f 15161/15161/10360 17805/17805/12671 17771/17771/12641 +f 15167/15167/10365 15212/15212/10404 17805/17805/12671 +f 15167/15167/10365 17805/17805/12671 17804/17804/12670 +f 15217/15217/10409 17784/17784/12652 17805/17805/12671 +f 15217/15217/10409 17805/17805/12671 15212/15212/10404 +f 17783/17783/12651 17806/17806/12672 17805/17805/12671 +f 17783/17783/12651 17805/17805/12671 17784/17784/12652 +f 15208/15208/10401 17771/17771/12641 17805/17805/12671 +f 15208/15208/10401 17805/17805/12671 17806/17806/12672 +f 15151/15151/10352 17807/17807/12673 17808/17808/12674 +f 15151/15151/10352 17808/17808/12674 17788/17788/12655 +f 15157/15157/10357 15199/15199/10393 17808/17808/12674 +f 15157/15157/10357 17808/17808/12674 17807/17807/12673 +f 15204/15204/10398 17809/17809/12675 17808/17808/12674 +f 15204/15204/10398 17808/17808/12674 15199/15199/10393 +f 17764/17764/12634 17762/17762/12632 17808/17808/12674 +f 17764/17764/12634 17808/17808/12674 17809/17809/12675 +f 15195/15195/10389 17788/17788/12655 17808/17808/12674 +f 15195/15195/10389 17808/17808/12674 17762/17762/12632 +f 15058/15058/10263 17810/17810/12676 17811/17811/12677 +f 15058/15058/10263 17811/17811/12677 15159/15159/10359 +f 17810/17810/12676 15066/15066/10271 15165/15165/10363 +f 17810/17810/12676 15165/15165/10363 17811/17811/12677 +f 17811/17811/12677 15165/15165/10363 15167/15167/10365 +f 17811/17811/12677 15167/15167/10365 17804/17804/12670 +f 15159/15159/10359 17811/17811/12677 17804/17804/12670 +f 15159/15159/10359 17804/17804/12670 15161/15161/10360 +f 15043/15043/10249 17812/17812/12678 17813/17813/12679 +f 15043/15043/10249 17813/17813/12679 15149/15149/10350 +f 17812/17812/12678 15051/15051/10257 15155/15155/10355 +f 17812/17812/12678 15155/15155/10355 17813/17813/12679 +f 17813/17813/12679 15155/15155/10355 15157/15157/10357 +f 17813/17813/12679 15157/15157/10357 17807/17807/12673 +f 15149/15149/10350 17813/17813/12679 17807/17807/12673 +f 15149/15149/10350 17807/17807/12673 15151/15151/10352 +f 14208/14208/9509 17814/17814/12680 17815/17815/12681 +f 14208/14208/9509 17815/17815/12681 17816/17816/12682 +f 14460/14460/9730 17817/17817/12683 17815/17815/12681 +f 14460/14460/9730 17815/17815/12681 17814/17814/12680 +f 15108/15108/10311 17818/17818/12684 17815/17815/12681 +f 15108/15108/10311 17815/17815/12681 17817/17817/12683 +f 17819/17819/12685 17820/17820/12686 17815/17815/12681 +f 17819/17819/12685 17815/17815/12681 17818/17818/12684 +f 17821/17821/12687 17816/17816/12682 17815/17815/12681 +f 17821/17821/12687 17815/17815/12681 17820/17820/12686 +f 14300/14300/9595 14299/14299/9594 17822/17822/12688 +f 14300/14300/9595 17822/17822/12688 17823/17823/12689 +f 14298/14298/9593 17824/17824/12690 17822/17822/12688 +f 14298/14298/9593 17822/17822/12688 14299/14299/9594 +f 15118/15118/10321 17825/17825/12691 17822/17822/12688 +f 15118/15118/10321 17822/17822/12688 17824/17824/12690 +f 17826/17826/12692 17827/17827/12693 17822/17822/12688 +f 17826/17826/12692 17822/17822/12688 17825/17825/12691 +f 17828/17828/12694 17823/17823/12689 17822/17822/12688 +f 17828/17828/12694 17822/17822/12688 17827/17827/12693 +f 15055/15055/10261 15095/15095/10299 17829/17829/12695 +f 15055/15055/10261 17829/17829/12695 15056/15056/10262 +f 15095/15095/10299 15061/15061/10266 15064/15064/10269 +f 15095/15095/10299 15064/15064/10269 17829/17829/12695 +f 17829/17829/12695 15064/15064/10269 15066/15066/10271 +f 17829/17829/12695 15066/15066/10271 17810/17810/12676 +f 15056/15056/10262 17829/17829/12695 17810/17810/12676 +f 15056/15056/10262 17810/17810/12676 15058/15058/10263 +f 15040/15040/10247 17830/17830/12696 17831/17831/12697 +f 15040/15040/10247 17831/17831/12697 15041/15041/10248 +f 17830/17830/12696 15046/15046/10252 15049/15049/10255 +f 17830/17830/12696 15049/15049/10255 17831/17831/12697 +f 17831/17831/12697 15049/15049/10255 15051/15051/10257 +f 17831/17831/12697 15051/15051/10257 17812/17812/12678 +f 15041/15041/10248 17831/17831/12697 17812/17812/12678 +f 15041/15041/10248 17812/17812/12678 15043/15043/10249 +f 14982/14982/10193 17768/17768/12638 17832/17832/12698 +f 14982/14982/10193 17832/17832/12698 14983/14983/10194 +f 17768/17768/12638 14971/14971/10183 14974/14974/10186 +f 17768/17768/12638 14974/14974/10186 17832/17832/12698 +f 17832/17832/12698 14974/14974/10186 14890/14890/10107 +f 17832/17832/12698 14890/14890/10107 17833/17833/12699 +f 14983/14983/10194 17832/17832/12698 17833/17833/12699 +f 14983/14983/10194 17833/17833/12699 14885/14885/10103 +f 14968/14968/10180 17834/17834/12700 17835/17835/12701 +f 14968/14968/10180 17835/17835/12701 14969/14969/10181 +f 17834/17834/12700 14957/14957/10169 14960/14960/10172 +f 17834/17834/12700 14960/14960/10172 17835/17835/12701 +f 17835/17835/12701 14960/14960/10172 14904/14904/10121 +f 17835/17835/12701 14904/14904/10121 17836/17836/12702 +f 14969/14969/10181 17835/17835/12701 17836/17836/12702 +f 14969/14969/10181 17836/17836/12702 14898/14898/10115 +f 14901/14901/10118 17837/17837/12703 17838/17838/12704 +f 14901/14901/10118 17838/17838/12704 14950/14950/10164 +f 17837/17837/12703 14909/14909/10126 17839/17839/10156 +f 17837/17837/12703 17839/17839/10156 17838/17838/12704 +f 17840/17840/12705 14941/14941/10156 14944/14944/10158 +f 17840/17840/12705 14944/14944/10158 17841/17841/10140 +f 17842/17842/10164 17840/17840/12705 17841/17841/10140 +f 17842/17842/10164 17841/17841/10140 17843/17843/12706 +f 14920/14920/10137 14917/14917/10134 17844/17844/12707 +f 14920/14920/10137 17844/17844/12707 17845/17845/10152 +f 14917/14917/10134 14916/14916/10133 14927/14927/10144 +f 14917/14917/10134 14927/14927/10144 17844/17844/12707 +f 17844/17844/12707 14927/14927/10144 14931/14931/10148 +f 17844/17844/12707 14931/14931/10148 17846/17846/12708 +f 17845/17845/10152 17844/17844/12707 17846/17846/12708 +f 17845/17845/10152 17846/17846/12708 17847/17847/12709 +f 14862/14862/10083 14925/14925/10142 17848/17848/12710 +f 14862/14862/10083 17848/17848/12710 14863/14863/10084 +f 14925/14925/10142 14916/14916/10133 14919/14919/10136 +f 14925/14925/10142 14919/14919/10136 17848/17848/12710 +f 17848/17848/12710 14919/14919/10136 14924/14924/10141 +f 17848/17848/12710 14924/14924/10141 17849/17849/10157 +f 14863/14863/10084 17848/17848/12710 17849/17849/10157 +f 14863/14863/10084 17849/17849/10157 14865/14865/10086 +f 14850/14850/10074 17850/17850/12711 17851/17851/12712 +f 14850/14850/10074 17851/17851/12712 14851/14851/10075 +f 17850/17850/12711 14876/14876/10094 14911/14911/10128 +f 17850/17850/12711 14911/14911/10128 17851/17851/12712 +f 17851/17851/12712 14911/14911/10128 14915/14915/10132 +f 17851/17851/12712 14915/14915/10132 17852/17852/12713 +f 14851/14851/10075 17851/17851/12712 17852/17852/12713 +f 14851/14851/10075 17852/17852/12713 14853/14853/10077 +f 14898/14898/10115 17836/17836/12702 17853/17853/12714 +f 14898/14898/10115 17853/17853/12714 14899/14899/10116 +f 17836/17836/12702 14904/14904/10121 14907/14907/10124 +f 17836/17836/12702 14907/14907/10124 17853/17853/12714 +f 17853/17853/12714 14907/14907/10124 14909/14909/10126 +f 17853/17853/12714 14909/14909/10126 17837/17837/12703 +f 14899/14899/10116 17853/17853/12714 17837/17837/12703 +f 14899/14899/10116 17837/17837/12703 14901/14901/10118 +f 14885/14885/10103 17833/17833/12699 17854/17854/12715 +f 14885/14885/10103 17854/17854/12715 14886/14886/10104 +f 17833/17833/12699 14890/14890/10107 14893/14893/10110 +f 17833/17833/12699 14893/14893/10110 17854/17854/12715 +f 17854/17854/12715 14893/14893/10110 14894/14894/10111 +f 17854/17854/12715 14894/14894/10111 17855/17855/12716 +f 14886/14886/10104 17854/17854/12715 17855/17855/12716 +f 14886/14886/10104 17855/17855/12716 17856/17856/10071 +f 14847/14847/10071 17857/17857/12716 17858/17858/12717 +f 14847/14847/10071 17858/17858/12717 14848/14848/10072 +f 17857/17857/12716 14866/14866/10087 14869/14869/10090 +f 17857/17857/12716 14869/14869/10090 17858/17858/12717 +f 17858/17858/12717 14869/14869/10090 14876/14876/10094 +f 17858/17858/12717 14876/14876/10094 17850/17850/12711 +f 14848/14848/10072 17858/17858/12717 17850/17850/12711 +f 14848/14848/10072 17850/17850/12711 14850/14850/10074 +f 14405/14405/9686 14402/14402/9683 17859/17859/12718 +f 14405/14405/9686 17859/17859/12718 17860/17860/10031 +f 14402/14402/9683 14401/14401/9682 14820/14820/10046 +f 14402/14402/9683 14820/14820/10046 17859/17859/12718 +f 17859/17859/12718 14820/14820/10046 14400/14400/9681 +f 17859/17859/12718 14400/14400/9681 14398/14398/9680 +f 17860/17860/10031 17859/17859/12718 14398/14398/9680 +f 17860/17860/10031 14398/14398/9680 14397/14397/9679 +f 14821/14821/10047 14818/14818/10044 17861/17861/12719 +f 14821/14821/10047 17861/17861/12719 17862/17862/9978 +f 14818/14818/10044 14401/14401/9682 14404/14404/9685 +f 14818/14818/10044 14404/14404/9685 17861/17861/12719 +f 17863/17863/12719 14411/14411/9691 14339/14339/9631 +f 17863/17863/12719 14339/14339/9631 14338/14338/9630 +f 14748/14748/9978 17863/17863/12719 14338/14338/9630 +f 14748/14748/9978 14338/14338/9630 14337/14337/9629 +f 14248/14248/9546 14247/14247/9545 17864/17864/12720 +f 14248/14248/9546 17864/17864/12720 14441/14441/9713 +f 14247/14247/9545 14246/14246/9544 14392/14392/9675 +f 14247/14247/9545 14392/14392/9675 17864/17864/12720 +f 17865/17865/12721 14399/14399/9675 14400/14400/9681 +f 17865/17865/12721 14400/14400/9681 14824/14824/10049 +f 17866/17866/9715 17865/17865/12721 14824/14824/10049 +f 17866/17866/9715 14824/14824/10049 14823/14823/9716 +f 14323/14323/9615 14320/14320/9612 17867/17867/12722 +f 14323/14323/9615 17867/17867/12722 14742/14742/9973 +f 14320/14320/9612 14319/14319/9611 14342/14342/9634 +f 14320/14320/9612 14342/14342/9634 17867/17867/12722 +f 17867/17867/12722 14342/14342/9634 14331/14331/9623 +f 17867/17867/12722 14331/14331/9623 17868/17868/12723 +f 14742/14742/9973 17867/17867/12722 17868/17868/12723 +f 14742/14742/9973 17868/17868/12723 14689/14689/9927 +f 14689/14689/9927 17868/17868/12723 17869/17869/12724 +f 14689/14689/9927 17869/17869/12724 14690/14690/9928 +f 17868/17868/12723 14331/14331/9623 14334/14334/9626 +f 17868/17868/12723 14334/14334/9626 17869/17869/12724 +f 17869/17869/12724 14334/14334/9626 14339/14339/9631 +f 17869/17869/12724 14339/14339/9631 14410/14410/9690 +f 14690/14690/9928 17869/17869/12724 14410/14410/9690 +f 14690/14690/9928 14410/14410/9690 14409/14409/9689 +f 14760/14760/9989 17870/17870/12725 17871/17871/12726 +f 14760/14760/9989 17871/17871/12726 14761/14761/9990 +f 17870/17870/12725 14267/14267/9562 14329/14329/9621 +f 17870/17870/12725 14329/14329/9621 17871/17871/12726 +f 17871/17871/12726 14329/14329/9621 14268/14268/9563 +f 17871/17871/12726 14268/14268/9563 17872/17872/12727 +f 14761/14761/9990 17871/17871/12726 17872/17872/12727 +f 14761/14761/9990 17872/17872/12727 14618/14618/9868 +f 14589/14589/9843 17873/17873/12728 17874/17874/12729 +f 14589/14589/9843 17874/17874/12729 14755/14755/9984 +f 17873/17873/12728 14309/14309/9604 14326/14326/9618 +f 17873/17873/12728 14326/14326/9618 17874/17874/12729 +f 17874/17874/12729 14326/14326/9618 14256/14256/9554 +f 17874/17874/12729 14256/14256/9554 17875/17875/12730 +f 14755/14755/9984 17874/17874/12729 17875/17875/12730 +f 14755/14755/9984 17875/17875/12730 14530/14530/9790 +f 14343/14343/9635 14340/14340/9632 17876/17876/12731 +f 14343/14343/9635 17876/17876/12731 14726/14726/9960 +f 14340/14340/9632 14319/14319/9611 14322/14322/9614 +f 14340/14340/9632 14322/14322/9614 17876/17876/12731 +f 17876/17876/12731 14322/14322/9614 14310/14310/9605 +f 17876/17876/12731 14310/14310/9605 17877/17877/12732 +f 14726/14726/9960 17876/17876/12731 17877/17877/12732 +f 14726/14726/9960 17877/17877/12732 14713/14713/9949 +f 14713/14713/9949 17877/17877/12732 17878/17878/12733 +f 14713/14713/9949 17878/17878/12733 14714/14714/9950 +f 17877/17877/12732 14310/14310/9605 14313/14313/9608 +f 17877/17877/12732 14313/14313/9608 17878/17878/12733 +f 17879/17879/12733 14318/14318/9608 14301/14301/9596 +f 17879/17879/12733 14301/14301/9596 17880/17880/12734 +f 14716/14716/9950 17879/17879/12733 17880/17880/12734 +f 14716/14716/9950 17880/17880/12734 14586/14586/9840 +f 14586/14586/9840 17880/17880/12734 17881/17881/12735 +f 14586/14586/9840 17881/17881/12735 14587/14587/9841 +f 17880/17880/12734 14301/14301/9596 14304/14304/9599 +f 17880/17880/12734 14304/14304/9599 17881/17881/12735 +f 17881/17881/12735 14304/14304/9599 14309/14309/9604 +f 17881/17881/12735 14309/14309/9604 17873/17873/12728 +f 14587/14587/9841 17881/17881/12735 17873/17873/12728 +f 14587/14587/9841 17873/17873/12728 14589/14589/9843 +f 14456/14456/9727 17882/17882/12736 17883/17883/12737 +f 14456/14456/9727 17883/17883/12737 14457/14457/9728 +f 17882/17882/12736 14294/14294/9589 14296/14296/9591 +f 17882/17882/12736 14296/14296/9591 17883/17883/12737 +f 17883/17883/12737 14296/14296/9591 14300/14300/9595 +f 17883/17883/12737 14300/14300/9595 17884/17884/12738 +f 14457/14457/9728 17883/17883/12737 17884/17884/12738 +f 14457/14457/9728 17884/17884/12738 14459/14459/9729 +f 14503/14503/9767 17885/17885/12739 17886/17886/12740 +f 14503/14503/9767 17886/17886/12740 14504/14504/9768 +f 17885/17885/12739 14288/14288/9583 14290/14290/9585 +f 17885/17885/12739 14290/14290/9585 17886/17886/12740 +f 17886/17886/12740 14290/14290/9585 14294/14294/9589 +f 17886/17886/12740 14294/14294/9589 17882/17882/12736 +f 14504/14504/9768 17886/17886/12740 17882/17882/12736 +f 14504/14504/9768 17882/17882/12736 14456/14456/9727 +f 14540/14540/9800 17887/17887/12741 17888/17888/12742 +f 14540/14540/9800 17888/17888/12742 14541/14541/9801 +f 17887/17887/12741 14282/14282/9577 14284/14284/9579 +f 17887/17887/12741 14284/14284/9579 17888/17888/12742 +f 17888/17888/12742 14284/14284/9579 14288/14288/9583 +f 17888/17888/12742 14288/14288/9583 17885/17885/12739 +f 14541/14541/9801 17888/17888/12742 17885/17885/12739 +f 14541/14541/9801 17885/17885/12739 14503/14503/9767 +f 14576/14576/9830 17889/17889/12743 17890/17890/12744 +f 14576/14576/9830 17890/17890/12744 14577/14577/9831 +f 17889/17889/12743 14276/14276/9571 14278/14278/9573 +f 17889/17889/12743 14278/14278/9573 17890/17890/12744 +f 17890/17890/12744 14278/14278/9573 14282/14282/9577 +f 17890/17890/12744 14282/14282/9577 17887/17887/12741 +f 14577/14577/9831 17890/17890/12744 17887/17887/12741 +f 14577/14577/9831 17887/17887/12741 14540/14540/9800 +f 14618/14618/9868 17872/17872/12727 17891/17891/12745 +f 14618/14618/9868 17891/17891/12745 14619/14619/9869 +f 17872/17872/12727 14268/14268/9563 14271/14271/9566 +f 17872/17872/12727 14271/14271/9566 17891/17891/12745 +f 17891/17891/12745 14271/14271/9566 14276/14276/9571 +f 17891/17891/12745 14276/14276/9571 17889/17889/12743 +f 14619/14619/9869 17891/17891/12745 17889/17889/12743 +f 14619/14619/9869 17889/17889/12743 14576/14576/9830 +f 14530/14530/9790 17875/17875/12730 17892/17892/12746 +f 14530/14530/9790 17892/17892/12746 14531/14531/9791 +f 17875/17875/12730 14256/14256/9554 14259/14259/9557 +f 17875/17875/12730 14259/14259/9557 17892/17892/12746 +f 17893/17893/12747 14266/14266/9557 14267/14267/9562 +f 17893/17893/12747 14267/14267/9562 17870/17870/12725 +f 17894/17894/9791 17893/17893/12747 17870/17870/12725 +f 17894/17894/9791 17870/17870/12725 14760/14760/9989 +f 14235/14235/9533 14604/14604/9855 17895/17895/12748 +f 14235/14235/9533 17895/17895/12748 14233/14233/9531 +f 14604/14604/9855 14421/14421/9699 17896/17896/12749 +f 14604/14604/9855 17896/17896/12749 17895/17895/12748 +f 17895/17895/12748 17896/17896/12749 14242/14242/9540 +f 17895/17895/12748 14242/14242/9540 14251/14251/9549 +f 14233/14233/9531 17895/17895/12748 14251/14251/9549 +f 14233/14233/9531 14251/14251/9549 14230/14230/9528 +f 14421/14421/9699 14419/14419/9697 17897/17897/12750 +f 14421/14421/9699 17897/17897/12750 17896/17896/12749 +f 14419/14419/9697 14393/14393/9676 14390/14390/9673 +f 14419/14419/9697 14390/14390/9673 17897/17897/12750 +f 17897/17897/12750 14390/14390/9673 14246/14246/9544 +f 17897/17897/12750 14246/14246/9544 14243/14243/9541 +f 17896/17896/12749 17897/17897/12750 14243/14243/9541 +f 17896/17896/12749 14243/14243/9541 14242/14242/9540 +f 14354/14354/9644 14591/14591/9845 17898/17898/12751 +f 14354/14354/9644 17898/17898/12751 17899/17899/12752 +f 14591/14591/9845 14590/14590/9844 17900/17900/12753 +f 14591/14591/9845 17900/17900/12753 17898/17898/12751 +f 17898/17898/12751 17900/17900/12753 14179/14179/9480 +f 17898/17898/12751 14179/14179/9480 14239/14239/9537 +f 17899/17899/12752 17898/17898/12751 14239/14239/9537 +f 17899/17899/12752 14239/14239/9537 14172/14172/9475 +f 14368/14368/9656 14472/14472/9740 17901/17901/12754 +f 14368/14368/9656 17901/17901/12754 17902/17902/12755 +f 14472/14472/9740 14359/14359/9648 17903/17903/12756 +f 14472/14472/9740 17903/17903/12756 17901/17901/12754 +f 17901/17901/12754 17903/17903/12756 14167/14167/9471 +f 17901/17901/12754 14167/14167/9471 14236/14236/9534 +f 17902/17902/12755 17901/17901/12754 14236/14236/9534 +f 17902/17902/12755 14236/14236/9534 14216/14216/9517 +f 14255/14255/9553 14629/14629/9877 17904/17904/12757 +f 14255/14255/9553 17904/17904/12757 14253/14253/9551 +f 14629/14629/9877 14432/14432/9707 17905/17905/12758 +f 14629/14629/9877 17905/17905/12758 17904/17904/12757 +f 17904/17904/12757 17905/17905/12758 14221/14221/9522 +f 17904/17904/12757 14221/14221/9522 14231/14231/9529 +f 14253/14253/9551 17904/17904/12757 14231/14231/9529 +f 14253/14253/9551 14231/14231/9529 14230/14230/9528 +f 14432/14432/9707 14431/14431/9706 17906/17906/12759 +f 14432/14432/9707 17906/17906/12759 17905/17905/12758 +f 14429/14429/9704 14372/14372/9660 17907/17907/12760 +f 14429/14429/9704 17907/17907/12760 17908/17908/12759 +f 17908/17908/12759 17907/17907/12760 14212/14212/9513 +f 17908/17908/12759 14212/14212/9513 14225/14225/9523 +f 17905/17905/12758 17906/17906/12759 14222/14222/9523 +f 17905/17905/12758 14222/14222/9523 14221/14221/9522 +f 14372/14372/9660 14369/14369/9657 17909/17909/12761 +f 14372/14372/9660 17909/17909/12761 17907/17907/12760 +f 14369/14369/9657 14368/14368/9656 17902/17902/12755 +f 14369/14369/9657 17902/17902/12755 17909/17909/12761 +f 17909/17909/12761 17902/17902/12755 14216/14216/9517 +f 17909/17909/12761 14216/14216/9517 14213/14213/9514 +f 17907/17907/12760 17909/17909/12761 14213/14213/9514 +f 17907/17907/12760 14213/14213/9514 14212/14212/9513 +f 14464/14464/9734 14461/14461/9731 17910/17910/12762 +f 14464/14464/9734 17910/17910/12762 17911/17911/12763 +f 14461/14461/9731 14460/14460/9730 17814/17814/12680 +f 14461/14461/9731 17814/17814/12680 17910/17910/12762 +f 17910/17910/12762 17814/17814/12680 14208/14208/9509 +f 17910/17910/12762 14208/14208/9509 14206/14206/9507 +f 17911/17911/12763 17910/17910/12762 14206/14206/9507 +f 17911/17911/12763 14206/14206/9507 14202/14202/9503 +f 14507/14507/9771 14505/14505/9769 17912/17912/12764 +f 14507/14507/9771 17912/17912/12764 17913/17913/12765 +f 14505/14505/9769 14464/14464/9734 17911/17911/12763 +f 14505/14505/9769 17911/17911/12763 17912/17912/12764 +f 17912/17912/12764 17911/17911/12763 14202/14202/9503 +f 17912/17912/12764 14202/14202/9503 14200/14200/9501 +f 17913/17913/12765 17912/17912/12764 14200/14200/9501 +f 17913/17913/12765 14200/14200/9501 14196/14196/9497 +f 14544/14544/9804 14542/14542/9802 17914/17914/12766 +f 14544/14544/9804 17914/17914/12766 17915/17915/12767 +f 14542/14542/9802 14507/14507/9771 17913/17913/12765 +f 14542/14542/9802 17913/17913/12765 17914/17914/12766 +f 17914/17914/12766 17913/17913/12765 14196/14196/9497 +f 17914/17914/12766 14196/14196/9497 14194/14194/9495 +f 17915/17915/12767 17914/17914/12766 14194/14194/9495 +f 17915/17915/12767 14194/14194/9495 14190/14190/9491 +f 14552/14552/9812 14550/14550/9810 17916/17916/12768 +f 14552/14552/9812 17916/17916/12768 17917/17917/12769 +f 14550/14550/9810 14544/14544/9804 17915/17915/12767 +f 14550/14550/9810 17915/17915/12767 17916/17916/12768 +f 17916/17916/12768 17915/17915/12767 14190/14190/9491 +f 17916/17916/12768 14190/14190/9491 14188/14188/9489 +f 17917/17917/12769 17916/17916/12768 14188/14188/9489 +f 17917/17917/12769 14188/14188/9489 14183/14183/9484 +f 14590/14590/9844 14608/14608/9859 17918/17918/12770 +f 14590/14590/9844 17918/17918/12770 17900/17900/12753 +f 14608/14608/9859 14552/14552/9812 17917/17917/12769 +f 14608/14608/9859 17917/17917/12769 17918/17918/12770 +f 17918/17918/12770 17917/17917/12769 14183/14183/9484 +f 17918/17918/12770 14183/14183/9484 14180/14180/9481 +f 17900/17900/12753 17918/17918/12770 14180/14180/9481 +f 17900/17900/12753 14180/14180/9481 14179/14179/9480 +f 14359/14359/9648 14358/14358/9645 17919/17919/12771 +f 14359/14359/9648 17919/17919/12771 17903/17903/12756 +f 14355/14355/9645 14354/14354/9644 17899/17899/12752 +f 14355/14355/9645 17899/17899/12752 17920/17920/12772 +f 17920/17920/12772 17899/17899/12752 14172/14172/9475 +f 17920/17920/12772 14172/14172/9475 14171/14171/9472 +f 17903/17903/12756 17919/17919/12771 14168/14168/9472 +f 17903/17903/12756 14168/14168/9472 14167/14167/9471 +f 17921/17921/12773 17922/17922/12774 17923/17923/12775 +f 17921/17921/12773 17923/17923/12775 17924/17924/12776 +f 17925/17925/12774 17773/17773/12643 17776/17776/12646 +f 17925/17925/12774 17776/17776/12646 17926/17926/12775 +f 17927/17927/12775 17785/17785/12646 15217/15217/10409 +f 17927/17927/12775 15217/15217/10409 15216/15216/10408 +f 17928/17928/12776 17927/17927/12775 15216/15216/10408 +f 17928/17928/12776 15216/15216/10408 15215/15215/10407 +f 17929/17929/12777 17930/17930/12778 17931/17931/12779 +f 17929/17929/12777 17931/17931/12779 17932/17932/12780 +f 17933/17933/12781 17921/17921/12773 17924/17924/12776 +f 17933/17933/12781 17924/17924/12776 17934/17934/12782 +f 17935/17935/12779 17928/17928/12776 15215/15215/10407 +f 17935/17935/12779 15215/15215/10407 17801/17801/12667 +f 17932/17932/12780 17931/17931/12779 17936/17936/12783 +f 17932/17932/12780 17936/17936/12783 17937/17937/12784 +f 15208/15208/10401 17806/17806/12672 17938/17938/12785 +f 15208/15208/10401 17938/17938/12785 15209/15209/10402 +f 17783/17783/12651 17939/17939/12786 17938/17938/12785 +f 17783/17783/12651 17938/17938/12785 17806/17806/12672 +f 17800/17800/12666 17803/17803/12669 17938/17938/12785 +f 17800/17800/12666 17938/17938/12785 17939/17939/12786 +f 14957/14957/10169 17834/17834/12700 17938/17938/12785 +f 14957/14957/10169 17938/17938/12785 17803/17803/12669 +f 14968/14968/10180 15209/15209/10402 17938/17938/12785 +f 14968/14968/10180 17938/17938/12785 17834/17834/12700 +f 17778/17778/12647 17940/17940/12787 17941/17941/12788 +f 17778/17778/12647 17941/17941/12788 17779/17779/12648 +f 17942/17942/12787 17929/17929/12777 17932/17932/12780 +f 17942/17942/12787 17932/17932/12780 17943/17943/12788 +f 17943/17943/12788 17932/17932/12780 17937/17937/12784 +f 17943/17943/12788 17937/17937/12784 17944/17944/12786 +f 17782/17782/12648 17945/17945/12788 17939/17939/12786 +f 17782/17782/12648 17939/17939/12786 17783/17783/12651 +f 15093/15093/10297 17946/17946/12789 17947/17947/12790 +f 15093/15093/10297 17947/17947/12790 15094/15094/10298 +f 17826/17826/12692 17825/17825/12691 17947/17947/12790 +f 17826/17826/12692 17947/17947/12790 17946/17946/12789 +f 15118/15118/10321 15121/15121/10324 17947/17947/12790 +f 15118/15118/10321 17947/17947/12790 17825/17825/12691 +f 15001/15001/10211 15062/15062/10267 17947/17947/12790 +f 15001/15001/10211 17947/17947/12790 15121/15121/10324 +f 15061/15061/10266 15094/15094/10298 17947/17947/12790 +f 15061/15061/10266 17947/17947/12790 15062/15062/10267 +f 15077/15077/10282 17948/17948/12791 17949/17949/12792 +f 15077/15077/10282 17949/17949/12792 17950/17950/12793 +f 17819/17819/12685 17818/17818/12684 17949/17949/12792 +f 17819/17819/12685 17949/17949/12792 17948/17948/12791 +f 15108/15108/10311 15111/15111/10314 17949/17949/12792 +f 15108/15108/10311 17949/17949/12792 17818/17818/12684 +f 15022/15022/10231 15047/15047/10253 17949/17949/12792 +f 15022/15022/10231 17949/17949/12792 15111/15111/10314 +f 15046/15046/10252 17950/17950/12793 17949/17949/12792 +f 15046/15046/10252 17949/17949/12792 15047/15047/10253 +f 14298/14298/9593 14674/14674/9915 17951/17951/12794 +f 14298/14298/9593 17951/17951/12794 17824/17824/12690 +f 14672/14672/9913 14671/14671/9912 17952/17952/12795 +f 14672/14672/9913 17952/17952/12795 17953/17953/12796 +f 17953/17953/12796 17952/17952/12795 15104/15104/10307 +f 17953/17953/12796 15104/15104/10307 15122/15122/10322 +f 17824/17824/12690 17951/17951/12794 15119/15119/10322 +f 17824/17824/12690 15119/15119/10322 15118/15118/10321 +f 14471/14471/9739 14800/14800/10028 17954/17954/12797 +f 14471/14471/9739 17954/17954/12797 17955/17955/12798 +f 14800/14800/10028 14448/14448/9720 17956/17956/12799 +f 14800/14800/10028 17956/17956/12799 17954/17954/12797 +f 17954/17954/12797 17956/17956/12799 15081/15081/10286 +f 17954/17954/12797 15081/15081/10286 15116/15116/10319 +f 17955/17955/12798 17954/17954/12797 15116/15116/10319 +f 17955/17955/12798 15116/15116/10319 15113/15113/10316 +f 14460/14460/9730 14463/14463/9733 17957/17957/12800 +f 14460/14460/9730 17957/17957/12800 17817/17817/12683 +f 14470/14470/9738 14471/14471/9739 17955/17955/12798 +f 14470/14470/9738 17955/17955/12798 17958/17958/12800 +f 17958/17958/12800 17955/17955/12798 15113/15113/10316 +f 17958/17958/12800 15113/15113/10316 15112/15112/10315 +f 17817/17817/12683 17957/17957/12800 15109/15109/10312 +f 17817/17817/12683 15109/15109/10312 15108/15108/10311 +f 14671/14671/9912 14798/14798/10026 17959/17959/12801 +f 14671/14671/9912 17959/17959/12801 17952/17952/12795 +f 14798/14798/10026 14679/14679/9918 17960/17960/12802 +f 14798/14798/10026 17960/17960/12802 17959/17959/12801 +f 17959/17959/12801 17960/17960/12802 15096/15096/10300 +f 17959/17959/12801 15096/15096/10300 15105/15105/10308 +f 17952/17952/12795 17959/17959/12801 15105/15105/10308 +f 17952/17952/12795 15105/15105/10308 15104/15104/10307 +f 14679/14679/9918 14678/14678/9917 17961/17961/12803 +f 14679/14679/9918 17961/17961/12803 17960/17960/12802 +f 14676/14676/9917 14210/14210/9511 17962/17962/12804 +f 14676/14676/9917 17962/17962/12804 17963/17963/12803 +f 17963/17963/12803 17962/17962/12804 15101/15101/10304 +f 17963/17963/12803 15101/15101/10304 15100/15100/10301 +f 17960/17960/12802 17961/17961/12803 15097/15097/10301 +f 17960/17960/12802 15097/15097/10301 15096/15096/10300 +f 14210/14210/9511 14209/14209/9510 17964/17964/12805 +f 14210/14210/9511 17964/17964/12805 17962/17962/12804 +f 14208/14208/9509 17816/17816/12682 17964/17964/12805 +f 14208/14208/9509 17964/17964/12805 14209/14209/9510 +f 17821/17821/12687 17965/17965/12806 17964/17964/12805 +f 17821/17821/12687 17964/17964/12805 17816/17816/12682 +f 15080/15080/10285 17966/17966/12807 17964/17964/12805 +f 15080/15080/10285 17964/17964/12805 17965/17965/12806 +f 15101/15101/10304 17962/17962/12804 17964/17964/12805 +f 15101/15101/10304 17964/17964/12805 17966/17966/12807 +f 14448/14448/9720 14451/14451/9723 17967/17967/12808 +f 14448/14448/9720 17967/17967/12808 17956/17956/12799 +f 14458/14458/9723 14459/14459/9729 17968/17968/12809 +f 14458/14458/9723 17968/17968/12809 17969/17969/12808 +f 17969/17969/12808 17968/17968/12809 15086/15086/10291 +f 17969/17969/12808 15086/15086/10291 15085/15085/10290 +f 17956/17956/12799 17967/17967/12808 15082/15082/10287 +f 17956/17956/12799 15082/15082/10287 15081/15081/10286 +f 14459/14459/9729 17884/17884/12738 17970/17970/12810 +f 14459/14459/9729 17970/17970/12810 17968/17968/12809 +f 14300/14300/9595 17823/17823/12689 17970/17970/12810 +f 14300/14300/9595 17970/17970/12810 17884/17884/12738 +f 17828/17828/12694 17971/17971/12811 17970/17970/12810 +f 17828/17828/12694 17970/17970/12810 17823/17823/12689 +f 15091/15091/10295 15089/15089/10293 17970/17970/12810 +f 15091/15091/10295 17970/17970/12810 17971/17971/12811 +f 15086/15086/10291 17968/17968/12809 17970/17970/12810 +f 15086/15086/10291 17970/17970/12810 15089/15089/10293 +f 17972/17972/12812 17973/17973/12813 17974/17974/12814 +f 17972/17972/12812 17974/17974/12814 17975/17975/12815 +f 17976/17976/12813 15067/15067/10272 15070/15070/10275 +f 17976/17976/12813 15070/15070/10275 17977/17977/12814 +f 17978/17978/12816 15079/15079/10284 15080/15080/10285 +f 17978/17978/12816 15080/15080/10285 17965/17965/12806 +f 17979/17979/12815 17978/17978/12816 17965/17965/12806 +f 17979/17979/12815 17965/17965/12806 17821/17821/12687 +f 17980/17980/12817 17981/17981/12818 17982/17982/12819 +f 17980/17980/12817 17982/17982/12819 17983/17983/12820 +f 17984/17984/12821 17972/17972/12812 17975/17975/12815 +f 17984/17984/12821 17975/17975/12815 17985/17985/12822 +f 17986/17986/12823 17979/17979/12815 17821/17821/12687 +f 17986/17986/12823 17821/17821/12687 17820/17820/12686 +f 17987/17987/12824 17986/17986/12823 17820/17820/12686 +f 17987/17987/12824 17820/17820/12686 17819/17819/12685 +f 15101/15101/10304 17966/17966/12807 17988/17988/12825 +f 15101/15101/10304 17988/17988/12825 15102/15102/10305 +f 15080/15080/10285 15078/15078/10283 17988/17988/12825 +f 15080/15080/10285 17988/17988/12825 17966/17966/12807 +f 15077/15077/10282 17950/17950/12793 17988/17988/12825 +f 15077/15077/10282 17988/17988/12825 15078/15078/10283 +f 15046/15046/10252 17830/17830/12696 17988/17988/12825 +f 15046/15046/10252 17988/17988/12825 17950/17950/12793 +f 15040/15040/10247 15102/15102/10305 17988/17988/12825 +f 15040/15040/10247 17988/17988/12825 17830/17830/12696 +f 15072/15072/10277 17989/17989/12826 17990/17990/12827 +f 15072/15072/10277 17990/17990/12827 15073/15073/10278 +f 17991/17991/12828 17980/17980/12817 17983/17983/12820 +f 17991/17991/12828 17983/17983/12820 17992/17992/12829 +f 17993/17993/12830 17987/17987/12824 17819/17819/12685 +f 17993/17993/12830 17819/17819/12685 17948/17948/12791 +f 15076/15076/10281 17993/17993/12830 17948/17948/12791 +f 15076/15076/10281 17948/17948/12791 15077/15077/10282 +f 16044/16044/11131 16043/16043/11130 17994/17994/12831 +f 16044/16044/11131 17994/17994/12831 16216/16216/11286 +f 16043/16043/11130 16042/16042/11129 16069/16069/11153 +f 16043/16043/11130 16069/16069/11153 17994/17994/12831 +f 17995/17995/12832 16071/16071/11155 16053/16053/11138 +f 17995/17995/12832 16053/16053/11138 17996/17996/12833 +f 16218/16218/11286 17995/17995/12832 17996/17996/12833 +f 16218/16218/11286 17996/17996/12833 16219/16219/11287 +f 16223/16223/11291 17997/17997/12834 17998/17998/12835 +f 16223/16223/11291 17998/17998/12835 16224/16224/11292 +f 17997/17997/12834 16064/16064/11148 16066/16066/11150 +f 17997/17997/12834 16066/16066/11150 17998/17998/12835 +f 17998/17998/12835 16066/16066/11150 16026/16026/11114 +f 17998/17998/12835 16026/16026/11114 17999/17999/12836 +f 16224/16224/11292 17998/17998/12835 17999/17999/12836 +f 16224/16224/11292 17999/17999/12836 16225/16225/11293 +f 16200/16200/11272 18000/18000/12837 18001/18001/12838 +f 16200/16200/11272 18001/18001/12838 16228/16228/11296 +f 18000/18000/12837 16057/16057/11142 16060/16060/11145 +f 18000/18000/12837 16060/16060/11145 18001/18001/12838 +f 18002/18002/12839 16063/16063/11147 16064/16064/11148 +f 18002/18002/12839 16064/16064/11148 17997/17997/12834 +f 16230/16230/11296 18002/18002/12839 17997/17997/12834 +f 16230/16230/11296 17997/17997/12834 16223/16223/11291 +f 16219/16219/11287 17996/17996/12833 18003/18003/12840 +f 16219/16219/11287 18003/18003/12840 16232/16232/11298 +f 17996/17996/12833 16053/16053/11138 16056/16056/11141 +f 17996/17996/12833 16056/16056/11141 18003/18003/12840 +f 18003/18003/12840 16056/16056/11141 16045/16045/11132 +f 18003/18003/12840 16045/16045/11132 18004/18004/12841 +f 16232/16232/11298 18003/18003/12840 18004/18004/12841 +f 16232/16232/11298 18004/18004/12841 16233/16233/11299 +f 16237/16237/11299 18005/18005/12841 18006/18006/12842 +f 16237/16237/11299 18006/18006/12842 16238/16238/11302 +f 18004/18004/12841 16045/16045/11132 16048/16048/11135 +f 18004/18004/12841 16048/16048/11135 18007/18007/12842 +f 18006/18006/12842 16051/16051/11135 16052/16052/11137 +f 18006/18006/12842 16052/16052/11137 18008/18008/12843 +f 16238/16238/11302 18006/18006/12842 18008/18008/12843 +f 16238/16238/11302 18008/18008/12843 16239/16239/11303 +f 16052/16052/11137 16050/16050/11136 18009/18009/12844 +f 16052/16052/11137 18009/18009/12844 18010/18010/12845 +f 15938/15938/11042 18011/18011/12846 18009/18009/12844 +f 15938/15938/11042 18009/18009/12844 16050/16050/11136 +f 15939/15939/11043 18012/18012/12847 18009/18009/12844 +f 15939/15939/11043 18009/18009/12844 18011/18011/12846 +f 18013/18013/12848 18014/18014/12849 18009/18009/12844 +f 18013/18013/12848 18009/18009/12844 18012/18012/12847 +f 18015/18015/12850 18010/18010/12845 18009/18009/12844 +f 18015/18015/12850 18009/18009/12844 18014/18014/12849 +f 16225/16225/11293 17999/17999/12836 18016/18016/12851 +f 16225/16225/11293 18016/18016/12851 18017/18017/12852 +f 17999/17999/12836 16026/16026/11114 16029/16029/11117 +f 17999/17999/12836 16029/16029/11117 18016/18016/12851 +f 18018/18018/12851 16032/16032/11117 16033/16033/11120 +f 18018/18018/12851 16033/16033/11120 18019/18019/12853 +f 16252/16252/11314 18018/18018/12851 18019/18019/12853 +f 16252/16252/11314 18019/18019/12853 16253/16253/11315 +f 16033/16033/11120 16031/16031/11119 18020/18020/12854 +f 16033/16033/11120 18020/18020/12854 18021/18021/12855 +f 15954/15954/11053 18022/18022/12856 18020/18020/12854 +f 15954/15954/11053 18020/18020/12854 16031/16031/11119 +f 15955/15955/11054 18023/18023/12857 18020/18020/12854 +f 15955/15955/11054 18020/18020/12854 18022/18022/12856 +f 18024/18024/12858 18025/18025/12859 18020/18020/12854 +f 18024/18024/12858 18020/18020/12854 18023/18023/12857 +f 18026/18026/12860 18021/18021/12855 18020/18020/12854 +f 18026/18026/12860 18020/18020/12854 18025/18025/12859 +f 16040/16040/11127 18027/18027/12861 18028/18028/12862 +f 16040/16040/11127 18028/18028/12862 16041/16041/11128 +f 18024/18024/12858 18023/18023/12857 18028/18028/12862 +f 18024/18024/12858 18028/18028/12862 18027/18027/12861 +f 15955/15955/11054 15958/15958/11057 18028/18028/12862 +f 15955/15955/11054 18028/18028/12862 18023/18023/12857 +f 15534/15534/10697 16067/16067/11151 18028/18028/12862 +f 15534/15534/10697 18028/18028/12862 15958/15958/11057 +f 16042/16042/11129 16041/16041/11128 18028/18028/12862 +f 16042/16042/11129 18028/18028/12862 16067/16067/11151 +f 16022/16022/11110 18029/18029/12863 18030/18030/12864 +f 16022/16022/11110 18030/18030/12864 18031/18031/12865 +f 18013/18013/12848 18012/18012/12847 18030/18030/12864 +f 18013/18013/12848 18030/18030/12864 18029/18029/12863 +f 15939/15939/11043 15942/15942/11046 18030/18030/12864 +f 15939/15939/11043 18030/18030/12864 18012/18012/12847 +f 15858/15858/10974 16058/16058/11143 18030/18030/12864 +f 15858/15858/10974 18030/18030/12864 15942/15942/11046 +f 16057/16057/11142 18031/18031/12865 18030/18030/12864 +f 16057/16057/11142 18030/18030/12864 16058/16058/11143 +f 16136/16136/11215 16247/16247/11311 18032/18032/12866 +f 16136/16136/11215 18032/18032/12866 16137/16137/11216 +f 16246/16246/11310 18033/18033/12867 18032/18032/12866 +f 16246/16246/11310 18032/18032/12866 16247/16247/11311 +f 16208/16208/11278 16211/16211/11281 18032/18032/12866 +f 16208/16208/11278 18032/18032/12866 18033/18033/12867 +f 16163/16163/11240 16161/16161/11238 18032/18032/12866 +f 16163/16163/11240 18032/18032/12866 16211/16211/11281 +f 16076/16076/11160 16137/16137/11216 18032/18032/12866 +f 16076/16076/11160 18032/18032/12866 16161/16161/11238 +f 16121/16121/11201 18034/18034/12868 18035/18035/12869 +f 16121/16121/11201 18035/18035/12869 16122/16122/11202 +f 18036/18036/12870 18037/18037/12871 18035/18035/12869 +f 18036/18036/12870 18035/18035/12869 18034/18034/12868 +f 16192/16192/11264 16195/16195/11267 18035/18035/12869 +f 16192/16192/11264 18035/18035/12869 18037/18037/12871 +f 16177/16177/11252 16175/16175/11250 18035/18035/12869 +f 16177/16177/11252 18035/18035/12869 16195/16195/11267 +f 16097/16097/11180 16122/16122/11202 18035/18035/12869 +f 16097/16097/11180 18035/18035/12869 16175/16175/11250 +f 16206/16206/11276 16254/16254/11316 18038/18038/12872 +f 16206/16206/11276 18038/18038/12872 16243/16243/11307 +f 16253/16253/11315 18039/18039/12873 18038/18038/12872 +f 16253/16253/11315 18038/18038/12872 16254/16254/11316 +f 16034/16034/11121 16213/16213/11283 18038/18038/12872 +f 16034/16034/11121 18038/18038/12872 18039/18039/12873 +f 16212/16212/11282 18040/18040/12874 18038/18038/12872 +f 16212/16212/11282 18038/18038/12872 16213/16213/11283 +f 16244/16244/11308 16243/16243/11307 18038/18038/12872 +f 16244/16244/11308 18038/18038/12872 18040/18040/12874 +f 16190/16190/11262 16240/16240/11304 18041/18041/12875 +f 16190/16190/11262 18041/18041/12875 18042/18042/12876 +f 16239/16239/11303 18043/18043/12877 18041/18041/12875 +f 16239/16239/11303 18041/18041/12875 16240/16240/11304 +f 16198/16198/11270 16197/16197/11269 18041/18041/12875 +f 16198/16198/11270 18041/18041/12875 18043/18043/12877 +f 16196/16196/11268 16266/16266/11326 18041/18041/12875 +f 16196/16196/11268 18041/18041/12875 16197/16197/11269 +f 16265/16265/11325 18042/18042/12876 18041/18041/12875 +f 16265/16265/11325 18041/18041/12875 16266/16266/11326 +f 15257/15257/10449 16152/16152/11230 18044/18044/12878 +f 15257/15257/10449 18044/18044/12878 15258/15258/10450 +f 16152/16152/11230 16116/16116/11196 18045/18045/12879 +f 16152/16152/11230 18045/18045/12879 18044/18044/12878 +f 18044/18044/12878 18045/18045/12879 16117/16117/11197 +f 18044/18044/12878 16117/16117/11197 16145/16145/11223 +f 15258/15258/10450 18044/18044/12878 16145/16145/11223 +f 15258/15258/10450 16145/16145/11223 15259/15259/10451 +f 15502/15502/10671 16144/16144/11222 18046/18046/12880 +f 15502/15502/10671 18046/18046/12880 18047/18047/12881 +f 16144/16144/11222 16131/16131/11210 18048/18048/12882 +f 16144/16144/11222 18048/18048/12882 18046/18046/12880 +f 18046/18046/12880 18048/18048/12882 16132/16132/11211 +f 18046/18046/12880 16132/16132/11211 16138/16138/11217 +f 18047/18047/12881 18046/18046/12880 16138/16138/11217 +f 18047/18047/12881 16138/16138/11217 15345/15345/10534 +f 16131/16131/11210 16129/16129/11208 18049/18049/12883 +f 16131/16131/11210 18049/18049/12883 18048/18048/12882 +f 16129/16129/11208 16128/16128/11207 16242/16242/11306 +f 16129/16129/11208 16242/16242/11306 18049/18049/12883 +f 18049/18049/12883 16242/16242/11306 16136/16136/11215 +f 18049/18049/12883 16136/16136/11215 16133/16133/11212 +f 18048/18048/12882 18049/18049/12883 16133/16133/11212 +f 18048/18048/12882 16133/16133/11212 16132/16132/11211 +f 16116/16116/11196 16114/16114/11195 18050/18050/12884 +f 16116/16116/11196 18050/18050/12884 18045/18045/12879 +f 16114/16114/11195 16113/16113/11194 18051/18051/12885 +f 16114/16114/11195 18051/18051/12885 18050/18050/12884 +f 18050/18050/12884 18051/18051/12885 16121/16121/11201 +f 18050/18050/12884 16121/16121/11201 16118/16118/11198 +f 18045/18045/12879 18050/18050/12884 16118/16118/11198 +f 18045/18045/12879 16118/16118/11198 16117/16117/11197 +f 16239/16239/11303 18008/18008/12843 18052/18052/12886 +f 16239/16239/11303 18052/18052/12886 18043/18043/12877 +f 16052/16052/11137 18010/18010/12845 18052/18052/12886 +f 16052/16052/11137 18052/18052/12886 18008/18008/12843 +f 18015/18015/12850 18053/18053/12887 18052/18052/12886 +f 18015/18015/12850 18052/18052/12886 18010/18010/12845 +f 16025/16025/11113 18054/18054/12888 18052/18052/12886 +f 16025/16025/11113 18052/18052/12886 18053/18053/12887 +f 16198/16198/11270 18043/18043/12877 18052/18052/12886 +f 16198/16198/11270 18052/18052/12886 18054/18054/12888 +f 16253/16253/11315 18019/18019/12853 18055/18055/12889 +f 16253/16253/11315 18055/18055/12889 18039/18039/12873 +f 16033/16033/11120 18021/18021/12855 18055/18055/12889 +f 16033/16033/11120 18055/18055/12889 18019/18019/12853 +f 18026/18026/12860 18056/18056/12890 18055/18055/12889 +f 18026/18026/12860 18055/18055/12889 18021/18021/12855 +f 16038/16038/11125 16035/16035/11122 18055/18055/12889 +f 16038/16038/11125 18055/18055/12889 18056/18056/12890 +f 16034/16034/11121 18039/18039/12873 18055/18055/12889 +f 16034/16034/11121 18055/18055/12889 16035/16035/11122 +f 16009/16009/11051 16008/16008/11099 18057/18057/12891 +f 16009/16009/11051 18057/18057/12891 18058/18058/12892 +f 16008/16008/11099 18059/18059/11075 18060/18060/12893 +f 16008/16008/11099 18060/18060/12893 18057/18057/12891 +f 18057/18057/12891 18060/18060/12893 15996/15996/11091 +f 18057/18057/12891 15996/15996/11091 15995/15995/11089 +f 18058/18058/12892 18057/18057/12891 15995/15995/11089 +f 18058/18058/12892 15995/15995/11089 18061/18061/11058 +f 15978/15978/11077 15989/15989/11087 18062/18062/12894 +f 15978/15978/11077 18062/18062/12894 15973/15973/11072 +f 15989/15989/11087 15967/15967/11066 15965/15965/11064 +f 15989/15989/11087 15965/15965/11064 18062/18062/12894 +f 18062/18062/12894 15965/15965/11064 15964/15964/11063 +f 18062/18062/12894 15964/15964/11063 15979/15979/11078 +f 15973/15973/11072 18062/18062/12894 15979/15979/11078 +f 15973/15973/11072 15979/15979/11078 15970/15970/11069 +f 15985/15985/11084 18063/18063/11022 18064/18064/12895 +f 15985/15985/11084 18064/18064/12895 15981/15981/11080 +f 18063/18063/11022 18065/18065/12896 18066/18066/12897 +f 18063/18063/11022 18066/18066/12897 18064/18064/12895 +f 18064/18064/12895 18066/18066/12897 15974/15974/11073 +f 18064/18064/12895 15974/15974/11073 15971/15971/11070 +f 15981/15981/11080 18064/18064/12895 15971/15971/11070 +f 15981/15981/11080 15971/15971/11070 15970/15970/11069 +f 15904/15904/11014 15903/15903/11013 18067/18067/12898 +f 15904/15904/11014 18067/18067/12898 18068/18068/12899 +f 18069/18069/12900 15983/15983/11082 15982/15982/11081 +f 18069/18069/12900 15982/15982/11081 18070/18070/12901 +f 18070/18070/12901 15982/15982/11081 15964/15964/11063 +f 18070/18070/12901 15964/15964/11063 15963/15963/11062 +f 18068/18068/12899 18067/18067/12898 15961/15961/11060 +f 18068/18068/12899 15961/15961/11060 15922/15922/11030 +f 15954/15954/11053 15952/15952/11052 18071/18071/12902 +f 15954/15954/11053 18071/18071/12902 18022/18022/12856 +f 15952/15952/11052 15951/15951/11051 18072/18072/12903 +f 15952/15952/11052 18072/18072/12903 18071/18071/12902 +f 18071/18071/12902 18072/18072/12903 15959/15959/11058 +f 18071/18071/12902 15959/15959/11058 15956/15956/11055 +f 18022/18022/12856 18071/18071/12902 15956/15956/11055 +f 18022/18022/12856 15956/15956/11055 15955/15955/11054 +f 15938/15938/11042 15936/15936/11041 18073/18073/12904 +f 15938/15938/11042 18073/18073/12904 18011/18011/12846 +f 15936/15936/11041 15935/15935/11017 18074/18074/12905 +f 15936/15936/11041 18074/18074/12905 18073/18073/12904 +f 18073/18073/12904 18074/18074/12905 15943/15943/11026 +f 18073/18073/12904 15943/15943/11026 15940/15940/11044 +f 18011/18011/12846 18073/18073/12904 15940/15940/11044 +f 18011/18011/12846 15940/15940/11044 15939/15939/11043 +f 15907/15907/11017 15905/15905/11015 18075/18075/12906 +f 15907/15907/11017 18075/18075/12906 18076/18076/12905 +f 15905/15905/11015 15904/15904/11014 18068/18068/12899 +f 15905/15905/11015 18068/18068/12899 18075/18075/12906 +f 18075/18075/12906 18068/18068/12899 15922/15922/11030 +f 18075/18075/12906 15922/15922/11030 15919/15919/11027 +f 18076/18076/12905 18075/18075/12906 15919/15919/11027 +f 18076/18076/12905 15919/15919/11027 15918/15918/11026 +f 15460/15460/10634 18077/18077/10970 18078/18078/12907 +f 15460/15460/10634 18078/18078/12907 15453/15453/10629 +f 18077/18077/10970 15446/15446/10623 15444/15444/10622 +f 18077/18077/10970 15444/15444/10622 18078/18078/12907 +f 18078/18078/12907 15444/15444/10622 15443/15443/10621 +f 18078/18078/12907 15443/15443/10621 15871/15871/10985 +f 15453/15453/10629 18078/18078/12907 15871/15871/10985 +f 15453/15453/10629 15871/15871/10985 15450/15450/10626 +f 15877/15877/10919 18079/18079/12908 18080/18080/12909 +f 15877/15877/10919 18080/18080/12909 15873/15873/10987 +f 15797/15797/10917 15388/15388/10572 15387/15387/10571 +f 15797/15797/10917 15387/15387/10571 18081/18081/12909 +f 18081/18081/12909 15387/15387/10571 15386/15386/10570 +f 18081/18081/12909 15386/15386/10570 15454/15454/10627 +f 15873/15873/10987 18080/18080/12909 15451/15451/10627 +f 15873/15873/10987 15451/15451/10627 15450/15450/10626 +f 15299/15299/10488 15496/15496/10665 18082/18082/12910 +f 15299/15299/10488 18082/18082/12910 15300/15300/10489 +f 18083/18083/12911 15875/15875/10663 15874/15874/10988 +f 18083/18083/12911 15874/15874/10988 18084/18084/12912 +f 18084/18084/12912 15874/15874/10988 15443/15443/10621 +f 18084/18084/12912 15443/15443/10621 15442/15442/10618 +f 15300/15300/10489 18082/18082/12910 15439/15439/10618 +f 15300/15300/10489 15439/15439/10618 15301/15301/10490 +f 15372/15372/10559 15789/15789/10909 18085/18085/12913 +f 15372/15372/10559 18085/18085/12913 15367/15367/10556 +f 15789/15789/10909 15739/15739/10866 18086/18086/12914 +f 15789/15789/10909 18086/18086/12914 18085/18085/12913 +f 18085/18085/12913 18086/18086/12914 15382/15382/10566 +f 18085/18085/12913 15382/15382/10566 15391/15391/10575 +f 15367/15367/10556 18085/18085/12913 15391/15391/10575 +f 15367/15367/10556 15391/15391/10575 15364/15364/10553 +f 15739/15739/10866 15737/15737/10865 18087/18087/12915 +f 15739/15739/10866 18087/18087/12915 18086/18086/12914 +f 15737/15737/10865 15457/15457/10631 15455/15455/10630 +f 15737/15737/10865 15455/15455/10630 18087/18087/12915 +f 18087/18087/12915 15455/15455/10630 15386/15386/10570 +f 18087/18087/12915 15386/15386/10570 15383/15383/10567 +f 18086/18086/12914 18087/18087/12915 15383/15383/10567 +f 18086/18086/12914 15383/15383/10567 15382/15382/10566 +f 15576/15576/10731 15813/15813/10929 18088/18088/12916 +f 15576/15576/10731 18088/18088/12916 18089/18089/12917 +f 15810/15810/10929 15668/15668/10807 18090/18090/12918 +f 15810/15810/10929 18090/18090/12918 18091/18091/12916 +f 18091/18091/12916 18090/18090/12918 15316/15316/10505 +f 18091/18091/12916 15316/15316/10505 15377/15377/10563 +f 18089/18089/12917 18088/18088/12916 18092/18092/10563 +f 18089/18089/12917 18092/18092/10563 15311/15311/10500 +f 15632/15632/10779 15806/15806/10926 18093/18093/12919 +f 15632/15632/10779 18093/18093/12919 18094/18094/12920 +f 15806/15806/10926 15579/15579/10734 18095/18095/12921 +f 15806/15806/10926 18095/18095/12921 18093/18093/12919 +f 18093/18093/12919 18095/18095/12921 15307/15307/10496 +f 18093/18093/12919 15307/15307/10496 15373/15373/10560 +f 18094/18094/12920 18093/18093/12919 15373/15373/10560 +f 18094/18094/12920 15373/15373/10560 15353/15353/10542 +f 15395/15395/10579 15773/15773/10895 18096/18096/12922 +f 15395/15395/10579 18096/18096/12922 15393/15393/10577 +f 15773/15773/10895 15764/15764/10888 18097/18097/12923 +f 15773/15773/10895 18097/18097/12923 18096/18096/12922 +f 18096/18096/12922 18097/18097/12923 15368/15368/10547 +f 18096/18096/12922 15368/15368/10547 15365/15365/10554 +f 15393/15393/10577 18096/18096/12922 15365/15365/10554 +f 15393/15393/10577 15365/15365/10554 15364/15364/10553 +f 15764/15764/10888 15763/15763/10886 18098/18098/12924 +f 15764/15764/10888 18098/18098/12924 18097/18097/12923 +f 15760/15760/10886 15635/15635/10781 18099/18099/12925 +f 15760/15760/10886 18099/18099/12925 18100/18100/12924 +f 18100/18100/12924 18099/18099/12925 15349/15349/10538 +f 18100/18100/12924 15349/15349/10538 15359/15359/10548 +f 18101/18101/12923 18100/18100/12924 15359/15359/10548 +f 18101/18101/12923 15359/15359/10548 15358/15358/10547 +f 15635/15635/10781 15633/15633/10780 18102/18102/12926 +f 15635/15635/10781 18102/18102/12926 18099/18099/12925 +f 15633/15633/10780 15632/15632/10779 18094/18094/12920 +f 15633/15633/10780 18094/18094/12920 18102/18102/12926 +f 18102/18102/12926 18094/18094/12920 15353/15353/10542 +f 18102/18102/12926 15353/15353/10542 15350/15350/10539 +f 18099/18099/12925 18102/18102/12926 15350/15350/10539 +f 18099/18099/12925 15350/15350/10539 15349/15349/10538 +f 15505/15505/10673 15503/15503/10672 18103/18103/12927 +f 15505/15505/10673 18103/18103/12927 18104/18104/12928 +f 15503/15503/10672 15502/15502/10671 18047/18047/12881 +f 15503/15503/10672 18047/18047/12881 18103/18103/12927 +f 18103/18103/12927 18047/18047/12881 15345/15345/10534 +f 18103/18103/12927 15345/15345/10534 15343/15343/10532 +f 18104/18104/12928 18103/18103/12927 15343/15343/10532 +f 18104/18104/12928 15343/15343/10532 15339/15339/10528 +f 15550/15550/10711 15548/15548/10709 18105/18105/12929 +f 15550/15550/10711 18105/18105/12929 18106/18106/12930 +f 15548/15548/10709 15505/15505/10673 18104/18104/12928 +f 15548/15548/10709 18104/18104/12928 18105/18105/12929 +f 18105/18105/12929 18104/18104/12928 15339/15339/10528 +f 18105/18105/12929 15339/15339/10528 15337/15337/10526 +f 18106/18106/12930 18105/18105/12929 15337/15337/10526 +f 18106/18106/12930 15337/15337/10526 15333/15333/10522 +f 15587/15587/10741 15585/15585/10740 18107/18107/12931 +f 15587/15587/10741 18107/18107/12931 18108/18108/12932 +f 15585/15585/10740 15550/15550/10711 18106/18106/12930 +f 15585/15585/10740 18106/18106/12930 18107/18107/12931 +f 18107/18107/12931 18106/18106/12930 15333/15333/10522 +f 18107/18107/12931 15333/15333/10522 15331/15331/10520 +f 18108/18108/12932 18107/18107/12931 15331/15331/10520 +f 18108/18108/12932 15331/15331/10520 15327/15327/10516 +f 15623/15623/10771 15621/15621/10770 18109/18109/12933 +f 15623/15623/10771 18109/18109/12933 18110/18110/12934 +f 15621/15621/10770 15587/15587/10741 18108/18108/12932 +f 15621/15621/10770 18108/18108/12932 18109/18109/12933 +f 18109/18109/12933 18108/18108/12932 15327/15327/10516 +f 18109/18109/12933 15327/15327/10516 15325/15325/10514 +f 18110/18110/12934 18109/18109/12933 15325/15325/10514 +f 18110/18110/12934 15325/15325/10514 15320/15320/10509 +f 15668/15668/10807 15666/15666/10806 18111/18111/12935 +f 15668/15668/10807 18111/18111/12935 18090/18090/12918 +f 15666/15666/10806 15623/15623/10771 18110/18110/12934 +f 15666/15666/10806 18110/18110/12934 18111/18111/12935 +f 18111/18111/12935 18110/18110/12934 15320/15320/10509 +f 18111/18111/12935 15320/15320/10509 15317/15317/10506 +f 18090/18090/12918 18111/18111/12935 15317/15317/10506 +f 18090/18090/12918 15317/15317/10506 15316/15316/10505 +f 15579/15579/10734 15577/15577/10732 18112/18112/12936 +f 15579/15579/10734 18112/18112/12936 18095/18095/12921 +f 15577/15577/10732 15576/15576/10731 18089/18089/12917 +f 15577/15577/10732 18089/18089/12917 18112/18112/12936 +f 18112/18112/12936 18089/18089/12917 15311/15311/10500 +f 18112/18112/12936 15311/15311/10500 15308/15308/10497 +f 18095/18095/12921 18112/18112/12936 15308/15308/10497 +f 18095/18095/12921 15308/15308/10497 15307/15307/10496 +f 15282/15282/10473 15279/15279/10470 18113/18113/12937 +f 15282/15282/10473 18113/18113/12937 15657/15657/10798 +f 15279/15279/10470 15278/15278/10469 15304/15304/10493 +f 15279/15279/10470 15304/15304/10493 18113/18113/12937 +f 18113/18113/12937 15304/15304/10493 15293/15293/10482 +f 18113/18113/12937 15293/15293/10482 18114/18114/12938 +f 15657/15657/10798 18113/18113/12937 18114/18114/12938 +f 15657/15657/10798 18114/18114/12938 15477/15477/10648 +f 15477/15477/10648 18114/18114/12938 18115/18115/12939 +f 15477/15477/10648 18115/18115/12939 15469/15469/10642 +f 18114/18114/12938 15293/15293/10482 15296/15296/10485 +f 18114/18114/12938 15296/15296/10485 18115/18115/12939 +f 18115/18115/12939 15296/15296/10485 15301/15301/10490 +f 18115/18115/12939 15301/15301/10490 15441/15441/10620 +f 15469/15469/10642 18115/18115/12939 15441/15441/10620 +f 15469/15469/10642 15441/15441/10620 15449/15449/10625 +f 18116/18116/10588 18117/18117/12940 18118/18118/12941 +f 18116/18116/10588 18118/18118/12941 15642/15642/10788 +f 18117/18117/12940 15287/15287/10478 15290/15290/10480 +f 18117/18117/12940 15290/15290/10480 18118/18118/12941 +f 18118/18118/12941 15290/15290/10480 15227/15227/10419 +f 18118/18118/12941 15227/15227/10419 18119/18119/12942 +f 15642/15642/10788 18118/18118/12941 18119/18119/12942 +f 15642/15642/10788 18119/18119/12942 15639/15639/10785 +f 15417/15417/10598 18120/18120/12943 18121/18121/12944 +f 15417/15417/10598 18121/18121/12944 15522/15522/10688 +f 18120/18120/12943 15268/15268/10460 15285/15285/10476 +f 18120/18120/12943 15285/15285/10476 18121/18121/12944 +f 18121/18121/12944 15285/15285/10476 15218/15218/10410 +f 18121/18121/12944 15218/15218/10410 18122/18122/12945 +f 15522/15522/10688 18121/18121/12944 18122/18122/12945 +f 15522/15522/10688 18122/18122/12945 15416/15416/10597 +f 15305/15305/10494 15302/15302/10491 18123/18123/12946 +f 15305/15305/10494 18123/18123/12946 15682/15682/10820 +f 15302/15302/10491 15278/15278/10469 15281/15281/10472 +f 15302/15302/10491 15281/15281/10472 18123/18123/12946 +f 18123/18123/12946 15281/15281/10472 15269/15269/10461 +f 18123/18123/12946 15269/15269/10461 18124/18124/12947 +f 15682/15682/10820 18123/18123/12946 18124/18124/12947 +f 15682/15682/10820 18124/18124/12947 15487/15487/10656 +f 15487/15487/10656 18124/18124/12947 18125/18125/12948 +f 15487/15487/10656 18125/18125/12948 15484/15484/10650 +f 18124/18124/12947 15269/15269/10461 15272/15272/10464 +f 18124/18124/12947 15272/15272/10464 18125/18125/12948 +f 18126/18126/12948 15277/15277/10464 15260/15260/10452 +f 18126/18126/12948 15260/15260/10452 18127/18127/12949 +f 15479/15479/10650 18126/18126/12948 18127/18127/12949 +f 15479/15479/10650 18127/18127/12949 15428/15428/10609 +f 15428/15428/10609 18127/18127/12949 18128/18128/12950 +f 15428/15428/10609 18128/18128/12950 15420/15420/10601 +f 18127/18127/12949 15260/15260/10452 15263/15263/10455 +f 18127/18127/12949 15263/15263/10455 18128/18128/12950 +f 18128/18128/12950 15263/15263/10455 15268/15268/10460 +f 18128/18128/12950 15268/15268/10460 18120/18120/12943 +f 15420/15420/10601 18128/18128/12950 18120/18120/12943 +f 15420/15420/10601 18120/18120/12943 15417/15417/10598 +f 15520/15520/10686 18129/18129/12951 18130/18130/12952 +f 15520/15520/10686 18130/18130/12952 15512/15512/10680 +f 18129/18129/12951 15253/15253/10445 15255/15255/10447 +f 18129/18129/12951 15255/15255/10447 18130/18130/12952 +f 18130/18130/12952 15255/15255/10447 15259/15259/10451 +f 18130/18130/12952 15259/15259/10451 16147/16147/11225 +f 15512/15512/10680 18130/18130/12952 16147/16147/11225 +f 15512/15512/10680 16147/16147/11225 15509/15509/10677 +f 15561/15561/10720 18131/18131/12953 18132/18132/12954 +f 15561/15561/10720 18132/18132/12954 15555/15555/10716 +f 18131/18131/12953 15247/15247/10439 15249/15249/10441 +f 18131/18131/12953 15249/15249/10441 18132/18132/12954 +f 18132/18132/12954 15249/15249/10441 15253/15253/10445 +f 18132/18132/12954 15253/15253/10445 18129/18129/12951 +f 15555/15555/10716 18132/18132/12954 18129/18129/12951 +f 15555/15555/10716 18129/18129/12951 15520/15520/10686 +f 15598/15598/10750 18133/18133/12955 18134/18134/12956 +f 15598/15598/10750 18134/18134/12956 15592/15592/10745 +f 18133/18133/12955 15241/15241/10433 15243/15243/10435 +f 18133/18133/12955 15243/15243/10435 18134/18134/12956 +f 18134/18134/12956 15243/15243/10435 15247/15247/10439 +f 18134/18134/12956 15247/15247/10439 18131/18131/12953 +f 15592/15592/10745 18134/18134/12956 18131/18131/12953 +f 15592/15592/10745 18131/18131/12953 15561/15561/10720 +f 15606/15606/10757 18135/18135/12957 18136/18136/12958 +f 15606/15606/10757 18136/18136/12958 15600/15600/10752 +f 18135/18135/12957 15235/15235/10427 15237/15237/10429 +f 18135/18135/12957 15237/15237/10429 18136/18136/12958 +f 18136/18136/12958 15237/15237/10429 15241/15241/10433 +f 18136/18136/12958 15241/15241/10433 18133/18133/12955 +f 15600/15600/10752 18136/18136/12958 18133/18133/12955 +f 15600/15600/10752 18133/18133/12955 15598/15598/10750 +f 15639/15639/10785 18119/18119/12942 18137/18137/12959 +f 15639/15639/10785 18137/18137/12959 15661/15661/10801 +f 18119/18119/12942 15227/15227/10419 15230/15230/10422 +f 18119/18119/12942 15230/15230/10422 18137/18137/12959 +f 18137/18137/12959 15230/15230/10422 15235/15235/10427 +f 18137/18137/12959 15235/15235/10427 18135/18135/12957 +f 15661/15661/10801 18137/18137/12959 18135/18135/12957 +f 15661/15661/10801 18135/18135/12957 15606/15606/10757 +f 15416/15416/10597 18122/18122/12945 18138/18138/12960 +f 15416/15416/10597 18138/18138/12960 15408/15408/10591 +f 18122/18122/12945 15218/15218/10410 15221/15221/10413 +f 18122/18122/12945 15221/15221/10413 18138/18138/12960 +f 18138/18138/12960 15221/15221/10413 15226/15226/10418 +f 18138/18138/12960 15226/15226/10418 18139/18139/12940 +f 15408/15408/10591 18138/18138/12960 18139/18139/12940 +f 15408/15408/10591 18139/18139/12940 15405/15405/10588 +f 18140/18140/12961 18141/18141/12962 18142/18142/12963 +f 18140/18140/12961 18142/18142/12963 18143/18143/12964 +f 18144/18144/12965 16012/16012/11102 16015/16015/11105 +f 18144/18144/12965 16015/16015/11105 18145/18145/12966 +f 18145/18145/12966 16015/16015/11105 18146/18146/12967 +f 18145/18145/12966 18146/18146/12967 18147/18147/12887 +f 18148/18148/12968 18149/18149/12963 18053/18053/12887 +f 18148/18148/12968 18053/18053/12887 18015/18015/12850 +f 18150/18150/12969 18151/18151/12970 18152/18152/12971 +f 18150/18150/12969 18152/18152/12971 18153/18153/12972 +f 18154/18154/12970 18140/18140/12961 18143/18143/12964 +f 18154/18154/12970 18143/18143/12964 18155/18155/12973 +f 18156/18156/12974 18148/18148/12968 18015/18015/12850 +f 18156/18156/12974 18015/18015/12850 18014/18014/12849 +f 18157/18157/12975 18156/18156/12974 18014/18014/12849 +f 18157/18157/12975 18014/18014/12849 18013/18013/12848 +f 16198/16198/11270 18054/18054/12888 18158/18158/12976 +f 16198/16198/11270 18158/18158/12976 16199/16199/11271 +f 16025/16025/11113 16023/16023/11111 18158/18158/12976 +f 16025/16025/11113 18158/18158/12976 18054/18054/12888 +f 16022/16022/11110 18031/18031/12865 18158/18158/12976 +f 16022/16022/11110 18158/18158/12976 16023/16023/11111 +f 16057/16057/11142 18000/18000/12837 18158/18158/12976 +f 16057/16057/11142 18158/18158/12976 18031/18031/12865 +f 16200/16200/11272 16199/16199/11271 18158/18158/12976 +f 16200/16200/11272 18158/18158/12976 18000/18000/12837 +f 16017/16017/11106 18159/18159/12977 18160/18160/12978 +f 16017/16017/11106 18160/18160/12978 16018/16018/11107 +f 18161/18161/12979 18150/18150/12969 18153/18153/12972 +f 18161/18161/12979 18153/18153/12972 18162/18162/12978 +f 18163/18163/12978 18157/18157/12975 18013/18013/12848 +f 18163/18163/12978 18013/18013/12848 18029/18029/12863 +f 16021/16021/11109 18163/18163/12978 18029/18029/12863 +f 16021/16021/11109 18029/18029/12863 16022/16022/11110 +f 18164/18164/12980 18165/18165/12981 18166/18166/12982 +f 18164/18164/12980 18166/18166/12982 18167/18167/12983 +f 18168/18168/12981 16255/16255/11317 16258/16258/11320 +f 18168/18168/12981 16258/16258/11320 18169/18169/12982 +f 18170/18170/12982 16267/16267/11327 16196/16196/11268 +f 18170/18170/12982 16196/16196/11268 16193/16193/11265 +f 18171/18171/12984 18170/18170/12982 16193/16193/11265 +f 18171/18171/12984 16193/16193/11265 16192/16192/11264 +f 18172/18172/12985 18173/18173/12986 18174/18174/12987 +f 18172/18172/12985 18174/18174/12987 18175/18175/12988 +f 18176/18176/12989 18164/18164/12980 18167/18167/12983 +f 18176/18176/12989 18167/18167/12983 18177/18177/12990 +f 18178/18178/12991 18171/18171/12984 16192/16192/11264 +f 18178/18178/12991 16192/16192/11264 18037/18037/12871 +f 18179/18179/12988 18178/18178/12991 18037/18037/12871 +f 18179/18179/12988 18037/18037/12871 18036/18036/12870 +f 16113/16113/11194 16191/16191/11263 18180/18180/12992 +f 16113/16113/11194 18180/18180/12992 18051/18051/12885 +f 16190/16190/11262 18042/18042/12876 18180/18180/12992 +f 16190/16190/11262 18180/18180/12992 16191/16191/11263 +f 16265/16265/11325 18181/18181/12993 18180/18180/12992 +f 16265/16265/11325 18180/18180/12992 18042/18042/12876 +f 18036/18036/12870 18034/18034/12868 18180/18180/12992 +f 18036/18036/12870 18180/18180/12992 18181/18181/12993 +f 16121/16121/11201 18051/18051/12885 18180/18180/12992 +f 16121/16121/11201 18180/18180/12992 18034/18034/12868 +f 16260/16260/11322 18182/18182/12994 18183/18183/12995 +f 16260/16260/11322 18183/18183/12995 16261/16261/11323 +f 18184/18184/12994 18172/18172/12985 18175/18175/12988 +f 18184/18184/12994 18175/18175/12988 18185/18185/12996 +f 18186/18186/12995 18179/18179/12988 18036/18036/12870 +f 18186/18186/12995 18036/18036/12870 18181/18181/12993 +f 16264/16264/11323 18186/18186/12995 18181/18181/12993 +f 16264/16264/11323 18181/18181/12993 16265/16265/11325 +f 18026/18026/12860 18025/18025/12859 18187/18187/12997 +f 18026/18026/12860 18187/18187/12997 18188/18188/12998 +f 18189/18189/12999 18190/18190/12858 18191/18191/13000 +f 18189/18189/12999 18191/18191/13000 18192/18192/13001 +f 18192/18192/13001 18191/18191/13000 18150/18150/12969 +f 18192/18192/13001 18150/18150/12969 18161/18161/12979 +f 18193/18193/12998 18194/18194/13002 18159/18159/12977 +f 18193/18193/12998 18159/18159/12977 16017/16017/11106 +f 18190/18190/12858 18195/18195/13003 18196/18196/13004 +f 18190/18190/12858 18196/18196/13004 18191/18191/13000 +f 18027/18027/12861 16040/16040/11127 18197/18197/13005 +f 18027/18027/12861 18197/18197/13005 18198/18198/13004 +f 18199/18199/13006 18200/18200/13007 18140/18140/12961 +f 18199/18199/13006 18140/18140/12961 18154/18154/12970 +f 18191/18191/13000 18196/18196/13004 18151/18151/12970 +f 18191/18191/13000 18151/18151/12970 18150/18150/12969 +f 16040/16040/11127 16039/16039/11126 18201/18201/13008 +f 16040/16040/11127 18201/18201/13008 18197/18197/13005 +f 16039/16039/11126 16038/16038/11125 18202/18202/13009 +f 16039/16039/11126 18202/18202/13009 18201/18201/13008 +f 18203/18203/13010 18204/18204/13009 16012/16012/11102 +f 18203/18203/13010 16012/16012/11102 18144/18144/12965 +f 18200/18200/13007 18205/18205/13010 18141/18141/12962 +f 18200/18200/13007 18141/18141/12962 18140/18140/12961 +f 16038/16038/11125 18056/18056/12890 18206/18206/13011 +f 16038/16038/11125 18206/18206/13011 18202/18202/13009 +f 18056/18056/12890 18026/18026/12860 18188/18188/12998 +f 18056/18056/12890 18188/18188/12998 18206/18206/13011 +f 18207/18207/13012 18193/18193/12998 16017/16017/11106 +f 18207/18207/13012 16017/16017/11106 16016/16016/11103 +f 18204/18204/13009 18208/18208/13011 16013/16013/11103 +f 18204/18204/13009 16013/16013/11103 16012/16012/11102 +f 16208/16208/11278 18033/18033/12867 18209/18209/13013 +f 16208/16208/11278 18209/18209/13013 18210/18210/13014 +f 18033/18033/12867 16246/16246/11310 18211/18211/13015 +f 18033/18033/12867 18211/18211/13015 18209/18209/13013 +f 18212/18212/13013 18213/18213/13015 18172/18172/12985 +f 18212/18212/13013 18172/18172/12985 18184/18184/12994 +f 18214/18214/13016 18215/18215/13013 18182/18182/12994 +f 18214/18214/13016 18182/18182/12994 16260/16260/11322 +f 16246/16246/11310 16245/16245/11309 18216/18216/13017 +f 16246/16246/11310 18216/18216/13017 18211/18211/13015 +f 16245/16245/11309 16244/16244/11308 18217/18217/13018 +f 16245/16245/11309 18217/18217/13018 18216/18216/13017 +f 18218/18218/13019 18219/18219/13020 18164/18164/12980 +f 18218/18218/13019 18164/18164/12980 18176/18176/12989 +f 18213/18213/13015 18220/18220/13021 18173/18173/12986 +f 18213/18213/13015 18173/18173/12986 18172/18172/12985 +f 16244/16244/11308 18040/18040/12874 18221/18221/13022 +f 16244/16244/11308 18221/18221/13022 18217/18217/13018 +f 18040/18040/12874 16212/16212/11282 18222/18222/13023 +f 18040/18040/12874 18222/18222/13023 18221/18221/13022 +f 18223/18223/13022 18224/18224/13024 16255/16255/11317 +f 18223/18223/13022 16255/16255/11317 18168/18168/12981 +f 18219/18219/13020 18225/18225/13022 18165/18165/12981 +f 18219/18219/13020 18165/18165/12981 18164/18164/12980 +f 16212/16212/11282 16209/16209/11279 18226/18226/13025 +f 16212/16212/11282 18226/18226/13025 18222/18222/13023 +f 16209/16209/11279 16208/16208/11278 18210/18210/13014 +f 16209/16209/11279 18210/18210/13014 18226/18226/13025 +f 18227/18227/13025 18214/18214/13016 16260/16260/11322 +f 18227/18227/13025 16260/16260/11322 16259/16259/11321 +f 18224/18224/13024 18228/18228/13026 16256/16256/11318 +f 18224/18224/13024 16256/16256/11318 16255/16255/11317 +f 15093/15093/10297 15092/15092/10296 18229/18229/13027 +f 15093/15093/10297 18229/18229/13027 18230/18230/13028 +f 15092/15092/10296 15091/15091/10295 18231/18231/13029 +f 15092/15092/10296 18231/18231/13029 18229/18229/13027 +f 18232/18232/13027 18233/18233/13030 17980/17980/12817 +f 18232/18232/13027 17980/17980/12817 17991/17991/12828 +f 18234/18234/13028 18235/18235/13031 17989/17989/12826 +f 18234/18234/13028 17989/17989/12826 15072/15072/10277 +f 15091/15091/10295 17971/17971/12811 18236/18236/13032 +f 15091/15091/10295 18236/18236/13032 18231/18231/13029 +f 17971/17971/12811 17828/17828/12694 18237/18237/13033 +f 17971/17971/12811 18237/18237/13033 18236/18236/13032 +f 18238/18238/13034 18239/18239/13033 17972/17972/12812 +f 18238/18238/13034 17972/17972/12812 17984/17984/12821 +f 18233/18233/13030 18240/18240/13034 17981/17981/12818 +f 18233/18233/13030 17981/17981/12818 17980/17980/12817 +f 17828/17828/12694 17827/17827/12693 18241/18241/13035 +f 17828/17828/12694 18241/18241/13035 18237/18237/13033 +f 17827/17827/12693 17826/17826/12692 18242/18242/13036 +f 17827/17827/12693 18242/18242/13036 18241/18241/13035 +f 18243/18243/13035 18244/18244/13037 15067/15067/10272 +f 18243/18243/13035 15067/15067/10272 17976/17976/12813 +f 18239/18239/13033 18245/18245/13035 17973/17973/12813 +f 18239/18239/13033 17973/17973/12813 17972/17972/12812 +f 17826/17826/12692 17946/17946/12789 18246/18246/13038 +f 17826/17826/12692 18246/18246/13038 18242/18242/13036 +f 17946/17946/12789 15093/15093/10297 18230/18230/13028 +f 17946/17946/12789 18230/18230/13028 18246/18246/13038 +f 18247/18247/13039 18234/18234/13028 15072/15072/10277 +f 18247/18247/13039 15072/15072/10277 15071/15071/10276 +f 18244/18244/13037 18248/18248/13039 15068/15068/10273 +f 18244/18244/13037 15068/15068/10273 15067/15067/10272 +f 15202/15202/10396 17798/17798/12664 18249/18249/13040 +f 15202/15202/10396 18249/18249/13040 18250/18250/13041 +f 17798/17798/12664 17766/17766/12636 18251/18251/13042 +f 17798/17798/12664 18251/18251/13042 18249/18249/13040 +f 18252/18252/13040 18253/18253/13042 17929/17929/12777 +f 18252/18252/13040 17929/17929/12777 17942/17942/12787 +f 18254/18254/13043 18255/18255/13040 17940/17940/12787 +f 18254/18254/13043 17940/17940/12787 17778/17778/12647 +f 17766/17766/12636 17765/17765/12635 18256/18256/13044 +f 17766/17766/12636 18256/18256/13044 18251/18251/13042 +f 17765/17765/12635 17764/17764/12634 18257/18257/13045 +f 17765/17765/12635 18257/18257/13045 18256/18256/13044 +f 18258/18258/13046 18259/18259/13045 17921/17921/12773 +f 18258/18258/13046 17921/17921/12773 17933/17933/12781 +f 18253/18253/13042 18260/18260/13046 17930/17930/12778 +f 18253/18253/13042 17930/17930/12778 17929/17929/12777 +f 17764/17764/12634 17809/17809/12675 18261/18261/13047 +f 17764/17764/12634 18261/18261/13047 18257/18257/13045 +f 17809/17809/12675 15204/15204/10398 18262/18262/13048 +f 17809/17809/12675 18262/18262/13048 18261/18261/13047 +f 18263/18263/13047 18264/18264/13049 17773/17773/12643 +f 18263/18263/13047 17773/17773/12643 17925/17925/12774 +f 18259/18259/13045 18265/18265/13047 17922/17922/12774 +f 18259/18259/13045 17922/17922/12774 17921/17921/12773 +f 18266/18266/13050 18267/18267/13051 18268/18268/13052 +f 18266/18266/13050 18268/18268/13052 18264/18264/13049 +f 15203/15203/10397 15202/15202/10396 18250/18250/13041 +f 15203/15203/10397 18250/18250/13041 18269/18269/13053 +f 18270/18270/13053 18254/18254/13043 17778/17778/12647 +f 18270/18270/13053 17778/17778/12647 17777/17777/12644 +f 18264/18264/13049 18268/18268/13052 17774/17774/12644 +f 18264/18264/13049 17774/17774/12644 17773/17773/12643 +f 17145/17145/12086 17144/17144/12085 18271/18271/13054 +f 17145/17145/12086 18271/18271/13054 18272/18272/13055 +f 18272/18272/13055 18271/18271/13054 17212/17212/12125 +f 18272/18272/13055 17212/17212/12125 17210/17210/12146 +f 17141/17141/12076 17140/17140/12083 18273/18273/13056 +f 17141/17141/12076 18273/18273/13056 18274/18274/13057 +f 17140/17140/12083 17139/17139/12082 18275/18275/13058 +f 17140/17140/12083 18275/18275/13058 18273/18273/13056 +f 18273/18273/13056 18275/18275/13058 17163/17163/12102 +f 18273/18273/13056 17163/17163/12102 17204/17204/12140 +f 18274/18274/13057 18273/18273/13056 17204/17204/12140 +f 18274/18274/13057 17204/17204/12140 17203/17203/12129 +f 17135/17135/12078 17134/17134/12077 18276/18276/13059 +f 17135/17135/12078 18276/18276/13059 18277/18277/13054 +f 17134/17134/12077 17133/17133/12076 18278/18278/13060 +f 17134/17134/12077 18278/18278/13060 18276/18276/13059 +f 18276/18276/13059 18278/18278/13060 17192/17192/12129 +f 18276/18276/13059 17192/17192/12129 17189/17189/12126 +f 18277/18277/13054 18276/18276/13059 17189/17189/12126 +f 18277/18277/13054 17189/17189/12126 17188/17188/12125 +f 17129/17129/12072 17128/17128/12071 18279/18279/13061 +f 17129/17129/12072 18279/18279/13061 18280/18280/13062 +f 17128/17128/12071 17127/17127/12070 18281/18281/13063 +f 17128/17128/12071 18281/18281/13063 18279/18279/13061 +f 18279/18279/13061 18281/18281/13063 17184/17184/12121 +f 18279/18279/13061 17184/17184/12121 17182/17182/12119 +f 18280/18280/13062 18279/18279/13061 17182/17182/12119 +f 18280/18280/13062 17182/17182/12119 17167/17167/12106 +f 17123/17123/12066 17122/17122/12065 18282/18282/13064 +f 17123/17123/12066 18282/18282/13064 18283/18283/13065 +f 18283/18283/13065 18282/18282/13064 17173/17173/12112 +f 18283/18283/13065 17173/17173/12112 17172/17172/12111 +f 17139/17139/12082 17153/17153/12092 18284/18284/13066 +f 17139/17139/12082 18284/18284/13066 18275/18275/13058 +f 17153/17153/12092 17129/17129/12072 18280/18280/13062 +f 17153/17153/12092 18280/18280/13062 18284/18284/13066 +f 18284/18284/13066 18280/18280/13062 17167/17167/12106 +f 18284/18284/13066 17167/17167/12106 17164/17164/12103 +f 18275/18275/13058 18284/18284/13066 17164/17164/12103 +f 18275/18275/13058 17164/17164/12103 17163/17163/12102 +f 17151/17151/12090 17150/17150/12089 18285/18285/13067 +f 17151/17151/12090 18285/18285/13067 18286/18286/13068 +f 17150/17150/12089 17149/17149/12088 18287/18287/13065 +f 17150/17150/12089 18287/18287/13065 18285/18285/13067 +f 18285/18285/13067 18287/18287/13065 17158/17158/12097 +f 18285/18285/13067 17158/17158/12097 17155/17155/12094 +f 18286/18286/13068 18285/18285/13067 17155/17155/12094 +f 18286/18286/13068 17155/17155/12094 17154/17154/12093 +o Cube.031__0 +v -0.563200 -1.533142 0.702486 +v -0.562182 -1.536381 0.701274 +v -0.560329 -1.535695 0.701289 +v -0.559105 -1.335238 0.768709 +v -0.561254 -1.336546 0.768520 +v -0.559408 -1.337118 0.768110 +v -0.565377 -1.527848 0.675964 +v -0.566395 -1.524609 0.677176 +v -0.563524 -1.527162 0.675979 +v -0.332347 -1.530551 0.676293 +v -0.330198 -1.529242 0.676483 +v -0.332045 -1.528670 0.676892 +v -0.563240 -1.529024 0.675317 +v -0.565498 -1.331316 0.742220 +v -0.564449 -1.328013 0.743210 +v -0.562603 -1.328585 0.742800 +v -0.562301 -1.326705 0.743399 +v -0.328253 -1.332647 0.742517 +v -0.329271 -1.329408 0.743728 +v -0.331123 -1.330094 0.743714 +v -0.332345 -1.517408 0.652163 +v -0.333393 -1.520709 0.651173 +v -0.335239 -1.520137 0.651582 +v -0.335542 -1.522018 0.650983 +v -0.334603 -1.319698 0.719065 +v -0.332466 -1.320875 0.718418 +v -0.334319 -1.321561 0.718404 +v -0.331449 -1.324114 0.717207 +v -0.543613 -1.407109 0.714108 +v -0.540728 -1.417353 0.710317 +v -0.553616 -1.423973 0.709596 +v -0.533667 -1.421417 0.708119 +v -0.533295 -1.341314 0.735074 +v -0.540396 -1.345813 0.734390 +v -0.552298 -1.335549 0.739246 +v -0.543377 -1.356238 0.731226 +v -0.353806 -1.350405 0.710967 +v -0.356691 -1.340160 0.714758 +v -0.344690 -1.329159 0.717059 +v -0.363753 -1.336097 0.716955 +v -0.364124 -1.416200 0.690000 +v -0.357024 -1.411700 0.690684 +v -0.344194 -1.417529 0.687216 +v -0.354042 -1.401275 0.693849 +v -0.350847 -1.409808 0.719159 +v -0.353829 -1.420234 0.715994 +v -0.340999 -1.426061 0.712526 +v -0.360929 -1.424732 0.715310 +v -0.360558 -1.344630 0.742265 +v -0.353496 -1.348693 0.740068 +v -0.341495 -1.337692 0.742369 +v -0.350611 -1.358938 0.736277 +v -0.540182 -1.364771 0.756536 +v -0.537201 -1.354346 0.759700 +v -0.549103 -1.344081 0.764556 +v -0.530100 -1.349847 0.760384 +v -0.530472 -1.429950 0.733429 +v -0.537533 -1.425886 0.735627 +v -0.550420 -1.432506 0.734906 +v -0.540418 -1.415642 0.739418 +v -0.351271 -1.501018 0.688466 +v -0.354251 -1.511443 0.685302 +v -0.342349 -1.521708 0.680447 +v -0.361352 -1.515942 0.684618 +v -0.360981 -1.435839 0.711573 +v -0.353920 -1.439902 0.709376 +v -0.341033 -1.433283 0.710096 +v -0.351034 -1.450147 0.705584 +v -0.540605 -1.455981 0.725843 +v -0.537624 -1.445554 0.729008 +v -0.550453 -1.439728 0.732476 +v -0.530523 -1.441056 0.729692 +v -0.530895 -1.521159 0.702737 +v -0.537956 -1.517096 0.704934 +v -0.549957 -1.528097 0.702634 +v -0.540841 -1.506851 0.708725 +v -0.544036 -1.498318 0.683415 +v -0.541151 -1.508563 0.679624 +v -0.553153 -1.519564 0.677323 +v -0.534090 -1.512626 0.677427 +v -0.533719 -1.432523 0.704382 +v -0.540819 -1.437022 0.703698 +v -0.553648 -1.431195 0.707166 +v -0.543800 -1.447448 0.700534 +v -0.354229 -1.441614 0.680274 +v -0.357114 -1.431369 0.684066 +v -0.344228 -1.424751 0.684786 +v -0.364176 -1.427306 0.686263 +v -0.364548 -1.507410 0.659308 +v -0.357447 -1.502910 0.659992 +v -0.345544 -1.513175 0.655137 +v -0.354466 -1.492485 0.663156 +v -0.560045 -1.537558 0.700627 +v -0.562303 -1.339849 0.767529 +v -0.329150 -1.525941 0.677473 +v -0.331408 -1.328231 0.744375 +v 0.571458 -1.534152 0.674024 +v 0.568527 -1.536700 0.672973 +v 0.570374 -1.537390 0.672866 +v 0.571041 -1.336244 0.740360 +v 0.571309 -1.338125 0.739748 +v 0.573175 -1.337556 0.740064 +v 0.572312 -1.528861 0.647427 +v 0.570463 -1.528171 0.647534 +v 0.573395 -1.525624 0.648585 +v 0.339586 -1.531149 0.659439 +v 0.339319 -1.529268 0.660052 +v 0.337453 -1.529837 0.659736 +v 0.570143 -1.530034 0.646888 +v 0.576104 -1.332332 0.713584 +v 0.573247 -1.329597 0.714309 +v 0.575112 -1.329028 0.714625 +v 0.572978 -1.327716 0.714922 +v 0.339170 -1.333241 0.725775 +v 0.342102 -1.330693 0.726827 +v 0.340253 -1.330004 0.726934 +v 0.338399 -1.518005 0.635338 +v 0.341256 -1.520739 0.634613 +v 0.339390 -1.521309 0.634297 +v 0.341524 -1.522621 0.634000 +v 0.344360 -1.320302 0.702034 +v 0.344039 -1.322165 0.701388 +v 0.342191 -1.321476 0.701495 +v 0.341108 -1.324713 0.700337 +v 0.552702 -1.408085 0.686608 +v 0.562436 -1.424967 0.681602 +v 0.549613 -1.418324 0.682967 +v 0.542443 -1.422375 0.681126 +v 0.543566 -1.342273 0.708062 +v 0.562765 -1.336541 0.711275 +v 0.550615 -1.346784 0.707024 +v 0.553416 -1.357215 0.703714 +v 0.363078 -1.351043 0.692984 +v 0.354317 -1.329782 0.699525 +v 0.366168 -1.340804 0.696626 +v 0.373338 -1.336754 0.698466 +v 0.372215 -1.416855 0.671530 +v 0.352168 -1.418149 0.669749 +v 0.365165 -1.412344 0.672569 +v 0.362366 -1.401913 0.675878 +v 0.360428 -1.410441 0.701317 +v 0.350231 -1.426677 0.695187 +v 0.363228 -1.420873 0.698008 +v 0.370277 -1.425384 0.696969 +v 0.371400 -1.345281 0.723905 +v 0.352379 -1.338310 0.724964 +v 0.364231 -1.349332 0.722065 +v 0.361141 -1.359572 0.718423 +v 0.551478 -1.365743 0.729153 +v 0.560827 -1.345069 0.736714 +v 0.548678 -1.355313 0.732463 +v 0.541629 -1.350801 0.733501 +v 0.540506 -1.430904 0.706565 +v 0.560498 -1.433495 0.707040 +v 0.547675 -1.426852 0.708405 +v 0.550765 -1.416613 0.712047 +v 0.359150 -1.501651 0.670646 +v 0.349800 -1.522324 0.663085 +v 0.361949 -1.512080 0.667337 +v 0.368999 -1.516592 0.666298 +v 0.370122 -1.436490 0.693234 +v 0.350130 -1.433898 0.692759 +v 0.362952 -1.440540 0.691394 +v 0.359863 -1.450780 0.687752 +v 0.550200 -1.456952 0.698482 +v 0.560397 -1.440717 0.704612 +v 0.547400 -1.446521 0.701792 +v 0.540350 -1.442009 0.702830 +v 0.539228 -1.522112 0.675894 +v 0.558249 -1.529083 0.674836 +v 0.546397 -1.518061 0.677734 +v 0.549487 -1.507822 0.681376 +v 0.551424 -1.499294 0.655937 +v 0.560186 -1.520555 0.649397 +v 0.548334 -1.509533 0.652296 +v 0.541165 -1.513584 0.650455 +v 0.542287 -1.433481 0.677392 +v 0.562335 -1.432189 0.679173 +v 0.549337 -1.437992 0.676353 +v 0.552137 -1.448424 0.673043 +v 0.361800 -1.442252 0.662314 +v 0.352067 -1.425370 0.667320 +v 0.364889 -1.432011 0.665955 +v 0.372059 -1.427962 0.667796 +v 0.370937 -1.508065 0.640859 +v 0.351737 -1.513796 0.637646 +v 0.363887 -1.503552 0.641898 +v 0.361087 -1.493122 0.645208 +v 0.568206 -1.538563 0.672326 +v 0.574166 -1.340861 0.739022 +v 0.336461 -1.526533 0.660777 +v 0.342422 -1.328830 0.727473 +v -0.569870 -1.526212 0.700596 +v -0.569448 -1.435189 0.731226 +v -0.571523 -1.429648 0.714790 +v -0.571945 -1.520671 0.684160 +v -0.360558 -1.344630 0.742265 +v -0.530100 -1.349847 0.760384 +v -0.533295 -1.341314 0.735074 +v -0.363753 -1.336097 0.716955 +v -0.566044 -1.333740 0.765020 +v -0.568119 -1.328198 0.748585 +v -0.571100 -1.338624 0.745420 +v -0.569026 -1.344165 0.761856 +v -0.533719 -1.432523 0.704382 +v -0.364176 -1.427306 0.686263 +v -0.360981 -1.435839 0.711573 +v -0.530523 -1.441056 0.729692 +v -0.540182 -1.364771 0.756536 +v -0.540418 -1.415642 0.739418 +v -0.543613 -1.407109 0.714108 +v -0.543377 -1.356238 0.731226 +v -0.530472 -1.429950 0.733429 +v -0.360929 -1.424732 0.715310 +v -0.364124 -1.416200 0.690000 +v -0.533667 -1.421417 0.708119 +v -0.325200 -1.422068 0.688466 +v -0.324777 -1.331044 0.719096 +v -0.322702 -1.336585 0.735532 +v -0.323125 -1.427608 0.704902 +v -0.354229 -1.441614 0.680274 +v -0.354466 -1.492485 0.663156 +v -0.351271 -1.501018 0.688466 +v -0.351034 -1.450147 0.705584 +v -0.544036 -1.498318 0.683415 +v -0.543800 -1.447448 0.700534 +v -0.540605 -1.455981 0.725843 +v -0.540841 -1.506851 0.708725 +v -0.325623 -1.513091 0.657836 +v -0.323547 -1.518632 0.674272 +v -0.350847 -1.409808 0.719159 +v -0.350611 -1.358938 0.736277 +v -0.353806 -1.350405 0.710967 +v -0.354042 -1.401275 0.693849 +v -0.364548 -1.507410 0.659308 +v -0.534090 -1.512626 0.677427 +v -0.530895 -1.521159 0.702737 +v -0.361352 -1.515942 0.684618 +v -0.569059 -1.530916 0.680369 +v -0.566985 -1.536457 0.696805 +v -0.561999 -1.534979 0.678172 +v -0.335704 -1.528015 0.653988 +v -0.333630 -1.533556 0.670424 +v -0.559924 -1.540520 0.694608 +v -0.558944 -1.329240 0.765704 +v -0.561018 -1.323700 0.749268 +v -0.568119 -1.328198 0.748585 +v -0.566044 -1.333740 0.765020 +v -0.328603 -1.523517 0.654672 +v -0.326529 -1.529057 0.671108 +v -0.327662 -1.320799 0.722887 +v -0.325588 -1.326340 0.739323 +v -0.566985 -1.536457 0.696805 +v -0.569059 -1.530916 0.680369 +v -0.334723 -1.316736 0.725085 +v -0.332648 -1.322277 0.741521 +v -0.326529 -1.529057 0.671108 +v -0.328603 -1.523517 0.654672 +v -0.325588 -1.326340 0.739323 +v -0.327662 -1.320799 0.722887 +v -0.537533 -1.425886 0.735627 +v -0.540728 -1.417353 0.710317 +v -0.540728 -1.417353 0.710317 +v -0.537533 -1.425886 0.735627 +v -0.357024 -1.411700 0.690684 +v -0.353829 -1.420234 0.715994 +v -0.353829 -1.420234 0.715994 +v -0.357024 -1.411700 0.690684 +v -0.356691 -1.340160 0.714758 +v -0.353496 -1.348693 0.740068 +v -0.353496 -1.348693 0.740068 +v -0.356691 -1.340160 0.714758 +v -0.540396 -1.345813 0.734390 +v -0.537201 -1.354346 0.759700 +v -0.537201 -1.354346 0.759700 +v -0.540396 -1.345813 0.734390 +v -0.357447 -1.502910 0.659992 +v -0.354251 -1.511443 0.685302 +v -0.354251 -1.511443 0.685302 +v -0.357447 -1.502910 0.659992 +v -0.537956 -1.517096 0.704934 +v -0.541151 -1.508563 0.679624 +v -0.541151 -1.508563 0.679624 +v -0.537956 -1.517096 0.704934 +v -0.537624 -1.445554 0.729008 +v -0.540819 -1.437022 0.703698 +v -0.540819 -1.437022 0.703698 +v -0.537624 -1.445554 0.729008 +v -0.353920 -1.439902 0.709376 +v -0.357114 -1.431369 0.684066 +v -0.357114 -1.431369 0.684066 +v -0.353920 -1.439902 0.709376 +v -0.565346 -1.537054 0.699952 +v -0.567684 -1.528861 0.702987 +v -0.567684 -1.528861 0.702987 +v -0.565346 -1.537054 0.699952 +v -0.559728 -1.540272 0.698209 +v -0.565346 -1.537054 0.699952 +v -0.559728 -1.540272 0.698209 +v -0.564409 -1.335181 0.767883 +v -0.558759 -1.331616 0.768422 +v -0.558759 -1.331616 0.768422 +v -0.564409 -1.335181 0.767883 +v -0.566824 -1.343520 0.765356 +v -0.564409 -1.335181 0.767883 +v -0.566824 -1.343520 0.765356 +v -0.568213 -1.529398 0.677241 +v -0.562594 -1.532616 0.675498 +v -0.562594 -1.532616 0.675498 +v -0.568213 -1.529398 0.677241 +v -0.570551 -1.521205 0.680277 +v -0.568213 -1.529398 0.677241 +v -0.570551 -1.521205 0.680277 +v -0.567276 -1.327524 0.745172 +v -0.569691 -1.335864 0.742645 +v -0.569691 -1.335864 0.742645 +v -0.567276 -1.327524 0.745172 +v -0.561626 -1.323961 0.745711 +v -0.567276 -1.327524 0.745172 +v -0.561626 -1.323961 0.745711 +v -0.327372 -1.529732 0.674520 +v -0.333022 -1.533296 0.673981 +v -0.333022 -1.533296 0.673981 +v -0.327372 -1.529732 0.674520 +v -0.324956 -1.521392 0.677047 +v -0.327372 -1.529732 0.674520 +v -0.324956 -1.521392 0.677047 +v -0.326434 -1.327858 0.742451 +v -0.324096 -1.336052 0.739416 +v -0.324096 -1.336052 0.739416 +v -0.326434 -1.327858 0.742451 +v -0.332054 -1.324641 0.744195 +v -0.326434 -1.327858 0.742451 +v -0.332054 -1.324641 0.744195 +v -0.330238 -1.522075 0.651809 +v -0.327824 -1.513736 0.654337 +v -0.327824 -1.513736 0.654337 +v -0.330238 -1.522075 0.651809 +v -0.335889 -1.525640 0.651270 +v -0.330238 -1.522075 0.651809 +v -0.335889 -1.525640 0.651270 +v -0.329301 -1.320202 0.719740 +v -0.334919 -1.316983 0.721484 +v -0.334919 -1.316983 0.721484 +v -0.329301 -1.320202 0.719740 +v -0.326963 -1.328395 0.716705 +v -0.329301 -1.320202 0.719740 +v -0.326963 -1.328395 0.716705 +v -0.562795 -1.436496 0.735012 +v -0.567267 -1.436191 0.734173 +v -0.567267 -1.436191 0.734173 +v -0.565991 -1.427964 0.709702 +v -0.570134 -1.428535 0.711462 +v -0.570134 -1.428535 0.711462 +v -0.331852 -1.420758 0.684680 +v -0.327380 -1.421065 0.685519 +v -0.327380 -1.421065 0.685519 +v -0.328658 -1.429291 0.709990 +v -0.324514 -1.428722 0.708230 +v -0.324514 -1.428722 0.708230 +v 0.578037 -1.527234 0.671802 +v 0.579295 -1.521696 0.655283 +v 0.580571 -1.430673 0.685891 +v 0.579313 -1.436211 0.702411 +v 0.371400 -1.345281 0.723905 +v 0.373338 -1.336754 0.698466 +v 0.543566 -1.342273 0.708062 +v 0.541629 -1.350801 0.733501 +v 0.577788 -1.334758 0.736329 +v 0.580589 -1.345188 0.733019 +v 0.581846 -1.339650 0.716500 +v 0.579047 -1.329219 0.719809 +v 0.542287 -1.433481 0.677392 +v 0.540350 -1.442009 0.702830 +v 0.370122 -1.436490 0.693234 +v 0.372059 -1.427962 0.667796 +v 0.551478 -1.365743 0.729153 +v 0.553416 -1.357215 0.703714 +v 0.552702 -1.408085 0.686608 +v 0.550765 -1.416613 0.712047 +v 0.540506 -1.430904 0.706565 +v 0.542443 -1.422375 0.681126 +v 0.372215 -1.416855 0.671530 +v 0.370277 -1.425384 0.696969 +v 0.333252 -1.422654 0.671950 +v 0.331994 -1.428192 0.688469 +v 0.333270 -1.337169 0.719077 +v 0.334528 -1.331631 0.702558 +v 0.361800 -1.442252 0.662314 +v 0.359863 -1.450780 0.687752 +v 0.359150 -1.501651 0.670646 +v 0.361087 -1.493122 0.645208 +v 0.551424 -1.499294 0.655937 +v 0.549487 -1.507822 0.681376 +v 0.550200 -1.456952 0.698482 +v 0.552137 -1.448424 0.673043 +v 0.331977 -1.513676 0.641341 +v 0.330718 -1.519215 0.657861 +v 0.360428 -1.410441 0.701317 +v 0.362366 -1.401913 0.675878 +v 0.363078 -1.351043 0.692984 +v 0.361141 -1.359572 0.718423 +v 0.370937 -1.508065 0.640859 +v 0.368999 -1.516592 0.666298 +v 0.539228 -1.522112 0.675894 +v 0.541165 -1.513584 0.650455 +v 0.576205 -1.531936 0.651641 +v 0.574948 -1.537473 0.668161 +v 0.569036 -1.535986 0.649801 +v 0.567778 -1.541524 0.666321 +v 0.340568 -1.534157 0.653512 +v 0.341826 -1.528619 0.636993 +v 0.570739 -1.330246 0.737368 +v 0.577788 -1.334758 0.736329 +v 0.579047 -1.329219 0.719809 +v 0.571997 -1.324709 0.720848 +v 0.333519 -1.529645 0.654551 +v 0.334776 -1.524107 0.638031 +v 0.337618 -1.321391 0.706199 +v 0.336360 -1.326929 0.722719 +v 0.576205 -1.531936 0.651641 +v 0.574948 -1.537473 0.668161 +v 0.344787 -1.317341 0.708040 +v 0.343529 -1.322879 0.724560 +v 0.333519 -1.529645 0.654551 +v 0.334776 -1.524107 0.638031 +v 0.337618 -1.321391 0.706199 +v 0.336360 -1.326929 0.722719 +v 0.549613 -1.418324 0.682967 +v 0.547675 -1.426852 0.708405 +v 0.549613 -1.418324 0.682967 +v 0.547675 -1.426852 0.708405 +v 0.363228 -1.420873 0.698008 +v 0.365165 -1.412344 0.672569 +v 0.363228 -1.420873 0.698008 +v 0.365165 -1.412344 0.672569 +v 0.364231 -1.349332 0.722065 +v 0.366168 -1.340804 0.696626 +v 0.364231 -1.349332 0.722065 +v 0.366168 -1.340804 0.696626 +v 0.548678 -1.355313 0.732463 +v 0.550615 -1.346784 0.707024 +v 0.548678 -1.355313 0.732463 +v 0.550615 -1.346784 0.707024 +v 0.361949 -1.512080 0.667337 +v 0.363887 -1.503552 0.641898 +v 0.361949 -1.512080 0.667337 +v 0.363887 -1.503552 0.641898 +v 0.548334 -1.509533 0.652296 +v 0.546397 -1.518061 0.677734 +v 0.548334 -1.509533 0.652296 +v 0.546397 -1.518061 0.677734 +v 0.549337 -1.437992 0.676353 +v 0.547400 -1.446521 0.701792 +v 0.549337 -1.437992 0.676353 +v 0.547400 -1.446521 0.701792 +v 0.364889 -1.432011 0.665955 +v 0.362952 -1.440540 0.691394 +v 0.364889 -1.432011 0.665955 +v 0.362952 -1.440540 0.691394 +v 0.575969 -1.529880 0.674300 +v 0.573467 -1.538069 0.671386 +v 0.575969 -1.529880 0.674300 +v 0.573467 -1.538069 0.671386 +v 0.573467 -1.538069 0.671386 +v 0.567763 -1.541276 0.669927 +v 0.567763 -1.541276 0.669927 +v 0.570687 -1.332622 0.740092 +v 0.576297 -1.336197 0.739270 +v 0.570687 -1.332622 0.740092 +v 0.576297 -1.336197 0.739270 +v 0.576297 -1.336197 0.739270 +v 0.578567 -1.344540 0.736625 +v 0.578567 -1.344540 0.736625 +v 0.569501 -1.533624 0.647100 +v 0.575206 -1.530416 0.648560 +v 0.569501 -1.533624 0.647100 +v 0.575206 -1.530416 0.648560 +v 0.575206 -1.530416 0.648560 +v 0.577708 -1.522227 0.651474 +v 0.577708 -1.522227 0.651474 +v 0.580306 -1.336888 0.713798 +v 0.578035 -1.328544 0.716444 +v 0.580306 -1.336888 0.713798 +v 0.578035 -1.328544 0.716444 +v 0.578035 -1.328544 0.716444 +v 0.572425 -1.324970 0.717265 +v 0.572425 -1.324970 0.717265 +v 0.340140 -1.533895 0.657095 +v 0.334530 -1.530321 0.657917 +v 0.340140 -1.533895 0.657095 +v 0.334530 -1.530321 0.657917 +v 0.334530 -1.530321 0.657917 +v 0.332260 -1.521977 0.660562 +v 0.332260 -1.521977 0.660562 +v 0.334858 -1.336638 0.722886 +v 0.337359 -1.328449 0.725801 +v 0.334858 -1.336638 0.722886 +v 0.337359 -1.328449 0.725801 +v 0.337359 -1.328449 0.725801 +v 0.343064 -1.325241 0.727260 +v 0.343064 -1.325241 0.727260 +v 0.333998 -1.514324 0.637736 +v 0.336268 -1.522668 0.635090 +v 0.333998 -1.514324 0.637736 +v 0.336268 -1.522668 0.635090 +v 0.336268 -1.522668 0.635090 +v 0.341878 -1.526243 0.634269 +v 0.341878 -1.526243 0.634269 +v 0.344803 -1.317589 0.704434 +v 0.339098 -1.320797 0.702974 +v 0.344803 -1.317589 0.704434 +v 0.339098 -1.320797 0.702974 +v 0.339098 -1.320797 0.702974 +v 0.336596 -1.328985 0.700060 +v 0.336596 -1.328985 0.700060 +v 0.577281 -1.437210 0.705463 +v 0.572856 -1.437508 0.706526 +v 0.577281 -1.437210 0.705463 +v 0.574794 -1.428980 0.681087 +v 0.579020 -1.429558 0.682637 +v 0.579020 -1.429558 0.682637 +v 0.335284 -1.421655 0.668897 +v 0.339709 -1.421356 0.667835 +v 0.335284 -1.421655 0.668897 +v 0.337771 -1.429885 0.693274 +v 0.333546 -1.429307 0.691723 +v 0.333546 -1.429307 0.691723 +vt 0.295417 0.028463 +vt 0.295672 0.028386 +vt 0.295623 0.028249 +vt 0.279979 0.028235 +vt 0.280076 0.028394 +vt 0.280125 0.028257 +vt 0.662406 0.030730 +vt 0.662661 0.030807 +vt 0.662455 0.030593 +vt 0.295769 0.011305 +vt 0.295672 0.011146 +vt 0.295623 0.011283 +vt 0.662309 0.030571 +vt 0.677746 0.030815 +vt 0.678002 0.030738 +vt 0.677953 0.030601 +vt 0.678099 0.030579 +vt 0.280331 0.011077 +vt 0.280076 0.011154 +vt 0.280125 0.011291 +vt 0.662661 0.013393 +vt 0.662406 0.013470 +vt 0.662455 0.013608 +vt 0.662309 0.013629 +vt 0.678099 0.013638 +vt 0.678002 0.013478 +vt 0.677953 0.013616 +vt 0.677746 0.013401 +vt 0.671778 0.029157 +vt 0.670971 0.028939 +vt 0.670486 0.029895 +vt 0.670637 0.028412 +vt 0.676889 0.028415 +vt 0.676555 0.028942 +vt 0.677384 0.029831 +vt 0.675748 0.029159 +vt 0.675748 0.015055 +vt 0.676555 0.015273 +vt 0.677384 0.014385 +vt 0.676889 0.015800 +vt 0.670637 0.015797 +vt 0.670971 0.015271 +vt 0.670486 0.014314 +vt 0.671778 0.015053 +vt 0.286300 0.012727 +vt 0.287106 0.012944 +vt 0.287592 0.011988 +vt 0.287441 0.013470 +vt 0.281189 0.013473 +vt 0.281523 0.012947 +vt 0.280693 0.012059 +vt 0.282330 0.012729 +vt 0.282330 0.026817 +vt 0.281523 0.026599 +vt 0.280693 0.027488 +vt 0.281189 0.026073 +vt 0.287441 0.026070 +vt 0.287106 0.026597 +vt 0.287592 0.027552 +vt 0.286300 0.026815 +vt 0.293418 0.012723 +vt 0.294225 0.012940 +vt 0.295054 0.012052 +vt 0.294559 0.013466 +vt 0.288307 0.013470 +vt 0.288641 0.012943 +vt 0.288156 0.011988 +vt 0.289448 0.012725 +vt 0.289448 0.026813 +vt 0.288641 0.026596 +vt 0.288156 0.027552 +vt 0.288307 0.026070 +vt 0.294559 0.026066 +vt 0.294225 0.026593 +vt 0.295054 0.027481 +vt 0.293418 0.026811 +vt 0.664660 0.029154 +vt 0.663853 0.028935 +vt 0.663023 0.029824 +vt 0.663519 0.028408 +vt 0.669771 0.028411 +vt 0.669436 0.028938 +vt 0.669922 0.029895 +vt 0.668630 0.029156 +vt 0.668630 0.015051 +vt 0.669436 0.015270 +vt 0.669922 0.014313 +vt 0.669771 0.015797 +vt 0.663519 0.015794 +vt 0.663853 0.015267 +vt 0.663023 0.014377 +vt 0.664660 0.015049 +vt 0.295769 0.028227 +vt 0.280331 0.028471 +vt 0.295417 0.011069 +vt 0.279979 0.011313 +vt 0.670204 0.013394 +vt 0.670204 0.030814 +vt 0.287874 0.011070 +vt 0.287874 0.028470 +vt 0.281189 0.013473 +vt 0.280693 0.027488 +vt 0.280693 0.012059 +vt 0.280125 0.028257 +vt 0.280125 0.011291 +vt 0.677746 0.030815 +vt 0.675748 0.029159 +vt 0.677384 0.029831 +vt 0.677953 0.030601 +vt 0.280331 0.011077 +vt 0.282330 0.012729 +vt 0.670486 0.029895 +vt 0.670204 0.013394 +vt 0.670486 0.014314 +vt 0.662661 0.013393 +vt 0.663023 0.014377 +vt 0.662455 0.013608 +vt 0.668630 0.015051 +vt 0.669922 0.014313 +vt 0.663023 0.029824 +vt 0.662661 0.030807 +vt 0.662455 0.030593 +vt 0.670204 0.030814 +vt 0.668630 0.029156 +vt 0.669922 0.029895 +vt 0.295054 0.012052 +vt 0.295417 0.011069 +vt 0.295623 0.011283 +vt 0.287874 0.011070 +vt 0.289448 0.012725 +vt 0.288156 0.011988 +vt 0.282330 0.026817 +vt 0.280331 0.028471 +vt 0.675748 0.015055 +vt 0.677746 0.013401 +vt 0.677384 0.014385 +vt 0.677953 0.013616 +vt 0.295769 0.011305 +vt 0.295623 0.028249 +vt 0.295054 0.027481 +vt 0.287592 0.027552 +vt 0.287592 0.011988 +vt 0.669771 0.015797 +vt 0.662309 0.013629 +vt 0.676889 0.015800 +vt 0.295417 0.028463 +vt 0.289448 0.026813 +vt 0.287874 0.028470 +vt 0.288156 0.027552 +vt 0.288307 0.013470 +vt 0.295672 0.028386 +vt 0.279979 0.028235 +vt 0.280076 0.028394 +vt 0.662406 0.030730 +vt 0.295672 0.011146 +vt 0.662309 0.030571 +vt 0.678002 0.030738 +vt 0.678099 0.030579 +vt 0.280076 0.011154 +vt 0.662406 0.013470 +vt 0.678099 0.013638 +vt 0.678002 0.013478 +vt 0.671778 0.029157 +vt 0.670971 0.028939 +vt 0.670637 0.028412 +vt 0.676889 0.028415 +vt 0.676555 0.028942 +vt 0.676555 0.015273 +vt 0.670637 0.015797 +vt 0.670971 0.015271 +vt 0.671778 0.015053 +vt 0.286300 0.012727 +vt 0.287106 0.012944 +vt 0.287441 0.013470 +vt 0.281523 0.012947 +vt 0.281523 0.026599 +vt 0.281189 0.026073 +vt 0.287441 0.026070 +vt 0.287106 0.026597 +vt 0.286300 0.026815 +vt 0.293418 0.012723 +vt 0.294225 0.012940 +vt 0.294559 0.013466 +vt 0.288641 0.012943 +vt 0.288641 0.026596 +vt 0.288307 0.026070 +vt 0.294559 0.026066 +vt 0.294225 0.026593 +vt 0.293418 0.026811 +vt 0.664660 0.029154 +vt 0.663853 0.028935 +vt 0.663519 0.028408 +vt 0.669771 0.028411 +vt 0.669436 0.028938 +vt 0.669436 0.015270 +vt 0.663519 0.015794 +vt 0.663853 0.015267 +vt 0.664660 0.015049 +vt 0.295769 0.028227 +vt 0.279979 0.011313 +vt 0.425727 0.048247 +vt 0.425727 0.055349 +vt 0.427019 0.055349 +vt 0.427019 0.048247 +vt 0.489381 0.014266 +vt 0.489381 0.001652 +vt 0.487391 0.001635 +vt 0.487391 0.014249 +vt 0.425725 0.063257 +vt 0.427017 0.063257 +vt 0.427019 0.062451 +vt 0.425727 0.062451 +vt 0.485322 0.014266 +vt 0.485322 0.001652 +vt 0.483332 0.001635 +vt 0.483332 0.014250 +vt 0.099014 0.075173 +vt 0.099014 0.071204 +vt 0.097024 0.071204 +vt 0.097024 0.075173 +vt 0.485361 0.001652 +vt 0.485362 0.014266 +vt 0.487351 0.014250 +vt 0.487351 0.001635 +vt 0.416955 0.012547 +vt 0.416955 0.019649 +vt 0.418247 0.019649 +vt 0.418247 0.012547 +vt 0.188500 0.037259 +vt 0.188500 0.041228 +vt 0.190490 0.041228 +vt 0.190490 0.037259 +vt 0.974852 0.412112 +vt 0.974852 0.408143 +vt 0.972862 0.408143 +vt 0.972862 0.412112 +vt 0.416955 0.005445 +vt 0.418247 0.005445 +vt 0.186467 0.037259 +vt 0.186467 0.041228 +vt 0.188457 0.041228 +vt 0.188457 0.037259 +vt 0.491410 0.014250 +vt 0.491410 0.001635 +vt 0.489420 0.001652 +vt 0.489420 0.014266 +vt 0.427017 0.047441 +vt 0.425725 0.047441 +vt 0.880832 0.129067 +vt 0.880832 0.145904 +vt 0.882124 0.145915 +vt 0.882124 0.129078 +vt 0.859242 0.171052 +vt 0.857950 0.171063 +vt 0.857950 0.171589 +vt 0.859242 0.171578 +vt 0.880832 0.146431 +vt 0.882124 0.146442 +vt 0.416953 0.020455 +vt 0.418245 0.020455 +vt 0.882124 0.128551 +vt 0.880832 0.128540 +vt 0.857950 0.154226 +vt 0.859242 0.154215 +vt 0.418245 0.004639 +vt 0.416953 0.004639 +vt 0.859242 0.153688 +vt 0.857950 0.153699 +vt 0.099015 0.070398 +vt 0.097026 0.070398 +vt 0.487351 0.001108 +vt 0.485362 0.001125 +vt 0.188458 0.036452 +vt 0.186469 0.036452 +vt 0.485362 0.014793 +vt 0.487351 0.014776 +vt 0.487391 0.014776 +vt 0.489381 0.014793 +vt 0.186469 0.042034 +vt 0.188458 0.042034 +vt 0.097026 0.075980 +vt 0.099015 0.075980 +vt 0.489381 0.001125 +vt 0.487391 0.001108 +vt 0.188498 0.042034 +vt 0.190488 0.042034 +vt 0.489420 0.014793 +vt 0.491410 0.014776 +vt 0.972860 0.412919 +vt 0.974850 0.412919 +vt 0.491410 0.001108 +vt 0.489420 0.001125 +vt 0.483332 0.014776 +vt 0.485322 0.014793 +vt 0.974850 0.407337 +vt 0.972860 0.407337 +vt 0.190488 0.036452 +vt 0.188498 0.036452 +vt 0.485322 0.001125 +vt 0.483332 0.001108 +vt 0.425478 0.047473 +vt 0.425479 0.048119 +vt 0.295106 0.028791 +vt 0.295751 0.028614 +vt 0.882371 0.129065 +vt 0.882371 0.128645 +vt 0.296016 0.028196 +vt 0.859488 0.171484 +vt 0.859488 0.171065 +vt 0.279732 0.028204 +vt 0.279997 0.028623 +vt 0.425479 0.062579 +vt 0.425478 0.063224 +vt 0.280642 0.028799 +vt 0.880585 0.128630 +vt 0.880585 0.129050 +vt 0.662062 0.030533 +vt 0.662327 0.030952 +vt 0.427265 0.048119 +vt 0.427263 0.047474 +vt 0.662972 0.031129 +vt 0.427263 0.063224 +vt 0.427265 0.062579 +vt 0.677436 0.031137 +vt 0.678081 0.030960 +vt 0.857703 0.171080 +vt 0.857703 0.171499 +vt 0.678346 0.030541 +vt 0.882371 0.146351 +vt 0.882371 0.145932 +vt 0.296016 0.011347 +vt 0.295751 0.010929 +vt 0.418492 0.005317 +vt 0.418491 0.004672 +vt 0.295106 0.010752 +vt 0.418491 0.020423 +vt 0.418492 0.019778 +vt 0.280642 0.010760 +vt 0.279997 0.010937 +vt 0.859488 0.154197 +vt 0.859488 0.153778 +vt 0.279732 0.011356 +vt 0.416706 0.004672 +vt 0.416707 0.005317 +vt 0.662972 0.013070 +vt 0.662327 0.013246 +vt 0.880585 0.145917 +vt 0.880585 0.146336 +vt 0.662062 0.013665 +vt 0.857703 0.153793 +vt 0.857703 0.154212 +vt 0.678346 0.013674 +vt 0.678081 0.013254 +vt 0.416707 0.019778 +vt 0.416706 0.020423 +vt 0.677436 0.013077 +vt 0.287874 0.028796 +vt 0.425479 0.055349 +vt 0.670204 0.031134 +vt 0.427265 0.055349 +vt 0.670204 0.013073 +vt 0.416707 0.012547 +vt 0.287874 0.010755 +vt 0.418492 0.012547 +vt 0.425727 0.048247 +vt 0.427019 0.048247 +vt 0.427019 0.055349 +vt 0.425727 0.055349 +vt 0.489381 0.014266 +vt 0.487391 0.014249 +vt 0.487391 0.001635 +vt 0.489381 0.001652 +vt 0.425725 0.063257 +vt 0.425727 0.062451 +vt 0.427019 0.062451 +vt 0.427017 0.063257 +vt 0.485322 0.014266 +vt 0.483332 0.014250 +vt 0.483332 0.001635 +vt 0.485322 0.001652 +vt 0.099014 0.075173 +vt 0.097024 0.075173 +vt 0.097024 0.071204 +vt 0.099014 0.071204 +vt 0.485361 0.001652 +vt 0.487351 0.001635 +vt 0.487351 0.014250 +vt 0.485362 0.014266 +vt 0.416955 0.012547 +vt 0.418247 0.012547 +vt 0.418247 0.019649 +vt 0.416955 0.019649 +vt 0.188500 0.037259 +vt 0.190490 0.037259 +vt 0.190490 0.041228 +vt 0.188500 0.041228 +vt 0.974852 0.412112 +vt 0.972862 0.412112 +vt 0.972862 0.408143 +vt 0.974852 0.408143 +vt 0.416955 0.005445 +vt 0.418247 0.005445 +vt 0.186467 0.037259 +vt 0.188457 0.037259 +vt 0.188457 0.041228 +vt 0.186467 0.041228 +vt 0.491410 0.014250 +vt 0.489420 0.014266 +vt 0.489420 0.001652 +vt 0.491410 0.001635 +vt 0.427017 0.047441 +vt 0.425725 0.047441 +vt 0.880832 0.129067 +vt 0.882124 0.129078 +vt 0.882124 0.145915 +vt 0.880832 0.145904 +vt 0.859242 0.171052 +vt 0.859242 0.171578 +vt 0.857950 0.171589 +vt 0.857950 0.171063 +vt 0.882124 0.146442 +vt 0.880832 0.146431 +vt 0.416953 0.020455 +vt 0.418245 0.020455 +vt 0.880832 0.128540 +vt 0.882124 0.128551 +vt 0.857950 0.154226 +vt 0.859242 0.154215 +vt 0.418245 0.004639 +vt 0.416953 0.004639 +vt 0.857950 0.153699 +vt 0.859242 0.153688 +vt 0.097026 0.070398 +vt 0.099015 0.070398 +vt 0.487351 0.001108 +vt 0.485362 0.001125 +vt 0.186469 0.036452 +vt 0.188458 0.036452 +vt 0.485362 0.014793 +vt 0.487351 0.014776 +vt 0.489381 0.014793 +vt 0.487391 0.014776 +vt 0.186469 0.042034 +vt 0.188458 0.042034 +vt 0.099015 0.075980 +vt 0.097026 0.075980 +vt 0.489381 0.001125 +vt 0.487391 0.001108 +vt 0.190488 0.042034 +vt 0.188498 0.042034 +vt 0.489420 0.014793 +vt 0.491410 0.014776 +vt 0.974850 0.412919 +vt 0.972860 0.412919 +vt 0.491410 0.001108 +vt 0.489420 0.001125 +vt 0.485322 0.014793 +vt 0.483332 0.014776 +vt 0.974850 0.407337 +vt 0.972860 0.407337 +vt 0.188498 0.036452 +vt 0.190488 0.036452 +vt 0.485322 0.001125 +vt 0.483332 0.001108 +vt 0.425479 0.048119 +vt 0.425478 0.047473 +vt 0.295106 0.028791 +vt 0.295751 0.028614 +vt 0.882371 0.128645 +vt 0.882371 0.129065 +vt 0.296016 0.028196 +vt 0.859488 0.171065 +vt 0.859488 0.171484 +vt 0.279732 0.028204 +vt 0.279997 0.028623 +vt 0.425478 0.063224 +vt 0.425479 0.062579 +vt 0.280642 0.028799 +vt 0.880585 0.129050 +vt 0.880585 0.128630 +vt 0.662062 0.030533 +vt 0.662327 0.030952 +vt 0.427263 0.047474 +vt 0.427265 0.048119 +vt 0.662972 0.031129 +vt 0.427265 0.062579 +vt 0.427263 0.063224 +vt 0.677436 0.031137 +vt 0.678081 0.030960 +vt 0.857703 0.171499 +vt 0.857703 0.171080 +vt 0.678346 0.030541 +vt 0.882371 0.145932 +vt 0.882371 0.146351 +vt 0.296016 0.011347 +vt 0.295751 0.010929 +vt 0.418491 0.004672 +vt 0.418492 0.005317 +vt 0.295106 0.010752 +vt 0.418492 0.019778 +vt 0.418491 0.020423 +vt 0.280642 0.010760 +vt 0.279997 0.010937 +vt 0.859488 0.153778 +vt 0.859488 0.154197 +vt 0.279732 0.011356 +vt 0.416707 0.005317 +vt 0.416706 0.004672 +vt 0.662972 0.013070 +vt 0.662327 0.013246 +vt 0.880585 0.146336 +vt 0.880585 0.145917 +vt 0.662062 0.013665 +vt 0.857703 0.154212 +vt 0.857703 0.153793 +vt 0.678346 0.013674 +vt 0.678081 0.013254 +vt 0.416706 0.020423 +vt 0.416707 0.019778 +vt 0.677436 0.013077 +vt 0.287874 0.028796 +vt 0.425479 0.055349 +vt 0.670204 0.031134 +vt 0.427265 0.055349 +vt 0.670204 0.013073 +vt 0.416707 0.012547 +vt 0.287874 0.010755 +vt 0.418492 0.012547 +vn -0.0951 -0.3604 0.9279 +vn -0.0890 -0.4794 0.8731 +vn 0.1103 -0.3175 0.9418 +vn 0.0167 -0.0849 0.9962 +vn -0.0871 -0.1455 0.9855 +vn 0.1104 -0.3176 0.9418 +vn -0.3029 0.1325 -0.9438 +vn -0.3121 0.2601 -0.9138 +vn -0.1104 0.3175 -0.9418 +vn 0.1975 -0.5297 0.8249 +vn 0.3012 -0.4675 0.8311 +vn 0.1104 -0.3174 0.9418 +vn -0.1998 0.0781 -0.9767 +vn -0.3029 0.1323 -0.9438 +vn -0.3116 0.3478 -0.8843 +vn -0.3011 0.4677 -0.8310 +vn -0.1104 0.3174 -0.9418 +vn -0.3012 0.4677 -0.8310 +vn -0.1974 0.5298 -0.8248 +vn 0.3121 -0.2600 0.9138 +vn 0.3029 -0.1323 0.9438 +vn 0.1105 -0.3174 0.9418 +vn 0.0944 0.2732 -0.9573 +vn 0.0872 0.1453 -0.9855 +vn 0.0871 0.1453 -0.9855 +vn -0.0167 0.0846 -0.9963 +vn -0.1105 0.3176 -0.9418 +vn -0.0144 0.5349 -0.8448 +vn 0.0887 0.4792 -0.8732 +vn -0.1106 0.3175 -0.9418 +vn 0.0889 0.4793 -0.8731 +vn 0.0949 0.3603 -0.9280 +vn -0.1105 0.3173 -0.9419 +vn 0.5804 0.3396 -0.7401 +vn 0.3934 0.6056 -0.6917 +vn 0.3934 0.6055 -0.6918 +vn 0.0928 0.8254 -0.5569 +vn 0.0868 -0.3217 -0.9429 +vn 0.3900 -0.0675 -0.9183 +vn 0.5796 0.1720 -0.7965 +vn -0.7494 0.1279 -0.6497 +vn -0.5730 -0.1027 -0.8131 +vn -0.2628 -0.3350 -0.9048 +vn -0.2570 0.8161 -0.5176 +vn -0.5697 0.5782 -0.5841 +vn -0.5696 0.5783 -0.5841 +vn -0.7486 0.2973 -0.5927 +vn -0.5796 -0.1720 0.7965 +vn -0.3901 0.0675 0.9183 +vn -0.3900 0.0675 0.9183 +vn -0.0869 0.3217 0.9429 +vn -0.0927 -0.8254 0.5569 +vn -0.3934 -0.6056 0.6918 +vn -0.3934 -0.6055 0.6918 +vn -0.5804 -0.3396 0.7401 +vn 0.7486 -0.2973 0.5926 +vn 0.5696 -0.5783 0.5840 +vn 0.1104 -0.3175 0.9418 +vn 0.5697 -0.5782 0.5841 +vn 0.2569 -0.8162 0.5175 +vn 0.2628 0.3350 0.9048 +vn 0.5730 0.1027 0.8131 +vn 0.7494 -0.1278 0.6496 +vn -0.0868 0.3217 0.9429 +vn -0.0926 -0.8254 0.5568 +vn -0.5804 -0.3397 0.7401 +vn 0.7486 -0.2972 0.5927 +vn 0.5697 -0.5783 0.5840 +vn 0.2568 -0.8162 0.5175 +vn 0.2627 0.3351 0.9048 +vn 0.5730 0.1028 0.8131 +vn 0.7494 -0.1278 0.6497 +vn 0.5804 0.3397 -0.7401 +vn -0.7494 0.1278 -0.6497 +vn -0.2569 0.8162 -0.5175 +vn -0.5696 0.5783 -0.5840 +vn -0.7486 0.2972 -0.5927 +vn -0.0890 -0.4796 0.8730 +vn 0.0142 -0.5352 0.8446 +vn -0.0872 -0.1451 0.9856 +vn -0.0945 -0.2731 0.9573 +vn 0.3011 -0.4677 0.8310 +vn 0.3116 -0.3478 0.8843 +vn 0.3029 -0.1326 0.9437 +vn 0.1999 -0.0785 0.9767 +vn -0.0927 -0.8254 0.5568 +vn 0.5796 0.1721 -0.7965 +vn -0.3116 0.3479 -0.8843 +vn 0.3120 -0.2601 0.9138 +vn 0.3120 -0.2600 0.9138 +vn 0.0427 0.3186 -0.9469 +vn 0.0427 0.3185 -0.9470 +vn -0.3121 0.2602 -0.9137 +vn -0.1105 0.3175 -0.9418 +vn -0.2617 0.3090 -0.9144 +vn 0.3116 -0.3479 0.8843 +vn 0.2617 -0.3089 0.9144 +vn -0.0944 -0.2732 0.9573 +vn 0.1974 -0.5297 0.8249 +vn 0.2617 -0.3090 0.9144 +vn -0.2628 -0.3348 -0.9049 +vn -0.1104 0.3179 -0.9417 +vn -0.0168 0.0848 -0.9963 +vn -0.1104 0.3176 -0.9418 +vn -0.2628 -0.3351 -0.9048 +vn -0.0949 -0.3604 0.9279 +vn -0.0427 -0.3185 0.9470 +vn 0.7486 -0.2972 0.5926 +vn -0.0927 -0.8252 0.5571 +vn 0.1191 -0.8256 0.5515 +vn -0.0636 -0.3173 0.9462 +vn 0.2675 0.3473 -0.8988 +vn -0.6185 0.1732 -0.7665 +vn 0.0636 0.3173 -0.9462 +vn 0.2675 0.3472 -0.8988 +vn -0.2663 -0.2596 0.9283 +vn 0.6162 -0.3407 0.7101 +vn -0.2663 -0.2595 0.9283 +vn -0.0896 0.3187 -0.9436 +vn -0.1418 0.2734 -0.9514 +vn 0.7161 0.1266 -0.6864 +vn -0.0895 0.3186 -0.9436 +vn 0.2663 0.2596 -0.9283 +vn 0.2161 0.3086 -0.9263 +vn -0.2675 -0.3473 0.8988 +vn -0.2161 -0.3085 0.9264 +vn 0.6161 -0.3407 0.7101 +vn -0.0637 -0.3173 0.9462 +vn -0.7185 -0.2959 0.6295 +vn 0.1418 -0.2734 0.9514 +vn 0.7161 0.1265 -0.6865 +vn -0.1406 0.3605 -0.9221 +vn -0.1407 0.3605 -0.9221 +vn -0.1568 -0.5293 0.8338 +vn -0.2161 -0.3085 0.9263 +vn 0.2165 -0.3353 -0.9169 +vn 0.0636 0.3174 -0.9461 +vn -0.0331 0.0848 -0.9959 +vn 0.2165 -0.3355 -0.9168 +vn 0.1407 -0.3607 0.9220 +vn 0.0896 -0.3186 0.9437 +vn 0.1190 -0.8254 0.5518 +vn -0.0636 -0.3169 0.9463 +vn 0.1406 -0.3606 0.9221 +vn 0.1316 -0.4794 0.8677 +vn 0.0330 -0.0848 0.9959 +vn 0.1361 -0.1455 0.9800 +vn 0.2555 0.1320 -0.9578 +vn -0.1567 -0.5294 0.8338 +vn -0.0635 -0.3172 0.9462 +vn -0.2599 -0.4672 0.8451 +vn 0.1506 0.0781 -0.9855 +vn 0.2674 0.3473 -0.8988 +vn 0.2600 0.4672 -0.8450 +vn 0.1568 0.5294 -0.8337 +vn -0.2664 -0.2595 0.9283 +vn -0.2554 -0.1320 0.9578 +vn -0.1418 0.2735 -0.9514 +vn 0.0636 0.3174 -0.9462 +vn -0.1362 0.1456 -0.9799 +vn -0.0331 0.0847 -0.9959 +vn -0.0271 0.5350 -0.8444 +vn 0.0637 0.3172 -0.9462 +vn -0.1316 0.4794 -0.8677 +vn -0.6162 0.3407 -0.7101 +vn -0.4265 0.6063 -0.6712 +vn -0.1191 0.8257 -0.5514 +vn -0.1346 -0.3215 -0.9373 +vn -0.4357 -0.0668 -0.8976 +vn -0.6185 0.1731 -0.7665 +vn 0.7161 0.1265 -0.6864 +vn 0.5314 -0.1037 -0.8408 +vn 0.2321 0.8157 -0.5299 +vn 0.5407 0.5773 -0.6119 +vn 0.7185 0.2959 -0.6295 +vn 0.6185 -0.1731 0.7665 +vn 0.4357 0.0668 0.8976 +vn 0.1346 0.3214 0.9373 +vn 0.1191 -0.8256 0.5516 +vn 0.4265 -0.6063 0.6712 +vn -0.7185 -0.2960 0.6295 +vn -0.5407 -0.5773 0.6119 +vn -0.2322 -0.8157 0.5298 +vn -0.2165 0.3355 0.9168 +vn -0.5314 0.1036 0.8408 +vn -0.7161 -0.1265 0.6864 +vn 0.1346 0.3215 0.9373 +vn 0.1190 -0.8256 0.5516 +vn -0.2320 -0.8159 0.5296 +vn -0.5314 0.1037 0.8408 +vn -0.1191 0.8256 -0.5515 +vn -0.1346 -0.3214 -0.9373 +vn -0.6185 0.1730 -0.7665 +vn 0.5313 -0.1037 -0.8408 +vn 0.2165 -0.3354 -0.9169 +vn 0.2321 0.8158 -0.5298 +vn 0.0271 -0.5350 0.8444 +vn -0.1507 -0.0781 0.9855 +vn -0.9360 -0.2084 0.2835 +vn -0.9338 -0.1102 0.3403 +vn -0.9916 0.0454 -0.1211 +vn -0.9885 -0.0671 -0.1352 +vn 0.2570 -0.8162 0.5175 +vn -0.7700 0.4640 0.4381 +vn -0.8105 0.5753 0.1106 +vn -0.9875 0.1438 -0.0645 +vn -0.9352 0.0022 0.3542 +vn 0.2628 0.3351 0.9048 +vn -0.2570 0.8162 -0.5175 +vn 0.9338 0.1101 -0.3403 +vn 0.9361 0.2080 -0.2835 +vn 0.9885 0.0673 0.1354 +vn 0.9916 -0.0454 0.1211 +vn -0.5796 -0.1721 0.7965 +vn 0.9351 -0.0024 -0.3545 +vn 0.9876 -0.1434 0.0643 +vn -0.0869 0.3217 0.9428 +vn -0.8158 -0.5180 -0.2573 +vn -0.7753 -0.6276 0.0706 +vn -0.2850 -0.8516 -0.4398 +vn 0.2363 -0.8339 -0.4988 +vn 0.2759 -0.9469 -0.1653 +vn -0.2456 -0.9636 -0.1054 +vn -0.2362 0.8337 0.4991 +vn -0.2759 0.9468 0.1656 +vn -0.8104 0.5753 0.1105 +vn -0.7700 0.4638 0.4381 +vn 0.7700 -0.4639 -0.4381 +vn 0.8104 -0.5753 -0.1105 +vn 0.7753 0.6276 -0.0707 +vn 0.8158 0.5180 0.2573 +vn -0.7753 -0.6276 0.0707 +vn 0.2454 0.9636 0.1057 +vn 0.2851 0.8517 0.4397 +vn 0.8105 -0.5753 -0.1105 +vn 0.5731 0.1026 0.8131 +vn 0.3900 -0.0674 -0.9183 +vn 0.3901 -0.0674 -0.9183 +vn -0.3933 -0.6056 0.6918 +vn -0.5364 -0.6599 0.5261 +vn -0.5969 -0.3492 0.7224 +vn -0.5969 -0.3492 0.7223 +vn -0.5364 -0.6598 0.5262 +vn -0.0889 -0.4791 0.8732 +vn -0.0949 -0.3604 0.9280 +vn -0.1455 -0.9007 0.4094 +vn -0.5364 -0.6599 0.5262 +vn -0.1455 -0.9008 0.4091 +vn 0.0143 -0.5351 0.8447 +vn -0.5321 0.2120 0.8197 +vn -0.1384 0.4714 0.8710 +vn -0.0871 -0.1454 0.9855 +vn 0.0168 -0.0847 0.9963 +vn -0.5959 -0.1536 0.7882 +vn -0.5321 0.2121 0.8197 +vn -0.5960 -0.1535 0.7882 +vn -0.6828 -0.2531 -0.6854 +vn -0.2919 -0.4867 -0.8233 +vn -0.2919 -0.4865 -0.8235 +vn -0.6828 -0.2531 -0.6853 +vn -0.1998 0.0784 -0.9767 +vn -0.7621 0.1085 -0.6383 +vn -0.6785 0.6219 -0.3910 +vn -0.7610 0.3058 -0.5721 +vn -0.7612 0.3058 -0.5719 +vn -0.6785 0.6219 -0.3911 +vn -0.3012 0.4676 -0.8310 +vn -0.3118 0.3480 -0.8841 +vn -0.2849 0.8880 -0.3610 +vn -0.6785 0.6220 -0.3909 +vn -0.2848 0.8880 -0.3610 +vn -0.1974 0.5298 -0.8249 +vn 0.6785 -0.6219 0.3909 +vn 0.2849 -0.8881 0.3608 +vn 0.2849 -0.8880 0.3610 +vn 0.3012 -0.4677 0.8310 +vn 0.1975 -0.5297 0.8248 +vn 0.7612 -0.3058 0.5719 +vn 0.6785 -0.6219 0.3910 +vn 0.3117 -0.3479 0.8842 +vn 0.6828 0.2532 0.6853 +vn 0.7621 -0.1085 0.6383 +vn 0.6828 0.2531 0.6854 +vn 0.3029 -0.1327 0.9438 +vn 0.2919 0.4865 0.8235 +vn 0.2918 0.4867 0.8234 +vn 0.1998 -0.0783 0.9767 +vn 0.5320 -0.2120 -0.8197 +vn 0.5960 0.1536 -0.7882 +vn 0.5960 0.1535 -0.7882 +vn 0.5321 -0.2121 -0.8197 +vn 0.0871 0.1455 -0.9855 +vn 0.0945 0.2733 -0.9573 +vn 0.1384 -0.4715 -0.8710 +vn 0.5320 -0.2120 -0.8198 +vn 0.1385 -0.4714 -0.8710 +vn -0.0167 0.0847 -0.9963 +vn 0.5364 0.6598 -0.5263 +vn 0.1455 0.9007 -0.4094 +vn 0.1455 0.9007 -0.4093 +vn 0.0888 0.4792 -0.8732 +vn -0.0144 0.5350 -0.8447 +vn 0.5968 0.3492 -0.7224 +vn 0.5363 0.6598 -0.5263 +vn 0.5969 0.3492 -0.7223 +vn -0.5457 -0.2650 0.7950 +vn -0.2617 0.3089 -0.9144 +vn -0.7214 0.2239 -0.6553 +vn -0.7213 0.2239 -0.6555 +vn 0.5457 0.2650 -0.7950 +vn 0.7213 -0.2239 0.6554 +vn 0.9487 -0.2101 0.2363 +vn 0.9804 -0.0688 -0.1845 +vn 0.9844 0.0436 -0.1706 +vn 0.9495 -0.1118 0.2931 +vn -0.2321 -0.8158 0.5297 +vn 0.7918 0.4626 0.3989 +vn 0.9518 0.0005 0.3069 +vn 0.9833 0.1420 -0.1139 +vn 0.8160 0.5738 0.0696 +vn -0.2320 -0.8158 0.5298 +vn 0.2164 -0.3355 -0.9169 +vn -0.1191 0.8256 -0.5516 +vn -0.9495 0.1118 -0.2931 +vn -0.9844 -0.0436 0.1707 +vn -0.9803 0.0690 0.1849 +vn -0.9488 0.2097 -0.2362 +vn -0.9517 -0.0008 -0.3071 +vn -0.9834 -0.1417 0.1138 +vn 0.7161 0.1264 -0.6864 +vn 0.8009 -0.5194 -0.2979 +vn 0.7768 -0.6290 0.0317 +vn 0.2611 -0.8521 -0.4535 +vn 0.2383 -0.9640 -0.1176 +vn -0.2855 -0.9464 -0.1512 +vn -0.2625 -0.8334 -0.4863 +vn 0.2624 0.8333 0.4866 +vn 0.7918 0.4624 0.3989 +vn 0.8160 0.5739 0.0697 +vn 0.2855 0.9463 0.1514 +vn -0.8160 -0.5738 -0.0698 +vn -0.7918 -0.4626 -0.3989 +vn -0.7767 0.6290 -0.0317 +vn -0.8009 0.5194 0.2979 +vn 0.7767 -0.6290 0.0317 +vn -0.2380 0.9641 0.1179 +vn -0.2612 0.8522 0.4533 +vn -0.7918 -0.4625 -0.3989 +vn -0.7768 0.6290 -0.0318 +vn 0.4357 0.0667 0.8976 +vn 0.4265 -0.6062 0.6712 +vn -0.5407 -0.5773 0.6118 +vn -0.4357 -0.0667 -0.8976 +vn -0.5407 -0.5772 0.6119 +vn 0.5407 0.5772 -0.6119 +vn -0.4265 0.6062 -0.6712 +vn -0.4265 0.6062 -0.6713 +vn 0.6317 -0.3503 0.6916 +vn 0.5609 -0.6609 0.4986 +vn 0.6318 -0.3503 0.6915 +vn 0.5609 -0.6608 0.4987 +vn 0.1642 -0.9010 0.4015 +vn 0.1642 -0.9011 0.4013 +vn 0.1828 0.4711 0.8629 +vn 0.5729 0.2110 0.7920 +vn 0.5729 0.2111 0.7920 +vn 0.6344 -0.1547 0.7574 +vn 0.6345 -0.1547 0.7573 +vn 0.2494 -0.4872 -0.8369 +vn 0.6471 -0.2543 -0.7187 +vn 0.2494 -0.4870 -0.8371 +vn 0.6472 -0.2543 -0.7187 +vn 0.7294 0.1072 -0.6757 +vn 0.7293 0.1072 -0.6757 +vn 0.7321 0.3045 -0.6093 +vn 0.6592 0.6207 -0.4246 +vn 0.7320 0.3045 -0.6094 +vn 0.6591 0.6207 -0.4246 +vn 0.2679 0.8875 -0.3748 +vn 0.2680 0.8875 -0.3749 +vn -0.2680 -0.8876 0.3747 +vn -0.6592 -0.6208 0.4244 +vn -0.2679 -0.8875 0.3749 +vn -0.6592 -0.6207 0.4245 +vn -0.7321 -0.3045 0.6094 +vn -0.7293 -0.1073 0.6758 +vn -0.6471 0.2543 0.7187 +vn -0.7293 -0.1072 0.6757 +vn -0.2494 0.4872 0.8369 +vn -0.2494 0.4871 0.8370 +vn -0.6345 0.1546 -0.7573 +vn -0.5729 -0.2111 -0.7920 +vn -0.6344 0.1546 -0.7573 +vn -0.5728 -0.2111 -0.7920 +vn -0.1828 -0.4712 -0.8629 +vn -0.1828 -0.4711 -0.8629 +vn -0.1642 0.9010 -0.4015 +vn -0.5609 0.6608 -0.4987 +vn -0.1642 0.9010 -0.4014 +vn -0.5609 0.6608 -0.4988 +vn -0.6317 0.3503 -0.6915 +vn 0.5844 -0.2660 0.7667 +vn 0.0896 -0.3186 0.9436 +vn 0.5844 -0.2660 0.7666 +vn 0.2161 0.3085 -0.9264 +vn 0.6880 0.2227 -0.6907 +vn 0.6880 0.2227 -0.6908 +vn -0.5844 0.2660 -0.7666 +vn -0.0896 0.3186 -0.9436 +vn -0.5843 0.2660 -0.7667 +vn -0.6880 -0.2226 0.6908 +vn -0.6879 -0.2227 0.6908 +vn -0.0928 -0.8254 0.5569 +vn 0.1104 -0.3173 0.9419 +vn -0.1104 0.3174 -0.9419 +vn 0.0928 0.8255 -0.5567 +vn 0.1104 -0.3174 0.9419 +vn -0.0869 0.3216 0.9429 +vn -0.0868 0.3217 0.9428 +vn -0.2628 -0.3349 -0.9049 +vn 0.0868 -0.3216 -0.9429 +vn 0.0927 0.8255 -0.5568 +vn 0.2569 -0.8163 0.5174 +vn -0.0896 0.3186 -0.9437 +vn 0.2165 -0.3354 -0.9168 +vn 0.1190 -0.8257 0.5514 +usemtl Scene_-_Root +s off +f 18288/18288/13069 18289/18289/13070 18290/18290/13071 +f 18291/18291/13072 18292/18292/13073 18293/18293/13074 +f 18294/18294/13075 18295/18295/13076 18296/18296/13077 +f 18297/18297/13078 18298/18298/13079 18299/18299/13080 +f 18300/18300/13081 18294/18294/13082 18296/18296/13077 +f 18301/18301/13083 18302/18302/13084 18303/18303/13085 +f 18302/18302/13086 18304/18304/13087 18303/18303/13077 +f 18305/18305/13088 18306/18306/13089 18307/18307/13090 +f 18308/18308/13091 18309/18309/13092 18310/18310/13077 +f 18309/18309/13093 18311/18311/13094 18310/18310/13095 +f 18312/18312/13096 18313/18313/13097 18314/18314/13098 +f 18313/18313/13099 18315/18315/13100 18314/18314/13101 +f 18316/18316/13102 18317/18317/13103 18318/18318/13085 +f 18317/18317/13104 18319/18319/13105 18318/18318/13077 +f 18320/18320/13106 18321/18321/13107 18322/18322/13077 +f 18321/18321/13107 18323/18323/13108 18322/18322/13077 +f 18324/18324/13109 18325/18325/13110 18326/18326/13085 +f 18325/18325/13110 18327/18327/13111 18326/18326/13085 +f 18328/18328/13112 18329/18329/13113 18330/18330/13085 +f 18329/18329/13114 18331/18331/13115 18330/18330/13077 +f 18332/18332/13116 18333/18333/13117 18334/18334/13080 +f 18333/18333/13118 18335/18335/13119 18334/18334/13080 +f 18336/18336/13120 18337/18337/13121 18338/18338/13080 +f 18337/18337/13122 18339/18339/13123 18338/18338/13080 +f 18340/18340/13124 18341/18341/13125 18342/18342/13126 +f 18341/18341/13127 18343/18343/13128 18342/18342/13080 +f 18344/18344/13129 18345/18345/13130 18346/18346/13080 +f 18345/18345/13130 18347/18347/13131 18346/18346/13080 +f 18348/18348/13116 18349/18349/13118 18350/18350/13080 +f 18349/18349/13118 18351/18351/13132 18350/18350/13080 +f 18352/18352/13133 18353/18353/13121 18354/18354/13080 +f 18353/18353/13122 18355/18355/13134 18354/18354/13080 +f 18356/18356/13135 18357/18357/13136 18358/18358/13080 +f 18357/18357/13125 18359/18359/13137 18358/18358/13126 +f 18360/18360/13138 18361/18361/13139 18362/18362/13126 +f 18361/18361/13130 18363/18363/13140 18362/18362/13080 +f 18364/18364/13141 18365/18365/13104 18366/18366/13077 +f 18365/18365/13104 18367/18367/13105 18366/18366/13085 +f 18368/18368/13106 18369/18369/13107 18370/18370/13077 +f 18369/18369/13107 18371/18371/13108 18370/18370/13085 +f 18372/18372/13142 18373/18373/13110 18374/18374/13085 +f 18373/18373/13110 18375/18375/13111 18374/18374/13077 +f 18376/18376/13143 18377/18377/13113 18378/18378/13085 +f 18377/18377/13144 18379/18379/13145 18378/18378/13077 +f 18289/18289/13146 18380/18380/13147 18290/18290/13071 +f 18292/18292/13148 18381/18381/13149 18293/18293/13126 +f 18298/18298/13150 18382/18382/13151 18299/18299/13080 +f 18306/18306/13152 18383/18383/13153 18307/18307/13080 +f 18342/18342/13126 18336/18336/13154 18338/18338/13126 +f 18342/18342/13080 18338/18338/13080 18293/18293/13080 +f 18293/18293/13080 18338/18338/13080 18307/18307/13080 +f 18323/18323/13155 18301/18301/13156 18322/18322/13077 +f 18322/18322/13077 18301/18301/13083 18303/18303/13077 +f 18339/18339/13123 18305/18305/13157 18338/18338/13126 +f 18338/18338/13080 18305/18305/13158 18307/18307/13080 +f 18642/18384/13159 18318/18318/13077 18330/18330/13077 +f 18378/18378/13077 18308/18308/13091 18310/18310/13077 +f 18642/18384/13160 18372/18372/13109 18374/18374/13085 +f 18295/18295/13161 18366/18366/13162 18296/18296/13162 +f 18371/18371/13155 18639/18385/13163 18370/18370/13085 +f 18382/18382/13164 18350/18350/13126 18299/18299/13126 +f 18355/18355/13134 18645/18386/13165 18354/18354/13126 +f 18381/18381/13166 18340/18340/13135 18342/18342/13080 +f 18381/18381/13166 18342/18342/13080 18293/18293/13080 +f 18315/18315/13100 18324/18324/13142 18326/18326/13085 +f 18315/18315/13100 18326/18326/13085 18314/18314/13085 +f 18290/18290/13080 18297/18297/13167 18299/18299/13080 +f 18290/18290/13126 18299/18299/13126 18362/18362/13126 +f 18362/18362/13080 18299/18299/13080 18350/18350/13080 +f 18346/18346/13126 18645/18386/13168 18334/18334/13126 +f 18375/18375/13169 18370/18370/13170 18374/18374/13170 +f 18311/18311/13171 18296/18296/13172 18310/18310/13172 +f 18310/18310/13085 18296/18296/13085 18366/18366/13085 +f 18310/18310/13077 18366/18366/13077 18378/18378/13077 +f 18327/18327/13173 18322/18322/13085 18326/18326/13085 +f 18326/18326/13085 18322/18322/13085 18303/18303/13085 +f 18326/18326/13085 18303/18303/13085 18314/18314/13085 +f 18362/18362/13126 18288/18288/13174 18290/18290/13126 +f 18636/18387/13175 18356/18356/13176 18358/18358/13080 +f 18358/18358/13080 18352/18352/13177 18354/18354/13080 +f 18432/18388/13178 18437/18389/13179 18433/18390/13179 +f 18433/18390/13179 18437/18389/13179 18388/18391/13179 +f 18433/18390/13179 18388/18391/13179 18402/18392/13179 +f 18397/18393/13180 18419/18394/13181 18417/18395/13182 +f 18397/18393/13183 18417/18395/13182 18398/18396/13182 +f 18401/18397/13184 18435/18398/13185 18433/18390/13179 +f 18401/18397/13186 18433/18390/13179 18402/18392/13179 +f 18413/18399/13182 18811/18400/13187 18425/18401/13182 +f 18404/18402/13188 18473/18403/13182 18405/18404/13182 +f 18468/18405/13189 18811/18400/13190 18469/18406/13182 +f 18461/18407/13182 18392/18408/13191 18391/18409/13182 +f 18807/18410/13192 18467/18411/13181 18465/18412/13182 +f 18445/18413/13179 18478/18414/13193 18394/18415/13179 +f 18813/18416/13194 18451/18417/13195 18449/18418/13196 +f 18436/18419/13197 18477/18420/13198 18437/18389/13179 +f 18437/18389/13179 18477/18420/13198 18388/18391/13179 +f 18420/18421/13199 18411/18422/13200 18421/18423/13182 +f 18421/18423/13182 18411/18422/13201 18409/18424/13182 +f 18393/18425/13202 18385/18426/13179 18394/18415/13179 +f 18394/18415/13179 18385/18426/13179 18457/18427/13179 +f 18394/18415/13179 18457/18427/13179 18445/18413/13179 +f 18813/18416/13203 18441/18428/13179 18429/18429/13179 +f 18465/18412/13182 18471/18430/13204 18469/18406/13182 +f 18391/18409/13205 18407/18431/13206 18405/18404/13205 +f 18391/18409/13182 18405/18404/13182 18461/18407/13182 +f 18461/18407/13182 18405/18404/13182 18473/18403/13182 +f 18417/18395/13182 18423/18432/13207 18421/18423/13182 +f 18417/18395/13182 18421/18423/13182 18398/18396/13182 +f 18398/18396/13182 18421/18423/13182 18409/18424/13182 +f 18384/18433/13208 18457/18427/13179 18385/18426/13179 +f 18452/18434/13197 18805/18435/13209 18453/18436/13179 +f 18448/18437/13210 18453/18436/13211 18449/18418/13211 +s 1 +f 18384/18433/13212 18385/18426/13179 18386/18438/13213 +f 18387/18439/13214 18388/18391/13179 18389/18440/13215 +f 18390/18441/13216 18391/18409/13182 18392/18408/13191 +f 18393/18425/13217 18394/18415/13218 18395/18442/13219 +f 18396/18443/13220 18391/18409/13182 18390/18441/13216 +f 18397/18393/13221 18398/18396/13182 18399/18444/13222 +f 18399/18444/13222 18398/18396/13182 18400/18445/13223 +f 18401/18397/13224 18402/18392/13179 18403/18446/13225 +f 18404/18402/13226 18405/18404/13227 18406/18447/13228 +f 18406/18447/13228 18405/18404/13227 18407/18431/13229 +f 18408/18448/13230 18409/18424/13231 18410/18449/13232 +f 18410/18449/13232 18409/18424/13231 18411/18422/13200 +f 18412/18450/13233 18413/18399/13182 18414/18451/13234 +f 18414/18451/13234 18413/18399/13182 18415/18452/13235 +f 18416/18453/13236 18417/18395/13182 18418/18454/13237 +f 18418/18454/13237 18417/18395/13182 18419/18394/13238 +f 18420/18421/13239 18421/18423/13182 18422/18455/13240 +f 18422/18455/13240 18421/18423/13182 18423/18432/13207 +f 18424/18456/13241 18425/18401/13182 18426/18457/13242 +f 18426/18457/13242 18425/18401/13182 18427/18458/13243 +f 18428/18459/13244 18429/18429/13179 18430/18460/13245 +f 18430/18460/13245 18429/18429/13179 18431/18461/13246 +f 18432/18388/13247 18433/18390/13179 18434/18462/13248 +f 18434/18462/13248 18433/18390/13179 18435/18398/13185 +f 18436/18419/13249 18437/18389/13179 18438/18463/13250 +f 18438/18463/13250 18437/18389/13179 18439/18464/13251 +f 18440/18465/13252 18441/18428/13179 18442/18466/13253 +f 18442/18466/13253 18441/18428/13179 18443/18467/13254 +f 18444/18468/13244 18445/18413/13179 18446/18469/13245 +f 18446/18469/13245 18445/18413/13179 18447/18470/13255 +f 18448/18437/13256 18449/18418/13179 18450/18471/13248 +f 18450/18471/13248 18449/18418/13179 18451/18417/13185 +f 18452/18434/13197 18453/18436/13179 18454/18472/13250 +f 18454/18472/13250 18453/18436/13179 18455/18473/13257 +f 18456/18474/13252 18457/18427/13179 18458/18475/13258 +f 18458/18475/13258 18457/18427/13179 18459/18476/13254 +f 18460/18477/13233 18461/18407/13182 18462/18478/13234 +f 18462/18478/13234 18461/18407/13182 18463/18479/13259 +f 18464/18480/13260 18465/18412/13182 18466/18481/13237 +f 18466/18481/13237 18465/18412/13182 18467/18411/13261 +f 18468/18405/13189 18469/18406/13182 18470/18482/13262 +f 18470/18482/13262 18469/18406/13182 18471/18430/13263 +f 18472/18483/13264 18473/18403/13182 18474/18484/13242 +f 18474/18484/13242 18473/18403/13182 18475/18485/13243 +f 18386/18438/13213 18385/18426/13179 18476/18486/13265 +f 18389/18440/13215 18388/18391/13179 18477/18420/13198 +f 18395/18442/13219 18394/18415/13218 18478/18414/13193 +f 18403/18446/13225 18402/18392/13179 18479/18487/13266 +f 18480/18488/13267 18481/18489/13268 18482/18490/13269 +f 18480/18488/13267 18482/18490/13269 18483/18491/13270 +f 18484/18492/13120 18485/18493/13271 18486/18494/13106 +f 18484/18492/13120 18486/18494/13106 18487/18495/13111 +f 18488/18496/13272 18489/18497/13273 18490/18498/13274 +f 18488/18496/13272 18490/18498/13274 18491/18499/13275 +f 18492/18500/13106 18493/18501/13111 18494/18502/13120 +f 18492/18500/13106 18494/18502/13120 18495/18503/13137 +f 18496/18504/13135 18497/18505/13140 18498/18506/13102 +f 18496/18504/13135 18498/18506/13102 18499/18507/13108 +f 18500/18508/13276 18501/18509/13132 18502/18510/13277 +f 18500/18508/13276 18502/18510/13277 18503/18511/13105 +f 18504/18512/13278 18505/18513/13279 18506/18514/13280 +f 18504/18512/13278 18506/18514/13280 18507/18515/13281 +f 18508/18516/13142 18509/18517/13145 18510/18518/13282 +f 18508/18516/13142 18510/18518/13282 18511/18519/13123 +f 18512/18520/13141 18513/18521/13108 18514/18522/13135 +f 18512/18520/13141 18514/18522/13135 18515/18523/13140 +f 18516/18524/13283 18504/18512/13278 18507/18515/13281 +f 18516/18524/13283 18507/18515/13281 18517/18525/13284 +f 18518/18526/13116 18519/18527/13123 18520/18528/13109 +f 18518/18526/13116 18520/18528/13109 18521/18529/13145 +f 18481/18489/13268 18491/18499/13275 18490/18498/13274 +f 18481/18489/13268 18490/18498/13274 18482/18490/13269 +f 18522/18530/13143 18523/18531/13105 18524/18532/13138 +f 18522/18530/13143 18524/18532/13138 18525/18533/13285 +f 18526/18534/13286 18527/18535/13287 18480/18488/13267 +f 18526/18534/13286 18480/18488/13267 18483/18491/13270 +f 18528/18536/13288 18529/18537/13289 18530/18538/13290 +f 18528/18536/13288 18530/18538/13290 18531/18539/13291 +f 18532/18540/13292 18533/18541/13293 18534/18542/13294 +f 18532/18540/13292 18534/18542/13294 18535/18543/13295 +f 18530/18538/13290 18529/18537/13289 18536/18544/13296 +f 18530/18538/13290 18536/18544/13296 18537/18545/13297 +f 18538/18546/13298 18539/18547/13299 18506/18514/13280 +f 18538/18546/13298 18506/18514/13280 18505/18513/13279 +f 18528/18536/13288 18531/18539/13291 18540/18548/13300 +f 18528/18536/13288 18540/18548/13300 18541/18549/13286 +f 18542/18550/13301 18533/18541/13293 18532/18540/13292 +f 18542/18550/13301 18532/18540/13292 18543/18551/13302 +f 18544/18552/13303 18545/18553/13296 18516/18524/13283 +f 18544/18552/13303 18516/18524/13283 18517/18525/13284 +f 18542/18550/13301 18543/18551/13302 18546/18554/13299 +f 18542/18550/13301 18546/18554/13299 18547/18555/13298 +f 18498/18506/13102 18497/18505/13140 18548/18556/13130 +f 18498/18506/13102 18548/18556/13130 18549/18557/13103 +f 18550/18558/13104 18551/18559/13304 18500/18508/13276 +f 18550/18558/13104 18500/18508/13276 18503/18511/13105 +f 18518/18526/13116 18521/18529/13145 18552/18560/13144 +f 18518/18526/13116 18552/18560/13144 18553/18561/13118 +f 18554/18562/13118 18555/18563/13113 18502/18510/13277 +f 18554/18562/13118 18502/18510/13277 18501/18509/13132 +f 18484/18492/13120 18487/18495/13111 18556/18564/13110 +f 18484/18492/13120 18556/18564/13110 18557/18565/13122 +f 18558/18566/13122 18559/18567/13110 18520/18528/13109 +f 18558/18566/13122 18520/18528/13109 18519/18527/13123 +f 18496/18504/13135 18499/18507/13108 18560/18568/13305 +f 18496/18504/13135 18560/18568/13305 18561/18569/13125 +f 18562/18570/13127 18563/18571/13107 18486/18494/13106 +f 18562/18570/13127 18486/18494/13106 18485/18493/13271 +f 18510/18518/13282 18509/18517/13145 18564/18572/13113 +f 18510/18518/13282 18564/18572/13113 18565/18573/13118 +f 18566/18574/13118 18567/18575/13113 18522/18530/13143 +f 18566/18574/13118 18522/18530/13143 18525/18533/13285 +f 18512/18520/13141 18515/18523/13140 18568/18576/13130 +f 18512/18520/13141 18568/18576/13130 18569/18577/13104 +f 18570/18578/13104 18571/18579/13130 18524/18532/13138 +f 18570/18578/13104 18524/18532/13138 18523/18531/13105 +f 18492/18500/13106 18495/18503/13137 18572/18580/13125 +f 18492/18500/13106 18572/18580/13125 18573/18581/13107 +f 18574/18582/13306 18575/18583/13125 18514/18522/13135 +f 18574/18582/13306 18514/18522/13135 18513/18521/13108 +f 18508/18516/13142 18511/18519/13123 18576/18584/13122 +f 18508/18516/13142 18576/18584/13122 18577/18585/13110 +f 18578/18586/13110 18579/18587/13307 18494/18502/13120 +f 18578/18586/13110 18494/18502/13120 18493/18501/13111 +f 18480/18488/13267 18527/18535/13287 18580/18588/13308 +f 18480/18488/13267 18580/18588/13308 18581/18589/13309 +f 18582/18590/13310 18583/18591/13311 18289/18289/13312 +f 18582/18590/13310 18289/18289/13312 18288/18288/13313 +f 18540/18548/13300 18531/18539/13291 18584/18592/13314 +f 18540/18548/13300 18584/18592/13314 18585/18593/13315 +f 18583/18591/13311 18586/18594/13316 18380/18380/13317 +f 18583/18591/13311 18380/18380/13317 18289/18289/13312 +f 18532/18540/13292 18535/18543/13295 18587/18595/13318 +f 18532/18540/13292 18587/18595/13318 18588/18596/13319 +f 18589/18597/13319 18590/18598/13318 18292/18292/13320 +f 18589/18597/13319 18292/18292/13320 18291/18291/13321 +f 18488/18496/13272 18491/18499/13275 18591/18599/13322 +f 18488/18496/13272 18591/18599/13322 18592/18600/13323 +f 18590/18598/13318 18593/18601/13324 18381/18381/13166 +f 18590/18598/13318 18381/18381/13166 18292/18292/13320 +f 18528/18536/13288 18541/18549/13286 18594/18602/13325 +f 18528/18536/13288 18594/18602/13325 18595/18603/13326 +f 18596/18604/13327 18597/18605/13328 18294/18294/13075 +f 18596/18604/13327 18294/18294/13075 18300/18300/13329 +f 18526/18534/13286 18483/18491/13270 18598/18606/13330 +f 18526/18534/13286 18598/18606/13330 18599/18607/13328 +f 18597/18605/13328 18600/18608/13330 18295/18295/13076 +f 18597/18605/13328 18295/18295/13076 18294/18294/13075 +f 18490/18498/13274 18489/18497/13273 18601/18609/13331 +f 18490/18498/13274 18601/18609/13331 18602/18610/13332 +f 18603/18611/13333 18604/18612/13334 18302/18302/13335 +f 18603/18611/13333 18302/18302/13335 18301/18301/13336 +f 18534/18542/13294 18533/18541/13293 18605/18613/13337 +f 18534/18542/13294 18605/18613/13337 18606/18614/13338 +f 18604/18612/13334 18607/18615/13339 18304/18304/13340 +f 18604/18612/13334 18304/18304/13340 18302/18302/13335 +f 18530/18538/13290 18537/18545/13297 18608/18616/13341 +f 18530/18538/13290 18608/18616/13341 18609/18617/13342 +f 18610/18618/13343 18611/18619/13341 18298/18298/13344 +f 18610/18618/13343 18298/18298/13344 18297/18297/13345 +f 18544/18552/13303 18517/18525/13284 18612/18620/13346 +f 18544/18552/13303 18612/18620/13346 18613/18621/13347 +f 18611/18619/13341 18614/18622/13346 18382/18382/13348 +f 18611/18619/13341 18382/18382/13348 18298/18298/13344 +f 18506/18514/13280 18539/18547/13299 18615/18623/13349 +f 18506/18514/13280 18615/18623/13349 18616/18624/13350 +f 18617/18625/13350 18618/18626/13351 18306/18306/13352 +f 18617/18625/13350 18306/18306/13352 18305/18305/13088 +f 18546/18554/13299 18543/18551/13302 18619/18627/13353 +f 18546/18554/13299 18619/18627/13353 18620/18628/13349 +f 18618/18626/13351 18621/18629/13354 18383/18383/13355 +f 18618/18626/13351 18383/18383/13355 18306/18306/13352 +f 18516/18524/13283 18545/18553/13296 18622/18630/13356 +f 18516/18524/13283 18622/18630/13356 18623/18631/13357 +f 18624/18632/13358 18625/18633/13359 18309/18309/13360 +f 18624/18632/13358 18309/18309/13360 18308/18308/13361 +f 18536/18544/13296 18529/18537/13289 18626/18634/13362 +f 18536/18544/13296 18626/18634/13362 18627/18635/13363 +f 18625/18633/13359 18628/18636/13364 18311/18311/13365 +f 18625/18633/13359 18311/18311/13365 18309/18309/13360 +f 18542/18550/13301 18547/18555/13298 18629/18637/13366 +f 18542/18550/13301 18629/18637/13366 18630/18638/13367 +f 18631/18639/13368 18632/18640/13366 18313/18313/13369 +f 18631/18639/13368 18313/18313/13369 18312/18312/13370 +f 18538/18546/13298 18505/18513/13279 18633/18641/13371 +f 18538/18546/13298 18633/18641/13371 18634/18642/13372 +f 18632/18640/13366 18635/18643/13373 18315/18315/13100 +f 18632/18640/13366 18315/18315/13100 18313/18313/13369 +f 18288/18288/13313 18636/18387/13175 18637/18644/13374 +f 18288/18288/13313 18637/18644/13374 18582/18590/13310 +f 18581/18589/13309 18638/18645/13374 18481/18489/13268 +f 18581/18589/13309 18481/18489/13268 18480/18488/13267 +f 18639/18385/13375 18295/18295/13076 18600/18608/13330 +f 18639/18385/13375 18600/18608/13330 18640/18646/13376 +f 18641/18647/13377 18598/18606/13330 18483/18491/13270 +f 18641/18647/13377 18483/18491/13270 18482/18490/13269 +f 18300/18300/13329 18311/18311/13365 18628/18636/13364 +f 18300/18300/13329 18628/18636/13364 18596/18604/13327 +f 18595/18603/13326 18626/18634/13362 18529/18537/13289 +f 18595/18603/13326 18529/18537/13289 18528/18536/13288 +f 18297/18297/13345 18380/18380/13317 18586/18594/13316 +f 18297/18297/13345 18586/18594/13316 18610/18618/13343 +f 18609/18617/13342 18584/18592/13314 18531/18539/13291 +f 18609/18617/13342 18531/18539/13291 18530/18538/13290 +f 18491/18499/13275 18481/18489/13268 18638/18645/13374 +f 18491/18499/13275 18638/18645/13374 18591/18599/13322 +f 18593/18601/13324 18637/18644/13374 18636/18387/13175 +f 18593/18601/13324 18636/18387/13175 18381/18381/13166 +f 18301/18301/13336 18639/18385/13375 18640/18646/13376 +f 18301/18301/13336 18640/18646/13376 18603/18611/13333 +f 18602/18610/13332 18641/18647/13377 18482/18490/13269 +f 18602/18610/13332 18482/18490/13269 18490/18498/13274 +f 18312/18312/13370 18304/18304/13340 18607/18615/13339 +f 18312/18312/13370 18607/18615/13339 18631/18639/13368 +f 18630/18638/13367 18605/18613/13337 18533/18541/13293 +f 18630/18638/13367 18533/18541/13293 18542/18550/13301 +f 18291/18291/13321 18383/18383/13355 18621/18629/13354 +f 18291/18291/13321 18621/18629/13354 18589/18597/13319 +f 18588/18596/13319 18619/18627/13353 18543/18551/13302 +f 18588/18596/13319 18543/18551/13302 18532/18540/13292 +f 18308/18308/13361 18642/18384/13160 18643/18648/13378 +f 18308/18308/13361 18643/18648/13378 18624/18632/13358 +f 18623/18631/13357 18644/18649/13378 18504/18512/13278 +f 18623/18631/13357 18504/18512/13278 18516/18524/13283 +f 18645/18386/13165 18382/18382/13348 18614/18622/13346 +f 18645/18386/13165 18614/18622/13346 18646/18650/13379 +f 18647/18651/13379 18612/18620/13346 18517/18525/13284 +f 18647/18651/13379 18517/18525/13284 18507/18515/13281 +f 18642/18384/13160 18315/18315/13100 18635/18643/13373 +f 18642/18384/13160 18635/18643/13373 18643/18648/13378 +f 18644/18649/13378 18633/18641/13371 18505/18513/13279 +f 18644/18649/13378 18505/18513/13279 18504/18512/13278 +f 18305/18305/13088 18645/18386/13165 18646/18650/13379 +f 18305/18305/13088 18646/18650/13379 18617/18625/13350 +f 18616/18624/13350 18647/18651/13379 18507/18515/13281 +f 18616/18624/13350 18507/18515/13281 18506/18514/13280 +f 18648/18652/13380 18649/18653/13381 18650/18654/13382 +f 18648/18652/13380 18650/18654/13382 18651/18655/13383 +f 18652/18656/13247 18653/18657/13207 18654/18658/13236 +f 18652/18656/13247 18654/18658/13236 18655/18659/13384 +f 18656/18660/13385 18657/18661/13386 18658/18662/13387 +f 18656/18660/13385 18658/18662/13387 18659/18663/13388 +f 18660/18664/13236 18661/18665/13389 18662/18666/13247 +f 18660/18664/13236 18662/18666/13247 18663/18667/13390 +f 18664/18668/13197 18665/18669/13238 18666/18670/13233 +f 18664/18668/13197 18666/18670/13233 18667/18671/13254 +f 18668/18672/13252 18669/18673/13391 18670/18674/13264 +f 18668/18672/13252 18670/18674/13264 18671/18675/13255 +f 18672/18676/13392 18673/18677/13393 18674/18678/13394 +f 18672/18676/13392 18674/18678/13394 18675/18679/13395 +f 18676/18680/13239 18677/18681/13185 18678/18682/13244 +f 18676/18680/13239 18678/18682/13244 18679/18683/13243 +f 18680/18684/13233 18681/18685/13254 18682/18686/13197 +f 18680/18684/13233 18682/18686/13197 18683/18687/13238 +f 18684/18688/13396 18685/18689/13397 18673/18677/13393 +f 18684/18688/13396 18673/18677/13393 18672/18676/13392 +f 18686/18690/13244 18687/18691/13243 18688/18692/13398 +f 18686/18690/13244 18688/18692/13398 18689/18693/13185 +f 18651/18655/13383 18650/18654/13382 18658/18662/13387 +f 18651/18655/13383 18658/18662/13387 18657/18661/13386 +f 18690/18694/13264 18691/18695/13255 18692/18696/13252 +f 18690/18694/13264 18692/18696/13252 18693/18697/13391 +f 18694/18698/13399 18649/18653/13381 18648/18652/13380 +f 18694/18698/13399 18648/18652/13380 18695/18699/13400 +f 18696/18700/13401 18697/18701/13402 18698/18702/13403 +f 18696/18700/13401 18698/18702/13403 18699/18703/13404 +f 18700/18704/13405 18701/18705/13406 18702/18706/13407 +f 18700/18704/13405 18702/18706/13407 18703/18707/13408 +f 18698/18702/13403 18704/18708/13409 18705/18709/13410 +f 18698/18702/13403 18705/18709/13410 18699/18703/13404 +f 18706/18710/13411 18675/18679/13395 18674/18678/13394 +f 18706/18710/13411 18674/18678/13394 18707/18711/13412 +f 18696/18700/13401 18708/18712/13399 18709/18713/13413 +f 18696/18700/13401 18709/18713/13413 18697/18701/13402 +f 18710/18714/13414 18711/18715/13415 18700/18704/13405 +f 18710/18714/13414 18700/18704/13405 18703/18707/13408 +f 18712/18716/13409 18685/18689/13397 18684/18688/13396 +f 18712/18716/13409 18684/18688/13396 18713/18717/13416 +f 18710/18714/13414 18714/18718/13417 18715/18719/13412 +f 18710/18714/13414 18715/18719/13412 18711/18715/13415 +f 18666/18670/13233 18716/18720/13234 18717/18721/13258 +f 18666/18670/13233 18717/18721/13258 18667/18671/13254 +f 18718/18722/13234 18669/18673/13391 18668/18672/13252 +f 18718/18722/13234 18668/18672/13252 18719/18723/13253 +f 18686/18690/13244 18720/18724/13418 18721/18725/13242 +f 18686/18690/13244 18721/18725/13242 18687/18691/13243 +f 18722/18726/13245 18671/18675/13255 18670/18674/13264 +f 18722/18726/13245 18670/18674/13264 18723/18727/13242 +f 18652/18656/13247 18724/18728/13419 18725/18729/13240 +f 18652/18656/13247 18725/18729/13240 18653/18657/13207 +f 18726/18730/13248 18689/18693/13185 18688/18692/13398 +f 18726/18730/13248 18688/18692/13398 18727/18731/13262 +f 18664/18668/13197 18728/18732/13420 18729/18733/13421 +f 18664/18668/13197 18729/18733/13421 18665/18669/13238 +f 18730/18734/13422 18655/18659/13384 18654/18658/13236 +f 18730/18734/13422 18654/18658/13236 18731/18735/13237 +f 18678/18682/13244 18732/18736/13245 18733/18737/13423 +f 18678/18682/13244 18733/18737/13423 18679/18683/13243 +f 18734/18738/13245 18691/18695/13255 18690/18694/13264 +f 18734/18738/13245 18690/18694/13264 18735/18739/13423 +f 18680/18684/13233 18736/18740/13424 18737/18741/13258 +f 18680/18684/13233 18737/18741/13258 18681/18685/13254 +f 18738/18742/13425 18693/18697/13391 18692/18696/13252 +f 18738/18742/13425 18692/18696/13252 18739/18743/13253 +f 18660/18664/13236 18740/18744/13237 18741/18745/13250 +f 18660/18664/13236 18741/18745/13250 18661/18665/13389 +f 18742/18746/13421 18683/18687/13238 18682/18686/13197 +f 18742/18746/13421 18682/18686/13197 18743/18747/13250 +f 18676/18680/13239 18744/18748/13262 18745/18749/13419 +f 18676/18680/13239 18745/18749/13419 18677/18681/13185 +f 18746/18750/13240 18663/18667/13390 18662/18666/13247 +f 18746/18750/13240 18662/18666/13247 18747/18751/13248 +f 18648/18652/13380 18748/18752/13426 18749/18753/13427 +f 18648/18652/13380 18749/18753/13427 18695/18699/13400 +f 18750/18754/13428 18384/18433/13212 18386/18438/13213 +f 18750/18754/13428 18386/18438/13213 18751/18755/13429 +f 18709/18713/13413 18752/18756/13427 18753/18757/13430 +f 18709/18713/13413 18753/18757/13430 18697/18701/13402 +f 18751/18755/13429 18386/18438/13213 18476/18486/13265 +f 18751/18755/13429 18476/18486/13265 18754/18758/13431 +f 18700/18704/13405 18755/18759/13432 18756/18760/13433 +f 18700/18704/13405 18756/18760/13433 18701/18705/13406 +f 18757/18761/13432 18387/18439/13214 18389/18440/13215 +f 18757/18761/13432 18389/18440/13215 18758/18762/13433 +f 18656/18660/13385 18759/18763/13434 18760/18764/13435 +f 18656/18660/13385 18760/18764/13435 18657/18661/13386 +f 18758/18762/13433 18389/18440/13215 18477/18420/13198 +f 18758/18762/13433 18477/18420/13198 18761/18765/13436 +f 18696/18700/13401 18762/18766/13437 18763/18767/13438 +f 18696/18700/13401 18763/18767/13438 18708/18712/13399 +f 18764/18768/13439 18396/18443/13220 18390/18441/13216 +f 18764/18768/13439 18390/18441/13216 18765/18769/13440 +f 18694/18698/13399 18766/18770/13440 18767/18771/13441 +f 18694/18698/13399 18767/18771/13441 18649/18653/13381 +f 18765/18769/13440 18390/18441/13216 18392/18408/13191 +f 18765/18769/13440 18392/18408/13191 18768/18772/13442 +f 18658/18662/13387 18769/18773/13443 18770/18774/13444 +f 18658/18662/13387 18770/18774/13444 18659/18663/13388 +f 18771/18775/13445 18397/18393/13221 18399/18444/13222 +f 18771/18775/13445 18399/18444/13222 18772/18776/13446 +f 18702/18706/13407 18773/18777/13446 18774/18778/13447 +f 18702/18706/13407 18774/18778/13447 18703/18707/13408 +f 18772/18776/13446 18399/18444/13222 18400/18445/13223 +f 18772/18776/13446 18400/18445/13223 18775/18779/13448 +f 18698/18702/13403 18776/18780/13449 18777/18781/13450 +f 18698/18702/13403 18777/18781/13450 18704/18708/13409 +f 18778/18782/13451 18393/18425/13217 18395/18442/13219 +f 18778/18782/13451 18395/18442/13219 18779/18783/13452 +f 18712/18716/13409 18780/18784/13452 18781/18785/13453 +f 18712/18716/13409 18781/18785/13453 18685/18689/13397 +f 18779/18783/13452 18395/18442/13219 18478/18414/13193 +f 18779/18783/13452 18478/18414/13193 18782/18786/13453 +f 18674/18678/13394 18783/18787/13454 18784/18788/13455 +f 18674/18678/13394 18784/18788/13455 18707/18711/13412 +f 18785/18789/13456 18401/18397/13224 18403/18446/13225 +f 18785/18789/13456 18403/18446/13225 18786/18790/13455 +f 18715/18719/13412 18787/18791/13455 18788/18792/13457 +f 18715/18719/13412 18788/18792/13457 18711/18715/13415 +f 18786/18790/13455 18403/18446/13225 18479/18487/13266 +f 18786/18790/13455 18479/18487/13266 18789/18793/13458 +f 18684/18688/13396 18790/18794/13459 18791/18795/13460 +f 18684/18688/13396 18791/18795/13460 18713/18717/13416 +f 18792/18796/13461 18404/18402/13226 18406/18447/13228 +f 18792/18796/13461 18406/18447/13228 18793/18797/13460 +f 18705/18709/13410 18794/18798/13462 18795/18799/13463 +f 18705/18709/13410 18795/18799/13463 18699/18703/13404 +f 18793/18797/13460 18406/18447/13228 18407/18431/13229 +f 18793/18797/13460 18407/18431/13229 18796/18800/13464 +f 18710/18714/13414 18797/18801/13465 18798/18802/13466 +f 18710/18714/13414 18798/18802/13466 18714/18718/13417 +f 18799/18803/13467 18408/18448/13230 18410/18449/13232 +f 18799/18803/13467 18410/18449/13232 18800/18804/13466 +f 18706/18710/13411 18801/18805/13468 18802/18806/13469 +f 18706/18710/13411 18802/18806/13469 18675/18679/13395 +f 18800/18804/13466 18410/18449/13232 18411/18422/13200 +f 18800/18804/13466 18411/18422/13200 18803/18807/13469 +f 18384/18433/13212 18750/18754/13428 18804/18808/13470 +f 18384/18433/13212 18804/18808/13470 18805/18435/13471 +f 18748/18752/13426 18648/18652/13380 18651/18655/13383 +f 18748/18752/13426 18651/18655/13383 18806/18809/13472 +f 18807/18410/13473 18808/18810/13474 18768/18772/13442 +f 18807/18410/13473 18768/18772/13442 18392/18408/13191 +f 18809/18811/13475 18650/18654/13382 18649/18653/13381 +f 18809/18811/13475 18649/18653/13381 18767/18771/13441 +f 18396/18443/13220 18764/18768/13439 18796/18800/13464 +f 18396/18443/13220 18796/18800/13464 18407/18431/13229 +f 18762/18766/13437 18696/18700/13401 18699/18703/13404 +f 18762/18766/13437 18699/18703/13404 18795/18799/13463 +f 18393/18425/13217 18778/18782/13451 18754/18758/13431 +f 18393/18425/13217 18754/18758/13431 18476/18486/13265 +f 18776/18780/13449 18698/18702/13403 18697/18701/13402 +f 18776/18780/13449 18697/18701/13402 18753/18757/13430 +f 18657/18661/13386 18760/18764/13435 18806/18809/13472 +f 18657/18661/13386 18806/18809/13472 18651/18655/13383 +f 18761/18765/13436 18477/18420/13198 18805/18435/13471 +f 18761/18765/13436 18805/18435/13471 18804/18808/13470 +f 18397/18393/13221 18771/18775/13445 18808/18810/13474 +f 18397/18393/13221 18808/18810/13474 18807/18410/13473 +f 18769/18773/13443 18658/18662/13387 18650/18654/13382 +f 18769/18773/13443 18650/18654/13382 18809/18811/13475 +f 18408/18448/13230 18799/18803/13467 18775/18779/13448 +f 18408/18448/13230 18775/18779/13448 18400/18445/13223 +f 18797/18801/13465 18710/18714/13414 18703/18707/13408 +f 18797/18801/13465 18703/18707/13408 18774/18778/13447 +f 18387/18439/13214 18757/18761/13432 18789/18793/13458 +f 18387/18439/13214 18789/18793/13458 18479/18487/13266 +f 18755/18759/13432 18700/18704/13405 18711/18715/13415 +f 18755/18759/13432 18711/18715/13415 18788/18792/13457 +f 18404/18402/13226 18792/18796/13461 18810/18812/13476 +f 18404/18402/13226 18810/18812/13476 18811/18400/13477 +f 18790/18794/13459 18684/18688/13396 18672/18676/13392 +f 18790/18794/13459 18672/18676/13392 18812/18813/13478 +f 18813/18416/13194 18814/18814/13479 18782/18786/13453 +f 18813/18416/13194 18782/18786/13453 18478/18414/13193 +f 18815/18815/13480 18673/18677/13393 18685/18689/13397 +f 18815/18815/13480 18685/18689/13397 18781/18785/13453 +f 18811/18400/13477 18810/18812/13476 18803/18807/13469 +f 18811/18400/13477 18803/18807/13469 18411/18422/13200 +f 18812/18813/13478 18672/18676/13392 18675/18679/13395 +f 18812/18813/13478 18675/18679/13395 18802/18806/13469 +f 18401/18397/13224 18785/18789/13456 18814/18814/13479 +f 18401/18397/13224 18814/18814/13479 18813/18416/13194 +f 18783/18787/13454 18674/18678/13394 18673/18677/13393 +f 18783/18787/13454 18673/18677/13393 18815/18815/13480 +f 18336/18336/13481 18342/18342/13080 18343/18343/13128 +f 18293/18293/13482 18307/18307/13080 18291/18291/13321 +f 18291/18291/13321 18307/18307/13080 18383/18383/13355 +f 18301/18301/13336 18318/18318/13085 18639/18385/13375 +f 18318/18318/13085 18301/18301/13336 18316/18316/13102 +f 18316/18316/13102 18301/18301/13336 18323/18323/13108 +f 18305/18305/13088 18334/18334/13080 18645/18386/13165 +f 18334/18334/13080 18305/18305/13088 18332/18332/13116 +f 18332/18332/13116 18305/18305/13088 18339/18339/13134 +f 18318/18318/13085 18642/18384/13160 18639/18385/13375 +f 18330/18330/13483 18318/18318/13077 18319/18319/13484 +f 18330/18330/13483 18319/18319/13484 18328/18328/13112 +f 18308/18308/13361 18378/18378/13085 18642/18384/13160 +f 18642/18384/13160 18378/18378/13085 18379/18379/13145 +f 18642/18384/13160 18379/18379/13145 18372/18372/13142 +f 18366/18366/13085 18295/18295/13076 18639/18385/13375 +f 18366/18366/13085 18639/18385/13375 18364/18364/13102 +f 18364/18364/13102 18639/18385/13375 18371/18371/13108 +f 18350/18350/13080 18382/18382/13348 18645/18386/13165 +f 18350/18350/13080 18645/18386/13165 18348/18348/13116 +f 18348/18348/13116 18645/18386/13165 18355/18355/13134 +f 18346/18346/13080 18381/18381/13166 18636/18387/13175 +f 18381/18381/13166 18346/18346/13080 18347/18347/13140 +f 18381/18381/13166 18347/18347/13140 18340/18340/13135 +f 18330/18330/13085 18315/18315/13100 18642/18384/13160 +f 18315/18315/13100 18330/18330/13085 18331/18331/13145 +f 18315/18315/13100 18331/18331/13145 18324/18324/13142 +f 18297/18297/13345 18290/18290/13126 18380/18380/13317 +f 18362/18362/13485 18350/18350/13080 18360/18360/13276 +f 18360/18360/13276 18350/18350/13080 18351/18351/13486 +f 18645/18386/13165 18346/18346/13080 18636/18387/13175 +f 18346/18346/13126 18334/18334/13485 18344/18344/13138 +f 18344/18344/13138 18334/18334/13485 18335/18335/13487 +f 18370/18370/13085 18375/18375/13488 18368/18368/13489 +f 18374/18374/13085 18370/18370/13085 18639/18385/13375 +f 18374/18374/13085 18639/18385/13375 18642/18384/13160 +f 18296/18296/13077 18311/18311/13365 18300/18300/13329 +f 18378/18378/13085 18366/18366/13077 18367/18367/13490 +f 18378/18378/13085 18367/18367/13490 18376/18376/13143 +f 18322/18322/13077 18327/18327/13111 18320/18320/13106 +f 18314/18314/13172 18303/18303/13077 18304/18304/13340 +f 18314/18314/13172 18304/18304/13340 18312/18312/13370 +f 18288/18288/13313 18362/18362/13080 18636/18387/13175 +f 18636/18387/13175 18362/18362/13080 18363/18363/13140 +f 18636/18387/13175 18363/18363/13140 18356/18356/13135 +f 18352/18352/13154 18358/18358/13080 18359/18359/13491 +f 18358/18358/13126 18354/18354/13080 18636/18387/13175 +f 18636/18387/13175 18354/18354/13080 18645/18386/13165 +f 18437/18389/13179 18432/18388/13247 18439/18464/13251 +f 18402/18392/13179 18388/18391/13179 18387/18439/13214 +f 18402/18392/13179 18387/18439/13214 18479/18487/13266 +f 18413/18399/13182 18397/18393/13221 18807/18410/13473 +f 18397/18393/13221 18413/18399/13182 18412/18450/13233 +f 18397/18393/13221 18412/18450/13233 18419/18394/13238 +f 18429/18429/13179 18401/18397/13224 18813/18416/13194 +f 18401/18397/13224 18429/18429/13179 18428/18459/13244 +f 18401/18397/13224 18428/18459/13244 18435/18398/13185 +f 18811/18400/13492 18413/18399/13182 18807/18410/13473 +f 18413/18399/13182 18425/18401/13182 18415/18452/13235 +f 18415/18452/13235 18425/18401/13182 18424/18456/13241 +f 18473/18403/13182 18404/18402/13226 18811/18400/13477 +f 18473/18403/13182 18811/18400/13477 18475/18485/13243 +f 18475/18485/13243 18811/18400/13477 18468/18405/13239 +f 18392/18408/13191 18461/18407/13182 18807/18410/13473 +f 18807/18410/13473 18461/18407/13182 18460/18477/13233 +f 18807/18410/13473 18460/18477/13233 18467/18411/13238 +f 18478/18414/13193 18445/18413/13179 18813/18416/13194 +f 18813/18416/13194 18445/18413/13179 18444/18468/13244 +f 18813/18416/13194 18444/18468/13244 18451/18417/13185 +f 18477/18420/13198 18441/18428/13179 18805/18435/13471 +f 18441/18428/13179 18477/18420/13198 18443/18467/13254 +f 18443/18467/13254 18477/18420/13198 18436/18419/13197 +f 18411/18422/13200 18425/18401/13182 18811/18400/13477 +f 18425/18401/13182 18411/18422/13200 18427/18458/13243 +f 18427/18458/13243 18411/18422/13200 18420/18421/13199 +f 18385/18426/13179 18393/18425/13217 18476/18486/13265 +f 18445/18413/13179 18457/18427/13179 18456/18474/13252 +f 18445/18413/13179 18456/18474/13252 18447/18470/13255 +f 18441/18428/13179 18813/18416/13203 18805/18435/13471 +f 18429/18429/13179 18441/18428/13179 18440/18465/13252 +f 18429/18429/13179 18440/18465/13252 18431/18461/13246 +f 18471/18430/13493 18465/18412/13182 18464/18480/13260 +f 18465/18412/13182 18469/18406/13182 18807/18410/13473 +f 18807/18410/13473 18469/18406/13182 18811/18400/13492 +f 18407/18431/13229 18391/18409/13182 18396/18443/13220 +f 18461/18407/13182 18473/18403/13182 18463/18479/13259 +f 18463/18479/13259 18473/18403/13182 18472/18483/13264 +f 18423/18432/13207 18417/18395/13182 18416/18453/13236 +f 18398/18396/13182 18409/18424/13231 18400/18445/13223 +f 18400/18445/13223 18409/18424/13231 18408/18448/13230 +f 18457/18427/13179 18384/18433/13212 18805/18435/13471 +f 18457/18427/13179 18805/18435/13471 18459/18476/13254 +f 18459/18476/13254 18805/18435/13471 18452/18434/13197 +f 18453/18436/13179 18448/18437/13494 18455/18473/13257 +f 18449/18418/13179 18453/18436/13179 18805/18435/13471 +f 18449/18418/13179 18805/18435/13471 18813/18416/13203 +o Cylinder.031__0 +v -0.538219 -1.310310 0.715405 +v -0.532451 -1.085911 0.709293 +v -0.362390 -1.092940 0.690033 +v -0.363038 -1.310747 0.692873 +v -0.532451 -1.085911 0.709293 +v -0.531157 -0.963683 0.608156 +v -0.362224 -0.977583 0.592137 +v -0.362390 -1.092940 0.690033 +v -0.533097 -0.855552 0.458168 +v -0.364684 -0.874984 0.447279 +v -0.528429 -0.817232 0.280170 +v -0.362940 -0.837717 0.275488 +v -0.533495 -0.789599 0.087028 +v -0.367832 -0.810259 0.089121 +v -0.549240 -0.705142 -0.090927 +v -0.554130 -0.723037 -0.125007 +v -0.384759 -0.717183 -0.114549 +v -0.380871 -0.701566 -0.087067 +v -0.554130 -0.723037 -0.125007 +v -0.552872 -0.949075 -0.184459 +v -0.382840 -0.963091 -0.173302 +v -0.384759 -0.717183 -0.114549 +v -0.536573 -1.309920 0.739236 +v -0.361355 -1.310269 0.719511 +v -0.359844 -1.083831 0.714881 +v -0.529922 -1.076146 0.734774 +v -0.529922 -1.076146 0.734774 +v -0.359844 -1.083831 0.714881 +v -0.357965 -0.958313 0.609951 +v -0.526943 -0.943643 0.626389 +v -0.358412 -0.851217 0.457776 +v -0.526878 -0.830830 0.468876 +v -0.356280 -0.812177 0.280058 +v -0.521812 -0.790678 0.284909 +v -0.361805 -0.784329 0.087623 +v -0.527518 -0.762637 0.085461 +v -0.544081 -0.680202 -0.097311 +v -0.375678 -0.677642 -0.093340 +v -0.380400 -0.697199 -0.131458 +v -0.549791 -0.702097 -0.142321 +v -0.549791 -0.702097 -0.142321 +v -0.380400 -0.697199 -0.131458 +v -0.379837 -0.944927 -0.192423 +v -0.549935 -0.930274 -0.204244 +v -0.380871 -0.701566 -0.087067 +v -0.384759 -0.717183 -0.114549 +v -0.380400 -0.697199 -0.131458 +v -0.375678 -0.677642 -0.093340 +v -0.531157 -0.963683 0.608156 +v -0.532451 -1.085911 0.709293 +v -0.529922 -1.076146 0.734774 +v -0.526943 -0.943643 0.626389 +v -0.382840 -0.963091 -0.173302 +v -0.379837 -0.944927 -0.192423 +v -0.538219 -1.310310 0.715405 +v -0.536573 -1.309920 0.739236 +v -0.382840 -0.963091 -0.173302 +v -0.552872 -0.949075 -0.184459 +v -0.549935 -0.930274 -0.204244 +v -0.379837 -0.944927 -0.192423 +v -0.365419 -1.448696 0.728127 +v -0.363951 -1.458398 0.750306 +v -0.367201 -1.482789 0.680915 +v -0.368603 -1.470032 0.657312 +v -0.363038 -1.310747 0.692873 +v -0.362390 -1.092940 0.690033 +v -0.359844 -1.083831 0.714881 +v -0.361355 -1.310269 0.719511 +v -0.552872 -0.949075 -0.184459 +v -0.554130 -0.723037 -0.125007 +v -0.549791 -0.702097 -0.142321 +v -0.549935 -0.930274 -0.204244 +v -0.362224 -0.977583 0.592137 +v -0.357965 -0.958313 0.609951 +v -0.549240 -0.705142 -0.090927 +v -0.533495 -0.789599 0.087028 +v -0.527518 -0.762637 0.085461 +v -0.544081 -0.680202 -0.097311 +v -0.364684 -0.874984 0.447279 +v -0.358412 -0.851217 0.457776 +v -0.528429 -0.817232 0.280170 +v -0.521812 -0.790678 0.284909 +v -0.362940 -0.837717 0.275488 +v -0.356280 -0.812177 0.280058 +v -0.533097 -0.855552 0.458168 +v -0.526878 -0.830830 0.468876 +v -0.367832 -0.810259 0.089121 +v -0.361805 -0.784329 0.087623 +v -0.363648 -1.366315 0.708261 +v -0.362030 -1.364932 0.734146 +v -0.362206 -1.409608 0.768375 +v -0.363757 -1.407865 0.743102 +v -0.534130 -1.462497 0.773109 +v -0.535613 -1.452490 0.750266 +v -0.538562 -1.475729 0.676766 +v -0.537236 -1.488583 0.700947 +v -0.363951 -1.458398 0.750306 +v -0.534130 -1.462497 0.773109 +v -0.537236 -1.488583 0.700947 +v -0.367201 -1.482789 0.680915 +v -0.541592 -1.569615 0.649150 +v -0.540113 -1.563107 0.678028 +v -0.362030 -1.364932 0.734146 +v -0.532303 -1.366709 0.756744 +v -0.532551 -1.413603 0.791245 +v -0.362206 -1.409608 0.768375 +v -0.532303 -1.366709 0.756744 +v -0.533956 -1.367973 0.730122 +v -0.534120 -1.411581 0.765322 +v -0.532551 -1.413603 0.791245 +v -0.533956 -1.367973 0.730122 +v -0.363648 -1.366315 0.708261 +v -0.363757 -1.407865 0.743102 +v -0.534120 -1.411581 0.765322 +v -0.529076 -1.635680 0.695179 +v -0.530365 -1.643903 0.667985 +v -0.518438 -1.708603 0.714398 +v -0.517477 -1.689521 0.734037 +v -0.538562 -1.475729 0.676766 +v -0.368603 -1.470032 0.657312 +v -0.371249 -1.562527 0.630885 +v -0.541592 -1.569615 0.649150 +v -0.369830 -1.556694 0.659415 +v -0.371249 -1.562527 0.630885 +v -0.367201 -1.482789 0.680915 +v -0.537236 -1.488583 0.700947 +v -0.540113 -1.563107 0.678028 +v -0.369830 -1.556694 0.659415 +v -0.396418 -1.708897 0.700416 +v -0.395472 -1.690363 0.720128 +v -0.427400 -1.703344 0.735829 +v -0.427926 -1.722411 0.716468 +v -0.530365 -1.643903 0.667985 +v -0.384172 -1.638376 0.652255 +v -0.396418 -1.708897 0.700416 +v -0.518438 -1.708603 0.714398 +v -0.384172 -1.638376 0.652255 +v -0.382922 -1.630757 0.679202 +v -0.395472 -1.690363 0.720128 +v -0.396418 -1.708897 0.700416 +v -0.382922 -1.630757 0.679202 +v -0.529076 -1.635680 0.695179 +v -0.517477 -1.689521 0.734037 +v -0.395472 -1.690363 0.720128 +v -0.488092 -1.720129 0.722770 +v -0.487561 -1.700791 0.742091 +v -0.487561 -1.700791 0.742091 +v -0.427400 -1.703344 0.735829 +v -0.517477 -1.689521 0.734037 +v -0.518438 -1.708603 0.714398 +v -0.427926 -1.722411 0.716468 +v -0.488092 -1.720129 0.722770 +v -0.555836 -1.349439 -0.198156 +v -0.559752 -1.519448 -0.137111 +v -0.387203 -1.509117 -0.127644 +v -0.384883 -1.345429 -0.186395 +v -0.559752 -1.519448 -0.137111 +v -0.546326 -1.630556 0.002665 +v -0.377031 -1.615541 0.007713 +v -0.387203 -1.509117 -0.127644 +v -0.509556 -1.684634 0.235878 +v -0.350202 -1.665188 0.233265 +v -0.526586 -1.651507 0.425824 +v -0.360530 -1.635065 0.416350 +v -0.526586 -1.651507 0.425824 +v -0.541369 -1.556571 0.579114 +v -0.369557 -1.544988 0.564493 +v -0.360530 -1.635065 0.416350 +v -0.534097 -1.412286 0.715672 +v -0.362871 -1.405256 0.705267 +v -0.556947 -1.360015 -0.227651 +v -0.385922 -1.355712 -0.215099 +v -0.387901 -1.526954 -0.152420 +v -0.560473 -1.537765 -0.162670 +v -0.560473 -1.537765 -0.162670 +v -0.387901 -1.526954 -0.152420 +v -0.376504 -1.643019 -0.005368 +v -0.545849 -1.658795 -0.011037 +v -0.348548 -1.695486 0.232423 +v -0.507890 -1.715941 0.234991 +v -0.359175 -1.663512 0.427004 +v -0.525250 -1.680790 0.437046 +v -0.525250 -1.680790 0.437046 +v -0.359175 -1.663512 0.427004 +v -0.368938 -1.566541 0.586068 +v -0.540731 -1.578685 0.601458 +v -0.362524 -1.430762 0.731534 +v -0.533652 -1.438320 0.742797 +v -0.377031 -1.615541 0.007713 +v -0.350202 -1.665188 0.233265 +v -0.348548 -1.695486 0.232423 +v -0.376504 -1.643019 -0.005368 +v -0.546326 -1.630556 0.002665 +v -0.559752 -1.519448 -0.137111 +v -0.560473 -1.537765 -0.162670 +v -0.545849 -1.658795 -0.011037 +v -0.360530 -1.635065 0.416350 +v -0.359175 -1.663512 0.427004 +v -0.555836 -1.349439 -0.198156 +v -0.556947 -1.360015 -0.227651 +v -0.369557 -1.544988 0.564493 +v -0.368938 -1.566541 0.586068 +v -0.362871 -1.405256 0.705267 +v -0.534097 -1.412286 0.715672 +v -0.533830 -1.406883 0.728491 +v -0.362547 -1.402689 0.720497 +v -0.362871 -1.405256 0.705267 +v -0.362524 -1.430762 0.731534 +v -0.534097 -1.412286 0.715672 +v -0.541369 -1.556571 0.579114 +v -0.540731 -1.578685 0.601458 +v -0.533652 -1.438320 0.742797 +v -0.555836 -1.349439 -0.198156 +v -0.384883 -1.345429 -0.186395 +v -0.385922 -1.355712 -0.215099 +v -0.556947 -1.360015 -0.227651 +v -0.526586 -1.651507 0.425824 +v -0.525250 -1.680790 0.437046 +v -0.384883 -1.345429 -0.186395 +v -0.387203 -1.509117 -0.127644 +v -0.387901 -1.526954 -0.152420 +v -0.385922 -1.355712 -0.215099 +v -0.509556 -1.684634 0.235878 +v -0.507890 -1.715941 0.234991 +v -0.365419 -1.448696 0.728127 +v -0.535613 -1.452490 0.750266 +v -0.534120 -1.411581 0.765322 +v -0.363757 -1.407865 0.743102 +v -0.362206 -1.409608 0.768375 +v -0.532551 -1.413603 0.791245 +v -0.534130 -1.462497 0.773109 +v -0.363951 -1.458398 0.750306 +v -0.535613 -1.452490 0.750266 +v -0.365419 -1.448696 0.728127 +v -0.368603 -1.470032 0.657312 +v -0.538562 -1.475729 0.676766 +v -0.533645 -1.422638 0.744908 +v -0.362451 -1.418125 0.736396 +v -0.533645 -1.422638 0.744908 +v -0.533830 -1.406883 0.728491 +v -0.362547 -1.402689 0.720497 +v -0.362451 -1.418125 0.736396 +v -0.362451 -1.418125 0.736396 +v -0.533645 -1.422638 0.744908 +v -0.363648 -1.366315 0.708261 +v -0.533956 -1.367973 0.730122 +v -0.532303 -1.366709 0.756744 +v -0.362030 -1.364932 0.734146 +v 0.547552 -1.311277 0.688169 +v 0.371462 -1.311401 0.674448 +v 0.371060 -1.093593 0.671635 +v 0.541885 -1.086867 0.682344 +v 0.541885 -1.086867 0.682344 +v 0.371060 -1.093593 0.671635 +v 0.366191 -0.978232 0.573865 +v 0.535739 -0.964634 0.581394 +v 0.361568 -0.852702 0.428248 +v 0.530349 -0.856499 0.431492 +v 0.351279 -0.819550 0.256905 +v 0.514997 -0.818161 0.253996 +v 0.346871 -0.794629 0.071194 +v 0.512256 -0.790530 0.060796 +v 0.521681 -0.696026 -0.089844 +v 0.355434 -0.717667 -0.085641 +v 0.355361 -0.732924 -0.118809 +v 0.522469 -0.714419 -0.134795 +v 0.522469 -0.714419 -0.134795 +v 0.355361 -0.732924 -0.118809 +v 0.348431 -0.963742 -0.191645 +v 0.517714 -0.950028 -0.211314 +v 0.547104 -1.310885 0.712053 +v 0.540654 -1.077099 0.707920 +v 0.369780 -1.084481 0.696579 +v 0.371117 -1.310921 0.701138 +v 0.540654 -1.077099 0.707920 +v 0.532480 -0.944587 0.599814 +v 0.362865 -0.958955 0.591869 +v 0.369780 -1.084481 0.696579 +v 0.524719 -0.828536 0.442383 +v 0.355872 -0.828925 0.439045 +v 0.508674 -0.791596 0.259060 +v 0.344902 -0.793997 0.261802 +v 0.506256 -0.763558 0.059530 +v 0.340822 -0.768688 0.069998 +v 0.516189 -0.670268 -0.094847 +v 0.517485 -0.691003 -0.148356 +v 0.350368 -0.710515 -0.132121 +v 0.349914 -0.692918 -0.090448 +v 0.517485 -0.691003 -0.148356 +v 0.513822 -0.931221 -0.230927 +v 0.344505 -0.945572 -0.210592 +v 0.350368 -0.710515 -0.132121 +v 0.355434 -0.717667 -0.085641 +v 0.349914 -0.692918 -0.090448 +v 0.350368 -0.710515 -0.132121 +v 0.355361 -0.732924 -0.118809 +v 0.535739 -0.964634 0.581394 +v 0.532480 -0.944587 0.599814 +v 0.540654 -1.077099 0.707920 +v 0.541885 -1.086867 0.682344 +v 0.344505 -0.945572 -0.210592 +v 0.348431 -0.963742 -0.191645 +v 0.547104 -1.310885 0.712053 +v 0.547552 -1.311277 0.688169 +v 0.348431 -0.963742 -0.191645 +v 0.344505 -0.945572 -0.210592 +v 0.513822 -0.931221 -0.230927 +v 0.517714 -0.950028 -0.211314 +v 0.375362 -1.449355 0.709546 +v 0.374953 -1.470694 0.638660 +v 0.374714 -1.483450 0.662305 +v 0.374991 -1.459056 0.731770 +v 0.371462 -1.311401 0.674448 +v 0.371117 -1.310921 0.701138 +v 0.369780 -1.084481 0.696579 +v 0.371060 -1.093593 0.671635 +v 0.517714 -0.950028 -0.211314 +v 0.513822 -0.931221 -0.230927 +v 0.517485 -0.691003 -0.148356 +v 0.522469 -0.714419 -0.134795 +v 0.362865 -0.958955 0.591869 +v 0.366191 -0.978232 0.573865 +v 0.521681 -0.696026 -0.089844 +v 0.516189 -0.670268 -0.094847 +v 0.506256 -0.763558 0.059530 +v 0.512256 -0.790530 0.060796 +v 0.355872 -0.828925 0.439045 +v 0.361568 -0.852702 0.428248 +v 0.508674 -0.791596 0.259060 +v 0.514997 -0.818161 0.253996 +v 0.344902 -0.793997 0.261802 +v 0.351279 -0.819550 0.256905 +v 0.524719 -0.828536 0.442383 +v 0.530349 -0.856499 0.431492 +v 0.340822 -0.768688 0.069998 +v 0.346871 -0.794629 0.071194 +v 0.372743 -1.366971 0.689789 +v 0.374525 -1.408523 0.724582 +v 0.374240 -1.410263 0.749902 +v 0.372428 -1.365586 0.715722 +v 0.546091 -1.463458 0.746013 +v 0.545528 -1.489547 0.673787 +v 0.545663 -1.476695 0.649569 +v 0.546444 -1.453453 0.723123 +v 0.374991 -1.459056 0.731770 +v 0.374714 -1.483450 0.662305 +v 0.545528 -1.489547 0.673787 +v 0.546091 -1.463458 0.746013 +v 0.546616 -1.613244 0.632391 +v 0.546634 -1.619753 0.603475 +v 0.372428 -1.365586 0.715722 +v 0.374240 -1.410263 0.749902 +v 0.545510 -1.414563 0.764202 +v 0.543616 -1.367667 0.729756 +v 0.543616 -1.367667 0.729756 +v 0.545510 -1.414563 0.764202 +v 0.545781 -1.412543 0.738234 +v 0.543930 -1.368933 0.703084 +v 0.543930 -1.368933 0.703084 +v 0.545781 -1.412543 0.738234 +v 0.374525 -1.408523 0.724582 +v 0.372743 -1.366971 0.689789 +v 0.524766 -1.726672 0.616240 +v 0.524530 -1.726446 0.588843 +v 0.545663 -1.476695 0.649569 +v 0.546634 -1.619753 0.603475 +v 0.375602 -1.612360 0.593774 +v 0.374953 -1.470694 0.638660 +v 0.375602 -1.612360 0.593774 +v 0.375625 -1.606526 0.622338 +v 0.374714 -1.483450 0.662305 +v 0.375625 -1.606526 0.622338 +v 0.546616 -1.613244 0.632391 +v 0.545528 -1.489547 0.673787 +v 0.402045 -1.718800 0.584012 +v 0.433939 -1.739184 0.584559 +v 0.434597 -1.739218 0.611730 +v 0.402289 -1.719466 0.611076 +v 0.524530 -1.726446 0.588843 +v 0.402045 -1.718800 0.584012 +v 0.402045 -1.718800 0.584012 +v 0.402289 -1.719466 0.611076 +v 0.402289 -1.719466 0.611076 +v 0.524766 -1.726672 0.616240 +v 0.494350 -1.741018 0.588020 +v 0.495008 -1.740830 0.615353 +v 0.434597 -1.739218 0.611730 +v 0.495008 -1.740830 0.615353 +v 0.524766 -1.726672 0.616240 +v 0.524530 -1.726446 0.588843 +v 0.494350 -1.741018 0.588020 +v 0.433939 -1.739184 0.584559 +v 0.519275 -1.350397 -0.225124 +v 0.349133 -1.346083 -0.204807 +v 0.354105 -1.509777 -0.146240 +v 0.525944 -1.520415 -0.164345 +v 0.525944 -1.520415 -0.164345 +v 0.354105 -1.509777 -0.146240 +v 0.350543 -1.616189 -0.010538 +v 0.519345 -1.631505 -0.024067 +v 0.334968 -1.665798 0.216078 +v 0.494218 -1.685528 0.210700 +v 0.354516 -1.635702 0.398414 +v 0.520808 -1.652440 0.399551 +v 0.520808 -1.652440 0.399551 +v 0.354516 -1.635702 0.398414 +v 0.371119 -1.545647 0.545914 +v 0.543427 -1.557537 0.551903 +v 0.371749 -1.405910 0.686840 +v 0.543267 -1.413245 0.688647 +v 0.518887 -1.360973 -0.254638 +v 0.525349 -1.538732 -0.189907 +v 0.353528 -1.527614 -0.171018 +v 0.348714 -1.356366 -0.233527 +v 0.525349 -1.538732 -0.189907 +v 0.518131 -1.659743 -0.037726 +v 0.349312 -1.643665 -0.023575 +v 0.353528 -1.527614 -0.171018 +v 0.492453 -1.716832 0.209898 +v 0.333219 -1.696093 0.215321 +v 0.519984 -1.681721 0.410827 +v 0.353647 -1.664147 0.409124 +v 0.519984 -1.681721 0.410827 +v 0.543871 -1.579651 0.574251 +v 0.371543 -1.567201 0.567494 +v 0.353647 -1.664147 0.409124 +v 0.544137 -1.439280 0.715762 +v 0.372673 -1.431417 0.713093 +v 0.350543 -1.616189 -0.010538 +v 0.349312 -1.643665 -0.023575 +v 0.333219 -1.696093 0.215321 +v 0.334968 -1.665798 0.216078 +v 0.519345 -1.631505 -0.024067 +v 0.518131 -1.659743 -0.037726 +v 0.525349 -1.538732 -0.189907 +v 0.525944 -1.520415 -0.164345 +v 0.353647 -1.664147 0.409124 +v 0.354516 -1.635702 0.398414 +v 0.518887 -1.360973 -0.254638 +v 0.519275 -1.350397 -0.225124 +v 0.371543 -1.567201 0.567494 +v 0.371119 -1.545647 0.545914 +v 0.371749 -1.405910 0.686840 +v 0.372193 -1.403343 0.702067 +v 0.543654 -1.407842 0.701463 +v 0.543267 -1.413245 0.688647 +v 0.372673 -1.431417 0.713093 +v 0.371749 -1.405910 0.686840 +v 0.543267 -1.413245 0.688647 +v 0.544137 -1.439280 0.715762 +v 0.543871 -1.579651 0.574251 +v 0.543427 -1.557537 0.551903 +v 0.519275 -1.350397 -0.225124 +v 0.518887 -1.360973 -0.254638 +v 0.348714 -1.356366 -0.233527 +v 0.349133 -1.346083 -0.204807 +v 0.519984 -1.681721 0.410827 +v 0.520808 -1.652440 0.399551 +v 0.349133 -1.346083 -0.204807 +v 0.348714 -1.356366 -0.233527 +v 0.353528 -1.527614 -0.171018 +v 0.354105 -1.509777 -0.146240 +v 0.492453 -1.716832 0.209898 +v 0.494218 -1.685528 0.210700 +v 0.375362 -1.449355 0.709546 +v 0.374525 -1.408523 0.724582 +v 0.545781 -1.412543 0.738234 +v 0.546444 -1.453453 0.723123 +v 0.374240 -1.410263 0.749902 +v 0.374991 -1.459056 0.731770 +v 0.546091 -1.463458 0.746013 +v 0.545510 -1.414563 0.764202 +v 0.546444 -1.453453 0.723123 +v 0.545663 -1.476695 0.649569 +v 0.374953 -1.470694 0.638660 +v 0.375362 -1.449355 0.709546 +v 0.372866 -1.418779 0.717952 +v 0.544264 -1.423598 0.717870 +v 0.543654 -1.407842 0.701463 +v 0.544264 -1.423598 0.717870 +v 0.372866 -1.418779 0.717952 +v 0.372193 -1.403343 0.702067 +v 0.544264 -1.423598 0.717870 +v 0.372866 -1.418779 0.717952 +v 0.543930 -1.368933 0.703084 +v 0.372743 -1.366971 0.689789 +v 0.372428 -1.365586 0.715722 +v 0.543616 -1.367667 0.729756 +v -0.529076 -1.635680 0.695179 +v -0.382922 -1.630757 0.679202 +v -0.384172 -1.638376 0.652255 +v -0.530365 -1.643903 0.667985 +vt 0.964369 0.009894 +vt 0.964423 0.025662 +vt 0.977036 0.025102 +vt 0.977354 0.009741 +vt 0.960190 0.999331 +vt 0.959835 0.989524 +vt 0.947329 0.988989 +vt 0.947590 0.998419 +vt 0.959654 0.976568 +vt 0.947200 0.976515 +vt 0.958999 0.963167 +vt 0.946772 0.963570 +vt 0.959050 0.948913 +vt 0.946820 0.949799 +vt 0.959866 0.934474 +vt 0.960190 0.932448 +vt 0.947677 0.933353 +vt 0.947419 0.934961 +vt 0.712475 0.005204 +vt 0.712444 0.022449 +vt 0.724994 0.023415 +vt 0.724994 0.004737 +vt 0.965997 0.548614 +vt 0.978983 0.548635 +vt 0.978801 0.532257 +vt 0.966185 0.531693 +vt 0.954286 0.223398 +vt 0.941661 0.224362 +vt 0.941439 0.234296 +vt 0.953984 0.233713 +vt 0.941266 0.247242 +vt 0.953768 0.247150 +vt 0.940769 0.260671 +vt 0.953041 0.261042 +vt 0.940792 0.274944 +vt 0.953063 0.275819 +vt 0.953986 0.290491 +vt 0.941549 0.289958 +vt 0.941793 0.292300 +vt 0.954286 0.293281 +vt 0.761756 0.022947 +vt 0.774277 0.023506 +vt 0.774277 0.004665 +vt 0.761711 0.005471 +vt 0.853358 0.490127 +vt 0.855563 0.489330 +vt 0.855243 0.487421 +vt 0.852303 0.488627 +vt 0.820623 0.337433 +vt 0.822704 0.325895 +vt 0.820935 0.324917 +vt 0.818618 0.337351 +vt 0.872206 0.497840 +vt 0.872097 0.495894 +vt 0.835096 0.314857 +vt 0.833936 0.313527 +vt 0.929156 0.844917 +vt 0.929096 0.857534 +vt 0.930917 0.857479 +vt 0.930917 0.844852 +vt 0.856183 0.571851 +vt 0.855660 0.573565 +vt 0.860370 0.570834 +vt 0.860790 0.568894 +vt 0.850115 0.563244 +vt 0.838005 0.552622 +vt 0.836295 0.553582 +vt 0.848806 0.564719 +vt 0.857638 0.382927 +vt 0.842029 0.390356 +vt 0.841669 0.392323 +vt 0.857518 0.384934 +vt 0.836221 0.541577 +vt 0.834273 0.541655 +vt 0.839388 0.389275 +vt 0.835657 0.375165 +vt 0.834205 0.376526 +vt 0.838280 0.390814 +vt 0.837414 0.528504 +vt 0.835561 0.527955 +vt 0.827998 0.362931 +vt 0.826267 0.363916 +vt 0.843565 0.517057 +vt 0.841896 0.516090 +vt 0.821672 0.351064 +vt 0.819760 0.351625 +vt 0.850981 0.505258 +vt 0.849583 0.503931 +vt 0.852502 0.566778 +vt 0.851178 0.568167 +vt 0.852046 0.572238 +vt 0.853165 0.570732 +vt 0.840939 0.304330 +vt 0.841465 0.306101 +vt 0.846288 0.309148 +vt 0.845859 0.307167 +vt 0.166597 0.003547 +vt 0.166440 0.016243 +vt 0.170967 0.015935 +vt 0.170967 0.003268 +vt 0.852913 0.306235 +vt 0.851166 0.304912 +vt 0.998238 0.159544 +vt 0.998238 0.146842 +vt 0.994883 0.146447 +vt 0.994945 0.159159 +vt 0.836307 0.309820 +vt 0.837650 0.311266 +vt 0.838434 0.307199 +vt 0.837310 0.305636 +vt 0.885152 0.597146 +vt 0.885152 0.584455 +vt 0.881811 0.584892 +vt 0.881742 0.597597 +vt 0.854441 0.300457 +vt 0.856205 0.301603 +vt 0.857638 0.295870 +vt 0.855622 0.295669 +vt 0.869883 0.597381 +vt 0.869883 0.584796 +vt 0.862768 0.584987 +vt 0.862644 0.597600 +vt 0.865563 0.573174 +vt 0.867264 0.571850 +vt 0.931674 0.157477 +vt 0.931674 0.144878 +vt 0.925944 0.144612 +vt 0.926008 0.157228 +vt 0.917701 0.541695 +vt 0.919323 0.541699 +vt 0.918532 0.539337 +vt 0.916877 0.539364 +vt 0.540373 0.785163 +vt 0.540373 0.774282 +vt 0.535566 0.775759 +vt 0.535613 0.784834 +vt 0.870529 0.576689 +vt 0.868804 0.577838 +vt 0.870215 0.582997 +vt 0.872206 0.582779 +vt 0.551594 0.785163 +vt 0.551594 0.774289 +vt 0.547688 0.774776 +vt 0.547632 0.783855 +vt 0.917005 0.534903 +vt 0.918679 0.534876 +vt 0.546646 0.776897 +vt 0.546533 0.781368 +vt 0.919323 0.532658 +vt 0.917662 0.532653 +vt 0.534410 0.778238 +vt 0.534521 0.782702 +vt 0.881593 0.584959 +vt 0.870119 0.584139 +vt 0.870541 0.596911 +vt 0.881593 0.597593 +vt 0.985664 0.999572 +vt 0.985240 0.987388 +vt 0.972771 0.986617 +vt 0.972973 0.998381 +vt 0.983540 0.969575 +vt 0.971773 0.969477 +vt 0.985664 0.956776 +vt 0.973370 0.957080 +vt 0.971819 0.661564 +vt 0.970780 0.671569 +vt 0.983509 0.671873 +vt 0.984126 0.662329 +vt 0.971449 0.684685 +vt 0.984126 0.684757 +vt 0.852467 0.016939 +vt 0.852467 0.004290 +vt 0.841694 0.005021 +vt 0.841288 0.017807 +vt 0.983964 0.772404 +vt 0.971244 0.773625 +vt 0.971168 0.786573 +vt 0.983675 0.785797 +vt 0.970128 0.804608 +vt 0.981937 0.804557 +vt 0.971634 0.817593 +vt 0.983964 0.817972 +vt 0.128372 0.034032 +vt 0.140695 0.033233 +vt 0.140037 0.023951 +vt 0.127297 0.024291 +vt 0.140668 0.012072 +vt 0.127990 0.012139 +vt 0.902798 0.126115 +vt 0.900214 0.109199 +vt 0.897976 0.109117 +vt 0.900710 0.126951 +vt 0.306582 0.099975 +vt 0.314152 0.089127 +vt 0.312683 0.087323 +vt 0.304434 0.099094 +vt 0.903270 0.095847 +vt 0.901222 0.094926 +vt 0.326419 0.083855 +vt 0.325503 0.081725 +vt 0.910592 0.085350 +vt 0.909102 0.083657 +vt 0.352597 0.002046 +vt 0.352781 0.014727 +vt 0.353589 0.014766 +vt 0.353632 0.002090 +vt 0.921566 0.075603 +vt 0.919805 0.073546 +vt 0.325961 0.151606 +vt 0.314688 0.142175 +vt 0.313158 0.143926 +vt 0.324164 0.153727 +vt 0.493340 0.014636 +vt 0.493340 0.001987 +vt 0.491499 0.002145 +vt 0.491449 0.014802 +vt 0.306964 0.131332 +vt 0.304853 0.132296 +vt 0.921826 0.141706 +vt 0.910013 0.136613 +vt 0.908581 0.138359 +vt 0.920933 0.143778 +vt 0.303633 0.117507 +vt 0.301316 0.117588 +vt 0.301848 0.002565 +vt 0.301841 0.015170 +vt 0.305060 0.015116 +vt 0.305060 0.002497 +vt 0.179594 0.016246 +vt 0.179594 0.003622 +vt 0.175789 0.003525 +vt 0.175798 0.016136 +vt 0.925342 0.897487 +vt 0.925493 0.910180 +vt 0.930115 0.910561 +vt 0.930115 0.897908 +vt 0.355067 0.014815 +vt 0.355067 0.002143 +vt 0.325331 0.153811 +vt 0.326419 0.152527 +vt 0.921826 0.074491 +vt 0.920760 0.073246 +vt 0.140695 0.011087 +vt 0.128022 0.010971 +vt 0.977381 0.006133 +vt 0.964761 0.006133 +vt 0.966361 0.552487 +vt 0.978983 0.552401 +vt 0.054279 0.022131 +vt 0.067294 0.022189 +vt 0.066978 0.006828 +vt 0.054341 0.006360 +vt 0.960156 0.077948 +vt 0.947533 0.078826 +vt 0.947400 0.088256 +vt 0.959938 0.087755 +vt 0.947360 0.101287 +vt 0.959834 0.100711 +vt 0.946865 0.114130 +vt 0.958977 0.114109 +vt 0.946819 0.127799 +vt 0.959067 0.128364 +vt 0.960049 0.141051 +vt 0.947732 0.140543 +vt 0.947761 0.142554 +vt 0.960156 0.143824 +vt 0.261970 0.004606 +vt 0.249608 0.005939 +vt 0.249437 0.023723 +vt 0.261970 0.022786 +vt 0.820335 0.397450 +vt 0.820455 0.414373 +vt 0.833090 0.413900 +vt 0.833337 0.397522 +vt 0.954435 0.222012 +vt 0.953957 0.211694 +vt 0.941455 0.211052 +vt 0.941840 0.220988 +vt 0.953650 0.198184 +vt 0.941178 0.197597 +vt 0.952880 0.184360 +vt 0.940770 0.184257 +vt 0.953166 0.169585 +vt 0.940917 0.170082 +vt 0.954184 0.156775 +vt 0.954435 0.153370 +vt 0.942063 0.154557 +vt 0.941907 0.157182 +vt 0.012660 0.024053 +vt 0.012660 0.005282 +vt 0.000125 0.004524 +vt 0.000297 0.022845 +vt 0.840770 0.290945 +vt 0.839709 0.292487 +vt 0.842790 0.293788 +vt 0.843289 0.291917 +vt 0.168821 0.194648 +vt 0.166816 0.194593 +vt 0.168269 0.207156 +vt 0.170102 0.206302 +vt 0.859307 0.285844 +vt 0.859291 0.283896 +vt 0.180453 0.219413 +vt 0.181702 0.218165 +vt 0.818306 0.014547 +vt 0.820064 0.014590 +vt 0.820064 0.001946 +vt 0.818246 0.001913 +vt 0.838567 0.211060 +vt 0.843353 0.213717 +vt 0.842811 0.211808 +vt 0.837936 0.209384 +vt 0.833063 0.220038 +vt 0.831662 0.218649 +vt 0.819888 0.230563 +vt 0.821656 0.231413 +vt 0.208882 0.151811 +vt 0.208901 0.149800 +vt 0.191892 0.141818 +vt 0.192427 0.143745 +vt 0.818634 0.242595 +vt 0.820582 0.242549 +vt 0.189138 0.145184 +vt 0.188040 0.143591 +vt 0.185068 0.156585 +vt 0.186422 0.158043 +vt 0.819622 0.257409 +vt 0.821435 0.256744 +vt 0.176282 0.168621 +vt 0.177939 0.169722 +vt 0.826915 0.268624 +vt 0.828518 0.267553 +vt 0.168774 0.180259 +vt 0.170807 0.181123 +vt 0.835464 0.280101 +vt 0.836773 0.278687 +vt 0.835218 0.216358 +vt 0.835627 0.212370 +vt 0.834414 0.210939 +vt 0.833808 0.215056 +vt 0.186807 0.229069 +vt 0.191910 0.226578 +vt 0.192474 0.224631 +vt 0.187453 0.227339 +vt 0.151994 0.016140 +vt 0.156356 0.016501 +vt 0.156356 0.003836 +vt 0.151838 0.003441 +vt 0.200604 0.230749 +vt 0.202438 0.229549 +vt 0.052534 0.002290 +vt 0.049249 0.002752 +vt 0.049187 0.015462 +vt 0.052534 0.014985 +vt 0.182564 0.223274 +vt 0.183276 0.227518 +vt 0.184505 0.226035 +vt 0.184003 0.221924 +vt 0.183082 0.003545 +vt 0.179666 0.003153 +vt 0.179736 0.015860 +vt 0.183082 0.016242 +vt 0.207502 0.235724 +vt 0.208901 0.234258 +vt 0.427458 0.005969 +vt 0.427434 0.017081 +vt 0.440072 0.016707 +vt 0.440072 0.005719 +vt 0.853180 0.208794 +vt 0.851398 0.207581 +vt 0.995623 0.367826 +vt 0.995623 0.358331 +vt 0.982995 0.357867 +vt 0.983010 0.367428 +vt 0.922165 0.641635 +vt 0.921814 0.639260 +vt 0.919899 0.639101 +vt 0.920242 0.641507 +vt 0.429120 0.024941 +vt 0.438171 0.024461 +vt 0.859307 0.203768 +vt 0.857947 0.202300 +vt 0.993742 0.349954 +vt 0.984696 0.349420 +vt 0.921780 0.634784 +vt 0.919858 0.634625 +vt 0.991371 0.348507 +vt 0.986909 0.348400 +vt 0.920228 0.632437 +vt 0.922165 0.632566 +vt 0.431360 0.025980 +vt 0.435824 0.025904 +vt 0.925180 0.909636 +vt 0.925180 0.897018 +vt 0.914132 0.897797 +vt 0.913710 0.910556 +vt 0.985535 0.913122 +vt 0.972814 0.914329 +vt 0.972777 0.926088 +vt 0.985284 0.925301 +vt 0.971772 0.943230 +vt 0.983582 0.943117 +vt 0.973208 0.955632 +vt 0.985535 0.955920 +vt 0.780417 0.584467 +vt 0.792753 0.583903 +vt 0.792090 0.574341 +vt 0.779334 0.574438 +vt 0.792753 0.561462 +vt 0.780062 0.561328 +vt 0.971569 0.078654 +vt 0.960401 0.077589 +vt 0.960806 0.090356 +vt 0.971569 0.091278 +vt 0.979982 0.530978 +vt 0.979538 0.517581 +vt 0.967063 0.516827 +vt 0.967289 0.529779 +vt 0.977802 0.498824 +vt 0.966031 0.498795 +vt 0.979982 0.485412 +vt 0.967681 0.485812 +vt 0.935138 0.295318 +vt 0.934032 0.305078 +vt 0.946789 0.305257 +vt 0.947480 0.295961 +vt 0.934756 0.317226 +vt 0.947443 0.317132 +vt 0.858746 0.096154 +vt 0.856658 0.095317 +vt 0.853919 0.113150 +vt 0.856157 0.113068 +vt 0.741498 0.140492 +vt 0.739350 0.141373 +vt 0.747601 0.153144 +vt 0.749070 0.151340 +vt 0.857168 0.127342 +vt 0.859217 0.126421 +vt 0.760419 0.158742 +vt 0.761334 0.156612 +vt 0.865051 0.138612 +vt 0.866542 0.136919 +vt 0.959915 0.014845 +vt 0.960950 0.014816 +vt 0.960907 0.002132 +vt 0.960099 0.002152 +vt 0.875755 0.148723 +vt 0.877515 0.146665 +vt 0.760877 0.088861 +vt 0.759080 0.086740 +vt 0.748075 0.096541 +vt 0.749606 0.098292 +vt 0.761478 0.002352 +vt 0.759591 0.002146 +vt 0.759641 0.014822 +vt 0.761478 0.015020 +vt 0.739766 0.108172 +vt 0.741878 0.109136 +vt 0.877776 0.080563 +vt 0.876882 0.078491 +vt 0.864531 0.083910 +vt 0.865963 0.085656 +vt 0.736225 0.122881 +vt 0.738541 0.122963 +vt 0.298564 0.015107 +vt 0.301776 0.015170 +vt 0.301776 0.002520 +vt 0.298557 0.002470 +vt 0.975524 0.078555 +vt 0.971727 0.078655 +vt 0.971719 0.091288 +vt 0.975524 0.091200 +vt 0.991002 0.425469 +vt 0.995783 0.425143 +vt 0.995783 0.412486 +vt 0.991153 0.412778 +vt 0.962385 0.014738 +vt 0.962385 0.002059 +vt 0.761334 0.087940 +vt 0.760247 0.086656 +vt 0.876710 0.149023 +vt 0.877776 0.147778 +vt 0.934804 0.318394 +vt 0.947480 0.318117 +vt 0.054644 0.025891 +vt 0.067294 0.025798 +vt 0.833337 0.393755 +vt 0.820696 0.393579 +vt 0.920904 0.145333 +vt 0.920917 0.156161 +vt 0.857850 0.585976 +vt 0.857784 0.596801 +vn -0.7577 -0.1046 -0.6441 +vn -0.8560 -0.1590 -0.4918 +vn 0.7091 -0.2578 -0.6563 +vn 0.6077 -0.1146 -0.7858 +vn -0.8561 -0.1590 -0.4918 +vn -0.8270 -0.4086 -0.3861 +vn 0.6269 -0.5742 -0.5265 +vn 0.7091 -0.2578 -0.6562 +vn -0.8638 -0.4554 -0.2157 +vn 0.6148 -0.7232 -0.3146 +vn -0.8266 -0.5540 -0.0995 +vn 0.5763 -0.8033 -0.1504 +vn -0.7764 -0.6030 -0.1832 +vn 0.5410 -0.7935 -0.2787 +vn -0.8924 -0.4309 0.1342 +vn -0.8712 -0.2500 0.4225 +vn 0.7249 -0.4584 0.5142 +vn 0.7283 -0.6751 -0.1177 +vn -0.8712 -0.2500 0.4224 +vn -0.6145 -0.7690 0.1758 +vn 0.4873 -0.8255 0.2848 +vn 0.7248 -0.4585 0.5142 +vn -0.6842 0.0885 0.7239 +vn 0.7980 0.0841 0.5967 +vn 0.7146 0.2347 0.6590 +vn -0.5568 0.3008 0.7742 +vn -0.5568 0.3008 0.7743 +vn 0.7767 0.4595 0.4307 +vn -0.5684 0.6049 0.5577 +vn 0.7769 0.5744 0.2580 +vn -0.5421 0.7711 0.3341 +vn 0.8222 0.5613 0.0946 +vn -0.5506 0.8215 0.1481 +vn 0.8704 0.4861 0.0782 +vn -0.5937 0.7507 0.2898 +vn -0.5396 0.8413 0.0309 +vn 0.6904 0.7230 -0.0256 +vn 0.6666 0.4525 -0.5923 +vn -0.5811 0.5303 -0.6173 +vn -0.5811 0.5303 -0.6174 +vn 0.6666 0.4525 -0.5924 +vn 0.6748 -0.2623 -0.6898 +vn -0.5377 -0.1795 -0.8238 +vn 0.7283 -0.6751 -0.1176 +vn 0.7248 -0.4584 0.5142 +vn 0.6904 0.7229 -0.0257 +vn -0.5685 0.6049 0.5576 +vn 0.4873 -0.8255 0.2847 +vn 0.6748 -0.2623 -0.6899 +vn -0.6145 -0.7691 0.1758 +vn 0.7742 0.4431 -0.4519 +vn 0.6762 -0.5501 0.4900 +vn 0.8645 -0.3659 0.3448 +vn 0.5598 0.5617 -0.6092 +vn 0.7767 0.4595 0.4308 +vn -0.7764 -0.6031 -0.1832 +vn -0.5396 0.8413 0.0310 +vn 0.7768 0.5744 0.2581 +vn 0.5948 -0.3645 -0.7165 +vn 0.8115 0.2491 0.5286 +vn 0.6826 0.1075 0.7229 +vn 0.7796 -0.1359 -0.6114 +vn -0.5657 -0.5637 0.6019 +vn -0.8625 0.3833 -0.3303 +vn -0.6636 0.5455 -0.5119 +vn -0.7775 -0.4168 0.4710 +vn 0.6762 -0.5502 0.4900 +vn -0.5657 -0.5638 0.6018 +vn 0.8644 -0.3659 0.3448 +vn -0.7300 -0.0337 -0.6826 +vn -0.7273 -0.0544 0.6841 +vn -0.6756 0.3200 0.6642 +vn -0.5406 0.1161 0.8332 +vn -0.7086 -0.3515 -0.6118 +vn -0.8864 -0.0477 -0.4604 +vn -0.5406 0.1162 0.8332 +vn -0.7086 -0.3516 -0.6118 +vn -0.6993 0.1805 0.6917 +vn -0.7044 -0.3811 -0.5988 +vn -0.6642 -0.7316 -0.1536 +vn -0.5915 0.0369 0.8055 +vn -0.6636 0.5456 -0.5118 +vn 0.5598 0.5617 -0.6091 +vn 0.6153 -0.0464 -0.7870 +vn 0.8235 -0.0939 0.5595 +vn 0.6056 -0.7522 -0.2596 +vn 0.7016 0.0271 0.7121 +vn 0.2807 -0.0740 0.9569 +vn 0.1804 -0.9832 0.0268 +vn 0.6103 -0.4126 -0.6762 +vn 0.6057 -0.7522 -0.2596 +vn -0.6641 -0.7317 -0.1536 +vn 0.6103 -0.4125 -0.6763 +vn 0.7834 0.1293 0.6079 +vn 0.7834 0.1292 0.6079 +vn -0.6992 0.1805 0.6917 +vn -0.1962 -0.9788 0.0594 +vn -0.0906 -0.0599 0.9941 +vn -0.5915 0.0368 0.8055 +vn 0.1805 -0.9832 0.0268 +vn -0.5797 0.7453 0.3293 +vn -0.7963 0.3325 0.5053 +vn 0.7498 0.4028 0.5250 +vn 0.5719 0.7340 0.3662 +vn -0.7963 0.3324 0.5053 +vn -0.7932 0.4992 0.3489 +vn 0.7137 0.6592 0.2368 +vn 0.7497 0.4027 0.5250 +vn -0.7900 0.6116 0.0432 +vn 0.7110 0.7032 -0.0040 +vn -0.7989 0.5330 -0.2787 +vn 0.6960 0.6860 -0.2121 +vn -0.7855 0.4687 -0.4041 +vn 0.6809 0.5790 -0.4484 +vn 0.6960 0.6860 -0.2122 +vn -0.6936 0.6289 -0.3514 +vn 0.6121 0.6702 -0.4197 +vn -0.5592 0.3382 -0.7569 +vn 0.5914 0.3559 -0.7236 +vn 0.6671 -0.4224 -0.6137 +vn -0.6393 -0.4639 -0.6133 +vn 0.6671 -0.4223 -0.6137 +vn 0.6933 -0.6240 -0.3606 +vn -0.6258 -0.7277 -0.2808 +vn 0.7435 -0.6675 -0.0399 +vn -0.5641 -0.8257 -0.0050 +vn 0.7214 -0.6355 0.2752 +vn -0.6066 -0.7580 0.2397 +vn 0.7196 -0.5464 0.4285 +vn -0.6525 -0.6046 0.4569 +vn 0.7034 -0.3654 0.6097 +vn -0.5922 -0.3938 0.7031 +vn 0.7435 -0.6675 -0.0400 +vn 0.6932 -0.6240 -0.3606 +vn -0.6258 -0.7277 -0.2809 +vn -0.5798 0.7452 0.3293 +vn -0.5593 0.3381 -0.7569 +vn 0.6809 0.5791 -0.4483 +vn 0.7196 -0.5464 0.4284 +vn -0.6936 0.6289 -0.3513 +vn -0.5919 0.7774 0.2128 +vn 0.6262 0.7605 0.1718 +vn -0.7855 0.4688 -0.4041 +vn -0.6525 -0.6045 0.4569 +vn 0.5719 0.7340 0.3663 +vn -0.5593 0.3382 -0.7569 +vn -0.6067 -0.7579 0.2398 +vn 0.7743 0.4430 -0.4519 +vn 0.7796 -0.1358 -0.6114 +vn 0.6825 0.1075 0.7229 +vn -0.5657 -0.5637 0.6018 +vn 0.7743 0.4431 -0.4519 +vn -0.6636 0.5455 -0.5118 +vn -0.6050 0.2101 0.7680 +vn 0.6110 0.2279 0.7581 +vn -0.5918 0.7775 0.2128 +vn 0.6110 0.2280 0.7581 +vn -0.7086 -0.3516 -0.6117 +vn 0.7243 -0.1059 -0.6813 +vn -0.6466 -0.1134 -0.7544 +vn -0.7416 -0.2565 -0.6199 +vn 0.8300 -0.1605 -0.5341 +vn -0.6537 -0.5578 -0.5114 +vn 0.7962 -0.4082 -0.4466 +vn -0.6796 -0.6805 -0.2740 +vn 0.8254 -0.4823 -0.2933 +vn -0.6273 -0.7717 -0.1048 +vn 0.7822 -0.6064 -0.1429 +vn -0.5831 -0.7741 -0.2465 +vn 0.7422 -0.6353 -0.2135 +vn 0.9163 -0.3955 0.0636 +vn -0.6817 -0.7273 -0.0802 +vn -0.6791 -0.4732 0.5611 +vn 0.9065 -0.2933 0.3037 +vn -0.6791 -0.4732 0.5612 +vn -0.4722 -0.8336 0.2867 +vn 0.6266 -0.7710 0.1136 +vn 0.7198 0.0872 0.6887 +vn 0.5955 0.2998 0.7453 +vn -0.6802 0.2359 0.6940 +vn -0.7670 0.0855 0.6360 +vn 0.5954 0.2997 0.7454 +vn 0.6089 0.5848 0.5360 +vn -0.7565 0.4482 0.4762 +vn -0.6802 0.2360 0.6940 +vn 0.5940 0.7436 0.3070 +vn -0.7224 0.6153 0.3155 +vn 0.6041 0.7902 0.1035 +vn -0.7850 0.6047 0.1343 +vn 0.6255 0.7283 0.2800 +vn -0.8465 0.5148 0.1359 +vn 0.5149 0.8558 0.0505 +vn 0.5133 0.6021 -0.6115 +vn -0.7304 0.4618 -0.5033 +vn -0.7209 0.6918 0.0427 +vn 0.5132 0.6022 -0.6116 +vn 0.4877 -0.1478 -0.8604 +vn -0.7074 -0.2383 -0.6654 +vn -0.7304 0.4617 -0.5033 +vn 0.7962 -0.4082 -0.4465 +vn 0.5955 0.2997 0.7453 +vn -0.4722 -0.8335 0.2867 +vn 0.6266 -0.7710 0.1137 +vn -0.7952 0.4445 -0.4125 +vn -0.5889 0.5713 -0.5717 +vn -0.8434 -0.3702 0.3894 +vn -0.6517 -0.5490 0.5234 +vn -0.6466 -0.1135 -0.7544 +vn -0.7224 0.6153 0.3154 +vn 0.6041 0.7902 0.1034 +vn -0.7850 0.6047 0.1344 +vn -0.6306 -0.3634 -0.6858 +vn -0.8095 -0.1344 -0.5715 +vn -0.6453 0.1087 0.7562 +vn -0.7835 0.2506 0.5686 +vn 0.5941 -0.5647 0.5728 +vn 0.7959 -0.4298 0.4264 +vn 0.6419 0.5478 -0.5366 +vn 0.8456 0.3818 -0.3732 +vn -0.6517 -0.5490 0.5233 +vn -0.8434 -0.3702 0.3893 +vn 0.5941 -0.5648 0.5727 +vn 0.7174 -0.2030 0.6664 +vn 0.7391 0.0608 -0.6709 +vn -0.7835 0.2505 0.5686 +vn -0.6453 0.1086 0.7562 +vn 0.5819 0.1151 0.8051 +vn 0.7086 0.3188 0.6295 +vn 0.5819 0.1152 0.8051 +vn 0.8621 -0.0493 -0.5043 +vn 0.6764 -0.3528 -0.6465 +vn 0.8621 -0.0492 -0.5043 +vn -0.8095 -0.1345 -0.5715 +vn 0.6012 -0.5265 0.6012 +vn 0.6390 -0.4385 -0.6320 +vn 0.6419 0.5479 -0.5365 +vn 0.7391 0.0608 -0.6708 +vn -0.6966 0.0490 -0.7158 +vn -0.6966 0.0490 -0.7157 +vn -0.7614 -0.2102 0.6133 +vn 0.7959 -0.4297 0.4264 +vn -0.6183 -0.4139 -0.6681 +vn -0.1979 -0.7215 -0.6635 +vn -0.2413 -0.7292 0.6403 +vn -0.6403 -0.4932 0.5888 +vn -0.6404 -0.4932 0.5888 +vn 0.1797 -0.7352 -0.6536 +vn 0.1314 -0.7393 0.6604 +vn -0.1980 -0.7215 -0.6635 +vn 0.5969 0.7442 0.2998 +vn -0.5515 0.7350 0.3944 +vn -0.7218 0.4041 0.5619 +vn 0.8212 0.3310 0.4647 +vn 0.8212 0.3310 0.4648 +vn -0.7218 0.4041 0.5620 +vn -0.6998 0.6605 0.2722 +vn 0.8105 0.4978 0.3086 +vn -0.7090 0.7045 0.0317 +vn 0.7922 0.6102 0.0035 +vn -0.7045 0.6873 -0.1770 +vn 0.7849 0.5316 -0.3184 +vn 0.7849 0.5316 -0.3185 +vn -0.7045 0.6873 -0.1771 +vn -0.7015 0.5803 -0.4137 +vn 0.7651 0.4674 -0.4430 +vn -0.6312 0.6713 -0.3885 +vn 0.6762 0.6277 -0.3857 +vn 0.5212 0.3372 -0.7840 +vn 0.6069 -0.4650 -0.6445 +vn -0.6978 -0.4212 -0.5794 +vn -0.6263 0.3570 -0.6930 +vn 0.6096 -0.7288 -0.3118 +vn -0.7116 -0.6227 -0.3254 +vn -0.6978 -0.4211 -0.5794 +vn 0.5616 -0.8267 -0.0333 +vn -0.7458 -0.6662 -0.0026 +vn 0.6165 -0.7591 0.2090 +vn -0.7078 -0.6342 0.3111 +vn 0.6735 -0.6057 0.4237 +vn -0.6982 -0.5451 0.4640 +vn -0.7078 -0.6342 0.3110 +vn 0.6260 -0.3948 0.6725 +vn -0.6726 -0.3642 0.6442 +vn -0.6998 0.6605 0.2723 +vn -0.7115 -0.6228 -0.3254 +vn -0.7090 0.7045 0.0316 +vn 0.6096 -0.7288 -0.3119 +vn 0.8213 0.3310 0.4647 +vn -0.6311 0.6713 -0.3886 +vn -0.6155 0.7616 0.2029 +vn 0.6032 0.7764 0.1829 +vn -0.6311 0.6714 -0.3885 +vn 0.6762 0.6277 -0.3858 +vn -0.6263 0.3570 -0.6931 +vn -0.5515 0.7350 0.3945 +vn 0.6166 -0.7590 0.2091 +vn 0.7848 0.5316 -0.3185 +vn -0.5516 0.7350 0.3944 +vn 0.5617 -0.8267 -0.0333 +vn -0.7952 0.4444 -0.4126 +vn -0.8095 -0.1344 -0.5716 +vn -0.6452 0.1086 0.7562 +vn 0.5941 -0.5648 0.5728 +vn -0.5888 0.5713 -0.5718 +vn -0.5718 0.2290 0.7878 +vn 0.6431 0.2090 0.7367 +vn 0.6032 0.7764 0.1828 +vn 0.7835 0.1293 0.6079 +vn 0.6103 -0.4126 -0.6763 +usemtl Scene_-_Root +s 1 +f 18816/18816/13495 18817/18817/13496 18818/18818/13497 +f 18816/18816/13495 18818/18818/13497 18819/18819/13498 +f 18820/18820/13499 18821/18821/13500 18822/18822/13501 +f 18820/18820/13499 18822/18822/13501 18823/18823/13502 +f 18821/18821/13500 18824/18824/13503 18825/18825/13504 +f 18821/18821/13500 18825/18825/13504 18822/18822/13501 +f 18824/18824/13503 18826/18826/13505 18827/18827/13506 +f 18824/18824/13503 18827/18827/13506 18825/18825/13504 +f 18826/18826/13505 18828/18828/13507 18829/18829/13508 +f 18826/18826/13505 18829/18829/13508 18827/18827/13506 +f 18830/18830/13509 18831/18831/13510 18832/18832/13511 +f 18830/18830/13509 18832/18832/13511 18833/18833/13512 +f 18834/18834/13513 18835/18835/13514 18836/18836/13515 +f 18834/18834/13513 18836/18836/13515 18837/18837/13516 +f 18838/18838/13517 18839/18839/13518 18840/18840/13519 +f 18838/18838/13517 18840/18840/13519 18841/18841/13520 +f 18842/18842/13521 18843/18843/13519 18844/18844/13522 +f 18842/18842/13521 18844/18844/13522 18845/18845/13523 +f 18845/18845/13523 18844/18844/13522 18846/18846/13524 +f 18845/18845/13523 18846/18846/13524 18847/18847/13525 +f 18847/18847/13525 18846/18846/13524 18848/18848/13526 +f 18847/18847/13525 18848/18848/13526 18849/18849/13527 +f 18849/18849/13527 18848/18848/13526 18850/18850/13528 +f 18849/18849/13527 18850/18850/13528 18851/18851/13529 +f 18852/18852/13530 18853/18853/13531 18854/18854/13532 +f 18852/18852/13530 18854/18854/13532 18855/18855/13533 +f 18856/18856/13534 18857/18857/13535 18858/18858/13536 +f 18856/18856/13534 18858/18858/13536 18859/18859/13537 +f 18860/18860/13538 18861/18861/13539 18862/18862/13535 +f 18860/18860/13538 18862/18862/13535 18863/18863/13540 +f 18864/18864/13500 18865/18865/13496 18866/18866/13520 +f 18864/18864/13500 18866/18866/13520 18867/18867/13541 +f 18861/18861/13539 18868/18868/13542 18869/18869/13543 +f 18861/18861/13539 18869/18869/13543 18862/18862/13535 +f 18865/18865/13496 18870/18870/13495 18871/18871/13517 +f 18865/18865/13496 18871/18871/13517 18866/18866/13520 +f 18872/18872/13515 18873/18873/13544 18874/18874/13537 +f 18872/18872/13515 18874/18874/13537 18875/18875/13536 +f 18876/18876/13545 18877/18877/13546 18878/18878/13547 +f 18876/18876/13545 18878/18878/13547 18879/18879/13548 +f 18880/18880/13498 18881/18881/13497 18882/18882/13519 +f 18880/18880/13498 18882/18882/13519 18883/18883/13518 +f 18884/18884/13544 18885/18885/13510 18886/18886/13533 +f 18884/18884/13544 18886/18886/13533 18887/18887/13537 +f 18881/18881/13497 18888/18888/13501 18889/18889/13549 +f 18881/18881/13497 18889/18889/13549 18882/18882/13519 +f 18890/18890/13509 18891/18891/13550 18892/18892/13529 +f 18890/18890/13509 18892/18892/13529 18893/18893/13551 +f 18888/18888/13501 18894/18894/13504 18895/18895/13552 +f 18888/18888/13501 18895/18895/13552 18889/18889/13549 +f 18891/18891/13550 18896/18896/13505 18897/18897/13527 +f 18891/18891/13550 18897/18897/13527 18892/18892/13529 +f 18894/18894/13504 18898/18898/13506 18899/18899/13526 +f 18894/18894/13504 18899/18899/13526 18895/18895/13552 +f 18896/18896/13505 18900/18900/13503 18901/18901/13525 +f 18896/18896/13505 18901/18901/13525 18897/18897/13527 +f 18898/18898/13506 18902/18902/13508 18903/18903/13528 +f 18898/18898/13506 18903/18903/13528 18899/18899/13526 +f 18900/18900/13503 18864/18864/13500 18867/18867/13541 +f 18900/18900/13503 18867/18867/13541 18901/18901/13525 +f 18904/18904/13553 18905/18905/13554 18906/18906/13555 +f 18904/18904/13553 18906/18906/13555 18907/18907/13556 +f 18908/18908/13557 18909/18909/13558 18910/18910/13559 +f 18908/18908/13557 18910/18910/13559 18911/18911/13560 +f 18912/18912/13561 18913/18913/13562 18914/18914/13560 +f 18912/18912/13561 18914/18914/13560 18915/18915/13563 +f 18911/18911/13560 18910/18910/13559 18916/18916/13564 +f 18911/18911/13560 18916/18916/13564 18917/18917/13565 +f 18918/18918/13554 18919/18919/13566 18920/18920/13567 +f 18918/18918/13554 18920/18920/13567 18921/18921/13555 +f 18922/18922/13566 18923/18923/13568 18924/18924/13569 +f 18922/18922/13566 18924/18924/13569 18925/18925/13570 +f 18926/18926/13571 18927/18927/13553 18928/18928/13556 +f 18926/18926/13571 18928/18928/13556 18929/18929/13569 +f 18930/18930/13572 18931/18931/13573 18932/18932/13574 +f 18930/18930/13572 18932/18932/13574 18933/18933/13575 +f 18934/18934/13576 18935/18935/13577 18936/18936/13578 +f 18934/18934/13576 18936/18936/13578 18937/18937/13564 +f 18879/18879/13548 18878/18878/13547 18938/18938/13579 +f 18879/18879/13548 18938/18938/13579 18939/18939/13578 +f 18940/18940/13563 18941/18941/13560 18942/18942/13565 +f 18940/18940/13563 18942/18942/13565 18943/18943/13579 +f 18944/18944/13580 18945/18945/13581 18946/18946/13582 +f 18944/18944/13580 18946/18946/13582 18947/18947/13583 +f 18948/18948/13573 18949/18949/13584 18950/18950/13585 +f 18948/18948/13573 18950/18950/13585 18951/18951/13586 +f 18952/18952/13587 18953/18953/13588 18954/18954/13581 +f 18952/18952/13587 18954/18954/13581 18955/18955/13585 +f 18956/18956/13589 18957/18957/13590 18958/18958/13575 +f 18956/18956/13589 18958/18958/13575 18959/18959/13581 +f 18960/18960/13591 18947/18947/13583 18946/18946/13582 +f 18960/18960/13591 18946/18946/13582 18961/18961/13592 +f 18959/18959/13581 18958/18958/13575 18962/18962/13592 +f 18959/18959/13581 18962/18962/13592 18963/18963/13582 +f 18964/18964/13593 18965/18965/13574 18960/18960/13591 +f 18964/18964/13593 18960/18960/13591 18961/18961/13592 +f 18951/18951/13586 18950/18950/13585 18966/18966/13594 +f 18951/18951/13586 18966/18966/13594 18967/18967/13591 +f 18968/18968/13595 18969/18969/13596 18970/18970/13597 +f 18968/18968/13595 18970/18970/13597 18971/18971/13598 +f 18972/18972/13599 18973/18973/13600 18974/18974/13601 +f 18972/18972/13599 18974/18974/13601 18975/18975/13602 +f 18973/18973/13600 18976/18976/13603 18977/18977/13604 +f 18973/18973/13600 18977/18977/13604 18974/18974/13601 +f 18976/18976/13603 18978/18978/13605 18979/18979/13606 +f 18976/18976/13603 18979/18979/13606 18977/18977/13604 +f 18980/18980/13605 18981/18981/13607 18982/18982/13608 +f 18980/18980/13605 18982/18982/13608 18983/18983/13609 +f 18981/18981/13607 18984/18984/13610 18985/18985/13611 +f 18981/18981/13607 18985/18985/13611 18982/18982/13608 +f 18986/18986/13612 18987/18987/13613 18988/18988/13614 +f 18986/18986/13612 18988/18988/13614 18989/18989/13615 +f 18990/18990/13615 18991/18991/13616 18992/18992/13617 +f 18990/18990/13615 18992/18992/13617 18993/18993/13618 +f 18993/18993/13618 18992/18992/13617 18994/18994/13619 +f 18993/18993/13618 18994/18994/13619 18995/18995/13620 +f 18995/18995/13620 18994/18994/13619 18996/18996/13621 +f 18995/18995/13620 18996/18996/13621 18997/18997/13622 +f 18998/18998/13622 18999/18999/13621 19000/19000/13623 +f 18998/18998/13622 19000/19000/13623 19001/19001/13624 +f 19001/19001/13624 19000/19000/13623 19002/19002/13625 +f 19001/19001/13624 19002/19002/13625 19003/19003/13626 +f 19004/19004/13601 19005/19005/13604 19006/19006/13627 +f 19004/19004/13601 19006/19006/13627 19007/19007/13628 +f 19008/19008/13600 19009/19009/13596 19010/19010/13615 +f 19008/19008/13600 19010/19010/13615 19011/19011/13629 +f 19005/19005/13604 19012/19012/13609 19013/19013/13621 +f 19005/19005/13604 19013/19013/13621 19006/19006/13627 +f 19009/19009/13596 19014/19014/13630 19015/19015/13631 +f 19009/19009/13596 19015/19015/13631 19010/19010/13615 +f 19012/19012/13609 19016/19016/13632 19017/19017/13633 +f 19012/19012/13609 19017/19017/13633 19013/19013/13621 +f 19018/19018/13611 19019/19019/13634 19020/19020/13635 +f 19018/19018/13611 19020/19020/13635 19021/19021/13636 +f 19016/19016/13632 19022/19022/13611 19023/19023/13625 +f 19016/19016/13632 19023/19023/13625 19017/19017/13633 +f 19024/19024/13610 19025/19025/13637 19026/19026/13638 +f 19024/19024/13610 19026/19026/13638 19027/19027/13626 +f 19028/19028/13630 19029/19029/13639 19030/19030/13613 +f 19028/19028/13630 19030/19030/13613 19031/19031/13640 +f 19025/19025/13637 19032/19032/13605 19033/19033/13641 +f 19025/19025/13637 19033/19033/13641 19026/19026/13638 +f 19034/19034/13598 19035/19035/13597 19036/19036/13614 +f 19034/19034/13598 19036/19036/13614 19037/19037/13613 +f 19032/19032/13605 19038/19038/13603 19039/19039/13620 +f 19032/19032/13605 19039/19039/13620 19033/19033/13641 +f 19035/19035/13597 19004/19004/13601 19007/19007/13628 +f 19035/19035/13597 19007/19007/13628 19036/19036/13614 +f 19038/19038/13603 19008/19008/13600 19011/19011/13629 +f 19038/19038/13603 19011/19011/13629 19039/19039/13620 +f 19040/19040/13642 19041/19041/13558 19042/19042/13569 +f 19040/19040/13642 19042/19042/13569 19043/19043/13643 +f 19044/19044/13644 19045/19045/13567 19046/19046/13645 +f 19044/19044/13644 19046/19046/13645 19047/19047/13561 +f 18909/18909/13558 18908/18908/13557 18925/18925/13570 +f 18909/18909/13558 18925/18925/13570 18924/18924/13569 +f 18907/18907/13556 18906/18906/13555 18877/18877/13546 +f 18907/18907/13556 18877/18877/13546 18876/18876/13545 +f 19048/19048/13558 19049/19049/13646 19050/19050/13548 +f 19048/19048/13558 19050/19050/13548 19051/19051/13647 +f 19021/19021/13636 19020/19020/13635 19052/19052/13648 +f 19021/19021/13636 19052/19052/13648 19053/19053/13649 +f 19024/19024/13610 19027/19027/13626 19054/19054/13648 +f 19024/19024/13610 19054/19054/13648 19055/19055/13650 +f 19023/19023/13625 19022/19022/13611 19056/19056/13636 +f 19023/19023/13625 19056/19056/13636 19057/19057/13649 +f 19003/19003/13626 19002/19002/13625 19058/19058/13651 +f 19003/19003/13626 19058/19058/13651 19059/19059/13648 +f 18816/18816/13495 18819/18819/13498 19060/19060/13553 +f 18816/18816/13495 19060/19060/13553 19061/19061/13652 +f 18871/18871/13517 18870/18870/13495 18923/18923/13568 +f 18871/18871/13517 18923/18923/13568 18922/18922/13566 +f 18839/18839/13518 18838/18838/13517 19062/19062/13566 +f 18839/18839/13518 19062/19062/13566 19063/19063/13554 +f 18880/18880/13498 18883/18883/13518 18905/18905/13554 +f 18880/18880/13498 18905/18905/13554 18904/18904/13553 +f 19064/19064/13653 19065/19065/13654 19066/19066/13655 +f 19064/19064/13653 19066/19066/13655 19067/19067/13656 +f 19068/19068/13656 19069/19069/13655 19070/19070/13657 +f 19068/19068/13656 19070/19070/13657 19071/19071/13658 +f 19071/19071/13658 19070/19070/13657 19072/19072/13659 +f 19071/19071/13658 19072/19072/13659 19073/19073/13660 +f 19073/19073/13660 19072/19072/13659 19074/19074/13661 +f 19073/19073/13660 19074/19074/13661 19075/19075/13662 +f 19075/19075/13662 19074/19074/13661 19076/19076/13663 +f 19075/19075/13662 19076/19076/13663 19077/19077/13664 +f 19078/19078/13665 19079/19079/13666 19080/19080/13667 +f 19078/19078/13665 19080/19080/13667 19081/19081/13668 +f 19082/19082/13668 19083/19083/13669 19084/19084/13670 +f 19082/19082/13668 19084/19084/13670 19085/19085/13671 +f 19086/19086/13672 19087/19087/13673 19088/19088/13674 +f 19086/19086/13672 19088/19088/13674 19089/19089/13675 +f 19090/19090/13676 19091/19091/13677 19092/19092/13678 +f 19090/19090/13676 19092/19092/13678 19093/19093/13679 +f 19091/19091/13677 19094/19094/13680 19095/19095/13681 +f 19091/19091/13677 19095/19095/13681 19092/19092/13678 +f 19094/19094/13680 19096/19096/13682 19097/19097/13683 +f 19094/19094/13680 19097/19097/13683 19095/19095/13681 +f 19096/19096/13682 19098/19098/13684 19099/19099/13685 +f 19096/19096/13682 19099/19099/13685 19097/19097/13683 +f 19100/19100/13686 19101/19101/13687 19102/19102/13688 +f 19100/19100/13686 19102/19102/13688 19103/19103/13689 +f 19104/19104/13690 19105/19105/13691 19106/19106/13692 +f 19104/19104/13690 19106/19106/13692 19107/19107/13688 +f 19108/19108/13666 19109/19109/13689 19110/19110/13693 +f 19108/19108/13666 19110/19110/13693 19111/19111/13669 +f 19112/19112/13694 19113/19113/13677 19114/19114/13695 +f 19112/19112/13694 19114/19114/13695 19115/19115/13656 +f 19111/19111/13669 19110/19110/13693 19116/19116/13692 +f 19111/19111/13669 19116/19116/13692 19117/19117/13696 +f 19115/19115/13656 19114/19114/13695 19118/19118/13672 +f 19115/19115/13656 19118/19118/13672 19119/19119/13653 +f 19120/19120/13670 19121/19121/13692 19122/19122/13691 +f 19120/19120/13670 19122/19122/13691 19123/19123/13697 +f 19124/19124/13698 19125/19125/13699 19126/19126/13700 +f 19124/19124/13698 19126/19126/13700 19127/19127/13701 +f 19128/19128/13702 19129/19129/13675 19130/19130/13679 +f 19128/19128/13702 19130/19130/13679 19131/19131/13655 +f 19132/19132/13697 19133/19133/13691 19134/19134/13687 +f 19132/19132/13697 19134/19134/13687 19135/19135/13668 +f 19131/19131/13655 19130/19130/13679 19136/19136/13678 +f 19131/19131/13655 19136/19136/13678 19137/19137/13657 +f 19138/19138/13665 19139/19139/13686 19140/19140/13684 +f 19138/19138/13665 19140/19140/13684 19141/19141/13664 +f 19137/19137/13657 19136/19136/13678 19142/19142/13703 +f 19137/19137/13657 19142/19142/13703 19143/19143/13659 +f 19141/19141/13664 19140/19140/13684 19144/19144/13704 +f 19141/19141/13664 19144/19144/13704 19145/19145/13662 +f 19143/19143/13659 19142/19142/13703 19146/19146/13705 +f 19143/19143/13659 19146/19146/13705 19147/19147/13661 +f 19145/19145/13662 19144/19144/13704 19148/19148/13680 +f 19145/19145/13662 19148/19148/13680 19149/19149/13660 +f 19147/19147/13661 19146/19146/13705 19150/19150/13685 +f 19147/19147/13661 19150/19150/13685 19151/19151/13663 +f 19149/19149/13660 19148/19148/13680 19113/19113/13677 +f 19149/19149/13660 19113/19113/13677 19112/19112/13694 +f 19152/19152/13706 19153/19153/13707 19154/19154/13708 +f 19152/19152/13706 19154/19154/13708 19155/19155/13709 +f 19156/19156/13710 19157/19157/13711 19158/19158/13712 +f 19156/19156/13710 19158/19158/13712 19159/19159/13713 +f 19160/19160/13714 19161/19161/13715 19162/19162/13711 +f 19160/19160/13714 19162/19162/13711 19163/19163/13716 +f 19157/19157/13711 19164/19164/13717 19165/19165/13718 +f 19157/19157/13711 19165/19165/13718 19158/19158/13712 +f 19166/19166/13719 19167/19167/13720 19168/19168/13721 +f 19166/19166/13719 19168/19168/13721 19169/19169/13722 +f 19170/19170/13722 19171/19171/13723 19172/19172/13724 +f 19170/19170/13722 19172/19172/13724 19173/19173/13725 +f 19174/19174/13725 19175/19175/13726 19176/19176/13727 +f 19174/19174/13725 19176/19176/13727 19177/19177/13706 +f 19164/19164/13717 19178/19178/13728 19179/19179/13729 +f 19164/19164/13717 19179/19179/13729 19165/19165/13718 +f 19180/19180/13730 19181/19181/13731 19182/19182/13732 +f 19180/19180/13730 19182/19182/13732 19183/19183/13699 +f 19125/19125/13699 19184/19184/13733 19185/19185/13734 +f 19125/19125/13699 19185/19185/13734 19126/19126/13700 +f 19186/19186/13715 19187/19187/13734 19188/19188/13717 +f 19186/19186/13715 19188/19188/13717 19189/19189/13735 +f 19190/19190/13736 19191/19191/13737 19192/19192/13738 +f 19190/19190/13736 19192/19192/13738 19193/19193/13739 +f 19181/19181/13731 19194/19194/13729 19195/19195/13736 +f 19181/19181/13731 19195/19195/13736 19182/19182/13732 +f 19184/19184/13733 19196/19196/13736 19197/19197/13740 +f 19184/19184/13733 19197/19197/13740 19185/19185/13734 +f 19187/19187/13734 19198/19198/13739 19199/19199/13728 +f 19187/19187/13734 19199/19199/13728 19188/19188/13717 +f 19200/19200/13741 19201/19201/13742 19192/19192/13738 +f 19200/19200/13741 19192/19192/13738 19191/19191/13737 +f 19198/19198/13739 19202/19202/13738 19203/19203/13742 +f 19198/19198/13739 19203/19203/13742 19199/19199/13728 +f 19204/19204/13728 19201/19201/13742 19200/19200/13741 +f 19204/19204/13728 19200/19200/13741 19205/19205/13729 +f 19194/19194/13729 19206/19206/13741 19207/19207/13743 +f 19194/19194/13729 19207/19207/13743 19195/19195/13736 +f 19208/19208/13744 19209/19209/13745 19210/19210/13746 +f 19208/19208/13744 19210/19210/13746 19211/19211/13747 +f 19212/19212/13748 19213/19213/13749 19214/19214/13750 +f 19212/19212/13748 19214/19214/13750 19215/19215/13751 +f 19215/19215/13751 19214/19214/13750 19216/19216/13752 +f 19215/19215/13751 19216/19216/13752 19217/19217/13753 +f 19217/19217/13753 19216/19216/13752 19218/19218/13754 +f 19217/19217/13753 19218/19218/13754 19219/19219/13755 +f 19220/19220/13756 19221/19221/13757 19222/19222/13758 +f 19220/19220/13756 19222/19222/13758 19223/19223/13759 +f 19223/19223/13759 19222/19222/13758 19224/19224/13760 +f 19223/19223/13759 19224/19224/13760 19225/19225/13761 +f 19226/19226/13762 19227/19227/13763 19228/19228/13764 +f 19226/19226/13762 19228/19228/13764 19229/19229/13765 +f 19230/19230/13763 19231/19231/13766 19232/19232/13767 +f 19230/19230/13763 19232/19232/13767 19233/19233/13768 +f 19231/19231/13766 19234/19234/13769 19235/19235/13770 +f 19231/19231/13766 19235/19235/13770 19232/19232/13767 +f 19234/19234/13769 19236/19236/13771 19237/19237/13772 +f 19234/19234/13769 19237/19237/13772 19235/19235/13770 +f 19238/19238/13771 19239/19239/13773 19240/19240/13774 +f 19238/19238/13771 19240/19240/13774 19241/19241/13775 +f 19239/19239/13773 19242/19242/13776 19243/19243/13777 +f 19239/19239/13773 19243/19243/13777 19240/19240/13774 +f 19244/19244/13778 19245/19245/13779 19246/19246/13770 +f 19244/19244/13778 19246/19246/13770 19247/19247/13780 +f 19248/19248/13751 19249/19249/13781 19250/19250/13763 +f 19248/19248/13751 19250/19250/13763 19251/19251/13782 +f 19247/19247/13780 19246/19246/13770 19252/19252/13775 +f 19247/19247/13780 19252/19252/13775 19253/19253/13754 +f 19251/19251/13782 19250/19250/13763 19254/19254/13762 +f 19251/19251/13782 19254/19254/13762 19255/19255/13744 +f 19253/19253/13754 19252/19252/13775 19256/19256/13774 +f 19253/19253/13754 19256/19256/13774 19257/19257/13758 +f 19258/19258/13783 19259/19259/13784 19260/19260/13785 +f 19258/19258/13783 19260/19260/13785 19261/19261/13761 +f 19257/19257/13758 19256/19256/13774 19262/19262/13777 +f 19257/19257/13758 19262/19262/13777 19263/19263/13786 +f 19264/19264/13787 19265/19265/13776 19266/19266/13773 +f 19264/19264/13787 19266/19266/13773 19267/19267/13759 +f 19268/19268/13744 19269/19269/13762 19270/19270/13788 +f 19268/19268/13744 19270/19270/13788 19271/19271/13789 +f 19267/19267/13759 19266/19266/13773 19272/19272/13790 +f 19267/19267/13759 19272/19272/13790 19273/19273/13791 +f 19274/19274/13792 19275/19275/13788 19276/19276/13764 +f 19274/19274/13792 19276/19276/13764 19277/19277/13746 +f 19273/19273/13791 19272/19272/13790 19278/19278/13793 +f 19273/19273/13791 19278/19278/13793 19279/19279/13753 +f 19277/19277/13746 19276/19276/13764 19245/19245/13779 +f 19277/19277/13746 19245/19245/13779 19244/19244/13778 +f 19279/19279/13753 19278/19278/13793 19249/19249/13781 +f 19279/19279/13753 19249/19249/13781 19248/19248/13751 +f 19280/19280/13794 19281/19281/13795 19282/19282/13724 +f 19280/19280/13794 19282/19282/13724 19283/19283/13713 +f 19284/19284/13796 19285/19285/13714 19286/19286/13797 +f 19284/19284/13796 19286/19286/13797 19287/19287/13721 +f 19159/19159/13713 19172/19172/13724 19171/19171/13723 +f 19159/19159/13713 19171/19171/13723 19156/19156/13710 +f 19153/19153/13707 19124/19124/13698 19127/19127/13701 +f 19153/19153/13707 19127/19127/13701 19154/19154/13708 +f 19288/19288/13713 19289/19289/13712 19290/19290/13798 +f 19288/19288/13713 19290/19290/13798 19291/19291/13698 +f 19259/19259/13784 19292/19292/13799 19293/19293/13800 +f 19259/19259/13784 19293/19293/13800 19260/19260/13785 +f 19264/19264/13787 19294/19294/13801 19295/19295/13800 +f 19264/19264/13787 19295/19295/13800 19265/19265/13776 +f 19262/19262/13777 19296/19296/13799 19297/19297/13784 +f 19262/19262/13777 19297/19297/13784 19263/19263/13786 +f 19242/19242/13776 19298/19298/13800 19299/19299/13799 +f 19242/19242/13776 19299/19299/13799 19243/19243/13777 +f 19064/19064/13653 19300/19300/13725 19301/19301/13706 +f 19064/19064/13653 19301/19301/13706 19065/19065/13654 +f 19118/19118/13672 19170/19170/13722 19173/19173/13725 +f 19118/19118/13672 19173/19173/13725 19119/19119/13653 +f 19089/19089/13675 19302/19302/13719 19303/19303/13722 +f 19089/19089/13675 19303/19303/13722 19086/19086/13672 +f 19128/19128/13702 19152/19152/13706 19155/19155/13709 +f 19128/19128/13702 19155/19155/13709 19129/19129/13675 +f 18943/18943/13579 18942/18942/13565 19304/19304/13572 +f 18943/18943/13579 19304/19304/13572 19305/19305/13802 +f 18939/18939/13578 18938/18938/13579 18953/18953/13588 +f 18939/18939/13578 18953/18953/13588 18952/18952/13587 +f 18937/18937/13564 18936/18936/13578 19306/19306/13803 +f 18937/18937/13564 19306/19306/13803 19307/19307/13573 +f 18917/18917/13565 18916/18916/13564 18931/18931/13573 +f 18917/18917/13565 18931/18931/13573 18930/18930/13572 +f 18885/18885/13510 18890/18890/13509 18893/18893/13551 +f 18885/18885/13510 18893/18893/13551 18886/18886/13533 +f 18902/18902/13508 18860/18860/13538 18863/18863/13540 +f 18902/18902/13508 18863/18863/13540 18903/18903/13528 +f 18851/18851/13529 18850/18850/13528 18853/18853/13531 +f 18851/18851/13529 18853/18853/13531 18852/18852/13530 +f 18828/18828/13507 18830/18830/13509 18833/18833/13512 +f 18828/18828/13507 18833/18833/13512 18829/18829/13508 +f 19135/19135/13668 19134/19134/13687 19139/19139/13686 +f 19135/19135/13668 19139/19139/13686 19138/19138/13665 +f 19151/19151/13663 19150/19150/13685 19109/19109/13689 +f 19151/19151/13663 19109/19109/13689 19108/19108/13666 +f 19098/19098/13684 19100/19100/13686 19103/19103/13689 +f 19098/19098/13684 19103/19103/13689 19099/19099/13685 +f 19077/19077/13664 19076/19076/13663 19079/19079/13666 +f 19077/19077/13664 19079/19079/13666 19078/19078/13665 +o Cube.032__0 +v -0.817403 -1.212970 -0.886515 +v -0.806067 -0.854108 -0.891976 +v -0.806067 -0.860857 -0.956416 +v -0.817403 -1.208599 -0.951062 +v -0.817403 -1.208599 -0.951062 +v -0.806067 -0.860857 -0.956416 +v 0.792784 -0.904557 -0.956524 +v 0.818843 -1.213614 -0.951062 +v 0.818843 -1.213614 -0.951062 +v 0.792784 -0.904557 -0.956524 +v 0.792784 -0.903914 -0.891977 +v 0.818843 -1.212970 -0.886515 +v 0.818843 -1.212970 -0.886515 +v 0.792784 -0.903914 -0.891977 +v -0.806067 -0.854108 -0.891976 +v -0.817403 -1.212970 -0.886515 +v -0.817403 -1.208599 -0.951062 +v 0.818843 -1.213614 -0.951062 +v 0.818843 -1.212970 -0.886515 +v -0.817403 -1.212970 -0.886515 +v 0.792784 -0.904557 -0.956524 +v -0.806067 -0.860857 -0.956416 +v -0.806067 -0.854108 -0.891976 +v 0.792784 -0.903914 -0.891977 +vt 0.985538 0.842457 +vt 0.985538 0.819519 +vt 0.980763 0.819556 +vt 0.980763 0.842494 +vt 0.984305 0.254719 +vt 0.984305 0.228166 +vt 0.979532 0.228592 +vt 0.979536 0.254324 +vt 0.524165 0.127500 +vt 0.498439 0.128260 +vt 0.501308 0.246499 +vt 0.524166 0.248496 +vt 0.099195 0.128177 +vt 0.076332 0.130104 +vt 0.072648 0.248334 +vt 0.099195 0.249172 +vt 0.686565 0.265056 +vt 0.686561 0.144060 +vt 0.681790 0.144060 +vt 0.681783 0.265055 +vt 0.529258 0.248523 +vt 0.529258 0.130249 +vt 0.524471 0.130235 +vt 0.524488 0.248522 +vn 0.9965 0.0840 -0.0008 +vn -0.9995 0.0321 -0.0005 +vn -0.9995 0.0321 -0.0006 +vn -0.0003 -0.0165 -0.9999 +vn -0.0003 -0.0166 -0.9999 +vn -0.0003 -0.0164 -0.9999 +vn 0.0003 0.0165 0.9999 +vn 0.0003 0.0164 0.9999 +vn 0.0002 0.0163 0.9999 +vn 0.0002 0.0162 0.9999 +vn -0.0015 -0.9996 -0.0289 +vn 0.0292 0.9979 -0.0572 +usemtl Scene_-_Root +s off +f 19316/19308/13804 19317/19309/13804 19318/19310/13804 +f 19316/19308/13804 19318/19310/13804 19319/19311/13804 +s 1 +f 19308/19312/13805 19309/19313/13806 19310/19314/13806 +f 19308/19312/13805 19310/19314/13806 19311/19315/13806 +f 19312/19316/13807 19313/19317/13808 19314/19318/13807 +f 19312/19316/13807 19314/19318/13807 19315/19319/13809 +f 19320/19320/13810 19321/19321/13811 19322/19322/13812 +f 19320/19320/13810 19322/19322/13812 19323/19323/13813 +f 19324/19324/13814 19325/19325/13814 19326/19326/13814 +f 19324/19324/13814 19326/19326/13814 19327/19327/13814 +f 19328/19328/13815 19329/19329/13815 19330/19330/13815 +f 19328/19328/13815 19330/19330/13815 19331/19331/13815 +o Cylinder.032__0 +v 1.283635 1.788152 -0.754091 +v 1.287508 1.793746 -0.754944 +v 1.282907 1.798089 -0.734168 +v 1.279254 1.792288 -0.734306 +v 1.270709 1.803423 -0.717009 +v 1.267637 1.797368 -0.717966 +v 1.267637 1.797368 -0.717966 +v 1.270709 1.803423 -0.717009 +v 1.252769 1.808937 -0.706081 +v 1.250554 1.802619 -0.707559 +v 1.231820 1.813792 -0.703047 +v 1.230604 1.807242 -0.704669 +v 1.211049 1.817249 -0.708368 +v 1.210824 1.810534 -0.709737 +v 1.193620 1.818781 -0.721235 +v 1.194227 1.811992 -0.721990 +v 1.194227 1.811992 -0.721990 +v 1.193620 1.818781 -0.721235 +v 1.182187 1.818154 -0.739689 +v 1.183338 1.811396 -0.739563 +v 1.178488 1.815465 -0.760920 +v 1.179817 1.808835 -0.759782 +v 1.183089 1.811123 -0.781696 +v 1.184197 1.804700 -0.779567 +v 1.195287 1.805789 -0.798855 +v 1.195814 1.799620 -0.795907 +v 1.195814 1.799620 -0.795907 +v 1.195287 1.805789 -0.798855 +v 1.213227 1.800274 -0.809783 +v 1.212898 1.794369 -0.806314 +v 1.234177 1.795419 -0.812817 +v 1.232848 1.789746 -0.809203 +v 1.254946 1.791963 -0.807496 +v 1.252628 1.786454 -0.804136 +v 1.272376 1.790431 -0.794629 +v 1.269225 1.784995 -0.791882 +v 1.234177 1.795419 -0.812817 +v 1.213227 1.800274 -0.809783 +v 1.211252 1.799842 -0.814960 +v 1.234294 1.794502 -0.818297 +v 1.269225 1.784995 -0.791882 +v 1.272376 1.790431 -0.794629 +v 1.283809 1.791057 -0.776175 +v 1.280113 1.785592 -0.774309 +v 1.167200 1.186354 -0.705981 +v 1.154536 1.182138 -0.748037 +v 1.182053 1.167775 -0.801044 +v 1.201842 1.177802 -0.714212 +v 1.215984 1.840956 -0.712230 +v 1.236754 1.837500 -0.706909 +v 1.240422 1.852435 -0.719529 +v 1.223404 1.855267 -0.723889 +v 1.252769 1.808937 -0.706081 +v 1.270709 1.803423 -0.717009 +v 1.274474 1.803305 -0.712923 +v 1.254743 1.809370 -0.700904 +v 1.292442 1.817454 -0.758806 +v 1.287842 1.821796 -0.738030 +v 1.292825 1.821145 -0.735657 +v 1.297885 1.816369 -0.758508 +v 1.259881 1.815670 -0.811358 +v 1.277310 1.814138 -0.798491 +v 1.281242 1.812723 -0.802155 +v 1.262073 1.814408 -0.816307 +v 1.287508 1.793746 -0.754944 +v 1.283809 1.791057 -0.776175 +v 1.288883 1.789705 -0.777997 +v 1.292950 1.792662 -0.754646 +v 1.182187 1.818154 -0.739689 +v 1.193620 1.818781 -0.721235 +v 1.189689 1.820196 -0.717571 +v 1.177113 1.819507 -0.737867 +v 1.239111 1.819127 -0.816679 +v 1.239229 1.818209 -0.822160 +v 1.218162 1.823982 -0.813645 +v 1.216187 1.823549 -0.818822 +v 1.195287 1.805789 -0.798855 +v 1.191522 1.805907 -0.802941 +v 1.282907 1.798089 -0.734168 +v 1.287891 1.797438 -0.731795 +v 1.200222 1.829496 -0.802717 +v 1.196456 1.829614 -0.806803 +v 1.272376 1.790431 -0.794629 +v 1.276307 1.789016 -0.798293 +v 1.211049 1.817249 -0.708368 +v 1.208858 1.818511 -0.703419 +v 1.188023 1.834831 -0.785558 +v 1.183040 1.835481 -0.787931 +v 1.183423 1.839173 -0.764782 +v 1.177980 1.840257 -0.765081 +v 1.183089 1.811123 -0.781696 +v 1.178105 1.811774 -0.784069 +v 1.210490 1.845878 -0.798026 +v 1.200495 1.850248 -0.783968 +v 1.217269 1.862669 -0.779709 +v 1.223887 1.859775 -0.789018 +v 1.259881 1.815670 -0.811358 +v 1.239111 1.819127 -0.816679 +v 1.242353 1.837382 -0.809466 +v 1.259370 1.834550 -0.805106 +v 1.198555 1.842488 -0.725097 +v 1.209124 1.856522 -0.734431 +v 1.277310 1.814138 -0.798491 +v 1.273650 1.833295 -0.794564 +v 1.187121 1.841862 -0.743551 +v 1.198555 1.842488 -0.725097 +v 1.209124 1.856522 -0.734431 +v 1.199756 1.856009 -0.749551 +v 1.288744 1.814765 -0.780037 +v 1.277310 1.814138 -0.798491 +v 1.273650 1.833295 -0.794564 +v 1.283018 1.833808 -0.779445 +v 1.183423 1.839173 -0.764782 +v 1.196726 1.853806 -0.766946 +v 1.287842 1.821796 -0.738030 +v 1.292442 1.817454 -0.758806 +v 1.286048 1.836011 -0.762049 +v 1.282279 1.839569 -0.745027 +v 1.188023 1.834831 -0.785558 +v 1.200495 1.850248 -0.783968 +v 1.275644 1.827130 -0.720871 +v 1.272284 1.843939 -0.730969 +v 1.200222 1.829496 -0.802717 +v 1.210490 1.845878 -0.798026 +v 1.257704 1.832645 -0.709943 +v 1.275644 1.827130 -0.720871 +v 1.272284 1.843939 -0.730969 +v 1.257586 1.848458 -0.722015 +v 1.218162 1.823982 -0.813645 +v 1.200222 1.829496 -0.802717 +v 1.210490 1.845878 -0.798026 +v 1.225188 1.841360 -0.806980 +v 1.261786 1.854483 -0.773076 +v 1.257862 1.854268 -0.779409 +v 1.270405 1.914526 -0.789226 +v 1.274329 1.914741 -0.782892 +v 1.257586 1.848458 -0.722015 +v 1.272284 1.843939 -0.730969 +v 1.264809 1.858491 -0.744612 +v 1.255075 1.861483 -0.738683 +v 1.225188 1.841360 -0.806980 +v 1.233621 1.856783 -0.794948 +v 1.240422 1.852435 -0.719529 +v 1.243709 1.864117 -0.737036 +v 1.242353 1.837382 -0.809466 +v 1.244987 1.854149 -0.796594 +v 1.223404 1.855267 -0.723889 +v 1.232439 1.865993 -0.739923 +v 1.259370 1.834550 -0.805106 +v 1.256257 1.852273 -0.793707 +v 1.209124 1.856522 -0.734431 +v 1.222983 1.866824 -0.746905 +v 1.273650 1.833295 -0.794564 +v 1.265713 1.851442 -0.786726 +v 1.199756 1.856009 -0.749551 +v 1.216779 1.866484 -0.756917 +v 1.283018 1.833808 -0.779445 +v 1.271917 1.851782 -0.776713 +v 1.196726 1.853806 -0.766946 +v 1.214773 1.865025 -0.768436 +v 1.282279 1.839569 -0.745027 +v 1.286048 1.836011 -0.762049 +v 1.273923 1.853241 -0.765194 +v 1.271427 1.855597 -0.753922 +v 1.257138 1.790700 -0.812444 +v 1.259173 1.789528 -0.817040 +v 1.279958 1.787701 -0.801695 +v 1.214354 1.823147 -0.823630 +v 1.192960 1.829724 -0.810597 +v 1.234404 1.793650 -0.823386 +v 1.178412 1.836085 -0.790135 +v 1.209419 1.799440 -0.819767 +v 1.172926 1.841264 -0.765358 +v 1.188025 1.806016 -0.806735 +v 1.182048 1.843215 -0.741729 +v 1.177337 1.844471 -0.740038 +v 1.173478 1.812378 -0.786272 +v 1.194623 1.843903 -0.721433 +v 1.190973 1.845217 -0.718031 +v 1.173046 1.816550 -0.761218 +v 1.167992 1.817556 -0.761495 +v 1.213792 1.842219 -0.707281 +v 1.211757 1.843391 -0.702686 +v 1.172402 1.820763 -0.736176 +v 1.236637 1.838417 -0.701429 +v 1.236527 1.839269 -0.696340 +v 1.186038 1.821510 -0.714169 +v 1.259678 1.833077 -0.704766 +v 1.261511 1.833479 -0.699959 +v 1.288744 1.814765 -0.780037 +v 1.293818 1.813412 -0.781859 +v 1.275644 1.827130 -0.720871 +v 1.279409 1.827012 -0.716786 +v 1.178488 1.815465 -0.760920 +v 1.257704 1.832645 -0.709943 +v 1.236754 1.837500 -0.706909 +v 1.231820 1.813792 -0.703047 +v 1.231702 1.814710 -0.697566 +v 1.254946 1.791963 -0.807496 +v 1.215984 1.840956 -0.712230 +v 1.198555 1.842488 -0.725097 +v 1.187121 1.841862 -0.743551 +v 1.256577 1.809772 -0.696097 +v 1.277971 1.803195 -0.709129 +v 1.282906 1.826902 -0.712991 +v 1.261511 1.833479 -0.699959 +v 1.167992 1.817556 -0.761495 +v 1.172402 1.820763 -0.736176 +v 1.177337 1.844471 -0.740038 +v 1.172926 1.841264 -0.765358 +v 1.292518 1.796834 -0.729592 +v 1.298004 1.791655 -0.754369 +v 1.302939 1.815362 -0.758231 +v 1.297453 1.820541 -0.733454 +v 1.259173 1.789528 -0.817040 +v 1.234404 1.793650 -0.823386 +v 1.239338 1.817358 -0.827248 +v 1.264108 1.813235 -0.820902 +v 1.186038 1.821510 -0.714169 +v 1.206823 1.819684 -0.698824 +v 1.211757 1.843391 -0.702686 +v 1.190973 1.845217 -0.718031 +v 1.209419 1.799440 -0.819767 +v 1.188025 1.806016 -0.806735 +v 1.192960 1.829724 -0.810597 +v 1.214354 1.823147 -0.823630 +v 1.293594 1.788448 -0.779688 +v 1.298529 1.812156 -0.783550 +v 1.231593 1.815561 -0.692477 +v 1.236527 1.839269 -0.696340 +v 1.173478 1.812378 -0.786272 +v 1.178412 1.836085 -0.790135 +v 1.279958 1.787701 -0.801695 +v 1.284893 1.811409 -0.805557 +v 1.277971 1.803195 -0.709129 +v 1.282906 1.826902 -0.712991 +v 1.186038 1.821510 -0.714169 +v 1.190973 1.845217 -0.718031 +v 1.188025 1.806016 -0.806735 +v 1.192960 1.829724 -0.810597 +v 1.279958 1.787701 -0.801695 +v 1.284893 1.811409 -0.805557 +v 1.298004 1.791655 -0.754369 +v 1.292518 1.796834 -0.729592 +v 1.239338 1.817358 -0.827248 +v 1.293594 1.788448 -0.779688 +v 1.277971 1.803195 -0.709129 +v 1.264108 1.813235 -0.820902 +v 1.256577 1.809772 -0.696097 +v 1.284893 1.811409 -0.805557 +v 1.297453 1.820541 -0.733454 +v 1.302939 1.815362 -0.758231 +v 1.231593 1.815561 -0.692477 +v 1.298529 1.812156 -0.783550 +v 1.282906 1.826902 -0.712991 +v 1.206823 1.819684 -0.698824 +v 1.123555 1.208789 -0.587173 +v 1.111916 1.214676 -0.565912 +v 1.106970 1.190914 -0.562041 +v 1.118609 1.185028 -0.583302 +v 1.052964 1.220028 -0.745819 +v 1.081170 1.210429 -0.768704 +v 1.077461 1.197338 -0.853797 +v 1.044142 1.211201 -0.811274 +v 1.189493 1.212838 -0.615510 +v 1.170213 1.222636 -0.580003 +v 1.179036 1.231462 -0.514548 +v 1.202502 1.212818 -0.599009 +v 1.165107 1.202667 -0.608518 +v 1.170912 1.193562 -0.656989 +v 1.208173 1.186139 -0.654947 +v 1.199314 1.197502 -0.596514 +v 1.134849 1.181558 -0.776753 +v 1.150635 1.166809 -0.847116 +v 1.173631 1.195988 -0.739204 +v 1.191343 1.198416 -0.701669 +v 1.205030 1.193118 -0.716707 +v 1.185241 1.183091 -0.803540 +v 1.076704 1.245245 -0.560697 +v 1.049546 1.246675 -0.586617 +v 1.037936 1.259572 -0.522282 +v 1.069354 1.260538 -0.476211 +v 1.111135 1.184701 -0.787757 +v 1.112788 1.171812 -0.864763 +v 1.087005 1.191090 -0.779375 +v 1.074273 1.182022 -0.851301 +v 1.033684 1.229825 -0.710312 +v 1.020675 1.229845 -0.726813 +v 1.066132 1.199750 -0.752883 +v 1.040953 1.195885 -0.808779 +v 1.196913 1.204333 -0.658234 +v 1.211361 1.201455 -0.657442 +v 1.146474 1.197419 -0.765124 +v 1.153823 1.182125 -0.849611 +v 1.109172 1.240174 -0.550339 +v 1.107201 1.255535 -0.458563 +v 1.051694 1.209365 -0.712313 +v 1.017487 1.214530 -0.724318 +v 1.045890 1.218469 -0.663842 +v 1.008629 1.225893 -0.665885 +v 1.145716 1.245325 -0.472025 +v 1.107201 1.255535 -0.458563 +v 1.104013 1.240219 -0.456068 +v 1.142528 1.230009 -0.469530 +v 1.011817 1.241208 -0.668380 +v 1.020675 1.229845 -0.726813 +v 1.017487 1.214530 -0.724318 +v 1.008629 1.225893 -0.665885 +v 1.153823 1.182125 -0.849611 +v 1.185241 1.183091 -0.803540 +v 1.182053 1.167775 -0.801044 +v 1.150635 1.166809 -0.847116 +v 1.202502 1.212818 -0.599009 +v 1.179036 1.231462 -0.514548 +v 1.175848 1.216146 -0.512052 +v 1.199314 1.197502 -0.596514 +v 1.037936 1.259572 -0.522282 +v 1.018147 1.249545 -0.609115 +v 1.014959 1.234230 -0.606620 +v 1.034748 1.244256 -0.519787 +v 1.077461 1.197338 -0.853797 +v 1.115976 1.187128 -0.867259 +v 1.112788 1.171812 -0.864763 +v 1.074273 1.182022 -0.851301 +v 1.069354 1.260538 -0.476211 +v 1.066166 1.245222 -0.473716 +v 1.044142 1.211201 -0.811274 +v 1.040953 1.195885 -0.808779 +v 1.205030 1.193118 -0.716707 +v 1.201842 1.177802 -0.714212 +v 1.145716 1.245325 -0.472025 +v 1.142528 1.230009 -0.469530 +v 1.211361 1.201455 -0.657442 +v 1.208173 1.186139 -0.654947 +v 1.153823 1.182125 -0.849611 +v 1.150635 1.166809 -0.847116 +v 1.069354 1.260538 -0.476211 +v 1.066166 1.245222 -0.473716 +v 1.077461 1.197338 -0.853797 +v 1.074273 1.182022 -0.851301 +v 1.150669 1.212281 -0.567949 +v 1.175848 1.216146 -0.512052 +v 1.031834 1.244247 -0.624152 +v 1.018147 1.249545 -0.609115 +v 1.129797 1.220942 -0.541456 +v 1.142528 1.230009 -0.469530 +v 1.105666 1.227330 -0.533074 +v 1.104013 1.240219 -0.456068 +v 1.142008 1.232234 -0.557118 +v 1.145716 1.245325 -0.472025 +v 1.114006 1.202489 -0.775483 +v 1.115976 1.187128 -0.867259 +v 1.081953 1.230474 -0.544079 +v 1.066166 1.245222 -0.473716 +v 1.026264 1.238330 -0.667588 +v 1.011817 1.241208 -0.668380 +v 1.062265 1.229893 -0.572795 +v 1.034748 1.244256 -0.519787 +v 1.049602 1.225678 -0.614850 +v 1.014959 1.234230 -0.606620 +v 1.262218 1.671592 -0.757962 +v 1.266142 1.674445 -0.735434 +v 1.250085 1.670927 -0.777543 +v 1.231592 1.672553 -0.791196 +v 1.250085 1.670927 -0.777543 +v 1.209554 1.676220 -0.796842 +v 1.187325 1.681372 -0.793622 +v 1.168289 1.687223 -0.782027 +v 1.155345 1.692883 -0.763820 +v 1.168289 1.687223 -0.782027 +v 1.150465 1.697490 -0.741775 +v 1.154388 1.700344 -0.719248 +v 1.166521 1.701008 -0.699667 +v 1.185014 1.699383 -0.686014 +v 1.166521 1.701008 -0.699667 +v 1.207053 1.695715 -0.680367 +v 1.229282 1.690564 -0.683587 +v 1.248317 1.684713 -0.695183 +v 1.261261 1.679052 -0.713389 +v 1.248317 1.684713 -0.695183 +v 1.182345 1.213989 -0.660163 +v 1.191775 1.286007 -0.672014 +v 1.186368 1.291111 -0.647595 +v 1.176487 1.219517 -0.633708 +v 1.210358 1.362956 -0.684495 +v 1.204743 1.368256 -0.659137 +v 1.219961 1.441694 -0.697468 +v 1.214896 1.446474 -0.674593 +v 1.238250 1.518700 -0.709965 +v 1.233002 1.523654 -0.686263 +v 1.248146 1.597380 -0.722921 +v 1.243423 1.601837 -0.701591 +v 1.172031 1.297381 -0.627429 +v 1.160955 1.226310 -0.611861 +v 1.189854 1.374767 -0.638195 +v 1.201465 1.452348 -0.655702 +v 1.219086 1.529739 -0.666689 +v 1.230900 1.607314 -0.683976 +v 1.160955 1.226310 -0.611861 +v 1.172031 1.297381 -0.627429 +v 1.150946 1.303862 -0.614584 +v 1.138113 1.233331 -0.597946 +v 1.189854 1.374767 -0.638195 +v 1.167958 1.381497 -0.624857 +v 1.201465 1.452348 -0.655702 +v 1.181714 1.458419 -0.643671 +v 1.219086 1.529739 -0.666689 +v 1.198620 1.536030 -0.654222 +v 1.230900 1.607314 -0.683976 +v 1.212482 1.612975 -0.672757 +v 1.126323 1.309568 -0.611018 +v 1.111438 1.239513 -0.594083 +v 1.142389 1.387423 -0.621153 +v 1.158648 1.463764 -0.640329 +v 1.174721 1.541569 -0.650760 +v 1.190974 1.617959 -0.669641 +v 1.101910 1.313631 -0.617272 +v 1.084991 1.243914 -0.600858 +v 1.117038 1.391642 -0.627648 +v 1.135780 1.467570 -0.646188 +v 1.151026 1.545512 -0.656831 +v 1.169651 1.621508 -0.675105 +v 1.081426 1.315431 -0.632395 +v 1.062800 1.245864 -0.617242 +v 1.095765 1.393511 -0.643353 +v 1.116592 1.469256 -0.660355 +v 1.131143 1.547260 -0.671510 +v 1.151757 1.623081 -0.688314 +v 1.062800 1.245864 -0.617242 +v 1.081426 1.315431 -0.632395 +v 1.067987 1.314695 -0.654085 +v 1.048241 1.245067 -0.640739 +v 1.095765 1.393511 -0.643353 +v 1.081810 1.392746 -0.665876 +v 1.116592 1.469256 -0.660355 +v 1.104003 1.468566 -0.680672 +v 1.131143 1.547260 -0.671510 +v 1.118100 1.546545 -0.692562 +v 1.151757 1.623081 -0.688314 +v 1.140019 1.622437 -0.707260 +v 1.063640 1.311535 -0.679039 +v 1.043532 1.241643 -0.667772 +v 1.077296 1.389465 -0.691789 +v 1.099931 1.465606 -0.704048 +v 1.113880 1.543478 -0.716782 +v 1.136222 1.619677 -0.729057 +v 1.069047 1.306431 -0.703458 +v 1.049389 1.236114 -0.694226 +v 1.082911 1.384165 -0.717147 +v 1.104996 1.460825 -0.726922 +v 1.119129 1.538524 -0.740484 +v 1.140945 1.615219 -0.750386 +v 1.083385 1.300161 -0.723624 +v 1.064922 1.229322 -0.716073 +v 1.097800 1.377654 -0.738089 +v 1.118427 1.454952 -0.745813 +v 1.133044 1.532438 -0.760058 +v 1.153468 1.609743 -0.768002 +v 1.064922 1.229322 -0.716073 +v 1.083385 1.300161 -0.723624 +v 1.104470 1.293680 -0.736469 +v 1.087764 1.222300 -0.729988 +v 1.097800 1.377654 -0.738089 +v 1.119696 1.370923 -0.751428 +v 1.118427 1.454952 -0.745813 +v 1.138178 1.448881 -0.757845 +v 1.133044 1.532438 -0.760058 +v 1.153510 1.526147 -0.772525 +v 1.153468 1.609743 -0.768002 +v 1.171886 1.604081 -0.779221 +v 1.129093 1.287973 -0.740036 +v 1.114439 1.216119 -0.733852 +v 1.145265 1.364998 -0.755131 +v 1.161243 1.443535 -0.761186 +v 1.177410 1.520609 -0.775986 +v 1.193394 1.599097 -0.782336 +v 1.153505 1.283911 -0.733781 +v 1.140885 1.211717 -0.727076 +v 1.170616 1.360779 -0.748636 +v 1.184111 1.439730 -0.755327 +v 1.201104 1.516665 -0.769916 +v 1.214718 1.595548 -0.776874 +v 1.173990 1.282111 -0.718658 +v 1.163077 1.209767 -0.710693 +v 1.191889 1.358910 -0.732932 +v 1.203300 1.438044 -0.741161 +v 1.220987 1.514918 -0.755237 +v 1.232611 1.593976 -0.763664 +v 1.163077 1.209767 -0.710693 +v 1.173990 1.282111 -0.718658 +v 1.187428 1.282847 -0.696968 +v 1.177636 1.210565 -0.687196 +v 1.191889 1.358910 -0.732932 +v 1.205844 1.359674 -0.710408 +v 1.203300 1.438044 -0.741161 +v 1.215889 1.438733 -0.720843 +v 1.220987 1.514918 -0.755237 +v 1.234031 1.515633 -0.734185 +v 1.232611 1.593976 -0.763664 +v 1.244349 1.594619 -0.744718 +v 1.177657 1.203715 -0.686631 +v 1.182466 1.207211 -0.659026 +v 1.162790 1.202901 -0.710626 +v 1.140128 1.204892 -0.727357 +v 1.162790 1.202901 -0.710626 +v 1.113121 1.209387 -0.734276 +v 1.085881 1.215699 -0.730331 +v 1.062555 1.222870 -0.716121 +v 1.046693 1.229806 -0.693811 +v 1.062555 1.222870 -0.716121 +v 1.040712 1.235452 -0.666796 +v 1.045521 1.238948 -0.639190 +v 1.060388 1.239763 -0.615196 +v 1.083050 1.237771 -0.598465 +v 1.060388 1.239763 -0.615196 +v 1.110056 1.233277 -0.591546 +v 1.137296 1.226964 -0.595491 +v 1.160623 1.219794 -0.609701 +v 1.176484 1.212857 -0.632011 +v 1.160623 1.219794 -0.609701 +v 1.090910 1.192019 -0.731830 +v 1.102604 1.185684 -0.750598 +v 1.097658 1.161922 -0.746727 +v 1.085964 1.168257 -0.727959 +v 1.129731 1.202220 -0.619608 +v 1.124785 1.178458 -0.615737 +v 1.084733 1.198588 -0.699394 +v 1.079787 1.174826 -0.695524 +v 1.105066 1.217293 -0.558598 +v 1.100120 1.193532 -0.554727 +v 1.102604 1.185684 -0.750598 +v 1.109289 1.184352 -0.750232 +v 1.104343 1.160590 -0.746361 +v 1.097658 1.161922 -0.746727 +v 1.105066 1.217293 -0.558598 +v 1.098546 1.217340 -0.566645 +v 1.093600 1.193578 -0.562774 +v 1.100120 1.193532 -0.554727 +v 1.115974 1.183021 -0.749865 +v 1.111028 1.159259 -0.745994 +v 1.087846 1.215904 -0.589131 +v 1.082900 1.192142 -0.585260 +v 1.115974 1.183021 -0.749865 +v 1.126619 1.184905 -0.729872 +v 1.121673 1.161143 -0.726002 +v 1.111028 1.159259 -0.745994 +v 1.083075 1.211515 -0.622166 +v 1.078129 1.187753 -0.618295 +v 1.131389 1.189293 -0.696837 +v 1.126443 1.165532 -0.692966 +v 1.081982 1.205434 -0.660886 +v 1.077036 1.181673 -0.657015 +v 1.132483 1.195374 -0.658117 +v 1.127537 1.171612 -0.654246 +v 1.083150 1.211046 -0.661800 +v 1.085901 1.204200 -0.700309 +v 1.132557 1.194905 -0.697751 +v 1.133651 1.200985 -0.659032 +v 1.130899 1.207832 -0.620523 +v 1.084243 1.217127 -0.623080 +v 1.127787 1.190516 -0.730787 +v 1.089014 1.221515 -0.590045 +v 1.120120 1.188039 -0.750616 +v 1.096736 1.223545 -0.567723 +v 1.110457 1.189964 -0.751146 +v 1.120120 1.188039 -0.750616 +v 1.106234 1.222905 -0.559512 +v 1.096736 1.223545 -0.567723 +v 1.098546 1.217340 -0.566645 +v 1.105066 1.217293 -0.558598 +v 1.100794 1.191889 -0.751676 +v 1.116061 1.219694 -0.566663 +v 1.111916 1.214676 -0.565912 +v 1.092078 1.197630 -0.732744 +v 1.100794 1.191889 -0.751676 +v 1.124723 1.214401 -0.588087 +v 1.116061 1.219694 -0.566663 +v 1.083150 1.211046 -0.661800 +v 1.084243 1.217127 -0.623080 +v 1.089014 1.221515 -0.590045 +v 1.096736 1.223545 -0.567723 +v 1.106234 1.222905 -0.559512 +v 1.116061 1.219694 -0.566663 +v 1.124723 1.214401 -0.588087 +v 1.133651 1.200985 -0.659032 +v 1.132557 1.194905 -0.697751 +v 1.130899 1.207832 -0.620523 +v 1.085901 1.204200 -0.700309 +v 1.092078 1.197630 -0.732744 +v 1.100794 1.191889 -0.751676 +v 1.110457 1.189964 -0.751146 +v 1.120120 1.188039 -0.750616 +v 1.127787 1.190516 -0.730787 +v 1.040712 1.235452 -0.666796 +v 1.046693 1.229806 -0.693811 +v 1.113121 1.209387 -0.734276 +v 1.140128 1.204892 -0.727357 +v 1.137296 1.226964 -0.595491 +v 1.110056 1.233277 -0.591546 +v 1.045521 1.238948 -0.639190 +v 1.085881 1.215699 -0.730331 +v 1.160623 1.219794 -0.609701 +v 1.177657 1.203715 -0.686631 +v 1.182466 1.207211 -0.659026 +v 1.060388 1.239763 -0.615196 +v 1.083050 1.237771 -0.598465 +v 1.162790 1.202901 -0.710626 +v 1.176484 1.212857 -0.632011 +v 1.062555 1.222870 -0.716121 +v 1.263055 1.855406 -0.765790 +v 1.261476 1.856896 -0.758660 +v 1.257290 1.858727 -0.752771 +v 1.251133 1.860620 -0.749021 +v 1.243944 1.862286 -0.747979 +v 1.236815 1.863472 -0.749805 +v 1.230834 1.863998 -0.754221 +v 1.226910 1.863783 -0.760554 +v 1.225641 1.862860 -0.767841 +v 1.227219 1.861370 -0.774971 +v 1.231406 1.859539 -0.780859 +v 1.237563 1.857646 -0.784610 +v 1.244752 1.855980 -0.785651 +v 1.251881 1.854794 -0.783825 +v 1.257862 1.854268 -0.779409 +v 1.261786 1.854483 -0.773076 +v 1.225641 1.862860 -0.767841 +v 1.226910 1.863783 -0.760554 +v 1.239453 1.924041 -0.770370 +v 1.238183 1.923118 -0.777657 +v 1.261476 1.856896 -0.758660 +v 1.263055 1.855406 -0.765790 +v 1.275598 1.915664 -0.775606 +v 1.274019 1.917154 -0.768476 +v 1.227219 1.861370 -0.774971 +v 1.239762 1.921628 -0.784787 +v 1.257290 1.858727 -0.752771 +v 1.269833 1.918985 -0.762587 +v 1.231406 1.859539 -0.780859 +v 1.243949 1.919797 -0.790676 +v 1.251133 1.860620 -0.749021 +v 1.257290 1.858727 -0.752771 +v 1.269833 1.918985 -0.762587 +v 1.263676 1.920877 -0.758837 +v 1.237563 1.857646 -0.784610 +v 1.231406 1.859539 -0.780859 +v 1.243949 1.919797 -0.790676 +v 1.250105 1.917904 -0.794426 +v 1.243944 1.862286 -0.747979 +v 1.256486 1.922544 -0.757796 +v 1.244752 1.855980 -0.785651 +v 1.257295 1.916238 -0.795468 +v 1.236815 1.863472 -0.749805 +v 1.249358 1.923730 -0.759622 +v 1.251881 1.854794 -0.783825 +v 1.264423 1.915052 -0.793641 +v 1.230834 1.863998 -0.754221 +v 1.243377 1.924256 -0.764038 +v 1.257862 1.854268 -0.779409 +v 1.270405 1.914526 -0.789226 +v 1.230834 1.863998 -0.754221 +v 1.243377 1.924256 -0.764038 +v 1.299024 1.983040 -0.760319 +v 1.294295 1.994490 -0.762337 +v 1.295366 1.986144 -0.812199 +v 1.300094 1.974694 -0.810181 +v 1.298945 1.970661 -0.758248 +v 1.300015 1.962315 -0.808111 +v 1.234471 2.019426 -0.819077 +v 1.217296 2.002635 -0.816636 +v 1.216225 2.010982 -0.766773 +v 1.233400 2.027772 -0.769215 +v 1.280197 1.908705 -0.799563 +v 1.302555 1.917756 -0.800598 +v 1.301484 1.926102 -0.750736 +v 1.279127 1.917051 -0.749701 +v 1.256828 2.028477 -0.820112 +v 1.234471 2.019426 -0.819077 +v 1.233400 2.027772 -0.769215 +v 1.255758 2.036823 -0.770250 +v 1.256061 1.908772 -0.800093 +v 1.254991 1.917117 -0.750230 +v 1.280964 2.028410 -0.819583 +v 1.279894 2.036757 -0.769721 +v 1.233820 1.917944 -0.802105 +v 1.232750 1.926291 -0.752243 +v 1.303205 2.019238 -0.817570 +v 1.302134 2.027584 -0.767708 +v 1.216861 1.934828 -0.805296 +v 1.215791 1.943174 -0.755433 +v 1.320164 2.002354 -0.814380 +v 1.319093 2.010700 -0.764518 +v 1.207766 1.956852 -0.809177 +v 1.216861 1.934828 -0.805296 +v 1.215791 1.943174 -0.755433 +v 1.206696 1.965198 -0.759315 +v 1.329259 1.980330 -0.810498 +v 1.320164 2.002354 -0.814380 +v 1.319093 2.010700 -0.764518 +v 1.328189 1.988676 -0.760636 +v 1.207919 1.980663 -0.813159 +v 1.206848 1.989009 -0.763297 +v 1.319729 1.934546 -0.803040 +v 1.329107 1.956520 -0.806516 +v 1.328036 1.964865 -0.756654 +v 1.318659 1.942892 -0.753177 +v 1.302555 1.917756 -0.800598 +v 1.301484 1.926102 -0.750736 +v 1.315656 1.937253 -0.803580 +v 1.324288 1.957479 -0.806780 +v 1.329107 1.956520 -0.806516 +v 1.319729 1.934546 -0.803040 +v 1.299847 1.921799 -0.801333 +v 1.302555 1.917756 -0.800598 +v 1.279268 1.913467 -0.800380 +v 1.280197 1.908705 -0.799563 +v 1.257051 1.913528 -0.800868 +v 1.256061 1.908772 -0.800093 +v 1.236579 1.921972 -0.802720 +v 1.233820 1.917944 -0.802105 +v 1.220969 1.937513 -0.805657 +v 1.216861 1.934828 -0.805296 +v 1.212597 1.957785 -0.809230 +v 1.207766 1.956852 -0.809177 +v 1.212738 1.979703 -0.812895 +v 1.207919 1.980663 -0.813159 +v 1.221369 1.999928 -0.816095 +v 1.217296 2.002635 -0.816636 +v 1.237178 2.015383 -0.818342 +v 1.234471 2.019426 -0.819077 +v 1.257757 2.023714 -0.819295 +v 1.256828 2.028477 -0.820112 +v 1.279974 2.023654 -0.818808 +v 1.280964 2.028410 -0.819583 +v 1.300446 2.015210 -0.816955 +v 1.303205 2.019238 -0.817570 +v 1.316056 1.999669 -0.814019 +v 1.320164 2.002354 -0.814380 +v 1.324428 1.979397 -0.810446 +v 1.329259 1.980330 -0.810498 +v 1.323217 1.965825 -0.756918 +v 1.314586 1.945600 -0.753718 +v 1.318659 1.942892 -0.753177 +v 1.328036 1.964865 -0.756654 +v 1.298777 1.930145 -0.751471 +v 1.301484 1.926102 -0.750736 +v 1.278198 1.921813 -0.750518 +v 1.279127 1.917051 -0.749701 +v 1.255981 1.921874 -0.751005 +v 1.254991 1.917117 -0.750230 +v 1.235509 1.930318 -0.752858 +v 1.232750 1.926291 -0.752243 +v 1.219898 1.945859 -0.755794 +v 1.215791 1.943174 -0.755433 +v 1.211526 1.966131 -0.759367 +v 1.206696 1.965198 -0.759315 +v 1.211667 1.988049 -0.763033 +v 1.206848 1.989009 -0.763297 +v 1.220299 2.008274 -0.766233 +v 1.216225 2.010982 -0.766773 +v 1.236107 2.023729 -0.768480 +v 1.233400 2.027772 -0.769215 +v 1.256687 2.032060 -0.769433 +v 1.255758 2.036823 -0.770250 +v 1.278903 2.031999 -0.768946 +v 1.279894 2.036757 -0.769721 +v 1.299376 2.023556 -0.767093 +v 1.302134 2.027584 -0.767708 +v 1.314986 2.008015 -0.764156 +v 1.319093 2.010700 -0.764518 +v 1.323358 1.987743 -0.760583 +v 1.328189 1.988676 -0.760636 +v 1.295140 1.950891 -0.806304 +v 1.300015 1.962315 -0.808111 +v 1.286211 1.942162 -0.805034 +v 1.274587 1.937457 -0.804496 +v 1.262039 1.937491 -0.804771 +v 1.250476 1.942260 -0.805818 +v 1.241660 1.951038 -0.807476 +v 1.236931 1.962488 -0.809494 +v 1.237010 1.974867 -0.811564 +v 1.241885 1.986290 -0.813372 +v 1.250814 1.995020 -0.814641 +v 1.262438 1.999725 -0.815179 +v 1.274986 1.999691 -0.814904 +v 1.286549 1.994922 -0.813858 +v 1.295366 1.986144 -0.812199 +v 1.300094 1.974694 -0.810181 +v 1.298945 1.970661 -0.758248 +v 1.294069 1.959237 -0.756441 +v 1.285140 1.950508 -0.755172 +v 1.273517 1.945803 -0.754634 +v 1.260969 1.945837 -0.754909 +v 1.249406 1.950606 -0.755955 +v 1.240589 1.959384 -0.757614 +v 1.235860 1.970834 -0.759632 +v 1.235940 1.983213 -0.761702 +v 1.240815 1.994637 -0.763510 +v 1.249744 2.003366 -0.764779 +v 1.261367 2.008071 -0.765317 +v 1.273916 2.008037 -0.765042 +v 1.285478 2.003268 -0.763995 +v 1.294295 1.994490 -0.762337 +v 1.299024 1.983040 -0.760319 +v 1.294295 1.994490 -0.762337 +v 1.285478 2.003268 -0.763995 +v 1.286549 1.994922 -0.813858 +v 1.295366 1.986144 -0.812199 +v 1.273916 2.008037 -0.765042 +v 1.274986 1.999691 -0.814904 +v 1.261367 2.008071 -0.765317 +v 1.262438 1.999725 -0.815179 +v 1.249744 2.003366 -0.764779 +v 1.250814 1.995020 -0.814641 +v 1.249744 2.003366 -0.764779 +v 1.240815 1.994637 -0.763510 +v 1.241885 1.986290 -0.813372 +v 1.250814 1.995020 -0.814641 +v 1.235940 1.983213 -0.761702 +v 1.237010 1.974867 -0.811564 +v 1.235860 1.970834 -0.759632 +v 1.236931 1.962488 -0.809494 +v 1.240589 1.959384 -0.757614 +v 1.241660 1.951038 -0.807476 +v 1.240589 1.959384 -0.757614 +v 1.249406 1.950606 -0.755955 +v 1.250476 1.942260 -0.805818 +v 1.241660 1.951038 -0.807476 +v 1.260969 1.945837 -0.754909 +v 1.262039 1.937491 -0.804771 +v 1.273517 1.945803 -0.754634 +v 1.274587 1.937457 -0.804496 +v 1.285140 1.950508 -0.755172 +v 1.286211 1.942162 -0.805034 +v 1.285140 1.950508 -0.755172 +v 1.294069 1.959237 -0.756441 +v 1.295140 1.950891 -0.806304 +v 1.286211 1.942162 -0.805034 +v 0.853497 0.107747 -0.482062 +v 0.856248 0.100901 -0.520571 +v 0.700131 -0.744413 -0.346822 +v 0.699847 -0.743706 -0.342845 +v 0.903997 0.097686 -0.479293 +v 0.901246 0.104532 -0.440784 +v 0.704778 -0.744039 -0.338583 +v 0.705062 -0.744745 -0.342560 +v 0.902904 0.091606 -0.518013 +v 0.704949 -0.745373 -0.346558 +v 0.854590 0.113827 -0.443342 +v 0.699960 -0.743079 -0.338847 +v 0.898133 0.087217 -0.551049 +v 0.704456 -0.745826 -0.349970 +v 0.859361 0.118216 -0.410307 +v 0.700453 -0.742625 -0.335436 +v 0.887434 0.085781 -0.573534 +v 0.703352 -0.745975 -0.352291 +v 0.870060 0.119652 -0.387821 +v 0.701558 -0.742477 -0.333113 +v 0.880914 0.085827 -0.581581 +v 0.702679 -0.745970 -0.353122 +v 0.876581 0.119606 -0.379774 +v 0.702231 -0.742482 -0.332282 +v 0.874063 0.088445 -0.574267 +v 0.880914 0.085827 -0.581581 +v 0.702679 -0.745970 -0.353122 +v 0.701971 -0.745700 -0.352367 +v 0.883430 0.116988 -0.387088 +v 0.876581 0.119606 -0.379774 +v 0.702231 -0.742482 -0.332282 +v 0.702938 -0.742752 -0.333038 +v 0.862424 0.094331 -0.553006 +v 0.700769 -0.745092 -0.350171 +v 0.895070 0.111102 -0.408349 +v 0.704140 -0.743360 -0.335233 +v 1.069736 1.126540 -0.687657 +v 1.066985 1.133386 -0.649148 +v 1.072011 1.157529 -0.653081 +v 1.074762 1.150683 -0.691590 +v 1.117486 1.123325 -0.646380 +v 1.116392 1.117245 -0.685100 +v 1.121418 1.141388 -0.689033 +v 1.122511 1.147469 -0.650313 +v 1.114734 1.130171 -0.607871 +v 1.119760 1.154315 -0.611804 +v 1.068078 1.139466 -0.610429 +v 1.073104 1.163610 -0.614362 +v 1.111622 1.112856 -0.718135 +v 1.116647 1.137000 -0.722068 +v 1.072849 1.143855 -0.577393 +v 1.077874 1.167999 -0.581326 +v 1.100922 1.111420 -0.740621 +v 1.106003 1.135115 -0.742061 +v 1.083549 1.145291 -0.554908 +v 1.089810 1.169457 -0.579458 +v 1.077874 1.167999 -0.581326 +v 1.089810 1.169457 -0.579458 +v 1.093600 1.193578 -0.562774 +v 1.082900 1.192142 -0.585260 +v 1.100922 1.111420 -0.740621 +v 1.094402 1.111466 -0.748668 +v 1.099318 1.136447 -0.742428 +v 1.106003 1.135115 -0.742061 +v 1.090069 1.145245 -0.546860 +v 1.096330 1.169411 -0.571411 +v 1.087552 1.114084 -0.741354 +v 1.092633 1.137779 -0.742794 +v 1.090069 1.145245 -0.546860 +v 1.096919 1.142628 -0.554175 +v 1.103180 1.166793 -0.578726 +v 1.096330 1.169411 -0.571411 +v 1.087552 1.114084 -0.741354 +v 1.075913 1.119970 -0.720093 +v 1.080938 1.144114 -0.724026 +v 1.092633 1.137779 -0.742794 +v 1.108558 1.136741 -0.575436 +v 1.113583 1.160884 -0.579369 +v 1.094402 1.111466 -0.748668 +v 1.094402 1.111466 -0.748668 +v 0.705062 -0.744745 -0.342560 +v 0.704778 -0.744039 -0.338583 +v 0.704140 -0.743360 -0.335233 +v 0.702938 -0.742752 -0.333038 +v 0.702231 -0.742482 -0.332282 +v 0.701558 -0.742477 -0.333113 +v 0.700453 -0.742625 -0.335436 +v 0.699960 -0.743079 -0.338847 +v 0.699847 -0.743706 -0.342845 +v 0.700131 -0.744413 -0.346822 +v 0.700769 -0.745092 -0.350171 +v 0.701971 -0.745700 -0.352367 +v 0.702679 -0.745970 -0.353122 +v 0.703352 -0.745975 -0.352291 +v 0.704456 -0.745826 -0.349970 +v 0.704949 -0.745373 -0.346558 +v 1.274019 1.917154 -0.768476 +v 1.275598 1.915664 -0.775606 +v 1.274329 1.914741 -0.782892 +v 1.270405 1.914526 -0.789226 +v 1.264423 1.915052 -0.793641 +v 1.257295 1.916238 -0.795468 +v 1.250105 1.917904 -0.794426 +v 1.243949 1.919797 -0.790676 +v 1.239762 1.921628 -0.784787 +v 1.238183 1.923118 -0.777657 +v 1.239453 1.924041 -0.770370 +v 1.243377 1.924256 -0.764038 +v 1.249358 1.923730 -0.759622 +v 1.256486 1.922544 -0.757796 +v 1.263676 1.920877 -0.758837 +v 1.269833 1.918985 -0.762587 +vt 0.479052 0.776939 +vt 0.480188 0.778074 +vt 0.480529 0.777846 +vt 0.479280 0.776597 +vt 0.473341 0.782648 +vt 0.472726 0.781164 +vt 0.472323 0.781244 +vt 0.472999 0.782876 +vt 0.482550 0.781164 +vt 0.482550 0.779558 +vt 0.482147 0.779478 +vt 0.482147 0.781244 +vt 0.485785 0.784398 +vt 0.484301 0.783783 +vt 0.484072 0.784125 +vt 0.485705 0.784801 +vt 0.473341 0.778074 +vt 0.474477 0.776939 +vt 0.474249 0.776597 +vt 0.472999 0.777846 +vt 0.479052 0.783783 +vt 0.477568 0.784398 +vt 0.477648 0.784801 +vt 0.479280 0.784125 +vt 0.487391 0.784398 +vt 0.487471 0.784801 +vt 0.488875 0.783783 +vt 0.489104 0.784125 +vt 0.480802 0.779558 +vt 0.481206 0.779478 +vt 0.472726 0.779558 +vt 0.472323 0.779478 +vt 0.490011 0.782648 +vt 0.490353 0.782876 +vt 0.475961 0.776324 +vt 0.475881 0.775921 +vt 0.475961 0.784398 +vt 0.475881 0.784801 +vt 0.490626 0.781164 +vt 0.491029 0.781244 +vt 0.490626 0.779558 +vt 0.491029 0.779478 +vt 0.480802 0.781164 +vt 0.481206 0.781244 +vt 0.483165 0.782648 +vt 0.482823 0.782876 +vt 0.483165 0.778074 +vt 0.482823 0.777846 +vt 0.480188 0.782648 +vt 0.480529 0.782876 +vt 0.484301 0.776939 +vt 0.484072 0.776597 +vt 0.485785 0.776324 +vt 0.485705 0.775921 +vt 0.474477 0.783783 +vt 0.474249 0.784125 +vt 0.477568 0.776324 +vt 0.477648 0.775921 +vt 0.487391 0.776324 +vt 0.487471 0.775921 +vt 0.488875 0.776939 +vt 0.489104 0.776597 +vt 0.490011 0.778074 +vt 0.490353 0.777846 +vt 0.215162 0.081324 +vt 0.214657 0.081324 +vt 0.214657 0.083141 +vt 0.214152 0.083141 +vt 0.214657 0.080895 +vt 0.214152 0.081324 +vt 0.215386 0.080895 +vt 0.969971 0.239730 +vt 0.969741 0.236839 +vt 0.967065 0.236422 +vt 0.967180 0.240092 +vt 0.969835 0.234352 +vt 0.967681 0.233218 +vt 0.970237 0.232645 +vt 0.968933 0.230968 +vt 0.970886 0.231980 +vt 0.970631 0.230014 +vt 0.971684 0.232457 +vt 0.972516 0.230502 +vt 0.972509 0.234004 +vt 0.974302 0.232358 +vt 0.973753 0.239238 +vt 0.973982 0.242129 +vt 0.976658 0.242546 +vt 0.976544 0.238876 +vt 0.973236 0.236385 +vt 0.975716 0.235298 +vt 0.970488 0.242583 +vt 0.968007 0.243670 +vt 0.971214 0.244964 +vt 0.976043 0.245750 +vt 0.866611 0.034323 +vt 0.865943 0.036301 +vt 0.866791 0.037604 +vt 0.867693 0.034464 +vt 0.860613 0.038941 +vt 0.858634 0.038273 +vt 0.857852 0.041050 +vt 0.860215 0.042005 +vt 0.859909 0.028466 +vt 0.861993 0.028326 +vt 0.862391 0.025262 +vt 0.859862 0.025581 +vt 0.866471 0.032239 +vt 0.867623 0.031197 +vt 0.862697 0.038800 +vt 0.862743 0.041685 +vt 0.858037 0.029393 +vt 0.857553 0.027127 +vt 0.856134 0.035027 +vt 0.855994 0.032944 +vt 0.854912 0.032803 +vt 0.854982 0.036070 +vt 0.865544 0.030368 +vt 0.866591 0.028301 +vt 0.863972 0.028994 +vt 0.864754 0.026217 +vt 0.857061 0.036898 +vt 0.856014 0.038966 +vt 0.856662 0.030965 +vt 0.855815 0.029663 +vt 0.864569 0.037874 +vt 0.865052 0.040140 +vt 0.522315 0.778716 +vt 0.523172 0.778361 +vt 0.522815 0.776564 +vt 0.521297 0.777192 +vt 0.521658 0.779373 +vt 0.520135 0.778354 +vt 0.521303 0.780230 +vt 0.519506 0.779872 +vt 0.521303 0.781158 +vt 0.519506 0.781516 +vt 0.521658 0.782016 +vt 0.520135 0.783034 +vt 0.522315 0.782672 +vt 0.521297 0.784196 +vt 0.523172 0.783027 +vt 0.522815 0.784825 +vt 0.524100 0.783027 +vt 0.524458 0.784825 +vt 0.524958 0.782672 +vt 0.525976 0.784196 +vt 0.525614 0.782016 +vt 0.527138 0.783035 +vt 0.525969 0.781159 +vt 0.527767 0.781516 +vt 0.525969 0.780231 +vt 0.527767 0.779873 +vt 0.525614 0.779373 +vt 0.527138 0.778355 +vt 0.524958 0.778717 +vt 0.525976 0.777193 +vt 0.524100 0.778361 +vt 0.524458 0.776564 +vt 0.514017 0.783027 +vt 0.513160 0.782672 +vt 0.512141 0.784196 +vt 0.513659 0.784825 +vt 0.512503 0.782016 +vt 0.510979 0.783034 +vt 0.512148 0.781159 +vt 0.510350 0.781516 +vt 0.512148 0.780230 +vt 0.510350 0.779873 +vt 0.512503 0.779373 +vt 0.510979 0.778355 +vt 0.513160 0.778717 +vt 0.512142 0.777193 +vt 0.514017 0.778361 +vt 0.513660 0.776564 +vt 0.514946 0.778361 +vt 0.515303 0.776564 +vt 0.515803 0.778717 +vt 0.516822 0.777193 +vt 0.516459 0.779373 +vt 0.517984 0.778355 +vt 0.516815 0.780230 +vt 0.518612 0.779873 +vt 0.516815 0.781159 +vt 0.518612 0.781516 +vt 0.516459 0.782016 +vt 0.517983 0.783034 +vt 0.515803 0.782672 +vt 0.516821 0.784196 +vt 0.514945 0.783027 +vt 0.515303 0.784825 +vt 0.214152 0.084987 +vt 0.214657 0.084987 +vt 0.215162 0.083141 +vt 0.866367 0.441864 +vt 0.866378 0.441398 +vt 0.864787 0.441395 +vt 0.864852 0.441861 +vt 0.863404 0.441387 +vt 0.863535 0.441854 +vt 0.856596 0.156753 +vt 0.856735 0.156288 +vt 0.855400 0.156305 +vt 0.855324 0.156769 +vt 0.853824 0.156310 +vt 0.853824 0.156774 +vt 0.852248 0.156305 +vt 0.852324 0.156769 +vt 0.850913 0.156288 +vt 0.851052 0.156753 +vt 0.359128 0.015855 +vt 0.359278 0.015389 +vt 0.358024 0.015397 +vt 0.357933 0.015862 +vt 0.356481 0.015399 +vt 0.356463 0.015865 +vt 0.354884 0.015397 +vt 0.354943 0.015862 +vt 0.353477 0.015389 +vt 0.353603 0.015855 +vt 0.805292 0.591007 +vt 0.805430 0.590543 +vt 0.804095 0.590564 +vt 0.804020 0.591027 +vt 0.802519 0.590571 +vt 0.802519 0.591034 +vt 0.800944 0.590564 +vt 0.801019 0.591027 +vt 0.799608 0.590543 +vt 0.799747 0.591007 +vt 0.869071 0.441854 +vt 0.869217 0.441387 +vt 0.867934 0.441395 +vt 0.867848 0.441861 +vt 0.978543 0.249543 +vt 0.979335 0.242964 +vt 0.140848 0.082359 +vt 0.140843 0.083934 +vt 0.142126 0.083934 +vt 0.142131 0.082643 +vt 0.583791 0.783772 +vt 0.584295 0.782556 +vt 0.583177 0.782334 +vt 0.582844 0.783139 +vt 0.661300 0.092012 +vt 0.661293 0.093587 +vt 0.662579 0.093587 +vt 0.662585 0.092296 +vt 0.140865 0.081023 +vt 0.142144 0.081549 +vt 0.661321 0.090676 +vt 0.662602 0.091202 +vt 0.214008 0.047225 +vt 0.214016 0.048479 +vt 0.215290 0.047912 +vt 0.215284 0.046884 +vt 0.839635 0.048028 +vt 0.839643 0.049311 +vt 0.840917 0.048757 +vt 0.840911 0.047706 +vt 0.214005 0.045682 +vt 0.215282 0.045620 +vt 0.839635 0.044883 +vt 0.839633 0.046473 +vt 0.840909 0.046432 +vt 0.840911 0.045129 +vt 0.214008 0.044086 +vt 0.215284 0.044312 +vt 0.839643 0.043500 +vt 0.840917 0.043996 +vt 0.214016 0.042680 +vt 0.215290 0.043160 +vt 0.140848 0.085509 +vt 0.140865 0.086844 +vt 0.142144 0.086318 +vt 0.142131 0.085224 +vt 0.661300 0.095162 +vt 0.661321 0.096497 +vt 0.662602 0.095971 +vt 0.662585 0.094877 +vt 0.633815 0.785224 +vt 0.634255 0.785222 +vt 0.634255 0.780613 +vt 0.633815 0.780616 +vt 0.579113 0.779094 +vt 0.578182 0.780024 +vt 0.579129 0.780657 +vt 0.579746 0.780041 +vt 0.582861 0.784702 +vt 0.582228 0.783755 +vt 0.580329 0.778591 +vt 0.580551 0.779708 +vt 0.581645 0.785205 +vt 0.581422 0.784088 +vt 0.581645 0.778591 +vt 0.581422 0.779708 +vt 0.580329 0.785205 +vt 0.580551 0.784088 +vt 0.582861 0.779094 +vt 0.582228 0.780041 +vt 0.579113 0.784702 +vt 0.579746 0.783755 +vt 0.583791 0.780024 +vt 0.582844 0.780657 +vt 0.578182 0.783772 +vt 0.579129 0.783139 +vt 0.584295 0.781240 +vt 0.583177 0.781462 +vt 0.577678 0.781240 +vt 0.577678 0.782556 +vt 0.578796 0.782334 +vt 0.578796 0.781462 +vt 0.477722 0.775547 +vt 0.475807 0.775547 +vt 0.489316 0.784442 +vt 0.490670 0.783088 +vt 0.479492 0.776280 +vt 0.491404 0.781319 +vt 0.480847 0.777634 +vt 0.491404 0.779404 +vt 0.481580 0.779404 +vt 0.490670 0.777634 +vt 0.481580 0.781319 +vt 0.489316 0.776280 +vt 0.480847 0.783088 +vt 0.487546 0.775547 +vt 0.479492 0.784442 +vt 0.485630 0.775547 +vt 0.477722 0.785175 +vt 0.483860 0.776280 +vt 0.953154 0.737105 +vt 0.953174 0.738698 +vt 0.954988 0.738698 +vt 0.954968 0.737105 +vt 0.956887 0.735361 +vt 0.956890 0.737201 +vt 0.958704 0.737202 +vt 0.958701 0.735362 +vt 0.955028 0.733416 +vt 0.955024 0.735312 +vt 0.956838 0.735313 +vt 0.956841 0.733416 +vt 0.950736 0.540127 +vt 0.950745 0.538249 +vt 0.948931 0.538249 +vt 0.948923 0.540127 +vt 0.953174 0.731756 +vt 0.953154 0.733349 +vt 0.954968 0.733349 +vt 0.954988 0.731756 +vt 0.950736 0.536370 +vt 0.950711 0.534778 +vt 0.948898 0.534778 +vt 0.948923 0.536370 +vt 0.955028 0.737167 +vt 0.956841 0.737167 +vt 0.953147 0.735227 +vt 0.954961 0.735227 +vt 0.956890 0.733458 +vt 0.958704 0.733459 +vt 0.950711 0.541720 +vt 0.948898 0.541720 +vt 0.955037 0.731766 +vt 0.956850 0.731767 +vt 0.956900 0.738697 +vt 0.958713 0.738698 +vt 0.956900 0.731780 +vt 0.958713 0.731782 +vt 0.955037 0.738697 +vt 0.956850 0.738698 +vt 0.472682 0.777634 +vt 0.471949 0.779404 +vt 0.487546 0.785175 +vt 0.474037 0.776280 +vt 0.471949 0.781319 +vt 0.485630 0.785175 +vt 0.472682 0.783088 +vt 0.483860 0.784442 +vt 0.481773 0.779404 +vt 0.481773 0.781319 +vt 0.474037 0.784442 +vt 0.482506 0.783088 +vt 0.482506 0.777634 +vt 0.475807 0.785175 +vt 0.875025 0.433741 +vt 0.873340 0.433734 +vt 0.873340 0.435552 +vt 0.875025 0.435558 +vt 0.862338 0.048045 +vt 0.865190 0.045066 +vt 0.857415 0.022201 +vt 0.854968 0.028360 +vt 0.979335 0.238513 +vt 0.978197 0.234211 +vt 0.974791 0.248000 +vt 0.976546 0.253153 +vt 0.853830 0.037113 +vt 0.854622 0.043693 +vt 0.867984 0.023574 +vt 0.865987 0.019965 +vt 0.973093 0.248954 +vt 0.973837 0.254681 +vt 0.971207 0.248466 +vt 0.970827 0.253896 +vt 0.867638 0.038907 +vt 0.969421 0.246610 +vt 0.967974 0.250916 +vt 0.853830 0.032663 +vt 0.856618 0.047302 +vt 0.863278 0.018437 +vt 0.965527 0.244757 +vt 0.964389 0.240455 +vt 0.849704 0.862969 +vt 0.849726 0.865852 +vt 0.850897 0.865852 +vt 0.850876 0.862969 +vt 0.592075 0.309197 +vt 0.592080 0.304751 +vt 0.590909 0.304751 +vt 0.590904 0.309197 +vt 0.592115 0.351745 +vt 0.592094 0.348564 +vt 0.590923 0.348564 +vt 0.590943 0.351744 +vt 0.592080 0.333430 +vt 0.592094 0.326926 +vt 0.590923 0.326926 +vt 0.590909 0.333430 +vt 0.592095 0.319806 +vt 0.592080 0.313546 +vt 0.590909 0.313545 +vt 0.590923 0.319805 +vt 0.850903 0.874617 +vt 0.850876 0.871734 +vt 0.849704 0.871734 +vt 0.849731 0.874617 +vt 0.849704 0.868735 +vt 0.850876 0.868735 +vt 0.592095 0.298213 +vt 0.590923 0.298212 +vt 0.592080 0.342243 +vt 0.590909 0.342242 +vt 0.592115 0.323473 +vt 0.590943 0.323472 +vt 0.592075 0.337869 +vt 0.590904 0.337868 +vt 0.850903 0.868851 +vt 0.849731 0.868851 +vt 0.592116 0.322907 +vt 0.590944 0.322906 +vt 0.592116 0.294694 +vt 0.590944 0.294694 +vt 0.975749 0.228052 +vt 0.868776 0.030154 +vt 0.972897 0.225073 +vt 0.969887 0.224287 +vt 0.860268 0.019222 +vt 0.859327 0.048830 +vt 0.967177 0.225816 +vt 0.868776 0.034604 +vt 0.965181 0.229425 +vt 0.964389 0.236005 +vt 0.868038 0.450471 +vt 0.866388 0.450474 +vt 0.869400 0.450463 +vt 0.800847 0.599641 +vt 0.799430 0.599619 +vt 0.802519 0.599649 +vt 0.804191 0.599641 +vt 0.805608 0.599619 +vt 0.354801 0.024472 +vt 0.353308 0.024464 +vt 0.356495 0.024475 +vt 0.358132 0.024472 +vt 0.359464 0.024464 +vt 0.852152 0.165381 +vt 0.850735 0.165364 +vt 0.853824 0.165388 +vt 0.855496 0.165381 +vt 0.856913 0.165364 +vt 0.864700 0.450471 +vt 0.863232 0.450463 +vt 0.866420 0.485522 +vt 0.866400 0.480092 +vt 0.864530 0.480089 +vt 0.864395 0.485519 +vt 0.866413 0.474171 +vt 0.864472 0.474168 +vt 0.866388 0.468244 +vt 0.864637 0.468241 +vt 0.866400 0.462322 +vt 0.864586 0.462319 +vt 0.866377 0.456395 +vt 0.864744 0.456393 +vt 0.862904 0.480080 +vt 0.862633 0.485509 +vt 0.862783 0.474158 +vt 0.863114 0.468232 +vt 0.863008 0.462311 +vt 0.863324 0.456385 +vt 0.857531 0.200412 +vt 0.857246 0.194980 +vt 0.855676 0.195000 +vt 0.855830 0.200433 +vt 0.857377 0.189061 +vt 0.855747 0.189081 +vt 0.857029 0.183132 +vt 0.855559 0.183150 +vt 0.857145 0.177212 +vt 0.855621 0.177231 +vt 0.856813 0.171284 +vt 0.855442 0.171301 +vt 0.853824 0.195007 +vt 0.853824 0.200440 +vt 0.853824 0.189088 +vt 0.853824 0.183157 +vt 0.853824 0.177238 +vt 0.853824 0.171307 +vt 0.851972 0.195000 +vt 0.851818 0.200433 +vt 0.851901 0.189081 +vt 0.852089 0.183150 +vt 0.852027 0.177231 +vt 0.852207 0.171301 +vt 0.850402 0.194980 +vt 0.850117 0.200412 +vt 0.850271 0.189061 +vt 0.850619 0.183132 +vt 0.850503 0.177212 +vt 0.850835 0.171284 +vt 0.360106 0.059511 +vt 0.359802 0.054081 +vt 0.358327 0.054090 +vt 0.358508 0.059521 +vt 0.359948 0.048160 +vt 0.358417 0.048169 +vt 0.359576 0.042234 +vt 0.358195 0.042242 +vt 0.359706 0.036312 +vt 0.358275 0.036321 +vt 0.359351 0.030386 +vt 0.358063 0.030394 +vt 0.356513 0.054094 +vt 0.356544 0.059524 +vt 0.356534 0.048172 +vt 0.356496 0.042245 +vt 0.356514 0.036324 +vt 0.356479 0.030397 +vt 0.354637 0.054090 +vt 0.354511 0.059521 +vt 0.354585 0.048169 +vt 0.354738 0.042242 +vt 0.354693 0.036321 +vt 0.354840 0.030394 +vt 0.352983 0.054081 +vt 0.352719 0.059511 +vt 0.352868 0.048160 +vt 0.353189 0.042234 +vt 0.353088 0.036312 +vt 0.353395 0.030386 +vt 0.806226 0.634667 +vt 0.805941 0.629234 +vt 0.804371 0.629259 +vt 0.804525 0.634693 +vt 0.806072 0.623316 +vt 0.804442 0.623341 +vt 0.805724 0.617386 +vt 0.804254 0.617409 +vt 0.805840 0.611468 +vt 0.804317 0.611491 +vt 0.805508 0.605538 +vt 0.804137 0.605560 +vt 0.802519 0.629267 +vt 0.802519 0.634702 +vt 0.802519 0.623350 +vt 0.802519 0.617417 +vt 0.802519 0.611500 +vt 0.802519 0.605567 +vt 0.800667 0.629259 +vt 0.800513 0.634693 +vt 0.800596 0.623341 +vt 0.800785 0.617409 +vt 0.800722 0.611491 +vt 0.800902 0.605560 +vt 0.799098 0.629234 +vt 0.798812 0.634667 +vt 0.798966 0.623316 +vt 0.799314 0.617386 +vt 0.799198 0.611468 +vt 0.799530 0.605538 +vt 0.870035 0.485509 +vt 0.869737 0.480080 +vt 0.868228 0.480089 +vt 0.868400 0.485519 +vt 0.869878 0.474158 +vt 0.868312 0.474168 +vt 0.869514 0.468232 +vt 0.868101 0.468241 +vt 0.869639 0.462311 +vt 0.868175 0.462319 +vt 0.869292 0.456385 +vt 0.867974 0.456393 +vt 0.868448 0.486016 +vt 0.866426 0.486019 +vt 0.870118 0.486006 +vt 0.800471 0.635191 +vt 0.798734 0.635164 +vt 0.802519 0.635201 +vt 0.804568 0.635191 +vt 0.806305 0.635164 +vt 0.354477 0.060017 +vt 0.352647 0.060007 +vt 0.356553 0.060021 +vt 0.358559 0.060017 +vt 0.360191 0.060007 +vt 0.851775 0.200931 +vt 0.850039 0.200909 +vt 0.853824 0.200938 +vt 0.855873 0.200931 +vt 0.857609 0.200909 +vt 0.864358 0.486016 +vt 0.862559 0.486006 +vt 0.879339 0.849790 +vt 0.877806 0.849844 +vt 0.877806 0.851661 +vt 0.879339 0.851607 +vt 0.877500 0.433743 +vt 0.877500 0.435561 +vt 0.881821 0.849792 +vt 0.881821 0.851609 +vt 0.872736 0.433730 +vt 0.872736 0.435548 +vt 0.892098 0.849769 +vt 0.891567 0.849774 +vt 0.891567 0.851591 +vt 0.892098 0.851586 +vt 0.890004 0.849782 +vt 0.890004 0.851599 +vt 0.887129 0.433788 +vt 0.885712 0.433736 +vt 0.885712 0.435553 +vt 0.887129 0.435606 +vt 0.887593 0.849787 +vt 0.887593 0.851605 +vt 0.883284 0.433740 +vt 0.883284 0.435558 +vt 0.884719 0.849791 +vt 0.884719 0.851608 +vt 0.880400 0.433743 +vt 0.880400 0.435560 +vt 0.884719 0.849362 +vt 0.881821 0.849363 +vt 0.883284 0.433311 +vt 0.880400 0.433314 +vt 0.877500 0.433314 +vt 0.887593 0.849358 +vt 0.885712 0.433307 +vt 0.890004 0.849353 +vt 0.887141 0.433361 +vt 0.891586 0.849346 +vt 0.213927 0.080895 +vt 0.509806 0.774153 +vt 0.509817 0.773424 +vt 0.509388 0.773649 +vt 0.509377 0.774153 +vt 0.509817 0.774883 +vt 0.509388 0.774658 +vt 0.879339 0.849361 +vt 0.877825 0.849417 +vt 0.875025 0.433312 +vt 0.873352 0.433307 +vt 0.972037 0.246333 +vt 0.972760 0.246239 +vt 0.973484 0.246145 +vt 0.973889 0.244616 +vt 0.579601 0.782174 +vt 0.579601 0.781622 +vt 0.579812 0.781113 +vt 0.580202 0.780724 +vt 0.580711 0.780513 +vt 0.581262 0.780513 +vt 0.581772 0.780724 +vt 0.582161 0.781113 +vt 0.582372 0.781622 +vt 0.582372 0.782174 +vt 0.582161 0.782683 +vt 0.581772 0.783073 +vt 0.581262 0.783283 +vt 0.580711 0.783283 +vt 0.580202 0.783072 +vt 0.579812 0.782683 +vt 0.944155 0.901336 +vt 0.944685 0.901334 +vt 0.944685 0.896726 +vt 0.944155 0.896727 +vt 0.632735 0.785225 +vt 0.633281 0.785226 +vt 0.633281 0.780617 +vt 0.632735 0.780616 +vt 0.943607 0.901335 +vt 0.943607 0.896726 +vt 0.632260 0.785222 +vt 0.632260 0.780614 +vt 0.943124 0.901333 +vt 0.943124 0.896724 +vt 0.942626 0.901334 +vt 0.943084 0.901328 +vt 0.943084 0.896720 +vt 0.942626 0.896725 +vt 0.939756 0.149572 +vt 0.940215 0.149565 +vt 0.940215 0.144957 +vt 0.939756 0.144964 +vt 0.942085 0.901336 +vt 0.942085 0.896727 +vt 0.939216 0.149575 +vt 0.939216 0.144967 +vt 0.941545 0.901334 +vt 0.941545 0.896725 +vt 0.938675 0.149572 +vt 0.938675 0.144964 +vt 0.941086 0.901328 +vt 0.941086 0.896720 +vt 0.938217 0.149565 +vt 0.938217 0.144957 +vt 0.945115 0.901331 +vt 0.945115 0.896723 +vt 0.828891 0.879340 +vt 0.829659 0.879384 +vt 0.829659 0.875658 +vt 0.828891 0.875614 +vt 0.827982 0.879323 +vt 0.827982 0.875598 +vt 0.148701 0.096994 +vt 0.148617 0.095501 +vt 0.144890 0.095504 +vt 0.144975 0.096997 +vt 0.152663 0.095513 +vt 0.152663 0.096997 +vt 0.156403 0.096997 +vt 0.156403 0.095513 +vt 0.160219 0.092011 +vt 0.160219 0.090526 +vt 0.156478 0.090526 +vt 0.156478 0.092011 +vt 0.152663 0.093762 +vt 0.156404 0.093762 +vt 0.160219 0.093762 +vt 0.156478 0.093762 +vt 0.152663 0.092011 +vt 0.156403 0.092011 +vt 0.160219 0.095513 +vt 0.156478 0.095513 +vt 0.152663 0.090526 +vt 0.156403 0.090526 +vt 0.160219 0.096997 +vt 0.156478 0.096997 +vt 0.148617 0.092000 +vt 0.148701 0.090524 +vt 0.144975 0.090527 +vt 0.144890 0.092002 +vt 0.148797 0.095504 +vt 0.148853 0.096997 +vt 0.152587 0.096995 +vt 0.152532 0.095502 +vt 0.148587 0.093747 +vt 0.144860 0.093750 +vt 0.148797 0.092003 +vt 0.148778 0.093750 +vt 0.152512 0.093749 +vt 0.152532 0.092001 +vt 0.148853 0.090527 +vt 0.152587 0.090525 +vt 0.522744 0.776207 +vt 0.521094 0.776890 +vt 0.519832 0.778152 +vt 0.519149 0.779801 +vt 0.519149 0.781587 +vt 0.519832 0.783236 +vt 0.521094 0.784498 +vt 0.522744 0.785182 +vt 0.524529 0.785182 +vt 0.526178 0.784499 +vt 0.527441 0.783237 +vt 0.528124 0.781587 +vt 0.528124 0.779802 +vt 0.527441 0.778153 +vt 0.526178 0.776890 +vt 0.524529 0.776207 +vt 0.511939 0.784499 +vt 0.513588 0.785182 +vt 0.510677 0.783236 +vt 0.509993 0.781587 +vt 0.509993 0.779802 +vt 0.510677 0.778153 +vt 0.511939 0.776890 +vt 0.513589 0.776207 +vt 0.515374 0.776207 +vt 0.517024 0.776890 +vt 0.518286 0.778153 +vt 0.518969 0.779802 +vt 0.518969 0.781587 +vt 0.518286 0.783236 +vt 0.517023 0.784499 +vt 0.515374 0.785182 +vt 0.835950 0.879385 +vt 0.836722 0.879384 +vt 0.836722 0.875645 +vt 0.835950 0.875645 +vt 0.837632 0.879384 +vt 0.837632 0.875645 +vt 0.838543 0.879384 +vt 0.838543 0.875645 +vt 0.839315 0.879385 +vt 0.839315 0.875645 +vt 0.829726 0.879345 +vt 0.830494 0.879374 +vt 0.830494 0.875640 +vt 0.829726 0.875611 +vt 0.831402 0.879384 +vt 0.831402 0.875651 +vt 0.832314 0.879375 +vt 0.832314 0.875641 +vt 0.833091 0.879346 +vt 0.833091 0.875613 +vt 0.839382 0.879385 +vt 0.840154 0.879385 +vt 0.840154 0.875645 +vt 0.839382 0.875645 +vt 0.841065 0.879385 +vt 0.841065 0.875645 +vt 0.841975 0.879385 +vt 0.841975 0.875645 +vt 0.842747 0.879385 +vt 0.842747 0.875645 +vt 0.826294 0.879382 +vt 0.827070 0.879338 +vt 0.827070 0.875612 +vt 0.826294 0.875656 +vt 0.884719 0.933746 +vt 0.881821 0.933747 +vt 0.884274 0.998508 +vt 0.884573 0.998508 +vt 0.880400 0.517698 +vt 0.877500 0.517698 +vt 0.880005 0.582461 +vt 0.880304 0.582461 +vt 0.883284 0.517696 +vt 0.880602 0.582461 +vt 0.887593 0.933743 +vt 0.884870 0.998508 +vt 0.885712 0.517691 +vt 0.880853 0.582460 +vt 0.890004 0.933737 +vt 0.885119 0.998507 +vt 0.887303 0.517683 +vt 0.881017 0.582459 +vt 0.891567 0.933729 +vt 0.885280 0.998506 +vt 0.887851 0.517678 +vt 0.881074 0.582459 +vt 0.892098 0.933724 +vt 0.885335 0.998506 +vt 0.877632 0.933739 +vt 0.877015 0.933735 +vt 0.883778 0.998507 +vt 0.883841 0.998508 +vt 0.873340 0.517690 +vt 0.872736 0.517686 +vt 0.879513 0.582460 +vt 0.879575 0.582460 +vt 0.879339 0.933745 +vt 0.884018 0.998508 +vt 0.875025 0.517696 +vt 0.879749 0.582461 +vt 0.881821 0.855302 +vt 0.884719 0.855301 +vt 0.884719 0.853455 +vt 0.881821 0.853456 +vt 0.880400 0.439254 +vt 0.883284 0.439251 +vt 0.883284 0.437404 +vt 0.880400 0.437407 +vt 0.877500 0.439254 +vt 0.877500 0.437407 +vt 0.887593 0.855298 +vt 0.887593 0.853451 +vt 0.885712 0.439246 +vt 0.885712 0.437400 +vt 0.890004 0.855293 +vt 0.890004 0.853446 +vt 0.887303 0.439238 +vt 0.887129 0.437452 +vt 0.891567 0.855284 +vt 0.890066 0.853178 +vt 0.204044 0.417454 +vt 0.203193 0.417712 +vt 0.203200 0.419270 +vt 0.204044 0.419300 +vt 0.214172 0.086777 +vt 0.214677 0.086790 +vt 0.892098 0.855279 +vt 0.890597 0.853174 +vt 0.215182 0.086777 +vt 0.215162 0.084987 +vt 0.872736 0.439241 +vt 0.873340 0.439245 +vt 0.874843 0.437138 +vt 0.874240 0.437134 +vt 0.877632 0.855294 +vt 0.879339 0.855301 +vt 0.879339 0.853454 +vt 0.877806 0.853508 +vt 0.875025 0.439251 +vt 0.875025 0.437405 +vt 0.877015 0.855291 +vt 0.887851 0.439234 +vt 0.215303 0.564413 +vt 0.215199 0.564418 +vt 0.215254 0.564475 +vt 0.215381 0.564240 +vt 0.215103 0.564253 +vt 0.215411 0.563984 +vt 0.215048 0.564002 +vt 0.215018 0.563704 +vt 0.215411 0.563685 +vt 0.215381 0.563387 +vt 0.215018 0.563405 +vt 0.215326 0.563136 +vt 0.215048 0.563150 +vt 0.215230 0.562971 +vt 0.215126 0.562976 +vt 0.215175 0.562914 +vt 0.515405 0.774568 +vt 0.514804 0.775467 +vt 0.515194 0.775078 +vt 0.515405 0.774017 +vt 0.514295 0.775678 +vt 0.515194 0.773508 +vt 0.513744 0.775678 +vt 0.514804 0.773118 +vt 0.513234 0.775467 +vt 0.512844 0.775078 +vt 0.514295 0.772907 +vt 0.513744 0.772907 +vt 0.512634 0.774568 +vt 0.513234 0.773118 +vt 0.512634 0.774017 +vt 0.512844 0.773508 +vn -0.1634 -0.9190 -0.3587 +vn -0.3523 -0.8753 -0.3313 +vn -0.2012 -0.9668 0.1575 +vn -0.1634 -0.9191 -0.3586 +vn -0.2012 -0.9668 0.1576 +vn 0.0042 -0.7972 0.6037 +vn 0.1659 -0.8469 0.5052 +vn -0.2013 -0.9668 0.1575 +vn 0.6184 0.7772 -0.1168 +vn 0.5814 0.8121 0.0503 +vn 0.2013 0.9668 -0.1575 +vn 0.3565 0.7628 -0.5394 +vn 0.4966 0.7506 -0.4360 +vn 0.2012 0.9668 -0.1575 +vn 0.3565 0.7629 -0.5394 +vn 0.3175 -0.9341 0.1632 +vn 0.2841 -0.9584 -0.0283 +vn 0.3174 -0.9341 0.1632 +vn -0.6322 -0.7141 0.3007 +vn -0.5291 -0.7085 0.4671 +vn 0.1894 0.7906 -0.5823 +vn 0.3565 0.7628 -0.5395 +vn 0.0209 0.8297 -0.5579 +vn 0.0209 0.8297 -0.5578 +vn -0.3523 -0.8752 -0.3314 +vn -0.5141 -0.8256 -0.2328 +vn -0.2012 -0.9668 0.1574 +vn -0.3524 -0.8753 -0.3313 +vn 0.2760 -0.8950 0.3505 +vn -0.1233 0.8740 -0.4700 +vn -0.1233 0.8741 -0.4699 +vn 0.1810 -0.9640 -0.1946 +vn -0.5291 -0.7084 0.4671 +vn -0.3720 -0.7222 0.5831 +vn -0.2215 0.9169 -0.3320 +vn -0.1233 0.8740 -0.4699 +vn -0.2585 0.9518 -0.1649 +vn -0.2584 0.9519 -0.1649 +vn -0.6241 -0.7775 -0.0780 +vn -0.5141 -0.8256 -0.2327 +vn 0.4966 0.7506 -0.4359 +vn 0.5886 0.7556 -0.2876 +vn 0.4832 0.8550 0.1883 +vn 0.5886 0.7555 -0.2876 +vn -0.6656 -0.7383 0.1093 +vn -0.6322 -0.7141 0.3008 +vn 0.3389 0.8994 0.2762 +vn 0.3390 0.8993 0.2762 +vn 0.1705 0.9384 0.3006 +vn 0.3390 0.8994 0.2761 +vn -0.1847 -0.7534 0.6311 +vn 0.0042 -0.7972 0.6038 +vn 0.0238 -0.9502 -0.3106 +vn -0.1635 -0.9191 -0.3586 +vn -0.2013 -0.9668 0.1576 +vn 0.0239 -0.9502 -0.3107 +vn 0.0034 0.9662 0.2578 +vn -0.6241 -0.7774 -0.0780 +vn 0.0034 0.9662 0.2579 +vn -0.1367 0.9785 0.1544 +vn 0.2012 0.9668 -0.1574 +vn -0.1367 0.9785 0.1543 +vn -0.2287 0.9735 0.0059 +vn -0.3720 -0.7223 0.5831 +vn -0.3720 -0.7222 0.5832 +vn -0.4305 -0.1109 -0.8957 +vn 0.0212 -0.1651 -0.9861 +vn 0.5128 -0.2410 -0.8240 +vn -0.1254 -0.7935 -0.5955 +vn 0.4554 -0.2879 -0.8424 +vn 0.0212 -0.1650 -0.9861 +vn -0.4682 -0.8528 -0.2312 +vn -0.8257 -0.5590 0.0759 +vn -0.8217 -0.5497 0.1504 +vn -0.8257 -0.5590 0.0758 +vn -0.7580 -0.5940 0.2692 +vn -0.8217 -0.5497 0.1505 +vn -0.6221 -0.6702 0.4047 +vn -0.1922 -0.8142 0.5479 +vn -0.6222 -0.6702 0.4047 +vn -0.1923 -0.8142 0.5479 +vn 0.2725 -0.8484 0.4538 +vn 0.2726 -0.8484 0.4537 +vn 0.4407 -0.8329 0.3349 +vn 0.5365 -0.8304 0.1505 +vn 0.5317 -0.8434 0.0765 +vn 0.5286 -0.8187 0.2245 +vn -0.8185 -0.5745 0.0025 +vn -0.8185 -0.5744 0.0025 +vn -0.7428 -0.6620 -0.0998 +vn -0.8185 -0.5744 0.0024 +vn 0.5317 -0.8435 0.0764 +vn -0.1957 -0.9678 0.1585 +vn -0.3960 0.9042 -0.1599 +vn -0.3487 0.8595 -0.3736 +vn -0.3959 0.9043 -0.1599 +vn 0.1771 0.6980 -0.6939 +vn 0.3908 0.6624 -0.6392 +vn 0.3684 0.8370 0.4045 +vn 0.1528 0.8870 0.4357 +vn 0.3684 0.8371 0.4045 +vn -0.3579 0.9319 0.0586 +vn -0.0385 0.7479 -0.6627 +vn 0.5530 0.7803 0.2920 +vn 0.6878 0.6530 -0.3169 +vn 0.7259 0.6808 -0.0984 +vn 0.6879 0.6531 -0.3168 +vn -0.2402 0.9384 0.2485 +vn -0.3579 0.9319 0.0587 +vn 0.1529 0.8870 0.4357 +vn -0.0609 0.9226 0.3810 +vn 0.5701 0.6466 -0.5067 +vn 0.7259 0.6808 -0.0983 +vn 0.6786 0.7254 0.1154 +vn -0.3487 0.8596 -0.3736 +vn -0.2231 0.8047 -0.5502 +vn 0.5701 0.6466 -0.5068 +vn 0.5702 0.6466 -0.5067 +vn -0.5280 0.2372 -0.8155 +vn -0.6276 0.0039 -0.7785 +vn -0.3455 0.4155 -0.8414 +vn -0.3456 0.4155 -0.8414 +vn -0.1081 0.5116 -0.8524 +vn 0.1483 0.5109 -0.8468 +vn -0.1084 0.5116 -0.8524 +vn 0.1482 0.5109 -0.8468 +vn 0.3844 0.4135 -0.8254 +vn 0.1479 0.5110 -0.8468 +vn 0.0211 -0.1650 -0.9861 +vn 0.5646 0.2341 -0.7915 +vn 0.3846 0.4134 -0.8254 +vn 0.5645 0.2342 -0.7915 +vn 0.6611 0.0002 -0.7503 +vn 0.6611 0.0003 -0.7503 +vn 0.6595 -0.2527 -0.7080 +vn 0.6595 -0.2526 -0.7080 +vn 0.5599 -0.4860 -0.6711 +vn 0.3775 -0.6643 -0.6451 +vn 0.1400 -0.7604 -0.6341 +vn 0.1401 -0.7604 -0.6341 +vn -0.1163 -0.7597 -0.6398 +vn -0.3526 -0.6623 -0.6611 +vn -0.3525 -0.6623 -0.6611 +vn -0.5326 -0.4830 -0.6950 +vn -0.6292 -0.2490 -0.7363 +vn -0.5326 -0.4829 -0.6950 +vn -0.6292 -0.2491 -0.7363 +vn -0.6276 0.0038 -0.7785 +vn -0.6292 -0.2491 -0.7362 +vn -0.6595 0.2526 0.7080 +vn -0.5599 0.4859 0.6711 +vn -0.0212 0.1650 0.9861 +vn -0.3775 0.6643 0.6451 +vn -0.5599 0.4860 0.6711 +vn -0.1403 0.7604 0.6341 +vn -0.1401 0.7604 0.6341 +vn 0.1163 0.7597 0.6398 +vn -0.0212 0.1651 0.9861 +vn 0.1162 0.7597 0.6398 +vn 0.3527 0.6622 0.6612 +vn 0.3524 0.6623 0.6611 +vn 0.5326 0.4830 0.6950 +vn 0.3525 0.6623 0.6611 +vn 0.6292 0.2491 0.7362 +vn 0.6276 -0.0038 0.7785 +vn 0.6276 -0.0037 0.7785 +vn 0.5280 -0.2371 0.8155 +vn 0.3456 -0.4155 0.8414 +vn 0.5280 -0.2372 0.8155 +vn 0.1082 -0.5116 0.8524 +vn -0.1482 -0.5109 0.8468 +vn 0.1081 -0.5116 0.8524 +vn -0.3844 -0.4135 0.8254 +vn -0.5645 -0.2342 0.7915 +vn -0.6611 -0.0003 0.7503 +vn 0.6428 -0.1887 -0.7424 +vn 0.0468 -0.0499 -0.9977 +vn -0.4673 -0.0465 -0.8829 +vn 0.9283 -0.3630 0.0807 +vn 0.3174 -0.9341 0.1631 +vn 0.8469 -0.2862 0.4481 +vn 0.6312 -0.1919 0.7515 +vn 0.0042 -0.7971 0.6038 +vn 0.3140 -0.0944 0.9447 +vn -0.0564 -0.0086 0.9984 +vn -0.3719 -0.7222 0.5831 +vn -0.4237 0.0526 0.9043 +vn -0.7319 0.0796 0.6768 +vn -0.9341 0.0686 0.3504 +vn -0.6655 -0.7383 0.1093 +vn -0.9995 0.0210 -0.0250 +vn -0.9181 -0.0557 -0.3924 +vn -0.5140 -0.8256 -0.2328 +vn -0.7024 -0.1501 -0.6958 +vn -0.3852 -0.2476 -0.8890 +vn -0.1635 -0.9190 -0.3587 +vn -0.0148 -0.3334 -0.9427 +vn 0.0238 -0.9502 -0.3107 +vn 0.3525 -0.3946 -0.8486 +vn 0.6607 -0.4216 -0.6210 +vn 0.6607 -0.4217 -0.6210 +vn 0.2841 -0.9584 -0.0282 +vn 0.8629 -0.4106 -0.2947 +vn 0.5327 -0.8284 -0.1731 +vn 0.5559 -0.8312 0.0138 +vn 0.1064 0.7223 0.6834 +vn -0.1887 0.7714 0.6078 +vn -0.4126 0.6085 -0.6778 +vn -0.5859 0.6843 -0.4340 +vn -0.1848 0.9296 -0.3190 +vn -0.0948 0.8902 -0.4456 +vn 0.1895 0.7906 -0.5823 +vn 0.1399 0.4612 -0.8762 +vn 0.4350 0.4121 -0.8006 +vn -0.4363 0.7931 0.4250 +vn 0.4966 0.7505 -0.4359 +vn 0.6826 0.3903 -0.6178 +vn -0.5987 0.7842 0.1628 +vn 0.4966 0.7505 -0.4360 +vn 0.8451 0.3992 -0.3556 +vn -0.2585 0.9519 -0.1649 +vn -0.6513 0.7460 -0.1389 +vn 0.8976 0.4374 -0.0539 +vn 0.8323 0.4991 0.2412 +vn -0.2214 0.9169 -0.3320 +vn 0.6590 0.5749 0.4850 +vn 0.4832 0.8550 0.1882 +vn 0.4041 0.6533 0.6403 +vn -0.1577 0.5302 -0.8331 +vn 0.7516 0.5688 -0.3340 +vn 0.6166 0.5614 -0.5519 +vn 0.6619 0.4536 -0.5968 +vn 0.8152 0.4620 -0.3494 +vn 0.4617 0.8728 0.1584 +vn 0.3294 0.9135 0.2390 +vn 0.0376 0.8495 -0.5262 +vn 0.1064 0.7222 0.6834 +vn 0.1748 0.9493 0.2614 +vn 0.1922 0.8137 -0.5486 +vn 0.0215 0.9748 0.2221 +vn 0.3454 0.7882 -0.5093 +vn -0.1071 0.9861 0.1272 +vn 0.4740 0.7769 -0.4144 +vn -0.1914 0.9815 -0.0090 +vn 0.5584 0.7815 -0.2782 +vn -0.6513 0.7460 -0.1388 +vn -0.2187 0.9616 -0.1657 +vn 0.5857 0.8014 -0.1216 +vn 0.5517 0.8334 0.0317 +vn 0.1602 -0.8131 -0.5596 +vn 0.3939 -0.8337 -0.3871 +vn -0.1311 0.5855 -0.8000 +vn -0.3715 0.6595 -0.6535 +vn -0.1182 -0.7668 -0.6310 +vn -0.5351 0.7310 -0.4234 +vn -0.3990 -0.7017 -0.5903 +vn -0.5968 0.7892 -0.1450 +vn -0.6395 -0.6278 -0.4438 +vn -0.5472 0.8252 0.1397 +vn -0.8031 -0.5562 -0.2137 +vn -0.3939 0.8337 0.3871 +vn -0.8647 -0.4981 0.0648 +vn -0.1602 0.8131 0.5596 +vn -0.8151 -0.4620 0.3494 +vn 0.1182 0.7668 0.6310 +vn -0.6619 -0.4536 0.5968 +vn 0.2012 0.9668 -0.1576 +vn 0.3990 0.7017 0.5902 +vn 0.1311 -0.5855 0.8000 +vn 0.3716 -0.6595 0.6535 +vn 0.6395 0.6278 0.4438 +vn 0.3991 0.7017 0.5902 +vn -0.8152 -0.4620 0.3494 +vn -0.5472 0.8253 0.1397 +vn 0.5351 -0.7310 0.4234 +vn 0.5968 -0.7892 0.1448 +vn 0.8647 0.4980 -0.0648 +vn 0.8031 0.5563 0.2137 +vn 0.1601 -0.8131 -0.5597 +vn -0.1182 -0.7668 -0.6309 +vn 0.1497 0.5205 -0.8407 +vn 0.4282 0.4741 -0.7693 +vn -0.4281 -0.4742 0.7694 +vn -0.3991 -0.7017 -0.5902 +vn -0.3716 0.6595 -0.6535 +vn -0.1311 0.5856 -0.8000 +vn 0.5472 -0.8253 -0.1398 +vn -0.1499 -0.5204 0.8406 +vn 0.1182 0.7668 0.6309 +vn -0.8031 -0.5563 -0.2137 +vn -0.5351 0.7310 -0.4236 +vn 0.3716 -0.6595 0.6534 +vn 0.6395 0.6278 0.4437 +vn -0.6395 -0.6278 -0.4437 +vn -0.3716 0.6595 -0.6534 +vn 0.5968 -0.7892 0.1449 +vn 0.1497 0.5205 -0.8406 +vn 0.5472 -0.8253 -0.1397 +vn 0.4282 0.4742 -0.7693 +vn 0.6618 0.4536 -0.5969 +vn 0.8647 0.4981 -0.0647 +vn -0.1498 -0.5205 0.8406 +vn 0.6396 0.6278 0.4437 +vn -0.4282 -0.4741 0.7693 +vn 0.9139 -0.1931 0.3570 +vn 0.7566 -0.1611 0.6338 +vn 0.6899 -0.2765 0.6690 +vn 0.8780 -0.1911 0.4388 +vn -0.3127 0.6209 -0.7188 +vn -0.5192 0.7232 -0.4554 +vn 0.7874 0.5654 0.2455 +vn 0.8294 0.5552 0.0621 +vn 0.5820 -0.7999 0.1464 +vn 0.5501 -0.7865 0.2807 +vn -0.1955 -0.9687 0.1528 +vn 0.3381 -0.8189 -0.4638 +vn 0.8351 0.5105 -0.2048 +vn 0.8009 0.4602 -0.3831 +vn -0.5327 0.8284 0.1731 +vn -0.3381 0.8189 0.4638 +vn -0.2013 -0.9682 0.1489 +vn -0.1107 -0.7386 -0.6650 +vn -0.2067 -0.9665 0.1524 +vn -0.5745 -0.6371 -0.5139 +vn -0.5501 0.7865 -0.2807 +vn -0.2068 -0.9656 0.1579 +vn -0.7874 -0.5654 -0.2455 +vn 0.8554 0.5135 -0.0676 +vn 0.5999 0.4391 -0.6688 +vn 0.1107 0.7386 0.6650 +vn -0.8294 -0.5552 -0.0621 +vn -0.8554 -0.5135 0.0675 +vn 0.5745 0.6371 0.5139 +vn -0.1435 -0.4827 0.8640 +vn 0.3127 -0.6209 0.7188 +vn -0.5820 0.7999 -0.1463 +vn -0.8554 -0.5135 0.0677 +vn 0.8009 0.4602 -0.3830 +vn 0.5326 -0.8284 -0.1732 +vn 0.3380 -0.8189 -0.4639 +vn 0.5193 -0.7232 0.4553 +vn -0.5559 0.8312 -0.0139 +vn -0.8351 -0.5105 0.2048 +vn -0.8009 -0.4602 0.3832 +vn 0.1436 0.4827 -0.8639 +vn -0.1108 -0.7386 -0.6650 +vn -0.3380 0.8189 0.4639 +vn -0.5999 -0.4391 0.6688 +vn -0.7874 -0.5654 -0.2456 +vn 0.5558 -0.8312 0.0138 +vn 0.3126 -0.6209 0.7188 +vn 0.8554 0.5135 -0.0675 +vn 0.3381 -0.8189 -0.4639 +vn -0.3126 0.6209 -0.7189 +vn 0.5192 -0.7232 0.4554 +vn -0.5559 0.8312 -0.0138 +vn -0.1436 -0.4827 0.8639 +vn 0.1435 0.4827 -0.8639 +vn -0.8009 -0.4602 0.3831 +vn 0.9156 -0.2299 -0.3299 +vn 0.9820 -0.1816 0.0515 +vn 0.7102 -0.2411 -0.6614 +vn 0.3971 -0.2136 -0.8926 +vn 0.0240 -0.1515 -0.9882 +vn -0.3524 -0.0643 -0.9337 +vn -0.6746 0.0347 -0.7373 +vn -0.8938 0.1306 -0.4291 +vn -0.9764 0.2086 -0.0559 +vn -0.9100 0.2569 0.3255 +vn -0.7046 0.2681 0.6570 +vn -0.3915 0.2406 0.8882 +vn -0.0184 0.1785 0.9838 +vn 0.3580 0.0913 0.9293 +vn 0.6802 -0.0078 0.7330 +vn 0.8994 -0.1036 0.4247 +vn 0.6802 -0.0078 0.7329 +vn 0.9983 -0.0499 0.0298 +vn 0.9834 -0.1743 0.0503 +vn 0.9008 -0.0963 0.4235 +vn 0.9166 0.0273 0.3989 +vn 0.9841 -0.1703 0.0496 +vn 0.9015 -0.0923 0.4228 +vn 0.9845 -0.1681 0.0493 +vn 0.9019 -0.0902 0.4224 +vn 0.9845 -0.1682 0.0493 +vn 0.6817 -0.0005 0.7316 +vn 0.6998 0.1221 0.7038 +vn 0.6824 0.0035 0.7310 +vn 0.6828 0.0056 0.7305 +vn 0.6824 0.0035 0.7309 +vn 0.3595 0.0986 0.9279 +vn 0.3811 0.2201 0.8980 +vn 0.6824 0.0034 0.7310 +vn 0.3602 0.1025 0.9272 +vn 0.3607 0.1047 0.9268 +vn 0.6828 0.0056 0.7306 +vn -0.0168 0.1858 0.9824 +vn 0.0088 0.3063 0.9519 +vn -0.0160 0.1897 0.9817 +vn -0.0156 0.1919 0.9813 +vn -0.3899 0.2479 0.8869 +vn -0.3602 0.3677 0.8573 +vn -0.3891 0.2518 0.8861 +vn -0.3886 0.2539 0.8857 +vn -0.7029 0.2754 0.6558 +vn -0.6699 0.3949 0.6287 +vn -0.7021 0.2793 0.6550 +vn -0.7016 0.2814 0.6547 +vn -0.7030 0.2754 0.6557 +vn -0.9083 0.2642 0.3243 +vn -0.8730 0.3838 0.3008 +vn -0.9074 0.2680 0.3236 +vn -0.9069 0.2702 0.3233 +vn -0.9074 0.2681 0.3236 +vn -0.7016 0.2814 0.6546 +vn -0.9069 0.2702 0.3232 +vn -0.9748 0.2159 -0.0571 +vn -0.9387 0.3360 -0.0764 +vn -0.9738 0.2197 -0.0577 +vn -0.9733 0.2219 -0.0580 +vn -0.9738 0.2198 -0.0577 +vn -0.8921 0.1379 -0.4302 +vn -0.8570 0.2589 -0.4456 +vn -0.8912 0.1418 -0.4308 +vn -0.8907 0.1439 -0.4312 +vn -0.6730 0.0420 -0.7384 +vn -0.6403 0.1641 -0.7504 +vn -0.6721 0.0459 -0.7390 +vn -0.6717 0.0481 -0.7393 +vn -0.6722 0.0460 -0.7390 +vn -0.3508 -0.0570 -0.9347 +vn -0.3215 0.0661 -0.9446 +vn -0.3499 -0.0531 -0.9353 +vn -0.3495 -0.0509 -0.9356 +vn -0.6721 0.0460 -0.7390 +vn -0.6716 0.0481 -0.7393 +vn 0.0255 -0.1442 -0.9892 +vn 0.0507 -0.0201 -0.9985 +vn 0.0263 -0.1403 -0.9898 +vn 0.0268 -0.1381 -0.9901 +vn 0.3986 -0.2063 -0.8936 +vn 0.4198 -0.0816 -0.9040 +vn 0.3993 -0.2024 -0.8942 +vn 0.3998 -0.2002 -0.8945 +vn 0.3993 -0.2023 -0.8942 +vn 0.7116 -0.2338 -0.6625 +vn 0.7294 -0.1088 -0.6753 +vn 0.7124 -0.2299 -0.6631 +vn 0.7128 -0.2277 -0.6634 +vn 0.7124 -0.2298 -0.6631 +vn 0.9170 -0.2226 -0.3311 +vn 0.9326 -0.0976 -0.3474 +vn 0.9177 -0.2186 -0.3317 +vn 0.9181 -0.2164 -0.3320 +vn 0.6878 0.6531 -0.3168 +vn -0.3486 0.8596 -0.3736 +vn -0.2403 0.9383 0.2486 +vn -0.9294 0.0731 -0.3618 +vn -0.4673 -0.0466 -0.8829 +vn -0.9127 0.1267 -0.3884 +vn 0.9713 -0.1761 0.1601 +vn -0.9713 0.1761 -0.1601 +vn -0.0465 0.0414 0.9981 +vn -0.0849 -0.1534 0.9845 +vn -0.0464 0.0414 0.9981 +vn -0.8228 0.1536 0.5472 +vn -0.8091 0.0201 0.5873 +vn 0.4554 -0.2878 -0.8425 +vn -0.9504 0.1783 0.2548 +vn -0.9251 0.1672 0.3410 +vn 0.9223 -0.2947 -0.2502 +vn 0.9305 -0.2389 -0.2777 +vn -0.9759 0.2118 0.0533 +vn 0.9759 -0.2118 -0.0533 +vn -0.9793 0.1951 -0.0537 +vn 0.9793 -0.1951 0.0537 +vn -0.8257 -0.5591 0.0756 +vn -0.8186 -0.5744 0.0027 +vn 0.5318 -0.8434 0.0765 +vn -0.8217 -0.5497 0.1503 +vn 0.4442 -0.8955 -0.0293 +vn -0.7581 -0.5940 0.2692 +vn 0.1285 -0.9734 -0.1899 +vn -0.8228 0.1535 0.5472 +vn -0.0465 0.0413 0.9981 +vn -0.4681 -0.8529 -0.2312 +vn -0.4305 -0.1109 -0.8958 +vn -0.4682 -0.8529 -0.2312 +vn 0.4407 -0.8328 0.3349 +vn 0.2726 -0.8484 0.4538 +vn 0.7952 0.6006 -0.0834 +vn 0.7409 0.6518 0.1619 +vn 0.5969 0.7148 0.3644 +vn 0.3852 0.7799 0.4934 +vn 0.1377 0.8372 0.5293 +vn -0.1075 0.8780 0.4664 +vn -0.3132 0.8961 0.3145 +vn -0.4482 0.8887 0.0967 +vn -0.4919 0.8569 -0.1540 +vn -0.4375 0.8057 -0.3993 +vn -0.2935 0.7427 -0.6019 +vn -0.0817 0.6776 -0.7309 +vn 0.1656 0.6203 -0.7667 +vn 0.4108 0.5795 -0.7039 +vn 0.7516 0.5688 -0.3341 +vn -0.5968 0.7892 -0.1449 +vn 0.7409 0.6518 0.1620 +vn 0.7952 0.6005 -0.0834 +vn 0.8647 0.4981 -0.0646 +vn 0.8031 0.5562 0.2138 +vn -0.4374 0.8056 -0.3995 +vn -0.5352 0.7310 -0.4233 +vn -0.2935 0.7427 -0.6018 +vn 0.3991 0.7016 0.5903 +vn -0.0816 0.6776 -0.7309 +vn 0.1376 0.8372 0.5293 +vn 0.1181 0.7668 0.6310 +vn 0.1657 0.6203 -0.7667 +vn -0.1074 0.8780 0.4665 +vn -0.1603 0.8131 0.5596 +vn -0.3132 0.8961 0.3146 +vn 0.6165 0.5614 -0.5520 +vn -0.6611 -0.0002 0.7503 +vn -0.5645 -0.2341 0.7915 +vn -0.6595 0.2528 0.7079 +vn -0.6277 0.0035 -0.7785 +vn -0.3965 0.5032 -0.7679 +vn -0.6036 0.3007 -0.7384 +vn -0.6317 0.5205 0.5745 +vn -0.4247 0.7229 0.5450 +vn 0.1551 -0.8321 -0.5325 +vn 0.4246 -0.7229 -0.5450 +vn 0.3964 -0.5032 0.7679 +vn 0.1268 -0.6123 0.7804 +vn -0.1268 0.6123 -0.7804 +vn -0.3964 0.5032 -0.7679 +vn -0.4246 0.7229 0.5450 +vn -0.1550 0.8321 0.5325 +vn -0.1362 -0.8313 -0.5389 +vn -0.1642 -0.6116 0.7740 +vn 0.1643 0.6115 -0.7740 +vn 0.1360 0.8313 0.5389 +vn -0.4042 -0.7208 -0.5632 +vn -0.4325 -0.5009 0.7497 +vn 0.4324 0.5009 -0.7497 +vn 0.4043 0.7207 0.5632 +vn -0.6088 -0.5171 -0.6017 +vn -0.6370 -0.2973 0.7112 +vn 0.6370 0.2973 -0.7112 +vn 0.6088 0.5171 0.6017 +vn -0.7185 -0.2514 -0.6485 +vn -0.6088 -0.5170 -0.6017 +vn -0.7467 -0.0317 0.6644 +vn 0.7467 0.0317 -0.6644 +vn 0.6088 0.5170 0.6017 +vn 0.7185 0.2514 0.6485 +vn -0.7167 0.0356 -0.6965 +vn -0.7448 0.2556 0.6164 +vn 0.6318 -0.5204 -0.5745 +vn 0.7448 -0.2555 -0.6164 +vn 0.7166 -0.0359 0.6965 +vn 0.6036 -0.3007 0.7384 +vn 0.4247 -0.7229 -0.5450 +vn 0.3965 -0.5032 0.7679 +vn 0.6318 -0.5204 -0.5744 +vn 0.4246 -0.7230 -0.5450 +vn 0.1550 -0.8321 -0.5325 +vn -0.1361 -0.8313 -0.5389 +vn -0.4042 -0.7207 -0.5632 +vn -0.7167 0.0357 -0.6965 +vn -0.6036 0.3006 -0.7384 +vn 0.7167 -0.0357 0.6965 +vn -0.1643 -0.6115 0.7740 +vn -0.4324 -0.5009 0.7497 +vn -0.6370 -0.2974 0.7112 +vn -0.7449 0.2554 0.6164 +vn -0.6318 0.5204 0.5744 +vn 0.4042 0.7207 0.5632 +vn -0.1162 -0.7598 -0.6397 +vn 0.1402 -0.7604 -0.6341 +vn 0.5279 -0.2373 0.8155 +vn 0.6596 -0.2523 -0.7080 +vn 0.6292 0.2490 0.7363 +vn 0.6611 0.0005 -0.7503 +vn 0.3526 0.6622 0.6611 +vn 0.3843 0.4136 -0.8254 +vn -0.1399 0.7605 0.6341 +vn -0.1083 0.5116 -0.8524 +vn -0.5279 0.2373 -0.8155 +vn -0.9819 0.1823 -0.0516 +vn -0.9740 0.1621 -0.1585 +vn -0.8313 -0.5558 -0.0017 +vn -0.8361 -0.5437 0.0730 +vn 0.9766 -0.2078 0.0558 +vn 0.9682 -0.1898 0.1630 +vn 0.5477 -0.8062 0.2236 +vn 0.5522 -0.8203 0.1491 +vn 0.9728 -0.2257 -0.0518 +vn 0.5510 -0.8312 0.0741 +vn -0.9786 0.1981 0.0563 +vn -0.8345 -0.5308 0.1479 +vn 0.9307 -0.2574 -0.2597 +vn 0.5411 -0.8375 -0.0756 +vn -0.9391 0.2174 0.2662 +vn -0.8184 -0.4946 0.2926 +vn 0.8137 -0.2833 -0.5076 +vn 0.4460 -0.8597 -0.2490 +vn -0.8258 0.2249 0.5171 +vn -0.7286 -0.4980 0.4702 +vn 0.0109 -0.2140 -0.9768 +vn -0.1059 -0.7199 -0.6859 +vn -0.0313 0.1157 0.9928 +vn -0.1395 -0.4582 0.8779 +vn -0.8019 0.0385 -0.5962 +vn -0.1054 -0.7199 -0.6860 +vn -0.7116 -0.6291 -0.3127 +vn 0.7898 -0.0970 0.6057 +vn -0.1390 -0.4582 0.8779 +vn 0.4293 -0.7287 0.5336 +vn -0.9256 0.1124 -0.3614 +vn -0.8089 -0.5686 -0.1495 +vn 0.9173 -0.1524 0.3680 +vn 0.5316 -0.7635 0.3666 +vn 0.9356 -0.2332 -0.2650 +vn 0.9328 -0.2342 -0.2740 +vn -0.9018 0.3042 0.3071 +vn -0.8853 0.2610 0.3848 +vn 0.7805 -0.1943 -0.5942 +vn 0.6429 -0.1887 -0.7424 +vn -0.7368 0.4304 0.5215 +vn -0.7406 0.2011 0.6411 +vn -0.7406 0.2012 0.6411 +vn -0.9251 0.1672 0.3409 +vn 0.0462 -0.0362 -0.9983 +vn 0.0336 0.4195 0.9071 +vn -0.0401 0.0592 0.9974 +vn -0.7264 0.1107 -0.6782 +vn -0.5754 0.0595 -0.8157 +vn 0.0336 0.4196 0.9071 +vn 0.7863 0.1250 0.6050 +vn 0.6913 -0.0842 0.7177 +vn -0.7265 0.1107 -0.6782 +vn -0.9189 0.1385 -0.3695 +vn -0.9138 0.1351 -0.3829 +vn 0.9121 -0.0582 0.4059 +vn 0.8730 -0.0895 0.4794 +vn 0.4462 -0.8595 -0.2493 +vn -0.7116 -0.6291 -0.3128 +vn -0.1055 -0.7197 -0.6863 +vn 0.5412 -0.8375 -0.0756 +vn -0.8089 -0.5687 -0.1495 +vn 0.5521 -0.8203 0.1491 +vn 0.5478 -0.8062 0.2236 +vn -0.8184 -0.4945 0.2926 +vn 0.4292 -0.7288 0.5335 +vn -0.7287 -0.4980 0.4701 +vn -0.1394 -0.4588 0.8775 +vn -0.1310 0.5855 -0.8000 +vn 0.1497 0.5204 -0.8407 +vn -0.3716 0.6594 -0.6535 +vn 0.8647 0.4980 -0.0647 +vn 0.8031 0.5562 0.2137 +vn 0.3990 0.7018 0.5902 +usemtl Scene_-_Root +s off +f 19368/19332/13816 19369/19333/13817 19370/19334/13818 +f 19368/19332/13819 19370/19334/13820 19371/19335/13820 +f 19384/19336/13821 19385/19337/13822 19386/19338/13823 +f 19384/19336/13821 19386/19338/13818 19387/19339/13818 +f 19388/19340/13824 19389/19341/13825 19390/19342/13826 +f 19388/19340/13824 19390/19342/13826 19391/19343/13826 +f 19392/19344/13827 19393/19345/13828 19394/19346/13829 +f 19392/19344/13830 19394/19346/13829 19395/19347/13829 +f 19396/19348/13831 19397/19349/13832 19398/19350/13818 +f 19396/19348/13833 19398/19350/13823 19399/19351/13823 +f 19400/19352/13834 19401/19353/13835 19402/19354/13818 +f 19400/19352/13834 19402/19354/13818 19403/19355/13818 +f 19404/19356/13836 19392/19344/13837 19395/19347/13829 +f 19404/19356/13836 19395/19347/13829 19405/19357/13829 +f 19406/19358/13838 19404/19356/13836 19405/19357/13829 +f 19406/19358/13839 19405/19357/13829 19407/19359/13829 +f 19369/19333/13840 19408/19360/13841 19409/19361/13842 +f 19369/19333/13843 19409/19361/13818 19370/19334/13818 +f 19385/19337/13822 19410/19362/13844 19411/19363/13823 +f 19385/19337/13822 19411/19363/13823 19386/19338/13823 +f 19412/19364/13845 19406/19358/13838 19407/19359/13829 +f 19412/19364/13846 19407/19359/13829 19413/19365/13829 +f 19397/19349/13832 19414/19366/13847 19415/19367/13818 +f 19397/19349/13832 19415/19367/13818 19398/19350/13818 +f 19401/19353/13848 19416/19368/13849 19417/19369/13818 +f 19401/19353/13835 19417/19369/13818 19402/19354/13818 +f 19418/19370/13850 19412/19364/13851 19413/19365/13829 +f 19418/19370/13850 19413/19365/13829 19419/19371/13829 +f 19420/19372/13852 19418/19370/13850 19419/19371/13829 +f 19420/19372/13853 19419/19371/13826 19421/19373/13826 +f 19408/19360/13841 19422/19374/13854 19423/19375/13818 +f 19408/19360/13855 19423/19375/13818 19409/19361/13818 +f 19393/19345/13856 19521/19376/13857 19522/19377/13829 +f 19393/19345/13856 19522/19377/13829 19394/19346/13829 +f 19389/19341/13825 19523/19378/13858 19524/19379/13826 +f 19389/19341/13825 19524/19379/13826 19390/19342/13826 +f 19521/19376/13859 19388/19340/13824 19391/19343/13826 +f 19521/19376/13857 19391/19343/13829 19522/19377/13829 +f 19525/19380/13860 19400/19352/13861 19403/19355/13818 +f 19525/19380/13860 19403/19355/13818 19511/19381/13818 +f 19523/19378/13858 19526/19382/13862 19519/19383/13829 +f 19523/19378/13858 19519/19383/13826 19524/19379/13826 +f 19526/19382/13863 19527/19384/13864 19516/19385/13826 +f 19526/19382/13865 19516/19385/13829 19519/19383/13829 +f 19528/19386/13866 19384/19336/13867 19387/19339/13818 +f 19528/19386/13866 19387/19339/13818 19529/19387/13818 +f 19530/19388/13868 19368/19332/13869 19371/19335/13870 +f 19530/19388/13871 19371/19335/13818 19496/19389/13818 +f 19527/19384/13864 19531/19390/13872 19513/19391/13829 +f 19527/19384/13864 19513/19391/13829 19516/19385/13829 +f 19422/19374/13873 19525/19380/13860 19511/19381/13818 +f 19422/19374/13854 19511/19381/13818 19423/19375/13818 +f 19531/19390/13874 19532/19392/13875 19509/19393/13876 +f 19531/19390/13872 19509/19393/13829 19513/19391/13829 +f 19532/19392/13877 19533/19394/13878 19506/19395/13829 +f 19532/19392/13877 19506/19395/13829 19509/19393/13829 +f 19416/19368/13879 19528/19386/13866 19529/19387/13842 +f 19416/19368/13880 19529/19387/13818 19417/19369/13818 +f 19414/19366/13847 19530/19388/13871 19496/19389/13818 +f 19414/19366/13847 19496/19389/13818 19415/19367/13818 +f 19410/19362/13844 19396/19348/13833 19399/19351/13823 +f 19410/19362/13844 19399/19351/13823 19411/19363/13823 +f 19533/19394/13878 19420/19372/13853 19421/19373/13826 +f 19533/19394/13878 19421/19373/13829 19506/19395/13829 +f 19862/19396/13881 19863/19397/13882 19864/19398/13882 +f 19863/19397/13882 19871/19399/13883 19864/19398/13882 +f 19896/19400/13884 19870/19401/13885 19863/19397/13886 +f 19902/19402/13887 19896/19400/13884 19863/19397/13886 +f 19909/19403/13888 19910/19404/13889 19690/19405/13818 +f 19909/19403/13890 19690/19405/13818 19630/19406/13818 +f 19910/19404/13889 19911/19407/13891 19688/19408/13818 +f 19910/19404/13892 19688/19408/13818 19690/19405/13818 +f 19911/19407/13891 19912/19409/13893 19684/19410/13818 +f 19911/19407/13891 19684/19410/13818 19688/19408/13818 +f 19912/19409/13893 19913/19411/13894 19678/19412/13818 +f 19912/19409/13895 19678/19412/13818 19684/19410/13818 +f 19913/19411/13896 19914/19413/13897 19676/19414/13823 +f 19913/19411/13894 19676/19414/13818 19678/19412/13818 +f 19914/19413/13898 19915/19415/13899 19672/19416/13818 +f 19914/19413/13898 19672/19416/13818 19676/19414/13818 +f 19916/19417/13900 19917/19418/13901 19376/19419/13818 +f 19916/19417/13900 19376/19419/13818 19601/19420/13818 +f 19915/19415/13899 19918/19421/13902 19600/19422/13818 +f 19915/19415/13899 19600/19422/13818 19672/19416/13818 +f 19919/19423/13903 19909/19403/13890 19630/19406/13818 +f 19919/19423/13904 19630/19406/13818 19628/19424/13818 +f 19920/19425/13905 19919/19423/13906 19628/19424/13818 +f 19918/19421/13902 19916/19417/13900 19601/19420/13818 +f 19918/19421/13902 19601/19420/13818 19600/19422/13818 +f 19917/19418/13907 19377/19426/13908 19376/19419/13818 +f 19925/19427/13909 19926/19428/13910 19618/19429/13829 +f 19925/19427/13911 19618/19429/13826 19686/19430/13826 +f 19927/19431/13912 19928/19432/13913 19624/19433/13829 +f 19927/19431/13912 19624/19433/13829 19682/19434/13829 +f 19929/19435/13914 19930/19436/13915 19626/19437/13829 +f 19929/19435/13916 19626/19437/13829 19680/19438/13829 +f 19931/19439/13917 19925/19427/13911 19686/19430/13826 +f 19931/19439/13917 19686/19430/13829 19674/19440/13829 +f 19932/19441/13918 19927/19431/13912 19682/19434/13829 +f 19932/19441/13918 19682/19434/13829 19593/19442/13829 +f 19933/19443/13919 19929/19435/13916 19680/19438/13829 +f 19933/19443/13919 19680/19438/13829 19597/19444/13829 +f 19934/19445/13920 19935/19446/13921 19622/19447/13826 +f 19934/19445/13922 19622/19447/13829 19607/19448/13829 +f 19936/19449/13923 19931/19439/13924 19674/19440/13829 +f 19936/19449/13923 19674/19440/13829 19611/19450/13829 +f 19930/19436/13925 19937/19451/13926 19610/19452/13829 +f 19930/19436/13915 19610/19452/13829 19626/19437/13829 +f 19928/19432/13913 19938/19453/13927 19606/19454/13829 +f 19928/19432/13913 19606/19454/13829 19624/19433/13829 +f 19935/19446/13928 19939/19455/13929 19596/19456/13829 +f 19935/19446/13921 19596/19456/13829 19622/19447/13829 +f 19926/19428/13930 19940/19457/13931 19592/19458/13826 +f 19926/19428/13910 19592/19458/13829 19618/19429/13829 +f 19937/19451/13926 19936/19449/13923 19611/19450/13829 +f 19937/19451/13926 19611/19450/13829 19610/19452/13829 +f 19938/19453/13932 19934/19445/13920 19607/19448/13829 +f 19938/19453/13933 19607/19448/13829 19606/19454/13829 +f 19939/19455/13929 19933/19443/13919 19597/19444/13829 +f 19939/19455/13929 19597/19444/13829 19596/19456/13829 +f 19940/19457/13931 19932/19441/13918 19593/19442/13829 +f 19940/19457/13931 19593/19442/13829 19592/19458/13829 +f 20103/19459/13934 20104/19460/13935 20040/19461/13886 +f 20103/19459/13934 20040/19461/13886 20039/19462/13886 +f 20105/19463/13936 20103/19459/13934 20039/19462/13886 +f 20105/19463/13937 20039/19462/13886 20043/19464/13886 +f 20106/19465/13938 20105/19463/13937 20043/19464/13886 +f 20106/19465/13938 20043/19464/13886 20045/19466/13886 +f 20107/19467/13939 20106/19465/13940 20045/19466/13886 +f 20107/19467/13941 20045/19466/13886 20047/19468/13886 +f 20108/19469/13942 20107/19467/13943 20047/19468/13944 +f 20108/19469/13942 20047/19468/13886 20049/19470/13886 +f 20109/19471/13945 20108/19469/13946 20049/19470/13886 +f 20109/19471/13947 20049/19470/13886 20051/19472/13886 +f 20110/19473/13948 20109/19471/13947 20051/19472/13886 +f 20110/19473/13949 20051/19472/13886 20053/19474/13886 +f 20111/19475/13950 20110/19473/13948 20053/19474/13886 +f 20111/19475/13951 20053/19474/13886 20055/19476/13886 +f 20112/19477/13952 20111/19475/13951 20055/19476/13882 +f 20112/19477/13952 20055/19476/13886 20057/19478/13886 +f 20113/19479/13953 20112/19477/13952 20057/19478/13886 +f 20113/19479/13953 20057/19478/13886 20059/19480/13886 +f 20114/19481/13954 20113/19479/13953 20059/19480/13886 +f 20114/19481/13955 20059/19480/13886 20061/19482/13886 +f 20115/19483/13956 20114/19481/13954 20061/19482/13882 +f 20115/19483/13956 20061/19482/13886 20063/19484/13886 +f 20116/19485/13957 20115/19483/13956 20063/19484/13882 +f 20116/19485/13958 20063/19484/13886 20065/19486/13886 +f 20117/19487/13959 20116/19485/13958 20065/19486/13886 +f 20117/19487/13959 20065/19486/13886 20067/19488/13886 +f 20118/19489/13960 20117/19487/13961 20067/19488/13886 +f 20118/19489/13962 20067/19488/13886 20069/19490/13886 +f 20104/19460/13963 20118/19489/13964 20069/19490/13882 +f 20104/19460/13963 20069/19490/13886 20040/19461/13886 +f 20119/19491/13965 20120/19492/13966 20072/19493/13967 +f 20119/19491/13965 20072/19493/13967 20071/19494/13967 +f 20120/19492/13966 20121/19495/13968 20075/19496/13967 +f 20120/19492/13969 20075/19496/13967 20072/19493/13967 +f 20121/19495/13968 20122/19497/13970 20077/19498/13967 +f 20121/19495/13968 20077/19498/13967 20075/19496/13967 +f 20122/19497/13971 20123/19499/13972 20079/19500/13973 +f 20122/19497/13971 20079/19500/13967 20077/19498/13967 +f 20123/19499/13974 20124/19501/13975 20081/19502/13967 +f 20123/19499/13972 20081/19502/13967 20079/19500/13967 +f 20124/19501/13976 20125/19503/13977 20083/19504/13973 +f 20124/19501/13978 20083/19504/13967 20081/19502/13967 +f 20125/19503/13977 20126/19505/13979 20085/19506/13967 +f 20125/19503/13977 20085/19506/13967 20083/19504/13967 +f 20126/19505/13979 20127/19507/13980 20087/19508/13967 +f 20126/19505/13979 20087/19508/13967 20085/19506/13967 +f 20127/19507/13981 20128/19509/13982 20089/19510/13973 +f 20127/19507/13980 20089/19510/13967 20087/19508/13967 +f 20128/19509/13982 20129/19511/13983 20091/19512/13967 +f 20128/19509/13984 20091/19512/13967 20089/19510/13967 +f 20129/19511/13983 20130/19513/13985 20093/19514/13967 +f 20129/19511/13983 20093/19514/13973 20091/19512/13973 +f 20130/19513/13985 20131/19515/13986 20095/19516/13967 +f 20130/19513/13987 20095/19516/13967 20093/19514/13967 +f 20131/19515/13986 20132/19517/13988 20097/19518/13967 +f 20131/19515/13986 20097/19518/13967 20095/19516/13967 +f 20132/19517/13988 20133/19519/13989 20099/19520/13973 +f 20132/19517/13988 20099/19520/13967 20097/19518/13967 +f 20133/19519/13989 20134/19521/13990 20101/19522/13967 +f 20133/19519/13989 20101/19522/13967 20099/19520/13967 +f 20134/19521/13990 20119/19491/13965 20071/19494/13973 +f 20134/19521/13990 20071/19494/13967 20101/19522/13967 +f 20232/19523/13991 20231/19524/13992 19864/19398/13886 +f 20231/19524/13992 19865/19525/13993 19864/19398/13886 +s 1 +f 19332/19526/13994 19333/19527/13995 19334/19528/13844 +f 19332/19526/13994 19334/19528/13844 19335/19529/13996 +f 19335/19529/13996 19334/19528/13844 19336/19530/13822 +f 19335/19529/13996 19336/19530/13822 19337/19531/13997 +f 19338/19532/13997 19339/19533/13822 19340/19534/13998 +f 19338/19532/13997 19340/19534/13998 19341/19535/13999 +f 19341/19535/13999 19340/19534/13998 19342/19536/13866 +f 19341/19535/13999 19342/19536/13866 19343/19537/14000 +f 19343/19537/14000 19342/19536/13866 19344/19538/14001 +f 19343/19537/14000 19344/19538/14001 19345/19539/14002 +f 19345/19539/14002 19344/19538/14001 19346/19540/13848 +f 19345/19539/14002 19346/19540/13848 19347/19541/14003 +f 19348/19542/14003 19349/19543/13848 19350/19544/13834 +f 19348/19542/14003 19350/19544/13834 19351/19545/14004 +f 19351/19545/14004 19350/19544/13834 19352/19546/14005 +f 19351/19545/14004 19352/19546/14005 19353/19547/14006 +f 19353/19547/14006 19352/19546/14005 19354/19548/13873 +f 19353/19547/14006 19354/19548/13873 19355/19549/14007 +f 19355/19549/14007 19354/19548/13873 19356/19550/14008 +f 19355/19549/14007 19356/19550/14008 19357/19551/14009 +f 19358/19552/14009 19359/19553/13855 19360/19554/13817 +f 19358/19552/14009 19360/19554/13817 19361/19555/14010 +f 19361/19555/14010 19360/19554/13817 19362/19556/14011 +f 19361/19555/14010 19362/19556/14011 19363/19557/14012 +f 19363/19557/14012 19362/19556/14011 19364/19558/14013 +f 19363/19557/14012 19364/19558/14013 19365/19559/14014 +f 19365/19559/14014 19364/19558/14013 19366/19560/13847 +f 19365/19559/14014 19366/19560/13847 19367/19561/14015 +f 19372/19562/14016 19373/19563/13847 19374/19564/14017 +f 19372/19562/14016 19374/19564/14017 19375/19565/14018 +f 19375/19565/14018 19374/19564/14017 19333/19527/13995 +f 19375/19565/14018 19333/19527/13995 19332/19526/13994 +f 19376/19419/13818 19377/19426/13908 19378/19566/14019 +f 19376/19419/13818 19378/19566/14019 19379/19567/14020 +f 19380/19568/13872 19381/19569/13864 19382/19570/14021 +f 19380/19568/13872 19382/19570/14021 19383/19571/14022 +f 19424/19572/14023 19425/19573/14024 19426/19574/14025 +f 19424/19572/14023 19426/19574/14025 19427/19575/14026 +f 19428/19576/13837 19429/19577/14027 19430/19578/14028 +f 19428/19576/13837 19430/19578/14028 19431/19579/14029 +f 19432/19580/13877 19380/19568/13872 19383/19571/14022 +f 19432/19580/13877 19383/19571/14022 19433/19581/14030 +f 19434/19582/14031 19428/19576/13837 19431/19579/14029 +f 19434/19582/14031 19431/19579/14029 19435/19583/14032 +f 19436/19584/13878 19437/19585/13877 19438/19586/14030 +f 19436/19584/13878 19438/19586/14030 19439/19587/14033 +f 19440/19588/13859 19441/19589/14034 19442/19590/14032 +f 19440/19588/13859 19442/19590/14032 19443/19591/14035 +f 19444/19592/14036 19436/19584/13878 19439/19587/14033 +f 19444/19592/14036 19439/19587/14033 19445/19593/14037 +f 19446/19594/13825 19447/19595/13824 19448/19596/14038 +f 19446/19594/13825 19448/19596/14038 19449/19597/14039 +f 19447/19595/13824 19440/19588/13859 19443/19591/14035 +f 19447/19595/13824 19443/19591/14035 19448/19596/14038 +f 19450/19598/14040 19444/19592/14036 19445/19593/14037 +f 19450/19598/14040 19445/19593/14037 19451/19599/14024 +f 19452/19600/13858 19446/19594/13825 19449/19597/14039 +f 19452/19600/13858 19449/19597/14039 19453/19601/14041 +f 19454/19602/13851 19450/19598/14040 19451/19599/14024 +f 19454/19602/13851 19451/19599/14024 19455/19603/14023 +f 19456/19604/13862 19457/19605/14042 19458/19606/14041 +f 19456/19604/13862 19458/19606/14041 19459/19607/14043 +f 19460/19608/13839 19461/19609/13846 19462/19610/14023 +f 19460/19608/13839 19462/19610/14023 19463/19611/14044 +f 19381/19569/13864 19456/19604/13862 19459/19607/14043 +f 19381/19569/13864 19459/19607/14043 19382/19570/14021 +f 19429/19577/14027 19460/19608/13839 19463/19611/14044 +f 19429/19577/14027 19463/19611/14044 19430/19578/14028 +f 19464/19612/14045 19465/19613/14046 19466/19614/14047 +f 19464/19612/14045 19466/19614/14047 19467/19615/14048 +f 19468/19616/14043 19469/19617/14041 19470/19618/14049 +f 19468/19616/14043 19470/19618/14049 19471/19619/14050 +f 19472/19620/14044 19424/19572/14023 19427/19575/14026 +f 19472/19620/14044 19427/19575/14026 19473/19621/14051 +f 19474/19622/14052 19468/19616/14043 19471/19619/14050 +f 19474/19622/14052 19471/19619/14050 19475/19623/14053 +f 19476/19624/14028 19472/19620/14044 19473/19621/14051 +f 19476/19624/14028 19473/19621/14051 19477/19625/14054 +f 19478/19626/14022 19474/19622/14052 19475/19623/14053 +f 19478/19626/14022 19475/19623/14053 19479/19627/14055 +f 19480/19628/14029 19476/19624/14028 19477/19625/14054 +f 19480/19628/14029 19477/19625/14054 19481/19629/14056 +f 19482/19630/14030 19478/19626/14022 19479/19627/14055 +f 19482/19630/14030 19479/19627/14055 19483/19631/14057 +f 19484/19632/14032 19480/19628/14029 19481/19629/14056 +f 19484/19632/14032 19481/19629/14056 19485/19633/14058 +f 19486/19634/14033 19482/19630/14030 19483/19631/14057 +f 19486/19634/14033 19483/19631/14057 19487/19635/14059 +f 19488/19636/14035 19484/19632/14032 19485/19633/14058 +f 19488/19636/14035 19485/19633/14058 19489/19637/14060 +f 19490/19638/14061 19486/19634/14033 19487/19635/14059 +f 19490/19638/14061 19487/19635/14059 19491/19639/14062 +f 19492/19640/14039 19493/19641/14038 19494/19642/14063 +f 19492/19640/14039 19494/19642/14063 19495/19643/14064 +f 19493/19641/14038 19488/19636/14035 19489/19637/14060 +f 19493/19641/14038 19489/19637/14060 19494/19642/14063 +f 19425/19573/14024 19490/19638/14061 19491/19639/14062 +f 19425/19573/14024 19491/19639/14062 19426/19574/14025 +f 19469/19617/14041 19492/19640/14039 19495/19643/14064 +f 19469/19617/14041 19495/19643/14064 19470/19618/14049 +f 19415/19367/13823 19496/19389/13818 19497/19644/14065 +f 19415/19367/13823 19497/19644/14065 19498/19645/14066 +f 19413/19365/13829 19407/19359/13829 19499/19646/14067 +f 19413/19365/13829 19499/19646/14067 19500/19647/14068 +f 19496/19389/13818 19371/19335/13818 19501/19648/14069 +f 19496/19389/13818 19501/19648/14069 19497/19644/14065 +f 19419/19371/13829 19413/19365/13829 19500/19647/14068 +f 19419/19371/13829 19500/19647/14068 19502/19649/14070 +f 19371/19335/13818 19370/19334/13818 19503/19650/14071 +f 19371/19335/13818 19503/19650/14071 19501/19648/14069 +f 19421/19373/13829 19419/19371/13829 19502/19649/14070 +f 19421/19373/13829 19502/19649/14070 19504/19651/14072 +f 19370/19334/13818 19409/19361/13818 19505/19652/14073 +f 19370/19334/13818 19505/19652/14073 19503/19650/14071 +f 19506/19395/13829 19421/19373/13829 19504/19651/14072 +f 19506/19395/13829 19504/19651/14072 19507/19653/14074 +f 19409/19361/13818 19423/19375/13818 19508/19654/14075 +f 19409/19361/13818 19508/19654/14075 19505/19652/14073 +f 19509/19393/13826 19506/19395/13829 19507/19653/14074 +f 19509/19393/13826 19507/19653/14074 19510/19655/14076 +f 19423/19375/13818 19511/19381/13818 19512/19656/14077 +f 19423/19375/13818 19512/19656/14077 19508/19654/14075 +f 19513/19391/13829 19509/19393/13826 19510/19655/14076 +f 19513/19391/13829 19510/19655/14076 19514/19657/14078 +f 19511/19381/13818 19403/19355/13818 19515/19658/14079 +f 19511/19381/13818 19515/19658/14079 19512/19656/14077 +f 19516/19385/13829 19513/19391/13829 19514/19657/14078 +f 19516/19385/13829 19514/19657/14078 19517/19659/14080 +f 19403/19355/13818 19402/19354/13823 19518/19660/14081 +f 19403/19355/13818 19518/19660/14081 19515/19658/14079 +f 19519/19383/14082 19516/19385/13829 19517/19659/14080 +f 19519/19383/14082 19517/19659/14080 19520/19661/14083 +f 19534/19662/14084 19535/19663/14085 19536/19664/14086 +f 19534/19662/14084 19536/19664/14086 19537/19665/14087 +f 19538/19666/14077 19539/19667/14088 19540/19668/14089 +f 19538/19666/14077 19540/19668/14089 19541/19669/14072 +f 19542/19670/14090 19543/19671/14091 19544/19672/14092 +f 19542/19670/14090 19544/19672/14092 19545/19673/14093 +f 19546/19674/14094 19547/19675/14095 19548/19676/14096 +f 19546/19674/14094 19548/19676/14096 19549/19677/14097 +f 19550/19678/14081 19551/19679/14098 19552/19680/14078 +f 19550/19678/14081 19552/19680/14078 19553/19681/14076 +f 19554/19682/14099 19555/19683/14073 19556/19684/14100 +f 19554/19682/14099 19556/19684/14100 19557/19685/14101 +f 19543/19671/14091 19558/19686/14102 19559/19687/14048 +f 19543/19671/14091 19559/19687/14048 19544/19672/14092 +f 19560/19688/14103 19534/19662/14084 19537/19665/14087 +f 19560/19688/14103 19537/19665/14087 19561/19689/14104 +f 19562/19690/14105 19538/19666/14077 19541/19669/14072 +f 19562/19690/14105 19541/19669/14072 19563/19691/14106 +f 19564/19692/14066 19546/19674/14094 19549/19677/14097 +f 19564/19692/14066 19549/19677/14097 19565/19693/14047 +f 19566/19694/14107 19542/19670/14090 19545/19673/14093 +f 19566/19694/14107 19545/19673/14093 19567/19695/14108 +f 19539/19667/14088 19568/19696/14081 19569/19697/14076 +f 19539/19667/14088 19569/19697/14076 19540/19668/14089 +f 19547/19675/14095 19554/19682/14099 19557/19685/14101 +f 19547/19675/14095 19557/19685/14101 19548/19676/14096 +f 19551/19679/14098 19560/19688/14103 19561/19689/14104 +f 19551/19679/14098 19561/19689/14104 19552/19680/14078 +f 19570/19698/14109 19562/19690/14105 19563/19691/14106 +f 19570/19698/14109 19563/19691/14106 19571/19699/14110 +f 19558/19686/14102 19572/19700/14066 19573/19701/14047 +f 19558/19686/14102 19573/19701/14047 19559/19687/14048 +f 19411/19363/13818 19399/19351/13818 19574/19702/14111 +f 19411/19363/13818 19574/19702/14111 19575/19703/14090 +f 19407/19359/13829 19405/19357/13829 19576/19704/14112 +f 19407/19359/13829 19576/19704/14112 19499/19646/14067 +f 19398/19350/13818 19415/19367/13823 19498/19645/14066 +f 19398/19350/13818 19498/19645/14066 19577/19705/14113 +f 19386/19338/13818 19411/19363/13818 19575/19703/14090 +f 19386/19338/13818 19575/19703/14090 19578/19706/14107 +f 19405/19357/13829 19395/19347/13829 19579/19707/14114 +f 19405/19357/13829 19579/19707/14114 19576/19704/14112 +f 19399/19351/13818 19398/19350/13818 19577/19705/14113 +f 19399/19351/13818 19577/19705/14113 19574/19702/14111 +f 19387/19339/13820 19386/19338/13818 19578/19706/14107 +f 19387/19339/13820 19578/19706/14107 19580/19708/14084 +f 19395/19347/13829 19394/19346/13826 19581/19709/14115 +f 19395/19347/13829 19581/19709/14115 19579/19707/14114 +f 19391/19343/13829 19390/19342/13829 19582/19710/14093 +f 19391/19343/13829 19582/19710/14093 19583/19711/14116 +f 19529/19387/13818 19387/19339/13820 19580/19708/14084 +f 19529/19387/13818 19580/19708/14084 19584/19712/14117 +f 19394/19346/13826 19522/19377/13826 19585/19713/14048 +f 19394/19346/13826 19585/19713/14048 19581/19709/14115 +f 19390/19342/13829 19524/19379/13829 19586/19714/14118 +f 19390/19342/13829 19586/19714/14118 19582/19710/14093 +f 19417/19369/13823 19529/19387/13818 19584/19712/14117 +f 19417/19369/13823 19584/19712/14117 19587/19715/14119 +f 19522/19377/13826 19391/19343/13829 19583/19711/14116 +f 19522/19377/13826 19583/19711/14116 19585/19713/14048 +f 19524/19379/13829 19519/19383/14082 19520/19661/14083 +f 19524/19379/13829 19520/19661/14083 19586/19714/14118 +f 19402/19354/13823 19417/19369/13823 19587/19715/14119 +f 19402/19354/13823 19587/19715/14119 19518/19660/14081 +f 19588/19716/14120 19589/19717/14121 19590/19718/14122 +f 19588/19716/14120 19590/19718/14122 19591/19719/14123 +f 19592/19458/13829 19593/19442/13829 19594/19720/14124 +f 19592/19458/13829 19594/19720/14124 19595/19721/14125 +f 19596/19456/13829 19597/19444/13829 19598/19722/14126 +f 19596/19456/13829 19598/19722/14126 19599/19723/14127 +f 19600/19422/13818 19601/19420/13818 19602/19724/14128 +f 19600/19422/13818 19602/19724/14128 19603/19725/14129 +f 19377/19426/13908 19604/19726/14130 19605/19727/14131 +f 19377/19426/13908 19605/19727/14131 19378/19566/14019 +f 19606/19454/13829 19607/19448/13829 19608/19728/14132 +f 19606/19454/13829 19608/19728/14132 19609/19729/14133 +f 19610/19452/13829 19611/19450/13829 19612/19730/14134 +f 19610/19452/13829 19612/19730/14134 19613/19731/14135 +f 19604/19726/14130 19614/19732/14136 19615/19733/14137 +f 19604/19726/14130 19615/19733/14137 19605/19727/14131 +f 19614/19732/14136 19616/19734/14138 19617/19735/14139 +f 19614/19732/14136 19617/19735/14139 19615/19733/14137 +f 19618/19429/13829 19592/19458/13829 19595/19721/14125 +f 19618/19429/13829 19595/19721/14125 19619/19736/14140 +f 19616/19734/14138 19620/19737/14141 19621/19738/14142 +f 19616/19734/14138 19621/19738/14142 19617/19735/14139 +f 19622/19447/13829 19596/19456/13829 19599/19723/14127 +f 19622/19447/13829 19599/19723/14127 19623/19739/14143 +f 19624/19433/13829 19606/19454/13829 19609/19729/14133 +f 19624/19433/13829 19609/19729/14133 19625/19740/14144 +f 19626/19437/13829 19610/19452/13829 19613/19731/14135 +f 19626/19437/13829 19613/19731/14135 19627/19741/14145 +f 19620/19737/14141 19628/19424/13818 19629/19742/14146 +f 19620/19737/14141 19629/19742/14146 19621/19738/14142 +f 19628/19424/13818 19630/19406/13818 19631/19743/14147 +f 19628/19424/13818 19631/19743/14147 19629/19742/14146 +f 19632/19744/14148 19633/19745/14145 19634/19746/14149 +f 19632/19744/14148 19634/19746/14149 19635/19747/14150 +f 19636/19748/14151 19637/19749/14140 19638/19750/14146 +f 19636/19748/14151 19638/19750/14146 19639/19751/14152 +f 19640/19752/14144 19641/19753/14153 19642/19754/14154 +f 19640/19752/14144 19642/19754/14154 19643/19755/14155 +f 19644/19756/14127 19645/19757/14126 19646/19758/14156 +f 19644/19756/14127 19646/19758/14156 19647/19759/14129 +f 19648/19760/14134 19649/19761/14157 19650/19762/14158 +f 19648/19760/14134 19650/19762/14158 19651/19763/14159 +f 19652/19764/14124 19653/19765/14160 19654/19766/14161 +f 19652/19764/14124 19654/19766/14161 19655/19767/14139 +f 19633/19745/14145 19656/19768/14162 19657/19769/14163 +f 19633/19745/14145 19657/19769/14163 19634/19746/14149 +f 19637/19749/14140 19658/19770/14125 19659/19771/14164 +f 19637/19749/14140 19659/19771/14164 19638/19750/14146 +f 19641/19753/14153 19660/19772/14132 19661/19773/14165 +f 19641/19753/14153 19661/19773/14165 19642/19754/14154 +f 19645/19757/14126 19662/19774/14148 19663/19775/14166 +f 19645/19757/14126 19663/19775/14166 19646/19758/14156 +f 19649/19761/14157 19636/19748/14151 19639/19751/14152 +f 19649/19761/14157 19639/19751/14152 19650/19762/14158 +f 19664/19776/14167 19644/19756/14127 19647/19759/14129 +f 19664/19776/14167 19647/19759/14129 19665/19777/14128 +f 19653/19765/14160 19666/19778/14144 19667/19779/14168 +f 19653/19765/14160 19667/19779/14168 19654/19766/14161 +f 19668/19780/14162 19648/19760/14134 19651/19763/14159 +f 19668/19780/14162 19651/19763/14159 19669/19781/14163 +f 19658/19770/14125 19670/19782/14169 19671/19783/14139 +f 19658/19770/14125 19671/19783/14139 19659/19771/14164 +f 19660/19772/14132 19664/19776/14167 19665/19777/14128 +f 19660/19772/14132 19665/19777/14128 19661/19773/14165 +f 19672/19416/13818 19600/19422/13818 19603/19725/14129 +f 19672/19416/13818 19603/19725/14129 19673/19784/14170 +f 19601/19420/13818 19376/19419/13818 19379/19567/14020 +f 19601/19420/13818 19379/19567/14020 19602/19724/14128 +f 19611/19450/13829 19674/19440/13829 19675/19785/14171 +f 19611/19450/13829 19675/19785/14171 19612/19730/14134 +f 19607/19448/13829 19622/19447/13829 19623/19739/14143 +f 19607/19448/13829 19623/19739/14143 19608/19728/14132 +f 19676/19414/13818 19672/19416/13818 19673/19784/14170 +f 19676/19414/13818 19673/19784/14170 19677/19786/14150 +f 19678/19412/13818 19676/19414/13818 19677/19786/14150 +f 19678/19412/13818 19677/19786/14150 19679/19787/14172 +f 19597/19444/13829 19680/19438/13829 19681/19788/14148 +f 19597/19444/13829 19681/19788/14148 19598/19722/14126 +f 19593/19442/13829 19682/19434/13829 19683/19789/14173 +f 19593/19442/13829 19683/19789/14173 19594/19720/14124 +f 19684/19410/13818 19678/19412/13818 19679/19787/14172 +f 19684/19410/13818 19679/19787/14172 19685/19790/14163 +f 19674/19440/13829 19686/19430/13829 19687/19791/14151 +f 19674/19440/13829 19687/19791/14151 19675/19785/14171 +f 19688/19408/13818 19684/19410/13818 19685/19790/14163 +f 19688/19408/13818 19685/19790/14163 19689/19792/14174 +f 19690/19405/13818 19688/19408/13818 19689/19792/14174 +f 19690/19405/13818 19689/19792/14174 19691/19793/14158 +f 19680/19438/13829 19626/19437/13829 19627/19741/14145 +f 19680/19438/13829 19627/19741/14145 19681/19788/14148 +f 19682/19434/13829 19624/19433/13829 19625/19740/14144 +f 19682/19434/13829 19625/19740/14144 19683/19789/14173 +f 19630/19406/13818 19690/19405/13818 19691/19793/14158 +f 19630/19406/13818 19691/19793/14158 19631/19743/14147 +f 19686/19430/13829 19618/19429/13829 19619/19736/14140 +f 19686/19430/13829 19619/19736/14140 19687/19791/14151 +f 19692/19794/14175 19375/19565/14018 19332/19526/13994 +f 19692/19794/14175 19332/19526/13994 19693/19795/14176 +f 19694/19796/14177 19372/19562/14016 19375/19565/14018 +f 19694/19796/14177 19375/19565/14018 19692/19794/14175 +f 19695/19797/14178 19365/19559/14014 19367/19561/14015 +f 19695/19797/14178 19367/19561/14015 19696/19798/14177 +f 19697/19799/14179 19363/19557/14012 19365/19559/14014 +f 19697/19799/14179 19365/19559/14014 19695/19797/14178 +f 19698/19800/14180 19361/19555/14010 19363/19557/14012 +f 19698/19800/14180 19363/19557/14012 19697/19799/14179 +f 19699/19801/14181 19358/19552/14009 19361/19555/14010 +f 19699/19801/14181 19361/19555/14010 19698/19800/14180 +f 19700/19802/14182 19355/19549/14007 19357/19551/14009 +f 19700/19802/14182 19357/19551/14009 19701/19803/14181 +f 19702/19804/14183 19353/19547/14006 19355/19549/14007 +f 19702/19804/14183 19355/19549/14007 19700/19802/14182 +f 19703/19805/14184 19351/19545/14004 19353/19547/14006 +f 19703/19805/14184 19353/19547/14006 19702/19804/14183 +f 19704/19806/14185 19348/19542/14003 19351/19545/14004 +f 19704/19806/14185 19351/19545/14004 19703/19805/14184 +f 19705/19807/14186 19345/19539/14002 19347/19541/14003 +f 19705/19807/14186 19347/19541/14003 19706/19808/14185 +f 19707/19809/14187 19343/19537/14000 19345/19539/14002 +f 19707/19809/14187 19345/19539/14002 19705/19807/14186 +f 19708/19810/14188 19341/19535/13999 19343/19537/14000 +f 19708/19810/14188 19343/19537/14000 19707/19809/14187 +f 19709/19811/14189 19338/19532/13997 19341/19535/13999 +f 19709/19811/14189 19341/19535/13999 19708/19810/14188 +f 19710/19812/14190 19335/19529/13996 19337/19531/13997 +f 19710/19812/14190 19337/19531/13997 19711/19813/14191 +f 19693/19795/14176 19332/19526/13994 19335/19529/13996 +f 19693/19795/14176 19335/19529/13996 19710/19812/14190 +f 19712/19814/14192 19713/19815/14193 19714/19816/14194 +f 19712/19814/14192 19714/19816/14194 19715/19817/14195 +f 19713/19815/14193 19716/19818/14196 19717/19819/14197 +f 19713/19815/14193 19717/19819/14197 19714/19816/14194 +f 19716/19818/14196 19718/19820/14198 19719/19821/14199 +f 19716/19818/14196 19719/19821/14199 19717/19819/14197 +f 19718/19820/14198 19720/19822/14196 19721/19823/14197 +f 19718/19820/14198 19721/19823/14197 19719/19821/14199 +f 19720/19822/14196 19722/19824/14200 19723/19825/14199 +f 19720/19822/14196 19723/19825/14199 19721/19823/14197 +f 19722/19824/14200 19693/19795/14176 19710/19812/14190 +f 19722/19824/14200 19710/19812/14190 19723/19825/14199 +f 19715/19817/14195 19714/19816/14194 19724/19826/14201 +f 19715/19817/14195 19724/19826/14201 19725/19827/14202 +f 19714/19816/14194 19717/19819/14197 19726/19828/14203 +f 19714/19816/14194 19726/19828/14203 19724/19826/14201 +f 19717/19819/14197 19719/19821/14199 19727/19829/14204 +f 19717/19819/14197 19727/19829/14204 19726/19828/14203 +f 19719/19821/14199 19721/19823/14197 19728/19830/14205 +f 19719/19821/14199 19728/19830/14205 19727/19829/14204 +f 19721/19823/14197 19723/19825/14199 19729/19831/14204 +f 19721/19823/14197 19729/19831/14204 19728/19830/14205 +f 19723/19825/14199 19710/19812/14190 19711/19813/14191 +f 19723/19825/14199 19711/19813/14191 19729/19831/14204 +f 19730/19832/14202 19731/19833/14201 19732/19834/14206 +f 19730/19832/14202 19732/19834/14206 19733/19835/14207 +f 19731/19833/14201 19734/19836/14208 19735/19837/14209 +f 19731/19833/14201 19735/19837/14209 19732/19834/14206 +f 19734/19836/14208 19736/19838/14204 19737/19839/14210 +f 19734/19836/14208 19737/19839/14210 19735/19837/14209 +f 19736/19838/14204 19738/19840/14205 19739/19841/14209 +f 19736/19838/14204 19739/19841/14209 19737/19839/14210 +f 19738/19840/14205 19740/19842/14211 19741/19843/14210 +f 19738/19840/14205 19741/19843/14210 19739/19841/14209 +f 19740/19842/14211 19709/19811/14189 19708/19810/14188 +f 19740/19842/14211 19708/19810/14188 19741/19843/14210 +f 19733/19835/14207 19732/19834/14206 19742/19844/14212 +f 19733/19835/14207 19742/19844/14212 19743/19845/14213 +f 19732/19834/14206 19735/19837/14209 19744/19846/14214 +f 19732/19834/14206 19744/19846/14214 19742/19844/14212 +f 19735/19837/14209 19737/19839/14210 19745/19847/14215 +f 19735/19837/14209 19745/19847/14215 19744/19846/14214 +f 19737/19839/14210 19739/19841/14209 19746/19848/14214 +f 19737/19839/14210 19746/19848/14214 19745/19847/14215 +f 19739/19841/14209 19741/19843/14210 19747/19849/14215 +f 19739/19841/14209 19747/19849/14215 19746/19848/14214 +f 19741/19843/14210 19708/19810/14188 19707/19809/14187 +f 19741/19843/14210 19707/19809/14187 19747/19849/14215 +f 19743/19845/14213 19742/19844/14212 19748/19850/14216 +f 19743/19845/14213 19748/19850/14216 19749/19851/14217 +f 19742/19844/14212 19744/19846/14214 19750/19852/14218 +f 19742/19844/14212 19750/19852/14218 19748/19850/14216 +f 19744/19846/14214 19745/19847/14215 19751/19853/14219 +f 19744/19846/14214 19751/19853/14219 19750/19852/14218 +f 19745/19847/14215 19746/19848/14214 19752/19854/14218 +f 19745/19847/14215 19752/19854/14218 19751/19853/14219 +f 19746/19848/14214 19747/19849/14215 19753/19855/14219 +f 19746/19848/14214 19753/19855/14219 19752/19854/14218 +f 19747/19849/14215 19707/19809/14187 19705/19807/14186 +f 19747/19849/14215 19705/19807/14186 19753/19855/14219 +f 19749/19851/14217 19748/19850/14216 19754/19856/14220 +f 19749/19851/14217 19754/19856/14220 19755/19857/14221 +f 19748/19850/14216 19750/19852/14218 19756/19858/14222 +f 19748/19850/14216 19756/19858/14222 19754/19856/14220 +f 19750/19852/14218 19751/19853/14219 19757/19859/14223 +f 19750/19852/14218 19757/19859/14223 19756/19858/14222 +f 19751/19853/14219 19752/19854/14218 19758/19860/14222 +f 19751/19853/14219 19758/19860/14222 19757/19859/14223 +f 19752/19854/14218 19753/19855/14219 19759/19861/14223 +f 19752/19854/14218 19759/19861/14223 19758/19860/14222 +f 19753/19855/14219 19705/19807/14186 19706/19808/14185 +f 19753/19855/14219 19706/19808/14185 19759/19861/14223 +f 19760/19862/14221 19761/19863/14224 19762/19864/14225 +f 19760/19862/14221 19762/19864/14225 19763/19865/14226 +f 19761/19863/14224 19764/19866/14222 19765/19867/14227 +f 19761/19863/14224 19765/19867/14227 19762/19864/14225 +f 19764/19866/14222 19766/19868/14223 19767/19869/14228 +f 19764/19866/14222 19767/19869/14228 19765/19867/14227 +f 19766/19868/14223 19768/19870/14222 19769/19871/14229 +f 19766/19868/14223 19769/19871/14229 19767/19869/14228 +f 19768/19870/14222 19770/19872/14230 19771/19873/14231 +f 19768/19870/14222 19771/19873/14231 19769/19871/14229 +f 19770/19872/14230 19704/19806/14185 19703/19805/14184 +f 19770/19872/14230 19703/19805/14184 19771/19873/14231 +f 19763/19865/14226 19762/19864/14225 19772/19874/14232 +f 19763/19865/14226 19772/19874/14232 19773/19875/14233 +f 19762/19864/14225 19765/19867/14227 19774/19876/14234 +f 19762/19864/14225 19774/19876/14234 19772/19874/14232 +f 19765/19867/14227 19767/19869/14228 19775/19877/14235 +f 19765/19867/14227 19775/19877/14235 19774/19876/14234 +f 19767/19869/14228 19769/19871/14229 19776/19878/14236 +f 19767/19869/14228 19776/19878/14236 19775/19877/14235 +f 19769/19871/14229 19771/19873/14231 19777/19879/14235 +f 19769/19871/14229 19777/19879/14235 19776/19878/14236 +f 19771/19873/14231 19703/19805/14184 19702/19804/14183 +f 19771/19873/14231 19702/19804/14183 19777/19879/14235 +f 19773/19875/14233 19772/19874/14232 19778/19880/14237 +f 19773/19875/14233 19778/19880/14237 19779/19881/14238 +f 19772/19874/14232 19774/19876/14234 19780/19882/14239 +f 19772/19874/14232 19780/19882/14239 19778/19880/14237 +f 19774/19876/14234 19775/19877/14235 19781/19883/14240 +f 19774/19876/14234 19781/19883/14240 19780/19882/14239 +f 19775/19877/14235 19776/19878/14236 19782/19884/14239 +f 19775/19877/14235 19782/19884/14239 19781/19883/14240 +f 19776/19878/14236 19777/19879/14235 19783/19885/14240 +f 19776/19878/14236 19783/19885/14240 19782/19884/14239 +f 19777/19879/14235 19702/19804/14183 19700/19802/14182 +f 19777/19879/14235 19700/19802/14182 19783/19885/14240 +f 19779/19881/14238 19778/19880/14237 19784/19886/14241 +f 19779/19881/14238 19784/19886/14241 19785/19887/14242 +f 19778/19880/14237 19780/19882/14239 19786/19888/14243 +f 19778/19880/14237 19786/19888/14243 19784/19886/14241 +f 19780/19882/14239 19781/19883/14240 19787/19889/14244 +f 19780/19882/14239 19787/19889/14244 19786/19888/14243 +f 19781/19883/14240 19782/19884/14239 19788/19890/14245 +f 19781/19883/14240 19788/19890/14245 19787/19889/14244 +f 19782/19884/14239 19783/19885/14240 19789/19891/14244 +f 19782/19884/14239 19789/19891/14244 19788/19890/14245 +f 19783/19885/14240 19700/19802/14182 19701/19803/14181 +f 19783/19885/14240 19701/19803/14181 19789/19891/14244 +f 19790/19892/14242 19791/19893/14241 19792/19894/14246 +f 19790/19892/14242 19792/19894/14246 19793/19895/14247 +f 19791/19893/14241 19794/19896/14243 19795/19897/14248 +f 19791/19893/14241 19795/19897/14248 19792/19894/14246 +f 19794/19896/14243 19796/19898/14244 19797/19899/14249 +f 19794/19896/14243 19797/19899/14249 19795/19897/14248 +f 19796/19898/14244 19798/19900/14250 19799/19901/14248 +f 19796/19898/14244 19799/19901/14248 19797/19899/14249 +f 19798/19900/14250 19800/19902/14251 19801/19903/14249 +f 19798/19900/14250 19801/19903/14249 19799/19901/14248 +f 19800/19902/14251 19699/19801/14181 19698/19800/14180 +f 19800/19902/14251 19698/19800/14180 19801/19903/14249 +f 19793/19895/14247 19792/19894/14246 19802/19904/14252 +f 19793/19895/14247 19802/19904/14252 19803/19905/14253 +f 19792/19894/14246 19795/19897/14248 19804/19906/14254 +f 19792/19894/14246 19804/19906/14254 19802/19904/14252 +f 19795/19897/14248 19797/19899/14249 19805/19907/14255 +f 19795/19897/14248 19805/19907/14255 19804/19906/14254 +f 19797/19899/14249 19799/19901/14248 19806/19908/14254 +f 19797/19899/14249 19806/19908/14254 19805/19907/14255 +f 19799/19901/14248 19801/19903/14249 19807/19909/14255 +f 19799/19901/14248 19807/19909/14255 19806/19908/14254 +f 19801/19903/14249 19698/19800/14180 19697/19799/14179 +f 19801/19903/14249 19697/19799/14179 19807/19909/14255 +f 19803/19905/14253 19802/19904/14252 19808/19910/14256 +f 19803/19905/14253 19808/19910/14256 19809/19911/14257 +f 19802/19904/14252 19804/19906/14254 19810/19912/14258 +f 19802/19904/14252 19810/19912/14258 19808/19910/14256 +f 19804/19906/14254 19805/19907/14255 19811/19913/14259 +f 19804/19906/14254 19811/19913/14259 19810/19912/14258 +f 19805/19907/14255 19806/19908/14254 19812/19914/14260 +f 19805/19907/14255 19812/19914/14260 19811/19913/14259 +f 19806/19908/14254 19807/19909/14255 19813/19915/14259 +f 19806/19908/14254 19813/19915/14259 19812/19914/14260 +f 19807/19909/14255 19697/19799/14179 19695/19797/14178 +f 19807/19909/14255 19695/19797/14178 19813/19915/14259 +f 19809/19911/14257 19808/19910/14256 19814/19916/14261 +f 19809/19911/14257 19814/19916/14261 19815/19917/14262 +f 19808/19910/14256 19810/19912/14258 19816/19918/14263 +f 19808/19910/14256 19816/19918/14263 19814/19916/14261 +f 19810/19912/14258 19811/19913/14259 19817/19919/14264 +f 19810/19912/14258 19817/19919/14264 19816/19918/14263 +f 19811/19913/14259 19812/19914/14260 19818/19920/14265 +f 19811/19913/14259 19818/19920/14265 19817/19919/14264 +f 19812/19914/14260 19813/19915/14259 19819/19921/14264 +f 19812/19914/14260 19819/19921/14264 19818/19920/14265 +f 19813/19915/14259 19695/19797/14178 19696/19798/14177 +f 19813/19915/14259 19696/19798/14177 19819/19921/14264 +f 19820/19922/14262 19821/19923/14261 19822/19924/14266 +f 19820/19922/14262 19822/19924/14266 19823/19925/14267 +f 19821/19923/14261 19824/19926/14263 19825/19927/14268 +f 19821/19923/14261 19825/19927/14268 19822/19924/14266 +f 19824/19926/14263 19826/19928/14264 19827/19929/14269 +f 19824/19926/14263 19827/19929/14269 19825/19927/14268 +f 19826/19928/14264 19828/19930/14263 19829/19931/14268 +f 19826/19928/14264 19829/19931/14268 19827/19929/14269 +f 19828/19930/14263 19830/19932/14264 19831/19933/14269 +f 19828/19930/14263 19831/19933/14269 19829/19931/14268 +f 19830/19932/14264 19694/19796/14177 19692/19794/14175 +f 19830/19932/14264 19692/19794/14175 19831/19933/14269 +f 19823/19925/14267 19822/19924/14266 19713/19815/14193 +f 19823/19925/14267 19713/19815/14193 19712/19814/14192 +f 19822/19924/14266 19825/19927/14268 19716/19818/14196 +f 19822/19924/14266 19716/19818/14196 19713/19815/14193 +f 19825/19927/14268 19827/19929/14269 19718/19820/14198 +f 19825/19927/14268 19718/19820/14198 19716/19818/14196 +f 19827/19929/14269 19829/19931/14268 19720/19822/14196 +f 19827/19929/14269 19720/19822/14196 19718/19820/14198 +f 19829/19931/14268 19831/19933/14269 19722/19824/14200 +f 19829/19931/14268 19722/19824/14200 19720/19822/14196 +f 19831/19933/14269 19692/19794/14175 19693/19795/14176 +f 19831/19933/14269 19693/19795/14176 19722/19824/14200 +f 19832/19934/14270 19823/19925/14267 19712/19814/14192 +f 19832/19934/14270 19712/19814/14192 19833/19935/13928 +f 19834/19936/13933 19820/19922/14262 19823/19925/14267 +f 19834/19936/13933 19823/19925/14267 19832/19934/14270 +f 19835/19937/13913 19809/19911/14257 19815/19917/14262 +f 19835/19937/13913 19815/19917/14262 19836/19938/13933 +f 19837/19939/13912 19803/19905/14253 19809/19911/14257 +f 19837/19939/13912 19809/19911/14257 19835/19937/13913 +f 19838/19940/13918 19793/19895/14247 19803/19905/14253 +f 19838/19940/13918 19803/19905/14253 19837/19939/13912 +f 19839/19941/13931 19790/19892/14242 19793/19895/14247 +f 19839/19941/13931 19793/19895/14247 19838/19940/13918 +f 19840/19942/14271 19779/19881/14238 19785/19887/14242 +f 19840/19942/14271 19785/19887/14242 19841/19943/13931 +f 19842/19944/13909 19773/19875/14233 19779/19881/14238 +f 19842/19944/13909 19779/19881/14238 19840/19942/14271 +f 19843/19945/13917 19763/19865/14226 19773/19875/14233 +f 19843/19945/13917 19773/19875/14233 19842/19944/13909 +f 19844/19946/14272 19760/19862/14221 19763/19865/14226 +f 19844/19946/14272 19763/19865/14226 19843/19945/13917 +f 19845/19947/13926 19749/19851/14217 19755/19857/14221 +f 19845/19947/13926 19755/19857/14221 19846/19948/14272 +f 19847/19949/13915 19743/19845/14213 19749/19851/14217 +f 19847/19949/13915 19749/19851/14217 19845/19947/13926 +f 19848/19950/13916 19733/19835/14207 19743/19845/14213 +f 19848/19950/13916 19743/19845/14213 19847/19949/13915 +f 19849/19951/13919 19730/19832/14202 19733/19835/14207 +f 19849/19951/13919 19733/19835/14207 19848/19950/13916 +f 19850/19952/13929 19715/19817/14195 19725/19827/14202 +f 19850/19952/13929 19725/19827/14202 19851/19953/13919 +f 19833/19935/13928 19712/19814/14192 19715/19817/14195 +f 19833/19935/13928 19715/19817/14195 19850/19952/13929 +f 19852/19954/14273 19853/19955/13881 19854/19956/14274 +f 19852/19954/14273 19854/19956/14274 19855/19957/14275 +f 19856/19958/14276 19588/19716/14120 19591/19719/14123 +f 19856/19958/14276 19591/19719/14123 19857/19959/14276 +f 19858/19960/14277 19852/19954/14273 19855/19957/14275 +f 19858/19960/14277 19855/19957/14275 19859/19961/14277 +f 19589/19717/14121 19860/19962/14278 19861/19963/14279 +f 19589/19717/14121 19861/19963/14279 19590/19718/14122 +f 19862/19396/13881 19864/19398/13886 19865/19525/13993 +f 19866/19964/14280 19867/19965/14281 19868/19966/14282 +f 19866/19964/14280 19868/19966/14282 19869/19967/14279 +f 19863/19397/13886 19870/19401/14283 19871/19399/13883 +f 19867/19965/14281 19872/19968/14284 19873/19969/14285 +f 19867/19965/14281 19873/19969/14285 19868/19966/14282 +f 19874/19970/14283 19875/19971/14286 19876/19972/14287 +f 19874/19970/14283 19876/19972/14287 19877/19973/13883 +f 19872/19968/14284 19878/19974/14288 19879/19975/14288 +f 19872/19968/14284 19879/19975/14288 19873/19969/14285 +f 19875/19971/14286 19880/19976/14289 19881/19977/14289 +f 19875/19971/14286 19881/19977/14289 19876/19972/14287 +f 19878/19974/14288 19882/19978/14290 19883/19979/14290 +f 19878/19974/14288 19883/19979/14290 19879/19975/14288 +f 19880/19976/14289 19884/19980/14291 19885/19981/14291 +f 19880/19976/14289 19885/19981/14291 19881/19977/14289 +f 19882/19978/14290 19858/19960/14277 19859/19961/14277 +f 19882/19978/14290 19859/19961/14277 19883/19979/14290 +f 19886/19982/14292 19887/19983/14293 19858/19960/14277 +f 19886/19982/14292 19858/19960/14277 19882/19978/14290 +f 19888/19984/14294 19889/19985/13900 19884/19980/14291 +f 19888/19984/14294 19884/19980/14291 19880/19976/14289 +f 19889/19985/13900 19890/19986/13902 19856/19958/14276 +f 19889/19985/13900 19856/19958/14276 19884/19980/14291 +f 19891/19987/14295 19886/19982/14292 19882/19978/14290 +f 19891/19987/14295 19882/19978/14290 19878/19974/14288 +f 19892/19988/14296 19888/19984/14294 19880/19976/14289 +f 19892/19988/14296 19880/19976/14289 19875/19971/14286 +f 19893/19989/14297 19891/19987/14295 19878/19974/14288 +f 19893/19989/14297 19878/19974/14288 19872/19968/14284 +f 19894/19990/14298 19892/19988/14296 19875/19971/14286 +f 19894/19990/14298 19875/19971/14286 19874/19970/14283 +f 19895/19991/13895 19893/19989/14297 19872/19968/14284 +f 19895/19991/13895 19872/19968/14284 19867/19965/14281 +f 19896/19400/13884 19897/19992/14298 19870/19401/14283 +f 19898/19993/13894 19899/19994/13895 19900/19995/14299 +f 19898/19993/13894 19900/19995/14299 19901/19996/14300 +f 19902/19402/14301 19863/19397/13886 19862/19396/14302 +f 19903/19997/13898 19898/19993/13894 19901/19996/14300 +f 19903/19997/13898 19901/19996/14300 19904/19998/14121 +f 19905/19999/13905 19906/20000/14303 19853/19955/13881 +f 19905/19999/13905 19853/19955/13881 19852/19954/14273 +f 19907/20001/14304 19908/20002/14305 19589/19717/14121 +f 19907/20001/14304 19589/19717/14121 19588/19716/14120 +f 19887/19983/14293 19905/19999/13905 19852/19954/14273 +f 19887/19983/14293 19852/19954/14273 19858/19960/14277 +f 19890/19986/13902 19907/20001/14304 19588/19716/14120 +f 19890/19986/13902 19588/19716/14120 19856/19958/14276 +f 19920/19425/13905 19628/19424/13818 19620/19737/14141 +f 19921/20003/14301 19920/19425/13905 19620/19737/14141 +f 19921/20003/14301 19620/19737/14141 19616/19734/14138 +f 19922/20004/13884 19921/20003/14301 19616/19734/14138 +f 19922/20004/13884 19616/19734/14138 19614/19732/14136 +f 19923/20005/14298 19922/20004/13884 19614/19732/14136 +f 19923/20005/14298 19614/19732/14136 19604/19726/14130 +f 19924/20006/14296 19923/20005/14298 19604/19726/14130 +f 19924/20006/14296 19604/19726/14130 19377/19426/13908 +f 19917/19418/13901 19924/20006/14296 19377/19426/13908 +f 19941/20007/14306 19942/20008/14307 19495/19643/14064 +f 19941/20007/14306 19495/19643/14064 19494/19642/14063 +f 19942/20008/14307 19943/20009/14308 19470/19618/14049 +f 19942/20008/14307 19470/19618/14049 19495/19643/14064 +f 19943/20009/14308 19944/20010/14309 19471/19619/14050 +f 19943/20009/14308 19471/19619/14050 19470/19618/14049 +f 19944/20010/14309 19945/20011/14310 19475/19623/14053 +f 19944/20010/14309 19475/19623/14053 19471/19619/14050 +f 19945/20011/14310 19946/20012/14311 19479/19627/14055 +f 19945/20011/14310 19479/19627/14055 19475/19623/14053 +f 19946/20012/14311 19947/20013/14312 19483/19631/14057 +f 19946/20012/14311 19483/19631/14057 19479/19627/14055 +f 19947/20013/14312 19948/20014/14313 19487/19635/14059 +f 19947/20013/14312 19487/19635/14059 19483/19631/14057 +f 19948/20014/14313 19949/20015/14314 19491/19639/14062 +f 19948/20014/14313 19491/19639/14062 19487/19635/14059 +f 19949/20015/14314 19950/20016/14315 19426/19574/14025 +f 19949/20015/14314 19426/19574/14025 19491/19639/14062 +f 19950/20016/14315 19951/20017/14316 19427/19575/14026 +f 19950/20016/14315 19427/19575/14026 19426/19574/14025 +f 19951/20017/14316 19952/20018/14317 19473/19621/14051 +f 19951/20017/14316 19473/19621/14051 19427/19575/14026 +f 19952/20018/14317 19953/20019/14318 19477/19625/14054 +f 19952/20018/14317 19477/19625/14054 19473/19621/14051 +f 19953/20019/14318 19954/20020/14319 19481/19629/14056 +f 19953/20019/14318 19481/19629/14056 19477/19625/14054 +f 19954/20020/14319 19955/20021/14046 19485/19633/14058 +f 19954/20020/14319 19485/19633/14058 19481/19629/14056 +f 19955/20021/14046 19956/20022/14320 19489/19637/14060 +f 19955/20021/14046 19489/19637/14060 19485/19633/14058 +f 19956/20022/14320 19941/20007/14306 19494/19642/14063 +f 19956/20022/14320 19494/19642/14063 19489/19637/14060 +f 19957/20023/14314 19958/20024/14313 19959/20025/14074 +f 19957/20023/14314 19959/20025/14074 19960/20026/14321 +f 19961/20027/14322 19962/20028/14323 19963/20029/14324 +f 19961/20027/14322 19963/20029/14324 19964/20030/14325 +f 19962/20028/14323 19464/19612/14045 19467/19615/14048 +f 19962/20028/14323 19467/19615/14048 19963/20029/14324 +f 19965/20031/14326 19957/20023/14314 19960/20026/14321 +f 19965/20031/14326 19960/20026/14321 19966/20032/14327 +f 19967/20033/14308 19961/20027/14322 19964/20030/14325 +f 19967/20033/14308 19964/20030/14325 19968/20034/14108 +f 19969/20035/14328 19965/20031/14326 19966/20032/14327 +f 19969/20035/14328 19966/20032/14327 19970/20036/14110 +f 19971/20037/14309 19972/20038/14308 19973/20039/14086 +f 19971/20037/14309 19973/20039/14086 19974/20040/14329 +f 19975/20041/14330 19976/20042/14316 19977/20043/14068 +f 19975/20041/14330 19977/20043/14068 19978/20044/14067 +f 19979/20045/14331 19971/20037/14309 19974/20040/14329 +f 19979/20045/14331 19974/20040/14329 19980/20046/14332 +f 19981/20047/14333 19975/20041/14330 19978/20044/14067 +f 19981/20047/14333 19978/20044/14067 19982/20048/14096 +f 19983/20049/14334 19979/20045/14331 19980/20046/14332 +f 19983/20049/14334 19980/20046/14332 19984/20050/14335 +f 19985/20051/14319 19981/20047/14333 19982/20048/14096 +f 19985/20051/14319 19982/20048/14096 19986/20052/14097 +f 19987/20053/14336 19983/20049/14334 19984/20050/14335 +f 19987/20053/14336 19984/20050/14335 19988/20054/14076 +f 19989/20055/14337 19985/20051/14319 19986/20052/14097 +f 19989/20055/14337 19986/20052/14097 19990/20056/14047 +f 19958/20024/14313 19991/20057/14312 19992/20058/14076 +f 19958/20024/14313 19992/20058/14076 19959/20025/14074 +f 19993/20059/14338 19994/20060/14339 19995/20061/13959 +f 19993/20059/14338 19995/20061/13959 19996/20062/13960 +f 19997/20063/14340 19993/20059/14338 19996/20062/13960 +f 19997/20063/14340 19996/20062/13960 19998/20064/14341 +f 19999/20065/14342 20000/20066/14343 20001/20067/14344 +f 19999/20065/14342 20001/20067/14344 20002/20068/14345 +f 20003/20069/14346 20004/20070/14347 20005/20071/14348 +f 20003/20069/14346 20005/20071/14348 20006/20072/14349 +f 20007/20073/14350 20008/20074/14351 20009/20075/14352 +f 20007/20073/14350 20009/20075/14352 20010/20076/14353 +f 20011/20077/14354 20003/20069/14346 20006/20072/14349 +f 20011/20077/14354 20006/20072/14349 20012/20078/14355 +f 20013/20079/14356 20007/20073/14350 20010/20076/14353 +f 20013/20079/14356 20010/20076/14353 20014/20080/14357 +f 20015/20081/14358 20011/20077/14354 20012/20078/14355 +f 20015/20081/14358 20012/20078/14355 20016/20082/14359 +f 20017/20083/14360 20013/20079/14356 20014/20080/14357 +f 20017/20083/14360 20014/20080/14357 20018/20084/14361 +f 20019/20085/14362 20015/20081/14358 20016/20082/14359 +f 20019/20085/14362 20016/20082/14359 20020/20086/14363 +f 20021/20087/14364 20017/20083/14360 20018/20084/14361 +f 20021/20087/14364 20018/20084/14361 20022/20088/14365 +f 20023/20089/14366 20024/20090/14367 20025/20091/14363 +f 20023/20089/14366 20025/20091/14363 20026/20092/14368 +f 20027/20093/14369 20028/20094/14364 20029/20095/14370 +f 20027/20093/14369 20029/20095/14370 20030/20096/14371 +f 20031/20097/14372 20023/20089/14366 20026/20092/14368 +f 20031/20097/14372 20026/20092/14368 20032/20098/14373 +f 20033/20099/14374 20034/20100/14375 20035/20101/14376 +f 20033/20099/14374 20035/20101/14376 20036/20102/14377 +f 20034/20100/14375 20027/20093/14369 20030/20096/14371 +f 20034/20100/14375 20030/20096/14371 20035/20101/14376 +f 20000/20066/14343 20031/20097/14372 20032/20098/14373 +f 20000/20066/14343 20032/20098/14373 20001/20067/14344 +f 20037/20103/14378 20033/20099/14374 20036/20102/14377 +f 20037/20103/14378 20036/20102/14377 20038/20104/14379 +f 20039/19462/13882 20040/19461/13886 20041/20105/14375 +f 20039/19462/13882 20041/20105/14375 20042/20106/14380 +f 20043/19464/13882 20039/19462/13882 20042/20106/14380 +f 20043/19464/13882 20042/20106/14380 20044/20107/14381 +f 20045/19466/13882 20043/19464/13882 20044/20107/14381 +f 20045/19466/13882 20044/20107/14381 20046/20108/14382 +f 20047/19468/13886 20045/19466/13882 20046/20108/14382 +f 20047/19468/13886 20046/20108/14382 20048/20109/14383 +f 20049/19470/13886 20047/19468/13886 20048/20109/14383 +f 20049/19470/13886 20048/20109/14383 20050/20110/14384 +f 20051/19472/13886 20049/19470/13886 20050/20110/14384 +f 20051/19472/13886 20050/20110/14384 20052/20111/14362 +f 20053/19474/13886 20051/19472/13886 20052/20111/14362 +f 20053/19474/13886 20052/20111/14362 20054/20112/14366 +f 20055/19476/13886 20053/19474/13886 20054/20112/14366 +f 20055/19476/13886 20054/20112/14366 20056/20113/14385 +f 20057/19478/13882 20055/19476/13886 20056/20113/14385 +f 20057/19478/13882 20056/20113/14385 20058/20114/14386 +f 20059/19480/13886 20057/19478/13882 20058/20114/14386 +f 20059/19480/13886 20058/20114/14386 20060/20115/14342 +f 20061/19482/13882 20059/19480/13886 20060/20115/14342 +f 20061/19482/13882 20060/20115/14342 20062/20116/14350 +f 20063/19484/13886 20061/19482/13882 20062/20116/14350 +f 20063/19484/13886 20062/20116/14350 20064/20117/14356 +f 20065/19486/13886 20063/19484/13886 20064/20117/14356 +f 20065/19486/13886 20064/20117/14356 20066/20118/14360 +f 20067/19488/13882 20065/19486/13886 20066/20118/14360 +f 20067/19488/13882 20066/20118/14360 20068/20119/14364 +f 20069/19490/13886 20067/19488/13882 20068/20119/14364 +f 20069/19490/13886 20068/20119/14364 20070/20120/14369 +f 20040/19461/13886 20069/19490/13886 20070/20120/14369 +f 20040/19461/13886 20070/20120/14369 20041/20105/14375 +f 20071/19494/13967 20072/19493/13973 20073/20121/14377 +f 20071/19494/13967 20073/20121/14377 20074/20122/14387 +f 20072/19493/13973 20075/19496/13973 20076/20123/14348 +f 20072/19493/13973 20076/20123/14348 20073/20121/14377 +f 20075/19496/13973 20077/19498/13967 20078/20124/14349 +f 20075/19496/13973 20078/20124/14349 20076/20123/14348 +f 20077/19498/13967 20079/19500/13967 20080/20125/14388 +f 20077/19498/13967 20080/20125/14388 20078/20124/14349 +f 20079/19500/13967 20081/19502/13967 20082/20126/14389 +f 20079/19500/13967 20082/20126/14389 20080/20125/14388 +f 20081/19502/13967 20083/19504/13967 20084/20127/14390 +f 20081/19502/13967 20084/20127/14390 20082/20126/14389 +f 20083/19504/13967 20085/19506/13967 20086/20128/14368 +f 20083/19504/13967 20086/20128/14368 20084/20127/14390 +f 20085/19506/13967 20087/19508/13967 20088/20129/14391 +f 20085/19506/13967 20088/20129/14391 20086/20128/14368 +f 20087/19508/13967 20089/19510/13973 20090/20130/14392 +f 20087/19508/13967 20090/20130/14392 20088/20129/14391 +f 20089/19510/13973 20091/19512/13973 20092/20131/14345 +f 20089/19510/13973 20092/20131/14345 20090/20130/14392 +f 20091/19512/13973 20093/19514/13967 20094/20132/14353 +f 20091/19512/13973 20094/20132/14353 20092/20131/14345 +f 20093/19514/13967 20095/19516/13967 20096/20133/14357 +f 20093/19514/13967 20096/20133/14357 20094/20132/14353 +f 20095/19516/13967 20097/19518/13967 20098/20134/14393 +f 20095/19516/13967 20098/20134/14393 20096/20133/14357 +f 20097/19518/13967 20099/19520/13967 20100/20135/14365 +f 20097/19518/13967 20100/20135/14365 20098/20134/14393 +f 20099/19520/13967 20101/19522/13967 20102/20136/14371 +f 20099/19520/13967 20102/20136/14371 20100/20135/14365 +f 20101/19522/13967 20071/19494/13967 20074/20122/14387 +f 20101/19522/13967 20074/20122/14387 20102/20136/14371 +f 20135/20137/13989 20136/20138/13988 20137/20139/13958 +f 20135/20137/13989 20137/20139/13958 20138/20140/13959 +f 20136/20138/13988 20139/20141/13986 20140/20142/14394 +f 20136/20138/13988 20140/20142/14394 20137/20139/13958 +f 20139/20141/13986 20141/20143/13985 20142/20144/14395 +f 20139/20141/13986 20142/20144/14395 20140/20142/14394 +f 20141/20143/13985 20143/20145/13983 20144/20146/13953 +f 20141/20143/13985 20144/20146/13953 20142/20144/14395 +f 20145/20147/13983 20146/20148/14396 20147/20149/13952 +f 20145/20147/13983 20147/20149/13952 20148/20150/13953 +f 20146/20148/14396 20149/20151/13980 20150/20152/14397 +f 20146/20148/14396 20150/20152/14397 20147/20149/13952 +f 20149/20151/13980 20151/20153/14398 20152/20154/14399 +f 20149/20151/13980 20152/20154/14399 20150/20152/14397 +f 20151/20153/14398 20153/20155/13977 20154/20156/13947 +f 20151/20153/14398 20154/20156/13947 20152/20154/14399 +f 20155/20157/13977 20156/20158/14400 20157/20159/14401 +f 20155/20157/13977 20157/20159/14401 20158/20160/13947 +f 20156/20158/14400 20159/20161/13974 20160/20162/13941 +f 20156/20158/14400 20160/20162/13941 20157/20159/14401 +f 20159/20161/13974 20161/20163/14402 20162/20164/14403 +f 20159/20161/13974 20162/20164/14403 20160/20162/13941 +f 20161/20163/14402 20163/20165/13968 20164/20166/13937 +f 20161/20163/14402 20164/20166/13937 20162/20164/14403 +f 20165/20167/13968 20166/20168/13969 20167/20169/14404 +f 20165/20167/13968 20167/20169/14404 20168/20170/13937 +f 20166/20168/13969 19997/20063/14340 19998/20064/14341 +f 20166/20168/13969 19998/20064/14341 20167/20169/14404 +f 19884/19980/14291 19856/19958/14276 19857/19959/14276 +f 19884/19980/14291 19857/19959/14276 19885/19981/14291 +f 20169/20171/14405 20170/20172/14406 20171/20173/14407 +f 20169/20171/14405 20171/20173/14407 20172/20174/14408 +f 20173/20175/14409 20174/20176/14410 20175/20177/14411 +f 20173/20175/14409 20175/20177/14411 20176/20178/14412 +f 20177/20179/14413 20173/20175/14409 20176/20178/14412 +f 20177/20179/14413 20176/20178/14412 20178/20180/14414 +f 20179/20181/14415 20169/20171/14405 20172/20174/14408 +f 20179/20181/14415 20172/20174/14408 20180/20182/14416 +f 20181/20183/14417 20177/20179/14413 20178/20180/14414 +f 20181/20183/14417 20178/20180/14414 20182/20184/14418 +f 20183/20185/14419 20179/20181/14415 20180/20182/14416 +f 20183/20185/14419 20180/20182/14416 20184/20186/14420 +f 20185/20187/14421 20181/20183/14417 20182/20184/14418 +f 20185/20187/14421 20182/20184/14418 20186/20188/14422 +f 20187/20189/14423 20183/20185/14419 20184/20186/14420 +f 20187/20189/14423 20184/20186/14420 20188/20190/14424 +f 20189/20191/14425 20185/20187/14421 20186/20188/14422 +f 20189/20191/14425 20186/20188/14422 20190/20192/14426 +f 20191/20193/14427 20187/20189/14423 20188/20190/14424 +f 20191/20193/14427 20188/20190/14424 20192/20194/14428 +f 20193/20195/14429 20194/20196/14425 20195/20197/14430 +f 20193/20195/14429 20195/20197/14430 20196/20198/14431 +f 20197/20199/14432 20198/20200/14427 20199/20201/14433 +f 20197/20199/14432 20199/20201/14433 20200/20202/14434 +f 20201/20203/14435 20193/20195/14429 20196/20198/14431 +f 20201/20203/14435 20196/20198/14431 20202/20204/14436 +f 20170/20172/14406 20201/20203/14435 20202/20204/14436 +f 20170/20172/14406 20202/20204/14436 20171/20173/14407 +f 20174/20176/14410 20203/20205/14437 20204/20206/14438 +f 20174/20176/14410 20204/20206/14438 20175/20177/14411 +f 20205/20207/14277 20206/20208/14290 20207/20209/14290 +f 20205/20207/14277 20207/20209/14290 20208/20210/14277 +f 20208/20210/14277 20207/20209/14290 19883/19979/14290 +f 20208/20210/14277 19883/19979/14290 19859/19961/14277 +f 20209/20211/14291 20210/20212/14289 20211/20213/14289 +f 20209/20211/14291 20211/20213/14289 20212/20214/14291 +f 20212/20214/14291 20211/20213/14289 19881/19977/14289 +f 20212/20214/14291 19881/19977/14289 19885/19981/14291 +f 20213/20215/14276 20209/20211/14291 20212/20214/14291 +f 20213/20215/14276 20212/20214/14291 20214/20216/14276 +f 20214/20216/14276 20212/20214/14291 19885/19981/14291 +f 20214/20216/14276 19885/19981/14291 19857/19959/14276 +f 20206/20208/14290 20215/20217/14288 20216/20218/14288 +f 20206/20208/14290 20216/20218/14288 20207/20209/14290 +f 20207/20209/14290 20216/20218/14288 19879/19975/14288 +f 20207/20209/14290 19879/19975/14288 19883/19979/14290 +f 20210/20212/14289 20217/20219/14439 20218/20220/14440 +f 20210/20212/14289 20218/20220/14440 20211/20213/14289 +f 20211/20213/14289 20218/20220/14440 19876/19972/14287 +f 20211/20213/14289 19876/19972/14287 19881/19977/14289 +f 20215/20217/14288 20219/20221/14441 20220/20222/14442 +f 20215/20217/14288 20220/20222/14442 20216/20218/14288 +f 20216/20218/14288 20220/20222/14442 19873/19969/14285 +f 20216/20218/14288 19873/19969/14285 19879/19975/14288 +f 20217/20219/14439 20221/20223/14443 20222/20224/14444 +f 20217/20219/14439 20222/20224/14444 20218/20220/14440 +f 20218/20220/14440 20222/20224/14444 19877/19973/13883 +f 20218/20220/14440 19877/19973/13883 19876/19972/14287 +f 20219/20221/14441 20223/20225/14445 20224/20226/14446 +f 20219/20221/14441 20224/20226/14446 20220/20222/14442 +f 20225/20227/14442 20226/20228/14447 20227/20229/14282 +f 20225/20227/14442 20227/20229/14282 20228/20230/14448 +f 20229/20231/14443 20230/20232/14449 20231/19524/13992 +f 20229/20231/14443 20231/19524/13992 20232/19523/13991 +f 20232/19523/13991 19864/19398/13886 19871/19399/13883 +f 20223/20225/14445 20233/20233/14450 20234/20234/14451 +f 20223/20225/14445 20234/20234/14451 20224/20226/14446 +f 20224/20226/14446 20234/20234/14451 19869/19967/14279 +f 20224/20226/14446 19869/19967/14279 19868/19966/14282 +f 20230/20232/14449 20235/20235/14452 20236/20236/14453 +f 20230/20232/14449 20236/20236/14453 20231/19524/13992 +f 20231/19524/13992 20236/20236/14453 19865/19525/14274 +f 20237/20237/14454 20238/20238/14455 20239/20239/14456 +f 20237/20237/14454 20239/20239/14456 20240/20240/14451 +f 20240/20240/14451 20239/20239/14456 19590/19718/14122 +f 20240/20240/14451 19590/19718/14122 19861/19963/14279 +f 20241/20241/14457 20242/20242/14458 20243/20243/14459 +f 20241/20241/14457 20243/20243/14459 20244/20244/14453 +f 20244/20244/14453 20243/20243/14459 19855/19957/14275 +f 20244/20244/14453 19855/19957/14275 19854/19956/14274 +f 20238/20238/14455 20245/20245/14460 20246/20246/14461 +f 20238/20238/14455 20246/20246/14461 20239/20239/14456 +f 20239/20239/14456 20246/20246/14461 19591/19719/14123 +f 20239/20239/14456 19591/19719/14123 19590/19718/14122 +f 20242/20242/14458 20205/20207/14277 20208/20210/14277 +f 20242/20242/14458 20208/20210/14277 20243/20243/14459 +f 20243/20243/14459 20208/20210/14277 19859/19961/14277 +f 20243/20243/14459 19859/19961/14277 19855/19957/14275 +f 20245/20245/14460 20213/20215/14276 20214/20216/14276 +f 20245/20245/14460 20214/20216/14276 20246/20246/14461 +f 20246/20246/14461 20214/20216/14276 19857/19959/14276 +f 20246/20246/14461 19857/19959/14276 19591/19719/14123 +f 20203/20205/14437 20197/20199/14432 20200/20202/14434 +f 20203/20205/14437 20200/20202/14434 20204/20206/14438 +f 20245/20245/14460 20238/20238/14455 20197/20199/14432 +f 20245/20245/14460 20197/20199/14432 20203/20205/14437 +f 20213/20215/14276 20245/20245/14460 20203/20205/14437 +f 20213/20215/14276 20203/20205/14437 20174/20176/14410 +f 20205/20207/14277 20242/20242/14458 20201/20203/14435 +f 20205/20207/14277 20201/20203/14435 20170/20172/14406 +f 20242/20242/14458 20241/20241/14457 20193/20195/14429 +f 20242/20242/14458 20193/20195/14429 20201/20203/14435 +f 20238/20238/14455 20237/20237/14454 20198/20200/14427 +f 20238/20238/14455 20198/20200/14427 20197/20199/14432 +f 20241/20241/14457 20247/20247/14449 20194/20196/14425 +f 20241/20241/14457 20194/20196/14425 20193/20195/14429 +f 20233/20233/14450 20223/20225/14445 20187/20189/14423 +f 20233/20233/14450 20187/20189/14423 20191/20193/14427 +f 20248/20248/14449 20221/20223/14443 20185/20187/14421 +f 20248/20248/14449 20185/20187/14421 20189/20191/14425 +f 20223/20225/14445 20219/20221/14441 20183/20185/14419 +f 20223/20225/14445 20183/20185/14419 20187/20189/14423 +f 20221/20223/14443 20217/20219/14439 20181/20183/14417 +f 20221/20223/14443 20181/20183/14417 20185/20187/14421 +f 20219/20221/14441 20215/20217/14288 20179/20181/14415 +f 20219/20221/14441 20179/20181/14415 20183/20185/14419 +f 20217/20219/14439 20210/20212/14289 20177/20179/14413 +f 20217/20219/14439 20177/20179/14413 20181/20183/14417 +f 20215/20217/14288 20206/20208/14290 20169/20171/14405 +f 20215/20217/14288 20169/20171/14405 20179/20181/14415 +f 20210/20212/14289 20209/20211/14291 20173/20175/14409 +f 20210/20212/14289 20173/20175/14409 20177/20179/14413 +f 20209/20211/14291 20213/20215/14276 20174/20176/14410 +f 20209/20211/14291 20174/20176/14410 20173/20175/14409 +f 20206/20208/14290 20205/20207/14277 20170/20172/14406 +f 20206/20208/14290 20170/20172/14406 20169/20171/14405 +f 20262/20249/14462 20260/20250/14463 20261/20251/14464 +f 20260/20250/14463 20262/20249/14462 20263/20252/14465 +f 20260/20250/14463 20263/20252/14465 20259/20253/14466 +f 20259/20253/14466 20263/20252/14465 20264/20254/14414 +f 20259/20253/14466 20264/20254/14414 20258/20255/14407 +f 20258/20255/14407 20264/20254/14414 20257/20256/14408 +f 20257/20256/14408 20264/20254/14414 20249/20257/14467 +f 20257/20256/14408 20249/20257/14467 20250/20258/14468 +f 20257/20256/14408 20250/20258/14468 20256/20259/14416 +f 20256/20259/14416 20250/20258/14468 20251/20260/14438 +f 20256/20259/14416 20251/20260/14438 20255/20261/14469 +f 20255/20261/14469 20251/20260/14438 20252/20262/14470 +f 20255/20261/14469 20252/20262/14470 20254/20263/14471 +f 20254/20263/14471 20252/20262/14470 20253/20264/14472 +f 20271/20265/14473 20269/20266/14097 20270/20267/14474 +f 20269/20266/14097 20271/20265/14473 20272/20268/14475 +f 20269/20266/14097 20272/20268/14475 20268/20269/14047 +f 20268/20269/14047 20272/20268/14475 20273/20270/14070 +f 20268/20269/14047 20273/20270/14070 20267/20271/14048 +f 20267/20271/14048 20273/20270/14070 20274/20272/14321 +f 20267/20271/14048 20274/20272/14321 20266/20273/14476 +f 20266/20273/14476 20274/20272/14321 20265/20274/14477 +f 20265/20274/14477 20274/20272/14321 20275/20275/14089 +f 20265/20274/14477 20275/20275/14089 20276/20276/14076 +f 20265/20274/14477 20276/20276/14076 20280/20277/14118 +f 20280/20277/14118 20276/20276/14076 20277/20278/14078 +f 20280/20277/14118 20277/20278/14078 20279/20279/14478 +f 20279/20279/14478 20277/20278/14078 20278/20280/14104 +o Cube.033__0 +v -0.664414 0.542481 -0.086066 +v -0.662084 0.538988 -0.087147 +v -0.660300 0.540287 -0.086450 +v -0.729945 0.768658 -0.017553 +v -0.731823 0.766555 -0.018570 +v -0.729576 0.766388 -0.018383 +v -0.659178 0.551646 -0.115466 +v -0.661509 0.555139 -0.114385 +v -0.657394 0.552944 -0.114769 +v -0.411093 0.607792 -0.048174 +v -0.409215 0.609894 -0.047158 +v -0.411463 0.610062 -0.047344 +v -0.656385 0.550854 -0.115459 +v -0.728840 0.775088 -0.048463 +v -0.728918 0.779213 -0.046888 +v -0.726670 0.779046 -0.046702 +v -0.727040 0.781315 -0.045871 +v -0.470471 0.839120 0.032909 +v -0.472802 0.842613 0.033991 +v -0.474586 0.841315 0.033294 +v -0.406387 0.626677 -0.073901 +v -0.406310 0.622552 -0.075476 +v -0.408557 0.622719 -0.075663 +v -0.408188 0.620450 -0.076493 +v -0.472690 0.856063 0.005665 +v -0.469897 0.855271 0.005672 +v -0.471681 0.853973 0.004975 +v -0.467566 0.851778 0.004591 +v -0.680269 0.697976 -0.077060 +v -0.673267 0.686836 -0.080555 +v -0.684992 0.675659 -0.086154 +v -0.663973 0.684015 -0.080603 +v -0.689637 0.772147 -0.045222 +v -0.695779 0.764998 -0.048652 +v -0.712721 0.773727 -0.047189 +v -0.695172 0.752065 -0.053549 +v -0.482382 0.815160 -0.011120 +v -0.489383 0.826299 -0.007623 +v -0.480269 0.842335 -0.000451 +v -0.498678 0.829121 -0.007576 +v -0.475006 0.735836 -0.040104 +v -0.468863 0.742986 -0.036674 +v -0.452556 0.739668 -0.036130 +v -0.469471 0.755919 -0.031777 +v -0.472376 0.743260 -0.003459 +v -0.471769 0.730328 -0.008356 +v -0.455462 0.727010 -0.007812 +v -0.477911 0.723178 -0.011786 +v -0.501584 0.816463 0.020742 +v -0.492289 0.813641 0.020695 +v -0.483175 0.829677 0.027868 +v -0.485287 0.802502 0.017199 +v -0.698077 0.739407 -0.025231 +v -0.698685 0.752340 -0.020333 +v -0.715627 0.761069 -0.018870 +v -0.692542 0.759490 -0.016903 +v -0.666878 0.671357 -0.052284 +v -0.676173 0.674178 -0.052237 +v -0.687898 0.663001 -0.057836 +v -0.683174 0.685318 -0.048741 +v -0.442961 0.637043 -0.040497 +v -0.442353 0.624110 -0.045394 +v -0.425411 0.615380 -0.046857 +v -0.448496 0.616960 -0.048824 +v -0.473823 0.710244 -0.016296 +v -0.464528 0.707423 -0.016343 +v -0.452804 0.718601 -0.010744 +v -0.457527 0.696284 -0.019839 +v -0.668325 0.638341 -0.065122 +v -0.668932 0.651274 -0.060224 +v -0.685239 0.654592 -0.060768 +v -0.662790 0.658423 -0.056794 +v -0.633303 0.565139 -0.073899 +v -0.642597 0.567960 -0.073852 +v -0.651711 0.551924 -0.081024 +v -0.649599 0.579100 -0.070355 +v -0.646693 0.591757 -0.098674 +v -0.639691 0.580618 -0.102170 +v -0.648806 0.564582 -0.109343 +v -0.630397 0.577796 -0.102217 +v -0.659885 0.671081 -0.085112 +v -0.666027 0.663931 -0.088542 +v -0.682333 0.667249 -0.089087 +v -0.665420 0.650999 -0.093440 +v -0.454621 0.708941 -0.048158 +v -0.461623 0.720081 -0.044662 +v -0.449898 0.731258 -0.039063 +v -0.470917 0.722902 -0.044614 +v -0.445590 0.629618 -0.077142 +v -0.439448 0.636767 -0.073713 +v -0.422506 0.628038 -0.075175 +v -0.440056 0.649700 -0.068815 +v -0.659291 0.538196 -0.087140 +v -0.731745 0.762431 -0.020145 +v -0.409293 0.614019 -0.045583 +v -0.475595 0.843406 0.033984 +v -0.672664 0.549373 -0.090213 +v -0.706171 0.655375 -0.068674 +v -0.704284 0.663595 -0.087063 +v -0.670777 0.557593 -0.108602 +v -0.501584 0.816463 0.020742 +v -0.692542 0.759490 -0.016903 +v -0.689637 0.772147 -0.045222 +v -0.498678 0.829121 -0.007576 +v -0.736463 0.769158 -0.023961 +v -0.734576 0.777378 -0.042350 +v -0.733968 0.764445 -0.047248 +v -0.735855 0.756226 -0.028858 +v -0.659885 0.671081 -0.085112 +v -0.470917 0.722902 -0.044614 +v -0.473823 0.710244 -0.016296 +v -0.662790 0.658423 -0.056794 +v -0.698077 0.739407 -0.025231 +v -0.683174 0.685318 -0.048741 +v -0.680269 0.697976 -0.077060 +v -0.695172 0.752065 -0.053549 +v -0.666878 0.671357 -0.052284 +v -0.477911 0.723178 -0.011786 +v -0.475006 0.735836 -0.040104 +v -0.663973 0.684015 -0.080603 +v -0.431624 0.738884 -0.028225 +v -0.459317 0.844886 0.008738 +v -0.461204 0.836666 0.027127 +v -0.433511 0.730664 -0.009835 +v -0.454621 0.708941 -0.048158 +v -0.440056 0.649700 -0.068815 +v -0.442961 0.637043 -0.040497 +v -0.457527 0.696284 -0.019839 +v -0.646693 0.591757 -0.098674 +v -0.665420 0.650999 -0.093440 +v -0.668325 0.638341 -0.065122 +v -0.649599 0.579100 -0.070355 +v -0.402278 0.632882 -0.065187 +v -0.404165 0.624662 -0.046798 +v -0.472376 0.743260 -0.003459 +v -0.485287 0.802502 0.017199 +v -0.482382 0.815160 -0.011120 +v -0.469471 0.755919 -0.031777 +v -0.445590 0.629618 -0.077142 +v -0.630397 0.577796 -0.102217 +v -0.633303 0.565139 -0.073899 +v -0.448496 0.616960 -0.048824 +v -0.663775 0.546453 -0.112099 +v -0.665662 0.538234 -0.093709 +v -0.654481 0.543633 -0.112146 +v -0.407813 0.612800 -0.073515 +v -0.409699 0.604580 -0.055126 +v -0.656368 0.535412 -0.093756 +v -0.730320 0.776308 -0.020531 +v -0.728433 0.784527 -0.038920 +v -0.734576 0.777378 -0.042350 +v -0.736463 0.769158 -0.023961 +v -0.401670 0.619949 -0.070085 +v -0.403557 0.611730 -0.051696 +v -0.466318 0.856026 0.012234 +v -0.468205 0.847806 0.030624 +v -0.665662 0.538234 -0.093709 +v -0.663775 0.546453 -0.112099 +v -0.475613 0.858847 0.012281 +v -0.477499 0.850627 0.030671 +v -0.403557 0.611730 -0.051696 +v -0.401670 0.619949 -0.070085 +v -0.468205 0.847806 0.030624 +v -0.466318 0.856026 0.012234 +v -0.676173 0.674178 -0.052237 +v -0.673267 0.686836 -0.080555 +v -0.673267 0.686836 -0.080555 +v -0.676173 0.674178 -0.052237 +v -0.468863 0.742986 -0.036674 +v -0.471769 0.730328 -0.008356 +v -0.471769 0.730328 -0.008356 +v -0.468863 0.742986 -0.036674 +v -0.489383 0.826299 -0.007623 +v -0.492289 0.813641 0.020695 +v -0.492289 0.813641 0.020695 +v -0.489383 0.826299 -0.007623 +v -0.695779 0.764998 -0.048652 +v -0.698685 0.752340 -0.020333 +v -0.698685 0.752340 -0.020333 +v -0.695779 0.764998 -0.048652 +v -0.439448 0.636767 -0.073713 +v -0.442353 0.624110 -0.045394 +v -0.442353 0.624110 -0.045394 +v -0.439448 0.636767 -0.073713 +v -0.642597 0.567960 -0.073852 +v -0.639691 0.580618 -0.102170 +v -0.639691 0.580618 -0.102170 +v -0.642597 0.567960 -0.073852 +v -0.668932 0.651274 -0.060224 +v -0.666027 0.663931 -0.088542 +v -0.666027 0.663931 -0.088542 +v -0.668932 0.651274 -0.060224 +v -0.464528 0.707423 -0.016343 +v -0.461623 0.720081 -0.044662 +v -0.461623 0.720081 -0.044662 +v -0.464528 0.707423 -0.016343 +v -0.664825 0.537536 -0.089731 +v -0.670458 0.546436 -0.086942 +v -0.670458 0.546436 -0.086942 +v -0.664825 0.537536 -0.089731 +v -0.657435 0.535309 -0.089762 +v -0.664825 0.537536 -0.089731 +v -0.657435 0.535309 -0.089762 +v -0.735314 0.767477 -0.020325 +v -0.730421 0.773148 -0.017602 +v -0.730421 0.773148 -0.017602 +v -0.735314 0.767477 -0.020325 +v -0.734862 0.757124 -0.024250 +v -0.735314 0.767477 -0.020325 +v -0.734862 0.757124 -0.024250 +v -0.662218 0.548893 -0.115141 +v -0.654828 0.546667 -0.115173 +v -0.654828 0.546667 -0.115173 +v -0.662218 0.548893 -0.115141 +v -0.667851 0.557794 -0.112352 +v -0.662218 0.548893 -0.115141 +v -0.667851 0.557794 -0.112352 +v -0.732708 0.778834 -0.045736 +v -0.732255 0.768482 -0.049660 +v -0.732255 0.768482 -0.049660 +v -0.732708 0.778834 -0.045736 +v -0.727814 0.784505 -0.043013 +v -0.732708 0.778834 -0.045736 +v -0.727814 0.784505 -0.043013 +v -0.405426 0.610273 -0.048310 +v -0.410319 0.604602 -0.051033 +v -0.410319 0.604602 -0.051033 +v -0.405426 0.610273 -0.048310 +v -0.405878 0.620626 -0.044386 +v -0.405426 0.610273 -0.048310 +v -0.405878 0.620626 -0.044386 +v -0.469763 0.845366 0.033666 +v -0.464129 0.836466 0.030877 +v -0.464129 0.836466 0.030877 +v -0.469763 0.845366 0.033666 +v -0.477152 0.847592 0.033697 +v -0.469763 0.845366 0.033666 +v -0.477152 0.847592 0.033697 +v -0.402818 0.621631 -0.073720 +v -0.403270 0.631984 -0.069796 +v -0.403270 0.631984 -0.069796 +v -0.402818 0.621631 -0.073720 +v -0.407712 0.615960 -0.076443 +v -0.402818 0.621631 -0.073720 +v -0.407712 0.615960 -0.076443 +v -0.467155 0.856724 0.008256 +v -0.474545 0.858950 0.008287 +v -0.474545 0.858950 0.008287 +v -0.467155 0.856724 0.008256 +v -0.461522 0.847824 0.005467 +v -0.467155 0.856724 0.008256 +v -0.461522 0.847824 0.005467 +v -0.700039 0.655019 -0.062254 +v -0.704586 0.654351 -0.064737 +v -0.704586 0.654351 -0.064737 +v -0.697134 0.667676 -0.090572 +v -0.701979 0.665709 -0.090147 +v -0.701979 0.665709 -0.090147 +v -0.437756 0.739241 -0.034644 +v -0.433209 0.739908 -0.032161 +v -0.433209 0.739908 -0.032161 +v -0.440661 0.726583 -0.006326 +v -0.435816 0.728550 -0.006751 +v -0.435816 0.728550 -0.006751 +vt 0.047391 0.040890 +vt 0.047701 0.040806 +vt 0.047638 0.040647 +vt 0.029274 0.040317 +vt 0.029396 0.040502 +vt 0.029453 0.040345 +vt 0.980096 0.820034 +vt 0.979787 0.819951 +vt 0.980034 0.820193 +vt 0.047815 0.021372 +vt 0.047693 0.021187 +vt 0.047636 0.021344 +vt 0.980211 0.820215 +vt 0.962104 0.820246 +vt 0.961791 0.820339 +vt 0.961848 0.820496 +vt 0.961669 0.820524 +vt 0.029203 0.020090 +vt 0.028894 0.020174 +vt 0.028956 0.020333 +vt 0.979775 0.839747 +vt 0.980088 0.839654 +vt 0.980031 0.839497 +vt 0.980210 0.839469 +vt 0.961174 0.840487 +vt 0.961289 0.840668 +vt 0.961352 0.840509 +vt 0.961599 0.840751 +vt 0.968985 0.821813 +vt 0.969964 0.822048 +vt 0.970576 0.820938 +vt 0.970361 0.822646 +vt 0.963100 0.822987 +vt 0.963518 0.822375 +vt 0.962525 0.821369 +vt 0.964506 0.822108 +vt 0.964071 0.838809 +vt 0.963091 0.838574 +vt 0.962061 0.839613 +vt 0.962695 0.837975 +vt 0.970190 0.837441 +vt 0.969771 0.838054 +vt 0.970344 0.839144 +vt 0.968783 0.838321 +vt 0.036388 0.022521 +vt 0.037376 0.022788 +vt 0.037949 0.021698 +vt 0.037795 0.023400 +vt 0.030300 0.022867 +vt 0.030696 0.022268 +vt 0.029665 0.021228 +vt 0.031675 0.022033 +vt 0.032112 0.038734 +vt 0.031124 0.038467 +vt 0.030130 0.039472 +vt 0.030705 0.037854 +vt 0.037966 0.038195 +vt 0.037570 0.038794 +vt 0.038182 0.039903 +vt 0.036591 0.039028 +vt 0.044977 0.022956 +vt 0.045966 0.023223 +vt 0.046959 0.022217 +vt 0.046384 0.023835 +vt 0.038852 0.023418 +vt 0.039249 0.022819 +vt 0.038636 0.021709 +vt 0.040228 0.022584 +vt 0.040430 0.039092 +vt 0.039442 0.038825 +vt 0.038870 0.039915 +vt 0.039023 0.038212 +vt 0.046295 0.038113 +vt 0.045899 0.038712 +vt 0.046929 0.039751 +vt 0.044919 0.038947 +vt 0.977315 0.821893 +vt 0.978294 0.822128 +vt 0.979325 0.821089 +vt 0.978690 0.822727 +vt 0.971418 0.822629 +vt 0.971836 0.822017 +vt 0.971264 0.820926 +vt 0.972825 0.821749 +vt 0.972623 0.838257 +vt 0.971644 0.838023 +vt 0.971031 0.839132 +vt 0.971247 0.837424 +vt 0.978779 0.837006 +vt 0.978361 0.837618 +vt 0.979354 0.838624 +vt 0.977372 0.837885 +vt 0.047816 0.040625 +vt 0.029709 0.040596 +vt 0.047380 0.021093 +vt 0.028779 0.020355 +vt 0.999079 0.631766 +vt 0.998388 0.623421 +vt 0.996899 0.623274 +vt 0.997590 0.631619 +vt 0.999353 0.276347 +vt 0.999381 0.261666 +vt 0.997078 0.261740 +vt 0.997050 0.276422 +vt 0.999072 0.614161 +vt 0.997584 0.614014 +vt 0.997551 0.614999 +vt 0.999039 0.615146 +vt 0.997051 0.245725 +vt 0.997049 0.260165 +vt 0.999354 0.260143 +vt 0.999356 0.245702 +vt 0.209345 0.231133 +vt 0.209406 0.235619 +vt 0.211710 0.235612 +vt 0.211648 0.231126 +vt 0.528115 0.001431 +vt 0.528117 0.015854 +vt 0.530421 0.015877 +vt 0.530419 0.001454 +vt 0.127141 0.045332 +vt 0.127128 0.053862 +vt 0.128621 0.053772 +vt 0.128634 0.045242 +vt 0.934227 0.901879 +vt 0.934240 0.906624 +vt 0.936538 0.906765 +vt 0.936526 0.902021 +vt 0.929295 0.640142 +vt 0.929488 0.635539 +vt 0.927252 0.636092 +vt 0.927059 0.640695 +vt 0.127137 0.036765 +vt 0.128630 0.036674 +vt 0.938904 0.906766 +vt 0.938887 0.902059 +vt 0.936588 0.901911 +vt 0.936606 0.906618 +vt 0.999656 0.342882 +vt 0.999601 0.328999 +vt 0.997304 0.328816 +vt 0.997359 0.342700 +vt 0.997539 0.632599 +vt 0.999027 0.632746 +vt 0.985896 0.817646 +vt 0.985935 0.799008 +vt 0.984442 0.799101 +vt 0.984403 0.817738 +vt 0.921680 0.071641 +vt 0.920184 0.071600 +vt 0.920191 0.072294 +vt 0.921687 0.072334 +vt 0.985919 0.798316 +vt 0.984425 0.798409 +vt 0.127143 0.054842 +vt 0.128636 0.054752 +vt 0.984450 0.818229 +vt 0.985943 0.818136 +vt 0.920165 0.052195 +vt 0.921661 0.052236 +vt 0.128634 0.035688 +vt 0.127142 0.035778 +vt 0.921691 0.051746 +vt 0.920195 0.051706 +vt 0.209366 0.236598 +vt 0.211669 0.236591 +vt 0.530441 0.000964 +vt 0.528136 0.000941 +vt 0.936606 0.907604 +vt 0.938905 0.907751 +vt 0.528136 0.016548 +vt 0.530441 0.016570 +vt 0.997082 0.276914 +vt 0.999385 0.276839 +vt 0.938905 0.901078 +vt 0.936606 0.900930 +vt 0.211710 0.230141 +vt 0.209406 0.230148 +vt 0.999385 0.260974 +vt 0.997082 0.261048 +vt 0.934243 0.907610 +vt 0.936542 0.907751 +vt 0.997330 0.343393 +vt 0.999627 0.343575 +vt 0.927252 0.641656 +vt 0.929488 0.641103 +vt 0.999656 0.328512 +vt 0.997359 0.328329 +vt 0.999375 0.245010 +vt 0.997071 0.245033 +vt 0.929313 0.634567 +vt 0.927078 0.635121 +vt 0.936542 0.901040 +vt 0.934243 0.900898 +vt 0.997071 0.260658 +vt 0.999375 0.260635 +vt 0.999309 0.632732 +vt 0.999351 0.631949 +vt 0.047013 0.041253 +vt 0.047796 0.041063 +vt 0.984123 0.817742 +vt 0.984160 0.818133 +vt 0.048110 0.040586 +vt 0.921976 0.072248 +vt 0.921971 0.071697 +vt 0.028965 0.040269 +vt 0.029297 0.040756 +vt 0.999324 0.615016 +vt 0.999351 0.614228 +vt 0.030088 0.040972 +vt 0.986224 0.818005 +vt 0.986187 0.817614 +vt 0.980519 0.820251 +vt 0.980205 0.819775 +vt 0.997294 0.631746 +vt 0.997252 0.632530 +vt 0.979422 0.819584 +vt 0.997294 0.614025 +vt 0.997267 0.614813 +vt 0.962496 0.819867 +vt 0.961705 0.820083 +vt 0.919904 0.071641 +vt 0.919909 0.072192 +vt 0.961374 0.820570 +vt 0.984147 0.798520 +vt 0.984160 0.799071 +vt 0.048110 0.021418 +vt 0.047779 0.020931 +vt 0.128920 0.036498 +vt 0.128924 0.035709 +vt 0.046988 0.020715 +vt 0.128925 0.054693 +vt 0.128913 0.053909 +vt 0.029568 0.019724 +vt 0.028785 0.019914 +vt 0.921953 0.052258 +vt 0.921976 0.051868 +vt 0.028471 0.020391 +vt 0.126861 0.035834 +vt 0.126857 0.036623 +vt 0.979397 0.840124 +vt 0.980187 0.839907 +vt 0.986224 0.798943 +vt 0.986211 0.798392 +vt 0.980519 0.839420 +vt 0.919909 0.051812 +vt 0.919886 0.052202 +vt 0.960880 0.840448 +vt 0.961194 0.840925 +vt 0.126850 0.054034 +vt 0.126862 0.054818 +vt 0.961977 0.841115 +vt 0.038545 0.040966 +vt 0.038545 0.041334 +vt 0.998666 0.623447 +vt 0.970939 0.819875 +vt 0.970953 0.819505 +vt 0.996610 0.623245 +vt 0.970668 0.840195 +vt 0.970669 0.840562 +vt 0.126862 0.045347 +vt 0.038273 0.020646 +vt 0.038260 0.020276 +vt 0.128925 0.045222 +vn -0.3048 -0.3768 0.8747 +vn -0.2383 -0.5445 0.8042 +vn -0.1004 -0.3199 0.9421 +vn -0.2515 -0.1653 0.9536 +vn -0.3372 -0.2445 0.9091 +vn -0.0950 -0.3647 0.9263 +vn -0.0361 0.1529 -0.9876 +vn -0.0578 0.1986 -0.9784 +vn 0.1004 0.3198 -0.9421 +vn 0.0923 -0.5235 0.8470 +vn 0.1427 -0.4493 0.8819 +vn -0.0846 -0.3508 0.9326 +vn 0.0556 0.1162 -0.9917 +vn -0.1149 0.3585 -0.9264 +vn -0.1427 0.4493 -0.8819 +vn 0.0949 0.3647 -0.9263 +vn -0.0758 0.5271 -0.8464 +vn 0.0801 -0.2614 0.9619 +vn 0.0362 -0.1528 0.9876 +vn -0.0975 -0.3536 0.9303 +vn 0.3102 0.3536 -0.8825 +vn 0.3374 0.2445 -0.9091 +vn 0.0847 0.3508 -0.9326 +vn 0.2324 0.1595 -0.9595 +vn 0.1067 0.5758 -0.8106 +vn 0.2382 0.5445 -0.8042 +vn 0.0975 0.3536 -0.9303 +vn 0.2866 0.4325 -0.8549 +vn 0.6834 0.4999 -0.5320 +vn 0.4569 0.7197 -0.5228 +vn 0.0998 0.3703 -0.9235 +vn 0.0649 0.8759 -0.4780 +vn 0.4236 -0.2038 -0.8826 +vn 0.6475 0.0891 -0.7569 +vn 0.0915 0.3693 -0.9248 +vn 0.7512 0.3452 -0.5627 +vn -0.5301 0.0588 -0.8459 +vn -0.2657 -0.1366 -0.9543 +vn 0.0956 0.3523 -0.9310 +vn 0.0878 -0.2784 -0.9564 +vn -0.2942 0.7771 -0.5563 +vn -0.5056 0.4721 -0.7222 +vn 0.1037 0.3545 -0.9293 +vn -0.6051 0.1987 -0.7709 +vn -0.7532 -0.3088 0.5808 +vn -0.6475 -0.0891 0.7568 +vn -0.1037 -0.3545 0.9293 +vn -0.4278 0.1968 0.8822 +vn -0.0482 -0.8754 0.4810 +vn -0.4568 -0.7198 0.5227 +vn -0.0956 -0.3523 0.9310 +vn -0.6997 -0.4633 0.5439 +vn 0.5942 -0.2181 0.7742 +vn 0.5056 -0.4720 0.7222 +vn -0.0915 -0.3694 0.9248 +vn 0.3088 -0.7693 0.5593 +vn -0.0952 0.2825 0.9545 +vn 0.2657 0.1366 0.9543 +vn -0.0998 -0.3703 0.9235 +vn 0.5485 -0.0657 0.8336 +vn -0.7493 -0.3180 0.5808 +vn -0.0779 -0.3485 0.9341 +vn -0.3923 0.2181 0.8936 +vn -0.0649 -0.8759 0.4780 +vn -0.4569 -0.7197 0.5228 +vn -0.1030 -0.3549 0.9292 +vn -0.6985 -0.4721 0.5378 +vn 0.5835 -0.0773 0.8084 +vn 0.5056 -0.4721 0.7222 +vn -0.1256 -0.3114 0.9419 +vn 0.2943 -0.7771 0.5564 +vn -0.0526 0.2831 0.9577 +vn -0.1029 -0.3000 0.9484 +vn 0.4719 0.0520 0.8801 +vn 0.7552 0.4354 -0.4899 +vn 0.1029 0.3000 -0.9484 +vn 0.0340 0.8810 -0.4719 +vn 0.4279 -0.1968 -0.8821 +vn 0.6475 0.0891 -0.7568 +vn 0.1256 0.3114 -0.9419 +vn 0.7383 0.2779 -0.6145 +vn -0.5316 0.0505 -0.8455 +vn 0.1030 0.3549 -0.9292 +vn 0.0952 -0.2824 -0.9546 +vn -0.3165 0.7589 -0.5691 +vn 0.0779 0.3485 -0.9341 +vn -0.6006 0.1924 -0.7761 +vn -0.0915 -0.5711 0.8158 +vn -0.3036 -0.3737 0.8765 +vn 0.1078 -0.3400 0.9342 +vn -0.0763 -0.1203 0.9898 +vn -0.9179 -0.3967 -0.0112 +vn -0.9537 -0.2997 0.0239 +vn -0.8919 -0.1467 -0.4278 +vn -0.8588 -0.2716 -0.4344 +vn -0.0482 -0.8754 0.4809 +vn 0.3087 -0.7693 0.5593 +vn 0.4235 -0.2038 -0.8827 +vn -0.9523 0.2349 0.1951 +vn -0.9231 0.3634 -0.1260 +vn -0.9360 -0.0366 -0.3502 +vn -0.9773 -0.2048 0.0535 +vn 0.4278 -0.1968 -0.8822 +vn 0.2942 -0.7771 0.5564 +vn 0.5942 -0.2180 0.7742 +vn 0.7511 0.3452 -0.5627 +vn -0.0952 0.2824 0.9546 +vn -0.4279 0.1968 0.8822 +vn -0.2942 0.7771 -0.5564 +vn 0.9603 0.2749 -0.0471 +vn 0.9263 0.3766 0.0140 +vn 0.8768 0.2150 0.4302 +vn 0.9075 0.1023 0.4073 +vn -0.5315 0.0505 -0.8455 +vn 0.7553 0.4354 -0.4899 +vn 0.7384 0.2778 -0.6145 +vn 0.5835 -0.0774 0.8084 +vn 0.9796 0.1938 -0.0526 +vn 0.9343 0.0370 0.3546 +vn -0.7532 -0.3089 0.5808 +vn -0.6996 -0.4634 0.5439 +vn -0.5301 0.0589 -0.8459 +vn -0.6052 0.1987 -0.7709 +vn -0.0526 0.2830 0.9577 +vn -0.3924 0.2181 0.8936 +vn -0.5756 -0.6235 -0.5291 +vn -0.6176 -0.7598 -0.2032 +vn 0.0440 -0.8280 -0.5590 +vn 0.5602 -0.6930 -0.4537 +vn 0.5394 -0.8342 -0.1146 +vn 0.0186 -0.9754 -0.2195 +vn -0.5742 0.6863 0.4464 +vn -0.5472 0.8298 0.1096 +vn -0.9230 0.3634 -0.1260 +vn -0.9522 0.2349 0.1951 +vn 0.9523 -0.2349 -0.1950 +vn 0.9230 -0.3634 0.1261 +vn 0.6176 0.7598 0.2032 +vn 0.5757 0.6234 0.5291 +vn -0.0286 0.9749 0.2208 +vn -0.0606 0.8263 0.5599 +vn 0.9230 -0.3635 0.1261 +vn 0.6175 0.7599 0.2032 +vn 0.2658 0.1366 0.9543 +vn 0.4568 0.7197 -0.5228 +vn -0.5056 0.4720 -0.7222 +vn -0.6475 -0.0890 0.7568 +vn -0.6475 -0.0892 0.7568 +vn -0.2658 -0.1365 -0.9543 +vn -0.4568 -0.7197 0.5227 +vn -0.5056 0.4721 -0.7221 +vn 0.2657 0.1365 0.9543 +vn 0.4569 0.7197 -0.5227 +vn 0.2658 0.1365 0.9543 +vn 0.6475 0.0890 -0.7569 +vn 0.5056 -0.4721 0.7221 +vn -0.2657 -0.1365 -0.9543 +vn -0.2656 -0.1366 -0.9543 +vn -0.4568 -0.7197 0.5228 +vn -0.5222 -0.7899 0.3216 +vn -0.6992 -0.4641 0.5438 +vn -0.6993 -0.4641 0.5437 +vn -0.0433 -0.9406 0.3366 +vn -0.0432 -0.9407 0.3365 +vn -0.7833 0.0092 0.6216 +vn -0.4950 0.3239 0.8063 +vn -0.4950 0.3239 0.8062 +vn -0.7833 0.0094 0.6215 +vn -0.7460 -0.3396 0.5728 +vn -0.7833 0.0093 0.6216 +vn -0.7460 -0.3396 0.5729 +vn -0.3805 -0.3023 -0.8740 +vn 0.0539 -0.4408 -0.8960 +vn -0.3805 -0.3024 -0.8740 +vn -0.5437 -0.0573 -0.8373 +vn -0.5438 -0.0574 -0.8373 +vn -0.6644 0.4842 -0.5693 +vn -0.6218 0.2038 -0.7562 +vn -0.3869 0.8214 -0.4191 +vn -0.6644 0.4842 -0.5694 +vn 0.6644 -0.4842 0.5694 +vn 0.3923 -0.8214 0.4140 +vn 0.6644 -0.4842 0.5693 +vn 0.6096 -0.1941 0.7686 +vn 0.6643 -0.4842 0.5694 +vn 0.6095 -0.1942 0.7686 +vn 0.3804 0.3023 0.8740 +vn 0.5494 -0.0240 0.8352 +vn 0.3805 0.3024 0.8739 +vn -0.0759 0.4371 0.8962 +vn 0.3804 0.3022 0.8740 +vn 0.7833 -0.0093 -0.6215 +vn 0.7572 0.3190 -0.5700 +vn 0.7833 -0.0093 -0.6216 +vn 0.4758 -0.3307 -0.8151 +vn 0.7834 -0.0093 -0.6215 +vn 0.4757 -0.3306 -0.8151 +vn 0.5221 0.7899 -0.3217 +vn 0.0460 0.9428 -0.3302 +vn 0.0460 0.9429 -0.3300 +vn 0.5221 0.7899 -0.3216 +vn 0.7067 0.4941 -0.5064 +vn 0.7067 0.4942 -0.5064 +vn -0.2537 -0.3483 0.9024 +vn -0.6996 -0.3910 0.5981 +vn -0.0469 0.2759 -0.9600 +vn -0.5332 0.0885 -0.8414 +vn -0.5332 0.0885 -0.8413 +vn 0.2512 0.3788 -0.8907 +vn 0.6962 0.3965 -0.5984 +vn 0.0442 -0.3184 0.9469 +vn 0.5329 -0.1467 0.8334 +vn 0.5330 -0.1466 0.8333 +usemtl Scene_-_Root +s 1 +f 20281/20281/14479 20282/20282/14480 20283/20283/14481 +f 20284/20284/14482 20285/20285/14483 20286/20286/14484 +f 20287/20287/14485 20288/20288/14486 20289/20289/14487 +f 20290/20290/14488 20291/20291/14489 20292/20292/14490 +f 20293/20293/14491 20287/20287/14485 20289/20289/14487 +f 20294/20294/14492 20295/20295/14493 20296/20296/14494 +f 20295/20295/14493 20297/20297/14495 20296/20296/14494 +f 20298/20298/14496 20299/20299/14497 20300/20300/14498 +f 20301/20301/14499 20302/20302/14500 20303/20303/14501 +f 20302/20302/14500 20304/20304/14502 20303/20303/14501 +f 20305/20305/14503 20306/20306/14504 20307/20307/14505 +f 20306/20306/14504 20308/20308/14506 20307/20307/14505 +f 20309/20309/14507 20310/20310/14508 20311/20311/14509 +f 20310/20310/14508 20312/20312/14510 20311/20311/14509 +f 20313/20313/14511 20314/20314/14512 20315/20315/14513 +f 20314/20314/14512 20316/20316/14514 20315/20315/14513 +f 20317/20317/14515 20318/20318/14516 20319/20319/14517 +f 20318/20318/14516 20320/20320/14518 20319/20319/14517 +f 20321/20321/14519 20322/20322/14520 20323/20323/14521 +f 20322/20322/14520 20324/20324/14522 20323/20323/14521 +f 20325/20325/14523 20326/20326/14524 20327/20327/14525 +f 20326/20326/14524 20328/20328/14526 20327/20327/14525 +f 20329/20329/14527 20330/20330/14528 20331/20331/14529 +f 20330/20330/14528 20332/20332/14530 20331/20331/14529 +f 20333/20333/14531 20334/20334/14532 20335/20335/14533 +f 20334/20334/14532 20336/20336/14534 20335/20335/14533 +f 20337/20337/14535 20338/20338/14536 20339/20339/14537 +f 20338/20338/14536 20340/20340/14538 20339/20339/14537 +f 20341/20341/14539 20342/20342/14524 20343/20343/14540 +f 20342/20342/14524 20344/20344/14541 20343/20343/14540 +f 20345/20345/14542 20346/20346/14543 20347/20347/14544 +f 20346/20346/14543 20348/20348/14545 20347/20347/14544 +f 20349/20349/14546 20350/20350/14547 20351/20351/14548 +f 20350/20350/14547 20352/20352/14549 20351/20351/14548 +f 20353/20353/14550 20354/20354/14536 20355/20355/14551 +f 20354/20354/14536 20356/20356/14552 20355/20355/14551 +f 20357/20357/14553 20358/20358/14508 20359/20359/14554 +f 20358/20358/14508 20360/20360/14555 20359/20359/14554 +f 20361/20361/14556 20362/20362/14557 20363/20363/14558 +f 20362/20362/14557 20364/20364/14559 20363/20363/14558 +f 20365/20365/14560 20366/20366/14516 20367/20367/14561 +f 20366/20366/14516 20368/20368/14562 20367/20367/14561 +f 20369/20369/14563 20370/20370/14520 20371/20371/14564 +f 20370/20370/14520 20372/20372/14565 20371/20371/14564 +f 20282/20282/14480 20373/20373/14566 20283/20283/14481 +f 20285/20285/14483 20374/20374/14567 20286/20286/14484 +f 20291/20291/14489 20375/20375/14568 20292/20292/14490 +f 20299/20299/14497 20376/20376/14569 20300/20300/14498 +f 20377/20377/14570 20378/20378/14571 20379/20379/14572 +f 20377/20377/14570 20379/20379/14572 20380/20380/14573 +f 20381/20381/14574 20382/20382/14575 20383/20383/14576 +f 20381/20381/14574 20383/20383/14576 20384/20384/14518 +f 20385/20385/14577 20386/20386/14578 20387/20387/14579 +f 20385/20385/14577 20387/20387/14579 20388/20388/14580 +f 20389/20389/14581 20390/20390/14562 20391/20391/14542 +f 20389/20389/14581 20391/20391/14542 20392/20392/14582 +f 20393/20393/14583 20394/20394/14538 20395/20395/14507 +f 20393/20393/14583 20395/20395/14507 20396/20396/14584 +f 20397/20397/14585 20398/20398/14586 20399/20399/14587 +f 20397/20397/14585 20399/20399/14587 20400/20400/14510 +f 20401/20401/14588 20402/20402/14589 20403/20403/14590 +f 20401/20401/14588 20403/20403/14590 20404/20404/14591 +f 20405/20405/14592 20406/20406/14565 20407/20407/14539 +f 20405/20405/14592 20407/20407/14539 20408/20408/14545 +f 20409/20409/14593 20410/20410/14594 20411/20411/14595 +f 20409/20409/14593 20411/20411/14595 20412/20412/14552 +f 20413/20413/14596 20401/20401/14588 20404/20404/14591 +f 20413/20413/14596 20404/20404/14591 20414/20414/14597 +f 20415/20415/14598 20416/20416/14599 20417/20417/14600 +f 20415/20415/14598 20417/20417/14600 20418/20418/14601 +f 20378/20378/14571 20388/20388/14580 20387/20387/14579 +f 20378/20378/14571 20387/20387/14579 20379/20379/14572 +f 20419/20419/14563 20420/20420/14555 20421/20421/14602 +f 20419/20419/14563 20421/20421/14602 20422/20422/14603 +f 20423/20423/14604 20424/20424/14605 20377/20377/14570 +f 20423/20423/14604 20377/20377/14570 20380/20380/14573 +f 20425/20425/14606 20426/20426/14607 20427/20427/14608 +f 20425/20425/14606 20427/20427/14608 20428/20428/14609 +f 20429/20429/14610 20430/20430/14611 20431/20431/14612 +f 20429/20429/14610 20431/20431/14612 20432/20432/14613 +f 20427/20427/14608 20426/20426/14607 20433/20433/14614 +f 20427/20427/14608 20433/20433/14614 20434/20434/14615 +f 20435/20435/14616 20436/20436/14617 20403/20403/14590 +f 20435/20435/14616 20403/20403/14590 20402/20402/14589 +f 20425/20425/14606 20428/20428/14609 20437/20437/14605 +f 20425/20425/14606 20437/20437/14605 20438/20438/14604 +f 20439/20439/14618 20430/20430/14611 20429/20429/14610 +f 20439/20439/14618 20429/20429/14610 20440/20440/14619 +f 20441/20441/14620 20442/20442/14614 20413/20413/14596 +f 20441/20441/14620 20413/20413/14596 20414/20414/14597 +f 20439/20439/14618 20440/20440/14619 20443/20443/14617 +f 20439/20439/14618 20443/20443/14617 20444/20444/14621 +f 20395/20395/14507 20394/20394/14538 20445/20445/14622 +f 20395/20395/14507 20445/20445/14622 20446/20446/14623 +f 20447/20447/14623 20448/20448/14536 20397/20397/14585 +f 20447/20447/14623 20397/20397/14585 20400/20400/14510 +f 20415/20415/14598 20418/20418/14601 20449/20449/14624 +f 20415/20415/14598 20449/20449/14624 20450/20450/14625 +f 20451/20451/14626 20452/20452/14520 20399/20399/14587 +f 20451/20451/14626 20399/20399/14587 20398/20398/14586 +f 20381/20381/14574 20384/20384/14518 20453/20453/14627 +f 20381/20381/14574 20453/20453/14627 20454/20454/14528 +f 20455/20455/14628 20456/20456/14627 20417/20417/14600 +f 20455/20455/14628 20417/20417/14600 20416/20416/14599 +f 20393/20393/14583 20396/20396/14584 20457/20457/14512 +f 20393/20393/14583 20457/20457/14512 20458/20458/14532 +f 20459/20459/14547 20460/20460/14557 20383/20383/14576 +f 20459/20459/14547 20383/20383/14576 20382/20382/14575 +f 20407/20407/14539 20406/20406/14565 20461/20461/14629 +f 20407/20407/14539 20461/20461/14629 20462/20462/14524 +f 20463/20463/14524 20464/20464/14520 20419/20419/14563 +f 20463/20463/14524 20419/20419/14563 20422/20422/14603 +f 20409/20409/14593 20412/20412/14552 20465/20465/14630 +f 20409/20409/14593 20465/20465/14630 20466/20466/14631 +f 20467/20467/14623 20468/20468/14632 20421/20421/14602 +f 20467/20467/14623 20421/20421/14602 20420/20420/14555 +f 20389/20389/14581 20392/20392/14582 20469/20469/14547 +f 20389/20389/14581 20469/20469/14547 20470/20470/14512 +f 20471/20471/14633 20472/20472/14634 20411/20411/14595 +f 20471/20471/14633 20411/20411/14595 20410/20410/14594 +f 20405/20405/14592 20408/20408/14545 20473/20473/14543 +f 20405/20405/14592 20473/20473/14543 20474/20474/14635 +f 20475/20475/14636 20476/20476/14637 20391/20391/14542 +f 20475/20475/14636 20391/20391/14542 20390/20390/14562 +f 20377/20377/14570 20424/20424/14605 20477/20477/14638 +f 20377/20377/14570 20477/20477/14638 20478/20478/14639 +f 20479/20479/14640 20480/20480/14638 20282/20282/14480 +f 20479/20479/14640 20282/20282/14480 20281/20281/14479 +f 20437/20437/14605 20428/20428/14609 20481/20481/14641 +f 20437/20437/14605 20481/20481/14641 20482/20482/14638 +f 20480/20480/14638 20483/20483/14642 20373/20373/14566 +f 20480/20480/14638 20373/20373/14566 20282/20282/14480 +f 20429/20429/14610 20432/20432/14613 20484/20484/14643 +f 20429/20429/14610 20484/20484/14643 20485/20485/14644 +f 20486/20486/14645 20487/20487/14646 20285/20285/14483 +f 20486/20486/14645 20285/20285/14483 20284/20284/14482 +f 20385/20385/14577 20388/20388/14580 20488/20488/14647 +f 20385/20385/14577 20488/20488/14647 20489/20489/14648 +f 20487/20487/14646 20490/20490/14649 20374/20374/14567 +f 20487/20487/14646 20374/20374/14567 20285/20285/14483 +f 20425/20425/14606 20438/20438/14604 20491/20491/14650 +f 20425/20425/14606 20491/20491/14650 20492/20492/14651 +f 20493/20493/14651 20494/20494/14652 20287/20287/14485 +f 20493/20493/14651 20287/20287/14485 20293/20293/14491 +f 20423/20423/14604 20380/20380/14573 20495/20495/14653 +f 20423/20423/14604 20495/20495/14653 20496/20496/14650 +f 20494/20494/14652 20497/20497/14654 20288/20288/14486 +f 20494/20494/14652 20288/20288/14486 20287/20287/14485 +f 20387/20387/14579 20386/20386/14578 20498/20498/14655 +f 20387/20387/14579 20498/20498/14655 20499/20499/14656 +f 20500/20500/14656 20501/20501/14655 20295/20295/14493 +f 20500/20500/14656 20295/20295/14493 20294/20294/14492 +f 20431/20431/14612 20430/20430/14611 20502/20502/14657 +f 20431/20431/14612 20502/20502/14657 20503/20503/14658 +f 20501/20501/14655 20504/20504/14657 20297/20297/14495 +f 20501/20501/14655 20297/20297/14495 20295/20295/14493 +f 20427/20427/14608 20434/20434/14615 20505/20505/14659 +f 20427/20427/14608 20505/20505/14659 20506/20506/14660 +f 20507/20507/14660 20508/20508/14661 20291/20291/14489 +f 20507/20507/14660 20291/20291/14489 20290/20290/14488 +f 20441/20441/14620 20414/20414/14597 20509/20509/14662 +f 20441/20441/14620 20509/20509/14662 20510/20510/14663 +f 20508/20508/14661 20511/20511/14664 20375/20375/14568 +f 20508/20508/14661 20375/20375/14568 20291/20291/14489 +f 20403/20403/14590 20436/20436/14617 20512/20512/14665 +f 20403/20403/14590 20512/20512/14665 20513/20513/14666 +f 20514/20514/14666 20515/20515/14667 20299/20299/14497 +f 20514/20514/14666 20299/20299/14497 20298/20298/14496 +f 20443/20443/14617 20440/20440/14619 20516/20516/14668 +f 20443/20443/14617 20516/20516/14668 20517/20517/14669 +f 20515/20515/14667 20518/20518/14668 20376/20376/14569 +f 20515/20515/14667 20376/20376/14569 20299/20299/14497 +f 20413/20413/14596 20442/20442/14614 20519/20519/14670 +f 20413/20413/14596 20519/20519/14670 20520/20520/14671 +f 20521/20521/14671 20522/20522/14672 20302/20302/14500 +f 20521/20521/14671 20302/20302/14500 20301/20301/14499 +f 20433/20433/14614 20426/20426/14607 20523/20523/14673 +f 20433/20433/14614 20523/20523/14673 20524/20524/14674 +f 20522/20522/14672 20525/20525/14675 20304/20304/14502 +f 20522/20522/14672 20304/20304/14502 20302/20302/14500 +f 20439/20439/14618 20444/20444/14621 20526/20526/14676 +f 20439/20439/14618 20526/20526/14676 20527/20527/14677 +f 20528/20528/14678 20529/20529/14679 20306/20306/14504 +f 20528/20528/14678 20306/20306/14504 20305/20305/14503 +f 20435/20435/14616 20402/20402/14589 20530/20530/14680 +f 20435/20435/14616 20530/20530/14680 20531/20531/14679 +f 20529/20529/14679 20532/20532/14681 20308/20308/14506 +f 20529/20529/14679 20308/20308/14506 20306/20306/14504 +f 20281/20281/14479 20533/20533/14682 20534/20534/14683 +f 20281/20281/14479 20534/20534/14683 20479/20479/14640 +f 20478/20478/14639 20535/20535/14683 20378/20378/14571 +f 20478/20478/14639 20378/20378/14571 20377/20377/14570 +f 20536/20536/14684 20288/20288/14486 20497/20497/14654 +f 20536/20536/14684 20497/20497/14654 20537/20537/14685 +f 20538/20538/14686 20495/20495/14653 20380/20380/14573 +f 20538/20538/14686 20380/20380/14573 20379/20379/14572 +f 20293/20293/14491 20304/20304/14502 20525/20525/14675 +f 20293/20293/14491 20525/20525/14675 20493/20493/14651 +f 20492/20492/14651 20523/20523/14673 20426/20426/14607 +f 20492/20492/14651 20426/20426/14607 20425/20425/14606 +f 20290/20290/14488 20373/20373/14566 20483/20483/14642 +f 20290/20290/14488 20483/20483/14642 20507/20507/14660 +f 20506/20506/14660 20481/20481/14641 20428/20428/14609 +f 20506/20506/14660 20428/20428/14609 20427/20427/14608 +f 20388/20388/14580 20378/20378/14571 20535/20535/14683 +f 20388/20388/14580 20535/20535/14683 20488/20488/14647 +f 20490/20490/14649 20534/20534/14683 20533/20533/14682 +f 20490/20490/14649 20533/20533/14682 20374/20374/14567 +f 20294/20294/14492 20536/20536/14684 20537/20537/14685 +f 20294/20294/14492 20537/20537/14685 20500/20500/14656 +f 20499/20499/14656 20538/20538/14686 20379/20379/14572 +f 20499/20499/14656 20379/20379/14572 20387/20387/14579 +f 20305/20305/14503 20297/20297/14495 20504/20504/14657 +f 20305/20305/14503 20504/20504/14657 20528/20528/14678 +f 20527/20527/14677 20502/20502/14657 20430/20430/14611 +f 20527/20527/14677 20430/20430/14611 20439/20439/14618 +f 20284/20284/14482 20376/20376/14569 20518/20518/14668 +f 20284/20284/14482 20518/20518/14668 20486/20486/14645 +f 20485/20485/14644 20516/20516/14668 20440/20440/14619 +f 20485/20485/14644 20440/20440/14619 20429/20429/14610 +f 20301/20301/14499 20539/20539/14687 20540/20540/14688 +f 20301/20301/14499 20540/20540/14688 20521/20521/14671 +f 20520/20520/14671 20541/20541/14688 20401/20401/14588 +f 20520/20520/14671 20401/20401/14588 20413/20413/14596 +f 20542/20542/14689 20375/20375/14568 20511/20511/14664 +f 20542/20542/14689 20511/20511/14664 20543/20543/14690 +f 20544/20544/14691 20509/20509/14662 20414/20414/14597 +f 20544/20544/14691 20414/20414/14597 20404/20404/14591 +f 20539/20539/14687 20308/20308/14506 20532/20532/14681 +f 20539/20539/14687 20532/20532/14681 20540/20540/14688 +f 20541/20541/14688 20530/20530/14680 20402/20402/14589 +f 20541/20541/14688 20402/20402/14589 20401/20401/14588 +f 20298/20298/14496 20542/20542/14689 20543/20543/14690 +f 20298/20298/14496 20543/20543/14690 20514/20514/14666 +f 20513/20513/14666 20544/20544/14691 20404/20404/14591 +f 20513/20513/14666 20404/20404/14591 20403/20403/14590 +f 20329/20329/14527 20335/20335/14533 20336/20336/14534 +f 20335/20335/14533 20329/20329/14527 20286/20286/14484 +f 20286/20286/14484 20329/20329/14527 20284/20284/14482 +f 20284/20284/14482 20329/20329/14527 20376/20376/14569 +f 20376/20376/14569 20329/20329/14527 20331/20331/14529 +f 20376/20376/14569 20331/20331/14529 20300/20300/14498 +f 20294/20294/14492 20311/20311/14509 20536/20536/14684 +f 20311/20311/14509 20294/20294/14492 20309/20309/14507 +f 20309/20309/14507 20294/20294/14492 20316/20316/14514 +f 20316/20316/14514 20294/20294/14492 20315/20315/14513 +f 20315/20315/14513 20294/20294/14492 20296/20296/14494 +f 20542/20542/14689 20325/20325/14523 20327/20327/14525 +f 20325/20325/14523 20542/20542/14689 20298/20298/14496 +f 20325/20325/14523 20298/20298/14496 20332/20332/14530 +f 20332/20332/14530 20298/20298/14496 20331/20331/14529 +f 20331/20331/14529 20298/20298/14496 20300/20300/14498 +f 20311/20311/14509 20539/20539/14687 20536/20536/14684 +f 20539/20539/14687 20311/20311/14509 20312/20312/14510 +f 20539/20539/14687 20312/20312/14510 20321/20321/14519 +f 20539/20539/14687 20321/20321/14519 20323/20323/14521 +f 20371/20371/14564 20301/20301/14499 20303/20303/14501 +f 20301/20301/14499 20371/20371/14564 20539/20539/14687 +f 20539/20539/14687 20371/20371/14564 20372/20372/14565 +f 20539/20539/14687 20372/20372/14565 20365/20365/14560 +f 20539/20539/14687 20365/20365/14560 20367/20367/14561 +f 20288/20288/14486 20359/20359/14554 20289/20289/14487 +f 20359/20359/14554 20288/20288/14486 20536/20536/14684 +f 20359/20359/14554 20536/20536/14684 20357/20357/14553 +f 20357/20357/14553 20536/20536/14684 20364/20364/14559 +f 20364/20364/14559 20536/20536/14684 20363/20363/14558 +f 20375/20375/14568 20343/20343/14540 20292/20292/14490 +f 20343/20343/14540 20375/20375/14568 20542/20542/14689 +f 20343/20343/14540 20542/20542/14689 20341/20341/14539 +f 20341/20341/14539 20542/20542/14689 20348/20348/14545 +f 20348/20348/14545 20542/20542/14689 20347/20347/14544 +f 20339/20339/14537 20374/20374/14567 20533/20533/14682 +f 20374/20374/14567 20339/20339/14537 20340/20340/14538 +f 20374/20374/14567 20340/20340/14538 20333/20333/14531 +f 20374/20374/14567 20333/20333/14531 20335/20335/14533 +f 20374/20374/14567 20335/20335/14533 20286/20286/14484 +f 20324/20324/14522 20539/20539/14687 20323/20323/14521 +f 20539/20539/14687 20324/20324/14522 20308/20308/14506 +f 20308/20308/14506 20324/20324/14522 20317/20317/14515 +f 20308/20308/14506 20317/20317/14515 20319/20319/14517 +f 20308/20308/14506 20319/20319/14517 20307/20307/14505 +f 20290/20290/14488 20283/20283/14481 20373/20373/14566 +f 20283/20283/14481 20290/20290/14488 20355/20355/14551 +f 20355/20355/14551 20290/20290/14488 20353/20353/14550 +f 20353/20353/14550 20290/20290/14488 20344/20344/14541 +f 20344/20344/14541 20290/20290/14488 20292/20292/14490 +f 20344/20344/14541 20292/20292/14490 20343/20343/14540 +f 20542/20542/14689 20339/20339/14537 20533/20533/14682 +f 20339/20339/14537 20542/20542/14689 20337/20337/14535 +f 20337/20337/14535 20542/20542/14689 20328/20328/14526 +f 20328/20328/14526 20542/20542/14689 20327/20327/14525 +f 20539/20539/14687 20363/20363/14558 20536/20536/14684 +f 20363/20363/14558 20539/20539/14687 20361/20361/14556 +f 20361/20361/14556 20539/20539/14687 20368/20368/14562 +f 20368/20368/14562 20539/20539/14687 20367/20367/14561 +f 20289/20289/14487 20304/20304/14502 20293/20293/14491 +f 20304/20304/14502 20289/20289/14487 20359/20359/14554 +f 20304/20304/14502 20359/20359/14554 20360/20360/14555 +f 20304/20304/14502 20360/20360/14555 20369/20369/14563 +f 20304/20304/14502 20369/20369/14563 20303/20303/14501 +f 20303/20303/14501 20369/20369/14563 20371/20371/14564 +f 20315/20315/14513 20320/20320/14518 20313/20313/14511 +f 20320/20320/14518 20315/20315/14513 20296/20296/14494 +f 20320/20320/14518 20296/20296/14494 20297/20297/14495 +f 20320/20320/14518 20297/20297/14495 20305/20305/14503 +f 20320/20320/14518 20305/20305/14503 20319/20319/14517 +f 20319/20319/14517 20305/20305/14503 20307/20307/14505 +f 20355/20355/14551 20281/20281/14479 20283/20283/14481 +f 20281/20281/14479 20355/20355/14551 20533/20533/14682 +f 20533/20533/14682 20355/20355/14551 20356/20356/14552 +f 20533/20533/14682 20356/20356/14552 20349/20349/14546 +f 20533/20533/14682 20349/20349/14546 20351/20351/14548 +f 20351/20351/14548 20542/20542/14689 20533/20533/14682 +f 20542/20542/14689 20351/20351/14548 20352/20352/14549 +f 20542/20542/14689 20352/20352/14549 20345/20345/14542 +f 20542/20542/14689 20345/20345/14542 20347/20347/14544 +o Cube.034__0 +v -0.582219 0.694344 -0.041788 +v -0.582739 0.588555 0.068871 +v -0.581263 0.596712 0.076677 +v -0.580743 0.702502 -0.033982 +v -0.571309 0.704078 -0.032431 +v -0.571829 0.598289 0.078228 +v -0.563280 0.594971 0.075097 +v -0.562760 0.700761 -0.035562 +v -0.562760 0.700761 -0.035562 +v -0.563280 0.594971 0.075097 +v -0.564756 0.586814 0.067291 +v -0.564236 0.692603 -0.043368 +v -0.573670 0.691026 -0.044919 +v -0.574190 0.585237 0.065739 +v -0.582739 0.588555 0.068871 +v -0.582219 0.694344 -0.041788 +v -0.571309 0.704078 -0.032431 +v -0.562760 0.700761 -0.035562 +v -0.564236 0.692603 -0.043368 +v -0.573670 0.691026 -0.044919 +v -0.565316 0.591189 0.077709 +v -0.566485 0.584726 0.071525 +v -0.572089 0.593818 0.080190 +v -0.565316 0.591189 0.077709 +v -0.580743 0.702502 -0.033982 +v -0.582219 0.694344 -0.041788 +v -0.564236 0.692603 -0.043368 +v -0.564756 0.586814 0.067291 +v -0.580743 0.702502 -0.033982 +v -0.581263 0.596712 0.076677 +v -0.572089 0.593818 0.080190 +v -0.579564 0.592569 0.078961 +v -0.580733 0.586106 0.072776 +v -0.573960 0.583477 0.070296 +v -0.565316 0.591189 0.077709 +v -0.566485 0.584726 0.071525 +v -0.566485 0.584726 0.071525 +v -0.573960 0.583477 0.070296 +v -0.579564 0.592569 0.078961 +v -0.580733 0.586106 0.072776 +v -0.579564 0.592569 0.078961 +v -0.580733 0.586106 0.072776 +vt 0.408749 0.339205 +vt 0.408749 0.328106 +vt 0.407907 0.328106 +vt 0.407907 0.339205 +vt 0.288169 0.167390 +vt 0.288169 0.178513 +vt 0.288885 0.178513 +vt 0.288885 0.167390 +vt 0.215182 0.334948 +vt 0.215182 0.323848 +vt 0.214339 0.323848 +vt 0.214339 0.334948 +vt 0.165661 0.166050 +vt 0.165661 0.154927 +vt 0.165122 0.154839 +vt 0.165122 0.165962 +vt 0.451774 0.773233 +vt 0.451103 0.773485 +vt 0.451103 0.774327 +vt 0.451774 0.774580 +vt 0.215094 0.323494 +vt 0.214427 0.323494 +vt 0.288218 0.178865 +vt 0.288786 0.178865 +vt 0.452445 0.773485 +vt 0.452445 0.774327 +vt 0.166377 0.166050 +vt 0.166377 0.154927 +vt 0.287630 0.167478 +vt 0.287630 0.178601 +vt 0.536958 0.773951 +vt 0.537490 0.773751 +vt 0.537490 0.773083 +vt 0.536958 0.772883 +vt 0.536427 0.773751 +vt 0.536427 0.773083 +vt 0.166278 0.154575 +vt 0.165710 0.154575 +vt 0.287791 0.178935 +vt 0.408662 0.327751 +vt 0.407994 0.327751 +vt 0.165283 0.154505 +vn -0.7102 0.1504 -0.6878 +vn -0.8710 -0.4653 -0.1575 +vn -0.7274 0.3288 0.6023 +vn -0.5920 0.8034 -0.0629 +vn 0.1020 0.9923 0.0697 +vn 0.1266 0.5727 0.8100 +vn 0.8696 0.1742 0.4620 +vn 0.7142 0.6770 -0.1777 +vn 0.7260 -0.6199 -0.2978 +vn 0.5961 0.0239 -0.8026 +vn -0.0977 -0.1138 -0.9887 +vn -0.1279 -0.8343 -0.5363 +vn 0.1022 0.9923 0.0697 +vn 0.7142 0.6771 -0.1777 +vn 0.5960 0.0240 -0.8026 +vn -0.0978 -0.1138 -0.9887 +vn 0.5676 -0.3128 0.7616 +vn 0.4713 -0.8452 0.2522 +vn 0.0790 -0.0856 0.9932 +vn -0.5920 0.8035 -0.0629 +vn -0.7101 0.1504 -0.6878 +vn 0.5961 0.0239 -0.8025 +vn 0.0789 -0.0856 0.9932 +vn -0.4765 -0.2116 0.8533 +vn -0.5728 -0.7441 0.3438 +vn -0.0842 -0.9880 0.1298 +vn 0.5676 -0.3127 0.7616 +vn 0.4712 -0.8452 0.2521 +vn 0.4713 -0.8452 0.2521 +vn -0.5728 -0.7441 0.3439 +vn -0.4765 -0.2117 0.8533 +usemtl Scene_-_Root +s 1 +f 20545/20545/14692 20546/20546/14693 20547/20547/14694 +f 20545/20545/14692 20547/20547/14694 20548/20548/14695 +f 20549/20549/14696 20550/20550/14697 20551/20551/14698 +f 20549/20549/14696 20551/20551/14698 20552/20552/14699 +f 20553/20553/14699 20554/20554/14698 20555/20555/14700 +f 20553/20553/14699 20555/20555/14700 20556/20556/14701 +f 20557/20557/14702 20558/20558/14703 20559/20559/14693 +f 20557/20557/14702 20559/20559/14693 20560/20560/14692 +f 20561/20561/14704 20562/20562/14705 20563/20563/14706 +f 20561/20561/14704 20563/20563/14706 20564/20564/14707 +f 20555/20555/14700 20554/20554/14698 20565/20565/14708 +f 20555/20555/14700 20565/20565/14708 20566/20566/14709 +f 20551/20551/14698 20550/20550/14697 20567/20567/14710 +f 20551/20551/14698 20567/20567/14710 20568/20568/14708 +f 20569/20569/14711 20561/20561/14704 20564/20564/14707 +f 20569/20569/14711 20564/20564/14707 20570/20570/14712 +f 20571/20571/14713 20572/20572/14700 20558/20558/14703 +f 20571/20571/14713 20558/20558/14703 20557/20557/14702 +f 20573/20573/14711 20574/20574/14694 20550/20550/14697 +f 20573/20573/14711 20550/20550/14697 20549/20549/14696 +f 20575/20575/14714 20576/20576/14715 20577/20577/14716 +f 20575/20575/14714 20577/20577/14716 20578/20578/14717 +f 20579/20579/14718 20575/20575/14714 20578/20578/14717 +f 20579/20579/14718 20578/20578/14717 20580/20580/14719 +f 20558/20558/14703 20572/20572/14700 20581/20581/14720 +f 20558/20558/14703 20581/20581/14720 20582/20582/14717 +f 20550/20550/14697 20574/20574/14694 20583/20583/14715 +f 20550/20550/14697 20583/20583/14715 20567/20567/14710 +f 20547/20547/14694 20546/20546/14693 20584/20584/14721 +f 20547/20547/14694 20584/20584/14721 20585/20585/14722 +f 20559/20559/14693 20558/20558/14703 20582/20582/14717 +f 20559/20559/14693 20582/20582/14717 20586/20586/14721 +o Cube.035__0 +v -0.459060 -1.418295 0.706666 +v -0.457764 -1.508643 0.745185 +v -0.459320 -1.505105 0.753535 +v -0.460617 -1.414757 0.715017 +v -0.453958 -1.412903 0.719143 +v -0.452662 -1.503251 0.757661 +v -0.444877 -1.503958 0.755741 +v -0.446173 -1.413610 0.717222 +v -0.446173 -1.413610 0.717222 +v -0.444877 -1.503958 0.755741 +v -0.443321 -1.507496 0.747390 +v -0.444617 -1.417148 0.708872 +v -0.451275 -1.419003 0.704746 +v -0.449979 -1.509351 0.743264 +v -0.457764 -1.508643 0.745185 +v -0.459060 -1.418295 0.706666 +v -0.453958 -1.412903 0.719143 +v -0.446173 -1.413610 0.717222 +v -0.444617 -1.417148 0.708872 +v -0.451275 -1.419003 0.704746 +v -0.446476 -1.508973 0.756259 +v -0.445322 -1.511598 0.750063 +v -0.452252 -1.508448 0.757684 +v -0.446476 -1.508973 0.756259 +v -0.460617 -1.414757 0.715017 +v -0.459060 -1.418295 0.706666 +v -0.444617 -1.417148 0.708872 +v -0.443321 -1.507496 0.747390 +v -0.460617 -1.414757 0.715017 +v -0.459320 -1.505105 0.753535 +v -0.452252 -1.508448 0.757684 +v -0.457192 -1.509825 0.754623 +v -0.456038 -1.512449 0.748427 +v -0.450262 -1.512974 0.747002 +v -0.446476 -1.508973 0.756259 +v -0.445322 -1.511598 0.750063 +v -0.445322 -1.511598 0.750063 +v -0.450262 -1.512974 0.747002 +v -0.457192 -1.509825 0.754623 +v -0.456038 -1.512449 0.748427 +v -0.457192 -1.509825 0.754623 +v -0.456038 -1.512449 0.748427 +vt 0.280195 0.379656 +vt 0.280195 0.372521 +vt 0.279514 0.372521 +vt 0.279514 0.379656 +vt 0.214732 0.315729 +vt 0.214732 0.322868 +vt 0.215328 0.322868 +vt 0.215328 0.315729 +vt 0.280195 0.371996 +vt 0.280195 0.364860 +vt 0.279514 0.364860 +vt 0.279514 0.371996 +vt 0.408152 0.319285 +vt 0.408152 0.312146 +vt 0.407761 0.312063 +vt 0.407761 0.319202 +vt 0.534904 0.772989 +vt 0.534362 0.773235 +vt 0.534362 0.773915 +vt 0.534904 0.774162 +vt 0.280107 0.364486 +vt 0.279602 0.364486 +vt 0.214795 0.323242 +vt 0.215237 0.323242 +vt 0.535446 0.773235 +vt 0.535446 0.773915 +vt 0.408748 0.319285 +vt 0.408748 0.312146 +vt 0.214341 0.315812 +vt 0.214341 0.322951 +vt 0.541120 0.773768 +vt 0.541523 0.773585 +vt 0.541523 0.773080 +vt 0.541120 0.772897 +vt 0.540718 0.773585 +vt 0.540718 0.773080 +vt 0.408657 0.311772 +vt 0.408215 0.311772 +vt 0.214504 0.323303 +vt 0.280107 0.372146 +vt 0.279602 0.372146 +vt 0.407924 0.311710 +vn -0.5958 0.3363 -0.7293 +vn -0.7196 -0.4539 -0.5255 +vn -0.8988 -0.0466 0.4359 +vn -0.7419 0.6683 0.0544 +vn -0.1404 0.8748 0.4637 +vn -0.1635 0.2020 0.9656 +vn 0.7249 0.0825 0.6838 +vn 0.5799 0.7734 0.2562 +vn 0.5799 0.7733 0.2562 +vn 0.7250 0.0824 0.6838 +vn 0.9041 -0.3249 -0.2775 +vn 0.7260 0.4413 -0.5275 +vn 0.1238 0.2744 -0.9536 +vn 0.1685 -0.5529 -0.8161 +vn -0.7196 -0.4538 -0.5255 +vn -0.1403 0.8748 0.4636 +vn 0.5799 0.7733 0.2563 +vn 0.7259 0.4413 -0.5275 +vn 0.1239 0.2744 -0.9536 +vn 0.4871 -0.5221 0.7001 +vn 0.6062 -0.7930 0.0608 +vn -0.0979 -0.4621 0.8814 +vn 0.4871 -0.5221 0.7000 +vn -0.7418 0.6684 0.0544 +vn 0.9041 -0.3248 -0.2775 +vn -0.7419 0.6684 0.0544 +vn -0.8988 -0.0465 0.4360 +vn -0.5862 -0.6074 0.5362 +vn -0.4670 -0.8782 -0.1031 +vn 0.1182 -0.9533 -0.2780 +vn 0.6063 -0.7929 0.0609 +vn -0.5862 -0.6073 0.5363 +vn -0.4671 -0.8782 -0.1031 +usemtl Scene_-_Root +s 1 +f 20587/20587/14723 20588/20588/14724 20589/20589/14725 +f 20587/20587/14723 20589/20589/14725 20590/20590/14726 +f 20591/20591/14727 20592/20592/14728 20593/20593/14729 +f 20591/20591/14727 20593/20593/14729 20594/20594/14730 +f 20595/20595/14731 20596/20596/14732 20597/20597/14733 +f 20595/20595/14731 20597/20597/14733 20598/20598/14734 +f 20599/20599/14735 20600/20600/14736 20601/20601/14737 +f 20599/20599/14735 20601/20601/14737 20602/20602/14723 +f 20603/20603/14738 20604/20604/14739 20605/20605/14740 +f 20603/20603/14738 20605/20605/14740 20606/20606/14741 +f 20597/20597/14733 20596/20596/14732 20607/20607/14742 +f 20597/20597/14733 20607/20607/14742 20608/20608/14743 +f 20593/20593/14729 20592/20592/14728 20609/20609/14744 +f 20593/20593/14729 20609/20609/14744 20610/20610/14745 +f 20611/20611/14746 20603/20603/14738 20606/20606/14741 +f 20611/20611/14746 20606/20606/14741 20612/20612/14723 +f 20613/20613/14740 20614/20614/14747 20600/20600/14736 +f 20613/20613/14740 20600/20600/14736 20599/20599/14735 +f 20615/20615/14748 20616/20616/14749 20592/20592/14728 +f 20615/20615/14748 20592/20592/14728 20591/20591/14727 +f 20617/20617/14744 20618/20618/14750 20619/20619/14751 +f 20617/20617/14744 20619/20619/14751 20620/20620/14752 +f 20621/20621/14742 20617/20617/14744 20620/20620/14752 +f 20621/20621/14742 20620/20620/14752 20622/20622/14743 +f 20600/20600/14736 20614/20614/14747 20623/20623/14753 +f 20600/20600/14736 20623/20623/14753 20624/20624/14752 +f 20592/20592/14728 20616/20616/14749 20625/20625/14754 +f 20592/20592/14728 20625/20625/14754 20609/20609/14744 +f 20589/20589/14725 20588/20588/14724 20626/20626/14751 +f 20589/20589/14725 20626/20626/14751 20627/20627/14750 +f 20601/20601/14737 20600/20600/14736 20624/20624/14752 +f 20601/20601/14737 20624/20624/14752 20628/20628/14755 +o Cube.036__0 +v 0.455023 -1.429046 0.676772 +v 0.447617 -1.512575 0.712184 +v 0.447388 -1.508361 0.722074 +v 0.454794 -1.424832 0.686663 +v 0.463268 -1.424326 0.689630 +v 0.455863 -1.507855 0.725041 +v 0.464454 -1.509501 0.722955 +v 0.471859 -1.425972 0.687543 +v 0.471859 -1.425972 0.687543 +v 0.464454 -1.509501 0.722955 +v 0.464683 -1.513714 0.713064 +v 0.472088 -1.430185 0.677653 +v 0.463614 -1.430692 0.674686 +v 0.456208 -1.514221 0.710098 +v 0.447617 -1.512575 0.712184 +v 0.455023 -1.429046 0.676772 +v 0.463268 -1.424326 0.689630 +v 0.471859 -1.425972 0.687543 +v 0.472088 -1.430185 0.677653 +v 0.463614 -1.430692 0.674686 +v 0.460545 -1.517312 0.723922 +v 0.460685 -1.519889 0.717872 +v 0.455290 -1.516305 0.725199 +v 0.460545 -1.517312 0.723922 +v 0.454794 -1.424832 0.686663 +v 0.455023 -1.429046 0.676772 +v 0.472088 -1.430185 0.677653 +v 0.464683 -1.513714 0.713064 +v 0.454794 -1.424832 0.686663 +v 0.447388 -1.508361 0.722074 +v 0.455290 -1.516305 0.725199 +v 0.450106 -1.516615 0.723384 +v 0.450246 -1.519192 0.717334 +v 0.455502 -1.520199 0.716058 +v 0.460545 -1.517312 0.723922 +v 0.460685 -1.519889 0.717872 +v 0.460685 -1.519889 0.717872 +v 0.455502 -1.520199 0.716058 +v 0.450106 -1.516615 0.723384 +v 0.450246 -1.519192 0.717334 +v 0.450106 -1.516615 0.723384 +v 0.450246 -1.519192 0.717334 +vt 0.408108 0.420495 +vt 0.408108 0.413898 +vt 0.407313 0.413898 +vt 0.407313 0.420495 +vt 0.214732 0.159004 +vt 0.214732 0.152384 +vt 0.214191 0.152314 +vt 0.214191 0.158934 +vt 0.407954 0.304347 +vt 0.407954 0.310944 +vt 0.408750 0.310944 +vt 0.408750 0.304347 +vt 0.214732 0.159149 +vt 0.214732 0.165769 +vt 0.215398 0.165769 +vt 0.215398 0.159149 +vt 0.455120 0.773455 +vt 0.455324 0.774088 +vt 0.456119 0.774088 +vt 0.456322 0.773455 +vt 0.408109 0.311563 +vt 0.408595 0.311563 +vt 0.214804 0.151772 +vt 0.214473 0.151729 +vt 0.455324 0.772822 +vt 0.456119 0.772822 +vt 0.214191 0.159219 +vt 0.214191 0.165839 +vt 0.215398 0.159004 +vt 0.215398 0.152384 +vt 0.431464 0.773196 +vt 0.431340 0.772808 +vt 0.430853 0.772808 +vt 0.430729 0.773196 +vt 0.431340 0.773583 +vt 0.430853 0.773583 +vt 0.214473 0.166424 +vt 0.214804 0.166381 +vt 0.215211 0.151772 +vt 0.407954 0.413279 +vt 0.407467 0.413279 +vt 0.215211 0.166381 +vn -0.5883 0.4041 -0.7005 +vn -0.7941 -0.3662 -0.4850 +vn -0.8185 0.0826 0.5685 +vn -0.6084 0.7751 0.1704 +vn 0.0362 0.8909 0.4527 +vn -0.0358 0.2172 0.9755 +vn 0.7597 -0.0229 0.6499 +vn 0.6851 0.6887 0.2372 +vn 0.7597 -0.0228 0.6499 +vn 0.7840 -0.4716 -0.4036 +vn 0.7053 0.3177 -0.6337 +vn 0.0688 0.2916 -0.9540 +vn 0.0060 -0.5532 -0.8330 +vn -0.7942 -0.3662 -0.4850 +vn -0.5882 0.4041 -0.7005 +vn 0.6852 0.6887 0.2371 +vn 0.0687 0.2916 -0.9541 +vn 0.4440 -0.5822 0.6811 +vn 0.4605 -0.8870 -0.0343 +vn -0.0767 -0.4691 0.8798 +vn -0.5883 0.4041 -0.7004 +vn 0.7840 -0.4716 -0.4035 +vn -0.8186 0.0826 0.5685 +vn -0.5847 -0.5135 0.6280 +vn -0.5682 -0.8183 -0.0874 +vn -0.0501 -0.9605 -0.2738 +vn 0.4606 -0.8870 -0.0343 +vn 0.4605 -0.8870 -0.0342 +vn -0.0500 -0.9605 -0.2737 +vn -0.5682 -0.8183 -0.0873 +usemtl Scene_-_Root +s 1 +f 20629/20629/14756 20630/20630/14757 20631/20631/14758 +f 20629/20629/14756 20631/20631/14758 20632/20632/14759 +f 20633/20633/14760 20634/20634/14761 20635/20635/14762 +f 20633/20633/14760 20635/20635/14762 20636/20636/14763 +f 20637/20637/14763 20638/20638/14764 20639/20639/14765 +f 20637/20637/14763 20639/20639/14765 20640/20640/14766 +f 20641/20641/14767 20642/20642/14768 20643/20643/14769 +f 20641/20641/14767 20643/20643/14769 20644/20644/14770 +f 20645/20645/14760 20646/20646/14771 20647/20647/14766 +f 20645/20645/14760 20647/20647/14766 20648/20648/14772 +f 20639/20639/14765 20638/20638/14764 20649/20649/14773 +f 20639/20639/14765 20649/20649/14773 20650/20650/14774 +f 20635/20635/14762 20634/20634/14761 20651/20651/14775 +f 20635/20635/14762 20651/20651/14775 20652/20652/14773 +f 20653/20653/14759 20645/20645/14760 20648/20648/14772 +f 20653/20653/14759 20648/20648/14772 20654/20654/14776 +f 20655/20655/14766 20656/20656/14777 20642/20642/14768 +f 20655/20655/14766 20642/20642/14768 20641/20641/14767 +f 20657/20657/14759 20658/20658/14778 20634/20634/14761 +f 20657/20657/14759 20634/20634/14761 20633/20633/14760 +f 20659/20659/14775 20660/20660/14779 20661/20661/14780 +f 20659/20659/14775 20661/20661/14780 20662/20662/14781 +f 20663/20663/14773 20659/20659/14775 20662/20662/14781 +f 20663/20663/14773 20662/20662/14781 20664/20664/14782 +f 20642/20642/14768 20656/20656/14777 20665/20665/14783 +f 20642/20642/14768 20665/20665/14783 20666/20666/14784 +f 20634/20634/14761 20658/20658/14778 20667/20667/14779 +f 20634/20634/14761 20667/20667/14779 20651/20651/14775 +f 20631/20631/14758 20630/20630/14757 20668/20668/14785 +f 20631/20631/14758 20668/20668/14785 20669/20669/14779 +f 20643/20643/14769 20642/20642/14768 20666/20666/14784 +f 20643/20643/14769 20666/20666/14784 20670/20670/14785 +o Cylinder.033__0 +v -1.870981 -0.665391 -0.012792 +v -1.361621 -0.388580 -0.011651 +v -1.344634 -0.424258 -0.020963 +v -1.851692 -0.708419 -0.023868 +v -1.855818 -0.783222 0.035905 +v -1.868747 -0.756406 0.017478 +v -1.841132 -0.755058 -0.011605 +v -1.823884 -0.790839 0.012985 +v -1.846472 -0.801428 0.064312 +v -1.811417 -0.815129 0.050890 +v -1.842132 -0.808250 0.098376 +v -1.805628 -0.824232 0.096342 +v -1.843458 -0.802652 0.132911 +v -1.807399 -0.816762 0.142420 +v -1.850248 -0.785485 0.162659 +v -1.816458 -0.793857 0.182111 +v -1.861470 -0.759363 0.183092 +v -1.831429 -0.759003 0.209374 +v -1.875413 -0.728263 0.191097 +v -1.850030 -0.717506 0.220058 +v -1.889956 -0.696918 0.185458 +v -1.869433 -0.675682 0.212537 +v -1.902885 -0.670102 0.167032 +v -1.886683 -0.639897 0.187953 +v -1.912230 -0.651897 0.138625 +v -1.902885 -0.670102 0.167032 +v -1.886683 -0.639897 0.187953 +v -1.899152 -0.615601 0.150048 +v -1.916571 -0.645075 0.104560 +v -1.904943 -0.606494 0.104593 +v -1.915245 -0.650673 0.070026 +v -1.903174 -0.613963 0.058509 +v -1.908455 -0.667840 0.040277 +v -1.915245 -0.650673 0.070026 +v -1.903174 -0.613963 0.058509 +v -1.894113 -0.636872 0.018812 +v -1.304807 -0.493609 0.153868 +v -1.296469 -0.513296 0.119357 +v -0.715734 -0.201760 0.099398 +v -0.726022 -0.183140 0.133976 +v -1.897233 -0.693961 0.019845 +v -1.908455 -0.667840 0.040277 +v -1.894113 -0.636872 0.018812 +v -1.879140 -0.671731 -0.008452 +v -1.883291 -0.725062 0.011839 +v -1.860535 -0.713233 -0.019133 +v -0.809267 -0.055120 -0.007391 +v -0.819554 -0.036500 0.027187 +v -0.187803 0.396130 0.002643 +v -0.174467 0.376685 -0.035902 +v -1.380169 -0.340350 0.126123 +v -1.368868 -0.361241 0.159047 +v -0.802808 -0.057744 0.139589 +v -0.816059 -0.037920 0.106732 +v -0.792642 -0.083483 -0.031208 +v -0.772212 -0.117275 -0.040638 +v -1.294769 -0.519711 0.079306 +v -1.299964 -0.511876 0.039812 +v -0.719230 -0.200339 0.019853 +v -0.713349 -0.207799 0.059324 +v -1.353182 -0.392009 0.180388 +v -1.335499 -0.427968 0.186898 +v -0.763077 -0.120985 0.167223 +v -0.784203 -0.086912 0.160831 +v -1.375327 -0.358617 0.012066 +v -1.383665 -0.338930 0.046578 +v -1.311266 -0.490985 0.006888 +v -1.326952 -0.460217 -0.014453 +v -0.751086 -0.151348 -0.034246 +v -0.732481 -0.180516 -0.013004 +v -1.318512 -0.463645 0.177586 +v -0.742647 -0.154776 0.157793 +v -1.385365 -0.332515 0.086629 +v -0.821940 -0.030461 0.067261 +v -1.296469 -0.513296 0.119357 +v -0.715734 -0.201760 0.099398 +v -1.368868 -0.361241 0.159047 +v -0.802808 -0.057744 0.139589 +v -1.383665 -0.338930 0.046578 +v -0.819554 -0.036500 0.027187 +v -1.326952 -0.460217 -0.014453 +v -0.751086 -0.151348 -0.034246 +v -0.052865 0.216820 0.037879 +v -0.060072 0.224674 -0.006030 +v 0.244390 0.451962 -0.015352 +v 0.251597 0.444109 0.028557 +v -0.069517 0.242538 0.121048 +v -0.090842 0.272194 0.147647 +v -0.153143 0.347028 -0.062500 +v -0.116909 0.307546 0.158248 +v -0.127076 0.311676 -0.073102 +v -0.100235 0.276010 -0.066093 +v -0.143750 0.343213 0.151240 +v -0.100235 0.276010 -0.066093 +v -0.076706 0.245458 -0.042541 +v -0.167278 0.373764 0.127687 +v -0.167278 0.373764 0.127687 +v -0.183912 0.394549 0.091177 +v -0.191120 0.402402 0.047267 +v -0.056182 0.223093 0.082504 +v -0.187803 0.396130 0.002643 +v -0.726022 -0.183140 0.133976 +v -0.069517 0.242538 0.121048 +v 0.120549 0.621838 0.081855 +v 0.113342 0.629691 0.037946 +v 0.248280 0.450382 0.073181 +v 0.116659 0.623419 -0.006679 +v -0.056182 0.223093 0.082504 +v 0.248280 0.450382 0.073181 +v 0.234945 0.469827 0.111727 +v 0.116659 0.623419 -0.006679 +v 0.129995 0.603974 -0.045224 +v 0.213620 0.499483 0.138325 +v 0.151320 0.574318 -0.071822 +v 0.187553 0.534835 0.148926 +v 0.177386 0.538965 -0.082424 +v 0.204227 0.503298 -0.075415 +v 0.160712 0.570502 0.141918 +v 0.204227 0.503298 -0.075415 +v 0.227756 0.472747 -0.051863 +v 0.137184 0.601053 0.118365 +v 0.137184 0.601053 0.118365 +v 0.329631 0.563004 0.027250 +v 0.325450 0.567559 0.001781 +v 0.320502 0.563865 0.001933 +v 0.324682 0.559309 0.027402 +v 0.314798 0.577809 -0.096206 +v 0.342119 0.542335 -0.068858 +v 0.361433 0.518200 -0.026464 +v 0.236950 0.691319 0.128805 +v 0.217635 0.715453 0.086410 +v 0.369802 0.509081 0.024522 +v 0.209266 0.724572 0.035424 +v 0.365951 0.516365 0.076338 +v 0.213117 0.717288 -0.016392 +v 0.234945 0.469827 0.111727 +v 0.350466 0.538944 0.121096 +v 0.213117 0.717288 -0.016392 +v 0.228602 0.694710 -0.061149 +v 0.350466 0.538944 0.121096 +v 0.325704 0.573379 0.151980 +v 0.253364 0.660274 -0.092034 +v 0.295436 0.614429 0.164291 +v 0.283631 0.619224 -0.104344 +v 0.314798 0.577809 -0.096206 +v 0.286585 0.618024 -0.037124 +v 0.302154 0.597336 -0.033058 +v 0.314798 0.577809 -0.096206 +v 0.283631 0.619224 -0.104344 +v 0.315802 0.579615 -0.019397 +v 0.342119 0.542335 -0.068858 +v 0.325450 0.567559 0.001781 +v 0.361433 0.518200 -0.026464 +v 0.329631 0.563004 0.027250 +v 0.369802 0.509081 0.024522 +v 0.327707 0.566642 0.053134 +v 0.365951 0.516365 0.076338 +v 0.319972 0.577921 0.075492 +v 0.350466 0.538944 0.121096 +v 0.307602 0.595123 0.090921 +v 0.325704 0.573379 0.151980 +v 0.292482 0.615629 0.097070 +v 0.295436 0.614429 0.164291 +v 0.263266 0.654038 0.079343 +v 0.253618 0.666094 0.058166 +v 0.217635 0.715453 0.086410 +v 0.236950 0.691319 0.128805 +v 0.249437 0.670649 0.032696 +v 0.209266 0.724572 0.035424 +v 0.251361 0.667011 0.006812 +v 0.213117 0.717288 -0.016392 +v 0.259097 0.655732 -0.015546 +v 0.228602 0.694710 -0.061149 +v 0.271466 0.638530 -0.030974 +v 0.253364 0.660274 -0.092034 +v 0.269840 0.647243 0.128336 +v 0.248834 0.675887 0.140701 +v 0.231247 0.628629 0.151613 +v 0.281879 0.632444 0.160751 +v -1.831574 -0.751785 -0.016067 +v -1.813689 -0.788887 0.009425 +v -1.800761 -0.814075 0.048727 +v -1.794756 -0.823515 0.095854 +v -1.796590 -0.815769 0.143633 +v -1.304807 -0.493609 0.153868 +v -1.805983 -0.792018 0.184789 +v -1.805983 -0.792018 0.184789 +v -1.821505 -0.755876 0.213057 +v -1.840794 -0.712847 0.224133 +v -1.860913 -0.669481 0.216330 +v -1.878799 -0.632381 0.190838 +v -1.878799 -0.632381 0.190838 +v -1.891728 -0.607194 0.151537 +v -1.897732 -0.597755 0.104410 +v -1.895898 -0.605500 0.056632 +v -1.895898 -0.605500 0.056632 +v -1.886505 -0.629251 0.015476 +v -1.831574 -0.751785 -0.016067 +v -1.883256 -0.748335 0.053885 +v -1.891567 -0.730423 0.050663 +v -1.883291 -0.725062 0.011839 +v -1.875867 -0.763659 0.064415 +v -1.870527 -0.774063 0.080649 +v -1.868046 -0.777962 0.100116 +v -1.868804 -0.774763 0.119851 +v -1.872684 -0.764953 0.136851 +v -1.879097 -0.750025 0.148528 +v -1.887065 -0.732252 0.153103 +v -1.895376 -0.714340 0.149880 +v -1.902764 -0.699016 0.139350 +v -1.908105 -0.688612 0.123116 +v -1.912230 -0.651897 0.138625 +v -1.910586 -0.684713 0.103650 +v -1.916571 -0.645075 0.104560 +v -1.909828 -0.687912 0.083914 +v -1.905948 -0.697722 0.066914 +v -1.899535 -0.712650 0.055238 +v -1.897233 -0.693961 0.019845 +v -1.836571 -0.754014 -0.014767 +v -1.856494 -0.711069 -0.022494 +v -1.841132 -0.755058 -0.011605 +v -1.813689 -0.788887 0.009425 +v -1.818859 -0.790754 0.010479 +v -1.823884 -0.790839 0.012985 +v -1.806056 -0.815696 0.049399 +v -1.818859 -0.790754 0.010479 +v -1.811417 -0.815129 0.050890 +v -1.823884 -0.790839 0.012985 +v -1.800110 -0.825043 0.096069 +v -1.805628 -0.824232 0.096342 +v -1.801927 -0.817373 0.143383 +v -1.807399 -0.816762 0.142420 +v -1.796590 -0.815769 0.143633 +v -1.811229 -0.793854 0.184139 +v -1.801927 -0.817373 0.143383 +v -1.801927 -0.817373 0.143383 +v -1.811229 -0.793854 0.184139 +v -1.826602 -0.758064 0.212132 +v -1.831429 -0.759003 0.209374 +v -1.816458 -0.793857 0.182111 +v -1.845704 -0.715454 0.223102 +v -1.850030 -0.717506 0.220058 +v -1.865628 -0.672510 0.215376 +v -1.869433 -0.675682 0.212537 +v -1.860913 -0.669481 0.216330 +v -1.883339 -0.635769 0.190132 +v -1.865628 -0.672510 0.215376 +v -1.869433 -0.675682 0.212537 +v -1.896144 -0.610826 0.151212 +v -1.902091 -0.601477 0.104542 +v -1.900274 -0.609147 0.057225 +v -1.886505 -0.629251 0.015476 +v -1.890971 -0.632667 0.016468 +v -1.894113 -0.636872 0.018812 +v -1.875597 -0.668458 -0.011526 +v -1.890971 -0.632667 0.016468 +v -1.860535 -0.713233 -0.019133 +v 0.249437 0.670649 0.032696 +v 0.253618 0.666094 0.058166 +v 0.248669 0.662400 0.058317 +v 0.244488 0.666955 0.032848 +v 0.327707 0.566642 0.053134 +v 0.322758 0.562948 0.053286 +v 0.251361 0.667011 0.006812 +v 0.246412 0.663317 0.006964 +v 0.319972 0.577921 0.075492 +v 0.327707 0.566642 0.053134 +v 0.322758 0.562948 0.053286 +v 0.315023 0.574227 0.075644 +v 0.259097 0.655732 -0.015546 +v 0.251361 0.667011 0.006812 +v 0.246412 0.663317 0.006964 +v 0.254148 0.652038 -0.015394 +v 0.307602 0.595123 0.090921 +v 0.302654 0.591429 0.091072 +v 0.271466 0.638530 -0.030974 +v 0.266517 0.634836 -0.030823 +v 0.292482 0.615629 0.097070 +v 0.287534 0.611934 0.097222 +v 0.302154 0.597336 -0.033058 +v 0.286585 0.618024 -0.037124 +v 0.281637 0.614330 -0.036972 +v 0.297206 0.593642 -0.032907 +v 0.276914 0.636317 0.093005 +v 0.271965 0.632623 0.093156 +v 0.315802 0.579615 -0.019397 +v 0.310853 0.575921 -0.019245 +v 0.263266 0.654038 0.079343 +v 0.276914 0.636317 0.093005 +v 0.271965 0.632623 0.093156 +v 0.258318 0.650344 0.079494 +v 0.315802 0.579615 -0.019397 +v 0.310853 0.575921 -0.019245 +v 0.276914 0.636317 0.093005 +v 0.248834 0.675887 0.140701 +v 0.269840 0.647243 0.128336 +v 0.281879 0.632444 0.160751 +v 0.231247 0.628629 0.151613 +v 0.248834 0.675887 0.140701 +v 0.236950 0.691319 0.128805 +v 0.281879 0.632444 0.160751 +v 0.297206 0.593642 -0.032907 +v 0.281637 0.614330 -0.036972 +v 0.266517 0.634836 -0.030823 +v 0.254148 0.652038 -0.015394 +v 0.246412 0.663317 0.006964 +v 0.244488 0.666955 0.032848 +v 0.248669 0.662400 0.058317 +v 0.258318 0.650344 0.079494 +v 0.271965 0.632623 0.093156 +v 0.287534 0.611934 0.097222 +v 0.302654 0.591429 0.091072 +v 0.315023 0.574227 0.075644 +v 0.322758 0.562948 0.053286 +v 0.324682 0.559309 0.027402 +v 0.320502 0.563865 0.001933 +v 0.310853 0.575921 -0.019245 +vt 0.776727 0.405603 +vt 0.775985 0.407394 +vt 0.780124 0.410158 +vt 0.781609 0.406574 +vt 0.774614 0.408764 +vt 0.777380 0.412902 +vt 0.772823 0.409506 +vt 0.773794 0.414386 +vt 0.770885 0.409506 +vt 0.769913 0.414386 +vt 0.769094 0.408764 +vt 0.766328 0.412902 +vt 0.767723 0.407394 +vt 0.763584 0.410158 +vt 0.766981 0.405603 +vt 0.762099 0.406574 +vt 0.766981 0.403665 +vt 0.762099 0.402694 +vt 0.769094 0.400504 +vt 0.770885 0.399762 +vt 0.769913 0.394881 +vt 0.766328 0.396366 +vt 0.772823 0.399762 +vt 0.773794 0.394881 +vt 0.774614 0.400504 +vt 0.777380 0.396366 +vt 0.775985 0.401874 +vt 0.780124 0.399110 +vt 0.776727 0.403665 +vt 0.781609 0.402694 +vt 0.765134 0.397560 +vt 0.765407 0.400327 +vt 0.767723 0.401874 +vt 0.427111 0.551298 +vt 0.424031 0.554814 +vt 0.425586 0.554650 +vt 0.430345 0.554047 +vt 0.429154 0.554216 +vt 0.762745 0.401135 +vt 0.462009 0.779333 +vt 0.464122 0.776172 +vt 0.462751 0.777543 +vt 0.462009 0.781272 +vt 0.465913 0.775431 +vt 0.467851 0.775431 +vt 0.462751 0.783062 +vt 0.464122 0.784433 +vt 0.469642 0.776172 +vt 0.471013 0.777543 +vt 0.465913 0.785174 +vt 0.467851 0.785174 +vt 0.471755 0.779333 +vt 0.469642 0.784433 +vt 0.471755 0.781272 +vt 0.471013 0.783062 +vt 0.861076 0.839373 +vt 0.858797 0.796868 +vt 0.855811 0.797185 +vt 0.857523 0.839831 +vt 0.777722 0.778172 +vt 0.779538 0.776357 +vt 0.778073 0.774599 +vt 0.775651 0.777021 +vt 0.776740 0.780553 +vt 0.774341 0.780198 +vt 0.776740 0.783138 +vt 0.774341 0.783647 +vt 0.777723 0.785534 +vt 0.775652 0.786843 +vt 0.779538 0.787375 +vt 0.778074 0.789300 +vt 0.781910 0.788381 +vt 0.781238 0.790642 +vt 0.784477 0.788400 +vt 0.784664 0.790667 +vt 0.786849 0.787427 +vt 0.787828 0.789370 +vt 0.788664 0.785612 +vt 0.790251 0.786949 +vt 0.876075 0.842437 +vt 0.878462 0.842729 +vt 0.879759 0.840463 +vt 0.876574 0.840072 +vt 0.873487 0.842344 +vt 0.873121 0.839948 +vt 0.871092 0.842464 +vt 0.869924 0.840108 +vt 0.786848 0.776410 +vt 0.788664 0.778251 +vt 0.790251 0.777125 +vt 0.787828 0.774669 +vt 0.416508 0.411122 +vt 0.414398 0.410844 +vt 0.411177 0.459465 +vt 0.413296 0.459579 +vt 0.860893 0.842383 +vt 0.863272 0.842177 +vt 0.864248 0.839889 +vt 0.861073 0.840163 +vt 0.858324 0.842713 +vt 0.857646 0.840605 +vt 0.858413 0.749460 +vt 0.860547 0.749604 +vt 0.862725 0.693104 +vt 0.860357 0.692776 +vt 0.877209 0.797119 +vt 0.879978 0.797421 +vt 0.881105 0.750436 +vt 0.878333 0.750297 +vt 0.855634 0.749398 +vt 0.852631 0.749426 +vt 0.603141 0.263830 +vt 0.600139 0.263881 +vt 0.600580 0.312613 +vt 0.603583 0.312620 +vt 0.425012 0.412025 +vt 0.422252 0.411761 +vt 0.419071 0.459683 +vt 0.421847 0.459657 +vt 0.861562 0.796686 +vt 0.863686 0.796666 +vt 0.597365 0.264008 +vt 0.595243 0.264190 +vt 0.595681 0.312511 +vt 0.597805 0.312575 +vt 0.419266 0.411444 +vt 0.416068 0.459655 +vt 0.874208 0.797024 +vt 0.875330 0.750260 +vt 0.605915 0.263863 +vt 0.606356 0.312594 +vt 0.427125 0.412196 +vt 0.423974 0.459582 +vt 0.871431 0.797151 +vt 0.872555 0.750329 +vt 0.853059 0.797589 +vt 0.849862 0.749541 +vt 0.603211 0.370636 +vt 0.599869 0.370570 +vt 0.599306 0.398477 +vt 0.602647 0.398544 +vt 0.414319 0.517392 +vt 0.417395 0.517226 +vt 0.857272 0.692455 +vt 0.420727 0.516959 +vt 0.853941 0.692190 +vt 0.850869 0.692021 +vt 0.423806 0.516634 +vt 0.594421 0.370037 +vt 0.596783 0.370359 +vt 0.426165 0.516298 +vt 0.881905 0.693683 +vt 0.878819 0.693697 +vt 0.875477 0.693714 +vt 0.606299 0.370549 +vt 0.872388 0.693732 +vt 0.608479 0.312541 +vt 0.608663 0.370322 +vt 0.878675 0.665593 +vt 0.875333 0.665610 +vt 0.605735 0.398457 +vt 0.872243 0.665628 +vt 0.411966 0.517434 +vt 0.414213 0.545394 +vt 0.416566 0.545352 +vt 0.864968 0.665138 +vt 0.862599 0.664810 +vt 0.419642 0.545186 +vt 0.859515 0.664489 +vt 0.422974 0.544919 +vt 0.856183 0.664224 +vt 0.853112 0.664055 +vt 0.426053 0.544594 +vt 0.593858 0.397945 +vt 0.596219 0.398267 +vt 0.428412 0.544259 +vt 0.881761 0.665579 +vt 0.583835 0.774741 +vt 0.583835 0.776680 +vt 0.584291 0.776680 +vt 0.584291 0.774741 +vt 0.592512 0.407825 +vt 0.595254 0.408199 +vt 0.598838 0.408443 +vt 0.882479 0.655691 +vt 0.878895 0.655707 +vt 0.602718 0.408521 +vt 0.875015 0.655727 +vt 0.606303 0.408419 +vt 0.871427 0.655748 +vt 0.608099 0.398229 +vt 0.609048 0.408155 +vt 0.866896 0.655349 +vt 0.864146 0.654969 +vt 0.416590 0.555317 +vt 0.420162 0.555124 +vt 0.860565 0.654596 +vt 0.856696 0.654288 +vt 0.853130 0.654092 +vt 0.426394 0.554420 +vt 0.429154 0.554216 +vt 0.427111 0.551298 +vt 0.425586 0.554650 +vt 0.854249 0.840392 +vt 0.596313 0.220835 +vt 0.599622 0.220639 +vt 0.603204 0.220562 +vt 0.606514 0.220617 +vt 0.608039 0.263974 +vt 0.609048 0.220794 +vt 0.417713 0.368039 +vt 0.420996 0.368491 +vt 0.424549 0.368949 +vt 0.427832 0.369343 +vt 0.430345 0.369614 +vt 0.879958 0.839667 +vt 0.876657 0.839263 +vt 0.873076 0.839134 +vt 0.869762 0.839300 +vt 0.866896 0.839020 +vt 0.864368 0.839089 +vt 0.593782 0.221120 +vt 0.781205 0.778691 +vt 0.782560 0.778135 +vt 0.781909 0.775385 +vt 0.780167 0.779728 +vt 0.779606 0.781089 +vt 0.779606 0.782566 +vt 0.780167 0.783935 +vt 0.781205 0.784987 +vt 0.782560 0.785562 +vt 0.784027 0.785573 +vt 0.785383 0.785017 +vt 0.786420 0.783980 +vt 0.786981 0.782619 +vt 0.789646 0.783231 +vt 0.786981 0.781142 +vt 0.789646 0.780646 +vt 0.786420 0.779773 +vt 0.785382 0.778721 +vt 0.784027 0.778146 +vt 0.784477 0.775403 +vt 0.854324 0.840799 +vt 0.857566 0.840244 +vt 0.854488 0.841146 +vt 0.851752 0.840970 +vt 0.851852 0.841372 +vt 0.852080 0.841703 +vt 0.599636 0.220238 +vt 0.596360 0.220432 +vt 0.599679 0.219912 +vt 0.596488 0.220101 +vt 0.603183 0.220162 +vt 0.603133 0.219838 +vt 0.606461 0.220216 +vt 0.606326 0.219891 +vt 0.415201 0.367662 +vt 0.417788 0.367636 +vt 0.415300 0.367263 +vt 0.775423 0.786989 +vt 0.777910 0.789511 +vt 0.421038 0.368083 +vt 0.421116 0.367739 +vt 0.417951 0.367304 +vt 0.424557 0.368537 +vt 0.424543 0.368181 +vt 0.427808 0.368927 +vt 0.427710 0.368561 +vt 0.882479 0.840285 +vt 0.879900 0.840085 +vt 0.882396 0.840697 +vt 0.882189 0.841059 +vt 0.876630 0.839685 +vt 0.873084 0.839557 +vt 0.869803 0.839722 +vt 0.867219 0.839736 +vt 0.867284 0.840154 +vt 0.867471 0.840529 +vt 0.861085 0.839791 +vt 0.864345 0.839509 +vt 0.781238 0.773301 +vt 0.280068 0.362545 +vt 0.280023 0.360607 +vt 0.279569 0.360618 +vt 0.279614 0.362555 +vt 0.583833 0.772950 +vt 0.584290 0.772950 +vt 0.280195 0.364331 +vt 0.279742 0.364342 +vt 0.280047 0.344709 +vt 0.280112 0.343324 +vt 0.279656 0.343329 +vt 0.279591 0.344714 +vt 0.211658 0.371208 +vt 0.211743 0.369846 +vt 0.211287 0.369846 +vt 0.211202 0.371208 +vt 0.280025 0.346507 +vt 0.279568 0.346512 +vt 0.211612 0.372994 +vt 0.211156 0.372994 +vt 0.280047 0.348445 +vt 0.279591 0.348450 +vt 0.211658 0.376727 +vt 0.211612 0.374932 +vt 0.211156 0.374932 +vt 0.211202 0.376728 +vt 0.280112 0.350227 +vt 0.279656 0.350232 +vt 0.211743 0.378106 +vt 0.211287 0.378106 +vt 0.280068 0.358814 +vt 0.280195 0.357438 +vt 0.279742 0.357448 +vt 0.279614 0.358824 +vt 0.583833 0.778469 +vt 0.584290 0.778469 +vn 0.8011 0.5980 -0.0245 +vn 0.8011 0.5980 -0.0246 +vn -0.2969 0.2047 0.9327 +vn -0.0673 -0.1003 0.9927 +vn -0.1814 0.0564 0.9818 +vn -0.4981 0.4660 0.7313 +vn -0.4011 0.3452 0.8485 +vn 0.8010 0.5981 -0.0245 +vn -0.3032 0.3123 -0.9003 +vn -0.2094 0.3608 -0.9088 +vn -0.0288 0.0262 -0.9992 +vn -0.1240 -0.0205 -0.9921 +vn -0.6537 -0.6766 -0.3390 +vn -0.7268 -0.5263 -0.4414 +vn -0.5014 -0.5237 -0.6887 +vn -0.3876 -0.7505 -0.5353 +vn -0.6006 -0.7790 -0.1802 +vn -0.3046 -0.9055 -0.2953 +vn -0.5757 -0.8176 0.0109 +vn -0.2658 -0.9640 -0.0055 +vn -0.5828 -0.7863 0.2049 +vn -0.2773 -0.9163 0.2888 +vn -0.6210 -0.6898 0.3721 +vn -0.3375 -0.7700 0.5415 +vn -0.6844 -0.5430 0.4865 +vn -0.4365 -0.5483 0.7133 +vn -0.7631 -0.3686 0.5309 +vn -0.5588 -0.2863 0.7783 +vn -0.8451 -0.1933 0.4985 +vn -0.6854 -0.0245 0.7277 +vn -0.9177 -0.0440 0.3947 +vn -0.7971 0.1974 0.5707 +vn -0.9702 0.0569 0.2356 +vn -0.9178 -0.0439 0.3947 +vn -0.7971 0.1975 0.5707 +vn -0.8773 0.3468 0.3319 +vn -0.9945 0.0943 0.0456 +vn -0.9144 0.4021 0.0474 +vn -0.9872 0.0628 -0.1468 +vn -0.9031 0.3556 -0.2406 +vn -0.9493 -0.0328 -0.3126 +vn -0.9032 0.3556 -0.2406 +vn -0.8452 0.2141 -0.4897 +vn 0.3858 -0.6245 0.6791 +vn 0.4754 -0.8083 0.3472 +vn 0.4841 -0.8040 0.3452 +vn 0.3883 -0.6258 0.6765 +vn -0.8867 -0.1781 -0.4268 +vn -0.7489 -0.0019 -0.6627 +vn -0.8085 -0.3513 -0.4721 +vn -0.6283 -0.2607 -0.7330 +vn -0.3983 0.6129 -0.6824 +vn -0.4961 0.7949 -0.3493 +vn -0.5537 0.7573 -0.3464 +vn -0.4427 0.5849 -0.6797 +vn -0.4117 0.8113 0.4151 +vn -0.2936 0.6160 0.7310 +vn -0.3359 0.5874 0.7363 +vn -0.4623 0.7812 0.4195 +vn -0.2404 0.3362 -0.9106 +vn -0.0474 0.0088 -0.9988 +vn 0.4951 -0.8680 -0.0372 +vn 0.4418 -0.7946 -0.4164 +vn 0.4506 -0.7904 -0.4149 +vn 0.5059 -0.8618 -0.0376 +vn -0.1284 0.3278 0.9360 +vn 0.0588 -0.0092 0.9982 +vn 0.0406 -0.0271 0.9988 +vn -0.1591 0.3033 0.9395 +vn -0.3556 0.6411 -0.6801 +vn -0.4452 0.8250 -0.3481 +vn 0.3238 -0.5992 -0.7322 +vn 0.1585 -0.3110 -0.9371 +vn 0.1518 -0.3204 -0.9351 +vn 0.3264 -0.6005 -0.7300 +vn 0.2394 -0.3436 0.9081 +vn 0.2327 -0.3533 0.9061 +vn -0.4649 0.8846 0.0362 +vn -0.5186 0.8542 0.0380 +vn -0.3359 0.5875 0.7363 +vn 0.1518 -0.3204 -0.9350 +vn 0.5687 -0.8216 -0.0397 +vn 0.5085 -0.7531 -0.4175 +vn 0.4774 -0.7735 -0.4170 +vn 0.5395 -0.8411 -0.0387 +vn 0.4322 -0.5963 0.6765 +vn 0.2558 -0.3360 0.9065 +vn -0.2653 0.3227 -0.9086 +vn 0.0397 -0.0252 0.9989 +vn -0.0484 0.0109 -0.9988 +vn 0.1749 -0.3031 -0.9368 +vn -0.1839 0.2894 0.9394 +vn 0.1748 -0.3031 -0.9368 +vn 0.3704 -0.5713 -0.7324 +vn -0.3805 0.5596 0.7362 +vn -0.3805 0.5597 0.7362 +vn -0.5199 0.7436 0.4204 +vn -0.5808 0.8131 0.0400 +vn 0.5419 -0.7666 0.3444 +vn -0.5536 0.7573 -0.3464 +vn 0.4322 -0.5962 0.6766 +vn -0.5894 0.6898 0.4204 +vn -0.6515 0.7575 0.0422 +vn 0.5109 -0.7871 0.3457 +vn -0.6229 0.7035 -0.3422 +vn 0.3960 -0.6196 0.6777 +vn -0.6229 0.7034 -0.3423 +vn -0.5080 0.5360 -0.6743 +vn 0.2123 -0.3641 0.9068 +vn -0.3243 0.2805 -0.9034 +vn -0.0122 -0.0596 0.9981 +vn -0.0998 -0.0240 -0.9947 +vn 0.1314 -0.3313 -0.9343 +vn -0.2434 0.2476 0.9378 +vn 0.3341 -0.5944 -0.7315 +vn -0.4461 0.5108 0.7349 +vn -0.5969 0.8013 0.0405 +vn -0.5347 0.7335 0.4197 +vn 0.0753 -0.3701 -0.9260 +vn 0.2765 -0.6314 -0.7245 +vn 0.4188 -0.8091 -0.4123 +vn -0.4981 0.4659 0.7313 +vn -0.6403 0.6437 0.4191 +vn 0.4804 -0.8763 -0.0368 +vn -0.7020 0.7109 0.0435 +vn 0.4520 -0.8226 0.3449 +vn -0.6736 0.6572 -0.3381 +vn 0.3380 -0.6564 0.6745 +vn -0.5596 0.4909 -0.6677 +vn 0.3380 -0.6563 0.6745 +vn 0.1556 -0.4027 0.9020 +vn -0.3772 0.2373 -0.8952 +vn -0.0673 -0.1004 0.9927 +vn -0.1543 -0.0651 -0.9859 +vn 0.0753 -0.3701 -0.9259 +vn 0.2250 0.5442 0.8082 +vn 0.0624 -0.3572 -0.9320 +vn 0.2276 -0.6460 -0.7286 +vn 0.3460 -0.8425 -0.4129 +vn 0.3995 -0.9161 -0.0340 +vn 0.3799 -0.8559 0.3508 +vn 0.3858 -0.6244 0.6791 +vn 0.2903 -0.6710 0.6823 +vn 0.1443 -0.3899 0.9095 +vn -0.0357 -0.0556 0.9978 +vn -0.2219 0.2800 0.9340 +vn -0.3857 0.5656 0.7289 +vn -0.5025 0.7587 0.4147 +vn -0.5551 0.8309 0.0392 +vn -0.5360 0.7719 -0.3418 +vn -0.4477 0.5903 -0.6716 +vn 0.0624 -0.3571 -0.9320 +vn -0.8793 -0.4625 -0.1138 +vn -0.9046 -0.4080 -0.1235 +vn -0.8567 -0.5092 -0.0819 +vn -0.8404 -0.5410 -0.0325 +vn -0.8328 -0.5529 0.0268 +vn -0.8351 -0.5432 0.0869 +vn -0.8469 -0.5133 0.1388 +vn -0.8665 -0.4677 0.1743 +vn -0.8908 -0.4136 0.1881 +vn -0.9161 -0.3591 0.1782 +vn -0.9386 -0.3126 0.1461 +vn -0.9548 -0.2810 0.0966 +vn -0.9702 0.0569 0.2357 +vn -0.9623 -0.2693 0.0375 +vn -0.9600 -0.2790 -0.0224 +vn -0.9482 -0.3088 -0.0740 +vn -0.9288 -0.3541 -0.1095 +vn -0.8866 -0.1781 -0.4268 +vn -0.2287 -0.4651 -0.8552 +vn -0.3929 -0.1481 -0.9076 +vn 0.2275 -0.6460 -0.7286 +vn -0.0816 -0.7391 -0.6686 +vn 0.0250 -0.9265 -0.3755 +vn -0.3046 -0.9056 -0.2953 +vn 0.0740 -0.9970 -0.0211 +vn 0.0576 -0.9392 0.3386 +vn -0.0217 -0.7623 0.6469 +vn 0.0575 -0.9392 0.3386 +vn -0.0218 -0.7623 0.6468 +vn -0.1510 -0.4950 0.8557 +vn -0.3095 -0.1799 0.9337 +vn -0.4726 0.1339 0.8711 +vn -0.6855 -0.0245 0.7277 +vn -0.2219 0.2801 0.9340 +vn -0.6155 0.3992 0.6796 +vn -0.6855 -0.0246 0.7277 +vn -0.7174 0.5775 0.3898 +vn -0.7639 0.6438 0.0450 +vn -0.7486 0.5891 -0.3044 +vn -0.6735 0.4208 -0.6077 +vn -0.5489 0.1627 -0.8199 +vn -0.6734 0.4208 -0.6078 +vn -0.6283 -0.2608 -0.7330 +vn 0.5970 -0.8012 -0.0405 +vn 0.5347 -0.7334 -0.4197 +vn 0.5347 -0.7335 -0.4197 +vn -0.5683 0.7471 -0.3448 +vn 0.5683 -0.7471 0.3448 +vn -0.4531 0.5792 -0.6776 +vn -0.4531 0.5792 -0.6777 +vn 0.4531 -0.5792 0.6777 +vn -0.2690 0.3231 -0.9073 +vn 0.2690 -0.3231 0.9073 +vn -0.0439 0.0178 -0.9989 +vn -0.1879 0.2902 0.9384 +vn 0.0439 -0.0178 0.9989 +vn -0.1879 0.2901 0.9384 +vn 0.1879 -0.2902 -0.9384 +vn -0.3910 0.5540 0.7350 +vn 0.3911 -0.5540 -0.7350 +usemtl Scene_-_Root +s off +f 20816/20671/14786 20817/20672/14786 20818/20673/14786 +f 20816/20671/14786 20818/20673/14786 20819/20674/14786 +f 20817/20672/14786 20820/20675/14786 20821/20676/14786 +f 20817/20672/14786 20821/20676/14786 20818/20673/14786 +f 20820/20675/14786 20822/20677/14786 20823/20678/14786 +f 20820/20675/14786 20823/20678/14786 20821/20676/14786 +f 20822/20677/14787 20824/20679/14787 20825/20680/14787 +f 20822/20677/14786 20825/20680/14786 20823/20678/14786 +f 20824/20679/14786 20826/20681/14786 20827/20682/14786 +f 20824/20679/14786 20827/20682/14786 20825/20680/14786 +f 20826/20681/14786 20828/20683/14786 20829/20684/14786 +f 20826/20681/14786 20829/20684/14786 20827/20682/14786 +f 20828/20683/14786 20830/20685/14786 20831/20686/14786 +f 20828/20683/14786 20831/20686/14786 20829/20684/14786 +f 20830/20685/14786 20832/20687/14786 20833/20688/14786 +f 20830/20685/14786 20833/20688/14786 20831/20686/14786 +f 20834/20689/14786 20835/20690/14786 20836/20691/14786 +f 20834/20689/14786 20836/20691/14786 20837/20692/14786 +f 20835/20690/14787 20838/20693/14787 20839/20694/14787 +f 20835/20690/14786 20839/20694/14786 20836/20691/14786 +f 20838/20693/14786 20840/20695/14786 20841/20696/14786 +f 20838/20693/14786 20841/20696/14786 20839/20694/14786 +f 20840/20695/14786 20842/20697/14786 20843/20698/14786 +f 20840/20695/14786 20843/20698/14786 20841/20696/14786 +f 20842/20697/14786 20844/20699/14786 20845/20700/14786 +f 20842/20697/14786 20845/20700/14786 20843/20698/14786 +f 20844/20699/14786 20816/20671/14786 20819/20674/14786 +f 20844/20699/14786 20819/20674/14786 20845/20700/14786 +f 20965/20701/14786 20834/20689/14786 20837/20692/14786 +f 20834/20689/14786 20965/20701/14786 20966/20702/14786 +f 20834/20689/14786 20966/20702/14786 20964/20703/14786 +f 20968/20704/14788 20813/20705/14789 20967/20706/14790 +f 20970/20707/14791 20968/20704/14788 20969/20708/14792 +f 20971/20709/14786 20964/20703/14786 20966/20702/14786 +f 20964/20703/14786 20971/20709/14786 20832/20687/14786 +f 20832/20687/14786 20971/20709/14786 20833/20688/14786 +f 20978/20710/14793 20976/20711/14793 20977/20712/14793 +f 20976/20711/14786 20978/20710/14786 20979/20713/14786 +f 20976/20711/14786 20979/20713/14786 20975/20714/14786 +f 20975/20714/14786 20979/20713/14786 20974/20715/14786 +f 20974/20715/14786 20979/20713/14786 20980/20716/14786 +f 20974/20715/14786 20980/20716/14786 20981/20717/14786 +f 20974/20715/14786 20981/20717/14786 20973/20718/14786 +f 20973/20718/14786 20981/20717/14786 20972/20719/14786 +f 20972/20719/14786 20981/20717/14786 20982/20720/14786 +f 20972/20719/14786 20982/20720/14786 20983/20721/14786 +f 20972/20719/14786 20983/20721/14786 20987/20722/14786 +f 20987/20722/14786 20983/20721/14786 20984/20723/14786 +f 20987/20722/14786 20984/20723/14786 20986/20724/14786 +f 20986/20724/14793 20984/20723/14793 20985/20725/14793 +s 1 +f 20671/20726/14794 20672/20727/14795 20673/20728/14796 +f 20671/20726/14794 20673/20728/14796 20674/20729/14797 +f 20675/20730/14798 20676/20731/14799 20677/20732/14800 +f 20675/20730/14798 20677/20732/14800 20678/20733/14801 +f 20679/20734/14802 20675/20730/14798 20678/20733/14801 +f 20679/20734/14802 20678/20733/14801 20680/20735/14803 +f 20681/20736/14804 20679/20734/14802 20680/20735/14803 +f 20681/20736/14804 20680/20735/14803 20682/20737/14805 +f 20683/20738/14806 20681/20736/14804 20682/20737/14805 +f 20683/20738/14806 20682/20737/14805 20684/20739/14807 +f 20685/20740/14808 20683/20738/14806 20684/20739/14807 +f 20685/20740/14808 20684/20739/14807 20686/20741/14809 +f 20687/20742/14810 20685/20740/14808 20686/20741/14809 +f 20687/20742/14810 20686/20741/14809 20688/20743/14811 +f 20689/20744/14812 20687/20742/14810 20688/20743/14811 +f 20689/20744/14812 20688/20743/14811 20690/20745/14813 +f 20691/20746/14814 20689/20744/14812 20690/20745/14813 +f 20691/20746/14814 20690/20745/14813 20692/20747/14815 +f 20693/20748/14816 20691/20746/14814 20692/20747/14815 +f 20693/20748/14816 20692/20747/14815 20694/20749/14817 +f 20695/20750/14818 20696/20751/14819 20697/20752/14820 +f 20695/20750/14818 20697/20752/14820 20698/20753/14821 +f 20699/20754/14822 20695/20750/14818 20698/20753/14821 +f 20699/20754/14822 20698/20753/14821 20700/20755/14823 +f 20701/20756/14824 20699/20754/14822 20700/20755/14823 +f 20701/20756/14824 20700/20755/14823 20702/20757/14825 +f 20703/20758/14826 20704/20759/14824 20705/20760/14827 +f 20703/20758/14826 20705/20760/14827 20706/20761/14828 +f 20707/20762/14829 20708/20763/14830 20709/20764/14831 +f 20707/20762/14829 20709/20764/14831 20710/20765/14832 +f 20711/20766/14833 20712/20767/14826 20713/20768/14828 +f 20711/20766/14833 20713/20768/14828 20714/20769/14834 +f 20715/20770/14835 20711/20766/14833 20714/20769/14834 +f 20715/20770/14835 20714/20769/14834 20716/20771/14836 +f 20717/20772/14837 20718/20773/14838 20719/20774/14839 +f 20717/20772/14837 20719/20774/14839 20720/20775/14840 +f 20721/20776/14841 20722/20777/14842 20723/20778/14843 +f 20721/20776/14841 20723/20778/14843 20724/20779/14844 +f 20673/20728/14796 20672/20727/14795 20725/20780/14845 +f 20673/20728/14796 20725/20780/14845 20726/20781/14846 +f 20727/20782/14847 20728/20783/14848 20729/20784/14849 +f 20727/20782/14847 20729/20784/14849 20730/20785/14850 +f 20731/20786/14851 20732/20787/14852 20733/20788/14853 +f 20731/20786/14851 20733/20788/14853 20734/20789/14854 +f 20735/20790/14855 20736/20791/14856 20718/20773/14838 +f 20735/20790/14855 20718/20773/14838 20717/20772/14837 +f 20737/20792/14857 20738/20793/14858 20739/20794/14859 +f 20737/20792/14857 20739/20794/14859 20740/20795/14860 +f 20741/20796/14861 20707/20762/14829 20710/20765/14832 +f 20741/20796/14861 20710/20765/14832 20742/20797/14862 +f 20743/20798/14863 20721/20776/14841 20724/20779/14844 +f 20743/20798/14863 20724/20779/14844 20744/20799/14864 +f 20745/20800/14830 20727/20782/14847 20730/20785/14850 +f 20745/20800/14830 20730/20785/14850 20746/20801/14831 +f 20747/20802/14842 20731/20786/14851 20734/20789/14854 +f 20747/20802/14842 20734/20789/14854 20748/20803/14865 +f 20672/20727/14795 20735/20790/14855 20717/20772/14837 +f 20672/20727/14795 20717/20772/14837 20725/20780/14845 +f 20728/20783/14848 20737/20792/14857 20740/20795/14860 +f 20728/20783/14848 20740/20795/14860 20729/20784/14849 +f 20732/20787/14852 20741/20796/14861 20742/20797/14862 +f 20732/20787/14852 20742/20797/14862 20733/20788/14853 +f 20749/20804/14856 20743/20798/14863 20744/20799/14864 +f 20749/20804/14856 20744/20799/14864 20750/20805/14838 +f 20751/20806/14858 20673/20728/14796 20726/20781/14846 +f 20751/20806/14858 20726/20781/14846 20752/20807/14866 +f 20753/20808/14867 20754/20809/14868 20755/20810/14869 +f 20753/20808/14867 20755/20810/14869 20756/20811/14870 +f 20742/20797/14862 20710/20765/14832 20757/20812/14871 +f 20742/20797/14862 20757/20812/14871 20758/20813/14872 +f 20725/20780/14845 20717/20772/14837 20720/20775/14840 +f 20725/20780/14845 20720/20775/14840 20759/20814/14873 +f 20733/20788/14853 20742/20797/14862 20758/20813/14872 +f 20733/20788/14853 20758/20813/14872 20760/20815/14874 +f 20752/20807/14866 20726/20781/14846 20761/20816/14875 +f 20752/20807/14866 20761/20816/14875 20762/20817/14876 +f 20726/20781/14846 20725/20780/14845 20759/20814/14873 +f 20726/20781/14846 20759/20814/14873 20761/20816/14875 +f 20734/20789/14854 20733/20788/14853 20760/20815/14874 +f 20734/20789/14854 20760/20815/14874 20763/20818/14877 +f 20740/20795/14860 20739/20794/14859 20764/20819/14878 +f 20740/20795/14860 20764/20819/14878 20765/20820/14879 +f 20748/20803/14865 20734/20789/14854 20763/20818/14877 +f 20748/20803/14865 20763/20818/14877 20766/20821/14880 +f 20729/20784/14849 20740/20795/14860 20765/20820/14879 +f 20729/20784/14849 20765/20820/14879 20754/20809/14868 +f 20724/20779/14844 20723/20778/14843 20767/20822/14881 +f 20724/20779/14844 20767/20822/14881 20768/20823/14882 +f 20730/20785/14850 20729/20784/14849 20754/20809/14868 +f 20730/20785/14850 20754/20809/14868 20753/20808/14867 +f 20744/20799/14864 20724/20779/14844 20768/20823/14882 +f 20744/20799/14864 20768/20823/14882 20769/20824/14883 +f 20746/20801/14831 20730/20785/14850 20753/20808/14867 +f 20746/20801/14831 20753/20808/14867 20770/20825/14884 +f 20750/20805/14838 20744/20799/14864 20769/20824/14883 +f 20750/20805/14838 20769/20824/14883 20771/20826/14885 +f 20772/20827/14832 20746/20801/14831 20770/20825/14884 +f 20772/20827/14832 20770/20825/14884 20773/20828/14886 +f 20769/20824/14883 20768/20823/14882 20774/20829/14887 +f 20769/20824/14883 20774/20829/14887 20775/20830/14888 +f 20770/20825/14884 20753/20808/14867 20756/20811/14870 +f 20770/20825/14884 20756/20811/14870 20776/20831/14889 +f 20771/20826/14885 20769/20824/14883 20775/20830/14888 +f 20771/20826/14885 20775/20830/14888 20777/20832/14890 +f 20757/20812/14871 20778/20833/14884 20779/20834/14889 +f 20757/20812/14871 20779/20834/14889 20780/20835/14891 +f 20720/20775/14840 20719/20774/14839 20781/20836/14892 +f 20720/20775/14840 20781/20836/14892 20782/20837/14893 +f 20758/20813/14872 20757/20812/14871 20780/20835/14891 +f 20758/20813/14872 20780/20835/14891 20783/20838/14894 +f 20759/20814/14873 20720/20775/14840 20782/20837/14893 +f 20759/20814/14873 20782/20837/14893 20784/20839/14895 +f 20760/20815/14874 20758/20813/14872 20783/20838/14894 +f 20760/20815/14874 20783/20838/14894 20785/20840/14896 +f 20762/20817/14876 20761/20816/14875 20786/20841/14897 +f 20762/20817/14876 20786/20841/14897 20787/20842/14898 +f 20761/20816/14875 20759/20814/14873 20784/20839/14895 +f 20761/20816/14875 20784/20839/14895 20786/20841/14897 +f 20763/20818/14877 20760/20815/14874 20785/20840/14896 +f 20763/20818/14877 20785/20840/14896 20788/20843/14899 +f 20765/20820/14879 20764/20819/14878 20789/20844/14898 +f 20765/20820/14879 20789/20844/14898 20790/20845/14900 +f 20766/20821/14880 20763/20818/14877 20788/20843/14899 +f 20766/20821/14880 20788/20843/14899 20791/20846/14901 +f 20754/20809/14868 20765/20820/14879 20790/20845/14900 +f 20754/20809/14868 20790/20845/14900 20755/20810/14869 +f 20768/20823/14882 20767/20822/14881 20792/20847/14901 +f 20768/20823/14882 20792/20847/14901 20774/20829/14887 +f 20793/20848/14902 20794/20849/14903 20795/20850/14903 +f 20793/20848/14902 20795/20850/14903 20796/20851/14902 +f 20790/20845/14900 20789/20844/14898 20797/20852/14904 +f 20790/20845/14900 20797/20852/14904 20798/20853/14905 +f 20755/20810/14869 20790/20845/14900 20798/20853/14905 +f 20755/20810/14869 20798/20853/14905 20799/20854/14906 +f 20774/20829/14887 20792/20847/14901 20800/20855/14907 +f 20774/20829/14887 20800/20855/14907 20801/20856/14908 +f 20756/20811/14870 20755/20810/14869 20799/20854/14906 +f 20756/20811/14870 20799/20854/14906 20802/20857/14909 +f 20775/20830/14888 20774/20829/14887 20801/20856/14908 +f 20775/20830/14888 20801/20856/14908 20803/20858/14910 +f 20776/20831/14889 20756/20811/14870 20802/20857/14909 +f 20776/20831/14889 20802/20857/14909 20804/20859/14911 +f 20777/20832/14890 20775/20830/14888 20803/20858/14910 +f 20777/20832/14890 20803/20858/14910 20805/20860/14912 +f 20806/20861/14891 20776/20831/14889 20804/20859/14911 +f 20806/20861/14891 20804/20859/14911 20807/20862/14913 +f 20782/20837/14893 20781/20836/14892 20808/20863/14912 +f 20782/20837/14893 20808/20863/14912 20809/20864/14914 +f 20783/20838/14894 20780/20835/14891 20810/20865/14915 +f 20783/20838/14894 20810/20865/14915 20811/20866/14916 +f 20784/20839/14895 20782/20837/14893 20809/20864/14914 +f 20784/20839/14895 20809/20864/14914 20812/20867/14917 +f 20785/20840/14896 20783/20838/14894 20811/20866/14916 +f 20785/20840/14896 20811/20866/14916 20813/20705/14918 +f 20787/20842/14898 20786/20841/14897 20814/20868/14919 +f 20787/20842/14898 20814/20868/14919 20815/20869/14920 +f 20786/20841/14897 20784/20839/14895 20812/20867/14917 +f 20786/20841/14897 20812/20867/14917 20814/20868/14919 +f 20846/20870/14921 20847/20871/14921 20848/20872/14921 +f 20846/20870/14921 20848/20872/14921 20849/20873/14921 +f 20674/20729/14797 20673/20728/14796 20751/20806/14858 +f 20674/20729/14797 20751/20806/14858 20850/20874/14922 +f 20851/20875/14923 20737/20792/14857 20728/20783/14848 +f 20851/20875/14923 20728/20783/14848 20852/20876/14924 +f 20852/20876/14924 20728/20783/14848 20727/20782/14847 +f 20852/20876/14924 20727/20782/14847 20853/20877/14925 +f 20853/20877/14925 20727/20782/14847 20745/20800/14830 +f 20853/20877/14925 20745/20800/14830 20854/20878/14926 +f 20854/20878/14926 20745/20800/14830 20855/20879/14927 +f 20854/20878/14926 20855/20879/14927 20856/20880/14928 +f 20857/20881/14928 20707/20762/14829 20741/20796/14861 +f 20857/20881/14928 20741/20796/14861 20858/20882/14929 +f 20858/20882/14929 20741/20796/14861 20732/20787/14852 +f 20858/20882/14929 20732/20787/14852 20859/20883/14930 +f 20859/20883/14930 20732/20787/14852 20731/20786/14851 +f 20859/20883/14930 20731/20786/14851 20860/20884/14931 +f 20860/20884/14931 20731/20786/14851 20747/20802/14842 +f 20860/20884/14931 20747/20802/14842 20861/20885/14932 +f 20862/20886/14932 20722/20777/14842 20721/20776/14841 +f 20862/20886/14932 20721/20776/14841 20863/20887/14933 +f 20863/20887/14933 20721/20776/14841 20743/20798/14863 +f 20863/20887/14933 20743/20798/14863 20864/20888/14934 +f 20864/20888/14934 20743/20798/14863 20749/20804/14856 +f 20864/20888/14934 20749/20804/14856 20865/20889/14935 +f 20866/20890/14935 20736/20791/14856 20735/20790/14855 +f 20866/20890/14935 20735/20790/14855 20867/20891/14936 +f 20867/20891/14936 20735/20790/14855 20672/20727/14795 +f 20867/20891/14936 20672/20727/14795 20671/20726/14794 +f 20868/20892/14937 20738/20793/14858 20737/20792/14857 +f 20868/20892/14937 20737/20792/14857 20851/20875/14923 +f 20869/20893/14938 20870/20894/14939 20871/20895/14835 +f 20869/20893/14938 20871/20895/14835 20676/20731/14799 +f 20872/20896/14940 20869/20893/14938 20676/20731/14799 +f 20872/20896/14940 20676/20731/14799 20675/20730/14798 +f 20873/20897/14941 20872/20896/14940 20675/20730/14798 +f 20873/20897/14941 20675/20730/14798 20679/20734/14802 +f 20874/20898/14942 20873/20897/14941 20679/20734/14802 +f 20874/20898/14942 20679/20734/14802 20681/20736/14804 +f 20875/20899/14943 20874/20898/14942 20681/20736/14804 +f 20875/20899/14943 20681/20736/14804 20683/20738/14806 +f 20876/20900/14944 20875/20899/14943 20683/20738/14806 +f 20876/20900/14944 20683/20738/14806 20685/20740/14808 +f 20877/20901/14945 20876/20900/14944 20685/20740/14808 +f 20877/20901/14945 20685/20740/14808 20687/20742/14810 +f 20878/20902/14946 20877/20901/14945 20687/20742/14810 +f 20878/20902/14946 20687/20742/14810 20689/20744/14812 +f 20879/20903/14947 20878/20902/14946 20689/20744/14812 +f 20879/20903/14947 20689/20744/14812 20691/20746/14814 +f 20880/20904/14948 20879/20903/14947 20691/20746/14814 +f 20880/20904/14948 20691/20746/14814 20693/20748/14816 +f 20881/20905/14949 20880/20904/14948 20693/20748/14816 +f 20881/20905/14949 20693/20748/14816 20882/20906/14950 +f 20883/20907/14951 20881/20905/14949 20882/20906/14950 +f 20883/20907/14951 20882/20906/14950 20884/20908/14822 +f 20885/20909/14952 20883/20907/14951 20884/20908/14822 +f 20885/20909/14952 20884/20908/14822 20704/20759/14824 +f 20886/20910/14953 20885/20909/14952 20704/20759/14824 +f 20886/20910/14953 20704/20759/14824 20703/20758/14826 +f 20887/20911/14954 20886/20910/14953 20703/20758/14826 +f 20887/20911/14954 20703/20758/14826 20888/20912/14955 +f 20870/20894/14939 20887/20911/14954 20888/20912/14955 +f 20870/20894/14939 20888/20912/14955 20871/20895/14835 +f 20674/20729/14797 20850/20874/14922 20889/20913/14956 +f 20674/20729/14797 20889/20913/14956 20890/20914/14957 +f 20890/20914/14957 20889/20913/14956 20891/20915/14800 +f 20890/20914/14957 20891/20915/14800 20716/20771/14836 +f 20850/20874/14922 20892/20916/14958 20893/20917/14959 +f 20850/20874/14922 20893/20917/14959 20889/20913/14956 +f 20889/20913/14956 20893/20917/14959 20894/20918/14801 +f 20889/20913/14956 20894/20918/14801 20891/20915/14800 +f 20851/20875/14923 20852/20876/14924 20895/20919/14960 +f 20851/20875/14923 20895/20919/14960 20896/20920/14959 +f 20896/20920/14959 20895/20919/14960 20897/20921/14961 +f 20896/20920/14959 20897/20921/14961 20898/20922/14801 +f 20852/20876/14924 20853/20877/14925 20899/20923/14962 +f 20852/20876/14924 20899/20923/14962 20895/20919/14960 +f 20895/20919/14960 20899/20923/14962 20900/20924/14805 +f 20895/20919/14960 20900/20924/14805 20897/20921/14961 +f 20853/20877/14925 20854/20878/14926 20901/20925/14963 +f 20853/20877/14925 20901/20925/14963 20899/20923/14962 +f 20899/20923/14962 20901/20925/14963 20902/20926/14807 +f 20899/20923/14962 20902/20926/14807 20900/20924/14805 +f 20903/20927/14926 20857/20881/14928 20904/20928/14964 +f 20903/20927/14926 20904/20928/14964 20905/20929/14965 +f 20906/20930/14965 20907/20931/14966 20686/20741/14809 +f 20906/20930/14965 20686/20741/14809 20684/20739/14807 +f 20857/20881/14928 20858/20882/14929 20908/20932/14967 +f 20857/20881/14928 20908/20932/14967 20904/20928/14964 +f 20904/20928/14964 20908/20932/14967 20909/20933/14811 +f 20904/20928/14964 20909/20933/14811 20910/20934/14809 +f 20858/20882/14929 20859/20883/14930 20911/20935/14968 +f 20858/20882/14929 20911/20935/14968 20908/20932/14967 +f 20908/20932/14967 20911/20935/14968 20912/20936/14813 +f 20908/20932/14967 20912/20936/14813 20909/20933/14811 +f 20859/20883/14930 20860/20884/14931 20913/20937/14969 +f 20859/20883/14930 20913/20937/14969 20911/20935/14968 +f 20911/20935/14968 20913/20937/14969 20914/20938/14970 +f 20911/20935/14968 20914/20938/14970 20912/20936/14813 +f 20915/20939/14971 20862/20886/14932 20916/20940/14972 +f 20915/20939/14971 20916/20940/14972 20917/20941/14969 +f 20917/20941/14969 20916/20940/14972 20697/20752/14820 +f 20917/20941/14969 20697/20752/14820 20918/20942/14973 +f 20862/20886/14932 20863/20887/14933 20919/20943/14974 +f 20862/20886/14932 20919/20943/14974 20916/20940/14972 +f 20916/20940/14972 20919/20943/14974 20698/20753/14821 +f 20916/20940/14972 20698/20753/14821 20697/20752/14820 +f 20863/20887/14933 20864/20888/14934 20920/20944/14975 +f 20863/20887/14933 20920/20944/14975 20919/20943/14974 +f 20919/20943/14974 20920/20944/14975 20700/20755/14823 +f 20919/20943/14974 20700/20755/14823 20698/20753/14821 +f 20864/20888/14934 20865/20889/14935 20921/20945/14976 +f 20864/20888/14934 20921/20945/14976 20920/20944/14975 +f 20920/20944/14975 20921/20945/14976 20702/20757/14825 +f 20920/20944/14975 20702/20757/14825 20700/20755/14823 +f 20865/20889/14935 20922/20946/14936 20923/20947/14977 +f 20865/20889/14935 20923/20947/14977 20921/20945/14976 +f 20921/20945/14976 20923/20947/14977 20924/20948/14828 +f 20921/20945/14976 20924/20948/14828 20702/20757/14825 +f 20867/20891/14936 20671/20726/14794 20925/20949/14978 +f 20867/20891/14936 20925/20949/14978 20926/20950/14979 +f 20926/20950/14979 20925/20949/14978 20714/20769/14834 +f 20926/20950/14979 20714/20769/14834 20713/20768/14828 +f 20671/20726/14794 20674/20729/14797 20890/20914/14957 +f 20671/20726/14794 20890/20914/14957 20925/20949/14978 +f 20925/20949/14978 20890/20914/14957 20716/20771/14836 +f 20925/20949/14978 20716/20771/14836 20714/20769/14834 +f 20676/20731/14799 20871/20895/14835 20927/20951/14980 +f 20676/20731/14799 20927/20951/14980 20677/20732/14800 +f 20928/20952/14981 20929/20953/14982 20930/20954/14983 +f 20928/20952/14981 20930/20954/14983 20931/20955/14981 +f 20932/20956/14984 20793/20848/14902 20796/20851/14902 +f 20932/20956/14984 20796/20851/14902 20933/20957/14984 +f 20934/20958/14985 20928/20952/14981 20931/20955/14981 +f 20934/20958/14985 20931/20955/14981 20935/20959/14985 +f 20936/20960/14986 20937/20961/14984 20938/20962/14984 +f 20936/20960/14986 20938/20962/14984 20939/20963/14987 +f 20940/20964/14988 20941/20965/14985 20942/20966/14985 +f 20940/20964/14988 20942/20966/14985 20943/20967/14988 +f 20944/20968/14989 20936/20960/14986 20939/20963/14987 +f 20944/20968/14989 20939/20963/14987 20945/20969/14989 +f 20946/20970/14990 20940/20964/14988 20943/20967/14988 +f 20946/20970/14990 20943/20967/14988 20947/20971/14990 +f 20948/20972/14991 20944/20968/14989 20945/20969/14989 +f 20948/20972/14991 20945/20969/14989 20949/20973/14991 +f 20950/20974/14992 20951/20975/14993 20952/20976/14993 +f 20950/20974/14992 20952/20976/14993 20953/20977/14994 +f 20951/20975/14993 20946/20970/14990 20947/20971/14990 +f 20951/20975/14993 20947/20971/14990 20952/20976/14993 +f 20954/20978/14995 20948/20972/14991 20949/20973/14991 +f 20954/20978/14995 20949/20973/14991 20955/20979/14995 +f 20956/20980/14996 20950/20974/14992 20953/20977/14994 +f 20956/20980/14996 20953/20977/14994 20957/20981/14996 +f 20958/20982/14997 20959/20983/14995 20960/20984/14995 +f 20958/20982/14997 20960/20984/14995 20961/20985/14997 +f 20794/20849/14903 20962/20986/14996 20963/20987/14996 +f 20794/20849/14903 20963/20987/14996 20795/20850/14903 +f 20929/20953/14982 20958/20982/14997 20961/20985/14997 +f 20929/20953/14982 20961/20985/14997 20930/20954/14983 +f 20885/20909/14952 20881/20905/14949 20883/20907/14951 +f 20881/20905/14949 20885/20909/14952 20880/20904/14948 +f 20880/20904/14948 20885/20909/14952 20886/20910/14953 +f 20880/20904/14948 20886/20910/14953 20879/20903/14947 +f 20879/20903/14947 20886/20910/14953 20887/20911/14954 +f 20879/20903/14947 20887/20911/14954 20878/20902/14946 +f 20878/20902/14946 20887/20911/14954 20870/20894/14939 +f 20878/20902/14946 20870/20894/14939 20869/20893/14938 +f 20878/20902/14946 20869/20893/14938 20877/20901/14945 +f 20877/20901/14945 20869/20893/14938 20872/20896/14940 +f 20877/20901/14945 20872/20896/14940 20876/20900/14944 +f 20876/20900/14944 20872/20896/14940 20873/20897/14941 +f 20876/20900/14944 20873/20897/14941 20875/20899/14943 +f 20875/20899/14943 20873/20897/14941 20874/20898/14942 +f 20785/20840/14896 20968/20704/14788 20788/20843/14899 +f 20968/20704/14788 20785/20840/14896 20813/20705/14918 +f 20788/20843/14899 20970/20707/14907 20791/20846/14901 +f 20970/20707/14907 20788/20843/14899 20968/20704/14788 +o Cube.037__0 +v -0.059895 0.338427 0.184206 +v -0.101168 0.400477 0.174596 +v -0.224931 0.310676 0.178432 +v -0.183659 0.248626 0.188041 +v 0.282591 0.503845 0.126801 +v 0.305195 0.465656 0.045105 +v 0.253686 0.429718 0.046538 +v 0.232333 0.470645 0.123840 +v -0.159579 0.463892 0.003961 +v -0.283343 0.374092 0.007797 +v -0.270219 0.371922 0.116218 +v -0.146455 0.461723 0.112382 +v -0.194210 0.261235 -0.076766 +v -0.164423 0.213607 -0.059129 +v -0.113422 0.250612 -0.060710 +v -0.143208 0.298240 -0.078346 +v 0.105115 0.480697 -0.107972 +v 0.058257 0.539680 -0.091153 +v 0.182020 0.629480 -0.094989 +v 0.228879 0.570498 -0.111808 +v 0.016450 0.229170 0.010366 +v -0.110839 0.146792 0.013178 +v -0.158295 0.204203 -0.081537 +v -0.034531 0.294003 -0.085373 +v 0.015868 0.594651 -0.001415 +v 0.139632 0.684451 -0.005251 +v 0.182020 0.629480 -0.094989 +v 0.058257 0.539680 -0.091153 +v 0.194061 0.359049 0.054248 +v 0.318333 0.447782 0.050559 +v 0.293367 0.489941 0.144650 +v 0.170401 0.403893 0.144417 +v -0.146455 0.461723 0.112382 +v -0.270219 0.371922 0.116218 +v 0.191897 0.359928 0.004990 +v 0.316168 0.448661 0.001302 +v 0.314632 0.381021 0.003290 +v 0.224351 0.317095 0.006116 +v 0.072520 0.197937 0.053396 +v -0.010562 0.130571 0.055844 +v 0.075317 0.016513 0.044094 +v 0.149773 0.064813 0.041684 +v 0.316168 0.448661 0.001302 +v 0.318333 0.447782 0.050559 +v 0.316505 0.380260 0.045928 +v 0.314632 0.381021 0.003290 +v 0.018615 0.228291 0.059624 +v -0.108675 0.145913 0.062435 +v -0.108675 0.145913 0.062435 +v -0.110839 0.146792 0.013178 +v -0.012436 0.131332 0.013206 +v -0.010562 0.130571 0.055844 +v 0.078160 -0.460433 0.024236 +v 0.076984 -0.459034 0.008327 +v 0.007053 -0.662309 0.008988 +v 0.007362 -0.662434 0.016001 +v -0.010562 0.130571 0.055844 +v -0.012436 0.131332 0.013206 +v 0.073964 0.017063 0.013309 +v 0.075317 0.016513 0.044094 +v 0.447135 0.367191 0.000921 +v 0.357634 0.228313 0.004614 +v 0.314632 0.381021 0.003290 +v 0.316505 0.380260 0.045928 +v 0.448684 0.366561 0.036174 +v 0.447135 0.367191 0.000921 +v 0.762591 -0.211901 -0.016175 +v 0.772277 -0.157055 -0.015884 +v 0.772593 -0.157184 -0.008696 +v 0.762900 -0.212027 -0.009161 +v 0.859022 0.140630 -0.015336 +v 0.860198 0.139231 0.000574 +v 0.974107 0.039018 -0.013962 +v 0.973799 0.039144 -0.020975 +v 0.265872 -0.369181 0.017616 +v 0.078160 -0.460433 0.024236 +v 0.007362 -0.662434 0.016001 +v 0.308177 -0.539529 0.004975 +v 0.185322 -0.066423 0.036563 +v 0.104216 -0.127755 0.039032 +v 0.109509 -0.285674 0.034764 +v 0.222662 -0.196624 0.031381 +v 0.577543 0.321067 -0.003245 +v 0.578883 0.320523 0.027242 +v 0.727845 0.245625 0.017348 +v 0.726681 0.246098 -0.009127 +v 0.473770 0.161619 -0.000464 +v 0.577543 0.321067 -0.003245 +v 0.726681 0.246098 -0.009127 +v 0.575862 0.082028 -0.005155 +v 0.104216 -0.127755 0.039032 +v 0.102970 -0.127249 0.010675 +v 0.108369 -0.285211 0.008834 +v 0.109509 -0.285674 0.034764 +v 0.102970 -0.127249 0.010675 +v 0.184076 -0.065917 0.008205 +v 0.221522 -0.196161 0.005451 +v 0.108369 -0.285211 0.008834 +v 0.264385 0.001144 0.005873 +v 0.339731 -0.103098 0.001917 +v 0.578883 0.320523 0.027242 +v 0.475016 0.161113 0.027894 +v 0.577001 0.081565 0.020775 +v 0.727845 0.245625 0.017348 +v 0.265630 0.000638 0.034231 +v 0.340871 -0.103561 0.027848 +v 0.445642 -0.245386 0.011926 +v 0.549508 -0.385002 -0.002872 +v 0.076984 -0.459034 0.008327 +v 0.264695 -0.367782 0.001706 +v 0.307869 -0.539404 -0.002038 +v 0.007053 -0.662309 0.008988 +v 0.444465 -0.243988 -0.003984 +v 0.549199 -0.384877 -0.009885 +v 0.007053 -0.662309 0.008988 +v 0.307869 -0.539404 -0.002038 +v 0.308177 -0.539529 0.004975 +v 0.007362 -0.662434 0.016001 +v 0.549199 -0.384877 -0.009885 +v 0.549508 -0.385002 -0.002872 +v 0.974107 0.039018 -0.013962 +v 0.814616 -0.160017 -0.010506 +v 0.814308 -0.159893 -0.017519 +v 0.973799 0.039144 -0.020975 +v -0.012436 0.131332 0.013206 +v 0.070646 0.198699 0.010758 +v 0.148420 0.065363 0.010899 +v 0.073964 0.017063 0.013309 +v 0.103686 0.221923 0.009720 +v 0.195715 0.102085 0.009476 +v 0.318333 0.447782 0.050559 +v 0.194061 0.359049 0.054248 +v 0.226225 0.316334 0.048754 +v 0.316505 0.380260 0.045928 +v 0.070298 0.269248 0.058084 +v 0.105559 0.221162 0.052358 +v 0.358987 0.227763 0.035399 +v 0.448684 0.366561 0.036174 +v 0.197068 0.101535 0.040262 +v -0.110839 0.146792 0.013178 +v 0.016450 0.229170 0.010366 +v 0.068133 0.270128 0.008826 +v 0.152756 0.682282 0.103170 +v 0.028993 0.592481 0.107006 +v 0.074279 0.531235 0.169220 +v 0.198043 0.621036 0.165384 +v -0.093668 0.500356 0.111163 +v -0.049485 0.441435 0.173056 +v -0.108675 0.145913 0.062435 +v 0.018615 0.228291 0.059624 +v -0.004987 0.273078 0.150299 +v -0.128658 0.183187 0.154938 +v 0.070298 0.269248 0.058084 +v 0.046731 0.314003 0.149057 +v -0.117191 0.408921 -0.085777 +v -0.240955 0.319120 -0.081941 +v -0.106792 0.502525 0.002742 +v -0.065507 0.449879 -0.087317 +v 0.316168 0.448661 0.001302 +v 0.191897 0.359928 0.004990 +v 0.140916 0.424762 -0.090749 +v 0.264680 0.514563 -0.094584 +v 0.068133 0.270128 0.008826 +v 0.017152 0.334961 -0.086913 +v -0.194095 0.260138 -0.098760 +v -0.240955 0.319120 -0.081941 +v -0.117191 0.408921 -0.085777 +v -0.069824 0.348870 -0.102449 +v -0.065507 0.449879 -0.087317 +v -0.018648 0.390897 -0.104136 +v 0.028993 0.592481 0.107006 +v 0.152756 0.682282 0.103170 +v -0.093668 0.500356 0.111163 +v 0.237054 0.557315 0.180569 +v 0.115552 0.469185 0.178830 +v -0.008213 0.379384 0.182665 +v 0.447135 0.367191 0.000921 +v 0.448684 0.366561 0.036174 +v 0.703242 -0.041939 -0.011750 +v 0.704418 -0.043338 0.004160 +v 0.860198 0.139231 0.000574 +v 0.859022 0.140630 -0.015336 +v 0.076984 -0.459034 0.008327 +v 0.078160 -0.460433 0.024236 +v 0.258550 0.523967 -0.072177 +v 0.303587 0.466309 0.008520 +v 0.264680 0.514563 -0.094584 +v -0.123420 0.164440 0.020396 +v -0.164423 0.213607 -0.059129 +v -0.158295 0.204203 -0.081537 +v -0.110839 0.146792 0.013178 +v -0.235759 0.308067 -0.055487 +v -0.270055 0.356156 0.016673 +v -0.283343 0.374092 0.007797 +v -0.240955 0.319120 -0.081941 +v 0.152920 0.666516 0.003625 +v 0.187921 0.622270 -0.073407 +v 0.182020 0.629480 -0.094989 +v 0.139632 0.684451 -0.005251 +v -0.139435 0.197092 0.137088 +v -0.121813 0.163787 0.056981 +v -0.108675 0.145913 0.062435 +v -0.128658 0.183187 0.154938 +v 0.305195 0.465656 0.045105 +v 0.282591 0.503845 0.126801 +v 0.293367 0.489941 0.144650 +v 0.202017 0.614609 0.143125 +v 0.165187 0.664695 0.092530 +v 0.152756 0.682282 0.103170 +v 0.198043 0.621036 0.165384 +v -0.257787 0.354335 0.105578 +v -0.220958 0.304248 0.156172 +v -0.224931 0.310676 0.178432 +v -0.270219 0.371922 0.116218 +v -0.185700 0.250505 0.166195 +v -0.183659 0.248626 0.188041 +v -0.194210 0.261235 -0.076766 +v -0.194095 0.260138 -0.098760 +v 0.235013 0.559194 0.158723 +v 0.237054 0.557315 0.180569 +v 0.228765 0.571595 -0.089813 +v 0.228879 0.570498 -0.111808 +v 0.235013 0.559194 0.158723 +v 0.282591 0.503845 0.126801 +v 0.232333 0.470645 0.123840 +v 0.186273 0.523860 0.154728 +v 0.165187 0.664695 0.092530 +v 0.202017 0.614609 0.143125 +v 0.151015 0.577603 0.144706 +v 0.114186 0.627690 0.094111 +v 0.152920 0.666516 0.003625 +v 0.165187 0.664695 0.092530 +v 0.114186 0.627690 0.094111 +v 0.101918 0.629510 0.005206 +v -0.220958 0.304248 0.156172 +v -0.257787 0.354335 0.105578 +v -0.206786 0.391341 0.103997 +v -0.169956 0.341254 0.154592 +v 0.303587 0.466309 0.008520 +v 0.258550 0.523967 -0.072177 +v 0.207549 0.486961 -0.070596 +v 0.252078 0.430371 0.009953 +v 0.228765 0.571595 -0.089813 +v 0.187921 0.622270 -0.073407 +v 0.136919 0.585264 -0.071826 +v 0.177764 0.534589 -0.088233 +v -0.123420 0.164440 0.020396 +v -0.121813 0.163787 0.056981 +v -0.067286 0.193370 0.056424 +v -0.072418 0.201446 0.018816 +v -0.164423 0.213607 -0.059129 +v -0.113422 0.250612 -0.060710 +v -0.270055 0.356156 0.016673 +v -0.235759 0.308067 -0.055487 +v -0.184052 0.348916 -0.061940 +v -0.221314 0.391491 0.020668 +v -0.185700 0.250505 0.166195 +v -0.134698 0.287511 0.164614 +v 0.187921 0.622270 -0.073407 +v 0.136919 0.585264 -0.071826 +v -0.257787 0.354335 0.105578 +v -0.206786 0.391341 0.103997 +v -0.139435 0.197092 0.137088 +v -0.088471 0.234135 0.135176 +v 0.258550 0.523967 -0.072177 +v 0.207549 0.486961 -0.070596 +v 0.017152 0.334961 -0.086913 +v 0.140916 0.424762 -0.090749 +v -0.034531 0.294003 -0.085373 +v -0.158295 0.204203 -0.081537 +v 0.264680 0.514563 -0.094584 +v -0.235759 0.308067 -0.055487 +v -0.184052 0.348916 -0.061940 +v -0.139435 0.197092 0.137088 +v -0.088471 0.234135 0.135176 +v 0.046731 0.314003 0.149057 +v -0.004987 0.273078 0.150299 +v 0.170401 0.403893 0.144417 +v 0.293367 0.489941 0.144650 +v -0.128658 0.183187 0.154938 +v 0.772277 -0.157055 -0.015884 +v 0.772593 -0.157184 -0.008696 +v 0.772277 -0.157055 -0.015884 +v 0.762591 -0.211901 -0.016175 +v 0.762900 -0.212027 -0.009161 +v 0.772593 -0.157184 -0.008696 +v 0.814616 -0.160017 -0.010506 +v 0.974107 0.039018 -0.013962 +v 0.973799 0.039144 -0.020975 +v 0.814308 -0.159893 -0.017519 +vt 0.427997 0.258675 +vt 0.425207 0.261024 +vt 0.427806 0.263731 +vt 0.430222 0.261698 +vt 0.496337 0.247356 +vt 0.496890 0.250323 +vt 0.497412 0.250323 +vt 0.317361 0.230861 +vt 0.314855 0.215625 +vt 0.302641 0.220336 +vt 0.308067 0.243759 +vt 0.314656 0.199480 +vt 0.301668 0.199161 +vt 0.497507 0.182564 +vt 0.496875 0.205905 +vt 0.498016 0.182563 +vt 0.498016 0.270914 +vt 0.496511 0.252713 +vt 0.497507 0.270914 +vt 0.575645 0.220892 +vt 0.575448 0.216467 +vt 0.565996 0.213020 +vt 0.566616 0.220734 +vt 0.576353 0.236061 +vt 0.346192 0.199750 +vt 0.337911 0.180407 +vt 0.337160 0.199906 +vt 0.345994 0.204174 +vt 0.346256 0.210734 +vt 0.336539 0.207620 +vt 0.336298 0.215137 +vt 0.565756 0.205503 +vt 0.327643 0.199800 +vt 0.315809 0.175223 +vt 0.327070 0.210913 +vt 0.496890 0.250323 +vt 0.497019 0.252713 +vt 0.497412 0.250323 +vt 0.303004 0.178887 +vt 0.305904 0.175962 +vt 0.309151 0.155415 +vt 0.303937 0.173543 +vt 0.320186 0.158022 +vt 0.290633 0.057191 +vt 0.285195 0.056940 +vt 0.285177 0.068251 +vt 0.290615 0.068502 +vt 0.142410 0.001800 +vt 0.142365 0.008016 +vt 0.147010 0.008124 +vt 0.146850 0.002217 +vt 0.070208 0.282421 +vt 0.070200 0.271113 +vt 0.062215 0.271633 +vt 0.062223 0.282941 +vt 0.572103 0.780387 +vt 0.572501 0.776359 +vt 0.567840 0.776267 +vt 0.567441 0.780294 +vt 0.989278 0.210997 +vt 0.983685 0.210769 +vt 0.983770 0.222079 +vt 0.989363 0.222307 +vt 0.992400 0.116616 +vt 0.992436 0.105420 +vt 0.986395 0.105257 +vt 0.986382 0.116568 +vt 0.070200 0.298597 +vt 0.070208 0.309905 +vt 0.077108 0.310318 +vt 0.077100 0.299010 +vt 0.839526 0.021600 +vt 0.839545 0.010306 +vt 0.832092 0.010128 +vt 0.832338 0.021220 +vt 0.279924 0.056866 +vt 0.279906 0.068177 +vt 0.361923 0.188970 +vt 0.361976 0.177675 +vt 0.357959 0.180657 +vt 0.357953 0.188840 +vt 0.586821 0.217465 +vt 0.586302 0.209571 +vt 0.575711 0.209907 +vt 0.590976 0.215496 +vt 0.591431 0.204292 +vt 0.745033 0.607901 +vt 0.748575 0.607422 +vt 0.748575 0.602171 +vt 0.745509 0.602585 +vt 0.687786 0.253203 +vt 0.686624 0.253317 +vt 0.687273 0.266137 +vt 0.687786 0.266079 +vt 0.897468 0.005246 +vt 0.894311 0.005246 +vt 0.894746 0.015815 +vt 0.897026 0.015815 +vt 0.351467 0.173245 +vt 0.346902 0.184580 +vt 0.163428 0.089507 +vt 0.160288 0.089367 +vt 0.160831 0.096870 +vt 0.163428 0.096986 +vt 0.496846 0.247356 +vt 0.996617 0.280988 +vt 0.995436 0.281074 +vt 0.996015 0.292202 +vt 0.996534 0.292202 +vt 0.544213 0.204994 +vt 0.546720 0.189758 +vt 0.537501 0.176878 +vt 0.532074 0.200300 +vt 0.555985 0.199089 +vt 0.556530 0.209726 +vt 0.996845 0.257362 +vt 0.994588 0.257362 +vt 0.994757 0.268712 +vt 0.996717 0.268712 +vt 0.343112 0.167334 +vt 0.332212 0.161520 +vt 0.328741 0.177633 +vt 0.896964 0.025866 +vt 0.894864 0.025866 +vt 0.894997 0.035778 +vt 0.896917 0.035778 +vt 0.326523 0.221550 +vt 0.572561 0.253308 +vt 0.567364 0.240233 +vt 0.558196 0.243006 +vt 0.561663 0.259120 +vt 0.557101 0.220839 +vt 0.544011 0.221139 +vt 0.531098 0.221476 +vt 0.496367 0.205905 +vt 0.496120 0.227065 +vt 0.496629 0.227065 +vt 0.356844 0.211073 +vt 0.357366 0.203179 +vt 0.357358 0.200192 +vt 0.591431 0.242971 +vt 0.591379 0.231676 +vt 0.587407 0.231804 +vt 0.587411 0.239987 +vt 0.591242 0.220366 +vt 0.586813 0.220452 +vt 0.580917 0.247398 +vt 0.361976 0.216354 +vt 0.361518 0.205150 +vt 0.361785 0.200279 +vt 0.279761 0.029371 +vt 0.279743 0.040681 +vt 0.285013 0.040755 +vt 0.285031 0.029445 +vt 0.279910 0.052028 +vt 0.284995 0.052066 +vt 0.839506 0.048981 +vt 0.839545 0.037785 +vt 0.832321 0.037405 +vt 0.832248 0.048715 +vt 0.839511 0.032911 +vt 0.832265 0.032531 +vt 0.077108 0.282834 +vt 0.077100 0.271526 +vt 0.070179 0.287257 +vt 0.077092 0.287702 +vt 0.992408 0.144095 +vt 0.992424 0.132800 +vt 0.986406 0.132752 +vt 0.986393 0.144063 +vt 0.992436 0.121490 +vt 0.986418 0.121441 +vt 0.989278 0.183501 +vt 0.983685 0.183273 +vt 0.983770 0.194584 +vt 0.989448 0.194795 +vt 0.983600 0.199459 +vt 0.989192 0.199686 +vt 0.062215 0.299117 +vt 0.062223 0.310425 +vt 0.062195 0.287777 +vt 0.290440 0.029914 +vt 0.290451 0.041006 +vt 0.290433 0.052317 +vt 0.997000 0.248539 +vt 0.994390 0.248539 +vt 0.545160 0.245396 +vt 0.549532 0.262598 +vt 0.895149 0.045141 +vt 0.896330 0.045229 +vt 0.428010 0.249815 +vt 0.426596 0.257739 +vt 0.429827 0.249453 +vt 0.003808 0.040443 +vt 0.002028 0.033116 +vt 0.000209 0.032759 +vt 0.002406 0.041385 +vt 0.007580 0.026359 +vt 0.014471 0.026166 +vt 0.014959 0.024459 +vt 0.006580 0.024459 +vt 0.415555 0.242888 +vt 0.422615 0.242705 +vt 0.423457 0.241184 +vt 0.415066 0.241184 +vt 0.012271 0.043616 +vt 0.005885 0.042183 +vt 0.005202 0.043727 +vt 0.012523 0.045451 +vt 0.424523 0.259483 +vt 0.417755 0.260620 +vt 0.417506 0.262455 +vt 0.410612 0.253371 +vt 0.410764 0.247457 +vt 0.409169 0.246684 +vt 0.408970 0.253940 +vt 0.019305 0.030683 +vt 0.019459 0.036607 +vt 0.021104 0.037172 +vt 0.020901 0.029903 +vt 0.017138 0.040820 +vt 0.018295 0.041966 +vt 0.003538 0.029035 +vt 0.002206 0.028097 +vt 0.412588 0.257791 +vt 0.411433 0.258940 +vt 0.426519 0.245770 +vt 0.427848 0.244829 +vt 0.971031 0.918261 +vt 0.971529 0.912836 +vt 0.967084 0.913021 +vt 0.966585 0.918251 +vt 0.971529 0.927507 +vt 0.971483 0.922987 +vt 0.966821 0.922983 +vt 0.966867 0.927503 +vt 0.923471 0.851189 +vt 0.923868 0.844782 +vt 0.919206 0.844847 +vt 0.918809 0.851255 +vt 0.864065 0.013468 +vt 0.864179 0.017987 +vt 0.868841 0.017921 +vt 0.868727 0.013402 +vt 0.142311 0.010711 +vt 0.142350 0.016383 +vt 0.147010 0.016485 +vt 0.146956 0.010819 +vt 0.572602 0.780300 +vt 0.572900 0.785182 +vt 0.577562 0.785159 +vt 0.577264 0.780276 +vt 0.731972 0.011117 +vt 0.732056 0.008422 +vt 0.727499 0.008231 +vt 0.727313 0.010964 +vt 0.732065 0.016746 +vt 0.727406 0.016592 +vt 0.923969 0.851320 +vt 0.924142 0.857284 +vt 0.929027 0.857534 +vt 0.928407 0.850857 +vt 0.863759 0.008740 +vt 0.868420 0.008674 +vt 0.923868 0.857468 +vt 0.919206 0.857533 +vt 0.924366 0.844913 +vt 0.929027 0.844848 +vt 0.732065 0.002347 +vt 0.727406 0.002218 +vt 0.572900 0.776264 +vt 0.577562 0.776241 +vt 0.994067 0.199337 +vt 0.994152 0.210647 +vt 0.994237 0.194462 +vt 0.994152 0.183152 +vt 0.994237 0.221958 +vt 0.572501 0.785108 +vt 0.567618 0.785182 +vt 0.864179 0.003485 +vt 0.868841 0.003422 +vt 0.296904 0.051816 +vt 0.297101 0.056689 +vt 0.296917 0.040505 +vt 0.297101 0.029413 +vt 0.297089 0.068000 +vt 0.532430 0.241750 +vt 0.535328 0.244676 +vt 0.538570 0.265222 +vt 0.533362 0.247094 +vn 0.9272 0.3729 -0.0352 +vn 0.9246 0.3788 -0.0404 +vn 0.9987 -0.0240 -0.0443 +vn 0.9272 0.3729 -0.0353 +vn 0.8608 -0.5067 -0.0469 +vn 0.9837 -0.1735 -0.0463 +vn -0.0407 0.0112 -0.9991 +vn -0.0401 0.0115 -0.9991 +vn -0.0408 0.0115 -0.9991 +vn -0.0406 0.0111 -0.9991 +vn -0.0405 0.0115 -0.9991 +vn -0.0409 0.0113 -0.9991 +vn -0.0401 0.0116 -0.9991 +vn -0.0400 0.0121 -0.9991 +vn 0.3770 -0.9256 -0.0331 +vn 0.4594 -0.8875 -0.0360 +vn 0.7792 -0.6252 -0.0454 +vn 0.4003 -0.9158 -0.0339 +vn 0.0588 -0.0372 0.9976 +vn 0.0583 -0.0372 0.9976 +vn 0.0498 -0.0255 0.9984 +vn 0.0497 -0.0254 0.9984 +vn 0.0503 -0.0255 0.9984 +vn 0.0582 -0.0382 0.9976 +vn 0.0500 -0.0257 0.9984 +vn -0.0290 -0.0015 -0.9996 +vn -0.0374 0.0076 -0.9993 +vn -0.0378 0.0099 -0.9992 +vn -0.0295 -0.0015 -0.9996 +vn -0.0378 0.0100 -0.9992 +vn -0.0302 -0.0010 -0.9995 +vn -0.0380 0.0102 -0.9992 +vn -0.0384 0.0105 -0.9992 +vn 0.0497 -0.0255 0.9984 +vn -0.0388 0.0113 -0.9992 +vn -0.0388 0.0125 -0.9992 +vn -0.0396 0.0124 -0.9991 +vn -0.0389 0.0110 -0.9992 +vn -0.0679 -0.9976 -0.0148 +vn 0.4015 -0.9152 -0.0339 +vn -0.0397 0.0122 -0.9991 +vn -0.0395 0.0125 -0.9991 +vn -0.0388 0.0126 -0.9992 +vn -0.0380 0.0131 -0.9992 +vn -0.0380 0.0130 -0.9992 +vn -0.0389 0.0125 -0.9992 +vn -0.0383 0.0125 -0.9992 +vn 0.0958 -0.0864 0.9916 +vn -0.2178 0.3283 0.9191 +vn -0.2107 0.3298 0.9202 +vn 0.0915 -0.0812 0.9925 +vn -0.3553 0.5744 -0.7375 +vn -0.5481 0.8019 -0.2375 +vn -0.5491 0.8030 -0.2315 +vn -0.3536 0.5723 -0.7399 +vn -0.5738 0.7696 -0.2803 +vn -0.5687 0.7717 -0.2847 +vn -0.5117 0.7249 0.4613 +vn -0.5153 0.7195 0.4655 +vn 0.0334 0.0339 0.9989 +vn -0.3168 0.4718 0.8228 +vn -0.3119 0.4653 0.8284 +vn 0.0329 0.0344 0.9989 +vn -0.0103 -0.0285 -0.9995 +vn -0.3344 0.4217 -0.8428 +vn -0.3270 0.4144 -0.8493 +vn -0.0110 -0.0275 -0.9996 +vn 0.2327 -0.3494 -0.9076 +vn 0.3169 -0.4924 -0.8106 +vn 0.2931 -0.4570 -0.8398 +vn 0.3037 -0.4423 -0.8439 +vn -0.5748 0.7693 -0.2789 +vn -0.5696 0.7731 -0.2792 +vn -0.3270 0.4145 -0.8493 +vn 0.3388 -0.4386 0.8324 +vn 0.3959 -0.5355 0.7460 +vn 0.3886 -0.5489 0.7401 +vn 0.3958 -0.5353 0.7462 +vn 0.2314 -0.3581 -0.9046 +vn 0.2889 -0.4374 -0.8516 +vn -0.0146 -0.0221 -0.9996 +vn -0.0141 -0.0219 -0.9997 +vn 0.0705 -0.0555 0.9960 +vn 0.0667 -0.0548 0.9963 +vn 0.0574 -0.0367 0.9977 +vn 0.3381 -0.4287 0.8378 +vn 0.4169 -0.5786 0.7010 +vn -0.6167 -0.7868 0.0239 +vn -0.6024 -0.7980 0.0175 +vn -0.5040 -0.8637 0.0067 +vn -0.5069 -0.8620 0.0069 +vn -0.9650 0.2518 0.0727 +vn -0.9661 0.2478 0.0722 +vn -0.9419 0.3255 0.0827 +vn -0.5041 -0.8636 0.0067 +vn -0.9098 -0.4138 0.0326 +vn -0.0303 -0.0042 -0.9995 +vn -0.0296 -0.0024 -0.9996 +vn 0.1040 0.9945 0.0132 +vn 0.2187 0.9758 0.0078 +vn 0.8604 -0.5074 -0.0469 +vn 0.6426 0.7662 0.0033 +vn 0.6437 0.7653 0.0035 +vn 0.6618 0.7496 0.0070 +vn 0.0697 -0.0606 0.9957 +vn 0.0656 -0.0625 0.9959 +vn 0.0629 -0.0609 0.9962 +vn 0.0652 -0.0585 0.9962 +vn 0.0495 -0.0253 0.9985 +vn 0.0667 -0.0554 0.9962 +vn 0.0618 -0.0438 0.9971 +vn 0.3915 0.9202 -0.0008 +vn 0.5380 0.8429 -0.0019 +vn 0.5393 0.8421 -0.0019 +vn -0.0373 0.0075 -0.9993 +vn -0.0368 0.0054 -0.9993 +vn -0.0378 0.0103 -0.9992 +vn -0.0383 0.0109 -0.9992 +vn -0.9923 -0.1169 0.0415 +vn -0.9961 0.0700 0.0530 +vn -0.9962 0.0686 0.0529 +vn -0.0381 0.0103 -0.9992 +vn -0.0380 0.0103 -0.9992 +vn -0.0386 0.0109 -0.9992 +vn -0.0393 0.0108 -0.9992 +vn -0.0379 0.0104 -0.9992 +vn 0.0511 -0.0302 0.9982 +vn 0.0504 -0.0281 0.9983 +vn 0.0648 -0.0412 0.9970 +vn 0.0681 -0.0412 0.9968 +vn 0.0498 -0.0254 0.9984 +vn 0.0620 -0.0417 0.9972 +vn 0.0728 -0.0559 0.9958 +vn 0.0717 -0.0539 0.9960 +vn -0.0401 0.0114 -0.9991 +vn -0.0398 0.0120 -0.9991 +vn -0.0406 0.0114 -0.9991 +vn 0.4595 -0.8875 -0.0360 +vn 0.5841 -0.8107 -0.0401 +vn 0.4015 -0.9152 -0.0340 +vn -0.0115 -0.0221 -0.9997 +vn -0.0142 -0.0213 -0.9997 +vn -0.0295 -0.0016 -0.9996 +vn -0.0302 -0.0011 -0.9995 +vn -0.0149 -0.0204 -0.9997 +vn -0.0290 -0.0016 -0.9996 +vn 0.3388 -0.4387 0.8324 +vn 0.0738 -0.0583 0.9956 +vn 0.0734 -0.0593 0.9955 +vn 0.3519 -0.4300 0.8314 +vn 0.0729 -0.0561 0.9958 +vn 0.0582 -0.0383 0.9976 +vn 0.0575 -0.0398 0.9975 +vn 0.3169 -0.4923 -0.8107 +vn 0.2328 -0.3494 -0.9076 +vn 0.2417 -0.3549 -0.9031 +vn -0.5076 0.7198 0.4736 +vn -0.5149 0.7201 0.4651 +vn -0.2244 0.3381 0.9140 +vn -0.2351 0.3474 0.9078 +vn -0.5197 0.7160 0.4662 +vn -0.2234 0.3339 0.9158 +vn 0.4147 -0.5270 0.7419 +vn 0.3992 -0.5372 0.7430 +vn 0.4121 -0.5136 0.7525 +vn -0.3357 0.4152 -0.8455 +vn -0.3355 0.4276 -0.8394 +vn -0.5794 0.7668 -0.2763 +vn -0.3429 0.4214 -0.8396 +vn 0.2920 -0.4399 -0.8492 +vn 0.2882 -0.4359 -0.8526 +vn 0.3015 -0.4308 -0.8506 +vn -0.0090 -0.0297 -0.9995 +vn -0.3357 0.4151 -0.8455 +vn -0.0051 -0.0335 -0.9994 +vn -0.0121 -0.0255 -0.9996 +vn -0.5149 0.7202 0.4651 +vn 0.0635 -0.0897 0.9939 +vn 0.0803 -0.0885 0.9928 +vn 0.0926 -0.0821 0.9923 +vn 0.0493 -0.0254 0.9985 +vn -0.0397 0.0121 -0.9991 +vn -0.0402 0.0115 -0.9991 +vn -0.0406 0.0110 -0.9991 +vn 0.0777 -0.0530 0.9956 +vn 0.0805 -0.0518 0.9954 +vn -0.0382 0.0126 -0.9992 +vn 0.8259 0.5635 -0.0185 +vn 0.8081 0.5884 -0.0269 +vn 0.8284 0.5598 -0.0171 +vn -0.8048 -0.5927 0.0330 +vn -0.8223 -0.5685 0.0251 +vn -0.8260 -0.5632 0.0223 +vn -0.8032 -0.5945 -0.0390 +vn -0.8159 -0.5773 0.0328 +vn -0.8171 -0.5759 0.0254 +vn -0.7978 -0.6016 -0.0408 +vn 0.7997 0.5987 -0.0463 +vn 0.7861 0.6180 -0.0044 +vn 0.7846 0.6199 -0.0067 +vn 0.7989 0.6002 -0.0398 +vn -0.7915 -0.6107 0.0230 +vn -0.8132 -0.5806 0.0404 +vn -0.7922 -0.6099 0.0238 +vn 0.8114 0.5835 -0.0348 +vn 0.7901 0.6127 -0.0176 +vn 0.7913 0.6112 -0.0189 +vn 0.8345 0.5507 -0.0171 +vn 0.8096 0.5844 -0.0545 +vn 0.8094 0.5846 -0.0560 +vn 0.8381 0.5453 -0.0169 +vn -0.8096 -0.5844 0.0545 +vn -0.8242 -0.5660 0.0193 +vn -0.8254 -0.5642 0.0193 +vn -0.8094 -0.5846 0.0560 +vn -0.8013 -0.5982 0.0050 +vn -0.8011 -0.5985 0.0050 +vn -0.8112 -0.5844 -0.0214 +vn -0.8129 -0.5820 -0.0200 +vn 0.8150 0.5794 -0.0037 +vn 0.8131 0.5822 -0.0032 +vn 0.8133 0.5817 -0.0113 +vn 0.8143 0.5804 -0.0112 +vn -0.0290 0.1119 -0.9933 +vn -0.3554 0.5744 -0.7374 +vn -0.0291 0.1123 -0.9932 +vn 0.5020 -0.7194 -0.4801 +vn 0.2543 -0.3519 -0.9008 +vn 0.2482 -0.3416 -0.9065 +vn 0.5103 -0.7232 -0.4654 +vn 0.5722 -0.7775 0.2610 +vn 0.5054 -0.7170 -0.4802 +vn 0.5712 -0.7758 0.2678 +vn 0.2172 -0.3384 -0.9156 +vn 0.5117 -0.7212 -0.4670 +vn 0.5050 -0.7129 -0.4865 +vn 0.2230 -0.3462 -0.9113 +vn -0.5264 0.7636 0.3739 +vn -0.2948 0.4477 0.8442 +vn -0.2985 0.4571 0.8378 +vn -0.5251 0.7621 0.3788 +vn 0.0045 0.0365 0.9993 +vn 0.3392 -0.4318 0.8358 +vn 0.3501 -0.4474 0.8229 +vn 0.0026 0.0391 0.9992 +vn -0.5029 0.7653 0.4018 +vn -0.5294 0.8321 -0.1654 +vn -0.5292 0.8317 -0.1682 +vn -0.5030 0.7655 0.4013 +vn -0.3120 0.4653 0.8283 +vn 0.5752 -0.7632 0.2943 +vn 0.3806 -0.4414 0.8126 +vn 0.3678 -0.4207 0.8293 +vn 0.5820 -0.7758 0.2437 +vn -0.0888 0.0779 -0.9930 +vn -0.0928 0.0835 -0.9922 +vn 0.3502 -0.4474 0.8229 +vn -0.3841 0.5481 -0.7430 +vn -0.3880 0.5557 -0.7353 +vn -0.3006 0.4556 0.8379 +vn 0.3677 -0.4207 0.8293 +vn 0.4146 -0.5270 0.7419 +vn 0.3886 -0.5488 0.7401 +vn 0.3991 -0.5372 0.7431 +vn -0.0395 0.0123 -0.9991 +vn -0.0398 0.0121 -0.9991 +vn -0.0390 0.0125 -0.9992 +vn -0.0389 0.0123 -0.9992 +vn 0.0746 -0.0521 0.9959 +vn 0.0768 -0.0519 0.9957 +vn 0.0796 -0.0516 0.9955 +vn 0.0794 -0.0516 0.9955 +usemtl Scene_-_Root +s off +f 21030/20988/14998 21031/20989/14999 21032/20990/15000 +f 21030/20988/15001 21032/20990/15000 21033/20991/15000 +f 21054/20992/15002 21055/20993/15003 21056/20994/15003 +f 21096/20995/15004 21097/20996/15005 21098/20997/15006 +f 21096/20995/15007 21098/20997/15008 21099/20998/15009 +f 21097/20996/15010 21100/20999/15011 21101/21000/15011 +f 21102/21001/15012 21104/21002/15013 21105/21003/15012 +f 21108/21004/15014 21110/21005/15015 21111/21006/15014 +f 21126/21007/15016 21029/21008/15017 21066/21009/15018 +f 21126/21007/15016 21066/21009/15019 21092/21010/15020 +f 21124/21011/15021 21126/21007/15016 21092/21010/15022 +f 21117/21012/15023 21074/21013/15024 21086/21014/15025 +f 21114/21015/15026 21117/21012/15023 21086/21014/15027 +f 21115/21016/15028 21083/21017/15029 21082/21018/15030 +f 21029/21008/15017 21067/21019/15031 21066/21009/15031 +f 21087/21020/15032 21166/21021/15033 21100/20999/15034 +f 21084/21022/15035 21087/21020/15032 21100/20999/15034 +f 21268/21023/15036 21109/21024/15037 21269/21025/15036 +f 21100/20999/15038 21271/21026/15039 21101/21000/15038 +f 21270/21027/15040 21276/21028/15041 21277/21029/15041 +f 21276/21028/15042 21166/21021/15043 21169/21030/15044 +s 1 +f 20988/21031/15045 20989/21032/15046 20990/21033/15047 +f 20988/21031/15045 20990/21033/15047 20991/21034/15048 +f 20992/21035/15049 20993/21036/15050 20994/21037/15051 +f 20992/21035/15049 20994/21037/15051 20995/21038/15052 +f 20996/21039/15053 20997/21040/15054 20998/21041/15055 +f 20996/21039/15053 20998/21041/15055 20999/21042/15056 +f 21000/21043/15057 21001/21044/15058 21002/21045/15059 +f 21000/21043/15057 21002/21045/15059 21003/21046/15060 +f 21004/21047/15061 21005/21048/15062 21006/21049/15063 +f 21004/21047/15061 21006/21049/15063 21007/21050/15064 +f 21008/21051/15065 21009/21052/15066 21010/21053/15067 +f 21008/21051/15065 21010/21053/15067 21011/21054/15068 +f 21012/21055/15069 21013/21056/15070 21014/21057/15071 +f 21012/21055/15069 21014/21057/15071 21015/21058/15062 +f 21016/21059/15072 21017/21060/15073 21018/21061/15074 +f 21016/21059/15072 21018/21061/15074 21019/21062/15075 +f 21020/21063/15056 21021/21064/15055 20990/21033/15047 +f 21020/21063/15056 20990/21033/15047 20989/21032/15046 +f 21022/21065/15076 21023/21066/15077 21024/21067/15078 +f 21022/21065/15076 21024/21067/15078 21025/21068/15079 +f 21026/21069/15080 21027/21070/15081 21028/21071/15082 +f 21026/21069/15080 21028/21071/15082 21029/21008/15017 +f 21034/21072/15083 21035/21073/15084 21027/21070/15081 +f 21034/21072/15083 21027/21070/15081 21026/21069/15080 +f 21036/21074/15085 21037/21075/15086 21038/21076/15087 +f 21036/21074/15085 21038/21076/15087 21039/21077/15088 +f 21040/21078/15089 21041/21079/15090 21042/21080/15091 +f 21040/21078/15089 21042/21080/15091 21043/21081/15091 +f 21044/21082/15088 21045/21083/15092 21046/21084/15093 +f 21044/21082/15088 21046/21084/15093 21047/21085/15093 +f 21025/21068/15079 21024/21067/15078 21048/21086/15094 +f 21025/21068/15079 21048/21086/15094 21049/21087/15095 +f 21050/21088/15096 21051/21089/15096 21052/21090/15097 +f 21050/21088/15096 21052/21090/15097 21053/21091/15097 +f 21054/20992/15002 21056/20994/15003 21057/21092/15098 +f 21058/21093/15099 21059/21094/15100 21060/21095/15101 +f 21058/21093/15099 21060/21095/15101 21061/21096/15101 +f 21062/21097/15102 21063/21098/15103 21064/21099/15104 +f 21062/21097/15102 21064/21099/15104 21065/21100/15105 +f 21066/21009/15019 21067/21019/15106 21068/21101/15107 +f 21066/21009/15019 21068/21101/15107 21069/21102/15108 +f 21070/21103/15109 21071/21104/15109 21072/21105/15110 +f 21070/21103/15109 21072/21105/15110 21073/21106/15111 +f 21074/21013/15112 21075/21107/15113 21076/21108/15114 +f 21074/21013/15112 21076/21108/15114 21077/21109/15115 +f 21078/21110/15116 21079/21111/15116 21080/21112/15117 +f 21078/21110/15116 21080/21112/15117 21081/21113/15118 +f 21082/21018/15119 21083/21017/15120 21084/21022/15121 +f 21082/21018/15119 21084/21022/15121 21085/21114/15122 +f 21083/21017/15120 21086/21014/15123 21087/21020/15032 +f 21083/21017/15120 21087/21020/15032 21084/21022/15121 +f 21086/21014/15123 21074/21013/15112 21077/21109/15115 +f 21086/21014/15123 21077/21109/15115 21087/21020/15032 +f 21088/21115/15124 21089/21116/15125 21090/21117/15126 +f 21088/21115/15124 21090/21117/15126 21091/21118/15127 +f 21089/21116/15125 21092/21010/15128 21093/21119/15129 +f 21089/21116/15125 21093/21119/15129 21090/21117/15126 +f 21092/21010/15128 21066/21009/15019 21069/21102/15108 +f 21092/21010/15128 21069/21102/15108 21093/21119/15129 +f 21094/21120/15130 21062/21097/15102 21065/21100/15105 +f 21094/21120/15130 21065/21100/15105 21095/21121/15131 +f 21097/20996/15132 21101/21000/15133 21098/20997/15134 +f 21102/21001/15012 21103/21122/15013 21104/21002/15135 +f 21103/21122/15013 21106/21123/15136 21107/21124/15136 +f 21103/21122/15013 21107/21124/15136 21104/21002/15135 +f 21108/21004/15014 21109/21024/15137 21110/21005/15015 +f 21112/21125/15138 21113/21126/15139 21114/21015/15140 +f 21112/21125/15138 21114/21015/15140 21115/21016/15141 +f 21113/21126/15139 21116/21127/15142 21117/21012/15143 +f 21113/21126/15139 21117/21012/15143 21114/21015/15140 +f 21116/21127/15142 21025/21068/15079 21049/21087/15095 +f 21116/21127/15142 21049/21087/15095 21117/21012/15143 +f 21118/21128/15073 21119/21129/15144 21120/21130/15145 +f 21118/21128/15073 21120/21130/15145 21121/21131/15146 +f 21119/21129/15144 21122/21132/15147 21123/21133/15148 +f 21119/21129/15144 21123/21133/15148 21120/21130/15145 +f 21122/21132/15147 21034/21072/15083 21026/21069/15080 +f 21122/21132/15147 21026/21069/15080 21123/21133/15148 +f 21121/21131/15146 21120/21130/15145 21124/21011/15149 +f 21121/21131/15146 21124/21011/15149 21125/21134/15150 +f 21120/21130/15145 21123/21133/15148 21126/21007/15016 +f 21120/21130/15145 21126/21007/15016 21124/21011/15149 +f 21123/21133/15148 21026/21069/15080 21029/21008/15017 +f 21123/21133/15148 21029/21008/15017 21126/21007/15016 +f 21127/21135/15151 21128/21136/15152 21113/21126/15139 +f 21127/21135/15151 21113/21126/15139 21112/21125/15138 +f 21128/21136/15152 21129/21137/15153 21116/21127/15142 +f 21128/21136/15152 21116/21127/15142 21113/21126/15139 +f 21129/21137/15153 21022/21065/15076 21025/21068/15079 +f 21129/21137/15153 21025/21068/15079 21116/21127/15142 +f 21130/21138/15154 21131/21139/15155 21132/21140/15156 +f 21130/21138/15154 21132/21140/15156 21133/21141/15157 +f 21131/21139/15155 21134/21142/15158 21135/21143/15159 +f 21131/21139/15155 21135/21143/15159 21132/21140/15156 +f 21134/21142/15158 21020/21063/15056 20989/21032/15046 +f 21134/21142/15158 20989/21032/15046 21135/21143/15159 +f 21136/21144/15084 21137/21145/15083 21138/21146/15160 +f 21136/21144/15084 21138/21146/15160 21139/21147/15161 +f 21137/21145/15083 21140/21148/15147 21141/21149/15162 +f 21137/21145/15083 21141/21149/15162 21138/21146/15160 +f 21140/21148/15147 21016/21059/15072 21019/21062/15075 +f 21140/21148/15147 21019/21062/15075 21141/21149/15162 +f 20997/21040/15054 20996/21039/15053 21142/21150/15163 +f 20997/21040/15054 21142/21150/15163 21143/21151/15164 +f 20996/21039/15053 21144/21152/15165 21145/21153/15166 +f 20996/21039/15053 21145/21153/15166 21142/21150/15163 +f 21144/21152/15165 21012/21055/15069 21015/21058/15062 +f 21144/21152/15165 21015/21058/15062 21145/21153/15166 +f 21146/21154/15077 21147/21155/15076 21148/21156/15167 +f 21146/21154/15077 21148/21156/15167 21149/21157/15168 +f 21147/21155/15076 21150/21158/15153 21151/21159/15169 +f 21147/21155/15076 21151/21159/15169 21148/21156/15167 +f 21150/21158/15153 21008/21051/15065 21011/21054/15068 +f 21150/21158/15153 21011/21054/15068 21151/21159/15169 +f 21152/21160/15170 21153/21161/15164 21154/21162/15171 +f 21152/21160/15170 21154/21162/15171 21155/21163/15172 +f 21155/21163/15172 21154/21162/15171 21156/21164/15166 +f 21155/21163/15172 21156/21164/15166 21157/21165/15173 +f 21157/21165/15173 21156/21164/15166 21005/21048/15062 +f 21157/21165/15173 21005/21048/15062 21004/21047/15061 +f 21013/21056/15070 21012/21055/15069 21158/21166/15174 +f 21013/21056/15070 21158/21166/15174 21159/21167/15154 +f 21012/21055/15069 21144/21152/15165 21160/21168/15158 +f 21012/21055/15069 21160/21168/15158 21158/21166/15174 +f 21144/21152/15165 20996/21039/15053 20999/21042/15056 +f 21144/21152/15165 20999/21042/15056 21160/21168/15158 +f 21161/21169/15175 21133/21141/15157 21132/21140/15156 +f 21161/21169/15175 21132/21140/15156 21162/21170/15176 +f 21162/21170/15176 21132/21140/15156 21135/21143/15159 +f 21162/21170/15176 21135/21143/15159 21163/21171/15177 +f 21163/21171/15177 21135/21143/15159 20989/21032/15046 +f 21163/21171/15177 20989/21032/15046 20988/21031/15045 +f 21124/21011/15149 21092/21010/15128 21089/21116/15125 +f 21125/21134/15150 21124/21011/15149 21089/21116/15125 +f 21125/21134/15150 21089/21116/15125 21088/21115/15124 +f 21117/21012/15143 21049/21087/15095 21074/21013/15112 +f 21114/21015/15140 21086/21014/15123 21083/21017/15120 +f 21115/21016/15141 21114/21015/15140 21083/21017/15120 +f 21047/21085/15093 21046/21084/15093 21079/21111/15116 +f 21047/21085/15093 21079/21111/15116 21078/21110/15116 +f 21049/21087/15095 21048/21086/15094 21075/21107/15113 +f 21049/21087/15095 21075/21107/15113 21074/21013/15112 +f 21164/21172/15097 21165/21173/15097 21071/21104/15109 +f 21164/21172/15097 21071/21104/15109 21070/21103/15109 +f 21029/21008/15017 21028/21071/15082 21067/21019/15178 +f 21087/21020/15032 21077/21109/15115 21166/21021/15033 +f 21084/21022/15121 21100/20999/15179 21097/20996/15180 +f 21085/21114/15122 21084/21022/15121 21097/20996/15180 +f 21085/21114/15122 21097/20996/15180 21096/20995/15181 +f 21093/21119/15129 21069/21102/15108 21062/21097/15102 +f 21093/21119/15129 21062/21097/15102 21094/21120/15130 +f 21090/21117/15126 21093/21119/15129 21094/21120/15130 +f 21090/21117/15126 21094/21120/15130 21167/21174/15182 +f 21091/21118/15127 21090/21117/15126 21167/21174/15182 +f 21091/21118/15127 21167/21174/15182 21168/21175/15183 +f 21069/21102/15108 21068/21101/15107 21063/21098/15103 +f 21069/21102/15108 21063/21098/15103 21062/21097/15102 +f 21073/21106/15111 21072/21105/15110 21059/21094/15100 +f 21073/21106/15111 21059/21094/15100 21058/21093/15099 +f 21077/21109/15115 21076/21108/15114 21169/21030/15184 +f 21077/21109/15115 21169/21030/15184 21166/21021/15033 +f 21081/21113/15118 21080/21112/15117 21170/21176/15090 +f 21081/21113/15118 21170/21176/15090 21171/21177/15089 +f 21172/21178/15185 21173/21179/15186 21030/20988/14998 +f 21172/21178/15185 21030/20988/14998 21174/21180/15187 +f 21175/21181/15188 21176/21182/15189 21177/21183/15190 +f 21175/21181/15188 21177/21183/15190 21178/21184/15086 +f 21179/21185/15191 21180/21186/15192 21181/21187/15193 +f 21179/21185/15191 21181/21187/15193 21182/21188/15194 +f 21183/21189/15195 21184/21190/15196 21185/21191/15197 +f 21183/21189/15195 21185/21191/15197 21186/21192/15198 +f 21187/21193/15199 21188/21194/15200 21189/21195/15085 +f 21187/21193/15199 21189/21195/15085 21190/21196/15201 +f 21191/21197/15202 21192/21198/15203 21193/21199/15204 +f 21191/21197/15202 21193/21199/15204 21031/20989/14999 +f 21194/21200/15205 21195/21201/15206 21196/21202/15207 +f 21194/21200/15205 21196/21202/15207 21197/21203/15208 +f 21198/21204/15209 21199/21205/15210 21200/21206/15211 +f 21198/21204/15209 21200/21206/15211 21201/21207/15212 +f 21188/21194/15200 21175/21181/15188 21178/21184/15086 +f 21188/21194/15200 21178/21184/15086 21189/21195/15085 +f 21173/21179/15186 21191/21197/15202 21031/20989/14999 +f 21173/21179/15186 21031/20989/14999 21030/20988/14998 +f 21202/21208/15213 21187/21193/15199 21190/21196/15201 +f 21202/21208/15213 21190/21196/15201 21203/21209/15214 +f 21180/21186/15192 21198/21204/15209 21201/21207/15212 +f 21180/21186/15192 21201/21207/15212 21181/21187/15193 +f 21204/21210/15215 21179/21185/15191 21182/21188/15194 +f 21204/21210/15215 21182/21188/15194 21205/21211/15216 +f 21206/21212/15217 21194/21200/15205 21197/21203/15208 +f 21206/21212/15217 21197/21203/15208 21207/21213/15218 +f 21195/21201/15206 21183/21189/15195 21186/21192/15198 +f 21195/21201/15206 21186/21192/15198 21196/21202/15207 +f 21208/21214/15219 21172/21178/15185 21174/21180/15187 +f 21208/21214/15219 21174/21180/15187 21209/21215/15220 +f 21210/21216/15221 21211/21217/15222 21212/21218/15052 +f 21210/21216/15221 21212/21218/15052 21213/21219/15223 +f 21214/21220/15224 21215/21221/15225 21216/21222/15226 +f 21214/21220/15224 21216/21222/15226 21217/21223/15227 +f 21218/21224/15228 21219/21225/15229 21220/21226/15227 +f 21218/21224/15228 21220/21226/15227 21221/21227/15230 +f 21222/21228/15231 21223/21229/15232 21224/21230/15233 +f 21222/21228/15231 21224/21230/15233 21225/21231/15234 +f 21226/21232/15235 21227/21233/15236 21228/21234/15237 +f 21226/21232/15235 21228/21234/15237 21229/21235/15238 +f 21230/21236/15239 21231/21237/15240 21232/21238/15241 +f 21230/21236/15239 21232/21238/15241 21233/21239/15242 +f 21234/21240/15243 21235/21241/15244 21236/21242/15245 +f 21234/21240/15243 21236/21242/15245 21237/21243/15246 +f 21238/21244/15058 21234/21240/15243 21237/21243/15246 +f 21238/21244/15058 21237/21243/15246 21239/21245/15247 +f 20993/21036/15050 21226/21232/15235 21229/21235/15238 +f 20993/21036/15050 21229/21235/15238 20994/21037/15051 +f 21240/21246/15248 21241/21247/15249 21242/21248/15250 +f 21240/21246/15248 21242/21248/15250 21243/21249/15251 +f 21244/21250/15252 21222/21228/15231 21225/21231/15234 +f 21244/21250/15252 21225/21231/15234 21245/21251/15253 +f 21246/21252/15240 21218/21224/15228 21221/21227/15230 +f 21246/21252/15240 21221/21227/15230 21247/21253/15254 +f 21248/21254/15232 21240/21246/15248 21243/21249/15251 +f 21248/21254/15232 21243/21249/15251 21249/21255/15233 +f 21235/21241/15244 21250/21256/15255 21251/21257/15256 +f 21235/21241/15244 21251/21257/15256 21236/21242/15245 +f 21252/21258/15236 21230/21236/15239 21233/21239/15242 +f 21252/21258/15236 21233/21239/15242 21253/21259/15257 +f 21184/21190/15196 21208/21214/15219 21209/21215/15220 +f 21184/21190/15196 21209/21215/15220 21185/21191/15197 +f 21176/21182/15189 21204/21210/15215 21205/21211/15216 +f 21176/21182/15189 21205/21211/15216 21177/21183/15190 +f 21254/21260/15169 21157/21165/15173 21004/21047/15061 +f 21254/21260/15169 21004/21047/15061 21255/21261/15167 +f 21256/21262/15068 21155/21163/15172 21157/21165/15173 +f 21256/21262/15068 21157/21165/15173 21254/21260/15169 +f 21257/21263/15067 21152/21160/15170 21155/21163/15172 +f 21257/21263/15067 21155/21163/15172 21256/21262/15068 +f 21255/21261/15167 21004/21047/15061 21007/21050/15064 +f 21255/21261/15167 21007/21050/15064 21258/21264/15168 +f 21259/21265/15249 21000/21043/15057 21003/21046/15060 +f 21259/21265/15249 21003/21046/15060 21260/21266/15258 +f 21261/21267/15255 21244/21250/15252 21245/21251/15253 +f 21261/21267/15255 21245/21251/15253 21262/21268/15256 +f 21215/21221/15225 21210/21216/15221 21213/21219/15223 +f 21215/21221/15225 21213/21219/15223 21216/21222/15226 +f 21192/21198/15203 21206/21212/15217 21207/21213/15218 +f 21192/21198/15203 21207/21213/15218 21193/21199/15204 +f 21199/21205/15210 21202/21208/15213 21203/21209/15214 +f 21199/21205/15210 21203/21209/15214 21200/21206/15211 +f 21263/21269/15162 21163/21171/15177 20988/21031/15045 +f 21263/21269/15162 20988/21031/15045 21264/21270/15259 +f 21265/21271/15075 21162/21170/15176 21163/21171/15177 +f 21265/21271/15075 21163/21171/15177 21263/21269/15162 +f 21266/21272/15260 21161/21169/15175 21162/21170/15176 +f 21266/21272/15260 21162/21170/15176 21265/21271/15075 +f 21264/21270/15259 20988/21031/15045 20991/21034/15048 +f 21264/21270/15259 20991/21034/15048 21267/21273/15261 +f 21268/21023/15036 21110/21005/15015 21109/21024/15137 +f 21107/21124/15136 21106/21123/15136 21054/20992/15002 +f 21107/21124/15136 21054/20992/15002 21057/21092/15098 +f 21271/21026/15262 21100/20999/15263 21270/21027/15264 +f 21270/21027/15264 21100/20999/15263 21166/21021/15265 +f 21272/21274/15266 21094/21120/15130 21095/21121/15131 +f 21094/21120/15130 21272/21274/15266 21273/21275/15267 +f 21094/21120/15130 21273/21275/15267 21167/21174/15182 +f 21275/21276/15268 21273/21275/15267 21274/21277/15269 +f 21273/21275/15267 21275/21276/15268 21167/21174/15182 +f 21167/21174/15182 21275/21276/15268 21168/21175/15183 +f 21276/21028/15041 21270/21027/15264 21166/21021/15265 +o Cylinder.034__0 +v -1.326067 2.155519 -0.100688 +v -1.279226 2.171575 -0.072850 +v -1.512826 2.815510 0.053561 +v -1.569291 2.794482 0.025432 +v -1.279226 2.171575 -0.072850 +v -1.260181 2.168765 -0.013107 +v -1.489309 2.814597 0.113456 +v -1.512826 2.815510 0.053561 +v -1.278274 2.148926 0.043657 +v -1.512152 2.793139 0.170126 +v -1.324767 2.123734 0.064129 +v -1.568125 2.762693 0.190248 +v -1.324767 2.123734 0.064129 +v -1.373995 2.107557 0.036290 +v -1.625551 2.739635 0.162010 +v -1.568125 2.762693 0.190248 +v -1.373995 2.107557 0.036290 +v -1.395330 2.110132 -0.023514 +v -1.650096 2.738590 0.101997 +v -1.625551 2.739635 0.162010 +v -1.374886 2.130033 -0.080252 +v -1.626395 2.762103 0.045467 +v -1.326067 2.155519 -0.100688 +v -1.569291 2.794482 0.025432 +v -1.331959 2.743466 0.092008 +v -1.381919 2.724809 -0.055256 +v -1.379667 2.726409 -0.058016 +v -1.328191 2.744956 0.092337 +v -1.477898 2.838660 0.019204 +v -1.439640 2.836120 0.116916 +v -1.414201 2.847145 0.118692 +v -1.460067 2.850497 0.001564 +v -1.621098 2.537616 -0.075188 +v -1.671896 2.469759 0.050345 +v -1.675131 2.468510 0.050099 +v -1.623674 2.537076 -0.077689 +v -1.625919 2.487631 0.191624 +v -1.521685 2.602762 0.274576 +v -1.521818 2.602133 0.278262 +v -1.628491 2.486290 0.193664 +v -1.335837 2.145768 0.179419 +v -1.227223 2.213560 0.135196 +v -1.218911 2.214882 0.143427 +v -1.335060 2.143106 0.190519 +v -1.301495 2.536747 -0.105038 +v -1.234736 2.534861 0.043418 +v -1.231395 2.536135 0.043418 +v -1.299538 2.537840 -0.107353 +v -1.324696 2.754024 0.094519 +v -1.365695 2.834211 0.114356 +v -1.422584 2.784039 0.253590 +v -1.359238 2.636658 0.230309 +v -1.285553 2.429184 0.184602 +v -1.283188 2.429519 0.187338 +v -1.453113 2.407694 0.243779 +v -1.529035 2.269316 0.147323 +v -1.531510 2.267654 0.150064 +v -1.452972 2.406924 0.247431 +v -1.440927 2.490408 -0.153669 +v -1.440852 2.491023 -0.157346 +v -1.305283 2.567952 -0.107198 +v -1.363132 2.703951 -0.069853 +v -1.308224 2.722754 0.086240 +v -1.233113 2.565777 0.049858 +v -1.279226 2.171575 -0.072850 +v -1.326067 2.155519 -0.100688 +v -1.321065 2.171074 -0.179628 +v -1.227497 2.202641 -0.125148 +v -1.465011 2.432359 0.259928 +v -1.512430 2.573377 0.281706 +v -1.623076 2.456849 0.193649 +v -1.550285 2.290503 0.158441 +v -1.174494 2.228985 -0.003355 +v -1.163778 2.232964 -0.002938 +v -1.476953 2.802353 0.209639 +v -1.567181 2.755398 0.242466 +v -1.566743 2.751626 0.269275 +v -1.458967 2.807040 0.229926 +v -1.209875 2.239608 -0.147323 +v -1.243852 2.356381 -0.135238 +v -1.188331 2.346136 0.013448 +v -1.163778 2.232964 -0.002938 +v -1.656875 2.720470 0.198165 +v -1.672753 2.710743 0.216728 +v -1.378407 2.735943 -0.061274 +v -1.423930 2.838457 -0.030976 +v -1.365695 2.834211 0.114356 +v -1.324696 2.754024 0.094519 +v -1.701108 2.716722 0.098519 +v -1.727048 2.705632 0.096733 +v -1.542598 2.359080 -0.111275 +v -1.582411 2.278848 0.011267 +v -1.585639 2.277574 0.011032 +v -1.545441 2.358439 -0.113691 +v -1.662084 2.755672 0.006146 +v -1.680186 2.752493 -0.014042 +v -1.335060 2.143106 0.190519 +v -1.373837 2.232265 0.212888 +v -1.477082 2.143988 0.129879 +v -1.452655 2.084316 0.117203 +v -1.569071 2.807326 -0.026669 +v -1.569008 2.813893 -0.053418 +v -1.374886 2.130033 -0.080252 +v -1.421549 2.120889 -0.139596 +v -1.251705 2.390566 -0.131151 +v -1.292100 2.533603 -0.113917 +v -1.221952 2.531958 0.042310 +v -1.193377 2.380636 0.018891 +v -1.507991 2.090690 -0.026540 +v -1.518682 2.117296 -0.020924 +v -1.459106 2.152636 -0.160714 +v -1.454004 2.138791 -0.163097 +v -1.395330 2.110132 -0.023514 +v -1.464266 2.081778 -0.028524 +v -1.388114 2.263882 0.220625 +v -1.449510 2.398722 0.253323 +v -1.532619 2.258065 0.153449 +v -1.493044 2.176163 0.135115 +v -1.322206 2.724896 0.087466 +v -1.354538 2.608627 0.217082 +v -1.352144 2.609091 0.219748 +v -1.318959 2.726213 0.087554 +v -1.373995 2.107557 0.036290 +v -1.419867 2.076897 0.088524 +v -1.218019 2.235562 -0.139778 +v -1.209875 2.239608 -0.147323 +v -1.516271 2.680810 -0.120750 +v -1.558281 2.793594 -0.096426 +v -1.324767 2.123734 0.064129 +v -1.325771 2.123981 0.147281 +v -1.618613 2.467703 0.187594 +v -1.663790 2.450273 0.046410 +v -1.667670 2.448755 0.046072 +v -1.621128 2.466254 0.190209 +v -1.257775 2.379653 -0.124295 +v -1.382370 2.346869 -0.175729 +v -1.382681 2.347295 -0.179611 +v -1.255126 2.381016 -0.126939 +v -1.278274 2.148926 0.043657 +v -1.234345 2.180858 0.109128 +v -1.363271 2.628528 0.220478 +v -1.360837 2.628969 0.223497 +v -1.260181 2.168765 -0.013107 +v -1.190731 2.196863 -0.008291 +v -1.328332 2.198520 -0.201522 +v -1.327564 2.200336 -0.212812 +v -1.233113 2.565777 0.049858 +v -1.308224 2.722754 0.086240 +v -1.344074 2.603219 0.224207 +v -1.286561 2.457734 0.198380 +v -1.512554 2.671882 -0.111039 +v -1.512924 2.672611 -0.114873 +v -1.572794 2.259866 0.007349 +v -1.576825 2.258298 0.006957 +v -1.291653 2.449369 0.188633 +v -1.241286 2.554837 0.047337 +v -1.237578 2.556282 0.047681 +v -1.289121 2.449811 0.191579 +v -1.671654 2.439415 0.044154 +v -1.596369 2.281132 0.011835 +v -1.174494 2.228985 -0.003355 +v -1.227223 2.213560 0.135196 +v -1.234345 2.180858 0.109128 +v -1.190731 2.196863 -0.008291 +v -1.335837 2.145768 0.179419 +v -1.445335 2.089090 0.110159 +v -1.419867 2.076897 0.088524 +v -1.325771 2.123981 0.147281 +v -1.445335 2.089090 0.110159 +v -1.497372 2.094841 -0.025774 +v -1.497372 2.094841 -0.025774 +v -1.446749 2.140239 -0.154662 +v -1.421549 2.120889 -0.139596 +v -1.464266 2.081778 -0.028524 +v -1.446749 2.140239 -0.154662 +v -1.566607 2.809596 -0.060332 +v -1.453776 2.847425 -0.003393 +v -1.438817 2.816730 -0.009499 +v -1.553152 2.778218 -0.066437 +v -1.687799 2.733052 -0.032186 +v -1.740561 2.680353 0.091942 +v -1.729083 2.647875 0.085837 +v -1.675620 2.700963 -0.038291 +v -1.567572 2.757770 0.225079 +v -1.646943 2.726648 0.186005 +v -1.634686 2.694603 0.179899 +v -1.554440 2.726210 0.218973 +v -1.730415 2.697331 0.095338 +v -1.681725 2.746081 -0.019656 +v -1.669528 2.714002 -0.025762 +v -1.718885 2.664883 0.089232 +v -1.488813 2.799253 0.196524 +v -1.567572 2.757770 0.225079 +v -1.554440 2.726210 0.218973 +v -1.474195 2.768410 0.190418 +v -1.740561 2.680353 0.091942 +v -1.680266 2.685770 0.227001 +v -1.668028 2.653715 0.220895 +v -1.729083 2.647875 0.085837 +v -1.489702 2.830942 0.030641 +v -1.456319 2.828977 0.115817 +v -1.441048 2.798406 0.109711 +v -1.474929 2.800161 0.024535 +v -1.674175 2.702788 0.219825 +v -1.730415 2.697331 0.095338 +v -1.718885 2.664883 0.089232 +v -1.661917 2.670743 0.213719 +v -1.462592 2.180404 -0.146818 +v -1.382370 2.346869 -0.175729 +v -1.375544 2.327142 -0.178950 +v -1.454848 2.160742 -0.150651 +v -1.542598 2.359080 -0.111275 +v -1.449149 2.510174 -0.149758 +v -1.440927 2.490408 -0.153669 +v -1.533531 2.339764 -0.115189 +v -1.621098 2.537616 -0.075188 +v -1.512554 2.671882 -0.111039 +v -1.504827 2.652220 -0.115538 +v -1.613111 2.518066 -0.079110 +v -1.519191 2.147595 -0.015375 +v -1.510884 2.128284 -0.019207 +v -1.582411 2.278848 0.011267 +v -1.572794 2.259866 0.007349 +v -1.671896 2.469759 0.050345 +v -1.621098 2.537616 -0.075188 +v -1.613111 2.518066 -0.079110 +v -1.663790 2.450273 0.046410 +v -1.481884 2.174423 0.127414 +v -1.519191 2.147595 -0.015375 +v -1.510884 2.128284 -0.019207 +v -1.473240 2.155351 0.123499 +v -1.538518 2.288438 0.151306 +v -1.582411 2.278848 0.011267 +v -1.572794 2.259866 0.007349 +v -1.529035 2.269316 0.147323 +v -1.625919 2.487631 0.191624 +v -1.671896 2.469759 0.050345 +v -1.663790 2.450273 0.046410 +v -1.618613 2.467703 0.187594 +v -1.385172 2.260201 0.207997 +v -1.377375 2.241302 0.203371 +v -1.461415 2.427593 0.247713 +v -1.453113 2.407694 0.243779 +v -1.521685 2.602762 0.274576 +v -1.515003 2.582226 0.271529 +v -1.256651 2.317486 0.159724 +v -1.385172 2.260201 0.207997 +v -1.377375 2.241302 0.203371 +v -1.251751 2.297872 0.155230 +v -1.291653 2.449369 0.188633 +v -1.285553 2.429184 0.184602 +v -1.363271 2.628528 0.220478 +v -1.354538 2.608627 0.217082 +v -1.203152 2.369618 0.017069 +v -1.200159 2.349199 0.014001 +v -1.241286 2.554837 0.047337 +v -1.291653 2.449369 0.188633 +v -1.285553 2.429184 0.184602 +v -1.234736 2.534861 0.043418 +v -1.331959 2.743466 0.092008 +v -1.363271 2.628528 0.220478 +v -1.354538 2.608627 0.217082 +v -1.322206 2.724896 0.087466 +v -1.257775 2.379653 -0.124295 +v -1.253086 2.359437 -0.126590 +v -1.309082 2.556631 -0.101153 +v -1.241286 2.554837 0.047337 +v -1.234736 2.534861 0.043418 +v -1.301495 2.536747 -0.105038 +v -1.381919 2.724809 -0.055256 +v -1.331959 2.743466 0.092008 +v -1.322206 2.724896 0.087466 +v -1.373182 2.705838 -0.060628 +v -1.382370 2.346869 -0.175729 +v -1.257775 2.379653 -0.124295 +v -1.253086 2.359437 -0.126590 +v -1.375544 2.327142 -0.178950 +v -1.449149 2.510174 -0.149758 +v -1.440927 2.490408 -0.153669 +v -1.242145 2.292208 0.162166 +v -1.218911 2.214882 0.143427 +v -1.538518 2.288438 0.151306 +v -1.461415 2.427593 0.247713 +v -1.461804 2.426839 0.251311 +v -1.541323 2.286972 0.153154 +v -1.454004 2.138791 -0.163097 +v -1.459106 2.152636 -0.160714 +v -1.372084 2.322399 -0.191332 +v -1.327564 2.200336 -0.212812 +v -1.309082 2.556631 -0.101153 +v -1.449149 2.510174 -0.149758 +v -1.449827 2.510825 -0.153629 +v -1.306860 2.558203 -0.103881 +v -1.518682 2.117296 -0.020924 +v -1.507991 2.090690 -0.026540 +v -1.462592 2.180404 -0.146818 +v -1.465084 2.179801 -0.149170 +v -1.533531 2.339764 -0.115189 +v -1.535957 2.339373 -0.118399 +v -1.554242 2.363811 -0.117297 +v -1.617508 2.510360 -0.089073 +v -1.502334 2.648102 -0.128294 +v -1.453644 2.518908 -0.159250 +v -1.433823 2.840027 -0.021735 +v -1.379331 2.836251 0.115069 +v -1.375899 2.837615 0.115335 +v -1.431469 2.841581 -0.024135 +v -1.256651 2.317486 0.159724 +v -1.203152 2.369618 0.017069 +v -1.199450 2.370987 0.017326 +v -1.253900 2.317907 0.162634 +v -1.251751 2.297872 0.155230 +v -1.377375 2.241302 0.203371 +v -1.377120 2.240508 0.206865 +v -1.249317 2.298203 0.157898 +v -1.481884 2.174423 0.127414 +v -1.385172 2.260201 0.207997 +v -1.385257 2.259221 0.211767 +v -1.484538 2.172840 0.129465 +v -1.510884 2.128284 -0.019207 +v -1.454848 2.160742 -0.150651 +v -1.457275 2.160314 -0.153838 +v -1.514776 2.126724 -0.019311 +v -1.685361 2.472375 0.050914 +v -1.752368 2.661217 0.088489 +v -1.694405 2.718712 -0.047581 +v -1.631748 2.542751 -0.081637 +v -1.375544 2.327142 -0.178950 +v -1.253086 2.359437 -0.126590 +v -1.250793 2.360622 -0.129002 +v -1.375139 2.327835 -0.182733 +v -1.689330 2.726648 -0.037788 +v -1.560466 2.797689 -0.083845 +v -1.560548 2.798493 -0.087504 +v -1.691731 2.726237 -0.040560 +v -1.473240 2.155351 0.123499 +v -1.475534 2.153739 0.126197 +v -1.559066 2.724717 0.292047 +v -1.681709 2.677818 0.230057 +v -1.684190 2.676429 0.232621 +v -1.559010 2.724133 0.295815 +v -1.480236 2.752783 0.286610 +v -1.430994 2.623322 0.266876 +v -1.432751 2.789047 0.246217 +v -1.430289 2.789541 0.248949 +v -1.200159 2.349199 0.014001 +v -1.196773 2.350455 0.014146 +v -1.515003 2.582226 0.271529 +v -1.514913 2.581644 0.275222 +v -1.504827 2.652220 -0.115538 +v -1.373182 2.705838 -0.060628 +v -1.371061 2.707243 -0.062840 +v -1.504840 2.653126 -0.119262 +v -1.524270 2.607950 0.286821 +v -1.556818 2.716202 0.302356 +v -1.687128 2.666902 0.236217 +v -1.636275 2.490432 0.199546 +v -1.452655 2.084316 0.117203 +v -1.743922 2.672072 0.090526 +v -1.747322 2.670753 0.090298 +v -1.519191 2.147595 -0.015375 +v -1.522344 2.146392 -0.015785 +v -1.250402 2.325480 0.169617 +v -1.276133 2.423432 0.191597 +v -1.449510 2.398722 0.253323 +v -1.388114 2.263882 0.220625 +v -1.752368 2.661217 0.088489 +v -1.685361 2.472375 0.050914 +v -1.243852 2.356381 -0.135238 +v -1.209875 2.239608 -0.147323 +v -1.507991 2.090690 -0.026540 +v -1.373837 2.232265 0.212888 +v -1.335060 2.143106 0.190519 +v -1.453644 2.518908 -0.159250 +v -1.502334 2.648102 -0.128294 +v -1.596369 2.281132 0.011835 +v -1.671654 2.439415 0.044154 +v -1.385685 2.354910 -0.185988 +v -1.437759 2.485444 -0.165995 +v -1.434940 2.487633 -0.175082 +v -1.382867 2.357099 -0.195075 +v -1.286561 2.457734 0.198380 +v -1.344074 2.603219 0.224207 +v -1.532732 2.150167 -0.015417 +v -1.580128 2.249134 0.004945 +v -1.537226 2.331924 -0.125488 +v -1.473290 2.185266 -0.153123 +v -1.631748 2.542751 -0.081637 +v -1.694405 2.718712 -0.047581 +v -1.613111 2.518066 -0.079110 +v -1.615652 2.517722 -0.082194 +v -1.454004 2.138791 -0.163097 +v -1.193377 2.380636 0.018891 +v -1.221952 2.531958 0.042310 +v -1.580128 2.249134 0.004945 +v -1.532732 2.150167 -0.015417 +v -1.294047 2.536709 -0.112727 +v -1.223969 2.535075 0.042863 +v -1.223969 2.535075 0.042863 +v -1.294047 2.536709 -0.112727 +v -1.296773 2.538260 -0.110324 +v -1.227429 2.536603 0.043269 +v -1.310893 2.725578 0.086970 +v -1.346248 2.606512 0.224060 +v -1.314820 2.726845 0.087451 +v -1.349199 2.608663 0.222427 +v -1.349199 2.608663 0.222427 +v -1.314820 2.726845 0.087451 +v -1.512430 2.573377 0.281706 +v -1.513603 2.577073 0.281235 +v -1.513603 2.577073 0.281235 +v -1.346248 2.606512 0.224060 +v -1.514512 2.580099 0.278861 +v -1.463702 2.429024 0.258372 +v -1.286085 2.454078 0.197016 +v -1.462529 2.427003 0.255218 +v -1.287026 2.451177 0.194526 +v -1.287026 2.451177 0.194526 +v -1.462529 2.427003 0.255218 +v -1.634410 2.487304 0.198215 +v -1.523144 2.604571 0.285300 +v -1.631561 2.485788 0.196062 +v -1.522247 2.602442 0.282168 +v -1.522247 2.602442 0.282168 +v -1.631561 2.485788 0.196062 +v -1.375277 2.235750 0.212677 +v -1.477910 2.147747 0.129910 +v -1.376478 2.238767 0.210472 +v -1.477342 2.151315 0.128562 +v -1.477342 2.151315 0.128562 +v -1.376478 2.238767 0.210472 +v -1.532619 2.258065 0.153449 +v -1.533673 2.261778 0.153542 +v -1.580893 2.252777 0.005715 +v -1.580893 2.252777 0.005715 +v -1.533673 2.261778 0.153542 +v -1.533268 2.265288 0.152303 +v -1.579686 2.256130 0.006452 +v -1.530262 2.147242 -0.015956 +v -1.490789 2.173318 0.133826 +v -1.490789 2.173318 0.133826 +v -1.530262 2.147242 -0.015956 +v -1.526463 2.145858 -0.016092 +v -1.487672 2.172101 0.131758 +v -1.551942 2.360655 -0.117289 +v -1.593717 2.278284 0.011235 +v -1.548724 2.358688 -0.115969 +v -1.589791 2.276981 0.010941 +v -1.589791 2.276981 0.010941 +v -1.548724 2.358688 -0.115969 +v -1.618258 2.513817 -0.087682 +v -1.503597 2.651272 -0.126488 +v -1.617579 2.516511 -0.085163 +v -1.504514 2.653111 -0.123182 +v -1.504514 2.653111 -0.123182 +v -1.617579 2.516511 -0.085163 +v -1.372084 2.322399 -0.191332 +v -1.459789 2.156195 -0.159358 +v -1.373325 2.325613 -0.189745 +v -1.459115 2.159006 -0.156841 +v -1.374443 2.327603 -0.186598 +v -1.374443 2.327603 -0.186598 +v -1.459115 2.159006 -0.156841 +v -1.752497 2.664957 0.089215 +v -1.694883 2.722164 -0.046171 +v -1.694883 2.722164 -0.046171 +v -1.752497 2.664957 0.089215 +v -1.750652 2.668447 0.089877 +v -1.693906 2.724918 -0.043600 +v -1.368176 2.836955 0.115048 +v -1.424573 2.787164 0.253342 +v -1.371908 2.838202 0.115407 +v -1.427392 2.789178 0.251643 +v -1.427392 2.789178 0.251643 +v -1.371908 2.838202 0.115407 +v -1.423930 2.838457 -0.030976 +v -1.425915 2.841197 -0.029379 +v -1.368176 2.836955 0.115048 +v -1.425915 2.841197 -0.029379 +v -1.428673 2.842341 -0.026875 +v -1.557875 2.719740 0.301836 +v -1.687428 2.670675 0.236252 +v -1.687428 2.670675 0.236252 +v -1.557875 2.719740 0.301836 +v -1.558677 2.722643 0.299442 +v -1.686354 2.674161 0.234936 +v -1.752497 2.664957 0.089215 +v -1.473290 2.185266 -0.153123 +v -1.385685 2.354910 -0.185988 +v -1.384400 2.351401 -0.185511 +v -1.471218 2.182046 -0.153053 +v -1.383301 2.348613 -0.183177 +v -1.468211 2.180045 -0.151606 +v -1.468211 2.180045 -0.151606 +v -1.383301 2.348613 -0.183177 +v -1.538188 2.335395 -0.124068 +v -1.439248 2.488698 -0.164450 +v -1.537726 2.338120 -0.121473 +v -1.440380 2.490741 -0.161284 +v -1.440380 2.490741 -0.161284 +v -1.537726 2.338120 -0.121473 +v -1.514856 2.677221 -0.120502 +v -1.629694 2.539500 -0.081598 +v -1.513631 2.674221 -0.118351 +v -1.626741 2.537422 -0.080153 +v -1.626741 2.537422 -0.080153 +v -1.513631 2.674221 -0.118351 +v -1.519183 2.121028 -0.020184 +v -1.517756 2.124477 -0.019594 +v -1.517756 2.124477 -0.019594 +v -1.629694 2.539500 -0.081598 +v -1.682955 2.469397 0.050301 +v -1.626741 2.537422 -0.080153 +v -1.679211 2.467982 0.050002 +v -1.679211 2.467982 0.050002 +v -1.672127 2.443120 0.044898 +v -1.670668 2.446540 0.045600 +v -1.670668 2.446540 0.045600 +v -1.593717 2.278284 0.011235 +v -1.547950 2.287616 0.157214 +v -1.547950 2.287616 0.157214 +v -1.593717 2.278284 0.011235 +v -1.544670 2.286323 0.155279 +v -1.623076 2.456849 0.193649 +v -1.623805 2.460572 0.193701 +v -1.672127 2.443120 0.044898 +v -1.623805 2.460572 0.193701 +v -1.623091 2.464014 0.192442 +v -1.386744 2.260859 0.218863 +v -1.487672 2.172101 0.131758 +v -1.385699 2.259153 0.215620 +v -1.385699 2.259153 0.215620 +v -1.451133 2.402245 0.253124 +v -1.533673 2.261778 0.153542 +v -1.452401 2.405247 0.250967 +v -1.533268 2.265288 0.152303 +v -1.452401 2.405247 0.250967 +v -1.386744 2.260859 0.218863 +v -1.250256 2.321983 0.168127 +v -1.250256 2.321983 0.168127 +v -1.386744 2.260859 0.218863 +v -1.251536 2.319211 0.165571 +v -1.243763 2.295471 0.162188 +v -1.375277 2.235750 0.212677 +v -1.375277 2.235750 0.212677 +v -1.243763 2.295471 0.162188 +v -1.246389 2.297666 0.160626 +v -1.359238 2.636658 0.230309 +v -1.358357 2.633115 0.228998 +v -1.358357 2.633115 0.228998 +v -1.523144 2.604571 0.285300 +v -1.358941 2.630302 0.226505 +v -1.286085 2.454078 0.197016 +v -1.232800 2.562018 0.049005 +v -1.232800 2.562018 0.049005 +v -1.286085 2.454078 0.197016 +v -1.234439 2.558542 0.048208 +v -1.358357 2.633115 0.228998 +v -1.323935 2.750481 0.093647 +v -1.358941 2.630302 0.226505 +v -1.325213 2.747162 0.092849 +v -1.325213 2.747162 0.092849 +v -1.232800 2.562018 0.049005 +v -1.304538 2.564165 -0.107426 +v -1.304538 2.564165 -0.107426 +v -1.305116 2.560596 -0.106212 +v -1.189851 2.349293 0.013912 +v -1.192941 2.350875 0.014167 +v -1.246389 2.297666 0.160626 +v -1.192941 2.350875 0.014167 +v -1.223969 2.535075 0.042863 +v -1.277824 2.426734 0.191589 +v -1.227429 2.536603 0.043269 +v -1.280410 2.428961 0.190030 +v -1.280410 2.428961 0.190030 +v -1.245401 2.359493 -0.134141 +v -1.247941 2.361046 -0.131859 +v -1.247941 2.361046 -0.131859 +v -1.251705 2.390566 -0.131151 +v -1.193821 2.376768 0.018287 +v -1.251564 2.386742 -0.130891 +v -1.251564 2.386742 -0.130891 +v -1.193821 2.376768 0.018287 +v -1.196045 2.373236 0.017715 +v -1.252816 2.383247 -0.129349 +v -1.451133 2.402245 0.253124 +v -1.451133 2.402245 0.253124 +v -1.277824 2.426734 0.191589 +v -1.452401 2.405247 0.250967 +v -1.513603 2.577073 0.281235 +v -1.623805 2.460572 0.193701 +v -1.544670 2.286323 0.155279 +v -1.682955 2.469397 0.050301 +v -1.634410 2.487304 0.198215 +v -1.682955 2.469397 0.050301 +v -1.477082 2.143988 0.129879 +v -1.477910 2.147747 0.129910 +v -1.519183 2.121028 -0.020184 +v -1.477910 2.147747 0.129910 +v -1.579686 2.256130 0.006452 +v -1.471218 2.182046 -0.153053 +v -1.530262 2.147242 -0.015956 +v -1.468211 2.180045 -0.151606 +v -1.526463 2.145858 -0.016092 +v -1.554242 2.363811 -0.117297 +v -1.452198 2.515315 -0.159098 +v -1.551942 2.360655 -0.117289 +v -1.450801 2.512355 -0.157041 +v -1.548724 2.358688 -0.115969 +v -1.450801 2.512355 -0.157041 +v -1.694883 2.722164 -0.046171 +v -1.559478 2.796647 -0.094714 +v -1.559478 2.796647 -0.094714 +v -1.560307 2.798440 -0.091448 +v -1.556818 2.716202 0.302356 +v -1.557875 2.719740 0.301836 +v -1.424573 2.787164 0.253342 +v -1.425915 2.841197 -0.029379 +v -1.560307 2.798440 -0.091448 +v -1.428673 2.842341 -0.026875 +v -1.378407 2.735943 -0.061274 +v -1.377489 2.732276 -0.061547 +v -1.377489 2.732276 -0.061547 +v -1.323935 2.750481 0.093647 +v -1.377950 2.728787 -0.060354 +v -1.365285 2.706800 -0.068246 +v -1.310893 2.725578 0.086970 +v -1.310893 2.725578 0.086970 +v -1.365285 2.706800 -0.068246 +v -1.368186 2.708005 -0.065679 +v -1.251705 2.390566 -0.131151 +v -1.251564 2.386742 -0.130891 +v -1.384400 2.351401 -0.185511 +v -1.373325 2.325613 -0.189745 +v -1.245401 2.359493 -0.134141 +v -1.374443 2.327603 -0.186598 +v -1.247941 2.361046 -0.131859 +v -1.305116 2.560596 -0.106212 +v -1.437759 2.485444 -0.165995 +v -1.439248 2.488698 -0.164450 +v -1.440380 2.490741 -0.161284 +v -1.296773 2.538260 -0.110324 +v -1.377489 2.732276 -0.061547 +v -1.377950 2.728787 -0.060354 +v -1.503597 2.651272 -0.126488 +v -1.504514 2.653111 -0.123182 +v -1.368186 2.708005 -0.065679 +v -1.447770 2.832513 0.116284 +v -1.483497 2.834839 0.024929 +v -1.468655 2.804094 0.018823 +v -1.432446 2.801964 0.110178 +v -1.561540 2.731245 0.287205 +v -1.548066 2.699876 0.281099 +v -1.567251 2.756680 0.233742 +v -1.482632 2.800878 0.203001 +v -1.467956 2.770065 0.196895 +v -1.554060 2.725154 0.227636 +v -1.564239 2.745120 0.274122 +v -1.550786 2.713740 0.268017 +v -1.651287 2.723805 0.192229 +v -1.639029 2.691761 0.186123 +v -1.439068 2.793763 0.242895 +v -1.424173 2.763042 0.236789 +v -1.692628 2.720207 0.098958 +v -1.680912 2.687861 0.092852 +v -1.452679 2.802319 0.233238 +v -1.564239 2.745120 0.274122 +v -1.550786 2.713740 0.268017 +v -1.437936 2.771537 0.227133 +v -1.512826 2.815510 0.053561 +v -1.489309 2.814597 0.113456 +v -1.464463 2.825364 0.115186 +v -1.495294 2.827120 0.036382 +v -1.512152 2.793139 0.170126 +v -1.568125 2.762693 0.190248 +v -1.567652 2.759046 0.216357 +v -1.494488 2.797780 0.189883 +v -1.625551 2.739635 0.162010 +v -1.641277 2.730017 0.180087 +v -1.650096 2.738590 0.101997 +v -1.675669 2.727619 0.100258 +v -1.626395 2.762103 0.045467 +v -1.644309 2.758849 0.025806 +v -1.569291 2.794482 0.025432 +v -1.569180 2.800905 -0.000618 +v -1.569008 2.813893 -0.053418 +v -1.460067 2.850497 0.001564 +v -1.562825 2.801994 -0.076929 +v -1.440126 2.843099 -0.016741 +v -1.433823 2.840027 -0.021735 +v -1.560466 2.797689 -0.083845 +v -1.406168 2.843889 0.117993 +v -1.453776 2.847425 -0.003393 +v -1.440126 2.843099 -0.016741 +v -1.387429 2.839488 0.115776 +v -1.406168 2.843889 0.117993 +v -1.414201 2.847145 0.118692 +v -1.458967 2.807040 0.229926 +v -1.387429 2.839488 0.115776 +v -1.439068 2.793763 0.242895 +v -1.432751 2.789047 0.246217 +v -1.379331 2.836251 0.115069 +v -1.564239 2.745120 0.274122 +v -1.452679 2.802319 0.233238 +v -1.439068 2.793763 0.242895 +v -1.561540 2.731245 0.287205 +v -1.674175 2.702788 0.219825 +v -1.680266 2.685770 0.227001 +v -1.730415 2.697331 0.095338 +v -1.740561 2.680353 0.091942 +v -1.727048 2.705632 0.096733 +v -1.680186 2.752493 -0.014042 +v -1.740561 2.680353 0.091942 +v -1.687799 2.733052 -0.032186 +v -1.689330 2.726648 -0.037788 +v -1.743922 2.672072 0.090526 +v -1.566607 2.809596 -0.060332 +v -1.681725 2.746081 -0.019656 +v -1.687799 2.733052 -0.032186 +v -1.562825 2.801994 -0.076929 +v -1.568943 2.805320 -0.018050 +v -1.483497 2.834839 0.024929 +v -1.447770 2.832513 0.116284 +v -1.482632 2.800878 0.203001 +v -1.656240 2.756680 0.012711 +v -1.692628 2.720207 0.098958 +v -1.651287 2.723805 0.192229 +v -1.567251 2.756680 0.233742 +v -1.456319 2.828977 0.115817 +v -1.489702 2.830942 0.030641 +v -1.567572 2.757770 0.225079 +v -1.488813 2.799253 0.196524 +v -1.646943 2.726648 0.186005 +v -1.684160 2.724131 0.099771 +v -1.650187 2.757822 0.019242 +v -1.569315 2.802908 -0.009233 +v -1.553152 2.778218 -0.066437 +v -1.438817 2.816730 -0.009499 +v -1.425003 2.812469 -0.022847 +v -1.549341 2.770630 -0.083035 +v -1.390580 2.813444 0.111887 +v -1.371608 2.809137 0.109671 +v -1.437936 2.771537 0.227133 +v -1.424173 2.763042 0.236789 +v -1.550786 2.713740 0.268017 +v -1.548066 2.699876 0.281099 +v -1.661917 2.670743 0.213719 +v -1.668028 2.653715 0.220895 +v -1.718885 2.664883 0.089232 +v -1.729083 2.647875 0.085837 +v -1.669528 2.714002 -0.025762 +v -1.675620 2.700963 -0.038291 +v -1.556174 2.771352 -0.015338 +v -1.474929 2.800161 0.024535 +v -1.468655 2.804094 0.018823 +v -1.555748 2.773795 -0.024156 +v -1.441048 2.798406 0.109711 +v -1.474195 2.768410 0.190418 +v -1.467956 2.770065 0.196895 +v -1.432446 2.801964 0.110178 +v -1.637960 2.725761 0.013137 +v -1.644027 2.724610 0.006605 +v -1.672392 2.691814 0.093665 +v -1.680912 2.687861 0.092852 +v -1.634686 2.694603 0.179899 +v -1.639029 2.691761 0.186123 +v -1.554440 2.726210 0.218973 +v -1.554060 2.725154 0.227636 +v -1.684160 2.724131 0.099771 +v -1.672392 2.691814 0.093665 +v -1.681725 2.746081 -0.019656 +v -1.669528 2.714002 -0.025762 +v -1.440126 2.843099 -0.016741 +v -1.562825 2.801994 -0.076929 +v -1.549341 2.770630 -0.083035 +v -1.425003 2.812469 -0.022847 +v -1.684160 2.724131 0.099771 +v -1.650187 2.757822 0.019242 +v -1.637960 2.725761 0.013137 +v -1.672392 2.691814 0.093665 +v -1.562825 2.801994 -0.076929 +v -1.549341 2.770630 -0.083035 +v -1.453776 2.847425 -0.003393 +v -1.390580 2.813444 0.111887 +v -1.438817 2.816730 -0.009499 +v -1.650187 2.757822 0.019242 +v -1.569315 2.802908 -0.009233 +v -1.556174 2.771352 -0.015338 +v -1.637960 2.725761 0.013137 +v -1.568943 2.805320 -0.018050 +v -1.555748 2.773795 -0.024156 +v -1.387429 2.839488 0.115776 +v -1.371608 2.809137 0.109671 +v -1.482632 2.800878 0.203001 +v -1.447770 2.832513 0.116284 +v -1.432446 2.801964 0.110178 +v -1.467956 2.770065 0.196895 +v -1.489702 2.830942 0.030641 +v -1.474929 2.800161 0.024535 +v -1.568943 2.805320 -0.018050 +v -1.656240 2.756680 0.012711 +v -1.644027 2.724610 0.006605 +v -1.555748 2.773795 -0.024156 +v -1.439068 2.793763 0.242895 +v -1.387429 2.839488 0.115776 +v -1.371608 2.809137 0.109671 +v -1.424173 2.763042 0.236789 +v -1.692628 2.720207 0.098958 +v -1.680912 2.687861 0.092852 +v -1.552997 2.716012 0.313044 +v -1.520449 2.607760 0.297508 +v -1.524270 2.607950 0.286821 +v -1.359238 2.636658 0.230309 +v -1.430994 2.623322 0.266876 +v -1.520449 2.607760 0.297508 +v -1.520449 2.607760 0.297508 +v -1.552997 2.716012 0.313044 +v -1.422584 2.784039 0.253590 +v -1.556818 2.716202 0.302356 +v -1.552997 2.716012 0.313044 +v -1.480236 2.752783 0.286610 +v -1.382867 2.357099 -0.195075 +v -1.434940 2.487633 -0.175082 +v -1.337245 2.519934 -0.140152 +v -1.293004 2.381014 -0.158295 +v -1.437759 2.485444 -0.165995 +v -1.292100 2.533603 -0.113917 +v -1.337245 2.519934 -0.140152 +v -1.434940 2.487633 -0.175082 +v -1.251705 2.390566 -0.131151 +v -1.385685 2.354910 -0.185988 +v -1.382867 2.357099 -0.195075 +v -1.293004 2.381014 -0.158295 +vt 0.955914 0.900980 +vt 0.965826 0.897519 +vt 0.965568 0.896850 +vt 0.955656 0.900310 +vt 0.879357 0.410269 +vt 0.885163 0.415236 +vt 0.879604 0.409663 +vt 0.408749 0.351854 +vt 0.408749 0.339444 +vt 0.407910 0.345114 +vt 0.407910 0.351841 +vt 0.201033 0.426226 +vt 0.209260 0.428015 +vt 0.209333 0.427418 +vt 0.201107 0.425630 +vt 0.214344 0.335178 +vt 0.214344 0.346808 +vt 0.215182 0.346812 +vt 0.215182 0.340508 +vt 0.408022 0.464293 +vt 0.408022 0.452347 +vt 0.407312 0.456271 +vt 0.407312 0.464283 +vt 0.408030 0.441154 +vt 0.408030 0.430191 +vt 0.407312 0.430163 +vt 0.407312 0.437516 +vt 0.070535 0.116212 +vt 0.066343 0.116465 +vt 0.065636 0.167968 +vt 0.070535 0.167622 +vt 0.971532 0.405885 +vt 0.974960 0.405834 +vt 0.974446 0.354350 +vt 0.971173 0.354410 +vt 0.979589 0.405960 +vt 0.979234 0.354457 +vt 0.982753 0.406136 +vt 0.982753 0.354735 +vt 0.587667 0.175333 +vt 0.591996 0.175479 +vt 0.591996 0.124322 +vt 0.586981 0.123929 +vt 0.140713 0.034874 +vt 0.137349 0.034778 +vt 0.137507 0.085768 +vt 0.140713 0.086028 +vt 0.132656 0.034808 +vt 0.132655 0.085961 +vt 0.129424 0.034978 +vt 0.129064 0.086386 +vt 0.476695 0.051109 +vt 0.488153 0.051602 +vt 0.488290 0.051347 +vt 0.476578 0.050833 +vt 0.866451 0.415223 +vt 0.871853 0.409662 +vt 0.871052 0.407775 +vt 0.864568 0.414434 +vt 0.495329 0.072353 +vt 0.487803 0.080573 +vt 0.487901 0.080810 +vt 0.495567 0.072476 +vt 0.476860 0.080222 +vt 0.468648 0.071654 +vt 0.468395 0.071765 +vt 0.476783 0.080471 +vt 0.090884 0.069208 +vt 0.080879 0.068843 +vt 0.080504 0.069626 +vt 0.091174 0.070002 +vt 0.107763 0.055970 +vt 0.119795 0.055989 +vt 0.119897 0.055747 +vt 0.107667 0.055756 +vt 0.984909 0.595764 +vt 0.991710 0.595757 +vt 0.992564 0.584064 +vt 0.980644 0.582940 +vt 0.127940 0.066612 +vt 0.128196 0.066532 +vt 0.126647 0.078606 +vt 0.118233 0.085872 +vt 0.118343 0.086149 +vt 0.126897 0.078721 +vt 0.100242 0.064553 +vt 0.099997 0.064431 +vt 0.745746 0.042355 +vt 0.734850 0.045168 +vt 0.735018 0.053777 +vt 0.747904 0.051210 +vt 0.080909 0.053166 +vt 0.083730 0.050053 +vt 0.081135 0.044690 +vt 0.075493 0.050832 +vt 0.387661 0.033089 +vt 0.376926 0.030233 +vt 0.380091 0.043408 +vt 0.393478 0.046187 +vt 0.074025 0.060591 +vt 0.073237 0.060890 +vt 0.886966 0.414403 +vt 0.880338 0.407767 +vt 0.339240 0.033109 +vt 0.348198 0.034281 +vt 0.348218 0.025896 +vt 0.339690 0.024840 +vt 0.885458 0.423065 +vt 0.887290 0.423654 +vt 0.643215 0.026561 +vt 0.651743 0.025765 +vt 0.651148 0.017956 +vt 0.644342 0.018128 +vt 0.880264 0.429206 +vt 0.881077 0.431126 +vt 0.760801 0.076013 +vt 0.753587 0.084292 +vt 0.753696 0.084525 +vt 0.761047 0.076145 +vt 0.872335 0.428967 +vt 0.871563 0.430833 +vt 0.888075 0.428913 +vt 0.894957 0.431536 +vt 0.894920 0.419771 +vt 0.890386 0.418024 +vt 0.866568 0.423113 +vt 0.864671 0.423848 +vt 0.088067 0.050247 +vt 0.089940 0.044945 +vt 0.013015 0.012752 +vt 0.023996 0.012058 +vt 0.024213 0.003090 +vt 0.012901 0.004896 +vt 0.655349 0.041091 +vt 0.657477 0.040719 +vt 0.654302 0.029629 +vt 0.653223 0.029866 +vt 0.091271 0.053680 +vt 0.096382 0.051596 +vt 0.911342 0.030343 +vt 0.921346 0.035378 +vt 0.919062 0.021429 +vt 0.912856 0.018524 +vt 0.618671 0.084332 +vt 0.610221 0.075057 +vt 0.609973 0.075157 +vt 0.618578 0.084572 +vt 0.091372 0.058378 +vt 0.096412 0.060859 +vt 0.073453 0.050006 +vt 0.072644 0.049688 +vt 0.643538 0.038381 +vt 0.652552 0.037268 +vt 0.088400 0.061553 +vt 0.090299 0.067283 +vt 0.619144 0.054689 +vt 0.629950 0.054494 +vt 0.630077 0.054214 +vt 0.619031 0.054426 +vt 0.854733 0.056889 +vt 0.862393 0.050153 +vt 0.862311 0.049875 +vt 0.854464 0.056772 +vt 0.084215 0.061297 +vt 0.081864 0.066912 +vt 0.468375 0.059809 +vt 0.468104 0.059710 +vt 0.081159 0.057801 +vt 0.076020 0.059885 +vt 0.080153 0.042937 +vt 0.079793 0.042172 +vt 0.565738 0.034420 +vt 0.578845 0.035138 +vt 0.574961 0.021941 +vt 0.563326 0.020490 +vt 0.495279 0.060256 +vt 0.495555 0.060170 +vt 0.107531 0.085184 +vt 0.107382 0.085467 +vt 0.733153 0.065399 +vt 0.741344 0.055138 +vt 0.741214 0.054873 +vt 0.732880 0.065306 +vt 0.379919 0.052061 +vt 0.392894 0.054329 +vt 0.880228 0.089098 +vt 0.880228 0.078115 +vt 0.878036 0.079316 +vt 0.878266 0.088618 +vt 0.882563 0.128256 +vt 0.882563 0.117799 +vt 0.880695 0.118127 +vt 0.880587 0.127038 +vt 0.098042 0.061675 +vt 0.098033 0.050905 +vt 0.882091 0.089100 +vt 0.882091 0.078326 +vt 0.880292 0.079078 +vt 0.880268 0.088338 +vt 0.090493 0.043214 +vt 0.996235 0.965997 +vt 0.996450 0.975739 +vt 0.999015 0.975785 +vt 0.998800 0.965931 +vt 0.777001 0.015600 +vt 0.777253 0.004897 +vt 0.774676 0.004660 +vt 0.774431 0.015391 +vt 0.957387 0.014848 +vt 0.957331 0.007926 +vt 0.954760 0.007739 +vt 0.954821 0.014726 +vt 0.428694 0.181051 +vt 0.428700 0.171140 +vt 0.426126 0.171286 +vt 0.426115 0.181223 +vt 0.996896 0.926964 +vt 0.997182 0.931906 +vt 0.999749 0.931940 +vt 0.999454 0.926941 +vt 0.408338 0.367211 +vt 0.408206 0.375103 +vt 0.410777 0.374920 +vt 0.410913 0.366969 +vt 0.997191 0.915500 +vt 0.996948 0.920166 +vt 0.999505 0.920119 +vt 0.999749 0.915471 +vt 0.999465 0.905554 +vt 0.999497 0.897662 +vt 0.996921 0.897423 +vt 0.996894 0.905369 +vt 0.603896 0.010808 +vt 0.608936 0.000208 +vt 0.607517 0.000860 +vt 0.602426 0.011409 +vt 0.441687 0.014354 +vt 0.444185 0.003510 +vt 0.442744 0.004228 +vt 0.440238 0.015039 +vt 0.916907 0.411434 +vt 0.914059 0.421469 +vt 0.915582 0.420987 +vt 0.918432 0.410989 +vt 0.608936 0.020424 +vt 0.607465 0.021001 +vt 0.444185 0.025297 +vt 0.442732 0.025958 +vt 0.528860 0.088199 +vt 0.528860 0.099394 +vt 0.530435 0.099185 +vt 0.530435 0.087995 +vt 0.072094 0.157036 +vt 0.072365 0.148898 +vt 0.070875 0.148371 +vt 0.070602 0.156533 +vt 0.996154 0.068960 +vt 0.995543 0.076745 +vt 0.997120 0.077006 +vt 0.997734 0.069235 +vt 0.164004 0.033680 +vt 0.164460 0.041896 +vt 0.166029 0.042136 +vt 0.165573 0.033983 +vt 0.072365 0.168287 +vt 0.070923 0.167722 +vt 0.990354 0.056514 +vt 0.991934 0.056878 +vt 0.159879 0.021333 +vt 0.161457 0.021655 +vt 0.757264 0.797377 +vt 0.757456 0.789459 +vt 0.755906 0.789513 +vt 0.755745 0.797328 +vt 0.996227 0.048595 +vt 0.997734 0.049094 +vt 0.164414 0.013345 +vt 0.166029 0.013543 +vt 0.757353 0.809279 +vt 0.755850 0.809068 +vt 0.213856 0.126685 +vt 0.213855 0.140237 +vt 0.215358 0.140739 +vt 0.215358 0.127176 +vt 0.735816 0.165183 +vt 0.735816 0.152229 +vt 0.734334 0.151564 +vt 0.734324 0.164659 +vt 0.757456 0.817209 +vt 0.755932 0.816998 +vt 0.712349 0.787058 +vt 0.712403 0.778464 +vt 0.710826 0.778564 +vt 0.710750 0.787088 +vt 0.916502 0.432403 +vt 0.916882 0.440446 +vt 0.918432 0.440116 +vt 0.918034 0.431976 +vt 0.931738 0.907717 +vt 0.931738 0.897459 +vt 0.930210 0.897563 +vt 0.930178 0.907696 +vt 0.712403 0.798513 +vt 0.710794 0.798499 +vt 0.348186 0.013550 +vt 0.342077 0.013486 +vt 0.742784 0.084876 +vt 0.734016 0.077888 +vt 0.733782 0.078029 +vt 0.742739 0.085143 +vt 0.996848 0.838076 +vt 0.995743 0.838097 +vt 0.987116 0.846394 +vt 0.996848 0.846162 +vt 0.753413 0.055389 +vt 0.760753 0.064199 +vt 0.761036 0.064119 +vt 0.753535 0.055131 +vt 0.895452 0.411138 +vt 0.893440 0.410351 +vt 0.873701 0.050365 +vt 0.873823 0.050139 +vt 0.100346 0.076701 +vt 0.100056 0.076774 +vt 0.590508 0.033516 +vt 0.602285 0.031283 +vt 0.606088 0.021500 +vt 0.595778 0.023247 +vt 0.307040 0.052668 +vt 0.317921 0.052437 +vt 0.318027 0.052185 +vt 0.306933 0.052417 +vt 0.863112 0.076688 +vt 0.854854 0.068109 +vt 0.854585 0.068221 +vt 0.862993 0.076960 +vt 0.499175 0.060057 +vt 0.499367 0.049387 +vt 0.499119 0.049291 +vt 0.498924 0.060152 +vt 0.881189 0.068858 +vt 0.874072 0.076795 +vt 0.874195 0.077055 +vt 0.881452 0.068934 +vt 0.517852 0.042309 +vt 0.525241 0.049879 +vt 0.525527 0.049793 +vt 0.517967 0.042023 +vt 0.388311 0.021031 +vt 0.388311 0.005969 +vt 0.376596 0.005305 +vt 0.376652 0.019334 +vt 0.525576 0.061606 +vt 0.518566 0.068840 +vt 0.518667 0.069076 +vt 0.525823 0.061743 +vt 0.299502 0.071914 +vt 0.299524 0.060538 +vt 0.299268 0.060435 +vt 0.299248 0.072015 +vt 0.507208 0.042280 +vt 0.507086 0.042021 +vt 0.325663 0.071148 +vt 0.318293 0.078958 +vt 0.318407 0.079213 +vt 0.325926 0.071246 +vt 0.992726 0.579644 +vt 0.982448 0.578452 +vt 0.325669 0.060187 +vt 0.325921 0.060078 +vt 0.507444 0.068318 +vt 0.507340 0.068562 +vt 0.611024 0.063349 +vt 0.610767 0.063250 +vt 0.637368 0.075268 +vt 0.630106 0.083886 +vt 0.630202 0.084114 +vt 0.637626 0.075385 +vt 0.199941 0.437566 +vt 0.213354 0.441013 +vt 0.098813 0.061981 +vt 0.307066 0.079957 +vt 0.306964 0.080206 +vt 0.881236 0.058053 +vt 0.881463 0.057945 +vt 0.994452 0.169610 +vt 0.986838 0.169307 +vt 0.982996 0.178478 +vt 0.994202 0.178052 +vt 0.199009 0.446775 +vt 0.213807 0.449673 +vt 0.987564 0.857034 +vt 0.996522 0.856492 +vt 0.098813 0.050584 +vt 0.348371 0.005326 +vt 0.340999 0.005619 +vt 0.742777 0.030577 +vt 0.732720 0.033464 +vt 0.590040 0.045265 +vt 0.603030 0.043111 +vt 0.393573 0.024586 +vt 0.382136 0.021994 +vt 0.954567 0.922127 +vt 0.962517 0.919944 +vt 0.961678 0.908117 +vt 0.950193 0.911610 +vt 0.638810 0.048106 +vt 0.652734 0.046305 +vt 0.637350 0.062894 +vt 0.637631 0.062800 +vt 0.090802 0.042445 +vt 0.994471 0.157019 +vt 0.983160 0.155575 +vt 0.921845 0.013608 +vt 0.914360 0.010144 +vt 0.024274 0.012090 +vt 0.024485 0.003144 +vt 0.120099 0.055346 +vt 0.107486 0.055346 +vt 0.107555 0.055505 +vt 0.120011 0.055497 +vt 0.579120 0.035114 +vt 0.575235 0.021999 +vt 0.579325 0.035029 +vt 0.575426 0.022097 +vt 0.609704 0.075255 +vt 0.618469 0.084843 +vt 0.579061 0.013388 +vt 0.579325 0.013503 +vt 0.610298 0.063017 +vt 0.609497 0.075310 +vt 0.610501 0.063133 +vt 0.387927 0.033184 +vt 0.393825 0.024731 +vt 0.388114 0.033300 +vt 0.393978 0.024969 +vt 0.732619 0.065207 +vt 0.733537 0.078166 +vt 0.213631 0.441042 +vt 0.209528 0.428101 +vt 0.213848 0.440997 +vt 0.209720 0.428222 +vt 0.468136 0.071867 +vt 0.476694 0.080730 +vt 0.895223 0.431602 +vt 0.895172 0.419888 +vt 0.895452 0.431589 +vt 0.895347 0.420016 +vt 0.506968 0.041767 +vt 0.498848 0.049179 +vt 0.966117 0.927348 +vt 0.966370 0.927215 +vt 0.962777 0.919848 +vt 0.107187 0.085883 +vt 0.118525 0.086590 +vt 0.118444 0.086399 +vt 0.107264 0.085703 +vt 0.914082 0.010090 +vt 0.912597 0.018438 +vt 0.881918 0.069073 +vt 0.881918 0.057726 +vt 0.881728 0.057818 +vt 0.881721 0.069012 +vt 0.590240 0.033582 +vt 0.589764 0.045276 +vt 0.590049 0.033666 +vt 0.589551 0.045222 +vt 0.753822 0.084793 +vt 0.761297 0.076277 +vt 0.602558 0.031259 +vt 0.606369 0.021522 +vt 0.602766 0.031301 +vt 0.606596 0.021677 +vt 0.637882 0.075491 +vt 0.637882 0.062705 +vt 0.661292 0.019874 +vt 0.654578 0.029601 +vt 0.661570 0.019883 +vt 0.654794 0.029641 +vt 0.661807 0.020029 +vt 0.526063 0.061864 +vt 0.525778 0.049704 +vt 0.388278 0.005704 +vt 0.376623 0.005041 +vt 0.298800 0.072241 +vt 0.306779 0.080714 +vt 0.306856 0.080484 +vt 0.298987 0.072131 +vt 0.991973 0.595729 +vt 0.992821 0.584118 +vt 0.992166 0.595649 +vt 0.993001 0.584214 +vt 0.326188 0.059976 +vt 0.318139 0.051926 +vt 0.990938 0.603675 +vt 0.991203 0.603602 +vt 0.318225 0.051744 +vt 0.306731 0.051991 +vt 0.306819 0.052164 +vt 0.200772 0.426204 +vt 0.199688 0.437474 +vt 0.318598 0.079703 +vt 0.326394 0.071474 +vt 0.326191 0.071360 +vt 0.318518 0.079477 +vt 0.198759 0.446648 +vt 0.998555 0.083764 +vt 0.994006 0.094770 +vt 0.994259 0.094687 +vt 0.998833 0.083719 +vt 0.994461 0.094686 +vt 0.999091 0.083820 +vt 0.873953 0.049889 +vt 0.862225 0.049610 +vt 0.961955 0.908070 +vt 0.966113 0.897497 +vt 0.962179 0.908097 +vt 0.966370 0.897614 +vt 0.099750 0.064314 +vt 0.099798 0.076845 +vt 0.643260 0.038381 +vt 0.638530 0.048064 +vt 0.643048 0.038321 +vt 0.638313 0.047892 +vt 0.495818 0.072599 +vt 0.495818 0.060082 +vt 0.657743 0.040642 +vt 0.657926 0.040526 +vt 0.518064 0.041768 +vt 0.376672 0.019609 +vt 0.388273 0.021305 +vt 0.376733 0.019812 +vt 0.388184 0.021506 +vt 0.488012 0.081078 +vt 0.603292 0.043033 +vt 0.603474 0.042922 +vt 0.630185 0.053962 +vt 0.393180 0.054299 +vt 0.393757 0.046198 +vt 0.742653 0.085623 +vt 0.753915 0.084992 +vt 0.742691 0.085421 +vt 0.606342 0.050586 +vt 0.606596 0.050470 +vt 0.630257 0.053760 +vt 0.618843 0.053972 +vt 0.618925 0.054174 +vt 0.911123 0.030193 +vt 0.912379 0.018439 +vt 0.910995 0.030039 +vt 0.874310 0.077311 +vt 0.921613 0.035471 +vt 0.919307 0.021566 +vt 0.921845 0.035483 +vt 0.919471 0.021708 +vt 0.127157 0.078844 +vt 0.994468 0.177976 +vt 0.994714 0.169596 +vt 0.862750 0.077427 +vt 0.874388 0.077505 +vt 0.862868 0.077222 +vt 0.348449 0.013585 +vt 0.348641 0.005386 +vt 0.498650 0.049082 +vt 0.498458 0.060274 +vt 0.498651 0.060240 +vt 0.213821 0.419619 +vt 0.214089 0.419717 +vt 0.467666 0.059536 +vt 0.467946 0.071917 +vt 0.467849 0.059613 +vt 0.563046 0.020475 +vt 0.565467 0.034366 +vt 0.740987 0.054421 +vt 0.732422 0.065114 +vt 0.741088 0.054620 +vt 0.980362 0.582945 +vt 0.984638 0.595738 +vt 0.980146 0.583009 +vt 0.984441 0.595663 +vt 0.476470 0.050584 +vt 0.748150 0.051065 +vt 0.746007 0.042253 +vt 0.753711 0.054696 +vt 0.753644 0.054884 +vt 0.348478 0.025903 +vt 0.348671 0.025843 +vt 0.348644 0.013670 +vt 0.507227 0.068803 +vt 0.982888 0.155588 +vt 0.986571 0.169270 +vt 0.982687 0.155668 +vt 0.986375 0.169183 +vt 0.128466 0.066463 +vt 0.348465 0.034245 +vt 0.348671 0.034069 +vt 0.518778 0.069326 +vt 0.994471 0.148629 +vt 0.994729 0.157087 +vt 0.994729 0.148735 +vt 0.853960 0.056581 +vt 0.854061 0.068423 +vt 0.854306 0.068332 +vt 0.854192 0.056661 +vt 0.982718 0.178421 +vt 0.127350 0.078942 +vt 0.128659 0.066440 +vt 0.127157 0.078844 +vt 0.376652 0.030192 +vt 0.379831 0.043322 +vt 0.393978 0.046129 +vt 0.214089 0.449641 +vt 0.476621 0.080901 +vt 0.488090 0.081267 +vt 0.661547 0.048125 +vt 0.661807 0.048011 +vt 0.518130 0.041565 +vt 0.506877 0.041565 +vt 0.962952 0.919727 +vt 0.949939 0.911714 +vt 0.954297 0.922177 +vt 0.949767 0.911830 +vt 0.954084 0.922161 +vt 0.747616 0.020560 +vt 0.743054 0.030533 +vt 0.747904 0.020576 +vt 0.743278 0.030569 +vt 0.748150 0.020727 +vt 0.761297 0.064038 +vt 0.652990 0.046201 +vt 0.652809 0.037211 +vt 0.298815 0.060291 +vt 0.299005 0.060340 +vt 0.992748 0.575702 +vt 0.993001 0.575810 +vt 0.326394 0.059921 +vt 0.652005 0.025769 +vt 0.652990 0.037118 +vt 0.652199 0.025836 +vt 0.982346 0.603827 +vt 0.982073 0.603764 +vt 0.488490 0.050934 +vt 0.476388 0.050409 +vt 0.488412 0.051108 +vt 0.734576 0.045199 +vt 0.734731 0.053751 +vt 0.618382 0.085037 +vt 0.630400 0.084559 +vt 0.630316 0.084377 +vt 0.998880 0.104659 +vt 0.999091 0.104499 +vt 0.862145 0.049415 +vt 0.986843 0.846424 +vt 0.987297 0.857028 +vt 0.986636 0.846482 +vt 0.987091 0.856960 +vt 0.746191 0.042128 +vt 0.023893 0.024010 +vt 0.024174 0.023999 +vt 0.024386 0.023943 +vt 0.024485 0.012169 +vt 0.642943 0.026610 +vt 0.642744 0.026697 +vt 0.732464 0.033563 +vt 0.732292 0.033680 +vt 0.734364 0.045158 +vt 0.949394 0.002110 +vt 0.949312 0.007426 +vt 0.951873 0.007330 +vt 0.951956 0.001981 +vt 0.408147 0.385498 +vt 0.410711 0.385411 +vt 0.495047 0.285014 +vt 0.495151 0.290564 +vt 0.497715 0.290552 +vt 0.497612 0.284891 +vt 0.999497 0.915130 +vt 0.996934 0.915033 +vt 0.495081 0.277672 +vt 0.497651 0.277476 +vt 0.408348 0.393501 +vt 0.410913 0.393519 +vt 0.495143 0.272243 +vt 0.497715 0.272006 +vt 0.850434 0.088785 +vt 0.850766 0.095773 +vt 0.853330 0.095779 +vt 0.852991 0.088743 +vt 0.763491 0.775977 +vt 0.768242 0.775870 +vt 0.768988 0.774012 +vt 0.762739 0.774126 +vt 0.771601 0.779246 +vt 0.771595 0.784174 +vt 0.773413 0.784835 +vt 0.773415 0.778431 +vt 0.768202 0.787888 +vt 0.769055 0.789575 +vt 0.763427 0.788130 +vt 0.762660 0.790039 +vt 0.760089 0.784626 +vt 0.758267 0.785405 +vt 0.760122 0.779558 +vt 0.758308 0.778758 +vt 0.995792 0.966147 +vt 0.995993 0.975555 +vt 0.497731 0.394906 +vt 0.497725 0.405451 +vt 0.498177 0.405646 +vt 0.498177 0.394764 +vt 0.870930 0.407377 +vt 0.864209 0.414281 +vt 0.307189 0.053030 +vt 0.317726 0.052810 +vt 0.850515 0.079095 +vt 0.850073 0.079275 +vt 0.849996 0.088624 +vt 0.497737 0.383694 +vt 0.497738 0.394388 +vt 0.498177 0.394545 +vt 0.498177 0.383507 +vt 0.887419 0.414238 +vt 0.880554 0.407377 +vt 0.325240 0.060312 +vt 0.325227 0.070943 +vt 0.887766 0.423823 +vt 0.318079 0.078502 +vt 0.881323 0.431573 +vt 0.307209 0.079469 +vt 0.429171 0.180835 +vt 0.429171 0.171291 +vt 0.211121 0.386574 +vt 0.211126 0.397279 +vt 0.211597 0.397430 +vt 0.211597 0.386359 +vt 0.864313 0.424030 +vt 0.871442 0.431263 +vt 0.299890 0.071694 +vt 0.299907 0.060659 +vt 0.867173 0.422865 +vt 0.867058 0.415467 +vt 0.872107 0.410269 +vt 0.872588 0.428364 +vt 0.879993 0.428586 +vt 0.884854 0.422840 +vt 0.884573 0.415501 +vt 0.769237 0.773401 +vt 0.762480 0.773525 +vt 0.774018 0.785062 +vt 0.774018 0.778176 +vt 0.769322 0.790166 +vt 0.762411 0.790668 +vt 0.757661 0.785657 +vt 0.757705 0.778508 +vt 0.052909 0.060481 +vt 0.046097 0.067609 +vt 0.046605 0.068547 +vt 0.053895 0.060761 +vt 0.036447 0.067852 +vt 0.036052 0.068866 +vt 0.029617 0.061031 +vt 0.028528 0.061327 +vt 0.029582 0.051226 +vt 0.028531 0.050586 +vt 0.036099 0.044063 +vt 0.035676 0.042896 +vt 0.046147 0.043012 +vt 0.046560 0.041820 +vt 0.052947 0.050224 +vt 0.053895 0.049619 +vt 0.888540 0.738420 +vt 0.893333 0.733288 +vt 0.893091 0.732644 +vt 0.887935 0.738118 +vt 0.900102 0.733095 +vt 0.904888 0.737896 +vt 0.905493 0.737594 +vt 0.900349 0.732454 +vt 0.888508 0.745643 +vt 0.887901 0.745915 +vt 0.893270 0.750670 +vt 0.893004 0.751313 +vt 0.900190 0.750096 +vt 0.900513 0.750593 +vt 0.904884 0.744899 +vt 0.905493 0.745096 +vt 0.957387 0.002595 +vt 0.954813 0.002372 +vt 0.996442 0.958333 +vt 0.999015 0.958170 +vt 0.996815 0.232999 +vt 0.996908 0.243540 +vt 0.999473 0.243520 +vt 0.999376 0.232863 +vt 0.927009 0.641502 +vt 0.927009 0.634577 +vt 0.924435 0.634713 +vt 0.924432 0.641656 +vt 0.777253 0.023506 +vt 0.774694 0.023350 +vt 0.850773 0.072427 +vt 0.853072 0.079023 +vt 0.853330 0.072377 +vt 0.952136 0.002544 +vt 0.952010 0.007944 +vt 0.954576 0.007829 +vt 0.954707 0.002359 +vt 0.949389 0.014821 +vt 0.951956 0.014844 +vt 0.996911 0.225238 +vt 0.999473 0.225053 +vt 0.926304 0.418079 +vt 0.926304 0.410783 +vt 0.923744 0.410709 +vt 0.923744 0.418029 +vt 0.952141 0.014840 +vt 0.954707 0.014848 +vt 0.754282 0.015017 +vt 0.754083 0.009512 +vt 0.751513 0.009296 +vt 0.751722 0.014841 +vt 0.730464 0.107939 +vt 0.730464 0.097244 +vt 0.727903 0.097138 +vt 0.727903 0.107866 +vt 0.754282 0.002087 +vt 0.751709 0.001851 +vt 0.992826 0.575112 +vt 0.984491 0.573840 +vt 0.013351 0.023799 +vt 0.023837 0.024039 +vt 0.023907 0.016023 +vt 0.013089 0.016409 +vn -0.3485 -0.1187 -0.9297 +vn -0.5061 0.1065 -0.8559 +vn -0.8879 -0.3009 -0.3479 +vn -0.3487 -0.1188 -0.9297 +vn -0.8880 -0.3009 -0.3478 +vn -0.4149 0.8971 0.1522 +vn -0.4136 0.9003 0.1359 +vn -0.4119 0.8983 0.1527 +vn 0.1476 -0.9866 -0.0703 +vn -0.4599 -0.1247 0.8792 +vn -0.3708 -0.3639 0.8545 +vn -0.8956 -0.3144 0.3146 +vn -0.3988 0.9032 0.1586 +vn -0.3988 0.9032 0.1587 +vn -0.3489 0.9300 0.1158 +vn 0.3052 -0.9430 -0.1325 +vn 0.3052 -0.9430 -0.1324 +vn 0.0187 -0.1835 0.9828 +vn -0.6649 -0.3689 0.6495 +vn -0.6844 -0.3714 0.6274 +vn -0.0154 -0.1960 0.9805 +vn -0.6648 -0.3689 0.6495 +vn -0.9432 -0.3274 -0.0563 +vn -0.9432 -0.3274 -0.0565 +vn -0.6784 -0.1033 -0.7274 +vn -0.6970 -0.1135 -0.7081 +vn -0.0065 0.1947 -0.9808 +vn -0.0403 0.1821 -0.9824 +vn 0.6552 0.3893 -0.6474 +vn 0.6406 0.3865 -0.6635 +vn -0.0403 0.1821 -0.9825 +vn 0.6550 0.3899 -0.6473 +vn 0.9304 0.3613 0.0624 +vn 0.9304 0.3616 0.0604 +vn 0.6406 0.3866 -0.6635 +vn 0.6706 0.1216 0.7318 +vn 0.6578 0.1138 0.7445 +vn -0.0155 -0.1960 0.9805 +vn 0.4839 -0.8299 -0.2777 +vn 0.4410 -0.8905 -0.1122 +vn 0.5355 -0.8134 -0.2272 +vn 0.6205 -0.7374 -0.2671 +vn -0.4080 0.8920 0.1947 +vn -0.4093 0.8959 0.1725 +vn 0.0751 0.9795 0.1868 +vn -0.0581 0.9889 -0.1370 +vn 0.5598 -0.7625 -0.3244 +vn 0.4094 -0.8981 -0.1607 +vn 0.2638 -0.9490 -0.1725 +vn 0.4471 -0.7833 -0.4319 +vn 0.5686 -0.8217 0.0388 +vn 0.4408 -0.8976 0.0065 +vn 0.4293 -0.8889 0.1600 +vn 0.4539 -0.8819 0.1272 +vn 0.4761 -0.8734 0.1023 +vn 0.5384 -0.8387 0.0822 +vn 0.3555 -0.9245 -0.1374 +vn 0.4766 -0.8536 -0.2104 +vn -0.3489 0.9245 0.1536 +vn -0.3921 0.8674 0.3064 +vn -0.2427 0.9205 0.3061 +vn -0.2518 0.9670 0.0397 +vn 0.9418 0.3332 0.0445 +vn 0.8429 0.5294 0.0962 +vn 0.6054 0.2835 0.7437 +vn 0.7112 0.0285 0.7024 +vn -0.2697 0.9223 0.2770 +vn -0.1651 0.9078 0.3856 +vn -0.5269 0.8499 -0.0006 +vn -0.6442 0.7648 -0.0092 +vn -0.7538 0.6523 0.0794 +vn -0.5259 0.8354 0.1596 +vn -0.6006 0.7671 0.2254 +vn -0.5960 0.8000 0.0694 +vn 0.6213 0.2991 -0.7242 +vn 0.5141 0.5453 -0.6621 +vn 0.8289 0.5477 0.1135 +vn 0.9621 0.2715 0.0235 +vn 0.3880 -0.9080 -0.1577 +vn 0.3947 -0.9055 -0.1558 +vn 0.3456 -0.7426 -0.5737 +vn 0.6404 -0.6573 -0.3973 +vn -0.0092 -0.2726 0.9621 +vn -0.1101 -0.0402 0.9931 +vn -0.7231 -0.2952 0.6244 +vn -0.5700 -0.5430 0.6166 +vn 0.6008 -0.7977 -0.0525 +vn 0.3067 -0.9483 -0.0819 +vn -0.4119 0.8984 0.1525 +vn -0.4136 0.9002 0.1359 +vn -0.3589 0.7231 0.5902 +vn -0.0542 0.8683 0.4931 +vn 0.6970 0.2825 -0.6591 +vn 0.6491 0.4026 -0.6455 +vn 0.9367 0.3447 0.0615 +vn 0.9726 0.2310 0.0256 +vn -0.4029 0.9054 0.1337 +vn -0.6425 0.6247 0.4438 +vn 0.6481 0.3283 -0.6872 +vn 0.5476 0.5567 -0.6246 +vn 0.8430 0.5293 0.0962 +vn 0.9419 0.3330 0.0445 +vn -0.3925 0.9028 0.1760 +vn -0.7796 0.6121 0.1323 +vn 0.5945 -0.6930 -0.4077 +vn 0.4197 -0.8776 -0.2318 +vn 0.2798 -0.9294 -0.2408 +vn 0.4782 -0.7188 -0.5045 +vn -0.4019 0.8896 0.2170 +vn -0.6579 0.7338 -0.1697 +vn -0.0101 -0.2484 0.9686 +vn -0.0690 -0.1066 0.9919 +vn -0.7175 -0.3094 0.6241 +vn -0.6727 -0.4169 0.6113 +vn -0.4097 0.8869 0.2134 +vn -0.3678 0.8872 -0.2787 +vn 0.3914 -0.9051 -0.1664 +vn 0.0422 -0.8776 -0.4775 +vn 0.7267 0.1359 -0.6734 +vn 0.6261 0.4189 -0.6577 +vn 0.9176 0.3900 0.0766 +vn 0.9971 0.0756 -0.0006 +vn -0.9305 -0.3597 -0.0690 +vn -0.9658 -0.2524 -0.0590 +vn -0.7098 -0.0462 -0.7029 +vn -0.6754 -0.1258 -0.7267 +vn 0.3891 -0.9040 -0.1772 +vn -0.0756 -0.9791 -0.1890 +vn 0.0507 -0.3416 0.9385 +vn -0.1051 -0.1045 0.9890 +vn -0.7033 -0.3670 0.6089 +vn -0.5710 -0.5535 0.6063 +vn -0.4742 0.8319 0.2883 +vn -0.3206 0.8968 0.3049 +vn -0.2158 0.8823 0.4184 +vn -0.3357 0.8952 0.2931 +vn 0.4096 -0.9042 -0.1214 +vn 0.0773 -0.9838 0.1619 +vn 0.5339 -0.7903 -0.3006 +vn 0.3548 -0.9257 -0.1312 +vn 0.0060 0.1148 -0.9934 +vn -0.0912 0.3347 -0.9379 +vn 0.4758 -0.8795 -0.0110 +vn 0.4062 -0.8325 0.3768 +vn -0.5727 0.8196 -0.0147 +vn -0.4160 0.8948 0.1622 +vn -0.5614 0.8148 0.1446 +vn -0.6716 0.7359 0.0856 +vn 0.3175 -0.9331 -0.1689 +vn 0.5880 -0.7651 -0.2625 +vn 0.5881 -0.6964 -0.4112 +vn 0.4114 -0.8699 -0.2720 +vn 0.4975 -0.8674 0.0096 +vn 0.6819 -0.6753 0.2811 +vn 0.3337 -0.8910 -0.3079 +vn 0.4390 -0.8798 -0.1823 +vn 0.4289 -0.8989 -0.0891 +vn 0.7427 -0.6675 -0.0527 +vn 0.3751 -0.8356 -0.4012 +vn 0.3793 -0.9165 -0.1274 +vn 0.9621 0.2715 0.0234 +vn 0.8289 0.5477 0.1134 +vn 0.5871 0.2201 0.7790 +vn 0.6916 -0.0330 0.7215 +vn 0.5664 -0.7805 -0.2647 +vn 0.5498 -0.7258 -0.4135 +vn -0.4442 0.8668 0.2267 +vn -0.5934 0.7775 0.2083 +vn 0.2884 -0.9223 -0.2573 +vn 0.4247 -0.8528 -0.3038 +vn 0.5646 -0.7717 -0.2927 +vn 0.3921 -0.9100 -0.1348 +vn -0.9581 -0.2787 -0.0664 +vn -0.8341 -0.5374 -0.1245 +vn 0.4761 -0.8735 0.1022 +vn 0.2369 -0.9704 0.0465 +vn 0.0774 -0.9838 0.1619 +vn 0.4062 -0.8325 0.3767 +vn 0.2369 -0.9704 0.0466 +vn 0.0922 -0.9773 -0.1909 +vn 0.1718 -0.9122 -0.3721 +vn 0.0423 -0.8776 -0.4774 +vn 0.1718 -0.9121 -0.3721 +vn -0.1491 0.4995 -0.8534 +vn 0.4508 0.7066 -0.5454 +vn 0.3516 0.8131 -0.4639 +vn -0.2086 0.6065 -0.7672 +vn 0.6393 0.0958 0.7630 +vn 0.9405 0.3374 0.0408 +vn 0.9404 0.3379 0.0381 +vn 0.6631 0.1082 0.7407 +vn 0.0256 -0.1720 0.9848 +vn -0.6149 -0.3677 0.6977 +vn -0.6376 -0.3714 0.6749 +vn 0.0057 -0.1800 0.9836 +vn -0.9994 -0.0286 0.0212 +vn -0.7414 0.2048 -0.6390 +vn -0.7588 0.3392 -0.5561 +vn -0.9849 0.1629 0.0593 +vn 0.6375 0.1537 0.7549 +vn 0.6425 0.1573 0.7500 +vn 0.6151 0.3668 -0.6979 +vn 0.6371 0.3700 -0.6762 +vn 0.6224 0.4264 -0.6563 +vn 0.9019 0.4250 0.0770 +vn 0.9019 0.4255 0.0745 +vn 0.6280 0.4280 -0.6500 +vn -0.7143 -0.0383 0.6988 +vn -0.7335 0.1157 0.6697 +vn -0.6287 -0.1076 -0.7702 +vn 0.0849 0.1627 -0.9830 +vn -0.1002 0.1119 -0.9887 +vn -0.7298 -0.1704 -0.6620 +vn -0.6021 -0.1233 -0.7889 +vn -0.0166 0.1808 -0.9834 +vn -0.1347 0.1309 -0.9822 +vn -0.7087 -0.2019 -0.6760 +vn -0.6071 -0.0808 -0.7905 +vn -0.0036 0.2346 -0.9721 +vn -0.1161 0.1827 -0.9763 +vn -0.6992 -0.1401 -0.7010 +vn -0.9206 -0.3896 -0.0280 +vn -0.9219 -0.3696 -0.1164 +vn -0.8996 -0.4230 -0.1084 +vn -0.8996 -0.4292 -0.0805 +vn -0.9305 -0.3581 -0.0773 +vn -0.6071 -0.0807 -0.7905 +vn -0.6993 -0.1401 -0.7010 +vn -0.9303 -0.3561 -0.0880 +vn -0.6154 -0.4170 0.6689 +vn -0.9205 -0.3896 -0.0280 +vn -0.7074 -0.4323 0.5592 +vn -0.6162 -0.4313 0.6590 +vn -0.7186 -0.4598 0.5218 +vn -0.6152 -0.3561 0.7034 +vn -0.9303 -0.3561 -0.0879 +vn -0.7267 -0.3828 0.5704 +vn 0.0558 -0.2261 0.9725 +vn -0.0424 -0.2604 0.9646 +vn 0.0269 -0.2044 0.9785 +vn -0.0748 -0.2445 0.9668 +vn 0.0203 -0.1497 0.9885 +vn -0.0664 -0.1816 0.9811 +vn 0.7212 0.0152 0.6925 +vn 0.0559 -0.2261 0.9725 +vn 0.6980 0.0066 0.7161 +vn 0.6636 0.0691 0.7449 +vn 0.6432 0.0595 0.7634 +vn 0.6337 0.1543 0.7580 +vn 0.6089 0.1383 0.7811 +vn 0.9841 0.1775 0.0093 +vn 0.9842 0.1731 0.0383 +vn 0.9475 0.3198 -0.0072 +vn 0.9506 0.3006 0.0777 +vn 0.8973 0.4391 0.0443 +vn 0.6337 0.1544 0.7580 +vn 0.8990 0.4272 0.0966 +vn 0.6868 0.2411 -0.6857 +vn 0.6813 0.2411 -0.6911 +vn 0.5958 0.3581 -0.7189 +vn 0.5907 0.3573 -0.7235 +vn 0.5999 0.4568 -0.6569 +vn 0.8973 0.4392 0.0443 +vn 0.8989 0.4273 0.0966 +vn 0.5489 0.4431 -0.7087 +vn -0.0167 0.1808 -0.9834 +vn -0.1348 0.1309 -0.9822 +vn 0.6628 0.1637 0.7307 +vn 0.7160 0.0467 0.6966 +vn 0.6217 -0.7785 0.0857 +vn 0.4716 -0.8791 0.0693 +vn 0.4671 -0.8557 0.2226 +vn 0.5087 -0.8471 0.1539 +vn -0.7099 -0.0461 -0.7028 +vn -0.1249 0.2721 -0.9541 +vn -0.0158 0.1444 -0.9894 +vn 0.3794 -0.9030 -0.2017 +vn 0.5616 -0.7635 -0.3188 +vn 0.5419 -0.6982 -0.4678 +vn 0.4696 -0.8232 -0.3190 +vn -0.9658 -0.2523 -0.0590 +vn 0.6248 -0.7434 -0.2388 +vn 0.5184 -0.7847 -0.3397 +vn -0.6216 0.7052 0.3410 +vn -0.7276 0.6527 0.2113 +vn -0.5677 -0.2476 -0.7851 +vn -0.7107 -0.0285 -0.7029 +vn -0.1611 0.3160 -0.9350 +vn -0.0384 0.1049 -0.9937 +vn -0.1855 0.9825 -0.0160 +vn -0.0963 0.9775 0.1878 +vn -0.2401 0.9529 0.1854 +vn -0.2937 0.9517 0.0898 +vn 0.3423 -0.9168 -0.2056 +vn 0.3395 -0.9199 -0.1964 +vn 0.4729 -0.8613 -0.1855 +vn 0.4392 -0.8937 -0.0916 +vn -0.3404 0.9167 0.2095 +vn -0.5271 0.8389 0.1358 +vn -0.5171 0.8067 0.2860 +vn -0.2329 0.9205 0.3136 +vn 0.5645 -0.8253 0.0167 +vn 0.5075 -0.8537 -0.1165 +vn 0.4980 -0.8662 0.0406 +vn 0.4496 -0.8866 0.1088 +vn -0.4047 0.9141 0.0252 +vn -0.6208 0.7625 0.1824 +vn -0.7252 0.6845 0.0748 +vn -0.5527 0.8333 0.0118 +vn -0.8799 -0.4666 -0.0897 +vn -0.9825 -0.1850 -0.0233 +vn -0.7057 0.0369 -0.7075 +vn -0.5757 -0.2137 -0.7893 +vn -0.6332 0.7409 0.2238 +vn -0.3174 0.9331 0.1689 +vn -0.2135 0.9746 0.0671 +vn -0.6139 0.7854 0.0797 +vn -0.5824 0.8124 -0.0272 +vn -0.3926 0.9131 -0.1101 +vn -0.4031 0.9134 0.0573 +vn -0.4891 0.8664 0.1003 +vn -0.5788 0.8155 0.0046 +vn -0.6780 0.7275 0.1053 +vn -0.3852 0.8083 0.4453 +vn -0.5720 0.7487 0.3350 +vn -0.4800 0.8464 0.2309 +vn -0.3977 0.8690 0.2944 +vn 0.4024 0.0144 0.9154 +vn 0.4089 0.0183 0.9124 +vn -0.1742 0.9052 0.3875 +vn -0.2852 0.9164 0.2809 +vn -0.3360 0.9210 0.1969 +vn -0.1892 0.9608 0.2026 +vn -0.4602 0.8878 0.0094 +vn -0.4558 0.8739 0.1688 +vn -0.5783 0.7742 0.2571 +vn -0.4392 0.8910 0.1149 +vn -0.3427 0.9394 0.0053 +vn -0.5763 0.8108 0.1026 +vn -0.3708 -0.3638 0.8545 +vn -0.4599 -0.1246 0.8792 +vn -0.6970 -0.2062 0.6868 +vn -0.5843 -0.4719 0.6602 +vn 0.4552 -0.8737 -0.1713 +vn -0.6256 0.7649 0.1537 +vn -0.5127 0.8425 0.1655 +vn 0.3953 -0.9184 -0.0171 +vn 0.2519 -0.9672 -0.0318 +vn 0.7260 -0.1022 0.6800 +vn 0.6436 0.1367 0.7531 +vn -0.1050 -0.1045 0.9890 +vn -0.8799 -0.4666 -0.0896 +vn 0.6491 0.4026 -0.6454 +vn 0.3795 -0.9075 -0.1800 +vn -0.0385 0.1049 -0.9937 +vn -0.9581 -0.2787 -0.0663 +vn 0.6917 -0.0330 0.7215 +vn 0.5871 0.2200 0.7790 +vn -0.8467 -0.5251 -0.0860 +vn -0.9458 -0.3186 -0.0631 +vn -0.7079 -0.0729 -0.7026 +vn -0.5464 -0.2773 -0.7903 +vn -0.5756 -0.2137 -0.7893 +vn -0.7057 0.0369 -0.7076 +vn -0.5565 0.7704 0.3110 +vn -0.6549 0.7325 0.1861 +vn 0.3816 -0.9106 -0.1587 +vn -0.9457 -0.3187 -0.0632 +vn -0.8467 -0.5250 -0.0860 +vn 0.3624 0.7454 -0.5595 +vn 0.6476 0.7397 0.1831 +vn 0.6475 0.7397 0.1830 +vn 0.3625 0.7454 -0.5595 +vn 0.0235 0.9670 -0.2536 +vn 0.1671 0.9465 0.2760 +vn 0.5295 0.8221 0.2094 +vn 0.3966 0.4897 0.7764 +vn 0.0483 0.9586 0.2807 +vn 0.0715 0.7654 0.6395 +vn 0.0714 0.7654 0.6395 +vn 0.0484 0.9586 0.2807 +vn -0.1101 -0.0403 0.9931 +vn -0.2681 0.3432 0.9002 +vn -0.2680 0.3433 0.9002 +vn 0.3967 0.4897 0.7764 +vn -0.4108 0.7248 0.5531 +vn 0.1379 -0.5155 0.8457 +vn 0.7303 -0.4101 0.5463 +vn 0.3564 -0.7510 0.5559 +vn 0.6060 -0.7718 0.1928 +vn 0.6060 -0.7717 0.1928 +vn 0.3563 -0.7510 0.5559 +vn -0.3035 -0.7648 0.5683 +vn 0.1481 -0.5157 0.8439 +vn 0.1266 -0.9294 0.3467 +vn 0.3345 -0.7857 0.5204 +vn 0.3344 -0.7857 0.5204 +vn 0.1266 -0.9294 0.3468 +vn -0.2621 0.2542 0.9310 +vn -0.8317 0.0241 0.5547 +vn -0.4452 0.6335 0.6329 +vn -0.8238 0.4517 0.3425 +vn -0.4452 0.6335 0.6328 +vn -0.7032 -0.3671 0.6088 +vn -0.8409 -0.0713 0.5365 +vn -0.9999 -0.0009 0.0129 +vn -0.9999 -0.0010 0.0128 +vn -0.8409 -0.0712 0.5365 +vn -0.8829 0.3482 0.3150 +vn -0.8779 0.4607 0.1304 +vn -0.5916 -0.8012 -0.0903 +vn -0.2997 -0.7969 0.5246 +vn -0.2996 -0.7969 0.5245 +vn -0.5917 -0.8011 -0.0903 +vn -0.1336 -0.9887 -0.0679 +vn 0.1247 -0.9390 0.3204 +vn -0.2710 -0.5058 -0.8190 +vn -0.5528 -0.8100 -0.1956 +vn 0.1582 -0.6954 -0.7010 +vn -0.0966 -0.9656 -0.2415 +vn 0.1581 -0.6954 -0.7010 +vn -0.8119 0.2631 -0.5211 +vn -0.3449 0.5967 -0.7246 +vn -0.8050 0.5736 -0.1516 +vn -0.5186 0.8026 -0.2948 +vn -0.5186 0.8025 -0.2949 +vn -0.8050 0.5735 -0.1518 +vn -0.1250 0.2721 -0.9541 +vn -0.8191 0.1989 -0.5381 +vn -0.3501 0.5694 -0.7438 +vn -0.8440 0.4910 -0.2158 +vn -0.5399 0.7846 -0.3047 +vn -0.5399 0.7847 -0.3047 +vn -0.8440 0.4911 -0.2156 +vn -0.9832 0.1749 0.0520 +vn -0.7568 0.3701 -0.5388 +vn -0.7938 0.5948 0.1266 +vn -0.6704 0.7129 -0.2055 +vn 0.5931 0.7907 0.1515 +vn 0.3672 0.5761 0.7302 +vn 0.1438 0.9715 0.1886 +vn 0.0054 0.8470 0.5315 +vn 0.0052 0.8471 0.5315 +vn 0.1438 0.9715 0.1885 +vn 0.5477 0.5567 -0.6246 +vn 0.3416 0.8177 -0.4633 +vn 0.5931 0.7907 0.1514 +vn 0.3416 0.8178 -0.4632 +vn -0.0112 0.9851 -0.1718 +vn -0.1932 0.3173 0.9284 +vn -0.7352 0.1599 0.6587 +vn -0.1932 0.3174 0.9284 +vn -0.3371 0.6909 0.6395 +vn -0.6532 0.5940 0.4695 +vn -0.5465 -0.2772 -0.7902 +vn -0.3486 -0.1187 -0.9297 +vn 0.2202 -0.2152 -0.9514 +vn -0.2333 -0.5782 -0.7819 +vn 0.4726 -0.5135 -0.7162 +vn 0.2085 -0.7869 -0.5808 +vn 0.4727 -0.5135 -0.7162 +vn -0.5062 0.1065 -0.8558 +vn -0.8406 0.1835 -0.5096 +vn -0.3621 0.5398 -0.7599 +vn -0.8653 0.4841 -0.1300 +vn -0.5408 0.7734 -0.3308 +vn -0.5408 0.7733 -0.3309 +vn -0.8653 0.4840 -0.1302 +vn 0.1918 -0.1788 -0.9650 +vn -0.2920 -0.5075 -0.8107 +vn 0.4287 -0.5266 -0.7341 +vn 0.1275 -0.7406 -0.6597 +vn 0.1277 -0.7407 -0.6596 +vn -0.9955 0.0879 -0.0355 +vn -0.8407 0.5414 -0.0087 +vn -0.8408 0.5414 -0.0087 +vn -0.2921 -0.5075 -0.8106 +vn -0.6078 -0.7792 -0.1533 +vn -0.1352 -0.9736 -0.1836 +vn -0.1352 -0.9737 -0.1837 +vn -0.9970 0.0773 0.0002 +vn -0.8470 0.5245 0.0864 +vn -0.8470 0.5245 0.0863 +vn -0.2531 -0.8028 0.5398 +vn -0.2530 -0.8028 0.5399 +vn 0.1904 -0.9198 0.3431 +vn -0.7231 -0.2953 0.6244 +vn -0.8246 0.0450 0.5640 +vn -0.8246 0.0453 0.5640 +vn -0.8191 0.4649 0.3361 +vn 0.2106 -0.5945 0.7760 +vn 0.4034 -0.8161 0.4139 +vn 0.4034 -0.8161 0.4138 +vn -0.3150 0.2849 0.9053 +vn -0.9006 0.2925 0.3215 +vn 0.7477 -0.4245 0.5106 +vn 0.7477 -0.4246 0.5105 +vn 0.2106 -0.5946 0.7759 +vn 0.6314 -0.7494 0.1993 +vn 0.4613 0.5037 0.7304 +vn -0.2621 0.2542 0.9309 +vn 0.4612 0.5037 0.7304 +vn 0.0820 0.8286 0.5538 +vn 0.7112 0.0286 0.7024 +vn 0.7624 -0.3573 0.5396 +vn 0.7623 -0.3573 0.5396 +vn 0.1481 -0.5158 0.8438 +vn 0.6583 -0.7359 0.1586 +vn 0.7303 -0.4101 0.5464 +vn 0.9921 -0.0869 -0.0900 +vn 0.9922 -0.0869 -0.0899 +vn 0.7303 -0.4102 0.5463 +vn 0.8367 -0.5014 -0.2203 +vn 0.7623 -0.3574 0.5396 +vn 0.9984 0.0210 -0.0531 +vn 0.6583 -0.7359 0.1585 +vn 0.8836 -0.4281 -0.1896 +vn 0.8837 -0.4280 -0.1895 +vn 0.9922 -0.0870 -0.0899 +vn 0.6829 -0.0732 -0.7269 +vn 0.6829 -0.0731 -0.7268 +vn 0.6300 -0.5324 -0.5654 +vn 0.7211 0.6812 0.1266 +vn 0.2374 0.9526 0.1905 +vn 0.0821 0.8286 0.5538 +vn 0.6475 0.7397 0.1831 +vn 0.4528 0.4555 0.7665 +vn 0.1258 0.7771 0.6167 +vn 0.1259 0.7771 0.6167 +vn 0.4539 0.7258 -0.5169 +vn 0.0900 0.9736 -0.2100 +vn 0.7268 0.1358 -0.6733 +vn 0.9610 -0.2690 -0.0644 +vn 0.7104 -0.2267 -0.6663 +vn 0.7103 -0.2268 -0.6663 +vn 0.9609 -0.2692 -0.0644 +vn 0.7515 -0.6444 -0.1412 +vn 0.5958 -0.6329 -0.4944 +vn -0.3149 0.2850 0.9053 +vn -0.3150 0.2850 0.9053 +vn 0.4529 0.4555 0.7664 +vn 0.0914 0.8142 0.5733 +vn -0.8245 0.0450 0.5641 +vn -0.3034 -0.7649 0.5683 +vn -0.8317 0.0240 0.5547 +vn -0.9955 0.0881 -0.0355 +vn -0.8316 0.0241 0.5548 +vn -0.8780 0.4607 0.1303 +vn -0.5916 -0.8012 -0.0904 +vn -0.1335 -0.9887 -0.0680 +vn -0.5678 -0.2476 -0.7851 +vn 0.1430 -0.1711 -0.9748 +vn 0.3996 -0.4972 -0.7702 +vn 0.3997 -0.4973 -0.7700 +vn -0.7568 0.3701 -0.5389 +vn -0.2211 0.6342 -0.7409 +vn -0.2211 0.6343 -0.7408 +vn -0.3552 0.8748 -0.3294 +vn -0.3552 0.8748 -0.3293 +vn -0.0113 0.9851 -0.1718 +vn 0.6480 0.3283 -0.6872 +vn 0.7381 -0.0403 -0.6735 +vn 0.7381 -0.0406 -0.6735 +vn 0.9984 0.0208 -0.0531 +vn 0.7023 -0.5203 -0.4858 +vn 0.2890 0.8017 -0.5233 +vn 0.5295 0.8220 0.2095 +vn 0.2889 0.8017 -0.5233 +vn -0.0646 0.9648 -0.2550 +vn 0.7103 -0.2267 -0.6664 +vn 0.2202 -0.2151 -0.9514 +vn -0.3500 0.5694 -0.7438 +vn 0.0900 0.9736 -0.2099 +vn 0.6300 -0.5323 -0.5655 +vn -0.5062 0.1064 -0.8558 +vn -0.3621 0.5398 -0.7600 +vn 0.7381 -0.0404 -0.6735 +vn 0.7024 -0.5204 -0.4857 +vn -0.3449 0.5967 -0.7245 +vn -0.5187 0.8025 -0.2948 +vn -0.0646 0.9648 -0.2549 +vn -0.9016 -0.4256 -0.0774 +vn -0.6231 -0.4278 0.6548 +vn -0.6300 -0.4300 0.6467 +vn -0.9011 -0.4272 -0.0748 +vn -0.0149 0.1758 -0.9843 +vn -0.0036 0.1805 -0.9836 +vn -0.0243 0.1724 -0.9847 +vn -0.6371 -0.1547 -0.7551 +vn -0.6435 -0.1593 -0.7486 +vn -0.0062 0.1798 -0.9837 +vn -0.1271 0.1531 0.9800 +vn -0.1804 0.2885 0.9403 +vn 0.6110 0.3669 -0.7015 +vn 0.6341 0.3702 -0.6789 +vn -0.6317 -0.1588 -0.7588 +vn -0.6420 -0.1664 -0.7484 +vn 0.9390 0.3414 0.0416 +vn 0.9390 0.3418 0.0392 +vn 0.4627 0.4544 0.7612 +vn -0.1271 0.1530 0.9800 +vn 0.3701 0.5747 0.7299 +vn -0.4142 0.8906 0.1878 +vn -0.4093 0.8958 0.1733 +vn -0.4128 0.8942 0.1730 +vn -0.4145 0.8899 0.1905 +vn -0.4177 0.8946 0.1588 +vn -0.4220 0.8962 0.1368 +vn -0.4197 0.8973 0.1366 +vn -0.4176 0.8951 0.1562 +vn -0.4070 0.9034 0.1349 +vn -0.4042 0.9048 0.1339 +vn -0.3954 0.9015 0.1762 +vn -0.3902 0.9036 0.1766 +vn -0.4064 0.8878 0.2159 +vn -0.4028 0.8893 0.2166 +vn -0.4187 0.8833 0.2111 +vn -0.4164 0.8843 0.2113 +vn -0.3678 0.8871 -0.2788 +vn -0.0582 0.9889 -0.1369 +vn -0.2932 0.7637 -0.5751 +vn 0.1760 0.9229 -0.3426 +vn -0.1854 0.9825 -0.0161 +vn -0.3925 0.9131 -0.1101 +vn 0.7091 0.6931 0.1292 +vn 0.4507 0.7066 -0.5455 +vn 0.1760 0.9229 -0.3425 +vn 0.3803 0.9089 0.1711 +vn 0.7091 0.6932 0.1291 +vn 0.1897 0.7307 0.6558 +vn -0.1743 0.9052 0.3876 +vn -0.0962 0.9775 0.1878 +vn 0.4626 0.4544 0.7612 +vn 0.1896 0.7307 0.6558 +vn -0.2768 0.5022 0.8193 +vn -0.7143 -0.0382 0.6988 +vn -0.7245 0.3501 0.5937 +vn -0.9270 0.3647 0.0876 +vn -0.7796 0.6122 0.1323 +vn -0.9270 0.3646 0.0877 +vn -0.7429 0.5312 -0.4074 +vn -0.1491 0.4996 -0.8533 +vn -0.7414 0.2048 -0.6391 +vn -0.2932 0.7637 -0.5752 +vn -0.4115 0.8862 0.2129 +vn -0.4116 0.8903 0.1950 +vn -0.4139 0.8938 0.1725 +vn -0.4149 0.8970 0.1522 +vn -0.4002 0.8901 0.2182 +vn -0.3877 0.9047 0.1766 +vn -0.4016 0.9062 0.1325 +vn -0.4152 0.8995 0.1359 +vn -0.4150 0.8933 0.1728 +vn -0.4147 0.8894 0.1924 +vn -0.4183 0.8980 0.1364 +vn -0.4177 0.8954 0.1545 +vn -0.4018 0.9059 0.1336 +vn -0.3873 0.9049 0.1767 +vn -0.4006 0.8902 0.2171 +vn -0.4150 0.8849 0.2116 +vn 0.0566 0.9652 -0.2553 +vn -0.3402 0.8258 -0.4498 +vn 0.5821 0.7981 0.1554 +vn 0.2420 0.9552 0.1705 +vn 0.0794 0.7989 0.5962 +vn -0.1804 0.2884 0.9404 +vn -0.3386 0.6014 0.7237 +vn -0.7100 0.4788 0.5164 +vn -0.9849 0.1629 0.0592 +vn -0.8603 0.4980 0.1088 +vn -0.7248 0.6247 -0.2904 +vn -0.4121 0.8857 0.2140 +vn -0.4022 0.8959 0.1886 +vn -0.4014 0.8965 0.1876 +vn -0.4120 0.8861 0.2126 +vn -0.3947 0.9023 0.1732 +vn -0.4074 0.8994 0.1585 +vn -0.4064 0.8997 0.1595 +vn -0.3946 0.9024 0.1733 +vn -0.4125 0.8856 0.2137 +vn -0.4124 0.8858 0.2129 +vn -0.4122 0.8942 0.1747 +vn -0.4122 0.8940 0.1757 +vn -0.4137 0.8999 0.1380 +vn -0.4140 0.9000 0.1361 +vn -0.4164 0.8990 0.1358 +vn -0.4165 0.8988 0.1365 +vn -0.9388 -0.3412 -0.0474 +vn -0.9388 -0.3416 -0.0449 +vn -0.7587 0.3392 -0.5561 +vn -0.6142 -0.4338 0.6592 +vn 0.0111 -0.1965 0.9804 +vn 0.0204 -0.1925 0.9811 +vn -0.6255 -0.4374 0.6461 +vn -0.9388 -0.3411 -0.0474 +vn -0.6382 -0.0970 -0.7637 +vn -0.6622 -0.1098 -0.7413 +vn 0.4508 0.7066 -0.5455 +vn 0.5821 0.7981 0.1553 +vn -0.6382 -0.0969 -0.7637 +vn -0.0028 0.1978 -0.9802 +vn -0.0216 0.1900 -0.9815 +vn -0.6621 -0.1098 -0.7413 +vn 0.0023 -0.1985 0.9801 +vn 0.0192 -0.1914 0.9813 +vn -0.8965 -0.4360 -0.0785 +vn -0.8960 -0.4377 -0.0750 +vn -0.9011 -0.4266 -0.0776 +vn -0.6435 -0.1593 -0.7487 +vn 0.6225 0.4264 -0.6563 +vn 0.0022 -0.1985 0.9801 +vn 0.6378 0.0963 0.7641 +vn 0.6623 0.1095 0.7412 +vn 0.0192 -0.1915 0.9813 +vn -0.8960 -0.4370 -0.0787 +vn 0.3384 -0.0231 0.9407 +vn 0.3384 -0.0232 0.9407 +vn 0.2854 0.2336 -0.9295 +vn 0.3776 0.2407 -0.8941 +vn 0.3748 0.2405 -0.8953 +usemtl Scene_-_Root +s off +f 21655/21278/15270 21656/21279/15271 21657/21280/15272 +f 21655/21278/15273 21657/21280/15274 21658/21281/15274 +f 22001/21282/15275 21353/21283/15276 21352/21284/15277 +f 22089/21285/15278 22090/21286/15278 22091/21287/15278 +f 22089/21285/15278 22091/21287/15278 22092/21288/15278 +f 21632/21289/15279 21631/21290/15280 22093/21291/15281 +f 21632/21289/15279 22093/21291/15281 22094/21292/15281 +f 22095/21293/15282 22096/21294/15282 22097/21295/15282 +f 22095/21293/15283 22097/21295/15283 22098/21296/15283 +f 22103/21297/15284 22104/21298/15284 22105/21299/15284 +f 22103/21297/15284 22105/21299/15284 22106/21300/15284 +f 22107/21301/15285 22108/21302/15285 22109/21303/15285 +f 22107/21301/15286 22109/21303/15286 22110/21304/15286 +s 1 +f 21278/21305/15287 21279/21306/15288 21280/21307/15289 +f 21278/21305/15287 21280/21307/15289 21281/21308/15290 +f 21282/21309/15291 21283/21310/15292 21284/21311/15293 +f 21282/21309/15291 21284/21311/15293 21285/21312/15289 +f 21283/21310/15292 21286/21313/15294 21287/21314/15295 +f 21283/21310/15292 21287/21314/15295 21284/21311/15293 +f 21286/21313/15294 21288/21315/15296 21289/21316/15297 +f 21286/21313/15294 21289/21316/15297 21287/21314/15295 +f 21290/21317/15296 21291/21318/15298 21292/21319/15299 +f 21290/21317/15296 21292/21319/15299 21293/21320/15300 +f 21294/21321/15301 21295/21322/15302 21296/21323/15303 +f 21294/21321/15301 21296/21323/15303 21297/21324/15304 +f 21295/21322/15302 21298/21325/15305 21299/21326/15306 +f 21295/21322/15302 21299/21326/15306 21296/21323/15303 +f 21298/21325/15305 21300/21327/15287 21301/21328/15307 +f 21298/21325/15305 21301/21328/15307 21299/21326/15306 +f 21302/21329/15308 21303/21330/15309 21304/21331/15310 +f 21302/21329/15308 21304/21331/15310 21305/21332/15311 +f 21306/21333/15312 21307/21334/15313 21308/21335/15314 +f 21306/21333/15312 21308/21335/15314 21309/21336/15315 +f 21310/21337/15316 21311/21338/15317 21312/21339/15318 +f 21310/21337/15316 21312/21339/15318 21313/21340/15319 +f 21314/21341/15320 21315/21342/15321 21316/21343/15322 +f 21314/21341/15320 21316/21343/15322 21317/21344/15323 +f 21318/21345/15324 21319/21346/15325 21320/21347/15326 +f 21318/21345/15324 21320/21347/15326 21321/21348/15327 +f 21322/21349/15328 21323/21350/15329 21324/21351/15330 +f 21322/21349/15328 21324/21351/15330 21325/21352/15331 +f 21326/21353/15332 21327/21354/15333 21328/21355/15334 +f 21326/21353/15332 21328/21355/15334 21329/21356/15335 +f 21323/21350/15329 21330/21357/15336 21331/21358/15337 +f 21323/21350/15329 21331/21358/15337 21324/21351/15330 +f 21332/21359/15338 21333/21360/15339 21334/21361/15340 +f 21332/21359/15338 21334/21361/15340 21335/21362/15341 +f 21336/21363/15342 21322/21349/15328 21325/21352/15331 +f 21336/21363/15342 21325/21352/15331 21337/21364/15343 +f 21338/21365/15344 21339/21366/15345 21340/21367/15346 +f 21338/21365/15344 21340/21367/15346 21341/21368/15347 +f 21342/21369/15348 21343/21370/15349 21344/21371/15350 +f 21342/21369/15348 21344/21371/15350 21345/21372/15351 +f 21346/21373/15352 21347/21374/15353 21348/21375/15354 +f 21346/21373/15352 21348/21375/15354 21349/21376/15355 +f 21319/21346/15325 21350/21377/15356 21351/21378/15357 +f 21319/21346/15325 21351/21378/15357 21320/21347/15326 +f 21352/21284/15358 21353/21283/15359 21354/21379/15360 +f 21352/21284/15358 21354/21379/15360 21355/21380/15361 +f 21356/21381/15362 21357/21382/15363 21358/21383/15364 +f 21356/21381/15362 21358/21383/15364 21359/21384/15365 +f 21353/21283/15359 21360/21385/15366 21361/21386/15367 +f 21353/21283/15359 21361/21386/15367 21354/21379/15360 +f 21362/21387/15368 21363/21388/15369 21364/21389/15370 +f 21362/21387/15368 21364/21389/15370 21365/21390/15371 +f 21360/21385/15366 21366/21391/15372 21367/21392/15373 +f 21360/21385/15366 21367/21392/15373 21361/21386/15367 +f 21368/21393/15374 21369/21394/15375 21370/21395/15376 +f 21368/21393/15374 21370/21395/15376 21371/21396/15377 +f 21366/21391/15372 21372/21397/15378 21373/21398/15379 +f 21366/21391/15372 21373/21398/15379 21367/21392/15373 +f 21374/21399/15380 21375/21400/15381 21376/21401/15382 +f 21374/21399/15380 21376/21401/15382 21377/21402/15383 +f 21372/21397/15378 21378/21403/15384 21379/21404/15385 +f 21372/21397/15378 21379/21404/15385 21373/21398/15379 +f 21343/21370/15349 21380/21405/15386 21381/21406/15387 +f 21343/21370/15349 21381/21406/15387 21344/21371/15350 +f 21382/21407/15388 21383/21408/15389 21384/21409/15390 +f 21382/21407/15388 21384/21409/15390 21385/21410/15391 +f 21386/21411/15392 21387/21412/15393 21388/21413/15394 +f 21386/21411/15392 21388/21413/15394 21389/21414/15395 +f 21380/21405/15386 21390/21415/15396 21391/21416/15397 +f 21380/21405/15386 21391/21416/15397 21381/21406/15387 +f 21392/21417/15398 21393/21418/15399 21394/21419/15400 +f 21392/21417/15398 21394/21419/15400 21395/21420/15401 +f 21396/21421/15402 21397/21422/15403 21398/21423/15404 +f 21396/21421/15402 21398/21423/15404 21399/21424/15405 +f 21390/21415/15396 21400/21425/15406 21401/21426/15407 +f 21390/21415/15396 21401/21426/15407 21391/21416/15397 +f 21350/21377/15356 21402/21427/15408 21403/21428/15409 +f 21350/21377/15356 21403/21428/15409 21351/21378/15357 +f 21404/21429/15410 21405/21430/15411 21363/21388/15369 +f 21404/21429/15410 21363/21388/15369 21362/21387/15368 +f 21400/21425/15406 21406/21431/15412 21407/21432/15413 +f 21400/21425/15406 21407/21432/15413 21401/21426/15407 +f 21408/21433/15414 21409/21434/15415 21410/21435/15416 +f 21408/21433/15414 21410/21435/15416 21411/21436/15417 +f 21412/21437/15418 21413/21438/15419 21414/21439/15420 +f 21412/21437/15418 21414/21439/15420 21415/21440/15421 +f 21406/21431/15412 21416/21441/15422 21417/21442/15423 +f 21406/21431/15412 21417/21442/15423 21407/21432/15413 +f 21418/21443/15424 21302/21329/15308 21305/21332/15311 +f 21418/21443/15424 21305/21332/15311 21419/21444/15425 +f 21311/21338/15317 21314/21341/15320 21317/21344/15323 +f 21311/21338/15317 21317/21344/15323 21312/21339/15318 +f 21416/21441/15422 21420/21445/15426 21421/21446/15427 +f 21416/21441/15422 21421/21446/15427 21417/21442/15423 +f 21402/21427/15408 21422/21447/15428 21423/21448/15429 +f 21402/21427/15408 21423/21448/15429 21403/21428/15409 +f 21424/21449/15430 21425/21450/15431 21426/21451/15432 +f 21424/21449/15430 21426/21451/15432 21427/21452/15433 +f 21307/21334/15313 21352/21284/15358 21355/21380/15361 +f 21307/21334/15313 21355/21380/15361 21308/21335/15314 +f 21428/21453/15434 21310/21337/15316 21313/21340/15319 +f 21428/21453/15434 21313/21340/15319 21429/21454/15435 +f 21333/21360/15339 21430/21455/15436 21431/21456/15437 +f 21333/21360/15339 21431/21456/15437 21334/21361/15340 +f 21420/21445/15426 21342/21369/15348 21345/21372/15351 +f 21420/21445/15426 21345/21372/15351 21421/21446/15427 +f 21432/21457/15438 21433/21458/15439 21434/21459/15440 +f 21432/21457/15438 21434/21459/15440 21435/21460/15441 +f 21349/21376/15355 21348/21375/15354 21436/21461/15442 +f 21349/21376/15355 21436/21461/15442 21437/21462/15443 +f 21422/21447/15428 21402/21427/15408 21345/21372/15351 +f 21422/21447/15428 21345/21372/15351 21344/21371/15350 +f 21402/21427/15408 21350/21377/15356 21421/21446/15427 +f 21402/21427/15408 21421/21446/15427 21345/21372/15351 +f 21438/21463/15356 21439/21464/15325 21440/21465/15423 +f 21438/21463/15356 21440/21465/15423 21441/21466/15427 +f 21319/21346/15325 21318/21345/15324 21407/21432/15413 +f 21319/21346/15325 21407/21432/15413 21417/21442/15423 +f 21442/21467/15444 21443/21468/15445 21444/21469/15446 +f 21442/21467/15444 21444/21469/15446 21445/21470/15447 +f 21446/21471/15448 21447/21472/15449 21391/21416/15397 +f 21446/21471/15448 21391/21416/15397 21401/21426/15407 +f 21448/21473/15449 21449/21474/15450 21450/21475/15451 +f 21448/21473/15449 21450/21475/15451 21451/21476/15397 +f 21452/21477/15452 21422/21447/15428 21344/21371/15350 +f 21452/21477/15452 21344/21371/15350 21381/21406/15387 +f 21453/21478/15453 21454/21479/15454 21455/21480/15455 +f 21453/21478/15453 21455/21480/15455 21456/21481/15456 +f 21457/21482/15457 21458/21483/15458 21459/21484/15459 +f 21457/21482/15457 21459/21484/15459 21460/21485/15460 +f 21461/21486/15461 21462/21487/15462 21463/21488/15463 +f 21461/21486/15461 21463/21488/15463 21464/21489/15464 +f 21465/21490/15465 21466/21491/15466 21467/21492/15467 +f 21465/21490/15465 21467/21492/15467 21468/21493/15468 +f 21469/21494/15469 21470/21495/15461 21471/21496/15464 +f 21469/21494/15469 21471/21496/15464 21472/21497/15470 +f 21473/21498/15458 21474/21499/15471 21475/21500/15472 +f 21473/21498/15458 21475/21500/15472 21476/21501/15459 +f 21477/21502/15473 21478/21503/15474 21479/21504/15475 +f 21477/21502/15473 21479/21504/15475 21480/21505/15476 +f 21481/21506/15477 21482/21507/15465 21483/21508/15468 +f 21481/21506/15477 21483/21508/15468 21484/21509/15478 +f 21378/21403/15384 21306/21333/15312 21309/21336/15315 +f 21378/21403/15384 21309/21336/15315 21379/21404/15385 +f 21485/21510/15479 21486/21511/15480 21487/21512/15481 +f 21485/21510/15479 21487/21512/15481 21488/21513/15482 +f 21489/21514/15483 21490/21515/15484 21491/21516/15485 +f 21489/21514/15483 21491/21516/15485 21492/21517/15486 +f 21493/21518/15487 21494/21519/15488 21495/21520/15489 +f 21493/21518/15487 21495/21520/15489 21496/21521/15490 +f 21497/21522/15491 21485/21510/15479 21488/21513/15482 +f 21497/21522/15491 21488/21513/15482 21498/21523/15492 +f 21499/21524/15493 21489/21514/15483 21492/21517/15486 +f 21499/21524/15493 21492/21517/15486 21500/21525/15494 +f 21501/21526/15495 21502/21527/15496 21503/21528/15497 +f 21501/21526/15495 21503/21528/15497 21504/21529/15498 +f 21505/21530/15499 21506/21531/15500 21507/21532/15492 +f 21505/21530/15499 21507/21532/15492 21508/21533/15501 +f 21509/21534/15502 21510/21535/15493 21511/21536/15494 +f 21509/21534/15502 21511/21536/15494 21512/21537/15503 +f 21513/21538/15504 21514/21539/15495 21515/21540/15505 +f 21513/21538/15504 21515/21540/15505 21516/21541/15506 +f 21517/21542/15507 21505/21530/15499 21508/21533/15501 +f 21517/21542/15507 21508/21533/15501 21518/21543/15508 +f 21519/21544/15509 21509/21534/15502 21512/21537/15503 +f 21519/21544/15509 21512/21537/15503 21520/21545/15510 +f 21521/21546/15511 21513/21538/15504 21516/21541/15506 +f 21521/21546/15511 21516/21541/15506 21522/21547/15512 +f 21523/21548/15513 21524/21549/15514 21525/21550/15508 +f 21523/21548/15513 21525/21550/15508 21526/21551/15515 +f 21527/21552/15516 21519/21544/15509 21520/21545/15510 +f 21527/21552/15516 21520/21545/15510 21528/21553/15517 +f 21529/21554/15518 21521/21546/15511 21522/21547/15512 +f 21529/21554/15518 21522/21547/15512 21530/21555/15519 +f 21531/21556/15520 21523/21548/15513 21526/21551/15515 +f 21531/21556/15520 21526/21551/15515 21532/21557/15521 +f 21533/21558/15522 21534/21559/15516 21535/21560/15517 +f 21533/21558/15522 21535/21560/15517 21536/21561/15523 +f 21537/21562/15524 21538/21563/15525 21539/21564/15519 +f 21537/21562/15524 21539/21564/15519 21540/21565/15526 +f 21541/21566/15527 21531/21556/15520 21532/21557/15521 +f 21541/21566/15527 21532/21557/15521 21542/21567/15528 +f 21543/21568/15529 21544/21569/15522 21545/21570/15523 +f 21543/21568/15529 21545/21570/15523 21546/21571/15530 +f 21547/21572/15531 21548/21573/15532 21549/21574/15533 +f 21547/21572/15531 21549/21574/15533 21550/21575/15534 +f 21551/21576/15480 21552/21577/15527 21553/21578/15528 +f 21551/21576/15480 21553/21578/15528 21554/21579/15481 +f 21555/21580/15535 21543/21568/15529 21546/21571/15530 +f 21555/21580/15535 21546/21571/15530 21556/21581/15536 +f 21494/21519/15488 21547/21572/15531 21550/21575/15534 +f 21494/21519/15488 21550/21575/15534 21495/21520/15489 +f 21359/21384/15365 21358/21383/15364 21557/21582/15537 +f 21359/21384/15365 21557/21582/15537 21558/21583/15538 +f 21330/21357/15336 21332/21359/15338 21335/21362/15341 +f 21330/21357/15336 21335/21362/15341 21331/21358/15337 +f 21559/21584/15539 21560/21585/15540 21561/21586/15541 +f 21559/21584/15539 21561/21586/15541 21562/21587/15542 +f 21369/21394/15375 21559/21584/15539 21562/21587/15542 +f 21369/21394/15375 21562/21587/15542 21370/21395/15376 +f 21563/21588/15395 21564/21589/15543 21565/21590/15544 +f 21563/21588/15395 21565/21590/15544 21566/21591/15545 +f 21567/21592/15546 21568/21593/15547 21569/21594/15548 +f 21567/21592/15546 21569/21594/15548 21570/21595/15549 +f 21377/21402/15383 21376/21401/15382 21571/21596/15550 +f 21377/21402/15383 21571/21596/15550 21572/21597/15392 +f 21413/21438/15419 21573/21598/15551 21574/21599/15552 +f 21413/21438/15419 21574/21599/15552 21414/21439/15420 +f 21575/21600/15553 21336/21363/15342 21337/21364/15343 +f 21575/21600/15553 21337/21364/15343 21576/21601/15554 +f 21430/21455/15436 21575/21600/15553 21576/21601/15554 +f 21430/21455/15436 21576/21601/15554 21431/21456/15437 +f 21577/21602/15555 21578/21603/15556 21579/21604/15557 +f 21577/21602/15555 21579/21604/15557 21580/21605/15558 +f 21581/21606/15559 21582/21607/15560 21583/21608/15561 +f 21581/21606/15559 21583/21608/15561 21584/21609/15562 +f 21585/21610/15563 21586/21611/15564 21587/21612/15565 +f 21585/21610/15563 21587/21612/15565 21588/21613/15566 +f 21589/21614/15567 21590/21615/15568 21591/21616/15569 +f 21589/21614/15567 21591/21616/15569 21592/21617/15570 +f 21593/21618/15571 21594/21619/15572 21595/21620/15573 +f 21593/21618/15571 21595/21620/15573 21596/21621/15574 +f 21597/21622/15575 21598/21623/15576 21599/21624/15577 +f 21597/21622/15575 21599/21624/15577 21600/21625/15578 +f 21601/21626/15579 21602/21627/15580 21603/21628/15581 +f 21601/21626/15579 21603/21628/15581 21604/21629/15582 +f 21605/21630/15583 21606/21631/15584 21607/21632/15585 +f 21605/21630/15583 21607/21632/15585 21608/21633/15586 +f 21609/21634/15587 21610/21635/15588 21611/21636/15589 +f 21609/21634/15587 21611/21636/15589 21612/21637/15590 +f 21613/21638/15591 21597/21622/15575 21600/21625/15578 +f 21613/21638/15591 21600/21625/15578 21614/21639/15592 +f 21615/21640/15593 21616/21641/15594 21617/21642/15595 +f 21615/21640/15593 21617/21642/15595 21618/21643/15596 +f 21590/21615/15568 21613/21638/15591 21614/21639/15592 +f 21590/21615/15568 21614/21639/15592 21591/21616/15569 +f 21329/21356/15335 21328/21355/15334 21619/21644/15597 +f 21329/21356/15335 21619/21644/15597 21620/21645/15598 +f 21560/21585/15540 21432/21457/15438 21435/21460/15441 +f 21560/21585/15540 21435/21460/15441 21561/21586/15541 +f 21621/21646/15599 21615/21640/15593 21618/21643/15596 +f 21621/21646/15599 21618/21643/15596 21622/21647/15600 +f 21623/21648/15601 21589/21614/15567 21592/21617/15570 +f 21623/21648/15601 21592/21617/15570 21624/21649/15602 +f 21582/21607/15560 21621/21646/15599 21622/21647/15600 +f 21582/21607/15560 21622/21647/15600 21583/21608/15561 +f 21606/21631/15584 21623/21648/15601 21624/21649/15602 +f 21606/21631/15584 21624/21649/15602 21607/21632/15585 +f 21610/21635/15588 21581/21606/15559 21584/21609/15562 +f 21610/21635/15588 21584/21609/15562 21611/21636/15589 +f 21586/21611/15564 21412/21437/15418 21415/21440/15421 +f 21586/21611/15564 21415/21440/15421 21587/21612/15565 +f 21433/21458/15439 21567/21592/15546 21570/21595/15549 +f 21433/21458/15439 21570/21595/15549 21434/21459/15440 +f 21568/21593/15547 21368/21393/15374 21371/21396/15377 +f 21568/21593/15547 21371/21396/15377 21569/21594/15548 +f 21625/21650/15603 21408/21433/15414 21411/21436/15417 +f 21625/21650/15603 21411/21436/15417 21626/21651/15604 +f 21627/21652/15605 21628/21653/15606 21629/21654/15607 +f 21627/21652/15605 21629/21654/15607 21630/21655/15608 +f 21631/21290/15609 21632/21289/15610 21633/21656/15611 +f 21631/21290/15609 21633/21656/15611 21634/21657/15612 +f 21628/21653/15606 21396/21421/15402 21399/21424/15405 +f 21628/21653/15606 21399/21424/15405 21629/21654/15607 +f 21446/21471/15448 21318/21345/15324 21321/21348/15327 +f 21446/21471/15448 21321/21348/15327 21635/21658/15613 +f 21594/21619/15572 21585/21610/15563 21588/21613/15566 +f 21594/21619/15572 21588/21613/15566 21595/21620/15573 +f 21636/21659/15614 21609/21634/15587 21612/21637/15590 +f 21636/21659/15614 21612/21637/15590 21637/21660/15615 +f 21573/21598/15551 21638/21661/15616 21639/21662/15617 +f 21573/21598/15551 21639/21662/15617 21574/21599/15552 +f 21640/21663/15618 21641/21664/15619 21642/21665/15620 +f 21640/21663/15618 21642/21665/15620 21643/21666/15398 +f 21598/21623/15576 21605/21630/15583 21608/21633/15586 +f 21598/21623/15576 21608/21633/15586 21599/21624/15577 +f 21634/21657/15612 21633/21656/15611 21644/21667/15580 +f 21634/21657/15612 21644/21667/15580 21645/21668/15621 +f 21566/21591/15545 21565/21590/15544 21646/21669/15622 +f 21566/21591/15545 21646/21669/15622 21647/21670/15362 +f 21447/21472/15449 21446/21471/15448 21635/21658/15613 +f 21447/21472/15449 21635/21658/15613 21648/21671/15623 +f 21558/21583/15538 21557/21582/15537 21649/21672/15381 +f 21558/21583/15538 21649/21672/15381 21650/21673/15380 +f 21651/21674/15624 21652/21675/15557 21339/21366/15345 +f 21651/21674/15624 21339/21366/15345 21338/21365/15344 +f 21653/21676/15443 21654/21677/15625 21578/21603/15556 +f 21653/21676/15443 21578/21603/15556 21577/21602/15555 +f 21659/21678/15626 21660/21679/15627 21347/21374/15353 +f 21659/21678/15626 21347/21374/15353 21346/21373/15352 +f 21661/21680/15628 21662/21681/15629 21663/21682/15630 +f 21661/21680/15628 21663/21682/15630 21664/21683/15631 +f 21665/21684/15632 21666/21685/15633 21405/21430/15411 +f 21665/21684/15632 21405/21430/15411 21404/21429/15410 +f 21667/21686/15634 21627/21652/15605 21630/21655/15608 +f 21667/21686/15634 21630/21655/15608 21668/21687/15635 +f 21452/21477/15452 21447/21472/15449 21648/21671/15623 +f 21452/21477/15452 21648/21671/15623 21669/21688/15636 +f 21315/21342/15321 21418/21443/15424 21419/21444/15425 +f 21315/21342/15321 21419/21444/15425 21316/21343/15322 +f 21409/21434/15415 21667/21686/15634 21668/21687/15635 +f 21409/21434/15415 21668/21687/15635 21410/21435/15416 +f 21303/21330/15309 21428/21453/15434 21429/21454/15435 +f 21303/21330/15309 21429/21454/15435 21304/21331/15310 +f 21616/21641/15594 21636/21659/15614 21637/21660/15615 +f 21616/21641/15594 21637/21660/15615 21617/21642/15595 +f 21397/21422/15403 21625/21650/15603 21626/21651/15604 +f 21397/21422/15403 21626/21651/15604 21398/21423/15404 +f 21638/21661/15616 21593/21618/15571 21596/21621/15574 +f 21638/21661/15616 21596/21621/15574 21639/21662/15617 +f 21422/21447/15428 21452/21477/15452 21669/21688/15636 +f 21422/21447/15428 21669/21688/15636 21423/21448/15429 +f 21670/21689/15391 21671/21690/15390 21641/21664/15619 +f 21670/21689/15391 21641/21664/15619 21640/21663/15618 +f 21395/21420/15401 21394/21419/15400 21672/21691/15637 +f 21395/21420/15401 21672/21691/15637 21673/21692/15638 +f 21384/21409/15390 21383/21408/15389 21674/21693/15639 +f 21384/21409/15390 21674/21693/15639 21675/21694/15640 +f 21676/21695/15641 21677/21696/15642 21678/21697/15643 +f 21676/21695/15641 21678/21697/15643 21679/21698/15644 +f 21679/21698/15644 21678/21697/15643 21325/21352/15331 +f 21679/21698/15644 21325/21352/15331 21324/21351/15330 +f 21426/21451/15432 21425/21450/15431 21680/21699/15645 +f 21426/21451/15432 21680/21699/15645 21681/21700/15646 +f 21681/21700/15646 21680/21699/15645 21682/21701/15647 +f 21681/21700/15646 21682/21701/15647 21683/21702/15648 +f 21684/21703/15649 21685/21704/15650 21399/21424/15405 +f 21684/21703/15649 21399/21424/15405 21398/21423/15404 +f 21686/21705/15651 21426/21451/15432 21681/21700/15646 +f 21686/21705/15651 21681/21700/15646 21687/21706/15652 +f 21688/21707/15653 21689/21708/15654 21684/21703/15649 +f 21688/21707/15653 21684/21703/15649 21690/21709/15655 +f 21690/21709/15655 21684/21703/15649 21398/21423/15404 +f 21690/21709/15655 21398/21423/15404 21626/21651/15604 +f 21659/21678/15626 21346/21373/15352 21691/21710/15656 +f 21659/21678/15626 21691/21710/15656 21692/21711/15657 +f 21692/21711/15657 21691/21710/15656 21693/21712/15658 +f 21692/21711/15657 21693/21712/15658 21694/21713/15659 +f 21695/21714/15660 21696/21715/15661 21561/21586/15541 +f 21695/21714/15660 21561/21586/15541 21435/21460/15441 +f 21631/21290/15609 21634/21657/15612 21697/21716/15662 +f 21631/21290/15609 21697/21716/15662 21698/21717/15663 +f 21698/21717/15663 21697/21716/15662 21699/21718/15664 +f 21698/21717/15663 21699/21718/15664 21700/21719/15665 +f 21701/21720/15666 21702/21721/15667 21317/21344/15323 +f 21701/21720/15666 21317/21344/15323 21316/21343/15322 +f 21376/21401/15382 21375/21400/15381 21703/21722/15668 +f 21376/21401/15382 21703/21722/15668 21704/21723/15669 +f 21704/21723/15669 21703/21722/15668 21705/21724/15670 +f 21704/21723/15669 21705/21724/15670 21706/21725/15671 +f 21707/21726/15671 21708/21727/15672 21591/21616/15569 +f 21707/21726/15671 21591/21616/15569 21614/21639/15592 +f 21662/21681/15629 21709/21728/15673 21710/21729/15674 +f 21662/21681/15629 21710/21729/15674 21711/21730/15675 +f 21712/21731/15676 21713/21732/15677 21714/21733/15678 +f 21712/21731/15676 21714/21733/15678 21715/21734/15679 +f 21715/21734/15679 21714/21733/15678 21334/21361/15340 +f 21715/21734/15679 21334/21361/15340 21431/21456/15437 +f 21395/21420/15401 21673/21692/15638 21716/21735/15680 +f 21395/21420/15401 21716/21735/15680 21717/21736/15681 +f 21718/21737/15682 21719/21738/15683 21720/21739/15684 +f 21718/21737/15682 21720/21739/15684 21721/21740/15685 +f 21721/21740/15685 21720/21739/15684 21639/21662/15617 +f 21721/21740/15685 21639/21662/15617 21596/21621/15574 +f 21653/21676/15443 21577/21602/15555 21722/21741/15686 +f 21653/21676/15443 21722/21741/15686 21723/21742/15687 +f 21723/21742/15687 21722/21741/15686 21724/21743/15688 +f 21723/21742/15687 21724/21743/15688 21725/21744/15689 +f 21726/21745/15689 21727/21746/15690 21371/21396/15377 +f 21726/21745/15689 21371/21396/15377 21370/21395/15376 +f 21579/21604/15557 21578/21603/15556 21728/21747/15691 +f 21579/21604/15557 21728/21747/15691 21729/21748/15692 +f 21729/21748/15692 21728/21747/15691 21730/21749/15693 +f 21729/21748/15692 21730/21749/15693 21731/21750/15694 +f 21732/21751/15695 21733/21752/15696 21668/21687/15635 +f 21732/21751/15695 21668/21687/15635 21630/21655/15608 +f 21734/21753/15697 21388/21413/15394 21735/21754/15698 +f 21734/21753/15697 21735/21754/15698 21736/21755/15699 +f 21736/21755/15699 21735/21754/15698 21737/21756/15700 +f 21736/21755/15699 21737/21756/15700 21738/21757/15701 +f 21739/21758/15702 21740/21759/15703 21599/21624/15577 +f 21739/21758/15702 21599/21624/15577 21608/21633/15586 +f 21603/21628/15581 21602/21627/15580 21741/21760/15704 +f 21603/21628/15581 21741/21760/15704 21742/21761/15705 +f 21743/21762/15705 21744/21763/15704 21745/21764/15706 +f 21743/21762/15705 21745/21764/15706 21746/21765/15707 +f 21746/21765/15707 21745/21764/15706 21637/21660/15615 +f 21746/21765/15707 21637/21660/15615 21612/21637/15590 +f 21328/21355/15334 21327/21354/15333 21747/21766/15708 +f 21328/21355/15334 21747/21766/15708 21748/21767/15709 +f 21748/21767/15709 21747/21766/15708 21749/21768/15710 +f 21748/21767/15709 21749/21768/15710 21750/21769/15711 +f 21751/21770/15712 21752/21771/15713 21583/21608/15561 +f 21751/21770/15712 21583/21608/15561 21622/21647/15600 +f 21327/21354/15333 21753/21772/15714 21754/21773/15715 +f 21327/21354/15333 21754/21773/15715 21747/21766/15708 +f 21755/21774/15716 21756/21775/15717 21757/21776/15718 +f 21755/21774/15716 21757/21776/15718 21752/21771/15713 +f 21752/21771/15713 21757/21776/15718 21584/21609/15562 +f 21752/21771/15713 21584/21609/15562 21583/21608/15561 +f 21633/21656/15611 21632/21289/15610 21758/21777/15719 +f 21633/21656/15611 21758/21777/15719 21759/21778/15720 +f 21760/21779/15720 21761/21780/15721 21762/21781/15722 +f 21760/21779/15720 21762/21781/15722 21763/21782/15723 +f 21763/21782/15723 21762/21781/15722 21618/21643/15596 +f 21763/21782/15723 21618/21643/15596 21617/21642/15595 +f 21644/21667/15580 21633/21656/15611 21759/21778/15720 +f 21644/21667/15580 21759/21778/15720 21764/21783/15704 +f 21744/21763/15704 21760/21779/15720 21763/21782/15723 +f 21744/21763/15704 21763/21782/15723 21745/21764/15706 +f 21745/21764/15706 21763/21782/15723 21617/21642/15595 +f 21745/21764/15706 21617/21642/15595 21637/21660/15615 +f 21765/21784/15724 21766/21785/15725 21767/21786/15726 +f 21765/21784/15724 21767/21786/15726 21768/21787/15727 +f 21768/21787/15727 21767/21786/15726 21769/21788/15728 +f 21768/21787/15727 21769/21788/15728 21770/21789/15729 +f 21771/21790/15729 21772/21791/15730 21414/21439/15420 +f 21771/21790/15729 21414/21439/15420 21574/21599/15552 +f 21656/21279/15731 21663/21682/15630 21773/21792/15732 +f 21656/21279/15731 21773/21792/15732 21774/21793/15733 +f 21774/21793/15733 21773/21792/15732 21775/21794/15734 +f 21774/21793/15733 21775/21794/15734 21776/21795/15735 +f 21777/21796/15736 21778/21797/15737 21576/21601/15554 +f 21777/21796/15736 21576/21601/15554 21337/21364/15343 +f 21665/21684/15632 21404/21429/15410 21779/21798/15738 +f 21665/21684/15632 21779/21798/15738 21780/21799/15739 +f 21780/21799/15739 21779/21798/15738 21781/21800/15740 +f 21780/21799/15739 21781/21800/15740 21782/21801/15741 +f 21783/21802/15742 21784/21803/15740 21429/21454/15435 +f 21783/21802/15742 21429/21454/15435 21313/21340/15319 +f 21388/21413/15394 21387/21412/15393 21785/21804/15743 +f 21388/21413/15394 21785/21804/15743 21735/21754/15698 +f 21735/21754/15698 21785/21804/15743 21786/21805/15744 +f 21735/21754/15698 21786/21805/15744 21737/21756/15700 +f 21740/21759/15703 21787/21806/15745 21600/21625/15578 +f 21740/21759/15703 21600/21625/15578 21599/21624/15577 +f 21601/21626/15579 21604/21629/15582 21788/21807/15746 +f 21601/21626/15579 21788/21807/15746 21789/21808/15747 +f 21789/21808/15747 21788/21807/15746 21790/21809/15741 +f 21789/21808/15747 21790/21809/15741 21791/21810/15748 +f 21792/21811/15749 21783/21802/15742 21313/21340/15319 +f 21792/21811/15749 21313/21340/15319 21312/21339/15318 +f 21578/21603/15556 21654/21677/15625 21793/21812/15750 +f 21578/21603/15556 21793/21812/15750 21728/21747/15691 +f 21728/21747/15691 21793/21812/15750 21794/21813/15751 +f 21728/21747/15691 21794/21813/15751 21730/21749/15693 +f 21733/21752/15696 21795/21814/15752 21410/21435/15416 +f 21733/21752/15696 21410/21435/15416 21668/21687/15635 +f 21349/21376/15355 21437/21462/15443 21796/21815/15687 +f 21349/21376/15355 21796/21815/15687 21797/21816/15753 +f 21798/21817/15754 21799/21818/15687 21726/21745/15689 +f 21798/21817/15754 21726/21745/15689 21800/21819/15755 +f 21800/21819/15755 21726/21745/15689 21370/21395/15376 +f 21800/21819/15755 21370/21395/15376 21562/21587/15542 +f 21654/21677/15625 21801/21820/15756 21802/21821/15757 +f 21654/21677/15625 21802/21821/15757 21793/21812/15750 +f 21803/21822/15750 21804/21823/15758 21805/21824/15759 +f 21803/21822/15750 21805/21824/15759 21795/21814/15752 +f 21795/21814/15752 21805/21824/15759 21411/21436/15417 +f 21795/21814/15752 21411/21436/15417 21410/21435/15416 +f 21392/21417/15398 21395/21420/15401 21717/21736/15681 +f 21392/21417/15398 21717/21736/15681 21806/21825/15760 +f 21806/21825/15760 21717/21736/15681 21807/21826/15685 +f 21806/21825/15760 21807/21826/15685 21808/21827/15761 +f 21809/21828/15762 21721/21740/15685 21596/21621/15574 +f 21809/21828/15762 21596/21621/15574 21595/21620/15573 +f 21394/21419/15400 21393/21418/15399 21810/21829/15763 +f 21394/21419/15400 21810/21829/15763 21811/21830/15674 +f 21811/21830/15674 21810/21829/15763 21812/21831/15764 +f 21811/21830/15674 21812/21831/15764 21813/21832/15678 +f 21714/21733/15678 21814/21833/15764 21335/21362/15341 +f 21714/21733/15678 21335/21362/15341 21334/21361/15340 +f 21640/21663/15618 21643/21666/15398 21815/21834/15760 +f 21640/21663/15618 21815/21834/15760 21816/21835/15765 +f 21817/21836/15766 21818/21837/15767 21809/21828/15762 +f 21817/21836/15766 21809/21828/15762 21819/21838/15768 +f 21819/21838/15768 21809/21828/15762 21595/21620/15573 +f 21819/21838/15768 21595/21620/15573 21588/21613/15566 +f 21649/21672/15381 21557/21582/15537 21820/21839/15769 +f 21649/21672/15381 21820/21839/15769 21821/21840/15668 +f 21822/21841/15770 21823/21842/15771 21824/21843/15772 +f 21822/21841/15770 21824/21843/15772 21708/21727/15672 +f 21708/21727/15672 21824/21843/15772 21592/21617/15570 +f 21708/21727/15672 21592/21617/15570 21591/21616/15569 +f 21825/21844/15773 21631/21290/15609 21698/21717/15663 +f 21825/21844/15773 21698/21717/15663 21826/21845/15774 +f 21827/21846/15775 21828/21847/15776 21701/21720/15666 +f 21827/21846/15775 21701/21720/15666 21829/21848/15777 +f 21829/21848/15777 21701/21720/15666 21316/21343/15322 +f 21829/21848/15777 21316/21343/15322 21419/21444/15425 +f 21424/21449/15430 21427/21452/15433 21830/21849/15778 +f 21424/21449/15430 21830/21849/15778 21831/21850/15779 +f 21832/21851/15780 21833/21852/15781 21695/21714/15660 +f 21832/21851/15780 21695/21714/15660 21834/21853/15782 +f 21834/21853/15782 21695/21714/15660 21435/21460/15441 +f 21834/21853/15782 21435/21460/15441 21434/21459/15440 +f 21326/21353/15332 21329/21356/15335 21835/21854/15783 +f 21326/21353/15332 21835/21854/15783 21836/21855/15784 +f 21836/21855/15784 21835/21854/15783 21837/21856/15785 +f 21836/21855/15784 21837/21856/15785 21838/21857/15786 +f 21839/21858/15787 21829/21848/15777 21419/21444/15425 +f 21839/21858/15787 21419/21444/15425 21305/21332/15311 +f 21338/21365/15344 21341/21368/15347 21840/21859/15788 +f 21338/21365/15344 21840/21859/15788 21841/21860/15789 +f 21842/21861/15790 21832/21851/15780 21834/21853/15782 +f 21842/21861/15790 21834/21853/15782 21843/21862/15791 +f 21843/21862/15791 21834/21853/15782 21434/21459/15440 +f 21843/21862/15791 21434/21459/15440 21570/21595/15549 +f 21557/21582/15537 21358/21383/15364 21844/21863/15792 +f 21557/21582/15537 21844/21863/15792 21820/21839/15769 +f 21820/21839/15769 21844/21863/15792 21845/21864/15793 +f 21820/21839/15769 21845/21864/15793 21846/21865/15794 +f 21824/21843/15772 21847/21866/15793 21624/21649/15602 +f 21824/21843/15772 21624/21649/15602 21592/21617/15570 +f 21641/21664/15619 21671/21690/15390 21848/21867/15795 +f 21641/21664/15619 21848/21867/15795 21849/21868/15796 +f 21849/21868/15796 21848/21867/15795 21850/21869/15644 +f 21849/21868/15796 21850/21869/15644 21851/21870/15797 +f 21852/21871/15798 21679/21698/15644 21324/21351/15330 +f 21852/21871/15798 21324/21351/15330 21331/21358/15337 +f 21358/21383/15364 21357/21382/15363 21853/21872/15799 +f 21358/21383/15364 21853/21872/15799 21844/21863/15792 +f 21844/21863/15792 21853/21872/15799 21854/21873/15800 +f 21844/21863/15792 21854/21873/15800 21845/21864/15793 +f 21847/21866/15793 21855/21874/15800 21607/21632/15585 +f 21847/21866/15793 21607/21632/15585 21624/21649/15602 +f 21856/21875/15801 21670/21689/15391 21857/21876/15802 +f 21856/21875/15801 21857/21876/15802 21858/21877/15803 +f 21859/21878/15804 21860/21879/15805 21861/21880/15806 +f 21859/21878/15804 21861/21880/15806 21862/21881/15807 +f 21862/21881/15807 21861/21880/15806 21587/21612/15565 +f 21862/21881/15807 21587/21612/15565 21415/21440/15421 +f 21642/21665/15620 21641/21664/15619 21849/21868/15796 +f 21642/21665/15620 21849/21868/15796 21863/21882/15808 +f 21864/21883/15809 21865/21884/15810 21852/21871/15798 +f 21864/21883/15809 21852/21871/15798 21866/21885/15811 +f 21866/21885/15811 21852/21871/15798 21331/21358/15337 +f 21866/21885/15811 21331/21358/15337 21335/21362/15341 +f 21670/21689/15391 21640/21663/15618 21816/21835/15765 +f 21670/21689/15391 21816/21835/15765 21857/21876/15802 +f 21860/21879/15805 21817/21836/15766 21819/21838/15768 +f 21860/21879/15805 21819/21838/15768 21861/21880/15806 +f 21861/21880/15806 21819/21838/15768 21588/21613/15566 +f 21861/21880/15806 21588/21613/15566 21587/21612/15565 +f 21348/21375/15354 21347/21374/15353 21867/21886/15652 +f 21348/21375/15354 21867/21886/15652 21868/21887/15812 +f 21804/21823/15758 21688/21707/15653 21690/21709/15655 +f 21804/21823/15758 21690/21709/15655 21805/21824/15759 +f 21805/21824/15759 21690/21709/15655 21626/21651/15604 +f 21805/21824/15759 21626/21651/15604 21411/21436/15417 +f 21346/21373/15352 21349/21376/15355 21797/21816/15753 +f 21346/21373/15352 21797/21816/15753 21691/21710/15656 +f 21691/21710/15656 21797/21816/15753 21869/21888/15755 +f 21691/21710/15656 21869/21888/15755 21693/21712/15658 +f 21696/21715/15661 21800/21819/15755 21562/21587/15542 +f 21696/21715/15661 21562/21587/15542 21561/21586/15541 +f 21634/21657/15612 21645/21668/15621 21870/21889/15747 +f 21634/21657/15612 21870/21889/15747 21697/21716/15662 +f 21871/21890/15813 21872/21891/15747 21792/21811/15749 +f 21871/21890/15813 21792/21811/15749 21702/21721/15667 +f 21702/21721/15667 21792/21811/15749 21312/21339/15318 +f 21702/21721/15667 21312/21339/15318 21317/21344/15323 +f 21387/21412/15393 21873/21892/15382 21874/21893/15814 +f 21387/21412/15393 21874/21893/15814 21785/21804/15743 +f 21875/21894/15815 21876/21895/15816 21707/21726/15671 +f 21875/21894/15815 21707/21726/15671 21787/21806/15745 +f 21787/21806/15745 21707/21726/15671 21614/21639/15592 +f 21787/21806/15745 21614/21639/15592 21600/21625/15578 +f 21663/21682/15630 21662/21681/15629 21711/21730/15675 +f 21663/21682/15630 21711/21730/15675 21773/21792/15732 +f 21773/21792/15732 21711/21730/15675 21877/21896/15817 +f 21773/21792/15732 21877/21896/15817 21775/21794/15734 +f 21778/21797/15737 21715/21734/15679 21431/21456/15437 +f 21778/21797/15737 21431/21456/15437 21576/21601/15554 +f 21661/21680/15628 21664/21683/15631 21878/21897/15727 +f 21661/21680/15628 21878/21897/15727 21879/21898/15818 +f 21879/21898/15818 21878/21897/15727 21880/21899/15729 +f 21879/21898/15818 21880/21899/15729 21881/21900/15819 +f 21720/21739/15684 21771/21790/15729 21574/21599/15552 +f 21720/21739/15684 21574/21599/15552 21639/21662/15617 +f 21882/21901/15820 21651/21674/15624 21883/21902/15821 +f 21882/21901/15820 21883/21902/15821 21884/21903/15686 +f 21884/21903/15686 21883/21902/15821 21885/21904/15822 +f 21884/21903/15686 21885/21904/15822 21886/21905/15688 +f 21727/21746/15690 21887/21906/15823 21569/21594/15548 +f 21727/21746/15690 21569/21594/15548 21371/21396/15377 +f 21405/21430/15411 21666/21685/15633 21888/21907/15824 +f 21405/21430/15411 21888/21907/15824 21889/21908/15825 +f 21890/21909/15826 21743/21762/15705 21746/21765/15707 +f 21890/21909/15826 21746/21765/15707 21891/21910/15827 +f 21891/21910/15827 21746/21765/15707 21612/21637/15590 +f 21891/21910/15827 21612/21637/15590 21611/21636/15589 +f 21892/21911/15279 21328/21355/15334 21748/21767/15709 +f 21892/21911/15279 21748/21767/15709 21893/21912/15719 +f 21761/21780/15721 21894/21913/15709 21751/21770/15712 +f 21761/21780/15721 21751/21770/15712 21762/21781/15722 +f 21762/21781/15722 21751/21770/15712 21622/21647/15600 +f 21762/21781/15722 21622/21647/15600 21618/21643/15596 +f 21363/21388/15369 21405/21430/15411 21889/21908/15825 +f 21363/21388/15369 21889/21908/15825 21895/21914/15715 +f 21895/21914/15715 21889/21908/15825 21896/21915/15828 +f 21895/21914/15715 21896/21915/15828 21897/21916/15829 +f 21757/21776/15718 21891/21910/15827 21611/21636/15589 +f 21757/21776/15718 21611/21636/15589 21584/21609/15562 +f 21898/21917/15830 21326/21353/15332 21836/21855/15784 +f 21898/21917/15830 21836/21855/15784 21899/21918/15831 +f 21900/21919/15832 21901/21920/15833 21839/21858/15787 +f 21900/21919/15832 21839/21858/15787 21902/21921/15834 +f 21902/21921/15834 21839/21858/15787 21305/21332/15311 +f 21902/21921/15834 21305/21332/15311 21304/21331/15310 +f 21340/21367/15346 21339/21366/15345 21903/21922/15835 +f 21340/21367/15346 21903/21922/15835 21904/21923/15645 +f 21905/21924/15836 21906/21925/15837 21907/21926/15838 +f 21905/21924/15836 21907/21926/15838 21685/21704/15650 +f 21685/21704/15650 21907/21926/15838 21629/21654/15607 +f 21685/21704/15650 21629/21654/15607 21399/21424/15405 +f 21766/21785/15725 21908/21927/15388 21909/21928/15839 +f 21766/21785/15725 21909/21928/15839 21767/21786/15726 +f 21910/21929/15840 21859/21878/15804 21862/21881/15807 +f 21910/21929/15840 21862/21881/15807 21772/21791/15730 +f 21772/21791/15730 21862/21881/15807 21415/21440/15421 +f 21772/21791/15730 21415/21440/15421 21414/21439/15420 +f 21646/21669/15622 21565/21590/15544 21911/21930/15841 +f 21646/21669/15622 21911/21930/15841 21912/21931/15799 +f 21912/21931/15799 21911/21930/15841 21913/21932/15702 +f 21912/21931/15799 21913/21932/15702 21914/21933/15842 +f 21855/21874/15800 21739/21758/15702 21608/21633/15586 +f 21855/21874/15800 21608/21633/15586 21607/21632/15585 +f 21651/21674/15624 21338/21365/15344 21841/21860/15789 +f 21651/21674/15624 21841/21860/15789 21883/21902/15821 +f 21883/21902/15821 21841/21860/15789 21915/21934/15843 +f 21883/21902/15821 21915/21934/15843 21885/21904/15822 +f 21887/21906/15823 21843/21862/15791 21570/21595/15549 +f 21887/21906/15823 21570/21595/15549 21569/21594/15548 +f 21383/21408/15389 21916/21935/15844 21917/21936/15845 +f 21383/21408/15389 21917/21936/15845 21674/21693/15639 +f 21674/21693/15639 21917/21936/15845 21918/21937/15736 +f 21674/21693/15639 21918/21937/15736 21919/21938/15643 +f 21678/21697/15643 21777/21796/15736 21337/21364/15343 +f 21678/21697/15643 21337/21364/15343 21325/21352/15331 +f 21404/21429/15410 21362/21387/15368 21920/21939/15846 +f 21404/21429/15410 21920/21939/15846 21779/21798/15738 +f 21779/21798/15738 21920/21939/15846 21921/21940/15847 +f 21779/21798/15738 21921/21940/15847 21781/21800/15740 +f 21784/21803/15740 21902/21921/15834 21304/21331/15310 +f 21784/21803/15740 21304/21331/15310 21429/21454/15435 +f 21339/21366/15345 21652/21675/15557 21922/21941/15848 +f 21339/21366/15345 21922/21941/15848 21903/21922/15835 +f 21903/21922/15835 21922/21941/15848 21923/21942/15849 +f 21903/21922/15835 21923/21942/15849 21924/21943/15850 +f 21907/21926/15838 21732/21751/15695 21630/21655/15608 +f 21907/21926/15838 21630/21655/15608 21629/21654/15607 +f 21664/21683/15631 21663/21682/15630 21656/21279/15731 +f 21664/21683/15631 21656/21279/15731 21655/21278/15725 +f 21925/21944/15851 21926/21945/15852 21927/21946/15853 +f 21925/21944/15851 21927/21946/15853 21928/21947/15854 +f 21474/21499/15471 21929/21948/15855 21930/21949/15856 +f 21474/21499/15471 21930/21949/15856 21475/21500/15472 +f 21931/21950/15857 21932/21951/15858 21933/21952/15859 +f 21931/21950/15857 21933/21952/15859 21934/21953/15860 +f 21935/21954/15861 21481/21506/15477 21484/21509/15478 +f 21935/21954/15861 21484/21509/15478 21936/21955/15862 +f 21937/21956/15863 21931/21950/15857 21934/21953/15860 +f 21937/21956/15863 21934/21953/15860 21938/21957/15864 +f 21929/21948/15855 21939/21958/15865 21940/21959/15866 +f 21929/21948/15855 21940/21959/15866 21930/21949/15856 +f 21941/21960/15867 21937/21956/15863 21938/21957/15864 +f 21941/21960/15867 21938/21957/15864 21942/21961/15868 +f 21943/21962/15869 21944/21963/15870 21945/21964/15862 +f 21943/21962/15869 21945/21964/15862 21946/21965/15871 +f 21947/21966/15872 21948/21967/15873 21949/21968/15874 +f 21947/21966/15872 21949/21968/15874 21950/21969/15875 +f 21951/21970/15876 21952/21971/15877 21953/21972/15878 +f 21951/21970/15876 21953/21972/15878 21954/21973/15879 +f 21952/21971/15877 21955/21974/15880 21956/21975/15881 +f 21952/21971/15877 21956/21975/15881 21953/21972/15878 +f 21955/21974/15880 21957/21976/15882 21958/21977/15883 +f 21955/21974/15880 21958/21977/15883 21956/21975/15881 +f 21957/21976/15882 21959/21978/15884 21960/21979/15885 +f 21957/21976/15882 21960/21979/15885 21958/21977/15883 +f 21959/21978/15884 21961/21980/15886 21962/21981/15887 +f 21959/21978/15884 21962/21981/15887 21960/21979/15885 +f 21948/21967/15873 21951/21970/15876 21954/21973/15879 +f 21948/21967/15873 21954/21973/15879 21949/21968/15874 +f 21961/21980/15886 21947/21966/15872 21950/21969/15875 +f 21961/21980/15886 21950/21969/15875 21962/21981/15887 +f 21454/21479/15454 21453/21478/15453 21963/21982/15888 +f 21454/21479/15454 21963/21982/15888 21964/21983/15889 +f 21965/21984/15890 21966/21985/15891 21967/21986/15892 +f 21965/21984/15890 21967/21986/15892 21968/21987/15893 +f 21969/21988/15894 21970/21989/15895 21309/21336/15315 +f 21969/21988/15894 21309/21336/15315 21308/21335/15314 +f 21971/21990/15896 21972/21991/15897 21582/21607/15560 +f 21971/21990/15896 21582/21607/15560 21581/21606/15559 +f 21943/21962/15869 21973/21992/15898 21974/21993/15314 +f 21943/21962/15869 21974/21993/15314 21975/21994/15361 +f 21976/21995/15897 21977/21996/15899 21978/21997/15900 +f 21976/21995/15897 21978/21997/15900 21979/21998/15901 +f 21980/21999/15870 21981/22000/15902 21355/21380/15361 +f 21980/21999/15870 21355/21380/15361 21354/21379/15360 +f 21982/22001/15903 21983/22002/15904 21615/21640/15593 +f 21982/22001/15903 21615/21640/15593 21621/21646/15599 +f 21984/22003/15905 21980/21999/15870 21354/21379/15360 +f 21984/22003/15905 21354/21379/15360 21361/21386/15367 +f 21983/22002/15904 21985/22004/15906 21616/21641/15594 +f 21983/22002/15904 21616/21641/15594 21615/21640/15593 +f 21986/22005/15465 21984/22003/15905 21361/21386/15367 +f 21986/22005/15465 21361/21386/15367 21367/21392/15373 +f 21985/22004/15906 21987/22006/15907 21636/21659/15614 +f 21985/22004/15906 21636/21659/15614 21616/21641/15594 +f 21466/21491/15466 21465/21490/15465 21988/22007/15908 +f 21466/21491/15466 21988/22007/15908 21989/22008/15379 +f 21990/22009/15909 21991/22010/15910 21992/22011/15587 +f 21990/22009/15909 21992/22011/15587 21993/22012/15614 +f 21994/22013/15911 21995/22014/15912 21373/21398/15379 +f 21994/22013/15911 21373/21398/15379 21379/21404/15385 +f 21996/22015/15910 21997/22016/15913 21610/21635/15588 +f 21996/22015/15910 21610/21635/15588 21609/21634/15587 +f 21998/22017/15914 21999/22018/15915 21306/21333/15312 +f 21998/22017/15914 21306/21333/15312 21378/21403/15384 +f 22000/22019/15916 22001/21282/15917 21352/21284/15358 +f 22000/22019/15916 21352/21284/15358 21307/21334/15313 +f 22002/22020/15918 21998/22017/15914 21378/21403/15384 +f 22002/22020/15918 21378/21403/15384 21372/21397/15378 +f 22003/22021/15919 22002/22020/15918 21372/21397/15378 +f 22003/22021/15919 21372/21397/15378 21366/21391/15372 +f 22004/22022/15920 22003/22021/15919 21366/21391/15372 +f 22004/22022/15920 21366/21391/15372 21360/21385/15366 +f 22005/22023/15921 22004/22022/15920 21360/21385/15366 +f 22005/22023/15921 21360/21385/15366 21353/21283/15359 +f 22001/21282/15275 22005/22023/15921 21353/21283/15359 +f 21999/22018/15915 22000/22019/15916 21307/21334/15313 +f 21999/22018/15915 21307/21334/15313 21306/21333/15312 +f 22006/22024/15922 22007/22025/15923 21950/21969/15875 +f 22006/22024/15922 21950/21969/15875 21949/21968/15874 +f 22008/22026/15924 22009/22027/15925 21954/21973/15879 +f 22008/22026/15924 21954/21973/15879 21953/21972/15878 +f 22010/22028/15926 22008/22026/15924 21953/21972/15878 +f 22010/22028/15926 21953/21972/15878 21956/21975/15881 +f 22011/22029/15927 22010/22028/15926 21956/21975/15881 +f 22011/22029/15927 21956/21975/15881 21958/21977/15883 +f 22012/22030/15928 22011/22029/15927 21958/21977/15883 +f 22012/22030/15928 21958/21977/15883 21960/21979/15885 +f 22013/22031/15929 22012/22030/15928 21960/21979/15885 +f 22013/22031/15929 21960/21979/15885 21962/21981/15887 +f 22009/22027/15925 22006/22024/15922 21949/21968/15874 +f 22009/22027/15925 21949/21968/15874 21954/21973/15879 +f 22007/22025/15923 22013/22031/15929 21962/21981/15887 +f 22007/22025/15923 21962/21981/15887 21950/21969/15875 +f 22014/22032/15456 22015/22033/15455 22016/22034/15930 +f 22014/22032/15456 22016/22034/15930 22017/22035/15931 +f 22015/22033/15455 22018/22036/15932 22019/22037/15933 +f 22015/22033/15455 22019/22037/15933 22016/22034/15930 +f 22018/22036/15932 22020/22038/15871 22021/22039/15934 +f 22018/22036/15932 22021/22039/15934 22019/22037/15933 +f 22020/22038/15871 22022/22040/15935 22023/22041/15936 +f 22020/22038/15871 22023/22041/15936 22021/22039/15934 +f 22022/22040/15935 22024/22042/15478 22025/22043/15937 +f 22022/22040/15935 22025/22043/15937 22023/22041/15936 +f 22024/22042/15478 22026/22044/15938 22027/22045/15939 +f 22024/22042/15478 22027/22045/15939 22025/22043/15937 +f 22026/22044/15938 22028/22046/15467 22029/22047/15940 +f 22026/22044/15938 22029/22047/15940 22027/22045/15939 +f 22028/22046/15467 22014/22032/15456 22017/22035/15931 +f 22028/22046/15467 22017/22035/15931 22029/22047/15940 +f 22030/22048/15941 22031/22049/15942 22032/22050/15943 +f 22030/22048/15941 22032/22050/15943 22033/22051/15944 +f 22034/22052/15945 22035/22053/15946 22036/22054/15947 +f 22034/22052/15945 22036/22054/15947 22037/22055/15948 +f 22038/22056/15949 22030/22048/15941 22033/22051/15944 +f 22038/22056/15949 22033/22051/15944 22039/22057/15950 +f 22040/22058/15951 22038/22056/15949 22039/22057/15950 +f 22040/22058/15951 22039/22057/15950 22041/22059/15952 +f 22042/22060/15953 22040/22058/15951 22041/22059/15952 +f 22042/22060/15953 22041/22059/15952 22043/22061/15954 +f 22044/22062/15955 22042/22060/15953 22043/22061/15954 +f 22044/22062/15955 22043/22061/15954 22045/22063/15956 +f 22035/22053/15946 22044/22062/15955 22045/22063/15956 +f 22035/22053/15946 22045/22063/15956 22036/22054/15947 +f 22031/22049/15942 22034/22052/15945 22037/22055/15948 +f 22031/22049/15942 22037/22055/15948 22032/22050/15943 +f 21462/21487/15462 22046/22064/15957 22047/22065/15958 +f 21462/21487/15462 22047/22065/15958 21463/21488/15463 +f 22048/22066/15466 21453/21478/15453 21456/21481/15456 +f 22048/22066/15466 21456/21481/15456 22049/22067/15959 +f 22050/22068/15960 22051/22069/15961 22052/22070/15962 +f 22050/22068/15960 22052/22070/15962 22053/22071/15963 +f 22054/22072/15964 22055/22073/15965 22056/22074/15966 +f 22054/22072/15964 22056/22074/15966 22057/22075/15958 +f 22058/22076/15961 21457/21482/15457 21460/21485/15460 +f 22058/22076/15961 21460/21485/15460 22059/22077/15962 +f 22060/22078/15967 21973/21992/15898 22061/22079/15968 +f 22060/22078/15967 22061/22079/15968 22062/22080/15455 +f 22063/22081/15969 22064/22082/15970 22065/22083/15971 +f 22063/22081/15969 22065/22083/15971 22066/22084/15972 +f 21926/21945/15852 22067/22085/15973 22068/22086/15974 +f 21926/21945/15852 22068/22086/15974 21927/21946/15853 +f 22069/22087/15975 22050/22068/15960 22053/22071/15963 +f 22069/22087/15975 22053/22071/15963 22070/22088/15976 +f 21478/21503/15474 21469/21494/15469 21472/21497/15470 +f 21478/21503/15474 21472/21497/15470 21479/21504/15475 +f 22071/22089/15858 22072/22090/15977 22073/22091/15854 +f 22071/22089/15858 22073/22091/15854 22074/22092/15978 +f 21973/21992/15898 21943/21962/15869 21946/21965/15871 +f 21973/21992/15898 21946/21965/15871 22061/22079/15968 +f 22064/22082/15970 22075/22093/15979 22076/22094/15476 +f 22064/22082/15970 22076/22094/15476 22065/22083/15971 +f 22077/22095/15980 22078/22096/15981 22079/22097/15982 +f 22077/22095/15980 22079/22097/15982 22080/22098/15983 +f 22081/22099/15865 22082/22100/15984 22083/22101/15976 +f 22081/22099/15865 22083/22101/15976 22084/22102/15866 +f 22078/22096/15981 22085/22103/15867 22086/22104/15868 +f 22078/22096/15981 22086/22104/15868 22079/22097/15982 +f 21620/21645/15598 21619/21644/15597 22087/22105/15985 +f 21620/21645/15598 22087/22105/15985 22088/22106/15986 +f 22099/22107/15987 22100/22108/15987 22101/22109/15988 +f 22099/22107/15987 22101/22109/15988 22102/22110/15989 +f 21383/21408/15389 21382/21407/15388 22102/22110/15989 +f 21383/21408/15389 22102/22110/15989 22101/22109/15988 +o Cylinder.035__0 +v 0.644351 1.503819 -0.616224 +v 0.652680 1.520711 -0.611622 +v 0.751697 1.483589 -0.654573 +v 0.743368 1.466697 -0.659175 +v 0.854126 1.433239 -0.655138 +v 0.845798 1.416347 -0.659739 +v 0.845798 1.416347 -0.659739 +v 0.854126 1.433239 -0.655138 +v 0.944374 1.377326 -0.613230 +v 0.936045 1.360434 -0.617831 +v 1.008700 1.324361 -0.535228 +v 1.000371 1.307469 -0.539830 +v 1.037312 1.282410 -0.433010 +v 1.028984 1.265518 -0.437611 +v 1.025854 1.257857 -0.322135 +v 1.017525 1.240965 -0.326737 +v 0.976070 1.254442 -0.219485 +v 0.967741 1.237550 -0.224086 +v 0.967741 1.237550 -0.224086 +v 0.976070 1.254442 -0.219485 +v 0.895540 1.272684 -0.140686 +v 0.887211 1.255792 -0.145288 +v 0.796523 1.309805 -0.097735 +v 0.788194 1.292913 -0.102336 +v 0.694093 1.360156 -0.097170 +v 0.685764 1.343264 -0.101772 +v 0.685764 1.343264 -0.101772 +v 0.694093 1.360156 -0.097170 +v 0.603846 1.416069 -0.139079 +v 0.595517 1.399177 -0.143680 +v 0.539519 1.469033 -0.217080 +v 0.531191 1.452142 -0.221681 +v 0.510907 1.510985 -0.319299 +v 0.502579 1.494093 -0.323900 +v 0.502579 1.494093 -0.323900 +v 0.510907 1.510985 -0.319299 +v 0.522366 1.535537 -0.430172 +v 0.514037 1.518646 -0.434774 +v 0.938883 1.377950 -0.605584 +v 0.851546 1.432060 -0.646141 +v 0.841237 1.411152 -0.651836 +v 0.928574 1.357042 -0.611279 +v 0.572150 1.538953 -0.532823 +v 0.563821 1.522061 -0.537425 +v 0.685743 1.349825 -0.691011 +v 0.788172 1.299475 -0.691575 +v 0.395108 1.277441 -0.500478 +v 0.449054 1.386853 -0.470674 +v 0.498838 1.390268 -0.573325 +v 0.444892 1.280856 -0.603128 +v 0.383650 1.252888 -0.389604 +v 0.437596 1.362300 -0.359800 +v 0.412262 1.210937 -0.287385 +v 0.466208 1.320349 -0.257581 +v 0.437596 1.362300 -0.359800 +v 0.383650 1.252888 -0.389604 +v 0.476588 1.157973 -0.209384 +v 0.530535 1.267384 -0.179580 +v 0.566835 1.102059 -0.167476 +v 0.620782 1.211471 -0.137672 +v 0.669265 1.051709 -0.168040 +v 0.723212 1.161120 -0.138237 +v 0.620782 1.211471 -0.137672 +v 0.566835 1.102059 -0.167476 +v 0.768282 1.014587 -0.210991 +v 0.822229 1.123999 -0.181188 +v 0.848813 0.996345 -0.289790 +v 0.902759 1.105757 -0.259987 +v 0.898596 0.999761 -0.392441 +v 0.952543 1.109172 -0.362637 +v 0.902759 1.105757 -0.259987 +v 0.848813 0.996345 -0.289790 +v 0.910055 1.024313 -0.503315 +v 0.964001 1.133725 -0.473511 +v 0.881442 1.066265 -0.605534 +v 0.935389 1.175676 -0.575730 +v 0.817116 1.119229 -0.683535 +v 0.871063 1.228641 -0.653731 +v 0.726869 1.175142 -0.725443 +v 0.780815 1.284554 -0.695639 +v 0.624439 1.225492 -0.724879 +v 0.678386 1.334904 -0.695075 +v 0.780815 1.284554 -0.695639 +v 0.726869 1.175142 -0.725443 +v 0.506196 1.405189 -0.569261 +v 0.586726 1.386947 -0.648059 +v 0.329814 0.865894 -0.789994 +v 0.337832 0.882156 -0.785563 +v 0.436850 0.845034 -0.828515 +v 0.428832 0.828772 -0.832945 +v 0.539279 0.794684 -0.829079 +v 0.531261 0.778422 -0.833509 +v 0.531261 0.778422 -0.833509 +v 0.539279 0.794684 -0.829079 +v 0.629527 0.738770 -0.787171 +v 0.621508 0.722508 -0.791601 +v 0.693853 0.685806 -0.709170 +v 0.685834 0.669544 -0.713600 +v 0.722465 0.643855 -0.606951 +v 0.714447 0.627593 -0.611381 +v 0.711007 0.619302 -0.496077 +v 0.702988 0.603040 -0.500507 +v 0.661223 0.615887 -0.393426 +v 0.653204 0.599625 -0.397856 +v 0.653204 0.599625 -0.397856 +v 0.661223 0.615887 -0.393426 +v 0.580692 0.634129 -0.314627 +v 0.572674 0.617867 -0.319057 +v 0.481675 0.671250 -0.271676 +v 0.473657 0.654988 -0.276106 +v 0.379246 0.721601 -0.271112 +v 0.371227 0.705339 -0.275542 +v 0.371227 0.705339 -0.275542 +v 0.379246 0.721601 -0.271112 +v 0.288999 0.777514 -0.313020 +v 0.280980 0.761252 -0.317450 +v 0.224672 0.830478 -0.391021 +v 0.216654 0.814216 -0.395451 +v 0.196060 0.872430 -0.493240 +v 0.188042 0.856168 -0.497670 +v 0.188042 0.856168 -0.497670 +v 0.196060 0.872430 -0.493240 +v 0.207518 0.896982 -0.604114 +v 0.199500 0.880720 -0.608544 +v 0.257302 0.900398 -0.706765 +v 0.249284 0.884136 -0.711195 +v 0.656596 1.516712 -0.604029 +v 0.752420 1.480787 -0.645595 +v 0.751697 1.483589 -0.654573 +v 0.652680 1.520711 -0.611622 +v 0.851546 1.432060 -0.646141 +v 0.854126 1.433239 -0.655138 +v 0.938883 1.377950 -0.605584 +v 0.944374 1.377326 -0.613230 +v 1.001135 1.326694 -0.530098 +v 1.008700 1.324361 -0.535228 +v 1.028824 1.286095 -0.431176 +v 1.037312 1.282410 -0.433010 +v 1.017735 1.262335 -0.323878 +v 1.025854 1.257857 -0.322135 +v 0.969557 1.259029 -0.224537 +v 0.976070 1.254442 -0.219485 +v 0.891623 1.276683 -0.148280 +v 0.895540 1.272684 -0.140686 +v 0.795800 1.312608 -0.106714 +v 0.796523 1.309805 -0.097735 +v 0.696674 1.361334 -0.106168 +v 0.694093 1.360156 -0.097170 +v 0.609336 1.415444 -0.146724 +v 0.603846 1.416069 -0.139079 +v 0.547085 1.466701 -0.222210 +v 0.539519 1.469033 -0.217080 +v 0.519395 1.507299 -0.321132 +v 0.510907 1.510985 -0.319299 +v 0.530484 1.531060 -0.428431 +v 0.522366 1.535537 -0.430172 +v 0.578663 1.534365 -0.527771 +v 0.572150 1.538953 -0.532823 +v 0.609336 1.415444 -0.146724 +v 0.696674 1.361334 -0.106168 +v 0.686365 1.340426 -0.111863 +v 0.599027 1.394536 -0.152420 +v 1.001135 1.326694 -0.530098 +v 0.990826 1.305786 -0.535794 +v 0.547085 1.466701 -0.222210 +v 0.536776 1.445792 -0.227905 +v 1.028824 1.286095 -0.431176 +v 1.018515 1.265187 -0.436872 +v 0.519395 1.507299 -0.321132 +v 0.509086 1.486391 -0.326827 +v 1.017735 1.262335 -0.323878 +v 1.007426 1.241426 -0.329573 +v 0.530484 1.531060 -0.428431 +v 0.520175 1.510152 -0.434126 +v 0.969557 1.259029 -0.224537 +v 1.017735 1.262335 -0.323878 +v 1.007426 1.241426 -0.329573 +v 0.959248 1.238121 -0.230233 +v 0.578663 1.534365 -0.527771 +v 0.530484 1.531060 -0.428431 +v 0.520175 1.510152 -0.434126 +v 0.568353 1.513457 -0.533466 +v 0.891623 1.276683 -0.148280 +v 0.881314 1.255774 -0.153975 +v 0.752420 1.480787 -0.645595 +v 0.656596 1.516712 -0.604029 +v 0.646287 1.495803 -0.609724 +v 0.742111 1.459879 -0.651290 +v 0.795800 1.312608 -0.106714 +v 0.785491 1.291699 -0.112409 +v 0.851546 1.432060 -0.646141 +v 0.841237 1.411152 -0.651836 +v 0.696674 1.361334 -0.106168 +v 0.686365 1.340426 -0.111863 +v 0.655596 1.486296 -0.591672 +v 0.743829 1.453218 -0.629946 +v 0.742111 1.459879 -0.651290 +v 0.646287 1.495803 -0.609724 +v 0.835103 1.408350 -0.630448 +v 0.841237 1.411152 -0.651836 +v 0.915521 1.358527 -0.593104 +v 0.928574 1.357042 -0.611279 +v 0.972841 1.311331 -0.523599 +v 0.990826 1.305786 -0.535794 +v 0.998337 1.273949 -0.432513 +v 1.018515 1.265187 -0.436872 +v 0.988127 1.252070 -0.333714 +v 1.007426 1.241426 -0.329573 +v 0.943765 1.249027 -0.242244 +v 0.959248 1.238121 -0.230233 +v 0.872005 1.265282 -0.172027 +v 0.881314 1.255774 -0.153975 +v 0.783772 1.298361 -0.133754 +v 0.785491 1.291699 -0.112409 +v 0.692499 1.343227 -0.133251 +v 0.686365 1.340426 -0.111863 +v 0.612080 1.393051 -0.170595 +v 0.599027 1.394536 -0.152420 +v 0.554760 1.440247 -0.240100 +v 0.536776 1.445792 -0.227905 +v 0.529264 1.477629 -0.331186 +v 0.509086 1.486391 -0.326827 +v 0.539474 1.499508 -0.429985 +v 0.520175 1.510152 -0.434126 +v 0.583836 1.502551 -0.521456 +v 0.568353 1.513457 -0.533466 +v 0.322284 1.032191 -0.670865 +v 0.376231 1.141603 -0.641061 +v 0.456762 1.123361 -0.719860 +v 0.402815 1.013949 -0.749663 +v 0.395458 0.999028 -0.753728 +v 0.494475 0.961906 -0.796679 +v 0.579369 1.372026 -0.652124 +v 0.525422 1.262614 -0.681927 +v 0.788172 1.299475 -0.691575 +v 0.878420 1.243561 -0.649667 +v 0.596904 0.911556 -0.797243 +v 0.501832 0.976827 -0.792615 +v 0.555779 1.086239 -0.762811 +v 0.658208 1.035889 -0.763375 +v 0.604261 0.926477 -0.793179 +v 0.563136 1.101160 -0.758747 +v 0.617083 1.210572 -0.728943 +v 0.719512 1.160222 -0.729507 +v 0.665565 1.050809 -0.759311 +v 0.942746 1.190597 -0.571666 +v 0.596904 0.911556 -0.797243 +v 0.687151 0.855643 -0.755335 +v 0.604261 0.926477 -0.793179 +v 0.658208 1.035889 -0.763375 +v 0.748456 0.979975 -0.721467 +v 0.694509 0.870564 -0.751271 +v 0.665565 1.050809 -0.759311 +v 0.719512 1.160222 -0.729507 +v 0.809759 1.104308 -0.687599 +v 0.755812 0.994896 -0.717403 +v 0.971358 1.148645 -0.469447 +v 0.751478 0.802679 -0.677334 +v 0.812782 0.927011 -0.643466 +v 0.758835 0.817599 -0.673270 +v 0.874085 1.051344 -0.609598 +v 0.820138 0.941932 -0.639402 +v 0.959900 1.124093 -0.358573 +v 0.780090 0.760727 -0.575116 +v 0.841394 0.885059 -0.541247 +v 0.787447 0.775648 -0.571051 +v 0.902698 1.009392 -0.507380 +v 0.848751 0.899980 -0.537183 +v 0.959900 1.124093 -0.358573 +v 1.017525 1.240965 -0.326737 +v 0.910116 1.120677 -0.255922 +v 0.768632 0.736175 -0.464241 +v 0.829936 0.860507 -0.430373 +v 0.775989 0.751095 -0.460177 +v 0.891239 0.984840 -0.396505 +v 0.837292 0.875428 -0.426309 +v 0.829586 1.138919 -0.177123 +v 0.718848 0.732759 -0.361591 +v 0.780152 0.857091 -0.327723 +v 0.726205 0.747680 -0.357526 +v 0.841455 0.981424 -0.293855 +v 0.787508 0.872012 -0.323658 +v 0.730568 1.176041 -0.134172 +v 0.718848 0.732759 -0.361591 +v 0.638317 0.751001 -0.282792 +v 0.726205 0.747680 -0.357526 +v 0.780152 0.857091 -0.327723 +v 0.699621 0.875333 -0.248924 +v 0.645674 0.765922 -0.278727 +v 0.787508 0.872012 -0.323658 +v 0.841455 0.981424 -0.293855 +v 0.760925 0.999666 -0.215055 +v 0.706978 0.890254 -0.244859 +v 0.628139 1.226392 -0.133608 +v 0.539300 0.788123 -0.239841 +v 0.600604 0.912455 -0.205973 +v 0.546658 0.803043 -0.235776 +v 0.661908 1.036788 -0.172104 +v 0.607961 0.927376 -0.201908 +v 0.628139 1.226392 -0.133608 +v 0.537892 1.282305 -0.175516 +v 0.436871 0.838473 -0.239276 +v 0.498175 0.962806 -0.205408 +v 0.444228 0.853394 -0.235212 +v 0.559479 1.087138 -0.171540 +v 0.505532 0.977726 -0.201344 +v 0.473565 1.335269 -0.253517 +v 0.436871 0.838473 -0.239276 +v 0.346623 0.894387 -0.281184 +v 0.444228 0.853394 -0.235212 +v 0.498175 0.962806 -0.205408 +v 0.407927 1.018719 -0.247316 +v 0.353981 0.909307 -0.277120 +v 0.505532 0.977726 -0.201344 +v 0.559479 1.087138 -0.171540 +v 0.469231 1.143052 -0.213448 +v 0.415284 1.033640 -0.243252 +v 0.444953 1.377221 -0.355736 +v 0.282297 0.947351 -0.359186 +v 0.343601 1.071683 -0.325317 +v 0.289654 0.962271 -0.355121 +v 0.404905 1.196016 -0.291450 +v 0.350958 1.086604 -0.321253 +v 0.444953 1.377221 -0.355736 +v 0.456411 1.401773 -0.466610 +v 0.253685 0.989302 -0.461404 +v 0.314989 1.113635 -0.427536 +v 0.261042 1.004223 -0.457340 +v 0.376293 1.237968 -0.393668 +v 0.322346 1.128556 -0.423472 +v 0.253685 0.989302 -0.461404 +v 0.265143 1.013855 -0.572278 +v 0.261042 1.004223 -0.457340 +v 0.314989 1.113635 -0.427536 +v 0.326447 1.138187 -0.538410 +v 0.272500 1.028775 -0.568214 +v 0.322346 1.128556 -0.423472 +v 0.376293 1.237968 -0.393668 +v 0.387751 1.262520 -0.504542 +v 0.333804 1.153108 -0.534346 +v 0.314927 1.017270 -0.674929 +v 0.437535 1.265935 -0.607193 +v 0.383588 1.156523 -0.636997 +v 0.518065 1.247694 -0.685992 +v 0.464118 1.138281 -0.715796 +v 0.497693 0.968965 -0.795973 +v 0.398276 1.006237 -0.752849 +v 0.559243 1.093799 -0.761969 +v 0.459827 1.131070 -0.718845 +v 0.620794 1.218633 -0.727964 +v 0.521378 1.255904 -0.684840 +v 0.682345 1.343466 -0.693960 +v 0.582928 1.380737 -0.650836 +v 0.600535 0.918412 -0.796540 +v 0.662086 1.043246 -0.762536 +v 0.723636 1.168080 -0.728531 +v 0.785187 1.292913 -0.694526 +v 0.691146 0.862273 -0.754463 +v 0.600535 0.918412 -0.796540 +v 0.752697 0.987107 -0.720458 +v 0.662086 1.043246 -0.762536 +v 0.814247 1.111941 -0.686454 +v 0.723636 1.168080 -0.728531 +v 0.875798 1.236774 -0.652449 +v 0.785187 1.292913 -0.694526 +v 0.755731 0.809096 -0.676148 +v 0.817282 0.933929 -0.642143 +v 0.878833 1.058764 -0.608139 +v 0.940383 1.183597 -0.574134 +v 0.784458 0.766975 -0.573517 +v 0.846009 0.891809 -0.539513 +v 0.907560 1.016643 -0.505508 +v 0.969110 1.141476 -0.471504 +v 0.772954 0.742323 -0.462196 +v 0.834505 0.867157 -0.428191 +v 0.896056 0.991991 -0.394187 +v 0.957606 1.116824 -0.360182 +v 0.722970 0.738894 -0.359132 +v 0.784521 0.863728 -0.325127 +v 0.846071 0.988562 -0.291123 +v 0.910116 1.120677 -0.255922 +v 0.907622 1.113395 -0.257118 +v 0.642115 0.757210 -0.280015 +v 0.722970 0.738894 -0.359132 +v 0.703665 0.882043 -0.246011 +v 0.784521 0.863728 -0.325127 +v 0.765216 1.006877 -0.212006 +v 0.846071 0.988562 -0.291123 +v 0.826767 1.131711 -0.178002 +v 0.907622 1.113395 -0.257118 +v 0.542698 0.794481 -0.236891 +v 0.604249 0.919315 -0.202887 +v 0.665800 1.044149 -0.168882 +v 0.727350 1.168982 -0.134878 +v 0.439857 0.845035 -0.236324 +v 0.501407 0.969868 -0.202320 +v 0.562958 1.094702 -0.168315 +v 0.624509 1.219535 -0.134311 +v 0.349246 0.901173 -0.278402 +v 0.439857 0.845035 -0.236324 +v 0.410796 1.026007 -0.244397 +v 0.501407 0.969868 -0.202320 +v 0.472347 1.150841 -0.210392 +v 0.562958 1.094702 -0.168315 +v 0.533897 1.275674 -0.176388 +v 0.624509 1.219535 -0.134311 +v 0.284660 0.954351 -0.356717 +v 0.346210 1.079185 -0.322712 +v 0.407761 1.204019 -0.288708 +v 0.469312 1.328852 -0.254704 +v 0.255933 0.996471 -0.459347 +v 0.317483 1.121305 -0.425343 +v 0.379034 1.246139 -0.391338 +v 0.440585 1.370972 -0.357334 +v 0.267437 1.021123 -0.570668 +v 0.255933 0.996471 -0.459347 +v 0.328988 1.145957 -0.536664 +v 0.317483 1.121305 -0.425343 +v 0.390538 1.270791 -0.502659 +v 0.379034 1.246139 -0.391338 +v 0.452089 1.395624 -0.468655 +v 0.440585 1.370972 -0.357334 +v 0.317421 1.024552 -0.673733 +v 0.378972 1.149386 -0.639729 +v 0.440523 1.274220 -0.605724 +v 0.502074 1.399053 -0.571719 +v 0.329814 0.865894 -0.789994 +v 0.428832 0.828772 -0.832945 +v 0.531261 0.778422 -0.833509 +v 0.621508 0.722508 -0.791601 +v 0.685834 0.669544 -0.713600 +v 0.714447 0.627593 -0.611381 +v 0.702988 0.603040 -0.500507 +v 0.653204 0.599625 -0.397856 +v 0.572674 0.617867 -0.319057 +v 0.473657 0.654988 -0.276106 +v 0.371227 0.705339 -0.275542 +v 0.280980 0.761252 -0.317450 +v 0.216654 0.814216 -0.395451 +v 0.188042 0.856168 -0.497670 +v 0.199500 0.880720 -0.608544 +v 0.249284 0.884136 -0.711195 +vt 0.052984 0.108983 +vt 0.038511 0.106105 +vt 0.045461 0.108983 +vt 0.059934 0.106105 +vt 0.033191 0.100787 +vt 0.065253 0.100787 +vt 0.030312 0.093838 +vt 0.068132 0.093838 +vt 0.030312 0.086318 +vt 0.033191 0.079369 +vt 0.068132 0.086318 +vt 0.038511 0.074051 +vt 0.065253 0.079369 +vt 0.059934 0.074051 +vt 0.045461 0.071173 +vt 0.052984 0.071173 +vt 0.274915 0.164507 +vt 0.274915 0.165941 +vt 0.282715 0.165941 +vt 0.282715 0.164507 +vt 0.288684 0.165941 +vt 0.288684 0.164507 +vt 0.251836 0.111799 +vt 0.251836 0.110365 +vt 0.245867 0.110365 +vt 0.245867 0.111799 +vt 0.238067 0.110365 +vt 0.238067 0.111799 +vt 0.229625 0.110365 +vt 0.229625 0.111799 +vt 0.221825 0.110365 +vt 0.221825 0.111799 +vt 0.215856 0.110365 +vt 0.215856 0.111799 +vt 0.801972 0.070497 +vt 0.801972 0.069064 +vt 0.794172 0.069064 +vt 0.794172 0.070497 +vt 0.785730 0.069064 +vt 0.785730 0.070497 +vt 0.777930 0.069064 +vt 0.777930 0.070497 +vt 0.946396 0.089785 +vt 0.946396 0.088352 +vt 0.938596 0.088352 +vt 0.938596 0.089785 +vt 0.930154 0.088352 +vt 0.930154 0.089785 +vt 0.922354 0.088352 +vt 0.922354 0.089785 +vt 0.252704 0.164507 +vt 0.252704 0.165941 +vt 0.258673 0.165941 +vt 0.258673 0.164507 +vt 0.882360 0.272923 +vt 0.882360 0.265377 +vt 0.880585 0.265377 +vt 0.880585 0.272923 +vt 0.266473 0.165941 +vt 0.266473 0.164507 +vt 0.282715 0.154588 +vt 0.288684 0.154588 +vt 0.258673 0.144035 +vt 0.258673 0.153321 +vt 0.266473 0.153321 +vt 0.266473 0.144035 +vt 0.252704 0.144035 +vt 0.252704 0.153321 +vt 0.930154 0.110257 +vt 0.930154 0.100971 +vt 0.922354 0.100971 +vt 0.922354 0.110257 +vt 0.938596 0.110257 +vt 0.938596 0.100971 +vt 0.946396 0.110257 +vt 0.946396 0.100971 +vt 0.785730 0.090969 +vt 0.785730 0.081683 +vt 0.777930 0.081683 +vt 0.777930 0.090969 +vt 0.794172 0.090969 +vt 0.794172 0.081683 +vt 0.801972 0.090969 +vt 0.801972 0.081683 +vt 0.221825 0.132270 +vt 0.221825 0.122984 +vt 0.215856 0.122984 +vt 0.215856 0.132270 +vt 0.229625 0.132270 +vt 0.229625 0.122984 +vt 0.238067 0.132270 +vt 0.238067 0.122984 +vt 0.245867 0.132270 +vt 0.245867 0.122984 +vt 0.251836 0.132270 +vt 0.251836 0.122984 +vt 0.282715 0.144035 +vt 0.282715 0.153321 +vt 0.288684 0.153321 +vt 0.288684 0.144035 +vt 0.266473 0.154588 +vt 0.274915 0.154588 +vt 0.274915 0.110365 +vt 0.274915 0.111745 +vt 0.282715 0.111745 +vt 0.282715 0.110365 +vt 0.288684 0.111745 +vt 0.288684 0.110365 +vt 0.251836 0.165941 +vt 0.251836 0.164560 +vt 0.245867 0.164560 +vt 0.245867 0.165941 +vt 0.238067 0.164560 +vt 0.238067 0.165941 +vt 0.229625 0.164560 +vt 0.229625 0.165941 +vt 0.221825 0.164560 +vt 0.221825 0.165941 +vt 0.215856 0.164560 +vt 0.215856 0.165941 +vt 0.801972 0.124639 +vt 0.801972 0.123259 +vt 0.794172 0.123259 +vt 0.794172 0.124639 +vt 0.785730 0.123259 +vt 0.785730 0.124639 +vt 0.777930 0.123259 +vt 0.777930 0.124639 +vt 0.946396 0.143927 +vt 0.946396 0.142547 +vt 0.938596 0.142547 +vt 0.938596 0.143927 +vt 0.930154 0.142547 +vt 0.930154 0.143927 +vt 0.922354 0.142547 +vt 0.922354 0.143927 +vt 0.252704 0.110365 +vt 0.252704 0.111745 +vt 0.258673 0.111745 +vt 0.258673 0.110365 +vt 0.266473 0.111745 +vt 0.266473 0.110365 +vt 0.697814 0.112281 +vt 0.705362 0.109155 +vt 0.705226 0.108471 +vt 0.697426 0.111701 +vt 0.713532 0.109155 +vt 0.713668 0.108471 +vt 0.721080 0.112281 +vt 0.721468 0.111701 +vt 0.726857 0.118056 +vt 0.727437 0.117669 +vt 0.729984 0.125603 +vt 0.730668 0.125467 +vt 0.729984 0.133770 +vt 0.730668 0.133907 +vt 0.726857 0.141317 +vt 0.727437 0.141704 +vt 0.721080 0.147092 +vt 0.721468 0.147672 +vt 0.713532 0.150218 +vt 0.713668 0.150902 +vt 0.705362 0.150218 +vt 0.705226 0.150902 +vt 0.697814 0.147092 +vt 0.697426 0.147672 +vt 0.692037 0.141317 +vt 0.691457 0.141704 +vt 0.688910 0.133770 +vt 0.688226 0.133907 +vt 0.688910 0.125603 +vt 0.688226 0.125466 +vt 0.692037 0.118056 +vt 0.691457 0.117669 +vt 0.880585 0.199787 +vt 0.880585 0.205563 +vt 0.882360 0.205563 +vt 0.882360 0.199787 +vt 0.882360 0.281091 +vt 0.880585 0.281091 +vt 0.880585 0.192241 +vt 0.882360 0.192241 +vt 0.882360 0.288637 +vt 0.880585 0.288637 +vt 0.880585 0.184073 +vt 0.882360 0.184073 +vt 0.882360 0.294412 +vt 0.880585 0.294412 +vt 0.880585 0.176527 +vt 0.882360 0.176527 +vt 0.882360 0.213690 +vt 0.882360 0.206144 +vt 0.880585 0.206144 +vt 0.880585 0.213690 +vt 0.425478 0.086966 +vt 0.425478 0.092741 +vt 0.427253 0.092741 +vt 0.427253 0.086966 +vt 0.882360 0.221858 +vt 0.880585 0.221858 +vt 0.425478 0.071252 +vt 0.425478 0.079420 +vt 0.427253 0.079420 +vt 0.427253 0.071252 +vt 0.882360 0.229404 +vt 0.880585 0.229404 +vt 0.425478 0.063706 +vt 0.427253 0.063706 +vt 0.882360 0.235179 +vt 0.880585 0.235179 +vt 0.031812 0.078448 +vt 0.028685 0.085994 +vt 0.037589 0.072672 +vt 0.045137 0.069547 +vt 0.053307 0.069547 +vt 0.060855 0.072672 +vt 0.066632 0.078448 +vt 0.069759 0.085994 +vt 0.069759 0.094162 +vt 0.066632 0.101708 +vt 0.060855 0.107484 +vt 0.053307 0.110609 +vt 0.045137 0.110609 +vt 0.037589 0.107484 +vt 0.031812 0.101708 +vt 0.028685 0.094162 +vt 0.266473 0.122931 +vt 0.266473 0.132217 +vt 0.274915 0.132217 +vt 0.274915 0.122931 +vt 0.274915 0.121664 +vt 0.282715 0.121664 +vt 0.274915 0.153321 +vt 0.274915 0.144035 +vt 0.251836 0.121718 +vt 0.245867 0.121718 +vt 0.288684 0.121664 +vt 0.282715 0.122931 +vt 0.282715 0.132217 +vt 0.288684 0.132217 +vt 0.288684 0.122931 +vt 0.282715 0.133483 +vt 0.282715 0.142769 +vt 0.288684 0.142769 +vt 0.288684 0.133483 +vt 0.238067 0.121718 +vt 0.251836 0.154641 +vt 0.245867 0.154641 +vt 0.251836 0.153375 +vt 0.251836 0.144089 +vt 0.245867 0.144089 +vt 0.245867 0.153375 +vt 0.251836 0.142823 +vt 0.251836 0.133537 +vt 0.245867 0.133537 +vt 0.245867 0.142823 +vt 0.229625 0.121718 +vt 0.238067 0.154641 +vt 0.238067 0.144089 +vt 0.238067 0.153375 +vt 0.238067 0.133537 +vt 0.238067 0.142823 +vt 0.221825 0.121718 +vt 0.229625 0.154641 +vt 0.229625 0.144089 +vt 0.229625 0.153375 +vt 0.229625 0.133537 +vt 0.229625 0.142823 +vt 0.807941 0.080417 +vt 0.807941 0.070497 +vt 0.801972 0.080417 +vt 0.221825 0.154641 +vt 0.221825 0.144089 +vt 0.221825 0.153375 +vt 0.221825 0.133537 +vt 0.221825 0.142823 +vt 0.794172 0.080417 +vt 0.215856 0.154641 +vt 0.215856 0.144089 +vt 0.215856 0.153375 +vt 0.215856 0.133537 +vt 0.215856 0.142823 +vt 0.785730 0.080417 +vt 0.801972 0.113340 +vt 0.794172 0.113340 +vt 0.801972 0.112074 +vt 0.801972 0.102788 +vt 0.794172 0.102788 +vt 0.794172 0.112074 +vt 0.801972 0.101521 +vt 0.801972 0.092235 +vt 0.794172 0.092235 +vt 0.794172 0.101521 +vt 0.777930 0.080417 +vt 0.785730 0.113340 +vt 0.785730 0.102788 +vt 0.785730 0.112074 +vt 0.785730 0.092235 +vt 0.785730 0.101521 +vt 0.946396 0.099705 +vt 0.938596 0.099705 +vt 0.777930 0.113340 +vt 0.777930 0.102788 +vt 0.777930 0.112074 +vt 0.777930 0.092235 +vt 0.777930 0.101521 +vt 0.930154 0.099705 +vt 0.946396 0.132628 +vt 0.938596 0.132628 +vt 0.946396 0.131362 +vt 0.946396 0.122076 +vt 0.938596 0.122076 +vt 0.938596 0.131362 +vt 0.946396 0.120809 +vt 0.946396 0.111523 +vt 0.938596 0.111523 +vt 0.938596 0.120809 +vt 0.922354 0.099705 +vt 0.930154 0.132628 +vt 0.930154 0.122076 +vt 0.930154 0.131362 +vt 0.930154 0.111523 +vt 0.930154 0.120809 +vt 0.252704 0.154588 +vt 0.258673 0.154588 +vt 0.922354 0.132628 +vt 0.922354 0.122076 +vt 0.922354 0.131362 +vt 0.922354 0.111523 +vt 0.922354 0.120809 +vt 0.252704 0.121664 +vt 0.258673 0.121664 +vt 0.252704 0.122931 +vt 0.252704 0.132217 +vt 0.258673 0.132217 +vt 0.258673 0.122931 +vt 0.252704 0.133483 +vt 0.252704 0.142769 +vt 0.258673 0.142769 +vt 0.258673 0.133483 +vt 0.266473 0.121664 +vt 0.266473 0.142769 +vt 0.266473 0.133483 +vt 0.274915 0.142769 +vt 0.274915 0.133483 +vt 0.282763 0.122234 +vt 0.274932 0.122234 +vt 0.282763 0.132829 +vt 0.274932 0.132829 +vt 0.282763 0.143424 +vt 0.274932 0.143424 +vt 0.282763 0.154018 +vt 0.274932 0.154018 +vt 0.288757 0.122234 +vt 0.288757 0.132829 +vt 0.288757 0.143424 +vt 0.288757 0.154018 +vt 0.245915 0.154072 +vt 0.251909 0.154072 +vt 0.245915 0.143477 +vt 0.251909 0.143477 +vt 0.245915 0.132882 +vt 0.251909 0.132882 +vt 0.245915 0.122287 +vt 0.251909 0.122287 +vt 0.238084 0.154072 +vt 0.238084 0.143477 +vt 0.238084 0.132882 +vt 0.238084 0.122287 +vt 0.229608 0.154072 +vt 0.229608 0.143477 +vt 0.229608 0.132882 +vt 0.229608 0.122287 +vt 0.221777 0.154072 +vt 0.221777 0.143477 +vt 0.221777 0.132882 +vt 0.221777 0.122287 +vt 0.215783 0.154072 +vt 0.215783 0.143477 +vt 0.215783 0.132882 +vt 0.215856 0.121718 +vt 0.215783 0.122287 +vt 0.794189 0.112770 +vt 0.802020 0.112770 +vt 0.794189 0.102176 +vt 0.802020 0.102176 +vt 0.794189 0.091581 +vt 0.802020 0.091581 +vt 0.794189 0.080986 +vt 0.802020 0.080986 +vt 0.785713 0.112771 +vt 0.785713 0.102176 +vt 0.785713 0.091581 +vt 0.785713 0.080986 +vt 0.777882 0.112771 +vt 0.777882 0.102176 +vt 0.777882 0.091581 +vt 0.777882 0.080986 +vt 0.938613 0.132059 +vt 0.946444 0.132059 +vt 0.938613 0.121464 +vt 0.946444 0.121464 +vt 0.938613 0.110869 +vt 0.946444 0.110869 +vt 0.938613 0.100274 +vt 0.946444 0.100274 +vt 0.930137 0.132059 +vt 0.930137 0.121464 +vt 0.930137 0.110869 +vt 0.930137 0.100274 +vt 0.922306 0.132059 +vt 0.922306 0.121464 +vt 0.922306 0.110869 +vt 0.922306 0.100274 +vt 0.258625 0.122234 +vt 0.252631 0.122234 +vt 0.258625 0.132829 +vt 0.252631 0.132829 +vt 0.258625 0.143424 +vt 0.252631 0.143424 +vt 0.258625 0.154018 +vt 0.252631 0.154018 +vt 0.266456 0.122234 +vt 0.266456 0.132829 +vt 0.266456 0.143424 +vt 0.266456 0.154018 +vt 0.678878 0.575822 +vt 0.688079 0.562057 +vt 0.682109 0.568025 +vt 0.695878 0.558827 +vt 0.678878 0.584263 +vt 0.704320 0.558827 +vt 0.682109 0.592060 +vt 0.712120 0.562057 +vt 0.688079 0.598028 +vt 0.695878 0.601258 +vt 0.718090 0.568025 +vt 0.704320 0.601258 +vt 0.721320 0.575822 +vt 0.712120 0.598028 +vt 0.721320 0.584263 +vt 0.718090 0.592060 +vn 0.4296 0.8713 0.2373 +vn -0.4151 0.4239 -0.8050 +vn -0.0237 0.8963 -0.4427 +vn 0.2289 0.8017 -0.5522 +vn -0.0766 0.2970 -0.9518 +vn 0.4901 0.6733 -0.5536 +vn 0.2736 0.1249 -0.9537 +vn 0.2735 0.1249 -0.9537 +vn 0.4901 0.6732 -0.5536 +vn 0.7203 0.5306 -0.4467 +vn 0.5821 -0.0662 -0.8104 +vn 0.8845 0.3954 -0.2476 +vn 0.8020 -0.2473 -0.5438 +vn 0.9574 0.2885 0.0131 +vn 0.8998 -0.3907 -0.1944 +vn 0.9281 0.2258 0.2959 +vn 0.8606 -0.4746 0.1847 +vn 0.8012 0.2172 0.5576 +vn 0.6904 -0.4863 0.5356 +vn 0.8012 0.2172 0.5577 +vn 0.5956 0.2637 0.7587 +vn 0.4151 -0.4239 0.8050 +vn 0.3432 0.3584 0.8682 +vn 0.0766 -0.2970 0.9518 +vn 0.0819 0.4868 0.8697 +vn -0.2735 -0.1249 0.9537 +vn -0.1484 0.6295 0.7627 +vn -0.5821 0.0662 0.8104 +vn -0.3125 0.7646 0.5637 +vn -0.8020 0.2473 0.5438 +vn -0.3854 0.8716 0.3031 +vn -0.8998 0.3907 0.1944 +vn -0.3854 0.8716 0.3030 +vn -0.3561 0.9342 0.0200 +vn -0.8606 0.4746 -0.1847 +vn -0.0586 0.7002 0.7115 +vn 0.1441 0.5747 0.8056 +vn -0.1483 0.6294 0.7628 +vn -0.2292 0.9429 -0.2416 +vn -0.6904 0.4863 -0.5356 +vn -0.0435 0.3629 -0.9308 +vn 0.3056 0.1913 -0.9327 +vn -0.8278 0.5356 -0.1673 +vn -0.8858 0.4191 -0.1992 +vn -0.7160 0.4308 -0.5494 +vn -0.6580 0.5472 -0.5173 +vn -0.8668 0.4518 0.2108 +vn -0.9249 0.3353 0.1791 +vn -0.7693 0.3088 0.5593 +vn -0.8273 0.1922 0.5279 +vn -0.9249 0.3353 0.1792 +vn -0.5499 0.1282 0.8253 +vn -0.6078 0.0115 0.7940 +vn -0.2422 -0.0625 0.9682 +vn -0.2999 -0.1793 0.9370 +vn 0.1071 -0.2341 0.9663 +vn 0.0496 -0.3511 0.9350 +vn 0.4447 -0.3607 0.8198 +vn 0.3874 -0.4777 0.7885 +vn 0.7193 -0.4230 0.5511 +vn 0.6621 -0.5399 0.5197 +vn 0.8890 -0.4113 0.2011 +vn 0.8320 -0.5283 0.1694 +vn 0.9281 -0.3276 -0.1770 +vn 0.8711 -0.4445 -0.2089 +vn 0.8305 -0.1845 -0.5255 +vn 0.7735 -0.3014 -0.5576 +vn 0.6112 -0.0039 -0.7915 +vn 0.5540 -0.1207 -0.8237 +vn 0.3035 0.1867 -0.9344 +vn 0.2461 0.0701 -0.9667 +vn -0.0458 0.3584 -0.9324 +vn -0.1034 0.2419 -0.9648 +vn -0.6555 0.5516 -0.5158 +vn -0.3810 0.4894 -0.7844 +vn -0.5959 -0.2637 -0.7586 +vn -0.3432 -0.3584 -0.8682 +vn 0.2736 0.1250 -0.9537 +vn -0.0819 -0.4868 -0.8697 +vn -0.0819 -0.4868 -0.8696 +vn 0.1481 -0.6293 -0.7629 +vn 0.3124 -0.7645 -0.5638 +vn 0.3854 -0.8716 -0.3031 +vn 0.3563 -0.9342 -0.0203 +vn 0.2292 -0.9429 0.2416 +vn 0.2292 -0.9429 0.2417 +vn 0.4151 -0.4240 0.8050 +vn 0.0237 -0.8964 0.4426 +vn -0.2288 -0.8017 0.5522 +vn -0.4901 -0.6733 0.5537 +vn -0.4901 -0.6732 0.5536 +vn -0.7202 -0.5307 0.4468 +vn -0.8844 -0.3956 0.2479 +vn -0.9574 -0.2885 -0.0129 +vn -0.9574 -0.2885 -0.0130 +vn -0.9282 -0.2259 -0.2956 +vn -0.8011 -0.2172 -0.5577 +vn 0.5966 0.3782 0.7078 +vn 0.3741 0.4616 0.8043 +vn 0.2288 0.8017 -0.5522 +vn -0.0237 0.8964 -0.4427 +vn 0.1441 0.5746 0.8056 +vn -0.0587 0.7002 0.7115 +vn -0.2032 0.8192 0.5363 +vn 0.8844 0.3955 -0.2478 +vn -0.2675 0.9135 0.3066 +vn 0.9574 0.2885 0.0129 +vn -0.2417 0.9686 0.0575 +vn 0.9282 0.2259 0.2958 +vn -0.1299 0.9763 -0.1730 +vn 0.8011 0.2172 0.5577 +vn 0.0510 0.9353 -0.3501 +vn 0.5957 0.2637 0.7587 +vn 0.2735 0.8519 -0.4466 +vn 0.5035 0.7389 -0.4478 +vn 0.0818 0.4868 0.8697 +vn 0.7063 0.6132 -0.3537 +vn -0.1483 0.6295 0.7627 +vn 0.8508 0.4943 -0.1785 +vn -0.3124 0.7645 0.5638 +vn 0.9151 0.4000 0.0512 +vn 0.8893 0.3448 0.3003 +vn -0.3562 0.9342 0.0202 +vn 0.7775 0.3372 0.5308 +vn -0.2292 0.9429 -0.2417 +vn 0.7065 0.6131 -0.3535 +vn 0.5036 0.7388 -0.4478 +vn 0.4901 0.6733 -0.5537 +vn 0.7203 0.5306 -0.4468 +vn -0.2032 0.8193 0.5361 +vn -0.3125 0.7646 0.5638 +vn 0.8509 0.4942 -0.1784 +vn 0.8845 0.3954 -0.2477 +vn -0.2675 0.9135 0.3065 +vn -0.3854 0.8715 0.3031 +vn 0.9151 0.4000 0.0513 +vn -0.2417 0.9686 0.0576 +vn 0.8893 0.3448 0.3002 +vn -0.1298 0.9763 -0.1731 +vn -0.2291 0.9429 -0.2418 +vn 0.7774 0.3372 0.5309 +vn 0.8011 0.2171 0.5578 +vn 0.0512 0.9353 -0.3502 +vn -0.0239 0.8964 -0.4426 +vn 0.3742 0.4615 0.8043 +vn 0.5965 0.3782 0.7080 +vn 0.5958 0.2637 0.7586 +vn 0.3432 0.3583 0.8682 +vn -0.3124 0.7646 0.5638 +vn -0.0238 0.8964 -0.4426 +vn -0.6621 0.5399 -0.5197 +vn -0.7193 0.4229 -0.5511 +vn -0.4447 0.3607 -0.8198 +vn -0.3874 0.4777 -0.7885 +vn -0.4468 0.3560 -0.8208 +vn -0.1093 0.2295 -0.9672 +vn -0.4412 0.3685 -0.8182 +vn -0.3834 0.4850 -0.7860 +vn 0.6132 0.0007 -0.7899 +vn 0.2398 0.0578 -0.9691 +vn -0.0496 0.3510 -0.9351 +vn -0.1071 0.2342 -0.9663 +vn 0.2422 0.0625 -0.9682 +vn 0.2999 0.1793 -0.9370 +vn -0.0478 0.3545 -0.9338 +vn -0.1051 0.2383 -0.9655 +vn 0.2443 0.0665 -0.9674 +vn 0.3016 0.1827 -0.9358 +vn 0.8325 -0.1798 -0.5240 +vn 0.5474 -0.1328 -0.8262 +vn 0.5499 -0.1282 -0.8253 +vn 0.6078 -0.0115 -0.7940 +vn 0.3016 0.1828 -0.9358 +vn 0.2443 0.0666 -0.9674 +vn 0.5521 -0.1242 -0.8245 +vn 0.6094 -0.0080 -0.7928 +vn 0.9300 -0.3228 -0.1756 +vn 0.7667 -0.3133 -0.5604 +vn 0.7693 -0.3088 -0.5593 +vn 0.8273 -0.1922 -0.5279 +vn 0.7715 -0.3048 -0.5584 +vn 0.8288 -0.1886 -0.5268 +vn 0.8910 -0.4065 0.2023 +vn 0.8642 -0.4563 -0.2120 +vn 0.8668 -0.4518 -0.2108 +vn 0.9249 -0.3353 -0.1791 +vn 0.8691 -0.4479 -0.2098 +vn 0.9264 -0.3317 -0.1781 +vn 0.7213 -0.4181 0.5522 +vn 0.8251 -0.5400 0.1659 +vn 0.8278 -0.5356 0.1673 +vn 0.8858 -0.4191 0.1992 +vn 0.8300 -0.5317 0.1684 +vn 0.8873 -0.4154 0.2001 +vn 0.4468 -0.3560 0.8208 +vn 0.6555 -0.5516 0.5158 +vn 0.6580 -0.5472 0.5173 +vn 0.7160 -0.4308 0.5494 +vn 0.6602 -0.5433 0.5186 +vn 0.7175 -0.4271 0.5502 +vn 0.1093 -0.2294 0.9672 +vn 0.3810 -0.4894 0.7844 +vn 0.7159 -0.4308 0.5494 +vn 0.3834 -0.4850 0.7860 +vn 0.4412 -0.3685 0.8182 +vn 0.3855 -0.4811 0.7873 +vn 0.4428 -0.3649 0.8190 +vn -0.2398 -0.0578 0.9691 +vn 0.0435 -0.3629 0.9308 +vn 0.0458 -0.3584 0.9324 +vn 0.1034 -0.2419 0.9648 +vn 0.0478 -0.3545 0.9338 +vn 0.1051 -0.2383 0.9655 +vn -0.5474 0.1328 0.8262 +vn -0.3056 -0.1913 0.9327 +vn -0.3035 -0.1867 0.9344 +vn -0.2461 -0.0701 0.9667 +vn -0.3016 -0.1827 0.9358 +vn -0.2443 -0.0665 0.9674 +vn -0.7667 0.3133 0.5604 +vn -0.3057 -0.1913 0.9327 +vn -0.6132 -0.0007 0.7899 +vn -0.6112 0.0039 0.7915 +vn -0.5540 0.1207 0.8237 +vn -0.2443 -0.0666 0.9674 +vn -0.6094 0.0080 0.7928 +vn -0.5521 0.1242 0.8245 +vn -0.8642 0.4563 0.2120 +vn -0.8325 0.1798 0.5240 +vn -0.8306 0.1845 0.5255 +vn -0.7735 0.3014 0.5576 +vn -0.8288 0.1886 0.5268 +vn -0.7715 0.3049 0.5584 +vn -0.8252 0.5400 -0.1659 +vn -0.9300 0.3228 0.1756 +vn -0.9281 0.3276 0.1770 +vn -0.8711 0.4445 0.2089 +vn -0.9264 0.3317 0.1781 +vn -0.8691 0.4479 0.2097 +vn -0.8910 0.4065 -0.2023 +vn -0.8890 0.4113 -0.2011 +vn -0.8320 0.5283 -0.1694 +vn -0.8691 0.4479 0.2098 +vn -0.8873 0.4155 -0.2001 +vn -0.8300 0.5317 -0.1684 +vn -0.7213 0.4181 -0.5522 +vn -0.7175 0.4271 -0.5502 +vn -0.6602 0.5434 -0.5185 +vn -0.4428 0.3649 -0.8190 +vn -0.3855 0.4811 -0.7873 +vn -0.0824 0.2852 -0.9549 +vn -0.4209 0.4121 -0.8081 +vn -0.0785 0.2932 -0.9528 +vn -0.4170 0.4200 -0.8060 +vn -0.0747 0.3009 -0.9507 +vn -0.4132 0.4278 -0.8039 +vn -0.0708 0.3088 -0.9485 +vn -0.4093 0.4357 -0.8017 +vn 0.2677 0.1132 -0.9568 +vn 0.2716 0.1210 -0.9548 +vn 0.2755 0.1288 -0.9526 +vn 0.2793 0.1366 -0.9504 +vn 0.5762 -0.0780 -0.8136 +vn 0.5801 -0.0701 -0.8115 +vn 0.5840 -0.0623 -0.8094 +vn 0.2754 0.1288 -0.9527 +vn 0.5878 -0.0545 -0.8072 +vn 0.2793 0.1367 -0.9504 +vn 0.7961 -0.2590 -0.5470 +vn 0.8000 -0.2512 -0.5449 +vn 0.8039 -0.2434 -0.5427 +vn 0.8077 -0.2355 -0.5405 +vn 0.8939 -0.4025 -0.1976 +vn 0.8978 -0.3946 -0.1954 +vn 0.9017 -0.3868 -0.1933 +vn 0.9055 -0.3789 -0.1911 +vn 0.8547 -0.4864 0.1814 +vn 0.8587 -0.4785 0.1836 +vn 0.8625 -0.4707 0.1857 +vn 0.8663 -0.4628 0.1879 +vn 0.6846 -0.4980 0.5323 +vn 0.6885 -0.4902 0.5345 +vn 0.6923 -0.4824 0.5366 +vn 0.7213 -0.4182 0.5522 +vn 0.6961 -0.4745 0.5387 +vn 0.4093 -0.4357 0.8017 +vn 0.4132 -0.4278 0.8039 +vn 0.4170 -0.4200 0.8060 +vn 0.4209 -0.4121 0.8081 +vn 0.6962 -0.4745 0.5387 +vn 0.0708 -0.3088 0.9485 +vn 0.0747 -0.3009 0.9507 +vn 0.0785 -0.2931 0.9528 +vn 0.0824 -0.2853 0.9549 +vn -0.2793 -0.1366 0.9504 +vn -0.2755 -0.1288 0.9526 +vn -0.2716 -0.1210 0.9548 +vn -0.2677 -0.1131 0.9568 +vn -0.5878 0.0545 0.8072 +vn -0.2793 -0.1367 0.9504 +vn -0.5840 0.0623 0.8094 +vn -0.5801 0.0701 0.8115 +vn -0.5762 0.0780 0.8136 +vn -0.2677 -0.1132 0.9568 +vn -0.8077 0.2355 0.5405 +vn -0.8039 0.2434 0.5427 +vn -0.8000 0.2512 0.5449 +vn -0.7961 0.2590 0.5470 +vn -0.9055 0.3789 0.1911 +vn -0.9017 0.3868 0.1933 +vn -0.8978 0.3946 0.1954 +vn -0.8939 0.4024 0.1975 +vn -0.8663 0.4628 -0.1879 +vn -0.9055 0.3789 0.1912 +vn -0.8625 0.4707 -0.1857 +vn -0.8587 0.4785 -0.1836 +vn -0.8547 0.4864 -0.1814 +vn -0.6961 0.4745 -0.5387 +vn -0.6923 0.4824 -0.5366 +vn -0.6885 0.4902 -0.5345 +vn -0.6845 0.4980 -0.5323 +vn -0.7203 -0.5306 0.4467 +vn -0.8844 -0.3955 0.2478 +vn -0.9282 -0.2259 -0.2958 +vn 0.0237 -0.8964 0.4427 +vn -0.5958 -0.2637 -0.7586 +vn -0.0818 -0.4868 -0.8696 +vn 0.3562 -0.9342 -0.0202 +vn 0.1484 -0.6295 -0.7627 +vn 0.3124 -0.7646 -0.5637 +usemtl Scene_-_Root +s off +f 22327/22111/15990 22331/22112/15990 22329/22113/15990 +f 22331/22112/15990 22327/22111/15990 22325/22114/15990 +f 22331/22112/15990 22325/22114/15990 22333/22115/15990 +f 22333/22115/15990 22325/22114/15990 22323/22116/15990 +f 22333/22115/15990 22323/22116/15990 22335/22117/15990 +f 22335/22117/15990 22323/22116/15990 22321/22118/15990 +f 22335/22117/15990 22321/22118/15990 22305/22119/15990 +f 22305/22119/15990 22321/22118/15990 22306/22120/15990 +f 22306/22120/15990 22321/22118/15990 22319/22121/15990 +f 22306/22120/15990 22319/22121/15990 22309/22122/15990 +f 22309/22122/15990 22319/22121/15990 22317/22123/15990 +f 22309/22122/15990 22317/22123/15990 22315/22124/15990 +f 22309/22122/15990 22315/22124/15990 22311/22125/15990 +f 22311/22125/15990 22315/22124/15990 22313/22126/15990 +s 1 +f 22111/22127/15991 22112/22128/15992 22113/22129/15993 +f 22111/22127/15991 22113/22129/15993 22114/22130/15994 +f 22114/22130/15994 22113/22129/15993 22115/22131/15995 +f 22114/22130/15994 22115/22131/15995 22116/22132/15996 +f 22117/22133/15997 22118/22134/15998 22119/22135/15999 +f 22117/22133/15997 22119/22135/15999 22120/22136/16000 +f 22120/22136/16000 22119/22135/15999 22121/22137/16001 +f 22120/22136/16000 22121/22137/16001 22122/22138/16002 +f 22122/22138/16002 22121/22137/16001 22123/22139/16003 +f 22122/22138/16002 22123/22139/16003 22124/22140/16004 +f 22124/22140/16004 22123/22139/16003 22125/22141/16005 +f 22124/22140/16004 22125/22141/16005 22126/22142/16006 +f 22126/22142/16006 22125/22141/16005 22127/22143/16007 +f 22126/22142/16006 22127/22143/16007 22128/22144/16008 +f 22129/22145/16008 22130/22146/16009 22131/22147/16010 +f 22129/22145/16008 22131/22147/16010 22132/22148/16011 +f 22132/22148/16011 22131/22147/16010 22133/22149/16012 +f 22132/22148/16011 22133/22149/16012 22134/22150/16013 +f 22134/22150/16013 22133/22149/16012 22135/22151/16014 +f 22134/22150/16013 22135/22151/16014 22136/22152/16015 +f 22137/22153/16015 22138/22154/16014 22139/22155/16016 +f 22137/22153/16015 22139/22155/16016 22140/22156/16017 +f 22140/22156/16017 22139/22155/16016 22141/22157/16018 +f 22140/22156/16017 22141/22157/16018 22142/22158/16019 +f 22142/22158/16019 22141/22157/16018 22143/22159/16020 +f 22142/22158/16019 22143/22159/16020 22144/22160/16021 +f 22145/22161/16021 22146/22162/16022 22147/22163/16023 +f 22145/22161/16021 22147/22163/16023 22148/22164/16024 +f 22149/22165/16025 22150/22166/16026 22151/22167/16014 +f 22149/22165/16025 22151/22167/16014 22152/22168/16027 +f 22148/22164/16024 22147/22163/16023 22153/22169/16028 +f 22148/22164/16024 22153/22169/16028 22154/22170/16029 +f 22154/22170/16029 22153/22169/16028 22112/22128/15992 +f 22154/22170/16029 22112/22128/15992 22111/22127/15991 +f 22155/22171/16030 22114/22130/15994 22116/22132/15996 +f 22155/22171/16030 22116/22132/15996 22156/22172/16031 +f 22157/22173/16032 22158/22174/16033 22159/22175/16034 +f 22157/22173/16032 22159/22175/16034 22160/22176/16035 +f 22161/22177/16036 22162/22178/16037 22158/22174/16033 +f 22161/22177/16036 22158/22174/16033 22157/22173/16032 +f 22163/22179/16038 22164/22180/16039 22165/22181/16040 +f 22163/22179/16038 22165/22181/16040 22166/22182/16036 +f 22167/22183/16041 22168/22184/16042 22164/22180/16039 +f 22167/22183/16041 22164/22180/16039 22163/22179/16038 +f 22169/22185/16043 22170/22186/16044 22168/22184/16042 +f 22169/22185/16043 22168/22184/16042 22167/22183/16041 +f 22171/22187/16045 22172/22188/16046 22173/22189/16044 +f 22171/22187/16045 22173/22189/16044 22174/22190/16043 +f 22175/22191/16047 22176/22192/16048 22172/22188/16046 +f 22175/22191/16047 22172/22188/16046 22171/22187/16045 +f 22177/22193/16049 22178/22194/16050 22176/22192/16048 +f 22177/22193/16049 22176/22192/16048 22175/22191/16047 +f 22179/22195/16051 22180/22196/16052 22181/22197/16050 +f 22179/22195/16051 22181/22197/16050 22182/22198/16049 +f 22183/22199/16053 22184/22200/16054 22180/22196/16052 +f 22183/22199/16053 22180/22196/16052 22179/22195/16051 +f 22185/22201/16055 22186/22202/16056 22184/22200/16054 +f 22185/22201/16055 22184/22200/16054 22183/22199/16053 +f 22187/22203/16057 22188/22204/16058 22186/22202/16056 +f 22187/22203/16057 22186/22202/16056 22185/22201/16055 +f 22189/22205/16059 22190/22206/16060 22188/22204/16058 +f 22189/22205/16059 22188/22204/16058 22187/22203/16057 +f 22191/22207/16061 22192/22208/16062 22193/22209/16060 +f 22191/22207/16061 22193/22209/16060 22194/22210/16059 +f 22195/22211/16063 22154/22170/16029 22111/22127/15991 +f 22195/22211/16063 22111/22127/15991 22196/22212/16064 +f 22197/22213/16065 22198/22214/15991 22199/22215/15994 +f 22197/22213/16065 22199/22215/15994 22200/22216/16066 +f 22200/22216/16066 22199/22215/15994 22201/22217/16067 +f 22200/22216/16066 22201/22217/16067 22202/22218/16068 +f 22203/22219/16069 22204/22220/15997 22205/22221/16000 +f 22203/22219/16069 22205/22221/16000 22206/22222/16070 +f 22206/22222/16070 22205/22221/16000 22207/22223/16002 +f 22206/22222/16070 22207/22223/16002 22208/22224/16071 +f 22208/22224/16071 22207/22223/16002 22209/22225/16004 +f 22208/22224/16071 22209/22225/16004 22210/22226/16072 +f 22210/22226/16072 22209/22225/16004 22211/22227/16006 +f 22210/22226/16072 22211/22227/16006 22212/22228/16073 +f 22212/22228/16073 22211/22227/16006 22213/22229/16008 +f 22212/22228/16073 22213/22229/16008 22214/22230/16074 +f 22215/22231/16075 22216/22232/16008 22217/22233/16076 +f 22215/22231/16075 22217/22233/16076 22218/22234/16077 +f 22218/22234/16077 22217/22233/16076 22219/22235/16013 +f 22218/22234/16077 22219/22235/16013 22220/22236/16078 +f 22220/22236/16078 22219/22235/16013 22221/22237/16015 +f 22220/22236/16078 22221/22237/16015 22222/22238/16079 +f 22223/22239/16080 22224/22240/16015 22225/22241/16017 +f 22223/22239/16080 22225/22241/16017 22226/22242/16081 +f 22226/22242/16081 22225/22241/16017 22227/22243/16019 +f 22226/22242/16081 22227/22243/16019 22228/22244/16082 +f 22228/22244/16082 22227/22243/16019 22229/22245/16021 +f 22228/22244/16082 22229/22245/16021 22230/22246/16083 +f 22231/22247/16084 22232/22248/16021 22233/22249/16024 +f 22231/22247/16084 22233/22249/16024 22234/22250/16085 +f 22234/22250/16085 22233/22249/16024 22235/22251/16029 +f 22234/22250/16085 22235/22251/16029 22236/22252/16086 +f 22236/22252/16086 22235/22251/16029 22198/22214/15991 +f 22236/22252/16086 22198/22214/15991 22197/22213/16065 +f 22237/22253/16087 22238/22254/16088 22239/22255/16089 +f 22237/22253/16087 22239/22255/16089 22240/22256/16090 +f 22238/22254/16088 22241/22257/16091 22242/22258/15998 +f 22238/22254/16088 22242/22258/15998 22239/22255/16089 +f 22241/22257/16091 22243/22259/16092 22244/22260/15999 +f 22241/22257/16091 22244/22260/15999 22242/22258/15998 +f 22243/22259/16092 22245/22261/16093 22246/22262/16094 +f 22243/22259/16092 22246/22262/16094 22244/22260/15999 +f 22245/22261/16093 22247/22263/16095 22248/22264/16096 +f 22245/22261/16093 22248/22264/16096 22246/22262/16094 +f 22247/22263/16095 22249/22265/16097 22250/22266/16098 +f 22247/22263/16095 22250/22266/16098 22248/22264/16096 +f 22249/22265/16097 22251/22267/16099 22252/22268/16100 +f 22249/22265/16097 22252/22268/16100 22250/22266/16098 +f 22251/22267/16099 22253/22269/16101 22254/22270/16102 +f 22251/22267/16099 22254/22270/16102 22252/22268/16100 +f 22253/22269/16101 22255/22271/16103 22256/22272/16012 +f 22253/22269/16101 22256/22272/16012 22254/22270/16102 +f 22255/22271/16103 22257/22273/16104 22258/22274/16105 +f 22255/22271/16103 22258/22274/16105 22256/22272/16012 +f 22257/22273/16104 22259/22275/16106 22260/22276/16107 +f 22257/22273/16104 22260/22276/16107 22258/22274/16105 +f 22259/22275/16106 22261/22277/16108 22262/22278/16109 +f 22259/22275/16106 22262/22278/16109 22260/22276/16107 +f 22261/22277/16108 22263/22279/16110 22264/22280/16020 +f 22261/22277/16108 22264/22280/16020 22262/22278/16109 +f 22263/22279/16110 22265/22281/16111 22266/22282/16112 +f 22263/22279/16110 22266/22282/16112 22264/22280/16020 +f 22265/22281/16111 22267/22283/16113 22268/22284/16114 +f 22265/22281/16111 22268/22284/16114 22266/22282/16112 +f 22267/22283/16113 22237/22253/16087 22240/22256/16090 +f 22267/22283/16113 22240/22256/16090 22268/22284/16114 +f 22269/22285/16115 22270/22286/16116 22271/22287/16117 +f 22269/22285/16115 22271/22287/16117 22272/22288/16118 +f 22273/22289/16119 22149/22165/16025 22152/22168/16027 +f 22273/22289/16119 22152/22168/16027 22274/22290/16120 +f 22275/22291/16121 22269/22285/16115 22272/22288/16118 +f 22275/22291/16121 22272/22288/16118 22276/22292/16122 +f 22277/22293/16123 22273/22289/16119 22274/22290/16120 +f 22277/22293/16123 22274/22290/16120 22278/22294/16124 +f 22279/22295/16125 22275/22291/16121 22276/22292/16122 +f 22279/22295/16125 22276/22292/16122 22280/22296/16096 +f 22281/22297/16126 22277/22293/16123 22278/22294/16124 +f 22281/22297/16126 22278/22294/16124 22282/22298/16112 +f 22283/22299/16127 22279/22295/16125 22280/22296/16096 +f 22283/22299/16127 22280/22296/16096 22284/22300/16098 +f 22285/22301/16128 22286/22302/16097 22287/22303/16112 +f 22285/22301/16128 22287/22303/16112 22288/22304/16129 +f 22289/22305/16130 22290/22306/16111 22291/22307/16098 +f 22289/22305/16130 22291/22307/16098 22292/22308/16131 +f 22293/22309/16132 22285/22301/16128 22288/22304/16129 +f 22293/22309/16132 22288/22304/16129 22294/22310/16133 +f 22295/22311/16134 22296/22312/16135 22297/22313/16136 +f 22295/22311/16134 22297/22313/16136 22298/22314/16137 +f 22296/22312/16135 22289/22305/16130 22292/22308/16131 +f 22296/22312/16135 22292/22308/16131 22297/22313/16136 +f 22299/22315/16103 22293/22309/16132 22294/22310/16133 +f 22299/22315/16103 22294/22310/16133 22300/22316/16089 +f 22301/22317/16026 22295/22311/16134 22298/22314/16137 +f 22301/22317/16026 22298/22314/16137 22302/22318/16014 +f 22303/22319/16116 22299/22315/16103 22300/22316/16089 +f 22303/22319/16116 22300/22316/16089 22304/22320/15998 +f 22305/22119/15990 22306/22120/15990 22307/22321/16012 +f 22305/22119/15990 22307/22321/16012 22308/22322/16102 +f 22306/22120/15990 22309/22122/15990 22310/22323/16014 +f 22306/22120/15990 22310/22323/16014 22307/22321/16012 +f 22309/22122/15990 22311/22125/15990 22312/22324/16016 +f 22309/22122/15990 22312/22324/16016 22310/22323/16014 +f 22311/22125/15990 22313/22126/15990 22314/22325/16138 +f 22311/22125/15990 22314/22325/16138 22312/22324/16016 +f 22313/22126/15990 22315/22124/15990 22316/22326/16020 +f 22313/22126/15990 22316/22326/16020 22314/22325/16138 +f 22315/22124/15990 22317/22123/15990 22318/22327/16112 +f 22315/22124/15990 22318/22327/16112 22316/22326/16020 +f 22317/22123/15990 22319/22121/15990 22320/22328/16114 +f 22317/22123/15990 22320/22328/16114 22318/22327/16112 +f 22319/22121/15990 22321/22118/15990 22322/22329/16139 +f 22319/22121/15990 22322/22329/16139 22320/22328/16114 +f 22321/22118/15990 22323/22116/15990 22324/22330/16089 +f 22321/22118/15990 22324/22330/16089 22322/22329/16139 +f 22323/22116/15990 22325/22114/15990 22326/22331/16117 +f 22323/22116/15990 22326/22331/16117 22324/22330/16089 +f 22325/22114/15990 22327/22111/15990 22328/22332/15999 +f 22325/22114/15990 22328/22332/15999 22326/22331/16117 +f 22327/22111/15990 22329/22113/15990 22330/22333/16094 +f 22327/22111/15990 22330/22333/16094 22328/22332/15999 +f 22329/22113/15990 22331/22112/15990 22332/22334/16096 +f 22329/22113/15990 22332/22334/16096 22330/22333/16094 +f 22331/22112/15990 22333/22115/15990 22334/22335/16098 +f 22331/22112/15990 22334/22335/16098 22332/22334/16096 +f 22333/22115/15990 22335/22117/15990 22336/22336/16009 +f 22333/22115/15990 22336/22336/16009 22334/22335/16098 +f 22335/22117/15990 22305/22119/15990 22308/22322/16102 +f 22335/22117/15990 22308/22322/16102 22336/22336/16009 +f 22337/22337/16140 22338/22338/16141 22339/22339/16142 +f 22337/22337/16140 22339/22339/16142 22340/22340/16143 +f 22198/22214/15991 22341/22341/16144 22342/22342/16145 +f 22198/22214/15991 22342/22342/16145 22199/22215/15994 +f 22160/22176/16035 22159/22175/16034 22343/22343/16146 +f 22160/22176/16035 22343/22343/16146 22344/22344/16147 +f 22196/22212/16064 22111/22127/15991 22114/22130/15994 +f 22196/22212/16064 22114/22130/15994 22155/22171/16030 +f 22345/22345/16031 22117/22133/15997 22120/22136/16000 +f 22345/22345/16031 22120/22136/16000 22346/22346/16148 +f 22199/22215/15994 22342/22342/16145 22347/22347/16149 +f 22199/22215/15994 22347/22347/16149 22201/22217/16067 +f 22348/22348/16150 22349/22349/16151 22350/22350/16152 +f 22348/22348/16150 22350/22350/16152 22351/22351/16153 +f 22352/22352/16154 22353/22353/16155 22354/22354/16156 +f 22352/22352/16154 22354/22354/16156 22355/22355/16157 +f 22346/22346/16148 22120/22136/16000 22122/22138/16002 +f 22346/22346/16148 22122/22138/16002 22356/22356/16158 +f 22204/22220/15997 22357/22357/16149 22358/22358/16159 +f 22204/22220/15997 22358/22358/16159 22205/22221/16000 +f 22359/22359/16153 22360/22360/16152 22361/22361/16160 +f 22359/22359/16153 22361/22361/16160 22362/22362/16161 +f 22363/22363/16162 22364/22364/16163 22365/22365/16164 +f 22363/22363/16162 22365/22365/16164 22366/22366/16165 +f 22356/22356/16158 22122/22138/16002 22124/22140/16004 +f 22356/22356/16158 22124/22140/16004 22367/22367/16166 +f 22205/22221/16000 22358/22358/16159 22368/22368/16167 +f 22205/22221/16000 22368/22368/16167 22207/22223/16002 +f 22362/22362/16161 22361/22361/16160 22369/22369/16168 +f 22362/22362/16161 22369/22369/16168 22370/22370/16169 +f 22366/22366/16165 22365/22365/16164 22371/22371/16170 +f 22366/22366/16165 22371/22371/16170 22372/22372/16171 +f 22367/22367/16166 22124/22140/16004 22126/22142/16006 +f 22367/22367/16166 22126/22142/16006 22373/22373/16172 +f 22207/22223/16002 22368/22368/16167 22374/22374/16173 +f 22207/22223/16002 22374/22374/16173 22209/22225/16004 +f 22370/22370/16169 22369/22369/16168 22375/22375/16174 +f 22370/22370/16169 22375/22375/16174 22376/22376/16175 +f 22372/22372/16171 22371/22371/16170 22377/22377/16176 +f 22372/22372/16171 22377/22377/16176 22378/22378/16177 +f 22379/22379/16172 22380/22380/16006 22129/22145/16008 +f 22379/22379/16172 22129/22145/16008 22381/22381/16178 +f 22209/22225/16004 22374/22374/16173 22382/22382/16179 +f 22209/22225/16004 22382/22382/16179 22211/22227/16006 +f 22376/22376/16175 22375/22375/16174 22383/22383/16180 +f 22376/22376/16175 22383/22383/16180 22384/22384/16181 +f 22378/22378/16177 22377/22377/16176 22385/22385/16182 +f 22378/22378/16177 22385/22385/16182 22386/22386/16183 +f 22381/22381/16178 22129/22145/16008 22132/22148/16011 +f 22381/22381/16178 22132/22148/16011 22387/22387/16184 +f 22211/22227/16006 22382/22382/16179 22388/22388/16185 +f 22211/22227/16006 22388/22388/16185 22213/22229/16008 +f 22384/22384/16181 22383/22383/16180 22389/22389/16186 +f 22384/22384/16181 22389/22389/16186 22390/22390/16187 +f 22386/22386/16183 22385/22385/16182 22391/22391/16188 +f 22386/22386/16183 22391/22391/16188 22392/22392/16189 +f 22387/22387/16184 22132/22148/16011 22134/22150/16013 +f 22387/22387/16184 22134/22150/16013 22393/22393/16190 +f 22216/22232/16008 22394/22394/16185 22395/22395/16191 +f 22216/22232/16008 22395/22395/16191 22217/22233/16076 +f 22396/22396/16192 22397/22397/16186 22398/22398/16193 +f 22396/22396/16192 22398/22398/16193 22399/22399/16194 +f 22400/22400/16189 22401/22401/16188 22402/22402/16195 +f 22400/22400/16189 22402/22402/16195 22403/22403/16196 +f 22393/22393/16190 22134/22150/16013 22136/22152/16015 +f 22393/22393/16190 22136/22152/16015 22404/22404/16197 +f 22217/22233/16076 22395/22395/16191 22405/22405/16198 +f 22217/22233/16076 22405/22405/16198 22219/22235/16013 +f 22399/22399/16194 22398/22398/16193 22406/22406/16199 +f 22399/22399/16194 22406/22406/16199 22407/22407/16200 +f 22403/22403/16196 22402/22402/16195 22408/22408/16201 +f 22403/22403/16196 22408/22408/16201 22409/22409/16202 +f 22410/22410/16197 22137/22153/16015 22140/22156/16017 +f 22410/22410/16197 22140/22156/16017 22411/22411/16203 +f 22219/22235/16013 22405/22405/16198 22412/22412/16204 +f 22219/22235/16013 22412/22412/16204 22221/22237/16015 +f 22407/22407/16200 22406/22406/16199 22413/22413/16205 +f 22407/22407/16200 22413/22413/16205 22414/22414/16206 +f 22409/22409/16202 22408/22408/16201 22415/22415/16207 +f 22409/22409/16202 22415/22415/16207 22416/22416/16208 +f 22411/22411/16203 22140/22156/16017 22142/22158/16019 +f 22411/22411/16203 22142/22158/16019 22417/22417/16209 +f 22224/22240/16015 22418/22418/16210 22419/22419/16211 +f 22224/22240/16015 22419/22419/16211 22225/22241/16017 +f 22420/22420/16206 22421/22421/16205 22422/22422/16212 +f 22420/22420/16206 22422/22422/16212 22423/22423/16213 +f 22424/22424/16214 22425/22425/16207 22426/22426/16215 +f 22424/22424/16214 22426/22426/16215 22427/22427/16216 +f 22417/22417/16209 22142/22158/16019 22144/22160/16021 +f 22417/22417/16209 22144/22160/16021 22428/22428/16217 +f 22225/22241/16017 22419/22419/16211 22429/22429/16218 +f 22225/22241/16017 22429/22429/16218 22227/22243/16019 +f 22423/22423/16213 22422/22422/16212 22430/22430/16219 +f 22423/22423/16213 22430/22430/16219 22431/22431/16220 +f 22427/22427/16216 22426/22426/16215 22432/22432/16221 +f 22427/22427/16216 22432/22432/16221 22433/22433/16222 +f 22434/22434/16217 22145/22161/16021 22148/22164/16024 +f 22434/22434/16217 22148/22164/16024 22435/22435/16223 +f 22227/22243/16019 22429/22429/16218 22436/22436/16224 +f 22227/22243/16019 22436/22436/16224 22229/22245/16021 +f 22431/22431/16220 22430/22430/16219 22437/22437/16225 +f 22431/22431/16220 22437/22437/16225 22438/22438/16226 +f 22433/22433/16222 22432/22432/16221 22439/22439/16227 +f 22433/22433/16222 22439/22439/16227 22440/22440/16228 +f 22435/22435/16223 22148/22164/16024 22154/22170/16029 +f 22435/22435/16223 22154/22170/16029 22195/22211/16063 +f 22232/22248/16021 22441/22441/16224 22442/22442/16229 +f 22232/22248/16021 22442/22442/16229 22233/22249/16024 +f 22443/22443/16226 22444/22444/16225 22445/22445/16230 +f 22443/22443/16226 22445/22445/16230 22446/22446/16231 +f 22447/22447/16232 22448/22448/16227 22449/22449/16233 +f 22447/22447/16232 22449/22449/16233 22450/22450/16234 +f 22233/22249/16024 22442/22442/16229 22451/22451/16235 +f 22233/22249/16024 22451/22451/16235 22235/22251/16029 +f 22446/22446/16231 22445/22445/16230 22338/22338/16141 +f 22446/22446/16231 22338/22338/16141 22337/22337/16140 +f 22450/22450/16234 22449/22449/16233 22452/22452/16236 +f 22450/22450/16234 22452/22452/16236 22453/22453/16237 +f 22340/22340/16143 22339/22339/16142 22349/22349/16151 +f 22340/22340/16143 22349/22349/16151 22348/22348/16150 +f 22453/22453/16237 22452/22452/16236 22454/22454/16238 +f 22453/22453/16237 22454/22454/16238 22455/22455/16239 +f 22455/22455/16239 22454/22454/16238 22353/22353/16155 +f 22455/22455/16239 22353/22353/16155 22352/22352/16154 +f 22344/22344/16147 22343/22343/16146 22192/22208/16062 +f 22344/22344/16147 22192/22208/16062 22191/22207/16061 +f 22340/22340/16143 22348/22348/16150 22456/22456/16240 +f 22340/22340/16143 22456/22456/16240 22457/22457/16241 +f 22457/22457/16241 22456/22456/16240 22342/22342/16145 +f 22457/22457/16241 22342/22342/16145 22341/22341/16144 +f 22455/22455/16239 22352/22352/16154 22458/22458/16242 +f 22455/22455/16239 22458/22458/16242 22459/22459/16243 +f 22459/22459/16243 22458/22458/16242 22349/22349/16151 +f 22459/22459/16243 22349/22349/16151 22339/22339/16142 +f 22344/22344/16147 22191/22207/16061 22460/22460/16244 +f 22344/22344/16147 22460/22460/16244 22461/22461/16245 +f 22461/22461/16245 22460/22460/16244 22353/22353/16155 +f 22461/22461/16245 22353/22353/16155 22454/22454/16238 +f 22196/22212/16064 22155/22171/16030 22462/22462/16246 +f 22196/22212/16064 22462/22462/16246 22463/22463/16247 +f 22463/22463/16247 22462/22462/16246 22192/22208/16062 +f 22463/22463/16247 22192/22208/16062 22343/22343/16146 +f 22348/22348/16150 22351/22351/16153 22464/22464/16248 +f 22348/22348/16150 22464/22464/16248 22456/22456/16240 +f 22456/22456/16240 22464/22464/16248 22347/22347/16149 +f 22456/22456/16240 22347/22347/16149 22342/22342/16145 +f 22352/22352/16154 22355/22355/16157 22465/22465/16249 +f 22352/22352/16154 22465/22465/16249 22458/22458/16242 +f 22458/22458/16242 22465/22465/16249 22350/22350/16152 +f 22458/22458/16242 22350/22350/16152 22349/22349/16151 +f 22191/22207/16061 22194/22210/16059 22466/22466/16250 +f 22191/22207/16061 22466/22466/16250 22460/22460/16244 +f 22460/22460/16244 22466/22466/16250 22354/22354/16156 +f 22460/22460/16244 22354/22354/16156 22353/22353/16155 +f 22155/22171/16030 22156/22172/16031 22467/22467/16251 +f 22155/22171/16030 22467/22467/16251 22462/22462/16246 +f 22462/22462/16246 22467/22467/16251 22193/22209/16060 +f 22462/22462/16246 22193/22209/16060 22192/22208/16062 +f 22359/22359/16153 22362/22362/16161 22468/22468/16252 +f 22359/22359/16153 22468/22468/16252 22469/22469/16248 +f 22469/22469/16248 22468/22468/16252 22358/22358/16159 +f 22469/22469/16248 22358/22358/16159 22357/22357/16149 +f 22363/22363/16162 22366/22366/16165 22470/22470/16253 +f 22363/22363/16162 22470/22470/16253 22471/22471/16249 +f 22471/22471/16249 22470/22470/16253 22361/22361/16160 +f 22471/22471/16249 22361/22361/16160 22360/22360/16152 +f 22189/22205/16059 22187/22203/16057 22472/22472/16254 +f 22189/22205/16059 22472/22472/16254 22473/22473/16255 +f 22473/22473/16255 22472/22472/16254 22365/22365/16164 +f 22473/22473/16255 22365/22365/16164 22364/22364/16163 +f 22345/22345/16031 22346/22346/16148 22474/22474/16256 +f 22345/22345/16031 22474/22474/16256 22475/22475/16257 +f 22475/22475/16257 22474/22474/16256 22188/22204/16058 +f 22475/22475/16257 22188/22204/16058 22190/22206/16060 +f 22362/22362/16161 22370/22370/16169 22476/22476/16258 +f 22362/22362/16161 22476/22476/16258 22468/22468/16252 +f 22468/22468/16252 22476/22476/16258 22368/22368/16167 +f 22468/22468/16252 22368/22368/16167 22358/22358/16159 +f 22366/22366/16165 22372/22372/16171 22477/22477/16259 +f 22366/22366/16165 22477/22477/16259 22470/22470/16253 +f 22470/22470/16253 22477/22477/16259 22369/22369/16168 +f 22470/22470/16253 22369/22369/16168 22361/22361/16160 +f 22187/22203/16057 22185/22201/16055 22478/22478/16260 +f 22187/22203/16057 22478/22478/16260 22472/22472/16254 +f 22472/22472/16254 22478/22478/16260 22371/22371/16170 +f 22472/22472/16254 22371/22371/16170 22365/22365/16164 +f 22346/22346/16148 22356/22356/16158 22479/22479/16261 +f 22346/22346/16148 22479/22479/16261 22474/22474/16256 +f 22474/22474/16256 22479/22479/16261 22186/22202/16056 +f 22474/22474/16256 22186/22202/16056 22188/22204/16058 +f 22370/22370/16169 22376/22376/16175 22480/22480/16262 +f 22370/22370/16169 22480/22480/16262 22476/22476/16258 +f 22476/22476/16258 22480/22480/16262 22374/22374/16173 +f 22476/22476/16258 22374/22374/16173 22368/22368/16167 +f 22372/22372/16171 22378/22378/16177 22481/22481/16263 +f 22372/22372/16171 22481/22481/16263 22477/22477/16259 +f 22477/22477/16259 22481/22481/16263 22375/22375/16174 +f 22477/22477/16259 22375/22375/16174 22369/22369/16168 +f 22185/22201/16055 22183/22199/16053 22482/22482/16264 +f 22185/22201/16055 22482/22482/16264 22478/22478/16260 +f 22478/22478/16260 22482/22482/16264 22377/22377/16176 +f 22478/22478/16260 22377/22377/16176 22371/22371/16170 +f 22356/22356/16158 22367/22367/16166 22483/22483/16265 +f 22356/22356/16158 22483/22483/16265 22479/22479/16261 +f 22479/22479/16261 22483/22483/16265 22184/22200/16054 +f 22479/22479/16261 22184/22200/16054 22186/22202/16056 +f 22376/22376/16175 22384/22384/16181 22484/22484/16266 +f 22376/22376/16175 22484/22484/16266 22480/22480/16262 +f 22480/22480/16262 22484/22484/16266 22382/22382/16179 +f 22480/22480/16262 22382/22382/16179 22374/22374/16173 +f 22378/22378/16177 22386/22386/16183 22485/22485/16267 +f 22378/22378/16177 22485/22485/16267 22481/22481/16263 +f 22481/22481/16263 22485/22485/16267 22383/22383/16180 +f 22481/22481/16263 22383/22383/16180 22375/22375/16174 +f 22183/22199/16053 22179/22195/16051 22486/22486/16268 +f 22183/22199/16053 22486/22486/16268 22482/22482/16264 +f 22482/22482/16264 22486/22486/16268 22385/22385/16182 +f 22482/22482/16264 22385/22385/16182 22377/22377/16176 +f 22367/22367/16166 22373/22373/16172 22487/22487/16269 +f 22367/22367/16166 22487/22487/16269 22483/22483/16265 +f 22483/22483/16265 22487/22487/16269 22180/22196/16052 +f 22483/22483/16265 22180/22196/16052 22184/22200/16054 +f 22384/22384/16181 22390/22390/16187 22488/22488/16270 +f 22384/22384/16181 22488/22488/16270 22484/22484/16266 +f 22484/22484/16266 22488/22488/16270 22388/22388/16185 +f 22484/22484/16266 22388/22388/16185 22382/22382/16179 +f 22386/22386/16183 22392/22392/16189 22489/22489/16271 +f 22386/22386/16183 22489/22489/16271 22485/22485/16267 +f 22485/22485/16267 22489/22489/16271 22389/22389/16186 +f 22485/22485/16267 22389/22389/16186 22383/22383/16180 +f 22179/22195/16051 22182/22198/16049 22490/22490/16272 +f 22179/22195/16051 22490/22490/16272 22486/22486/16268 +f 22486/22486/16268 22490/22490/16272 22391/22391/16188 +f 22486/22486/16268 22391/22391/16188 22385/22385/16182 +f 22373/22373/16172 22491/22491/16273 22492/22492/16274 +f 22373/22373/16172 22492/22492/16274 22487/22487/16269 +f 22487/22487/16269 22492/22492/16274 22181/22197/16050 +f 22487/22487/16269 22181/22197/16050 22180/22196/16052 +f 22396/22396/16192 22399/22399/16194 22493/22493/16275 +f 22396/22396/16192 22493/22493/16275 22494/22494/16270 +f 22494/22494/16270 22493/22493/16275 22395/22395/16191 +f 22494/22494/16270 22395/22395/16191 22394/22394/16185 +f 22400/22400/16189 22403/22403/16196 22495/22495/16276 +f 22400/22400/16189 22495/22495/16276 22496/22496/16271 +f 22496/22496/16271 22495/22495/16276 22398/22398/16193 +f 22496/22496/16271 22398/22398/16193 22397/22397/16186 +f 22177/22193/16049 22175/22191/16047 22497/22497/16277 +f 22177/22193/16049 22497/22497/16277 22498/22498/16272 +f 22498/22498/16272 22497/22497/16277 22402/22402/16195 +f 22498/22498/16272 22402/22402/16195 22401/22401/16188 +f 22381/22381/16178 22387/22387/16184 22499/22499/16278 +f 22381/22381/16178 22499/22499/16278 22500/22500/16279 +f 22500/22500/16279 22499/22499/16278 22176/22192/16048 +f 22500/22500/16279 22176/22192/16048 22178/22194/16050 +f 22399/22399/16194 22407/22407/16200 22501/22501/16280 +f 22399/22399/16194 22501/22501/16280 22493/22493/16275 +f 22493/22493/16275 22501/22501/16280 22405/22405/16198 +f 22493/22493/16275 22405/22405/16198 22395/22395/16191 +f 22403/22403/16196 22409/22409/16202 22502/22502/16281 +f 22403/22403/16196 22502/22502/16281 22495/22495/16276 +f 22495/22495/16276 22502/22502/16281 22406/22406/16199 +f 22495/22495/16276 22406/22406/16199 22398/22398/16193 +f 22175/22191/16047 22171/22187/16045 22503/22503/16282 +f 22175/22191/16047 22503/22503/16282 22497/22497/16277 +f 22497/22497/16277 22503/22503/16282 22408/22408/16201 +f 22497/22497/16277 22408/22408/16201 22402/22402/16195 +f 22387/22387/16184 22393/22393/16190 22504/22504/16283 +f 22387/22387/16184 22504/22504/16283 22499/22499/16278 +f 22499/22499/16278 22504/22504/16283 22172/22188/16046 +f 22499/22499/16278 22172/22188/16046 22176/22192/16048 +f 22407/22407/16200 22414/22414/16206 22505/22505/16284 +f 22407/22407/16200 22505/22505/16284 22501/22501/16280 +f 22501/22501/16280 22505/22505/16284 22412/22412/16204 +f 22501/22501/16280 22412/22412/16204 22405/22405/16198 +f 22409/22409/16202 22416/22416/16208 22506/22506/16285 +f 22409/22409/16202 22506/22506/16285 22502/22502/16281 +f 22502/22502/16281 22506/22506/16285 22413/22413/16205 +f 22502/22502/16281 22413/22413/16205 22406/22406/16199 +f 22171/22187/16045 22174/22190/16043 22507/22507/16286 +f 22171/22187/16045 22507/22507/16286 22503/22503/16282 +f 22503/22503/16282 22507/22507/16286 22415/22415/16207 +f 22503/22503/16282 22415/22415/16207 22408/22408/16201 +f 22393/22393/16190 22404/22404/16197 22508/22508/16287 +f 22393/22393/16190 22508/22508/16287 22504/22504/16283 +f 22504/22504/16283 22508/22508/16287 22173/22189/16044 +f 22504/22504/16283 22173/22189/16044 22172/22188/16046 +f 22420/22420/16206 22423/22423/16213 22509/22509/16288 +f 22420/22420/16206 22509/22509/16288 22510/22510/16289 +f 22510/22510/16289 22509/22509/16288 22419/22419/16211 +f 22510/22510/16289 22419/22419/16211 22418/22418/16210 +f 22424/22424/16214 22427/22427/16216 22511/22511/16290 +f 22424/22424/16214 22511/22511/16290 22512/22512/16285 +f 22512/22512/16285 22511/22511/16290 22422/22422/16212 +f 22512/22512/16285 22422/22422/16212 22421/22421/16205 +f 22169/22185/16043 22167/22183/16041 22513/22513/16291 +f 22169/22185/16043 22513/22513/16291 22514/22514/16286 +f 22514/22514/16286 22513/22513/16291 22426/22426/16215 +f 22514/22514/16286 22426/22426/16215 22425/22425/16207 +f 22410/22410/16197 22411/22411/16203 22515/22515/16292 +f 22410/22410/16197 22515/22515/16292 22516/22516/16293 +f 22516/22516/16293 22515/22515/16292 22168/22184/16042 +f 22516/22516/16293 22168/22184/16042 22170/22186/16044 +f 22423/22423/16213 22431/22431/16220 22517/22517/16294 +f 22423/22423/16213 22517/22517/16294 22509/22509/16288 +f 22509/22509/16288 22517/22517/16294 22429/22429/16218 +f 22509/22509/16288 22429/22429/16218 22419/22419/16211 +f 22427/22427/16216 22433/22433/16222 22518/22518/16295 +f 22427/22427/16216 22518/22518/16295 22511/22511/16290 +f 22511/22511/16290 22518/22518/16295 22430/22430/16219 +f 22511/22511/16290 22430/22430/16219 22422/22422/16212 +f 22167/22183/16041 22163/22179/16038 22519/22519/16296 +f 22167/22183/16041 22519/22519/16296 22513/22513/16291 +f 22513/22513/16291 22519/22519/16296 22432/22432/16221 +f 22513/22513/16291 22432/22432/16221 22426/22426/16215 +f 22411/22411/16203 22417/22417/16209 22520/22520/16297 +f 22411/22411/16203 22520/22520/16297 22515/22515/16292 +f 22515/22515/16292 22520/22520/16297 22164/22180/16039 +f 22515/22515/16292 22164/22180/16039 22168/22184/16042 +f 22431/22431/16220 22438/22438/16226 22521/22521/16298 +f 22431/22431/16220 22521/22521/16298 22517/22517/16294 +f 22517/22517/16294 22521/22521/16298 22436/22436/16224 +f 22517/22517/16294 22436/22436/16224 22429/22429/16218 +f 22433/22433/16222 22440/22440/16228 22522/22522/16299 +f 22433/22433/16222 22522/22522/16299 22518/22518/16295 +f 22518/22518/16295 22522/22522/16299 22437/22437/16225 +f 22518/22518/16295 22437/22437/16225 22430/22430/16219 +f 22163/22179/16038 22166/22182/16036 22523/22523/16300 +f 22163/22179/16038 22523/22523/16300 22519/22519/16296 +f 22519/22519/16296 22523/22523/16300 22439/22439/16227 +f 22519/22519/16296 22439/22439/16227 22432/22432/16221 +f 22417/22417/16209 22428/22428/16217 22524/22524/16301 +f 22417/22417/16209 22524/22524/16301 22520/22520/16297 +f 22520/22520/16297 22524/22524/16301 22165/22181/16040 +f 22520/22520/16297 22165/22181/16040 22164/22180/16039 +f 22443/22443/16226 22446/22446/16231 22525/22525/16302 +f 22443/22443/16226 22525/22525/16302 22526/22526/16303 +f 22526/22526/16303 22525/22525/16302 22442/22442/16229 +f 22526/22526/16303 22442/22442/16229 22441/22441/16224 +f 22447/22447/16232 22450/22450/16234 22527/22527/16304 +f 22447/22447/16232 22527/22527/16304 22528/22528/16299 +f 22528/22528/16299 22527/22527/16304 22445/22445/16230 +f 22528/22528/16299 22445/22445/16230 22444/22444/16225 +f 22161/22177/16036 22157/22173/16032 22529/22529/16305 +f 22161/22177/16036 22529/22529/16305 22530/22530/16300 +f 22530/22530/16300 22529/22529/16305 22449/22449/16233 +f 22530/22530/16300 22449/22449/16233 22448/22448/16227 +f 22434/22434/16217 22435/22435/16223 22531/22531/16306 +f 22434/22434/16217 22531/22531/16306 22532/22532/16301 +f 22532/22532/16301 22531/22531/16306 22158/22174/16033 +f 22532/22532/16301 22158/22174/16033 22162/22178/16037 +f 22446/22446/16231 22337/22337/16140 22533/22533/16307 +f 22446/22446/16231 22533/22533/16307 22525/22525/16302 +f 22525/22525/16302 22533/22533/16307 22451/22451/16235 +f 22525/22525/16302 22451/22451/16235 22442/22442/16229 +f 22450/22450/16234 22453/22453/16237 22534/22534/16308 +f 22450/22450/16234 22534/22534/16308 22527/22527/16304 +f 22527/22527/16304 22534/22534/16308 22338/22338/16141 +f 22527/22527/16304 22338/22338/16141 22445/22445/16230 +f 22157/22173/16032 22160/22176/16035 22535/22535/16309 +f 22157/22173/16032 22535/22535/16309 22529/22529/16305 +f 22529/22529/16305 22535/22535/16309 22452/22452/16236 +f 22529/22529/16305 22452/22452/16236 22449/22449/16233 +f 22435/22435/16223 22195/22211/16063 22536/22536/16310 +f 22435/22435/16223 22536/22536/16310 22531/22531/16306 +f 22531/22531/16306 22536/22536/16310 22159/22175/16034 +f 22531/22531/16306 22159/22175/16034 22158/22174/16033 +f 22337/22337/16140 22340/22340/16143 22457/22457/16241 +f 22337/22337/16140 22457/22457/16241 22533/22533/16307 +f 22533/22533/16307 22457/22457/16241 22341/22341/16144 +f 22533/22533/16307 22341/22341/16144 22451/22451/16235 +f 22453/22453/16237 22455/22455/16239 22459/22459/16243 +f 22453/22453/16237 22459/22459/16243 22534/22534/16308 +f 22534/22534/16308 22459/22459/16243 22339/22339/16142 +f 22534/22534/16308 22339/22339/16142 22338/22338/16141 +f 22160/22176/16035 22344/22344/16147 22461/22461/16245 +f 22160/22176/16035 22461/22461/16245 22535/22535/16309 +f 22535/22535/16309 22461/22461/16245 22454/22454/16238 +f 22535/22535/16309 22454/22454/16238 22452/22452/16236 +f 22195/22211/16063 22196/22212/16064 22463/22463/16247 +f 22195/22211/16063 22463/22463/16247 22536/22536/16310 +f 22536/22536/16310 22463/22463/16247 22343/22343/16146 +f 22536/22536/16310 22343/22343/16146 22159/22175/16034 +f 22235/22251/16029 22451/22451/16235 22341/22341/16144 +f 22235/22251/16029 22341/22341/16144 22198/22214/15991 +f 22550/22537/16083 22548/22538/16311 22549/22539/16312 +f 22548/22538/16311 22550/22537/16083 22547/22540/16079 +f 22547/22540/16079 22550/22537/16083 22551/22541/16313 +f 22547/22540/16079 22551/22541/16313 22546/22542/16078 +f 22546/22542/16078 22551/22541/16313 22552/22543/16086 +f 22546/22542/16078 22552/22543/16086 22545/22544/16314 +f 22545/22544/16314 22552/22543/16086 22537/22545/16315 +f 22545/22544/16314 22537/22545/16315 22538/22546/16066 +f 22545/22544/16314 22538/22546/16066 22544/22547/16075 +f 22544/22547/16075 22538/22546/16066 22539/22548/16316 +f 22544/22547/16075 22539/22548/16316 22543/22549/16317 +f 22543/22549/16317 22539/22548/16316 22540/22550/16318 +f 22543/22549/16317 22540/22550/16318 22542/22551/16072 +f 22542/22551/16072 22540/22550/16318 22541/22552/16319 +o Cube.038__0 +v 0.251580 0.306249 -0.208177 +v 0.089088 0.937895 -0.148656 +v -0.472178 0.798424 -0.200815 +v -0.309687 0.166778 -0.260335 +v 0.275377 0.326299 -0.355988 +v 0.112886 0.957946 -0.296468 +v 0.104085 0.942989 -0.161772 +v 0.266577 0.311343 -0.221293 +v 0.095223 0.968477 -0.296452 +v -0.466043 0.829006 -0.348611 +v -0.474844 0.814050 -0.213915 +v 0.086423 0.953521 -0.161757 +v -0.322799 0.164887 -0.276063 +v -0.485290 0.796533 -0.216543 +v -0.476490 0.811490 -0.351238 +v -0.313999 0.179843 -0.410759 +v -0.299001 0.184937 -0.423875 +v -0.461492 0.816584 -0.364355 +v 0.099774 0.956054 -0.312196 +v 0.262265 0.324408 -0.371717 +v -0.305137 0.154355 -0.276079 +v -0.306860 0.157331 -0.265494 +v -0.315320 0.157341 -0.267948 +v -0.316132 0.155993 -0.276615 +v -0.319349 0.164777 -0.265483 +v -0.315320 0.157341 -0.267948 +v -0.306860 0.157331 -0.265494 +v -0.316132 0.155993 -0.276615 +v -0.315320 0.157341 -0.267948 +v -0.319349 0.164777 -0.265483 +v -0.474453 0.808810 -0.204104 +v -0.481978 0.805182 -0.206901 +v -0.481840 0.796424 -0.205963 +v -0.483725 0.807473 -0.215226 +v -0.481978 0.805182 -0.206901 +v -0.474453 0.808810 -0.204104 +v -0.481840 0.796424 -0.205963 +v -0.481978 0.805182 -0.206901 +v -0.483725 0.807473 -0.215226 +v -0.296336 0.169312 -0.410774 +v -0.307331 0.170950 -0.411311 +v -0.305432 0.174147 -0.419297 +v -0.296726 0.174552 -0.420585 +v -0.309216 0.181999 -0.420574 +v -0.305432 0.174147 -0.419297 +v -0.307331 0.170950 -0.411311 +v -0.296726 0.174552 -0.420585 +v -0.305432 0.174147 -0.419297 +v -0.309216 0.181999 -0.420574 +v -0.464319 0.826031 -0.359196 +v -0.472089 0.821987 -0.358250 +v -0.474924 0.822429 -0.349921 +v -0.471707 0.813645 -0.361054 +v -0.472089 0.821987 -0.358250 +v -0.464319 0.826031 -0.359196 +v -0.474924 0.822429 -0.349921 +v -0.472089 0.821987 -0.358250 +v -0.471707 0.813645 -0.361054 +v 0.256130 0.293826 -0.223920 +v 0.265011 0.300404 -0.222610 +v 0.262175 0.300846 -0.214281 +v 0.254407 0.296802 -0.213335 +v 0.261794 0.309188 -0.211478 +v 0.262175 0.300846 -0.214281 +v 0.265011 0.300404 -0.222610 +v 0.254407 0.296802 -0.213335 +v 0.262175 0.300846 -0.214281 +v 0.261794 0.309188 -0.211478 +v 0.086813 0.948281 -0.151946 +v 0.095518 0.948685 -0.153234 +v 0.097418 0.951883 -0.161220 +v 0.099303 0.940834 -0.151957 +v 0.095518 0.948685 -0.153234 +v 0.086813 0.948281 -0.151946 +v 0.097418 0.951883 -0.161220 +v 0.095518 0.948685 -0.153234 +v 0.099303 0.940834 -0.151957 +v 0.264930 0.308783 -0.358616 +v 0.264540 0.314023 -0.368427 +v 0.272064 0.317651 -0.365630 +v 0.273812 0.315360 -0.357305 +v 0.271927 0.326409 -0.366569 +v 0.272064 0.317651 -0.365630 +v 0.264540 0.314023 -0.368427 +v 0.273812 0.315360 -0.357305 +v 0.272064 0.317651 -0.365630 +v 0.271927 0.326409 -0.366569 +v 0.106218 0.966839 -0.295916 +v 0.105407 0.965491 -0.304584 +v 0.096947 0.965502 -0.307037 +v 0.109436 0.958055 -0.307048 +v 0.105407 0.965491 -0.304584 +v 0.106218 0.966839 -0.295916 +v 0.096947 0.965502 -0.307037 +v 0.105407 0.965491 -0.304584 +v 0.109436 0.958055 -0.307048 +vt 0.754502 0.585958 +vt 0.754502 0.634387 +vt 0.797453 0.634387 +vt 0.797453 0.585958 +vt 0.985657 0.895285 +vt 0.985657 0.846856 +vt 0.975612 0.846856 +vt 0.975612 0.895285 +vt 0.852098 0.061283 +vt 0.852098 0.019069 +vt 0.842053 0.019069 +vt 0.842053 0.061283 +vt 0.985417 0.657488 +vt 0.985417 0.609058 +vt 0.975372 0.609058 +vt 0.975372 0.657488 +vt 0.100666 0.130046 +vt 0.100666 0.178475 +vt 0.143617 0.178475 +vt 0.143617 0.130046 +vt 0.202956 0.054396 +vt 0.202196 0.054338 +vt 0.202335 0.054923 +vt 0.202956 0.055086 +vt 0.798213 0.585958 +vt 0.798074 0.585337 +vt 0.797453 0.585198 +vt 0.985417 0.658248 +vt 0.986038 0.658109 +vt 0.986178 0.657488 +vt 0.797453 0.635148 +vt 0.798074 0.635008 +vt 0.798213 0.634387 +vt 0.842053 0.018379 +vt 0.841432 0.018542 +vt 0.841292 0.019127 +vt 0.986178 0.609058 +vt 0.986038 0.608438 +vt 0.985417 0.608298 +vt 0.213002 0.054396 +vt 0.213002 0.055086 +vt 0.213623 0.054923 +vt 0.213762 0.054338 +vt 0.974612 0.657488 +vt 0.974751 0.658109 +vt 0.975372 0.658248 +vt 0.100666 0.129286 +vt 0.100045 0.129425 +vt 0.099905 0.130046 +vt 0.852858 0.019127 +vt 0.852719 0.018542 +vt 0.852098 0.018379 +vt 0.099905 0.178475 +vt 0.100045 0.179096 +vt 0.100666 0.179236 +vt 0.975372 0.608298 +vt 0.974751 0.608438 +vt 0.974612 0.609058 +vt 0.202956 0.012182 +vt 0.202956 0.011376 +vt 0.202335 0.011488 +vt 0.202196 0.012124 +vt 0.974851 0.895285 +vt 0.974991 0.895906 +vt 0.975612 0.896045 +vt 0.754502 0.585198 +vt 0.753881 0.585337 +vt 0.753742 0.585958 +vt 0.841292 0.061341 +vt 0.841432 0.061977 +vt 0.842053 0.062089 +vt 0.753742 0.634387 +vt 0.753881 0.635008 +vt 0.754502 0.635148 +vt 0.975612 0.846095 +vt 0.974991 0.846235 +vt 0.974851 0.846856 +vt 0.213002 0.012182 +vt 0.213762 0.012124 +vt 0.213623 0.011488 +vt 0.213002 0.011376 +vt 0.144377 0.130046 +vt 0.144238 0.129425 +vt 0.143617 0.129286 +vt 0.985657 0.896045 +vt 0.986278 0.895906 +vt 0.986418 0.895285 +vt 0.852098 0.062089 +vt 0.852719 0.061977 +vt 0.852858 0.061341 +vt 0.986418 0.846856 +vt 0.986278 0.846235 +vt 0.985657 0.846095 +vt 0.143617 0.179236 +vt 0.144238 0.179096 +vt 0.144377 0.178475 +vn 0.1552 -0.2364 0.9592 +vn 0.0662 0.1096 0.9918 +vn -0.2806 0.0234 0.9595 +vn -0.1916 -0.3226 0.9269 +vn 0.9911 0.0791 -0.1073 +vn 0.9021 0.4251 -0.0747 +vn 0.8788 0.3856 0.2811 +vn 0.9678 0.0396 0.2485 +vn -0.0550 0.9958 -0.0739 +vn -0.4018 0.9096 -0.1061 +vn -0.4250 0.8701 0.2497 +vn -0.0782 0.9562 0.2819 +vn -0.9021 -0.4251 0.0747 +vn -0.9911 -0.0791 0.1073 +vn -0.9678 -0.0396 -0.2485 +vn -0.8788 -0.3856 -0.2811 +vn -0.0662 -0.1096 -0.9918 +vn -0.1552 0.2365 -0.9592 +vn 0.1916 0.3226 -0.9269 +vn 0.2806 -0.0234 -0.9595 +vn 0.0550 -0.9957 0.0739 +vn -0.0391 -0.7899 0.6120 +vn -0.4522 -0.7591 0.4683 +vn -0.5116 -0.8580 0.0453 +vn -0.6756 -0.4104 0.6125 +vn -0.6755 -0.4104 0.6125 +vn -0.3847 0.5536 0.7386 +vn -0.7387 0.3545 0.5732 +vn -0.7612 -0.0776 0.6439 +vn -0.8572 0.4854 0.1718 +vn -0.7387 0.3546 0.5732 +vn -0.7611 -0.0776 0.6439 +vn -0.8572 0.4855 0.1718 +vn 0.0782 -0.9562 -0.2819 +vn -0.4893 -0.8200 -0.2970 +vn -0.3774 -0.6319 -0.6770 +vn 0.0512 -0.6365 -0.7696 +vn -0.5852 -0.2570 -0.7691 +vn -0.3774 -0.6319 -0.6769 +vn -0.4892 -0.8201 -0.2970 +vn -0.5853 -0.2570 -0.7690 +vn -0.2944 0.7070 -0.6430 +vn -0.6639 0.4818 -0.5720 +vn -0.8349 0.5234 -0.1704 +vn -0.6709 0.0758 -0.7376 +vn -0.6639 0.4817 -0.5720 +vn -0.8348 0.5235 -0.1704 +vn -0.6709 0.0758 -0.7377 +vn 0.4018 -0.9096 0.1061 +vn 0.8349 -0.5234 0.1704 +vn 0.6639 -0.4817 0.5720 +vn 0.2945 -0.7070 0.6430 +vn 0.6709 -0.0758 0.7377 +vn 0.8348 -0.5235 0.1704 +vn -0.0512 0.6365 0.7696 +vn 0.3774 0.6319 0.6770 +vn 0.4893 0.8200 0.2970 +vn 0.5853 0.2570 0.7690 +vn 0.4892 0.8200 0.2970 +vn 0.3774 0.6319 0.6769 +vn 0.4250 -0.8701 -0.2497 +vn 0.3847 -0.5536 -0.7386 +vn 0.7387 -0.3546 -0.5732 +vn 0.8572 -0.4854 -0.1719 +vn 0.7612 0.0776 -0.6439 +vn 0.8572 -0.4855 -0.1719 +vn 0.5116 0.8580 -0.0453 +vn 0.4522 0.7591 -0.4683 +vn 0.0391 0.7899 -0.6120 +vn 0.6756 0.4104 -0.6125 +vn 0.4522 0.7591 -0.4682 +vn 0.6755 0.4104 -0.6125 +usemtl Scene_-_Root +s 1 +f 22553/22553/16320 22554/22554/16321 22555/22555/16322 +f 22553/22553/16320 22555/22555/16322 22556/22556/16323 +f 22557/22557/16324 22558/22558/16325 22559/22559/16326 +f 22557/22557/16324 22559/22559/16326 22560/22560/16327 +f 22561/22561/16328 22562/22562/16329 22563/22563/16330 +f 22561/22561/16328 22563/22563/16330 22564/22564/16331 +f 22565/22565/16332 22566/22566/16333 22567/22567/16334 +f 22565/22565/16332 22567/22567/16334 22568/22568/16335 +f 22569/22569/16336 22570/22570/16337 22571/22571/16338 +f 22569/22569/16336 22571/22571/16338 22572/22572/16339 +f 22573/22573/16340 22574/22574/16341 22575/22575/16342 +f 22573/22573/16340 22575/22575/16342 22576/22576/16343 +f 22556/22556/16323 22577/22577/16344 22578/22578/16342 +f 22556/22556/16323 22578/22578/16342 22579/22579/16341 +f 22565/22565/16332 22580/22580/16343 22581/22581/16342 +f 22565/22565/16332 22581/22581/16342 22582/22582/16345 +f 22555/22555/16322 22583/22583/16346 22584/22584/16347 +f 22555/22555/16322 22584/22584/16347 22585/22585/16348 +f 22563/22563/16330 22586/22586/16349 22587/22587/16350 +f 22563/22563/16330 22587/22587/16350 22588/22588/16346 +f 22566/22566/16333 22589/22589/16351 22590/22590/16350 +f 22566/22566/16333 22590/22590/16350 22591/22591/16352 +f 22592/22592/16353 22593/22593/16354 22594/22594/16355 +f 22592/22592/16353 22594/22594/16355 22595/22595/16356 +f 22568/22568/16335 22596/22596/16357 22597/22597/16358 +f 22568/22568/16335 22597/22597/16358 22598/22598/16359 +f 22569/22569/16336 22599/22599/16356 22600/22600/16358 +f 22569/22569/16336 22600/22600/16358 22601/22601/16360 +f 22562/22562/16329 22602/22602/16361 22603/22603/16362 +f 22562/22562/16329 22603/22603/16362 22604/22604/16363 +f 22570/22570/16337 22605/22605/16364 22606/22606/16365 +f 22570/22570/16337 22606/22606/16365 22607/22607/16361 +f 22567/22567/16334 22608/22608/16366 22609/22609/16365 +f 22567/22567/16334 22609/22609/16365 22610/22610/16367 +f 22611/22611/16368 22612/22612/16369 22613/22613/16370 +f 22611/22611/16368 22613/22613/16370 22614/22614/16371 +f 22560/22560/16327 22615/22615/16372 22616/22616/16370 +f 22560/22560/16327 22616/22616/16370 22617/22617/16373 +f 22553/22553/16320 22618/22618/16371 22619/22619/16370 +f 22553/22553/16320 22619/22619/16370 22620/22620/16372 +f 22564/22564/16331 22621/22621/16374 22622/22622/16375 +f 22564/22564/16331 22622/22622/16375 22623/22623/16376 +f 22554/22554/16321 22624/22624/16377 22625/22625/16375 +f 22554/22554/16321 22625/22625/16375 22626/22626/16374 +f 22559/22559/16326 22627/22627/16378 22628/22628/16379 +f 22559/22559/16326 22628/22628/16379 22629/22629/16377 +f 22630/22630/16380 22631/22631/16381 22632/22632/16382 +f 22630/22630/16380 22632/22632/16382 22633/22633/16383 +f 22572/22572/16339 22634/22634/16384 22635/22635/16382 +f 22572/22572/16339 22635/22635/16382 22636/22636/16381 +f 22557/22557/16324 22637/22637/16385 22638/22638/16382 +f 22557/22557/16324 22638/22638/16382 22639/22639/16384 +f 22561/22561/16328 22640/22640/16386 22641/22641/16387 +f 22561/22561/16328 22641/22641/16387 22642/22642/16388 +f 22558/22558/16325 22643/22643/16389 22644/22644/16390 +f 22558/22558/16325 22644/22644/16390 22645/22645/16386 +f 22571/22571/16338 22646/22646/16388 22647/22647/16387 +f 22571/22571/16338 22647/22647/16387 22648/22648/16391 +f 22592/22592/16353 22573/22573/16340 22576/22576/16343 +f 22592/22592/16353 22576/22576/16343 22593/22593/16354 +f 22598/22598/16359 22580/22580/16343 22565/22565/16332 +f 22598/22598/16359 22565/22565/16332 22568/22568/16335 +f 22556/22556/16323 22555/22555/16322 22585/22585/16348 +f 22556/22556/16323 22585/22585/16348 22577/22577/16344 +f 22582/22582/16345 22589/22589/16351 22566/22566/16333 +f 22582/22582/16345 22566/22566/16333 22565/22565/16332 +f 22563/22563/16330 22562/22562/16329 22604/22604/16363 +f 22563/22563/16330 22604/22604/16363 22586/22586/16349 +f 22591/22591/16352 22608/22608/16366 22567/22567/16334 +f 22591/22591/16352 22567/22567/16334 22566/22566/16333 +f 22570/22570/16337 22569/22569/16336 22601/22601/16360 +f 22570/22570/16337 22601/22601/16360 22605/22605/16364 +f 22610/22610/16367 22596/22596/16357 22568/22568/16335 +f 22610/22610/16367 22568/22568/16335 22567/22567/16334 +f 22630/22630/16380 22592/22592/16353 22595/22595/16356 +f 22630/22630/16380 22595/22595/16356 22631/22631/16381 +f 22636/22636/16381 22599/22599/16356 22569/22569/16336 +f 22636/22636/16381 22569/22569/16336 22572/22572/16339 +f 22562/22562/16329 22561/22561/16328 22642/22642/16388 +f 22562/22562/16329 22642/22642/16388 22602/22602/16361 +f 22607/22607/16361 22646/22646/16388 22571/22571/16338 +f 22607/22607/16361 22571/22571/16338 22570/22570/16337 +f 22558/22558/16325 22557/22557/16324 22639/22639/16384 +f 22558/22558/16325 22639/22639/16384 22643/22643/16389 +f 22648/22648/16391 22634/22634/16384 22572/22572/16339 +f 22648/22648/16391 22572/22572/16339 22571/22571/16338 +f 22611/22611/16368 22630/22630/16380 22633/22633/16383 +f 22611/22611/16368 22633/22633/16383 22612/22612/16369 +f 22617/22617/16373 22637/22637/16385 22557/22557/16324 +f 22617/22617/16373 22557/22557/16324 22560/22560/16327 +f 22561/22561/16328 22564/22564/16331 22623/22623/16376 +f 22561/22561/16328 22623/22623/16376 22640/22640/16386 +f 22645/22645/16386 22627/22627/16378 22559/22559/16326 +f 22645/22645/16386 22559/22559/16326 22558/22558/16325 +f 22554/22554/16321 22553/22553/16320 22620/22620/16372 +f 22554/22554/16321 22620/22620/16372 22624/22624/16377 +f 22629/22629/16377 22615/22615/16372 22560/22560/16327 +f 22629/22629/16377 22560/22560/16327 22559/22559/16326 +f 22573/22573/16340 22611/22611/16368 22614/22614/16371 +f 22573/22573/16340 22614/22614/16371 22574/22574/16341 +f 22579/22579/16341 22618/22618/16371 22553/22553/16320 +f 22579/22579/16341 22553/22553/16320 22556/22556/16323 +f 22564/22564/16331 22563/22563/16330 22588/22588/16346 +f 22564/22564/16331 22588/22588/16346 22621/22621/16374 +f 22626/22626/16374 22583/22583/16346 22555/22555/16322 +f 22626/22626/16374 22555/22555/16322 22554/22554/16321 +f 22592/22592/16353 22630/22630/16380 22611/22611/16368 +f 22592/22592/16353 22611/22611/16368 22573/22573/16340 +o Cube.039__0 +v 1.125683 1.004150 -0.618145 +v 1.125683 1.027713 -0.618145 +v 1.125683 1.027713 -0.603697 +v 1.125683 1.004150 -0.603697 +v 1.102119 1.004150 -0.603697 +v 1.125683 1.004150 -0.603697 +v 1.125683 1.004150 -0.546381 +v 1.102119 1.004150 -0.546381 +v 1.102119 1.004150 -0.618145 +v 1.125683 1.004150 -0.618145 +v 1.125683 1.027713 -0.618145 +v 1.102119 1.027713 -0.618145 +v 1.102119 1.027713 -0.603697 +v 1.125683 1.027713 -0.603697 +v 1.102119 1.004150 -0.603697 +v 1.102119 1.027713 -0.603697 +v 1.102119 1.027713 -0.618145 +v 1.102119 1.004150 -0.618145 +v 1.125683 1.027713 -0.546381 +v 1.102119 1.027713 -0.546381 +v 1.103652 1.027713 -0.534976 +v 1.124150 1.027713 -0.523353 +v 1.125683 1.027713 -0.546381 +v 1.125683 1.004150 -0.546381 +v 1.102119 1.004150 -0.546381 +v 1.102119 1.027713 -0.546381 +v 1.103652 1.004150 -0.534976 +v 1.124150 1.004150 -0.523353 +v 1.113296 1.004150 -0.505625 +v 1.097949 1.004150 -0.523505 +v 1.124150 1.027713 -0.523353 +v 1.124150 1.004150 -0.523353 +v 1.103652 1.004150 -0.534976 +v 1.103652 1.027713 -0.534976 +v 1.113296 1.027713 -0.505625 +v 1.097949 1.027713 -0.523505 +v 1.074131 1.027713 -0.502200 +v 1.082752 1.027713 -0.480270 +v 1.097949 1.004150 -0.523505 +v 1.097949 1.027713 -0.523505 +v 1.113296 1.027713 -0.505625 +v 1.113296 1.004150 -0.505625 +v 1.082752 1.004150 -0.480270 +v 1.082752 1.027713 -0.480270 +v 1.050016 1.027713 -0.467846 +v 1.050016 1.004150 -0.467846 +v 1.113296 1.004150 -0.505625 +v 1.113296 1.027713 -0.505625 +v 1.082752 1.004150 -0.480270 +v 1.074131 1.004150 -0.502200 +v 1.097949 1.027713 -0.523505 +v 1.097949 1.004150 -0.523505 +v 1.074131 1.004150 -0.502200 +v 1.074131 1.027713 -0.502200 +v 1.047468 1.004150 -0.491271 +v 1.050016 1.004150 -0.467846 +v 1.037408 1.004150 -0.466308 +v 1.037408 1.004150 -0.489733 +v 1.047468 1.004150 -0.491271 +v 1.047468 1.027713 -0.491271 +v 1.047468 1.027713 -0.491271 +v 1.050016 1.027713 -0.467846 +v 1.037408 1.004150 -0.489733 +v 1.037408 1.027713 -0.489733 +v 1.037408 1.027713 -0.489733 +v 1.037408 1.027713 -0.466308 +v 1.050016 1.004150 -0.467846 +v 1.050016 1.027713 -0.467846 +v 1.050016 1.027713 -0.422130 +v 1.050016 1.004150 -0.422130 +v 1.037408 0.998198 -0.344557 +v 1.050016 0.998198 -0.344557 +v 1.050016 0.990199 -0.268291 +v 1.037408 0.990199 -0.268291 +v 1.050016 1.004150 -0.422130 +v 1.037408 1.004150 -0.422130 +v 1.037408 1.027713 -0.422130 +v 1.050016 1.027713 -0.422130 +v 1.050016 0.980428 -0.196133 +v 1.037408 0.980428 -0.196133 +v 1.050016 0.998198 -0.344557 +v 1.050016 1.021761 -0.344557 +v 1.050016 1.013617 -0.265679 +v 1.050016 0.990199 -0.268291 +v 1.050016 1.021761 -0.344557 +v 1.037408 1.021761 -0.344557 +v 1.037408 1.013617 -0.265679 +v 1.050016 1.013617 -0.265679 +v 1.043480 0.967475 -0.138429 +v 1.030873 0.967475 -0.138233 +v 1.050016 1.003551 -0.191597 +v 1.050016 0.980428 -0.196133 +v 1.037408 1.003551 -0.191597 +v 1.050016 1.003551 -0.191597 +v 1.018337 0.990598 -0.133503 +v 1.018266 0.967475 -0.138037 +v 0.915238 0.967475 -0.134213 +v 0.915309 0.990598 -0.129679 +v 1.043551 0.990598 -0.133895 +v 1.043480 0.967475 -0.138429 +v 1.030943 0.990598 -0.133699 +v 1.043551 0.990598 -0.133895 +v 0.949133 1.004150 -0.618145 +v 0.949133 1.004150 -0.603697 +v 0.949133 1.027713 -0.603697 +v 0.949133 1.027713 -0.618145 +v 0.972697 1.004150 -0.603697 +v 0.972697 1.004150 -0.546381 +v 0.949133 1.004150 -0.546381 +v 0.949133 1.004150 -0.603697 +v 0.972697 1.004150 -0.618145 +v 0.949133 1.004150 -0.618145 +v 0.949133 1.027713 -0.618145 +v 0.949133 1.027713 -0.603697 +v 0.972697 1.027713 -0.603697 +v 0.972697 1.027713 -0.618145 +v 0.972697 1.004150 -0.603697 +v 0.972697 1.004150 -0.618145 +v 0.972697 1.027713 -0.618145 +v 0.972697 1.027713 -0.603697 +v 0.949133 1.027713 -0.546381 +v 0.950666 1.027713 -0.523353 +v 0.971164 1.027713 -0.534976 +v 0.972697 1.027713 -0.546381 +v 0.949133 1.004150 -0.546381 +v 0.949133 1.027713 -0.546381 +v 0.972697 1.027713 -0.546381 +v 0.972697 1.004150 -0.546381 +v 0.971164 1.004150 -0.534976 +v 0.976866 1.004150 -0.523505 +v 0.961519 1.004150 -0.505625 +v 0.950666 1.004150 -0.523353 +v 0.950666 1.004150 -0.523353 +v 0.950666 1.027713 -0.523353 +v 0.971164 1.027713 -0.534976 +v 0.971164 1.004150 -0.534976 +v 0.961519 1.027713 -0.505625 +v 0.992064 1.027713 -0.480270 +v 1.000685 1.027713 -0.502200 +v 0.976866 1.027713 -0.523505 +v 0.976866 1.027713 -0.523505 +v 0.976866 1.004150 -0.523505 +v 0.961519 1.004150 -0.505625 +v 0.961519 1.027713 -0.505625 +v 0.992064 1.004150 -0.480270 +v 1.024799 1.004150 -0.467846 +v 1.024799 1.027713 -0.467846 +v 0.992064 1.027713 -0.480270 +v 0.961519 1.004150 -0.505625 +v 0.961519 1.027713 -0.505625 +v 1.000685 1.004150 -0.502200 +v 0.992064 1.004150 -0.480270 +v 0.976866 1.027713 -0.523505 +v 1.000685 1.027713 -0.502200 +v 1.000685 1.004150 -0.502200 +v 0.976866 1.004150 -0.523505 +v 1.027347 1.004150 -0.491271 +v 1.024799 1.004150 -0.467846 +v 1.027347 1.027713 -0.491271 +v 1.027347 1.004150 -0.491271 +v 1.024799 1.027713 -0.467846 +v 1.027347 1.027713 -0.491271 +v 1.024799 1.004150 -0.467846 +v 1.024799 1.004150 -0.422130 +v 1.024799 1.027713 -0.422130 +v 1.024799 1.027713 -0.467846 +v 1.024799 0.990199 -0.268291 +v 1.024799 0.998198 -0.344557 +v 1.024799 1.004150 -0.422130 +v 1.024799 1.027713 -0.422130 +v 1.024799 0.980428 -0.196133 +v 1.024799 0.998198 -0.344557 +v 1.024799 0.990199 -0.268291 +v 1.024799 1.013617 -0.265679 +v 1.024799 1.021761 -0.344557 +v 1.024799 1.021761 -0.344557 +v 1.024799 1.013617 -0.265679 +v 1.018266 0.967475 -0.138037 +v 1.024799 0.980428 -0.196133 +v 1.024799 1.003551 -0.191597 +v 1.024799 1.003551 -0.191597 +v 1.018337 0.990598 -0.133503 +v 1.006043 0.985120 -0.114103 +v 1.024564 0.985120 -0.115132 +v 1.018266 0.967475 -0.138037 +v 1.018337 0.990598 -0.133503 +v 1.038211 0.961998 -0.121795 +v 1.035992 0.985120 -0.117839 +v 1.024564 0.985120 -0.115132 +v 1.024494 0.961998 -0.119666 +v 1.005973 0.961998 -0.118638 +v 1.006043 0.985120 -0.114103 +v 1.038211 0.961998 -0.121795 +v 1.024494 0.961998 -0.119666 +v 1.035992 0.985120 -0.117839 +v 1.038211 0.961998 -0.121795 +v 1.005973 0.961998 -0.118638 +v 1.035992 0.985120 -0.117839 +v 0.915514 0.961998 -0.116491 +v 0.915584 0.985120 -0.111956 +v 0.907225 0.985120 -0.111826 +v 0.907155 0.961998 -0.116361 +v 0.915514 0.961998 -0.116491 +v 0.915238 0.967475 -0.134213 +v 0.915309 0.990598 -0.129679 +v 0.915584 0.985120 -0.111956 +v 0.897825 0.994424 -0.111680 +v 0.897755 0.952523 -0.116215 +v 0.906950 0.990598 -0.129549 +v 0.907225 0.985120 -0.111826 +v 0.907155 0.961998 -0.116361 +v 0.906879 0.967475 -0.134084 +v 0.906879 0.967475 -0.134084 +v 0.906950 0.990598 -0.129549 +v 0.897480 0.952523 -0.133938 +v 0.897755 0.952523 -0.116215 +v 0.872324 0.952523 -0.115819 +v 0.872049 0.952523 -0.133542 +v 0.897550 0.996546 -0.129403 +v 0.897825 0.994424 -0.111680 +v 0.906879 0.967475 -0.134084 +v 0.907155 0.961998 -0.116361 +v 0.897755 0.952523 -0.116215 +v 0.897480 0.952523 -0.133938 +v 0.897480 0.952523 -0.133938 +v 0.897550 0.996546 -0.129403 +v 0.872324 0.952523 -0.115819 +v 0.872395 0.994424 -0.111285 +v 0.863359 0.985713 -0.114377 +v 0.863303 0.961036 -0.118008 +v 0.872049 0.952523 -0.133542 +v 0.872119 0.996546 -0.129008 +v 0.872119 0.996546 -0.129008 +v 0.872395 0.994424 -0.111285 +v 0.863171 0.986994 -0.126539 +v 0.863114 0.962316 -0.130172 +v 0.863303 0.961036 -0.118008 +v 0.863359 0.985713 -0.114377 +v 0.872395 0.994424 -0.111285 +v 0.872119 0.996546 -0.129008 +v 0.872049 0.952523 -0.133542 +v 0.872324 0.952523 -0.115819 +v 0.863114 0.962316 -0.130172 +v 0.863171 0.986994 -0.126539 +v 1.125683 1.004150 -0.632594 +v 1.125683 1.027713 -0.632594 +v 1.102119 1.004150 -0.632594 +v 1.102119 1.004150 -0.689909 +v 1.125683 1.004150 -0.689909 +v 1.125683 1.004150 -0.632594 +v 1.125683 1.027713 -0.632594 +v 1.102119 1.027713 -0.632594 +v 1.102119 1.004150 -0.632594 +v 1.102119 1.027713 -0.632594 +v 1.125683 1.027713 -0.689909 +v 1.124150 1.027713 -0.712938 +v 1.103652 1.027713 -0.701315 +v 1.102119 1.027713 -0.689909 +v 1.125683 1.004150 -0.689909 +v 1.125683 1.027713 -0.689909 +v 1.102119 1.027713 -0.689909 +v 1.102119 1.004150 -0.689909 +v 1.103652 1.004150 -0.701315 +v 1.097949 1.004150 -0.712785 +v 1.113296 1.004150 -0.730665 +v 1.124150 1.004150 -0.712938 +v 1.124150 1.004150 -0.712938 +v 1.124150 1.027713 -0.712938 +v 1.103652 1.027713 -0.701315 +v 1.103652 1.004150 -0.701315 +v 1.113296 1.027713 -0.730665 +v 1.082752 1.027713 -0.756020 +v 1.074131 1.027713 -0.734091 +v 1.097949 1.027713 -0.712785 +v 1.097949 1.027713 -0.712785 +v 1.097949 1.004150 -0.712785 +v 1.113296 1.004150 -0.730665 +v 1.113296 1.027713 -0.730665 +v 1.082752 1.004150 -0.756020 +v 1.050016 1.004150 -0.768445 +v 1.050016 1.027713 -0.768445 +v 1.082752 1.027713 -0.756020 +v 1.113296 1.004150 -0.730665 +v 1.113296 1.027713 -0.730665 +v 1.074131 1.004150 -0.734091 +v 1.082752 1.004150 -0.756020 +v 1.097949 1.027713 -0.712785 +v 1.074131 1.027713 -0.734091 +v 1.074131 1.004150 -0.734091 +v 1.097949 1.004150 -0.712785 +v 1.047468 1.004150 -0.745019 +v 1.037408 1.004150 -0.746558 +v 1.037408 1.004150 -0.769983 +v 1.050016 1.004150 -0.768445 +v 1.047468 1.027713 -0.745019 +v 1.047468 1.004150 -0.745019 +v 1.050016 1.027713 -0.768445 +v 1.047468 1.027713 -0.745019 +v 1.037408 1.027713 -0.746558 +v 1.037408 1.004150 -0.746558 +v 1.037408 1.027713 -0.769983 +v 1.037408 1.027713 -0.746558 +v 1.050016 1.004150 -0.768445 +v 1.050016 1.004150 -0.814161 +v 1.050016 1.027713 -0.814161 +v 1.050016 1.027713 -0.768445 +v 1.039251 0.998198 -0.843807 +v 1.039251 0.990199 -0.861087 +v 1.051860 0.990199 -0.861087 +v 1.051860 0.998198 -0.843807 +v 1.037408 1.004150 -0.814161 +v 1.050016 1.004150 -0.814161 +v 1.050016 1.027713 -0.814161 +v 1.037408 1.027713 -0.814161 +v 1.038568 0.980277 -0.881834 +v 1.051159 0.980481 -0.882468 +v 1.051860 0.998198 -0.843807 +v 1.051860 0.990199 -0.861087 +v 1.051860 1.013617 -0.863699 +v 1.051860 1.021761 -0.843807 +v 1.051860 1.021761 -0.843807 +v 1.051860 1.013617 -0.863699 +v 1.039251 1.013617 -0.863699 +v 1.039251 1.021761 -0.843807 +v 1.029517 0.969850 -0.898330 +v 1.042116 0.970021 -0.898771 +v 1.051159 0.980481 -0.882468 +v 1.050746 1.004033 -0.883095 +v 1.050746 1.004033 -0.883095 +v 1.038156 1.003829 -0.882460 +v 1.016574 0.993231 -0.898519 +v 0.913491 0.992198 -0.897104 +v 0.913833 0.968646 -0.896473 +v 1.016917 0.969678 -0.897889 +v 1.042116 0.970021 -0.898771 +v 1.041774 0.993573 -0.899401 +v 1.041774 0.993573 -0.899401 +v 1.029174 0.993402 -0.898960 +v 0.949133 1.027713 -0.632594 +v 0.949133 1.004150 -0.632594 +v 0.972697 1.004150 -0.632594 +v 0.949133 1.004150 -0.632594 +v 0.949133 1.004150 -0.689909 +v 0.972697 1.004150 -0.689909 +v 0.972697 1.027713 -0.632594 +v 0.949133 1.027713 -0.632594 +v 0.972697 1.004150 -0.632594 +v 0.972697 1.027713 -0.632594 +v 0.949133 1.027713 -0.689909 +v 0.972697 1.027713 -0.689909 +v 0.971164 1.027713 -0.701315 +v 0.950666 1.027713 -0.712938 +v 0.949133 1.027713 -0.689909 +v 0.949133 1.004150 -0.689909 +v 0.972697 1.004150 -0.689909 +v 0.972697 1.027713 -0.689909 +v 0.971164 1.004150 -0.701315 +v 0.950666 1.004150 -0.712938 +v 0.961519 1.004150 -0.730665 +v 0.976866 1.004150 -0.712785 +v 0.950666 1.027713 -0.712938 +v 0.950666 1.004150 -0.712938 +v 0.971164 1.004150 -0.701315 +v 0.971164 1.027713 -0.701315 +v 0.961519 1.027713 -0.730665 +v 0.976866 1.027713 -0.712785 +v 1.000685 1.027713 -0.734091 +v 0.992064 1.027713 -0.756020 +v 0.976866 1.004150 -0.712785 +v 0.976866 1.027713 -0.712785 +v 0.961519 1.027713 -0.730665 +v 0.961519 1.004150 -0.730665 +v 0.992064 1.004150 -0.756020 +v 0.992064 1.027713 -0.756020 +v 1.024799 1.027713 -0.768445 +v 1.024799 1.004150 -0.768445 +v 0.961519 1.004150 -0.730665 +v 0.961519 1.027713 -0.730665 +v 0.992064 1.004150 -0.756020 +v 1.000685 1.004150 -0.734091 +v 0.976866 1.027713 -0.712785 +v 0.976866 1.004150 -0.712785 +v 1.000685 1.004150 -0.734091 +v 1.000685 1.027713 -0.734091 +v 1.027347 1.004150 -0.745019 +v 1.024799 1.004150 -0.768445 +v 1.027347 1.004150 -0.745019 +v 1.027347 1.027713 -0.745019 +v 1.027347 1.027713 -0.745019 +v 1.024799 1.027713 -0.768445 +v 1.024799 1.004150 -0.768445 +v 1.024799 1.027713 -0.768445 +v 1.024799 1.027713 -0.814161 +v 1.024799 1.004150 -0.814161 +v 1.026643 0.998198 -0.843807 +v 1.026643 0.990199 -0.861087 +v 1.024799 1.004150 -0.814161 +v 1.024799 1.027713 -0.814161 +v 1.025977 0.980074 -0.881199 +v 1.026643 0.998198 -0.843807 +v 1.026643 1.021761 -0.843807 +v 1.026643 1.013617 -0.863699 +v 1.026643 0.990199 -0.861087 +v 1.026643 1.021761 -0.843807 +v 1.026643 1.013617 -0.863699 +v 1.016917 0.969678 -0.897889 +v 1.025565 1.003625 -0.881826 +v 1.025977 0.980074 -0.881199 +v 1.025565 1.003625 -0.881826 +v 1.021875 0.990969 -0.917835 +v 1.003326 0.990839 -0.917916 +v 1.016574 0.993231 -0.898519 +v 1.016574 0.993231 -0.898519 +v 1.016917 0.969678 -0.897889 +v 1.036026 0.967286 -0.915798 +v 1.022217 0.967416 -0.917204 +v 1.021875 0.990969 -0.917835 +v 1.033428 0.990705 -0.915743 +v 1.003668 0.967287 -0.917286 +v 1.003326 0.990839 -0.917916 +v 1.022217 0.967416 -0.917204 +v 1.036026 0.967286 -0.915798 +v 1.036026 0.967286 -0.915798 +v 1.033428 0.990705 -0.915743 +v 1.003668 0.967287 -0.917286 +v 1.033428 0.990705 -0.915743 +v 0.913223 0.966180 -0.914851 +v 0.904869 0.966067 -0.914558 +v 0.904527 0.989619 -0.915188 +v 0.912881 0.989733 -0.915481 +v 0.913833 0.968646 -0.896473 +v 0.913223 0.966180 -0.914851 +v 0.912881 0.989733 -0.915481 +v 0.913491 0.992198 -0.897104 +v 0.895547 0.956597 -0.915803 +v 0.895061 0.998666 -0.913315 +v 0.904527 0.989619 -0.915188 +v 0.905136 0.992084 -0.896811 +v 0.905479 0.968532 -0.896181 +v 0.904869 0.966067 -0.914558 +v 0.905136 0.992084 -0.896811 +v 0.905479 0.968532 -0.896181 +v 0.896198 0.953660 -0.898335 +v 0.870782 0.953315 -0.897445 +v 0.870130 0.956251 -0.914913 +v 0.895547 0.956597 -0.915803 +v 0.895061 0.998666 -0.913315 +v 0.895697 0.997821 -0.895494 +v 0.905479 0.968532 -0.896181 +v 0.896198 0.953660 -0.898335 +v 0.895547 0.956597 -0.915803 +v 0.904869 0.966067 -0.914558 +v 0.895697 0.997821 -0.895494 +v 0.896198 0.953660 -0.898335 +v 0.870130 0.956251 -0.914913 +v 0.861172 0.964137 -0.910890 +v 0.860851 0.989073 -0.910372 +v 0.869645 0.998321 -0.912425 +v 0.870281 0.997476 -0.894605 +v 0.870782 0.953315 -0.897445 +v 0.869645 0.998321 -0.912425 +v 0.870281 0.997476 -0.894605 +v 0.861288 0.988321 -0.898171 +v 0.860851 0.989073 -0.910372 +v 0.861172 0.964137 -0.910890 +v 0.861610 0.963384 -0.898690 +v 0.869645 0.998321 -0.912425 +v 0.870281 0.997476 -0.894605 +v 0.870782 0.953315 -0.897445 +v 0.870130 0.956251 -0.914913 +v 0.861288 0.988321 -0.898171 +v 0.861610 0.963384 -0.898690 +vt 0.940260 0.573902 +vt 0.940076 0.575635 +vt 0.941009 0.575746 +vt 0.595218 0.077789 +vt 0.596145 0.079411 +vt 0.596151 0.077678 +vt 0.941748 0.573898 +vt 0.941004 0.574014 +vt 0.597083 0.077795 +vt 0.596161 0.074412 +vt 0.940212 0.555138 +vt 0.940955 0.555023 +vt 0.940951 0.553291 +vt 0.595147 0.100017 +vt 0.596069 0.103401 +vt 0.596080 0.100134 +vt 0.941700 0.555135 +vt 0.941884 0.553402 +vt 0.597013 0.100023 +vt 0.596085 0.098402 +vt 0.672422 0.178947 +vt 0.674165 0.178947 +vt 0.674165 0.177878 +vt 0.672422 0.177878 +vt 0.936196 0.565599 +vt 0.934453 0.565604 +vt 0.934464 0.569842 +vt 0.936207 0.569837 +vt 0.936193 0.564531 +vt 0.934451 0.564535 +vt 0.589586 0.088885 +vt 0.591329 0.088891 +vt 0.591332 0.087823 +vt 0.589589 0.087817 +vt 0.983463 0.478891 +vt 0.985206 0.478891 +vt 0.985206 0.477823 +vt 0.983463 0.477823 +vt 0.589603 0.083579 +vt 0.591345 0.083584 +vt 0.591235 0.082741 +vt 0.589721 0.081876 +vt 0.674165 0.173640 +vt 0.672422 0.173640 +vt 0.983463 0.483129 +vt 0.985206 0.483129 +vt 0.936096 0.570681 +vt 0.934582 0.571545 +vt 0.935388 0.572853 +vt 0.936520 0.571528 +vt 0.674165 0.171939 +vt 0.672422 0.171939 +vt 0.983463 0.483974 +vt 0.985206 0.483974 +vt 0.590528 0.080568 +vt 0.591659 0.081894 +vt 0.593426 0.080324 +vt 0.592793 0.078700 +vt 0.983463 0.484816 +vt 0.985206 0.484816 +vt 0.674165 0.170641 +vt 0.672422 0.170641 +vt 0.962708 0.732749 +vt 0.960971 0.732821 +vt 0.961007 0.735233 +vt 0.962744 0.735161 +vt 0.962744 0.730505 +vt 0.961007 0.730577 +vt 0.937652 0.574722 +vt 0.938286 0.573099 +vt 0.929111 0.418064 +vt 0.930852 0.418060 +vt 0.930782 0.416232 +vt 0.929041 0.416235 +vt 0.930746 0.414227 +vt 0.929005 0.414230 +vt 0.595401 0.079522 +vt 0.930741 0.413478 +vt 0.929000 0.413482 +vt 0.186422 0.015986 +vt 0.184692 0.015775 +vt 0.184283 0.019130 +vt 0.186013 0.019341 +vt 0.941032 0.584747 +vt 0.940100 0.584750 +vt 0.940114 0.590387 +vt 0.941047 0.590385 +vt 0.940085 0.579015 +vt 0.941017 0.579013 +vt 0.595228 0.074409 +vt 0.940129 0.595720 +vt 0.941061 0.595718 +vt 0.185756 0.025088 +vt 0.184026 0.024877 +vt 0.183918 0.030739 +vt 0.185661 0.030757 +vt 0.595246 0.068674 +vt 0.596179 0.068677 +vt 0.596198 0.062846 +vt 0.595265 0.062843 +vt 0.940623 0.599982 +vt 0.941556 0.599994 +vt 0.183994 0.036267 +vt 0.185733 0.036141 +vt 0.596215 0.057371 +vt 0.595282 0.057368 +vt 0.629387 0.785149 +vt 0.631110 0.785157 +vt 0.631103 0.777533 +vt 0.629379 0.777526 +vt 0.184430 0.040610 +vt 0.186168 0.040484 +vt 0.596707 0.053094 +vt 0.595774 0.053106 +vt 0.070602 0.139672 +vt 0.070602 0.140740 +vt 0.072344 0.140740 +vt 0.072344 0.139672 +vt 0.945769 0.565575 +vt 0.945780 0.569813 +vt 0.947523 0.569808 +vt 0.947512 0.565570 +vt 0.945766 0.564506 +vt 0.947509 0.564502 +vt 0.602644 0.088927 +vt 0.602648 0.087858 +vt 0.600905 0.087853 +vt 0.600902 0.088921 +vt 0.360794 0.071735 +vt 0.360794 0.072803 +vt 0.362537 0.072803 +vt 0.362537 0.071735 +vt 0.602661 0.083620 +vt 0.602553 0.081917 +vt 0.601034 0.082771 +vt 0.600918 0.083615 +vt 0.070602 0.144978 +vt 0.072344 0.144978 +vt 0.362537 0.067497 +vt 0.360794 0.067497 +vt 0.945896 0.570656 +vt 0.945476 0.571505 +vt 0.946615 0.572824 +vt 0.947414 0.571511 +vt 0.070602 0.146682 +vt 0.072344 0.146682 +vt 0.362537 0.066655 +vt 0.360794 0.066655 +vt 0.601755 0.080603 +vt 0.599501 0.078721 +vt 0.598858 0.080341 +vt 0.600615 0.081922 +vt 0.362537 0.065801 +vt 0.360794 0.065801 +vt 0.070602 0.148005 +vt 0.072345 0.148005 +vt 0.960900 0.732953 +vt 0.960935 0.730523 +vt 0.959198 0.730454 +vt 0.959162 0.732884 +vt 0.960935 0.735233 +vt 0.959198 0.735163 +vt 0.943718 0.573085 +vt 0.944360 0.574705 +vt 0.929111 0.409119 +vt 0.929041 0.410809 +vt 0.930782 0.410806 +vt 0.930852 0.409115 +vt 0.941941 0.575630 +vt 0.929005 0.412744 +vt 0.930746 0.412740 +vt 0.596889 0.079527 +vt 0.530464 0.041648 +vt 0.530091 0.038289 +vt 0.528358 0.038482 +vt 0.528732 0.041841 +vt 0.941980 0.590382 +vt 0.941965 0.584745 +vt 0.941950 0.579011 +vt 0.597093 0.074414 +vt 0.941994 0.595715 +vt 0.529894 0.032540 +vt 0.529858 0.026870 +vt 0.528115 0.026869 +vt 0.528162 0.032732 +vt 0.597112 0.068680 +vt 0.597130 0.062849 +vt 0.942489 0.600006 +vt 0.529986 0.021487 +vt 0.528250 0.021343 +vt 0.597148 0.057374 +vt 0.597639 0.053083 +vt 0.598553 0.051653 +vt 0.597183 0.051724 +vt 0.530464 0.017120 +vt 0.528728 0.016975 +vt 0.750773 0.002089 +vt 0.749047 0.002253 +vt 0.749034 0.003096 +vt 0.750763 0.003101 +vt 0.750759 0.004470 +vt 0.749030 0.004465 +vt 0.941017 0.601210 +vt 0.942032 0.601365 +vt 0.184689 0.041830 +vt 0.186422 0.041748 +vt 0.943402 0.601437 +vt 0.596337 0.051922 +vt 0.750755 0.011158 +vt 0.749026 0.011152 +vt 0.749026 0.011770 +vt 0.750755 0.011776 +vt 0.950093 0.601579 +vt 0.950110 0.600270 +vt 0.605261 0.052824 +vt 0.605245 0.051515 +vt 0.748340 0.012466 +vt 0.751455 0.012469 +vt 0.605879 0.052816 +vt 0.605863 0.051507 +vt 0.950711 0.601587 +vt 0.950728 0.600278 +vt 0.631103 0.776915 +vt 0.629379 0.776908 +vt 0.501260 0.774879 +vt 0.502571 0.774879 +vt 0.502571 0.772998 +vt 0.501260 0.772998 +vt 0.606574 0.052806 +vt 0.606558 0.051496 +vt 0.458731 0.772827 +vt 0.459136 0.774138 +vt 0.459836 0.774138 +vt 0.459836 0.772827 +vt 0.632208 0.776219 +vt 0.628940 0.776213 +vt 0.751455 0.014350 +vt 0.748340 0.014346 +vt 0.748999 0.015016 +vt 0.750838 0.015019 +vt 0.632208 0.774339 +vt 0.628940 0.774333 +vt 0.608455 0.052783 +vt 0.608439 0.051473 +vt 0.577355 0.775433 +vt 0.577435 0.773591 +vt 0.576530 0.773589 +vt 0.576450 0.775431 +vt 0.576279 0.776097 +vt 0.577599 0.776118 +vt 0.577599 0.772846 +vt 0.576295 0.772980 +vt 0.631473 0.773669 +vt 0.629638 0.773663 +vt 0.672422 0.180015 +vt 0.674165 0.180015 +vt 0.936191 0.563462 +vt 0.936180 0.559224 +vt 0.934437 0.559229 +vt 0.934448 0.563467 +vt 0.589582 0.089954 +vt 0.591325 0.089959 +vt 0.983463 0.476755 +vt 0.985206 0.476755 +vt 0.589569 0.094192 +vt 0.589677 0.095895 +vt 0.591196 0.095041 +vt 0.591312 0.094198 +vt 0.672422 0.184253 +vt 0.674165 0.184253 +vt 0.985206 0.472517 +vt 0.983463 0.472517 +vt 0.936064 0.558381 +vt 0.936484 0.557532 +vt 0.935345 0.556212 +vt 0.934546 0.557525 +vt 0.672422 0.185957 +vt 0.674165 0.185957 +vt 0.985206 0.471675 +vt 0.983463 0.471675 +vt 0.590476 0.097209 +vt 0.592729 0.099091 +vt 0.593372 0.097471 +vt 0.591615 0.095890 +vt 0.985206 0.470821 +vt 0.983463 0.470821 +vt 0.672422 0.187280 +vt 0.674165 0.187280 +vt 0.849167 0.876998 +vt 0.849191 0.879376 +vt 0.850932 0.879325 +vt 0.850908 0.876947 +vt 0.849191 0.874822 +vt 0.850932 0.874771 +vt 0.938242 0.555952 +vt 0.937600 0.554332 +vt 0.929381 0.541698 +vt 0.929273 0.539922 +vt 0.927534 0.539923 +vt 0.927642 0.541700 +vt 0.940019 0.553407 +vt 0.929217 0.537943 +vt 0.927479 0.537944 +vt 0.595341 0.098286 +vt 0.929210 0.537198 +vt 0.927471 0.537199 +vt 0.885328 0.663768 +vt 0.884473 0.660498 +vt 0.882786 0.660939 +vt 0.883642 0.664209 +vt 0.940801 0.547830 +vt 0.940798 0.546550 +vt 0.939865 0.546553 +vt 0.939868 0.547833 +vt 0.940943 0.550024 +vt 0.940010 0.550026 +vt 0.595137 0.103398 +vt 0.940845 0.545013 +vt 0.939913 0.544969 +vt 0.884344 0.658268 +vt 0.884593 0.656883 +vt 0.882868 0.657134 +vt 0.882658 0.658709 +vt 0.594994 0.105591 +vt 0.594989 0.107064 +vt 0.595922 0.107067 +vt 0.595926 0.105594 +vt 0.941511 0.543789 +vt 0.940579 0.543758 +vt 0.884888 0.655170 +vt 0.883191 0.655566 +vt 0.595067 0.108501 +vt 0.595998 0.108457 +vt 0.626055 0.773672 +vt 0.626039 0.781293 +vt 0.627774 0.781286 +vt 0.627790 0.773664 +vt 0.885328 0.653799 +vt 0.883631 0.654194 +vt 0.595727 0.109712 +vt 0.596659 0.109682 +vt 0.072344 0.138604 +vt 0.070602 0.138604 +vt 0.945764 0.563438 +vt 0.947506 0.563433 +vt 0.947496 0.559195 +vt 0.945753 0.559199 +vt 0.600898 0.089990 +vt 0.602641 0.089995 +vt 0.360794 0.073871 +vt 0.362537 0.073871 +vt 0.602628 0.094233 +vt 0.600885 0.094228 +vt 0.600995 0.095072 +vt 0.602509 0.095936 +vt 0.072344 0.134366 +vt 0.070602 0.134366 +vt 0.360794 0.078109 +vt 0.362537 0.078109 +vt 0.945864 0.558356 +vt 0.947378 0.557492 +vt 0.946572 0.556184 +vt 0.945440 0.557509 +vt 0.072344 0.132665 +vt 0.070602 0.132665 +vt 0.360794 0.078954 +vt 0.362537 0.078954 +vt 0.601702 0.097244 +vt 0.600571 0.095918 +vt 0.598804 0.097488 +vt 0.599437 0.099112 +vt 0.360794 0.079796 +vt 0.362537 0.079796 +vt 0.072345 0.131366 +vt 0.070602 0.131366 +vt 0.360794 0.063231 +vt 0.362535 0.063272 +vt 0.362558 0.060814 +vt 0.360817 0.060772 +vt 0.360817 0.065571 +vt 0.362558 0.065612 +vt 0.944308 0.554314 +vt 0.943674 0.555938 +vt 0.929381 0.532745 +vt 0.927642 0.532746 +vt 0.927534 0.534492 +vt 0.929273 0.534491 +vt 0.927479 0.536456 +vt 0.929217 0.536455 +vt 0.596830 0.098290 +vt 0.591888 0.113396 +vt 0.590203 0.112948 +vt 0.589334 0.116215 +vt 0.591018 0.116663 +vt 0.941733 0.547828 +vt 0.941730 0.546548 +vt 0.941875 0.550021 +vt 0.597002 0.103404 +vt 0.941776 0.545058 +vt 0.590880 0.118892 +vt 0.589196 0.118444 +vt 0.589400 0.120021 +vt 0.591123 0.120279 +vt 0.596859 0.105597 +vt 0.596854 0.107070 +vt 0.942443 0.543819 +vt 0.589769 0.121507 +vt 0.591465 0.121910 +vt 0.596930 0.108413 +vt 0.597194 0.111080 +vt 0.598566 0.111091 +vt 0.597591 0.109652 +vt 0.590192 0.122907 +vt 0.591888 0.123309 +vt 0.310841 0.015168 +vt 0.310824 0.014152 +vt 0.309085 0.014153 +vt 0.309108 0.015000 +vt 0.310817 0.012782 +vt 0.309079 0.012783 +vt 0.942048 0.542391 +vt 0.941027 0.542497 +vt 0.885203 0.652523 +vt 0.883528 0.652963 +vt 0.943420 0.542381 +vt 0.596340 0.110923 +vt 0.310810 0.006092 +vt 0.310810 0.005474 +vt 0.309072 0.005475 +vt 0.309072 0.006093 +vt 0.950068 0.543904 +vt 0.950110 0.542544 +vt 0.605257 0.110932 +vt 0.605216 0.109572 +vt 0.311506 0.004780 +vt 0.308389 0.004779 +vt 0.605875 0.110912 +vt 0.605834 0.109552 +vt 0.950686 0.543923 +vt 0.950728 0.542564 +vt 0.626039 0.781911 +vt 0.627774 0.781903 +vt 0.502597 0.772995 +vt 0.502597 0.774876 +vt 0.503890 0.774879 +vt 0.503890 0.772998 +vt 0.606575 0.110774 +vt 0.606532 0.109456 +vt 0.458709 0.772822 +vt 0.457596 0.772822 +vt 0.457614 0.774133 +vt 0.458321 0.774138 +vt 0.625601 0.782603 +vt 0.628874 0.782603 +vt 0.311506 0.002899 +vt 0.310902 0.002232 +vt 0.309057 0.002233 +vt 0.308389 0.002898 +vt 0.625601 0.784482 +vt 0.628874 0.784481 +vt 0.608455 0.110714 +vt 0.608413 0.109396 +vt 0.588034 0.085143 +vt 0.587130 0.085146 +vt 0.587210 0.086988 +vt 0.588114 0.086986 +vt 0.586944 0.084472 +vt 0.588264 0.084450 +vt 0.588264 0.087723 +vt 0.586960 0.087589 +vt 0.626287 0.785157 +vt 0.628130 0.785153 +vn -0.1811 -0.7348 -0.6537 +vn 0.4205 -0.8596 0.2902 +vn 0.0000 -1.0000 0.0000 +vn 0.4205 0.8596 0.2902 +vn 0.0000 0.7428 -0.6695 +vn 0.0000 1.0000 0.0000 +vn 0.1812 -0.7348 -0.6537 +vn 0.0000 -0.7428 -0.6695 +vn -0.4205 0.8596 0.2902 +vn -0.0000 0.9993 0.0382 +vn -0.1812 -0.7348 0.6537 +vn -0.0000 -0.7428 0.6695 +vn 0.4205 0.8596 -0.2902 +vn 0.0000 0.9951 -0.0989 +vn 0.1811 -0.7348 0.6537 +vn -0.4205 -0.8596 -0.2902 +vn -0.4205 0.8596 -0.2902 +vn -0.0000 0.7428 0.6695 +vn 0.7071 -0.7071 0.0000 +vn 0.7071 0.7071 -0.0000 +vn -0.7071 -0.7071 0.0000 +vn 0.7140 -0.6997 0.0237 +vn -0.7199 -0.6924 0.0481 +vn -0.7071 0.7071 -0.0000 +vn 0.7140 0.6997 0.0237 +vn -0.7199 0.6924 0.0481 +vn -0.6181 0.7794 -0.1022 +vn 0.7184 0.6571 0.2284 +vn -0.7199 -0.6924 0.0483 +vn -0.6181 -0.7794 -0.1022 +vn 0.7184 -0.6571 0.2284 +vn 0.5598 -0.6721 0.4847 +vn -0.5241 -0.7521 -0.3995 +vn 0.7184 -0.6571 0.2286 +vn -0.6181 0.7794 -0.1021 +vn 0.5598 0.6721 0.4847 +vn -0.5241 0.7521 -0.3995 +vn -0.3526 0.7473 -0.5632 +vn 0.3730 0.6719 0.6399 +vn 0.3731 -0.6719 0.6398 +vn 0.3728 0.6720 0.6399 +vn 0.4206 0.8596 0.2902 +vn 0.4206 -0.8596 0.2902 +vn 0.3730 -0.6719 0.6399 +vn -0.3526 -0.7473 -0.5632 +vn -0.5242 0.7521 -0.3995 +vn -0.5242 -0.7521 -0.3995 +vn -0.3527 0.7473 -0.5631 +vn -0.1812 -0.7348 -0.6537 +vn -0.1811 -0.7347 -0.6537 +vn -0.1813 0.7348 -0.6537 +vn -0.1811 0.7348 -0.6537 +vn 0.0000 -0.7428 -0.6696 +vn -0.0000 0.7428 -0.6696 +vn 0.4205 -0.8596 0.2903 +vn 0.4205 0.8596 0.2903 +vn 0.6986 0.7150 0.0274 +vn 0.7158 -0.6978 -0.0267 +vn 0.0000 -0.9959 -0.0904 +vn 0.7103 -0.7011 -0.0636 +vn 0.7105 -0.6987 -0.0839 +vn 0.0000 -0.9929 -0.1193 +vn 0.0000 -0.9993 -0.0383 +vn -0.0000 0.9993 0.0384 +vn 0.7268 -0.6821 -0.0812 +vn -0.0008 -0.9843 -0.1765 +vn 0.7042 0.7072 0.0636 +vn 0.7035 0.7057 0.0843 +vn 0.0000 0.9960 0.0896 +vn 0.0000 0.9929 0.1187 +vn 0.7239 -0.6899 0.0034 +vn -0.0112 -0.9662 -0.2576 +vn 0.7094 0.6859 0.1620 +vn 0.7267 -0.6821 -0.0813 +vn 0.0005 0.9843 0.1767 +vn -0.3196 0.9420 -0.1021 +vn -0.3097 -0.7742 -0.5519 +vn -0.0219 -0.5172 -0.8556 +vn -0.0141 0.8593 -0.5112 +vn 0.7032 0.6275 0.3344 +vn 0.0146 0.9653 0.2607 +vn 0.7199 -0.6924 0.0481 +vn -0.7140 -0.6997 0.0237 +vn -0.7140 0.6997 0.0237 +vn -0.7184 0.6571 0.2284 +vn 0.6181 0.7794 -0.1022 +vn 0.7199 0.6924 0.0481 +vn 0.7199 0.6924 0.0483 +vn 0.6181 -0.7794 -0.1022 +vn 0.5241 -0.7521 -0.3995 +vn -0.5598 -0.6721 0.4847 +vn -0.7184 -0.6571 0.2284 +vn -0.7184 -0.6571 0.2283 +vn -0.5598 0.6721 0.4847 +vn -0.3730 0.6719 0.6399 +vn 0.3526 0.7473 -0.5632 +vn 0.5241 0.7521 -0.3995 +vn 0.5242 0.7521 -0.3995 +vn 0.5242 -0.7521 -0.3995 +vn -0.3730 -0.6719 0.6398 +vn -0.4206 -0.8596 0.2902 +vn -0.4206 0.8596 0.2902 +vn -0.3731 0.6720 0.6397 +vn 0.3526 -0.7473 -0.5632 +vn -0.3730 -0.6719 0.6399 +vn -0.4205 -0.8596 0.2902 +vn 0.1809 0.7348 -0.6537 +vn 0.1813 -0.7347 -0.6537 +vn 0.1811 0.7348 -0.6537 +vn -0.4205 -0.8596 0.2903 +vn -0.7158 -0.6978 -0.0267 +vn -0.6986 0.7150 0.0274 +vn -0.4205 0.8596 0.2903 +vn -0.7105 -0.6987 -0.0839 +vn -0.7103 -0.7011 -0.0636 +vn -0.7040 -0.6911 -0.1633 +vn -0.7035 0.7057 0.0843 +vn -0.7042 0.7072 0.0636 +vn -0.7035 0.7057 0.0842 +vn -0.6831 0.7244 0.0928 +vn 0.0327 0.5147 0.8567 +vn 0.0951 0.5021 0.8596 +vn -0.3097 -0.7743 -0.5519 +vn 0.5248 -0.7299 0.4379 +vn 0.4967 0.4469 0.7440 +vn 0.0801 -0.8438 0.5306 +vn 0.0221 -0.8522 0.5227 +vn 0.5249 -0.7299 0.4379 +vn 0.0094 -0.8562 0.5165 +vn 0.0175 0.5144 0.8574 +vn 0.1838 0.3838 0.9049 +vn 0.3061 -0.6733 0.6730 +vn 0.0094 -0.8563 0.5165 +vn 0.2730 0.6484 0.7107 +vn 0.3380 -0.7435 0.5770 +vn 0.1955 0.7464 -0.6362 +vn 0.1839 0.3838 0.9049 +vn 0.3060 -0.6733 0.6730 +vn 0.1603 -0.3306 -0.9301 +vn 0.1955 0.7464 -0.6361 +vn 0.3391 -0.6646 -0.6658 +vn 0.3381 -0.7435 0.5769 +vn -0.3120 -0.7279 0.6106 +vn -0.3507 -0.6576 -0.6668 +vn 0.2215 0.7947 -0.5651 +vn 0.1604 -0.3305 -0.9301 +vn -0.3237 0.6180 0.7165 +vn -0.7964 0.2200 0.5633 +vn -0.8013 -0.3485 0.4863 +vn -0.3506 -0.6576 -0.6668 +vn -0.3335 0.7579 -0.5607 +vn -0.3237 0.6179 0.7165 +vn -0.8203 0.3472 -0.4544 +vn -0.8175 -0.2191 -0.5326 +vn -0.7964 0.2199 0.5633 +vn -0.3238 0.6179 0.7165 +vn -0.8175 -0.2190 -0.5327 +vn -0.7199 -0.6924 -0.0481 +vn 0.7140 -0.6997 -0.0237 +vn 0.7140 0.6997 -0.0237 +vn 0.7184 0.6571 -0.2284 +vn -0.6181 0.7794 0.1022 +vn -0.7199 0.6924 -0.0481 +vn -0.6181 -0.7794 0.1022 +vn -0.5241 -0.7521 0.3995 +vn 0.5598 -0.6721 -0.4847 +vn 0.7184 -0.6571 -0.2284 +vn 0.7184 -0.6571 -0.2283 +vn 0.5598 0.6721 -0.4847 +vn 0.3730 0.6719 -0.6399 +vn -0.3526 0.7473 0.5632 +vn -0.5241 0.7521 0.3995 +vn 0.3729 -0.6719 -0.6399 +vn 0.4206 -0.8596 -0.2902 +vn 0.4206 0.8596 -0.2902 +vn 0.3731 0.6720 -0.6397 +vn -0.3526 -0.7473 0.5632 +vn 0.3730 -0.6719 -0.6399 +vn -0.5242 0.7521 0.3995 +vn -0.5242 -0.7521 0.3995 +vn 0.4205 -0.8596 -0.2902 +vn -0.1811 0.7348 0.6537 +vn -0.1813 -0.7347 0.6537 +vn 0.0000 0.7428 0.6696 +vn -0.0000 -0.7428 0.6696 +vn 0.4205 -0.8596 -0.2903 +vn 0.7217 -0.6859 0.0932 +vn 0.6791 0.7320 -0.0545 +vn 0.4205 0.8596 -0.2903 +vn 0.0000 -0.9505 0.3106 +vn 0.0091 -0.9049 0.4255 +vn 0.7177 -0.6387 0.2774 +vn 0.7379 -0.6353 0.2279 +vn 0.0000 -0.9951 0.0989 +vn 0.0265 -0.8787 0.4766 +vn 0.7828 -0.6197 0.0573 +vn 0.7177 -0.6386 0.2774 +vn 0.6983 0.6464 -0.3074 +vn 0.6965 0.6933 -0.1849 +vn -0.0094 0.9072 -0.4206 +vn 0.0000 0.9573 -0.2892 +vn 0.0189 -0.9424 0.3339 +vn 0.6684 -0.7438 0.0025 +vn 0.6798 0.5712 -0.4599 +vn -0.0269 0.8704 -0.4917 +vn -0.3863 0.8624 0.3273 +vn 0.0060 0.7626 0.6469 +vn 0.0267 -0.6519 0.7578 +vn -0.1687 -0.7859 0.5950 +vn 0.6684 -0.7438 0.0024 +vn 0.6065 0.5719 -0.5524 +vn 0.6064 0.5719 -0.5525 +vn -0.0156 0.9413 -0.3372 +vn -0.7140 -0.6997 -0.0237 +vn 0.7199 -0.6924 -0.0481 +vn -0.7140 0.6997 -0.0237 +vn 0.7199 0.6924 -0.0481 +vn 0.6181 0.7794 0.1022 +vn -0.7184 0.6571 -0.2284 +vn 0.7199 -0.6924 -0.0483 +vn 0.7199 0.6924 -0.0482 +vn 0.6181 -0.7794 0.1022 +vn -0.7184 -0.6571 -0.2284 +vn -0.5598 -0.6721 -0.4847 +vn 0.5241 -0.7521 0.3995 +vn -0.5598 0.6721 -0.4847 +vn 0.5241 0.7521 0.3995 +vn 0.3526 0.7473 0.5632 +vn -0.3730 0.6719 -0.6399 +vn 0.5242 -0.7521 0.3995 +vn 0.5242 0.7521 0.3995 +vn -0.3731 -0.6719 -0.6398 +vn -0.3728 0.6720 -0.6399 +vn -0.4206 0.8596 -0.2902 +vn -0.4206 -0.8596 -0.2902 +vn -0.3730 -0.6719 -0.6399 +vn 0.3526 -0.7473 0.5632 +vn 0.3527 0.7473 0.5631 +vn 0.1812 -0.7348 0.6537 +vn 0.1811 -0.7347 0.6537 +vn 0.1811 0.7348 0.6537 +vn -0.4205 -0.8596 -0.2903 +vn -0.4205 0.8596 -0.2903 +vn -0.6912 0.7171 -0.0899 +vn -0.7373 -0.6743 0.0414 +vn -0.7305 -0.6548 0.1939 +vn -0.6983 -0.6383 0.3238 +vn -0.6912 0.7171 -0.0898 +vn -0.5635 -0.6199 0.5461 +vn -0.6750 0.6994 -0.2350 +vn -0.6953 0.6547 -0.2965 +vn -0.6983 -0.6384 0.3238 +vn -0.6751 0.6993 -0.2350 +vn -0.6924 0.6765 -0.2509 +vn -0.5635 -0.6198 0.5461 +vn 0.0462 0.6388 -0.7680 +vn -0.0160 0.6498 -0.7599 +vn -0.3863 0.8624 0.3272 +vn -0.3862 0.8624 0.3273 +vn -0.1687 -0.7859 0.5949 +vn 0.5068 -0.6388 -0.5789 +vn 0.0587 -0.7430 -0.6667 +vn 0.0461 0.6388 -0.7680 +vn 0.4537 0.5718 -0.6835 +vn 0.0012 -0.7535 -0.6574 +vn -0.0160 0.6499 -0.7599 +vn 0.4537 0.5718 -0.6836 +vn -0.0111 -0.7588 -0.6513 +vn 0.2756 -0.5477 -0.7900 +vn 0.1334 0.5311 -0.8367 +vn -0.0312 0.6493 -0.7599 +vn 0.0267 -0.6519 0.7579 +vn -0.0313 0.6493 -0.7599 +vn 0.0061 0.7626 0.6469 +vn 0.3131 -0.6323 -0.7086 +vn 0.2305 0.7614 -0.6059 +vn 0.2229 0.6339 0.7406 +vn 0.2112 -0.4772 0.8530 +vn 0.2755 -0.5477 -0.7900 +vn 0.3785 -0.7600 0.5283 +vn -0.3103 -0.7644 0.5651 +vn -0.3379 -0.6218 -0.7065 +vn 0.2447 0.6937 0.6774 +vn 0.2113 -0.4772 0.8530 +vn 0.3131 -0.6323 -0.7087 +vn 0.2446 0.6938 0.6774 +vn -0.8230 -0.2761 -0.4965 +vn -0.8264 0.2972 -0.4782 +vn -0.3654 0.7227 -0.5867 +vn -0.3095 0.6492 0.6948 +vn -0.3103 -0.7644 0.5652 +vn -0.7980 0.2540 0.5465 +vn -0.8230 -0.2762 -0.4965 +vn -0.7868 -0.3173 0.5294 +vn -0.3379 -0.6219 -0.7065 +usemtl Scene_-_Root +s off +f 22703/22649/16392 22704/22650/16393 22705/22651/16394 +f 22710/22652/16395 22713/22653/16396 22714/22654/16397 +f 22805/22655/16398 22706/22656/16399 22705/22651/16394 +f 22809/22657/16400 22725/22658/16401 22714/22654/16397 +f 22939/22659/16402 22940/22660/16403 22941/22661/16394 +f 22945/22662/16404 22962/22663/16405 22949/22664/16397 +f 23033/22665/16406 23034/22666/16407 22941/22661/16394 +f 23038/22667/16408 22950/22668/16409 22949/22664/16397 +s 1 +f 22649/22669/16410 22650/22670/16411 22651/22671/16411 +f 22649/22669/16410 22651/22671/16411 22652/22672/16410 +f 22653/22673/16412 22654/22674/16410 22655/22675/16413 +f 22653/22673/16412 22655/22675/16413 22656/22676/16414 +f 22657/22677/16412 22658/22678/16410 22654/22674/16410 +f 22657/22677/16412 22654/22674/16410 22653/22673/16412 +f 22659/22679/16411 22660/22680/16415 22661/22681/16415 +f 22659/22679/16411 22661/22681/16415 22662/22682/16411 +f 22663/22683/16412 22664/22684/16415 22665/22685/16415 +f 22663/22683/16412 22665/22685/16415 22666/22686/16412 +f 22667/22687/16416 22668/22688/16417 22669/22689/16418 +f 22667/22687/16416 22669/22689/16418 22670/22690/16419 +f 22662/22682/16411 22661/22681/16415 22668/22688/16417 +f 22662/22682/16411 22668/22688/16417 22667/22687/16416 +f 22652/22672/16410 22651/22671/16411 22671/22691/16416 +f 22652/22672/16410 22671/22691/16416 22672/22692/16413 +f 22664/22684/16415 22663/22683/16412 22673/22693/16420 +f 22664/22684/16415 22673/22693/16420 22674/22694/16417 +f 22675/22695/16421 22676/22696/16422 22677/22697/16423 +f 22675/22695/16421 22677/22697/16423 22678/22698/16424 +f 22672/22692/16413 22671/22691/16416 22679/22699/16419 +f 22672/22692/16413 22679/22699/16419 22680/22700/16425 +f 22656/22676/16414 22655/22675/16413 22676/22696/16422 +f 22656/22676/16414 22676/22696/16422 22675/22695/16421 +f 22674/22694/16417 22673/22693/16420 22681/22701/16421 +f 22674/22694/16417 22681/22701/16421 22682/22702/16426 +f 22683/22703/16427 22684/22704/16428 22685/22705/16429 +f 22683/22703/16427 22685/22705/16429 22686/22706/16430 +f 22682/22702/16426 22681/22701/16421 22687/22707/16424 +f 22682/22702/16426 22687/22707/16424 22688/22708/16428 +f 22670/22690/16419 22669/22689/16418 22684/22704/16428 +f 22670/22690/16419 22684/22704/16428 22683/22703/16427 +f 22680/22700/16425 22679/22699/16419 22689/22709/16427 +f 22680/22700/16425 22689/22709/16427 22690/22710/16423 +f 22691/22711/16431 22692/22712/16432 22693/22713/16433 +f 22691/22711/16431 22693/22713/16433 22694/22714/16434 +f 22695/22715/16423 22696/22716/16427 22692/22712/16432 +f 22695/22715/16423 22692/22712/16432 22691/22711/16431 +f 22678/22698/16424 22677/22697/16423 22697/22717/16435 +f 22678/22698/16424 22697/22717/16435 22698/22718/16436 +f 22699/22719/16437 22700/22720/16438 22701/22721/16436 +f 22699/22719/16437 22701/22721/16436 22702/22722/16439 +f 22703/22649/16440 22705/22651/16394 22706/22656/16399 +f 22698/22718/16436 22697/22717/16435 22704/22650/16393 +f 22698/22718/16436 22704/22650/16393 22703/22649/16440 +f 22702/22722/16439 22701/22721/16436 22707/22723/16441 +f 22702/22722/16439 22707/22723/16441 22708/22724/16442 +f 22686/22706/16430 22685/22705/16429 22709/22725/16443 +f 22686/22706/16430 22709/22725/16443 22710/22652/16433 +f 22708/22724/16442 22707/22723/16441 22711/22726/16444 +f 22708/22724/16442 22711/22726/16444 22712/22727/16445 +f 22710/22652/16433 22709/22725/16443 22713/22653/16396 +f 22715/22728/16446 22716/22729/16447 22717/22730/16448 +f 22715/22728/16446 22717/22730/16448 22718/22731/16449 +f 22719/22732/16450 22720/22733/16451 22721/22734/16452 +f 22719/22732/16450 22721/22734/16452 22722/22735/16453 +f 22705/22651/16394 22704/22650/16393 22723/22736/16449 +f 22705/22651/16394 22723/22736/16449 22724/22737/16454 +f 22710/22652/16395 22714/22654/16397 22725/22658/16455 +f 22710/22652/16395 22725/22658/16455 22726/22738/16448 +f 22722/22735/16453 22721/22734/16452 22727/22739/16456 +f 22722/22735/16453 22727/22739/16456 22728/22740/16457 +f 22729/22741/16451 22730/22742/16458 22731/22743/16459 +f 22729/22741/16451 22731/22743/16459 22732/22744/16452 +f 22733/22745/16458 22734/22746/16460 22735/22747/16461 +f 22733/22745/16458 22735/22747/16461 22736/22748/16459 +f 22728/22740/16457 22727/22739/16456 22737/22749/16462 +f 22728/22740/16457 22737/22749/16462 22738/22750/16463 +f 22732/22744/16452 22731/22743/16459 22739/22751/16464 +f 22732/22744/16452 22739/22751/16464 22740/22752/16465 +f 22736/22748/16459 22735/22747/16461 22741/22753/16466 +f 22736/22748/16459 22741/22753/16466 22742/22754/16464 +f 22743/22755/16467 22744/22756/16468 22745/22757/16469 +f 22743/22755/16467 22745/22757/16469 22746/22758/16470 +f 22740/22752/16465 22739/22751/16464 22747/22759/16471 +f 22740/22752/16465 22747/22759/16471 22748/22760/16462 +f 22742/22754/16464 22741/22753/16466 22749/22761/16472 +f 22742/22754/16464 22749/22761/16472 22750/22762/16471 +f 22751/22763/16412 22752/22764/16412 22753/22765/16415 +f 22751/22763/16412 22753/22765/16415 22754/22766/16415 +f 22755/22767/16410 22756/22768/16473 22757/22769/16474 +f 22755/22767/16410 22757/22769/16474 22758/22770/16412 +f 22759/22771/16410 22755/22767/16410 22758/22770/16412 +f 22759/22771/16410 22758/22770/16412 22760/22772/16412 +f 22761/22773/16415 22762/22774/16415 22763/22775/16411 +f 22761/22773/16415 22763/22775/16411 22764/22776/16411 +f 22765/22777/16410 22766/22778/16410 22767/22779/16411 +f 22765/22777/16410 22767/22779/16411 22768/22780/16411 +f 22769/22781/16475 22770/22782/16476 22771/22783/16477 +f 22769/22781/16475 22771/22783/16477 22772/22784/16478 +f 22762/22774/16415 22769/22781/16475 22772/22784/16478 +f 22762/22774/16415 22772/22784/16478 22763/22775/16411 +f 22752/22764/16412 22773/22785/16474 22774/22786/16475 +f 22752/22764/16412 22774/22786/16475 22753/22765/16415 +f 22768/22780/16411 22775/22787/16479 22776/22788/16473 +f 22768/22780/16411 22776/22788/16473 22765/22777/16410 +f 22777/22789/16480 22778/22790/16481 22779/22791/16482 +f 22777/22789/16480 22779/22791/16482 22780/22792/16483 +f 22773/22785/16474 22781/22793/16484 22782/22794/16476 +f 22773/22785/16474 22782/22794/16476 22774/22786/16475 +f 22756/22768/16473 22777/22789/16480 22780/22792/16483 +f 22756/22768/16473 22780/22792/16483 22757/22769/16474 +f 22775/22787/16479 22783/22795/16477 22784/22796/16480 +f 22775/22787/16479 22784/22796/16480 22776/22788/16473 +f 22785/22797/16485 22786/22798/16486 22787/22799/16487 +f 22785/22797/16485 22787/22799/16487 22788/22800/16488 +f 22783/22795/16477 22789/22801/16489 22790/22802/16490 +f 22783/22795/16477 22790/22802/16490 22784/22796/16480 +f 22770/22782/16476 22785/22797/16485 22788/22800/16488 +f 22770/22782/16476 22788/22800/16488 22771/22783/16477 +f 22781/22793/16484 22791/22803/16482 22792/22804/16485 +f 22781/22793/16484 22792/22804/16485 22782/22794/16476 +f 22793/22805/16491 22794/22806/16492 22795/22807/16493 +f 22793/22805/16491 22795/22807/16493 22796/22808/16494 +f 22797/22809/16482 22793/22805/16491 22796/22808/16494 +f 22797/22809/16482 22796/22808/16494 22798/22810/16485 +f 22778/22790/16481 22799/22811/16495 22800/22812/16496 +f 22778/22790/16481 22800/22812/16496 22779/22791/16482 +f 22801/22813/16489 22802/22814/16487 22803/22815/16495 +f 22801/22813/16489 22803/22815/16495 22804/22816/16490 +f 22805/22655/16398 22705/22651/16394 22806/22817/16497 +f 22799/22811/16495 22805/22655/16398 22806/22817/16497 +f 22799/22811/16495 22806/22817/16497 22800/22812/16496 +f 22802/22814/16487 22807/22818/16498 22808/22819/16499 +f 22802/22814/16487 22808/22819/16499 22803/22815/16495 +f 22786/22798/16486 22809/22657/16400 22810/22820/16500 +f 22786/22798/16486 22810/22820/16500 22787/22799/16487 +f 22807/22818/16498 22712/22727/16445 22711/22726/16444 +f 22807/22818/16498 22711/22726/16444 22808/22819/16499 +f 22809/22657/16400 22714/22654/16397 22713/22653/16396 +f 22809/22657/16400 22713/22653/16396 22810/22820/16500 +f 22811/22821/16501 22812/22822/16502 22813/22823/16503 +f 22811/22821/16501 22813/22823/16503 22814/22824/16504 +f 22719/22732/16450 22722/22735/16453 22815/22825/16505 +f 22719/22732/16450 22815/22825/16505 22816/22826/16506 +f 22705/22651/16394 22724/22737/16454 22817/22827/16502 +f 22705/22651/16394 22817/22827/16502 22806/22817/16497 +f 22809/22657/16400 22818/22828/16503 22725/22658/16455 +f 22722/22735/16453 22728/22740/16457 22819/22829/16507 +f 22722/22735/16453 22819/22829/16507 22815/22825/16505 +f 22820/22830/16506 22821/22831/16505 22822/22832/16508 +f 22820/22830/16506 22822/22832/16508 22823/22833/16509 +f 22824/22834/16509 22825/22835/16510 22735/22747/16461 +f 22824/22834/16509 22735/22747/16461 22734/22746/16460 +f 22728/22740/16457 22738/22750/16463 22826/22836/16468 +f 22728/22740/16457 22826/22836/16468 22819/22829/16507 +f 22821/22831/16505 22827/22837/16507 22828/22838/16511 +f 22821/22831/16505 22828/22838/16511 22822/22832/16508 +f 22825/22835/16510 22829/22839/16511 22741/22753/16466 +f 22825/22835/16510 22741/22753/16466 22735/22747/16461 +f 22749/22761/16472 22830/22840/16467 22831/22841/16512 +f 22749/22761/16472 22831/22841/16512 22832/22842/16513 +f 22827/22837/16507 22833/22843/16514 22834/22844/16467 +f 22827/22837/16507 22834/22844/16467 22828/22838/16511 +f 22829/22839/16511 22830/22840/16467 22749/22761/16472 +f 22829/22839/16511 22749/22761/16472 22741/22753/16466 +f 22835/22845/16515 22836/22846/16516 22837/22847/16513 +f 22835/22845/16515 22837/22847/16513 22838/22848/16517 +f 22839/22849/16518 22838/22848/16517 22837/22847/16513 +f 22839/22849/16518 22837/22847/16513 22840/22850/16512 +f 22738/22750/16463 22737/22749/16462 22841/22851/16519 +f 22738/22750/16463 22841/22851/16519 22842/22852/16517 +f 22748/22760/16462 22747/22759/16471 22843/22853/16516 +f 22748/22760/16462 22843/22853/16516 22844/22854/16519 +f 22826/22836/16468 22738/22750/16463 22842/22852/16517 +f 22826/22836/16468 22842/22852/16517 22845/22855/16518 +f 22750/22762/16471 22749/22761/16472 22832/22842/16513 +f 22750/22762/16471 22832/22842/16513 22846/22856/16516 +f 22847/22857/16520 22848/22858/16521 22849/22859/16522 +f 22847/22857/16520 22849/22859/16522 22850/22860/16523 +f 22826/22836/16468 22845/22855/16518 22851/22861/16524 +f 22826/22836/16468 22851/22861/16524 22852/22862/16469 +f 22831/22841/16512 22830/22840/16467 22853/22863/16470 +f 22831/22841/16512 22853/22863/16470 22854/22864/16521 +f 22839/22849/16518 22840/22850/16512 22848/22858/16521 +f 22839/22849/16518 22848/22858/16521 22847/22857/16520 +f 22850/22860/16523 22849/22859/16522 22855/22865/16525 +f 22850/22860/16523 22855/22865/16525 22856/22866/16526 +f 22854/22864/16521 22853/22863/16470 22857/22867/16527 +f 22854/22864/16521 22857/22867/16527 22858/22868/16528 +f 22852/22862/16469 22851/22861/16524 22859/22869/16529 +f 22852/22862/16469 22859/22869/16529 22860/22870/16530 +f 22746/22758/16470 22745/22757/16469 22861/22871/16530 +f 22746/22758/16470 22861/22871/16530 22862/22872/16531 +f 22863/22873/16532 22864/22874/16533 22865/22875/16534 +f 22863/22873/16532 22865/22875/16534 22866/22876/16535 +f 22858/22868/16528 22857/22867/16527 22867/22877/16536 +f 22858/22868/16528 22867/22877/16536 22868/22878/16525 +f 22869/22879/16537 22870/22880/16523 22871/22881/16533 +f 22869/22879/16537 22871/22881/16533 22872/22882/16532 +f 22862/22872/16531 22861/22871/16530 22873/22883/16532 +f 22862/22872/16531 22873/22883/16532 22874/22884/16536 +f 22875/22885/16534 22876/22886/16538 22877/22887/16539 +f 22875/22885/16534 22877/22887/16539 22878/22888/16540 +f 22874/22884/16536 22873/22883/16532 22879/22889/16541 +f 22874/22884/16536 22879/22889/16541 22880/22890/16542 +f 22856/22866/16526 22855/22865/16525 22876/22886/16538 +f 22856/22866/16526 22876/22886/16538 22875/22885/16534 +f 22868/22878/16525 22867/22877/16536 22881/22891/16542 +f 22868/22878/16525 22881/22891/16542 22882/22892/16543 +f 22883/22893/16544 22884/22894/16545 22885/22895/16540 +f 22883/22893/16544 22885/22895/16540 22886/22896/16546 +f 22887/22897/16547 22888/22898/16542 22883/22893/16544 +f 22887/22897/16547 22883/22893/16544 22886/22896/16546 +f 22889/22899/16535 22890/22900/16534 22885/22895/16540 +f 22889/22899/16535 22885/22895/16540 22884/22894/16545 +f 22880/22890/16542 22879/22889/16541 22891/22901/16548 +f 22880/22890/16542 22891/22901/16548 22892/22902/16544 +f 22818/22828/16503 22824/22834/16509 22734/22746/16460 +f 22818/22828/16503 22734/22746/16460 22725/22658/16455 +f 22812/22822/16502 22820/22830/16506 22823/22833/16509 +f 22812/22822/16502 22823/22833/16509 22813/22823/16503 +f 22724/22737/16454 22719/22732/16450 22816/22826/16506 +f 22724/22737/16454 22816/22826/16506 22817/22827/16502 +f 22726/22738/16448 22725/22658/16455 22734/22746/16460 +f 22726/22738/16448 22734/22746/16460 22733/22745/16458 +f 22718/22731/16449 22717/22730/16448 22730/22742/16458 +f 22718/22731/16449 22730/22742/16458 22729/22741/16451 +f 22724/22737/16454 22723/22736/16449 22720/22733/16451 +f 22724/22737/16454 22720/22733/16451 22719/22732/16450 +f 22649/22669/16410 22893/22903/16410 22894/22904/16411 +f 22649/22669/16410 22894/22904/16411 22650/22670/16411 +f 22895/22905/16412 22896/22906/16549 22897/22907/16550 +f 22895/22905/16412 22897/22907/16550 22898/22908/16410 +f 22657/22677/16412 22895/22905/16412 22898/22908/16410 +f 22657/22677/16412 22898/22908/16410 22658/22678/16410 +f 22659/22679/16411 22899/22909/16411 22900/22910/16415 +f 22659/22679/16411 22900/22910/16415 22660/22680/16415 +f 22901/22911/16412 22666/22686/16412 22665/22685/16415 +f 22901/22911/16412 22665/22685/16415 22902/22912/16415 +f 22903/22913/16551 22904/22914/16552 22905/22915/16553 +f 22903/22913/16551 22905/22915/16553 22906/22916/16554 +f 22899/22909/16411 22903/22913/16551 22906/22916/16554 +f 22899/22909/16411 22906/22916/16554 22900/22910/16415 +f 22893/22903/16410 22907/22917/16550 22908/22918/16551 +f 22893/22903/16410 22908/22918/16551 22894/22904/16411 +f 22902/22912/16415 22909/22919/16554 22910/22920/16549 +f 22902/22912/16415 22910/22920/16549 22901/22911/16412 +f 22911/22921/16555 22912/22922/16556 22913/22923/16557 +f 22911/22921/16555 22913/22923/16557 22914/22924/16558 +f 22907/22917/16550 22915/22925/16559 22916/22926/16552 +f 22907/22917/16550 22916/22926/16552 22908/22918/16551 +f 22896/22906/16549 22911/22921/16555 22914/22924/16558 +f 22896/22906/16549 22914/22924/16558 22897/22907/16550 +f 22909/22919/16554 22917/22927/16553 22918/22928/16555 +f 22909/22919/16554 22918/22928/16555 22910/22920/16549 +f 22919/22929/16560 22920/22930/16561 22921/22931/16562 +f 22919/22929/16560 22921/22931/16562 22922/22932/16563 +f 22917/22927/16553 22923/22933/16563 22924/22934/16556 +f 22917/22927/16553 22924/22934/16556 22918/22928/16555 +f 22904/22914/16552 22919/22929/16560 22922/22932/16563 +f 22904/22914/16552 22922/22932/16563 22905/22915/16553 +f 22915/22925/16559 22925/22935/16557 22926/22936/16560 +f 22915/22925/16559 22926/22936/16560 22916/22926/16552 +f 22927/22937/16564 22928/22938/16565 22929/22939/16566 +f 22927/22937/16564 22929/22939/16566 22930/22940/16567 +f 22931/22941/16557 22927/22937/16564 22930/22940/16567 +f 22931/22941/16557 22930/22940/16567 22932/22942/16560 +f 22912/22922/16556 22933/22943/16568 22934/22944/16569 +f 22912/22922/16556 22934/22944/16569 22913/22923/16557 +f 22935/22945/16570 22936/22946/16562 22937/22947/16568 +f 22935/22945/16570 22937/22947/16568 22938/22948/16571 +f 22939/22659/16402 22941/22661/16394 22942/22949/16572 +f 22933/22943/16568 22939/22659/16402 22942/22949/16572 +f 22933/22943/16568 22942/22949/16572 22934/22944/16569 +f 22936/22946/16562 22943/22950/16573 22944/22951/16574 +f 22936/22946/16562 22944/22951/16574 22937/22947/16568 +f 22920/22930/16561 22945/22662/16404 22946/22952/16573 +f 22920/22930/16561 22946/22952/16573 22921/22931/16562 +f 22943/22950/16573 22947/22953/16575 22948/22954/16576 +f 22943/22950/16573 22948/22954/16576 22944/22951/16574 +f 22945/22662/16404 22949/22664/16397 22950/22668/16409 +f 22945/22662/16404 22950/22668/16409 22946/22952/16573 +f 22951/22955/16577 22952/22956/16578 22953/22957/16579 +f 22951/22955/16577 22953/22957/16579 22954/22958/16580 +f 22955/22959/16581 22956/22960/16582 22957/22961/16583 +f 22955/22959/16581 22957/22961/16583 22958/22962/16584 +f 22941/22661/16394 22959/22963/16585 22960/22964/16578 +f 22941/22661/16394 22960/22964/16578 22942/22949/16572 +f 22945/22662/16404 22961/22965/16579 22962/22663/16405 +f 22956/22960/16582 22963/22966/16586 22964/22967/16587 +f 22956/22960/16582 22964/22967/16587 22957/22961/16583 +f 22965/22968/16584 22966/22969/16588 22967/22970/16589 +f 22965/22968/16584 22967/22970/16589 22968/22971/16590 +f 22969/22972/16590 22970/22973/16589 22971/22974/16591 +f 22969/22972/16590 22971/22974/16591 22972/22975/16592 +f 22963/22966/16586 22973/22976/16593 22974/22977/16594 +f 22963/22966/16586 22974/22977/16594 22964/22967/16587 +f 22966/22969/16588 22975/22978/16587 22976/22979/16595 +f 22966/22969/16588 22976/22979/16595 22967/22970/16589 +f 22970/22973/16589 22977/22980/16595 22978/22981/16596 +f 22970/22973/16589 22978/22981/16596 22971/22974/16591 +f 22979/22982/16597 22980/22983/16598 22981/22984/16599 +f 22979/22982/16597 22981/22984/16599 22982/22985/16600 +f 22975/22978/16587 22983/22986/16601 22984/22987/16602 +f 22975/22978/16587 22984/22987/16602 22976/22979/16595 +f 22977/22980/16595 22985/22988/16603 22986/22989/16604 +f 22977/22980/16595 22986/22989/16604 22978/22981/16596 +f 22751/22763/16412 22754/22766/16415 22987/22990/16415 +f 22751/22763/16412 22987/22990/16415 22988/22991/16412 +f 22989/22992/16410 22990/22993/16412 22991/22994/16605 +f 22989/22992/16410 22991/22994/16605 22992/22995/16606 +f 22759/22771/16410 22760/22772/16412 22990/22993/16412 +f 22759/22771/16410 22990/22993/16412 22989/22992/16410 +f 22761/22773/16415 22764/22776/16411 22993/22996/16411 +f 22761/22773/16415 22993/22996/16411 22994/22997/16415 +f 22995/22998/16410 22996/22999/16411 22767/22779/16411 +f 22995/22998/16410 22767/22779/16411 22766/22778/16410 +f 22997/23000/16607 22998/23001/16608 22999/23002/16609 +f 22997/23000/16607 22999/23002/16609 23000/23003/16610 +f 22994/22997/16415 22993/22996/16411 22998/23001/16608 +f 22994/22997/16415 22998/23001/16608 22997/23000/16607 +f 22988/22991/16412 22987/22990/16415 23001/23004/16607 +f 22988/22991/16412 23001/23004/16607 23002/23005/16605 +f 22996/22999/16411 22995/22998/16410 23003/23006/16611 +f 22996/22999/16411 23003/23006/16611 23004/23007/16612 +f 23005/23008/16613 23006/23009/16614 23007/23010/16615 +f 23005/23008/16613 23007/23010/16615 23008/23011/16616 +f 23002/23005/16605 23001/23004/16607 23009/23012/16610 +f 23002/23005/16605 23009/23012/16610 23010/23013/16614 +f 22992/22995/16606 22991/22994/16605 23006/23009/16614 +f 22992/22995/16606 23006/23009/16614 23005/23008/16613 +f 23004/23007/16612 23003/23006/16611 23011/23014/16613 +f 23004/23007/16612 23011/23014/16613 23012/23015/16609 +f 23013/23016/16617 23014/23017/16618 23015/23018/16619 +f 23013/23016/16617 23015/23018/16619 23016/23019/16620 +f 23012/23015/16609 23011/23014/16613 23017/23020/16621 +f 23012/23015/16609 23017/23020/16621 23018/23021/16622 +f 23000/23003/16610 22999/23002/16609 23014/23017/16618 +f 23000/23003/16610 23014/23017/16618 23013/23016/16617 +f 23010/23013/16614 23009/23012/16610 23019/23022/16617 +f 23010/23013/16614 23019/23022/16617 23020/23023/16615 +f 23021/23024/16623 23022/23025/16624 23023/23026/16625 +f 23021/23024/16623 23023/23026/16625 23024/23027/16626 +f 23025/23028/16615 23026/23029/16617 23022/23025/16624 +f 23025/23028/16615 23022/23025/16624 23021/23024/16623 +f 23008/23011/16616 23007/23010/16615 23027/23030/16627 +f 23008/23011/16616 23027/23030/16627 23028/23031/16628 +f 23029/23032/16622 23030/23033/16621 23031/23034/16628 +f 23029/23032/16622 23031/23034/16628 23032/23035/16629 +f 23033/22665/16630 22941/22661/16394 22940/22660/16403 +f 23028/23031/16628 23027/23030/16627 23034/22666/16407 +f 23028/23031/16628 23034/22666/16407 23033/22665/16630 +f 23032/23035/16629 23031/23034/16628 23035/23036/16631 +f 23032/23035/16629 23035/23036/16631 23036/23037/16632 +f 23016/23019/16620 23015/23018/16619 23037/23038/16632 +f 23016/23019/16620 23037/23038/16632 23038/22667/16625 +f 23036/23037/16632 23035/23036/16631 22948/22954/16576 +f 23036/23037/16632 22948/22954/16576 22947/22953/16575 +f 23038/22667/16625 23037/23038/16632 22950/22668/16409 +f 23039/23039/16633 23040/23040/16634 23041/23041/16635 +f 23039/23039/16633 23041/23041/16635 23042/23042/16636 +f 22955/22959/16581 23043/23043/16637 23044/23044/16638 +f 22955/22959/16581 23044/23044/16638 22956/22960/16582 +f 22941/22661/16394 23034/22666/16407 23045/23045/16636 +f 22941/22661/16394 23045/23045/16636 22959/22963/16585 +f 23038/22667/16408 22949/22664/16397 22962/22663/16405 +f 23038/22667/16408 22962/22663/16405 23046/23046/16639 +f 22956/22960/16582 23044/23044/16638 23047/23047/16640 +f 22956/22960/16582 23047/23047/16640 22963/22966/16586 +f 23048/23048/16637 23049/23049/16641 23050/23050/16642 +f 23048/23048/16637 23050/23050/16642 23051/23051/16643 +f 23052/23052/16644 22972/22975/16592 22971/22974/16591 +f 23052/23052/16644 22971/22974/16591 23053/23053/16642 +f 22963/22966/16586 23047/23047/16640 23054/23054/16600 +f 22963/22966/16586 23054/23054/16600 22973/22976/16593 +f 23051/23051/16643 23050/23050/16642 23055/23055/16645 +f 23051/23051/16643 23055/23055/16645 23056/23056/16646 +f 23053/23053/16642 22971/22974/16591 22978/22981/16596 +f 23053/23053/16642 22978/22981/16596 23057/23057/16645 +f 22986/22989/16604 23058/23058/16647 23059/23059/16648 +f 22986/22989/16604 23059/23059/16648 23060/23060/16649 +f 23056/23056/16646 23055/23055/16645 23061/23061/16650 +f 23056/23056/16646 23061/23061/16650 23062/23062/16651 +f 23057/23057/16645 22978/22981/16596 22986/22989/16604 +f 23057/23057/16645 22986/22989/16604 23060/23060/16649 +f 23063/23063/16652 23064/23064/16653 23065/23065/16654 +f 23063/23063/16652 23065/23065/16654 23066/23066/16655 +f 23067/23067/16656 23068/23068/16657 23065/23065/16654 +f 23067/23067/16656 23065/23065/16654 23064/23064/16653 +f 22973/22976/16593 23069/23069/16653 23070/23070/16652 +f 22973/22976/16593 23070/23070/16652 22974/22977/16594 +f 22983/22986/16601 23071/23071/16652 23072/23072/16658 +f 22983/22986/16601 23072/23072/16658 22984/22987/16602 +f 23054/23054/16600 23073/23073/16656 23069/23069/16653 +f 23054/23054/16600 23069/23069/16653 22973/22976/16593 +f 22985/22988/16603 23074/23074/16655 23058/23058/16647 +f 22985/22988/16603 23058/23058/16647 22986/22989/16604 +f 23075/23075/16659 23076/23076/16660 23077/23077/16661 +f 23075/23075/16659 23077/23077/16661 23078/23078/16662 +f 23054/23054/16600 23079/23079/16663 23080/23080/16659 +f 23054/23054/16600 23080/23080/16659 23073/23073/16656 +f 23059/23059/16648 23081/23081/16664 23082/23082/16665 +f 23059/23059/16648 23082/23082/16665 23060/23060/16649 +f 23067/23067/16656 23075/23075/16659 23078/23078/16662 +f 23067/23067/16656 23078/23078/16662 23068/23068/16657 +f 23076/23076/16660 23083/23083/16666 23084/23084/16667 +f 23076/23076/16660 23084/23084/16667 23077/23077/16661 +f 23081/23081/16664 23085/23085/16661 23086/23086/16668 +f 23081/23081/16664 23086/23086/16668 23082/23082/16665 +f 23079/23079/16663 23087/23087/16669 23088/23088/16670 +f 23079/23079/16663 23088/23088/16670 23080/23080/16659 +f 22980/22983/16598 23089/23089/16668 23090/23090/16669 +f 22980/22983/16598 23090/23090/16669 22981/22984/16599 +f 23091/23091/16671 23092/23092/16672 23093/23093/16673 +f 23091/23091/16671 23093/23093/16673 23094/23094/16666 +f 23085/23085/16661 23095/23095/16667 23096/23096/16674 +f 23085/23085/16661 23096/23096/16674 23086/23086/16668 +f 23097/23097/16675 23098/23098/16671 23099/23099/16676 +f 23097/23097/16675 23099/23099/16676 23100/23100/16660 +f 23089/23089/16668 23101/23101/16677 23102/23102/16671 +f 23089/23089/16668 23102/23102/16671 23090/23090/16669 +f 23103/23103/16673 23104/23104/16678 23105/23105/16679 +f 23103/23103/16673 23105/23105/16679 23106/23106/16680 +f 23101/23101/16677 23107/23107/16681 23108/23108/16682 +f 23101/23101/16677 23108/23108/16682 23102/23102/16671 +f 23083/23083/16666 23103/23103/16673 23106/23106/16680 +f 23083/23083/16666 23106/23106/16680 23084/23084/16667 +f 23095/23095/16667 23109/23109/16680 23110/23110/16681 +f 23095/23095/16667 23110/23110/16681 23096/23096/16674 +f 23111/23111/16683 23112/23112/16679 23113/23113/16684 +f 23111/23111/16683 23113/23113/16684 23114/23114/16685 +f 23115/23115/16680 23112/23112/16679 23111/23111/16683 +f 23115/23115/16680 23111/23111/16683 23116/23116/16681 +f 23117/23117/16682 23114/23114/16685 23113/23113/16684 +f 23117/23117/16682 23113/23113/16684 23118/23118/16686 +f 23107/23107/16681 23119/23119/16683 23120/23120/16685 +f 23107/23107/16681 23120/23120/16685 23108/23108/16682 +f 23046/23046/16639 22962/22663/16405 22972/22975/16592 +f 23046/23046/16639 22972/22975/16592 23052/23052/16644 +f 23042/23042/16636 23041/23041/16635 23049/23049/16641 +f 23042/23042/16636 23049/23049/16641 23048/23048/16637 +f 22959/22963/16585 23045/23045/16636 23043/23043/16637 +f 22959/22963/16585 23043/23043/16637 22955/22959/16581 +f 22961/22965/16579 22969/22972/16590 22972/22975/16592 +f 22961/22965/16579 22972/22975/16592 22962/22663/16405 +f 22952/22956/16578 22965/22968/16584 22968/22971/16590 +f 22952/22956/16578 22968/22971/16590 22953/22957/16579 +f 22959/22963/16585 22955/22959/16581 22958/22962/16584 +f 22959/22963/16585 22958/22962/16584 22960/22964/16578 +o Cylinder.036__0 +v 0.885390 0.994171 -0.924311 +v 0.885390 0.994171 -0.910091 +v 0.897144 0.989302 -0.910091 +v 0.897144 0.989302 -0.924311 +v 0.897144 0.989302 -0.924311 +v 0.897144 0.989302 -0.910091 +v 0.902013 0.977548 -0.910091 +v 0.902013 0.977548 -0.924311 +v 0.902013 0.977548 -0.924311 +v 0.902013 0.977548 -0.910091 +v 0.897144 0.965794 -0.910091 +v 0.897144 0.965794 -0.924311 +v 0.897144 0.965794 -0.924311 +v 0.897144 0.965794 -0.910091 +v 0.885390 0.960925 -0.910091 +v 0.885390 0.960925 -0.924311 +v 0.885390 0.960925 -0.924311 +v 0.885390 0.960925 -0.910091 +v 0.873636 0.965794 -0.910091 +v 0.873636 0.965794 -0.924311 +v 0.873636 0.965794 -0.924311 +v 0.873636 0.965794 -0.910091 +v 0.868767 0.977548 -0.910091 +v 0.868767 0.977548 -0.924311 +v 0.868767 0.977548 -0.924311 +v 0.868767 0.977548 -0.910091 +v 0.873636 0.989302 -0.910091 +v 0.873636 0.989302 -0.924311 +v 0.873636 0.989302 -0.924311 +v 0.873636 0.989302 -0.910091 +v 0.885390 0.994171 -0.910091 +v 0.885390 0.994171 -0.924311 +v 0.897144 0.989302 -0.910091 +v 0.885390 0.994171 -0.910091 +v 0.873636 0.989302 -0.910091 +v 0.868767 0.977548 -0.910091 +v 0.873636 0.965794 -0.910091 +v 0.885390 0.960925 -0.910091 +v 0.897144 0.965794 -0.910091 +v 0.902013 0.977548 -0.910091 +v 0.885390 0.994171 -0.924311 +v 0.897144 0.989302 -0.924311 +v 0.902013 0.977548 -0.924311 +v 0.897144 0.965794 -0.924311 +v 0.885390 0.960925 -0.924311 +v 0.873636 0.965794 -0.924311 +v 0.868767 0.977548 -0.924311 +v 0.873636 0.989302 -0.924311 +vt 0.507216 0.773941 +vt 0.506164 0.773941 +vt 0.506164 0.774882 +vt 0.507216 0.774882 +vt 0.215411 0.273155 +vt 0.214359 0.273155 +vt 0.214359 0.273820 +vt 0.215411 0.273820 +vt 0.215411 0.273820 +vt 0.214359 0.273820 +vt 0.214359 0.274761 +vt 0.215411 0.274761 +vt 0.215411 0.274761 +vt 0.214359 0.274761 +vt 0.214359 0.275426 +vt 0.215411 0.275426 +vt 0.539411 0.773951 +vt 0.539411 0.772899 +vt 0.538470 0.772899 +vt 0.538470 0.773951 +vt 0.509362 0.773276 +vt 0.508310 0.773276 +vt 0.508310 0.773941 +vt 0.509362 0.773941 +vt 0.509362 0.773941 +vt 0.508310 0.773941 +vt 0.508310 0.774882 +vt 0.509362 0.774882 +vt 0.507216 0.773276 +vt 0.506164 0.773276 +vt 0.506164 0.773941 +vt 0.507216 0.773941 +vt 0.474325 0.773039 +vt 0.475932 0.773705 +vt 0.475266 0.773039 +vt 0.473660 0.773705 +vt 0.475932 0.774645 +vt 0.473660 0.774645 +vt 0.475266 0.775311 +vt 0.474325 0.775311 +vt 0.482929 0.773705 +vt 0.484535 0.773039 +vt 0.483594 0.773039 +vt 0.482929 0.774645 +vt 0.485201 0.773705 +vt 0.485201 0.774645 +vt 0.483594 0.775311 +vt 0.484535 0.775311 +vn 0.3827 0.9239 0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.9239 -0.3827 0.0000 +vn 0.3827 -0.9239 0.0000 +vn -0.3827 -0.9239 0.0000 +vn -0.9239 -0.3827 0.0000 +vn -0.9239 0.3827 0.0000 +vn -0.3827 0.9239 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +usemtl Scene_-_Root +s off +f 23121/23121/16687 23122/23122/16687 23123/23123/16687 +f 23121/23121/16687 23123/23123/16687 23124/23124/16687 +f 23125/23125/16688 23126/23126/16688 23127/23127/16688 +f 23125/23125/16688 23127/23127/16688 23128/23128/16688 +f 23129/23129/16689 23130/23130/16689 23131/23131/16689 +f 23129/23129/16689 23131/23131/16689 23132/23132/16689 +f 23133/23133/16690 23134/23134/16690 23135/23135/16690 +f 23133/23133/16690 23135/23135/16690 23136/23136/16690 +f 23137/23137/16691 23138/23138/16691 23139/23139/16691 +f 23137/23137/16691 23139/23139/16691 23140/23140/16691 +f 23141/23141/16692 23142/23142/16692 23143/23143/16692 +f 23141/23141/16692 23143/23143/16692 23144/23144/16692 +f 23145/23145/16693 23146/23146/16693 23147/23147/16693 +f 23145/23145/16693 23147/23147/16693 23148/23148/16693 +f 23149/23149/16694 23150/23150/16694 23151/23151/16694 +f 23149/23149/16694 23151/23151/16694 23152/23152/16694 +f 23157/23153/16695 23155/23154/16695 23156/23155/16695 +f 23155/23154/16695 23157/23153/16695 23158/23156/16695 +f 23155/23154/16695 23158/23156/16695 23154/23157/16695 +f 23154/23157/16695 23158/23156/16695 23159/23158/16695 +f 23154/23157/16695 23159/23158/16695 23153/23159/16695 +f 23153/23159/16695 23159/23158/16695 23160/23160/16695 +f 23168/23161/16696 23166/23162/16696 23167/23163/16696 +f 23166/23162/16696 23168/23161/16696 23161/23164/16696 +f 23166/23162/16696 23161/23164/16696 23165/23165/16696 +f 23165/23165/16696 23161/23164/16696 23164/23166/16696 +f 23164/23166/16696 23161/23164/16696 23162/23167/16696 +f 23164/23166/16696 23162/23167/16696 23163/23168/16696 +o Cylinder.037__0 +v 0.885390 0.994171 -0.864233 +v 0.885390 0.994171 -0.846987 +v 0.897144 0.989302 -0.846987 +v 0.897144 0.989302 -0.864233 +v 0.897144 0.989302 -0.864233 +v 0.897144 0.989302 -0.846987 +v 0.902013 0.977548 -0.846987 +v 0.902013 0.977548 -0.864233 +v 0.902013 0.977548 -0.864233 +v 0.902013 0.977548 -0.846987 +v 0.897144 0.965794 -0.846987 +v 0.897144 0.965794 -0.864233 +v 0.897144 0.965794 -0.864233 +v 0.897144 0.965794 -0.846987 +v 0.885390 0.960925 -0.846987 +v 0.885390 0.960925 -0.864233 +v 0.885390 0.960925 -0.864233 +v 0.885390 0.960925 -0.846987 +v 0.873636 0.965794 -0.846987 +v 0.873636 0.965794 -0.864233 +v 0.873636 0.965794 -0.864233 +v 0.873636 0.965794 -0.846987 +v 0.868767 0.977548 -0.846987 +v 0.868767 0.977548 -0.864233 +v 0.885390 0.968473 -0.846987 +v 0.891807 0.971131 -0.846987 +v 0.891807 0.971131 -0.839103 +v 0.885390 0.968473 -0.839103 +v 0.868767 0.977548 -0.864233 +v 0.868767 0.977548 -0.846987 +v 0.873636 0.989302 -0.846987 +v 0.873636 0.989302 -0.864233 +v 0.873636 0.989302 -0.864233 +v 0.873636 0.989302 -0.846987 +v 0.885390 0.994171 -0.846987 +v 0.885390 0.994171 -0.864233 +v 0.885390 0.986623 -0.846987 +v 0.891807 0.983965 -0.846987 +v 0.897144 0.989302 -0.846987 +v 0.885390 0.994171 -0.846987 +v 0.891807 0.983965 -0.846987 +v 0.894465 0.977548 -0.846987 +v 0.902013 0.977548 -0.846987 +v 0.897144 0.989302 -0.846987 +v 0.894465 0.977548 -0.846987 +v 0.891807 0.971131 -0.846987 +v 0.897144 0.965794 -0.846987 +v 0.902013 0.977548 -0.846987 +v 0.891807 0.971131 -0.846987 +v 0.885390 0.968473 -0.846987 +v 0.885390 0.960925 -0.846987 +v 0.897144 0.965794 -0.846987 +v 0.885390 0.968473 -0.846987 +v 0.878973 0.971131 -0.846987 +v 0.873636 0.965794 -0.846987 +v 0.885390 0.960925 -0.846987 +v 0.878973 0.971131 -0.846987 +v 0.876315 0.977548 -0.846987 +v 0.868767 0.977548 -0.846987 +v 0.873636 0.965794 -0.846987 +v 0.878973 0.983965 -0.846987 +v 0.873636 0.989302 -0.846987 +v 0.894465 0.977548 -0.846987 +v 0.891807 0.983965 -0.846987 +v 0.891807 0.983965 -0.839103 +v 0.894465 0.977548 -0.839103 +v 0.878973 0.983965 -0.846987 +v 0.876315 0.977548 -0.846987 +v 0.876315 0.977548 -0.839103 +v 0.878973 0.983965 -0.839103 +v 0.878973 0.971131 -0.846987 +v 0.885390 0.968473 -0.846987 +v 0.885390 0.968473 -0.839103 +v 0.878973 0.971131 -0.839103 +v 0.891807 0.971131 -0.846987 +v 0.894465 0.977548 -0.846987 +v 0.894465 0.977548 -0.839103 +v 0.891807 0.971131 -0.839103 +v 0.891807 0.983965 -0.846987 +v 0.885390 0.986623 -0.846987 +v 0.885390 0.986623 -0.839103 +v 0.891807 0.983965 -0.839103 +v 0.885390 0.986623 -0.846987 +v 0.878973 0.983965 -0.846987 +v 0.878973 0.983965 -0.839103 +v 0.885390 0.986623 -0.839103 +v 0.876315 0.977548 -0.846987 +v 0.878973 0.971131 -0.846987 +v 0.878973 0.971131 -0.839103 +v 0.876315 0.977548 -0.839103 +v 0.885390 0.994171 -0.864233 +v 0.897144 0.989302 -0.864233 +v 0.902013 0.977548 -0.864233 +v 0.897144 0.965794 -0.864233 +v 0.885390 0.960925 -0.864233 +v 0.873636 0.965794 -0.864233 +v 0.868767 0.977548 -0.864233 +v 0.873636 0.989302 -0.864233 +v 0.891807 0.983965 -0.839103 +v 0.885390 0.986623 -0.839103 +v 0.878973 0.983965 -0.839103 +v 0.876315 0.977548 -0.839103 +v 0.878973 0.971131 -0.839103 +v 0.885390 0.968473 -0.839103 +v 0.891807 0.971131 -0.839103 +v 0.894465 0.977548 -0.839103 +vt 0.445897 0.773636 +vt 0.444622 0.773636 +vt 0.444622 0.774577 +vt 0.445897 0.774577 +vt 0.447224 0.774577 +vt 0.448500 0.774577 +vt 0.448500 0.773912 +vt 0.447224 0.773912 +vt 0.447224 0.773912 +vt 0.448500 0.773912 +vt 0.448500 0.772971 +vt 0.447224 0.772971 +vt 0.444596 0.772971 +vt 0.443320 0.772971 +vt 0.443320 0.773636 +vt 0.444596 0.773636 +vt 0.444596 0.773636 +vt 0.443320 0.773636 +vt 0.443320 0.774577 +vt 0.444596 0.774577 +vt 0.449801 0.772971 +vt 0.448525 0.772971 +vt 0.448525 0.773636 +vt 0.449801 0.773636 +vt 0.540704 0.774141 +vt 0.540704 0.773778 +vt 0.540121 0.773778 +vt 0.540121 0.774141 +vt 0.449801 0.773636 +vt 0.448525 0.773636 +vt 0.448525 0.774577 +vt 0.449801 0.774577 +vt 0.445897 0.772971 +vt 0.444622 0.772971 +vt 0.444622 0.773636 +vt 0.445897 0.773636 +vt 0.472735 0.774795 +vt 0.472221 0.774795 +vt 0.472008 0.775311 +vt 0.472949 0.775311 +vt 0.472221 0.774795 +vt 0.471858 0.774432 +vt 0.471342 0.774645 +vt 0.472008 0.775311 +vt 0.471858 0.774432 +vt 0.471858 0.773918 +vt 0.471342 0.773705 +vt 0.471342 0.774645 +vt 0.471858 0.773918 +vt 0.472221 0.773555 +vt 0.472008 0.773039 +vt 0.471342 0.773705 +vt 0.472221 0.773555 +vt 0.472735 0.773555 +vt 0.472949 0.773039 +vt 0.472008 0.773039 +vt 0.472735 0.773555 +vt 0.473098 0.773918 +vt 0.473614 0.773705 +vt 0.472949 0.773039 +vt 0.473098 0.774432 +vt 0.473614 0.774645 +vt 0.540704 0.773264 +vt 0.540704 0.772901 +vt 0.540121 0.772901 +vt 0.540121 0.773264 +vt 0.544105 0.773811 +vt 0.544105 0.773297 +vt 0.543522 0.773297 +vt 0.543522 0.773811 +vt 0.432489 0.773002 +vt 0.431975 0.773002 +vt 0.431975 0.773585 +vt 0.432489 0.773585 +vt 0.540704 0.773778 +vt 0.540704 0.773264 +vt 0.540121 0.773264 +vt 0.540121 0.773778 +vt 0.542927 0.772934 +vt 0.542927 0.773448 +vt 0.543510 0.773448 +vt 0.543510 0.772934 +vt 0.542927 0.773448 +vt 0.542927 0.773811 +vt 0.543510 0.773811 +vt 0.543510 0.773448 +vt 0.544105 0.773297 +vt 0.544105 0.772934 +vt 0.543522 0.772934 +vt 0.543522 0.773297 +vt 0.479901 0.773039 +vt 0.480566 0.774645 +vt 0.480566 0.773705 +vt 0.478960 0.773039 +vt 0.479901 0.775311 +vt 0.478960 0.775311 +vt 0.478294 0.773705 +vt 0.478294 0.774645 +vt 0.453856 0.773212 +vt 0.454733 0.772848 +vt 0.454219 0.772848 +vt 0.453856 0.773725 +vt 0.455096 0.773212 +vt 0.454219 0.774088 +vt 0.455096 0.773725 +vt 0.454733 0.774088 +vn 0.3827 0.9239 0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.9239 -0.3827 0.0000 +vn 0.3827 -0.9239 0.0000 +vn -0.3827 -0.9239 0.0000 +vn -0.9239 -0.3827 0.0000 +vn -0.9239 0.3827 0.0000 +vn -0.3827 0.9239 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +usemtl Scene_-_Root +s off +f 23169/23169/16697 23170/23170/16697 23171/23171/16697 +f 23169/23169/16697 23171/23171/16697 23172/23172/16697 +f 23173/23173/16698 23174/23174/16698 23175/23175/16698 +f 23173/23173/16698 23175/23175/16698 23176/23176/16698 +f 23177/23177/16699 23178/23178/16699 23179/23179/16699 +f 23177/23177/16699 23179/23179/16699 23180/23180/16699 +f 23181/23181/16700 23182/23182/16700 23183/23183/16700 +f 23181/23181/16700 23183/23183/16700 23184/23184/16700 +f 23185/23185/16701 23186/23186/16701 23187/23187/16701 +f 23185/23185/16701 23187/23187/16701 23188/23188/16701 +f 23189/23189/16702 23190/23190/16702 23191/23191/16702 +f 23189/23189/16702 23191/23191/16702 23192/23192/16702 +f 23193/23193/16700 23194/23194/16700 23195/23195/16700 +f 23193/23193/16700 23195/23195/16700 23196/23196/16700 +f 23197/23197/16703 23198/23198/16703 23199/23199/16703 +f 23197/23197/16703 23199/23199/16703 23200/23200/16703 +f 23201/23201/16704 23202/23202/16704 23203/23203/16704 +f 23201/23201/16704 23203/23203/16704 23204/23204/16704 +f 23205/23205/16705 23206/23206/16705 23207/23207/16705 +f 23205/23205/16705 23207/23207/16705 23208/23208/16705 +f 23209/23209/16705 23210/23210/16705 23211/23211/16705 +f 23209/23209/16705 23211/23211/16705 23212/23212/16705 +f 23213/23213/16705 23214/23214/16705 23215/23215/16705 +f 23213/23213/16705 23215/23215/16705 23216/23216/16705 +f 23217/23217/16705 23218/23218/16705 23219/23219/16705 +f 23217/23217/16705 23219/23219/16705 23220/23220/16705 +f 23221/23221/16705 23222/23222/16705 23223/23223/16705 +f 23221/23221/16705 23223/23223/16705 23224/23224/16705 +f 23225/23225/16705 23226/23226/16705 23227/23227/16705 +f 23225/23225/16705 23227/23227/16705 23228/23228/16705 +f 23226/23226/16705 23229/23229/16705 23230/23230/16705 +f 23226/23226/16705 23230/23230/16705 23227/23227/16705 +f 23229/23229/16705 23205/23205/16705 23208/23208/16705 +f 23229/23229/16705 23208/23208/16705 23230/23230/16705 +f 23231/23231/16698 23232/23232/16698 23233/23233/16698 +f 23231/23231/16698 23233/23233/16698 23234/23234/16698 +f 23235/23235/16703 23236/23236/16703 23237/23237/16703 +f 23235/23235/16703 23237/23237/16703 23238/23238/16703 +f 23239/23239/16701 23240/23240/16701 23241/23241/16701 +f 23239/23239/16701 23241/23241/16701 23242/23242/16701 +f 23243/23243/16699 23244/23244/16699 23245/23245/16699 +f 23243/23243/16699 23245/23245/16699 23246/23246/16699 +f 23247/23247/16697 23248/23248/16697 23249/23249/16697 +f 23247/23247/16697 23249/23249/16697 23250/23250/16697 +f 23251/23251/16704 23252/23252/16704 23253/23253/16704 +f 23251/23251/16704 23253/23253/16704 23254/23254/16704 +f 23255/23255/16702 23256/23256/16702 23257/23257/16702 +f 23255/23255/16702 23257/23257/16702 23258/23258/16702 +f 23266/23259/16706 23264/23260/16706 23265/23261/16706 +f 23264/23260/16706 23266/23259/16706 23259/23262/16706 +f 23264/23260/16706 23259/23262/16706 23263/23263/16706 +f 23263/23263/16706 23259/23262/16706 23262/23264/16706 +f 23262/23264/16706 23259/23262/16706 23260/23265/16706 +f 23262/23264/16706 23260/23265/16706 23261/23266/16706 +f 23271/23267/16705 23269/23268/16705 23270/23269/16705 +f 23269/23268/16705 23271/23267/16705 23272/23270/16705 +f 23269/23268/16705 23272/23270/16705 23268/23271/16705 +f 23268/23271/16705 23272/23270/16705 23273/23272/16705 +f 23268/23271/16705 23273/23272/16705 23267/23273/16705 +f 23267/23273/16705 23273/23272/16705 23274/23274/16705 +o Cylinder.038__0 +v 0.885390 0.994171 -0.179777 +v 0.885390 0.994171 -0.162531 +v 0.897144 0.989302 -0.162531 +v 0.897144 0.989302 -0.179777 +v 0.897144 0.989302 -0.179777 +v 0.897144 0.989302 -0.162531 +v 0.902013 0.977548 -0.162531 +v 0.902013 0.977548 -0.179777 +v 0.902013 0.977548 -0.179777 +v 0.902013 0.977548 -0.162531 +v 0.897144 0.965794 -0.162531 +v 0.897144 0.965794 -0.179777 +v 0.897144 0.965794 -0.179777 +v 0.897144 0.965794 -0.162531 +v 0.885390 0.960925 -0.162531 +v 0.885390 0.960925 -0.179777 +v 0.885390 0.960925 -0.179777 +v 0.885390 0.960925 -0.162531 +v 0.873636 0.965794 -0.162531 +v 0.873636 0.965794 -0.179777 +v 0.873636 0.965794 -0.179777 +v 0.873636 0.965794 -0.162531 +v 0.868767 0.977548 -0.162531 +v 0.868767 0.977548 -0.179777 +v 0.868767 0.977548 -0.179777 +v 0.868767 0.977548 -0.162531 +v 0.873636 0.989302 -0.162531 +v 0.873636 0.989302 -0.179777 +v 0.873636 0.989302 -0.179777 +v 0.873636 0.989302 -0.162531 +v 0.885390 0.994171 -0.162531 +v 0.885390 0.994171 -0.179777 +v 0.891497 0.971442 -0.179777 +v 0.885390 0.968912 -0.179777 +v 0.885390 0.968912 -0.188992 +v 0.891497 0.971442 -0.188992 +v 0.891497 0.983654 -0.179777 +v 0.885390 0.986184 -0.179777 +v 0.885390 0.994171 -0.179777 +v 0.897144 0.989302 -0.179777 +v 0.894026 0.977548 -0.179777 +v 0.891497 0.983654 -0.179777 +v 0.897144 0.989302 -0.179777 +v 0.902013 0.977548 -0.179777 +v 0.891497 0.971442 -0.179777 +v 0.894026 0.977548 -0.179777 +v 0.902013 0.977548 -0.179777 +v 0.897144 0.965794 -0.179777 +v 0.885390 0.968912 -0.179777 +v 0.891497 0.971442 -0.179777 +v 0.897144 0.965794 -0.179777 +v 0.885390 0.960925 -0.179777 +v 0.879283 0.971442 -0.179777 +v 0.873636 0.965794 -0.179777 +v 0.876754 0.977548 -0.179777 +v 0.879283 0.971442 -0.179777 +v 0.873636 0.965794 -0.179777 +v 0.868767 0.977548 -0.179777 +v 0.879283 0.983654 -0.179777 +v 0.876754 0.977548 -0.179777 +v 0.868767 0.977548 -0.179777 +v 0.873636 0.989302 -0.179777 +v 0.885390 0.986184 -0.179777 +v 0.879283 0.983654 -0.179777 +v 0.873636 0.989302 -0.179777 +v 0.885390 0.994171 -0.179777 +v 0.891497 0.983654 -0.179777 +v 0.894026 0.977548 -0.179777 +v 0.894026 0.977548 -0.188992 +v 0.891497 0.983654 -0.188992 +v 0.876754 0.977548 -0.179777 +v 0.879283 0.983654 -0.179777 +v 0.879283 0.983654 -0.188992 +v 0.876754 0.977548 -0.188992 +v 0.885390 0.968912 -0.179777 +v 0.879283 0.971442 -0.179777 +v 0.879283 0.971442 -0.188992 +v 0.885390 0.968912 -0.188992 +v 0.894026 0.977548 -0.179777 +v 0.891497 0.971442 -0.179777 +v 0.891497 0.971442 -0.188992 +v 0.894026 0.977548 -0.188992 +v 0.885390 0.986184 -0.179777 +v 0.891497 0.983654 -0.179777 +v 0.891497 0.983654 -0.188992 +v 0.885390 0.986184 -0.188992 +v 0.879283 0.983654 -0.179777 +v 0.885390 0.986184 -0.179777 +v 0.885390 0.986184 -0.188992 +v 0.879283 0.983654 -0.188992 +v 0.879283 0.971442 -0.179777 +v 0.876754 0.977548 -0.179777 +v 0.876754 0.977548 -0.188992 +v 0.879283 0.971442 -0.188992 +v 0.897144 0.989302 -0.162531 +v 0.885390 0.994171 -0.162531 +v 0.873636 0.989302 -0.162531 +v 0.868767 0.977548 -0.162531 +v 0.873636 0.965794 -0.162531 +v 0.885390 0.960925 -0.162531 +v 0.897144 0.965794 -0.162531 +v 0.902013 0.977548 -0.162531 +v 0.885390 0.986184 -0.188992 +v 0.891497 0.983654 -0.188992 +v 0.894026 0.977548 -0.188992 +v 0.891497 0.971442 -0.188992 +v 0.885390 0.968912 -0.188992 +v 0.879283 0.971442 -0.188992 +v 0.876754 0.977548 -0.188992 +v 0.879283 0.983654 -0.188992 +vt 0.535466 0.772885 +vt 0.535466 0.774161 +vt 0.536407 0.774161 +vt 0.536407 0.772885 +vt 0.445923 0.774577 +vt 0.447198 0.774577 +vt 0.447198 0.773912 +vt 0.445923 0.773912 +vt 0.445923 0.773912 +vt 0.447198 0.773912 +vt 0.447198 0.772971 +vt 0.445923 0.772971 +vt 0.443295 0.772971 +vt 0.442019 0.772971 +vt 0.442019 0.773636 +vt 0.443295 0.773636 +vt 0.443295 0.773636 +vt 0.442019 0.773636 +vt 0.442019 0.774577 +vt 0.443295 0.774577 +vt 0.289484 0.248103 +vt 0.288209 0.248103 +vt 0.288209 0.248769 +vt 0.289484 0.248769 +vt 0.289484 0.248769 +vt 0.288209 0.248769 +vt 0.288209 0.249709 +vt 0.289484 0.249709 +vt 0.289484 0.249709 +vt 0.288209 0.249709 +vt 0.288209 0.250375 +vt 0.289484 0.250375 +vt 0.539427 0.773735 +vt 0.539427 0.774081 +vt 0.540109 0.774081 +vt 0.540109 0.773735 +vt 0.481503 0.774765 +vt 0.481157 0.774419 +vt 0.480612 0.774645 +vt 0.481277 0.775311 +vt 0.481992 0.774765 +vt 0.481503 0.774765 +vt 0.481277 0.775311 +vt 0.482218 0.775311 +vt 0.482338 0.774419 +vt 0.481992 0.774765 +vt 0.482218 0.775311 +vt 0.482884 0.774645 +vt 0.482338 0.773931 +vt 0.482338 0.774419 +vt 0.482884 0.774645 +vt 0.482884 0.773705 +vt 0.481992 0.773585 +vt 0.482218 0.773039 +vt 0.481503 0.773585 +vt 0.481992 0.773585 +vt 0.482218 0.773039 +vt 0.481277 0.773039 +vt 0.481157 0.773931 +vt 0.481503 0.773585 +vt 0.481277 0.773039 +vt 0.480612 0.773705 +vt 0.481157 0.774419 +vt 0.481157 0.773931 +vt 0.480612 0.773705 +vt 0.480612 0.774645 +vt 0.539427 0.772901 +vt 0.539427 0.773246 +vt 0.540109 0.773246 +vt 0.540109 0.772901 +vt 0.542233 0.773279 +vt 0.542233 0.773768 +vt 0.542914 0.773768 +vt 0.542914 0.773279 +vt 0.431965 0.772903 +vt 0.431476 0.772903 +vt 0.431476 0.773584 +vt 0.431965 0.773584 +vt 0.539427 0.773246 +vt 0.539427 0.773735 +vt 0.540109 0.773735 +vt 0.540109 0.773246 +vt 0.542219 0.773423 +vt 0.542219 0.772934 +vt 0.541537 0.772934 +vt 0.541537 0.773423 +vt 0.542219 0.773768 +vt 0.542219 0.773423 +vt 0.541537 0.773423 +vt 0.541537 0.773768 +vt 0.542233 0.772934 +vt 0.542233 0.773279 +vt 0.542914 0.773279 +vt 0.542914 0.772934 +vt 0.470632 0.773039 +vt 0.471297 0.774645 +vt 0.471297 0.773705 +vt 0.469690 0.773039 +vt 0.470632 0.775311 +vt 0.469025 0.773705 +vt 0.469690 0.775311 +vt 0.469025 0.774645 +vt 0.459859 0.773305 +vt 0.460694 0.772959 +vt 0.460205 0.772959 +vt 0.461039 0.773305 +vt 0.459859 0.773794 +vt 0.461039 0.773794 +vt 0.460205 0.774139 +vt 0.460694 0.774139 +vn 0.3827 0.9239 0.0000 +vn 0.9239 0.3827 0.0000 +vn 0.9239 -0.3827 0.0000 +vn 0.3827 -0.9239 0.0000 +vn -0.3827 -0.9239 0.0000 +vn -0.9239 -0.3827 0.0000 +vn -0.9239 0.3827 0.0000 +vn -0.3827 0.9239 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +usemtl Scene_-_Root +s off +f 23275/23275/16707 23276/23276/16707 23277/23277/16707 +f 23275/23275/16707 23277/23277/16707 23278/23278/16707 +f 23279/23279/16708 23280/23280/16708 23281/23281/16708 +f 23279/23279/16708 23281/23281/16708 23282/23282/16708 +f 23283/23283/16709 23284/23284/16709 23285/23285/16709 +f 23283/23283/16709 23285/23285/16709 23286/23286/16709 +f 23287/23287/16710 23288/23288/16710 23289/23289/16710 +f 23287/23287/16710 23289/23289/16710 23290/23290/16710 +f 23291/23291/16711 23292/23292/16711 23293/23293/16711 +f 23291/23291/16711 23293/23293/16711 23294/23294/16711 +f 23295/23295/16712 23296/23296/16712 23297/23297/16712 +f 23295/23295/16712 23297/23297/16712 23298/23298/16712 +f 23299/23299/16713 23300/23300/16713 23301/23301/16713 +f 23299/23299/16713 23301/23301/16713 23302/23302/16713 +f 23303/23303/16714 23304/23304/16714 23305/23305/16714 +f 23303/23303/16714 23305/23305/16714 23306/23306/16714 +f 23307/23307/16710 23308/23308/16710 23309/23309/16710 +f 23307/23307/16710 23309/23309/16710 23310/23310/16710 +f 23311/23311/16715 23312/23312/16715 23313/23313/16715 +f 23311/23311/16715 23313/23313/16715 23314/23314/16715 +f 23315/23315/16715 23316/23316/16715 23317/23317/16715 +f 23315/23315/16715 23317/23317/16715 23318/23318/16715 +f 23319/23319/16715 23320/23320/16715 23321/23321/16715 +f 23319/23319/16715 23321/23321/16715 23322/23322/16715 +f 23323/23323/16715 23324/23324/16715 23325/23325/16715 +f 23323/23323/16715 23325/23325/16715 23326/23326/16715 +f 23327/23327/16715 23323/23323/16715 23326/23326/16715 +f 23327/23327/16715 23326/23326/16715 23328/23328/16715 +f 23329/23329/16715 23330/23330/16715 23331/23331/16715 +f 23329/23329/16715 23331/23331/16715 23332/23332/16715 +f 23333/23333/16715 23334/23334/16715 23335/23335/16715 +f 23333/23333/16715 23335/23335/16715 23336/23336/16715 +f 23337/23337/16715 23338/23338/16715 23339/23339/16715 +f 23337/23337/16715 23339/23339/16715 23340/23340/16715 +f 23341/23341/16708 23342/23342/16708 23343/23343/16708 +f 23341/23341/16708 23343/23343/16708 23344/23344/16708 +f 23345/23345/16713 23346/23346/16713 23347/23347/16713 +f 23345/23345/16713 23347/23347/16713 23348/23348/16713 +f 23349/23349/16711 23350/23350/16711 23351/23351/16711 +f 23349/23349/16711 23351/23351/16711 23352/23352/16711 +f 23353/23353/16709 23354/23354/16709 23355/23355/16709 +f 23353/23353/16709 23355/23355/16709 23356/23356/16709 +f 23357/23357/16707 23358/23358/16707 23359/23359/16707 +f 23357/23357/16707 23359/23359/16707 23360/23360/16707 +f 23361/23361/16714 23362/23362/16714 23363/23363/16714 +f 23361/23361/16714 23363/23363/16714 23364/23364/16714 +f 23365/23365/16712 23366/23366/16712 23367/23367/16712 +f 23365/23365/16712 23367/23367/16712 23368/23368/16712 +f 23373/23369/16716 23371/23370/16716 23372/23371/16716 +f 23371/23370/16716 23373/23369/16716 23374/23372/16716 +f 23371/23370/16716 23374/23372/16716 23370/23373/16716 +f 23370/23373/16716 23374/23372/16716 23375/23374/16716 +f 23370/23373/16716 23375/23374/16716 23369/23375/16716 +f 23369/23375/16716 23375/23374/16716 23376/23376/16716 +f 23384/23377/16715 23382/23378/16715 23383/23379/16715 +f 23382/23378/16715 23384/23377/16715 23381/23380/16715 +f 23381/23380/16715 23384/23377/16715 23377/23381/16715 +f 23381/23380/16715 23377/23381/16715 23380/23382/16715 +f 23380/23382/16715 23377/23381/16715 23378/23383/16715 +f 23380/23382/16715 23378/23383/16715 23379/23384/16715 +o Cylinder.039__0 +v 0.885390 0.990541 -0.115633 +v 0.885390 0.989774 -0.101434 +v 0.897144 0.984913 -0.101697 +v 0.897144 0.985679 -0.115896 +v 0.897144 0.985679 -0.115896 +v 0.897144 0.984913 -0.101697 +v 0.902013 0.973176 -0.102330 +v 0.902013 0.973942 -0.116530 +v 0.902013 0.973942 -0.116530 +v 0.902013 0.973176 -0.102330 +v 0.897144 0.961438 -0.102964 +v 0.897144 0.962205 -0.117163 +v 0.897144 0.962205 -0.117163 +v 0.897144 0.961438 -0.102964 +v 0.885390 0.956577 -0.103226 +v 0.885390 0.957343 -0.117426 +v 0.885390 0.957343 -0.117426 +v 0.885390 0.956577 -0.103226 +v 0.873636 0.961438 -0.102964 +v 0.873636 0.962205 -0.117163 +v 0.873636 0.962205 -0.117163 +v 0.873636 0.961438 -0.102964 +v 0.868767 0.973176 -0.102330 +v 0.868767 0.973942 -0.116530 +v 0.868767 0.973942 -0.116530 +v 0.868767 0.973176 -0.102330 +v 0.873636 0.984913 -0.101697 +v 0.873636 0.985679 -0.115896 +v 0.873636 0.985679 -0.115896 +v 0.873636 0.984913 -0.101697 +v 0.885390 0.989774 -0.101434 +v 0.885390 0.990541 -0.115633 +v 0.897144 0.984913 -0.101697 +v 0.885390 0.989774 -0.101434 +v 0.873636 0.984913 -0.101697 +v 0.868767 0.973176 -0.102330 +v 0.873636 0.961438 -0.102964 +v 0.885390 0.956577 -0.103226 +v 0.897144 0.961438 -0.102964 +v 0.902013 0.973176 -0.102330 +v 0.885390 0.990541 -0.115633 +v 0.897144 0.985679 -0.115896 +v 0.902013 0.973942 -0.116530 +v 0.897144 0.962205 -0.117163 +v 0.885390 0.957343 -0.117426 +v 0.873636 0.962205 -0.117163 +v 0.868767 0.973942 -0.116530 +v 0.873636 0.985679 -0.115896 +vt 0.508289 0.773941 +vt 0.507237 0.773941 +vt 0.507237 0.774882 +vt 0.508289 0.774882 +vt 0.215411 0.275472 +vt 0.214359 0.275472 +vt 0.214359 0.276137 +vt 0.215411 0.276137 +vt 0.215411 0.276137 +vt 0.214359 0.276137 +vt 0.214359 0.277078 +vt 0.215411 0.277078 +vt 0.215411 0.277078 +vt 0.214359 0.277078 +vt 0.214359 0.277743 +vt 0.215411 0.277743 +vt 0.538451 0.773951 +vt 0.538451 0.772899 +vt 0.537510 0.772899 +vt 0.537510 0.773951 +vt 0.203174 0.417697 +vt 0.202122 0.417697 +vt 0.202122 0.418362 +vt 0.203174 0.418362 +vt 0.203174 0.418362 +vt 0.202122 0.418362 +vt 0.202122 0.419303 +vt 0.203174 0.419303 +vt 0.508289 0.773276 +vt 0.507237 0.773276 +vt 0.507237 0.773941 +vt 0.508289 0.773941 +vt 0.467373 0.773039 +vt 0.468980 0.773705 +vt 0.468314 0.773039 +vt 0.466708 0.773705 +vt 0.468980 0.774645 +vt 0.466708 0.774645 +vt 0.468314 0.775311 +vt 0.467373 0.775311 +vt 0.475977 0.773705 +vt 0.477583 0.773039 +vt 0.476642 0.773039 +vt 0.475977 0.774645 +vt 0.478249 0.773705 +vt 0.478249 0.774645 +vt 0.476642 0.775311 +vt 0.477583 0.775311 +vn 0.3827 0.9225 0.0498 +vn 0.9239 0.3821 0.0206 +vn 0.9239 -0.3821 -0.0206 +vn 0.3827 -0.9225 -0.0498 +vn -0.3827 -0.9225 -0.0498 +vn -0.9239 -0.3821 -0.0206 +vn -0.9239 0.3821 0.0206 +vn -0.3827 0.9225 0.0498 +vn -0.0000 -0.0539 0.9985 +vn 0.0000 0.0539 -0.9985 +usemtl Scene_-_Root +s off +f 23385/23385/16717 23386/23386/16717 23387/23387/16717 +f 23385/23385/16717 23387/23387/16717 23388/23388/16717 +f 23389/23389/16718 23390/23390/16718 23391/23391/16718 +f 23389/23389/16718 23391/23391/16718 23392/23392/16718 +f 23393/23393/16719 23394/23394/16719 23395/23395/16719 +f 23393/23393/16719 23395/23395/16719 23396/23396/16719 +f 23397/23397/16720 23398/23398/16720 23399/23399/16720 +f 23397/23397/16720 23399/23399/16720 23400/23400/16720 +f 23401/23401/16721 23402/23402/16721 23403/23403/16721 +f 23401/23401/16721 23403/23403/16721 23404/23404/16721 +f 23405/23405/16722 23406/23406/16722 23407/23407/16722 +f 23405/23405/16722 23407/23407/16722 23408/23408/16722 +f 23409/23409/16723 23410/23410/16723 23411/23411/16723 +f 23409/23409/16723 23411/23411/16723 23412/23412/16723 +f 23413/23413/16724 23414/23414/16724 23415/23415/16724 +f 23413/23413/16724 23415/23415/16724 23416/23416/16724 +f 23421/23417/16725 23419/23418/16725 23420/23419/16725 +f 23419/23418/16725 23421/23417/16725 23422/23420/16725 +f 23419/23418/16725 23422/23420/16725 23418/23421/16725 +f 23418/23421/16725 23422/23420/16725 23423/23422/16725 +f 23418/23421/16725 23423/23422/16725 23417/23423/16725 +f 23417/23423/16725 23423/23422/16725 23424/23424/16725 +f 23432/23425/16726 23430/23426/16726 23431/23427/16726 +f 23430/23426/16726 23432/23425/16726 23425/23428/16726 +f 23430/23426/16726 23425/23428/16726 23429/23429/16726 +f 23429/23429/16726 23425/23428/16726 23428/23430/16726 +f 23428/23430/16726 23425/23428/16726 23426/23431/16726 +f 23428/23430/16726 23426/23431/16726 23427/23432/16726 +o Cylinder.040__0 +v 0.683448 1.116407 -1.017704 +v 0.683448 1.118585 -0.990245 +v 0.701023 1.111328 -0.989670 +v 0.701023 1.109150 -1.017128 +v 0.701023 1.109150 -1.017128 +v 0.701023 1.111328 -0.989670 +v 0.708303 1.093808 -0.988280 +v 0.708303 1.091630 -1.015738 +v 0.708303 1.091630 -1.015738 +v 0.708303 1.093808 -0.988280 +v 0.701023 1.076288 -0.986889 +v 0.701023 1.074110 -1.014348 +v 0.701023 1.074110 -1.014348 +v 0.701023 1.076288 -0.986889 +v 0.683448 1.069031 -0.986313 +v 0.683448 1.066852 -1.013772 +v 0.683448 1.066852 -1.013772 +v 0.683448 1.069031 -0.986313 +v 0.665873 1.076288 -0.986889 +v 0.665873 1.074110 -1.014348 +v 0.665873 1.074110 -1.014348 +v 0.665873 1.076288 -0.986889 +v 0.658593 1.093808 -0.988280 +v 0.658593 1.091630 -1.015738 +v 0.658593 1.091630 -1.015738 +v 0.658593 1.093808 -0.988280 +v 0.665873 1.111328 -0.989670 +v 0.665873 1.109150 -1.017128 +v 0.665873 1.109150 -1.017128 +v 0.665873 1.111328 -0.989670 +v 0.683448 1.118585 -0.990245 +v 0.683448 1.116407 -1.017704 +v 0.701023 1.111328 -0.989670 +v 0.683448 1.118585 -0.990245 +v 0.665873 1.111328 -0.989670 +v 0.658593 1.093808 -0.988280 +v 0.665873 1.076288 -0.986889 +v 0.683448 1.069031 -0.986313 +v 0.701023 1.076288 -0.986889 +v 0.708303 1.093808 -0.988280 +v 0.683448 1.116407 -1.017704 +v 0.701023 1.109150 -1.017128 +v 0.708303 1.091630 -1.015738 +v 0.701023 1.074110 -1.014348 +v 0.683448 1.066852 -1.013772 +v 0.665873 1.074110 -1.014348 +v 0.658593 1.091630 -1.015738 +v 0.665873 1.109150 -1.017128 +vt 0.923135 0.731589 +vt 0.921097 0.731589 +vt 0.921097 0.732996 +vt 0.923135 0.732996 +vt 0.923135 0.732996 +vt 0.921097 0.732996 +vt 0.921097 0.733990 +vt 0.923135 0.733990 +vt 0.497708 0.775427 +vt 0.499746 0.775427 +vt 0.499746 0.774432 +vt 0.497708 0.774432 +vt 0.497708 0.774432 +vt 0.499746 0.774432 +vt 0.499746 0.773025 +vt 0.497708 0.773025 +vt 0.937894 0.426589 +vt 0.935857 0.426589 +vt 0.935857 0.427584 +vt 0.937894 0.427584 +vt 0.937894 0.427584 +vt 0.935857 0.427584 +vt 0.935857 0.428991 +vt 0.937894 0.428991 +vt 0.937894 0.428991 +vt 0.935857 0.428991 +vt 0.935857 0.429985 +vt 0.937894 0.429985 +vt 0.923135 0.730594 +vt 0.921097 0.730594 +vt 0.921097 0.731589 +vt 0.923135 0.731589 +vt 0.680083 0.111933 +vt 0.677681 0.110938 +vt 0.678676 0.111933 +vt 0.681078 0.110938 +vt 0.677681 0.109532 +vt 0.681078 0.109532 +vt 0.678676 0.108537 +vt 0.680083 0.108537 +vt 0.677613 0.110938 +vt 0.675211 0.111933 +vt 0.676618 0.111933 +vt 0.677613 0.109532 +vt 0.674216 0.110938 +vt 0.674216 0.109532 +vt 0.676618 0.108537 +vt 0.675211 0.108537 +vn 0.3827 0.9210 -0.0731 +vn 0.9239 0.3815 -0.0303 +vn 0.9239 -0.3815 0.0303 +vn 0.3827 -0.9210 0.0731 +vn -0.3827 -0.9210 0.0731 +vn -0.9239 -0.3815 0.0303 +vn -0.9239 0.3815 -0.0303 +vn -0.3827 0.9210 -0.0731 +vn -0.0000 0.0791 0.9969 +vn 0.0000 -0.0791 -0.9969 +usemtl Scene_-_Root +s off +f 23433/23433/16727 23434/23434/16727 23435/23435/16727 +f 23433/23433/16727 23435/23435/16727 23436/23436/16727 +f 23437/23437/16728 23438/23438/16728 23439/23439/16728 +f 23437/23437/16728 23439/23439/16728 23440/23440/16728 +f 23441/23441/16729 23442/23442/16729 23443/23443/16729 +f 23441/23441/16729 23443/23443/16729 23444/23444/16729 +f 23445/23445/16730 23446/23446/16730 23447/23447/16730 +f 23445/23445/16730 23447/23447/16730 23448/23448/16730 +f 23449/23449/16731 23450/23450/16731 23451/23451/16731 +f 23449/23449/16731 23451/23451/16731 23452/23452/16731 +f 23453/23453/16732 23454/23454/16732 23455/23455/16732 +f 23453/23453/16732 23455/23455/16732 23456/23456/16732 +f 23457/23457/16733 23458/23458/16733 23459/23459/16733 +f 23457/23457/16733 23459/23459/16733 23460/23460/16733 +f 23461/23461/16734 23462/23462/16734 23463/23463/16734 +f 23461/23461/16734 23463/23463/16734 23464/23464/16734 +f 23469/23465/16735 23467/23466/16735 23468/23467/16735 +f 23467/23466/16735 23469/23465/16735 23470/23468/16735 +f 23467/23466/16735 23470/23468/16735 23466/23469/16735 +f 23466/23469/16735 23470/23468/16735 23471/23470/16735 +f 23466/23469/16735 23471/23470/16735 23465/23471/16735 +f 23465/23471/16735 23471/23470/16735 23472/23472/16735 +f 23480/23473/16736 23478/23474/16736 23479/23475/16736 +f 23478/23474/16736 23480/23473/16736 23473/23476/16736 +f 23478/23474/16736 23473/23476/16736 23477/23477/16736 +f 23477/23477/16736 23473/23476/16736 23476/23478/16736 +f 23476/23478/16736 23473/23476/16736 23474/23479/16736 +f 23476/23478/16736 23474/23479/16736 23475/23480/16736 +o Cylinder.041__0 +v -0.015857 1.109647 -1.017704 +v -0.017381 1.111204 -0.990245 +v 0.000255 1.118312 -0.989670 +v 0.001779 1.116755 -1.017128 +v 0.001779 1.116755 -1.017128 +v 0.000255 1.118312 -0.989670 +v 0.017713 1.110883 -0.988279 +v 0.019237 1.109326 -1.015738 +v 0.019237 1.109326 -1.015738 +v 0.017713 1.110883 -0.988279 +v 0.024765 1.093271 -0.986889 +v 0.026290 1.091714 -1.014348 +v 0.026290 1.091714 -1.014348 +v 0.024765 1.093271 -0.986889 +v 0.017282 1.075791 -0.986313 +v 0.018806 1.074234 -1.013772 +v 0.018806 1.074234 -1.013772 +v 0.017282 1.075791 -0.986313 +v -0.000354 1.068683 -0.986889 +v 0.001170 1.067126 -1.014348 +v 0.001170 1.067126 -1.014348 +v -0.000354 1.068683 -0.986889 +v -0.017812 1.076112 -0.988280 +v -0.016288 1.074555 -1.015738 +v -0.016288 1.074555 -1.015738 +v -0.017812 1.076112 -0.988280 +v -0.024865 1.093724 -0.989670 +v -0.023340 1.092167 -1.017128 +v -0.023340 1.092167 -1.017128 +v -0.024865 1.093724 -0.989670 +v -0.017381 1.111204 -0.990245 +v -0.015857 1.109647 -1.017704 +v 0.000255 1.118312 -0.989670 +v -0.017381 1.111204 -0.990245 +v -0.024865 1.093724 -0.989670 +v -0.017812 1.076112 -0.988280 +v -0.000354 1.068683 -0.986889 +v 0.017282 1.075791 -0.986313 +v 0.024765 1.093271 -0.986889 +v 0.017713 1.110883 -0.988279 +v -0.015857 1.109647 -1.017704 +v 0.001779 1.116755 -1.017128 +v 0.019237 1.109326 -1.015738 +v 0.026290 1.091714 -1.014348 +v 0.018806 1.074234 -1.013772 +v 0.001170 1.067126 -1.014348 +v -0.016288 1.074555 -1.015738 +v -0.023340 1.092167 -1.017128 +vt 0.925776 0.408200 +vt 0.923738 0.408200 +vt 0.923738 0.409607 +vt 0.925776 0.409607 +vt 0.925776 0.409607 +vt 0.923738 0.409607 +vt 0.923738 0.410601 +vt 0.925776 0.410601 +vt 0.519870 0.775896 +vt 0.521908 0.775896 +vt 0.521908 0.774901 +vt 0.519870 0.774901 +vt 0.519870 0.774901 +vt 0.521908 0.774901 +vt 0.521908 0.773494 +vt 0.519870 0.773494 +vt 0.939972 0.426589 +vt 0.937935 0.426589 +vt 0.937935 0.427584 +vt 0.939972 0.427584 +vt 0.939972 0.427584 +vt 0.937935 0.427584 +vt 0.937935 0.428991 +vt 0.939972 0.428991 +vt 0.939972 0.428991 +vt 0.937935 0.428991 +vt 0.937935 0.429985 +vt 0.939972 0.429985 +vt 0.925776 0.407205 +vt 0.923738 0.407205 +vt 0.923738 0.408200 +vt 0.925776 0.408200 +vt 0.890438 0.410104 +vt 0.888036 0.409110 +vt 0.889031 0.410104 +vt 0.891433 0.409110 +vt 0.888036 0.407703 +vt 0.891433 0.407703 +vt 0.889031 0.406708 +vt 0.890438 0.406708 +vt 0.292554 0.112724 +vt 0.290152 0.113718 +vt 0.291559 0.113718 +vt 0.292554 0.111317 +vt 0.289157 0.112724 +vt 0.289157 0.111317 +vt 0.291559 0.110322 +vt 0.290152 0.110322 +vn -0.3707 0.9259 -0.0731 +vn 0.3934 0.9189 -0.0303 +vn 0.9271 0.3736 0.0303 +vn 0.9177 -0.3905 0.0731 +vn 0.3707 -0.9259 0.0731 +vn -0.3934 -0.9189 0.0303 +vn -0.9271 -0.3736 -0.0303 +vn -0.9177 0.3905 -0.0731 +vn -0.0553 0.0565 0.9969 +vn 0.0553 -0.0565 -0.9969 +usemtl Scene_-_Root +s off +f 23481/23481/16737 23482/23482/16737 23483/23483/16737 +f 23481/23481/16737 23483/23483/16737 23484/23484/16737 +f 23485/23485/16738 23486/23486/16738 23487/23487/16738 +f 23485/23485/16738 23487/23487/16738 23488/23488/16738 +f 23489/23489/16739 23490/23490/16739 23491/23491/16739 +f 23489/23489/16739 23491/23491/16739 23492/23492/16739 +f 23493/23493/16740 23494/23494/16740 23495/23495/16740 +f 23493/23493/16740 23495/23495/16740 23496/23496/16740 +f 23497/23497/16741 23498/23498/16741 23499/23499/16741 +f 23497/23497/16741 23499/23499/16741 23500/23500/16741 +f 23501/23501/16742 23502/23502/16742 23503/23503/16742 +f 23501/23501/16742 23503/23503/16742 23504/23504/16742 +f 23505/23505/16743 23506/23506/16743 23507/23507/16743 +f 23505/23505/16743 23507/23507/16743 23508/23508/16743 +f 23509/23509/16744 23510/23510/16744 23511/23511/16744 +f 23509/23509/16744 23511/23511/16744 23512/23512/16744 +f 23517/23513/16745 23515/23514/16745 23516/23515/16745 +f 23515/23514/16745 23517/23513/16745 23518/23516/16745 +f 23515/23514/16745 23518/23516/16745 23514/23517/16745 +f 23514/23517/16745 23518/23516/16745 23519/23518/16745 +f 23514/23517/16745 23519/23518/16745 23513/23519/16745 +f 23513/23519/16745 23519/23518/16745 23520/23520/16745 +f 23528/23521/16746 23526/23522/16746 23527/23523/16746 +f 23526/23522/16746 23528/23521/16746 23521/23524/16746 +f 23526/23522/16746 23521/23524/16746 23525/23525/16746 +f 23525/23525/16746 23521/23524/16746 23524/23526/16746 +f 23524/23526/16746 23521/23524/16746 23522/23527/16746 +f 23524/23526/16746 23522/23527/16746 23523/23528/16746 +o Cylinder.042__0 +v -0.754533 1.090955 -1.017704 +v -0.756705 1.090793 -0.990245 +v -0.750777 1.108860 -0.989670 +v -0.748605 1.109022 -1.017128 +v -0.748605 1.109022 -1.017128 +v -0.750777 1.108860 -0.989670 +v -0.733848 1.117424 -0.988279 +v -0.731675 1.117586 -1.015738 +v -0.731675 1.117586 -1.015738 +v -0.733848 1.117424 -0.988279 +v -0.715834 1.111469 -0.986889 +v -0.713662 1.111631 -1.014348 +v -0.713662 1.111631 -1.014348 +v -0.715834 1.111469 -0.986889 +v -0.707288 1.094483 -0.986313 +v -0.705116 1.094645 -1.013772 +v -0.705116 1.094645 -1.013772 +v -0.707288 1.094483 -0.986313 +v -0.713217 1.076416 -0.986889 +v -0.711045 1.076578 -1.014348 +v -0.711045 1.076578 -1.014348 +v -0.713217 1.076416 -0.986889 +v -0.730147 1.067852 -0.988279 +v -0.727974 1.068014 -1.015738 +v -0.727974 1.068014 -1.015738 +v -0.730147 1.067852 -0.988279 +v -0.748160 1.073807 -0.989670 +v -0.745988 1.073969 -1.017128 +v -0.745988 1.073969 -1.017128 +v -0.748160 1.073807 -0.989670 +v -0.756705 1.090793 -0.990245 +v -0.754533 1.090955 -1.017704 +v -0.750777 1.108860 -0.989670 +v -0.756705 1.090793 -0.990245 +v -0.748160 1.073807 -0.989670 +v -0.730147 1.067852 -0.988279 +v -0.713217 1.076416 -0.986889 +v -0.707288 1.094483 -0.986313 +v -0.715834 1.111469 -0.986889 +v -0.733848 1.117424 -0.988279 +v -0.754533 1.090955 -1.017704 +v -0.748605 1.109022 -1.017128 +v -0.731675 1.117586 -1.015738 +v -0.713662 1.111631 -1.014348 +v -0.705116 1.094645 -1.013772 +v -0.711045 1.076578 -1.014348 +v -0.727974 1.068014 -1.015738 +v -0.745988 1.073969 -1.017128 +vt 0.929369 0.731589 +vt 0.927332 0.731589 +vt 0.927332 0.732996 +vt 0.929369 0.732996 +vt 0.929369 0.732996 +vt 0.927332 0.732996 +vt 0.927332 0.733990 +vt 0.929369 0.733990 +vt 0.493552 0.775427 +vt 0.495589 0.775427 +vt 0.495589 0.774432 +vt 0.493552 0.774432 +vt 0.493552 0.774432 +vt 0.495589 0.774432 +vt 0.495589 0.773025 +vt 0.493552 0.773025 +vt 0.937886 0.896967 +vt 0.935849 0.896967 +vt 0.935849 0.897962 +vt 0.937886 0.897962 +vt 0.937886 0.897962 +vt 0.935849 0.897962 +vt 0.935849 0.899368 +vt 0.937886 0.899368 +vt 0.937886 0.899368 +vt 0.935849 0.899368 +vt 0.935849 0.900363 +vt 0.937886 0.900363 +vt 0.929369 0.730594 +vt 0.927332 0.730594 +vt 0.927332 0.731589 +vt 0.929369 0.731589 +vt 0.068023 0.115661 +vt 0.065621 0.114666 +vt 0.066616 0.115661 +vt 0.069018 0.114666 +vt 0.065621 0.113259 +vt 0.069018 0.113259 +vt 0.066616 0.112265 +vt 0.068023 0.112265 +vt 0.859472 0.152480 +vt 0.857070 0.153475 +vt 0.858477 0.153475 +vt 0.859472 0.151073 +vt 0.856075 0.152480 +vt 0.856075 0.151073 +vt 0.858477 0.150079 +vt 0.857070 0.150079 +vn -0.9469 0.3130 -0.0731 +vn -0.4492 0.8929 -0.0303 +vn 0.3116 0.9497 0.0303 +vn 0.8899 0.4502 0.0731 +vn 0.9469 -0.3131 0.0731 +vn 0.4492 -0.8929 0.0303 +vn -0.3116 -0.9497 -0.0303 +vn -0.8899 -0.4502 -0.0731 +vn -0.0789 -0.0059 0.9969 +vn 0.0789 0.0059 -0.9969 +usemtl Scene_-_Root +s off +f 23529/23529/16747 23530/23530/16747 23531/23531/16747 +f 23529/23529/16747 23531/23531/16747 23532/23532/16747 +f 23533/23533/16748 23534/23534/16748 23535/23535/16748 +f 23533/23533/16748 23535/23535/16748 23536/23536/16748 +f 23537/23537/16749 23538/23538/16749 23539/23539/16749 +f 23537/23537/16749 23539/23539/16749 23540/23540/16749 +f 23541/23541/16750 23542/23542/16750 23543/23543/16750 +f 23541/23541/16750 23543/23543/16750 23544/23544/16750 +f 23545/23545/16751 23546/23546/16751 23547/23547/16751 +f 23545/23545/16751 23547/23547/16751 23548/23548/16751 +f 23549/23549/16752 23550/23550/16752 23551/23551/16752 +f 23549/23549/16752 23551/23551/16752 23552/23552/16752 +f 23553/23553/16753 23554/23554/16753 23555/23555/16753 +f 23553/23553/16753 23555/23555/16753 23556/23556/16753 +f 23557/23557/16754 23558/23558/16754 23559/23559/16754 +f 23557/23557/16754 23559/23559/16754 23560/23560/16754 +f 23565/23561/16755 23563/23562/16755 23564/23563/16755 +f 23563/23562/16755 23565/23561/16755 23566/23564/16755 +f 23563/23562/16755 23566/23564/16755 23562/23565/16755 +f 23562/23565/16755 23566/23564/16755 23567/23566/16755 +f 23562/23565/16755 23567/23566/16755 23561/23567/16755 +f 23561/23567/16755 23567/23566/16755 23568/23568/16755 +f 23576/23569/16756 23574/23570/16756 23575/23571/16756 +f 23574/23570/16756 23576/23569/16756 23569/23572/16756 +f 23574/23570/16756 23569/23572/16756 23573/23573/16756 +f 23573/23573/16756 23569/23572/16756 23572/23574/16756 +f 23572/23574/16756 23569/23572/16756 23570/23575/16756 +f 23572/23574/16756 23570/23575/16756 23571/23576/16756 +o Cylinder.043__0 +v 0.664521 0.751326 -0.997502 +v 0.661711 0.753255 -0.970169 +v 0.677616 0.763653 -0.969268 +v 0.680425 0.761724 -0.996601 +v 0.680425 0.761724 -0.996601 +v 0.677616 0.763653 -0.969268 +v 0.696114 0.759782 -0.967093 +v 0.698923 0.757853 -0.994426 +v 0.698923 0.757853 -0.994426 +v 0.696114 0.759782 -0.967093 +v 0.706369 0.743908 -0.964919 +v 0.709178 0.741978 -0.992252 +v 0.709178 0.741978 -0.992252 +v 0.706369 0.743908 -0.964919 +v 0.702374 0.725330 -0.964018 +v 0.705184 0.723401 -0.991351 +v 0.705184 0.723401 -0.991351 +v 0.702374 0.725330 -0.964018 +v 0.686471 0.714932 -0.964919 +v 0.689280 0.713002 -0.992252 +v 0.689280 0.713002 -0.992252 +v 0.686471 0.714932 -0.964919 +v 0.667973 0.718804 -0.967093 +v 0.670782 0.716874 -0.994426 +v 0.670782 0.716874 -0.994426 +v 0.667973 0.718804 -0.967093 +v 0.657717 0.734677 -0.969268 +v 0.660527 0.732748 -0.996601 +v 0.660527 0.732748 -0.996601 +v 0.657717 0.734677 -0.969268 +v 0.661711 0.753255 -0.970169 +v 0.664521 0.751326 -0.997502 +v 0.677616 0.763653 -0.969268 +v 0.661711 0.753255 -0.970169 +v 0.657717 0.734677 -0.969268 +v 0.667973 0.718804 -0.967093 +v 0.686471 0.714932 -0.964919 +v 0.702374 0.725330 -0.964018 +v 0.706369 0.743908 -0.964919 +v 0.696114 0.759782 -0.967093 +v 0.664521 0.751326 -0.997502 +v 0.680425 0.761724 -0.996601 +v 0.698923 0.757853 -0.994426 +v 0.709178 0.741978 -0.992252 +v 0.705184 0.723401 -0.991351 +v 0.689280 0.713002 -0.992252 +v 0.670782 0.716874 -0.994426 +v 0.660527 0.732748 -0.996601 +vt 0.933677 0.532539 +vt 0.931639 0.532539 +vt 0.931639 0.533946 +vt 0.933677 0.533946 +vt 0.933677 0.533946 +vt 0.931639 0.533946 +vt 0.931639 0.534941 +vt 0.933677 0.534941 +vt 0.489400 0.775309 +vt 0.491438 0.775309 +vt 0.491438 0.774315 +vt 0.489400 0.774315 +vt 0.489400 0.774315 +vt 0.491438 0.774315 +vt 0.491438 0.772908 +vt 0.489400 0.772908 +vt 0.935816 0.426589 +vt 0.933779 0.426589 +vt 0.933779 0.427584 +vt 0.935816 0.427584 +vt 0.935816 0.427584 +vt 0.933779 0.427584 +vt 0.933779 0.428991 +vt 0.935816 0.428991 +vt 0.935816 0.428991 +vt 0.933779 0.428991 +vt 0.933779 0.429985 +vt 0.935816 0.429985 +vt 0.933677 0.531545 +vt 0.931639 0.531545 +vt 0.931639 0.532539 +vt 0.933677 0.532539 +vt 0.403455 0.412872 +vt 0.401052 0.411877 +vt 0.402047 0.412872 +vt 0.404449 0.411877 +vt 0.401052 0.410470 +vt 0.404449 0.410470 +vt 0.402047 0.409476 +vt 0.403455 0.409476 +vt 0.400985 0.411877 +vt 0.398583 0.412872 +vt 0.399990 0.412872 +vt 0.400985 0.410470 +vt 0.397588 0.411877 +vt 0.397588 0.410470 +vt 0.399990 0.409476 +vt 0.398583 0.409476 +vn -0.5391 0.8345 -0.1143 +vn 0.2100 0.9766 -0.0473 +vn 0.8360 0.5466 0.0474 +vn 0.9724 -0.2035 0.1143 +vn 0.5391 -0.8344 0.1143 +vn -0.2100 -0.9766 0.0473 +vn -0.8360 -0.5466 -0.0473 +vn -0.8360 -0.5466 -0.0474 +vn -0.9724 0.2035 -0.1143 +vn -0.1020 0.0700 0.9923 +vn 0.1020 -0.0701 -0.9923 +vn 0.1020 -0.0700 -0.9923 +usemtl Scene_-_Root +s off +f 23577/23577/16757 23578/23578/16757 23579/23579/16757 +f 23577/23577/16757 23579/23579/16757 23580/23580/16757 +f 23581/23581/16758 23582/23582/16758 23583/23583/16758 +f 23581/23581/16758 23583/23583/16758 23584/23584/16758 +f 23585/23585/16759 23586/23586/16759 23587/23587/16759 +f 23585/23585/16759 23587/23587/16759 23588/23588/16759 +f 23589/23589/16760 23590/23590/16760 23591/23591/16760 +f 23589/23589/16760 23591/23591/16760 23592/23592/16760 +f 23593/23593/16761 23594/23594/16761 23595/23595/16761 +f 23593/23593/16761 23595/23595/16761 23596/23596/16761 +f 23597/23597/16762 23598/23598/16762 23599/23599/16762 +f 23597/23597/16762 23599/23599/16762 23600/23600/16762 +f 23601/23601/16763 23602/23602/16763 23603/23603/16763 +f 23601/23601/16764 23603/23603/16764 23604/23604/16764 +f 23605/23605/16765 23606/23606/16765 23607/23607/16765 +f 23605/23605/16765 23607/23607/16765 23608/23608/16765 +f 23613/23609/16766 23611/23610/16766 23612/23611/16766 +f 23611/23610/16766 23613/23609/16766 23614/23612/16766 +f 23611/23610/16766 23614/23612/16766 23610/23613/16766 +f 23610/23613/16766 23614/23612/16766 23615/23614/16766 +f 23610/23613/16766 23615/23614/16766 23609/23615/16766 +f 23609/23615/16766 23615/23614/16766 23616/23616/16766 +f 23624/23617/16767 23622/23618/16767 23623/23619/16767 +f 23622/23618/16768 23624/23617/16768 23617/23620/16768 +f 23622/23618/16768 23617/23620/16768 23621/23621/16768 +f 23621/23621/16768 23617/23620/16768 23620/23622/16768 +f 23620/23622/16768 23617/23620/16768 23618/23623/16768 +f 23620/23622/16768 23618/23623/16768 23619/23624/16768 +o Cylinder.044__0 +v -0.022375 0.740358 -0.997198 +v -0.025321 0.741548 -0.969837 +v -0.016199 0.758239 -0.969581 +v -0.013253 0.757050 -0.996942 +v -0.013253 0.757050 -0.996942 +v -0.016199 0.758239 -0.969581 +v 0.001968 0.763615 -0.967859 +v 0.004913 0.762426 -0.995220 +v 0.004913 0.762426 -0.995220 +v 0.001968 0.763615 -0.967859 +v 0.018536 0.754527 -0.965680 +v 0.021482 0.753337 -0.993041 +v 0.021482 0.753337 -0.993041 +v 0.018536 0.754527 -0.965680 +v 0.023803 0.736297 -0.964321 +v 0.026748 0.735108 -0.991682 +v 0.026748 0.735108 -0.991682 +v 0.023803 0.736297 -0.964321 +v 0.014680 0.719605 -0.964577 +v 0.017626 0.718416 -0.991938 +v 0.017626 0.718416 -0.991938 +v 0.014680 0.719605 -0.964577 +v -0.003486 0.714229 -0.966299 +v -0.000540 0.713040 -0.993660 +v -0.000540 0.713040 -0.993660 +v -0.003486 0.714229 -0.966299 +v -0.020055 0.723318 -0.968478 +v -0.017110 0.722129 -0.995839 +v -0.017110 0.722129 -0.995839 +v -0.020055 0.723318 -0.968478 +v -0.025321 0.741548 -0.969837 +v -0.022375 0.740358 -0.997198 +v -0.016199 0.758239 -0.969581 +v -0.025321 0.741548 -0.969837 +v -0.020055 0.723318 -0.968478 +v -0.003486 0.714229 -0.966299 +v 0.014680 0.719605 -0.964577 +v 0.023803 0.736297 -0.964321 +v 0.018536 0.754527 -0.965680 +v 0.001968 0.763615 -0.967859 +v -0.022375 0.740358 -0.997198 +v -0.013253 0.757050 -0.996942 +v 0.004913 0.762426 -0.995220 +v 0.021482 0.753337 -0.993041 +v 0.026748 0.735108 -0.991682 +v 0.017626 0.718416 -0.991938 +v -0.000540 0.713040 -0.993660 +v -0.017110 0.722129 -0.995839 +vt 0.926858 0.532463 +vt 0.924820 0.532463 +vt 0.924820 0.533870 +vt 0.926858 0.533870 +vt 0.926858 0.533870 +vt 0.924820 0.533870 +vt 0.924820 0.534865 +vt 0.926858 0.534865 +vt 0.487322 0.775309 +vt 0.489359 0.775309 +vt 0.489359 0.774315 +vt 0.487322 0.774315 +vt 0.487322 0.774315 +vt 0.489359 0.774315 +vt 0.489359 0.772908 +vt 0.487322 0.772908 +vt 0.935808 0.896967 +vt 0.933771 0.896967 +vt 0.933771 0.897962 +vt 0.935808 0.897962 +vt 0.935808 0.897962 +vt 0.933771 0.897962 +vt 0.933771 0.899368 +vt 0.935808 0.899368 +vt 0.935808 0.899368 +vt 0.933771 0.899368 +vt 0.933771 0.900363 +vt 0.935808 0.900363 +vt 0.926858 0.531468 +vt 0.924820 0.531468 +vt 0.924820 0.532463 +vt 0.926858 0.532463 +vt 0.396525 0.412872 +vt 0.394123 0.411877 +vt 0.395118 0.412872 +vt 0.397520 0.411877 +vt 0.394123 0.410470 +vt 0.397520 0.410470 +vt 0.395118 0.409476 +vt 0.396525 0.409476 +vt 0.687520 0.112869 +vt 0.685118 0.113863 +vt 0.686525 0.113863 +vt 0.687520 0.111462 +vt 0.684123 0.112869 +vt 0.684123 0.111462 +vt 0.686525 0.110467 +vt 0.685118 0.110467 +vn -0.8710 0.4778 -0.1145 +vn -0.2768 0.9583 -0.0714 +vn 0.4795 0.8774 0.0135 +vn 0.9550 0.2826 0.0905 +vn 0.8710 -0.4778 0.1145 +vn 0.2768 -0.9583 0.0715 +vn -0.4795 -0.8774 -0.0135 +vn -0.9550 -0.2826 -0.0905 +vn -0.1069 0.0432 0.9933 +vn 0.1069 -0.0432 -0.9933 +usemtl Scene_-_Root +s off +f 23625/23625/16769 23626/23626/16769 23627/23627/16769 +f 23625/23625/16769 23627/23627/16769 23628/23628/16769 +f 23629/23629/16770 23630/23630/16770 23631/23631/16770 +f 23629/23629/16770 23631/23631/16770 23632/23632/16770 +f 23633/23633/16771 23634/23634/16771 23635/23635/16771 +f 23633/23633/16771 23635/23635/16771 23636/23636/16771 +f 23637/23637/16772 23638/23638/16772 23639/23639/16772 +f 23637/23637/16772 23639/23639/16772 23640/23640/16772 +f 23641/23641/16773 23642/23642/16773 23643/23643/16773 +f 23641/23641/16773 23643/23643/16773 23644/23644/16773 +f 23645/23645/16774 23646/23646/16774 23647/23647/16774 +f 23645/23645/16774 23647/23647/16774 23648/23648/16774 +f 23649/23649/16775 23650/23650/16775 23651/23651/16775 +f 23649/23649/16775 23651/23651/16775 23652/23652/16775 +f 23653/23653/16776 23654/23654/16776 23655/23655/16776 +f 23653/23653/16776 23655/23655/16776 23656/23656/16776 +f 23661/23657/16777 23659/23658/16777 23660/23659/16777 +f 23659/23658/16777 23661/23657/16777 23662/23660/16777 +f 23659/23658/16777 23662/23660/16777 23658/23661/16777 +f 23658/23661/16777 23662/23660/16777 23663/23662/16777 +f 23658/23661/16777 23663/23662/16777 23657/23663/16777 +f 23657/23663/16777 23663/23662/16777 23664/23664/16777 +f 23672/23665/16778 23670/23666/16778 23671/23667/16778 +f 23670/23666/16778 23672/23665/16778 23665/23668/16778 +f 23670/23666/16778 23665/23668/16778 23669/23669/16778 +f 23669/23669/16778 23665/23668/16778 23668/23670/16778 +f 23668/23670/16778 23665/23668/16778 23666/23671/16778 +f 23668/23670/16778 23666/23671/16778 23667/23672/16778 +o Cylinder.045__0 +v -0.751140 0.752922 -0.996360 +v -0.751965 0.755199 -0.968922 +v -0.735164 0.764119 -0.969157 +v -0.734339 0.761843 -0.996595 +v -0.734339 0.761843 -0.996595 +v -0.735164 0.764119 -0.969157 +v -0.716987 0.758598 -0.968153 +v -0.716162 0.756322 -0.995591 +v -0.716162 0.756322 -0.995591 +v -0.716987 0.758598 -0.968153 +v -0.708082 0.741870 -0.966497 +v -0.707257 0.739593 -0.993935 +v -0.707257 0.739593 -0.993935 +v -0.708082 0.741870 -0.966497 +v -0.713665 0.723734 -0.965160 +v -0.712840 0.721457 -0.992598 +v -0.712840 0.721457 -0.992598 +v -0.713665 0.723734 -0.965160 +v -0.730465 0.714813 -0.964925 +v -0.729640 0.712537 -0.992363 +v -0.729640 0.712537 -0.992363 +v -0.730465 0.714813 -0.964925 +v -0.748642 0.720334 -0.965929 +v -0.747817 0.718057 -0.993367 +v -0.747817 0.718057 -0.993367 +v -0.748642 0.720334 -0.965929 +v -0.757547 0.737062 -0.967585 +v -0.756722 0.734786 -0.995023 +v -0.756722 0.734786 -0.995023 +v -0.757547 0.737062 -0.967585 +v -0.751965 0.755199 -0.968922 +v -0.751140 0.752922 -0.996360 +v -0.735164 0.764119 -0.969157 +v -0.751965 0.755199 -0.968922 +v -0.757547 0.737062 -0.967585 +v -0.748642 0.720334 -0.965929 +v -0.730465 0.714813 -0.964925 +v -0.713665 0.723734 -0.965160 +v -0.708082 0.741870 -0.966497 +v -0.716987 0.758598 -0.968153 +v -0.751140 0.752922 -0.996360 +v -0.734339 0.761843 -0.996595 +v -0.716162 0.756322 -0.995591 +v -0.707257 0.739593 -0.993935 +v -0.712840 0.721457 -0.992598 +v -0.729640 0.712537 -0.992363 +v -0.747817 0.718057 -0.993367 +v -0.756722 0.734786 -0.995023 +vt 0.925213 0.731589 +vt 0.923176 0.731589 +vt 0.923176 0.732996 +vt 0.925213 0.732996 +vt 0.925213 0.732996 +vt 0.923176 0.732996 +vt 0.923176 0.733990 +vt 0.925213 0.733990 +vt 0.485244 0.775309 +vt 0.487281 0.775309 +vt 0.487281 0.774315 +vt 0.485244 0.774315 +vt 0.485244 0.774315 +vt 0.487281 0.774315 +vt 0.487281 0.772908 +vt 0.485244 0.772908 +vt 0.937833 0.531545 +vt 0.935795 0.531545 +vt 0.935795 0.532539 +vt 0.937833 0.532539 +vt 0.937833 0.532539 +vt 0.935795 0.532539 +vt 0.935795 0.533946 +vt 0.937833 0.533946 +vt 0.937833 0.533946 +vt 0.935795 0.533946 +vt 0.935795 0.534941 +vt 0.937833 0.534941 +vt 0.925213 0.730594 +vt 0.923176 0.730594 +vt 0.923176 0.731589 +vt 0.925213 0.731589 +vt 0.295024 0.113718 +vt 0.292622 0.112724 +vt 0.293617 0.113718 +vt 0.296019 0.112724 +vt 0.292622 0.111317 +vt 0.296019 0.111317 +vt 0.293617 0.110322 +vt 0.295024 0.110322 +vt 0.913422 0.732996 +vt 0.911020 0.733990 +vt 0.912427 0.733990 +vt 0.913422 0.731589 +vt 0.910025 0.732996 +vt 0.910025 0.731589 +vt 0.912427 0.730594 +vt 0.911020 0.730594 +vn -0.4681 0.8794 -0.0870 +vn 0.2935 0.9534 -0.0703 +vn 0.8832 0.4689 -0.0124 +vn 0.8831 0.4689 -0.0124 +vn 0.9555 -0.2902 0.0528 +vn 0.4681 -0.8794 0.0870 +vn -0.2935 -0.9534 0.0703 +vn -0.8832 -0.4689 0.0124 +vn -0.9555 0.2902 -0.0528 +vn -0.0299 0.0827 0.9961 +vn -0.0300 0.0826 0.9961 +vn -0.0300 0.0827 0.9961 +vn 0.0299 -0.0827 -0.9961 +vn 0.0300 -0.0827 -0.9961 +usemtl Scene_-_Root +s off +f 23673/23673/16779 23674/23674/16779 23675/23675/16779 +f 23673/23673/16779 23675/23675/16779 23676/23676/16779 +f 23677/23677/16780 23678/23678/16780 23679/23679/16780 +f 23677/23677/16780 23679/23679/16780 23680/23680/16780 +f 23681/23681/16781 23682/23682/16781 23683/23683/16781 +f 23681/23681/16782 23683/23683/16782 23684/23684/16782 +f 23685/23685/16783 23686/23686/16783 23687/23687/16783 +f 23685/23685/16783 23687/23687/16783 23688/23688/16783 +f 23689/23689/16784 23690/23690/16784 23691/23691/16784 +f 23689/23689/16784 23691/23691/16784 23692/23692/16784 +f 23693/23693/16785 23694/23694/16785 23695/23695/16785 +f 23693/23693/16785 23695/23695/16785 23696/23696/16785 +f 23697/23697/16786 23698/23698/16786 23699/23699/16786 +f 23697/23697/16786 23699/23699/16786 23700/23700/16786 +f 23701/23701/16787 23702/23702/16787 23703/23703/16787 +f 23701/23701/16787 23703/23703/16787 23704/23704/16787 +f 23709/23705/16788 23707/23706/16788 23708/23707/16788 +f 23707/23706/16789 23709/23705/16789 23710/23708/16789 +f 23707/23706/16790 23710/23708/16790 23706/23709/16790 +f 23706/23709/16788 23710/23708/16788 23711/23710/16788 +f 23706/23709/16790 23711/23710/16790 23705/23711/16790 +f 23705/23711/16788 23711/23710/16788 23712/23712/16788 +f 23720/23713/16791 23718/23714/16791 23719/23715/16791 +f 23718/23714/16792 23720/23713/16792 23713/23716/16792 +f 23718/23714/16792 23713/23716/16792 23717/23717/16792 +f 23717/23717/16791 23713/23716/16791 23716/23718/16791 +f 23716/23718/16791 23713/23716/16791 23714/23719/16791 +f 23716/23718/16792 23714/23719/16792 23715/23720/16792 +o Cylinder.046__0 +v 0.662527 -1.054489 -0.979021 +v 0.663252 -1.052560 -0.951553 +v 0.679141 -1.042162 -0.952703 +v 0.678415 -1.044091 -0.980171 +v 0.678415 -1.044091 -0.980171 +v 0.679141 -1.042162 -0.952703 +v 0.697765 -1.046033 -0.952923 +v 0.697039 -1.047962 -0.980391 +v 0.697039 -1.047962 -0.980391 +v 0.697765 -1.046033 -0.952923 +v 0.708215 -1.061908 -0.952084 +v 0.707489 -1.063837 -0.979552 +v 0.707489 -1.063837 -0.979552 +v 0.708215 -1.061908 -0.952084 +v 0.704369 -1.080485 -0.950678 +v 0.703643 -1.082414 -0.978145 +v 0.703643 -1.082414 -0.978145 +v 0.704369 -1.080485 -0.950678 +v 0.688481 -1.090883 -0.949528 +v 0.687755 -1.092813 -0.976995 +v 0.687755 -1.092813 -0.976995 +v 0.688481 -1.090883 -0.949528 +v 0.669857 -1.087012 -0.949308 +v 0.669131 -1.088941 -0.976775 +v 0.669131 -1.088941 -0.976775 +v 0.669857 -1.087012 -0.949308 +v 0.659407 -1.071138 -0.950147 +v 0.658681 -1.073067 -0.977614 +v 0.658681 -1.073067 -0.977614 +v 0.659407 -1.071138 -0.950147 +v 0.663252 -1.052560 -0.951553 +v 0.662527 -1.054489 -0.979021 +v 0.679141 -1.042162 -0.952703 +v 0.663252 -1.052560 -0.951553 +v 0.659407 -1.071138 -0.950147 +v 0.669857 -1.087012 -0.949308 +v 0.688481 -1.090883 -0.949528 +v 0.704369 -1.080485 -0.950678 +v 0.708215 -1.061908 -0.952084 +v 0.697765 -1.046033 -0.952923 +v 0.662527 -1.054489 -0.979021 +v 0.678415 -1.044091 -0.980171 +v 0.697039 -1.047962 -0.980391 +v 0.707489 -1.063837 -0.979552 +v 0.703643 -1.082414 -0.978145 +v 0.687755 -1.092813 -0.976995 +v 0.669131 -1.088941 -0.976775 +v 0.658681 -1.073067 -0.977614 +vt 0.918979 0.731589 +vt 0.916941 0.731589 +vt 0.916941 0.732996 +vt 0.918979 0.732996 +vt 0.918979 0.732996 +vt 0.916941 0.732996 +vt 0.916941 0.733990 +vt 0.918979 0.733990 +vt 0.495630 0.775427 +vt 0.497667 0.775427 +vt 0.497667 0.774432 +vt 0.495630 0.774432 +vt 0.495630 0.774432 +vt 0.497667 0.774432 +vt 0.497667 0.773025 +vt 0.495630 0.773025 +vt 0.940986 0.896937 +vt 0.938948 0.896937 +vt 0.938948 0.897932 +vt 0.940986 0.897932 +vt 0.940986 0.897932 +vt 0.938948 0.897932 +vt 0.938948 0.899338 +vt 0.940986 0.899338 +vt 0.940986 0.899338 +vt 0.938948 0.899338 +vt 0.938948 0.900333 +vt 0.940986 0.900333 +vt 0.918979 0.730594 +vt 0.916941 0.730594 +vt 0.916941 0.731589 +vt 0.918979 0.731589 +vt 0.915892 0.733990 +vt 0.913490 0.732996 +vt 0.914485 0.733990 +vt 0.916887 0.732996 +vt 0.913490 0.731589 +vt 0.916887 0.731589 +vt 0.914485 0.730594 +vt 0.915892 0.730594 +vt 0.917446 0.409665 +vt 0.915044 0.410660 +vt 0.916451 0.410660 +vt 0.917446 0.408259 +vt 0.914049 0.409665 +vt 0.914049 0.408259 +vt 0.916451 0.407264 +vt 0.915044 0.407264 +vn -0.5493 0.8345 -0.0441 +vn 0.2021 0.9766 -0.0739 +vn 0.8352 0.5466 -0.0605 +vn 0.9790 -0.2035 -0.0116 +vn 0.5493 -0.8344 0.0441 +vn -0.2021 -0.9766 0.0739 +vn -0.8352 -0.5466 0.0605 +vn -0.9790 0.2035 0.0116 +vn 0.0263 0.0700 0.9972 +vn -0.0263 -0.0700 -0.9972 +usemtl Scene_-_Root +s off +f 23721/23721/16793 23722/23722/16793 23723/23723/16793 +f 23721/23721/16793 23723/23723/16793 23724/23724/16793 +f 23725/23725/16794 23726/23726/16794 23727/23727/16794 +f 23725/23725/16794 23727/23727/16794 23728/23728/16794 +f 23729/23729/16795 23730/23730/16795 23731/23731/16795 +f 23729/23729/16795 23731/23731/16795 23732/23732/16795 +f 23733/23733/16796 23734/23734/16796 23735/23735/16796 +f 23733/23733/16796 23735/23735/16796 23736/23736/16796 +f 23737/23737/16797 23738/23738/16797 23739/23739/16797 +f 23737/23737/16797 23739/23739/16797 23740/23740/16797 +f 23741/23741/16798 23742/23742/16798 23743/23743/16798 +f 23741/23741/16798 23743/23743/16798 23744/23744/16798 +f 23745/23745/16799 23746/23746/16799 23747/23747/16799 +f 23745/23745/16799 23747/23747/16799 23748/23748/16799 +f 23749/23749/16800 23750/23750/16800 23751/23751/16800 +f 23749/23749/16800 23751/23751/16800 23752/23752/16800 +f 23757/23753/16801 23755/23754/16801 23756/23755/16801 +f 23755/23754/16801 23757/23753/16801 23758/23756/16801 +f 23755/23754/16801 23758/23756/16801 23754/23757/16801 +f 23754/23757/16801 23758/23756/16801 23759/23758/16801 +f 23754/23757/16801 23759/23758/16801 23753/23759/16801 +f 23753/23759/16801 23759/23758/16801 23760/23760/16801 +f 23768/23761/16802 23766/23762/16802 23767/23763/16802 +f 23766/23762/16802 23768/23761/16802 23761/23764/16802 +f 23766/23762/16802 23761/23764/16802 23765/23765/16802 +f 23765/23765/16802 23761/23764/16802 23764/23766/16802 +f 23764/23766/16802 23761/23764/16802 23762/23767/16802 +f 23764/23766/16802 23762/23767/16802 23763/23768/16802 +o Cylinder.047__0 +v -0.043056 -1.054489 -0.979021 +v -0.042331 -1.052560 -0.951553 +v -0.026442 -1.042162 -0.952703 +v -0.027168 -1.044091 -0.980171 +v -0.027168 -1.044091 -0.980171 +v -0.026442 -1.042162 -0.952703 +v -0.007818 -1.046033 -0.952923 +v -0.008544 -1.047962 -0.980391 +v -0.008544 -1.047962 -0.980391 +v -0.007818 -1.046033 -0.952923 +v 0.002632 -1.061908 -0.952084 +v 0.001906 -1.063837 -0.979552 +v 0.001906 -1.063837 -0.979552 +v 0.002632 -1.061908 -0.952084 +v -0.001214 -1.080485 -0.950678 +v -0.001940 -1.082414 -0.978145 +v -0.001940 -1.082414 -0.978145 +v -0.001214 -1.080485 -0.950678 +v -0.017102 -1.090883 -0.949528 +v -0.017828 -1.092813 -0.976995 +v -0.017828 -1.092813 -0.976995 +v -0.017102 -1.090883 -0.949528 +v -0.035726 -1.087012 -0.949308 +v -0.036452 -1.088941 -0.976775 +v -0.036452 -1.088941 -0.976775 +v -0.035726 -1.087012 -0.949308 +v -0.046176 -1.071138 -0.950147 +v -0.046901 -1.073067 -0.977614 +v -0.046901 -1.073067 -0.977614 +v -0.046176 -1.071138 -0.950147 +v -0.042331 -1.052560 -0.951553 +v -0.043056 -1.054489 -0.979021 +v -0.026442 -1.042162 -0.952703 +v -0.042331 -1.052560 -0.951553 +v -0.046176 -1.071138 -0.950147 +v -0.035726 -1.087012 -0.949308 +v -0.017102 -1.090883 -0.949528 +v -0.001214 -1.080485 -0.950678 +v 0.002632 -1.061908 -0.952084 +v -0.007818 -1.046033 -0.952923 +v -0.043056 -1.054489 -0.979021 +v -0.027168 -1.044091 -0.980171 +v -0.008544 -1.047962 -0.980391 +v 0.001906 -1.063837 -0.979552 +v -0.001940 -1.082414 -0.978145 +v -0.017828 -1.092813 -0.976995 +v -0.036452 -1.088941 -0.976775 +v -0.046901 -1.073067 -0.977614 +vt 0.921057 0.731589 +vt 0.919019 0.731589 +vt 0.919019 0.732996 +vt 0.921057 0.732996 +vt 0.921057 0.732996 +vt 0.919019 0.732996 +vt 0.919019 0.733990 +vt 0.921057 0.733990 +vt 0.521948 0.775896 +vt 0.523986 0.775896 +vt 0.523986 0.774901 +vt 0.521948 0.774901 +vt 0.521948 0.774901 +vt 0.523986 0.774901 +vt 0.523986 0.773494 +vt 0.521948 0.773494 +vt 0.942051 0.426589 +vt 0.940013 0.426589 +vt 0.940013 0.427584 +vt 0.942051 0.427584 +vt 0.942051 0.427584 +vt 0.940013 0.427584 +vt 0.940013 0.428991 +vt 0.942051 0.428991 +vt 0.942051 0.428991 +vt 0.940013 0.428991 +vt 0.940013 0.429985 +vt 0.942051 0.429985 +vt 0.921057 0.730594 +vt 0.919019 0.730594 +vt 0.919019 0.731589 +vt 0.921057 0.731589 +vt 0.908962 0.733990 +vt 0.906560 0.732996 +vt 0.907555 0.733990 +vt 0.909957 0.732996 +vt 0.906560 0.731589 +vt 0.909957 0.731589 +vt 0.907555 0.730594 +vt 0.908962 0.730594 +vt 0.894898 0.409110 +vt 0.892496 0.410104 +vt 0.893903 0.410104 +vt 0.894898 0.407703 +vt 0.891501 0.409110 +vt 0.891501 0.407703 +vt 0.893903 0.406708 +vt 0.892496 0.406708 +vn -0.5493 0.8345 -0.0441 +vn 0.2021 0.9766 -0.0739 +vn 0.8352 0.5466 -0.0605 +vn 0.9790 -0.2035 -0.0116 +vn 0.5493 -0.8344 0.0441 +vn -0.2021 -0.9766 0.0739 +vn -0.8352 -0.5466 0.0605 +vn -0.9790 0.2035 0.0116 +vn 0.0263 0.0700 0.9972 +vn -0.0263 -0.0700 -0.9972 +usemtl Scene_-_Root +s off +f 23769/23769/16803 23770/23770/16803 23771/23771/16803 +f 23769/23769/16803 23771/23771/16803 23772/23772/16803 +f 23773/23773/16804 23774/23774/16804 23775/23775/16804 +f 23773/23773/16804 23775/23775/16804 23776/23776/16804 +f 23777/23777/16805 23778/23778/16805 23779/23779/16805 +f 23777/23777/16805 23779/23779/16805 23780/23780/16805 +f 23781/23781/16806 23782/23782/16806 23783/23783/16806 +f 23781/23781/16806 23783/23783/16806 23784/23784/16806 +f 23785/23785/16807 23786/23786/16807 23787/23787/16807 +f 23785/23785/16807 23787/23787/16807 23788/23788/16807 +f 23789/23789/16808 23790/23790/16808 23791/23791/16808 +f 23789/23789/16808 23791/23791/16808 23792/23792/16808 +f 23793/23793/16809 23794/23794/16809 23795/23795/16809 +f 23793/23793/16809 23795/23795/16809 23796/23796/16809 +f 23797/23797/16810 23798/23798/16810 23799/23799/16810 +f 23797/23797/16810 23799/23799/16810 23800/23800/16810 +f 23805/23801/16811 23803/23802/16811 23804/23803/16811 +f 23803/23802/16811 23805/23801/16811 23806/23804/16811 +f 23803/23802/16811 23806/23804/16811 23802/23805/16811 +f 23802/23805/16811 23806/23804/16811 23807/23806/16811 +f 23802/23805/16811 23807/23806/16811 23801/23807/16811 +f 23801/23807/16811 23807/23806/16811 23808/23808/16811 +f 23816/23809/16812 23814/23810/16812 23815/23811/16812 +f 23814/23810/16812 23816/23809/16812 23809/23812/16812 +f 23814/23810/16812 23809/23812/16812 23813/23813/16812 +f 23813/23813/16812 23809/23812/16812 23812/23814/16812 +f 23812/23814/16812 23809/23812/16812 23810/23815/16812 +f 23812/23814/16812 23810/23815/16812 23811/23816/16812 +o Cylinder.048__0 +v -0.700979 -1.054489 -0.979021 +v -0.700254 -1.052560 -0.951553 +v -0.684365 -1.042162 -0.952703 +v -0.685091 -1.044091 -0.980171 +v -0.685091 -1.044091 -0.980171 +v -0.684365 -1.042162 -0.952703 +v -0.665741 -1.046033 -0.952923 +v -0.666467 -1.047962 -0.980391 +v -0.666467 -1.047962 -0.980391 +v -0.665741 -1.046033 -0.952923 +v -0.655291 -1.061908 -0.952084 +v -0.656017 -1.063837 -0.979552 +v -0.656017 -1.063837 -0.979552 +v -0.655291 -1.061908 -0.952084 +v -0.659137 -1.080485 -0.950678 +v -0.659863 -1.082414 -0.978145 +v -0.659863 -1.082414 -0.978145 +v -0.659137 -1.080485 -0.950678 +v -0.675025 -1.090883 -0.949528 +v -0.675751 -1.092813 -0.976995 +v -0.675751 -1.092813 -0.976995 +v -0.675025 -1.090883 -0.949528 +v -0.693649 -1.087012 -0.949308 +v -0.694375 -1.088941 -0.976775 +v -0.694375 -1.088941 -0.976775 +v -0.693649 -1.087012 -0.949308 +v -0.704099 -1.071138 -0.950147 +v -0.704824 -1.073067 -0.977614 +v -0.704824 -1.073067 -0.977614 +v -0.704099 -1.071138 -0.950147 +v -0.700254 -1.052560 -0.951553 +v -0.700979 -1.054489 -0.979021 +v -0.684365 -1.042162 -0.952703 +v -0.700254 -1.052560 -0.951553 +v -0.704099 -1.071138 -0.950147 +v -0.693649 -1.087012 -0.949308 +v -0.675025 -1.090883 -0.949528 +v -0.659137 -1.080485 -0.950678 +v -0.655291 -1.061908 -0.952084 +v -0.665741 -1.046033 -0.952923 +v -0.700979 -1.054489 -0.979021 +v -0.685091 -1.044091 -0.980171 +v -0.666467 -1.047962 -0.980391 +v -0.656017 -1.063837 -0.979552 +v -0.659863 -1.082414 -0.978145 +v -0.675751 -1.092813 -0.976995 +v -0.694375 -1.088941 -0.976775 +v -0.704824 -1.073067 -0.977614 +vt 0.927291 0.731589 +vt 0.925254 0.731589 +vt 0.925254 0.732996 +vt 0.927291 0.732996 +vt 0.927291 0.732996 +vt 0.925254 0.732996 +vt 0.925254 0.733990 +vt 0.927291 0.733990 +vt 0.562343 0.775245 +vt 0.564381 0.775245 +vt 0.564381 0.774251 +vt 0.562343 0.774251 +vt 0.562343 0.774251 +vt 0.564381 0.774251 +vt 0.564381 0.772844 +vt 0.562343 0.772844 +vt 0.935755 0.531545 +vt 0.933717 0.531545 +vt 0.933717 0.532539 +vt 0.935755 0.532539 +vt 0.935755 0.532539 +vt 0.933717 0.532539 +vt 0.933717 0.533946 +vt 0.935755 0.533946 +vt 0.935755 0.533946 +vt 0.933717 0.533946 +vt 0.933717 0.534941 +vt 0.935755 0.534941 +vt 0.927291 0.730594 +vt 0.925254 0.730594 +vt 0.925254 0.731589 +vt 0.927291 0.731589 +vt 0.848121 0.879388 +vt 0.845719 0.878393 +vt 0.846714 0.879388 +vt 0.849116 0.878393 +vt 0.845719 0.876987 +vt 0.849116 0.876987 +vt 0.846714 0.875992 +vt 0.848121 0.875992 +vt 0.407914 0.411877 +vt 0.405512 0.412872 +vt 0.406919 0.412872 +vt 0.407914 0.410470 +vt 0.404517 0.411877 +vt 0.404517 0.410470 +vt 0.406919 0.409476 +vt 0.405512 0.409476 +vn -0.5493 0.8345 -0.0441 +vn 0.2021 0.9766 -0.0739 +vn 0.8352 0.5466 -0.0605 +vn 0.9790 -0.2035 -0.0116 +vn 0.5493 -0.8344 0.0441 +vn -0.2021 -0.9766 0.0739 +vn -0.8352 -0.5466 0.0605 +vn -0.9790 0.2035 0.0116 +vn 0.0263 0.0700 0.9972 +vn -0.0263 -0.0700 -0.9972 +usemtl Scene_-_Root +s off +f 23817/23817/16813 23818/23818/16813 23819/23819/16813 +f 23817/23817/16813 23819/23819/16813 23820/23820/16813 +f 23821/23821/16814 23822/23822/16814 23823/23823/16814 +f 23821/23821/16814 23823/23823/16814 23824/23824/16814 +f 23825/23825/16815 23826/23826/16815 23827/23827/16815 +f 23825/23825/16815 23827/23827/16815 23828/23828/16815 +f 23829/23829/16816 23830/23830/16816 23831/23831/16816 +f 23829/23829/16816 23831/23831/16816 23832/23832/16816 +f 23833/23833/16817 23834/23834/16817 23835/23835/16817 +f 23833/23833/16817 23835/23835/16817 23836/23836/16817 +f 23837/23837/16818 23838/23838/16818 23839/23839/16818 +f 23837/23837/16818 23839/23839/16818 23840/23840/16818 +f 23841/23841/16819 23842/23842/16819 23843/23843/16819 +f 23841/23841/16819 23843/23843/16819 23844/23844/16819 +f 23845/23845/16820 23846/23846/16820 23847/23847/16820 +f 23845/23845/16820 23847/23847/16820 23848/23848/16820 +f 23853/23849/16821 23851/23850/16821 23852/23851/16821 +f 23851/23850/16821 23853/23849/16821 23854/23852/16821 +f 23851/23850/16821 23854/23852/16821 23850/23853/16821 +f 23850/23853/16821 23854/23852/16821 23855/23854/16821 +f 23850/23853/16821 23855/23854/16821 23849/23855/16821 +f 23849/23855/16821 23855/23854/16821 23856/23856/16821 +f 23864/23857/16822 23862/23858/16822 23863/23859/16822 +f 23862/23858/16822 23864/23857/16822 23857/23860/16822 +f 23862/23858/16822 23857/23860/16822 23861/23861/16822 +f 23861/23861/16822 23857/23860/16822 23860/23862/16822 +f 23860/23862/16822 23857/23860/16822 23858/23863/16822 +f 23860/23862/16822 23858/23863/16822 23859/23864/16822 +o Cylinder.049__0 +v 1.213177 0.197668 -0.293499 +v 1.211772 0.203028 -0.285571 +v 1.219217 0.288361 -0.341947 +v 1.220623 0.283000 -0.349874 +v 1.264818 0.367996 -0.387708 +v 1.266223 0.362636 -0.395636 +v 1.341630 0.429811 -0.415889 +v 1.343035 0.424451 -0.423816 +v 1.437960 0.464394 -0.422199 +v 1.439365 0.459033 -0.430127 +v 1.439365 0.459033 -0.430127 +v 1.437960 0.464394 -0.422199 +v 1.539143 0.466480 -0.405678 +v 1.540548 0.461120 -0.413605 +v 1.629775 0.435752 -0.368840 +v 1.631180 0.430392 -0.376767 +v 1.696057 0.376888 -0.317293 +v 1.697462 0.371528 -0.325221 +v 1.727899 0.298849 -0.258887 +v 1.729304 0.293489 -0.266814 +v 1.729304 0.293489 -0.266814 +v 1.727899 0.298849 -0.258887 +v 1.720453 0.213516 -0.202511 +v 1.721858 0.208156 -0.210438 +v 1.674853 0.133880 -0.156749 +v 1.676258 0.128520 -0.164677 +v 1.598041 0.072065 -0.128568 +v 1.599446 0.066705 -0.136496 +v 1.501711 0.037483 -0.122258 +v 1.503116 0.032123 -0.130186 +v 1.503116 0.032123 -0.130186 +v 1.501711 0.037483 -0.122258 +v 1.400527 0.035396 -0.138780 +v 1.401932 0.030036 -0.146708 +v 1.250056 0.283755 -0.333368 +v 1.243526 0.208923 -0.283929 +v 1.332551 -0.130709 -0.786254 +v 1.339081 -0.055876 -0.835693 +v 1.309896 0.066124 -0.175618 +v 1.311301 0.060764 -0.183546 +v 1.245019 0.119628 -0.235092 +v 1.243614 0.124989 -0.227164 +v 1.211772 0.203028 -0.285571 +v 1.213177 0.197668 -0.293499 +v 1.329576 0.088866 -0.187506 +v 1.409056 0.061919 -0.155201 +v 1.498081 -0.277712 -0.657526 +v 1.418602 -0.250766 -0.689831 +v 1.243526 0.208923 -0.283929 +v 1.271451 0.140487 -0.232710 +v 1.360476 -0.199145 -0.735035 +v 1.332551 -0.130709 -0.786254 +v 1.290045 0.353592 -0.373498 +v 1.379070 0.013960 -0.875823 +v 1.357406 0.407800 -0.398212 +v 1.446431 0.068169 -0.900537 +v 1.441882 0.438128 -0.403745 +v 1.530907 0.098496 -0.906070 +v 1.530615 0.439957 -0.389257 +v 1.441882 0.438128 -0.403745 +v 1.530907 0.098496 -0.906070 +v 1.619640 0.100326 -0.891582 +v 1.610094 0.413011 -0.356951 +v 1.699119 0.073379 -0.859277 +v 1.668221 0.361390 -0.311748 +v 1.757246 0.021758 -0.814073 +v 1.696144 0.292953 -0.260528 +v 1.785169 -0.046678 -0.762853 +v 1.689615 0.218121 -0.211090 +v 1.696144 0.292953 -0.260528 +v 1.785169 -0.046678 -0.762853 +v 1.778640 -0.121511 -0.713415 +v 1.649626 0.148284 -0.170959 +v 1.738651 -0.191347 -0.673284 +v 1.582265 0.094076 -0.146246 +v 1.671290 -0.245555 -0.648571 +v 1.497788 0.063748 -0.140712 +v 1.586813 -0.275883 -0.643038 +v 1.497788 0.063748 -0.140712 +v 1.586813 -0.275883 -0.643038 +v 1.266626 0.140796 -0.228019 +v 1.238119 0.210660 -0.280307 +v 1.215809 0.206518 -0.281461 +v 1.247069 0.129908 -0.224123 +v 1.671675 0.366309 -0.308707 +v 1.700182 0.296444 -0.256418 +v 1.722492 0.300586 -0.255265 +v 1.691232 0.377197 -0.312603 +v 1.244785 0.287054 -0.330777 +v 1.223118 0.290289 -0.336805 +v 1.693516 0.220050 -0.205948 +v 1.715182 0.216815 -0.199921 +v 1.285608 0.358348 -0.371746 +v 1.267884 0.368468 -0.381729 +v 1.652693 0.148757 -0.164980 +v 1.670417 0.138637 -0.154997 +v 1.354375 0.413687 -0.396974 +v 1.343291 0.429151 -0.409394 +v 1.583926 0.093417 -0.139751 +v 1.595010 0.077953 -0.127331 +v 1.440614 0.444648 -0.402623 +v 1.437858 0.463101 -0.415589 +v 1.497687 0.062456 -0.134102 +v 1.500442 0.044003 -0.121137 +v 1.531198 0.446516 -0.387832 +v 1.537190 0.465149 -0.399369 +v 1.407103 0.060589 -0.148893 +v 1.401110 0.041955 -0.137356 +v 1.612336 0.419007 -0.354853 +v 1.626163 0.434984 -0.363205 +v 1.325965 0.088098 -0.181872 +v 1.312138 0.072120 -0.173520 +v 1.400678 -0.280211 -0.687859 +v 1.334397 -0.221347 -0.739405 +v 1.338506 -0.224189 -0.746610 +v 1.403927 -0.282289 -0.695733 +v 1.403927 -0.282289 -0.695733 +v 1.338506 -0.224189 -0.746610 +v 1.346081 -0.222095 -0.750765 +v 1.409426 -0.278351 -0.701503 +v 1.302554 -0.143308 -0.797812 +v 1.307077 -0.147163 -0.804259 +v 1.307077 -0.147163 -0.804259 +v 1.315650 -0.147515 -0.806583 +v 1.302554 -0.143308 -0.797812 +v 1.310000 -0.057975 -0.854187 +v 1.314426 -0.062938 -0.859903 +v 1.307077 -0.147163 -0.804259 +v 1.314426 -0.062938 -0.859903 +v 1.322766 -0.065964 -0.860460 +v 1.355600 0.021660 -0.899949 +v 1.359435 0.015665 -0.905070 +v 1.359435 0.015665 -0.905070 +v 1.366345 0.010142 -0.904194 +v 1.432412 0.083475 -0.928129 +v 1.435250 0.076677 -0.932885 +v 1.435250 0.076677 -0.932885 +v 1.439753 0.069217 -0.931126 +v 1.528742 0.118058 -0.934440 +v 1.530330 0.110811 -0.939113 +v 1.530330 0.110811 -0.939113 +v 1.531814 0.102268 -0.937156 +v 1.528742 0.118058 -0.934440 +v 1.629925 0.120144 -0.917918 +v 1.630199 0.112870 -0.922807 +v 1.530330 0.110811 -0.939113 +v 1.630199 0.112870 -0.922807 +v 1.628513 0.104261 -0.921367 +v 1.720557 0.089417 -0.881080 +v 1.719654 0.082541 -0.886447 +v 1.719654 0.082541 -0.886447 +v 1.715128 0.074895 -0.886162 +v 1.786839 0.030552 -0.829534 +v 1.785077 0.024441 -0.835570 +v 1.785077 0.024441 -0.835570 +v 1.778473 0.018640 -0.836900 +v 1.818681 -0.047487 -0.771127 +v 1.816505 -0.052585 -0.777921 +v 1.816505 -0.052585 -0.777921 +v 1.808904 -0.055940 -0.781081 +v 1.818681 -0.047487 -0.771127 +v 1.811236 -0.132819 -0.714751 +v 1.809156 -0.136810 -0.722277 +v 1.816505 -0.052585 -0.777921 +v 1.809156 -0.136810 -0.722277 +v 1.801788 -0.137492 -0.727204 +v 1.765636 -0.212455 -0.668990 +v 1.764148 -0.215412 -0.677109 +v 1.764148 -0.215412 -0.677109 +v 1.758209 -0.213598 -0.683470 +v 1.688823 -0.274270 -0.640809 +v 1.688333 -0.276424 -0.649294 +v 1.688333 -0.276424 -0.649294 +v 1.684801 -0.272673 -0.656538 +v 1.592493 -0.308853 -0.634499 +v 1.593253 -0.310559 -0.643066 +v 1.593253 -0.310559 -0.643066 +v 1.592740 -0.305724 -0.650508 +v 1.592493 -0.308853 -0.634499 +v 1.491310 -0.310939 -0.651021 +v 1.493383 -0.312618 -0.659374 +v 1.593253 -0.310559 -0.643066 +v 1.493383 -0.312618 -0.659374 +v 1.496041 -0.307718 -0.666297 +v 1.668685 -0.157809 -0.724955 +v 1.628278 -0.190325 -0.710130 +v 1.627072 -0.185725 -0.703327 +v 1.667479 -0.153208 -0.718151 +v 1.243614 0.124989 -0.227164 +v 1.309896 0.066124 -0.175618 +v 1.211772 0.203028 -0.285571 +v 1.219217 0.288361 -0.341947 +v 1.264818 0.367996 -0.387708 +v 1.341630 0.429811 -0.415889 +v 1.437960 0.464394 -0.422199 +v 1.539143 0.466480 -0.405678 +v 1.629775 0.435752 -0.368840 +v 1.696057 0.376888 -0.317293 +v 1.727899 0.298849 -0.258887 +v 1.720453 0.213516 -0.202511 +v 1.674853 0.133880 -0.156749 +v 1.598041 0.072065 -0.128568 +v 1.501711 0.037483 -0.122258 +v 1.400527 0.035396 -0.138780 +v 1.329576 0.088866 -0.187506 +v 1.271451 0.140487 -0.232710 +v 1.243526 0.208923 -0.283929 +v 1.250056 0.283755 -0.333368 +v 1.290045 0.353592 -0.373498 +v 1.357406 0.407800 -0.398212 +v 1.441882 0.438128 -0.403745 +v 1.530615 0.439957 -0.389257 +v 1.610094 0.413011 -0.356951 +v 1.668221 0.361390 -0.311748 +v 1.696144 0.292953 -0.260528 +v 1.689615 0.218121 -0.211090 +v 1.649626 0.148284 -0.170959 +v 1.582265 0.094076 -0.146246 +v 1.497788 0.063748 -0.140712 +v 1.409056 0.061919 -0.155201 +v 1.399873 -0.277141 -0.683318 +v 1.333592 -0.218277 -0.734864 +v 1.320920 -0.169933 -0.663363 +v 1.289078 -0.091894 -0.721769 +v 1.301749 -0.140238 -0.793271 +v 1.309195 -0.054905 -0.849646 +v 1.296523 -0.006561 -0.778145 +v 1.342124 0.073074 -0.823906 +v 1.354795 0.024730 -0.895408 +v 1.490505 -0.307869 -0.646480 +v 1.477833 -0.259526 -0.574978 +v 1.387202 -0.228797 -0.611816 +v 1.591688 -0.305783 -0.629958 +v 1.579017 -0.257439 -0.558457 +v 1.688018 -0.271200 -0.636268 +v 1.591688 -0.305783 -0.629958 +v 1.326962 -0.011076 -0.284172 +v 1.418972 -0.042271 -0.246774 +v 1.417918 -0.045550 -0.244744 +v 1.324530 -0.013887 -0.282703 +v 1.764831 -0.209385 -0.664449 +v 1.675346 -0.222857 -0.564767 +v 1.579017 -0.257439 -0.558457 +v 1.810431 -0.129749 -0.710211 +v 1.405756 0.181115 -0.789052 +v 1.503345 0.216150 -0.795444 +v 1.502095 0.224519 -0.801324 +v 1.400729 0.188128 -0.794684 +v 1.817877 -0.044417 -0.766586 +v 1.752159 -0.161041 -0.592948 +v 1.786034 0.033623 -0.824993 +v 1.817877 -0.044417 -0.766586 +v 1.797759 -0.081406 -0.638709 +v 1.719752 0.092486 -0.876539 +v 1.805205 0.003927 -0.695085 +v 1.629121 0.123214 -0.913377 +v 1.773363 0.081966 -0.753492 +v 1.805205 0.003927 -0.695085 +v 1.527937 0.121128 -0.929899 +v 1.707080 0.140830 -0.805038 +v 1.431607 0.086545 -0.923589 +v 1.527937 0.121128 -0.929899 +v 1.616449 0.171558 -0.841876 +v 1.515265 0.169472 -0.858397 +v 1.418936 0.134889 -0.852087 +v 1.515265 0.169472 -0.858397 +v 1.301749 -0.140238 -0.793271 +v 1.509652 0.007187 -0.167067 +v 1.408469 0.005100 -0.183589 +v 1.219713 0.172731 -0.330380 +v 1.227159 0.258064 -0.386755 +v 1.272759 0.337700 -0.432517 +v 1.349571 0.399515 -0.460698 +v 1.445901 0.434097 -0.467008 +v 1.445901 0.434097 -0.467008 +v 1.547085 0.436184 -0.450486 +v 1.637716 0.405456 -0.413648 +v 1.703998 0.346592 -0.362102 +v 1.735841 0.268553 -0.303695 +v 1.735841 0.268553 -0.303695 +v 1.728395 0.183220 -0.247320 +v 1.682795 0.103584 -0.201558 +v 1.605982 0.041770 -0.173377 +v 1.509652 0.007187 -0.167067 +v 1.663842 -0.178967 -0.499853 +v 1.617540 -0.002324 -0.238592 +v 1.521210 -0.036906 -0.232282 +v 1.567512 -0.213550 -0.493543 +v 1.567512 -0.213550 -0.493543 +v 1.521210 -0.036906 -0.232282 +v 1.420027 -0.038993 -0.248804 +v 1.466329 -0.215637 -0.510065 +v 1.251555 0.094692 -0.271973 +v 1.219713 0.172731 -0.330380 +v 1.317837 0.035828 -0.220427 +v 1.715556 0.302499 -0.427317 +v 1.649274 0.361363 -0.478863 +v 1.651706 0.364174 -0.480333 +v 1.718997 0.304414 -0.428003 +v 1.605982 0.041770 -0.173377 +v 1.509652 0.007187 -0.167067 +v 1.510137 0.003940 -0.164786 +v 1.607932 0.039049 -0.171192 +v 1.272759 0.337700 -0.432517 +v 1.349571 0.399515 -0.460698 +v 1.347621 0.402235 -0.462883 +v 1.269640 0.339480 -0.434273 +v 1.263113 0.050600 -0.337188 +v 1.329395 -0.008265 -0.285642 +v 1.259673 0.048684 -0.336502 +v 1.617540 -0.002324 -0.238592 +v 1.694352 0.059491 -0.266773 +v 1.697471 0.057711 -0.265016 +v 1.619490 -0.005044 -0.236407 +v 1.284317 0.293607 -0.497732 +v 1.238717 0.213971 -0.451970 +v 1.234905 0.214540 -0.453030 +v 1.281198 0.295387 -0.499488 +v 1.317837 0.035828 -0.220427 +v 1.251555 0.094692 -0.271973 +v 1.248115 0.092777 -0.271287 +v 1.315405 0.033017 -0.218957 +v 1.637716 0.405456 -0.413648 +v 1.703998 0.346592 -0.362102 +v 1.707439 0.348507 -0.362787 +v 1.640149 0.408267 -0.415118 +v 1.231271 0.128639 -0.395595 +v 1.227346 0.127910 -0.395797 +v 1.558642 0.392091 -0.515701 +v 1.559696 0.395369 -0.517731 +v 1.682795 0.103584 -0.201558 +v 1.685913 0.101804 -0.199802 +v 1.227159 0.258064 -0.386755 +v 1.223347 0.258633 -0.387816 +v 1.219713 0.172731 -0.330380 +v 1.215788 0.172003 -0.330583 +v 1.739952 0.139127 -0.312535 +v 1.743764 0.138558 -0.311474 +v 1.547085 0.436184 -0.450486 +v 1.548139 0.439462 -0.452516 +v 1.609883 0.036328 -0.169007 +v 1.689031 0.100023 -0.198045 +v 1.223421 0.127181 -0.396000 +v 1.231093 0.215109 -0.454091 +v 1.244674 0.090861 -0.270602 +v 1.312972 0.030206 -0.217488 +v 1.278080 0.297168 -0.501245 +v 1.445417 0.437344 -0.469289 +v 1.549193 0.442740 -0.454546 +v 1.444932 0.440591 -0.471570 +v 1.510622 0.000693 -0.162505 +v 1.359179 0.358142 -0.528098 +v 1.357229 0.360862 -0.530283 +v 1.456974 0.393251 -0.534504 +v 1.456490 0.396498 -0.536785 +v 1.642581 0.411078 -0.416587 +v 1.407415 0.001822 -0.181559 +v 1.406361 -0.001457 -0.179529 +v 1.560751 0.398648 -0.519760 +v 1.654139 0.366985 -0.481802 +v 1.710881 0.350423 -0.363473 +v 1.722438 0.306330 -0.428688 +v 1.735841 0.268553 -0.303695 +v 1.739766 0.269282 -0.303492 +v 1.361129 0.355422 -0.525913 +v 1.521210 -0.036906 -0.232282 +v 1.521695 -0.040153 -0.230001 +v 1.445901 0.434097 -0.467008 +v 1.408469 0.005100 -0.183589 +v 1.747398 0.224460 -0.368910 +v 1.751323 0.225189 -0.368707 +v 1.728395 0.183220 -0.247320 +v 1.732207 0.182651 -0.246259 +v 1.457459 0.390004 -0.532223 +v 1.420027 -0.038993 -0.248804 +v 1.211863 0.171274 -0.330786 +v 1.219535 0.259202 -0.388876 +v 1.231093 0.215109 -0.454091 +v 1.223421 0.127181 -0.396000 +v 1.266522 0.341261 -0.436030 +v 1.278080 0.297168 -0.501245 +v 1.345671 0.404955 -0.465068 +v 1.357229 0.360862 -0.530283 +v 1.444932 0.440591 -0.471570 +v 1.456490 0.396498 -0.536785 +v 1.444932 0.440591 -0.471570 +v 1.549193 0.442740 -0.454546 +v 1.560751 0.398648 -0.519760 +v 1.456490 0.396498 -0.536785 +v 1.642581 0.411078 -0.416587 +v 1.654139 0.366985 -0.481802 +v 1.710881 0.350423 -0.363473 +v 1.722438 0.306330 -0.428688 +v 1.743691 0.270010 -0.303289 +v 1.755249 0.225917 -0.368504 +v 1.743691 0.270010 -0.303289 +v 1.736018 0.182081 -0.245199 +v 1.747576 0.137988 -0.310414 +v 1.755249 0.225917 -0.368504 +v 1.689031 0.100023 -0.198045 +v 1.700589 0.055930 -0.263260 +v 1.609883 0.036328 -0.169007 +v 1.621440 -0.007765 -0.234222 +v 1.510622 0.000693 -0.162505 +v 1.522180 -0.043400 -0.227720 +v 1.510622 0.000693 -0.162505 +v 1.406361 -0.001457 -0.179529 +v 1.417918 -0.045550 -0.244744 +v 1.522180 -0.043400 -0.227720 +v 1.312972 0.030206 -0.217488 +v 1.324530 -0.013887 -0.282703 +v 1.244674 0.090861 -0.270602 +v 1.211863 0.171274 -0.330786 +v 1.223421 0.127181 -0.396000 +v 1.256232 0.046768 -0.335817 +v 1.345671 0.404955 -0.465068 +v 1.522180 -0.043400 -0.227720 +v 1.256232 0.046768 -0.335817 +v 1.736018 0.182081 -0.245199 +v 1.621440 -0.007765 -0.234222 +v 1.266522 0.341261 -0.436030 +v 1.700589 0.055930 -0.263260 +v 1.211863 0.171274 -0.330786 +v 1.743691 0.270010 -0.303289 +v 1.747576 0.137988 -0.310414 +v 1.219535 0.259202 -0.388876 +v 1.755249 0.225917 -0.368504 +v 1.309416 -0.126044 -0.598449 +v 1.263113 0.050600 -0.337188 +v 1.231271 0.128639 -0.395595 +v 1.277574 -0.048005 -0.656856 +v 1.285019 0.037328 -0.713232 +v 1.238717 0.213971 -0.451970 +v 1.284317 0.293607 -0.497732 +v 1.330619 0.116963 -0.758993 +v 1.361129 0.355422 -0.525913 +v 1.407431 0.178778 -0.787174 +v 1.457459 0.390004 -0.532223 +v 1.503761 0.213361 -0.793484 +v 1.503761 0.213361 -0.793484 +v 1.457459 0.390004 -0.532223 +v 1.558642 0.392091 -0.515701 +v 1.604944 0.215447 -0.776963 +v 1.649274 0.361363 -0.478863 +v 1.695576 0.184719 -0.740124 +v 1.715556 0.302499 -0.427317 +v 1.761858 0.125855 -0.688578 +v 1.747398 0.224460 -0.368910 +v 1.793700 0.047816 -0.630172 +v 1.793700 0.047816 -0.630172 +v 1.747398 0.224460 -0.368910 +v 1.739952 0.139127 -0.312535 +v 1.786255 -0.037517 -0.573796 +v 1.694352 0.059491 -0.266773 +v 1.740655 -0.117152 -0.528034 +v 1.289078 -0.091894 -0.721769 +v 1.329395 -0.008265 -0.285642 +v 1.375697 -0.184908 -0.546903 +v 1.277574 -0.048005 -0.656856 +v 1.231271 0.128639 -0.395595 +v 1.296523 -0.006561 -0.778145 +v 1.289078 -0.091894 -0.721769 +v 1.285706 -0.092521 -0.721944 +v 1.293248 -0.006073 -0.779056 +v 1.752159 -0.161041 -0.592948 +v 1.797759 -0.081406 -0.638709 +v 1.801034 -0.081895 -0.637798 +v 1.754838 -0.162571 -0.591439 +v 1.277574 -0.048005 -0.656856 +v 1.285019 0.037328 -0.713232 +v 1.281744 0.037817 -0.714143 +v 1.274201 -0.048632 -0.657030 +v 1.604944 0.215447 -0.776963 +v 1.695576 0.184719 -0.740124 +v 1.697666 0.187135 -0.741387 +v 1.605850 0.218264 -0.778706 +v 1.320920 -0.169933 -0.663363 +v 1.317964 -0.171579 -0.662773 +v 1.387202 -0.228797 -0.611816 +v 1.385112 -0.231213 -0.610554 +v 1.616449 0.171558 -0.841876 +v 1.515265 0.169472 -0.858397 +v 1.514850 0.172261 -0.860357 +v 1.617354 0.174375 -0.843620 +v 1.786255 -0.037517 -0.573796 +v 1.740655 -0.117152 -0.528034 +v 1.743334 -0.118682 -0.526525 +v 1.789530 -0.038006 -0.572885 +v 1.375697 -0.184908 -0.546903 +v 1.309416 -0.126044 -0.598449 +v 1.306459 -0.127690 -0.597860 +v 1.373607 -0.187324 -0.545641 +v 1.805205 0.003927 -0.695085 +v 1.808578 0.004553 -0.694911 +v 1.503761 0.213361 -0.793484 +v 1.477833 -0.259526 -0.574978 +v 1.579017 -0.257439 -0.558457 +v 1.579433 -0.260229 -0.556497 +v 1.476928 -0.262342 -0.573234 +v 1.418936 0.134889 -0.852087 +v 1.417260 0.137226 -0.853965 +v 1.793700 0.047816 -0.630172 +v 1.797073 0.048442 -0.629997 +v 1.773363 0.081966 -0.753492 +v 1.776320 0.083612 -0.754081 +v 1.785188 0.088550 -0.755847 +v 1.818695 0.006431 -0.694387 +v 1.608567 0.226714 -0.783938 +v 1.339444 0.074604 -0.825416 +v 1.283422 -0.004606 -0.781789 +v 1.331407 0.079193 -0.829943 +v 1.703936 0.194380 -0.745175 +v 1.810860 -0.083362 -0.635065 +v 1.764815 0.127501 -0.689167 +v 1.773684 0.132439 -0.690934 +v 1.762876 -0.167161 -0.586911 +v 1.412234 0.144239 -0.859597 +v 1.807191 0.050320 -0.629474 +v 1.799356 -0.039473 -0.570152 +v 1.271918 0.039284 -0.716876 +v 1.264083 -0.050510 -0.657553 +v 1.513599 0.180630 -0.866237 +v 1.665518 -0.181305 -0.497976 +v 1.670544 -0.188318 -0.492344 +v 1.751372 -0.123271 -0.521998 +v 1.677022 -0.225194 -0.562889 +v 1.682049 -0.232207 -0.557257 +v 1.567929 -0.216340 -0.491584 +v 1.569178 -0.224708 -0.485704 +v 1.330619 0.116963 -0.758993 +v 1.327940 0.118493 -0.760503 +v 1.663842 -0.178967 -0.499853 +v 1.707080 0.140830 -0.805038 +v 1.709170 0.143245 -0.806300 +v 1.466329 -0.215637 -0.510065 +v 1.465423 -0.218453 -0.508321 +v 1.761858 0.125855 -0.688578 +v 1.342124 0.073074 -0.823906 +v 1.675346 -0.222857 -0.564767 +v 1.407431 0.178778 -0.787174 +v 1.567512 -0.213550 -0.493543 +v 1.297589 -0.132628 -0.596093 +v 1.264083 -0.050510 -0.657553 +v 1.275587 -0.094399 -0.722467 +v 1.309094 -0.176517 -0.661007 +v 1.271918 0.039284 -0.716876 +v 1.319902 0.123082 -0.765030 +v 1.331407 0.079193 -0.829943 +v 1.283422 -0.004606 -0.781789 +v 1.400729 0.188128 -0.794684 +v 1.412234 0.144239 -0.859597 +v 1.502095 0.224519 -0.801324 +v 1.513599 0.180630 -0.866237 +v 1.502095 0.224519 -0.801324 +v 1.608567 0.226714 -0.783938 +v 1.620072 0.182825 -0.848852 +v 1.513599 0.180630 -0.866237 +v 1.703936 0.194380 -0.745175 +v 1.715441 0.150491 -0.810088 +v 1.773684 0.132439 -0.690934 +v 1.785188 0.088550 -0.755847 +v 1.807191 0.050320 -0.629474 +v 1.818695 0.006431 -0.694387 +v 1.807191 0.050320 -0.629474 +v 1.799356 -0.039473 -0.570152 +v 1.810860 -0.083362 -0.635065 +v 1.818695 0.006431 -0.694387 +v 1.751372 -0.123271 -0.521998 +v 1.762876 -0.167161 -0.586911 +v 1.670544 -0.188318 -0.492344 +v 1.682049 -0.232207 -0.557257 +v 1.569178 -0.224708 -0.485704 +v 1.580683 -0.268597 -0.550617 +v 1.569178 -0.224708 -0.485704 +v 1.462706 -0.226904 -0.503089 +v 1.474211 -0.270793 -0.568002 +v 1.580683 -0.268597 -0.550617 +v 1.367337 -0.194569 -0.541853 +v 1.378841 -0.238458 -0.606766 +v 1.264083 -0.050510 -0.657553 +v 1.275587 -0.094399 -0.722467 +v 1.319902 0.123082 -0.765030 +v 1.474211 -0.270793 -0.568002 +v 1.378841 -0.238458 -0.606766 +v 1.715441 0.150491 -0.810088 +v 1.309094 -0.176517 -0.661007 +v 1.297589 -0.132628 -0.596093 +v 1.620072 0.182825 -0.848852 +v 1.367337 -0.194569 -0.541853 +v 1.462706 -0.226904 -0.503089 +v 1.580683 -0.268597 -0.550617 +v 1.275587 -0.094399 -0.722467 +v 1.176488 0.401041 -0.529584 +v 1.191954 0.392024 -0.543303 +v 1.164295 0.398651 -0.576415 +v 1.145116 0.408359 -0.567523 +v 1.197543 0.371595 -0.551056 +v 1.173598 0.377532 -0.579341 +v 1.159527 0.371671 -0.613848 +v 1.147608 0.392306 -0.616179 +v 1.125811 0.401530 -0.612544 +v 1.277926 0.283653 -0.468491 +v 1.269845 0.289937 -0.447773 +v 1.245166 0.304004 -0.461722 +v 1.253398 0.297656 -0.482311 +v 1.271640 0.307634 -0.433022 +v 1.246809 0.321765 -0.447098 +v 1.218676 0.337498 -0.463576 +v 1.218089 0.319293 -0.477301 +v 1.227378 0.312499 -0.496992 +v 1.245012 0.367929 -0.479484 +v 1.254301 0.361136 -0.499175 +v 1.223504 0.377837 -0.518210 +v 1.211631 0.385671 -0.500807 +v 1.253714 0.342931 -0.512900 +v 1.225502 0.358591 -0.529649 +v 1.281378 0.345848 -0.483596 +v 1.279734 0.328088 -0.498219 +v 1.273145 0.352197 -0.463006 +v 1.297976 0.338066 -0.448930 +v 1.306057 0.331781 -0.469647 +v 1.304263 0.314085 -0.484399 +v 1.277926 0.283653 -0.468491 +v 1.253398 0.297656 -0.482311 +v 1.267801 0.308352 -0.496867 +v 1.292273 0.294372 -0.483096 +v 1.227378 0.312499 -0.496992 +v 1.242178 0.323028 -0.511211 +v 1.253714 0.342931 -0.512900 +v 1.279734 0.328088 -0.498219 +v 1.304263 0.314085 -0.484399 +v 1.218676 0.337498 -0.463576 +v 1.246809 0.321765 -0.447098 +v 1.258743 0.341501 -0.448450 +v 1.230212 0.357401 -0.465265 +v 1.271640 0.307634 -0.433022 +v 1.283630 0.327347 -0.434325 +v 1.297976 0.338066 -0.448930 +v 1.273145 0.352197 -0.463006 +v 1.245012 0.367929 -0.479484 +v 1.214934 0.338297 -0.527103 +v 1.225502 0.358591 -0.529649 +v 1.199166 0.328159 -0.513740 +v 1.171207 0.341164 -0.535148 +v 1.188323 0.350859 -0.547128 +v 1.197543 0.371595 -0.551056 +v 1.195862 0.375533 -0.487445 +v 1.185295 0.355239 -0.484899 +v 1.211631 0.385671 -0.500807 +v 1.176488 0.401041 -0.529584 +v 1.159373 0.391346 -0.517604 +v 1.150152 0.370609 -0.513676 +v 1.187292 0.335993 -0.496337 +v 1.199166 0.328159 -0.513740 +v 1.185295 0.355239 -0.484899 +v 1.150152 0.370609 -0.513676 +v 1.155742 0.350181 -0.521429 +v 1.171207 0.341164 -0.535148 +v 1.099475 0.371099 -0.596636 +v 1.106322 0.391913 -0.604346 +v 1.104630 0.367107 -0.654600 +v 1.098018 0.347059 -0.645036 +v 1.125811 0.401530 -0.612544 +v 1.124354 0.377491 -0.660944 +v 1.133687 0.345696 -0.706317 +v 1.114197 0.334279 -0.701561 +v 1.107351 0.315264 -0.690409 +v 1.165771 0.356536 -0.573603 +v 1.173598 0.377532 -0.579341 +v 1.147263 0.347100 -0.563433 +v 1.165771 0.356536 -0.573603 +v 1.147263 0.347100 -0.563433 +v 1.133192 0.341239 -0.597940 +v 1.152681 0.350856 -0.606138 +v 1.173598 0.377532 -0.579341 +v 1.159527 0.371671 -0.613848 +v 1.126608 0.398922 -0.557353 +v 1.118780 0.377927 -0.551615 +v 1.145116 0.408359 -0.567523 +v 1.125811 0.401530 -0.612544 +v 1.106322 0.391913 -0.604346 +v 1.118780 0.377927 -0.551615 +v 1.126608 0.398922 -0.557353 +v 1.128083 0.356807 -0.554541 +v 1.147263 0.347100 -0.563433 +v 1.118780 0.377927 -0.551615 +v 1.099475 0.371099 -0.596636 +v 1.111396 0.350462 -0.594305 +v 1.133192 0.341239 -0.597940 +v 1.133687 0.345696 -0.706317 +v 1.155482 0.341270 -0.700773 +v 1.166409 0.314031 -0.734791 +v 1.145603 0.315861 -0.743663 +v 1.167402 0.325433 -0.689263 +v 1.177340 0.300789 -0.719954 +v 1.188895 0.276552 -0.747189 +v 1.179454 0.287087 -0.764737 +v 1.160138 0.286211 -0.776319 +v 1.110564 0.328466 -0.637760 +v 1.132987 0.321286 -0.636449 +v 1.098018 0.347059 -0.645036 +v 1.107351 0.315264 -0.690409 +v 1.119270 0.299427 -0.678899 +v 1.141066 0.295001 -0.673354 +v 1.146776 0.370310 -0.659633 +v 1.124354 0.377491 -0.660944 +v 1.159322 0.351717 -0.652357 +v 1.152711 0.331669 -0.642793 +v 1.159322 0.351717 -0.652357 +v 1.132987 0.321286 -0.636449 +v 1.141066 0.295001 -0.673354 +v 1.160556 0.306418 -0.678111 +v 1.167402 0.325433 -0.689263 +v 1.188895 0.276552 -0.747189 +v 1.181119 0.259525 -0.733773 +v 1.194687 0.234364 -0.759445 +v 1.203311 0.250192 -0.773749 +v 1.162559 0.246120 -0.731281 +v 1.176976 0.219760 -0.757841 +v 1.195232 0.192776 -0.779236 +v 1.211884 0.208641 -0.780183 +v 1.221569 0.223207 -0.795144 +v 1.170122 0.282748 -0.707555 +v 1.177340 0.300789 -0.719954 +v 1.151003 0.270358 -0.704046 +v 1.126484 0.303471 -0.740154 +v 1.119267 0.285429 -0.727755 +v 1.145603 0.315861 -0.743663 +v 1.160138 0.286211 -0.776319 +v 1.141578 0.272806 -0.773827 +v 1.133802 0.255780 -0.760411 +v 1.130197 0.272187 -0.712918 +v 1.151003 0.270358 -0.704046 +v 1.119267 0.285429 -0.727755 +v 1.133802 0.255780 -0.760411 +v 1.143242 0.245244 -0.742863 +v 1.162559 0.246120 -0.731281 +v 1.176656 0.189316 -0.816610 +v 1.186340 0.203883 -0.831572 +v 1.216120 0.171099 -0.844988 +v 1.205294 0.157685 -0.829707 +v 1.186340 0.203883 -0.831572 +v 1.202991 0.219747 -0.832518 +v 1.231630 0.188117 -0.845615 +v 1.216120 0.171099 -0.844988 +v 1.262770 0.159734 -0.848359 +v 1.248319 0.141773 -0.847781 +v 1.205294 0.157685 -0.829707 +v 1.236434 0.129302 -0.832451 +v 1.161369 0.238854 -0.806012 +v 1.152744 0.223026 -0.791708 +v 1.179081 0.253458 -0.807616 +v 1.202991 0.219747 -0.832518 +v 1.159922 0.215687 -0.771791 +v 1.176976 0.219760 -0.757841 +v 1.152744 0.223026 -0.791708 +v 1.176656 0.189316 -0.816610 +v 1.181006 0.185340 -0.794940 +v 1.195232 0.192776 -0.779236 +v 1.196134 0.257531 -0.793665 +v 1.179081 0.253458 -0.807616 +v 1.203311 0.250192 -0.773749 +v 1.221569 0.223207 -0.795144 +v 1.217218 0.227184 -0.816814 +v 1.202991 0.219747 -0.832518 +v 1.262770 0.159734 -0.848359 +v 1.271131 0.172758 -0.831675 +v 1.299668 0.150209 -0.827567 +v 1.293564 0.135388 -0.843952 +v 1.269616 0.174371 -0.809025 +v 1.295897 0.153618 -0.805217 +v 1.319517 0.136938 -0.798022 +v 1.325027 0.132292 -0.819860 +v 1.320662 0.116234 -0.835732 +v 1.206604 0.156785 -0.807188 +v 1.217789 0.167297 -0.790635 +v 1.205294 0.157685 -0.829707 +v 1.236434 0.129302 -0.832451 +v 1.234919 0.130915 -0.809801 +v 1.243280 0.143939 -0.793117 +v 1.242815 0.198629 -0.829062 +v 1.231630 0.188117 -0.845615 +v 1.244124 0.197729 -0.806543 +v 1.233299 0.184315 -0.791262 +v 1.244124 0.197729 -0.806543 +v 1.211884 0.208641 -0.780183 +v 1.195232 0.192776 -0.779236 +v 1.217789 0.167297 -0.790635 +v 1.233299 0.184315 -0.791262 +v 1.243280 0.143939 -0.793117 +v 1.257732 0.161900 -0.793695 +v 1.244124 0.197729 -0.806543 +v 1.269616 0.174371 -0.809025 +v 1.294326 0.085803 -0.819824 +v 1.307708 0.097137 -0.834849 +v 1.329326 0.083338 -0.825457 +v 1.315427 0.072342 -0.810642 +v 1.320662 0.116234 -0.835732 +v 1.341763 0.102774 -0.826550 +v 1.359278 0.092531 -0.817148 +v 1.347288 0.072818 -0.815845 +v 1.332942 0.062099 -0.801240 +v 1.283166 0.141820 -0.789999 +v 1.295897 0.153618 -0.805217 +v 1.269561 0.123186 -0.789308 +v 1.293181 0.106506 -0.782114 +v 1.306135 0.125604 -0.782997 +v 1.319517 0.136938 -0.798022 +v 1.279959 0.116754 -0.843261 +v 1.267228 0.104956 -0.828044 +v 1.293564 0.135388 -0.843952 +v 1.263456 0.108365 -0.805693 +v 1.269561 0.123186 -0.789308 +v 1.267228 0.104956 -0.828044 +v 1.294326 0.085803 -0.819824 +v 1.288815 0.090448 -0.797986 +v 1.293181 0.106506 -0.782114 +v 1.308540 0.077888 -0.789360 +v 1.311529 0.094846 -0.774045 +v 1.315427 0.072342 -0.810642 +v 1.332942 0.062099 -0.801240 +v 1.324860 0.068384 -0.780522 +v 1.326655 0.086081 -0.765770 +v 1.344752 0.119731 -0.811234 +v 1.341763 0.102774 -0.826550 +v 1.337864 0.125278 -0.789953 +v 1.352992 0.116512 -0.781678 +v 1.361072 0.110227 -0.802396 +v 1.359278 0.092531 -0.817148 +v 1.323966 0.114282 -0.775138 +v 1.337864 0.125278 -0.789953 +v 1.311529 0.094846 -0.774045 +v 1.326655 0.086081 -0.765770 +v 1.338645 0.105793 -0.767074 +v 1.352992 0.116512 -0.781678 +v 1.441834 -0.162486 -0.761996 +v 1.476701 -0.193451 -0.734881 +v 1.425083 -0.121434 -0.792721 +v 1.429000 -0.076545 -0.822376 +v 1.452988 -0.034653 -0.846449 +v 1.493394 -0.002136 -0.861274 +v 1.544069 0.016056 -0.864593 +v 1.597295 0.017154 -0.855902 +v 1.644971 0.000989 -0.836524 +v 1.679838 -0.029976 -0.809408 +v 1.696589 -0.071028 -0.778683 +v 1.692672 -0.115916 -0.749027 +v 1.668685 -0.157809 -0.724955 +v 1.628278 -0.190325 -0.710130 +v 1.577604 -0.208518 -0.706811 +v 1.524377 -0.209615 -0.715502 +v 1.493394 -0.002136 -0.861274 +v 1.544069 0.016056 -0.864593 +v 1.542863 0.020656 -0.857789 +v 1.492188 0.002464 -0.854470 +v 1.577604 -0.208518 -0.706811 +v 1.576398 -0.203918 -0.700007 +v 1.544069 0.016056 -0.864593 +v 1.597295 0.017154 -0.855902 +v 1.596089 0.021754 -0.849098 +v 1.542863 0.020656 -0.857789 +v 1.577604 -0.208518 -0.706811 +v 1.524377 -0.209615 -0.715502 +v 1.523171 -0.205015 -0.708699 +v 1.576398 -0.203918 -0.700007 +v 1.644971 0.000989 -0.836524 +v 1.643765 0.005589 -0.829720 +v 1.476701 -0.193451 -0.734881 +v 1.441834 -0.162486 -0.761996 +v 1.440628 -0.157885 -0.755193 +v 1.475495 -0.188851 -0.728077 +v 1.679838 -0.029976 -0.809408 +v 1.678633 -0.025376 -0.802604 +v 1.425083 -0.121434 -0.792721 +v 1.423878 -0.116834 -0.785917 +v 1.696589 -0.071028 -0.778683 +v 1.695383 -0.066427 -0.771880 +v 1.425083 -0.121434 -0.792721 +v 1.429000 -0.076545 -0.822376 +v 1.427794 -0.071945 -0.815573 +v 1.423878 -0.116834 -0.785917 +v 1.696589 -0.071028 -0.778683 +v 1.692672 -0.115916 -0.749027 +v 1.691466 -0.111316 -0.742224 +v 1.695383 -0.066427 -0.771880 +v 1.452988 -0.034653 -0.846449 +v 1.451782 -0.030053 -0.839646 +v 1.360476 -0.199145 -0.735035 +v 1.418602 -0.250766 -0.689831 +v 1.498081 -0.277712 -0.657526 +v 1.586813 -0.275883 -0.643038 +v 1.671290 -0.245555 -0.648571 +v 1.738651 -0.191347 -0.673284 +v 1.778640 -0.121511 -0.713415 +v 1.785169 -0.046678 -0.762853 +v 1.757246 0.021758 -0.814073 +v 1.699119 0.073379 -0.859277 +v 1.619640 0.100326 -0.891582 +v 1.530907 0.098496 -0.906070 +v 1.446431 0.068169 -0.900537 +v 1.379070 0.013960 -0.875823 +v 1.339081 -0.055876 -0.835693 +v 1.332551 -0.130709 -0.786254 +v 1.475495 -0.188851 -0.728077 +v 1.440628 -0.157885 -0.755193 +v 1.423878 -0.116834 -0.785917 +v 1.427794 -0.071945 -0.815573 +v 1.451782 -0.030053 -0.839646 +v 1.492188 0.002464 -0.854470 +v 1.542863 0.020656 -0.857789 +v 1.596089 0.021754 -0.849098 +v 1.643765 0.005589 -0.829720 +v 1.678633 -0.025376 -0.802604 +v 1.695383 -0.066427 -0.771880 +v 1.691466 -0.111316 -0.742224 +v 1.667479 -0.153208 -0.718151 +v 1.627072 -0.185725 -0.703327 +v 1.576398 -0.203918 -0.700007 +v 1.523171 -0.205015 -0.708699 +vt 0.443496 0.070001 +vt 0.451196 0.070001 +vt 0.451254 0.069711 +vt 0.443439 0.069711 +vt 0.257498 0.085510 +vt 0.260438 0.078413 +vt 0.259804 0.077990 +vt 0.256750 0.085361 +vt 0.458146 0.105511 +vt 0.451139 0.108413 +vt 0.451196 0.108702 +vt 0.458311 0.105756 +vt 0.726905 0.091805 +vt 0.724002 0.098810 +vt 0.724248 0.098975 +vt 0.727195 0.091862 +vt 0.688774 0.091805 +vt 0.688774 0.084222 +vt 0.688484 0.084164 +vt 0.688484 0.091862 +vt 0.436547 0.073193 +vt 0.443554 0.070291 +vt 0.436382 0.072947 +vt 0.463510 0.078555 +vt 0.466412 0.085560 +vt 0.466702 0.085503 +vt 0.463755 0.078390 +vt 0.428281 0.093143 +vt 0.428281 0.085560 +vt 0.427991 0.085503 +vt 0.427991 0.093201 +vt 0.711632 0.107074 +vt 0.704047 0.107074 +vt 0.703990 0.107364 +vt 0.711690 0.107364 +vt 0.704047 0.068953 +vt 0.711631 0.068953 +vt 0.711689 0.068663 +vt 0.703989 0.068663 +vt 0.431183 0.078555 +vt 0.430937 0.078390 +vt 0.443554 0.108413 +vt 0.443496 0.108702 +vt 0.726905 0.084222 +vt 0.727194 0.084164 +vt 0.691677 0.098810 +vt 0.691431 0.098975 +vt 0.697040 0.104172 +vt 0.696876 0.104418 +vt 0.466412 0.093143 +vt 0.466702 0.093201 +vt 0.697040 0.071854 +vt 0.696875 0.071609 +vt 0.727485 0.091920 +vt 0.727484 0.084107 +vt 0.430692 0.078226 +vt 0.427701 0.085445 +vt 0.703932 0.107654 +vt 0.711747 0.107654 +vt 0.427701 0.093259 +vt 0.691431 0.077052 +vt 0.696711 0.071363 +vt 0.691185 0.076888 +vt 0.724494 0.099139 +vt 0.430937 0.100313 +vt 0.430692 0.100477 +vt 0.436382 0.105756 +vt 0.436218 0.106002 +vt 0.703932 0.068373 +vt 0.718803 0.104418 +vt 0.718968 0.104664 +vt 0.443439 0.108992 +vt 0.451254 0.108992 +vt 0.711747 0.068373 +vt 0.458475 0.106002 +vt 0.718639 0.071854 +vt 0.718803 0.071609 +vt 0.431183 0.100149 +vt 0.458146 0.073193 +vt 0.458310 0.072947 +vt 0.691677 0.077216 +vt 0.718639 0.104172 +vt 0.463510 0.100149 +vt 0.463755 0.100313 +vt 0.724002 0.077216 +vt 0.724248 0.077052 +vt 0.436547 0.105511 +vt 0.451139 0.070291 +vt 0.688194 0.084107 +vt 0.458475 0.072701 +vt 0.436218 0.072701 +vt 0.724494 0.076888 +vt 0.464001 0.078226 +vt 0.688194 0.091920 +vt 0.466992 0.085445 +vt 0.696712 0.104664 +vt 0.718967 0.071363 +vt 0.466992 0.093259 +vt 0.691185 0.099139 +vt 0.464001 0.100477 +vt 0.239678 0.070290 +vt 0.246685 0.073192 +vt 0.246826 0.072981 +vt 0.239727 0.070041 +vt 0.239678 0.108412 +vt 0.232093 0.108412 +vt 0.232043 0.108661 +vt 0.239727 0.108661 +vt 0.266013 0.105510 +vt 0.260650 0.100148 +vt 0.260438 0.100289 +vt 0.265872 0.105721 +vt 0.266012 0.073192 +vt 0.273019 0.070290 +vt 0.272970 0.070041 +vt 0.265871 0.072981 +vt 0.252049 0.078554 +vt 0.252260 0.078413 +vt 0.254951 0.085560 +vt 0.255200 0.085510 +vt 0.216820 0.085560 +vt 0.219722 0.078554 +vt 0.219511 0.078413 +vt 0.216571 0.085510 +vt 0.292975 0.078554 +vt 0.295877 0.085560 +vt 0.296126 0.085510 +vt 0.293186 0.078413 +vt 0.280605 0.108412 +vt 0.273020 0.108412 +vt 0.272970 0.108661 +vt 0.280654 0.108661 +vt 0.225086 0.105510 +vt 0.224944 0.105721 +vt 0.260649 0.078554 +vt 0.254951 0.093143 +vt 0.252049 0.100148 +vt 0.252260 0.100289 +vt 0.255200 0.093192 +vt 0.225086 0.073192 +vt 0.224944 0.072981 +vt 0.287611 0.073192 +vt 0.287752 0.072981 +vt 0.219722 0.100148 +vt 0.219511 0.100289 +vt 0.218877 0.100712 +vt 0.224521 0.106355 +vt 0.265448 0.072348 +vt 0.232043 0.070041 +vt 0.239876 0.069294 +vt 0.231895 0.069294 +vt 0.272821 0.069294 +vt 0.231895 0.109408 +vt 0.280654 0.070041 +vt 0.280802 0.069294 +vt 0.239876 0.109408 +vt 0.224521 0.072348 +vt 0.288176 0.072348 +vt 0.293819 0.077990 +vt 0.259805 0.100712 +vt 0.265448 0.106355 +vt 0.218877 0.077990 +vt 0.296126 0.093192 +vt 0.296874 0.093341 +vt 0.296874 0.085361 +vt 0.246826 0.105721 +vt 0.247250 0.106355 +vt 0.293186 0.100289 +vt 0.293820 0.100713 +vt 0.257747 0.093143 +vt 0.257498 0.093192 +vt 0.295877 0.093143 +vt 0.216820 0.093143 +vt 0.216571 0.093192 +vt 0.287612 0.105510 +vt 0.287753 0.105721 +vt 0.280604 0.070290 +vt 0.232093 0.070290 +vt 0.246685 0.105510 +vt 0.257747 0.085560 +vt 0.292975 0.100148 +vt 0.256750 0.093341 +vt 0.255948 0.093341 +vt 0.255948 0.085361 +vt 0.215823 0.093341 +vt 0.252893 0.077990 +vt 0.272822 0.109408 +vt 0.215823 0.085361 +vt 0.280803 0.109408 +vt 0.288176 0.106355 +vt 0.252893 0.100713 +vt 0.247250 0.072348 +vt 0.357897 0.068048 +vt 0.360442 0.080842 +vt 0.360442 0.074192 +vt 0.353194 0.063346 +vt 0.357897 0.086985 +vt 0.347049 0.060802 +vt 0.353194 0.091687 +vt 0.340397 0.060802 +vt 0.347049 0.094232 +vt 0.340398 0.094232 +vt 0.334252 0.063346 +vt 0.334253 0.091687 +vt 0.329549 0.068048 +vt 0.327004 0.074192 +vt 0.329550 0.086985 +vt 0.327004 0.080842 +vt 0.760176 0.398674 +vt 0.761703 0.406349 +vt 0.761703 0.402360 +vt 0.757355 0.395854 +vt 0.760176 0.410034 +vt 0.753669 0.394327 +vt 0.757355 0.412854 +vt 0.753669 0.414381 +vt 0.749679 0.394327 +vt 0.745993 0.395854 +vt 0.749679 0.414381 +vt 0.743171 0.398674 +vt 0.745993 0.412854 +vt 0.741644 0.402360 +vt 0.743171 0.410034 +vt 0.741644 0.406349 +vt 0.797048 0.013307 +vt 0.796334 0.013298 +vt 0.796072 0.020294 +vt 0.796786 0.020303 +vt 0.795979 0.027877 +vt 0.796694 0.027885 +vt 0.796072 0.034891 +vt 0.796786 0.034899 +vt 0.796334 0.040268 +vt 0.797048 0.040277 +vt 0.878879 0.089483 +vt 0.878163 0.089482 +vt 0.878084 0.096139 +vt 0.878799 0.096140 +vt 0.878056 0.103678 +vt 0.878771 0.103679 +vt 0.878084 0.110953 +vt 0.878799 0.110954 +vt 0.878163 0.116855 +vt 0.878879 0.116856 +vt 0.527119 0.042360 +vt 0.526404 0.042359 +vt 0.526386 0.049357 +vt 0.527102 0.049358 +vt 0.526380 0.056940 +vt 0.527095 0.056940 +vt 0.526386 0.063953 +vt 0.527102 0.063954 +vt 0.526404 0.069330 +vt 0.527119 0.069331 +vt 0.927665 0.765055 +vt 0.926949 0.765056 +vt 0.926870 0.770958 +vt 0.927585 0.770957 +vt 0.148639 0.042907 +vt 0.142500 0.042896 +vt 0.142500 0.088216 +vt 0.148639 0.088226 +vt 0.926842 0.778233 +vt 0.927557 0.778232 +vt 0.927585 0.785771 +vt 0.926870 0.785773 +vt 0.926949 0.792429 +vt 0.927665 0.792428 +vt 0.012693 0.046229 +vt 0.006080 0.046216 +vt 0.006080 0.091527 +vt 0.012693 0.091540 +vt 0.024251 0.046115 +vt 0.019074 0.046194 +vt 0.019074 0.091505 +vt 0.024251 0.091426 +vt 0.155290 0.042907 +vt 0.155290 0.088226 +vt 0.161442 0.042897 +vt 0.161442 0.088216 +vt 0.166159 0.042877 +vt 0.166159 0.088197 +vt 0.406386 0.047231 +vt 0.401209 0.047152 +vt 0.401209 0.092463 +vt 0.406386 0.092542 +vt 0.412767 0.047266 +vt 0.412767 0.092577 +vt 0.419381 0.047253 +vt 0.419381 0.092564 +vt 0.425220 0.047193 +vt 0.425220 0.092504 +vt 0.172771 0.042987 +vt 0.166632 0.042831 +vt 0.166632 0.088066 +vt 0.172771 0.088222 +vt 0.179422 0.042988 +vt 0.179422 0.088223 +vt 0.185574 0.042833 +vt 0.185574 0.088068 +vt 0.190288 0.042547 +vt 0.190288 0.087782 +vt 0.000240 0.046156 +vt 0.000240 0.091467 +vt 0.908297 0.894167 +vt 0.902024 0.891570 +vt 0.901090 0.892967 +vt 0.907969 0.895815 +vt 0.915087 0.860039 +vt 0.921361 0.862637 +vt 0.922294 0.861240 +vt 0.915415 0.858392 +vt 0.897223 0.886769 +vt 0.895825 0.887703 +vt 0.926162 0.867438 +vt 0.927559 0.866504 +vt 0.894624 0.880497 +vt 0.892976 0.880825 +vt 0.928760 0.873709 +vt 0.930409 0.873382 +vt 0.894624 0.873709 +vt 0.892976 0.873381 +vt 0.928760 0.880498 +vt 0.930409 0.880826 +vt 0.897223 0.867437 +vt 0.895825 0.866504 +vt 0.926162 0.886770 +vt 0.927559 0.887703 +vt 0.902024 0.862637 +vt 0.901090 0.861240 +vt 0.921361 0.891570 +vt 0.922294 0.892967 +vt 0.908297 0.860039 +vt 0.907969 0.858391 +vt 0.915087 0.894168 +vt 0.915415 0.895815 +vt 0.685445 0.016835 +vt 0.685474 0.024375 +vt 0.686075 0.024299 +vt 0.686048 0.016857 +vt 0.400592 0.077584 +vt 0.400592 0.070100 +vt 0.399995 0.070219 +vt 0.399995 0.077466 +vt 0.685553 0.031032 +vt 0.686154 0.030869 +vt 0.397727 0.063185 +vt 0.397221 0.063524 +vt 0.097924 0.014653 +vt 0.097662 0.021649 +vt 0.098273 0.021706 +vt 0.098532 0.014801 +vt 0.392434 0.057893 +vt 0.392095 0.058400 +vt 0.097570 0.029232 +vt 0.098182 0.029190 +vt 0.385517 0.055029 +vt 0.385398 0.055627 +vt 0.097662 0.036246 +vt 0.098273 0.036113 +vt 0.378031 0.055029 +vt 0.378150 0.055627 +vt 0.097924 0.041623 +vt 0.098532 0.041421 +vt 0.371114 0.057893 +vt 0.371453 0.058400 +vt 0.997840 0.808363 +vt 0.997760 0.815020 +vt 0.998362 0.815096 +vt 0.998441 0.808525 +vt 0.365821 0.063185 +vt 0.366327 0.063524 +vt 0.997732 0.822559 +vt 0.998334 0.822538 +vt 0.362956 0.070100 +vt 0.363553 0.070219 +vt 0.997760 0.829834 +vt 0.998362 0.829718 +vt 0.362956 0.077584 +vt 0.363553 0.077466 +vt 0.997840 0.835736 +vt 0.998441 0.835543 +vt 0.365821 0.084499 +vt 0.366327 0.084161 +vt 0.993282 0.077628 +vt 0.993265 0.084626 +vt 0.993863 0.084676 +vt 0.993880 0.077769 +vt 0.371114 0.089791 +vt 0.371453 0.089285 +vt 0.993259 0.092208 +vt 0.993857 0.092160 +vt 0.378031 0.092655 +vt 0.378150 0.092059 +vt 0.993265 0.099222 +vt 0.993863 0.099083 +vt 0.385517 0.092655 +vt 0.385398 0.092059 +vt 0.993282 0.104599 +vt 0.993880 0.104390 +vt 0.392434 0.089791 +vt 0.392095 0.089285 +vt 0.685553 0.003659 +vt 0.685474 0.009561 +vt 0.686075 0.009677 +vt 0.686154 0.003851 +vt 0.397727 0.084499 +vt 0.397221 0.084161 +vt 0.407313 0.516073 +vt 0.407361 0.519762 +vt 0.407974 0.519770 +vt 0.407925 0.516080 +vt 0.907903 0.896164 +vt 0.915487 0.896164 +vt 0.900895 0.893262 +vt 0.895532 0.887900 +vt 0.892630 0.880894 +vt 0.892630 0.873311 +vt 0.895532 0.866306 +vt 0.900895 0.860944 +vt 0.907903 0.858042 +vt 0.915487 0.858042 +vt 0.922495 0.860944 +vt 0.927858 0.866306 +vt 0.930760 0.873312 +vt 0.930760 0.880895 +vt 0.927858 0.887900 +vt 0.922495 0.893262 +vt 0.915021 0.893818 +vt 0.908369 0.893818 +vt 0.902224 0.891273 +vt 0.897521 0.886571 +vt 0.894976 0.880428 +vt 0.894976 0.873778 +vt 0.897521 0.867634 +vt 0.902224 0.862932 +vt 0.908369 0.860388 +vt 0.915021 0.860388 +vt 0.921166 0.862932 +vt 0.925869 0.867635 +vt 0.928414 0.873778 +vt 0.928414 0.880428 +vt 0.925869 0.886572 +vt 0.921166 0.891273 +vt 0.685036 0.016836 +vt 0.685064 0.024376 +vt 0.678612 0.024387 +vt 0.678692 0.031044 +vt 0.685144 0.031033 +vt 0.097253 0.021644 +vt 0.090813 0.021567 +vt 0.090721 0.029149 +vt 0.097161 0.029227 +vt 0.685064 0.009561 +vt 0.678612 0.009572 +vt 0.678584 0.016847 +vt 0.685144 0.003659 +vt 0.678692 0.003670 +vt 0.992855 0.099222 +vt 0.992872 0.104598 +vt 0.992849 0.092208 +vt 0.986403 0.099217 +vt 0.986420 0.104593 +vt 0.992855 0.084625 +vt 0.992872 0.077628 +vt 0.986396 0.092203 +vt 0.997350 0.829833 +vt 0.997430 0.835735 +vt 0.986403 0.084620 +vt 0.997322 0.822559 +vt 0.986420 0.077623 +vt 0.997350 0.815019 +vt 0.990899 0.829822 +vt 0.990979 0.835724 +vt 0.997430 0.808362 +vt 0.990871 0.822548 +vt 0.097253 0.036241 +vt 0.097515 0.041618 +vt 0.990899 0.815008 +vt 0.990979 0.808351 +vt 0.090813 0.036163 +vt 0.091075 0.041541 +vt 0.097515 0.014648 +vt 0.930992 0.765049 +vt 0.930912 0.770951 +vt 0.800370 0.013347 +vt 0.800107 0.020343 +vt 0.800015 0.027925 +vt 0.800107 0.034939 +vt 0.800370 0.040317 +vt 0.882206 0.089489 +vt 0.882127 0.096145 +vt 0.882099 0.103685 +vt 0.882127 0.110960 +vt 0.882206 0.116862 +vt 0.530447 0.042363 +vt 0.530430 0.049360 +vt 0.530424 0.056943 +vt 0.530430 0.063957 +vt 0.530447 0.069333 +vt 0.123285 0.049387 +vt 0.099708 0.049387 +vt 0.099730 0.054764 +vt 0.123307 0.054764 +vt 0.930466 0.734298 +vt 0.906893 0.734298 +vt 0.906803 0.740200 +vt 0.930376 0.740200 +vt 0.930913 0.785766 +vt 0.930992 0.792423 +vt 0.930884 0.778226 +vt 0.992782 0.505359 +vt 0.992512 0.512568 +vt 0.998385 0.512639 +vt 0.998655 0.505430 +vt 0.992417 0.520381 +vt 0.998290 0.520452 +vt 0.992512 0.527609 +vt 0.998385 0.527679 +vt 0.992782 0.533150 +vt 0.998655 0.533220 +vt 0.992889 0.544322 +vt 0.992807 0.551182 +vt 0.998691 0.551192 +vt 0.998773 0.544332 +vt 0.992778 0.558951 +vt 0.998662 0.558961 +vt 0.992807 0.566447 +vt 0.998691 0.566457 +vt 0.992889 0.572528 +vt 0.998773 0.572538 +vt 0.993213 0.576054 +vt 0.993195 0.583264 +vt 0.999080 0.583269 +vt 0.999098 0.576058 +vt 0.993189 0.591077 +vt 0.999074 0.591082 +vt 0.993195 0.598304 +vt 0.999080 0.598309 +vt 0.993213 0.603845 +vt 0.999098 0.603849 +vt 0.992830 0.868057 +vt 0.992748 0.874138 +vt 0.998632 0.874128 +vt 0.998714 0.868047 +vt 0.992719 0.881634 +vt 0.998603 0.881624 +vt 0.992748 0.889403 +vt 0.992830 0.896263 +vt 0.998714 0.896253 +vt 0.998632 0.889393 +vt 0.930351 0.755014 +vt 0.906778 0.755014 +vt 0.906847 0.761671 +vt 0.930420 0.761671 +vt 0.688544 0.060711 +vt 0.712077 0.060711 +vt 0.712078 0.053129 +vt 0.688545 0.053129 +vt 0.711902 0.046116 +vt 0.688369 0.046116 +vt 0.711575 0.040742 +vt 0.688042 0.040742 +vt 0.777865 0.068234 +vt 0.801437 0.068234 +vt 0.801506 0.061577 +vt 0.777933 0.061577 +vt 0.801521 0.054037 +vt 0.777948 0.054037 +vt 0.801481 0.046763 +vt 0.777908 0.046763 +vt 0.801391 0.040861 +vt 0.777818 0.040861 +vt 0.123285 0.027793 +vt 0.099709 0.027793 +vt 0.099697 0.034791 +vt 0.123274 0.034791 +vt 0.099697 0.042374 +vt 0.123273 0.042374 +vt 0.091075 0.014571 +vt 0.906763 0.747475 +vt 0.930336 0.747475 +vt 0.688366 0.067710 +vt 0.711899 0.067710 +vt 0.992443 0.497788 +vt 0.992527 0.504792 +vt 0.998384 0.504782 +vt 0.998300 0.497778 +vt 0.992388 0.016839 +vt 0.992291 0.024818 +vt 0.998138 0.024888 +vt 0.998235 0.016909 +vt 0.992388 0.032198 +vt 0.998235 0.032269 +vt 0.992664 0.037857 +vt 0.998510 0.037928 +vt 0.992670 0.115381 +vt 0.992586 0.122385 +vt 0.998443 0.122395 +vt 0.998527 0.115390 +vt 0.992557 0.130319 +vt 0.998414 0.130329 +vt 0.992586 0.137974 +vt 0.998443 0.137984 +vt 0.992670 0.144185 +vt 0.998527 0.144195 +vt 0.681819 0.114181 +vt 0.681800 0.121545 +vt 0.687658 0.121549 +vt 0.687677 0.114186 +vt 0.681794 0.129524 +vt 0.687652 0.129528 +vt 0.681800 0.136904 +vt 0.687658 0.136909 +vt 0.681819 0.142562 +vt 0.687677 0.142566 +vt 0.992527 0.475988 +vt 0.992443 0.482199 +vt 0.998300 0.482189 +vt 0.998384 0.475978 +vt 0.992414 0.489854 +vt 0.998271 0.489844 +vt 0.992664 0.009477 +vt 0.998510 0.009548 +vt 0.963746 0.344902 +vt 0.964555 0.343554 +vt 0.961693 0.342088 +vt 0.960494 0.343208 +vt 0.965258 0.342182 +vt 0.962785 0.340945 +vt 0.961077 0.338748 +vt 0.959684 0.339578 +vt 0.958183 0.340385 +vt 0.913799 0.410577 +vt 0.913834 0.408965 +vt 0.911503 0.408992 +vt 0.911482 0.410599 +vt 0.913762 0.407377 +vt 0.911416 0.407408 +vt 0.908750 0.407485 +vt 0.908941 0.409043 +vt 0.909025 0.410625 +vt 0.970381 0.345909 +vt 0.970572 0.344351 +vt 0.967639 0.344184 +vt 0.967193 0.345672 +vt 0.970655 0.342769 +vt 0.967979 0.342673 +vt 0.973133 0.344403 +vt 0.973113 0.342795 +vt 0.973046 0.345987 +vt 0.975393 0.346017 +vt 0.975464 0.344429 +vt 0.975429 0.342818 +vt 0.305125 0.002461 +vt 0.305125 0.004786 +vt 0.306725 0.004780 +vt 0.306725 0.002460 +vt 0.305125 0.007253 +vt 0.306725 0.007207 +vt 0.308326 0.007253 +vt 0.308326 0.004786 +vt 0.308326 0.002461 +vt 0.954124 0.538042 +vt 0.954124 0.535366 +vt 0.952524 0.535376 +vt 0.952524 0.538091 +vt 0.954124 0.533010 +vt 0.952524 0.533015 +vt 0.950923 0.533010 +vt 0.950923 0.535366 +vt 0.950923 0.538042 +vt 0.306725 0.009798 +vt 0.308326 0.009941 +vt 0.305125 0.009941 +vt 0.305125 0.012676 +vt 0.306725 0.012397 +vt 0.308326 0.012676 +vt 0.952524 0.541389 +vt 0.954124 0.541242 +vt 0.950923 0.541242 +vt 0.950923 0.544705 +vt 0.952524 0.544988 +vt 0.954124 0.544705 +vt 0.906009 0.409210 +vt 0.906348 0.410722 +vt 0.905562 0.407723 +vt 0.902115 0.408493 +vt 0.902925 0.409841 +vt 0.903627 0.411212 +vt 0.731387 0.071375 +vt 0.729720 0.071011 +vt 0.729453 0.074988 +vt 0.731132 0.075214 +vt 0.728246 0.071341 +vt 0.727991 0.075180 +vt 0.727917 0.079331 +vt 0.729375 0.079280 +vt 0.731058 0.079365 +vt 0.306725 0.014743 +vt 0.308326 0.015170 +vt 0.305125 0.015170 +vt 0.299537 0.113092 +vt 0.301029 0.113505 +vt 0.300676 0.111321 +vt 0.299207 0.111024 +vt 0.297888 0.113533 +vt 0.297535 0.111349 +vt 0.952524 0.548405 +vt 0.954124 0.547975 +vt 0.950923 0.547975 +vt 0.950923 0.550304 +vt 0.952524 0.550848 +vt 0.731901 0.068731 +vt 0.730259 0.068259 +vt 0.900063 0.411306 +vt 0.901155 0.412450 +vt 0.898863 0.410187 +vt 0.896553 0.413010 +vt 0.898053 0.413816 +vt 0.899446 0.414646 +vt 0.957524 0.332323 +vt 0.959156 0.332271 +vt 0.959614 0.328980 +vt 0.958020 0.328714 +vt 0.960680 0.332195 +vt 0.961100 0.329223 +vt 0.961709 0.326461 +vt 0.960313 0.325928 +vt 0.958809 0.325372 +vt 0.897361 0.417349 +vt 0.898879 0.417801 +vt 0.895735 0.416920 +vt 0.895894 0.421071 +vt 0.897525 0.421124 +vt 0.899050 0.421200 +vt 0.958991 0.336046 +vt 0.957366 0.336474 +vt 0.960509 0.335593 +vt 0.299076 0.108015 +vt 0.297393 0.108198 +vt 0.300534 0.108170 +vt 0.300532 0.104770 +vt 0.299076 0.104755 +vt 0.297391 0.104798 +vt 0.297531 0.099055 +vt 0.299209 0.099242 +vt 0.299336 0.096511 +vt 0.297669 0.096213 +vt 0.300672 0.099028 +vt 0.300810 0.096185 +vt 0.301029 0.093589 +vt 0.299540 0.094018 +vt 0.297888 0.093617 +vt 0.299125 0.101899 +vt 0.297442 0.101822 +vt 0.300583 0.101794 +vt 0.729379 0.083036 +vt 0.731063 0.083001 +vt 0.727922 0.082967 +vt 0.727989 0.086359 +vt 0.729450 0.086539 +vt 0.731130 0.086393 +vt 0.897983 0.424414 +vt 0.899470 0.424172 +vt 0.896390 0.424680 +vt 0.897179 0.428023 +vt 0.898683 0.427466 +vt 0.900079 0.426934 +vt 0.731522 0.093152 +vt 0.729864 0.093521 +vt 0.730260 0.096144 +vt 0.731901 0.095690 +vt 0.158185 0.002367 +vt 0.156585 0.002774 +vt 0.156585 0.005046 +vt 0.158185 0.004734 +vt 0.156585 0.007692 +vt 0.158185 0.007469 +vt 0.159785 0.005046 +vt 0.159785 0.007692 +vt 0.729601 0.090164 +vt 0.731273 0.089903 +vt 0.728132 0.089868 +vt 0.728381 0.093117 +vt 0.899710 0.430600 +vt 0.900945 0.429770 +vt 0.898368 0.431453 +vt 0.900078 0.434584 +vt 0.901201 0.433458 +vt 0.902217 0.432356 +vt 0.961341 0.322795 +vt 0.959999 0.321941 +vt 0.962575 0.323625 +vt 0.963847 0.321039 +vt 0.962831 0.319937 +vt 0.961708 0.318811 +vt 0.966646 0.314798 +vt 0.967277 0.316270 +vt 0.969800 0.315313 +vt 0.969369 0.313763 +vt 0.967799 0.317719 +vt 0.970124 0.316839 +vt 0.972267 0.316359 +vt 0.972101 0.314796 +vt 0.971828 0.313209 +vt 0.903237 0.435625 +vt 0.904002 0.434315 +vt 0.902365 0.436959 +vt 0.905016 0.438597 +vt 0.905646 0.437124 +vt 0.906169 0.435676 +vt 0.964868 0.317769 +vt 0.963995 0.316436 +vt 0.965633 0.319079 +vt 0.299847 0.092124 +vt 0.298212 0.091644 +vt 0.655599 0.232976 +vt 0.653999 0.232572 +vt 0.653999 0.234357 +vt 0.655599 0.234667 +vt 0.653999 0.236527 +vt 0.655599 0.236746 +vt 0.657200 0.234357 +vt 0.657200 0.236527 +vt 0.159785 0.012877 +vt 0.158185 0.012788 +vt 0.158185 0.014796 +vt 0.159785 0.014836 +vt 0.156585 0.012877 +vt 0.156585 0.014836 +vt 0.156585 0.016490 +vt 0.158185 0.016491 +vt 0.159785 0.016490 +vt 0.655599 0.239002 +vt 0.657200 0.238858 +vt 0.653999 0.238858 +vt 0.653999 0.241007 +vt 0.655599 0.241092 +vt 0.657200 0.241007 +vt 0.158185 0.010267 +vt 0.159785 0.010415 +vt 0.156585 0.010415 +vt 0.908170 0.438081 +vt 0.908494 0.436555 +vt 0.907739 0.439632 +vt 0.910197 0.440185 +vt 0.910471 0.438599 +vt 0.910637 0.437035 +vt 0.912298 0.438785 +vt 0.912337 0.437205 +vt 0.912151 0.440388 +vt 0.913799 0.440410 +vt 0.913834 0.438799 +vt 0.913762 0.437211 +vt 0.973928 0.314610 +vt 0.973782 0.313006 +vt 0.973968 0.316190 +vt 0.975393 0.316183 +vt 0.975464 0.314596 +vt 0.975429 0.312984 +vt 0.655599 0.242750 +vt 0.657200 0.242713 +vt 0.653999 0.242713 +vt 0.653999 0.244144 +vt 0.655599 0.244139 +vt 0.657200 0.244144 +vt 0.391804 0.071847 +vt 0.391804 0.075836 +vt 0.390277 0.068162 +vt 0.387455 0.065341 +vt 0.383769 0.063814 +vt 0.379779 0.063814 +vt 0.376093 0.065341 +vt 0.373272 0.068162 +vt 0.371745 0.071847 +vt 0.371745 0.075836 +vt 0.373272 0.079521 +vt 0.376093 0.082341 +vt 0.379779 0.083868 +vt 0.383769 0.083868 +vt 0.387455 0.082341 +vt 0.390277 0.079521 +vt 0.407314 0.475914 +vt 0.407323 0.478742 +vt 0.407937 0.478742 +vt 0.407928 0.475914 +vt 0.407499 0.522591 +vt 0.408112 0.522599 +vt 0.407368 0.479029 +vt 0.407326 0.482134 +vt 0.407940 0.482133 +vt 0.407982 0.479028 +vt 0.407368 0.493717 +vt 0.407326 0.497219 +vt 0.407940 0.497220 +vt 0.407982 0.493718 +vt 0.407311 0.485961 +vt 0.407925 0.485960 +vt 0.407311 0.501185 +vt 0.407326 0.505012 +vt 0.407940 0.505013 +vt 0.407925 0.501186 +vt 0.407326 0.489927 +vt 0.407940 0.489926 +vt 0.407368 0.508117 +vt 0.407982 0.508118 +vt 0.407368 0.493429 +vt 0.407982 0.493428 +vt 0.407323 0.464554 +vt 0.407314 0.468235 +vt 0.407928 0.468236 +vt 0.407937 0.464555 +vt 0.407499 0.508404 +vt 0.407361 0.512084 +vt 0.407974 0.512091 +vt 0.408112 0.508411 +vt 0.407311 0.472224 +vt 0.407925 0.472225 +vn 0.1453 -0.5542 -0.8196 +vn 0.1452 -0.5542 -0.8196 +vn -0.1453 0.5542 0.8196 +vn -0.1453 0.5541 0.8196 +vn 0.1453 -0.5541 -0.8196 +vn -0.1452 0.5541 0.8197 +vn -0.1453 0.5541 0.8197 +vn -0.1452 0.5542 0.8196 +vn 0.1453 -0.5543 -0.8196 +vn 0.1452 -0.5541 -0.8197 +vn -0.1452 0.5542 0.8197 +vn 0.1453 -0.5541 -0.8197 +vn 0.1454 -0.5542 -0.8196 +vn -0.1452 0.5541 0.8196 +vn 0.1452 -0.5541 -0.8196 +vn -0.9819 -0.1823 -0.0508 +vn -0.9658 0.0363 0.2569 +vn -0.9395 0.3378 0.0577 +vn -0.9536 0.1424 -0.2653 +vn -0.7783 0.6192 -0.1040 +vn -0.7801 0.4454 -0.4394 +vn -0.5070 0.8376 -0.2036 +vn -0.4878 0.6806 -0.5466 +vn -0.1665 0.9598 -0.2259 +vn -0.1213 0.8122 -0.5706 +vn -0.1213 0.8122 -0.5707 +vn 0.1910 0.9672 -0.1675 +vn 0.2637 0.8201 -0.5078 +vn 0.5113 0.8586 -0.0373 +vn 0.6086 0.7032 -0.3676 +vn 0.7455 0.6506 0.1448 +vn 0.8608 0.4792 -0.1715 +vn 0.8580 0.3749 0.3512 +vn 0.9819 0.1823 0.0508 +vn 0.8317 0.0733 0.5504 +vn 0.9536 -0.1424 0.2653 +vn 0.6705 -0.2081 0.7121 +vn 0.7801 -0.4454 0.4394 +vn 0.3991 -0.4265 0.8117 +vn 0.4878 -0.6806 0.5466 +vn 0.0587 -0.5486 0.8340 +vn 0.1213 -0.8122 0.5706 +vn -0.2988 -0.5560 0.7756 +vn -0.2637 -0.8201 0.5078 +vn 0.8128 0.0946 0.5748 +vn 0.8387 0.3913 0.3787 +vn -0.6191 -0.4474 0.6454 +vn -0.6086 -0.7032 0.3676 +vn -0.8608 -0.4792 0.1715 +vn -0.8533 -0.2394 0.4632 +vn 0.4974 0.8675 -0.0037 +vn 0.1823 0.9744 -0.1318 +vn 0.7279 0.6628 0.1755 +vn 0.6543 -0.1824 0.7339 +vn 0.3871 -0.3974 0.8320 +vn 0.0520 -0.5178 0.8539 +vn -0.2999 -0.5250 0.7965 +vn -0.6152 -0.4181 0.6683 +vn -0.8458 -0.2133 0.4890 +vn -0.9565 0.0580 0.2859 +vn -0.9306 0.3549 0.0898 +vn -0.7720 0.6319 -0.0694 +vn -0.5049 0.8468 -0.1673 +vn -0.1698 0.9671 -0.1893 +vn 0.1527 0.6831 0.7142 +vn 0.1934 0.5832 0.7890 +vn -0.5417 0.4276 0.7237 +vn -0.4911 0.3037 0.8164 +vn -0.4263 0.3607 0.8296 +vn -0.4670 0.4606 0.7548 +vn 0.2777 0.5797 0.7661 +vn 0.2271 0.7036 0.6733 +vn 0.1839 0.4740 0.8611 +vn -0.5299 0.5630 0.6342 +vn -0.4575 0.5698 0.6827 +vn 0.2658 0.4442 0.8556 +vn 0.1255 0.3721 0.9197 +vn -0.4575 0.6895 0.5615 +vn -0.3992 0.6717 0.6241 +vn 0.1935 0.3178 0.9282 +vn 0.0273 0.2930 0.9557 +vn -0.3355 0.7876 0.5168 +vn -0.3009 0.7508 0.5881 +vn 0.0715 0.2197 0.9730 +vn -0.0960 0.2487 0.9638 +vn -0.1826 0.8425 0.5068 +vn -0.1776 0.7950 0.5800 +vn -0.0814 0.1648 0.9830 +vn -0.2255 0.2461 0.9427 +vn -0.0220 0.8458 0.5330 +vn -0.0481 0.7977 0.6011 +vn -0.2420 0.1614 0.9567 +vn -0.3415 0.2854 0.8955 +vn 0.1219 0.7970 0.5915 +vn 0.0679 0.7584 0.6482 +vn -0.3859 0.2102 0.8983 +vn -0.5689 -0.7973 0.2017 +vn -0.8163 -0.5776 0.0093 +vn -0.5239 -0.7292 -0.4403 +vn -0.3411 -0.8915 -0.2981 +vn -0.3411 -0.8915 -0.2982 +vn -0.5239 -0.7291 -0.4404 +vn -0.0093 -0.6302 -0.7764 +vn 0.0353 -0.6699 -0.7416 +vn -0.9351 -0.2863 -0.2087 +vn -0.6117 -0.5139 -0.6014 +vn -0.0308 -0.5777 -0.8157 +vn -0.9074 0.0323 -0.4191 +vn -0.5912 -0.2785 -0.7569 +vn -0.5911 -0.2786 -0.7569 +vn -0.0258 -0.5202 -0.8536 +vn -0.7371 0.3295 -0.5899 +vn -0.4654 -0.0589 -0.8831 +vn 0.0049 -0.4666 -0.8845 +vn -0.4504 0.5603 -0.6951 +vn -0.2535 0.1116 -0.9609 +vn 0.0566 -0.4250 -0.9034 +vn -0.0908 0.6894 -0.7187 +vn 0.0122 0.2070 -0.9783 +vn 0.1215 -0.4017 -0.9077 +vn 0.2869 0.6972 -0.6570 +vn 0.2912 0.2127 -0.9327 +vn 0.1896 -0.4003 -0.8966 +vn 0.6252 0.5825 -0.5195 +vn 0.5412 0.1280 -0.8311 +vn 0.2507 -0.4210 -0.8718 +vn 0.8726 0.3628 -0.3271 +vn 0.7240 -0.0343 -0.6889 +vn 0.7240 -0.0344 -0.6890 +vn 0.2953 -0.4606 -0.8370 +vn 0.9915 0.0714 -0.1091 +vn 0.8119 -0.2496 -0.5278 +vn 0.8118 -0.2496 -0.5278 +vn 0.3167 -0.5132 -0.7977 +vn 0.9637 -0.2471 0.1014 +vn 0.7913 -0.4850 -0.3723 +vn 0.3117 -0.5706 -0.7597 +vn 0.7935 -0.5444 0.2722 +vn 0.6655 -0.7046 -0.2461 +vn 0.2810 -0.6242 -0.7289 +vn 0.5067 -0.7751 0.3774 +vn 0.4537 -0.8751 -0.1684 +vn 0.2293 -0.6659 -0.7100 +vn 0.1472 -0.9042 0.4009 +vn 0.1880 -0.9705 -0.1509 +vn 0.1880 -0.9705 -0.1510 +vn 0.1644 -0.6892 -0.7057 +vn 0.1471 -0.9042 0.4009 +vn -0.2306 -0.9120 0.3392 +vn -0.0911 -0.9763 -0.1966 +vn -0.0911 -0.9762 -0.1966 +vn 0.0963 -0.6906 -0.7168 +vn -0.8532 -0.2395 0.4633 +vn -0.6190 -0.4475 0.6454 +vn -0.9394 0.3378 0.0577 +vn -0.5069 0.8376 -0.2035 +vn -0.1665 0.9598 -0.2258 +vn 0.5112 0.8586 -0.0373 +vn 0.8580 0.3748 0.3512 +vn 0.8317 0.0734 0.5504 +vn 0.3991 -0.4264 0.8117 +vn 0.7280 0.6628 0.1756 +vn 0.8128 0.0945 0.5748 +vn 0.6542 -0.1824 0.7340 +vn 0.3870 -0.3975 0.8320 +vn 0.0520 -0.5177 0.8540 +vn -0.3000 -0.5250 0.7965 +vn -0.6152 -0.4181 0.6684 +vn -0.8458 -0.2134 0.4891 +vn -0.9565 0.0581 0.2859 +vn -0.9306 0.3549 0.0899 +vn -0.7720 0.6318 -0.0693 +vn -0.5048 0.8469 -0.1673 +vn -0.1697 0.9671 -0.1893 +vn 0.1822 0.9744 -0.1319 +vn -0.8608 -0.4793 0.1715 +vn -0.9819 -0.1823 -0.0507 +vn 0.1213 -0.8121 0.5707 +vn 0.1255 0.9702 0.2074 +vn 0.5980 0.7231 -0.3458 +vn 0.5821 0.7363 -0.3450 +vn -0.0198 0.9996 0.0186 +vn 0.6987 0.0421 -0.7142 +vn 0.8538 0.0426 -0.5189 +vn 0.9656 0.1048 -0.2379 +vn 0.5676 0.7350 -0.3709 +vn -0.1381 0.9514 -0.2752 +vn -0.3273 -0.8891 -0.3199 +vn -0.6088 -0.7029 0.3679 +vn -0.6094 -0.7022 0.3683 +vn -0.3264 -0.8891 -0.3210 +vn -0.5344 -0.1036 0.8388 +vn -0.5382 -0.0990 0.8370 +vn -0.5527 -0.0827 0.8293 +vn -0.6111 -0.6999 0.3696 +vn -0.3175 -0.8928 -0.3196 +vn 0.2985 0.9009 0.3151 +vn 0.6059 0.7065 -0.3657 +vn 0.6034 0.7134 -0.3563 +vn 0.2373 0.9264 0.2922 +vn 0.5388 0.0967 -0.8369 +vn 0.5858 0.0756 -0.8069 +vn 0.6077 0.7041 -0.3673 +vn 0.5328 0.1037 -0.8399 +vn 0.3196 0.8923 0.3188 +vn 0.3254 0.8900 0.3195 +vn 0.6084 0.7034 -0.3675 +vn 0.5330 0.1050 -0.8396 +vn -0.3274 -0.8891 -0.3199 +vn -0.3264 -0.8891 -0.3209 +vn 0.1448 -0.5539 -0.8199 +vn 0.1532 -0.5587 -0.8151 +vn 0.5388 0.0967 -0.8368 +vn 0.5327 0.1037 -0.8399 +vn -0.1548 0.5595 0.8143 +vn -0.1798 0.5734 0.7993 +vn -0.5345 -0.1035 0.8388 +vn -0.1479 0.5558 0.8180 +vn 0.3197 0.8923 0.3188 +vn 0.2149 -0.5920 -0.7767 +vn -0.2738 -0.9178 -0.2876 +vn -0.1744 -0.9668 -0.1868 +vn 0.3698 -0.6612 -0.6527 +vn -0.2539 0.6115 0.7494 +vn -0.6007 -0.0419 0.7984 +vn 0.2373 0.9265 0.2922 +vn -0.4009 0.6722 0.6225 +vn -0.7050 0.0105 0.7091 +vn -0.6136 -0.6929 0.3788 +vn -0.2738 -0.9177 -0.2877 +vn -0.6185 -0.6827 0.3890 +vn -0.9733 -0.0136 0.2292 +vn -0.7627 0.6462 -0.0265 +vn -0.7907 0.4998 -0.3535 +vn -0.9917 -0.1283 -0.0054 +vn -0.1381 0.9514 -0.2753 +vn -0.1498 0.8446 -0.5139 +vn -0.1269 0.7780 -0.6153 +vn -0.7670 0.4034 -0.4990 +vn -0.9741 -0.2009 -0.1035 +vn 0.5981 -0.7110 -0.3699 +vn -0.0472 -0.9986 0.0254 +vn 0.5981 -0.7110 -0.3698 +vn -0.0473 -0.9986 0.0254 +vn 0.0542 -0.9483 0.3126 +vn 0.7709 -0.6337 0.0641 +vn -0.6009 0.7110 0.3654 +vn -0.8524 0.0375 0.5216 +vn -0.0197 0.9996 0.0186 +vn -0.1382 0.9514 -0.2752 +vn -0.6008 0.7110 0.3653 +vn -0.6332 -0.6688 0.3897 +vn -0.6478 -0.6697 0.3633 +vn -0.1270 0.7780 -0.6153 +vn 0.6003 0.7071 -0.3737 +vn 0.6014 0.7062 -0.3738 +vn -0.1116 0.7353 -0.6685 +vn 0.9711 0.2176 0.0976 +vn 0.9571 0.2513 0.1443 +vn 0.9407 0.2832 0.1868 +vn 0.6018 0.7051 -0.3751 +vn -0.0934 0.6885 -0.7192 +vn -0.6291 -0.6917 0.3548 +vn 0.1068 -0.8437 0.5261 +vn -0.9917 -0.1282 -0.0054 +vn -0.9741 -0.2009 -0.1036 +vn -0.6164 -0.6995 0.3617 +vn 0.1092 -0.7784 0.6182 +vn 0.5875 0.7143 -0.3802 +vn -0.1498 0.8446 -0.5140 +vn 0.9852 0.1713 -0.0045 +vn 0.7881 -0.4819 0.3831 +vn 0.7645 -0.3959 0.5088 +vn 0.9711 0.2176 0.0975 +vn 0.9407 0.2833 0.1868 +vn 0.7224 -0.2994 0.6233 +vn 0.6795 -0.2227 0.6990 +vn 0.9086 0.3416 0.2405 +vn 0.0851 -0.7055 0.7036 +vn 0.0508 -0.6496 0.7586 +vn -0.0375 -0.5467 0.8365 +vn 0.5740 -0.0702 0.8158 +vn 0.8325 0.4586 0.3109 +vn 0.7450 -0.3468 0.5698 +vn 0.9571 0.2513 0.1442 +vn 0.0976 -0.7419 0.6634 +vn -0.7432 0.3430 -0.5745 +vn -0.9574 -0.2420 -0.1575 +vn -0.1116 0.7354 -0.6684 +vn -0.7112 0.2780 -0.6457 +vn -0.9353 -0.2843 -0.2107 +vn -0.6160 -0.7000 0.3613 +vn -0.9574 -0.2421 -0.1575 +vn -0.6153 -0.7013 0.3600 +vn -0.8157 -0.4506 -0.3628 +vn -0.5439 0.0324 -0.8385 +vn -0.3797 -0.1487 -0.9131 +vn -0.6956 -0.5872 -0.4139 +vn 0.0118 0.5057 -0.8626 +vn 0.1370 0.3750 -0.9169 +vn 0.2599 0.2727 -0.9263 +vn -0.2201 -0.2956 -0.9296 +vn -0.5804 -0.6984 -0.4187 +vn -0.6563 0.1856 -0.7314 +vn -0.8968 -0.3433 -0.2791 +vn -0.0636 0.6195 -0.7824 +vn -0.6205 -0.6997 0.3541 +vn -0.8157 -0.4505 -0.3628 +vn -0.6274 -0.6995 0.3422 +vn 0.5965 0.7065 -0.3810 +vn 0.9086 0.3416 0.2404 +vn 0.5892 0.7062 -0.3926 +vn 0.6023 0.6976 -0.3881 +vn 0.6063 0.6973 -0.3823 +vn 0.3566 0.2038 -0.9118 +vn 0.5920 0.7076 0.3858 +vn 0.4988 0.7806 0.3766 +vn 0.4261 0.8321 0.3551 +vn 0.6083 0.6970 -0.3796 +vn 0.4319 0.1545 -0.8886 +vn -0.6214 -0.7056 0.3406 +vn -0.1621 -0.4124 0.8965 +vn -0.6146 -0.7085 0.3467 +vn -0.2796 -0.2994 0.9122 +vn 0.5951 0.7003 -0.3943 +vn 0.7120 0.5977 0.3685 +vn 0.3992 0.1291 0.9077 +vn 0.7120 0.5977 0.3684 +vn 0.3991 0.1291 0.9078 +vn 0.2255 0.2912 0.9297 +vn -0.4178 -0.8274 -0.3753 +vn 0.0099 -0.4699 -0.8827 +vn 0.0916 -0.5224 -0.8478 +vn -0.3607 -0.8656 -0.3472 +vn 0.4319 0.1546 -0.8886 +vn 0.4920 0.1197 -0.8623 +vn 0.5186 0.1083 -0.8482 +vn 0.1266 -0.5431 -0.8301 +vn -0.3377 -0.8812 -0.3309 +vn 0.0920 0.3975 0.9130 +vn 0.4987 0.7806 0.3766 +vn -0.3703 -0.2236 0.9016 +vn -0.4428 -0.1720 0.8800 +vn -0.0122 0.4713 0.8819 +vn -0.0922 -0.3974 -0.9130 +vn -0.4899 -0.7744 -0.4004 +vn -0.6106 -0.7089 0.3529 +vn -0.4899 -0.7743 -0.4005 +vn -0.6087 -0.7092 0.3557 +vn -0.6078 -0.7083 0.3590 +vn -0.5019 -0.1324 0.8547 +vn -0.6087 -0.7051 0.3637 +vn -0.5259 -0.1115 0.8432 +vn 0.6094 0.6977 -0.3766 +vn 0.4921 0.1197 -0.8623 +vn 0.3656 0.8700 0.3307 +vn 0.3363 0.8848 0.3224 +vn 0.6085 0.7012 -0.3715 +vn 0.5186 0.1083 -0.8481 +vn -0.0983 0.5262 0.8447 +vn -0.1354 0.5483 0.8253 +vn 0.3364 0.8848 0.3224 +vn 0.2200 -0.5101 -0.8315 +vn 0.1980 -0.4905 -0.8487 +vn 0.2306 -0.5361 -0.8120 +vn 0.2282 -0.5645 -0.7933 +vn 0.2130 -0.5910 -0.7780 +vn 0.1874 -0.6116 -0.7687 +vn 0.1553 -0.6231 -0.7666 +vn 0.1216 -0.6238 -0.7721 +vn 0.0914 -0.6136 -0.7843 +vn 0.0694 -0.5940 -0.8015 +vn 0.0588 -0.5680 -0.8209 +vn 0.0613 -0.5396 -0.8397 +vn 0.0764 -0.5131 -0.8549 +vn 0.1020 -0.4925 -0.8643 +vn 0.1341 -0.4810 -0.8664 +vn 0.1678 -0.4803 -0.8609 +vn 0.1213 -0.8122 0.5707 +usemtl Scene_-_Root +s off +f 24101/23865/16823 24102/23866/16823 24103/23867/16823 +f 24101/23865/16824 24103/23867/16824 24104/23868/16824 +f 24109/23869/16825 24110/23870/16825 24111/23871/16825 +f 24109/23869/16826 24111/23871/16826 24112/23872/16826 +f 24160/23873/16824 24161/23874/16824 24162/23875/16824 +f 24160/23873/16824 24162/23875/16824 24163/23876/16824 +f 24164/23877/16826 24165/23878/16826 24166/23879/16826 +f 24164/23877/16825 24166/23879/16825 24167/23880/16825 +f 24168/23881/16825 24169/23882/16825 24170/23883/16825 +f 24168/23881/16825 24170/23883/16825 24171/23884/16825 +f 24172/23885/16827 24173/23886/16827 24101/23865/16827 +f 24172/23885/16823 24101/23865/16823 24174/23887/16823 +f 24175/23888/16823 24176/23889/16823 24177/23890/16823 +f 24175/23888/16823 24177/23890/16823 24178/23891/16823 +f 24179/23892/16824 24180/23893/16824 24181/23894/16824 +f 24179/23892/16823 24181/23894/16823 24182/23895/16823 +f 24183/23896/16825 24184/23897/16825 24185/23898/16825 +f 24183/23896/16825 24185/23898/16825 24186/23899/16825 +f 24187/23900/16825 24188/23901/16825 24189/23902/16825 +f 24187/23900/16826 24189/23902/16826 24190/23903/16826 +f 24191/23904/16827 24172/23885/16827 24174/23887/16827 +f 24191/23904/16823 24174/23887/16823 24192/23905/16823 +f 24161/23874/16823 24193/23906/16823 24194/23907/16823 +f 24161/23874/16824 24194/23907/16824 24162/23875/16824 +f 24195/23908/16825 24164/23877/16825 24167/23880/16825 +f 24195/23908/16828 24167/23880/16828 24196/23909/16828 +f 24197/23910/16825 24168/23881/16825 24171/23884/16825 +f 24197/23910/16825 24171/23884/16825 24198/23911/16825 +f 24184/23897/16825 24199/23912/16825 24200/23913/16825 +f 24184/23897/16825 24200/23913/16825 24185/23898/16825 +f 24176/23889/16823 24201/23914/16823 24202/23915/16823 +f 24176/23889/16823 24202/23915/16823 24177/23890/16823 +f 24180/23893/16823 24191/23904/16823 24192/23905/16823 +f 24180/23893/16824 24192/23905/16824 24181/23894/16824 +f 24203/23916/16829 24187/23900/16829 24190/23903/16829 +f 24203/23916/16825 24190/23903/16825 24204/23917/16825 +f 24196/23909/16825 24167/23880/16825 24205/23918/16825 +f 24196/23909/16825 24205/23918/16825 24206/23919/16825 +f 24181/23894/16823 24192/23905/16823 24207/23920/16823 +f 24181/23894/16823 24207/23920/16823 24208/23921/16823 +f 24186/23899/16826 24185/23898/16826 24209/23922/16826 +f 24186/23899/16825 24209/23922/16825 24210/23923/16825 +f 24182/23895/16823 24181/23894/16823 24208/23921/16823 +f 24182/23895/16823 24208/23921/16823 24211/23924/16823 +f 24212/23925/16825 24204/23917/16825 24213/23926/16825 +f 24212/23925/16825 24213/23926/16825 24214/23927/16825 +f 24167/23880/16825 24166/23879/16825 24215/23928/16825 +f 24167/23880/16825 24215/23928/16825 24205/23918/16825 +f 24216/23929/16823 24182/23895/16823 24211/23924/16823 +f 24216/23929/16823 24211/23924/16823 24217/23930/16823 +f 24218/23931/16823 24216/23929/16823 24217/23930/16823 +f 24218/23931/16823 24217/23930/16823 24219/23932/16823 +f 24204/23917/16825 24190/23903/16825 24220/23933/16825 +f 24204/23917/16830 24220/23933/16830 24213/23926/16830 +f 24166/23879/16825 24221/23934/16825 24222/23935/16825 +f 24166/23879/16825 24222/23935/16825 24215/23928/16825 +f 24194/23907/16831 24218/23931/16831 24219/23932/16831 +f 24194/23907/16827 24219/23932/16827 24223/23936/16827 +f 24162/23875/16823 24194/23907/16823 24223/23936/16823 +f 24162/23875/16824 24223/23936/16824 24224/23937/16824 +f 24190/23903/16830 24189/23902/16830 24225/23938/16830 +f 24190/23903/16825 24225/23938/16825 24220/23933/16825 +f 24221/23934/16825 24186/23899/16825 24210/23923/16825 +f 24221/23934/16825 24210/23923/16825 24222/23935/16825 +f 24163/23876/16824 24162/23875/16824 24224/23937/16824 +f 24163/23876/16823 24224/23937/16823 24226/23939/16823 +f 24188/23901/16826 24227/23940/16826 24228/23941/16826 +f 24188/23901/16825 24228/23941/16825 24189/23902/16825 +f 24229/23942/16823 24179/23892/16823 24182/23895/16823 +f 24229/23942/16823 24182/23895/16823 24216/23929/16823 +f 24230/23943/16823 24175/23888/16823 24178/23891/16823 +f 24230/23943/16823 24178/23891/16823 24231/23944/16823 +f 24169/23882/16825 24232/23945/16825 24212/23925/16825 +f 24169/23882/16825 24212/23925/16825 24170/23883/16825 +f 24165/23878/16829 24233/23946/16829 24221/23934/16829 +f 24165/23878/16829 24221/23934/16829 24166/23879/16829 +f 24234/23947/16824 24160/23873/16824 24163/23876/16824 +f 24234/23947/16827 24163/23876/16827 24235/23948/16827 +f 24227/23940/16830 24236/23949/16830 24237/23950/16830 +f 24227/23940/16825 24237/23950/16825 24228/23941/16825 +f 24238/23951/16823 24229/23942/16823 24216/23929/16823 +f 24238/23951/16832 24216/23929/16832 24218/23931/16832 +f 24239/23952/16823 24230/23943/16823 24231/23944/16823 +f 24239/23952/16823 24231/23944/16823 24102/23866/16823 +f 24232/23945/16825 24203/23916/16825 24204/23917/16825 +f 24232/23945/16825 24204/23917/16825 24212/23925/16825 +f 24233/23946/16826 24183/23896/16826 24186/23899/16826 +f 24233/23946/16829 24186/23899/16829 24221/23934/16829 +f 24201/23914/16823 24234/23947/16823 24235/23948/16823 +f 24201/23914/16823 24235/23948/16823 24202/23915/16823 +f 24199/23912/16825 24197/23910/16825 24198/23911/16825 +f 24199/23912/16825 24198/23911/16825 24200/23913/16825 +f 24236/23949/16833 24195/23908/16833 24196/23909/16833 +f 24236/23949/16830 24196/23909/16830 24237/23950/16830 +f 24193/23906/16834 24238/23951/16834 24218/23931/16834 +f 24193/23906/16823 24218/23931/16823 24194/23907/16823 +f 24173/23886/16823 24239/23952/16823 24102/23866/16823 +f 24173/23886/16834 24102/23866/16834 24101/23865/16834 +f 24170/23883/16825 24212/23925/16825 24214/23927/16825 +f 24170/23883/16825 24214/23927/16825 24280/23953/16825 +f 24102/23866/16834 24231/23944/16834 24281/23954/16834 +f 24102/23866/16823 24281/23954/16823 24103/23867/16823 +f 24192/23905/16824 24174/23887/16824 24282/23955/16824 +f 24192/23905/16823 24282/23955/16823 24207/23920/16823 +f 24237/23950/16825 24196/23909/16825 24206/23919/16825 +f 24237/23950/16830 24206/23919/16830 24283/23956/16830 +f 24231/23944/16827 24178/23891/16827 24284/23957/16827 +f 24231/23944/16832 24284/23957/16832 24281/23954/16832 +f 24171/23884/16825 24170/23883/16825 24280/23953/16825 +f 24171/23884/16825 24280/23953/16825 24285/23958/16825 +f 24174/23887/16824 24101/23865/16824 24104/23868/16824 +f 24174/23887/16823 24104/23868/16823 24282/23955/16823 +f 24178/23891/16824 24177/23890/16824 24286/23959/16824 +f 24178/23891/16832 24286/23959/16832 24284/23957/16832 +f 24185/23898/16825 24200/23913/16825 24287/23960/16825 +f 24185/23898/16826 24287/23960/16826 24209/23922/16826 +f 24228/23941/16830 24237/23950/16830 24283/23956/16830 +f 24228/23941/16825 24283/23956/16825 24288/23961/16825 +f 24177/23890/16824 24202/23915/16824 24289/23962/16824 +f 24177/23890/16824 24289/23962/16824 24286/23959/16824 +f 24198/23911/16825 24171/23884/16825 24285/23958/16825 +f 24198/23911/16825 24285/23958/16825 24290/23963/16825 +f 24202/23915/16824 24235/23948/16824 24291/23964/16824 +f 24202/23915/16824 24291/23964/16824 24289/23962/16824 +f 24189/23902/16825 24228/23941/16825 24288/23961/16825 +f 24189/23902/16825 24288/23961/16825 24225/23938/16825 +f 24235/23948/16823 24163/23876/16823 24226/23939/16823 +f 24235/23948/16824 24226/23939/16824 24291/23964/16824 +f 24200/23913/16830 24198/23911/16830 24290/23963/16830 +f 24200/23913/16825 24290/23963/16825 24287/23960/16825 +f 24325/23965/16827 24326/23966/16827 24327/23967/16827 +f 24325/23965/16835 24327/23967/16835 24328/23968/16835 +f 24329/23969/16824 24330/23970/16824 24331/23971/16824 +f 24329/23969/16827 24331/23971/16827 24332/23972/16827 +f 24333/23973/16825 24334/23974/16825 24335/23975/16825 +f 24333/23973/16826 24335/23975/16826 24336/23976/16826 +f 24337/23977/16825 24338/23978/16825 24339/23979/16825 +f 24337/23977/16826 24339/23979/16826 24340/23980/16826 +f 24326/23966/16824 24341/23981/16824 24342/23982/16824 +f 24326/23966/16827 24342/23982/16827 24327/23967/16827 +f 24341/23981/16823 24343/23983/16823 24344/23984/16823 +f 24341/23981/16824 24344/23984/16824 24342/23982/16824 +f 24345/23985/16823 24346/23986/16823 24347/23987/16823 +f 24345/23985/16827 24347/23987/16827 24348/23988/16827 +f 24349/23989/16825 24350/23990/16825 24351/23991/16825 +f 24349/23989/16825 24351/23991/16825 24352/23992/16825 +f 24353/23993/16830 24354/23994/16830 24355/23995/16830 +f 24353/23993/16825 24355/23995/16825 24356/23996/16825 +f 24330/23970/16823 24357/23997/16823 24358/23998/16823 +f 24330/23970/16823 24358/23998/16823 24331/23971/16823 +f 24354/23994/16825 24333/23973/16825 24336/23976/16825 +f 24354/23994/16830 24336/23976/16830 24355/23995/16830 +f 24359/23999/16829 24337/23977/16829 24340/23980/16829 +f 24359/23999/16825 24340/23980/16825 24110/23870/16825 +f 24360/24000/16823 24361/24001/16823 24362/24002/16823 +f 24360/24000/16823 24362/24002/16823 24363/24003/16823 +f 24346/23986/16823 24364/24004/16823 24365/24005/16823 +f 24346/23986/16823 24365/24005/16823 24347/23987/16823 +f 24366/24006/16825 24349/23989/16825 24352/23992/16825 +f 24366/24006/16825 24352/23992/16825 24367/24007/16825 +f 24357/23997/16824 24368/24008/16824 24369/24009/16824 +f 24357/23997/16823 24369/24009/16823 24358/23998/16823 +f 24358/23998/16823 24369/24009/16823 24370/24010/16823 +f 24358/23998/16824 24370/24010/16824 24371/24011/16824 +f 24110/23870/16825 24340/23980/16825 24372/24012/16825 +f 24110/23870/16825 24372/24012/16825 24111/23871/16825 +f 24373/24013/16823 24328/23968/16823 24374/24014/16823 +f 24373/24013/16824 24374/24014/16824 24375/24015/16824 +f 24340/23980/16825 24339/23979/16825 24376/24016/16825 +f 24340/23980/16825 24376/24016/16825 24372/24012/16825 +f 24331/23971/16824 24358/23998/16824 24371/24011/16824 +f 24331/23971/16824 24371/24011/16824 24377/24017/16824 +f 24339/23979/16825 24378/24018/16825 24379/24019/16825 +f 24339/23979/16825 24379/24019/16825 24376/24016/16825 +f 24332/23972/16824 24331/23971/16824 24377/24017/16824 +f 24332/23972/16823 24377/24017/16823 24380/24020/16823 +f 24365/24005/16823 24373/24013/16823 24375/24015/16823 +f 24365/24005/16824 24375/24015/16824 24381/24021/16824 +f 24378/24018/16830 24367/24007/16830 24382/24022/16830 +f 24378/24018/16825 24382/24022/16825 24379/24019/16825 +f 24367/24007/16830 24352/23992/16830 24383/24023/16830 +f 24367/24007/16830 24383/24023/16830 24382/24022/16830 +f 24336/23976/16825 24335/23975/16825 24384/24024/16825 +f 24336/23976/16830 24384/24024/16830 24385/24025/16830 +f 24347/23987/16827 24365/24005/16827 24381/24021/16827 +f 24347/23987/16823 24381/24021/16823 24386/24026/16823 +f 24351/23991/16825 24387/24027/16825 24388/24028/16825 +f 24351/23991/16825 24388/24028/16825 24389/24029/16825 +f 24390/24030/16823 24332/23972/16823 24380/24020/16823 +f 24390/24030/16823 24380/24020/16823 24391/24031/16823 +f 24387/24027/16825 24392/24032/16825 24393/24033/16825 +f 24387/24027/16825 24393/24033/16825 24388/24028/16825 +f 24334/23974/16825 24394/24034/16825 24395/24035/16825 +f 24334/23974/16825 24395/24035/16825 24335/23975/16825 +f 24350/23990/16836 24396/24036/16836 24387/24027/16836 +f 24350/23990/16830 24387/24027/16830 24351/23991/16830 +f 24397/24037/16827 24345/23985/16827 24348/23988/16827 +f 24397/24037/16823 24348/23988/16823 24398/24038/16823 +f 24399/24039/16826 24353/23993/16826 24356/23996/16826 +f 24399/24039/16830 24356/23996/16830 24400/24040/16830 +f 24338/23978/16830 24401/24041/16830 24378/24018/16830 +f 24338/23978/16825 24378/24018/16825 24339/23979/16825 +f 24343/23983/16824 24360/24000/16824 24363/24003/16824 +f 24343/23983/16834 24363/24003/16834 24344/23984/16834 +f 24402/24042/16823 24325/23965/16823 24328/23968/16823 +f 24402/24042/16823 24328/23968/16823 24373/24013/16823 +f 24403/24043/16824 24329/23969/16824 24332/23972/16824 +f 24403/24043/16832 24332/23972/16832 24390/24030/16832 +f 24394/24034/16825 24404/24044/16825 24109/23869/16825 +f 24394/24034/16825 24109/23869/16825 24395/24035/16825 +f 24396/24036/16825 24405/24045/16825 24392/24032/16825 +f 24396/24036/16829 24392/24032/16829 24387/24027/16829 +f 24368/24008/16823 24397/24037/16823 24398/24038/16823 +f 24368/24008/16824 24398/24038/16824 24369/24009/16824 +f 24401/24041/16825 24366/24006/16825 24367/24007/16825 +f 24401/24041/16825 24367/24007/16825 24378/24018/16825 +f 24364/24004/16823 24402/24042/16823 24373/24013/16823 +f 24364/24004/16823 24373/24013/16823 24365/24005/16823 +f 24361/24001/16834 24403/24043/16834 24390/24030/16834 +f 24361/24001/16837 24390/24030/16837 24362/24002/16837 +f 24404/24044/16825 24359/23999/16825 24110/23870/16825 +f 24404/24044/16825 24110/23870/16825 24109/23869/16825 +f 24405/24045/16825 24399/24039/16825 24400/24040/16825 +f 24405/24045/16825 24400/24040/16825 24392/24032/16825 +f 24395/24035/16830 24109/23869/16830 24112/23872/16830 +f 24395/24035/16825 24112/23872/16825 24446/24046/16825 +f 24344/23984/16823 24363/24003/16823 24447/24047/16823 +f 24344/23984/16823 24447/24047/16823 24448/24048/16823 +f 24369/24009/16823 24398/24038/16823 24449/24049/16823 +f 24369/24009/16823 24449/24049/16823 24370/24010/16823 +f 24335/23975/16825 24395/24035/16825 24446/24046/16825 +f 24335/23975/16825 24446/24046/16825 24384/24024/16825 +f 24342/23982/16823 24344/23984/16823 24448/24048/16823 +f 24342/23982/16823 24448/24048/16823 24450/24050/16823 +f 24355/23995/16830 24336/23976/16830 24385/24025/16830 +f 24355/23995/16825 24385/24025/16825 24451/24051/16825 +f 24398/24038/16823 24348/23988/16823 24452/24052/16823 +f 24398/24038/16823 24452/24052/16823 24449/24049/16823 +f 24400/24040/16825 24356/23996/16825 24453/24053/16825 +f 24400/24040/16826 24453/24053/16826 24454/24054/16826 +f 24363/24003/16823 24362/24002/16823 24455/24055/16823 +f 24363/24003/16827 24455/24055/16827 24447/24047/16827 +f 24352/23992/16825 24351/23991/16825 24389/24029/16825 +f 24352/23992/16830 24389/24029/16830 24383/24023/16830 +f 24327/23967/16823 24342/23982/16823 24450/24050/16823 +f 24327/23967/16824 24450/24050/16824 24456/24056/16824 +f 24356/23996/16825 24355/23995/16825 24451/24051/16825 +f 24356/23996/16825 24451/24051/16825 24453/24053/16825 +f 24392/24032/16826 24400/24040/16826 24454/24054/16826 +f 24392/24032/16825 24454/24054/16825 24393/24033/16825 +f 24362/24002/16823 24390/24030/16823 24391/24031/16823 +f 24362/24002/16823 24391/24031/16823 24455/24055/16823 +f 24348/23988/16823 24347/23987/16823 24386/24026/16823 +f 24348/23988/16823 24386/24026/16823 24452/24052/16823 +f 24328/23968/16824 24327/23967/16824 24456/24056/16824 +f 24328/23968/16823 24456/24056/16823 24374/24014/16823 +f 24758/24057/16825 24756/24058/16825 24757/24059/16825 +f 24756/24058/16825 24758/24057/16825 24759/24060/16825 +f 24756/24058/16825 24759/24060/16825 24755/24061/16825 +f 24755/24061/16825 24759/24060/16825 24760/24062/16825 +f 24755/24061/16825 24760/24062/16825 24754/24063/16825 +f 24754/24063/16825 24760/24062/16825 24761/24064/16825 +f 24754/24063/16825 24761/24064/16825 24753/24065/16825 +f 24753/24065/16825 24761/24064/16825 24752/24066/16825 +f 24752/24066/16825 24761/24064/16825 24762/24067/16825 +f 24752/24066/16825 24762/24067/16825 24767/24068/16825 +f 24767/24068/16825 24762/24067/16825 24763/24069/16825 +f 24767/24068/16825 24763/24069/16825 24764/24070/16825 +f 24767/24068/16825 24764/24070/16825 24766/24071/16825 +f 24766/24071/16825 24764/24070/16825 24765/24072/16825 +f 24781/24073/16823 24779/24074/16823 24780/24075/16823 +f 24779/24074/16823 24781/24073/16823 24782/24076/16823 +f 24779/24074/16823 24782/24076/16823 24778/24077/16823 +f 24778/24077/16823 24782/24076/16823 24783/24078/16823 +f 24778/24077/16823 24783/24078/16823 24777/24079/16823 +f 24777/24079/16823 24783/24078/16823 24776/24080/16823 +f 24776/24080/16823 24783/24078/16823 24768/24081/16823 +f 24776/24080/16823 24768/24081/16823 24769/24082/16823 +f 24776/24080/16823 24769/24082/16823 24775/24083/16823 +f 24775/24083/16823 24769/24082/16823 24770/24084/16823 +f 24775/24083/16823 24770/24084/16823 24774/24085/16823 +f 24774/24085/16823 24770/24084/16823 24771/24086/16823 +f 24774/24085/16823 24771/24086/16823 24773/24087/16823 +f 24773/24087/16823 24771/24086/16823 24772/24088/16823 +s 1 +f 23865/24089/16838 23866/24090/16839 23867/24091/16840 +f 23865/24089/16838 23867/24091/16840 23868/24092/16841 +f 23868/24092/16841 23867/24091/16840 23869/24093/16842 +f 23868/24092/16841 23869/24093/16842 23870/24094/16843 +f 23870/24094/16843 23869/24093/16842 23871/24095/16844 +f 23870/24094/16843 23871/24095/16844 23872/24096/16845 +f 23872/24096/16845 23871/24095/16844 23873/24097/16846 +f 23872/24096/16845 23873/24097/16846 23874/24098/16847 +f 23875/24099/16848 23876/24100/16846 23877/24101/16849 +f 23875/24099/16848 23877/24101/16849 23878/24102/16850 +f 23878/24102/16850 23877/24101/16849 23879/24103/16851 +f 23878/24102/16850 23879/24103/16851 23880/24104/16852 +f 23880/24104/16852 23879/24103/16851 23881/24105/16853 +f 23880/24104/16852 23881/24105/16853 23882/24106/16854 +f 23882/24106/16854 23881/24105/16853 23883/24107/16855 +f 23882/24106/16854 23883/24107/16855 23884/24108/16856 +f 23885/24109/16856 23886/24110/16855 23887/24111/16857 +f 23885/24109/16856 23887/24111/16857 23888/24112/16858 +f 23888/24112/16858 23887/24111/16857 23889/24113/16859 +f 23888/24112/16858 23889/24113/16859 23890/24114/16860 +f 23890/24114/16860 23889/24113/16859 23891/24115/16861 +f 23890/24114/16860 23891/24115/16861 23892/24116/16862 +f 23892/24116/16862 23891/24115/16861 23893/24117/16863 +f 23892/24116/16862 23893/24117/16863 23894/24118/16864 +f 23895/24119/16864 23896/24120/16863 23897/24121/16865 +f 23895/24119/16864 23897/24121/16865 23898/24122/16866 +f 23899/24123/16867 23900/24124/16868 23901/24125/16856 +f 23899/24123/16867 23901/24125/16856 23902/24126/16858 +f 23898/24122/16866 23897/24121/16865 23903/24127/16869 +f 23898/24122/16866 23903/24127/16869 23904/24128/16870 +f 23905/24129/16871 23906/24130/16872 23907/24131/16839 +f 23905/24129/16871 23907/24131/16839 23908/24132/16838 +f 23909/24133/16873 23910/24134/16874 23911/24135/16850 +f 23909/24133/16873 23911/24135/16850 23912/24136/16852 +f 23913/24137/16868 23914/24138/16875 23915/24139/16854 +f 23913/24137/16868 23915/24139/16854 23916/24140/16856 +f 23917/24141/16876 23899/24123/16867 23902/24126/16858 +f 23917/24141/16876 23902/24126/16858 23918/24142/16860 +f 23919/24143/16877 23917/24141/16876 23918/24142/16860 +f 23919/24143/16877 23918/24142/16860 23920/24144/16862 +f 23921/24145/16878 23919/24143/16877 23920/24144/16862 +f 23921/24145/16878 23920/24144/16862 23922/24146/16864 +f 23923/24147/16879 23924/24148/16878 23925/24149/16864 +f 23923/24147/16879 23925/24149/16864 23926/24150/16866 +f 23927/24151/16880 23923/24147/16879 23926/24150/16866 +f 23927/24151/16880 23926/24150/16866 23928/24152/16870 +f 23929/24153/16881 23927/24151/16880 23928/24152/16870 +f 23929/24153/16881 23928/24152/16870 23930/24154/16871 +f 23931/24155/16882 23929/24153/16881 23930/24154/16871 +f 23931/24155/16882 23930/24154/16871 23932/24156/16838 +f 23933/24157/16883 23934/24158/16882 23935/24159/16838 +f 23933/24157/16883 23935/24159/16838 23936/24160/16841 +f 23937/24161/16884 23933/24157/16883 23936/24160/16841 +f 23937/24161/16884 23936/24160/16841 23938/24162/16843 +f 23939/24163/16885 23937/24161/16884 23938/24162/16843 +f 23939/24163/16885 23938/24162/16843 23940/24164/16845 +f 23941/24165/16886 23939/24163/16885 23940/24164/16845 +f 23941/24165/16886 23940/24164/16845 23942/24166/16847 +f 23910/24134/16874 23943/24167/16886 23944/24168/16847 +f 23910/24134/16874 23944/24168/16847 23911/24135/16850 +f 23904/24128/16870 23903/24127/16869 23906/24130/16872 +f 23904/24128/16870 23906/24130/16872 23905/24129/16871 +f 23945/24169/16887 23946/24170/16888 23947/24171/16889 +f 23945/24169/16887 23947/24171/16889 23948/24172/16890 +f 23949/24173/16891 23950/24174/16892 23951/24175/16893 +f 23949/24173/16891 23951/24175/16893 23952/24176/16894 +f 23946/24170/16888 23953/24177/16895 23954/24178/16896 +f 23946/24170/16888 23954/24178/16896 23947/24171/16889 +f 23950/24174/16892 23955/24179/16897 23956/24180/16898 +f 23950/24174/16892 23956/24180/16898 23951/24175/16893 +f 23953/24177/16895 23957/24181/16899 23958/24182/16900 +f 23953/24177/16895 23958/24182/16900 23954/24178/16896 +f 23955/24179/16897 23959/24183/16901 23960/24184/16902 +f 23955/24179/16897 23960/24184/16902 23956/24180/16898 +f 23957/24181/16899 23961/24185/16903 23962/24186/16904 +f 23957/24181/16899 23962/24186/16904 23958/24182/16900 +f 23959/24183/16901 23963/24187/16905 23964/24188/16906 +f 23959/24183/16901 23964/24188/16906 23960/24184/16902 +f 23961/24185/16903 23965/24189/16907 23966/24190/16908 +f 23961/24185/16903 23966/24190/16908 23962/24186/16904 +f 23963/24187/16905 23967/24191/16909 23968/24192/16910 +f 23963/24187/16905 23968/24192/16910 23964/24188/16906 +f 23965/24189/16907 23969/24193/16911 23970/24194/16912 +f 23965/24189/16907 23970/24194/16912 23966/24190/16908 +f 23967/24191/16909 23971/24195/16913 23972/24196/16914 +f 23967/24191/16909 23972/24196/16914 23968/24192/16910 +f 23969/24193/16911 23973/24197/16915 23974/24198/16916 +f 23969/24193/16911 23974/24198/16916 23970/24194/16912 +f 23975/24199/16917 23945/24169/16887 23948/24172/16890 +f 23975/24199/16917 23948/24172/16890 23976/24200/16918 +f 23971/24195/16913 23975/24199/16917 23976/24200/16918 +f 23971/24195/16913 23976/24200/16918 23972/24196/16914 +f 23973/24197/16915 23949/24173/16891 23952/24176/16894 +f 23973/24197/16915 23952/24176/16894 23974/24198/16916 +f 23977/24201/16919 23978/24202/16920 23979/24203/16921 +f 23977/24201/16919 23979/24203/16921 23980/24204/16922 +f 23981/24205/16923 23982/24206/16924 23983/24207/16925 +f 23981/24205/16923 23983/24207/16925 23984/24208/16926 +f 23978/24202/16920 23985/24209/16927 23986/24210/16928 +f 23978/24202/16920 23986/24210/16928 23979/24203/16921 +f 23982/24206/16924 23987/24211/16928 23988/24212/16929 +f 23982/24206/16924 23988/24212/16929 23983/24207/16925 +f 23989/24213/16927 23990/24214/16930 23991/24215/16931 +f 23989/24213/16927 23991/24215/16931 23992/24216/16928 +f 23987/24211/16928 23993/24217/16932 23994/24218/16933 +f 23987/24211/16928 23994/24218/16933 23988/24212/16929 +f 23990/24214/16930 23995/24219/16934 23996/24220/16935 +f 23990/24214/16930 23996/24220/16935 23991/24215/16931 +f 23993/24217/16932 23997/24221/16935 23998/24222/16936 +f 23993/24217/16932 23998/24222/16936 23994/24218/16933 +f 23995/24219/16934 23999/24223/16937 24000/24224/16938 +f 23995/24219/16934 24000/24224/16938 23996/24220/16935 +f 23997/24221/16935 24001/24225/16938 24002/24226/16939 +f 23997/24221/16935 24002/24226/16939 23998/24222/16936 +f 23999/24223/16937 24003/24227/16940 24004/24228/16941 +f 23999/24223/16937 24004/24228/16941 24000/24224/16938 +f 24001/24225/16938 24005/24229/16941 24006/24230/16942 +f 24001/24225/16938 24006/24230/16942 24002/24226/16939 +f 24007/24231/16940 24008/24232/16943 24009/24233/16944 +f 24007/24231/16940 24009/24233/16944 24010/24234/16941 +f 24005/24229/16941 24011/24235/16944 24012/24236/16945 +f 24005/24229/16941 24012/24236/16945 24006/24230/16942 +f 24008/24232/16943 24013/24237/16946 24014/24238/16947 +f 24008/24232/16943 24014/24238/16947 24009/24233/16944 +f 24011/24235/16944 24015/24239/16947 24016/24240/16948 +f 24011/24235/16944 24016/24240/16948 24012/24236/16945 +f 24013/24237/16946 24017/24241/16949 24018/24242/16950 +f 24013/24237/16946 24018/24242/16950 24014/24238/16947 +f 24015/24239/16947 24019/24243/16951 24020/24244/16952 +f 24015/24239/16947 24020/24244/16952 24016/24240/16948 +f 24017/24241/16949 24021/24245/16953 24022/24246/16954 +f 24017/24241/16949 24022/24246/16954 24018/24242/16950 +f 24019/24243/16951 24023/24247/16955 24024/24248/16956 +f 24019/24243/16951 24024/24248/16956 24020/24244/16952 +f 24025/24249/16953 24026/24250/16957 24027/24251/16958 +f 24025/24249/16953 24027/24251/16958 24028/24252/16954 +f 24023/24247/16955 24029/24253/16958 24030/24254/16959 +f 24023/24247/16955 24030/24254/16959 24024/24248/16956 +f 24026/24250/16957 24031/24255/16960 24032/24256/16961 +f 24026/24250/16957 24032/24256/16961 24027/24251/16958 +f 24029/24253/16958 24033/24257/16961 24034/24258/16962 +f 24029/24253/16958 24034/24258/16962 24030/24254/16959 +f 24031/24255/16960 24035/24259/16963 24036/24260/16964 +f 24031/24255/16960 24036/24260/16964 24032/24256/16961 +f 24033/24257/16961 24037/24261/16964 24038/24262/16965 +f 24033/24257/16961 24038/24262/16965 24034/24258/16962 +f 24035/24259/16963 24039/24263/16966 24040/24264/16967 +f 24035/24259/16963 24040/24264/16967 24036/24260/16964 +f 24037/24261/16964 24041/24265/16968 24042/24266/16969 +f 24037/24261/16964 24042/24266/16969 24038/24262/16965 +f 24043/24267/16970 24044/24268/16971 24045/24269/16972 +f 24043/24267/16970 24045/24269/16972 24046/24270/16967 +f 24041/24265/16968 24047/24271/16973 24048/24272/16974 +f 24041/24265/16968 24048/24272/16974 24042/24266/16969 +f 24044/24268/16971 23977/24201/16919 23980/24204/16922 +f 24044/24268/16971 23980/24204/16922 24045/24269/16972 +f 24047/24271/16973 23981/24205/16923 23984/24208/16926 +f 24047/24271/16973 23984/24208/16926 24048/24272/16974 +f 24049/24273/16843 24050/24274/16845 24051/24275/16845 +f 24049/24273/16843 24051/24275/16845 24052/24276/16843 +f 24053/24277/16975 24054/24278/16976 23976/24200/16918 +f 24053/24277/16975 23976/24200/16918 23948/24172/16890 +f 24055/24279/16839 24053/24277/16975 23948/24172/16890 +f 24055/24279/16839 23948/24172/16890 23947/24171/16889 +f 24056/24280/16977 24055/24279/16839 23947/24171/16889 +f 24056/24280/16977 23947/24171/16889 23954/24178/16896 +f 24057/24281/16842 24056/24280/16977 23954/24178/16896 +f 24057/24281/16842 23954/24178/16896 23958/24182/16900 +f 24058/24282/16978 24057/24281/16842 23958/24182/16900 +f 24058/24282/16978 23958/24182/16900 23962/24186/16904 +f 24059/24283/16979 24058/24282/16978 23962/24186/16904 +f 24059/24283/16979 23962/24186/16904 23966/24190/16908 +f 24060/24284/16849 24059/24283/16979 23966/24190/16908 +f 24060/24284/16849 23966/24190/16908 23970/24194/16912 +f 24061/24285/16980 24060/24284/16849 23970/24194/16912 +f 24061/24285/16980 23970/24194/16912 23974/24198/16916 +f 24062/24286/16853 24061/24285/16980 23974/24198/16916 +f 24062/24286/16853 23974/24198/16916 23952/24176/16894 +f 24063/24287/16981 24062/24286/16853 23952/24176/16894 +f 24063/24287/16981 23952/24176/16894 23951/24175/16893 +f 24064/24288/16982 24063/24287/16981 23951/24175/16893 +f 24064/24288/16982 23951/24175/16893 23956/24180/16898 +f 24065/24289/16859 24064/24288/16982 23956/24180/16898 +f 24065/24289/16859 23956/24180/16898 23960/24184/16902 +f 24066/24290/16983 24065/24289/16859 23960/24184/16902 +f 24066/24290/16983 23960/24184/16902 23964/24188/16906 +f 24067/24291/16863 24066/24290/16983 23964/24188/16906 +f 24067/24291/16863 23964/24188/16906 23968/24192/16910 +f 24068/24292/16865 24067/24291/16863 23968/24192/16910 +f 24068/24292/16865 23968/24192/16910 23972/24196/16914 +f 24054/24278/16976 24068/24292/16865 23972/24196/16914 +f 24054/24278/16976 23972/24196/16914 23976/24200/16918 +f 23945/24169/16887 23975/24199/16917 24069/24293/16873 +f 23945/24169/16887 24069/24293/16873 24070/24294/16984 +f 23946/24170/16888 23945/24169/16887 24070/24294/16984 +f 23946/24170/16888 24070/24294/16984 24071/24295/16868 +f 23953/24177/16895 23946/24170/16888 24071/24295/16868 +f 23953/24177/16895 24071/24295/16868 24072/24296/16985 +f 23957/24181/16899 23953/24177/16895 24072/24296/16985 +f 23957/24181/16899 24072/24296/16985 24073/24297/16986 +f 23961/24185/16903 23957/24181/16899 24073/24297/16986 +f 23961/24185/16903 24073/24297/16986 24074/24298/16987 +f 23965/24189/16907 23961/24185/16903 24074/24298/16987 +f 23965/24189/16907 24074/24298/16987 24075/24299/16988 +f 23969/24193/16911 23965/24189/16907 24075/24299/16988 +f 23969/24193/16911 24075/24299/16988 24076/24300/16989 +f 23973/24197/16915 23969/24193/16911 24076/24300/16989 +f 23973/24197/16915 24076/24300/16989 24077/24301/16990 +f 23949/24173/16891 23973/24197/16915 24077/24301/16990 +f 23949/24173/16891 24077/24301/16990 24078/24302/16991 +f 23950/24174/16892 23949/24173/16891 24078/24302/16991 +f 23950/24174/16892 24078/24302/16991 24079/24303/16992 +f 23955/24179/16897 23950/24174/16892 24079/24303/16992 +f 23955/24179/16897 24079/24303/16992 24080/24304/16993 +f 23959/24183/16901 23955/24179/16897 24080/24304/16993 +f 23959/24183/16901 24080/24304/16993 24081/24305/16994 +f 23963/24187/16905 23959/24183/16901 24081/24305/16994 +f 23963/24187/16905 24081/24305/16994 24082/24306/16995 +f 23967/24191/16909 23963/24187/16905 24082/24306/16995 +f 23967/24191/16909 24082/24306/16995 24083/24307/16996 +f 23971/24195/16913 23967/24191/16909 24083/24307/16996 +f 23971/24195/16913 24083/24307/16996 24084/24308/16997 +f 23975/24199/16917 23971/24195/16913 24084/24308/16997 +f 23975/24199/16917 24084/24308/16997 24069/24293/16873 +f 23914/24138/16875 23909/24133/16873 23912/24136/16852 +f 23914/24138/16875 23912/24136/16852 23915/24139/16854 +f 23977/24201/16919 24085/24309/16870 24086/24310/16998 +f 23977/24201/16919 24086/24310/16998 23978/24202/16920 +f 24086/24310/16998 24087/24311/16871 24088/24312/16838 +f 24086/24310/16998 24088/24312/16838 24089/24313/16838 +f 23978/24202/16920 24086/24310/16998 24089/24313/16838 +f 23978/24202/16920 24089/24313/16838 23985/24209/16927 +f 24090/24314/16841 24091/24315/16841 24092/24316/16843 +f 24090/24314/16841 24092/24316/16843 24093/24317/16843 +f 24044/24268/16971 24094/24318/16866 24085/24309/16870 +f 24044/24268/16971 24085/24309/16870 23977/24201/16919 +f 24094/24318/16866 24095/24319/16866 24096/24320/16870 +f 24094/24318/16866 24096/24320/16870 24085/24309/16870 +f 24043/24267/16970 24097/24321/16864 24094/24318/16866 +f 24043/24267/16970 24094/24318/16866 24044/24268/16971 +f 24097/24321/16864 24098/24322/16864 24095/24319/16866 +f 24097/24321/16864 24095/24319/16866 24094/24318/16866 +f 24035/24259/16963 24099/24323/16862 24100/24324/16864 +f 24035/24259/16963 24100/24324/16864 24039/24263/16966 +f 24031/24255/16960 24105/24325/16860 24099/24323/16862 +f 24031/24255/16960 24099/24323/16862 24035/24259/16963 +f 24099/24323/16862 24106/24326/16862 24107/24327/16864 +f 24099/24323/16862 24107/24327/16864 24100/24324/16864 +f 24026/24250/16957 24108/24328/16858 24105/24325/16860 +f 24026/24250/16957 24105/24325/16860 24031/24255/16960 +f 24025/24249/16953 24113/24329/16856 24108/24328/16858 +f 24025/24249/16953 24108/24328/16858 24026/24250/16957 +f 24105/24325/16860 24114/24330/16860 24106/24326/16862 +f 24105/24325/16860 24106/24326/16862 24099/24323/16862 +f 24017/24241/16949 24115/24331/16854 24116/24332/16856 +f 24017/24241/16949 24116/24332/16856 24021/24245/16953 +f 24108/24328/16858 24117/24333/16858 24114/24330/16860 +f 24108/24328/16858 24114/24330/16860 24105/24325/16860 +f 24013/24237/16946 24118/24334/16852 24115/24331/16854 +f 24013/24237/16946 24115/24331/16854 24017/24241/16949 +f 24113/24329/16856 24119/24335/16856 24117/24333/16858 +f 24113/24329/16856 24117/24333/16858 24108/24328/16858 +f 24008/24232/16943 24120/24336/16850 24118/24334/16852 +f 24008/24232/16943 24118/24334/16852 24013/24237/16946 +f 24115/24331/16854 24121/24337/16854 24122/24338/16856 +f 24115/24331/16854 24122/24338/16856 24116/24332/16856 +f 24007/24231/16940 24123/24339/16847 24120/24336/16850 +f 24007/24231/16940 24120/24336/16850 24008/24232/16943 +f 24118/24334/16852 24124/24340/16852 24121/24337/16854 +f 24118/24334/16852 24121/24337/16854 24115/24331/16854 +f 23999/24223/16937 24125/24341/16845 24126/24342/16847 +f 23999/24223/16937 24126/24342/16847 24003/24227/16940 +f 24120/24336/16850 24127/24343/16850 24124/24340/16852 +f 24120/24336/16850 24124/24340/16852 24118/24334/16852 +f 23995/24219/16934 24093/24317/16843 24125/24341/16845 +f 23995/24219/16934 24125/24341/16845 23999/24223/16937 +f 24123/24339/16847 24128/24344/16847 24127/24343/16850 +f 24123/24339/16847 24127/24343/16850 24120/24336/16850 +f 23990/24214/16930 24090/24314/16841 24093/24317/16843 +f 23990/24214/16930 24093/24317/16843 23995/24219/16934 +f 24125/24341/16845 24129/24345/16845 24130/24346/16847 +f 24125/24341/16845 24130/24346/16847 24126/24342/16847 +f 23989/24213/16927 24131/24347/16838 24090/24314/16841 +f 23989/24213/16927 24090/24314/16841 23990/24214/16930 +f 24132/24348/16864 23895/24119/16864 23898/24122/16866 +f 24132/24348/16864 23898/24122/16866 24133/24349/16866 +f 24134/24350/16999 23865/24089/16838 23868/24092/16841 +f 24134/24350/16999 23868/24092/16841 24135/24351/16841 +f 24135/24351/16841 23868/24092/16841 23870/24094/16843 +f 24135/24351/16841 23870/24094/16843 24136/24352/16843 +f 24136/24352/16843 23870/24094/16843 23872/24096/16845 +f 24136/24352/16843 23872/24096/16845 24137/24353/16845 +f 24137/24353/16845 23872/24096/16845 23874/24098/16847 +f 24137/24353/16845 23874/24098/16847 24138/24354/16847 +f 24139/24355/16847 23875/24099/16848 23878/24102/16850 +f 24139/24355/16847 23878/24102/16850 24140/24356/16850 +f 24140/24356/16850 23878/24102/16850 23880/24104/16852 +f 24140/24356/16850 23880/24104/16852 24141/24357/16852 +f 24141/24357/16852 23880/24104/16852 23882/24106/16854 +f 24141/24357/16852 23882/24106/16854 24142/24358/16854 +f 24142/24358/16854 23882/24106/16854 23884/24108/16856 +f 24142/24358/16854 23884/24108/16856 24143/24359/16856 +f 24144/24360/16856 23885/24109/16856 23888/24112/16858 +f 24144/24360/16856 23888/24112/16858 24145/24361/16858 +f 24145/24361/16858 23888/24112/16858 23890/24114/16860 +f 24145/24361/16858 23890/24114/16860 24146/24362/16860 +f 24146/24362/16860 23890/24114/16860 23892/24116/16862 +f 24146/24362/16860 23892/24116/16862 24147/24363/16862 +f 24147/24363/16862 23892/24116/16862 23894/24118/16864 +f 24147/24363/16862 23894/24118/16864 24148/24364/16864 +f 24149/24365/16862 24150/24366/16862 24151/24367/16864 +f 24149/24365/16862 24151/24367/16864 24152/24368/16864 +f 24153/24369/16864 24154/24370/16864 24155/24371/16866 +f 24153/24369/16864 24155/24371/16866 24156/24372/16866 +f 24157/24373/16871 23905/24129/16871 23908/24132/16838 +f 24157/24373/16871 23908/24132/16838 24158/24374/16838 +f 24159/24375/16870 23904/24128/16870 23905/24129/16871 +f 24159/24375/16870 23905/24129/16871 24157/24373/16871 +f 24133/24349/16866 23898/24122/16866 23904/24128/16870 +f 24133/24349/16866 23904/24128/16870 24159/24375/16870 +f 24240/24376/16838 24241/24377/16841 24242/24378/16841 +f 24240/24376/16838 24242/24378/16841 24243/24379/16838 +f 24241/24377/16841 24244/24380/16843 24245/24381/16843 +f 24241/24377/16841 24245/24381/16843 24242/24378/16841 +f 24244/24380/16843 24246/24382/16845 24247/24383/16845 +f 24244/24380/16843 24247/24383/16845 24245/24381/16843 +f 24246/24382/16845 24248/24384/16847 24249/24385/16847 +f 24246/24382/16845 24249/24385/16847 24247/24383/16845 +f 24250/24386/16847 24251/24387/16850 24252/24388/16850 +f 24250/24386/16847 24252/24388/16850 24253/24389/16847 +f 24251/24387/16850 24254/24390/16852 24255/24391/16852 +f 24251/24387/16850 24255/24391/16852 24252/24388/16850 +f 24254/24390/16852 24256/24392/16854 24257/24393/16854 +f 24254/24390/16852 24257/24393/16854 24255/24391/16852 +f 24256/24392/16854 24258/24394/16856 24259/24395/16856 +f 24256/24392/16854 24259/24395/16856 24257/24393/16854 +f 24260/24396/16856 24261/24397/16858 24262/24398/16858 +f 24260/24396/16856 24262/24398/16858 24263/24399/16856 +f 24261/24397/16858 24264/24400/16860 24265/24401/16860 +f 24261/24397/16858 24265/24401/16860 24262/24398/16858 +f 24264/24400/16860 24266/24402/16862 24267/24403/16862 +f 24264/24400/16860 24267/24403/16862 24265/24401/16860 +f 24266/24402/16862 24268/24404/16864 24269/24405/17000 +f 24266/24402/16862 24269/24405/17000 24267/24403/16862 +f 24270/24406/16864 24271/24407/16866 24272/24408/16866 +f 24270/24406/16864 24272/24408/16866 24273/24409/16864 +f 24271/24407/16866 24274/24410/16870 24275/24411/16870 +f 24271/24407/16866 24275/24411/16870 24272/24408/16866 +f 24276/24412/16871 24277/24413/16838 24278/24414/16838 +f 24276/24412/16871 24278/24414/16838 24279/24415/16871 +f 24274/24410/16870 24276/24412/16871 24279/24415/16871 +f 24274/24410/16870 24279/24415/16871 24275/24411/16870 +f 24292/24416/16871 24293/24417/16871 24294/24418/16838 +f 24292/24416/16871 24294/24418/16838 24295/24419/16838 +f 24296/24420/16841 24297/24421/16841 24298/24422/16843 +f 24296/24420/16841 24298/24422/16843 24299/24423/16843 +f 24299/24423/16843 24298/24422/16843 24300/24424/16845 +f 24299/24423/16843 24300/24424/16845 24301/24425/16845 +f 24301/24425/16845 24300/24424/16845 24302/24426/16847 +f 24301/24425/16845 24302/24426/16847 24303/24427/16847 +f 24304/24428/16847 24305/24429/16847 24306/24430/16850 +f 24304/24428/16847 24306/24430/16850 24307/24431/16850 +f 24307/24431/16850 24306/24430/16850 24308/24432/16852 +f 24307/24431/16850 24308/24432/16852 24309/24433/16852 +f 24309/24433/16852 24308/24432/16852 24310/24434/16854 +f 24309/24433/16852 24310/24434/16854 24311/24435/16854 +f 24311/24435/16854 24310/24434/16854 24312/24436/16856 +f 24311/24435/16854 24312/24436/16856 24313/24437/16856 +f 24314/24438/16856 24315/24439/16856 24316/24440/16858 +f 24314/24438/16856 24316/24440/16858 24317/24441/16858 +f 24317/24441/16858 24316/24440/16858 24318/24442/16860 +f 24317/24441/16858 24318/24442/16860 24319/24443/16860 +f 24319/24443/16860 24318/24442/16860 24150/24366/16862 +f 24319/24443/16860 24150/24366/16862 24149/24365/16862 +f 24093/24317/16843 24092/24316/16843 24129/24345/16845 +f 24093/24317/16843 24129/24345/16845 24125/24341/16845 +f 24131/24347/16838 24320/24444/16838 24091/24315/16841 +f 24131/24347/16838 24091/24315/16841 24090/24314/16841 +f 24156/24372/16866 24155/24371/16866 24321/24445/16870 +f 24156/24372/16866 24321/24445/16870 24322/24446/16870 +f 24323/24447/16838 24324/24448/16838 24297/24421/16841 +f 24323/24447/16838 24297/24421/16841 24296/24420/16841 +f 24085/24309/16870 24096/24320/16870 24087/24311/16871 +f 24085/24309/16870 24087/24311/16871 24086/24310/16998 +f 24322/24446/16870 24321/24445/16870 24293/24417/16871 +f 24322/24446/16870 24293/24417/16871 24292/24416/16871 +f 24406/24449/16871 24407/24450/16838 24408/24451/16838 +f 24406/24449/16871 24408/24451/16838 24409/24452/16871 +f 24410/24453/16841 24411/24454/16843 24412/24455/16843 +f 24410/24453/16841 24412/24455/16843 24413/24456/16841 +f 24411/24454/16843 24414/24457/16845 24415/24458/16845 +f 24411/24454/16843 24415/24458/16845 24412/24455/16843 +f 24414/24457/16845 24416/24459/16847 24417/24460/16847 +f 24414/24457/16845 24417/24460/16847 24415/24458/16845 +f 24418/24461/16847 24419/24462/16850 24420/24463/16850 +f 24418/24461/16847 24420/24463/16850 24421/24464/16847 +f 24419/24462/16850 24422/24465/16852 24423/24466/16852 +f 24419/24462/16850 24423/24466/16852 24420/24463/16850 +f 24422/24465/16852 24424/24467/16854 24425/24468/16854 +f 24422/24465/16852 24425/24468/16854 24423/24466/16852 +f 24424/24467/16854 24426/24469/16856 24427/24470/16856 +f 24424/24467/16854 24427/24470/16856 24425/24468/16854 +f 24428/24471/16856 24429/24472/16858 24430/24473/16858 +f 24428/24471/16856 24430/24473/16858 24431/24474/16856 +f 24429/24472/16858 24432/24475/16860 24433/24476/16860 +f 24429/24472/16858 24433/24476/16860 24430/24473/16858 +f 24432/24475/16860 24434/24477/16862 24435/24478/16862 +f 24432/24475/16860 24435/24478/16862 24433/24476/16860 +f 24434/24477/16862 24436/24479/16864 24437/24480/16864 +f 24434/24477/16862 24437/24480/16864 24435/24478/16862 +f 24438/24481/16864 24439/24482/16866 24440/24483/16866 +f 24438/24481/16864 24440/24483/16866 24441/24484/16864 +f 24442/24485/16870 24406/24449/16871 24409/24452/16871 +f 24442/24485/16870 24409/24452/16871 24443/24486/16870 +f 24444/24487/16838 24410/24453/16841 24413/24456/16841 +f 24444/24487/16838 24413/24456/16841 24445/24488/16838 +f 24439/24482/16866 24442/24485/16870 24443/24486/16870 +f 24439/24482/16866 24443/24486/16870 24440/24483/16866 +f 24457/24489/17001 24458/24490/17002 24459/24491/17003 +f 24457/24489/17001 24459/24491/17003 24460/24492/17004 +f 24458/24490/17002 24461/24493/17005 24462/24494/17006 +f 24458/24490/17002 24462/24494/17006 24459/24491/17003 +f 24459/24491/17003 24462/24494/17006 24463/24495/17007 +f 24459/24491/17003 24463/24495/17007 24464/24496/17008 +f 24460/24492/17004 24459/24491/17003 24464/24496/17008 +f 24460/24492/17004 24464/24496/17008 24465/24497/17009 +f 24466/24498/17010 24467/24499/17011 24468/24500/17012 +f 24466/24498/17010 24468/24500/17012 24469/24501/17013 +f 24467/24499/17011 24470/24502/17014 24471/24503/17015 +f 24467/24499/17011 24471/24503/17015 24468/24500/17012 +f 24468/24500/17012 24471/24503/17015 24472/24504/17016 +f 24468/24500/17012 24472/24504/17016 24473/24505/17017 +f 24469/24501/17013 24468/24500/17012 24473/24505/17017 +f 24469/24501/17013 24473/24505/17017 24474/24506/17018 +f 24475/24507/17019 24476/24508/17020 24477/24509/17021 +f 24475/24507/17019 24477/24509/17021 24478/24510/17022 +f 24476/24508/17020 24479/24511/17023 24480/24512/17024 +f 24476/24508/17020 24480/24512/17024 24477/24509/17021 +f 24477/24509/17021 24480/24512/17024 24461/24493/17005 +f 24477/24509/17021 24461/24493/17005 24458/24490/17002 +f 24478/24510/17022 24477/24509/17021 24458/24490/17002 +f 24478/24510/17022 24458/24490/17002 24457/24489/17001 +f 24479/24511/17023 24476/24508/17020 24481/24513/17025 +f 24479/24511/17023 24481/24513/17025 24482/24514/17026 +f 24476/24508/17020 24475/24507/17019 24483/24515/17027 +f 24476/24508/17020 24483/24515/17027 24481/24513/17025 +f 24481/24513/17025 24483/24515/17027 24484/24516/17028 +f 24481/24513/17025 24484/24516/17028 24485/24517/17029 +f 24482/24514/17026 24481/24513/17025 24485/24517/17029 +f 24482/24514/17026 24485/24517/17029 24486/24518/17030 +f 24487/24519/17031 24488/24520/17032 24489/24521/17033 +f 24487/24519/17031 24489/24521/17033 24490/24522/16834 +f 24488/24520/17032 24491/24523/17018 24492/24524/17034 +f 24488/24520/17032 24492/24524/17034 24489/24521/17033 +f 24489/24521/17033 24492/24524/17034 24493/24525/17035 +f 24489/24521/17033 24493/24525/17035 24494/24526/17036 +f 24490/24522/16834 24489/24521/17033 24494/24526/17036 +f 24490/24522/16834 24494/24526/17036 24495/24527/17030 +f 24496/24528/17016 24497/24529/17015 24498/24530/17037 +f 24496/24528/17016 24498/24530/17037 24499/24531/17038 +f 24497/24529/17015 24500/24532/17039 24501/24533/17040 +f 24497/24529/17015 24501/24533/17040 24498/24530/17037 +f 24498/24530/17037 24501/24533/17040 24502/24534/17028 +f 24498/24530/17037 24502/24534/17028 24503/24535/17041 +f 24499/24531/17038 24498/24530/17037 24503/24535/17041 +f 24499/24531/17038 24503/24535/17041 24504/24536/17019 +f 24493/24525/17035 24492/24524/17034 24505/24537/17042 +f 24493/24525/17035 24505/24537/17042 24506/24538/17024 +f 24492/24524/17034 24491/24523/17018 24507/24539/17043 +f 24492/24524/17034 24507/24539/17043 24505/24537/17042 +f 24505/24537/17042 24507/24539/17043 24508/24540/17044 +f 24505/24537/17042 24508/24540/17044 24509/24541/17045 +f 24506/24538/17024 24505/24537/17042 24509/24541/17045 +f 24506/24538/17024 24509/24541/17045 24510/24542/17005 +f 24496/24528/17016 24499/24531/17038 24511/24543/17046 +f 24496/24528/17016 24511/24543/17046 24512/24544/17047 +f 24499/24531/17038 24504/24536/17019 24513/24545/17048 +f 24499/24531/17038 24513/24545/17048 24511/24543/17046 +f 24511/24543/17046 24513/24545/17048 24514/24546/17001 +f 24511/24543/17046 24514/24546/17001 24515/24547/17049 +f 24512/24544/17047 24511/24543/17046 24515/24547/17049 +f 24512/24544/17047 24515/24547/17049 24516/24548/17050 +f 24474/24506/17018 24473/24505/17017 24517/24549/17051 +f 24474/24506/17018 24517/24549/17051 24518/24550/17052 +f 24473/24505/17017 24472/24504/17016 24519/24551/17047 +f 24473/24505/17017 24519/24551/17047 24517/24549/17051 +f 24517/24549/17051 24519/24551/17047 24520/24552/17050 +f 24517/24549/17051 24520/24552/17050 24521/24553/17053 +f 24518/24550/17052 24517/24549/17051 24521/24553/17053 +f 24518/24550/17052 24521/24553/17053 24522/24554/17044 +f 24523/24555/17054 24524/24556/17055 24525/24557/17056 +f 24523/24555/17054 24525/24557/17056 24526/24558/17057 +f 24524/24556/17055 24527/24559/17058 24528/24560/17059 +f 24524/24556/17055 24528/24560/17059 24525/24557/17056 +f 24525/24557/17056 24528/24560/17059 24529/24561/17060 +f 24525/24557/17056 24529/24561/17060 24530/24562/17061 +f 24526/24558/17057 24525/24557/17056 24530/24562/17061 +f 24526/24558/17057 24530/24562/17061 24531/24563/17062 +f 24510/24542/17005 24509/24541/17045 24532/24564/17063 +f 24510/24542/17005 24532/24564/17063 24533/24565/17006 +f 24509/24541/17045 24508/24540/17044 24534/24566/17064 +f 24509/24541/17045 24534/24566/17064 24532/24564/17063 +f 24535/24567/17065 24536/24568/17066 24537/24569/17067 +f 24535/24567/17065 24537/24569/17067 24538/24570/17068 +f 24539/24571/17006 24535/24567/17065 24538/24570/17068 +f 24539/24571/17006 24538/24570/17068 24540/24572/17007 +f 24516/24548/17050 24515/24547/17049 24541/24573/17069 +f 24516/24548/17050 24541/24573/17069 24542/24574/17070 +f 24515/24547/17049 24514/24546/17001 24543/24575/17071 +f 24515/24547/17049 24543/24575/17071 24541/24573/17069 +f 24541/24573/17069 24543/24575/17071 24544/24576/17072 +f 24541/24573/17069 24544/24576/17072 24545/24577/17055 +f 24546/24578/17070 24547/24579/17073 24524/24556/17055 +f 24546/24578/17070 24524/24556/17055 24523/24555/17054 +f 24522/24554/17044 24521/24553/17053 24548/24580/17074 +f 24522/24554/17044 24548/24580/17074 24549/24581/17066 +f 24521/24553/17053 24520/24552/17050 24550/24582/17070 +f 24521/24553/17053 24550/24582/17070 24548/24580/17074 +f 24548/24580/17074 24550/24582/17070 24551/24583/17054 +f 24548/24580/17074 24551/24583/17054 24552/24584/17075 +f 24549/24581/17066 24548/24580/17074 24552/24584/17075 +f 24549/24581/17066 24552/24584/17075 24553/24585/17067 +f 24554/24586/17076 24555/24587/17077 24556/24588/17078 +f 24554/24586/17076 24556/24588/17078 24557/24589/17079 +f 24555/24587/17077 24558/24590/17080 24559/24591/17081 +f 24555/24587/17077 24559/24591/17081 24556/24588/17078 +f 24556/24588/17078 24559/24591/17081 24560/24592/17082 +f 24556/24588/17078 24560/24592/17082 24561/24593/17083 +f 24557/24589/17079 24556/24588/17078 24561/24593/17083 +f 24557/24589/17079 24561/24593/17083 24562/24594/17084 +f 24553/24585/17067 24552/24584/17075 24563/24595/17085 +f 24553/24585/17067 24563/24595/17085 24564/24596/17086 +f 24552/24584/17075 24551/24583/17054 24565/24597/17087 +f 24552/24584/17075 24565/24597/17087 24563/24595/17085 +f 24563/24595/17085 24565/24597/17087 24566/24598/17088 +f 24563/24595/17085 24566/24598/17088 24567/24599/17089 +f 24564/24596/17086 24563/24595/17085 24567/24599/17089 +f 24564/24596/17086 24567/24599/17089 24568/24600/17090 +f 24465/24497/17009 24464/24496/17008 24569/24601/17091 +f 24465/24497/17009 24569/24601/17091 24570/24602/17092 +f 24464/24496/17008 24463/24495/17007 24571/24603/17093 +f 24464/24496/17008 24571/24603/17093 24569/24601/17091 +f 24569/24601/17091 24571/24603/17093 24558/24590/17080 +f 24569/24601/17091 24558/24590/17080 24555/24587/17077 +f 24570/24602/17092 24569/24601/17091 24555/24587/17077 +f 24570/24602/17092 24555/24587/17077 24554/24586/17076 +f 24540/24572/17007 24538/24570/17068 24572/24604/17094 +f 24540/24572/17007 24572/24604/17094 24573/24605/17093 +f 24538/24570/17068 24537/24569/17067 24574/24606/17086 +f 24538/24570/17068 24574/24606/17086 24572/24604/17094 +f 24572/24604/17094 24574/24606/17086 24575/24607/17090 +f 24572/24604/17094 24575/24607/17090 24576/24608/17095 +f 24573/24605/17093 24572/24604/17094 24576/24608/17095 +f 24573/24605/17093 24576/24608/17095 24577/24609/17096 +f 24578/24610/17097 24579/24611/17098 24580/24612/17099 +f 24578/24610/17097 24580/24612/17099 24581/24613/17100 +f 24579/24611/17098 24582/24614/17101 24583/24615/17102 +f 24579/24611/17098 24583/24615/17102 24580/24612/17099 +f 24580/24612/17099 24583/24615/17102 24584/24616/17103 +f 24580/24612/17099 24584/24616/17103 24585/24617/17104 +f 24581/24613/17100 24580/24612/17099 24585/24617/17104 +f 24581/24613/17100 24585/24617/17104 24586/24618/17105 +f 24577/24609/17096 24576/24608/17095 24587/24619/17106 +f 24577/24609/17096 24587/24619/17106 24588/24620/17107 +f 24576/24608/17095 24575/24607/17090 24589/24621/17108 +f 24576/24608/17095 24589/24621/17108 24587/24619/17106 +f 24587/24619/17106 24589/24621/17108 24582/24614/17101 +f 24587/24619/17106 24582/24614/17101 24579/24611/17098 +f 24588/24620/17107 24587/24619/17106 24579/24611/17098 +f 24588/24620/17107 24579/24611/17098 24578/24610/17097 +f 24531/24563/17062 24530/24562/17061 24590/24622/17109 +f 24531/24563/17062 24590/24622/17109 24591/24623/17110 +f 24530/24562/17061 24529/24561/17060 24592/24624/17111 +f 24530/24562/17061 24592/24624/17111 24590/24622/17109 +f 24590/24622/17109 24592/24624/17111 24593/24625/17084 +f 24590/24622/17109 24593/24625/17084 24594/24626/17112 +f 24591/24623/17110 24590/24622/17109 24594/24626/17112 +f 24591/24623/17110 24594/24626/17112 24595/24627/17113 +f 24568/24600/17090 24567/24599/17089 24596/24628/17114 +f 24568/24600/17090 24596/24628/17114 24597/24629/17108 +f 24567/24599/17089 24566/24598/17088 24598/24630/17115 +f 24567/24599/17089 24598/24630/17115 24596/24628/17114 +f 24596/24628/17114 24598/24630/17115 24599/24631/17113 +f 24596/24628/17114 24599/24631/17113 24600/24632/17116 +f 24597/24629/17108 24596/24628/17114 24600/24632/17116 +f 24597/24629/17108 24600/24632/17116 24601/24633/17101 +f 24602/24634/17117 24603/24635/17118 24604/24636/17119 +f 24602/24634/17117 24604/24636/17119 24605/24637/17120 +f 24606/24638/17118 24607/24639/17121 24608/24640/17122 +f 24606/24638/17118 24608/24640/17122 24609/24641/17119 +f 24609/24641/17119 24608/24640/17122 24610/24642/17123 +f 24609/24641/17119 24610/24642/17123 24611/24643/17124 +f 24612/24644/17120 24609/24641/17119 24611/24643/17124 +f 24612/24644/17120 24611/24643/17124 24613/24645/17125 +f 24595/24627/17113 24594/24626/17112 24614/24646/17126 +f 24595/24627/17113 24614/24646/17126 24615/24647/17127 +f 24594/24626/17112 24593/24625/17084 24616/24648/17128 +f 24594/24626/17112 24616/24648/17128 24614/24646/17126 +f 24614/24646/17126 24616/24648/17128 24617/24649/17121 +f 24614/24646/17126 24617/24649/17121 24603/24635/17118 +f 24615/24647/17127 24614/24646/17126 24603/24635/17118 +f 24615/24647/17127 24603/24635/17118 24602/24634/17117 +f 24601/24633/17101 24600/24632/17116 24618/24650/17129 +f 24601/24633/17101 24618/24650/17129 24619/24651/17102 +f 24600/24632/17116 24599/24631/17113 24620/24652/17127 +f 24600/24632/17116 24620/24652/17127 24618/24650/17129 +f 24618/24650/17129 24620/24652/17127 24621/24653/17130 +f 24618/24650/17129 24621/24653/17130 24622/24654/17131 +f 24619/24651/17102 24618/24650/17129 24622/24654/17131 +f 24619/24651/17102 24622/24654/17131 24623/24655/17103 +f 24562/24594/17084 24561/24593/17083 24624/24656/17132 +f 24562/24594/17084 24624/24656/17132 24625/24657/17128 +f 24561/24593/17083 24560/24592/17082 24626/24658/17133 +f 24561/24593/17083 24626/24658/17133 24624/24656/17132 +f 24624/24656/17132 24626/24658/17133 24627/24659/17105 +f 24624/24656/17132 24627/24659/17105 24628/24660/17134 +f 24625/24657/17128 24624/24656/17132 24628/24660/17134 +f 24625/24657/17128 24628/24660/17134 24629/24661/17121 +f 24630/24662/17123 24631/24663/17135 24632/24664/17136 +f 24630/24662/17123 24632/24664/17136 24633/24665/17137 +f 24631/24663/17135 24634/24666/17138 24635/24667/17139 +f 24631/24663/17135 24635/24667/17139 24632/24664/17136 +f 24632/24664/17136 24635/24667/17139 24636/24668/17140 +f 24632/24664/17136 24636/24668/17140 24637/24669/17141 +f 24633/24665/17137 24632/24664/17136 24637/24669/17141 +f 24633/24665/17137 24637/24669/17141 24638/24670/17142 +f 24623/24655/17103 24622/24654/17131 24639/24671/17143 +f 24623/24655/17103 24639/24671/17143 24640/24672/17144 +f 24622/24654/17131 24621/24653/17130 24641/24673/17120 +f 24622/24654/17131 24641/24673/17120 24639/24671/17143 +f 24639/24671/17143 24641/24673/17120 24642/24674/17125 +f 24639/24671/17143 24642/24674/17125 24643/24675/17145 +f 24640/24672/17144 24639/24671/17143 24643/24675/17145 +f 24640/24672/17144 24643/24675/17145 24644/24676/17146 +f 24629/24661/17121 24628/24660/17134 24645/24677/17147 +f 24629/24661/17121 24645/24677/17147 24646/24678/17122 +f 24628/24660/17134 24627/24659/17105 24647/24679/17148 +f 24628/24660/17134 24647/24679/17148 24645/24677/17147 +f 24645/24677/17147 24647/24679/17148 24634/24666/17138 +f 24645/24677/17147 24634/24666/17138 24631/24663/17135 +f 24646/24678/17122 24645/24677/17147 24631/24663/17135 +f 24646/24678/17122 24631/24663/17135 24630/24662/17123 +f 24586/24618/17105 24585/24617/17104 24648/24680/17149 +f 24586/24618/17105 24648/24680/17149 24649/24681/17150 +f 24650/24682/17104 24651/24683/17103 24652/24684/17144 +f 24650/24682/17104 24652/24684/17144 24653/24685/17151 +f 24653/24685/17151 24652/24684/17144 24654/24686/17146 +f 24653/24685/17151 24654/24686/17146 24655/24687/17152 +f 24656/24688/17150 24653/24685/17151 24655/24687/17152 +f 24656/24688/17150 24655/24687/17152 24657/24689/17138 +f 24658/24690/17153 24659/24691/17154 24660/24692/17155 +f 24658/24690/17153 24660/24692/17155 24661/24693/17156 +f 24659/24691/17154 24662/24694/17157 24663/24695/17158 +f 24659/24691/17154 24663/24695/17158 24660/24692/17155 +f 24660/24692/17155 24663/24695/17158 24664/24696/17159 +f 24660/24692/17155 24664/24696/17159 24665/24697/17160 +f 24661/24693/17156 24660/24692/17155 24665/24697/17160 +f 24661/24693/17156 24665/24697/17160 24666/24698/17161 +f 24657/24689/17138 24655/24687/17152 24667/24699/17162 +f 24657/24689/17138 24667/24699/17162 24668/24700/17163 +f 24655/24687/17152 24654/24686/17146 24669/24701/17164 +f 24655/24687/17152 24669/24701/17164 24667/24699/17162 +f 24667/24699/17162 24669/24701/17164 24670/24702/17165 +f 24667/24699/17162 24670/24702/17165 24671/24703/17166 +f 24668/24700/17163 24667/24699/17162 24671/24703/17166 +f 24668/24700/17163 24671/24703/17166 24672/24704/17140 +f 24613/24645/17125 24611/24643/17124 24673/24705/17167 +f 24613/24645/17125 24673/24705/17167 24674/24706/17168 +f 24611/24643/17124 24610/24642/17123 24675/24707/17137 +f 24611/24643/17124 24675/24707/17137 24673/24705/17167 +f 24673/24705/17167 24675/24707/17137 24662/24694/17157 +f 24673/24705/17167 24662/24694/17157 24659/24691/17154 +f 24674/24706/17168 24673/24705/17167 24659/24691/17154 +f 24674/24706/17168 24659/24691/17154 24658/24690/17153 +f 24644/24676/17146 24643/24675/17145 24676/24708/17169 +f 24644/24676/17146 24676/24708/17169 24677/24709/17164 +f 24643/24675/17145 24642/24674/17125 24678/24710/17170 +f 24643/24675/17145 24678/24710/17170 24676/24708/17169 +f 24676/24708/17169 24678/24710/17170 24679/24711/17153 +f 24676/24708/17169 24679/24711/17153 24680/24712/17171 +f 24677/24709/17164 24676/24708/17169 24680/24712/17171 +f 24677/24709/17164 24680/24712/17171 24681/24713/17165 +f 24681/24713/17165 24680/24712/17171 24682/24714/17172 +f 24681/24713/17165 24682/24714/17172 24683/24715/17173 +f 24680/24712/17171 24679/24711/17153 24684/24716/17156 +f 24680/24712/17171 24684/24716/17156 24682/24714/17172 +f 24682/24714/17172 24684/24716/17156 24685/24717/17161 +f 24682/24714/17172 24685/24717/17161 24686/24718/17174 +f 24683/24715/17173 24682/24714/17172 24686/24718/17174 +f 24683/24715/17173 24686/24718/17174 24687/24719/17175 +f 24638/24670/17142 24637/24669/17141 24688/24720/17176 +f 24638/24670/17142 24688/24720/17176 24689/24721/17177 +f 24637/24669/17141 24636/24668/17140 24690/24722/17178 +f 24637/24669/17141 24690/24722/17178 24688/24720/17176 +f 24688/24720/17176 24690/24722/17178 24691/24723/17179 +f 24688/24720/17176 24691/24723/17179 24692/24724/17180 +f 24689/24721/17177 24688/24720/17176 24692/24724/17180 +f 24689/24721/17177 24692/24724/17180 24693/24725/17181 +f 24672/24704/17140 24671/24703/17166 24694/24726/17182 +f 24672/24704/17140 24694/24726/17182 24695/24727/17178 +f 24671/24703/17166 24670/24702/17165 24696/24728/17173 +f 24671/24703/17166 24696/24728/17173 24694/24726/17182 +f 24694/24726/17182 24696/24728/17173 24697/24729/17175 +f 24694/24726/17182 24697/24729/17175 24698/24730/17183 +f 24695/24727/17178 24694/24726/17182 24698/24730/17183 +f 24695/24727/17178 24698/24730/17183 24699/24731/17184 +f 24700/24732/17185 24701/24733/17186 23984/24208/16926 +f 24700/24732/17185 23984/24208/16926 23983/24207/16925 +f 24702/24734/17187 24700/24732/17185 23983/24207/16925 +f 24702/24734/17187 23983/24207/16925 23988/24212/16929 +f 24703/24735/17188 24702/24734/17187 23988/24212/16929 +f 24703/24735/17188 23988/24212/16929 23994/24218/16933 +f 24704/24736/17189 24703/24735/17188 23994/24218/16933 +f 24704/24736/17189 23994/24218/16933 23998/24222/16936 +f 24705/24737/17190 24704/24736/17189 23998/24222/16936 +f 24705/24737/17190 23998/24222/16936 24002/24226/16939 +f 24706/24738/17191 24705/24737/17190 24002/24226/16939 +f 24706/24738/17191 24002/24226/16939 24006/24230/16942 +f 24707/24739/17192 24706/24738/17191 24006/24230/16942 +f 24707/24739/17192 24006/24230/16942 24012/24236/16945 +f 24708/24740/17193 24707/24739/17192 24012/24236/16945 +f 24708/24740/17193 24012/24236/16945 24016/24240/16948 +f 24709/24741/17194 24708/24740/17193 24016/24240/16948 +f 24709/24741/17194 24016/24240/16948 24020/24244/16952 +f 24710/24742/17195 24709/24741/17194 24020/24244/16952 +f 24710/24742/17195 24020/24244/16952 24024/24248/16956 +f 24711/24743/17196 24710/24742/17195 24024/24248/16956 +f 24711/24743/17196 24024/24248/16956 24030/24254/16959 +f 24712/24744/17197 24711/24743/17196 24030/24254/16959 +f 24712/24744/17197 24030/24254/16959 24034/24258/16962 +f 24713/24745/17198 24712/24744/17197 24034/24258/16962 +f 24713/24745/17198 24034/24258/16962 24038/24262/16965 +f 24714/24746/17199 24713/24745/17198 24038/24262/16965 +f 24714/24746/17199 24038/24262/16965 24042/24266/16969 +f 24715/24747/17200 24714/24746/17199 24042/24266/16969 +f 24715/24747/17200 24042/24266/16969 24048/24272/16974 +f 24701/24733/17186 24715/24747/17200 24048/24272/16974 +f 24701/24733/17186 24048/24272/16974 23984/24208/16926 +f 24716/24748/16862 24717/24749/16864 24718/24750/16864 +f 24716/24748/16862 24718/24750/16864 24719/24751/16862 +f 24050/24274/16845 24720/24752/16847 24721/24753/16847 +f 24050/24274/16845 24721/24753/16847 24051/24275/16845 +f 24722/24754/17201 24723/24755/16866 24724/24756/16866 +f 24722/24754/17201 24724/24756/16866 24725/24757/17201 +f 24726/24758/16847 24727/24759/16850 24728/24760/16850 +f 24726/24758/16847 24728/24760/16850 24729/24761/16847 +f 24723/24755/16866 24730/24762/16870 24731/24763/16870 +f 24723/24755/16866 24731/24763/16870 24724/24756/16866 +f 24732/24764/16852 24733/24765/16854 24734/24766/16854 +f 24732/24764/16852 24734/24766/16854 24735/24767/16852 +f 24727/24759/16850 24732/24764/16852 24735/24767/16852 +f 24727/24759/16850 24735/24767/16852 24728/24760/16850 +f 24730/24762/16870 24736/24768/16871 24737/24769/16871 +f 24730/24762/16870 24737/24769/16871 24731/24763/16870 +f 24733/24765/16854 24738/24770/16856 24739/24771/16856 +f 24733/24765/16854 24739/24771/16856 24734/24766/16854 +f 24736/24768/16871 24740/24772/16838 24741/24773/16838 +f 24736/24768/16871 24741/24773/16838 24737/24769/16871 +f 24742/24774/16856 24743/24775/16858 24744/24776/16858 +f 24742/24774/16856 24744/24776/16858 24745/24777/16856 +f 24746/24778/16838 24747/24779/16841 24748/24780/16841 +f 24746/24778/16838 24748/24780/16841 24749/24781/16838 +f 24743/24775/16858 24750/24782/16860 24751/24783/16860 +f 24743/24775/16858 24751/24783/16860 24744/24776/16858 +f 24747/24779/16841 24049/24273/16843 24052/24276/16843 +f 24747/24779/16841 24052/24276/16843 24748/24780/16841 +f 24750/24782/16860 24716/24748/16862 24719/24751/16862 +f 24750/24782/16860 24719/24751/16862 24751/24783/16860 +o Cube.040__0 +v 1.030735 0.352231 -0.484109 +v 1.043592 0.359668 -0.485003 +v 1.023699 0.389725 -0.581120 +v 1.010656 0.382567 -0.581120 +v 1.056184 0.360499 -0.491261 +v 1.037586 0.388598 -0.581120 +v 1.056184 0.360499 -0.670979 +v 1.043592 0.359668 -0.677236 +v 1.030735 0.352231 -0.678130 +v 1.030735 0.352231 -0.678130 +v 1.043592 0.359668 -0.677236 +v 1.096642 0.279518 -0.713280 +v 1.084278 0.271334 -0.714509 +v 1.056184 0.360499 -0.670979 +v 1.105780 0.285566 -0.704676 +v 1.155376 0.210633 -0.670979 +v 1.149691 0.199367 -0.677236 +v 1.137821 0.190438 -0.678130 +v 1.137821 0.190438 -0.678130 +v 1.149691 0.199367 -0.677236 +v 1.169585 0.169310 -0.581120 +v 1.157899 0.160102 -0.581120 +v 1.155376 0.210633 -0.670979 +v 1.173974 0.182533 -0.581120 +v 1.155376 0.210633 -0.491261 +v 1.149691 0.199367 -0.485003 +v 1.137821 0.190438 -0.484109 +v 1.137821 0.190438 -0.484109 +v 1.149691 0.199367 -0.485003 +v 1.096642 0.279518 -0.448959 +v 1.084278 0.271334 -0.447730 +v 1.149691 0.199367 -0.485003 +v 1.155376 0.210633 -0.491261 +v 1.105780 0.285566 -0.457563 +v 1.096642 0.279518 -0.448959 +v 1.105780 0.285566 -0.457563 +v 1.056184 0.360499 -0.491261 +v 1.043592 0.359668 -0.485003 +v 1.030735 0.352231 -0.484109 +v 1.132893 0.255934 -0.620794 +v 1.110996 0.289018 -0.635672 +v 1.112827 0.290230 -0.631664 +v 1.133115 0.259577 -0.617879 +v 1.089098 0.322102 -0.620794 +v 1.092538 0.320884 -0.617879 +v 1.096076 0.319517 -0.614787 +v 1.114658 0.291442 -0.627412 +v 1.133240 0.263367 -0.614787 +v 1.077865 0.337085 -0.522752 +v 1.065784 0.355337 -0.581120 +v 1.052476 0.374276 -0.581120 +v 1.068040 0.350761 -0.505924 +v 1.077865 0.337085 -0.639488 +v 1.068040 0.350761 -0.656315 +v 1.056184 0.360499 -0.670979 +v 1.037586 0.388598 -0.581120 +v 1.056184 0.360499 -0.491261 +v 1.110080 0.288412 -0.661376 +v 1.109543 0.288056 -0.684514 +v 1.142295 0.239739 -0.639488 +v 1.151045 0.225351 -0.656316 +v 1.155376 0.210633 -0.670979 +v 1.105780 0.285566 -0.704676 +v 1.154376 0.221487 -0.581120 +v 1.166609 0.201837 -0.581120 +v 1.142295 0.239739 -0.522752 +v 1.151045 0.225351 -0.505924 +v 1.173974 0.182533 -0.581120 +v 1.110080 0.288412 -0.500864 +v 1.109543 0.288056 -0.477726 +v 1.089098 0.322102 -0.541445 +v 1.080886 0.334509 -0.581120 +v 1.075027 0.341621 -0.581120 +v 1.084618 0.327130 -0.534780 +v 1.084618 0.327130 -0.627459 +v 1.110194 0.288488 -0.644836 +v 1.135771 0.249846 -0.627460 +v 1.141104 0.243527 -0.581120 +v 1.145361 0.235355 -0.581120 +v 1.132893 0.255934 -0.541445 +v 1.135771 0.249846 -0.534781 +v 1.110996 0.289018 -0.526567 +v 1.110194 0.288488 -0.517403 +v 1.214044 0.396218 -0.563154 +v 1.231761 0.392246 -0.556107 +v 1.225039 0.420930 -0.556693 +v 1.207440 0.418696 -0.563655 +v 1.249477 0.388274 -0.562605 +v 1.242638 0.423164 -0.563274 +v 1.225424 0.451748 -0.564046 +v 1.209381 0.444386 -0.557340 +v 1.193338 0.437024 -0.564177 +v 1.140723 0.248082 -0.581120 +v 1.133115 0.259577 -0.544360 +v 1.140208 0.252839 -0.581120 +v 1.133240 0.263367 -0.547452 +v 1.084930 0.332378 -0.581120 +v 1.092538 0.320884 -0.544360 +v 1.096076 0.319517 -0.547452 +v 1.089108 0.330045 -0.581120 +v 1.112827 0.290230 -0.530576 +v 1.114658 0.291442 -0.534827 +v 1.115499 0.317569 -0.559934 +v 1.111174 0.324103 -0.581118 +v 1.096106 0.324388 -0.581120 +v 1.101775 0.315823 -0.553695 +v 1.115499 0.317569 -0.602294 +v 1.101775 0.315823 -0.608543 +v 1.096106 0.324388 -0.581120 +v 1.101775 0.315823 -0.608543 +v 1.101775 0.315823 -0.553695 +v 1.115499 0.317569 -0.602294 +v 1.127030 0.300143 -0.610225 +v 1.116891 0.292984 -0.618825 +v 1.101775 0.315823 -0.608543 +v 1.138562 0.282718 -0.602271 +v 1.132008 0.270145 -0.608540 +v 1.116891 0.292984 -0.618825 +v 1.132008 0.270145 -0.608540 +v 1.138562 0.282718 -0.602271 +v 1.142887 0.276184 -0.581086 +v 1.137676 0.261581 -0.581116 +v 1.132008 0.270145 -0.608540 +v 1.138562 0.282718 -0.559910 +v 1.132008 0.270145 -0.553692 +v 1.137676 0.261581 -0.581116 +v 1.132008 0.270145 -0.553692 +v 1.127030 0.300143 -0.551980 +v 1.116891 0.292984 -0.543410 +v 1.127030 0.300143 -0.551980 +v 1.115499 0.317569 -0.559934 +v 1.101775 0.315823 -0.553695 +v 1.116891 0.292984 -0.543410 +v 1.116891 0.292984 -0.543410 +v 1.225424 0.451748 -0.564046 +v 1.231440 0.454509 -0.582080 +v 1.221956 0.469486 -0.582446 +v 1.216143 0.465854 -0.564101 +v 1.225424 0.451748 -0.600163 +v 1.216143 0.465854 -0.600797 +v 1.215127 0.471038 -0.602873 +v 1.221535 0.475199 -0.582498 +v 1.215127 0.471038 -0.562123 +v 1.249477 0.388274 -0.598722 +v 1.231761 0.392246 -0.605768 +v 1.225039 0.420930 -0.606354 +v 1.242638 0.423164 -0.599391 +v 1.214044 0.396218 -0.599271 +v 1.207440 0.418696 -0.599772 +v 1.193338 0.437024 -0.600294 +v 1.209381 0.444386 -0.607000 +v 1.225424 0.451748 -0.600163 +v 1.249477 0.388274 -0.562605 +v 1.256121 0.386784 -0.580560 +v 1.249238 0.424002 -0.581261 +v 1.242638 0.423164 -0.563274 +v 1.249477 0.388274 -0.598722 +v 1.242638 0.423164 -0.599391 +v 1.214044 0.396218 -0.599271 +v 1.207401 0.397707 -0.581315 +v 1.200840 0.417858 -0.581785 +v 1.207440 0.418696 -0.599772 +v 1.214044 0.396218 -0.563154 +v 1.207440 0.418696 -0.563655 +v 1.193338 0.437024 -0.564177 +v 1.187322 0.434264 -0.582260 +v 1.193338 0.437024 -0.600294 +v 1.158249 0.489962 -0.599517 +v 1.172522 0.499232 -0.602533 +v 1.173037 0.498438 -0.615924 +v 1.152570 0.485147 -0.606902 +v 1.186795 0.508501 -0.599517 +v 1.193503 0.511730 -0.606902 +v 1.201502 0.509031 -0.612140 +v 1.176643 0.492886 -0.623255 +v 1.151784 0.476741 -0.612140 +v 1.179331 0.442854 -0.582469 +v 1.185143 0.446486 -0.600814 +v 1.185143 0.446486 -0.564117 +v 1.180952 0.448843 -0.562123 +v 1.174544 0.444681 -0.582498 +v 1.180952 0.448843 -0.602873 +v 1.200643 0.456170 -0.557229 +v 1.185143 0.446486 -0.564117 +v 1.216143 0.465854 -0.564101 +v 1.200643 0.456170 -0.557229 +v 1.216143 0.465854 -0.564101 +v 1.215127 0.471038 -0.562123 +v 1.198040 0.459940 -0.554482 +v 1.198040 0.459940 -0.554482 +v 1.180952 0.448843 -0.562123 +v 1.200643 0.456170 -0.607686 +v 1.216143 0.465854 -0.600797 +v 1.185143 0.446486 -0.600814 +v 1.180952 0.448843 -0.602873 +v 1.198040 0.459940 -0.610514 +v 1.215127 0.471038 -0.602873 +v 1.172522 0.499232 -0.582498 +v 1.189324 0.510144 -0.582498 +v 1.155720 0.488319 -0.582498 +v 1.158249 0.489962 -0.565480 +v 1.172522 0.499232 -0.562463 +v 1.186795 0.508501 -0.565480 +v 1.180952 0.448843 -0.602873 +v 1.174544 0.444681 -0.582498 +v 1.167994 0.443070 -0.582498 +v 1.175859 0.448178 -0.607507 +v 1.180952 0.448843 -0.562123 +v 1.175859 0.448178 -0.557490 +v 1.167994 0.443070 -0.582498 +v 1.175859 0.448178 -0.557490 +v 1.168269 0.451359 -0.552857 +v 1.158946 0.445304 -0.582498 +v 1.175859 0.448178 -0.607507 +v 1.168269 0.451359 -0.612140 +v 1.173037 0.498438 -0.549073 +v 1.193503 0.511730 -0.558094 +v 1.152570 0.485147 -0.558094 +v 1.173037 0.498438 -0.549073 +v 1.152570 0.485147 -0.558094 +v 1.151784 0.476741 -0.552857 +v 1.176643 0.492886 -0.541741 +v 1.193503 0.511730 -0.558094 +v 1.201502 0.509031 -0.552857 +v 1.221535 0.475199 -0.582498 +v 1.225671 0.480528 -0.582498 +v 1.217806 0.475420 -0.557490 +v 1.215127 0.471038 -0.602873 +v 1.217806 0.475420 -0.607507 +v 1.217987 0.483648 -0.612140 +v 1.227309 0.489702 -0.582498 +v 1.217987 0.483648 -0.552857 +v 1.217987 0.483648 -0.552857 +v 1.227309 0.489702 -0.582498 +v 1.221070 0.503695 -0.582498 +v 1.211202 0.497286 -0.551119 +v 1.217987 0.483648 -0.612140 +v 1.211202 0.497286 -0.613878 +v 1.201502 0.509031 -0.612140 +v 1.210824 0.515085 -0.582498 +v 1.201502 0.509031 -0.552857 +v 1.148701 0.456695 -0.582498 +v 1.158569 0.463104 -0.613878 +v 1.158569 0.463104 -0.551119 +v 1.151784 0.476741 -0.552857 +v 1.142462 0.470687 -0.582498 +v 1.151784 0.476741 -0.612140 +v 1.168269 0.451359 -0.552857 +v 1.193128 0.467503 -0.541741 +v 1.184886 0.480195 -0.539352 +v 1.158569 0.463104 -0.551119 +v 1.217987 0.483648 -0.552857 +v 1.211202 0.497286 -0.551119 +v 1.217987 0.483648 -0.612140 +v 1.193128 0.467503 -0.623255 +v 1.184886 0.480195 -0.625644 +v 1.211202 0.497286 -0.613878 +v 1.168269 0.451359 -0.612140 +v 1.158569 0.463104 -0.613878 +v 1.151784 0.476741 -0.612140 +v 1.176643 0.492886 -0.623255 +v 1.201502 0.509031 -0.612140 +v 1.196833 0.461799 -0.548112 +v 1.193128 0.467503 -0.541741 +v 1.168269 0.451359 -0.552857 +v 1.198040 0.459940 -0.610514 +v 1.196833 0.461799 -0.616885 +v 1.196833 0.461799 -0.616885 +v 1.175859 0.448178 -0.607507 +v 1.217806 0.475420 -0.607507 +v 1.201070 0.516644 -0.582498 +v 1.201070 0.516644 -0.582498 +v 1.193503 0.511730 -0.558094 +v 1.210824 0.515085 -0.582498 +v 1.145004 0.480233 -0.582498 +v 1.142462 0.470687 -0.582498 +v 1.151784 0.476741 -0.552857 +v 1.137657 0.337287 -0.581115 +v 1.141387 0.331852 -0.599547 +v 1.141387 0.331852 -0.562650 +v 1.172888 0.353150 -0.563005 +v 1.168727 0.357813 -0.581105 +v 1.172888 0.353150 -0.599122 +v 1.165014 0.297429 -0.581000 +v 1.161283 0.302864 -0.562567 +v 1.161283 0.302864 -0.599465 +v 1.195080 0.328277 -0.598898 +v 1.199240 0.323614 -0.580797 +v 1.195080 0.328277 -0.562781 +v 1.151335 0.317358 -0.606424 +v 1.161283 0.302864 -0.599465 +v 1.141387 0.331852 -0.599547 +v 1.172888 0.353150 -0.599122 +v 1.183984 0.340714 -0.605782 +v 1.195080 0.328277 -0.598898 +v 1.151335 0.317358 -0.555690 +v 1.141387 0.331852 -0.562650 +v 1.138562 0.282718 -0.559910 +v 1.161283 0.302864 -0.562567 +v 1.195080 0.328277 -0.562781 +v 1.183984 0.340714 -0.556121 +v 1.172888 0.353150 -0.563005 +v 1.195046 0.377943 -0.581120 +v 1.200552 0.374552 -0.599096 +v 1.200552 0.374552 -0.562979 +v 1.214044 0.396218 -0.563154 +v 1.207401 0.397707 -0.581315 +v 1.214044 0.396218 -0.599271 +v 1.235425 0.353075 -0.580509 +v 1.229919 0.356466 -0.562534 +v 1.229919 0.356466 -0.598651 +v 1.249477 0.388274 -0.598722 +v 1.256121 0.386784 -0.580560 +v 1.249477 0.388274 -0.562605 +v 1.215236 0.365509 -0.605645 +v 1.229919 0.356466 -0.598651 +v 1.200552 0.374552 -0.599096 +v 1.215236 0.365509 -0.555984 +v 1.200552 0.374552 -0.562979 +v 1.229919 0.356466 -0.562534 +vt 0.736035 0.563229 +vt 0.736678 0.562125 +vt 0.735308 0.561621 +vt 0.735822 0.560232 +vt 0.496176 0.181539 +vt 0.497274 0.181466 +vt 0.497219 0.174922 +vt 0.496121 0.174934 +vt 0.498093 0.180933 +vt 0.498043 0.174816 +vt 0.498093 0.167842 +vt 0.497274 0.167463 +vt 0.496176 0.167405 +vt 0.757569 0.015011 +vt 0.758652 0.015002 +vt 0.758051 0.008967 +vt 0.756962 0.008920 +vt 0.759546 0.014481 +vt 0.758984 0.008839 +vt 0.759546 0.001774 +vt 0.758652 0.001410 +vt 0.757569 0.001293 +vt 0.947284 0.014836 +vt 0.948369 0.014824 +vt 0.947802 0.008839 +vt 0.946711 0.008795 +vt 0.949260 0.014298 +vt 0.948729 0.008703 +vt 0.949260 0.001633 +vt 0.948369 0.001276 +vt 0.947284 0.001162 +vt 0.279546 0.008821 +vt 0.278472 0.008942 +vt 0.278065 0.015178 +vt 0.279135 0.015115 +vt 0.959566 0.032872 +vt 0.959319 0.032229 +vt 0.952224 0.032229 +vt 0.951977 0.032872 +vt 0.277361 0.015364 +vt 0.277742 0.022412 +vt 0.278472 0.022716 +vt 0.279546 0.022723 +vt 0.959203 0.021948 +vt 0.956839 0.019892 +vt 0.956741 0.020159 +vt 0.958931 0.022065 +vt 0.953707 0.019892 +vt 0.953838 0.020159 +vt 0.953978 0.020443 +vt 0.956636 0.020443 +vt 0.958642 0.022188 +vt 0.949877 0.026188 +vt 0.949868 0.021587 +vt 0.948264 0.020990 +vt 0.948275 0.026918 +vt 0.952892 0.018120 +vt 0.952160 0.016524 +vt 0.951512 0.015150 +vt 0.946857 0.020487 +vt 0.946870 0.027571 +vt 0.957501 0.018120 +vt 0.958097 0.016524 +vt 0.960979 0.021146 +vt 0.962577 0.020421 +vt 0.963961 0.019808 +vt 0.958607 0.015150 +vt 0.960987 0.025747 +vt 0.962588 0.026350 +vt 0.957963 0.029214 +vt 0.958693 0.030816 +vt 0.963975 0.026892 +vt 0.953355 0.029214 +vt 0.952756 0.030816 +vt 0.951657 0.025376 +vt 0.951651 0.022248 +vt 0.951014 0.022015 +vt 0.951021 0.025668 +vt 0.953415 0.019262 +vt 0.957074 0.019262 +vt 0.959835 0.021665 +vt 0.959209 0.025076 +vt 0.959842 0.025318 +vt 0.957154 0.027433 +vt 0.957441 0.028070 +vt 0.954021 0.027433 +vt 0.953782 0.028070 +vt 0.023913 0.036138 +vt 0.022535 0.036538 +vt 0.023971 0.038139 +vt 0.025122 0.037344 +vt 0.021444 0.036917 +vt 0.023108 0.038913 +vt 0.025190 0.040125 +vt 0.025774 0.039078 +vt 0.026646 0.038010 +vt 0.958937 0.024962 +vt 0.957032 0.027146 +vt 0.958647 0.024843 +vt 0.956903 0.026842 +vt 0.951934 0.022342 +vt 0.951940 0.025240 +vt 0.952239 0.025097 +vt 0.952234 0.022443 +vt 0.954130 0.027146 +vt 0.954245 0.026842 +vt 0.613348 0.784228 +vt 0.611905 0.784239 +vt 0.612010 0.785170 +vt 0.613878 0.785154 +vt 0.610262 0.784228 +vt 0.609881 0.785154 +vt 0.952834 0.022653 +vt 0.954254 0.021024 +vt 0.952837 0.024815 +vt 0.953294 0.308354 +vt 0.952195 0.309080 +vt 0.952760 0.309954 +vt 0.954204 0.309004 +vt 0.950676 0.309726 +vt 0.950773 0.310802 +vt 0.956417 0.021023 +vt 0.958048 0.022444 +vt 0.918224 0.856427 +vt 0.916898 0.856485 +vt 0.916993 0.857534 +vt 0.918707 0.857456 +vt 0.915241 0.856280 +vt 0.914845 0.857266 +vt 0.958052 0.024606 +vt 0.956632 0.026235 +vt 0.914243 0.855902 +vt 0.913544 0.856771 +vt 0.025638 0.026806 +vt 0.027130 0.027496 +vt 0.027780 0.026894 +vt 0.025827 0.025990 +vt 0.954469 0.026236 +vt 0.924626 0.540089 +vt 0.923262 0.540021 +vt 0.923243 0.541331 +vt 0.924631 0.541338 +vt 0.921961 0.540110 +vt 0.921923 0.541359 +vt 0.921762 0.541720 +vt 0.923228 0.541699 +vt 0.924770 0.541696 +vt 0.947870 0.298867 +vt 0.949243 0.299304 +vt 0.950692 0.297725 +vt 0.949552 0.296896 +vt 0.950258 0.299674 +vt 0.951473 0.298485 +vt 0.952979 0.297839 +vt 0.952478 0.296809 +vt 0.951620 0.295712 +vt 0.924770 0.535202 +vt 0.923419 0.534847 +vt 0.923313 0.537414 +vt 0.924672 0.537624 +vt 0.922104 0.535223 +vt 0.922006 0.537646 +vt 0.853239 0.155733 +vt 0.854603 0.155372 +vt 0.854417 0.153903 +vt 0.853017 0.154127 +vt 0.855750 0.155795 +vt 0.855529 0.154189 +vt 0.855521 0.152478 +vt 0.854428 0.152331 +vt 0.853009 0.152417 +vt 0.736908 0.560869 +vt 0.737605 0.562466 +vt 0.737614 0.560547 +vt 0.736362 0.563932 +vt 0.736663 0.564461 +vt 0.738183 0.562685 +vt 0.738183 0.560350 +vt 0.854455 0.151466 +vt 0.853007 0.151492 +vt 0.855559 0.151554 +vt 0.855750 0.151228 +vt 0.854526 0.151140 +vt 0.852916 0.151159 +vt 0.026724 0.039518 +vt 0.027481 0.038321 +vt 0.026258 0.040695 +vt 0.736793 0.605835 +vt 0.736853 0.604401 +vt 0.736551 0.604281 +vt 0.736495 0.605882 +vt 0.026958 0.039671 +vt 0.027780 0.038323 +vt 0.953437 0.296384 +vt 0.952693 0.295158 +vt 0.953817 0.297541 +vt 0.954204 0.297556 +vt 0.953801 0.296253 +vt 0.952995 0.294875 +vt 0.734794 0.563011 +vt 0.734580 0.560014 +vt 0.733938 0.561118 +vt 0.733707 0.562374 +vt 0.740113 0.606036 +vt 0.738944 0.607089 +vt 0.739025 0.607512 +vt 0.740460 0.606219 +vt 0.737441 0.607089 +vt 0.737180 0.607512 +vt 0.845585 0.877064 +vt 0.845656 0.875559 +vt 0.845120 0.875139 +vt 0.845036 0.876922 +vt 0.845656 0.879038 +vt 0.845120 0.879262 +vt 0.733033 0.560787 +vt 0.733024 0.562706 +vt 0.734276 0.559321 +vt 0.295740 0.248139 +vt 0.295906 0.246258 +vt 0.295336 0.245913 +vt 0.295131 0.248200 +vt 0.295906 0.249827 +vt 0.295336 0.250247 +vt 0.737720 0.603228 +vt 0.737523 0.602773 +vt 0.736087 0.604065 +vt 0.739223 0.603228 +vt 0.739368 0.602773 +vt 0.739391 0.602285 +vt 0.737205 0.602285 +vt 0.735503 0.603817 +vt 0.835889 0.879250 +vt 0.835889 0.877008 +vt 0.834773 0.877002 +vt 0.834773 0.879376 +vt 0.835861 0.874876 +vt 0.834743 0.874745 +vt 0.833623 0.874888 +vt 0.833651 0.877020 +vt 0.833651 0.879262 +vt 0.843904 0.876902 +vt 0.843994 0.879378 +vt 0.843994 0.875014 +vt 0.842894 0.875217 +vt 0.842809 0.877001 +vt 0.842894 0.879340 +vt 0.293167 0.245830 +vt 0.292963 0.248116 +vt 0.294003 0.248184 +vt 0.294220 0.245763 +vt 0.293167 0.250164 +vt 0.294220 0.250351 +vt 0.292321 0.250181 +vt 0.292076 0.247870 +vt 0.290955 0.247906 +vt 0.291215 0.250352 +vt 0.292321 0.245902 +vt 0.291215 0.245823 +vt 0.290185 0.246048 +vt 0.289939 0.248016 +vt 0.290185 0.250326 +vt 0.736019 0.606031 +vt 0.735422 0.606146 +vt 0.736798 0.607902 +vt 0.740169 0.604434 +vt 0.740529 0.604254 +vt 0.292697 0.247936 +vt 0.292904 0.246275 +vt 0.292904 0.249885 +vt 0.734462 0.563945 +vt 0.833152 0.877059 +vt 0.833152 0.878904 +vt 0.734351 0.564487 +vt 0.736176 0.559308 +vt 0.736441 0.558834 +vt 0.734129 0.558860 +vt 0.611866 0.782063 +vt 0.610439 0.782045 +vt 0.613128 0.782045 +vt 0.613117 0.779235 +vt 0.611876 0.779310 +vt 0.610485 0.779235 +vt 0.917026 0.854222 +vt 0.915589 0.854055 +vt 0.918186 0.854183 +vt 0.918444 0.851102 +vt 0.917307 0.851079 +vt 0.915901 0.850977 +vt 0.951286 0.307063 +vt 0.949993 0.307586 +vt 0.952214 0.306471 +vt 0.951119 0.303944 +vt 0.950192 0.304361 +vt 0.948907 0.304710 +vt 0.024830 0.028793 +vt 0.026100 0.029353 +vt 0.024484 0.026092 +vt 0.023854 0.028211 +vt 0.022677 0.031076 +vt 0.023656 0.031483 +vt 0.024922 0.031869 +vt 0.611912 0.776870 +vt 0.610529 0.776660 +vt 0.613160 0.776660 +vt 0.613289 0.774960 +vt 0.612027 0.775316 +vt 0.610657 0.774960 +vt 0.917576 0.847661 +vt 0.916164 0.847695 +vt 0.918707 0.847820 +vt 0.918662 0.845121 +vt 0.917526 0.844801 +vt 0.916119 0.844996 +vt 0.949246 0.301622 +vt 0.947870 0.301621 +vt 0.950264 0.301555 +vt 0.022606 0.034216 +vt 0.023975 0.034253 +vt 0.021524 0.034158 +vn -0.5130 0.8576 -0.0369 +vn -0.5441 0.8378 -0.0457 +vn -0.5447 0.8387 0.0000 +vn -0.5824 0.8129 -0.0000 +vn -0.3181 0.6344 0.7046 +vn -0.0751 0.7451 0.6627 +vn -0.2301 0.9732 -0.0000 +vn -0.4811 0.8766 0.0000 +vn 0.4490 0.7924 0.4130 +vn 0.3549 0.9349 -0.0000 +vn 0.4490 0.7924 -0.4130 +vn -0.0751 0.7450 -0.6628 +vn -0.3180 0.6344 -0.7045 +vn -0.3180 0.6344 -0.7046 +vn -0.0751 0.7451 -0.6628 +vn 0.2879 0.1906 -0.9385 +vn 0.0689 0.0456 -0.9966 +vn 0.6771 0.4482 -0.5837 +vn 0.9048 0.1036 -0.4130 +vn 0.6565 -0.3603 -0.6627 +vn 0.4597 -0.5406 -0.7046 +vn 0.4597 -0.5407 -0.7045 +vn 0.8059 -0.5920 -0.0000 +vn 0.6189 -0.7854 0.0000 +vn 0.9993 -0.0386 -0.0000 +vn 0.9048 0.1036 0.4130 +vn 0.6565 -0.3603 0.6628 +vn 0.4597 -0.5406 0.7046 +vn 0.6565 -0.3602 0.6627 +vn 0.2879 0.1906 0.9385 +vn 0.0689 0.0456 0.9966 +vn 0.6565 -0.3603 0.6627 +vn 0.9048 0.1037 0.4130 +vn 0.6771 0.4481 0.5837 +vn 0.6771 0.4482 0.5837 +vn -0.3180 0.6344 0.7046 +vn 0.9036 0.3928 -0.1711 +vn 0.8061 0.5335 -0.2562 +vn 0.7352 0.4866 -0.4719 +vn 0.9199 0.2170 -0.3267 +vn 0.7146 0.6782 -0.1711 +vn 0.5592 0.7619 -0.3267 +vn 0.6143 0.7388 -0.2771 +vn 0.7651 0.5063 -0.3978 +vn 0.9202 0.2773 -0.2764 +vn 0.8259 0.5637 0.0142 +vn 0.8225 0.5687 0.0000 +vn 0.7449 0.6671 0.0000 +vn 0.7684 0.6317 0.1027 +vn 0.8259 0.5637 -0.0143 +vn 0.7684 0.6317 -0.1027 +vn 0.8337 0.5518 -0.0203 +vn 0.8251 0.5461 -0.1452 +vn 0.8416 0.5399 -0.0142 +vn 0.8817 0.4605 -0.1027 +vn 0.9048 0.1037 -0.4130 +vn 0.8449 0.5349 0.0000 +vn 0.9052 0.4250 0.0000 +vn 0.8416 0.5399 0.0142 +vn 0.8817 0.4605 0.1027 +vn 0.8337 0.5518 0.0203 +vn 0.8251 0.5461 0.1452 +vn 0.7146 0.6782 0.1712 +vn 0.6646 0.7472 -0.0000 +vn 0.8080 0.5892 0.0000 +vn 0.8167 0.5763 0.0298 +vn 0.8167 0.5763 -0.0298 +vn 0.8330 0.5514 -0.0454 +vn 0.8496 0.5266 -0.0298 +vn 0.9475 0.3198 -0.0000 +vn 0.8581 0.5135 -0.0000 +vn 0.9036 0.3928 0.1711 +vn 0.8496 0.5266 0.0298 +vn 0.8061 0.5335 0.2562 +vn 0.8330 0.5514 0.0454 +vn -0.6335 0.0977 0.7676 +vn 0.0748 0.0013 0.9972 +vn 0.0238 0.0364 0.9991 +vn -0.6308 -0.3031 0.7143 +vn 0.7293 -0.1260 0.6725 +vn 0.6824 0.2770 0.6764 +vn 0.6050 0.3921 0.6930 +vn 0.0019 -0.0002 1.0000 +vn -0.5617 -0.4518 0.6931 +vn 0.9957 0.0931 -0.0000 +vn 0.9199 0.2170 0.3267 +vn 0.9844 0.1758 0.0000 +vn 0.9202 0.2773 0.2764 +vn 0.4748 0.8801 -0.0000 +vn 0.5592 0.7619 0.3267 +vn 0.6143 0.7388 0.2771 +vn 0.5454 0.8382 -0.0000 +vn 0.7352 0.4866 0.4719 +vn 0.7651 0.5062 0.3979 +vn -0.0438 0.7594 0.6492 +vn -0.2038 0.9790 -0.0001 +vn 0.3995 0.9167 -0.0000 +vn 0.5052 0.7793 0.3708 +vn -0.0426 0.7592 -0.6494 +vn 0.5055 0.7792 -0.3707 +vn 0.5055 0.7792 -0.3706 +vn 0.5052 0.7793 0.3707 +vn 0.3182 0.2102 -0.9244 +vn 0.7024 0.4633 -0.5404 +vn 0.7046 -0.3082 -0.6392 +vn 0.9167 0.1702 -0.3614 +vn 0.8495 -0.5277 0.0001 +vn 0.9996 0.0286 -0.0001 +vn 0.9167 0.1702 -0.3615 +vn 0.7030 -0.3095 0.6404 +vn 0.9167 0.1696 0.3618 +vn 0.3157 0.2101 0.9253 +vn 0.7019 0.4631 0.5411 +vn 0.3156 0.2100 0.9253 +vn -0.0438 0.7593 0.6492 +vn 0.7020 0.4632 0.5411 +vn 0.7020 0.4631 0.5411 +vn 0.8515 0.5243 -0.0000 +vn 0.9535 0.3014 -0.0009 +vn 0.7205 0.1419 0.6787 +vn 0.6209 0.3669 -0.6927 +vn 0.7268 0.1231 -0.6758 +vn 0.7841 -0.4730 -0.4018 +vn 0.9353 -0.3538 -0.0007 +vn 0.7855 -0.4692 0.4035 +vn 0.7370 -0.1395 -0.6613 +vn 0.0949 -0.0264 -0.9951 +vn 0.0480 -0.0004 -0.9988 +vn 0.6955 0.2538 -0.6722 +vn -0.6261 0.0725 -0.7763 +vn -0.6137 -0.3321 -0.7163 +vn -0.5438 -0.4742 -0.6924 +vn 0.0261 -0.0352 -0.9990 +vn 0.9830 -0.1836 0.0034 +vn 0.9385 0.3454 0.0010 +vn 0.6824 0.2770 0.6765 +vn 0.7370 -0.1396 -0.6613 +vn -0.9928 0.1196 -0.0000 +vn -0.8774 -0.4798 -0.0002 +vn -0.6138 -0.3321 -0.7163 +vn -0.7614 -0.6483 -0.0001 +vn -0.5748 0.8174 -0.0368 +vn -0.4845 0.7461 -0.4568 +vn -0.7558 0.5690 -0.3239 +vn -0.5130 0.8576 -0.0368 +vn -0.2126 0.9219 -0.3239 +vn 0.2857 0.7204 -0.6320 +vn -0.2427 0.3736 -0.8953 +vn -0.7743 0.0320 -0.6320 +vn -0.5505 -0.8349 -0.0010 +vn -0.3412 -0.6833 -0.6456 +vn -0.3545 -0.6737 0.6484 +vn 0.1352 -0.9145 0.3814 +vn -0.0078 -1.0000 -0.0004 +vn 0.1381 -0.9146 -0.3800 +vn 0.1546 -0.2495 0.9559 +vn -0.3544 -0.6737 0.6484 +vn 0.7206 0.1419 0.6787 +vn 0.7855 -0.4693 0.4035 +vn 0.4424 -0.6853 0.5785 +vn 0.1689 -0.2704 -0.9478 +vn 0.4443 -0.6879 -0.5739 +vn 0.7841 -0.4730 -0.4017 +vn -0.5058 0.8627 0.0000 +vn -0.5748 0.8174 0.0369 +vn -0.5441 0.8378 0.0457 +vn -0.5130 0.8576 0.0368 +vn -0.0440 -0.9990 -0.0000 +vn 0.1018 -0.9070 -0.4086 +vn 0.1353 -0.9145 0.3813 +vn 0.1018 -0.9070 0.4086 +vn -0.3106 -0.7008 0.6422 +vn -0.5369 -0.8436 -0.0000 +vn -0.3106 -0.7008 -0.6422 +vn -0.4845 0.7460 0.4568 +vn -0.2126 0.9219 0.3239 +vn -0.7558 0.5691 0.3239 +vn -0.7743 0.0320 0.6320 +vn -0.2427 0.3736 0.8953 +vn -0.2125 0.9219 0.3239 +vn 0.2856 0.7204 0.6320 +vn 0.9306 -0.3661 0.0000 +vn 0.7872 -0.4618 0.4087 +vn 0.7872 -0.4619 -0.4086 +vn 0.7665 -0.0012 -0.6422 +vn 0.9891 0.1475 0.0000 +vn 0.7665 -0.0012 0.6422 +vn 0.8387 0.5447 0.0000 +vn 0.5930 0.3851 0.7071 +vn 0.5930 0.3851 -0.7071 +vn 0.5082 0.8613 0.0000 +vn 0.2857 0.7204 0.6320 +vn -0.8387 -0.5447 0.0000 +vn -0.5930 -0.3851 -0.7071 +vn -0.5930 -0.3851 0.7071 +vn -0.7743 0.0321 0.6320 +vn -0.9935 -0.1140 0.0000 +vn -0.7743 0.0321 -0.6320 +vn 0.2261 -0.3481 0.9098 +vn 0.0000 0.0000 1.0000 +vn -0.5930 -0.3852 0.7071 +vn 0.5930 0.3852 0.7071 +vn 0.2261 -0.3481 -0.9098 +vn 0.0000 0.0000 -1.0000 +vn 0.5930 0.3852 -0.7071 +vn -0.5930 -0.3852 -0.7071 +vn 0.4433 -0.6826 0.5810 +vn 0.4443 -0.6879 -0.5740 +vn 0.4433 -0.6826 -0.5810 +vn 0.4433 -0.6825 -0.5811 +vn 0.1018 -0.9070 -0.4087 +vn 0.7872 -0.4618 -0.4087 +vn -0.1014 0.9948 0.0000 +vn -0.8676 0.4973 -0.0000 +vn -0.5021 0.8648 -0.0003 +vn -0.3428 0.6316 -0.6954 +vn -0.3454 0.6323 0.6934 +vn -0.4230 0.5887 0.6888 +vn -0.5817 0.8134 -0.0007 +vn -0.4184 0.5862 -0.6937 +vn 0.6497 -0.7602 0.0002 +vn 0.4813 -0.5356 0.6938 +vn 0.4855 -0.5345 -0.6918 +vn 0.4540 -0.5722 -0.6830 +vn 0.6182 -0.7860 0.0007 +vn 0.4467 -0.5723 0.6877 +vn 0.0645 0.0407 -0.9971 +vn 0.0164 -0.0019 -0.9999 +vn 0.4540 -0.5722 -0.6831 +vn 0.0583 0.0422 0.9974 +vn -0.3454 0.6324 0.6934 +vn 0.7029 -0.3095 0.6404 +vn 0.4813 -0.5357 0.6938 +vn 0.0044 0.0039 1.0000 +vn -0.4230 0.5887 0.6889 +vn -0.7360 0.6770 -0.0006 +vn -0.5136 0.4640 -0.7218 +vn -0.5184 0.4717 0.7133 +vn -0.9928 0.1196 -0.0001 +vn 0.7557 -0.6550 0.0021 +vn 0.5517 -0.4866 0.6774 +vn 0.5594 -0.4910 -0.6678 +vn 0.0353 -0.0392 -0.9986 +vn 0.0185 -0.0247 0.9995 +usemtl Scene_-_Root +s off +f 24955/24784/17202 24952/24785/17203 24981/24786/17204 +f 24952/24785/17203 24983/24787/17205 24981/24786/17204 +s 1 +f 24784/24788/17206 24785/24789/17207 24786/24790/17208 +f 24784/24788/17206 24786/24790/17208 24787/24791/17209 +f 24785/24789/17207 24788/24792/17210 24789/24793/17211 +f 24785/24789/17207 24789/24793/17211 24786/24790/17208 +f 24786/24790/17208 24789/24793/17211 24790/24794/17212 +f 24786/24790/17208 24790/24794/17212 24791/24795/17213 +f 24787/24791/17209 24786/24790/17208 24791/24795/17213 +f 24787/24791/17209 24791/24795/17213 24792/24796/17214 +f 24793/24797/17215 24794/24798/17216 24795/24799/17217 +f 24793/24797/17215 24795/24799/17217 24796/24800/17218 +f 24794/24798/17216 24797/24801/17212 24798/24802/17219 +f 24794/24798/17216 24798/24802/17219 24795/24799/17217 +f 24795/24799/17217 24798/24802/17219 24799/24803/17220 +f 24795/24799/17217 24799/24803/17220 24800/24804/17221 +f 24796/24800/17218 24795/24799/17217 24800/24804/17221 +f 24796/24800/17218 24800/24804/17221 24801/24805/17222 +f 24802/24806/17223 24803/24807/17221 24804/24808/17224 +f 24802/24806/17223 24804/24808/17224 24805/24809/17225 +f 24803/24807/17221 24806/24810/17220 24807/24811/17226 +f 24803/24807/17221 24807/24811/17226 24804/24808/17224 +f 24804/24808/17224 24807/24811/17226 24808/24812/17227 +f 24804/24808/17224 24808/24812/17227 24809/24813/17228 +f 24805/24809/17225 24804/24808/17224 24809/24813/17228 +f 24805/24809/17225 24809/24813/17228 24810/24814/17229 +f 24811/24815/17229 24812/24816/17230 24813/24817/17231 +f 24811/24815/17229 24813/24817/17231 24814/24818/17232 +f 24815/24819/17233 24816/24820/17234 24817/24821/17235 +f 24815/24819/17233 24817/24821/17235 24818/24822/17231 +f 24813/24817/17231 24819/24823/17236 24820/24824/17210 +f 24813/24817/17231 24820/24824/17210 24821/24825/17207 +f 24814/24818/17232 24813/24817/17231 24821/24825/17207 +f 24814/24818/17232 24821/24825/17207 24822/24826/17237 +f 24823/24827/17238 24824/24828/17239 24825/24829/17240 +f 24823/24827/17238 24825/24829/17240 24826/24830/17241 +f 24824/24828/17239 24827/24831/17242 24828/24832/17243 +f 24824/24828/17239 24828/24832/17243 24825/24829/17240 +f 24825/24829/17240 24828/24832/17243 24829/24833/17244 +f 24825/24829/17240 24829/24833/17244 24830/24834/17245 +f 24826/24830/17241 24825/24829/17240 24830/24834/17245 +f 24826/24830/17241 24830/24834/17245 24831/24835/17246 +f 24832/24836/17247 24833/24837/17248 24834/24838/17249 +f 24832/24836/17247 24834/24838/17249 24835/24839/17250 +f 24833/24837/17248 24836/24840/17251 24837/24841/17252 +f 24833/24837/17248 24837/24841/17252 24834/24838/17249 +f 24834/24838/17249 24837/24841/17252 24838/24842/17212 +f 24834/24838/17249 24838/24842/17212 24839/24843/17211 +f 24835/24839/17250 24834/24838/17249 24839/24843/17211 +f 24835/24839/17250 24839/24843/17211 24840/24844/17210 +f 24836/24840/17251 24841/24845/17253 24842/24846/17254 +f 24836/24840/17251 24842/24846/17254 24837/24841/17252 +f 24841/24845/17253 24843/24847/17255 24844/24848/17256 +f 24841/24845/17253 24844/24848/17256 24842/24846/17254 +f 24842/24846/17254 24844/24848/17256 24845/24849/17257 +f 24842/24846/17254 24845/24849/17257 24846/24850/17219 +f 24837/24841/17252 24842/24846/17254 24846/24850/17219 +f 24837/24841/17252 24846/24850/17219 24838/24842/17212 +f 24843/24847/17255 24847/24851/17258 24848/24852/17259 +f 24843/24847/17255 24848/24852/17259 24844/24848/17256 +f 24847/24851/17258 24849/24853/17260 24850/24854/17261 +f 24847/24851/17258 24850/24854/17261 24848/24852/17259 +f 24848/24852/17259 24850/24854/17261 24816/24820/17234 +f 24848/24852/17259 24816/24820/17234 24851/24855/17226 +f 24844/24848/17256 24848/24852/17259 24851/24855/17226 +f 24844/24848/17256 24851/24855/17226 24845/24849/17257 +f 24849/24853/17260 24852/24856/17262 24853/24857/17263 +f 24849/24853/17260 24853/24857/17263 24850/24854/17261 +f 24852/24856/17262 24832/24836/17247 24835/24839/17250 +f 24852/24856/17262 24835/24839/17250 24853/24857/17263 +f 24853/24857/17263 24835/24839/17250 24840/24844/17210 +f 24853/24857/17263 24840/24844/17210 24817/24821/17235 +f 24850/24854/17261 24853/24857/17263 24817/24821/17235 +f 24850/24854/17261 24817/24821/17235 24816/24820/17234 +f 24854/24858/17264 24855/24859/17265 24856/24860/17266 +f 24854/24858/17264 24856/24860/17266 24857/24861/17267 +f 24855/24859/17265 24827/24831/17242 24858/24862/17268 +f 24855/24859/17265 24858/24862/17268 24856/24860/17266 +f 24856/24860/17266 24858/24862/17268 24836/24840/17251 +f 24856/24860/17266 24836/24840/17251 24833/24837/17248 +f 24857/24861/17267 24856/24860/17266 24833/24837/17248 +f 24857/24861/17267 24833/24837/17248 24832/24836/17247 +f 24827/24831/17242 24824/24828/17239 24859/24863/17269 +f 24827/24831/17242 24859/24863/17269 24858/24862/17268 +f 24824/24828/17239 24823/24827/17238 24860/24864/17270 +f 24824/24828/17239 24860/24864/17270 24859/24863/17269 +f 24859/24863/17269 24860/24864/17270 24843/24847/17255 +f 24859/24863/17269 24843/24847/17255 24841/24845/17253 +f 24858/24862/17268 24859/24863/17269 24841/24845/17253 +f 24858/24862/17268 24841/24845/17253 24836/24840/17251 +f 24823/24827/17238 24861/24865/17271 24862/24866/17272 +f 24823/24827/17238 24862/24866/17272 24860/24864/17270 +f 24861/24865/17271 24863/24867/17273 24864/24868/17274 +f 24861/24865/17271 24864/24868/17274 24862/24866/17272 +f 24862/24866/17272 24864/24868/17274 24849/24853/17260 +f 24862/24866/17272 24849/24853/17260 24847/24851/17258 +f 24860/24864/17270 24862/24866/17272 24847/24851/17258 +f 24860/24864/17270 24847/24851/17258 24843/24847/17255 +f 24863/24867/17273 24865/24869/17275 24866/24870/17276 +f 24863/24867/17273 24866/24870/17276 24864/24868/17274 +f 24865/24869/17275 24854/24858/17264 24857/24861/17267 +f 24865/24869/17275 24857/24861/17267 24866/24870/17276 +f 24866/24870/17276 24857/24861/17267 24832/24836/17247 +f 24866/24870/17276 24832/24836/17247 24852/24856/17262 +f 24864/24868/17274 24866/24870/17276 24852/24856/17262 +f 24864/24868/17274 24852/24856/17262 24849/24853/17260 +f 24867/24871/17277 24868/24872/17278 24869/24873/17279 +f 24867/24871/17277 24869/24873/17279 24870/24874/17280 +f 24868/24872/17278 24871/24875/17281 24872/24876/17282 +f 24868/24872/17278 24872/24876/17282 24869/24873/17279 +f 24869/24873/17279 24872/24876/17282 24873/24877/17283 +f 24869/24873/17279 24873/24877/17283 24874/24878/17284 +f 24870/24874/17280 24869/24873/17279 24874/24878/17284 +f 24870/24874/17280 24874/24878/17284 24875/24879/17285 +f 24863/24867/17273 24861/24865/17271 24876/24880/17286 +f 24863/24867/17273 24876/24880/17286 24877/24881/17287 +f 24861/24865/17271 24823/24827/17238 24826/24830/17241 +f 24861/24865/17271 24826/24830/17241 24876/24880/17286 +f 24876/24880/17286 24826/24830/17241 24831/24835/17246 +f 24876/24880/17286 24831/24835/17246 24878/24882/17288 +f 24877/24881/17287 24876/24880/17286 24878/24882/17288 +f 24877/24881/17287 24878/24882/17288 24879/24883/17289 +f 24827/24831/17242 24855/24859/17265 24880/24884/17290 +f 24827/24831/17242 24880/24884/17290 24828/24832/17243 +f 24855/24859/17265 24854/24858/17264 24881/24885/17291 +f 24855/24859/17265 24881/24885/17291 24880/24884/17290 +f 24880/24884/17290 24881/24885/17291 24882/24886/17292 +f 24880/24884/17290 24882/24886/17292 24883/24887/17293 +f 24828/24832/17243 24880/24884/17290 24883/24887/17293 +f 24828/24832/17243 24883/24887/17293 24829/24833/17244 +f 24854/24858/17264 24865/24869/17275 24884/24888/17294 +f 24854/24858/17264 24884/24888/17294 24881/24885/17291 +f 24865/24869/17275 24863/24867/17273 24877/24881/17287 +f 24865/24869/17275 24877/24881/17287 24884/24888/17294 +f 24884/24888/17294 24877/24881/17287 24879/24883/17289 +f 24884/24888/17294 24879/24883/17289 24885/24889/17295 +f 24881/24885/17291 24884/24888/17294 24885/24889/17295 +f 24881/24885/17291 24885/24889/17295 24882/24886/17292 +f 24886/24890/17296 24887/24891/17297 24888/24892/17298 +f 24886/24890/17296 24888/24892/17298 24889/24893/17299 +f 24887/24891/17297 24890/24894/17300 24891/24895/17301 +f 24887/24891/17297 24891/24895/17301 24888/24892/17298 +f 24892/24896/17298 24893/24897/17302 24829/24833/17244 +f 24892/24896/17298 24829/24833/17244 24883/24887/17293 +f 24894/24898/17303 24892/24896/17298 24883/24887/17293 +f 24894/24898/17303 24883/24887/17293 24882/24886/17292 +f 24895/24899/17300 24896/24900/17304 24897/24901/17305 +f 24895/24899/17300 24897/24901/17305 24898/24902/17302 +f 24896/24900/17304 24899/24903/17306 24900/24904/17307 +f 24896/24900/17304 24900/24904/17307 24897/24901/17305 +f 24901/24905/17305 24902/24906/17307 24831/24835/17246 +f 24901/24905/17305 24831/24835/17246 24830/24834/17245 +f 24893/24897/17302 24901/24905/17305 24830/24834/17245 +f 24893/24897/17302 24830/24834/17245 24829/24833/17244 +f 24903/24907/17306 24904/24908/17308 24905/24909/17309 +f 24903/24907/17306 24905/24909/17309 24906/24910/17310 +f 24904/24908/17308 24907/24911/17311 24908/24912/17312 +f 24904/24908/17308 24908/24912/17312 24905/24909/17309 +f 24909/24913/17309 24910/24914/17312 24879/24883/17289 +f 24909/24913/17309 24879/24883/17289 24878/24882/17288 +f 24902/24906/17307 24909/24913/17309 24878/24882/17288 +f 24902/24906/17307 24878/24882/17288 24831/24835/17246 +f 24907/24911/17311 24911/24915/17313 24912/24916/17314 +f 24907/24911/17311 24912/24916/17314 24908/24912/17312 +f 24913/24917/17315 24914/24918/17316 24915/24919/17303 +f 24913/24917/17315 24915/24919/17303 24916/24920/17317 +f 24917/24921/17318 24894/24898/17303 24882/24886/17292 +f 24917/24921/17318 24882/24886/17292 24885/24889/17295 +f 24910/24914/17312 24917/24921/17318 24885/24889/17295 +f 24910/24914/17312 24885/24889/17295 24879/24883/17289 +f 24918/24922/17283 24919/24923/17319 24920/24924/17320 +f 24918/24922/17283 24920/24924/17320 24921/24925/17321 +f 24919/24923/17319 24922/24926/17322 24923/24927/17323 +f 24919/24923/17319 24923/24927/17323 24920/24924/17320 +f 24920/24924/17320 24923/24927/17323 24924/24928/17324 +f 24920/24924/17320 24924/24928/17324 24925/24929/17325 +f 24921/24925/17321 24920/24924/17320 24925/24929/17325 +f 24921/24925/17321 24925/24929/17325 24926/24930/17326 +f 24927/24931/17327 24928/24932/17328 24929/24933/17329 +f 24927/24931/17327 24929/24933/17329 24930/24934/17330 +f 24928/24932/17328 24931/24935/17331 24932/24936/17332 +f 24928/24932/17328 24932/24936/17332 24929/24933/17329 +f 24929/24933/17329 24932/24936/17332 24933/24937/17333 +f 24929/24933/17329 24933/24937/17333 24934/24938/17334 +f 24930/24934/17330 24929/24933/17329 24934/24938/17334 +f 24930/24934/17330 24934/24938/17334 24935/24939/17322 +f 24936/24940/17281 24937/24941/17335 24938/24942/17336 +f 24936/24940/17281 24938/24942/17336 24939/24943/17337 +f 24937/24941/17335 24940/24944/17338 24941/24945/17330 +f 24937/24941/17335 24941/24945/17330 24938/24942/17336 +f 24938/24942/17336 24941/24945/17330 24922/24926/17322 +f 24938/24942/17336 24922/24926/17322 24919/24923/17319 +f 24939/24943/17337 24938/24942/17336 24919/24923/17319 +f 24939/24943/17337 24919/24923/17319 24918/24922/17283 +f 24942/24946/17331 24943/24947/17339 24944/24948/17340 +f 24942/24946/17331 24944/24948/17340 24945/24949/17341 +f 24943/24947/17339 24946/24950/17277 24947/24951/17280 +f 24943/24947/17339 24947/24951/17280 24944/24948/17340 +f 24944/24948/17340 24947/24951/17280 24948/24952/17285 +f 24944/24948/17340 24948/24952/17285 24949/24953/17342 +f 24945/24949/17341 24944/24948/17340 24949/24953/17342 +f 24945/24949/17341 24949/24953/17342 24950/24954/17333 +f 24951/24955/17343 24952/24785/17203 24953/24956/17344 +f 24951/24955/17343 24953/24956/17344 24954/24957/17345 +f 24952/24785/17203 24955/24784/17346 24956/24958/17347 +f 24952/24785/17203 24956/24958/17347 24953/24956/17344 +f 24953/24956/17344 24956/24958/17347 24957/24959/17348 +f 24953/24956/17344 24957/24959/17348 24958/24960/17349 +f 24954/24957/17345 24953/24956/17344 24958/24960/17349 +f 24954/24957/17345 24958/24960/17349 24959/24961/17350 +f 24950/24954/17333 24949/24953/17342 24960/24962/17351 +f 24950/24954/17333 24960/24962/17351 24961/24963/17352 +f 24949/24953/17342 24948/24952/17285 24962/24964/17353 +f 24949/24953/17342 24962/24964/17353 24960/24962/17351 +f 24960/24962/17351 24962/24964/17353 24963/24965/17354 +f 24960/24962/17351 24963/24965/17354 24964/24966/17355 +f 24961/24963/17352 24960/24962/17351 24964/24966/17355 +f 24961/24963/17352 24964/24966/17355 24965/24967/17356 +f 24875/24879/17285 24874/24878/17284 24966/24968/17357 +f 24875/24879/17285 24966/24968/17357 24967/24969/17358 +f 24874/24878/17284 24873/24877/17283 24968/24970/17359 +f 24874/24878/17284 24968/24970/17359 24966/24968/17357 +f 24969/24971/17357 24970/24972/17321 24971/24973/17360 +f 24969/24971/17357 24971/24973/17360 24972/24974/17361 +f 24967/24969/17358 24966/24968/17357 24973/24975/17361 +f 24967/24969/17358 24973/24975/17361 24974/24976/17354 +f 24935/24939/17322 24934/24938/17334 24975/24977/17362 +f 24935/24939/17322 24975/24977/17362 24976/24978/17323 +f 24934/24938/17334 24933/24937/17333 24977/24979/17352 +f 24934/24938/17334 24977/24979/17352 24975/24977/17362 +f 24975/24977/17362 24977/24979/17352 24978/24980/17356 +f 24975/24977/17362 24978/24980/17356 24979/24981/17363 +f 24976/24978/17323 24975/24977/17362 24979/24981/17363 +f 24976/24978/17323 24979/24981/17363 24980/24982/17364 +f 24955/24784/17346 24981/24786/17204 24982/24983/17365 +f 24952/24785/17203 24951/24955/17343 24983/24787/17205 +f 24981/24786/17204 24983/24787/17205 24984/24984/17366 +f 24981/24786/17204 24984/24984/17366 24985/24985/17367 +f 24982/24983/17365 24981/24786/17204 24985/24985/17367 +f 24982/24983/17365 24985/24985/17367 24986/24986/17368 +f 24987/24987/17356 24988/24988/17355 24989/24989/17369 +f 24987/24987/17356 24989/24989/17369 24990/24990/17370 +f 24988/24988/17355 24991/24991/17371 24992/24992/17372 +f 24988/24988/17355 24992/24992/17372 24989/24989/17369 +f 24993/24993/17369 24994/24994/17372 24995/24995/17373 +f 24993/24993/17369 24995/24995/17373 24996/24996/17374 +f 24997/24997/17370 24993/24993/17369 24996/24996/17374 +f 24997/24997/17370 24996/24996/17374 24998/24998/17375 +f 24986/24986/17368 24985/24985/17367 24999/24999/17376 +f 24986/24986/17368 24999/24999/17376 25000/25000/17377 +f 24985/24985/17367 24984/24984/17366 25001/25001/17378 +f 24985/24985/17367 25001/25001/17378 24999/24999/17376 +f 25002/25002/17376 25003/25003/17378 25004/25004/17379 +f 25002/25002/17376 25004/25004/17379 25005/25005/17380 +f 25006/25006/17381 25002/25002/17376 25005/25005/17380 +f 25006/25006/17381 25005/25005/17380 25007/25007/17382 +f 24971/24973/17360 25008/25008/17325 25009/25009/17383 +f 24971/24973/17360 25009/25009/17383 25010/25010/17384 +f 25008/25008/17325 25011/25011/17364 25012/25012/17385 +f 25008/25008/17325 25012/25012/17385 25009/25009/17383 +f 25009/25009/17383 25012/25012/17385 25013/25013/17386 +f 25009/25009/17383 25013/25013/17386 25014/25014/17387 +f 25010/25010/17384 25009/25009/17383 25014/25014/17387 +f 25010/25010/17384 25014/25014/17387 25015/25015/17388 +f 25016/25016/17388 25017/25017/17387 25018/25018/17389 +f 25016/25016/17388 25018/25018/17389 25019/25019/17390 +f 25017/25017/17387 25020/25020/17386 25021/25021/17391 +f 25017/25017/17387 25021/25021/17391 25018/25018/17389 +f 25018/25018/17389 25021/25021/17391 25022/25022/17348 +f 25018/25018/17389 25022/25022/17348 25023/25023/17392 +f 25019/25019/17390 25018/25018/17389 25023/25023/17392 +f 25019/25019/17390 25023/25023/17392 25024/25024/17393 +f 24998/24998/17375 24996/24996/17374 25025/25025/17394 +f 24998/24998/17375 25025/25025/17394 25026/25026/17395 +f 24996/24996/17374 24995/24995/17373 25027/25027/17396 +f 24996/24996/17374 25027/25027/17396 25025/25025/17394 +f 25025/25025/17394 25027/25027/17396 25028/25028/17397 +f 25025/25025/17394 25028/25028/17397 25029/25029/17398 +f 25026/25026/17395 25025/25025/17394 25029/25029/17398 +f 25026/25026/17395 25029/25029/17398 25030/25030/17399 +f 25031/25031/17373 25032/25032/17400 25033/25033/17401 +f 25031/25031/17373 25033/25033/17401 25034/25034/17402 +f 25032/25032/17400 25035/25035/17388 25036/25036/17403 +f 25032/25032/17400 25036/25036/17403 25033/25033/17401 +f 25033/25033/17401 25036/25036/17403 25007/25007/17382 +f 25033/25033/17401 25007/25007/17382 25005/25005/17380 +f 25034/25034/17402 25033/25033/17401 25005/25005/17380 +f 25034/25034/17402 25005/25005/17380 25004/25004/17379 +f 25037/25037/17386 25038/25038/17404 25039/25039/17405 +f 25037/25037/17386 25039/25039/17405 25040/25040/17406 +f 25038/25038/17404 25041/25041/17375 25042/25042/17407 +f 25038/25038/17404 25042/25042/17407 25039/25039/17405 +f 25039/25039/17405 25042/25042/17407 25043/25043/17350 +f 25039/25039/17405 25043/25043/17350 25044/25044/17349 +f 25040/25040/17406 25039/25039/17405 25044/25044/17349 +f 25040/25040/17406 25044/25044/17349 25045/25045/17348 +f 24991/24991/17371 24972/24974/17361 25046/25046/17408 +f 24991/24991/17371 25046/25046/17408 24992/24992/17372 +f 24972/24974/17361 24971/24973/17360 25010/25010/17384 +f 24972/24974/17361 25010/25010/17384 25046/25046/17408 +f 25046/25046/17408 25010/25010/17384 25015/25015/17388 +f 25046/25046/17408 25015/25015/17388 25047/25047/17400 +f 24992/24992/17372 25046/25046/17408 25047/25047/17400 +f 24992/24992/17372 25047/25047/17400 25048/25048/17373 +f 25011/25011/17364 25049/25049/17409 25050/25050/17410 +f 25011/25011/17364 25050/25050/17410 25012/25012/17385 +f 25049/25049/17409 24987/24987/17356 24990/24990/17370 +f 25049/25049/17409 24990/24990/17370 25050/25050/17410 +f 25051/25051/17411 25052/25052/17412 25041/25041/17375 +f 25051/25051/17411 25041/25041/17375 25038/25038/17404 +f 25053/25053/17413 25051/25051/17411 25038/25038/17404 +f 25053/25053/17413 25038/25038/17404 25037/25037/17386 +f 24955/24784/17346 24982/24983/17365 25054/25054/17414 +f 24955/24784/17346 25054/25054/17414 24956/24958/17347 +f 24982/24983/17365 24986/24986/17368 25000/25000/17377 +f 24982/24983/17365 25000/25000/17377 25054/25054/17414 +f 25055/25055/17414 25056/25056/17377 25024/25024/17393 +f 25055/25055/17414 25024/25024/17393 25023/25023/17392 +f 24956/24958/17347 25054/25054/17414 25057/25057/17392 +f 24956/24958/17347 25057/25057/17392 24957/24959/17348 +f 24984/24984/17366 24983/24787/17205 25058/25058/17415 +f 24984/24984/17366 25058/25058/17415 25001/25001/17378 +f 24983/24787/17205 24951/24955/17343 24954/24957/17345 +f 24983/24787/17205 24954/24957/17345 25058/25058/17415 +f 25058/25058/17415 24954/24957/17345 24959/24961/17350 +f 25058/25058/17415 24959/24961/17350 25059/25059/17398 +f 25001/25001/17378 25058/25058/17415 25059/25059/17398 +f 25001/25001/17378 25059/25059/17398 25060/25060/17379 +f 24890/24894/17300 24887/24891/17297 25061/25061/17416 +f 24890/24894/17300 25061/25061/17416 25062/25062/17417 +f 24887/24891/17297 24886/24890/17296 25063/25063/17418 +f 24887/24891/17297 25063/25063/17418 25061/25061/17416 +f 25061/25061/17416 25063/25063/17418 25064/25064/17419 +f 25061/25061/17416 25064/25064/17419 25065/25065/17420 +f 25062/25062/17417 25061/25061/17416 25065/25065/17420 +f 25062/25062/17417 25065/25065/17420 25066/25066/17421 +f 24907/24911/17311 24904/24908/17308 25067/25067/17422 +f 24907/24911/17311 25067/25067/17422 25068/25068/17423 +f 24904/24908/17308 24903/24907/17306 25069/25069/17424 +f 24904/24908/17308 25069/25069/17424 25067/25067/17422 +f 25067/25067/17422 25069/25069/17424 25070/25070/17425 +f 25067/25067/17422 25070/25070/17425 25071/25071/17426 +f 25068/25068/17423 25067/25067/17422 25071/25071/17426 +f 25068/25068/17423 25071/25071/17426 25072/25072/17427 +f 24899/24903/17306 24896/24900/17304 25073/25073/17428 +f 24899/24903/17306 25073/25073/17428 25074/25074/17424 +f 24896/24900/17304 24895/24899/17300 25075/25075/17417 +f 24896/24900/17304 25075/25075/17417 25073/25073/17428 +f 25073/25073/17428 25075/25075/17417 25076/25076/17421 +f 25073/25073/17428 25076/25076/17421 25077/25077/17429 +f 25074/25074/17424 25073/25073/17428 25077/25077/17429 +f 25074/25074/17424 25077/25077/17429 25078/25078/17430 +f 24914/24918/17316 24913/24917/17315 25079/25079/17431 +f 24914/24918/17316 25079/25079/17431 25080/25080/17432 +f 24913/24917/17315 25081/25081/17433 25082/25082/17434 +f 24913/24917/17315 25082/25082/17434 25079/25079/17431 +f 25079/25079/17431 25082/25082/17434 25083/25083/17427 +f 25079/25079/17431 25083/25083/17427 25084/25084/17435 +f 25080/25080/17432 25079/25079/17431 25084/25084/17435 +f 25080/25080/17432 25084/25084/17435 25085/25085/17436 +f 25066/25066/17421 25065/25065/17420 25086/25086/17437 +f 25066/25066/17421 25086/25086/17437 25087/25087/17438 +f 25065/25065/17420 25064/25064/17419 25088/25088/17439 +f 25065/25065/17420 25088/25088/17439 25086/25086/17437 +f 25086/25086/17437 25088/25088/17439 25089/25089/17277 +f 25086/25086/17437 25089/25089/17277 25090/25090/17440 +f 25087/25087/17438 25086/25086/17437 25090/25090/17440 +f 25087/25087/17438 25090/25090/17440 25091/25091/17331 +f 25072/25072/17427 25071/25071/17426 25092/25092/17441 +f 25072/25072/17427 25092/25092/17441 25093/25093/17442 +f 25071/25071/17426 25070/25070/17425 25094/25094/17443 +f 25071/25071/17426 25094/25094/17443 25092/25092/17441 +f 25092/25092/17441 25094/25094/17443 25095/25095/17327 +f 25092/25092/17441 25095/25095/17327 25096/25096/17335 +f 25093/25093/17442 25092/25092/17441 25096/25096/17335 +f 25093/25093/17442 25096/25096/17335 25097/25097/17281 +f 25078/25078/17430 25077/25077/17429 25098/25098/17444 +f 25078/25078/17430 25098/25098/17444 25099/25099/17443 +f 25077/25077/17429 25076/25076/17421 25100/25100/17438 +f 25077/25077/17429 25100/25100/17438 25098/25098/17444 +f 25098/25098/17444 25100/25100/17438 24931/24935/17331 +f 25098/25098/17444 24931/24935/17331 24928/24932/17328 +f 25099/25099/17443 25098/25098/17444 24928/24932/17328 +f 25099/25099/17443 24928/24932/17328 24927/24931/17327 +f 25085/25085/17436 25084/25084/17435 25101/25101/17445 +f 25085/25085/17436 25101/25101/17445 25102/25102/17439 +f 25084/25084/17435 25083/25083/17427 25103/25103/17442 +f 25084/25084/17435 25103/25103/17442 25101/25101/17445 +f 25101/25101/17445 25103/25103/17442 24871/24875/17281 +f 25101/25101/17445 24871/24875/17281 24868/24872/17278 +f 25102/25102/17439 25101/25101/17445 24868/24872/17278 +f 25102/25102/17439 24868/24872/17278 24867/24871/17277 +o Cube.041__0 +v -0.517655 -0.277498 -0.167407 +v -0.517228 -0.278887 -0.160301 +v -0.464664 -0.269890 -0.159812 +v -0.464664 -0.268427 -0.166914 +v -0.516067 -0.281940 -0.154253 +v -0.464664 -0.273141 -0.153775 +v -0.412100 -0.278887 -0.160301 +v -0.411672 -0.277498 -0.167408 +v -0.413261 -0.281940 -0.154253 +v -0.561675 -0.304183 -0.176524 +v -0.561563 -0.304710 -0.168886 +v -0.517655 -0.277498 -0.167407 +v -0.517717 -0.276939 -0.175043 +v -0.560781 -0.305880 -0.161768 +v -0.517228 -0.278887 -0.160301 +v -0.558657 -0.308337 -0.155688 +v -0.516067 -0.281940 -0.154253 +v -0.558657 -0.308337 -0.155688 +v -0.554523 -0.312723 -0.151165 +v -0.513806 -0.287488 -0.149794 +v -0.516067 -0.281940 -0.154253 +v -0.464664 -0.279076 -0.149337 +v -0.464664 -0.273141 -0.153775 +v -0.415522 -0.287488 -0.149794 +v -0.413261 -0.281940 -0.154253 +v -0.374805 -0.312723 -0.151165 +v -0.370671 -0.308337 -0.155688 +v -0.370671 -0.308337 -0.155688 +v -0.368547 -0.305880 -0.161768 +v -0.367765 -0.304710 -0.168886 +v -0.411612 -0.276939 -0.175043 +v -0.367653 -0.304183 -0.176524 +v -0.464664 -0.267858 -0.174550 +v -0.517717 -0.276939 -0.175043 +v -0.340512 -0.348553 -0.171269 +v -0.341515 -0.349369 -0.164131 +v -0.332504 -0.401855 -0.166984 +v -0.331428 -0.401466 -0.174145 +v -0.344235 -0.350865 -0.157999 +v -0.335423 -0.402192 -0.160789 +v -0.341515 -0.454341 -0.169836 +v -0.340512 -0.454380 -0.177020 +v -0.344235 -0.453519 -0.163578 +v -0.340512 -0.348553 -0.171269 +v -0.340369 -0.348076 -0.178909 +v -0.341515 -0.349369 -0.164131 +v -0.344235 -0.350865 -0.157999 +v -0.349532 -0.353380 -0.153375 +v -0.344235 -0.350865 -0.157999 +v -0.341108 -0.402450 -0.156041 +v -0.335423 -0.402192 -0.160789 +v -0.341108 -0.402450 -0.156041 +v -0.349532 -0.451519 -0.158708 +v -0.344235 -0.453519 -0.163578 +v -0.349532 -0.451519 -0.158708 +v -0.374805 -0.492177 -0.160918 +v -0.370671 -0.496047 -0.165889 +v -0.370671 -0.496047 -0.165889 +v -0.368547 -0.497830 -0.172200 +v -0.367765 -0.498222 -0.179403 +v -0.340369 -0.454025 -0.184667 +v -0.367653 -0.497918 -0.187052 +v -0.331275 -0.401051 -0.181788 +v -0.340369 -0.348076 -0.178909 +v -0.411672 -0.525435 -0.180882 +v -0.412100 -0.524823 -0.173667 +v -0.464664 -0.533821 -0.174155 +v -0.464664 -0.534506 -0.181375 +v -0.413261 -0.522444 -0.167324 +v -0.464664 -0.531242 -0.167802 +v -0.517228 -0.524823 -0.173666 +v -0.517655 -0.525435 -0.180882 +v -0.516067 -0.522444 -0.167324 +v -0.367653 -0.497918 -0.187052 +v -0.367765 -0.498222 -0.179403 +v -0.411612 -0.525162 -0.188533 +v -0.368547 -0.497830 -0.172200 +v -0.370671 -0.496047 -0.165889 +v -0.415522 -0.517412 -0.162289 +v -0.413261 -0.522444 -0.167324 +v -0.464664 -0.525824 -0.162746 +v -0.464664 -0.531242 -0.167802 +v -0.513806 -0.517412 -0.162289 +v -0.516067 -0.522444 -0.167324 +v -0.554523 -0.492177 -0.160918 +v -0.558657 -0.496047 -0.165889 +v -0.558657 -0.496047 -0.165889 +v -0.560781 -0.497830 -0.172200 +v -0.561563 -0.498222 -0.179403 +v -0.517717 -0.525162 -0.188533 +v -0.561675 -0.497918 -0.187052 +v -0.464664 -0.534243 -0.189026 +v -0.588815 -0.454380 -0.177020 +v -0.587813 -0.454341 -0.169836 +v -0.596824 -0.401855 -0.166984 +v -0.597900 -0.401466 -0.174145 +v -0.585093 -0.453519 -0.163578 +v -0.593905 -0.402192 -0.160789 +v -0.587813 -0.349369 -0.164131 +v -0.588815 -0.348553 -0.171269 +v -0.585093 -0.350865 -0.157999 +v -0.588815 -0.454380 -0.177020 +v -0.588959 -0.454025 -0.184667 +v -0.587813 -0.454341 -0.169836 +v -0.585093 -0.453519 -0.163578 +v -0.579796 -0.451519 -0.158708 +v -0.585093 -0.453519 -0.163578 +v -0.588220 -0.402450 -0.156041 +v -0.593905 -0.402192 -0.160789 +v -0.579796 -0.353380 -0.153375 +v -0.585093 -0.350865 -0.157999 +v -0.588959 -0.348076 -0.178909 +v -0.598054 -0.401051 -0.181788 +v -0.588959 -0.454025 -0.184667 +v -0.416034 -0.423571 -0.149929 +v -0.412476 -0.402843 -0.148802 +v -0.414148 -0.402908 -0.147603 +v -0.417592 -0.422982 -0.148694 +v -0.416034 -0.382116 -0.147676 +v -0.417592 -0.382835 -0.146512 +v -0.415921 -0.402974 -0.146404 +v -0.419245 -0.422368 -0.147458 +v -0.419245 -0.383579 -0.145350 +v -0.424990 -0.442405 -0.151949 +v -0.413831 -0.424454 -0.150973 +v -0.426709 -0.440745 -0.150862 +v -0.410111 -0.402789 -0.149796 +v -0.413831 -0.381124 -0.148618 +v -0.424990 -0.363173 -0.147643 +v -0.426709 -0.364942 -0.146742 +v -0.427925 -0.366203 -0.145608 +v -0.429215 -0.367509 -0.144477 +v -0.431158 -0.369410 -0.143584 +v -0.421735 -0.384643 -0.144411 +v -0.418594 -0.403028 -0.145411 +v -0.421735 -0.421412 -0.146410 +v -0.429215 -0.438438 -0.148331 +v -0.431158 -0.436645 -0.147238 +v -0.427925 -0.439614 -0.149598 +v -0.501040 -0.317626 -0.146348 +v -0.464664 -0.311399 -0.146009 +v -0.464664 -0.299453 -0.145925 +v -0.505787 -0.306492 -0.146307 +v -0.428288 -0.317626 -0.146348 +v -0.423542 -0.306492 -0.146307 +v -0.464664 -0.288198 -0.146846 +v -0.510237 -0.295999 -0.147270 +v -0.419091 -0.295999 -0.147271 +v -0.523032 -0.344448 -0.147725 +v -0.496584 -0.328056 -0.146834 +v -0.531181 -0.336306 -0.147363 +v -0.464664 -0.322592 -0.146537 +v -0.432744 -0.328056 -0.146834 +v -0.406296 -0.344448 -0.147725 +v -0.398147 -0.336306 -0.147363 +v -0.389468 -0.327610 -0.147455 +v -0.381331 -0.319402 -0.148542 +v -0.547997 -0.319402 -0.148542 +v -0.539860 -0.327610 -0.147455 +v -0.379439 -0.366402 -0.148999 +v -0.373203 -0.402725 -0.150973 +v -0.361270 -0.402695 -0.151536 +v -0.368320 -0.361633 -0.149304 +v -0.379439 -0.439048 -0.152947 +v -0.368320 -0.443757 -0.153767 +v -0.350081 -0.402612 -0.153064 +v -0.357893 -0.357106 -0.150591 +v -0.357893 -0.448117 -0.155538 +v -0.389880 -0.370857 -0.149160 +v -0.384408 -0.402730 -0.150892 +v -0.389880 -0.434603 -0.152624 +v -0.406296 -0.461012 -0.154060 +v -0.398147 -0.469145 -0.154582 +v -0.389468 -0.477780 -0.155616 +v -0.381331 -0.485822 -0.157587 +v -0.428288 -0.487825 -0.155597 +v -0.464664 -0.494052 -0.155936 +v -0.464664 -0.505937 -0.157146 +v -0.423542 -0.498897 -0.156764 +v -0.501040 -0.487825 -0.155597 +v -0.505787 -0.498897 -0.156764 +v -0.464664 -0.517026 -0.159282 +v -0.419091 -0.509225 -0.158858 +v -0.510237 -0.509225 -0.158859 +v -0.432744 -0.477404 -0.154950 +v -0.464664 -0.482868 -0.155247 +v -0.496584 -0.477404 -0.154950 +v -0.523032 -0.461012 -0.154060 +v -0.531181 -0.469145 -0.154582 +v -0.539860 -0.477780 -0.155616 +v -0.547997 -0.485822 -0.157587 +v -0.549889 -0.439048 -0.152946 +v -0.556125 -0.402725 -0.150973 +v -0.568058 -0.402695 -0.151536 +v -0.561009 -0.443757 -0.153767 +v -0.549889 -0.366402 -0.148998 +v -0.561009 -0.361633 -0.149304 +v -0.579247 -0.402612 -0.153064 +v -0.571435 -0.448117 -0.155537 +v -0.571435 -0.357106 -0.150591 +v -0.539448 -0.434603 -0.152624 +v -0.544920 -0.402730 -0.150892 +v -0.539448 -0.370857 -0.149160 +v -0.487852 -0.348508 -0.147482 +v -0.464664 -0.344539 -0.147266 +v -0.464664 -0.339114 -0.147298 +v -0.490006 -0.343452 -0.147533 +v -0.441476 -0.348508 -0.147482 +v -0.439322 -0.343452 -0.147533 +v -0.464664 -0.331860 -0.147023 +v -0.492893 -0.336692 -0.147286 +v -0.436435 -0.336692 -0.147286 +v -0.504339 -0.363173 -0.147643 +v -0.486361 -0.352031 -0.147037 +v -0.507065 -0.360416 -0.148129 +v -0.464664 -0.348317 -0.146835 +v -0.442967 -0.352031 -0.147037 +v -0.422263 -0.360416 -0.148129 +v -0.418324 -0.356466 -0.148241 +v -0.413045 -0.351188 -0.148074 +v -0.516283 -0.351188 -0.148074 +v -0.511003 -0.356466 -0.148241 +v -0.410338 -0.379601 -0.149171 +v -0.406362 -0.402755 -0.150430 +v -0.400947 -0.402737 -0.150755 +v -0.405292 -0.377433 -0.149380 +v -0.410338 -0.425909 -0.151688 +v -0.405292 -0.428042 -0.152130 +v -0.393688 -0.402731 -0.150875 +v -0.398528 -0.374543 -0.149343 +v -0.398528 -0.430918 -0.152407 +v -0.422263 -0.445094 -0.152731 +v -0.418324 -0.449008 -0.153270 +v -0.413045 -0.454273 -0.153676 +v -0.441476 -0.457001 -0.153378 +v -0.464664 -0.460971 -0.153594 +v -0.464664 -0.466360 -0.154213 +v -0.439322 -0.462022 -0.153977 +v -0.487852 -0.457001 -0.153378 +v -0.490006 -0.462022 -0.153977 +v -0.464664 -0.473602 -0.154726 +v -0.436435 -0.468770 -0.154464 +v -0.492893 -0.468770 -0.154464 +v -0.442967 -0.453547 -0.152554 +v -0.464664 -0.457262 -0.152756 +v -0.486361 -0.453547 -0.152554 +v -0.504339 -0.442405 -0.151949 +v -0.507065 -0.445094 -0.152731 +v -0.511003 -0.449008 -0.153270 +v -0.516283 -0.454273 -0.153676 +v -0.518991 -0.425909 -0.151688 +v -0.522966 -0.402755 -0.150430 +v -0.528381 -0.402737 -0.150755 +v -0.524036 -0.428042 -0.152130 +v -0.518991 -0.379601 -0.149171 +v -0.524036 -0.377433 -0.149380 +v -0.535640 -0.402731 -0.150875 +v -0.530801 -0.430918 -0.152407 +v -0.530801 -0.374543 -0.149343 +v -0.515497 -0.424454 -0.150973 +v -0.519216 -0.402789 -0.149796 +v -0.515497 -0.381124 -0.148618 +v -0.470248 -0.390140 -0.082530 +v -0.470246 -0.389968 -0.083600 +v -0.464664 -0.390985 -0.083786 +v -0.464664 -0.391140 -0.082815 +v -0.470239 -0.390201 -0.085151 +v -0.464664 -0.391212 -0.085220 +v -0.459082 -0.389968 -0.083600 +v -0.459080 -0.390140 -0.082530 +v -0.459089 -0.390201 -0.085151 +v -0.475461 -0.387820 -0.080243 +v -0.475462 -0.387138 -0.081675 +v -0.470247 -0.390698 -0.081414 +v -0.475458 -0.386916 -0.083044 +v -0.475446 -0.387170 -0.084943 +v -0.475418 -0.387917 -0.087965 +v -0.470226 -0.390858 -0.087707 +v -0.464664 -0.391839 -0.087621 +v -0.459102 -0.390858 -0.087707 +v -0.453910 -0.387917 -0.087965 +v -0.453882 -0.387170 -0.084943 +v -0.453869 -0.386916 -0.083044 +v -0.453866 -0.387138 -0.081675 +v -0.459081 -0.390698 -0.081414 +v -0.453866 -0.387820 -0.080243 +v -0.464664 -0.391657 -0.081804 +v -0.485420 -0.451405 -0.151441 +v -0.464664 -0.454958 -0.151634 +v -0.464664 -0.453378 -0.150346 +v -0.484756 -0.449937 -0.150159 +v -0.443907 -0.451405 -0.151441 +v -0.444572 -0.449937 -0.150159 +v -0.464664 -0.451738 -0.149054 +v -0.484050 -0.448413 -0.148873 +v -0.445278 -0.448413 -0.148873 +v -0.502619 -0.440745 -0.150862 +v -0.446340 -0.446100 -0.147751 +v -0.464664 -0.449252 -0.147923 +v -0.482987 -0.446100 -0.147751 +v -0.500113 -0.438438 -0.148331 +v -0.498170 -0.436645 -0.147238 +v -0.501403 -0.439614 -0.149598 +v -0.443907 -0.354282 -0.146163 +v -0.464664 -0.350729 -0.145970 +v -0.464664 -0.352439 -0.144860 +v -0.444572 -0.355880 -0.145047 +v -0.485420 -0.354282 -0.146163 +v -0.484756 -0.355880 -0.145047 +v -0.464664 -0.354210 -0.143754 +v -0.445278 -0.357535 -0.143935 +v -0.484050 -0.357535 -0.143934 +v -0.502619 -0.364942 -0.146742 +v -0.501403 -0.366203 -0.145608 +v -0.500113 -0.367509 -0.144477 +v -0.498170 -0.369410 -0.143584 +v -0.482987 -0.359955 -0.143070 +v -0.464664 -0.356803 -0.142899 +v -0.446340 -0.359955 -0.143070 +v -0.513294 -0.382116 -0.147676 +v -0.516852 -0.402843 -0.148802 +v -0.515180 -0.402908 -0.147603 +v -0.511736 -0.382835 -0.146512 +v -0.513294 -0.423571 -0.149929 +v -0.511736 -0.422982 -0.148694 +v -0.513406 -0.402974 -0.146404 +v -0.510083 -0.383579 -0.145350 +v -0.510083 -0.422368 -0.147458 +v -0.507593 -0.421412 -0.146410 +v -0.510735 -0.403028 -0.145411 +v -0.507593 -0.384643 -0.144411 +v -0.477478 -0.371354 -0.138353 +v -0.464664 -0.369013 -0.138213 +v -0.464664 -0.365113 -0.141129 +v -0.479414 -0.367709 -0.141283 +v -0.451850 -0.371354 -0.138353 +v -0.449914 -0.367709 -0.141283 +v -0.464664 -0.360683 -0.142316 +v -0.481363 -0.363573 -0.142475 +v -0.447966 -0.363573 -0.142475 +v -0.484989 -0.380311 -0.132023 +v -0.475779 -0.373168 -0.132348 +v -0.477478 -0.371354 -0.138353 +v -0.487982 -0.378422 -0.138924 +v -0.475779 -0.373168 -0.132348 +v -0.464664 -0.371129 -0.132361 +v -0.464664 -0.369013 -0.138213 +v -0.477478 -0.371354 -0.138353 +v -0.453549 -0.373168 -0.132348 +v -0.451850 -0.371354 -0.138353 +v -0.444340 -0.380311 -0.132023 +v -0.441345 -0.378422 -0.138924 +v -0.441345 -0.378422 -0.138924 +v -0.437737 -0.375492 -0.141777 +v -0.434135 -0.372244 -0.142955 +v -0.495193 -0.372244 -0.142955 +v -0.491592 -0.375492 -0.141777 +v -0.487982 -0.378422 -0.138924 +v -0.435113 -0.389764 -0.140152 +v -0.433129 -0.403265 -0.141198 +v -0.427788 -0.403133 -0.143511 +v -0.430254 -0.388017 -0.142603 +v -0.435113 -0.416801 -0.141621 +v -0.430254 -0.418260 -0.144247 +v -0.422705 -0.403069 -0.144659 +v -0.425560 -0.386211 -0.143732 +v -0.425560 -0.419927 -0.145565 +v -0.444340 -0.380311 -0.132023 +v -0.439424 -0.391666 -0.135719 +v -0.435113 -0.389764 -0.140152 +v -0.441345 -0.378422 -0.138924 +v -0.438052 -0.403496 -0.137117 +v -0.433129 -0.403265 -0.141198 +v -0.439424 -0.415413 -0.137009 +v -0.435113 -0.416801 -0.141621 +v -0.444340 -0.427120 -0.134566 +v -0.441345 -0.428213 -0.141630 +v -0.441345 -0.428213 -0.141630 +v -0.437737 -0.430802 -0.144783 +v -0.434135 -0.433897 -0.146306 +v -0.451850 -0.435303 -0.141828 +v -0.464664 -0.437645 -0.141943 +v -0.464664 -0.441190 -0.145264 +v -0.449914 -0.438592 -0.145134 +v -0.477478 -0.435303 -0.141828 +v -0.479414 -0.438592 -0.145134 +v -0.464664 -0.445459 -0.146924 +v -0.447966 -0.442569 -0.146768 +v -0.481363 -0.442569 -0.146768 +v -0.453549 -0.434184 -0.135663 +v -0.451850 -0.435303 -0.141828 +v -0.453549 -0.434184 -0.135663 +v -0.464664 -0.436210 -0.135898 +v -0.464664 -0.437645 -0.141943 +v -0.451850 -0.435303 -0.141828 +v -0.475779 -0.434184 -0.135663 +v -0.477478 -0.435303 -0.141828 +v -0.484989 -0.427120 -0.134566 +v -0.487982 -0.428213 -0.141630 +v -0.487982 -0.428213 -0.141630 +v -0.491592 -0.430802 -0.144783 +v -0.495193 -0.433897 -0.146306 +v -0.494215 -0.416801 -0.141621 +v -0.496199 -0.403265 -0.141198 +v -0.501540 -0.403133 -0.143511 +v -0.499074 -0.418260 -0.144247 +v -0.494215 -0.389764 -0.140152 +v -0.499074 -0.388017 -0.142603 +v -0.506623 -0.403069 -0.144659 +v -0.503768 -0.419927 -0.145565 +v -0.503768 -0.386211 -0.143732 +v -0.484989 -0.427120 -0.134566 +v -0.489904 -0.415413 -0.137009 +v -0.494215 -0.416801 -0.141621 +v -0.487982 -0.428213 -0.141630 +v -0.489904 -0.415413 -0.137009 +v -0.491276 -0.403496 -0.137117 +v -0.489904 -0.391666 -0.135719 +v -0.489904 -0.391666 -0.135719 +v -0.494215 -0.389764 -0.140152 +v -0.470246 -0.395365 -0.076368 +v -0.470246 -0.393154 -0.078078 +v -0.464664 -0.393945 -0.078731 +v -0.464664 -0.396014 -0.077146 +v -0.470246 -0.393154 -0.078078 +v -0.470247 -0.391656 -0.079869 +v -0.464664 -0.392547 -0.080386 +v -0.464664 -0.393945 -0.078731 +v -0.459082 -0.393154 -0.078078 +v -0.459082 -0.395365 -0.076368 +v -0.459082 -0.391656 -0.079869 +v -0.459082 -0.393154 -0.078078 +v -0.475460 -0.397087 -0.072449 +v -0.475460 -0.393419 -0.074035 +v -0.470246 -0.398462 -0.075066 +v -0.475460 -0.393419 -0.074035 +v -0.475460 -0.390782 -0.076119 +v -0.470246 -0.395365 -0.076368 +v -0.475460 -0.388981 -0.078317 +v -0.453867 -0.388981 -0.078317 +v -0.459082 -0.391656 -0.079869 +v -0.453867 -0.388981 -0.078317 +v -0.453868 -0.390782 -0.076119 +v -0.453868 -0.393419 -0.074035 +v -0.459082 -0.398462 -0.075066 +v -0.453868 -0.397087 -0.072449 +v -0.464664 -0.398921 -0.075938 +v -0.473375 -0.450302 -0.088027 +v -0.464664 -0.451315 -0.088067 +v -0.464664 -0.452289 -0.083335 +v -0.473389 -0.451256 -0.083409 +v -0.455952 -0.450302 -0.088027 +v -0.455939 -0.451256 -0.083409 +v -0.464664 -0.452074 -0.079487 +v -0.473394 -0.451047 -0.079660 +v -0.455934 -0.451047 -0.079660 +v -0.479961 -0.445165 -0.094048 +v -0.473349 -0.448061 -0.094625 +v -0.480007 -0.447264 -0.087904 +v -0.464664 -0.449027 -0.094817 +v -0.455979 -0.448061 -0.094625 +v -0.449367 -0.445165 -0.094048 +v -0.449321 -0.447264 -0.087904 +v -0.449298 -0.448158 -0.083631 +v -0.449290 -0.447966 -0.080181 +v -0.449289 -0.446808 -0.076509 +v -0.455934 -0.449801 -0.075671 +v -0.464664 -0.450798 -0.075392 +v -0.473394 -0.449801 -0.075671 +v -0.480038 -0.447966 -0.080181 +v -0.480039 -0.446808 -0.076509 +v -0.480030 -0.448158 -0.083631 +v -0.455952 -0.362581 -0.083255 +v -0.464664 -0.361571 -0.083186 +v -0.464664 -0.361141 -0.078344 +v -0.455939 -0.362159 -0.078529 +v -0.473375 -0.362581 -0.083255 +v -0.473389 -0.362159 -0.078529 +v -0.464664 -0.361790 -0.074455 +v -0.455934 -0.362791 -0.074740 +v -0.473394 -0.362791 -0.074740 +v -0.449367 -0.366998 -0.089803 +v -0.455979 -0.364056 -0.090061 +v -0.449321 -0.365613 -0.083463 +v -0.464664 -0.363076 -0.090147 +v -0.473349 -0.364056 -0.090061 +v -0.473349 -0.364056 -0.090061 +v -0.479961 -0.366998 -0.089803 +v -0.480007 -0.365613 -0.083463 +v -0.473375 -0.362581 -0.083255 +v -0.480030 -0.365211 -0.079086 +v -0.473389 -0.362159 -0.078529 +v -0.480038 -0.365793 -0.075595 +v -0.473394 -0.362791 -0.074740 +v -0.480039 -0.367356 -0.071915 +v -0.473394 -0.364478 -0.070744 +v -0.473394 -0.364478 -0.070744 +v -0.464664 -0.363519 -0.070354 +v -0.455934 -0.364478 -0.070744 +v -0.449290 -0.365793 -0.075595 +v -0.449289 -0.367356 -0.071915 +v -0.449298 -0.365211 -0.079086 +v -0.473394 -0.396561 -0.049275 +v -0.473394 -0.408443 -0.049276 +v -0.464664 -0.408494 -0.048354 +v -0.464664 -0.396344 -0.048355 +v -0.473394 -0.420228 -0.051073 +v -0.464664 -0.420545 -0.050192 +v -0.455934 -0.408443 -0.049276 +v -0.455934 -0.396561 -0.049275 +v -0.455934 -0.420228 -0.051073 +v -0.480039 -0.387310 -0.053842 +v -0.480039 -0.397213 -0.052037 +v -0.473394 -0.385935 -0.051225 +v -0.480039 -0.408289 -0.052042 +v -0.480039 -0.419276 -0.053713 +v -0.480039 -0.428907 -0.056906 +v -0.473394 -0.430561 -0.054511 +v -0.464664 -0.431112 -0.053712 +v -0.455934 -0.430561 -0.054511 +v -0.449290 -0.428907 -0.056906 +v -0.449290 -0.419276 -0.053713 +v -0.449290 -0.408289 -0.052042 +v -0.449290 -0.397213 -0.052037 +v -0.455934 -0.385935 -0.051225 +v -0.449290 -0.387310 -0.053842 +v -0.464664 -0.385476 -0.050353 +v -0.473394 -0.447542 -0.070634 +v -0.464664 -0.448485 -0.070227 +v -0.464664 -0.444755 -0.064408 +v -0.473394 -0.443897 -0.064955 +v -0.455934 -0.447542 -0.070634 +v -0.455934 -0.443897 -0.064955 +v -0.473394 -0.443897 -0.064955 +v -0.464664 -0.444755 -0.064408 +v -0.464664 -0.439125 -0.058661 +v -0.473394 -0.438395 -0.059344 +v -0.455934 -0.443897 -0.064955 +v -0.455934 -0.438395 -0.059344 +v -0.480039 -0.444710 -0.071855 +v -0.449289 -0.444710 -0.071855 +v -0.449289 -0.441323 -0.066596 +v -0.449289 -0.441323 -0.066596 +v -0.449290 -0.436203 -0.061392 +v -0.480039 -0.436203 -0.061392 +v -0.480039 -0.441323 -0.066596 +v -0.473394 -0.438395 -0.059344 +v -0.480039 -0.436203 -0.061392 +v -0.470246 -0.411559 -0.075129 +v -0.470246 -0.407045 -0.074473 +v -0.464664 -0.406993 -0.075395 +v -0.464664 -0.411242 -0.076009 +v -0.470246 -0.402497 -0.074433 +v -0.464664 -0.402714 -0.075353 +v -0.459082 -0.407045 -0.074473 +v -0.459082 -0.411559 -0.075129 +v -0.459082 -0.402497 -0.074433 +v -0.475460 -0.417147 -0.073942 +v -0.475460 -0.412510 -0.072488 +v -0.470246 -0.415494 -0.076338 +v -0.475460 -0.407198 -0.071708 +v -0.475460 -0.401845 -0.071671 +v -0.453868 -0.401845 -0.071671 +v -0.453868 -0.407198 -0.071708 +v -0.453868 -0.412510 -0.072488 +v -0.459082 -0.415494 -0.076338 +v -0.453868 -0.417147 -0.073942 +v -0.464664 -0.414943 -0.077137 +v -0.470247 -0.421746 -0.081761 +v -0.470246 -0.420445 -0.079906 +v -0.464664 -0.419587 -0.080453 +v -0.464664 -0.420802 -0.082168 +v -0.470246 -0.418430 -0.078009 +v -0.464664 -0.417699 -0.078691 +v -0.464664 -0.420802 -0.082168 +v -0.464664 -0.419587 -0.080453 +v -0.459082 -0.420445 -0.079906 +v -0.459082 -0.421746 -0.081761 +v -0.459082 -0.418430 -0.078009 +v -0.459082 -0.420445 -0.079906 +v -0.475461 -0.425529 -0.082467 +v -0.475460 -0.424577 -0.080539 +v -0.470247 -0.421746 -0.081761 +v -0.470247 -0.422536 -0.083305 +v -0.475460 -0.423019 -0.078265 +v -0.470246 -0.420445 -0.079906 +v -0.475460 -0.420621 -0.075960 +v -0.470246 -0.418430 -0.078009 +v -0.475460 -0.420621 -0.075960 +v -0.453868 -0.420621 -0.075960 +v -0.453868 -0.423019 -0.078265 +v -0.453868 -0.423019 -0.078265 +v -0.453867 -0.424577 -0.080539 +v -0.459081 -0.422536 -0.083305 +v -0.453866 -0.425529 -0.082467 +v -0.464664 -0.421539 -0.083584 +v -0.470247 -0.422536 -0.083305 +v -0.470247 -0.421746 -0.081761 +v -0.470239 -0.422621 -0.086915 +v -0.470246 -0.423028 -0.085431 +v -0.464664 -0.421995 -0.085505 +v -0.464664 -0.421608 -0.086874 +v -0.470248 -0.422974 -0.084400 +v -0.464664 -0.421947 -0.084573 +v -0.459082 -0.423028 -0.085431 +v -0.459089 -0.422621 -0.086915 +v -0.459080 -0.422974 -0.084400 +v -0.475418 -0.424572 -0.089945 +v -0.475446 -0.425659 -0.087037 +v -0.470239 -0.422621 -0.086915 +v -0.470226 -0.421676 -0.089368 +v -0.475459 -0.426126 -0.085209 +v -0.470246 -0.423028 -0.085431 +v -0.475462 -0.426055 -0.083879 +v -0.470248 -0.422974 -0.084400 +v -0.453866 -0.426055 -0.083879 +v -0.453869 -0.426126 -0.085209 +v -0.453882 -0.425659 -0.087037 +v -0.459102 -0.421676 -0.089368 +v -0.453910 -0.424572 -0.089945 +v -0.464664 -0.420711 -0.089175 +v -0.470226 -0.421676 -0.089368 +v -0.474391 -0.436444 -0.126083 +v -0.464664 -0.437816 -0.126557 +v -0.464664 -0.441391 -0.115386 +v -0.473612 -0.440396 -0.114872 +v -0.454937 -0.436444 -0.126083 +v -0.455716 -0.440396 -0.114872 +v -0.464664 -0.445470 -0.104278 +v -0.473352 -0.444555 -0.103898 +v -0.455976 -0.444555 -0.103898 +v -0.481539 -0.432914 -0.123977 +v -0.447789 -0.432914 -0.123977 +v -0.454937 -0.436444 -0.126083 +v -0.447789 -0.432914 -0.123977 +v -0.449011 -0.437633 -0.113108 +v -0.449375 -0.441836 -0.102729 +v -0.479953 -0.441836 -0.102729 +v -0.480317 -0.437633 -0.113108 +v -0.454937 -0.372015 -0.122582 +v -0.464664 -0.370597 -0.122905 +v -0.464664 -0.368319 -0.111415 +v -0.455716 -0.369365 -0.111013 +v -0.474391 -0.372015 -0.122582 +v -0.473612 -0.369365 -0.111013 +v -0.464664 -0.365531 -0.099935 +v -0.455976 -0.366483 -0.099657 +v -0.473352 -0.366483 -0.099657 +v -0.447789 -0.375760 -0.120873 +v -0.481539 -0.375760 -0.120873 +v -0.474391 -0.372015 -0.122582 +v -0.480317 -0.372310 -0.109561 +v -0.473612 -0.369365 -0.111013 +v -0.479953 -0.369316 -0.098792 +v -0.473352 -0.366483 -0.099657 +v -0.449375 -0.369316 -0.098792 +v -0.449011 -0.372310 -0.109561 +v -0.470149 -0.415397 -0.101933 +v -0.470176 -0.418027 -0.097535 +v -0.464664 -0.417250 -0.096916 +v -0.464664 -0.414770 -0.101097 +v -0.470204 -0.420136 -0.093092 +v -0.464664 -0.419248 -0.092698 +v -0.459152 -0.418027 -0.097535 +v -0.459179 -0.415397 -0.101933 +v -0.459124 -0.420136 -0.093092 +v -0.475220 -0.413593 -0.108541 +v -0.475266 -0.417278 -0.104438 +v -0.470149 -0.415397 -0.101933 +v -0.470126 -0.412293 -0.105519 +v -0.475320 -0.420358 -0.099392 +v -0.470176 -0.418027 -0.097535 +v -0.475374 -0.422801 -0.094272 +v -0.470204 -0.420136 -0.093092 +v -0.453954 -0.422801 -0.094272 +v -0.454008 -0.420358 -0.099392 +v -0.454062 -0.417278 -0.104438 +v -0.459202 -0.412293 -0.105519 +v -0.454108 -0.413593 -0.108541 +v -0.464664 -0.411860 -0.104511 +v -0.470126 -0.412293 -0.105519 +v -0.455934 -0.367287 -0.065732 +v -0.464664 -0.366395 -0.065214 +v -0.464664 -0.370750 -0.059579 +v -0.455934 -0.371541 -0.060232 +v -0.473394 -0.367287 -0.065732 +v -0.473394 -0.371541 -0.060232 +v -0.455934 -0.371541 -0.060232 +v -0.464664 -0.370750 -0.059579 +v -0.464664 -0.376978 -0.054330 +v -0.455934 -0.377627 -0.055108 +v -0.473394 -0.371541 -0.060232 +v -0.473394 -0.377627 -0.055108 +v -0.449289 -0.369962 -0.067283 +v -0.480039 -0.369962 -0.067283 +v -0.473394 -0.367287 -0.065732 +v -0.480039 -0.373913 -0.062190 +v -0.473394 -0.371541 -0.060232 +v -0.480039 -0.373913 -0.062190 +v -0.480039 -0.379574 -0.057441 +v -0.449290 -0.379574 -0.057441 +v -0.449289 -0.373913 -0.062191 +v -0.455934 -0.377627 -0.055108 +v -0.449290 -0.379574 -0.057441 +v -0.449718 -0.399017 -0.115767 +v -0.449709 -0.404631 -0.117128 +v -0.445797 -0.404245 -0.123930 +v -0.445967 -0.396871 -0.122356 +v -0.449718 -0.410366 -0.116381 +v -0.445967 -0.411752 -0.123163 +v -0.442117 -0.403842 -0.131019 +v -0.442736 -0.394280 -0.129393 +v -0.442736 -0.413532 -0.130438 +v -0.454108 -0.396700 -0.107630 +v -0.454136 -0.400602 -0.110507 +v -0.449727 -0.394011 -0.112297 +v -0.454145 -0.404943 -0.111631 +v -0.454136 -0.409385 -0.110982 +v -0.454108 -0.413593 -0.108541 +v -0.449727 -0.415737 -0.113472 +v -0.446313 -0.418623 -0.119779 +v -0.444177 -0.422191 -0.126846 +v -0.444177 -0.386084 -0.124886 +v -0.446313 -0.390430 -0.118251 +v -0.479609 -0.410366 -0.116381 +v -0.479619 -0.404631 -0.117128 +v -0.483531 -0.404245 -0.123930 +v -0.483361 -0.411752 -0.123163 +v -0.479609 -0.399017 -0.115767 +v -0.483361 -0.396871 -0.122356 +v -0.487211 -0.403842 -0.131019 +v -0.486592 -0.413532 -0.130438 +v -0.486592 -0.394280 -0.129393 +v -0.475192 -0.409385 -0.110982 +v -0.479601 -0.415737 -0.113472 +v -0.475183 -0.404943 -0.111631 +v -0.475192 -0.400602 -0.110507 +v -0.475220 -0.396700 -0.107630 +v -0.479601 -0.394011 -0.112297 +v -0.483014 -0.390430 -0.118251 +v -0.485151 -0.386084 -0.124886 +v -0.491276 -0.403496 -0.137117 +v -0.485151 -0.422191 -0.126846 +v -0.483014 -0.418623 -0.119779 +v -0.479858 -0.431019 -0.083041 +v -0.479852 -0.431118 -0.084852 +v -0.482649 -0.437142 -0.084420 +v -0.482657 -0.437010 -0.082030 +v -0.479832 -0.430554 -0.087234 +v -0.482625 -0.436462 -0.087471 +v -0.482995 -0.443166 -0.083988 +v -0.483004 -0.443002 -0.081019 +v -0.482968 -0.442369 -0.087708 +v -0.479857 -0.430350 -0.081117 +v -0.479791 -0.429238 -0.090874 +v -0.482574 -0.434869 -0.091996 +v -0.482914 -0.440500 -0.093118 +v -0.479961 -0.445165 -0.094048 +v -0.480007 -0.447264 -0.087904 +v -0.480030 -0.448158 -0.083631 +v -0.480038 -0.447966 -0.080181 +v -0.483004 -0.441987 -0.077859 +v -0.480039 -0.446808 -0.076509 +v -0.482657 -0.436168 -0.079488 +v -0.479618 -0.389997 -0.106880 +v -0.479663 -0.386939 -0.100393 +v -0.482526 -0.381925 -0.103585 +v -0.482705 -0.385520 -0.111602 +v -0.479728 -0.384701 -0.093886 +v -0.482510 -0.379281 -0.095614 +v -0.483099 -0.376760 -0.106886 +v -0.483842 -0.380566 -0.116695 +v -0.482876 -0.373843 -0.097356 +v -0.475220 -0.396700 -0.107630 +v -0.475266 -0.393506 -0.103158 +v -0.479618 -0.389997 -0.106880 +v -0.479601 -0.394011 -0.112297 +v -0.475320 -0.391023 -0.097815 +v -0.479663 -0.386939 -0.100393 +v -0.475374 -0.389182 -0.092463 +v -0.479728 -0.384701 -0.093886 +v -0.479791 -0.383178 -0.088382 +v -0.479791 -0.383178 -0.088382 +v -0.482574 -0.377457 -0.088884 +v -0.482914 -0.371737 -0.089386 +v -0.449470 -0.382302 -0.080297 +v -0.449476 -0.381999 -0.082147 +v -0.446678 -0.376063 -0.081065 +v -0.446670 -0.376465 -0.078635 +v -0.449496 -0.382286 -0.084607 +v -0.446703 -0.376391 -0.084203 +v -0.446333 -0.370129 -0.079983 +v -0.446324 -0.370629 -0.076972 +v -0.446360 -0.370497 -0.083798 +v -0.453866 -0.387820 -0.080243 +v -0.453866 -0.387138 -0.081675 +v -0.449471 -0.383184 -0.078356 +v -0.453869 -0.386916 -0.083044 +v -0.453882 -0.387170 -0.084943 +v -0.453910 -0.387917 -0.087965 +v -0.449536 -0.383178 -0.088382 +v -0.446754 -0.377457 -0.088884 +v -0.446413 -0.371737 -0.089386 +v -0.446360 -0.370497 -0.083798 +v -0.446413 -0.371737 -0.089386 +v -0.446333 -0.370129 -0.079983 +v -0.446324 -0.370629 -0.076972 +v -0.446324 -0.371993 -0.073802 +v -0.446670 -0.377588 -0.076079 +v -0.446324 -0.371993 -0.073802 +v -0.449710 -0.420345 -0.108519 +v -0.449665 -0.424127 -0.102400 +v -0.446803 -0.428750 -0.106120 +v -0.446623 -0.424262 -0.113700 +v -0.449599 -0.427095 -0.096176 +v -0.446818 -0.432288 -0.098484 +v -0.446623 -0.424262 -0.113700 +v -0.446803 -0.428750 -0.106120 +v -0.446229 -0.433511 -0.109963 +v -0.445486 -0.428609 -0.119302 +v -0.446818 -0.432288 -0.098484 +v -0.446451 -0.437498 -0.100809 +v -0.449727 -0.415737 -0.113472 +v -0.449536 -0.429238 -0.090874 +v -0.446754 -0.434869 -0.091996 +v -0.446754 -0.434869 -0.091996 +v -0.446413 -0.440500 -0.093118 +v -0.449367 -0.445165 -0.094048 +v -0.449375 -0.441836 -0.102729 +v -0.449011 -0.437633 -0.113108 +v -0.449710 -0.420345 -0.108519 +v -0.449472 -0.390282 -0.070275 +v -0.449472 -0.386960 -0.072963 +v -0.446671 -0.382348 -0.069155 +v -0.446672 -0.386496 -0.065738 +v -0.449471 -0.384672 -0.075817 +v -0.446671 -0.379472 -0.072800 +v -0.446325 -0.377735 -0.065346 +v -0.446325 -0.382711 -0.061201 +v -0.446324 -0.374271 -0.069783 +v -0.449472 -0.390282 -0.070275 +v -0.449472 -0.394872 -0.068233 +v -0.453868 -0.393419 -0.074035 +v -0.453868 -0.390782 -0.076119 +v -0.453867 -0.388981 -0.078317 +v -0.446324 -0.374271 -0.069783 +v -0.446325 -0.377735 -0.065346 +v -0.449289 -0.373913 -0.062191 +v -0.449290 -0.379574 -0.057441 +v -0.446325 -0.389525 -0.058057 +v -0.449290 -0.387310 -0.053842 +v -0.446672 -0.392199 -0.063145 +v -0.449472 -0.394872 -0.068233 +v -0.479856 -0.384672 -0.075817 +v -0.479856 -0.386960 -0.072963 +v -0.482656 -0.382348 -0.069155 +v -0.482657 -0.379472 -0.072800 +v -0.479855 -0.390282 -0.070275 +v -0.482656 -0.386496 -0.065738 +v -0.483003 -0.377735 -0.065346 +v -0.483004 -0.374271 -0.069783 +v -0.483003 -0.382711 -0.061201 +v -0.479856 -0.384672 -0.075817 +v -0.479857 -0.383184 -0.078356 +v -0.479856 -0.386960 -0.072963 +v -0.475460 -0.390782 -0.076119 +v -0.475460 -0.393419 -0.074035 +v -0.475460 -0.397087 -0.072449 +v -0.479855 -0.394872 -0.068233 +v -0.482656 -0.392199 -0.063145 +v -0.483003 -0.389525 -0.058057 +v -0.480039 -0.387310 -0.053842 +v -0.480039 -0.379574 -0.057441 +v -0.483004 -0.371993 -0.073802 +v -0.482657 -0.377588 -0.076079 +v -0.479857 -0.383184 -0.078356 +v -0.479855 -0.400796 -0.067223 +v -0.479855 -0.407445 -0.067252 +v -0.482656 -0.407744 -0.061875 +v -0.482656 -0.399529 -0.061854 +v -0.479855 -0.414043 -0.068234 +v -0.482656 -0.415893 -0.063100 +v -0.483003 -0.408042 -0.056497 +v -0.483003 -0.398263 -0.056485 +v -0.483003 -0.417743 -0.057966 +v -0.475460 -0.401845 -0.071671 +v -0.475460 -0.407198 -0.071708 +v -0.475460 -0.412510 -0.072488 +v -0.475460 -0.417147 -0.073942 +v -0.479855 -0.419812 -0.070083 +v -0.482656 -0.423028 -0.065424 +v -0.483003 -0.426243 -0.060766 +v -0.480039 -0.428907 -0.056906 +v -0.480039 -0.419276 -0.053713 +v -0.480039 -0.408289 -0.052042 +v -0.480039 -0.397213 -0.052037 +v -0.449496 -0.430554 -0.087234 +v -0.449476 -0.431118 -0.084852 +v -0.446678 -0.437142 -0.084420 +v -0.446703 -0.436462 -0.087471 +v -0.449470 -0.431019 -0.083041 +v -0.446670 -0.437010 -0.082030 +v -0.446703 -0.436462 -0.087471 +v -0.446678 -0.437142 -0.084420 +v -0.446333 -0.443166 -0.083988 +v -0.446360 -0.442369 -0.087708 +v -0.446670 -0.437010 -0.082030 +v -0.446324 -0.443002 -0.081019 +v -0.449471 -0.430350 -0.081117 +v -0.446670 -0.436168 -0.079488 +v -0.446670 -0.436168 -0.079488 +v -0.446324 -0.441987 -0.077859 +v -0.449289 -0.446808 -0.076509 +v -0.449290 -0.447966 -0.080181 +v -0.449298 -0.448158 -0.083631 +v -0.449321 -0.447264 -0.087904 +v -0.479832 -0.382286 -0.084607 +v -0.479851 -0.381999 -0.082147 +v -0.482649 -0.376063 -0.081064 +v -0.482625 -0.376391 -0.084203 +v -0.479857 -0.382302 -0.080297 +v -0.482657 -0.376465 -0.078635 +v -0.482995 -0.370129 -0.079983 +v -0.482968 -0.370497 -0.083798 +v -0.483004 -0.370629 -0.076972 +v -0.479832 -0.382286 -0.084607 +v -0.479851 -0.381999 -0.082147 +v -0.479857 -0.382302 -0.080297 +v -0.479728 -0.427095 -0.096176 +v -0.479663 -0.424127 -0.102400 +v -0.482526 -0.428750 -0.106120 +v -0.482510 -0.432288 -0.098484 +v -0.479618 -0.420345 -0.108519 +v -0.482705 -0.424262 -0.113700 +v -0.483099 -0.433511 -0.109963 +v -0.482876 -0.437498 -0.100809 +v -0.483842 -0.428609 -0.119302 +v -0.481539 -0.432914 -0.123977 +v -0.480317 -0.437633 -0.113108 +v -0.479953 -0.441836 -0.102729 +v -0.449600 -0.384701 -0.093886 +v -0.449665 -0.386939 -0.100393 +v -0.446803 -0.381925 -0.103585 +v -0.446818 -0.379281 -0.095615 +v -0.449710 -0.389997 -0.106880 +v -0.446623 -0.385520 -0.111602 +v -0.446229 -0.376760 -0.106886 +v -0.446451 -0.373843 -0.097356 +v -0.445486 -0.380566 -0.116696 +v -0.453954 -0.389182 -0.092463 +v -0.454008 -0.391023 -0.097815 +v -0.454063 -0.393506 -0.103158 +v -0.447789 -0.375760 -0.120873 +v -0.446229 -0.376760 -0.106886 +v -0.445486 -0.380566 -0.116696 +v -0.446451 -0.373843 -0.097356 +v -0.449472 -0.414043 -0.068234 +v -0.449472 -0.407445 -0.067252 +v -0.446672 -0.407744 -0.061875 +v -0.446672 -0.415893 -0.063100 +v -0.449472 -0.400796 -0.067223 +v -0.446672 -0.399529 -0.061854 +v -0.446325 -0.408042 -0.056498 +v -0.446325 -0.417743 -0.057966 +v -0.446325 -0.398263 -0.056485 +v -0.449472 -0.414043 -0.068234 +v -0.449472 -0.419812 -0.070083 +v -0.449472 -0.407445 -0.067252 +v -0.449472 -0.400796 -0.067223 +v -0.449290 -0.397213 -0.052037 +v -0.449290 -0.408289 -0.052042 +v -0.449290 -0.419276 -0.053713 +v -0.446325 -0.426243 -0.060766 +v -0.449290 -0.428907 -0.056906 +v -0.446672 -0.423028 -0.065424 +v -0.449472 -0.419812 -0.070083 +v -0.479855 -0.424151 -0.072659 +v -0.479856 -0.427166 -0.075621 +v -0.482656 -0.432171 -0.072430 +v -0.482656 -0.428412 -0.068676 +v -0.479856 -0.429138 -0.078572 +v -0.482657 -0.434644 -0.076197 +v -0.483003 -0.437176 -0.069239 +v -0.483003 -0.432673 -0.064693 +v -0.483004 -0.440149 -0.073823 +v -0.480039 -0.444710 -0.071855 +v -0.480039 -0.441323 -0.066596 +v -0.480039 -0.436203 -0.061392 +v -0.449471 -0.429138 -0.078572 +v -0.449472 -0.427166 -0.075621 +v -0.446671 -0.432171 -0.072430 +v -0.446671 -0.434644 -0.076198 +v -0.449472 -0.427166 -0.075621 +v -0.449472 -0.424151 -0.072659 +v -0.446672 -0.428412 -0.068676 +v -0.446671 -0.432171 -0.072430 +v -0.446671 -0.434644 -0.076198 +v -0.446325 -0.437176 -0.069239 +v -0.446324 -0.440149 -0.073823 +v -0.446325 -0.432673 -0.064693 +v -0.453868 -0.420621 -0.075960 +v -0.449472 -0.424151 -0.072659 +v -0.449472 -0.424151 -0.072659 +v -0.449290 -0.436203 -0.061392 +v -0.449289 -0.441323 -0.066596 +v -0.449289 -0.444710 -0.071855 +v -0.470204 -0.391962 -0.091581 +v -0.470176 -0.393549 -0.096223 +v -0.464664 -0.394391 -0.095693 +v -0.464664 -0.392889 -0.091286 +v -0.470149 -0.395659 -0.100873 +v -0.464664 -0.396376 -0.100111 +v -0.459152 -0.393549 -0.096223 +v -0.459124 -0.391962 -0.091581 +v -0.459179 -0.395659 -0.100873 +v -0.470126 -0.398332 -0.104768 +v -0.464664 -0.398877 -0.103813 +v -0.459202 -0.398332 -0.104768 +v -0.459179 -0.395659 -0.100873 +v -0.459202 -0.398332 -0.104768 +v -0.459152 -0.393549 -0.096223 +v -0.454008 -0.391023 -0.097815 +v -0.453954 -0.389182 -0.092463 +v -0.470112 -0.401561 -0.107269 +v -0.470107 -0.405135 -0.108238 +v -0.464664 -0.405199 -0.107106 +v -0.464664 -0.401880 -0.106189 +v -0.470112 -0.408798 -0.107659 +v -0.464664 -0.408603 -0.106552 +v -0.459221 -0.405135 -0.108238 +v -0.459216 -0.401561 -0.107269 +v -0.459216 -0.408798 -0.107659 +v -0.475220 -0.396700 -0.107630 +v -0.475192 -0.400602 -0.110507 +v -0.470126 -0.398332 -0.104768 +v -0.475183 -0.404943 -0.111631 +v -0.475192 -0.409385 -0.110982 +v -0.475220 -0.413593 -0.108541 +v -0.470126 -0.412293 -0.105519 +v -0.464664 -0.411860 -0.104511 +v -0.459202 -0.412293 -0.105519 +v -0.459216 -0.408798 -0.107659 +v -0.454136 -0.409385 -0.110982 +v -0.454136 -0.409385 -0.110982 +v -0.454145 -0.404943 -0.111631 +v -0.454136 -0.400602 -0.110507 +v -0.459216 -0.401561 -0.107269 +v -0.464664 -0.398877 -0.103813 +v -0.459202 -0.398332 -0.104768 +vt 0.998079 0.328036 +vt 0.998612 0.327977 +vt 0.998460 0.325034 +vt 0.997925 0.325069 +vt 0.999081 0.327803 +vt 0.998932 0.324925 +vt 0.998398 0.321385 +vt 0.997863 0.321390 +vt 0.998872 0.321357 +vt 0.530415 0.123228 +vt 0.529849 0.123222 +vt 0.529857 0.126140 +vt 0.530423 0.126149 +vt 0.529318 0.123185 +vt 0.529326 0.126079 +vt 0.528860 0.123084 +vt 0.528868 0.125915 +vt 0.816277 0.412998 +vt 0.816010 0.412645 +vt 0.812729 0.413978 +vt 0.812846 0.414393 +vt 0.809046 0.413978 +vt 0.808993 0.414393 +vt 0.805573 0.412750 +vt 0.805360 0.413109 +vt 0.802924 0.410400 +vt 0.802589 0.410650 +vt 0.998919 0.317651 +vt 0.998447 0.317595 +vt 0.997912 0.317569 +vt 0.997298 0.321385 +vt 0.997347 0.317559 +vt 0.997360 0.325068 +vt 0.997514 0.328038 +vt 0.711479 0.799739 +vt 0.710945 0.799782 +vt 0.711141 0.803400 +vt 0.711678 0.803387 +vt 0.710464 0.799908 +vt 0.710656 0.803446 +vt 0.711141 0.807334 +vt 0.711678 0.807353 +vt 0.710656 0.807293 +vt 0.998079 0.314140 +vt 0.997514 0.314126 +vt 0.998612 0.314193 +vt 0.999081 0.314324 +vt 0.801592 0.407117 +vt 0.801196 0.407216 +vt 0.801592 0.403430 +vt 0.801196 0.403359 +vt 0.710246 0.803542 +vt 0.710246 0.807220 +vt 0.802479 0.399723 +vt 0.802819 0.399953 +vt 0.805167 0.397301 +vt 0.804936 0.396949 +vt 0.710447 0.810816 +vt 0.710928 0.810936 +vt 0.711462 0.810984 +vt 0.712239 0.807360 +vt 0.712024 0.810996 +vt 0.712239 0.803390 +vt 0.712041 0.799738 +vt 0.466181 0.066289 +vt 0.466715 0.066245 +vt 0.466614 0.062530 +vt 0.466080 0.062545 +vt 0.467186 0.066125 +vt 0.467087 0.062492 +vt 0.466607 0.058587 +vt 0.466072 0.058569 +vt 0.467080 0.058636 +vt 0.465802 0.069152 +vt 0.466367 0.069141 +vt 0.465616 0.066297 +vt 0.466900 0.069073 +vt 0.467366 0.068891 +vt 0.808447 0.395968 +vt 0.808367 0.395554 +vt 0.812131 0.395968 +vt 0.812219 0.395554 +vt 0.815604 0.397195 +vt 0.815852 0.396838 +vt 0.818253 0.399546 +vt 0.818623 0.399297 +vt 0.467173 0.055197 +vt 0.466702 0.055070 +vt 0.466168 0.055024 +vt 0.465506 0.058568 +vt 0.465603 0.055018 +vt 0.465514 0.062548 +vt 0.529857 0.112057 +vt 0.529326 0.112110 +vt 0.529319 0.115602 +vt 0.529849 0.115578 +vt 0.528868 0.112253 +vt 0.528861 0.115668 +vt 0.529316 0.119505 +vt 0.529846 0.119512 +vt 0.528858 0.119485 +vt 0.466367 0.052480 +vt 0.465802 0.052472 +vt 0.466900 0.052547 +vt 0.467366 0.052730 +vt 0.819585 0.402829 +vt 0.820016 0.402731 +vt 0.819585 0.406516 +vt 0.820016 0.406588 +vt 0.818358 0.409993 +vt 0.818733 0.410224 +vt 0.530412 0.119514 +vt 0.530415 0.115574 +vt 0.530423 0.112050 +vt 0.807280 0.402852 +vt 0.806762 0.404320 +vt 0.806879 0.404341 +vt 0.807381 0.402919 +vt 0.806762 0.405878 +vt 0.806879 0.405849 +vt 0.807004 0.404363 +vt 0.807488 0.402989 +vt 0.807003 0.405820 +vt 0.808172 0.401585 +vt 0.807135 0.402756 +vt 0.808272 0.401732 +vt 0.806593 0.404291 +vt 0.806593 0.405919 +vt 0.807181 0.407368 +vt 0.807324 0.407265 +vt 0.807423 0.407193 +vt 0.807528 0.407118 +vt 0.807689 0.407007 +vt 0.807194 0.405778 +vt 0.807195 0.404397 +vt 0.807653 0.403094 +vt 0.808415 0.401941 +vt 0.808530 0.402100 +vt 0.808341 0.401834 +vt 0.812155 0.411638 +vt 0.809428 0.411639 +vt 0.809281 0.412508 +vt 0.812363 0.412508 +vt 0.806857 0.410730 +vt 0.806375 0.411481 +vt 0.809147 0.413324 +vt 0.812563 0.413324 +vt 0.805927 0.412185 +vt 0.814091 0.409956 +vt 0.811960 0.410822 +vt 0.814583 0.410651 +vt 0.809568 0.410822 +vt 0.807312 0.410024 +vt 0.805591 0.408498 +vt 0.804896 0.408990 +vt 0.804158 0.409514 +vt 0.803470 0.410006 +vt 0.815605 0.412087 +vt 0.815108 0.411392 +vt 0.803910 0.406559 +vt 0.803910 0.403830 +vt 0.803044 0.403681 +vt 0.803044 0.406766 +vt 0.804818 0.401257 +vt 0.804070 0.400772 +vt 0.802235 0.403542 +vt 0.802235 0.406961 +vt 0.803372 0.400318 +vt 0.804726 0.406365 +vt 0.804726 0.403970 +vt 0.805523 0.401712 +vt 0.807048 0.399989 +vt 0.806557 0.399294 +vt 0.806035 0.398553 +vt 0.805550 0.397858 +vt 0.808985 0.398307 +vt 0.811711 0.398306 +vt 0.811862 0.397437 +vt 0.808780 0.397437 +vt 0.814282 0.399215 +vt 0.814769 0.398464 +vt 0.812008 0.396621 +vt 0.808592 0.396622 +vt 0.815228 0.397760 +vt 0.809179 0.399123 +vt 0.811571 0.399123 +vt 0.813827 0.399921 +vt 0.815548 0.401447 +vt 0.816243 0.400955 +vt 0.816985 0.400431 +vt 0.817685 0.399940 +vt 0.817229 0.403386 +vt 0.817229 0.406115 +vt 0.818100 0.406264 +vt 0.818100 0.403179 +vt 0.816321 0.408688 +vt 0.817073 0.409173 +vt 0.818920 0.406404 +vt 0.818920 0.402985 +vt 0.817783 0.409628 +vt 0.816413 0.403580 +vt 0.816413 0.405975 +vt 0.815616 0.408233 +vt 0.811578 0.409222 +vt 0.809840 0.409222 +vt 0.809774 0.409616 +vt 0.811673 0.409616 +vt 0.808201 0.408642 +vt 0.807983 0.408983 +vt 0.809683 0.410146 +vt 0.811799 0.410145 +vt 0.807688 0.409440 +vt 0.812959 0.408360 +vt 0.811511 0.408948 +vt 0.813126 0.408592 +vt 0.809884 0.408948 +vt 0.808351 0.408406 +vt 0.806951 0.407533 +vt 0.806616 0.407771 +vt 0.806167 0.408090 +vt 0.813683 0.409379 +vt 0.813365 0.408929 +vt 0.806323 0.405984 +vt 0.806323 0.404244 +vt 0.805930 0.404177 +vt 0.805930 0.406078 +vt 0.806902 0.402604 +vt 0.806562 0.402384 +vt 0.805402 0.404086 +vt 0.805402 0.406204 +vt 0.806106 0.402089 +vt 0.808010 0.401352 +vt 0.807773 0.401016 +vt 0.807455 0.400566 +vt 0.809557 0.400723 +vt 0.811295 0.400723 +vt 0.811364 0.400329 +vt 0.809465 0.400329 +vt 0.812934 0.401303 +vt 0.813155 0.400962 +vt 0.811455 0.399799 +vt 0.809339 0.399800 +vt 0.813450 0.400505 +vt 0.809620 0.400996 +vt 0.811246 0.400996 +vt 0.812780 0.401538 +vt 0.813949 0.402576 +vt 0.814184 0.402412 +vt 0.814521 0.402174 +vt 0.814972 0.401855 +vt 0.814813 0.403961 +vt 0.814813 0.405701 +vt 0.815208 0.405768 +vt 0.815208 0.403867 +vt 0.814234 0.407341 +vt 0.814576 0.407561 +vt 0.815737 0.405859 +vt 0.815737 0.403741 +vt 0.815032 0.407856 +vt 0.814537 0.404026 +vt 0.814537 0.405654 +vt 0.813996 0.407189 +vt 0.518648 0.773690 +vt 0.518645 0.773768 +vt 0.519064 0.773787 +vt 0.519067 0.773715 +vt 0.518647 0.773883 +vt 0.519066 0.773893 +vt 0.519458 0.773775 +vt 0.519461 0.773696 +vt 0.519460 0.773890 +vt 0.518240 0.773514 +vt 0.518230 0.773619 +vt 0.518656 0.773608 +vt 0.518227 0.773720 +vt 0.518229 0.773861 +vt 0.518238 0.774085 +vt 0.518654 0.774073 +vt 0.519072 0.774072 +vt 0.519465 0.774080 +vt 0.519806 0.774097 +vt 0.519801 0.773873 +vt 0.519800 0.773732 +vt 0.519804 0.773631 +vt 0.519469 0.773614 +vt 0.519814 0.773526 +vt 0.519074 0.773641 +vt 0.812680 0.401687 +vt 0.811213 0.401168 +vt 0.811188 0.401288 +vt 0.812608 0.401790 +vt 0.809657 0.401168 +vt 0.809682 0.401289 +vt 0.811162 0.401413 +vt 0.812532 0.401898 +vt 0.809709 0.401413 +vt 0.813799 0.402680 +vt 0.809753 0.401599 +vt 0.811127 0.401598 +vt 0.812422 0.402057 +vt 0.813577 0.402826 +vt 0.813409 0.402937 +vt 0.813691 0.402752 +vt 0.808443 0.408258 +vt 0.809910 0.408776 +vt 0.809926 0.408656 +vt 0.808506 0.408154 +vt 0.811466 0.408776 +vt 0.811432 0.408656 +vt 0.809943 0.408531 +vt 0.808573 0.408047 +vt 0.811396 0.408531 +vt 0.812851 0.408213 +vt 0.812773 0.408110 +vt 0.812691 0.408003 +vt 0.812568 0.407844 +vt 0.811345 0.408345 +vt 0.809971 0.408346 +vt 0.808677 0.407887 +vt 0.813843 0.407093 +vt 0.814362 0.405624 +vt 0.814235 0.405603 +vt 0.813734 0.407025 +vt 0.814362 0.404067 +vt 0.814236 0.404095 +vt 0.814102 0.405581 +vt 0.813617 0.406955 +vt 0.814102 0.404124 +vt 0.813905 0.404166 +vt 0.813904 0.405547 +vt 0.813445 0.406850 +vt 0.811063 0.407465 +vt 0.810100 0.407475 +vt 0.810065 0.407748 +vt 0.811172 0.407743 +vt 0.809197 0.407144 +vt 0.809024 0.407374 +vt 0.810016 0.408066 +vt 0.811268 0.408063 +vt 0.808837 0.407646 +vt 0.608031 0.779189 +vt 0.608741 0.779134 +vt 0.608806 0.778684 +vt 0.608068 0.778673 +vt 0.937009 0.541064 +vt 0.936396 0.541147 +vt 0.936491 0.541590 +vt 0.937198 0.541506 +vt 0.935621 0.541202 +vt 0.935598 0.541665 +vt 0.934763 0.541189 +vt 0.934663 0.541727 +vt 0.808521 0.406497 +vt 0.808235 0.406654 +vt 0.807938 0.406841 +vt 0.812384 0.407603 +vt 0.812156 0.407326 +vt 0.811917 0.407079 +vt 0.808212 0.405589 +vt 0.808237 0.404577 +vt 0.807857 0.404511 +vt 0.807847 0.405646 +vt 0.808550 0.403615 +vt 0.808225 0.403438 +vt 0.807491 0.404448 +vt 0.807488 0.405714 +vt 0.807910 0.403253 +vt 0.621076 0.779133 +vt 0.621842 0.778890 +vt 0.621679 0.778501 +vt 0.620961 0.778582 +vt 0.622677 0.778859 +vt 0.622620 0.778501 +vt 0.623549 0.778972 +vt 0.623623 0.778595 +vt 0.624442 0.779296 +vt 0.624541 0.778755 +vt 0.809144 0.402862 +vt 0.808926 0.402617 +vt 0.808709 0.402340 +vt 0.809996 0.402477 +vt 0.810958 0.402466 +vt 0.811016 0.402195 +vt 0.809910 0.402200 +vt 0.811862 0.402797 +vt 0.812058 0.402569 +vt 0.811076 0.401878 +vt 0.809824 0.401880 +vt 0.812256 0.402297 +vt 0.625111 0.779381 +vt 0.625224 0.778921 +vt 0.750590 0.559045 +vt 0.751366 0.558933 +vt 0.751297 0.558490 +vt 0.750400 0.558607 +vt 0.752198 0.558855 +vt 0.752255 0.558388 +vt 0.752964 0.558856 +vt 0.753107 0.558312 +vt 0.812539 0.403445 +vt 0.812848 0.403289 +vt 0.813154 0.403103 +vt 0.812853 0.404353 +vt 0.812830 0.405365 +vt 0.813227 0.405432 +vt 0.813236 0.404298 +vt 0.812515 0.406327 +vt 0.812858 0.406505 +vt 0.813601 0.405496 +vt 0.813604 0.404230 +vt 0.813183 0.406691 +vt 0.604732 0.779189 +vt 0.605433 0.778963 +vt 0.605219 0.778630 +vt 0.604559 0.778673 +vt 0.812502 0.404418 +vt 0.812456 0.405302 +vt 0.812205 0.406152 +vt 0.607106 0.778963 +vt 0.607124 0.778630 +vt 0.493159 0.773315 +vt 0.493183 0.773154 +vt 0.492783 0.773209 +vt 0.492762 0.773360 +vt 0.518690 0.773365 +vt 0.518669 0.773495 +vt 0.519087 0.773538 +vt 0.519106 0.773417 +vt 0.492369 0.773146 +vt 0.492346 0.773308 +vt 0.519483 0.773501 +vt 0.519503 0.773371 +vt 0.493488 0.773442 +vt 0.493512 0.773172 +vt 0.493140 0.773543 +vt 0.518316 0.773063 +vt 0.518281 0.773214 +vt 0.518719 0.773242 +vt 0.518257 0.773373 +vt 0.519830 0.773386 +vt 0.492393 0.773038 +vt 0.491996 0.772834 +vt 0.491967 0.772965 +vt 0.491938 0.773157 +vt 0.492326 0.773535 +vt 0.491915 0.773427 +vt 0.492744 0.773574 +vt 0.752221 0.562377 +vt 0.751577 0.562449 +vt 0.751604 0.562797 +vt 0.752248 0.562717 +vt 0.750960 0.562526 +vt 0.750986 0.562866 +vt 0.751640 0.563079 +vt 0.752283 0.562992 +vt 0.751019 0.563141 +vt 0.752712 0.561878 +vt 0.752192 0.561893 +vt 0.752740 0.562329 +vt 0.751549 0.561953 +vt 0.750935 0.562041 +vt 0.750498 0.562139 +vt 0.750520 0.562591 +vt 0.750543 0.562905 +vt 0.750574 0.563159 +vt 0.750619 0.563428 +vt 0.751069 0.563434 +vt 0.751690 0.563380 +vt 0.752333 0.563285 +vt 0.752799 0.562896 +vt 0.752845 0.563166 +vt 0.752767 0.562643 +vt 0.936101 0.537652 +vt 0.936685 0.537599 +vt 0.936693 0.537246 +vt 0.936109 0.537307 +vt 0.937189 0.537543 +vt 0.937198 0.537199 +vt 0.936661 0.536957 +vt 0.936077 0.537025 +vt 0.937167 0.536917 +vt 0.935527 0.538145 +vt 0.936057 0.538141 +vt 0.935568 0.537688 +vt 0.936638 0.538100 +vt 0.937142 0.538033 +vt 0.609602 0.782219 +vt 0.609245 0.782252 +vt 0.609366 0.782715 +vt 0.609731 0.782716 +vt 0.609411 0.783036 +vt 0.609779 0.783063 +vt 0.609384 0.783296 +vt 0.609749 0.783346 +vt 0.609288 0.783574 +vt 0.609646 0.783647 +vt 0.937093 0.536613 +vt 0.936585 0.536644 +vt 0.936002 0.536721 +vt 0.935544 0.537110 +vt 0.935476 0.536830 +vt 0.935574 0.537370 +vt 0.683529 0.111987 +vt 0.683529 0.111110 +vt 0.682881 0.111108 +vt 0.682880 0.112004 +vt 0.683536 0.110232 +vt 0.682888 0.110210 +vt 0.682239 0.111105 +vt 0.682239 0.111982 +vt 0.682247 0.110227 +vt 0.684036 0.112651 +vt 0.684030 0.111928 +vt 0.683535 0.112762 +vt 0.684030 0.111110 +vt 0.684037 0.110292 +vt 0.684049 0.109566 +vt 0.683550 0.109453 +vt 0.682902 0.109414 +vt 0.682260 0.109449 +vt 0.681778 0.109558 +vt 0.681765 0.110283 +vt 0.681759 0.111102 +vt 0.681758 0.111919 +vt 0.682246 0.112757 +vt 0.681764 0.112642 +vt 0.682887 0.112797 +vt 0.752404 0.563654 +vt 0.751763 0.563759 +vt 0.751860 0.564186 +vt 0.752498 0.564071 +vt 0.751140 0.563803 +vt 0.751235 0.564220 +vt 0.683589 0.108422 +vt 0.682942 0.108359 +vt 0.682920 0.108800 +vt 0.683568 0.108853 +vt 0.682299 0.108417 +vt 0.682278 0.108849 +vt 0.752911 0.563507 +vt 0.750685 0.563770 +vt 0.750773 0.564156 +vt 0.681814 0.108598 +vt 0.681794 0.108999 +vt 0.684066 0.109008 +vt 0.752998 0.563893 +vt 0.752616 0.564482 +vt 0.753107 0.564275 +vt 0.493129 0.774511 +vt 0.493125 0.774177 +vt 0.492730 0.774170 +vt 0.492734 0.774485 +vt 0.493129 0.773840 +vt 0.492733 0.773854 +vt 0.492311 0.774169 +vt 0.492316 0.774503 +vt 0.492315 0.773833 +vt 0.493489 0.774926 +vt 0.493475 0.774582 +vt 0.493141 0.774804 +vt 0.493470 0.774188 +vt 0.493474 0.773792 +vt 0.491901 0.773777 +vt 0.491896 0.774173 +vt 0.491902 0.774567 +vt 0.492327 0.774796 +vt 0.491916 0.774911 +vt 0.492745 0.774760 +vt 0.493204 0.775272 +vt 0.493181 0.775174 +vt 0.492782 0.775107 +vt 0.492803 0.775199 +vt 0.493159 0.775023 +vt 0.492762 0.774965 +vt 0.527874 0.773871 +vt 0.527944 0.773766 +vt 0.527573 0.773670 +vt 0.527497 0.773784 +vt 0.492346 0.775015 +vt 0.492368 0.775166 +vt 0.605264 0.783027 +vt 0.605339 0.783166 +vt 0.605652 0.783063 +vt 0.605590 0.782952 +vt 0.605457 0.783327 +vt 0.605750 0.783195 +vt 0.605635 0.783488 +vt 0.605899 0.783327 +vt 0.493512 0.775186 +vt 0.491938 0.775171 +vt 0.491965 0.775351 +vt 0.527176 0.773473 +vt 0.527085 0.773613 +vt 0.527445 0.773884 +vt 0.527022 0.773738 +vt 0.527826 0.773962 +vt 0.528141 0.773970 +vt 0.528193 0.773871 +vt 0.528085 0.774229 +vt 0.528092 0.774116 +vt 0.527781 0.774093 +vt 0.527776 0.774198 +vt 0.528109 0.774042 +vt 0.527797 0.774027 +vt 0.527397 0.774029 +vt 0.527391 0.774142 +vt 0.527413 0.773956 +vt 0.605303 0.782471 +vt 0.605238 0.782690 +vt 0.605570 0.782686 +vt 0.605627 0.782501 +vt 0.605212 0.782827 +vt 0.605547 0.782797 +vt 0.605222 0.782925 +vt 0.605555 0.782873 +vt 0.526982 0.773832 +vt 0.526960 0.773926 +vt 0.526952 0.774065 +vt 0.527391 0.774333 +vt 0.526952 0.774291 +vt 0.527776 0.774377 +vt 0.528084 0.774419 +vt 0.752150 0.559571 +vt 0.751424 0.559620 +vt 0.751473 0.560441 +vt 0.752138 0.560402 +vt 0.750742 0.559737 +vt 0.750843 0.560555 +vt 0.751515 0.561257 +vt 0.752158 0.561211 +vt 0.750901 0.561359 +vt 0.752730 0.559664 +vt 0.624806 0.780149 +vt 0.625198 0.780110 +vt 0.750287 0.559953 +vt 0.750407 0.560741 +vt 0.750468 0.561501 +vt 0.752681 0.561240 +vt 0.752673 0.560474 +vt 0.935736 0.540484 +vt 0.936400 0.540456 +vt 0.936469 0.539628 +vt 0.935869 0.539647 +vt 0.936951 0.540363 +vt 0.936986 0.539536 +vt 0.936559 0.538803 +vt 0.935978 0.538830 +vt 0.937063 0.538722 +vt 0.935138 0.540379 +vt 0.608472 0.779993 +vt 0.608892 0.779850 +vt 0.608787 0.780815 +vt 0.609141 0.780694 +vt 0.609048 0.781598 +vt 0.609394 0.781521 +vt 0.935452 0.538790 +vt 0.935331 0.539563 +vt 0.528130 0.775418 +vt 0.528098 0.775062 +vt 0.527793 0.774986 +vt 0.527824 0.775325 +vt 0.528086 0.774711 +vt 0.527779 0.774653 +vt 0.527412 0.774976 +vt 0.527447 0.775333 +vt 0.527396 0.774625 +vt 0.606007 0.781054 +vt 0.605763 0.781372 +vt 0.606021 0.781548 +vt 0.606226 0.781271 +vt 0.605565 0.781757 +vt 0.605853 0.781883 +vt 0.605412 0.782145 +vt 0.605722 0.782220 +vt 0.526958 0.774629 +vt 0.526978 0.775035 +vt 0.527022 0.775445 +vt 0.527512 0.775638 +vt 0.527103 0.775796 +vt 0.527883 0.775614 +vt 0.528193 0.775722 +vt 0.935882 0.536335 +vt 0.936462 0.536249 +vt 0.936279 0.535807 +vt 0.935704 0.535904 +vt 0.936972 0.536227 +vt 0.936794 0.535795 +vt 0.682278 0.113779 +vt 0.682920 0.113843 +vt 0.682901 0.113407 +vt 0.682259 0.113353 +vt 0.683568 0.113784 +vt 0.683549 0.113358 +vt 0.935364 0.536473 +vt 0.609123 0.783927 +vt 0.609469 0.784029 +vt 0.608865 0.784319 +vt 0.609191 0.784452 +vt 0.684066 0.113601 +vt 0.684049 0.113205 +vt 0.681777 0.113197 +vt 0.935198 0.536074 +vt 0.935453 0.535489 +vt 0.934965 0.535689 +vt 0.622337 0.780517 +vt 0.622751 0.780460 +vt 0.622727 0.779916 +vt 0.622188 0.779978 +vt 0.623153 0.780557 +vt 0.623258 0.780029 +vt 0.622708 0.779354 +vt 0.622020 0.779408 +vt 0.623404 0.779475 +vt 0.622163 0.781144 +vt 0.622470 0.780964 +vt 0.621945 0.780732 +vt 0.622792 0.780915 +vt 0.623102 0.780995 +vt 0.623377 0.781203 +vt 0.623507 0.780808 +vt 0.623719 0.780330 +vt 0.624010 0.779818 +vt 0.621414 0.779692 +vt 0.621692 0.780232 +vt 0.606103 0.780463 +vt 0.606503 0.780385 +vt 0.606414 0.779883 +vt 0.605893 0.779969 +vt 0.606902 0.780463 +vt 0.606942 0.779969 +vt 0.606331 0.779359 +vt 0.605666 0.779440 +vt 0.607023 0.779440 +vt 0.606293 0.780857 +vt 0.605737 0.780700 +vt 0.606603 0.780791 +vt 0.606912 0.780857 +vt 0.607197 0.781054 +vt 0.607268 0.780699 +vt 0.607418 0.780246 +vt 0.607649 0.779740 +vt 0.606238 0.778908 +vt 0.605105 0.779740 +vt 0.605432 0.780247 +vt 0.604776 0.783008 +vt 0.604762 0.782875 +vt 0.604277 0.782932 +vt 0.604295 0.783108 +vt 0.604793 0.782697 +vt 0.604313 0.782704 +vt 0.603848 0.782988 +vt 0.603871 0.783206 +vt 0.603890 0.782710 +vt 0.604831 0.783148 +vt 0.604872 0.782423 +vt 0.604409 0.782363 +vt 0.604001 0.782303 +vt 0.603737 0.782252 +vt 0.603612 0.782714 +vt 0.603566 0.783033 +vt 0.603593 0.783287 +vt 0.603954 0.783436 +vt 0.603688 0.783554 +vt 0.604364 0.783292 +vt 0.607571 0.781083 +vt 0.607810 0.781550 +vt 0.608084 0.781295 +vt 0.607796 0.780717 +vt 0.607991 0.782021 +vt 0.608302 0.781873 +vt 0.608421 0.781031 +vt 0.608099 0.780322 +vt 0.608668 0.781723 +vt 0.518348 0.775552 +vt 0.518308 0.775217 +vt 0.517944 0.775484 +vt 0.517991 0.775891 +vt 0.518277 0.774818 +vt 0.517907 0.775000 +vt 0.518254 0.774420 +vt 0.517879 0.774516 +vt 0.517859 0.774107 +vt 0.608118 0.782422 +vt 0.608454 0.782363 +vt 0.608847 0.782303 +vt 0.620782 0.782964 +vt 0.620779 0.782827 +vt 0.620298 0.782828 +vt 0.620302 0.783007 +vt 0.620825 0.782651 +vt 0.620354 0.782603 +vt 0.619858 0.782858 +vt 0.619863 0.783080 +vt 0.619923 0.782584 +vt 0.621249 0.783062 +vt 0.621214 0.782953 +vt 0.620825 0.783111 +vt 0.621212 0.782852 +vt 0.621250 0.782717 +vt 0.621334 0.782503 +vt 0.620927 0.782385 +vt 0.620478 0.782272 +vt 0.620069 0.782189 +vt 0.935190 0.537700 +vt 0.935154 0.538102 +vt 0.935196 0.537423 +vt 0.935170 0.537198 +vt 0.935110 0.536957 +vt 0.620357 0.783201 +vt 0.619929 0.783320 +vt 0.526578 0.775659 +vt 0.526523 0.775161 +vt 0.526119 0.775337 +vt 0.526165 0.775949 +vt 0.526499 0.774668 +vt 0.526099 0.774734 +vt 0.624066 0.780817 +vt 0.624312 0.781402 +vt 0.624681 0.781152 +vt 0.624413 0.780429 +vt 0.624488 0.781983 +vt 0.624877 0.781848 +vt 0.526679 0.776085 +vt 0.526492 0.774254 +vt 0.526093 0.774228 +vt 0.624606 0.782472 +vt 0.625013 0.782428 +vt 0.625405 0.782431 +vt 0.625255 0.781777 +vt 0.625053 0.780988 +vt 0.623785 0.781201 +vt 0.621250 0.783750 +vt 0.621041 0.783531 +vt 0.620626 0.783739 +vt 0.620888 0.784017 +vt 0.620906 0.783307 +vt 0.620458 0.783453 +vt 0.620253 0.783977 +vt 0.620566 0.784314 +vt 0.620051 0.783629 +vt 0.491573 0.772918 +vt 0.491543 0.773255 +vt 0.621585 0.783554 +vt 0.621418 0.783383 +vt 0.621312 0.783211 +vt 0.935013 0.536647 +vt 0.934868 0.536299 +vt 0.619998 0.784213 +vt 0.620354 0.784600 +vt 0.621021 0.784593 +vt 0.620869 0.784918 +vt 0.621269 0.784248 +vt 0.621557 0.783933 +vt 0.608061 0.783356 +vt 0.607911 0.783575 +vt 0.608186 0.783839 +vt 0.608374 0.783558 +vt 0.607688 0.783787 +vt 0.607908 0.784108 +vt 0.608517 0.784102 +vt 0.608743 0.783760 +vt 0.608184 0.784428 +vt 0.517884 0.773180 +vt 0.517863 0.773365 +vt 0.517915 0.772972 +vt 0.607730 0.783357 +vt 0.607553 0.783521 +vt 0.607302 0.783653 +vt 0.607374 0.783956 +vt 0.607517 0.784322 +vt 0.607717 0.784687 +vt 0.607957 0.784989 +vt 0.608486 0.784692 +vt 0.608887 0.783454 +vt 0.608493 0.783309 +vt 0.608155 0.783162 +vt 0.606961 0.784055 +vt 0.606494 0.784079 +vt 0.606430 0.784478 +vt 0.607007 0.784447 +vt 0.606027 0.784033 +vt 0.605853 0.784421 +vt 0.606422 0.784877 +vt 0.607109 0.784838 +vt 0.605735 0.784807 +vt 0.606970 0.783729 +vt 0.606594 0.783748 +vt 0.606218 0.783712 +vt 0.605887 0.783623 +vt 0.605614 0.783920 +vt 0.605343 0.784278 +vt 0.605127 0.784635 +vt 0.605022 0.784929 +vt 0.605712 0.785127 +vt 0.606490 0.785206 +vt 0.607268 0.785162 +vt 0.526493 0.773971 +vt 0.526506 0.773791 +vt 0.526114 0.773648 +vt 0.526096 0.773878 +vt 0.526535 0.773663 +vt 0.526153 0.773478 +vt 0.624673 0.782811 +vt 0.624690 0.783037 +vt 0.625110 0.783109 +vt 0.625091 0.782834 +vt 0.624656 0.783210 +vt 0.625068 0.783323 +vt 0.526588 0.773534 +vt 0.526221 0.773308 +vt 0.624571 0.783388 +vt 0.624964 0.783545 +vt 0.625344 0.783715 +vt 0.625463 0.783457 +vt 0.625512 0.783208 +vt 0.625492 0.782892 +vt 0.608194 0.782697 +vt 0.608224 0.782877 +vt 0.608581 0.782934 +vt 0.608546 0.782704 +vt 0.608210 0.783015 +vt 0.608562 0.783115 +vt 0.608994 0.782991 +vt 0.608954 0.782710 +vt 0.608971 0.783215 +vt 0.517848 0.773826 +vt 0.517845 0.773644 +vt 0.517850 0.773508 +vt 0.605004 0.782023 +vt 0.605189 0.781551 +vt 0.604785 0.781296 +vt 0.604566 0.781874 +vt 0.605432 0.781084 +vt 0.605066 0.780718 +vt 0.604422 0.781031 +vt 0.604183 0.781723 +vt 0.604713 0.780322 +vt 0.604445 0.779994 +vt 0.604184 0.780815 +vt 0.603937 0.781598 +vt 0.621093 0.781997 +vt 0.621319 0.781542 +vt 0.620946 0.781239 +vt 0.620677 0.781798 +vt 0.621603 0.781095 +vt 0.621280 0.780682 +vt 0.620601 0.780954 +vt 0.620300 0.781627 +vt 0.620959 0.780261 +vt 0.621471 0.782187 +vt 0.621657 0.781813 +vt 0.621889 0.781444 +vt 0.620697 0.779951 +vt 0.934976 0.539355 +vt 0.934796 0.540056 +vt 0.935088 0.538673 +vt 0.622925 0.784075 +vt 0.622445 0.784097 +vt 0.622365 0.784455 +vt 0.622959 0.784427 +vt 0.621970 0.784050 +vt 0.621779 0.784396 +vt 0.622326 0.784843 +vt 0.623033 0.784809 +vt 0.621628 0.784772 +vt 0.491526 0.774672 +vt 0.491544 0.775101 +vt 0.491520 0.774183 +vt 0.491525 0.773691 +vt 0.621558 0.785123 +vt 0.622348 0.785205 +vt 0.623149 0.785165 +vt 0.623668 0.784669 +vt 0.623868 0.785005 +vt 0.623491 0.784311 +vt 0.623356 0.783983 +vt 0.605299 0.783747 +vt 0.605076 0.783541 +vt 0.604673 0.783797 +vt 0.604952 0.784059 +vt 0.604926 0.783331 +vt 0.604484 0.783529 +vt 0.604326 0.784053 +vt 0.604660 0.784370 +vt 0.604099 0.783726 +vt 0.603854 0.783889 +vt 0.604112 0.784264 +vt 0.604492 0.784627 +vt 0.526670 0.773369 +vt 0.526786 0.773186 +vt 0.526472 0.772860 +vt 0.526325 0.773094 +vt 0.623936 0.783636 +vt 0.623691 0.783828 +vt 0.623908 0.784115 +vt 0.624214 0.783870 +vt 0.624429 0.783615 +vt 0.624533 0.784135 +vt 0.624792 0.783824 +vt 0.624166 0.784431 +vt 0.527299 0.773343 +vt 0.526941 0.773018 +vt 0.491573 0.775425 +vt 0.624434 0.784733 +vt 0.624852 0.784394 +vt 0.625147 0.784037 +vt 0.518667 0.774361 +vt 0.518685 0.774707 +vt 0.519098 0.774672 +vt 0.519082 0.774344 +vt 0.518710 0.775054 +vt 0.519120 0.775002 +vt 0.519489 0.774713 +vt 0.519474 0.774368 +vt 0.519509 0.775060 +vt 0.518743 0.775345 +vt 0.519148 0.775279 +vt 0.519539 0.775352 +vt 0.622105 0.781688 +vt 0.622335 0.781426 +vt 0.621907 0.782010 +vt 0.519830 0.774830 +vt 0.519815 0.774432 +vt 0.450183 0.774188 +vt 0.450452 0.774190 +vt 0.450451 0.773784 +vt 0.450202 0.773782 +vt 0.450719 0.774188 +vt 0.450700 0.773782 +vt 0.450452 0.773386 +vt 0.450184 0.773383 +vt 0.450720 0.773383 +vt 0.449826 0.774567 +vt 0.450127 0.774575 +vt 0.449934 0.774181 +vt 0.450453 0.774578 +vt 0.450778 0.774575 +vt 0.451077 0.774567 +vt 0.450968 0.774180 +vt 0.450931 0.773773 +vt 0.450968 0.773374 +vt 0.527612 0.775844 +vt 0.527226 0.776035 +vt 0.450778 0.773020 +vt 0.450453 0.773024 +vt 0.450128 0.773020 +vt 0.622591 0.781268 +vt 0.449970 0.773773 +vt 0.449934 0.773374 +vn -0.3538 0.9255 0.1351 +vn -0.3401 0.8781 0.3365 +vn 0.0000 0.9414 0.3374 +vn -0.0000 0.9905 0.1378 +vn -0.2830 0.7124 0.6421 +vn -0.0000 0.7665 0.6423 +vn 0.3401 0.8781 0.3365 +vn 0.3538 0.9255 0.1351 +vn 0.2830 0.7125 0.6421 +vn -0.7070 0.7048 0.0590 +vn -0.7045 0.6988 0.1240 +vn -0.3548 0.9323 0.0710 +vn -0.6764 0.6596 0.3276 +vn -0.5627 0.5290 0.6353 +vn -0.2830 0.7125 0.6421 +vn -0.5627 0.5290 0.6352 +vn -0.3518 0.3042 0.8853 +vn -0.1764 0.4200 0.8902 +vn 0.0000 0.4544 0.8908 +vn -0.0000 0.7664 0.6423 +vn 0.1764 0.4200 0.8902 +vn 0.3518 0.3042 0.8853 +vn 0.5627 0.5290 0.6352 +vn 0.5627 0.5290 0.6353 +vn 0.6764 0.6596 0.3276 +vn 0.7045 0.6988 0.1240 +vn 0.3548 0.9323 0.0710 +vn 0.7069 0.7048 0.0590 +vn -0.0000 0.9972 0.0743 +vn -0.3547 0.9323 0.0710 +vn 0.9315 0.3486 0.1038 +vn 0.8951 0.3239 0.3064 +vn 0.9583 -0.0155 0.2854 +vn 0.9965 -0.0045 0.0837 +vn 0.7462 0.2499 0.6170 +vn 0.8002 -0.0326 0.5989 +vn 0.8951 -0.3553 0.2695 +vn 0.9315 -0.3578 0.0654 +vn 0.7463 -0.3153 0.5863 +vn 0.9347 0.3531 0.0395 +vn 0.8951 0.3240 0.3063 +vn 0.7463 0.2499 0.6170 +vn 0.4677 0.1291 0.8744 +vn 0.5020 -0.0469 0.8636 +vn 0.4677 -0.2231 0.8553 +vn 0.7463 -0.3153 0.5862 +vn 0.3518 -0.3984 0.8471 +vn 0.5627 -0.5948 0.5741 +vn 0.5627 -0.5947 0.5742 +vn 0.6764 -0.6913 0.2543 +vn 0.7045 -0.7081 0.0475 +vn 0.9347 -0.3553 0.0010 +vn 0.7070 -0.7070 -0.0178 +vn 0.9998 -0.0011 0.0201 +vn 0.3538 -0.9347 0.0340 +vn 0.3401 -0.9094 0.2393 +vn 0.0000 -0.9724 0.2334 +vn 0.0000 -0.9996 0.0296 +vn 0.2830 -0.7779 0.5611 +vn 0.0000 -0.8315 0.5555 +vn -0.3401 -0.9094 0.2393 +vn -0.3537 -0.9347 0.0340 +vn -0.2830 -0.7778 0.5611 +vn 0.7045 -0.7081 0.0476 +vn 0.3548 -0.9345 -0.0305 +vn 0.6764 -0.6912 0.2543 +vn 0.1764 -0.5140 0.8395 +vn 0.2830 -0.7778 0.5611 +vn -0.0000 -0.5483 0.8363 +vn -0.0000 -0.8316 0.5554 +vn -0.1764 -0.5140 0.8395 +vn -0.3518 -0.3984 0.8471 +vn -0.5627 -0.5947 0.5741 +vn -0.5627 -0.5947 0.5742 +vn -0.6764 -0.6912 0.2543 +vn -0.7045 -0.7081 0.0476 +vn -0.3548 -0.9345 -0.0305 +vn -0.7070 -0.7070 -0.0178 +vn 0.0000 -0.9994 -0.0343 +vn -0.9315 -0.3578 0.0654 +vn -0.8951 -0.3552 0.2694 +vn -0.9583 -0.0155 0.2854 +vn -0.9965 -0.0045 0.0837 +vn -0.7462 -0.3153 0.5863 +vn -0.8001 -0.0326 0.5989 +vn -0.8951 0.3240 0.3064 +vn -0.9315 0.3486 0.1038 +vn -0.7462 0.2499 0.6170 +vn -0.9347 -0.3553 0.0010 +vn -0.8951 -0.3553 0.2694 +vn -0.7463 -0.3153 0.5863 +vn -0.4677 -0.2231 0.8553 +vn -0.7463 -0.3153 0.5862 +vn -0.5021 -0.0469 0.8635 +vn -0.8002 -0.0325 0.5989 +vn -0.4677 0.1291 0.8744 +vn -0.7463 0.2499 0.6170 +vn -0.9347 0.3531 0.0396 +vn -0.9998 -0.0011 0.0201 +vn -0.9347 -0.3553 0.0011 +vn 0.4435 -0.2154 0.8700 +vn 0.4794 -0.0476 0.8763 +vn 0.5735 -0.0444 0.8180 +vn 0.5331 -0.2457 0.8096 +vn 0.4435 0.1198 0.8882 +vn 0.5331 0.1564 0.8315 +vn 0.4681 -0.0480 0.8824 +vn 0.4374 -0.2129 0.8737 +vn 0.4374 0.1169 0.8916 +vn 0.1818 -0.2340 0.9551 +vn 0.2461 -0.1457 0.9582 +vn 0.3307 -0.3779 0.8648 +vn 0.2678 -0.0523 0.9621 +vn 0.2461 0.0410 0.9684 +vn 0.1818 0.1291 0.9748 +vn 0.3307 0.2820 0.9006 +vn 0.4014 0.3557 0.8440 +vn 0.3315 0.2832 0.8999 +vn 0.1982 0.1456 0.9693 +vn 0.2581 0.0444 0.9651 +vn 0.2752 -0.0522 0.9600 +vn 0.2583 -0.1491 0.9545 +vn 0.3315 -0.3790 0.8640 +vn 0.1978 -0.2497 0.9479 +vn 0.4013 -0.4450 0.8006 +vn -0.0103 -0.0268 0.9996 +vn -0.0000 -0.0249 0.9997 +vn 0.0000 0.0421 0.9991 +vn -0.0336 0.0355 0.9988 +vn 0.0103 -0.0268 0.9996 +vn 0.0336 0.0355 0.9988 +vn 0.0000 0.1827 0.9832 +vn -0.0825 0.1664 0.9826 +vn 0.0825 0.1664 0.9826 +vn -0.0034 -0.0509 0.9987 +vn -0.0017 -0.0498 0.9988 +vn -0.0207 -0.0336 0.9992 +vn -0.0000 -0.0494 0.9988 +vn 0.0017 -0.0498 0.9988 +vn 0.0034 -0.0509 0.9987 +vn 0.0207 -0.0336 0.9992 +vn 0.0673 0.0132 0.9976 +vn 0.1647 0.1117 0.9800 +vn -0.1647 0.1117 0.9800 +vn -0.0673 0.0132 0.9976 +vn 0.0274 -0.0440 0.9987 +vn 0.0294 -0.0542 0.9981 +vn 0.0962 -0.0540 0.9939 +vn 0.0896 -0.0205 0.9958 +vn 0.0275 -0.0645 0.9975 +vn 0.0896 -0.0876 0.9921 +vn 0.2358 -0.0527 0.9704 +vn 0.2195 0.0296 0.9752 +vn 0.2195 -0.1351 0.9662 +vn 0.0045 -0.0526 0.9986 +vn 0.0048 -0.0543 0.9985 +vn 0.0045 -0.0559 0.9984 +vn 0.0034 -0.0576 0.9983 +vn 0.0207 -0.0749 0.9970 +vn 0.0673 -0.1213 0.9903 +vn 0.1647 -0.2173 0.9621 +vn 0.0103 -0.0817 0.9966 +vn -0.0000 -0.0836 0.9965 +vn -0.0000 -0.1501 0.9887 +vn 0.0336 -0.1435 0.9891 +vn -0.0103 -0.0817 0.9966 +vn -0.0336 -0.1435 0.9891 +vn -0.0000 -0.2882 0.9576 +vn 0.0825 -0.2719 0.9588 +vn -0.0825 -0.2719 0.9588 +vn 0.0017 -0.0588 0.9983 +vn -0.0000 -0.0591 0.9983 +vn -0.0017 -0.0588 0.9983 +vn -0.0034 -0.0576 0.9983 +vn -0.0207 -0.0749 0.9970 +vn -0.0673 -0.1213 0.9903 +vn -0.1647 -0.2173 0.9621 +vn -0.0275 -0.0645 0.9975 +vn -0.0294 -0.0542 0.9981 +vn -0.0962 -0.0540 0.9939 +vn -0.0896 -0.0876 0.9921 +vn -0.0274 -0.0440 0.9987 +vn -0.0896 -0.0204 0.9958 +vn -0.2358 -0.0527 0.9704 +vn -0.2195 -0.1351 0.9662 +vn -0.2195 0.0296 0.9752 +vn -0.0045 -0.0559 0.9984 +vn -0.0048 -0.0543 0.9985 +vn -0.0045 -0.0526 0.9986 +vn -0.0376 0.0448 0.9983 +vn -0.0000 0.0539 0.9985 +vn 0.0000 -0.0183 0.9998 +vn -0.0125 -0.0214 0.9997 +vn 0.0377 0.0449 0.9983 +vn 0.0125 -0.0214 0.9997 +vn 0.0000 -0.0459 0.9989 +vn -0.0029 -0.0466 0.9989 +vn 0.0029 -0.0466 0.9989 +vn -0.1818 0.1291 0.9748 +vn -0.0936 0.1935 0.9766 +vn -0.0728 0.0188 0.9972 +vn -0.0000 0.2153 0.9765 +vn 0.0936 0.1935 0.9766 +vn 0.0728 0.0188 0.9972 +vn 0.0241 -0.0301 0.9993 +vn 0.0056 -0.0487 0.9988 +vn -0.0056 -0.0487 0.9988 +vn -0.0241 -0.0301 0.9993 +vn 0.0989 -0.0164 0.9950 +vn 0.1079 -0.0539 0.9927 +vn 0.0360 -0.0542 0.9979 +vn 0.0329 -0.0417 0.9986 +vn 0.0990 -0.0916 0.9909 +vn 0.0329 -0.0667 0.9972 +vn 0.0084 -0.0543 0.9985 +vn 0.0077 -0.0513 0.9987 +vn 0.0076 -0.0572 0.9983 +vn 0.0728 -0.1267 0.9893 +vn 0.0241 -0.0783 0.9966 +vn 0.0056 -0.0598 0.9982 +vn 0.0377 -0.1528 0.9875 +vn 0.0000 -0.1617 0.9868 +vn 0.0000 -0.0901 0.9959 +vn 0.0125 -0.0871 0.9961 +vn -0.0376 -0.1528 0.9875 +vn -0.0125 -0.0871 0.9961 +vn 0.0000 -0.0627 0.9980 +vn 0.0029 -0.0619 0.9981 +vn -0.0029 -0.0619 0.9981 +vn 0.0936 -0.2982 0.9499 +vn 0.0000 -0.3199 0.9475 +vn -0.0936 -0.2982 0.9499 +vn -0.1818 -0.2340 0.9551 +vn -0.0728 -0.1267 0.9893 +vn -0.0241 -0.0783 0.9966 +vn -0.0056 -0.0598 0.9982 +vn -0.0990 -0.0916 0.9909 +vn -0.1079 -0.0539 0.9927 +vn -0.0359 -0.0542 0.9979 +vn -0.0329 -0.0667 0.9972 +vn -0.0990 -0.0164 0.9950 +vn -0.0329 -0.0417 0.9986 +vn -0.0084 -0.0543 0.9985 +vn -0.0077 -0.0572 0.9983 +vn -0.0077 -0.0513 0.9987 +vn -0.2461 -0.1457 0.9582 +vn -0.2678 -0.0523 0.9621 +vn -0.2461 0.0410 0.9684 +vn -0.3605 -0.8879 -0.2856 +vn -0.3544 -0.9351 -0.0046 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 -0.9510 -0.3091 +vn -0.3385 -0.9226 0.1851 +vn 0.0000 -0.9792 0.2029 +vn 0.3544 -0.9351 -0.0044 +vn 0.3605 -0.8880 -0.2855 +vn 0.3385 -0.9226 0.1852 +vn -0.6397 -0.6770 -0.3639 +vn -0.6488 -0.7261 -0.2276 +vn -0.3522 -0.8179 -0.4549 +vn -0.6423 -0.7664 -0.0128 +vn -0.6232 -0.7692 0.1415 +vn -0.6185 -0.7612 0.1950 +vn -0.3353 -0.9100 0.2438 +vn 0.0000 -0.9649 0.2625 +vn 0.3354 -0.9100 0.2439 +vn 0.6185 -0.7611 0.1953 +vn 0.6234 -0.7690 0.1415 +vn 0.6423 -0.7663 -0.0129 +vn 0.6488 -0.7261 -0.2276 +vn 0.3522 -0.8179 -0.4549 +vn 0.6398 -0.6769 -0.3640 +vn 0.0000 -0.8711 -0.4912 +vn -0.1688 -0.4924 0.8538 +vn 0.0000 -0.5293 0.8485 +vn 0.0000 -0.6259 0.7799 +vn -0.2042 -0.5829 0.7865 +vn 0.1688 -0.4924 0.8538 +vn 0.2043 -0.5828 0.7865 +vn 0.0001 -0.5298 0.8481 +vn -0.1687 -0.4941 0.8529 +vn 0.1688 -0.4941 0.8529 +vn -0.3307 -0.3779 0.8648 +vn 0.1012 -0.3208 0.9417 +vn -0.0000 -0.3433 0.9392 +vn -0.1013 -0.3209 0.9417 +vn -0.3313 -0.3793 0.8639 +vn -0.1978 -0.2498 0.9479 +vn -0.4013 -0.4450 0.8006 +vn 0.1689 0.3971 0.9021 +vn -0.0000 0.4342 0.9008 +vn -0.0000 0.5374 0.8433 +vn 0.2042 0.4942 0.8450 +vn -0.1689 0.3970 0.9021 +vn -0.2043 0.4942 0.8450 +vn -0.0000 0.4344 0.9007 +vn 0.1687 0.3987 0.9014 +vn -0.1688 0.3987 0.9014 +vn -0.3306 0.2819 0.9007 +vn -0.4013 0.3556 0.8441 +vn -0.3315 0.2832 0.8999 +vn -0.1981 0.1453 0.9694 +vn -0.1014 0.2169 0.9709 +vn 0.0000 0.2394 0.9709 +vn 0.1013 0.2169 0.9709 +vn -0.4434 0.1198 0.8883 +vn -0.4795 -0.0476 0.8763 +vn -0.5734 -0.0445 0.8181 +vn -0.5330 0.1565 0.8315 +vn -0.4435 -0.2154 0.8700 +vn -0.5331 -0.2457 0.8096 +vn -0.4685 -0.0479 0.8822 +vn -0.4370 0.1167 0.8918 +vn -0.4371 -0.2125 0.8740 +vn -0.2583 -0.1490 0.9545 +vn -0.2753 -0.0522 0.9600 +vn -0.2581 0.0447 0.9651 +vn -0.3071 0.7014 0.6432 +vn 0.0000 0.7909 0.6119 +vn -0.0000 0.4160 0.9094 +vn -0.1643 0.3615 0.9178 +vn 0.3071 0.7014 0.6432 +vn 0.1643 0.3615 0.9178 +vn 0.0000 0.1965 0.9805 +vn -0.0865 0.1716 0.9814 +vn 0.0865 0.1716 0.9814 +vn -0.7998 0.5134 0.3110 +vn -0.3804 0.9117 0.1554 +vn -0.5439 0.4128 0.7306 +vn -0.0000 0.9906 0.1371 +vn 0.3804 0.9117 0.1554 +vn 0.7998 0.5134 0.3111 +vn 0.5438 0.4128 0.7306 +vn 0.2835 0.2133 0.9350 +vn 0.1582 0.1022 0.9821 +vn -0.1582 0.1022 0.9821 +vn -0.2834 0.2133 0.9350 +vn -0.5438 0.4128 0.7307 +vn 0.5805 0.1159 0.8060 +vn 0.5455 -0.0455 0.8369 +vn 0.3189 -0.0514 0.9464 +vn 0.3222 0.0573 0.9450 +vn 0.5809 -0.2026 0.7884 +vn 0.3223 -0.1594 0.9331 +vn 0.2035 -0.0531 0.9776 +vn 0.1960 0.0188 0.9804 +vn 0.1961 -0.1250 0.9726 +vn 0.7998 0.5134 0.3110 +vn 0.8197 0.1188 0.5603 +vn 0.5805 0.1159 0.8059 +vn 0.7692 -0.0347 0.6380 +vn 0.8201 -0.1789 0.5436 +vn 0.5809 -0.2026 0.7883 +vn 0.8005 -0.5443 0.2510 +vn 0.5448 -0.4901 0.6804 +vn 0.2839 -0.3137 0.9061 +vn 0.1583 -0.2081 0.9652 +vn 0.3079 -0.7686 0.5608 +vn -0.0000 -0.8545 0.5195 +vn 0.0000 -0.5131 0.8583 +vn 0.1647 -0.4596 0.8727 +vn -0.3079 -0.7686 0.5608 +vn -0.1646 -0.4596 0.8727 +vn 0.0000 -0.3018 0.9534 +vn 0.0865 -0.2770 0.9570 +vn -0.0866 -0.2771 0.9569 +vn 0.3807 -0.9233 0.0507 +vn -0.0000 -0.9997 0.0235 +vn -0.3807 -0.9233 0.0507 +vn -0.8005 -0.5443 0.2510 +vn -0.5449 -0.4901 0.6804 +vn -0.5448 -0.4901 0.6804 +vn -0.2839 -0.3137 0.9061 +vn -0.1583 -0.2081 0.9652 +vn -0.5809 -0.2026 0.7884 +vn -0.5455 -0.0455 0.8369 +vn -0.3188 -0.0514 0.9464 +vn -0.3223 -0.1594 0.9331 +vn -0.5805 0.1159 0.8059 +vn -0.3222 0.0573 0.9449 +vn -0.2035 -0.0531 0.9776 +vn -0.1961 -0.1250 0.9726 +vn -0.1959 0.0189 0.9804 +vn -0.8201 -0.1789 0.5436 +vn -0.8201 -0.1788 0.5436 +vn -0.7692 -0.0347 0.6381 +vn -0.8197 0.1188 0.5603 +vn -0.5805 0.1159 0.8060 +vn -0.3470 -0.4721 -0.8104 +vn -0.3521 -0.6492 -0.6743 +vn 0.0000 -0.6906 -0.7232 +vn 0.0001 -0.4999 -0.8661 +vn -0.3521 -0.6493 -0.6742 +vn -0.3526 -0.7590 -0.5473 +vn -0.0000 -0.8086 -0.5884 +vn -0.0000 -0.6907 -0.7231 +vn 0.3521 -0.6492 -0.6742 +vn 0.3470 -0.4721 -0.8104 +vn 0.3525 -0.7591 -0.5473 +vn 0.3521 -0.6493 -0.6741 +vn -0.6197 -0.2196 -0.7535 +vn -0.6334 -0.3961 -0.6648 +vn -0.3362 -0.2562 -0.9063 +vn -0.6334 -0.3962 -0.6647 +vn -0.6394 -0.5387 -0.5486 +vn -0.6399 -0.6279 -0.4430 +vn 0.6399 -0.6279 -0.4431 +vn 0.3526 -0.7591 -0.5472 +vn 0.6399 -0.6280 -0.4429 +vn 0.6394 -0.5388 -0.5485 +vn 0.6334 -0.3962 -0.6648 +vn 0.3361 -0.2562 -0.9063 +vn 0.6196 -0.2196 -0.7535 +vn -0.0000 -0.2690 -0.9631 +vn -0.2622 -0.9312 -0.2532 +vn -0.0002 -0.9653 -0.2610 +vn -0.0001 -0.9974 -0.0722 +vn -0.2688 -0.9606 -0.0706 +vn 0.2618 -0.9313 -0.2532 +vn 0.2686 -0.9607 -0.0703 +vn -0.0001 -0.9840 0.1782 +vn -0.2724 -0.9468 0.1712 +vn 0.2726 -0.9467 0.1714 +vn -0.6525 -0.7115 -0.2607 +vn -0.2606 -0.9085 -0.3268 +vn -0.6519 -0.7303 -0.2042 +vn -0.0004 -0.9416 -0.3367 +vn 0.2607 -0.9084 -0.3268 +vn 0.6526 -0.7115 -0.2607 +vn 0.6519 -0.7303 -0.2042 +vn 0.6570 -0.7515 -0.0593 +vn 0.6626 -0.7370 0.1336 +vn 0.6652 -0.6977 0.2661 +vn 0.2718 -0.9000 0.3407 +vn 0.0001 -0.9355 0.3534 +vn -0.2716 -0.9001 0.3407 +vn -0.6625 -0.7370 0.1336 +vn -0.6652 -0.6977 0.2661 +vn -0.6571 -0.7515 -0.0592 +vn 0.2624 0.9540 -0.1454 +vn 0.0002 0.9888 -0.1493 +vn -0.0001 0.9992 0.0393 +vn 0.2686 0.9625 0.0373 +vn -0.2622 0.9540 -0.1457 +vn -0.2686 0.9625 0.0373 +vn -0.0000 0.9605 0.2783 +vn 0.2723 0.9242 0.2678 +vn -0.2725 0.9241 0.2680 +vn 0.6528 0.7363 -0.1781 +vn 0.2608 0.9397 -0.2214 +vn 0.6521 0.7487 -0.1195 +vn -0.0000 0.9737 -0.2279 +vn -0.2608 0.9397 -0.2214 +vn -0.6528 0.7363 -0.1781 +vn -0.6522 0.7486 -0.1195 +vn -0.2622 0.9540 -0.1456 +vn -0.6572 0.7533 0.0251 +vn -0.2686 0.9625 0.0372 +vn -0.6626 0.7194 0.2087 +vn -0.6657 0.6697 0.3293 +vn -0.2722 0.8643 0.4229 +vn -0.0001 0.8985 0.4389 +vn 0.2720 0.8644 0.4228 +vn 0.6628 0.7192 0.2086 +vn 0.6663 0.6692 0.3290 +vn 0.6569 0.7536 0.0252 +vn -0.2486 0.0885 0.9646 +vn -0.2458 -0.0732 0.9666 +vn 0.0000 -0.0755 0.9971 +vn 0.0001 0.0916 0.9958 +vn -0.2473 -0.2275 0.9419 +vn -0.0000 -0.2348 0.9720 +vn 0.2458 -0.0731 0.9666 +vn 0.2487 0.0887 0.9645 +vn 0.2472 -0.2273 0.9419 +vn -0.6403 0.2328 0.7320 +vn -0.6324 0.0697 0.7715 +vn -0.2560 0.2960 0.9203 +vn -0.6292 -0.0588 0.7750 +vn -0.6307 -0.1812 0.7545 +vn -0.6370 -0.3254 0.6988 +vn -0.2530 -0.4105 0.8761 +vn 0.0000 -0.4247 0.9053 +vn 0.2531 -0.4108 0.8759 +vn 0.6370 -0.3254 0.6988 +vn 0.6307 -0.1812 0.7546 +vn 0.6292 -0.0587 0.7750 +vn 0.6324 0.0697 0.7715 +vn 0.2559 0.2956 0.9204 +vn 0.6403 0.2328 0.7320 +vn -0.0000 0.3062 0.9520 +vn -0.2696 -0.8470 0.4582 +vn 0.0001 -0.8799 0.4751 +vn 0.0000 -0.7825 0.6226 +vn -0.2661 -0.7541 0.6004 +vn 0.2696 -0.8471 0.4580 +vn 0.2661 -0.7541 0.6005 +vn 0.0000 -0.7826 0.6225 +vn 0.0001 -0.6254 0.7803 +vn -0.2605 -0.6034 0.7537 +vn 0.2661 -0.7541 0.6004 +vn 0.2606 -0.6035 0.7536 +vn -0.6614 -0.6590 0.3581 +vn 0.6615 -0.6590 0.3581 +vn 0.6554 -0.5898 0.4718 +vn 0.6469 -0.4749 0.5966 +vn -0.6469 -0.4749 0.5966 +vn -0.6554 -0.5898 0.4718 +vn -0.2604 -0.6035 0.7537 +vn -0.6469 -0.4750 0.5966 +vn -0.3238 0.2072 -0.9232 +vn -0.3219 0.0724 -0.9440 +vn -0.0000 0.0767 -0.9971 +vn 0.0001 0.2175 -0.9761 +vn -0.3256 -0.0687 -0.9430 +vn -0.0000 -0.0710 -0.9975 +vn 0.3221 0.0722 -0.9439 +vn 0.3239 0.2071 -0.9231 +vn 0.3255 -0.0687 -0.9430 +vn -0.6143 0.3174 -0.7225 +vn -0.6030 0.1775 -0.7777 +vn -0.3320 0.3731 -0.8663 +vn -0.6003 0.0610 -0.7974 +vn -0.6055 -0.0612 -0.7935 +vn 0.6057 -0.0615 -0.7933 +vn 0.6006 0.0606 -0.7973 +vn 0.6032 0.1771 -0.7777 +vn 0.3321 0.3732 -0.8663 +vn 0.6143 0.3172 -0.7226 +vn 0.0000 0.3930 -0.9195 +vn -0.3504 0.8028 -0.4825 +vn -0.3483 0.7088 -0.6134 +vn -0.0000 0.7534 -0.6576 +vn 0.0001 0.8546 -0.5193 +vn -0.3420 0.5578 -0.7562 +vn 0.0000 0.5905 -0.8071 +vn -0.0000 0.8546 -0.5193 +vn -0.0000 0.7534 -0.6575 +vn 0.3483 0.7088 -0.6134 +vn 0.3504 0.8027 -0.4825 +vn 0.3420 0.5578 -0.7562 +vn 0.3483 0.7088 -0.6135 +vn -0.6386 0.7066 -0.3047 +vn -0.6374 0.6650 -0.3893 +vn -0.3505 0.8027 -0.4825 +vn -0.3511 0.8533 -0.3855 +vn -0.6350 0.5893 -0.4996 +vn -0.6271 0.4683 -0.6225 +vn -0.6271 0.4682 -0.6225 +vn 0.6270 0.4682 -0.6226 +vn 0.6348 0.5893 -0.4997 +vn 0.6375 0.6650 -0.3892 +vn 0.3511 0.8532 -0.3856 +vn 0.6387 0.7065 -0.3049 +vn 0.0000 0.9083 -0.4183 +vn -0.3380 0.8948 0.2916 +vn -0.3548 0.9296 0.1003 +vn -0.0000 0.9937 0.1124 +vn -0.0000 0.9487 0.3162 +vn -0.3612 0.9109 -0.1995 +vn 0.0000 0.9759 -0.2182 +vn 0.3548 0.9295 0.1003 +vn 0.3380 0.8948 0.2916 +vn 0.3612 0.9109 -0.1995 +vn -0.6183 0.7339 0.2812 +vn -0.6228 0.7479 0.2297 +vn -0.3380 0.8949 0.2915 +vn -0.3350 0.8760 0.3469 +vn -0.6428 0.7626 0.0727 +vn -0.3548 0.9295 0.1003 +vn -0.6497 0.7441 -0.1557 +vn 0.6497 0.7441 -0.1557 +vn 0.6428 0.7625 0.0731 +vn 0.6226 0.7480 0.2299 +vn 0.3349 0.8760 0.3470 +vn 0.6181 0.7341 0.2812 +vn -0.0000 0.9282 0.3720 +vn -0.3363 -0.9090 -0.2461 +vn -0.0000 -0.9678 -0.2516 +vn 0.0000 -0.9435 -0.3313 +vn -0.2866 -0.9028 -0.3205 +vn 0.3363 -0.9090 -0.2461 +vn 0.2866 -0.9029 -0.3205 +vn -0.0000 -0.9366 -0.3505 +vn -0.2664 -0.9020 -0.3396 +vn 0.2664 -0.9020 -0.3396 +vn -0.7540 -0.6411 -0.1433 +vn 0.7540 -0.6410 -0.1433 +vn 0.6894 -0.6848 -0.2364 +vn 0.6612 -0.7016 -0.2657 +vn -0.6612 -0.7016 -0.2657 +vn -0.6893 -0.6848 -0.2364 +vn 0.3365 0.9311 -0.1411 +vn 0.0000 0.9902 -0.1398 +vn 0.0000 0.9751 -0.2220 +vn 0.2868 0.9333 -0.2159 +vn -0.3364 0.9311 -0.1412 +vn -0.2868 0.9333 -0.2159 +vn 0.0000 0.9703 -0.2419 +vn 0.2666 0.9347 -0.2350 +vn -0.2666 0.9347 -0.2350 +vn 0.7540 0.6532 -0.0695 +vn -0.7540 0.6532 -0.0695 +vn -0.3365 0.9311 -0.1412 +vn -0.6895 0.7070 -0.1571 +vn -0.2869 0.9333 -0.2158 +vn -0.6615 0.7270 -0.1843 +vn 0.6614 0.7270 -0.1843 +vn 0.6895 0.7070 -0.1572 +vn -0.3490 0.7609 0.5470 +vn -0.3403 0.8302 0.4415 +vn 0.0003 0.8832 0.4690 +vn 0.0000 0.8140 0.5809 +vn -0.3370 0.8615 0.3798 +vn -0.0003 0.9140 0.4057 +vn 0.3405 0.8303 0.4413 +vn 0.3490 0.7609 0.5470 +vn 0.3369 0.8615 0.3800 +vn -0.6600 0.4771 0.5802 +vn -0.6368 0.6220 0.4556 +vn -0.3490 0.7609 0.5471 +vn -0.3683 0.6040 0.7068 +vn -0.6250 0.6893 0.3665 +vn -0.6204 0.7194 0.3122 +vn 0.6203 0.7196 0.3121 +vn 0.6251 0.6893 0.3664 +vn 0.6368 0.6220 0.4555 +vn 0.3683 0.6040 0.7068 +vn 0.6601 0.4771 0.5802 +vn 0.0000 0.6549 0.7557 +vn 0.2706 0.8030 0.5310 +vn -0.0001 0.8344 0.5512 +vn 0.0000 0.7221 0.6917 +vn 0.2685 0.6954 0.6666 +vn -0.2707 0.8029 0.5311 +vn -0.2684 0.6954 0.6666 +vn 0.2684 0.6954 0.6666 +vn -0.0001 0.5397 0.8419 +vn 0.2638 0.5202 0.8123 +vn -0.2639 0.5202 0.8122 +vn 0.6633 0.6234 0.4140 +vn -0.6628 0.6238 0.4142 +vn -0.6583 0.5423 0.5220 +vn -0.2684 0.6953 0.6667 +vn -0.6507 0.4076 0.6407 +vn 0.6507 0.4076 0.6407 +vn 0.6583 0.5423 0.5220 +vn 0.8390 -0.2105 0.5017 +vn 0.8350 -0.0298 0.5494 +vn 0.8890 -0.0249 0.4572 +vn 0.9063 -0.1062 0.4092 +vn 0.8387 0.1548 0.5222 +vn 0.9061 0.0612 0.4185 +vn 0.8794 -0.0258 0.4754 +vn 0.9141 0.0223 0.4048 +vn 0.9142 -0.0661 0.3998 +vn 0.6609 -0.5378 0.5235 +vn 0.6811 -0.3157 0.6606 +vn 0.8405 -0.3696 0.3961 +vn 0.6877 -0.0393 0.7250 +vn 0.6805 0.2422 0.6916 +vn 0.6600 0.4772 0.5802 +vn 0.8400 0.3241 0.4351 +vn 0.9373 0.1489 0.3150 +vn 0.9681 -0.1228 0.2183 +vn 0.9680 0.0986 0.2309 +vn 0.9376 -0.1822 0.2963 +vn -0.8387 0.1548 0.5222 +vn -0.8350 -0.0298 0.5494 +vn -0.8890 -0.0249 0.4571 +vn -0.9061 0.0612 0.4186 +vn -0.8390 -0.2105 0.5017 +vn -0.9063 -0.1062 0.4092 +vn -0.8794 -0.0258 0.4754 +vn -0.9142 -0.0661 0.3998 +vn -0.9141 0.0223 0.4049 +vn -0.6805 0.2422 0.6916 +vn -0.8400 0.3242 0.4351 +vn -0.6877 -0.0393 0.7249 +vn -0.6811 -0.3157 0.6606 +vn -0.6609 -0.5378 0.5234 +vn -0.8405 -0.3696 0.3961 +vn -0.9376 -0.1822 0.2963 +vn -0.9680 0.0986 0.2309 +vn -0.9681 -0.1228 0.2183 +vn -0.9373 0.1489 0.3150 +vn -0.8454 0.5237 -0.1050 +vn -0.8417 0.5382 0.0437 +vn -0.9735 0.2284 0.0121 +vn -0.9739 0.2225 -0.0439 +vn -0.8288 0.5382 0.1530 +vn -0.9696 0.2376 0.0583 +vn -0.9649 -0.2609 -0.0285 +vn -0.9664 -0.2531 0.0451 +vn -0.9661 -0.2460 -0.0782 +vn -0.8386 0.5038 -0.2072 +vn -0.8245 0.5313 0.1948 +vn -0.9675 0.2398 0.0805 +vn -0.9679 -0.2337 -0.0927 +vn -0.6526 -0.7115 -0.2607 +vn -0.6626 -0.7370 0.1336 +vn -0.9689 -0.2308 0.0895 +vn -0.6652 -0.6977 0.2660 +vn -0.9713 0.2211 -0.0879 +vn -0.8328 -0.4743 0.2854 +vn -0.8273 -0.5220 0.2076 +vn -0.9629 -0.2444 0.1145 +vn -0.9553 -0.2302 0.1857 +vn -0.8254 -0.5414 0.1601 +vn -0.9663 -0.2466 0.0735 +vn -0.9777 0.2092 -0.0172 +vn -0.9846 0.1604 0.0691 +vn -0.9709 0.2327 -0.0557 +vn -0.6609 -0.5378 0.5235 +vn -0.6375 -0.6687 0.3827 +vn -0.6254 -0.7260 0.2859 +vn -0.8273 -0.5220 0.2075 +vn -0.6207 -0.7502 0.2281 +vn -0.8253 -0.5415 0.1601 +vn -0.8247 -0.5499 0.1325 +vn -0.8247 -0.5498 0.1325 +vn -0.9676 -0.2470 0.0527 +vn -0.9680 0.2424 -0.0654 +vn 0.8448 -0.5115 -0.1569 +vn 0.8413 -0.5403 -0.0172 +vn 0.9733 -0.2290 -0.0136 +vn 0.9737 -0.2179 -0.0665 +vn 0.8291 -0.5519 0.0900 +vn 0.9697 -0.2425 0.0307 +vn 0.9650 0.2622 0.0013 +vn 0.9666 0.2463 0.0706 +vn 0.9661 0.2532 -0.0496 +vn 0.8391 -0.4828 -0.2507 +vn 0.6235 -0.7689 0.1415 +vn 0.8245 -0.5501 0.1323 +vn 0.9675 -0.2472 0.0526 +vn 0.9680 0.2424 -0.0654 +vn 0.9650 0.2621 0.0013 +vn 0.9692 0.2207 0.1097 +vn 0.9713 -0.2122 -0.1073 +vn 0.9691 0.2208 0.1097 +vn 0.8324 0.4399 0.3372 +vn 0.8270 0.4955 0.2654 +vn 0.9628 0.2302 0.1415 +vn 0.9551 0.2084 0.2107 +vn 0.8251 0.5200 0.2207 +vn 0.9663 0.2368 0.1011 +vn 0.9551 0.2085 0.2106 +vn 0.9628 0.2303 0.1416 +vn 0.9777 -0.2058 -0.0408 +vn 0.9847 -0.1667 0.0505 +vn 0.9663 0.2369 0.1011 +vn 0.9709 -0.2250 -0.0818 +vn 0.8400 0.3242 0.4352 +vn 0.8244 0.5314 0.1948 +vn 0.9675 0.2396 0.0806 +vn 0.9679 -0.2336 -0.0927 +vn 0.6525 -0.7115 -0.2607 +vn 0.6894 -0.6847 -0.2364 +vn 0.8355 -0.2865 -0.4688 +vn 0.8391 -0.3855 -0.3838 +vn 0.9723 -0.1674 -0.1630 +vn 0.9721 -0.1251 -0.1986 +vn 0.8392 -0.4480 -0.3083 +vn 0.9716 -0.1958 -0.1327 +vn 0.9663 0.1843 0.1799 +vn 0.9640 0.1395 0.2264 +vn 0.9681 0.2081 0.1396 +vn 0.8263 -0.1625 -0.5392 +vn 0.6334 -0.3961 -0.6648 +vn 0.6399 -0.6279 -0.4430 +vn 0.9681 0.2080 0.1396 +vn 0.9663 0.1842 0.1799 +vn 0.6507 0.4076 0.6406 +vn 0.9621 0.0779 0.2613 +vn 0.9702 -0.0734 -0.2310 +vn -0.8391 -0.4479 -0.3087 +vn -0.8391 -0.3853 -0.3840 +vn -0.9722 -0.1678 -0.1634 +vn -0.9717 -0.1958 -0.1325 +vn -0.8354 -0.2869 -0.4688 +vn -0.9720 -0.1250 -0.1987 +vn -0.9663 0.1839 0.1800 +vn -0.9682 0.2078 0.1397 +vn -0.9641 0.1392 0.2259 +vn -0.8391 -0.4478 -0.3087 +vn -0.8391 -0.4828 -0.2508 +vn -0.8391 -0.3852 -0.3841 +vn -0.6394 -0.5388 -0.5485 +vn -0.8262 -0.1627 -0.5393 +vn -0.9700 -0.0735 -0.2316 +vn -0.9623 0.0778 0.2608 +vn -0.6508 0.4076 0.6406 +vn -0.9692 0.2204 0.1100 +vn -0.9713 -0.2124 -0.1073 +vn -0.8390 -0.4828 -0.2508 +vn -0.8158 -0.0472 -0.5764 +vn -0.8118 0.0447 -0.5822 +vn -0.9657 0.0197 -0.2591 +vn -0.9669 -0.0228 -0.2540 +vn -0.8140 0.1320 -0.5656 +vn -0.9664 0.0599 -0.2498 +vn -0.9622 -0.0210 0.2714 +vn -0.9622 0.0217 0.2714 +vn -0.9621 -0.0618 0.2656 +vn -0.6003 0.0610 -0.7975 +vn -0.8225 0.2333 -0.5187 +vn -0.9691 0.1041 -0.2238 +vn -0.9620 -0.1114 0.2494 +vn -0.6308 -0.1812 0.7545 +vn -0.6292 -0.0587 0.7750 +vn 0.8289 0.5382 0.1528 +vn 0.8416 0.5383 0.0440 +vn 0.9735 0.2284 0.0121 +vn 0.9696 0.2375 0.0584 +vn 0.8454 0.5237 -0.1047 +vn 0.9739 0.2225 -0.0441 +vn 0.9735 0.2285 0.0121 +vn 0.9649 -0.2612 -0.0286 +vn 0.9661 -0.2460 -0.0783 +vn 0.9664 -0.2531 0.0453 +vn 0.8386 0.5038 -0.2073 +vn 0.9713 0.2211 -0.0879 +vn 0.9690 -0.2303 0.0898 +vn 0.6652 -0.6977 0.2660 +vn 0.6625 -0.7370 0.1336 +vn 0.6570 -0.7515 -0.0592 +vn -0.8291 -0.5519 0.0900 +vn -0.8414 -0.5402 -0.0167 +vn -0.9734 -0.2287 -0.0138 +vn -0.9697 -0.2424 0.0307 +vn -0.8449 -0.5115 -0.1567 +vn -0.9736 -0.2182 -0.0664 +vn -0.9650 0.2622 0.0012 +vn -0.9661 0.2533 -0.0497 +vn -0.9666 0.2463 0.0706 +vn -0.8413 -0.5403 -0.0167 +vn -0.8252 0.5199 0.2208 +vn -0.8270 0.4956 0.2654 +vn -0.9628 0.2302 0.1416 +vn -0.9663 0.2368 0.1011 +vn -0.8324 0.4399 0.3372 +vn -0.9551 0.2084 0.2106 +vn -0.9777 -0.2059 -0.0408 +vn -0.9709 -0.2250 -0.0818 +vn -0.9847 -0.1667 0.0505 +vn -0.7540 -0.6410 -0.1433 +vn -0.6894 -0.6847 -0.2364 +vn 0.8254 -0.5414 0.1602 +vn 0.8273 -0.5220 0.2075 +vn 0.9629 -0.2444 0.1144 +vn 0.9663 -0.2466 0.0735 +vn 0.8328 -0.4744 0.2854 +vn 0.9553 -0.2302 0.1857 +vn 0.9777 0.2092 -0.0172 +vn 0.9710 0.2327 -0.0557 +vn 0.9846 0.1604 0.0692 +vn 0.6207 -0.7501 0.2281 +vn 0.6254 -0.7260 0.2860 +vn 0.6375 -0.6687 0.3827 +vn 0.9709 0.2327 -0.0557 +vn 0.8138 0.1317 -0.5660 +vn 0.8116 0.0444 -0.5825 +vn 0.9657 0.0195 -0.2590 +vn 0.9664 0.0598 -0.2502 +vn 0.8157 -0.0473 -0.5765 +vn 0.9670 -0.0230 -0.2536 +vn 0.9622 -0.0208 0.2714 +vn 0.9621 -0.0616 0.2655 +vn 0.9621 0.0218 0.2717 +vn 0.8223 0.2332 -0.5190 +vn 0.6307 -0.1812 0.7545 +vn 0.9621 -0.1113 0.2490 +vn 0.9689 0.1042 -0.2243 +vn -0.8313 0.3390 -0.4406 +vn -0.8362 0.4223 -0.3499 +vn -0.9717 0.1838 -0.1485 +vn -0.9710 0.1482 -0.1878 +vn -0.8377 0.4749 -0.2696 +vn -0.9713 0.2077 -0.1155 +vn -0.9658 -0.2008 0.1641 +vn -0.9636 -0.1633 0.2117 +vn -0.9678 -0.2204 0.1218 +vn 0.8376 0.4751 -0.2697 +vn 0.8362 0.4222 -0.3501 +vn 0.9716 0.1838 -0.1490 +vn 0.9714 0.2077 -0.1154 +vn 0.8312 0.3388 -0.4408 +vn 0.9710 0.1482 -0.1878 +vn 0.9714 0.2077 -0.1153 +vn 0.9659 -0.2004 0.1638 +vn 0.9679 -0.2201 0.1218 +vn 0.9637 -0.1631 0.2112 +vn 0.6271 0.4682 -0.6226 +vn -0.3374 -0.8991 0.2790 +vn -0.3407 -0.8747 0.3446 +vn -0.0003 -0.9306 0.3660 +vn -0.0001 -0.9545 0.2983 +vn -0.3495 -0.8173 0.4581 +vn -0.0000 -0.8740 0.4859 +vn 0.3407 -0.8747 0.3446 +vn 0.3374 -0.8990 0.2793 +vn 0.3495 -0.8173 0.4582 +vn -0.3690 -0.6782 0.6355 +vn 0.0000 -0.7344 0.6788 +vn 0.3690 -0.6782 0.6356 +vn 0.3690 -0.6782 0.6355 +vn 0.6206 -0.7502 0.2281 +vn -0.3903 -0.4123 0.8232 +vn -0.3987 -0.0495 0.9157 +vn 0.0000 -0.0539 0.9985 +vn -0.0000 -0.4533 0.8914 +vn -0.3896 0.3203 0.8635 +vn 0.0000 0.3538 0.9353 +vn 0.3987 -0.0496 0.9157 +vn 0.3902 -0.4121 0.8234 +vn 0.3896 0.3203 0.8635 +vn -0.3690 -0.6782 0.6356 +vn -0.6600 0.4771 0.5803 +vn 0.3682 0.6040 0.7068 +vn 0.6805 0.2422 0.6915 +vn 0.3903 -0.4121 0.8233 +vn 0.0000 -0.7343 0.6788 +usemtl Scene_-_Root +s 1 +f 25104/25104/17446 25105/25105/17447 25106/25106/17448 +f 25104/25104/17446 25106/25106/17448 25107/25107/17449 +f 25105/25105/17447 25108/25108/17450 25109/25109/17451 +f 25105/25105/17447 25109/25109/17451 25106/25106/17448 +f 25107/25107/17449 25106/25106/17448 25110/25110/17452 +f 25107/25107/17449 25110/25110/17452 25111/25111/17453 +f 25106/25106/17448 25109/25109/17451 25112/25112/17454 +f 25106/25106/17448 25112/25112/17454 25110/25110/17452 +f 25113/25113/17455 25114/25114/17456 25115/25115/17446 +f 25113/25113/17455 25115/25115/17446 25116/25116/17457 +f 25114/25114/17456 25117/25117/17458 25118/25118/17447 +f 25114/25114/17456 25118/25118/17447 25115/25115/17446 +f 25117/25117/17458 25119/25119/17459 25120/25120/17460 +f 25117/25117/17458 25120/25120/17460 25118/25118/17447 +f 25121/25121/17461 25122/25122/17462 25123/25123/17463 +f 25121/25121/17461 25123/25123/17463 25124/25124/17460 +f 25124/25124/17460 25123/25123/17463 25125/25125/17464 +f 25124/25124/17460 25125/25125/17464 25126/25126/17465 +f 25126/25126/17465 25125/25125/17464 25127/25127/17466 +f 25126/25126/17465 25127/25127/17466 25128/25128/17454 +f 25128/25128/17454 25127/25127/17466 25129/25129/17467 +f 25128/25128/17454 25129/25129/17467 25130/25130/17468 +f 25110/25110/17452 25112/25112/17454 25131/25131/17469 +f 25110/25110/17452 25131/25131/17469 25132/25132/17470 +f 25111/25111/17453 25110/25110/17452 25132/25132/17470 +f 25111/25111/17453 25132/25132/17470 25133/25133/17471 +f 25134/25134/17472 25111/25111/17453 25133/25133/17471 +f 25134/25134/17472 25133/25133/17471 25135/25135/17473 +f 25136/25136/17474 25107/25107/17449 25111/25111/17453 +f 25136/25136/17474 25111/25111/17453 25134/25134/17472 +f 25137/25137/17475 25104/25104/17446 25107/25107/17449 +f 25137/25137/17475 25107/25107/17449 25136/25136/17474 +f 25138/25138/17476 25139/25139/17477 25140/25140/17478 +f 25138/25138/17476 25140/25140/17478 25141/25141/17479 +f 25139/25139/17477 25142/25142/17480 25143/25143/17481 +f 25139/25139/17477 25143/25143/17481 25140/25140/17478 +f 25141/25141/17479 25140/25140/17478 25144/25144/17482 +f 25141/25141/17479 25144/25144/17482 25145/25145/17483 +f 25140/25140/17478 25143/25143/17481 25146/25146/17484 +f 25140/25140/17478 25146/25146/17484 25144/25144/17482 +f 25135/25135/17473 25133/25133/17471 25147/25147/17476 +f 25135/25135/17473 25147/25147/17476 25148/25148/17485 +f 25133/25133/17471 25132/25132/17470 25149/25149/17486 +f 25133/25133/17471 25149/25149/17486 25147/25147/17476 +f 25132/25132/17470 25131/25131/17469 25150/25150/17487 +f 25132/25132/17470 25150/25150/17487 25149/25149/17486 +f 25130/25130/17468 25129/25129/17467 25151/25151/17488 +f 25130/25130/17468 25151/25151/17488 25152/25152/17487 +f 25152/25152/17487 25151/25151/17488 25153/25153/17489 +f 25152/25152/17487 25153/25153/17489 25154/25154/17481 +f 25143/25143/17481 25155/25155/17489 25156/25156/17490 +f 25143/25143/17481 25156/25156/17490 25146/25146/17484 +f 25157/25157/17491 25158/25158/17490 25159/25159/17492 +f 25157/25157/17491 25159/25159/17492 25160/25160/17493 +f 25144/25144/17482 25146/25146/17484 25161/25161/17494 +f 25144/25144/17482 25161/25161/17494 25162/25162/17495 +f 25145/25145/17483 25144/25144/17482 25162/25162/17495 +f 25145/25145/17483 25162/25162/17495 25163/25163/17496 +f 25164/25164/17497 25145/25145/17483 25163/25163/17496 +f 25164/25164/17497 25163/25163/17496 25165/25165/17498 +f 25166/25166/17499 25141/25141/17479 25145/25145/17483 +f 25166/25166/17499 25145/25145/17483 25164/25164/17497 +f 25167/25167/17485 25138/25138/17476 25141/25141/17479 +f 25167/25167/17485 25141/25141/17479 25166/25166/17499 +f 25168/25168/17500 25169/25169/17501 25170/25170/17502 +f 25168/25168/17500 25170/25170/17502 25171/25171/17503 +f 25169/25169/17501 25172/25172/17504 25173/25173/17505 +f 25169/25169/17501 25173/25173/17505 25170/25170/17502 +f 25171/25171/17503 25170/25170/17502 25174/25174/17506 +f 25171/25171/17503 25174/25174/17506 25175/25175/17507 +f 25170/25170/17502 25173/25173/17505 25176/25176/17508 +f 25170/25170/17502 25176/25176/17508 25174/25174/17506 +f 25177/25177/17498 25178/25178/17509 25168/25168/17500 +f 25177/25177/17498 25168/25168/17500 25179/25179/17510 +f 25178/25178/17509 25180/25180/17511 25169/25169/17501 +f 25178/25178/17509 25169/25169/17501 25168/25168/17500 +f 25180/25180/17511 25181/25181/17494 25172/25172/17504 +f 25180/25180/17511 25172/25172/17504 25169/25169/17501 +f 25160/25160/17493 25159/25159/17492 25182/25182/17512 +f 25160/25160/17493 25182/25182/17512 25183/25183/17513 +f 25183/25183/17513 25182/25182/17512 25184/25184/17514 +f 25183/25183/17513 25184/25184/17514 25185/25185/17515 +f 25185/25185/17515 25184/25184/17514 25186/25186/17516 +f 25185/25185/17515 25186/25186/17516 25187/25187/17508 +f 25187/25187/17508 25186/25186/17516 25188/25188/17517 +f 25187/25187/17508 25188/25188/17517 25189/25189/17518 +f 25174/25174/17506 25176/25176/17508 25190/25190/17519 +f 25174/25174/17506 25190/25190/17519 25191/25191/17520 +f 25175/25175/17507 25174/25174/17506 25191/25191/17520 +f 25175/25175/17507 25191/25191/17520 25192/25192/17521 +f 25193/25193/17522 25175/25175/17507 25192/25192/17521 +f 25193/25193/17522 25192/25192/17521 25194/25194/17523 +f 25195/25195/17524 25171/25171/17503 25175/25175/17507 +f 25195/25195/17524 25175/25175/17507 25193/25193/17522 +f 25179/25179/17510 25168/25168/17500 25171/25171/17503 +f 25179/25179/17510 25171/25171/17503 25195/25195/17524 +f 25196/25196/17525 25197/25197/17526 25198/25198/17527 +f 25196/25196/17525 25198/25198/17527 25199/25199/17528 +f 25197/25197/17526 25200/25200/17529 25201/25201/17530 +f 25197/25197/17526 25201/25201/17530 25198/25198/17527 +f 25199/25199/17528 25198/25198/17527 25202/25202/17531 +f 25199/25199/17528 25202/25202/17531 25203/25203/17532 +f 25198/25198/17527 25201/25201/17530 25204/25204/17533 +f 25198/25198/17527 25204/25204/17533 25202/25202/17531 +f 25194/25194/17523 25192/25192/17521 25205/25205/17525 +f 25194/25194/17523 25205/25205/17525 25206/25206/17534 +f 25192/25192/17521 25191/25191/17520 25207/25207/17535 +f 25192/25192/17521 25207/25207/17535 25205/25205/17525 +f 25191/25191/17520 25190/25190/17519 25208/25208/17536 +f 25191/25191/17520 25208/25208/17536 25207/25207/17535 +f 25189/25189/17518 25188/25188/17517 25209/25209/17537 +f 25189/25189/17518 25209/25209/17537 25210/25210/17538 +f 25210/25210/17538 25209/25209/17537 25211/25211/17539 +f 25210/25210/17538 25211/25211/17539 25212/25212/17540 +f 25212/25212/17540 25211/25211/17539 25213/25213/17541 +f 25212/25212/17540 25213/25213/17541 25214/25214/17542 +f 25214/25214/17542 25213/25213/17541 25122/25122/17462 +f 25214/25214/17542 25122/25122/17462 25121/25121/17461 +f 25202/25202/17531 25204/25204/17533 25119/25119/17459 +f 25202/25202/17531 25119/25119/17459 25117/25117/17458 +f 25203/25203/17532 25202/25202/17531 25117/25117/17458 +f 25203/25203/17532 25117/25117/17458 25114/25114/17456 +f 25215/25215/17543 25203/25203/17532 25114/25114/17456 +f 25215/25215/17543 25114/25114/17456 25113/25113/17455 +f 25216/25216/17544 25199/25199/17528 25203/25203/17532 +f 25216/25216/17544 25203/25203/17532 25215/25215/17543 +f 25217/25217/17545 25196/25196/17525 25199/25199/17528 +f 25217/25217/17545 25199/25199/17528 25216/25216/17544 +f 25218/25218/17546 25219/25219/17547 25220/25220/17548 +f 25218/25218/17546 25220/25220/17548 25221/25221/17549 +f 25219/25219/17547 25222/25222/17550 25223/25223/17551 +f 25219/25219/17547 25223/25223/17551 25220/25220/17548 +f 25221/25221/17549 25220/25220/17548 25224/25224/17552 +f 25221/25221/17549 25224/25224/17552 25225/25225/17553 +f 25220/25220/17548 25223/25223/17551 25226/25226/17554 +f 25220/25220/17548 25226/25226/17554 25224/25224/17552 +f 25227/25227/17555 25228/25228/17556 25218/25218/17546 +f 25227/25227/17555 25218/25218/17546 25229/25229/17557 +f 25228/25228/17556 25230/25230/17558 25219/25219/17547 +f 25228/25228/17556 25219/25219/17547 25218/25218/17546 +f 25230/25230/17558 25231/25231/17559 25222/25222/17550 +f 25230/25230/17558 25222/25222/17550 25219/25219/17547 +f 25231/25231/17559 25232/25232/17560 25233/25233/17561 +f 25231/25231/17559 25233/25233/17561 25222/25222/17550 +f 25222/25222/17550 25233/25233/17561 25234/25234/17562 +f 25222/25222/17550 25234/25234/17562 25223/25223/17551 +f 25223/25223/17551 25234/25234/17562 25235/25235/17563 +f 25223/25223/17551 25235/25235/17563 25226/25226/17554 +f 25226/25226/17554 25235/25235/17563 25236/25236/17564 +f 25226/25226/17554 25236/25236/17564 25237/25237/17565 +f 25224/25224/17552 25226/25226/17554 25237/25237/17565 +f 25224/25224/17552 25237/25237/17565 25238/25238/17566 +f 25225/25225/17553 25224/25224/17552 25238/25238/17566 +f 25225/25225/17553 25238/25238/17566 25239/25239/17567 +f 25240/25240/17568 25225/25225/17553 25239/25239/17567 +f 25240/25240/17568 25239/25239/17567 25241/25241/17569 +f 25242/25242/17570 25221/25221/17549 25225/25225/17553 +f 25242/25242/17570 25225/25225/17553 25240/25240/17568 +f 25229/25229/17557 25218/25218/17546 25221/25221/17549 +f 25229/25229/17557 25221/25221/17549 25242/25242/17570 +f 25243/25243/17571 25244/25244/17572 25245/25245/17573 +f 25243/25243/17571 25245/25245/17573 25246/25246/17574 +f 25244/25244/17572 25247/25247/17575 25248/25248/17576 +f 25244/25244/17572 25248/25248/17576 25245/25245/17573 +f 25246/25246/17574 25245/25245/17573 25249/25249/17577 +f 25246/25246/17574 25249/25249/17577 25250/25250/17578 +f 25245/25245/17573 25248/25248/17576 25251/25251/17579 +f 25245/25245/17573 25251/25251/17579 25249/25249/17577 +f 25252/25252/17580 25253/25253/17581 25243/25243/17571 +f 25252/25252/17580 25243/25243/17571 25254/25254/17582 +f 25253/25253/17581 25255/25255/17583 25244/25244/17572 +f 25253/25253/17581 25244/25244/17572 25243/25243/17571 +f 25255/25255/17583 25256/25256/17584 25247/25247/17575 +f 25255/25255/17583 25247/25247/17575 25244/25244/17572 +f 25256/25256/17584 25257/25257/17585 25258/25258/17586 +f 25256/25256/17584 25258/25258/17586 25247/25247/17575 +f 25247/25247/17575 25258/25258/17586 25259/25259/17587 +f 25247/25247/17575 25259/25259/17587 25248/25248/17576 +f 25248/25248/17576 25259/25259/17587 25260/25260/17588 +f 25248/25248/17576 25260/25260/17588 25251/25251/17579 +f 25251/25251/17579 25260/25260/17588 25129/25129/17467 +f 25251/25251/17579 25129/25129/17467 25127/25127/17466 +f 25249/25249/17577 25251/25251/17579 25127/25127/17466 +f 25249/25249/17577 25127/25127/17466 25125/25125/17464 +f 25250/25250/17578 25249/25249/17577 25125/25125/17464 +f 25250/25250/17578 25125/25125/17464 25123/25123/17463 +f 25261/25261/17589 25250/25250/17578 25123/25123/17463 +f 25261/25261/17589 25123/25123/17463 25122/25122/17462 +f 25262/25262/17590 25246/25246/17574 25250/25250/17578 +f 25262/25262/17590 25250/25250/17578 25261/25261/17589 +f 25254/25254/17582 25243/25243/17571 25246/25246/17574 +f 25254/25254/17582 25246/25246/17574 25262/25262/17590 +f 25263/25263/17591 25264/25264/17592 25265/25265/17593 +f 25263/25263/17591 25265/25265/17593 25266/25266/17594 +f 25264/25264/17592 25267/25267/17595 25268/25268/17596 +f 25264/25264/17592 25268/25268/17596 25265/25265/17593 +f 25266/25266/17594 25265/25265/17593 25269/25269/17597 +f 25266/25266/17594 25269/25269/17597 25270/25270/17598 +f 25265/25265/17593 25268/25268/17596 25271/25271/17599 +f 25265/25265/17593 25271/25271/17599 25269/25269/17597 +f 25257/25257/17585 25272/25272/17600 25263/25263/17591 +f 25257/25257/17585 25263/25263/17591 25258/25258/17586 +f 25272/25272/17600 25273/25273/17601 25264/25264/17592 +f 25272/25272/17600 25264/25264/17592 25263/25263/17591 +f 25273/25273/17601 25274/25274/17602 25267/25267/17595 +f 25273/25273/17601 25267/25267/17595 25264/25264/17592 +f 25274/25274/17602 25275/25275/17603 25276/25276/17604 +f 25274/25274/17602 25276/25276/17604 25267/25267/17595 +f 25267/25267/17595 25276/25276/17604 25277/25277/17605 +f 25267/25267/17595 25277/25277/17605 25268/25268/17596 +f 25268/25268/17596 25277/25277/17605 25278/25278/17606 +f 25268/25268/17596 25278/25278/17606 25271/25271/17599 +f 25271/25271/17599 25278/25278/17606 25159/25159/17492 +f 25271/25271/17599 25159/25159/17492 25158/25158/17490 +f 25269/25269/17597 25271/25271/17599 25158/25158/17490 +f 25269/25269/17597 25158/25158/17490 25153/25153/17489 +f 25270/25270/17598 25269/25269/17597 25153/25153/17489 +f 25270/25270/17598 25153/25153/17489 25151/25151/17488 +f 25260/25260/17588 25270/25270/17598 25151/25151/17488 +f 25260/25260/17588 25151/25151/17488 25129/25129/17467 +f 25259/25259/17587 25266/25266/17594 25270/25270/17598 +f 25259/25259/17587 25270/25270/17598 25260/25260/17588 +f 25258/25258/17586 25263/25263/17591 25266/25266/17594 +f 25258/25258/17586 25266/25266/17594 25259/25259/17587 +f 25279/25279/17607 25280/25280/17608 25281/25281/17609 +f 25279/25279/17607 25281/25281/17609 25282/25282/17610 +f 25280/25280/17608 25283/25283/17611 25284/25284/17612 +f 25280/25280/17608 25284/25284/17612 25281/25281/17609 +f 25282/25282/17610 25281/25281/17609 25285/25285/17613 +f 25282/25282/17610 25285/25285/17613 25286/25286/17614 +f 25281/25281/17609 25284/25284/17612 25287/25287/17615 +f 25281/25281/17609 25287/25287/17615 25285/25285/17613 +f 25275/25275/17603 25288/25288/17616 25279/25279/17607 +f 25275/25275/17603 25279/25279/17607 25276/25276/17604 +f 25288/25288/17616 25289/25289/17617 25280/25280/17608 +f 25288/25288/17616 25280/25280/17608 25279/25279/17607 +f 25289/25289/17617 25290/25290/17618 25283/25283/17611 +f 25289/25289/17617 25283/25283/17611 25280/25280/17608 +f 25290/25290/17618 25291/25291/17619 25292/25292/17620 +f 25290/25290/17618 25292/25292/17620 25283/25283/17611 +f 25283/25283/17611 25292/25292/17620 25293/25293/17621 +f 25283/25283/17611 25293/25293/17621 25284/25284/17612 +f 25284/25284/17612 25293/25293/17621 25294/25294/17622 +f 25284/25284/17612 25294/25294/17622 25287/25287/17615 +f 25287/25287/17615 25294/25294/17622 25188/25188/17517 +f 25287/25287/17615 25188/25188/17517 25186/25186/17516 +f 25285/25285/17613 25287/25287/17615 25186/25186/17516 +f 25285/25285/17613 25186/25186/17516 25184/25184/17514 +f 25286/25286/17614 25285/25285/17613 25184/25184/17514 +f 25286/25286/17614 25184/25184/17514 25182/25182/17512 +f 25278/25278/17606 25286/25286/17614 25182/25182/17512 +f 25278/25278/17606 25182/25182/17512 25159/25159/17492 +f 25277/25277/17605 25282/25282/17610 25286/25286/17614 +f 25277/25277/17605 25286/25286/17614 25278/25278/17606 +f 25276/25276/17604 25279/25279/17607 25282/25282/17610 +f 25276/25276/17604 25282/25282/17610 25277/25277/17605 +f 25295/25295/17623 25296/25296/17624 25297/25297/17625 +f 25295/25295/17623 25297/25297/17625 25298/25298/17626 +f 25296/25296/17624 25299/25299/17627 25300/25300/17628 +f 25296/25296/17624 25300/25300/17628 25297/25297/17625 +f 25298/25298/17626 25297/25297/17625 25301/25301/17629 +f 25298/25298/17626 25301/25301/17629 25302/25302/17630 +f 25297/25297/17625 25300/25300/17628 25303/25303/17631 +f 25297/25297/17625 25303/25303/17631 25301/25301/17629 +f 25291/25291/17619 25304/25304/17632 25295/25295/17623 +f 25291/25291/17619 25295/25295/17623 25292/25292/17620 +f 25304/25304/17632 25305/25305/17633 25296/25296/17624 +f 25304/25304/17632 25296/25296/17624 25295/25295/17623 +f 25305/25305/17633 25306/25306/17634 25299/25299/17627 +f 25305/25305/17633 25299/25299/17627 25296/25296/17624 +f 25306/25306/17634 25252/25252/17580 25254/25254/17582 +f 25306/25306/17634 25254/25254/17582 25299/25299/17627 +f 25299/25299/17627 25254/25254/17582 25262/25262/17590 +f 25299/25299/17627 25262/25262/17590 25300/25300/17628 +f 25300/25300/17628 25262/25262/17590 25261/25261/17589 +f 25300/25300/17628 25261/25261/17589 25303/25303/17631 +f 25303/25303/17631 25261/25261/17589 25122/25122/17462 +f 25303/25303/17631 25122/25122/17462 25213/25213/17541 +f 25301/25301/17629 25303/25303/17631 25213/25213/17541 +f 25301/25301/17629 25213/25213/17541 25211/25211/17539 +f 25302/25302/17630 25301/25301/17629 25211/25211/17539 +f 25302/25302/17630 25211/25211/17539 25209/25209/17537 +f 25294/25294/17622 25302/25302/17630 25209/25209/17537 +f 25294/25294/17622 25209/25209/17537 25188/25188/17517 +f 25293/25293/17621 25298/25298/17626 25302/25302/17630 +f 25293/25293/17621 25302/25302/17630 25294/25294/17622 +f 25292/25292/17620 25295/25295/17623 25298/25298/17626 +f 25292/25292/17620 25298/25298/17626 25293/25293/17621 +f 25307/25307/17635 25308/25308/17636 25309/25309/17637 +f 25307/25307/17635 25309/25309/17637 25310/25310/17638 +f 25308/25308/17636 25311/25311/17639 25312/25312/17640 +f 25308/25308/17636 25312/25312/17640 25309/25309/17637 +f 25310/25310/17638 25309/25309/17637 25313/25313/17641 +f 25310/25310/17638 25313/25313/17641 25314/25314/17642 +f 25309/25309/17637 25312/25312/17640 25315/25315/17643 +f 25309/25309/17637 25315/25315/17643 25313/25313/17641 +f 25316/25316/17644 25317/25317/17645 25307/25307/17635 +f 25316/25316/17644 25307/25307/17635 25318/25318/17646 +f 25317/25317/17645 25319/25319/17647 25308/25308/17636 +f 25317/25317/17645 25308/25308/17636 25307/25307/17635 +f 25319/25319/17647 25320/25320/17648 25311/25311/17639 +f 25319/25319/17647 25311/25311/17639 25308/25308/17636 +f 25320/25320/17648 25232/25232/17560 25321/25321/17649 +f 25320/25320/17648 25321/25321/17649 25311/25311/17639 +f 25311/25311/17639 25321/25321/17649 25322/25322/17650 +f 25311/25311/17639 25322/25322/17650 25312/25312/17640 +f 25312/25312/17640 25322/25322/17650 25323/25323/17651 +f 25312/25312/17640 25323/25323/17651 25315/25315/17643 +f 25315/25315/17643 25323/25323/17651 25257/25257/17585 +f 25315/25315/17643 25257/25257/17585 25256/25256/17584 +f 25313/25313/17641 25315/25315/17643 25256/25256/17584 +f 25313/25313/17641 25256/25256/17584 25255/25255/17583 +f 25314/25314/17642 25313/25313/17641 25255/25255/17583 +f 25314/25314/17642 25255/25255/17583 25253/25253/17581 +f 25324/25324/17652 25314/25314/17642 25253/25253/17581 +f 25324/25324/17652 25253/25253/17581 25252/25252/17580 +f 25325/25325/17653 25310/25310/17638 25314/25314/17642 +f 25325/25325/17653 25314/25314/17642 25324/25324/17652 +f 25318/25318/17646 25307/25307/17635 25310/25310/17638 +f 25318/25318/17646 25310/25310/17638 25325/25325/17653 +f 25326/25326/17654 25327/25327/17655 25328/25328/17656 +f 25326/25326/17654 25328/25328/17656 25329/25329/17657 +f 25327/25327/17655 25330/25330/17658 25331/25331/17659 +f 25327/25327/17655 25331/25331/17659 25328/25328/17656 +f 25329/25329/17657 25328/25328/17656 25332/25332/17660 +f 25329/25329/17657 25332/25332/17660 25333/25333/17661 +f 25328/25328/17656 25331/25331/17659 25334/25334/17662 +f 25328/25328/17656 25334/25334/17662 25332/25332/17660 +f 25232/25232/17560 25231/25231/17559 25326/25326/17654 +f 25232/25232/17560 25326/25326/17654 25321/25321/17649 +f 25231/25231/17559 25230/25230/17558 25327/25327/17655 +f 25231/25231/17559 25327/25327/17655 25326/25326/17654 +f 25230/25230/17558 25228/25228/17556 25330/25330/17658 +f 25230/25230/17558 25330/25330/17658 25327/25327/17655 +f 25228/25228/17556 25227/25227/17555 25335/25335/17663 +f 25228/25228/17556 25335/25335/17663 25330/25330/17658 +f 25330/25330/17658 25335/25335/17663 25336/25336/17664 +f 25330/25330/17658 25336/25336/17664 25331/25331/17659 +f 25331/25331/17659 25336/25336/17664 25337/25337/17665 +f 25331/25331/17659 25337/25337/17665 25334/25334/17662 +f 25334/25334/17662 25337/25337/17665 25275/25275/17603 +f 25334/25334/17662 25275/25275/17603 25274/25274/17602 +f 25332/25332/17660 25334/25334/17662 25274/25274/17602 +f 25332/25332/17660 25274/25274/17602 25273/25273/17601 +f 25333/25333/17661 25332/25332/17660 25273/25273/17601 +f 25333/25333/17661 25273/25273/17601 25272/25272/17600 +f 25323/25323/17651 25333/25333/17661 25272/25272/17600 +f 25323/25323/17651 25272/25272/17600 25257/25257/17585 +f 25322/25322/17650 25329/25329/17657 25333/25333/17661 +f 25322/25322/17650 25333/25333/17661 25323/25323/17651 +f 25321/25321/17649 25326/25326/17654 25329/25329/17657 +f 25321/25321/17649 25329/25329/17657 25322/25322/17650 +f 25338/25338/17666 25339/25339/17667 25340/25340/17668 +f 25338/25338/17666 25340/25340/17668 25341/25341/17669 +f 25339/25339/17667 25342/25342/17670 25343/25343/17671 +f 25339/25339/17667 25343/25343/17671 25340/25340/17668 +f 25341/25341/17669 25340/25340/17668 25344/25344/17672 +f 25341/25341/17669 25344/25344/17672 25345/25345/17673 +f 25340/25340/17668 25343/25343/17671 25346/25346/17674 +f 25340/25340/17668 25346/25346/17674 25344/25344/17672 +f 25227/25227/17555 25347/25347/17675 25338/25338/17666 +f 25227/25227/17555 25338/25338/17666 25335/25335/17663 +f 25347/25347/17675 25348/25348/17676 25339/25339/17667 +f 25347/25347/17675 25339/25339/17667 25338/25338/17666 +f 25348/25348/17676 25349/25349/17677 25342/25342/17670 +f 25348/25348/17676 25342/25342/17670 25339/25339/17667 +f 25349/25349/17677 25350/25350/17678 25351/25351/17679 +f 25349/25349/17677 25351/25351/17679 25342/25342/17670 +f 25342/25342/17670 25351/25351/17679 25352/25352/17680 +f 25342/25342/17670 25352/25352/17680 25343/25343/17671 +f 25343/25343/17671 25352/25352/17680 25353/25353/17681 +f 25343/25343/17671 25353/25353/17681 25346/25346/17674 +f 25346/25346/17674 25353/25353/17681 25291/25291/17619 +f 25346/25346/17674 25291/25291/17619 25290/25290/17618 +f 25344/25344/17672 25346/25346/17674 25290/25290/17618 +f 25344/25344/17672 25290/25290/17618 25289/25289/17617 +f 25345/25345/17673 25344/25344/17672 25289/25289/17617 +f 25345/25345/17673 25289/25289/17617 25288/25288/17616 +f 25337/25337/17665 25345/25345/17673 25288/25288/17616 +f 25337/25337/17665 25288/25288/17616 25275/25275/17603 +f 25336/25336/17664 25341/25341/17669 25345/25345/17673 +f 25336/25336/17664 25345/25345/17673 25337/25337/17665 +f 25335/25335/17663 25338/25338/17666 25341/25341/17669 +f 25335/25335/17663 25341/25341/17669 25336/25336/17664 +f 25354/25354/17682 25355/25355/17683 25356/25356/17684 +f 25354/25354/17682 25356/25356/17684 25357/25357/17685 +f 25355/25355/17683 25358/25358/17686 25359/25359/17687 +f 25355/25355/17683 25359/25359/17687 25356/25356/17684 +f 25357/25357/17685 25356/25356/17684 25360/25360/17688 +f 25357/25357/17685 25360/25360/17688 25361/25361/17689 +f 25356/25356/17684 25359/25359/17687 25362/25362/17690 +f 25356/25356/17684 25362/25362/17690 25360/25360/17688 +f 25350/25350/17678 25363/25363/17691 25354/25354/17682 +f 25350/25350/17678 25354/25354/17682 25351/25351/17679 +f 25363/25363/17691 25364/25364/17692 25355/25355/17683 +f 25363/25363/17691 25355/25355/17683 25354/25354/17682 +f 25364/25364/17692 25365/25365/17693 25358/25358/17686 +f 25364/25364/17692 25358/25358/17686 25355/25355/17683 +f 25365/25365/17693 25316/25316/17644 25318/25318/17646 +f 25365/25365/17693 25318/25318/17646 25358/25358/17686 +f 25358/25358/17686 25318/25318/17646 25325/25325/17653 +f 25358/25358/17686 25325/25325/17653 25359/25359/17687 +f 25359/25359/17687 25325/25325/17653 25324/25324/17652 +f 25359/25359/17687 25324/25324/17652 25362/25362/17690 +f 25362/25362/17690 25324/25324/17652 25252/25252/17580 +f 25362/25362/17690 25252/25252/17580 25306/25306/17634 +f 25360/25360/17688 25362/25362/17690 25306/25306/17634 +f 25360/25360/17688 25306/25306/17634 25305/25305/17633 +f 25361/25361/17689 25360/25360/17688 25305/25305/17633 +f 25361/25361/17689 25305/25305/17633 25304/25304/17632 +f 25353/25353/17681 25361/25361/17689 25304/25304/17632 +f 25353/25353/17681 25304/25304/17632 25291/25291/17619 +f 25352/25352/17680 25357/25357/17685 25361/25361/17689 +f 25352/25352/17680 25361/25361/17689 25353/25353/17681 +f 25351/25351/17679 25354/25354/17682 25357/25357/17685 +f 25351/25351/17679 25357/25357/17685 25352/25352/17680 +f 25366/25366/17694 25367/25367/17695 25368/25368/17696 +f 25366/25366/17694 25368/25368/17696 25369/25369/17697 +f 25367/25367/17695 25370/25370/17698 25371/25371/17699 +f 25367/25367/17695 25371/25371/17699 25368/25368/17696 +f 25369/25369/17697 25368/25368/17696 25372/25372/17700 +f 25369/25369/17697 25372/25372/17700 25373/25373/17701 +f 25368/25368/17696 25371/25371/17699 25374/25374/17702 +f 25368/25368/17696 25374/25374/17702 25372/25372/17700 +f 25375/25375/17703 25376/25376/17704 25366/25366/17694 +f 25375/25375/17703 25366/25366/17694 25377/25377/17705 +f 25376/25376/17704 25378/25378/17706 25367/25367/17695 +f 25376/25376/17704 25367/25367/17695 25366/25366/17694 +f 25378/25378/17706 25379/25379/17707 25370/25370/17698 +f 25378/25378/17706 25370/25370/17698 25367/25367/17695 +f 25379/25379/17707 25380/25380/17708 25381/25381/17709 +f 25379/25379/17707 25381/25381/17709 25370/25370/17698 +f 25370/25370/17698 25381/25381/17709 25382/25382/17710 +f 25370/25370/17698 25382/25382/17710 25371/25371/17699 +f 25371/25371/17699 25382/25382/17710 25383/25383/17711 +f 25371/25371/17699 25383/25383/17711 25374/25374/17702 +f 25374/25374/17702 25383/25383/17711 25384/25384/17712 +f 25374/25374/17702 25384/25384/17712 25385/25385/17713 +f 25372/25372/17700 25374/25374/17702 25385/25385/17713 +f 25372/25372/17700 25385/25385/17713 25386/25386/17714 +f 25373/25373/17701 25372/25372/17700 25386/25386/17714 +f 25373/25373/17701 25386/25386/17714 25387/25387/17715 +f 25388/25388/17716 25373/25373/17701 25387/25387/17715 +f 25388/25388/17716 25387/25387/17715 25389/25389/17717 +f 25390/25390/17718 25369/25369/17697 25373/25373/17701 +f 25390/25390/17718 25373/25373/17701 25388/25388/17716 +f 25377/25377/17705 25366/25366/17694 25369/25369/17697 +f 25377/25377/17705 25369/25369/17697 25390/25390/17718 +f 25391/25391/17719 25392/25392/17720 25393/25393/17721 +f 25391/25391/17719 25393/25393/17721 25394/25394/17722 +f 25392/25392/17720 25395/25395/17723 25396/25396/17724 +f 25392/25392/17720 25396/25396/17724 25393/25393/17721 +f 25394/25394/17722 25393/25393/17721 25397/25397/17725 +f 25394/25394/17722 25397/25397/17725 25398/25398/17726 +f 25393/25393/17721 25396/25396/17724 25399/25399/17727 +f 25393/25393/17721 25399/25399/17727 25397/25397/17725 +f 25350/25350/17678 25349/25349/17677 25391/25391/17719 +f 25350/25350/17678 25391/25391/17719 25400/25400/17728 +f 25349/25349/17677 25348/25348/17676 25392/25392/17720 +f 25349/25349/17677 25392/25392/17720 25391/25391/17719 +f 25348/25348/17676 25347/25347/17675 25395/25395/17723 +f 25348/25348/17676 25395/25395/17723 25392/25392/17720 +f 25347/25347/17675 25227/25227/17555 25229/25229/17557 +f 25347/25347/17675 25229/25229/17557 25395/25395/17723 +f 25395/25395/17723 25229/25229/17557 25242/25242/17570 +f 25395/25395/17723 25242/25242/17570 25396/25396/17724 +f 25396/25396/17724 25242/25242/17570 25240/25240/17568 +f 25396/25396/17724 25240/25240/17568 25399/25399/17727 +f 25399/25399/17727 25240/25240/17568 25241/25241/17569 +f 25399/25399/17727 25241/25241/17569 25401/25401/17729 +f 25397/25397/17725 25399/25399/17727 25401/25401/17729 +f 25397/25397/17725 25401/25401/17729 25402/25402/17730 +f 25398/25398/17726 25397/25397/17725 25402/25402/17730 +f 25398/25398/17726 25402/25402/17730 25403/25403/17731 +f 25404/25404/17732 25398/25398/17726 25403/25403/17731 +f 25404/25404/17732 25403/25403/17731 25405/25405/17733 +f 25406/25406/17734 25394/25394/17722 25398/25398/17726 +f 25406/25406/17734 25398/25398/17726 25404/25404/17732 +f 25400/25400/17728 25391/25391/17719 25394/25394/17722 +f 25400/25400/17728 25394/25394/17722 25406/25406/17734 +f 25407/25407/17735 25408/25408/17736 25409/25409/17737 +f 25407/25407/17735 25409/25409/17737 25410/25410/17738 +f 25408/25408/17736 25411/25411/17739 25412/25412/17740 +f 25408/25408/17736 25412/25412/17740 25409/25409/17737 +f 25410/25410/17738 25409/25409/17737 25413/25413/17741 +f 25410/25410/17738 25413/25413/17741 25414/25414/17742 +f 25409/25409/17737 25412/25412/17740 25415/25415/17743 +f 25409/25409/17737 25415/25415/17743 25413/25413/17741 +f 25232/25232/17560 25320/25320/17648 25407/25407/17735 +f 25232/25232/17560 25407/25407/17735 25233/25233/17561 +f 25320/25320/17648 25319/25319/17647 25408/25408/17736 +f 25320/25320/17648 25408/25408/17736 25407/25407/17735 +f 25319/25319/17647 25317/25317/17645 25411/25411/17739 +f 25319/25319/17647 25411/25411/17739 25408/25408/17736 +f 25317/25317/17645 25316/25316/17644 25416/25416/17744 +f 25317/25317/17645 25416/25416/17744 25411/25411/17739 +f 25411/25411/17739 25416/25416/17744 25417/25417/17745 +f 25411/25411/17739 25417/25417/17745 25412/25412/17740 +f 25412/25412/17740 25417/25417/17745 25418/25418/17746 +f 25412/25412/17740 25418/25418/17746 25415/25415/17743 +f 25415/25415/17743 25418/25418/17746 25419/25419/17747 +f 25415/25415/17743 25419/25419/17747 25420/25420/17748 +f 25413/25413/17741 25415/25415/17743 25420/25420/17748 +f 25413/25413/17741 25420/25420/17748 25421/25421/17749 +f 25414/25414/17742 25413/25413/17741 25421/25421/17749 +f 25414/25414/17742 25421/25421/17749 25422/25422/17750 +f 25235/25235/17563 25414/25414/17742 25422/25422/17750 +f 25235/25235/17563 25422/25422/17750 25236/25236/17564 +f 25234/25234/17562 25410/25410/17738 25414/25414/17742 +f 25234/25234/17562 25414/25414/17742 25235/25235/17563 +f 25233/25233/17561 25407/25407/17735 25410/25410/17738 +f 25233/25233/17561 25410/25410/17738 25234/25234/17562 +f 25423/25423/17751 25424/25424/17752 25425/25425/17753 +f 25423/25423/17751 25425/25425/17753 25426/25426/17754 +f 25424/25424/17752 25427/25427/17755 25428/25428/17756 +f 25424/25424/17752 25428/25428/17756 25425/25425/17753 +f 25426/25426/17754 25425/25425/17753 25429/25429/17757 +f 25426/25426/17754 25429/25429/17757 25430/25430/17758 +f 25425/25425/17753 25428/25428/17756 25431/25431/17759 +f 25425/25425/17753 25431/25431/17759 25429/25429/17757 +f 25316/25316/17644 25365/25365/17693 25423/25423/17751 +f 25316/25316/17644 25423/25423/17751 25416/25416/17744 +f 25365/25365/17693 25364/25364/17692 25424/25424/17752 +f 25365/25365/17693 25424/25424/17752 25423/25423/17751 +f 25364/25364/17692 25363/25363/17691 25427/25427/17755 +f 25364/25364/17692 25427/25427/17755 25424/25424/17752 +f 25363/25363/17691 25350/25350/17678 25400/25400/17728 +f 25363/25363/17691 25400/25400/17728 25427/25427/17755 +f 25427/25427/17755 25400/25400/17728 25406/25406/17734 +f 25427/25427/17755 25406/25406/17734 25428/25428/17756 +f 25428/25428/17756 25406/25406/17734 25404/25404/17732 +f 25428/25428/17756 25404/25404/17732 25431/25431/17759 +f 25431/25431/17759 25404/25404/17732 25405/25405/17733 +f 25431/25431/17759 25405/25405/17733 25432/25432/17760 +f 25429/25429/17757 25431/25431/17759 25432/25432/17760 +f 25429/25429/17757 25432/25432/17760 25433/25433/17761 +f 25430/25430/17758 25429/25429/17757 25433/25433/17761 +f 25430/25430/17758 25433/25433/17761 25434/25434/17762 +f 25418/25418/17746 25430/25430/17758 25434/25434/17762 +f 25418/25418/17746 25434/25434/17762 25419/25419/17747 +f 25417/25417/17745 25426/25426/17754 25430/25430/17758 +f 25417/25417/17745 25430/25430/17758 25418/25418/17746 +f 25416/25416/17744 25423/25423/17751 25426/25426/17754 +f 25416/25416/17744 25426/25426/17754 25417/25417/17745 +f 25435/25435/17763 25436/25436/17764 25437/25437/17765 +f 25435/25435/17763 25437/25437/17765 25438/25438/17766 +f 25436/25436/17764 25439/25439/17767 25440/25440/17768 +f 25436/25436/17764 25440/25440/17768 25437/25437/17765 +f 25438/25438/17766 25437/25437/17765 25441/25441/17769 +f 25438/25438/17766 25441/25441/17769 25442/25442/17770 +f 25437/25437/17765 25440/25440/17768 25443/25443/17771 +f 25437/25437/17765 25443/25443/17771 25441/25441/17769 +f 25444/25444/17772 25445/25445/17773 25446/25446/17763 +f 25444/25444/17772 25446/25446/17763 25447/25447/17774 +f 25448/25448/17773 25449/25449/17775 25450/25450/17764 +f 25448/25448/17773 25450/25450/17764 25451/25451/17763 +f 25449/25449/17775 25452/25452/17776 25453/25453/17767 +f 25449/25449/17775 25453/25453/17767 25450/25450/17764 +f 25452/25452/17776 25454/25454/17777 25455/25455/17778 +f 25452/25452/17776 25455/25455/17778 25453/25453/17767 +f 25439/25439/17767 25456/25456/17778 25457/25457/17779 +f 25439/25439/17767 25457/25457/17779 25440/25440/17768 +f 25440/25440/17768 25457/25457/17779 25458/25458/17780 +f 25440/25440/17768 25458/25458/17780 25443/25443/17771 +f 25443/25443/17771 25458/25458/17780 25236/25236/17564 +f 25443/25443/17771 25236/25236/17564 25422/25422/17750 +f 25441/25441/17769 25443/25443/17771 25422/25422/17750 +f 25441/25441/17769 25422/25422/17750 25421/25421/17749 +f 25442/25442/17770 25441/25441/17769 25421/25421/17749 +f 25442/25442/17770 25421/25421/17749 25420/25420/17748 +f 25459/25459/17781 25442/25442/17770 25420/25420/17748 +f 25459/25459/17781 25420/25420/17748 25419/25419/17747 +f 25460/25460/17782 25438/25438/17766 25442/25442/17770 +f 25460/25460/17782 25442/25442/17770 25459/25459/17781 +f 25461/25461/17783 25435/25435/17763 25438/25438/17766 +f 25461/25461/17783 25438/25438/17766 25460/25460/17782 +f 25462/25462/17784 25463/25463/17785 25464/25464/17786 +f 25462/25462/17784 25464/25464/17786 25465/25465/17787 +f 25463/25463/17785 25466/25466/17788 25467/25467/17789 +f 25463/25463/17785 25467/25467/17789 25464/25464/17786 +f 25465/25465/17787 25464/25464/17786 25468/25468/17790 +f 25465/25465/17787 25468/25468/17790 25469/25469/17791 +f 25464/25464/17786 25467/25467/17789 25470/25470/17792 +f 25464/25464/17786 25470/25470/17792 25468/25468/17790 +f 25471/25471/17793 25472/25472/17794 25473/25473/17795 +f 25471/25471/17793 25473/25473/17795 25474/25474/17778 +f 25472/25472/17794 25475/25475/17796 25476/25476/17785 +f 25472/25472/17794 25476/25476/17785 25473/25473/17795 +f 25475/25475/17796 25477/25477/17797 25478/25478/17798 +f 25475/25475/17796 25478/25478/17798 25476/25476/17785 +f 25477/25477/17797 25479/25479/17799 25480/25480/17800 +f 25477/25477/17797 25480/25480/17800 25478/25478/17798 +f 25466/25466/17788 25481/25481/17800 25482/25482/17801 +f 25466/25466/17788 25482/25482/17801 25467/25467/17789 +f 25467/25467/17789 25482/25482/17801 25483/25483/17802 +f 25467/25467/17789 25483/25483/17802 25470/25470/17792 +f 25470/25470/17792 25483/25483/17802 25241/25241/17569 +f 25470/25470/17792 25241/25241/17569 25239/25239/17567 +f 25468/25468/17790 25470/25470/17792 25239/25239/17567 +f 25468/25468/17790 25239/25239/17567 25238/25238/17566 +f 25469/25469/17791 25468/25468/17790 25238/25238/17566 +f 25469/25469/17791 25238/25238/17566 25237/25237/17565 +f 25458/25458/17780 25469/25469/17791 25237/25237/17565 +f 25458/25458/17780 25237/25237/17565 25236/25236/17564 +f 25457/25457/17779 25465/25465/17787 25469/25469/17791 +f 25457/25457/17779 25469/25469/17791 25458/25458/17780 +f 25456/25456/17778 25462/25462/17784 25465/25465/17787 +f 25456/25456/17778 25465/25465/17787 25457/25457/17779 +f 25484/25484/17803 25485/25485/17804 25486/25486/17805 +f 25484/25484/17803 25486/25486/17805 25487/25487/17806 +f 25485/25485/17804 25488/25488/17807 25489/25489/17808 +f 25485/25485/17804 25489/25489/17808 25486/25486/17805 +f 25487/25487/17806 25486/25486/17805 25490/25490/17809 +f 25487/25487/17806 25490/25490/17809 25491/25491/17810 +f 25486/25486/17805 25489/25489/17808 25492/25492/17811 +f 25486/25486/17805 25492/25492/17811 25490/25490/17809 +f 25479/25479/17799 25493/25493/17812 25494/25494/17803 +f 25479/25479/17799 25494/25494/17803 25480/25480/17800 +f 25495/25495/17812 25496/25496/17813 25497/25497/17804 +f 25495/25495/17812 25497/25497/17804 25498/25498/17803 +f 25496/25496/17813 25499/25499/17814 25500/25500/17807 +f 25496/25496/17813 25500/25500/17807 25497/25497/17804 +f 25499/25499/17814 25501/25501/17815 25502/25502/17816 +f 25499/25499/17814 25502/25502/17816 25500/25500/17807 +f 25488/25488/17807 25503/25503/17817 25504/25504/17818 +f 25488/25488/17807 25504/25504/17818 25489/25489/17808 +f 25489/25489/17808 25504/25504/17818 25505/25505/17819 +f 25489/25489/17808 25505/25505/17819 25492/25492/17811 +f 25492/25492/17811 25505/25505/17819 25405/25405/17733 +f 25492/25492/17811 25405/25405/17733 25403/25403/17731 +f 25490/25490/17809 25492/25492/17811 25403/25403/17731 +f 25490/25490/17809 25403/25403/17731 25402/25402/17730 +f 25491/25491/17810 25490/25490/17809 25402/25402/17730 +f 25491/25491/17810 25402/25402/17730 25401/25401/17729 +f 25483/25483/17802 25491/25491/17810 25401/25401/17729 +f 25483/25483/17802 25401/25401/17729 25241/25241/17569 +f 25482/25482/17801 25487/25487/17806 25491/25491/17810 +f 25482/25482/17801 25491/25491/17810 25483/25483/17802 +f 25481/25481/17800 25484/25484/17803 25487/25487/17806 +f 25481/25481/17800 25487/25487/17806 25482/25482/17801 +f 25506/25506/17820 25507/25507/17821 25508/25508/17822 +f 25506/25506/17820 25508/25508/17822 25509/25509/17823 +f 25507/25507/17821 25510/25510/17824 25511/25511/17825 +f 25507/25507/17821 25511/25511/17825 25508/25508/17822 +f 25509/25509/17823 25508/25508/17822 25512/25512/17826 +f 25509/25509/17823 25512/25512/17826 25513/25513/17827 +f 25508/25508/17822 25511/25511/17825 25514/25514/17828 +f 25508/25508/17822 25514/25514/17828 25512/25512/17826 +f 25515/25515/17815 25516/25516/17829 25517/25517/17820 +f 25515/25515/17815 25517/25517/17820 25518/25518/17817 +f 25519/25519/17830 25520/25520/17831 25507/25507/17821 +f 25519/25519/17830 25507/25507/17821 25506/25506/17820 +f 25520/25520/17831 25521/25521/17832 25510/25510/17824 +f 25520/25520/17831 25510/25510/17824 25507/25507/17821 +f 25522/25522/17832 25444/25444/17772 25447/25447/17774 +f 25522/25522/17832 25447/25447/17774 25523/25523/17833 +f 25510/25510/17824 25461/25461/17783 25460/25460/17782 +f 25510/25510/17824 25460/25460/17782 25511/25511/17825 +f 25511/25511/17825 25460/25460/17782 25459/25459/17781 +f 25511/25511/17825 25459/25459/17781 25514/25514/17828 +f 25514/25514/17828 25459/25459/17781 25419/25419/17747 +f 25514/25514/17828 25419/25419/17747 25434/25434/17762 +f 25512/25512/17826 25514/25514/17828 25434/25434/17762 +f 25512/25512/17826 25434/25434/17762 25433/25433/17761 +f 25513/25513/17827 25512/25512/17826 25433/25433/17761 +f 25513/25513/17827 25433/25433/17761 25432/25432/17760 +f 25505/25505/17819 25513/25513/17827 25432/25432/17760 +f 25505/25505/17819 25432/25432/17760 25405/25405/17733 +f 25504/25504/17818 25509/25509/17823 25513/25513/17827 +f 25504/25504/17818 25513/25513/17827 25505/25505/17819 +f 25503/25503/17817 25506/25506/17820 25509/25509/17823 +f 25503/25503/17817 25509/25509/17823 25504/25504/17818 +f 25524/25524/17834 25525/25525/17835 25526/25526/17836 +f 25524/25524/17834 25526/25526/17836 25527/25527/17837 +f 25528/25528/17838 25529/25529/17839 25530/25530/17840 +f 25528/25528/17838 25530/25530/17840 25531/25531/17841 +f 25527/25527/17837 25526/25526/17836 25532/25532/17842 +f 25527/25527/17837 25532/25532/17842 25533/25533/17843 +f 25531/25531/17841 25530/25530/17840 25534/25534/17844 +f 25531/25531/17841 25534/25534/17844 25535/25535/17845 +f 25536/25536/17846 25537/25537/17847 25524/25524/17834 +f 25536/25536/17846 25524/25524/17834 25538/25538/17848 +f 25539/25539/17849 25540/25540/17850 25528/25528/17838 +f 25539/25539/17849 25528/25528/17838 25541/25541/17834 +f 25540/25540/17850 25542/25542/17851 25529/25529/17839 +f 25540/25540/17850 25529/25529/17839 25528/25528/17838 +f 25542/25542/17851 25375/25375/17703 25377/25377/17705 +f 25542/25542/17851 25377/25377/17705 25529/25529/17839 +f 25529/25529/17839 25377/25377/17705 25390/25390/17718 +f 25529/25529/17839 25390/25390/17718 25530/25530/17840 +f 25530/25530/17840 25390/25390/17718 25388/25388/17716 +f 25530/25530/17840 25388/25388/17716 25534/25534/17844 +f 25534/25534/17844 25388/25388/17716 25389/25389/17717 +f 25534/25534/17844 25389/25389/17717 25543/25543/17852 +f 25532/25532/17842 25544/25544/17853 25545/25545/17854 +f 25532/25532/17842 25545/25545/17854 25546/25546/17855 +f 25533/25533/17843 25532/25532/17842 25546/25546/17855 +f 25533/25533/17843 25546/25546/17855 25547/25547/17856 +f 25548/25548/17857 25533/25533/17843 25547/25547/17856 +f 25548/25548/17857 25547/25547/17856 25549/25549/17858 +f 25550/25550/17859 25527/25527/17837 25533/25533/17843 +f 25550/25550/17859 25533/25533/17843 25548/25548/17857 +f 25538/25538/17848 25524/25524/17834 25527/25527/17837 +f 25538/25538/17848 25527/25527/17837 25550/25550/17859 +f 25551/25551/17860 25552/25552/17861 25553/25553/17862 +f 25551/25551/17860 25553/25553/17862 25554/25554/17863 +f 25552/25552/17861 25555/25555/17864 25556/25556/17865 +f 25552/25552/17861 25556/25556/17865 25553/25553/17862 +f 25554/25554/17863 25553/25553/17862 25557/25557/17866 +f 25554/25554/17863 25557/25557/17866 25558/25558/17867 +f 25553/25553/17862 25556/25556/17865 25559/25559/17868 +f 25553/25553/17862 25559/25559/17868 25557/25557/17866 +f 25560/25560/17869 25561/25561/17870 25551/25551/17860 +f 25560/25560/17869 25551/25551/17860 25562/25562/17871 +f 25561/25561/17870 25563/25563/17872 25552/25552/17861 +f 25561/25561/17870 25552/25552/17861 25551/25551/17860 +f 25563/25563/17872 25564/25564/17873 25555/25555/17864 +f 25563/25563/17872 25555/25555/17864 25552/25552/17861 +f 25564/25564/17873 25565/25565/17874 25566/25566/17875 +f 25564/25564/17873 25566/25566/17875 25555/25555/17864 +f 25555/25555/17864 25566/25566/17875 25567/25567/17876 +f 25555/25555/17864 25567/25567/17876 25556/25556/17865 +f 25556/25556/17865 25567/25567/17876 25568/25568/17877 +f 25556/25556/17865 25568/25568/17877 25559/25559/17868 +f 25559/25559/17868 25568/25568/17877 25569/25569/17878 +f 25559/25559/17868 25569/25569/17878 25570/25570/17879 +f 25557/25557/17866 25559/25559/17868 25570/25570/17879 +f 25557/25557/17866 25570/25570/17879 25571/25571/17880 +f 25558/25558/17867 25557/25557/17866 25571/25571/17880 +f 25558/25558/17867 25571/25571/17880 25572/25572/17881 +f 25573/25573/17882 25558/25558/17867 25572/25572/17881 +f 25573/25573/17882 25572/25572/17881 25574/25574/17883 +f 25575/25575/17884 25554/25554/17863 25558/25558/17867 +f 25575/25575/17884 25558/25558/17867 25573/25573/17882 +f 25562/25562/17871 25551/25551/17860 25554/25554/17863 +f 25562/25562/17871 25554/25554/17863 25575/25575/17884 +f 25576/25576/17885 25577/25577/17886 25578/25578/17887 +f 25576/25576/17885 25578/25578/17887 25579/25579/17888 +f 25577/25577/17886 25580/25580/17889 25581/25581/17890 +f 25577/25577/17886 25581/25581/17890 25578/25578/17887 +f 25579/25579/17888 25578/25578/17887 25582/25582/17891 +f 25579/25579/17888 25582/25582/17891 25583/25583/17892 +f 25578/25578/17887 25581/25581/17890 25584/25584/17893 +f 25578/25578/17887 25584/25584/17893 25582/25582/17891 +f 25585/25585/17894 25586/25586/17895 25576/25576/17885 +f 25585/25585/17894 25576/25576/17885 25587/25587/17896 +f 25586/25586/17895 25588/25588/17897 25577/25577/17886 +f 25586/25586/17895 25577/25577/17886 25576/25576/17885 +f 25588/25588/17897 25589/25589/17898 25580/25580/17889 +f 25588/25588/17897 25580/25580/17889 25577/25577/17886 +f 25590/25590/17898 25591/25591/17899 25592/25592/17900 +f 25590/25590/17898 25592/25592/17900 25593/25593/17901 +f 25593/25593/17901 25592/25592/17900 25594/25594/17902 +f 25593/25593/17901 25594/25594/17902 25595/25595/17903 +f 25595/25595/17903 25594/25594/17902 25596/25596/17904 +f 25595/25595/17903 25596/25596/17904 25597/25597/17893 +f 25597/25597/17893 25596/25596/17904 25598/25598/17905 +f 25597/25597/17893 25598/25598/17905 25599/25599/17906 +f 25582/25582/17891 25584/25584/17893 25600/25600/17906 +f 25582/25582/17891 25600/25600/17906 25601/25601/17907 +f 25583/25583/17892 25582/25582/17891 25601/25601/17907 +f 25583/25583/17892 25601/25601/17907 25602/25602/17908 +f 25603/25603/17909 25583/25583/17892 25602/25602/17908 +f 25603/25603/17909 25602/25602/17908 25604/25604/17910 +f 25605/25605/17911 25579/25579/17888 25583/25583/17892 +f 25605/25605/17911 25583/25583/17892 25603/25603/17909 +f 25587/25587/17896 25576/25576/17885 25579/25579/17888 +f 25587/25587/17896 25579/25579/17888 25605/25605/17911 +f 25606/25606/17912 25607/25607/17913 25608/25608/17914 +f 25606/25606/17912 25608/25608/17914 25609/25609/17915 +f 25607/25607/17913 25610/25610/17916 25611/25611/17917 +f 25607/25607/17913 25611/25611/17917 25608/25608/17914 +f 25609/25609/17915 25608/25608/17914 25612/25612/17918 +f 25609/25609/17915 25612/25612/17918 25613/25613/17919 +f 25608/25608/17914 25611/25611/17917 25614/25614/17920 +f 25608/25608/17914 25614/25614/17920 25612/25612/17918 +f 25615/25615/17921 25616/25616/17922 25606/25606/17912 +f 25615/25615/17921 25606/25606/17912 25617/25617/17923 +f 25616/25616/17922 25618/25618/17924 25607/25607/17913 +f 25616/25616/17922 25607/25607/17913 25606/25606/17912 +f 25618/25618/17924 25619/25619/17925 25610/25610/17916 +f 25618/25618/17924 25610/25610/17916 25607/25607/17913 +f 25619/25619/17925 25620/25620/17926 25621/25621/17927 +f 25619/25619/17925 25621/25621/17927 25610/25610/17916 +f 25610/25610/17916 25621/25621/17927 25622/25622/17928 +f 25610/25610/17916 25622/25622/17928 25611/25611/17917 +f 25611/25611/17917 25622/25622/17928 25623/25623/17929 +f 25611/25611/17917 25623/25623/17929 25614/25614/17920 +f 25614/25614/17920 25623/25623/17929 25624/25624/17930 +f 25614/25614/17920 25624/25624/17930 25625/25625/17931 +f 25612/25612/17918 25614/25614/17920 25625/25625/17931 +f 25612/25612/17918 25625/25625/17931 25626/25626/17932 +f 25613/25613/17919 25612/25612/17918 25626/25626/17932 +f 25613/25613/17919 25626/25626/17932 25627/25627/17933 +f 25628/25628/17934 25613/25613/17919 25627/25627/17933 +f 25628/25628/17934 25627/25627/17933 25629/25629/17935 +f 25630/25630/17936 25609/25609/17915 25613/25613/17919 +f 25630/25630/17936 25613/25613/17919 25628/25628/17934 +f 25617/25617/17923 25606/25606/17912 25609/25609/17915 +f 25617/25617/17923 25609/25609/17915 25630/25630/17936 +f 25631/25631/17937 25632/25632/17938 25633/25633/17939 +f 25631/25631/17937 25633/25633/17939 25634/25634/17940 +f 25632/25632/17938 25635/25635/17941 25636/25636/17942 +f 25632/25632/17938 25636/25636/17942 25633/25633/17939 +f 25637/25637/17940 25638/25638/17943 25639/25639/17944 +f 25637/25637/17940 25639/25639/17944 25640/25640/17945 +f 25638/25638/17943 25641/25641/17946 25642/25642/17947 +f 25638/25638/17943 25642/25642/17947 25639/25639/17944 +f 25574/25574/17883 25572/25572/17881 25631/25631/17937 +f 25574/25574/17883 25631/25631/17937 25643/25643/17948 +f 25572/25572/17881 25571/25571/17880 25632/25632/17938 +f 25572/25572/17881 25632/25632/17938 25631/25631/17937 +f 25571/25571/17880 25570/25570/17879 25635/25635/17941 +f 25571/25571/17880 25635/25635/17941 25632/25632/17938 +f 25570/25570/17879 25569/25569/17878 25644/25644/17949 +f 25570/25570/17879 25644/25644/17949 25635/25635/17941 +f 25635/25635/17941 25644/25644/17949 25645/25645/17950 +f 25635/25635/17941 25645/25645/17950 25636/25636/17942 +f 25641/25641/17946 25646/25646/17950 25647/25647/17951 +f 25641/25641/17946 25647/25647/17951 25642/25642/17947 +f 25642/25642/17947 25647/25647/17951 25624/25624/17930 +f 25642/25642/17947 25624/25624/17930 25623/25623/17929 +f 25639/25639/17944 25642/25642/17947 25623/25623/17929 +f 25639/25639/17944 25623/25623/17929 25622/25622/17928 +f 25640/25640/17945 25639/25639/17944 25622/25622/17928 +f 25640/25640/17945 25622/25622/17928 25621/25621/17927 +f 25648/25648/17952 25640/25640/17945 25621/25621/17927 +f 25648/25648/17952 25621/25621/17927 25620/25620/17926 +f 25649/25649/17953 25634/25634/17940 25650/25650/17954 +f 25649/25649/17953 25650/25650/17954 25651/25651/17955 +f 25643/25643/17948 25631/25631/17937 25634/25634/17940 +f 25643/25643/17948 25634/25634/17940 25649/25649/17953 +f 25652/25652/17956 25653/25653/17957 25654/25654/17958 +f 25652/25652/17956 25654/25654/17958 25655/25655/17959 +f 25653/25653/17957 25656/25656/17960 25657/25657/17961 +f 25653/25653/17957 25657/25657/17961 25654/25654/17958 +f 25655/25655/17959 25654/25654/17958 25658/25658/17962 +f 25655/25655/17959 25658/25658/17962 25659/25659/17963 +f 25654/25654/17958 25657/25657/17961 25660/25660/17964 +f 25654/25654/17958 25660/25660/17964 25658/25658/17962 +f 25661/25661/17965 25662/25662/17966 25652/25652/17956 +f 25661/25661/17965 25652/25652/17956 25663/25663/17967 +f 25662/25662/17966 25664/25664/17968 25653/25653/17957 +f 25662/25662/17966 25653/25653/17957 25652/25652/17956 +f 25664/25664/17968 25665/25665/17969 25656/25656/17960 +f 25664/25664/17968 25656/25656/17960 25653/25653/17957 +f 25665/25665/17969 25536/25536/17846 25538/25538/17848 +f 25665/25665/17969 25538/25538/17848 25656/25656/17960 +f 25656/25656/17960 25538/25538/17848 25550/25550/17859 +f 25656/25656/17960 25550/25550/17859 25657/25657/17961 +f 25657/25657/17961 25550/25550/17859 25548/25548/17857 +f 25657/25657/17961 25548/25548/17857 25660/25660/17964 +f 25660/25660/17964 25548/25548/17857 25549/25549/17858 +f 25660/25660/17964 25549/25549/17858 25666/25666/17970 +f 25658/25658/17962 25660/25660/17964 25666/25666/17970 +f 25658/25658/17962 25666/25666/17970 25667/25667/17971 +f 25659/25659/17963 25658/25658/17962 25667/25667/17971 +f 25659/25659/17963 25667/25667/17971 25668/25668/17972 +f 25669/25669/17973 25659/25659/17963 25668/25668/17972 +f 25669/25669/17973 25668/25668/17972 25670/25670/17974 +f 25671/25671/17975 25655/25655/17959 25659/25659/17963 +f 25671/25671/17975 25659/25659/17963 25669/25669/17973 +f 25663/25663/17967 25652/25652/17956 25655/25655/17959 +f 25663/25663/17967 25655/25655/17959 25671/25671/17975 +f 25672/25672/17976 25673/25673/17977 25674/25674/17978 +f 25672/25672/17976 25674/25674/17978 25675/25675/17979 +f 25673/25673/17977 25676/25676/17980 25677/25677/17981 +f 25673/25673/17977 25677/25677/17981 25674/25674/17978 +f 25678/25678/17982 25679/25679/17983 25680/25680/17984 +f 25678/25678/17982 25680/25680/17984 25681/25681/17985 +f 25674/25674/17978 25677/25677/17981 25682/25682/17986 +f 25674/25674/17978 25682/25682/17986 25683/25683/17987 +f 25684/25684/17988 25685/25685/17989 25686/25686/17990 +f 25684/25684/17988 25686/25686/17990 25687/25687/17991 +f 25685/25685/17989 25688/25688/17992 25689/25689/17977 +f 25685/25685/17989 25689/25689/17977 25686/25686/17990 +f 25688/25688/17992 25690/25690/17993 25691/25691/17980 +f 25688/25688/17992 25691/25691/17980 25689/25689/17977 +f 25692/25692/17994 25661/25661/17965 25663/25663/17967 +f 25692/25692/17994 25663/25663/17967 25676/25676/17980 +f 25676/25676/17980 25663/25663/17967 25671/25671/17975 +f 25676/25676/17980 25671/25671/17975 25677/25677/17981 +f 25677/25677/17981 25671/25671/17975 25669/25669/17973 +f 25677/25677/17981 25669/25669/17973 25682/25682/17986 +f 25682/25682/17986 25669/25669/17973 25670/25670/17974 +f 25682/25682/17986 25670/25670/17974 25693/25693/17995 +f 25683/25683/17987 25682/25682/17986 25693/25693/17995 +f 25683/25683/17987 25693/25693/17995 25694/25694/17996 +f 25681/25681/17985 25680/25680/17984 25695/25695/17996 +f 25681/25681/17985 25695/25695/17996 25696/25696/17997 +f 25697/25697/17998 25681/25681/17985 25696/25696/17997 +f 25697/25697/17998 25696/25696/17997 25698/25698/17999 +f 25699/25699/18000 25678/25678/17982 25681/25681/17985 +f 25699/25699/18000 25681/25681/17985 25697/25697/17998 +f 25700/25700/17991 25701/25701/17976 25678/25678/17982 +f 25700/25700/17991 25678/25678/17982 25699/25699/18000 +f 25702/25702/18001 25703/25703/18002 25704/25704/18003 +f 25702/25702/18001 25704/25704/18003 25705/25705/18004 +f 25703/25703/18002 25706/25706/18005 25707/25707/18006 +f 25703/25703/18002 25707/25707/18006 25704/25704/18003 +f 25705/25705/18004 25704/25704/18003 25708/25708/18007 +f 25705/25705/18004 25708/25708/18007 25709/25709/18008 +f 25704/25704/18003 25707/25707/18006 25710/25710/18009 +f 25704/25704/18003 25710/25710/18009 25708/25708/18007 +f 25711/25711/18010 25712/25712/18011 25713/25713/18012 +f 25711/25711/18010 25713/25713/18012 25714/25714/18013 +f 25712/25712/18011 25715/25715/18014 25716/25716/18015 +f 25712/25712/18011 25716/25716/18015 25713/25713/18012 +f 25715/25715/18014 25717/25717/18016 25718/25718/18005 +f 25715/25715/18014 25718/25718/18005 25716/25716/18015 +f 25717/25717/18016 25684/25684/17988 25687/25687/17991 +f 25717/25717/18016 25687/25687/17991 25718/25718/18005 +f 25706/25706/18005 25700/25700/17991 25699/25699/18000 +f 25706/25706/18005 25699/25699/18000 25707/25707/18006 +f 25707/25707/18006 25699/25699/18000 25697/25697/17998 +f 25707/25707/18006 25697/25697/17998 25710/25710/18009 +f 25710/25710/18009 25697/25697/17998 25698/25698/17999 +f 25710/25710/18009 25698/25698/17999 25719/25719/18017 +f 25708/25708/18007 25710/25710/18009 25719/25719/18017 +f 25708/25708/18007 25719/25719/18017 25720/25720/18018 +f 25709/25709/18008 25708/25708/18007 25720/25720/18018 +f 25709/25709/18008 25720/25720/18018 25721/25721/18019 +f 25722/25722/18020 25709/25709/18008 25721/25721/18019 +f 25722/25722/18020 25721/25721/18019 25723/25723/18021 +f 25724/25724/18022 25705/25705/18004 25709/25709/18008 +f 25724/25724/18022 25709/25709/18008 25722/25722/18020 +f 25725/25725/18013 25702/25702/18001 25705/25705/18004 +f 25725/25725/18013 25705/25705/18004 25724/25724/18022 +f 25726/25726/18023 25727/25727/18024 25728/25728/18025 +f 25726/25726/18023 25728/25728/18025 25729/25729/18026 +f 25727/25727/18024 25730/25730/18027 25731/25731/18028 +f 25727/25727/18024 25731/25731/18028 25728/25728/18025 +f 25729/25729/18026 25728/25728/18025 25732/25732/18029 +f 25729/25729/18026 25732/25732/18029 25733/25733/18030 +f 25728/25728/18025 25731/25731/18028 25734/25734/18031 +f 25728/25728/18025 25734/25734/18031 25732/25732/18029 +f 25501/25501/17815 25499/25499/17814 25726/25726/18023 +f 25501/25501/17815 25726/25726/18023 25735/25735/18032 +f 25499/25499/17814 25496/25496/17813 25727/25727/18024 +f 25499/25499/17814 25727/25727/18024 25726/25726/18023 +f 25496/25496/17813 25495/25495/17812 25730/25730/18027 +f 25496/25496/17813 25730/25730/18027 25727/25727/18024 +f 25493/25493/17812 25479/25479/17799 25736/25736/18033 +f 25493/25493/17812 25736/25736/18033 25737/25737/18027 +f 25730/25730/18027 25738/25738/18033 25739/25739/18034 +f 25730/25730/18027 25739/25739/18034 25731/25731/18028 +f 25731/25731/18028 25739/25739/18034 25740/25740/18035 +f 25731/25731/18028 25740/25740/18035 25734/25734/18031 +f 25734/25734/18031 25740/25740/18035 25565/25565/17874 +f 25734/25734/18031 25565/25565/17874 25564/25564/17873 +f 25732/25732/18029 25734/25734/18031 25564/25564/17873 +f 25732/25732/18029 25564/25564/17873 25563/25563/17872 +f 25733/25733/18030 25732/25732/18029 25563/25563/17872 +f 25733/25733/18030 25563/25563/17872 25561/25561/17870 +f 25741/25741/18036 25733/25733/18030 25561/25561/17870 +f 25741/25741/18036 25561/25561/17870 25560/25560/17869 +f 25742/25742/18037 25729/25729/18026 25733/25733/18030 +f 25742/25742/18037 25733/25733/18030 25741/25741/18036 +f 25735/25735/18032 25726/25726/18023 25729/25729/18026 +f 25735/25735/18032 25729/25729/18026 25742/25742/18037 +f 25743/25743/18038 25744/25744/18039 25745/25745/18040 +f 25743/25743/18038 25745/25745/18040 25746/25746/18041 +f 25744/25744/18039 25747/25747/18042 25748/25748/18043 +f 25744/25744/18039 25748/25748/18043 25745/25745/18040 +f 25746/25746/18041 25745/25745/18040 25749/25749/18044 +f 25746/25746/18041 25749/25749/18044 25750/25750/18045 +f 25745/25745/18040 25748/25748/18043 25751/25751/18046 +f 25745/25745/18040 25751/25751/18046 25749/25749/18044 +f 25454/25454/17777 25452/25452/17776 25743/25743/18038 +f 25454/25454/17777 25743/25743/18038 25752/25752/18047 +f 25452/25452/17776 25449/25449/17775 25744/25744/18039 +f 25452/25452/17776 25744/25744/18039 25743/25743/18038 +f 25449/25449/17775 25448/25448/17773 25747/25747/18042 +f 25449/25449/17775 25747/25747/18042 25744/25744/18039 +f 25445/25445/17773 25444/25444/17772 25753/25753/18048 +f 25445/25445/17773 25753/25753/18048 25754/25754/18049 +f 25754/25754/18049 25753/25753/18048 25755/25755/18050 +f 25754/25754/18049 25755/25755/18050 25756/25756/18051 +f 25756/25756/18051 25755/25755/18050 25757/25757/18052 +f 25756/25756/18051 25757/25757/18052 25758/25758/18046 +f 25758/25758/18046 25757/25757/18052 25591/25591/17899 +f 25758/25758/18046 25591/25591/17899 25590/25590/17898 +f 25749/25749/18044 25751/25751/18046 25589/25589/17898 +f 25749/25749/18044 25589/25589/17898 25588/25588/17897 +f 25750/25750/18045 25749/25749/18044 25588/25588/17897 +f 25750/25750/18045 25588/25588/17897 25586/25586/17895 +f 25759/25759/18053 25750/25750/18045 25586/25586/17895 +f 25759/25759/18053 25586/25586/17895 25585/25585/17894 +f 25760/25760/18054 25746/25746/18041 25750/25750/18045 +f 25760/25760/18054 25750/25750/18045 25759/25759/18053 +f 25752/25752/18047 25743/25743/18038 25746/25746/18041 +f 25752/25752/18047 25746/25746/18041 25760/25760/18054 +f 25761/25761/18055 25762/25762/18056 25763/25763/18057 +f 25761/25761/18055 25763/25763/18057 25764/25764/18058 +f 25762/25762/18056 25765/25765/18059 25766/25766/18060 +f 25762/25762/18056 25766/25766/18060 25763/25763/18057 +f 25764/25764/18058 25763/25763/18057 25767/25767/18061 +f 25764/25764/18058 25767/25767/18061 25768/25768/18062 +f 25763/25763/18057 25766/25766/18060 25769/25769/18063 +f 25763/25763/18057 25769/25769/18063 25767/25767/18061 +f 25770/25770/18064 25771/25771/18065 25772/25772/18066 +f 25770/25770/18064 25772/25772/18066 25773/25773/18067 +f 25771/25771/18065 25774/25774/18068 25775/25775/18056 +f 25771/25771/18065 25775/25775/18056 25772/25772/18066 +f 25774/25774/18068 25776/25776/18069 25777/25777/18059 +f 25774/25774/18068 25777/25777/18059 25775/25775/18056 +f 25776/25776/18069 25711/25711/18010 25714/25714/18013 +f 25776/25776/18069 25714/25714/18013 25777/25777/18059 +f 25765/25765/18059 25725/25725/18013 25724/25724/18022 +f 25765/25765/18059 25724/25724/18022 25766/25766/18060 +f 25766/25766/18060 25724/25724/18022 25722/25722/18020 +f 25766/25766/18060 25722/25722/18020 25769/25769/18063 +f 25769/25769/18063 25722/25722/18020 25723/25723/18021 +f 25769/25769/18063 25723/25723/18021 25778/25778/18070 +f 25767/25767/18061 25769/25769/18063 25778/25778/18070 +f 25767/25767/18061 25778/25778/18070 25779/25779/18071 +f 25768/25768/18062 25767/25767/18061 25779/25779/18071 +f 25768/25768/18062 25779/25779/18071 25780/25780/18072 +f 25781/25781/18073 25768/25768/18062 25780/25780/18072 +f 25781/25781/18073 25780/25780/18072 25782/25782/18074 +f 25783/25783/18075 25764/25764/18058 25768/25768/18062 +f 25783/25783/18075 25768/25768/18062 25781/25781/18073 +f 25784/25784/18067 25761/25761/18055 25764/25764/18058 +f 25784/25784/18067 25764/25764/18058 25783/25783/18075 +f 25785/25785/18076 25786/25786/18077 25787/25787/18078 +f 25785/25785/18076 25787/25787/18078 25788/25788/18079 +f 25786/25786/18077 25789/25789/18080 25790/25790/18081 +f 25786/25786/18077 25790/25790/18081 25787/25787/18078 +f 25791/25791/18082 25792/25792/18078 25793/25793/18083 +f 25791/25791/18082 25793/25793/18083 25794/25794/18084 +f 25792/25792/18078 25795/25795/18081 25796/25796/18085 +f 25792/25792/18078 25796/25796/18085 25793/25793/18083 +f 25604/25604/17910 25602/25602/17908 25785/25785/18076 +f 25604/25604/17910 25785/25785/18076 25797/25797/18086 +f 25602/25602/17908 25601/25601/17907 25786/25786/18077 +f 25602/25602/17908 25786/25786/18077 25785/25785/18076 +f 25601/25601/17907 25600/25600/17906 25789/25789/18080 +f 25601/25601/17907 25789/25789/18080 25786/25786/18077 +f 25599/25599/17906 25598/25598/17905 25798/25798/18087 +f 25599/25599/17906 25798/25798/18087 25799/25799/18080 +f 25799/25799/18080 25798/25798/18087 25800/25800/18088 +f 25799/25799/18080 25800/25800/18088 25801/25801/18089 +f 25795/25795/18081 25802/25802/18088 25803/25803/18090 +f 25795/25795/18081 25803/25803/18090 25796/25796/18085 +f 25796/25796/18085 25803/25803/18090 25615/25615/17921 +f 25796/25796/18085 25615/25615/17921 25617/25617/17923 +f 25793/25793/18083 25796/25796/18085 25617/25617/17923 +f 25793/25793/18083 25617/25617/17923 25630/25630/17936 +f 25794/25794/18084 25793/25793/18083 25630/25630/17936 +f 25794/25794/18084 25630/25630/17936 25628/25628/17934 +f 25804/25804/18091 25794/25794/18084 25628/25628/17934 +f 25804/25804/18091 25628/25628/17934 25629/25629/17935 +f 25805/25805/18092 25788/25788/18079 25806/25806/18084 +f 25805/25805/18092 25806/25806/18084 25807/25807/18091 +f 25797/25797/18086 25785/25785/18076 25788/25788/18079 +f 25797/25797/18086 25788/25788/18079 25805/25805/18092 +f 25808/25808/18093 25809/25809/18094 25810/25810/18095 +f 25808/25808/18093 25810/25810/18095 25811/25811/18096 +f 25809/25809/18094 25812/25812/18097 25813/25813/18098 +f 25809/25809/18094 25813/25813/18098 25810/25810/18095 +f 25811/25811/18096 25810/25810/18095 25814/25814/18099 +f 25811/25811/18096 25814/25814/18099 25815/25815/18100 +f 25810/25810/18095 25813/25813/18098 25816/25816/18101 +f 25810/25810/18095 25816/25816/18101 25814/25814/18099 +f 25817/25817/18102 25818/25818/18103 25808/25808/18093 +f 25817/25817/18102 25808/25808/18093 25819/25819/18104 +f 25818/25818/18103 25820/25820/18105 25809/25809/18094 +f 25818/25818/18103 25809/25809/18094 25808/25808/18093 +f 25820/25820/18105 25821/25821/18106 25812/25812/18097 +f 25820/25820/18105 25812/25812/18097 25809/25809/18094 +f 25821/25821/18106 25822/25822/18107 25823/25823/18108 +f 25821/25821/18106 25823/25823/18108 25812/25812/18097 +f 25812/25812/18097 25823/25823/18108 25824/25824/18109 +f 25812/25812/18097 25824/25824/18109 25813/25813/18098 +f 25813/25813/18098 25824/25824/18109 25825/25825/18110 +f 25813/25813/18098 25825/25825/18110 25816/25816/18101 +f 25816/25816/18101 25825/25825/18110 25479/25479/17799 +f 25816/25816/18101 25479/25479/17799 25477/25477/17797 +f 25814/25814/18099 25816/25816/18101 25477/25477/17797 +f 25814/25814/18099 25477/25477/17797 25475/25475/17796 +f 25815/25815/18100 25814/25814/18099 25475/25475/17796 +f 25815/25815/18100 25475/25475/17796 25472/25472/17794 +f 25826/25826/18111 25815/25815/18100 25472/25472/17794 +f 25826/25826/18111 25472/25472/17794 25471/25471/17793 +f 25827/25827/18112 25811/25811/18096 25815/25815/18100 +f 25827/25827/18112 25815/25815/18100 25826/25826/18111 +f 25819/25819/18104 25808/25808/18093 25811/25811/18096 +f 25819/25819/18104 25811/25811/18096 25827/25827/18112 +f 25828/25828/18113 25829/25829/18114 25830/25830/18115 +f 25828/25828/18113 25830/25830/18115 25831/25831/18116 +f 25829/25829/18114 25832/25832/18117 25833/25833/18118 +f 25829/25829/18114 25833/25833/18118 25830/25830/18115 +f 25831/25831/18116 25830/25830/18115 25834/25834/18119 +f 25831/25831/18116 25834/25834/18119 25835/25835/18120 +f 25830/25830/18115 25833/25833/18118 25836/25836/18121 +f 25830/25830/18115 25836/25836/18121 25834/25834/18119 +f 25770/25770/18064 25837/25837/18122 25828/25828/18113 +f 25770/25770/18064 25828/25828/18113 25838/25838/18123 +f 25837/25837/18122 25839/25839/18124 25829/25829/18114 +f 25837/25837/18122 25829/25829/18114 25828/25828/18113 +f 25839/25839/18124 25840/25840/18125 25832/25832/18117 +f 25839/25839/18124 25832/25832/18117 25829/25829/18114 +f 25840/25840/18125 25841/25841/18126 25842/25842/18127 +f 25840/25840/18125 25842/25842/18127 25832/25832/18117 +f 25832/25832/18117 25842/25842/18127 25843/25843/18128 +f 25832/25832/18117 25843/25843/18128 25833/25833/18118 +f 25833/25833/18118 25843/25843/18128 25844/25844/18129 +f 25833/25833/18118 25844/25844/18129 25836/25836/18121 +f 25836/25836/18121 25844/25844/18129 25444/25444/17772 +f 25836/25836/18121 25444/25444/17772 25522/25522/17832 +f 25834/25834/18119 25836/25836/18121 25522/25522/17832 +f 25834/25834/18119 25522/25522/17832 25845/25845/17831 +f 25835/25835/18120 25834/25834/18119 25845/25845/17831 +f 25835/25835/18120 25845/25845/17831 25516/25516/17829 +f 25846/25846/18130 25835/25835/18120 25516/25516/17829 +f 25846/25846/18130 25516/25516/17829 25515/25515/17815 +f 25847/25847/18131 25831/25831/18116 25835/25835/18120 +f 25847/25847/18131 25835/25835/18120 25846/25846/18130 +f 25838/25838/18123 25828/25828/18113 25831/25831/18116 +f 25838/25838/18123 25831/25831/18116 25847/25847/18131 +f 25848/25848/18132 25849/25849/18133 25850/25850/18134 +f 25848/25848/18132 25850/25850/18134 25851/25851/18135 +f 25849/25849/18133 25852/25852/18136 25853/25853/18137 +f 25849/25849/18133 25853/25853/18137 25850/25850/18134 +f 25851/25851/18135 25850/25850/18134 25854/25854/18138 +f 25851/25851/18135 25854/25854/18138 25855/25855/18139 +f 25850/25850/18134 25853/25853/18137 25856/25856/18140 +f 25850/25850/18134 25856/25856/18140 25854/25854/18138 +f 25684/25684/17988 25717/25717/18016 25848/25848/18132 +f 25684/25684/17988 25848/25848/18132 25857/25857/18141 +f 25717/25717/18016 25715/25715/18014 25849/25849/18133 +f 25717/25717/18016 25849/25849/18133 25848/25848/18132 +f 25715/25715/18014 25712/25712/18011 25852/25852/18136 +f 25715/25715/18014 25852/25852/18136 25849/25849/18133 +f 25712/25712/18011 25711/25711/18010 25858/25858/18142 +f 25712/25712/18011 25858/25858/18142 25852/25852/18136 +f 25852/25852/18136 25858/25858/18142 25859/25859/18143 +f 25852/25852/18136 25859/25859/18143 25853/25853/18137 +f 25853/25853/18137 25859/25859/18143 25860/25860/18144 +f 25853/25853/18137 25860/25860/18144 25856/25856/18140 +f 25856/25856/18140 25860/25860/18144 25861/25861/18145 +f 25856/25856/18140 25861/25861/18145 25862/25862/17871 +f 25854/25854/18138 25856/25856/18140 25862/25862/17871 +f 25854/25854/18138 25862/25862/17871 25863/25863/17884 +f 25855/25855/18139 25854/25854/18138 25863/25863/17884 +f 25855/25855/18139 25863/25863/17884 25864/25864/18146 +f 25865/25865/18147 25855/25855/18139 25864/25864/18146 +f 25865/25865/18147 25864/25864/18146 25866/25866/18148 +f 25867/25867/18149 25851/25851/18135 25855/25855/18139 +f 25867/25867/18149 25855/25855/18139 25865/25865/18147 +f 25857/25857/18141 25848/25848/18132 25851/25851/18135 +f 25857/25857/18141 25851/25851/18135 25867/25867/18149 +f 25868/25868/18150 25869/25869/18151 25870/25870/18152 +f 25868/25868/18150 25870/25870/18152 25871/25871/18153 +f 25869/25869/18151 25872/25872/18154 25873/25873/18155 +f 25869/25869/18151 25873/25873/18155 25870/25870/18152 +f 25871/25871/18153 25870/25870/18152 25874/25874/18156 +f 25871/25871/18153 25874/25874/18156 25875/25875/18157 +f 25870/25870/18152 25873/25873/18155 25876/25876/18158 +f 25870/25870/18152 25876/25876/18158 25874/25874/18156 +f 25877/25877/18159 25878/25878/18160 25879/25879/18150 +f 25877/25877/18159 25879/25879/18150 25880/25880/18127 +f 25878/25878/18160 25881/25881/18161 25882/25882/18162 +f 25878/25878/18160 25882/25882/18162 25879/25879/18150 +f 25881/25881/18161 25883/25883/18163 25884/25884/18164 +f 25881/25881/18161 25884/25884/18164 25882/25882/18162 +f 25883/25883/18163 25380/25380/17708 25885/25885/18165 +f 25883/25883/18163 25885/25885/18165 25884/25884/18164 +f 25872/25872/18154 25886/25886/18166 25887/25887/18167 +f 25872/25872/18154 25887/25887/18167 25873/25873/18155 +f 25873/25873/18155 25887/25887/18167 25888/25888/18168 +f 25873/25873/18155 25888/25888/18168 25876/25876/18158 +f 25876/25876/18158 25888/25888/18168 25591/25591/17899 +f 25876/25876/18158 25591/25591/17899 25757/25757/18052 +f 25874/25874/18156 25876/25876/18158 25757/25757/18052 +f 25874/25874/18156 25757/25757/18052 25755/25755/18050 +f 25875/25875/18157 25874/25874/18156 25755/25755/18050 +f 25875/25875/18157 25755/25755/18050 25753/25753/18048 +f 25844/25844/18129 25875/25875/18157 25753/25753/18048 +f 25844/25844/18129 25753/25753/18048 25444/25444/17772 +f 25843/25843/18128 25871/25871/18153 25875/25875/18157 +f 25843/25843/18128 25875/25875/18157 25844/25844/18129 +f 25842/25842/18127 25868/25868/18150 25871/25871/18153 +f 25842/25842/18127 25871/25871/18153 25843/25843/18128 +f 25889/25889/18169 25890/25890/18170 25891/25891/18171 +f 25889/25889/18169 25891/25891/18171 25892/25892/18172 +f 25890/25890/18170 25893/25893/18173 25894/25894/18174 +f 25890/25890/18170 25894/25894/18174 25891/25891/18171 +f 25892/25892/18172 25891/25891/18171 25895/25895/18175 +f 25892/25892/18172 25895/25895/18175 25896/25896/18176 +f 25891/25891/18171 25894/25894/18174 25897/25897/18177 +f 25891/25891/18171 25897/25897/18177 25895/25895/18175 +f 25898/25898/17717 25899/25899/17715 25889/25889/18169 +f 25898/25898/17717 25889/25889/18169 25900/25900/18178 +f 25899/25899/17715 25901/25901/17714 25890/25890/18170 +f 25899/25899/17715 25890/25890/18170 25889/25889/18169 +f 25901/25901/17714 25902/25902/18179 25893/25893/18173 +f 25901/25901/17714 25893/25893/18173 25890/25890/18170 +f 25902/25902/18179 25903/25903/17712 25904/25904/18180 +f 25902/25902/18179 25904/25904/18180 25893/25893/18173 +f 25893/25893/18173 25904/25904/18180 25905/25905/18181 +f 25893/25893/18173 25905/25905/18181 25894/25894/18174 +f 25894/25894/18174 25905/25905/18181 25906/25906/18182 +f 25894/25894/18174 25906/25906/18182 25897/25897/18177 +f 25907/25907/18177 25908/25908/18182 25585/25585/17894 +f 25907/25907/18177 25585/25585/17894 25587/25587/17896 +f 25909/25909/18183 25907/25907/18177 25587/25587/17896 +f 25909/25909/18183 25587/25587/17896 25605/25605/17911 +f 25910/25910/18176 25909/25909/18183 25605/25605/17911 +f 25910/25910/18176 25605/25605/17911 25603/25603/17909 +f 25911/25911/18184 25910/25910/18176 25603/25603/17909 +f 25911/25911/18184 25603/25603/17909 25604/25604/17910 +f 25912/25912/18185 25892/25892/18172 25896/25896/18176 +f 25912/25912/18185 25896/25896/18176 25913/25913/18186 +f 25900/25900/18178 25889/25889/18169 25892/25892/18172 +f 25900/25900/18178 25892/25892/18172 25912/25912/18185 +f 25914/25914/18187 25915/25915/18188 25916/25916/18189 +f 25914/25914/18187 25916/25916/18189 25917/25917/18190 +f 25915/25915/18188 25918/25918/18191 25919/25919/18192 +f 25915/25915/18188 25919/25919/18192 25916/25916/18189 +f 25920/25920/18193 25921/25921/18194 25922/25922/18195 +f 25920/25920/18193 25922/25922/18195 25923/25923/18196 +f 25921/25921/18194 25924/25924/18197 25925/25925/18198 +f 25921/25921/18194 25925/25925/18198 25922/25922/18195 +f 25782/25782/18074 25780/25780/18072 25914/25914/18187 +f 25782/25782/18074 25914/25914/18187 25926/25926/18199 +f 25780/25780/18072 25779/25779/18071 25915/25915/18188 +f 25780/25780/18072 25915/25915/18188 25914/25914/18187 +f 25779/25779/18071 25778/25778/18070 25918/25918/18191 +f 25779/25779/18071 25918/25918/18191 25915/25915/18188 +f 25778/25778/18070 25723/25723/18021 25927/25927/18200 +f 25778/25778/18070 25927/25927/18200 25918/25918/18191 +f 25918/25918/18191 25927/25927/18200 25928/25928/18201 +f 25918/25918/18191 25928/25928/18201 25919/25919/18192 +f 25924/25924/18197 25929/25929/18201 25930/25930/18202 +f 25924/25924/18197 25930/25930/18202 25925/25925/18198 +f 25925/25925/18198 25930/25930/18202 25931/25931/18203 +f 25925/25925/18198 25931/25931/18203 25932/25932/18035 +f 25922/25922/18195 25925/25925/18198 25932/25932/18035 +f 25922/25922/18195 25932/25932/18035 25933/25933/18204 +f 25923/25923/18196 25922/25922/18195 25933/25933/18204 +f 25923/25923/18196 25933/25933/18204 25736/25736/18033 +f 25825/25825/18110 25923/25923/18196 25736/25736/18033 +f 25825/25825/18110 25736/25736/18033 25479/25479/17799 +f 25824/25824/18109 25920/25920/18193 25923/25923/18196 +f 25824/25824/18109 25923/25923/18196 25825/25825/18110 +f 25823/25823/18108 25934/25934/18187 25920/25920/18193 +f 25823/25823/18108 25920/25920/18193 25824/25824/18109 +f 25935/25935/18205 25936/25936/18206 25937/25937/18207 +f 25935/25935/18205 25937/25937/18207 25938/25938/18208 +f 25936/25936/18206 25939/25939/18209 25940/25940/18210 +f 25936/25936/18206 25940/25940/18210 25937/25937/18207 +f 25938/25938/18208 25937/25937/18207 25941/25941/18211 +f 25938/25938/18208 25941/25941/18211 25942/25942/18212 +f 25937/25937/18207 25940/25940/18210 25943/25943/18213 +f 25937/25937/18207 25943/25943/18213 25941/25941/18211 +f 25549/25549/17858 25547/25547/17856 25944/25944/18205 +f 25549/25549/17858 25944/25944/18205 25945/25945/18214 +f 25946/25946/18215 25947/25947/17855 25936/25936/18206 +f 25946/25946/18215 25936/25936/18206 25935/25935/18205 +f 25947/25947/17855 25948/25948/18216 25939/25939/18209 +f 25947/25947/17855 25939/25939/18209 25936/25936/18206 +f 25948/25948/18216 25898/25898/17717 25900/25900/18178 +f 25948/25948/18216 25900/25900/18178 25939/25939/18209 +f 25939/25939/18209 25900/25900/18178 25912/25912/18185 +f 25939/25939/18209 25912/25912/18185 25940/25940/18210 +f 25940/25940/18210 25912/25912/18185 25913/25913/18186 +f 25940/25940/18210 25913/25913/18186 25943/25943/18213 +f 25949/25949/18217 25911/25911/18184 25604/25604/17910 +f 25949/25949/18217 25604/25604/17910 25797/25797/18086 +f 25950/25950/18218 25949/25949/18217 25797/25797/18086 +f 25950/25950/18218 25797/25797/18086 25805/25805/18092 +f 25942/25942/18212 25941/25941/18211 25951/25951/18092 +f 25942/25942/18212 25951/25951/18092 25952/25952/18219 +f 25953/25953/18220 25942/25942/18212 25952/25952/18219 +f 25953/25953/18220 25952/25952/18219 25954/25954/17935 +f 25955/25955/18221 25938/25938/18208 25942/25942/18212 +f 25955/25955/18221 25942/25942/18212 25953/25953/18220 +f 25956/25956/18214 25935/25935/18205 25938/25938/18208 +f 25956/25956/18214 25938/25938/18208 25955/25955/18221 +f 25957/25957/18222 25958/25958/18223 25959/25959/18224 +f 25957/25957/18222 25959/25959/18224 25960/25960/18225 +f 25958/25958/18223 25961/25961/18226 25962/25962/18227 +f 25958/25958/18223 25962/25962/18227 25959/25959/18224 +f 25960/25960/18225 25959/25959/18224 25963/25963/18228 +f 25960/25960/18225 25963/25963/18228 25964/25964/18229 +f 25959/25959/18224 25962/25962/18227 25965/25965/18230 +f 25959/25959/18224 25965/25965/18230 25963/25963/18228 +f 25375/25375/17703 25542/25542/17851 25966/25966/18231 +f 25375/25375/17703 25966/25966/18231 25967/25967/18232 +f 25542/25542/17851 25540/25540/17850 25968/25968/18233 +f 25542/25542/17851 25968/25968/18233 25966/25966/18231 +f 25969/25969/18234 25970/25970/17849 25961/25961/18226 +f 25969/25969/18234 25961/25961/18226 25958/25958/18223 +f 25970/25970/17849 25971/25971/17846 25972/25972/18235 +f 25970/25970/17849 25972/25972/18235 25961/25961/18226 +f 25961/25961/18226 25972/25972/18235 25973/25973/18236 +f 25961/25961/18226 25973/25973/18236 25962/25962/18227 +f 25962/25962/18227 25973/25973/18236 25974/25974/18237 +f 25962/25962/18227 25974/25974/18237 25965/25965/18230 +f 25965/25965/18230 25974/25974/18237 25975/25975/17921 +f 25965/25965/18230 25975/25975/17921 25976/25976/18238 +f 25963/25963/18228 25965/25965/18230 25976/25976/18238 +f 25963/25963/18228 25976/25976/18238 25800/25800/18088 +f 25964/25964/18229 25963/25963/18228 25800/25800/18088 +f 25964/25964/18229 25800/25800/18088 25798/25798/18087 +f 25977/25977/18239 25964/25964/18229 25798/25798/18087 +f 25977/25977/18239 25798/25798/18087 25598/25598/17905 +f 25978/25978/18240 25960/25960/18225 25964/25964/18229 +f 25978/25978/18240 25964/25964/18229 25977/25977/18239 +f 25979/25979/18241 25957/25957/18222 25960/25960/18225 +f 25979/25979/18241 25960/25960/18225 25978/25978/18240 +f 25980/25980/18242 25981/25981/18243 25982/25982/18244 +f 25980/25980/18242 25982/25982/18244 25983/25983/18245 +f 25981/25981/18243 25984/25984/18246 25985/25985/18247 +f 25981/25981/18243 25985/25985/18247 25982/25982/18244 +f 25983/25983/18245 25982/25982/18244 25986/25986/18248 +f 25983/25983/18245 25986/25986/18248 25987/25987/18249 +f 25982/25982/18244 25985/25985/18247 25988/25988/18250 +f 25982/25982/18244 25988/25988/18250 25986/25986/18248 +f 25971/25971/17846 25989/25989/17969 25980/25980/18242 +f 25971/25971/17846 25980/25980/18242 25972/25972/18235 +f 25989/25989/17969 25990/25990/18251 25981/25981/18243 +f 25989/25989/17969 25981/25981/18243 25980/25980/18242 +f 25990/25990/18251 25991/25991/17966 25984/25984/18246 +f 25990/25990/18251 25984/25984/18246 25981/25981/18243 +f 25991/25991/17966 25992/25992/17965 25993/25993/18252 +f 25991/25991/17966 25993/25993/18252 25984/25984/18246 +f 25984/25984/18246 25993/25993/18252 25994/25994/18253 +f 25984/25984/18246 25994/25994/18253 25985/25985/18247 +f 25985/25985/18247 25994/25994/18253 25995/25995/18254 +f 25985/25985/18247 25995/25995/18254 25988/25988/18250 +f 25988/25988/18250 25995/25995/18254 25996/25996/17926 +f 25988/25988/18250 25996/25996/17926 25997/25997/18255 +f 25986/25986/18248 25988/25988/18250 25997/25997/18255 +f 25986/25986/18248 25997/25997/18255 25998/25998/18256 +f 25987/25987/18249 25986/25986/18248 25998/25998/18256 +f 25987/25987/18249 25998/25998/18256 25999/25999/17922 +f 25974/25974/18237 25987/25987/18249 25999/25999/17922 +f 25974/25974/18237 25999/25999/17922 25975/25975/17921 +f 25973/25973/18236 25983/25983/18245 25987/25987/18249 +f 25973/25973/18236 25987/25987/18249 25974/25974/18237 +f 25972/25972/18235 25980/25980/18242 25983/25983/18245 +f 25972/25972/18235 25983/25983/18245 25973/25973/18236 +f 26000/26000/18257 26001/26001/18258 26002/26002/18259 +f 26000/26000/18257 26002/26002/18259 26003/26003/18260 +f 26001/26001/18258 26004/26004/18261 26005/26005/18262 +f 26001/26001/18258 26005/26005/18262 26002/26002/18259 +f 26006/26006/18260 26007/26007/18263 26008/26008/18264 +f 26006/26006/18260 26008/26008/18264 26009/26009/18265 +f 26007/26007/18263 26010/26010/18262 26011/26011/18266 +f 26007/26007/18263 26011/26011/18266 26008/26008/18264 +f 25723/25723/18021 25721/25721/18019 26000/26000/18257 +f 25723/25723/18021 26000/26000/18257 25927/25927/18200 +f 25721/25721/18019 25720/25720/18018 26001/26001/18258 +f 25721/25721/18019 26001/26001/18258 26000/26000/18257 +f 25720/25720/18018 25719/25719/18017 26004/26004/18261 +f 25720/25720/18018 26004/26004/18261 26001/26001/18258 +f 25719/25719/18017 25698/25698/17999 26012/26012/18267 +f 25719/25719/18017 26012/26012/18267 26004/26004/18261 +f 26004/26004/18261 26012/26012/18267 26013/26013/18268 +f 26004/26004/18261 26013/26013/18268 26005/26005/18262 +f 26010/26010/18262 26014/26014/18268 26015/26015/18269 +f 26010/26010/18262 26015/26015/18269 26011/26011/18266 +f 26011/26011/18266 26015/26015/18269 26016/26016/18270 +f 26011/26011/18266 26016/26016/18270 26017/26017/18271 +f 26008/26008/18264 26011/26011/18266 26017/26017/18271 +f 26008/26008/18264 26017/26017/18271 26018/26018/18272 +f 26009/26009/18265 26008/26008/18264 26018/26018/18272 +f 26009/26009/18265 26018/26018/18272 26019/26019/17875 +f 25930/25930/18202 26009/26009/18265 26019/26019/17875 +f 25930/25930/18202 26019/26019/17875 25931/25931/18203 +f 25929/25929/18201 26006/26006/18260 26009/26009/18265 +f 25929/25929/18201 26009/26009/18265 25930/25930/18202 +f 25927/25927/18200 26000/26000/18257 26003/26003/18260 +f 25927/25927/18200 26003/26003/18260 25928/25928/18201 +f 26020/26020/18273 26021/26021/18274 26022/26022/18275 +f 26020/26020/18273 26022/26022/18275 26023/26023/18276 +f 26021/26021/18274 26024/26024/18277 26025/26025/18278 +f 26021/26021/18274 26025/26025/18278 26022/26022/18275 +f 26023/26023/18276 26022/26022/18275 26026/26026/18279 +f 26023/26023/18276 26026/26026/18279 26027/26027/18280 +f 26022/26022/18275 26025/26025/18278 26028/26028/18281 +f 26022/26022/18275 26028/26028/18281 26026/26026/18279 +f 25380/25380/17708 25379/25379/17707 26029/26029/18273 +f 25380/25380/17708 26029/26029/18273 25885/25885/18165 +f 25379/25379/17707 25378/25378/17706 26030/26030/18282 +f 25379/25379/17707 26030/26030/18282 26029/26029/18273 +f 25378/25378/17706 25376/25376/17704 26031/26031/18277 +f 25378/25378/17706 26031/26031/18277 26030/26030/18282 +f 25376/25376/17704 25375/25375/17703 25967/25967/18232 +f 25376/25376/17704 25967/25967/18232 26031/26031/18277 +f 26024/26024/18277 25979/25979/18241 25978/25978/18240 +f 26024/26024/18277 25978/25978/18240 26025/26025/18278 +f 26025/26025/18278 25978/25978/18240 25977/25977/18239 +f 26025/26025/18278 25977/25977/18239 26028/26028/18281 +f 26028/26028/18281 25977/25977/18239 25598/25598/17905 +f 26028/26028/18281 25598/25598/17905 25596/25596/17904 +f 26026/26026/18279 26028/26028/18281 25596/25596/17904 +f 26026/26026/18279 25596/25596/17904 25594/25594/17902 +f 26027/26027/18280 26026/26026/18279 25594/25594/17902 +f 26027/26027/18280 25594/25594/17902 25592/25592/17900 +f 25888/25888/18168 26027/26027/18280 25592/25592/17900 +f 25888/25888/18168 25592/25592/17900 25591/25591/17899 +f 25887/25887/18167 26023/26023/18276 26027/26027/18280 +f 25887/25887/18167 26027/26027/18280 25888/25888/18168 +f 25886/25886/18166 26020/26020/18273 26023/26023/18276 +f 25886/25886/18166 26023/26023/18276 25887/25887/18167 +f 26032/26032/18283 26033/26033/18284 26034/26034/18285 +f 26032/26032/18283 26034/26034/18285 26035/26035/18286 +f 26033/26033/18284 26036/26036/18287 26037/26037/18288 +f 26033/26033/18284 26037/26037/18288 26034/26034/18285 +f 26035/26035/18286 26034/26034/18285 26038/26038/18289 +f 26035/26035/18286 26038/26038/18289 26039/26039/18290 +f 26034/26034/18285 26037/26037/18288 26040/26040/18291 +f 26034/26034/18285 26040/26040/18291 26038/26038/18289 +f 25711/25711/18010 25776/25776/18069 26032/26032/18283 +f 25711/25711/18010 26032/26032/18283 25858/25858/18142 +f 25776/25776/18069 25774/25774/18068 26033/26033/18284 +f 25776/25776/18069 26033/26033/18284 26032/26032/18283 +f 25774/25774/18068 25771/25771/18065 26036/26036/18287 +f 25774/25774/18068 26036/26036/18287 26033/26033/18284 +f 25771/25771/18065 25770/25770/18064 25838/25838/18123 +f 25771/25771/18065 25838/25838/18123 26036/26036/18287 +f 26036/26036/18287 25838/25838/18123 25847/25847/18131 +f 26036/26036/18287 25847/25847/18131 26037/26037/18288 +f 26037/26037/18288 25847/25847/18131 25846/25846/18130 +f 26037/26037/18288 25846/25846/18130 26040/26040/18291 +f 26040/26040/18291 25846/25846/18130 25515/25515/17815 +f 26040/26040/18291 25515/25515/17815 26041/26041/18292 +f 26038/26038/18289 26040/26040/18291 26041/26041/18292 +f 26038/26038/18289 26041/26041/18292 26042/26042/18293 +f 26039/26039/18290 26038/26038/18289 26042/26042/18293 +f 26039/26039/18290 26042/26042/18293 26043/26043/18036 +f 25860/25860/18144 26039/26039/18290 26043/26043/18036 +f 25860/25860/18144 26043/26043/18036 25861/25861/18145 +f 25859/25859/18143 26035/26035/18286 26039/26039/18290 +f 25859/25859/18143 26039/26039/18290 25860/25860/18144 +f 25858/25858/18142 26032/26032/18283 26035/26035/18286 +f 25858/25858/18142 26035/26035/18286 25859/25859/18143 +f 26044/26044/18294 26045/26045/18295 26046/26046/18296 +f 26044/26044/18294 26046/26046/18296 26047/26047/18297 +f 26045/26045/18295 26048/26048/18298 26049/26049/18299 +f 26045/26045/18295 26049/26049/18299 26046/26046/18296 +f 26047/26047/18297 26046/26046/18296 26050/26050/18300 +f 26047/26047/18297 26050/26050/18300 26051/26051/18301 +f 26046/26046/18296 26049/26049/18299 26052/26052/18302 +f 26046/26046/18296 26052/26052/18302 26050/26050/18300 +f 25903/25903/17712 26053/26053/18303 26044/26044/18294 +f 25903/25903/17712 26044/26044/18294 25904/25904/18180 +f 26053/26053/18303 26054/26054/18304 26045/26045/18295 +f 26053/26053/18303 26045/26045/18295 26044/26044/18294 +f 26054/26054/18304 26055/26055/18305 26048/26048/18298 +f 26054/26054/18304 26048/26048/18298 26045/26045/18295 +f 26055/26055/18305 25817/25817/18102 25819/25819/18104 +f 26055/26055/18305 25819/25819/18104 26048/26048/18298 +f 26048/26048/18298 25819/25819/18104 25827/25827/18112 +f 26048/26048/18298 25827/25827/18112 26049/26049/18299 +f 26049/26049/18299 25827/25827/18112 25826/25826/18111 +f 26049/26049/18299 25826/25826/18111 26052/26052/18302 +f 26052/26052/18302 25826/25826/18111 25471/25471/17793 +f 26052/26052/18302 25471/25471/17793 26056/26056/18047 +f 26057/26057/18300 26058/26058/18302 25752/25752/18047 +f 26057/26057/18300 25752/25752/18047 25760/25760/18054 +f 26059/26059/18306 26057/26057/18300 25760/25760/18054 +f 26059/26059/18306 25760/25760/18054 25759/25759/18053 +f 25908/25908/18182 26059/26059/18306 25759/25759/18053 +f 25908/25908/18182 25759/25759/18053 25585/25585/17894 +f 25905/25905/18181 26047/26047/18297 26051/26051/18301 +f 25905/25905/18181 26051/26051/18301 25906/25906/18182 +f 25904/25904/18180 26044/26044/18294 26047/26047/18297 +f 25904/25904/18180 26047/26047/18297 25905/25905/18181 +f 26060/26060/18307 26061/26061/18308 26062/26062/18309 +f 26060/26060/18307 26062/26062/18309 26063/26063/18310 +f 26061/26061/18308 26064/26064/18311 26065/26065/18312 +f 26061/26061/18308 26065/26065/18312 26062/26062/18309 +f 26063/26063/18310 26062/26062/18309 26066/26066/18313 +f 26063/26063/18310 26066/26066/18313 26067/26067/18314 +f 26062/26062/18309 26065/26065/18312 26068/26068/18315 +f 26062/26062/18309 26068/26068/18315 26066/26066/18313 +f 25670/25670/17974 25668/25668/17972 26069/26069/18307 +f 25670/25670/17974 26069/26069/18307 26070/26070/18316 +f 25668/25668/17972 25667/25667/17971 26071/26071/18308 +f 25668/25668/17972 26071/26071/18308 26069/26069/18307 +f 25667/25667/17971 25666/25666/17970 26072/26072/18311 +f 25667/25667/17971 26072/26072/18311 26071/26071/18308 +f 25666/25666/17970 25549/25549/17858 25945/25945/18214 +f 25666/25666/17970 25945/25945/18214 26072/26072/18311 +f 26064/26064/18311 25956/25956/18214 25955/25955/18221 +f 26064/26064/18311 25955/25955/18221 26065/26065/18312 +f 26065/26065/18312 25955/25955/18221 25953/25953/18220 +f 26065/26065/18312 25953/25953/18220 26068/26068/18315 +f 26068/26068/18315 25953/25953/18220 25954/25954/17935 +f 26068/26068/18315 25954/25954/17935 26073/26073/17933 +f 26066/26066/18313 26068/26068/18315 26073/26073/17933 +f 26066/26066/18313 26073/26073/17933 26074/26074/17932 +f 26067/26067/18314 26066/26066/18313 26074/26074/17932 +f 26067/26067/18314 26074/26074/17932 26075/26075/18317 +f 26076/26076/18318 26067/26067/18314 26075/26075/18317 +f 26076/26076/18318 26075/26075/18317 26077/26077/17930 +f 26078/26078/18319 26063/26063/18310 26067/26067/18314 +f 26078/26078/18319 26067/26067/18314 26076/26076/18318 +f 26079/26079/18316 26060/26060/18307 26063/26063/18310 +f 26079/26079/18316 26063/26063/18310 26078/26078/18319 +f 26080/26080/18320 26081/26081/18321 26082/26082/18322 +f 26080/26080/18320 26082/26082/18322 26083/26083/18323 +f 26081/26081/18321 26084/26084/18324 26085/26085/18325 +f 26081/26081/18321 26085/26085/18325 26082/26082/18322 +f 26083/26083/18323 26082/26082/18322 26086/26086/18326 +f 26083/26083/18323 26086/26086/18326 26087/26087/18327 +f 26082/26082/18322 26085/26085/18325 26088/26088/18328 +f 26082/26082/18322 26088/26088/18328 26086/26086/18326 +f 25992/25992/17965 25690/25690/17993 26080/26080/18320 +f 25992/25992/17965 26080/26080/18320 25993/25993/18252 +f 25690/25690/17993 25688/25688/17992 26081/26081/18321 +f 25690/25690/17993 26081/26081/18321 26080/26080/18320 +f 25688/25688/17992 25685/25685/17989 26084/26084/18324 +f 25688/25688/17992 26084/26084/18324 26081/26081/18321 +f 25685/25685/17989 25684/25684/17988 25857/25857/18141 +f 25685/25685/17989 25857/25857/18141 26084/26084/18324 +f 26084/26084/18324 25857/25857/18141 25867/25867/18149 +f 26084/26084/18324 25867/25867/18149 26085/26085/18325 +f 26085/26085/18325 25867/25867/18149 25865/25865/18147 +f 26085/26085/18325 25865/25865/18147 26088/26088/18328 +f 26088/26088/18328 25865/25865/18147 25866/25866/18148 +f 26088/26088/18328 25866/25866/18148 26089/26089/17948 +f 26086/26086/18326 26088/26088/18328 26089/26089/17948 +f 26086/26086/18326 26089/26089/17948 26090/26090/17953 +f 26087/26087/18327 26086/26086/18326 26090/26090/17953 +f 26087/26087/18327 26090/26090/17953 26091/26091/17952 +f 25995/25995/18254 26087/26087/18327 26091/26091/17952 +f 25995/25995/18254 26091/26091/17952 25996/25996/17926 +f 25994/25994/18253 26083/26083/18323 26087/26087/18327 +f 25994/25994/18253 26087/26087/18327 25995/25995/18254 +f 25993/25993/18252 26080/26080/18320 26083/26083/18323 +f 25993/25993/18252 26083/26083/18323 25994/25994/18253 +f 26092/26092/18329 26093/26093/18330 26094/26094/18331 +f 26092/26092/18329 26094/26094/18331 26095/26095/18332 +f 26096/26096/18330 26097/26097/18333 26098/26098/18334 +f 26096/26096/18330 26098/26098/18334 26099/26099/18331 +f 26100/26100/18335 26099/26099/18331 26101/26101/18336 +f 26100/26100/18335 26101/26101/18336 26102/26102/18337 +f 26099/26099/18331 26098/26098/18334 26103/26103/18338 +f 26099/26099/18331 26103/26103/18338 26101/26101/18336 +f 25698/25698/17999 25696/25696/17997 26092/26092/18329 +f 25698/25698/17999 26092/26092/18329 26012/26012/18267 +f 25696/25696/17997 25695/25695/17996 26093/26093/18330 +f 25696/25696/17997 26093/26093/18330 26092/26092/18329 +f 25695/25695/17996 26104/26104/18339 26105/26105/18333 +f 25695/25695/17996 26105/26105/18333 26093/26093/18330 +f 25693/25693/17995 25670/25670/17974 26070/26070/18316 +f 25693/25693/17995 26070/26070/18316 26106/26106/18333 +f 26097/26097/18333 26079/26079/18316 26078/26078/18319 +f 26097/26097/18333 26078/26078/18319 26098/26098/18334 +f 26098/26098/18334 26078/26078/18319 26076/26076/18318 +f 26098/26098/18334 26076/26076/18318 26103/26103/18338 +f 26103/26103/18338 26076/26076/18318 26077/26077/17930 +f 26103/26103/18338 26077/26077/17930 26107/26107/17951 +f 26101/26101/18336 26103/26103/18338 26107/26107/17951 +f 26101/26101/18336 26107/26107/17951 26108/26108/17950 +f 26102/26102/18337 26101/26101/18336 26108/26108/17950 +f 26102/26102/18337 26108/26108/17950 26109/26109/17949 +f 26015/26015/18269 26102/26102/18337 26109/26109/17949 +f 26015/26015/18269 26109/26109/17949 26016/26016/18270 +f 26014/26014/18268 26100/26100/18335 26102/26102/18337 +f 26014/26014/18268 26102/26102/18337 26015/26015/18269 +f 26012/26012/18267 26092/26092/18329 26095/26095/18332 +f 26012/26012/18267 26095/26095/18332 26013/26013/18268 +f 26110/26110/18340 26111/26111/18341 26112/26112/18342 +f 26110/26110/18340 26112/26112/18342 26113/26113/18343 +f 26111/26111/18341 26114/26114/18344 26115/26115/18345 +f 26111/26111/18341 26115/26115/18345 26112/26112/18342 +f 26113/26113/18343 26112/26112/18342 26116/26116/18346 +f 26113/26113/18343 26116/26116/18346 26117/26117/18347 +f 26112/26112/18342 26115/26115/18345 26118/26118/18348 +f 26112/26112/18342 26118/26118/18348 26116/26116/18346 +f 25380/25380/17708 25883/25883/18163 26110/26110/18340 +f 25380/25380/17708 26110/26110/18340 25381/25381/17709 +f 25883/25883/18163 25881/25881/18161 26111/26111/18341 +f 25883/25883/18163 26111/26111/18341 26110/26110/18340 +f 25881/25881/18161 25878/25878/18160 26114/26114/18344 +f 25881/25881/18161 26114/26114/18344 26111/26111/18341 +f 25878/25878/18160 25877/25877/18159 26119/26119/18349 +f 25878/25878/18160 26119/26119/18349 26114/26114/18344 +f 26114/26114/18344 26119/26119/18349 26120/26120/18350 +f 26114/26114/18344 26120/26120/18350 26115/26115/18345 +f 26115/26115/18345 26120/26120/18350 26121/26121/18351 +f 26115/26115/18345 26121/26121/18351 26118/26118/18348 +f 26122/26122/18348 26123/26123/18352 25817/25817/18102 +f 26122/26122/18348 25817/25817/18102 26055/26055/18305 +f 26124/26124/18346 26122/26122/18348 26055/26055/18305 +f 26124/26124/18346 26055/26055/18305 26054/26054/18304 +f 26117/26117/18347 26116/26116/18346 26125/26125/18304 +f 26117/26117/18347 26125/26125/18304 26126/26126/18353 +f 25383/25383/17711 26117/26117/18347 26126/26126/18353 +f 25383/25383/17711 26126/26126/18353 25384/25384/17712 +f 25382/25382/17710 26113/26113/18343 26117/26117/18347 +f 25382/25382/17710 26117/26117/18347 25383/25383/17711 +f 25381/25381/17709 26110/26110/18340 26113/26113/18343 +f 25381/25381/17709 26113/26113/18343 25382/25382/17710 +f 26127/26127/18354 26128/26128/18355 26129/26129/18356 +f 26127/26127/18354 26129/26129/18356 26130/26130/18357 +f 26128/26128/18355 26131/26131/18358 26132/26132/18359 +f 26128/26128/18355 26132/26132/18359 26129/26129/18356 +f 26130/26130/18357 26129/26129/18356 26133/26133/18360 +f 26130/26130/18357 26133/26133/18360 26134/26134/18361 +f 26129/26129/18356 26132/26132/18359 26135/26135/18362 +f 26129/26129/18356 26135/26135/18362 26133/26133/18360 +f 26136/26136/18126 26137/26137/18125 26127/26127/18354 +f 26136/26136/18126 26127/26127/18354 26138/26138/18363 +f 26137/26137/18125 26139/26139/18124 26128/26128/18355 +f 26137/26137/18125 26128/26128/18355 26127/26127/18354 +f 26139/26139/18124 26140/26140/18122 26131/26131/18358 +f 26139/26139/18124 26131/26131/18358 26128/26128/18355 +f 26140/26140/18122 26141/26141/18364 26142/26142/18067 +f 26140/26140/18122 26142/26142/18067 26131/26131/18358 +f 26131/26131/18358 26142/26142/18067 26143/26143/18075 +f 26131/26131/18358 26143/26143/18075 26132/26132/18359 +f 26132/26132/18359 26143/26143/18075 26144/26144/18365 +f 26132/26132/18359 26144/26144/18365 26135/26135/18362 +f 26145/26145/18362 25781/25781/18073 25782/25782/18074 +f 26145/26145/18362 25782/25782/18074 26146/26146/18366 +f 26133/26133/18360 26135/26135/18362 26147/26147/18106 +f 26133/26133/18360 26147/26147/18106 26148/26148/18105 +f 26134/26134/18361 26133/26133/18360 26148/26148/18105 +f 26134/26134/18361 26148/26148/18105 26149/26149/18103 +f 26123/26123/18352 26150/26150/18367 25818/25818/18103 +f 26123/26123/18352 25818/25818/18103 25817/25817/18102 +f 26151/26151/18368 26130/26130/18357 26134/26134/18361 +f 26151/26151/18368 26134/26134/18361 26152/26152/18351 +f 26138/26138/18363 26127/26127/18354 26130/26130/18357 +f 26138/26138/18363 26130/26130/18357 26151/26151/18368 +o Cube.042__0 +v 0.354049 -0.277498 -0.167407 +v 0.354476 -0.278887 -0.160301 +v 0.407040 -0.269890 -0.159812 +v 0.407040 -0.268427 -0.166914 +v 0.355638 -0.281940 -0.154253 +v 0.407040 -0.273141 -0.153775 +v 0.459604 -0.278887 -0.160301 +v 0.460032 -0.277498 -0.167408 +v 0.458443 -0.281940 -0.154253 +v 0.310029 -0.304183 -0.176524 +v 0.310141 -0.304710 -0.168886 +v 0.353987 -0.276939 -0.175043 +v 0.310923 -0.305880 -0.161768 +v 0.313047 -0.308337 -0.155688 +v 0.313047 -0.308337 -0.155688 +v 0.317181 -0.312723 -0.151165 +v 0.357898 -0.287488 -0.149794 +v 0.355638 -0.281940 -0.154253 +v 0.407040 -0.279076 -0.149337 +v 0.407040 -0.273141 -0.153775 +v 0.456182 -0.287488 -0.149794 +v 0.458443 -0.281940 -0.154253 +v 0.496899 -0.312723 -0.151165 +v 0.501033 -0.308337 -0.155688 +v 0.501033 -0.308337 -0.155688 +v 0.503157 -0.305880 -0.161768 +v 0.503939 -0.304710 -0.168886 +v 0.460093 -0.276939 -0.175043 +v 0.504051 -0.304183 -0.176524 +v 0.407040 -0.267858 -0.174550 +v 0.531192 -0.348553 -0.171269 +v 0.530190 -0.349369 -0.164131 +v 0.539200 -0.401855 -0.166984 +v 0.540276 -0.401466 -0.174145 +v 0.527469 -0.350865 -0.157999 +v 0.536281 -0.402192 -0.160789 +v 0.530190 -0.454341 -0.169836 +v 0.531192 -0.454380 -0.177020 +v 0.527469 -0.453519 -0.163578 +v 0.504051 -0.304183 -0.176524 +v 0.503939 -0.304710 -0.168886 +v 0.531335 -0.348076 -0.178909 +v 0.503157 -0.305880 -0.161768 +v 0.501033 -0.308337 -0.155688 +v 0.522172 -0.353380 -0.153375 +v 0.527469 -0.350865 -0.157999 +v 0.530596 -0.402450 -0.156041 +v 0.536281 -0.402192 -0.160789 +v 0.522172 -0.451519 -0.158708 +v 0.527469 -0.453519 -0.163578 +v 0.496899 -0.492177 -0.160918 +v 0.501033 -0.496047 -0.165889 +v 0.501033 -0.496047 -0.165889 +v 0.503157 -0.497830 -0.172200 +v 0.503939 -0.498222 -0.179403 +v 0.531335 -0.454025 -0.184667 +v 0.504051 -0.497918 -0.187052 +v 0.540430 -0.401051 -0.181788 +v 0.460032 -0.525435 -0.180882 +v 0.459604 -0.524823 -0.173667 +v 0.407040 -0.533821 -0.174155 +v 0.407040 -0.534506 -0.181375 +v 0.458443 -0.522444 -0.167324 +v 0.407040 -0.531242 -0.167802 +v 0.354476 -0.524823 -0.173666 +v 0.354049 -0.525435 -0.180882 +v 0.355638 -0.522444 -0.167324 +v 0.504051 -0.497918 -0.187052 +v 0.503939 -0.498222 -0.179403 +v 0.460093 -0.525162 -0.188533 +v 0.503157 -0.497830 -0.172200 +v 0.501033 -0.496047 -0.165889 +v 0.456182 -0.517412 -0.162289 +v 0.458443 -0.522444 -0.167324 +v 0.407040 -0.525824 -0.162746 +v 0.407040 -0.531242 -0.167802 +v 0.357898 -0.517412 -0.162289 +v 0.355638 -0.522444 -0.167324 +v 0.317181 -0.492177 -0.160918 +v 0.313047 -0.496047 -0.165889 +v 0.354476 -0.524823 -0.173666 +v 0.355638 -0.522444 -0.167324 +v 0.313047 -0.496047 -0.165889 +v 0.310923 -0.497830 -0.172200 +v 0.310923 -0.497830 -0.172200 +v 0.310141 -0.498222 -0.179403 +v 0.353987 -0.525162 -0.188533 +v 0.310029 -0.497918 -0.187052 +v 0.407040 -0.534243 -0.189026 +v 0.282889 -0.454380 -0.177020 +v 0.283891 -0.454341 -0.169836 +v 0.274880 -0.401855 -0.166984 +v 0.273804 -0.401466 -0.174145 +v 0.286611 -0.453519 -0.163578 +v 0.277799 -0.402192 -0.160789 +v 0.283891 -0.349369 -0.164131 +v 0.282889 -0.348553 -0.171269 +v 0.286611 -0.350865 -0.157999 +v 0.310029 -0.497918 -0.187052 +v 0.310141 -0.498222 -0.179403 +v 0.282745 -0.454025 -0.184667 +v 0.291908 -0.451519 -0.158708 +v 0.286611 -0.453519 -0.163578 +v 0.283484 -0.402450 -0.156041 +v 0.277799 -0.402192 -0.160789 +v 0.291908 -0.353380 -0.153375 +v 0.286611 -0.350865 -0.157999 +v 0.283891 -0.349369 -0.164131 +v 0.286611 -0.350865 -0.157999 +v 0.310923 -0.305880 -0.161768 +v 0.310141 -0.304710 -0.168886 +v 0.282745 -0.348076 -0.178909 +v 0.310029 -0.304183 -0.176524 +v 0.273650 -0.401051 -0.181788 +v 0.455670 -0.423571 -0.149929 +v 0.459228 -0.402843 -0.148802 +v 0.457556 -0.402908 -0.147603 +v 0.454113 -0.422982 -0.148694 +v 0.455670 -0.382116 -0.147676 +v 0.454113 -0.382835 -0.146512 +v 0.455783 -0.402974 -0.146404 +v 0.452459 -0.422368 -0.147458 +v 0.452459 -0.383579 -0.145350 +v 0.446714 -0.442405 -0.151949 +v 0.457873 -0.424454 -0.150973 +v 0.444995 -0.440745 -0.150862 +v 0.461593 -0.402789 -0.149796 +v 0.457873 -0.381124 -0.148618 +v 0.446714 -0.363173 -0.147643 +v 0.444995 -0.364942 -0.146742 +v 0.443779 -0.366203 -0.145608 +v 0.442489 -0.367509 -0.144477 +v 0.440546 -0.369410 -0.143584 +v 0.449970 -0.384643 -0.144411 +v 0.453110 -0.403028 -0.145411 +v 0.449970 -0.421412 -0.146410 +v 0.442489 -0.438438 -0.148331 +v 0.440546 -0.436645 -0.147238 +v 0.443779 -0.439614 -0.149598 +v 0.370664 -0.317626 -0.146348 +v 0.407040 -0.311399 -0.146009 +v 0.407040 -0.299453 -0.145925 +v 0.365917 -0.306492 -0.146307 +v 0.443417 -0.317626 -0.146348 +v 0.448163 -0.306492 -0.146307 +v 0.407040 -0.288198 -0.146846 +v 0.361467 -0.295999 -0.147270 +v 0.452613 -0.295999 -0.147271 +v 0.348672 -0.344448 -0.147725 +v 0.375120 -0.328056 -0.146834 +v 0.340523 -0.336306 -0.147363 +v 0.407040 -0.322592 -0.146537 +v 0.438960 -0.328056 -0.146834 +v 0.465408 -0.344448 -0.147725 +v 0.473557 -0.336306 -0.147363 +v 0.482236 -0.327610 -0.147455 +v 0.490373 -0.319402 -0.148542 +v 0.323707 -0.319402 -0.148542 +v 0.331844 -0.327610 -0.147455 +v 0.492265 -0.366402 -0.148999 +v 0.498501 -0.402725 -0.150973 +v 0.510434 -0.402695 -0.151536 +v 0.503385 -0.361633 -0.149304 +v 0.492265 -0.439048 -0.152947 +v 0.503385 -0.443757 -0.153767 +v 0.521623 -0.402612 -0.153064 +v 0.513811 -0.357106 -0.150591 +v 0.513811 -0.448117 -0.155538 +v 0.481824 -0.370857 -0.149160 +v 0.487296 -0.402730 -0.150892 +v 0.481824 -0.434603 -0.152624 +v 0.465408 -0.461012 -0.154060 +v 0.473557 -0.469145 -0.154582 +v 0.482236 -0.477780 -0.155616 +v 0.490373 -0.485822 -0.157587 +v 0.443417 -0.487825 -0.155597 +v 0.407040 -0.494052 -0.155936 +v 0.407040 -0.505937 -0.157146 +v 0.448163 -0.498897 -0.156764 +v 0.370664 -0.487825 -0.155597 +v 0.365917 -0.498897 -0.156764 +v 0.407040 -0.517026 -0.159282 +v 0.452613 -0.509225 -0.158858 +v 0.361467 -0.509225 -0.158859 +v 0.438960 -0.477404 -0.154950 +v 0.407040 -0.482868 -0.155247 +v 0.375120 -0.477404 -0.154950 +v 0.348672 -0.461012 -0.154060 +v 0.340523 -0.469145 -0.154582 +v 0.331844 -0.477780 -0.155616 +v 0.323707 -0.485822 -0.157587 +v 0.321815 -0.439048 -0.152946 +v 0.315579 -0.402725 -0.150973 +v 0.303646 -0.402695 -0.151536 +v 0.310695 -0.443757 -0.153767 +v 0.321815 -0.366402 -0.148998 +v 0.310695 -0.361633 -0.149304 +v 0.292457 -0.402612 -0.153064 +v 0.300269 -0.448117 -0.155537 +v 0.300269 -0.357106 -0.150591 +v 0.332256 -0.434603 -0.152624 +v 0.326784 -0.402730 -0.150892 +v 0.332256 -0.370857 -0.149160 +v 0.383852 -0.348508 -0.147482 +v 0.407040 -0.344539 -0.147266 +v 0.407040 -0.339114 -0.147298 +v 0.381698 -0.343452 -0.147533 +v 0.430228 -0.348508 -0.147482 +v 0.432382 -0.343452 -0.147533 +v 0.407040 -0.331860 -0.147023 +v 0.378811 -0.336692 -0.147286 +v 0.435269 -0.336692 -0.147286 +v 0.367366 -0.363173 -0.147643 +v 0.385343 -0.352031 -0.147037 +v 0.364639 -0.360416 -0.148129 +v 0.407040 -0.348317 -0.146835 +v 0.428737 -0.352031 -0.147037 +v 0.449441 -0.360416 -0.148129 +v 0.453380 -0.356466 -0.148241 +v 0.458659 -0.351188 -0.148074 +v 0.355422 -0.351188 -0.148074 +v 0.360701 -0.356466 -0.148241 +v 0.461366 -0.379601 -0.149171 +v 0.465342 -0.402755 -0.150430 +v 0.470757 -0.402737 -0.150755 +v 0.466413 -0.377433 -0.149380 +v 0.461366 -0.425909 -0.151688 +v 0.466413 -0.428042 -0.152130 +v 0.478016 -0.402731 -0.150875 +v 0.473176 -0.374543 -0.149343 +v 0.473176 -0.430918 -0.152407 +v 0.449441 -0.445094 -0.152731 +v 0.453380 -0.449008 -0.153270 +v 0.458659 -0.454273 -0.153676 +v 0.430228 -0.457001 -0.153378 +v 0.407040 -0.460971 -0.153594 +v 0.407040 -0.466360 -0.154213 +v 0.432382 -0.462022 -0.153977 +v 0.383852 -0.457001 -0.153378 +v 0.381698 -0.462022 -0.153977 +v 0.407040 -0.473602 -0.154726 +v 0.435269 -0.468770 -0.154464 +v 0.378811 -0.468770 -0.154464 +v 0.428737 -0.453547 -0.152554 +v 0.407040 -0.457262 -0.152756 +v 0.385343 -0.453547 -0.152554 +v 0.367366 -0.442405 -0.151949 +v 0.364639 -0.445094 -0.152731 +v 0.360701 -0.449008 -0.153270 +v 0.355422 -0.454273 -0.153676 +v 0.352714 -0.425909 -0.151688 +v 0.348738 -0.402755 -0.150430 +v 0.343323 -0.402737 -0.150755 +v 0.347668 -0.428042 -0.152130 +v 0.352714 -0.379601 -0.149171 +v 0.347668 -0.377433 -0.149380 +v 0.336065 -0.402731 -0.150875 +v 0.340904 -0.430918 -0.152407 +v 0.340904 -0.374543 -0.149343 +v 0.356207 -0.424454 -0.150973 +v 0.352488 -0.402789 -0.149796 +v 0.356207 -0.381124 -0.148618 +v 0.400040 -0.385349 -0.080876 +v 0.400041 -0.385132 -0.082237 +v 0.407040 -0.385986 -0.082377 +v 0.407040 -0.386189 -0.081105 +v 0.400049 -0.385440 -0.084231 +v 0.407040 -0.386290 -0.084270 +v 0.414039 -0.385132 -0.082237 +v 0.414041 -0.385349 -0.080876 +v 0.414031 -0.385440 -0.084231 +v 0.393857 -0.383658 -0.078485 +v 0.393855 -0.382832 -0.080188 +v 0.400040 -0.386068 -0.079458 +v 0.393859 -0.382568 -0.081818 +v 0.393874 -0.382890 -0.084116 +v 0.393907 -0.383820 -0.087822 +v 0.400066 -0.386301 -0.087548 +v 0.407040 -0.387128 -0.087457 +v 0.414015 -0.386301 -0.087548 +v 0.420173 -0.383820 -0.087822 +v 0.420206 -0.382890 -0.084116 +v 0.420221 -0.382568 -0.081818 +v 0.420225 -0.382832 -0.080188 +v 0.414040 -0.386068 -0.079458 +v 0.420224 -0.383658 -0.078485 +v 0.407040 -0.386871 -0.079783 +v 0.386284 -0.451405 -0.151441 +v 0.407040 -0.454958 -0.151634 +v 0.407040 -0.453378 -0.150346 +v 0.386949 -0.449937 -0.150159 +v 0.427797 -0.451405 -0.151441 +v 0.427132 -0.449937 -0.150159 +v 0.407040 -0.451738 -0.149054 +v 0.387654 -0.448413 -0.148873 +v 0.426426 -0.448413 -0.148873 +v 0.369085 -0.440745 -0.150862 +v 0.425364 -0.446100 -0.147751 +v 0.407040 -0.449252 -0.147923 +v 0.388717 -0.446100 -0.147751 +v 0.371591 -0.438438 -0.148331 +v 0.373534 -0.436645 -0.147238 +v 0.370301 -0.439614 -0.149598 +v 0.427797 -0.354282 -0.146163 +v 0.407040 -0.350729 -0.145970 +v 0.407040 -0.352439 -0.144860 +v 0.427132 -0.355880 -0.145047 +v 0.386284 -0.354282 -0.146163 +v 0.386949 -0.355880 -0.145047 +v 0.407040 -0.354210 -0.143754 +v 0.426426 -0.357535 -0.143935 +v 0.387654 -0.357535 -0.143934 +v 0.369085 -0.364942 -0.146742 +v 0.370301 -0.366203 -0.145608 +v 0.371591 -0.367509 -0.144477 +v 0.373534 -0.369410 -0.143584 +v 0.388717 -0.359955 -0.143070 +v 0.407040 -0.356803 -0.142899 +v 0.425364 -0.359955 -0.143070 +v 0.358411 -0.382116 -0.147676 +v 0.354852 -0.402843 -0.148802 +v 0.356524 -0.402908 -0.147603 +v 0.359968 -0.382835 -0.146512 +v 0.358411 -0.423571 -0.149929 +v 0.359968 -0.422982 -0.148694 +v 0.358298 -0.402974 -0.146404 +v 0.361621 -0.383579 -0.145350 +v 0.361621 -0.422368 -0.147458 +v 0.364111 -0.421412 -0.146410 +v 0.360970 -0.403028 -0.145411 +v 0.364111 -0.384643 -0.144411 +v 0.394128 -0.371295 -0.138482 +v 0.407040 -0.368976 -0.138289 +v 0.407040 -0.365101 -0.141155 +v 0.392260 -0.367692 -0.141324 +v 0.419953 -0.371295 -0.138482 +v 0.421821 -0.367692 -0.141324 +v 0.407040 -0.360682 -0.142319 +v 0.390338 -0.363571 -0.142480 +v 0.423743 -0.363571 -0.142480 +v 0.386154 -0.380011 -0.132677 +v 0.395731 -0.373038 -0.132572 +v 0.394128 -0.371295 -0.138482 +v 0.383520 -0.378331 -0.139181 +v 0.407040 -0.371053 -0.132482 +v 0.407040 -0.368976 -0.138289 +v 0.418350 -0.373038 -0.132572 +v 0.419953 -0.371295 -0.138482 +v 0.427927 -0.380011 -0.132677 +v 0.430560 -0.378331 -0.139181 +v 0.430560 -0.378331 -0.139181 +v 0.434025 -0.375467 -0.141852 +v 0.437577 -0.372241 -0.142964 +v 0.376504 -0.372241 -0.142964 +v 0.380055 -0.375467 -0.141852 +v 0.383520 -0.378331 -0.139181 +v 0.436862 -0.389691 -0.140525 +v 0.438870 -0.403240 -0.141620 +v 0.444002 -0.403126 -0.143633 +v 0.441528 -0.387996 -0.142711 +v 0.436862 -0.416831 -0.141999 +v 0.441528 -0.418268 -0.144356 +v 0.449009 -0.403068 -0.144675 +v 0.446154 -0.386209 -0.143746 +v 0.446154 -0.419928 -0.145578 +v 0.427927 -0.380011 -0.132677 +v 0.432975 -0.391461 -0.136663 +v 0.436862 -0.389691 -0.140525 +v 0.430560 -0.378331 -0.139181 +v 0.432975 -0.391461 -0.136663 +v 0.434383 -0.403437 -0.138156 +v 0.432975 -0.415509 -0.137970 +v 0.432975 -0.415509 -0.137970 +v 0.427927 -0.427344 -0.135248 +v 0.430560 -0.428274 -0.141895 +v 0.436862 -0.416831 -0.141999 +v 0.430560 -0.428274 -0.141895 +v 0.434025 -0.430818 -0.144860 +v 0.437577 -0.433899 -0.146315 +v 0.419953 -0.435346 -0.141963 +v 0.407040 -0.437673 -0.142023 +v 0.407040 -0.441199 -0.145291 +v 0.421821 -0.438605 -0.145178 +v 0.394128 -0.435346 -0.141963 +v 0.392260 -0.438605 -0.145178 +v 0.407040 -0.445460 -0.146927 +v 0.423743 -0.442570 -0.146773 +v 0.390338 -0.442570 -0.146773 +v 0.427927 -0.427344 -0.135248 +v 0.418350 -0.434288 -0.135900 +v 0.419953 -0.435346 -0.141963 +v 0.430560 -0.428274 -0.141895 +v 0.407040 -0.436271 -0.136026 +v 0.407040 -0.437673 -0.142023 +v 0.395731 -0.434288 -0.135900 +v 0.394128 -0.435346 -0.141963 +v 0.395731 -0.434288 -0.135900 +v 0.386154 -0.427344 -0.135248 +v 0.383520 -0.428274 -0.141895 +v 0.394128 -0.435346 -0.141963 +v 0.383520 -0.428274 -0.141895 +v 0.380055 -0.430818 -0.144860 +v 0.376504 -0.433899 -0.146315 +v 0.377218 -0.416831 -0.141999 +v 0.375211 -0.403240 -0.141619 +v 0.370079 -0.403126 -0.143633 +v 0.372552 -0.418268 -0.144356 +v 0.377218 -0.389691 -0.140524 +v 0.372552 -0.387996 -0.142711 +v 0.365071 -0.403068 -0.144675 +v 0.367926 -0.419928 -0.145578 +v 0.367926 -0.386209 -0.143746 +v 0.381105 -0.415509 -0.137970 +v 0.377218 -0.416831 -0.141999 +v 0.381105 -0.415509 -0.137970 +v 0.379697 -0.403437 -0.138157 +v 0.381105 -0.391461 -0.136663 +v 0.381105 -0.391461 -0.136663 +v 0.386154 -0.380011 -0.132677 +v 0.383520 -0.378331 -0.139181 +v 0.377218 -0.389691 -0.140524 +v 0.400042 -0.392102 -0.072977 +v 0.400041 -0.389239 -0.075178 +v 0.407040 -0.389898 -0.075733 +v 0.407040 -0.392641 -0.073641 +v 0.400041 -0.389239 -0.075178 +v 0.400041 -0.387303 -0.077480 +v 0.407040 -0.388048 -0.077917 +v 0.407040 -0.389898 -0.075733 +v 0.414039 -0.389239 -0.075178 +v 0.414039 -0.392102 -0.072977 +v 0.414039 -0.387303 -0.077480 +v 0.414039 -0.389239 -0.075178 +v 0.393859 -0.394980 -0.069064 +v 0.393859 -0.390485 -0.070987 +v 0.400042 -0.396118 -0.071300 +v 0.393859 -0.387263 -0.073513 +v 0.393859 -0.387263 -0.073513 +v 0.393858 -0.385068 -0.076170 +v 0.420223 -0.385068 -0.076170 +v 0.420222 -0.387263 -0.073513 +v 0.420222 -0.387263 -0.073513 +v 0.420222 -0.390485 -0.070987 +v 0.414039 -0.396118 -0.071300 +v 0.420222 -0.394980 -0.069064 +v 0.407040 -0.396497 -0.072045 +v 0.398006 -0.450683 -0.087996 +v 0.407040 -0.451533 -0.088049 +v 0.407040 -0.452512 -0.083298 +v 0.397992 -0.451647 -0.083344 +v 0.416075 -0.450683 -0.087996 +v 0.416088 -0.451647 -0.083344 +v 0.407040 -0.452297 -0.079438 +v 0.397988 -0.451437 -0.079574 +v 0.416093 -0.451437 -0.079574 +v 0.390950 -0.445983 -0.094108 +v 0.398033 -0.448419 -0.094651 +v 0.390903 -0.448134 -0.087833 +v 0.407040 -0.449231 -0.094832 +v 0.416047 -0.448419 -0.094651 +v 0.423130 -0.445983 -0.094108 +v 0.423178 -0.448134 -0.087833 +v 0.423202 -0.449051 -0.083483 +v 0.423210 -0.448856 -0.079983 +v 0.423211 -0.447675 -0.076259 +v 0.416093 -0.450180 -0.075562 +v 0.407040 -0.451015 -0.075330 +v 0.397987 -0.450180 -0.075562 +v 0.390871 -0.448856 -0.079983 +v 0.390870 -0.447675 -0.076259 +v 0.390879 -0.449051 -0.083483 +v 0.416075 -0.362207 -0.083183 +v 0.407040 -0.361357 -0.083144 +v 0.407040 -0.360924 -0.078282 +v 0.416088 -0.361778 -0.078422 +v 0.398006 -0.362207 -0.083183 +v 0.397992 -0.361778 -0.078422 +v 0.407040 -0.361575 -0.074381 +v 0.416093 -0.362414 -0.074610 +v 0.397988 -0.362414 -0.074610 +v 0.423130 -0.366179 -0.089774 +v 0.416047 -0.363698 -0.090048 +v 0.423178 -0.364757 -0.083297 +v 0.407040 -0.362871 -0.090140 +v 0.398033 -0.363698 -0.090048 +v 0.390950 -0.366179 -0.089774 +v 0.390903 -0.364757 -0.083297 +v 0.390879 -0.364342 -0.078841 +v 0.390871 -0.364931 -0.075298 +v 0.390870 -0.366524 -0.071564 +v 0.397987 -0.364114 -0.070590 +v 0.407040 -0.363311 -0.070266 +v 0.416093 -0.364114 -0.070590 +v 0.423210 -0.364931 -0.075298 +v 0.423211 -0.366524 -0.071564 +v 0.423202 -0.364342 -0.078841 +v 0.397987 -0.396472 -0.048965 +v 0.397987 -0.408460 -0.048967 +v 0.407040 -0.408504 -0.048177 +v 0.407040 -0.396293 -0.048177 +v 0.397987 -0.420351 -0.050778 +v 0.407040 -0.420615 -0.050024 +v 0.416093 -0.408460 -0.048967 +v 0.416093 -0.396472 -0.048965 +v 0.416093 -0.420351 -0.050778 +v 0.390871 -0.386889 -0.053164 +v 0.390871 -0.397008 -0.051327 +v 0.397987 -0.385751 -0.050928 +v 0.390871 -0.408329 -0.051335 +v 0.390871 -0.419558 -0.053041 +v 0.390871 -0.429401 -0.056298 +v 0.397987 -0.430777 -0.054245 +v 0.407040 -0.431236 -0.053560 +v 0.416093 -0.430777 -0.054245 +v 0.423210 -0.429401 -0.056298 +v 0.423210 -0.419558 -0.053041 +v 0.423210 -0.408329 -0.051335 +v 0.423210 -0.397008 -0.051327 +v 0.416093 -0.385751 -0.050928 +v 0.423210 -0.386889 -0.053164 +v 0.407040 -0.385371 -0.050183 +v 0.397987 -0.447903 -0.070491 +v 0.407040 -0.448692 -0.070145 +v 0.407040 -0.444945 -0.064302 +v 0.397987 -0.444229 -0.064770 +v 0.416093 -0.447903 -0.070491 +v 0.416093 -0.444229 -0.064770 +v 0.397987 -0.444229 -0.064770 +v 0.407040 -0.444945 -0.064302 +v 0.407040 -0.439288 -0.058531 +v 0.397987 -0.438679 -0.059116 +v 0.416093 -0.444229 -0.064770 +v 0.416093 -0.438679 -0.059116 +v 0.390870 -0.445537 -0.071528 +v 0.423210 -0.445537 -0.071528 +v 0.423210 -0.442081 -0.066173 +v 0.423210 -0.442081 -0.066173 +v 0.423210 -0.436854 -0.060871 +v 0.390871 -0.436854 -0.060871 +v 0.390871 -0.442081 -0.066173 +v 0.390871 -0.442081 -0.066173 +v 0.400042 -0.413128 -0.071390 +v 0.400042 -0.407264 -0.070542 +v 0.407040 -0.407220 -0.071331 +v 0.407040 -0.412863 -0.072144 +v 0.400042 -0.401357 -0.070486 +v 0.407040 -0.401536 -0.071273 +v 0.414039 -0.407264 -0.070542 +v 0.414039 -0.413128 -0.071390 +v 0.414039 -0.401357 -0.070486 +v 0.393859 -0.419614 -0.070900 +v 0.393859 -0.413921 -0.069128 +v 0.400042 -0.418238 -0.072954 +v 0.393859 -0.407395 -0.068174 +v 0.393859 -0.400821 -0.068124 +v 0.420222 -0.400821 -0.068124 +v 0.420222 -0.407395 -0.068174 +v 0.420222 -0.413921 -0.069128 +v 0.414039 -0.418238 -0.072954 +v 0.420222 -0.419614 -0.070900 +v 0.407040 -0.417779 -0.073638 +v 0.400041 -0.426340 -0.079939 +v 0.400041 -0.424658 -0.077554 +v 0.407040 -0.423942 -0.078022 +v 0.407040 -0.425551 -0.080285 +v 0.400041 -0.424658 -0.077554 +v 0.400042 -0.422046 -0.075109 +v 0.407040 -0.421438 -0.075695 +v 0.407040 -0.423942 -0.078022 +v 0.414039 -0.424658 -0.077554 +v 0.414039 -0.426340 -0.079939 +v 0.414039 -0.422046 -0.075110 +v 0.414039 -0.424658 -0.077554 +v 0.393857 -0.429865 -0.081218 +v 0.393858 -0.428707 -0.078902 +v 0.400040 -0.427360 -0.081915 +v 0.393859 -0.426806 -0.076151 +v 0.393859 -0.426806 -0.076151 +v 0.393859 -0.423872 -0.073354 +v 0.420222 -0.423872 -0.073354 +v 0.420222 -0.426806 -0.076151 +v 0.420222 -0.426806 -0.076151 +v 0.420223 -0.428707 -0.078902 +v 0.414040 -0.427360 -0.081915 +v 0.420224 -0.429865 -0.081218 +v 0.407040 -0.426526 -0.082147 +v 0.400049 -0.427463 -0.086518 +v 0.400041 -0.427994 -0.084613 +v 0.407040 -0.427129 -0.084659 +v 0.407040 -0.426613 -0.086464 +v 0.400040 -0.427926 -0.083304 +v 0.407040 -0.427066 -0.083441 +v 0.414039 -0.427994 -0.084613 +v 0.414031 -0.427463 -0.086518 +v 0.414041 -0.427926 -0.083304 +v 0.393907 -0.428664 -0.090242 +v 0.393874 -0.430012 -0.086680 +v 0.400066 -0.426229 -0.089699 +v 0.393859 -0.430590 -0.084474 +v 0.393855 -0.430506 -0.082895 +v 0.420225 -0.430506 -0.082895 +v 0.420221 -0.430590 -0.084474 +v 0.420206 -0.430012 -0.086680 +v 0.414015 -0.426229 -0.089699 +v 0.420174 -0.428664 -0.090242 +v 0.407040 -0.425417 -0.089517 +v 0.397048 -0.436630 -0.126335 +v 0.407040 -0.437922 -0.126695 +v 0.407040 -0.441540 -0.115497 +v 0.397789 -0.440659 -0.115071 +v 0.417032 -0.436630 -0.126335 +v 0.416292 -0.440659 -0.115071 +v 0.407040 -0.445653 -0.104342 +v 0.398033 -0.444875 -0.104010 +v 0.416047 -0.444875 -0.104010 +v 0.386154 -0.427344 -0.135248 +v 0.389462 -0.433357 -0.124623 +v 0.424618 -0.433357 -0.124623 +v 0.423457 -0.438241 -0.113584 +v 0.423117 -0.442569 -0.102988 +v 0.390964 -0.442569 -0.102988 +v 0.390624 -0.438241 -0.113584 +v 0.417032 -0.371801 -0.122813 +v 0.407040 -0.370477 -0.123030 +v 0.407040 -0.368157 -0.111510 +v 0.416292 -0.369081 -0.111182 +v 0.397048 -0.371801 -0.122813 +v 0.397789 -0.369081 -0.111182 +v 0.407040 -0.365342 -0.099978 +v 0.416047 -0.366153 -0.099734 +v 0.398033 -0.366153 -0.099734 +v 0.424618 -0.375246 -0.121468 +v 0.389462 -0.375246 -0.121468 +v 0.390624 -0.371651 -0.109970 +v 0.390964 -0.368559 -0.098971 +v 0.423117 -0.368559 -0.098971 +v 0.423457 -0.371651 -0.109970 +v 0.400160 -0.418046 -0.106099 +v 0.400126 -0.421467 -0.100352 +v 0.407040 -0.420805 -0.099828 +v 0.407040 -0.417509 -0.105405 +v 0.400093 -0.424217 -0.094551 +v 0.407040 -0.423466 -0.094206 +v 0.413954 -0.421467 -0.100352 +v 0.413920 -0.418046 -0.106099 +v 0.413988 -0.424217 -0.094551 +v 0.394143 -0.415148 -0.113279 +v 0.394089 -0.419659 -0.108184 +v 0.400188 -0.414023 -0.110790 +v 0.394024 -0.423450 -0.101924 +v 0.393959 -0.426469 -0.095583 +v 0.420121 -0.426469 -0.095583 +v 0.420057 -0.423450 -0.101924 +v 0.419991 -0.419659 -0.108184 +v 0.413892 -0.414023 -0.110790 +v 0.419937 -0.415148 -0.113279 +v 0.407040 -0.413649 -0.109960 +v 0.416093 -0.366945 -0.065544 +v 0.407040 -0.366200 -0.065107 +v 0.407040 -0.370574 -0.059448 +v 0.416093 -0.371233 -0.060004 +v 0.397987 -0.366945 -0.065544 +v 0.397987 -0.371233 -0.060004 +v 0.416093 -0.371233 -0.060004 +v 0.407040 -0.370574 -0.059448 +v 0.407040 -0.376832 -0.054178 +v 0.416093 -0.377371 -0.054841 +v 0.397987 -0.377371 -0.054841 +v 0.407040 -0.376832 -0.054178 +v 0.423210 -0.369179 -0.066854 +v 0.390870 -0.369179 -0.066854 +v 0.390871 -0.373209 -0.061669 +v 0.390871 -0.378988 -0.056832 +v 0.397987 -0.377371 -0.054841 +v 0.390871 -0.378988 -0.056832 +v 0.423210 -0.378988 -0.056832 +v 0.423210 -0.373209 -0.061669 +v 0.423210 -0.373209 -0.061669 +v 0.424514 -0.398001 -0.120047 +v 0.424522 -0.404374 -0.121625 +v 0.428035 -0.404057 -0.127213 +v 0.427860 -0.396135 -0.125473 +v 0.424514 -0.410888 -0.120744 +v 0.427860 -0.412129 -0.126340 +v 0.431011 -0.403725 -0.133072 +v 0.430374 -0.393834 -0.131321 +v 0.430374 -0.413755 -0.132402 +v 0.419937 -0.394615 -0.112172 +v 0.419904 -0.399359 -0.115738 +v 0.424510 -0.392306 -0.116012 +v 0.419893 -0.404629 -0.117126 +v 0.419904 -0.410024 -0.116314 +v 0.419937 -0.415148 -0.113279 +v 0.424510 -0.417009 -0.117348 +v 0.427513 -0.419546 -0.122591 +v 0.428910 -0.422751 -0.128551 +v 0.434383 -0.403437 -0.138156 +v 0.428910 -0.385333 -0.126521 +v 0.427513 -0.389192 -0.120947 +v 0.389567 -0.410888 -0.120744 +v 0.389559 -0.404374 -0.121625 +v 0.386046 -0.404057 -0.127213 +v 0.386220 -0.412129 -0.126340 +v 0.389567 -0.398001 -0.120047 +v 0.386220 -0.396135 -0.125473 +v 0.383069 -0.403725 -0.133072 +v 0.383706 -0.413755 -0.132402 +v 0.383706 -0.393834 -0.131321 +v 0.394143 -0.415148 -0.113279 +v 0.394176 -0.410024 -0.116314 +v 0.389567 -0.410888 -0.120744 +v 0.389570 -0.417009 -0.117348 +v 0.394188 -0.404629 -0.117126 +v 0.389559 -0.404374 -0.121625 +v 0.394176 -0.399359 -0.115738 +v 0.389567 -0.398001 -0.120047 +v 0.394176 -0.399359 -0.115738 +v 0.394143 -0.394615 -0.112172 +v 0.389570 -0.392306 -0.116012 +v 0.386567 -0.389192 -0.120947 +v 0.385170 -0.385333 -0.126521 +v 0.379697 -0.403437 -0.138157 +v 0.385170 -0.422751 -0.128551 +v 0.386567 -0.419546 -0.122591 +v 0.389570 -0.417009 -0.117348 +v 0.389261 -0.434664 -0.082235 +v 0.389267 -0.434773 -0.084249 +v 0.386867 -0.439821 -0.083978 +v 0.386858 -0.439681 -0.081439 +v 0.389289 -0.434118 -0.086941 +v 0.386894 -0.439073 -0.087257 +v 0.387218 -0.444868 -0.083708 +v 0.387208 -0.444699 -0.080643 +v 0.387246 -0.444029 -0.087572 +v 0.389261 -0.434664 -0.082235 +v 0.389262 -0.433900 -0.080094 +v 0.389267 -0.434773 -0.084249 +v 0.389289 -0.434118 -0.086941 +v 0.389335 -0.432588 -0.091118 +v 0.389335 -0.432588 -0.091118 +v 0.386949 -0.437324 -0.092175 +v 0.387303 -0.442060 -0.093232 +v 0.390950 -0.445983 -0.094108 +v 0.390903 -0.448134 -0.087833 +v 0.390879 -0.449051 -0.083483 +v 0.390871 -0.448856 -0.079983 +v 0.387208 -0.443640 -0.077383 +v 0.390870 -0.447675 -0.076259 +v 0.386859 -0.438770 -0.078738 +v 0.389262 -0.433900 -0.080094 +v 0.389543 -0.387712 -0.109717 +v 0.389485 -0.384189 -0.102183 +v 0.387021 -0.379913 -0.104891 +v 0.386863 -0.383854 -0.113662 +v 0.389408 -0.381596 -0.094634 +v 0.387022 -0.377007 -0.096161 +v 0.387147 -0.375489 -0.107699 +v 0.386445 -0.379530 -0.117955 +v 0.387348 -0.372399 -0.097702 +v 0.394089 -0.390715 -0.106627 +v 0.394024 -0.387664 -0.100003 +v 0.393960 -0.385390 -0.093376 +v 0.393907 -0.383820 -0.087822 +v 0.389335 -0.379823 -0.088265 +v 0.386949 -0.374999 -0.088799 +v 0.387303 -0.370175 -0.089332 +v 0.387348 -0.372399 -0.097702 +v 0.387303 -0.370175 -0.089332 +v 0.387147 -0.375489 -0.107699 +v 0.386445 -0.379530 -0.117955 +v 0.389462 -0.375246 -0.121468 +v 0.424820 -0.378776 -0.079080 +v 0.424813 -0.378439 -0.081144 +v 0.427213 -0.373455 -0.080329 +v 0.427222 -0.373882 -0.077743 +v 0.424791 -0.378782 -0.083931 +v 0.427186 -0.373823 -0.083707 +v 0.426862 -0.368471 -0.079515 +v 0.426872 -0.368987 -0.076406 +v 0.426834 -0.368865 -0.083483 +v 0.424820 -0.378776 -0.079080 +v 0.424819 -0.379776 -0.076917 +v 0.424813 -0.378439 -0.081144 +v 0.424791 -0.378782 -0.083931 +v 0.424745 -0.379823 -0.088265 +v 0.424745 -0.379823 -0.088265 +v 0.427131 -0.374999 -0.088799 +v 0.426778 -0.370175 -0.089332 +v 0.423130 -0.366179 -0.089774 +v 0.423178 -0.364757 -0.083297 +v 0.423202 -0.364342 -0.078841 +v 0.423210 -0.364931 -0.075298 +v 0.426872 -0.370405 -0.073132 +v 0.423211 -0.366524 -0.071564 +v 0.427222 -0.375091 -0.075025 +v 0.424819 -0.379776 -0.076917 +v 0.424538 -0.422294 -0.111583 +v 0.424596 -0.426658 -0.104473 +v 0.427060 -0.430603 -0.107631 +v 0.427218 -0.425683 -0.115926 +v 0.424673 -0.430099 -0.097250 +v 0.427059 -0.434488 -0.099270 +v 0.426933 -0.434683 -0.110907 +v 0.427635 -0.429496 -0.120664 +v 0.426732 -0.438895 -0.101306 +v 0.419991 -0.419659 -0.108184 +v 0.420057 -0.423450 -0.101924 +v 0.420121 -0.426469 -0.095583 +v 0.420174 -0.428664 -0.090242 +v 0.424745 -0.432588 -0.091118 +v 0.427132 -0.437324 -0.092175 +v 0.426778 -0.442060 -0.093232 +v 0.426732 -0.438895 -0.101306 +v 0.426778 -0.442060 -0.093232 +v 0.423117 -0.442569 -0.102988 +v 0.423457 -0.438241 -0.113584 +v 0.424618 -0.433357 -0.124623 +v 0.424816 -0.387880 -0.067780 +v 0.424816 -0.384079 -0.070829 +v 0.427219 -0.380236 -0.067591 +v 0.427219 -0.384737 -0.063909 +v 0.424817 -0.381469 -0.074059 +v 0.427220 -0.377124 -0.071512 +v 0.426871 -0.376393 -0.064353 +v 0.426871 -0.381593 -0.060039 +v 0.426871 -0.372779 -0.068964 +v 0.424816 -0.387880 -0.067780 +v 0.424816 -0.393147 -0.065462 +v 0.420222 -0.390485 -0.070987 +v 0.420222 -0.387263 -0.073513 +v 0.424817 -0.381469 -0.074059 +v 0.424816 -0.384079 -0.070829 +v 0.423210 -0.369179 -0.066854 +v 0.423210 -0.373209 -0.061669 +v 0.423210 -0.378988 -0.056832 +v 0.426871 -0.388722 -0.056767 +v 0.423210 -0.386889 -0.053164 +v 0.427219 -0.390934 -0.061114 +v 0.424816 -0.393147 -0.065462 +v 0.389263 -0.381469 -0.074059 +v 0.389264 -0.384079 -0.070829 +v 0.386861 -0.380236 -0.067591 +v 0.386860 -0.377124 -0.071512 +v 0.389264 -0.387880 -0.067780 +v 0.386861 -0.384737 -0.063909 +v 0.387210 -0.376393 -0.064353 +v 0.387209 -0.372779 -0.068964 +v 0.387210 -0.381593 -0.060039 +v 0.393857 -0.383658 -0.078485 +v 0.393858 -0.385068 -0.076170 +v 0.389262 -0.379776 -0.076917 +v 0.393859 -0.387263 -0.073513 +v 0.393859 -0.390485 -0.070987 +v 0.393859 -0.394980 -0.069064 +v 0.389264 -0.393147 -0.065462 +v 0.386861 -0.390934 -0.061114 +v 0.387210 -0.388722 -0.056767 +v 0.390871 -0.386889 -0.053164 +v 0.390871 -0.378988 -0.056832 +v 0.390871 -0.373209 -0.061669 +v 0.387209 -0.372779 -0.068964 +v 0.387210 -0.376393 -0.064353 +v 0.387208 -0.370405 -0.073132 +v 0.386859 -0.375091 -0.075024 +v 0.387208 -0.370405 -0.073132 +v 0.389264 -0.399957 -0.064318 +v 0.389264 -0.407607 -0.064359 +v 0.386861 -0.407862 -0.059754 +v 0.386861 -0.398914 -0.059726 +v 0.389264 -0.415198 -0.065483 +v 0.386861 -0.416739 -0.061084 +v 0.387210 -0.408118 -0.055150 +v 0.387210 -0.397872 -0.055133 +v 0.387210 -0.418281 -0.056685 +v 0.389264 -0.399957 -0.064318 +v 0.389264 -0.393147 -0.065462 +v 0.389264 -0.407607 -0.064359 +v 0.389264 -0.415198 -0.065483 +v 0.389264 -0.421831 -0.067592 +v 0.389264 -0.421831 -0.067592 +v 0.386861 -0.424507 -0.063599 +v 0.387210 -0.427183 -0.059606 +v 0.390871 -0.429401 -0.056298 +v 0.390871 -0.419558 -0.053041 +v 0.390871 -0.408329 -0.051335 +v 0.387210 -0.397872 -0.055133 +v 0.387210 -0.408118 -0.055150 +v 0.387210 -0.388722 -0.056767 +v 0.424792 -0.434117 -0.086942 +v 0.424813 -0.434773 -0.084249 +v 0.427213 -0.439821 -0.083978 +v 0.427186 -0.439073 -0.087257 +v 0.424820 -0.434664 -0.082235 +v 0.427222 -0.439681 -0.081439 +v 0.426862 -0.444868 -0.083708 +v 0.426834 -0.444029 -0.087572 +v 0.426872 -0.444699 -0.080643 +v 0.420206 -0.430012 -0.086680 +v 0.420221 -0.430590 -0.084474 +v 0.420225 -0.430506 -0.082895 +v 0.420224 -0.429865 -0.081218 +v 0.424819 -0.433900 -0.080094 +v 0.427222 -0.438770 -0.078738 +v 0.426872 -0.443640 -0.077383 +v 0.423211 -0.447675 -0.076259 +v 0.423210 -0.448856 -0.079983 +v 0.423202 -0.449051 -0.083483 +v 0.426834 -0.444029 -0.087572 +v 0.426862 -0.444868 -0.083708 +v 0.389289 -0.378782 -0.083931 +v 0.389267 -0.378439 -0.081144 +v 0.386867 -0.373455 -0.080329 +v 0.386894 -0.373823 -0.083707 +v 0.389261 -0.378776 -0.079080 +v 0.386858 -0.373882 -0.077743 +v 0.387218 -0.368471 -0.079515 +v 0.387246 -0.368865 -0.083483 +v 0.387208 -0.368987 -0.076406 +v 0.393874 -0.382890 -0.084116 +v 0.393859 -0.382568 -0.081818 +v 0.393855 -0.382832 -0.080188 +v 0.387208 -0.368987 -0.076406 +v 0.387218 -0.368471 -0.079515 +v 0.387246 -0.368865 -0.083483 +v 0.389408 -0.430099 -0.097250 +v 0.389485 -0.426658 -0.104473 +v 0.387021 -0.430603 -0.107631 +v 0.387022 -0.434488 -0.099270 +v 0.389543 -0.422294 -0.111583 +v 0.386863 -0.425683 -0.115926 +v 0.387147 -0.434683 -0.110907 +v 0.387348 -0.438895 -0.101306 +v 0.386445 -0.429496 -0.120664 +v 0.389408 -0.430099 -0.097250 +v 0.389485 -0.426658 -0.104473 +v 0.389543 -0.422294 -0.111583 +v 0.389570 -0.417009 -0.117348 +v 0.389462 -0.433357 -0.124623 +v 0.390624 -0.438241 -0.113584 +v 0.390964 -0.442569 -0.102988 +v 0.424673 -0.381596 -0.094634 +v 0.424596 -0.384189 -0.102184 +v 0.427060 -0.379913 -0.104891 +v 0.427059 -0.377007 -0.096161 +v 0.424538 -0.387712 -0.109717 +v 0.427218 -0.383854 -0.113662 +v 0.426933 -0.375489 -0.107699 +v 0.426732 -0.372399 -0.097702 +v 0.427635 -0.379530 -0.117955 +v 0.420121 -0.385390 -0.093376 +v 0.424673 -0.381596 -0.094634 +v 0.420057 -0.387664 -0.100003 +v 0.424596 -0.384189 -0.102184 +v 0.419991 -0.390715 -0.106627 +v 0.424538 -0.387712 -0.109717 +v 0.419991 -0.390715 -0.106627 +v 0.424618 -0.375246 -0.121468 +v 0.423457 -0.371651 -0.109970 +v 0.423117 -0.368559 -0.098971 +v 0.424816 -0.415198 -0.065483 +v 0.424816 -0.407607 -0.064359 +v 0.427219 -0.407862 -0.059754 +v 0.427219 -0.416739 -0.061084 +v 0.424816 -0.399957 -0.064318 +v 0.427219 -0.398914 -0.059726 +v 0.426871 -0.408118 -0.055150 +v 0.426871 -0.418281 -0.056685 +v 0.426871 -0.397872 -0.055133 +v 0.424816 -0.415198 -0.065483 +v 0.424816 -0.421831 -0.067592 +v 0.424816 -0.407607 -0.064359 +v 0.424816 -0.399957 -0.064318 +v 0.423210 -0.397008 -0.051327 +v 0.423210 -0.408329 -0.051335 +v 0.423210 -0.419558 -0.053041 +v 0.426871 -0.427183 -0.059606 +v 0.423210 -0.429401 -0.056298 +v 0.427219 -0.424507 -0.063599 +v 0.424816 -0.421831 -0.067592 +v 0.389264 -0.426813 -0.070526 +v 0.389264 -0.430266 -0.073890 +v 0.386861 -0.434443 -0.071162 +v 0.386861 -0.430363 -0.067112 +v 0.389263 -0.432520 -0.077231 +v 0.386860 -0.437122 -0.075215 +v 0.387210 -0.438620 -0.068434 +v 0.387210 -0.433913 -0.063699 +v 0.387209 -0.441723 -0.073199 +v 0.389264 -0.426813 -0.070526 +v 0.389264 -0.430266 -0.073890 +v 0.389263 -0.432520 -0.077231 +v 0.389264 -0.430266 -0.073890 +v 0.390870 -0.445537 -0.071528 +v 0.390871 -0.442081 -0.066173 +v 0.390871 -0.436854 -0.060871 +v 0.424817 -0.432520 -0.077232 +v 0.424816 -0.430266 -0.073890 +v 0.427219 -0.434443 -0.071162 +v 0.427220 -0.437122 -0.075215 +v 0.424816 -0.426813 -0.070526 +v 0.427219 -0.430363 -0.067112 +v 0.426871 -0.438620 -0.068434 +v 0.426871 -0.441723 -0.073199 +v 0.426871 -0.433913 -0.063699 +v 0.420223 -0.428707 -0.078902 +v 0.420222 -0.426806 -0.076151 +v 0.420222 -0.423872 -0.073354 +v 0.424816 -0.426813 -0.070526 +v 0.423210 -0.436854 -0.060871 +v 0.423210 -0.442081 -0.066173 +v 0.423210 -0.445537 -0.071528 +v 0.400093 -0.387744 -0.092596 +v 0.400126 -0.389812 -0.098657 +v 0.407040 -0.390528 -0.098209 +v 0.407040 -0.388528 -0.092336 +v 0.400160 -0.392553 -0.104732 +v 0.407040 -0.393165 -0.104100 +v 0.413954 -0.389812 -0.098657 +v 0.413987 -0.387744 -0.092596 +v 0.413920 -0.392553 -0.104732 +v 0.393960 -0.385390 -0.093376 +v 0.394024 -0.387664 -0.100003 +v 0.394089 -0.390715 -0.106627 +v 0.394143 -0.394615 -0.112172 +v 0.400188 -0.396013 -0.109821 +v 0.407040 -0.396479 -0.109037 +v 0.413892 -0.396013 -0.109821 +v 0.419937 -0.394615 -0.112172 +v 0.400206 -0.400178 -0.113088 +v 0.400212 -0.404786 -0.114351 +v 0.407040 -0.404838 -0.113425 +v 0.407040 -0.400451 -0.112204 +v 0.400206 -0.409509 -0.113591 +v 0.407040 -0.409338 -0.112683 +v 0.413869 -0.404786 -0.114351 +v 0.413875 -0.400178 -0.113088 +v 0.413875 -0.409509 -0.113591 +v 0.394143 -0.394615 -0.112172 +v 0.400188 -0.396013 -0.109821 +v 0.400188 -0.414023 -0.110790 +v 0.407040 -0.413649 -0.109960 +v 0.413892 -0.414023 -0.110790 +v 0.419937 -0.415148 -0.113279 +v 0.419904 -0.410024 -0.116314 +v 0.419893 -0.404629 -0.117126 +v 0.419904 -0.399359 -0.115738 +v 0.413892 -0.396013 -0.109821 +v 0.419937 -0.394615 -0.112172 +v 0.407040 -0.396479 -0.109037 +vt 0.466072 0.046253 +vt 0.466606 0.046234 +vt 0.466612 0.042292 +vt 0.466078 0.042279 +vt 0.467077 0.046179 +vt 0.467083 0.042324 +vt 0.466698 0.038538 +vt 0.466164 0.038495 +vt 0.467167 0.038653 +vt 0.465588 0.049757 +vt 0.466153 0.049752 +vt 0.465506 0.046254 +vt 0.466687 0.049705 +vt 0.467156 0.049573 +vt 0.785733 0.396949 +vt 0.785998 0.397302 +vt 0.789279 0.395968 +vt 0.789165 0.395554 +vt 0.792963 0.395968 +vt 0.793020 0.395554 +vt 0.796438 0.397196 +vt 0.796654 0.396838 +vt 0.799088 0.399547 +vt 0.799426 0.399297 +vt 0.467320 0.035812 +vt 0.466855 0.035632 +vt 0.466322 0.035565 +vt 0.465599 0.038487 +vt 0.465757 0.035554 +vt 0.465512 0.042275 +vt 0.361399 0.091124 +vt 0.361933 0.091093 +vt 0.361894 0.087193 +vt 0.361360 0.087192 +vt 0.362403 0.091011 +vt 0.362365 0.087197 +vt 0.361933 0.083321 +vt 0.361399 0.083289 +vt 0.362403 0.083411 +vt 0.360950 0.094423 +vt 0.361516 0.094414 +vt 0.360833 0.091129 +vt 0.362049 0.094357 +vt 0.362516 0.094203 +vt 0.800420 0.402830 +vt 0.800819 0.402732 +vt 0.800420 0.406517 +vt 0.800819 0.406588 +vt 0.799193 0.409994 +vt 0.799536 0.410224 +vt 0.796844 0.412645 +vt 0.797078 0.412998 +vt 0.362516 0.080305 +vt 0.362049 0.080145 +vt 0.361516 0.080087 +vt 0.360833 0.083285 +vt 0.360950 0.080079 +vt 0.360794 0.087192 +vt 0.071626 0.120185 +vt 0.071103 0.120206 +vt 0.071051 0.124137 +vt 0.071574 0.124148 +vt 0.070661 0.120271 +vt 0.070610 0.124115 +vt 0.071103 0.127949 +vt 0.071626 0.127990 +vt 0.070661 0.127842 +vt 0.072345 0.116767 +vt 0.071781 0.116771 +vt 0.072190 0.120185 +vt 0.071256 0.116820 +vt 0.070811 0.116959 +vt 0.793562 0.413979 +vt 0.793646 0.414393 +vt 0.789878 0.413979 +vt 0.789792 0.414393 +vt 0.786404 0.412751 +vt 0.786158 0.413109 +vt 0.783754 0.410400 +vt 0.783386 0.410650 +vt 0.735494 0.224342 +vt 0.735957 0.224177 +vt 0.735894 0.221359 +vt 0.735429 0.221461 +vt 0.071256 0.130977 +vt 0.071781 0.131044 +vt 0.072190 0.128000 +vt 0.072345 0.131057 +vt 0.072138 0.124153 +vt 0.734878 0.217792 +vt 0.735411 0.217785 +vt 0.735434 0.213880 +vt 0.734902 0.213854 +vt 0.735876 0.217766 +vt 0.735899 0.213946 +vt 0.735494 0.210378 +vt 0.734962 0.210324 +vt 0.735957 0.210521 +vt 0.734331 0.221501 +vt 0.734897 0.221497 +vt 0.734312 0.217792 +vt 0.782421 0.407117 +vt 0.781992 0.407215 +vt 0.782421 0.403430 +vt 0.781992 0.403359 +vt 0.783648 0.399953 +vt 0.783276 0.399722 +vt 0.466855 0.052139 +vt 0.467320 0.051953 +vt 0.735582 0.207914 +vt 0.735051 0.207841 +vt 0.734396 0.210315 +vt 0.734485 0.207829 +vt 0.734336 0.213850 +vt 0.794726 0.407094 +vt 0.795245 0.405626 +vt 0.795127 0.405605 +vt 0.794625 0.407027 +vt 0.795245 0.404068 +vt 0.795127 0.404097 +vt 0.795001 0.405583 +vt 0.794517 0.406957 +vt 0.795002 0.404125 +vt 0.793835 0.408361 +vt 0.794872 0.407190 +vt 0.793734 0.408214 +vt 0.795414 0.405655 +vt 0.795414 0.404027 +vt 0.794825 0.402578 +vt 0.794682 0.402681 +vt 0.794582 0.402753 +vt 0.794476 0.402828 +vt 0.794315 0.402938 +vt 0.794811 0.404168 +vt 0.794810 0.405549 +vt 0.794351 0.406852 +vt 0.793589 0.408005 +vt 0.793474 0.407846 +vt 0.793664 0.408112 +vt 0.789851 0.398308 +vt 0.792579 0.398308 +vt 0.792726 0.397438 +vt 0.789643 0.397438 +vt 0.795150 0.399217 +vt 0.795633 0.398465 +vt 0.792861 0.396622 +vt 0.789444 0.396622 +vt 0.796083 0.397761 +vt 0.787914 0.399990 +vt 0.790046 0.399124 +vt 0.787422 0.399294 +vt 0.792439 0.399124 +vt 0.794696 0.399922 +vt 0.796417 0.401449 +vt 0.797112 0.400957 +vt 0.797851 0.400433 +vt 0.798540 0.399941 +vt 0.786401 0.397859 +vt 0.786897 0.398553 +vt 0.798098 0.403387 +vt 0.798098 0.406116 +vt 0.798966 0.406265 +vt 0.798966 0.403180 +vt 0.797190 0.408690 +vt 0.797939 0.409174 +vt 0.799776 0.406405 +vt 0.799776 0.402986 +vt 0.798638 0.409629 +vt 0.797282 0.403581 +vt 0.797282 0.405976 +vt 0.796485 0.408234 +vt 0.794959 0.409957 +vt 0.795451 0.410653 +vt 0.795973 0.411394 +vt 0.796459 0.412088 +vt 0.793022 0.411640 +vt 0.790295 0.411640 +vt 0.790144 0.412509 +vt 0.793227 0.412509 +vt 0.787723 0.410731 +vt 0.787237 0.411482 +vt 0.789999 0.413325 +vt 0.793416 0.413325 +vt 0.786777 0.412186 +vt 0.792828 0.410823 +vt 0.790435 0.410823 +vt 0.788178 0.410025 +vt 0.786457 0.408498 +vt 0.785761 0.408991 +vt 0.785019 0.409515 +vt 0.784320 0.410006 +vt 0.784775 0.406560 +vt 0.784775 0.403831 +vt 0.783904 0.403682 +vt 0.783904 0.406767 +vt 0.785683 0.401258 +vt 0.784931 0.400773 +vt 0.783084 0.403542 +vt 0.783084 0.406961 +vt 0.784222 0.400318 +vt 0.785591 0.406366 +vt 0.785591 0.403971 +vt 0.786388 0.401713 +vt 0.790428 0.400724 +vt 0.792166 0.400724 +vt 0.792233 0.400330 +vt 0.790333 0.400330 +vt 0.793806 0.401304 +vt 0.794024 0.400963 +vt 0.792323 0.399801 +vt 0.790207 0.399801 +vt 0.794319 0.400506 +vt 0.789046 0.401586 +vt 0.790495 0.400998 +vt 0.788879 0.401353 +vt 0.792121 0.400998 +vt 0.793655 0.401540 +vt 0.795056 0.402413 +vt 0.795391 0.402175 +vt 0.795841 0.401856 +vt 0.788322 0.400566 +vt 0.788641 0.401017 +vt 0.795685 0.403962 +vt 0.795685 0.405702 +vt 0.796078 0.405770 +vt 0.796078 0.403868 +vt 0.795106 0.407342 +vt 0.795445 0.407562 +vt 0.796607 0.405860 +vt 0.796607 0.403742 +vt 0.795902 0.407857 +vt 0.793997 0.408594 +vt 0.794234 0.408930 +vt 0.794552 0.409381 +vt 0.792449 0.409223 +vt 0.790710 0.409223 +vt 0.790642 0.409617 +vt 0.792542 0.409617 +vt 0.789071 0.408643 +vt 0.788850 0.408984 +vt 0.790551 0.410147 +vt 0.792667 0.410147 +vt 0.788555 0.409441 +vt 0.792386 0.408950 +vt 0.790759 0.408950 +vt 0.789225 0.408407 +vt 0.788055 0.407369 +vt 0.787820 0.407534 +vt 0.787483 0.407772 +vt 0.787033 0.408091 +vt 0.787192 0.405985 +vt 0.787192 0.404245 +vt 0.786796 0.404177 +vt 0.786796 0.406079 +vt 0.787771 0.402605 +vt 0.787429 0.402385 +vt 0.786267 0.404087 +vt 0.786267 0.406205 +vt 0.786972 0.402090 +vt 0.787467 0.405920 +vt 0.787467 0.404292 +vt 0.788009 0.402757 +vt 0.517328 0.775125 +vt 0.517325 0.775023 +vt 0.516816 0.775033 +vt 0.516818 0.775128 +vt 0.517325 0.774880 +vt 0.516816 0.774897 +vt 0.516294 0.775046 +vt 0.516297 0.775148 +vt 0.516296 0.774903 +vt 0.517774 0.775274 +vt 0.517767 0.775142 +vt 0.517334 0.775236 +vt 0.517763 0.775020 +vt 0.517763 0.774854 +vt 0.517764 0.774591 +vt 0.517327 0.774645 +vt 0.516820 0.774671 +vt 0.516300 0.774668 +vt 0.515830 0.774634 +vt 0.515824 0.774897 +vt 0.515822 0.775062 +vt 0.515825 0.775184 +vt 0.516303 0.775259 +vt 0.515832 0.775317 +vt 0.516824 0.775231 +vt 0.789324 0.408259 +vt 0.790792 0.408777 +vt 0.790816 0.408657 +vt 0.789396 0.408155 +vt 0.792348 0.408777 +vt 0.792322 0.408657 +vt 0.790841 0.408533 +vt 0.789471 0.408048 +vt 0.792295 0.408532 +vt 0.788205 0.407266 +vt 0.792250 0.408346 +vt 0.790876 0.408348 +vt 0.789581 0.407889 +vt 0.788425 0.407119 +vt 0.788593 0.407009 +vt 0.788312 0.407194 +vt 0.793562 0.401688 +vt 0.792095 0.401170 +vt 0.792078 0.401290 +vt 0.793499 0.401792 +vt 0.790539 0.401170 +vt 0.790572 0.401290 +vt 0.792061 0.401414 +vt 0.793431 0.401899 +vt 0.790607 0.401415 +vt 0.789153 0.401733 +vt 0.789230 0.401835 +vt 0.789312 0.401942 +vt 0.789434 0.402101 +vt 0.790658 0.401601 +vt 0.792032 0.401600 +vt 0.793327 0.402059 +vt 0.788161 0.402853 +vt 0.787642 0.404322 +vt 0.787768 0.404342 +vt 0.788270 0.402920 +vt 0.787642 0.405879 +vt 0.787768 0.405851 +vt 0.787901 0.404365 +vt 0.788385 0.402991 +vt 0.787900 0.405822 +vt 0.788097 0.405779 +vt 0.788098 0.404398 +vt 0.788557 0.403095 +vt 0.790930 0.402476 +vt 0.791900 0.402467 +vt 0.791937 0.402197 +vt 0.790828 0.402201 +vt 0.792811 0.402798 +vt 0.792981 0.402571 +vt 0.791987 0.401880 +vt 0.790734 0.401882 +vt 0.793167 0.402299 +vt 0.743631 0.558753 +vt 0.744405 0.558696 +vt 0.744296 0.558248 +vt 0.743445 0.558262 +vt 0.745253 0.558681 +vt 0.745265 0.558236 +vt 0.746061 0.558686 +vt 0.746187 0.558236 +vt 0.746690 0.558734 +vt 0.746890 0.558241 +vt 0.793495 0.403446 +vt 0.793772 0.403291 +vt 0.794066 0.403105 +vt 0.789618 0.402342 +vt 0.789841 0.402617 +vt 0.790068 0.402858 +vt 0.793809 0.404356 +vt 0.793784 0.405372 +vt 0.794152 0.405436 +vt 0.794161 0.404300 +vt 0.793469 0.406337 +vt 0.793783 0.406509 +vt 0.794513 0.405498 +vt 0.794516 0.404232 +vt 0.794094 0.406693 +vt 0.585800 0.779075 +vt 0.586669 0.778805 +vt 0.586560 0.778497 +vt 0.585705 0.778577 +vt 0.793518 0.404421 +vt 0.793468 0.405316 +vt 0.793218 0.406177 +vt 0.588450 0.778805 +vt 0.589305 0.779075 +vt 0.589404 0.778577 +vt 0.588570 0.778497 +vt 0.792870 0.407091 +vt 0.793080 0.407331 +vt 0.793295 0.407605 +vt 0.792010 0.407473 +vt 0.791041 0.407482 +vt 0.790985 0.407751 +vt 0.792094 0.407747 +vt 0.790129 0.407151 +vt 0.789941 0.407377 +vt 0.790926 0.408068 +vt 0.792179 0.408065 +vt 0.789746 0.407648 +vt 0.747150 0.559153 +vt 0.747902 0.559155 +vt 0.747786 0.558723 +vt 0.746957 0.558679 +vt 0.748748 0.559145 +vt 0.748753 0.558719 +vt 0.749568 0.559116 +vt 0.749688 0.558679 +vt 0.614669 0.779078 +vt 0.615375 0.779077 +vt 0.615339 0.778585 +vt 0.614604 0.778632 +vt 0.789444 0.406503 +vt 0.789149 0.406657 +vt 0.788847 0.406842 +vt 0.789125 0.405592 +vt 0.789147 0.404576 +vt 0.788767 0.404512 +vt 0.788759 0.405648 +vt 0.789464 0.403611 +vt 0.789137 0.403438 +vt 0.788399 0.404449 +vt 0.788397 0.405716 +vt 0.788818 0.403254 +vt 0.616309 0.778818 +vt 0.616285 0.778517 +vt 0.789440 0.405529 +vt 0.789485 0.404633 +vt 0.789740 0.403773 +vt 0.618006 0.778818 +vt 0.618717 0.779077 +vt 0.618865 0.778585 +vt 0.618201 0.778517 +vt 0.511787 0.773266 +vt 0.511794 0.773066 +vt 0.511278 0.773117 +vt 0.511272 0.773309 +vt 0.517359 0.775580 +vt 0.517344 0.775393 +vt 0.516833 0.775379 +vt 0.516847 0.775557 +vt 0.510759 0.773066 +vt 0.510753 0.773266 +vt 0.516313 0.775416 +vt 0.516328 0.775603 +vt 0.512233 0.773458 +vt 0.512239 0.773136 +vt 0.511782 0.773553 +vt 0.512247 0.772911 +vt 0.517802 0.775673 +vt 0.517785 0.775458 +vt 0.515843 0.775500 +vt 0.515860 0.775716 +vt 0.510298 0.772911 +vt 0.510291 0.773136 +vt 0.510747 0.773553 +vt 0.510285 0.773458 +vt 0.511267 0.773585 +vt 0.749552 0.562788 +vt 0.748892 0.562808 +vt 0.748903 0.563165 +vt 0.749563 0.563138 +vt 0.748221 0.562819 +vt 0.748231 0.563169 +vt 0.748905 0.563446 +vt 0.749566 0.563413 +vt 0.748232 0.563444 +vt 0.750035 0.562283 +vt 0.749529 0.562279 +vt 0.750058 0.562764 +vt 0.748871 0.562289 +vt 0.748202 0.562310 +vt 0.747665 0.562338 +vt 0.747681 0.562819 +vt 0.747689 0.563146 +vt 0.747690 0.563401 +vt 0.747685 0.563663 +vt 0.748227 0.563726 +vt 0.748900 0.563735 +vt 0.749560 0.563695 +vt 0.750072 0.563346 +vt 0.750067 0.563608 +vt 0.750070 0.563091 +vt 0.746087 0.562222 +vt 0.745435 0.562221 +vt 0.745447 0.562575 +vt 0.746101 0.562568 +vt 0.744764 0.562230 +vt 0.744776 0.562576 +vt 0.745447 0.562867 +vt 0.746101 0.562853 +vt 0.744775 0.562861 +vt 0.746552 0.561769 +vt 0.746059 0.561730 +vt 0.746581 0.562232 +vt 0.745408 0.561720 +vt 0.744740 0.561738 +vt 0.744196 0.561783 +vt 0.744218 0.562246 +vt 0.744228 0.562570 +vt 0.744227 0.562836 +vt 0.744216 0.563123 +vt 0.744764 0.563171 +vt 0.745436 0.563184 +vt 0.746090 0.563163 +vt 0.746595 0.562821 +vt 0.746585 0.563109 +vt 0.746594 0.562556 +vt 0.303914 0.248482 +vt 0.303918 0.247597 +vt 0.303246 0.247594 +vt 0.303243 0.248495 +vt 0.303926 0.246711 +vt 0.303255 0.246691 +vt 0.302580 0.247589 +vt 0.302576 0.248474 +vt 0.302588 0.246703 +vt 0.304451 0.249174 +vt 0.304448 0.248435 +vt 0.303918 0.249265 +vt 0.304451 0.247599 +vt 0.304459 0.246763 +vt 0.304472 0.246022 +vt 0.303940 0.245926 +vt 0.303269 0.245892 +vt 0.302602 0.245918 +vt 0.302082 0.246007 +vt 0.302069 0.246748 +vt 0.302061 0.247585 +vt 0.302058 0.248421 +vt 0.302580 0.249256 +vt 0.302061 0.249159 +vt 0.303246 0.249292 +vt 0.749549 0.564045 +vt 0.748888 0.564093 +vt 0.748867 0.564486 +vt 0.749529 0.564429 +vt 0.748216 0.564076 +vt 0.748195 0.564460 +vt 0.303976 0.244886 +vt 0.303306 0.244831 +vt 0.303286 0.245275 +vt 0.303957 0.245321 +vt 0.302638 0.244878 +vt 0.302619 0.245313 +vt 0.750056 0.563934 +vt 0.747675 0.563990 +vt 0.747655 0.564349 +vt 0.302116 0.245027 +vt 0.302098 0.245437 +vt 0.304488 0.245451 +vt 0.304506 0.245041 +vt 0.750037 0.564294 +vt 0.511779 0.774808 +vt 0.511778 0.774371 +vt 0.511263 0.774372 +vt 0.511264 0.774793 +vt 0.511779 0.773935 +vt 0.511264 0.773953 +vt 0.510743 0.774371 +vt 0.510745 0.774808 +vt 0.510744 0.773935 +vt 0.512234 0.775284 +vt 0.512230 0.774855 +vt 0.511782 0.775193 +vt 0.512229 0.774369 +vt 0.512230 0.773884 +vt 0.510281 0.773884 +vt 0.510280 0.774369 +vt 0.510281 0.774855 +vt 0.510748 0.775193 +vt 0.510285 0.775284 +vt 0.511267 0.775163 +vt 0.568300 0.775651 +vt 0.568324 0.775811 +vt 0.568842 0.775760 +vt 0.568820 0.775608 +vt 0.511793 0.775691 +vt 0.511787 0.775486 +vt 0.511272 0.775444 +vt 0.511278 0.775640 +vt 0.569349 0.775791 +vt 0.569325 0.775631 +vt 0.510753 0.775486 +vt 0.510759 0.775691 +vt 0.567808 0.775596 +vt 0.567826 0.775756 +vt 0.568285 0.775514 +vt 0.567853 0.775942 +vt 0.512246 0.775842 +vt 0.512239 0.775611 +vt 0.510291 0.775611 +vt 0.510298 0.775842 +vt 0.569783 0.775904 +vt 0.569757 0.775719 +vt 0.569310 0.775494 +vt 0.569739 0.775559 +vt 0.568805 0.775480 +vt 0.568272 0.775177 +vt 0.568271 0.775322 +vt 0.568792 0.775301 +vt 0.568793 0.775164 +vt 0.568275 0.775417 +vt 0.568796 0.775390 +vt 0.569296 0.775302 +vt 0.569296 0.775157 +vt 0.569300 0.775397 +vt 0.567800 0.774923 +vt 0.567794 0.775197 +vt 0.568278 0.774933 +vt 0.567793 0.775364 +vt 0.567797 0.775479 +vt 0.569728 0.775441 +vt 0.569723 0.775326 +vt 0.569722 0.775159 +vt 0.569299 0.774913 +vt 0.569724 0.774886 +vt 0.568797 0.774929 +vt 0.749495 0.559842 +vt 0.748767 0.559845 +vt 0.748801 0.560700 +vt 0.749477 0.560707 +vt 0.748023 0.559876 +vt 0.748114 0.560739 +vt 0.748839 0.561557 +vt 0.749497 0.561559 +vt 0.748170 0.561590 +vt 0.750227 0.559081 +vt 0.750033 0.559923 +vt 0.747444 0.559983 +vt 0.747572 0.560837 +vt 0.747635 0.561655 +vt 0.750003 0.561600 +vt 0.749990 0.560781 +vt 0.745993 0.559393 +vt 0.745275 0.559370 +vt 0.745318 0.560196 +vt 0.745986 0.560224 +vt 0.744530 0.559402 +vt 0.744631 0.560232 +vt 0.745366 0.561019 +vt 0.746017 0.561040 +vt 0.744698 0.561048 +vt 0.746516 0.559518 +vt 0.743941 0.559534 +vt 0.744082 0.560347 +vt 0.744157 0.561128 +vt 0.746512 0.561114 +vt 0.746487 0.560332 +vt 0.568325 0.773658 +vt 0.568302 0.774109 +vt 0.568817 0.774132 +vt 0.568836 0.773694 +vt 0.568287 0.774559 +vt 0.568805 0.774568 +vt 0.569315 0.774090 +vt 0.569332 0.773638 +vt 0.569305 0.774539 +vt 0.567895 0.773114 +vt 0.567858 0.773527 +vt 0.568355 0.773278 +vt 0.567831 0.774020 +vt 0.567813 0.774512 +vt 0.569728 0.774474 +vt 0.569737 0.773983 +vt 0.569755 0.773490 +vt 0.569359 0.773259 +vt 0.569783 0.773077 +vt 0.568863 0.773326 +vt 0.746069 0.563558 +vt 0.745415 0.563588 +vt 0.745379 0.564041 +vt 0.746034 0.564002 +vt 0.744743 0.563566 +vt 0.744708 0.564010 +vt 0.302604 0.250287 +vt 0.303271 0.250342 +vt 0.303257 0.249904 +vt 0.302590 0.249857 +vt 0.744653 0.564441 +vt 0.745323 0.564481 +vt 0.746565 0.563478 +vt 0.744197 0.563492 +vt 0.744164 0.563908 +vt 0.744112 0.564312 +vt 0.303928 0.249865 +vt 0.304460 0.249740 +vt 0.302070 0.249726 +vt 0.302084 0.250130 +vt 0.746532 0.563893 +vt 0.587073 0.780093 +vt 0.587550 0.780002 +vt 0.587554 0.779574 +vt 0.586962 0.779671 +vt 0.588027 0.780093 +vt 0.588146 0.779671 +vt 0.587557 0.779128 +vt 0.586819 0.779220 +vt 0.588294 0.779220 +vt 0.586785 0.780679 +vt 0.587149 0.780435 +vt 0.586637 0.780367 +vt 0.587543 0.780354 +vt 0.587939 0.780436 +vt 0.588305 0.780680 +vt 0.588466 0.780368 +vt 0.588679 0.779979 +vt 0.588941 0.779546 +vt 0.587561 0.778737 +vt 0.586170 0.779546 +vt 0.586431 0.779978 +vt 0.616522 0.780089 +vt 0.616976 0.779998 +vt 0.617052 0.779577 +vt 0.616484 0.779674 +vt 0.617431 0.780089 +vt 0.617613 0.779674 +vt 0.617116 0.779136 +vt 0.616399 0.779227 +vt 0.617805 0.779227 +vt 0.565939 0.774748 +vt 0.565574 0.774756 +vt 0.565658 0.775110 +vt 0.566094 0.775099 +vt 0.565179 0.774759 +vt 0.565181 0.775115 +vt 0.564784 0.774756 +vt 0.564703 0.775110 +vt 0.617252 0.780423 +vt 0.617603 0.780667 +vt 0.617850 0.780364 +vt 0.618114 0.779981 +vt 0.618392 0.779551 +vt 0.617189 0.778752 +vt 0.615751 0.779551 +vt 0.615972 0.779981 +vt 0.616106 0.780365 +vt 0.615029 0.783026 +vt 0.615012 0.782878 +vt 0.614712 0.782913 +vt 0.614734 0.783100 +vt 0.615046 0.782677 +vt 0.614749 0.782668 +vt 0.614350 0.782954 +vt 0.614376 0.783179 +vt 0.614392 0.782665 +vt 0.567420 0.775570 +vt 0.567434 0.775721 +vt 0.567414 0.775423 +vt 0.567416 0.775220 +vt 0.567423 0.774900 +vt 0.615134 0.782362 +vt 0.614849 0.782298 +vt 0.614503 0.782240 +vt 0.614142 0.782199 +vt 0.614020 0.782671 +vt 0.613975 0.782995 +vt 0.614005 0.783253 +vt 0.614466 0.783416 +vt 0.614105 0.783523 +vt 0.614810 0.783295 +vt 0.615093 0.783181 +vt 0.618202 0.780810 +vt 0.618485 0.781352 +vt 0.618829 0.781130 +vt 0.618516 0.780498 +vt 0.618703 0.781899 +vt 0.619073 0.781762 +vt 0.619125 0.780905 +vt 0.618810 0.780163 +vt 0.619383 0.781631 +vt 0.617903 0.781061 +vt 0.618149 0.781537 +vt 0.618340 0.782017 +vt 0.618477 0.782420 +vt 0.618858 0.782361 +vt 0.619249 0.782297 +vt 0.619578 0.782239 +vt 0.743855 0.561256 +vt 0.743888 0.561851 +vt 0.743792 0.560548 +vt 0.743682 0.559830 +vt 0.619028 0.779893 +vt 0.585493 0.783034 +vt 0.585477 0.782881 +vt 0.585109 0.782910 +vt 0.585131 0.783103 +vt 0.585513 0.782677 +vt 0.585150 0.782663 +vt 0.584737 0.782952 +vt 0.584763 0.783183 +vt 0.584782 0.782661 +vt 0.515460 0.775235 +vt 0.515468 0.775403 +vt 0.515456 0.775080 +vt 0.515458 0.774879 +vt 0.515465 0.774571 +vt 0.585607 0.782362 +vt 0.585256 0.782293 +vt 0.584902 0.782236 +vt 0.584602 0.782203 +vt 0.584472 0.782674 +vt 0.584424 0.783001 +vt 0.584454 0.783264 +vt 0.584855 0.783430 +vt 0.584557 0.783546 +vt 0.585209 0.783308 +vt 0.585559 0.783198 +vt 0.588834 0.780814 +vt 0.589128 0.781355 +vt 0.589436 0.781127 +vt 0.589105 0.780496 +vt 0.589354 0.781901 +vt 0.589690 0.781759 +vt 0.589750 0.780903 +vt 0.589406 0.780160 +vt 0.590023 0.781628 +vt 0.588619 0.781073 +vt 0.588874 0.781550 +vt 0.589072 0.782029 +vt 0.589213 0.782431 +vt 0.589514 0.782363 +vt 0.589872 0.782293 +vt 0.590225 0.782236 +vt 0.747345 0.561749 +vt 0.747370 0.562371 +vt 0.590295 0.781535 +vt 0.590017 0.780735 +vt 0.589702 0.779896 +vt 0.586121 0.783904 +vt 0.585853 0.783664 +vt 0.585560 0.783877 +vt 0.585878 0.784166 +vt 0.585672 0.783415 +vt 0.585346 0.783575 +vt 0.585263 0.784101 +vt 0.585630 0.784440 +vt 0.585014 0.783747 +vt 0.509943 0.772927 +vt 0.509936 0.773304 +vt 0.586319 0.783697 +vt 0.586091 0.783498 +vt 0.515482 0.775628 +vt 0.515502 0.775890 +vt 0.584734 0.783904 +vt 0.585011 0.784302 +vt 0.585419 0.784682 +vt 0.586144 0.784710 +vt 0.585988 0.784984 +vt 0.586325 0.784397 +vt 0.586501 0.784096 +vt 0.618808 0.783416 +vt 0.618639 0.783665 +vt 0.618978 0.783883 +vt 0.619179 0.783582 +vt 0.618385 0.783906 +vt 0.618678 0.784173 +vt 0.619255 0.784108 +vt 0.619488 0.783753 +vt 0.618909 0.784447 +vt 0.618531 0.783109 +vt 0.618443 0.783285 +vt 0.618914 0.783199 +vt 0.618300 0.783490 +vt 0.618085 0.783689 +vt 0.617777 0.783849 +vt 0.618025 0.784098 +vt 0.618254 0.784404 +vt 0.618422 0.784717 +vt 0.618485 0.784984 +vt 0.619024 0.784681 +vt 0.619409 0.784301 +vt 0.743888 0.563370 +vt 0.743859 0.563739 +vt 0.743906 0.563043 +vt 0.619306 0.783314 +vt 0.619637 0.783436 +vt 0.617551 0.784209 +vt 0.617013 0.784237 +vt 0.617070 0.784573 +vt 0.617699 0.784539 +vt 0.616474 0.784185 +vt 0.616439 0.784510 +vt 0.617065 0.784914 +vt 0.617785 0.784874 +vt 0.616343 0.784842 +vt 0.512559 0.773800 +vt 0.512564 0.773304 +vt 0.512558 0.774364 +vt 0.512560 0.774930 +vt 0.512564 0.775431 +vt 0.615998 0.784056 +vt 0.615881 0.784356 +vt 0.615703 0.784662 +vt 0.615480 0.784923 +vt 0.616187 0.785124 +vt 0.616985 0.785205 +vt 0.304730 0.248356 +vt 0.304733 0.247599 +vt 0.304733 0.249024 +vt 0.589611 0.782676 +vt 0.589649 0.782877 +vt 0.590024 0.782907 +vt 0.589982 0.782663 +vt 0.589633 0.783025 +vt 0.590004 0.783094 +vt 0.590395 0.782949 +vt 0.590348 0.782661 +vt 0.590371 0.783174 +vt 0.589299 0.782699 +vt 0.589333 0.782864 +vt 0.589321 0.782980 +vt 0.589267 0.783101 +vt 0.589568 0.783180 +vt 0.589926 0.783289 +vt 0.590280 0.783410 +vt 0.590568 0.783525 +vt 0.590669 0.783255 +vt 0.590697 0.782998 +vt 0.747384 0.562805 +vt 0.747391 0.563096 +vt 0.618952 0.782677 +vt 0.618989 0.782881 +vt 0.619397 0.782916 +vt 0.619356 0.782668 +vt 0.618975 0.783035 +vt 0.619379 0.783109 +vt 0.619744 0.782957 +vt 0.619698 0.782666 +vt 0.619722 0.783188 +vt 0.618560 0.782690 +vt 0.618593 0.782858 +vt 0.618582 0.782980 +vt 0.743915 0.562791 +vt 0.743916 0.562558 +vt 0.743907 0.562270 +vt 0.615280 0.781900 +vt 0.615487 0.781353 +vt 0.615251 0.781131 +vt 0.615015 0.781763 +vt 0.615761 0.780811 +vt 0.615563 0.780498 +vt 0.614946 0.780905 +vt 0.614689 0.781631 +vt 0.615283 0.780163 +vt 0.567438 0.774428 +vt 0.567460 0.773867 +vt 0.567490 0.773307 +vt 0.567530 0.772838 +vt 0.614926 0.779893 +vt 0.614606 0.780730 +vt 0.614342 0.781530 +vt 0.585762 0.781900 +vt 0.585983 0.781354 +vt 0.585682 0.781126 +vt 0.585433 0.781758 +vt 0.586273 0.780813 +vt 0.586008 0.780495 +vt 0.585366 0.780902 +vt 0.585099 0.781628 +vt 0.585706 0.780159 +vt 0.515840 0.774242 +vt 0.515478 0.774121 +vt 0.515855 0.773778 +vt 0.515496 0.773592 +vt 0.515876 0.773321 +vt 0.515518 0.773073 +vt 0.586475 0.781072 +vt 0.585398 0.779896 +vt 0.585086 0.780734 +vt 0.584814 0.781534 +vt 0.588130 0.784182 +vt 0.587565 0.784235 +vt 0.587569 0.784565 +vt 0.588230 0.784502 +vt 0.587000 0.784207 +vt 0.586909 0.784531 +vt 0.587570 0.784907 +vt 0.588326 0.784834 +vt 0.586813 0.784867 +vt 0.509932 0.774930 +vt 0.509936 0.775431 +vt 0.509930 0.774364 +vt 0.509931 0.773800 +vt 0.586728 0.785160 +vt 0.587564 0.785205 +vt 0.588400 0.785124 +vt 0.588995 0.784655 +vt 0.589140 0.784923 +vt 0.588814 0.784348 +vt 0.588628 0.784053 +vt 0.615634 0.783859 +vt 0.615376 0.783624 +vt 0.615148 0.783837 +vt 0.615454 0.784120 +vt 0.615203 0.783387 +vt 0.614942 0.783549 +vt 0.614859 0.784056 +vt 0.615211 0.784387 +vt 0.614619 0.783717 +vt 0.512571 0.775813 +vt 0.512579 0.776085 +vt 0.567456 0.775919 +vt 0.567487 0.776144 +vt 0.614276 0.783864 +vt 0.614544 0.784245 +vt 0.614935 0.784615 +vt 0.589455 0.783386 +vt 0.589275 0.783623 +vt 0.589577 0.783830 +vt 0.589791 0.783542 +vt 0.589007 0.783857 +vt 0.589260 0.784113 +vt 0.589874 0.784050 +vt 0.590122 0.783711 +vt 0.589508 0.784380 +vt 0.589172 0.783267 +vt 0.589021 0.783462 +vt 0.588794 0.783657 +vt 0.509943 0.775813 +vt 0.589708 0.784616 +vt 0.590115 0.784246 +vt 0.590391 0.783865 +vt 0.517331 0.774289 +vt 0.517339 0.773864 +vt 0.516835 0.773915 +vt 0.516825 0.774327 +vt 0.517350 0.773445 +vt 0.516848 0.773508 +vt 0.516320 0.773887 +vt 0.516308 0.774311 +vt 0.516337 0.773467 +vt 0.517767 0.774199 +vt 0.517772 0.773735 +vt 0.517783 0.773279 +vt 0.517802 0.772910 +vt 0.517368 0.773105 +vt 0.516867 0.773178 +vt 0.516358 0.773127 +vt 0.515902 0.772951 +vt 0.564833 0.774302 +vt 0.565179 0.774305 +vt 0.565178 0.773798 +vt 0.564849 0.773795 +vt 0.565524 0.774302 +vt 0.565507 0.773795 +vt 0.565179 0.773296 +vt 0.564833 0.773293 +vt 0.565524 0.773293 +vt 0.564418 0.774748 +vt 0.564510 0.774294 +vt 0.565844 0.774294 +vt 0.565813 0.773786 +vt 0.565845 0.773282 +vt 0.565939 0.772843 +vt 0.565575 0.772855 +vt 0.565180 0.772860 +vt 0.564785 0.772855 +vt 0.564511 0.773282 +vt 0.564418 0.772843 +vt 0.564541 0.773786 +vn -0.3537 0.9255 0.1351 +vn -0.3401 0.8781 0.3365 +vn 0.0000 0.9414 0.3374 +vn -0.0000 0.9905 0.1378 +vn -0.2830 0.7125 0.6421 +vn -0.0000 0.7665 0.6423 +vn 0.3401 0.8781 0.3365 +vn 0.3538 0.9255 0.1351 +vn 0.2830 0.7125 0.6421 +vn -0.7070 0.7048 0.0590 +vn -0.7045 0.6988 0.1240 +vn -0.3548 0.9323 0.0710 +vn -0.6764 0.6596 0.3276 +vn -0.5627 0.5290 0.6353 +vn -0.5627 0.5290 0.6352 +vn -0.3518 0.3042 0.8853 +vn -0.1764 0.4200 0.8902 +vn 0.0000 0.4544 0.8908 +vn -0.0000 0.7664 0.6423 +vn 0.1764 0.4200 0.8902 +vn 0.3518 0.3042 0.8853 +vn 0.5627 0.5290 0.6352 +vn 0.5627 0.5290 0.6353 +vn 0.6764 0.6596 0.3276 +vn 0.7045 0.6988 0.1240 +vn 0.3548 0.9323 0.0710 +vn 0.7070 0.7048 0.0590 +vn -0.0000 0.9972 0.0743 +vn 0.9315 0.3486 0.1038 +vn 0.8951 0.3240 0.3064 +vn 0.9583 -0.0155 0.2854 +vn 0.9965 -0.0045 0.0837 +vn 0.7463 0.2499 0.6170 +vn 0.8001 -0.0325 0.5989 +vn 0.8951 -0.3553 0.2695 +vn 0.9315 -0.3578 0.0654 +vn 0.7463 -0.3153 0.5863 +vn 0.7069 0.7048 0.0590 +vn 0.9347 0.3531 0.0395 +vn 0.4677 0.1291 0.8744 +vn 0.5021 -0.0469 0.8635 +vn 0.8002 -0.0326 0.5989 +vn 0.4677 -0.2231 0.8553 +vn 0.7462 -0.3153 0.5863 +vn 0.3518 -0.3984 0.8471 +vn 0.5627 -0.5948 0.5741 +vn 0.5627 -0.5947 0.5742 +vn 0.6764 -0.6913 0.2543 +vn 0.7045 -0.7081 0.0475 +vn 0.9347 -0.3553 0.0010 +vn 0.7070 -0.7070 -0.0178 +vn 0.9998 -0.0011 0.0201 +vn 0.3538 -0.9347 0.0340 +vn 0.3401 -0.9094 0.2393 +vn 0.0000 -0.9724 0.2334 +vn 0.0000 -0.9996 0.0296 +vn 0.2830 -0.7779 0.5611 +vn 0.0000 -0.8315 0.5555 +vn -0.3401 -0.9094 0.2393 +vn -0.3537 -0.9347 0.0340 +vn -0.2830 -0.7778 0.5611 +vn 0.7045 -0.7081 0.0476 +vn 0.3548 -0.9345 -0.0305 +vn 0.6764 -0.6912 0.2543 +vn 0.1764 -0.5140 0.8395 +vn 0.2830 -0.7778 0.5611 +vn -0.0000 -0.5483 0.8363 +vn -0.1764 -0.5140 0.8395 +vn -0.3518 -0.3984 0.8471 +vn -0.5627 -0.5947 0.5741 +vn -0.2830 -0.7779 0.5611 +vn -0.5627 -0.5947 0.5742 +vn -0.6764 -0.6912 0.2542 +vn -0.7045 -0.7081 0.0475 +vn -0.3548 -0.9345 -0.0305 +vn -0.7070 -0.7070 -0.0178 +vn 0.0000 -0.9994 -0.0343 +vn -0.9315 -0.3578 0.0654 +vn -0.8951 -0.3553 0.2695 +vn -0.9583 -0.0155 0.2854 +vn -0.9965 -0.0046 0.0837 +vn -0.7462 -0.3153 0.5863 +vn -0.8001 -0.0326 0.5989 +vn -0.8951 0.3239 0.3063 +vn -0.9315 0.3486 0.1038 +vn -0.7462 0.2499 0.6170 +vn -0.9347 -0.3553 0.0011 +vn -0.4677 -0.2231 0.8553 +vn -0.7463 -0.3153 0.5862 +vn -0.5021 -0.0469 0.8635 +vn -0.8002 -0.0325 0.5989 +vn -0.4677 0.1291 0.8744 +vn -0.7463 0.2499 0.6170 +vn -0.8951 0.3240 0.3063 +vn -0.9347 0.3531 0.0396 +vn -0.9998 -0.0011 0.0201 +vn 0.4435 -0.2154 0.8700 +vn 0.4794 -0.0476 0.8763 +vn 0.5735 -0.0444 0.8180 +vn 0.5331 -0.2457 0.8096 +vn 0.4435 0.1198 0.8882 +vn 0.5331 0.1564 0.8315 +vn 0.4681 -0.0480 0.8824 +vn 0.4374 -0.2129 0.8737 +vn 0.4374 0.1169 0.8916 +vn 0.1818 -0.2340 0.9551 +vn 0.2461 -0.1457 0.9582 +vn 0.3307 -0.3779 0.8648 +vn 0.2678 -0.0523 0.9621 +vn 0.2461 0.0410 0.9684 +vn 0.1818 0.1291 0.9748 +vn 0.3307 0.2820 0.9006 +vn 0.4014 0.3557 0.8440 +vn 0.3315 0.2832 0.8999 +vn 0.1971 0.1450 0.9696 +vn 0.2573 0.0445 0.9653 +vn 0.2740 -0.0522 0.9603 +vn 0.2573 -0.1488 0.9548 +vn 0.3315 -0.3790 0.8640 +vn 0.1972 -0.2491 0.9482 +vn 0.4013 -0.4450 0.8006 +vn -0.0103 -0.0268 0.9996 +vn -0.0000 -0.0249 0.9997 +vn 0.0000 0.0421 0.9991 +vn -0.0336 0.0355 0.9988 +vn 0.0103 -0.0268 0.9996 +vn 0.0336 0.0355 0.9988 +vn 0.0000 0.1827 0.9832 +vn -0.0825 0.1664 0.9826 +vn 0.0825 0.1664 0.9826 +vn -0.0034 -0.0509 0.9987 +vn -0.0017 -0.0498 0.9988 +vn -0.0207 -0.0336 0.9992 +vn -0.0000 -0.0494 0.9988 +vn 0.0017 -0.0498 0.9988 +vn 0.0034 -0.0509 0.9987 +vn 0.0207 -0.0336 0.9992 +vn 0.0673 0.0132 0.9976 +vn 0.1647 0.1117 0.9800 +vn -0.1647 0.1117 0.9800 +vn -0.0673 0.0132 0.9976 +vn 0.0274 -0.0440 0.9987 +vn 0.0294 -0.0542 0.9981 +vn 0.0962 -0.0540 0.9939 +vn 0.0896 -0.0205 0.9958 +vn 0.0275 -0.0645 0.9975 +vn 0.0896 -0.0876 0.9921 +vn 0.2358 -0.0527 0.9704 +vn 0.2195 0.0296 0.9752 +vn 0.2195 -0.1351 0.9662 +vn 0.0045 -0.0526 0.9986 +vn 0.0048 -0.0543 0.9985 +vn 0.0045 -0.0559 0.9984 +vn 0.0034 -0.0576 0.9983 +vn 0.0207 -0.0749 0.9970 +vn 0.0673 -0.1213 0.9903 +vn 0.1647 -0.2173 0.9621 +vn 0.0103 -0.0817 0.9966 +vn -0.0000 -0.0836 0.9965 +vn -0.0000 -0.1501 0.9887 +vn 0.0336 -0.1435 0.9891 +vn -0.0103 -0.0817 0.9966 +vn -0.0336 -0.1435 0.9891 +vn -0.0000 -0.2882 0.9576 +vn 0.0825 -0.2719 0.9588 +vn -0.0825 -0.2719 0.9588 +vn 0.0017 -0.0588 0.9983 +vn -0.0000 -0.0591 0.9983 +vn -0.0017 -0.0588 0.9983 +vn -0.0034 -0.0576 0.9983 +vn -0.0207 -0.0749 0.9970 +vn -0.0673 -0.1213 0.9903 +vn -0.1647 -0.2173 0.9621 +vn -0.0275 -0.0645 0.9975 +vn -0.0294 -0.0542 0.9981 +vn -0.0962 -0.0540 0.9939 +vn -0.0896 -0.0876 0.9921 +vn -0.0274 -0.0440 0.9987 +vn -0.0896 -0.0204 0.9958 +vn -0.2358 -0.0527 0.9704 +vn -0.2195 -0.1351 0.9662 +vn -0.2195 0.0296 0.9752 +vn -0.0045 -0.0559 0.9984 +vn -0.0048 -0.0543 0.9985 +vn -0.0045 -0.0526 0.9986 +vn -0.0376 0.0448 0.9983 +vn -0.0000 0.0539 0.9985 +vn 0.0000 -0.0183 0.9998 +vn -0.0125 -0.0214 0.9997 +vn 0.0377 0.0449 0.9983 +vn 0.0125 -0.0214 0.9997 +vn 0.0000 -0.0459 0.9989 +vn -0.0029 -0.0466 0.9989 +vn 0.0029 -0.0466 0.9989 +vn -0.1818 0.1291 0.9748 +vn -0.0936 0.1935 0.9766 +vn -0.0728 0.0188 0.9972 +vn -0.0000 0.2153 0.9765 +vn 0.0936 0.1935 0.9766 +vn 0.0728 0.0188 0.9972 +vn 0.0241 -0.0301 0.9993 +vn 0.0056 -0.0487 0.9988 +vn -0.0056 -0.0487 0.9988 +vn -0.0241 -0.0301 0.9993 +vn 0.0989 -0.0164 0.9950 +vn 0.1079 -0.0539 0.9927 +vn 0.0360 -0.0542 0.9979 +vn 0.0329 -0.0417 0.9986 +vn 0.0990 -0.0916 0.9909 +vn 0.0329 -0.0667 0.9972 +vn 0.0084 -0.0543 0.9985 +vn 0.0077 -0.0513 0.9987 +vn 0.0076 -0.0572 0.9983 +vn 0.0728 -0.1267 0.9893 +vn 0.0241 -0.0783 0.9966 +vn 0.0056 -0.0598 0.9982 +vn 0.0377 -0.1528 0.9875 +vn 0.0000 -0.1617 0.9868 +vn 0.0000 -0.0901 0.9959 +vn 0.0125 -0.0871 0.9961 +vn -0.0376 -0.1528 0.9875 +vn -0.0125 -0.0871 0.9961 +vn 0.0000 -0.0627 0.9980 +vn 0.0029 -0.0619 0.9981 +vn -0.0029 -0.0619 0.9981 +vn 0.0936 -0.2982 0.9499 +vn 0.0000 -0.3199 0.9475 +vn -0.0936 -0.2982 0.9499 +vn -0.1818 -0.2340 0.9551 +vn -0.0728 -0.1267 0.9893 +vn -0.0241 -0.0783 0.9966 +vn -0.0056 -0.0598 0.9982 +vn -0.0990 -0.0916 0.9909 +vn -0.1079 -0.0539 0.9927 +vn -0.0359 -0.0542 0.9979 +vn -0.0329 -0.0667 0.9972 +vn -0.0990 -0.0164 0.9950 +vn -0.0329 -0.0417 0.9986 +vn -0.0084 -0.0543 0.9985 +vn -0.0077 -0.0572 0.9983 +vn -0.0077 -0.0513 0.9987 +vn -0.2461 -0.1457 0.9582 +vn -0.2678 -0.0523 0.9621 +vn -0.2461 0.0410 0.9684 +vn -0.2627 -0.9179 -0.2975 +vn -0.2588 -0.9659 -0.0026 +vn -0.0000 -1.0000 0.0008 +vn 0.0000 -0.9505 -0.3108 +vn -0.2480 -0.9491 0.1940 +vn 0.0000 -0.9787 0.2052 +vn 0.2587 -0.9659 -0.0026 +vn 0.2626 -0.9179 -0.2974 +vn 0.2480 -0.9491 0.1940 +vn -0.5383 -0.7400 -0.4034 +vn -0.5480 -0.7975 -0.2524 +vn -0.2567 -0.8427 -0.4733 +vn -0.5427 -0.8398 -0.0102 +vn -0.5254 -0.8358 0.1592 +vn -0.5222 -0.8252 0.2153 +vn -0.2467 -0.9355 0.2528 +vn 0.0001 -0.9645 0.2640 +vn 0.2467 -0.9355 0.2528 +vn 0.5222 -0.8252 0.2155 +vn 0.5254 -0.8358 0.1593 +vn 0.5427 -0.8398 -0.0102 +vn 0.5480 -0.7975 -0.2524 +vn 0.2566 -0.8427 -0.4734 +vn 0.5380 -0.7402 -0.4034 +vn 0.0000 -0.8694 -0.4941 +vn -0.1688 -0.4924 0.8538 +vn 0.0000 -0.5293 0.8485 +vn 0.0000 -0.6259 0.7799 +vn -0.2042 -0.5829 0.7865 +vn 0.1688 -0.4924 0.8538 +vn 0.2043 -0.5828 0.7865 +vn 0.0001 -0.5298 0.8481 +vn -0.1687 -0.4941 0.8529 +vn 0.1688 -0.4941 0.8529 +vn -0.3307 -0.3779 0.8648 +vn 0.1011 -0.3203 0.9419 +vn 0.0000 -0.3431 0.9393 +vn -0.1011 -0.3203 0.9419 +vn -0.3313 -0.3793 0.8639 +vn -0.1972 -0.2492 0.9482 +vn -0.4013 -0.4450 0.8006 +vn 0.1689 0.3971 0.9021 +vn -0.0000 0.4342 0.9008 +vn -0.0000 0.5374 0.8433 +vn 0.2042 0.4942 0.8450 +vn -0.1689 0.3970 0.9021 +vn -0.2043 0.4942 0.8450 +vn -0.0000 0.4344 0.9007 +vn 0.1687 0.3987 0.9014 +vn -0.1688 0.3987 0.9014 +vn -0.3306 0.2819 0.9007 +vn -0.4013 0.3556 0.8441 +vn -0.3315 0.2832 0.8999 +vn -0.1971 0.1450 0.9696 +vn -0.1011 0.2164 0.9711 +vn -0.0001 0.2394 0.9709 +vn 0.1011 0.2164 0.9711 +vn -0.4434 0.1198 0.8883 +vn -0.4795 -0.0476 0.8763 +vn -0.5734 -0.0445 0.8181 +vn -0.5330 0.1565 0.8315 +vn -0.4435 -0.2154 0.8700 +vn -0.5331 -0.2457 0.8096 +vn -0.4685 -0.0479 0.8822 +vn -0.4370 0.1167 0.8918 +vn -0.4371 -0.2125 0.8740 +vn -0.2571 -0.1483 0.9549 +vn -0.2738 -0.0521 0.9604 +vn -0.2573 0.0445 0.9653 +vn -0.3066 0.7035 0.6412 +vn -0.0000 0.7912 0.6116 +vn 0.0000 0.4106 0.9118 +vn -0.1624 0.3545 0.9208 +vn 0.3066 0.7035 0.6412 +vn 0.1624 0.3545 0.9208 +vn 0.0000 0.1936 0.9811 +vn -0.0853 0.1681 0.9821 +vn 0.0852 0.1680 0.9821 +vn -0.7933 0.5448 0.2718 +vn -0.3654 0.9209 0.1354 +vn -0.5433 0.4106 0.7323 +vn 0.0000 0.9917 0.1285 +vn 0.0000 0.7911 0.6117 +vn 0.3654 0.9209 0.1354 +vn 0.7933 0.5448 0.2718 +vn 0.5433 0.4106 0.7323 +vn 0.5433 0.4107 0.7322 +vn 0.2755 0.2041 0.9394 +vn 0.1544 0.0982 0.9831 +vn -0.1543 0.0982 0.9831 +vn -0.2755 0.2041 0.9394 +vn -0.5433 0.4107 0.7322 +vn 0.5670 0.1092 0.8164 +vn 0.5210 -0.0463 0.8523 +vn 0.2971 -0.0518 0.9535 +vn 0.3051 0.0499 0.9510 +vn 0.5674 -0.1971 0.7995 +vn 0.3052 -0.1527 0.9400 +vn 0.1949 -0.0532 0.9794 +vn 0.1889 0.0160 0.9819 +vn 0.1890 -0.1224 0.9743 +vn 0.8267 0.1243 0.5487 +vn 0.5433 0.4107 0.7323 +vn 0.8268 0.1243 0.5487 +vn 0.7646 -0.0350 0.6435 +vn 0.8271 -0.1831 0.5314 +vn 0.8271 -0.1830 0.5314 +vn 0.7939 -0.5712 0.2084 +vn 0.5443 -0.4881 0.6822 +vn 0.5673 -0.1971 0.7996 +vn 0.2759 -0.3049 0.9116 +vn 0.1545 -0.2042 0.9667 +vn 0.3074 -0.7704 0.5585 +vn 0.0000 -0.8547 0.5191 +vn 0.0000 -0.5080 0.8614 +vn 0.1628 -0.4530 0.8765 +vn -0.3074 -0.7704 0.5586 +vn -0.1628 -0.4530 0.8765 +vn -0.0000 -0.2989 0.9543 +vn 0.0854 -0.2737 0.9580 +vn -0.0853 -0.2736 0.9580 +vn 0.3656 -0.9303 0.0297 +vn -0.0000 -0.9999 0.0148 +vn 0.0000 -0.8547 0.5192 +vn -0.3656 -0.9303 0.0297 +vn -0.3074 -0.7704 0.5585 +vn -0.7939 -0.5712 0.2084 +vn -0.5443 -0.4881 0.6823 +vn -0.5443 -0.4882 0.6822 +vn -0.2759 -0.3049 0.9115 +vn -0.1544 -0.2042 0.9667 +vn -0.5673 -0.1971 0.7996 +vn -0.5210 -0.0463 0.8523 +vn -0.2971 -0.0518 0.9534 +vn -0.3052 -0.1527 0.9400 +vn -0.5670 0.1092 0.8164 +vn -0.3051 0.0499 0.9510 +vn -0.1949 -0.0532 0.9794 +vn -0.1890 -0.1223 0.9743 +vn -0.1890 0.0160 0.9819 +vn -0.8271 -0.1831 0.5314 +vn -0.5674 -0.1971 0.7995 +vn -0.7646 -0.0350 0.6436 +vn -0.8267 0.1243 0.5487 +vn -0.2545 -0.4850 -0.8367 +vn -0.2575 -0.6685 -0.6977 +vn -0.0000 -0.6894 -0.7243 +vn -0.0001 -0.4987 -0.8668 +vn -0.2573 -0.7822 -0.5674 +vn 0.0000 -0.8073 -0.5902 +vn 0.0000 -0.6895 -0.7243 +vn 0.2575 -0.6685 -0.6977 +vn 0.2545 -0.4850 -0.8367 +vn 0.2573 -0.7821 -0.5675 +vn -0.5246 -0.2356 -0.8181 +vn -0.5361 -0.4293 -0.7269 +vn -0.2474 -0.2622 -0.9328 +vn -0.5402 -0.5873 -0.6027 +vn -0.5394 -0.6860 -0.4883 +vn 0.5391 -0.6861 -0.4885 +vn 0.5402 -0.5873 -0.6027 +vn 0.5360 -0.4293 -0.7269 +vn 0.2474 -0.2623 -0.9327 +vn 0.5244 -0.2356 -0.8182 +vn -0.0000 -0.2683 -0.9633 +vn -0.2130 -0.9427 -0.2570 +vn 0.0000 -0.9651 -0.2620 +vn -0.0001 -0.9973 -0.0728 +vn -0.2177 -0.9734 -0.0721 +vn 0.2124 -0.9428 -0.2570 +vn 0.2176 -0.9734 -0.0721 +vn 0.0001 -0.9840 0.1780 +vn -0.2200 -0.9599 0.1738 +vn 0.2201 -0.9598 0.1742 +vn -0.5497 -0.7843 -0.2878 +vn -0.2123 -0.9193 -0.3313 +vn -0.5487 -0.8052 -0.2250 +vn -0.0000 -0.9414 -0.3374 +vn 0.2122 -0.9194 -0.3312 +vn 0.5497 -0.7842 -0.2878 +vn 0.5487 -0.8052 -0.2250 +vn 0.5543 -0.8298 -0.0647 +vn 0.5589 -0.8158 0.1487 +vn 0.5599 -0.7738 0.2962 +vn 0.2193 -0.9123 0.3460 +vn 0.0002 -0.9353 0.3538 +vn -0.2189 -0.9123 0.3460 +vn -0.5588 -0.8158 0.1488 +vn -0.5599 -0.7738 0.2962 +vn -0.5543 -0.8298 -0.0648 +vn 0.2131 0.9658 -0.1479 +vn 0.0002 0.9887 -0.1498 +vn -0.0000 0.9992 0.0388 +vn 0.2176 0.9753 0.0371 +vn -0.2126 0.9659 -0.1478 +vn -0.2173 0.9754 0.0375 +vn -0.0001 0.9605 0.2784 +vn 0.2199 0.9369 0.2717 +vn -0.2200 0.9368 0.2720 +vn 0.5499 0.8117 -0.1966 +vn 0.2124 0.9510 -0.2246 +vn 0.5489 0.8255 -0.1315 +vn 0.0004 0.9737 -0.2279 +vn -0.2125 0.9510 -0.2246 +vn -0.5501 0.8116 -0.1966 +vn -0.5489 0.8255 -0.1315 +vn -0.5545 0.8317 0.0284 +vn -0.5588 0.7963 0.2317 +vn -0.5605 0.7428 0.3662 +vn -0.2196 0.8761 0.4292 +vn -0.0001 0.8984 0.4392 +vn 0.2193 0.8762 0.4292 +vn 0.5590 0.7962 0.2316 +vn 0.5607 0.7427 0.3662 +vn 0.5543 0.8319 0.0284 +vn -0.2038 0.0891 0.9749 +vn -0.2017 -0.0740 0.9766 +vn 0.0000 -0.0755 0.9971 +vn 0.0001 0.0913 0.9958 +vn -0.2028 -0.2296 0.9519 +vn -0.0001 -0.2345 0.9721 +vn 0.2017 -0.0739 0.9766 +vn 0.2040 0.0892 0.9749 +vn 0.2026 -0.2294 0.9520 +vn -0.5403 0.2551 0.8019 +vn -0.5326 0.0759 0.8430 +vn -0.2092 0.2985 0.9312 +vn -0.5292 -0.0641 0.8461 +vn -0.5306 -0.1979 0.8242 +vn -0.5367 -0.3562 0.7649 +vn -0.2068 -0.4144 0.8863 +vn -0.0000 -0.4239 0.9057 +vn 0.2068 -0.4147 0.8862 +vn 0.5366 -0.3562 0.7650 +vn 0.5305 -0.1979 0.8242 +vn 0.5292 -0.0641 0.8461 +vn 0.5324 0.0761 0.8431 +vn 0.2092 0.2982 0.9313 +vn 0.5403 0.2551 0.8019 +vn -0.0000 0.3056 0.9521 +vn -0.2176 -0.8583 0.4647 +vn 0.0002 -0.8797 0.4755 +vn 0.0000 -0.7822 0.6230 +vn -0.2158 -0.7634 0.6088 +vn 0.2179 -0.8583 0.4646 +vn 0.2158 -0.7634 0.6088 +vn -0.2158 -0.7635 0.6088 +vn 0.0002 -0.6249 0.7807 +vn -0.2123 -0.6101 0.7634 +vn 0.2158 -0.7635 0.6087 +vn 0.2123 -0.6103 0.7632 +vn -0.5571 -0.7293 0.3972 +vn 0.5571 -0.7293 0.3972 +vn 0.5525 -0.6505 0.5211 +vn 0.5525 -0.6506 0.5210 +vn 0.5455 -0.5218 0.6558 +vn -0.5455 -0.5219 0.6558 +vn -0.5525 -0.6506 0.5210 +vn -0.5525 -0.6506 0.5211 +vn -0.2389 0.2120 -0.9476 +vn -0.2380 0.0746 -0.9684 +vn -0.0000 0.0766 -0.9971 +vn 0.0003 0.2169 -0.9762 +vn -0.2402 -0.0698 -0.9682 +vn -0.0003 -0.0703 -0.9975 +vn 0.2380 0.0741 -0.9684 +vn 0.2391 0.2118 -0.9476 +vn 0.2402 -0.0697 -0.9682 +vn -0.5193 0.3415 -0.7834 +vn -0.5102 0.1905 -0.8387 +vn -0.2441 0.3823 -0.8912 +vn -0.5078 0.0658 -0.8590 +vn -0.5124 -0.0645 -0.8563 +vn 0.5125 -0.0649 -0.8562 +vn 0.5078 0.0658 -0.8589 +vn 0.5101 0.1900 -0.8389 +vn 0.2444 0.3824 -0.8911 +vn 0.5196 0.3412 -0.7834 +vn 0.0001 0.3923 -0.9198 +vn -0.2557 0.8270 -0.5007 +vn -0.2547 0.7296 -0.6347 +vn -0.0000 0.7523 -0.6588 +vn 0.0000 0.8533 -0.5214 +vn -0.2548 0.7296 -0.6346 +vn -0.2507 0.5730 -0.7803 +vn 0.0000 0.5896 -0.8077 +vn 0.0000 0.7523 -0.6589 +vn 0.2548 0.7296 -0.6347 +vn 0.2558 0.8270 -0.5007 +vn 0.2509 0.5730 -0.7802 +vn -0.5368 0.7723 -0.3396 +vn -0.5371 0.7260 -0.4295 +vn -0.2558 0.8789 -0.4026 +vn -0.5359 0.6417 -0.5486 +vn -0.5359 0.6417 -0.5487 +vn -0.5299 0.5072 -0.6797 +vn 0.5300 0.5072 -0.6796 +vn 0.5359 0.6417 -0.5486 +vn 0.5371 0.7260 -0.4295 +vn 0.2557 0.8789 -0.4026 +vn 0.5372 0.7721 -0.3395 +vn 0.0000 0.9065 -0.4221 +vn -0.2476 0.9200 0.3037 +vn -0.2590 0.9600 0.1059 +vn -0.0000 0.9936 0.1132 +vn -0.0000 0.9479 0.3185 +vn -0.2631 0.9418 -0.2094 +vn -0.0000 0.9754 -0.2206 +vn 0.2590 0.9601 0.1059 +vn 0.2476 0.9200 0.3037 +vn 0.2631 0.9417 -0.2095 +vn -0.5218 0.7952 0.3090 +vn -0.5248 0.8120 0.2555 +vn -0.2464 0.9003 0.3589 +vn -0.5432 0.8355 0.0835 +vn -0.5489 0.8175 -0.1742 +vn 0.5489 0.8176 -0.1742 +vn 0.5432 0.8354 0.0838 +vn 0.5248 0.8120 0.2555 +vn 0.2463 0.9002 0.3590 +vn 0.5217 0.7953 0.3088 +vn -0.0000 0.9277 0.3733 +vn -0.3022 -0.9162 -0.2633 +vn -0.0000 -0.9661 -0.2581 +vn -0.0000 -0.9425 -0.3343 +vn -0.2432 -0.9118 -0.3307 +vn 0.3021 -0.9162 -0.2633 +vn 0.2432 -0.9119 -0.3307 +vn -0.0001 -0.9362 -0.3515 +vn -0.2193 -0.9123 -0.3458 +vn 0.2193 -0.9123 -0.3458 +vn -0.6929 -0.6934 -0.1974 +vn 0.6929 -0.6934 -0.1974 +vn 0.6001 -0.7501 -0.2780 +vn 0.5612 -0.7721 -0.2980 +vn -0.5612 -0.7721 -0.2980 +vn -0.6001 -0.7501 -0.2780 +vn 0.3023 0.9401 -0.1575 +vn 0.0000 0.9892 -0.1465 +vn -0.0000 0.9743 -0.2252 +vn 0.2434 0.9435 -0.2251 +vn -0.3023 0.9401 -0.1574 +vn -0.2434 0.9435 -0.2251 +vn 0.0000 0.9700 -0.2430 +vn 0.2194 0.9457 -0.2400 +vn -0.2194 0.9457 -0.2400 +vn 0.6931 0.7113 -0.1174 +vn -0.6931 0.7113 -0.1173 +vn -0.6003 0.7766 -0.1910 +vn -0.5614 0.8008 -0.2084 +vn 0.5615 0.8008 -0.2084 +vn 0.6003 0.7766 -0.1910 +vn -0.2555 0.7864 0.5625 +vn -0.2509 0.8548 0.4543 +vn 0.0003 0.8835 0.4685 +vn 0.0000 0.8148 0.5797 +vn -0.2483 0.8860 0.3916 +vn -0.0002 0.9139 0.4059 +vn 0.2506 0.8550 0.4541 +vn 0.2559 0.7862 0.5625 +vn 0.2485 0.8860 0.3914 +vn -0.5580 0.5318 0.6370 +vn -0.5389 0.6815 0.4950 +vn -0.2679 0.6286 0.7301 +vn -0.5293 0.7493 0.3980 +vn -0.5249 0.7802 0.3403 +vn 0.5248 0.7802 0.3403 +vn 0.5292 0.7494 0.3979 +vn 0.5389 0.6816 0.4950 +vn 0.2679 0.6286 0.7301 +vn 0.5580 0.5318 0.6370 +vn -0.0000 0.6564 0.7544 +vn 0.2185 0.8137 0.5387 +vn 0.0002 0.8339 0.5518 +vn 0.0000 0.7218 0.6921 +vn 0.2176 0.7041 0.6759 +vn -0.2188 0.8136 0.5387 +vn -0.2178 0.7042 0.6758 +vn -0.0000 0.5391 0.8423 +vn 0.2146 0.5261 0.8229 +vn -0.2148 0.5260 0.8229 +vn 0.0000 0.5390 0.8423 +vn 0.5587 0.6906 0.4593 +vn -0.5582 0.6908 0.4596 +vn -0.5555 0.5987 0.5771 +vn -0.5497 0.4482 0.7049 +vn 0.5497 0.4482 0.7049 +vn 0.5555 0.5987 0.5770 +vn 0.5555 0.5986 0.5771 +vn 0.7989 -0.2389 0.5519 +vn 0.7924 -0.0330 0.6092 +vn 0.8860 -0.0252 0.4629 +vn 0.9075 -0.1093 0.4057 +vn 0.7985 0.1775 0.5752 +vn 0.9073 0.0646 0.4154 +vn 0.8870 -0.0251 0.4612 +vn 0.9269 0.0319 0.3739 +vn 0.9271 -0.0723 0.3679 +vn 0.5588 -0.5986 0.5740 +vn 0.5755 -0.3575 0.7356 +vn 0.8050 -0.4101 0.4286 +vn 0.5807 -0.0440 0.8129 +vn 0.5749 0.2755 0.7704 +vn 0.5581 0.5318 0.6370 +vn 0.8045 0.3607 0.4719 +vn 0.9451 0.1390 0.2956 +vn 0.9738 -0.1628 0.1587 +vn 0.7646 -0.0350 0.6436 +vn 0.9737 0.1447 0.1762 +vn 0.9453 -0.1702 0.2782 +vn -0.7986 0.1776 0.5751 +vn -0.7924 -0.0330 0.6092 +vn -0.8860 -0.0252 0.4630 +vn -0.9073 0.0647 0.4154 +vn -0.7990 -0.2389 0.5519 +vn -0.9074 -0.1094 0.4057 +vn -0.8870 -0.0251 0.4612 +vn -0.9271 -0.0722 0.3679 +vn -0.9269 0.0319 0.3739 +vn -0.5749 0.2755 0.7704 +vn -0.8044 0.3607 0.4719 +vn -0.5807 -0.0440 0.8129 +vn -0.7924 -0.0330 0.6091 +vn -0.5755 -0.3574 0.7356 +vn -0.5755 -0.3574 0.7355 +vn -0.5588 -0.5985 0.5740 +vn -0.8050 -0.4101 0.4286 +vn -0.9453 -0.1703 0.2782 +vn -0.9737 0.1448 0.1762 +vn -0.9738 -0.1628 0.1587 +vn -0.9451 0.1390 0.2956 +vn -0.8045 0.3607 0.4719 +vn -0.8138 0.5694 -0.1162 +vn -0.8106 0.5835 0.0500 +vn -0.9864 0.1642 0.0065 +vn -0.9865 0.1607 -0.0326 +vn -0.7963 0.5806 0.1696 +vn -0.9835 0.1763 0.0414 +vn -0.9126 -0.4070 -0.0391 +vn -0.9149 -0.3972 0.0728 +vn -0.9141 -0.3881 -0.1179 +vn -0.8045 0.5477 -0.2297 +vn -0.7924 0.5718 0.2125 +vn -0.7924 0.5719 0.2125 +vn -0.9818 0.1805 0.0587 +vn -0.9169 -0.3722 -0.1441 +vn -0.5497 -0.7842 -0.2878 +vn -0.5486 -0.8052 -0.2250 +vn -0.5542 -0.8298 -0.0648 +vn -0.9187 -0.3679 0.1435 +vn -0.5600 -0.7737 0.2962 +vn -0.9840 0.1655 -0.0668 +vn -0.8003 -0.5159 0.3054 +vn -0.7962 -0.5626 0.2224 +vn -0.9769 -0.1925 0.0932 +vn -0.9672 -0.1949 0.1629 +vn -0.7942 -0.5824 0.1732 +vn -0.9808 -0.1872 0.0553 +vn -0.9398 0.3348 -0.0680 +vn -0.9671 0.2542 0.0116 +vn -0.9231 0.3719 -0.0982 +vn -0.5394 -0.7325 0.4153 +vn -0.5296 -0.7894 0.3105 +vn -0.5251 -0.8137 0.2492 +vn -0.7927 -0.5920 0.1455 +vn -0.9819 -0.1858 0.0378 +vn -0.9170 0.3859 -0.1008 +vn -0.9171 0.3858 -0.1008 +vn -0.6930 0.7113 -0.1174 +vn 0.8131 -0.5562 -0.1720 +vn 0.8101 -0.5861 -0.0156 +vn 0.9863 -0.1646 -0.0116 +vn 0.9862 -0.1579 -0.0488 +vn 0.7967 -0.5959 0.1013 +vn 0.9835 -0.1798 0.0208 +vn 0.9128 0.4084 0.0066 +vn 0.9153 0.3868 0.1125 +vn 0.9142 0.3987 -0.0728 +vn 0.8130 -0.5562 -0.1720 +vn 0.8050 -0.5249 -0.2764 +vn 0.7927 -0.5921 0.1455 +vn 0.7927 -0.5920 0.1455 +vn 0.9819 -0.1858 0.0376 +vn 0.9169 0.3861 -0.1008 +vn 0.5500 0.8117 -0.1966 +vn 0.5542 0.8319 0.0284 +vn 0.5589 0.7962 0.2317 +vn 0.9191 0.3524 0.1761 +vn 0.5606 0.7427 0.3662 +vn 0.9839 -0.1590 -0.0814 +vn 0.8050 -0.5249 -0.2765 +vn 0.7999 0.4789 0.3617 +vn 0.7959 0.5342 0.2848 +vn 0.9768 0.1810 0.1145 +vn 0.9671 0.1759 0.1839 +vn 0.7939 0.5593 0.2386 +vn 0.9807 0.1799 0.0762 +vn 0.9398 -0.3249 -0.1056 +vn 0.9672 -0.2536 -0.0173 +vn 0.9230 -0.3585 -0.1398 +vn 0.5217 0.7953 0.3087 +vn 0.7924 0.5718 0.2124 +vn 0.9818 0.1804 0.0588 +vn 0.9169 -0.3721 -0.1441 +vn 0.9170 -0.3721 -0.1441 +vn 0.5612 -0.7722 -0.2980 +vn 0.6930 -0.6934 -0.1974 +vn 0.8052 -0.3071 -0.5073 +vn 0.8074 -0.4161 -0.4182 +vn 0.9853 -0.1218 -0.1195 +vn 0.9857 -0.0900 -0.1425 +vn 0.8061 -0.4859 -0.3380 +vn 0.9845 -0.1452 -0.0986 +vn 0.9148 0.2891 0.2820 +vn 0.9114 0.2174 0.3494 +vn 0.9176 0.3300 0.2217 +vn 0.8052 -0.3072 -0.5073 +vn 0.7967 -0.1726 -0.5792 +vn 0.8074 -0.4162 -0.4182 +vn 0.5555 0.5987 0.5771 +vn 0.5497 0.4482 0.7050 +vn 0.9081 0.1222 0.4006 +vn 0.9848 -0.0531 -0.1652 +vn -0.8060 -0.4859 -0.3379 +vn -0.8073 -0.4164 -0.4181 +vn -0.9853 -0.1221 -0.1196 +vn -0.9844 -0.1455 -0.0989 +vn -0.8049 -0.3076 -0.5074 +vn -0.9856 -0.0902 -0.1428 +vn -0.9148 0.2891 0.2819 +vn -0.9176 0.3300 0.2217 +vn -0.9115 0.2170 0.3493 +vn -0.5382 -0.7400 -0.4034 +vn -0.5393 -0.6861 -0.4883 +vn -0.8050 -0.5251 -0.2762 +vn -0.5360 -0.4293 -0.7269 +vn -0.5246 -0.2355 -0.8181 +vn -0.7967 -0.1726 -0.5792 +vn -0.9848 -0.0532 -0.1654 +vn -0.9081 0.1223 0.4005 +vn -0.5497 0.4482 0.7050 +vn -0.9192 0.3524 0.1759 +vn -0.9839 -0.1591 -0.0814 +vn -0.7862 -0.0495 -0.6160 +vn -0.7822 0.0474 -0.6212 +vn -0.9820 0.0142 -0.1884 +vn -0.9829 -0.0167 -0.1836 +vn -0.7842 0.1397 -0.6046 +vn -0.9824 0.0436 -0.1814 +vn -0.9070 -0.0321 0.4198 +vn -0.9073 0.0351 0.4190 +vn -0.9070 -0.0964 0.4099 +vn -0.7967 -0.1726 -0.5791 +vn -0.7822 0.0474 -0.6213 +vn -0.7925 0.2483 -0.5571 +vn -0.7925 0.2483 -0.5570 +vn -0.9841 0.0753 -0.1607 +vn -0.9073 -0.1735 0.3830 +vn -0.5366 -0.3562 0.7650 +vn 0.7963 0.5806 0.1695 +vn 0.8105 0.5836 0.0501 +vn 0.9864 0.1641 0.0064 +vn 0.9835 0.1763 0.0415 +vn 0.8138 0.5694 -0.1161 +vn 0.9864 0.1608 -0.0326 +vn 0.9126 -0.4069 -0.0392 +vn 0.9140 -0.3881 -0.1179 +vn 0.9149 -0.3971 0.0727 +vn 0.5249 0.8119 0.2555 +vn 0.5433 0.8354 0.0839 +vn 0.5489 0.8175 -0.1743 +vn 0.8045 0.5477 -0.2297 +vn 0.9839 0.1656 -0.0668 +vn 0.9188 -0.3677 0.1435 +vn -0.7967 -0.5959 0.1012 +vn -0.8102 -0.5860 -0.0157 +vn -0.9863 -0.1645 -0.0117 +vn -0.9835 -0.1796 0.0208 +vn -0.8130 -0.5563 -0.1720 +vn -0.9862 -0.1580 -0.0491 +vn -0.9128 0.4084 0.0067 +vn -0.9142 0.3988 -0.0726 +vn -0.9153 0.3868 0.1126 +vn -0.5255 -0.8358 0.1592 +vn -0.9152 0.3869 0.1125 +vn -0.9128 0.4085 0.0067 +vn -0.7939 0.5592 0.2386 +vn -0.7959 0.5343 0.2848 +vn -0.9768 0.1810 0.1144 +vn -0.9807 0.1799 0.0762 +vn -0.7999 0.4789 0.3617 +vn -0.9671 0.1759 0.1840 +vn -0.9398 -0.3250 -0.1056 +vn -0.9230 -0.3585 -0.1398 +vn -0.9672 -0.2536 -0.0173 +vn -0.7959 0.5342 0.2848 +vn -0.6929 -0.6935 -0.1974 +vn 0.7942 -0.5825 0.1733 +vn 0.7962 -0.5626 0.2224 +vn 0.9769 -0.1925 0.0932 +vn 0.9808 -0.1872 0.0552 +vn 0.8003 -0.5159 0.3054 +vn 0.9672 -0.1949 0.1629 +vn 0.9398 0.3348 -0.0680 +vn 0.9231 0.3719 -0.0982 +vn 0.9671 0.2542 0.0116 +vn 0.5251 -0.8137 0.2492 +vn 0.7941 -0.5825 0.1733 +vn 0.5296 -0.7893 0.3106 +vn 0.7962 -0.5627 0.2225 +vn 0.5394 -0.7325 0.4153 +vn 0.8003 -0.5159 0.3055 +vn 0.5395 -0.7325 0.4152 +vn 0.6931 0.7113 -0.1173 +vn 0.7842 0.1397 -0.6046 +vn 0.7822 0.0474 -0.6213 +vn 0.9820 0.0140 -0.1884 +vn 0.9824 0.0436 -0.1815 +vn 0.7862 -0.0495 -0.6160 +vn 0.9828 -0.0169 -0.1839 +vn 0.9072 -0.0320 0.4196 +vn 0.9071 -0.0961 0.4098 +vn 0.9073 0.0351 0.4190 +vn 0.7925 0.2483 -0.5571 +vn 0.5306 -0.1979 0.8242 +vn 0.9075 -0.1732 0.3826 +vn 0.9841 0.0753 -0.1609 +vn 0.7925 0.2483 -0.5570 +vn -0.8006 0.3634 -0.4765 +vn -0.8043 0.4558 -0.3812 +vn -0.9849 0.1341 -0.1091 +vn -0.9850 0.1071 -0.1350 +vn -0.8046 0.5148 -0.2961 +vn -0.9843 0.1540 -0.0859 +vn -0.9139 -0.3150 0.2561 +vn -0.9103 -0.2544 0.3265 +vn -0.9169 -0.3492 0.1930 +vn -0.8043 0.4557 -0.3812 +vn -0.5571 -0.7293 0.3971 +vn -0.5455 -0.5218 0.6558 +vn 0.8045 0.5149 -0.2960 +vn 0.8043 0.4558 -0.3812 +vn 0.9849 0.1342 -0.1091 +vn 0.9843 0.1542 -0.0861 +vn 0.8006 0.3634 -0.4765 +vn 0.9850 0.1072 -0.1353 +vn 0.9140 -0.3146 0.2561 +vn 0.9170 -0.3490 0.1929 +vn 0.9105 -0.2540 0.3263 +vn 0.8005 0.3634 -0.4766 +vn 0.5455 -0.5219 0.6558 +vn -0.2486 -0.9248 0.2878 +vn -0.2509 -0.9008 0.3543 +vn -0.0003 -0.9308 0.3655 +vn 0.0002 -0.9543 0.2990 +vn -0.2562 -0.8443 0.4707 +vn -0.0000 -0.8747 0.4847 +vn 0.2511 -0.9007 0.3546 +vn 0.2487 -0.9248 0.2881 +vn 0.2558 -0.8444 0.4706 +vn -0.5588 -0.5986 0.5740 +vn -0.2684 -0.7053 0.6561 +vn 0.0000 -0.7357 0.6773 +vn 0.2684 -0.7054 0.6561 +vn -0.2822 -0.4325 0.8564 +vn -0.2876 -0.0516 0.9564 +vn 0.0000 -0.0539 0.9985 +vn -0.0000 -0.4550 0.8905 +vn -0.2816 0.3368 0.8985 +vn 0.0000 0.3555 0.9347 +vn 0.2876 -0.0518 0.9564 +vn 0.2821 -0.4324 0.8564 +vn 0.2817 0.3369 0.8984 +vn -0.2684 -0.7054 0.6560 +vn 0.5755 -0.3574 0.7355 +usemtl Scene_-_Root +s 1 +f 26153/26153/18369 26154/26154/18370 26155/26155/18371 +f 26153/26153/18369 26155/26155/18371 26156/26156/18372 +f 26154/26154/18370 26157/26157/18373 26158/26158/18374 +f 26154/26154/18370 26158/26158/18374 26155/26155/18371 +f 26156/26156/18372 26155/26155/18371 26159/26159/18375 +f 26156/26156/18372 26159/26159/18375 26160/26160/18376 +f 26155/26155/18371 26158/26158/18374 26161/26161/18377 +f 26155/26155/18371 26161/26161/18377 26159/26159/18375 +f 26162/26162/18378 26163/26163/18379 26153/26153/18369 +f 26162/26162/18378 26153/26153/18369 26164/26164/18380 +f 26163/26163/18379 26165/26165/18381 26154/26154/18370 +f 26163/26163/18379 26154/26154/18370 26153/26153/18369 +f 26165/26165/18381 26166/26166/18382 26157/26157/18373 +f 26165/26165/18381 26157/26157/18373 26154/26154/18370 +f 26167/26167/18383 26168/26168/18384 26169/26169/18385 +f 26167/26167/18383 26169/26169/18385 26170/26170/18373 +f 26170/26170/18373 26169/26169/18385 26171/26171/18386 +f 26170/26170/18373 26171/26171/18386 26172/26172/18387 +f 26172/26172/18387 26171/26171/18386 26173/26173/18388 +f 26172/26172/18387 26173/26173/18388 26174/26174/18377 +f 26174/26174/18377 26173/26173/18388 26175/26175/18389 +f 26174/26174/18377 26175/26175/18389 26176/26176/18390 +f 26159/26159/18375 26161/26161/18377 26177/26177/18391 +f 26159/26159/18375 26177/26177/18391 26178/26178/18392 +f 26160/26160/18376 26159/26159/18375 26178/26178/18392 +f 26160/26160/18376 26178/26178/18392 26179/26179/18393 +f 26180/26180/18394 26160/26160/18376 26179/26179/18393 +f 26180/26180/18394 26179/26179/18393 26181/26181/18395 +f 26182/26182/18396 26156/26156/18372 26160/26160/18376 +f 26182/26182/18396 26160/26160/18376 26180/26180/18394 +f 26164/26164/18380 26153/26153/18369 26156/26156/18372 +f 26164/26164/18380 26156/26156/18372 26182/26182/18396 +f 26183/26183/18397 26184/26184/18398 26185/26185/18399 +f 26183/26183/18397 26185/26185/18399 26186/26186/18400 +f 26184/26184/18398 26187/26187/18401 26188/26188/18402 +f 26184/26184/18398 26188/26188/18402 26185/26185/18399 +f 26186/26186/18400 26185/26185/18399 26189/26189/18403 +f 26186/26186/18400 26189/26189/18403 26190/26190/18404 +f 26185/26185/18399 26188/26188/18402 26191/26191/18405 +f 26185/26185/18399 26191/26191/18405 26189/26189/18403 +f 26192/26192/18406 26193/26193/18393 26183/26183/18397 +f 26192/26192/18406 26183/26183/18397 26194/26194/18407 +f 26193/26193/18393 26195/26195/18392 26184/26184/18398 +f 26193/26193/18393 26184/26184/18398 26183/26183/18397 +f 26195/26195/18392 26196/26196/18391 26187/26187/18401 +f 26195/26195/18392 26187/26187/18401 26184/26184/18398 +f 26176/26176/18390 26175/26175/18389 26197/26197/18408 +f 26176/26176/18390 26197/26197/18408 26198/26198/18401 +f 26198/26198/18401 26197/26197/18408 26199/26199/18409 +f 26198/26198/18401 26199/26199/18409 26200/26200/18410 +f 26200/26200/18410 26199/26199/18409 26201/26201/18411 +f 26200/26200/18410 26201/26201/18411 26202/26202/18412 +f 26202/26202/18412 26201/26201/18411 26203/26203/18413 +f 26202/26202/18412 26203/26203/18413 26204/26204/18414 +f 26189/26189/18403 26191/26191/18405 26205/26205/18415 +f 26189/26189/18403 26205/26205/18415 26206/26206/18416 +f 26190/26190/18404 26189/26189/18403 26206/26206/18416 +f 26190/26190/18404 26206/26206/18416 26207/26207/18417 +f 26208/26208/18418 26190/26190/18404 26207/26207/18417 +f 26208/26208/18418 26207/26207/18417 26209/26209/18419 +f 26210/26210/18420 26186/26186/18400 26190/26190/18404 +f 26210/26210/18420 26190/26190/18404 26208/26208/18418 +f 26194/26194/18407 26183/26183/18397 26186/26186/18400 +f 26194/26194/18407 26186/26186/18400 26210/26210/18420 +f 26211/26211/18421 26212/26212/18422 26213/26213/18423 +f 26211/26211/18421 26213/26213/18423 26214/26214/18424 +f 26212/26212/18422 26215/26215/18425 26216/26216/18426 +f 26212/26212/18422 26216/26216/18426 26213/26213/18423 +f 26214/26214/18424 26213/26213/18423 26217/26217/18427 +f 26214/26214/18424 26217/26217/18427 26218/26218/18428 +f 26213/26213/18423 26216/26216/18426 26219/26219/18429 +f 26213/26213/18423 26219/26219/18429 26217/26217/18427 +f 26220/26220/18419 26221/26221/18430 26211/26211/18421 +f 26220/26220/18419 26211/26211/18421 26222/26222/18431 +f 26221/26221/18430 26223/26223/18432 26212/26212/18422 +f 26221/26221/18430 26212/26212/18422 26211/26211/18421 +f 26223/26223/18432 26224/26224/18415 26215/26215/18425 +f 26223/26223/18432 26215/26215/18425 26212/26212/18422 +f 26204/26204/18414 26203/26203/18413 26225/26225/18433 +f 26204/26204/18414 26225/26225/18433 26226/26226/18434 +f 26226/26226/18434 26225/26225/18433 26227/26227/18435 +f 26226/26226/18434 26227/26227/18435 26228/26228/18426 +f 26228/26228/18426 26227/26227/18435 26229/26229/18436 +f 26228/26228/18426 26229/26229/18436 26230/26230/18429 +f 26230/26230/18429 26229/26229/18436 26231/26231/18437 +f 26230/26230/18429 26231/26231/18437 26232/26232/18438 +f 26233/26233/18427 26234/26234/18439 26235/26235/18440 +f 26233/26233/18427 26235/26235/18440 26236/26236/18441 +f 26218/26218/18428 26217/26217/18427 26237/26237/18441 +f 26218/26218/18428 26237/26237/18441 26238/26238/18442 +f 26239/26239/18443 26218/26218/18428 26238/26238/18442 +f 26239/26239/18443 26238/26238/18442 26240/26240/18444 +f 26241/26241/18445 26214/26214/18424 26218/26218/18428 +f 26241/26241/18445 26218/26218/18428 26239/26239/18443 +f 26222/26222/18431 26211/26211/18421 26214/26214/18424 +f 26222/26222/18431 26214/26214/18424 26241/26241/18445 +f 26242/26242/18446 26243/26243/18447 26244/26244/18448 +f 26242/26242/18446 26244/26244/18448 26245/26245/18449 +f 26243/26243/18447 26246/26246/18450 26247/26247/18451 +f 26243/26243/18447 26247/26247/18451 26244/26244/18448 +f 26245/26245/18449 26244/26244/18448 26248/26248/18452 +f 26245/26245/18449 26248/26248/18452 26249/26249/18453 +f 26244/26244/18448 26247/26247/18451 26250/26250/18454 +f 26244/26244/18448 26250/26250/18454 26248/26248/18452 +f 26251/26251/18444 26252/26252/18442 26242/26242/18446 +f 26251/26251/18444 26242/26242/18446 26253/26253/18455 +f 26252/26252/18442 26236/26236/18441 26243/26243/18447 +f 26252/26252/18442 26243/26243/18447 26242/26242/18446 +f 26236/26236/18441 26235/26235/18440 26246/26246/18450 +f 26236/26236/18441 26246/26246/18450 26243/26243/18447 +f 26232/26232/18438 26231/26231/18437 26254/26254/18456 +f 26232/26232/18438 26254/26254/18456 26255/26255/18457 +f 26255/26255/18457 26254/26254/18456 26256/26256/18458 +f 26255/26255/18457 26256/26256/18458 26257/26257/18459 +f 26257/26257/18459 26256/26256/18458 26258/26258/18460 +f 26257/26257/18459 26258/26258/18460 26259/26259/18461 +f 26259/26259/18461 26258/26258/18460 26168/26168/18384 +f 26259/26259/18461 26168/26168/18384 26167/26167/18383 +f 26260/26260/18462 26261/26261/18461 26166/26166/18382 +f 26260/26260/18462 26166/26166/18382 26165/26165/18381 +f 26249/26249/18453 26248/26248/18452 26262/26262/18381 +f 26249/26249/18453 26262/26262/18381 26263/26263/18379 +f 26264/26264/18463 26249/26249/18453 26263/26263/18379 +f 26264/26264/18463 26263/26263/18379 26265/26265/18378 +f 26266/26266/18464 26245/26245/18449 26249/26249/18453 +f 26266/26266/18464 26249/26249/18453 26264/26264/18463 +f 26253/26253/18455 26242/26242/18446 26245/26245/18449 +f 26253/26253/18455 26245/26245/18449 26266/26266/18464 +f 26267/26267/18465 26268/26268/18466 26269/26269/18467 +f 26267/26267/18465 26269/26269/18467 26270/26270/18468 +f 26268/26268/18466 26271/26271/18469 26272/26272/18470 +f 26268/26268/18466 26272/26272/18470 26269/26269/18467 +f 26270/26270/18468 26269/26269/18467 26273/26273/18471 +f 26270/26270/18468 26273/26273/18471 26274/26274/18472 +f 26269/26269/18467 26272/26272/18470 26275/26275/18473 +f 26269/26269/18467 26275/26275/18473 26273/26273/18471 +f 26276/26276/18474 26277/26277/18475 26267/26267/18465 +f 26276/26276/18474 26267/26267/18465 26278/26278/18476 +f 26277/26277/18475 26279/26279/18477 26268/26268/18466 +f 26277/26277/18475 26268/26268/18466 26267/26267/18465 +f 26279/26279/18477 26280/26280/18478 26271/26271/18469 +f 26279/26279/18477 26271/26271/18469 26268/26268/18466 +f 26280/26280/18478 26281/26281/18479 26282/26282/18480 +f 26280/26280/18478 26282/26282/18480 26271/26271/18469 +f 26271/26271/18469 26282/26282/18480 26283/26283/18481 +f 26271/26271/18469 26283/26283/18481 26272/26272/18470 +f 26272/26272/18470 26283/26283/18481 26284/26284/18482 +f 26272/26272/18470 26284/26284/18482 26275/26275/18473 +f 26275/26275/18473 26284/26284/18482 26285/26285/18483 +f 26275/26275/18473 26285/26285/18483 26286/26286/18484 +f 26273/26273/18471 26275/26275/18473 26286/26286/18484 +f 26273/26273/18471 26286/26286/18484 26287/26287/18485 +f 26274/26274/18472 26273/26273/18471 26287/26287/18485 +f 26274/26274/18472 26287/26287/18485 26288/26288/18486 +f 26289/26289/18487 26274/26274/18472 26288/26288/18486 +f 26289/26289/18487 26288/26288/18486 26290/26290/18488 +f 26291/26291/18489 26270/26270/18468 26274/26274/18472 +f 26291/26291/18489 26274/26274/18472 26289/26289/18487 +f 26278/26278/18476 26267/26267/18465 26270/26270/18468 +f 26278/26278/18476 26270/26270/18468 26291/26291/18489 +f 26292/26292/18490 26293/26293/18491 26294/26294/18492 +f 26292/26292/18490 26294/26294/18492 26295/26295/18493 +f 26293/26293/18491 26296/26296/18494 26297/26297/18495 +f 26293/26293/18491 26297/26297/18495 26294/26294/18492 +f 26295/26295/18493 26294/26294/18492 26298/26298/18496 +f 26295/26295/18493 26298/26298/18496 26299/26299/18497 +f 26294/26294/18492 26297/26297/18495 26300/26300/18498 +f 26294/26294/18492 26300/26300/18498 26298/26298/18496 +f 26301/26301/18499 26302/26302/18500 26292/26292/18490 +f 26301/26301/18499 26292/26292/18490 26303/26303/18501 +f 26302/26302/18500 26304/26304/18502 26293/26293/18491 +f 26302/26302/18500 26293/26293/18491 26292/26292/18490 +f 26304/26304/18502 26305/26305/18503 26296/26296/18494 +f 26304/26304/18502 26296/26296/18494 26293/26293/18491 +f 26305/26305/18503 26306/26306/18504 26307/26307/18505 +f 26305/26305/18503 26307/26307/18505 26296/26296/18494 +f 26296/26296/18494 26307/26307/18505 26308/26308/18506 +f 26296/26296/18494 26308/26308/18506 26297/26297/18495 +f 26297/26297/18495 26308/26308/18506 26309/26309/18507 +f 26297/26297/18495 26309/26309/18507 26300/26300/18498 +f 26300/26300/18498 26309/26309/18507 26175/26175/18389 +f 26300/26300/18498 26175/26175/18389 26173/26173/18388 +f 26298/26298/18496 26300/26300/18498 26173/26173/18388 +f 26298/26298/18496 26173/26173/18388 26171/26171/18386 +f 26299/26299/18497 26298/26298/18496 26171/26171/18386 +f 26299/26299/18497 26171/26171/18386 26169/26169/18385 +f 26310/26310/18508 26299/26299/18497 26169/26169/18385 +f 26310/26310/18508 26169/26169/18385 26168/26168/18384 +f 26311/26311/18509 26295/26295/18493 26299/26299/18497 +f 26311/26311/18509 26299/26299/18497 26310/26310/18508 +f 26303/26303/18501 26292/26292/18490 26295/26295/18493 +f 26303/26303/18501 26295/26295/18493 26311/26311/18509 +f 26312/26312/18510 26313/26313/18511 26314/26314/18512 +f 26312/26312/18510 26314/26314/18512 26315/26315/18513 +f 26313/26313/18511 26316/26316/18514 26317/26317/18515 +f 26313/26313/18511 26317/26317/18515 26314/26314/18512 +f 26315/26315/18513 26314/26314/18512 26318/26318/18516 +f 26315/26315/18513 26318/26318/18516 26319/26319/18517 +f 26314/26314/18512 26317/26317/18515 26320/26320/18518 +f 26314/26314/18512 26320/26320/18518 26318/26318/18516 +f 26306/26306/18504 26321/26321/18519 26312/26312/18510 +f 26306/26306/18504 26312/26312/18510 26307/26307/18505 +f 26321/26321/18519 26322/26322/18520 26313/26313/18511 +f 26321/26321/18519 26313/26313/18511 26312/26312/18510 +f 26322/26322/18520 26323/26323/18521 26316/26316/18514 +f 26322/26322/18520 26316/26316/18514 26313/26313/18511 +f 26323/26323/18521 26324/26324/18522 26325/26325/18523 +f 26323/26323/18521 26325/26325/18523 26316/26316/18514 +f 26316/26316/18514 26325/26325/18523 26326/26326/18524 +f 26316/26316/18514 26326/26326/18524 26317/26317/18515 +f 26317/26317/18515 26326/26326/18524 26327/26327/18525 +f 26317/26317/18515 26327/26327/18525 26320/26320/18518 +f 26320/26320/18518 26327/26327/18525 26203/26203/18413 +f 26320/26320/18518 26203/26203/18413 26201/26201/18411 +f 26318/26318/18516 26320/26320/18518 26201/26201/18411 +f 26318/26318/18516 26201/26201/18411 26199/26199/18409 +f 26319/26319/18517 26318/26318/18516 26199/26199/18409 +f 26319/26319/18517 26199/26199/18409 26197/26197/18408 +f 26309/26309/18507 26319/26319/18517 26197/26197/18408 +f 26309/26309/18507 26197/26197/18408 26175/26175/18389 +f 26308/26308/18506 26315/26315/18513 26319/26319/18517 +f 26308/26308/18506 26319/26319/18517 26309/26309/18507 +f 26307/26307/18505 26312/26312/18510 26315/26315/18513 +f 26307/26307/18505 26315/26315/18513 26308/26308/18506 +f 26328/26328/18526 26329/26329/18527 26330/26330/18528 +f 26328/26328/18526 26330/26330/18528 26331/26331/18529 +f 26329/26329/18527 26332/26332/18530 26333/26333/18531 +f 26329/26329/18527 26333/26333/18531 26330/26330/18528 +f 26331/26331/18529 26330/26330/18528 26334/26334/18532 +f 26331/26331/18529 26334/26334/18532 26335/26335/18533 +f 26330/26330/18528 26333/26333/18531 26336/26336/18534 +f 26330/26330/18528 26336/26336/18534 26334/26334/18532 +f 26324/26324/18522 26337/26337/18535 26328/26328/18526 +f 26324/26324/18522 26328/26328/18526 26325/26325/18523 +f 26337/26337/18535 26338/26338/18536 26329/26329/18527 +f 26337/26337/18535 26329/26329/18527 26328/26328/18526 +f 26338/26338/18536 26339/26339/18537 26332/26332/18530 +f 26338/26338/18536 26332/26332/18530 26329/26329/18527 +f 26339/26339/18537 26340/26340/18538 26341/26341/18539 +f 26339/26339/18537 26341/26341/18539 26332/26332/18530 +f 26332/26332/18530 26341/26341/18539 26342/26342/18540 +f 26332/26332/18530 26342/26342/18540 26333/26333/18531 +f 26333/26333/18531 26342/26342/18540 26343/26343/18541 +f 26333/26333/18531 26343/26343/18541 26336/26336/18534 +f 26336/26336/18534 26343/26343/18541 26231/26231/18437 +f 26336/26336/18534 26231/26231/18437 26229/26229/18436 +f 26334/26334/18532 26336/26336/18534 26229/26229/18436 +f 26334/26334/18532 26229/26229/18436 26227/26227/18435 +f 26335/26335/18533 26334/26334/18532 26227/26227/18435 +f 26335/26335/18533 26227/26227/18435 26225/26225/18433 +f 26327/26327/18525 26335/26335/18533 26225/26225/18433 +f 26327/26327/18525 26225/26225/18433 26203/26203/18413 +f 26326/26326/18524 26331/26331/18529 26335/26335/18533 +f 26326/26326/18524 26335/26335/18533 26327/26327/18525 +f 26325/26325/18523 26328/26328/18526 26331/26331/18529 +f 26325/26325/18523 26331/26331/18529 26326/26326/18524 +f 26344/26344/18542 26345/26345/18543 26346/26346/18544 +f 26344/26344/18542 26346/26346/18544 26347/26347/18545 +f 26345/26345/18543 26348/26348/18546 26349/26349/18547 +f 26345/26345/18543 26349/26349/18547 26346/26346/18544 +f 26347/26347/18545 26346/26346/18544 26350/26350/18548 +f 26347/26347/18545 26350/26350/18548 26351/26351/18549 +f 26346/26346/18544 26349/26349/18547 26352/26352/18550 +f 26346/26346/18544 26352/26352/18550 26350/26350/18548 +f 26340/26340/18538 26353/26353/18551 26344/26344/18542 +f 26340/26340/18538 26344/26344/18542 26341/26341/18539 +f 26353/26353/18551 26354/26354/18552 26345/26345/18543 +f 26353/26353/18551 26345/26345/18543 26344/26344/18542 +f 26354/26354/18552 26355/26355/18553 26348/26348/18546 +f 26354/26354/18552 26348/26348/18546 26345/26345/18543 +f 26355/26355/18553 26301/26301/18499 26303/26303/18501 +f 26355/26355/18553 26303/26303/18501 26348/26348/18546 +f 26348/26348/18546 26303/26303/18501 26311/26311/18509 +f 26348/26348/18546 26311/26311/18509 26349/26349/18547 +f 26349/26349/18547 26311/26311/18509 26310/26310/18508 +f 26349/26349/18547 26310/26310/18508 26352/26352/18550 +f 26352/26352/18550 26310/26310/18508 26168/26168/18384 +f 26352/26352/18550 26168/26168/18384 26258/26258/18460 +f 26350/26350/18548 26352/26352/18550 26258/26258/18460 +f 26350/26350/18548 26258/26258/18460 26256/26256/18458 +f 26351/26351/18549 26350/26350/18548 26256/26256/18458 +f 26351/26351/18549 26256/26256/18458 26254/26254/18456 +f 26343/26343/18541 26351/26351/18549 26254/26254/18456 +f 26343/26343/18541 26254/26254/18456 26231/26231/18437 +f 26342/26342/18540 26347/26347/18545 26351/26351/18549 +f 26342/26342/18540 26351/26351/18549 26343/26343/18541 +f 26341/26341/18539 26344/26344/18542 26347/26347/18545 +f 26341/26341/18539 26347/26347/18545 26342/26342/18540 +f 26356/26356/18554 26357/26357/18555 26358/26358/18556 +f 26356/26356/18554 26358/26358/18556 26359/26359/18557 +f 26357/26357/18555 26360/26360/18558 26361/26361/18559 +f 26357/26357/18555 26361/26361/18559 26358/26358/18556 +f 26359/26359/18557 26358/26358/18556 26362/26362/18560 +f 26359/26359/18557 26362/26362/18560 26363/26363/18561 +f 26358/26358/18556 26361/26361/18559 26364/26364/18562 +f 26358/26358/18556 26364/26364/18562 26362/26362/18560 +f 26365/26365/18563 26366/26366/18564 26356/26356/18554 +f 26365/26365/18563 26356/26356/18554 26367/26367/18565 +f 26366/26366/18564 26368/26368/18566 26357/26357/18555 +f 26366/26366/18564 26357/26357/18555 26356/26356/18554 +f 26368/26368/18566 26369/26369/18567 26360/26360/18558 +f 26368/26368/18566 26360/26360/18558 26357/26357/18555 +f 26369/26369/18567 26281/26281/18479 26370/26370/18568 +f 26369/26369/18567 26370/26370/18568 26360/26360/18558 +f 26360/26360/18558 26370/26370/18568 26371/26371/18569 +f 26360/26360/18558 26371/26371/18569 26361/26361/18559 +f 26361/26361/18559 26371/26371/18569 26372/26372/18570 +f 26361/26361/18559 26372/26372/18570 26364/26364/18562 +f 26364/26364/18562 26372/26372/18570 26306/26306/18504 +f 26364/26364/18562 26306/26306/18504 26305/26305/18503 +f 26362/26362/18560 26364/26364/18562 26305/26305/18503 +f 26362/26362/18560 26305/26305/18503 26304/26304/18502 +f 26363/26363/18561 26362/26362/18560 26304/26304/18502 +f 26363/26363/18561 26304/26304/18502 26302/26302/18500 +f 26373/26373/18571 26363/26363/18561 26302/26302/18500 +f 26373/26373/18571 26302/26302/18500 26301/26301/18499 +f 26374/26374/18572 26359/26359/18557 26363/26363/18561 +f 26374/26374/18572 26363/26363/18561 26373/26373/18571 +f 26367/26367/18565 26356/26356/18554 26359/26359/18557 +f 26367/26367/18565 26359/26359/18557 26374/26374/18572 +f 26375/26375/18573 26376/26376/18574 26377/26377/18575 +f 26375/26375/18573 26377/26377/18575 26378/26378/18576 +f 26376/26376/18574 26379/26379/18577 26380/26380/18578 +f 26376/26376/18574 26380/26380/18578 26377/26377/18575 +f 26378/26378/18576 26377/26377/18575 26381/26381/18579 +f 26378/26378/18576 26381/26381/18579 26382/26382/18580 +f 26377/26377/18575 26380/26380/18578 26383/26383/18581 +f 26377/26377/18575 26383/26383/18581 26381/26381/18579 +f 26281/26281/18479 26280/26280/18478 26375/26375/18573 +f 26281/26281/18479 26375/26375/18573 26370/26370/18568 +f 26280/26280/18478 26279/26279/18477 26376/26376/18574 +f 26280/26280/18478 26376/26376/18574 26375/26375/18573 +f 26279/26279/18477 26277/26277/18475 26379/26379/18577 +f 26279/26279/18477 26379/26379/18577 26376/26376/18574 +f 26277/26277/18475 26276/26276/18474 26384/26384/18582 +f 26277/26277/18475 26384/26384/18582 26379/26379/18577 +f 26379/26379/18577 26384/26384/18582 26385/26385/18583 +f 26379/26379/18577 26385/26385/18583 26380/26380/18578 +f 26380/26380/18578 26385/26385/18583 26386/26386/18584 +f 26380/26380/18578 26386/26386/18584 26383/26383/18581 +f 26383/26383/18581 26386/26386/18584 26324/26324/18522 +f 26383/26383/18581 26324/26324/18522 26323/26323/18521 +f 26381/26381/18579 26383/26383/18581 26323/26323/18521 +f 26381/26381/18579 26323/26323/18521 26322/26322/18520 +f 26382/26382/18580 26381/26381/18579 26322/26322/18520 +f 26382/26382/18580 26322/26322/18520 26321/26321/18519 +f 26372/26372/18570 26382/26382/18580 26321/26321/18519 +f 26372/26372/18570 26321/26321/18519 26306/26306/18504 +f 26371/26371/18569 26378/26378/18576 26382/26382/18580 +f 26371/26371/18569 26382/26382/18580 26372/26372/18570 +f 26370/26370/18568 26375/26375/18573 26378/26378/18576 +f 26370/26370/18568 26378/26378/18576 26371/26371/18569 +f 26387/26387/18585 26388/26388/18586 26389/26389/18587 +f 26387/26387/18585 26389/26389/18587 26390/26390/18588 +f 26388/26388/18586 26391/26391/18589 26392/26392/18590 +f 26388/26388/18586 26392/26392/18590 26389/26389/18587 +f 26390/26390/18588 26389/26389/18587 26393/26393/18591 +f 26390/26390/18588 26393/26393/18591 26394/26394/18592 +f 26389/26389/18587 26392/26392/18590 26395/26395/18593 +f 26389/26389/18587 26395/26395/18593 26393/26393/18591 +f 26276/26276/18474 26396/26396/18594 26387/26387/18585 +f 26276/26276/18474 26387/26387/18585 26384/26384/18582 +f 26396/26396/18594 26397/26397/18595 26388/26388/18586 +f 26396/26396/18594 26388/26388/18586 26387/26387/18585 +f 26397/26397/18595 26398/26398/18596 26391/26391/18589 +f 26397/26397/18595 26391/26391/18589 26388/26388/18586 +f 26398/26398/18596 26399/26399/18597 26400/26400/18598 +f 26398/26398/18596 26400/26400/18598 26391/26391/18589 +f 26391/26391/18589 26400/26400/18598 26401/26401/18599 +f 26391/26391/18589 26401/26401/18599 26392/26392/18590 +f 26392/26392/18590 26401/26401/18599 26402/26402/18600 +f 26392/26392/18590 26402/26402/18600 26395/26395/18593 +f 26395/26395/18593 26402/26402/18600 26340/26340/18538 +f 26395/26395/18593 26340/26340/18538 26339/26339/18537 +f 26393/26393/18591 26395/26395/18593 26339/26339/18537 +f 26393/26393/18591 26339/26339/18537 26338/26338/18536 +f 26394/26394/18592 26393/26393/18591 26338/26338/18536 +f 26394/26394/18592 26338/26338/18536 26337/26337/18535 +f 26386/26386/18584 26394/26394/18592 26337/26337/18535 +f 26386/26386/18584 26337/26337/18535 26324/26324/18522 +f 26385/26385/18583 26390/26390/18588 26394/26394/18592 +f 26385/26385/18583 26394/26394/18592 26386/26386/18584 +f 26384/26384/18582 26387/26387/18585 26390/26390/18588 +f 26384/26384/18582 26390/26390/18588 26385/26385/18583 +f 26403/26403/18601 26404/26404/18602 26405/26405/18603 +f 26403/26403/18601 26405/26405/18603 26406/26406/18604 +f 26404/26404/18602 26407/26407/18605 26408/26408/18606 +f 26404/26404/18602 26408/26408/18606 26405/26405/18603 +f 26406/26406/18604 26405/26405/18603 26409/26409/18607 +f 26406/26406/18604 26409/26409/18607 26410/26410/18608 +f 26405/26405/18603 26408/26408/18606 26411/26411/18609 +f 26405/26405/18603 26411/26411/18609 26409/26409/18607 +f 26399/26399/18597 26412/26412/18610 26403/26403/18601 +f 26399/26399/18597 26403/26403/18601 26400/26400/18598 +f 26412/26412/18610 26413/26413/18611 26404/26404/18602 +f 26412/26412/18610 26404/26404/18602 26403/26403/18601 +f 26413/26413/18611 26414/26414/18612 26407/26407/18605 +f 26413/26413/18611 26407/26407/18605 26404/26404/18602 +f 26414/26414/18612 26365/26365/18563 26367/26367/18565 +f 26414/26414/18612 26367/26367/18565 26407/26407/18605 +f 26407/26407/18605 26367/26367/18565 26374/26374/18572 +f 26407/26407/18605 26374/26374/18572 26408/26408/18606 +f 26408/26408/18606 26374/26374/18572 26373/26373/18571 +f 26408/26408/18606 26373/26373/18571 26411/26411/18609 +f 26411/26411/18609 26373/26373/18571 26301/26301/18499 +f 26411/26411/18609 26301/26301/18499 26355/26355/18553 +f 26409/26409/18607 26411/26411/18609 26355/26355/18553 +f 26409/26409/18607 26355/26355/18553 26354/26354/18552 +f 26410/26410/18608 26409/26409/18607 26354/26354/18552 +f 26410/26410/18608 26354/26354/18552 26353/26353/18551 +f 26402/26402/18600 26410/26410/18608 26353/26353/18551 +f 26402/26402/18600 26353/26353/18551 26340/26340/18538 +f 26401/26401/18599 26406/26406/18604 26410/26410/18608 +f 26401/26401/18599 26410/26410/18608 26402/26402/18600 +f 26400/26400/18598 26403/26403/18601 26406/26406/18604 +f 26400/26400/18598 26406/26406/18604 26401/26401/18599 +f 26415/26415/18613 26416/26416/18614 26417/26417/18615 +f 26415/26415/18613 26417/26417/18615 26418/26418/18616 +f 26416/26416/18614 26419/26419/18617 26420/26420/18618 +f 26416/26416/18614 26420/26420/18618 26417/26417/18615 +f 26418/26418/18616 26417/26417/18615 26421/26421/18619 +f 26418/26418/18616 26421/26421/18619 26422/26422/18620 +f 26417/26417/18615 26420/26420/18618 26423/26423/18621 +f 26417/26417/18615 26423/26423/18621 26421/26421/18619 +f 26424/26424/18622 26425/26425/18623 26415/26415/18613 +f 26424/26424/18622 26415/26415/18613 26426/26426/18624 +f 26425/26425/18623 26427/26427/18625 26416/26416/18614 +f 26425/26425/18623 26416/26416/18614 26415/26415/18613 +f 26427/26427/18625 26428/26428/18626 26419/26419/18617 +f 26427/26427/18625 26419/26419/18617 26416/26416/18614 +f 26428/26428/18626 26429/26429/18627 26430/26430/18628 +f 26428/26428/18626 26430/26430/18628 26419/26419/18617 +f 26419/26419/18617 26430/26430/18628 26431/26431/18629 +f 26419/26419/18617 26431/26431/18629 26420/26420/18618 +f 26420/26420/18618 26431/26431/18629 26432/26432/18630 +f 26420/26420/18618 26432/26432/18630 26423/26423/18621 +f 26423/26423/18621 26432/26432/18630 26433/26433/18631 +f 26423/26423/18621 26433/26433/18631 26434/26434/18632 +f 26421/26421/18619 26423/26423/18621 26434/26434/18632 +f 26421/26421/18619 26434/26434/18632 26435/26435/18633 +f 26422/26422/18620 26421/26421/18619 26435/26435/18633 +f 26422/26422/18620 26435/26435/18633 26436/26436/18634 +f 26437/26437/18635 26422/26422/18620 26436/26436/18634 +f 26437/26437/18635 26436/26436/18634 26438/26438/18636 +f 26439/26439/18637 26418/26418/18616 26422/26422/18620 +f 26439/26439/18637 26422/26422/18620 26437/26437/18635 +f 26426/26426/18624 26415/26415/18613 26418/26418/18616 +f 26426/26426/18624 26418/26418/18616 26439/26439/18637 +f 26440/26440/18638 26441/26441/18639 26442/26442/18640 +f 26440/26440/18638 26442/26442/18640 26443/26443/18641 +f 26441/26441/18639 26444/26444/18642 26445/26445/18643 +f 26441/26441/18639 26445/26445/18643 26442/26442/18640 +f 26443/26443/18641 26442/26442/18640 26446/26446/18644 +f 26443/26443/18641 26446/26446/18644 26447/26447/18645 +f 26442/26442/18640 26445/26445/18643 26448/26448/18646 +f 26442/26442/18640 26448/26448/18646 26446/26446/18644 +f 26399/26399/18597 26398/26398/18596 26440/26440/18638 +f 26399/26399/18597 26440/26440/18638 26449/26449/18647 +f 26398/26398/18596 26397/26397/18595 26441/26441/18639 +f 26398/26398/18596 26441/26441/18639 26440/26440/18638 +f 26397/26397/18595 26396/26396/18594 26444/26444/18642 +f 26397/26397/18595 26444/26444/18642 26441/26441/18639 +f 26396/26396/18594 26276/26276/18474 26278/26278/18476 +f 26396/26396/18594 26278/26278/18476 26444/26444/18642 +f 26444/26444/18642 26278/26278/18476 26291/26291/18489 +f 26444/26444/18642 26291/26291/18489 26445/26445/18643 +f 26445/26445/18643 26291/26291/18489 26289/26289/18487 +f 26445/26445/18643 26289/26289/18487 26448/26448/18646 +f 26448/26448/18646 26289/26289/18487 26290/26290/18488 +f 26448/26448/18646 26290/26290/18488 26450/26450/18648 +f 26446/26446/18644 26448/26448/18646 26450/26450/18648 +f 26446/26446/18644 26450/26450/18648 26451/26451/18649 +f 26447/26447/18645 26446/26446/18644 26451/26451/18649 +f 26447/26447/18645 26451/26451/18649 26452/26452/18650 +f 26453/26453/18651 26447/26447/18645 26452/26452/18650 +f 26453/26453/18651 26452/26452/18650 26454/26454/18652 +f 26455/26455/18653 26443/26443/18641 26447/26447/18645 +f 26455/26455/18653 26447/26447/18645 26453/26453/18651 +f 26449/26449/18647 26440/26440/18638 26443/26443/18641 +f 26449/26449/18647 26443/26443/18641 26455/26455/18653 +f 26456/26456/18654 26457/26457/18655 26458/26458/18656 +f 26456/26456/18654 26458/26458/18656 26459/26459/18657 +f 26457/26457/18655 26460/26460/18658 26461/26461/18659 +f 26457/26457/18655 26461/26461/18659 26458/26458/18656 +f 26459/26459/18657 26458/26458/18656 26462/26462/18660 +f 26459/26459/18657 26462/26462/18660 26463/26463/18661 +f 26458/26458/18656 26461/26461/18659 26464/26464/18662 +f 26458/26458/18656 26464/26464/18662 26462/26462/18660 +f 26281/26281/18479 26369/26369/18567 26456/26456/18654 +f 26281/26281/18479 26456/26456/18654 26282/26282/18480 +f 26369/26369/18567 26368/26368/18566 26457/26457/18655 +f 26369/26369/18567 26457/26457/18655 26456/26456/18654 +f 26368/26368/18566 26366/26366/18564 26460/26460/18658 +f 26368/26368/18566 26460/26460/18658 26457/26457/18655 +f 26366/26366/18564 26365/26365/18563 26465/26465/18663 +f 26366/26366/18564 26465/26465/18663 26460/26460/18658 +f 26460/26460/18658 26465/26465/18663 26466/26466/18664 +f 26460/26460/18658 26466/26466/18664 26461/26461/18659 +f 26461/26461/18659 26466/26466/18664 26467/26467/18665 +f 26461/26461/18659 26467/26467/18665 26464/26464/18662 +f 26464/26464/18662 26467/26467/18665 26468/26468/18666 +f 26464/26464/18662 26468/26468/18666 26469/26469/18667 +f 26462/26462/18660 26464/26464/18662 26469/26469/18667 +f 26462/26462/18660 26469/26469/18667 26470/26470/18668 +f 26463/26463/18661 26462/26462/18660 26470/26470/18668 +f 26463/26463/18661 26470/26470/18668 26471/26471/18669 +f 26284/26284/18482 26463/26463/18661 26471/26471/18669 +f 26284/26284/18482 26471/26471/18669 26285/26285/18483 +f 26283/26283/18481 26459/26459/18657 26463/26463/18661 +f 26283/26283/18481 26463/26463/18661 26284/26284/18482 +f 26282/26282/18480 26456/26456/18654 26459/26459/18657 +f 26282/26282/18480 26459/26459/18657 26283/26283/18481 +f 26472/26472/18670 26473/26473/18671 26474/26474/18672 +f 26472/26472/18670 26474/26474/18672 26475/26475/18673 +f 26473/26473/18671 26476/26476/18674 26477/26477/18675 +f 26473/26473/18671 26477/26477/18675 26474/26474/18672 +f 26475/26475/18673 26474/26474/18672 26478/26478/18676 +f 26475/26475/18673 26478/26478/18676 26479/26479/18677 +f 26474/26474/18672 26477/26477/18675 26480/26480/18678 +f 26474/26474/18672 26480/26480/18678 26478/26478/18676 +f 26365/26365/18563 26414/26414/18612 26472/26472/18670 +f 26365/26365/18563 26472/26472/18670 26465/26465/18663 +f 26414/26414/18612 26413/26413/18611 26473/26473/18671 +f 26414/26414/18612 26473/26473/18671 26472/26472/18670 +f 26413/26413/18611 26412/26412/18610 26476/26476/18674 +f 26413/26413/18611 26476/26476/18674 26473/26473/18671 +f 26412/26412/18610 26399/26399/18597 26449/26449/18647 +f 26412/26412/18610 26449/26449/18647 26476/26476/18674 +f 26476/26476/18674 26449/26449/18647 26455/26455/18653 +f 26476/26476/18674 26455/26455/18653 26477/26477/18675 +f 26477/26477/18675 26455/26455/18653 26453/26453/18651 +f 26477/26477/18675 26453/26453/18651 26480/26480/18678 +f 26480/26480/18678 26453/26453/18651 26454/26454/18652 +f 26480/26480/18678 26454/26454/18652 26481/26481/18679 +f 26478/26478/18676 26480/26480/18678 26481/26481/18679 +f 26478/26478/18676 26481/26481/18679 26482/26482/18680 +f 26479/26479/18677 26478/26478/18676 26482/26482/18680 +f 26479/26479/18677 26482/26482/18680 26483/26483/18681 +f 26467/26467/18665 26479/26479/18677 26483/26483/18681 +f 26467/26467/18665 26483/26483/18681 26468/26468/18666 +f 26466/26466/18664 26475/26475/18673 26479/26479/18677 +f 26466/26466/18664 26479/26479/18677 26467/26467/18665 +f 26465/26465/18663 26472/26472/18670 26475/26475/18673 +f 26465/26465/18663 26475/26475/18673 26466/26466/18664 +f 26484/26484/18682 26485/26485/18683 26486/26486/18684 +f 26484/26484/18682 26486/26486/18684 26487/26487/18685 +f 26485/26485/18683 26488/26488/18686 26489/26489/18687 +f 26485/26485/18683 26489/26489/18687 26486/26486/18684 +f 26487/26487/18685 26486/26486/18684 26490/26490/18688 +f 26487/26487/18685 26490/26490/18688 26491/26491/18689 +f 26486/26486/18684 26489/26489/18687 26492/26492/18690 +f 26486/26486/18684 26492/26492/18690 26490/26490/18688 +f 26493/26493/18691 26494/26494/18692 26495/26495/18682 +f 26493/26493/18691 26495/26495/18682 26496/26496/18693 +f 26494/26494/18692 26497/26497/18694 26498/26498/18695 +f 26494/26494/18692 26498/26498/18695 26495/26495/18682 +f 26497/26497/18694 26499/26499/18696 26500/26500/18686 +f 26497/26497/18694 26500/26500/18686 26498/26498/18695 +f 26499/26499/18696 26501/26501/18697 26502/26502/18698 +f 26499/26499/18696 26502/26502/18698 26500/26500/18686 +f 26488/26488/18686 26503/26503/18699 26504/26504/18700 +f 26488/26488/18686 26504/26504/18700 26489/26489/18687 +f 26489/26489/18687 26504/26504/18700 26505/26505/18701 +f 26489/26489/18687 26505/26505/18701 26492/26492/18690 +f 26492/26492/18690 26505/26505/18701 26285/26285/18483 +f 26492/26492/18690 26285/26285/18483 26471/26471/18669 +f 26490/26490/18688 26492/26492/18690 26471/26471/18669 +f 26490/26490/18688 26471/26471/18669 26470/26470/18668 +f 26491/26491/18689 26490/26490/18688 26470/26470/18668 +f 26491/26491/18689 26470/26470/18668 26469/26469/18667 +f 26506/26506/18702 26491/26491/18689 26469/26469/18667 +f 26506/26506/18702 26469/26469/18667 26468/26468/18666 +f 26507/26507/18703 26487/26487/18685 26491/26491/18689 +f 26507/26507/18703 26491/26491/18689 26506/26506/18702 +f 26508/26508/18704 26484/26484/18682 26487/26487/18685 +f 26508/26508/18704 26487/26487/18685 26507/26507/18703 +f 26509/26509/18705 26510/26510/18706 26511/26511/18707 +f 26509/26509/18705 26511/26511/18707 26512/26512/18708 +f 26510/26510/18706 26513/26513/18709 26514/26514/18710 +f 26510/26510/18706 26514/26514/18710 26511/26511/18707 +f 26512/26512/18708 26511/26511/18707 26515/26515/18711 +f 26512/26512/18708 26515/26515/18711 26516/26516/18712 +f 26511/26511/18707 26514/26514/18710 26517/26517/18713 +f 26511/26511/18707 26517/26517/18713 26515/26515/18711 +f 26518/26518/18697 26519/26519/18714 26520/26520/18705 +f 26518/26518/18697 26520/26520/18705 26521/26521/18715 +f 26522/26522/18716 26523/26523/18717 26510/26510/18706 +f 26522/26522/18716 26510/26510/18706 26509/26509/18705 +f 26523/26523/18717 26524/26524/18718 26513/26513/18709 +f 26523/26523/18717 26513/26513/18709 26510/26510/18706 +f 26525/26525/18719 26526/26526/18720 26527/26527/18721 +f 26525/26525/18719 26527/26527/18721 26528/26528/18722 +f 26513/26513/18709 26529/26529/18721 26530/26530/18723 +f 26513/26513/18709 26530/26530/18723 26514/26514/18710 +f 26514/26514/18710 26530/26530/18723 26531/26531/18724 +f 26514/26514/18710 26531/26531/18724 26517/26517/18713 +f 26517/26517/18713 26531/26531/18724 26290/26290/18488 +f 26517/26517/18713 26290/26290/18488 26288/26288/18486 +f 26515/26515/18711 26517/26517/18713 26288/26288/18486 +f 26515/26515/18711 26288/26288/18486 26287/26287/18485 +f 26516/26516/18712 26515/26515/18711 26287/26287/18485 +f 26516/26516/18712 26287/26287/18485 26286/26286/18484 +f 26505/26505/18701 26516/26516/18712 26286/26286/18484 +f 26505/26505/18701 26286/26286/18484 26285/26285/18483 +f 26504/26504/18700 26512/26512/18708 26516/26516/18712 +f 26504/26504/18700 26516/26516/18712 26505/26505/18701 +f 26503/26503/18699 26509/26509/18705 26512/26512/18708 +f 26503/26503/18699 26512/26512/18708 26504/26504/18700 +f 26532/26532/18725 26533/26533/18726 26534/26534/18727 +f 26532/26532/18725 26534/26534/18727 26535/26535/18728 +f 26533/26533/18726 26536/26536/18729 26537/26537/18730 +f 26533/26533/18726 26537/26537/18730 26534/26534/18727 +f 26535/26535/18728 26534/26534/18727 26538/26538/18731 +f 26535/26535/18728 26538/26538/18731 26539/26539/18732 +f 26534/26534/18727 26537/26537/18730 26540/26540/18733 +f 26534/26534/18727 26540/26540/18733 26538/26538/18731 +f 26541/26541/18720 26542/26542/18734 26543/26543/18725 +f 26541/26541/18720 26543/26543/18725 26544/26544/18721 +f 26542/26542/18734 26545/26545/18735 26546/26546/18736 +f 26542/26542/18734 26546/26546/18736 26543/26543/18725 +f 26545/26545/18735 26547/26547/18737 26548/26548/18738 +f 26545/26545/18735 26548/26548/18738 26546/26546/18736 +f 26549/26549/18737 26550/26550/18739 26551/26551/18740 +f 26549/26549/18737 26551/26551/18740 26552/26552/18738 +f 26536/26536/18729 26553/26553/18741 26554/26554/18742 +f 26536/26536/18729 26554/26554/18742 26537/26537/18730 +f 26537/26537/18730 26554/26554/18742 26555/26555/18743 +f 26537/26537/18730 26555/26555/18743 26540/26540/18733 +f 26540/26540/18733 26555/26555/18743 26454/26454/18652 +f 26540/26540/18733 26454/26454/18652 26452/26452/18650 +f 26538/26538/18731 26540/26540/18733 26452/26452/18650 +f 26538/26538/18731 26452/26452/18650 26451/26451/18649 +f 26539/26539/18732 26538/26538/18731 26451/26451/18649 +f 26539/26539/18732 26451/26451/18649 26450/26450/18648 +f 26531/26531/18724 26539/26539/18732 26450/26450/18648 +f 26531/26531/18724 26450/26450/18648 26290/26290/18488 +f 26530/26530/18723 26535/26535/18728 26539/26539/18732 +f 26530/26530/18723 26539/26539/18732 26531/26531/18724 +f 26529/26529/18721 26532/26532/18725 26535/26535/18728 +f 26529/26529/18721 26535/26535/18728 26530/26530/18723 +f 26556/26556/18744 26557/26557/18745 26558/26558/18746 +f 26556/26556/18744 26558/26558/18746 26559/26559/18747 +f 26557/26557/18745 26560/26560/18748 26561/26561/18749 +f 26557/26557/18745 26561/26561/18749 26558/26558/18746 +f 26559/26559/18747 26558/26558/18746 26562/26562/18750 +f 26559/26559/18747 26562/26562/18750 26563/26563/18751 +f 26558/26558/18746 26561/26561/18749 26564/26564/18752 +f 26558/26558/18746 26564/26564/18752 26562/26562/18750 +f 26550/26550/18739 26565/26565/18753 26566/26566/18754 +f 26550/26550/18739 26566/26566/18754 26551/26551/18740 +f 26567/26567/18753 26568/26568/18755 26557/26557/18745 +f 26567/26567/18753 26557/26557/18745 26556/26556/18744 +f 26568/26568/18755 26569/26569/18756 26560/26560/18748 +f 26568/26568/18755 26560/26560/18748 26557/26557/18745 +f 26570/26570/18756 26571/26571/18691 26572/26572/18693 +f 26570/26570/18756 26572/26572/18693 26573/26573/18748 +f 26560/26560/18748 26508/26508/18704 26507/26507/18703 +f 26560/26560/18748 26507/26507/18703 26561/26561/18749 +f 26561/26561/18749 26507/26507/18703 26506/26506/18702 +f 26561/26561/18749 26506/26506/18702 26564/26564/18752 +f 26564/26564/18752 26506/26506/18702 26468/26468/18666 +f 26564/26564/18752 26468/26468/18666 26483/26483/18681 +f 26562/26562/18750 26564/26564/18752 26483/26483/18681 +f 26562/26562/18750 26483/26483/18681 26482/26482/18680 +f 26563/26563/18751 26562/26562/18750 26482/26482/18680 +f 26563/26563/18751 26482/26482/18680 26481/26481/18679 +f 26555/26555/18743 26563/26563/18751 26481/26481/18679 +f 26555/26555/18743 26481/26481/18679 26454/26454/18652 +f 26554/26554/18742 26559/26559/18747 26563/26563/18751 +f 26554/26554/18742 26563/26563/18751 26555/26555/18743 +f 26553/26553/18741 26556/26556/18744 26559/26559/18747 +f 26553/26553/18741 26559/26559/18747 26554/26554/18742 +f 26574/26574/18757 26575/26575/18758 26576/26576/18759 +f 26574/26574/18757 26576/26576/18759 26577/26577/18760 +f 26578/26578/18758 26579/26579/18761 26580/26580/18762 +f 26578/26578/18758 26580/26580/18762 26581/26581/18763 +f 26577/26577/18760 26576/26576/18759 26582/26582/18764 +f 26577/26577/18760 26582/26582/18764 26583/26583/18765 +f 26581/26581/18763 26580/26580/18762 26584/26584/18766 +f 26581/26581/18763 26584/26584/18766 26585/26585/18764 +f 26586/26586/18767 26587/26587/18768 26574/26574/18757 +f 26586/26586/18767 26574/26574/18757 26588/26588/18769 +f 26587/26587/18768 26589/26589/18770 26575/26575/18758 +f 26587/26587/18768 26575/26575/18758 26574/26574/18757 +f 26590/26590/18770 26591/26591/18771 26579/26579/18761 +f 26590/26590/18770 26579/26579/18761 26578/26578/18758 +f 26591/26591/18771 26424/26424/18622 26426/26426/18624 +f 26591/26591/18771 26426/26426/18624 26579/26579/18761 +f 26579/26579/18761 26426/26426/18624 26439/26439/18637 +f 26579/26579/18761 26439/26439/18637 26580/26580/18762 +f 26580/26580/18762 26439/26439/18637 26437/26437/18635 +f 26580/26580/18762 26437/26437/18635 26584/26584/18766 +f 26584/26584/18766 26437/26437/18635 26438/26438/18636 +f 26584/26584/18766 26438/26438/18636 26592/26592/18772 +f 26585/26585/18764 26584/26584/18766 26592/26592/18772 +f 26585/26585/18764 26592/26592/18772 26593/26593/18773 +f 26583/26583/18765 26582/26582/18764 26594/26594/18773 +f 26583/26583/18765 26594/26594/18773 26595/26595/18774 +f 26596/26596/18775 26583/26583/18765 26595/26595/18774 +f 26596/26596/18775 26595/26595/18774 26597/26597/18776 +f 26598/26598/18777 26577/26577/18760 26583/26583/18765 +f 26598/26598/18777 26583/26583/18765 26596/26596/18775 +f 26588/26588/18769 26574/26574/18757 26577/26577/18760 +f 26588/26588/18769 26577/26577/18760 26598/26598/18777 +f 26599/26599/18778 26600/26600/18779 26601/26601/18780 +f 26599/26599/18778 26601/26601/18780 26602/26602/18781 +f 26600/26600/18779 26603/26603/18782 26604/26604/18783 +f 26600/26600/18779 26604/26604/18783 26601/26601/18780 +f 26602/26602/18781 26601/26601/18780 26605/26605/18784 +f 26602/26602/18781 26605/26605/18784 26606/26606/18785 +f 26601/26601/18780 26604/26604/18783 26607/26607/18786 +f 26601/26601/18780 26607/26607/18786 26605/26605/18784 +f 26608/26608/18787 26609/26609/18788 26599/26599/18778 +f 26608/26608/18787 26599/26599/18778 26610/26610/18789 +f 26609/26609/18788 26611/26611/18790 26600/26600/18779 +f 26609/26609/18788 26600/26600/18779 26599/26599/18778 +f 26611/26611/18790 26612/26612/18791 26603/26603/18782 +f 26611/26611/18790 26603/26603/18782 26600/26600/18779 +f 26612/26612/18791 26613/26613/18792 26614/26614/18793 +f 26612/26612/18791 26614/26614/18793 26603/26603/18782 +f 26603/26603/18782 26614/26614/18793 26615/26615/18794 +f 26603/26603/18782 26615/26615/18794 26604/26604/18783 +f 26604/26604/18783 26615/26615/18794 26616/26616/18795 +f 26604/26604/18783 26616/26616/18795 26607/26607/18786 +f 26607/26607/18786 26616/26616/18795 26617/26617/18796 +f 26607/26607/18786 26617/26617/18796 26618/26618/18797 +f 26605/26605/18784 26607/26607/18786 26618/26618/18797 +f 26605/26605/18784 26618/26618/18797 26619/26619/18798 +f 26606/26606/18785 26605/26605/18784 26619/26619/18798 +f 26606/26606/18785 26619/26619/18798 26620/26620/18799 +f 26621/26621/18800 26606/26606/18785 26620/26620/18799 +f 26621/26621/18800 26620/26620/18799 26622/26622/18801 +f 26623/26623/18802 26602/26602/18781 26606/26606/18785 +f 26623/26623/18802 26606/26606/18785 26621/26621/18800 +f 26610/26610/18789 26599/26599/18778 26602/26602/18781 +f 26610/26610/18789 26602/26602/18781 26623/26623/18802 +f 26624/26624/18803 26625/26625/18804 26626/26626/18805 +f 26624/26624/18803 26626/26626/18805 26627/26627/18806 +f 26625/26625/18804 26628/26628/18807 26629/26629/18808 +f 26625/26625/18804 26629/26629/18808 26626/26626/18805 +f 26627/26627/18806 26626/26626/18805 26630/26630/18809 +f 26627/26627/18806 26630/26630/18809 26631/26631/18810 +f 26626/26626/18805 26629/26629/18808 26632/26632/18811 +f 26626/26626/18805 26632/26632/18811 26630/26630/18809 +f 26633/26633/18812 26634/26634/18813 26624/26624/18803 +f 26633/26633/18812 26624/26624/18803 26635/26635/18814 +f 26634/26634/18813 26636/26636/18815 26625/26625/18804 +f 26634/26634/18813 26625/26625/18804 26624/26624/18803 +f 26636/26636/18815 26637/26637/18816 26628/26628/18807 +f 26636/26636/18815 26628/26628/18807 26625/26625/18804 +f 26637/26637/18816 26638/26638/18817 26639/26639/18818 +f 26637/26637/18816 26639/26639/18818 26628/26628/18807 +f 26628/26628/18807 26639/26639/18818 26640/26640/18819 +f 26628/26628/18807 26640/26640/18819 26629/26629/18808 +f 26629/26629/18808 26640/26640/18819 26641/26641/18820 +f 26629/26629/18808 26641/26641/18820 26632/26632/18811 +f 26632/26632/18811 26641/26641/18820 26642/26642/18821 +f 26632/26632/18811 26642/26642/18821 26643/26643/18822 +f 26630/26630/18809 26632/26632/18811 26643/26643/18822 +f 26630/26630/18809 26643/26643/18822 26644/26644/18823 +f 26631/26631/18810 26630/26630/18809 26644/26644/18823 +f 26631/26631/18810 26644/26644/18823 26645/26645/18824 +f 26646/26646/18825 26631/26631/18810 26645/26645/18824 +f 26646/26646/18825 26645/26645/18824 26647/26647/18826 +f 26648/26648/18827 26627/26627/18806 26631/26631/18810 +f 26648/26648/18827 26631/26631/18810 26646/26646/18825 +f 26635/26635/18814 26624/26624/18803 26627/26627/18806 +f 26635/26635/18814 26627/26627/18806 26648/26648/18827 +f 26649/26649/18828 26650/26650/18829 26651/26651/18830 +f 26649/26649/18828 26651/26651/18830 26652/26652/18831 +f 26650/26650/18829 26653/26653/18832 26654/26654/18833 +f 26650/26650/18829 26654/26654/18833 26651/26651/18830 +f 26652/26652/18831 26651/26651/18830 26655/26655/18834 +f 26652/26652/18831 26655/26655/18834 26656/26656/18835 +f 26651/26651/18830 26654/26654/18833 26657/26657/18836 +f 26651/26651/18830 26657/26657/18836 26655/26655/18834 +f 26658/26658/18837 26659/26659/18838 26649/26649/18828 +f 26658/26658/18837 26649/26649/18828 26660/26660/18839 +f 26659/26659/18838 26661/26661/18840 26650/26650/18829 +f 26659/26659/18838 26650/26650/18829 26649/26649/18828 +f 26661/26661/18840 26662/26662/18841 26653/26653/18832 +f 26661/26661/18840 26653/26653/18832 26650/26650/18829 +f 26662/26662/18841 26663/26663/18842 26664/26664/18843 +f 26662/26662/18841 26664/26664/18843 26653/26653/18832 +f 26653/26653/18832 26664/26664/18843 26665/26665/18844 +f 26653/26653/18832 26665/26665/18844 26654/26654/18833 +f 26654/26654/18833 26665/26665/18844 26666/26666/18845 +f 26654/26654/18833 26666/26666/18845 26657/26657/18836 +f 26657/26657/18836 26666/26666/18845 26667/26667/18846 +f 26657/26657/18836 26667/26667/18846 26668/26668/18847 +f 26655/26655/18834 26657/26657/18836 26668/26668/18847 +f 26655/26655/18834 26668/26668/18847 26669/26669/18848 +f 26656/26656/18835 26655/26655/18834 26669/26669/18848 +f 26656/26656/18835 26669/26669/18848 26670/26670/18849 +f 26671/26671/18850 26656/26656/18835 26670/26670/18849 +f 26671/26671/18850 26670/26670/18849 26672/26672/18851 +f 26673/26673/18852 26652/26652/18831 26656/26656/18835 +f 26673/26673/18852 26656/26656/18835 26671/26671/18850 +f 26660/26660/18839 26649/26649/18828 26652/26652/18831 +f 26660/26660/18839 26652/26652/18831 26673/26673/18852 +f 26674/26674/18853 26675/26675/18854 26676/26676/18855 +f 26674/26674/18853 26676/26676/18855 26677/26677/18856 +f 26675/26675/18854 26678/26678/18857 26679/26679/18858 +f 26675/26675/18854 26679/26679/18858 26676/26676/18855 +f 26680/26680/18859 26681/26681/18855 26682/26682/18860 +f 26680/26680/18859 26682/26682/18860 26683/26683/18861 +f 26681/26681/18855 26684/26684/18862 26685/26685/18863 +f 26681/26681/18855 26685/26685/18863 26682/26682/18860 +f 26622/26622/18801 26620/26620/18799 26674/26674/18853 +f 26622/26622/18801 26674/26674/18853 26686/26686/18864 +f 26620/26620/18799 26619/26619/18798 26675/26675/18854 +f 26620/26620/18799 26675/26675/18854 26674/26674/18853 +f 26619/26619/18798 26618/26618/18797 26678/26678/18857 +f 26619/26619/18798 26678/26678/18857 26675/26675/18854 +f 26618/26618/18797 26617/26617/18796 26687/26687/18865 +f 26618/26618/18797 26687/26687/18865 26678/26678/18857 +f 26678/26678/18857 26687/26687/18865 26688/26688/18866 +f 26678/26678/18857 26688/26688/18866 26679/26679/18858 +f 26684/26684/18862 26689/26689/18867 26690/26690/18868 +f 26684/26684/18862 26690/26690/18868 26685/26685/18863 +f 26685/26685/18863 26690/26690/18868 26667/26667/18846 +f 26685/26685/18863 26667/26667/18846 26666/26666/18845 +f 26682/26682/18860 26685/26685/18863 26666/26666/18845 +f 26682/26682/18860 26666/26666/18845 26665/26665/18844 +f 26683/26683/18861 26682/26682/18860 26665/26665/18844 +f 26683/26683/18861 26665/26665/18844 26664/26664/18843 +f 26691/26691/18869 26683/26683/18861 26664/26664/18843 +f 26691/26691/18869 26664/26664/18843 26663/26663/18842 +f 26692/26692/18870 26680/26680/18859 26683/26683/18861 +f 26692/26692/18870 26683/26683/18861 26691/26691/18869 +f 26686/26686/18864 26674/26674/18853 26677/26677/18856 +f 26686/26686/18864 26677/26677/18856 26693/26693/18871 +f 26694/26694/18872 26695/26695/18873 26696/26696/18874 +f 26694/26694/18872 26696/26696/18874 26697/26697/18875 +f 26695/26695/18873 26698/26698/18876 26699/26699/18877 +f 26695/26695/18873 26699/26699/18877 26696/26696/18874 +f 26697/26697/18875 26696/26696/18874 26700/26700/18878 +f 26697/26697/18875 26700/26700/18878 26701/26701/18879 +f 26696/26696/18874 26699/26699/18877 26702/26702/18880 +f 26696/26696/18874 26702/26702/18880 26700/26700/18878 +f 26703/26703/18881 26704/26704/18882 26694/26694/18872 +f 26703/26703/18881 26694/26694/18872 26705/26705/18883 +f 26704/26704/18882 26706/26706/18884 26695/26695/18873 +f 26704/26704/18882 26695/26695/18873 26694/26694/18872 +f 26706/26706/18884 26707/26707/18885 26698/26698/18876 +f 26706/26706/18884 26698/26698/18876 26695/26695/18873 +f 26707/26707/18885 26586/26586/18767 26588/26588/18769 +f 26707/26707/18885 26588/26588/18769 26698/26698/18876 +f 26698/26698/18876 26588/26588/18769 26598/26598/18777 +f 26698/26698/18876 26598/26598/18777 26699/26699/18877 +f 26699/26699/18877 26598/26598/18777 26596/26596/18775 +f 26699/26699/18877 26596/26596/18775 26702/26702/18880 +f 26702/26702/18880 26596/26596/18775 26597/26597/18776 +f 26702/26702/18880 26597/26597/18776 26708/26708/18886 +f 26700/26700/18878 26702/26702/18880 26708/26708/18886 +f 26700/26700/18878 26708/26708/18886 26709/26709/18887 +f 26701/26701/18879 26700/26700/18878 26709/26709/18887 +f 26701/26701/18879 26709/26709/18887 26710/26710/18888 +f 26711/26711/18889 26701/26701/18879 26710/26710/18888 +f 26711/26711/18889 26710/26710/18888 26712/26712/18890 +f 26713/26713/18891 26697/26697/18875 26701/26701/18879 +f 26713/26713/18891 26701/26701/18879 26711/26711/18889 +f 26705/26705/18883 26694/26694/18872 26697/26697/18875 +f 26705/26705/18883 26697/26697/18875 26713/26713/18891 +f 26714/26714/18892 26715/26715/18893 26716/26716/18894 +f 26714/26714/18892 26716/26716/18894 26717/26717/18895 +f 26718/26718/18896 26719/26719/18897 26720/26720/18898 +f 26718/26718/18896 26720/26720/18898 26721/26721/18899 +f 26717/26717/18895 26716/26716/18894 26722/26722/18900 +f 26717/26717/18895 26722/26722/18900 26723/26723/18901 +f 26721/26721/18899 26720/26720/18898 26724/26724/18902 +f 26721/26721/18899 26724/26724/18902 26725/26725/18900 +f 26726/26726/18903 26727/26727/18904 26714/26714/18892 +f 26726/26726/18903 26714/26714/18892 26728/26728/18905 +f 26727/26727/18904 26729/26729/18906 26715/26715/18893 +f 26727/26727/18904 26715/26715/18893 26714/26714/18892 +f 26730/26730/18907 26731/26731/18908 26719/26719/18897 +f 26730/26730/18907 26719/26719/18897 26718/26718/18896 +f 26731/26731/18908 26703/26703/18881 26705/26705/18883 +f 26731/26731/18908 26705/26705/18883 26719/26719/18897 +f 26719/26719/18897 26705/26705/18883 26713/26713/18891 +f 26719/26719/18897 26713/26713/18891 26720/26720/18898 +f 26720/26720/18898 26713/26713/18891 26711/26711/18889 +f 26720/26720/18898 26711/26711/18889 26724/26724/18902 +f 26724/26724/18902 26711/26711/18889 26712/26712/18890 +f 26724/26724/18902 26712/26712/18890 26732/26732/18909 +f 26725/26725/18900 26724/26724/18902 26732/26732/18909 +f 26725/26725/18900 26732/26732/18909 26733/26733/18910 +f 26723/26723/18901 26722/26722/18900 26734/26734/18910 +f 26723/26723/18901 26734/26734/18910 26735/26735/18911 +f 26736/26736/18912 26723/26723/18901 26735/26735/18911 +f 26736/26736/18912 26735/26735/18911 26737/26737/18913 +f 26738/26738/18914 26717/26717/18895 26723/26723/18901 +f 26738/26738/18914 26723/26723/18901 26736/26736/18912 +f 26728/26728/18905 26714/26714/18892 26717/26717/18895 +f 26728/26728/18905 26717/26717/18895 26738/26738/18914 +f 26739/26739/18915 26740/26740/18916 26741/26741/18917 +f 26739/26739/18915 26741/26741/18917 26742/26742/18918 +f 26740/26740/18916 26743/26743/18919 26744/26744/18920 +f 26740/26740/18916 26744/26744/18920 26741/26741/18917 +f 26742/26742/18918 26741/26741/18917 26745/26745/18921 +f 26742/26742/18918 26745/26745/18921 26746/26746/18922 +f 26741/26741/18917 26744/26744/18920 26747/26747/18923 +f 26741/26741/18917 26747/26747/18923 26745/26745/18921 +f 26748/26748/18924 26749/26749/18925 26739/26739/18915 +f 26748/26748/18924 26739/26739/18915 26750/26750/18926 +f 26749/26749/18925 26751/26751/18927 26740/26740/18916 +f 26749/26749/18925 26740/26740/18916 26739/26739/18915 +f 26751/26751/18927 26752/26752/18928 26743/26743/18919 +f 26751/26751/18927 26743/26743/18919 26740/26740/18916 +f 26752/26752/18928 26726/26726/18903 26728/26728/18905 +f 26752/26752/18928 26728/26728/18905 26743/26743/18919 +f 26743/26743/18919 26728/26728/18905 26738/26738/18914 +f 26743/26743/18919 26738/26738/18914 26744/26744/18920 +f 26744/26744/18920 26738/26738/18914 26736/26736/18912 +f 26744/26744/18920 26736/26736/18912 26747/26747/18923 +f 26747/26747/18923 26736/26736/18912 26737/26737/18913 +f 26747/26747/18923 26737/26737/18913 26753/26753/18929 +f 26745/26745/18921 26747/26747/18923 26753/26753/18929 +f 26745/26745/18921 26753/26753/18929 26754/26754/18930 +f 26746/26746/18922 26745/26745/18921 26754/26754/18930 +f 26746/26746/18922 26754/26754/18930 26755/26755/18931 +f 26756/26756/18932 26746/26746/18922 26755/26755/18931 +f 26756/26756/18932 26755/26755/18931 26757/26757/18933 +f 26758/26758/18934 26742/26742/18918 26746/26746/18922 +f 26758/26758/18934 26746/26746/18922 26756/26756/18932 +f 26750/26750/18926 26739/26739/18915 26742/26742/18918 +f 26750/26750/18926 26742/26742/18918 26758/26758/18934 +f 26759/26759/18935 26760/26760/18936 26761/26761/18937 +f 26759/26759/18935 26761/26761/18937 26762/26762/18938 +f 26760/26760/18936 26763/26763/18939 26764/26764/18940 +f 26760/26760/18936 26764/26764/18940 26761/26761/18937 +f 26762/26762/18938 26761/26761/18937 26765/26765/18941 +f 26762/26762/18938 26765/26765/18941 26766/26766/18942 +f 26761/26761/18937 26764/26764/18940 26767/26767/18943 +f 26761/26761/18937 26767/26767/18943 26765/26765/18941 +f 26768/26768/18739 26547/26547/18737 26759/26759/18935 +f 26768/26768/18739 26759/26759/18935 26769/26769/18944 +f 26547/26547/18737 26545/26545/18735 26760/26760/18936 +f 26547/26547/18737 26760/26760/18936 26759/26759/18935 +f 26545/26545/18735 26542/26542/18734 26763/26763/18939 +f 26545/26545/18735 26763/26763/18939 26760/26760/18936 +f 26542/26542/18734 26541/26541/18720 26770/26770/18945 +f 26542/26542/18734 26770/26770/18945 26763/26763/18939 +f 26763/26763/18939 26770/26770/18945 26771/26771/18946 +f 26763/26763/18939 26771/26771/18946 26764/26764/18940 +f 26764/26764/18940 26771/26771/18946 26772/26772/18947 +f 26764/26764/18940 26772/26772/18947 26767/26767/18943 +f 26767/26767/18943 26772/26772/18947 26613/26613/18792 +f 26767/26767/18943 26613/26613/18792 26612/26612/18791 +f 26765/26765/18941 26767/26767/18943 26612/26612/18791 +f 26765/26765/18941 26612/26612/18791 26611/26611/18790 +f 26766/26766/18942 26765/26765/18941 26611/26611/18790 +f 26766/26766/18942 26611/26611/18790 26609/26609/18788 +f 26773/26773/18948 26766/26766/18942 26609/26609/18788 +f 26773/26773/18948 26609/26609/18788 26608/26608/18787 +f 26774/26774/18949 26762/26762/18938 26766/26766/18942 +f 26774/26774/18949 26766/26766/18942 26773/26773/18948 +f 26769/26769/18944 26759/26759/18935 26762/26762/18938 +f 26769/26769/18944 26762/26762/18938 26774/26774/18949 +f 26775/26775/18950 26776/26776/18951 26777/26777/18952 +f 26775/26775/18950 26777/26777/18952 26778/26778/18953 +f 26776/26776/18951 26779/26779/18954 26780/26780/18955 +f 26776/26776/18951 26780/26780/18955 26777/26777/18952 +f 26778/26778/18953 26777/26777/18952 26781/26781/18956 +f 26778/26778/18953 26781/26781/18956 26782/26782/18957 +f 26777/26777/18952 26780/26780/18955 26783/26783/18958 +f 26777/26777/18952 26783/26783/18958 26781/26781/18956 +f 26501/26501/18697 26499/26499/18696 26775/26775/18950 +f 26501/26501/18697 26775/26775/18950 26784/26784/18959 +f 26499/26499/18696 26497/26497/18694 26776/26776/18951 +f 26499/26499/18696 26776/26776/18951 26775/26775/18950 +f 26497/26497/18694 26494/26494/18692 26779/26779/18954 +f 26497/26497/18694 26779/26779/18954 26776/26776/18951 +f 26494/26494/18692 26493/26493/18691 26785/26785/18960 +f 26494/26494/18692 26785/26785/18960 26779/26779/18954 +f 26779/26779/18954 26785/26785/18960 26786/26786/18961 +f 26779/26779/18954 26786/26786/18961 26780/26780/18955 +f 26780/26780/18955 26786/26786/18961 26787/26787/18962 +f 26780/26780/18955 26787/26787/18962 26783/26783/18958 +f 26783/26783/18958 26787/26787/18962 26638/26638/18817 +f 26783/26783/18958 26638/26638/18817 26637/26637/18816 +f 26781/26781/18956 26783/26783/18958 26637/26637/18816 +f 26781/26781/18956 26637/26637/18816 26636/26636/18815 +f 26782/26782/18957 26781/26781/18956 26636/26636/18815 +f 26782/26782/18957 26636/26636/18815 26634/26634/18813 +f 26788/26788/18963 26782/26782/18957 26634/26634/18813 +f 26788/26788/18963 26634/26634/18813 26633/26633/18812 +f 26789/26789/18964 26778/26778/18953 26782/26782/18957 +f 26789/26789/18964 26782/26782/18957 26788/26788/18963 +f 26784/26784/18959 26775/26775/18950 26778/26778/18953 +f 26784/26784/18959 26778/26778/18953 26789/26789/18964 +f 26790/26790/18965 26791/26791/18966 26792/26792/18967 +f 26790/26790/18965 26792/26792/18967 26793/26793/18968 +f 26791/26791/18966 26794/26794/18969 26795/26795/18970 +f 26791/26791/18966 26795/26795/18970 26792/26792/18967 +f 26793/26793/18968 26792/26792/18967 26796/26796/18971 +f 26793/26793/18968 26796/26796/18971 26797/26797/18972 +f 26792/26792/18967 26795/26795/18970 26798/26798/18973 +f 26792/26792/18967 26798/26798/18973 26796/26796/18971 +f 26799/26799/18974 26800/26800/18975 26790/26790/18965 +f 26799/26799/18974 26790/26790/18965 26801/26801/18976 +f 26800/26800/18975 26802/26802/18977 26791/26791/18966 +f 26800/26800/18975 26791/26791/18966 26790/26790/18965 +f 26802/26802/18977 26803/26803/18978 26794/26794/18969 +f 26802/26802/18977 26794/26794/18969 26791/26791/18966 +f 26803/26803/18978 26748/26748/18924 26750/26750/18926 +f 26803/26803/18978 26750/26750/18926 26794/26794/18969 +f 26794/26794/18969 26750/26750/18926 26758/26758/18934 +f 26794/26794/18969 26758/26758/18934 26795/26795/18970 +f 26795/26795/18970 26758/26758/18934 26756/26756/18932 +f 26795/26795/18970 26756/26756/18932 26798/26798/18973 +f 26798/26798/18973 26756/26756/18932 26757/26757/18933 +f 26798/26798/18973 26757/26757/18933 26804/26804/18979 +f 26796/26796/18971 26798/26798/18973 26804/26804/18979 +f 26796/26796/18971 26804/26804/18979 26805/26805/18980 +f 26797/26797/18972 26796/26796/18971 26805/26805/18980 +f 26797/26797/18972 26805/26805/18980 26806/26806/18981 +f 26807/26807/18982 26797/26797/18972 26806/26806/18981 +f 26807/26807/18982 26806/26806/18981 26808/26808/18983 +f 26809/26809/18984 26793/26793/18968 26797/26797/18972 +f 26809/26809/18984 26797/26797/18972 26807/26807/18982 +f 26801/26801/18976 26790/26790/18965 26793/26793/18968 +f 26801/26801/18976 26793/26793/18968 26809/26809/18984 +f 26810/26810/18985 26811/26811/18986 26812/26812/18987 +f 26810/26810/18985 26812/26812/18987 26813/26813/18988 +f 26811/26811/18986 26814/26814/18989 26815/26815/18990 +f 26811/26811/18986 26815/26815/18990 26812/26812/18987 +f 26816/26816/18988 26817/26817/18987 26818/26818/18991 +f 26816/26816/18988 26818/26818/18991 26819/26819/18992 +f 26812/26812/18987 26815/26815/18990 26820/26820/18993 +f 26812/26812/18987 26820/26820/18993 26821/26821/18994 +f 26647/26647/18826 26645/26645/18824 26810/26810/18985 +f 26647/26647/18826 26810/26810/18985 26822/26822/18995 +f 26645/26645/18824 26644/26644/18823 26811/26811/18986 +f 26645/26645/18824 26811/26811/18986 26810/26810/18985 +f 26644/26644/18823 26643/26643/18822 26814/26814/18989 +f 26644/26644/18823 26814/26814/18989 26811/26811/18986 +f 26643/26643/18822 26642/26642/18821 26823/26823/18996 +f 26643/26643/18822 26823/26823/18996 26814/26814/18989 +f 26814/26814/18989 26823/26823/18996 26824/26824/18997 +f 26814/26814/18989 26824/26824/18997 26815/26815/18990 +f 26815/26815/18990 26824/26824/18997 26825/26825/18998 +f 26815/26815/18990 26825/26825/18998 26820/26820/18993 +f 26826/26826/18993 26827/26827/18998 26658/26658/18837 +f 26826/26826/18993 26658/26658/18837 26660/26660/18839 +f 26818/26818/18991 26826/26826/18993 26660/26660/18839 +f 26818/26818/18991 26660/26660/18839 26673/26673/18852 +f 26819/26819/18992 26818/26818/18991 26673/26673/18852 +f 26819/26819/18992 26673/26673/18852 26671/26671/18850 +f 26828/26828/18999 26819/26819/18992 26671/26671/18850 +f 26828/26828/18999 26671/26671/18850 26672/26672/18851 +f 26829/26829/19000 26816/26816/18988 26819/26819/18992 +f 26829/26829/19000 26819/26819/18992 26828/26828/18999 +f 26822/26822/18995 26810/26810/18985 26813/26813/18988 +f 26822/26822/18995 26813/26813/18988 26830/26830/19001 +f 26831/26831/19002 26832/26832/19003 26833/26833/19004 +f 26831/26831/19002 26833/26833/19004 26834/26834/19005 +f 26832/26832/19003 26835/26835/19006 26836/26836/19007 +f 26832/26832/19003 26836/26836/19007 26833/26833/19004 +f 26834/26834/19005 26833/26833/19004 26837/26837/19008 +f 26834/26834/19005 26837/26837/19008 26838/26838/19009 +f 26833/26833/19004 26836/26836/19007 26839/26839/19010 +f 26833/26833/19004 26839/26839/19010 26837/26837/19008 +f 26840/26840/19011 26841/26841/19012 26831/26831/19002 +f 26840/26840/19011 26831/26831/19002 26842/26842/19013 +f 26841/26841/19012 26843/26843/19014 26832/26832/19003 +f 26841/26841/19012 26832/26832/19003 26831/26831/19002 +f 26843/26843/19014 26844/26844/19015 26835/26835/19006 +f 26843/26843/19014 26835/26835/19006 26832/26832/19003 +f 26844/26844/19015 26845/26845/19016 26846/26846/19017 +f 26844/26844/19015 26846/26846/19017 26835/26835/19006 +f 26835/26835/19006 26846/26846/19017 26847/26847/19018 +f 26835/26835/19006 26847/26847/19018 26836/26836/19007 +f 26836/26836/19007 26847/26847/19018 26848/26848/19019 +f 26836/26836/19007 26848/26848/19019 26839/26839/19010 +f 26839/26839/19010 26848/26848/19019 26526/26526/18720 +f 26839/26839/19010 26526/26526/18720 26525/26525/18719 +f 26837/26837/19008 26839/26839/19010 26525/26525/18719 +f 26837/26837/19008 26525/26525/18719 26849/26849/19020 +f 26838/26838/19009 26837/26837/19008 26849/26849/19020 +f 26838/26838/19009 26849/26849/19020 26519/26519/18714 +f 26850/26850/19021 26838/26838/19009 26519/26519/18714 +f 26850/26850/19021 26519/26519/18714 26518/26518/18697 +f 26851/26851/19022 26834/26834/19005 26838/26838/19009 +f 26851/26851/19022 26838/26838/19009 26850/26850/19021 +f 26842/26842/19013 26831/26831/19002 26834/26834/19005 +f 26842/26842/19013 26834/26834/19005 26851/26851/19022 +f 26852/26852/19023 26853/26853/19024 26854/26854/19025 +f 26852/26852/19023 26854/26854/19025 26855/26855/19026 +f 26853/26853/19024 26856/26856/19027 26857/26857/19028 +f 26853/26853/19024 26857/26857/19028 26854/26854/19025 +f 26855/26855/19026 26854/26854/19025 26858/26858/19029 +f 26855/26855/19026 26858/26858/19029 26859/26859/19030 +f 26854/26854/19025 26857/26857/19028 26860/26860/19031 +f 26854/26854/19025 26860/26860/19031 26858/26858/19029 +f 26861/26861/18974 26862/26862/19032 26863/26863/19023 +f 26861/26861/18974 26863/26863/19023 26864/26864/19033 +f 26862/26862/19032 26865/26865/19034 26866/26866/19035 +f 26862/26862/19032 26866/26866/19035 26863/26863/19023 +f 26865/26865/19034 26867/26867/19036 26868/26868/19027 +f 26865/26865/19034 26868/26868/19027 26866/26866/19035 +f 26869/26869/19037 26870/26870/19038 26871/26871/19039 +f 26869/26869/19037 26871/26871/19039 26856/26856/19027 +f 26856/26856/19027 26871/26871/19039 26872/26872/19040 +f 26856/26856/19027 26872/26872/19040 26857/26857/19028 +f 26857/26857/19028 26872/26872/19040 26873/26873/19041 +f 26857/26857/19028 26873/26873/19041 26860/26860/19031 +f 26860/26860/19031 26873/26873/19041 26571/26571/18691 +f 26860/26860/19031 26571/26571/18691 26570/26570/18756 +f 26858/26858/19029 26860/26860/19031 26570/26570/18756 +f 26858/26858/19029 26570/26570/18756 26874/26874/18755 +f 26859/26859/19030 26858/26858/19029 26874/26874/18755 +f 26859/26859/19030 26874/26874/18755 26565/26565/18753 +f 26875/26875/19042 26859/26859/19030 26565/26565/18753 +f 26875/26875/19042 26565/26565/18753 26550/26550/18739 +f 26876/26876/19043 26855/26855/19026 26859/26859/19030 +f 26876/26876/19043 26859/26859/19030 26875/26875/19042 +f 26877/26877/19044 26852/26852/19023 26855/26855/19026 +f 26877/26877/19044 26855/26855/19026 26876/26876/19043 +f 26878/26878/19045 26879/26879/19046 26880/26880/19047 +f 26878/26878/19045 26880/26880/19047 26881/26881/19048 +f 26879/26879/19046 26882/26882/19049 26883/26883/19050 +f 26879/26879/19046 26883/26883/19050 26880/26880/19047 +f 26881/26881/19048 26880/26880/19047 26884/26884/19051 +f 26881/26881/19048 26884/26884/19051 26885/26885/19052 +f 26880/26880/19047 26883/26883/19050 26886/26886/19053 +f 26880/26880/19047 26886/26886/19053 26884/26884/19051 +f 26726/26726/18903 26752/26752/18928 26887/26887/19045 +f 26726/26726/18903 26887/26887/19045 26888/26888/19054 +f 26752/26752/18928 26751/26751/18927 26889/26889/19046 +f 26752/26752/18928 26889/26889/19046 26887/26887/19045 +f 26751/26751/18927 26749/26749/18925 26890/26890/19049 +f 26751/26751/18927 26890/26890/19049 26889/26889/19046 +f 26749/26749/18925 26748/26748/18924 26891/26891/19055 +f 26749/26749/18925 26891/26891/19055 26890/26890/19049 +f 26882/26882/19049 26892/26892/19056 26893/26893/19057 +f 26882/26882/19049 26893/26893/19057 26883/26883/19050 +f 26883/26883/19050 26893/26893/19057 26894/26894/19058 +f 26883/26883/19050 26894/26894/19058 26886/26886/19053 +f 26886/26886/19053 26894/26894/19058 26895/26895/19059 +f 26886/26886/19053 26895/26895/19059 26896/26896/19060 +f 26884/26884/19051 26886/26886/19053 26896/26896/19060 +f 26884/26884/19051 26896/26896/19060 26897/26897/19061 +f 26885/26885/19052 26884/26884/19051 26897/26897/19061 +f 26885/26885/19052 26897/26897/19061 26898/26898/18800 +f 26899/26899/19062 26885/26885/19052 26898/26898/18800 +f 26899/26899/19062 26898/26898/18800 26900/26900/19063 +f 26901/26901/19064 26881/26881/19048 26885/26885/19052 +f 26901/26901/19064 26885/26885/19052 26899/26899/19062 +f 26902/26902/19054 26878/26878/19045 26881/26881/19048 +f 26902/26902/19054 26881/26881/19048 26901/26901/19064 +f 26903/26903/19065 26904/26904/19066 26905/26905/19067 +f 26903/26903/19065 26905/26905/19067 26906/26906/19068 +f 26904/26904/19066 26907/26907/19069 26908/26908/19070 +f 26904/26904/19066 26908/26908/19070 26905/26905/19067 +f 26906/26906/19068 26905/26905/19067 26909/26909/19071 +f 26906/26906/19068 26909/26909/19071 26910/26910/19072 +f 26905/26905/19067 26908/26908/19070 26911/26911/19073 +f 26905/26905/19067 26911/26911/19073 26909/26909/19071 +f 26870/26870/19038 26912/26912/19074 26903/26903/19065 +f 26870/26870/19038 26903/26903/19065 26871/26871/19039 +f 26912/26912/19074 26913/26913/19075 26904/26904/19066 +f 26912/26912/19074 26904/26904/19066 26903/26903/19065 +f 26913/26913/19075 26914/26914/19076 26907/26907/19069 +f 26913/26913/19075 26907/26907/19069 26904/26904/19066 +f 26914/26914/19076 26915/26915/18627 26916/26916/19077 +f 26914/26914/19076 26916/26916/19077 26907/26907/19069 +f 26907/26907/19069 26916/26916/19077 26917/26917/19078 +f 26907/26907/19069 26917/26917/19078 26908/26908/19070 +f 26908/26908/19070 26917/26917/19078 26918/26918/19079 +f 26908/26908/19070 26918/26918/19079 26911/26911/19073 +f 26919/26919/19073 26920/26920/19080 26638/26638/18817 +f 26919/26919/19073 26638/26638/18817 26787/26787/18962 +f 26921/26921/19071 26919/26919/19073 26787/26787/18962 +f 26921/26921/19071 26787/26787/18962 26786/26786/18961 +f 26922/26922/19072 26921/26921/19071 26786/26786/18961 +f 26922/26922/19072 26786/26786/18961 26785/26785/18960 +f 26873/26873/19041 26910/26910/19072 26923/26923/19081 +f 26873/26873/19041 26923/26923/19081 26571/26571/18691 +f 26872/26872/19040 26906/26906/19068 26910/26910/19072 +f 26872/26872/19040 26910/26910/19072 26873/26873/19041 +f 26871/26871/19039 26903/26903/19065 26906/26906/19068 +f 26871/26871/19039 26906/26906/19068 26872/26872/19040 +f 26924/26924/19082 26925/26925/19083 26926/26926/19084 +f 26924/26924/19082 26926/26926/19084 26927/26927/19085 +f 26925/26925/19083 26928/26928/19086 26929/26929/19087 +f 26925/26925/19083 26929/26929/19087 26926/26926/19084 +f 26927/26927/19085 26926/26926/19084 26930/26930/19088 +f 26927/26927/19085 26930/26930/19088 26931/26931/19089 +f 26926/26926/19084 26929/26929/19087 26932/26932/19090 +f 26926/26926/19084 26932/26932/19090 26930/26930/19088 +f 26438/26438/18636 26436/26436/18634 26933/26933/19091 +f 26438/26438/18636 26933/26933/19091 26934/26934/19092 +f 26436/26436/18634 26435/26435/18633 26935/26935/19083 +f 26436/26436/18634 26935/26935/19083 26933/26933/19091 +f 26435/26435/18633 26434/26434/18632 26936/26936/19086 +f 26435/26435/18633 26936/26936/19086 26935/26935/19083 +f 26434/26434/18632 26433/26433/18631 26937/26937/19093 +f 26434/26434/18632 26937/26937/19093 26936/26936/19086 +f 26928/26928/19086 26938/26938/19094 26939/26939/19095 +f 26928/26928/19086 26939/26939/19095 26929/26929/19087 +f 26929/26929/19087 26939/26939/19095 26940/26940/19096 +f 26929/26929/19087 26940/26940/19096 26932/26932/19090 +f 26932/26932/19090 26940/26940/19096 26941/26941/19097 +f 26932/26932/19090 26941/26941/19097 26942/26942/18814 +f 26930/26930/19088 26932/26932/19090 26942/26942/18814 +f 26930/26930/19088 26942/26942/18814 26943/26943/19098 +f 26931/26931/19089 26930/26930/19088 26943/26943/19098 +f 26931/26931/19089 26943/26943/19098 26944/26944/19099 +f 26945/26945/19100 26931/26931/19089 26944/26944/19099 +f 26945/26945/19100 26944/26944/19099 26946/26946/19101 +f 26947/26947/19102 26927/26927/19085 26931/26931/19089 +f 26947/26947/19102 26931/26931/19089 26945/26945/19100 +f 26948/26948/19103 26924/26924/19082 26927/26927/19085 +f 26948/26948/19103 26927/26927/19085 26947/26947/19102 +f 26949/26949/19104 26950/26950/19105 26951/26951/19106 +f 26949/26949/19104 26951/26951/19106 26952/26952/19107 +f 26950/26950/19105 26953/26953/19108 26954/26954/19109 +f 26950/26950/19105 26954/26954/19109 26951/26951/19106 +f 26952/26952/19107 26951/26951/19106 26955/26955/19110 +f 26952/26952/19107 26955/26955/19110 26956/26956/19111 +f 26951/26951/19106 26954/26954/19109 26957/26957/19112 +f 26951/26951/19106 26957/26957/19112 26955/26955/19110 +f 26845/26845/19016 26958/26958/18981 26949/26949/19104 +f 26845/26845/19016 26949/26949/19104 26846/26846/19017 +f 26958/26958/18981 26959/26959/18980 26950/26950/19105 +f 26958/26958/18981 26950/26950/19105 26949/26949/19104 +f 26959/26959/18980 26960/26960/18979 26953/26953/19108 +f 26959/26959/18980 26953/26953/19108 26950/26950/19105 +f 26960/26960/18979 26961/26961/19113 26962/26962/19114 +f 26960/26960/18979 26962/26962/19114 26953/26953/19108 +f 26953/26953/19108 26962/26962/19114 26963/26963/19115 +f 26953/26953/19108 26963/26963/19115 26954/26954/19109 +f 26954/26954/19109 26963/26963/19115 26964/26964/19116 +f 26954/26954/19109 26964/26964/19116 26957/26957/19112 +f 26965/26965/19112 26966/26966/19117 26613/26613/18792 +f 26965/26965/19112 26613/26613/18792 26772/26772/18947 +f 26955/26955/19110 26957/26957/19112 26967/26967/19118 +f 26955/26955/19110 26967/26967/19118 26968/26968/18946 +f 26956/26956/19111 26955/26955/19110 26968/26968/18946 +f 26956/26956/19111 26968/26968/18946 26969/26969/19119 +f 26848/26848/19019 26956/26956/19111 26969/26969/19119 +f 26848/26848/19019 26969/26969/19119 26526/26526/18720 +f 26847/26847/19018 26952/26952/19107 26956/26956/19111 +f 26847/26847/19018 26956/26956/19111 26848/26848/19019 +f 26846/26846/19017 26949/26949/19104 26952/26952/19107 +f 26846/26846/19017 26952/26952/19107 26847/26847/19018 +f 26970/26970/19120 26971/26971/19121 26972/26972/19122 +f 26970/26970/19120 26972/26972/19122 26973/26973/19123 +f 26971/26971/19121 26974/26974/19124 26975/26975/19125 +f 26971/26971/19121 26975/26975/19125 26972/26972/19122 +f 26973/26973/19123 26972/26972/19122 26976/26976/19126 +f 26973/26973/19123 26976/26976/19126 26977/26977/19127 +f 26972/26972/19122 26975/26975/19125 26978/26978/19128 +f 26972/26972/19122 26978/26978/19128 26976/26976/19126 +f 26597/26597/18776 26595/26595/18774 26979/26979/19129 +f 26597/26597/18776 26979/26979/19129 26980/26980/19130 +f 26981/26981/18774 26982/26982/18773 26971/26971/19121 +f 26981/26981/18774 26971/26971/19121 26970/26970/19120 +f 26593/26593/18773 26592/26592/18772 26983/26983/19124 +f 26593/26593/18773 26983/26983/19124 26984/26984/19131 +f 26592/26592/18772 26438/26438/18636 26934/26934/19092 +f 26592/26592/18772 26934/26934/19092 26983/26983/19124 +f 26974/26974/19124 26948/26948/19103 26947/26947/19102 +f 26974/26974/19124 26947/26947/19102 26975/26975/19125 +f 26975/26975/19125 26947/26947/19102 26945/26945/19100 +f 26975/26975/19125 26945/26945/19100 26978/26978/19128 +f 26978/26978/19128 26945/26945/19100 26946/26946/19101 +f 26978/26978/19128 26946/26946/19101 26985/26985/18995 +f 26976/26976/19126 26978/26978/19128 26985/26985/18995 +f 26976/26976/19126 26985/26985/18995 26986/26986/19132 +f 26977/26977/19127 26976/26976/19126 26986/26986/19132 +f 26977/26977/19127 26986/26986/19132 26987/26987/19133 +f 26988/26988/19134 26977/26977/19127 26987/26987/19133 +f 26988/26988/19134 26987/26987/19133 26989/26989/18851 +f 26990/26990/19135 26973/26973/19123 26977/26977/19127 +f 26990/26990/19135 26977/26977/19127 26988/26988/19134 +f 26991/26991/19130 26970/26970/19120 26973/26973/19123 +f 26991/26991/19130 26973/26973/19123 26990/26990/19135 +f 26992/26992/19136 26993/26993/19137 26994/26994/19138 +f 26992/26992/19136 26994/26994/19138 26995/26995/19139 +f 26993/26993/19137 26996/26996/19140 26997/26997/19141 +f 26993/26993/19137 26997/26997/19141 26994/26994/19138 +f 26995/26995/19139 26994/26994/19138 26998/26998/19142 +f 26995/26995/19139 26998/26998/19142 26999/26999/19143 +f 26994/26994/19138 26997/26997/19141 27000/27000/19144 +f 26994/26994/19138 27000/27000/19144 26998/26998/19142 +f 27001/27001/19145 27002/27002/19146 26992/26992/19136 +f 27001/27001/19145 26992/26992/19136 27003/27003/19147 +f 27002/27002/19146 27004/27004/18770 26993/26993/19137 +f 27002/27002/19146 26993/26993/19137 26992/26992/19136 +f 27004/27004/18770 27005/27005/19148 26996/26996/19140 +f 27004/27004/18770 26996/26996/19140 26993/26993/19137 +f 27005/27005/19148 27006/27006/19149 27007/27007/19150 +f 27005/27005/19148 27007/27007/19150 26996/26996/19140 +f 26996/26996/19140 27007/27007/19150 27008/27008/19151 +f 26996/26996/19140 27008/27008/19151 26997/26997/19141 +f 26997/26997/19141 27008/27008/19151 27009/27009/19152 +f 26997/26997/19141 27009/27009/19152 27000/27000/19144 +f 27000/27000/19144 27009/27009/19152 27010/27010/18837 +f 27000/27000/19144 27010/27010/18837 27011/27011/19153 +f 26998/26998/19142 27000/27000/19144 27011/27011/19153 +f 26998/26998/19142 27011/27011/19153 27012/27012/18997 +f 27013/27013/19143 27014/27014/19142 26824/26824/18997 +f 27013/27013/19143 26824/26824/18997 26823/26823/18996 +f 27015/27015/19154 27013/27013/19143 26823/26823/18996 +f 27015/27015/19154 26823/26823/18996 26642/26642/18821 +f 27016/27016/19155 26995/26995/19139 26999/26999/19143 +f 27016/27016/19155 26999/26999/19143 27017/27017/19154 +f 27003/27003/19147 26992/26992/19136 26995/26995/19139 +f 27003/27003/19147 26995/26995/19139 27016/27016/19155 +f 27018/27018/19156 27019/27019/19157 27020/27020/19158 +f 27018/27018/19156 27020/27020/19158 27021/27021/19159 +f 27019/27019/19157 27022/27022/19160 27023/27023/19161 +f 27019/27019/19157 27023/27023/19161 27020/27020/19158 +f 27021/27021/19159 27020/27020/19158 27024/27024/19162 +f 27021/27021/19159 27024/27024/19162 27025/27025/19163 +f 27020/27020/19158 27023/27023/19161 27026/27026/19164 +f 27020/27020/19158 27026/27026/19164 27024/27024/19162 +f 26586/26586/18767 26707/26707/18885 27027/27027/19156 +f 26586/26586/18767 27027/27027/19156 27028/27028/19165 +f 26707/26707/18885 26706/26706/18884 27029/27029/19166 +f 26707/26707/18885 27029/27029/19166 27027/27027/19156 +f 26706/26706/18884 26704/26704/18882 27030/27030/19160 +f 26706/26706/18884 27030/27030/19160 27029/27029/19166 +f 26704/26704/18882 26703/26703/18881 27031/27031/19167 +f 26704/26704/18882 27031/27031/19167 27030/27030/19160 +f 27022/27022/19160 27032/27032/19168 27033/27033/19169 +f 27022/27022/19160 27033/27033/19169 27023/27023/19161 +f 27023/27023/19161 27033/27033/19169 27034/27034/19170 +f 27023/27023/19161 27034/27034/19170 27026/27026/19164 +f 27026/27026/19164 27034/27034/19170 27035/27035/19171 +f 27026/27026/19164 27035/27035/19171 27036/27036/18841 +f 27024/27024/19162 27026/27026/19164 27036/27036/18841 +f 27024/27024/19162 27036/27036/18841 27037/27037/18840 +f 27038/27038/19163 27039/27039/19162 26661/26661/18840 +f 27038/27038/19163 26661/26661/18840 26659/26659/18838 +f 27040/27040/19152 27038/27038/19163 26659/26659/18838 +f 27040/27040/19152 26659/26659/18838 26658/26658/18837 +f 27008/27008/19151 27021/27021/19159 27025/27025/19163 +f 27008/27008/19151 27025/27025/19163 27009/27009/19152 +f 27007/27007/19150 27018/27018/19156 27021/27021/19159 +f 27007/27007/19150 27021/27021/19159 27008/27008/19151 +f 27041/27041/19172 27042/27042/19173 27043/27043/19174 +f 27041/27041/19172 27043/27043/19174 27044/27044/19175 +f 27042/27042/19173 27045/27045/19176 27046/27046/19177 +f 27042/27042/19173 27046/27046/19177 27043/27043/19174 +f 27044/27044/19175 27043/27043/19174 27047/27047/19178 +f 27044/27044/19175 27047/27047/19178 27048/27048/19179 +f 27043/27043/19174 27046/27046/19177 27049/27049/19180 +f 27043/27043/19174 27049/27049/19180 27047/27047/19178 +f 26961/26961/19113 27050/27050/19181 27041/27041/19172 +f 26961/26961/19113 27041/27041/19172 26962/26962/19114 +f 27050/27050/19181 27051/27051/19182 27042/27042/19173 +f 27050/27050/19181 27042/27042/19173 27041/27041/19172 +f 27051/27051/19182 27052/27052/19183 27045/27045/19176 +f 27051/27051/19182 27045/27045/19176 27042/27042/19173 +f 27052/27052/19183 27053/27053/18913 27054/27054/19184 +f 27052/27052/19183 27054/27054/19184 27045/27045/19176 +f 27045/27045/19176 27054/27054/19184 27055/27055/19185 +f 27045/27045/19176 27055/27055/19185 27046/27046/19177 +f 27046/27046/19177 27055/27055/19185 27056/27056/19186 +f 27046/27046/19177 27056/27056/19186 27049/27049/19180 +f 27049/27049/19180 27056/27056/19186 27057/27057/18796 +f 27049/27049/19180 27057/27057/18796 27058/27058/18795 +f 27047/27047/19178 27049/27049/19180 27058/27058/18795 +f 27047/27047/19178 27058/27058/18795 27059/27059/18794 +f 27060/27060/19179 27061/27061/19178 26615/26615/18794 +f 27060/27060/19179 26615/26615/18794 26614/26614/18793 +f 26966/26966/19117 27060/27060/19179 26614/26614/18793 +f 26966/26966/19117 26614/26614/18793 26613/26613/18792 +f 26963/26963/19115 27044/27044/19175 27048/27048/19179 +f 26963/26963/19115 27048/27048/19179 26964/26964/19116 +f 26962/26962/19114 27041/27041/19172 27044/27044/19175 +f 26962/26962/19114 27044/27044/19175 26963/26963/19115 +f 27062/27062/19187 27063/27063/19188 27064/27064/19189 +f 27062/27062/19187 27064/27064/19189 27065/27065/19190 +f 27063/27063/19188 27066/27066/19191 27067/27067/19192 +f 27063/27063/19188 27067/27067/19192 27064/27064/19189 +f 27065/27065/19190 27064/27064/19189 27068/27068/19193 +f 27065/27065/19190 27068/27068/19193 27069/27069/19194 +f 27064/27064/19189 27067/27067/19192 27070/27070/19195 +f 27064/27064/19189 27070/27070/19195 27068/27068/19193 +f 26915/26915/18627 27071/27071/19196 27062/27062/19187 +f 26915/26915/18627 27062/27062/19187 26916/26916/19077 +f 27071/27071/19196 27072/27072/18625 27063/27063/19188 +f 27071/27071/19196 27063/27063/19188 27062/27062/19187 +f 27072/27072/18625 27073/27073/18623 27066/27066/19191 +f 27072/27072/18625 27066/27066/19191 27063/27063/19188 +f 27073/27073/18623 27001/27001/19145 27003/27003/19147 +f 27073/27073/18623 27003/27003/19147 27066/27066/19191 +f 27066/27066/19191 27003/27003/19147 27016/27016/19155 +f 27066/27066/19191 27016/27016/19155 27067/27067/19192 +f 27067/27067/19192 27016/27016/19155 27017/27017/19154 +f 27067/27067/19192 27017/27017/19154 27070/27070/19195 +f 27074/27074/19197 27015/27015/19154 26642/26642/18821 +f 27074/27074/19197 26642/26642/18821 26641/26641/18820 +f 27075/27075/19198 27074/27074/19197 26641/26641/18820 +f 27075/27075/19198 26641/26641/18820 26640/26640/18819 +f 27076/27076/19194 27075/27075/19198 26640/26640/18819 +f 27076/27076/19194 26640/26640/18819 26639/26639/18818 +f 26920/26920/19080 27076/27076/19194 26639/26639/18818 +f 26920/26920/19080 26639/26639/18818 26638/26638/18817 +f 26917/26917/19078 27065/27065/19190 27069/27069/19194 +f 26917/26917/19078 27069/27069/19194 26918/26918/19079 +f 26916/26916/19077 27062/27062/19187 27065/27065/19190 +f 26916/26916/19077 27065/27065/19190 26917/26917/19078 +f 27077/27077/19199 27078/27078/19200 27079/27079/19201 +f 27077/27077/19199 27079/27079/19201 27080/27080/19202 +f 27078/27078/19200 27081/27081/19203 27082/27082/19204 +f 27078/27078/19200 27082/27082/19204 27079/27079/19201 +f 27080/27080/19202 27079/27079/19201 27083/27083/19205 +f 27080/27080/19202 27083/27083/19205 27084/27084/19206 +f 27079/27079/19201 27082/27082/19204 27085/27085/19207 +f 27079/27079/19201 27085/27085/19207 27083/27083/19205 +f 26748/26748/18924 26803/26803/18978 27086/27086/19199 +f 26748/26748/18924 27086/27086/19199 26891/26891/19055 +f 26803/26803/18978 26802/26802/18977 27087/27087/19208 +f 26803/26803/18978 27087/27087/19208 27086/27086/19199 +f 26802/26802/18977 26800/26800/18975 27088/27088/19203 +f 26802/26802/18977 27088/27088/19203 27087/27087/19208 +f 26800/26800/18975 26799/26799/18974 27089/27089/19044 +f 26800/26800/18975 27089/27089/19044 27088/27088/19203 +f 27081/27081/19203 26877/26877/19044 26876/26876/19043 +f 27081/27081/19203 26876/26876/19043 27082/27082/19204 +f 27082/27082/19204 26876/26876/19043 26875/26875/19042 +f 27082/27082/19204 26875/26875/19042 27085/27085/19207 +f 27085/27085/19207 26875/26875/19042 26550/26550/18739 +f 27085/27085/19207 26550/26550/18739 27090/27090/19209 +f 27083/27083/19205 27085/27085/19207 27090/27090/19209 +f 27083/27083/19205 27090/27090/19209 27091/27091/18949 +f 27084/27084/19206 27083/27083/19205 27091/27091/18949 +f 27084/27084/19206 27091/27091/18949 27092/27092/18948 +f 26894/26894/19058 27084/27084/19206 27092/27092/18948 +f 26894/26894/19058 27092/27092/18948 26895/26895/19059 +f 26893/26893/19057 27080/27080/19202 27084/27084/19206 +f 26893/26893/19057 27084/27084/19206 26894/26894/19058 +f 26892/26892/19056 27077/27077/19199 27080/27080/19202 +f 26892/26892/19056 27080/27080/19202 26893/26893/19057 +f 27093/27093/19210 27094/27094/19211 27095/27095/19212 +f 27093/27093/19210 27095/27095/19212 27096/27096/19213 +f 27094/27094/19211 27097/27097/19214 27098/27098/19215 +f 27094/27094/19211 27098/27098/19215 27095/27095/19212 +f 27096/27096/19213 27095/27095/19212 27099/27099/19216 +f 27096/27096/19213 27099/27099/19216 27100/27100/19217 +f 27095/27095/19212 27098/27098/19215 27101/27101/19218 +f 27095/27095/19212 27101/27101/19218 27099/27099/19216 +f 26433/26433/18631 27102/27102/19219 27103/27103/19220 +f 26433/26433/18631 27103/27103/19220 26937/26937/19093 +f 27102/27102/19219 27104/27104/19221 27105/27105/19222 +f 27102/27102/19219 27105/27105/19222 27103/27103/19220 +f 27104/27104/19221 27106/27106/19223 27107/27107/19224 +f 27104/27104/19221 27107/27107/19224 27105/27105/19222 +f 27108/27108/19225 26840/26840/19011 26842/26842/19013 +f 27108/27108/19225 26842/26842/19013 27097/27097/19214 +f 27097/27097/19214 26842/26842/19013 26851/26851/19022 +f 27097/27097/19214 26851/26851/19022 27098/27098/19215 +f 27098/27098/19215 26851/26851/19022 26850/26850/19021 +f 27098/27098/19215 26850/26850/19021 27101/27101/19218 +f 27101/27101/19218 26850/26850/19021 26518/26518/18697 +f 27101/27101/19218 26518/26518/18697 27109/27109/19226 +f 27099/27099/19216 27101/27101/19218 27109/27109/19226 +f 27099/27099/19216 27109/27109/19226 27110/27110/18964 +f 27100/27100/19217 27099/27099/19216 27110/27110/18964 +f 27100/27100/19217 27110/27110/18964 27111/27111/18963 +f 26940/26940/19096 27100/27100/19217 27111/27111/18963 +f 26940/26940/19096 27111/27111/18963 26941/26941/19097 +f 26939/26939/19095 27096/27096/19213 27100/27100/19217 +f 26939/26939/19095 27100/27100/19217 26940/26940/19096 +f 26938/26938/19094 27093/27093/19210 27096/27096/19213 +f 26938/26938/19094 27096/27096/19213 26939/26939/19095 +f 27112/27112/19227 27113/27113/19228 27114/27114/19229 +f 27112/27112/19227 27114/27114/19229 27115/27115/19230 +f 27113/27113/19228 27116/27116/19231 27117/27117/19232 +f 27113/27113/19228 27117/27117/19232 27114/27114/19229 +f 27115/27115/19230 27114/27114/19229 27118/27118/19233 +f 27115/27115/19230 27118/27118/19233 27119/27119/19234 +f 27114/27114/19229 27117/27117/19232 27120/27120/19235 +f 27114/27114/19229 27120/27120/19235 27118/27118/19233 +f 26712/26712/18890 26710/26710/18888 27121/27121/19227 +f 26712/26712/18890 27121/27121/19227 27122/27122/19236 +f 26710/26710/18888 26709/26709/18887 27123/27123/19228 +f 26710/26710/18888 27123/27123/19228 27121/27121/19227 +f 26709/26709/18887 26708/26708/18886 27124/27124/19231 +f 26709/26709/18887 27124/27124/19231 27123/27123/19228 +f 26708/26708/18886 26597/26597/18776 26980/26980/19130 +f 26708/26708/18886 26980/26980/19130 27124/27124/19231 +f 27116/27116/19231 26991/26991/19130 26990/26990/19135 +f 27116/27116/19231 26990/26990/19135 27117/27117/19232 +f 27117/27117/19232 26990/26990/19135 26988/26988/19134 +f 27117/27117/19232 26988/26988/19134 27120/27120/19235 +f 27120/27120/19235 26988/26988/19134 26989/26989/18851 +f 27120/27120/19235 26989/26989/18851 27125/27125/18849 +f 27118/27118/19233 27120/27120/19235 27125/27125/18849 +f 27118/27118/19233 27125/27125/18849 27126/27126/18848 +f 27119/27119/19234 27118/27118/19233 27126/27126/18848 +f 27119/27119/19234 27126/27126/18848 27127/27127/19237 +f 27128/27128/19238 27119/27119/19234 27127/27127/19237 +f 27128/27128/19238 27127/27127/19237 27129/27129/18846 +f 27130/27130/19239 27115/27115/19230 27119/27119/19234 +f 27130/27130/19239 27119/27119/19234 27128/27128/19238 +f 27131/27131/19240 27112/27112/19227 27115/27115/19230 +f 27131/27131/19240 27115/27115/19230 27130/27130/19239 +f 27132/27132/19241 27133/27133/19242 27134/27134/19243 +f 27132/27132/19241 27134/27134/19243 27135/27135/19244 +f 27133/27133/19242 27136/27136/19245 27137/27137/19246 +f 27133/27133/19242 27137/27137/19246 27134/27134/19243 +f 27135/27135/19244 27134/27134/19243 27138/27138/19247 +f 27135/27135/19244 27138/27138/19247 27139/27139/19248 +f 27134/27134/19243 27137/27137/19246 27140/27140/19249 +f 27134/27134/19243 27140/27140/19249 27138/27138/19247 +f 26703/26703/18881 26731/26731/18908 27141/27141/19241 +f 26703/26703/18881 27141/27141/19241 27031/27031/19167 +f 26731/26731/18908 26730/26730/18907 27142/27142/19250 +f 26731/26731/18908 27142/27142/19250 27141/27141/19241 +f 26729/26729/18906 26727/26727/18904 27143/27143/19245 +f 26729/26729/18906 27143/27143/19245 27144/27144/19242 +f 26727/26727/18904 26726/26726/18903 26888/26888/19054 +f 26727/26727/18904 26888/26888/19054 27143/27143/19245 +f 27136/27136/19245 26902/26902/19054 26901/26901/19064 +f 27136/27136/19245 26901/26901/19064 27137/27137/19246 +f 27137/27137/19246 26901/26901/19064 26899/26899/19062 +f 27137/27137/19246 26899/26899/19062 27140/27140/19249 +f 27140/27140/19249 26899/26899/19062 26900/26900/19063 +f 27140/27140/19249 26900/26900/19063 27145/27145/19251 +f 27138/27138/19247 27140/27140/19249 27145/27145/19251 +f 27138/27138/19247 27145/27145/19251 27146/27146/18870 +f 27139/27139/19248 27138/27138/19247 27146/27146/18870 +f 27139/27139/19248 27146/27146/18870 27147/27147/19252 +f 27034/27034/19170 27139/27139/19248 27147/27147/19252 +f 27034/27034/19170 27147/27147/19252 27035/27035/19171 +f 27033/27033/19169 27135/27135/19244 27139/27139/19248 +f 27033/27033/19169 27139/27139/19248 27034/27034/19170 +f 27032/27032/19168 27132/27132/19241 27135/27135/19244 +f 27032/27032/19168 27135/27135/19244 27033/27033/19169 +f 27148/27148/19253 27149/27149/19254 27150/27150/19255 +f 27148/27148/19253 27150/27150/19255 27151/27151/19256 +f 27149/27149/19254 27152/27152/19257 27153/27153/19258 +f 27149/27149/19254 27153/27153/19258 27150/27150/19255 +f 27151/27151/19256 27150/27150/19255 27154/27154/19259 +f 27151/27151/19256 27154/27154/19259 27155/27155/19260 +f 27150/27150/19255 27153/27153/19258 27156/27156/19261 +f 27150/27150/19255 27156/27156/19261 27154/27154/19259 +f 27053/27053/18913 27157/27157/18911 27148/27148/19253 +f 27053/27053/18913 27148/27148/19253 27054/27054/19184 +f 27157/27157/18911 27158/27158/18910 27149/27149/19254 +f 27157/27157/18911 27149/27149/19254 27148/27148/19253 +f 27158/27158/18910 27159/27159/18909 27152/27152/19257 +f 27158/27158/18910 27152/27152/19257 27149/27149/19254 +f 26732/26732/18909 26712/26712/18890 27122/27122/19236 +f 26732/26732/18909 27122/27122/19236 27160/27160/19262 +f 27152/27152/19257 27131/27131/19240 27130/27130/19239 +f 27152/27152/19257 27130/27130/19239 27153/27153/19258 +f 27153/27153/19258 27130/27130/19239 27128/27128/19238 +f 27153/27153/19258 27128/27128/19238 27156/27156/19261 +f 27156/27156/19261 27128/27128/19238 27129/27129/18846 +f 27156/27156/19261 27129/27129/18846 27161/27161/19263 +f 27154/27154/19259 27156/27156/19261 27161/27161/19263 +f 27154/27154/19259 27161/27161/19263 27162/27162/18867 +f 27155/27155/19260 27154/27154/19259 27162/27162/18867 +f 27155/27155/19260 27162/27162/18867 27163/27163/18865 +f 27056/27056/19186 27155/27155/19260 27163/27163/18865 +f 27056/27056/19186 27163/27163/18865 27057/27057/18796 +f 27055/27055/19185 27151/27151/19256 27155/27155/19260 +f 27055/27055/19185 27155/27155/19260 27056/27056/19186 +f 27054/27054/19184 27148/27148/19253 27151/27151/19256 +f 27054/27054/19184 27151/27151/19256 27055/27055/19185 +f 27164/27164/19264 27165/27165/19265 27166/27166/19266 +f 27164/27164/19264 27166/27166/19266 27167/27167/19267 +f 27165/27165/19265 27168/27168/19268 27169/27169/19269 +f 27165/27165/19265 27169/27169/19269 27166/27166/19266 +f 27167/27167/19267 27166/27166/19266 27170/27170/19270 +f 27167/27167/19267 27170/27170/19270 27171/27171/19271 +f 27166/27166/19266 27169/27169/19269 27172/27172/19272 +f 27166/27166/19266 27172/27172/19272 27170/27170/19270 +f 26429/26429/18627 27173/27173/19076 27164/27164/19264 +f 26429/26429/18627 27164/27164/19264 26430/26430/18628 +f 27173/27173/19076 27174/27174/19075 27165/27165/19265 +f 27173/27173/19076 27165/27165/19265 27164/27164/19264 +f 27174/27174/19075 27175/27175/19074 27168/27168/19268 +f 27174/27174/19075 27168/27168/19268 27165/27165/19265 +f 27175/27175/19074 27176/27176/19273 27177/27177/19274 +f 27175/27175/19074 27177/27177/19274 27168/27168/19268 +f 27168/27168/19268 27177/27177/19274 27178/27178/19275 +f 27168/27168/19268 27178/27178/19275 27169/27169/19269 +f 27169/27169/19269 27178/27178/19275 27179/27179/19276 +f 27169/27169/19269 27179/27179/19276 27172/27172/19272 +f 27172/27172/19272 27179/27179/19276 27180/27180/19011 +f 27172/27172/19272 27180/27180/19011 27106/27106/19223 +f 27170/27170/19270 27172/27172/19272 27106/27106/19223 +f 27170/27170/19270 27106/27106/19223 27104/27104/19221 +f 27171/27171/19271 27170/27170/19270 27104/27104/19221 +f 27171/27171/19271 27104/27104/19221 27102/27102/19219 +f 26432/26432/18630 27171/27171/19271 27102/27102/19219 +f 26432/26432/18630 27102/27102/19219 26433/26433/18631 +f 26431/26431/18629 27167/27167/19267 27171/27171/19271 +f 26431/26431/18629 27171/27171/19271 26432/26432/18630 +f 26430/26430/18628 27164/27164/19264 27167/27167/19267 +f 26430/26430/18628 27167/27167/19267 26431/26431/18629 +f 27181/27181/19277 27182/27182/19278 27183/27183/19279 +f 27181/27181/19277 27183/27183/19279 27184/27184/19280 +f 27182/27182/19278 27185/27185/19281 27186/27186/19282 +f 27182/27182/19278 27186/27186/19282 27183/27183/19279 +f 27184/27184/19280 27183/27183/19279 27187/27187/19283 +f 27184/27184/19280 27187/27187/19283 27188/27188/19284 +f 27183/27183/19279 27186/27186/19282 27189/27189/19285 +f 27183/27183/19279 27189/27189/19285 27187/27187/19283 +f 27190/27190/19273 26867/26867/19036 27181/27181/19277 +f 27190/27190/19273 27181/27181/19277 27191/27191/19286 +f 26867/26867/19036 26865/26865/19034 27182/27182/19278 +f 26867/26867/19036 27182/27182/19278 27181/27181/19277 +f 26865/26865/19034 26862/26862/19032 27185/27185/19281 +f 26865/26865/19034 27185/27185/19281 27182/27182/19278 +f 26862/26862/19032 26861/26861/18974 27192/27192/18976 +f 26862/26862/19032 27192/27192/18976 27185/27185/19281 +f 27185/27185/19281 27192/27192/18976 27193/27193/18984 +f 27185/27185/19281 27193/27193/18984 27186/27186/19282 +f 27186/27186/19282 27193/27193/18984 27194/27194/18982 +f 27186/27186/19282 27194/27194/18982 27189/27189/19285 +f 27189/27189/19285 27194/27194/18982 27195/27195/19016 +f 27189/27189/19285 27195/27195/19016 27196/27196/19015 +f 27187/27187/19283 27189/27189/19285 27196/27196/19015 +f 27187/27187/19283 27196/27196/19015 27197/27197/19014 +f 27188/27188/19284 27187/27187/19283 27197/27197/19014 +f 27188/27188/19284 27197/27197/19014 27198/27198/19287 +f 27199/27199/19276 27188/27188/19284 27198/27198/19287 +f 27199/27199/19276 27198/27198/19287 27200/27200/19011 +f 27201/27201/19275 27184/27184/19280 27188/27188/19284 +f 27201/27201/19275 27188/27188/19284 27199/27199/19276 +f 27191/27191/19286 27181/27181/19277 27184/27184/19280 +f 27191/27191/19286 27184/27184/19280 27201/27201/19275 +o Cube.043__0 +v -0.482489 -0.426740 -0.084474 +v -0.483680 -0.414345 -0.079690 +v -0.493261 -0.416451 -0.079690 +v -0.489608 -0.428031 -0.084474 +v -0.484871 -0.401950 -0.084474 +v -0.496914 -0.404871 -0.084474 +v -0.508435 -0.409426 -0.084474 +v -0.501838 -0.419677 -0.079690 +v -0.495240 -0.429927 -0.084474 +v -0.464451 -0.426145 -0.084474 +v -0.464451 -0.413385 -0.079690 +v -0.474032 -0.413505 -0.079690 +v -0.473883 -0.426219 -0.084474 +v -0.464451 -0.400626 -0.084474 +v -0.474180 -0.400791 -0.084474 +v -0.464451 -0.400626 -0.109994 +v -0.474180 -0.400791 -0.109994 +v -0.474237 -0.396024 -0.097234 +v -0.464451 -0.395841 -0.097234 +v -0.484871 -0.401950 -0.109994 +v -0.485317 -0.397302 -0.097234 +v -0.484871 -0.401950 -0.084474 +v -0.474180 -0.400791 -0.084474 +v -0.464451 -0.400626 -0.084474 +v -0.482489 -0.426740 -0.109994 +v -0.473883 -0.426219 -0.109994 +v -0.473827 -0.430987 -0.097234 +v -0.482043 -0.431388 -0.097234 +v -0.464451 -0.426145 -0.109994 +v -0.464451 -0.430930 -0.097234 +v -0.464451 -0.426145 -0.084474 +v -0.473883 -0.426219 -0.084474 +v -0.482489 -0.426740 -0.084474 +v -0.482489 -0.426740 -0.109994 +v -0.483680 -0.414345 -0.114779 +v -0.474032 -0.413505 -0.114779 +v -0.473883 -0.426219 -0.109994 +v -0.484871 -0.401950 -0.109994 +v -0.474180 -0.400791 -0.109994 +v -0.464451 -0.400626 -0.109994 +v -0.464451 -0.413385 -0.114779 +v -0.464451 -0.426145 -0.109994 +v -0.495240 -0.429927 -0.109994 +v -0.492766 -0.433771 -0.097234 +v -0.496612 -0.436254 -0.097234 +v -0.499968 -0.433064 -0.109994 +v -0.495240 -0.429927 -0.084474 +v -0.499968 -0.433064 -0.084474 +v -0.496612 -0.436254 -0.097234 +v -0.499968 -0.433064 -0.084474 +v -0.506040 -0.441765 -0.084474 +v -0.502084 -0.444285 -0.097234 +v -0.499968 -0.433064 -0.109994 +v -0.506040 -0.441765 -0.109994 +v -0.498284 -0.400529 -0.097234 +v -0.496914 -0.404871 -0.084474 +v -0.496914 -0.404871 -0.109994 +v -0.508435 -0.409426 -0.109994 +v -0.510909 -0.405582 -0.097234 +v -0.508435 -0.409426 -0.084474 +v -0.488238 -0.432374 -0.097234 +v -0.489608 -0.428031 -0.109994 +v -0.489608 -0.428031 -0.084474 +v -0.493261 -0.416451 -0.114779 +v -0.496914 -0.404871 -0.109994 +v -0.489608 -0.428031 -0.109994 +v -0.495240 -0.429927 -0.109994 +v -0.501838 -0.419677 -0.114779 +v -0.508435 -0.409426 -0.109994 +v -0.527143 -0.428324 -0.109994 +v -0.516592 -0.435044 -0.114779 +v -0.526886 -0.456234 -0.114779 +v -0.538389 -0.450999 -0.109994 +v -0.506040 -0.441765 -0.109994 +v -0.515384 -0.461469 -0.109994 +v -0.526960 -0.498377 -0.109994 +v -0.538989 -0.494358 -0.114779 +v -0.551020 -0.490339 -0.109994 +v -0.508918 -0.424556 -0.114779 +v -0.517868 -0.416049 -0.109994 +v -0.499968 -0.433064 -0.109994 +v -0.508918 -0.424556 -0.079690 +v -0.499968 -0.433064 -0.084474 +v -0.517868 -0.416049 -0.084474 +v -0.527143 -0.428324 -0.084474 +v -0.516592 -0.435044 -0.079690 +v -0.506040 -0.441765 -0.084474 +v -0.521224 -0.412859 -0.097234 +v -0.517868 -0.416049 -0.084474 +v -0.510909 -0.405582 -0.097234 +v -0.508435 -0.409426 -0.109994 +v -0.517868 -0.416049 -0.109994 +v -0.521224 -0.412859 -0.097234 +v -0.527143 -0.428324 -0.109994 +v -0.531099 -0.425803 -0.097234 +v -0.531099 -0.425803 -0.097234 +v -0.527143 -0.428324 -0.084474 +v -0.551020 -0.490339 -0.084474 +v -0.555531 -0.488832 -0.097234 +v -0.568268 -0.547645 -0.097234 +v -0.563642 -0.548719 -0.084474 +v -0.551020 -0.490339 -0.109994 +v -0.563642 -0.548719 -0.109994 +v -0.574368 -0.611456 -0.109994 +v -0.579025 -0.610999 -0.097234 +v -0.574368 -0.611456 -0.084474 +v -0.526886 -0.456234 -0.079690 +v -0.515384 -0.461469 -0.084474 +v -0.538389 -0.450999 -0.084474 +v -0.551020 -0.490339 -0.084474 +v -0.538989 -0.494358 -0.079690 +v -0.526960 -0.498377 -0.084474 +v -0.527143 -0.428324 -0.084474 +v -0.542703 -0.449036 -0.097234 +v -0.538389 -0.450999 -0.084474 +v -0.538389 -0.450999 -0.109994 +v -0.511070 -0.463432 -0.097234 +v -0.515384 -0.461469 -0.109994 +v -0.515384 -0.461469 -0.084474 +v -0.526960 -0.498377 -0.084474 +v -0.522448 -0.499884 -0.097234 +v -0.526960 -0.498377 -0.109994 +v -0.574368 -0.611456 -0.109994 +v -0.561949 -0.612673 -0.114779 +v -0.569033 -0.661205 -0.114779 +v -0.581213 -0.662543 -0.109994 +v -0.549531 -0.613890 -0.109994 +v -0.556853 -0.659867 -0.109994 +v -0.559557 -0.689070 -0.109994 +v -0.570933 -0.693411 -0.114779 +v -0.582310 -0.697752 -0.109994 +v -0.534342 -0.555521 -0.097234 +v -0.538968 -0.554447 -0.109994 +v -0.538968 -0.554447 -0.084474 +v -0.549531 -0.613890 -0.084474 +v -0.544874 -0.614347 -0.097234 +v -0.549531 -0.613890 -0.109994 +v -0.551305 -0.551583 -0.114779 +v -0.563642 -0.548719 -0.109994 +v -0.538968 -0.554447 -0.109994 +v -0.551305 -0.551583 -0.079690 +v -0.538968 -0.554447 -0.084474 +v -0.563642 -0.548719 -0.084474 +v -0.574368 -0.611456 -0.084474 +v -0.561949 -0.612673 -0.079690 +v -0.549531 -0.613890 -0.084474 +v -0.559557 -0.689070 -0.084474 +v -0.570933 -0.693411 -0.079690 +v -0.566801 -0.710227 -0.079690 +v -0.556957 -0.703054 -0.084474 +v -0.582310 -0.697752 -0.084474 +v -0.576647 -0.717399 -0.084474 +v -0.566504 -0.728211 -0.084474 +v -0.558609 -0.718750 -0.079690 +v -0.550715 -0.709288 -0.084474 +v -0.569033 -0.661205 -0.079690 +v -0.556853 -0.659867 -0.084474 +v -0.581213 -0.662543 -0.084474 +v -0.585780 -0.663045 -0.097234 +v -0.581213 -0.662543 -0.084474 +v -0.581213 -0.662543 -0.109994 +v -0.582310 -0.697752 -0.109994 +v -0.586576 -0.699380 -0.097234 +v -0.582310 -0.697752 -0.084474 +v -0.552286 -0.659365 -0.097234 +v -0.556853 -0.659867 -0.109994 +v -0.556853 -0.659867 -0.084474 +v -0.559557 -0.689070 -0.084474 +v -0.555291 -0.687442 -0.097234 +v -0.559557 -0.689070 -0.109994 +v -0.566504 -0.728211 -0.084474 +v -0.569465 -0.731760 -0.097234 +v -0.556720 -0.740944 -0.097234 +v -0.554506 -0.736823 -0.084474 +v -0.566504 -0.728211 -0.109994 +v -0.554506 -0.736823 -0.109994 +v -0.541337 -0.743087 -0.109994 +v -0.542849 -0.747549 -0.097234 +v -0.541337 -0.743087 -0.084474 +v -0.580338 -0.720089 -0.097234 +v -0.576647 -0.717399 -0.084474 +v -0.576647 -0.717399 -0.109994 +v -0.566504 -0.728211 -0.109994 +v -0.569465 -0.731760 -0.097234 +v -0.576647 -0.717399 -0.084474 +v -0.580338 -0.720089 -0.097234 +v -0.553265 -0.700365 -0.097234 +v -0.556957 -0.703054 -0.109994 +v -0.556957 -0.703054 -0.084474 +v -0.550715 -0.709288 -0.084474 +v -0.547754 -0.705740 -0.097234 +v -0.556957 -0.703054 -0.109994 +v -0.553265 -0.700365 -0.097234 +v -0.547754 -0.705740 -0.097234 +v -0.550715 -0.709288 -0.109994 +v -0.566801 -0.710227 -0.114779 +v -0.576647 -0.717399 -0.109994 +v -0.558609 -0.718750 -0.114779 +v -0.566504 -0.728211 -0.109994 +v -0.541337 -0.743087 -0.109994 +v -0.537302 -0.731189 -0.114779 +v -0.524437 -0.733406 -0.114779 +v -0.526850 -0.745807 -0.109994 +v -0.533268 -0.719290 -0.109994 +v -0.522025 -0.721005 -0.109994 +v -0.507135 -0.721085 -0.109994 +v -0.508326 -0.733722 -0.114779 +v -0.509516 -0.746360 -0.109994 +v -0.550715 -0.709288 -0.109994 +v -0.547754 -0.705740 -0.097234 +v -0.540488 -0.710722 -0.097234 +v -0.542701 -0.714843 -0.109994 +v -0.550715 -0.709288 -0.084474 +v -0.542701 -0.714843 -0.084474 +v -0.533268 -0.719290 -0.084474 +v -0.531755 -0.714828 -0.097234 +v -0.533268 -0.719290 -0.109994 +v -0.548604 -0.725833 -0.114779 +v -0.554506 -0.736823 -0.109994 +v -0.542701 -0.714843 -0.109994 +v -0.548604 -0.725833 -0.079690 +v -0.542701 -0.714843 -0.084474 +v -0.554506 -0.736823 -0.084474 +v -0.541337 -0.743087 -0.084474 +v -0.537302 -0.731189 -0.079690 +v -0.533268 -0.719290 -0.084474 +v -0.509516 -0.746360 -0.084474 +v -0.509962 -0.751099 -0.097234 +v -0.488335 -0.751215 -0.097234 +v -0.488164 -0.746444 -0.084474 +v -0.509516 -0.746360 -0.109994 +v -0.488164 -0.746444 -0.109994 +v -0.464451 -0.746456 -0.109994 +v -0.464451 -0.751231 -0.097234 +v -0.464451 -0.746456 -0.084474 +v -0.524437 -0.733406 -0.079690 +v -0.522025 -0.721005 -0.084474 +v -0.526850 -0.745807 -0.084474 +v -0.509516 -0.746360 -0.084474 +v -0.508326 -0.733722 -0.079690 +v -0.507135 -0.721085 -0.084474 +v -0.527755 -0.750457 -0.097234 +v -0.526850 -0.745807 -0.084474 +v -0.526850 -0.745807 -0.109994 +v -0.521120 -0.716355 -0.097234 +v -0.522025 -0.721005 -0.109994 +v -0.522025 -0.721005 -0.084474 +v -0.507135 -0.721085 -0.084474 +v -0.506689 -0.716346 -0.097234 +v -0.507135 -0.721085 -0.109994 +v -0.487084 -0.716231 -0.097234 +v -0.487254 -0.721001 -0.109994 +v -0.487254 -0.721001 -0.084474 +v -0.464451 -0.720989 -0.084474 +v -0.464451 -0.716214 -0.097234 +v -0.464451 -0.720989 -0.109994 +v -0.487709 -0.733723 -0.114779 +v -0.488164 -0.746444 -0.109994 +v -0.487254 -0.721001 -0.109994 +v -0.464451 -0.720989 -0.109994 +v -0.464451 -0.733723 -0.114779 +v -0.464451 -0.746456 -0.109994 +v -0.487709 -0.733722 -0.079690 +v -0.487254 -0.721001 -0.084474 +v -0.488164 -0.746444 -0.084474 +v -0.464451 -0.746456 -0.084474 +v -0.464451 -0.733722 -0.079690 +v -0.464451 -0.720989 -0.084474 +v -0.446413 -0.426740 -0.084474 +v -0.439294 -0.428031 -0.084474 +v -0.435641 -0.416451 -0.079690 +v -0.445222 -0.414345 -0.079690 +v -0.433662 -0.429927 -0.084474 +v -0.427064 -0.419677 -0.079690 +v -0.420466 -0.409426 -0.084474 +v -0.431988 -0.404871 -0.084474 +v -0.444031 -0.401950 -0.084474 +v -0.455019 -0.426219 -0.084474 +v -0.454870 -0.413505 -0.079690 +v -0.454721 -0.400791 -0.084474 +v -0.454665 -0.396024 -0.097234 +v -0.454721 -0.400791 -0.109994 +v -0.454721 -0.400791 -0.084474 +v -0.444031 -0.401950 -0.084474 +v -0.443584 -0.397302 -0.097234 +v -0.444031 -0.401950 -0.109994 +v -0.446413 -0.426740 -0.109994 +v -0.446860 -0.431388 -0.097234 +v -0.455075 -0.430987 -0.097234 +v -0.455019 -0.426219 -0.109994 +v -0.446413 -0.426740 -0.084474 +v -0.455019 -0.426219 -0.084474 +v -0.446413 -0.426740 -0.109994 +v -0.455019 -0.426219 -0.109994 +v -0.454870 -0.413505 -0.114779 +v -0.445222 -0.414345 -0.114779 +v -0.454721 -0.400791 -0.109994 +v -0.444031 -0.401950 -0.109994 +v -0.433662 -0.429927 -0.109994 +v -0.428934 -0.433064 -0.109994 +v -0.432291 -0.436254 -0.097234 +v -0.436136 -0.433771 -0.097234 +v -0.428934 -0.433064 -0.109994 +v -0.422861 -0.441765 -0.109994 +v -0.426818 -0.444285 -0.097234 +v -0.432291 -0.436254 -0.097234 +v -0.426818 -0.444285 -0.097234 +v -0.422861 -0.441765 -0.084474 +v -0.428934 -0.433064 -0.084474 +v -0.433662 -0.429927 -0.084474 +v -0.431988 -0.404871 -0.084474 +v -0.430618 -0.400529 -0.097234 +v -0.420466 -0.409426 -0.084474 +v -0.417992 -0.405582 -0.097234 +v -0.420466 -0.409426 -0.109994 +v -0.431988 -0.404871 -0.109994 +v -0.439294 -0.428031 -0.109994 +v -0.440664 -0.432374 -0.097234 +v -0.439294 -0.428031 -0.084474 +v -0.431988 -0.404871 -0.109994 +v -0.435641 -0.416451 -0.114779 +v -0.420466 -0.409426 -0.109994 +v -0.427064 -0.419677 -0.114779 +v -0.433662 -0.429927 -0.109994 +v -0.439294 -0.428031 -0.109994 +v -0.401760 -0.428324 -0.109994 +v -0.390513 -0.450999 -0.109994 +v -0.402015 -0.456234 -0.114779 +v -0.412311 -0.435044 -0.114779 +v -0.377882 -0.490339 -0.109994 +v -0.389912 -0.494358 -0.114779 +v -0.401942 -0.498377 -0.109994 +v -0.413518 -0.461469 -0.109994 +v -0.422861 -0.441765 -0.109994 +v -0.411035 -0.416049 -0.109994 +v -0.419985 -0.424556 -0.114779 +v -0.428934 -0.433064 -0.109994 +v -0.428934 -0.433064 -0.084474 +v -0.419985 -0.424556 -0.079690 +v -0.422861 -0.441765 -0.084474 +v -0.412311 -0.435044 -0.079690 +v -0.401760 -0.428324 -0.084474 +v -0.411035 -0.416049 -0.084474 +v -0.411035 -0.416049 -0.084474 +v -0.407678 -0.412859 -0.097234 +v -0.411035 -0.416049 -0.084474 +v -0.401760 -0.428324 -0.084474 +v -0.397803 -0.425803 -0.097234 +v -0.407678 -0.412859 -0.097234 +v -0.401760 -0.428324 -0.109994 +v -0.411035 -0.416049 -0.109994 +v -0.411035 -0.416049 -0.109994 +v -0.377882 -0.490339 -0.084474 +v -0.365260 -0.548719 -0.084474 +v -0.360633 -0.547645 -0.097234 +v -0.373371 -0.488832 -0.097234 +v -0.354534 -0.611456 -0.084474 +v -0.349877 -0.610999 -0.097234 +v -0.354534 -0.611456 -0.109994 +v -0.365260 -0.548719 -0.109994 +v -0.377882 -0.490339 -0.109994 +v -0.413518 -0.461469 -0.084474 +v -0.402015 -0.456234 -0.079690 +v -0.401942 -0.498377 -0.084474 +v -0.389912 -0.494358 -0.079690 +v -0.377882 -0.490339 -0.084474 +v -0.390513 -0.450999 -0.084474 +v -0.390513 -0.450999 -0.084474 +v -0.386199 -0.449036 -0.097234 +v -0.390513 -0.450999 -0.109994 +v -0.413518 -0.461469 -0.109994 +v -0.417832 -0.463432 -0.097234 +v -0.401942 -0.498377 -0.109994 +v -0.406453 -0.499884 -0.097234 +v -0.401942 -0.498377 -0.084474 +v -0.413518 -0.461469 -0.084474 +v -0.422861 -0.441765 -0.084474 +v -0.354534 -0.611456 -0.109994 +v -0.347689 -0.662543 -0.109994 +v -0.359869 -0.661205 -0.114779 +v -0.366952 -0.612673 -0.114779 +v -0.346592 -0.697752 -0.109994 +v -0.357969 -0.693411 -0.114779 +v -0.369345 -0.689070 -0.109994 +v -0.372049 -0.659867 -0.109994 +v -0.379370 -0.613890 -0.109994 +v -0.389933 -0.554447 -0.109994 +v -0.394560 -0.555521 -0.097234 +v -0.379370 -0.613890 -0.109994 +v -0.384027 -0.614347 -0.097234 +v -0.379370 -0.613890 -0.084474 +v -0.389933 -0.554447 -0.084474 +v -0.365260 -0.548719 -0.109994 +v -0.377596 -0.551583 -0.114779 +v -0.389933 -0.554447 -0.109994 +v -0.389933 -0.554447 -0.084474 +v -0.377596 -0.551583 -0.079690 +v -0.379370 -0.613890 -0.084474 +v -0.366952 -0.612673 -0.079690 +v -0.354534 -0.611456 -0.084474 +v -0.365260 -0.548719 -0.084474 +v -0.369345 -0.689070 -0.084474 +v -0.371945 -0.703054 -0.084474 +v -0.362100 -0.710227 -0.079690 +v -0.357969 -0.693411 -0.079690 +v -0.378187 -0.709288 -0.084474 +v -0.370292 -0.718750 -0.079690 +v -0.362397 -0.728211 -0.084474 +v -0.352256 -0.717399 -0.084474 +v -0.346592 -0.697752 -0.084474 +v -0.372049 -0.659867 -0.084474 +v -0.359869 -0.661205 -0.079690 +v -0.347689 -0.662543 -0.084474 +v -0.347689 -0.662543 -0.084474 +v -0.343122 -0.663045 -0.097234 +v -0.346592 -0.697752 -0.084474 +v -0.342326 -0.699380 -0.097234 +v -0.346592 -0.697752 -0.109994 +v -0.347689 -0.662543 -0.109994 +v -0.372049 -0.659867 -0.109994 +v -0.376616 -0.659365 -0.097234 +v -0.369345 -0.689070 -0.109994 +v -0.373611 -0.687442 -0.097234 +v -0.369345 -0.689070 -0.084474 +v -0.372049 -0.659867 -0.084474 +v -0.362397 -0.728211 -0.084474 +v -0.374396 -0.736823 -0.084474 +v -0.372182 -0.740944 -0.097234 +v -0.359437 -0.731760 -0.097234 +v -0.387565 -0.743087 -0.084474 +v -0.386052 -0.747549 -0.097234 +v -0.387565 -0.743087 -0.109994 +v -0.374396 -0.736823 -0.109994 +v -0.362397 -0.728211 -0.109994 +v -0.352256 -0.717399 -0.084474 +v -0.348564 -0.720089 -0.097234 +v -0.362397 -0.728211 -0.084474 +v -0.359437 -0.731760 -0.097234 +v -0.362397 -0.728211 -0.109994 +v -0.352256 -0.717399 -0.109994 +v -0.371945 -0.703054 -0.109994 +v -0.375637 -0.700365 -0.097234 +v -0.378187 -0.709288 -0.109994 +v -0.381148 -0.705740 -0.097234 +v -0.375637 -0.700365 -0.097234 +v -0.381148 -0.705740 -0.097234 +v -0.378187 -0.709288 -0.084474 +v -0.371945 -0.703054 -0.084474 +v -0.371945 -0.703054 -0.084474 +v -0.352256 -0.717399 -0.109994 +v -0.362100 -0.710227 -0.114779 +v -0.362397 -0.728211 -0.109994 +v -0.370292 -0.718750 -0.114779 +v -0.378187 -0.709288 -0.109994 +v -0.371945 -0.703054 -0.109994 +v -0.387565 -0.743087 -0.109994 +v -0.402052 -0.745807 -0.109994 +v -0.404464 -0.733406 -0.114779 +v -0.391599 -0.731189 -0.114779 +v -0.419386 -0.746360 -0.109994 +v -0.420577 -0.733723 -0.114779 +v -0.421767 -0.721085 -0.109994 +v -0.406877 -0.721005 -0.109994 +v -0.395634 -0.719290 -0.109994 +v -0.378187 -0.709288 -0.109994 +v -0.386201 -0.714844 -0.109994 +v -0.388414 -0.710722 -0.097234 +v -0.395634 -0.719290 -0.109994 +v -0.397147 -0.714828 -0.097234 +v -0.395634 -0.719290 -0.084474 +v -0.386201 -0.714843 -0.084474 +v -0.374396 -0.736823 -0.109994 +v -0.380298 -0.725833 -0.114779 +v -0.386201 -0.714844 -0.109994 +v -0.386201 -0.714843 -0.084474 +v -0.380298 -0.725833 -0.079690 +v -0.395634 -0.719290 -0.084474 +v -0.391599 -0.731189 -0.079690 +v -0.387565 -0.743087 -0.084474 +v -0.374396 -0.736823 -0.084474 +v -0.419386 -0.746360 -0.084474 +v -0.440738 -0.746444 -0.084474 +v -0.440567 -0.751215 -0.097234 +v -0.418940 -0.751099 -0.097234 +v -0.440738 -0.746444 -0.109994 +v -0.419386 -0.746360 -0.109994 +v -0.406877 -0.721005 -0.084474 +v -0.404464 -0.733406 -0.079690 +v -0.421767 -0.721085 -0.084474 +v -0.420577 -0.733723 -0.079690 +v -0.419386 -0.746360 -0.084474 +v -0.402052 -0.745807 -0.084474 +v -0.402052 -0.745807 -0.084474 +v -0.401147 -0.750457 -0.097234 +v -0.402052 -0.745807 -0.109994 +v -0.406877 -0.721005 -0.109994 +v -0.407782 -0.716355 -0.097234 +v -0.421767 -0.721085 -0.109994 +v -0.422213 -0.716346 -0.097234 +v -0.421767 -0.721085 -0.084474 +v -0.406877 -0.721005 -0.084474 +v -0.464451 -0.720989 -0.084474 +v -0.464451 -0.716214 -0.097234 +v -0.464451 -0.733722 -0.097234 +v -0.464451 -0.733722 -0.079690 +v -0.464451 -0.720989 -0.109994 +v -0.464451 -0.733723 -0.114779 +v -0.464451 -0.746456 -0.109994 +v -0.464451 -0.751231 -0.097234 +v -0.464451 -0.746456 -0.084474 +v -0.441648 -0.721001 -0.109994 +v -0.441818 -0.716231 -0.097234 +v -0.441648 -0.721001 -0.084474 +v -0.440738 -0.746444 -0.109994 +v -0.441193 -0.733722 -0.114779 +v -0.441648 -0.721001 -0.109994 +v -0.441648 -0.721001 -0.084474 +v -0.441193 -0.733722 -0.079690 +v -0.440738 -0.746444 -0.084474 +vt 0.466023 0.772893 +vt 0.465053 0.772873 +vt 0.465492 0.774091 +vt 0.464322 0.774521 +vt 0.932128 0.043731 +vt 0.932158 0.044645 +vt 0.932857 0.044489 +vt 0.932648 0.043635 +vt 0.932299 0.045564 +vt 0.933179 0.045348 +vt 0.934021 0.045012 +vt 0.933484 0.044251 +vt 0.933060 0.043495 +vt 0.930811 0.043774 +vt 0.930753 0.044715 +vt 0.931453 0.044707 +vt 0.931500 0.043769 +vt 0.930808 0.045661 +vt 0.931518 0.045649 +vt 0.917496 0.636582 +vt 0.917474 0.637301 +vt 0.918230 0.637296 +vt 0.918253 0.636574 +vt 0.917474 0.638095 +vt 0.918233 0.638120 +vt 0.919238 0.638124 +vt 0.919237 0.637330 +vt 0.919260 0.636611 +vt 0.972857 0.352508 +vt 0.972843 0.351874 +vt 0.972086 0.351834 +vt 0.972097 0.352439 +vt 0.972841 0.351178 +vt 0.972085 0.351142 +vt 0.971077 0.351141 +vt 0.971079 0.351837 +vt 0.971092 0.352471 +vt 0.972862 0.482793 +vt 0.972696 0.483646 +vt 0.973399 0.483708 +vt 0.973489 0.482831 +vt 0.972643 0.484605 +vt 0.973421 0.484691 +vt 0.974132 0.484703 +vt 0.974099 0.483717 +vt 0.974178 0.482837 +vt 0.972941 0.353437 +vt 0.972159 0.353221 +vt 0.972225 0.353496 +vt 0.973023 0.353774 +vt 0.971176 0.353400 +vt 0.971259 0.353737 +vt 0.661830 0.064797 +vt 0.660844 0.064631 +vt 0.660736 0.065290 +vt 0.661733 0.065405 +vt 0.662610 0.064511 +vt 0.662501 0.065170 +vt 0.918282 0.639092 +vt 0.919281 0.639027 +vt 0.917517 0.638998 +vt 0.917605 0.639870 +vt 0.918379 0.640048 +vt 0.919369 0.639899 +vt 0.972123 0.352892 +vt 0.972891 0.353028 +vt 0.971126 0.352992 +vt 0.972001 0.483492 +vt 0.971769 0.484391 +vt 0.972344 0.482698 +vt 0.971937 0.482560 +vt 0.971380 0.483256 +vt 0.970936 0.484058 +vt 0.969605 0.482676 +vt 0.970331 0.482132 +vt 0.969618 0.480582 +vt 0.968824 0.481017 +vt 0.971170 0.481694 +vt 0.970523 0.480253 +vt 0.969745 0.477553 +vt 0.968803 0.477794 +vt 0.967973 0.478140 +vt 0.970872 0.482899 +vt 0.970260 0.483573 +vt 0.971597 0.482330 +vt 0.934002 0.043891 +vt 0.933405 0.043264 +vt 0.934711 0.044523 +vt 0.935389 0.043615 +vt 0.934563 0.043115 +vt 0.933850 0.042621 +vt 0.918541 0.640844 +vt 0.919516 0.640627 +vt 0.561573 0.040034 +vt 0.562543 0.039796 +vt 0.562375 0.039283 +vt 0.561388 0.039470 +vt 0.562230 0.038354 +vt 0.561234 0.038489 +vt 0.918853 0.641636 +vt 0.919812 0.641370 +vt 0.560161 0.033633 +vt 0.560968 0.033773 +vt 0.560927 0.029399 +vt 0.560120 0.029291 +vt 0.561972 0.033714 +vt 0.561931 0.029371 +vt 0.561946 0.024712 +vt 0.560943 0.024693 +vt 0.560135 0.024631 +vt 0.935318 0.041549 +vt 0.934535 0.041164 +vt 0.936213 0.041939 +vt 0.937140 0.039030 +vt 0.936206 0.038730 +vt 0.935384 0.038435 +vt 0.560419 0.038273 +vt 0.561083 0.036744 +vt 0.560273 0.036570 +vt 0.562084 0.036651 +vt 0.661607 0.066842 +vt 0.662368 0.066649 +vt 0.660603 0.066769 +vt 0.660506 0.069524 +vt 0.661512 0.069562 +vt 0.662271 0.069403 +vt 0.966488 0.469284 +vt 0.967341 0.469142 +vt 0.966911 0.465593 +vt 0.966080 0.465548 +vt 0.968305 0.469106 +vt 0.967854 0.465744 +vt 0.967709 0.463609 +vt 0.966831 0.463238 +vt 0.966064 0.462973 +vt 0.661508 0.073698 +vt 0.662267 0.073572 +vt 0.660501 0.073692 +vt 0.660552 0.078105 +vt 0.661557 0.078066 +vt 0.662318 0.077985 +vt 0.968007 0.473609 +vt 0.967157 0.473871 +vt 0.968969 0.473453 +vt 0.937112 0.034499 +vt 0.936268 0.034289 +vt 0.938069 0.034714 +vt 0.938860 0.030075 +vt 0.937897 0.029982 +vt 0.937046 0.029894 +vt 0.937787 0.024336 +vt 0.938562 0.024013 +vt 0.938263 0.022769 +vt 0.937599 0.023301 +vt 0.939450 0.023694 +vt 0.939039 0.022241 +vt 0.938299 0.021442 +vt 0.937665 0.022138 +vt 0.937144 0.022840 +vt 0.938420 0.026394 +vt 0.937586 0.026495 +vt 0.939366 0.026298 +vt 0.560999 0.020833 +vt 0.560185 0.020842 +vt 0.561996 0.020922 +vt 0.562105 0.018320 +vt 0.561118 0.018149 +vt 0.560294 0.018239 +vt 0.661610 0.081406 +vt 0.662379 0.081396 +vt 0.660613 0.081517 +vt 0.660702 0.083678 +vt 0.661685 0.083485 +vt 0.662467 0.083557 +vt 0.230282 0.006756 +vt 0.229303 0.006550 +vt 0.229079 0.007530 +vt 0.230072 0.007679 +vt 0.228517 0.006751 +vt 0.228307 0.007674 +vt 0.228161 0.008673 +vt 0.228924 0.008583 +vt 0.229926 0.008678 +vt 0.561324 0.016635 +vt 0.560484 0.016803 +vt 0.562295 0.016884 +vt 0.562543 0.016111 +vt 0.561590 0.015801 +vt 0.230552 0.005962 +vt 0.229594 0.005698 +vt 0.661807 0.084432 +vt 0.662610 0.084581 +vt 0.660844 0.084701 +vt 0.661038 0.085144 +vt 0.661977 0.084813 +vt 0.967925 0.462587 +vt 0.968339 0.462924 +vt 0.968751 0.462532 +vt 0.968392 0.462131 +vt 0.967163 0.462009 +vt 0.966513 0.461537 +vt 0.967776 0.461386 +vt 0.967273 0.460747 +vt 0.969137 0.459660 +vt 0.969354 0.460477 +vt 0.970297 0.460316 +vt 0.970200 0.459462 +vt 0.969683 0.461400 +vt 0.970507 0.461275 +vt 0.971595 0.461270 +vt 0.971474 0.460293 +vt 0.971466 0.459422 +vt 0.483291 0.001537 +vt 0.482503 0.001788 +vt 0.482372 0.002305 +vt 0.483145 0.002107 +vt 0.481528 0.001574 +vt 0.481381 0.002145 +vt 0.481264 0.002824 +vt 0.482264 0.002934 +vt 0.483028 0.002787 +vt 0.968519 0.460869 +vt 0.968165 0.460118 +vt 0.968987 0.461725 +vt 0.936936 0.021614 +vt 0.936560 0.022429 +vt 0.937424 0.020804 +vt 0.936463 0.020341 +vt 0.936111 0.021218 +vt 0.935871 0.022100 +vt 0.229882 0.011041 +vt 0.228875 0.011026 +vt 0.228900 0.012623 +vt 0.229908 0.012617 +vt 0.228117 0.011036 +vt 0.228143 0.012612 +vt 0.228174 0.014363 +vt 0.228931 0.014386 +vt 0.229939 0.014368 +vt 0.935172 0.021053 +vt 0.935050 0.021973 +vt 0.935406 0.020139 +vt 0.934140 0.020097 +vt 0.933995 0.021029 +vt 0.933963 0.021966 +vt 0.228868 0.009709 +vt 0.229873 0.009759 +vt 0.228109 0.009754 +vt 0.482223 0.003714 +vt 0.482983 0.003610 +vt 0.481219 0.003648 +vt 0.481217 0.004747 +vt 0.482224 0.004779 +vt 0.482980 0.004709 +vt 0.482227 0.006227 +vt 0.482983 0.006177 +vt 0.481219 0.006215 +vt 0.481219 0.007899 +vt 0.482227 0.007898 +vt 0.482983 0.007861 +vt 0.972979 0.460294 +vt 0.973025 0.459417 +vt 0.973046 0.461277 +vt 0.974711 0.461279 +vt 0.974678 0.460295 +vt 0.974757 0.459417 +vt 0.932490 0.021029 +vt 0.932511 0.021972 +vt 0.932581 0.020090 +vt 0.930849 0.020089 +vt 0.930791 0.021028 +vt 0.930846 0.021972 +vt 0.929494 0.043729 +vt 0.928974 0.043634 +vt 0.928650 0.044487 +vt 0.929349 0.044643 +vt 0.928563 0.043493 +vt 0.928024 0.044248 +vt 0.927597 0.045009 +vt 0.928438 0.045346 +vt 0.929317 0.045562 +vt 0.930122 0.043768 +vt 0.930054 0.044706 +vt 0.930097 0.045648 +vt 0.918285 0.635852 +vt 0.917527 0.635865 +vt 0.919291 0.635894 +vt 0.919351 0.635111 +vt 0.918349 0.635041 +vt 0.917587 0.635082 +vt 0.972857 0.349844 +vt 0.972097 0.349841 +vt 0.972086 0.350449 +vt 0.972843 0.350481 +vt 0.971092 0.349807 +vt 0.971079 0.350445 +vt 0.975496 0.482794 +vt 0.974866 0.482832 +vt 0.974798 0.483709 +vt 0.975504 0.483648 +vt 0.974842 0.484691 +vt 0.975625 0.484607 +vt 0.972941 0.348890 +vt 0.973023 0.348529 +vt 0.972225 0.348747 +vt 0.972159 0.349040 +vt 0.984440 0.777542 +vt 0.984349 0.778182 +vt 0.985346 0.778314 +vt 0.985427 0.777723 +vt 0.972436 0.348312 +vt 0.971487 0.348011 +vt 0.971259 0.348493 +vt 0.971176 0.348854 +vt 0.919461 0.634236 +vt 0.918469 0.634100 +vt 0.919612 0.633408 +vt 0.918637 0.633193 +vt 0.917848 0.633380 +vt 0.917697 0.634208 +vt 0.972891 0.349313 +vt 0.972123 0.349380 +vt 0.971126 0.349277 +vt 0.976509 0.484394 +vt 0.976207 0.483494 +vt 0.977359 0.484061 +vt 0.976839 0.483259 +vt 0.976432 0.482562 +vt 0.976018 0.482700 +vt 0.978759 0.482680 +vt 0.979621 0.481023 +vt 0.978734 0.480587 +vt 0.977944 0.482136 +vt 0.980614 0.478147 +vt 0.979687 0.477800 +vt 0.978872 0.477558 +vt 0.977960 0.480256 +vt 0.977242 0.481697 +vt 0.978059 0.483577 +vt 0.977365 0.482902 +vt 0.976783 0.482333 +vt 0.928218 0.043261 +vt 0.927507 0.043887 +vt 0.927776 0.042617 +vt 0.926948 0.043112 +vt 0.926233 0.043611 +vt 0.926909 0.044519 +vt 0.919812 0.632744 +vt 0.918856 0.632467 +vt 0.998222 0.999583 +vt 0.998032 0.998672 +vt 0.997037 0.998804 +vt 0.997239 0.999764 +vt 0.996265 0.998567 +vt 0.996455 0.999478 +vt 0.918048 0.632716 +vt 0.997665 0.994082 +vt 0.997575 0.989766 +vt 0.996568 0.989791 +vt 0.996660 0.994139 +vt 0.997550 0.985129 +vt 0.996545 0.985108 +vt 0.995784 0.985025 +vt 0.995808 0.989661 +vt 0.995899 0.993978 +vt 0.927096 0.041160 +vt 0.926199 0.041544 +vt 0.926255 0.038430 +vt 0.925320 0.038725 +vt 0.924497 0.039024 +vt 0.925415 0.041933 +vt 0.997833 0.996993 +vt 0.996831 0.997083 +vt 0.996067 0.996888 +vt 0.984236 0.779633 +vt 0.985237 0.779724 +vt 0.984145 0.782353 +vt 0.985149 0.782411 +vt 0.985954 0.782243 +vt 0.986045 0.779523 +vt 0.986159 0.778072 +vt 0.982538 0.469292 +vt 0.983130 0.465557 +vt 0.982182 0.465601 +vt 0.981577 0.469149 +vt 0.983273 0.462982 +vt 0.982379 0.463246 +vt 0.981596 0.463616 +vt 0.981346 0.465751 +vt 0.980729 0.469113 +vt 0.984123 0.786488 +vt 0.985127 0.786514 +vt 0.984144 0.790872 +vt 0.985147 0.790852 +vt 0.985953 0.790762 +vt 0.985932 0.786378 +vt 0.981641 0.473879 +vt 0.980689 0.473616 +vt 0.979850 0.473459 +vt 0.925385 0.034284 +vt 0.924427 0.034493 +vt 0.924620 0.029888 +vt 0.923657 0.029975 +vt 0.922806 0.030067 +vt 0.923582 0.034706 +vt 0.923897 0.024328 +vt 0.924089 0.023294 +vt 0.923314 0.022761 +vt 0.923011 0.024005 +vt 0.924545 0.022834 +vt 0.923914 0.022131 +vt 0.923394 0.021434 +vt 0.922653 0.022233 +vt 0.922237 0.023686 +vt 0.924091 0.026488 +vt 0.923146 0.026386 +vt 0.922313 0.026289 +vt 0.997579 0.981354 +vt 0.996580 0.981263 +vt 0.997692 0.978754 +vt 0.996705 0.978580 +vt 0.995926 0.978649 +vt 0.995812 0.981250 +vt 0.984178 0.794263 +vt 0.985175 0.794173 +vt 0.984239 0.796418 +vt 0.985226 0.796244 +vt 0.986049 0.796308 +vt 0.985987 0.794153 +vt 0.230552 0.021824 +vt 0.230310 0.020975 +vt 0.229323 0.021154 +vt 0.229581 0.022055 +vt 0.230129 0.020030 +vt 0.229132 0.020158 +vt 0.228364 0.020025 +vt 0.228546 0.020970 +vt 0.228787 0.021819 +vt 0.997917 0.977306 +vt 0.996949 0.977054 +vt 0.998222 0.976513 +vt 0.997276 0.976197 +vt 0.996455 0.976408 +vt 0.996150 0.977202 +vt 0.984349 0.797451 +vt 0.985320 0.797199 +vt 0.984504 0.797914 +vt 0.985455 0.797598 +vt 0.482645 0.014516 +vt 0.482503 0.014089 +vt 0.481528 0.014313 +vt 0.481692 0.014797 +vt 0.986159 0.797341 +vt 0.982895 0.461545 +vt 0.982108 0.462017 +vt 0.982174 0.460755 +vt 0.981525 0.461393 +vt 0.980987 0.462138 +vt 0.981432 0.462594 +vt 0.980364 0.459666 +vt 0.979311 0.459466 +vt 0.979056 0.460320 +vt 0.979992 0.460483 +vt 0.978047 0.459425 +vt 0.977881 0.460297 +vt 0.977827 0.461273 +vt 0.978914 0.461280 +vt 0.979732 0.461406 +vt 0.483291 0.014275 +vt 0.483145 0.013662 +vt 0.482372 0.013533 +vt 0.483028 0.012949 +vt 0.482264 0.012873 +vt 0.481264 0.012986 +vt 0.481381 0.013700 +vt 0.981314 0.460124 +vt 0.980807 0.460875 +vt 0.980412 0.461731 +vt 0.925131 0.022423 +vt 0.924645 0.021608 +vt 0.925821 0.022095 +vt 0.925471 0.021212 +vt 0.925234 0.020335 +vt 0.924272 0.020797 +vt 0.230001 0.017695 +vt 0.229971 0.016119 +vt 0.228963 0.016149 +vt 0.228995 0.017745 +vt 0.228206 0.016113 +vt 0.228236 0.017689 +vt 0.926642 0.021968 +vt 0.926411 0.021049 +vt 0.927729 0.021963 +vt 0.927587 0.021026 +vt 0.927558 0.020094 +vt 0.926292 0.020134 +vt 0.230038 0.018972 +vt 0.229035 0.019056 +vt 0.228274 0.018967 +vt 0.482983 0.012112 +vt 0.482223 0.012082 +vt 0.482980 0.011012 +vt 0.482224 0.011016 +vt 0.481217 0.011050 +vt 0.481219 0.012149 +vt 0.466662 0.773662 +vt 0.464322 0.773518 +vt 0.464960 0.775289 +vt 0.465930 0.775309 +vt 0.466662 0.774665 +vt 0.482983 0.009545 +vt 0.482227 0.009569 +vt 0.481219 0.009582 +vt 0.976488 0.459418 +vt 0.976376 0.460296 +vt 0.976376 0.461279 +vt 0.929181 0.021970 +vt 0.929093 0.021027 +vt 0.929117 0.020089 +vn -0.3715 0.6571 0.6559 +vn -0.3811 0.9245 -0.0003 +vn -1.0000 0.0000 0.0000 +vn -0.3811 0.9245 0.0001 +vn -0.3809 0.0004 -0.9246 +vn 0.0842 -0.7004 0.7087 +vn -0.0080 0.0140 0.9999 +vn -0.0092 0.0146 0.9999 +vn 0.1761 -0.6869 0.7052 +vn -0.1242 0.7108 0.6923 +vn -0.2197 0.6929 0.6868 +vn -0.3473 0.6448 0.6809 +vn -0.0138 0.0247 0.9996 +vn 0.3073 -0.6299 0.7133 +vn 0.0000 -0.7065 0.7077 +vn -0.0000 0.0028 1.0000 +vn -0.0034 0.0083 1.0000 +vn 0.0241 -0.7051 0.7087 +vn -0.0000 0.7097 0.7045 +vn -0.0447 0.7134 0.6993 +vn -0.0000 0.7097 -0.7045 +vn -0.0447 0.7134 -0.6993 +vn -0.0642 0.9979 -0.0001 +vn 0.0000 1.0000 0.0002 +vn -0.1242 0.7109 -0.6923 +vn -0.1742 0.9847 0.0000 +vn 0.0842 -0.7004 -0.7087 +vn 0.0241 -0.7051 -0.7087 +vn 0.0309 -0.9995 0.0000 +vn 0.1120 -0.9937 -0.0000 +vn -0.0000 -0.7065 -0.7077 +vn 0.0000 -1.0000 0.0000 +vn 0.0842 -0.7005 0.7087 +vn -0.0080 0.0140 -0.9999 +vn -0.0034 0.0082 -1.0000 +vn 0.0000 0.0025 -1.0000 +vn 0.3073 -0.6299 -0.7133 +vn 0.4286 -0.9035 -0.0000 +vn 0.6974 -0.7167 0.0000 +vn 0.4794 -0.4918 -0.7269 +vn 0.4793 -0.4917 0.7269 +vn 0.4794 -0.4917 0.7269 +vn 0.6062 -0.3520 0.7131 +vn 0.8670 -0.4983 -0.0000 +vn 0.4794 -0.4917 -0.7269 +vn 0.6062 -0.3520 -0.7132 +vn -0.3049 0.9524 -0.0000 +vn -0.2197 0.6929 -0.6868 +vn -0.3473 0.6448 -0.6809 +vn -0.4776 0.8786 0.0000 +vn 0.2380 -0.9713 0.0000 +vn 0.1760 -0.6869 -0.7051 +vn 0.1760 -0.6869 0.7052 +vn -0.0092 0.0145 -0.9999 +vn -0.0138 0.0247 -0.9996 +vn -0.6153 0.3806 -0.6903 +vn -0.0162 0.0122 -0.9998 +vn -0.0150 0.0063 -0.9999 +vn -0.6665 0.2706 -0.6946 +vn 0.6062 -0.3520 -0.7131 +vn 0.6524 -0.2556 -0.7134 +vn 0.6800 -0.1790 -0.7110 +vn -0.0103 0.0025 -0.9999 +vn -0.6912 0.1852 -0.6986 +vn -0.0260 0.0293 -0.9992 +vn -0.5087 0.5272 -0.6807 +vn -0.0251 0.0290 0.9993 +vn -0.5087 0.5271 0.6807 +vn -0.6153 0.3805 0.6904 +vn -0.0162 0.0121 0.9998 +vn 0.6062 -0.3520 0.7132 +vn -0.6952 0.7188 -0.0000 +vn -0.4775 0.8786 0.0000 +vn -0.5087 0.5271 -0.6807 +vn -0.8494 0.5277 -0.0000 +vn -0.6912 0.1852 0.6985 +vn -0.9656 0.2599 -0.0002 +vn -0.9818 0.1899 0.0001 +vn -0.7000 0.1354 0.7012 +vn -0.6912 0.1852 -0.6985 +vn -0.7000 0.1354 -0.7012 +vn -0.7086 0.1080 -0.6973 +vn -0.9888 0.1491 0.0001 +vn -0.7086 0.1080 0.6973 +vn -0.0148 0.0062 0.9999 +vn 0.6525 -0.2556 0.7134 +vn -0.6665 0.2706 0.6946 +vn -0.6912 0.1852 0.6986 +vn -0.0102 0.0024 0.9999 +vn 0.6800 -0.1790 0.7110 +vn -0.6153 0.3806 0.6903 +vn -0.9260 0.3776 0.0000 +vn 0.9319 -0.3626 0.0002 +vn 0.6524 -0.2556 0.7134 +vn 0.9673 -0.2535 0.0003 +vn 0.6800 -0.1790 -0.7111 +vn -0.0029 -0.0008 -1.0000 +vn -0.0082 -0.0013 -1.0000 +vn -0.7265 0.0597 -0.6845 +vn 0.7037 -0.1185 -0.7005 +vn 0.7147 -0.0899 -0.6937 +vn 0.7101 0.0317 -0.7034 +vn -0.0340 -0.0009 -0.9994 +vn -0.7364 -0.0925 -0.6702 +vn 0.9814 -0.1922 0.0002 +vn 0.6947 -0.1360 -0.7063 +vn 0.6947 -0.1360 0.7063 +vn 0.7037 -0.1185 0.7006 +vn 0.9858 -0.1679 -0.0001 +vn -0.0043 0.0005 -1.0000 +vn -0.0046 0.0005 1.0000 +vn -0.0030 -0.0008 1.0000 +vn 0.7037 -0.1186 0.7005 +vn 0.7100 0.0317 0.7034 +vn -0.0340 -0.0010 0.9994 +vn -0.0558 -0.0253 0.9981 +vn 0.5945 0.3115 0.7413 +vn -0.7364 -0.0925 0.6702 +vn -0.6460 -0.3670 0.6694 +vn -0.4798 -0.5470 0.6860 +vn -0.0161 -0.0148 0.9998 +vn 0.4509 0.5404 0.7103 +vn -0.0083 -0.0013 1.0000 +vn 0.7146 -0.0899 0.6937 +vn -0.7265 0.0597 0.6846 +vn -0.9971 0.0765 0.0001 +vn -0.7265 0.0597 0.6845 +vn -0.7265 0.0597 -0.6846 +vn -0.9905 -0.1375 0.0000 +vn 0.9914 -0.1310 -0.0000 +vn 0.7101 0.0318 0.7034 +vn 0.9997 0.0261 -0.0000 +vn 0.7101 0.0318 -0.7034 +vn -0.6600 -0.7513 -0.0000 +vn -0.5084 -0.8611 -0.0003 +vn -0.3681 -0.6235 0.6898 +vn -0.4798 -0.5470 -0.6860 +vn -0.3681 -0.6235 -0.6898 +vn -0.2248 -0.6903 -0.6877 +vn -0.3113 -0.9503 -0.0001 +vn -0.2248 -0.6903 0.6877 +vn -0.8656 -0.5008 0.0000 +vn -0.6460 -0.3670 0.6693 +vn -0.6460 -0.3670 -0.6693 +vn -0.6600 -0.7512 -0.0000 +vn -0.8656 -0.5007 -0.0000 +vn 0.8914 0.4533 0.0000 +vn 0.5945 0.3115 -0.7413 +vn 0.4510 0.5404 0.7103 +vn 0.6376 0.7703 -0.0000 +vn 0.5945 0.3116 -0.7413 +vn 0.4510 0.5404 -0.7103 +vn -0.0557 -0.0253 -0.9981 +vn -0.0162 -0.0148 -0.9998 +vn -0.0103 -0.0290 -0.9995 +vn -0.0028 -0.0166 -0.9999 +vn -0.0781 -0.7158 -0.6939 +vn 0.2013 0.6598 -0.7240 +vn 0.0548 0.6990 -0.7130 +vn 0.0003 0.7093 -0.7049 +vn -0.0014 -0.0020 -1.0000 +vn -0.0127 -0.7113 -0.7028 +vn 0.4510 0.5404 -0.7104 +vn 0.4990 0.8666 0.0000 +vn 0.3508 0.6079 -0.7123 +vn 0.3508 0.6079 0.7123 +vn 0.2012 0.6598 0.7240 +vn 0.2882 0.9576 0.0000 +vn 0.2012 0.6598 -0.7240 +vn -0.0114 -0.0163 -0.9998 +vn -0.0113 -0.0162 0.9998 +vn -0.0103 -0.0289 0.9995 +vn 0.2013 0.6598 0.7240 +vn -0.0127 -0.7113 0.7028 +vn -0.0197 -0.9998 -0.0001 +vn -0.0028 -1.0000 -0.0002 +vn -0.0015 -0.7083 0.7059 +vn -0.0016 -0.7083 -0.7059 +vn -0.3714 -0.6571 -0.6559 +vn -0.3811 -0.9245 -0.0000 +vn -0.3715 -0.6571 0.6559 +vn -0.0028 -0.0166 0.9999 +vn 0.0548 0.6990 0.7130 +vn -0.0781 -0.7158 0.6940 +vn -0.0014 -0.0019 1.0000 +vn 0.0003 0.7093 0.7049 +vn -0.1123 -0.9937 -0.0002 +vn -0.0781 -0.7158 -0.6940 +vn 0.0728 0.9973 0.0000 +vn 0.0549 0.6990 -0.7130 +vn 0.0549 0.6990 0.7130 +vn -0.0013 1.0000 -0.0000 +vn -0.0030 1.0000 0.0002 +vn -0.0017 0.7084 -0.7058 +vn -0.0017 0.7084 0.7058 +vn -0.3715 0.6571 -0.6559 +vn -0.0003 -0.0002 -1.0000 +vn -0.3714 0.6572 -0.6559 +vn -0.3809 -0.0000 -0.9246 +vn -0.0003 0.0002 1.0000 +vn -0.0016 -0.7083 0.7059 +vn -0.3809 0.0001 0.9246 +vn -0.0842 -0.7004 0.7087 +vn -0.1760 -0.6869 0.7051 +vn 0.0092 0.0146 0.9999 +vn 0.0079 0.0140 0.9999 +vn -0.3073 -0.6299 0.7133 +vn 0.0138 0.0247 0.9996 +vn 0.3473 0.6447 0.6809 +vn 0.2197 0.6929 0.6868 +vn 0.1242 0.7108 0.6923 +vn -0.0241 -0.7051 0.7087 +vn 0.0034 0.0083 1.0000 +vn 0.0447 0.7134 0.6993 +vn 0.0642 0.9979 -0.0001 +vn 0.0447 0.7134 -0.6993 +vn 0.1742 0.9847 0.0000 +vn 0.1242 0.7108 -0.6923 +vn -0.0842 -0.7004 -0.7087 +vn -0.1120 -0.9937 -0.0000 +vn -0.0309 -0.9995 0.0000 +vn -0.0241 -0.7051 -0.7087 +vn -0.0842 -0.7005 0.7087 +vn 0.0034 0.0082 -1.0000 +vn 0.0080 0.0140 -0.9999 +vn 0.1242 0.7109 -0.6923 +vn -0.3073 -0.6299 -0.7133 +vn -0.4794 -0.4917 -0.7269 +vn -0.6974 -0.7167 -0.0000 +vn -0.4286 -0.9035 -0.0000 +vn -0.6062 -0.3520 -0.7132 +vn -0.8670 -0.4983 -0.0000 +vn -0.6062 -0.3520 0.7132 +vn -0.4794 -0.4917 0.7269 +vn 0.3049 0.9524 0.0000 +vn 0.3473 0.6448 0.6809 +vn 0.4776 0.8786 0.0001 +vn 0.3473 0.6447 -0.6810 +vn 0.2197 0.6929 -0.6868 +vn -0.1760 -0.6869 -0.7051 +vn -0.2380 -0.9713 -0.0000 +vn -0.1760 -0.6869 0.7052 +vn 0.0092 0.0145 -0.9999 +vn 0.3473 0.6448 -0.6809 +vn 0.0138 0.0247 -0.9996 +vn 0.6153 0.3806 -0.6903 +vn 0.6665 0.2706 -0.6946 +vn 0.0149 0.0064 -0.9999 +vn 0.0162 0.0122 -0.9998 +vn 0.6912 0.1852 -0.6985 +vn 0.0107 0.0025 -0.9999 +vn -0.6800 -0.1790 -0.7110 +vn -0.6524 -0.2556 -0.7134 +vn -0.6062 -0.3520 -0.7131 +vn 0.5087 0.5272 -0.6807 +vn 0.0260 0.0293 -0.9992 +vn 0.0251 0.0290 0.9993 +vn 0.0162 0.0121 0.9998 +vn 0.6153 0.3805 0.6904 +vn 0.5087 0.5271 0.6807 +vn 0.5087 0.5272 0.6807 +vn 0.6952 0.7188 -0.0000 +vn 0.6153 0.3806 0.6903 +vn 0.8494 0.5277 -0.0000 +vn 0.5087 0.5271 -0.6807 +vn 0.5086 0.5272 -0.6807 +vn 0.6912 0.1852 0.6986 +vn 0.7000 0.1354 0.7012 +vn 0.9818 0.1899 0.0001 +vn 0.9656 0.2599 -0.0002 +vn 0.7086 0.1080 0.6973 +vn 0.9888 0.1491 0.0001 +vn 0.7086 0.1080 -0.6973 +vn 0.7000 0.1354 -0.7012 +vn 0.6912 0.1852 -0.6986 +vn -0.6525 -0.2556 0.7134 +vn 0.0148 0.0062 0.9999 +vn -0.6800 -0.1790 0.7110 +vn 0.0103 0.0024 0.9999 +vn 0.6912 0.1852 0.6985 +vn 0.6665 0.2706 0.6946 +vn 0.9260 0.3776 0.0000 +vn -0.9319 -0.3626 0.0002 +vn -0.9673 -0.2535 0.0003 +vn -0.6524 -0.2556 0.7134 +vn 0.7265 0.0597 -0.6845 +vn 0.0082 -0.0013 -1.0000 +vn 0.0028 -0.0008 -1.0000 +vn 0.7364 -0.0926 -0.6702 +vn 0.0340 -0.0009 -0.9994 +vn -0.7101 0.0317 -0.7034 +vn -0.7146 -0.0899 -0.6937 +vn -0.7037 -0.1185 -0.7005 +vn -0.6947 -0.1360 -0.7063 +vn -0.9813 -0.1923 -0.0001 +vn -0.7037 -0.1186 -0.7005 +vn -0.9858 -0.1679 -0.0001 +vn -0.7037 -0.1186 0.7006 +vn -0.6947 -0.1360 0.7063 +vn 0.0043 0.0005 -1.0000 +vn 0.0046 0.0005 1.0000 +vn -0.7037 -0.1186 0.7005 +vn 0.0030 -0.0008 1.0000 +vn -0.7100 0.0317 0.7034 +vn -0.5945 0.3115 0.7413 +vn 0.0558 -0.0253 0.9981 +vn 0.0340 -0.0010 0.9994 +vn -0.4509 0.5404 0.7104 +vn 0.0161 -0.0148 0.9998 +vn 0.4798 -0.5470 0.6860 +vn 0.6460 -0.3670 0.6694 +vn 0.7364 -0.0925 0.6702 +vn -0.7146 -0.0899 0.6937 +vn 0.0083 -0.0013 1.0000 +vn 0.7265 0.0597 0.6846 +vn 0.7265 0.0597 0.6845 +vn 0.9971 0.0765 0.0000 +vn 0.7363 -0.0925 0.6702 +vn 0.9905 -0.1375 0.0000 +vn 0.7265 0.0597 -0.6846 +vn -0.7147 -0.0899 -0.6937 +vn -0.9914 -0.1310 -0.0000 +vn -0.7100 0.0317 -0.7034 +vn -0.9997 0.0260 -0.0000 +vn -0.7100 0.0318 0.7034 +vn 0.3681 -0.6234 0.6898 +vn 0.5084 -0.8611 -0.0003 +vn 0.6600 -0.7513 -0.0000 +vn 0.2248 -0.6903 0.6877 +vn 0.3112 -0.9503 -0.0000 +vn 0.2248 -0.6903 -0.6877 +vn 0.3681 -0.6235 -0.6898 +vn 0.4798 -0.5470 -0.6860 +vn 0.8656 -0.5008 0.0000 +vn 0.6460 -0.3670 -0.6694 +vn -0.5945 0.3115 -0.7413 +vn -0.8914 0.4533 -0.0000 +vn -0.4509 0.5404 -0.7103 +vn -0.6376 0.7704 -0.0000 +vn -0.6376 0.7703 -0.0000 +vn -0.4510 0.5404 0.7103 +vn -0.5945 0.3116 0.7413 +vn 0.6460 -0.3670 -0.6693 +vn 0.0556 -0.0253 -0.9981 +vn 0.0162 -0.0148 -0.9998 +vn -0.4510 0.5404 -0.7103 +vn 0.0781 -0.7158 -0.6939 +vn 0.0028 -0.0166 -0.9999 +vn 0.0103 -0.0290 -0.9995 +vn 0.0127 -0.7113 -0.7028 +vn 0.0014 -0.0020 -1.0000 +vn -0.0003 0.7093 -0.7049 +vn -0.0548 0.6990 -0.7130 +vn -0.2012 0.6598 -0.7240 +vn -0.4510 0.5404 -0.7104 +vn -0.3508 0.6078 -0.7124 +vn -0.4990 0.8666 -0.0000 +vn -0.2883 0.9575 0.0000 +vn -0.2012 0.6598 0.7240 +vn -0.3508 0.6078 0.7124 +vn 0.0113 -0.0165 -0.9998 +vn -0.3508 0.6079 -0.7123 +vn -0.3508 0.6079 0.7124 +vn 0.0114 -0.0163 0.9998 +vn -0.2013 0.6598 0.7240 +vn 0.0103 -0.0289 0.9995 +vn 0.3681 -0.6235 0.6898 +vn 0.0127 -0.7113 0.7028 +vn 0.0016 -0.7083 0.7059 +vn 0.0028 -1.0000 -0.0002 +vn 0.0197 -0.9998 -0.0002 +vn 0.0016 -0.7083 -0.7059 +vn -0.0548 0.6990 0.7130 +vn 0.0028 -0.0166 0.9999 +vn -0.0003 0.7093 0.7049 +vn 0.0015 -0.0020 1.0000 +vn 0.0781 -0.7158 0.6939 +vn 0.0781 -0.7158 0.6940 +vn 0.1122 -0.9937 -0.0001 +vn 0.0781 -0.7158 -0.6940 +vn -0.0549 0.6990 -0.7130 +vn -0.0728 0.9973 -0.0000 +vn 0.0013 1.0000 -0.0000 +vn -0.0004 0.7093 0.7049 +vn -0.0549 0.6990 0.7130 +vn -0.3715 0.6571 0.6560 +vn -0.3811 0.9245 -0.0001 +vn -0.3715 0.6572 -0.6559 +vn -0.3809 -0.0001 -0.9246 +vn -0.3715 -0.6571 -0.6559 +vn -0.3811 -0.9245 -0.0001 +vn -0.3715 -0.6571 0.6560 +vn 0.0017 0.7084 -0.7058 +vn 0.0030 1.0000 0.0002 +vn 0.0017 0.7084 0.7058 +vn 0.0015 -0.7083 -0.7059 +vn 0.0003 -0.0002 -1.0000 +vn 0.0003 0.0002 1.0000 +usemtl Scene_-_Root +s off +f 27703/27202/19288 27704/27203/19289 27705/27204/19290 +f 27704/27203/19291 27708/27205/19292 27705/27204/19290 +s 1 +f 27202/27206/19293 27203/27207/19294 27204/27208/19295 +f 27202/27206/19293 27204/27208/19295 27205/27209/19296 +f 27203/27207/19294 27206/27210/19297 27207/27211/19298 +f 27203/27207/19294 27207/27211/19298 27204/27208/19295 +f 27204/27208/19295 27207/27211/19298 27208/27212/19299 +f 27204/27208/19295 27208/27212/19299 27209/27213/19300 +f 27205/27209/19296 27204/27208/19295 27209/27213/19300 +f 27205/27209/19296 27209/27213/19300 27210/27214/19301 +f 27211/27215/19302 27212/27216/19303 27213/27217/19304 +f 27211/27215/19302 27213/27217/19304 27214/27218/19305 +f 27212/27216/19303 27215/27219/19306 27216/27220/19307 +f 27212/27216/19303 27216/27220/19307 27213/27217/19304 +f 27213/27217/19304 27216/27220/19307 27206/27210/19297 +f 27213/27217/19304 27206/27210/19297 27203/27207/19294 +f 27214/27218/19305 27213/27217/19304 27203/27207/19294 +f 27214/27218/19305 27203/27207/19294 27202/27206/19293 +f 27217/27221/19308 27218/27222/19309 27219/27223/19310 +f 27217/27221/19308 27219/27223/19310 27220/27224/19311 +f 27218/27222/19309 27221/27225/19312 27222/27226/19313 +f 27218/27222/19309 27222/27226/19313 27219/27223/19310 +f 27219/27223/19310 27222/27226/19313 27223/27227/19297 +f 27219/27223/19310 27223/27227/19297 27224/27228/19307 +f 27220/27224/19311 27219/27223/19310 27224/27228/19307 +f 27220/27224/19311 27224/27228/19307 27225/27229/19306 +f 27226/27230/19314 27227/27231/19315 27228/27232/19316 +f 27226/27230/19314 27228/27232/19316 27229/27233/19317 +f 27227/27231/19315 27230/27234/19318 27231/27235/19319 +f 27227/27231/19315 27231/27235/19319 27228/27232/19316 +f 27228/27232/19316 27231/27235/19319 27232/27236/19302 +f 27228/27232/19316 27232/27236/19302 27233/27237/19305 +f 27229/27233/19317 27228/27232/19316 27233/27237/19305 +f 27229/27233/19317 27233/27237/19305 27234/27238/19320 +f 27235/27239/19314 27236/27240/19321 27237/27241/19322 +f 27235/27239/19314 27237/27241/19322 27238/27242/19315 +f 27236/27240/19321 27239/27243/19312 27240/27244/19309 +f 27236/27240/19321 27240/27244/19309 27237/27241/19322 +f 27237/27241/19322 27240/27244/19309 27241/27245/19308 +f 27237/27241/19322 27241/27245/19308 27242/27246/19323 +f 27238/27242/19315 27237/27241/19322 27242/27246/19323 +f 27238/27242/19315 27242/27246/19323 27243/27247/19318 +f 27244/27248/19324 27245/27249/19325 27246/27250/19326 +f 27244/27248/19324 27246/27250/19326 27247/27251/19327 +f 27245/27249/19325 27248/27252/19301 27249/27253/19328 +f 27245/27249/19325 27249/27253/19328 27246/27250/19326 +f 27250/27254/19326 27251/27255/19329 27252/27256/19330 +f 27250/27254/19326 27252/27256/19330 27253/27257/19331 +f 27254/27258/19332 27250/27254/19326 27253/27257/19331 +f 27254/27258/19332 27253/27257/19331 27255/27259/19333 +f 27223/27227/19297 27222/27226/19313 27256/27260/19334 +f 27223/27227/19297 27256/27260/19334 27257/27261/19298 +f 27222/27226/19313 27221/27225/19312 27258/27262/19335 +f 27222/27226/19313 27258/27262/19335 27256/27260/19334 +f 27256/27260/19334 27258/27262/19335 27259/27263/19336 +f 27256/27260/19334 27259/27263/19336 27260/27264/19337 +f 27257/27261/19298 27256/27260/19334 27260/27264/19337 +f 27257/27261/19298 27260/27264/19337 27261/27265/19299 +f 27226/27230/19314 27229/27233/19317 27262/27266/19338 +f 27226/27230/19314 27262/27266/19338 27263/27267/19339 +f 27229/27233/19317 27234/27238/19320 27264/27268/19340 +f 27229/27233/19317 27264/27268/19340 27262/27266/19338 +f 27262/27266/19338 27264/27268/19340 27248/27252/19301 +f 27262/27266/19338 27248/27252/19301 27245/27249/19325 +f 27263/27267/19339 27262/27266/19338 27245/27249/19325 +f 27263/27267/19339 27245/27249/19325 27244/27248/19324 +f 27239/27243/19312 27236/27240/19321 27265/27269/19341 +f 27239/27243/19312 27265/27269/19341 27266/27270/19335 +f 27236/27240/19321 27235/27239/19314 27267/27271/19339 +f 27236/27240/19321 27267/27271/19339 27265/27269/19341 +f 27265/27269/19341 27267/27271/19339 27268/27272/19324 +f 27265/27269/19341 27268/27272/19324 27269/27273/19342 +f 27266/27270/19335 27265/27269/19341 27269/27273/19342 +f 27266/27270/19335 27269/27273/19342 27270/27274/19336 +f 27271/27275/19343 27272/27276/19344 27273/27277/19345 +f 27271/27275/19343 27273/27277/19345 27274/27278/19346 +f 27272/27276/19344 27275/27279/19347 27276/27280/19348 +f 27272/27276/19344 27276/27280/19348 27273/27277/19345 +f 27273/27277/19345 27276/27280/19348 27277/27281/19349 +f 27273/27277/19345 27277/27281/19349 27278/27282/19350 +f 27274/27278/19346 27273/27277/19345 27278/27282/19350 +f 27274/27278/19346 27278/27282/19350 27279/27283/19351 +f 27270/27274/19336 27269/27273/19342 27280/27284/19352 +f 27270/27274/19336 27280/27284/19352 27281/27285/19353 +f 27269/27273/19342 27268/27272/19324 27282/27286/19332 +f 27269/27273/19342 27282/27286/19332 27280/27284/19352 +f 27280/27284/19352 27282/27286/19332 27275/27279/19347 +f 27280/27284/19352 27275/27279/19347 27272/27276/19344 +f 27281/27285/19353 27280/27284/19352 27272/27276/19344 +f 27281/27285/19353 27272/27276/19344 27271/27275/19343 +f 27210/27214/19301 27209/27213/19300 27283/27287/19354 +f 27210/27214/19301 27283/27287/19354 27284/27288/19329 +f 27209/27213/19300 27208/27212/19299 27285/27289/19355 +f 27209/27213/19300 27285/27289/19355 27283/27287/19354 +f 27283/27287/19354 27285/27289/19355 27286/27290/19356 +f 27283/27287/19354 27286/27290/19356 27287/27291/19357 +f 27284/27288/19329 27283/27287/19354 27287/27291/19357 +f 27284/27288/19329 27287/27291/19357 27288/27292/19358 +f 27261/27265/19299 27260/27264/19337 27289/27293/19359 +f 27261/27265/19299 27289/27293/19359 27290/27294/19355 +f 27291/27295/19360 27292/27296/19336 27293/27297/19361 +f 27291/27295/19360 27293/27297/19361 27294/27298/19359 +f 27294/27298/19359 27293/27297/19361 27295/27299/19343 +f 27294/27298/19359 27295/27299/19343 27296/27300/19362 +f 27290/27294/19355 27289/27293/19359 27297/27301/19362 +f 27290/27294/19355 27297/27301/19362 27298/27302/19356 +f 27299/27303/19363 27300/27304/19364 27301/27305/19365 +f 27299/27303/19363 27301/27305/19365 27302/27306/19366 +f 27300/27304/19364 27303/27307/19367 27304/27308/19368 +f 27300/27304/19364 27304/27308/19368 27301/27305/19365 +f 27301/27305/19365 27304/27308/19368 27305/27309/19369 +f 27301/27305/19365 27305/27309/19369 27306/27310/19370 +f 27302/27306/19366 27301/27305/19365 27306/27310/19370 +f 27302/27306/19366 27306/27310/19370 27307/27311/19371 +f 27288/27292/19358 27287/27291/19357 27308/27312/19372 +f 27288/27292/19358 27308/27312/19372 27309/27313/19373 +f 27287/27291/19357 27286/27290/19356 27310/27314/19374 +f 27287/27291/19357 27310/27314/19374 27308/27312/19372 +f 27308/27312/19372 27310/27314/19374 27311/27315/19375 +f 27308/27312/19372 27311/27315/19375 27312/27316/19376 +f 27309/27313/19373 27308/27312/19372 27312/27316/19376 +f 27309/27313/19373 27312/27316/19376 27313/27317/19377 +f 27314/27318/19378 27296/27300/19362 27315/27319/19379 +f 27314/27318/19378 27315/27319/19379 27316/27320/19374 +f 27296/27300/19362 27295/27299/19343 27317/27321/19346 +f 27296/27300/19362 27317/27321/19346 27315/27319/19379 +f 27315/27319/19379 27317/27321/19346 27303/27307/19367 +f 27315/27319/19379 27303/27307/19367 27300/27304/19364 +f 27316/27320/19374 27315/27319/19379 27300/27304/19364 +f 27316/27320/19374 27300/27304/19364 27299/27303/19363 +f 27255/27259/19333 27253/27257/19331 27318/27322/19380 +f 27255/27259/19333 27318/27322/19380 27319/27323/19348 +f 27253/27257/19331 27252/27256/19330 27320/27324/19381 +f 27253/27257/19331 27320/27324/19381 27318/27322/19380 +f 27318/27322/19380 27320/27324/19381 27321/27325/19377 +f 27318/27322/19380 27321/27325/19377 27322/27326/19382 +f 27319/27323/19348 27318/27322/19380 27322/27326/19382 +f 27319/27323/19348 27322/27326/19382 27323/27327/19383 +f 27324/27328/19369 27325/27329/19384 27326/27330/19385 +f 27324/27328/19369 27326/27330/19385 27327/27331/19386 +f 27325/27329/19384 27328/27332/19387 27329/27333/19388 +f 27325/27329/19384 27329/27333/19388 27326/27330/19385 +f 27326/27330/19385 27329/27333/19388 27330/27334/19389 +f 27326/27330/19385 27330/27334/19389 27331/27335/19390 +f 27327/27331/19386 27326/27330/19385 27331/27335/19390 +f 27327/27331/19386 27331/27335/19390 27332/27336/19391 +f 27323/27327/19383 27322/27326/19382 27333/27337/19392 +f 27323/27327/19383 27333/27337/19392 27334/27338/19393 +f 27322/27326/19382 27321/27325/19377 27335/27339/19394 +f 27322/27326/19382 27335/27339/19394 27333/27337/19392 +f 27333/27337/19392 27335/27339/19394 27336/27340/19395 +f 27333/27337/19392 27336/27340/19395 27337/27341/19396 +f 27334/27338/19393 27333/27337/19392 27337/27341/19396 +f 27334/27338/19393 27337/27341/19396 27338/27342/19387 +f 27279/27283/19351 27278/27282/19350 27339/27343/19397 +f 27279/27283/19351 27339/27343/19397 27340/27344/19368 +f 27278/27282/19350 27277/27281/19349 27341/27345/19393 +f 27278/27282/19350 27341/27345/19393 27339/27343/19397 +f 27339/27343/19397 27341/27345/19393 27328/27332/19387 +f 27339/27343/19397 27328/27332/19387 27325/27329/19384 +f 27340/27344/19368 27339/27343/19397 27325/27329/19384 +f 27340/27344/19368 27325/27329/19384 27324/27328/19369 +f 27313/27317/19377 27312/27316/19376 27342/27346/19398 +f 27313/27317/19377 27342/27346/19398 27343/27347/19394 +f 27312/27316/19376 27311/27315/19375 27344/27348/19366 +f 27312/27316/19376 27344/27348/19366 27342/27346/19398 +f 27342/27346/19398 27344/27348/19366 27345/27349/19371 +f 27342/27346/19398 27345/27349/19371 27346/27350/19399 +f 27343/27347/19394 27342/27346/19398 27346/27350/19399 +f 27343/27347/19394 27346/27350/19399 27347/27351/19400 +f 27348/27352/19401 27349/27353/19402 27350/27354/19403 +f 27348/27352/19401 27350/27354/19403 27351/27355/19404 +f 27349/27353/19402 27352/27356/19405 27353/27357/19406 +f 27349/27353/19402 27353/27357/19406 27350/27354/19403 +f 27350/27354/19403 27353/27357/19406 27354/27358/19407 +f 27350/27354/19403 27354/27358/19407 27355/27359/19408 +f 27351/27355/19404 27350/27354/19403 27355/27359/19408 +f 27351/27355/19404 27355/27359/19408 27356/27360/19409 +f 27347/27351/19400 27346/27350/19399 27357/27361/19410 +f 27347/27351/19400 27357/27361/19410 27358/27362/19411 +f 27346/27350/19399 27345/27349/19371 27359/27363/19412 +f 27346/27350/19399 27359/27363/19412 27357/27361/19410 +f 27357/27361/19410 27359/27363/19412 27352/27356/19405 +f 27357/27361/19410 27352/27356/19405 27349/27353/19402 +f 27358/27362/19411 27357/27361/19410 27349/27353/19402 +f 27358/27362/19411 27349/27353/19402 27348/27352/19401 +f 27307/27311/19371 27306/27310/19370 27360/27364/19413 +f 27307/27311/19371 27360/27364/19413 27361/27365/19414 +f 27306/27310/19370 27305/27309/19369 27362/27366/19415 +f 27306/27310/19370 27362/27366/19415 27360/27364/19413 +f 27360/27364/19413 27362/27366/19415 27363/27367/19391 +f 27360/27364/19413 27363/27367/19391 27364/27368/19416 +f 27361/27365/19414 27360/27364/19413 27364/27368/19416 +f 27361/27365/19414 27364/27368/19416 27365/27369/19405 +f 27338/27342/19387 27337/27341/19396 27366/27370/19417 +f 27338/27342/19387 27366/27370/19417 27367/27371/19388 +f 27337/27341/19396 27336/27340/19395 27368/27372/19411 +f 27337/27341/19396 27368/27372/19411 27366/27370/19417 +f 27366/27370/19417 27368/27372/19411 27369/27373/19418 +f 27366/27370/19417 27369/27373/19418 27370/27374/19419 +f 27367/27371/19388 27366/27370/19417 27370/27374/19419 +f 27367/27371/19388 27370/27374/19419 27371/27375/19420 +f 27372/27376/19407 27373/27377/19421 27374/27378/19422 +f 27372/27376/19407 27374/27378/19422 27375/27379/19423 +f 27373/27377/19421 27376/27380/19424 27377/27381/19425 +f 27373/27377/19421 27377/27381/19425 27374/27378/19422 +f 27374/27378/19422 27377/27381/19425 27378/27382/19426 +f 27374/27378/19422 27378/27382/19426 27379/27383/19427 +f 27375/27379/19423 27374/27378/19422 27379/27383/19427 +f 27375/27379/19423 27379/27383/19427 27380/27384/19428 +f 27365/27369/19405 27364/27368/19416 27381/27385/19429 +f 27365/27369/19405 27381/27385/19429 27382/27386/19430 +f 27364/27368/19416 27363/27367/19391 27383/27387/19431 +f 27364/27368/19416 27383/27387/19431 27381/27385/19429 +f 27381/27385/19429 27383/27387/19431 27384/27388/19424 +f 27381/27385/19429 27384/27388/19424 27385/27389/19432 +f 27386/27390/19430 27387/27391/19433 27373/27377/19421 +f 27386/27390/19430 27373/27377/19421 27372/27376/19407 +f 27371/27375/19420 27370/27374/19419 27388/27392/19434 +f 27371/27375/19420 27388/27392/19434 27389/27393/19435 +f 27370/27374/19419 27369/27373/19418 27390/27394/19404 +f 27370/27374/19419 27390/27394/19404 27388/27392/19434 +f 27388/27392/19434 27390/27394/19404 27391/27395/19436 +f 27388/27392/19434 27391/27395/19436 27392/27396/19437 +f 27393/27397/19438 27394/27398/19434 27395/27399/19437 +f 27393/27397/19438 27395/27399/19437 27396/27400/19439 +f 27332/27336/19391 27331/27335/19390 27397/27401/19440 +f 27332/27336/19391 27397/27401/19440 27398/27402/19431 +f 27331/27335/19390 27330/27334/19389 27393/27397/19438 +f 27331/27335/19390 27393/27397/19438 27397/27401/19440 +f 27397/27401/19440 27393/27397/19438 27396/27400/19439 +f 27397/27401/19440 27396/27400/19439 27399/27403/19441 +f 27398/27402/19431 27397/27401/19440 27399/27403/19441 +f 27398/27402/19431 27399/27403/19441 27400/27404/19424 +f 27401/27405/19426 27402/27406/19442 27403/27407/19443 +f 27401/27405/19426 27403/27407/19443 27404/27408/19444 +f 27402/27406/19442 27405/27409/19445 27406/27410/19446 +f 27402/27406/19442 27406/27410/19446 27403/27407/19443 +f 27403/27407/19443 27406/27410/19446 27407/27411/19447 +f 27403/27407/19443 27407/27411/19447 27408/27412/19448 +f 27404/27408/19444 27403/27407/19443 27408/27412/19448 +f 27404/27408/19444 27408/27412/19448 27409/27413/19449 +f 27410/27414/19450 27411/27415/19437 27412/27416/19451 +f 27410/27414/19450 27412/27416/19451 27413/27417/19452 +f 27411/27415/19437 27414/27418/19436 27415/27419/19453 +f 27411/27415/19437 27415/27419/19453 27412/27416/19451 +f 27412/27416/19451 27415/27419/19453 27416/27420/19454 +f 27412/27416/19451 27416/27420/19454 27417/27421/19455 +f 27413/27417/19452 27412/27416/19451 27417/27421/19455 +f 27413/27417/19452 27417/27421/19455 27418/27422/19456 +f 27400/27404/19424 27399/27403/19441 27419/27423/19457 +f 27400/27404/19424 27419/27423/19457 27420/27424/19425 +f 27399/27403/19441 27396/27400/19439 27421/27425/19452 +f 27399/27403/19441 27421/27425/19452 27419/27423/19457 +f 27419/27423/19457 27421/27425/19452 27405/27409/19445 +f 27419/27423/19457 27405/27409/19445 27402/27406/19442 +f 27420/27424/19425 27419/27423/19457 27402/27406/19442 +f 27420/27424/19425 27402/27406/19442 27401/27405/19426 +f 27356/27360/19409 27355/27359/19408 27422/27426/19458 +f 27356/27360/19409 27422/27426/19458 27423/27427/19453 +f 27355/27359/19408 27354/27358/19407 27424/27428/19423 +f 27355/27359/19408 27424/27428/19423 27422/27426/19458 +f 27422/27426/19458 27424/27428/19423 27425/27429/19428 +f 27422/27426/19458 27425/27429/19428 27426/27430/19459 +f 27423/27427/19453 27422/27426/19458 27426/27430/19459 +f 27423/27427/19453 27426/27430/19459 27427/27431/19460 +f 27428/27432/19461 27429/27433/19462 27430/27434/19463 +f 27428/27432/19461 27430/27434/19463 27431/27435/19464 +f 27429/27433/19462 27432/27436/19449 27433/27437/19465 +f 27429/27433/19462 27433/27437/19465 27430/27434/19463 +f 27430/27434/19463 27433/27437/19465 27434/27438/19466 +f 27430/27434/19463 27434/27438/19466 27435/27439/19467 +f 27431/27435/19464 27430/27434/19463 27435/27439/19467 +f 27431/27435/19464 27435/27439/19467 27436/27440/19468 +f 27427/27431/19460 27426/27430/19459 27437/27441/19469 +f 27427/27431/19460 27437/27441/19469 27438/27442/19470 +f 27426/27430/19459 27425/27429/19428 27439/27443/19471 +f 27426/27430/19459 27439/27443/19471 27437/27441/19469 +f 27437/27441/19469 27439/27443/19471 27440/27444/19461 +f 27437/27441/19469 27440/27444/19461 27441/27445/19472 +f 27438/27442/19470 27437/27441/19469 27441/27445/19472 +f 27438/27442/19470 27441/27445/19472 27442/27446/19473 +f 27380/27384/19428 27379/27383/19427 27443/27447/19474 +f 27380/27384/19428 27443/27447/19474 27444/27448/19471 +f 27379/27383/19427 27378/27382/19426 27445/27449/19475 +f 27379/27383/19427 27445/27449/19475 27443/27447/19474 +f 27443/27447/19474 27445/27449/19475 27432/27436/19449 +f 27443/27447/19474 27432/27436/19449 27429/27433/19462 +f 27444/27448/19471 27443/27447/19474 27429/27433/19462 +f 27444/27448/19471 27429/27433/19462 27428/27432/19461 +f 27418/27422/19456 27417/27421/19455 27446/27450/19476 +f 27418/27422/19456 27446/27450/19476 27447/27451/19477 +f 27417/27421/19455 27416/27420/19454 27448/27452/19478 +f 27417/27421/19455 27448/27452/19478 27446/27450/19476 +f 27446/27450/19476 27448/27452/19478 27449/27453/19473 +f 27446/27450/19476 27449/27453/19473 27450/27454/19479 +f 27447/27451/19477 27446/27450/19476 27450/27454/19479 +f 27447/27451/19477 27450/27454/19479 27451/27455/19447 +f 27451/27455/19447 27450/27454/19479 27452/27456/19480 +f 27451/27455/19447 27452/27456/19480 27453/27457/19481 +f 27450/27454/19479 27449/27453/19473 27454/27458/19482 +f 27450/27454/19479 27454/27458/19482 27452/27456/19480 +f 27452/27456/19480 27454/27458/19482 27455/27459/19288 +f 27452/27456/19480 27455/27459/19288 27456/27460/19291 +f 27453/27457/19481 27452/27456/19480 27456/27460/19291 +f 27453/27457/19481 27456/27460/19291 27457/27461/19483 +f 27409/27413/19449 27408/27412/19448 27458/27462/19484 +f 27409/27413/19449 27458/27462/19484 27459/27463/19465 +f 27408/27412/19448 27407/27411/19447 27460/27464/19481 +f 27408/27412/19448 27460/27464/19481 27458/27462/19484 +f 27458/27462/19484 27460/27464/19481 27461/27465/19485 +f 27458/27462/19484 27461/27465/19485 27462/27466/19486 +f 27459/27463/19465 27458/27462/19484 27462/27466/19486 +f 27459/27463/19465 27462/27466/19486 27463/27467/19466 +f 27442/27446/19473 27441/27445/19472 27464/27468/19487 +f 27442/27446/19473 27464/27468/19487 27465/27469/19482 +f 27441/27445/19472 27440/27444/19461 27466/27470/19488 +f 27441/27445/19472 27466/27470/19488 27464/27468/19487 +f 27464/27468/19487 27466/27470/19488 27467/27471/19468 +f 27464/27468/19487 27467/27471/19468 27468/27472/19489 +f 27465/27469/19482 27464/27468/19487 27468/27472/19489 +f 27465/27469/19482 27468/27472/19489 27469/27473/19288 +f 27470/27474/19490 27471/27475/19491 27472/27476/19492 +f 27470/27474/19490 27472/27476/19492 27473/27477/19493 +f 27471/27475/19491 27474/27478/19494 27475/27479/19495 +f 27471/27475/19491 27475/27479/19495 27472/27476/19492 +f 27472/27476/19492 27475/27479/19495 27476/27480/19496 +f 27472/27476/19492 27476/27480/19496 27477/27481/19497 +f 27473/27477/19493 27472/27476/19492 27477/27481/19497 +f 27473/27477/19493 27477/27481/19497 27478/27482/19498 +f 27211/27215/19302 27479/27483/19499 27480/27484/19500 +f 27211/27215/19302 27480/27484/19500 27212/27216/19303 +f 27479/27483/19499 27470/27474/19490 27473/27477/19493 +f 27479/27483/19499 27473/27477/19493 27480/27484/19500 +f 27480/27484/19500 27473/27477/19493 27478/27482/19498 +f 27480/27484/19500 27478/27482/19498 27481/27485/19501 +f 27212/27216/19303 27480/27484/19500 27481/27485/19501 +f 27212/27216/19303 27481/27485/19501 27215/27219/19306 +f 27217/27221/19308 27220/27224/19311 27482/27486/19502 +f 27217/27221/19308 27482/27486/19502 27483/27487/19503 +f 27220/27224/19311 27225/27229/19306 27484/27488/19501 +f 27220/27224/19311 27484/27488/19501 27482/27486/19502 +f 27482/27486/19502 27484/27488/19501 27485/27489/19498 +f 27482/27486/19502 27485/27489/19498 27486/27490/19504 +f 27483/27487/19503 27482/27486/19502 27486/27490/19504 +f 27483/27487/19503 27486/27490/19504 27487/27491/19505 +f 27488/27492/19506 27489/27493/19507 27490/27494/19508 +f 27488/27492/19506 27490/27494/19508 27491/27495/19509 +f 27489/27493/19507 27492/27496/19510 27493/27497/19499 +f 27489/27493/19507 27493/27497/19499 27490/27494/19508 +f 27490/27494/19508 27493/27497/19499 27232/27236/19302 +f 27490/27494/19508 27232/27236/19302 27231/27235/19319 +f 27491/27495/19509 27490/27494/19508 27231/27235/19319 +f 27491/27495/19509 27231/27235/19319 27230/27234/19318 +f 27494/27498/19506 27495/27499/19509 27496/27500/19511 +f 27494/27498/19506 27496/27500/19511 27497/27501/19512 +f 27495/27499/19509 27243/27247/19318 27242/27246/19323 +f 27495/27499/19509 27242/27246/19323 27496/27500/19511 +f 27496/27500/19511 27242/27246/19323 27241/27245/19308 +f 27496/27500/19511 27241/27245/19308 27498/27502/19503 +f 27497/27501/19512 27496/27500/19511 27498/27502/19503 +f 27497/27501/19512 27498/27502/19503 27499/27503/19513 +f 27500/27504/19514 27501/27505/19515 27502/27506/19516 +f 27500/27504/19514 27502/27506/19516 27503/27507/19517 +f 27504/27508/19515 27505/27509/19518 27506/27510/19519 +f 27504/27508/19515 27506/27510/19519 27507/27511/19516 +f 27502/27506/19516 27508/27512/19519 27509/27513/19520 +f 27502/27506/19516 27509/27513/19520 27510/27514/19521 +f 27503/27507/19517 27502/27506/19516 27510/27514/19521 +f 27503/27507/19517 27510/27514/19521 27511/27515/19494 +f 27485/27489/19498 27512/27516/19497 27513/27517/19522 +f 27485/27489/19498 27513/27517/19522 27486/27490/19504 +f 27512/27516/19497 27514/27518/19523 27515/27519/19524 +f 27512/27516/19497 27515/27519/19524 27513/27517/19522 +f 27513/27517/19522 27515/27519/19524 27516/27520/19525 +f 27513/27517/19522 27516/27520/19525 27517/27521/19526 +f 27486/27490/19504 27513/27517/19522 27517/27521/19526 +f 27486/27490/19504 27517/27521/19526 27487/27491/19505 +f 27488/27492/19506 27518/27522/19527 27519/27523/19528 +f 27488/27492/19506 27519/27523/19528 27489/27493/19507 +f 27518/27522/19527 27500/27504/19514 27503/27507/19517 +f 27518/27522/19527 27503/27507/19517 27519/27523/19528 +f 27519/27523/19528 27503/27507/19517 27511/27515/19494 +f 27519/27523/19528 27511/27515/19494 27520/27524/19529 +f 27489/27493/19507 27519/27523/19528 27520/27524/19529 +f 27489/27493/19507 27520/27524/19529 27492/27496/19510 +f 27499/27503/19513 27521/27525/19526 27522/27526/19530 +f 27499/27503/19513 27522/27526/19530 27497/27501/19512 +f 27521/27525/19526 27523/27527/19531 27524/27528/19532 +f 27521/27525/19526 27524/27528/19532 27522/27526/19530 +f 27522/27526/19530 27524/27528/19532 27525/27529/19514 +f 27522/27526/19530 27525/27529/19514 27526/27530/19527 +f 27497/27501/19512 27522/27526/19530 27526/27530/19527 +f 27497/27501/19512 27526/27530/19527 27494/27498/19506 +f 27527/27531/19533 27528/27532/19534 27529/27533/19535 +f 27527/27531/19533 27529/27533/19535 27530/27534/19536 +f 27528/27532/19534 27531/27535/19537 27532/27536/19538 +f 27528/27532/19534 27532/27536/19538 27529/27533/19535 +f 27529/27533/19535 27532/27536/19538 27533/27537/19539 +f 27529/27533/19535 27533/27537/19539 27534/27538/19540 +f 27530/27534/19536 27529/27533/19535 27534/27538/19540 +f 27530/27534/19536 27534/27538/19540 27535/27539/19541 +f 27523/27527/19531 27536/27540/19542 27537/27541/19543 +f 27523/27527/19531 27537/27541/19543 27524/27528/19532 +f 27536/27540/19542 27527/27531/19533 27530/27534/19536 +f 27536/27540/19542 27530/27534/19536 27537/27541/19543 +f 27537/27541/19543 27530/27534/19536 27535/27539/19541 +f 27537/27541/19543 27535/27539/19541 27538/27542/19515 +f 27524/27528/19532 27537/27541/19543 27538/27542/19515 +f 27524/27528/19532 27538/27542/19515 27525/27529/19514 +f 27474/27478/19494 27539/27543/19521 27540/27544/19544 +f 27474/27478/19494 27540/27544/19544 27475/27479/19495 +f 27539/27543/19521 27541/27545/19520 27542/27546/19545 +f 27539/27543/19521 27542/27546/19545 27540/27544/19544 +f 27540/27544/19544 27542/27546/19545 27543/27547/19546 +f 27540/27544/19544 27543/27547/19546 27544/27548/19547 +f 27475/27479/19495 27540/27544/19544 27544/27548/19547 +f 27475/27479/19495 27544/27548/19547 27476/27480/19496 +f 27514/27518/19523 27545/27549/19548 27546/27550/19549 +f 27514/27518/19523 27546/27550/19549 27515/27519/19524 +f 27547/27551/19547 27548/27552/19550 27549/27553/19551 +f 27547/27551/19547 27549/27553/19551 27550/27554/19549 +f 27550/27554/19549 27549/27553/19551 27551/27555/19533 +f 27550/27554/19549 27551/27555/19533 27552/27556/19552 +f 27515/27519/19524 27546/27550/19549 27553/27557/19553 +f 27515/27519/19524 27553/27557/19553 27516/27520/19525 +f 27554/27558/19554 27555/27559/19555 27556/27560/19556 +f 27554/27558/19554 27556/27560/19556 27557/27561/19557 +f 27555/27559/19555 27558/27562/19558 27559/27563/19559 +f 27555/27559/19555 27559/27563/19559 27556/27560/19556 +f 27556/27560/19556 27559/27563/19559 27560/27564/19560 +f 27556/27560/19556 27560/27564/19560 27561/27565/19561 +f 27557/27561/19557 27556/27560/19556 27561/27565/19561 +f 27557/27561/19557 27561/27565/19561 27562/27566/19562 +f 27541/27545/19520 27563/27567/19563 27564/27568/19564 +f 27541/27545/19520 27564/27568/19564 27542/27546/19545 +f 27563/27567/19563 27565/27569/19565 27566/27570/19566 +f 27563/27567/19563 27566/27570/19566 27564/27568/19564 +f 27564/27568/19564 27566/27570/19566 27567/27571/19567 +f 27564/27568/19564 27567/27571/19567 27568/27572/19568 +f 27542/27546/19545 27564/27568/19564 27568/27572/19568 +f 27542/27546/19545 27568/27572/19568 27543/27547/19546 +f 27548/27552/19550 27569/27573/19568 27570/27574/19569 +f 27548/27552/19550 27570/27574/19569 27549/27553/19551 +f 27569/27573/19568 27554/27558/19554 27557/27561/19557 +f 27569/27573/19568 27557/27561/19557 27570/27574/19569 +f 27570/27574/19569 27557/27561/19557 27562/27566/19562 +f 27570/27574/19569 27562/27566/19562 27571/27575/19534 +f 27549/27553/19551 27570/27574/19569 27571/27575/19534 +f 27549/27553/19551 27571/27575/19534 27551/27555/19533 +f 27505/27509/19518 27572/27576/19540 27573/27577/19570 +f 27505/27509/19518 27573/27577/19570 27506/27510/19519 +f 27572/27576/19540 27574/27578/19539 27575/27579/19571 +f 27572/27576/19540 27575/27579/19571 27573/27577/19570 +f 27573/27577/19570 27575/27579/19571 27576/27580/19565 +f 27573/27577/19570 27576/27580/19565 27577/27581/19572 +f 27506/27510/19519 27573/27577/19570 27577/27581/19572 +f 27506/27510/19519 27577/27581/19572 27578/27582/19520 +f 27579/27583/19560 27580/27584/19573 27581/27585/19574 +f 27579/27583/19560 27581/27585/19574 27582/27586/19575 +f 27580/27584/19573 27583/27587/19576 27584/27588/19577 +f 27580/27584/19573 27584/27588/19577 27581/27585/19574 +f 27581/27585/19574 27584/27588/19577 27585/27589/19578 +f 27581/27585/19574 27585/27589/19578 27586/27590/19579 +f 27582/27586/19575 27581/27585/19574 27586/27590/19579 +f 27582/27586/19575 27586/27590/19579 27587/27591/19580 +f 27574/27578/19539 27588/27592/19581 27589/27593/19582 +f 27574/27578/19539 27589/27593/19582 27575/27579/19571 +f 27588/27592/19581 27590/27594/19583 27591/27595/19584 +f 27588/27592/19581 27591/27595/19584 27589/27593/19582 +f 27589/27593/19582 27591/27595/19584 27592/27596/19585 +f 27589/27593/19582 27592/27596/19585 27593/27597/19586 +f 27575/27579/19571 27589/27593/19582 27593/27597/19586 +f 27575/27579/19571 27593/27597/19586 27576/27580/19565 +f 27531/27535/19537 27594/27598/19561 27595/27599/19587 +f 27531/27535/19537 27595/27599/19587 27532/27536/19538 +f 27594/27598/19561 27579/27583/19560 27582/27586/19575 +f 27594/27598/19561 27582/27586/19575 27595/27599/19587 +f 27595/27599/19587 27582/27586/19575 27587/27591/19580 +f 27595/27599/19587 27587/27591/19580 27596/27600/19581 +f 27532/27536/19538 27595/27599/19587 27596/27600/19581 +f 27532/27536/19538 27596/27600/19581 27533/27537/19539 +f 27565/27569/19565 27597/27601/19586 27598/27602/19588 +f 27565/27569/19565 27598/27602/19588 27566/27570/19566 +f 27597/27601/19586 27599/27603/19589 27600/27604/19590 +f 27597/27601/19586 27600/27604/19590 27598/27602/19588 +f 27598/27602/19588 27600/27604/19590 27601/27605/19558 +f 27598/27602/19588 27601/27605/19558 27602/27606/19555 +f 27566/27570/19566 27598/27602/19588 27602/27606/19555 +f 27566/27570/19566 27602/27606/19555 27567/27571/19567 +f 27603/27607/19591 27604/27608/19592 27605/27609/19593 +f 27603/27607/19591 27605/27609/19593 27606/27610/19594 +f 27604/27608/19592 27607/27611/19595 27608/27612/19596 +f 27604/27608/19592 27608/27612/19596 27605/27609/19593 +f 27605/27609/19593 27608/27612/19596 27609/27613/19597 +f 27605/27609/19593 27609/27613/19597 27610/27614/19598 +f 27606/27610/19594 27605/27609/19593 27610/27614/19598 +f 27606/27610/19594 27610/27614/19598 27611/27615/19599 +f 27599/27603/19589 27612/27616/19600 27613/27617/19601 +f 27599/27603/19589 27613/27617/19601 27600/27604/19590 +f 27612/27616/19600 27603/27607/19591 27606/27610/19594 +f 27612/27616/19600 27606/27610/19594 27613/27617/19601 +f 27613/27617/19601 27606/27610/19594 27611/27615/19599 +f 27613/27617/19601 27611/27615/19599 27614/27618/19602 +f 27600/27604/19590 27613/27617/19601 27614/27618/19602 +f 27600/27604/19590 27614/27618/19602 27601/27605/19558 +f 27558/27562/19558 27615/27619/19603 27616/27620/19604 +f 27558/27562/19558 27616/27620/19604 27559/27563/19559 +f 27615/27619/19603 27617/27621/19605 27618/27622/19606 +f 27615/27619/19603 27618/27622/19606 27616/27620/19604 +f 27616/27620/19604 27618/27622/19606 27619/27623/19576 +f 27616/27620/19604 27619/27623/19576 27620/27624/19607 +f 27559/27563/19559 27616/27620/19604 27620/27624/19607 +f 27559/27563/19559 27620/27624/19607 27560/27564/19560 +f 27590/27594/19583 27621/27625/19608 27622/27626/19609 +f 27590/27594/19583 27622/27626/19609 27591/27595/19584 +f 27621/27625/19608 27623/27627/19610 27624/27628/19611 +f 27621/27625/19608 27624/27628/19611 27622/27626/19609 +f 27622/27626/19609 27624/27628/19611 27625/27629/19612 +f 27622/27626/19609 27625/27629/19612 27626/27630/19600 +f 27591/27595/19584 27622/27626/19609 27626/27630/19600 +f 27591/27595/19584 27626/27630/19600 27592/27596/19585 +f 27627/27631/19597 27628/27632/19613 27629/27633/19614 +f 27627/27631/19597 27629/27633/19614 27630/27634/19615 +f 27628/27632/19613 27631/27635/19616 27632/27636/19617 +f 27628/27632/19613 27632/27636/19617 27629/27633/19614 +f 27629/27633/19614 27632/27636/19617 27633/27637/19618 +f 27629/27633/19614 27633/27637/19618 27634/27638/19619 +f 27630/27634/19615 27629/27633/19614 27634/27638/19619 +f 27630/27634/19615 27634/27638/19619 27635/27639/19620 +f 27617/27621/19605 27636/27640/19598 27637/27641/19621 +f 27617/27621/19605 27637/27641/19621 27618/27622/19606 +f 27636/27640/19598 27638/27642/19597 27639/27643/19615 +f 27636/27640/19598 27639/27643/19615 27637/27641/19621 +f 27637/27641/19621 27639/27643/19615 27640/27644/19620 +f 27637/27641/19621 27640/27644/19620 27641/27645/19622 +f 27618/27622/19606 27637/27641/19621 27641/27645/19622 +f 27618/27622/19606 27641/27645/19622 27619/27623/19576 +f 27623/27627/19610 27642/27646/19623 27643/27647/19624 +f 27623/27627/19610 27643/27647/19624 27624/27628/19611 +f 27642/27646/19623 27644/27648/19625 27645/27649/19626 +f 27642/27646/19623 27645/27649/19626 27643/27647/19624 +f 27646/27650/19624 27647/27651/19627 27648/27652/19628 +f 27646/27650/19624 27648/27652/19628 27649/27653/19592 +f 27624/27628/19611 27643/27647/19624 27650/27654/19629 +f 27624/27628/19611 27650/27654/19629 27625/27629/19612 +f 27583/27587/19576 27651/27655/19630 27652/27656/19631 +f 27583/27587/19576 27652/27656/19631 27584/27588/19577 +f 27651/27655/19630 27653/27657/19620 27654/27658/19632 +f 27651/27655/19630 27654/27658/19632 27652/27656/19631 +f 27652/27656/19631 27654/27658/19632 27655/27659/19633 +f 27652/27656/19631 27655/27659/19633 27656/27660/19623 +f 27584/27588/19577 27652/27656/19631 27656/27660/19623 +f 27584/27588/19577 27656/27660/19623 27585/27589/19578 +f 27657/27661/19618 27658/27662/19634 27659/27663/19635 +f 27657/27661/19618 27659/27663/19635 27660/27664/19636 +f 27658/27662/19634 27661/27665/19637 27662/27666/19638 +f 27658/27662/19634 27662/27666/19638 27659/27663/19635 +f 27659/27663/19635 27662/27666/19638 27663/27667/19639 +f 27659/27663/19635 27663/27667/19639 27664/27668/19640 +f 27660/27664/19636 27659/27663/19635 27664/27668/19640 +f 27660/27664/19636 27664/27668/19640 27665/27669/19641 +f 27666/27670/19642 27667/27671/19643 27668/27672/19644 +f 27666/27670/19642 27668/27672/19644 27647/27651/19627 +f 27667/27671/19643 27669/27673/19641 27670/27674/19645 +f 27667/27671/19643 27670/27674/19645 27668/27672/19644 +f 27668/27672/19644 27670/27674/19645 27671/27675/19646 +f 27668/27672/19644 27671/27675/19646 27672/27676/19647 +f 27647/27651/19627 27668/27672/19644 27672/27676/19647 +f 27647/27651/19627 27672/27676/19647 27648/27652/19628 +f 27653/27657/19620 27673/27677/19619 27674/27678/19648 +f 27653/27657/19620 27674/27678/19648 27654/27658/19632 +f 27673/27677/19619 27657/27661/19618 27660/27664/19636 +f 27673/27677/19619 27660/27664/19636 27674/27678/19648 +f 27674/27678/19648 27660/27664/19636 27665/27669/19641 +f 27674/27678/19648 27665/27669/19641 27675/27679/19649 +f 27654/27658/19632 27674/27678/19648 27675/27679/19649 +f 27654/27658/19632 27675/27679/19649 27655/27659/19633 +f 27607/27611/19595 27676/27680/19650 27677/27681/19651 +f 27607/27611/19595 27677/27681/19651 27608/27612/19596 +f 27676/27680/19650 27678/27682/19652 27679/27683/19653 +f 27676/27680/19650 27679/27683/19653 27677/27681/19651 +f 27677/27681/19651 27679/27683/19653 27680/27684/19616 +f 27677/27681/19651 27680/27684/19616 27681/27685/19654 +f 27608/27612/19596 27677/27681/19651 27681/27685/19654 +f 27608/27612/19596 27681/27685/19654 27609/27613/19597 +f 27682/27686/19655 27683/27687/19656 27684/27688/19657 +f 27682/27686/19655 27684/27688/19657 27685/27689/19658 +f 27683/27687/19656 27436/27440/19468 27435/27439/19467 +f 27683/27687/19656 27435/27439/19467 27684/27688/19657 +f 27684/27688/19657 27435/27439/19467 27434/27438/19466 +f 27684/27688/19657 27434/27438/19466 27686/27690/19659 +f 27685/27689/19658 27684/27688/19657 27686/27690/19659 +f 27685/27689/19658 27686/27690/19659 27687/27691/19637 +f 27678/27682/19652 27688/27692/19660 27689/27693/19661 +f 27678/27682/19652 27689/27693/19661 27679/27683/19653 +f 27688/27692/19660 27690/27694/19662 27691/27695/19663 +f 27688/27692/19660 27691/27695/19663 27689/27693/19661 +f 27689/27693/19661 27691/27695/19663 27692/27696/19655 +f 27689/27693/19661 27692/27696/19655 27693/27697/19664 +f 27679/27683/19653 27689/27693/19661 27693/27697/19664 +f 27679/27683/19653 27693/27697/19664 27680/27684/19616 +f 27631/27635/19616 27694/27698/19665 27695/27699/19666 +f 27631/27635/19616 27695/27699/19666 27632/27636/19617 +f 27694/27698/19665 27682/27686/19655 27685/27689/19658 +f 27694/27698/19665 27685/27689/19658 27695/27699/19666 +f 27695/27699/19666 27685/27689/19658 27687/27691/19637 +f 27695/27699/19666 27687/27691/19637 27696/27700/19667 +f 27632/27636/19617 27695/27699/19666 27696/27700/19667 +f 27632/27636/19617 27696/27700/19667 27633/27637/19618 +f 27669/27673/19641 27697/27701/19668 27698/27702/19669 +f 27669/27673/19641 27698/27702/19669 27670/27674/19645 +f 27697/27701/19668 27699/27703/19639 27700/27704/19670 +f 27697/27701/19668 27700/27704/19670 27698/27702/19669 +f 27698/27702/19669 27700/27704/19670 27701/27705/19671 +f 27698/27702/19669 27701/27705/19671 27702/27706/19672 +f 27670/27674/19645 27698/27702/19669 27702/27706/19672 +f 27670/27674/19645 27702/27706/19672 27671/27675/19646 +f 27703/27202/19673 27705/27204/19290 27706/27707/19489 +f 27704/27203/19674 27707/27708/19675 27708/27205/19486 +f 27705/27204/19290 27708/27205/19676 27709/27709/19677 +f 27705/27204/19290 27709/27709/19677 27710/27710/19678 +f 27706/27707/19489 27705/27204/19290 27710/27710/19678 +f 27706/27707/19489 27710/27710/19678 27711/27711/19679 +f 27699/27703/19639 27712/27712/19680 27713/27713/19681 +f 27699/27703/19639 27713/27713/19681 27700/27704/19670 +f 27712/27712/19680 27457/27461/19483 27456/27460/19291 +f 27712/27712/19680 27456/27460/19291 27713/27713/19681 +f 27713/27713/19681 27456/27460/19291 27455/27459/19288 +f 27713/27713/19681 27455/27459/19288 27714/27714/19682 +f 27700/27704/19670 27713/27713/19681 27714/27714/19682 +f 27700/27704/19670 27714/27714/19682 27701/27705/19671 +f 27661/27665/19637 27715/27715/19683 27716/27716/19684 +f 27661/27665/19637 27716/27716/19684 27662/27666/19638 +f 27715/27715/19683 27463/27467/19466 27462/27466/19486 +f 27715/27715/19683 27462/27466/19486 27716/27716/19684 +f 27716/27716/19684 27462/27466/19486 27461/27465/19485 +f 27716/27716/19684 27461/27465/19485 27717/27717/19680 +f 27662/27666/19638 27716/27716/19684 27717/27717/19680 +f 27662/27666/19638 27717/27717/19680 27663/27667/19639 +f 27690/27694/19662 27718/27718/19682 27719/27719/19685 +f 27690/27694/19662 27719/27719/19685 27691/27695/19663 +f 27718/27718/19682 27469/27473/19288 27468/27472/19489 +f 27718/27718/19682 27468/27472/19489 27719/27719/19685 +f 27719/27719/19685 27468/27472/19489 27467/27471/19468 +f 27719/27719/19685 27467/27471/19468 27720/27720/19656 +f 27691/27695/19663 27719/27719/19685 27720/27720/19656 +f 27691/27695/19663 27720/27720/19656 27692/27696/19655 +o Cube.044__0 +v 0.388727 -0.428394 -0.084475 +v 0.386364 -0.416169 -0.079690 +v 0.377026 -0.419176 -0.079690 +v 0.381763 -0.430356 -0.084475 +v 0.383999 -0.403943 -0.084475 +v 0.372289 -0.407996 -0.084475 +v 0.361253 -0.413625 -0.084475 +v 0.368794 -0.423202 -0.079690 +v 0.376337 -0.432779 -0.084475 +v 0.406627 -0.426087 -0.084475 +v 0.405414 -0.413385 -0.079690 +v 0.395888 -0.414416 -0.079690 +v 0.397244 -0.427058 -0.084475 +v 0.404201 -0.400684 -0.084475 +v 0.394531 -0.401773 -0.084475 +v 0.404201 -0.400684 -0.109994 +v 0.394531 -0.401773 -0.109994 +v 0.394022 -0.397032 -0.097234 +v 0.403746 -0.395920 -0.097234 +v 0.383999 -0.403943 -0.109994 +v 0.383113 -0.399359 -0.097234 +v 0.383999 -0.403943 -0.084475 +v 0.394531 -0.401773 -0.084475 +v 0.404201 -0.400684 -0.084475 +v 0.388727 -0.428394 -0.109994 +v 0.397244 -0.427058 -0.109994 +v 0.397754 -0.431799 -0.097234 +v 0.389613 -0.432979 -0.097234 +v 0.406627 -0.426087 -0.109994 +v 0.407082 -0.430850 -0.097234 +v 0.406627 -0.426087 -0.084475 +v 0.397244 -0.427058 -0.084475 +v 0.388727 -0.428394 -0.084475 +v 0.388727 -0.428394 -0.109994 +v 0.386364 -0.416169 -0.114779 +v 0.395888 -0.414416 -0.114779 +v 0.397244 -0.427058 -0.109994 +v 0.383999 -0.403943 -0.109994 +v 0.394531 -0.401773 -0.109994 +v 0.404201 -0.400684 -0.109994 +v 0.405414 -0.413385 -0.114779 +v 0.406627 -0.426087 -0.109994 +v 0.376337 -0.432779 -0.109994 +v 0.379165 -0.436371 -0.097234 +v 0.375573 -0.439208 -0.097234 +v 0.371929 -0.436351 -0.109994 +v 0.376337 -0.432779 -0.084475 +v 0.371929 -0.436351 -0.084475 +v 0.375573 -0.439208 -0.097234 +v 0.371929 -0.436351 -0.084475 +v 0.366711 -0.445590 -0.084475 +v 0.370889 -0.447723 -0.097234 +v 0.371929 -0.436351 -0.109994 +v 0.366711 -0.445590 -0.109994 +v 0.370512 -0.403803 -0.097234 +v 0.372289 -0.407996 -0.084475 +v 0.372289 -0.407996 -0.109994 +v 0.361253 -0.413625 -0.109994 +v 0.358424 -0.410034 -0.097234 +v 0.361253 -0.413625 -0.084475 +v 0.383540 -0.434549 -0.097234 +v 0.381763 -0.430356 -0.109994 +v 0.381763 -0.430356 -0.084475 +v 0.377026 -0.419176 -0.114779 +v 0.372289 -0.407996 -0.109994 +v 0.381763 -0.430356 -0.109994 +v 0.376337 -0.432779 -0.109994 +v 0.368794 -0.423202 -0.114779 +v 0.361253 -0.413625 -0.109994 +v 0.344426 -0.434215 -0.109994 +v 0.355569 -0.439902 -0.114779 +v 0.347334 -0.461975 -0.114779 +v 0.335386 -0.457857 -0.109994 +v 0.366711 -0.445590 -0.109994 +v 0.359282 -0.466092 -0.109994 +v 0.351267 -0.503934 -0.109994 +v 0.338910 -0.501077 -0.114779 +v 0.326552 -0.498219 -0.109994 +v 0.362211 -0.428733 -0.114779 +v 0.352493 -0.421114 -0.109994 +v 0.371929 -0.436351 -0.109994 +v 0.362211 -0.428733 -0.079690 +v 0.371929 -0.436351 -0.084475 +v 0.352493 -0.421114 -0.084475 +v 0.344426 -0.434215 -0.084475 +v 0.355569 -0.439902 -0.079690 +v 0.366711 -0.445590 -0.084475 +v 0.348848 -0.418257 -0.097234 +v 0.352493 -0.421114 -0.084475 +v 0.358424 -0.410034 -0.097234 +v 0.361253 -0.413625 -0.109994 +v 0.352493 -0.421114 -0.109994 +v 0.348848 -0.418257 -0.097234 +v 0.344426 -0.434215 -0.109994 +v 0.340248 -0.432082 -0.097234 +v 0.340248 -0.432082 -0.097234 +v 0.344426 -0.434215 -0.084475 +v 0.326552 -0.498219 -0.084475 +v 0.321918 -0.497148 -0.097234 +v 0.314829 -0.556906 -0.097234 +v 0.319536 -0.557535 -0.084475 +v 0.326552 -0.498219 -0.109994 +v 0.319536 -0.557535 -0.109994 +v 0.314823 -0.621007 -0.109994 +v 0.310144 -0.620995 -0.097234 +v 0.314823 -0.621007 -0.084475 +v 0.347334 -0.461975 -0.079690 +v 0.359282 -0.466092 -0.084475 +v 0.335386 -0.457857 -0.084475 +v 0.326552 -0.498219 -0.084475 +v 0.338910 -0.501077 -0.079690 +v 0.351267 -0.503934 -0.084475 +v 0.344426 -0.434215 -0.084475 +v 0.330905 -0.456313 -0.097234 +v 0.335386 -0.457857 -0.084475 +v 0.335386 -0.457857 -0.109994 +v 0.363763 -0.467637 -0.097234 +v 0.359282 -0.466092 -0.109994 +v 0.359282 -0.466092 -0.084475 +v 0.351267 -0.503934 -0.084475 +v 0.355902 -0.505006 -0.097234 +v 0.351267 -0.503934 -0.109994 +v 0.314823 -0.621007 -0.109994 +v 0.327301 -0.621039 -0.114779 +v 0.324863 -0.670024 -0.114779 +v 0.312865 -0.672514 -0.109994 +v 0.339778 -0.621070 -0.109994 +v 0.336860 -0.667535 -0.109994 +v 0.336944 -0.696862 -0.109994 +v 0.326032 -0.702265 -0.114779 +v 0.315120 -0.707668 -0.109994 +v 0.349350 -0.561521 -0.097234 +v 0.344643 -0.560892 -0.109994 +v 0.344643 -0.560892 -0.084475 +v 0.339778 -0.621070 -0.084475 +v 0.344457 -0.621082 -0.097234 +v 0.339778 -0.621070 -0.109994 +v 0.332090 -0.559213 -0.114779 +v 0.319536 -0.557535 -0.109994 +v 0.344643 -0.560892 -0.109994 +v 0.332090 -0.559213 -0.079690 +v 0.344643 -0.560892 -0.084475 +v 0.319536 -0.557535 -0.084475 +v 0.314823 -0.621007 -0.084475 +v 0.327301 -0.621039 -0.079690 +v 0.339778 -0.621070 -0.084475 +v 0.336944 -0.696862 -0.084475 +v 0.326032 -0.702265 -0.079690 +v 0.331744 -0.718611 -0.079690 +v 0.340863 -0.710536 -0.084475 +v 0.315120 -0.707668 -0.084475 +v 0.322625 -0.726688 -0.084475 +v 0.333749 -0.736487 -0.084475 +v 0.340709 -0.726318 -0.079690 +v 0.347669 -0.716148 -0.084475 +v 0.324863 -0.670024 -0.079690 +v 0.336860 -0.667535 -0.084475 +v 0.312865 -0.672514 -0.084475 +v 0.308366 -0.673448 -0.097234 +v 0.312865 -0.672514 -0.084475 +v 0.312865 -0.672514 -0.109994 +v 0.315120 -0.707668 -0.109994 +v 0.311028 -0.709694 -0.097234 +v 0.315120 -0.707668 -0.084475 +v 0.341359 -0.666601 -0.097234 +v 0.336860 -0.667535 -0.109994 +v 0.336860 -0.667535 -0.084475 +v 0.336944 -0.696862 -0.084475 +v 0.341037 -0.694836 -0.097234 +v 0.336944 -0.696862 -0.109994 +v 0.333749 -0.736487 -0.084475 +v 0.331139 -0.740300 -0.097234 +v 0.344700 -0.748232 -0.097234 +v 0.346511 -0.743919 -0.084475 +v 0.333749 -0.736487 -0.109994 +v 0.346511 -0.743919 -0.109994 +v 0.360217 -0.748903 -0.109994 +v 0.359135 -0.753489 -0.097234 +v 0.360217 -0.748903 -0.084475 +v 0.319206 -0.729716 -0.097234 +v 0.322625 -0.726688 -0.084475 +v 0.322625 -0.726688 -0.109994 +v 0.333749 -0.736487 -0.109994 +v 0.331139 -0.740300 -0.097234 +v 0.322625 -0.726688 -0.084475 +v 0.319206 -0.729716 -0.097234 +v 0.344282 -0.707507 -0.097234 +v 0.340863 -0.710536 -0.109994 +v 0.340863 -0.710536 -0.084475 +v 0.347669 -0.716148 -0.084475 +v 0.350278 -0.712335 -0.097234 +v 0.340863 -0.710536 -0.109994 +v 0.344282 -0.707507 -0.097234 +v 0.350278 -0.712335 -0.097234 +v 0.347669 -0.716148 -0.109994 +v 0.331744 -0.718611 -0.114779 +v 0.322625 -0.726688 -0.109994 +v 0.340709 -0.726318 -0.114779 +v 0.333749 -0.736487 -0.109994 +v 0.360217 -0.748903 -0.109994 +v 0.363102 -0.736675 -0.114779 +v 0.376120 -0.737659 -0.114779 +v 0.374897 -0.750233 -0.109994 +v 0.365987 -0.724447 -0.109994 +v 0.377343 -0.725085 -0.109994 +v 0.392172 -0.723749 -0.109994 +v 0.392189 -0.736443 -0.114779 +v 0.392205 -0.749136 -0.109994 +v 0.347669 -0.716148 -0.109994 +v 0.350278 -0.712335 -0.097234 +v 0.357985 -0.716604 -0.097234 +v 0.356174 -0.720917 -0.109994 +v 0.347669 -0.716148 -0.084475 +v 0.356174 -0.720917 -0.084475 +v 0.365987 -0.724447 -0.084475 +v 0.367069 -0.719861 -0.097234 +v 0.365987 -0.724447 -0.109994 +v 0.351343 -0.732418 -0.114779 +v 0.346511 -0.743919 -0.109994 +v 0.356174 -0.720917 -0.109994 +v 0.351343 -0.732418 -0.079690 +v 0.356174 -0.720917 -0.084475 +v 0.346511 -0.743919 -0.084475 +v 0.360217 -0.748903 -0.084475 +v 0.363102 -0.736675 -0.079690 +v 0.365987 -0.724447 -0.084475 +v 0.392205 -0.749136 -0.084475 +v 0.392211 -0.753896 -0.097234 +v 0.413751 -0.751955 -0.097234 +v 0.413467 -0.747190 -0.084475 +v 0.392205 -0.749136 -0.109994 +v 0.413467 -0.747190 -0.109994 +v 0.437075 -0.744948 -0.109994 +v 0.437529 -0.749701 -0.097234 +v 0.437075 -0.744948 -0.084475 +v 0.376120 -0.737659 -0.079690 +v 0.377343 -0.725085 -0.084475 +v 0.374897 -0.750233 -0.084475 +v 0.392205 -0.749136 -0.084475 +v 0.392189 -0.736443 -0.079690 +v 0.392172 -0.723749 -0.084475 +v 0.374438 -0.754948 -0.097234 +v 0.374897 -0.750233 -0.084475 +v 0.374897 -0.750233 -0.109994 +v 0.377801 -0.720370 -0.097234 +v 0.377343 -0.725085 -0.109994 +v 0.377343 -0.725085 -0.084475 +v 0.392172 -0.723749 -0.084475 +v 0.392166 -0.718990 -0.097234 +v 0.392172 -0.723749 -0.109994 +v 0.411672 -0.717011 -0.097234 +v 0.411955 -0.721776 -0.109994 +v 0.411955 -0.721776 -0.084475 +v 0.434654 -0.719596 -0.084475 +v 0.434200 -0.714843 -0.097234 +v 0.434654 -0.719596 -0.109994 +v 0.412712 -0.734483 -0.114779 +v 0.413467 -0.747190 -0.109994 +v 0.411955 -0.721776 -0.109994 +v 0.434654 -0.719596 -0.109994 +v 0.435864 -0.732272 -0.114779 +v 0.437075 -0.744948 -0.109994 +v 0.412712 -0.734483 -0.079690 +v 0.411955 -0.721776 -0.084475 +v 0.413467 -0.747190 -0.084475 +v 0.437075 -0.744948 -0.084475 +v 0.435864 -0.732272 -0.079690 +v 0.434654 -0.719596 -0.084475 +v 0.424640 -0.424965 -0.084475 +v 0.431849 -0.425574 -0.084475 +v 0.434385 -0.413699 -0.079690 +v 0.424647 -0.412513 -0.079690 +v 0.437636 -0.426926 -0.084475 +v 0.443230 -0.416094 -0.079690 +v 0.448823 -0.405263 -0.084475 +v 0.436921 -0.401824 -0.084475 +v 0.424654 -0.400061 -0.084475 +v 0.416023 -0.425264 -0.084475 +v 0.414963 -0.412594 -0.079690 +v 0.413903 -0.399923 -0.084475 +v 0.413505 -0.395172 -0.097234 +v 0.413903 -0.399923 -0.109994 +v 0.413903 -0.399923 -0.084475 +v 0.424654 -0.400061 -0.084475 +v 0.424657 -0.395391 -0.097234 +v 0.424654 -0.400061 -0.109994 +v 0.424640 -0.424965 -0.109994 +v 0.424637 -0.429634 -0.097234 +v 0.416421 -0.430016 -0.097234 +v 0.416023 -0.425264 -0.109994 +v 0.424640 -0.424965 -0.084475 +v 0.416023 -0.425264 -0.084475 +v 0.424640 -0.424965 -0.109994 +v 0.416023 -0.425264 -0.109994 +v 0.414963 -0.412594 -0.114779 +v 0.424647 -0.412513 -0.114779 +v 0.413903 -0.399923 -0.109994 +v 0.424654 -0.400061 -0.109994 +v 0.437636 -0.426926 -0.109994 +v 0.442641 -0.429599 -0.109994 +v 0.439603 -0.433094 -0.097234 +v 0.435539 -0.430988 -0.097234 +v 0.442641 -0.429599 -0.109994 +v 0.449513 -0.437683 -0.109994 +v 0.445814 -0.440568 -0.097234 +v 0.439603 -0.433094 -0.097234 +v 0.445814 -0.440568 -0.097234 +v 0.449513 -0.437683 -0.084475 +v 0.442641 -0.429599 -0.084475 +v 0.437636 -0.426926 -0.084475 +v 0.436921 -0.401824 -0.084475 +v 0.437872 -0.397371 -0.097234 +v 0.448823 -0.405263 -0.084475 +v 0.450921 -0.401201 -0.097234 +v 0.448823 -0.405263 -0.109994 +v 0.436921 -0.401824 -0.109994 +v 0.431849 -0.425574 -0.109994 +v 0.430898 -0.430026 -0.097234 +v 0.431849 -0.425574 -0.084475 +v 0.436921 -0.401824 -0.109994 +v 0.434385 -0.413699 -0.114779 +v 0.448823 -0.405263 -0.109994 +v 0.443230 -0.416094 -0.114779 +v 0.437636 -0.426926 -0.109994 +v 0.431849 -0.425574 -0.109994 +v 0.469241 -0.422296 -0.109994 +v 0.482593 -0.443801 -0.109994 +v 0.471640 -0.450105 -0.114779 +v 0.459377 -0.429990 -0.114779 +v 0.498905 -0.481761 -0.109994 +v 0.487312 -0.486906 -0.114779 +v 0.475719 -0.492051 -0.109994 +v 0.460687 -0.456409 -0.109994 +v 0.449513 -0.437683 -0.109994 +v 0.458842 -0.410959 -0.109994 +v 0.450741 -0.420279 -0.114779 +v 0.442641 -0.429599 -0.109994 +v 0.442641 -0.429599 -0.084475 +v 0.450741 -0.420279 -0.079690 +v 0.449513 -0.437683 -0.084475 +v 0.459377 -0.429990 -0.079690 +v 0.469241 -0.422296 -0.084475 +v 0.458842 -0.410959 -0.084475 +v 0.458842 -0.410959 -0.084475 +v 0.461879 -0.407464 -0.097234 +v 0.458842 -0.410959 -0.084475 +v 0.469241 -0.422296 -0.084475 +v 0.472941 -0.419411 -0.097234 +v 0.461879 -0.407464 -0.097234 +v 0.469241 -0.422296 -0.109994 +v 0.458842 -0.410959 -0.109994 +v 0.458842 -0.410959 -0.109994 +v 0.498905 -0.481761 -0.084475 +v 0.517020 -0.538677 -0.084475 +v 0.521524 -0.537169 -0.097234 +v 0.503253 -0.479833 -0.097234 +v 0.533661 -0.600110 -0.084475 +v 0.538254 -0.599213 -0.097234 +v 0.533661 -0.600110 -0.109994 +v 0.517020 -0.538677 -0.109994 +v 0.498905 -0.481761 -0.109994 +v 0.460687 -0.456409 -0.084475 +v 0.471640 -0.450105 -0.079690 +v 0.475719 -0.492051 -0.084475 +v 0.487312 -0.486906 -0.079690 +v 0.498905 -0.481761 -0.084475 +v 0.482593 -0.443801 -0.084475 +v 0.482593 -0.443801 -0.084475 +v 0.486700 -0.441436 -0.097234 +v 0.482593 -0.443801 -0.109994 +v 0.460687 -0.456409 -0.109994 +v 0.456579 -0.458774 -0.097234 +v 0.475719 -0.492051 -0.109994 +v 0.471371 -0.493979 -0.097234 +v 0.475719 -0.492051 -0.084475 +v 0.460687 -0.456409 -0.084475 +v 0.449513 -0.437683 -0.084475 +v 0.533661 -0.600110 -0.109994 +v 0.545332 -0.650316 -0.109994 +v 0.533079 -0.650141 -0.114779 +v 0.521415 -0.602503 -0.114779 +v 0.549771 -0.685261 -0.109994 +v 0.538033 -0.682021 -0.114779 +v 0.526295 -0.678781 -0.109994 +v 0.520828 -0.649967 -0.109994 +v 0.509169 -0.604895 -0.109994 +v 0.493003 -0.546725 -0.109994 +v 0.488500 -0.548234 -0.097234 +v 0.509169 -0.604895 -0.109994 +v 0.504576 -0.605792 -0.097234 +v 0.509169 -0.604895 -0.084475 +v 0.493003 -0.546725 -0.084475 +v 0.517020 -0.538677 -0.109994 +v 0.505012 -0.542701 -0.114779 +v 0.493003 -0.546725 -0.109994 +v 0.493003 -0.546725 -0.084475 +v 0.505012 -0.542701 -0.079690 +v 0.509169 -0.604895 -0.084475 +v 0.521415 -0.602503 -0.079690 +v 0.533661 -0.600110 -0.084475 +v 0.517020 -0.538677 -0.084475 +v 0.526295 -0.678781 -0.084475 +v 0.525036 -0.692949 -0.084475 +v 0.535518 -0.699153 -0.079690 +v 0.538033 -0.682021 -0.079690 +v 0.519415 -0.699748 -0.084475 +v 0.528174 -0.708417 -0.079690 +v 0.536932 -0.717085 -0.084475 +v 0.546000 -0.705358 -0.084475 +v 0.549771 -0.685261 -0.084475 +v 0.520828 -0.649967 -0.084475 +v 0.533079 -0.650141 -0.079690 +v 0.545332 -0.650316 -0.084475 +v 0.545332 -0.650316 -0.084475 +v 0.549926 -0.650381 -0.097234 +v 0.549771 -0.685261 -0.084475 +v 0.554172 -0.686476 -0.097234 +v 0.549771 -0.685261 -0.109994 +v 0.545332 -0.650316 -0.109994 +v 0.520828 -0.649967 -0.109994 +v 0.516233 -0.649902 -0.097234 +v 0.526295 -0.678781 -0.109994 +v 0.521893 -0.677566 -0.097234 +v 0.526295 -0.678781 -0.084475 +v 0.520828 -0.649967 -0.084475 +v 0.536932 -0.717085 -0.084475 +v 0.525807 -0.726798 -0.084475 +v 0.528402 -0.730690 -0.097234 +v 0.540216 -0.720336 -0.097234 +v 0.513292 -0.734286 -0.084475 +v 0.515223 -0.738584 -0.097234 +v 0.513292 -0.734286 -0.109994 +v 0.525807 -0.726798 -0.109994 +v 0.536932 -0.717085 -0.109994 +v 0.546000 -0.705358 -0.084475 +v 0.549931 -0.707684 -0.097234 +v 0.536932 -0.717085 -0.084475 +v 0.540216 -0.720336 -0.097234 +v 0.536932 -0.717085 -0.109994 +v 0.546000 -0.705358 -0.109994 +v 0.525036 -0.692949 -0.109994 +v 0.521105 -0.690623 -0.097234 +v 0.519415 -0.699748 -0.109994 +v 0.516131 -0.696498 -0.097234 +v 0.521105 -0.690623 -0.097234 +v 0.516131 -0.696498 -0.097234 +v 0.519415 -0.699748 -0.084475 +v 0.525036 -0.692949 -0.084475 +v 0.525036 -0.692949 -0.084475 +v 0.546000 -0.705358 -0.109994 +v 0.535518 -0.699153 -0.114779 +v 0.536932 -0.717085 -0.109994 +v 0.528174 -0.708417 -0.114779 +v 0.519415 -0.699748 -0.109994 +v 0.525036 -0.692949 -0.109994 +v 0.513292 -0.734286 -0.109994 +v 0.499130 -0.738370 -0.109994 +v 0.495549 -0.726254 -0.114779 +v 0.508145 -0.722825 -0.114779 +v 0.481927 -0.740569 -0.109994 +v 0.479540 -0.728101 -0.114779 +v 0.477154 -0.715635 -0.109994 +v 0.491969 -0.714139 -0.109994 +v 0.502998 -0.711364 -0.109994 +v 0.519415 -0.699748 -0.109994 +v 0.511966 -0.706040 -0.109994 +v 0.509371 -0.702148 -0.097234 +v 0.502998 -0.711364 -0.109994 +v 0.501068 -0.707066 -0.097234 +v 0.502998 -0.711364 -0.084475 +v 0.511966 -0.706040 -0.084475 +v 0.525807 -0.726798 -0.109994 +v 0.518887 -0.716419 -0.114779 +v 0.511966 -0.706040 -0.109994 +v 0.511966 -0.706040 -0.084475 +v 0.518887 -0.716419 -0.079690 +v 0.502998 -0.711364 -0.084475 +v 0.508145 -0.722825 -0.079690 +v 0.513292 -0.734286 -0.084475 +v 0.525807 -0.726798 -0.084475 +v 0.481927 -0.740569 -0.084475 +v 0.460680 -0.742682 -0.084475 +v 0.461303 -0.747415 -0.097234 +v 0.482821 -0.745244 -0.097234 +v 0.460680 -0.742682 -0.109994 +v 0.481927 -0.740569 -0.109994 +v 0.491969 -0.714139 -0.084475 +v 0.495549 -0.726254 -0.079690 +v 0.477155 -0.715635 -0.084475 +v 0.479540 -0.728101 -0.079690 +v 0.481927 -0.740569 -0.084475 +v 0.499130 -0.738370 -0.084475 +v 0.499130 -0.738370 -0.084475 +v 0.500472 -0.742913 -0.097234 +v 0.499130 -0.738370 -0.109994 +v 0.491969 -0.714139 -0.109994 +v 0.490626 -0.709596 -0.097234 +v 0.477154 -0.715635 -0.109994 +v 0.476259 -0.710960 -0.097234 +v 0.477155 -0.715635 -0.084475 +v 0.491969 -0.714139 -0.084475 +v 0.434654 -0.719596 -0.084475 +v 0.434200 -0.714843 -0.097234 +v 0.435864 -0.732272 -0.097234 +v 0.435864 -0.732272 -0.079690 +v 0.434654 -0.719596 -0.109994 +v 0.435864 -0.732272 -0.114779 +v 0.437075 -0.744948 -0.109994 +v 0.437529 -0.749701 -0.097234 +v 0.437075 -0.744948 -0.084475 +v 0.457355 -0.717441 -0.109994 +v 0.456732 -0.712708 -0.097234 +v 0.457355 -0.717441 -0.084475 +v 0.460680 -0.742682 -0.109994 +v 0.459018 -0.730061 -0.114779 +v 0.457355 -0.717441 -0.109994 +v 0.457355 -0.717441 -0.084475 +v 0.459018 -0.730061 -0.079690 +v 0.460680 -0.742682 -0.084475 +vt 0.463637 0.772893 +vt 0.462666 0.772873 +vt 0.463105 0.774091 +vt 0.461935 0.774521 +vt 0.411032 0.044511 +vt 0.411062 0.045426 +vt 0.411761 0.045270 +vt 0.411552 0.044416 +vt 0.411203 0.046345 +vt 0.412083 0.046129 +vt 0.412925 0.045793 +vt 0.412388 0.045032 +vt 0.411964 0.044276 +vt 0.409715 0.044555 +vt 0.409657 0.045496 +vt 0.410357 0.045487 +vt 0.410404 0.044550 +vt 0.409712 0.046442 +vt 0.410423 0.046430 +vt 0.919393 0.536644 +vt 0.919371 0.537363 +vt 0.920128 0.537358 +vt 0.920150 0.536635 +vt 0.919371 0.538157 +vt 0.920130 0.538182 +vt 0.921135 0.538186 +vt 0.921134 0.537392 +vt 0.921157 0.536673 +vt 0.972655 0.411650 +vt 0.972641 0.411017 +vt 0.971884 0.410976 +vt 0.971895 0.411581 +vt 0.972639 0.410321 +vt 0.971883 0.410284 +vt 0.970875 0.410284 +vt 0.970877 0.410980 +vt 0.970890 0.411614 +vt 0.149234 0.040261 +vt 0.149068 0.041114 +vt 0.149771 0.041176 +vt 0.149861 0.040299 +vt 0.149015 0.042073 +vt 0.149794 0.042159 +vt 0.150504 0.042171 +vt 0.150471 0.041185 +vt 0.150550 0.040305 +vt 0.972738 0.412580 +vt 0.971957 0.412364 +vt 0.972022 0.412639 +vt 0.972821 0.412917 +vt 0.970974 0.412543 +vt 0.971056 0.412880 +vt 0.932958 0.409466 +vt 0.931972 0.409301 +vt 0.931863 0.409960 +vt 0.932861 0.410074 +vt 0.933737 0.409180 +vt 0.933629 0.409839 +vt 0.920179 0.539154 +vt 0.921178 0.539089 +vt 0.919415 0.539060 +vt 0.919502 0.539932 +vt 0.920276 0.540110 +vt 0.921266 0.539961 +vt 0.971920 0.412035 +vt 0.972689 0.412171 +vt 0.970924 0.412134 +vt 0.148373 0.040960 +vt 0.148141 0.041859 +vt 0.148716 0.040166 +vt 0.148309 0.040027 +vt 0.147752 0.040724 +vt 0.147308 0.041526 +vt 0.145977 0.040144 +vt 0.146703 0.039600 +vt 0.145990 0.038050 +vt 0.145197 0.038485 +vt 0.147542 0.039162 +vt 0.146895 0.037721 +vt 0.146117 0.035021 +vt 0.145175 0.035262 +vt 0.144346 0.035608 +vt 0.147244 0.040367 +vt 0.146632 0.041041 +vt 0.147969 0.039798 +vt 0.412906 0.044671 +vt 0.412309 0.044044 +vt 0.413615 0.045303 +vt 0.414293 0.044396 +vt 0.413467 0.043896 +vt 0.412754 0.043401 +vt 0.920438 0.540906 +vt 0.921413 0.540689 +vt 0.997161 0.790710 +vt 0.998132 0.790473 +vt 0.997963 0.789960 +vt 0.996977 0.790147 +vt 0.997818 0.789030 +vt 0.996822 0.789166 +vt 0.920750 0.541698 +vt 0.921709 0.541432 +vt 0.995749 0.784310 +vt 0.996557 0.784450 +vt 0.996515 0.780075 +vt 0.995709 0.779967 +vt 0.997560 0.784390 +vt 0.997519 0.780048 +vt 0.997534 0.775388 +vt 0.996531 0.775370 +vt 0.995723 0.775308 +vt 0.414222 0.042330 +vt 0.413439 0.041945 +vt 0.415117 0.042720 +vt 0.416044 0.039811 +vt 0.415110 0.039511 +vt 0.414288 0.039216 +vt 0.996007 0.788949 +vt 0.996671 0.787421 +vt 0.995861 0.787247 +vt 0.997672 0.787327 +vt 0.932734 0.411511 +vt 0.933496 0.411318 +vt 0.931731 0.411439 +vt 0.931634 0.414193 +vt 0.932640 0.414231 +vt 0.933399 0.414073 +vt 0.142860 0.026752 +vt 0.143713 0.026610 +vt 0.143283 0.023061 +vt 0.142452 0.023016 +vt 0.144677 0.026574 +vt 0.144226 0.023212 +vt 0.144081 0.021077 +vt 0.143203 0.020706 +vt 0.142436 0.020441 +vt 0.932636 0.418368 +vt 0.933394 0.418241 +vt 0.931629 0.418362 +vt 0.931680 0.422775 +vt 0.932684 0.422735 +vt 0.933445 0.422654 +vt 0.144379 0.031077 +vt 0.143529 0.031339 +vt 0.145341 0.030921 +vt 0.416016 0.035280 +vt 0.415172 0.035070 +vt 0.416973 0.035495 +vt 0.417764 0.030856 +vt 0.416801 0.030763 +vt 0.415950 0.030675 +vt 0.416691 0.025116 +vt 0.417466 0.024793 +vt 0.417167 0.023550 +vt 0.416503 0.024082 +vt 0.418354 0.024475 +vt 0.417943 0.023022 +vt 0.417203 0.022222 +vt 0.416570 0.022919 +vt 0.416048 0.023621 +vt 0.417324 0.027175 +vt 0.416490 0.027276 +vt 0.418270 0.027079 +vt 0.996587 0.771510 +vt 0.995773 0.771518 +vt 0.997584 0.771599 +vt 0.997693 0.768996 +vt 0.996707 0.768825 +vt 0.995883 0.768916 +vt 0.932738 0.426076 +vt 0.933506 0.426065 +vt 0.931741 0.426186 +vt 0.931830 0.428347 +vt 0.932813 0.428155 +vt 0.933595 0.428226 +vt 0.245621 0.006777 +vt 0.244642 0.006571 +vt 0.244418 0.007552 +vt 0.245412 0.007700 +vt 0.243856 0.006772 +vt 0.243647 0.007695 +vt 0.243500 0.008694 +vt 0.244263 0.008604 +vt 0.245265 0.008699 +vt 0.996912 0.767312 +vt 0.996072 0.767480 +vt 0.997883 0.767560 +vt 0.998132 0.766787 +vt 0.997179 0.766478 +vt 0.245891 0.005983 +vt 0.244933 0.005719 +vt 0.932935 0.429102 +vt 0.933737 0.429250 +vt 0.931972 0.429371 +vt 0.932166 0.429813 +vt 0.933105 0.429483 +vt 0.144297 0.020055 +vt 0.144711 0.020392 +vt 0.145123 0.020000 +vt 0.144764 0.019599 +vt 0.143535 0.019477 +vt 0.142885 0.019005 +vt 0.144148 0.018854 +vt 0.143645 0.018215 +vt 0.145509 0.017128 +vt 0.145726 0.017945 +vt 0.146670 0.017784 +vt 0.146572 0.016930 +vt 0.146055 0.018868 +vt 0.146879 0.018743 +vt 0.147967 0.018738 +vt 0.147846 0.017761 +vt 0.147838 0.016890 +vt 0.359461 0.001550 +vt 0.358672 0.001801 +vt 0.358541 0.002318 +vt 0.359314 0.002120 +vt 0.357697 0.001587 +vt 0.357551 0.002157 +vt 0.357433 0.002837 +vt 0.358433 0.002947 +vt 0.359197 0.002799 +vt 0.144891 0.018337 +vt 0.144537 0.017586 +vt 0.145359 0.019193 +vt 0.415840 0.022395 +vt 0.415464 0.023210 +vt 0.416328 0.021585 +vt 0.415367 0.021121 +vt 0.415015 0.021999 +vt 0.414775 0.022881 +vt 0.245221 0.011062 +vt 0.244214 0.011047 +vt 0.244239 0.012644 +vt 0.245247 0.012639 +vt 0.243456 0.011057 +vt 0.243482 0.012633 +vt 0.243513 0.014384 +vt 0.244271 0.014407 +vt 0.245278 0.014389 +vt 0.414076 0.021834 +vt 0.413954 0.022753 +vt 0.414310 0.020920 +vt 0.413044 0.020878 +vt 0.412899 0.021810 +vt 0.412867 0.022747 +vt 0.244207 0.009730 +vt 0.245213 0.009780 +vt 0.243448 0.009775 +vt 0.358393 0.003726 +vt 0.359152 0.003623 +vt 0.357388 0.003660 +vt 0.357386 0.004759 +vt 0.358393 0.004792 +vt 0.359150 0.004722 +vt 0.358396 0.006240 +vt 0.359152 0.006190 +vt 0.357388 0.006227 +vt 0.357389 0.007911 +vt 0.358396 0.007911 +vt 0.359152 0.007874 +vt 0.149352 0.017762 +vt 0.149397 0.016885 +vt 0.149418 0.018745 +vt 0.151083 0.018747 +vt 0.151050 0.017763 +vt 0.151129 0.016885 +vt 0.411394 0.021809 +vt 0.411415 0.022752 +vt 0.411485 0.020871 +vt 0.409753 0.020869 +vt 0.409695 0.021808 +vt 0.409750 0.022753 +vt 0.408398 0.044510 +vt 0.407878 0.044414 +vt 0.407554 0.045268 +vt 0.408253 0.045424 +vt 0.407467 0.044274 +vt 0.406928 0.045029 +vt 0.406501 0.045789 +vt 0.407342 0.046127 +vt 0.408221 0.046343 +vt 0.409026 0.044549 +vt 0.408958 0.045487 +vt 0.409001 0.046429 +vt 0.920182 0.535914 +vt 0.919424 0.535927 +vt 0.921188 0.535956 +vt 0.921248 0.535173 +vt 0.920246 0.535103 +vt 0.919484 0.535144 +vt 0.972655 0.408987 +vt 0.971895 0.408984 +vt 0.971884 0.409592 +vt 0.972641 0.409624 +vt 0.970890 0.408950 +vt 0.970877 0.409587 +vt 0.151868 0.040262 +vt 0.151238 0.040300 +vt 0.151170 0.041177 +vt 0.151876 0.041116 +vt 0.151214 0.042159 +vt 0.151997 0.042075 +vt 0.972738 0.408033 +vt 0.972821 0.407672 +vt 0.972022 0.407889 +vt 0.971957 0.408183 +vt 0.496437 0.061000 +vt 0.496346 0.061640 +vt 0.497343 0.061772 +vt 0.497424 0.061181 +vt 0.972233 0.407455 +vt 0.971285 0.407154 +vt 0.971056 0.407635 +vt 0.970974 0.407996 +vt 0.921358 0.534298 +vt 0.920366 0.534162 +vt 0.921509 0.533470 +vt 0.920534 0.533255 +vt 0.919746 0.533442 +vt 0.919594 0.534270 +vt 0.972689 0.408456 +vt 0.971920 0.408522 +vt 0.970924 0.408419 +vt 0.152881 0.041862 +vt 0.152579 0.040962 +vt 0.153731 0.041529 +vt 0.153211 0.040727 +vt 0.152804 0.040030 +vt 0.152390 0.040168 +vt 0.155131 0.040148 +vt 0.155993 0.038491 +vt 0.155106 0.038055 +vt 0.154316 0.039604 +vt 0.156986 0.035615 +vt 0.156059 0.035268 +vt 0.155244 0.035026 +vt 0.154332 0.037724 +vt 0.153614 0.039165 +vt 0.154431 0.041045 +vt 0.153737 0.040370 +vt 0.153155 0.039801 +vt 0.407122 0.044042 +vt 0.406411 0.044668 +vt 0.406680 0.043398 +vt 0.405852 0.043892 +vt 0.405137 0.044391 +vt 0.405813 0.045299 +vt 0.921709 0.532806 +vt 0.920753 0.532529 +vt 0.998212 0.367603 +vt 0.998022 0.366693 +vt 0.997027 0.366825 +vt 0.997229 0.367785 +vt 0.996256 0.366588 +vt 0.996446 0.367498 +vt 0.919945 0.532778 +vt 0.997656 0.362103 +vt 0.997565 0.357787 +vt 0.996558 0.357812 +vt 0.996650 0.362160 +vt 0.997540 0.353150 +vt 0.996535 0.353129 +vt 0.995774 0.353045 +vt 0.995799 0.357682 +vt 0.995889 0.361998 +vt 0.406000 0.041941 +vt 0.405103 0.042325 +vt 0.405159 0.039211 +vt 0.404224 0.039505 +vt 0.403401 0.039805 +vt 0.404319 0.042714 +vt 0.997823 0.365013 +vt 0.996821 0.365104 +vt 0.996057 0.364909 +vt 0.496233 0.063091 +vt 0.497234 0.063182 +vt 0.496142 0.065811 +vt 0.497146 0.065869 +vt 0.497952 0.065701 +vt 0.498042 0.062981 +vt 0.498156 0.061530 +vt 0.158910 0.026760 +vt 0.159502 0.023025 +vt 0.158554 0.023069 +vt 0.157949 0.026617 +vt 0.159645 0.020450 +vt 0.158751 0.020714 +vt 0.157969 0.021084 +vt 0.157718 0.023219 +vt 0.157101 0.026581 +vt 0.496120 0.069945 +vt 0.497124 0.069972 +vt 0.496141 0.074330 +vt 0.497144 0.074310 +vt 0.497950 0.074220 +vt 0.497929 0.069836 +vt 0.158013 0.031346 +vt 0.157061 0.031084 +vt 0.156222 0.030927 +vt 0.404289 0.035065 +vt 0.403331 0.035273 +vt 0.403524 0.030669 +vt 0.402561 0.030756 +vt 0.401710 0.030848 +vt 0.402486 0.035487 +vt 0.402801 0.025109 +vt 0.402993 0.024075 +vt 0.402218 0.023542 +vt 0.401915 0.024785 +vt 0.403449 0.023615 +vt 0.402818 0.022912 +vt 0.402298 0.022215 +vt 0.401557 0.023014 +vt 0.401141 0.024466 +vt 0.402995 0.027269 +vt 0.402050 0.027167 +vt 0.401217 0.027070 +vt 0.997569 0.349375 +vt 0.996570 0.349283 +vt 0.997682 0.346775 +vt 0.996696 0.346600 +vt 0.995916 0.346670 +vt 0.995803 0.349270 +vt 0.496175 0.077721 +vt 0.497172 0.077631 +vt 0.496236 0.079876 +vt 0.497223 0.079702 +vt 0.498046 0.079766 +vt 0.497984 0.077611 +vt 0.245891 0.021845 +vt 0.245650 0.020996 +vt 0.244662 0.021175 +vt 0.244920 0.022076 +vt 0.245468 0.020051 +vt 0.244471 0.020179 +vt 0.243703 0.020046 +vt 0.243885 0.020991 +vt 0.244126 0.021840 +vt 0.997907 0.345327 +vt 0.996940 0.345074 +vt 0.998212 0.344533 +vt 0.997267 0.344218 +vt 0.996446 0.344429 +vt 0.996141 0.345222 +vt 0.496346 0.080909 +vt 0.497317 0.080657 +vt 0.496501 0.081371 +vt 0.497452 0.081056 +vt 0.358814 0.014529 +vt 0.358672 0.014101 +vt 0.357697 0.014325 +vt 0.357861 0.014810 +vt 0.498156 0.080799 +vt 0.159267 0.019013 +vt 0.158480 0.019485 +vt 0.158547 0.018223 +vt 0.157897 0.018861 +vt 0.157360 0.019606 +vt 0.157804 0.020062 +vt 0.156736 0.017134 +vt 0.155683 0.016934 +vt 0.155429 0.017788 +vt 0.156364 0.017951 +vt 0.154419 0.016893 +vt 0.154253 0.017765 +vt 0.154199 0.018741 +vt 0.155286 0.018748 +vt 0.156104 0.018874 +vt 0.359461 0.014288 +vt 0.359314 0.013675 +vt 0.358541 0.013546 +vt 0.359197 0.012961 +vt 0.358433 0.012885 +vt 0.357433 0.012999 +vt 0.357551 0.013712 +vt 0.157686 0.017592 +vt 0.157179 0.018343 +vt 0.156785 0.019199 +vt 0.404035 0.023204 +vt 0.403549 0.022389 +vt 0.404725 0.022876 +vt 0.404375 0.021993 +vt 0.404138 0.021116 +vt 0.403176 0.021578 +vt 0.245340 0.017716 +vt 0.245310 0.016140 +vt 0.244303 0.016170 +vt 0.244334 0.017766 +vt 0.243545 0.016135 +vt 0.243575 0.017710 +vt 0.405546 0.022749 +vt 0.405315 0.021830 +vt 0.406633 0.022744 +vt 0.406491 0.021807 +vt 0.406462 0.020875 +vt 0.405196 0.020915 +vt 0.245378 0.018993 +vt 0.244375 0.019077 +vt 0.243613 0.018988 +vt 0.359152 0.012124 +vt 0.358393 0.012094 +vt 0.359150 0.011025 +vt 0.358393 0.011029 +vt 0.357386 0.011062 +vt 0.357388 0.012162 +vt 0.464275 0.773662 +vt 0.461935 0.773518 +vt 0.462573 0.775289 +vt 0.463544 0.775309 +vt 0.464275 0.774665 +vt 0.359152 0.009557 +vt 0.358396 0.009582 +vt 0.357388 0.009595 +vt 0.152860 0.016886 +vt 0.152748 0.017764 +vt 0.152748 0.018747 +vt 0.408085 0.022751 +vt 0.407997 0.021808 +vt 0.408021 0.020869 +vn -0.4322 0.6188 0.6559 +vn -0.4673 0.8841 -0.0003 +vn -0.9955 -0.0950 0.0000 +vn -0.4673 0.8841 0.0001 +vn -0.3792 -0.0358 -0.9246 +vn 0.1504 -0.6893 0.7087 +vn -0.0093 0.0132 0.9999 +vn -0.0105 0.0137 0.9999 +vn 0.2405 -0.6670 0.7051 +vn -0.1912 0.6958 0.6923 +vn -0.2846 0.6689 0.6868 +vn -0.4070 0.6088 0.6809 +vn -0.0161 0.0233 0.9996 +vn 0.3658 -0.5978 0.7133 +vn 0.0672 -0.7033 0.7077 +vn -0.0003 0.0028 1.0000 +vn -0.0041 0.0079 1.0000 +vn 0.0910 -0.6996 0.7087 +vn -0.0675 0.7065 0.7045 +vn -0.1123 0.7059 0.6993 +vn -0.0675 0.7065 -0.7045 +vn -0.1123 0.7059 -0.6993 +vn -0.1588 0.9873 -0.0001 +vn -0.0951 0.9955 0.0001 +vn -0.1912 0.6958 -0.6923 +vn -0.2670 0.9637 -0.0000 +vn -0.0674 0.7065 0.7045 +vn 0.1504 -0.6893 -0.7087 +vn 0.0910 -0.6996 -0.7087 +vn 0.1258 -0.9921 0.0000 +vn 0.2059 -0.9786 0.0000 +vn 0.0671 -0.7033 -0.7077 +vn 0.0951 -0.9955 0.0000 +vn -0.0093 0.0132 -0.9999 +vn -0.0041 0.0079 -1.0000 +vn -0.0002 0.0024 -1.0000 +vn 0.0671 -0.7033 -0.7078 +vn 0.3658 -0.5978 -0.7133 +vn 0.5126 -0.8586 -0.0000 +vn 0.7623 -0.6472 0.0000 +vn 0.5239 -0.4440 -0.7269 +vn 0.3658 -0.5979 0.7133 +vn 0.5239 -0.4439 0.7269 +vn 0.7624 -0.6471 -0.0000 +vn 0.5240 -0.4439 0.7269 +vn 0.6369 -0.2928 0.7132 +vn 0.9105 -0.4136 -0.0000 +vn 0.5239 -0.4439 -0.7269 +vn 0.6369 -0.2928 -0.7132 +vn -0.3940 0.9191 -0.0000 +vn -0.2846 0.6688 -0.6868 +vn -0.4070 0.6088 -0.6809 +vn -0.5589 0.8292 0.0000 +vn 0.3293 -0.9442 0.0000 +vn 0.2405 -0.6670 -0.7051 +vn -0.0105 0.0136 -0.9999 +vn -0.0161 0.0233 -0.9996 +vn -0.4070 0.6088 -0.6810 +vn -0.6487 0.3204 -0.6904 +vn -0.0173 0.0106 -0.9998 +vn -0.0156 0.0049 -0.9999 +vn -0.6892 0.2060 -0.6946 +vn 0.6738 -0.1925 -0.7134 +vn 0.6939 -0.1136 -0.7110 +vn -0.0105 0.0015 -0.9999 +vn -0.7056 0.1186 -0.6986 +vn -0.0286 0.0267 -0.9992 +vn -0.5565 0.4764 -0.6807 +vn -0.0277 0.0265 0.9993 +vn -0.5565 0.4764 0.6807 +vn -0.6487 0.3203 0.6904 +vn -0.0173 0.0105 0.9998 +vn -0.7604 0.6495 0.0000 +vn -0.8957 0.4446 -0.0000 +vn -0.7057 0.1187 0.6985 +vn -0.9860 0.1669 -0.0002 +vn -0.9954 0.0957 0.0001 +vn -0.7097 0.0683 0.7012 +vn -0.7057 0.1187 -0.6985 +vn -0.7097 0.0682 -0.7012 +vn -0.7157 0.0401 -0.6973 +vn -0.9985 0.0544 0.0001 +vn -0.7157 0.0402 0.6973 +vn -0.0154 0.0048 0.9999 +vn 0.6738 -0.1925 0.7134 +vn -0.6892 0.2060 0.6946 +vn -0.7056 0.1186 0.6986 +vn -0.0104 0.0014 0.9999 +vn 0.6939 -0.1136 0.7110 +vn -0.6487 0.3204 0.6903 +vn -0.9577 0.2879 0.0000 +vn 0.9622 -0.2724 0.0002 +vn 0.9871 -0.1604 0.0003 +vn 0.6939 -0.1136 -0.7111 +vn -0.7156 0.0401 -0.6973 +vn -0.0028 -0.0011 -1.0000 +vn -0.0080 -0.0020 -1.0000 +vn -0.7289 -0.0097 -0.6845 +vn 0.7118 -0.0511 -0.7005 +vn 0.7199 -0.0216 -0.6937 +vn 0.7038 0.0991 -0.7034 +vn -0.0337 -0.0042 -0.9994 +vn -0.7242 -0.1621 -0.6702 +vn 0.9952 -0.0981 0.0002 +vn 0.7045 -0.0694 -0.7063 +vn 0.7045 -0.0694 0.7063 +vn 0.7118 -0.0511 0.7005 +vn 0.9973 -0.0734 -0.0001 +vn -0.0043 0.0001 -1.0000 +vn -0.0046 0.0001 1.0000 +vn -0.7156 0.0401 0.6973 +vn -0.0029 -0.0011 1.0000 +vn 0.7038 0.0991 0.7034 +vn -0.0337 -0.0042 0.9994 +vn -0.0531 -0.0305 0.9981 +vn 0.5622 0.3666 0.7413 +vn -0.7242 -0.1621 0.6702 +vn -0.6081 -0.4267 0.6694 +vn -0.4256 -0.5901 0.6860 +vn -0.0146 -0.0163 0.9998 +vn 0.3975 0.5808 0.7104 +vn -0.0082 -0.0021 1.0000 +vn 0.7199 -0.0215 0.6937 +vn -0.7289 -0.0097 0.6846 +vn -0.9998 -0.0187 0.0001 +vn -0.7289 -0.0096 0.6846 +vn -0.7289 -0.0096 -0.6846 +vn -0.9729 -0.2311 0.0000 +vn 0.9993 -0.0362 -0.0000 +vn 0.7200 -0.0216 -0.6937 +vn 0.9927 0.1210 -0.0000 +vn -0.5856 -0.8106 -0.0000 +vn -0.4242 -0.9055 -0.0003 +vn -0.3072 -0.6556 0.6898 +vn -0.4256 -0.5901 -0.6860 +vn -0.3072 -0.6556 -0.6898 +vn -0.1582 -0.7085 -0.6877 +vn -0.2195 -0.9756 -0.0001 +vn -0.1582 -0.7085 0.6877 +vn -0.8141 -0.5808 0.0000 +vn -0.6082 -0.4267 0.6693 +vn -0.6082 -0.4267 -0.6693 +vn -0.8141 -0.5807 -0.0000 +vn 0.8442 0.5360 0.0000 +vn 0.5622 0.3666 -0.7413 +vn 0.3976 0.5808 0.7104 +vn 0.5616 0.8274 -0.0000 +vn 0.5622 0.3667 -0.7413 +vn 0.8443 0.5359 -0.0000 +vn 0.5615 0.8274 -0.0000 +vn 0.3975 0.5808 -0.7103 +vn -0.0530 -0.0305 -0.9981 +vn -0.0147 -0.0163 -0.9998 +vn -0.0075 -0.0298 -0.9995 +vn -0.0012 -0.0168 -0.9999 +vn -0.0097 -0.7200 -0.6940 +vn 0.1376 0.6760 -0.7240 +vn -0.0119 0.7011 -0.7130 +vn -0.0671 0.7061 -0.7049 +vn -0.0012 -0.0021 -1.0000 +vn 0.0550 -0.7093 -0.7028 +vn 0.3976 0.5808 -0.7103 +vn 0.5615 0.8275 0.0000 +vn 0.4143 0.9101 0.0000 +vn 0.2915 0.6385 -0.7123 +vn 0.3976 0.5808 0.7103 +vn 0.2915 0.6385 0.7123 +vn 0.1376 0.6760 0.7240 +vn 0.1959 0.9806 0.0000 +vn 0.1376 0.6759 -0.7240 +vn -0.0098 -0.0173 -0.9998 +vn 0.2914 0.6385 -0.7123 +vn -0.0097 -0.0172 0.9998 +vn -0.0075 -0.0297 0.9995 +vn 0.1376 0.6759 0.7240 +vn 0.0550 -0.7093 0.7028 +vn 0.0755 -0.9971 -0.0001 +vn 0.0923 -0.9957 -0.0002 +vn 0.0658 -0.7053 0.7059 +vn 0.0658 -0.7053 -0.7059 +vn -0.3073 -0.6894 -0.6559 +vn -0.2915 -0.9566 -0.0000 +vn -0.3073 -0.6894 0.6559 +vn -0.0012 -0.0167 0.9999 +vn -0.0119 0.7011 0.7130 +vn -0.0097 -0.7200 0.6940 +vn -0.0012 -0.0020 1.0000 +vn -0.0671 0.7061 0.7049 +vn -0.0173 -0.9999 -0.0002 +vn -0.0097 -0.7199 0.6940 +vn -0.0097 -0.7199 -0.6940 +vn -0.0224 0.9998 0.0000 +vn -0.0118 0.7011 -0.7130 +vn -0.0118 0.7011 0.7130 +vn -0.0964 0.9953 -0.0000 +vn -0.0980 0.9952 0.0002 +vn -0.0690 0.7050 -0.7058 +vn -0.0690 0.7051 0.7058 +vn -0.4672 0.8841 0.0001 +vn -0.4322 0.6188 -0.6559 +vn -0.0002 -0.0002 -1.0000 +vn -0.4322 0.6189 -0.6559 +vn -0.3791 -0.0362 -0.9246 +vn -0.0003 0.0002 1.0000 +vn -0.0690 0.7050 0.7058 +vn -0.3074 -0.6894 0.6559 +vn -0.3792 -0.0362 0.9246 +vn -0.0173 -0.7053 0.7087 +vn -0.1100 -0.7005 0.7052 +vn 0.0078 0.0154 0.9999 +vn 0.0066 0.0147 0.9999 +vn -0.2460 -0.6563 0.7133 +vn 0.0114 0.0259 0.9996 +vn 0.2845 0.6748 0.6809 +vn 0.1528 0.7106 0.6868 +vn 0.0561 0.7194 0.6923 +vn 0.0431 -0.7042 0.7087 +vn 0.0026 0.0085 1.0000 +vn -0.0233 0.7144 0.6993 +vn -0.0309 0.9995 -0.0001 +vn -0.0233 0.7144 -0.6993 +vn 0.0798 0.9968 0.0000 +vn 0.0561 0.7194 -0.6923 +vn -0.0173 -0.7053 -0.7087 +vn -0.0170 -0.9999 0.0000 +vn 0.0643 -0.9979 0.0000 +vn 0.0431 -0.7042 -0.7087 +vn 0.0430 -0.7042 -0.7087 +vn 0.0026 0.0085 -1.0000 +vn 0.0066 0.0147 -0.9999 +vn -0.2460 -0.6563 -0.7133 +vn -0.4304 -0.5351 -0.7269 +vn -0.6261 -0.7797 -0.0000 +vn -0.3408 -0.9401 0.0000 +vn -0.5700 -0.4080 -0.7132 +vn -0.8157 -0.5784 -0.0000 +vn -0.6261 -0.7798 -0.0000 +vn -0.8157 -0.5785 0.0000 +vn -0.5700 -0.4081 0.7132 +vn -0.4304 -0.5351 0.7269 +vn 0.2130 0.9771 0.0000 +vn 0.2844 0.6748 0.6809 +vn 0.3919 0.9200 0.0001 +vn 0.2845 0.6748 -0.6810 +vn 0.1528 0.7106 -0.6868 +vn -0.1099 -0.7005 -0.7051 +vn -0.1446 -0.9895 0.0000 +vn -0.1099 -0.7005 0.7051 +vn 0.1529 0.7106 -0.6868 +vn 0.0077 0.0154 -0.9999 +vn 0.2844 0.6748 -0.6810 +vn 0.0114 0.0259 -0.9996 +vn 0.5763 0.4373 -0.6903 +vn 0.6378 0.3327 -0.6946 +vn 0.0143 0.0077 -0.9999 +vn 0.0149 0.0137 -0.9998 +vn 0.6704 0.2500 -0.6986 +vn 0.0104 0.0035 -0.9999 +vn -0.6599 -0.2428 -0.7110 +vn -0.6252 -0.3165 -0.7134 +vn -0.5700 -0.4080 -0.7131 +vn 0.4562 0.5731 -0.6807 +vn 0.0231 0.0316 -0.9992 +vn 0.0222 0.0313 0.9993 +vn -0.5700 -0.4080 0.7131 +vn 0.0150 0.0136 0.9998 +vn 0.5763 0.4373 0.6904 +vn 0.4563 0.5731 0.6807 +vn 0.6237 0.7816 -0.0000 +vn 0.5763 0.4373 0.6903 +vn 0.7954 0.6061 -0.0000 +vn 0.4563 0.5731 -0.6807 +vn 0.6704 0.2501 0.6986 +vn 0.6840 0.2014 0.7012 +vn 0.9593 0.2824 0.0001 +vn 0.9366 0.3505 -0.0002 +vn 0.6951 0.1749 0.6973 +vn 0.9702 0.2424 0.0001 +vn 0.6951 0.1748 -0.6973 +vn 0.6840 0.2013 -0.7012 +vn 0.6704 0.2501 -0.6986 +vn -0.6252 -0.3165 0.7134 +vn 0.0142 0.0076 0.9999 +vn -0.6599 -0.2428 0.7110 +vn 0.0100 0.0033 0.9999 +vn 0.6705 0.2500 0.6985 +vn 0.6378 0.3327 0.6946 +vn 0.8859 0.4639 0.0000 +vn -0.8932 -0.4496 0.0002 +vn -0.6599 -0.2429 -0.7110 +vn -0.9389 -0.3443 0.0003 +vn -0.5700 -0.4080 0.7132 +vn 0.7175 0.1285 -0.6846 +vn 0.0082 -0.0005 -1.0000 +vn 0.0029 -0.0006 -1.0000 +vn 0.7418 -0.0221 -0.6702 +vn 0.0339 0.0023 -0.9994 +vn -0.7098 -0.0359 -0.7034 +vn -0.7029 -0.1574 -0.6937 +vn -0.6892 -0.1849 -0.7005 +vn -0.6786 -0.2015 -0.7063 +vn -0.9586 -0.2848 -0.0001 +vn -0.9654 -0.2608 -0.0001 +vn -0.6892 -0.1849 0.7005 +vn -0.6786 -0.2014 0.7063 +vn 0.0042 0.0009 -1.0000 +vn -0.6786 -0.2014 -0.7063 +vn -0.6786 -0.2015 0.7063 +vn 0.0045 0.0010 1.0000 +vn 0.0031 -0.0005 1.0000 +vn 0.6840 0.2013 0.7012 +vn -0.7098 -0.0359 0.7034 +vn -0.6214 0.2536 0.7413 +vn 0.0580 -0.0199 0.9981 +vn 0.0339 0.0023 0.9994 +vn -0.5003 0.4951 0.7104 +vn 0.0175 -0.0132 0.9998 +vn 0.5296 -0.4989 0.6860 +vn 0.6779 -0.3039 0.6694 +vn 0.7418 -0.0221 0.6702 +vn -0.7028 -0.1574 0.6937 +vn 0.0084 -0.0005 1.0000 +vn 0.7175 0.1285 0.6846 +vn 0.7176 0.1285 0.6845 +vn 0.9853 0.1709 0.0000 +vn 0.9991 -0.0428 0.0000 +vn -0.9744 -0.2247 -0.0000 +vn -0.9976 -0.0691 -0.0000 +vn -0.7098 -0.0359 0.7035 +vn 0.4257 -0.5856 0.6898 +vn 0.5880 -0.8089 -0.0003 +vn 0.7284 -0.6851 -0.0000 +vn 0.2894 -0.6658 0.6877 +vn 0.4001 -0.9165 -0.0000 +vn 0.2894 -0.6658 -0.6877 +vn 0.4257 -0.5856 -0.6898 +vn 0.5296 -0.4989 -0.6860 +vn 0.6779 -0.3039 0.6693 +vn 0.9093 -0.4162 0.0000 +vn 0.6779 -0.3039 -0.6694 +vn -0.6214 0.2536 -0.7413 +vn -0.9304 0.3665 -0.0000 +vn -0.5003 0.4951 -0.7103 +vn -0.7080 0.7063 -0.0000 +vn -0.7080 0.7062 -0.0000 +vn -0.5003 0.4951 0.7103 +vn 0.6779 -0.3039 -0.6693 +vn 0.0577 -0.0198 -0.9981 +vn 0.0175 -0.0132 -0.9998 +vn 0.1458 -0.7051 -0.6940 +vn 0.0044 -0.0162 -0.9999 +vn 0.0130 -0.0279 -0.9995 +vn 0.0802 -0.7069 -0.7028 +vn 0.0016 -0.0018 -1.0000 +vn -0.0678 0.7061 -0.7049 +vn -0.1210 0.6907 -0.7130 +vn -0.2631 0.6377 -0.7240 +vn -0.4070 0.5717 -0.7124 +vn -0.5791 0.8153 -0.0000 +vn -0.2630 0.6377 -0.7240 +vn -0.3780 0.9258 0.0000 +vn -0.2630 0.6377 0.7240 +vn -0.4070 0.5717 0.7124 +vn 0.0129 -0.0154 -0.9998 +vn -0.4070 0.5718 -0.7123 +vn -0.4070 0.5718 0.7124 +vn 0.0129 -0.0151 0.9998 +vn -0.2631 0.6377 0.7240 +vn 0.0130 -0.0278 0.9995 +vn 0.0802 -0.7069 0.7028 +vn 0.0689 -0.7049 0.7059 +vn 0.0978 -0.9952 -0.0002 +vn 0.1146 -0.9934 -0.0002 +vn 0.0689 -0.7050 -0.7059 +vn -0.1210 0.6907 0.7130 +vn 0.0044 -0.0162 0.9999 +vn -0.0678 0.7061 0.7049 +vn 0.0017 -0.0018 1.0000 +vn 0.0802 -0.7068 0.7028 +vn 0.1458 -0.7051 0.6940 +vn 0.2062 -0.9785 -0.0001 +vn -0.1211 0.6906 -0.7130 +vn -0.1673 0.9859 -0.0000 +vn -0.0937 0.9956 -0.0000 +vn -0.1211 0.6907 0.7130 +vn -0.4322 0.6188 0.6560 +vn -0.9955 -0.0951 -0.0000 +vn -0.3792 -0.0361 0.9246 +vn -0.4672 0.8841 -0.0001 +vn -0.3791 -0.0363 -0.9246 +vn -0.3073 -0.6894 -0.6560 +vn -0.2915 -0.9566 -0.0001 +vn -0.3073 -0.6894 0.6560 +vn -0.0657 0.7054 -0.7058 +vn -0.0921 0.9958 0.0002 +vn -0.0657 0.7054 0.7058 +vn 0.0003 -0.0002 -1.0000 +vn -0.0657 0.7053 0.7058 +vn 0.0003 0.0003 1.0000 +vn 0.0689 -0.7050 0.7059 +usemtl Scene_-_Root +s off +f 28222/27721/19686 28223/27722/19687 28224/27723/19688 +f 28223/27722/19689 28227/27724/19690 28224/27723/19688 +s 1 +f 27721/27725/19691 27722/27726/19692 27723/27727/19693 +f 27721/27725/19691 27723/27727/19693 27724/27728/19694 +f 27722/27726/19692 27725/27729/19695 27726/27730/19696 +f 27722/27726/19692 27726/27730/19696 27723/27727/19693 +f 27723/27727/19693 27726/27730/19696 27727/27731/19697 +f 27723/27727/19693 27727/27731/19697 27728/27732/19698 +f 27724/27728/19694 27723/27727/19693 27728/27732/19698 +f 27724/27728/19694 27728/27732/19698 27729/27733/19699 +f 27730/27734/19700 27731/27735/19701 27732/27736/19702 +f 27730/27734/19700 27732/27736/19702 27733/27737/19703 +f 27731/27735/19701 27734/27738/19704 27735/27739/19705 +f 27731/27735/19701 27735/27739/19705 27732/27736/19702 +f 27732/27736/19702 27735/27739/19705 27725/27729/19695 +f 27732/27736/19702 27725/27729/19695 27722/27726/19692 +f 27733/27737/19703 27732/27736/19702 27722/27726/19692 +f 27733/27737/19703 27722/27726/19692 27721/27725/19691 +f 27736/27740/19706 27737/27741/19707 27738/27742/19708 +f 27736/27740/19706 27738/27742/19708 27739/27743/19709 +f 27737/27741/19707 27740/27744/19710 27741/27745/19711 +f 27737/27741/19707 27741/27745/19711 27738/27742/19708 +f 27738/27742/19708 27741/27745/19711 27742/27746/19695 +f 27738/27742/19708 27742/27746/19695 27743/27747/19705 +f 27739/27743/19709 27738/27742/19708 27743/27747/19705 +f 27739/27743/19709 27743/27747/19705 27744/27748/19712 +f 27745/27749/19713 27746/27750/19714 27747/27751/19715 +f 27745/27749/19713 27747/27751/19715 27748/27752/19716 +f 27746/27750/19714 27749/27753/19717 27750/27754/19718 +f 27746/27750/19714 27750/27754/19718 27747/27751/19715 +f 27747/27751/19715 27750/27754/19718 27751/27755/19700 +f 27747/27751/19715 27751/27755/19700 27752/27756/19703 +f 27748/27752/19716 27747/27751/19715 27752/27756/19703 +f 27748/27752/19716 27752/27756/19703 27753/27757/19691 +f 27754/27758/19713 27755/27759/19719 27756/27760/19720 +f 27754/27758/19713 27756/27760/19720 27757/27761/19714 +f 27755/27759/19719 27758/27762/19710 27759/27763/19707 +f 27755/27759/19719 27759/27763/19707 27756/27760/19720 +f 27756/27760/19720 27759/27763/19707 27760/27764/19706 +f 27756/27760/19720 27760/27764/19706 27761/27765/19721 +f 27757/27761/19714 27756/27760/19720 27761/27765/19721 +f 27757/27761/19714 27761/27765/19721 27762/27766/19722 +f 27763/27767/19723 27764/27768/19724 27765/27769/19725 +f 27763/27767/19723 27765/27769/19725 27766/27770/19726 +f 27764/27768/19724 27767/27771/19727 27768/27772/19728 +f 27764/27768/19724 27768/27772/19728 27765/27769/19725 +f 27769/27773/19729 27770/27774/19730 27771/27775/19731 +f 27769/27773/19729 27771/27775/19731 27772/27776/19732 +f 27773/27777/19733 27769/27773/19729 27772/27776/19732 +f 27773/27777/19733 27772/27776/19732 27774/27778/19734 +f 27742/27746/19695 27741/27745/19711 27775/27779/19735 +f 27742/27746/19695 27775/27779/19735 27776/27780/19696 +f 27741/27745/19711 27740/27744/19710 27777/27781/19736 +f 27741/27745/19711 27777/27781/19736 27775/27779/19735 +f 27775/27779/19735 27777/27781/19736 27778/27782/19737 +f 27775/27779/19735 27778/27782/19737 27779/27783/19738 +f 27776/27780/19696 27775/27779/19735 27779/27783/19738 +f 27776/27780/19696 27779/27783/19738 27780/27784/19697 +f 27745/27749/19713 27748/27752/19716 27781/27785/19739 +f 27745/27749/19713 27781/27785/19739 27782/27786/19740 +f 27748/27752/19716 27753/27757/19691 27783/27787/19694 +f 27748/27752/19716 27783/27787/19694 27781/27785/19739 +f 27781/27785/19739 27783/27787/19694 27767/27771/19727 +f 27781/27785/19739 27767/27771/19727 27764/27768/19724 +f 27782/27786/19740 27781/27785/19739 27764/27768/19724 +f 27782/27786/19740 27764/27768/19724 27763/27767/19723 +f 27758/27762/19710 27755/27759/19719 27784/27788/19741 +f 27758/27762/19710 27784/27788/19741 27785/27789/19736 +f 27755/27759/19719 27754/27758/19713 27786/27790/19740 +f 27755/27759/19719 27786/27790/19740 27784/27788/19741 +f 27784/27788/19741 27786/27790/19740 27787/27791/19723 +f 27784/27788/19741 27787/27791/19723 27788/27792/19742 +f 27785/27789/19736 27784/27788/19741 27788/27792/19742 +f 27785/27789/19736 27788/27792/19742 27789/27793/19743 +f 27790/27794/19744 27791/27795/19745 27792/27796/19746 +f 27790/27794/19744 27792/27796/19746 27793/27797/19747 +f 27791/27795/19745 27794/27798/19734 27795/27799/19748 +f 27791/27795/19745 27795/27799/19748 27792/27796/19746 +f 27792/27796/19746 27795/27799/19748 27796/27800/19749 +f 27792/27796/19746 27796/27800/19749 27797/27801/19750 +f 27793/27797/19747 27792/27796/19746 27797/27801/19750 +f 27793/27797/19747 27797/27801/19750 27798/27802/19751 +f 27789/27793/19743 27788/27792/19742 27799/27803/19752 +f 27789/27793/19743 27799/27803/19752 27800/27804/19753 +f 27788/27792/19742 27787/27791/19723 27801/27805/19733 +f 27788/27792/19742 27801/27805/19733 27799/27803/19752 +f 27799/27803/19752 27801/27805/19733 27794/27798/19734 +f 27799/27803/19752 27794/27798/19734 27791/27795/19745 +f 27800/27804/19753 27799/27803/19752 27791/27795/19745 +f 27800/27804/19753 27791/27795/19745 27790/27794/19744 +f 27729/27733/19699 27728/27732/19698 27802/27806/19754 +f 27729/27733/19699 27802/27806/19754 27803/27807/19728 +f 27728/27732/19698 27727/27731/19697 27804/27808/19755 +f 27728/27732/19698 27804/27808/19755 27802/27806/19754 +f 27802/27806/19754 27804/27808/19755 27805/27809/19756 +f 27802/27806/19754 27805/27809/19756 27806/27810/19757 +f 27803/27807/19728 27802/27806/19754 27806/27810/19757 +f 27803/27807/19728 27806/27810/19757 27807/27811/19731 +f 27780/27784/19697 27779/27783/19738 27808/27812/19758 +f 27780/27784/19697 27808/27812/19758 27809/27813/19755 +f 27810/27814/19738 27811/27815/19743 27812/27816/19753 +f 27810/27814/19738 27812/27816/19753 27813/27817/19758 +f 27813/27817/19758 27812/27816/19753 27814/27818/19744 +f 27813/27817/19758 27814/27818/19744 27815/27819/19759 +f 27809/27813/19755 27808/27812/19758 27816/27820/19759 +f 27809/27813/19755 27816/27820/19759 27817/27821/19756 +f 27818/27822/19760 27819/27823/19761 27820/27824/19762 +f 27818/27822/19760 27820/27824/19762 27821/27825/19763 +f 27819/27823/19761 27822/27826/19764 27823/27827/19765 +f 27819/27823/19761 27823/27827/19765 27820/27824/19762 +f 27820/27824/19762 27823/27827/19765 27824/27828/19766 +f 27820/27824/19762 27824/27828/19766 27825/27829/19767 +f 27821/27825/19763 27820/27824/19762 27825/27829/19767 +f 27821/27825/19763 27825/27829/19767 27826/27830/19768 +f 27807/27811/19731 27806/27810/19757 27827/27831/19769 +f 27807/27811/19731 27827/27831/19769 27828/27832/19770 +f 27806/27810/19757 27805/27809/19756 27829/27833/19771 +f 27806/27810/19757 27829/27833/19771 27827/27831/19769 +f 27827/27831/19769 27829/27833/19771 27830/27834/19772 +f 27827/27831/19769 27830/27834/19772 27831/27835/19773 +f 27828/27832/19770 27827/27831/19769 27831/27835/19773 +f 27828/27832/19770 27831/27835/19773 27832/27836/19774 +f 27833/27837/19775 27815/27819/19759 27834/27838/19776 +f 27833/27837/19775 27834/27838/19776 27835/27839/19771 +f 27815/27819/19759 27814/27818/19744 27836/27840/19747 +f 27815/27819/19759 27836/27840/19747 27834/27838/19776 +f 27834/27838/19776 27836/27840/19747 27822/27826/19764 +f 27834/27838/19776 27822/27826/19764 27819/27823/19761 +f 27835/27839/19771 27834/27838/19776 27819/27823/19761 +f 27835/27839/19771 27819/27823/19761 27818/27822/19760 +f 27774/27778/19734 27772/27776/19732 27837/27841/19777 +f 27774/27778/19734 27837/27841/19777 27838/27842/19748 +f 27772/27776/19732 27771/27775/19731 27839/27843/19770 +f 27772/27776/19732 27839/27843/19770 27837/27841/19777 +f 27837/27841/19777 27839/27843/19770 27840/27844/19774 +f 27837/27841/19777 27840/27844/19774 27841/27845/19778 +f 27838/27842/19748 27837/27841/19777 27841/27845/19778 +f 27838/27842/19748 27841/27845/19778 27842/27846/19779 +f 27843/27847/19780 27844/27848/19781 27845/27849/19782 +f 27843/27847/19780 27845/27849/19782 27846/27850/19783 +f 27844/27848/19781 27847/27851/19784 27848/27852/19785 +f 27844/27848/19781 27848/27852/19785 27845/27849/19782 +f 27845/27849/19782 27848/27852/19785 27849/27853/19786 +f 27845/27849/19782 27849/27853/19786 27850/27854/19787 +f 27846/27850/19783 27845/27849/19782 27850/27854/19787 +f 27846/27850/19783 27850/27854/19787 27851/27855/19788 +f 27842/27846/19779 27841/27845/19778 27852/27856/19789 +f 27842/27846/19779 27852/27856/19789 27853/27857/19790 +f 27841/27845/19778 27840/27844/19774 27854/27858/19791 +f 27841/27845/19778 27854/27858/19791 27852/27856/19789 +f 27852/27856/19789 27854/27858/19791 27855/27859/19792 +f 27852/27856/19789 27855/27859/19792 27856/27860/19793 +f 27853/27857/19790 27852/27856/19789 27856/27860/19793 +f 27853/27857/19790 27856/27860/19793 27857/27861/19784 +f 27798/27802/19751 27797/27801/19750 27858/27862/19794 +f 27798/27802/19751 27858/27862/19794 27859/27863/19765 +f 27797/27801/19750 27796/27800/19749 27860/27864/19790 +f 27797/27801/19750 27860/27864/19790 27858/27862/19794 +f 27858/27862/19794 27860/27864/19790 27847/27851/19784 +f 27858/27862/19794 27847/27851/19784 27844/27848/19781 +f 27859/27863/19765 27858/27862/19794 27844/27848/19781 +f 27859/27863/19765 27844/27848/19781 27843/27847/19780 +f 27832/27836/19774 27831/27835/19773 27861/27865/19795 +f 27832/27836/19774 27861/27865/19795 27862/27866/19791 +f 27831/27835/19773 27830/27834/19772 27863/27867/19763 +f 27831/27835/19773 27863/27867/19763 27861/27865/19795 +f 27861/27865/19795 27863/27867/19763 27864/27868/19796 +f 27861/27865/19795 27864/27868/19796 27865/27869/19797 +f 27862/27866/19791 27861/27865/19795 27865/27869/19797 +f 27862/27866/19791 27865/27869/19797 27866/27870/19792 +f 27867/27871/19798 27868/27872/19799 27869/27873/19800 +f 27867/27871/19798 27869/27873/19800 27870/27874/19801 +f 27868/27872/19799 27871/27875/19802 27872/27876/19803 +f 27868/27872/19799 27872/27876/19803 27869/27873/19800 +f 27869/27873/19800 27872/27876/19803 27873/27877/19804 +f 27869/27873/19800 27873/27877/19804 27874/27878/19805 +f 27870/27874/19801 27869/27873/19800 27874/27878/19805 +f 27870/27874/19801 27874/27878/19805 27875/27879/19806 +f 27866/27870/19792 27865/27869/19797 27876/27880/19807 +f 27866/27870/19792 27876/27880/19807 27877/27881/19808 +f 27865/27869/19797 27864/27868/19796 27878/27882/19809 +f 27865/27869/19797 27878/27882/19809 27876/27880/19807 +f 27876/27880/19807 27878/27882/19809 27871/27875/19802 +f 27876/27880/19807 27871/27875/19802 27868/27872/19799 +f 27877/27881/19808 27876/27880/19807 27868/27872/19799 +f 27877/27881/19808 27868/27872/19799 27867/27871/19798 +f 27826/27830/19768 27825/27829/19767 27879/27883/19810 +f 27826/27830/19768 27879/27883/19810 27880/27884/19811 +f 27825/27829/19767 27824/27828/19766 27881/27885/19812 +f 27825/27829/19767 27881/27885/19812 27879/27883/19810 +f 27879/27883/19810 27881/27885/19812 27882/27886/19788 +f 27879/27883/19810 27882/27886/19788 27883/27887/19813 +f 27880/27884/19811 27879/27883/19810 27883/27887/19813 +f 27880/27884/19811 27883/27887/19813 27884/27888/19802 +f 27857/27861/19784 27856/27860/19793 27885/27889/19814 +f 27857/27861/19784 27885/27889/19814 27886/27890/19815 +f 27856/27860/19793 27855/27859/19792 27887/27891/19808 +f 27856/27860/19793 27887/27891/19808 27885/27889/19814 +f 27885/27889/19814 27887/27891/19808 27888/27892/19798 +f 27885/27889/19814 27888/27892/19798 27889/27893/19816 +f 27886/27890/19815 27885/27889/19814 27889/27893/19816 +f 27886/27890/19815 27889/27893/19816 27890/27894/19786 +f 27891/27895/19804 27892/27896/19817 27893/27897/19818 +f 27891/27895/19804 27893/27897/19818 27894/27898/19819 +f 27892/27896/19817 27895/27899/19820 27896/27900/19821 +f 27892/27896/19817 27896/27900/19821 27893/27897/19818 +f 27893/27897/19818 27896/27900/19821 27897/27901/19822 +f 27893/27897/19818 27897/27901/19822 27898/27902/19823 +f 27894/27898/19819 27893/27897/19818 27898/27902/19823 +f 27894/27898/19819 27898/27902/19823 27899/27903/19824 +f 27884/27888/19802 27883/27887/19813 27900/27904/19825 +f 27884/27888/19802 27900/27904/19825 27901/27905/19826 +f 27883/27887/19813 27882/27886/19788 27902/27906/19827 +f 27883/27887/19813 27902/27906/19827 27900/27904/19825 +f 27900/27904/19825 27902/27906/19827 27903/27907/19820 +f 27900/27904/19825 27903/27907/19820 27904/27908/19817 +f 27905/27909/19826 27906/27910/19828 27892/27896/19817 +f 27905/27909/19826 27892/27896/19817 27891/27895/19804 +f 27890/27894/19786 27889/27893/19816 27907/27911/19829 +f 27890/27894/19786 27907/27911/19829 27908/27912/19830 +f 27889/27893/19816 27888/27892/19798 27909/27913/19801 +f 27889/27893/19816 27909/27913/19801 27907/27911/19829 +f 27907/27911/19829 27909/27913/19801 27910/27914/19831 +f 27907/27911/19829 27910/27914/19831 27911/27915/19832 +f 27912/27916/19833 27913/27917/19834 27914/27918/19835 +f 27912/27916/19833 27914/27918/19835 27915/27919/19836 +f 27851/27855/19788 27850/27854/19787 27916/27920/19837 +f 27851/27855/19788 27916/27920/19837 27917/27921/19827 +f 27850/27854/19787 27849/27853/19786 27912/27916/19833 +f 27850/27854/19787 27912/27916/19833 27916/27920/19837 +f 27916/27920/19837 27912/27916/19833 27915/27919/19836 +f 27916/27920/19837 27915/27919/19836 27918/27922/19838 +f 27917/27921/19827 27916/27920/19837 27918/27922/19838 +f 27917/27921/19827 27918/27922/19838 27919/27923/19820 +f 27920/27924/19822 27921/27925/19839 27922/27926/19840 +f 27920/27924/19822 27922/27926/19840 27923/27927/19841 +f 27921/27925/19839 27924/27928/19842 27925/27929/19843 +f 27921/27925/19839 27925/27929/19843 27922/27926/19840 +f 27922/27926/19840 27925/27929/19843 27926/27930/19844 +f 27922/27926/19840 27926/27930/19844 27927/27931/19845 +f 27923/27927/19841 27922/27926/19840 27927/27931/19845 +f 27923/27927/19841 27927/27931/19845 27928/27932/19846 +f 27929/27933/19847 27930/27934/19848 27931/27935/19849 +f 27929/27933/19847 27931/27935/19849 27932/27936/19850 +f 27930/27934/19848 27933/27937/19851 27934/27938/19852 +f 27930/27934/19848 27934/27938/19852 27931/27935/19849 +f 27931/27935/19849 27934/27938/19852 27935/27939/19853 +f 27931/27935/19849 27935/27939/19853 27936/27940/19854 +f 27932/27936/19850 27931/27935/19849 27936/27940/19854 +f 27932/27936/19850 27936/27940/19854 27937/27941/19855 +f 27919/27923/19820 27918/27922/19838 27938/27942/19856 +f 27919/27923/19820 27938/27942/19856 27939/27943/19821 +f 27918/27922/19838 27915/27919/19836 27940/27944/19857 +f 27918/27922/19838 27940/27944/19857 27938/27942/19856 +f 27938/27942/19856 27940/27944/19857 27924/27928/19842 +f 27938/27942/19856 27924/27928/19842 27921/27925/19839 +f 27939/27943/19821 27938/27942/19856 27921/27925/19839 +f 27939/27943/19821 27921/27925/19839 27920/27924/19822 +f 27875/27879/19806 27874/27878/19805 27941/27945/19858 +f 27875/27879/19806 27941/27945/19858 27942/27946/19852 +f 27874/27878/19805 27873/27877/19804 27943/27947/19819 +f 27874/27878/19805 27943/27947/19819 27941/27945/19858 +f 27941/27945/19858 27943/27947/19819 27944/27948/19824 +f 27941/27945/19858 27944/27948/19824 27945/27949/19859 +f 27942/27946/19852 27941/27945/19858 27945/27949/19859 +f 27942/27946/19852 27945/27949/19859 27946/27950/19860 +f 27947/27951/19861 27948/27952/19862 27949/27953/19863 +f 27947/27951/19861 27949/27953/19863 27950/27954/19864 +f 27948/27952/19862 27951/27955/19846 27952/27956/19865 +f 27948/27952/19862 27952/27956/19865 27949/27953/19863 +f 27949/27953/19863 27952/27956/19865 27953/27957/19866 +f 27949/27953/19863 27953/27957/19866 27954/27958/19867 +f 27950/27954/19864 27949/27953/19863 27954/27958/19867 +f 27950/27954/19864 27954/27958/19867 27955/27959/19868 +f 27946/27950/19860 27945/27949/19859 27956/27960/19869 +f 27946/27950/19860 27956/27960/19869 27957/27961/19870 +f 27945/27949/19859 27944/27948/19824 27958/27962/19871 +f 27945/27949/19859 27958/27962/19871 27956/27960/19869 +f 27956/27960/19869 27958/27962/19871 27959/27963/19861 +f 27956/27960/19869 27959/27963/19861 27960/27964/19872 +f 27957/27961/19870 27956/27960/19869 27960/27964/19872 +f 27957/27961/19870 27960/27964/19872 27961/27965/19873 +f 27899/27903/19824 27898/27902/19823 27962/27966/19874 +f 27899/27903/19824 27962/27966/19874 27963/27967/19875 +f 27898/27902/19823 27897/27901/19822 27964/27968/19876 +f 27898/27902/19823 27964/27968/19876 27962/27966/19874 +f 27962/27966/19874 27964/27968/19876 27951/27955/19846 +f 27962/27966/19874 27951/27955/19846 27948/27952/19862 +f 27963/27967/19875 27962/27966/19874 27948/27952/19862 +f 27963/27967/19875 27948/27952/19862 27947/27951/19861 +f 27937/27941/19855 27936/27940/19854 27965/27969/19877 +f 27937/27941/19855 27965/27969/19877 27966/27970/19878 +f 27936/27940/19854 27935/27939/19853 27967/27971/19879 +f 27936/27940/19854 27967/27971/19879 27965/27969/19877 +f 27965/27969/19877 27967/27971/19879 27968/27972/19873 +f 27965/27969/19877 27968/27972/19873 27969/27973/19880 +f 27966/27970/19878 27965/27969/19877 27969/27973/19880 +f 27966/27970/19878 27969/27973/19880 27970/27974/19844 +f 27970/27974/19844 27969/27973/19880 27971/27975/19881 +f 27970/27974/19844 27971/27975/19881 27972/27976/19882 +f 27969/27973/19880 27968/27972/19873 27973/27977/19883 +f 27969/27973/19880 27973/27977/19883 27971/27975/19881 +f 27971/27975/19881 27973/27977/19883 27974/27978/19686 +f 27971/27975/19881 27974/27978/19686 27975/27979/19884 +f 27972/27976/19882 27971/27975/19881 27975/27979/19884 +f 27972/27976/19882 27975/27979/19884 27976/27980/19885 +f 27928/27932/19846 27927/27931/19845 27977/27981/19886 +f 27928/27932/19846 27977/27981/19886 27978/27982/19865 +f 27927/27931/19845 27926/27930/19844 27979/27983/19882 +f 27927/27931/19845 27979/27983/19882 27977/27981/19886 +f 27977/27981/19886 27979/27983/19882 27980/27984/19887 +f 27977/27981/19886 27980/27984/19887 27981/27985/19888 +f 27978/27982/19865 27977/27981/19886 27981/27985/19888 +f 27978/27982/19865 27981/27985/19888 27982/27986/19866 +f 27961/27965/19873 27960/27964/19872 27983/27987/19889 +f 27961/27965/19873 27983/27987/19889 27984/27988/19890 +f 27960/27964/19872 27959/27963/19861 27985/27989/19864 +f 27960/27964/19872 27985/27989/19864 27983/27987/19889 +f 27983/27987/19889 27985/27989/19864 27986/27990/19891 +f 27983/27987/19889 27986/27990/19891 27987/27991/19892 +f 27984/27988/19890 27983/27987/19889 27987/27991/19892 +f 27984/27988/19890 27987/27991/19892 27988/27992/19686 +f 27989/27993/19893 27990/27994/19894 27991/27995/19895 +f 27989/27993/19893 27991/27995/19895 27992/27996/19896 +f 27990/27994/19894 27993/27997/19897 27994/27998/19898 +f 27990/27994/19894 27994/27998/19898 27991/27995/19895 +f 27991/27995/19895 27994/27998/19898 27995/27999/19899 +f 27991/27995/19895 27995/27999/19899 27996/28000/19900 +f 27992/27996/19896 27991/27995/19895 27996/28000/19900 +f 27992/27996/19896 27996/28000/19900 27997/28001/19901 +f 27730/27734/19700 27998/28002/19902 27999/28003/19903 +f 27730/27734/19700 27999/28003/19903 27731/27735/19701 +f 27998/28002/19902 27989/27993/19893 27992/27996/19896 +f 27998/28002/19902 27992/27996/19896 27999/28003/19903 +f 27999/28003/19903 27992/27996/19896 27997/28001/19901 +f 27999/28003/19903 27997/28001/19901 28000/28004/19904 +f 27731/27735/19701 27999/28003/19903 28000/28004/19904 +f 27731/27735/19701 28000/28004/19904 27734/27738/19704 +f 27736/27740/19706 27739/27743/19709 28001/28005/19905 +f 27736/27740/19706 28001/28005/19905 28002/28006/19906 +f 27739/27743/19709 27744/27748/19712 28003/28007/19904 +f 27739/27743/19709 28003/28007/19904 28001/28005/19905 +f 28001/28005/19905 28003/28007/19904 28004/28008/19901 +f 28001/28005/19905 28004/28008/19901 28005/28009/19907 +f 28002/28006/19906 28001/28005/19905 28005/28009/19907 +f 28002/28006/19906 28005/28009/19907 28006/28010/19908 +f 28007/28011/19909 28008/28012/19910 28009/28013/19911 +f 28007/28011/19909 28009/28013/19911 28010/28014/19912 +f 28008/28012/19910 28011/28015/19893 28012/28016/19902 +f 28008/28012/19910 28012/28016/19902 28009/28013/19911 +f 28009/28013/19911 28012/28016/19902 27751/27755/19700 +f 28009/28013/19911 27751/27755/19700 27750/27754/19718 +f 28010/28014/19912 28009/28013/19911 27750/27754/19718 +f 28010/28014/19912 27750/27754/19718 27749/27753/19717 +f 28013/28017/19909 28014/28018/19913 28015/28019/19914 +f 28013/28017/19909 28015/28019/19914 28016/28020/19915 +f 28014/28018/19913 27762/27766/19722 27761/27765/19721 +f 28014/28018/19913 27761/27765/19721 28015/28019/19914 +f 28015/28019/19914 27761/27765/19721 27760/27764/19706 +f 28015/28019/19914 27760/27764/19706 28017/28021/19906 +f 28016/28020/19915 28015/28019/19914 28017/28021/19906 +f 28016/28020/19915 28017/28021/19906 28018/28022/19908 +f 28019/28023/19916 28020/28024/19917 28021/28025/19918 +f 28019/28023/19916 28021/28025/19918 28022/28026/19919 +f 28023/28027/19917 28024/28028/19920 28025/28029/19921 +f 28023/28027/19917 28025/28029/19921 28026/28030/19922 +f 28021/28025/19918 28027/28031/19923 28028/28032/19924 +f 28021/28025/19918 28028/28032/19924 28029/28033/19925 +f 28022/28026/19919 28021/28025/19918 28029/28033/19925 +f 28022/28026/19919 28029/28033/19925 28030/28034/19897 +f 28004/28008/19901 28031/28035/19900 28032/28036/19926 +f 28004/28008/19901 28032/28036/19926 28005/28009/19907 +f 28031/28035/19900 28033/28037/19927 28034/28038/19928 +f 28031/28035/19900 28034/28038/19928 28032/28036/19926 +f 28032/28036/19926 28034/28038/19928 28035/28039/19929 +f 28032/28036/19926 28035/28039/19929 28036/28040/19930 +f 28005/28009/19907 28032/28036/19926 28036/28040/19930 +f 28005/28009/19907 28036/28040/19930 28006/28010/19908 +f 28007/28011/19909 28037/28041/19931 28038/28042/19932 +f 28007/28011/19909 28038/28042/19932 28008/28012/19910 +f 28037/28041/19931 28019/28023/19916 28022/28026/19919 +f 28037/28041/19931 28022/28026/19919 28038/28042/19932 +f 28038/28042/19932 28022/28026/19919 28030/28034/19897 +f 28038/28042/19932 28030/28034/19897 28039/28043/19933 +f 28008/28012/19910 28038/28042/19932 28039/28043/19933 +f 28008/28012/19910 28039/28043/19933 28011/28015/19893 +f 28018/28022/19908 28040/28044/19934 28041/28045/19935 +f 28018/28022/19908 28041/28045/19935 28016/28020/19915 +f 28040/28044/19934 28042/28046/19936 28043/28047/19937 +f 28040/28044/19934 28043/28047/19937 28041/28045/19935 +f 28041/28045/19935 28043/28047/19937 28044/28048/19916 +f 28041/28045/19935 28044/28048/19916 28045/28049/19931 +f 28016/28020/19915 28041/28045/19935 28045/28049/19931 +f 28016/28020/19915 28045/28049/19931 28013/28017/19909 +f 28046/28050/19938 28047/28051/19939 28048/28052/19940 +f 28046/28050/19938 28048/28052/19940 28049/28053/19941 +f 28047/28051/19939 28050/28054/19942 28051/28055/19943 +f 28047/28051/19939 28051/28055/19943 28048/28052/19940 +f 28048/28052/19940 28051/28055/19943 28052/28056/19944 +f 28048/28052/19940 28052/28056/19944 28053/28057/19945 +f 28049/28053/19941 28048/28052/19940 28053/28057/19945 +f 28049/28053/19941 28053/28057/19945 28054/28058/19946 +f 28042/28046/19936 28055/28059/19947 28056/28060/19948 +f 28042/28046/19936 28056/28060/19948 28043/28047/19937 +f 28055/28059/19947 28046/28050/19938 28049/28053/19941 +f 28055/28059/19947 28049/28053/19941 28056/28060/19948 +f 28056/28060/19948 28049/28053/19941 28054/28058/19946 +f 28056/28060/19948 28054/28058/19946 28057/28061/19917 +f 28043/28047/19937 28056/28060/19948 28057/28061/19917 +f 28043/28047/19937 28057/28061/19917 28044/28048/19916 +f 27993/27997/19897 28058/28062/19925 28059/28063/19949 +f 27993/27997/19897 28059/28063/19949 27994/27998/19898 +f 28058/28062/19925 28060/28064/19950 28061/28065/19951 +f 28058/28062/19925 28061/28065/19951 28059/28063/19949 +f 28059/28063/19949 28061/28065/19951 28062/28066/19952 +f 28059/28063/19949 28062/28066/19952 28063/28067/19953 +f 27994/27998/19898 28059/28063/19949 28063/28067/19953 +f 27994/27998/19898 28063/28067/19953 27995/27999/19899 +f 28033/28037/19927 28064/28068/19953 28065/28069/19954 +f 28033/28037/19927 28065/28069/19954 28034/28038/19928 +f 28066/28070/19953 28067/28071/19955 28068/28072/19956 +f 28066/28070/19953 28068/28072/19956 28069/28073/19954 +f 28069/28073/19954 28068/28072/19956 28070/28074/19938 +f 28069/28073/19954 28070/28074/19938 28071/28075/19957 +f 28034/28038/19928 28065/28069/19954 28072/28076/19947 +f 28034/28038/19928 28072/28076/19947 28035/28039/19929 +f 28073/28077/19958 28074/28078/19959 28075/28079/19960 +f 28073/28077/19958 28075/28079/19960 28076/28080/19961 +f 28074/28078/19959 28077/28081/19962 28078/28082/19963 +f 28074/28078/19959 28078/28082/19963 28075/28079/19960 +f 28075/28079/19960 28078/28082/19963 28079/28083/19964 +f 28075/28079/19960 28079/28083/19964 28080/28084/19965 +f 28076/28080/19961 28075/28079/19960 28080/28084/19965 +f 28076/28080/19961 28080/28084/19965 28081/28085/19966 +f 28060/28064/19950 28082/28086/19967 28083/28087/19968 +f 28060/28064/19950 28083/28087/19968 28061/28065/19951 +f 28082/28086/19967 28084/28088/19969 28085/28089/19970 +f 28082/28086/19967 28085/28089/19970 28083/28087/19968 +f 28083/28087/19968 28085/28089/19970 28086/28090/19971 +f 28083/28087/19968 28086/28090/19971 28087/28091/19972 +f 28061/28065/19951 28083/28087/19968 28087/28091/19972 +f 28061/28065/19951 28087/28091/19972 28062/28066/19952 +f 28067/28071/19955 28088/28092/19972 28089/28093/19973 +f 28067/28071/19955 28089/28093/19973 28068/28072/19956 +f 28088/28092/19972 28073/28077/19958 28076/28080/19961 +f 28088/28092/19972 28076/28080/19961 28089/28093/19973 +f 28089/28093/19973 28076/28080/19961 28081/28085/19966 +f 28089/28093/19973 28081/28085/19966 28090/28094/19939 +f 28068/28072/19956 28089/28093/19973 28090/28094/19939 +f 28068/28072/19956 28090/28094/19939 28070/28074/19938 +f 28024/28028/19920 28091/28095/19945 28092/28096/19974 +f 28024/28028/19920 28092/28096/19974 28025/28029/19921 +f 28091/28095/19945 28093/28097/19975 28094/28098/19976 +f 28091/28095/19945 28094/28098/19976 28092/28096/19974 +f 28092/28096/19974 28094/28098/19976 28095/28099/19969 +f 28092/28096/19974 28095/28099/19969 28096/28100/19967 +f 28025/28029/19921 28092/28096/19974 28096/28100/19967 +f 28025/28029/19921 28096/28100/19967 28097/28101/19977 +f 28098/28102/19964 28099/28103/19978 28100/28104/19979 +f 28098/28102/19964 28100/28104/19979 28101/28105/19980 +f 28099/28103/19978 28102/28106/19981 28103/28107/19982 +f 28099/28103/19978 28103/28107/19982 28100/28104/19979 +f 28100/28104/19979 28103/28107/19982 28104/28108/19983 +f 28100/28104/19979 28104/28108/19983 28105/28109/19984 +f 28101/28105/19980 28100/28104/19979 28105/28109/19984 +f 28101/28105/19980 28105/28109/19984 28106/28110/19985 +f 28093/28097/19975 28107/28111/19986 28108/28112/19987 +f 28093/28097/19975 28108/28112/19987 28094/28098/19976 +f 28107/28111/19986 28109/28113/19985 28110/28114/19988 +f 28107/28111/19986 28110/28114/19988 28108/28112/19987 +f 28108/28112/19987 28110/28114/19988 28111/28115/19989 +f 28108/28112/19987 28111/28115/19989 28112/28116/19990 +f 28094/28098/19976 28108/28112/19987 28112/28116/19990 +f 28094/28098/19976 28112/28116/19990 28095/28099/19969 +f 28050/28054/19942 28113/28117/19965 28114/28118/19991 +f 28050/28054/19942 28114/28118/19991 28051/28055/19943 +f 28113/28117/19965 28098/28102/19964 28101/28105/19980 +f 28113/28117/19965 28101/28105/19980 28114/28118/19991 +f 28114/28118/19991 28101/28105/19980 28106/28110/19985 +f 28114/28118/19991 28106/28110/19985 28115/28119/19992 +f 28051/28055/19943 28114/28118/19991 28115/28119/19992 +f 28051/28055/19943 28115/28119/19992 28052/28056/19944 +f 28084/28088/19969 28116/28120/19993 28117/28121/19994 +f 28084/28088/19969 28117/28121/19994 28085/28089/19970 +f 28116/28120/19993 28118/28122/19989 28119/28123/19995 +f 28116/28120/19993 28119/28123/19995 28117/28121/19994 +f 28117/28121/19994 28119/28123/19995 28120/28124/19962 +f 28117/28121/19994 28120/28124/19962 28121/28125/19996 +f 28085/28089/19970 28117/28121/19994 28121/28125/19996 +f 28085/28089/19970 28121/28125/19996 28086/28090/19971 +f 28122/28126/19997 28123/28127/19998 28124/28128/19999 +f 28122/28126/19997 28124/28128/19999 28125/28129/20000 +f 28123/28127/19998 28126/28130/20001 28127/28131/20002 +f 28123/28127/19998 28127/28131/20002 28124/28128/19999 +f 28124/28128/19999 28127/28131/20002 28128/28132/20003 +f 28124/28128/19999 28128/28132/20003 28129/28133/20004 +f 28125/28129/20000 28124/28128/19999 28129/28133/20004 +f 28125/28129/20000 28129/28133/20004 28130/28134/20005 +f 28118/28122/19989 28131/28135/20006 28132/28136/20007 +f 28118/28122/19989 28132/28136/20007 28119/28123/19995 +f 28131/28135/20006 28122/28126/19997 28125/28129/20000 +f 28131/28135/20006 28125/28129/20000 28132/28136/20007 +f 28132/28136/20007 28125/28129/20000 28130/28134/20005 +f 28132/28136/20007 28130/28134/20005 28133/28137/20008 +f 28119/28123/19995 28132/28136/20007 28133/28137/20008 +f 28119/28123/19995 28133/28137/20008 28120/28124/19962 +f 28077/28081/19962 28134/28138/20009 28135/28139/20010 +f 28077/28081/19962 28135/28139/20010 28078/28082/19963 +f 28134/28138/20009 28136/28140/20005 28137/28141/20011 +f 28134/28138/20009 28137/28141/20011 28135/28139/20010 +f 28135/28139/20010 28137/28141/20011 28138/28142/19981 +f 28135/28139/20010 28138/28142/19981 28139/28143/19978 +f 28078/28082/19963 28135/28139/20010 28139/28143/19978 +f 28078/28082/19963 28139/28143/19978 28079/28083/19964 +f 28109/28113/19985 28140/28144/19984 28141/28145/20012 +f 28109/28113/19985 28141/28145/20012 28110/28114/19988 +f 28140/28144/19984 28142/28146/19983 28143/28147/20013 +f 28140/28144/19984 28143/28147/20013 28141/28145/20012 +f 28141/28145/20012 28143/28147/20013 28144/28148/20014 +f 28141/28145/20012 28144/28148/20014 28145/28149/20006 +f 28110/28114/19988 28141/28145/20012 28145/28149/20006 +f 28110/28114/19988 28145/28149/20006 28111/28115/19989 +f 28146/28150/20003 28147/28151/20015 28148/28152/20016 +f 28146/28150/20003 28148/28152/20016 28149/28153/20017 +f 28147/28151/20015 28150/28154/20018 28151/28155/20019 +f 28147/28151/20015 28151/28155/20019 28148/28152/20016 +f 28148/28152/20016 28151/28155/20019 28152/28156/20020 +f 28148/28152/20016 28152/28156/20020 28153/28157/20021 +f 28149/28153/20017 28148/28152/20016 28153/28157/20021 +f 28149/28153/20017 28153/28157/20021 28154/28158/20022 +f 28136/28140/20005 28155/28159/20023 28156/28160/20024 +f 28136/28140/20005 28156/28160/20024 28137/28141/20011 +f 28155/28159/20023 28157/28161/20003 28158/28162/20017 +f 28155/28159/20023 28158/28162/20017 28156/28160/20024 +f 28156/28160/20024 28158/28162/20017 28159/28163/20022 +f 28156/28160/20024 28159/28163/20022 28160/28164/20025 +f 28137/28141/20011 28156/28160/20024 28160/28164/20025 +f 28137/28141/20011 28160/28164/20025 28138/28142/19981 +f 28142/28146/19983 28161/28165/20026 28162/28166/20027 +f 28142/28146/19983 28162/28166/20027 28143/28147/20013 +f 28161/28165/20026 28163/28167/20028 28164/28168/20029 +f 28161/28165/20026 28164/28168/20029 28162/28166/20027 +f 28165/28169/20027 28166/28170/20030 28167/28171/20031 +f 28165/28169/20027 28167/28171/20031 28168/28172/19998 +f 28143/28147/20013 28162/28166/20027 28169/28173/19998 +f 28143/28147/20013 28169/28173/19998 28144/28148/20014 +f 28102/28106/19981 28170/28174/20032 28171/28175/20033 +f 28102/28106/19981 28171/28175/20033 28103/28107/19982 +f 28170/28174/20032 28172/28176/20022 28173/28177/20034 +f 28170/28174/20032 28173/28177/20034 28171/28175/20033 +f 28171/28175/20033 28173/28177/20034 28174/28178/20028 +f 28171/28175/20033 28174/28178/20028 28175/28179/20026 +f 28103/28107/19982 28171/28175/20033 28175/28179/20026 +f 28103/28107/19982 28175/28179/20026 28104/28108/19983 +f 28176/28180/20020 28177/28181/20035 28178/28182/20036 +f 28176/28180/20020 28178/28182/20036 28179/28183/20037 +f 28177/28181/20035 28180/28184/20038 28181/28185/20039 +f 28177/28181/20035 28181/28185/20039 28178/28182/20036 +f 28178/28182/20036 28181/28185/20039 28182/28186/20040 +f 28178/28182/20036 28182/28186/20040 28183/28187/20041 +f 28179/28183/20037 28178/28182/20036 28183/28187/20041 +f 28179/28183/20037 28183/28187/20041 28184/28188/20042 +f 28185/28189/20028 28186/28190/20043 28187/28191/20044 +f 28185/28189/20028 28187/28191/20044 28166/28170/20030 +f 28186/28190/20043 28188/28192/20045 28189/28193/20046 +f 28186/28190/20043 28189/28193/20046 28187/28191/20044 +f 28187/28191/20044 28189/28193/20046 28190/28194/20047 +f 28187/28191/20044 28190/28194/20047 28191/28195/20048 +f 28166/28170/20030 28187/28191/20044 28191/28195/20048 +f 28166/28170/20030 28191/28195/20048 28167/28171/20031 +f 28172/28176/20022 28192/28196/20021 28193/28197/20049 +f 28172/28176/20022 28193/28197/20049 28173/28177/20034 +f 28192/28196/20021 28176/28180/20020 28179/28183/20037 +f 28192/28196/20021 28179/28183/20037 28193/28197/20049 +f 28193/28197/20049 28179/28183/20037 28184/28188/20042 +f 28193/28197/20049 28184/28188/20042 28194/28198/20050 +f 28173/28177/20034 28193/28197/20049 28194/28198/20050 +f 28173/28177/20034 28194/28198/20050 28174/28178/20028 +f 28126/28130/20001 28195/28199/20051 28196/28200/20052 +f 28126/28130/20001 28196/28200/20052 28127/28131/20002 +f 28195/28199/20051 28197/28201/20053 28198/28202/20054 +f 28195/28199/20051 28198/28202/20054 28196/28200/20052 +f 28196/28200/20052 28198/28202/20054 28199/28203/20018 +f 28196/28200/20052 28199/28203/20018 28200/28204/20015 +f 28127/28131/20002 28196/28200/20052 28200/28204/20015 +f 28127/28131/20002 28200/28204/20015 28128/28132/20003 +f 28201/28205/20055 28202/28206/20056 28203/28207/20057 +f 28201/28205/20055 28203/28207/20057 28204/28208/20058 +f 28202/28206/20056 27955/27959/19868 27954/27958/19867 +f 28202/28206/20056 27954/27958/19867 28203/28207/20057 +f 28203/28207/20057 27954/27958/19867 27953/27957/19866 +f 28203/28207/20057 27953/27957/19866 28205/28209/20059 +f 28204/28208/20058 28203/28207/20057 28205/28209/20059 +f 28204/28208/20058 28205/28209/20059 28206/28210/20038 +f 28197/28201/20053 28207/28211/20060 28208/28212/20061 +f 28197/28201/20053 28208/28212/20061 28198/28202/20054 +f 28207/28211/20060 28209/28213/20062 28210/28214/20063 +f 28207/28211/20060 28210/28214/20063 28208/28212/20061 +f 28208/28212/20061 28210/28214/20063 28211/28215/20064 +f 28208/28212/20061 28211/28215/20064 28212/28216/20065 +f 28198/28202/20054 28208/28212/20061 28212/28216/20065 +f 28198/28202/20054 28212/28216/20065 28199/28203/20018 +f 28150/28154/20018 28213/28217/20065 28214/28218/20066 +f 28150/28154/20018 28214/28218/20066 28151/28155/20019 +f 28213/28217/20065 28201/28205/20055 28204/28208/20058 +f 28213/28217/20065 28204/28208/20058 28214/28218/20066 +f 28214/28218/20066 28204/28208/20058 28206/28210/20038 +f 28214/28218/20066 28206/28210/20038 28215/28219/20035 +f 28151/28155/20019 28214/28218/20066 28215/28219/20035 +f 28151/28155/20019 28215/28219/20035 28152/28156/20020 +f 28188/28192/20045 28216/28220/20067 28217/28221/20068 +f 28188/28192/20045 28217/28221/20068 28189/28193/20046 +f 28216/28220/20067 28218/28222/20040 28219/28223/20069 +f 28216/28220/20067 28219/28223/20069 28217/28221/20068 +f 28217/28221/20068 28219/28223/20069 28220/28224/20062 +f 28217/28221/20068 28220/28224/20062 28221/28225/20070 +f 28189/28193/20046 28217/28221/20068 28221/28225/20070 +f 28189/28193/20046 28221/28225/20070 28190/28194/20047 +f 28222/27721/20071 28224/27723/20072 28225/28226/20073 +f 28223/27722/20074 28226/28227/19887 28227/27724/19888 +f 28224/27723/20072 28227/27724/20075 28228/28228/20076 +f 28224/27723/20072 28228/28228/20076 28229/28229/20077 +f 28225/28226/20073 28224/27723/20072 28229/28229/20077 +f 28225/28226/20073 28229/28229/20077 28230/28230/20078 +f 28218/28222/20040 28231/28231/20079 28232/28232/20080 +f 28218/28222/20040 28232/28232/20080 28219/28223/20069 +f 28231/28231/20079 27976/27980/19885 27975/27979/19884 +f 28231/28231/20079 27975/27979/19884 28232/28232/20080 +f 28232/28232/20080 27975/27979/19884 27974/27978/19686 +f 28232/28232/20080 27974/27978/19686 28233/28233/20081 +f 28219/28223/20069 28232/28232/20080 28233/28233/20081 +f 28219/28223/20069 28233/28233/20081 28220/28224/20062 +f 28180/28184/20038 28234/28234/20059 28235/28235/20082 +f 28180/28184/20038 28235/28235/20082 28181/28185/20039 +f 28234/28234/20059 27982/27986/19866 27981/27985/19888 +f 28234/28234/20059 27981/27985/19888 28235/28235/20082 +f 28235/28235/20082 27981/27985/19888 27980/27984/19887 +f 28235/28235/20082 27980/27984/19887 28236/28236/20079 +f 28181/28185/20039 28235/28235/20082 28236/28236/20079 +f 28181/28185/20039 28236/28236/20079 28182/28186/20040 +f 28209/28213/20062 28237/28237/20083 28238/28238/20084 +f 28209/28213/20062 28238/28238/20084 28210/28214/20063 +f 28237/28237/20083 27988/27992/19686 27987/27991/19892 +f 28237/28237/20083 27987/27991/19892 28238/28238/20084 +f 28238/28238/20084 27987/27991/19892 27986/27990/19891 +f 28238/28238/20084 27986/27990/19891 28239/28239/20085 +f 28210/28214/20063 28238/28238/20084 28239/28239/20085 +f 28210/28214/20063 28239/28239/20085 28211/28215/20064 +o Cube.045__0 +v -0.248012 1.177792 -0.927617 +v -0.244442 1.237960 -0.937002 +v -0.242174 1.236107 -0.942701 +v -0.245687 1.177170 -0.931296 +v -0.236486 1.293761 -0.949372 +v -0.234297 1.290274 -0.955690 +v -0.242174 1.236107 -0.942701 +v -0.234297 1.290274 -0.955690 +v -0.217413 1.284984 -0.959055 +v -0.224815 1.233065 -0.946549 +v -0.245687 1.177170 -0.931296 +v -0.228056 1.176593 -0.934029 +v -0.228056 1.176593 -0.934029 +v -0.224815 1.233065 -0.946549 +v -0.184820 1.228451 -0.946847 +v -0.187470 1.176168 -0.934860 +v -0.217413 1.284984 -0.959055 +v -0.178482 1.277399 -0.957092 +v -0.139503 1.272264 -0.949731 +v -0.144823 1.225117 -0.942497 +v -0.146921 1.176233 -0.932786 +v -0.146921 1.176233 -0.932786 +v -0.144823 1.225117 -0.942497 +v -0.129921 1.225818 -0.933784 +v -0.131886 1.177006 -0.927615 +v -0.139503 1.272264 -0.949731 +v -0.124897 1.274062 -0.938678 +v -0.129921 1.225818 -0.933784 +v -0.124897 1.274062 -0.938678 +v -0.139401 1.280999 -0.930414 +v -0.144894 1.229687 -0.925911 +v -0.131886 1.177006 -0.927615 +v -0.147145 1.177984 -0.922444 +v -0.147145 1.177984 -0.922444 +v -0.144894 1.229687 -0.925911 +v -0.184563 1.234800 -0.923800 +v -0.187379 1.178596 -0.920372 +v -0.139401 1.280999 -0.930414 +v -0.178049 1.289568 -0.930493 +v -0.216744 1.295687 -0.935969 +v -0.224236 1.238632 -0.926336 +v -0.227576 1.178717 -0.921206 +v -0.178482 1.277399 -0.957092 +v -0.165714 1.319337 -0.965111 +v -0.128714 1.315029 -0.953598 +v -0.217413 1.284984 -0.959055 +v -0.202613 1.327814 -0.972084 +v -0.180869 1.357082 -0.988371 +v -0.147574 1.349217 -0.975456 +v -0.114114 1.347132 -0.959554 +v -0.113549 1.367746 -0.948618 +v -0.101343 1.355137 -0.948696 +v -0.086540 1.373990 -0.961754 +v -0.096508 1.387588 -0.965351 +v -0.101343 1.355137 -0.948696 +v -0.114114 1.347132 -0.959554 +v -0.097354 1.364034 -0.972399 +v -0.086540 1.373990 -0.961754 +v -0.076180 1.371768 -0.987947 +v -0.068076 1.381555 -0.976357 +v -0.068076 1.381555 -0.976357 +v -0.075084 1.395470 -0.981359 +v -0.114743 1.319740 -0.942164 +v -0.128402 1.329888 -0.937233 +v -0.128714 1.315029 -0.953598 +v -0.114743 1.319740 -0.942164 +v -0.114114 1.347132 -0.959554 +v -0.101343 1.355137 -0.948696 +v -0.101343 1.355137 -0.948696 +v -0.113549 1.367746 -0.948618 +v -0.236486 1.293761 -0.949372 +v -0.233823 1.296392 -0.942589 +v -0.218111 1.345356 -0.961331 +v -0.220658 1.340578 -0.967090 +v -0.233823 1.296392 -0.942589 +v -0.216744 1.295687 -0.935969 +v -0.201864 1.346094 -0.953426 +v -0.218111 1.345356 -0.961331 +v -0.180003 1.382353 -0.977300 +v -0.194744 1.379628 -0.986154 +v -0.194744 1.379628 -0.986154 +v -0.197088 1.372787 -0.990023 +v -0.178049 1.289568 -0.930493 +v -0.165083 1.340075 -0.943059 +v -0.201864 1.346094 -0.953426 +v -0.128402 1.329888 -0.937233 +v -0.113549 1.367746 -0.948618 +v -0.146694 1.377940 -0.961465 +v -0.180003 1.382353 -0.977300 +v -0.115279 1.409072 -1.026677 +v -0.095028 1.405592 -1.003156 +v -0.057651 1.412999 -1.013337 +v -0.068789 1.420685 -1.038830 +v -0.075084 1.395470 -0.981359 +v -0.046863 1.399149 -0.990529 +v -0.012385 1.400117 -0.993441 +v -0.013564 1.418023 -1.015546 +v -0.015099 1.430321 -1.041558 +v -0.164164 1.395806 -1.013841 +v -0.166201 1.387951 -1.016345 +v -0.151816 1.399830 -1.004092 +v -0.164164 1.395806 -1.013841 +v -0.115279 1.409072 -1.026677 +v -0.124378 1.405283 -1.037609 +v -0.124378 1.405283 -1.037609 +v -0.126008 1.397383 -1.039957 +v -0.146694 1.377940 -0.961465 +v -0.124043 1.397007 -0.983787 +v -0.151816 1.399830 -1.004092 +v -0.113549 1.367746 -0.948618 +v -0.096508 1.387588 -0.965351 +v -0.114114 1.347132 -0.959554 +v -0.125235 1.364326 -0.991939 +v -0.097354 1.364034 -0.972399 +v -0.152878 1.371215 -1.009609 +v -0.116586 1.380189 -1.031115 +v -0.096536 1.372658 -1.010393 +v -0.076180 1.371768 -0.987947 +v -0.012385 1.400117 -0.993441 +v -0.012453 1.385115 -0.991666 +v 0.022703 1.382732 -0.991626 +v 0.026093 1.397815 -0.991755 +v -0.012453 1.385115 -0.991666 +v -0.013630 1.380311 -1.007834 +v 0.024981 1.379111 -1.008472 +v 0.022703 1.382732 -0.991626 +v 0.061436 1.372108 -1.002691 +v 0.055835 1.375199 -0.986282 +v 0.055835 1.375199 -0.986282 +v 0.062416 1.389720 -0.984752 +v -0.096536 1.372658 -1.010393 +v -0.059396 1.382123 -1.025282 +v -0.048104 1.377247 -1.000570 +v -0.116586 1.380189 -1.031115 +v -0.070340 1.393163 -1.047309 +v -0.016826 1.404491 -1.055417 +v -0.015406 1.389597 -1.033579 +v -0.013630 1.380311 -1.007834 +v -0.075084 1.395470 -0.981359 +v -0.068076 1.381555 -0.976357 +v -0.043343 1.384686 -0.986639 +v -0.046863 1.399149 -0.990529 +v -0.068076 1.381555 -0.976357 +v -0.076180 1.371768 -0.987947 +v -0.048104 1.377247 -1.000570 +v -0.043343 1.384686 -0.986639 +v -0.126008 1.397383 -1.039957 +v -0.124378 1.405283 -1.037609 +v -0.073949 1.418945 -1.051360 +v -0.075084 1.411606 -1.054949 +v -0.124378 1.405283 -1.037609 +v -0.115279 1.409072 -1.026677 +v -0.068789 1.420685 -1.038830 +v -0.073949 1.418945 -1.051360 +v -0.015099 1.430321 -1.041558 +v -0.016098 1.430868 -1.055308 +v -0.016098 1.430868 -1.055308 +v -0.016701 1.424204 -1.060450 +v 0.062416 1.389720 -0.984752 +v 0.055835 1.375199 -0.986282 +v 0.081060 1.360178 -0.975939 +v 0.090813 1.373388 -0.972040 +v 0.055835 1.375199 -0.986282 +v 0.061436 1.372108 -1.002691 +v 0.089850 1.358046 -0.991570 +v 0.081060 1.360178 -0.975939 +v 0.110008 1.336491 -0.978217 +v 0.098541 1.337561 -0.963505 +v 0.098541 1.337561 -0.963505 +v 0.110950 1.348633 -0.956895 +v -0.016701 1.424204 -1.060450 +v -0.016098 1.430868 -1.055308 +v 0.044504 1.432898 -1.050743 +v 0.044434 1.426666 -1.056695 +v -0.016098 1.430868 -1.055308 +v -0.015099 1.430321 -1.041558 +v 0.041543 1.431345 -1.036921 +v 0.044504 1.432898 -1.050743 +v 0.095265 1.422918 -1.023964 +v 0.102050 1.424773 -1.036943 +v 0.102050 1.424773 -1.036943 +v 0.102538 1.419015 -1.043317 +v 0.033981 1.417232 -1.012055 +v 0.041543 1.431345 -1.036921 +v 0.026093 1.397815 -0.991755 +v 0.062416 1.389720 -0.984752 +v 0.078987 1.408813 -1.001896 +v 0.095265 1.422918 -1.023964 +v -0.015406 1.389597 -1.033579 +v 0.032211 1.390257 -1.033437 +v 0.024981 1.379111 -1.008472 +v 0.039767 1.406706 -1.053836 +v 0.093566 1.399872 -1.042831 +v 0.077355 1.383495 -1.025223 +v 0.061436 1.372108 -1.002691 +v 0.174740 1.377127 -0.976817 +v 0.142978 1.364598 -0.963891 +v 0.160601 1.327976 -0.945017 +v 0.196944 1.337666 -0.953276 +v 0.110950 1.348633 -0.956895 +v 0.124043 1.315849 -0.943050 +v 0.132050 1.275480 -0.932402 +v 0.170992 1.283224 -0.930956 +v 0.209779 1.289398 -0.935525 +v 0.102538 1.419015 -1.043317 +v 0.102050 1.424773 -1.036943 +v 0.151049 1.407547 -1.013959 +v 0.152138 1.402643 -1.020915 +v 0.102050 1.424773 -1.036943 +v 0.095265 1.422918 -1.023964 +v 0.140529 1.405271 -1.002296 +v 0.151049 1.407547 -1.013959 +v 0.174740 1.377127 -0.976817 +v 0.188420 1.379657 -0.986952 +v 0.188420 1.379657 -0.986952 +v 0.190073 1.375903 -0.994566 +v 0.115811 1.391501 -0.984470 +v 0.140529 1.405271 -1.002296 +v 0.090813 1.373388 -0.972040 +v 0.142978 1.364598 -0.963891 +v 0.174740 1.377127 -0.976817 +v 0.114296 1.369474 -1.010429 +v 0.089850 1.358046 -0.991570 +v 0.139024 1.385246 -1.023890 +v 0.173567 1.361343 -1.001511 +v 0.141655 1.347199 -0.992829 +v 0.110008 1.336491 -0.978217 +v 0.132050 1.275480 -0.932402 +v 0.117134 1.270176 -0.942105 +v 0.121749 1.225457 -0.933892 +v 0.137002 1.228500 -0.925762 +v 0.117134 1.270176 -0.942105 +v 0.131434 1.269871 -0.953866 +v 0.136486 1.224947 -0.942700 +v 0.121749 1.225457 -0.933892 +v 0.140009 1.175852 -0.931788 +v 0.125138 1.176747 -0.926601 +v 0.125138 1.176747 -0.926601 +v 0.140484 1.177957 -0.921440 +v 0.110008 1.336491 -0.978217 +v 0.141655 1.347199 -0.992829 +v 0.159634 1.315725 -0.976045 +v 0.123248 1.307198 -0.965569 +v 0.173567 1.361343 -1.001511 +v 0.196234 1.326690 -0.980229 +v 0.209527 1.282609 -0.961717 +v 0.170403 1.275455 -0.960799 +v 0.131434 1.269871 -0.953866 +v 0.098541 1.337561 -0.963505 +v 0.109969 1.307651 -0.951977 +v 0.124043 1.315849 -0.943050 +v 0.098541 1.337561 -0.963505 +v 0.123248 1.307198 -0.965569 +v 0.109969 1.307651 -0.951977 +v 0.212726 1.339865 -0.961823 +v 0.214825 1.337342 -0.969863 +v 0.196944 1.337666 -0.953276 +v 0.212726 1.339865 -0.961823 +v 0.209779 1.289398 -0.935525 +v 0.226726 1.290853 -0.942343 +v 0.226726 1.290853 -0.942343 +v 0.229131 1.289335 -0.949993 +v 0.234132 1.236136 -0.930468 +v 0.236711 1.235172 -0.936492 +v 0.216681 1.235566 -0.925615 +v 0.234132 1.236136 -0.930468 +v 0.220668 1.179002 -0.920290 +v 0.238286 1.178641 -0.923035 +v 0.238286 1.178641 -0.923035 +v 0.240967 1.177953 -0.926701 +v 0.176902 1.232528 -0.923312 +v 0.216681 1.235566 -0.925615 +v 0.137002 1.228500 -0.925762 +v 0.140484 1.177957 -0.921440 +v 0.180627 1.178774 -0.919412 +v 0.220668 1.179002 -0.920290 +v 0.176560 1.227679 -0.946959 +v 0.136486 1.224947 -0.942700 +v 0.216754 1.231399 -0.946465 +v 0.220978 1.176485 -0.933078 +v 0.180442 1.175874 -0.933886 +v 0.140009 1.175852 -0.931788 +v 0.209527 1.282609 -0.961717 +v 0.226666 1.286985 -0.957299 +v 0.234292 1.233785 -0.942404 +v 0.216754 1.231399 -0.946465 +v 0.226666 1.286985 -0.957299 +v 0.229131 1.289335 -0.949993 +v 0.236711 1.235172 -0.936492 +v 0.234292 1.233785 -0.942404 +v 0.240967 1.177953 -0.926701 +v 0.238613 1.177212 -0.930363 +v 0.238613 1.177212 -0.930363 +v 0.220978 1.176485 -0.933078 +v 0.173567 1.361343 -1.001511 +v 0.187746 1.370482 -1.000830 +v 0.212365 1.333528 -0.977125 +v 0.196234 1.326690 -0.980229 +v 0.187746 1.370482 -1.000830 +v 0.214825 1.337342 -0.969863 +v 0.212365 1.333528 -0.977125 +v 0.093566 1.399872 -1.042831 +v 0.100996 1.411352 -1.047210 +v 0.150135 1.395894 -1.025915 +v 0.139024 1.385246 -1.023890 +v 0.100996 1.411352 -1.047210 +v 0.102538 1.419015 -1.043317 +v 0.150135 1.395894 -1.025915 +v 0.190073 1.375903 -0.994566 +v 0.187746 1.370482 -1.000830 +v 0.187746 1.370482 -1.000830 +v -0.017119 1.415840 -1.062601 +v 0.043420 1.418525 -1.059818 +v -0.017119 1.415840 -1.062601 +v 0.044434 1.426666 -1.056695 +v 0.043420 1.418525 -1.059818 +v 0.102538 1.419015 -1.043317 +v 0.100996 1.411352 -1.047210 +v 0.100996 1.411352 -1.047210 +v -0.125118 1.388796 -1.039539 +v -0.074840 1.403096 -1.055568 +v -0.125118 1.388796 -1.039539 +v -0.074840 1.403096 -1.055568 +v -0.195268 1.365179 -0.992094 +v -0.164774 1.379488 -1.016475 +v -0.195268 1.365179 -0.992094 +v -0.197088 1.372787 -0.990023 +v -0.166201 1.387951 -1.016345 +v -0.164774 1.379488 -1.016475 +v -0.234297 1.290274 -0.955690 +v -0.218601 1.334894 -0.971765 +v -0.202613 1.327814 -0.972084 +v -0.234297 1.290274 -0.955690 +v -0.236486 1.293761 -0.949372 +v -0.220658 1.340578 -0.967090 +v -0.218601 1.334894 -0.971765 +v -0.197088 1.372787 -0.990023 +v -0.195268 1.365179 -0.992094 +v -0.195268 1.365179 -0.992094 +v -0.180869 1.357082 -0.988371 +v -0.227576 1.178717 -0.921206 +v -0.224236 1.238632 -0.926336 +v -0.241731 1.239285 -0.931163 +v -0.245287 1.178380 -0.923939 +v -0.233823 1.296392 -0.942589 +v -0.241731 1.239285 -0.931163 +v -0.233823 1.296392 -0.942589 +v -0.236486 1.293761 -0.949372 +v -0.244442 1.237960 -0.937002 +v -0.245287 1.178380 -0.923939 +v -0.248012 1.177792 -0.927617 +vt 0.392788 0.001500 +vt 0.391343 0.005771 +vt 0.391793 0.005866 +vt 0.393061 0.001588 +vt 0.390245 0.009890 +vt 0.390801 0.009912 +vt 0.391793 0.005866 +vt 0.390801 0.009912 +vt 0.391356 0.009934 +vt 0.392243 0.005961 +vt 0.393061 0.001588 +vt 0.393334 0.001676 +vt 0.660230 0.048769 +vt 0.655817 0.049014 +vt 0.656287 0.053461 +vt 0.660246 0.053280 +vt 0.651781 0.049586 +vt 0.652608 0.053915 +vt 0.653434 0.058243 +vt 0.656757 0.057908 +vt 0.660262 0.057791 +vt 0.997235 0.695074 +vt 0.996803 0.698538 +vt 0.997755 0.698694 +vt 0.997818 0.695112 +vt 0.996657 0.701851 +vt 0.997796 0.702220 +vt 0.997755 0.698694 +vt 0.997796 0.702220 +vt 0.998935 0.702588 +vt 0.998708 0.698850 +vt 0.997818 0.695112 +vt 0.998401 0.695150 +vt 0.919648 0.063285 +vt 0.915986 0.063115 +vt 0.915507 0.067506 +vt 0.919624 0.067732 +vt 0.912262 0.062724 +vt 0.911433 0.067015 +vt 0.910604 0.071306 +vt 0.915028 0.071897 +vt 0.919600 0.072179 +vt 0.652607 0.053915 +vt 0.649483 0.054828 +vt 0.650498 0.058944 +vt 0.651781 0.049586 +vt 0.648473 0.050643 +vt 0.646146 0.051656 +vt 0.647174 0.056132 +vt 0.648239 0.059872 +vt 0.998568 0.709196 +vt 0.997790 0.708125 +vt 0.996987 0.709575 +vt 0.997562 0.710849 +vt 0.997790 0.708125 +vt 0.997011 0.707053 +vt 0.996411 0.708301 +vt 0.996987 0.709575 +vt 0.995364 0.708970 +vt 0.995783 0.710349 +vt 0.995783 0.710349 +vt 0.996201 0.711727 +vt 0.997941 0.705539 +vt 0.998969 0.706260 +vt 0.996914 0.704817 +vt 0.997941 0.705539 +vt 0.997011 0.707053 +vt 0.997790 0.708125 +vt 0.997790 0.708125 +vt 0.998568 0.709196 +vt 0.390245 0.009890 +vt 0.389690 0.009867 +vt 0.389273 0.013855 +vt 0.389807 0.013763 +vt 0.389690 0.009867 +vt 0.389134 0.009845 +vt 0.388730 0.014006 +vt 0.389273 0.013855 +vt 0.389312 0.017487 +vt 0.389778 0.017187 +vt 0.389778 0.017187 +vt 0.390339 0.017780 +vt 0.911433 0.067015 +vt 0.907561 0.066063 +vt 0.906565 0.070159 +vt 0.908556 0.061966 +vt 0.905518 0.060995 +vt 0.904505 0.064728 +vt 0.903493 0.068461 +vt 0.900685 0.063301 +vt 0.901849 0.061057 +vt 0.901109 0.058301 +vt 0.899496 0.059548 +vt 0.903358 0.059371 +vt 0.902584 0.057406 +vt 0.902441 0.054866 +vt 0.900681 0.055003 +vt 0.898604 0.055222 +vt 0.391166 0.019325 +vt 0.391544 0.018917 +vt 0.390797 0.019822 +vt 0.391166 0.019325 +vt 0.392775 0.021469 +vt 0.393054 0.020879 +vt 0.393054 0.020879 +vt 0.393334 0.020289 +vt 0.904505 0.064728 +vt 0.902763 0.063109 +vt 0.901775 0.066231 +vt 0.905518 0.060995 +vt 0.903784 0.060045 +vt 0.648239 0.059872 +vt 0.645783 0.057918 +vt 0.646848 0.060895 +vt 0.644820 0.055619 +vt 0.643765 0.058491 +vt 0.644818 0.060055 +vt 0.646033 0.062180 +vt 0.902441 0.054866 +vt 0.903670 0.054868 +vt 0.903815 0.052256 +vt 0.902692 0.051981 +vt 0.903670 0.054868 +vt 0.904582 0.054953 +vt 0.904626 0.052372 +vt 0.903815 0.052256 +vt 0.904845 0.049577 +vt 0.904188 0.049448 +vt 0.904188 0.049448 +vt 0.904165 0.048974 +vt 0.644818 0.060055 +vt 0.643843 0.062764 +vt 0.645466 0.063923 +vt 0.643765 0.058491 +vt 0.642501 0.061915 +vt 0.641518 0.065872 +vt 0.643141 0.065975 +vt 0.645167 0.066126 +vt 0.903358 0.059371 +vt 0.904016 0.059143 +vt 0.903760 0.057129 +vt 0.902584 0.057406 +vt 0.904016 0.059143 +vt 0.905251 0.059183 +vt 0.904829 0.057175 +vt 0.903760 0.057129 +vt 0.642711 0.056381 +vt 0.642032 0.057132 +vt 0.640523 0.061500 +vt 0.641070 0.061431 +vt 0.642032 0.057132 +vt 0.641391 0.057260 +vt 0.639971 0.061547 +vt 0.640523 0.061500 +vt 0.639046 0.065944 +vt 0.639529 0.065910 +vt 0.639529 0.065910 +vt 0.640013 0.065876 +vt 0.997331 0.655073 +vt 0.998648 0.654451 +vt 0.998246 0.652898 +vt 0.996898 0.653327 +vt 0.998648 0.654451 +vt 0.999965 0.653829 +vt 0.999595 0.652470 +vt 0.998246 0.652898 +vt 0.999344 0.650871 +vt 0.997974 0.651103 +vt 0.997974 0.651103 +vt 0.996604 0.651335 +vt 0.640013 0.065875 +vt 0.639529 0.065910 +vt 0.639391 0.070486 +vt 0.639835 0.070449 +vt 0.639529 0.065910 +vt 0.639045 0.065944 +vt 0.638946 0.070523 +vt 0.639391 0.070486 +vt 0.639342 0.075212 +vt 0.639764 0.075173 +vt 0.639764 0.075173 +vt 0.640186 0.075134 +vt 0.900804 0.051431 +vt 0.898562 0.050684 +vt 0.902692 0.051981 +vt 0.904165 0.048974 +vt 0.901641 0.048042 +vt 0.899419 0.046363 +vt 0.643141 0.065975 +vt 0.643075 0.069500 +vt 0.645244 0.068656 +vt 0.641319 0.070244 +vt 0.641479 0.076194 +vt 0.643657 0.072950 +vt 0.645803 0.071035 +vt 0.903696 0.039827 +vt 0.905446 0.043327 +vt 0.908406 0.041998 +vt 0.907117 0.037982 +vt 0.907196 0.046826 +vt 0.909695 0.046015 +vt 0.912661 0.045511 +vt 0.911872 0.041219 +vt 0.911084 0.036927 +vt 0.070949 0.004762 +vt 0.070373 0.004453 +vt 0.069294 0.007119 +vt 0.069905 0.007309 +vt 0.070373 0.004453 +vt 0.069797 0.004144 +vt 0.068683 0.006929 +vt 0.069294 0.007119 +vt 0.067867 0.010070 +vt 0.068502 0.010136 +vt 0.068502 0.010136 +vt 0.069137 0.010203 +vt 0.903168 0.045350 +vt 0.901122 0.042662 +vt 0.905242 0.047962 +vt 0.905446 0.043327 +vt 0.903696 0.039827 +vt 0.644925 0.075586 +vt 0.646923 0.072820 +vt 0.642926 0.078484 +vt 0.645129 0.081108 +vt 0.646848 0.077576 +vt 0.648567 0.074044 +vt 0.996949 0.646014 +vt 0.998188 0.646102 +vt 0.998709 0.642857 +vt 0.997750 0.642745 +vt 0.998188 0.646102 +vt 0.999427 0.646191 +vt 0.999668 0.642968 +vt 0.998709 0.642857 +vt 0.999965 0.639412 +vt 0.999382 0.639342 +vt 0.999382 0.639342 +vt 0.998798 0.639271 +vt 0.648567 0.074044 +vt 0.646848 0.077576 +vt 0.649411 0.078909 +vt 0.650696 0.074854 +vt 0.645129 0.081108 +vt 0.648125 0.082964 +vt 0.651762 0.084054 +vt 0.652573 0.079714 +vt 0.653383 0.075375 +vt 0.997974 0.651103 +vt 0.997941 0.648859 +vt 0.996583 0.648900 +vt 0.997974 0.651103 +vt 0.999298 0.648818 +vt 0.997941 0.648859 +vt 0.068251 0.013741 +vt 0.068886 0.013684 +vt 0.067617 0.013797 +vt 0.068251 0.013741 +vt 0.068092 0.017839 +vt 0.068672 0.017704 +vt 0.068672 0.017704 +vt 0.069251 0.017570 +vt 0.069780 0.021742 +vt 0.070230 0.021609 +vt 0.069330 0.021874 +vt 0.069780 0.021742 +vt 0.070996 0.025869 +vt 0.071272 0.025788 +vt 0.071272 0.025788 +vt 0.071549 0.025706 +vt 0.915658 0.040788 +vt 0.915275 0.036385 +vt 0.916042 0.045191 +vt 0.919648 0.044958 +vt 0.919601 0.040528 +vt 0.919554 0.036098 +vt 0.656248 0.080182 +vt 0.656658 0.075719 +vt 0.655838 0.084644 +vt 0.660135 0.084988 +vt 0.660198 0.080483 +vt 0.660262 0.075978 +vt 0.070410 0.017301 +vt 0.069831 0.017435 +vt 0.070680 0.021477 +vt 0.071129 0.021345 +vt 0.069831 0.017435 +vt 0.069251 0.017570 +vt 0.070230 0.021609 +vt 0.070680 0.021477 +vt 0.071549 0.025706 +vt 0.071825 0.025625 +vt 0.071825 0.025625 +vt 0.072101 0.025544 +vt 0.070407 0.010336 +vt 0.069772 0.010270 +vt 0.069520 0.013628 +vt 0.070154 0.013572 +vt 0.069772 0.010270 +vt 0.068886 0.013684 +vt 0.069520 0.013628 +vt 0.072101 0.005379 +vt 0.071525 0.005070 +vt 0.070516 0.007499 +vt 0.071126 0.007689 +vt 0.071525 0.005070 +vt 0.070949 0.004762 +vt 0.070516 0.007499 +vt 0.069137 0.010203 +vt 0.069772 0.010270 +vt 0.069772 0.010270 +vt 0.640564 0.065849 +vt 0.640352 0.070415 +vt 0.640564 0.065849 +vt 0.639835 0.070449 +vt 0.640352 0.070415 +vt 0.640186 0.075134 +vt 0.640664 0.075237 +vt 0.640664 0.075237 +vt 0.643012 0.057744 +vt 0.641635 0.061553 +vt 0.643012 0.057744 +vt 0.641635 0.061553 +vt 0.644890 0.052104 +vt 0.644041 0.054812 +vt 0.644890 0.052104 +vt 0.644239 0.052180 +vt 0.643456 0.054592 +vt 0.644041 0.054812 +vt 0.390801 0.009912 +vt 0.390285 0.013577 +vt 0.390809 0.013387 +vt 0.390801 0.009912 +vt 0.390245 0.009890 +vt 0.389807 0.013763 +vt 0.390285 0.013577 +vt 0.390339 0.017780 +vt 0.390110 0.017036 +vt 0.390110 0.017036 +vt 0.390465 0.016528 +vt 0.392243 0.001324 +vt 0.390442 0.005581 +vt 0.390892 0.005676 +vt 0.392516 0.001412 +vt 0.389690 0.009867 +vt 0.390892 0.005676 +vt 0.389690 0.009867 +vt 0.390245 0.009890 +vt 0.391343 0.005771 +vt 0.392516 0.001412 +vt 0.392788 0.001500 +vn -0.9002 -0.0224 -0.4349 +vn -0.9167 0.0154 -0.3994 +vn -0.9153 0.0121 -0.4025 +vn -0.9046 0.0968 -0.4150 +vn -0.9088 0.0893 -0.4075 +vn -0.2240 -0.1902 -0.9558 +vn -0.2230 -0.2198 -0.9497 +vn -0.1087 -0.2300 -0.9671 +vn -0.1251 -0.2050 -0.9707 +vn -0.2003 -0.1876 -0.9616 +vn -0.1172 -0.2033 -0.9721 +vn 0.0368 -0.2108 -0.9768 +vn 0.0197 -0.2157 -0.9763 +vn 0.0918 -0.2178 -0.9717 +vn 0.3818 -0.1948 -0.9035 +vn 0.2947 -0.1877 -0.9370 +vn 0.2463 -0.1911 -0.9502 +vn 0.2947 -0.1876 -0.9370 +vn 0.4936 -0.1637 -0.8542 +vn 0.4217 -0.1625 -0.8921 +vn 0.6010 -0.1908 -0.7761 +vn 0.4443 0.0520 0.8943 +vn 0.4616 0.0188 0.8869 +vn 0.2295 0.0863 0.9695 +vn 0.2516 0.0663 0.9656 +vn 0.4047 0.0704 0.9117 +vn 0.2326 0.0667 0.9703 +vn 0.2325 0.0668 0.9703 +vn -0.0060 0.0982 0.9951 +vn 0.0079 0.0684 0.9976 +vn -0.0558 0.1961 0.9790 +vn -0.2296 0.2818 0.9316 +vn -0.1600 0.1400 0.9771 +vn -0.1265 0.0943 0.9875 +vn 0.1730 -0.3353 -0.9261 +vn 0.4678 -0.3009 -0.8311 +vn -0.0456 -0.3593 -0.9321 +vn -0.0334 -0.6268 -0.7784 +vn 0.1978 -0.6473 -0.7361 +vn 0.5597 -0.4055 -0.7227 +vn 0.0901 0.4703 0.8779 +vn 0.3088 0.2372 0.9211 +vn 0.3634 0.4389 0.8218 +vn 0.3691 0.4462 0.8153 +vn 0.6832 -0.7140 -0.1530 +vn 0.6368 -0.7709 0.0136 +vn 0.5984 -0.7930 0.1144 +vn 0.4364 -0.8339 0.3380 +vn 0.4115 -0.8393 0.3553 +vn 0.3401 0.4359 0.8332 +vn 0.3439 0.4392 0.8299 +vn 0.3716 0.0516 0.9270 +vn 0.1295 0.2006 0.9711 +vn 0.4678 -0.3009 -0.8310 +vn 0.6743 -0.3301 -0.6606 +vn 0.6916 -0.3984 -0.6025 +vn -0.9261 0.2761 0.2572 +vn -0.9254 0.2924 0.2410 +vn -0.8937 0.4477 -0.0298 +vn -0.9057 0.4224 0.0348 +vn -0.3327 0.3117 0.8900 +vn -0.2928 0.5139 0.8063 +vn -0.3880 0.5397 0.7471 +vn -0.3024 0.7967 0.5233 +vn -0.3967 0.7996 0.4509 +vn -0.7796 0.4739 -0.4094 +vn -0.8152 0.4844 -0.3176 +vn -0.1317 0.3848 0.9136 +vn -0.1572 0.6773 0.7187 +vn -0.2043 0.9750 0.0879 +vn -0.0662 0.9312 0.3584 +vn -0.0744 0.8986 0.4325 +vn -0.1814 0.9725 0.1462 +vn -0.0011 0.8898 0.4564 +vn -0.0167 0.8442 0.5358 +vn -0.0183 0.7827 0.6221 +vn -0.0496 0.8529 0.5197 +vn -0.0954 0.9698 0.2243 +vn -0.6130 0.3998 -0.6815 +vn -0.6223 0.1963 -0.7577 +vn -0.2381 0.9507 0.1987 +vn -0.3278 0.9410 0.0838 +vn -0.2746 0.9591 -0.0692 +vn -0.4294 0.3823 -0.8182 +vn -0.4326 0.1654 -0.8863 +vn -0.0960 0.8886 0.4486 +vn -0.0408 0.8404 0.5405 +vn 0.2704 -0.8088 -0.5223 +vn 0.1333 -0.8928 -0.4304 +vn 0.2113 -0.9132 -0.3483 +vn -0.0692 -0.8171 -0.5723 +vn -0.0362 -0.8310 -0.5551 +vn 0.0988 -0.9422 -0.3201 +vn 0.1471 -0.9663 -0.2114 +vn 0.0479 0.1339 0.9898 +vn 0.0470 0.1330 0.9900 +vn -0.0927 0.0398 0.9949 +vn -0.1003 0.0371 0.9943 +vn 0.0365 -0.9526 0.3021 +vn 0.0342 -0.9532 0.3005 +vn -0.1404 -0.9714 0.1917 +vn -0.1307 -0.9716 0.1973 +vn -0.3541 -0.9346 0.0330 +vn -0.3365 -0.9404 0.0482 +vn -0.2712 0.0251 0.9622 +vn -0.2812 0.0265 0.9593 +vn 0.0902 -0.9222 -0.3760 +vn 0.1013 -0.9630 -0.2499 +vn 0.0278 -0.7633 -0.6454 +vn 0.0433 -0.6891 -0.7234 +vn 0.0439 -0.8884 -0.4569 +vn 0.0330 -0.9435 -0.3299 +vn 0.1921 0.2873 0.9384 +vn 0.2020 0.2983 0.9328 +vn 0.4364 -0.8338 0.3380 +vn 0.2238 -0.8939 0.3885 +vn 0.2142 -0.8974 0.3856 +vn -0.2522 0.4803 -0.8401 +vn -0.2493 0.2775 -0.9278 +vn -0.2747 0.9590 -0.0692 +vn -0.2356 0.9711 -0.0374 +vn -0.1150 0.9927 0.0352 +vn -0.0655 0.6045 -0.7939 +vn -0.0664 0.4296 -0.9006 +vn -0.2711 0.0251 0.9622 +vn -0.4430 0.0670 0.8940 +vn -0.4450 0.0677 0.8930 +vn -0.3365 -0.9404 0.0483 +vn -0.5488 -0.8093 -0.2095 +vn -0.5392 -0.8198 -0.1927 +vn -0.6470 -0.6139 -0.4522 +vn -0.6457 -0.6192 -0.4468 +vn -0.5365 0.1033 0.8375 +vn -0.5354 0.1029 0.8383 +vn -0.0663 0.4295 -0.9006 +vn 0.1469 0.6807 -0.7177 +vn 0.1472 0.5202 -0.8413 +vn 0.0166 0.9539 0.2997 +vn 0.0399 0.9919 0.1205 +vn 0.1014 0.9141 0.3926 +vn 0.1593 0.9583 0.2374 +vn 0.3720 0.7120 -0.5955 +vn 0.3781 0.5552 -0.7408 +vn -0.0097 0.8096 0.5869 +vn -0.0108 0.7277 0.6858 +vn -0.0164 0.6722 0.7402 +vn 0.0113 0.7600 0.6498 +vn -0.0055 -0.8482 -0.5296 +vn -0.0370 -0.9104 -0.4121 +vn 0.0601 -0.6321 -0.7725 +vn 0.1083 -0.5928 -0.7980 +vn -0.0320 -0.7957 -0.6048 +vn -0.0950 -0.8564 -0.5074 +vn 0.2104 0.6840 0.6984 +vn 0.0254 0.5509 0.8342 +vn 0.0219 0.3901 0.9205 +vn 0.2281 0.4881 0.8425 +vn -0.0439 0.4768 0.8779 +vn -0.0561 0.3359 0.9402 +vn -0.3094 0.1539 0.9384 +vn 0.0075 0.2317 0.9728 +vn 0.2066 0.2943 0.9331 +vn 0.3719 0.7120 -0.5955 +vn 0.5913 0.7028 -0.3955 +vn 0.6054 0.5541 -0.5713 +vn 0.1620 0.8320 0.5305 +vn 0.2475 0.8789 0.4078 +vn 0.3165 0.7283 0.6078 +vn 0.7811 0.6088 -0.1387 +vn 0.8035 0.4799 -0.3524 +vn 0.0188 0.6795 0.7334 +vn -0.0322 0.5940 0.8038 +vn 0.0254 0.5510 0.8341 +vn 0.2105 0.6840 0.6984 +vn -0.0478 -0.7114 -0.7011 +vn -0.1409 -0.7556 -0.6397 +vn 0.1539 -0.5474 -0.8226 +vn 0.1721 -0.4703 -0.8655 +vn -0.0632 -0.5789 -0.8130 +vn -0.1666 -0.5961 -0.7854 +vn -0.5472 0.0927 0.8319 +vn -0.4654 0.0807 0.8814 +vn -0.2690 0.0954 0.9584 +vn -0.6067 -0.2821 -0.7432 +vn -0.3750 -0.3095 -0.8738 +vn -0.2982 -0.2396 -0.9239 +vn -0.4993 -0.2143 -0.8395 +vn -0.2457 -0.2195 -0.9442 +vn -0.4267 -0.1945 -0.8832 +vn -0.4063 0.0784 0.9104 +vn -0.2332 0.0776 0.9693 +vn -0.0632 -0.5788 -0.8130 +vn -0.0636 -0.4312 -0.9000 +vn -0.1596 -0.4290 -0.8891 +vn 0.1746 -0.3765 -0.9098 +vn 0.1667 -0.2929 -0.9415 +vn -0.0463 -0.3192 -0.9466 +vn -0.5669 0.1074 0.8168 +vn -0.5666 0.1077 0.8170 +vn -0.6457 -0.6193 -0.4468 +vn -0.6578 -0.4200 -0.6252 +vn -0.6577 -0.4190 -0.6260 +vn 0.8962 0.4347 0.0891 +vn 0.8933 0.4419 0.0818 +vn 0.3475 0.5264 0.7760 +vn 0.3263 0.3233 0.8883 +vn 0.9318 0.2697 0.2429 +vn 0.9316 0.2737 0.2393 +vn 0.9100 0.1672 0.3794 +vn 0.9096 0.1666 0.3806 +vn 0.1559 0.1537 0.9757 +vn 0.2552 0.1743 0.9510 +vn 0.1271 0.1059 0.9862 +vn 0.2094 0.1235 0.9700 +vn 0.8804 0.1329 0.4552 +vn 0.8804 0.1329 0.4553 +vn -0.0060 0.1181 0.9930 +vn -0.2331 0.0775 0.9693 +vn -0.0103 0.0804 0.9967 +vn -0.0276 -0.2563 -0.9662 +vn 0.1377 -0.2386 -0.9613 +vn 0.1197 -0.2209 -0.9679 +vn -0.0182 -0.2374 -0.9712 +vn 0.2881 -0.2602 -0.9216 +vn 0.2375 -0.2168 -0.9469 +vn 0.9287 0.0844 -0.3610 +vn 0.9293 0.0801 -0.3606 +vn 0.9162 0.0101 -0.4005 +vn 0.9170 0.0112 -0.3987 +vn 0.8963 -0.0174 -0.4430 +vn 0.8963 -0.0174 -0.4431 +vn 0.2025 -0.2030 -0.9580 +vn 0.1722 -0.4703 -0.8656 +vn 0.2919 -0.3842 -0.8759 +vn 0.3016 -0.3224 -0.8973 +vn 0.7633 0.3082 -0.5678 +vn 0.8034 0.4799 -0.3524 +vn 0.8904 0.1849 -0.4159 +vn 0.8852 0.1934 -0.4231 +vn 0.1871 -0.4476 -0.8744 +vn 0.2600 -0.4285 -0.8653 +vn 0.3550 0.3695 -0.8587 +vn 0.5732 0.3678 -0.7322 +vn 0.1721 -0.4703 -0.8656 +vn 0.0360 -0.5396 -0.8411 +vn 0.0962 -0.4742 -0.8751 +vn -0.0606 0.2259 -0.9723 +vn 0.1473 0.5202 -0.8413 +vn 0.1361 0.3300 -0.9341 +vn 0.3551 0.3695 -0.8587 +vn 0.1872 -0.4476 -0.8744 +vn -0.1188 -0.7353 -0.6673 +vn -0.0163 -0.6380 -0.7699 +vn -0.4025 -0.0486 -0.9141 +vn -0.2266 0.0669 -0.9717 +vn -0.1496 -0.5752 -0.8042 +vn -0.1759 -0.7404 -0.6488 +vn -0.7019 0.0539 -0.7102 +vn -0.6847 0.0348 -0.7280 +vn -0.5675 -0.0489 -0.8219 +vn -0.1651 -0.3445 -0.9241 +vn -0.9047 0.0968 -0.4150 +vn -0.8104 0.1228 -0.5728 +vn -0.8304 0.1265 -0.5427 +vn -0.6847 0.0349 -0.7280 +vn -0.2539 0.1615 0.9537 +vn -0.2077 0.1112 0.9718 +vn -0.9025 0.1611 0.3995 +vn -0.8997 0.1565 0.4075 +vn -0.8723 0.1165 0.4748 +usemtl Scene_-_Root +s 1 +f 28240/28240/20086 28241/28241/20087 28242/28242/20088 +f 28240/28240/20086 28242/28242/20088 28243/28243/20086 +f 28241/28241/20087 28244/28244/20089 28245/28245/20090 +f 28241/28241/20087 28245/28245/20090 28242/28242/20088 +f 28246/28246/20091 28247/28247/20092 28248/28248/20093 +f 28246/28246/20091 28248/28248/20093 28249/28249/20094 +f 28250/28250/20095 28246/28246/20091 28249/28249/20094 +f 28250/28250/20095 28249/28249/20094 28251/28251/20096 +f 28252/28252/20096 28253/28253/20094 28254/28254/20097 +f 28252/28252/20096 28254/28254/20097 28255/28255/20098 +f 28253/28253/20094 28256/28256/20093 28257/28257/20099 +f 28253/28253/20094 28257/28257/20099 28254/28254/20097 +f 28254/28254/20097 28257/28257/20099 28258/28258/20100 +f 28254/28254/20097 28258/28258/20100 28259/28259/20101 +f 28255/28255/20098 28254/28254/20097 28259/28259/20101 +f 28255/28255/20098 28259/28259/20101 28260/28260/20102 +f 28261/28261/20102 28262/28262/20103 28263/28263/20104 +f 28261/28261/20102 28263/28263/20104 28264/28264/20105 +f 28262/28262/20103 28265/28265/20100 28266/28266/20106 +f 28262/28262/20103 28266/28266/20106 28263/28263/20104 +f 28267/28267/20107 28268/28268/20108 28269/28269/20109 +f 28267/28267/20107 28269/28269/20109 28270/28270/20110 +f 28271/28271/20111 28267/28267/20107 28270/28270/20110 +f 28271/28271/20111 28270/28270/20110 28272/28272/20112 +f 28273/28273/20113 28274/28274/20110 28275/28275/20114 +f 28273/28273/20113 28275/28275/20114 28276/28276/20115 +f 28274/28274/20110 28277/28277/20109 28278/28278/20116 +f 28274/28274/20110 28278/28278/20116 28275/28275/20114 +f 28275/28275/20114 28278/28278/20116 28279/28279/20117 +f 28275/28275/20114 28279/28279/20117 28280/28280/20118 +f 28276/28276/20115 28275/28275/20114 28280/28280/20118 +f 28276/28276/20115 28280/28280/20118 28281/28281/20119 +f 28258/28258/20100 28282/28282/20099 28283/28283/20120 +f 28258/28258/20100 28283/28283/20120 28284/28284/20121 +f 28282/28282/20099 28285/28285/20093 28286/28286/20122 +f 28282/28282/20099 28286/28286/20122 28283/28283/20120 +f 28283/28283/20120 28286/28286/20122 28287/28287/20123 +f 28283/28283/20120 28287/28287/20123 28288/28288/20124 +f 28284/28284/20121 28283/28283/20120 28288/28288/20124 +f 28284/28284/20121 28288/28288/20124 28289/28289/20125 +f 28290/28290/20126 28291/28291/20127 28292/28292/20128 +f 28290/28290/20126 28292/28292/20128 28293/28293/20129 +f 28294/28294/20130 28295/28295/20130 28296/28296/20131 +f 28294/28294/20130 28296/28296/20131 28297/28297/20132 +f 28297/28297/20132 28296/28296/20131 28298/28298/20133 +f 28297/28297/20132 28298/28298/20133 28299/28299/20134 +f 28293/28293/20129 28292/28292/20128 28300/28300/20135 +f 28293/28293/20129 28300/28300/20135 28301/28301/20136 +f 28269/28269/20109 28268/28268/20108 28302/28302/20137 +f 28269/28269/20109 28302/28302/20137 28303/28303/20138 +f 28266/28266/20106 28265/28265/20100 28304/28304/20139 +f 28266/28266/20106 28304/28304/20139 28305/28305/20140 +f 28305/28305/20140 28304/28304/20139 28306/28306/20125 +f 28305/28305/20140 28306/28306/20125 28307/28307/20141 +f 28303/28303/20138 28302/28302/20137 28308/28308/20127 +f 28303/28303/20138 28308/28308/20127 28309/28309/20126 +f 28310/28310/20142 28311/28311/20143 28312/28312/20144 +f 28310/28310/20142 28312/28312/20144 28313/28313/20145 +f 28314/28314/20146 28315/28315/20117 28316/28316/20147 +f 28314/28314/20146 28316/28316/20147 28317/28317/20148 +f 28317/28317/20148 28316/28316/20147 28318/28318/20149 +f 28317/28317/20148 28318/28318/20149 28319/28319/20150 +f 28313/28313/20145 28312/28312/20144 28320/28320/20151 +f 28313/28313/20145 28320/28320/20151 28321/28321/20152 +f 28279/28279/20117 28322/28322/20116 28323/28323/20153 +f 28279/28279/20117 28323/28323/20153 28324/28324/20147 +f 28322/28322/20116 28277/28277/20109 28325/28325/20138 +f 28322/28322/20116 28325/28325/20138 28323/28323/20153 +f 28323/28323/20153 28325/28325/20138 28326/28326/20126 +f 28323/28323/20153 28326/28326/20126 28327/28327/20154 +f 28324/28324/20147 28323/28323/20153 28327/28327/20154 +f 28324/28324/20147 28327/28327/20154 28328/28328/20149 +f 28329/28329/20155 28330/28330/20156 28331/28331/20157 +f 28329/28329/20155 28331/28331/20157 28332/28332/20158 +f 28330/28330/20156 28333/28333/20159 28334/28334/20160 +f 28330/28330/20156 28334/28334/20160 28331/28331/20157 +f 28331/28331/20157 28334/28334/20160 28335/28335/20161 +f 28331/28331/20157 28335/28335/20161 28336/28336/20162 +f 28332/28332/20158 28331/28331/20157 28336/28336/20162 +f 28332/28332/20158 28336/28336/20162 28337/28337/20163 +f 28321/28321/20152 28320/28320/20151 28338/28338/20164 +f 28321/28321/20152 28338/28338/20164 28339/28339/20165 +f 28319/28319/20150 28318/28318/20149 28340/28340/20166 +f 28319/28319/20150 28340/28340/20166 28341/28341/20167 +f 28341/28341/20167 28340/28340/20166 28342/28342/20155 +f 28341/28341/20167 28342/28342/20155 28343/28343/20168 +f 28339/28339/20165 28338/28338/20164 28344/28344/20169 +f 28339/28339/20165 28344/28344/20169 28345/28345/20170 +f 28328/28328/20149 28346/28346/20154 28347/28347/20171 +f 28328/28328/20149 28347/28347/20171 28348/28348/20166 +f 28346/28346/20154 28349/28349/20126 28350/28350/20172 +f 28346/28346/20154 28350/28350/20172 28347/28347/20171 +f 28347/28347/20171 28350/28350/20172 28333/28333/20159 +f 28347/28347/20171 28333/28333/20159 28330/28330/20156 +f 28348/28348/20166 28347/28347/20171 28330/28330/20156 +f 28348/28348/20166 28330/28330/20156 28329/28329/20155 +f 28351/28351/20173 28288/28288/20124 28352/28352/20174 +f 28351/28351/20173 28352/28352/20174 28353/28353/20175 +f 28288/28288/20124 28287/28287/20123 28354/28354/20176 +f 28288/28288/20124 28354/28354/20176 28352/28352/20174 +f 28352/28352/20174 28354/28354/20176 28355/28355/20177 +f 28352/28352/20174 28355/28355/20177 28356/28356/20178 +f 28353/28353/20175 28352/28352/20174 28356/28356/20178 +f 28353/28353/20175 28356/28356/20178 28357/28357/20179 +f 28358/28358/20180 28359/28359/20181 28360/28360/20182 +f 28358/28358/20180 28360/28360/20182 28361/28361/20183 +f 28362/28362/20184 28363/28363/20185 28364/28364/20186 +f 28362/28362/20184 28364/28364/20186 28365/28365/20187 +f 28365/28365/20187 28364/28364/20186 28366/28366/20188 +f 28365/28365/20187 28366/28366/20188 28367/28367/20189 +f 28361/28361/20183 28360/28360/20182 28368/28368/20190 +f 28361/28361/20183 28368/28368/20190 28369/28369/20191 +f 28357/28357/20179 28370/28370/20178 28371/28371/20192 +f 28357/28357/20179 28371/28371/20192 28372/28372/20193 +f 28370/28370/20178 28373/28373/20177 28374/28374/20194 +f 28370/28370/20178 28374/28374/20194 28371/28371/20192 +f 28371/28371/20192 28374/28374/20194 28375/28375/20195 +f 28371/28371/20192 28375/28375/20195 28376/28376/20196 +f 28372/28372/20193 28371/28371/20192 28376/28376/20196 +f 28372/28372/20193 28376/28376/20196 28377/28377/20197 +f 28378/28378/20136 28379/28379/20135 28380/28380/20198 +f 28378/28378/20136 28380/28380/20198 28381/28381/20199 +f 28382/28382/20134 28383/28383/20200 28384/28384/20201 +f 28382/28382/20134 28384/28384/20201 28385/28385/20202 +f 28385/28385/20202 28384/28384/20201 28363/28363/20185 +f 28385/28385/20202 28363/28363/20185 28362/28362/20184 +f 28381/28381/20199 28380/28380/20198 28359/28359/20181 +f 28381/28381/20199 28359/28359/20181 28358/28358/20180 +f 28386/28386/20170 28387/28387/20169 28388/28388/20203 +f 28386/28386/20170 28388/28388/20203 28389/28389/20204 +f 28390/28390/20205 28391/28391/20155 28392/28392/20158 +f 28390/28390/20205 28392/28392/20158 28393/28393/20206 +f 28393/28393/20206 28392/28392/20158 28394/28394/20163 +f 28393/28393/20206 28394/28394/20163 28395/28395/20207 +f 28389/28389/20204 28388/28388/20203 28396/28396/20208 +f 28389/28389/20204 28396/28396/20208 28397/28397/20209 +f 28398/28398/20191 28399/28399/20210 28400/28400/20211 +f 28398/28398/20191 28400/28400/20211 28401/28401/20212 +f 28402/28402/20213 28403/28403/20188 28404/28404/20214 +f 28402/28402/20213 28404/28404/20214 28405/28405/20215 +f 28405/28405/20215 28404/28404/20214 28406/28406/20216 +f 28405/28405/20215 28406/28406/20216 28407/28407/20217 +f 28401/28401/20212 28400/28400/20211 28408/28408/20218 +f 28401/28401/20212 28408/28408/20218 28409/28409/20219 +f 28410/28410/20220 28411/28411/20208 28412/28412/20221 +f 28410/28410/20220 28412/28412/20221 28413/28413/20222 +f 28414/28414/20207 28415/28415/20163 28416/28416/20223 +f 28414/28414/20207 28416/28416/20223 28417/28417/20224 +f 28417/28417/20224 28416/28416/20223 28418/28418/20225 +f 28417/28417/20224 28418/28418/20225 28419/28419/20226 +f 28413/28413/20222 28412/28412/20221 28420/28420/20227 +f 28413/28413/20222 28420/28420/20227 28421/28421/20228 +f 28337/28337/20163 28336/28336/20162 28422/28422/20229 +f 28337/28337/20163 28422/28422/20229 28423/28423/20223 +f 28336/28336/20162 28335/28335/20161 28424/28424/20230 +f 28336/28336/20162 28424/28424/20230 28422/28422/20229 +f 28422/28422/20229 28424/28424/20230 28425/28425/20231 +f 28422/28422/20229 28425/28425/20231 28426/28426/20232 +f 28423/28423/20223 28422/28422/20229 28426/28426/20232 +f 28423/28423/20223 28426/28426/20232 28427/28427/20225 +f 28377/28377/20197 28428/28428/20196 28429/28429/20233 +f 28377/28377/20197 28429/28429/20233 28430/28430/20234 +f 28428/28428/20196 28375/28375/20195 28431/28431/20235 +f 28428/28428/20196 28431/28431/20235 28429/28429/20233 +f 28429/28429/20233 28431/28431/20235 28432/28432/20236 +f 28429/28429/20233 28432/28432/20236 28433/28433/20237 +f 28430/28430/20234 28429/28429/20233 28433/28433/20237 +f 28430/28430/20234 28433/28433/20237 28434/28434/20238 +f 28435/28435/20239 28436/28436/20240 28437/28437/20241 +f 28435/28435/20239 28437/28437/20241 28438/28438/20242 +f 28436/28436/20240 28439/28439/20243 28440/28440/20244 +f 28436/28436/20240 28440/28440/20244 28437/28437/20241 +f 28437/28437/20241 28440/28440/20244 28441/28441/20245 +f 28437/28437/20241 28441/28441/20245 28442/28442/20246 +f 28438/28438/20242 28437/28437/20241 28442/28442/20246 +f 28438/28438/20242 28442/28442/20246 28443/28443/20247 +f 28444/28444/20228 28445/28445/20248 28446/28446/20249 +f 28444/28444/20228 28446/28446/20249 28447/28447/20250 +f 28448/28448/20226 28449/28449/20225 28450/28450/20251 +f 28448/28448/20226 28450/28450/20251 28451/28451/20252 +f 28451/28451/20252 28450/28450/20251 28452/28452/20239 +f 28451/28451/20252 28452/28452/20239 28453/28453/20253 +f 28447/28447/20250 28446/28446/20249 28454/28454/20254 +f 28447/28447/20250 28454/28454/20254 28455/28455/20255 +f 28427/28427/20225 28426/28426/20232 28456/28456/20256 +f 28427/28427/20225 28456/28456/20256 28457/28457/20251 +f 28426/28426/20232 28425/28425/20231 28458/28458/20257 +f 28426/28426/20232 28458/28458/20257 28456/28456/20256 +f 28456/28456/20256 28458/28458/20257 28439/28439/20243 +f 28456/28456/20256 28439/28439/20243 28459/28459/20258 +f 28457/28457/20251 28456/28456/20256 28459/28459/20258 +f 28457/28457/20251 28459/28459/20258 28460/28460/20259 +f 28434/28434/20238 28433/28433/20237 28461/28461/20260 +f 28434/28434/20238 28461/28461/20260 28462/28462/20261 +f 28433/28433/20237 28432/28432/20236 28463/28463/20262 +f 28433/28433/20237 28463/28463/20262 28461/28461/20260 +f 28461/28461/20260 28463/28463/20262 28464/28464/20263 +f 28461/28461/20260 28464/28464/20263 28465/28465/20264 +f 28462/28462/20261 28461/28461/20260 28465/28465/20264 +f 28462/28462/20261 28465/28465/20264 28466/28466/20265 +f 28467/28467/20245 28468/28468/20266 28469/28469/20267 +f 28467/28467/20245 28469/28469/20267 28470/28470/20268 +f 28471/28471/20269 28472/28472/20270 28473/28473/20271 +f 28471/28471/20269 28473/28473/20271 28474/28474/20272 +f 28474/28474/20272 28473/28473/20271 28475/28475/20273 +f 28474/28474/20272 28475/28475/20273 28476/28476/20274 +f 28470/28470/20268 28469/28469/20267 28477/28477/20275 +f 28470/28470/20268 28477/28477/20275 28478/28478/20276 +f 28479/28479/20265 28480/28480/20277 28481/28481/20278 +f 28479/28479/20265 28481/28481/20278 28482/28482/20279 +f 28480/28480/20277 28483/28483/20263 28484/28484/20280 +f 28480/28480/20277 28484/28484/20280 28481/28481/20278 +f 28481/28481/20278 28484/28484/20280 28485/28485/20281 +f 28481/28481/20278 28485/28485/20281 28486/28486/20282 +f 28482/28482/20279 28481/28481/20278 28486/28486/20282 +f 28482/28482/20279 28486/28486/20282 28487/28487/20270 +f 28409/28409/20219 28488/28488/20218 28489/28489/20283 +f 28409/28409/20219 28489/28489/20283 28490/28490/20284 +f 28491/28491/20285 28406/28406/20216 28492/28492/20286 +f 28491/28491/20285 28492/28492/20286 28493/28493/20287 +f 28493/28493/20287 28492/28492/20286 28472/28472/20270 +f 28493/28493/20287 28472/28472/20270 28471/28471/20269 +f 28490/28490/20284 28489/28489/20283 28468/28468/20266 +f 28490/28490/20284 28468/28468/20266 28467/28467/20245 +f 28455/28455/20255 28454/28454/20254 28494/28494/20288 +f 28455/28455/20255 28494/28494/20288 28495/28495/20289 +f 28453/28453/20253 28452/28452/20239 28496/28496/20242 +f 28453/28453/20253 28496/28496/20242 28497/28497/20290 +f 28497/28497/20290 28496/28496/20242 28498/28498/20247 +f 28497/28497/20290 28498/28498/20247 28499/28499/20291 +f 28495/28495/20289 28494/28494/20288 28500/28500/20292 +f 28495/28495/20289 28500/28500/20292 28501/28501/20293 +f 28501/28501/20293 28500/28500/20292 28502/28502/20294 +f 28501/28501/20293 28502/28502/20294 28503/28503/20295 +f 28499/28499/20291 28498/28498/20247 28504/28504/20296 +f 28499/28499/20291 28504/28504/20296 28505/28505/20297 +f 28505/28505/20297 28504/28504/20296 28506/28506/20298 +f 28505/28505/20297 28506/28506/20298 28507/28507/20299 +f 28503/28503/20295 28502/28502/20294 28508/28508/20300 +f 28503/28503/20295 28508/28508/20300 28509/28509/20301 +f 28443/28443/20247 28442/28442/20246 28510/28510/20302 +f 28443/28443/20247 28510/28510/20302 28511/28511/20296 +f 28442/28442/20246 28441/28441/20245 28512/28512/20268 +f 28442/28442/20246 28512/28512/20268 28510/28510/20302 +f 28510/28510/20302 28512/28512/20268 28513/28513/20303 +f 28510/28510/20302 28513/28513/20303 28514/28514/20304 +f 28511/28511/20296 28510/28510/20302 28514/28514/20304 +f 28511/28511/20296 28514/28514/20304 28515/28515/20298 +f 28487/28487/20270 28486/28486/20282 28516/28516/20305 +f 28487/28487/20270 28516/28516/20305 28517/28517/20271 +f 28486/28486/20282 28485/28485/20281 28518/28518/20306 +f 28486/28486/20282 28518/28518/20306 28516/28516/20305 +f 28516/28516/20305 28518/28518/20306 28519/28519/20307 +f 28516/28516/20305 28519/28519/20307 28520/28520/20308 +f 28517/28517/20271 28516/28516/20305 28520/28520/20308 +f 28517/28517/20271 28520/28520/20308 28521/28521/20273 +f 28522/28522/20281 28523/28523/20309 28524/28524/20310 +f 28522/28522/20281 28524/28524/20310 28525/28525/20306 +f 28526/28526/20311 28527/28527/20312 28528/28528/20313 +f 28526/28526/20311 28528/28528/20313 28529/28529/20314 +f 28529/28529/20314 28528/28528/20313 28530/28530/20315 +f 28529/28529/20314 28530/28530/20315 28531/28531/20316 +f 28525/28525/20306 28524/28524/20310 28532/28532/20317 +f 28525/28525/20306 28532/28532/20317 28533/28533/20307 +f 28534/28534/20318 28535/28535/20319 28536/28536/20320 +f 28534/28534/20318 28536/28536/20320 28537/28537/20280 +f 28538/28538/20321 28455/28455/20322 28539/28539/20323 +f 28538/28538/20321 28539/28539/20323 28540/28540/20324 +f 28540/28540/20324 28539/28539/20323 28527/28527/20312 +f 28540/28540/20324 28527/28527/20312 28526/28526/20311 +f 28537/28537/20280 28536/28536/20320 28523/28523/20309 +f 28537/28537/20280 28523/28523/20309 28522/28522/20281 +f 28541/28541/20236 28542/28542/20325 28543/28543/20326 +f 28541/28541/20236 28543/28543/20326 28544/28544/20262 +f 28545/28545/20327 28546/28546/20228 28447/28447/20250 +f 28545/28545/20327 28447/28447/20250 28547/28547/20328 +f 28547/28547/20328 28447/28447/20250 28548/28548/20322 +f 28547/28547/20328 28548/28548/20322 28549/28549/20321 +f 28544/28544/20262 28543/28543/20326 28550/28550/20319 +f 28544/28544/20262 28550/28550/20319 28534/28534/20329 +f 28375/28375/20195 28551/28551/20330 28552/28552/20331 +f 28375/28375/20195 28552/28552/20331 28431/28431/20235 +f 28553/28553/20332 28397/28397/20209 28554/28554/20333 +f 28553/28553/20332 28554/28554/20333 28555/28555/20334 +f 28555/28555/20334 28554/28554/20333 28556/28556/20228 +f 28555/28555/20334 28556/28556/20228 28557/28557/20335 +f 28431/28431/20235 28552/28552/20331 28558/28558/20336 +f 28431/28431/20235 28558/28558/20336 28432/28432/20236 +f 28355/28355/20177 28559/28559/20337 28560/28560/20338 +f 28355/28355/20177 28560/28560/20338 28374/28374/20194 +f 28561/28561/20339 28386/28386/20170 28389/28389/20204 +f 28561/28561/20339 28389/28389/20204 28562/28562/20340 +f 28562/28562/20340 28389/28389/20204 28397/28397/20209 +f 28562/28562/20340 28397/28397/20209 28553/28553/20332 +f 28374/28374/20194 28560/28560/20338 28551/28551/20330 +f 28374/28374/20194 28551/28551/20330 28375/28375/20195 +f 28287/28287/20123 28563/28563/20341 28564/28564/20342 +f 28287/28287/20123 28564/28564/20342 28354/28354/20176 +f 28565/28565/20343 28566/28566/20344 28567/28567/20165 +f 28565/28565/20343 28567/28567/20165 28568/28568/20345 +f 28568/28568/20345 28567/28567/20165 28386/28386/20170 +f 28568/28568/20345 28386/28386/20170 28561/28561/20339 +f 28354/28354/20176 28564/28564/20342 28559/28559/20337 +f 28354/28354/20176 28559/28559/20337 28355/28355/20177 +f 28248/28248/20093 28569/28569/20092 28570/28570/20346 +f 28248/28248/20093 28570/28570/20346 28571/28571/20122 +f 28572/28572/20090 28573/28573/20347 28574/28574/20348 +f 28572/28572/20090 28574/28574/20348 28575/28575/20349 +f 28575/28575/20349 28574/28574/20348 28576/28576/20350 +f 28575/28575/20349 28576/28576/20350 28577/28577/20343 +f 28571/28571/20122 28570/28570/20346 28578/28578/20341 +f 28571/28571/20122 28578/28578/20341 28579/28579/20123 +f 28580/28580/20119 28581/28581/20118 28582/28582/20351 +f 28580/28580/20119 28582/28582/20351 28583/28583/20352 +f 28581/28581/20118 28315/28315/20117 28584/28584/20146 +f 28581/28581/20118 28584/28584/20146 28582/28582/20351 +f 28585/28585/20353 28586/28586/20143 28587/28587/20142 +f 28585/28585/20353 28587/28587/20142 28588/28588/20354 +f 28589/28589/20355 28585/28585/20353 28588/28588/20354 +f 28589/28589/20355 28588/28588/20354 28590/28590/20355 +o Plane.015__0 +v -1.447546 -0.725134 -0.315809 +v -1.445357 -0.726759 -0.217955 +v -1.433124 -0.826782 -0.226117 +v -1.438285 -0.827383 -0.315809 +v -1.450756 -0.628376 -0.315809 +v -1.446577 -0.629869 -0.209792 +v -1.443669 -0.631662 -0.174548 +v -1.440839 -0.783277 -0.179867 +v -1.430723 -0.793405 -0.172718 +v -1.433784 -0.792962 -0.173262 +v -1.438483 -0.631354 -0.167600 +v -1.435576 -0.630973 -0.167027 +v -1.436781 -0.790882 -0.174812 +v -1.441041 -0.631618 -0.169230 +v -1.436781 -0.790882 -0.174812 +v -1.439258 -0.787481 -0.177131 +v -1.442863 -0.631727 -0.171670 +v -1.441041 -0.631618 -0.169230 +v -1.423268 -0.825213 -0.173584 +v -1.426144 -0.825671 -0.174156 +v -1.428634 -0.826068 -0.175782 +v -1.428634 -0.826068 -0.175782 +v -1.430360 -0.826343 -0.178217 +v -1.431058 -0.826454 -0.181088 +v -1.455536 -0.724636 -0.315802 +v -1.446286 -0.827629 -0.315797 +v -1.441119 -0.827131 -0.225904 +v -1.453350 -0.726327 -0.217947 +v -1.458608 -0.629935 -0.315808 +v -1.454469 -0.631207 -0.209854 +v -1.448682 -0.784029 -0.178451 +v -1.451509 -0.632804 -0.173400 +v -1.431305 -0.793685 -0.164738 +v -1.436204 -0.631440 -0.159060 +v -1.441343 -0.631993 -0.160150 +v -1.436553 -0.793332 -0.165760 +v -1.446317 -0.632524 -0.163278 +v -1.441940 -0.791405 -0.168713 +v -1.441940 -0.791405 -0.168713 +v -1.446317 -0.632524 -0.163278 +v -1.449878 -0.632776 -0.167958 +v -1.446198 -0.788146 -0.173197 +v -1.423988 -0.825367 -0.165613 +v -1.429087 -0.825874 -0.166714 +v -1.433852 -0.826296 -0.169716 +v -1.433852 -0.826296 -0.169716 +v -1.437289 -0.826650 -0.174219 +v -1.438895 -0.826840 -0.179503 +v -1.434889 -0.827383 -0.692585 +v -1.438285 -0.827383 -0.315809 +v -1.446286 -0.827629 -0.315797 +v -1.442892 -0.827584 -0.692595 +v -0.985358 -0.753358 -0.182551 +v -1.055063 -0.732684 -0.179435 +v -1.054832 -0.732865 -0.171435 +v -0.985136 -0.753443 -0.174550 +v -1.443669 -0.631662 -0.174548 +v -1.446577 -0.629869 -0.209792 +v -1.454469 -0.631207 -0.209854 +v -1.451509 -0.632804 -0.173400 +v -1.438483 -0.631354 -0.167600 +v -1.441041 -0.631618 -0.169230 +v -1.446317 -0.632524 -0.163278 +v -1.441343 -0.631993 -0.160150 +v -1.431058 -0.826454 -0.181088 +v -1.430360 -0.826343 -0.178217 +v -1.437289 -0.826650 -0.174219 +v -1.438895 -0.826840 -0.179503 +v -0.948974 -0.693798 -0.175732 +v -1.105040 -0.625642 -0.172190 +v -1.105004 -0.626103 -0.164208 +v -0.948711 -0.694257 -0.167744 +v -1.426144 -0.825671 -0.174156 +v -1.423268 -0.825213 -0.173584 +v -1.423988 -0.825367 -0.165613 +v -1.429087 -0.825874 -0.166714 +v -1.443489 -0.699935 -0.753188 +v -1.439184 -0.772605 -0.663132 +v -1.447164 -0.772411 -0.663134 +v -1.451454 -0.699713 -0.753173 +v -1.450756 -0.628376 -0.315809 +v -1.448141 -0.628239 -0.685378 +v -1.455982 -0.629851 -0.685350 +v -1.458608 -0.629935 -0.315808 +v -1.010635 -0.813539 -0.183149 +v -0.985358 -0.753358 -0.182551 +v -0.985136 -0.753443 -0.174550 +v -1.010414 -0.813625 -0.175148 +v -1.444772 -0.669180 -0.693588 +v -1.443489 -0.699935 -0.753188 +v -1.451454 -0.699713 -0.753173 +v -1.452704 -0.669803 -0.693561 +v -1.442863 -0.631727 -0.171670 +v -1.449878 -0.632776 -0.167958 +v -1.433124 -0.826782 -0.226117 +v -1.441119 -0.827131 -0.225904 +v -1.428634 -0.826068 -0.175782 +v -1.433852 -0.826296 -0.169716 +v -1.439184 -0.772605 -0.663132 +v -1.434889 -0.827383 -0.692585 +v -1.442892 -0.827584 -0.692595 +v -1.447164 -0.772411 -0.663134 +v -1.435576 -0.630973 -0.167027 +v -1.436204 -0.631440 -0.159060 +v -1.448141 -0.628239 -0.685378 +v -1.444772 -0.669180 -0.693588 +v -1.452704 -0.669803 -0.693561 +v -1.455982 -0.629851 -0.685350 +v -1.010635 -0.813539 -0.183149 +v -1.010414 -0.813625 -0.175148 +v -1.055063 -0.732684 -0.179435 +v -0.948974 -0.693798 -0.175732 +v -0.948711 -0.694257 -0.167744 +v -1.054832 -0.732865 -0.171435 +v -1.055063 -0.732684 -0.179435 +v -0.985358 -0.753358 -0.182551 +v -1.010635 -0.813539 -0.183149 +v -1.105040 -0.625642 -0.172190 +v -0.948974 -0.693798 -0.175732 +v -1.443489 -0.699935 -0.753188 +v -1.444772 -0.669180 -0.693588 +v -1.448141 -0.628239 -0.685378 +v -1.434889 -0.827383 -0.692585 +v -1.439184 -0.772605 -0.663132 +v -1.010414 -0.813625 -0.175148 +v -0.985136 -0.753443 -0.174550 +v -1.054832 -0.732865 -0.171435 +v -0.948711 -0.694257 -0.167744 +v -1.105004 -0.626103 -0.164208 +v -1.455982 -0.629851 -0.685350 +v -1.452704 -0.669803 -0.693561 +v -1.451454 -0.699713 -0.753173 +v -1.447164 -0.772411 -0.663134 +v -1.442892 -0.827584 -0.692595 +vt 0.211156 0.336678 +vt 0.211156 0.341068 +vt 0.211747 0.341090 +vt 0.211747 0.336699 +vt 0.976185 0.190067 +vt 0.976061 0.182842 +vt 0.968636 0.183388 +vt 0.968604 0.190030 +vt 0.983346 0.190067 +vt 0.983226 0.182230 +vt 0.983087 0.179615 +vt 0.971872 0.180019 +vt 0.621327 0.018027 +vt 0.621293 0.017797 +vt 0.609385 0.017573 +vt 0.609358 0.017792 +vt 0.621150 0.017559 +vt 0.609415 0.017365 +vt 0.971300 0.179623 +vt 0.971557 0.179808 +vt 0.983080 0.179398 +vt 0.983084 0.179207 +vt 0.623681 0.018550 +vt 0.623715 0.018333 +vt 0.623755 0.018130 +vt 0.968678 0.179651 +vt 0.968662 0.179842 +vt 0.968656 0.180057 +vt 0.720121 0.056195 +vt 0.712472 0.056195 +vt 0.712474 0.062849 +vt 0.719980 0.063413 +vt 0.727119 0.056232 +vt 0.726996 0.064061 +vt 0.715697 0.066318 +vt 0.726859 0.066764 +vt 0.982144 0.770708 +vt 0.970134 0.770790 +vt 0.970169 0.771179 +vt 0.982111 0.771102 +vt 0.970211 0.771592 +vt 0.981970 0.771539 +vt 0.715110 0.067076 +vt 0.726846 0.067545 +vt 0.726850 0.067176 +vt 0.715377 0.066719 +vt 0.984502 0.770231 +vt 0.984533 0.770617 +vt 0.984567 0.771012 +vt 0.712488 0.067036 +vt 0.712483 0.066681 +vt 0.712480 0.066281 +vt 0.687555 0.107170 +vt 0.669539 0.085911 +vt 0.669084 0.086288 +vt 0.687101 0.107548 +vt 0.589981 0.773266 +vt 0.589981 0.778367 +vt 0.590573 0.778379 +vt 0.590573 0.773278 +vt 0.858656 0.625929 +vt 0.860325 0.623918 +vt 0.859908 0.623504 +vt 0.858180 0.625582 +vt 0.858572 0.626565 +vt 0.858520 0.626346 +vt 0.857932 0.626387 +vt 0.858035 0.626810 +vt 0.663581 0.077909 +vt 0.663485 0.077712 +vt 0.662902 0.077812 +vt 0.663060 0.078189 +vt 0.884808 0.651237 +vt 0.876465 0.643536 +vt 0.876054 0.643959 +vt 0.884409 0.651672 +vt 0.663535 0.077280 +vt 0.663673 0.077110 +vt 0.663255 0.076691 +vt 0.663015 0.076996 +vt 0.211747 0.354104 +vt 0.211747 0.347463 +vt 0.211161 0.347447 +vt 0.211162 0.354087 +vt 0.865581 0.618094 +vt 0.884808 0.598669 +vt 0.884389 0.598262 +vt 0.865163 0.617686 +vt 0.279537 0.332795 +vt 0.279537 0.337224 +vt 0.280125 0.337221 +vt 0.280125 0.332792 +vt 0.858550 0.626122 +vt 0.857985 0.625955 +vt 0.665592 0.080567 +vt 0.665127 0.080933 +vt 0.663469 0.077491 +vt 0.662885 0.077393 +vt 0.279543 0.328382 +vt 0.279542 0.332694 +vt 0.280125 0.332704 +vt 0.280125 0.328363 +vt 0.858696 0.626746 +vt 0.858251 0.627134 +vt 0.524605 0.776086 +vt 0.524605 0.772997 +vt 0.524027 0.772991 +vt 0.524030 0.776008 +vt 0.687555 0.058178 +vt 0.687188 0.057713 +vt 0.211156 0.361564 +vt 0.211157 0.369646 +vt 0.211747 0.369682 +vt 0.211747 0.361600 +vt 0.623755 0.048472 +vt 0.617703 0.045307 +vt 0.619390 0.050336 +vt 0.609686 0.041792 +vt 0.615032 0.053090 +vt 0.978034 0.222268 +vt 0.980311 0.217878 +vt 0.983346 0.217286 +vt 0.968592 0.217774 +vt 0.972652 0.215619 +vt 0.978495 0.743727 +vt 0.984567 0.740687 +vt 0.980177 0.738799 +vt 0.970476 0.747092 +vt 0.975857 0.736002 +vt 0.721944 0.024037 +vt 0.724155 0.028436 +vt 0.727119 0.029043 +vt 0.712465 0.028477 +vt 0.716557 0.030651 +vn 0.9217 -0.3868 -0.0296 +vn 0.9979 0.0636 -0.0117 +vn 0.9973 0.0564 -0.0479 +vn 0.9918 0.1277 -0.0091 +vn 0.9955 0.0942 -0.0133 +vn 0.9994 0.0328 -0.0100 +vn 0.9980 0.0224 -0.0585 +vn 0.9730 0.0269 -0.2292 +vn 0.9802 0.0989 -0.1713 +vn 0.0885 0.0485 -0.9949 +vn 0.3699 0.0870 -0.9250 +vn 0.3413 0.0426 -0.9390 +vn 0.0809 0.0438 -0.9958 +vn 0.6705 0.1218 -0.7319 +vn 0.6346 0.0437 -0.7716 +vn 0.6706 0.1218 -0.7318 +vn 0.8823 0.1352 -0.4509 +vn 0.8524 0.0377 -0.5215 +vn 0.0716 0.0483 -0.9963 +vn 0.3569 0.1085 -0.9278 +vn 0.6717 0.1751 -0.7199 +vn 0.6712 0.1771 -0.7199 +vn 0.8884 0.2146 -0.4058 +vn 0.9772 0.1876 -0.0994 +vn -0.9979 -0.0630 0.0115 +vn -0.9955 -0.0935 0.0132 +vn -0.9918 -0.1272 0.0100 +vn -0.9973 -0.0560 0.0479 +vn -0.9994 -0.0321 0.0099 +vn -0.9981 -0.0218 0.0584 +vn -0.9804 -0.1078 0.1651 +vn -0.9754 -0.0263 0.2190 +vn -0.0964 -0.0494 0.9941 +vn -0.0886 -0.0439 0.9951 +vn -0.3508 -0.0427 0.9355 +vn -0.3713 -0.0831 0.9248 +vn -0.6420 -0.0435 0.7655 +vn -0.6609 -0.1162 0.7414 +vn -0.8619 -0.0372 0.5057 +vn -0.8736 -0.1315 0.4686 +vn -0.0768 -0.0498 0.9958 +vn -0.3524 -0.1079 0.9296 +vn -0.6501 -0.1714 0.7403 +vn -0.8671 -0.2122 0.4506 +vn -0.9734 -0.1883 0.1305 +vn 0.0280 -0.9996 0.0002 +vn 0.0327 -0.9995 0.0021 +vn 0.0324 -0.9995 0.0021 +vn 0.0279 -0.9996 0.0002 +vn 0.2841 0.9588 0.0079 +vn -0.1416 0.9886 0.0509 +vn -0.1658 0.9853 0.0403 +vn -0.1669 0.9852 0.0387 +vn -0.1420 0.9885 0.0513 +vn -0.1259 0.9912 0.0398 +vn -0.1257 0.9913 0.0401 +vn -0.1258 0.9913 0.0398 +vn 0.0508 -0.9986 0.0127 +vn 0.0638 -0.9976 0.0281 +vn 0.0646 -0.9975 0.0288 +vn 0.0511 -0.9986 0.0129 +vn 0.4004 0.9152 0.0452 +vn 0.1975 0.9789 0.0526 +vn 0.1967 0.9790 0.0526 +vn 0.1073 -0.9941 0.0157 +vn 0.0735 -0.9973 -0.0045 +vn 0.0736 -0.9973 -0.0045 +vn 0.1074 -0.9941 0.0156 +vn -0.0208 -0.7785 -0.6274 +vn -0.1895 0.9818 0.0095 +vn -0.1981 0.9802 -0.0011 +vn -0.1896 0.9818 0.0093 +vn -0.0237 0.8908 -0.4538 +vn -0.1279 0.9908 0.0432 +vn -0.1278 0.9909 0.0432 +vn 0.0421 -0.9991 0.0043 +vn 0.0421 -0.9991 0.0042 +vn 0.0843 -0.9960 0.0310 +vn 0.0849 -0.9959 0.0308 +vn 0.0005 0.4723 -0.8814 +vn -0.0699 0.9963 0.0502 +vn -0.0692 0.9963 0.0504 +vn -0.0313 0.1964 -0.9800 +vn -0.0312 0.1964 -0.9800 +vn 0.0280 -0.9995 -0.0141 +vn 0.3441 -0.9377 -0.0481 +vn 0.3441 -0.9377 -0.0482 +vn -0.0247 0.0295 -0.9993 +vn -0.0208 0.0386 -0.9990 +vn -0.0173 0.0471 -0.9987 +vn 0.9980 0.0628 0.0112 +vn 0.9991 0.0413 0.0107 +vn 0.9966 0.0812 0.0117 +vn 0.0208 -0.0387 0.9990 +vn 0.0246 -0.0296 0.9993 +vn 0.0173 -0.0470 0.9987 +vn -0.9980 -0.0624 -0.0112 +vn -0.9991 -0.0407 -0.0107 +vn -0.9967 -0.0806 -0.0117 +usemtl Scene_-_Root +s off +f 28675/28591/20356 28676/28592/20356 28677/28593/20356 +f 28675/28591/20356 28677/28593/20356 28678/28594/20356 +s 1 +f 28591/28595/20357 28592/28596/20358 28593/28597/20359 +f 28591/28595/20357 28593/28597/20359 28594/28598/20360 +f 28595/28599/20361 28596/28600/20362 28592/28596/20358 +f 28595/28599/20361 28592/28596/20358 28591/28595/20357 +f 28596/28600/20362 28597/28601/20363 28598/28602/20364 +f 28596/28600/20362 28598/28602/20364 28592/28596/20358 +f 28599/28603/20365 28600/28604/20366 28601/28605/20367 +f 28599/28603/20365 28601/28605/20367 28602/28606/20368 +f 28600/28604/20366 28603/28607/20369 28604/28608/20370 +f 28600/28604/20366 28604/28608/20370 28601/28605/20367 +f 28605/28609/20371 28606/28610/20372 28607/28611/20373 +f 28605/28609/20371 28607/28611/20373 28608/28612/20370 +f 28606/28610/20372 28598/28602/20364 28597/28601/20363 +f 28606/28610/20372 28597/28601/20363 28607/28611/20373 +f 28609/28613/20374 28610/28614/20375 28600/28604/20366 +f 28609/28613/20374 28600/28604/20366 28599/28603/20365 +f 28610/28614/20375 28611/28615/20376 28603/28607/20369 +f 28610/28614/20375 28603/28607/20369 28600/28604/20366 +f 28612/28616/20377 28613/28617/20378 28606/28610/20372 +f 28612/28616/20377 28606/28610/20372 28605/28609/20371 +f 28613/28617/20378 28614/28618/20379 28598/28602/20364 +f 28613/28617/20378 28598/28602/20364 28606/28610/20372 +f 28592/28596/20358 28598/28602/20364 28614/28618/20379 +f 28592/28596/20358 28614/28618/20379 28593/28597/20359 +f 28615/28619/20380 28616/28620/20381 28617/28621/20382 +f 28615/28619/20380 28617/28621/20382 28618/28622/20383 +f 28619/28623/20384 28615/28619/20380 28618/28622/20383 +f 28619/28623/20384 28618/28622/20383 28620/28624/20385 +f 28620/28624/20385 28618/28622/20383 28621/28625/20386 +f 28620/28624/20385 28621/28625/20386 28622/28626/20387 +f 28623/28627/20388 28624/28628/20389 28625/28629/20390 +f 28623/28627/20388 28625/28629/20390 28626/28630/20391 +f 28626/28630/20391 28625/28629/20390 28627/28631/20392 +f 28626/28630/20391 28627/28631/20392 28628/28632/20393 +f 28629/28633/20393 28630/28634/20392 28631/28635/20394 +f 28629/28633/20393 28631/28635/20394 28632/28636/20395 +f 28632/28636/20395 28631/28635/20394 28622/28626/20387 +f 28632/28636/20395 28622/28626/20387 28621/28625/20386 +f 28633/28637/20396 28623/28627/20388 28626/28630/20391 +f 28633/28637/20396 28626/28630/20391 28634/28638/20397 +f 28634/28638/20397 28626/28630/20391 28628/28632/20393 +f 28634/28638/20397 28628/28632/20393 28635/28639/20398 +f 28636/28640/20398 28629/28633/20393 28632/28636/20395 +f 28636/28640/20398 28632/28636/20395 28637/28641/20399 +f 28637/28641/20399 28632/28636/20395 28621/28625/20386 +f 28637/28641/20399 28621/28625/20386 28638/28642/20400 +f 28618/28622/20383 28617/28621/20382 28638/28642/20400 +f 28618/28622/20383 28638/28642/20400 28621/28625/20386 +f 28639/28643/20401 28640/28644/20402 28641/28645/20403 +f 28639/28643/20401 28641/28645/20403 28642/28646/20404 +f 28643/28647/20405 28644/28648/20405 28645/28649/20405 +f 28643/28647/20405 28645/28649/20405 28646/28650/20405 +f 28647/28651/20406 28648/28652/20407 28649/28653/20408 +f 28647/28651/20406 28649/28653/20408 28650/28654/20409 +f 28651/28655/20410 28652/28656/20411 28653/28657/20412 +f 28651/28655/20410 28653/28657/20412 28654/28658/20410 +f 28655/28659/20413 28656/28660/20414 28657/28661/20415 +f 28655/28659/20413 28657/28661/20415 28658/28662/20416 +f 28659/28663/20417 28660/28664/20418 28661/28665/20419 +f 28659/28663/20417 28661/28665/20419 28662/28666/20417 +f 28663/28667/20420 28664/28668/20421 28665/28669/20422 +f 28663/28667/20420 28665/28669/20422 28666/28670/20423 +f 28667/28671/20424 28668/28672/20424 28669/28673/20424 +f 28667/28671/20424 28669/28673/20424 28670/28674/20424 +f 28671/28675/20425 28672/28676/20426 28673/28677/20426 +f 28671/28675/20425 28673/28677/20426 28674/28678/20427 +f 28679/28679/20428 28680/28680/20428 28681/28681/20428 +f 28679/28679/20428 28681/28681/20428 28682/28682/20428 +f 28652/28656/20411 28683/28683/20429 28684/28684/20430 +f 28652/28656/20411 28684/28684/20430 28653/28657/20412 +f 28685/28685/20431 28655/28659/20413 28658/28662/20416 +f 28685/28685/20431 28658/28662/20416 28686/28686/20432 +f 28640/28644/20402 28685/28685/20431 28686/28686/20432 +f 28640/28644/20402 28686/28686/20432 28641/28645/20403 +f 28687/28687/20433 28663/28667/20420 28666/28670/20423 +f 28687/28687/20433 28666/28670/20423 28688/28688/20434 +f 28689/28689/20435 28690/28690/20435 28691/28691/20435 +f 28689/28689/20435 28691/28691/20435 28692/28692/20435 +f 28648/28652/20407 28671/28675/20425 28674/28678/20427 +f 28648/28652/20407 28674/28678/20427 28649/28653/20408 +f 28693/28693/20436 28651/28655/20410 28654/28658/20410 +f 28693/28693/20436 28654/28658/20410 28694/28694/20437 +f 28695/28695/20438 28696/28696/20439 28697/28697/20439 +f 28695/28695/20438 28697/28697/20439 28698/28698/20438 +f 28664/28668/20421 28699/28699/20440 28700/28700/20440 +f 28664/28668/20421 28700/28700/20440 28665/28669/20422 +f 28656/28660/20414 28687/28687/20433 28688/28688/20434 +f 28656/28660/20414 28688/28688/20434 28657/28661/20415 +f 28701/28701/20441 28702/28702/20442 28703/28703/20442 +f 28701/28701/20441 28703/28703/20442 28704/28704/20442 +f 28683/28683/20429 28647/28651/20406 28650/28654/20409 +f 28683/28683/20429 28650/28654/20409 28684/28684/20430 +f 28660/28664/20418 28693/28693/20436 28694/28694/20437 +f 28660/28664/20418 28694/28694/20437 28661/28665/20419 +f 28707/28705/20443 28705/28706/20444 28706/28707/20443 +f 28705/28706/20444 28707/28705/20443 28609/28613/20374 +f 28705/28706/20444 28609/28613/20374 28599/28603/20365 +f 28705/28706/20444 28708/28708/20445 28709/28709/20445 +f 28708/28708/20445 28705/28706/20444 28599/28603/20365 +f 28708/28708/20445 28599/28603/20365 28602/28606/20368 +f 28710/28710/20446 28595/28599/20361 28591/28595/20357 +f 28595/28599/20361 28710/28710/20446 28711/28711/20447 +f 28595/28599/20361 28711/28711/20447 28712/28712/20447 +f 28713/28713/20448 28591/28595/20357 28594/28598/20360 +f 28591/28595/20357 28713/28713/20448 28714/28714/20448 +f 28591/28595/20357 28714/28714/20448 28710/28710/20446 +f 28717/28715/20449 28715/28716/20450 28716/28717/20450 +f 28715/28716/20450 28717/28715/20449 28633/28637/20396 +f 28633/28637/20396 28717/28715/20449 28623/28627/20388 +f 28719/28718/20451 28717/28715/20449 28718/28719/20451 +f 28717/28715/20449 28719/28718/20451 28623/28627/20388 +f 28623/28627/20388 28719/28718/20451 28624/28628/20389 +f 28619/28623/20384 28722/28720/20452 28615/28619/20380 +f 28722/28720/20452 28619/28623/20384 28721/28721/20453 +f 28721/28721/20453 28619/28623/20384 28720/28722/20453 +f 28615/28619/20380 28724/28723/20454 28616/28620/20381 +f 28724/28723/20454 28615/28619/20380 28723/28724/20454 +f 28723/28724/20454 28615/28619/20380 28722/28720/20452 +o Cube.046__0 +v -0.285534 0.086008 -0.130926 +v -0.402460 0.260785 -0.120087 +v -0.402460 0.262539 -0.148374 +v -0.285534 0.087762 -0.159212 +v -0.285534 0.087762 -0.159212 +v -0.402460 0.262539 -0.148374 +v -0.249910 0.364204 -0.142069 +v -0.132984 0.189428 -0.152907 +v -0.132984 0.189428 -0.152907 +v -0.249910 0.364204 -0.142069 +v -0.249910 0.362450 -0.113783 +v -0.132984 0.187673 -0.124621 +v -0.153460 0.190213 -0.110753 +v -0.254624 0.341429 -0.101376 +v -0.381984 0.256552 -0.106639 +v -0.280820 0.105335 -0.116017 +v -0.249910 0.362450 -0.113783 +v -0.249910 0.364204 -0.142069 +v -0.281178 0.360682 -0.142287 +v -0.281178 0.358928 -0.114001 +v -0.132984 0.187673 -0.124621 +v -0.285534 0.086008 -0.130926 +v -0.254266 0.089530 -0.130707 +v -0.148228 0.160198 -0.126325 +v -0.280820 0.105335 -0.116017 +v -0.381984 0.256552 -0.106639 +v -0.402460 0.260785 -0.120087 +v -0.285534 0.086008 -0.130926 +v -0.254624 0.341429 -0.101376 +v -0.153460 0.190213 -0.110753 +v -0.132984 0.187673 -0.124621 +v -0.249910 0.362450 -0.113783 +v -0.153460 0.190213 -0.110753 +v -0.280820 0.105335 -0.116017 +v -0.285534 0.086008 -0.130926 +v -0.132984 0.187673 -0.124621 +v -0.381984 0.256552 -0.106639 +v -0.254624 0.341429 -0.101376 +v -0.249910 0.362450 -0.113783 +v -0.402460 0.260785 -0.120087 +v -0.387217 0.290014 -0.146670 +v -0.387217 0.288260 -0.118383 +v -0.402123 0.310541 -0.117002 +v -0.402123 0.312295 -0.145288 +v -0.281178 0.360682 -0.142287 +v -0.387217 0.290014 -0.146670 +v -0.402123 0.312295 -0.145288 +v -0.296084 0.382964 -0.140906 +v -0.148228 0.161952 -0.154611 +v -0.254266 0.091285 -0.158993 +v -0.402460 0.262539 -0.148374 +v -0.402460 0.260785 -0.120087 +v -0.387217 0.288260 -0.118383 +v -0.387217 0.290014 -0.146670 +v -0.402460 0.260785 -0.120087 +v -0.249910 0.362450 -0.113783 +v -0.281178 0.358928 -0.114001 +v -0.387217 0.288260 -0.118383 +v -0.285534 0.086008 -0.130926 +v -0.285534 0.087762 -0.159212 +v -0.254266 0.091285 -0.158993 +v -0.254266 0.089530 -0.130707 +v -0.132984 0.189428 -0.152907 +v -0.132984 0.187673 -0.124621 +v -0.148228 0.160198 -0.126325 +v -0.148228 0.161952 -0.154611 +v -0.296084 0.381209 -0.112620 +v -0.296084 0.382964 -0.140906 +v -0.330746 0.409395 -0.139266 +v -0.330746 0.407641 -0.110980 +v -0.402123 0.310541 -0.117002 +v -0.296084 0.381209 -0.112620 +v -0.330746 0.407641 -0.110980 +v -0.413298 0.352625 -0.114392 +v -0.239360 0.067249 -0.132089 +v -0.133321 0.137917 -0.127707 +v -0.148228 0.161952 -0.154611 +v -0.148228 0.160198 -0.126325 +v -0.133321 0.137917 -0.127707 +v -0.133321 0.139671 -0.155993 +v -0.133321 0.139671 -0.155993 +v -0.239360 0.069003 -0.160375 +v -0.254266 0.089530 -0.130707 +v -0.254266 0.091285 -0.158993 +v -0.239360 0.069003 -0.160375 +v -0.239360 0.067249 -0.132089 +v -0.281178 0.358928 -0.114001 +v -0.281178 0.360682 -0.142287 +v -0.204698 0.042571 -0.162014 +v -0.122146 0.097588 -0.158602 +v -0.133818 0.069089 -0.160370 +v -0.173852 0.042409 -0.162024 +v -0.122146 0.097588 -0.158602 +v -0.122146 0.095833 -0.130316 +v -0.133818 0.067335 -0.132084 +v -0.133818 0.069089 -0.160370 +v -0.413298 0.354379 -0.142678 +v -0.330746 0.409395 -0.139266 +v -0.413298 0.352625 -0.114392 +v -0.413298 0.354379 -0.142678 +v -0.204698 0.040817 -0.133728 +v -0.122146 0.095833 -0.130316 +v -0.122146 0.095833 -0.130316 +v -0.122146 0.097588 -0.158602 +v -0.204698 0.042571 -0.162014 +v -0.204698 0.040817 -0.133728 +v -0.173852 0.042409 -0.162024 +v -0.173852 0.040655 -0.133738 +v -0.361592 0.409558 -0.139256 +v -0.401626 0.382878 -0.140911 +v -0.401626 0.381124 -0.112625 +v -0.361592 0.407804 -0.110970 +v -0.204698 0.040817 -0.133728 +v -0.204698 0.042571 -0.162014 +v -0.361592 0.407804 -0.110970 +v -0.401626 0.381124 -0.112625 +v -0.330746 0.407641 -0.110980 +v -0.330746 0.409395 -0.139266 +v -0.401626 0.382878 -0.140911 +v -0.361592 0.409558 -0.139256 +v -0.413298 0.354379 -0.142678 +v -0.413298 0.352625 -0.114392 +v -0.173852 0.040655 -0.133738 +v -0.133818 0.067335 -0.132084 +v -0.406666 0.313753 0.118985 +v -0.395992 0.320867 0.119426 +v -0.403391 0.336072 0.053258 +v -0.414065 0.328959 0.052817 +v -0.385596 0.294065 -0.073352 +v -0.374922 0.301179 -0.072911 +v -0.343390 0.256393 -0.113703 +v -0.354064 0.249279 -0.114144 +v -0.306194 0.201619 -0.130449 +v -0.316868 0.194505 -0.130890 +v -0.268998 0.145196 -0.120599 +v -0.279672 0.138082 -0.121040 +v -0.237465 0.095713 -0.085652 +v -0.248139 0.088599 -0.086093 +v -0.248139 0.088599 -0.086093 +v -0.237465 0.095713 -0.085652 +v -0.216396 0.060704 -0.030929 +v -0.227070 0.053591 -0.031370 +v -0.208997 0.045499 0.035239 +v -0.219671 0.038386 0.034798 +v -0.216396 0.052413 0.102778 +v -0.227070 0.045299 0.102337 +v -0.237465 0.080392 0.161407 +v -0.248139 0.073278 0.160966 +v -0.248139 0.073278 0.160966 +v -0.237465 0.080392 0.161407 +v -0.268998 0.125178 0.202200 +v -0.279672 0.118064 0.201759 +v -0.306194 0.179952 0.218946 +v -0.316868 0.172838 0.218505 +v -0.343390 0.236376 0.209095 +v -0.354064 0.229262 0.208654 +v -0.374922 0.285858 0.174149 +v -0.385596 0.278745 0.173707 +v -0.385596 0.278745 0.173707 +v -0.374922 0.285858 0.174149 +v -0.285054 0.340358 0.101397 +v -0.270024 0.315385 0.140434 +v -0.365896 0.251492 0.136472 +v -0.380925 0.276466 0.097435 +v -0.318119 0.365680 0.119701 +v -0.325242 0.380317 0.056002 +v -0.399765 0.330652 0.052922 +v -0.392642 0.316015 0.116621 +v -0.395992 0.329158 -0.014282 +v -0.406666 0.322045 -0.014723 +v -0.290333 0.351204 0.054196 +v -0.386203 0.287312 0.050234 +v -0.380925 0.282380 0.002055 +v -0.386203 0.287312 0.050234 +v -0.414065 0.328959 0.052817 +v -0.406666 0.322045 -0.014723 +v -0.290333 0.351204 0.054196 +v -0.285055 0.346272 0.006017 +v -0.310796 0.385937 -0.010761 +v -0.318193 0.392851 0.056779 +v -0.365895 0.262421 -0.039768 +v -0.385596 0.294065 -0.073352 +v -0.270025 0.326313 -0.035806 +v -0.289726 0.357957 -0.069390 +v -0.343401 0.230473 -0.068868 +v -0.354064 0.249279 -0.114144 +v -0.247531 0.294365 -0.064906 +v -0.258193 0.313171 -0.110182 +v -0.316868 0.191400 -0.080813 +v -0.316868 0.194505 -0.130890 +v -0.220997 0.255292 -0.076851 +v -0.220997 0.258397 -0.126928 +v -0.290334 0.151150 -0.073786 +v -0.279672 0.138082 -0.121040 +v -0.194464 0.215042 -0.069824 +v -0.183802 0.201974 -0.117078 +v -0.267840 0.115852 -0.048857 +v -0.248139 0.088599 -0.086093 +v -0.171970 0.179744 -0.044895 +v -0.152269 0.152491 -0.082131 +v -0.252810 0.090878 -0.009821 +v -0.227070 0.053591 -0.031370 +v -0.156940 0.154770 -0.005859 +v -0.131199 0.117482 -0.027408 +v -0.247533 0.080032 0.037380 +v -0.219671 0.038386 0.034798 +v -0.151662 0.143924 0.041342 +v -0.123801 0.102278 0.038760 +v -0.252810 0.084964 0.085560 +v -0.227070 0.045299 0.102337 +v -0.156940 0.148855 0.089522 +v -0.131199 0.109191 0.106299 +v -0.267840 0.104923 0.127383 +v -0.248139 0.073278 0.160966 +v -0.171970 0.168815 0.131345 +v -0.152269 0.137170 0.164928 +v -0.290334 0.136871 0.156482 +v -0.279672 0.118064 0.201759 +v -0.194464 0.200763 0.160444 +v -0.183802 0.181956 0.205721 +v -0.316868 0.175944 0.168428 +v -0.316868 0.172838 0.218505 +v -0.220997 0.239836 0.172390 +v -0.220996 0.236731 0.222467 +v -0.343401 0.216193 0.161401 +v -0.354064 0.229262 0.208654 +v -0.247530 0.280086 0.165363 +v -0.258192 0.293154 0.212616 +v -0.365896 0.251492 0.136472 +v -0.385596 0.278745 0.173707 +v -0.270024 0.315385 0.140434 +v -0.289725 0.342637 0.177670 +v -0.380925 0.276466 0.097435 +v -0.406666 0.313753 0.118985 +v -0.285054 0.340358 0.101397 +v -0.310795 0.377645 0.122947 +v -0.270024 0.315385 0.140434 +v -0.247530 0.280086 0.165363 +v -0.343401 0.216193 0.161401 +v -0.365896 0.251492 0.136472 +v -0.220997 0.239836 0.172390 +v -0.316868 0.175944 0.168428 +v -0.194464 0.200763 0.160444 +v -0.290334 0.136871 0.156482 +v -0.171970 0.168815 0.131345 +v -0.267840 0.104923 0.127383 +v -0.171970 0.168815 0.131345 +v -0.156940 0.148855 0.089522 +v -0.252810 0.084964 0.085560 +v -0.267840 0.104923 0.127383 +v -0.151662 0.143924 0.041342 +v -0.247533 0.080032 0.037380 +v -0.156940 0.154770 -0.005859 +v -0.252810 0.090878 -0.009821 +v -0.171970 0.179744 -0.044895 +v -0.267840 0.115852 -0.048857 +v -0.171970 0.179744 -0.044895 +v -0.194464 0.215042 -0.069824 +v -0.290334 0.151150 -0.073786 +v -0.267840 0.115852 -0.048857 +v -0.220997 0.255292 -0.076851 +v -0.316868 0.191400 -0.080813 +v -0.247531 0.294365 -0.064906 +v -0.343401 0.230473 -0.068868 +v -0.270025 0.326313 -0.035806 +v -0.365895 0.262421 -0.039768 +v -0.270025 0.326313 -0.035806 +v -0.285055 0.346272 0.006017 +v -0.380925 0.282380 0.002055 +v -0.365895 0.262421 -0.039768 +v -0.374922 0.301179 -0.072911 +v -0.385596 0.294065 -0.073352 +v -0.300399 0.335523 0.177228 +v -0.289725 0.342637 0.177670 +v -0.310795 0.377645 0.122947 +v -0.321469 0.370532 0.122506 +v -0.268867 0.286041 0.212175 +v -0.258192 0.293154 0.212616 +v -0.289725 0.342637 0.177670 +v -0.300399 0.335523 0.177228 +v -0.231671 0.229617 0.222026 +v -0.220996 0.236731 0.222467 +v -0.194475 0.174843 0.205280 +v -0.183802 0.181956 0.205721 +v -0.162942 0.130057 0.164487 +v -0.152269 0.137170 0.164928 +v -0.141873 0.102078 0.105858 +v -0.131199 0.109191 0.106299 +v -0.152269 0.137170 0.164928 +v -0.162942 0.130057 0.164487 +v -0.134474 0.095164 0.038319 +v -0.123801 0.102278 0.038760 +v -0.141873 0.110369 -0.027849 +v -0.131199 0.117482 -0.027408 +v -0.162942 0.145378 -0.082572 +v -0.152269 0.152491 -0.082131 +v -0.194475 0.194861 -0.117519 +v -0.183802 0.201974 -0.117078 +v -0.152269 0.152491 -0.082131 +v -0.162942 0.145378 -0.082572 +v -0.231671 0.251284 -0.127369 +v -0.220997 0.258397 -0.126928 +v -0.268867 0.306058 -0.110623 +v -0.258193 0.313171 -0.110182 +v -0.300399 0.350844 -0.069831 +v -0.289726 0.357957 -0.069390 +v -0.321469 0.378823 -0.011202 +v -0.310796 0.385937 -0.010761 +v -0.289726 0.357957 -0.069390 +v -0.300399 0.350844 -0.069831 +v -0.328868 0.385737 0.056338 +v -0.318193 0.392851 0.056779 +v -0.162942 0.145378 -0.082572 +v -0.141873 0.110369 -0.027849 +v -0.145223 0.115222 -0.025045 +v -0.165506 0.148924 -0.077727 +v -0.343390 0.256393 -0.113703 +v -0.374922 0.301179 -0.072911 +v -0.372359 0.297061 -0.068540 +v -0.342002 0.253946 -0.107811 +v -0.306194 0.179952 0.218946 +v -0.268998 0.125178 0.202200 +v -0.270386 0.127625 0.196308 +v -0.306194 0.180356 0.212429 +v -0.321469 0.370532 0.122506 +v -0.328868 0.385737 0.056338 +v -0.325242 0.380317 0.056002 +v -0.318119 0.365680 0.119701 +v -0.300399 0.350844 -0.069831 +v -0.268867 0.306058 -0.110623 +v -0.267479 0.303611 -0.104732 +v -0.297836 0.346726 -0.065460 +v -0.194475 0.174843 0.205280 +v -0.231671 0.229617 0.222026 +v -0.231671 0.230021 0.215509 +v -0.195863 0.177290 0.199388 +v -0.208997 0.045499 0.035239 +v -0.216396 0.060704 -0.030929 +v -0.219746 0.065557 -0.028125 +v -0.212623 0.050919 0.035575 +v -0.134474 0.095164 0.038319 +v -0.138100 0.100584 0.038655 +v -0.306194 0.201619 -0.130449 +v -0.306194 0.201215 -0.123932 +v -0.343390 0.236376 0.209095 +v -0.342002 0.234675 0.202946 +v -0.231671 0.251284 -0.127369 +v -0.231671 0.250880 -0.120852 +v -0.268867 0.286041 0.212175 +v -0.267479 0.284340 0.206026 +v -0.216396 0.052413 0.102778 +v -0.219745 0.057574 0.100595 +v -0.141873 0.102078 0.105858 +v -0.145222 0.107239 0.103675 +v -0.268998 0.145196 -0.120599 +v -0.270386 0.146896 -0.114450 +v -0.374922 0.285858 0.174149 +v -0.372359 0.282312 0.169303 +v -0.297836 0.331977 0.172383 +v -0.372359 0.282312 0.169303 +v -0.267479 0.284340 0.206026 +v -0.297836 0.331977 0.172383 +v -0.372359 0.282312 0.169303 +v -0.342002 0.234675 0.202946 +v -0.231671 0.230021 0.215509 +v -0.306194 0.180356 0.212429 +v -0.195863 0.177290 0.199388 +v -0.270386 0.127625 0.196308 +v -0.165506 0.134175 0.160117 +v -0.240029 0.084510 0.157037 +v -0.145222 0.107239 0.103675 +v -0.165506 0.134175 0.160117 +v -0.240029 0.084510 0.157037 +v -0.219745 0.057574 0.100595 +v -0.138100 0.100584 0.038655 +v -0.212623 0.050919 0.035575 +v -0.145223 0.115222 -0.025045 +v -0.219746 0.065557 -0.028125 +v -0.165506 0.148924 -0.077727 +v -0.240029 0.099259 -0.080806 +v -0.195863 0.196561 -0.111370 +v -0.165506 0.148924 -0.077727 +v -0.240029 0.099259 -0.080806 +v -0.270386 0.146896 -0.114450 +v -0.231671 0.250880 -0.120852 +v -0.306194 0.201215 -0.123932 +v -0.267479 0.303611 -0.104732 +v -0.342002 0.253946 -0.107811 +v -0.297836 0.346726 -0.065460 +v -0.372359 0.297061 -0.068540 +v -0.318119 0.373662 -0.009018 +v -0.297836 0.346726 -0.065460 +v -0.372359 0.297061 -0.068540 +v -0.392642 0.323997 -0.012098 +v -0.403391 0.336072 0.053258 +v -0.395992 0.320867 0.119426 +v -0.392642 0.316015 0.116621 +v -0.399765 0.330652 0.052922 +v -0.237465 0.095713 -0.085652 +v -0.240029 0.099259 -0.080806 +v -0.162942 0.130057 0.164487 +v -0.165506 0.134175 0.160117 +v -0.321469 0.378823 -0.011202 +v -0.318119 0.373662 -0.009018 +v -0.237465 0.080392 0.161407 +v -0.240029 0.084510 0.157037 +v -0.395992 0.329158 -0.014282 +v -0.392642 0.323997 -0.012098 +v -0.300399 0.335523 0.177228 +v -0.297836 0.331977 0.172383 +v -0.194475 0.194861 -0.117519 +v -0.195863 0.196561 -0.111370 +vt 0.725140 0.007877 +vt 0.725140 0.023447 +vt 0.727236 0.023447 +vt 0.727236 0.007877 +vt 0.992093 0.030528 +vt 0.992093 0.014958 +vt 0.978525 0.014958 +vt 0.978525 0.030528 +vt 0.264213 0.023758 +vt 0.264213 0.008188 +vt 0.262116 0.008188 +vt 0.262116 0.023758 +vt 0.689057 0.018268 +vt 0.689057 0.031739 +vt 0.700385 0.031739 +vt 0.700385 0.018268 +vt 0.555940 0.772979 +vt 0.555940 0.775074 +vt 0.557897 0.775074 +vt 0.557897 0.772979 +vt 0.687937 0.017218 +vt 0.701505 0.017218 +vt 0.699436 0.016151 +vt 0.690005 0.016151 +vt 0.700385 0.018268 +vt 0.700385 0.031739 +vt 0.701505 0.032789 +vt 0.701505 0.017218 +vt 0.689057 0.031739 +vt 0.689057 0.018268 +vt 0.687937 0.017218 +vt 0.687937 0.032789 +vt 0.689057 0.018268 +vt 0.700385 0.018268 +vt 0.701505 0.017218 +vt 0.687937 0.017218 +vt 0.700385 0.031739 +vt 0.689057 0.031739 +vt 0.687937 0.032789 +vt 0.701505 0.032789 +vt 0.980594 0.013891 +vt 0.990025 0.013891 +vt 0.990025 0.011906 +vt 0.980594 0.011906 +vt 0.980594 0.031595 +vt 0.990025 0.031595 +vt 0.553762 0.772913 +vt 0.551665 0.772913 +vt 0.551665 0.775074 +vt 0.553762 0.775074 +vt 0.701505 0.032789 +vt 0.687937 0.032789 +vt 0.690005 0.033855 +vt 0.699436 0.033855 +vt 0.557936 0.772979 +vt 0.557936 0.775074 +vt 0.559892 0.775074 +vt 0.559892 0.772979 +vt 0.553804 0.775074 +vt 0.555900 0.775074 +vt 0.555900 0.772913 +vt 0.553804 0.772913 +vt 0.699436 0.035840 +vt 0.690005 0.035840 +vt 0.691050 0.038892 +vt 0.698392 0.038892 +vt 0.699436 0.014166 +vt 0.690005 0.014166 +vt 0.980594 0.033580 +vt 0.990025 0.033580 +vt 0.988980 0.036632 +vt 0.981638 0.036632 +vt 0.983529 0.037909 +vt 0.987090 0.037909 +vt 0.988980 0.008854 +vt 0.981638 0.008854 +vt 0.698392 0.011114 +vt 0.691050 0.011114 +vt 0.692941 0.040169 +vt 0.696501 0.040169 +vt 0.987090 0.007577 +vt 0.983529 0.007577 +vt 0.696501 0.009838 +vt 0.692941 0.009838 +vt 0.683908 0.042465 +vt 0.683908 0.046067 +vt 0.687548 0.046791 +vt 0.687548 0.041741 +vt 0.761118 0.564073 +vt 0.764447 0.562694 +vt 0.763723 0.559055 +vt 0.759056 0.560988 +vt 0.682529 0.039136 +vt 0.685614 0.037075 +vt 0.768050 0.562694 +vt 0.768774 0.559055 +vt 0.679981 0.036589 +vt 0.682043 0.033504 +vt 0.771379 0.564073 +vt 0.773441 0.560988 +vt 0.676652 0.035210 +vt 0.677376 0.031572 +vt 0.773927 0.566620 +vt 0.777013 0.564559 +vt 0.673049 0.035210 +vt 0.672325 0.031572 +vt 0.775306 0.569949 +vt 0.778946 0.569225 +vt 0.669720 0.036589 +vt 0.667658 0.033504 +vt 0.775306 0.573551 +vt 0.778946 0.574275 +vt 0.667172 0.039136 +vt 0.664086 0.037075 +vt 0.773927 0.576879 +vt 0.777013 0.578941 +vt 0.665793 0.042465 +vt 0.662153 0.041741 +vt 0.771379 0.579427 +vt 0.773441 0.582512 +vt 0.665793 0.046067 +vt 0.662153 0.046791 +vt 0.768050 0.580805 +vt 0.768774 0.584444 +vt 0.667172 0.049396 +vt 0.664086 0.051457 +vt 0.764447 0.580805 +vt 0.763723 0.584444 +vt 0.669720 0.051943 +vt 0.667658 0.055028 +vt 0.761118 0.579427 +vt 0.759056 0.582512 +vt 0.673049 0.053322 +vt 0.672325 0.056960 +vt 0.758570 0.576879 +vt 0.755484 0.578941 +vt 0.676652 0.053321 +vt 0.677376 0.056960 +vt 0.757191 0.573551 +vt 0.753551 0.574275 +vt 0.679981 0.051943 +vt 0.682043 0.055028 +vt 0.757191 0.569949 +vt 0.753551 0.569225 +vt 0.682529 0.049395 +vt 0.685614 0.051457 +vt 0.758570 0.566620 +vt 0.755484 0.564559 +vt 0.350385 0.054710 +vt 0.352318 0.050044 +vt 0.351844 0.049950 +vt 0.349984 0.054442 +vt 0.530749 0.051329 +vt 0.532682 0.055995 +vt 0.533083 0.055727 +vt 0.531222 0.051235 +vt 0.556144 0.051329 +vt 0.556144 0.046279 +vt 0.555671 0.046373 +vt 0.555671 0.051235 +vt 0.326924 0.044994 +vt 0.326924 0.050044 +vt 0.327397 0.049950 +vt 0.327397 0.045088 +vt 0.332428 0.058281 +vt 0.337095 0.060213 +vt 0.337189 0.059740 +vt 0.332697 0.057879 +vt 0.342147 0.034825 +vt 0.337095 0.034825 +vt 0.337189 0.035298 +vt 0.342052 0.035298 +vt 0.545972 0.036110 +vt 0.540921 0.036110 +vt 0.541015 0.036583 +vt 0.545878 0.036583 +vt 0.352318 0.044994 +vt 0.351844 0.045088 +vt 0.530749 0.046279 +vt 0.531222 0.046373 +vt 0.554211 0.055995 +vt 0.553810 0.055727 +vt 0.342147 0.060213 +vt 0.342052 0.059740 +vt 0.332428 0.036757 +vt 0.332697 0.037158 +vt 0.550639 0.038043 +vt 0.550371 0.038444 +vt 0.350385 0.040328 +vt 0.349984 0.040597 +vt 0.532682 0.041614 +vt 0.533083 0.041882 +vt 0.550639 0.059566 +vt 0.550371 0.059165 +vt 0.540921 0.061499 +vt 0.545972 0.061499 +vt 0.545878 0.061025 +vt 0.541015 0.061025 +vt 0.536254 0.038043 +vt 0.536522 0.038444 +vt 0.346813 0.036757 +vt 0.346545 0.037159 +vt 0.328857 0.054710 +vt 0.329258 0.054441 +vt 0.554211 0.041614 +vt 0.553810 0.041882 +vt 0.536254 0.059566 +vt 0.536522 0.059165 +vt 0.328857 0.040328 +vt 0.329258 0.040596 +vt 0.346813 0.058281 +vt 0.346545 0.057879 +vt 0.938176 0.144543 +vt 0.936079 0.144543 +vt 0.936079 0.146528 +vt 0.938176 0.146528 +vt 0.936037 0.146518 +vt 0.933941 0.146518 +vt 0.933941 0.149570 +vt 0.936037 0.149570 +vt 0.931803 0.149570 +vt 0.933899 0.149570 +vt 0.933899 0.147585 +vt 0.931803 0.147585 +vt 0.669770 0.237777 +vt 0.671866 0.237777 +vt 0.671866 0.235792 +vt 0.669770 0.235792 +vt 0.936037 0.144533 +vt 0.933941 0.144533 +vt 0.941857 0.534410 +vt 0.939761 0.534410 +vt 0.939761 0.536414 +vt 0.941857 0.536414 +vt 0.936079 0.149570 +vt 0.938176 0.149570 +vt 0.933899 0.144533 +vt 0.931803 0.144533 +vt 0.671866 0.232731 +vt 0.669770 0.232731 +vt 0.941857 0.539957 +vt 0.939761 0.539957 +vt 0.941045 0.905987 +vt 0.941045 0.902444 +vt 0.938949 0.902444 +vt 0.938949 0.905987 +vt 0.939761 0.541716 +vt 0.941857 0.541716 +vt 0.938949 0.907746 +vt 0.941045 0.907746 +vt 0.941045 0.900440 +vt 0.938949 0.900440 +vt 0.288670 0.214799 +vt 0.287725 0.214799 +vt 0.287630 0.219752 +vt 0.288575 0.219752 +vt 0.214319 0.449791 +vt 0.215268 0.449791 +vt 0.215268 0.445592 +vt 0.214319 0.445592 +vt 0.215268 0.440639 +vt 0.214319 0.440639 +vt 0.215268 0.435685 +vt 0.214319 0.435685 +vt 0.215268 0.431486 +vt 0.214319 0.431486 +vt 0.806757 0.635464 +vt 0.807702 0.635464 +vt 0.807433 0.631265 +vt 0.806488 0.631265 +vt 0.807338 0.626312 +vt 0.806393 0.626312 +vt 0.807433 0.621359 +vt 0.806488 0.621359 +vt 0.807702 0.617160 +vt 0.806757 0.617160 +vt 0.215268 0.412816 +vt 0.214319 0.412816 +vt 0.214319 0.417015 +vt 0.215268 0.417015 +vt 0.214319 0.421968 +vt 0.215268 0.421968 +vt 0.214319 0.426921 +vt 0.215268 0.426921 +vt 0.214319 0.431120 +vt 0.215268 0.431120 +vt 0.288939 0.210600 +vt 0.287994 0.210600 +vt 0.081150 0.007112 +vt 0.080958 0.004117 +vt 0.072470 0.004117 +vt 0.072662 0.007112 +vt 0.931302 0.735017 +vt 0.931211 0.739786 +vt 0.937808 0.739786 +vt 0.937899 0.735017 +vt 0.287725 0.224705 +vt 0.288670 0.224705 +vt 0.081217 0.010645 +vt 0.072730 0.010645 +vt 0.609299 0.003820 +vt 0.609299 0.006815 +vt 0.617826 0.006815 +vt 0.617826 0.003820 +vt 0.609299 0.010349 +vt 0.617826 0.010349 +vt 0.609299 0.013882 +vt 0.617826 0.013882 +vt 0.609299 0.016877 +vt 0.617826 0.016877 +vt 0.081392 0.004117 +vt 0.081584 0.007112 +vt 0.090072 0.007112 +vt 0.089879 0.004117 +vt 0.081652 0.010645 +vt 0.090139 0.010645 +vt 0.081584 0.014179 +vt 0.090072 0.014179 +vt 0.081392 0.017174 +vt 0.089879 0.017174 +vt 0.777666 0.003797 +vt 0.777666 0.006793 +vt 0.786193 0.006793 +vt 0.786193 0.003797 +vt 0.777666 0.010326 +vt 0.786193 0.010326 +vt 0.777666 0.013859 +vt 0.786193 0.013859 +vt 0.777666 0.016855 +vt 0.786193 0.016855 +vt 0.080958 0.017174 +vt 0.081150 0.014179 +vt 0.072662 0.014179 +vt 0.072470 0.017174 +vt 0.287994 0.228904 +vt 0.288939 0.228904 +vt 0.288939 0.229270 +vt 0.287994 0.229270 +vt 0.287725 0.233469 +vt 0.288670 0.233469 +vt 0.215268 0.408251 +vt 0.214319 0.408251 +vt 0.214319 0.412450 +vt 0.215268 0.412450 +vt 0.215268 0.403298 +vt 0.214319 0.403298 +vt 0.215268 0.398345 +vt 0.214319 0.398345 +vt 0.215268 0.394145 +vt 0.214319 0.394145 +vt 0.806488 0.602689 +vt 0.807433 0.602689 +vt 0.807702 0.598489 +vt 0.806757 0.598489 +vt 0.806393 0.607642 +vt 0.807338 0.607642 +vt 0.806488 0.612595 +vt 0.807433 0.612595 +vt 0.806757 0.616794 +vt 0.807702 0.616794 +vt 0.215268 0.389580 +vt 0.214319 0.389580 +vt 0.214319 0.393779 +vt 0.215268 0.393779 +vt 0.215268 0.384627 +vt 0.214319 0.384627 +vt 0.215268 0.379674 +vt 0.214319 0.379674 +vt 0.215268 0.375475 +vt 0.214319 0.375475 +vt 0.288670 0.243376 +vt 0.287725 0.243376 +vt 0.287994 0.247575 +vt 0.288939 0.247575 +vt 0.288575 0.238423 +vt 0.287630 0.238423 +vt 0.931561 0.730975 +vt 0.938159 0.730975 +vt 0.990862 0.671942 +vt 0.990862 0.675985 +vt 0.997490 0.675985 +vt 0.997490 0.671942 +vt 0.990862 0.667174 +vt 0.997490 0.667174 +vt 0.990862 0.662406 +vt 0.997490 0.662406 +vt 0.990862 0.658363 +vt 0.997490 0.658363 +vt 0.990030 0.239506 +vt 0.989771 0.243548 +vt 0.996368 0.243548 +vt 0.996628 0.239506 +vt 0.990121 0.234737 +vt 0.996719 0.234737 +vt 0.990030 0.229969 +vt 0.996628 0.229969 +vt 0.989771 0.225927 +vt 0.996368 0.225927 +vt 0.939381 0.006078 +vt 0.939381 0.002035 +vt 0.932753 0.002035 +vt 0.932753 0.006077 +vt 0.939381 0.010846 +vt 0.932753 0.010846 +vt 0.939381 0.015614 +vt 0.932753 0.015614 +vt 0.939381 0.019657 +vt 0.932753 0.019657 +vt 0.931302 0.744554 +vt 0.931561 0.748596 +vt 0.938159 0.748596 +vt 0.937899 0.744554 +vn -0.8316 -0.5542 -0.0344 +vn 0.0000 0.0619 -0.9981 +vn 0.8316 0.5542 0.0344 +vn 0.0000 -0.0619 0.9981 +vn -0.1121 0.9918 0.0615 +vn -0.5576 -0.4175 0.7175 +vn 0.5576 0.3256 0.7636 +vn 0.5576 0.3257 0.7636 +vn 0.3854 -0.6207 0.6828 +vn -0.3854 0.5316 0.7542 +vn -0.8748 0.4835 0.0300 +vn 0.1121 -0.9918 -0.0615 +vn 0.8748 -0.4835 -0.0300 +vn 0.8317 0.5542 0.0344 +vn 0.8316 0.5542 0.0343 +vn 0.8317 0.5542 0.0343 +vn -0.8316 -0.5543 -0.0344 +vn -0.8317 -0.5542 -0.0344 +vn 0.8316 0.5543 0.0344 +vn -0.8316 -0.5543 -0.0343 +vn 0.8316 0.5543 0.0343 +vn -0.9115 -0.4105 -0.0255 +vn 0.7293 0.6829 0.0424 +vn 0.3229 0.9446 0.0586 +vn 0.9115 0.4105 0.0255 +vn -0.7293 -0.6829 -0.0424 +vn 0.9979 -0.0643 -0.0040 +vn 0.7744 -0.6315 -0.0392 +vn -0.9979 0.0643 0.0040 +vn -0.3229 -0.9446 -0.0586 +vn 0.2876 -0.9559 -0.0593 +vn -0.2876 0.9559 0.0593 +vn -0.7744 0.6315 0.0392 +vn -0.3230 -0.9446 -0.0586 +vn 0.3230 0.9446 0.0586 +vn -0.5130 0.7432 0.4295 +vn -0.5131 0.7432 0.4295 +vn -0.5553 0.8301 0.0515 +vn -0.3927 0.6307 -0.6694 +vn -0.2125 0.3748 -0.9024 +vn 0.2125 -0.2605 -0.9418 +vn 0.3927 -0.5432 -0.7421 +vn 0.3927 -0.5432 -0.7422 +vn 0.5130 -0.7432 -0.4295 +vn 0.5553 -0.8300 -0.0515 +vn 0.5130 -0.7905 0.3344 +vn 0.3927 -0.6307 0.6694 +vn 0.3927 -0.6307 0.6693 +vn 0.2125 -0.3748 0.9024 +vn -0.2125 0.2605 0.9418 +vn -0.3927 0.5432 0.7421 +vn -0.3927 0.5432 0.7422 +vn -0.5130 0.7906 -0.3344 +vn 0.5553 -0.8301 -0.0515 +vn -0.3927 0.6307 -0.6693 +vn 0.5130 -0.7906 0.3344 +vn -0.3926 0.5432 0.7422 +vn -0.3926 0.5432 0.7421 +vn 0.3926 -0.6307 0.6694 +vn 0.3926 -0.5432 -0.7422 +vn -0.5130 0.7905 -0.3344 +vn -0.5553 0.8300 0.0515 +vn -0.3926 0.6307 -0.6694 +usemtl Scene_-_Root +s off +f 28725/28725/20455 28726/28726/20455 28727/28727/20455 +f 28725/28725/20455 28727/28727/20455 28728/28728/20455 +f 28729/28729/20456 28730/28730/20456 28731/28731/20456 +f 28729/28729/20456 28731/28731/20456 28732/28732/20456 +f 28733/28733/20457 28734/28734/20457 28735/28735/20457 +f 28733/28733/20457 28735/28735/20457 28736/28736/20457 +f 28737/28737/20458 28738/28738/20458 28739/28739/20458 +f 28737/28737/20458 28739/28739/20458 28740/28740/20458 +f 28741/28741/20459 28742/28742/20459 28743/28743/20459 +f 28741/28741/20459 28743/28743/20459 28744/28744/20459 +f 28745/28745/20458 28746/28746/20458 28747/28747/20458 +f 28745/28745/20458 28747/28747/20458 28748/28748/20458 +f 28749/28749/20460 28750/28750/20460 28751/28751/20460 +f 28749/28749/20460 28751/28751/20460 28752/28752/20460 +f 28753/28753/20461 28754/28754/20461 28755/28755/20461 +f 28753/28753/20462 28755/28755/20462 28756/28756/20462 +f 28757/28757/20463 28758/28758/20463 28759/28759/20463 +f 28757/28757/20463 28759/28759/20463 28760/28760/20463 +f 28761/28761/20464 28762/28762/20464 28763/28763/20464 +f 28761/28761/20464 28763/28763/20464 28764/28764/20464 +f 28769/28765/20456 28770/28766/20456 28771/28767/20456 +f 28769/28765/20456 28771/28767/20456 28772/28768/20456 +f 28729/28729/20456 28732/28732/20456 28773/28769/20456 +f 28729/28729/20456 28773/28769/20456 28774/28770/20456 +f 28775/28771/20465 28776/28772/20465 28777/28773/20465 +f 28775/28771/20465 28777/28773/20465 28778/28774/20465 +f 28779/28775/20458 28780/28776/20458 28781/28777/20458 +f 28779/28775/20458 28781/28777/20458 28782/28778/20458 +f 28783/28779/20466 28784/28780/20466 28785/28781/20466 +f 28783/28779/20466 28785/28781/20466 28786/28782/20466 +f 28787/28783/20467 28788/28784/20467 28789/28785/20467 +f 28787/28783/20467 28789/28785/20467 28790/28786/20467 +f 28731/28731/20456 28730/28730/20456 28770/28766/20456 +f 28731/28731/20456 28770/28766/20456 28769/28765/20456 +f 28795/28787/20458 28796/28788/20458 28797/28789/20458 +f 28795/28787/20458 28797/28789/20458 28798/28790/20458 +f 28748/28748/20458 28747/28747/20458 28799/28791/20458 +f 28748/28748/20458 28799/28791/20458 28800/28792/20458 +f 28774/28770/20456 28773/28769/20456 28805/28793/20456 +f 28774/28770/20456 28805/28793/20456 28806/28794/20456 +f 28782/28778/20458 28781/28777/20458 28796/28788/20458 +f 28782/28778/20458 28796/28788/20458 28795/28787/20458 +f 28813/28795/20456 28814/28796/20456 28815/28797/20456 +f 28813/28795/20456 28815/28797/20456 28816/28798/20456 +f 28772/28768/20456 28771/28767/20456 28821/28799/20456 +f 28772/28768/20456 28821/28799/20456 28822/28800/20456 +f 28800/28792/20458 28799/28791/20458 28825/28801/20458 +f 28800/28792/20458 28825/28801/20458 28826/28802/20458 +f 28806/28794/20456 28805/28793/20456 28814/28796/20456 +f 28806/28794/20456 28814/28796/20456 28813/28795/20456 +f 28798/28790/20458 28797/28789/20458 28839/28803/20458 +f 28798/28790/20458 28839/28803/20458 28840/28804/20458 +f 28822/28800/20456 28821/28799/20456 28843/28805/20456 +f 28822/28800/20456 28843/28805/20456 28844/28806/20456 +f 28826/28802/20458 28825/28801/20458 28847/28807/20458 +f 28826/28802/20458 28847/28807/20458 28848/28808/20458 +f 28897/28809/20455 28898/28810/20455 28899/28811/20455 +f 28897/28809/20455 28899/28811/20455 28900/28812/20455 +f 28901/28813/20457 28902/28814/20457 28903/28815/20457 +f 28901/28813/20468 28903/28815/20468 28904/28816/20468 +f 28905/28817/20455 28897/28809/20455 28900/28812/20455 +f 28905/28817/20455 28900/28812/20455 28906/28818/20455 +f 28902/28814/20457 28907/28819/20457 28908/28820/20457 +f 28902/28814/20457 28908/28820/20457 28903/28815/20457 +f 28909/28821/20455 28905/28817/20455 28906/28818/20455 +f 28909/28821/20455 28906/28818/20455 28910/28822/20455 +f 28907/28819/20457 28911/28823/20457 28912/28824/20457 +f 28907/28819/20457 28912/28824/20457 28908/28820/20457 +f 28913/28825/20455 28909/28821/20455 28910/28822/20455 +f 28913/28825/20455 28910/28822/20455 28914/28826/20455 +f 28911/28823/20457 28915/28827/20457 28916/28828/20457 +f 28911/28823/20457 28916/28828/20457 28912/28824/20457 +f 28917/28829/20455 28913/28825/20455 28914/28826/20455 +f 28917/28829/20455 28914/28826/20455 28918/28830/20455 +f 28915/28827/20457 28919/28831/20457 28920/28832/20457 +f 28915/28827/20457 28920/28832/20457 28916/28828/20457 +f 28921/28833/20455 28917/28829/20455 28918/28830/20455 +f 28921/28833/20455 28918/28830/20455 28922/28834/20455 +f 28919/28831/20457 28923/28835/20457 28924/28836/20457 +f 28919/28831/20457 28924/28836/20457 28920/28832/20457 +f 28925/28837/20455 28921/28833/20455 28922/28834/20455 +f 28925/28837/20455 28922/28834/20455 28926/28838/20455 +f 28923/28835/20457 28927/28839/20457 28928/28840/20457 +f 28923/28835/20457 28928/28840/20457 28924/28836/20457 +f 28929/28841/20455 28925/28837/20455 28926/28838/20455 +f 28929/28841/20455 28926/28838/20455 28930/28842/20455 +f 28927/28839/20457 28931/28843/20457 28932/28844/20457 +f 28927/28839/20457 28932/28844/20457 28928/28840/20457 +f 28933/28845/20455 28929/28841/20455 28930/28842/20455 +f 28933/28845/20455 28930/28842/20455 28934/28846/20455 +f 28931/28843/20457 28935/28847/20457 28936/28848/20457 +f 28931/28843/20457 28936/28848/20457 28932/28844/20457 +f 28937/28849/20455 28933/28845/20455 28934/28846/20455 +f 28937/28849/20455 28934/28846/20455 28938/28850/20455 +f 28935/28847/20457 28939/28851/20457 28940/28852/20457 +f 28935/28847/20457 28940/28852/20457 28936/28848/20457 +f 28941/28853/20455 28937/28849/20455 28938/28850/20455 +f 28941/28853/20455 28938/28850/20455 28942/28854/20455 +f 28939/28851/20457 28943/28855/20457 28944/28856/20457 +f 28939/28851/20457 28944/28856/20457 28940/28852/20457 +f 28945/28857/20455 28941/28853/20455 28942/28854/20455 +f 28945/28857/20455 28942/28854/20455 28946/28858/20455 +f 28943/28855/20469 28947/28859/20469 28948/28860/20469 +f 28943/28855/20468 28948/28860/20468 28944/28856/20468 +f 28949/28861/20455 28945/28857/20455 28946/28858/20455 +f 28949/28861/20455 28946/28858/20455 28950/28862/20455 +f 28947/28859/20468 28951/28863/20468 28952/28864/20468 +f 28947/28859/20469 28952/28864/20469 28948/28860/20469 +f 28953/28865/20455 28949/28861/20455 28950/28862/20455 +f 28953/28865/20455 28950/28862/20455 28954/28866/20455 +f 28951/28863/20457 28955/28867/20457 28956/28868/20457 +f 28951/28863/20457 28956/28868/20457 28952/28864/20457 +f 28957/28869/20455 28953/28865/20455 28954/28866/20455 +f 28957/28869/20455 28954/28866/20455 28958/28870/20455 +f 28955/28867/20457 28959/28871/20457 28960/28872/20457 +f 28955/28867/20457 28960/28872/20457 28956/28868/20457 +f 28898/28810/20455 28957/28869/20455 28958/28870/20455 +f 28898/28810/20455 28958/28870/20455 28899/28811/20455 +f 28959/28871/20470 28901/28813/20470 28904/28816/20470 +f 28959/28871/20457 28904/28816/20457 28960/28872/20457 +f 29037/28873/20455 29038/28874/20455 29039/28875/20455 +f 29037/28873/20471 29039/28875/20471 29040/28876/20471 +f 29041/28877/20468 29042/28878/20468 29043/28879/20468 +f 29041/28877/20457 29043/28879/20457 29044/28880/20457 +f 29045/28881/20468 29046/28882/20468 29047/28883/20468 +f 29045/28881/20457 29047/28883/20457 29048/28884/20457 +f 29049/28885/20455 29050/28886/20455 29051/28887/20455 +f 29049/28885/20471 29051/28887/20471 29052/28888/20471 +f 29053/28889/20455 29054/28890/20455 29055/28891/20455 +f 29053/28889/20472 29055/28891/20472 29056/28892/20472 +f 29057/28893/20455 29058/28894/20455 29059/28895/20455 +f 29057/28893/20455 29059/28895/20455 29060/28896/20455 +f 29061/28897/20457 29062/28898/20457 29063/28899/20457 +f 29061/28897/20457 29063/28899/20457 29064/28900/20457 +f 29038/28874/20455 29065/28901/20455 29066/28902/20455 +f 29038/28874/20455 29066/28902/20455 29039/28875/20455 +f 29067/28903/20457 29041/28877/20457 29044/28880/20457 +f 29067/28903/20457 29044/28880/20457 29068/28904/20457 +f 29069/28905/20457 29045/28881/20457 29048/28884/20457 +f 29069/28905/20457 29048/28884/20457 29070/28906/20457 +f 29054/28890/20455 29071/28907/20455 29072/28908/20455 +f 29054/28890/20455 29072/28908/20455 29055/28891/20455 +f 29058/28894/20455 29073/28909/20455 29074/28910/20455 +f 29058/28894/20455 29074/28910/20455 29059/28895/20455 +f 29075/28911/20457 29061/28897/20457 29064/28900/20457 +f 29075/28911/20468 29064/28900/20468 29076/28912/20468 +f 29065/28901/20472 29077/28913/20472 29078/28914/20472 +f 29065/28901/20455 29078/28914/20455 29066/28902/20455 +f 29079/28915/20457 29067/28903/20457 29068/28904/20457 +f 29079/28915/20457 29068/28904/20457 29080/28916/20457 +f 29081/28917/20457 29069/28905/20457 29070/28906/20457 +f 29081/28917/20470 29070/28906/20470 29082/28918/20470 +f 29119/28919/20473 29120/28920/20473 29121/28921/20473 +f 29119/28919/20457 29121/28921/20457 29122/28922/20457 +f 29062/28898/20473 29123/28923/20473 29124/28924/20473 +f 29062/28898/20457 29124/28924/20457 29063/28899/20457 +f 29125/28925/20472 29057/28893/20472 29060/28896/20472 +f 29125/28925/20474 29060/28896/20474 29126/28926/20474 +f 29127/28927/20472 29053/28889/20472 29056/28892/20472 +f 29127/28927/20474 29056/28892/20474 29128/28928/20474 +f 29046/28882/20475 29129/28929/20475 29130/28930/20475 +f 29046/28882/20468 29130/28930/20468 29047/28883/20468 +f 29042/28878/20473 29131/28931/20473 29132/28932/20473 +f 29042/28878/20468 29132/28932/20468 29043/28879/20468 +f 29133/28933/20471 29049/28885/20471 29052/28888/20471 +f 29133/28933/20472 29052/28888/20472 29134/28934/20472 +f 29135/28935/20471 29037/28873/20471 29040/28876/20471 +f 29135/28935/20472 29040/28876/20472 29136/28936/20472 +f 29050/28886/20471 29127/28927/20471 29128/28928/20471 +f 29050/28886/20455 29128/28928/20455 29051/28887/20455 +f 29120/28920/20468 29081/28917/20468 29082/28918/20468 +f 29120/28920/20473 29082/28918/20473 29121/28921/20473 +f 29123/28923/20468 29079/28915/20468 29080/28916/20468 +f 29123/28923/20473 29080/28916/20473 29124/28924/20473 +f 29077/28913/20474 29125/28925/20474 29126/28926/20474 +f 29077/28913/20455 29126/28926/20455 29078/28914/20455 +f 29131/28931/20457 29119/28919/20457 29122/28922/20457 +f 29131/28931/20473 29122/28922/20473 29132/28932/20473 +f 29129/28929/20468 29075/28911/20468 29076/28912/20468 +f 29129/28929/20473 29076/28912/20473 29130/28930/20473 +f 29073/28909/20472 29133/28933/20472 29134/28934/20472 +f 29073/28909/20455 29134/28934/20455 29074/28910/20455 +f 29071/28907/20455 29135/28935/20455 29136/28936/20455 +f 29071/28907/20455 29136/28936/20455 29072/28908/20455 +s 1 +f 28765/28937/20455 28766/28938/20455 28767/28939/20476 +f 28765/28937/20455 28767/28939/20476 28768/28940/20476 +f 28791/28941/20477 28792/28942/20477 28793/28943/20478 +f 28791/28941/20477 28793/28943/20478 28794/28944/20478 +f 28801/28945/20457 28802/28946/20457 28803/28947/20479 +f 28801/28945/20457 28803/28947/20479 28804/28948/20479 +f 28807/28949/20455 28808/28950/20455 28809/28951/20480 +f 28807/28949/20455 28809/28951/20480 28810/28952/20480 +f 28811/28953/20457 28812/28954/20457 28792/28942/20477 +f 28811/28953/20457 28792/28942/20477 28791/28941/20477 +f 28817/28955/20481 28818/28956/20481 28819/28957/20482 +f 28817/28955/20481 28819/28957/20482 28820/28958/20482 +f 28768/28940/20476 28767/28939/20476 28823/28959/20483 +f 28768/28940/20476 28823/28959/20483 28824/28960/20483 +f 28804/28948/20479 28803/28947/20479 28827/28961/20481 +f 28804/28948/20479 28827/28961/20481 28828/28962/20481 +f 28810/28952/20480 28809/28951/20480 28829/28963/20484 +f 28810/28952/20480 28829/28963/20484 28830/28964/20484 +f 28831/28965/20485 28820/28958/20482 28819/28957/20482 +f 28831/28965/20485 28819/28957/20482 28832/28966/20485 +f 28833/28967/20486 28834/28968/20487 28835/28969/20487 +f 28833/28967/20486 28835/28969/20487 28836/28970/20486 +f 28837/28971/20488 28838/28972/20488 28831/28965/20485 +f 28837/28971/20488 28831/28965/20485 28832/28966/20485 +f 28841/28973/20489 28842/28974/20489 28833/28967/20486 +f 28841/28973/20489 28833/28967/20486 28836/28970/20486 +f 28845/28975/20483 28846/28976/20483 28835/28969/20487 +f 28845/28975/20483 28835/28969/20487 28834/28968/20487 +f 28849/28977/20490 28850/28978/20491 28851/28979/20492 +f 28849/28977/20490 28851/28979/20492 28852/28980/20492 +f 28853/28981/20493 28854/28982/20493 28855/28983/20494 +f 28853/28981/20493 28855/28983/20494 28856/28984/20494 +f 28856/28984/20494 28855/28983/20494 28857/28985/20456 +f 28856/28984/20494 28857/28985/20456 28858/28986/20456 +f 28858/28986/20456 28857/28985/20456 28859/28987/20495 +f 28858/28986/20456 28859/28987/20495 28860/28988/20495 +f 28860/28988/20495 28859/28987/20495 28861/28989/20496 +f 28860/28988/20495 28861/28989/20496 28862/28990/20496 +f 28863/28991/20497 28864/28992/20497 28865/28993/20498 +f 28863/28991/20497 28865/28993/20498 28866/28994/20498 +f 28866/28994/20498 28865/28993/20498 28867/28995/20499 +f 28866/28994/20498 28867/28995/20499 28868/28996/20499 +f 28868/28996/20499 28867/28995/20499 28869/28997/20500 +f 28868/28996/20499 28869/28997/20500 28870/28998/20500 +f 28870/28998/20500 28869/28997/20500 28871/28999/20501 +f 28870/28998/20500 28871/28999/20501 28872/29000/20501 +f 28873/29001/20502 28874/29002/20502 28875/29003/20503 +f 28873/29001/20502 28875/29003/20503 28876/29004/20503 +f 28876/29004/20503 28875/29003/20503 28877/29005/20458 +f 28876/29004/20503 28877/29005/20458 28878/29006/20458 +f 28878/29006/20458 28877/29005/20458 28879/29007/20504 +f 28878/29006/20458 28879/29007/20504 28880/29008/20504 +f 28880/29008/20504 28879/29007/20504 28881/29009/20505 +f 28880/29008/20504 28881/29009/20505 28882/29010/20505 +f 28883/29011/20506 28884/29012/20506 28850/28978/20491 +f 28883/29011/20506 28850/28978/20491 28849/28977/20490 +f 28885/29013/20498 28886/29014/20496 28887/29015/20496 +f 28885/29013/20498 28887/29015/20496 28888/29016/20498 +f 28889/29017/20490 28890/29018/20492 28891/29019/20492 +f 28889/29017/20490 28891/29019/20492 28892/29020/20490 +f 28852/28980/20492 28851/28979/20492 28893/29021/20507 +f 28852/28980/20492 28893/29021/20507 28894/29022/20507 +f 28895/29023/20508 28885/29013/20498 28888/29016/20498 +f 28895/29023/20508 28888/29016/20498 28896/29024/20508 +f 28961/29025/20496 28962/29026/20495 28963/29027/20495 +f 28961/29025/20496 28963/29027/20495 28964/29028/20496 +f 28962/29026/20495 28965/29029/20456 28966/29030/20456 +f 28962/29026/20495 28966/29030/20456 28963/29027/20495 +f 28965/29029/20456 28967/29031/20494 28968/29032/20494 +f 28965/29029/20456 28968/29032/20494 28966/29030/20456 +f 28967/29031/20494 28969/29033/20509 28970/29034/20509 +f 28967/29031/20494 28970/29034/20509 28968/29032/20494 +f 28971/29035/20493 28972/29036/20507 28973/29037/20507 +f 28971/29035/20493 28973/29037/20507 28974/29038/20493 +f 28972/29036/20507 28975/29039/20492 28976/29040/20492 +f 28972/29036/20507 28976/29040/20492 28973/29037/20507 +f 28975/29039/20492 28977/29041/20490 28978/29042/20490 +f 28975/29039/20492 28978/29042/20490 28976/29040/20492 +f 28977/29041/20490 28979/29043/20505 28980/29044/20505 +f 28977/29041/20490 28980/29044/20505 28978/29042/20490 +f 28981/29045/20505 28982/29046/20504 28983/29047/20504 +f 28981/29045/20505 28983/29047/20504 28984/29048/20505 +f 28982/29046/20504 28985/29049/20458 28986/29050/20458 +f 28982/29046/20504 28986/29050/20458 28983/29047/20504 +f 28985/29049/20458 28987/29051/20503 28988/29052/20503 +f 28985/29049/20458 28988/29052/20503 28986/29050/20458 +f 28987/29051/20503 28989/29053/20502 28990/29054/20502 +f 28987/29051/20503 28990/29054/20502 28988/29052/20503 +f 28991/29055/20501 28992/29056/20510 28993/29057/20510 +f 28991/29055/20501 28993/29057/20510 28994/29058/20501 +f 28992/29056/20510 28895/29023/20508 28896/29024/20508 +f 28992/29056/20510 28896/29024/20508 28993/29057/20510 +f 28894/29022/20507 28893/29021/20507 28995/29059/20493 +f 28894/29022/20507 28995/29059/20493 28996/29060/20493 +f 28997/29061/20511 28998/29062/20506 28999/29063/20490 +f 28997/29061/20511 28999/29063/20490 29000/29064/20490 +f 29001/29065/20504 29002/29066/20504 29003/29067/20505 +f 29001/29065/20504 29003/29067/20505 29004/29068/20512 +f 29005/29069/20458 29006/29070/20458 29002/29066/20504 +f 29005/29069/20458 29002/29066/20504 29001/29065/20504 +f 29007/29071/20503 29008/29072/20503 29006/29070/20458 +f 29007/29071/20503 29006/29070/20458 29005/29069/20458 +f 29009/29073/20501 29010/29074/20513 29008/29072/20503 +f 29009/29073/20501 29008/29072/20503 29007/29071/20503 +f 29011/29075/20510 29012/29076/20510 29013/29077/20513 +f 29011/29075/20510 29013/29077/20513 29014/29078/20501 +f 29015/29079/20508 29016/29080/20508 29012/29076/20510 +f 29015/29079/20508 29012/29076/20510 29011/29075/20510 +f 29017/29081/20498 29018/29082/20498 29016/29080/20508 +f 29017/29081/20498 29016/29080/20508 29015/29079/20508 +f 29019/29083/20497 29020/29084/20514 29018/29082/20498 +f 29019/29083/20497 29018/29082/20498 29017/29081/20498 +f 29021/29085/20495 29022/29086/20495 29023/29087/20496 +f 29021/29085/20495 29023/29087/20496 29024/29088/20496 +f 29025/29089/20456 29026/29090/20456 29022/29086/20495 +f 29025/29089/20456 29022/29086/20495 29021/29085/20495 +f 29027/29091/20494 29028/29092/20494 29026/29090/20456 +f 29027/29091/20494 29026/29090/20456 29025/29089/20456 +f 29029/29093/20493 29030/29094/20493 29028/29092/20494 +f 29029/29093/20493 29028/29092/20494 29027/29091/20494 +f 29031/29095/20515 29032/29096/20515 29033/29097/20493 +f 29031/29095/20515 29033/29097/20493 29034/29098/20493 +f 29035/29099/20516 29036/29100/20492 29032/29096/20515 +f 29035/29099/20516 29032/29096/20515 29031/29095/20515 +f 29000/29064/20490 28999/29063/20490 29036/29100/20492 +f 29000/29064/20490 29036/29100/20492 29035/29099/20516 +f 29083/29101/20506 28889/29017/20490 28892/29020/20490 +f 29083/29101/20506 28892/29020/20490 29084/29102/20506 +f 29085/29103/20504 29086/29104/20505 29087/29105/20505 +f 29085/29103/20504 29087/29105/20505 29088/29106/20504 +f 29089/29107/20458 29085/29103/20504 29088/29106/20504 +f 29089/29107/20458 29088/29106/20504 29090/29108/20458 +f 29091/29109/20503 29089/29107/20458 29090/29108/20458 +f 29091/29109/20503 29090/29108/20458 29092/29110/20503 +f 29093/29111/20502 29091/29109/20503 29092/29110/20503 +f 29093/29111/20502 29092/29110/20503 29094/29112/20502 +f 29095/29113/20510 29096/29114/20501 29097/29115/20501 +f 29095/29113/20510 29097/29115/20501 29098/29116/20510 +f 29099/29117/20508 29095/29113/20510 29098/29116/20510 +f 29099/29117/20508 29098/29116/20510 29100/29118/20508 +f 29101/29119/20498 29099/29117/20508 29100/29118/20508 +f 29101/29119/20498 29100/29118/20508 29102/29120/20498 +f 29103/29121/20497 29101/29119/20498 29102/29120/20498 +f 29103/29121/20497 29102/29120/20498 29104/29122/20497 +f 29105/29123/20495 29106/29124/20496 29107/29125/20496 +f 29105/29123/20495 29107/29125/20496 29108/29126/20495 +f 29109/29127/20456 29105/29123/20495 29108/29126/20495 +f 29109/29127/20456 29108/29126/20495 29110/29128/20456 +f 29111/29129/20494 29109/29127/20456 29110/29128/20456 +f 29111/29129/20494 29110/29128/20456 29112/29130/20494 +f 29113/29131/20509 29111/29129/20494 29112/29130/20494 +f 29113/29131/20509 29112/29130/20494 29114/29132/20509 +f 29115/29133/20507 29116/29134/20493 29117/29135/20517 +f 29115/29133/20507 29117/29135/20517 29118/29136/20507 +f 28890/29018/20492 29115/29133/20507 29118/29136/20507 +f 28890/29018/20492 29118/29136/20507 28891/29019/20492 +o Cube.047__0 +v -1.257597 1.505421 -0.489751 +v -1.309677 1.535674 -0.489228 +v -1.291260 1.573160 -0.480535 +v -1.239053 1.542663 -0.481081 +v -1.326610 1.543695 -0.488203 +v -1.308121 1.581321 -0.479533 +v -1.293861 1.612445 -0.476043 +v -1.277056 1.604112 -0.477019 +v -1.224705 1.573414 -0.477602 +v -0.822092 1.168668 -0.501901 +v -0.665428 1.007202 -0.505128 +v -0.690993 0.977972 -0.516047 +v -0.847097 1.137477 -0.513238 +v -0.528042 0.863118 -0.506247 +v -0.557020 0.839078 -0.516692 +v -0.599677 0.849416 -0.523431 +v -0.712735 0.958445 -0.524485 +v -0.866639 1.113414 -0.522300 +v -1.302387 1.621653 -0.415127 +v -1.302290 1.622683 -0.403570 +v -1.287738 1.658266 -0.408761 +v -1.288620 1.655121 -0.419829 +v -1.302290 1.622683 -0.403570 +v -1.297637 1.621041 -0.400353 +v -1.282860 1.657221 -0.405698 +v -1.287738 1.658266 -0.408761 +v -1.270187 1.687110 -0.418714 +v -1.275322 1.687593 -0.421567 +v -1.275322 1.687593 -0.421567 +v -1.277119 1.682495 -0.431813 +v -0.884117 1.100731 -0.456869 +v -0.728978 0.944641 -0.459743 +v -0.705788 0.965221 -0.449457 +v -0.863498 1.126076 -0.445891 +v -0.614265 0.834742 -0.459582 +v -0.569815 0.824987 -0.451833 +v -0.536639 0.851863 -0.440699 +v -0.676313 0.997640 -0.437874 +v -0.835172 1.160807 -0.433927 +v -0.501139 0.778420 -0.514567 +v -0.575651 0.814689 -0.522946 +v -0.469647 0.800858 -0.503995 +v -0.462415 0.790161 -0.494056 +v -0.494982 0.767412 -0.504760 +v -0.575651 0.814689 -0.522946 +v -0.501139 0.778420 -0.514567 +v -0.494982 0.767412 -0.504760 +v -0.572825 0.805243 -0.513485 +v -0.476624 0.789845 -0.444441 +v -0.447008 0.823493 -0.435996 +v -0.506592 0.885866 -0.432292 +v -0.466940 0.782788 -0.454593 +v -0.438423 0.815636 -0.446228 +v -0.412120 0.844505 -0.443366 +v -0.419372 0.853517 -0.433226 +v -0.478581 0.916436 -0.429627 +v -0.396691 0.878365 -0.437774 +v -0.455510 0.941853 -0.434357 +v -0.419372 0.853517 -0.433226 +v -0.412120 0.844505 -0.443366 +v -0.390813 0.867921 -0.447484 +v -0.396691 0.878365 -0.437774 +v -0.373476 0.887264 -0.457982 +v -0.378151 0.899172 -0.448985 +v -0.378151 0.899172 -0.448985 +v -0.436590 0.963176 -0.445812 +v -0.646087 1.032161 -0.429457 +v -0.805801 1.196937 -0.425416 +v -0.618162 1.063495 -0.426890 +v -0.779000 1.230044 -0.422933 +v -0.581681 0.795911 -0.474860 +v -0.502185 0.758397 -0.465842 +v -0.512134 0.764902 -0.455701 +v -0.589047 0.800694 -0.464494 +v -0.502185 0.758397 -0.465842 +v -0.512134 0.764902 -0.455701 +v -0.589047 0.800694 -0.464494 +v -1.346329 1.505380 -0.500034 +v -1.351796 1.505703 -0.496877 +v -1.331807 1.545034 -0.484776 +v -1.357099 1.480648 -0.507958 +v -1.363068 1.474821 -0.507061 +v -1.351796 1.505703 -0.496877 +v -1.363068 1.474821 -0.507061 +v -1.365777 1.470306 -0.496165 +v -1.354103 1.502696 -0.485542 +v -1.331807 1.545034 -0.484776 +v -1.333874 1.543188 -0.473264 +v -1.208097 1.612151 -0.487316 +v -1.260789 1.643203 -0.486702 +v -1.255042 1.659122 -0.499100 +v -1.202110 1.627877 -0.499682 +v -1.277520 1.651906 -0.485814 +v -1.271757 1.667989 -0.498279 +v -1.265835 1.683705 -0.514773 +v -1.249133 1.674704 -0.515505 +v -1.196004 1.643281 -0.516032 +v -1.298769 1.614778 -0.472760 +v -1.288904 1.637721 -0.475095 +v -1.284225 1.634781 -0.478225 +v -1.298769 1.614778 -0.472760 +v -1.300037 1.616374 -0.461226 +v -1.289388 1.641430 -0.464049 +v -1.288904 1.637721 -0.475095 +v -1.281513 1.661078 -0.472668 +v -1.281941 1.655418 -0.482894 +v -1.281941 1.655418 -0.482894 +v -1.277520 1.651906 -0.485814 +v -1.267464 1.626262 -0.479163 +v -1.214962 1.595387 -0.479775 +v -1.260789 1.643203 -0.486702 +v -1.208097 1.612151 -0.487316 +v -0.595132 1.089537 -0.431779 +v -0.756878 1.257506 -0.428021 +v -0.576154 1.111308 -0.443429 +v -0.738549 1.280340 -0.439953 +v -0.405421 0.998843 -0.484163 +v -0.347561 0.934070 -0.486699 +v -0.333878 0.949090 -0.511566 +v -0.391573 1.014136 -0.509459 +v -0.344475 0.919944 -0.493746 +v -0.331465 0.934284 -0.517452 +v -0.320097 0.946786 -0.546435 +v -0.321962 0.962113 -0.541813 +v -0.379557 1.027392 -0.540186 +v -0.559687 1.130401 -0.460615 +v -0.722553 1.300271 -0.457481 +v -0.420241 0.981949 -0.462772 +v -0.559687 1.130401 -0.460615 +v -0.420241 0.981949 -0.462772 +v -0.544805 1.147584 -0.482278 +v -0.722553 1.300271 -0.457481 +v -0.708145 1.318219 -0.479551 +v -0.362130 0.917517 -0.465658 +v -0.358340 0.904357 -0.473752 +v -0.362130 0.917517 -0.465658 +v -1.281941 1.655418 -0.482894 +v -1.275933 1.671969 -0.495616 +v -1.274645 1.679148 -0.486419 +v -1.275933 1.671969 -0.495616 +v -1.267887 1.696427 -0.504418 +v -1.269824 1.688053 -0.512426 +v -1.269824 1.688053 -0.512426 +v -1.253280 1.712240 -0.560522 +v -1.257091 1.717112 -0.558989 +v -1.252746 1.728383 -0.591356 +v -1.249036 1.723321 -0.592446 +v -1.257091 1.717112 -0.558989 +v -1.254540 1.727340 -0.553736 +v -1.249866 1.739172 -0.587620 +v -1.252746 1.728383 -0.591356 +v -1.246799 1.747526 -0.622646 +v -1.249970 1.736398 -0.624899 +v -1.249970 1.736398 -0.624899 +v -1.246351 1.731202 -0.625560 +v -1.263173 1.703368 -0.532955 +v -1.259287 1.698730 -0.534917 +v -1.260876 1.712772 -0.526267 +v -1.263173 1.703368 -0.532955 +v -1.242606 1.689631 -0.535533 +v -1.189407 1.658074 -0.535995 +v -1.236623 1.703062 -0.561001 +v -1.183410 1.671392 -0.561372 +v -0.531046 1.163208 -0.507909 +v -0.694997 1.334639 -0.505664 +v -0.519188 1.176779 -0.539022 +v -0.683764 1.348921 -0.537341 +v -1.176485 1.690010 -0.625828 +v -1.229729 1.721885 -0.625748 +v -1.228181 1.725985 -0.655020 +v -1.175044 1.694071 -0.654935 +v -1.244783 1.735332 -0.654972 +v -1.244376 1.735915 -0.682728 +v -1.227800 1.726569 -0.682633 +v -1.174860 1.694674 -0.682362 +v -1.232398 1.714067 -0.592780 +v -1.179152 1.682282 -0.593017 +v -0.510148 1.187628 -0.576189 +v -0.675221 1.360269 -0.575138 +v -0.370381 1.038007 -0.576941 +v -0.364234 1.045420 -0.614532 +v -0.504163 1.195221 -0.614170 +v -0.669657 1.368187 -0.613725 +v -0.312844 0.972516 -0.578070 +v -0.311290 0.956712 -0.581354 +v -0.305294 0.963590 -0.617163 +v -0.306699 0.979758 -0.615185 +v -0.360695 1.049749 -0.680138 +v -0.302956 0.983913 -0.679955 +v -0.305081 0.981323 -0.713171 +v -0.363014 1.047181 -0.713773 +v -0.301652 0.967586 -0.679561 +v -0.303695 0.965143 -0.711504 +v -0.308555 0.959507 -0.744187 +v -0.310155 0.975311 -0.747301 +v -0.368347 1.041122 -0.748345 +v -0.501249 1.199212 -0.648093 +v -0.667169 1.372396 -0.648146 +v -0.361066 1.049247 -0.648132 +v -0.501215 1.199869 -0.680372 +v -0.667560 1.373172 -0.680840 +v -0.303462 0.983474 -0.648356 +v -0.302142 0.967140 -0.649138 +v -1.248370 1.740593 -0.654711 +v -1.245090 1.751895 -0.653816 +v -1.248370 1.740593 -0.654711 +v -1.244732 1.752502 -0.683310 +v -1.247976 1.741177 -0.682866 +v -1.247976 1.741177 -0.682866 +v -1.178239 1.686445 -0.739032 +v -1.230590 1.718122 -0.739778 +v -1.233400 1.709242 -0.765585 +v -1.181423 1.677761 -0.764578 +v -1.247102 1.727363 -0.740199 +v -1.249888 1.718368 -0.766182 +v -1.254044 1.707319 -0.787063 +v -1.237559 1.698326 -0.786296 +v -1.185864 1.667049 -0.785073 +v -1.248861 1.738462 -0.712151 +v -1.245220 1.733259 -0.711585 +v -1.245752 1.749652 -0.714051 +v -1.248861 1.738462 -0.712151 +v -1.248032 1.743226 -0.744791 +v -1.250836 1.732417 -0.741237 +v -1.250836 1.732417 -0.741237 +v -1.228674 1.723947 -0.711333 +v -1.175997 1.692129 -0.710839 +v -0.503927 1.197442 -0.714254 +v -0.670672 1.370760 -0.715093 +v -0.509691 1.191497 -0.749042 +v -0.676769 1.364723 -0.750198 +v -0.697839 1.341377 -0.813349 +v -0.530612 1.168763 -0.811743 +v -0.544662 1.153534 -0.833426 +v -0.711475 1.325542 -0.835198 +v -0.388532 1.018349 -0.810701 +v -0.402489 1.003283 -0.832222 +v -0.418142 0.986250 -0.847886 +v -0.560322 1.136277 -0.849225 +v -0.726543 1.307583 -0.851140 +v -0.518744 1.181697 -0.782693 +v -0.686029 1.354707 -0.784101 +v -0.376970 1.031253 -0.781816 +v -0.518744 1.181697 -0.782693 +v -0.376970 1.031253 -0.781816 +v -0.686029 1.354707 -0.784101 +v -0.318456 0.965585 -0.780308 +v -0.316461 0.950451 -0.775566 +v -0.327013 0.938604 -0.802376 +v -0.329678 0.952893 -0.808728 +v -0.318456 0.965585 -0.780308 +v -0.329678 0.952893 -0.808728 +v -1.253778 1.723162 -0.767735 +v -1.251498 1.733254 -0.773151 +v -1.253778 1.723162 -0.767735 +v -1.256382 1.720765 -0.796401 +v -1.258101 1.711764 -0.789139 +v -1.249888 1.718368 -0.766182 +v -1.253778 1.723162 -0.767735 +v -1.258101 1.711764 -0.789139 +v -1.254044 1.707319 -0.787063 +v -0.358659 0.921371 -0.845140 +v -0.375353 0.902591 -0.856554 +v -0.435174 0.967064 -0.859504 +v -0.353867 0.909077 -0.836325 +v -0.369471 0.891672 -0.846972 +v -0.387692 0.871338 -0.852772 +v -0.394755 0.880722 -0.862769 +v -0.454926 0.944708 -0.865828 +v -0.343319 0.938085 -0.829817 +v -0.339656 0.924704 -0.822087 +v -0.343319 0.938085 -0.829817 +v -0.339656 0.924704 -0.822087 +v -1.264010 1.699242 -0.803834 +v -1.259822 1.695201 -0.801279 +v -1.262744 1.706778 -0.812685 +v -1.264010 1.699242 -0.803834 +v -1.269654 1.691289 -0.823995 +v -1.270354 1.685445 -0.813889 +v -1.270354 1.685445 -0.813889 +v -1.266008 1.681865 -0.810963 +v -1.185864 1.667049 -0.785073 +v -1.237559 1.698326 -0.786296 +v -1.243309 1.686337 -0.800363 +v -1.191710 1.655234 -0.799009 +v -1.249458 1.673143 -0.809937 +v -1.197923 1.642230 -0.808508 +v -1.210720 1.609543 -0.819841 +v -1.261874 1.639935 -0.821337 +v -1.271341 1.617607 -0.820554 +v -1.220249 1.587467 -0.819118 +v -1.278486 1.648278 -0.822442 +v -1.288023 1.625745 -0.821661 +v -1.298903 1.600884 -0.815615 +v -1.282147 1.592942 -0.814544 +v -1.231062 1.563029 -0.813243 +v -1.276265 1.669745 -0.821498 +v -1.271674 1.666685 -0.818358 +v -1.276453 1.673792 -0.832485 +v -1.276265 1.669745 -0.821498 +v -1.284554 1.652828 -0.837128 +v -1.283361 1.650755 -0.825679 +v -1.283361 1.650755 -0.825679 +v -1.255098 1.658141 -0.817276 +v -1.203752 1.627476 -0.815792 +v -0.577396 1.116866 -0.860933 +v -0.743013 1.287459 -0.862978 +v -0.597131 1.094187 -0.867343 +v -0.761966 1.263891 -0.869530 +v -0.503322 0.890979 -0.857549 +v -0.442502 0.828134 -0.854449 +v -0.466054 0.802095 -0.840205 +v -0.527126 0.864356 -0.843151 +v -0.442502 0.828134 -0.854449 +v -0.432615 0.821756 -0.844773 +v -0.454937 0.797091 -0.831235 +v -0.466054 0.802095 -0.840205 +v -0.474910 0.775016 -0.812191 +v -0.487074 0.778797 -0.820140 +v -0.527126 0.864356 -0.843151 +v -0.548345 0.840488 -0.822815 +v -0.620393 1.067593 -0.866853 +v -0.784104 1.236069 -0.869210 +v -0.478369 0.918630 -0.865223 +v -0.645067 1.039293 -0.859284 +v -0.807489 1.206330 -0.861793 +v -0.417856 0.855199 -0.862101 +v -0.409393 0.847348 -0.852075 +v -0.432615 0.821756 -0.844773 +v -1.293159 1.627587 -0.824922 +v -1.295232 1.627453 -0.836383 +v -1.293159 1.627587 -0.824922 +v -1.307145 1.599762 -0.829840 +v -1.304276 1.602101 -0.818792 +v -1.304276 1.602101 -0.818792 +v -0.504638 0.759476 -0.795150 +v -0.566061 0.820619 -0.797471 +v -0.491559 0.756703 -0.788464 +v -0.504823 0.742260 -0.760878 +v -0.518667 0.744304 -0.766253 +v -0.580190 0.804946 -0.768182 +v -1.314894 1.576767 -0.807317 +v -1.309299 1.576107 -0.804367 +v -1.318551 1.572471 -0.817564 +v -1.314894 1.576767 -0.807317 +v -1.328739 1.547761 -0.800385 +v -1.324369 1.553744 -0.791303 +v -1.309299 1.576107 -0.804367 +v -1.314894 1.576767 -0.807317 +v -1.324369 1.553744 -0.791303 +v -1.318573 1.553570 -0.788695 +v -1.292494 1.568344 -0.803388 +v -1.241454 1.538628 -0.802289 +v -1.292494 1.568344 -0.803388 +v -1.301724 1.545963 -0.787845 +v -1.241454 1.538628 -0.802289 +v -1.250721 1.516387 -0.786967 +v -0.668584 1.011971 -0.844931 +v -0.829771 1.177528 -0.847521 +v -0.668584 1.011971 -0.844931 +v -0.689511 0.987360 -0.824566 +v -0.689511 0.987360 -0.824566 +v -0.849562 1.151454 -0.827139 +v -1.265097 1.483190 -0.744760 +v -1.316245 1.512747 -0.745258 +v -1.321866 1.501254 -0.717976 +v -1.270569 1.471583 -0.717656 +v -1.333217 1.520139 -0.745830 +v -1.338885 1.508591 -0.718413 +v -1.342925 1.499381 -0.690021 +v -1.325892 1.492061 -0.689728 +v -1.274526 1.462286 -0.689560 +v -1.332450 1.534686 -0.771493 +v -1.326486 1.534937 -0.769296 +v -1.337367 1.527266 -0.779118 +v -1.332450 1.534686 -0.771493 +v -1.344543 1.510965 -0.753716 +v -1.339296 1.519535 -0.747607 +v -1.339296 1.519535 -0.747607 +v -1.309577 1.527454 -0.768585 +v -1.258538 1.497935 -0.767905 +v -0.849562 1.151454 -0.827139 +v -0.706911 0.966702 -0.799118 +v -0.865929 1.129376 -0.801554 +v -0.720698 0.950218 -0.769647 +v -0.878779 1.111550 -0.771810 +v -0.598697 0.784225 -0.702543 +v -0.537143 0.724294 -0.701483 +v -0.542084 0.717683 -0.668130 +v -0.603558 0.777496 -0.668594 +v -0.522435 0.723015 -0.698657 +v -0.527444 0.716762 -0.666985 +v -0.528308 0.714896 -0.635379 +v -0.542409 0.715727 -0.634259 +v -0.603669 0.775603 -0.633994 +v -0.731081 0.937690 -0.737293 +v -0.888350 1.097812 -0.739041 +v -0.590921 0.793191 -0.736093 +v -0.738614 0.928149 -0.703386 +v -0.895332 1.087359 -0.704592 +v -0.529354 0.732970 -0.734565 +v -0.514942 0.731360 -0.730415 +v -1.345016 1.507728 -0.719797 +v -1.350389 1.498342 -0.724511 +v -1.345016 1.507728 -0.719797 +v -1.354625 1.488532 -0.694191 +v -1.349089 1.498398 -0.690976 +v -1.349089 1.498398 -0.690976 +v -1.344137 1.487884 -0.641597 +v -1.350337 1.487243 -0.641342 +v -1.347203 1.489246 -0.622764 +v -1.341134 1.489398 -0.623789 +v -1.350337 1.487243 -0.641342 +v -1.356606 1.477798 -0.640069 +v -1.353422 1.481153 -0.618218 +v -1.347203 1.489246 -0.622764 +v -1.347002 1.495107 -0.600223 +v -1.341486 1.501152 -0.607924 +v -1.341134 1.489398 -0.623789 +v -1.347203 1.489246 -0.622764 +v -1.341486 1.501152 -0.607924 +v -1.335655 1.500699 -0.609750 +v -1.350932 1.491082 -0.664324 +v -1.344724 1.492001 -0.663912 +v -1.356855 1.481115 -0.665628 +v -1.350932 1.491082 -0.664324 +v -1.327726 1.484652 -0.663780 +v -1.276461 1.454865 -0.663715 +v -1.327222 1.480456 -0.641635 +v -1.276157 1.450698 -0.641634 +v -0.743412 0.921171 -0.668983 +v -0.899949 1.079906 -0.669535 +v -0.743486 0.919247 -0.633852 +v -0.900082 1.077890 -0.633656 +v -1.267844 1.463019 -0.610217 +v -1.318909 1.492952 -0.610137 +v -1.310828 1.516337 -0.599401 +v -1.259159 1.486038 -0.599502 +v -1.327634 1.524305 -0.598811 +v -1.316993 1.554383 -0.592038 +v -1.300113 1.546195 -0.592760 +v -1.247775 1.515512 -0.592868 +v -1.324331 1.481835 -0.623993 +v -1.273417 1.452065 -0.624040 +v -1.324331 1.481835 -0.623993 +v -1.273417 1.452065 -0.624040 +v -0.736394 0.925501 -0.598429 +v -0.893116 1.084359 -0.597415 +v -0.596770 0.781815 -0.599149 +v -0.736394 0.925501 -0.598429 +v -0.596770 0.781815 -0.599149 +v -0.580793 0.798903 -0.568406 +v -0.719967 0.942643 -0.567088 +v -0.893116 1.084359 -0.597415 +v -0.876796 1.102077 -0.565272 +v -0.535923 0.721706 -0.600252 +v -0.522881 0.720341 -0.604253 +v -0.508861 0.735782 -0.577159 +v -0.520523 0.738456 -0.570377 +v -0.535923 0.721706 -0.600252 +v -0.520523 0.738456 -0.570377 +v -0.523745 0.862927 -0.534165 +v -0.464863 0.801568 -0.537390 +v -0.433965 0.835618 -0.535905 +v -0.492214 0.897654 -0.532683 +v -0.456398 0.794546 -0.547092 +v -0.427433 0.826566 -0.545674 +v -0.433965 0.835618 -0.535905 +v -0.427433 0.826566 -0.545674 +v -0.401219 0.855427 -0.554922 +v -0.405876 0.866342 -0.545939 +v -0.405876 0.866342 -0.545939 +v -0.463585 0.929144 -0.543067 +v -0.693461 0.971664 -0.544416 +v -0.850379 1.132114 -0.541925 +v -0.554992 0.827848 -0.546298 +v -0.661562 1.007071 -0.531924 +v -0.818804 1.169035 -0.529021 +v -0.495408 0.767001 -0.549050 +v -0.508861 0.735782 -0.577159 +v -0.485249 0.762269 -0.557771 +v -1.333160 1.525384 -0.596265 +v -1.337248 1.521874 -0.586371 +v -1.333160 1.525384 -0.596265 +v -1.324731 1.555456 -0.578061 +v -1.322206 1.556126 -0.589061 +v -1.322206 1.556126 -0.589061 +v -1.222816 1.570535 -0.597771 +v -1.275653 1.601554 -0.597685 +v -1.267516 1.622265 -0.611548 +v -1.214505 1.591132 -0.611623 +v -1.292441 1.610116 -0.597075 +v -1.284239 1.631024 -0.611034 +v -1.278826 1.646183 -0.629558 +v -1.262153 1.637269 -0.629948 +v -1.209033 1.606053 -0.630001 +v -1.309201 1.586461 -0.587977 +v -1.304265 1.583992 -0.590942 +v -1.310585 1.588754 -0.576899 +v -1.309201 1.586461 -0.587977 +v -1.297506 1.618461 -0.584228 +v -1.297095 1.613336 -0.594424 +v -1.297095 1.613336 -0.594424 +v -1.292441 1.610116 -0.597075 +v -1.287405 1.575613 -0.591648 +v -1.234724 1.544713 -0.591748 +v -1.275653 1.601554 -0.597685 +v -1.222816 1.570535 -0.597771 +v -0.629724 1.042550 -0.530432 +v -0.787733 1.206489 -0.527497 +v -0.601037 1.074986 -0.541093 +v -0.760031 1.240955 -0.538495 +v -0.721270 1.291850 -0.593895 +v -0.560442 1.122898 -0.595046 +v -0.549951 1.135738 -0.629739 +v -0.711673 1.305630 -0.629401 +v -0.422733 0.975486 -0.596009 +v -0.411813 0.987745 -0.630111 +v -0.408449 0.991190 -0.667529 +v -0.547183 1.139593 -0.667732 +v -0.709689 1.310008 -0.668182 +v -0.577668 1.102240 -0.564046 +v -0.737600 1.269894 -0.562093 +v -0.440166 0.955544 -0.565565 +v -0.577668 1.102240 -0.564046 +v -0.440166 0.955544 -0.565565 +v -0.737600 1.269894 -0.562093 +v -0.382880 0.891987 -0.567907 +v -0.379738 0.879244 -0.575341 +v -0.382880 0.891987 -0.567907 +v -0.363688 0.897053 -0.602972 +v -0.365695 0.911299 -0.597668 +v -1.297095 1.613336 -0.594424 +v -1.288576 1.634949 -0.608826 +v -1.287873 1.642532 -0.600380 +v -1.288576 1.634949 -0.608826 +v -1.281231 1.660164 -0.621904 +v -1.282900 1.650659 -0.627934 +v -1.282900 1.650659 -0.627934 +v -0.351176 0.926486 -0.667469 +v -0.355886 0.920384 -0.706273 +v -0.413646 0.984907 -0.707212 +v -0.350193 0.911396 -0.667238 +v -0.354452 0.906210 -0.702718 +v -0.366563 0.892410 -0.733098 +v -0.369365 0.904705 -0.739652 +v -0.413646 0.984907 -0.707212 +v -0.355886 0.920384 -0.706273 +v -0.369365 0.904705 -0.739652 +v -0.427738 0.968758 -0.741331 +v -0.354786 0.923161 -0.630947 +v -0.353547 0.908079 -0.633700 +v -1.278792 1.660147 -0.648272 +v -1.274831 1.655389 -0.649140 +v -1.276674 1.670877 -0.645148 +v -1.278792 1.660147 -0.648272 +v -1.274338 1.674259 -0.669431 +v -1.276300 1.663235 -0.669148 +v -1.276300 1.663235 -0.669148 +v -1.272290 1.658526 -0.669158 +v -1.258203 1.646419 -0.649347 +v -1.205153 1.615202 -0.649354 +v -1.255702 1.649619 -0.669160 +v -1.202889 1.618490 -0.669101 +v -1.204257 1.609340 -0.704287 +v -1.256412 1.640136 -0.704480 +v -1.260028 1.630311 -0.712583 +v -1.208035 1.599640 -0.712364 +v -1.272961 1.648653 -0.704791 +v -1.276614 1.638634 -0.712976 +v -1.282133 1.626720 -0.712848 +v -1.265464 1.618574 -0.712432 +v -1.213467 1.587964 -0.712225 +v -1.275775 1.660110 -0.689795 +v -1.271568 1.655807 -0.688947 +v -1.274574 1.670242 -0.693879 +v -1.275775 1.660110 -0.689795 +v -1.277564 1.660081 -0.713873 +v -1.277475 1.652263 -0.706362 +v -1.277475 1.652263 -0.706362 +v -1.272961 1.648653 -0.704791 +v -1.255012 1.647074 -0.688771 +v -1.202543 1.616105 -0.688638 +v -1.256412 1.640136 -0.704480 +v -1.204257 1.609340 -0.704287 +v -0.553034 1.133493 -0.707927 +v -0.716049 1.303931 -0.709120 +v -0.553034 1.133493 -0.707927 +v -0.567620 1.117219 -0.742463 +v -0.716049 1.303931 -0.709120 +v -0.730639 1.287070 -0.744282 +v -0.476113 0.914535 -0.763898 +v -0.416573 0.852115 -0.761596 +v -0.440978 0.825296 -0.745319 +v -0.500941 0.886738 -0.747358 +v -0.416573 0.852115 -0.761596 +v -0.408627 0.845594 -0.752736 +v -0.430454 0.821455 -0.737888 +v -0.440978 0.825296 -0.745319 +v -0.447119 0.803173 -0.710895 +v -0.459416 0.805010 -0.715411 +v -0.500941 0.886738 -0.747358 +v -0.519567 0.865628 -0.716793 +v -0.590024 1.091691 -0.762923 +v -0.752374 1.260283 -0.765172 +v -0.449996 0.943732 -0.761501 +v -0.615967 1.061636 -0.765446 +v -0.777152 1.228466 -0.767857 +v -0.391008 0.880403 -0.759339 +v -0.366563 0.892410 -0.733098 +v -0.385857 0.870855 -0.750859 +v -0.408627 0.845594 -0.752736 +v -1.277475 1.652263 -0.706362 +v -1.281497 1.641368 -0.715005 +v -1.283265 1.645423 -0.724715 +v -1.281497 1.641368 -0.715005 +v -1.290900 1.628183 -0.725127 +v -1.287405 1.628502 -0.714990 +v -1.287405 1.628502 -0.714990 +v -0.468125 0.795108 -0.678864 +v -0.528187 0.855263 -0.679257 +v -0.455213 0.794354 -0.678180 +v -0.454369 0.794183 -0.648090 +v -0.467261 0.795003 -0.645017 +v -0.527196 0.855033 -0.644297 +v -1.282133 1.626720 -0.712848 +v -1.287405 1.628502 -0.714990 +v -1.294179 1.614978 -0.706961 +v -1.288543 1.614095 -0.705103 +v -1.299125 1.610674 -0.715458 +v -1.294179 1.614978 -0.706961 +v -1.305056 1.596536 -0.699134 +v -1.298972 1.603667 -0.693971 +v -1.298972 1.603667 -0.693971 +v -1.293073 1.603405 -0.692767 +v -1.271759 1.606114 -0.704725 +v -1.219641 1.575512 -0.704564 +v -1.288543 1.614095 -0.705103 +v -1.271759 1.606114 -0.704725 +v -1.276224 1.595537 -0.692495 +v -1.219641 1.575512 -0.704564 +v -1.224052 1.564941 -0.692394 +v -0.640394 1.032716 -0.748826 +v -0.800193 1.197549 -0.751074 +v -0.640394 1.032716 -0.748826 +v -0.658507 1.010515 -0.717931 +v -0.800193 1.197549 -0.751074 +v -0.817033 1.173573 -0.719661 +v -1.225752 1.559402 -0.668137 +v -1.278047 1.590068 -0.668125 +v -1.282414 1.597000 -0.661266 +v -1.229369 1.566102 -0.661300 +v -1.294911 1.597939 -0.667971 +v -1.299012 1.604557 -0.660930 +v -1.300998 1.609621 -0.657738 +v -1.287251 1.604126 -0.657406 +v -1.233708 1.573245 -0.657340 +v -1.299919 1.597488 -0.679604 +v -1.293916 1.597419 -0.679348 +v -1.306760 1.589176 -0.680397 +v -1.299919 1.597488 -0.679604 +v -1.307642 1.589752 -0.663674 +v -1.300888 1.598018 -0.667158 +v -1.300888 1.598018 -0.667158 +v -1.294911 1.597939 -0.667971 +v -1.277096 1.589574 -0.679257 +v -1.225019 1.559006 -0.679215 +v -1.278047 1.590068 -0.668125 +v -1.225752 1.559402 -0.668137 +v -0.666631 0.999384 -0.679809 +v -0.824296 1.161321 -0.680705 +v -0.665323 0.998813 -0.644161 +v -0.822646 1.160435 -0.644164 +v -1.099858 1.272169 -0.465362 +v -1.212667 1.345216 -0.461175 +v -1.208617 1.351111 -0.482316 +v -1.095073 1.276991 -0.485728 +v -1.311862 1.404712 -0.458427 +v -1.308452 1.411548 -0.480226 +v -1.305046 1.418380 -0.502026 +v -1.204573 1.357017 -0.503474 +v -1.090295 1.281837 -0.506125 +v -0.658244 1.007223 -0.619492 +v -0.814565 1.168214 -0.618724 +v -0.525054 0.868072 -0.620478 +v -0.658244 1.007223 -0.619492 +v -0.525054 0.868072 -0.620478 +v -0.545838 0.903982 -0.609738 +v -0.652697 1.019212 -0.606639 +v -0.814565 1.168214 -0.618724 +v -0.805751 1.177731 -0.605111 +v -0.467205 0.810545 -0.621857 +v -0.467261 0.795003 -0.645017 +v -0.454369 0.794183 -0.648090 +v -0.454610 0.808926 -0.627602 +v -0.467205 0.810545 -0.621857 +v -0.504459 0.877590 -0.616273 +v -0.515005 0.877785 -0.609292 +v -1.300888 1.598018 -0.667158 +v -1.304809 1.604761 -0.659122 +v -1.310380 1.597202 -0.652475 +v -1.304809 1.604761 -0.659122 +v -1.309401 1.603860 -0.646455 +v -1.305227 1.610508 -0.655019 +v -1.305227 1.610508 -0.655019 +v -0.435408 0.828360 -0.660957 +v -0.439169 0.845085 -0.664052 +v -0.440014 0.852701 -0.656983 +v -0.436382 0.837426 -0.651125 +v -0.439169 0.845085 -0.664052 +v -0.495811 0.907874 -0.664925 +v -0.494880 0.913347 -0.658688 +v -0.440014 0.852701 -0.656983 +v -0.516788 0.942120 -0.655891 +v -0.488577 0.911396 -0.653432 +v -0.488577 0.911396 -0.653432 +v -0.486900 0.899806 -0.645852 +v -0.644383 1.020901 -0.604033 +v -0.800709 1.183418 -0.602287 +v -0.644383 1.020901 -0.604033 +v -0.515005 0.877785 -0.609292 +v -0.504459 0.877590 -0.616273 +v -0.638362 1.025359 -0.611582 +v -0.800709 1.183418 -0.602287 +v -0.795947 1.189361 -0.610121 +v -0.779609 1.210369 -0.643683 +v -0.621236 1.045345 -0.643905 +v -0.618370 1.051566 -0.652320 +v -0.775758 1.215632 -0.652441 +v -0.516788 0.942120 -0.655891 +v -0.623167 1.056224 -0.655786 +v -0.776646 1.216229 -0.656121 +v -0.430994 0.832960 -0.692103 +v -0.435422 0.848762 -0.687676 +v -0.439954 0.845654 -0.675016 +v -0.436196 0.828842 -0.675643 +v -0.492344 0.911615 -0.686918 +v -0.496591 0.908461 -0.675017 +v -0.495811 0.907874 -0.664925 +v -0.411193 0.856097 -0.714953 +v -0.420031 0.867354 -0.706209 +v -0.428239 0.856858 -0.699128 +v -0.421999 0.842984 -0.706450 +v -0.420031 0.867354 -0.706209 +v -0.477985 0.929386 -0.704721 +v -0.485628 0.919421 -0.697857 +v -0.428239 0.856858 -0.699128 +v -0.485628 0.919421 -0.697857 +v -1.333709 1.553387 -0.649068 +v -1.339098 1.544553 -0.645577 +v -1.335150 1.556124 -0.619159 +v -1.330916 1.564413 -0.625684 +v -1.339098 1.544553 -0.645577 +v -1.335519 1.540676 -0.644752 +v -1.331665 1.551966 -0.617733 +v -1.335150 1.556124 -0.619159 +v -1.335150 1.556124 -0.619159 +v -1.331665 1.551966 -0.617733 +v -1.326055 1.561494 -0.605679 +v -1.326677 1.566983 -0.605069 +v -1.326677 1.566983 -0.605069 +v -1.323508 1.574956 -0.612954 +v -0.390891 0.878668 -0.705069 +v -0.404869 0.884223 -0.698607 +v -0.412018 0.876913 -0.706225 +v -0.400379 0.868638 -0.714596 +v -0.463959 0.945112 -0.697569 +v -0.470561 0.938353 -0.704830 +v -0.411193 0.856097 -0.714953 +v -1.302980 1.625781 -0.768662 +v -1.305118 1.624892 -0.778784 +v -1.320821 1.586555 -0.760178 +v -1.317235 1.591428 -0.751695 +v -1.305118 1.624892 -0.778784 +v -1.300870 1.622704 -0.780861 +v -1.316923 1.583476 -0.761978 +v -1.320821 1.586555 -0.760178 +v -1.320821 1.586555 -0.760178 +v -1.316923 1.583476 -0.761978 +v -1.329047 1.553884 -0.727161 +v -1.332690 1.557575 -0.726000 +v -1.332690 1.557575 -0.726000 +v -1.327968 1.565273 -0.720849 +v -1.338601 1.543722 -0.684243 +v -1.333120 1.552600 -0.683459 +v -1.335069 1.539847 -0.684473 +v -1.338601 1.543722 -0.684243 +v -0.380863 0.886537 -0.666008 +v -0.396601 0.889285 -0.665809 +v -0.399276 0.888530 -0.684004 +v -0.383955 0.884851 -0.687495 +v -0.456383 0.949452 -0.665970 +v -0.458807 0.948980 -0.683517 +v -0.463959 0.945112 -0.697569 +v -0.404869 0.884223 -0.698607 +v -0.390891 0.878668 -0.705069 +v -0.389469 0.875755 -0.624269 +v -0.404114 0.879268 -0.629530 +v -0.398121 0.886129 -0.647423 +v -0.382674 0.883403 -0.644675 +v -0.463643 0.939402 -0.630888 +v -0.457898 0.946196 -0.648227 +v -1.263588 1.718334 -0.670959 +v -1.260267 1.728778 -0.671233 +v -1.264304 1.720953 -0.715574 +v -1.266864 1.711396 -0.711502 +v -1.260267 1.728778 -0.671233 +v -1.254752 1.729475 -0.671201 +v -1.258998 1.721249 -0.716381 +v -1.264304 1.720953 -0.715574 +v -1.268937 1.698994 -0.755229 +v -1.273929 1.699378 -0.753716 +v -1.273929 1.699378 -0.753716 +v -1.275197 1.692133 -0.746218 +v -1.288439 1.665141 -0.776210 +v -1.288026 1.661658 -0.766515 +v -1.273929 1.699378 -0.753716 +v -1.268937 1.698994 -0.755229 +v -1.283812 1.663894 -0.778174 +v -1.288439 1.665141 -0.776210 +v -0.416444 0.847187 -0.591253 +v -0.428405 0.853907 -0.600121 +v -0.414454 0.868814 -0.612746 +v -0.400971 0.863857 -0.605394 +v -0.428405 0.853907 -0.600121 +v -0.487028 0.914553 -0.602191 +v -0.473548 0.929149 -0.614509 +v -0.414454 0.868814 -0.612746 +v -0.473548 0.929149 -0.614509 +v -1.271799 1.697383 -0.597517 +v -1.268768 1.706313 -0.591485 +v -1.261893 1.723400 -0.629504 +v -1.265371 1.713248 -0.632633 +v -1.268768 1.706313 -0.591485 +v -1.263302 1.706783 -0.589869 +v -1.256320 1.724145 -0.628632 +v -1.261893 1.723400 -0.629504 +v -0.456134 0.802004 -0.585904 +v -0.464357 0.812520 -0.595478 +v -0.445175 0.834222 -0.594502 +v -0.435066 0.825694 -0.584863 +v -0.522289 0.873928 -0.597803 +v -0.503422 0.895250 -0.596811 +v -0.416444 0.847187 -0.591253 +v -0.495637 0.761661 -0.605282 +v -0.500773 0.776495 -0.611985 +v -0.484648 0.792246 -0.601783 +v -0.478064 0.779465 -0.593172 +v -0.558093 0.838599 -0.613402 +v -0.542263 0.853982 -0.603768 +v -1.332340 1.551472 -0.533630 +v -1.333498 1.550234 -0.522630 +v -1.313448 1.598783 -0.520934 +v -1.313431 1.597059 -0.532014 +v -1.333498 1.550234 -0.522630 +v -1.329124 1.548014 -0.519677 +v -1.308807 1.597278 -0.517991 +v -1.313448 1.598783 -0.520934 +v -1.290577 1.642054 -0.529762 +v -1.295484 1.642817 -0.532394 +v -1.295484 1.642817 -0.532394 +v -1.296438 1.638261 -0.542593 +v -1.280276 1.679111 -0.557487 +v -1.282342 1.672099 -0.565935 +v -1.295484 1.642817 -0.532394 +v -1.290577 1.642054 -0.529762 +v -1.275065 1.679042 -0.555295 +v -1.280276 1.679111 -0.557487 +v -1.367373 1.468546 -0.568008 +v -1.371528 1.461930 -0.560306 +v -1.354289 1.501805 -0.535945 +v -1.351566 1.505885 -0.545839 +v -1.371528 1.461930 -0.560306 +v -1.367789 1.458475 -0.558503 +v -1.350235 1.498950 -0.533426 +v -1.354289 1.501805 -0.535945 +v -0.498042 0.753069 -0.687673 +v -0.500263 0.769434 -0.684912 +v -0.505347 0.765205 -0.661521 +v -0.503078 0.748526 -0.662635 +v -0.557217 0.833010 -0.684314 +v -0.562240 0.828587 -0.661275 +v -0.565494 0.827305 -0.641544 +v -0.508559 0.764246 -0.641322 +v -0.505775 0.747515 -0.640208 +v -0.508103 0.767481 -0.625000 +v -0.504297 0.751319 -0.621044 +v -0.565187 0.830068 -0.625798 +v -0.508103 0.767481 -0.625000 +v -0.565187 0.830068 -0.625798 +v -0.500773 0.776495 -0.611985 +v -0.495637 0.761661 -0.605282 +v -0.483961 0.769590 -0.739800 +v -0.487101 0.785312 -0.734544 +v -0.494354 0.776258 -0.710155 +v -0.491812 0.760167 -0.714209 +v -0.544458 0.849032 -0.733441 +v -0.551468 0.839942 -0.709298 +v -1.373908 1.448295 -0.706878 +v -1.378083 1.437849 -0.710097 +v -1.382482 1.429514 -0.671986 +v -1.377918 1.440062 -0.670679 +v -1.378083 1.437849 -0.710097 +v -1.374658 1.432943 -0.711030 +v -1.379102 1.424677 -0.672388 +v -1.382482 1.429514 -0.671986 +v -1.380954 1.423671 -0.633034 +v -1.384338 1.428224 -0.633287 +v -1.384338 1.428224 -0.633287 +v -1.379428 1.438248 -0.634559 +v -1.381323 1.437845 -0.594435 +v -1.376463 1.446513 -0.598981 +v -1.377818 1.433790 -0.593423 +v -1.381323 1.437845 -0.594435 +v -1.381323 1.437845 -0.594435 +v -1.377818 1.433790 -0.593423 +v -0.460778 0.795864 -0.780835 +v -0.465658 0.809984 -0.773021 +v -0.477686 0.796435 -0.755588 +v -0.473752 0.781374 -0.762144 +v -0.523688 0.873605 -0.771291 +v -0.535353 0.860131 -0.754182 +v -0.427661 0.832518 -0.806483 +v -0.434870 0.844162 -0.796932 +v -0.450976 0.826177 -0.786975 +v -0.445022 0.813215 -0.795813 +v -0.434870 0.844162 -0.796932 +v -0.493732 0.907474 -0.794708 +v -0.509409 0.889677 -0.784956 +v -0.450976 0.826177 -0.786975 +v -0.523688 0.873605 -0.771291 +v -0.465658 0.809984 -0.773021 +v -1.362658 1.475872 -0.778004 +v -1.366541 1.466728 -0.784122 +v -1.372971 1.450139 -0.747905 +v -1.368960 1.460102 -0.743185 +v -1.366541 1.466728 -0.784122 +v -1.363032 1.462193 -0.785851 +v -1.369512 1.445350 -0.749254 +v -1.372971 1.450139 -0.747905 +v -0.394075 0.870341 -0.812972 +v -0.404144 0.879058 -0.803081 +v -0.418833 0.862575 -0.802332 +v -0.410179 0.852358 -0.812242 +v -0.463886 0.941775 -0.800758 +v -0.478138 0.925613 -0.800015 +v -0.410179 0.852358 -0.812242 +v -0.418833 0.862575 -0.802332 +v -1.315863 1.589354 -0.873902 +v -1.317367 1.586446 -0.884963 +v -1.332711 1.549369 -0.868669 +v -1.330417 1.554238 -0.858408 +v -1.317367 1.586446 -0.884963 +v -1.313167 1.583694 -0.888053 +v -1.328732 1.546073 -0.871542 +v -1.332711 1.549369 -0.868669 +v -1.332711 1.549369 -0.868669 +v -1.328732 1.546073 -0.871542 +v -1.342680 1.512479 -0.848264 +v -1.346457 1.516250 -0.845722 +v -1.346457 1.516250 -0.845722 +v -1.343449 1.522808 -0.836624 +v -1.357780 1.488647 -0.817153 +v -1.354225 1.496643 -0.809515 +v -1.354164 1.484460 -0.819293 +v -1.357780 1.488647 -0.817153 +v -0.369201 0.896564 -0.801474 +v -0.381546 0.902407 -0.792752 +v -0.391757 0.891831 -0.799457 +v -0.380500 0.884626 -0.808941 +v -0.442029 0.964480 -0.790650 +v -0.451905 0.954222 -0.797192 +v -0.350905 0.918063 -0.777125 +v -0.365344 0.921908 -0.770854 +v -0.373024 0.912570 -0.783832 +v -0.359561 0.907813 -0.791475 +v -0.426218 0.983385 -0.769448 +v -0.433739 0.974340 -0.782034 +v -1.264181 1.713415 -0.864220 +v -1.262114 1.718696 -0.874338 +v -1.273350 1.692261 -0.887384 +v -1.274529 1.688776 -0.876383 +v -1.262114 1.718696 -0.874338 +v -1.256904 1.718264 -0.877183 +v -1.268387 1.691320 -0.890440 +v -1.273350 1.692261 -0.887384 +v -1.281768 1.660003 -0.897635 +v -1.286447 1.661516 -0.894486 +v -1.286447 1.661516 -0.894486 +v -1.286621 1.660008 -0.883023 +v -1.301494 1.625158 -0.893718 +v -1.300786 1.625858 -0.882243 +v -1.297066 1.623020 -0.896888 +v -1.301494 1.625158 -0.893718 +v -0.336268 0.933082 -0.731910 +v -0.351701 0.935388 -0.728860 +v -0.357934 0.929596 -0.752072 +v -0.342856 0.926606 -0.756740 +v -0.412746 0.996351 -0.728259 +v -0.418928 0.990797 -0.751081 +v -0.357934 0.929596 -0.752072 +v -0.418928 0.990797 -0.751081 +v -0.365344 0.921908 -0.770854 +v -0.350905 0.918063 -0.777125 +v -1.246809 1.755624 -0.825454 +v -1.243723 1.764058 -0.832718 +v -1.252353 1.742723 -0.856824 +v -1.254986 1.735751 -0.847966 +v -1.243723 1.764058 -0.832718 +v -1.238236 1.764471 -0.834716 +v -1.246991 1.742740 -0.859298 +v -1.252353 1.742723 -0.856824 +v -0.330211 0.939122 -0.678044 +v -0.345855 0.940866 -0.677680 +v -0.347670 0.939179 -0.703360 +v -0.332066 0.937266 -0.704979 +v -0.406744 1.001528 -0.677704 +v -0.408667 0.999964 -0.703097 +v -0.333317 0.935678 -0.624928 +v -0.348791 0.937538 -0.626885 +v -0.346125 0.940352 -0.653006 +v -0.330536 0.938634 -0.652217 +v -0.409407 0.998077 -0.627393 +v -0.406891 1.000931 -0.653282 +v -1.229267 1.796023 -0.685071 +v -1.224658 1.806774 -0.685513 +v -1.226318 1.803329 -0.723481 +v -1.230793 1.792711 -0.721582 +v -1.224658 1.806774 -0.685513 +v -1.218709 1.807978 -0.685631 +v -1.220411 1.804478 -0.724012 +v -1.226318 1.803329 -0.723481 +v -1.224259 1.796171 -0.763482 +v -1.230072 1.795164 -0.762495 +v -1.230072 1.795164 -0.762495 +v -1.234243 1.784923 -0.758941 +v -1.236084 1.781848 -0.800229 +v -1.239731 1.772323 -0.794812 +v -1.230432 1.782602 -0.801715 +v -1.236084 1.781848 -0.800229 +v -1.238236 1.764471 -0.834716 +v -1.243723 1.764058 -0.832718 +v -1.231620 1.790287 -0.613740 +v -1.227083 1.800844 -0.611486 +v -1.224844 1.806019 -0.649397 +v -1.229490 1.795292 -0.650293 +v -1.227083 1.800844 -0.611486 +v -1.221156 1.801990 -0.610834 +v -1.218884 1.807224 -0.649131 +v -1.224844 1.806019 -0.649397 +v -0.365816 0.899870 -0.521296 +v -0.379556 0.903677 -0.528193 +v -0.369932 0.914687 -0.546228 +v -0.355518 0.911537 -0.540466 +v -0.439476 0.964440 -0.529675 +v -0.430023 0.975332 -0.547470 +v -0.421592 0.985230 -0.570075 +v -0.361345 0.924654 -0.569090 +v -0.346375 0.922003 -0.564560 +v -0.354064 0.932333 -0.597482 +v -0.338766 0.930134 -0.594253 +v -0.414497 0.992872 -0.598223 +v -0.388701 0.875822 -0.493438 +v -0.400858 0.881800 -0.502243 +v -0.390001 0.892791 -0.513436 +v -0.376963 0.888041 -0.505515 +v -0.460241 0.942985 -0.504075 +v -0.449687 0.953730 -0.515111 +v -1.257547 1.728442 -0.472682 +v -1.254241 1.736256 -0.464660 +v -1.245431 1.757743 -0.493075 +v -1.249096 1.748901 -0.499773 +v -1.254241 1.736256 -0.464660 +v -1.248671 1.736592 -0.462365 +v -1.239763 1.758359 -0.491159 +v -1.245431 1.757743 -0.493075 +v -1.232084 1.777269 -0.526144 +v -1.237823 1.776429 -0.527638 +v -1.237823 1.776429 -0.527638 +v -1.241741 1.766767 -0.532895 +v -1.231548 1.790944 -0.569070 +v -1.235794 1.780724 -0.572807 +v -1.225710 1.791964 -0.568005 +v -1.231548 1.790944 -0.569070 +v -0.417150 0.844390 -0.483320 +v -0.426739 0.853193 -0.493243 +v -0.412264 0.869627 -0.495322 +v -0.401306 0.862216 -0.485818 +v -0.485421 0.914981 -0.495324 +v -0.471291 0.931119 -0.497293 +v -0.460241 0.942985 -0.504075 +v -0.400858 0.881800 -0.502243 +v -0.401306 0.862216 -0.485818 +v -0.412264 0.869627 -0.495322 +v -1.339326 1.534829 -0.427916 +v -1.360064 1.490718 -0.440861 +v -1.360791 1.487622 -0.429340 +v -1.340025 1.532406 -0.416388 +v -1.371917 1.456544 -0.451836 +v -1.372326 1.454140 -0.440022 +v -1.360791 1.487622 -0.429340 +v -1.372326 1.454140 -0.440022 +v -1.367126 1.458621 -0.434790 +v -1.356194 1.485533 -0.425706 +v -1.340025 1.532406 -0.416388 +v -1.335608 1.529769 -0.413017 +v -0.717724 0.944887 -0.525390 +v -0.875535 1.102831 -0.523361 +v -0.717724 0.944887 -0.525390 +v -0.720301 0.940145 -0.515977 +v -0.875535 1.102831 -0.523361 +v -0.879463 1.099333 -0.513867 +v -1.264210 1.713112 -0.440617 +v -1.266866 1.706493 -0.449831 +v -1.275322 1.687593 -0.421567 +v -1.270187 1.687110 -0.418714 +v -1.258828 1.713088 -0.438015 +v -1.264210 1.713112 -0.440617 +v -0.446437 0.829874 -0.496321 +v -0.438164 0.819960 -0.486310 +v -0.504864 0.891889 -0.498481 +v -1.313198 1.583097 -0.476162 +v -1.314979 1.582759 -0.464543 +v -1.313198 1.583097 -0.476162 +v -0.890244 1.091397 -0.474957 +v -0.730415 0.931521 -0.477374 +v -0.732982 0.931892 -0.466827 +v -0.891817 1.090864 -0.464295 +v -0.732982 0.931892 -0.466827 +v -0.891817 1.090864 -0.464295 +v -1.320648 1.580808 -0.639081 +v -1.320675 1.571570 -0.656372 +v -1.316455 1.589409 -0.629707 +v -0.445495 0.823176 -0.639364 +v -0.444888 0.811271 -0.654524 +v -0.495677 0.888696 -0.631063 +v -0.454610 0.808926 -0.627602 +v -0.454369 0.794183 -0.648090 +v -1.239474 1.568193 -0.643876 +v -1.293787 1.599242 -0.644198 +v -1.299405 1.585654 -0.626183 +v -1.244986 1.554769 -0.625679 +v -1.309401 1.603860 -0.646455 +v -1.316455 1.589409 -0.629707 +v -1.323508 1.574956 -0.612954 +v -1.305025 1.572064 -0.608162 +v -1.250507 1.541346 -0.607477 +v -1.319940 1.570889 -0.681929 +v -1.316512 1.580904 -0.709993 +v -1.308180 1.601052 -0.733578 +v -1.296940 1.626982 -0.746896 +v -0.445704 0.811598 -0.676911 +v -0.439056 0.818066 -0.701499 +v -0.455213 0.794354 -0.678180 +v -0.447119 0.803173 -0.710895 +v -1.285645 1.653541 -0.745616 +v -1.276380 1.676108 -0.730047 +v -0.390891 0.878668 -0.705069 +v -0.400379 0.868638 -0.714596 +v -0.393118 0.869746 -0.732727 +v -0.378726 0.885540 -0.719084 +v -0.409910 0.850845 -0.733845 +v -0.408627 0.845594 -0.752736 +v -0.385857 0.870855 -0.750859 +v -0.426227 0.832220 -0.722169 +v -0.430454 0.821455 -0.737888 +v -1.270718 1.690820 -0.702692 +v -1.268962 1.696297 -0.670197 +v -1.271022 1.692064 -0.638891 +v -1.276515 1.678775 -0.609711 +v -0.389469 0.875755 -0.624269 +v -0.382674 0.883403 -0.644675 +v -0.368111 0.895741 -0.639187 +v -0.376578 0.886404 -0.613621 +v -0.380863 0.886537 -0.666008 +v -0.365527 0.898967 -0.666623 +v -0.383955 0.884851 -0.687495 +v -0.369203 0.895531 -0.695106 +v -1.285108 1.657316 -0.583158 +v -1.296972 1.628361 -0.563412 +v -0.416444 0.847187 -0.591253 +v -0.400971 0.863857 -0.605394 +v -0.390354 0.871551 -0.590368 +v -0.408831 0.851307 -0.573087 +v -1.312007 1.592907 -0.554457 +v -1.328535 1.553465 -0.555846 +v -1.344406 1.513881 -0.566106 +v -1.357186 1.481829 -0.584116 +v -0.478064 0.779465 -0.593172 +v -0.481656 0.770867 -0.575471 +v -0.502249 0.748721 -0.591221 +v -0.456134 0.802004 -0.585904 +v -0.456266 0.798275 -0.566498 +v -0.456398 0.794546 -0.547092 +v -0.485249 0.762269 -0.557771 +v -0.508861 0.735782 -0.577159 +v -0.435066 0.825694 -0.584863 +v -0.431249 0.826130 -0.565269 +v -0.513589 0.735830 -0.612648 +v -0.517042 0.731205 -0.637794 +v -0.522881 0.720341 -0.604253 +v -0.528308 0.714896 -0.635379 +v -1.367384 1.460593 -0.668153 +v -1.364264 1.468417 -0.700533 +v -1.368015 1.458028 -0.637314 +v -1.364941 1.463837 -0.608600 +v -1.359673 1.479225 -0.733846 +v -1.353599 1.493422 -0.765857 +v -0.503377 0.745764 -0.722312 +v -0.494392 0.755925 -0.750339 +v -0.510239 0.738042 -0.693165 +v -0.522435 0.723015 -0.698657 +v -0.514942 0.731360 -0.730415 +v -0.504823 0.742260 -0.760878 +v -0.515261 0.732644 -0.664810 +v -0.527444 0.716762 -0.666985 +v -1.345795 1.511957 -0.794312 +v -1.336093 1.535287 -0.818499 +v -1.324483 1.563355 -0.837980 +v -1.311503 1.594558 -0.851866 +v -0.482656 0.769039 -0.775304 +v -0.467844 0.785440 -0.796513 +v -0.491559 0.756703 -0.788464 +v -0.474910 0.775016 -0.812191 +v -1.298009 1.626655 -0.859308 +v -1.285588 1.656416 -0.860070 +v -0.394075 0.870341 -0.812972 +v -0.409786 0.849853 -0.832158 +v -0.390884 0.870839 -0.832872 +v -0.430138 0.827137 -0.825628 +v -0.432615 0.821756 -0.844773 +v -0.409393 0.847348 -0.852075 +v -0.387692 0.871338 -0.852772 +v -0.449979 0.805153 -0.813524 +v -0.454937 0.797091 -0.831235 +v -1.275491 1.681283 -0.854429 +v -1.266918 1.702350 -0.844102 +v -1.258866 1.721262 -0.830322 +v -1.251596 1.738192 -0.810925 +v -0.350905 0.918063 -0.777125 +v -0.359561 0.907813 -0.791475 +v -0.349608 0.916259 -0.806781 +v -0.338959 0.928334 -0.789751 +v -0.369201 0.896564 -0.801474 +v -0.361534 0.902821 -0.818900 +v -0.353867 0.909077 -0.836325 +v -0.380500 0.884626 -0.808941 +v -0.374986 0.888149 -0.827956 +v -0.369471 0.891672 -0.846972 +v -1.245615 1.752786 -0.783979 +v -1.241138 1.764072 -0.751864 +v -0.336268 0.933082 -0.731910 +v -0.342856 0.926606 -0.756740 +v -0.329659 0.938529 -0.766153 +v -0.322412 0.946294 -0.738049 +v -1.238273 1.771179 -0.717815 +v -1.237000 1.774261 -0.684190 +v -1.237290 1.773592 -0.652055 +v -1.239210 1.768905 -0.618193 +v -0.333317 0.935678 -0.624928 +v -0.330536 0.938634 -0.652217 +v -0.316339 0.952887 -0.650678 +v -0.319305 0.949634 -0.621045 +v -0.330211 0.939122 -0.678044 +v -0.315932 0.953354 -0.678803 +v -0.332066 0.937266 -0.704979 +v -0.317880 0.951205 -0.708241 +v -0.346375 0.922003 -0.564560 +v -0.338766 0.930134 -0.594253 +v -0.325028 0.943422 -0.587804 +v -0.333236 0.934394 -0.555497 +v -1.254987 1.730833 -0.513023 +v -1.262718 1.712431 -0.488555 +v -1.248141 1.747051 -0.543318 +v -1.242831 1.759946 -0.580215 +v -1.270756 1.692818 -0.468131 +v -1.279316 1.671784 -0.452247 +v -0.388701 0.875822 -0.493438 +v -0.376963 0.888041 -0.505515 +v -0.367652 0.896199 -0.489633 +v -0.381088 0.881543 -0.475710 +v -0.365816 0.899870 -0.521296 +v -0.355146 0.909907 -0.507521 +v -0.355518 0.911537 -0.540466 +v -0.343492 0.922910 -0.528959 +v -1.289004 1.648274 -0.441946 +v -1.301212 1.619013 -0.438184 +v -1.319343 1.580357 -0.418378 +v -1.317160 1.581559 -0.441467 +v -1.336599 1.539010 -0.450595 +v -0.462415 0.790161 -0.494056 +v -0.438164 0.819960 -0.486310 +v -0.438293 0.817798 -0.466269 +v -0.464678 0.786474 -0.474324 +v -0.417150 0.844390 -0.483320 +v -0.414635 0.844447 -0.463343 +v -0.438423 0.815636 -0.446228 +v -0.466940 0.782788 -0.454593 +v -0.401306 0.862216 -0.485818 +v -0.396060 0.865068 -0.466651 +v -0.502185 0.758397 -0.465842 +v -0.498584 0.762904 -0.485301 +v -0.577252 0.800575 -0.494171 +v -0.498584 0.762904 -0.485301 +v -0.494982 0.767412 -0.504760 +v -1.357081 1.496710 -0.463207 +v -1.368845 1.463430 -0.474005 +v -1.362008 1.435263 -0.456657 +v -1.358872 1.442435 -0.478733 +v -1.371917 1.456544 -0.451836 +v -1.368845 1.463430 -0.474005 +v -1.365777 1.470306 -0.496165 +v -1.355740 1.449597 -0.500801 +v -1.319759 1.579448 -0.406739 +v -1.315259 1.577258 -0.403434 +v -1.319759 1.579448 -0.406739 +v -1.007670 1.416536 -0.643840 +v -1.131901 1.501269 -0.643871 +v -1.137720 1.488012 -0.625707 +v -1.014096 1.403825 -0.625904 +v -1.143561 1.474764 -0.607538 +v -1.020558 1.391131 -0.607962 +v -1.362572 1.433386 -0.444628 +v -1.372326 1.454140 -0.440022 +v -1.312622 1.403093 -0.446501 +v -1.362572 1.433386 -0.444628 +v -1.312622 1.403093 -0.446501 +v -1.306146 1.415315 -0.438395 +v -1.356086 1.445083 -0.436732 +v -1.345772 1.467758 -0.510649 +v -1.353103 1.454926 -0.511550 +v -1.294900 1.436958 -0.511602 +v -1.302314 1.423640 -0.512642 +v -1.353103 1.454926 -0.511550 +v -1.302314 1.423640 -0.512642 +v -1.363068 1.474821 -0.507061 +v -1.290527 1.605646 -0.653568 +v -1.305227 1.610508 -0.655019 +v -1.236394 1.574589 -0.653367 +v -1.233708 1.573245 -0.657340 +v -1.287251 1.604126 -0.657406 +v -1.300998 1.609621 -0.657738 +v -1.310413 1.556591 -0.602670 +v -1.308054 1.564292 -0.599749 +v -1.256529 1.525882 -0.602046 +v -1.253637 1.533652 -0.598980 +v -1.308054 1.564292 -0.599749 +v -1.253637 1.533652 -0.598980 +v -1.326677 1.566983 -0.605069 +v -1.318583 1.531997 -0.644575 +v -1.314920 1.543652 -0.616999 +v -1.265347 1.501033 -0.644505 +v -1.261296 1.512559 -0.616829 +v -1.314920 1.543652 -0.616999 +v -1.261296 1.512559 -0.616829 +v -1.312221 1.545276 -0.727298 +v -1.318211 1.531215 -0.684496 +v -1.259548 1.514698 -0.726971 +v -1.265331 1.500499 -0.684344 +v -1.002699 1.417797 -0.691577 +v -1.121337 1.499974 -0.692228 +v -1.122517 1.494111 -0.679121 +v -1.004312 1.412191 -0.678659 +v -1.122803 1.494301 -0.668085 +v -1.004120 1.412128 -0.667764 +v -1.004120 1.412128 -0.667764 +v -1.122803 1.494301 -0.668085 +v -1.124606 1.500268 -0.661265 +v -1.003694 1.416992 -0.661026 +v -1.126968 1.506625 -0.657312 +v -1.003608 1.422160 -0.657117 +v -1.283919 1.614299 -0.781018 +v -1.300056 1.574957 -0.762150 +v -1.231158 1.583465 -0.780230 +v -1.247415 1.544342 -0.761574 +v -1.300056 1.574957 -0.762150 +v -1.247415 1.544342 -0.761574 +v -0.992007 1.440223 -0.710870 +v -1.110950 1.522970 -0.711865 +v -1.116970 1.510530 -0.704294 +v -0.998120 1.428076 -0.703444 +v -1.116970 1.510530 -0.704294 +v -0.998120 1.428076 -0.703444 +v -1.251792 1.690780 -0.755306 +v -1.266766 1.655581 -0.778297 +v -1.198495 1.659205 -0.754566 +v -1.213771 1.624381 -0.777449 +v -1.237434 1.721520 -0.671124 +v -1.241757 1.713170 -0.716397 +v -1.183550 1.689592 -0.670906 +v -1.188144 1.681345 -0.715902 +v -1.241757 1.713170 -0.716397 +v -1.188144 1.681345 -0.715902 +v -1.258998 1.721249 -0.716381 +v -0.976824 1.467775 -0.668559 +v -1.098428 1.552465 -0.668956 +v -1.098822 1.550393 -0.688377 +v -0.978043 1.466146 -0.687694 +v -1.101246 1.543968 -0.703930 +v -0.981352 1.460293 -0.703016 +v -0.981352 1.460293 -0.703016 +v -1.101246 1.543968 -0.703930 +v -1.105436 1.534521 -0.711972 +v -0.986171 1.451365 -0.710950 +v -0.982113 1.455287 -0.630137 +v -1.104001 1.539877 -0.630012 +v -1.100208 1.549010 -0.649301 +v -0.978183 1.464187 -0.649176 +v -1.273392 1.633901 -0.529237 +v -1.257782 1.671016 -0.554854 +v -1.219539 1.602520 -0.529416 +v -1.203696 1.639402 -0.555022 +v -1.191830 1.667073 -0.589631 +v -1.245961 1.698855 -0.589525 +v -1.238967 1.716245 -0.628420 +v -1.184908 1.684345 -0.628404 +v -1.312206 1.539690 -0.519048 +v -1.291751 1.589018 -0.517374 +v -1.259449 1.509074 -0.519197 +v -1.238366 1.557962 -0.517531 +v -1.219539 1.602520 -0.529416 +v -1.273392 1.633901 -0.529237 +v -1.027433 1.369967 -0.593546 +v -1.145072 1.450723 -0.592955 +v -1.131091 1.479364 -0.591830 +v -1.011956 1.397262 -0.592429 +v -1.118652 1.504845 -0.597844 +v -0.998484 1.421716 -0.598365 +v -0.998484 1.421716 -0.598365 +v -1.118652 1.504845 -0.597844 +v -1.109816 1.525149 -0.611673 +v -0.988653 1.441164 -0.612025 +v -1.351128 1.450097 -0.558209 +v -1.333446 1.490603 -0.532935 +v -1.299668 1.420592 -0.558416 +v -1.281365 1.460543 -0.533123 +v -1.364549 1.415112 -0.633002 +v -1.361292 1.425330 -0.593278 +v -1.313934 1.386344 -0.633009 +v -1.310322 1.396263 -0.593420 +v -1.361292 1.425330 -0.593278 +v -1.310322 1.396263 -0.593420 +v -1.063366 1.310988 -0.641601 +v -1.176616 1.387957 -0.641619 +v -1.174139 1.389306 -0.624086 +v -1.061230 1.312342 -0.624298 +v -1.174139 1.389306 -0.624086 +v -1.168142 1.399909 -0.610295 +v -1.061230 1.312342 -0.624298 +v -1.054643 1.322322 -0.610678 +v -1.158042 1.422124 -0.599590 +v -1.042628 1.343079 -0.600103 +v -1.358372 1.424289 -0.711187 +v -1.362777 1.416046 -0.672461 +v -1.308129 1.395804 -0.710792 +v -1.312403 1.387455 -0.672292 +v -1.060040 1.322033 -0.688489 +v -1.174346 1.399474 -0.689243 +v -1.176511 1.392041 -0.663593 +v -1.062659 1.314822 -0.663262 +v -1.346723 1.453637 -0.786082 +v -1.353227 1.436727 -0.749457 +v -1.296492 1.425280 -0.785051 +v -1.303018 1.408329 -0.748772 +v -1.326287 1.504070 -0.848558 +v -1.337818 1.475979 -0.819556 +v -1.275969 1.475510 -0.846742 +v -1.287550 1.447579 -0.818139 +v -1.036047 1.375507 -0.782248 +v -1.151054 1.453939 -0.785175 +v -1.158901 1.435638 -0.766525 +v -1.044348 1.357812 -0.764118 +v -1.165313 1.420835 -0.743759 +v -1.050941 1.343314 -0.741886 +v -1.170517 1.408986 -0.717029 +v -1.056122 1.331513 -0.715732 +v -1.296654 1.575406 -0.888365 +v -1.312284 1.537727 -0.871856 +v -1.246152 1.546116 -0.885829 +v -1.261892 1.508867 -0.869656 +v -1.312284 1.537727 -0.871856 +v -1.261892 1.508867 -0.869656 +v -1.014512 1.419423 -0.806640 +v -1.130991 1.499780 -0.810557 +v -1.141600 1.475843 -0.800031 +v -1.025893 1.396531 -0.796572 +v -1.141600 1.475843 -0.800031 +v -1.151054 1.453939 -0.785175 +v -1.036047 1.375507 -0.782248 +v -1.265098 1.651839 -0.897888 +v -1.280477 1.614791 -0.897171 +v -1.214300 1.621472 -0.894969 +v -1.229831 1.584971 -0.894380 +v -1.240080 1.710221 -0.877410 +v -1.251638 1.683222 -0.890686 +v -1.188987 1.678920 -0.874655 +v -1.200706 1.652368 -0.887793 +v -0.976679 1.492161 -0.801418 +v -1.096408 1.576689 -0.805518 +v -1.102725 1.562488 -0.812698 +v -0.983824 1.478878 -0.808445 +v -1.110212 1.545169 -0.816730 +v -0.992259 1.462615 -0.812421 +v -1.120016 1.523681 -0.816139 +v -1.002834 1.442228 -0.811936 +v -0.963154 1.514757 -0.778943 +v -1.083843 1.600678 -0.782487 +v -1.089973 1.589265 -0.796162 +v -0.969774 1.504017 -0.792271 +v -1.207141 1.788281 -0.763493 +v -1.213387 1.774666 -0.801761 +v -1.154951 1.755657 -0.762172 +v -1.161489 1.742246 -0.799954 +v -1.213387 1.774666 -0.801761 +v -1.161489 1.742246 -0.799954 +v -1.169665 1.724368 -0.832574 +v -1.221271 1.756490 -0.834812 +v -1.230432 1.782602 -0.801715 +v -1.230097 1.734730 -0.859466 +v -1.178772 1.702995 -0.856920 +v -1.201490 1.800127 -0.685578 +v -1.203234 1.796614 -0.723992 +v -1.148778 1.767352 -0.685127 +v -1.150765 1.763877 -0.723132 +v -0.945937 1.538630 -0.680842 +v -1.069963 1.626879 -0.681756 +v -1.071689 1.624521 -0.709764 +v -0.948258 1.536579 -0.708183 +v -1.074675 1.619162 -0.737429 +v -0.952071 1.531749 -0.735137 +v -1.078719 1.610925 -0.762435 +v -0.957142 1.524240 -0.759452 +v -1.078719 1.610925 -0.762435 +v -1.181423 1.677761 -0.764578 +v -0.957142 1.524240 -0.759452 +v -1.203895 1.794139 -0.610710 +v -1.201636 1.799378 -0.649044 +v -1.150847 1.761466 -0.610927 +v -1.148734 1.766628 -0.648938 +v -1.214841 1.769381 -0.525931 +v -1.208451 1.784095 -0.567842 +v -1.161666 1.737025 -0.526771 +v -1.155299 1.751550 -0.568387 +v -0.954089 1.516810 -0.563526 +v -1.077981 1.604099 -0.562108 +v -1.073601 1.614722 -0.593478 +v -0.949320 1.526908 -0.594347 +v -1.070917 1.622245 -0.625959 +v -0.946400 1.534051 -0.626221 +v -1.069705 1.626225 -0.654720 +v -0.945290 1.537885 -0.654402 +v -1.231501 1.728676 -0.462027 +v -1.222549 1.750461 -0.490882 +v -1.178556 1.696861 -0.463262 +v -1.169460 1.718361 -0.491946 +v -0.967948 1.490580 -0.519206 +v -1.090912 1.576595 -0.517073 +v -1.084080 1.591059 -0.536913 +v -0.960573 1.504358 -0.538741 +v -1.253150 1.679072 -0.418305 +v -1.241716 1.705123 -0.437636 +v -1.200511 1.647833 -0.419786 +v -1.188917 1.673590 -0.439016 +v -1.280784 1.612842 -0.399861 +v -1.265910 1.649097 -0.405252 +v -1.228664 1.582341 -0.401339 +v -1.213483 1.618193 -0.406769 +v -1.200511 1.647833 -0.419786 +v -1.253150 1.679072 -0.418305 +v -1.002316 1.425895 -0.481281 +v -1.121682 1.508403 -0.478708 +v -1.111476 1.529950 -0.480952 +v -0.991197 1.446459 -0.483558 +v -1.104112 1.546314 -0.488513 +v -0.982965 1.461982 -0.491061 +v -0.982965 1.461982 -0.491061 +v -1.104112 1.546314 -0.488513 +v -1.097524 1.561604 -0.500824 +v -0.975414 1.476409 -0.503205 +v -1.318922 1.521485 -0.412400 +v -1.298508 1.569008 -0.402887 +v -1.267601 1.492001 -0.413659 +v -1.246799 1.538994 -0.404258 +v -1.340280 1.476641 -0.425303 +v -1.289417 1.447457 -0.426592 +v -1.330086 1.496913 -0.501296 +v -1.278320 1.466753 -0.501904 +v -1.038587 1.362019 -0.493089 +v -1.155635 1.441630 -0.490722 +v -1.136548 1.478184 -0.482102 +v -1.018298 1.396977 -0.484583 +v -0.641783 1.036046 -0.497227 +v -0.798535 1.198543 -0.493824 +v -0.779382 1.223029 -0.490614 +v -0.622236 1.059412 -0.494034 +v -0.937898 1.280740 -0.497311 +v -0.915764 1.313052 -0.489009 +v -0.898057 1.339723 -0.485768 +v -0.597286 1.087882 -0.502885 +v -0.586941 1.098892 -0.514039 +v -0.755313 1.253156 -0.499750 +v -0.745485 1.264950 -0.511180 +v -0.735898 1.276628 -0.526242 +v -0.576892 1.109847 -0.528748 +v -0.876173 1.372804 -0.495277 +v -0.867398 1.385903 -0.507086 +v -0.858797 1.398812 -0.522639 +v -0.608173 1.075791 -0.496028 +v -0.765744 1.240300 -0.492702 +v -0.755313 1.253156 -0.499750 +v -0.597286 1.087882 -0.502885 +v -0.885584 1.358626 -0.487976 +v -0.876173 1.372804 -0.495277 +v -0.567496 1.120912 -0.546706 +v -0.726824 1.288267 -0.544625 +v -0.718820 1.298862 -0.567962 +v -0.559156 1.130987 -0.569517 +v -0.850529 1.411500 -0.541623 +v -0.843276 1.423013 -0.565709 +v -0.547558 1.144367 -0.627367 +v -0.545333 1.147427 -0.653461 +v -0.708256 1.313284 -0.627076 +v -0.706445 1.316628 -0.653693 +v -0.706906 1.317509 -0.678715 +v -0.545465 1.148186 -0.678038 +v -0.834224 1.438872 -0.626640 +v -0.832860 1.442487 -0.654031 +v -0.833549 1.443340 -0.679735 +v -0.552316 1.138890 -0.597931 +v -0.712481 1.307324 -0.597009 +v -0.837741 1.432300 -0.595661 +v -0.552007 1.143272 -0.728805 +v -0.558321 1.137761 -0.751665 +v -0.713921 1.312480 -0.730263 +v -0.720231 1.306672 -0.753414 +v -0.558321 1.137761 -0.751665 +v -0.720231 1.306672 -0.753414 +v -0.727578 1.298997 -0.771990 +v -0.565719 1.130400 -0.770026 +v -0.840479 1.437519 -0.732550 +v -0.846362 1.430939 -0.756212 +v -0.846362 1.430939 -0.756212 +v -0.853201 1.422442 -0.775184 +v -0.547684 1.146775 -0.703555 +v -0.709420 1.316113 -0.704647 +v -0.836135 1.441676 -0.706327 +v -0.573395 1.121468 -0.782575 +v -0.735265 1.289850 -0.784689 +v -0.743478 1.279737 -0.793395 +v -0.581737 1.111659 -0.791166 +v -0.860451 1.412583 -0.788164 +v -0.868075 1.401674 -0.797075 +v -0.603107 1.088592 -0.801348 +v -0.617099 1.072190 -0.800662 +v -0.763733 1.255301 -0.803790 +v -0.777062 1.238048 -0.803196 +v -0.791663 1.218635 -0.798006 +v -0.632419 1.053741 -0.795416 +v -0.886120 1.374792 -0.807776 +v -0.898096 1.356013 -0.807273 +v -0.911235 1.334927 -0.802094 +v -0.591425 1.101270 -0.797730 +v -0.752702 1.268760 -0.800068 +v -0.876330 1.389603 -0.803917 +v -0.647738 1.035500 -0.785730 +v -0.806148 1.199277 -0.788311 +v -0.819205 1.181561 -0.774603 +v -0.661630 1.018919 -0.772112 +v -0.924160 1.313786 -0.792296 +v -0.935742 1.294365 -0.778361 +v -0.681775 0.993423 -0.734188 +v -0.688565 0.983935 -0.709882 +v -0.838103 1.154203 -0.736176 +v -0.844479 1.143993 -0.711422 +v -0.849557 1.135928 -0.685710 +v -0.694079 0.976568 -0.684693 +v -0.838103 1.154203 -0.736176 +v -0.952527 1.264408 -0.739064 +v -0.958225 1.253275 -0.713632 +v -0.844479 1.143993 -0.711422 +v -0.962658 1.244377 -0.687155 +v -0.849557 1.135928 -0.685710 +v -0.523688 0.873605 -0.771291 +v -0.661630 1.018919 -0.772112 +v -0.672950 1.004959 -0.755004 +v -0.535353 0.860131 -0.754182 +v -0.819205 1.181561 -0.774603 +v -0.829822 1.166593 -0.757305 +v -0.681775 0.993423 -0.734188 +v -0.672950 1.004959 -0.755004 +v -0.935742 1.294365 -0.778361 +v -0.945156 1.277956 -0.760706 +v -0.698779 0.971609 -0.661463 +v -0.853672 1.130206 -0.661951 +v -0.855877 1.127599 -0.641580 +v -0.701646 0.969728 -0.641575 +v -0.965999 1.237810 -0.662639 +v -0.853672 1.130206 -0.661951 +v -0.967442 1.234501 -0.641587 +v -0.855877 1.127599 -0.641580 +v -0.693632 0.980243 -0.613273 +v -0.677823 0.995903 -0.603654 +v -0.847138 1.137762 -0.612555 +v -0.831797 1.154457 -0.602676 +v -0.812473 1.176228 -0.596562 +v -0.657879 1.016295 -0.597704 +v -0.958522 1.245073 -0.611544 +v -0.944572 1.263722 -0.601289 +v -0.927009 1.287992 -0.594933 +v -0.700954 0.971941 -0.625717 +v -0.854613 1.129317 -0.625323 +v -0.700954 0.971941 -0.625717 +v -0.854613 1.129317 -0.625323 +v -0.967442 1.234501 -0.641587 +v -0.965696 1.235947 -0.624772 +v -0.965696 1.235947 -0.624772 +v -0.965696 1.235947 -0.624772 +v -0.622378 1.057439 -0.602076 +v -0.609165 1.072449 -0.614518 +v -0.777593 1.219550 -0.601051 +v -0.765015 1.235652 -0.613839 +v -0.609165 1.072449 -0.614518 +v -0.765015 1.235652 -0.613839 +v -0.756192 1.247279 -0.630826 +v -0.599648 1.083140 -0.631061 +v -0.777593 1.219550 -0.601051 +v -0.894731 1.335498 -0.599600 +v -0.883455 1.353320 -0.612859 +v -0.875766 1.366261 -0.630452 +v -0.638853 1.037889 -0.596684 +v -0.793760 1.198971 -0.595511 +v -0.909690 1.312978 -0.593846 +v -0.894731 1.335498 -0.599600 +v -0.594127 1.090210 -0.648518 +v -0.751081 1.254879 -0.648718 +v -0.749677 1.258357 -0.666971 +v -0.592630 1.093576 -0.666353 +v -0.871295 1.374567 -0.648957 +v -0.870011 1.378145 -0.667806 +v -0.599866 1.089148 -0.698145 +v -0.606323 1.082304 -0.705447 +v -0.756464 1.253278 -0.699476 +v -0.762647 1.245978 -0.706951 +v -0.769726 1.236466 -0.706848 +v -0.613646 1.073257 -0.705328 +v -0.875909 1.371927 -0.701330 +v -0.881479 1.363822 -0.709049 +v -0.887954 1.353480 -0.708966 +v -0.594910 1.093092 -0.684003 +v -0.751791 1.257640 -0.685019 +v -0.756464 1.253278 -0.699476 +v -0.599866 1.089148 -0.698145 +v -0.871803 1.377009 -0.686422 +v -0.875909 1.371927 -0.701330 +v -0.621176 1.063185 -0.698412 +v -0.776996 1.225900 -0.699804 +v -0.621176 1.063185 -0.698412 +v -0.776996 1.225900 -0.699804 +v -0.782959 1.217170 -0.688584 +v -0.627610 1.055082 -0.687417 +v -0.621176 1.063185 -0.698412 +v -0.627610 1.055082 -0.687417 +v -0.894619 1.342083 -0.701734 +v -0.894619 1.342083 -0.701734 +v -0.899843 1.332510 -0.690183 +v -0.630664 1.050880 -0.665461 +v -0.625924 1.052488 -0.659272 +v -0.785424 1.212373 -0.666143 +v -0.781111 1.214303 -0.659800 +v -0.776646 1.216229 -0.656121 +v -0.623167 1.056224 -0.655786 +v -0.901667 1.327168 -0.667018 +v -0.899179 1.330636 -0.660462 +v -0.896795 1.334278 -0.656657 +v -0.631402 1.051432 -0.675496 +v -0.782959 1.217170 -0.688584 +v -0.786072 1.212830 -0.676402 +v -0.785424 1.212373 -0.666143 +v -0.630664 1.050880 -0.665461 +v -0.902159 1.327456 -0.677615 +v -0.786072 1.212830 -0.676402 +v -0.901667 1.327168 -0.667018 +v -0.902159 1.327456 -0.677615 +v -0.901667 1.327168 -0.667018 +v -0.629791 1.035345 -0.627744 +v -0.787764 1.199854 -0.626903 +v -0.779609 1.210369 -0.643683 +v -0.900271 1.328559 -0.643767 +v -0.907605 1.316914 -0.626365 +v -0.787764 1.199854 -0.626903 +v -0.914975 1.305290 -0.608960 +v -0.795947 1.189361 -0.610121 +v -1.213738 1.344027 -0.449600 +v -1.101258 1.271432 -0.454199 +v -1.213738 1.344027 -0.449600 +v -1.101258 1.271432 -0.454199 +v -1.094453 1.282811 -0.446356 +v -1.207197 1.355965 -0.441597 +v -1.003789 1.198398 -0.470382 +v -1.005364 1.197889 -0.459530 +v -1.005364 1.197889 -0.459530 +v -0.998053 1.208447 -0.451898 +v -1.193826 1.374693 -0.512649 +v -1.201489 1.361782 -0.513782 +v -1.078687 1.298200 -0.514868 +v -1.086786 1.285996 -0.516068 +v -1.201489 1.361782 -0.513782 +v -1.086786 1.285996 -0.516068 +v -0.980762 1.221619 -0.518493 +v -0.989395 1.210348 -0.519656 +v -0.989395 1.210348 -0.519656 +v -0.993228 1.206663 -0.509992 +v -1.128805 1.507637 -0.653346 +v -1.004429 1.422710 -0.653197 +v -1.003608 1.422160 -0.657117 +v -1.126968 1.506625 -0.657312 +v -0.896715 1.334292 -0.652848 +v -0.775758 1.215632 -0.652441 +v -0.896715 1.334292 -0.652848 +v -0.896795 1.334278 -0.656657 +v -0.896795 1.334278 -0.656657 +v -1.150244 1.459661 -0.602118 +v -1.146924 1.467197 -0.599056 +v -1.028243 1.376833 -0.602610 +v -1.024323 1.383909 -0.599587 +v -1.146924 1.467197 -0.599056 +v -1.024323 1.383909 -0.599587 +v -0.923835 1.292327 -0.603766 +v -0.919277 1.298697 -0.600834 +v -0.919277 1.298697 -0.600834 +v -0.800709 1.183418 -0.602287 +v -1.160947 1.435907 -0.644407 +v -1.155883 1.446820 -0.616864 +v -1.041370 1.354910 -0.644295 +v -1.035048 1.364866 -0.617162 +v -1.155883 1.446820 -0.616864 +v -1.035048 1.364866 -0.617162 +v -0.939211 1.272852 -0.644213 +v -0.931803 1.281624 -0.617882 +v -0.931803 1.281624 -0.617882 +v -0.725356 0.935828 -0.496670 +v -0.884850 1.095355 -0.494402 +v -0.998505 1.202518 -0.490172 +v -1.156325 1.450388 -0.726106 +v -1.161709 1.435925 -0.683952 +v -1.037538 1.369881 -0.724495 +v -1.042886 1.355514 -0.683175 +v -0.934862 1.287266 -0.722096 +v -0.940999 1.273765 -0.681961 +v -1.127495 1.518263 -0.778269 +v -1.144157 1.479817 -0.760102 +v -1.006670 1.435150 -0.775218 +v -1.024634 1.398349 -0.757638 +v -1.144157 1.479817 -0.760102 +v -1.024634 1.398349 -0.757638 +v -0.899609 1.347562 -0.771411 +v -0.920093 1.313640 -0.754309 +v -0.920093 1.313640 -0.754309 +v -1.093344 1.591958 -0.752760 +v -1.109430 1.558161 -0.775366 +v -0.969401 1.504952 -0.750110 +v -0.987024 1.473033 -0.772249 +v -0.857482 1.411595 -0.747035 +v -0.877322 1.382362 -0.768541 +v -1.076952 1.621306 -0.670408 +v -1.082193 1.613386 -0.714708 +v -0.951088 1.532452 -0.669694 +v -0.957051 1.525101 -0.712958 +v -1.082193 1.613386 -0.714708 +v -0.957051 1.525101 -0.712958 +v -0.837400 1.436568 -0.668890 +v -0.843790 1.429968 -0.710932 +v -0.837400 1.436568 -0.668890 +v -0.843790 1.429968 -0.710932 +v -0.843790 1.429968 -0.710932 +v -1.113320 1.535849 -0.530099 +v -1.096822 1.572015 -0.555628 +v -0.989892 1.450674 -0.531845 +v -0.971946 1.485190 -0.557035 +v -0.959050 1.511160 -0.590906 +v -1.084751 1.599167 -0.590034 +v -0.989892 1.450674 -0.531845 +v -0.881766 1.361015 -0.535024 +v -0.861484 1.392745 -0.559474 +v -0.971946 1.485190 -0.557035 +v -0.861484 1.392745 -0.559474 +v -0.737600 1.269894 -0.562093 +v -0.721270 1.291850 -0.593895 +v -0.846887 1.416728 -0.592358 +v -1.077928 1.616109 -0.628448 +v -0.951890 1.527387 -0.628619 +v -0.838614 1.431772 -0.628984 +v -0.846887 1.416728 -0.592358 +v -0.838614 1.431772 -0.628984 +v -1.156038 1.444576 -0.519858 +v -1.133360 1.492238 -0.518206 +v -1.037353 1.364050 -0.521696 +v -1.012088 1.409189 -0.520074 +v -1.113320 1.535849 -0.530099 +v -0.935437 1.281868 -0.525175 +v -0.906931 1.323060 -0.523601 +v -1.199549 1.359031 -0.559061 +v -1.179678 1.397529 -0.533811 +v -1.085814 1.283715 -0.560463 +v -1.063639 1.319743 -0.535521 +v -0.989512 1.208729 -0.562798 +v -0.964802 1.241486 -0.538589 +v -1.215787 1.326667 -0.633044 +v -1.211377 1.335832 -0.593834 +v -1.104717 1.254103 -0.633160 +v -1.099288 1.262260 -0.594676 +v -1.211377 1.335832 -0.593834 +v -1.099288 1.262260 -0.594676 +v -1.011056 1.182203 -0.633394 +v -1.004694 1.189364 -0.596017 +v -1.004694 1.189364 -0.596017 +v -1.210710 1.336757 -0.709785 +v -1.214749 1.328191 -0.671859 +v -1.100228 1.264593 -0.708241 +v -1.104187 1.256024 -0.671182 +v -1.006566 1.192365 -0.706347 +v -1.010806 1.184264 -0.670333 +v -1.198996 1.366392 -0.782512 +v -1.205624 1.349424 -0.747057 +v -1.087727 1.293577 -0.778962 +v -1.094874 1.277057 -0.744548 +v -0.992149 1.219227 -0.775117 +v -1.000452 1.203956 -0.741644 +v -1.178098 1.415932 -0.842354 +v -1.189896 1.388490 -0.814688 +v -1.065261 1.341160 -0.836691 +v -1.077933 1.314895 -0.810066 +v -0.966387 1.263118 -0.831322 +v -0.980874 1.238904 -0.805388 +v -1.147600 1.484579 -0.879777 +v -1.163726 1.448465 -0.864377 +v -1.032426 1.406203 -0.872401 +v -1.049815 1.372079 -0.857772 +v -1.163726 1.448465 -0.864377 +v -1.049815 1.372079 -0.857772 +v -0.928944 1.322949 -0.866167 +v -0.948782 1.291584 -0.851878 +v -0.948782 1.291584 -0.851878 +v -0.829771 1.177528 -0.847521 +v -1.114794 1.557165 -0.888066 +v -1.130804 1.522065 -0.887757 +v -0.996888 1.474345 -0.879940 +v -1.014233 1.441447 -0.879849 +v -0.888359 1.385462 -0.873604 +v -0.908137 1.355287 -0.873471 +v -1.088593 1.612222 -0.868154 +v -1.100777 1.586810 -0.880960 +v -0.968524 1.525783 -0.860565 +v -0.981756 1.502078 -0.872969 +v -0.856323 1.432643 -0.854773 +v -0.871255 1.410918 -0.866842 +v -1.051811 1.685583 -0.759076 +v -1.059057 1.672715 -0.795716 +v -0.927503 1.593976 -0.755349 +v -0.935647 1.581992 -0.790692 +v -1.059057 1.672715 -0.795716 +v -0.935647 1.581992 -0.790692 +v -0.945593 1.566083 -0.821151 +v -1.067960 1.655608 -0.827318 +v -0.927503 1.593976 -0.755349 +v -0.810298 1.494694 -0.752286 +v -0.819206 1.483821 -0.786711 +v -0.676769 1.364723 -0.750198 +v -0.830267 1.469354 -0.816384 +v -1.077770 1.635208 -0.850925 +v -0.956558 1.547146 -0.843921 +v -0.842705 1.452130 -0.838565 +v -1.044419 1.696851 -0.684083 +v -1.046967 1.693490 -0.721124 +v -0.918826 1.604439 -0.682790 +v -0.921922 1.601331 -0.718667 +v -0.800977 1.504012 -0.681660 +v -0.804258 1.501304 -0.716573 +v -0.800977 1.504012 -0.681660 +v -0.804258 1.501304 -0.716573 +v -0.810298 1.494694 -0.752286 +v -0.810298 1.494694 -0.752286 +v -1.045762 1.691200 -0.611485 +v -1.043951 1.696171 -0.648721 +v -0.919693 1.599048 -0.612248 +v -0.918021 1.603764 -0.648466 +v -0.802210 1.498810 -0.613050 +v -0.800237 1.503265 -0.648270 +v -0.802210 1.498810 -0.613050 +v -0.800237 1.503265 -0.648270 +v -1.056402 1.667582 -0.528847 +v -1.050027 1.681616 -0.569739 +v -0.930737 1.576730 -0.531712 +v -0.924014 1.589973 -0.571585 +v -0.814688 1.478109 -0.534757 +v -0.807084 1.490349 -0.573518 +v -0.814688 1.478109 -0.534757 +v -0.807084 1.490349 -0.573518 +v -1.073962 1.628805 -0.466328 +v -1.064462 1.649570 -0.494578 +v -0.949883 1.540259 -0.470657 +v -0.939497 1.559789 -0.498257 +v -0.836515 1.444675 -0.475418 +v -0.824697 1.462566 -0.502240 +v -0.708145 1.318219 -0.479551 +v -0.694997 1.334639 -0.505664 +v -0.824697 1.462566 -0.502240 +v -1.096805 1.581325 -0.423476 +v -1.084743 1.606284 -0.442445 +v -0.974636 1.495467 -0.428766 +v -0.961574 1.519028 -0.447323 +v -0.974636 1.495467 -0.428766 +v -0.864271 1.403547 -0.434716 +v -0.849646 1.425185 -0.452744 +v -0.961574 1.519028 -0.447323 +v -0.849646 1.425185 -0.452744 +v -0.722553 1.300271 -0.457481 +v -1.126362 1.517822 -0.405064 +v -1.110365 1.552593 -0.410564 +v -1.007012 1.435532 -0.410583 +v -0.989416 1.468348 -0.416079 +v -1.096805 1.581325 -0.423476 +v -0.900917 1.348640 -0.417069 +v -0.880930 1.378677 -0.422397 +v -1.167450 1.430206 -0.416943 +v -1.145575 1.475766 -0.407759 +v -1.052170 1.352857 -0.421990 +v -1.028256 1.395843 -0.413069 +v -0.951969 1.272981 -0.428185 +v -0.925106 1.312356 -0.419500 +v -1.190044 1.387082 -0.429806 +v -1.076347 1.312183 -0.434680 +v -0.978483 1.235559 -0.440535 +v -1.176861 1.403785 -0.502894 +v -1.060914 1.325906 -0.505162 +v -0.961851 1.247295 -0.509061 +vt 0.923925 0.920017 +vt 0.924628 0.915623 +vt 0.921557 0.914904 +vt 0.920862 0.919318 +vt 0.924942 0.914279 +vt 0.921860 0.913558 +vt 0.919424 0.912905 +vt 0.919132 0.914256 +vt 0.918443 0.918687 +vt 0.922817 0.960712 +vt 0.924628 0.977248 +vt 0.927609 0.977171 +vt 0.925888 0.960760 +vt 0.926323 0.991865 +vt 0.929165 0.991349 +vt 0.930667 0.988433 +vt 0.929835 0.976855 +vt 0.928275 0.960783 +vt 0.735973 0.565758 +vt 0.735858 0.564908 +vt 0.733036 0.565431 +vt 0.733316 0.566237 +vt 0.904675 0.528970 +vt 0.904489 0.528623 +vt 0.901942 0.529509 +vt 0.902168 0.529839 +vt 0.899991 0.530226 +vt 0.900255 0.530544 +vt 0.730730 0.566492 +vt 0.731166 0.567230 +vt 0.915397 0.480570 +vt 0.916976 0.464372 +vt 0.914588 0.464019 +vt 0.912851 0.480588 +vt 0.917795 0.452653 +vt 0.916157 0.449659 +vt 0.912954 0.449037 +vt 0.911240 0.463869 +vt 0.909420 0.480612 +vt 0.929923 0.997390 +vt 0.931479 0.991438 +vt 0.927052 0.998124 +vt 0.927136 0.999034 +vt 0.930075 0.998253 +vt 0.282690 0.240029 +vt 0.283017 0.246178 +vt 0.283820 0.246961 +vt 0.283481 0.240540 +vt 0.913707 0.442697 +vt 0.910348 0.442602 +vt 0.909557 0.448934 +vt 0.913859 0.441827 +vt 0.910596 0.441756 +vt 0.907762 0.441630 +vt 0.907392 0.442454 +vt 0.906556 0.448792 +vt 0.905093 0.442353 +vt 0.904211 0.448696 +vt 0.357744 0.107161 +vt 0.357005 0.106370 +vt 0.356122 0.107958 +vt 0.356794 0.108845 +vt 0.354890 0.109198 +vt 0.355476 0.110179 +vt 0.903336 0.442304 +vt 0.902414 0.448650 +vt 0.907806 0.463780 +vt 0.905935 0.480648 +vt 0.904770 0.463679 +vt 0.902854 0.480695 +vt 0.286485 0.240378 +vt 0.286821 0.246903 +vt 0.287556 0.246080 +vt 0.287234 0.239782 +vt 0.917022 0.442685 +vt 0.916913 0.443543 +vt 0.918617 0.449615 +vt 0.928174 0.914964 +vt 0.928350 0.914635 +vt 0.925045 0.913917 +vt 0.930175 0.915518 +vt 0.930755 0.915451 +vt 0.745580 0.571339 +vt 0.748044 0.571972 +vt 0.748389 0.571148 +vt 0.745809 0.570488 +vt 0.742287 0.570605 +vt 0.742429 0.569745 +vt 0.920292 0.327456 +vt 0.920567 0.322981 +vt 0.919371 0.322814 +vt 0.919098 0.327310 +vt 0.920721 0.321599 +vt 0.919518 0.321427 +vt 0.918031 0.321252 +vt 0.917893 0.322642 +vt 0.917623 0.327158 +vt 0.919461 0.912513 +vt 0.917782 0.911998 +vt 0.917786 0.912405 +vt 0.736549 0.569997 +vt 0.736434 0.569149 +vt 0.734433 0.569456 +vt 0.734713 0.570260 +vt 0.732901 0.570169 +vt 0.733336 0.570905 +vt 0.916623 0.911567 +vt 0.916667 0.911986 +vt 0.917506 0.913763 +vt 0.916820 0.918211 +vt 0.916398 0.913351 +vt 0.915712 0.917818 +vt 0.902395 0.463615 +vt 0.900447 0.480751 +vt 0.900575 0.463588 +vt 0.898604 0.480811 +vt 0.352297 0.117207 +vt 0.351922 0.112224 +vt 0.349767 0.113012 +vt 0.350106 0.118010 +vt 0.351525 0.111106 +vt 0.349471 0.111860 +vt 0.347085 0.112430 +vt 0.347277 0.113606 +vt 0.347578 0.118616 +vt 0.899128 0.463584 +vt 0.897139 0.480873 +vt 0.900985 0.448637 +vt 0.354947 0.127659 +vt 0.354242 0.116250 +vt 0.352979 0.128634 +vt 0.355853 0.140733 +vt 0.353855 0.141762 +vt 0.901940 0.442289 +vt 0.353340 0.110226 +vt 0.353834 0.111287 +vt 0.920935 0.321214 +vt 0.919703 0.321043 +vt 0.731523 0.571255 +vt 0.732083 0.571908 +vt 0.730218 0.572652 +vt 0.730873 0.573212 +vt 0.918186 0.320868 +vt 0.914182 0.320958 +vt 0.914268 0.320565 +vt 0.911737 0.320320 +vt 0.911686 0.320714 +vt 0.728699 0.576767 +vt 0.727910 0.576416 +vt 0.727093 0.578965 +vt 0.727925 0.579201 +vt 0.726563 0.581584 +vt 0.727421 0.581709 +vt 0.909192 0.320059 +vt 0.909174 0.320454 +vt 0.916408 0.320729 +vt 0.916286 0.321118 +vt 0.728984 0.574330 +vt 0.729715 0.574789 +vt 0.916158 0.322510 +vt 0.915894 0.327034 +vt 0.914065 0.322352 +vt 0.913809 0.326882 +vt 0.350762 0.129459 +vt 0.351604 0.142642 +vt 0.348205 0.130084 +vt 0.349009 0.143316 +vt 0.908848 0.326391 +vt 0.909081 0.321852 +vt 0.906914 0.321652 +vt 0.906695 0.326187 +vt 0.906997 0.320255 +vt 0.905005 0.320093 +vt 0.904933 0.321490 +vt 0.904730 0.326012 +vt 0.911581 0.322110 +vt 0.911336 0.326646 +vt 0.345289 0.130458 +vt 0.346050 0.143722 +vt 0.344692 0.118976 +vt 0.341828 0.119106 +vt 0.342398 0.130597 +vt 0.343119 0.143880 +vt 0.344430 0.113957 +vt 0.344344 0.112761 +vt 0.341615 0.112870 +vt 0.341602 0.114078 +vt 0.337036 0.118730 +vt 0.336869 0.113697 +vt 0.334556 0.113172 +vt 0.334697 0.118203 +vt 0.337055 0.112503 +vt 0.334831 0.112001 +vt 0.332632 0.111269 +vt 0.332262 0.112399 +vt 0.332375 0.117422 +vt 0.339884 0.130526 +vt 0.340574 0.143822 +vt 0.339335 0.119026 +vt 0.337569 0.130240 +vt 0.338235 0.143542 +vt 0.339140 0.113994 +vt 0.339242 0.112787 +vt 0.906984 0.319857 +vt 0.726330 0.583903 +vt 0.727197 0.583927 +vt 0.726385 0.586084 +vt 0.727249 0.586009 +vt 0.904964 0.319692 +vt 0.900859 0.325683 +vt 0.901024 0.321204 +vt 0.899354 0.321122 +vt 0.899210 0.325572 +vt 0.901074 0.319813 +vt 0.899393 0.319735 +vt 0.898124 0.319659 +vt 0.898096 0.321043 +vt 0.897968 0.325468 +vt 0.902930 0.319534 +vt 0.903000 0.319939 +vt 0.726720 0.588344 +vt 0.727565 0.588162 +vt 0.727335 0.590590 +vt 0.728139 0.590287 +vt 0.900973 0.319403 +vt 0.902938 0.321333 +vt 0.902753 0.325837 +vt 0.335216 0.129722 +vt 0.335862 0.143023 +vt 0.332885 0.128949 +vt 0.333513 0.142241 +vt 0.887103 0.803561 +vt 0.888735 0.821243 +vt 0.890607 0.821195 +vt 0.888991 0.803566 +vt 0.890333 0.836446 +vt 0.892189 0.836396 +vt 0.894127 0.836338 +vt 0.892559 0.821149 +vt 0.890957 0.803586 +vt 0.330728 0.127919 +vt 0.331344 0.141193 +vt 0.330225 0.116387 +vt 0.886960 0.821272 +vt 0.888577 0.836459 +vt 0.885305 0.803567 +vt 0.330138 0.111378 +vt 0.330612 0.110312 +vt 0.328990 0.109209 +vt 0.328421 0.110198 +vt 0.889420 0.842897 +vt 0.891140 0.842893 +vt 0.899262 0.319320 +vt 0.728217 0.592646 +vt 0.728950 0.592209 +vt 0.729291 0.594314 +vt 0.729928 0.593746 +vt 0.765705 0.158117 +vt 0.765665 0.158569 +vt 0.766908 0.158261 +vt 0.766911 0.157817 +vt 0.894859 0.842792 +vt 0.896865 0.842756 +vt 0.896175 0.836303 +vt 0.895152 0.843643 +vt 0.897019 0.843602 +vt 0.899082 0.843549 +vt 0.899074 0.842710 +vt 0.898428 0.836260 +vt 0.892959 0.842847 +vt 0.327930 0.108037 +vt 0.327288 0.108949 +vt 0.893384 0.843687 +vt 0.768150 0.157981 +vt 0.768116 0.157549 +vt 0.730485 0.595461 +vt 0.731003 0.594781 +vt 0.731779 0.596235 +vt 0.732161 0.595468 +vt 0.769387 0.157659 +vt 0.769313 0.157241 +vt 0.765794 0.152072 +vt 0.766596 0.156464 +vt 0.767789 0.156201 +vt 0.766980 0.151822 +vt 0.768975 0.155898 +vt 0.768157 0.151532 +vt 0.770730 0.150636 +vt 0.771559 0.154956 +vt 0.773179 0.154378 +vt 0.772340 0.150074 +vt 0.771922 0.156284 +vt 0.773556 0.155700 +vt 0.775271 0.155072 +vt 0.774880 0.153756 +vt 0.774033 0.149464 +vt 0.770656 0.157218 +vt 0.770538 0.156811 +vt 0.733196 0.596794 +vt 0.733427 0.595969 +vt 0.734873 0.597056 +vt 0.734939 0.596205 +vt 0.772086 0.156677 +vt 0.770188 0.155475 +vt 0.769365 0.151132 +vt 0.894623 0.821121 +vt 0.893034 0.803627 +vt 0.896896 0.821096 +vt 0.895321 0.803688 +vt 0.903472 0.836087 +vt 0.904024 0.842519 +vt 0.906292 0.842421 +vt 0.905780 0.836002 +vt 0.920570 0.146230 +vt 0.919922 0.145309 +vt 0.918292 0.145976 +vt 0.918853 0.146933 +vt 0.916340 0.146527 +vt 0.916796 0.147511 +vt 0.919146 0.152933 +vt 0.917058 0.153505 +vt 0.899424 0.821052 +vt 0.897867 0.803766 +vt 0.900935 0.836182 +vt 0.901985 0.821004 +vt 0.900450 0.803860 +vt 0.901533 0.842624 +vt 0.901391 0.843469 +vt 0.903742 0.843373 +vt 0.773766 0.156076 +vt 0.736904 0.596901 +vt 0.736795 0.596058 +vt 0.739107 0.596308 +vt 0.738826 0.595504 +vt 0.775524 0.155430 +vt 0.914494 0.147944 +vt 0.914721 0.153929 +vt 0.914155 0.146937 +vt 0.911798 0.147210 +vt 0.912023 0.148238 +vt 0.912213 0.154212 +vt 0.777142 0.154760 +vt 0.776853 0.154417 +vt 0.741247 0.595294 +vt 0.740814 0.594557 +vt 0.743160 0.593928 +vt 0.742595 0.593284 +vt 0.958837 0.607571 +vt 0.958972 0.607121 +vt 0.957247 0.606745 +vt 0.957148 0.607204 +vt 0.776453 0.153107 +vt 0.775601 0.148828 +vt 0.958859 0.608829 +vt 0.957184 0.608462 +vt 0.958932 0.612644 +vt 0.957274 0.612271 +vt 0.904319 0.820969 +vt 0.902809 0.803965 +vt 0.919514 0.166899 +vt 0.917418 0.167429 +vt 0.906277 0.820946 +vt 0.904794 0.804076 +vt 0.953447 0.611954 +vt 0.953328 0.608140 +vt 0.951113 0.608167 +vt 0.951245 0.611989 +vt 0.953267 0.606877 +vt 0.951041 0.606903 +vt 0.948819 0.607052 +vt 0.948901 0.608315 +vt 0.949042 0.612141 +vt 0.955360 0.606512 +vt 0.955301 0.606975 +vt 0.744725 0.592277 +vt 0.744052 0.591745 +vt 0.745948 0.590336 +vt 0.745193 0.589921 +vt 0.953288 0.606413 +vt 0.955349 0.608235 +vt 0.955455 0.612043 +vt 0.917833 0.183146 +vt 0.915066 0.167807 +vt 0.915464 0.183411 +vt 0.912538 0.168042 +vt 0.912910 0.183540 +vt 0.906983 0.154396 +vt 0.906865 0.148447 +vt 0.904326 0.148359 +vt 0.904401 0.154295 +vt 0.906846 0.147401 +vt 0.904430 0.147340 +vt 0.902141 0.147132 +vt 0.901881 0.148097 +vt 0.901908 0.154016 +vt 0.909909 0.168147 +vt 0.910244 0.183552 +vt 0.909610 0.154366 +vt 0.907252 0.168141 +vt 0.907543 0.183478 +vt 0.909454 0.148404 +vt 0.909331 0.147360 +vt 0.951028 0.606442 +vt 0.746869 0.588129 +vt 0.746060 0.587819 +vt 0.747549 0.585850 +vt 0.746707 0.585654 +vt 0.948773 0.606595 +vt 0.945199 0.607704 +vt 0.945076 0.607261 +vt 0.943873 0.607750 +vt 0.944037 0.608174 +vt 0.747324 0.581949 +vt 0.748141 0.581815 +vt 0.747743 0.580216 +vt 0.747031 0.580588 +vt 0.746544 0.578943 +vt 0.746003 0.579540 +vt 0.947395 0.322998 +vt 0.947670 0.322664 +vt 0.946491 0.322399 +vt 0.946275 0.322750 +vt 0.946744 0.606873 +vt 0.946826 0.607325 +vt 0.748014 0.583713 +vt 0.747162 0.583658 +vt 0.946919 0.608583 +vt 0.947065 0.612400 +vt 0.945301 0.608955 +vt 0.945450 0.612755 +vt 0.904635 0.168025 +vt 0.904874 0.183331 +vt 0.902104 0.167740 +vt 0.902288 0.183042 +vt 0.945156 0.328371 +vt 0.945919 0.324063 +vt 0.944077 0.323383 +vt 0.943307 0.327743 +vt 0.944420 0.322055 +vt 0.942165 0.321201 +vt 0.941832 0.322544 +vt 0.941052 0.326959 +vt 0.944146 0.609414 +vt 0.944296 0.613204 +vt 0.947023 0.324306 +vt 0.946259 0.328598 +vt 0.899770 0.167216 +vt 0.899897 0.182528 +vt 0.899612 0.153509 +vt 0.918335 0.251755 +vt 0.919715 0.237004 +vt 0.917432 0.236893 +vt 0.916016 0.251621 +vt 0.916913 0.268195 +vt 0.914552 0.268094 +vt 0.899636 0.147616 +vt 0.900078 0.146725 +vt 0.898566 0.146068 +vt 0.897964 0.146888 +vt 0.920196 0.230697 +vt 0.917976 0.230604 +vt 0.910641 0.236730 +vt 0.911323 0.230475 +vt 0.908023 0.230376 +vt 0.907275 0.236627 +vt 0.911510 0.229674 +vt 0.908410 0.229585 +vt 0.350829 0.104845 +vt 0.350127 0.104057 +vt 0.348742 0.105972 +vt 0.349338 0.106881 +vt 0.905265 0.230288 +vt 0.904457 0.236546 +vt 0.912764 0.251502 +vt 0.911235 0.268028 +vt 0.914228 0.236811 +vt 0.909122 0.251399 +vt 0.907518 0.268016 +vt 0.914840 0.230542 +vt 0.917721 0.229828 +vt 0.914805 0.229754 +vt 0.944575 0.321691 +vt 0.744390 0.578023 +vt 0.744071 0.578771 +vt 0.741714 0.577539 +vt 0.741637 0.578358 +vt 0.942261 0.320822 +vt 0.963561 0.230361 +vt 0.963803 0.225874 +vt 0.962400 0.225714 +vt 0.962159 0.230216 +vt 0.963941 0.224491 +vt 0.962527 0.224329 +vt 0.960911 0.224123 +vt 0.960796 0.225510 +vt 0.960555 0.230022 +vt 0.939982 0.320093 +vt 0.939938 0.320492 +vt 0.739037 0.577585 +vt 0.739195 0.578397 +vt 0.736667 0.578244 +vt 0.737042 0.578980 +vt 0.938067 0.319487 +vt 0.938071 0.319906 +vt 0.939616 0.321843 +vt 0.938831 0.326288 +vt 0.937761 0.321262 +vt 0.936975 0.325721 +vt 0.905701 0.251316 +vt 0.904024 0.268070 +vt 0.902835 0.251277 +vt 0.901100 0.268185 +vt 0.346175 0.138701 +vt 0.345433 0.125721 +vt 0.342649 0.126261 +vt 0.343337 0.139304 +vt 0.344828 0.114407 +vt 0.342087 0.114909 +vt 0.339322 0.114761 +vt 0.339848 0.126139 +vt 0.340487 0.139215 +vt 0.900743 0.251302 +vt 0.898973 0.268344 +vt 0.902400 0.236526 +vt 0.348143 0.124597 +vt 0.347494 0.113331 +vt 0.348943 0.137487 +vt 0.903258 0.230255 +vt 0.346687 0.107420 +vt 0.347129 0.108441 +vt 0.344268 0.108375 +vt 0.344522 0.109479 +vt 0.964143 0.224098 +vt 0.962683 0.223933 +vt 0.734810 0.579531 +vt 0.735378 0.580128 +vt 0.733497 0.581189 +vt 0.734215 0.581600 +vt 0.961014 0.223725 +vt 0.339141 0.109812 +vt 0.336508 0.108982 +vt 0.336636 0.113910 +vt 0.339307 0.108707 +vt 0.336894 0.107977 +vt 0.335063 0.106699 +vt 0.334504 0.107541 +vt 0.935843 0.991987 +vt 0.936637 0.998332 +vt 0.938714 0.998358 +vt 0.937988 0.992002 +vt 0.341844 0.109960 +vt 0.341793 0.108824 +vt 0.959369 0.223590 +vt 0.959326 0.223994 +vt 0.732721 0.582948 +vt 0.733525 0.583140 +vt 0.732513 0.584756 +vt 0.733320 0.584696 +vt 0.957803 0.223536 +vt 0.957820 0.223947 +vt 0.959225 0.225381 +vt 0.958989 0.229888 +vt 0.957733 0.225331 +vt 0.957504 0.229820 +vt 0.981030 0.336697 +vt 0.981834 0.341095 +vt 0.982693 0.340821 +vt 0.981889 0.336438 +vt 0.982162 0.342430 +vt 0.983034 0.342148 +vt 0.983928 0.341871 +vt 0.983573 0.340548 +vt 0.982765 0.336168 +vt 0.956372 0.223537 +vt 0.956441 0.223955 +vt 0.732882 0.586548 +vt 0.733593 0.586211 +vt 0.733733 0.587986 +vt 0.734237 0.587406 +vt 0.955331 0.223556 +vt 0.955437 0.223978 +vt 0.956365 0.225332 +vt 0.956143 0.229794 +vt 0.955367 0.225349 +vt 0.955151 0.229785 +vt 0.337133 0.125299 +vt 0.337727 0.138371 +vt 0.934287 0.977016 +vt 0.936469 0.977009 +vt 0.932656 0.959667 +vt 0.934881 0.959688 +vt 0.943605 0.991906 +vt 0.944177 0.998249 +vt 0.946491 0.998150 +vt 0.945987 0.991830 +vt 0.202494 0.139262 +vt 0.203124 0.140042 +vt 0.204823 0.139376 +vt 0.204368 0.138511 +vt 0.207234 0.138951 +vt 0.207040 0.138042 +vt 0.204051 0.132620 +vt 0.206784 0.132167 +vt 0.939271 0.976994 +vt 0.937728 0.959772 +vt 0.940750 0.991971 +vt 0.942167 0.976981 +vt 0.940668 0.959909 +vt 0.941400 0.998326 +vt 0.939136 0.999100 +vt 0.941528 0.999067 +vt 0.944003 0.999001 +vt 0.982212 0.342858 +vt 0.983158 0.342554 +vt 0.734934 0.588730 +vt 0.735126 0.588002 +vt 0.736328 0.588692 +vt 0.736171 0.587950 +vt 0.984123 0.342252 +vt 0.209905 0.137956 +vt 0.209726 0.132106 +vt 0.209802 0.138852 +vt 0.211939 0.139083 +vt 0.212309 0.138206 +vt 0.212209 0.132375 +vt 0.926951 0.843211 +vt 0.926841 0.843630 +vt 0.927775 0.843963 +vt 0.927841 0.843525 +vt 0.737720 0.587908 +vt 0.737256 0.587302 +vt 0.738794 0.586647 +vt 0.738117 0.586298 +vt 0.928980 0.844091 +vt 0.928984 0.843645 +vt 0.984379 0.340281 +vt 0.983566 0.335894 +vt 0.984748 0.341602 +vt 0.927789 0.842277 +vt 0.928921 0.842393 +vt 0.927675 0.838393 +vt 0.928802 0.838507 +vt 0.944590 0.976981 +vt 0.943132 0.960083 +vt 0.203500 0.118847 +vt 0.206267 0.118463 +vt 0.202865 0.103134 +vt 0.205680 0.102892 +vt 0.886235 0.672110 +vt 0.887044 0.667703 +vt 0.886754 0.667116 +vt 0.885922 0.671577 +vt 0.887412 0.666380 +vt 0.887123 0.665823 +vt 0.886886 0.665463 +vt 0.886528 0.666497 +vt 0.885670 0.670984 +vt 0.930120 0.843937 +vt 0.930053 0.843498 +vt 0.739276 0.585236 +vt 0.738513 0.585215 +vt 0.739201 0.584001 +vt 0.738459 0.584296 +vt 0.930989 0.843834 +vt 0.930848 0.843411 +vt 0.929977 0.842251 +vt 0.929855 0.838372 +vt 0.930755 0.842165 +vt 0.930628 0.838271 +vt 0.209256 0.118462 +vt 0.208734 0.102987 +vt 0.211789 0.118766 +vt 0.211332 0.103329 +vt 0.285530 0.191272 +vt 0.285955 0.181498 +vt 0.284307 0.181509 +vt 0.283946 0.191368 +vt 0.286336 0.173039 +vt 0.284634 0.172976 +vt 0.282931 0.172913 +vt 0.282658 0.181519 +vt 0.282360 0.191463 +vt 0.213332 0.119130 +vt 0.212926 0.103783 +vt 0.213683 0.132263 +vt 0.983742 0.507534 +vt 0.984876 0.493335 +vt 0.983729 0.496242 +vt 0.982583 0.507809 +vt 0.982544 0.524083 +vt 0.981346 0.524056 +vt 0.213724 0.137875 +vt 0.986529 0.486567 +vt 0.986026 0.485817 +vt 0.984839 0.486542 +vt 0.985232 0.487312 +vt 0.983311 0.492665 +vt 0.983658 0.493251 +vt 0.887675 0.666041 +vt 0.887353 0.665487 +vt 0.738729 0.583195 +vt 0.738080 0.583719 +vt 0.738225 0.582774 +vt 0.737684 0.583435 +vt 0.886989 0.665181 +vt 0.341993 0.103026 +vt 0.341647 0.104231 +vt 0.342082 0.104864 +vt 0.342611 0.103794 +vt 0.887675 0.750647 +vt 0.886968 0.744443 +vt 0.886517 0.744223 +vt 0.887178 0.750224 +vt 0.885945 0.741603 +vt 0.886232 0.744664 +vt 0.342452 0.109378 +vt 0.343094 0.108603 +vt 0.982047 0.507431 +vt 0.980748 0.524056 +vt 0.347214 0.118491 +vt 0.346386 0.107478 +vt 0.345725 0.107351 +vt 0.346532 0.118715 +vt 0.348000 0.130988 +vt 0.347301 0.131324 +vt 0.344417 0.132450 +vt 0.343736 0.119777 +vt 0.343022 0.120134 +vt 0.343674 0.132729 +vt 0.342380 0.111707 +vt 0.342798 0.120457 +vt 0.343418 0.132738 +vt 0.339647 0.103023 +vt 0.339860 0.104241 +vt 0.340870 0.104162 +vt 0.340950 0.102912 +vt 0.340115 0.109062 +vt 0.341066 0.108970 +vt 0.341781 0.109029 +vt 0.337453 0.104402 +vt 0.338092 0.105350 +vt 0.338841 0.104687 +vt 0.338372 0.103573 +vt 0.983944 0.256917 +vt 0.983316 0.263164 +vt 0.984069 0.263094 +vt 0.984748 0.256852 +vt 0.339143 0.109493 +vt 0.742366 0.582764 +vt 0.743109 0.582469 +vt 0.742112 0.580562 +vt 0.741450 0.581078 +vt 0.211945 0.057025 +vt 0.212017 0.057387 +vt 0.213724 0.057460 +vt 0.213604 0.057093 +vt 0.986501 0.571902 +vt 0.986529 0.571504 +vt 0.985514 0.571655 +vt 0.985239 0.571959 +vt 0.741080 0.579570 +vt 0.740475 0.580183 +vt 0.981948 0.255855 +vt 0.982177 0.256896 +vt 0.983057 0.256941 +vt 0.983122 0.255898 +vt 0.981673 0.263150 +vt 0.982490 0.263191 +vt 0.984308 0.255883 +vt 0.736991 0.591882 +vt 0.737148 0.592624 +vt 0.740141 0.591099 +vt 0.739677 0.590494 +vt 0.943981 0.911197 +vt 0.943939 0.911543 +vt 0.946491 0.912507 +vt 0.946474 0.912138 +vt 0.202909 0.056360 +vt 0.202778 0.056705 +vt 0.205861 0.056967 +vt 0.205934 0.056618 +vt 0.742331 0.588461 +vt 0.741653 0.588113 +vt 0.743292 0.585323 +vt 0.742528 0.585302 +vt 0.209192 0.057220 +vt 0.209195 0.056867 +vt 0.957763 0.307137 +vt 0.957944 0.305996 +vt 0.956694 0.305726 +vt 0.956298 0.306846 +vt 0.957826 0.300165 +vt 0.956615 0.299908 +vt 0.955740 0.299590 +vt 0.955791 0.305389 +vt 0.955229 0.306456 +vt 0.961010 0.307140 +vt 0.960777 0.306016 +vt 0.959321 0.306103 +vt 0.959353 0.307241 +vt 0.960571 0.300196 +vt 0.959159 0.300271 +vt 0.729205 0.585031 +vt 0.728399 0.585091 +vt 0.729209 0.588334 +vt 0.729919 0.587998 +vt 0.952009 0.074926 +vt 0.951927 0.074526 +vt 0.948991 0.075369 +vt 0.949120 0.075745 +vt 0.946858 0.076510 +vt 0.947019 0.076856 +vt 0.731092 0.591065 +vt 0.731595 0.590486 +vt 0.733920 0.592592 +vt 0.734111 0.591865 +vt 0.938020 0.909351 +vt 0.937834 0.909652 +vt 0.940849 0.910522 +vt 0.940963 0.910200 +vt 0.964143 0.306387 +vt 0.963569 0.305325 +vt 0.962264 0.305738 +vt 0.962684 0.306840 +vt 0.938792 0.404804 +vt 0.938275 0.398597 +vt 0.937068 0.398665 +vt 0.937551 0.404883 +vt 0.962021 0.299939 +vt 0.730601 0.579525 +vt 0.729884 0.579114 +vt 0.728661 0.581989 +vt 0.729464 0.582181 +vt 0.958154 0.074501 +vt 0.958188 0.074084 +vt 0.955033 0.074101 +vt 0.955058 0.074516 +vt 0.942663 0.405728 +vt 0.942646 0.404769 +vt 0.940549 0.404803 +vt 0.940368 0.405772 +vt 0.942060 0.398565 +vt 0.939998 0.398599 +vt 0.938439 0.405791 +vt 0.947053 0.405466 +vt 0.946605 0.404471 +vt 0.944811 0.404610 +vt 0.945046 0.405586 +vt 0.945936 0.398266 +vt 0.944187 0.398407 +vt 0.742040 0.574234 +vt 0.742117 0.573415 +vt 0.738230 0.573481 +vt 0.738388 0.574293 +vt 0.910410 0.315246 +vt 0.910269 0.314891 +vt 0.906627 0.316117 +vt 0.906818 0.316453 +vt 0.903596 0.317260 +vt 0.903833 0.317575 +vt 0.734758 0.574500 +vt 0.735133 0.575236 +vt 0.731942 0.576496 +vt 0.732510 0.577093 +vt 0.963929 0.075542 +vt 0.964067 0.075150 +vt 0.961325 0.074438 +vt 0.961236 0.074844 +vt 0.748815 0.576446 +vt 0.749356 0.575849 +vt 0.746058 0.574208 +vt 0.745739 0.574956 +vt 0.917712 0.313178 +vt 0.917691 0.312800 +vt 0.914181 0.313732 +vt 0.914263 0.314100 +vt 0.341883 0.097483 +vt 0.341936 0.098716 +vt 0.343733 0.098669 +vt 0.343801 0.097429 +vt 0.342172 0.103589 +vt 0.343945 0.103523 +vt 0.345420 0.103646 +vt 0.345237 0.098820 +vt 0.345457 0.097598 +vt 0.346362 0.099224 +vt 0.346762 0.098068 +vt 0.346510 0.104010 +vt 0.947670 0.404504 +vt 0.946953 0.398289 +vt 0.347079 0.099990 +vt 0.347640 0.098955 +vt 0.337757 0.098097 +vt 0.338010 0.099313 +vt 0.339965 0.098932 +vt 0.339812 0.097703 +vt 0.338286 0.104203 +vt 0.340220 0.103815 +vt 0.750886 0.586626 +vt 0.751729 0.586823 +vt 0.752283 0.583974 +vt 0.751430 0.583919 +vt 0.906512 0.226517 +vt 0.906553 0.226146 +vt 0.903619 0.225939 +vt 0.903616 0.226309 +vt 0.900777 0.225772 +vt 0.900816 0.226139 +vt 0.752283 0.581109 +vt 0.751465 0.581243 +vt 0.751400 0.578275 +vt 0.750688 0.578647 +vt 0.898148 0.225604 +vt 0.898232 0.225968 +vt 0.920158 0.312609 +vt 0.920196 0.312216 +vt 0.334175 0.099505 +vt 0.334656 0.100637 +vt 0.336237 0.099873 +vt 0.335872 0.098689 +vt 0.334989 0.105528 +vt 0.336541 0.104765 +vt 0.331425 0.101793 +vt 0.332093 0.102771 +vt 0.333252 0.101621 +vt 0.332670 0.100559 +vt 0.774352 0.070134 +vt 0.773718 0.076497 +vt 0.775209 0.076478 +vt 0.775869 0.070130 +vt 0.776462 0.076465 +vt 0.777142 0.070132 +vt 0.748944 0.591987 +vt 0.749700 0.592403 +vt 0.750882 0.589663 +vt 0.750072 0.589354 +vt 0.912364 0.227103 +vt 0.912468 0.226742 +vt 0.909527 0.226427 +vt 0.909454 0.226795 +vt 0.771355 0.069184 +vt 0.771167 0.070161 +vt 0.772723 0.070160 +vt 0.773058 0.069186 +vt 0.770605 0.076544 +vt 0.772123 0.076533 +vt 0.330524 0.103118 +vt 0.331256 0.104001 +vt 0.740223 0.599515 +vt 0.740504 0.600320 +vt 0.743410 0.598971 +vt 0.742975 0.598233 +vt 0.903793 0.756943 +vt 0.903803 0.757314 +vt 0.906292 0.758218 +vt 0.906245 0.757833 +vt 0.920057 0.227880 +vt 0.920268 0.227532 +vt 0.917927 0.227303 +vt 0.917750 0.227653 +vt 0.745975 0.597146 +vt 0.745410 0.596501 +vt 0.748076 0.594928 +vt 0.747402 0.594396 +vt 0.915297 0.227038 +vt 0.915157 0.227393 +vt 0.768553 0.069095 +vt 0.768649 0.070057 +vt 0.769829 0.070104 +vt 0.769872 0.069135 +vt 0.768160 0.076448 +vt 0.769304 0.076493 +vt 0.766053 0.069126 +vt 0.766404 0.070108 +vt 0.767525 0.070081 +vt 0.767297 0.069109 +vt 0.765979 0.076492 +vt 0.767070 0.076470 +vt 0.730259 0.599288 +vt 0.729877 0.600056 +vt 0.732046 0.600915 +vt 0.732278 0.600089 +vt 0.893800 0.753738 +vt 0.893632 0.754055 +vt 0.895875 0.754705 +vt 0.896001 0.754377 +vt 0.898338 0.755451 +vt 0.898417 0.755112 +vt 0.734541 0.601318 +vt 0.734607 0.600466 +vt 0.737445 0.601119 +vt 0.737336 0.600275 +vt 0.901060 0.756352 +vt 0.901092 0.755998 +vt 0.901491 0.405009 +vt 0.901877 0.403920 +vt 0.900391 0.403532 +vt 0.899905 0.404607 +vt 0.901816 0.397985 +vt 0.900355 0.397596 +vt 0.765265 0.070064 +vt 0.764869 0.076441 +vt 0.899265 0.403148 +vt 0.898686 0.404197 +vt 0.726747 0.596590 +vt 0.726110 0.597159 +vt 0.727898 0.598856 +vt 0.728416 0.598175 +vt 0.889725 0.752576 +vt 0.889483 0.752867 +vt 0.891515 0.753431 +vt 0.891721 0.753127 +vt 0.905159 0.405567 +vt 0.905365 0.404465 +vt 0.903584 0.404235 +vt 0.903292 0.405332 +vt 0.905262 0.398545 +vt 0.903502 0.398306 +vt 0.909036 0.405789 +vt 0.909072 0.404680 +vt 0.907134 0.404614 +vt 0.907011 0.405719 +vt 0.908933 0.398780 +vt 0.907013 0.398704 +vt 0.722984 0.586382 +vt 0.722121 0.586457 +vt 0.722541 0.589247 +vt 0.723386 0.589065 +vt 0.540256 0.103961 +vt 0.540157 0.103530 +vt 0.537555 0.104059 +vt 0.537680 0.104482 +vt 0.534998 0.104744 +vt 0.535152 0.105157 +vt 0.723346 0.592096 +vt 0.724150 0.591793 +vt 0.724562 0.594830 +vt 0.725296 0.594393 +vt 0.532663 0.105575 +vt 0.532844 0.105971 +vt 0.530806 0.106458 +vt 0.531015 0.106837 +vt 0.723183 0.581091 +vt 0.722326 0.580966 +vt 0.722047 0.583787 +vt 0.722914 0.583810 +vt 0.545600 0.103329 +vt 0.545557 0.102892 +vt 0.542736 0.103149 +vt 0.542808 0.103585 +vt 0.917380 0.405316 +vt 0.917013 0.404235 +vt 0.915437 0.404441 +vt 0.915705 0.405541 +vt 0.916792 0.398369 +vt 0.915238 0.398568 +vt 0.913369 0.398699 +vt 0.913547 0.404578 +vt 0.913712 0.405693 +vt 0.911314 0.404663 +vt 0.911376 0.405778 +vt 0.911156 0.398773 +vt 0.920024 0.404670 +vt 0.919468 0.403618 +vt 0.918364 0.403950 +vt 0.918827 0.405019 +vt 0.919208 0.397774 +vt 0.918123 0.398093 +vt 0.727625 0.570429 +vt 0.726969 0.569868 +vt 0.725357 0.572051 +vt 0.726088 0.572510 +vt 0.557534 0.103588 +vt 0.557627 0.103157 +vt 0.555060 0.102865 +vt 0.555000 0.103299 +vt 0.552130 0.102724 +vt 0.552106 0.103157 +vt 0.723992 0.574676 +vt 0.724781 0.575027 +vt 0.722974 0.577794 +vt 0.723805 0.578030 +vt 0.548819 0.102741 +vt 0.548830 0.103177 +vt 0.921873 0.999058 +vt 0.922002 0.998103 +vt 0.920467 0.998156 +vt 0.920206 0.999124 +vt 0.921309 0.991849 +vt 0.919805 0.991897 +vt 0.918763 0.991974 +vt 0.919394 0.998239 +vt 0.920935 0.404277 +vt 0.920292 0.403259 +vt 0.742989 0.566360 +vt 0.746633 0.567140 +vt 0.746823 0.566277 +vt 0.743133 0.565500 +vt 0.749341 0.567819 +vt 0.749473 0.566938 +vt 0.915254 0.525917 +vt 0.917828 0.524998 +vt 0.917241 0.524908 +vt 0.915086 0.525552 +vt 0.911595 0.526845 +vt 0.911471 0.526465 +vt 0.930829 0.977209 +vt 0.929286 0.960774 +vt 0.282073 0.226556 +vt 0.282849 0.226561 +vt 0.281518 0.211215 +vt 0.282295 0.211093 +vt 0.728743 0.568000 +vt 0.729304 0.568655 +vt 0.561793 0.104554 +vt 0.561947 0.104146 +vt 0.559932 0.103583 +vt 0.559808 0.104005 +vt 0.924248 0.998078 +vt 0.924240 0.999010 +vt 0.923533 0.991829 +vt 0.921935 0.913183 +vt 0.739163 0.569260 +vt 0.739132 0.570122 +vt 0.285319 0.210761 +vt 0.285854 0.226294 +vt 0.286630 0.226153 +vt 0.286106 0.210715 +vt 0.918000 0.464004 +vt 0.916438 0.480549 +vt 0.740089 0.582137 +vt 0.740784 0.583383 +vt 0.739350 0.581479 +vt 0.343750 0.102909 +vt 0.342787 0.101879 +vt 0.344409 0.107977 +vt 0.344888 0.102023 +vt 0.343582 0.100732 +vt 0.988122 0.527353 +vt 0.988280 0.531398 +vt 0.989894 0.531494 +vt 0.989744 0.527439 +vt 0.988263 0.532577 +vt 0.989829 0.532793 +vt 0.991394 0.533008 +vt 0.991509 0.531590 +vt 0.991366 0.527526 +vt 0.740902 0.585269 +vt 0.740224 0.587380 +vt 0.738699 0.589201 +vt 0.736659 0.590287 +vt 0.341196 0.101674 +vt 0.339264 0.101867 +vt 0.341442 0.100436 +vt 0.338881 0.100712 +vt 0.734523 0.590298 +vt 0.732664 0.589236 +vt 0.337596 0.106078 +vt 0.337172 0.105282 +vt 0.335751 0.105147 +vt 0.336329 0.106388 +vt 0.336140 0.103818 +vt 0.334827 0.103233 +vt 0.334330 0.105013 +vt 0.337432 0.102639 +vt 0.336492 0.101705 +vt 0.731400 0.587273 +vt 0.730859 0.584894 +vt 0.731092 0.582565 +vt 0.732049 0.580357 +vt 0.343380 0.106696 +vt 0.341732 0.107018 +vt 0.341763 0.107921 +vt 0.343824 0.107535 +vt 0.340145 0.107019 +vt 0.339726 0.107863 +vt 0.338676 0.106685 +vt 0.337785 0.107331 +vt 0.733660 0.578312 +vt 0.735900 0.576740 +vt 0.346473 0.105051 +vt 0.345039 0.106065 +vt 0.345863 0.106743 +vt 0.347608 0.105512 +vt 0.738712 0.575939 +vt 0.741877 0.575886 +vt 0.745064 0.576490 +vt 0.747679 0.577695 +vt 0.348037 0.100315 +vt 0.349452 0.099883 +vt 0.348890 0.098179 +vt 0.347968 0.101954 +vt 0.349398 0.101883 +vt 0.350828 0.101812 +vt 0.350867 0.099451 +vt 0.350139 0.097404 +vt 0.347455 0.103617 +vt 0.348791 0.103837 +vt 0.347676 0.097058 +vt 0.345983 0.096473 +vt 0.348590 0.096048 +vt 0.346510 0.095348 +vt 0.749722 0.583816 +vt 0.749217 0.586238 +vt 0.749803 0.581529 +vt 0.749215 0.579432 +vt 0.748470 0.588741 +vt 0.747446 0.591161 +vt 0.339570 0.096610 +vt 0.337316 0.097029 +vt 0.341845 0.096374 +vt 0.341807 0.095265 +vt 0.339329 0.095517 +vt 0.336875 0.095960 +vt 0.344009 0.096292 +vt 0.344217 0.095154 +vt 0.746063 0.593336 +vt 0.744285 0.595214 +vt 0.742111 0.596763 +vt 0.739665 0.597911 +vt 0.335205 0.097685 +vt 0.333279 0.098608 +vt 0.334538 0.096680 +vt 0.332383 0.097710 +vt 0.737120 0.598587 +vt 0.734740 0.598760 +vt 0.330024 0.104364 +vt 0.329122 0.102727 +vt 0.328547 0.104182 +vt 0.330154 0.101211 +vt 0.328883 0.100629 +vt 0.327720 0.102336 +vt 0.327069 0.104000 +vt 0.331569 0.099805 +vt 0.330469 0.099051 +vt 0.732737 0.598441 +vt 0.731019 0.597761 +vt 0.729451 0.596818 +vt 0.728019 0.595452 +vt 0.331391 0.108060 +vt 0.330613 0.107194 +vt 0.329271 0.107616 +vt 0.330191 0.108634 +vt 0.330171 0.106305 +vt 0.328738 0.106553 +vt 0.327305 0.106801 +vt 0.329944 0.105398 +vt 0.328461 0.105438 +vt 0.326977 0.105478 +vt 0.726756 0.593519 +vt 0.725743 0.591191 +vt 0.334231 0.109570 +vt 0.332630 0.108865 +vt 0.331621 0.109588 +vt 0.333431 0.110420 +vt 0.725053 0.588704 +vt 0.724685 0.586233 +vt 0.724622 0.583857 +vt 0.724873 0.581338 +vt 0.341803 0.110856 +vt 0.339776 0.110779 +vt 0.339509 0.111783 +vt 0.341709 0.111863 +vt 0.337920 0.110546 +vt 0.337488 0.111524 +vt 0.336044 0.110139 +vt 0.335438 0.111070 +vt 0.346470 0.110531 +vt 0.344141 0.110789 +vt 0.344242 0.111775 +vt 0.346778 0.111481 +vt 0.727536 0.573420 +vt 0.728922 0.571541 +vt 0.726346 0.575722 +vt 0.725449 0.578498 +vt 0.730414 0.569955 +vt 0.732034 0.568700 +vt 0.352719 0.108052 +vt 0.351539 0.108776 +vt 0.352439 0.109501 +vt 0.353804 0.108625 +vt 0.350108 0.109435 +vt 0.350816 0.110270 +vt 0.348449 0.110050 +vt 0.348960 0.110955 +vt 0.733875 0.567847 +vt 0.736203 0.567454 +vt 0.739282 0.565836 +vt 0.739223 0.567549 +vt 0.742709 0.568053 +vt 0.354760 0.102063 +vt 0.354610 0.104230 +vt 0.356068 0.104280 +vt 0.356246 0.102007 +vt 0.354229 0.105967 +vt 0.355617 0.106168 +vt 0.357526 0.104330 +vt 0.357732 0.101950 +vt 0.353608 0.107184 +vt 0.354865 0.107571 +vt 0.357744 0.100185 +vt 0.356248 0.100299 +vt 0.284984 0.240459 +vt 0.285321 0.246932 +vt 0.354752 0.100413 +vt 0.746221 0.568814 +vt 0.748864 0.569484 +vt 0.286548 0.168750 +vt 0.284824 0.168658 +vt 0.286670 0.167470 +vt 0.284944 0.167382 +vt 0.283220 0.167293 +vt 0.283101 0.168566 +vt 0.739314 0.564973 +vt 0.907751 0.527550 +vt 0.907902 0.527914 +vt 0.987748 0.510043 +vt 0.987877 0.519332 +vt 0.989497 0.519442 +vt 0.989350 0.510202 +vt 0.991119 0.519553 +vt 0.990954 0.510363 +vt 0.287443 0.168818 +vt 0.287556 0.167563 +vt 0.287221 0.173085 +vt 0.918617 0.523467 +vt 0.918049 0.519199 +vt 0.916922 0.519401 +vt 0.917522 0.523643 +vt 0.930417 0.916772 +vt 0.931479 0.916958 +vt 0.929807 0.921124 +vt 0.930902 0.921328 +vt 0.282220 0.168541 +vt 0.282060 0.172898 +vt 0.282340 0.167297 +vt 0.987449 0.531321 +vt 0.987470 0.532424 +vt 0.987286 0.527291 +vt 0.986997 0.527150 +vt 0.987164 0.531135 +vt 0.987235 0.532154 +vt 0.984975 0.570549 +vt 0.984395 0.570796 +vt 0.984051 0.566064 +vt 0.983439 0.566284 +vt 0.992298 0.531659 +vt 0.992161 0.527602 +vt 0.992153 0.533095 +vt 0.211947 0.058789 +vt 0.213691 0.058841 +vt 0.211748 0.063303 +vt 0.213496 0.063386 +vt 0.986166 0.570170 +vt 0.985284 0.565681 +vt 0.205768 0.058358 +vt 0.209108 0.058614 +vt 0.205589 0.062824 +vt 0.208916 0.063098 +vt 0.928680 0.821957 +vt 0.928663 0.830841 +vt 0.929712 0.830723 +vt 0.929717 0.821873 +vt 0.930480 0.830589 +vt 0.930474 0.821706 +vt 0.883733 0.691626 +vt 0.884896 0.681015 +vt 0.884537 0.680619 +vt 0.883330 0.691407 +vt 0.884235 0.680175 +vt 0.882977 0.691158 +vt 0.943606 0.912900 +vt 0.946169 0.913864 +vt 0.942802 0.917346 +vt 0.945362 0.918294 +vt 0.202681 0.058095 +vt 0.202521 0.062562 +vt 0.980245 0.316661 +vt 0.981422 0.327305 +vt 0.982217 0.327023 +vt 0.981032 0.316399 +vt 0.927544 0.830729 +vt 0.927577 0.821825 +vt 0.937481 0.911010 +vt 0.940506 0.911880 +vt 0.936693 0.915522 +vt 0.939710 0.916357 +vt 0.951878 0.073241 +vt 0.948939 0.074091 +vt 0.951870 0.069223 +vt 0.948952 0.070089 +vt 0.935101 0.910463 +vt 0.934317 0.915005 +vt 0.935468 0.909106 +vt 0.956801 0.249561 +vt 0.957118 0.238833 +vt 0.955770 0.238748 +vt 0.955478 0.249410 +vt 0.954789 0.238682 +vt 0.954517 0.249268 +vt 0.978513 0.317047 +vt 0.979684 0.327788 +vt 0.980548 0.327564 +vt 0.979377 0.316883 +vt 0.959794 0.249818 +vt 0.960153 0.239077 +vt 0.958593 0.238938 +vt 0.958253 0.249698 +vt 0.964054 0.073869 +vt 0.961303 0.073151 +vt 0.964008 0.069860 +vt 0.961260 0.069124 +vt 0.958121 0.068763 +vt 0.958157 0.072794 +vt 0.954991 0.072812 +vt 0.954967 0.068784 +vt 0.909929 0.313539 +vt 0.906277 0.314761 +vt 0.909164 0.309104 +vt 0.905507 0.310270 +vt 0.902462 0.311369 +vt 0.903236 0.315902 +vt 0.938660 0.346336 +vt 0.939767 0.335844 +vt 0.937533 0.335252 +vt 0.936430 0.345892 +vt 0.935671 0.334731 +vt 0.934573 0.345479 +vt 0.962772 0.249922 +vt 0.963159 0.239342 +vt 0.961755 0.239241 +vt 0.961380 0.249915 +vt 0.917372 0.311461 +vt 0.913851 0.312387 +vt 0.916607 0.307152 +vt 0.913087 0.308017 +vt 0.900872 0.224412 +vt 0.898238 0.224237 +vt 0.901139 0.220143 +vt 0.898515 0.219937 +vt 0.919891 0.310881 +vt 0.919124 0.306621 +vt 0.945746 0.628648 +vt 0.945642 0.620181 +vt 0.944488 0.620609 +vt 0.944603 0.629048 +vt 0.945023 0.337192 +vt 0.943920 0.337007 +vt 0.943925 0.347236 +vt 0.942831 0.347113 +vt 0.942048 0.336496 +vt 0.940951 0.346781 +vt 0.906658 0.224791 +vt 0.903720 0.224582 +vt 0.906896 0.220554 +vt 0.903974 0.220335 +vt 0.949281 0.628173 +vt 0.949222 0.619617 +vt 0.947255 0.619857 +vt 0.947341 0.628373 +vt 0.912581 0.225389 +vt 0.909636 0.225074 +vt 0.912774 0.221152 +vt 0.909854 0.220840 +vt 0.918048 0.225950 +vt 0.915413 0.225686 +vt 0.918184 0.221696 +vt 0.915579 0.221443 +vt 0.957249 0.628372 +vt 0.957351 0.619730 +vt 0.955563 0.619494 +vt 0.955503 0.628093 +vt 0.953583 0.619410 +vt 0.953563 0.627987 +vt 0.951405 0.619460 +vt 0.951427 0.628030 +vt 0.903493 0.758642 +vt 0.905988 0.759545 +vt 0.902701 0.762890 +vt 0.905183 0.763766 +vt 0.920391 0.226177 +vt 0.920497 0.221906 +vt 0.771313 0.130442 +vt 0.772618 0.140827 +vt 0.774180 0.140226 +vt 0.772866 0.129935 +vt 0.958972 0.620125 +vt 0.775493 0.139658 +vt 0.774175 0.129450 +vt 0.898014 0.756782 +vt 0.900743 0.757682 +vt 0.897260 0.761097 +vt 0.899968 0.761963 +vt 0.893293 0.755389 +vt 0.895543 0.756037 +vt 0.892579 0.759766 +vt 0.894810 0.760384 +vt 0.765550 0.131932 +vt 0.766790 0.142702 +vt 0.767989 0.142357 +vt 0.766736 0.131678 +vt 0.769345 0.141920 +vt 0.768080 0.131345 +vt 0.770940 0.141402 +vt 0.769655 0.130924 +vt 0.763255 0.132283 +vt 0.764454 0.143174 +vt 0.765627 0.142960 +vt 0.764408 0.132129 +vt 0.534972 0.103474 +vt 0.532636 0.104311 +vt 0.535166 0.099568 +vt 0.532863 0.100421 +vt 0.887184 0.753756 +vt 0.886511 0.758232 +vt 0.888448 0.758652 +vt 0.889131 0.754206 +vt 0.887542 0.752415 +vt 0.891170 0.754768 +vt 0.890473 0.759179 +vt 0.540134 0.102252 +vt 0.537530 0.102784 +vt 0.540264 0.098316 +vt 0.537690 0.098862 +vt 0.904146 0.346113 +vt 0.904401 0.335111 +vt 0.902463 0.334893 +vt 0.902259 0.345849 +vt 0.900611 0.334682 +vt 0.900461 0.345572 +vt 0.899005 0.334503 +vt 0.898907 0.345306 +vt 0.763262 0.143381 +vt 0.764600 0.152339 +vt 0.762072 0.132404 +vt 0.545538 0.101610 +vt 0.542715 0.101869 +vt 0.545615 0.097657 +vt 0.542818 0.097923 +vt 0.552119 0.101442 +vt 0.548804 0.101459 +vt 0.552144 0.097487 +vt 0.548854 0.097503 +vt 0.912936 0.346942 +vt 0.913370 0.335993 +vt 0.910919 0.335775 +vt 0.910528 0.346770 +vt 0.908458 0.335529 +vt 0.908112 0.346555 +vt 0.906333 0.335314 +vt 0.906032 0.346341 +vt 0.557626 0.101879 +vt 0.555053 0.101585 +vt 0.557615 0.097947 +vt 0.555059 0.097640 +vt 0.916667 0.347070 +vt 0.917158 0.336226 +vt 0.915439 0.336129 +vt 0.914973 0.347032 +vt 0.561955 0.102877 +vt 0.559936 0.102310 +vt 0.561918 0.098971 +vt 0.559910 0.098390 +vt 0.904164 0.527278 +vt 0.901610 0.528162 +vt 0.903501 0.522878 +vt 0.900956 0.523725 +vt 0.899005 0.524413 +vt 0.899650 0.528878 +vt 0.916480 0.938316 +vt 0.917339 0.927624 +vt 0.915720 0.927193 +vt 0.914874 0.937985 +vt 0.914612 0.926848 +vt 0.913772 0.937728 +vt 0.919295 0.347092 +vt 0.919817 0.336423 +vt 0.918626 0.336331 +vt 0.918116 0.347092 +vt 0.911156 0.525125 +vt 0.907432 0.526208 +vt 0.910470 0.520818 +vt 0.906760 0.521854 +vt 0.914844 0.524227 +vt 0.914163 0.519960 +vt 0.927920 0.916290 +vt 0.927228 0.920662 +vt 0.921884 0.939260 +vt 0.922800 0.928836 +vt 0.919751 0.928199 +vt 0.918870 0.938767 +vt 0.921810 0.977235 +vt 0.919942 0.960645 +vt 0.917654 0.960584 +vt 0.919566 0.977249 +vt 0.921842 0.948830 +vt 0.918894 0.948568 +vt 0.916550 0.948321 +vt 0.918942 0.384207 +vt 0.917847 0.384504 +vt 0.918786 0.368629 +vt 0.917667 0.368866 +vt 0.916294 0.369067 +vt 0.916504 0.384761 +vt 0.918916 0.356931 +vt 0.917764 0.357055 +vt 0.916351 0.357150 +vt 0.918051 0.977281 +vt 0.916112 0.960551 +vt 0.915048 0.960545 +vt 0.917006 0.977338 +vt 0.914973 0.948144 +vt 0.913887 0.948019 +vt 0.914936 0.384950 +vt 0.914692 0.369215 +vt 0.912766 0.369292 +vt 0.913051 0.385068 +vt 0.914701 0.357208 +vt 0.912718 0.357202 +vt 0.908577 0.385090 +vt 0.906643 0.384987 +vt 0.908201 0.369205 +vt 0.906231 0.369063 +vt 0.904441 0.368851 +vt 0.904883 0.384804 +vt 0.908021 0.356960 +vt 0.905998 0.356774 +vt 0.904163 0.356544 +vt 0.910819 0.385116 +vt 0.910487 0.369285 +vt 0.910373 0.357111 +vt 0.901425 0.384199 +vt 0.899961 0.383798 +vt 0.900935 0.368212 +vt 0.899455 0.367820 +vt 0.763644 0.091368 +vt 0.762338 0.108618 +vt 0.763469 0.108658 +vt 0.764756 0.091427 +vt 0.900578 0.355927 +vt 0.899067 0.355583 +vt 0.761740 0.121696 +vt 0.762898 0.121669 +vt 0.903115 0.384540 +vt 0.902647 0.368564 +vt 0.902327 0.356256 +vt 0.765847 0.091419 +vt 0.764575 0.108641 +vt 0.765677 0.108603 +vt 0.766937 0.091403 +vt 0.764027 0.121593 +vt 0.765148 0.121483 +vt 0.769380 0.091453 +vt 0.770899 0.091417 +vt 0.768144 0.108524 +vt 0.769680 0.108410 +vt 0.771298 0.108256 +vt 0.772499 0.091350 +vt 0.767647 0.121162 +vt 0.769201 0.120898 +vt 0.770840 0.120581 +vt 0.768080 0.091430 +vt 0.766832 0.108576 +vt 0.766318 0.121349 +vt 0.773998 0.091290 +vt 0.772817 0.108095 +vt 0.774100 0.107933 +vt 0.775262 0.091230 +vt 0.772377 0.120246 +vt 0.773677 0.119919 +vt 0.338795 0.115277 +vt 0.340742 0.114861 +vt 0.339333 0.127609 +vt 0.341313 0.127143 +vt 0.343318 0.126839 +vt 0.342709 0.114604 +vt 0.952454 0.644134 +vt 0.953212 0.635427 +vt 0.951132 0.635420 +vt 0.950430 0.644065 +vt 0.949044 0.635512 +vt 0.948402 0.644097 +vt 0.953817 0.667362 +vt 0.954802 0.656861 +vt 0.953159 0.656336 +vt 0.952179 0.666811 +vt 0.955966 0.644854 +vt 0.954299 0.644386 +vt 0.951345 0.656037 +vt 0.337044 0.115871 +vt 0.956806 0.635971 +vt 0.955104 0.635601 +vt 0.344497 0.114499 +vt 0.345143 0.126682 +vt 0.346662 0.126711 +vt 0.345983 0.114579 +vt 0.947156 0.635647 +vt 0.946572 0.644162 +vt 0.945603 0.635859 +vt 0.945070 0.644306 +vt 0.944577 0.383842 +vt 0.942813 0.383969 +vt 0.943185 0.367645 +vt 0.941383 0.367695 +vt 0.939184 0.367729 +vt 0.940664 0.384103 +vt 0.942547 0.356228 +vt 0.940696 0.356106 +vt 0.938440 0.355920 +vt 0.347082 0.114902 +vt 0.347785 0.127000 +vt 0.945593 0.383842 +vt 0.944221 0.367643 +vt 0.347232 0.134953 +vt 0.348391 0.135226 +vt 0.944490 0.636223 +vt 0.943614 0.356276 +vt 0.936839 0.384124 +vt 0.935624 0.384157 +vt 0.935272 0.367610 +vt 0.934033 0.367555 +vt 0.961679 0.286509 +vt 0.961357 0.271124 +vt 0.959857 0.271264 +vt 0.960216 0.286726 +vt 0.962673 0.270841 +vt 0.962598 0.259485 +vt 0.961239 0.259627 +vt 0.959692 0.259646 +vt 0.938579 0.384133 +vt 0.937051 0.367686 +vt 0.936250 0.355691 +vt 0.934425 0.355454 +vt 0.958794 0.286777 +vt 0.958402 0.271269 +vt 0.957031 0.271146 +vt 0.957454 0.286666 +vt 0.958191 0.259583 +vt 0.956778 0.259445 +vt 0.980360 0.277733 +vt 0.981176 0.277762 +vt 0.978958 0.294447 +vt 0.979790 0.294439 +vt 0.980629 0.294365 +vt 0.982001 0.277725 +vt 0.978256 0.306876 +vt 0.979107 0.306795 +vt 0.979962 0.306647 +vt 0.956233 0.286418 +vt 0.955784 0.270913 +vt 0.954881 0.270640 +vt 0.955350 0.286116 +vt 0.955492 0.259244 +vt 0.954560 0.259028 +vt 0.982754 0.277644 +vt 0.981393 0.294245 +vt 0.929965 0.793212 +vt 0.928783 0.805070 +vt 0.929828 0.805315 +vt 0.930989 0.793497 +vt 0.339645 0.120517 +vt 0.340619 0.120063 +vt 0.980739 0.306453 +vt 0.927965 0.814011 +vt 0.929040 0.814196 +vt 0.885606 0.729984 +vt 0.885186 0.730164 +vt 0.884187 0.713517 +vt 0.883767 0.713658 +vt 0.883386 0.713810 +vt 0.884792 0.730134 +vt 0.883480 0.701464 +vt 0.883058 0.701428 +vt 0.882681 0.701381 +vt 0.341570 0.119934 +vt 0.341186 0.132495 +vt 0.342153 0.132316 +vt 0.342881 0.132386 +vt 0.342282 0.119994 +vt 0.930052 0.814170 +vt 0.930810 0.805355 +vt 0.930788 0.813985 +vt 0.342623 0.141127 +vt 0.343376 0.141214 +vt 0.345134 0.119246 +vt 0.345859 0.131886 +vt 0.988553 0.492813 +vt 0.987940 0.501961 +vt 0.989498 0.502197 +vt 0.990057 0.493122 +vt 0.991056 0.502435 +vt 0.991560 0.493432 +vt 0.286812 0.181509 +vt 0.286354 0.191246 +vt 0.916864 0.510794 +vt 0.915835 0.500978 +vt 0.914744 0.501121 +vt 0.915752 0.510978 +vt 0.285246 0.199933 +vt 0.286047 0.199887 +vt 0.915624 0.492059 +vt 0.914560 0.492134 +vt 0.928640 0.929820 +vt 0.929725 0.929991 +vt 0.927636 0.939988 +vt 0.928703 0.940101 +vt 0.281813 0.181544 +vt 0.281545 0.191535 +vt 0.927450 0.949180 +vt 0.928490 0.949218 +vt 0.281378 0.200347 +vt 0.282170 0.200237 +vt 0.987042 0.519269 +vt 0.986923 0.509967 +vt 0.986649 0.509963 +vt 0.986759 0.519190 +vt 0.987139 0.501856 +vt 0.987779 0.492681 +vt 0.344233 0.141863 +vt 0.343963 0.141823 +vt 0.986876 0.501917 +vt 0.982556 0.556940 +vt 0.981936 0.557126 +vt 0.981211 0.546132 +vt 0.980588 0.546262 +vt 0.991913 0.519646 +vt 0.991740 0.510488 +vt 0.980799 0.536212 +vt 0.980185 0.536272 +vt 0.991820 0.502605 +vt 0.992298 0.493642 +vt 0.211422 0.072288 +vt 0.213156 0.072457 +vt 0.211144 0.082770 +vt 0.212849 0.083050 +vt 0.983803 0.556629 +vt 0.982463 0.545928 +vt 0.211101 0.092110 +vt 0.212752 0.092495 +vt 0.982030 0.536134 +vt 0.284352 0.226428 +vt 0.283808 0.210927 +vt 0.283709 0.200086 +vt 0.205320 0.071710 +vt 0.208612 0.072015 +vt 0.205152 0.082132 +vt 0.208382 0.082433 +vt 0.205275 0.091537 +vt 0.208418 0.091752 +vt 0.941466 0.926304 +vt 0.944017 0.927197 +vt 0.940284 0.937086 +vt 0.942817 0.937827 +vt 0.202297 0.071459 +vt 0.202196 0.081965 +vt 0.939976 0.947308 +vt 0.942478 0.947769 +vt 0.202394 0.091563 +vt 0.935402 0.924662 +vt 0.938396 0.925401 +vt 0.934293 0.935807 +vt 0.937249 0.936369 +vt 0.934084 0.946579 +vt 0.936987 0.946887 +vt 0.951966 0.061260 +vt 0.949097 0.062165 +vt 0.952257 0.051833 +vt 0.949458 0.052780 +vt 0.933038 0.924225 +vt 0.931958 0.935499 +vt 0.952852 0.043272 +vt 0.950129 0.044237 +vt 0.341044 0.148949 +vt 0.338211 0.148055 +vt 0.931802 0.946434 +vt 0.963993 0.061943 +vt 0.961256 0.061156 +vt 0.964067 0.052734 +vt 0.961369 0.051833 +vt 0.958304 0.051383 +vt 0.958139 0.060776 +vt 0.900174 0.291172 +vt 0.900123 0.280792 +vt 0.897960 0.281207 +vt 0.897983 0.291853 +vt 0.961707 0.043557 +vt 0.962490 0.034220 +vt 0.959608 0.033483 +vt 0.958731 0.042965 +vt 0.955019 0.060800 +vt 0.955243 0.051371 +vt 0.955756 0.042855 +vt 0.346879 0.148327 +vt 0.343967 0.149016 +vt 0.907914 0.300196 +vt 0.904251 0.301213 +vt 0.906854 0.289660 +vt 0.903209 0.290410 +vt 0.901201 0.302198 +vt 0.906690 0.279988 +vt 0.903110 0.280366 +vt 0.915350 0.298570 +vt 0.911837 0.299277 +vt 0.914226 0.288562 +vt 0.910747 0.289021 +vt 0.913907 0.279550 +vt 0.910503 0.279710 +vt 0.901601 0.211750 +vt 0.899004 0.211470 +vt 0.902055 0.202100 +vt 0.899509 0.201726 +vt 0.917854 0.298158 +vt 0.916701 0.288326 +vt 0.902291 0.193641 +vt 0.899821 0.193181 +vt 0.916326 0.279509 +vt 0.907283 0.212221 +vt 0.904401 0.211983 +vt 0.907617 0.202612 +vt 0.904798 0.202374 +vt 0.907696 0.194129 +vt 0.904955 0.193931 +vt 0.913056 0.212809 +vt 0.910192 0.212508 +vt 0.913248 0.203114 +vt 0.910458 0.202869 +vt 0.913183 0.194425 +vt 0.910463 0.194301 +vt 0.918328 0.213294 +vt 0.915795 0.213077 +vt 0.918363 0.203421 +vt 0.915909 0.203304 +vt 0.918180 0.194389 +vt 0.915781 0.194461 +vt 0.901374 0.771387 +vt 0.903826 0.772188 +vt 0.900172 0.781626 +vt 0.902587 0.782261 +vt 0.920570 0.213454 +vt 0.920528 0.203454 +vt 0.899800 0.791438 +vt 0.902185 0.791804 +vt 0.920301 0.194200 +vt 0.919936 0.182737 +vt 0.896025 0.769780 +vt 0.898684 0.770552 +vt 0.894925 0.780384 +vt 0.897530 0.780976 +vt 0.894625 0.790751 +vt 0.897193 0.791075 +vt 0.891441 0.768614 +vt 0.893625 0.769150 +vt 0.890448 0.779513 +vt 0.892580 0.779909 +vt 0.890220 0.790290 +vt 0.892317 0.790495 +vt 0.535698 0.091829 +vt 0.533472 0.092723 +vt 0.536487 0.082486 +vt 0.534343 0.083434 +vt 0.885473 0.767332 +vt 0.884604 0.778627 +vt 0.886478 0.778851 +vt 0.887383 0.767673 +vt 0.882943 0.778485 +vt 0.882865 0.789840 +vt 0.884486 0.789885 +vt 0.883725 0.803583 +vt 0.886318 0.789976 +vt 0.889375 0.768113 +vt 0.888428 0.779155 +vt 0.888232 0.790115 +vt 0.540648 0.090510 +vt 0.538145 0.091086 +vt 0.541268 0.081097 +vt 0.538848 0.081701 +vt 0.542127 0.072233 +vt 0.539769 0.072842 +vt 0.338826 0.153609 +vt 0.336411 0.153062 +vt 0.334025 0.152232 +vt 0.537465 0.073652 +vt 0.545874 0.089815 +vt 0.543138 0.090094 +vt 0.546339 0.080390 +vt 0.543682 0.080668 +vt 0.547063 0.071574 +vt 0.544477 0.071819 +vt 0.343806 0.153944 +vt 0.341209 0.153897 +vt 0.552277 0.089651 +vt 0.549048 0.089656 +vt 0.552573 0.080281 +vt 0.549427 0.080248 +vt 0.553121 0.071598 +vt 0.550065 0.071486 +vt 0.349822 0.153288 +vt 0.346800 0.153753 +vt 0.557657 0.090173 +vt 0.555142 0.089830 +vt 0.557820 0.080940 +vt 0.555366 0.080522 +vt 0.558215 0.072479 +vt 0.555834 0.071944 +vt 0.559126 0.062842 +vt 0.556810 0.062199 +vt 0.352472 0.152527 +vt 0.561895 0.091273 +vt 0.559916 0.090652 +vt 0.561955 0.082196 +vt 0.560024 0.081495 +vt 0.897293 0.504388 +vt 0.897446 0.493778 +vt 0.895960 0.493999 +vt 0.895783 0.504791 +vt 0.560352 0.073150 +vt 0.561203 0.063617 +vt 0.902473 0.514021 +vt 0.899952 0.514770 +vt 0.901682 0.503356 +vt 0.899195 0.503923 +vt 0.898021 0.515382 +vt 0.901764 0.493227 +vt 0.899318 0.493526 +vt 0.909381 0.512211 +vt 0.905705 0.513119 +vt 0.908494 0.502012 +vt 0.904872 0.502682 +vt 0.908453 0.492549 +vt 0.904900 0.492881 +vt 0.913030 0.511465 +vt 0.912077 0.501471 +vt 0.911956 0.492295 +vt 0.926081 0.929413 +vt 0.925118 0.939693 +vt 0.924997 0.949045 +vn 0.1145 0.2059 -0.9719 +vn 0.0818 0.2209 -0.9719 +vn 0.0440 0.1474 -0.9881 +vn 0.0716 0.1350 -0.9883 +vn -0.1902 0.3421 -0.9202 +vn -0.2146 0.2608 -0.9412 +vn -0.2701 0.1247 -0.9547 +vn -0.0263 0.0165 -0.9995 +vn -0.0064 0.0078 -0.9999 +vn 0.1544 0.1838 -0.9708 +vn 0.1658 0.1727 -0.9709 +vn 0.1918 0.1970 -0.9615 +vn 0.1809 0.2095 -0.9609 +vn 0.1804 0.1552 -0.9713 +vn 0.1896 0.1548 -0.9696 +vn 0.1194 0.1062 -0.9872 +vn 0.1176 0.1223 -0.9855 +vn 0.1131 0.1397 -0.9837 +vn -0.9242 0.3784 -0.0521 +vn -0.8018 0.3440 0.4887 +vn -0.7568 0.4498 0.4743 +vn -0.9276 0.3690 -0.0577 +vn -0.8018 0.3439 0.4887 +vn -0.2576 0.1440 0.9555 +vn -0.1685 0.3385 0.9258 +vn -0.0847 0.5285 0.8447 +vn -0.7143 0.5538 0.4279 +vn -0.9298 0.3647 -0.0491 +vn -0.2758 -0.3122 0.9091 +vn -0.2900 -0.3041 0.9075 +vn -0.1952 -0.2089 0.9583 +vn -0.1847 -0.2212 0.9576 +vn -0.2907 -0.3099 0.9052 +vn -0.1995 -0.2398 0.9501 +vn -0.1376 -0.1724 0.9754 +vn -0.1461 -0.1621 0.9759 +vn -0.1350 -0.1722 0.9758 +vn 0.1071 -0.3828 -0.9176 +vn -0.2271 -0.3717 -0.9001 +vn 0.4104 -0.1192 -0.9041 +vn 0.6841 -0.5877 -0.4320 +vn 0.2044 -0.8360 -0.5092 +vn -0.4543 -0.7650 -0.4565 +vn 0.1174 -0.4326 0.8939 +vn 0.1882 -0.3279 0.9258 +vn -0.0688 -0.1043 0.9922 +vn 0.5614 -0.7438 0.3628 +vn 0.6507 -0.6472 0.3972 +vn 0.6867 -0.6111 0.3938 +vn 0.2932 -0.2266 0.9288 +vn 0.0469 0.0065 0.9989 +vn 0.4413 -0.0814 0.8937 +vn 0.2069 0.1590 0.9654 +vn 0.6867 -0.6110 0.3938 +vn 0.7480 -0.5456 0.3779 +vn 0.8084 -0.4818 0.3383 +vn 0.5842 0.0592 0.8095 +vn 0.3626 0.3072 0.8799 +vn -0.0757 -0.0944 0.9926 +vn -0.0637 -0.1011 0.9928 +vn 0.0402 0.0173 0.9990 +vn 0.0515 0.0149 0.9986 +vn -0.5211 -0.8431 -0.1330 +vn 0.0845 -0.9843 0.1550 +vn -0.2018 -0.7138 0.6706 +vn -0.5337 -0.6875 0.4924 +vn -0.2018 -0.7138 0.6707 +vn -0.2012 0.3754 -0.9047 +vn -0.7519 0.4738 -0.4584 +vn -0.7242 0.4891 -0.4861 +vn -0.2271 0.3157 -0.9213 +vn -0.7538 0.1245 -0.6452 +vn -0.7519 0.4738 -0.4583 +vn -0.9797 -0.0120 -0.2000 +vn -0.9130 0.4050 -0.0490 +vn -0.8921 0.4482 -0.0579 +vn -0.2677 -0.4215 -0.8664 +vn -0.2637 -0.4241 -0.8664 +vn -0.3377 -0.5617 -0.7553 +vn -0.3482 -0.5556 -0.7550 +vn -0.4727 -0.3167 -0.8223 +vn -0.5376 -0.4485 -0.7140 +vn -0.5744 -0.5189 -0.6331 +vn -0.3796 -0.6400 -0.6681 +vn -0.3941 -0.6323 -0.6670 +vn -0.7716 0.3407 -0.5372 +vn -0.8326 0.2063 -0.5140 +vn -0.3706 -0.0947 -0.9240 +vn -0.7716 0.3407 -0.5371 +vn -0.9122 0.3929 -0.1167 +vn -0.9286 0.3522 -0.1171 +vn -0.8326 0.2062 -0.5140 +vn -0.9437 0.3172 -0.0941 +vn -0.8884 0.0696 -0.4537 +vn -0.8885 0.0697 -0.4536 +vn -0.4727 -0.3168 -0.8223 +vn -0.1438 -0.2016 -0.9689 +vn -0.1360 -0.2044 -0.9694 +vn 0.1986 0.1701 0.9652 +vn 0.2066 0.1720 0.9632 +vn 0.3522 0.3189 0.8799 +vn 0.3551 0.3240 0.8769 +vn 0.5518 0.4875 0.6767 +vn 0.7512 0.2257 0.6202 +vn 0.8068 0.2791 0.5208 +vn 0.6148 0.5480 0.5672 +vn 0.8745 -0.4097 0.2597 +vn 0.8961 -0.3853 0.2201 +vn 0.9167 -0.3642 0.1640 +vn 0.8589 0.3289 0.3926 +vn 0.6724 0.6035 0.4286 +vn 0.4649 0.4284 0.7748 +vn 0.4633 0.4360 0.7715 +vn 0.4764 0.4156 0.7748 +vn 0.5400 0.5018 0.6757 +vn 0.5358 0.5120 0.6714 +vn 0.6859 0.1606 0.7098 +vn 0.8496 -0.4370 0.2954 +vn -0.9209 -0.0050 -0.3896 +vn -0.9489 0.3081 -0.0687 +vn -0.9210 -0.0050 -0.3896 +vn -0.9469 0.3157 -0.0612 +vn -0.9363 -0.0331 -0.3497 +vn -0.9363 -0.0332 -0.3496 +vn -0.6358 -0.6597 -0.4007 +vn -0.9686 -0.1086 -0.2236 +vn -0.9795 -0.1375 -0.1470 +vn -0.6566 -0.7025 -0.2746 +vn -0.9686 -0.1085 -0.2235 +vn -0.9525 0.3017 -0.0422 +vn -0.9542 0.2983 -0.0210 +vn -0.9522 0.3052 -0.0108 +vn -0.9854 -0.1417 -0.0945 +vn -0.6698 -0.7202 -0.1808 +vn -0.9511 -0.0636 -0.3022 +vn -0.6050 -0.5877 -0.5372 +vn -0.9476 0.3139 -0.0590 +vn -0.9511 -0.0635 -0.3021 +vn -0.4182 -0.7122 -0.5639 +vn -0.4364 -0.7023 -0.5624 +vn -0.4567 -0.7835 -0.4213 +vn -0.4784 -0.7713 -0.4197 +vn 0.6028 0.5637 0.5646 +vn 0.5960 0.5759 0.5595 +vn 0.6591 0.6192 0.4268 +vn 0.6494 0.6331 0.4213 +vn -0.5176 -0.8344 -0.1895 +vn -0.4928 -0.8486 -0.1924 +vn -0.5008 -0.8613 -0.0856 +vn -0.5263 -0.8463 -0.0821 +vn -0.6774 -0.7310 -0.0815 +vn -0.6780 -0.7344 0.0312 +vn -0.5034 -0.8634 0.0350 +vn -0.5292 -0.8476 0.0383 +vn -0.4804 -0.8272 -0.2914 +vn -0.5044 -0.8137 -0.2888 +vn 0.6945 0.6547 0.2982 +vn 0.6826 0.6691 0.2940 +vn 0.7086 0.6385 0.3004 +vn 0.7278 0.6574 0.1952 +vn 0.7133 0.6739 0.1927 +vn 0.7001 0.6889 0.1878 +vn 0.8915 0.3617 0.2728 +vn 0.9292 -0.3522 0.1118 +vn 0.9371 -0.3412 0.0734 +vn 0.9075 0.3805 0.1777 +vn 0.7404 0.6709 -0.0419 +vn 0.9187 0.3933 -0.0346 +vn 0.9106 0.3866 -0.1463 +vn 0.7306 0.6628 -0.1642 +vn 0.9429 -0.3327 -0.0130 +vn 0.9391 -0.3387 -0.0590 +vn 0.9304 -0.3503 -0.1075 +vn 0.8910 0.3685 -0.2650 +vn 0.7075 0.6422 -0.2949 +vn 0.7241 0.6853 0.0778 +vn 0.7099 0.7006 0.0721 +vn 0.7390 0.6687 0.0816 +vn 0.7250 0.6872 -0.0464 +vn 0.7101 0.7022 -0.0527 +vn 0.9169 0.3918 0.0764 +vn 0.9428 -0.3318 0.0331 +vn -0.9890 -0.1413 -0.0446 +vn -0.9512 0.3085 -0.0070 +vn -0.9521 0.3058 -0.0003 +vn -0.9892 -0.1460 0.0137 +vn -0.5140 -0.8133 0.2725 +vn -0.4881 -0.8300 0.2700 +vn -0.4656 -0.7840 0.4105 +vn -0.4903 -0.7678 0.4124 +vn -0.6592 -0.7086 0.2518 +vn -0.6342 -0.6697 0.3863 +vn -0.5915 -0.5781 0.5621 +vn -0.4185 -0.6914 0.5889 +vn -0.4393 -0.6773 0.5901 +vn -0.9864 -0.1483 0.0713 +vn -0.6720 -0.7272 0.1401 +vn -0.9543 0.2987 0.0074 +vn -0.9864 -0.1484 0.0713 +vn -0.9579 0.2868 0.0160 +vn -0.9805 -0.1475 0.1300 +vn -0.9805 -0.1476 0.1300 +vn -0.4992 -0.8532 0.1508 +vn -0.5252 -0.8370 0.1537 +vn 0.7149 0.6784 -0.1694 +vn 0.6996 0.6927 -0.1756 +vn 0.6916 0.6569 -0.3003 +vn 0.6766 0.6700 -0.3054 +vn 0.5667 0.5573 -0.6068 +vn 0.5770 0.5469 -0.6066 +vn 0.4707 0.4439 -0.7625 +vn 0.4654 0.4527 -0.7606 +vn 0.5915 0.5337 -0.6044 +vn 0.4834 0.4308 -0.7621 +vn 0.3701 0.3228 -0.8711 +vn 0.3586 0.3352 -0.8712 +vn 0.3575 0.3414 -0.8693 +vn 0.6499 0.6173 -0.4434 +vn 0.6363 0.6290 -0.4467 +vn 0.6656 0.6035 -0.4391 +vn 0.6500 0.6173 -0.4434 +vn 0.8548 0.3328 -0.3981 +vn 0.9153 -0.3691 -0.1612 +vn 0.8897 -0.3943 -0.2304 +vn 0.7878 0.2682 -0.5544 +vn -0.9684 -0.1338 0.2103 +vn -0.9598 0.2783 0.0377 +vn -0.9685 -0.1338 0.2102 +vn -0.9524 0.2954 0.0759 +vn -0.9437 -0.0695 0.3234 +vn -0.9437 -0.0693 0.3234 +vn 0.5867 0.0763 -0.8062 +vn 0.4739 -0.0363 -0.8798 +vn 0.2424 0.2013 -0.9490 +vn 0.8104 -0.4765 -0.3408 +vn 0.7645 -0.5241 -0.3753 +vn 0.7052 -0.5894 -0.3941 +vn 0.3309 -0.1795 -0.9264 +vn 0.0856 0.0519 -0.9950 +vn 0.6887 0.1740 -0.7038 +vn 0.8504 -0.4334 -0.2982 +vn 0.8504 -0.4334 -0.2983 +vn -0.9069 0.0284 0.4205 +vn -0.5312 -0.4303 0.7298 +vn -0.9399 0.3265 0.0997 +vn -0.9384 0.3317 0.0973 +vn -0.8813 0.0880 0.4642 +vn -0.8814 0.0880 0.4642 +vn -0.4757 -0.2995 0.8271 +vn -0.4393 -0.6773 0.5902 +vn -0.3434 -0.5479 0.7628 +vn -0.3574 -0.5388 0.7628 +vn -0.2706 -0.4110 0.8706 +vn -0.2779 -0.4066 0.8703 +vn -0.0718 -0.0677 0.9951 +vn -0.0830 -0.0636 0.9945 +vn 0.0199 0.1252 0.9919 +vn 0.0413 0.1142 0.9926 +vn -0.3132 0.0337 0.9491 +vn -0.2264 0.2255 0.9476 +vn -0.1599 0.3813 0.9105 +vn 0.1056 0.2814 0.9538 +vn 0.1364 0.2651 0.9545 +vn -0.8551 0.1506 0.4962 +vn -0.4092 -0.1635 0.8977 +vn -0.9380 0.3309 0.1034 +vn -0.8551 0.1506 0.4961 +vn -0.9239 0.3627 0.1218 +vn -0.8005 0.2697 0.5352 +vn -0.8006 0.2697 0.5351 +vn -0.1912 -0.2630 0.9457 +vn -0.1906 -0.2618 0.9461 +vn 0.2323 0.2128 -0.9491 +vn 0.2357 0.2162 -0.9475 +vn 0.0779 0.0633 -0.9950 +vn 0.0863 0.0637 -0.9942 +vn -0.1932 -0.2150 -0.9573 +vn 0.0710 -0.4343 -0.8979 +vn -0.0415 -0.5464 -0.8365 +vn -0.3148 -0.3315 -0.8894 +vn 0.5993 -0.7027 -0.3835 +vn 0.5516 -0.7523 -0.3603 +vn 0.5050 -0.8010 -0.3215 +vn -0.1485 -0.6534 -0.7423 +vn -0.4300 -0.4419 -0.7873 +vn -0.0698 -0.0796 -0.9944 +vn -0.0574 -0.0822 -0.9950 +vn -0.0636 -0.0907 -0.9938 +vn -0.1988 -0.2044 -0.9585 +vn -0.1840 -0.2102 -0.9602 +vn 0.1915 -0.3167 -0.9290 +vn 0.6494 -0.6511 -0.3928 +vn -0.7464 0.3922 0.5376 +vn -0.9077 0.4011 0.1237 +vn -0.9008 0.4194 0.1126 +vn -0.7135 0.4799 0.5105 +vn -0.2422 -0.7472 -0.6189 +vn -0.5293 -0.5372 -0.6568 +vn 0.4634 -0.8444 -0.2687 +vn 0.4307 -0.8775 -0.2110 +vn -0.3121 -0.8168 -0.4852 +vn -0.6032 -0.6084 -0.5158 +vn -0.6845 0.5539 0.4740 +vn -0.0971 0.5209 0.8481 +vn -0.8967 0.4306 0.1028 +vn -0.8902 0.4466 0.0895 +vn -0.6546 0.6299 0.4180 +vn -0.0350 0.6562 0.7538 +vn 0.1847 0.4238 0.8867 +vn 0.2241 0.4029 0.8874 +vn 0.2605 0.5594 0.7869 +vn 0.3083 0.5346 0.7869 +vn -0.3207 -0.3221 -0.8908 +vn -0.3046 -0.3309 -0.8932 +vn -0.4356 -0.4326 -0.7894 +vn -0.4188 -0.4439 -0.7922 +vn 0.4424 0.7439 0.5008 +vn 0.3815 0.7777 0.4996 +vn 0.4102 0.8287 0.3808 +vn 0.4747 0.7928 0.3824 +vn 0.0603 0.8786 0.4737 +vn 0.0799 0.9294 0.3602 +vn 0.0921 0.9503 0.2975 +vn 0.4245 0.8522 0.3058 +vn 0.4908 0.8159 0.3057 +vn -0.6277 0.7018 0.3368 +vn 0.0205 0.7833 0.6213 +vn -0.8845 0.4618 0.0664 +vn -0.8837 0.4663 0.0391 +vn -0.6096 0.7530 0.2478 +vn -0.6097 0.7529 0.2478 +vn 0.3298 0.6845 0.6501 +vn 0.3852 0.6550 0.6501 +vn -0.5348 -0.5280 -0.6597 +vn -0.5182 -0.5412 -0.6623 +vn -0.6093 -0.5994 -0.5191 +vn -0.5929 -0.6136 -0.5215 +vn -0.6767 -0.6790 -0.2847 +vn -0.3812 -0.8826 -0.2753 +vn -0.4035 -0.9036 -0.1439 +vn -0.6999 -0.7005 -0.1396 +vn 0.4050 -0.9056 -0.1261 +vn 0.3983 -0.9143 -0.0739 +vn 0.4020 -0.9152 0.0290 +vn -0.4081 -0.9085 0.0905 +vn -0.7035 -0.7025 0.1079 +vn -0.6566 -0.6446 -0.3917 +vn -0.6404 -0.6592 -0.3942 +vn -0.6495 -0.6532 -0.3892 +vn -0.6842 -0.6712 -0.2854 +vn -0.6684 -0.6860 -0.2875 +vn -0.3560 -0.8592 -0.3675 +vn 0.4117 -0.8969 -0.1617 +vn -0.6016 0.7766 0.1871 +vn -0.8874 0.4604 0.0246 +vn -0.6015 0.7766 0.1871 +vn -0.8875 0.4594 0.0357 +vn -0.5938 0.7862 0.1713 +vn -0.5938 0.7861 0.1713 +vn 0.1487 0.9884 0.0323 +vn -0.5422 0.8375 0.0681 +vn -0.5533 0.8107 -0.1917 +vn 0.1333 0.9067 -0.4001 +vn -0.8471 0.5294 0.0464 +vn -0.8365 0.5461 -0.0460 +vn -0.5533 0.8106 -0.1916 +vn -0.8598 0.4849 -0.1600 +vn -0.6055 0.6296 -0.4868 +vn 0.1333 0.9067 -0.4002 +vn 0.0160 0.6068 -0.7947 +vn -0.5723 0.8044 0.1591 +vn 0.1159 0.9672 0.2262 +vn -0.8738 0.4829 0.0576 +vn -0.5722 0.8045 0.1592 +vn 0.4386 0.8721 0.2169 +vn 0.5050 0.8361 0.2144 +vn 0.4537 0.8911 0.0064 +vn 0.5185 0.8551 0.0043 +vn -0.7072 -0.6933 -0.1384 +vn -0.6915 -0.7085 -0.1406 +vn -0.7098 -0.6959 0.1093 +vn -0.6944 -0.7116 0.1067 +vn 0.3057 0.5031 -0.8083 +vn 0.2623 0.5212 -0.8121 +vn 0.1272 0.2747 -0.9531 +vn 0.1588 0.2632 -0.9516 +vn -0.1120 0.3542 -0.9285 +vn -0.2011 0.2037 -0.9582 +vn 0.0378 0.1128 -0.9929 +vn 0.0619 0.1043 -0.9926 +vn 0.4134 0.8049 -0.4257 +vn 0.4711 0.7742 -0.4228 +vn 0.4711 0.7741 -0.4228 +vn -0.6410 -0.6302 0.4381 +vn -0.6270 -0.6463 0.4349 +vn -0.6351 -0.6358 0.4387 +vn -0.4615 -0.4700 0.7524 +vn -0.4698 -0.4663 0.7496 +vn -0.4590 -0.4806 0.7472 +vn -0.3424 -0.8449 0.4111 +vn 0.4342 -0.8845 0.1705 +vn 0.5116 -0.8061 0.2973 +vn -0.1748 -0.6807 0.7114 +vn -0.3424 -0.8448 0.4111 +vn -0.1748 -0.6806 0.7114 +vn -0.0848 -0.1145 0.9898 +vn 0.1767 -0.3364 0.9250 +vn 0.3382 -0.1806 0.9236 +vn 0.0934 0.0550 0.9941 +vn 0.6515 -0.6601 0.3739 +vn 0.7095 -0.5959 0.3762 +vn 0.3382 -0.1805 0.9236 +vn 0.7095 -0.5959 0.3761 +vn 0.7834 -0.5167 0.3454 +vn 0.5294 0.0053 0.8484 +vn 0.5293 0.0053 0.8484 +vn 0.3032 0.2547 0.9183 +vn -0.2660 -0.2713 0.9250 +vn -0.2587 -0.2825 0.9237 +vn -0.2557 -0.2752 0.9268 +vn -0.0946 -0.1075 0.9897 +vn -0.0883 -0.1139 0.9896 +vn 0.0210 -0.4883 0.8724 +vn 0.5960 -0.7219 0.3516 +vn -0.6789 0.4482 -0.5816 +vn -0.8932 0.4081 -0.1889 +vn -0.9070 0.3876 -0.1646 +vn -0.7317 0.3667 -0.5747 +vn -0.7316 0.3667 -0.5747 +vn -0.1980 -0.3230 -0.9255 +vn -0.1972 -0.3258 -0.9247 +vn -0.3283 -0.5684 -0.7544 +vn -0.3419 -0.5604 -0.7543 +vn -0.3927 -0.2273 -0.8911 +vn -0.5059 -0.4701 -0.7233 +vn -0.5799 -0.6185 -0.5303 +vn -0.4121 -0.7231 -0.5543 +vn -0.4333 -0.7115 -0.5532 +vn -0.7726 0.2806 -0.5695 +vn -0.2813 0.0286 -0.9592 +vn -0.9128 0.3755 -0.1606 +vn -0.7726 0.2806 -0.5694 +vn -0.9336 0.3243 -0.1523 +vn -0.8402 0.1227 -0.5282 +vn -0.8402 0.1227 -0.5283 +vn -0.0608 -0.0714 -0.9956 +vn -0.0472 -0.0751 -0.9961 +vn -0.1972 -0.3257 -0.9247 +vn 0.0851 0.0649 0.9943 +vn 0.0908 0.0649 0.9938 +vn 0.2948 0.2667 0.9176 +vn 0.2972 0.2727 0.9150 +vn 0.6053 0.5872 0.5374 +vn 0.6122 0.5738 0.5440 +vn 0.6993 0.6587 0.2777 +vn 0.6884 0.6730 0.2704 +vn 0.6230 0.5592 0.5471 +vn 0.7110 0.6438 0.2829 +vn 0.7389 0.6728 -0.0361 +vn 0.7265 0.6859 -0.0424 +vn 0.7132 0.6993 -0.0483 +vn 0.4819 0.4475 0.7534 +vn 0.4795 0.4580 0.7486 +vn 0.4918 0.4343 0.7547 +vn 0.4819 0.4474 0.7534 +vn 0.4918 0.4342 0.7547 +vn 0.6992 0.1736 0.6935 +vn 0.8499 -0.4478 0.2779 +vn 0.8938 -0.3998 0.2034 +vn 0.8140 0.2902 0.5032 +vn -0.8401 0.1227 -0.5283 +vn -0.9061 -0.0370 -0.4214 +vn -0.9555 0.2717 -0.1145 +vn -0.9639 0.2537 -0.0813 +vn -0.9434 -0.1217 -0.3085 +vn 0.9173 0.3975 -0.0248 +vn 0.8726 0.3580 -0.3322 +vn 0.6868 0.6258 -0.3697 +vn 0.9325 -0.3611 -0.0052 +vn 0.9143 -0.3861 -0.1225 +vn 0.8624 -0.4387 -0.2527 +vn 0.7242 0.2180 -0.6543 +vn 0.8726 0.3581 -0.3322 +vn 0.7241 0.2181 -0.6543 +vn 0.5218 0.4711 -0.7112 +vn 0.8910 0.3690 0.2646 +vn 0.9245 -0.3648 0.1110 +vn -0.9641 -0.1733 -0.2014 +vn -0.6218 -0.7155 -0.3185 +vn -0.9689 0.2390 -0.0649 +vn -0.9641 -0.1732 -0.2014 +vn -0.9785 0.2032 -0.0357 +vn -0.9709 -0.2309 -0.0634 +vn -0.9709 -0.2308 -0.0634 +vn -0.6300 -0.7746 -0.0554 +vn -0.4646 -0.8224 -0.3284 +vn -0.4913 -0.8069 -0.3280 +vn -0.4892 -0.8707 -0.0503 +vn -0.5202 -0.8525 -0.0511 +vn -0.4166 -0.6769 0.6069 +vn -0.3897 -0.6918 0.6079 +vn -0.1683 -0.2824 0.9444 +vn -0.1732 -0.2761 0.9454 +vn -0.5121 -0.6233 0.5910 +vn -0.3191 -0.2087 0.9245 +vn -0.0822 0.3082 0.9478 +vn 0.1065 0.2252 0.9685 +vn 0.1289 0.2173 0.9676 +vn -0.9566 -0.2646 0.1221 +vn -0.5970 -0.7666 0.2365 +vn -0.9855 0.1669 0.0317 +vn -0.9566 -0.2647 0.1221 +vn -0.9715 0.1886 0.1435 +vn -0.9117 -0.1760 0.3712 +vn -0.9117 -0.1761 0.3712 +vn -0.5121 -0.6232 0.5911 +vn -0.4733 -0.8450 0.2491 +vn -0.5059 -0.8265 0.2469 +vn 0.6743 0.6364 -0.3746 +vn 0.6622 0.6478 -0.3766 +vn 0.6743 0.6364 -0.3745 +vn 0.5119 0.4800 -0.7124 +vn 0.6622 0.6478 -0.3767 +vn 0.5063 0.4887 -0.7105 +vn -0.1160 -0.1339 -0.9842 +vn 0.1350 -0.3539 -0.9255 +vn -0.1408 -0.6237 -0.7689 +vn -0.4109 -0.4141 -0.8122 +vn 0.1351 -0.3539 -0.9255 +vn 0.6359 -0.6757 -0.3730 +vn 0.5298 -0.7897 -0.3094 +vn 0.4577 -0.8666 -0.1986 +vn -0.3267 -0.8065 -0.4928 +vn -0.6089 -0.6016 -0.5171 +vn 0.2234 0.2022 -0.9535 +vn 0.2275 0.2063 -0.9517 +vn 0.2286 0.1936 -0.9541 +vn -0.1192 -0.1266 -0.9848 +vn -0.1085 -0.1299 -0.9856 +vn 0.4557 -0.0415 -0.8892 +vn 0.7609 -0.5455 -0.3513 +vn 0.6358 -0.6757 -0.3730 +vn -0.7963 0.1207 0.5928 +vn -0.9228 0.3033 0.2376 +vn -0.7963 0.1207 0.5927 +vn -0.8635 0.4438 0.2395 +vn -0.6382 0.4686 0.6108 +vn -0.4134 -0.8967 -0.1582 +vn -0.7044 -0.6908 -0.1629 +vn 0.4299 -0.8995 -0.0783 +vn 0.4951 -0.8372 0.2325 +vn -0.3288 -0.8977 0.2934 +vn -0.6947 -0.6847 0.2205 +vn -0.0821 0.3081 0.9478 +vn -0.6381 0.4686 0.6109 +vn -0.5516 0.6700 0.4968 +vn 0.0550 0.6305 0.7742 +vn -0.8329 0.5205 0.1879 +vn -0.8185 0.5536 0.1536 +vn -0.5150 0.7721 0.3725 +vn -0.5149 0.7721 0.3725 +vn 0.1356 0.8242 0.5498 +vn 0.2780 0.5444 0.7914 +vn 0.3180 0.5256 0.7891 +vn 0.3840 0.7421 0.5494 +vn 0.3181 0.5256 0.7890 +vn 0.4354 0.7167 0.5447 +vn -0.4145 -0.4084 -0.8132 +vn -0.4019 -0.4188 -0.8143 +vn -0.6136 -0.5971 -0.5166 +vn -0.6005 -0.6109 -0.5160 +vn 0.5050 0.8244 -0.2556 +vn 0.4540 0.8512 -0.2633 +vn 0.3559 0.6915 -0.6287 +vn 0.4124 0.6807 -0.6054 +vn 0.2085 0.9191 -0.3342 +vn 0.0375 0.6603 -0.7501 +vn 0.0775 0.8476 -0.5249 +vn 0.4096 0.8292 -0.3804 +vn 0.4815 0.8016 -0.3543 +vn -0.4666 0.8749 0.1298 +vn 0.2162 0.9556 0.2002 +vn -0.8073 0.5887 0.0413 +vn -0.8403 0.4862 -0.2396 +vn -0.5115 0.7556 -0.4092 +vn 0.2085 0.9191 -0.3343 +vn 0.4575 0.8659 0.2021 +vn 0.5107 0.8359 0.2011 +vn 0.5051 0.8244 -0.2556 +vn -0.7088 -0.6864 -0.1627 +vn -0.6953 -0.7003 -0.1619 +vn -0.7021 -0.6790 0.2147 +vn -0.6892 -0.6923 0.2138 +vn -0.5691 -0.7915 -0.2226 +vn -0.5205 -0.8226 -0.2289 +vn -0.5102 -0.7982 -0.3204 +vn -0.5575 -0.7681 -0.3150 +vn -0.5079 -0.8279 -0.2381 +vn -0.4975 -0.8033 -0.3275 +vn -0.4828 -0.7751 -0.4075 +vn -0.4953 -0.7696 -0.4029 +vn -0.5412 -0.7398 -0.3997 +vn -0.5974 -0.5788 0.5551 +vn -0.5861 -0.5904 0.5549 +vn -0.5577 -0.5662 0.6070 +vn -0.3802 -0.3800 0.8432 +vn -0.3872 -0.3823 0.8390 +vn -0.3846 -0.3924 0.8356 +vn -0.0253 -0.4570 0.8891 +vn -0.3287 -0.8977 0.2934 +vn 0.6111 -0.3397 0.7150 +vn 0.5455 0.3478 0.7625 +vn 0.0778 -0.0344 0.9964 +vn -0.6413 0.4506 -0.6210 +vn -0.8838 0.3608 -0.2979 +vn -0.6414 0.4505 -0.6210 +vn -0.5522 0.7783 0.2987 +vn -0.3982 0.9132 -0.0860 +vn -0.3983 0.9132 -0.0860 +vn 0.9807 -0.1844 0.0651 +vn 0.9143 0.3812 -0.1368 +vn 0.8376 0.5423 0.0657 +vn 0.9037 0.1573 0.3982 +vn 0.9143 0.3812 -0.1367 +vn 0.7038 0.6427 -0.3026 +vn 0.6136 0.5488 -0.5678 +vn 0.8376 0.5423 0.0658 +vn 0.6547 0.6083 -0.4488 +vn 0.7534 0.6544 0.0641 +vn 0.7534 0.6544 0.0643 +vn 0.5826 0.4555 0.6731 +vn 0.1760 0.1420 0.9741 +vn 0.1666 0.1540 0.9739 +vn 0.0778 -0.0343 0.9964 +vn 0.5445 0.4942 0.6777 +vn 0.5374 0.5280 0.6576 +vn 0.5652 0.5591 0.6066 +vn 0.5701 0.5305 0.6274 +vn 0.6939 0.6496 0.3108 +vn 0.6818 0.6730 0.2867 +vn 0.6546 0.6082 -0.4490 +vn 0.6417 0.6103 -0.4645 +vn 0.6358 0.6275 -0.4494 +vn 0.9212 -0.2496 0.2984 +vn 0.7842 0.3373 0.5208 +vn 0.8766 0.4446 0.1841 +vn 0.9772 -0.1905 0.0936 +vn 0.6145 0.5652 0.5504 +vn 0.7204 0.6650 0.1972 +vn 0.7038 0.6427 -0.3025 +vn 0.7232 -0.4610 0.5143 +vn 0.3955 -0.0284 0.9180 +vn 0.6384 0.2038 0.7423 +vn 0.8504 -0.3214 0.4165 +vn 0.1899 0.1685 0.9672 +vn 0.4532 0.4149 0.7890 +vn -0.8598 0.5048 -0.0775 +vn -0.9847 -0.1514 0.0860 +vn -0.9522 0.0052 0.3053 +vn -0.8753 0.4828 -0.0268 +vn -0.6083 -0.7669 0.2045 +vn -0.5948 -0.6007 0.5343 +vn -0.5948 -0.6007 0.5342 +vn -0.4957 -0.3863 0.7779 +vn -0.6012 0.3271 0.7291 +vn -0.5270 0.7367 0.4238 +vn 0.3355 -0.8757 0.3473 +vn -0.3224 -0.7257 0.6078 +vn 0.0077 -0.4093 0.9124 +vn 0.5204 -0.6845 0.5105 +vn -0.5626 -0.5424 0.6240 +vn -0.2254 -0.2227 0.9485 +vn 0.7232 -0.4611 0.5142 +vn -0.8948 0.4082 0.1809 +vn -0.8141 0.2312 -0.5328 +vn -0.9022 0.0367 -0.4297 +vn -0.8706 0.4709 0.1422 +vn -0.2618 -0.0752 -0.9622 +vn -0.4339 -0.4319 -0.7907 +vn -0.9022 0.0368 -0.4297 +vn -0.9023 0.0368 -0.4296 +vn -0.4339 -0.4320 -0.7907 +vn -0.5475 -0.6692 -0.5024 +vn -0.9579 -0.0897 -0.2729 +vn -0.9579 -0.0898 -0.2729 +vn -0.8527 0.5140 0.0928 +vn -0.9844 -0.1466 -0.0974 +vn -0.8405 0.5415 0.0191 +vn -0.5988 -0.7846 -0.1605 +vn -0.9844 -0.1465 -0.0974 +vn 0.2830 -0.9585 -0.0342 +vn -0.4551 -0.8896 -0.0386 +vn -0.4460 -0.8564 0.2602 +vn 0.2640 -0.9546 0.1377 +vn -0.7178 -0.6955 -0.0323 +vn -0.6925 -0.6683 0.2717 +vn -0.5626 -0.5424 0.6239 +vn -0.3224 -0.7257 0.6077 +vn 0.3616 -0.8910 -0.2745 +vn -0.3241 -0.7800 -0.5353 +vn -0.4060 -0.8582 -0.3141 +vn 0.3238 -0.9309 -0.1691 +vn -0.5924 -0.5798 -0.5593 +vn -0.6783 -0.6604 -0.3221 +vn -0.9625 0.2710 0.0114 +vn -0.6009 0.7993 -0.0079 +vn -0.6046 0.7754 -0.1825 +vn -0.9660 0.2510 0.0624 +vn -0.6009 0.7993 -0.0080 +vn 0.1606 0.9865 -0.0313 +vn 0.1563 0.9201 -0.3591 +vn -0.6046 0.7753 -0.1825 +vn 0.0860 0.7126 -0.6963 +vn -0.6333 0.6753 -0.3781 +vn -0.6332 0.6753 -0.3780 +vn -0.9552 0.2658 0.1300 +vn -0.7138 0.4723 -0.5172 +vn -0.9275 0.3269 0.1816 +vn -0.6333 0.6753 -0.3780 +vn -0.0669 0.3481 -0.9351 +vn -0.7137 0.4723 -0.5173 +vn 0.5267 -0.7185 -0.4543 +vn -0.0085 -0.4685 -0.8834 +vn -0.2017 -0.6570 -0.7264 +vn 0.4227 -0.8262 -0.3723 +vn -0.2619 -0.2662 -0.9277 +vn -0.4615 -0.4554 -0.7614 +vn -0.9491 0.3111 -0.0491 +vn -0.6432 0.7151 0.2738 +vn -0.6139 0.7749 0.1504 +vn -0.9550 0.2958 -0.0223 +vn -0.6432 0.7150 0.2738 +vn 0.0750 0.8440 0.5311 +vn 0.1290 0.9520 0.2777 +vn 0.6827 -0.5432 -0.4886 +vn 0.3262 -0.1428 -0.9344 +vn 0.1907 -0.2770 -0.9418 +vn 0.6251 -0.6109 -0.4859 +vn 0.0980 0.0747 -0.9924 +vn -0.0537 -0.0695 -0.9961 +vn 0.8455 -0.3611 -0.3933 +vn 0.6287 0.1768 -0.7573 +vn 0.4385 -0.0150 -0.8986 +vn 0.7362 -0.4717 -0.4853 +vn 0.4337 0.3984 -0.8082 +vn 0.2306 0.2028 -0.9517 +vn -0.9134 0.3960 -0.0942 +vn -0.8282 0.2721 0.4899 +vn -0.7834 0.3765 0.4946 +vn -0.9236 0.3718 -0.0929 +vn -0.8282 0.2721 0.4900 +vn -0.3085 -0.0149 0.9511 +vn -0.2154 0.1994 0.9560 +vn -0.0991 0.4535 0.8857 +vn -0.7251 0.5115 0.4611 +vn -0.9342 0.3446 -0.0924 +vn -0.6767 0.6337 0.3748 +vn -0.9435 0.3228 -0.0750 +vn 0.0044 0.6832 0.7302 +vn -0.6767 0.6337 0.3749 +vn -0.8798 0.4642 -0.1019 +vn -0.9197 0.0193 0.3922 +vn -0.8677 0.1678 0.4680 +vn -0.8985 0.4255 -0.1081 +vn -0.9196 0.0192 0.3923 +vn -0.4911 -0.4800 0.7269 +vn -0.3884 -0.2241 0.8938 +vn -0.8676 0.1678 0.4680 +vn 0.9447 -0.2978 0.1372 +vn 0.8819 0.3772 0.2829 +vn 0.8929 0.3989 0.2088 +vn 0.9539 -0.2770 0.1152 +vn 0.6994 0.6452 0.3075 +vn 0.7161 0.6626 0.2195 +vn 0.7327 0.6805 0.0123 +vn 0.9052 0.4243 0.0220 +vn 0.9682 -0.2482 0.0296 +vn 0.8483 0.3730 -0.3759 +vn 0.9481 -0.2686 -0.1702 +vn 0.6656 0.6186 -0.4174 +vn 0.9240 -0.3202 0.2090 +vn 0.8284 0.3290 0.4533 +vn 0.8659 0.3613 0.3458 +vn 0.9386 -0.3072 0.1573 +vn 0.6385 0.5877 0.4970 +vn 0.6800 0.6265 0.3809 +vn -0.9131 0.4077 0.0006 +vn -0.9843 -0.0966 -0.1479 +vn -0.9888 -0.1182 -0.0912 +vn -0.9026 0.4304 -0.0077 +vn -0.6492 -0.7103 -0.2720 +vn -0.6535 -0.7437 -0.1406 +vn -0.9888 -0.1183 -0.0912 +vn -0.6430 -0.7599 0.0957 +vn -0.9905 -0.1331 0.0336 +vn -0.8853 0.4644 -0.0236 +vn -0.9707 -0.1003 0.2184 +vn -0.8732 0.4834 -0.0621 +vn -0.5912 -0.6888 0.4196 +vn -0.9707 -0.1003 0.2183 +vn 0.8501 -0.3921 0.3517 +vn 0.6637 0.1742 0.7274 +vn 0.7592 0.2648 0.5945 +vn 0.8939 -0.3487 0.2818 +vn 0.4578 0.4174 0.7850 +vn 0.5625 0.5162 0.6459 +vn 0.7545 -0.4880 0.4388 +vn 0.4537 -0.0274 0.8907 +vn 0.5595 0.0741 0.8255 +vn 0.8021 -0.4403 0.4034 +vn 0.2268 0.1984 0.9535 +vn 0.3433 0.3088 0.8870 +vn -0.9121 0.4093 0.0223 +vn -0.9681 -0.0553 -0.2443 +vn -0.9792 -0.0828 -0.1854 +vn -0.9151 0.4032 0.0111 +vn -0.9682 -0.0552 -0.2442 +vn -0.6122 -0.6249 -0.4844 +vn -0.6380 -0.6781 -0.3649 +vn 0.6248 -0.6262 0.4664 +vn 0.1890 -0.2809 0.9409 +vn 0.3353 -0.1380 0.9319 +vn 0.6987 -0.5438 0.4649 +vn -0.0529 -0.0665 0.9964 +vn 0.1003 0.0788 0.9918 +vn 0.3353 -0.1380 0.9320 +vn -0.9162 0.3971 0.0538 +vn -0.8621 0.2025 -0.4646 +vn -0.8927 0.1284 -0.4319 +vn -0.9132 0.4049 0.0469 +vn -0.3813 -0.1410 -0.9136 +vn -0.4496 -0.2852 -0.8465 +vn -0.8927 0.1284 -0.4320 +vn -0.5136 -0.4213 -0.7475 +vn -0.9224 0.0561 -0.3821 +vn -0.9225 0.0562 -0.3820 +vn -0.9104 0.4116 0.0414 +vn -0.9488 -0.0073 -0.3157 +vn -0.9096 0.4142 0.0332 +vn -0.5695 -0.5388 -0.6208 +vn -0.9488 -0.0073 -0.3156 +vn 0.5009 -0.7613 0.4116 +vn -0.0775 -0.5540 0.8289 +vn 0.0359 -0.4385 0.8980 +vn 0.5497 -0.7107 0.4390 +vn -0.3459 -0.3459 0.8722 +vn -0.2175 -0.2235 0.9501 +vn 0.3942 -0.8719 0.2904 +vn -0.3050 -0.7637 0.5690 +vn -0.1871 -0.6559 0.7313 +vn 0.4578 -0.8082 0.3704 +vn -0.5765 -0.5642 0.5910 +vn -0.4623 -0.4559 0.7605 +vn -0.9310 0.3629 0.0404 +vn -0.7133 0.5556 -0.4272 +vn -0.7430 0.4810 -0.4654 +vn -0.9273 0.3710 0.0505 +vn -0.0710 0.5398 -0.8388 +vn -0.1395 0.3868 -0.9115 +vn -0.2252 0.1963 -0.9543 +vn -0.7867 0.3794 -0.4870 +vn -0.9234 0.3790 0.0616 +vn -0.8292 0.2827 -0.4821 +vn -0.9194 0.3885 0.0621 +vn -0.3084 0.0141 -0.9512 +vn 0.3416 -0.9316 0.1238 +vn -0.4077 -0.8749 0.2615 +vn -0.3768 -0.8363 0.3984 +vn 0.3509 -0.9156 0.1965 +vn -0.6876 -0.6707 0.2781 +vn -0.6496 -0.6340 0.4195 +vn -0.3050 -0.7637 0.5689 +vn -0.9395 0.3407 0.0358 +vn -0.6559 0.6945 -0.2957 +vn -0.6838 0.6238 -0.3785 +vn -0.9355 0.3512 0.0378 +vn -0.6558 0.6946 -0.2958 +vn 0.0497 0.8108 -0.5832 +vn -0.0088 0.6773 -0.7356 +vn 0.3437 -0.9390 0.0144 +vn -0.4284 -0.9029 0.0335 +vn -0.4230 -0.8945 0.1449 +vn 0.3412 -0.9375 0.0678 +vn -0.7157 -0.6973 0.0383 +vn -0.7074 -0.6896 0.1551 +vn 0.3471 -0.9338 -0.0875 +vn -0.4160 -0.8904 -0.1850 +vn -0.4249 -0.9016 -0.0814 +vn 0.3479 -0.9367 -0.0396 +vn -0.7030 -0.6844 -0.1935 +vn -0.7139 -0.6953 -0.0830 +vn -0.9309 0.3651 0.0036 +vn -0.6189 0.7853 -0.0159 +vn -0.6220 0.7795 -0.0740 +vn -0.9331 0.3595 0.0084 +vn -0.6190 0.7853 -0.0159 +vn 0.1169 0.9924 -0.0373 +vn 0.1141 0.9812 -0.1555 +vn 0.1067 0.9536 -0.2817 +vn -0.6280 0.7663 -0.1358 +vn -0.6280 0.7662 -0.1358 +vn -0.9365 0.3503 0.0161 +vn -0.6392 0.7408 -0.2066 +vn -0.9397 0.3409 0.0270 +vn 0.0881 0.9024 -0.4217 +vn -0.6392 0.7407 -0.2066 +vn -0.9310 0.3650 -0.0066 +vn -0.6240 0.7759 0.0927 +vn -0.6181 0.7850 0.0418 +vn -0.9299 0.3679 -0.0010 +vn -0.6240 0.7759 0.0926 +vn 0.1086 0.9760 0.1890 +vn 0.1152 0.9900 0.0809 +vn -0.6182 0.7849 0.0418 +vn 0.4235 -0.8498 -0.3139 +vn -0.2491 -0.7258 -0.6412 +vn -0.3071 -0.7814 -0.5432 +vn 0.4018 -0.8752 -0.2692 +vn -0.5301 -0.5177 -0.6715 +vn -0.5912 -0.5761 -0.5644 +vn -0.6494 -0.6317 -0.4233 +vn -0.3665 -0.8364 -0.4075 +vn 0.3712 -0.9064 -0.2017 +vn -0.4018 -0.8713 -0.2818 +vn 0.3500 -0.9268 -0.1359 +vn -0.6849 -0.6662 -0.2950 +vn 0.4969 -0.7681 -0.4040 +vn -0.0855 -0.5563 -0.8266 +vn -0.1904 -0.6635 -0.7236 +vn 0.4462 -0.8229 -0.3517 +vn -0.3506 -0.3452 -0.8706 +vn -0.4630 -0.4534 -0.7616 +vn -0.9310 0.3643 -0.0218 +vn -0.6689 0.6666 0.3291 +vn -0.6524 0.7041 0.2805 +vn -0.9333 0.3586 -0.0171 +vn -0.6689 0.6666 0.3290 +vn 0.0140 0.7583 0.6518 +vn 0.0478 0.8352 0.5479 +vn 0.0794 0.9064 0.4149 +vn -0.6378 0.7411 0.2096 +vn -0.9347 0.3552 -0.0155 +vn -0.6306 0.7630 0.1418 +vn -0.9333 0.3588 -0.0122 +vn 0.0986 0.9520 0.2899 +vn -0.6306 0.7631 0.1419 +vn 0.6653 -0.5862 -0.4623 +vn 0.2573 -0.2182 -0.9414 +vn 0.0883 -0.3865 -0.9180 +vn 0.5829 -0.6780 -0.4477 +vn 0.0109 -0.0020 -0.9999 +vn -0.1692 -0.1726 -0.9704 +vn 0.5830 -0.6780 -0.4478 +vn 0.0883 -0.3865 -0.9181 +vn -0.9099 0.4149 -0.0017 +vn -0.9265 0.3762 0.0066 +vn -0.8692 0.2178 0.4439 +vn -0.8384 0.2585 0.4798 +vn -0.9944 -0.0408 -0.0978 +vn -0.8926 -0.1816 0.4126 +vn -0.4514 -0.1878 0.8723 +vn -0.4113 -0.1060 0.9053 +vn -0.3645 -0.0630 0.9291 +vn -0.3385 -0.3553 -0.8713 +vn -0.3391 -0.3280 -0.8817 +vn -0.3385 -0.3552 -0.8713 +vn -0.6311 -0.6625 -0.4035 +vn -0.6423 -0.6511 -0.4043 +vn -0.6855 0.6249 0.3736 +vn -0.9304 0.3650 -0.0342 +vn -0.0249 0.6673 0.7444 +vn -0.6854 0.6249 0.3736 +vn 0.3640 -0.1169 -0.9241 +vn 0.7259 -0.5244 -0.4450 +vn 0.1204 0.1010 -0.9876 +vn -0.7371 0.4323 -0.5194 +vn -0.9001 0.4260 -0.0917 +vn -0.7372 0.4322 -0.5194 +vn -0.6811 -0.6947 -0.2313 +vn -0.6709 -0.7045 -0.2315 +vn -0.6283 -0.6548 0.4200 +vn -0.6217 -0.6531 0.4323 +vn -0.6217 -0.6531 0.4324 +vn -0.8802 0.4543 -0.1372 +vn -0.8467 0.5131 -0.1412 +vn -0.5273 0.7648 0.3703 +vn 0.8161 0.0040 0.5779 +vn 0.8947 -0.4251 0.1369 +vn 0.5748 0.4293 0.6966 +vn 0.4951 -0.8372 0.2324 +vn 0.4039 0.6808 0.6110 +vn 0.2557 0.7330 0.6303 +vn 0.2133 0.7376 0.6406 +vn 0.3981 0.6742 0.6220 +vn -0.5522 0.7784 0.2987 +vn -0.5273 0.7647 0.3704 +vn -0.5269 0.7367 0.4238 +vn 0.1655 0.7219 0.6719 +vn 0.3803 0.6479 0.6600 +vn -0.8202 0.5713 0.0298 +vn -0.8329 0.5396 0.1228 +vn -0.8512 0.4963 0.1707 +vn -0.8799 0.4226 0.2174 +vn 0.8674 -0.4966 0.0299 +vn 0.8444 -0.5214 0.1231 +vn 0.4300 -0.8994 -0.0783 +vn 0.4576 -0.8667 -0.1986 +vn -0.9247 0.3128 0.2170 +vn -0.9630 0.2268 0.1458 +vn 0.6779 -0.7019 0.2186 +vn 0.6161 -0.7739 0.1467 +vn 0.7585 -0.6139 0.2187 +vn 0.8130 -0.5564 0.1714 +vn 0.5297 -0.7897 -0.3094 +vn -0.9768 0.2069 0.0554 +vn -0.9725 0.2330 -0.0069 +vn -0.9638 0.2632 -0.0426 +vn -0.9577 0.2799 -0.0674 +vn 0.3617 -0.8910 -0.2746 +vn 0.6503 -0.7585 -0.0426 +vn 0.6629 -0.7457 -0.0673 +vn 0.6265 -0.7794 -0.0070 +vn 0.6044 -0.7947 0.0556 +vn -0.9502 0.2956 -0.0984 +vn -0.9347 0.3324 -0.1262 +vn 0.6738 -0.7323 -0.0985 +vn 0.7004 -0.7025 -0.1263 +vn -0.9188 0.3725 -0.1305 +vn -0.9098 0.3933 -0.1328 +vn -0.8944 0.4210 -0.1511 +vn -0.8674 0.4791 -0.1344 +vn 0.7362 -0.4717 -0.4854 +vn 0.7633 -0.6281 -0.1514 +vn 0.8044 -0.5786 -0.1349 +vn 0.7448 -0.6539 -0.1329 +vn 0.7299 -0.6709 -0.1305 +vn 0.8339 -0.5484 -0.0616 +vn 0.8233 -0.5676 0.0038 +vn 0.4342 -0.8845 0.1704 +vn -0.8878 0.4597 0.0215 +vn -0.9001 0.4352 0.0177 +vn -0.8657 0.5006 0.0039 +vn -0.8529 0.5184 -0.0612 +vn -0.9012 0.4331 0.0189 +vn -0.8978 0.4392 0.0325 +vn 0.7770 -0.6292 0.0187 +vn 0.7813 -0.6233 0.0326 +vn 0.7786 -0.6273 0.0177 +vn 0.7955 -0.6055 0.0215 +vn -0.8969 0.4392 0.0516 +vn -0.9000 0.4306 0.0673 +vn -0.9049 0.4187 0.0769 +vn -0.9088 0.4084 0.0855 +vn 0.7810 -0.6224 0.0518 +vn 0.7744 -0.6291 0.0675 +vn 0.4634 -0.8444 -0.2686 +vn -0.9139 0.3946 0.0951 +vn -0.9237 0.3712 0.0946 +vn 0.7478 -0.6570 0.0956 +vn 0.7308 -0.6759 0.0952 +vn 0.7582 -0.6464 0.0859 +vn 0.7052 -0.5894 -0.3940 +vn 0.7657 -0.6385 0.0774 +vn -0.9327 0.3516 0.0800 +vn -0.9354 0.3464 0.0706 +vn -0.9390 0.3367 0.0698 +vn -0.9471 0.3158 0.0574 +vn 0.3943 -0.8719 0.2904 +vn 0.7059 -0.7048 0.0703 +vn 0.6906 -0.7209 0.0575 +vn 0.5010 -0.7613 0.4116 +vn 0.7133 -0.6973 0.0709 +vn 0.7169 -0.6925 0.0802 +vn 0.7645 -0.5240 -0.3753 +vn -0.9506 0.3084 0.0343 +vn -0.9481 0.3174 0.0175 +vn 0.6855 -0.7273 0.0344 +vn 0.6926 -0.7211 0.0175 +vn -0.9446 0.3280 0.0086 +vn -0.9423 0.3346 0.0015 +vn -0.9415 0.3370 -0.0041 +vn -0.9425 0.3341 -0.0093 +vn 0.3470 -0.9338 -0.0875 +vn 0.7075 -0.7067 -0.0041 +vn 0.7053 -0.7088 -0.0092 +vn 0.7056 -0.7086 0.0019 +vn 0.7007 -0.7134 0.0086 +vn 0.7002 -0.7137 -0.0174 +vn 0.6997 -0.7138 -0.0298 +vn -0.9413 0.3353 -0.0389 +vn -0.9397 0.3392 -0.0429 +vn -0.9446 0.3269 -0.0298 +vn -0.9447 0.3274 -0.0174 +vn -0.9401 0.3368 -0.0538 +vn -0.9371 0.3410 -0.0748 +vn 0.4969 -0.7680 -0.4040 +vn 0.7065 -0.7056 -0.0540 +vn 0.7091 -0.7011 -0.0751 +vn 0.7088 -0.7041 -0.0429 +vn 0.4018 -0.8752 -0.2693 +vn 0.7058 -0.7073 -0.0387 +vn -0.9286 0.3599 -0.0905 +vn -0.9190 0.3846 -0.0867 +vn -0.9181 0.3952 -0.0312 +vn -0.9099 0.4101 -0.0632 +vn -0.9016 0.4315 -0.0309 +vn 0.7601 -0.6468 -0.0633 +vn 0.6837 -0.7269 -0.0645 +vn 0.7409 -0.6660 -0.0872 +vn 0.7226 -0.6853 -0.0909 +vn 0.0845 -0.9843 0.1549 +vn 0.1150 -0.9704 -0.2124 +vn -0.5176 -0.7986 -0.3071 +vn 0.2045 -0.8360 -0.5092 +vn -0.9201 0.3910 -0.0218 +vn -0.9890 -0.0159 -0.1468 +vn -0.7383 -0.6373 -0.2208 +vn -0.7308 -0.6131 -0.3002 +vn -0.7115 -0.5949 -0.3740 +vn -0.8292 0.2805 0.4835 +vn -0.3235 0.0079 0.9462 +vn 0.4770 0.6377 0.6049 +vn 0.4338 0.6660 0.6069 +vn 0.4294 0.6584 0.6181 +vn 0.4721 0.6300 0.6166 +vn 0.4123 0.6316 0.6566 +vn 0.4540 0.6044 0.6547 +vn -0.6537 -0.6577 0.3743 +vn -0.8926 -0.1815 0.4126 +vn -0.4548 -0.7795 0.4306 +vn -0.4549 -0.7795 0.4306 +vn -0.1889 -0.3650 0.9116 +vn -0.2466 -0.3559 0.9014 +vn 0.0038 0.1656 -0.9862 +vn -0.4791 -0.3137 -0.8198 +vn 0.0790 0.1529 -0.9851 +vn -0.2604 -0.4009 -0.8783 +vn -0.7538 0.1244 -0.6452 +vn 0.3478 0.8692 0.3514 +vn 0.4781 0.8085 0.3432 +vn 0.4095 0.8292 -0.3805 +vn 0.0775 0.8477 -0.5247 +vn -0.2940 -0.4457 0.8455 +vn -0.0313 0.2960 0.9547 +vn -0.2862 -0.4728 0.8334 +vn 0.1109 0.1962 0.9743 +vn -0.4700 -0.8571 0.2110 +vn -0.4032 -0.7297 0.5522 +vn -0.5050 -0.8375 0.2087 +vn -0.4312 -0.7153 0.5499 +vn -0.4032 -0.7298 0.5522 +vn -0.4097 -0.7511 -0.5177 +vn -0.4731 -0.8655 -0.1645 +vn -0.4384 -0.7353 -0.5169 +vn -0.5082 -0.8453 -0.1651 +vn 0.5034 0.6707 0.5447 +vn 0.4615 0.7003 0.5447 +vn 0.5417 0.8165 0.1997 +vn 0.5929 0.7807 0.1975 +vn 0.5348 0.8026 -0.2643 +vn 0.5847 0.7630 -0.2757 +vn 0.5846 0.7630 -0.2757 +vn 0.4336 0.6569 -0.6168 +vn 0.4689 0.6162 -0.6328 +vn 0.5092 0.7786 -0.3668 +vn 0.5539 0.7380 -0.3854 +vn -0.0796 -0.1532 -0.9850 +vn -0.2768 -0.5113 -0.8136 +vn -0.0772 -0.1549 -0.9849 +vn -0.2926 -0.5026 -0.8135 +vn 0.1401 0.2022 0.9693 +vn 0.1341 0.2112 0.9682 +vn 0.3364 0.5138 0.7892 +vn 0.3652 0.4933 0.7895 +vn 0.3364 0.5137 0.7892 +vn 0.3332 0.6194 -0.7109 +vn 0.1465 0.2652 -0.9530 +vn 0.3765 0.5943 -0.7107 +vn 0.1710 0.2517 -0.9526 +vn 0.4636 0.8852 -0.0393 +vn 0.4349 0.8199 -0.3723 +vn 0.5242 0.8505 -0.0431 +vn 0.4896 0.7876 -0.3741 +vn 0.1563 0.9202 -0.3590 +vn -0.6066 -0.7939 -0.0418 +vn -0.5520 -0.8325 -0.0476 +vn -0.5367 -0.8059 0.2499 +vn -0.5890 -0.7674 0.2534 +vn -0.4425 -0.6600 0.6071 +vn -0.4874 -0.6284 0.6062 +vn -0.4874 -0.6284 0.6063 +vn -0.1864 -0.2706 0.9445 +vn -0.2114 -0.2588 0.9425 +vn -0.5084 -0.6649 -0.5472 +vn -0.4608 -0.6961 -0.5506 +vn -0.5221 -0.7889 -0.3241 +vn -0.5750 -0.7535 -0.3187 +vn 0.1745 0.3556 0.9182 +vn 0.2967 0.5836 0.7559 +vn 0.2097 0.3389 0.9172 +vn 0.3438 0.5604 0.7535 +vn 0.4383 0.7153 0.5443 +vn 0.3828 0.7440 0.5477 +vn 0.4417 0.8518 0.2815 +vn 0.5025 0.8189 0.2774 +vn -0.0790 -0.1180 0.9899 +vn 0.0372 0.1006 0.9942 +vn -0.0697 -0.1240 0.9898 +vn 0.0593 0.0900 0.9942 +vn 0.0657 0.1004 -0.9928 +vn 0.0646 0.1027 -0.9926 +vn -0.0514 -0.0732 -0.9960 +vn -0.0614 -0.0685 -0.9958 +vn -0.2115 -0.3160 -0.9249 +vn -0.2373 -0.3019 -0.9233 +vn -0.3643 -0.5486 -0.7525 +vn -0.4035 -0.5240 -0.7501 +vn -0.3164 -0.5771 0.7529 +vn -0.1868 -0.3264 0.9266 +vn -0.3351 -0.5708 0.7496 +vn -0.1912 -0.3279 0.9251 +vn -0.4759 -0.8729 0.1076 +vn -0.4289 -0.7891 0.4396 +vn -0.5042 -0.8571 0.1057 +vn -0.4564 -0.7755 0.4363 +vn -0.4564 -0.7754 0.4363 +vn 0.5934 0.8048 0.0121 +vn 0.5478 0.8366 0.0080 +vn 0.4982 0.7588 -0.4196 +vn 0.5395 0.7308 -0.4182 +vn 0.3232 0.4937 -0.8074 +vn 0.3475 0.4750 -0.8084 +vn 0.1673 0.2582 -0.9515 +vn 0.1777 0.2491 -0.9520 +vn -0.4614 -0.8406 -0.2837 +vn -0.4758 -0.8683 -0.1402 +vn -0.4826 -0.8278 -0.2860 +vn -0.5007 -0.8539 -0.1417 +vn 0.5611 0.7668 0.3119 +vn 0.5182 0.7973 0.3094 +vn 0.5334 0.8175 0.2175 +vn 0.5774 0.7860 0.2208 +vn -0.4088 -0.7540 -0.5141 +vn -0.4423 -0.8090 -0.3872 +vn -0.4225 -0.7442 -0.5173 +vn -0.4603 -0.7974 -0.3902 +vn -0.2877 -0.5458 -0.7870 +vn -0.3566 -0.6654 -0.6558 +vn -0.2869 -0.5424 -0.7896 +vn -0.3640 -0.6583 -0.6589 +vn 0.3463 0.5004 0.7935 +vn 0.3229 0.5205 0.7905 +vn 0.4054 0.6392 0.6534 +vn 0.4375 0.6154 0.6557 +vn 0.4666 0.7266 0.5044 +vn 0.5047 0.6991 0.5065 +vn 0.5009 0.7744 0.3866 +vn 0.5422 0.7446 0.3893 +vn -0.1252 -0.2592 -0.9577 +vn -0.2086 -0.4069 -0.8893 +vn -0.1055 -0.2641 -0.9587 +vn -0.1986 -0.4077 -0.8913 +vn 0.1471 0.2452 0.9583 +vn 0.1401 0.2556 0.9566 +vn 0.2329 0.3906 0.8906 +vn 0.2476 0.3745 0.8936 +vn 0.3229 0.5204 0.7905 +vn 0.3463 0.5003 0.7935 +vn 0.0631 0.0794 -0.9948 +vn -0.0365 -0.1015 -0.9942 +vn 0.1018 0.0632 -0.9928 +vn -0.0078 -0.1116 -0.9937 +vn 0.2486 0.4258 -0.8700 +vn 0.1655 0.2696 -0.9486 +vn 0.3045 0.3969 -0.8659 +vn 0.2142 0.2460 -0.9453 +vn -0.3229 -0.3789 0.8673 +vn -0.2956 -0.3970 0.8689 +vn -0.2034 -0.2555 0.9452 +vn -0.2229 -0.2432 0.9440 +vn -0.0787 -0.0673 0.9946 +vn -0.0887 -0.0636 0.9940 +vn 0.0401 0.1090 0.9932 +vn 0.0396 0.1052 0.9937 +vn -0.5041 -0.6278 0.5930 +vn -0.4643 -0.6586 0.5921 +vn -0.3791 -0.5253 0.7618 +vn -0.4131 -0.5018 0.7599 +vn 0.4565 0.8389 -0.2964 +vn 0.4330 0.7869 -0.4396 +vn 0.5270 0.7958 -0.2983 +vn 0.5016 0.7449 -0.4399 +vn 0.4548 0.6578 -0.6004 +vn 0.3889 0.6968 -0.6027 +vn 0.0882 0.9024 -0.4217 +vn 0.3218 0.5654 -0.7595 +vn 0.3832 0.5314 -0.7555 +vn 0.4723 0.8805 -0.0411 +vn 0.4683 0.8680 -0.1649 +vn 0.5438 0.8380 -0.0453 +vn 0.5397 0.8249 -0.1680 +vn -0.6131 -0.7884 0.0498 +vn -0.5610 -0.8267 0.0440 +vn -0.5563 -0.8155 0.1597 +vn -0.6067 -0.7777 0.1648 +vn -0.5436 -0.7918 0.2784 +vn -0.5916 -0.7546 0.2840 +vn -0.5179 -0.7466 0.4175 +vn -0.5624 -0.7111 0.4219 +vn -0.5624 -0.7111 0.4220 +vn 0.4608 0.8653 0.1975 +vn 0.4693 0.8792 0.0826 +vn 0.5307 0.8251 0.1936 +vn 0.5405 0.8376 0.0788 +vn 0.4234 0.7975 0.4298 +vn 0.4474 0.8416 0.3026 +vn 0.4898 0.7611 0.4253 +vn 0.5158 0.8030 0.2985 +vn -0.5612 -0.7180 -0.4118 +vn -0.5094 -0.7535 -0.4157 +vn -0.5362 -0.7945 -0.2851 +vn -0.5893 -0.7573 -0.2816 +vn -0.5499 -0.8146 -0.1846 +vn -0.6034 -0.7768 -0.1802 +vn -0.5587 -0.8259 -0.0760 +vn -0.6118 -0.7879 -0.0708 +vn 0.3447 0.6494 0.6778 +vn 0.3861 0.7276 0.5670 +vn 0.4047 0.6185 0.6735 +vn 0.4497 0.6941 0.5621 +vn -0.4668 -0.5873 -0.6612 +vn -0.4208 -0.6178 -0.6643 +vn -0.4656 -0.6864 -0.5586 +vn -0.5148 -0.6537 -0.5546 +vn 0.2227 0.4173 0.8811 +vn 0.2958 0.5560 0.7768 +vn 0.2708 0.3936 0.8785 +vn 0.3508 0.5279 0.7735 +vn 0.0177 0.0345 0.9992 +vn 0.1227 0.2287 0.9657 +vn 0.0465 0.0233 0.9986 +vn 0.1612 0.2114 0.9640 +vn -0.0232 0.0122 -0.9997 +vn -0.0113 0.0077 -0.9999 +vn -0.1494 -0.2009 -0.9682 +vn -0.1749 -0.1892 -0.9662 +vn -0.2878 -0.4121 -0.8645 +vn -0.3242 -0.3907 -0.8616 +vn -0.3725 -0.5428 -0.7528 +vn -0.4147 -0.5149 -0.7503 +vn -0.1065 -0.1884 0.9763 +vn -0.0601 -0.1063 0.9925 +vn -0.0888 -0.1966 0.9765 +vn -0.0382 -0.1143 0.9927 +vn -0.1361 -0.2443 0.9601 +vn -0.1222 -0.2539 0.9595 +vn 0.0982 0.2530 -0.9625 +vn 0.1316 0.2362 -0.9628 +vn 0.1223 0.2053 -0.9710 +vn 0.1193 0.2052 -0.9714 +vn 0.0724 0.1337 -0.9884 +vn 0.0694 0.1348 -0.9884 +vn 0.1052 0.1152 -0.9878 +vn 0.0934 0.1236 -0.9879 +vn -0.0157 0.0157 -0.9998 +vn -0.0044 0.0107 -0.9999 +vn 0.1358 0.1980 -0.9708 +vn 0.0768 0.1324 -0.9882 +vn -0.0269 0.0171 -0.9995 +vn -0.3658 -0.3361 -0.8679 +vn -0.4773 -0.4442 -0.7582 +vn -0.3710 -0.3404 -0.8640 +vn -0.4788 -0.4507 -0.7534 +vn -0.5417 -0.5158 -0.6637 +vn -0.5431 -0.5084 -0.6683 +vn -0.3604 -0.3600 -0.8605 +vn -0.4602 -0.4761 -0.7494 +vn -0.5179 -0.5444 -0.6598 +vn -0.1848 -0.1619 -0.9693 +vn -0.1940 -0.1621 -0.9675 +vn -0.3658 -0.3362 -0.8678 +vn -0.1953 -0.1717 -0.9656 +vn -0.3604 -0.3601 -0.8605 +vn -0.6031 -0.5669 -0.5611 +vn -0.5991 -0.5756 -0.5565 +vn -0.6539 -0.6330 -0.4143 +vn -0.6602 -0.6229 -0.4197 +vn -0.5707 -0.6072 -0.5527 +vn -0.6211 -0.6677 -0.4105 +vn -0.7127 -0.6754 -0.1895 +vn -0.7232 -0.6861 -0.0788 +vn -0.7034 -0.6867 -0.1836 +vn -0.7129 -0.6974 -0.0734 +vn -0.7136 -0.6989 0.0475 +vn -0.7245 -0.6880 0.0422 +vn -0.6665 -0.7237 -0.1791 +vn -0.6750 -0.7345 -0.0692 +vn -0.6755 -0.7355 0.0512 +vn -0.6951 -0.6575 -0.2907 +vn -0.6870 -0.6685 -0.2851 +vn -0.6516 -0.7049 -0.2805 +vn -0.6961 -0.6612 0.2798 +vn -0.6581 -0.6245 0.4205 +vn -0.6854 -0.6707 0.2836 +vn -0.6488 -0.6331 0.4222 +vn -0.6488 -0.6331 0.4223 +vn -0.5784 -0.5608 0.5924 +vn -0.5853 -0.5540 0.5920 +vn -0.6496 -0.7048 0.2853 +vn -0.6160 -0.6645 0.4231 +vn -0.6160 -0.6645 0.4230 +vn -0.5511 -0.5874 0.5927 +vn -0.7159 -0.6801 0.1578 +vn -0.7048 -0.6904 0.1629 +vn -0.6674 -0.7260 0.1660 +vn -0.4725 -0.4451 0.7607 +vn -0.4697 -0.4496 0.7598 +vn -0.3605 -0.3386 0.8691 +vn -0.3588 -0.3356 0.8710 +vn -0.4510 -0.4704 0.7585 +vn -0.3508 -0.3546 0.8667 +vn -0.0691 -0.0567 0.9960 +vn 0.0840 0.0902 0.9924 +vn -0.0798 -0.0553 0.9953 +vn 0.0702 0.0946 0.9930 +vn 0.1943 0.2178 0.9564 +vn 0.2092 0.2101 0.9550 +vn -0.0906 -0.0579 0.9942 +vn 0.0507 0.1005 0.9936 +vn 0.1686 0.2312 0.9582 +vn -0.2327 -0.2140 0.9487 +vn -0.2394 -0.2159 0.9466 +vn -0.2392 -0.2266 0.9442 +vn 0.3261 0.3216 0.8890 +vn 0.3099 0.3317 0.8910 +vn 0.4245 0.4438 0.7892 +vn 0.4409 0.4311 0.7872 +vn 0.2791 0.3525 0.8932 +vn 0.3881 0.4705 0.7925 +vn 0.6225 0.6030 0.4988 +vn 0.6640 0.6419 0.3835 +vn 0.6060 0.6184 0.5003 +vn 0.6478 0.6578 0.3843 +vn 0.6679 0.6765 0.3101 +vn 0.6837 0.6607 0.3099 +vn 0.5628 0.6552 0.5040 +vn 0.6036 0.6970 0.3872 +vn 0.6238 0.7171 0.3111 +vn 0.5462 0.5309 0.6480 +vn 0.5624 0.5162 0.6459 +vn 0.5295 0.5453 0.6498 +vn 0.6225 0.6030 0.4989 +vn 0.3881 0.4705 0.7924 +vn 0.4889 0.5778 0.6535 +vn 0.7010 0.6773 0.2235 +vn 0.6856 0.6931 0.2225 +vn 0.7036 0.7104 0.0174 +vn 0.7190 0.6948 0.0181 +vn 0.6413 0.7347 0.2213 +vn 0.6585 0.7524 0.0145 +vn 0.4210 0.4088 -0.8097 +vn 0.2167 0.2120 -0.9530 +vn 0.4113 0.4196 -0.8092 +vn 0.2102 0.2193 -0.9527 +vn 0.0797 0.0899 -0.9928 +vn 0.0850 0.0855 -0.9927 +vn 0.3838 0.4445 -0.8094 +vn 0.1954 0.2337 -0.9525 +vn 0.0715 0.0958 -0.9928 +vn 0.6539 0.6328 -0.4147 +vn 0.6399 0.6472 -0.4143 +vn 0.5983 0.6842 -0.4170 +vn -0.2735 -0.2573 -0.9268 +vn -0.4732 -0.4484 -0.7583 +vn -0.2752 -0.2620 -0.9250 +vn -0.4717 -0.4578 -0.7536 +vn -0.5973 -0.5834 -0.5504 +vn -0.6027 -0.5724 -0.5560 +vn -0.2651 -0.2793 -0.9229 +vn -0.4493 -0.4863 -0.7495 +vn -0.5660 -0.6180 -0.5456 +vn -0.0654 -0.0584 -0.9961 +vn -0.0688 -0.0572 -0.9960 +vn -0.0699 -0.0615 -0.9957 +vn -0.6863 -0.6521 -0.3220 +vn -0.6774 -0.6632 -0.3184 +vn -0.7141 -0.6990 -0.0376 +vn -0.7248 -0.6880 -0.0368 +vn -0.6397 -0.7008 -0.3156 +vn -0.6738 -0.7379 -0.0377 +vn -0.5727 -0.5398 0.6169 +vn -0.2357 -0.2173 0.9472 +vn -0.5685 -0.5502 0.6117 +vn -0.2396 -0.2222 0.9451 +vn 0.1738 0.1844 0.9674 +vn 0.1821 0.1795 0.9668 +vn -0.5405 -0.5828 0.6068 +vn -0.2355 -0.2388 0.9421 +vn 0.1558 0.1923 0.9689 +vn -0.7003 -0.6633 0.2639 +vn -0.6911 -0.6744 0.2600 +vn -0.5728 -0.5398 0.6169 +vn -0.6532 -0.7123 0.2568 +vn 0.4446 0.4272 0.7873 +vn 0.4355 0.4386 0.7861 +vn 0.5943 0.5911 0.5453 +vn 0.6041 0.5771 0.5495 +vn 0.4445 0.4272 0.7873 +vn 0.4063 0.4631 0.7877 +vn 0.4064 0.4631 0.7876 +vn 0.5592 0.6259 0.5437 +vn 0.6885 0.6535 -0.3145 +vn 0.5227 0.4938 -0.6949 +vn 0.6788 0.6681 -0.3048 +vn 0.5243 0.5146 -0.6785 +vn 0.6357 0.6275 -0.4496 +vn 0.6417 0.6102 -0.4646 +vn 0.6440 0.7078 -0.2902 +vn 0.5091 0.5599 -0.6536 +vn 0.6092 0.6775 -0.4122 +vn 0.7099 0.6760 0.1977 +vn 0.6977 0.6893 0.1953 +vn 0.6788 0.6681 -0.3047 +vn 0.6575 0.7278 0.1949 +vn 0.6441 0.7079 -0.2901 +vn 0.6440 0.7079 -0.2901 +vn 0.5648 0.5205 0.6404 +vn 0.5590 0.5513 0.6193 +vn 0.5653 0.5591 0.6066 +vn 0.5324 0.5942 0.6029 +vn 0.5266 0.5865 0.6154 +vn 0.5590 0.5514 0.6193 +vn 0.5066 0.5621 0.6538 +vn -0.4625 -0.7697 0.4400 +vn -0.5006 -0.7420 0.4460 +vn -0.5004 -0.7421 0.4460 +vn -0.2086 -0.3581 0.9101 +vn -0.1936 -0.3641 0.9110 +vn -0.6378 -0.7363 -0.2258 +vn -0.5679 -0.6941 0.4424 +vn -0.5679 -0.6941 0.4423 +vn -0.2416 -0.3372 0.9099 +vn 0.0860 0.1568 -0.9839 +vn -0.2632 -0.3921 -0.8815 +vn 0.0899 0.1620 -0.9827 +vn -0.2882 -0.3662 -0.8848 +vn -0.2883 -0.3662 -0.8847 +vn 0.1005 0.1563 -0.9826 +vn -0.3186 -0.3344 -0.8870 +vn -0.3186 -0.3343 -0.8870 +vn -0.6040 -0.6882 -0.4020 +vn 0.5122 0.7921 0.3320 +vn 0.5647 0.7616 0.3179 +vn 0.5091 0.7786 -0.3669 +vn 0.6360 0.7105 0.3011 +vn 0.6818 0.6730 0.2866 +vn 0.6091 0.6775 -0.4123 +vn 0.6091 0.6775 -0.4122 +vn -0.3002 -0.4645 0.8331 +vn 0.1261 0.1883 0.9740 +vn -0.3239 -0.4451 0.8348 +vn 0.1466 0.1837 0.9720 +vn 0.1260 0.1883 0.9740 +vn 0.1465 0.1837 0.9720 +vn -0.3591 -0.4156 0.8356 +vn 0.1650 0.1703 0.9715 +vn 0.1651 0.1703 0.9715 +vn -0.5335 -0.8198 0.2082 +vn -0.4550 -0.7003 0.5500 +vn -0.5814 -0.7861 0.2096 +vn -0.4949 -0.6713 0.5518 +vn -0.4551 -0.7003 0.5500 +vn -0.4949 -0.6713 0.5519 +vn -0.6464 -0.7330 0.2120 +vn -0.5496 -0.6258 0.5535 +vn -0.6540 -0.6848 -0.3216 +vn -0.6639 -0.6751 -0.3216 +vn -0.6233 -0.7149 -0.3167 +vn -0.4618 -0.7194 -0.5189 +vn -0.5367 -0.8273 -0.1661 +vn -0.5014 -0.6910 -0.5207 +vn -0.5848 -0.7940 -0.1661 +vn -0.5590 -0.6469 -0.5187 +vn -0.6509 -0.7414 -0.1632 +vn -0.0768 -0.1500 -0.9857 +vn -0.3059 -0.4908 -0.8158 +vn -0.0770 -0.1434 -0.9867 +vn -0.3288 -0.4714 -0.8183 +vn -0.0891 -0.1366 -0.9866 +vn -0.3683 -0.4431 -0.8173 +vn -0.3683 -0.4432 -0.8173 +vn 0.4012 0.5788 -0.7100 +vn 0.1855 0.2464 -0.9513 +vn 0.4399 0.5523 -0.7081 +vn 0.2072 0.2355 -0.9495 +vn 0.4837 0.5152 -0.7076 +vn 0.2261 0.2187 -0.9492 +vn 0.5575 0.8288 -0.0475 +vn 0.5202 0.7667 -0.3763 +vn 0.6103 0.7905 -0.0513 +vn 0.5685 0.7310 -0.3775 +vn 0.6738 0.7371 -0.0519 +vn 0.6266 0.6820 -0.3772 +vn 0.6266 0.6819 -0.3772 +vn 0.2278 0.3312 0.9156 +vn 0.3697 0.5486 0.7499 +vn 0.2587 0.3150 0.9132 +vn 0.4122 0.5234 0.7458 +vn 0.5185 0.6679 0.5339 +vn 0.4691 0.6993 0.5393 +vn 0.2893 0.2903 0.9122 +vn 0.4586 0.4855 0.7443 +vn 0.4122 0.5233 0.7458 +vn 0.4586 0.4856 0.7442 +vn 0.4794 0.4580 0.7486 +vn 0.5751 0.6213 0.5322 +vn 0.5359 0.7993 0.2719 +vn 0.5889 0.7631 0.2662 +vn 0.6516 0.7108 0.2649 +vn -0.0703 -0.1252 0.9896 +vn 0.0679 0.0868 0.9939 +vn -0.0684 -0.1257 0.9897 +vn 0.0838 0.0790 0.9933 +vn 0.2278 0.3313 0.9156 +vn -0.0746 -0.1220 0.9897 +vn 0.0952 0.0692 0.9931 +vn -0.3528 -0.5639 0.7467 +vn -0.2002 -0.3262 0.9239 +vn -0.3796 -0.5469 0.7461 +vn -0.2120 -0.3195 0.9236 +vn -0.4234 -0.5130 0.7467 +vn -0.2353 -0.3024 0.9237 +vn -0.5305 -0.8415 0.1024 +vn -0.4806 -0.7626 0.4329 +vn -0.5755 -0.8115 0.1012 +vn -0.5203 -0.7369 0.4317 +vn -0.6443 -0.7578 0.1028 +vn -0.5815 -0.6888 0.4329 +vn -0.5071 -0.8116 -0.2903 +vn -0.5266 -0.8377 -0.1448 +vn -0.5503 -0.7816 -0.2938 +vn -0.5715 -0.8074 -0.1467 +vn -0.6183 -0.7300 -0.2913 +vn -0.6408 -0.7539 -0.1445 +vn -0.4425 -0.7280 -0.5237 +vn -0.4829 -0.7810 -0.3961 +vn -0.4810 -0.6998 -0.5281 +vn -0.5245 -0.7514 -0.4003 +vn -0.5438 -0.6535 -0.5264 +vn -0.5906 -0.7017 -0.3984 +vn -0.2982 -0.5291 -0.7945 +vn -0.3799 -0.6430 -0.6650 +vn -0.3254 -0.5072 -0.7981 +vn -0.4136 -0.6175 -0.6691 +vn -0.3752 -0.4735 -0.7969 +vn -0.4710 -0.5767 -0.6676 +vn -0.1067 -0.2562 -0.9607 +vn -0.2050 -0.3970 -0.8946 +vn -0.1205 -0.2437 -0.9623 +vn -0.2254 -0.3795 -0.8973 +vn -0.2050 -0.3970 -0.8947 +vn -0.1516 -0.2258 -0.9623 +vn -0.2665 -0.3539 -0.8965 +vn 0.1101 0.0618 -0.9920 +vn -0.0040 -0.1071 -0.9942 +vn 0.1110 0.0625 -0.9919 +vn -0.0110 -0.1000 -0.9949 +vn 0.1017 0.0630 -0.9928 +vn -0.0320 -0.0903 -0.9954 +vn 0.3217 0.3850 -0.8650 +vn 0.2274 0.2391 -0.9440 +vn 0.3370 0.3713 -0.8652 +vn 0.2360 0.2319 -0.9437 +vn 0.3517 0.3541 -0.8666 +vn 0.2398 0.2229 -0.9449 +vn 0.5561 0.7733 -0.3047 +vn 0.5288 0.7229 -0.4448 +vn 0.5949 0.7419 -0.3094 +vn 0.5631 0.6939 -0.4489 +vn 0.5076 0.6127 -0.6057 +vn 0.4791 0.6379 -0.6030 +vn 0.6428 0.7008 -0.3093 +vn 0.6059 0.6567 -0.4491 +vn 0.6766 0.6700 -0.3055 +vn 0.5428 0.5810 -0.6065 +vn 0.4041 0.5155 -0.7556 +vn 0.4258 0.4957 -0.7569 +vn 0.4506 0.4711 -0.7583 +vn 0.5757 0.8160 -0.0525 +vn 0.5705 0.8024 -0.1750 +vn 0.6202 0.7823 -0.0577 +vn 0.6126 0.7695 -0.1802 +vn 0.6738 0.7366 -0.0578 +vn 0.6640 0.7257 -0.1802 +vn 0.5635 0.8045 0.1879 +vn 0.5732 0.8162 0.0722 +vn 0.6102 0.7707 0.1837 +vn 0.6192 0.7824 0.0672 +vn 0.6650 0.7240 0.1832 +vn 0.6739 0.7358 0.0670 +vn 0.5215 0.7423 0.4207 +vn 0.5483 0.7830 0.2938 +vn 0.5671 0.7102 0.4172 +vn 0.5949 0.7497 0.2900 +vn 0.6191 0.6656 0.4168 +vn 0.6491 0.7034 0.2895 +vn 0.4325 0.6029 0.6704 +vn 0.4797 0.6770 0.5582 +vn 0.4723 0.5753 0.6678 +vn 0.5228 0.6470 0.5551 +vn 0.5151 0.5380 0.6673 +vn 0.5705 0.6056 0.5547 +vn 0.5357 0.5120 0.6714 +vn 0.5705 0.6056 0.5548 +vn 0.2918 0.3831 0.8764 +vn 0.3758 0.5142 0.7709 +vn 0.3215 0.3644 0.8740 +vn 0.4115 0.4898 0.7686 +vn 0.3488 0.3395 0.8735 +vn 0.4483 0.4574 0.7680 +vn 0.0556 0.0215 0.9982 +vn 0.1768 0.2062 0.9624 +vn 0.0666 0.0173 0.9976 +vn 0.1977 0.1946 0.9608 +vn 0.0664 0.0130 0.9977 +vn 0.2117 0.1797 0.9607 +vn -0.0894 -0.1974 0.9762 +vn -0.0346 -0.1139 0.9929 +vn -0.0932 -0.1976 0.9758 +vn -0.0320 -0.1149 0.9929 +vn -0.1109 -0.1887 0.9758 +vn -0.0425 -0.1112 0.9929 +vn -0.1259 -0.2558 0.9585 +vn -0.1349 -0.2556 0.9573 +vn -0.1582 -0.2422 0.9572 +vn 0.1387 0.2365 -0.9617 +vn 0.1454 0.2369 -0.9606 +vn 0.1613 0.2265 -0.9606 +usemtl Scene_-_Root +s 1 +f 29137/29137/20518 29138/29138/20519 29139/29139/20520 +f 29137/29137/20518 29139/29139/20520 29140/29140/20521 +f 29138/29138/20519 29141/29141/20522 29142/29142/20523 +f 29138/29138/20519 29142/29142/20523 29139/29139/20520 +f 29139/29139/20520 29142/29142/20523 29143/29143/20524 +f 29139/29139/20520 29143/29143/20524 29144/29144/20525 +f 29140/29140/20521 29139/29139/20520 29144/29144/20525 +f 29140/29140/20521 29144/29144/20525 29145/29145/20526 +f 29146/29146/20527 29147/29147/20528 29148/29148/20529 +f 29146/29146/20527 29148/29148/20529 29149/29149/20530 +f 29147/29147/20528 29150/29150/20531 29151/29151/20532 +f 29147/29147/20528 29151/29151/20532 29148/29148/20529 +f 29148/29148/20529 29151/29151/20532 29152/29152/20533 +f 29148/29148/20529 29152/29152/20533 29153/29153/20534 +f 29149/29149/20530 29148/29148/20529 29153/29153/20534 +f 29149/29149/20530 29153/29153/20534 29154/29154/20535 +f 29155/29155/20536 29156/29156/20537 29157/29157/20538 +f 29155/29155/20536 29157/29157/20538 29158/29158/20539 +f 29159/29159/20540 29160/29160/20541 29161/29161/20542 +f 29159/29159/20540 29161/29161/20542 29162/29162/20538 +f 29162/29162/20538 29161/29161/20542 29163/29163/20543 +f 29162/29162/20538 29163/29163/20543 29164/29164/20544 +f 29158/29158/20539 29157/29157/20538 29165/29165/20544 +f 29158/29158/20539 29165/29165/20544 29166/29166/20545 +f 29167/29167/20546 29168/29168/20547 29169/29169/20548 +f 29167/29167/20546 29169/29169/20548 29170/29170/20549 +f 29168/29168/20547 29171/29171/20550 29172/29172/20551 +f 29168/29168/20547 29172/29172/20551 29169/29169/20548 +f 29169/29169/20548 29172/29172/20551 29173/29173/20552 +f 29169/29169/20548 29173/29173/20552 29174/29174/20553 +f 29170/29170/20549 29169/29169/20548 29174/29174/20553 +f 29170/29170/20549 29174/29174/20553 29175/29175/20554 +f 29152/29152/20533 29151/29151/20532 29176/29176/20555 +f 29152/29152/20533 29176/29176/20555 29177/29177/20556 +f 29151/29151/20532 29150/29150/20531 29178/29178/20557 +f 29151/29151/20532 29178/29178/20557 29176/29176/20555 +f 29176/29176/20555 29178/29178/20557 29179/29179/20558 +f 29176/29176/20555 29179/29179/20558 29180/29180/20559 +f 29181/29181/20556 29182/29182/20555 29183/29183/20559 +f 29181/29181/20556 29183/29183/20559 29184/29184/20560 +f 29173/29173/20552 29185/29185/20561 29186/29186/20562 +f 29173/29173/20552 29186/29186/20562 29187/29187/20563 +f 29185/29185/20561 29188/29188/20564 29189/29189/20565 +f 29185/29185/20561 29189/29189/20565 29186/29186/20562 +f 29186/29186/20562 29189/29189/20565 29190/29190/20566 +f 29186/29186/20562 29190/29190/20566 29191/29191/20567 +f 29187/29187/20563 29186/29186/20562 29191/29191/20567 +f 29187/29187/20563 29191/29191/20567 29192/29192/20568 +f 29192/29192/20568 29191/29191/20567 29193/29193/20569 +f 29192/29192/20568 29193/29193/20569 29194/29194/20570 +f 29195/29195/20567 29196/29196/20571 29197/29197/20572 +f 29195/29195/20567 29197/29197/20572 29198/29198/20569 +f 29198/29198/20569 29197/29197/20572 29199/29199/20573 +f 29198/29198/20569 29199/29199/20573 29200/29200/20574 +f 29194/29194/20570 29193/29193/20569 29201/29201/20574 +f 29194/29194/20570 29201/29201/20574 29202/29202/20575 +f 29175/29175/20554 29174/29174/20553 29203/29203/20576 +f 29175/29175/20554 29203/29203/20576 29204/29204/20577 +f 29174/29174/20553 29173/29173/20552 29187/29187/20563 +f 29174/29174/20553 29187/29187/20563 29203/29203/20576 +f 29203/29203/20576 29187/29187/20563 29192/29192/20568 +f 29203/29203/20576 29192/29192/20568 29205/29205/20578 +f 29204/29204/20577 29203/29203/20576 29205/29205/20578 +f 29204/29204/20577 29205/29205/20578 29206/29206/20579 +f 29207/29207/20580 29208/29208/20581 29209/29209/20582 +f 29207/29207/20580 29209/29209/20582 29210/29210/20583 +f 29211/29211/20581 29188/29188/20564 29185/29185/20561 +f 29211/29211/20581 29185/29185/20561 29212/29212/20584 +f 29212/29212/20584 29185/29185/20561 29173/29173/20552 +f 29212/29212/20584 29173/29173/20552 29172/29172/20551 +f 29213/29213/20583 29212/29212/20584 29172/29172/20551 +f 29213/29213/20583 29172/29172/20551 29171/29171/20550 +f 29141/29141/20522 29214/29214/20585 29215/29215/20586 +f 29141/29141/20522 29215/29215/20586 29216/29216/20587 +f 29214/29214/20585 29217/29217/20588 29218/29218/20589 +f 29214/29214/20585 29218/29218/20589 29215/29215/20586 +f 29219/29219/20590 29220/29220/20589 29221/29221/20591 +f 29219/29219/20590 29221/29221/20591 29222/29222/20592 +f 29223/29223/20587 29219/29219/20590 29222/29222/20592 +f 29223/29223/20587 29222/29222/20592 29224/29224/20593 +f 29225/29225/20594 29226/29226/20595 29227/29227/20596 +f 29225/29225/20594 29227/29227/20596 29228/29228/20597 +f 29226/29226/20595 29229/29229/20598 29230/29230/20599 +f 29226/29226/20595 29230/29230/20599 29227/29227/20596 +f 29227/29227/20596 29230/29230/20599 29231/29231/20600 +f 29227/29227/20596 29231/29231/20600 29232/29232/20601 +f 29228/29228/20597 29227/29227/20596 29232/29232/20601 +f 29228/29228/20597 29232/29232/20601 29233/29233/20602 +f 29143/29143/20524 29234/29234/20603 29235/29235/20604 +f 29143/29143/20524 29235/29235/20604 29236/29236/20605 +f 29237/29237/20606 29238/29238/20607 29239/29239/20608 +f 29237/29237/20606 29239/29239/20608 29240/29240/20609 +f 29240/29240/20609 29239/29239/20608 29241/29241/20610 +f 29240/29240/20609 29241/29241/20610 29242/29242/20611 +f 29236/29236/20605 29235/29235/20604 29243/29243/20612 +f 29236/29236/20605 29243/29243/20612 29244/29244/20613 +f 29145/29145/20526 29144/29144/20525 29245/29245/20614 +f 29145/29145/20526 29245/29245/20614 29246/29246/20615 +f 29144/29144/20525 29143/29143/20524 29236/29236/20605 +f 29144/29144/20525 29236/29236/20605 29245/29245/20614 +f 29245/29245/20614 29236/29236/20605 29244/29244/20613 +f 29245/29245/20614 29244/29244/20613 29247/29247/20595 +f 29246/29246/20615 29245/29245/20614 29247/29247/20595 +f 29246/29246/20615 29247/29247/20595 29248/29248/20594 +f 29206/29206/20579 29205/29205/20578 29249/29249/20616 +f 29206/29206/20579 29249/29249/20616 29250/29250/20617 +f 29205/29205/20578 29192/29192/20568 29194/29194/20570 +f 29205/29205/20578 29194/29194/20570 29249/29249/20616 +f 29249/29249/20616 29194/29194/20570 29202/29202/20575 +f 29249/29249/20616 29202/29202/20575 29251/29251/20618 +f 29250/29250/20617 29249/29249/20616 29251/29251/20618 +f 29250/29250/20617 29251/29251/20618 29252/29252/20619 +f 29253/29253/20620 29254/29254/20621 29255/29255/20622 +f 29253/29253/20620 29255/29255/20622 29256/29256/20623 +f 29254/29254/20621 29257/29257/20624 29258/29258/20625 +f 29254/29254/20621 29258/29258/20625 29255/29255/20622 +f 29255/29255/20622 29258/29258/20625 29259/29259/20626 +f 29255/29255/20622 29259/29259/20626 29260/29260/20627 +f 29256/29256/20623 29255/29255/20622 29260/29260/20627 +f 29256/29256/20623 29260/29260/20627 29261/29261/20628 +f 29252/29252/20619 29251/29251/20618 29262/29262/20629 +f 29252/29252/20619 29262/29262/20629 29263/29263/20630 +f 29251/29251/20618 29202/29202/20575 29264/29264/20631 +f 29251/29251/20618 29264/29264/20631 29262/29262/20629 +f 29265/29265/20629 29266/29266/20631 29253/29253/20620 +f 29265/29265/20629 29253/29253/20620 29267/29267/20632 +f 29268/29268/20630 29265/29265/20629 29267/29267/20632 +f 29268/29268/20630 29267/29267/20632 29269/29269/20633 +f 29202/29202/20575 29201/29201/20574 29270/29270/20634 +f 29202/29202/20575 29270/29270/20634 29264/29264/20631 +f 29200/29200/20574 29199/29199/20573 29271/29271/20635 +f 29200/29200/20574 29271/29271/20635 29272/29272/20634 +f 29272/29272/20634 29271/29271/20635 29257/29257/20624 +f 29272/29272/20634 29257/29257/20624 29254/29254/20621 +f 29266/29266/20631 29272/29272/20634 29254/29254/20621 +f 29266/29266/20631 29254/29254/20621 29253/29253/20620 +f 29229/29229/20598 29273/29273/20612 29274/29274/20636 +f 29229/29229/20598 29274/29274/20636 29230/29230/20599 +f 29242/29242/20611 29241/29241/20610 29275/29275/20637 +f 29242/29242/20611 29275/29275/20637 29276/29276/20638 +f 29276/29276/20638 29275/29275/20637 29277/29277/20639 +f 29276/29276/20638 29277/29277/20639 29278/29278/20640 +f 29230/29230/20599 29274/29274/20636 29279/29279/20641 +f 29230/29230/20599 29279/29279/20641 29231/29231/20600 +f 29280/29280/20642 29281/29281/20643 29282/29282/20644 +f 29280/29280/20642 29282/29282/20644 29283/29283/20645 +f 29284/29284/20646 29285/29285/20647 29286/29286/20648 +f 29284/29284/20646 29286/29286/20648 29287/29287/20644 +f 29287/29287/20644 29286/29286/20648 29288/29288/20649 +f 29287/29287/20644 29288/29288/20649 29289/29289/20650 +f 29283/29283/20645 29282/29282/20644 29290/29290/20650 +f 29283/29283/20645 29290/29290/20650 29291/29291/20651 +f 29231/29231/20600 29279/29279/20641 29292/29292/20652 +f 29231/29231/20600 29292/29292/20652 29293/29293/20653 +f 29278/29278/20640 29277/29277/20639 29294/29294/20654 +f 29278/29278/20640 29294/29294/20654 29295/29295/20655 +f 29295/29295/20655 29294/29294/20654 29285/29285/20647 +f 29295/29295/20655 29285/29285/20647 29284/29284/20646 +f 29293/29293/20653 29292/29292/20652 29281/29281/20643 +f 29293/29293/20653 29281/29281/20643 29280/29280/20642 +f 29233/29233/20602 29232/29232/20601 29296/29296/20656 +f 29233/29233/20602 29296/29296/20656 29297/29297/20657 +f 29232/29232/20601 29231/29231/20600 29293/29293/20653 +f 29232/29232/20601 29293/29293/20653 29296/29296/20656 +f 29296/29296/20656 29293/29293/20653 29280/29280/20642 +f 29296/29296/20656 29280/29280/20642 29298/29298/20658 +f 29297/29297/20657 29296/29296/20656 29298/29298/20658 +f 29297/29297/20657 29298/29298/20658 29299/29299/20659 +f 29269/29269/20633 29267/29267/20632 29300/29300/20660 +f 29269/29269/20633 29300/29300/20660 29301/29301/20661 +f 29267/29267/20632 29253/29253/20620 29256/29256/20623 +f 29267/29267/20632 29256/29256/20623 29300/29300/20660 +f 29300/29300/20660 29256/29256/20623 29261/29261/20628 +f 29300/29300/20660 29261/29261/20628 29302/29302/20662 +f 29301/29301/20661 29300/29300/20660 29302/29302/20662 +f 29301/29301/20661 29302/29302/20662 29303/29303/20663 +f 29304/29304/20664 29305/29305/20665 29306/29306/20666 +f 29304/29304/20664 29306/29306/20666 29307/29307/20667 +f 29305/29305/20665 29291/29291/20651 29308/29308/20668 +f 29305/29305/20665 29308/29308/20668 29306/29306/20666 +f 29306/29306/20666 29308/29308/20668 29309/29309/20669 +f 29306/29306/20666 29309/29309/20669 29310/29310/20670 +f 29307/29307/20667 29306/29306/20666 29310/29310/20670 +f 29307/29307/20667 29310/29310/20670 29311/29311/20671 +f 29299/29299/20659 29298/29298/20658 29312/29312/20672 +f 29299/29299/20659 29312/29312/20672 29313/29313/20673 +f 29298/29298/20658 29280/29280/20642 29283/29283/20645 +f 29298/29298/20658 29283/29283/20645 29312/29312/20672 +f 29312/29312/20672 29283/29283/20645 29291/29291/20651 +f 29312/29312/20672 29291/29291/20651 29305/29305/20665 +f 29313/29313/20673 29312/29312/20672 29305/29305/20665 +f 29313/29313/20673 29305/29305/20665 29304/29304/20664 +f 29303/29303/20663 29302/29302/20662 29314/29314/20674 +f 29303/29303/20663 29314/29314/20674 29315/29315/20675 +f 29302/29302/20662 29261/29261/20628 29316/29316/20676 +f 29302/29302/20662 29316/29316/20676 29314/29314/20674 +f 29314/29314/20674 29316/29316/20676 29317/29317/20677 +f 29314/29314/20674 29317/29317/20677 29318/29318/20678 +f 29315/29315/20675 29314/29314/20674 29318/29318/20678 +f 29315/29315/20675 29318/29318/20678 29319/29319/20679 +f 29261/29261/20628 29260/29260/20627 29320/29320/20680 +f 29261/29261/20628 29320/29320/20680 29316/29316/20676 +f 29260/29260/20627 29259/29259/20626 29321/29321/20681 +f 29260/29260/20627 29321/29321/20681 29320/29320/20680 +f 29320/29320/20680 29321/29321/20681 29322/29322/20682 +f 29320/29320/20680 29322/29322/20682 29323/29323/20683 +f 29316/29316/20676 29320/29320/20680 29323/29323/20683 +f 29316/29316/20676 29323/29323/20683 29317/29317/20677 +f 29324/29324/20684 29325/29325/20685 29326/29326/20686 +f 29324/29324/20684 29326/29326/20686 29327/29327/20687 +f 29325/29325/20685 29328/29328/20688 29329/29329/20689 +f 29325/29325/20685 29329/29329/20689 29326/29326/20686 +f 29326/29326/20686 29329/29329/20689 29330/29330/20690 +f 29326/29326/20686 29330/29330/20690 29331/29331/20691 +f 29327/29327/20687 29326/29326/20686 29331/29331/20691 +f 29327/29327/20687 29331/29331/20691 29332/29332/20692 +f 29319/29319/20679 29318/29318/20678 29333/29333/20693 +f 29319/29319/20679 29333/29333/20693 29334/29334/20694 +f 29318/29318/20678 29317/29317/20677 29335/29335/20695 +f 29318/29318/20678 29335/29335/20695 29333/29333/20693 +f 29333/29333/20693 29335/29335/20695 29324/29324/20684 +f 29333/29333/20693 29324/29324/20684 29336/29336/20696 +f 29334/29334/20694 29333/29333/20693 29336/29336/20696 +f 29334/29334/20694 29336/29336/20696 29337/29337/20697 +f 29317/29317/20677 29323/29323/20683 29338/29338/20698 +f 29317/29317/20677 29338/29338/20698 29335/29335/20695 +f 29323/29323/20683 29322/29322/20682 29339/29339/20699 +f 29323/29323/20683 29339/29339/20699 29338/29338/20698 +f 29338/29338/20698 29339/29339/20699 29328/29328/20688 +f 29338/29338/20698 29328/29328/20688 29325/29325/20685 +f 29335/29335/20695 29338/29338/20698 29325/29325/20685 +f 29335/29335/20695 29325/29325/20685 29324/29324/20684 +f 29291/29291/20651 29290/29290/20650 29340/29340/20700 +f 29291/29291/20651 29340/29340/20700 29308/29308/20668 +f 29289/29289/20650 29288/29288/20649 29341/29341/20701 +f 29289/29289/20650 29341/29341/20701 29342/29342/20700 +f 29342/29342/20700 29341/29341/20701 29343/29343/20702 +f 29342/29342/20700 29343/29343/20702 29344/29344/20703 +f 29308/29308/20668 29340/29340/20700 29345/29345/20703 +f 29308/29308/20668 29345/29345/20703 29309/29309/20669 +f 29346/29346/20704 29347/29347/20705 29348/29348/20706 +f 29346/29346/20704 29348/29348/20706 29349/29349/20707 +f 29347/29347/20705 29350/29350/20708 29351/29351/20709 +f 29347/29347/20705 29351/29351/20709 29348/29348/20706 +f 29348/29348/20706 29351/29351/20709 29352/29352/20710 +f 29348/29348/20706 29352/29352/20710 29353/29353/20711 +f 29349/29349/20707 29348/29348/20706 29353/29353/20711 +f 29349/29349/20707 29353/29353/20711 29354/29354/20712 +f 29309/29309/20669 29345/29345/20703 29355/29355/20713 +f 29309/29309/20669 29355/29355/20713 29356/29356/20714 +f 29344/29344/20703 29343/29343/20702 29357/29357/20715 +f 29344/29344/20703 29357/29357/20715 29358/29358/20716 +f 29358/29358/20716 29357/29357/20715 29359/29359/20717 +f 29358/29358/20716 29359/29359/20717 29360/29360/20718 +f 29356/29356/20714 29355/29355/20713 29361/29361/20719 +f 29356/29356/20714 29361/29361/20719 29350/29350/20708 +f 29311/29311/20671 29310/29310/20670 29362/29362/20720 +f 29311/29311/20671 29362/29362/20720 29363/29363/20721 +f 29310/29310/20670 29309/29309/20669 29356/29356/20714 +f 29310/29310/20670 29356/29356/20714 29362/29362/20720 +f 29362/29362/20720 29356/29356/20714 29350/29350/20708 +f 29362/29362/20720 29350/29350/20708 29347/29347/20705 +f 29363/29363/20721 29362/29362/20720 29347/29347/20705 +f 29363/29363/20721 29347/29347/20705 29346/29346/20704 +f 29337/29337/20697 29336/29336/20696 29364/29364/20722 +f 29337/29337/20697 29364/29364/20722 29365/29365/20723 +f 29336/29336/20696 29324/29324/20684 29327/29327/20687 +f 29336/29336/20696 29327/29327/20687 29364/29364/20722 +f 29364/29364/20722 29327/29327/20687 29332/29332/20692 +f 29364/29364/20722 29332/29332/20692 29366/29366/20724 +f 29365/29365/20723 29364/29364/20722 29366/29366/20724 +f 29365/29365/20723 29366/29366/20724 29367/29367/20725 +f 29368/29368/20726 29369/29369/20727 29370/29370/20728 +f 29368/29368/20726 29370/29370/20728 29371/29371/20729 +f 29369/29369/20727 29372/29372/20730 29373/29373/20731 +f 29369/29369/20727 29373/29373/20731 29370/29370/20728 +f 29370/29370/20728 29373/29373/20731 29374/29374/20732 +f 29370/29370/20728 29374/29374/20732 29375/29375/20733 +f 29371/29371/20729 29370/29370/20728 29375/29375/20733 +f 29371/29371/20729 29375/29375/20733 29376/29376/20734 +f 29367/29367/20725 29366/29366/20724 29377/29377/20735 +f 29367/29367/20725 29377/29377/20735 29378/29378/20736 +f 29366/29366/20724 29332/29332/20692 29379/29379/20737 +f 29366/29366/20724 29379/29379/20737 29377/29377/20735 +f 29380/29380/20738 29381/29381/20737 29372/29372/20730 +f 29380/29380/20738 29372/29372/20730 29369/29369/20727 +f 29382/29382/20736 29380/29380/20738 29369/29369/20727 +f 29382/29382/20736 29369/29369/20727 29368/29368/20726 +f 29332/29332/20692 29331/29331/20691 29383/29383/20739 +f 29332/29332/20692 29383/29383/20739 29379/29379/20737 +f 29331/29331/20691 29330/29330/20690 29384/29384/20740 +f 29331/29331/20691 29384/29384/20740 29383/29383/20739 +f 29383/29383/20739 29384/29384/20740 29385/29385/20741 +f 29383/29383/20739 29385/29385/20741 29386/29386/20742 +f 29381/29381/20737 29387/29387/20739 29388/29388/20742 +f 29381/29381/20737 29388/29388/20742 29372/29372/20730 +f 29350/29350/20708 29361/29361/20719 29389/29389/20743 +f 29350/29350/20708 29389/29389/20743 29351/29351/20709 +f 29360/29360/20718 29359/29359/20717 29390/29390/20744 +f 29360/29360/20718 29390/29390/20744 29391/29391/20745 +f 29391/29391/20745 29390/29390/20744 29392/29392/20746 +f 29391/29391/20745 29392/29392/20746 29393/29393/20747 +f 29394/29394/20709 29395/29395/20745 29396/29396/20748 +f 29394/29394/20709 29396/29396/20748 29397/29397/20710 +f 29374/29374/20732 29398/29398/20749 29399/29399/20750 +f 29374/29374/20732 29399/29399/20750 29400/29400/20751 +f 29398/29398/20749 29401/29401/20752 29402/29402/20753 +f 29398/29398/20749 29402/29402/20753 29399/29399/20750 +f 29399/29399/20750 29402/29402/20753 29403/29403/20754 +f 29399/29399/20750 29403/29403/20754 29404/29404/20755 +f 29400/29400/20751 29399/29399/20750 29404/29404/20755 +f 29400/29400/20751 29404/29404/20755 29405/29405/20756 +f 29372/29372/20730 29388/29388/20742 29406/29406/20757 +f 29372/29372/20730 29406/29406/20757 29373/29373/20731 +f 29386/29386/20742 29385/29385/20741 29407/29407/20758 +f 29386/29386/20742 29407/29407/20758 29408/29408/20757 +f 29406/29406/20757 29409/29409/20759 29401/29401/20752 +f 29406/29406/20757 29401/29401/20752 29398/29398/20749 +f 29373/29373/20731 29406/29406/20757 29398/29398/20749 +f 29373/29373/20731 29398/29398/20749 29374/29374/20732 +f 29397/29397/20710 29396/29396/20748 29410/29410/20760 +f 29397/29397/20710 29410/29410/20760 29411/29411/20761 +f 29393/29393/20747 29392/29392/20746 29412/29412/20762 +f 29393/29393/20747 29412/29412/20762 29413/29413/20760 +f 29413/29413/20760 29412/29412/20762 29414/29414/20763 +f 29413/29413/20760 29414/29414/20763 29415/29415/20764 +f 29411/29411/20761 29410/29410/20760 29416/29416/20765 +f 29411/29411/20761 29416/29416/20765 29417/29417/20766 +f 29418/29418/20767 29419/29419/20711 29420/29420/20768 +f 29418/29418/20767 29420/29420/20768 29421/29421/20769 +f 29419/29419/20711 29397/29397/20710 29411/29411/20761 +f 29419/29419/20711 29411/29411/20761 29420/29420/20768 +f 29420/29420/20768 29411/29411/20761 29417/29417/20766 +f 29420/29420/20768 29417/29417/20766 29422/29422/20770 +f 29421/29421/20769 29420/29420/20768 29422/29422/20770 +f 29421/29421/20769 29422/29422/20770 29423/29423/20771 +f 29424/29424/20772 29425/29425/20773 29426/29426/20774 +f 29424/29424/20772 29426/29426/20774 29427/29427/20775 +f 29425/29425/20773 29428/29428/20776 29429/29429/20777 +f 29425/29425/20773 29429/29429/20777 29426/29426/20774 +f 29426/29426/20774 29429/29429/20777 29430/29430/20778 +f 29426/29426/20774 29430/29430/20778 29431/29431/20779 +f 29427/29427/20775 29426/29426/20774 29431/29431/20779 +f 29427/29427/20775 29431/29431/20779 29432/29432/20780 +f 29417/29417/20766 29416/29416/20765 29433/29433/20781 +f 29417/29417/20766 29433/29433/20781 29434/29434/20782 +f 29415/29415/20764 29414/29414/20763 29435/29435/20783 +f 29415/29415/20764 29435/29435/20783 29436/29436/20784 +f 29436/29436/20784 29435/29435/20783 29437/29437/20785 +f 29436/29436/20784 29437/29437/20785 29438/29438/20786 +f 29434/29434/20782 29433/29433/20781 29439/29439/20787 +f 29434/29434/20782 29439/29439/20787 29428/29428/20776 +f 29423/29423/20771 29422/29422/20770 29440/29440/20788 +f 29423/29423/20771 29440/29440/20788 29441/29441/20789 +f 29422/29422/20770 29417/29417/20766 29434/29434/20782 +f 29422/29422/20770 29434/29434/20782 29440/29440/20788 +f 29440/29440/20788 29434/29434/20782 29428/29428/20776 +f 29440/29440/20788 29428/29428/20776 29425/29425/20773 +f 29441/29441/20789 29440/29440/20788 29425/29425/20773 +f 29441/29441/20789 29425/29425/20773 29424/29424/20772 +f 29376/29376/20734 29375/29375/20733 29442/29442/20790 +f 29376/29376/20734 29442/29442/20790 29443/29443/20791 +f 29375/29375/20733 29374/29374/20732 29400/29400/20751 +f 29375/29375/20733 29400/29400/20751 29442/29442/20790 +f 29442/29442/20790 29400/29400/20751 29405/29405/20756 +f 29442/29442/20790 29405/29405/20756 29444/29444/20792 +f 29443/29443/20791 29442/29442/20790 29444/29444/20792 +f 29443/29443/20791 29444/29444/20792 29445/29445/20793 +f 29446/29446/20794 29447/29447/20795 29448/29448/20796 +f 29446/29446/20794 29448/29448/20796 29449/29449/20797 +f 29450/29450/20795 29451/29451/20798 29452/29452/20799 +f 29450/29450/20795 29452/29452/20799 29453/29453/20796 +f 29453/29453/20796 29452/29452/20799 29454/29454/20800 +f 29453/29453/20796 29454/29454/20800 29455/29455/20801 +f 29456/29456/20797 29453/29453/20796 29455/29455/20801 +f 29456/29456/20797 29455/29455/20801 29457/29457/20802 +f 29445/29445/20793 29444/29444/20792 29458/29458/20803 +f 29445/29445/20793 29458/29458/20803 29459/29459/20804 +f 29444/29444/20792 29405/29405/20756 29460/29460/20805 +f 29444/29444/20792 29460/29460/20805 29458/29458/20803 +f 29458/29458/20803 29460/29460/20805 29446/29446/20794 +f 29458/29458/20803 29446/29446/20794 29461/29461/20806 +f 29459/29459/20804 29458/29458/20803 29461/29461/20806 +f 29459/29459/20804 29461/29461/20806 29462/29462/20807 +f 29405/29405/20756 29404/29404/20755 29463/29463/20808 +f 29405/29405/20756 29463/29463/20808 29460/29460/20805 +f 29404/29404/20755 29403/29403/20754 29464/29464/20809 +f 29404/29404/20755 29464/29464/20809 29463/29463/20808 +f 29463/29463/20808 29464/29464/20809 29465/29465/20798 +f 29463/29463/20808 29465/29465/20798 29447/29447/20795 +f 29460/29460/20805 29463/29463/20808 29447/29447/20795 +f 29460/29460/20805 29447/29447/20795 29446/29446/20794 +f 29428/29428/20776 29439/29439/20787 29466/29466/20810 +f 29428/29428/20776 29466/29466/20810 29429/29429/20777 +f 29438/29438/20786 29437/29437/20785 29467/29467/20811 +f 29438/29438/20786 29467/29467/20811 29468/29468/20810 +f 29468/29468/20810 29467/29467/20811 29469/29469/20812 +f 29468/29468/20810 29469/29469/20812 29470/29470/20813 +f 29429/29429/20777 29466/29466/20810 29471/29471/20813 +f 29429/29429/20777 29471/29471/20813 29430/29430/20778 +f 29457/29457/20802 29455/29455/20801 29472/29472/20814 +f 29457/29457/20802 29472/29472/20814 29473/29473/20815 +f 29455/29455/20801 29454/29454/20800 29474/29474/20816 +f 29455/29455/20801 29474/29474/20816 29472/29472/20814 +f 29472/29472/20814 29474/29474/20816 29475/29475/20817 +f 29472/29472/20814 29475/29475/20817 29476/29476/20818 +f 29473/29473/20815 29472/29472/20814 29476/29476/20818 +f 29473/29473/20815 29476/29476/20818 29477/29477/20819 +f 29430/29430/20778 29471/29471/20813 29478/29478/20820 +f 29430/29430/20778 29478/29478/20820 29479/29479/20821 +f 29470/29470/20813 29469/29469/20812 29480/29480/20822 +f 29470/29470/20813 29480/29480/20822 29481/29481/20820 +f 29481/29481/20820 29480/29480/20822 29482/29482/20823 +f 29481/29481/20820 29482/29482/20823 29483/29483/20824 +f 29484/29484/20821 29485/29485/20820 29486/29486/20824 +f 29484/29484/20821 29486/29486/20824 29487/29487/20825 +f 29432/29432/20780 29431/29431/20779 29488/29488/20826 +f 29432/29432/20780 29488/29488/20826 29489/29489/20827 +f 29431/29431/20779 29430/29430/20778 29479/29479/20821 +f 29431/29431/20779 29479/29479/20821 29488/29488/20826 +f 29490/29490/20826 29484/29484/20821 29487/29487/20825 +f 29490/29490/20826 29487/29487/20825 29491/29491/20828 +f 29492/29492/20827 29490/29490/20826 29491/29491/20828 +f 29492/29492/20827 29491/29491/20828 29493/29493/20829 +f 29462/29462/20807 29461/29461/20806 29494/29494/20830 +f 29462/29462/20807 29494/29494/20830 29495/29495/20831 +f 29461/29461/20806 29446/29446/20794 29449/29449/20797 +f 29461/29461/20806 29449/29449/20797 29494/29494/20830 +f 29496/29496/20830 29456/29456/20797 29457/29457/20802 +f 29496/29496/20830 29457/29457/20802 29497/29497/20832 +f 29495/29495/20831 29494/29494/20830 29498/29498/20832 +f 29495/29495/20831 29498/29498/20832 29499/29499/20833 +f 29500/29500/20834 29501/29501/20835 29502/29502/20836 +f 29500/29500/20834 29502/29502/20836 29503/29503/20837 +f 29501/29501/20835 29504/29504/20838 29505/29505/20839 +f 29501/29501/20835 29505/29505/20839 29502/29502/20836 +f 29502/29502/20836 29505/29505/20839 29506/29506/20840 +f 29502/29502/20836 29506/29506/20840 29507/29507/20841 +f 29503/29503/20837 29502/29502/20836 29507/29507/20841 +f 29503/29503/20837 29507/29507/20841 29508/29508/20842 +f 29487/29487/20825 29486/29486/20824 29509/29509/20843 +f 29487/29487/20825 29509/29509/20843 29510/29510/20844 +f 29483/29483/20824 29482/29482/20823 29511/29511/20845 +f 29483/29483/20824 29511/29511/20845 29512/29512/20843 +f 29512/29512/20843 29511/29511/20845 29513/29513/20846 +f 29512/29512/20843 29513/29513/20846 29514/29514/20847 +f 29510/29510/20844 29509/29509/20843 29515/29515/20848 +f 29510/29510/20844 29515/29515/20848 29504/29504/20838 +f 29493/29493/20829 29491/29491/20828 29516/29516/20849 +f 29493/29493/20829 29516/29516/20849 29517/29517/20850 +f 29491/29491/20828 29487/29487/20825 29510/29510/20844 +f 29491/29491/20828 29510/29510/20844 29516/29516/20849 +f 29516/29516/20849 29510/29510/20844 29504/29504/20838 +f 29516/29516/20849 29504/29504/20838 29501/29501/20835 +f 29517/29517/20850 29516/29516/20849 29501/29501/20835 +f 29517/29517/20850 29501/29501/20835 29500/29500/20834 +f 29518/29518/20833 29497/29497/20832 29519/29519/20851 +f 29518/29518/20833 29519/29519/20851 29520/29520/20852 +f 29497/29497/20832 29457/29457/20802 29473/29473/20815 +f 29497/29497/20832 29473/29473/20815 29519/29519/20851 +f 29519/29519/20851 29473/29473/20815 29477/29477/20819 +f 29519/29519/20851 29477/29477/20819 29521/29521/20853 +f 29520/29520/20852 29519/29519/20851 29521/29521/20853 +f 29520/29520/20852 29521/29521/20853 29522/29522/20854 +f 29523/29523/20855 29524/29524/20856 29525/29525/20857 +f 29523/29523/20855 29525/29525/20857 29526/29526/20858 +f 29524/29524/20856 29527/29527/20859 29528/29528/20860 +f 29524/29524/20856 29528/29528/20860 29525/29525/20857 +f 29525/29525/20857 29528/29528/20860 29529/29529/20861 +f 29525/29525/20857 29529/29529/20861 29530/29530/20862 +f 29526/29526/20858 29525/29525/20857 29530/29530/20862 +f 29526/29526/20858 29530/29530/20862 29531/29531/20863 +f 29522/29522/20854 29521/29521/20853 29532/29532/20864 +f 29522/29522/20854 29532/29532/20864 29533/29533/20865 +f 29521/29521/20853 29477/29477/20819 29534/29534/20866 +f 29521/29521/20853 29534/29534/20866 29532/29532/20864 +f 29532/29532/20864 29534/29534/20866 29523/29523/20855 +f 29532/29532/20864 29523/29523/20855 29535/29535/20867 +f 29533/29533/20865 29532/29532/20864 29535/29535/20867 +f 29533/29533/20865 29535/29535/20867 29536/29536/20868 +f 29477/29477/20819 29476/29476/20818 29537/29537/20869 +f 29477/29477/20819 29537/29537/20869 29534/29534/20866 +f 29476/29476/20818 29475/29475/20817 29538/29538/20870 +f 29476/29476/20818 29538/29538/20870 29537/29537/20869 +f 29537/29537/20869 29538/29538/20870 29527/29527/20859 +f 29537/29537/20869 29527/29527/20859 29524/29524/20856 +f 29534/29534/20866 29537/29537/20869 29524/29524/20856 +f 29534/29534/20866 29524/29524/20856 29523/29523/20855 +f 29504/29504/20838 29515/29515/20848 29539/29539/20871 +f 29504/29504/20838 29539/29539/20871 29505/29505/20839 +f 29514/29514/20847 29513/29513/20846 29540/29540/20872 +f 29514/29514/20847 29540/29540/20872 29541/29541/20873 +f 29541/29541/20873 29540/29540/20872 29542/29542/20874 +f 29541/29541/20873 29542/29542/20874 29543/29543/20875 +f 29505/29505/20839 29539/29539/20871 29544/29544/20876 +f 29505/29505/20839 29544/29544/20876 29506/29506/20840 +f 29545/29545/20877 29546/29546/20878 29547/29547/20879 +f 29545/29545/20877 29547/29547/20879 29548/29548/20880 +f 29549/29549/20878 29550/29550/20881 29551/29551/20882 +f 29549/29549/20878 29551/29551/20882 29552/29552/20883 +f 29552/29552/20883 29551/29551/20882 29553/29553/20884 +f 29552/29552/20883 29553/29553/20884 29554/29554/20885 +f 29555/29555/20886 29556/29556/20883 29557/29557/20885 +f 29555/29555/20886 29557/29557/20885 29558/29558/20887 +f 29506/29506/20840 29544/29544/20876 29559/29559/20888 +f 29506/29506/20840 29559/29559/20888 29560/29560/20889 +f 29543/29543/20875 29542/29542/20874 29561/29561/20890 +f 29543/29543/20875 29561/29561/20890 29562/29562/20891 +f 29562/29562/20891 29561/29561/20890 29550/29550/20881 +f 29562/29562/20891 29550/29550/20881 29549/29549/20878 +f 29560/29560/20889 29559/29559/20888 29546/29546/20878 +f 29560/29560/20889 29546/29546/20878 29545/29545/20877 +f 29508/29508/20842 29507/29507/20841 29563/29563/20892 +f 29508/29508/20842 29563/29563/20892 29564/29564/20893 +f 29507/29507/20841 29506/29506/20840 29560/29560/20889 +f 29507/29507/20841 29560/29560/20889 29563/29563/20892 +f 29563/29563/20892 29560/29560/20889 29545/29545/20877 +f 29563/29563/20892 29545/29545/20877 29565/29565/20894 +f 29564/29564/20893 29563/29563/20892 29565/29565/20894 +f 29564/29564/20893 29565/29565/20894 29566/29566/20895 +f 29536/29536/20868 29535/29535/20867 29567/29567/20896 +f 29536/29536/20868 29567/29567/20896 29568/29568/20897 +f 29535/29535/20867 29523/29523/20855 29526/29526/20858 +f 29535/29535/20867 29526/29526/20858 29567/29567/20896 +f 29567/29567/20896 29526/29526/20858 29531/29531/20863 +f 29567/29567/20896 29531/29531/20863 29569/29569/20898 +f 29568/29568/20897 29567/29567/20896 29569/29569/20898 +f 29568/29568/20897 29569/29569/20898 29570/29570/20899 +f 29571/29571/20900 29572/29572/20901 29573/29573/20902 +f 29571/29571/20900 29573/29573/20902 29574/29574/20903 +f 29572/29572/20901 29558/29558/20887 29575/29575/20904 +f 29572/29572/20901 29575/29575/20904 29573/29573/20902 +f 29573/29573/20902 29575/29575/20904 29576/29576/20905 +f 29573/29573/20902 29576/29576/20905 29577/29577/20906 +f 29574/29574/20903 29573/29573/20902 29577/29577/20906 +f 29574/29574/20903 29577/29577/20906 29578/29578/20907 +f 29566/29566/20895 29565/29565/20894 29579/29579/20908 +f 29566/29566/20895 29579/29579/20908 29580/29580/20909 +f 29565/29565/20894 29545/29545/20877 29548/29548/20880 +f 29565/29565/20894 29548/29548/20880 29579/29579/20908 +f 29581/29581/20908 29555/29555/20886 29558/29558/20887 +f 29581/29581/20908 29558/29558/20887 29572/29572/20901 +f 29582/29582/20910 29581/29581/20908 29572/29572/20901 +f 29582/29582/20910 29572/29572/20901 29571/29571/20900 +f 29570/29570/20899 29569/29569/20898 29583/29583/20911 +f 29570/29570/20899 29583/29583/20911 29584/29584/20912 +f 29569/29569/20898 29531/29531/20863 29585/29585/20913 +f 29569/29569/20898 29585/29585/20913 29583/29583/20911 +f 29586/29586/20911 29587/29587/20913 29588/29588/20914 +f 29586/29586/20911 29588/29588/20914 29589/29589/20915 +f 29590/29590/20912 29586/29586/20911 29589/29589/20915 +f 29590/29590/20912 29589/29589/20915 29591/29591/20916 +f 29531/29531/20863 29530/29530/20862 29592/29592/20917 +f 29531/29531/20863 29592/29592/20917 29585/29585/20913 +f 29530/29530/20862 29529/29529/20861 29593/29593/20918 +f 29530/29530/20862 29593/29593/20918 29592/29592/20917 +f 29592/29592/20917 29593/29593/20918 29594/29594/20919 +f 29592/29592/20917 29594/29594/20919 29595/29595/20920 +f 29587/29587/20913 29596/29596/20921 29597/29597/20922 +f 29587/29587/20913 29597/29597/20922 29588/29588/20914 +f 29598/29598/20923 29599/29599/20924 29600/29600/20925 +f 29598/29598/20923 29600/29600/20925 29601/29601/20926 +f 29599/29599/20924 29602/29602/20927 29603/29603/20928 +f 29599/29599/20924 29603/29603/20928 29600/29600/20925 +f 29604/29604/20929 29605/29605/20930 29606/29606/20931 +f 29604/29604/20929 29606/29606/20931 29607/29607/20932 +f 29601/29601/20926 29600/29600/20925 29608/29608/20933 +f 29601/29601/20926 29608/29608/20933 29609/29609/20934 +f 29591/29591/20916 29589/29589/20915 29610/29610/20935 +f 29591/29591/20916 29610/29610/20935 29611/29611/20936 +f 29589/29589/20915 29588/29588/20914 29612/29612/20937 +f 29589/29589/20915 29612/29612/20937 29610/29610/20935 +f 29610/29610/20935 29612/29612/20937 29598/29598/20923 +f 29610/29610/20935 29598/29598/20923 29613/29613/20938 +f 29611/29611/20936 29610/29610/20935 29613/29613/20938 +f 29611/29611/20936 29613/29613/20938 29614/29614/20939 +f 29588/29588/20914 29597/29597/20922 29615/29615/20940 +f 29588/29588/20914 29615/29615/20940 29612/29612/20937 +f 29597/29597/20922 29616/29616/20919 29617/29617/20941 +f 29597/29597/20922 29617/29617/20941 29615/29615/20940 +f 29615/29615/20940 29617/29617/20941 29602/29602/20927 +f 29615/29615/20940 29602/29602/20927 29599/29599/20924 +f 29612/29612/20937 29615/29615/20940 29599/29599/20924 +f 29612/29612/20937 29599/29599/20924 29598/29598/20923 +f 29558/29558/20887 29557/29557/20885 29618/29618/20942 +f 29558/29558/20887 29618/29618/20942 29575/29575/20904 +f 29554/29554/20885 29553/29553/20884 29619/29619/20943 +f 29554/29554/20885 29619/29619/20943 29620/29620/20942 +f 29620/29620/20942 29619/29619/20943 29621/29621/20944 +f 29620/29620/20942 29621/29621/20944 29622/29622/20945 +f 29575/29575/20904 29618/29618/20942 29623/29623/20946 +f 29575/29575/20904 29623/29623/20946 29576/29576/20905 +f 29624/29624/20947 29625/29625/20948 29626/29626/20949 +f 29624/29624/20947 29626/29626/20949 29627/29627/20950 +f 29625/29625/20948 29628/29628/20951 29629/29629/20952 +f 29625/29625/20948 29629/29629/20952 29626/29626/20949 +f 29626/29626/20949 29629/29629/20952 29630/29630/20953 +f 29626/29626/20949 29630/29630/20953 29631/29631/20954 +f 29627/29627/20950 29626/29626/20949 29631/29631/20954 +f 29627/29627/20950 29631/29631/20954 29632/29632/20955 +f 29576/29576/20905 29623/29623/20946 29633/29633/20956 +f 29576/29576/20905 29633/29633/20956 29634/29634/20957 +f 29622/29622/20945 29621/29621/20944 29635/29635/20958 +f 29622/29622/20945 29635/29635/20958 29636/29636/20959 +f 29636/29636/20959 29635/29635/20958 29637/29637/20960 +f 29636/29636/20959 29637/29637/20960 29638/29638/20961 +f 29634/29634/20957 29633/29633/20956 29639/29639/20962 +f 29634/29634/20957 29639/29639/20962 29640/29640/20951 +f 29578/29578/20907 29577/29577/20906 29641/29641/20963 +f 29578/29578/20907 29641/29641/20963 29642/29642/20964 +f 29577/29577/20906 29576/29576/20905 29634/29634/20957 +f 29577/29577/20906 29634/29634/20957 29641/29641/20963 +f 29641/29641/20963 29634/29634/20957 29640/29640/20951 +f 29641/29641/20963 29640/29640/20951 29643/29643/20965 +f 29642/29642/20964 29641/29641/20963 29643/29643/20965 +f 29642/29642/20964 29643/29643/20965 29644/29644/20947 +f 29614/29614/20939 29613/29613/20938 29645/29645/20966 +f 29614/29614/20939 29645/29645/20966 29646/29646/20967 +f 29613/29613/20938 29598/29598/20923 29601/29601/20926 +f 29613/29613/20938 29601/29601/20926 29645/29645/20966 +f 29645/29645/20966 29601/29601/20926 29609/29609/20934 +f 29645/29645/20966 29609/29609/20934 29647/29647/20968 +f 29646/29646/20967 29645/29645/20966 29647/29647/20968 +f 29646/29646/20967 29647/29647/20968 29648/29648/20969 +f 29649/29649/20970 29650/29650/20971 29651/29651/20972 +f 29649/29649/20970 29651/29651/20972 29652/29652/20973 +f 29650/29650/20971 29653/29653/20974 29654/29654/20975 +f 29650/29650/20971 29654/29654/20975 29651/29651/20972 +f 29651/29651/20972 29654/29654/20975 29655/29655/20976 +f 29651/29651/20972 29655/29655/20976 29656/29656/20977 +f 29652/29652/20973 29651/29651/20972 29656/29656/20977 +f 29652/29652/20973 29656/29656/20977 29657/29657/20978 +f 29648/29648/20969 29647/29647/20968 29658/29658/20979 +f 29648/29648/20969 29658/29658/20979 29659/29659/20980 +f 29647/29647/20968 29609/29609/20934 29660/29660/20981 +f 29647/29647/20968 29660/29660/20981 29658/29658/20979 +f 29661/29661/20982 29662/29662/20983 29653/29653/20974 +f 29661/29661/20982 29653/29653/20974 29650/29650/20971 +f 29663/29663/20980 29661/29661/20982 29650/29650/20971 +f 29663/29663/20980 29650/29650/20971 29649/29649/20970 +f 29609/29609/20934 29608/29608/20933 29664/29664/20984 +f 29609/29609/20934 29664/29664/20984 29660/29660/20981 +f 29607/29607/20932 29606/29606/20931 29665/29665/20985 +f 29607/29607/20932 29665/29665/20985 29666/29666/20984 +f 29666/29666/20984 29665/29665/20985 29667/29667/20986 +f 29666/29666/20984 29667/29667/20986 29668/29668/20987 +f 29662/29662/20983 29666/29666/20984 29668/29668/20987 +f 29662/29662/20983 29668/29668/20987 29653/29653/20974 +f 29628/29628/20951 29669/29669/20988 29670/29670/20989 +f 29628/29628/20951 29670/29670/20989 29629/29629/20952 +f 29638/29638/20961 29637/29637/20960 29671/29671/20990 +f 29638/29638/20961 29671/29671/20990 29672/29672/20989 +f 29672/29672/20989 29671/29671/20990 29673/29673/20991 +f 29672/29672/20989 29673/29673/20991 29674/29674/20992 +f 29629/29629/20952 29670/29670/20989 29675/29675/20992 +f 29629/29629/20952 29675/29675/20992 29630/29630/20953 +f 29655/29655/20976 29676/29676/20993 29677/29677/20994 +f 29655/29655/20976 29677/29677/20994 29678/29678/20995 +f 29676/29676/20993 29679/29679/20996 29680/29680/20997 +f 29676/29676/20993 29680/29680/20997 29677/29677/20994 +f 29677/29677/20994 29680/29680/20997 29681/29681/20998 +f 29677/29677/20994 29681/29681/20998 29682/29682/20999 +f 29683/29683/20995 29684/29684/21000 29685/29685/21001 +f 29683/29683/20995 29685/29685/21001 29686/29686/21002 +f 29653/29653/20974 29668/29668/20987 29687/29687/21003 +f 29653/29653/20974 29687/29687/21003 29654/29654/20975 +f 29668/29668/20987 29667/29667/20986 29688/29688/21004 +f 29668/29668/20987 29688/29688/21004 29687/29687/21003 +f 29687/29687/21003 29688/29688/21004 29679/29679/20996 +f 29687/29687/21003 29679/29679/20996 29676/29676/20993 +f 29654/29654/20975 29687/29687/21003 29676/29676/20993 +f 29654/29654/20975 29676/29676/20993 29655/29655/20976 +f 29630/29630/20953 29675/29675/20992 29689/29689/21005 +f 29630/29630/20953 29689/29689/21005 29690/29690/21006 +f 29674/29674/20992 29673/29673/20991 29691/29691/21007 +f 29674/29674/20992 29691/29691/21007 29692/29692/21008 +f 29692/29692/21008 29691/29691/21007 29693/29693/21009 +f 29692/29692/21008 29693/29693/21009 29694/29694/21010 +f 29690/29690/21006 29689/29689/21005 29695/29695/21011 +f 29690/29690/21006 29695/29695/21011 29696/29696/21012 +f 29632/29632/20955 29631/29631/20954 29697/29697/21013 +f 29632/29632/20955 29697/29697/21013 29698/29698/21014 +f 29631/29631/20954 29630/29630/20953 29690/29690/21006 +f 29631/29631/20954 29690/29690/21006 29697/29697/21013 +f 29697/29697/21013 29690/29690/21006 29696/29696/21012 +f 29697/29697/21013 29696/29696/21012 29699/29699/21015 +f 29698/29698/21014 29697/29697/21013 29699/29699/21015 +f 29698/29698/21014 29699/29699/21015 29700/29700/21016 +f 29701/29701/21017 29702/29702/21018 29703/29703/21019 +f 29701/29701/21017 29703/29703/21019 29704/29704/21020 +f 29702/29702/21018 29705/29705/21021 29706/29706/21022 +f 29702/29702/21018 29706/29706/21022 29703/29703/21019 +f 29703/29703/21019 29706/29706/21022 29707/29707/21023 +f 29703/29703/21019 29707/29707/21023 29708/29708/21024 +f 29704/29704/21020 29703/29703/21019 29708/29708/21024 +f 29704/29704/21020 29708/29708/21024 29709/29709/21025 +f 29696/29696/21012 29695/29695/21011 29710/29710/21026 +f 29696/29696/21012 29710/29710/21026 29711/29711/21027 +f 29694/29694/21010 29693/29693/21009 29712/29712/21028 +f 29694/29694/21010 29712/29712/21028 29713/29713/21029 +f 29713/29713/21029 29712/29712/21028 29714/29714/21030 +f 29713/29713/21029 29714/29714/21030 29715/29715/21031 +f 29711/29711/21027 29710/29710/21026 29716/29716/21032 +f 29711/29711/21027 29716/29716/21032 29717/29717/21033 +f 29700/29700/21016 29699/29699/21015 29718/29718/21034 +f 29700/29700/21016 29718/29718/21034 29719/29719/21035 +f 29699/29699/21015 29696/29696/21012 29711/29711/21027 +f 29699/29699/21015 29711/29711/21027 29718/29718/21034 +f 29718/29718/21034 29711/29711/21027 29717/29717/21033 +f 29718/29718/21034 29717/29717/21033 29720/29720/21018 +f 29719/29719/21035 29718/29718/21034 29720/29720/21018 +f 29719/29719/21035 29720/29720/21018 29721/29721/21017 +f 29657/29657/20978 29656/29656/20977 29722/29722/21036 +f 29657/29657/20978 29722/29722/21036 29723/29723/21037 +f 29656/29656/20977 29655/29655/20976 29678/29678/20995 +f 29656/29656/20977 29678/29678/20995 29722/29722/21036 +f 29724/29724/21038 29683/29683/20995 29686/29686/21002 +f 29724/29724/21038 29686/29686/21002 29725/29725/21039 +f 29726/29726/21040 29724/29724/21038 29725/29725/21039 +f 29726/29726/21040 29725/29725/21039 29727/29727/21041 +f 29728/29728/21042 29729/29729/21043 29730/29730/21044 +f 29728/29728/21042 29730/29730/21044 29731/29731/21045 +f 29732/29732/21046 29733/29733/21047 29734/29734/21048 +f 29732/29732/21046 29734/29734/21048 29735/29735/21044 +f 29735/29735/21044 29734/29734/21048 29736/29736/21049 +f 29735/29735/21044 29736/29736/21049 29737/29737/21050 +f 29738/29738/21045 29735/29735/21044 29737/29737/21050 +f 29738/29738/21045 29737/29737/21050 29739/29739/21051 +f 29727/29727/21041 29725/29725/21039 29740/29740/21052 +f 29727/29727/21041 29740/29740/21052 29741/29741/21053 +f 29725/29725/21039 29686/29686/21002 29742/29742/21054 +f 29725/29725/21039 29742/29742/21054 29740/29740/21052 +f 29740/29740/21052 29742/29742/21054 29728/29728/21042 +f 29740/29740/21052 29728/29728/21042 29743/29743/21055 +f 29741/29741/21053 29740/29740/21052 29743/29743/21055 +f 29741/29741/21053 29743/29743/21055 29744/29744/21056 +f 29686/29686/21002 29685/29685/21001 29745/29745/21057 +f 29686/29686/21002 29745/29745/21057 29742/29742/21054 +f 29685/29685/21001 29746/29746/20998 29747/29747/21058 +f 29685/29685/21001 29747/29747/21058 29745/29745/21057 +f 29745/29745/21057 29747/29747/21058 29748/29748/21059 +f 29745/29745/21057 29748/29748/21059 29729/29729/21043 +f 29742/29742/21054 29745/29745/21057 29729/29729/21043 +f 29742/29742/21054 29729/29729/21043 29728/29728/21042 +f 29705/29705/21021 29749/29749/21031 29750/29750/21060 +f 29705/29705/21021 29750/29750/21060 29706/29706/21022 +f 29715/29715/21031 29714/29714/21030 29751/29751/21061 +f 29715/29715/21031 29751/29751/21061 29752/29752/21062 +f 29752/29752/21062 29751/29751/21061 29753/29753/21063 +f 29752/29752/21062 29753/29753/21063 29754/29754/21064 +f 29706/29706/21022 29750/29750/21060 29755/29755/21064 +f 29706/29706/21022 29755/29755/21064 29707/29707/21023 +f 29739/29739/21051 29737/29737/21050 29756/29756/21065 +f 29739/29739/21051 29756/29756/21065 29757/29757/21066 +f 29737/29737/21050 29736/29736/21049 29758/29758/21067 +f 29737/29737/21050 29758/29758/21067 29756/29756/21065 +f 29756/29756/21065 29758/29758/21067 29759/29759/21068 +f 29756/29756/21065 29759/29759/21068 29760/29760/21069 +f 29757/29757/21066 29756/29756/21065 29760/29760/21069 +f 29757/29757/21066 29760/29760/21069 29761/29761/21070 +f 29762/29762/21071 29763/29763/21072 29764/29764/21073 +f 29762/29762/21071 29764/29764/21073 29765/29765/21074 +f 29754/29754/21064 29753/29753/21063 29766/29766/21075 +f 29754/29754/21064 29766/29766/21075 29767/29767/21073 +f 29767/29767/21073 29766/29766/21075 29768/29768/21076 +f 29767/29767/21073 29768/29768/21076 29769/29769/21077 +f 29765/29765/21074 29764/29764/21073 29770/29770/21078 +f 29765/29765/21074 29770/29770/21078 29771/29771/21079 +f 29709/29709/21025 29708/29708/21024 29772/29772/21080 +f 29709/29709/21025 29772/29772/21080 29773/29773/21081 +f 29708/29708/21024 29707/29707/21023 29774/29774/21074 +f 29708/29708/21024 29774/29774/21074 29772/29772/21080 +f 29775/29775/21080 29765/29765/21074 29771/29771/21079 +f 29775/29775/21080 29771/29771/21079 29776/29776/21082 +f 29777/29777/21083 29775/29775/21080 29776/29776/21082 +f 29777/29777/21083 29776/29776/21082 29778/29778/21084 +f 29744/29744/21056 29743/29743/21055 29779/29779/21085 +f 29744/29744/21056 29779/29779/21085 29780/29780/21086 +f 29743/29743/21055 29728/29728/21042 29731/29731/21045 +f 29743/29743/21055 29731/29731/21045 29779/29779/21085 +f 29781/29781/21085 29738/29738/21045 29739/29739/21051 +f 29781/29781/21085 29739/29739/21051 29782/29782/21087 +f 29783/29783/21086 29781/29781/21085 29782/29782/21087 +f 29783/29783/21086 29782/29782/21087 29784/29784/21088 +f 29785/29785/21089 29786/29786/21090 29787/29787/21091 +f 29785/29785/21089 29787/29787/21091 29788/29788/21092 +f 29786/29786/21090 29789/29789/21093 29790/29790/21094 +f 29786/29786/21090 29790/29790/21094 29787/29787/21091 +f 29787/29787/21091 29790/29790/21094 29791/29791/21095 +f 29787/29787/21091 29791/29791/21095 29792/29792/21096 +f 29788/29788/21092 29787/29787/21091 29792/29792/21096 +f 29788/29788/21092 29792/29792/21096 29793/29793/21097 +f 29771/29771/21079 29770/29770/21078 29794/29794/21098 +f 29771/29771/21079 29794/29794/21098 29795/29795/21099 +f 29769/29769/21077 29768/29768/21076 29796/29796/21100 +f 29769/29769/21077 29796/29796/21100 29797/29797/21098 +f 29797/29797/21098 29796/29796/21100 29798/29798/21101 +f 29797/29797/21098 29798/29798/21101 29799/29799/21102 +f 29795/29795/21099 29794/29794/21098 29800/29800/21102 +f 29795/29795/21099 29800/29800/21102 29801/29801/21103 +f 29778/29778/21084 29776/29776/21082 29802/29802/21104 +f 29778/29778/21084 29802/29802/21104 29803/29803/21105 +f 29776/29776/21082 29771/29771/21079 29795/29795/21099 +f 29776/29776/21082 29795/29795/21099 29802/29802/21104 +f 29802/29802/21104 29795/29795/21099 29801/29801/21103 +f 29802/29802/21104 29801/29801/21103 29804/29804/21090 +f 29803/29803/21105 29802/29802/21104 29804/29804/21090 +f 29803/29803/21105 29804/29804/21090 29805/29805/21106 +f 29784/29784/21088 29782/29782/21087 29806/29806/21107 +f 29784/29784/21088 29806/29806/21107 29807/29807/21108 +f 29782/29782/21087 29739/29739/21051 29757/29757/21066 +f 29782/29782/21087 29757/29757/21066 29806/29806/21107 +f 29806/29806/21107 29757/29757/21066 29761/29761/21070 +f 29806/29806/21107 29761/29761/21070 29808/29808/21109 +f 29807/29807/21108 29806/29806/21107 29808/29808/21109 +f 29807/29807/21108 29808/29808/21109 29809/29809/21110 +f 29810/29810/21111 29811/29811/21112 29812/29812/21113 +f 29810/29810/21111 29812/29812/21113 29813/29813/21114 +f 29811/29811/21112 29814/29814/21115 29815/29815/21116 +f 29811/29811/21112 29815/29815/21116 29812/29812/21113 +f 29812/29812/21113 29815/29815/21116 29816/29816/21117 +f 29812/29812/21113 29816/29816/21117 29817/29817/21118 +f 29813/29813/21114 29812/29812/21113 29817/29817/21118 +f 29813/29813/21114 29817/29817/21118 29818/29818/21119 +f 29809/29809/21110 29808/29808/21109 29819/29819/21120 +f 29809/29809/21110 29819/29819/21120 29820/29820/21121 +f 29808/29808/21109 29761/29761/21070 29821/29821/21122 +f 29808/29808/21109 29821/29821/21122 29819/29819/21120 +f 29822/29822/21120 29823/29823/21122 29824/29824/21123 +f 29822/29822/21120 29824/29824/21123 29825/29825/21124 +f 29826/29826/21121 29822/29822/21120 29825/29825/21124 +f 29826/29826/21121 29825/29825/21124 29827/29827/21125 +f 29761/29761/21070 29760/29760/21069 29828/29828/21126 +f 29761/29761/21070 29828/29828/21126 29821/29821/21122 +f 29829/29829/21127 29830/29830/21068 29831/29831/21128 +f 29829/29829/21127 29831/29831/21128 29832/29832/21126 +f 29832/29832/21126 29831/29831/21128 29833/29833/21129 +f 29832/29832/21126 29833/29833/21129 29834/29834/21130 +f 29823/29823/21122 29832/29832/21126 29834/29834/21130 +f 29823/29823/21122 29834/29834/21130 29824/29824/21123 +f 29789/29789/21093 29835/29835/21102 29836/29836/21131 +f 29789/29789/21093 29836/29836/21131 29790/29790/21094 +f 29799/29799/21102 29798/29798/21101 29837/29837/21132 +f 29799/29799/21102 29837/29837/21132 29838/29838/21133 +f 29838/29838/21133 29837/29837/21132 29839/29839/21134 +f 29838/29838/21133 29839/29839/21134 29840/29840/21135 +f 29790/29790/21094 29836/29836/21131 29841/29841/21136 +f 29790/29790/21094 29841/29841/21136 29791/29791/21095 +f 29842/29842/21137 29843/29843/21138 29844/29844/21139 +f 29842/29842/21137 29844/29844/21139 29845/29845/21140 +f 29846/29846/21141 29847/29847/21142 29848/29848/21143 +f 29846/29846/21141 29848/29848/21143 29849/29849/21144 +f 29849/29849/21144 29848/29848/21143 29850/29850/21145 +f 29849/29849/21144 29850/29850/21145 29851/29851/21146 +f 29845/29845/21140 29844/29844/21139 29852/29852/21147 +f 29845/29845/21140 29852/29852/21147 29853/29853/21148 +f 29827/29827/21125 29825/29825/21124 29854/29854/21149 +f 29827/29827/21125 29854/29854/21149 29855/29855/21150 +f 29825/29825/21124 29824/29824/21123 29834/29834/21130 +f 29825/29825/21124 29834/29834/21130 29854/29854/21149 +f 29856/29856/21149 29857/29857/21151 29858/29858/21129 +f 29856/29856/21149 29858/29858/21129 29859/29859/21152 +f 29860/29860/21150 29856/29856/21149 29859/29859/21152 +f 29860/29860/21150 29859/29859/21152 29861/29861/21153 +f 29862/29862/21154 29863/29863/21155 29864/29864/21156 +f 29862/29862/21154 29864/29864/21156 29865/29865/21157 +f 29863/29863/21155 29853/29853/21148 29852/29852/21147 +f 29863/29863/21155 29852/29852/21147 29864/29864/21156 +f 29864/29864/21156 29852/29852/21147 29866/29866/21158 +f 29864/29864/21156 29866/29866/21158 29867/29867/21159 +f 29865/29865/21157 29864/29864/21156 29867/29867/21159 +f 29865/29865/21157 29867/29867/21159 29868/29868/21160 +f 29869/29869/21161 29870/29870/21162 29871/29871/21163 +f 29869/29869/21161 29871/29871/21163 29872/29872/21164 +f 29870/29870/21162 29873/29873/21165 29874/29874/21166 +f 29870/29870/21162 29874/29874/21166 29871/29871/21163 +f 29871/29871/21163 29874/29874/21166 29875/29875/21167 +f 29871/29871/21163 29875/29875/21167 29843/29843/21138 +f 29872/29872/21164 29871/29871/21163 29843/29843/21138 +f 29872/29872/21164 29843/29843/21138 29842/29842/21137 +f 29876/29876/21168 29877/29877/21169 29878/29878/21170 +f 29876/29876/21168 29878/29878/21170 29879/29879/21171 +f 29880/29880/21169 29881/29881/21172 29882/29882/21173 +f 29880/29880/21169 29882/29882/21173 29883/29883/21170 +f 29878/29878/21170 29884/29884/21173 29873/29873/21165 +f 29878/29878/21170 29873/29873/21165 29870/29870/21162 +f 29879/29879/21171 29878/29878/21170 29870/29870/21162 +f 29879/29879/21171 29870/29870/21162 29869/29869/21161 +f 29885/29885/21174 29886/29886/21175 29887/29887/21176 +f 29885/29885/21174 29887/29887/21176 29888/29888/21177 +f 29889/29889/21175 29890/29890/21178 29891/29891/21179 +f 29889/29889/21175 29891/29891/21179 29892/29892/21176 +f 29893/29893/21176 29894/29894/21180 29895/29895/21181 +f 29893/29893/21176 29895/29895/21181 29896/29896/21182 +f 29888/29888/21177 29887/29887/21176 29897/29897/21182 +f 29888/29888/21177 29897/29897/21182 29898/29898/21183 +f 29899/29899/21184 29900/29900/21185 29901/29901/21186 +f 29899/29899/21184 29901/29901/21186 29902/29902/21187 +f 29900/29900/21185 29903/29903/21188 29904/29904/21189 +f 29900/29900/21185 29904/29904/21189 29901/29901/21186 +f 29901/29901/21186 29904/29904/21189 29881/29881/21172 +f 29901/29901/21186 29881/29881/21172 29880/29880/21169 +f 29902/29902/21187 29901/29901/21186 29880/29880/21169 +f 29902/29902/21187 29880/29880/21169 29905/29905/21190 +f 29906/29906/21191 29907/29907/21192 29908/29908/21193 +f 29906/29906/21191 29908/29908/21193 29909/29909/21194 +f 29910/29910/21192 29911/29911/21195 29912/29912/21196 +f 29910/29910/21192 29912/29912/21196 29913/29913/21197 +f 29914/29914/21198 29915/29915/21199 29916/29916/21200 +f 29914/29914/21198 29916/29916/21200 29917/29917/21201 +f 29909/29909/21194 29908/29908/21193 29918/29918/21202 +f 29909/29909/21194 29918/29918/21202 29919/29919/21203 +f 29919/29919/21203 29918/29918/21202 29920/29920/21204 +f 29919/29919/21203 29920/29920/21204 29921/29921/21205 +f 29917/29917/21201 29916/29916/21200 29922/29922/21206 +f 29917/29917/21201 29922/29922/21206 29923/29923/21207 +f 29923/29923/21207 29922/29922/21206 29890/29890/21178 +f 29923/29923/21207 29890/29890/21178 29889/29889/21175 +f 29921/29921/21205 29920/29920/21204 29886/29886/21175 +f 29921/29921/21205 29886/29886/21175 29885/29885/21174 +f 29924/29924/21208 29925/29925/21209 29926/29926/21210 +f 29924/29924/21208 29926/29926/21210 29927/29927/21211 +f 29925/29925/21209 29928/29928/21212 29929/29929/21213 +f 29925/29925/21209 29929/29929/21213 29926/29926/21210 +f 29926/29926/21210 29929/29929/21213 29930/29930/21214 +f 29926/29926/21210 29930/29930/21214 29931/29931/21215 +f 29927/29927/21211 29926/29926/21210 29931/29931/21215 +f 29927/29927/21211 29931/29931/21215 29932/29932/21184 +f 29933/29933/21216 29934/29934/21217 29935/29935/21218 +f 29933/29933/21216 29935/29935/21218 29936/29936/21219 +f 29934/29934/21217 29937/29937/21220 29938/29938/21221 +f 29934/29934/21217 29938/29938/21221 29935/29935/21218 +f 29935/29935/21218 29938/29938/21221 29928/29928/21212 +f 29935/29935/21218 29928/29928/21212 29925/29925/21209 +f 29936/29936/21219 29935/29935/21218 29925/29925/21209 +f 29936/29936/21219 29925/29925/21209 29924/29924/21208 +f 29939/29939/21222 29940/29940/21223 29941/29941/21224 +f 29939/29939/21222 29941/29941/21224 29942/29942/21225 +f 29943/29943/21226 29944/29944/21227 29945/29945/21228 +f 29943/29943/21226 29945/29945/21228 29946/29946/21229 +f 29946/29946/21229 29945/29945/21228 29947/29947/21230 +f 29946/29946/21229 29947/29947/21230 29948/29948/21231 +f 29942/29942/21225 29941/29941/21224 29949/29949/21232 +f 29942/29942/21225 29949/29949/21232 29950/29950/21233 +f 29950/29950/21233 29949/29949/21232 29951/29951/21234 +f 29950/29950/21233 29951/29951/21234 29952/29952/21235 +f 29953/29953/21236 29954/29954/21230 29955/29955/21237 +f 29953/29953/21236 29955/29955/21237 29956/29956/21238 +f 29956/29956/21238 29955/29955/21237 29911/29911/21195 +f 29956/29956/21238 29911/29911/21195 29910/29910/21192 +f 29952/29952/21235 29951/29951/21234 29907/29907/21192 +f 29952/29952/21235 29907/29907/21192 29906/29906/21191 +f 29957/29957/21239 29958/29958/21240 29959/29959/21241 +f 29957/29957/21239 29959/29959/21241 29960/29960/21242 +f 29961/29961/21240 29962/29962/21243 29963/29963/21244 +f 29961/29961/21240 29963/29963/21244 29964/29964/21241 +f 29959/29959/21241 29965/29965/21244 29937/29937/21220 +f 29959/29959/21241 29937/29937/21220 29934/29934/21217 +f 29960/29960/21242 29959/29959/21241 29934/29934/21217 +f 29960/29960/21242 29934/29934/21217 29933/29933/21216 +f 29966/29966/21245 29967/29967/21246 29968/29968/21247 +f 29966/29966/21245 29968/29968/21247 29969/29969/21248 +f 29970/29970/21249 29971/29971/21250 29972/29972/21251 +f 29970/29970/21249 29972/29972/21251 29973/29973/21247 +f 29973/29973/21247 29972/29972/21251 29944/29944/21227 +f 29973/29973/21247 29944/29944/21227 29943/29943/21226 +f 29969/29969/21248 29968/29968/21247 29940/29940/21223 +f 29969/29969/21248 29940/29940/21223 29939/29939/21222 +f 29974/29974/21252 29975/29975/21253 29976/29976/21254 +f 29974/29974/21252 29976/29976/21254 29977/29977/21255 +f 29975/29975/21253 29978/29978/21256 29979/29979/21257 +f 29975/29975/21253 29979/29979/21257 29976/29976/21254 +f 29976/29976/21254 29979/29979/21257 29962/29962/21243 +f 29976/29976/21254 29962/29962/21243 29961/29961/21240 +f 29977/29977/21255 29976/29976/21254 29961/29961/21240 +f 29977/29977/21255 29961/29961/21240 29980/29980/21239 +f 29981/29981/21258 29982/29982/21259 29983/29983/21260 +f 29981/29981/21258 29983/29983/21260 29984/29984/21261 +f 29982/29982/21259 29985/29985/21262 29986/29986/21263 +f 29982/29982/21259 29986/29986/21263 29983/29983/21260 +f 29983/29983/21260 29986/29986/21263 29978/29978/21256 +f 29983/29983/21260 29978/29978/21256 29975/29975/21253 +f 29984/29984/21261 29983/29983/21260 29975/29975/21253 +f 29984/29984/21261 29975/29975/21253 29974/29974/21252 +f 29987/29987/21264 29988/29988/21265 29989/29989/21266 +f 29987/29987/21264 29989/29989/21266 29990/29990/21267 +f 29991/29991/21268 29992/29992/21269 29993/29993/21270 +f 29991/29991/21268 29993/29993/21270 29994/29994/21266 +f 29994/29994/21266 29993/29993/21270 29995/29995/21271 +f 29994/29994/21266 29995/29995/21271 29996/29996/21272 +f 29990/29990/21267 29989/29989/21266 29997/29997/21272 +f 29990/29990/21267 29997/29997/21272 29998/29998/21273 +f 29998/29998/21273 29997/29997/21272 29999/29999/21274 +f 29998/29998/21273 29999/29999/21274 30000/30000/21275 +f 30001/30001/21272 30002/30002/21271 30003/30003/21276 +f 30001/30001/21272 30003/30003/21276 30004/30004/21277 +f 30004/30004/21277 30003/30003/21276 29971/29971/21250 +f 30004/30004/21277 29971/29971/21250 29970/29970/21249 +f 30000/30000/21275 29999/29999/21274 29967/29967/21246 +f 30000/30000/21275 29967/29967/21246 29966/29966/21245 +f 30005/30005/21278 30006/30006/21279 30007/30007/21280 +f 30005/30005/21278 30007/30007/21280 30008/30008/21281 +f 30009/30009/21282 30010/30010/21283 30011/30011/21284 +f 30009/30009/21282 30011/30011/21284 30012/30012/21285 +f 30012/30012/21285 30011/30011/21284 29992/29992/21269 +f 30012/30012/21285 29992/29992/21269 29991/29991/21268 +f 30008/30008/21281 30007/30007/21280 29988/29988/21265 +f 30008/30008/21281 29988/29988/21265 29987/29987/21264 +f 30013/30013/21286 30014/30014/21287 30015/30015/21288 +f 30013/30013/21286 30015/30015/21288 30016/30016/21289 +f 30014/30014/21287 30017/30017/21290 30018/30018/21291 +f 30014/30014/21287 30018/30018/21291 30015/30015/21288 +f 30015/30015/21288 30018/30018/21291 30019/30019/21292 +f 30015/30015/21288 30019/30019/21292 30020/30020/21293 +f 30016/30016/21289 30015/30015/21288 30020/30020/21293 +f 30016/30016/21289 30020/30020/21293 30021/30021/21294 +f 30021/30021/21294 30020/30020/21293 30022/30022/21295 +f 30021/30021/21294 30022/30022/21295 30023/30023/21296 +f 30020/30020/21293 30019/30019/21292 30024/30024/21297 +f 30020/30020/21293 30024/30024/21297 30022/30022/21295 +f 30025/30025/21295 30026/30026/21297 29985/29985/21262 +f 30025/30025/21295 29985/29985/21262 29982/29982/21259 +f 30023/30023/21296 30022/30022/21295 30027/30027/21259 +f 30023/30023/21296 30027/30027/21259 30028/30028/21258 +f 30029/30029/21298 30030/30030/21299 30031/30031/21300 +f 30029/30029/21298 30031/30031/21300 30032/30032/21301 +f 30030/30030/21299 30033/30033/21302 30034/30034/21303 +f 30030/30030/21299 30034/30034/21303 30031/30031/21300 +f 30031/30031/21300 30034/30034/21303 30017/30017/21290 +f 30031/30031/21300 30017/30017/21290 30014/30014/21287 +f 30032/30032/21301 30031/30031/21300 30014/30014/21287 +f 30032/30032/21301 30014/30014/21287 30013/30013/21286 +f 30035/30035/21304 30036/30036/21305 30037/30037/21306 +f 30035/30035/21304 30037/30037/21306 30038/30038/21307 +f 30039/30039/21305 30040/30040/21308 30041/30041/21309 +f 30039/30039/21305 30041/30041/21309 30042/30042/21310 +f 30042/30042/21310 30041/30041/21309 30043/30043/21311 +f 30042/30042/21310 30043/30043/21311 30044/30044/21312 +f 30038/30038/21307 30037/30037/21306 30045/30045/21312 +f 30038/30038/21307 30045/30045/21312 30046/30046/21313 +f 30046/30046/21313 30045/30045/21312 30047/30047/21314 +f 30046/30046/21313 30047/30047/21314 30048/30048/21315 +f 30044/30044/21312 30043/30043/21311 30049/30049/21316 +f 30044/30044/21312 30049/30049/21316 30050/30050/21314 +f 30051/30051/21317 30052/30052/21316 30010/30010/21283 +f 30051/30051/21317 30010/30010/21283 30009/30009/21282 +f 30048/30048/21315 30047/30047/21314 30006/30006/21279 +f 30048/30048/21315 30006/30006/21279 30005/30005/21278 +f 30053/30053/21318 30054/30054/21319 30055/30055/21320 +f 30053/30053/21318 30055/30055/21320 30056/30056/21321 +f 30054/30054/21319 30057/30057/21322 30058/30058/21323 +f 30054/30054/21319 30058/30058/21323 30055/30055/21320 +f 30055/30055/21320 30058/30058/21323 30033/30033/21302 +f 30055/30055/21320 30033/30033/21302 30030/30030/21299 +f 30056/30056/21321 30055/30055/21320 30030/30030/21299 +f 30056/30056/21321 30030/30030/21299 30029/30029/21298 +f 30059/30059/21324 30060/30060/21325 30061/30061/21326 +f 30059/30059/21324 30061/30061/21326 30062/30062/21327 +f 30063/30063/21325 30064/30064/21328 30065/30065/21329 +f 30063/30063/21325 30065/30065/21329 30066/30066/21326 +f 30066/30066/21326 30065/30065/21329 30067/30067/21322 +f 30066/30066/21326 30067/30067/21322 30068/30068/21319 +f 30062/30062/21327 30061/30061/21326 30054/30054/21319 +f 30062/30062/21327 30054/30054/21319 30053/30053/21318 +f 30069/30069/21330 30070/30070/21331 30071/30071/21332 +f 30069/30069/21330 30071/30071/21332 30072/30072/21333 +f 30073/30073/21334 30074/30074/21335 30075/30075/21336 +f 30073/30073/21334 30075/30075/21336 30076/30076/21332 +f 30076/30076/21332 30075/30075/21336 30040/30040/21308 +f 30076/30076/21332 30040/30040/21308 30039/30039/21305 +f 30072/30072/21333 30071/30071/21332 30036/30036/21305 +f 30072/30072/21333 30036/30036/21305 30035/30035/21304 +f 30077/30077/21337 30078/30078/21338 30079/30079/21339 +f 30077/30077/21337 30079/30079/21339 30080/30080/21340 +f 30078/30078/21338 30081/30081/21341 30082/30082/21342 +f 30078/30078/21338 30082/30082/21342 30079/30079/21339 +f 30079/30079/21339 30082/30082/21342 30064/30064/21328 +f 30079/30079/21339 30064/30064/21328 30063/30063/21325 +f 30083/30083/21340 30084/30084/21343 30060/30060/21325 +f 30083/30083/21340 30060/30060/21325 30059/30059/21324 +f 30085/30085/21344 30086/30086/21345 30087/30087/21346 +f 30085/30085/21344 30087/30087/21346 30088/30088/21347 +f 30089/30089/21345 30090/30090/21348 30091/30091/21349 +f 30089/30089/21345 30091/30091/21349 30092/30092/21350 +f 30093/30093/21350 30094/30094/21349 30095/30095/21351 +f 30093/30093/21350 30095/30095/21351 30096/30096/21352 +f 30088/30088/21347 30087/30087/21346 30097/30097/21353 +f 30088/30088/21347 30097/30097/21353 30098/30098/21354 +f 30098/30098/21354 30097/30097/21353 30099/30099/21355 +f 30098/30098/21354 30099/30099/21355 30100/30100/21356 +f 30096/30096/21352 30095/30095/21351 30101/30101/21357 +f 30096/30096/21352 30101/30101/21357 30102/30102/21358 +f 30102/30102/21358 30101/30101/21357 30074/30074/21335 +f 30102/30102/21358 30074/30074/21335 30073/30073/21334 +f 30100/30100/21356 30099/30099/21355 30070/30070/21331 +f 30100/30100/21356 30070/30070/21331 30069/30069/21330 +f 30103/30103/21359 30104/30104/21360 30105/30105/21361 +f 30103/30103/21359 30105/30105/21361 30106/30106/21362 +f 30104/30104/21360 30107/30107/21363 30108/30108/21364 +f 30104/30104/21360 30108/30108/21364 30105/30105/21361 +f 30105/30105/21361 30108/30108/21364 30081/30081/21341 +f 30105/30105/21361 30081/30081/21341 30078/30078/21338 +f 30106/30106/21362 30105/30105/21361 30078/30078/21338 +f 30106/30106/21362 30078/30078/21338 30077/30077/21337 +f 30109/30109/21365 30110/30110/21366 30111/30111/21367 +f 30109/30109/21365 30111/30111/21367 30112/30112/21368 +f 30110/30110/21366 30113/30113/21369 30114/30114/21370 +f 30110/30110/21366 30114/30114/21370 30111/30111/21367 +f 30111/30111/21367 30114/30114/21370 30107/30107/21363 +f 30111/30111/21367 30107/30107/21363 30104/30104/21360 +f 30112/30112/21368 30111/30111/21367 30104/30104/21360 +f 30112/30112/21368 30104/30104/21360 30103/30103/21359 +f 30115/30115/21371 30116/30116/21372 30117/30117/21373 +f 30115/30115/21371 30117/30117/21373 30118/30118/21374 +f 30119/30119/21372 30120/30120/21375 30121/30121/21376 +f 30119/30119/21372 30121/30121/21376 30122/30122/21373 +f 30122/30122/21373 30121/30121/21376 30123/30123/21377 +f 30122/30122/21373 30123/30123/21377 30124/30124/21378 +f 30118/30118/21374 30117/30117/21373 30125/30125/21378 +f 30118/30118/21374 30125/30125/21378 30126/30126/21379 +f 30126/30126/21379 30125/30125/21378 30127/30127/21380 +f 30126/30126/21379 30127/30127/21380 30128/30128/21381 +f 30124/30124/21378 30123/30123/21377 30129/30129/21382 +f 30124/30124/21378 30129/30129/21382 30130/30130/21380 +f 30130/30130/21380 30129/30129/21382 30090/30090/21348 +f 30130/30130/21380 30090/30090/21348 30089/30089/21345 +f 30128/30128/21381 30127/30127/21380 30086/30086/21345 +f 30128/30128/21381 30086/30086/21345 30085/30085/21344 +f 30131/30131/21383 30132/30132/21384 30133/30133/21385 +f 30131/30131/21383 30133/30133/21385 30134/30134/21386 +f 30132/30132/21384 30135/30135/21387 30136/30136/21388 +f 30132/30132/21384 30136/30136/21388 30133/30133/21385 +f 30137/30137/21385 30138/30138/21388 30113/30113/21369 +f 30137/30137/21385 30113/30113/21369 30110/30110/21366 +f 30134/30134/21386 30133/30133/21385 30139/30139/21389 +f 30134/30134/21386 30139/30139/21389 30140/30140/21365 +f 30141/30141/21390 30142/30142/21391 30143/30143/21392 +f 30141/30141/21390 30143/30143/21392 30144/30144/21393 +f 30145/30145/21394 30146/30146/21395 30147/30147/21396 +f 30145/30145/21394 30147/30147/21396 30148/30148/21392 +f 30148/30148/21392 30147/30147/21396 30120/30120/21375 +f 30148/30148/21392 30120/30120/21375 30119/30119/21372 +f 30144/30144/21393 30143/30143/21392 30116/30116/21372 +f 30144/30144/21393 30116/30116/21372 30115/30115/21371 +f 30149/30149/21397 30150/30150/21398 30151/30151/21399 +f 30149/30149/21397 30151/30151/21399 30152/30152/21400 +f 30150/30150/21398 30153/30153/21401 30154/30154/21402 +f 30150/30150/21398 30154/30154/21402 30151/30151/21399 +f 30151/30151/21399 30154/30154/21402 30135/30135/21387 +f 30151/30151/21399 30135/30135/21387 30132/30132/21384 +f 30152/30152/21400 30151/30151/21399 30132/30132/21384 +f 30152/30152/21400 30132/30132/21384 30131/30131/21383 +f 30155/30155/21403 30156/30156/21404 30157/30157/21405 +f 30155/30155/21403 30157/30157/21405 30158/30158/21406 +f 30156/30156/21404 30159/30159/21407 30160/30160/21408 +f 30156/30156/21404 30160/30160/21408 30157/30157/21405 +f 30157/30157/21405 30160/30160/21408 30153/30153/21401 +f 30157/30157/21405 30153/30153/21401 30150/30150/21398 +f 30158/30158/21406 30157/30157/21405 30150/30150/21398 +f 30158/30158/21406 30150/30150/21398 30149/30149/21397 +f 30161/30161/21409 30162/30162/21410 30163/30163/21411 +f 30161/30161/21409 30163/30163/21411 30164/30164/21412 +f 30165/30165/21413 30166/30166/21414 30167/30167/21415 +f 30165/30165/21413 30167/30167/21415 30168/30168/21411 +f 30168/30168/21411 30167/30167/21415 30169/30169/21416 +f 30168/30168/21411 30169/30169/21416 30170/30170/21417 +f 30164/30164/21412 30163/30163/21411 30171/30171/21418 +f 30164/30164/21412 30171/30171/21418 30172/30172/21419 +f 30172/30172/21419 30171/30171/21418 30173/30173/21420 +f 30172/30172/21419 30173/30173/21420 30174/30174/21421 +f 30170/30170/21417 30169/30169/21416 30175/30175/21422 +f 30170/30170/21417 30175/30175/21422 30176/30176/21423 +f 30176/30176/21423 30175/30175/21422 30177/30177/21395 +f 30176/30176/21423 30177/30177/21395 30178/30178/21391 +f 30174/30174/21421 30173/30173/21420 30142/30142/21391 +f 30174/30174/21421 30142/30142/21391 30141/30141/21390 +f 30179/30179/21424 30180/30180/21425 30181/30181/21426 +f 30179/30179/21424 30181/30181/21426 30182/30182/21427 +f 30183/30183/21428 30184/30184/21429 30185/30185/21430 +f 30183/30183/21428 30185/30185/21430 30186/30186/21431 +f 30186/30186/21431 30185/30185/21430 30166/30166/21414 +f 30186/30186/21431 30166/30166/21414 30165/30165/21413 +f 30182/30182/21427 30181/30181/21426 30162/30162/21410 +f 30182/30182/21427 30162/30162/21410 30161/30161/21409 +f 30187/30187/21432 30188/30188/21433 30189/30189/21434 +f 30187/30187/21432 30189/30189/21434 30190/30190/21435 +f 30188/30188/21433 30191/30191/21436 30192/30192/21437 +f 30188/30188/21433 30192/30192/21437 30189/30189/21434 +f 30189/30189/21434 30192/30192/21437 30193/30193/21438 +f 30189/30189/21434 30193/30193/21438 30194/30194/21439 +f 30190/30190/21435 30189/30189/21434 30194/30194/21439 +f 30190/30190/21435 30194/30194/21439 30195/30195/21440 +f 30195/30195/21440 30194/30194/21439 30196/30196/21441 +f 30195/30195/21440 30196/30196/21441 30197/30197/21442 +f 30194/30194/21439 30193/30193/21438 30198/30198/21443 +f 30194/30194/21439 30198/30198/21443 30196/30196/21441 +f 30196/30196/21441 30198/30198/21443 30159/30159/21407 +f 30196/30196/21441 30159/30159/21407 30156/30156/21404 +f 30197/30197/21442 30196/30196/21441 30156/30156/21404 +f 30197/30197/21442 30156/30156/21404 30155/30155/21403 +f 30199/30199/21444 30200/30200/21445 30201/30201/21446 +f 30199/30199/21444 30201/30201/21446 30202/30202/21447 +f 30200/30200/21445 30203/30203/21448 30204/30204/21449 +f 30200/30200/21445 30204/30204/21449 30201/30201/21446 +f 30201/30201/21446 30204/30204/21449 30191/30191/21436 +f 30201/30201/21446 30191/30191/21436 30188/30188/21433 +f 30202/30202/21447 30201/30201/21446 30188/30188/21433 +f 30202/30202/21447 30188/30188/21433 30187/30187/21432 +f 30205/30205/21450 30206/30206/21451 30207/30207/21452 +f 30205/30205/21450 30207/30207/21452 30208/30208/21453 +f 30209/30209/21454 30210/30210/21455 30211/30211/21456 +f 30209/30209/21454 30211/30211/21456 30212/30212/21452 +f 30212/30212/21452 30211/30211/21456 30213/30213/21457 +f 30212/30212/21452 30213/30213/21457 30214/30214/21458 +f 30208/30208/21453 30207/30207/21452 30215/30215/21458 +f 30208/30208/21453 30215/30215/21458 30216/30216/21459 +f 30216/30216/21459 30215/30215/21458 30217/30217/21460 +f 30216/30216/21459 30217/30217/21460 30218/30218/21461 +f 30214/30214/21458 30213/30213/21457 30219/30219/21462 +f 30214/30214/21458 30219/30219/21462 30220/30220/21463 +f 30220/30220/21463 30219/30219/21462 30184/30184/21429 +f 30220/30220/21463 30184/30184/21429 30183/30183/21428 +f 30218/30218/21461 30217/30217/21460 30180/30180/21425 +f 30218/30218/21461 30180/30180/21425 30179/30179/21424 +f 30221/30221/21464 30222/30222/21465 30223/30223/21466 +f 30221/30221/21464 30223/30223/21466 30224/30224/21467 +f 30222/30222/21465 30225/30225/21468 30226/30226/21469 +f 30222/30222/21465 30226/30226/21469 30223/30223/21466 +f 30223/30223/21466 30226/30226/21469 30227/30227/21448 +f 30223/30223/21466 30227/30227/21448 30228/30228/21445 +f 30229/30229/21470 30230/30230/21471 30200/30200/21445 +f 30229/30229/21470 30200/30200/21445 30199/30199/21444 +f 30231/30231/21472 30232/30232/21473 30233/30233/21474 +f 30231/30231/21472 30233/30233/21474 30234/30234/21475 +f 30232/30232/21473 30235/30235/21476 30236/30236/21477 +f 30232/30232/21473 30236/30236/21477 30233/30233/21474 +f 30237/30237/21474 30238/30238/21477 30239/30239/21478 +f 30237/30237/21474 30239/30239/21478 30240/30240/21479 +f 30241/30241/21475 30237/30237/21474 30240/30240/21479 +f 30241/30241/21475 30240/30240/21479 30242/30242/21480 +f 29154/29154/20535 29153/29153/20534 30243/30243/21481 +f 29154/29154/20535 30243/30243/21481 30244/30244/21482 +f 29153/29153/20534 29152/29152/20533 29177/29177/20556 +f 29153/29153/20534 29177/29177/20556 30243/30243/21481 +f 30245/30245/21483 29181/29181/20556 29184/29184/20560 +f 30245/30245/21483 29184/29184/20560 30246/30246/21484 +f 30247/30247/21482 30245/30245/21483 30246/30246/21484 +f 30247/30247/21482 30246/30246/21484 30248/30248/21485 +f 29166/29166/20545 29165/29165/20544 30249/30249/21486 +f 29166/29166/20545 30249/30249/21486 30250/30250/21487 +f 30251/30251/20544 30252/30252/20543 30253/30253/21488 +f 30251/30251/20544 30253/30253/21488 30254/30254/21489 +f 30254/30254/21489 30253/30253/21488 30210/30210/21455 +f 30254/30254/21489 30210/30210/21455 30209/30209/21454 +f 30250/30250/21487 30249/30249/21486 30206/30206/21451 +f 30250/30250/21487 30206/30206/21451 30205/30205/21450 +f 29179/29179/20558 29178/29178/20557 30255/30255/21490 +f 29179/29179/20558 30255/30255/21490 30256/30256/21491 +f 29178/29178/20557 29150/29150/20531 30257/30257/21492 +f 29178/29178/20557 30257/30257/21492 30255/30255/21490 +f 30255/30255/21490 30257/30257/21492 30225/30225/21468 +f 30255/30255/21490 30225/30225/21468 30222/30222/21465 +f 30256/30256/21491 30255/30255/21490 30222/30222/21465 +f 30256/30256/21491 30222/30222/21465 30221/30221/21464 +f 29141/29141/20522 29216/29216/20587 30258/30258/21493 +f 29141/29141/20522 30258/30258/21493 29142/29142/20523 +f 29223/29223/20587 29224/29224/20593 30259/30259/21494 +f 29223/29223/20587 30259/30259/21494 30260/30260/21495 +f 30260/30260/21495 30259/30259/21494 29238/29238/20607 +f 30260/30260/21495 29238/29238/20607 29237/29237/20606 +f 29142/29142/20523 30258/30258/21493 29234/29234/20603 +f 29142/29142/20523 29234/29234/20603 29143/29143/20524 +f 30261/30261/21496 30262/30262/21497 30263/30263/21498 +f 30261/30261/21496 30263/30263/21498 30264/30264/21499 +f 30262/30262/21497 29207/29207/20580 29210/29210/20583 +f 30262/30262/21497 29210/29210/20583 30263/30263/21498 +f 30265/30265/21498 29213/29213/20583 29171/29171/20550 +f 30265/30265/21498 29171/29171/20550 29168/29168/20547 +f 30266/30266/21500 30265/30265/21498 29168/29168/20547 +f 30266/30266/21500 29168/29168/20547 29167/29167/20546 +f 29885/29885/21174 29888/29888/21177 30267/30267/21501 +f 29885/29885/21174 30267/30267/21501 30268/30268/21502 +f 29888/29888/21177 29898/29898/21183 30269/30269/21503 +f 29888/29888/21177 30269/30269/21503 30267/30267/21501 +f 30267/30267/21501 30269/30269/21503 29839/29839/21134 +f 30267/30267/21501 29839/29839/21134 29837/29837/21132 +f 30268/30268/21502 30267/30267/21501 29837/29837/21132 +f 30268/30268/21502 29837/29837/21132 29798/29798/21101 +f 29842/29842/21137 29845/29845/21140 30270/30270/21504 +f 29842/29842/21137 30270/30270/21504 30271/30271/21505 +f 29845/29845/21140 29853/29853/21148 30272/30272/21506 +f 29845/29845/21140 30272/30272/21506 30270/30270/21504 +f 30270/30270/21504 30272/30272/21506 29858/29858/21129 +f 30270/30270/21504 29858/29858/21129 30273/30273/21128 +f 30271/30271/21505 30270/30270/21504 30273/30273/21128 +f 30271/30271/21505 30273/30273/21128 30274/30274/21507 +f 30275/30275/21508 30276/30276/21509 30277/30277/21510 +f 30275/30275/21508 30277/30277/21510 30278/30278/21511 +f 30276/30276/21509 30279/30279/21512 30280/30280/21513 +f 30276/30276/21509 30280/30280/21513 30277/30277/21510 +f 30277/30277/21510 30280/30280/21513 30281/30281/21514 +f 30277/30277/21510 30281/30281/21514 30282/30282/21515 +f 30278/30278/21511 30277/30277/21510 30282/30282/21515 +f 30278/30278/21511 30282/30282/21515 30283/30283/21516 +f 29919/29919/21203 29921/29921/21205 30284/30284/21517 +f 29919/29919/21203 30284/30284/21517 30285/30285/21518 +f 29921/29921/21205 29885/29885/21174 30268/30268/21502 +f 29921/29921/21205 30268/30268/21502 30284/30284/21517 +f 30284/30284/21517 30268/30268/21502 29798/29798/21101 +f 30284/30284/21517 29798/29798/21101 29796/29796/21100 +f 30285/30285/21518 30284/30284/21517 29796/29796/21100 +f 30285/30285/21518 29796/29796/21100 29768/29768/21076 +f 29906/29906/21191 29909/29909/21194 30286/30286/21519 +f 29906/29906/21191 30286/30286/21519 30287/30287/21520 +f 29909/29909/21194 29919/29919/21203 30285/30285/21518 +f 29909/29909/21194 30285/30285/21518 30286/30286/21519 +f 30286/30286/21519 30285/30285/21518 29768/29768/21076 +f 30286/30286/21519 29768/29768/21076 29766/29766/21075 +f 30287/30287/21520 30286/30286/21519 29766/29766/21075 +f 30287/30287/21520 29766/29766/21075 29753/29753/21063 +f 29869/29869/21161 29872/29872/21164 30288/30288/21521 +f 29869/29869/21161 30288/30288/21521 30289/30289/21522 +f 29872/29872/21164 29842/29842/21137 30271/30271/21505 +f 29872/29872/21164 30271/30271/21505 30288/30288/21521 +f 30288/30288/21521 30271/30271/21505 30274/30274/21507 +f 30288/30288/21521 30274/30274/21507 30290/30290/21523 +f 30289/30289/21522 30288/30288/21521 30290/30290/21523 +f 30289/30289/21522 30290/30290/21523 30291/30291/21524 +f 29950/29950/21233 29952/29952/21235 30292/30292/21525 +f 29950/29950/21233 30292/30292/21525 30293/30293/21526 +f 29952/29952/21235 29906/29906/21191 30287/30287/21520 +f 29952/29952/21235 30287/30287/21520 30292/30292/21525 +f 30292/30292/21525 30287/30287/21520 29753/29753/21063 +f 30292/30292/21525 29753/29753/21063 29751/29751/21061 +f 30293/30293/21526 30292/30292/21525 29751/29751/21061 +f 30293/30293/21526 29751/29751/21061 29714/29714/21030 +f 30294/30294/21184 30295/30295/21187 30296/30296/21527 +f 30294/30294/21184 30296/30296/21527 30297/30297/21528 +f 30295/30295/21187 29876/29876/21168 30298/30298/21529 +f 30295/30295/21187 30298/30298/21529 30296/30296/21527 +f 30296/30296/21527 30298/30298/21529 30299/30299/21059 +f 30296/30296/21527 30299/30299/21059 30300/30300/21058 +f 30297/30297/21528 30296/30296/21527 30300/30300/21058 +f 30297/30297/21528 30300/30300/21058 29681/29681/20998 +f 29876/29876/21168 29879/29879/21171 30301/30301/21530 +f 29876/29876/21168 30301/30301/21530 30298/30298/21529 +f 29879/29879/21171 29869/29869/21161 30289/30289/21522 +f 29879/29879/21171 30289/30289/21522 30301/30301/21530 +f 30301/30301/21530 30289/30289/21522 30291/30291/21524 +f 30301/30301/21530 30291/30291/21524 30302/30302/21531 +f 30298/30298/21529 30301/30301/21530 30302/30302/21531 +f 30298/30298/21529 30302/30302/21531 30299/30299/21059 +f 29939/29939/21222 29942/29942/21225 30303/30303/21532 +f 29939/29939/21222 30303/30303/21532 30304/30304/21533 +f 29942/29942/21225 29950/29950/21233 30293/30293/21526 +f 29942/29942/21225 30293/30293/21526 30303/30303/21532 +f 30303/30303/21532 30293/30293/21526 29714/29714/21030 +f 30303/30303/21532 29714/29714/21030 29712/29712/21028 +f 30304/30304/21533 30303/30303/21532 29712/29712/21028 +f 30304/30304/21533 29712/29712/21028 29693/29693/21009 +f 29966/29966/21245 29969/29969/21248 30305/30305/21534 +f 29966/29966/21245 30305/30305/21534 30306/30306/21535 +f 29969/29969/21248 29939/29939/21222 30304/30304/21533 +f 29969/29969/21248 30304/30304/21533 30305/30305/21534 +f 30305/30305/21534 30304/30304/21533 29693/29693/21009 +f 30305/30305/21534 29693/29693/21009 29691/29691/21007 +f 30306/30306/21535 30305/30305/21534 29691/29691/21007 +f 30306/30306/21535 29691/29691/21007 29673/29673/20991 +f 30307/30307/21536 30308/30308/21219 30309/30309/21537 +f 30307/30307/21536 30309/30309/21537 30310/30310/21538 +f 30308/30308/21219 30311/30311/21208 30312/30312/21539 +f 30308/30308/21219 30312/30312/21539 30309/30309/21537 +f 30309/30309/21537 30312/30312/21539 29679/29679/20996 +f 30309/30309/21537 29679/29679/20996 29688/29688/21004 +f 30310/30310/21538 30309/30309/21537 29688/29688/21004 +f 30310/30310/21538 29688/29688/21004 29667/29667/20986 +f 30311/30311/21208 30313/30313/21211 30314/30314/21540 +f 30311/30311/21208 30314/30314/21540 30312/30312/21539 +f 30313/30313/21211 30294/30294/21184 30297/30297/21528 +f 30313/30313/21211 30297/30297/21528 30314/30314/21540 +f 30314/30314/21540 30297/30297/21528 29681/29681/20998 +f 30314/30314/21540 29681/29681/20998 29680/29680/20997 +f 30312/30312/21539 30314/30314/21540 29680/29680/20997 +f 30312/30312/21539 29680/29680/20997 29679/29679/20996 +f 29998/29998/21273 30000/30000/21275 30315/30315/21541 +f 29998/29998/21273 30315/30315/21541 30316/30316/21542 +f 30000/30000/21275 29966/29966/21245 30306/30306/21535 +f 30000/30000/21275 30306/30306/21535 30315/30315/21541 +f 30315/30315/21541 30306/30306/21535 29673/29673/20991 +f 30315/30315/21541 29673/29673/20991 29671/29671/20990 +f 30316/30316/21542 30315/30315/21541 29671/29671/20990 +f 30316/30316/21542 29671/29671/20990 29637/29637/20960 +f 30317/30317/21239 30318/30318/21242 30319/30319/21543 +f 30317/30317/21239 30319/30319/21543 30320/30320/21544 +f 30318/30318/21242 30307/30307/21536 30310/30310/21538 +f 30318/30318/21242 30310/30310/21538 30319/30319/21543 +f 30319/30319/21543 30310/30310/21538 29667/29667/20986 +f 30319/30319/21543 29667/29667/20986 29665/29665/20985 +f 30320/30320/21544 30319/30319/21543 29665/29665/20985 +f 30320/30320/21544 29665/29665/20985 29606/29606/20931 +f 29987/29987/21264 29990/29990/21267 30321/30321/21545 +f 29987/29987/21264 30321/30321/21545 30322/30322/21546 +f 29990/29990/21267 29998/29998/21273 30316/30316/21542 +f 29990/29990/21267 30316/30316/21542 30321/30321/21545 +f 30321/30321/21545 30316/30316/21542 29637/29637/20960 +f 30321/30321/21545 29637/29637/20960 29635/29635/20958 +f 30322/30322/21546 30321/30321/21545 29635/29635/20958 +f 30322/30322/21546 29635/29635/20958 29621/29621/20944 +f 30005/30005/21278 30008/30008/21281 30323/30323/21547 +f 30005/30005/21278 30323/30323/21547 30324/30324/21548 +f 30008/30008/21281 29987/29987/21264 30322/30322/21546 +f 30008/30008/21281 30322/30322/21546 30323/30323/21547 +f 30323/30323/21547 30322/30322/21546 29621/29621/20944 +f 30323/30323/21547 29621/29621/20944 29619/29619/20943 +f 30324/30324/21548 30323/30323/21547 29619/29619/20943 +f 30324/30324/21548 29619/29619/20943 29553/29553/20884 +f 30028/30028/21258 30325/30325/21549 30326/30326/21550 +f 30028/30028/21258 30326/30326/21550 30327/30327/21551 +f 30325/30325/21549 30328/30328/21252 30329/30329/21552 +f 30325/30325/21549 30329/30329/21552 30326/30326/21550 +f 30326/30326/21550 30329/30329/21552 30330/30330/20927 +f 30326/30326/21550 30330/30330/20927 30331/30331/20941 +f 30327/30327/21551 30326/30326/21550 30331/30331/20941 +f 30327/30327/21551 30331/30331/20941 30332/30332/20919 +f 30328/30328/21252 30333/30333/21255 30334/30334/21553 +f 30328/30328/21252 30334/30334/21553 30329/30329/21552 +f 30333/30333/21255 30317/30317/21239 30320/30320/21544 +f 30333/30333/21255 30320/30320/21544 30334/30334/21553 +f 30334/30334/21553 30320/30320/21544 29606/29606/20931 +f 30334/30334/21553 29606/29606/20931 29605/29605/20930 +f 30329/30329/21552 30334/30334/21553 29605/29605/20930 +f 30329/30329/21552 29605/29605/20930 30330/30330/20927 +f 30021/30021/21294 30023/30023/21296 30335/30335/21554 +f 30021/30021/21294 30335/30335/21554 30336/30336/21555 +f 30023/30023/21296 30028/30028/21258 30327/30327/21551 +f 30023/30023/21296 30327/30327/21551 30335/30335/21554 +f 30335/30335/21554 30327/30327/21551 30332/30332/20919 +f 30335/30335/21554 30332/30332/20919 30337/30337/21556 +f 30336/30336/21555 30335/30335/21554 30337/30337/21556 +f 30336/30336/21555 30337/30337/21556 30338/30338/20861 +f 30035/30035/21304 30038/30038/21307 30339/30339/21557 +f 30035/30035/21304 30339/30339/21557 30340/30340/21558 +f 30038/30038/21307 30046/30046/21313 30341/30341/21559 +f 30038/30038/21307 30341/30341/21559 30339/30339/21557 +f 30339/30339/21557 30341/30341/21559 29550/29550/20881 +f 30339/30339/21557 29550/29550/20881 29561/29561/20890 +f 30340/30340/21558 30339/30339/21557 29561/29561/20890 +f 30340/30340/21558 29561/29561/20890 29542/29542/20874 +f 30046/30046/21313 30048/30048/21315 30342/30342/21560 +f 30046/30046/21313 30342/30342/21560 30341/30341/21559 +f 30048/30048/21315 30005/30005/21278 30324/30324/21548 +f 30048/30048/21315 30324/30324/21548 30342/30342/21560 +f 30342/30342/21560 30324/30324/21548 29553/29553/20884 +f 30342/30342/21560 29553/29553/20884 29551/29551/20882 +f 30341/30341/21559 30342/30342/21560 29551/29551/20882 +f 30341/30341/21559 29551/29551/20882 29550/29550/20881 +f 30069/30069/21330 30072/30072/21333 30343/30343/21561 +f 30069/30069/21330 30343/30343/21561 30344/30344/21562 +f 30072/30072/21333 30035/30035/21304 30340/30340/21558 +f 30072/30072/21333 30340/30340/21558 30343/30343/21561 +f 30343/30343/21561 30340/30340/21558 29542/29542/20874 +f 30343/30343/21561 29542/29542/20874 29540/29540/20872 +f 30344/30344/21562 30343/30343/21561 29540/29540/20872 +f 30344/30344/21562 29540/29540/20872 29513/29513/20846 +f 30029/30029/21298 30032/30032/21301 30345/30345/21563 +f 30029/30029/21298 30345/30345/21563 30346/30346/21564 +f 30032/30032/21301 30013/30013/21286 30347/30347/21565 +f 30032/30032/21301 30347/30347/21565 30345/30345/21563 +f 30345/30345/21563 30347/30347/21565 30348/30348/20859 +f 30345/30345/21563 30348/30348/20859 30349/30349/20870 +f 30346/30346/21564 30345/30345/21563 30349/30349/20870 +f 30346/30346/21564 30349/30349/20870 30350/30350/20817 +f 30013/30013/21286 30016/30016/21289 30351/30351/21566 +f 30013/30013/21286 30351/30351/21566 30347/30347/21565 +f 30016/30016/21289 30021/30021/21294 30336/30336/21555 +f 30016/30016/21289 30336/30336/21555 30351/30351/21566 +f 30351/30351/21566 30336/30336/21555 30338/30338/20861 +f 30351/30351/21566 30338/30338/20861 30352/30352/20860 +f 30347/30347/21565 30351/30351/21566 30352/30352/20860 +f 30347/30347/21565 30352/30352/20860 30348/30348/20859 +f 30098/30098/21354 30100/30100/21356 30353/30353/21567 +f 30098/30098/21354 30353/30353/21567 30354/30354/21568 +f 30100/30100/21356 30069/30069/21330 30344/30344/21562 +f 30100/30100/21356 30344/30344/21562 30353/30353/21567 +f 30353/30353/21567 30344/30344/21562 29513/29513/20846 +f 30353/30353/21567 29513/29513/20846 29511/29511/20845 +f 30354/30354/21568 30353/30353/21567 29511/29511/20845 +f 30354/30354/21568 29511/29511/20845 29482/29482/20823 +f 30085/30085/21344 30088/30088/21347 30355/30355/21569 +f 30085/30085/21344 30355/30355/21569 30356/30356/21570 +f 30088/30088/21347 30098/30098/21354 30354/30354/21568 +f 30088/30088/21347 30354/30354/21568 30355/30355/21569 +f 30355/30355/21569 30354/30354/21568 29482/29482/20823 +f 30355/30355/21569 29482/29482/20823 29480/29480/20822 +f 30356/30356/21570 30355/30355/21569 29480/29480/20822 +f 30356/30356/21570 29480/29480/20822 29469/29469/20812 +f 30053/30053/21318 30056/30056/21321 30357/30357/21571 +f 30053/30053/21318 30357/30357/21571 30358/30358/21572 +f 30056/30056/21321 30029/30029/21298 30346/30346/21564 +f 30056/30056/21321 30346/30346/21564 30357/30357/21571 +f 30357/30357/21571 30346/30346/21564 30350/30350/20817 +f 30357/30357/21571 30350/30350/20817 30359/30359/21573 +f 30358/30358/21572 30357/30357/21571 30359/30359/21573 +f 30358/30358/21572 30359/30359/21573 30360/30360/20800 +f 30126/30126/21379 30128/30128/21381 30361/30361/21574 +f 30126/30126/21379 30361/30361/21574 30362/30362/21575 +f 30128/30128/21381 30085/30085/21344 30356/30356/21570 +f 30128/30128/21381 30356/30356/21570 30361/30361/21574 +f 30361/30361/21574 30356/30356/21570 29469/29469/20812 +f 30361/30361/21574 29469/29469/20812 29467/29467/20811 +f 30362/30362/21575 30361/30361/21574 29467/29467/20811 +f 30362/30362/21575 29467/29467/20811 29437/29437/20785 +f 30363/30363/21337 30083/30083/21340 30364/30364/21576 +f 30363/30363/21337 30364/30364/21576 30365/30365/21577 +f 30083/30083/21340 30059/30059/21324 30366/30366/21578 +f 30083/30083/21340 30366/30366/21578 30364/30364/21576 +f 30364/30364/21576 30366/30366/21578 30367/30367/20798 +f 30364/30364/21576 30367/30367/20798 30368/30368/20809 +f 30365/30365/21577 30364/30364/21576 30368/30368/20809 +f 30365/30365/21577 30368/30368/20809 30369/30369/21579 +f 30059/30059/21324 30062/30062/21327 30370/30370/21580 +f 30059/30059/21324 30370/30370/21580 30366/30366/21578 +f 30062/30062/21327 30053/30053/21318 30358/30358/21572 +f 30062/30062/21327 30358/30358/21572 30370/30370/21580 +f 30370/30370/21580 30358/30358/21572 30360/30360/20800 +f 30370/30370/21580 30360/30360/20800 30371/30371/20799 +f 30366/30366/21578 30370/30370/21580 30371/30371/20799 +f 30366/30366/21578 30371/30371/20799 30367/30367/20798 +f 30115/30115/21371 30118/30118/21374 30372/30372/21581 +f 30115/30115/21371 30372/30372/21581 30373/30373/21582 +f 30118/30118/21374 30126/30126/21379 30362/30362/21575 +f 30118/30118/21374 30362/30362/21575 30372/30372/21581 +f 30372/30372/21581 30362/30362/21575 29437/29437/20785 +f 30372/30372/21581 29437/29437/20785 29435/29435/20783 +f 30373/30373/21582 30372/30372/21581 29435/29435/20783 +f 30373/30373/21582 29435/29435/20783 29414/29414/20763 +f 30141/30141/21390 30144/30144/21393 30374/30374/21583 +f 30141/30141/21390 30374/30374/21583 30375/30375/21584 +f 30144/30144/21393 30115/30115/21371 30373/30373/21582 +f 30144/30144/21393 30373/30373/21582 30374/30374/21583 +f 30374/30374/21583 30373/30373/21582 29414/29414/20763 +f 30374/30374/21583 29414/29414/20763 29412/29412/20762 +f 30375/30375/21584 30374/30374/21583 29412/29412/20762 +f 30375/30375/21584 29412/29412/20762 29392/29392/20746 +f 30376/30376/21585 30377/30377/21368 30378/30378/21586 +f 30376/30376/21585 30378/30378/21586 30379/30379/21587 +f 30377/30377/21368 30380/30380/21588 30381/30381/21589 +f 30377/30377/21368 30381/30381/21589 30378/30378/21586 +f 30378/30378/21586 30381/30381/21589 30382/30382/20752 +f 30378/30378/21586 30382/30382/20752 29407/29407/20758 +f 30379/30379/21587 30378/30378/21586 29407/29407/20758 +f 30379/30379/21587 29407/29407/20758 29385/29385/20741 +f 30380/30380/21588 30383/30383/21362 30384/30384/21590 +f 30380/30380/21588 30384/30384/21590 30381/30381/21589 +f 30383/30383/21362 30363/30363/21337 30365/30365/21577 +f 30383/30383/21362 30365/30365/21577 30384/30384/21590 +f 30384/30384/21590 30365/30365/21577 30369/30369/21579 +f 30384/30384/21590 30369/30369/21579 30385/30385/21591 +f 30381/30381/21589 30384/30384/21590 30385/30385/21591 +f 30381/30381/21589 30385/30385/21591 30382/30382/20752 +f 30172/30172/21419 30174/30174/21421 30386/30386/21592 +f 30172/30172/21419 30386/30386/21592 30387/30387/21593 +f 30174/30174/21421 30141/30141/21390 30375/30375/21584 +f 30174/30174/21421 30375/30375/21584 30386/30386/21592 +f 30386/30386/21592 30375/30375/21584 29392/29392/20746 +f 30386/30386/21592 29392/29392/20746 29390/29390/20744 +f 30387/30387/21593 30386/30386/21592 29390/29390/20744 +f 30387/30387/21593 29390/29390/20744 29359/29359/20717 +f 30388/30388/21383 30389/30389/21386 30390/30390/21594 +f 30388/30388/21383 30390/30390/21594 30391/30391/21595 +f 30389/30389/21386 30376/30376/21585 30379/30379/21587 +f 30389/30389/21386 30379/30379/21587 30390/30390/21594 +f 30390/30390/21594 30379/30379/21587 29385/29385/20741 +f 30390/30390/21594 29385/29385/20741 29384/29384/20740 +f 30391/30391/21595 30390/30390/21594 29384/29384/20740 +f 30391/30391/21595 29384/29384/20740 29330/29330/20690 +f 30161/30161/21409 30164/30164/21412 30392/30392/21596 +f 30161/30161/21409 30392/30392/21596 30393/30393/21597 +f 30164/30164/21412 30172/30172/21419 30387/30387/21593 +f 30164/30164/21412 30387/30387/21593 30392/30392/21596 +f 30392/30392/21596 30387/30387/21593 29359/29359/20717 +f 30392/30392/21596 29359/29359/20717 29357/29357/20715 +f 30393/30393/21597 30392/30392/21596 29357/29357/20715 +f 30393/30393/21597 29357/29357/20715 29343/29343/20702 +f 30179/30179/21424 30182/30182/21427 30394/30394/21598 +f 30179/30179/21424 30394/30394/21598 30395/30395/21599 +f 30182/30182/21427 30161/30161/21409 30393/30393/21597 +f 30182/30182/21427 30393/30393/21597 30394/30394/21598 +f 30394/30394/21598 30393/30393/21597 29343/29343/20702 +f 30394/30394/21598 29343/29343/20702 29341/29341/20701 +f 30395/30395/21599 30394/30394/21598 29341/29341/20701 +f 30395/30395/21599 29341/29341/20701 29288/29288/20649 +f 30396/30396/21600 30397/30397/21406 30398/30398/21601 +f 30396/30396/21600 30398/30398/21601 30399/30399/21602 +f 30397/30397/21406 30400/30400/21397 30401/30401/21603 +f 30397/30397/21406 30401/30401/21603 30398/30398/21601 +f 30398/30398/21601 30401/30401/21603 29328/29328/20688 +f 30398/30398/21601 29328/29328/20688 29339/29339/20699 +f 30399/30399/21602 30398/30398/21601 29339/29339/20699 +f 30399/30399/21602 29339/29339/20699 29322/29322/20682 +f 30400/30400/21397 30402/30402/21400 30403/30403/21604 +f 30400/30400/21397 30403/30403/21604 30401/30401/21603 +f 30402/30402/21400 30388/30388/21383 30391/30391/21595 +f 30402/30402/21400 30391/30391/21595 30403/30403/21604 +f 30403/30403/21604 30391/30391/21595 29330/29330/20690 +f 30403/30403/21604 29330/29330/20690 29329/29329/20689 +f 30401/30401/21603 30403/30403/21604 29329/29329/20689 +f 30401/30401/21603 29329/29329/20689 29328/29328/20688 +f 30404/30404/21440 30405/30405/21442 30406/30406/21605 +f 30404/30404/21440 30406/30406/21605 30407/30407/21606 +f 30405/30405/21442 30396/30396/21600 30399/30399/21602 +f 30405/30405/21442 30399/30399/21602 30406/30406/21605 +f 30406/30406/21605 30399/30399/21602 29322/29322/20682 +f 30406/30406/21605 29322/29322/20682 29321/29321/20681 +f 30407/30407/21606 30406/30406/21605 29321/29321/20681 +f 30407/30407/21606 29321/29321/20681 29259/29259/20626 +f 30205/30205/21450 30208/30208/21453 30408/30408/21607 +f 30205/30205/21450 30408/30408/21607 30409/30409/21608 +f 30208/30208/21453 30216/30216/21459 30410/30410/21609 +f 30208/30208/21453 30410/30410/21609 30408/30408/21607 +f 30408/30408/21607 30410/30410/21609 29285/29285/20647 +f 30408/30408/21607 29285/29285/20647 29294/29294/20654 +f 30409/30409/21608 30408/30408/21607 29294/29294/20654 +f 30409/30409/21608 29294/29294/20654 29277/29277/20639 +f 30216/30216/21459 30218/30218/21461 30411/30411/21610 +f 30216/30216/21459 30411/30411/21610 30410/30410/21609 +f 30218/30218/21461 30179/30179/21424 30395/30395/21599 +f 30218/30218/21461 30395/30395/21599 30411/30411/21610 +f 30411/30411/21610 30395/30395/21599 29288/29288/20649 +f 30411/30411/21610 29288/29288/20649 29286/29286/20648 +f 30410/30410/21609 30411/30411/21610 29286/29286/20648 +f 30410/30410/21609 29286/29286/20648 29285/29285/20647 +f 29166/29166/20545 30250/30250/21487 30412/30412/21611 +f 29166/29166/20545 30412/30412/21611 30413/30413/21612 +f 30250/30250/21487 30205/30205/21450 30409/30409/21608 +f 30250/30250/21487 30409/30409/21608 30412/30412/21611 +f 30412/30412/21611 30409/30409/21608 29277/29277/20639 +f 30412/30412/21611 29277/29277/20639 29275/29275/20637 +f 30413/30413/21612 30412/30412/21611 29275/29275/20637 +f 30413/30413/21612 29275/29275/20637 29241/29241/20610 +f 30414/30414/21613 30415/30415/21447 30416/30416/21614 +f 30414/30414/21613 30416/30416/21614 30417/30417/21615 +f 30415/30415/21447 30418/30418/21432 30419/30419/21616 +f 30415/30415/21447 30419/30419/21616 30416/30416/21614 +f 30416/30416/21614 30419/30419/21616 29257/29257/20624 +f 30416/30416/21614 29257/29257/20624 29271/29271/20635 +f 30417/30417/21615 30416/30416/21614 29271/29271/20635 +f 30417/30417/21615 29271/29271/20635 29199/29199/20573 +f 30418/30418/21432 30420/30420/21617 30421/30421/21618 +f 30418/30418/21432 30421/30421/21618 30419/30419/21616 +f 30420/30420/21617 30404/30404/21440 30407/30407/21606 +f 30420/30420/21617 30407/30407/21606 30421/30421/21618 +f 30421/30421/21618 30407/30407/21606 29259/29259/20626 +f 30421/30421/21618 29259/29259/20626 29258/29258/20625 +f 30419/30419/21616 30421/30421/21618 29258/29258/20625 +f 30419/30419/21616 29258/29258/20625 29257/29257/20624 +f 29155/29155/20536 29158/29158/20539 30422/30422/21619 +f 29155/29155/20536 30422/30422/21619 30423/30423/21620 +f 29158/29158/20539 29166/29166/20545 30413/30413/21612 +f 29158/29158/20539 30413/30413/21612 30422/30422/21619 +f 30422/30422/21619 30413/30413/21612 29241/29241/20610 +f 30422/30422/21619 29241/29241/20610 29239/29239/20608 +f 30423/30423/21620 30422/30422/21619 29239/29239/20608 +f 30423/30423/21620 29239/29239/20608 29238/29238/20607 +f 30231/30231/21472 30424/30424/21621 30425/30425/21622 +f 30231/30231/21472 30425/30425/21622 30426/30426/21623 +f 30424/30424/21621 29155/29155/20536 30423/30423/21620 +f 30424/30424/21621 30423/30423/21620 30425/30425/21622 +f 30425/30425/21622 30423/30423/21620 29238/29238/20607 +f 30425/30425/21622 29238/29238/20607 30259/30259/21494 +f 30426/30426/21623 30425/30425/21622 30259/30259/21494 +f 30426/30426/21623 30259/30259/21494 29224/29224/20593 +f 30427/30427/20558 30428/30428/21491 30429/30429/21624 +f 30427/30427/20558 30429/30429/21624 30430/30430/21625 +f 30428/30428/21491 30431/30431/21464 30432/30432/21626 +f 30428/30428/21491 30432/30432/21626 30429/30429/21624 +f 30429/30429/21624 30432/30432/21626 29196/29196/20571 +f 30429/30429/21624 29196/29196/20571 30433/30433/20565 +f 30430/30430/21625 30429/30429/21624 30433/30433/20565 +f 30430/30430/21625 30433/30433/20565 30434/30434/20564 +f 30431/30431/21464 30435/30435/21467 30436/30436/21627 +f 30431/30431/21464 30436/30436/21627 30432/30432/21626 +f 30435/30435/21467 30414/30414/21613 30417/30417/21615 +f 30435/30435/21467 30417/30417/21615 30436/30436/21627 +f 30436/30436/21627 30417/30417/21615 29199/29199/20573 +f 30436/30436/21627 29199/29199/20573 29197/29197/20572 +f 30432/30432/21626 30436/30436/21627 29197/29197/20572 +f 30432/30432/21626 29197/29197/20572 29196/29196/20571 +f 30434/30434/20564 30437/30437/21628 30438/30438/21629 +f 30434/30434/20564 30438/30438/21629 30430/30430/21625 +f 29208/29208/20581 29207/29207/20580 30439/30439/21630 +f 29208/29208/20581 30439/30439/21630 30440/30440/21629 +f 30440/30440/21629 30439/30439/21630 29184/29184/20560 +f 30440/30440/21629 29184/29184/20560 29183/29183/20559 +f 30430/30430/21625 30438/30438/21629 30441/30441/21631 +f 30430/30430/21625 30441/30441/21631 30427/30427/20558 +f 30235/30235/21476 30232/30232/21473 30442/30442/21632 +f 30235/30235/21476 30442/30442/21632 30443/30443/21633 +f 30232/30232/21473 30231/30231/21472 30426/30426/21623 +f 30232/30232/21473 30426/30426/21623 30442/30442/21632 +f 30442/30442/21632 30426/30426/21623 29224/29224/20593 +f 30442/30442/21632 29224/29224/20593 29222/29222/20592 +f 30443/30443/21633 30442/30442/21632 29222/29222/20592 +f 30443/30443/21633 29222/29222/20592 29221/29221/20591 +f 29814/29814/21115 30444/30444/21634 30445/30445/21635 +f 29814/29814/21115 30445/30445/21635 29815/29815/21116 +f 30444/30444/21634 30446/30446/21476 30447/30447/21633 +f 30444/30444/21634 30447/30447/21633 30445/30445/21635 +f 30445/30445/21635 30447/30447/21633 30448/30448/20591 +f 30445/30445/21635 30448/30448/20591 30449/30449/21636 +f 29815/29815/21116 30445/30445/21635 30449/30449/21636 +f 29815/29815/21116 30449/30449/21636 29816/29816/21117 +f 30231/30231/21472 30234/30234/21475 30450/30450/21637 +f 30231/30231/21472 30450/30450/21637 30424/30424/21621 +f 30241/30241/21475 30242/30242/21480 30451/30451/21638 +f 30241/30241/21475 30451/30451/21638 30452/30452/21637 +f 30452/30452/21637 30451/30451/21638 29160/29160/20541 +f 30452/30452/21637 29160/29160/20541 29159/29159/20540 +f 30424/30424/21621 30450/30450/21637 29156/29156/20537 +f 30424/30424/21621 29156/29156/20537 29155/29155/20536 +f 30453/30453/21639 30454/30454/21640 30455/30455/21641 +f 30453/30453/21639 30455/30455/21641 30456/30456/21642 +f 30454/30454/21640 30275/30275/21508 30278/30278/21511 +f 30454/30454/21640 30278/30278/21511 30455/30455/21641 +f 30455/30455/21641 30278/30278/21511 30283/30283/21516 +f 30455/30455/21641 30283/30283/21516 30457/30457/21643 +f 30456/30456/21642 30455/30455/21641 30457/30457/21643 +f 30456/30456/21642 30457/30457/21643 30458/30458/21644 +f 30446/30446/21476 30444/30444/21634 30459/30459/21645 +f 30446/30446/21476 30459/30459/21645 30460/30460/21646 +f 30444/30444/21634 29814/29814/21115 30461/30461/21647 +f 30444/30444/21634 30461/30461/21647 30459/30459/21645 +f 30462/30462/21645 30463/30463/21648 30464/30464/21649 +f 30462/30462/21645 30464/30464/21649 30465/30465/21650 +f 30238/30238/21477 30462/30462/21645 30465/30465/21650 +f 30238/30238/21477 30465/30465/21650 30239/30239/21478 +f 29217/29217/20588 30466/30466/21651 30467/30467/21652 +f 29217/29217/20588 30467/30467/21652 29218/29218/20589 +f 30466/30466/21651 30468/30468/21653 30469/30469/21654 +f 30466/30466/21651 30469/30469/21654 30467/30467/21652 +f 30470/30470/21652 30471/30471/21654 29816/29816/21117 +f 30470/30470/21652 29816/29816/21117 30449/30449/21636 +f 30472/30472/21655 30470/30470/21652 30449/30449/21636 +f 30472/30472/21655 30449/30449/21636 30448/30448/20591 +f 30279/30279/21512 30276/30276/21509 30473/30473/21656 +f 30279/30279/21512 30473/30473/21656 30474/30474/21135 +f 30276/30276/21509 30275/30275/21508 30475/30475/21657 +f 30276/30276/21509 30475/30475/21657 30473/30473/21656 +f 30473/30473/21656 30475/30475/21657 30476/30476/21097 +f 30473/30473/21656 30476/30476/21097 30477/30477/21658 +f 30474/30474/21135 30473/30473/21656 30477/30477/21658 +f 30474/30474/21135 30477/30477/21658 30478/30478/21659 +f 29895/29895/21181 30479/30479/21660 30480/30480/21661 +f 29895/29895/21181 30480/30480/21661 29896/29896/21182 +f 30479/30479/21660 30481/30481/21662 30482/30482/21663 +f 30479/30479/21660 30482/30482/21663 30480/30480/21661 +f 30483/30483/21661 30484/30484/21663 30283/30283/21516 +f 30483/30483/21661 30283/30283/21516 30282/30282/21515 +f 30485/30485/21182 30483/30483/21661 30282/30282/21515 +f 30485/30485/21182 30282/30282/21515 30281/30281/21514 +f 29890/29890/21178 30486/30486/21664 30487/30487/21665 +f 29890/29890/21178 30487/30487/21665 29891/29891/21179 +f 30486/30486/21664 30488/30488/21666 30489/30489/21667 +f 30486/30486/21664 30489/30489/21667 30487/30487/21665 +f 30490/30490/21668 30491/30491/21667 30481/30481/21662 +f 30490/30490/21668 30481/30481/21662 30479/30479/21660 +f 29894/29894/21180 30490/30490/21668 30479/30479/21660 +f 29894/29894/21180 30479/30479/21660 29895/29895/21181 +f 29916/29916/21200 30492/30492/21669 30493/30493/21670 +f 29916/29916/21200 30493/30493/21670 29922/29922/21206 +f 30492/30492/21669 30494/30494/21671 30495/30495/21672 +f 30492/30492/21669 30495/30495/21672 30493/30493/21670 +f 30493/30493/21670 30495/30495/21672 30488/30488/21666 +f 30493/30493/21670 30488/30488/21666 30486/30486/21664 +f 29922/29922/21206 30493/30493/21670 30486/30486/21664 +f 29922/29922/21206 30486/30486/21664 29890/29890/21178 +f 30496/30496/21673 30497/30497/21674 30498/30498/21675 +f 30496/30496/21673 30498/30498/21675 30499/30499/21676 +f 30497/30497/21674 29778/29778/21084 29803/29803/21105 +f 30497/30497/21674 29803/29803/21105 30498/30498/21675 +f 30498/30498/21675 29803/29803/21105 29805/29805/21106 +f 30498/30498/21675 29805/29805/21106 30500/30500/21677 +f 30499/30499/21676 30498/30498/21675 30500/30500/21677 +f 30499/30499/21676 30500/30500/21677 30501/30501/21678 +f 30502/30502/21679 30503/30503/21677 30504/30504/21680 +f 30502/30502/21679 30504/30504/21680 30505/30505/21681 +f 30503/30503/21677 29785/29785/21089 29788/29788/21092 +f 30503/30503/21677 29788/29788/21092 30504/30504/21680 +f 30504/30504/21680 29788/29788/21092 29793/29793/21097 +f 30504/30504/21680 29793/29793/21097 30506/30506/21682 +f 30505/30505/21681 30504/30504/21680 30506/30506/21682 +f 30505/30505/21681 30506/30506/21682 30507/30507/21683 +f 29911/29911/21195 30508/30508/21684 30509/30509/21685 +f 29911/29911/21195 30509/30509/21685 29912/29912/21196 +f 30508/30508/21684 30510/30510/21686 30511/30511/21687 +f 30508/30508/21684 30511/30511/21687 30509/30509/21685 +f 30512/30512/21685 30513/30513/21687 30494/30494/21671 +f 30512/30512/21685 30494/30494/21671 30492/30492/21669 +f 29915/29915/21199 30512/30512/21685 30492/30492/21669 +f 29915/29915/21199 30492/30492/21669 29916/29916/21200 +f 30514/30514/21688 30515/30515/21689 30516/30516/21690 +f 30514/30514/21688 30516/30516/21690 30517/30517/21691 +f 30515/30515/21689 29709/29709/21025 29773/29773/21081 +f 30515/30515/21689 29773/29773/21081 30516/30516/21690 +f 30518/30518/21692 29777/29777/21083 29778/29778/21084 +f 30518/30518/21692 29778/29778/21084 30497/30497/21674 +f 30519/30519/21691 30518/30518/21692 30497/30497/21674 +f 30519/30519/21691 30497/30497/21674 30496/30496/21673 +f 29954/29954/21230 30520/30520/21693 30521/30521/21694 +f 29954/29954/21230 30521/30521/21694 29955/29955/21237 +f 30520/30520/21693 30522/30522/21695 30523/30523/21696 +f 30520/30520/21693 30523/30523/21696 30521/30521/21694 +f 30521/30521/21694 30523/30523/21696 30510/30510/21686 +f 30521/30521/21694 30510/30510/21686 30508/30508/21684 +f 29955/29955/21237 30521/30521/21694 30508/30508/21684 +f 29955/29955/21237 30508/30508/21684 29911/29911/21195 +f 29944/29944/21227 30524/30524/21697 30525/30525/21698 +f 29944/29944/21227 30525/30525/21698 29945/29945/21228 +f 30524/30524/21697 30526/30526/21699 30527/30527/21700 +f 30524/30524/21697 30527/30527/21700 30525/30525/21698 +f 30528/30528/21698 30529/30529/21700 30522/30522/21695 +f 30528/30528/21698 30522/30522/21695 30520/30520/21693 +f 30530/30530/21701 30528/30528/21698 30520/30520/21693 +f 30530/30530/21701 30520/30520/21693 29954/29954/21230 +f 30531/30531/21702 30532/30532/21703 30533/30533/21704 +f 30531/30531/21702 30533/30533/21704 30534/30534/21705 +f 30532/30532/21703 29700/29700/21016 29719/29719/21035 +f 30532/30532/21703 29719/29719/21035 30533/30533/21704 +f 30533/30533/21704 29719/29719/21035 29721/29721/21017 +f 30533/30533/21704 29721/29721/21017 30535/30535/21706 +f 30534/30534/21705 30533/30533/21704 30535/30535/21706 +f 30534/30534/21705 30535/30535/21706 30536/30536/21707 +f 30537/30537/21708 30538/30538/21706 30539/30539/21709 +f 30537/30537/21708 30539/30539/21709 30540/30540/21710 +f 30538/30538/21706 29701/29701/21017 29704/29704/21020 +f 30538/30538/21706 29704/29704/21020 30539/30539/21709 +f 30539/30539/21709 29704/29704/21020 29709/29709/21025 +f 30539/30539/21709 29709/29709/21025 30515/30515/21689 +f 30540/30540/21710 30539/30539/21709 30515/30515/21689 +f 30540/30540/21710 30515/30515/21689 30514/30514/21688 +f 30541/30541/21711 30542/30542/21712 30543/30543/21713 +f 30541/30541/21711 30543/30543/21713 30544/30544/21714 +f 30542/30542/21712 29632/29632/20955 29698/29698/21014 +f 30542/30542/21712 29698/29698/21014 30543/30543/21713 +f 30543/30543/21713 29698/29698/21014 29700/29700/21016 +f 30543/30543/21713 29700/29700/21016 30532/30532/21703 +f 30544/30544/21714 30543/30543/21713 30532/30532/21703 +f 30544/30544/21714 30532/30532/21703 30531/30531/21702 +f 30002/30002/21271 30545/30545/21715 30546/30546/21716 +f 30002/30002/21271 30546/30546/21716 30003/30003/21276 +f 30545/30545/21715 30547/30547/21717 30548/30548/21718 +f 30545/30545/21715 30548/30548/21718 30546/30546/21716 +f 30546/30546/21716 30548/30548/21718 30549/30549/21719 +f 30546/30546/21716 30549/30549/21719 30550/30550/21720 +f 30003/30003/21276 30546/30546/21716 30550/30550/21720 +f 30003/30003/21276 30550/30550/21720 29971/29971/21250 +f 29971/29971/21250 30550/30550/21720 30551/30551/21721 +f 29971/29971/21250 30551/30551/21721 29972/29972/21251 +f 30550/30550/21720 30549/30549/21719 30552/30552/21722 +f 30550/30550/21720 30552/30552/21722 30551/30551/21721 +f 30551/30551/21721 30552/30552/21722 30526/30526/21699 +f 30551/30551/21721 30526/30526/21699 30524/30524/21697 +f 29972/29972/21251 30551/30551/21721 30524/30524/21697 +f 29972/29972/21251 30524/30524/21697 29944/29944/21227 +f 29992/29992/21269 30553/30553/21723 30554/30554/21724 +f 29992/29992/21269 30554/30554/21724 29993/29993/21270 +f 30553/30553/21723 30555/30555/21725 30556/30556/21726 +f 30553/30553/21723 30556/30556/21726 30554/30554/21724 +f 30554/30554/21724 30556/30556/21726 30557/30557/21717 +f 30554/30554/21724 30557/30557/21717 30558/30558/21715 +f 29993/29993/21270 30554/30554/21724 30558/30558/21715 +f 29993/29993/21270 30558/30558/21715 29995/29995/21271 +f 30559/30559/21727 30560/30560/21728 30561/30561/21729 +f 30559/30559/21727 30561/30561/21729 30562/30562/21730 +f 30560/30560/21728 29578/29578/20907 29642/29642/20964 +f 30560/30560/21728 29642/29642/20964 30561/30561/21729 +f 30561/30561/21729 29642/29642/20964 29644/29644/20947 +f 30561/30561/21729 29644/29644/20947 30563/30563/21731 +f 30562/30562/21730 30561/30561/21729 30563/30563/21731 +f 30562/30562/21730 30563/30563/21731 30564/30564/21732 +f 30565/30565/21732 30566/30566/21731 30567/30567/21733 +f 30565/30565/21732 30567/30567/21733 30568/30568/21734 +f 30566/30566/21731 29624/29624/20947 29627/29627/20950 +f 30566/30566/21731 29627/29627/20950 30567/30567/21733 +f 30567/30567/21733 29627/29627/20950 29632/29632/20955 +f 30567/30567/21733 29632/29632/20955 30542/30542/21712 +f 30568/30568/21734 30567/30567/21733 30542/30542/21712 +f 30568/30568/21734 30542/30542/21712 30541/30541/21711 +f 30010/30010/21283 30569/30569/21735 30570/30570/21736 +f 30010/30010/21283 30570/30570/21736 30011/30011/21284 +f 30569/30569/21735 30571/30571/21737 30572/30572/21738 +f 30569/30569/21735 30572/30572/21738 30570/30570/21736 +f 30570/30570/21736 30572/30572/21738 30555/30555/21725 +f 30570/30570/21736 30555/30555/21725 30553/30553/21723 +f 30011/30011/21284 30570/30570/21736 30553/30553/21723 +f 30011/30011/21284 30553/30553/21723 29992/29992/21269 +f 30043/30043/21311 30573/30573/21739 30574/30574/21740 +f 30043/30043/21311 30574/30574/21740 30049/30049/21316 +f 30573/30573/21739 30575/30575/21741 30576/30576/21742 +f 30573/30573/21739 30576/30576/21742 30574/30574/21740 +f 30577/30577/21740 30578/30578/21743 30571/30571/21737 +f 30577/30577/21740 30571/30571/21737 30569/30569/21735 +f 30052/30052/21316 30577/30577/21740 30569/30569/21735 +f 30052/30052/21316 30569/30569/21735 30010/30010/21283 +f 30579/30579/21744 30580/30580/21745 30581/30581/21746 +f 30579/30579/21744 30581/30581/21746 30582/30582/21747 +f 30580/30580/21745 29566/29566/20895 29580/29580/20909 +f 30580/30580/21745 29580/29580/20909 30581/30581/21746 +f 30583/30583/21746 29582/29582/20910 29571/29571/20900 +f 30583/30583/21746 29571/29571/20900 30584/30584/21748 +f 30585/30585/21747 30583/30583/21746 30584/30584/21748 +f 30585/30585/21747 30584/30584/21748 30586/30586/21749 +f 30586/30586/21749 30584/30584/21748 30587/30587/21750 +f 30586/30586/21749 30587/30587/21750 30588/30588/21751 +f 30584/30584/21748 29571/29571/20900 29574/29574/20903 +f 30584/30584/21748 29574/29574/20903 30587/30587/21750 +f 30587/30587/21750 29574/29574/20903 29578/29578/20907 +f 30587/30587/21750 29578/29578/20907 30560/30560/21728 +f 30588/30588/21751 30587/30587/21750 30560/30560/21728 +f 30588/30588/21751 30560/30560/21728 30559/30559/21727 +f 30040/30040/21308 30589/30589/21752 30590/30590/21753 +f 30040/30040/21308 30590/30590/21753 30041/30041/21309 +f 30589/30589/21752 30591/30591/21754 30592/30592/21755 +f 30589/30589/21752 30592/30592/21755 30590/30590/21753 +f 30590/30590/21753 30592/30592/21755 30575/30575/21741 +f 30590/30590/21753 30575/30575/21741 30573/30573/21739 +f 30041/30041/21309 30590/30590/21753 30573/30573/21739 +f 30041/30041/21309 30573/30573/21739 30043/30043/21311 +f 30593/30593/21756 30594/30594/21757 30595/30595/21758 +f 30593/30593/21756 30595/30595/21758 30596/30596/21759 +f 30594/30594/21757 29508/29508/20842 29564/29564/20893 +f 30594/30594/21757 29564/29564/20893 30595/30595/21758 +f 30595/30595/21758 29564/29564/20893 29566/29566/20895 +f 30595/30595/21758 29566/29566/20895 30580/30580/21745 +f 30596/30596/21759 30595/30595/21758 30580/30580/21745 +f 30596/30596/21759 30580/30580/21745 30579/30579/21744 +f 30074/30074/21335 30597/30597/21760 30598/30598/21761 +f 30074/30074/21335 30598/30598/21761 30075/30075/21336 +f 30597/30597/21760 30599/30599/21762 30600/30600/21763 +f 30597/30597/21760 30600/30600/21763 30598/30598/21761 +f 30598/30598/21761 30600/30600/21763 30591/30591/21754 +f 30598/30598/21761 30591/30591/21754 30589/30589/21752 +f 30075/30075/21336 30598/30598/21761 30589/30589/21752 +f 30075/30075/21336 30589/30589/21752 30040/30040/21308 +f 30095/30095/21351 30601/30601/21764 30602/30602/21765 +f 30095/30095/21351 30602/30602/21765 30101/30101/21357 +f 30601/30601/21764 30603/30603/21766 30604/30604/21767 +f 30601/30601/21764 30604/30604/21767 30602/30602/21765 +f 30602/30602/21765 30604/30604/21767 30599/30599/21762 +f 30602/30602/21765 30599/30599/21762 30597/30597/21760 +f 30101/30101/21357 30602/30602/21765 30597/30597/21760 +f 30101/30101/21357 30597/30597/21760 30074/30074/21335 +f 30605/30605/21768 30606/30606/21769 30607/30607/21770 +f 30605/30605/21768 30607/30607/21770 30608/30608/21771 +f 30606/30606/21769 29493/29493/20829 29517/29517/20850 +f 30606/30606/21769 29517/29517/20850 30607/30607/21770 +f 30607/30607/21770 29517/29517/20850 29500/29500/20834 +f 30607/30607/21770 29500/29500/20834 30609/30609/21772 +f 30608/30608/21771 30607/30607/21770 30609/30609/21772 +f 30608/30608/21771 30609/30609/21772 30610/30610/21773 +f 30610/30610/21773 30609/30609/21772 30611/30611/21774 +f 30610/30610/21773 30611/30611/21774 30612/30612/21775 +f 30609/30609/21772 29500/29500/20834 29503/29503/20837 +f 30609/30609/21772 29503/29503/20837 30611/30611/21774 +f 30611/30611/21774 29503/29503/20837 29508/29508/20842 +f 30611/30611/21774 29508/29508/20842 30594/30594/21757 +f 30612/30612/21775 30611/30611/21774 30594/30594/21757 +f 30612/30612/21775 30594/30594/21757 30593/30593/21756 +f 30090/30090/21348 30613/30613/21776 30614/30614/21777 +f 30090/30090/21348 30614/30614/21777 30091/30091/21349 +f 30613/30613/21776 30615/30615/21778 30616/30616/21779 +f 30613/30613/21776 30616/30616/21779 30614/30614/21777 +f 30617/30617/21777 30618/30618/21779 30603/30603/21766 +f 30617/30617/21777 30603/30603/21766 30601/30601/21764 +f 30094/30094/21349 30617/30617/21777 30601/30601/21764 +f 30094/30094/21349 30601/30601/21764 30095/30095/21351 +f 30619/30619/21780 30620/30620/21781 30621/30621/21782 +f 30619/30619/21780 30621/30621/21782 30622/30622/21783 +f 30620/30620/21781 29432/29432/20780 29489/29489/20827 +f 30620/30620/21781 29489/29489/20827 30621/30621/21782 +f 30623/30623/21782 29492/29492/20827 29493/29493/20829 +f 30623/30623/21782 29493/29493/20829 30606/30606/21769 +f 30622/30622/21783 30621/30621/21782 30624/30624/21784 +f 30622/30622/21783 30624/30624/21784 30625/30625/21785 +f 30123/30123/21377 30626/30626/21786 30627/30627/21787 +f 30123/30123/21377 30627/30627/21787 30129/30129/21382 +f 30626/30626/21786 30628/30628/21788 30629/30629/21789 +f 30626/30626/21786 30629/30629/21789 30627/30627/21787 +f 30627/30627/21787 30629/30629/21789 30615/30615/21778 +f 30627/30627/21787 30615/30615/21778 30613/30613/21776 +f 30129/30129/21382 30627/30627/21787 30613/30613/21776 +f 30129/30129/21382 30613/30613/21776 30090/30090/21348 +f 30120/30120/21375 30630/30630/21790 30631/30631/21791 +f 30120/30120/21375 30631/30631/21791 30121/30121/21376 +f 30630/30630/21790 30632/30632/21792 30633/30633/21793 +f 30630/30630/21790 30633/30633/21793 30631/30631/21791 +f 30631/30631/21791 30633/30633/21793 30628/30628/21788 +f 30631/30631/21791 30628/30628/21788 30626/30626/21786 +f 30121/30121/21376 30631/30631/21791 30626/30626/21786 +f 30121/30121/21376 30626/30626/21786 30123/30123/21377 +f 30634/30634/21794 30635/30635/21795 30636/30636/21796 +f 30634/30634/21794 30636/30636/21796 30637/30637/21797 +f 30635/30635/21795 29423/29423/20771 29441/29441/20789 +f 30635/30635/21795 29441/29441/20789 30636/30636/21796 +f 30636/30636/21796 29441/29441/20789 29424/29424/20772 +f 30636/30636/21796 29424/29424/20772 30638/30638/21798 +f 30637/30637/21797 30636/30636/21796 30638/30638/21798 +f 30637/30637/21797 30638/30638/21798 30639/30639/21799 +f 30639/30639/21799 30638/30638/21798 30640/30640/21800 +f 30639/30639/21799 30640/30640/21800 30641/30641/21801 +f 30638/30638/21798 29424/29424/20772 29427/29427/20775 +f 30638/30638/21798 29427/29427/20775 30640/30640/21800 +f 30640/30640/21800 29427/29427/20775 29432/29432/20780 +f 30640/30640/21800 29432/29432/20780 30620/30620/21781 +f 30641/30641/21801 30640/30640/21800 30620/30620/21781 +f 30641/30641/21801 30620/30620/21781 30619/30619/21780 +f 30642/30642/21802 30643/30643/21803 30644/30644/21804 +f 30642/30642/21802 30644/30644/21804 30645/30645/21805 +f 30643/30643/21803 29418/29418/20767 29421/29421/20769 +f 30643/30643/21803 29421/29421/20769 30644/30644/21804 +f 30644/30644/21804 29421/29421/20769 29423/29423/20771 +f 30644/30644/21804 29423/29423/20771 30635/30635/21795 +f 30645/30645/21805 30644/30644/21804 30635/30635/21795 +f 30645/30645/21805 30635/30635/21795 30634/30634/21794 +f 30169/30169/21416 30646/30646/21806 30647/30647/21807 +f 30169/30169/21416 30647/30647/21807 30175/30175/21422 +f 30646/30646/21806 30648/30648/21808 30649/30649/21809 +f 30646/30646/21806 30649/30649/21809 30647/30647/21807 +f 30650/30650/21807 30651/30651/21809 30652/30652/21810 +f 30650/30650/21807 30652/30652/21810 30653/30653/21811 +f 30654/30654/21812 30650/30650/21807 30653/30653/21811 +f 30654/30654/21812 30653/30653/21811 30146/30146/21395 +f 30146/30146/21395 30653/30653/21811 30655/30655/21813 +f 30146/30146/21395 30655/30655/21813 30147/30147/21396 +f 30653/30653/21811 30652/30652/21810 30656/30656/21814 +f 30653/30653/21811 30656/30656/21814 30655/30655/21813 +f 30655/30655/21813 30656/30656/21814 30632/30632/21792 +f 30655/30655/21813 30632/30632/21792 30630/30630/21790 +f 30147/30147/21396 30655/30655/21813 30630/30630/21790 +f 30147/30147/21396 30630/30630/21790 30120/30120/21375 +f 30166/30166/21414 30657/30657/21815 30658/30658/21816 +f 30166/30166/21414 30658/30658/21816 30167/30167/21415 +f 30657/30657/21815 30659/30659/21817 30660/30660/21818 +f 30657/30657/21815 30660/30660/21818 30658/30658/21816 +f 30658/30658/21816 30660/30660/21818 30648/30648/21808 +f 30658/30658/21816 30648/30648/21808 30646/30646/21806 +f 30167/30167/21415 30658/30658/21816 30646/30646/21806 +f 30167/30167/21415 30646/30646/21806 30169/30169/21416 +f 30661/30661/21819 30662/30662/21820 30663/30663/21821 +f 30661/30661/21819 30663/30663/21821 30664/30664/21822 +f 30662/30662/21820 29311/29311/20671 29363/29363/20721 +f 30662/30662/21820 29363/29363/20721 30663/30663/21821 +f 30663/30663/21821 29363/29363/20721 29346/29346/20704 +f 30663/30663/21821 29346/29346/20704 30665/30665/21823 +f 30664/30664/21822 30663/30663/21821 30665/30665/21823 +f 30664/30664/21822 30665/30665/21823 30666/30666/21824 +f 30666/30666/21824 30665/30665/21823 30667/30667/21825 +f 30666/30666/21824 30667/30667/21825 30668/30668/21826 +f 30665/30665/21823 29346/29346/20704 29349/29349/20707 +f 30665/30665/21823 29349/29349/20707 30667/30667/21825 +f 30669/30669/21825 30670/30670/20707 29418/29418/20767 +f 30669/30669/21825 29418/29418/20767 30643/30643/21803 +f 30671/30671/21827 30669/30669/21825 30643/30643/21803 +f 30671/30671/21827 30643/30643/21803 30642/30642/21802 +f 30184/30184/21429 30672/30672/21828 30673/30673/21829 +f 30184/30184/21429 30673/30673/21829 30185/30185/21430 +f 30672/30672/21828 30674/30674/21830 30675/30675/21831 +f 30672/30672/21828 30675/30675/21831 30673/30673/21829 +f 30673/30673/21829 30675/30675/21831 30659/30659/21817 +f 30673/30673/21829 30659/30659/21817 30657/30657/21815 +f 30185/30185/21430 30673/30673/21829 30657/30657/21815 +f 30185/30185/21430 30657/30657/21815 30166/30166/21414 +f 30213/30213/21457 30676/30676/21832 30677/30677/21833 +f 30213/30213/21457 30677/30677/21833 30219/30219/21462 +f 30676/30676/21832 30678/30678/21834 30679/30679/21835 +f 30676/30676/21832 30679/30679/21835 30677/30677/21833 +f 30677/30677/21833 30679/30679/21835 30674/30674/21830 +f 30677/30677/21833 30674/30674/21830 30672/30672/21828 +f 30219/30219/21462 30677/30677/21833 30672/30672/21828 +f 30219/30219/21462 30672/30672/21828 30184/30184/21429 +f 30680/30680/21836 30681/30681/21837 30682/30682/21838 +f 30680/30680/21836 30682/30682/21838 30683/30683/21839 +f 30681/30681/21837 29299/29299/20659 29313/29313/20673 +f 30681/30681/21837 29313/29313/20673 30682/30682/21838 +f 30682/30682/21838 29313/29313/20673 29304/29304/20664 +f 30682/30682/21838 29304/29304/20664 30684/30684/21840 +f 30683/30683/21839 30682/30682/21838 30684/30684/21840 +f 30683/30683/21839 30684/30684/21840 30685/30685/21841 +f 30685/30685/21841 30684/30684/21840 30686/30686/21842 +f 30685/30685/21841 30686/30686/21842 30687/30687/21843 +f 30684/30684/21840 29304/29304/20664 29307/29307/20667 +f 30684/30684/21840 29307/29307/20667 30686/30686/21842 +f 30686/30686/21842 29307/29307/20667 29311/29311/20671 +f 30686/30686/21842 29311/29311/20671 30662/30662/21820 +f 30687/30687/21843 30686/30686/21842 30662/30662/21820 +f 30687/30687/21843 30662/30662/21820 30661/30661/21819 +f 30210/30210/21455 30688/30688/21844 30689/30689/21845 +f 30210/30210/21455 30689/30689/21845 30211/30211/21456 +f 30688/30688/21844 30690/30690/21846 30691/30691/21847 +f 30688/30688/21844 30691/30691/21847 30689/30689/21845 +f 30689/30689/21845 30691/30691/21847 30678/30678/21834 +f 30689/30689/21845 30678/30678/21834 30676/30676/21832 +f 30211/30211/21456 30689/30689/21845 30676/30676/21832 +f 30211/30211/21456 30676/30676/21832 30213/30213/21457 +f 30692/30692/21848 30693/30693/21849 30694/30694/21850 +f 30692/30692/21848 30694/30694/21850 30695/30695/21851 +f 30693/30693/21849 29233/29233/20602 29297/29297/20657 +f 30693/30693/21849 29297/29297/20657 30694/30694/21850 +f 30694/30694/21850 29297/29297/20657 29299/29299/20659 +f 30694/30694/21850 29299/29299/20659 30681/30681/21837 +f 30695/30695/21851 30694/30694/21850 30681/30681/21837 +f 30695/30695/21851 30681/30681/21837 30680/30680/21836 +f 30252/30252/20543 30696/30696/21852 30697/30697/21853 +f 30252/30252/20543 30697/30697/21853 30253/30253/21488 +f 30696/30696/21852 30698/30698/21854 30699/30699/21855 +f 30696/30696/21852 30699/30699/21855 30697/30697/21853 +f 30697/30697/21853 30699/30699/21855 30690/30690/21846 +f 30697/30697/21853 30690/30690/21846 30688/30688/21844 +f 30253/30253/21488 30697/30697/21853 30688/30688/21844 +f 30253/30253/21488 30688/30688/21844 30210/30210/21455 +f 29160/29160/20541 30700/30700/21856 30701/30701/21857 +f 29160/29160/20541 30701/30701/21857 29161/29161/20542 +f 30700/30700/21856 30702/30702/21858 30703/30703/21859 +f 30700/30700/21856 30703/30703/21859 30701/30701/21857 +f 30701/30701/21857 30703/30703/21859 30704/30704/21854 +f 30701/30701/21857 30704/30704/21854 30705/30705/21852 +f 29161/29161/20542 30701/30701/21857 30705/30705/21852 +f 29161/29161/20542 30705/30705/21852 29163/29163/20543 +f 30706/30706/21860 30707/30707/21861 30708/30708/21862 +f 30706/30706/21860 30708/30708/21862 30709/30709/21863 +f 30707/30707/21861 29145/29145/20526 29246/29246/20615 +f 30707/30707/21861 29246/29246/20615 30708/30708/21862 +f 30708/30708/21862 29246/29246/20615 29248/29248/20594 +f 30708/30708/21862 29248/29248/20594 30710/30710/21864 +f 30709/30709/21863 30708/30708/21862 30710/30710/21864 +f 30709/30709/21863 30710/30710/21864 30711/30711/21865 +f 30712/30712/21865 30713/30713/21864 30714/30714/21866 +f 30712/30712/21865 30714/30714/21866 30715/30715/21867 +f 30713/30713/21864 29225/29225/20594 29228/29228/20597 +f 30713/30713/21864 29228/29228/20597 30714/30714/21866 +f 30714/30714/21866 29228/29228/20597 29233/29233/20602 +f 30714/30714/21866 29233/29233/20602 30693/30693/21849 +f 30715/30715/21867 30714/30714/21866 30693/30693/21849 +f 30715/30715/21867 30693/30693/21849 30692/30692/21848 +f 30242/30242/21480 30716/30716/21868 30717/30717/21869 +f 30242/30242/21480 30717/30717/21869 30451/30451/21638 +f 30716/30716/21868 30718/30718/21870 30719/30719/21871 +f 30716/30716/21868 30719/30719/21871 30717/30717/21869 +f 30717/30717/21869 30719/30719/21871 30702/30702/21858 +f 30717/30717/21869 30702/30702/21858 30700/30700/21856 +f 30451/30451/21638 30717/30717/21869 30700/30700/21856 +f 30451/30451/21638 30700/30700/21856 29160/29160/20541 +f 30239/30239/21478 30465/30465/21650 30720/30720/21872 +f 30239/30239/21478 30720/30720/21872 30240/30240/21479 +f 30465/30465/21650 30464/30464/21649 30721/30721/21873 +f 30465/30465/21650 30721/30721/21873 30720/30720/21872 +f 30720/30720/21872 30721/30721/21873 30718/30718/21870 +f 30720/30720/21872 30718/30718/21870 30716/30716/21868 +f 30240/30240/21479 30720/30720/21872 30716/30716/21868 +f 30240/30240/21479 30716/30716/21868 30242/30242/21480 +f 29141/29141/20522 29138/29138/20519 30722/30722/21874 +f 29141/29141/20522 30722/30722/21874 29214/29214/20585 +f 29138/29138/20519 29137/29137/20518 30723/30723/21875 +f 29138/29138/20519 30723/30723/21875 30722/30722/21874 +f 30722/30722/21874 30723/30723/21875 30468/30468/21653 +f 30722/30722/21874 30468/30468/21653 30466/30466/21651 +f 29214/29214/20585 30722/30722/21874 30466/30466/21651 +f 29214/29214/20585 30466/30466/21651 29217/29217/20588 +f 30724/30724/21876 30725/30725/21877 30726/30726/21878 +f 30724/30724/21876 30726/30726/21878 30727/30727/21879 +f 30725/30725/21877 29137/29137/20518 29140/29140/20521 +f 30725/30725/21877 29140/29140/20521 30726/30726/21878 +f 30726/30726/21878 29140/29140/20521 29145/29145/20526 +f 30726/30726/21878 29145/29145/20526 30707/30707/21861 +f 30727/30727/21879 30726/30726/21878 30707/30707/21861 +f 30727/30727/21879 30707/30707/21861 30706/30706/21860 +f 29150/29150/20531 29147/29147/20528 30728/30728/21880 +f 29150/29150/20531 30728/30728/21880 30257/30257/21492 +f 29147/29147/20528 29146/29146/20527 30729/30729/21881 +f 29147/29147/20528 30729/30729/21881 30728/30728/21880 +f 30728/30728/21880 30729/30729/21881 30730/30730/21882 +f 30728/30728/21880 30730/30730/21882 30731/30731/21883 +f 30257/30257/21492 30728/30728/21880 30731/30731/21883 +f 30257/30257/21492 30731/30731/21883 30225/30225/21468 +f 29146/29146/20527 30732/30732/21884 30733/30733/21885 +f 29146/29146/20527 30733/30733/21885 30729/30729/21881 +f 30732/30732/21884 30724/30724/21876 30727/30727/21879 +f 30732/30732/21884 30727/30727/21879 30733/30733/21885 +f 30733/30733/21885 30727/30727/21879 30706/30706/21860 +f 30733/30733/21885 30706/30706/21860 30734/30734/21886 +f 30729/30729/21881 30733/30733/21885 30734/30734/21886 +f 30729/30729/21881 30734/30734/21886 30730/30730/21882 +f 30203/30203/21448 30735/30735/21887 30736/30736/21888 +f 30203/30203/21448 30736/30736/21888 30204/30204/21449 +f 30735/30735/21887 30737/30737/21889 30738/30738/21890 +f 30735/30735/21887 30738/30738/21890 30736/30736/21888 +f 30736/30736/21888 30738/30738/21890 30739/30739/21891 +f 30736/30736/21888 30739/30739/21891 30740/30740/21892 +f 30204/30204/21449 30736/30736/21888 30740/30740/21892 +f 30204/30204/21449 30740/30740/21892 30191/30191/21436 +f 30737/30737/21889 30741/30741/21893 30742/30742/21894 +f 30737/30737/21889 30742/30742/21894 30738/30738/21890 +f 30741/30741/21893 30712/30712/21865 30715/30715/21867 +f 30741/30741/21893 30715/30715/21867 30742/30742/21894 +f 30742/30742/21894 30715/30715/21867 30692/30692/21848 +f 30742/30742/21894 30692/30692/21848 30743/30743/21895 +f 30738/30738/21890 30742/30742/21894 30743/30743/21895 +f 30738/30738/21890 30743/30743/21895 30739/30739/21891 +f 30225/30225/21468 30731/30731/21883 30744/30744/21896 +f 30225/30225/21468 30744/30744/21896 30226/30226/21469 +f 30731/30731/21883 30730/30730/21882 30745/30745/21897 +f 30731/30731/21883 30745/30745/21897 30744/30744/21896 +f 30744/30744/21896 30745/30745/21897 30746/30746/21889 +f 30744/30744/21896 30746/30746/21889 30747/30747/21898 +f 30226/30226/21469 30744/30744/21896 30747/30747/21898 +f 30226/30226/21469 30747/30747/21898 30227/30227/21448 +f 30730/30730/21882 30734/30734/21886 30748/30748/21899 +f 30730/30730/21882 30748/30748/21899 30745/30745/21897 +f 30734/30734/21886 30706/30706/21860 30709/30709/21863 +f 30734/30734/21886 30709/30709/21863 30748/30748/21899 +f 30748/30748/21899 30709/30709/21863 30711/30711/21865 +f 30748/30748/21899 30711/30711/21865 30749/30749/21900 +f 30745/30745/21897 30748/30748/21899 30749/30749/21900 +f 30745/30745/21897 30749/30749/21900 30746/30746/21889 +f 30191/30191/21436 30740/30740/21892 30750/30750/21901 +f 30191/30191/21436 30750/30750/21901 30192/30192/21437 +f 30740/30740/21892 30739/30739/21891 30751/30751/21902 +f 30740/30740/21892 30751/30751/21902 30750/30750/21901 +f 30750/30750/21901 30751/30751/21902 30752/30752/21903 +f 30750/30750/21901 30752/30752/21903 30753/30753/21904 +f 30192/30192/21437 30750/30750/21901 30753/30753/21904 +f 30192/30192/21437 30753/30753/21904 30193/30193/21438 +f 30739/30739/21891 30743/30743/21895 30754/30754/21905 +f 30739/30739/21891 30754/30754/21905 30751/30751/21902 +f 30743/30743/21895 30692/30692/21848 30695/30695/21851 +f 30743/30743/21895 30695/30695/21851 30754/30754/21905 +f 30754/30754/21905 30695/30695/21851 30680/30680/21836 +f 30754/30754/21905 30680/30680/21836 30755/30755/21906 +f 30751/30751/21902 30754/30754/21905 30755/30755/21906 +f 30751/30751/21902 30755/30755/21906 30752/30752/21903 +f 30159/30159/21407 30756/30756/21907 30757/30757/21908 +f 30159/30159/21407 30757/30757/21908 30160/30160/21408 +f 30756/30756/21907 30758/30758/21909 30759/30759/21910 +f 30756/30756/21907 30759/30759/21910 30757/30757/21908 +f 30757/30757/21908 30759/30759/21910 30760/30760/21911 +f 30757/30757/21908 30760/30760/21911 30761/30761/21912 +f 30160/30160/21408 30757/30757/21908 30761/30761/21912 +f 30160/30160/21408 30761/30761/21912 30153/30153/21401 +f 30758/30758/21909 30762/30762/21913 30763/30763/21914 +f 30758/30758/21909 30763/30763/21914 30759/30759/21910 +f 30762/30762/21913 30685/30685/21841 30687/30687/21843 +f 30762/30762/21913 30687/30687/21843 30763/30763/21914 +f 30763/30763/21914 30687/30687/21843 30661/30661/21819 +f 30763/30763/21914 30661/30661/21819 30764/30764/21915 +f 30759/30759/21910 30763/30763/21914 30764/30764/21915 +f 30759/30759/21910 30764/30764/21915 30760/30760/21911 +f 30193/30193/21438 30753/30753/21904 30765/30765/21916 +f 30193/30193/21438 30765/30765/21916 30198/30198/21443 +f 30753/30753/21904 30752/30752/21903 30766/30766/21917 +f 30753/30753/21904 30766/30766/21917 30765/30765/21916 +f 30765/30765/21916 30766/30766/21917 30758/30758/21909 +f 30765/30765/21916 30758/30758/21909 30756/30756/21907 +f 30198/30198/21443 30765/30765/21916 30756/30756/21907 +f 30198/30198/21443 30756/30756/21907 30159/30159/21407 +f 30752/30752/21903 30755/30755/21906 30767/30767/21918 +f 30752/30752/21903 30767/30767/21918 30766/30766/21917 +f 30755/30755/21906 30680/30680/21836 30683/30683/21839 +f 30755/30755/21906 30683/30683/21839 30767/30767/21918 +f 30767/30767/21918 30683/30683/21839 30685/30685/21841 +f 30767/30767/21918 30685/30685/21841 30762/30762/21913 +f 30766/30766/21917 30767/30767/21918 30762/30762/21913 +f 30766/30766/21917 30762/30762/21913 30758/30758/21909 +f 30135/30135/21387 30768/30768/21919 30769/30769/21920 +f 30135/30135/21387 30769/30769/21920 30136/30136/21388 +f 30768/30768/21919 30770/30770/21921 30771/30771/21922 +f 30768/30768/21919 30771/30771/21922 30769/30769/21920 +f 30772/30772/21920 30773/30773/21923 30774/30774/21924 +f 30772/30772/21920 30774/30774/21924 30775/30775/21925 +f 30138/30138/21388 30772/30772/21920 30775/30775/21925 +f 30138/30138/21388 30775/30775/21925 30113/30113/21369 +f 30770/30770/21921 30776/30776/21926 30777/30777/21927 +f 30770/30770/21921 30777/30777/21927 30771/30771/21922 +f 30776/30776/21926 30666/30666/21824 30668/30668/21826 +f 30776/30776/21926 30668/30668/21826 30777/30777/21927 +f 30778/30778/21928 30671/30671/21827 30642/30642/21802 +f 30778/30778/21928 30642/30642/21802 30779/30779/21929 +f 30773/30773/21923 30778/30778/21928 30779/30779/21929 +f 30773/30773/21923 30779/30779/21929 30774/30774/21924 +f 30153/30153/21401 30761/30761/21912 30780/30780/21930 +f 30153/30153/21401 30780/30780/21930 30154/30154/21402 +f 30761/30761/21912 30760/30760/21911 30781/30781/21931 +f 30761/30761/21912 30781/30781/21931 30780/30780/21930 +f 30780/30780/21930 30781/30781/21931 30770/30770/21921 +f 30780/30780/21930 30770/30770/21921 30768/30768/21919 +f 30154/30154/21402 30780/30780/21930 30768/30768/21919 +f 30154/30154/21402 30768/30768/21919 30135/30135/21387 +f 30760/30760/21911 30764/30764/21915 30782/30782/21932 +f 30760/30760/21911 30782/30782/21932 30781/30781/21931 +f 30764/30764/21915 30661/30661/21819 30664/30664/21822 +f 30764/30764/21915 30664/30664/21822 30782/30782/21932 +f 30782/30782/21932 30664/30664/21822 30666/30666/21824 +f 30782/30782/21932 30666/30666/21824 30776/30776/21926 +f 30781/30781/21931 30782/30782/21932 30776/30776/21926 +f 30781/30781/21931 30776/30776/21926 30770/30770/21921 +f 30113/30113/21369 30775/30775/21925 30783/30783/21933 +f 30113/30113/21369 30783/30783/21933 30114/30114/21370 +f 30775/30775/21925 30774/30774/21924 30784/30784/21934 +f 30775/30775/21925 30784/30784/21934 30783/30783/21933 +f 30783/30783/21933 30784/30784/21934 30785/30785/21935 +f 30783/30783/21933 30785/30785/21935 30786/30786/21936 +f 30114/30114/21370 30783/30783/21933 30786/30786/21936 +f 30114/30114/21370 30786/30786/21936 30107/30107/21363 +f 30774/30774/21924 30779/30779/21929 30787/30787/21937 +f 30774/30774/21924 30787/30787/21937 30784/30784/21934 +f 30779/30779/21929 30642/30642/21802 30645/30645/21805 +f 30779/30779/21929 30645/30645/21805 30787/30787/21937 +f 30787/30787/21937 30645/30645/21805 30634/30634/21794 +f 30787/30787/21937 30634/30634/21794 30788/30788/21938 +f 30784/30784/21934 30787/30787/21937 30788/30788/21938 +f 30784/30784/21934 30788/30788/21938 30785/30785/21935 +f 30081/30081/21341 30789/30789/21939 30790/30790/21940 +f 30081/30081/21341 30790/30790/21940 30082/30082/21342 +f 30789/30789/21939 30791/30791/21941 30792/30792/21942 +f 30789/30789/21939 30792/30792/21942 30790/30790/21940 +f 30790/30790/21940 30792/30792/21942 30793/30793/21943 +f 30790/30790/21940 30793/30793/21943 30794/30794/21944 +f 30082/30082/21342 30790/30790/21940 30794/30794/21944 +f 30082/30082/21342 30794/30794/21944 30064/30064/21328 +f 30791/30791/21941 30795/30795/21945 30796/30796/21946 +f 30791/30791/21941 30796/30796/21946 30792/30792/21942 +f 30795/30795/21945 30639/30639/21799 30641/30641/21801 +f 30795/30795/21945 30641/30641/21801 30796/30796/21946 +f 30796/30796/21946 30641/30641/21801 30619/30619/21780 +f 30796/30796/21946 30619/30619/21780 30797/30797/21947 +f 30792/30792/21942 30796/30796/21946 30797/30797/21947 +f 30792/30792/21942 30797/30797/21947 30793/30793/21943 +f 30107/30107/21363 30786/30786/21936 30798/30798/21948 +f 30107/30107/21363 30798/30798/21948 30108/30108/21364 +f 30786/30786/21936 30785/30785/21935 30799/30799/21949 +f 30786/30786/21936 30799/30799/21949 30798/30798/21948 +f 30798/30798/21948 30799/30799/21949 30791/30791/21941 +f 30798/30798/21948 30791/30791/21941 30789/30789/21939 +f 30108/30108/21364 30798/30798/21948 30789/30789/21939 +f 30108/30108/21364 30789/30789/21939 30081/30081/21341 +f 30785/30785/21935 30788/30788/21938 30800/30800/21950 +f 30785/30785/21935 30800/30800/21950 30799/30799/21949 +f 30788/30788/21938 30634/30634/21794 30637/30637/21797 +f 30788/30788/21938 30637/30637/21797 30800/30800/21950 +f 30800/30800/21950 30637/30637/21797 30639/30639/21799 +f 30800/30800/21950 30639/30639/21799 30795/30795/21945 +f 30799/30799/21949 30800/30800/21950 30795/30795/21945 +f 30799/30799/21949 30795/30795/21945 30791/30791/21941 +f 30064/30064/21328 30794/30794/21944 30801/30801/21951 +f 30064/30064/21328 30801/30801/21951 30065/30065/21329 +f 30794/30794/21944 30793/30793/21943 30802/30802/21952 +f 30794/30794/21944 30802/30802/21952 30801/30801/21951 +f 30801/30801/21951 30802/30802/21952 30803/30803/21953 +f 30801/30801/21951 30803/30803/21953 30804/30804/21954 +f 30065/30065/21329 30801/30801/21951 30804/30804/21954 +f 30065/30065/21329 30804/30804/21954 30067/30067/21322 +f 30793/30793/21943 30797/30797/21947 30805/30805/21955 +f 30793/30793/21943 30805/30805/21955 30802/30802/21952 +f 30797/30797/21947 30619/30619/21780 30622/30622/21783 +f 30797/30797/21947 30622/30622/21783 30805/30805/21955 +f 30805/30805/21955 30622/30622/21783 30625/30625/21785 +f 30805/30805/21955 30625/30625/21785 30806/30806/21956 +f 30802/30802/21952 30805/30805/21955 30806/30806/21956 +f 30802/30802/21952 30806/30806/21956 30803/30803/21953 +f 30033/30033/21302 30807/30807/21957 30808/30808/21958 +f 30033/30033/21302 30808/30808/21958 30034/30034/21303 +f 30807/30807/21957 30809/30809/21959 30810/30810/21960 +f 30807/30807/21957 30810/30810/21960 30808/30808/21958 +f 30808/30808/21958 30810/30810/21960 30811/30811/21961 +f 30808/30808/21958 30811/30811/21961 30812/30812/21962 +f 30034/30034/21303 30808/30808/21958 30812/30812/21962 +f 30034/30034/21303 30812/30812/21962 30017/30017/21290 +f 30813/30813/21959 30814/30814/21963 30815/30815/21964 +f 30813/30813/21959 30815/30815/21964 30816/30816/21960 +f 30814/30814/21963 30610/30610/21773 30612/30612/21775 +f 30814/30814/21963 30612/30612/21775 30815/30815/21964 +f 30815/30815/21964 30612/30612/21775 30593/30593/21756 +f 30815/30815/21964 30593/30593/21756 30817/30817/21965 +f 30816/30816/21960 30815/30815/21964 30817/30817/21965 +f 30816/30816/21960 30817/30817/21965 30818/30818/21961 +f 30819/30819/21322 30820/30820/21954 30821/30821/21966 +f 30819/30819/21322 30821/30821/21966 30822/30822/21967 +f 30820/30820/21954 30823/30823/21953 30824/30824/21968 +f 30820/30820/21954 30824/30824/21968 30821/30821/21966 +f 30821/30821/21966 30824/30824/21968 30813/30813/21959 +f 30821/30821/21966 30813/30813/21959 30825/30825/21969 +f 30058/30058/21323 30826/30826/21966 30807/30807/21957 +f 30058/30058/21323 30807/30807/21957 30033/30033/21302 +f 30823/30823/21953 30827/30827/21970 30828/30828/21971 +f 30823/30823/21953 30828/30828/21971 30824/30824/21968 +f 30827/30827/21970 30605/30605/21768 30608/30608/21771 +f 30827/30827/21970 30608/30608/21771 30828/30828/21971 +f 30828/30828/21971 30608/30608/21771 30610/30610/21773 +f 30828/30828/21971 30610/30610/21773 30814/30814/21963 +f 30824/30824/21968 30828/30828/21971 30814/30814/21963 +f 30824/30824/21968 30814/30814/21963 30813/30813/21959 +f 30017/30017/21290 30812/30812/21962 30829/30829/21972 +f 30017/30017/21290 30829/30829/21972 30018/30018/21291 +f 30812/30812/21962 30811/30811/21961 30830/30830/21973 +f 30812/30812/21962 30830/30830/21973 30829/30829/21972 +f 30829/30829/21972 30830/30830/21973 30831/30831/21974 +f 30829/30829/21972 30831/30831/21974 30832/30832/21975 +f 30018/30018/21291 30829/30829/21972 30832/30832/21975 +f 30018/30018/21291 30832/30832/21975 30019/30019/21292 +f 30818/30818/21961 30817/30817/21965 30833/30833/21976 +f 30818/30818/21961 30833/30833/21976 30834/30834/21973 +f 30817/30817/21965 30593/30593/21756 30596/30596/21759 +f 30817/30817/21965 30596/30596/21759 30833/30833/21976 +f 30833/30833/21976 30596/30596/21759 30579/30579/21744 +f 30833/30833/21976 30579/30579/21744 30835/30835/21977 +f 30834/30834/21973 30833/30833/21976 30835/30835/21977 +f 30834/30834/21973 30835/30835/21977 30836/30836/21974 +f 29985/29985/21262 30837/30837/21978 30838/30838/21979 +f 29985/29985/21262 30838/30838/21979 29986/29986/21263 +f 30837/30837/21978 30839/30839/21980 30840/30840/21981 +f 30837/30837/21978 30840/30840/21981 30838/30838/21979 +f 30838/30838/21979 30840/30840/21981 30841/30841/21982 +f 30838/30838/21979 30841/30841/21982 30842/30842/21983 +f 29986/29986/21263 30838/30838/21979 30842/30842/21983 +f 29986/29986/21263 30842/30842/21983 29978/29978/21256 +f 30839/30839/21980 30843/30843/21984 30844/30844/21985 +f 30839/30839/21980 30844/30844/21985 30840/30840/21981 +f 30843/30843/21984 30586/30586/21749 30588/30588/21751 +f 30843/30843/21984 30588/30588/21751 30844/30844/21985 +f 30844/30844/21985 30588/30588/21751 30559/30559/21727 +f 30844/30844/21985 30559/30559/21727 30845/30845/21986 +f 30840/30840/21981 30844/30844/21985 30845/30845/21986 +f 30840/30840/21981 30845/30845/21986 30841/30841/21982 +f 30019/30019/21292 30832/30832/21975 30846/30846/21987 +f 30019/30019/21292 30846/30846/21987 30024/30024/21297 +f 30832/30832/21975 30831/30831/21974 30847/30847/21988 +f 30832/30832/21975 30847/30847/21988 30846/30846/21987 +f 30848/30848/21987 30849/30849/21988 30839/30839/21980 +f 30848/30848/21987 30839/30839/21980 30837/30837/21978 +f 30026/30026/21297 30848/30848/21987 30837/30837/21978 +f 30026/30026/21297 30837/30837/21978 29985/29985/21262 +f 30831/30831/21974 30850/30850/21977 30851/30851/21989 +f 30831/30831/21974 30851/30851/21989 30847/30847/21988 +f 30835/30835/21977 30579/30579/21744 30582/30582/21747 +f 30835/30835/21977 30582/30582/21747 30852/30852/21989 +f 30853/30853/21989 30585/30585/21747 30586/30586/21749 +f 30853/30853/21989 30586/30586/21749 30843/30843/21984 +f 30849/30849/21988 30853/30853/21989 30843/30843/21984 +f 30849/30849/21988 30843/30843/21984 30839/30839/21980 +f 29962/29962/21243 30854/30854/21990 30855/30855/21991 +f 29962/29962/21243 30855/30855/21991 29963/29963/21244 +f 30854/30854/21990 30856/30856/21992 30857/30857/21993 +f 30854/30854/21990 30857/30857/21993 30855/30855/21991 +f 30858/30858/21991 30859/30859/21993 30860/30860/21994 +f 30858/30858/21991 30860/30860/21994 30861/30861/21995 +f 29965/29965/21244 30858/30858/21991 30861/30861/21995 +f 29965/29965/21244 30861/30861/21995 29937/29937/21220 +f 30862/30862/21992 30863/30863/21996 30864/30864/21997 +f 30862/30862/21992 30864/30864/21997 30859/30859/21993 +f 30863/30863/21996 30565/30565/21732 30568/30568/21734 +f 30863/30863/21996 30568/30568/21734 30864/30864/21997 +f 30864/30864/21997 30568/30568/21734 30541/30541/21711 +f 30864/30864/21997 30541/30541/21711 30865/30865/21998 +f 30859/30859/21993 30864/30864/21997 30865/30865/21998 +f 30859/30859/21993 30865/30865/21998 30860/30860/21994 +f 29978/29978/21256 30842/30842/21983 30866/30866/21999 +f 29978/29978/21256 30866/30866/21999 29979/29979/21257 +f 30842/30842/21983 30841/30841/21982 30867/30867/22000 +f 30842/30842/21983 30867/30867/22000 30866/30866/21999 +f 30866/30866/21999 30867/30867/22000 30856/30856/21992 +f 30866/30866/21999 30856/30856/21992 30854/30854/21990 +f 29979/29979/21257 30866/30866/21999 30854/30854/21990 +f 29979/29979/21257 30854/30854/21990 29962/29962/21243 +f 30841/30841/21982 30845/30845/21986 30868/30868/22001 +f 30841/30841/21982 30868/30868/22001 30867/30867/22000 +f 30845/30845/21986 30559/30559/21727 30562/30562/21730 +f 30845/30845/21986 30562/30562/21730 30868/30868/22001 +f 30868/30868/22001 30562/30562/21730 30564/30564/21732 +f 30868/30868/22001 30564/30564/21732 30869/30869/21996 +f 30867/30867/22000 30868/30868/22001 30869/30869/21996 +f 30867/30867/22000 30869/30869/21996 30856/30856/21992 +f 29937/29937/21220 30861/30861/21995 30870/30870/22002 +f 29937/29937/21220 30870/30870/22002 29938/29938/21221 +f 30861/30861/21995 30860/30860/21994 30871/30871/22003 +f 30861/30861/21995 30871/30871/22003 30870/30870/22002 +f 30870/30870/22002 30871/30871/22003 30872/30872/22004 +f 30870/30870/22002 30872/30872/22004 30873/30873/22005 +f 29938/29938/21221 30870/30870/22002 30873/30873/22005 +f 29938/29938/21221 30873/30873/22005 29928/29928/21212 +f 30860/30860/21994 30865/30865/21998 30874/30874/22006 +f 30860/30860/21994 30874/30874/22006 30871/30871/22003 +f 30865/30865/21998 30541/30541/21711 30544/30544/21714 +f 30865/30865/21998 30544/30544/21714 30874/30874/22006 +f 30874/30874/22006 30544/30544/21714 30531/30531/21702 +f 30874/30874/22006 30531/30531/21702 30875/30875/22007 +f 30871/30871/22003 30874/30874/22006 30875/30875/22007 +f 30871/30871/22003 30875/30875/22007 30872/30872/22004 +f 29903/29903/21188 30876/30876/22008 30877/30877/22009 +f 29903/29903/21188 30877/30877/22009 29904/29904/21189 +f 30876/30876/22008 30878/30878/22010 30879/30879/22011 +f 30876/30876/22008 30879/30879/22011 30877/30877/22009 +f 30877/30877/22009 30879/30879/22011 30880/30880/22012 +f 30877/30877/22009 30880/30880/22012 30881/30881/22013 +f 29904/29904/21189 30877/30877/22009 30881/30881/22013 +f 29904/29904/21189 30881/30881/22013 29881/29881/21172 +f 30878/30878/22010 30882/30882/22014 30883/30883/22015 +f 30878/30878/22010 30883/30883/22015 30879/30879/22011 +f 30882/30882/22014 30537/30537/21708 30540/30540/21710 +f 30882/30882/22014 30540/30540/21710 30883/30883/22015 +f 30883/30883/22015 30540/30540/21710 30514/30514/21688 +f 30883/30883/22015 30514/30514/21688 30884/30884/22016 +f 30879/30879/22011 30883/30883/22015 30884/30884/22016 +f 30879/30879/22011 30884/30884/22016 30880/30880/22012 +f 29928/29928/21212 30873/30873/22005 30885/30885/22017 +f 29928/29928/21212 30885/30885/22017 29929/29929/21213 +f 30873/30873/22005 30872/30872/22004 30886/30886/22018 +f 30873/30873/22005 30886/30886/22018 30885/30885/22017 +f 30885/30885/22017 30886/30886/22018 30887/30887/22010 +f 30885/30885/22017 30887/30887/22010 30888/30888/22019 +f 29929/29929/21213 30885/30885/22017 30888/30888/22019 +f 29929/29929/21213 30888/30888/22019 29930/29930/21214 +f 30872/30872/22004 30875/30875/22007 30889/30889/22020 +f 30872/30872/22004 30889/30889/22020 30886/30886/22018 +f 30875/30875/22007 30531/30531/21702 30534/30534/21705 +f 30875/30875/22007 30534/30534/21705 30889/30889/22020 +f 30889/30889/22020 30534/30534/21705 30536/30536/21707 +f 30889/30889/22020 30536/30536/21707 30890/30890/22014 +f 30886/30886/22018 30889/30889/22020 30890/30890/22014 +f 30886/30886/22018 30890/30890/22014 30887/30887/22010 +f 29881/29881/21172 30881/30881/22013 30891/30891/22021 +f 29881/29881/21172 30891/30891/22021 29882/29882/21173 +f 30881/30881/22013 30880/30880/22012 30892/30892/22022 +f 30881/30881/22013 30892/30892/22022 30891/30891/22021 +f 30893/30893/22021 30894/30894/22022 30895/30895/22023 +f 30893/30893/22021 30895/30895/22023 30896/30896/22024 +f 29884/29884/21173 30897/30897/22025 30898/30898/22024 +f 29884/29884/21173 30898/30898/22024 29873/29873/21165 +f 30880/30880/22012 30884/30884/22016 30899/30899/22026 +f 30880/30880/22012 30899/30899/22026 30892/30892/22022 +f 30884/30884/22016 30514/30514/21688 30517/30517/21691 +f 30884/30884/22016 30517/30517/21691 30899/30899/22026 +f 30900/30900/22027 30519/30519/21691 30496/30496/21673 +f 30900/30900/22027 30496/30496/21673 30901/30901/22028 +f 30894/30894/22022 30900/30900/22027 30901/30901/22028 +f 30894/30894/22022 30901/30901/22028 30895/30895/22023 +f 29847/29847/21142 30902/30902/22029 30903/30903/22030 +f 29847/29847/21142 30903/30903/22030 29848/29848/21143 +f 30902/30902/22029 30904/30904/22031 30905/30905/22032 +f 30902/30902/22029 30905/30905/22032 30903/30903/22030 +f 30903/30903/22030 30905/30905/22032 30906/30906/22033 +f 30903/30903/22030 30906/30906/22033 30907/30907/22034 +f 29848/29848/21143 30903/30903/22030 30907/30907/22034 +f 29848/29848/21143 30907/30907/22034 29850/29850/21145 +f 30904/30904/22031 30908/30908/22035 30909/30909/22036 +f 30904/30904/22031 30909/30909/22036 30905/30905/22032 +f 30908/30908/22035 30502/30502/21679 30505/30505/21681 +f 30908/30908/22035 30505/30505/21681 30909/30909/22036 +f 30909/30909/22036 30505/30505/21681 30507/30507/21683 +f 30909/30909/22036 30507/30507/21683 30910/30910/22037 +f 30905/30905/22032 30909/30909/22036 30910/30910/22037 +f 30905/30905/22032 30910/30910/22037 30906/30906/22033 +f 29873/29873/21165 30898/30898/22024 30911/30911/22038 +f 29873/29873/21165 30911/30911/22038 29874/29874/21166 +f 30898/30898/22024 30912/30912/22023 30913/30913/22039 +f 30898/30898/22024 30913/30913/22039 30911/30911/22038 +f 30911/30911/22038 30913/30913/22039 30914/30914/22040 +f 30911/30911/22038 30914/30914/22040 30915/30915/22029 +f 29874/29874/21166 30911/30911/22038 30915/30915/22029 +f 29874/29874/21166 30915/30915/22029 29875/29875/21167 +f 30895/30895/22023 30901/30901/22028 30916/30916/22041 +f 30895/30895/22023 30916/30916/22041 30917/30917/22039 +f 30901/30901/22028 30496/30496/21673 30499/30499/21676 +f 30901/30901/22028 30499/30499/21676 30916/30916/22041 +f 30916/30916/22041 30499/30499/21676 30501/30501/21678 +f 30916/30916/22041 30501/30501/21678 30918/30918/22042 +f 30913/30913/22039 30919/30919/22041 30920/30920/22043 +f 30913/30913/22039 30920/30920/22043 30914/30914/22040 +f 29853/29853/21148 29863/29863/21155 30921/30921/22044 +f 29853/29853/21148 30921/30921/22044 30272/30272/21506 +f 29863/29863/21155 29862/29862/21154 30922/30922/22045 +f 29863/29863/21155 30922/30922/22045 30921/30921/22044 +f 30921/30921/22044 30922/30922/22045 29861/29861/21153 +f 30921/30921/22044 29861/29861/21153 29859/29859/21152 +f 30272/30272/21506 30921/30921/22044 29859/29859/21152 +f 30272/30272/21506 29859/29859/21152 29858/29858/21129 +f 30923/30923/22046 30924/30924/22047 30925/30925/22048 +f 30923/30923/22046 30925/30925/22048 30926/30926/22049 +f 30924/30924/22047 30453/30453/21639 30456/30456/21642 +f 30924/30924/22047 30456/30456/21642 30925/30925/22048 +f 30925/30925/22048 30456/30456/21642 30458/30458/21644 +f 30925/30925/22048 30458/30458/21644 30927/30927/22050 +f 30926/30926/22049 30925/30925/22048 30927/30927/22050 +f 30926/30926/22049 30927/30927/22050 30928/30928/21153 +f 29814/29814/21115 29811/29811/21112 30929/30929/22051 +f 29814/29814/21115 30929/30929/22051 30461/30461/21647 +f 29811/29811/21112 29810/29810/21111 30930/30930/22052 +f 29811/29811/21112 30930/30930/22052 30929/30929/22051 +f 30931/30931/22051 30932/30932/22053 30933/30933/22054 +f 30931/30931/22051 30933/30933/22054 30934/30934/22055 +f 30463/30463/21648 30931/30931/22051 30934/30934/22055 +f 30463/30463/21648 30934/30934/22055 30464/30464/21649 +f 29810/29810/21111 30935/30935/22056 30936/30936/22057 +f 29810/29810/21111 30936/30936/22057 30930/30930/22052 +f 30935/30935/22056 30261/30261/21496 30264/30264/21499 +f 30935/30935/22056 30264/30264/21499 30936/30936/22057 +f 30937/30937/22058 30266/30266/21500 29167/29167/20546 +f 30937/30937/22058 29167/29167/20546 30938/30938/22059 +f 30932/30932/22053 30937/30937/22058 30938/30938/22059 +f 30932/30932/22053 30938/30938/22059 30933/30933/22054 +f 30468/30468/21653 30939/30939/22060 30940/30940/22061 +f 30468/30468/21653 30940/30940/22061 30469/30469/21654 +f 30939/30939/22060 30941/30941/22062 30942/30942/22063 +f 30939/30939/22060 30942/30942/22063 30940/30940/22061 +f 30943/30943/22061 30944/30944/22064 29818/29818/21119 +f 30943/30943/22061 29818/29818/21119 29817/29817/21118 +f 30471/30471/21654 30943/30943/22061 29817/29817/21118 +f 30471/30471/21654 29817/29817/21118 29816/29816/21117 +f 30941/30941/22062 30945/30945/22065 30946/30946/22066 +f 30941/30941/22062 30946/30946/22066 30942/30942/22063 +f 30945/30945/22065 29154/29154/20535 30244/30244/21482 +f 30945/30945/22065 30244/30244/21482 30946/30946/22066 +f 30947/30947/22067 30247/30247/21482 30248/30248/21485 +f 30947/30947/22067 30248/30248/21485 30948/30948/22068 +f 30944/30944/22064 30947/30947/22067 30948/30948/22068 +f 30944/30944/22064 30948/30948/22068 29818/29818/21119 +f 30275/30275/21508 30454/30454/21640 30949/30949/22069 +f 30275/30275/21508 30949/30949/22069 30475/30475/21657 +f 30454/30454/21640 30453/30453/21639 30950/30950/22070 +f 30454/30454/21640 30950/30950/22070 30949/30949/22069 +f 30949/30949/22069 30950/30950/22070 30951/30951/21683 +f 30949/30949/22069 30951/30951/21683 30952/30952/22071 +f 30475/30475/21657 30949/30949/22069 30952/30952/22071 +f 30475/30475/21657 30952/30952/22071 30476/30476/21097 +f 30453/30453/21639 30924/30924/22047 30953/30953/22072 +f 30453/30453/21639 30953/30953/22072 30950/30950/22070 +f 30924/30924/22047 30923/30923/22046 30954/30954/22073 +f 30924/30924/22047 30954/30954/22073 30953/30953/22072 +f 30955/30955/22072 29865/29865/21157 29868/29868/21160 +f 30955/30955/22072 29868/29868/21160 30956/30956/22074 +f 30950/30950/22070 30953/30953/22072 30957/30957/22075 +f 30950/30950/22070 30957/30957/22075 30951/30951/21683 +f 30481/30481/21662 30958/30958/22076 30959/30959/22077 +f 30481/30481/21662 30959/30959/22077 30482/30482/21663 +f 30958/30958/22076 30960/30960/22078 30961/30961/22079 +f 30958/30958/22076 30961/30961/22079 30959/30959/22077 +f 30962/30962/22080 30963/30963/22081 30458/30458/21644 +f 30962/30962/22080 30458/30458/21644 30457/30457/21643 +f 30484/30484/21663 30962/30962/22080 30457/30457/21643 +f 30484/30484/21663 30457/30457/21643 30283/30283/21516 +f 30960/30960/22078 30964/30964/22082 30965/30965/22083 +f 30960/30960/22078 30965/30965/22083 30961/30961/22079 +f 30964/30964/22082 29827/29827/21125 29855/29855/21150 +f 30964/30964/22082 29855/29855/21150 30965/30965/22083 +f 30966/30966/22084 30967/30967/21150 30928/30928/21153 +f 30966/30966/22084 30928/30928/21153 30927/30927/22050 +f 30963/30963/22081 30966/30966/22084 30927/30927/22050 +f 30963/30963/22081 30927/30927/22050 30458/30458/21644 +f 30488/30488/21666 30968/30968/22085 30969/30969/22086 +f 30488/30488/21666 30969/30969/22086 30489/30489/21667 +f 30968/30968/22085 30970/30970/22087 30971/30971/22088 +f 30968/30968/22085 30971/30971/22088 30969/30969/22086 +f 30972/30972/22089 30973/30973/22090 30960/30960/22078 +f 30972/30972/22089 30960/30960/22078 30958/30958/22076 +f 30491/30491/21667 30972/30972/22089 30958/30958/22076 +f 30491/30491/21667 30958/30958/22076 30481/30481/21662 +f 30970/30970/22087 30974/30974/22091 30975/30975/22092 +f 30970/30970/22087 30975/30975/22092 30971/30971/22088 +f 30974/30974/22091 29809/29809/21110 29820/29820/21121 +f 30974/30974/22091 29820/29820/21121 30975/30975/22092 +f 30976/30976/22092 29826/29826/21121 29827/29827/21125 +f 30976/30976/22092 29827/29827/21125 30964/30964/22082 +f 30973/30973/22090 30976/30976/22092 30964/30964/22082 +f 30973/30973/22090 30964/30964/22082 30960/30960/22078 +f 29207/29207/20580 30262/30262/21497 30977/30977/22093 +f 29207/29207/20580 30977/30977/22093 30439/30439/21630 +f 30262/30262/21497 30261/30261/21496 30978/30978/22094 +f 30262/30262/21497 30978/30978/22094 30977/30977/22093 +f 30977/30977/22093 30978/30978/22094 30248/30248/21485 +f 30977/30977/22093 30248/30248/21485 30246/30246/21484 +f 30439/30439/21630 30977/30977/22093 30246/30246/21484 +f 30439/30439/21630 30246/30246/21484 29184/29184/20560 +f 30261/30261/21496 30935/30935/22056 30979/30979/22095 +f 30261/30261/21496 30979/30979/22095 30978/30978/22094 +f 30935/30935/22056 29810/29810/21111 29813/29813/21114 +f 30935/30935/22056 29813/29813/21114 30979/30979/22095 +f 30979/30979/22095 29813/29813/21114 29818/29818/21119 +f 30979/30979/22095 29818/29818/21119 30948/30948/22068 +f 30978/30978/22094 30979/30979/22095 30948/30948/22068 +f 30978/30978/22094 30948/30948/22068 30248/30248/21485 +f 30494/30494/21671 30980/30980/22096 30981/30981/22097 +f 30494/30494/21671 30981/30981/22097 30495/30495/21672 +f 30980/30980/22096 30982/30982/22098 30983/30983/22099 +f 30980/30980/22096 30983/30983/22099 30981/30981/22097 +f 30981/30981/22097 30983/30983/22099 30970/30970/22087 +f 30981/30981/22097 30970/30970/22087 30968/30968/22085 +f 30495/30495/21672 30981/30981/22097 30968/30968/22085 +f 30495/30495/21672 30968/30968/22085 30488/30488/21666 +f 30982/30982/22098 30984/30984/22100 30985/30985/22101 +f 30982/30982/22098 30985/30985/22101 30983/30983/22099 +f 30984/30984/22100 29784/29784/21088 29807/29807/21108 +f 30984/30984/22100 29807/29807/21108 30985/30985/22101 +f 30985/30985/22101 29807/29807/21108 29809/29809/21110 +f 30985/30985/22101 29809/29809/21110 30974/30974/22091 +f 30983/30983/22099 30985/30985/22101 30974/30974/22091 +f 30983/30983/22099 30974/30974/22091 30970/30970/22087 +f 30510/30510/21686 30986/30986/22102 30987/30987/22103 +f 30510/30510/21686 30987/30987/22103 30511/30511/21687 +f 30986/30986/22102 30988/30988/22104 30989/30989/22105 +f 30986/30986/22102 30989/30989/22105 30987/30987/22103 +f 30990/30990/22103 30991/30991/22105 30982/30982/22098 +f 30990/30990/22103 30982/30982/22098 30980/30980/22096 +f 30513/30513/21687 30990/30990/22103 30980/30980/22096 +f 30513/30513/21687 30980/30980/22096 30494/30494/21671 +f 30988/30988/22104 30992/30992/22106 30993/30993/22107 +f 30988/30988/22104 30993/30993/22107 30989/30989/22105 +f 30992/30992/22106 29744/29744/21056 29780/29780/21086 +f 30992/30992/22106 29780/29780/21086 30993/30993/22107 +f 30994/30994/22108 29783/29783/21086 29784/29784/21088 +f 30994/30994/22108 29784/29784/21088 30984/30984/22100 +f 30991/30991/22105 30994/30994/22108 30984/30984/22100 +f 30991/30991/22105 30984/30984/22100 30982/30982/22098 +f 30522/30522/21695 30995/30995/22109 30996/30996/22110 +f 30522/30522/21695 30996/30996/22110 30523/30523/21696 +f 30995/30995/22109 30997/30997/22111 30998/30998/22112 +f 30995/30995/22109 30998/30998/22112 30996/30996/22110 +f 30996/30996/22110 30998/30998/22112 30988/30988/22104 +f 30996/30996/22110 30988/30988/22104 30986/30986/22102 +f 30523/30523/21696 30996/30996/22110 30986/30986/22102 +f 30523/30523/21696 30986/30986/22102 30510/30510/21686 +f 30997/30997/22111 30999/30999/22113 31000/31000/22114 +f 30997/30997/22111 31000/31000/22114 30998/30998/22112 +f 30999/30999/22113 29727/29727/21041 29741/29741/21053 +f 30999/30999/22113 29741/29741/21053 31000/31000/22114 +f 31000/31000/22114 29741/29741/21053 29744/29744/21056 +f 31000/31000/22114 29744/29744/21056 30992/30992/22106 +f 30998/30998/22112 31000/31000/22114 30992/30992/22106 +f 30998/30998/22112 30992/30992/22106 30988/30988/22104 +f 30526/30526/21699 31001/31001/22115 31002/31002/22116 +f 30526/30526/21699 31002/31002/22116 30527/30527/21700 +f 31001/31001/22115 31003/31003/22117 31004/31004/22118 +f 31001/31001/22115 31004/31004/22118 31002/31002/22116 +f 31005/31005/22116 31006/31006/22118 30997/30997/22111 +f 31005/31005/22116 30997/30997/22111 30995/30995/22109 +f 30529/30529/21700 31005/31005/22116 30995/30995/22109 +f 30529/30529/21700 30995/30995/22109 30522/30522/21695 +f 31003/31003/22117 31007/31007/22119 31008/31008/22120 +f 31003/31003/22117 31008/31008/22120 31004/31004/22118 +f 31009/31009/22119 29657/29657/20978 29723/29723/21037 +f 31009/31009/22119 29723/29723/21037 31010/31010/22120 +f 31011/31011/22121 29726/29726/21040 29727/29727/21041 +f 31011/31011/22121 29727/29727/21041 30999/30999/22113 +f 31006/31006/22118 31011/31011/22121 30999/30999/22113 +f 31006/31006/22118 30999/30999/22113 30997/30997/22111 +f 30547/30547/21717 31012/31012/22122 31013/31013/22123 +f 30547/30547/21717 31013/31013/22123 30548/30548/21718 +f 31012/31012/22122 31014/31014/22124 31015/31015/22125 +f 31012/31012/22122 31015/31015/22125 31013/31013/22123 +f 31013/31013/22123 31015/31015/22125 31016/31016/22126 +f 31013/31013/22123 31016/31016/22126 31017/31017/22127 +f 30548/30548/21718 31013/31013/22123 31017/31017/22127 +f 30548/30548/21718 31017/31017/22127 30549/30549/21719 +f 31018/31018/22124 31019/31019/22128 31020/31020/22129 +f 31018/31018/22124 31020/31020/22129 31021/31021/22130 +f 31019/31019/22128 29648/29648/20969 29659/29659/20980 +f 31019/31019/22128 29659/29659/20980 31020/31020/22129 +f 31022/31022/22131 31023/31023/22132 31024/31024/20970 +f 31022/31022/22131 31024/31024/20970 31025/31025/22133 +f 31015/31015/22125 31022/31022/22131 31025/31025/22133 +f 31015/31015/22125 31025/31025/22133 31016/31016/22126 +f 30549/30549/21719 31017/31017/22127 31026/31026/22134 +f 30549/30549/21719 31026/31026/22134 30552/30552/21722 +f 31017/31017/22127 31016/31016/22126 31027/31027/22135 +f 31017/31017/22127 31027/31027/22135 31026/31026/22134 +f 31026/31026/22134 31027/31027/22135 31003/31003/22117 +f 31026/31026/22134 31003/31003/22117 31001/31001/22115 +f 30552/30552/21722 31026/31026/22134 31001/31001/22115 +f 30552/30552/21722 31001/31001/22115 30526/30526/21699 +f 31016/31016/22126 31025/31025/22133 31028/31028/22136 +f 31016/31016/22126 31028/31028/22136 31027/31027/22135 +f 31029/31029/22133 29649/29649/20970 29652/29652/20973 +f 31029/31029/22133 29652/29652/20973 31030/31030/22136 +f 31030/31030/22136 29652/29652/20973 29657/29657/20978 +f 31030/31030/22136 29657/29657/20978 31009/31009/22119 +f 31027/31027/22135 31028/31028/22136 31007/31007/22119 +f 31027/31027/22135 31007/31007/22119 31003/31003/22117 +f 30555/30555/21725 31031/31031/22137 31032/31032/22138 +f 30555/30555/21725 31032/31032/22138 30556/30556/21726 +f 31031/31031/22137 31033/31033/22139 31034/31034/22140 +f 31031/31031/22137 31034/31034/22140 31032/31032/22138 +f 31032/31032/22138 31034/31034/22140 31018/31018/22124 +f 31032/31032/22138 31018/31018/22124 31035/31035/22141 +f 30556/30556/21726 31032/31032/22138 31035/31035/22141 +f 30556/30556/21726 31035/31035/22141 30557/30557/21717 +f 31033/31033/22139 31036/31036/22142 31037/31037/22143 +f 31033/31033/22139 31037/31037/22143 31034/31034/22140 +f 31036/31036/22142 29614/29614/20939 29646/29646/20967 +f 31036/31036/22142 29646/29646/20967 31037/31037/22143 +f 31037/31037/22143 29646/29646/20967 29648/29648/20969 +f 31037/31037/22143 29648/29648/20969 31019/31019/22128 +f 31034/31034/22140 31037/31037/22143 31019/31019/22128 +f 31034/31034/22140 31019/31019/22128 31018/31018/22124 +f 30571/30571/21737 31038/31038/22144 31039/31039/22145 +f 30571/30571/21737 31039/31039/22145 30572/30572/21738 +f 31038/31038/22144 31040/31040/22146 31041/31041/22147 +f 31038/31038/22144 31041/31041/22147 31039/31039/22145 +f 31039/31039/22145 31041/31041/22147 31033/31033/22139 +f 31039/31039/22145 31033/31033/22139 31031/31031/22137 +f 30572/30572/21738 31039/31039/22145 31031/31031/22137 +f 30572/30572/21738 31031/31031/22137 30555/30555/21725 +f 31040/31040/22146 31042/31042/22148 31043/31043/22149 +f 31040/31040/22146 31043/31043/22149 31041/31041/22147 +f 31042/31042/22148 29591/29591/20916 29611/29611/20936 +f 31042/31042/22148 29611/29611/20936 31043/31043/22149 +f 31043/31043/22149 29611/29611/20936 29614/29614/20939 +f 31043/31043/22149 29614/29614/20939 31036/31036/22142 +f 31041/31041/22147 31043/31043/22149 31036/31036/22142 +f 31041/31041/22147 31036/31036/22142 31033/31033/22139 +f 30575/30575/21741 31044/31044/22150 31045/31045/22151 +f 30575/30575/21741 31045/31045/22151 30576/30576/21742 +f 31044/31044/22150 31046/31046/22152 31047/31047/22153 +f 31044/31044/22150 31047/31047/22153 31045/31045/22151 +f 31048/31048/22151 31049/31049/22153 31040/31040/22146 +f 31048/31048/22151 31040/31040/22146 31038/31038/22144 +f 30578/30578/21743 31048/31048/22151 31038/31038/22144 +f 30578/30578/21743 31038/31038/22144 30571/30571/21737 +f 31046/31046/22152 31050/31050/22154 31051/31051/22155 +f 31046/31046/22152 31051/31051/22155 31047/31047/22153 +f 31050/31050/22154 29570/29570/20899 29584/29584/20912 +f 31050/31050/22154 29584/29584/20912 31051/31051/22155 +f 31052/31052/22155 29590/29590/20912 29591/29591/20916 +f 31052/31052/22155 29591/29591/20916 31042/31042/22148 +f 31049/31049/22153 31052/31052/22155 31042/31042/22148 +f 31049/31049/22153 31042/31042/22148 31040/31040/22146 +f 30591/30591/21754 31053/31053/22156 31054/31054/22157 +f 30591/30591/21754 31054/31054/22157 30592/30592/21755 +f 31053/31053/22156 31055/31055/22158 31056/31056/22159 +f 31053/31053/22156 31056/31056/22159 31054/31054/22157 +f 31054/31054/22157 31056/31056/22159 31046/31046/22152 +f 31054/31054/22157 31046/31046/22152 31044/31044/22150 +f 30592/30592/21755 31054/31054/22157 31044/31044/22150 +f 30592/30592/21755 31044/31044/22150 30575/30575/21741 +f 31055/31055/22158 31057/31057/22160 31058/31058/22161 +f 31055/31055/22158 31058/31058/22161 31056/31056/22159 +f 31057/31057/22160 29536/29536/20868 29568/29568/20897 +f 31057/31057/22160 29568/29568/20897 31058/31058/22161 +f 31058/31058/22161 29568/29568/20897 29570/29570/20899 +f 31058/31058/22161 29570/29570/20899 31050/31050/22154 +f 31056/31056/22159 31058/31058/22161 31050/31050/22154 +f 31056/31056/22159 31050/31050/22154 31046/31046/22152 +f 30599/30599/21762 31059/31059/22162 31060/31060/22163 +f 30599/30599/21762 31060/31060/22163 30600/30600/21763 +f 31059/31059/22162 31061/31061/22164 31062/31062/22165 +f 31059/31059/22162 31062/31062/22165 31060/31060/22163 +f 31060/31060/22163 31062/31062/22165 31055/31055/22158 +f 31060/31060/22163 31055/31055/22158 31053/31053/22156 +f 30600/30600/21763 31060/31060/22163 31053/31053/22156 +f 30600/30600/21763 31053/31053/22156 30591/30591/21754 +f 31061/31061/22164 31063/31063/22166 31064/31064/22167 +f 31061/31061/22164 31064/31064/22167 31062/31062/22165 +f 31063/31063/22166 29522/29522/20854 29533/29533/20865 +f 31063/31063/22166 29533/29533/20865 31064/31064/22167 +f 31064/31064/22167 29533/29533/20865 29536/29536/20868 +f 31064/31064/22167 29536/29536/20868 31057/31057/22160 +f 31062/31062/22165 31064/31064/22167 31057/31057/22160 +f 31062/31062/22165 31057/31057/22160 31055/31055/22158 +f 30603/30603/21766 31065/31065/22168 31066/31066/22169 +f 30603/30603/21766 31066/31066/22169 30604/30604/21767 +f 31065/31065/22168 31067/31067/22170 31068/31068/22171 +f 31065/31065/22168 31068/31068/22171 31066/31066/22169 +f 31066/31066/22169 31068/31068/22171 31061/31061/22164 +f 31066/31066/22169 31061/31061/22164 31059/31059/22162 +f 30604/30604/21767 31066/31066/22169 31059/31059/22162 +f 30604/30604/21767 31059/31059/22162 30599/30599/21762 +f 31067/31067/22170 31069/31069/22172 31070/31070/22173 +f 31067/31067/22170 31070/31070/22173 31068/31068/22171 +f 31069/31069/22172 29518/29518/20833 29520/29520/20852 +f 31069/31069/22172 29520/29520/20852 31070/31070/22173 +f 31070/31070/22173 29520/29520/20852 29522/29522/20854 +f 31070/31070/22173 29522/29522/20854 31063/31063/22166 +f 31068/31068/22171 31070/31070/22173 31063/31063/22166 +f 31068/31068/22171 31063/31063/22166 31061/31061/22164 +f 30615/30615/21778 31071/31071/22174 31072/31072/22175 +f 30615/30615/21778 31072/31072/22175 30616/30616/21779 +f 31071/31071/22174 31073/31073/22176 31074/31074/22177 +f 31071/31071/22174 31074/31074/22177 31072/31072/22175 +f 31075/31075/22178 31076/31076/22177 31067/31067/22170 +f 31075/31075/22178 31067/31067/22170 31065/31065/22168 +f 30618/30618/21779 31075/31075/22178 31065/31065/22168 +f 30618/30618/21779 31065/31065/22168 30603/30603/21766 +f 31073/31073/22176 31077/31077/22179 31078/31078/22180 +f 31073/31073/22176 31078/31078/22180 31074/31074/22177 +f 31077/31077/22179 29462/29462/20807 29495/29495/20831 +f 31077/31077/22179 29495/29495/20831 31078/31078/22180 +f 31079/31079/22180 31080/31080/20831 29518/29518/20833 +f 31079/31079/22180 29518/29518/20833 31069/31069/22172 +f 31076/31076/22177 31079/31079/22180 31069/31069/22172 +f 31076/31076/22177 31069/31069/22172 31067/31067/22170 +f 30628/30628/21788 31081/31081/22181 31082/31082/22182 +f 30628/30628/21788 31082/31082/22182 30629/30629/21789 +f 31081/31081/22181 31083/31083/22183 31084/31084/22184 +f 31081/31081/22181 31084/31084/22184 31082/31082/22182 +f 31082/31082/22182 31084/31084/22184 31073/31073/22176 +f 31082/31082/22182 31073/31073/22176 31071/31071/22174 +f 30629/30629/21789 31082/31082/22182 31071/31071/22174 +f 30629/30629/21789 31071/31071/22174 30615/30615/21778 +f 31083/31083/22183 31085/31085/22185 31086/31086/22186 +f 31083/31083/22183 31086/31086/22186 31084/31084/22184 +f 31085/31085/22185 29445/29445/20793 29459/29459/20804 +f 31085/31085/22185 29459/29459/20804 31086/31086/22186 +f 31086/31086/22186 29459/29459/20804 29462/29462/20807 +f 31086/31086/22186 29462/29462/20807 31077/31077/22179 +f 31084/31084/22184 31086/31086/22186 31077/31077/22179 +f 31084/31084/22184 31077/31077/22179 31073/31073/22176 +f 30632/30632/21792 31087/31087/22187 31088/31088/22188 +f 30632/30632/21792 31088/31088/22188 30633/30633/21793 +f 31087/31087/22187 31089/31089/22189 31090/31090/22190 +f 31087/31087/22187 31090/31090/22190 31088/31088/22188 +f 31088/31088/22188 31090/31090/22190 31083/31083/22183 +f 31088/31088/22188 31083/31083/22183 31081/31081/22181 +f 30633/30633/21793 31088/31088/22188 31081/31081/22181 +f 30633/30633/21793 31081/31081/22181 30628/30628/21788 +f 31089/31089/22189 31091/31091/22191 31092/31092/22192 +f 31089/31089/22189 31092/31092/22192 31090/31090/22190 +f 31091/31091/22191 29376/29376/20734 29443/29443/20791 +f 31091/31091/22191 29443/29443/20791 31092/31092/22192 +f 31092/31092/22192 29443/29443/20791 29445/29445/20793 +f 31092/31092/22192 29445/29445/20793 31085/31085/22185 +f 31090/31090/22190 31092/31092/22192 31085/31085/22185 +f 31090/31090/22190 31085/31085/22185 31083/31083/22183 +f 30648/30648/21808 31093/31093/22193 31094/31094/22194 +f 30648/30648/21808 31094/31094/22194 30649/30649/21809 +f 31093/31093/22193 31095/31095/22195 31096/31096/22196 +f 31093/31093/22193 31096/31096/22196 31094/31094/22194 +f 31097/31097/22194 31098/31098/22196 31099/31099/22197 +f 31097/31097/22194 31099/31099/22197 31100/31100/22198 +f 30651/30651/21809 31097/31097/22194 31100/31100/22198 +f 30651/30651/21809 31100/31100/22198 30652/30652/21810 +f 31101/31101/22195 31102/31102/22199 31103/31103/22200 +f 31101/31101/22195 31103/31103/22200 31098/31098/22196 +f 31102/31102/22199 31104/31104/22201 29382/29382/20736 +f 31102/31102/22199 29382/29382/20736 31103/31103/22200 +f 31103/31103/22200 29382/29382/20736 29368/29368/20726 +f 31103/31103/22200 29368/29368/20726 31105/31105/22202 +f 31098/31098/22196 31103/31103/22200 31105/31105/22202 +f 31098/31098/22196 31105/31105/22202 31099/31099/22197 +f 30652/30652/21810 31100/31100/22198 31106/31106/22203 +f 30652/30652/21810 31106/31106/22203 30656/30656/21814 +f 31100/31100/22198 31099/31099/22197 31107/31107/22204 +f 31100/31100/22198 31107/31107/22204 31106/31106/22203 +f 31106/31106/22203 31107/31107/22204 31089/31089/22189 +f 31106/31106/22203 31089/31089/22189 31087/31087/22187 +f 30656/30656/21814 31106/31106/22203 31087/31087/22187 +f 30656/30656/21814 31087/31087/22187 30632/30632/21792 +f 31099/31099/22197 31105/31105/22202 31108/31108/22205 +f 31099/31099/22197 31108/31108/22205 31107/31107/22204 +f 31105/31105/22202 29368/29368/20726 29371/29371/20729 +f 31105/31105/22202 29371/29371/20729 31108/31108/22205 +f 31108/31108/22205 29371/29371/20729 29376/29376/20734 +f 31108/31108/22205 29376/29376/20734 31091/31091/22191 +f 31107/31107/22204 31108/31108/22205 31091/31091/22191 +f 31107/31107/22204 31091/31091/22191 31089/31089/22189 +f 30659/30659/21817 31109/31109/22206 31110/31110/22207 +f 30659/30659/21817 31110/31110/22207 30660/30660/21818 +f 31109/31109/22206 31111/31111/22208 31112/31112/22209 +f 31109/31109/22206 31112/31112/22209 31110/31110/22207 +f 31110/31110/22207 31112/31112/22209 31095/31095/22195 +f 31110/31110/22207 31095/31095/22195 31093/31093/22193 +f 30660/30660/21818 31110/31110/22207 31093/31093/22193 +f 30660/30660/21818 31093/31093/22193 30648/30648/21808 +f 31111/31111/22208 31113/31113/22210 31114/31114/22211 +f 31111/31111/22208 31114/31114/22211 31112/31112/22209 +f 31115/31115/22210 29337/29337/20697 29365/29365/20723 +f 31115/31115/22210 29365/29365/20723 31116/31116/22211 +f 31116/31116/22211 29365/29365/20723 29367/29367/20725 +f 31116/31116/22211 29367/29367/20725 31117/31117/22199 +f 31112/31112/22209 31114/31114/22211 31118/31118/22199 +f 31112/31112/22209 31118/31118/22199 31095/31095/22195 +f 30674/30674/21830 31119/31119/22212 31120/31120/22213 +f 30674/30674/21830 31120/31120/22213 30675/30675/21831 +f 31119/31119/22212 31121/31121/22214 31122/31122/22215 +f 31119/31119/22212 31122/31122/22215 31120/31120/22213 +f 31120/31120/22213 31122/31122/22215 31111/31111/22208 +f 31120/31120/22213 31111/31111/22208 31109/31109/22206 +f 30675/30675/21831 31120/31120/22213 31109/31109/22206 +f 30675/30675/21831 31109/31109/22206 30659/30659/21817 +f 31121/31121/22214 31123/31123/22216 31124/31124/22217 +f 31121/31121/22214 31124/31124/22217 31122/31122/22215 +f 31125/31125/22216 29319/29319/20679 29334/29334/20694 +f 31125/31125/22216 29334/29334/20694 31126/31126/22217 +f 31126/31126/22217 29334/29334/20694 29337/29337/20697 +f 31126/31126/22217 29337/29337/20697 31115/31115/22210 +f 31122/31122/22215 31124/31124/22217 31113/31113/22210 +f 31122/31122/22215 31113/31113/22210 31111/31111/22208 +f 30678/30678/21834 31127/31127/22218 31128/31128/22219 +f 30678/30678/21834 31128/31128/22219 30679/30679/21835 +f 31127/31127/22218 31129/31129/22220 31130/31130/22221 +f 31127/31127/22218 31130/31130/22221 31128/31128/22219 +f 31128/31128/22219 31130/31130/22221 31121/31121/22214 +f 31128/31128/22219 31121/31121/22214 31119/31119/22212 +f 30679/30679/21835 31128/31128/22219 31119/31119/22212 +f 30679/30679/21835 31119/31119/22212 30674/30674/21830 +f 31129/31129/22220 31131/31131/22222 31132/31132/22223 +f 31129/31129/22220 31132/31132/22223 31130/31130/22221 +f 31133/31133/22222 29303/29303/20663 29315/29315/20675 +f 31133/31133/22222 29315/29315/20675 31134/31134/22223 +f 31134/31134/22223 29315/29315/20675 29319/29319/20679 +f 31134/31134/22223 29319/29319/20679 31125/31125/22216 +f 31130/31130/22221 31132/31132/22223 31123/31123/22216 +f 31130/31130/22221 31123/31123/22216 31121/31121/22214 +f 30690/30690/21846 31135/31135/22224 31136/31136/22225 +f 30690/30690/21846 31136/31136/22225 30691/30691/21847 +f 31135/31135/22224 31137/31137/22226 31138/31138/22227 +f 31135/31135/22224 31138/31138/22227 31136/31136/22225 +f 31136/31136/22225 31138/31138/22227 31129/31129/22220 +f 31136/31136/22225 31129/31129/22220 31127/31127/22218 +f 30691/30691/21847 31136/31136/22225 31127/31127/22218 +f 30691/30691/21847 31127/31127/22218 30678/30678/21834 +f 31137/31137/22226 31139/31139/22228 31140/31140/22229 +f 31137/31137/22226 31140/31140/22229 31138/31138/22227 +f 31139/31139/22228 31141/31141/22230 31142/31142/20661 +f 31139/31139/22228 31142/31142/20661 31140/31140/22229 +f 31143/31143/22231 29301/29301/20661 29303/29303/20663 +f 31143/31143/22231 29303/29303/20663 31133/31133/22222 +f 31138/31138/22227 31140/31140/22229 31131/31131/22222 +f 31138/31138/22227 31131/31131/22222 31129/31129/22220 +f 30698/30698/21854 31144/31144/22232 31145/31145/22233 +f 30698/30698/21854 31145/31145/22233 30699/30699/21855 +f 31144/31144/22232 31146/31146/22234 31147/31147/22235 +f 31144/31144/22232 31147/31147/22235 31145/31145/22233 +f 31145/31145/22233 31147/31147/22235 31137/31137/22226 +f 31145/31145/22233 31137/31137/22226 31135/31135/22224 +f 30699/30699/21855 31145/31145/22233 31135/31135/22224 +f 30699/30699/21855 31135/31135/22224 30690/30690/21846 +f 31148/31148/22234 31149/31149/22236 31150/31150/22237 +f 31148/31148/22234 31150/31150/22237 31151/31151/22235 +f 31149/31149/22236 29252/29252/20619 29263/29263/20630 +f 31149/31149/22236 29263/29263/20630 31150/31150/22237 +f 31152/31152/22237 31153/31153/20630 31141/31141/22230 +f 31152/31152/22237 31141/31141/22230 31139/31139/22228 +f 31147/31147/22235 31152/31152/22237 31139/31139/22228 +f 31147/31147/22235 31139/31139/22228 31137/31137/22226 +f 30702/30702/21858 31154/31154/22238 31155/31155/22239 +f 30702/30702/21858 31155/31155/22239 30703/30703/21859 +f 31154/31154/22238 31156/31156/22240 31157/31157/22241 +f 31154/31154/22238 31157/31157/22241 31155/31155/22239 +f 31155/31155/22239 31157/31157/22241 31148/31148/22234 +f 31155/31155/22239 31148/31148/22234 31158/31158/22232 +f 30703/30703/21859 31155/31155/22239 31158/31158/22232 +f 30703/30703/21859 31158/31158/22232 30704/30704/21854 +f 31156/31156/22240 31159/31159/22242 31160/31160/22243 +f 31156/31156/22240 31160/31160/22243 31157/31157/22241 +f 31159/31159/22242 29206/29206/20579 29250/29250/20617 +f 31159/31159/22242 29250/29250/20617 31160/31160/22243 +f 31160/31160/22243 29250/29250/20617 29252/29252/20619 +f 31160/31160/22243 29252/29252/20619 31149/31149/22236 +f 31157/31157/22241 31160/31160/22243 31149/31149/22236 +f 31157/31157/22241 31149/31149/22236 31148/31148/22234 +f 30718/30718/21870 31161/31161/22244 31162/31162/22245 +f 30718/30718/21870 31162/31162/22245 30719/30719/21871 +f 31161/31161/22244 31163/31163/22246 31164/31164/22247 +f 31161/31161/22244 31164/31164/22247 31162/31162/22245 +f 31162/31162/22245 31164/31164/22247 31156/31156/22240 +f 31162/31162/22245 31156/31156/22240 31154/31154/22238 +f 30719/30719/21871 31162/31162/22245 31154/31154/22238 +f 30719/30719/21871 31154/31154/22238 30702/30702/21858 +f 31163/31163/22246 31165/31165/22248 31166/31166/22249 +f 31163/31163/22246 31166/31166/22249 31164/31164/22247 +f 31165/31165/22248 29175/29175/20554 29204/29204/20577 +f 31165/31165/22248 29204/29204/20577 31166/31166/22249 +f 31166/31166/22249 29204/29204/20577 29206/29206/20579 +f 31166/31166/22249 29206/29206/20579 31159/31159/22242 +f 31164/31164/22247 31166/31166/22249 31159/31159/22242 +f 31164/31164/22247 31159/31159/22242 31156/31156/22240 +f 30464/30464/21649 30934/30934/22055 31167/31167/22250 +f 30464/30464/21649 31167/31167/22250 30721/30721/21873 +f 30934/30934/22055 30933/30933/22054 31168/31168/22251 +f 30934/30934/22055 31168/31168/22251 31167/31167/22250 +f 31167/31167/22250 31168/31168/22251 31163/31163/22246 +f 31167/31167/22250 31163/31163/22246 31161/31161/22244 +f 30721/30721/21873 31167/31167/22250 31161/31161/22244 +f 30721/30721/21873 31161/31161/22244 30718/30718/21870 +f 30933/30933/22054 30938/30938/22059 31169/31169/22252 +f 30933/30933/22054 31169/31169/22252 31168/31168/22251 +f 30938/30938/22059 29167/29167/20546 29170/29170/20549 +f 30938/30938/22059 29170/29170/20549 31169/31169/22252 +f 31169/31169/22252 29170/29170/20549 29175/29175/20554 +f 31169/31169/22252 29175/29175/20554 31165/31165/22248 +f 31168/31168/22251 31169/31169/22252 31165/31165/22248 +f 31168/31168/22251 31165/31165/22248 31163/31163/22246 +f 29137/29137/20518 30725/30725/21877 31170/31170/22253 +f 29137/29137/20518 31170/31170/22253 30723/30723/21875 +f 30725/30725/21877 30724/30724/21876 31171/31171/22254 +f 30725/30725/21877 31171/31171/22254 31170/31170/22253 +f 31170/31170/22253 31171/31171/22254 30941/30941/22062 +f 31170/31170/22253 30941/30941/22062 30939/30939/22060 +f 30723/30723/21875 31170/31170/22253 30939/30939/22060 +f 30723/30723/21875 30939/30939/22060 30468/30468/21653 +f 30724/30724/21876 30732/30732/21884 31172/31172/22255 +f 30724/30724/21876 31172/31172/22255 31171/31171/22254 +f 30732/30732/21884 29146/29146/20527 29149/29149/20530 +f 30732/30732/21884 29149/29149/20530 31172/31172/22255 +f 31172/31172/22255 29149/29149/20530 29154/29154/20535 +f 31172/31172/22255 29154/29154/20535 30945/30945/22065 +f 31171/31171/22254 31172/31172/22255 30945/30945/22065 +f 31171/31171/22254 30945/30945/22065 30941/30941/22062 +o Cylinder.050__0 +v -0.702281 -0.149145 -0.768390 +v -0.693953 -0.131639 -0.768171 +v -0.594936 -0.178344 -0.800443 +v -0.603264 -0.195850 -0.800662 +v -0.492507 -0.227228 -0.788365 +v -0.500835 -0.244733 -0.788584 +v -0.500835 -0.244733 -0.788584 +v -0.492507 -0.227228 -0.788365 +v -0.402259 -0.270848 -0.733776 +v -0.410588 -0.288353 -0.733995 +v -0.337933 -0.302563 -0.644987 +v -0.346261 -0.320068 -0.645206 +v -0.309321 -0.317545 -0.535515 +v -0.317650 -0.335051 -0.535734 +v -0.320779 -0.313514 -0.422027 +v -0.329108 -0.331020 -0.422246 +v -0.370563 -0.291083 -0.321799 +v -0.378891 -0.308589 -0.322018 +v -0.378891 -0.308589 -0.322018 +v -0.370563 -0.291083 -0.321799 +v -0.451093 -0.253666 -0.250090 +v -0.459422 -0.271172 -0.250309 +v -0.550110 -0.206962 -0.217819 +v -0.558439 -0.224467 -0.218038 +v -0.652539 -0.158078 -0.229897 +v -0.660868 -0.175584 -0.230116 +v -0.660868 -0.175584 -0.230116 +v -0.652539 -0.158078 -0.229897 +v -0.742787 -0.114458 -0.284486 +v -0.751116 -0.131964 -0.284705 +v -0.807113 -0.082743 -0.373275 +v -0.815442 -0.100248 -0.373494 +v -0.835725 -0.067760 -0.482746 +v -0.844054 -0.085266 -0.482965 +v -0.844054 -0.085266 -0.482965 +v -0.835725 -0.067760 -0.482746 +v -0.824267 -0.071792 -0.596235 +v -0.832596 -0.089297 -0.596454 +v -0.407750 -0.268326 -0.726531 +v -0.495087 -0.226113 -0.779360 +v -0.505396 -0.247781 -0.779631 +v -0.418059 -0.289994 -0.726802 +v -0.774483 -0.094223 -0.696463 +v -0.782812 -0.111728 -0.696682 +v -0.660889 -0.316971 -0.802177 +v -0.558460 -0.365855 -0.790100 +v -0.951525 -0.339271 -0.599582 +v -0.897578 -0.225882 -0.598164 +v -0.847794 -0.248313 -0.698392 +v -0.901741 -0.361702 -0.699811 +v -0.962983 -0.335240 -0.486094 +v -0.909036 -0.221851 -0.484675 +v -0.934371 -0.350223 -0.376622 +v -0.880424 -0.236833 -0.375203 +v -0.909036 -0.221851 -0.484675 +v -0.962983 -0.335240 -0.486094 +v -0.870045 -0.381938 -0.287833 +v -0.816098 -0.268548 -0.286414 +v -0.779797 -0.425558 -0.233244 +v -0.725850 -0.312168 -0.231825 +v -0.677368 -0.474441 -0.221166 +v -0.623421 -0.361052 -0.219747 +v -0.725850 -0.312168 -0.231825 +v -0.779797 -0.425558 -0.233244 +v -0.578351 -0.521146 -0.253438 +v -0.524404 -0.407757 -0.252019 +v -0.497821 -0.558563 -0.325146 +v -0.443874 -0.445173 -0.323727 +v -0.448036 -0.580994 -0.425374 +v -0.394090 -0.467605 -0.423955 +v -0.443874 -0.445173 -0.323727 +v -0.497821 -0.558563 -0.325146 +v -0.436579 -0.585025 -0.538862 +v -0.382632 -0.471636 -0.537444 +v -0.465190 -0.570043 -0.648334 +v -0.411244 -0.456653 -0.646915 +v -0.529517 -0.538327 -0.737123 +v -0.475570 -0.424938 -0.735704 +v -0.619764 -0.494707 -0.791712 +v -0.565818 -0.381318 -0.790293 +v -0.722193 -0.445824 -0.803790 +v -0.668247 -0.332435 -0.802371 +v -0.565818 -0.381318 -0.790293 +v -0.619764 -0.494707 -0.791712 +v -0.840437 -0.232850 -0.698198 +v -0.759907 -0.270266 -0.769906 +v -1.016818 -0.810262 -0.776663 +v -1.008800 -0.793409 -0.776452 +v -0.909783 -0.840114 -0.808724 +v -0.917801 -0.856967 -0.808935 +v -0.807354 -0.888997 -0.796646 +v -0.815372 -0.905851 -0.796857 +v -0.815372 -0.905851 -0.796857 +v -0.807354 -0.888997 -0.796646 +v -0.717106 -0.932617 -0.742057 +v -0.725125 -0.949471 -0.742268 +v -0.652780 -0.964333 -0.653268 +v -0.660798 -0.981186 -0.653479 +v -0.624168 -0.979315 -0.543797 +v -0.632186 -0.996168 -0.544007 +v -0.635626 -0.975284 -0.430308 +v -0.643645 -0.992137 -0.430519 +v -0.685410 -0.952852 -0.330080 +v -0.693428 -0.969706 -0.330291 +v -0.693428 -0.969706 -0.330291 +v -0.685410 -0.952852 -0.330080 +v -0.765940 -0.915436 -0.258372 +v -0.773959 -0.932290 -0.258582 +v -0.864957 -0.868731 -0.226100 +v -0.872976 -0.885584 -0.226311 +v -0.967386 -0.819848 -0.238178 +v -0.975405 -0.836701 -0.238389 +v -0.975405 -0.836701 -0.238389 +v -0.967386 -0.819848 -0.238178 +v -1.057634 -0.776228 -0.292767 +v -1.065653 -0.793081 -0.292978 +v -1.121960 -0.744513 -0.381556 +v -1.129979 -0.761366 -0.381767 +v -1.150573 -0.729530 -0.491028 +v -1.158591 -0.746383 -0.491238 +v -1.158591 -0.746383 -0.491238 +v -1.150573 -0.729530 -0.491028 +v -1.139114 -0.733561 -0.604517 +v -1.147133 -0.750414 -0.604727 +v -1.089330 -0.755992 -0.704745 +v -1.097349 -0.772846 -0.704955 +v -0.690037 -0.133607 -0.759818 +v -0.594213 -0.178806 -0.791048 +v -0.594936 -0.178344 -0.800443 +v -0.693953 -0.131639 -0.768171 +v -0.495087 -0.226113 -0.779360 +v -0.492507 -0.227228 -0.788365 +v -0.407750 -0.268326 -0.726531 +v -0.402259 -0.270848 -0.733776 +v -0.345498 -0.299018 -0.640606 +v -0.337933 -0.302563 -0.644987 +v -0.317809 -0.313518 -0.534664 +v -0.309321 -0.317545 -0.535515 +v -0.328897 -0.309617 -0.424835 +v -0.320779 -0.313514 -0.422027 +v -0.377076 -0.287909 -0.327840 +v -0.370563 -0.291083 -0.321799 +v -0.455009 -0.251699 -0.258444 +v -0.451093 -0.253666 -0.250090 +v -0.550833 -0.206500 -0.227213 +v -0.550110 -0.206962 -0.217819 +v -0.649959 -0.159193 -0.238902 +v -0.652539 -0.158078 -0.229897 +v -0.737296 -0.116980 -0.291730 +v -0.742787 -0.114458 -0.284486 +v -0.799548 -0.086287 -0.377656 +v -0.807113 -0.082743 -0.373275 +v -0.827237 -0.071788 -0.483597 +v -0.835725 -0.067760 -0.482746 +v -0.816149 -0.075689 -0.593426 +v -0.824267 -0.071792 -0.596235 +v -0.767970 -0.097397 -0.690422 +v -0.774483 -0.094223 -0.696463 +v -0.737296 -0.116980 -0.291730 +v -0.649959 -0.159193 -0.238902 +v -0.660268 -0.180861 -0.239173 +v -0.747606 -0.138648 -0.292001 +v -0.345498 -0.299018 -0.640606 +v -0.355807 -0.320687 -0.640877 +v -0.799548 -0.086287 -0.377656 +v -0.809857 -0.107956 -0.377927 +v -0.317809 -0.313518 -0.534664 +v -0.328118 -0.335186 -0.534935 +v -0.827237 -0.071788 -0.483597 +v -0.837547 -0.093457 -0.483868 +v -0.328897 -0.309617 -0.424835 +v -0.339206 -0.331285 -0.425107 +v -0.816149 -0.075689 -0.593426 +v -0.826458 -0.097358 -0.593697 +v -0.377076 -0.287909 -0.327840 +v -0.328897 -0.309617 -0.424835 +v -0.339206 -0.331285 -0.425107 +v -0.387385 -0.309577 -0.328111 +v -0.767970 -0.097397 -0.690422 +v -0.816149 -0.075689 -0.593426 +v -0.826458 -0.097358 -0.593697 +v -0.778280 -0.119066 -0.690693 +v -0.455009 -0.251699 -0.258444 +v -0.465318 -0.273367 -0.258715 +v -0.594213 -0.178806 -0.791048 +v -0.690037 -0.133607 -0.759818 +v -0.700346 -0.155275 -0.760089 +v -0.604522 -0.200474 -0.791319 +v -0.550833 -0.206500 -0.227213 +v -0.561142 -0.228168 -0.227484 +v -0.495087 -0.226113 -0.779360 +v -0.505396 -0.247781 -0.779631 +v -0.649959 -0.159193 -0.238902 +v -0.660268 -0.180861 -0.239173 +v -0.691037 -0.159953 -0.740230 +v -0.602804 -0.201571 -0.768987 +v -0.604522 -0.200474 -0.791319 +v -0.700346 -0.155275 -0.760089 +v -0.511530 -0.245131 -0.758224 +v -0.505396 -0.247781 -0.779631 +v -0.431112 -0.283999 -0.709581 +v -0.418059 -0.289994 -0.726802 +v -0.373792 -0.312261 -0.630462 +v -0.355807 -0.320687 -0.640877 +v -0.348296 -0.325612 -0.532912 +v -0.328118 -0.335186 -0.534935 +v -0.358506 -0.322019 -0.431784 +v -0.339206 -0.331285 -0.425107 +v -0.402868 -0.302031 -0.342473 +v -0.387385 -0.309577 -0.328111 +v -0.474628 -0.268690 -0.278574 +v -0.465318 -0.273367 -0.258715 +v -0.562861 -0.227072 -0.249817 +v -0.561142 -0.228168 -0.227484 +v -0.654134 -0.183512 -0.260580 +v -0.660268 -0.180861 -0.239173 +v -0.734552 -0.144643 -0.309223 +v -0.747606 -0.138648 -0.292001 +v -0.791873 -0.116382 -0.388342 +v -0.809857 -0.107956 -0.377927 +v -0.817369 -0.103031 -0.485891 +v -0.837547 -0.093457 -0.483868 +v -0.807158 -0.106623 -0.587019 +v -0.826458 -0.097358 -0.593697 +v -0.762796 -0.126612 -0.676332 +v -0.778280 -0.119066 -0.690693 +v -1.024348 -0.619408 -0.703035 +v -0.970402 -0.506019 -0.701617 +v -0.889871 -0.543435 -0.773324 +v -0.943818 -0.656825 -0.774743 +v -0.951175 -0.672288 -0.774936 +v -0.852158 -0.718993 -0.807208 +v -0.767264 -0.285730 -0.770099 +v -0.821210 -0.399119 -0.771518 +v -0.558460 -0.365855 -0.790100 +v -0.468213 -0.409475 -0.735511 +v -0.749729 -0.767876 -0.795131 +v -0.844801 -0.703530 -0.807015 +v -0.790854 -0.590140 -0.805596 +v -0.688425 -0.639024 -0.793518 +v -0.742372 -0.752413 -0.794937 +v -0.783497 -0.574677 -0.805402 +v -0.729550 -0.461287 -0.803983 +v -0.627121 -0.510171 -0.791906 +v -0.681068 -0.623560 -0.793325 +v -0.403887 -0.441190 -0.646722 +v -0.749729 -0.767876 -0.795131 +v -0.659481 -0.811496 -0.740542 +v -0.742372 -0.752413 -0.794937 +v -0.688425 -0.639024 -0.793518 +v -0.598177 -0.682643 -0.738929 +v -0.652124 -0.796033 -0.740348 +v -0.681068 -0.623560 -0.793325 +v -0.627121 -0.510171 -0.791906 +v -0.536874 -0.553791 -0.737317 +v -0.590820 -0.667180 -0.738736 +v -0.375275 -0.456172 -0.537250 +v -0.595155 -0.843212 -0.651753 +v -0.533851 -0.714359 -0.650140 +v -0.587798 -0.827748 -0.651559 +v -0.472547 -0.585506 -0.648528 +v -0.526494 -0.698895 -0.649947 +v -0.386733 -0.452141 -0.423761 +v -0.566543 -0.858194 -0.542281 +v -0.505239 -0.729341 -0.540668 +v -0.559186 -0.842731 -0.542087 +v -0.443936 -0.600488 -0.539056 +v -0.497882 -0.713878 -0.540475 +v -0.386733 -0.452141 -0.423761 +v -0.329108 -0.331020 -0.422246 +v -0.436517 -0.429710 -0.323534 +v -0.578001 -0.854163 -0.428792 +v -0.516697 -0.725310 -0.427180 +v -0.570644 -0.838699 -0.428599 +v -0.455394 -0.596457 -0.425567 +v -0.509340 -0.709846 -0.426986 +v -0.517047 -0.392293 -0.251825 +v -0.627785 -0.831732 -0.328564 +v -0.566481 -0.702879 -0.326952 +v -0.620428 -0.816268 -0.328371 +v -0.505177 -0.574026 -0.325340 +v -0.559124 -0.687415 -0.326758 +v -0.616064 -0.345589 -0.219553 +v -0.627785 -0.831732 -0.328564 +v -0.708316 -0.794315 -0.256856 +v -0.620428 -0.816268 -0.328371 +v -0.566481 -0.702879 -0.326952 +v -0.647012 -0.665462 -0.255244 +v -0.700958 -0.778852 -0.256662 +v -0.559124 -0.687415 -0.326758 +v -0.505177 -0.574026 -0.325340 +v -0.585708 -0.536610 -0.253631 +v -0.639655 -0.649999 -0.255050 +v -0.718493 -0.296705 -0.231631 +v -0.807333 -0.747610 -0.224584 +v -0.746029 -0.618757 -0.222972 +v -0.799975 -0.732147 -0.224391 +v -0.684725 -0.489904 -0.221359 +v -0.738672 -0.603294 -0.222778 +v -0.718493 -0.296705 -0.231631 +v -0.808741 -0.253085 -0.286220 +v -0.909762 -0.698727 -0.236662 +v -0.848458 -0.569874 -0.235050 +v -0.902405 -0.683263 -0.236469 +v -0.787154 -0.441021 -0.233437 +v -0.841101 -0.554410 -0.234856 +v -0.873067 -0.221370 -0.375009 +v -0.909762 -0.698727 -0.236662 +v -1.000009 -0.655107 -0.291251 +v -0.902405 -0.683263 -0.236469 +v -0.848458 -0.569874 -0.235050 +v -0.938705 -0.526254 -0.289639 +v -0.992652 -0.639643 -0.291058 +v -0.841101 -0.554410 -0.234856 +v -0.787154 -0.441021 -0.233437 +v -0.877402 -0.397401 -0.288026 +v -0.931348 -0.510791 -0.289445 +v -0.901679 -0.206388 -0.484481 +v -1.064336 -0.623392 -0.380040 +v -1.003031 -0.494539 -0.378428 +v -1.056978 -0.607928 -0.379847 +v -0.941728 -0.365686 -0.376815 +v -0.995675 -0.479075 -0.378234 +v -0.901679 -0.206388 -0.484481 +v -0.890221 -0.210419 -0.597970 +v -1.092948 -0.608409 -0.489512 +v -1.031644 -0.479556 -0.487900 +v -1.085590 -0.592946 -0.489318 +v -0.970340 -0.350703 -0.486287 +v -1.024287 -0.464093 -0.487706 +v -1.092948 -0.608409 -0.489512 +v -1.081489 -0.612440 -0.603001 +v -1.085590 -0.592946 -0.489318 +v -1.031644 -0.479556 -0.487900 +v -1.020186 -0.483587 -0.601388 +v -1.074133 -0.596977 -0.602807 +v -1.024287 -0.464093 -0.487706 +v -0.970340 -0.350703 -0.486287 +v -0.958882 -0.354734 -0.599776 +v -1.012829 -0.468124 -0.601195 +v -1.031706 -0.634871 -0.703229 +v -0.909098 -0.377166 -0.700004 +v -0.963045 -0.490555 -0.701423 +v -0.828567 -0.414582 -0.771712 +v -0.882514 -0.527972 -0.773130 +v -0.848940 -0.711982 -0.808295 +v -0.948356 -0.665089 -0.775893 +v -0.787390 -0.582610 -0.806676 +v -0.886805 -0.535717 -0.774274 +v -0.725839 -0.453238 -0.805058 +v -0.825255 -0.406345 -0.772655 +v -0.664288 -0.323866 -0.803439 +v -0.763704 -0.276973 -0.771037 +v -0.746098 -0.761063 -0.796169 +v -0.684548 -0.631691 -0.794550 +v -0.622997 -0.502319 -0.792931 +v -0.561446 -0.372947 -0.791312 +v -0.655487 -0.804859 -0.741360 +v -0.746098 -0.761063 -0.796169 +v -0.593936 -0.675487 -0.739741 +v -0.684548 -0.631691 -0.794550 +v -0.532386 -0.546114 -0.738122 +v -0.622997 -0.502319 -0.792931 +v -0.470835 -0.416742 -0.736504 +v -0.561446 -0.372947 -0.791312 +v -0.590902 -0.836702 -0.652213 +v -0.529351 -0.707330 -0.650594 +v -0.467800 -0.577958 -0.648975 +v -0.406249 -0.448586 -0.647356 +v -0.562174 -0.851745 -0.542300 +v -0.500623 -0.722373 -0.540681 +v -0.439072 -0.593001 -0.539062 +v -0.377522 -0.463629 -0.537443 +v -0.573678 -0.847697 -0.428354 +v -0.512128 -0.718325 -0.426735 +v -0.450577 -0.588953 -0.425116 +v -0.389026 -0.459581 -0.423497 +v -0.623663 -0.825176 -0.327722 +v -0.562112 -0.695803 -0.326103 +v -0.500561 -0.566432 -0.324484 +v -0.436517 -0.429710 -0.323534 +v -0.439011 -0.437059 -0.322865 +v -0.704518 -0.787608 -0.255725 +v -0.623663 -0.825176 -0.327722 +v -0.642967 -0.658236 -0.254106 +v -0.562112 -0.695803 -0.326103 +v -0.581416 -0.528864 -0.252487 +v -0.500561 -0.566432 -0.324484 +v -0.519866 -0.399492 -0.250868 +v -0.439011 -0.437059 -0.322865 +v -0.803934 -0.740715 -0.223323 +v -0.742383 -0.611343 -0.221704 +v -0.680833 -0.481971 -0.220085 +v -0.619282 -0.352599 -0.218467 +v -0.906776 -0.691635 -0.235450 +v -0.845226 -0.562263 -0.233831 +v -0.783674 -0.432890 -0.232212 +v -0.722124 -0.303518 -0.230593 +v -0.997388 -0.647839 -0.290258 +v -0.906776 -0.691635 -0.235450 +v -0.935837 -0.518467 -0.288639 +v -0.845226 -0.562263 -0.233831 +v -0.874286 -0.389095 -0.287020 +v -0.783674 -0.432890 -0.232212 +v -0.812735 -0.259723 -0.285402 +v -0.722124 -0.303518 -0.230593 +v -1.061973 -0.615996 -0.379405 +v -1.000422 -0.486624 -0.377786 +v -0.938871 -0.357252 -0.376168 +v -0.877321 -0.227880 -0.374549 +v -1.090700 -0.600953 -0.489319 +v -1.029150 -0.471581 -0.487700 +v -0.967599 -0.342209 -0.486081 +v -0.906048 -0.212837 -0.484462 +v -1.079196 -0.605000 -0.603265 +v -1.090700 -0.600953 -0.489319 +v -1.017645 -0.475628 -0.601646 +v -1.029150 -0.471581 -0.487700 +v -0.956095 -0.346256 -0.600027 +v -0.967599 -0.342209 -0.486081 +v -0.894544 -0.216884 -0.598408 +v -0.906048 -0.212837 -0.484462 +v -1.029211 -0.627522 -0.703897 +v -0.967661 -0.498150 -0.702277 +v -0.906110 -0.368778 -0.700659 +v -0.844559 -0.239406 -0.699040 +v -1.016818 -0.810262 -0.776663 +v -0.917801 -0.856967 -0.808935 +v -0.815372 -0.905851 -0.796857 +v -0.725125 -0.949471 -0.742268 +v -0.660798 -0.981186 -0.653479 +v -0.632186 -0.996168 -0.544007 +v -0.643645 -0.992137 -0.430519 +v -0.693428 -0.969706 -0.330291 +v -0.773959 -0.932290 -0.258582 +v -0.872976 -0.885584 -0.226311 +v -0.975405 -0.836701 -0.238389 +v -1.065653 -0.793081 -0.292978 +v -1.129979 -0.761366 -0.381767 +v -1.158591 -0.746383 -0.491238 +v -1.147133 -0.750414 -0.604727 +v -1.097349 -0.772846 -0.704955 +vt 0.124169 0.126749 +vt 0.109696 0.123871 +vt 0.116647 0.126749 +vt 0.131119 0.123871 +vt 0.104377 0.118553 +vt 0.136439 0.118553 +vt 0.101498 0.111605 +vt 0.139318 0.111605 +vt 0.101498 0.104084 +vt 0.104377 0.097135 +vt 0.139318 0.104084 +vt 0.109696 0.091817 +vt 0.136439 0.097136 +vt 0.131119 0.091817 +vt 0.116647 0.088939 +vt 0.124169 0.088939 +vt 0.453182 0.164083 +vt 0.453182 0.165516 +vt 0.460982 0.165516 +vt 0.460982 0.164083 +vt 0.466951 0.165516 +vt 0.466951 0.164083 +vt 0.064689 0.113009 +vt 0.064689 0.111576 +vt 0.058720 0.111576 +vt 0.058720 0.113009 +vt 0.050920 0.111576 +vt 0.050920 0.113009 +vt 0.042478 0.111576 +vt 0.042478 0.113009 +vt 0.034678 0.111576 +vt 0.034678 0.113009 +vt 0.028709 0.111576 +vt 0.028709 0.113009 +vt 0.522572 0.071593 +vt 0.522572 0.070159 +vt 0.514773 0.070159 +vt 0.514773 0.071593 +vt 0.506330 0.070159 +vt 0.506330 0.071593 +vt 0.498531 0.070159 +vt 0.498531 0.071593 +vt 0.096714 0.072269 +vt 0.096714 0.070836 +vt 0.088915 0.070836 +vt 0.088915 0.072269 +vt 0.080472 0.070836 +vt 0.080472 0.072269 +vt 0.072673 0.070836 +vt 0.072673 0.072269 +vt 0.430971 0.164083 +vt 0.430971 0.165516 +vt 0.436940 0.165516 +vt 0.436940 0.164083 +vt 0.859478 0.179605 +vt 0.859478 0.172059 +vt 0.857703 0.172059 +vt 0.857703 0.179605 +vt 0.444740 0.165516 +vt 0.444740 0.164083 +vt 0.460982 0.154164 +vt 0.466951 0.154164 +vt 0.436940 0.143611 +vt 0.436940 0.152897 +vt 0.444740 0.152897 +vt 0.444740 0.143611 +vt 0.430971 0.143611 +vt 0.430971 0.152897 +vt 0.080472 0.092741 +vt 0.080472 0.083455 +vt 0.072673 0.083455 +vt 0.072673 0.092741 +vt 0.088915 0.092741 +vt 0.088915 0.083455 +vt 0.096714 0.092741 +vt 0.096714 0.083455 +vt 0.506330 0.092064 +vt 0.506330 0.082778 +vt 0.498531 0.082778 +vt 0.498531 0.092064 +vt 0.514773 0.092064 +vt 0.514773 0.082778 +vt 0.522572 0.092064 +vt 0.522572 0.082778 +vt 0.034678 0.133481 +vt 0.034678 0.124195 +vt 0.028709 0.124195 +vt 0.028709 0.133481 +vt 0.042478 0.133481 +vt 0.042478 0.124195 +vt 0.050920 0.133481 +vt 0.050920 0.124195 +vt 0.058720 0.133481 +vt 0.058720 0.124195 +vt 0.064689 0.133481 +vt 0.064689 0.124195 +vt 0.460982 0.143611 +vt 0.460982 0.152897 +vt 0.466951 0.152897 +vt 0.466951 0.143611 +vt 0.444740 0.154164 +vt 0.453182 0.154164 +vt 0.453182 0.109941 +vt 0.453182 0.111321 +vt 0.460982 0.111321 +vt 0.460982 0.109941 +vt 0.466951 0.111321 +vt 0.466951 0.109941 +vt 0.064689 0.167151 +vt 0.064689 0.165771 +vt 0.058720 0.165771 +vt 0.058720 0.167151 +vt 0.050920 0.165771 +vt 0.050920 0.167151 +vt 0.042478 0.165771 +vt 0.042478 0.167151 +vt 0.034678 0.165771 +vt 0.034678 0.167151 +vt 0.028709 0.165771 +vt 0.028709 0.167151 +vt 0.522572 0.125734 +vt 0.522572 0.124354 +vt 0.514773 0.124354 +vt 0.514773 0.125734 +vt 0.506330 0.124354 +vt 0.506330 0.125734 +vt 0.498531 0.124354 +vt 0.498531 0.125734 +vt 0.096714 0.126411 +vt 0.096714 0.125031 +vt 0.088915 0.125031 +vt 0.088915 0.126411 +vt 0.080472 0.125031 +vt 0.080472 0.126411 +vt 0.072673 0.125031 +vt 0.072673 0.126411 +vt 0.430971 0.109941 +vt 0.430971 0.111321 +vt 0.436940 0.111321 +vt 0.436940 0.109941 +vt 0.444740 0.111321 +vt 0.444740 0.109941 +vt 0.722449 0.778442 +vt 0.729997 0.775316 +vt 0.729861 0.774632 +vt 0.722061 0.777861 +vt 0.738167 0.775316 +vt 0.738303 0.774632 +vt 0.745715 0.778442 +vt 0.746103 0.777861 +vt 0.751492 0.784217 +vt 0.752072 0.783830 +vt 0.754619 0.791763 +vt 0.755303 0.791627 +vt 0.754619 0.799931 +vt 0.755303 0.800067 +vt 0.751492 0.807477 +vt 0.752072 0.807865 +vt 0.745715 0.813253 +vt 0.746103 0.813833 +vt 0.738167 0.816378 +vt 0.738303 0.817063 +vt 0.729997 0.816378 +vt 0.729861 0.817063 +vt 0.722449 0.813253 +vt 0.722061 0.813833 +vt 0.716672 0.807477 +vt 0.716092 0.807865 +vt 0.713545 0.799931 +vt 0.712861 0.800067 +vt 0.713545 0.791763 +vt 0.712861 0.791627 +vt 0.716672 0.784217 +vt 0.716092 0.783830 +vt 0.880585 0.170171 +vt 0.880585 0.175947 +vt 0.882360 0.175947 +vt 0.882360 0.170171 +vt 0.859478 0.187773 +vt 0.857703 0.187773 +vt 0.880585 0.162625 +vt 0.882360 0.162625 +vt 0.859478 0.195319 +vt 0.857703 0.195319 +vt 0.880585 0.154457 +vt 0.882360 0.154457 +vt 0.859478 0.201094 +vt 0.857703 0.201094 +vt 0.880585 0.146911 +vt 0.882360 0.146911 +vt 0.882360 0.243306 +vt 0.882360 0.235760 +vt 0.880585 0.235760 +vt 0.880585 0.243306 +vt 0.070187 0.104954 +vt 0.070187 0.110730 +vt 0.071962 0.110730 +vt 0.071962 0.104954 +vt 0.882360 0.251474 +vt 0.880585 0.251474 +vt 0.070187 0.089240 +vt 0.070187 0.097408 +vt 0.071962 0.097408 +vt 0.071962 0.089240 +vt 0.882360 0.259020 +vt 0.880585 0.259020 +vt 0.070187 0.081694 +vt 0.071962 0.081694 +vt 0.882360 0.264796 +vt 0.880585 0.264796 +vt 0.102998 0.096214 +vt 0.099871 0.103760 +vt 0.108775 0.090439 +vt 0.116323 0.087313 +vt 0.124493 0.087313 +vt 0.132041 0.090439 +vt 0.137818 0.096214 +vt 0.140945 0.103760 +vt 0.140945 0.111928 +vt 0.137818 0.119474 +vt 0.132041 0.125250 +vt 0.124493 0.128376 +vt 0.116323 0.128376 +vt 0.108775 0.125250 +vt 0.102998 0.119474 +vt 0.099871 0.111928 +vt 0.444740 0.122507 +vt 0.444740 0.131793 +vt 0.453182 0.131793 +vt 0.453182 0.122507 +vt 0.453182 0.121240 +vt 0.460982 0.121240 +vt 0.453182 0.152897 +vt 0.453182 0.143611 +vt 0.064689 0.122929 +vt 0.058720 0.122929 +vt 0.466951 0.121240 +vt 0.460982 0.122507 +vt 0.460982 0.131793 +vt 0.466951 0.131793 +vt 0.466951 0.122507 +vt 0.460982 0.133059 +vt 0.460982 0.142345 +vt 0.466951 0.142345 +vt 0.466951 0.133059 +vt 0.050920 0.122929 +vt 0.064689 0.155852 +vt 0.058720 0.155852 +vt 0.064689 0.154586 +vt 0.064689 0.145300 +vt 0.058720 0.145300 +vt 0.058720 0.154586 +vt 0.064689 0.144033 +vt 0.064689 0.134747 +vt 0.058720 0.134747 +vt 0.058720 0.144033 +vt 0.042478 0.122929 +vt 0.050920 0.155852 +vt 0.050920 0.145300 +vt 0.050920 0.154586 +vt 0.050920 0.134747 +vt 0.050920 0.144033 +vt 0.034678 0.122929 +vt 0.042478 0.155852 +vt 0.042478 0.145300 +vt 0.042478 0.154586 +vt 0.042478 0.134747 +vt 0.042478 0.144033 +vt 0.528542 0.081512 +vt 0.528542 0.071593 +vt 0.522572 0.081512 +vt 0.034678 0.155852 +vt 0.034678 0.145300 +vt 0.034678 0.154586 +vt 0.034678 0.134747 +vt 0.034678 0.144033 +vt 0.514773 0.081512 +vt 0.028709 0.155852 +vt 0.028709 0.145300 +vt 0.028709 0.154586 +vt 0.028709 0.134747 +vt 0.028709 0.144033 +vt 0.506330 0.081512 +vt 0.522572 0.114435 +vt 0.514773 0.114435 +vt 0.522572 0.113169 +vt 0.522572 0.103883 +vt 0.514773 0.103883 +vt 0.514773 0.113169 +vt 0.522572 0.102616 +vt 0.522572 0.093330 +vt 0.514773 0.093330 +vt 0.514773 0.102616 +vt 0.498531 0.081512 +vt 0.506330 0.114435 +vt 0.506330 0.103883 +vt 0.506330 0.113169 +vt 0.506330 0.093330 +vt 0.506330 0.102616 +vt 0.096714 0.082189 +vt 0.088915 0.082189 +vt 0.498531 0.114435 +vt 0.498531 0.103883 +vt 0.498531 0.113169 +vt 0.498531 0.093330 +vt 0.498531 0.102616 +vt 0.080472 0.082189 +vt 0.096714 0.115112 +vt 0.088915 0.115112 +vt 0.096714 0.113846 +vt 0.096714 0.104560 +vt 0.088915 0.104560 +vt 0.088915 0.113846 +vt 0.096714 0.103293 +vt 0.096714 0.094007 +vt 0.088915 0.094007 +vt 0.088915 0.103293 +vt 0.072673 0.082189 +vt 0.080472 0.115112 +vt 0.080472 0.104560 +vt 0.080472 0.113846 +vt 0.080472 0.094007 +vt 0.080472 0.103293 +vt 0.430971 0.154164 +vt 0.436940 0.154164 +vt 0.072673 0.115112 +vt 0.072673 0.104560 +vt 0.072673 0.113846 +vt 0.072673 0.094007 +vt 0.072673 0.103293 +vt 0.430971 0.121240 +vt 0.436940 0.121240 +vt 0.430971 0.122507 +vt 0.430971 0.131793 +vt 0.436940 0.131793 +vt 0.436940 0.122507 +vt 0.430971 0.133059 +vt 0.430971 0.142345 +vt 0.436940 0.142345 +vt 0.436940 0.133059 +vt 0.444740 0.121240 +vt 0.444740 0.142345 +vt 0.444740 0.133059 +vt 0.453182 0.142345 +vt 0.453182 0.133059 +vt 0.461030 0.121810 +vt 0.453199 0.121810 +vt 0.461030 0.132405 +vt 0.453199 0.132405 +vt 0.461030 0.142999 +vt 0.453199 0.142999 +vt 0.461030 0.153594 +vt 0.453199 0.153594 +vt 0.467024 0.121810 +vt 0.467024 0.132405 +vt 0.467024 0.142999 +vt 0.467024 0.153594 +vt 0.058768 0.155283 +vt 0.064762 0.155283 +vt 0.058768 0.144688 +vt 0.064762 0.144688 +vt 0.058768 0.134093 +vt 0.064762 0.134093 +vt 0.058768 0.123498 +vt 0.064762 0.123498 +vt 0.050937 0.155283 +vt 0.050937 0.144688 +vt 0.050937 0.134093 +vt 0.050937 0.123498 +vt 0.042461 0.155283 +vt 0.042461 0.144688 +vt 0.042461 0.134093 +vt 0.042461 0.123498 +vt 0.034630 0.155283 +vt 0.034630 0.144688 +vt 0.034630 0.134093 +vt 0.034630 0.123498 +vt 0.028636 0.155283 +vt 0.028636 0.144688 +vt 0.028636 0.134093 +vt 0.028709 0.122929 +vt 0.028636 0.123498 +vt 0.514790 0.113866 +vt 0.522621 0.113866 +vt 0.514790 0.103271 +vt 0.522621 0.103271 +vt 0.514790 0.092676 +vt 0.522621 0.092676 +vt 0.514790 0.082081 +vt 0.522621 0.082081 +vt 0.506313 0.113866 +vt 0.506313 0.103271 +vt 0.506313 0.092676 +vt 0.506313 0.082081 +vt 0.498482 0.113866 +vt 0.498482 0.103271 +vt 0.498482 0.092676 +vt 0.498482 0.082081 +vt 0.088932 0.114543 +vt 0.096763 0.114543 +vt 0.088932 0.103948 +vt 0.096763 0.103948 +vt 0.088932 0.093353 +vt 0.096763 0.093353 +vt 0.088932 0.082758 +vt 0.096763 0.082758 +vt 0.080455 0.114543 +vt 0.080455 0.103948 +vt 0.080455 0.093353 +vt 0.080455 0.082758 +vt 0.072624 0.114543 +vt 0.072624 0.103948 +vt 0.072624 0.093353 +vt 0.072624 0.082758 +vt 0.436892 0.121810 +vt 0.430898 0.121810 +vt 0.436892 0.132405 +vt 0.430898 0.132405 +vt 0.436892 0.142999 +vt 0.430898 0.142999 +vt 0.436892 0.153594 +vt 0.430898 0.153594 +vt 0.444723 0.121810 +vt 0.444723 0.132405 +vt 0.444723 0.142999 +vt 0.444723 0.153594 +vt 0.635587 0.575822 +vt 0.644788 0.562057 +vt 0.638818 0.568025 +vt 0.652587 0.558827 +vt 0.635587 0.584263 +vt 0.661030 0.558827 +vt 0.638818 0.592060 +vt 0.668829 0.562057 +vt 0.644788 0.598028 +vt 0.652587 0.601258 +vt 0.674799 0.568025 +vt 0.661029 0.601258 +vt 0.678029 0.575822 +vt 0.668829 0.598028 +vt 0.678029 0.584263 +vt 0.674799 0.592060 +vn 0.4296 0.9030 0.0113 +vn 0.4296 0.9029 0.0113 +vn -0.4151 0.2086 -0.8855 +vn -0.0237 0.7567 -0.6533 +vn 0.2288 0.6376 -0.7356 +vn -0.0766 0.0489 -0.9959 +vn 0.4901 0.5129 -0.7048 +vn 0.2735 -0.1182 -0.9546 +vn 0.7203 0.4016 -0.5655 +vn 0.5821 -0.2673 -0.7680 +vn 0.8844 0.3207 -0.3390 +vn 0.8020 -0.3757 -0.4644 +vn 0.9574 0.2825 -0.0597 +vn 0.8998 -0.4270 -0.0902 +vn 0.9281 0.2928 0.2299 +vn 0.8606 -0.4132 0.2978 +vn 0.8012 0.3500 0.4854 +vn 0.6904 -0.3365 0.6404 +vn 0.5957 0.4455 0.6683 +vn 0.4151 -0.2086 0.8855 +vn 0.3432 0.5646 0.7506 +vn 0.0766 -0.0489 0.9959 +vn 0.0819 0.6893 0.7198 +vn -0.2735 0.1182 0.9546 +vn -0.1483 0.8005 0.5807 +vn -0.5821 0.2673 0.7680 +vn -0.3125 0.8815 0.3540 +vn -0.8020 0.3757 0.4644 +vn -0.3854 0.9197 0.0748 +vn -0.8998 0.4270 0.0902 +vn -0.8998 0.4269 0.0902 +vn -0.3562 0.9094 -0.2148 +vn -0.8606 0.4132 -0.2978 +vn -0.0586 0.8563 0.5132 +vn 0.1441 0.7583 0.6358 +vn -0.1485 0.8006 0.5805 +vn -0.2292 0.8522 -0.4704 +vn -0.6904 0.3365 -0.6404 +vn -0.0435 0.1180 -0.9921 +vn 0.3056 -0.0487 -0.9509 +vn -0.8278 0.4765 -0.2962 +vn -0.8858 0.3558 -0.2979 +vn -0.7160 0.2793 -0.6399 +vn -0.6580 0.4000 -0.6380 +vn -0.8669 0.4902 0.0908 +vn -0.9249 0.3695 0.0893 +vn -0.7693 0.4392 0.4640 +vn -0.8273 0.3184 0.4628 +vn -0.9249 0.3695 0.0894 +vn -0.8668 0.4902 0.0908 +vn -0.5499 0.3311 0.7668 +vn -0.6078 0.2102 0.7657 +vn -0.2422 0.1823 0.9529 +vn -0.2999 0.0614 0.9520 +vn 0.1071 0.0156 0.9941 +vn 0.0495 -0.1054 0.9932 +vn 0.4447 -0.1436 0.8841 +vn 0.3874 -0.2648 0.8831 +vn 0.7193 -0.2712 0.6396 +vn 0.6621 -0.3924 0.6385 +vn 0.8890 -0.3477 0.2978 +vn 0.8320 -0.4689 0.2965 +vn 0.6621 -0.3924 0.6384 +vn 0.9281 -0.3614 -0.0892 +vn 0.8711 -0.4827 -0.0907 +vn 0.8306 -0.3104 -0.4624 +vn 0.7735 -0.4316 -0.4642 +vn 0.6112 -0.2022 -0.7652 +vn 0.5540 -0.3234 -0.7672 +vn 0.3035 -0.0535 -0.9513 +vn 0.2461 -0.1745 -0.9534 +vn -0.0458 0.1132 -0.9925 +vn -0.1034 -0.0078 -0.9946 +vn 0.2461 -0.1746 -0.9534 +vn -0.6555 0.4047 -0.6377 +vn -0.3810 0.2771 -0.8821 +vn -0.5960 -0.4454 -0.6681 +vn -0.3434 -0.5645 -0.7506 +vn -0.0819 -0.6893 -0.7198 +vn 0.1482 -0.8006 -0.5806 +vn 0.3124 -0.8815 -0.3541 +vn 0.3854 -0.9197 -0.0749 +vn 0.3563 -0.9094 0.2145 +vn 0.2292 -0.8522 0.4703 +vn 0.2292 -0.8522 0.4704 +vn 0.0237 -0.7568 0.6533 +vn -0.2288 -0.6376 0.7356 +vn -0.4901 -0.5129 0.7048 +vn -0.7203 -0.4016 0.5655 +vn -0.8844 -0.3208 0.3391 +vn -0.9574 -0.2825 0.0598 +vn -0.9282 -0.2928 -0.2296 +vn -0.8012 -0.3500 -0.4853 +vn 0.5966 0.5435 0.5904 +vn 0.3741 0.6485 0.6629 +vn -0.0237 0.7568 -0.6533 +vn -0.2032 0.9275 0.3137 +vn 0.8844 0.3208 -0.3391 +vn -0.2675 0.9612 0.0678 +vn 0.9574 0.2825 -0.0598 +vn -0.2417 0.9521 -0.1872 +vn 0.9282 0.2928 0.2297 +vn -0.1299 0.9017 -0.4123 +vn 0.8011 0.3500 0.4854 +vn 0.0510 0.8177 -0.5734 +vn 0.2735 0.7128 -0.6459 +vn 0.5035 0.6030 -0.6188 +vn 0.7063 0.5050 -0.4962 +vn -0.1484 0.8006 0.5805 +vn 0.8508 0.4337 -0.2967 +vn -0.3124 0.8815 0.3541 +vn 0.9151 0.4001 -0.0507 +vn -0.3854 0.9197 0.0749 +vn 0.8893 0.4091 0.2042 +vn -0.3562 0.9094 -0.2146 +vn 0.7775 0.4595 0.4293 +vn 0.7064 0.5049 -0.4961 +vn 0.5036 0.6029 -0.6188 +vn -0.3125 0.8815 0.3541 +vn 0.8845 0.3207 -0.3390 +vn -0.2674 0.9612 0.0677 +vn -0.2417 0.9521 -0.1871 +vn -0.3562 0.9094 -0.2147 +vn -0.1298 0.9017 -0.4124 +vn -0.2291 0.8521 -0.4705 +vn 0.7774 0.4595 0.4294 +vn 0.8011 0.3500 0.4855 +vn 0.0512 0.8176 -0.5735 +vn -0.0238 0.7567 -0.6533 +vn 0.3743 0.6484 0.6629 +vn 0.5965 0.5436 0.5905 +vn 0.5959 0.4454 0.6682 +vn 0.2736 0.7127 -0.6459 +vn 0.2287 0.6377 -0.7356 +vn 0.5036 0.6030 -0.6188 +vn -0.1483 0.8006 0.5805 +vn -0.3124 0.8815 0.3540 +vn -0.0238 0.7568 -0.6532 +vn 0.7203 0.4017 -0.5655 +vn -0.6621 0.3924 -0.6384 +vn -0.7193 0.2712 -0.6396 +vn -0.4447 0.1436 -0.8841 +vn -0.3874 0.2648 -0.8831 +vn -0.4468 0.1388 -0.8838 +vn -0.1093 -0.0204 -0.9938 +vn -0.4412 0.1516 -0.8845 +vn -0.3834 0.2724 -0.8825 +vn 0.6133 -0.1973 -0.7648 +vn 0.2398 -0.1870 -0.9526 +vn -0.0495 0.1054 -0.9932 +vn -0.1071 -0.0156 -0.9941 +vn 0.2422 -0.1823 -0.9529 +vn 0.2999 -0.0614 -0.9520 +vn -0.0478 0.1091 -0.9929 +vn -0.1051 -0.0114 -0.9944 +vn 0.2443 -0.1781 -0.9532 +vn 0.3016 -0.0577 -0.9517 +vn 0.8325 -0.3055 -0.4622 +vn 0.5474 -0.3357 -0.7666 +vn 0.2422 -0.1823 -0.9530 +vn 0.5499 -0.3310 -0.7668 +vn 0.6078 -0.2102 -0.7657 +vn 0.5521 -0.3270 -0.7670 +vn 0.6094 -0.2065 -0.7655 +vn 0.9300 -0.3565 -0.0891 +vn 0.7667 -0.4438 -0.4639 +vn 0.7693 -0.4391 -0.4641 +vn 0.8273 -0.3184 -0.4628 +vn 0.7715 -0.4351 -0.4641 +vn 0.8288 -0.3147 -0.4626 +vn 0.8910 -0.3428 0.2978 +vn 0.8642 -0.4949 -0.0908 +vn 0.8668 -0.4903 -0.0908 +vn 0.9249 -0.3695 -0.0893 +vn 0.8691 -0.4863 -0.0908 +vn 0.9264 -0.3658 -0.0892 +vn 0.7213 -0.2663 0.6394 +vn 0.8251 -0.4811 0.2960 +vn 0.8278 -0.4765 0.2962 +vn 0.8858 -0.3558 0.2979 +vn 0.8300 -0.4725 0.2963 +vn 0.8873 -0.3520 0.2979 +vn 0.4468 -0.1388 0.8838 +vn 0.6555 -0.4047 0.6376 +vn 0.6580 -0.4000 0.6380 +vn 0.7160 -0.2793 0.6399 +vn 0.6602 -0.3960 0.6382 +vn 0.7175 -0.2755 0.6397 +vn 0.1093 0.0204 0.9938 +vn 0.6555 -0.4047 0.6377 +vn 0.3810 -0.2771 0.8821 +vn 0.7159 -0.2793 0.6399 +vn 0.3834 -0.2725 0.8825 +vn 0.4412 -0.1516 0.8845 +vn 0.7175 -0.2755 0.6398 +vn 0.3855 -0.2684 0.8828 +vn 0.4429 -0.1479 0.8843 +vn -0.2398 0.1870 0.9526 +vn 0.0435 -0.1179 0.9921 +vn 0.0458 -0.1132 0.9925 +vn 0.1034 0.0078 0.9946 +vn 0.0478 -0.1091 0.9929 +vn 0.1051 0.0114 0.9944 +vn -0.5474 0.3357 0.7666 +vn -0.3056 0.0487 0.9509 +vn -0.3035 0.0535 0.9513 +vn -0.2461 0.1746 0.9534 +vn -0.3016 0.0577 0.9517 +vn -0.2443 0.1782 0.9532 +vn -0.7667 0.4438 0.4639 +vn -0.3057 0.0487 0.9509 +vn -0.6133 0.1973 0.7648 +vn -0.2461 0.1745 0.9534 +vn -0.6112 0.2022 0.7652 +vn -0.5540 0.3234 0.7672 +vn -0.2443 0.1781 0.9532 +vn -0.6094 0.2065 0.7655 +vn -0.5521 0.3270 0.7670 +vn -0.8642 0.4949 0.0908 +vn -0.8325 0.3055 0.4622 +vn -0.8306 0.3104 0.4624 +vn -0.7735 0.4316 0.4642 +vn -0.8288 0.3147 0.4626 +vn -0.7715 0.4351 0.4641 +vn -0.8252 0.4811 -0.2960 +vn -0.9300 0.3565 0.0891 +vn -0.9281 0.3615 0.0892 +vn -0.8711 0.4827 0.0908 +vn -0.9264 0.3658 0.0893 +vn -0.8691 0.4862 0.0907 +vn -0.8910 0.3428 -0.2978 +vn -0.8711 0.4827 0.0907 +vn -0.8890 0.3477 -0.2978 +vn -0.8320 0.4689 -0.2965 +vn -0.8691 0.4862 0.0908 +vn -0.8873 0.3520 -0.2979 +vn -0.8300 0.4725 -0.2964 +vn -0.7213 0.2664 -0.6394 +vn -0.7175 0.2755 -0.6397 +vn -0.6602 0.3960 -0.6382 +vn -0.4428 0.1479 -0.8843 +vn -0.3855 0.2684 -0.8828 +vn -0.0824 0.0367 -0.9959 +vn -0.4209 0.1964 -0.8856 +vn -0.0785 0.0449 -0.9959 +vn -0.4170 0.2045 -0.8856 +vn -0.0747 0.0530 -0.9958 +vn -0.4132 0.2126 -0.8855 +vn -0.0708 0.0611 -0.9956 +vn -0.4093 0.2208 -0.8853 +vn 0.2677 -0.1304 -0.9546 +vn 0.2716 -0.1222 -0.9546 +vn 0.2754 -0.1142 -0.9545 +vn 0.2793 -0.1060 -0.9543 +vn 0.5762 -0.2795 -0.7680 +vn 0.5801 -0.2713 -0.7680 +vn 0.5840 -0.2633 -0.7679 +vn 0.5878 -0.2551 -0.7677 +vn 0.7961 -0.3879 -0.4645 +vn 0.8000 -0.3798 -0.4645 +vn 0.8039 -0.3717 -0.4644 +vn 0.8077 -0.3635 -0.4642 +vn 0.8939 -0.4391 -0.0903 +vn 0.8978 -0.4310 -0.0902 +vn 0.9017 -0.4229 -0.0901 +vn 0.9055 -0.4147 -0.0900 +vn 0.8547 -0.4253 0.2976 +vn 0.8587 -0.4172 0.2977 +vn 0.8625 -0.4091 0.2978 +vn 0.8663 -0.4009 0.2979 +vn 0.6846 -0.3487 0.6402 +vn 0.6885 -0.3405 0.6404 +vn 0.6923 -0.3325 0.6404 +vn 0.6961 -0.3243 0.6405 +vn 0.4093 -0.2208 0.8853 +vn 0.4132 -0.2126 0.8855 +vn 0.6885 -0.3405 0.6403 +vn 0.4170 -0.2045 0.8856 +vn 0.4209 -0.1964 0.8856 +vn 0.6962 -0.3243 0.6405 +vn 0.0708 -0.0611 0.9956 +vn 0.0747 -0.0530 0.9958 +vn 0.0785 -0.0449 0.9959 +vn 0.0824 -0.0367 0.9959 +vn -0.2793 0.1060 0.9543 +vn -0.2755 0.1142 0.9545 +vn -0.2716 0.1222 0.9546 +vn -0.2677 0.1304 0.9546 +vn -0.5878 0.2551 0.7677 +vn -0.5840 0.2633 0.7679 +vn -0.5801 0.2713 0.7680 +vn -0.5762 0.2795 0.7680 +vn -0.8077 0.3635 0.4642 +vn -0.8039 0.3717 0.4644 +vn -0.8000 0.3798 0.4645 +vn -0.7961 0.3879 0.4645 +vn -0.9055 0.4148 0.0900 +vn -0.9017 0.4229 0.0901 +vn -0.8978 0.4310 0.0902 +vn -0.8939 0.4391 0.0903 +vn -0.8663 0.4009 -0.2979 +vn -0.9055 0.4147 0.0901 +vn -0.8625 0.4091 -0.2978 +vn -0.8587 0.4172 -0.2977 +vn -0.8978 0.4310 0.0903 +vn -0.8547 0.4253 -0.2976 +vn -0.6961 0.3243 -0.6405 +vn -0.6923 0.3324 -0.6404 +vn -0.6885 0.3405 -0.6403 +vn -0.6845 0.3487 -0.6402 +vn -0.9282 -0.2928 -0.2297 +vn -0.8011 -0.3500 -0.4854 +vn 0.0237 -0.7567 0.6533 +vn -0.5958 -0.4455 -0.6683 +vn -0.3432 -0.5646 -0.7506 +vn -0.0818 -0.6893 -0.7198 +vn 0.3562 -0.9094 0.2147 +vn 0.1484 -0.8006 -0.5805 +vn 0.3124 -0.8815 -0.3540 +usemtl Scene_-_Root +s off +f 31389/31173/22256 31393/31174/22256 31391/31175/22256 +f 31393/31174/22257 31389/31173/22257 31387/31176/22257 +f 31393/31174/22256 31387/31176/22256 31395/31177/22256 +f 31395/31177/22256 31387/31176/22256 31385/31178/22256 +f 31395/31177/22256 31385/31178/22256 31397/31179/22256 +f 31397/31179/22256 31385/31178/22256 31383/31180/22256 +f 31397/31179/22256 31383/31180/22256 31367/31181/22256 +f 31367/31181/22256 31383/31180/22256 31368/31182/22256 +f 31368/31182/22256 31383/31180/22256 31381/31183/22256 +f 31368/31182/22256 31381/31183/22256 31371/31184/22256 +f 31371/31184/22256 31381/31183/22256 31379/31185/22256 +f 31371/31184/22256 31379/31185/22256 31377/31186/22256 +f 31371/31184/22256 31377/31186/22256 31373/31187/22256 +f 31373/31187/22256 31377/31186/22256 31375/31188/22256 +s 1 +f 31173/31189/22258 31174/31190/22259 31175/31191/22260 +f 31173/31189/22258 31175/31191/22260 31176/31192/22261 +f 31176/31192/22261 31175/31191/22260 31177/31193/22262 +f 31176/31192/22261 31177/31193/22262 31178/31194/22263 +f 31179/31195/22263 31180/31196/22262 31181/31197/22264 +f 31179/31195/22263 31181/31197/22264 31182/31198/22265 +f 31182/31198/22265 31181/31197/22264 31183/31199/22266 +f 31182/31198/22265 31183/31199/22266 31184/31200/22267 +f 31184/31200/22267 31183/31199/22266 31185/31201/22268 +f 31184/31200/22267 31185/31201/22268 31186/31202/22269 +f 31186/31202/22269 31185/31201/22268 31187/31203/22270 +f 31186/31202/22269 31187/31203/22270 31188/31204/22271 +f 31188/31204/22271 31187/31203/22270 31189/31205/22272 +f 31188/31204/22271 31189/31205/22272 31190/31206/22273 +f 31191/31207/22273 31192/31208/22272 31193/31209/22274 +f 31191/31207/22273 31193/31209/22274 31194/31210/22275 +f 31194/31210/22275 31193/31209/22274 31195/31211/22276 +f 31194/31210/22275 31195/31211/22276 31196/31212/22277 +f 31196/31212/22277 31195/31211/22276 31197/31213/22278 +f 31196/31212/22277 31197/31213/22278 31198/31214/22279 +f 31199/31215/22279 31200/31216/22278 31201/31217/22280 +f 31199/31215/22279 31201/31217/22280 31202/31218/22281 +f 31202/31218/22281 31201/31217/22280 31203/31219/22282 +f 31202/31218/22281 31203/31219/22282 31204/31220/22283 +f 31204/31220/22283 31203/31219/22282 31205/31221/22284 +f 31204/31220/22283 31205/31221/22284 31206/31222/22285 +f 31207/31223/22286 31208/31224/22284 31209/31225/22287 +f 31207/31223/22286 31209/31225/22287 31210/31226/22288 +f 31211/31227/22289 31212/31228/22290 31213/31229/22278 +f 31211/31227/22289 31213/31229/22278 31214/31230/22291 +f 31210/31226/22288 31209/31225/22287 31215/31231/22292 +f 31210/31226/22288 31215/31231/22292 31216/31232/22293 +f 31216/31232/22293 31215/31231/22292 31174/31190/22259 +f 31216/31232/22293 31174/31190/22259 31173/31189/22258 +f 31217/31233/22294 31176/31192/22261 31178/31194/22263 +f 31217/31233/22294 31178/31194/22263 31218/31234/22295 +f 31219/31235/22296 31220/31236/22297 31221/31237/22298 +f 31219/31235/22296 31221/31237/22298 31222/31238/22299 +f 31223/31239/22300 31224/31240/22301 31220/31236/22297 +f 31223/31239/22300 31220/31236/22297 31219/31235/22296 +f 31225/31241/22302 31226/31242/22303 31227/31243/22304 +f 31225/31241/22302 31227/31243/22304 31228/31244/22305 +f 31229/31245/22306 31230/31246/22307 31226/31242/22303 +f 31229/31245/22306 31226/31242/22303 31225/31241/22302 +f 31231/31247/22308 31232/31248/22309 31230/31246/22307 +f 31231/31247/22308 31230/31246/22307 31229/31245/22306 +f 31233/31249/22310 31234/31250/22311 31235/31251/22309 +f 31233/31249/22310 31235/31251/22309 31236/31252/22308 +f 31237/31253/22312 31238/31254/22313 31234/31250/22311 +f 31237/31253/22312 31234/31250/22311 31233/31249/22310 +f 31239/31255/22314 31240/31256/22315 31238/31254/22313 +f 31239/31255/22314 31238/31254/22313 31237/31253/22312 +f 31241/31257/22316 31242/31258/22317 31243/31259/22318 +f 31241/31257/22316 31243/31259/22318 31244/31260/22314 +f 31245/31261/22319 31246/31262/22320 31242/31258/22317 +f 31245/31261/22319 31242/31258/22317 31241/31257/22316 +f 31247/31263/22321 31248/31264/22322 31246/31262/22320 +f 31247/31263/22321 31246/31262/22320 31245/31261/22319 +f 31249/31265/22323 31250/31266/22324 31248/31264/22322 +f 31249/31265/22323 31248/31264/22322 31247/31263/22321 +f 31251/31267/22325 31252/31268/22326 31250/31266/22324 +f 31251/31267/22325 31250/31266/22324 31249/31265/22323 +f 31253/31269/22327 31254/31270/22328 31255/31271/22329 +f 31253/31269/22327 31255/31271/22329 31256/31272/22325 +f 31257/31273/22330 31216/31232/22293 31173/31189/22258 +f 31257/31273/22330 31173/31189/22258 31258/31274/22331 +f 31259/31275/22332 31260/31276/22258 31261/31277/22261 +f 31259/31275/22332 31261/31277/22261 31262/31278/22333 +f 31262/31278/22333 31261/31277/22261 31263/31279/22263 +f 31262/31278/22333 31263/31279/22263 31264/31280/22334 +f 31265/31281/22334 31266/31282/22263 31267/31283/22265 +f 31265/31281/22334 31267/31283/22265 31268/31284/22335 +f 31268/31284/22335 31267/31283/22265 31269/31285/22267 +f 31268/31284/22335 31269/31285/22267 31270/31286/22336 +f 31270/31286/22336 31269/31285/22267 31271/31287/22269 +f 31270/31286/22336 31271/31287/22269 31272/31288/22337 +f 31272/31288/22337 31271/31287/22269 31273/31289/22271 +f 31272/31288/22337 31273/31289/22271 31274/31290/22338 +f 31274/31290/22338 31273/31289/22271 31275/31291/22273 +f 31274/31290/22338 31275/31291/22273 31276/31292/22339 +f 31277/31293/22340 31278/31294/22273 31279/31295/22275 +f 31277/31293/22340 31279/31295/22275 31280/31296/22341 +f 31280/31296/22341 31279/31295/22275 31281/31297/22277 +f 31280/31296/22341 31281/31297/22277 31282/31298/22342 +f 31282/31298/22342 31281/31297/22277 31283/31299/22279 +f 31282/31298/22342 31283/31299/22279 31284/31300/22343 +f 31285/31301/22343 31286/31302/22279 31287/31303/22281 +f 31285/31301/22343 31287/31303/22281 31288/31304/22344 +f 31288/31304/22344 31287/31303/22281 31289/31305/22283 +f 31288/31304/22344 31289/31305/22283 31290/31306/22345 +f 31290/31306/22345 31289/31305/22283 31291/31307/22285 +f 31290/31306/22345 31291/31307/22285 31292/31308/22346 +f 31293/31309/22346 31294/31310/22286 31295/31311/22288 +f 31293/31309/22346 31295/31311/22288 31296/31312/22347 +f 31296/31312/22347 31295/31311/22288 31297/31313/22293 +f 31296/31312/22347 31297/31313/22293 31298/31314/22348 +f 31298/31314/22348 31297/31313/22293 31260/31276/22258 +f 31298/31314/22348 31260/31276/22258 31259/31275/22332 +f 31299/31315/22349 31300/31316/22350 31301/31317/22260 +f 31299/31315/22349 31301/31317/22260 31302/31318/22351 +f 31300/31316/22350 31303/31319/22290 31304/31320/22262 +f 31300/31316/22350 31304/31320/22262 31301/31317/22260 +f 31303/31319/22290 31305/31321/22289 31306/31322/22264 +f 31303/31319/22290 31306/31322/22264 31304/31320/22262 +f 31305/31321/22289 31307/31323/22352 31308/31324/22353 +f 31305/31321/22289 31308/31324/22353 31306/31322/22264 +f 31307/31323/22352 31309/31325/22354 31310/31326/22355 +f 31307/31323/22352 31310/31326/22355 31308/31324/22353 +f 31309/31325/22354 31311/31327/22356 31312/31328/22357 +f 31309/31325/22354 31312/31328/22357 31310/31326/22355 +f 31311/31327/22356 31313/31329/22358 31314/31330/22359 +f 31311/31327/22356 31314/31330/22359 31312/31328/22357 +f 31313/31329/22358 31315/31331/22360 31316/31332/22274 +f 31313/31329/22358 31316/31332/22274 31314/31330/22359 +f 31315/31331/22360 31317/31333/22361 31318/31334/22276 +f 31315/31331/22360 31318/31334/22276 31316/31332/22274 +f 31317/31333/22361 31319/31335/22362 31320/31336/22278 +f 31317/31333/22361 31320/31336/22278 31318/31334/22276 +f 31319/31335/22362 31321/31337/22363 31322/31338/22364 +f 31319/31335/22362 31322/31338/22364 31320/31336/22278 +f 31321/31337/22363 31323/31339/22365 31324/31340/22366 +f 31321/31337/22363 31324/31340/22366 31322/31338/22364 +f 31323/31339/22365 31325/31341/22367 31326/31342/22368 +f 31323/31339/22365 31326/31342/22368 31324/31340/22366 +f 31325/31341/22367 31327/31343/22369 31328/31344/22370 +f 31325/31341/22367 31328/31344/22370 31326/31342/22368 +f 31327/31343/22369 31329/31345/22371 31330/31346/22292 +f 31327/31343/22369 31330/31346/22292 31328/31344/22370 +f 31329/31345/22371 31299/31315/22349 31302/31318/22351 +f 31329/31345/22371 31302/31318/22351 31330/31346/22292 +f 31331/31347/22372 31332/31348/22373 31333/31349/22262 +f 31331/31347/22372 31333/31349/22262 31334/31350/22264 +f 31335/31351/22352 31211/31227/22289 31214/31230/22291 +f 31335/31351/22352 31214/31230/22291 31336/31352/22374 +f 31337/31353/22365 31331/31347/22372 31334/31350/22264 +f 31337/31353/22365 31334/31350/22264 31338/31354/22375 +f 31339/31355/22376 31335/31351/22352 31336/31352/22374 +f 31339/31355/22376 31336/31352/22374 31340/31356/22368 +f 31341/31357/22367 31337/31353/22365 31338/31354/22375 +f 31341/31357/22367 31338/31354/22375 31342/31358/22355 +f 31343/31359/22377 31339/31355/22376 31340/31356/22368 +f 31343/31359/22377 31340/31356/22368 31344/31360/22378 +f 31345/31361/22369 31341/31357/22367 31342/31358/22355 +f 31345/31361/22369 31342/31358/22355 31346/31362/22357 +f 31347/31363/22379 31348/31364/22356 31349/31365/22378 +f 31347/31363/22379 31349/31365/22378 31350/31366/22380 +f 31351/31367/22381 31352/31368/22369 31353/31369/22357 +f 31351/31367/22381 31353/31369/22357 31354/31370/22382 +f 31355/31371/22383 31347/31363/22379 31350/31366/22380 +f 31355/31371/22383 31350/31366/22380 31356/31372/22384 +f 31357/31373/22385 31358/31374/22386 31359/31375/22387 +f 31357/31373/22385 31359/31375/22387 31360/31376/22276 +f 31358/31374/22386 31351/31367/22381 31354/31370/22382 +f 31358/31374/22386 31354/31370/22382 31359/31375/22387 +f 31361/31377/22388 31355/31371/22383 31356/31372/22384 +f 31361/31377/22388 31356/31372/22384 31362/31378/22389 +f 31363/31379/22290 31357/31373/22385 31360/31376/22276 +f 31363/31379/22290 31360/31376/22276 31364/31380/22278 +f 31365/31381/22390 31361/31377/22388 31362/31378/22389 +f 31365/31381/22390 31362/31378/22389 31366/31382/22262 +f 31367/31181/22256 31368/31182/22256 31369/31383/22276 +f 31367/31181/22256 31369/31383/22276 31370/31384/22274 +f 31368/31182/22256 31371/31184/22256 31372/31385/22278 +f 31368/31182/22256 31372/31385/22278 31369/31383/22276 +f 31371/31184/22256 31373/31187/22256 31374/31386/22391 +f 31371/31184/22256 31374/31386/22391 31372/31385/22278 +f 31373/31187/22256 31375/31188/22256 31376/31387/22392 +f 31373/31187/22256 31376/31387/22392 31374/31386/22391 +f 31375/31188/22256 31377/31186/22256 31378/31388/22368 +f 31375/31188/22256 31378/31388/22368 31376/31387/22392 +f 31377/31186/22256 31379/31185/22257 31380/31389/22378 +f 31377/31186/22256 31380/31389/22378 31378/31388/22368 +f 31379/31185/22257 31381/31183/22256 31382/31390/22292 +f 31379/31185/22257 31382/31390/22292 31380/31389/22378 +f 31381/31183/22256 31383/31180/22257 31384/31391/22393 +f 31381/31183/22256 31384/31391/22393 31382/31390/22292 +f 31383/31180/22257 31385/31178/22256 31386/31392/22260 +f 31383/31180/22257 31386/31392/22260 31384/31391/22393 +f 31385/31178/22256 31387/31176/22256 31388/31393/22262 +f 31385/31178/22256 31388/31393/22262 31386/31392/22260 +f 31387/31176/22256 31389/31173/22256 31390/31394/22394 +f 31387/31176/22256 31390/31394/22394 31388/31393/22262 +f 31389/31173/22256 31391/31175/22257 31392/31395/22353 +f 31389/31173/22256 31392/31395/22353 31390/31394/22394 +f 31391/31175/22257 31393/31174/22256 31394/31396/22355 +f 31391/31175/22257 31394/31396/22355 31392/31395/22353 +f 31393/31174/22256 31395/31177/22256 31396/31397/22357 +f 31393/31174/22256 31396/31397/22357 31394/31396/22355 +f 31395/31177/22256 31397/31179/22256 31398/31398/22272 +f 31395/31177/22256 31398/31398/22272 31396/31397/22357 +f 31397/31179/22256 31367/31181/22256 31370/31384/22274 +f 31397/31179/22256 31370/31384/22274 31398/31398/22272 +f 31399/31399/22395 31400/31400/22396 31401/31401/22397 +f 31399/31399/22395 31401/31401/22397 31402/31402/22398 +f 31260/31276/22258 31403/31403/22399 31404/31404/22400 +f 31260/31276/22258 31404/31404/22400 31261/31277/22261 +f 31222/31238/22299 31221/31237/22298 31405/31405/22401 +f 31222/31238/22299 31405/31405/22401 31406/31406/22402 +f 31258/31274/22331 31173/31189/22258 31176/31192/22261 +f 31258/31274/22331 31176/31192/22261 31217/31233/22294 +f 31407/31407/22295 31179/31195/22263 31182/31198/22265 +f 31407/31407/22295 31182/31198/22265 31408/31408/22403 +f 31261/31277/22261 31404/31404/22400 31409/31409/22404 +f 31261/31277/22261 31409/31409/22404 31263/31279/22263 +f 31410/31410/22405 31411/31411/22406 31412/31412/22407 +f 31410/31410/22405 31412/31412/22407 31413/31413/22408 +f 31414/31414/22409 31415/31415/22410 31416/31416/22411 +f 31414/31414/22409 31416/31416/22411 31417/31417/22412 +f 31408/31408/22403 31182/31198/22265 31184/31200/22267 +f 31408/31408/22403 31184/31200/22267 31418/31418/22413 +f 31266/31282/22263 31419/31419/22404 31420/31420/22414 +f 31266/31282/22263 31420/31420/22414 31267/31283/22265 +f 31421/31421/22408 31422/31422/22415 31423/31423/22416 +f 31421/31421/22408 31423/31423/22416 31424/31424/22417 +f 31425/31425/22412 31426/31426/22411 31427/31427/22418 +f 31425/31425/22412 31427/31427/22418 31428/31428/22419 +f 31418/31418/22413 31184/31200/22267 31186/31202/22269 +f 31418/31418/22413 31186/31202/22269 31429/31429/22420 +f 31267/31283/22265 31420/31420/22414 31430/31430/22421 +f 31267/31283/22265 31430/31430/22421 31269/31285/22267 +f 31424/31424/22417 31423/31423/22416 31431/31431/22422 +f 31424/31424/22417 31431/31431/22422 31432/31432/22423 +f 31428/31428/22419 31427/31427/22418 31433/31433/22424 +f 31428/31428/22419 31433/31433/22424 31434/31434/22425 +f 31429/31429/22420 31186/31202/22269 31188/31204/22271 +f 31429/31429/22420 31188/31204/22271 31435/31435/22426 +f 31269/31285/22267 31430/31430/22421 31436/31436/22427 +f 31269/31285/22267 31436/31436/22427 31271/31287/22269 +f 31432/31432/22423 31431/31431/22422 31437/31437/22428 +f 31432/31432/22423 31437/31437/22428 31438/31438/22429 +f 31434/31434/22425 31433/31433/22424 31439/31439/22430 +f 31434/31434/22425 31439/31439/22430 31440/31440/22431 +f 31441/31441/22426 31442/31442/22271 31191/31207/22273 +f 31441/31441/22426 31191/31207/22273 31443/31443/22432 +f 31271/31287/22269 31436/31436/22427 31444/31444/22433 +f 31271/31287/22269 31444/31444/22433 31273/31289/22271 +f 31438/31438/22429 31437/31437/22428 31445/31445/22434 +f 31438/31438/22429 31445/31445/22434 31446/31446/22435 +f 31440/31440/22431 31439/31439/22430 31447/31447/22436 +f 31440/31440/22431 31447/31447/22436 31448/31448/22437 +f 31443/31443/22432 31191/31207/22273 31194/31210/22275 +f 31443/31443/22432 31194/31210/22275 31449/31449/22438 +f 31273/31289/22271 31444/31444/22433 31450/31450/22439 +f 31273/31289/22271 31450/31450/22439 31275/31291/22273 +f 31446/31446/22435 31445/31445/22434 31451/31451/22440 +f 31446/31446/22435 31451/31451/22440 31452/31452/22441 +f 31448/31448/22437 31447/31447/22436 31453/31453/22442 +f 31448/31448/22437 31453/31453/22442 31454/31454/22443 +f 31449/31449/22438 31194/31210/22275 31196/31212/22277 +f 31449/31449/22438 31196/31212/22277 31455/31455/22444 +f 31278/31294/22273 31456/31456/22445 31457/31457/22446 +f 31278/31294/22273 31457/31457/22446 31279/31295/22275 +f 31458/31458/22447 31459/31459/22440 31460/31460/22448 +f 31458/31458/22447 31460/31460/22448 31461/31461/22449 +f 31462/31462/22450 31463/31463/22442 31464/31464/22451 +f 31462/31462/22450 31464/31464/22451 31465/31465/22452 +f 31455/31455/22444 31196/31212/22277 31198/31214/22279 +f 31455/31455/22444 31198/31214/22279 31466/31466/22453 +f 31279/31295/22275 31457/31457/22446 31467/31467/22454 +f 31279/31295/22275 31467/31467/22454 31281/31297/22277 +f 31461/31461/22449 31460/31460/22448 31468/31468/22455 +f 31461/31461/22449 31468/31468/22455 31469/31469/22456 +f 31465/31465/22452 31464/31464/22451 31470/31470/22457 +f 31465/31465/22452 31470/31470/22457 31471/31471/22458 +f 31472/31472/22453 31199/31215/22279 31202/31218/22281 +f 31472/31472/22453 31202/31218/22281 31473/31473/22459 +f 31281/31297/22277 31467/31467/22454 31474/31474/22460 +f 31281/31297/22277 31474/31474/22460 31283/31299/22279 +f 31469/31469/22456 31468/31468/22455 31475/31475/22461 +f 31469/31469/22456 31475/31475/22461 31476/31476/22462 +f 31471/31471/22458 31470/31470/22457 31477/31477/22463 +f 31471/31471/22458 31477/31477/22463 31478/31478/22464 +f 31473/31473/22459 31202/31218/22281 31204/31220/22283 +f 31473/31473/22459 31204/31220/22283 31479/31479/22465 +f 31286/31302/22279 31480/31480/22466 31481/31481/22467 +f 31286/31302/22279 31481/31481/22467 31287/31303/22281 +f 31482/31482/22468 31483/31483/22461 31484/31484/22469 +f 31482/31482/22468 31484/31484/22469 31485/31485/22470 +f 31486/31486/22471 31487/31487/22463 31488/31488/22472 +f 31486/31486/22471 31488/31488/22472 31489/31489/22473 +f 31479/31479/22465 31204/31220/22283 31206/31222/22285 +f 31479/31479/22465 31206/31222/22285 31490/31490/22474 +f 31287/31303/22281 31481/31481/22467 31491/31491/22475 +f 31287/31303/22281 31491/31491/22475 31289/31305/22283 +f 31485/31485/22470 31484/31484/22469 31492/31492/22476 +f 31485/31485/22470 31492/31492/22476 31493/31493/22477 +f 31489/31489/22473 31488/31488/22472 31494/31494/22478 +f 31489/31489/22473 31494/31494/22478 31495/31495/22479 +f 31496/31496/22474 31207/31223/22286 31210/31226/22288 +f 31496/31496/22474 31210/31226/22288 31497/31497/22480 +f 31289/31305/22283 31491/31491/22475 31498/31498/22481 +f 31289/31305/22283 31498/31498/22481 31291/31307/22285 +f 31493/31493/22477 31492/31492/22476 31499/31499/22482 +f 31493/31493/22477 31499/31499/22482 31500/31500/22483 +f 31495/31495/22479 31494/31494/22478 31501/31501/22484 +f 31495/31495/22479 31501/31501/22484 31502/31502/22485 +f 31497/31497/22480 31210/31226/22288 31216/31232/22293 +f 31497/31497/22480 31216/31232/22293 31257/31273/22330 +f 31294/31310/22286 31503/31503/22481 31504/31504/22486 +f 31294/31310/22286 31504/31504/22486 31295/31311/22288 +f 31505/31505/22487 31506/31506/22482 31507/31507/22488 +f 31505/31505/22487 31507/31507/22488 31508/31508/22489 +f 31509/31509/22490 31510/31510/22484 31511/31511/22491 +f 31509/31509/22490 31511/31511/22491 31512/31512/22492 +f 31295/31311/22288 31504/31504/22486 31513/31513/22493 +f 31295/31311/22288 31513/31513/22493 31297/31313/22293 +f 31508/31508/22489 31507/31507/22488 31400/31400/22396 +f 31508/31508/22489 31400/31400/22396 31399/31399/22395 +f 31512/31512/22492 31511/31511/22491 31514/31514/22494 +f 31512/31512/22492 31514/31514/22494 31515/31515/22495 +f 31402/31402/22398 31401/31401/22397 31411/31411/22406 +f 31402/31402/22398 31411/31411/22406 31410/31410/22405 +f 31515/31515/22495 31514/31514/22494 31516/31516/22496 +f 31515/31515/22495 31516/31516/22496 31517/31517/22497 +f 31517/31517/22497 31516/31516/22496 31415/31415/22410 +f 31517/31517/22497 31415/31415/22410 31414/31414/22409 +f 31406/31406/22402 31405/31405/22401 31254/31270/22328 +f 31406/31406/22402 31254/31270/22328 31253/31269/22327 +f 31402/31402/22398 31410/31410/22405 31518/31518/22498 +f 31402/31402/22398 31518/31518/22498 31519/31519/22499 +f 31519/31519/22499 31518/31518/22498 31404/31404/22400 +f 31519/31519/22499 31404/31404/22400 31403/31403/22399 +f 31517/31517/22497 31414/31414/22409 31520/31520/22500 +f 31517/31517/22497 31520/31520/22500 31521/31521/22501 +f 31521/31521/22501 31520/31520/22500 31411/31411/22406 +f 31521/31521/22501 31411/31411/22406 31401/31401/22397 +f 31406/31406/22402 31253/31269/22327 31522/31522/22502 +f 31406/31406/22402 31522/31522/22502 31523/31523/22503 +f 31523/31523/22503 31522/31522/22502 31415/31415/22410 +f 31523/31523/22503 31415/31415/22410 31516/31516/22496 +f 31258/31274/22331 31217/31233/22294 31524/31524/22504 +f 31258/31274/22331 31524/31524/22504 31525/31525/22505 +f 31525/31525/22505 31524/31524/22504 31254/31270/22328 +f 31525/31525/22505 31254/31270/22328 31405/31405/22401 +f 31410/31410/22405 31413/31413/22408 31526/31526/22506 +f 31410/31410/22405 31526/31526/22506 31518/31518/22498 +f 31518/31518/22498 31526/31526/22506 31409/31409/22404 +f 31518/31518/22498 31409/31409/22404 31404/31404/22400 +f 31414/31414/22409 31417/31417/22412 31527/31527/22507 +f 31414/31414/22409 31527/31527/22507 31520/31520/22500 +f 31520/31520/22500 31527/31527/22507 31412/31412/22407 +f 31520/31520/22500 31412/31412/22407 31411/31411/22406 +f 31253/31269/22327 31256/31272/22325 31528/31528/22508 +f 31253/31269/22327 31528/31528/22508 31522/31522/22502 +f 31522/31522/22502 31528/31528/22508 31416/31416/22411 +f 31522/31522/22502 31416/31416/22411 31415/31415/22410 +f 31217/31233/22294 31218/31234/22295 31529/31529/22509 +f 31217/31233/22294 31529/31529/22509 31524/31524/22504 +f 31524/31524/22504 31529/31529/22509 31255/31271/22329 +f 31524/31524/22504 31255/31271/22329 31254/31270/22328 +f 31421/31421/22408 31424/31424/22417 31530/31530/22510 +f 31421/31421/22408 31530/31530/22510 31531/31531/22506 +f 31531/31531/22506 31530/31530/22510 31420/31420/22414 +f 31531/31531/22506 31420/31420/22414 31419/31419/22404 +f 31425/31425/22412 31428/31428/22419 31532/31532/22511 +f 31425/31425/22412 31532/31532/22511 31533/31533/22507 +f 31533/31533/22507 31532/31532/22511 31423/31423/22416 +f 31533/31533/22507 31423/31423/22416 31422/31422/22415 +f 31251/31267/22325 31249/31265/22323 31534/31534/22512 +f 31251/31267/22325 31534/31534/22512 31535/31535/22508 +f 31535/31535/22508 31534/31534/22512 31427/31427/22418 +f 31535/31535/22508 31427/31427/22418 31426/31426/22411 +f 31407/31407/22295 31408/31408/22403 31536/31536/22513 +f 31407/31407/22295 31536/31536/22513 31537/31537/22509 +f 31537/31537/22509 31536/31536/22513 31250/31266/22324 +f 31537/31537/22509 31250/31266/22324 31252/31268/22326 +f 31424/31424/22417 31432/31432/22423 31538/31538/22514 +f 31424/31424/22417 31538/31538/22514 31530/31530/22510 +f 31530/31530/22510 31538/31538/22514 31430/31430/22421 +f 31530/31530/22510 31430/31430/22421 31420/31420/22414 +f 31428/31428/22419 31434/31434/22425 31539/31539/22515 +f 31428/31428/22419 31539/31539/22515 31532/31532/22511 +f 31532/31532/22511 31539/31539/22515 31431/31431/22422 +f 31532/31532/22511 31431/31431/22422 31423/31423/22416 +f 31249/31265/22323 31247/31263/22321 31540/31540/22516 +f 31249/31265/22323 31540/31540/22516 31534/31534/22512 +f 31534/31534/22512 31540/31540/22516 31433/31433/22424 +f 31534/31534/22512 31433/31433/22424 31427/31427/22418 +f 31408/31408/22403 31418/31418/22413 31541/31541/22517 +f 31408/31408/22403 31541/31541/22517 31536/31536/22513 +f 31536/31536/22513 31541/31541/22517 31248/31264/22322 +f 31536/31536/22513 31248/31264/22322 31250/31266/22324 +f 31432/31432/22423 31438/31438/22429 31542/31542/22518 +f 31432/31432/22423 31542/31542/22518 31538/31538/22514 +f 31538/31538/22514 31542/31542/22518 31436/31436/22427 +f 31538/31538/22514 31436/31436/22427 31430/31430/22421 +f 31434/31434/22425 31440/31440/22431 31543/31543/22519 +f 31434/31434/22425 31543/31543/22519 31539/31539/22515 +f 31539/31539/22515 31543/31543/22519 31437/31437/22428 +f 31539/31539/22515 31437/31437/22428 31431/31431/22422 +f 31247/31263/22321 31245/31261/22319 31544/31544/22520 +f 31247/31263/22321 31544/31544/22520 31540/31540/22516 +f 31540/31540/22516 31544/31544/22520 31439/31439/22430 +f 31540/31540/22516 31439/31439/22430 31433/31433/22424 +f 31418/31418/22413 31429/31429/22420 31545/31545/22521 +f 31418/31418/22413 31545/31545/22521 31541/31541/22517 +f 31541/31541/22517 31545/31545/22521 31246/31262/22320 +f 31541/31541/22517 31246/31262/22320 31248/31264/22322 +f 31438/31438/22429 31446/31446/22435 31546/31546/22522 +f 31438/31438/22429 31546/31546/22522 31542/31542/22518 +f 31542/31542/22518 31546/31546/22522 31444/31444/22433 +f 31542/31542/22518 31444/31444/22433 31436/31436/22427 +f 31440/31440/22431 31448/31448/22437 31547/31547/22523 +f 31440/31440/22431 31547/31547/22523 31543/31543/22519 +f 31543/31543/22519 31547/31547/22523 31445/31445/22434 +f 31543/31543/22519 31445/31445/22434 31437/31437/22428 +f 31245/31261/22319 31241/31257/22316 31548/31548/22524 +f 31245/31261/22319 31548/31548/22524 31544/31544/22520 +f 31544/31544/22520 31548/31548/22524 31447/31447/22436 +f 31544/31544/22520 31447/31447/22436 31439/31439/22430 +f 31429/31429/22420 31435/31435/22426 31549/31549/22525 +f 31429/31429/22420 31549/31549/22525 31545/31545/22521 +f 31545/31545/22521 31549/31549/22525 31242/31258/22317 +f 31545/31545/22521 31242/31258/22317 31246/31262/22320 +f 31446/31446/22435 31452/31452/22441 31550/31550/22526 +f 31446/31446/22435 31550/31550/22526 31546/31546/22522 +f 31546/31546/22522 31550/31550/22526 31450/31450/22439 +f 31546/31546/22522 31450/31450/22439 31444/31444/22433 +f 31448/31448/22437 31454/31454/22443 31551/31551/22527 +f 31448/31448/22437 31551/31551/22527 31547/31547/22523 +f 31547/31547/22523 31551/31551/22527 31451/31451/22440 +f 31547/31547/22523 31451/31451/22440 31445/31445/22434 +f 31241/31257/22316 31244/31260/22314 31552/31552/22528 +f 31241/31257/22316 31552/31552/22528 31548/31548/22524 +f 31548/31548/22524 31552/31552/22528 31453/31453/22442 +f 31548/31548/22524 31453/31453/22442 31447/31447/22436 +f 31435/31435/22426 31553/31553/22432 31554/31554/22529 +f 31435/31435/22426 31554/31554/22529 31549/31549/22525 +f 31549/31549/22525 31554/31554/22529 31243/31259/22318 +f 31549/31549/22525 31243/31259/22318 31242/31258/22317 +f 31458/31458/22447 31461/31461/22449 31555/31555/22530 +f 31458/31458/22447 31555/31555/22530 31556/31556/22526 +f 31556/31556/22526 31555/31555/22530 31457/31457/22446 +f 31556/31556/22526 31457/31457/22446 31456/31456/22445 +f 31462/31462/22450 31465/31465/22452 31557/31557/22531 +f 31462/31462/22450 31557/31557/22531 31558/31558/22532 +f 31558/31558/22532 31557/31557/22531 31460/31460/22448 +f 31558/31558/22532 31460/31460/22448 31459/31459/22440 +f 31239/31255/22314 31237/31253/22312 31559/31559/22533 +f 31239/31255/22314 31559/31559/22533 31560/31560/22528 +f 31560/31560/22528 31559/31559/22533 31464/31464/22451 +f 31560/31560/22528 31464/31464/22451 31463/31463/22442 +f 31443/31443/22432 31449/31449/22438 31561/31561/22534 +f 31443/31443/22432 31561/31561/22534 31562/31562/22535 +f 31562/31562/22535 31561/31561/22534 31238/31254/22313 +f 31562/31562/22535 31238/31254/22313 31240/31256/22315 +f 31461/31461/22449 31469/31469/22456 31563/31563/22536 +f 31461/31461/22449 31563/31563/22536 31555/31555/22530 +f 31555/31555/22530 31563/31563/22536 31467/31467/22454 +f 31555/31555/22530 31467/31467/22454 31457/31457/22446 +f 31465/31465/22452 31471/31471/22458 31564/31564/22537 +f 31465/31465/22452 31564/31564/22537 31557/31557/22531 +f 31557/31557/22531 31564/31564/22537 31468/31468/22455 +f 31557/31557/22531 31468/31468/22455 31460/31460/22448 +f 31237/31253/22312 31233/31249/22310 31565/31565/22538 +f 31237/31253/22312 31565/31565/22538 31559/31559/22533 +f 31559/31559/22533 31565/31565/22538 31470/31470/22457 +f 31559/31559/22533 31470/31470/22457 31464/31464/22451 +f 31449/31449/22438 31455/31455/22444 31566/31566/22539 +f 31449/31449/22438 31566/31566/22539 31561/31561/22534 +f 31561/31561/22534 31566/31566/22539 31234/31250/22311 +f 31561/31561/22534 31234/31250/22311 31238/31254/22313 +f 31469/31469/22456 31476/31476/22462 31567/31567/22540 +f 31469/31469/22456 31567/31567/22540 31563/31563/22536 +f 31563/31563/22536 31567/31567/22540 31474/31474/22460 +f 31563/31563/22536 31474/31474/22460 31467/31467/22454 +f 31471/31471/22458 31478/31478/22464 31568/31568/22541 +f 31471/31471/22458 31568/31568/22541 31564/31564/22537 +f 31564/31564/22537 31568/31568/22541 31475/31475/22461 +f 31564/31564/22537 31475/31475/22461 31468/31468/22455 +f 31233/31249/22310 31236/31252/22308 31569/31569/22542 +f 31233/31249/22310 31569/31569/22542 31565/31565/22538 +f 31565/31565/22538 31569/31569/22542 31477/31477/22463 +f 31565/31565/22538 31477/31477/22463 31470/31470/22457 +f 31455/31455/22444 31466/31466/22453 31570/31570/22543 +f 31455/31455/22444 31570/31570/22543 31566/31566/22539 +f 31566/31566/22539 31570/31570/22543 31235/31251/22309 +f 31566/31566/22539 31235/31251/22309 31234/31250/22311 +f 31482/31482/22468 31485/31485/22470 31571/31571/22544 +f 31482/31482/22468 31571/31571/22544 31572/31572/22540 +f 31572/31572/22540 31571/31571/22544 31481/31481/22467 +f 31572/31572/22540 31481/31481/22467 31480/31480/22466 +f 31486/31486/22471 31489/31489/22473 31573/31573/22545 +f 31486/31486/22471 31573/31573/22545 31574/31574/22541 +f 31574/31574/22541 31573/31573/22545 31484/31484/22469 +f 31574/31574/22541 31484/31484/22469 31483/31483/22461 +f 31231/31247/22308 31229/31245/22306 31575/31575/22546 +f 31231/31247/22308 31575/31575/22546 31576/31576/22542 +f 31576/31576/22542 31575/31575/22546 31488/31488/22472 +f 31576/31576/22542 31488/31488/22472 31487/31487/22463 +f 31472/31472/22453 31473/31473/22459 31577/31577/22547 +f 31472/31472/22453 31577/31577/22547 31578/31578/22543 +f 31578/31578/22543 31577/31577/22547 31230/31246/22307 +f 31578/31578/22543 31230/31246/22307 31232/31248/22309 +f 31485/31485/22470 31493/31493/22477 31579/31579/22548 +f 31485/31485/22470 31579/31579/22548 31571/31571/22544 +f 31571/31571/22544 31579/31579/22548 31491/31491/22475 +f 31571/31571/22544 31491/31491/22475 31481/31481/22467 +f 31489/31489/22473 31495/31495/22479 31580/31580/22549 +f 31489/31489/22473 31580/31580/22549 31573/31573/22545 +f 31573/31573/22545 31580/31580/22549 31492/31492/22476 +f 31573/31573/22545 31492/31492/22476 31484/31484/22469 +f 31229/31245/22306 31225/31241/22302 31581/31581/22550 +f 31229/31245/22306 31581/31581/22550 31575/31575/22546 +f 31575/31575/22546 31581/31581/22550 31494/31494/22478 +f 31575/31575/22546 31494/31494/22478 31488/31488/22472 +f 31473/31473/22459 31479/31479/22465 31582/31582/22551 +f 31473/31473/22459 31582/31582/22551 31577/31577/22547 +f 31577/31577/22547 31582/31582/22551 31226/31242/22303 +f 31577/31577/22547 31226/31242/22303 31230/31246/22307 +f 31493/31493/22477 31500/31500/22483 31583/31583/22552 +f 31493/31493/22477 31583/31583/22552 31579/31579/22548 +f 31579/31579/22548 31583/31583/22552 31498/31498/22481 +f 31579/31579/22548 31498/31498/22481 31491/31491/22475 +f 31495/31495/22479 31502/31502/22485 31584/31584/22553 +f 31495/31495/22479 31584/31584/22553 31580/31580/22549 +f 31580/31580/22549 31584/31584/22553 31499/31499/22482 +f 31580/31580/22549 31499/31499/22482 31492/31492/22476 +f 31225/31241/22302 31228/31244/22305 31585/31585/22554 +f 31225/31241/22302 31585/31585/22554 31581/31581/22550 +f 31581/31581/22550 31585/31585/22554 31501/31501/22484 +f 31581/31581/22550 31501/31501/22484 31494/31494/22478 +f 31479/31479/22465 31490/31490/22474 31586/31586/22555 +f 31479/31479/22465 31586/31586/22555 31582/31582/22551 +f 31582/31582/22551 31586/31586/22555 31227/31243/22304 +f 31582/31582/22551 31227/31243/22304 31226/31242/22303 +f 31505/31505/22487 31508/31508/22489 31587/31587/22556 +f 31505/31505/22487 31587/31587/22556 31588/31588/22557 +f 31588/31588/22557 31587/31587/22556 31504/31504/22486 +f 31588/31588/22557 31504/31504/22486 31503/31503/22481 +f 31509/31509/22490 31512/31512/22492 31589/31589/22558 +f 31509/31509/22490 31589/31589/22558 31590/31590/22553 +f 31590/31590/22553 31589/31589/22558 31507/31507/22488 +f 31590/31590/22553 31507/31507/22488 31506/31506/22482 +f 31223/31239/22300 31219/31235/22296 31591/31591/22559 +f 31223/31239/22300 31591/31591/22559 31592/31592/22560 +f 31592/31592/22560 31591/31591/22559 31511/31511/22491 +f 31592/31592/22560 31511/31511/22491 31510/31510/22484 +f 31496/31496/22474 31497/31497/22480 31593/31593/22561 +f 31496/31496/22474 31593/31593/22561 31594/31594/22555 +f 31594/31594/22555 31593/31593/22561 31220/31236/22297 +f 31594/31594/22555 31220/31236/22297 31224/31240/22301 +f 31508/31508/22489 31399/31399/22395 31595/31595/22562 +f 31508/31508/22489 31595/31595/22562 31587/31587/22556 +f 31587/31587/22556 31595/31595/22562 31513/31513/22493 +f 31587/31587/22556 31513/31513/22493 31504/31504/22486 +f 31512/31512/22492 31515/31515/22495 31596/31596/22563 +f 31512/31512/22492 31596/31596/22563 31589/31589/22558 +f 31589/31589/22558 31596/31596/22563 31400/31400/22396 +f 31589/31589/22558 31400/31400/22396 31507/31507/22488 +f 31219/31235/22296 31222/31238/22299 31597/31597/22564 +f 31219/31235/22296 31597/31597/22564 31591/31591/22559 +f 31591/31591/22559 31597/31597/22564 31514/31514/22494 +f 31591/31591/22559 31514/31514/22494 31511/31511/22491 +f 31497/31497/22480 31257/31273/22330 31598/31598/22565 +f 31497/31497/22480 31598/31598/22565 31593/31593/22561 +f 31593/31593/22561 31598/31598/22565 31221/31237/22298 +f 31593/31593/22561 31221/31237/22298 31220/31236/22297 +f 31399/31399/22395 31402/31402/22398 31519/31519/22499 +f 31399/31399/22395 31519/31519/22499 31595/31595/22562 +f 31595/31595/22562 31519/31519/22499 31403/31403/22399 +f 31595/31595/22562 31403/31403/22399 31513/31513/22493 +f 31515/31515/22495 31517/31517/22497 31521/31521/22501 +f 31515/31515/22495 31521/31521/22501 31596/31596/22563 +f 31596/31596/22563 31521/31521/22501 31401/31401/22397 +f 31596/31596/22563 31401/31401/22397 31400/31400/22396 +f 31222/31238/22299 31406/31406/22402 31523/31523/22503 +f 31222/31238/22299 31523/31523/22503 31597/31597/22564 +f 31597/31597/22564 31523/31523/22503 31516/31516/22496 +f 31597/31597/22564 31516/31516/22496 31514/31514/22494 +f 31257/31273/22330 31258/31274/22331 31525/31525/22505 +f 31257/31273/22330 31525/31525/22505 31598/31598/22565 +f 31598/31598/22565 31525/31525/22505 31405/31405/22401 +f 31598/31598/22565 31405/31405/22401 31221/31237/22298 +f 31297/31313/22293 31513/31513/22493 31403/31403/22399 +f 31297/31313/22293 31403/31403/22399 31260/31276/22258 +f 31612/31599/22346 31610/31600/22344 31611/31601/22345 +f 31610/31600/22344 31612/31599/22346 31609/31602/22343 +f 31609/31602/22343 31612/31599/22346 31613/31603/22566 +f 31609/31602/22343 31613/31603/22566 31608/31604/22342 +f 31608/31604/22342 31613/31603/22566 31614/31605/22567 +f 31608/31604/22342 31614/31605/22567 31607/31606/22568 +f 31607/31606/22568 31614/31605/22567 31599/31607/22569 +f 31607/31606/22568 31599/31607/22569 31600/31608/22570 +f 31607/31606/22568 31600/31608/22570 31606/31609/22340 +f 31606/31609/22340 31600/31608/22570 31601/31610/22571 +f 31606/31609/22340 31601/31610/22571 31605/31611/22572 +f 31605/31611/22572 31601/31610/22571 31602/31612/22573 +f 31605/31611/22572 31602/31612/22573 31604/31613/22337 +f 31604/31613/22337 31602/31612/22573 31603/31614/22574 +o Cube.048__0 +v 0.598464 -0.763485 -0.293292 +v 0.133076 0.882398 -0.303243 +v -0.570069 0.707671 -0.368586 +v -0.217517 -1.042022 -0.358635 +v 0.637474 -0.787733 -0.697206 +v 0.172086 1.384140 -0.655121 +v 0.152754 0.890291 -0.333287 +v 0.618142 -0.755592 -0.323336 +v 0.149957 1.397337 -0.655101 +v -0.553188 1.222610 -0.720445 +v -0.572520 0.728762 -0.398610 +v 0.130625 0.903489 -0.333267 +v -0.233056 -1.042880 -0.391952 +v -0.585607 0.706813 -0.401903 +v -0.566275 1.200661 -0.723737 +v -0.213723 -1.075020 -0.765822 +v -0.194046 -1.067127 -0.795866 +v -0.546597 1.208555 -0.753781 +v 0.156548 1.383282 -0.688437 +v 0.621936 -0.788590 -0.730522 +v -0.210927 -1.056078 -0.391971 +v -0.213715 -1.053418 -0.369085 +v -0.224199 -1.053208 -0.373926 +v -0.224702 -1.054025 -0.392644 +v -0.217517 -1.042022 -0.358635 +v -0.229362 -1.044086 -0.369071 +v -0.224199 -1.053208 -0.373926 +v -0.213715 -1.053418 -0.369085 +v -0.224702 -1.054025 -0.392644 +v -0.572659 0.721128 -0.376694 +v -0.581970 0.716777 -0.381964 +v -0.581913 0.705607 -0.379022 +v -0.572520 0.728762 -0.398610 +v -0.583647 0.720521 -0.400252 +v -0.581970 0.716777 -0.381964 +v -0.572659 0.721128 -0.376694 +v -0.581913 0.705607 -0.379022 +v -0.581970 0.716777 -0.381964 +v -0.583647 0.720521 -0.400252 +v -0.191594 -1.088218 -0.765841 +v -0.205369 -1.086164 -0.766513 +v -0.202476 -1.081285 -0.784377 +v -0.191455 -1.080583 -0.787758 +v -0.207102 -1.071251 -0.787744 +v -0.202476 -1.081285 -0.784377 +v -0.205369 -1.086164 -0.766513 +v -0.191455 -1.080583 -0.787758 +v -0.202476 -1.081285 -0.784377 +v -0.207102 -1.071251 -0.787744 +v -0.553188 1.222610 -0.720445 +v -0.550400 1.219950 -0.743331 +v -0.560249 1.214688 -0.740380 +v -0.564315 1.214369 -0.722087 +v -0.559654 1.204431 -0.745659 +v -0.560249 1.214688 -0.740380 +v -0.550400 1.219950 -0.743331 +v -0.564315 1.214369 -0.722087 +v -0.560249 1.214688 -0.740380 +v -0.559654 1.204431 -0.745659 +v 0.605054 -0.777542 -0.326628 +v 0.616181 -0.769300 -0.324986 +v 0.612115 -0.769619 -0.306693 +v 0.602267 -0.774881 -0.303742 +v 0.611521 -0.759362 -0.301414 +v 0.612115 -0.769619 -0.306693 +v 0.616181 -0.769300 -0.324986 +v 0.598464 -0.763485 -0.293292 +v 0.611521 -0.759362 -0.301414 +v 0.130625 0.903489 -0.333267 +v 0.130486 0.895854 -0.311350 +v 0.141507 0.896557 -0.314731 +v 0.144400 0.901436 -0.332595 +v 0.146134 0.886522 -0.311364 +v 0.141507 0.896557 -0.314731 +v 0.130486 0.895854 -0.311350 +v 0.144400 0.901436 -0.332595 +v 0.141507 0.896557 -0.314731 +v 0.146134 0.886522 -0.311364 +v 0.624387 -0.809681 -0.700498 +v 0.624526 -0.802047 -0.722414 +v 0.633837 -0.797697 -0.717144 +v 0.635513 -0.801440 -0.698856 +v 0.633780 -0.786527 -0.720086 +v 0.633837 -0.797697 -0.717144 +v 0.624526 -0.802047 -0.722414 +v 0.635513 -0.801440 -0.698856 +v 0.633837 -0.797697 -0.717144 +v 0.633780 -0.786527 -0.720086 +v 0.149957 1.397337 -0.655101 +v 0.163733 1.395284 -0.654429 +v 0.163229 1.394467 -0.673147 +v 0.152745 1.394677 -0.677987 +v 0.168393 1.385345 -0.678001 +v 0.163229 1.394467 -0.673147 +v 0.163733 1.395284 -0.654429 +v 0.152745 1.394677 -0.677987 +v 0.163229 1.394467 -0.673147 +v 0.168393 1.385345 -0.678001 +v -0.229362 -1.044086 -0.369071 +v -0.564315 1.214369 -0.722087 +v -0.583647 0.720521 -0.400252 +v 0.156548 1.383282 -0.688437 +v -0.546597 1.208555 -0.753781 +v 0.144400 0.901436 -0.332595 +v 0.163733 1.395284 -0.654429 +v 0.611521 -0.759362 -0.301414 +v -0.217517 -1.042022 -0.358635 +vt 0.164784 0.410340 +vt 0.160558 0.288456 +vt 0.106751 0.288456 +vt 0.101067 0.415818 +vt 0.313077 0.415358 +vt 0.313077 0.252903 +vt 0.287833 0.288446 +vt 0.285523 0.411976 +vt 0.736382 0.161054 +vt 0.736382 0.214848 +vt 0.776804 0.222917 +vt 0.776804 0.169124 +vt 0.500909 0.255252 +vt 0.503780 0.383367 +vt 0.528531 0.415666 +vt 0.528531 0.252367 +vt 0.636751 0.604492 +vt 0.646448 0.768380 +vt 0.700212 0.770468 +vt 0.700212 0.612445 +vt 0.560085 0.110365 +vt 0.561786 0.110360 +vt 0.561487 0.109604 +vt 0.560110 0.109445 +vt 0.498498 0.254829 +vt 0.499228 0.255062 +vt 0.499586 0.254288 +vt 0.499261 0.253944 +vt 0.500966 0.254243 +vt 0.106752 0.287320 +vt 0.105975 0.287374 +vt 0.105800 0.288211 +vt 0.674166 0.188956 +vt 0.674166 0.188003 +vt 0.672802 0.188178 +vt 0.672495 0.188956 +vt 0.502099 0.383177 +vt 0.502336 0.383925 +vt 0.503689 0.384222 +vt 0.532437 0.108876 +vt 0.532462 0.107957 +vt 0.531124 0.108173 +vt 0.530812 0.108941 +vt 0.530178 0.252402 +vt 0.529925 0.251586 +vt 0.528587 0.251358 +vt 0.636799 0.603360 +vt 0.636024 0.603388 +vt 0.635817 0.604216 +vt 0.245939 0.013589 +vt 0.247610 0.013589 +vt 0.247303 0.012811 +vt 0.245939 0.012637 +vt 0.645513 0.768104 +vt 0.645670 0.768735 +vt 0.646434 0.769034 +vt 0.528440 0.416521 +vt 0.529805 0.416408 +vt 0.530178 0.415702 +vt 0.560085 0.174304 +vt 0.560136 0.175283 +vt 0.561508 0.175094 +vt 0.561786 0.174299 +vt 0.283854 0.412169 +vt 0.284217 0.412941 +vt 0.285591 0.412982 +vt 0.562566 0.174357 +vt 0.561890 0.175321 +vt 0.674166 0.242750 +vt 0.672495 0.242750 +vt 0.672802 0.243528 +vt 0.674166 0.243702 +vt 0.161514 0.288211 +vt 0.161339 0.287374 +vt 0.160560 0.287320 +vt 0.287757 0.287584 +vt 0.286408 0.287886 +vt 0.286163 0.288640 +vt 0.532437 0.172815 +vt 0.530812 0.172880 +vt 0.531145 0.173663 +vt 0.532488 0.173795 +vt 0.701181 0.612244 +vt 0.701039 0.611402 +vt 0.700259 0.611313 +vt 0.313145 0.416364 +vt 0.314490 0.416125 +vt 0.314739 0.415308 +vt 0.245939 0.067383 +vt 0.245939 0.068336 +vt 0.247303 0.068161 +vt 0.247610 0.067383 +vt 0.314739 0.252853 +vt 0.314373 0.252145 +vt 0.313001 0.252041 +vt 0.700198 0.771123 +vt 0.700989 0.770884 +vt 0.701181 0.770266 +vt 0.100117 0.415573 +vt 0.736751 0.215800 +vt 0.777173 0.223869 +vt 0.248302 0.067383 +vt 0.248302 0.013589 +vt 0.777173 0.168170 +vt 0.736751 0.160101 +vt 0.165739 0.410095 +vt 0.562566 0.110418 +vn 0.2810 -0.2402 0.9292 +vn 0.1251 0.2786 0.9522 +vn -0.3992 0.1517 0.9042 +vn -0.2548 -0.3919 0.8840 +vn 0.9990 0.0439 -0.0019 +vn 0.8777 0.4163 0.2375 +vn 0.8803 0.3409 0.3300 +vn 0.9733 0.0699 0.2186 +vn -0.0856 0.9101 0.4054 +vn -0.4065 0.8402 0.3590 +vn -0.4093 0.7129 0.5694 +vn -0.0950 0.7750 0.6248 +vn -0.9244 -0.3812 0.0160 +vn -0.9964 -0.0832 0.0158 +vn -0.9938 0.0249 -0.1086 +vn -0.9042 -0.3822 -0.1906 +vn -0.1351 -0.2615 -0.9557 +vn -0.2617 0.2808 -0.9234 +vn 0.2698 0.3968 -0.8774 +vn 0.4027 -0.1300 -0.9060 +vn 0.0974 -0.9900 0.1024 +vn -0.0083 -0.8836 0.4682 +vn -0.4911 -0.8240 0.2824 +vn -0.5213 -0.8510 0.0639 +vn -0.2547 -0.3919 0.8840 +vn -0.7700 -0.4220 0.4786 +vn -0.4912 -0.8240 0.2824 +vn -0.5214 -0.8509 0.0640 +vn -0.4451 0.6569 0.6086 +vn -0.8123 0.4244 0.4001 +vn -0.8686 0.0022 0.4955 +vn -0.8865 0.3632 0.2866 +vn -0.8686 0.0022 0.4956 +vn -0.8866 0.3632 0.2865 +vn 0.1069 -0.9878 -0.1131 +vn -0.4981 -0.8551 -0.1437 +vn -0.4390 -0.7353 -0.5163 +vn 0.0536 -0.7637 -0.6433 +vn -0.6974 -0.3279 -0.6373 +vn 0.0536 -0.7637 -0.6434 +vn -0.4390 -0.7353 -0.5164 +vn -0.3725 0.7803 -0.5024 +vn -0.7601 0.5131 -0.3987 +vn -0.8209 0.5302 0.2123 +vn -0.7827 0.0964 -0.6149 +vn -0.3724 0.7803 -0.5024 +vn -0.8209 0.5302 0.2122 +vn -0.7601 0.5130 -0.3987 +vn 0.4443 -0.8877 0.1211 +vn 0.8519 -0.5030 0.1455 +vn 0.7601 -0.5131 0.3987 +vn 0.4086 -0.7610 0.5040 +vn 0.7822 -0.0428 0.6216 +vn 0.8519 -0.5031 0.1455 +vn 0.2809 -0.2402 0.9292 +vn -0.0241 0.7615 0.6477 +vn 0.4390 0.7353 0.5163 +vn 0.4559 0.6532 0.6046 +vn 0.6703 0.3777 0.6388 +vn 0.4390 0.7353 0.5164 +vn 0.4559 0.6531 0.6046 +vn 0.6703 0.3778 0.6387 +vn 0.4549 -0.8857 -0.0931 +vn 0.4695 -0.6406 -0.6077 +vn 0.8123 -0.4244 -0.4001 +vn 0.8503 -0.5232 -0.0579 +vn 0.8673 0.0090 -0.4977 +vn 0.8123 -0.4243 -0.4001 +vn 0.4694 -0.6406 -0.6077 +vn 0.4450 0.8035 0.3955 +vn 0.4912 0.8240 -0.2824 +vn 0.0485 0.8849 -0.4633 +vn 0.7665 0.4322 -0.4750 +vn 0.0484 0.8849 -0.4633 +vn 0.4912 0.8240 -0.2825 +vn -0.7700 -0.4219 0.4787 +vn 0.2698 0.3968 -0.8773 +vn -0.2617 0.2809 -0.9234 +usemtl Scene_-_Root +s 1 +f 31615/31615/22575 31616/31616/22576 31617/31617/22577 +f 31615/31615/22575 31617/31617/22577 31618/31618/22578 +f 31619/31619/22579 31620/31620/22580 31621/31621/22581 +f 31619/31619/22579 31621/31621/22581 31622/31622/22582 +f 31623/31623/22583 31624/31624/22584 31625/31625/22585 +f 31623/31623/22583 31625/31625/22585 31626/31626/22586 +f 31627/31627/22587 31628/31628/22588 31629/31629/22589 +f 31627/31627/22587 31629/31629/22589 31630/31630/22590 +f 31631/31631/22591 31632/31632/22592 31633/31633/22593 +f 31631/31631/22591 31633/31633/22593 31634/31634/22594 +f 31635/31635/22595 31636/31636/22596 31637/31637/22597 +f 31635/31635/22595 31637/31637/22597 31638/31638/22598 +f 31639/31639/22599 31640/31640/22600 31641/31641/22601 +f 31639/31639/22599 31641/31641/22601 31642/31642/22596 +f 31627/31627/22587 31643/31643/22602 31641/31641/22601 +f 31627/31627/22587 31641/31641/22601 31640/31640/22600 +f 31617/31617/22577 31644/31644/22603 31645/31645/22604 +f 31617/31617/22577 31645/31645/22604 31646/31646/22605 +f 31647/31647/22585 31648/31648/22606 31649/31649/22604 +f 31647/31647/22585 31649/31649/22604 31650/31650/22603 +f 31628/31628/22588 31651/31651/22607 31652/31652/22604 +f 31628/31628/22588 31652/31652/22604 31653/31653/22608 +f 31654/31654/22609 31655/31655/22610 31656/31656/22611 +f 31654/31654/22609 31656/31656/22611 31657/31657/22612 +f 31630/31630/22590 31658/31658/22613 31659/31659/22611 +f 31630/31630/22590 31659/31659/22611 31660/31660/22610 +f 31631/31631/22591 31661/31661/22614 31662/31662/22615 +f 31631/31631/22591 31662/31662/22615 31663/31663/22613 +f 31664/31664/22584 31665/31665/22616 31666/31666/22617 +f 31664/31664/22584 31666/31666/22617 31667/31667/22618 +f 31632/31632/22592 31668/31668/22619 31669/31669/22617 +f 31632/31632/22592 31669/31669/22617 31670/31670/22620 +f 31629/31629/22589 31671/31671/22621 31672/31672/22622 +f 31629/31629/22589 31672/31672/22622 31673/31673/22619 +f 31674/31674/22623 31675/31675/22624 31676/31676/22625 +f 31674/31674/22623 31676/31676/22625 31677/31677/22626 +f 31622/31622/22582 31678/31678/22627 31679/31679/22625 +f 31622/31622/22582 31679/31679/22625 31680/31680/22628 +f 31681/31681/22629 31677/31677/22626 31676/31676/22625 +f 31681/31681/22629 31676/31676/22625 31682/31682/22627 +f 31683/31683/22586 31684/31684/22630 31685/31685/22631 +f 31683/31683/22586 31685/31685/22631 31686/31686/22632 +f 31616/31616/22576 31687/31687/22633 31688/31688/22634 +f 31616/31616/22576 31688/31688/22634 31689/31689/22630 +f 31621/31621/22581 31690/31690/22635 31691/31691/22631 +f 31621/31621/22581 31691/31691/22631 31692/31692/22636 +f 31693/31693/22637 31694/31694/22638 31695/31695/22639 +f 31693/31693/22637 31695/31695/22639 31696/31696/22640 +f 31634/31634/22594 31697/31697/22641 31698/31698/22642 +f 31634/31634/22594 31698/31698/22642 31699/31699/22643 +f 31619/31619/22579 31700/31700/22640 31701/31701/22639 +f 31619/31619/22579 31701/31701/22639 31702/31702/22641 +f 31703/31703/22583 31704/31704/22644 31705/31705/22645 +f 31703/31703/22583 31705/31705/22645 31706/31706/22646 +f 31620/31620/22580 31707/31707/22647 31708/31708/22645 +f 31620/31620/22580 31708/31708/22645 31709/31709/22644 +f 31633/31633/22593 31710/31710/22648 31711/31711/22649 +f 31633/31633/22593 31711/31711/22649 31712/31712/22647 +f 31654/31654/22609 31635/31635/22595 31638/31638/22598 +f 31654/31654/22609 31638/31638/22598 31655/31655/22610 +f 31660/31660/22610 31643/31643/22602 31627/31627/22587 +f 31660/31660/22610 31627/31627/22587 31630/31630/22590 +f 31618/31618/22578 31617/31617/22577 31646/31646/22605 +f 31618/31618/22578 31646/31646/22605 31713/31713/22650 +f 31640/31640/22600 31651/31651/22607 31628/31628/22588 +f 31640/31640/22600 31628/31628/22588 31627/31627/22587 +f 31625/31625/22585 31624/31624/22584 31714/31714/22621 +f 31625/31625/22585 31714/31714/22621 31715/31715/22606 +f 31653/31653/22608 31671/31671/22621 31629/31629/22589 +f 31653/31653/22608 31629/31629/22589 31628/31628/22588 +f 31632/31632/22592 31631/31631/22591 31663/31663/22613 +f 31632/31632/22592 31663/31663/22613 31668/31668/22619 +f 31673/31673/22619 31658/31658/22613 31630/31630/22590 +f 31673/31673/22619 31630/31630/22590 31629/31629/22589 +f 31693/31693/22637 31654/31654/22609 31657/31657/22612 +f 31693/31693/22637 31657/31657/22612 31694/31694/22638 +f 31699/31699/22643 31661/31661/22614 31631/31631/22591 +f 31699/31699/22643 31631/31631/22591 31634/31634/22594 +f 31664/31664/22584 31703/31703/22583 31706/31706/22646 +f 31664/31664/22584 31706/31706/22646 31665/31665/22616 +f 31665/31665/22616 31706/31706/22646 31716/31716/22651 +f 31665/31665/22616 31716/31716/22651 31717/31717/22652 +f 31620/31620/22580 31619/31619/22579 31702/31702/22641 +f 31620/31620/22580 31702/31702/22641 31707/31707/22647 +f 31712/31712/22647 31697/31697/22641 31634/31634/22594 +f 31712/31712/22647 31634/31634/22594 31633/31633/22593 +f 31674/31674/22623 31693/31693/22637 31696/31696/22640 +f 31674/31674/22623 31696/31696/22640 31675/31675/22624 +f 31680/31680/22628 31700/31700/22640 31619/31619/22579 +f 31680/31680/22628 31619/31619/22579 31622/31622/22582 +f 31623/31623/22583 31626/31626/22586 31718/31718/22632 +f 31623/31623/22583 31718/31718/22632 31719/31719/22644 +f 31709/31709/22644 31690/31690/22635 31621/31621/22581 +f 31709/31709/22644 31621/31621/22581 31620/31620/22580 +f 31616/31616/22576 31615/31615/22575 31720/31720/22627 +f 31616/31616/22576 31720/31720/22627 31687/31687/22633 +f 31692/31692/22636 31678/31678/22627 31622/31622/22582 +f 31692/31692/22636 31622/31622/22582 31621/31621/22581 +f 31635/31635/22595 31674/31674/22623 31677/31677/22626 +f 31635/31635/22595 31677/31677/22626 31636/31636/22596 +f 31636/31636/22596 31677/31677/22626 31681/31681/22629 +f 31636/31636/22596 31681/31681/22629 31721/31721/22578 +f 31683/31683/22586 31647/31647/22585 31650/31650/22603 +f 31683/31683/22586 31650/31650/22603 31684/31684/22630 +f 31689/31689/22630 31644/31644/22603 31617/31617/22577 +f 31689/31689/22630 31617/31617/22577 31616/31616/22576 +f 31654/31654/22609 31693/31693/22637 31674/31674/22623 +f 31654/31654/22609 31674/31674/22623 31635/31635/22595 +o Cylinder.051__0 +v -0.530510 0.490100 -0.106353 +v -0.529291 0.490107 -0.087829 +v -0.505777 0.470243 -0.089369 +v -0.506996 0.470236 -0.107893 +v -0.506996 0.470236 -0.107893 +v -0.505777 0.470243 -0.089369 +v -0.503165 0.439533 -0.089530 +v -0.504384 0.439526 -0.108054 +v -0.504384 0.439526 -0.108054 +v -0.503165 0.439533 -0.089530 +v -0.522985 0.415967 -0.088216 +v -0.524204 0.415960 -0.106741 +v -0.524204 0.415960 -0.106741 +v -0.522985 0.415967 -0.088216 +v -0.553628 0.413350 -0.086199 +v -0.554847 0.413343 -0.104723 +v -0.554847 0.413343 -0.104723 +v -0.553628 0.413350 -0.086199 +v -0.577144 0.433214 -0.084659 +v -0.578363 0.433208 -0.103184 +v -0.578363 0.433208 -0.103184 +v -0.577144 0.433214 -0.084659 +v -0.579756 0.463924 -0.084499 +v -0.580975 0.463917 -0.103023 +v -0.580975 0.463917 -0.103023 +v -0.579756 0.463924 -0.084499 +v -0.559935 0.487490 -0.085812 +v -0.561154 0.487483 -0.104336 +v -0.561154 0.487483 -0.104336 +v -0.559935 0.487490 -0.085812 +v -0.529291 0.490107 -0.087829 +v -0.530510 0.490100 -0.106353 +v -0.505777 0.470243 -0.089369 +v -0.529291 0.490107 -0.087829 +v -0.559935 0.487490 -0.085812 +v -0.579756 0.463924 -0.084499 +v -0.577144 0.433214 -0.084659 +v -0.553628 0.413350 -0.086199 +v -0.522985 0.415967 -0.088216 +v -0.503165 0.439533 -0.089530 +v -0.530510 0.490100 -0.106353 +v -0.506996 0.470236 -0.107893 +v -0.504384 0.439526 -0.108054 +v -0.524204 0.415960 -0.106741 +v -0.554847 0.413343 -0.104723 +v -0.578363 0.433208 -0.103184 +v -0.580975 0.463917 -0.103023 +v -0.561154 0.487483 -0.104336 +vt 0.661229 0.090579 +vt 0.662602 0.090579 +vt 0.662602 0.088300 +vt 0.661229 0.088300 +vt 0.661229 0.088300 +vt 0.662602 0.088300 +vt 0.662602 0.086689 +vt 0.661229 0.086689 +vt 0.072110 0.052435 +vt 0.070737 0.052435 +vt 0.070737 0.054046 +vt 0.072110 0.054046 +vt 0.072110 0.054046 +vt 0.070737 0.054046 +vt 0.070737 0.056326 +vt 0.072110 0.056326 +vt 0.072110 0.056326 +vt 0.070737 0.056326 +vt 0.070737 0.057937 +vt 0.072110 0.057937 +vt 0.529064 0.076993 +vt 0.530437 0.076993 +vt 0.530437 0.075381 +vt 0.529064 0.075381 +vt 0.529064 0.075381 +vt 0.530437 0.075381 +vt 0.530437 0.073102 +vt 0.529064 0.073102 +vt 0.529064 0.073102 +vt 0.530437 0.073102 +vt 0.530437 0.071491 +vt 0.529064 0.071491 +vt 0.615585 0.772893 +vt 0.619476 0.774504 +vt 0.617864 0.772893 +vt 0.613973 0.774504 +vt 0.619476 0.776784 +vt 0.613973 0.776784 +vt 0.617864 0.778395 +vt 0.615585 0.778395 +vt 0.711395 0.602401 +vt 0.713007 0.606291 +vt 0.713007 0.604012 +vt 0.709115 0.602401 +vt 0.711395 0.607903 +vt 0.709115 0.607903 +vt 0.707503 0.604012 +vt 0.707503 0.606291 +vn 0.6431 0.7646 -0.0426 +vn 0.9942 0.0849 -0.0655 +vn 0.7630 -0.6445 -0.0500 +vn 0.0847 -0.9964 -0.0052 +vn -0.6431 -0.7646 0.0426 +vn -0.9942 -0.0849 0.0655 +vn -0.7630 0.6445 0.0500 +vn -0.0847 0.9964 0.0052 +vn 0.0657 0.0004 0.9978 +vn -0.0657 -0.0004 -0.9978 +usemtl Scene_-_Root +s off +f 31722/31722/22653 31723/31723/22653 31724/31724/22653 +f 31722/31722/22653 31724/31724/22653 31725/31725/22653 +f 31726/31726/22654 31727/31727/22654 31728/31728/22654 +f 31726/31726/22654 31728/31728/22654 31729/31729/22654 +f 31730/31730/22655 31731/31731/22655 31732/31732/22655 +f 31730/31730/22655 31732/31732/22655 31733/31733/22655 +f 31734/31734/22656 31735/31735/22656 31736/31736/22656 +f 31734/31734/22656 31736/31736/22656 31737/31737/22656 +f 31738/31738/22657 31739/31739/22657 31740/31740/22657 +f 31738/31738/22657 31740/31740/22657 31741/31741/22657 +f 31742/31742/22658 31743/31743/22658 31744/31744/22658 +f 31742/31742/22658 31744/31744/22658 31745/31745/22658 +f 31746/31746/22659 31747/31747/22659 31748/31748/22659 +f 31746/31746/22659 31748/31748/22659 31749/31749/22659 +f 31750/31750/22660 31751/31751/22660 31752/31752/22660 +f 31750/31750/22660 31752/31752/22660 31753/31753/22660 +f 31758/31754/22661 31756/31755/22661 31757/31756/22661 +f 31756/31755/22661 31758/31754/22661 31759/31757/22661 +f 31756/31755/22661 31759/31757/22661 31755/31758/22661 +f 31755/31758/22661 31759/31757/22661 31760/31759/22661 +f 31755/31758/22661 31760/31759/22661 31754/31760/22661 +f 31754/31760/22661 31760/31759/22661 31761/31761/22661 +f 31769/31762/22662 31767/31763/22662 31768/31764/22662 +f 31767/31763/22662 31769/31762/22662 31762/31765/22662 +f 31767/31763/22662 31762/31765/22662 31766/31766/22662 +f 31766/31766/22662 31762/31765/22662 31765/31767/22662 +f 31765/31767/22662 31762/31765/22662 31763/31768/22662 +f 31765/31767/22662 31763/31768/22662 31764/31769/22662 +o Cylinder.052__0 +v -0.502378 0.181865 -0.112422 +v -0.502381 0.181937 -0.093858 +v -0.518819 0.155865 -0.093760 +v -0.518816 0.155794 -0.112324 +v -0.518816 0.155794 -0.112324 +v -0.518819 0.155865 -0.093760 +v -0.548877 0.149052 -0.093738 +v -0.548874 0.148981 -0.112303 +v -0.548874 0.148981 -0.112303 +v -0.548877 0.149052 -0.093738 +v -0.574949 0.165489 -0.093806 +v -0.574946 0.165418 -0.112370 +v -0.574946 0.165418 -0.112370 +v -0.574949 0.165489 -0.093806 +v -0.581762 0.195548 -0.093923 +v -0.581758 0.195477 -0.112487 +v -0.581758 0.195477 -0.112487 +v -0.581762 0.195548 -0.093923 +v -0.565325 0.221619 -0.094020 +v -0.565321 0.221548 -0.112585 +v -0.565321 0.221548 -0.112585 +v -0.565325 0.221619 -0.094020 +v -0.535266 0.228432 -0.094042 +v -0.535263 0.228361 -0.112606 +v -0.535263 0.228361 -0.112606 +v -0.535266 0.228432 -0.094042 +v -0.509194 0.211995 -0.093974 +v -0.509191 0.211924 -0.112538 +v -0.509191 0.211924 -0.112538 +v -0.509194 0.211995 -0.093974 +v -0.502381 0.181937 -0.093858 +v -0.502378 0.181865 -0.112422 +v -0.518819 0.155865 -0.093760 +v -0.502381 0.181937 -0.093858 +v -0.509194 0.211995 -0.093974 +v -0.535266 0.228432 -0.094042 +v -0.565325 0.221619 -0.094020 +v -0.581762 0.195548 -0.093923 +v -0.574949 0.165489 -0.093806 +v -0.548877 0.149052 -0.093738 +v -0.502378 0.181865 -0.112422 +v -0.518816 0.155794 -0.112324 +v -0.548874 0.148981 -0.112303 +v -0.574946 0.165418 -0.112370 +v -0.581758 0.195477 -0.112487 +v -0.565321 0.221548 -0.112585 +v -0.535263 0.228361 -0.112606 +v -0.509191 0.211924 -0.112538 +vt 0.951695 0.931740 +vt 0.953068 0.931740 +vt 0.953068 0.929461 +vt 0.951695 0.929461 +vt 0.951695 0.929461 +vt 0.953068 0.929461 +vt 0.953068 0.927850 +vt 0.951695 0.927850 +vt 0.142216 0.047346 +vt 0.140843 0.047346 +vt 0.140843 0.048958 +vt 0.142216 0.048958 +vt 0.142216 0.048958 +vt 0.140843 0.048958 +vt 0.140843 0.051237 +vt 0.142216 0.051237 +vt 0.142216 0.051237 +vt 0.140843 0.051237 +vt 0.140843 0.052848 +vt 0.142216 0.052848 +vt 0.140843 0.080910 +vt 0.142216 0.080910 +vt 0.142216 0.079298 +vt 0.140843 0.079298 +vt 0.140843 0.079298 +vt 0.142216 0.079298 +vt 0.142216 0.077019 +vt 0.140843 0.077019 +vt 0.140843 0.077019 +vt 0.142216 0.077019 +vt 0.142216 0.075408 +vt 0.140843 0.075408 +vt 0.605171 0.773007 +vt 0.609062 0.774618 +vt 0.607450 0.773007 +vt 0.603559 0.774618 +vt 0.609062 0.776897 +vt 0.603559 0.776897 +vt 0.607450 0.778509 +vt 0.605171 0.778509 +vt 0.722622 0.602401 +vt 0.724234 0.606291 +vt 0.724234 0.604012 +vt 0.720343 0.602401 +vt 0.722622 0.607903 +vt 0.720343 0.607903 +vt 0.718731 0.604012 +vt 0.718731 0.606291 +vn 0.8459 -0.5333 0.0022 +vn 0.2210 -0.9753 0.0038 +vn -0.5333 -0.8459 0.0032 +vn -0.9753 -0.2210 0.0007 +vn -0.8459 0.5333 -0.0022 +vn -0.2210 0.9753 -0.0038 +vn 0.5333 0.8459 -0.0032 +vn 0.9753 0.2210 -0.0007 +vn -0.0002 0.0038 1.0000 +vn -0.0002 0.0039 1.0000 +vn 0.0002 -0.0038 -1.0000 +vn 0.0002 -0.0039 -1.0000 +usemtl Scene_-_Root +s off +f 31770/31770/22663 31771/31771/22663 31772/31772/22663 +f 31770/31770/22663 31772/31772/22663 31773/31773/22663 +f 31774/31774/22664 31775/31775/22664 31776/31776/22664 +f 31774/31774/22664 31776/31776/22664 31777/31777/22664 +f 31778/31778/22665 31779/31779/22665 31780/31780/22665 +f 31778/31778/22665 31780/31780/22665 31781/31781/22665 +f 31782/31782/22666 31783/31783/22666 31784/31784/22666 +f 31782/31782/22666 31784/31784/22666 31785/31785/22666 +f 31786/31786/22667 31787/31787/22667 31788/31788/22667 +f 31786/31786/22667 31788/31788/22667 31789/31789/22667 +f 31790/31790/22668 31791/31791/22668 31792/31792/22668 +f 31790/31790/22668 31792/31792/22668 31793/31793/22668 +f 31794/31794/22669 31795/31795/22669 31796/31796/22669 +f 31794/31794/22669 31796/31796/22669 31797/31797/22669 +f 31798/31798/22670 31799/31799/22670 31800/31800/22670 +f 31798/31798/22670 31800/31800/22670 31801/31801/22670 +f 31806/31802/22671 31804/31803/22671 31805/31804/22671 +f 31804/31803/22672 31806/31802/22672 31807/31805/22672 +f 31804/31803/22671 31807/31805/22671 31803/31806/22671 +f 31803/31806/22672 31807/31805/22672 31808/31807/22672 +f 31803/31806/22671 31808/31807/22671 31802/31808/22671 +f 31802/31808/22672 31808/31807/22672 31809/31809/22672 +f 31817/31810/22673 31815/31811/22673 31816/31812/22673 +f 31815/31811/22673 31817/31810/22673 31810/31813/22673 +f 31815/31811/22674 31810/31813/22674 31814/31814/22674 +f 31814/31814/22674 31810/31813/22674 31813/31815/22674 +f 31813/31815/22673 31810/31813/22673 31811/31816/22673 +f 31813/31815/22674 31811/31816/22674 31812/31817/22674 +o Cylinder.053__0 +v 0.515537 0.490218 -0.118852 +v 0.516756 0.489703 -0.100335 +v 0.540272 0.469890 -0.102434 +v 0.539052 0.470406 -0.120951 +v 0.539052 0.470406 -0.120951 +v 0.540272 0.469890 -0.102434 +v 0.542883 0.439197 -0.103461 +v 0.541664 0.439713 -0.121978 +v 0.541664 0.439713 -0.121978 +v 0.542883 0.439197 -0.103461 +v 0.523063 0.415604 -0.102813 +v 0.521844 0.416120 -0.121330 +v 0.521844 0.416120 -0.121330 +v 0.523063 0.415604 -0.102813 +v 0.492419 0.412931 -0.100870 +v 0.491200 0.413447 -0.119387 +v 0.491200 0.413447 -0.119387 +v 0.492419 0.412931 -0.100870 +v 0.468904 0.432744 -0.098771 +v 0.467685 0.433260 -0.117288 +v 0.467685 0.433260 -0.117288 +v 0.468904 0.432744 -0.098771 +v 0.466292 0.463437 -0.097744 +v 0.465073 0.463952 -0.116261 +v 0.465073 0.463952 -0.116261 +v 0.466292 0.463437 -0.097744 +v 0.486113 0.487030 -0.098392 +v 0.484894 0.487546 -0.116909 +v 0.484894 0.487546 -0.116909 +v 0.486113 0.487030 -0.098392 +v 0.516756 0.489703 -0.100335 +v 0.515537 0.490218 -0.118852 +v 0.540272 0.469890 -0.102434 +v 0.516756 0.489703 -0.100335 +v 0.486113 0.487030 -0.098392 +v 0.466292 0.463437 -0.097744 +v 0.468904 0.432744 -0.098771 +v 0.492419 0.412931 -0.100870 +v 0.523063 0.415604 -0.102813 +v 0.542883 0.439197 -0.103461 +v 0.515537 0.490218 -0.118852 +v 0.539052 0.470406 -0.120951 +v 0.541664 0.439713 -0.121978 +v 0.521844 0.416120 -0.121330 +v 0.491200 0.413447 -0.119387 +v 0.467685 0.433260 -0.117288 +v 0.465073 0.463952 -0.116261 +v 0.484894 0.487546 -0.116909 +vt 0.945149 0.901343 +vt 0.946522 0.901343 +vt 0.946522 0.899064 +vt 0.945149 0.899064 +vt 0.945149 0.899064 +vt 0.946522 0.899064 +vt 0.946522 0.897452 +vt 0.945149 0.897452 +vt 0.142216 0.052958 +vt 0.140843 0.052958 +vt 0.140843 0.054570 +vt 0.142216 0.054570 +vt 0.142216 0.054570 +vt 0.140843 0.054570 +vt 0.140843 0.056849 +vt 0.142216 0.056849 +vt 0.142216 0.056849 +vt 0.140843 0.056849 +vt 0.140843 0.058461 +vt 0.142216 0.058461 +vt 0.140843 0.075298 +vt 0.142216 0.075298 +vt 0.142216 0.073686 +vt 0.140843 0.073686 +vt 0.140843 0.073686 +vt 0.142216 0.073686 +vt 0.142216 0.071407 +vt 0.140843 0.071407 +vt 0.140843 0.071407 +vt 0.142216 0.071407 +vt 0.142216 0.069795 +vt 0.140843 0.069795 +vt 0.703501 0.602401 +vt 0.707393 0.604012 +vt 0.705781 0.602401 +vt 0.701889 0.604012 +vt 0.707393 0.606291 +vt 0.701889 0.606291 +vt 0.705781 0.607903 +vt 0.703501 0.607903 +vt 0.728236 0.602401 +vt 0.729848 0.606291 +vt 0.729848 0.604012 +vt 0.725956 0.602401 +vt 0.728236 0.607903 +vt 0.725956 0.607903 +vt 0.724344 0.604012 +vt 0.724344 0.606291 +vn 0.6431 0.7655 -0.0210 +vn 0.9942 0.0867 -0.0630 +vn 0.7630 -0.6428 -0.0681 +vn 0.0848 -0.9958 -0.0333 +vn -0.6431 -0.7655 0.0210 +vn -0.9942 -0.0867 0.0630 +vn -0.7630 0.6428 0.0681 +vn -0.0847 0.9958 0.0333 +vn 0.0657 -0.0278 0.9975 +vn -0.0657 0.0278 -0.9975 +usemtl Scene_-_Root +s off +f 31818/31818/22675 31819/31819/22675 31820/31820/22675 +f 31818/31818/22675 31820/31820/22675 31821/31821/22675 +f 31822/31822/22676 31823/31823/22676 31824/31824/22676 +f 31822/31822/22676 31824/31824/22676 31825/31825/22676 +f 31826/31826/22677 31827/31827/22677 31828/31828/22677 +f 31826/31826/22677 31828/31828/22677 31829/31829/22677 +f 31830/31830/22678 31831/31831/22678 31832/31832/22678 +f 31830/31830/22678 31832/31832/22678 31833/31833/22678 +f 31834/31834/22679 31835/31835/22679 31836/31836/22679 +f 31834/31834/22679 31836/31836/22679 31837/31837/22679 +f 31838/31838/22680 31839/31839/22680 31840/31840/22680 +f 31838/31838/22680 31840/31840/22680 31841/31841/22680 +f 31842/31842/22681 31843/31843/22681 31844/31844/22681 +f 31842/31842/22681 31844/31844/22681 31845/31845/22681 +f 31846/31846/22682 31847/31847/22682 31848/31848/22682 +f 31846/31846/22682 31848/31848/22682 31849/31849/22682 +f 31854/31850/22683 31852/31851/22683 31853/31852/22683 +f 31852/31851/22683 31854/31850/22683 31855/31853/22683 +f 31852/31851/22683 31855/31853/22683 31851/31854/22683 +f 31851/31854/22683 31855/31853/22683 31856/31855/22683 +f 31851/31854/22683 31856/31855/22683 31850/31856/22683 +f 31850/31856/22683 31856/31855/22683 31857/31857/22683 +f 31865/31858/22684 31863/31859/22684 31864/31860/22684 +f 31863/31859/22684 31865/31858/22684 31858/31861/22684 +f 31863/31859/22684 31858/31861/22684 31862/31862/22684 +f 31862/31862/22684 31858/31861/22684 31861/31863/22684 +f 31861/31863/22684 31858/31861/22684 31859/31864/22684 +f 31861/31863/22684 31859/31864/22684 31860/31865/22684 +o Cylinder.054__0 +v 0.543670 0.182279 -0.133610 +v 0.543667 0.181827 -0.115051 +v 0.527230 0.155763 -0.115689 +v 0.527232 0.156215 -0.134248 +v 0.527232 0.156215 -0.134248 +v 0.527230 0.155763 -0.115689 +v 0.497171 0.148953 -0.115860 +v 0.497174 0.149405 -0.134418 +v 0.497174 0.149405 -0.134418 +v 0.497171 0.148953 -0.115860 +v 0.471099 0.165385 -0.115463 +v 0.471102 0.165838 -0.134022 +v 0.471102 0.165838 -0.134022 +v 0.471099 0.165385 -0.115463 +v 0.464287 0.195435 -0.114733 +v 0.464289 0.195887 -0.133291 +v 0.464289 0.195887 -0.133291 +v 0.464287 0.195435 -0.114733 +v 0.480724 0.221499 -0.114095 +v 0.480727 0.221951 -0.132654 +v 0.480727 0.221951 -0.132654 +v 0.480724 0.221499 -0.114095 +v 0.510782 0.228310 -0.113924 +v 0.510785 0.228762 -0.132483 +v 0.510785 0.228762 -0.132483 +v 0.510782 0.228310 -0.113924 +v 0.536854 0.211877 -0.114320 +v 0.536857 0.212329 -0.132879 +v 0.536857 0.212329 -0.132879 +v 0.536854 0.211877 -0.114320 +v 0.543667 0.181827 -0.115051 +v 0.543670 0.182279 -0.133610 +v 0.527230 0.155763 -0.115689 +v 0.543667 0.181827 -0.115051 +v 0.536854 0.211877 -0.114320 +v 0.510782 0.228310 -0.113924 +v 0.480724 0.221499 -0.114095 +v 0.464287 0.195435 -0.114733 +v 0.471099 0.165385 -0.115463 +v 0.497171 0.148953 -0.115860 +v 0.543670 0.182279 -0.133610 +v 0.527232 0.156215 -0.134248 +v 0.497174 0.149405 -0.134418 +v 0.471102 0.165838 -0.134022 +v 0.464289 0.195887 -0.133291 +v 0.480727 0.221951 -0.132654 +v 0.510785 0.228762 -0.132483 +v 0.536857 0.212329 -0.132879 +vt 0.953095 0.931740 +vt 0.954468 0.931740 +vt 0.954468 0.929461 +vt 0.953095 0.929461 +vt 0.953095 0.929461 +vt 0.954468 0.929461 +vt 0.954468 0.927850 +vt 0.953095 0.927850 +vt 0.661885 0.051657 +vt 0.660512 0.051657 +vt 0.660512 0.053269 +vt 0.661885 0.053269 +vt 0.661885 0.053269 +vt 0.660512 0.053269 +vt 0.660512 0.055548 +vt 0.661885 0.055548 +vt 0.661885 0.055548 +vt 0.660512 0.055548 +vt 0.660512 0.057159 +vt 0.661885 0.057159 +vt 0.214006 0.059707 +vt 0.215379 0.059707 +vt 0.215379 0.058095 +vt 0.214006 0.058095 +vt 0.214006 0.058095 +vt 0.215379 0.058095 +vt 0.215379 0.055816 +vt 0.214006 0.055816 +vt 0.214006 0.055816 +vt 0.215379 0.055816 +vt 0.215379 0.054205 +vt 0.214006 0.054205 +vt 0.621469 0.772877 +vt 0.625360 0.774489 +vt 0.623748 0.772877 +vt 0.619857 0.774489 +vt 0.625360 0.776768 +vt 0.619857 0.776768 +vt 0.623748 0.778379 +vt 0.621469 0.778379 +vt 0.731305 0.558987 +vt 0.732917 0.562877 +vt 0.732917 0.560598 +vt 0.729026 0.558987 +vt 0.731305 0.564489 +vt 0.729026 0.564489 +vt 0.727414 0.560598 +vt 0.727414 0.562877 +vn 0.8459 -0.5332 -0.0129 +vn 0.2210 -0.9750 -0.0237 +vn -0.5333 -0.8457 -0.0207 +vn -0.9753 -0.2210 -0.0055 +vn -0.8459 0.5332 0.0129 +vn -0.2210 0.9750 0.0237 +vn 0.5333 0.8457 0.0207 +vn 0.9753 0.2210 0.0055 +vn -0.0002 -0.0244 0.9997 +vn -0.0002 -0.0243 0.9997 +vn 0.0002 0.0244 -0.9997 +vn 0.0002 0.0243 -0.9997 +usemtl Scene_-_Root +s off +f 31866/31866/22685 31867/31867/22685 31868/31868/22685 +f 31866/31866/22685 31868/31868/22685 31869/31869/22685 +f 31870/31870/22686 31871/31871/22686 31872/31872/22686 +f 31870/31870/22686 31872/31872/22686 31873/31873/22686 +f 31874/31874/22687 31875/31875/22687 31876/31876/22687 +f 31874/31874/22687 31876/31876/22687 31877/31877/22687 +f 31878/31878/22688 31879/31879/22688 31880/31880/22688 +f 31878/31878/22688 31880/31880/22688 31881/31881/22688 +f 31882/31882/22689 31883/31883/22689 31884/31884/22689 +f 31882/31882/22689 31884/31884/22689 31885/31885/22689 +f 31886/31886/22690 31887/31887/22690 31888/31888/22690 +f 31886/31886/22690 31888/31888/22690 31889/31889/22690 +f 31890/31890/22691 31891/31891/22691 31892/31892/22691 +f 31890/31890/22691 31892/31892/22691 31893/31893/22691 +f 31894/31894/22692 31895/31895/22692 31896/31896/22692 +f 31894/31894/22692 31896/31896/22692 31897/31897/22692 +f 31902/31898/22693 31900/31899/22693 31901/31900/22693 +f 31900/31899/22693 31902/31898/22693 31903/31901/22693 +f 31900/31899/22693 31903/31901/22693 31899/31902/22693 +f 31899/31902/22693 31903/31901/22693 31904/31903/22693 +f 31899/31902/22693 31904/31903/22693 31898/31904/22693 +f 31898/31904/22694 31904/31903/22694 31905/31905/22694 +f 31913/31906/22695 31911/31907/22695 31912/31908/22695 +f 31911/31907/22695 31913/31906/22695 31906/31909/22695 +f 31911/31907/22695 31906/31909/22695 31910/31910/22695 +f 31910/31910/22695 31906/31909/22695 31909/31911/22695 +f 31909/31911/22695 31906/31909/22695 31907/31912/22695 +f 31909/31911/22696 31907/31912/22696 31908/31913/22696 +o BezierCurve.003__0 +v -1.499045 -1.097320 -0.698554 +v -1.509935 -0.986131 -0.698665 +v -1.490966 -0.984707 -0.703761 +v -1.480157 -1.095066 -0.703650 +v -1.512872 -1.098972 -0.684629 +v -1.523823 -0.987156 -0.684740 +v -1.517934 -1.099580 -0.665607 +v -1.528910 -0.987508 -0.665719 +v -1.512872 -1.098980 -0.646585 +v -1.523831 -0.987092 -0.646696 +v -1.528910 -0.987508 -0.665719 +v -1.517934 -1.099580 -0.665607 +v -1.499045 -1.097334 -0.632659 +v -1.509948 -0.986021 -0.632770 +v -1.480157 -1.095082 -0.627562 +v -1.490980 -0.984581 -0.627672 +v -1.461268 -1.092828 -0.632658 +v -1.472011 -0.983158 -0.632768 +v -1.490980 -0.984581 -0.627672 +v -1.480157 -1.095082 -0.627562 +v -1.447441 -1.091176 -0.646583 +v -1.458122 -0.982133 -0.646692 +v -1.442380 -1.090568 -0.665605 +v -1.453037 -0.981781 -0.665714 +v -1.447441 -1.091168 -0.684628 +v -1.458116 -0.982197 -0.684737 +v -1.453037 -0.981781 -0.665714 +v -1.442380 -1.090568 -0.665605 +v -1.461268 -1.092814 -0.698553 +v -1.471999 -0.983267 -0.698663 +v -1.480157 -1.095066 -0.703650 +v -1.490966 -0.984707 -0.703761 +v -1.515473 -0.881802 -0.698910 +v -1.496457 -0.881250 -0.704005 +v -1.529394 -0.882185 -0.684988 +v -1.534493 -0.882296 -0.665966 +v -1.529402 -0.882105 -0.646943 +v -1.534493 -0.882296 -0.665966 +v -1.515486 -0.881665 -0.633016 +v -1.496473 -0.881092 -0.627916 +v -1.477458 -0.880541 -0.633010 +v -1.496473 -0.881092 -0.627916 +v -1.463536 -0.880158 -0.646934 +v -1.458438 -0.880046 -0.665955 +v -1.463528 -0.880237 -0.684978 +v -1.458438 -0.880046 -0.665955 +v -1.477444 -0.880677 -0.698905 +v -1.496457 -0.881250 -0.704005 +v -1.516072 -0.783479 -0.699087 +v -1.497051 -0.783823 -0.704181 +v -1.529997 -0.783223 -0.685165 +v -1.535097 -0.783124 -0.666144 +v -1.530004 -0.783208 -0.647120 +v -1.535097 -0.783124 -0.666144 +v -1.516084 -0.783453 -0.633193 +v -1.497066 -0.783794 -0.628092 +v -1.478046 -0.784139 -0.633185 +v -1.497066 -0.783794 -0.628092 +v -1.464120 -0.784395 -0.647107 +v -1.459020 -0.784494 -0.666129 +v -1.464113 -0.784410 -0.685152 +v -1.459020 -0.784494 -0.666129 +v -1.478033 -0.784164 -0.699080 +v -1.497051 -0.783823 -0.704181 +v -1.512148 -0.690333 -0.698991 +v -1.493165 -0.691571 -0.704086 +v -1.526047 -0.689464 -0.685067 +v -1.531141 -0.689198 -0.666046 +v -1.526061 -0.689606 -0.647023 +v -1.531141 -0.689198 -0.666046 +v -1.512172 -0.690578 -0.633096 +v -1.493193 -0.691854 -0.627997 +v -1.474211 -0.693092 -0.633092 +v -1.493193 -0.691854 -0.627997 +v -1.460311 -0.693961 -0.647015 +v -1.455218 -0.694227 -0.666036 +v -1.460296 -0.693819 -0.685059 +v -1.455218 -0.694227 -0.666036 +v -1.474186 -0.692847 -0.698986 +v -1.493165 -0.691571 -0.704086 +v -1.504120 -0.601539 -0.698415 +v -1.485215 -0.603637 -0.703515 +v -1.517970 -0.600111 -0.684487 +v -1.523052 -0.599735 -0.665465 +v -1.518007 -0.600511 -0.646445 +v -1.523052 -0.599735 -0.665465 +v -1.504185 -0.602232 -0.632523 +v -1.485289 -0.604436 -0.627431 +v -1.466384 -0.606534 -0.632531 +v -1.485289 -0.604436 -0.627431 +v -1.452534 -0.607962 -0.646459 +v -1.447451 -0.608338 -0.665481 +v -1.452497 -0.607562 -0.684501 +v -1.447451 -0.608338 -0.665481 +v -1.466319 -0.605841 -0.698423 +v -1.485215 -0.603637 -0.703515 +v -1.492414 -0.516285 -0.697153 +v -1.473617 -0.519173 -0.702266 +v -1.506199 -0.514375 -0.683218 +v -1.511275 -0.513955 -0.664196 +v -1.506285 -0.515137 -0.645181 +v -1.511275 -0.513955 -0.664196 +v -1.492564 -0.517606 -0.631272 +v -1.473790 -0.520698 -0.626193 +v -1.454993 -0.523585 -0.631306 +v -1.473790 -0.520698 -0.626193 +v -1.441209 -0.525496 -0.645241 +v -1.436132 -0.525915 -0.664264 +v -1.441122 -0.524733 -0.683278 +v -1.436132 -0.525915 -0.664264 +v -1.454843 -0.522265 -0.697188 +v -1.473617 -0.519173 -0.702266 +v -1.477463 -0.433760 -0.695001 +v -1.458789 -0.437338 -0.700133 +v -1.491178 -0.431470 -0.681056 +v -1.496260 -0.431080 -0.662034 +v -1.491348 -0.432696 -0.643032 +v -1.496260 -0.431080 -0.662034 +v -1.477757 -0.435883 -0.629141 +v -1.459129 -0.439790 -0.624084 +v -1.440456 -0.443367 -0.629215 +v -1.459129 -0.439790 -0.624084 +v -1.426740 -0.445657 -0.643161 +v -1.421658 -0.446047 -0.662183 +v -1.426570 -0.444432 -0.681185 +v -1.421658 -0.446047 -0.662183 +v -1.440161 -0.441243 -0.695076 +v -1.458789 -0.437338 -0.700133 +v -1.459704 -0.353155 -0.691754 +v -1.441154 -0.357295 -0.696909 +v -1.473362 -0.350602 -0.677799 +v -1.478468 -0.350320 -0.658781 +v -1.473653 -0.352383 -0.639797 +v -1.478468 -0.350320 -0.658781 +v -1.460209 -0.356240 -0.625933 +v -1.441736 -0.360857 -0.620906 +v -1.423186 -0.364996 -0.626060 +v -1.441736 -0.360857 -0.620906 +v -1.409528 -0.367549 -0.640016 +v -1.404422 -0.367832 -0.659034 +v -1.409236 -0.365769 -0.678018 +v -1.404422 -0.367832 -0.659034 +v -1.422681 -0.361912 -0.691881 +v -1.441154 -0.357295 -0.696909 +v -1.439583 -0.273660 -0.687211 +v -1.421136 -0.278215 -0.692389 +v -1.453206 -0.270971 -0.673247 +v -1.458358 -0.270870 -0.654239 +v -1.453656 -0.273383 -0.635282 +v -1.458358 -0.270870 -0.654239 +v -1.440362 -0.277837 -0.621453 +v -1.422036 -0.283038 -0.616458 +v -1.403590 -0.287594 -0.621637 +v -1.422036 -0.283038 -0.616458 +v -1.389966 -0.290282 -0.635601 +v -1.384815 -0.290383 -0.654608 +v -1.389516 -0.287871 -0.673566 +v -1.384815 -0.290383 -0.654608 +v -1.402811 -0.283417 -0.687395 +v -1.421136 -0.278215 -0.692389 +v -1.417543 -0.194456 -0.681170 +v -1.399169 -0.199271 -0.686368 +v -1.431165 -0.191761 -0.667206 +v -1.436386 -0.191910 -0.648217 +v -1.431805 -0.194861 -0.629293 +v -1.436386 -0.191910 -0.648217 +v -1.418652 -0.199825 -0.615503 +v -1.400448 -0.205471 -0.610543 +v -1.382074 -0.210286 -0.615741 +v -1.400448 -0.205471 -0.610543 +v -1.368452 -0.212981 -0.629706 +v -1.363232 -0.212832 -0.648694 +v -1.367812 -0.209881 -0.667618 +v -1.363232 -0.212832 -0.648694 +v -1.380966 -0.204917 -0.681408 +v -1.399169 -0.199271 -0.686368 +v -1.394030 -0.114718 -0.673434 +v -1.375686 -0.119637 -0.678643 +v -1.407687 -0.112142 -0.659482 +v -1.412998 -0.112599 -0.640523 +v -1.408539 -0.115968 -0.621639 +v -1.412998 -0.112599 -0.640523 +v -1.395506 -0.121345 -0.607890 +v -1.377391 -0.127289 -0.602959 +v -1.359047 -0.132208 -0.608167 +v -1.377391 -0.127289 -0.602959 +v -1.345390 -0.134784 -0.622120 +v -1.340079 -0.134327 -0.641078 +v -1.344537 -0.130959 -0.659962 +v -1.340079 -0.134327 -0.641078 +v -1.357571 -0.125582 -0.673711 +v -1.375686 -0.119637 -0.678643 +v -1.369978 -0.035289 -0.663983 +v -1.351609 -0.040123 -0.669183 +v -1.383584 -0.032536 -0.650013 +v -1.388780 -0.032602 -0.631018 +v -1.384175 -0.035470 -0.612087 +v -1.388780 -0.032602 -0.631018 +v -1.371003 -0.040371 -0.598292 +v -1.352792 -0.045992 -0.593330 +v -1.334424 -0.050826 -0.598530 +v -1.352792 -0.045992 -0.593330 +v -1.320818 -0.053579 -0.612500 +v -1.315622 -0.053513 -0.631495 +v -1.320227 -0.050645 -0.650426 +v -1.315622 -0.053513 -0.631495 +v -1.333399 -0.045744 -0.664221 +v -1.351609 -0.040123 -0.669183 +v -1.351678 0.032387 -0.660877 +v -1.333252 0.027770 -0.666070 +v -1.365103 0.035818 -0.646882 +v -1.369926 0.037145 -0.627835 +v -1.364857 0.036013 -0.608839 +v -1.369926 0.037145 -0.627835 +v -1.351254 0.032724 -0.594984 +v -1.332761 0.028160 -0.589983 +v -1.314334 0.023543 -0.595176 +v -1.332761 0.028160 -0.589983 +v -1.300910 0.020112 -0.609170 +v -1.296087 0.018785 -0.628217 +v -1.301156 0.019917 -0.647213 +v -1.296087 0.018785 -0.628217 +v -1.314759 0.023206 -0.661068 +v -1.333252 0.027770 -0.666070 +v -1.333076 0.114327 -0.665702 +v -1.314600 0.109920 -0.670904 +v -1.346358 0.118372 -0.651736 +v -1.350887 0.120971 -0.632747 +v -1.345450 0.121427 -0.613825 +v -1.350887 0.120971 -0.632747 +v -1.331505 0.119618 -0.600039 +v -1.312786 0.116029 -0.595082 +v -1.294311 0.111621 -0.600284 +v -1.312786 0.116029 -0.595082 +v -1.281029 0.107577 -0.614250 +v -1.276500 0.104978 -0.633239 +v -1.281936 0.104522 -0.652161 +v -1.276500 0.104978 -0.633239 +v -1.295882 0.106331 -0.665948 +v -1.314600 0.109920 -0.670904 +v -1.314221 0.207839 -0.676277 +v -1.295712 0.203597 -0.681497 +v -1.327448 0.212156 -0.662340 +v -1.331847 0.215393 -0.643419 +v -1.326240 0.216681 -0.624584 +v -1.331847 0.215393 -0.643419 +v -1.312130 0.215677 -0.610883 +v -1.293298 0.212648 -0.605986 +v -1.274788 0.208407 -0.611206 +v -1.293298 0.212648 -0.605986 +v -1.261562 0.204089 -0.625144 +v -1.257163 0.200852 -0.644064 +v -1.262769 0.199564 -0.662899 +v -1.257163 0.200852 -0.644064 +v -1.276880 0.200568 -0.676600 +v -1.295712 0.203597 -0.681497 +v -1.295540 0.308536 -0.690292 +v -1.277002 0.304447 -0.695532 +v -1.308757 0.312900 -0.676361 +v -1.313113 0.316369 -0.657471 +v -1.307440 0.318015 -0.638685 +v -1.313113 0.316369 -0.657471 +v -1.293257 0.317396 -0.625036 +v -1.274367 0.314678 -0.620180 +v -1.255829 0.310589 -0.625420 +v -1.274367 0.314678 -0.620180 +v -1.242612 0.306225 -0.639352 +v -1.238256 0.302756 -0.658241 +v -1.243929 0.301110 -0.677027 +v -1.238256 0.302756 -0.658241 +v -1.258111 0.301729 -0.690677 +v -1.277002 0.304447 -0.695532 +v -1.277341 0.412366 -0.705350 +v -1.258775 0.408436 -0.710613 +v -1.290584 0.416585 -0.691399 +v -1.294955 0.419963 -0.672496 +v -1.289285 0.421595 -0.653708 +v -1.294955 0.419963 -0.672496 +v -1.275091 0.421044 -0.640068 +v -1.256177 0.418456 -0.635231 +v -1.237611 0.414527 -0.640494 +v -1.256177 0.418456 -0.635231 +v -1.224368 0.410307 -0.654445 +v -1.219996 0.406929 -0.673347 +v -1.225667 0.405298 -0.692136 +v -1.219996 0.406929 -0.673347 +v -1.239861 0.405849 -0.705776 +v -1.258775 0.408436 -0.710613 +v -1.259881 0.515470 -0.719031 +v -1.241284 0.511726 -0.724318 +v -1.273184 0.519336 -0.705035 +v -1.277628 0.522289 -0.686078 +v -1.272023 0.523537 -0.667241 +v -1.277628 0.522289 -0.686078 +v -1.257870 0.522746 -0.653570 +v -1.238961 0.520128 -0.648729 +v -1.220364 0.516384 -0.654016 +v -1.238961 0.520128 -0.648729 +v -1.207060 0.512517 -0.668012 +v -1.202616 0.509564 -0.686969 +v -1.208222 0.508317 -0.705806 +v -1.202616 0.509564 -0.686969 +v -1.222375 0.509108 -0.719476 +v -1.241284 0.511726 -0.724318 +v -1.243378 0.614173 -0.728890 +v -1.224740 0.610670 -0.734198 +v -1.256788 0.617404 -0.714834 +v -1.261377 0.619497 -0.695797 +v -1.255915 0.619890 -0.676881 +v -1.261377 0.619497 -0.695797 +v -1.241866 0.618479 -0.663153 +v -1.222995 0.615643 -0.658292 +v -1.204357 0.612139 -0.663600 +v -1.222995 0.615643 -0.658292 +v -1.190947 0.608909 -0.677656 +v -1.186358 0.606816 -0.696692 +v -1.191819 0.606422 -0.715609 +v -1.186358 0.606816 -0.696692 +v -1.205868 0.607833 -0.729337 +v -1.224740 0.610670 -0.734198 +v -1.227989 0.705096 -0.732391 +v -1.209292 0.701940 -0.737709 +v -1.241586 0.707231 -0.718307 +v -1.246439 0.707774 -0.699228 +v -1.241249 0.706579 -0.680269 +v -1.246439 0.707774 -0.699228 +v -1.227405 0.703966 -0.666509 +v -1.208617 0.700635 -0.661634 +v -1.189920 0.697479 -0.666952 +v -1.208617 0.700635 -0.661634 +v -1.176323 0.695344 -0.681037 +v -1.171470 0.694801 -0.700115 +v -1.176660 0.695996 -0.719074 +v -1.171470 0.694801 -0.700115 +v -1.190504 0.698609 -0.732835 +v -1.209292 0.701940 -0.737709 +v -1.213730 0.785454 -0.726622 +v -1.194932 0.782855 -0.731887 +v -1.227677 0.785646 -0.712719 +v -1.233036 0.783381 -0.693905 +v -1.228371 0.779264 -0.675220 +v -1.233036 0.783381 -0.693905 +v -1.214933 0.774400 -0.661672 +v -1.196321 0.770091 -0.656889 +v -1.177524 0.767491 -0.662155 +v -1.196321 0.770091 -0.656889 +v -1.163577 0.767299 -0.676057 +v -1.158218 0.769564 -0.694871 +v -1.162883 0.773681 -0.713556 +v -1.158218 0.769564 -0.694871 +v -1.176321 0.778545 -0.727105 +v -1.194932 0.782855 -0.731887 +v -1.200315 0.853289 -0.707063 +v -1.181327 0.851630 -0.712015 +v -1.214966 0.850012 -0.694318 +v -1.221354 0.842675 -0.677195 +v -1.217767 0.833246 -0.660282 +v -1.221354 0.842675 -0.677195 +v -1.205167 0.824250 -0.648111 +v -1.186929 0.818098 -0.643943 +v -1.205167 0.824250 -0.648111 +v -1.214933 0.774400 -0.661672 +v -1.167941 0.816439 -0.648896 +v -1.153290 0.819716 -0.661640 +v -1.146903 0.827053 -0.678763 +v -1.150489 0.836482 -0.695676 +v -1.146903 0.827053 -0.678763 +v -1.163090 0.845478 -0.707847 +v -1.163090 0.845478 -0.707847 +v -1.176321 0.778545 -0.727105 +v -1.187614 0.903596 -0.665941 +v -1.168314 0.903134 -0.669827 +v -1.203454 0.895757 -0.657255 +v -1.211591 0.881716 -0.646097 +v -1.203454 0.895757 -0.657255 +v -1.214966 0.850012 -0.694318 +v -1.209843 0.865237 -0.635457 +v -1.198679 0.850735 -0.628186 +v -1.181090 0.842095 -0.626232 +v -1.198679 0.850735 -0.628186 +v -1.161790 0.841633 -0.630118 +v -1.145949 0.849473 -0.638804 +v -1.137813 0.863513 -0.649962 +v -1.145949 0.849473 -0.638804 +v -1.153290 0.819716 -0.661640 +v -1.139561 0.879992 -0.660602 +v -1.150725 0.894494 -0.667873 +v -1.150725 0.894494 -0.667873 +v -1.187614 0.903596 -0.665941 +v -1.177763 0.922470 -0.604317 +v -1.158256 0.922431 -0.607019 +v -1.168314 0.903134 -0.669827 +v -1.203454 0.895757 -0.657255 +v -1.194545 0.912704 -0.601027 +v -1.204104 0.895749 -0.598032 +v -1.194545 0.912704 -0.601027 +v -1.203880 0.876149 -0.596132 +v -1.193932 0.859155 -0.595837 +v -1.181090 0.842095 -0.626232 +v -1.176927 0.849321 -0.597228 +v -1.193932 0.859155 -0.595837 +v -1.198679 0.850735 -0.628186 +v -1.161790 0.841633 -0.630118 +v -1.157420 0.849283 -0.599930 +v -1.145949 0.849473 -0.638804 +v -1.140638 0.859049 -0.603220 +v -1.131079 0.876003 -0.606216 +v -1.140638 0.859049 -0.603220 +v -1.131303 0.895604 -0.608115 +v -1.141250 0.912597 -0.608409 +v -1.141250 0.912597 -0.608409 +v -1.150725 0.894494 -0.667873 +v -1.170669 0.918025 -0.547859 +v -1.151149 0.917981 -0.550468 +v -1.187862 0.908426 -0.547599 +v -1.198123 0.891756 -0.549756 +v -1.187862 0.908426 -0.547599 +v -1.198700 0.872481 -0.553753 +v -1.189441 0.855766 -0.558519 +v -1.198700 0.872481 -0.553753 +v -1.203880 0.876149 -0.596132 +v -1.172825 0.846090 -0.562776 +v -1.153306 0.846046 -0.565385 +v -1.136112 0.855645 -0.565645 +v -1.125852 0.872316 -0.563488 +v -1.136112 0.855645 -0.565645 +v -1.125274 0.891590 -0.559491 +v -1.134534 0.908305 -0.554725 +v -1.125274 0.891590 -0.559491 +v -1.131303 0.895604 -0.608115 +v -1.164366 0.902246 -0.503264 +v -1.144850 0.902215 -0.505905 +v -1.181931 0.893708 -0.505788 +v -1.164366 0.902246 -0.503264 +v -1.170669 0.918025 -0.547859 +v -1.192841 0.878887 -0.512799 +v -1.194170 0.861755 -0.522419 +v -1.185565 0.846903 -0.532071 +v -1.194170 0.861755 -0.522419 +v -1.169328 0.838309 -0.539169 +v -1.149813 0.838277 -0.541809 +v -1.132247 0.846816 -0.539286 +v -1.149813 0.838277 -0.541809 +v -1.153306 0.846046 -0.565385 +v -1.121338 0.861636 -0.532275 +v -1.120008 0.878768 -0.522654 +v -1.128614 0.893621 -0.513002 +v -1.120008 0.878768 -0.522654 +v -1.160255 0.872748 -0.468663 +v -1.140679 0.872239 -0.470744 +v -1.178178 0.867008 -0.474464 +v -1.160255 0.872748 -0.468663 +v -1.189645 0.856557 -0.486593 +v -1.191584 0.844195 -0.501799 +v -1.183474 0.833234 -0.516009 +v -1.191584 0.844195 -0.501799 +v -1.167490 0.826611 -0.525415 +v -1.147913 0.826102 -0.527496 +v -1.129991 0.831842 -0.521695 +v -1.147913 0.826102 -0.527496 +v -1.118524 0.842293 -0.509567 +v -1.116585 0.854656 -0.494360 +v -1.124694 0.865616 -0.480150 +v -1.116585 0.854656 -0.494360 +v -1.160255 0.872748 -0.468663 +v -1.160354 0.832207 -0.446559 +v -1.140781 0.830582 -0.447996 +v -1.140679 0.872239 -0.470744 +v -1.178268 0.830132 -0.454473 +v -1.160354 0.832207 -0.446559 +v -1.189720 0.824911 -0.469620 +v -1.191644 0.817945 -0.487939 +v -1.183474 0.833234 -0.516009 +v -1.183524 0.811100 -0.504523 +v -1.191644 0.817945 -0.487939 +v -1.191584 0.844195 -0.501799 +v -1.167490 0.826611 -0.525415 +v -1.167535 0.806209 -0.514927 +v -1.147913 0.826102 -0.527496 +v -1.147962 0.804584 -0.516365 +v -1.130049 0.806659 -0.508450 +v -1.147962 0.804584 -0.516365 +v -1.118596 0.811879 -0.493304 +v -1.116672 0.818846 -0.474985 +v -1.124694 0.865616 -0.480150 +v -1.124792 0.825691 -0.458401 +v -1.116672 0.818846 -0.474985 +v -1.116585 0.854656 -0.494360 +v -1.165304 0.783664 -0.434249 +v -1.145860 0.780732 -0.435319 +v -1.182925 0.784554 -0.442999 +v -1.165304 0.783664 -0.434249 +v -1.194000 0.783164 -0.459224 +v -1.195562 0.779865 -0.478576 +v -1.187192 0.775543 -0.495870 +v -1.195562 0.779865 -0.478576 +v -1.171134 0.771354 -0.506472 +v -1.151689 0.768422 -0.507542 +v -1.134069 0.767532 -0.498792 +v -1.151689 0.768422 -0.507542 +v -1.122994 0.768922 -0.482568 +v -1.121433 0.772221 -0.463216 +v -1.129802 0.776543 -0.445921 +v -1.121433 0.772221 -0.463216 +v -1.175606 0.725940 -0.427556 +v -1.156367 0.721835 -0.428469 +v -1.192884 0.728786 -0.436567 +v -1.175606 0.725940 -0.427556 +v -1.203572 0.729609 -0.453088 +v -1.204805 0.728189 -0.472691 +v -1.196253 0.724906 -0.490124 +v -1.204805 0.728189 -0.472691 +v -1.180208 0.720641 -0.500716 +v -1.160969 0.716536 -0.501629 +v -1.143691 0.713691 -0.492618 +v -1.160969 0.716536 -0.501629 +v -1.133003 0.712868 -0.476098 +v -1.131770 0.714288 -0.456494 +v -1.140322 0.717570 -0.439061 +v -1.131770 0.714288 -0.456494 +v -1.192261 0.656599 -0.423664 +v -1.173256 0.651506 -0.424511 +v -1.209244 0.660687 -0.432758 +v -1.192261 0.656599 -0.423664 +v -1.219654 0.662676 -0.449356 +v -1.220703 0.662032 -0.469011 +v -1.212109 0.658928 -0.486456 +v -1.220703 0.662032 -0.469011 +v -1.196175 0.654196 -0.497017 +v -1.177171 0.649103 -0.497864 +v -1.160187 0.645015 -0.488771 +v -1.177171 0.649103 -0.497864 +v -1.149777 0.643026 -0.472173 +v -1.148728 0.643670 -0.452518 +v -1.157322 0.646774 -0.435073 +v -1.148728 0.643670 -0.452518 +v -1.216482 0.573606 -0.420527 +v -1.197718 0.567683 -0.421339 +v -1.233232 0.578495 -0.429656 +v -1.216482 0.573606 -0.420527 +v -1.243482 0.581041 -0.446278 +v -1.244483 0.580563 -0.465940 +v -1.235968 0.577187 -0.483374 +v -1.244483 0.580563 -0.465940 +v -1.220217 0.571819 -0.493907 +v -1.201453 0.565897 -0.494718 +v -1.184703 0.561007 -0.485590 +v -1.201453 0.565897 -0.494718 +v -1.174453 0.558461 -0.468967 +v -1.173453 0.558940 -0.449305 +v -1.181968 0.562315 -0.431872 +v -1.173453 0.558940 -0.449305 +v -1.249520 0.475333 -0.416315 +v -1.230991 0.468707 -0.417094 +v -1.266096 0.480747 -0.425468 +v -1.249520 0.475333 -0.416315 +v -1.276276 0.483498 -0.442099 +v -1.277334 0.482849 -0.461754 +v -1.268986 0.478974 -0.479164 +v -1.277334 0.482849 -0.461754 +v -1.253468 0.472911 -0.489665 +v -1.234940 0.466285 -0.490443 +v -1.218364 0.460871 -0.481291 +v -1.234940 0.466285 -0.490443 +v -1.208184 0.458120 -0.464659 +v -1.207126 0.458769 -0.445005 +v -1.215474 0.462644 -0.427595 +v -1.207126 0.458769 -0.445005 +v -1.292620 0.360378 -0.409242 +v -1.274317 0.353149 -0.409982 +v -1.309067 0.366138 -0.418417 +v -1.292620 0.360378 -0.409242 +v -1.319248 0.368886 -0.435048 +v -1.320437 0.367885 -0.454680 +v -1.312316 0.363403 -0.472052 +v -1.320437 0.367885 -0.454680 +v -1.297060 0.356641 -0.482509 +v -1.278757 0.349412 -0.483249 +v -1.262311 0.343652 -0.474074 +v -1.278757 0.349412 -0.483249 +v -1.252129 0.340904 -0.457443 +v -1.250939 0.341905 -0.437811 +v -1.259060 0.346387 -0.420439 +v -1.250939 0.341905 -0.437811 +v -1.347016 0.227455 -0.397527 +v -1.328925 0.219705 -0.398221 +v -1.363369 0.233443 -0.406723 +v -1.347016 0.227455 -0.397527 +v -1.373602 0.236065 -0.423343 +v -1.374974 0.234617 -0.442935 +v -1.367116 0.229489 -0.460249 +v -1.374974 0.234617 -0.442935 +v -1.352135 0.222053 -0.470646 +v -1.334044 0.214302 -0.471340 +v -1.317691 0.208314 -0.462145 +v -1.334044 0.214302 -0.471340 +v -1.307458 0.205693 -0.445525 +v -1.306086 0.207140 -0.425933 +v -1.313944 0.212269 -0.408618 +v -1.306086 0.207140 -0.425933 +v -1.414441 0.074174 -0.379246 +v -1.396547 0.065977 -0.379894 +v -1.430593 0.080618 -0.388486 +v -1.414441 0.074174 -0.379246 +v -1.440676 0.083582 -0.405141 +v -1.441987 0.082272 -0.424747 +v -1.434176 0.077039 -0.442050 +v -1.441987 0.082272 -0.424747 +v -1.419334 0.069285 -0.452415 +v -1.401440 0.061088 -0.453065 +v -1.385287 0.054644 -0.443824 +v -1.401440 0.061088 -0.453065 +v -1.375205 0.051680 -0.427169 +v -1.373893 0.052989 -0.407563 +v -1.381705 0.058223 -0.390260 +v -1.373893 0.052989 -0.407563 +v -1.491355 -0.089685 -0.367037 +v -1.473674 -0.098335 -0.367665 +v -1.506937 -0.082033 -0.376335 +v -1.491355 -0.089685 -0.367037 +v -1.516246 -0.077429 -0.393068 +v -1.516787 -0.077107 -0.412751 +v -1.508415 -0.081153 -0.430111 +v -1.516787 -0.077107 -0.412751 +v -1.493374 -0.088482 -0.440496 +v -1.475693 -0.097132 -0.441123 +v -1.460110 -0.104784 -0.431825 +v -1.475693 -0.097132 -0.441123 +v -1.450802 -0.109389 -0.415093 +v -1.450261 -0.109711 -0.395410 +v -1.458632 -0.105665 -0.378050 +v -1.450261 -0.109711 -0.395410 +v -1.556580 -0.217628 -0.377622 +v -1.539199 -0.226861 -0.378307 +v -1.571144 -0.207992 -0.386726 +v -1.556580 -0.217628 -0.377622 +v -1.578987 -0.200536 -0.403180 +v -1.578010 -0.197258 -0.422574 +v -1.568473 -0.199036 -0.439712 +v -1.578010 -0.197258 -0.422574 +v -1.552932 -0.205393 -0.450001 +v -1.535551 -0.214627 -0.450686 +v -1.520988 -0.224262 -0.441582 +v -1.535551 -0.214627 -0.450686 +v -1.513144 -0.231718 -0.425129 +v -1.514121 -0.234997 -0.405735 +v -1.523658 -0.233219 -0.388597 +v -1.514121 -0.234997 -0.405735 +v -1.610749 -0.312562 -0.407915 +v -1.593809 -0.322561 -0.408862 +v -1.623815 -0.300330 -0.416130 +v -1.610749 -0.312562 -0.407915 +v -1.629508 -0.289144 -0.431305 +v -1.626301 -0.282001 -0.449375 +v -1.615055 -0.280815 -0.465497 +v -1.626301 -0.282001 -0.449375 +v -1.598782 -0.285903 -0.475353 +v -1.581842 -0.295902 -0.476300 +v -1.568776 -0.308134 -0.468085 +v -1.581842 -0.295902 -0.476300 +v -1.563083 -0.319320 -0.452910 +v -1.566290 -0.326463 -0.434840 +v -1.577536 -0.327650 -0.418717 +v -1.566290 -0.326463 -0.434840 +v -1.654690 -0.377476 -0.455386 +v -1.638347 -0.388345 -0.456998 +v -1.665743 -0.362308 -0.461352 +v -1.654690 -0.377476 -0.455386 +v -1.668543 -0.346904 -0.473299 +v -1.662340 -0.335393 -0.488024 +v -1.648797 -0.330858 -0.501583 +v -1.662340 -0.335393 -0.488024 +v -1.631542 -0.334515 -0.510343 +v -1.615199 -0.345383 -0.511955 +v -1.604147 -0.360551 -0.505989 +v -1.615199 -0.345383 -0.511955 +v -1.601347 -0.375955 -0.494042 +v -1.607549 -0.387466 -0.479316 +v -1.621092 -0.392001 -0.465758 +v -1.607549 -0.387466 -0.479316 +v -1.654690 -0.377476 -0.455386 +v -1.688089 -0.413442 -0.516676 +v -1.672380 -0.424986 -0.519464 +v -1.638347 -0.388345 -0.456998 +v -1.697007 -0.395999 -0.518684 +v -1.688089 -0.413442 -0.516676 +v -1.696745 -0.377331 -0.524949 +v -1.687371 -0.362439 -0.533794 +v -1.648797 -0.330858 -0.501583 +v -1.671399 -0.355315 -0.542847 +v -1.687371 -0.362439 -0.533794 +v -1.662340 -0.335393 -0.488024 +v -1.631542 -0.334515 -0.510343 +v -1.653108 -0.357868 -0.549684 +v -1.615199 -0.345383 -0.511955 +v -1.637398 -0.369412 -0.552472 +v -1.628480 -0.386855 -0.550464 +v -1.637398 -0.369412 -0.552472 +v -1.628743 -0.405523 -0.544199 +v -1.638116 -0.420414 -0.535354 +v -1.621092 -0.392001 -0.465758 +v -1.654088 -0.427538 -0.526301 +v -1.638116 -0.420414 -0.535354 +v -1.607549 -0.387466 -0.479316 +v -1.709792 -0.421518 -0.585211 +v -1.694542 -0.433241 -0.589430 +v -1.717174 -0.403475 -0.582422 +v -1.709792 -0.421518 -0.585211 +v -1.714708 -0.383946 -0.581811 +v -1.703056 -0.368164 -0.583541 +v -1.685339 -0.360359 -0.587149 +v -1.703056 -0.368164 -0.583541 +v -1.666305 -0.362621 -0.591667 +v -1.651054 -0.374344 -0.595886 +v -1.643672 -0.392387 -0.598675 +v -1.651054 -0.374344 -0.595886 +v -1.646138 -0.411916 -0.599286 +v -1.657790 -0.427697 -0.597556 +v -1.675507 -0.435503 -0.593948 +v -1.657790 -0.427697 -0.597556 +v -1.719801 -0.405783 -0.653181 +v -1.704747 -0.417225 -0.658686 +v -1.726525 -0.388679 -0.646107 +v -1.719801 -0.405783 -0.653181 +v -1.723118 -0.370494 -0.639359 +v -1.710491 -0.356102 -0.634746 +v -1.692031 -0.349359 -0.633503 +v -1.710491 -0.356102 -0.634746 +v -1.672681 -0.352071 -0.635964 +v -1.657627 -0.363513 -0.641469 +v -1.650903 -0.380617 -0.648543 +v -1.657627 -0.363513 -0.641469 +v -1.654310 -0.398802 -0.655290 +v -1.666937 -0.413194 -0.659904 +v -1.685397 -0.419938 -0.661147 +v -1.666937 -0.413194 -0.659904 +v -1.719424 -0.371759 -0.715132 +v -1.704369 -0.382659 -0.721642 +v -1.726152 -0.356446 -0.704737 +v -1.719424 -0.371759 -0.715132 +v -1.722749 -0.340822 -0.693243 +v -1.710129 -0.329073 -0.683728 +v -1.691673 -0.324347 -0.678743 +v -1.710129 -0.329073 -0.683728 +v -1.672325 -0.327912 -0.679624 +v -1.657270 -0.338812 -0.686135 +v -1.650542 -0.354125 -0.696530 +v -1.657270 -0.338812 -0.686135 +v -1.653944 -0.369750 -0.708025 +v -1.666564 -0.381498 -0.717539 +v -1.685022 -0.386224 -0.722523 +v -1.666564 -0.381498 -0.717539 +v -1.709934 -0.323978 -0.767318 +v -1.694737 -0.334164 -0.774609 +v -1.726152 -0.356446 -0.704737 +v -1.717123 -0.310998 -0.754370 +v -1.709934 -0.323978 -0.767318 +v -1.719424 -0.371759 -0.715132 +v -1.714379 -0.298702 -0.739234 +v -1.717123 -0.310998 -0.754370 +v -1.702438 -0.290384 -0.725966 +v -1.691673 -0.324347 -0.678743 +v -1.684499 -0.288273 -0.718121 +v -1.665368 -0.292935 -0.717801 +v -1.684499 -0.288273 -0.718121 +v -1.657270 -0.338812 -0.686135 +v -1.650172 -0.303122 -0.725092 +v -1.665368 -0.292935 -0.717801 +v -1.672325 -0.327912 -0.679624 +v -1.650542 -0.354125 -0.696530 +v -1.642982 -0.316102 -0.738040 +v -1.645726 -0.328398 -0.753176 +v -1.642982 -0.316102 -0.738040 +v -1.657667 -0.336716 -0.766444 +v -1.685022 -0.386224 -0.722523 +v -1.675607 -0.338826 -0.774289 +v -1.675607 -0.338826 -0.774289 +v -1.692079 -0.265942 -0.805893 +v -1.676600 -0.275214 -0.813783 +v -1.694737 -0.334164 -0.774609 +v -1.700185 -0.255922 -0.791003 +v -1.698745 -0.247837 -0.773103 +v -1.700185 -0.255922 -0.791003 +v -1.688146 -0.243855 -0.756990 +v -1.671228 -0.245043 -0.746981 +v -1.652523 -0.251081 -0.745758 +v -1.671228 -0.245043 -0.746981 +v -1.684499 -0.288273 -0.718121 +v -1.637044 -0.260354 -0.753648 +v -1.628938 -0.270374 -0.768538 +v -1.630378 -0.278459 -0.786438 +v -1.628938 -0.270374 -0.768538 +v -1.640977 -0.282440 -0.802551 +v -1.657895 -0.281253 -0.812560 +v -1.657895 -0.281253 -0.812560 +v -1.675607 -0.338826 -0.774289 +v -1.666282 -0.200978 -0.826050 +v -1.650338 -0.209086 -0.834287 +v -1.675882 -0.194693 -0.810044 +v -1.676565 -0.191917 -0.790559 +v -1.675882 -0.194693 -0.810044 +v -1.668149 -0.193393 -0.772816 +v -1.652888 -0.198726 -0.761569 +v -1.634872 -0.206486 -0.759832 +v -1.652888 -0.198726 -0.761569 +v -1.618928 -0.214595 -0.768070 +v -1.609328 -0.220879 -0.784076 +v -1.608645 -0.223655 -0.803560 +v -1.609328 -0.220879 -0.784076 +v -1.617061 -0.222179 -0.821303 +v -1.632322 -0.216847 -0.832550 +v -1.632322 -0.216847 -0.832550 +v -1.634591 -0.136256 -0.822746 +v -1.618415 -0.143894 -0.830981 +v -1.645495 -0.132615 -0.806756 +v -1.648204 -0.133946 -0.787295 +v -1.645495 -0.132615 -0.806756 +v -1.641992 -0.139893 -0.769579 +v -1.628525 -0.148862 -0.758353 +v -1.611410 -0.158450 -0.756627 +v -1.628525 -0.148862 -0.758353 +v -1.595234 -0.166088 -0.764862 +v -1.584331 -0.169729 -0.780852 +v -1.581622 -0.168398 -0.800313 +v -1.584331 -0.169729 -0.780852 +v -1.587833 -0.162451 -0.818029 +v -1.601300 -0.153482 -0.829255 +v -1.601300 -0.153482 -0.829255 +v -1.597856 -0.075631 -0.808536 +v -1.582237 -0.084194 -0.816934 +v -1.608672 -0.071845 -0.792520 +v -1.611788 -0.073851 -0.773179 +v -1.608672 -0.071845 -0.792520 +v -1.606366 -0.081112 -0.755694 +v -1.593862 -0.091681 -0.744750 +v -1.577625 -0.102727 -0.743281 +v -1.593862 -0.091681 -0.744750 +v -1.562005 -0.111290 -0.751679 +v -1.551189 -0.115076 -0.767695 +v -1.548074 -0.113070 -0.787036 +v -1.551189 -0.115076 -0.767695 +v -1.553495 -0.105810 -0.804522 +v -1.565999 -0.095241 -0.815465 +v -1.565999 -0.095241 -0.815465 +v -1.556738 -0.018422 -0.798128 +v -1.542017 -0.028250 -0.806760 +v -1.566692 -0.013420 -0.781888 +v -1.569210 -0.014586 -0.762392 +v -1.566692 -0.013420 -0.781888 +v -1.563619 -0.021607 -0.744862 +v -1.551417 -0.032602 -0.733997 +v -1.535872 -0.044624 -0.732708 +v -1.551417 -0.032602 -0.733997 +v -1.521151 -0.054452 -0.741340 +v -1.511198 -0.059454 -0.757580 +v -1.508679 -0.058288 -0.777077 +v -1.511198 -0.059454 -0.757580 +v -1.514270 -0.051267 -0.794606 +v -1.526472 -0.040272 -0.805471 +v -1.526472 -0.040272 -0.805471 +v -1.511286 0.038158 -0.790588 +v -1.497238 0.027481 -0.799335 +v -1.520561 0.044012 -0.774232 +v -1.522579 0.043476 -0.754650 +v -1.520561 0.044012 -0.774232 +v -1.516800 0.036692 -0.737088 +v -1.504771 0.025479 -0.726254 +v -1.489715 0.012841 -0.725048 +v -1.504771 0.025479 -0.726254 +v -1.475668 0.002165 -0.733795 +v -1.466393 -0.003689 -0.750151 +v -1.464374 -0.003153 -0.769733 +v -1.466393 -0.003689 -0.750151 +v -1.470154 0.003631 -0.787295 +v -1.482183 0.014843 -0.798130 +v -1.482183 0.014843 -0.798130 +v -1.463027 0.094394 -0.785403 +v -1.449409 0.083214 -0.794198 +v -1.471829 0.100806 -0.768994 +v -1.473455 0.100732 -0.749368 +v -1.471829 0.100806 -0.768994 +v -1.467469 0.094190 -0.731784 +v -1.455477 0.082935 -0.720953 +v -1.440690 0.069981 -0.719777 +v -1.455477 0.082935 -0.720953 +v -1.427072 0.058800 -0.728572 +v -1.418270 0.052388 -0.744981 +v -1.416644 0.052463 -0.764606 +v -1.418270 0.052388 -0.744981 +v -1.422629 0.059005 -0.782191 +v -1.434622 0.070260 -0.793022 +v -1.434622 0.070260 -0.793022 +v -1.413488 0.150557 -0.782068 +v -1.400051 0.139169 -0.790876 +v -1.422021 0.157276 -0.765640 +v -1.423363 0.157526 -0.745995 +v -1.422021 0.157276 -0.765640 +v -1.417155 0.151240 -0.728395 +v -1.405059 0.140103 -0.717556 +v -1.390318 0.127098 -0.716384 +v -1.405059 0.140103 -0.717556 +v -1.376880 0.115710 -0.725191 +v -1.368347 0.108990 -0.741619 +v -1.367005 0.108740 -0.761265 +v -1.368347 0.108990 -0.741619 +v -1.373214 0.115026 -0.778865 +v -1.385309 0.126164 -0.789703 +v -1.385309 0.126164 -0.789703 +v -1.364192 0.206897 -0.780085 +v -1.350692 0.195582 -0.788890 +v -1.372658 0.213693 -0.763655 +v -1.373822 0.214149 -0.744001 +v -1.372658 0.213693 -0.763655 +v -1.367371 0.208143 -0.726391 +v -1.355033 0.197284 -0.715542 +v -1.340116 0.184482 -0.714362 +v -1.355033 0.197284 -0.715542 +v -1.326615 0.173167 -0.723166 +v -1.318149 0.166371 -0.739597 +v -1.316985 0.165915 -0.759251 +v -1.318149 0.166371 -0.739597 +v -1.323436 0.171921 -0.776861 +v -1.335774 0.182780 -0.787710 +v -1.335774 0.182780 -0.787710 +v -1.316661 0.263645 -0.778960 +v -1.302858 0.252695 -0.787757 +v -1.325258 0.270284 -0.762533 +v -1.326344 0.270833 -0.742878 +v -1.325258 0.270284 -0.762533 +v -1.319628 0.265145 -0.725260 +v -1.306911 0.254744 -0.714401 +v -1.291600 0.242417 -0.713211 +v -1.306911 0.254744 -0.714401 +v -1.277796 0.231467 -0.722008 +v -1.269200 0.224828 -0.738435 +v -1.268113 0.224278 -0.758090 +v -1.269200 0.224828 -0.738435 +v -1.274829 0.229967 -0.775708 +v -1.287546 0.240368 -0.786567 +v -1.287546 0.240368 -0.786567 +v -1.272412 0.321011 -0.778204 +v -1.258075 0.310760 -0.786990 +v -1.281328 0.327231 -0.761783 +v -1.282435 0.327754 -0.742128 +v -1.281328 0.327231 -0.761783 +v -1.275435 0.322439 -0.724505 +v -1.262205 0.312710 -0.713636 +v -1.246289 0.301175 -0.712433 +v -1.262205 0.312710 -0.713636 +v -1.231952 0.290924 -0.721219 +v -1.223036 0.284704 -0.737640 +v -1.221929 0.284181 -0.757295 +v -1.223036 0.284704 -0.737640 +v -1.228929 0.289496 -0.774918 +v -1.242160 0.299225 -0.785788 +v -1.242160 0.299225 -0.785788 +v -1.232947 0.379183 -0.777333 +v -1.217870 0.370037 -0.786100 +v -1.242354 0.384670 -0.760925 +v -1.243570 0.385029 -0.741272 +v -1.242354 0.384670 -0.760925 +v -1.236270 0.380162 -0.723641 +v -1.222409 0.371375 -0.712756 +v -1.205702 0.361022 -0.711533 +v -1.222409 0.371375 -0.712756 +v -1.190625 0.351876 -0.720300 +v -1.181218 0.346389 -0.736708 +v -1.180001 0.346030 -0.756361 +v -1.181218 0.346389 -0.736708 +v -1.187301 0.350897 -0.773992 +v -1.201163 0.359684 -0.784877 +v -1.201163 0.359684 -0.784877 +v -1.199730 0.438335 -0.775872 +v -1.183765 0.430796 -0.784596 +v -1.209755 0.442704 -0.759494 +v -1.211154 0.442732 -0.739850 +v -1.209755 0.442704 -0.759494 +v -1.203552 0.438412 -0.722205 +v -1.188985 0.430902 -0.711285 +v -1.171358 0.422212 -0.710017 +v -1.188985 0.430902 -0.711285 +v -1.155393 0.414674 -0.718741 +v -1.145368 0.410305 -0.735119 +v -1.143969 0.410277 -0.754763 +v -1.145368 0.410305 -0.735119 +v -1.151571 0.414597 -0.772408 +v -1.166138 0.422107 -0.783328 +v -1.166138 0.422107 -0.783328 +v -1.174168 0.498655 -0.773357 +v -1.157290 0.493314 -0.781984 +v -1.184846 0.501451 -0.757048 +v -1.186464 0.500952 -0.737428 +v -1.184846 0.501451 -0.757048 +v -1.178588 0.497292 -0.719753 +v -1.163328 0.491451 -0.708760 +v -1.144773 0.484996 -0.707394 +v -1.163328 0.491451 -0.708760 +v -1.127895 0.479655 -0.716022 +v -1.117216 0.476859 -0.732330 +v -1.115598 0.477358 -0.751951 +v -1.117216 0.476859 -0.732330 +v -1.123475 0.481018 -0.769625 +v -1.138735 0.486858 -0.780618 +v -1.138735 0.486858 -0.780618 +v -1.157314 0.561618 -0.769258 +v -1.139816 0.558467 -0.777727 +v -1.168489 0.562659 -0.753076 +v -1.170347 0.561311 -0.733516 +v -1.168489 0.562659 -0.753076 +v -1.162390 0.557936 -0.715822 +v -1.146750 0.553437 -0.704731 +v -1.127619 0.549020 -0.703218 +v -1.146750 0.553437 -0.704731 +v -1.110121 0.545869 -0.711687 +v -1.098946 0.544828 -0.727869 +v -1.097088 0.546176 -0.747428 +v -1.098946 0.544828 -0.727869 +v -1.105045 0.549551 -0.765124 +v -1.120684 0.554050 -0.776214 +v -1.120684 0.554050 -0.776214 +v -1.143452 0.638546 -0.760427 +v -1.125682 0.636762 -0.768727 +v -1.154937 0.638027 -0.744438 +v -1.157060 0.635344 -0.725044 +v -1.154937 0.638027 -0.744438 +v -1.149253 0.631216 -0.707442 +v -1.133607 0.626750 -0.696348 +v -1.114315 0.623141 -0.694735 +v -1.133607 0.626750 -0.696348 +v -1.096545 0.621358 -0.703035 +v -1.085060 0.621877 -0.719024 +v -1.082936 0.624560 -0.738418 +v -1.085060 0.621877 -0.719024 +v -1.090743 0.628688 -0.756020 +v -1.106390 0.633154 -0.767114 +v -1.106390 0.633154 -0.767114 +v -1.132106 0.706218 -0.746845 +v -1.114174 0.705401 -0.754946 +v -1.143858 0.704105 -0.731185 +v -1.146282 0.699628 -0.712161 +v -1.143858 0.704105 -0.731185 +v -1.138728 0.693987 -0.694871 +v -1.123221 0.688693 -0.683948 +v -1.103915 0.685165 -0.682318 +v -1.123221 0.688693 -0.683948 +v -1.085983 0.684348 -0.690418 +v -1.074231 0.686461 -0.706079 +v -1.071807 0.690938 -0.725103 +v -1.074231 0.686461 -0.706079 +v -1.079360 0.696579 -0.742393 +v -1.094868 0.701873 -0.753316 +v -1.094868 0.701873 -0.753316 +v -1.123182 0.763984 -0.728764 +v -1.105074 0.764313 -0.736497 +v -1.135235 0.759929 -0.713727 +v -1.138001 0.753235 -0.695414 +v -1.135235 0.759929 -0.713727 +v -1.130741 0.745694 -0.678733 +v -1.115399 0.739328 -0.668154 +v -1.096086 0.735842 -0.666510 +v -1.115399 0.739328 -0.668154 +v -1.077978 0.736171 -0.674244 +v -1.065926 0.740226 -0.689281 +v -1.063159 0.746921 -0.707594 +v -1.065926 0.740226 -0.689281 +v -1.070420 0.754462 -0.724275 +v -1.085761 0.760828 -0.734854 +v -1.085761 0.760828 -0.734854 +v -1.116413 0.812288 -0.706166 +v -1.098117 0.813951 -0.713260 +v -1.128792 0.805906 -0.692242 +v -1.131937 0.796516 -0.675220 +v -1.128792 0.805906 -0.692242 +v -1.125005 0.786633 -0.659660 +v -1.109853 0.778906 -0.649732 +v -1.090543 0.775405 -0.648095 +v -1.109853 0.778906 -0.649732 +v -1.072247 0.777069 -0.655190 +v -1.059869 0.783451 -0.669114 +v -1.056724 0.792841 -0.686136 +v -1.059869 0.783451 -0.669114 +v -1.063656 0.802723 -0.701696 +v -1.078807 0.810451 -0.711624 +v -1.078807 0.810451 -0.711624 +v -1.111561 0.851386 -0.678868 +v -1.093083 0.854517 -0.684916 +v -1.124267 0.842372 -0.666822 +v -1.127797 0.829889 -0.652005 +v -1.124267 0.842372 -0.666822 +v -1.121204 0.817281 -0.638388 +v -1.106256 0.807929 -0.629619 +v -1.086957 0.804336 -0.628049 +v -1.106256 0.807929 -0.629619 +v -1.068478 0.807466 -0.634097 +v -1.055772 0.816480 -0.646144 +v -1.052243 0.828964 -0.660960 +v -1.055772 0.816480 -0.646144 +v -1.058835 0.841571 -0.674577 +v -1.073784 0.850924 -0.683346 +v -1.073784 0.850924 -0.683346 +v -1.108439 0.881101 -0.646702 +v -1.089811 0.885644 -0.651193 +v -1.121423 0.869473 -0.637533 +v -1.125282 0.853877 -0.626145 +v -1.121423 0.869473 -0.637533 +v -1.118984 0.838492 -0.615588 +v -1.104216 0.827440 -0.608692 +v -1.086957 0.804336 -0.628049 +v -1.084934 0.823682 -0.607304 +v -1.104216 0.827440 -0.608692 +v -1.106256 0.807929 -0.629619 +v -1.066306 0.828225 -0.611795 +v -1.084934 0.823682 -0.607304 +v -1.053323 0.839853 -0.620963 +v -1.049463 0.855448 -0.632351 +v -1.053323 0.839853 -0.620963 +v -1.055761 0.870834 -0.642908 +v -1.070530 0.881886 -0.649805 +v -1.093083 0.854517 -0.684916 +v -1.089811 0.885644 -0.651193 +v -1.070530 0.881886 -0.649805 +v -1.073784 0.850924 -0.683346 +v -1.108439 0.881101 -0.646702 +v -1.106890 0.900747 -0.610015 +v -1.088176 0.906347 -0.612517 +v -1.120037 0.887105 -0.604643 +v -1.106890 0.900747 -0.610015 +v -1.124094 0.869074 -0.597841 +v -1.120037 0.887105 -0.604643 +v -1.117975 0.851488 -0.591431 +v -1.103318 0.839057 -0.587130 +v -1.117975 0.851488 -0.591431 +v -1.118984 0.838492 -0.615588 +v -1.084052 0.835114 -0.586092 +v -1.065338 0.840713 -0.588594 +v -1.084052 0.835114 -0.586092 +v -1.052191 0.854356 -0.593966 +v -1.048134 0.872386 -0.600768 +v -1.052191 0.854356 -0.593966 +v -1.054253 0.889973 -0.607178 +v -1.068910 0.902403 -0.611479 +v -1.054253 0.889973 -0.607178 +v -1.055761 0.870834 -0.642908 +v -1.106694 0.909723 -0.570077 +v -1.087965 0.915800 -0.570489 +v -1.119868 0.895139 -0.568836 +v -1.106694 0.909723 -0.570077 +v -1.106890 0.900747 -0.610015 +v -1.123959 0.875954 -0.567097 +v -1.117871 0.857309 -0.565328 +v -1.103235 0.844200 -0.564001 +v -1.117871 0.857309 -0.565328 +v -1.083972 0.840140 -0.563473 +v -1.065338 0.840713 -0.588594 +v -1.065244 0.846216 -0.563885 +v -1.052069 0.860801 -0.565126 +v -1.065244 0.846216 -0.563885 +v -1.065338 0.840713 -0.588594 +v -1.047977 0.879986 -0.566865 +v -1.054066 0.898631 -0.568635 +v -1.068702 0.911739 -0.569961 +v -1.054066 0.898631 -0.568635 +v -1.107511 0.908286 -0.528556 +v -1.088815 0.914314 -0.527163 +v -1.120620 0.893801 -0.531035 +v -1.107511 0.908286 -0.528556 +v -1.124630 0.874739 -0.533936 +v -1.118466 0.856209 -0.536480 +v -1.103779 0.843176 -0.537987 +v -1.118466 0.856209 -0.536480 +v -1.084506 0.839132 -0.538053 +v -1.065810 0.845160 -0.536659 +v -1.052701 0.859646 -0.534180 +v -1.065810 0.845160 -0.536659 +v -1.048691 0.878707 -0.531280 +v -1.054855 0.897237 -0.528735 +v -1.069542 0.910270 -0.527228 +v -1.054855 0.897237 -0.528735 +v -1.108956 0.897432 -0.486584 +v -1.090304 0.903127 -0.483849 +v -1.121971 0.883672 -0.491980 +v -1.108956 0.897432 -0.486584 +v -1.125860 0.865534 -0.498590 +v -1.119582 0.847877 -0.504644 +v -1.104819 0.835433 -0.508520 +v -1.119582 0.847877 -0.504644 +v -1.085526 0.831537 -0.509179 +v -1.066874 0.837231 -0.506444 +v -1.053859 0.850991 -0.501048 +v -1.066874 0.837231 -0.506444 +v -1.049970 0.869129 -0.494438 +v -1.056248 0.886786 -0.488384 +v -1.071011 0.899230 -0.484508 +v -1.056248 0.886786 -0.488384 +v -1.110676 0.878211 -0.444572 +v -1.092059 0.883498 -0.440928 +v -1.123607 0.865401 -0.452090 +v -1.110676 0.878211 -0.444572 +v -1.127388 0.848501 -0.461467 +v -1.121005 0.832040 -0.470191 +v -1.106169 0.820427 -0.475924 +v -1.121005 0.832040 -0.470191 +v -1.086854 0.816776 -0.477130 +v -1.068238 0.822063 -0.473487 +v -1.055306 0.834873 -0.465969 +v -1.068238 0.822063 -0.473487 +v -1.051525 0.851773 -0.456592 +v -1.057908 0.868235 -0.447868 +v -1.072745 0.879847 -0.442135 +v -1.057908 0.868235 -0.447868 +v -1.112398 0.851086 -0.402199 +v -1.093818 0.855838 -0.397725 +v -1.092059 0.883498 -0.440928 +v -1.125247 0.839473 -0.411573 +v -1.128923 0.824112 -0.423335 +v -1.122439 0.809117 -0.434333 +v -1.107534 0.798507 -0.441620 +v -1.122439 0.809117 -0.434333 +v -1.088202 0.795125 -0.443244 +v -1.069622 0.799877 -0.438770 +v -1.088202 0.795125 -0.443244 +v -1.086854 0.816776 -0.477130 +v -1.056772 0.811489 -0.429396 +v -1.053097 0.826851 -0.417634 +v -1.059580 0.841845 -0.406636 +v -1.074485 0.852455 -0.399349 +v -1.059580 0.841845 -0.406636 +v -1.093818 0.855838 -0.397725 +v -1.115468 0.803707 -0.348752 +v -1.096973 0.807281 -0.343007 +v -1.128154 0.794339 -0.360548 +v -1.131632 0.781686 -0.375232 +v -1.122439 0.809117 -0.434333 +v -1.124970 0.769140 -0.388872 +v -1.131632 0.781686 -0.375232 +v -1.128923 0.824112 -0.423335 +v -1.109954 0.760062 -0.397812 +v -1.124970 0.769140 -0.388872 +v -1.090606 0.756884 -0.399656 +v -1.072112 0.760458 -0.393911 +v -1.090606 0.756884 -0.399656 +v -1.059426 0.769826 -0.382116 +v -1.055948 0.782479 -0.367431 +v -1.059580 0.841845 -0.406636 +v -1.062609 0.795025 -0.353791 +v -1.055948 0.782479 -0.367431 +v -1.053097 0.826851 -0.417634 +v -1.077626 0.804104 -0.344852 +v -1.062609 0.795025 -0.353791 +v -1.096973 0.807281 -0.343007 +v -1.120131 0.754073 -0.315223 +v -1.101858 0.755387 -0.307997 +v -1.132423 0.748720 -0.329648 +v -1.135441 0.740761 -0.347406 +v -1.128375 0.732328 -0.363740 +v -1.135441 0.740761 -0.347406 +v -1.109954 0.760062 -0.397812 +v -1.113120 0.725682 -0.374273 +v -1.090606 0.756884 -0.399656 +v -1.093763 0.722604 -0.376183 +v -1.075490 0.723917 -0.368957 +v -1.093763 0.722604 -0.376183 +v -1.063198 0.729271 -0.354532 +v -1.060181 0.737230 -0.336774 +v -1.067246 0.745662 -0.320440 +v -1.060181 0.737230 -0.336774 +v -1.077626 0.804104 -0.344852 +v -1.082501 0.752308 -0.309907 +v -1.096973 0.807281 -0.343007 +v -1.101858 0.755387 -0.307997 +v -1.126781 0.703104 -0.300711 +v -1.108919 0.701334 -0.292608 +v -1.138371 0.703007 -0.316632 +v -1.140586 0.701068 -0.336104 +v -1.132831 0.697807 -0.353910 +v -1.140586 0.701068 -0.336104 +v -1.117184 0.694097 -0.365278 +v -1.097839 0.690933 -0.367163 +v -1.079977 0.689162 -0.359060 +v -1.097839 0.690933 -0.367163 +v -1.068386 0.689260 -0.343139 +v -1.066172 0.691199 -0.323667 +v -1.073927 0.694461 -0.305861 +v -1.066172 0.691199 -0.323667 +v -1.089574 0.698170 -0.294493 +v -1.108919 0.701334 -0.292608 +v -1.135453 0.653243 -0.302868 +v -1.118129 0.648404 -0.294850 +v -1.146171 0.658127 -0.318651 +v -1.147412 0.661749 -0.337968 +v -1.138843 0.663136 -0.355645 +v -1.147412 0.661749 -0.337968 +v -1.122760 0.661918 -0.366945 +v -1.103472 0.658421 -0.368839 +v -1.086149 0.653582 -0.360821 +v -1.103472 0.658421 -0.368839 +v -1.075430 0.648697 -0.345038 +v -1.074190 0.645076 -0.325721 +v -1.082759 0.643688 -0.308044 +v -1.074190 0.645076 -0.325721 +v -1.098842 0.644906 -0.296744 +v -1.118129 0.648404 -0.294850 +v -1.146059 0.606011 -0.317422 +v -1.129268 0.598801 -0.310082 +v -1.155971 0.614490 -0.332177 +v -1.156347 0.621965 -0.350393 +v -1.147086 0.626435 -0.367188 +v -1.156347 0.621965 -0.350393 +v -1.130670 0.626700 -0.378063 +v -1.111497 0.622690 -0.380104 +v -1.094705 0.615480 -0.372764 +v -1.111497 0.622690 -0.380104 +v -1.084794 0.607001 -0.358009 +v -1.084418 0.599526 -0.339794 +v -1.093679 0.595057 -0.322998 +v -1.084418 0.599526 -0.339794 +v -1.110095 0.594792 -0.312123 +v -1.129268 0.598801 -0.310082 +v -1.158722 0.561129 -0.340145 +v -1.142390 0.552286 -0.333596 +v -1.168009 0.571826 -0.353826 +v -1.167763 0.581511 -0.370971 +v -1.158049 0.587588 -0.386988 +v -1.167763 0.581511 -0.370971 +v -1.141471 0.588430 -0.397584 +v -1.122470 0.583811 -0.399920 +v -1.106138 0.574968 -0.393370 +v -1.122470 0.583811 -0.399920 +v -1.096851 0.564271 -0.379690 +v -1.097097 0.554586 -0.362544 +v -1.106811 0.548509 -0.346528 +v -1.097097 0.554586 -0.362544 +v -1.123390 0.547667 -0.335932 +v -1.142390 0.552286 -0.333596 +v -1.173713 0.517823 -0.367656 +v -1.157768 0.507863 -0.361794 +v -1.182568 0.529769 -0.380567 +v -1.181959 0.540501 -0.397068 +v -1.172050 0.547142 -0.412737 +v -1.181959 0.540501 -0.397068 +v -1.155497 0.547914 -0.423377 +v -1.136733 0.542608 -0.426135 +v -1.120788 0.532648 -0.420273 +v -1.136733 0.542608 -0.426135 +v -1.111933 0.520701 -0.407362 +v -1.112541 0.509970 -0.390861 +v -1.122450 0.503329 -0.375191 +v -1.112541 0.509970 -0.390861 +v -1.139004 0.502557 -0.364552 +v -1.157768 0.507863 -0.361794 +v -1.191294 0.475571 -0.397013 +v -1.175680 0.464817 -0.391689 +v -1.199903 0.488107 -0.409526 +v -1.199201 0.499066 -0.425873 +v -1.189373 0.505511 -0.441675 +v -1.199201 0.499066 -0.425873 +v -1.173055 0.505716 -0.452698 +v -1.154619 0.499624 -0.455989 +v -1.139004 0.488870 -0.450665 +v -1.154619 0.499624 -0.455989 +v -1.130395 0.476334 -0.438152 +v -1.131098 0.465375 -0.421805 +v -1.140925 0.458930 -0.406003 +v -1.131098 0.465375 -0.421805 +v -1.157243 0.458725 -0.394980 +v -1.175680 0.464817 -0.391689 +v -1.211648 0.434157 -0.425421 +v -1.196322 0.422817 -0.420488 +v -1.220218 0.446774 -0.437879 +v -1.219735 0.457286 -0.454525 +v -1.210329 0.462876 -0.470899 +v -1.219735 0.457286 -0.454525 +v -1.194520 0.462047 -0.482612 +v -1.176544 0.455021 -0.486528 +v -1.161218 0.443681 -0.481595 +v -1.176544 0.455021 -0.486528 +v -1.152648 0.431064 -0.469137 +v -1.153132 0.420552 -0.452491 +v -1.162538 0.414962 -0.436117 +v -1.153132 0.420552 -0.452491 +v -1.178347 0.415791 -0.424404 +v -1.196322 0.422817 -0.420488 +v -1.234856 0.393568 -0.450184 +v -1.219779 0.381791 -0.445510 +v -1.243649 0.405794 -0.462873 +v -1.243803 0.415194 -0.480178 +v -1.235278 0.419248 -0.497461 +v -1.243803 0.415194 -0.480178 +v -1.220356 0.416871 -0.510092 +v -1.203038 0.408699 -0.514685 +v -1.187962 0.396922 -0.510011 +v -1.203038 0.408699 -0.514685 +v -1.179168 0.384696 -0.497322 +v -1.179014 0.375296 -0.480017 +v -1.187540 0.371241 -0.462734 +v -1.179014 0.375296 -0.480017 +v -1.202461 0.373619 -0.450104 +v -1.219779 0.381791 -0.445510 +v -1.260925 0.353848 -0.468830 +v -1.246051 0.341764 -0.464294 +v -1.270295 0.365198 -0.481915 +v -1.271650 0.372774 -0.500042 +v -1.264626 0.374546 -0.518354 +v -1.271650 0.372774 -0.500042 +v -1.251106 0.370039 -0.531946 +v -1.234712 0.360461 -0.537174 +v -1.219838 0.348378 -0.532638 +v -1.234712 0.360461 -0.537174 +v -1.210468 0.337028 -0.519553 +v -1.209114 0.329452 -0.501426 +v -1.216137 0.327679 -0.483114 +v -1.209114 0.329452 -0.501426 +v -1.229658 0.332186 -0.469522 +v -1.246051 0.341764 -0.464294 +v -1.291138 0.313450 -0.479488 +v -1.276076 0.301628 -0.474882 +v -1.301516 0.323393 -0.492951 +v -1.304429 0.328793 -0.511664 +v -1.299097 0.328203 -0.530613 +v -1.304429 0.328793 -0.511664 +v -1.286949 0.321781 -0.544720 +v -1.271240 0.311247 -0.550205 +v -1.256178 0.299425 -0.545599 +v -1.271240 0.311247 -0.550205 +v -1.245801 0.289482 -0.532135 +v -1.242887 0.284082 -0.513422 +v -1.248219 0.284672 -0.494474 +v -1.242887 0.284082 -0.513422 +v -1.260367 0.291095 -0.480367 +v -1.276076 0.301628 -0.474882 +v -1.325989 0.265025 -0.483701 +v -1.310097 0.254401 -0.478967 +v -1.337589 0.273204 -0.497353 +v -1.341789 0.276747 -0.516264 +v -1.337464 0.274704 -0.535368 +v -1.341789 0.276747 -0.516264 +v -1.325773 0.267623 -0.549545 +v -1.309847 0.257402 -0.554997 +v -1.293955 0.246778 -0.550263 +v -1.309847 0.257402 -0.554997 +v -1.282355 0.238600 -0.536611 +v -1.278154 0.235057 -0.517700 +v -1.282480 0.237099 -0.498596 +v -1.278154 0.235057 -0.517700 +v -1.294171 0.244180 -0.484419 +v -1.310097 0.254401 -0.478967 +v -1.358177 0.211116 -0.483592 +v -1.341338 0.202069 -0.478855 +v -1.370824 0.217552 -0.497247 +v -1.375891 0.219650 -0.516161 +v -1.372021 0.216851 -0.535266 +v -1.375891 0.219650 -0.516161 +v -1.360249 0.209902 -0.549443 +v -1.343732 0.200667 -0.554893 +v -1.326893 0.191620 -0.550156 +v -1.343732 0.200667 -0.554893 +v -1.314246 0.185185 -0.536500 +v -1.309179 0.183086 -0.517586 +v -1.313049 0.185886 -0.498481 +v -1.309179 0.183086 -0.517586 +v -1.324821 0.192834 -0.484304 +v -1.341338 0.202069 -0.478855 +v -1.387132 0.153141 -0.479645 +v -1.369584 0.145506 -0.474999 +v -1.400543 0.158057 -0.493203 +v -1.406224 0.158935 -0.512038 +v -1.402653 0.155540 -0.531105 +v -1.406224 0.158935 -0.512038 +v -1.390785 0.148783 -0.545295 +v -1.373802 0.140474 -0.550804 +v -1.356254 0.132839 -0.546157 +v -1.373802 0.140474 -0.550804 +v -1.342842 0.127924 -0.532600 +v -1.337161 0.127046 -0.513764 +v -1.340733 0.130440 -0.494697 +v -1.337161 0.127046 -0.513764 +v -1.352600 0.137197 -0.480508 +v -1.369584 0.145506 -0.474999 +v -1.387132 0.153141 -0.479645 +v -1.413154 0.091249 -0.472512 +v -1.395091 0.084830 -0.468001 +v -1.427101 0.094900 -0.485928 +v -1.413154 0.091249 -0.472512 +v -1.433193 0.094806 -0.504655 +v -1.429799 0.090991 -0.523675 +v -1.433193 0.094806 -0.504655 +v -1.417829 0.084478 -0.537891 +v -1.400489 0.077012 -0.543495 +v -1.356254 0.132839 -0.546157 +v -1.382425 0.070593 -0.538984 +v -1.368479 0.066942 -0.525568 +v -1.382425 0.070593 -0.538984 +v -1.362386 0.067036 -0.506841 +v -1.365780 0.070851 -0.487821 +v -1.362386 0.067036 -0.506841 +v -1.377751 0.077364 -0.473605 +v -1.436550 0.025603 -0.462856 +v -1.418123 0.020200 -0.458491 +v -1.450857 0.028249 -0.476127 +v -1.436550 0.025603 -0.462856 +v -1.457211 0.027430 -0.494749 +v -1.429799 0.090991 -0.523675 +v -1.453907 0.023363 -0.513733 +v -1.441832 0.017141 -0.527991 +v -1.453907 0.023363 -0.513733 +v -1.424221 0.010429 -0.533703 +v -1.405793 0.005025 -0.529339 +v -1.391486 0.002379 -0.516068 +v -1.405793 0.005025 -0.529339 +v -1.385133 0.003199 -0.497446 +v -1.365780 0.070851 -0.487821 +v -1.388437 0.007264 -0.478462 +v -1.400512 0.013487 -0.464204 +v -1.388437 0.007264 -0.478462 +v -1.457636 -0.043627 -0.451351 +v -1.438955 -0.048206 -0.447122 +v -1.418123 0.020200 -0.458491 +v -1.472176 -0.041742 -0.464499 +v -1.478681 -0.043055 -0.483040 +v -1.475405 -0.047215 -0.502008 +v -1.463229 -0.053106 -0.516321 +v -1.475405 -0.047215 -0.502008 +v -1.445413 -0.059150 -0.522142 +v -1.426732 -0.063728 -0.517913 +v -1.412192 -0.065614 -0.504766 +v -1.426732 -0.063728 -0.517913 +v -1.405688 -0.064301 -0.486225 +v -1.408962 -0.060141 -0.467256 +v -1.421139 -0.054250 -0.452944 +v -1.408962 -0.060141 -0.467256 +v -1.438955 -0.048206 -0.447122 +v -1.476734 -0.116271 -0.438683 +v -1.457881 -0.120199 -0.434566 +v -1.491417 -0.114923 -0.451738 +v -1.497997 -0.116517 -0.470231 +v -1.494707 -0.120625 -0.489208 +v -1.482433 -0.126148 -0.503584 +v -1.494707 -0.120625 -0.489208 +v -1.464462 -0.131603 -0.509507 +v -1.445608 -0.135531 -0.505390 +v -1.430926 -0.136879 -0.492335 +v -1.445608 -0.135531 -0.505390 +v -1.424347 -0.135285 -0.473842 +v -1.427635 -0.131177 -0.454865 +v -1.439910 -0.125655 -0.440489 +v -1.427635 -0.131177 -0.454865 +v -1.457881 -0.120199 -0.434566 +v -1.476734 -0.116271 -0.438683 +v -1.494179 -0.192161 -0.425539 +v -1.475211 -0.195597 -0.421506 +v -1.508939 -0.191148 -0.438536 +v -1.494179 -0.192161 -0.425539 +v -1.515538 -0.192829 -0.457015 +v -1.512207 -0.196754 -0.476023 +v -1.499839 -0.201871 -0.490469 +v -1.512207 -0.196754 -0.476023 +v -1.481747 -0.206809 -0.496480 +v -1.462780 -0.210245 -0.492447 +v -1.448020 -0.211258 -0.479450 +v -1.462780 -0.210245 -0.492447 +v -1.441420 -0.209577 -0.460971 +v -1.444752 -0.205652 -0.441962 +v -1.457120 -0.200535 -0.427517 +v -1.444752 -0.205652 -0.441962 +v -1.510306 -0.271134 -0.412610 +v -1.491266 -0.274221 -0.408634 +v -1.525097 -0.270270 -0.425583 +v -1.510306 -0.271134 -0.412610 +v -1.531677 -0.271860 -0.444077 +v -1.528283 -0.275479 -0.463135 +v -1.515824 -0.280156 -0.477651 +v -1.528283 -0.275479 -0.463135 +v -1.497639 -0.284639 -0.483736 +v -1.478600 -0.287726 -0.479759 +v -1.463809 -0.288590 -0.466786 +v -1.478600 -0.287726 -0.479759 +v -1.457228 -0.287000 -0.448293 +v -1.460623 -0.283381 -0.429235 +v -1.473081 -0.278704 -0.414719 +v -1.460623 -0.283381 -0.429235 +v -1.525457 -0.353028 -0.400591 +v -1.506377 -0.355897 -0.396646 +v -1.540244 -0.352143 -0.413568 +v -1.525457 -0.353028 -0.400591 +v -1.546777 -0.353478 -0.432098 +v -1.543304 -0.356675 -0.451217 +v -1.530757 -0.360879 -0.465802 +v -1.543304 -0.356675 -0.451217 +v -1.512497 -0.364962 -0.471945 +v -1.493418 -0.367830 -0.468000 +v -1.478630 -0.368716 -0.455024 +v -1.493418 -0.367830 -0.468000 +v -1.472098 -0.367381 -0.436494 +v -1.475570 -0.364183 -0.417375 +v -1.488117 -0.359980 -0.402790 +v -1.475570 -0.364183 -0.417375 +v -1.539977 -0.437685 -0.390178 +v -1.520880 -0.440455 -0.386245 +v -1.554733 -0.436620 -0.403176 +v -1.539977 -0.437685 -0.390178 +v -1.561195 -0.437544 -0.421757 +v -1.557630 -0.440212 -0.440940 +v -1.544996 -0.443907 -0.455587 +v -1.557630 -0.440212 -0.440940 +v -1.526675 -0.447639 -0.461772 +v -1.507579 -0.450410 -0.457839 +v -1.492823 -0.451475 -0.444841 +v -1.507579 -0.450410 -0.457839 +v -1.486361 -0.450550 -0.426261 +v -1.489925 -0.447883 -0.407078 +v -1.502560 -0.444189 -0.392431 +v -1.489925 -0.447883 -0.407078 +v -1.554431 -0.526249 -0.382002 +v -1.535375 -0.529264 -0.378052 +v -1.569036 -0.524274 -0.395064 +v -1.554431 -0.526249 -0.382002 +v -1.575276 -0.523868 -0.413738 +v -1.571481 -0.525141 -0.433020 +v -1.558665 -0.527750 -0.447743 +v -1.571481 -0.525141 -0.433020 +v -1.540264 -0.530998 -0.453963 +v -1.521208 -0.534013 -0.450013 +v -1.506603 -0.535989 -0.436951 +v -1.521208 -0.534013 -0.450013 +v -1.500363 -0.536394 -0.418277 +v -1.504159 -0.535121 -0.398995 +v -1.516974 -0.532512 -0.384271 +v -1.504159 -0.535121 -0.398995 +v -1.569398 -0.615648 -0.384501 +v -1.550494 -0.619556 -0.380603 +v -1.583583 -0.611202 -0.397419 +v -1.569398 -0.615648 -0.384501 +v -1.589247 -0.607411 -0.415895 +v -1.584872 -0.605289 -0.434979 +v -1.571633 -0.605406 -0.449557 +v -1.584872 -0.605289 -0.434979 +v -1.553075 -0.607730 -0.455723 +v -1.534170 -0.611639 -0.451824 +v -1.519986 -0.616084 -0.438906 +v -1.534170 -0.611639 -0.451824 +v -1.514323 -0.619876 -0.420430 +v -1.518697 -0.621997 -0.401347 +v -1.531937 -0.621880 -0.386769 +v -1.518697 -0.621997 -0.401347 +v -1.582978 -0.689333 -0.405411 +v -1.564322 -0.694577 -0.401909 +v -1.596497 -0.681294 -0.417262 +v -1.582978 -0.689333 -0.405411 +v -1.601256 -0.672616 -0.434288 +v -1.595980 -0.665623 -0.451925 +v -1.582083 -0.662190 -0.465449 +v -1.595980 -0.665623 -0.451925 +v -1.563287 -0.663235 -0.471236 +v -1.544631 -0.668480 -0.467734 +v -1.531112 -0.676518 -0.455883 +v -1.544631 -0.668480 -0.467734 +v -1.526354 -0.685196 -0.438857 +v -1.531630 -0.692189 -0.421220 +v -1.545527 -0.695623 -0.407696 +v -1.531630 -0.692189 -0.421220 +v -1.594782 -0.745781 -0.442410 +v -1.576407 -0.752368 -0.439801 +v -1.607544 -0.734139 -0.451865 +v -1.594782 -0.745781 -0.442410 +v -1.611275 -0.720561 -0.465633 +v -1.604975 -0.708686 -0.480024 +v -1.590331 -0.701695 -0.491183 +v -1.604975 -0.708686 -0.480024 +v -1.571268 -0.701461 -0.496119 +v -1.552893 -0.708049 -0.493510 +v -1.540130 -0.719691 -0.484054 +v -1.552893 -0.708049 -0.493510 +v -1.536399 -0.733268 -0.470287 +v -1.542700 -0.745144 -0.455895 +v -1.557343 -0.752134 -0.444737 +v -1.542700 -0.745144 -0.455895 +v -1.594782 -0.745781 -0.442410 +v -1.604409 -0.783988 -0.491827 +v -1.586294 -0.791605 -0.490546 +v -1.576407 -0.752368 -0.439801 +v -1.616477 -0.769585 -0.497722 +v -1.604409 -0.783988 -0.491827 +v -1.619263 -0.752255 -0.506652 +v -1.612021 -0.736643 -0.516224 +v -1.596692 -0.726930 -0.523873 +v -1.612021 -0.736643 -0.516224 +v -1.577383 -0.725720 -0.527550 +v -1.552893 -0.708049 -0.493510 +v -1.559268 -0.733337 -0.526269 +v -1.577383 -0.725720 -0.527550 +v -1.571268 -0.701461 -0.496119 +v -1.547200 -0.747740 -0.520374 +v -1.559268 -0.733337 -0.526269 +v -1.544414 -0.765070 -0.511444 +v -1.551656 -0.780683 -0.501872 +v -1.566984 -0.790396 -0.494223 +v -1.551656 -0.780683 -0.501872 +v -1.586294 -0.791605 -0.490546 +v -1.611522 -0.803812 -0.548736 +v -1.593597 -0.811964 -0.548959 +v -1.616477 -0.769585 -0.497722 +v -1.623082 -0.787979 -0.550609 +v -1.625179 -0.768707 -0.554076 +v -1.623082 -0.787979 -0.550609 +v -1.617251 -0.751160 -0.558209 +v -1.601422 -0.740040 -0.561901 +v -1.617251 -0.751160 -0.558209 +v -1.581934 -0.738327 -0.564161 +v -1.601422 -0.740040 -0.561901 +v -1.596692 -0.726930 -0.523873 +v -1.564008 -0.746479 -0.564385 +v -1.547200 -0.747740 -0.520374 +v -1.552449 -0.762312 -0.562512 +v -1.550352 -0.781584 -0.559045 +v -1.552449 -0.762312 -0.562512 +v -1.558280 -0.799130 -0.554911 +v -1.574109 -0.810250 -0.551220 +v -1.558280 -0.799130 -0.554911 +v -1.574109 -0.810250 -0.551220 +v -1.566984 -0.790396 -0.494223 +v -1.616021 -0.806482 -0.608413 +v -1.598206 -0.814708 -0.610087 +v -1.627285 -0.790452 -0.606419 +v -1.628980 -0.770912 -0.604639 +v -1.627285 -0.790452 -0.606419 +v -1.620653 -0.753099 -0.603552 +v -1.601422 -0.740040 -0.561901 +v -1.604534 -0.741786 -0.603447 +v -1.584942 -0.740003 -0.604353 +v -1.604534 -0.741786 -0.603447 +v -1.567127 -0.748230 -0.606027 +v -1.555864 -0.764260 -0.608021 +v -1.554168 -0.783799 -0.609801 +v -1.555864 -0.764260 -0.608021 +v -1.562496 -0.801612 -0.610888 +v -1.574109 -0.810250 -0.551220 +v -1.578615 -0.812925 -0.610994 +v -1.578615 -0.812925 -0.610994 +v -1.617940 -0.793661 -0.667087 +v -1.600169 -0.801603 -0.670079 +v -1.629088 -0.778384 -0.661593 +v -1.630625 -0.759866 -0.655069 +v -1.629088 -0.778384 -0.661593 +v -1.622140 -0.743070 -0.649264 +v -1.605907 -0.732494 -0.645733 +v -1.586275 -0.730974 -0.645422 +v -1.605907 -0.732494 -0.645733 +v -1.568505 -0.738916 -0.648414 +v -1.557357 -0.754192 -0.653908 +v -1.555820 -0.772710 -0.660431 +v -1.557357 -0.754192 -0.653908 +v -1.564304 -0.789507 -0.666236 +v -1.580537 -0.800083 -0.669767 +v -1.580537 -0.800083 -0.669767 +v -1.617296 -0.766685 -0.721512 +v -1.599512 -0.774037 -0.725693 +v -1.628482 -0.752970 -0.712873 +v -1.630069 -0.736567 -0.702091 +v -1.628482 -0.752970 -0.712873 +v -1.621635 -0.721871 -0.692055 +v -1.605439 -0.712820 -0.685454 +v -1.585819 -0.711839 -0.684056 +v -1.605439 -0.712820 -0.685454 +v -1.568035 -0.719192 -0.688237 +v -1.556850 -0.732906 -0.696876 +v -1.555262 -0.749309 -0.707658 +v -1.556850 -0.732906 -0.696876 +v -1.563696 -0.764005 -0.717694 +v -1.579892 -0.773056 -0.724295 +v -1.579892 -0.773056 -0.724295 +v -1.614041 -0.726507 -0.768363 +v -1.596182 -0.732952 -0.773593 +v -1.628482 -0.752970 -0.712873 +v -1.625421 -0.715183 -0.756957 +v -1.614041 -0.726507 -0.768363 +v -1.617296 -0.766685 -0.721512 +v -1.627272 -0.702014 -0.742432 +v -1.625421 -0.715183 -0.756957 +v -1.619100 -0.690529 -0.728679 +v -1.603093 -0.683806 -0.719384 +v -1.583541 -0.683645 -0.717037 +v -1.603093 -0.683806 -0.719384 +v -1.565682 -0.690090 -0.722267 +v -1.556850 -0.732906 -0.696876 +v -1.554302 -0.701414 -0.733673 +v -1.565682 -0.690090 -0.722267 +v -1.568035 -0.719192 -0.688237 +v -1.552451 -0.714583 -0.748198 +v -1.554302 -0.701414 -0.733673 +v -1.560623 -0.726068 -0.761951 +v -1.576630 -0.732791 -0.771246 +v -1.576630 -0.732791 -0.771246 +v -1.608092 -0.674069 -0.803880 +v -1.590093 -0.679280 -0.809938 +v -1.596182 -0.732952 -0.773593 +v -1.619841 -0.665990 -0.790296 +v -1.622192 -0.657207 -0.772827 +v -1.619841 -0.665990 -0.790296 +v -1.614514 -0.650074 -0.756154 +v -1.598866 -0.646502 -0.744744 +v -1.583541 -0.683645 -0.717037 +v -1.579440 -0.647449 -0.741654 +v -1.561441 -0.652660 -0.747712 +v -1.579440 -0.647449 -0.741654 +v -1.583541 -0.683645 -0.717037 +v -1.549692 -0.660739 -0.761296 +v -1.547341 -0.669522 -0.778764 +v -1.549692 -0.660739 -0.761296 +v -1.555018 -0.676655 -0.795438 +v -1.570667 -0.680227 -0.806848 +v -1.596182 -0.732952 -0.773593 +v -1.590093 -0.679280 -0.809938 +v -1.599434 -0.610870 -0.823961 +v -1.581232 -0.614601 -0.830487 +v -1.611715 -0.606672 -0.809149 +v -1.614784 -0.603133 -0.790021 +v -1.611715 -0.606672 -0.809149 +v -1.607820 -0.601201 -0.771702 +v -1.592687 -0.601393 -0.759100 +v -1.573441 -0.603658 -0.755594 +v -1.555240 -0.607389 -0.762120 +v -1.573441 -0.603658 -0.755594 +v -1.542958 -0.611587 -0.776932 +v -1.539890 -0.615126 -0.796060 +v -1.542958 -0.611587 -0.776932 +v -1.546854 -0.617059 -0.814379 +v -1.561987 -0.616866 -0.826980 +v -1.581232 -0.614601 -0.830487 +v -1.588430 -0.540985 -0.825063 +v -1.570091 -0.543877 -0.831632 +v -1.601168 -0.539594 -0.810109 +v -1.604893 -0.540077 -0.790777 +v -1.601168 -0.539594 -0.810109 +v -1.598607 -0.542305 -0.772248 +v -1.583994 -0.545681 -0.759485 +v -1.564969 -0.549300 -0.755909 +v -1.583994 -0.545681 -0.759485 +v -1.592687 -0.601393 -0.759100 +v -1.546630 -0.552192 -0.762479 +v -1.533891 -0.553583 -0.777432 +v -1.530166 -0.553100 -0.796764 +v -1.533891 -0.553583 -0.777432 +v -1.536453 -0.550871 -0.815294 +v -1.551066 -0.547496 -0.828056 +v -1.551066 -0.547496 -0.828056 +v -1.561987 -0.616866 -0.826980 +v -1.570881 -0.454047 -0.813720 +v -1.552657 -0.457492 -0.820343 +v -1.583691 -0.453000 -0.798800 +v -1.587655 -0.454633 -0.779579 +v -1.583691 -0.453000 -0.798800 +v -1.581712 -0.458508 -0.761208 +v -1.567453 -0.463587 -0.748610 +v -1.548700 -0.468508 -0.745159 +v -1.567453 -0.463587 -0.748610 +v -1.530476 -0.471953 -0.751782 +v -1.517666 -0.473000 -0.766703 +v -1.513701 -0.471367 -0.785923 +v -1.517666 -0.473000 -0.766703 +v -1.519644 -0.467492 -0.804294 +v -1.533903 -0.462414 -0.816893 +v -1.533903 -0.462414 -0.816893 +v -1.548786 -0.373569 -0.802759 +v -1.530885 -0.378191 -0.809542 +v -1.561382 -0.371738 -0.787731 +v -1.565297 -0.373191 -0.768486 +v -1.561382 -0.371738 -0.787731 +v -1.559482 -0.377536 -0.750179 +v -1.545497 -0.383611 -0.737717 +v -1.527086 -0.389786 -0.734437 +v -1.545497 -0.383611 -0.737717 +v -1.509185 -0.394409 -0.741220 +v -1.496590 -0.396239 -0.756248 +v -1.492675 -0.394787 -0.775493 +v -1.496590 -0.396239 -0.756248 +v -1.498490 -0.390441 -0.793800 +v -1.512475 -0.384367 -0.806263 +v -1.512475 -0.384367 -0.806263 +v -1.522234 -0.297206 -0.791977 +v -1.504711 -0.302922 -0.798915 +v -1.534579 -0.294653 -0.776848 +v -1.538440 -0.295948 -0.757580 +v -1.534579 -0.294653 -0.776848 +v -1.532780 -0.300742 -0.739337 +v -1.519119 -0.307752 -0.727006 +v -1.501115 -0.315100 -0.723893 +v -1.519119 -0.307752 -0.727006 +v -1.483593 -0.320816 -0.730830 +v -1.471247 -0.323369 -0.745960 +v -1.467387 -0.322075 -0.765228 +v -1.471247 -0.323369 -0.745960 +v -1.473046 -0.317280 -0.783471 +v -1.486707 -0.310270 -0.795801 +v -1.486707 -0.310270 -0.795801 +v -1.491712 -0.224452 -0.781299 +v -1.474599 -0.231149 -0.788381 +v -1.503789 -0.221257 -0.766075 +v -1.507594 -0.222421 -0.746789 +v -1.503789 -0.221257 -0.766075 +v -1.502109 -0.227632 -0.728606 +v -1.488803 -0.235493 -0.716401 +v -1.471241 -0.243898 -0.713443 +v -1.488803 -0.235493 -0.716401 +v -1.454129 -0.250595 -0.720524 +v -1.442052 -0.253790 -0.735748 +v -1.438246 -0.252626 -0.755035 +v -1.442052 -0.253790 -0.735748 +v -1.443731 -0.247416 -0.773217 +v -1.457037 -0.239555 -0.785422 +v -1.457037 -0.239555 -0.785422 +v -1.457713 -0.154790 -0.770647 +v -1.441013 -0.162335 -0.777858 +v -1.469525 -0.151048 -0.755339 +v -1.473283 -0.152112 -0.736037 +v -1.469525 -0.151048 -0.755339 +v -1.467979 -0.157696 -0.717912 +v -1.455036 -0.166305 -0.705821 +v -1.437921 -0.175631 -0.703004 +v -1.455036 -0.166305 -0.705821 +v -1.421221 -0.183176 -0.710215 +v -1.409410 -0.186918 -0.725522 +v -1.405652 -0.185854 -0.744824 +v -1.409410 -0.186918 -0.725522 +v -1.410956 -0.180269 -0.762949 +v -1.423899 -0.171661 -0.775041 +v -1.423899 -0.171661 -0.775041 +v -1.420735 -0.087693 -0.759942 +v -1.404419 -0.095939 -0.767265 +v -1.432303 -0.083507 -0.744564 +v -1.436023 -0.084503 -0.725251 +v -1.432303 -0.083507 -0.744564 +v -1.430898 -0.090414 -0.707178 +v -1.418303 -0.099656 -0.695188 +v -1.401610 -0.109752 -0.692493 +v -1.418303 -0.099656 -0.695188 +v -1.385294 -0.117998 -0.699816 +v -1.373727 -0.122184 -0.715194 +v -1.370007 -0.121188 -0.734508 +v -1.373727 -0.122184 -0.715194 +v -1.375131 -0.115278 -0.752580 +v -1.387727 -0.106036 -0.764570 +v -1.387727 -0.106036 -0.764570 +v -1.381267 -0.022626 -0.749106 +v -1.365283 -0.031422 -0.756520 +v -1.392630 -0.018102 -0.733671 +v -1.396328 -0.019061 -0.714352 +v -1.392630 -0.018102 -0.733671 +v -1.391370 -0.025248 -0.696325 +v -1.379084 -0.035003 -0.684420 +v -1.362763 -0.045714 -0.681828 +v -1.379084 -0.035003 -0.684420 +v -1.346779 -0.054510 -0.689243 +v -1.335416 -0.059035 -0.704677 +v -1.331718 -0.058075 -0.723996 +v -1.335416 -0.059035 -0.704677 +v -1.336676 -0.051889 -0.742023 +v -1.348961 -0.042133 -0.753928 +v -1.348961 -0.042133 -0.753928 +v -1.339793 0.040954 -0.738058 +v -1.324070 0.031757 -0.745542 +v -1.351005 0.045712 -0.722583 +v -1.354700 0.044758 -0.703263 +v -1.351005 0.045712 -0.722583 +v -1.349888 0.038347 -0.685275 +v -1.337858 0.028197 -0.673439 +v -1.321835 0.017027 -0.670926 +v -1.337858 0.028197 -0.673439 +v -1.306110 0.007831 -0.678410 +v -1.294899 0.003073 -0.693885 +v -1.291204 0.004027 -0.713206 +v -1.294899 0.003073 -0.693885 +v -1.296017 0.010438 -0.731194 +v -1.308046 0.020588 -0.743030 +v -1.308046 0.020588 -0.743030 +v -1.296795 0.103593 -0.726718 +v -1.281244 0.094144 -0.734248 +v -1.307916 0.108484 -0.711219 +v -1.311627 0.107506 -0.691903 +v -1.307916 0.108484 -0.711219 +v -1.306934 0.100920 -0.673947 +v -1.295094 0.090492 -0.662161 +v -1.279280 0.079016 -0.659704 +v -1.295094 0.090492 -0.662161 +v -1.263729 0.069566 -0.667234 +v -1.252609 0.064675 -0.682734 +v -1.248897 0.065654 -0.702049 +v -1.252609 0.064675 -0.682734 +v -1.253590 0.072239 -0.720006 +v -1.265430 0.082667 -0.731791 +v -1.265430 0.082667 -0.731791 +v -1.252742 0.165842 -0.715006 +v -1.237270 0.156280 -0.722557 +v -1.263839 0.170767 -0.699500 +v -1.267587 0.169736 -0.680195 +v -1.263839 0.170767 -0.699500 +v -1.262982 0.163025 -0.662262 +v -1.251259 0.152432 -0.650507 +v -1.235558 0.140795 -0.648080 +v -1.251259 0.152432 -0.650507 +v -1.220086 0.131233 -0.655632 +v -1.208989 0.126308 -0.671137 +v -1.205241 0.127339 -0.690443 +v -1.208989 0.126308 -0.671137 +v -1.209846 0.134050 -0.708376 +v -1.221569 0.144643 -0.720131 +v -1.221569 0.144643 -0.720131 +v -1.208099 0.228248 -0.702841 +v -1.192611 0.218709 -0.710387 +v -1.219238 0.233114 -0.687346 +v -1.223043 0.232003 -0.668056 +v -1.219238 0.233114 -0.687346 +v -1.218494 0.225213 -0.650138 +v -1.206811 0.214564 -0.638395 +v -1.191124 0.202908 -0.635972 +v -1.206811 0.214564 -0.638395 +v -1.175635 0.193369 -0.643518 +v -1.164497 0.188504 -0.659012 +v -1.160691 0.189614 -0.678303 +v -1.164497 0.188504 -0.659012 +v -1.165240 0.196404 -0.696220 +v -1.176924 0.207053 -0.707964 +v -1.176924 0.207053 -0.707964 +v -1.163497 0.291116 -0.690188 +v -1.147868 0.281778 -0.697695 +v -1.174728 0.295851 -0.674720 +v -1.178551 0.294714 -0.655434 +v -1.174728 0.295851 -0.674720 +v -1.173943 0.288010 -0.637500 +v -1.162137 0.277535 -0.625722 +v -1.146298 0.266096 -0.623256 +v -1.162137 0.277535 -0.625722 +v -1.130669 0.256757 -0.630763 +v -1.119438 0.252022 -0.646232 +v -1.115615 0.253159 -0.665517 +v -1.119438 0.252022 -0.646232 +v -1.120223 0.259863 -0.683451 +v -1.132029 0.270339 -0.695229 +v -1.132029 0.270339 -0.695229 +v -1.117498 0.359326 -0.677153 +v -1.101583 0.350418 -0.684581 +v -1.128840 0.363895 -0.661716 +v -1.132569 0.362900 -0.642404 +v -1.128840 0.363895 -0.661716 +v -1.127685 0.356608 -0.624394 +v -1.115498 0.346705 -0.612509 +v -1.099273 0.335844 -0.609936 +v -1.115498 0.346705 -0.612509 +v -1.083358 0.326936 -0.617363 +v -1.072016 0.322367 -0.632801 +v -1.068288 0.323362 -0.652112 +v -1.072016 0.322367 -0.632801 +v -1.073171 0.329654 -0.670123 +v -1.085358 0.339557 -0.682008 +v -1.085358 0.339557 -0.682008 +v -1.081617 0.418144 -0.667724 +v -1.065316 0.409873 -0.675050 +v -1.093081 0.422513 -0.652318 +v -1.096634 0.421806 -0.632961 +v -1.093081 0.422513 -0.652318 +v -1.091326 0.416215 -0.614839 +v -1.078579 0.407238 -0.602809 +v -1.061808 0.397279 -0.600093 +v -1.078579 0.407238 -0.602809 +v -1.045507 0.389007 -0.607420 +v -1.034044 0.384639 -0.622825 +v -1.030490 0.385345 -0.642183 +v -1.034044 0.384639 -0.622825 +v -1.035798 0.390936 -0.660304 +v -1.048545 0.399914 -0.672335 +v -1.048545 0.399914 -0.672335 +v -1.054602 0.468778 -0.661490 +v -1.037862 0.461338 -0.668717 +v -1.066200 0.472891 -0.646115 +v -1.069548 0.472575 -0.626711 +v -1.066200 0.472891 -0.646115 +v -1.063748 0.467915 -0.608477 +v -1.050354 0.460160 -0.596299 +v -1.032956 0.451387 -0.593441 +v -1.050354 0.460160 -0.596299 +v -1.016215 0.443947 -0.600667 +v -1.004618 0.439834 -0.616043 +v -1.001270 0.440150 -0.635447 +v -1.004618 0.439834 -0.616043 +v -1.007070 0.444809 -0.653680 +v -1.020464 0.452565 -0.665858 +v -1.020464 0.452565 -0.665858 +v -1.035314 0.512202 -0.658067 +v -1.018105 0.505827 -0.665213 +v -1.047050 0.515999 -0.642716 +v -1.050170 0.516201 -0.623272 +v -1.047050 0.515999 -0.642716 +v -1.043837 0.512754 -0.604947 +v -1.029749 0.506582 -0.592649 +v -1.011680 0.499337 -0.589674 +v -1.029749 0.506582 -0.592649 +v -0.994472 0.492962 -0.596819 +v -0.982735 0.489165 -0.612170 +v -0.979615 0.488963 -0.631614 +v -0.982735 0.489165 -0.612170 +v -0.985948 0.492410 -0.649940 +v -1.000036 0.498582 -0.662238 +v -1.000036 0.498582 -0.662238 +v -1.022533 0.549479 -0.657039 +v -1.004884 0.544404 -0.664152 +v -1.034395 0.552904 -0.641697 +v -1.037292 0.553764 -0.622237 +v -1.034395 0.552904 -0.641697 +v -1.030448 0.551826 -0.603873 +v -1.015697 0.547611 -0.591526 +v -0.996991 0.542247 -0.588504 +v -1.015697 0.547611 -0.591526 +v -0.979342 0.537173 -0.595617 +v -0.967480 0.533747 -0.610959 +v -0.964582 0.532887 -0.630419 +v -0.967480 0.533747 -0.610959 +v -0.971426 0.534825 -0.648783 +v -0.986177 0.539040 -0.661130 +v -0.986177 0.539040 -0.661130 +v -1.014980 0.581874 -0.657988 +v -0.996993 0.578259 -0.665145 +v -1.026934 0.584902 -0.642633 +v -1.029653 0.586532 -0.623197 +v -1.026934 0.584902 -0.642633 +v -1.022408 0.586328 -0.604886 +v -1.007140 0.584342 -0.592607 +v -0.987940 0.581110 -0.589650 +v -1.007140 0.584342 -0.592607 +v -0.969953 0.577495 -0.596807 +v -0.957999 0.574466 -0.612161 +v -0.955280 0.572836 -0.631598 +v -0.957999 0.574466 -0.612161 +v -0.962525 0.573041 -0.649909 +v -0.977793 0.575026 -0.662188 +v -0.977793 0.575026 -0.662188 +v -1.011420 0.610931 -0.660553 +v -0.993252 0.608757 -0.667837 +v -1.023420 0.613592 -0.645167 +v -1.026038 0.616027 -0.625801 +v -1.023420 0.613592 -0.645167 +v -1.018573 0.617584 -0.607645 +v -1.003023 0.617846 -0.595562 +v -0.983557 0.616742 -0.592792 +v -1.003023 0.617846 -0.595562 +v -0.965390 0.614568 -0.600075 +v -0.953390 0.611907 -0.615461 +v -0.950771 0.609471 -0.634827 +v -0.953390 0.611907 -0.615461 +v -0.958237 0.607914 -0.652984 +v -0.973786 0.607653 -0.665066 +v -0.973786 0.607653 -0.665066 +v -1.010793 0.638361 -0.664498 +v -0.992591 0.637376 -0.671949 +v -1.022802 0.640754 -0.649074 +v -1.025398 0.643912 -0.629810 +v -1.022802 0.640754 -0.649074 +v -1.017887 0.646990 -0.611867 +v -1.002281 0.649163 -0.600054 +v -0.982761 0.649848 -0.597535 +v -1.002281 0.649163 -0.600054 +v -0.964559 0.648862 -0.604986 +v -0.952550 0.646470 -0.620410 +v -0.949954 0.643312 -0.639674 +v -0.952550 0.646470 -0.620410 +v -0.957465 0.640234 -0.657617 +v -0.973071 0.638061 -0.669430 +v -0.973071 0.638061 -0.669430 +v -1.012223 0.665789 -0.669673 +v -0.994052 0.665546 -0.677260 +v -1.024226 0.668061 -0.654227 +v -1.026845 0.671754 -0.635061 +v -1.024226 0.668061 -0.654227 +v -1.019379 0.675878 -0.617311 +v -1.003827 0.679328 -0.605732 +v -0.984356 0.681180 -0.603429 +v -1.003827 0.679328 -0.605732 +v -0.966185 0.680937 -0.611016 +v -0.954182 0.678665 -0.626462 +v -0.951563 0.674972 -0.645628 +v -0.954182 0.678665 -0.626462 +v -0.959029 0.670848 -0.663378 +v -0.974581 0.667397 -0.674956 +v -0.974581 0.667397 -0.674956 +v -1.014854 0.694564 -0.675911 +v -0.996700 0.694534 -0.683543 +v -1.026861 0.696880 -0.660474 +v -1.029504 0.700861 -0.641369 +v -1.026861 0.696880 -0.660474 +v -1.022074 0.705440 -0.623715 +v -1.006562 0.709390 -0.612243 +v -0.987126 0.711654 -0.610026 +v -1.006562 0.709390 -0.612243 +v -0.968971 0.711623 -0.617659 +v -0.956965 0.709307 -0.633096 +v -0.954322 0.705326 -0.652200 +v -0.956965 0.709307 -0.633096 +v -0.961752 0.700747 -0.669854 +v -0.977263 0.696797 -0.681326 +v -0.977263 0.696797 -0.681326 +v -1.017701 0.725764 -0.682940 +v -0.999522 0.725434 -0.690507 +v -1.029724 0.728273 -0.667546 +v -1.032369 0.732289 -0.648449 +v -1.029724 0.728273 -0.667546 +v -1.024928 0.736735 -0.630766 +v -1.009395 0.740420 -0.619235 +v -0.989931 0.742357 -0.616946 +v -1.009395 0.740420 -0.619235 +v -0.971753 0.742027 -0.624512 +v -0.959730 0.739517 -0.639906 +v -0.957084 0.735502 -0.659004 +v -0.959730 0.739517 -0.639906 +v -0.964525 0.731056 -0.676687 +v -0.980058 0.727371 -0.688218 +v -0.980058 0.727371 -0.688218 +v -1.019723 0.761966 -0.690621 +v -1.001545 0.761635 -0.698187 +v -1.031698 0.763609 -0.675073 +v -1.034260 0.766123 -0.655710 +v -1.031698 0.763609 -0.675073 +v -1.026723 0.768833 -0.637719 +v -1.011106 0.771015 -0.625921 +v -0.991594 0.772084 -0.623478 +v -1.011106 0.771015 -0.625921 +v -0.973415 0.771752 -0.631045 +v -0.961441 0.770109 -0.646592 +v -0.958879 0.767596 -0.665956 +v -0.961441 0.770109 -0.646592 +v -0.966416 0.764885 -0.683947 +v -0.982033 0.762703 -0.695744 +v -0.982033 0.762703 -0.695744 +v -1.020791 0.813067 -0.692955 +v -1.002650 0.814312 -0.700516 +v -1.032671 0.810763 -0.677418 +v -1.035107 0.808016 -0.658070 +v -1.032671 0.810763 -0.677418 +v -1.027446 0.805563 -0.640095 +v -1.011741 0.804062 -0.628308 +v -0.992200 0.803913 -0.625869 +v -1.011741 0.804062 -0.628308 +v -0.974059 0.805159 -0.633430 +v -0.962179 0.807463 -0.648967 +v -0.959743 0.810210 -0.668314 +v -0.962179 0.807463 -0.648967 +v -0.967403 0.812662 -0.686290 +v -0.983109 0.814164 -0.698076 +v -0.983109 0.814164 -0.698076 +v -1.020752 0.856619 -0.677437 +v -1.002609 0.860627 -0.683962 +v -1.032638 0.848153 -0.664214 +v -1.035082 0.837496 -0.647834 +v -1.032638 0.848153 -0.664214 +v -1.027427 0.827505 -0.632688 +v -1.011728 0.820856 -0.622833 +v -0.992188 0.819331 -0.620910 +v -1.011728 0.820856 -0.622833 +v -0.974044 0.823338 -0.627435 +v -0.962158 0.831805 -0.640659 +v -0.959715 0.842462 -0.657038 +v -0.962158 0.831805 -0.640659 +v -0.967368 0.852453 -0.672184 +v -0.983069 0.859102 -0.682039 +v -0.983069 0.859102 -0.682039 +v -1.019840 0.886142 -0.645838 +v -1.001631 0.892400 -0.649972 +v -1.031869 0.872758 -0.637838 +v -1.034496 0.855834 -0.628117 +v -1.031869 0.872758 -0.637838 +v -1.027014 0.839904 -0.619279 +v -1.011728 0.820856 -0.622833 +v -1.011431 0.829238 -0.613693 +v -1.027014 0.839904 -0.619279 +v -1.027427 0.827505 -0.632688 +v -0.992188 0.819331 -0.620910 +v -0.991921 0.826692 -0.612854 +v -0.973712 0.832950 -0.616989 +v -0.991921 0.826692 -0.612854 +v -0.961683 0.846334 -0.624989 +v -0.959057 0.863258 -0.634710 +v -0.961683 0.846334 -0.624989 +v -0.966538 0.879188 -0.643548 +v -0.983069 0.859102 -0.682039 +v -0.982121 0.889854 -0.649134 +v -0.966538 0.879188 -0.643548 +v -0.967368 0.852453 -0.672184 +v -1.002609 0.860627 -0.683962 +v -1.001631 0.892400 -0.649972 +v -1.019840 0.886142 -0.645838 +v -1.018538 0.898346 -0.605366 +v -1.000240 0.905513 -0.606655 +v -1.030755 0.883022 -0.603436 +v -1.018538 0.898346 -0.605366 +v -1.019840 0.886142 -0.645838 +v -1.033619 0.863646 -0.601381 +v -1.026361 0.845412 -0.599754 +v -1.010927 0.833204 -0.598989 +v -1.026361 0.845412 -0.599754 +v -0.991453 0.830293 -0.599292 +v -0.973712 0.832950 -0.616989 +v -0.973155 0.837460 -0.600581 +v -0.960938 0.852785 -0.602511 +v -0.973155 0.837460 -0.600581 +v -0.973712 0.832950 -0.616989 +v -0.958075 0.872160 -0.604565 +v -0.965332 0.890395 -0.606193 +v -0.980766 0.902603 -0.606958 +v -0.965332 0.890395 -0.606193 +v -1.017313 0.894937 -0.562414 +v -0.998947 0.901942 -0.561216 +v -1.029672 0.879947 -0.565636 +v -1.017313 0.894937 -0.562414 +v -1.032714 0.860990 -0.570017 +v -1.025621 0.843144 -0.574384 +v -1.010297 0.831193 -0.577568 +v -1.025621 0.843144 -0.574384 +v -0.990845 0.828337 -0.578713 +v -0.972479 0.835343 -0.577515 +v -0.960120 0.850332 -0.574294 +v -0.972479 0.835343 -0.577515 +v -0.957079 0.869290 -0.569912 +v -0.964171 0.887135 -0.565545 +v -0.979496 0.899087 -0.562362 +v -0.964171 0.887135 -0.565545 +v -1.016486 0.878198 -0.520067 +v -0.998083 0.884421 -0.516843 +v -1.028922 0.864780 -0.527356 +v -1.016486 0.878198 -0.520067 +v -1.032057 0.847761 -0.536757 +v -1.025051 0.831703 -0.545750 +v -1.009783 0.820908 -0.551927 +v -1.025051 0.831703 -0.545750 +v -0.990342 0.818268 -0.553631 +v -0.971938 0.824491 -0.550407 +v -0.959502 0.837909 -0.543118 +v -0.971938 0.824491 -0.550407 +v -0.956367 0.854928 -0.533717 +v -0.963373 0.870986 -0.524724 +v -0.978642 0.881781 -0.518548 +v -0.963373 0.870986 -0.524724 +v -1.016339 0.849156 -0.480580 +v -0.997930 0.854169 -0.475700 +v -0.998083 0.884421 -0.516843 +v -1.028784 0.838101 -0.491102 +v -1.031930 0.823966 -0.504448 +v -1.025051 0.831703 -0.545750 +v -1.024935 0.810538 -0.517042 +v -1.031930 0.823966 -0.504448 +v -1.032057 0.847761 -0.536757 +v -1.009673 0.801416 -0.525508 +v -1.024935 0.810538 -0.517042 +v -0.990233 0.799044 -0.527579 +v -0.971825 0.804058 -0.522700 +v -0.990233 0.799044 -0.527579 +v -0.990342 0.818268 -0.553631 +v -0.959379 0.815113 -0.512177 +v -0.956233 0.829248 -0.498831 +v -0.963228 0.842675 -0.486237 +v -0.978490 0.851797 -0.477771 +v -0.963228 0.842675 -0.486237 +v -0.997930 0.854169 -0.475700 +v -1.017160 0.808243 -0.446521 +v -0.998784 0.811693 -0.440338 +v -1.029543 0.800177 -0.459538 +v -1.032614 0.789655 -0.475899 +v -1.025551 0.779499 -0.491222 +v -1.032614 0.789655 -0.475899 +v -1.009673 0.801416 -0.525508 +v -1.010246 0.772428 -0.501399 +v -0.990800 0.770337 -0.503705 +v -1.010246 0.772428 -0.501399 +v -0.972424 0.773788 -0.497521 +v -0.990800 0.770337 -0.503705 +v -0.960041 0.781854 -0.484505 +v -0.956970 0.792375 -0.468143 +v -0.963228 0.842675 -0.486237 +v -0.964033 0.802532 -0.452821 +v -0.956970 0.792375 -0.468143 +v -0.956233 0.829248 -0.498831 +v -0.978490 0.851797 -0.477771 +v -0.979338 0.809603 -0.442643 +v -0.998784 0.811693 -0.440338 +v -0.979338 0.809603 -0.442643 +v -1.019240 0.755879 -0.420765 +v -1.000937 0.757505 -0.413681 +v -1.031484 0.751246 -0.435477 +v -1.034390 0.744848 -0.453874 +v -1.027178 0.738400 -0.471027 +v -1.034390 0.744848 -0.453874 +v -1.011781 0.733629 -0.482340 +v -0.990800 0.770337 -0.503705 +v -0.992324 0.731814 -0.484782 +v -0.974021 0.733440 -0.477698 +v -0.992324 0.731814 -0.484782 +v -0.961776 0.738073 -0.462986 +v -0.958871 0.744471 -0.444589 +v -0.966083 0.750919 -0.427436 +v -0.958871 0.744471 -0.444589 +v -0.981480 0.755690 -0.416123 +v -0.998784 0.811693 -0.440338 +v -1.000937 0.757505 -0.413681 +v -1.022847 0.692655 -0.406206 +v -1.004655 0.692356 -0.398672 +v -1.034887 0.691607 -0.421755 +v -1.037548 0.689493 -0.441153 +v -1.030116 0.686879 -0.459202 +v -1.037548 0.689493 -0.441153 +v -1.014584 0.684467 -0.471066 +v -0.995113 0.682901 -0.473566 +v -0.976920 0.682602 -0.466032 +v -0.995113 0.682901 -0.473566 +v -0.964880 0.683650 -0.450483 +v -0.962220 0.685764 -0.431085 +v -0.969651 0.688377 -0.413036 +v -0.962220 0.685764 -0.431085 +v -0.985183 0.690790 -0.401172 +v -1.004655 0.692356 -0.398672 +v -1.028228 0.619224 -0.405538 +v -1.010170 0.617085 -0.397978 +v -1.040019 0.621574 -0.421135 +v -1.042384 0.623505 -0.440591 +v -1.034688 0.624500 -0.458691 +v -1.042384 0.623505 -0.440591 +v -1.018995 0.624292 -0.470586 +v -0.999508 0.622937 -0.473089 +v -0.981450 0.620798 -0.465529 +v -0.999508 0.622937 -0.473089 +v -0.969659 0.618448 -0.449932 +v -0.967295 0.616516 -0.430476 +v -0.974990 0.615522 -0.412376 +v -0.967295 0.616516 -0.430476 +v -0.990684 0.615730 -0.400481 +v -1.010170 0.617085 -0.397978 +v -1.035474 0.538593 -0.420739 +v -1.017703 0.534047 -0.413572 +v -1.046897 0.544023 -0.435834 +v -1.048911 0.548884 -0.454811 +v -1.040977 0.551872 -0.472586 +v -1.048911 0.548884 -0.454811 +v -1.025221 0.552187 -0.484396 +v -1.005865 0.549745 -0.487077 +v -0.988095 0.545199 -0.479909 +v -1.005865 0.549745 -0.487077 +v -0.976672 0.539768 -0.464814 +v -0.974657 0.534908 -0.445837 +v -0.982591 0.531919 -0.428062 +v -0.974657 0.534908 -0.445837 +v -0.998347 0.531604 -0.416252 +v -1.017703 0.534047 -0.413572 +v -1.042081 0.510156 -0.429070 +v -1.025008 0.502707 -0.422678 +v -1.052931 0.517973 -0.443527 +v -1.054650 0.524062 -0.462177 +v -1.046778 0.526793 -0.480021 +v -1.054650 0.524062 -0.462177 +v -1.031425 0.525433 -0.492278 +v -1.012703 0.520347 -0.495665 +v -0.995631 0.512897 -0.489273 +v -1.012703 0.520347 -0.495665 +v -0.984781 0.505081 -0.474815 +v -0.983062 0.498991 -0.456166 +v -0.990934 0.496261 -0.438323 +v -0.983062 0.498991 -0.456166 +v -1.006287 0.497621 -0.426065 +v -1.025008 0.502707 -0.422678 +v -1.056479 0.476243 -0.439319 +v -1.040276 0.466636 -0.433574 +v -1.066754 0.485484 -0.453349 +v -1.068348 0.491883 -0.471905 +v -1.060834 0.493726 -0.490015 +v -1.068348 0.491883 -0.471905 +v -1.046225 0.490519 -0.502826 +v -1.028436 0.483122 -0.506906 +v -1.012233 0.473515 -0.501161 +v -1.028436 0.483122 -0.506906 +v -1.001958 0.464274 -0.487130 +v -1.000364 0.457874 -0.468574 +v -1.007878 0.456031 -0.450464 +v -1.000364 0.457874 -0.468574 +v -1.022486 0.459239 -0.437653 +v -1.040276 0.466636 -0.433574 +v -1.078672 0.435990 -0.451573 +v -1.063161 0.425101 -0.446216 +v -1.088508 0.446042 -0.465357 +v -1.090036 0.452564 -0.483876 +v -1.082845 0.453809 -0.502167 +v -1.090036 0.452564 -0.483876 +v -1.068862 0.449443 -0.515330 +v -1.051835 0.440636 -0.519836 +v -1.036325 0.429747 -0.514480 +v -1.051835 0.440636 -0.519836 +v -1.026488 0.419695 -0.500695 +v -1.024960 0.413172 -0.482177 +v -1.032150 0.411928 -0.463885 +v -1.024960 0.413172 -0.482177 +v -1.046133 0.416294 -0.450723 +v -1.063161 0.425101 -0.446216 +v -1.107846 0.390824 -0.465187 +v -1.092881 0.379082 -0.460087 +v -1.117358 0.401384 -0.478819 +v -1.118869 0.407932 -0.497330 +v -1.111974 0.408714 -0.515761 +v -1.118869 0.407932 -0.497330 +v -1.098521 0.403520 -0.529172 +v -1.082114 0.393742 -0.533970 +v -1.067149 0.382000 -0.528870 +v -1.082114 0.393742 -0.533970 +v -1.057637 0.371440 -0.515238 +v -1.056126 0.364892 -0.496727 +v -1.063020 0.364110 -0.478297 +v -1.056126 0.364892 -0.496727 +v -1.076474 0.369304 -0.464885 +v -1.092881 0.379082 -0.460087 +v -1.143161 0.341892 -0.479593 +v -1.128642 0.329530 -0.474675 +v -1.152431 0.352791 -0.493125 +v -1.153967 0.359304 -0.511647 +v -1.147358 0.359687 -0.530194 +v -1.153967 0.359304 -0.511647 +v -1.134376 0.353837 -0.543798 +v -1.118497 0.343323 -0.548812 +v -1.103978 0.330960 -0.543895 +v -1.118497 0.343323 -0.548812 +v -1.094708 0.320062 -0.530362 +v -1.093172 0.313549 -0.511840 +v -1.099781 0.313166 -0.493293 +v -1.093172 0.313549 -0.511840 +v -1.112763 0.319015 -0.479689 +v -1.128642 0.329530 -0.474675 +v -1.183786 0.290230 -0.494253 +v -1.169647 0.277382 -0.489473 +v -1.192872 0.301362 -0.507720 +v -1.194470 0.307796 -0.526263 +v -1.188153 0.307808 -0.544916 +v -1.194470 0.307796 -0.526263 +v -1.175612 0.301395 -0.558679 +v -1.160209 0.290274 -0.563865 +v -1.146070 0.277426 -0.559084 +v -1.160209 0.290274 -0.563865 +v -1.136984 0.266294 -0.545618 +v -1.135386 0.259860 -0.527074 +v -1.141703 0.259848 -0.508422 +v -1.135386 0.259860 -0.527074 +v -1.154244 0.266261 -0.494659 +v -1.169647 0.277382 -0.489473 +v -1.228899 0.236821 -0.508648 +v -1.215100 0.223570 -0.503976 +v -1.237845 0.248119 -0.522070 +v -1.239542 0.254437 -0.540645 +v -1.233534 0.254082 -0.559396 +v -1.239542 0.254437 -0.540645 +v -1.221431 0.247149 -0.573298 +v -1.206477 0.235496 -0.578628 +v -1.192678 0.222245 -0.573956 +v -1.206477 0.235496 -0.578628 +v -1.183732 0.210947 -0.560534 +v -1.182035 0.204629 -0.541959 +v -1.188043 0.204984 -0.523208 +v -1.182035 0.204629 -0.541959 +v -1.200146 0.211917 -0.509305 +v -1.215100 0.223570 -0.503976 +v -1.277679 0.182633 -0.522264 +v -1.264198 0.169028 -0.517680 +v -1.286520 0.194047 -0.535656 +v -1.288353 0.200213 -0.554269 +v -1.282688 0.199478 -0.573115 +v -1.288353 0.200213 -0.554269 +v -1.271040 0.192039 -0.587145 +v -1.256533 0.179889 -0.592598 +v -1.243052 0.166284 -0.588015 +v -1.256533 0.179889 -0.592598 +v -1.234210 0.154870 -0.574622 +v -1.232377 0.148704 -0.556009 +v -1.238043 0.149440 -0.537163 +v -1.232377 0.148704 -0.556009 +v -1.249690 0.156878 -0.523133 +v -1.264198 0.169028 -0.517680 +v -1.329303 0.128620 -0.534593 +v -1.316135 0.114688 -0.530083 +v -1.338069 0.140113 -0.547968 +v -1.340084 0.146089 -0.566624 +v -1.334808 0.144946 -0.585563 +v -1.340084 0.146089 -0.566624 +v -1.323655 0.136990 -0.599710 +v -1.309612 0.124353 -0.605274 +v -1.296444 0.110422 -0.600764 +v -1.309612 0.124353 -0.605274 +v -1.287678 0.098929 -0.587389 +v -1.285663 0.092953 -0.568733 +v -1.290939 0.094096 -0.549794 +v -1.285663 0.092953 -0.568733 +v -1.302092 0.102052 -0.535647 +v -1.316135 0.114688 -0.530083 +v -1.382943 0.075735 -0.545134 +v -1.370095 0.061488 -0.540687 +v -1.391661 0.087276 -0.558500 +v -1.393912 0.093019 -0.577202 +v -1.389093 0.091424 -0.596230 +v -1.393912 0.093019 -0.577202 +v -1.378496 0.082921 -0.610485 +v -1.364960 0.069785 -0.616148 +v -1.352112 0.055538 -0.611701 +v -1.364960 0.069785 -0.616148 +v -1.343395 0.043997 -0.598336 +v -1.341144 0.038254 -0.579633 +v -1.345962 0.039849 -0.560605 +v -1.341144 0.038254 -0.579633 +v -1.356559 0.048352 -0.546350 +v -1.370095 0.061488 -0.540687 +v -1.437757 0.024932 -0.553391 +v -1.425253 0.010366 -0.548995 +v -1.446452 0.036494 -0.566753 +v -1.449009 0.041954 -0.585501 +v -1.444742 0.039849 -0.604611 +v -1.449009 0.041954 -0.585501 +v -1.434794 0.030744 -0.618963 +v -1.421832 0.017078 -0.624710 +v -1.409328 0.002512 -0.620314 +v -1.421832 0.017078 -0.624710 +v -1.400633 -0.009050 -0.606952 +v -1.398076 -0.014510 -0.588205 +v -1.402343 -0.012405 -0.569095 +v -1.398076 -0.014510 -0.588205 +v -1.412291 -0.003300 -0.554743 +v -1.425253 0.010366 -0.548995 +v -1.493462 -0.023302 -0.558932 +v -1.480815 -0.037739 -0.554522 +v -1.502537 -0.012081 -0.572332 +v -1.505610 -0.007084 -0.591131 +v -1.501856 -0.009649 -0.610292 +v -1.505610 -0.007084 -0.591131 +v -1.492281 -0.019088 -0.624681 +v -1.479451 -0.032874 -0.630443 +v -1.466804 -0.047311 -0.626032 +v -1.479451 -0.032874 -0.630443 +v -1.457729 -0.058531 -0.612632 +v -1.454656 -0.063528 -0.593833 +v -1.458411 -0.060964 -0.574672 +v -1.454656 -0.063528 -0.593833 +v -1.467985 -0.051524 -0.560283 +v -1.480815 -0.037739 -0.554522 +v -1.493462 -0.023302 -0.558932 +v -1.586703 -0.110287 -0.563680 +v -1.572799 -0.123497 -0.559205 +v -1.597006 -0.100266 -0.577142 +v -1.586703 -0.110287 -0.563680 +v -1.600947 -0.096117 -0.595986 +v -1.597470 -0.098952 -0.615161 +v -1.600947 -0.096117 -0.595986 +v -1.587507 -0.108013 -0.629531 +v -1.573727 -0.120870 -0.635243 +v -1.466804 -0.047311 -0.626032 +v -1.559823 -0.134079 -0.630769 +v -1.549520 -0.144101 -0.617306 +v -1.559823 -0.134079 -0.630769 +v -1.545580 -0.148250 -0.598463 +v -1.549056 -0.145414 -0.579287 +v -1.545580 -0.148250 -0.598463 +v -1.559019 -0.136354 -0.564918 +v -1.658729 -0.197268 -0.563254 +v -1.643015 -0.208269 -0.558794 +v -1.670666 -0.189242 -0.576704 +v -1.658729 -0.197268 -0.563254 +v -1.675629 -0.186340 -0.595539 +v -1.672287 -0.189340 -0.614714 +v -1.675629 -0.186340 -0.595539 +v -1.661535 -0.197438 -0.629089 +v -1.646255 -0.208464 -0.634814 +v -1.630542 -0.219465 -0.630353 +v -1.618604 -0.227491 -0.616904 +v -1.630542 -0.219465 -0.630353 +v -1.613642 -0.230393 -0.598068 +v -1.616984 -0.227393 -0.578894 +v -1.613642 -0.230393 -0.598068 +v -1.627735 -0.219295 -0.564518 +v -1.711417 -0.284737 -0.558185 +v -1.694080 -0.293027 -0.553882 +v -1.724813 -0.279144 -0.571493 +v -1.711417 -0.284737 -0.558185 +v -1.730677 -0.277746 -0.590241 +v -1.727438 -0.280919 -0.609405 +v -1.730677 -0.277746 -0.590241 +v -1.715965 -0.287812 -0.623851 +v -1.699330 -0.296577 -0.629707 +v -1.681993 -0.304867 -0.625404 +v -1.668597 -0.310460 -0.612096 +v -1.681993 -0.304867 -0.625404 +v -1.662734 -0.311857 -0.593348 +v -1.665972 -0.308685 -0.574184 +v -1.662734 -0.311857 -0.593348 +v -1.677446 -0.301792 -0.559738 +v -1.747120 -0.373557 -0.549039 +v -1.728595 -0.378909 -0.545036 +v -1.761574 -0.370584 -0.562080 +v -1.747120 -0.373557 -0.549039 +v -1.768084 -0.370787 -0.580665 +v -1.727438 -0.280919 -0.609405 +v -1.764907 -0.374112 -0.599814 +v -1.752893 -0.379666 -0.614396 +v -1.764907 -0.374112 -0.599814 +v -1.735261 -0.385963 -0.620504 +v -1.716737 -0.391315 -0.616501 +v -1.702282 -0.394287 -0.603460 +v -1.716737 -0.391315 -0.616501 +v -1.695772 -0.394084 -0.584875 +v -1.665972 -0.308685 -0.574184 +v -1.698950 -0.390760 -0.565726 +v -1.710963 -0.385205 -0.551144 +v -1.698950 -0.390760 -0.565726 +v -1.768236 -0.464531 -0.536410 +v -1.749052 -0.467113 -0.532786 +v -1.783273 -0.464008 -0.549115 +v -1.768236 -0.464531 -0.536410 +v -1.790135 -0.465683 -0.567499 +v -1.786981 -0.469108 -0.586634 +v -1.774658 -0.473366 -0.601393 +v -1.786981 -0.469108 -0.586634 +v -1.756467 -0.477315 -0.607822 +v -1.737283 -0.479897 -0.604199 +v -1.722246 -0.480420 -0.591493 +v -1.737283 -0.479897 -0.604199 +v -1.715386 -0.478745 -0.573110 +v -1.718539 -0.475319 -0.553975 +v -1.730862 -0.471062 -0.539215 +v -1.718539 -0.475319 -0.553975 +v -1.777244 -0.558472 -0.520902 +v -1.757823 -0.558779 -0.517649 +v -1.792487 -0.559937 -0.533284 +v -1.777244 -0.558472 -0.520902 +v -1.799470 -0.562781 -0.551477 +v -1.796320 -0.566241 -0.570606 +v -1.783881 -0.569391 -0.585546 +v -1.796320 -0.566241 -0.570606 +v -1.765488 -0.571387 -0.592294 +v -1.746068 -0.571693 -0.589041 +v -1.730824 -0.570228 -0.576658 +v -1.746068 -0.571693 -0.589041 +v -1.723842 -0.567384 -0.558465 +v -1.726992 -0.563924 -0.539336 +v -1.739430 -0.560774 -0.524396 +v -1.726992 -0.563924 -0.539336 +v -1.776662 -0.656254 -0.503118 +v -1.757238 -0.654922 -0.500159 +v -1.791909 -0.659123 -0.515248 +v -1.776662 -0.656254 -0.503118 +v -1.798893 -0.662760 -0.533298 +v -1.795742 -0.666189 -0.552433 +v -1.783303 -0.668494 -0.567525 +v -1.795742 -0.666189 -0.552433 +v -1.764906 -0.669055 -0.574530 +v -1.745482 -0.667722 -0.571571 +v -1.730235 -0.664853 -0.559442 +v -1.745482 -0.667722 -0.571571 +v -1.723251 -0.661217 -0.541391 +v -1.726401 -0.657787 -0.522256 +v -1.738841 -0.655483 -0.507165 +v -1.726401 -0.657787 -0.522256 +v -1.769008 -0.758808 -0.483646 +v -1.749652 -0.756467 -0.480878 +v -1.784199 -0.762507 -0.495620 +v -1.769008 -0.758808 -0.483646 +v -1.791155 -0.766573 -0.513590 +v -1.788010 -0.769917 -0.532741 +v -1.775609 -0.771641 -0.547942 +v -1.788010 -0.769917 -0.532741 +v -1.757274 -0.771286 -0.555119 +v -1.737918 -0.768944 -0.552350 +v -1.722727 -0.765245 -0.540377 +v -1.737918 -0.768944 -0.552350 +v -1.715771 -0.761179 -0.522407 +v -1.718915 -0.757836 -0.503256 +v -1.731317 -0.756111 -0.488055 +v -1.718915 -0.757836 -0.503256 +v -1.756780 -0.867098 -0.463065 +v -1.737472 -0.864303 -0.460382 +v -1.771937 -0.871124 -0.474977 +v -1.756780 -0.867098 -0.463065 +v -1.778880 -0.875303 -0.492926 +v -1.775750 -0.878515 -0.512102 +v -1.763385 -0.879898 -0.527367 +v -1.775750 -0.878515 -0.512102 +v -1.745098 -0.879084 -0.534631 +v -1.725790 -0.876288 -0.531947 +v -1.710634 -0.872262 -0.520035 +v -1.725790 -0.876288 -0.531947 +v -1.703690 -0.868084 -0.502086 +v -1.706820 -0.864872 -0.482910 +v -1.719185 -0.863489 -0.467645 +v -1.706820 -0.864872 -0.482910 +v -1.742452 -0.982096 -0.441945 +v -1.723142 -0.979316 -0.439259 +v -1.757621 -0.986025 -0.453875 +v -1.742452 -0.982096 -0.441945 +v -1.764582 -0.990051 -0.471851 +v -1.761472 -0.993094 -0.491058 +v -1.749123 -0.994341 -0.506348 +v -1.761472 -0.993094 -0.491058 +v -1.730845 -0.993455 -0.513625 +v -1.711535 -0.990675 -0.510938 +v -1.696367 -0.986746 -0.499009 +v -1.711535 -0.990675 -0.510938 +v -1.689406 -0.982720 -0.481032 +v -1.692516 -0.979676 -0.461826 +v -1.704864 -0.978431 -0.446536 +v -1.692516 -0.979676 -0.461826 +v -1.728486 -1.104772 -0.420855 +v -1.709131 -1.102397 -0.418099 +v -1.743702 -1.108253 -0.432861 +v -1.728486 -1.104772 -0.420855 +v -1.750705 -1.111907 -0.450901 +v -1.747616 -1.114755 -0.470141 +v -1.735264 -1.116034 -0.485426 +v -1.747616 -1.114755 -0.470141 +v -1.716958 -1.115400 -0.492659 +v -1.697604 -1.113026 -0.489904 +v -1.682387 -1.109545 -0.477897 +v -1.697604 -1.113026 -0.489904 +v -1.675384 -1.105891 -0.459857 +v -1.678473 -1.103044 -0.440617 +v -1.690826 -1.101764 -0.425333 +v -1.678473 -1.103044 -0.440617 +v -1.717329 -1.236113 -0.400359 +v -1.697919 -1.234416 -0.397497 +v -1.732603 -1.238898 -0.412473 +v -1.717329 -1.236113 -0.400359 +v -1.739649 -1.242028 -0.430595 +v -1.736578 -1.244662 -0.449868 +v -1.724213 -1.246095 -0.465128 +v -1.736578 -1.244662 -0.449868 +v -1.705868 -1.245943 -0.472287 +v -1.686457 -1.244246 -0.469426 +v -1.671183 -1.241460 -0.457311 +v -1.686457 -1.244246 -0.469426 +v -1.664137 -1.238331 -0.439190 +v -1.667208 -1.235697 -0.419917 +v -1.679573 -1.234264 -0.404656 +v -1.667208 -1.235697 -0.419917 +vt 0.816791 0.072926 +vt 0.814961 0.080713 +vt 0.816315 0.081097 +vt 0.818132 0.073368 +vt 0.815405 0.072674 +vt 0.813564 0.080505 +vt 0.814344 0.072679 +vt 0.812500 0.080529 +vt 0.807333 0.376910 +vt 0.805300 0.369316 +vt 0.803921 0.369528 +vt 0.805957 0.377135 +vt 0.808676 0.376427 +vt 0.806654 0.368871 +vt 0.809628 0.375814 +vt 0.807620 0.368313 +vt 0.938050 0.894660 +vt 0.936283 0.886974 +vt 0.934926 0.887351 +vt 0.936707 0.895096 +vt 0.939437 0.894416 +vt 0.937680 0.886773 +vt 0.940497 0.894428 +vt 0.938744 0.886804 +vt 0.822314 0.431834 +vt 0.820383 0.439239 +vt 0.821764 0.439443 +vt 0.823692 0.432050 +vt 0.820968 0.431358 +vt 0.819026 0.438802 +vt 0.820014 0.430749 +vt 0.818058 0.438249 +vt 0.813537 0.088098 +vt 0.814903 0.088420 +vt 0.812132 0.087935 +vt 0.811064 0.087975 +vt 0.803549 0.362081 +vt 0.802166 0.362278 +vt 0.804913 0.361680 +vt 0.805894 0.361182 +vt 0.934919 0.879707 +vt 0.933551 0.880022 +vt 0.936325 0.879552 +vt 0.937392 0.879599 +vt 0.818727 0.446272 +vt 0.820112 0.446461 +vt 0.817360 0.445879 +vt 0.816378 0.445386 +vt 0.812477 0.095135 +vt 0.813853 0.095392 +vt 0.811065 0.095018 +vt 0.809995 0.095073 +vt 0.802065 0.355159 +vt 0.800678 0.355336 +vt 0.803440 0.354805 +vt 0.804434 0.354371 +vt 0.933914 0.872804 +vt 0.932537 0.873056 +vt 0.935327 0.872695 +vt 0.936396 0.872758 +vt 0.817331 0.452987 +vt 0.818720 0.453156 +vt 0.815955 0.452641 +vt 0.814959 0.452212 +vt 0.811739 0.101878 +vt 0.813122 0.102071 +vt 0.810322 0.101805 +vt 0.809251 0.101873 +vt 0.800835 0.348501 +vt 0.799444 0.348656 +vt 0.802220 0.348200 +vt 0.803226 0.347832 +vt 0.933226 0.866211 +vt 0.931841 0.866398 +vt 0.934643 0.866147 +vt 0.935714 0.866221 +vt 0.816182 0.459435 +vt 0.817575 0.459581 +vt 0.814796 0.459142 +vt 0.813789 0.458779 +vt 0.811280 0.108382 +vt 0.812668 0.108512 +vt 0.809860 0.108350 +vt 0.808788 0.108425 +vt 0.799846 0.342063 +vt 0.798450 0.342191 +vt 0.801239 0.341816 +vt 0.802256 0.341515 +vt 0.932810 0.859871 +vt 0.931422 0.859995 +vt 0.934230 0.859847 +vt 0.935301 0.859930 +vt 0.815263 0.465673 +vt 0.816660 0.465792 +vt 0.813869 0.465433 +vt 0.812852 0.465138 +vt 0.811058 0.114698 +vt 0.812447 0.114769 +vt 0.809636 0.114702 +vt 0.808564 0.114781 +vt 0.799083 0.335799 +vt 0.797684 0.335897 +vt 0.800483 0.335606 +vt 0.801507 0.335371 +vt 0.932624 0.853726 +vt 0.931234 0.853791 +vt 0.934045 0.853738 +vt 0.935117 0.853824 +vt 0.814561 0.471754 +vt 0.815961 0.471843 +vt 0.813161 0.471569 +vt 0.812136 0.471339 +vt 0.811028 0.120879 +vt 0.812418 0.120899 +vt 0.809606 0.120911 +vt 0.808534 0.120988 +vt 0.798532 0.329663 +vt 0.797130 0.329729 +vt 0.799937 0.329524 +vt 0.800967 0.329349 +vt 0.932626 0.847718 +vt 0.931235 0.847732 +vt 0.934047 0.847759 +vt 0.935118 0.847842 +vt 0.814061 0.477733 +vt 0.815464 0.477790 +vt 0.812656 0.477602 +vt 0.811627 0.477432 +vt 0.811147 0.126977 +vt 0.812536 0.126954 +vt 0.809726 0.127029 +vt 0.808654 0.127098 +vt 0.798178 0.323608 +vt 0.796774 0.323641 +vt 0.799585 0.323520 +vt 0.800618 0.323399 +vt 0.932772 0.841790 +vt 0.931383 0.841762 +vt 0.934193 0.841851 +vt 0.935264 0.841926 +vt 0.813750 0.483665 +vt 0.815155 0.483688 +vt 0.812343 0.483584 +vt 0.811310 0.483468 +vt 0.811372 0.133044 +vt 0.812760 0.132990 +vt 0.809951 0.133107 +vt 0.808878 0.133162 +vt 0.798005 0.317588 +vt 0.796600 0.317587 +vt 0.799413 0.317545 +vt 0.800448 0.317469 +vt 0.933021 0.835884 +vt 0.931633 0.835824 +vt 0.934441 0.835955 +vt 0.935513 0.836016 +vt 0.813615 0.489601 +vt 0.815021 0.489590 +vt 0.812207 0.489566 +vt 0.811174 0.489494 +vt 0.811658 0.139133 +vt 0.813046 0.139059 +vt 0.810238 0.139196 +vt 0.809164 0.139232 +vt 0.797997 0.311554 +vt 0.796592 0.311518 +vt 0.799405 0.311550 +vt 0.800440 0.311508 +vt 0.933331 0.829942 +vt 0.931944 0.829862 +vt 0.934751 0.830013 +vt 0.935824 0.830056 +vt 0.813644 0.495594 +vt 0.815050 0.495550 +vt 0.812236 0.495598 +vt 0.811203 0.495561 +vt 0.811963 0.145297 +vt 0.813349 0.145215 +vt 0.810541 0.145351 +vt 0.809467 0.145363 +vt 0.798139 0.305455 +vt 0.796734 0.305387 +vt 0.799547 0.305483 +vt 0.800581 0.305463 +vt 0.933660 0.823908 +vt 0.932273 0.823820 +vt 0.935080 0.823970 +vt 0.936155 0.823988 +vt 0.813823 0.501694 +vt 0.815228 0.501618 +vt 0.812416 0.501730 +vt 0.811383 0.501716 +vt 0.812235 0.151460 +vt 0.813622 0.151384 +vt 0.810815 0.151528 +vt 0.809741 0.151569 +vt 0.798416 0.299211 +vt 0.797011 0.299182 +vt 0.799825 0.299202 +vt 0.800859 0.299158 +vt 0.933971 0.817595 +vt 0.932585 0.817514 +vt 0.935391 0.817671 +vt 0.936464 0.817720 +vt 0.814138 0.507921 +vt 0.815544 0.507884 +vt 0.812730 0.507921 +vt 0.811697 0.507881 +vt 0.812529 0.156639 +vt 0.813917 0.156580 +vt 0.811111 0.156759 +vt 0.810045 0.156907 +vt 0.798249 0.293739 +vt 0.796849 0.293842 +vt 0.799653 0.293607 +vt 0.800684 0.293481 +vt 0.934324 0.811906 +vt 0.932936 0.811841 +vt 0.935741 0.812034 +vt 0.936806 0.812189 +vt 0.814006 0.513324 +vt 0.815408 0.513419 +vt 0.812602 0.513200 +vt 0.811571 0.513080 +vt 0.813007 0.162790 +vt 0.814396 0.162747 +vt 0.811593 0.162956 +vt 0.810533 0.163200 +vt 0.797357 0.287315 +vt 0.795972 0.287539 +vt 0.798747 0.287072 +vt 0.799769 0.286873 +vt 0.934869 0.805297 +vt 0.933480 0.805248 +vt 0.936282 0.805471 +vt 0.937341 0.805722 +vt 0.813161 0.519692 +vt 0.814548 0.519906 +vt 0.811770 0.519456 +vt 0.810749 0.519262 +vt 0.813607 0.169735 +vt 0.814997 0.169704 +vt 0.812195 0.169921 +vt 0.811139 0.170212 +vt 0.795948 0.280226 +vt 0.794575 0.280512 +vt 0.797327 0.279923 +vt 0.798341 0.279682 +vt 0.935526 0.798115 +vt 0.934136 0.798078 +vt 0.936937 0.798309 +vt 0.937991 0.798607 +vt 0.811798 0.526773 +vt 0.813173 0.527050 +vt 0.810418 0.526477 +vt 0.809404 0.526242 +vt 0.814258 0.177168 +vt 0.815650 0.177148 +vt 0.812846 0.177357 +vt 0.811792 0.177666 +vt 0.794223 0.272732 +vt 0.792856 0.273044 +vt 0.795595 0.272400 +vt 0.796604 0.272136 +vt 0.936224 0.790579 +vt 0.934833 0.790553 +vt 0.937635 0.790776 +vt 0.938688 0.791092 +vt 0.810115 0.534293 +vt 0.811484 0.534596 +vt 0.808741 0.533969 +vt 0.807732 0.533710 +vt 0.814888 0.184809 +vt 0.816280 0.184801 +vt 0.813475 0.184988 +vt 0.812421 0.185290 +vt 0.792384 0.265098 +vt 0.791017 0.265409 +vt 0.793755 0.264761 +vt 0.794761 0.264488 +vt 0.936893 0.782936 +vt 0.935501 0.782921 +vt 0.938305 0.783122 +vt 0.939358 0.783431 +vt 0.808311 0.541983 +vt 0.809681 0.542285 +vt 0.806939 0.541653 +vt 0.805932 0.541385 +vt 0.815426 0.192396 +vt 0.816819 0.192402 +vt 0.814011 0.192549 +vt 0.812954 0.192820 +vt 0.790632 0.257595 +vt 0.789258 0.257877 +vt 0.792007 0.257275 +vt 0.793014 0.257004 +vt 0.937461 0.775446 +vt 0.936068 0.775446 +vt 0.938875 0.775607 +vt 0.939930 0.775884 +vt 0.806587 0.549575 +vt 0.807964 0.549849 +vt 0.805211 0.549264 +vt 0.804204 0.548998 +vt 0.815799 0.199679 +vt 0.817193 0.199702 +vt 0.814382 0.199785 +vt 0.813322 0.199992 +vt 0.789169 0.250496 +vt 0.787783 0.250716 +vt 0.790553 0.250223 +vt 0.791564 0.249968 +vt 0.937859 0.768386 +vt 0.936465 0.768403 +vt 0.939275 0.768499 +vt 0.940334 0.768713 +vt 0.805143 0.556811 +vt 0.806531 0.557022 +vt 0.803758 0.556545 +vt 0.802747 0.556296 +vt 0.815932 0.206429 +vt 0.817327 0.206479 +vt 0.814514 0.206454 +vt 0.813452 0.206546 +vt 0.788195 0.244088 +vt 0.786792 0.244190 +vt 0.789591 0.243903 +vt 0.790607 0.243685 +vt 0.938018 0.762052 +vt 0.936623 0.762095 +vt 0.939436 0.762085 +vt 0.940497 0.762183 +vt 0.804179 0.563439 +vt 0.805583 0.563532 +vt 0.802782 0.563262 +vt 0.801767 0.563049 +vt 0.815739 0.212469 +vt 0.817131 0.212560 +vt 0.814327 0.212347 +vt 0.813274 0.212227 +vt 0.787899 0.238674 +vt 0.786489 0.238558 +vt 0.789301 0.238657 +vt 0.790319 0.238512 +vt 0.937884 0.756792 +vt 0.936490 0.756877 +vt 0.939296 0.756678 +vt 0.940349 0.756565 +vt 0.803907 0.569227 +vt 0.805317 0.569102 +vt 0.802506 0.569218 +vt 0.801488 0.569078 +vt 0.815077 0.217694 +vt 0.816459 0.217858 +vt 0.813704 0.217303 +vt 0.812708 0.216790 +vt 0.788426 0.234590 +vt 0.787089 0.234070 +vt 0.789772 0.234887 +vt 0.936070 0.753185 +vt 0.935049 0.753075 +vt 0.935489 0.756910 +vt 0.937453 0.753027 +vt 0.938828 0.752644 +vt 0.939826 0.752138 +vt 0.804584 0.573976 +vt 0.805919 0.573447 +vt 0.803241 0.574280 +vt 0.817480 0.217751 +vt 0.818132 0.212596 +vt 0.813699 0.221801 +vt 0.815045 0.222064 +vt 0.812461 0.221035 +vt 0.788832 0.230998 +vt 0.788202 0.229863 +vt 0.786117 0.233467 +vt 0.789810 0.232076 +vt 0.790876 0.232810 +vt 0.935485 0.751238 +vt 0.934391 0.750923 +vt 0.936833 0.750981 +vt 0.938074 0.750221 +vt 0.807550 0.576304 +vt 0.808174 0.575165 +vt 0.806888 0.572837 +vt 0.806577 0.577389 +vt 0.805518 0.578128 +vt 0.816140 0.221753 +vt 0.981583 0.897006 +vt 0.980921 0.901424 +vt 0.982323 0.901505 +vt 0.982997 0.897003 +vt 0.980493 0.897476 +vt 0.979889 0.901508 +vt 0.791940 0.229674 +vt 0.791835 0.228274 +vt 0.792356 0.231037 +vt 0.792972 0.231998 +vt 0.564905 0.784419 +vt 0.564827 0.782314 +vt 0.563416 0.782383 +vt 0.563502 0.784730 +vt 0.566310 0.784582 +vt 0.566229 0.782391 +vt 0.567341 0.785174 +vt 0.567246 0.782594 +vt 0.810389 0.577469 +vt 0.810485 0.576068 +vt 0.809981 0.578834 +vt 0.809372 0.579798 +vt 0.983718 0.901730 +vt 0.984357 0.897467 +vt 0.980600 0.905632 +vt 0.982001 0.905720 +vt 0.979585 0.905490 +vt 0.795273 0.229648 +vt 0.795524 0.228234 +vt 0.795282 0.231027 +vt 0.563510 0.779594 +vt 0.562481 0.779414 +vt 0.562372 0.782581 +vt 0.564913 0.779738 +vt 0.566315 0.779809 +vt 0.567341 0.779786 +vt 0.813340 0.577460 +vt 0.813081 0.576047 +vt 0.813340 0.578839 +vt 0.983412 0.905731 +vt 0.984455 0.905663 +vt 0.984734 0.902038 +vt 0.980632 0.909071 +vt 0.982033 0.909156 +vt 0.798603 0.228984 +vt 0.799252 0.227970 +vt 0.795968 0.227164 +vt 0.797994 0.230301 +vt 0.797588 0.231566 +vt 0.563755 0.777570 +vt 0.562772 0.777015 +vt 0.565132 0.777932 +vt 0.566534 0.778005 +vt 0.815018 0.575596 +vt 0.814363 0.574585 +vt 0.812632 0.574978 +vt 0.815635 0.576909 +vt 0.816049 0.578172 +vt 0.983442 0.908948 +vt 0.984482 0.908502 +vt 0.980935 0.911877 +vt 0.982341 0.912008 +vt 0.801115 0.230662 +vt 0.802026 0.229824 +vt 0.800097 0.231702 +vt 0.799245 0.232667 +vt 0.564052 0.776286 +vt 0.563147 0.775367 +vt 0.565390 0.776833 +vt 0.566802 0.776861 +vt 0.816428 0.574650 +vt 0.815513 0.573817 +vt 0.817452 0.575685 +vt 0.818311 0.576644 +vt 0.983731 0.911613 +vt 0.984734 0.910798 +vt 0.072036 0.269173 +vt 0.071954 0.266387 +vt 0.070739 0.266832 +vt 0.070821 0.269695 +vt 0.802922 0.233181 +vt 0.804021 0.232594 +vt 0.801637 0.233865 +vt 0.800508 0.234462 +vt 0.806874 0.129212 +vt 0.806803 0.130735 +vt 0.808101 0.130512 +vt 0.808175 0.128706 +vt 0.805422 0.129203 +vt 0.805352 0.130606 +vt 0.804208 0.128680 +vt 0.804138 0.130159 +vt 0.817626 0.572921 +vt 0.816525 0.572339 +vt 0.818916 0.573597 +vt 0.820049 0.574186 +vt 0.069369 0.269702 +vt 0.069288 0.266959 +vt 0.067990 0.266733 +vt 0.068068 0.269194 +vt 0.071562 0.262923 +vt 0.070337 0.263276 +vt 0.804157 0.236446 +vt 0.805342 0.236071 +vt 0.802760 0.236857 +vt 0.801525 0.237191 +vt 0.806499 0.133273 +vt 0.807779 0.133231 +vt 0.805054 0.133094 +vt 0.803830 0.132741 +vt 0.818656 0.570111 +vt 0.817470 0.569741 +vt 0.820056 0.570512 +vt 0.821294 0.570839 +vt 0.068891 0.263452 +vt 0.067612 0.263406 +vt 0.071027 0.258685 +vt 0.069792 0.258951 +vt 0.805036 0.240567 +vt 0.806254 0.240335 +vt 0.803601 0.240813 +vt 0.802334 0.241009 +vt 0.806020 0.136993 +vt 0.807291 0.137026 +vt 0.804574 0.136819 +vt 0.803340 0.136552 +vt 0.819478 0.566128 +vt 0.818259 0.565903 +vt 0.820914 0.566366 +vt 0.822183 0.566554 +vt 0.068346 0.259122 +vt 0.067075 0.259152 +vt 0.070462 0.253475 +vt 0.069220 0.253667 +vt 0.805705 0.245709 +vt 0.806936 0.245571 +vt 0.804258 0.245868 +vt 0.802982 0.246005 +vt 0.805474 0.141950 +vt 0.806743 0.141997 +vt 0.804024 0.141812 +vt 0.802781 0.141619 +vt 0.820122 0.560938 +vt 0.818891 0.560807 +vt 0.821570 0.561089 +vt 0.822847 0.561218 +vt 0.067769 0.253803 +vt 0.066500 0.253847 +vt 0.069970 0.247119 +vt 0.068722 0.247247 +vt 0.806269 0.252019 +vt 0.807506 0.251942 +vt 0.804818 0.252135 +vt 0.803541 0.252260 +vt 0.804978 0.148211 +vt 0.806248 0.148237 +vt 0.803524 0.148121 +vt 0.802277 0.147992 +vt 0.820661 0.554486 +vt 0.819424 0.554416 +vt 0.822113 0.554593 +vt 0.823391 0.554710 +vt 0.067268 0.247334 +vt 0.065998 0.247357 +vt 0.069656 0.239468 +vt 0.068406 0.239542 +vt 0.806820 0.259622 +vt 0.808060 0.259586 +vt 0.805368 0.259722 +vt 0.804092 0.259860 +vt 0.804651 0.155857 +vt 0.805923 0.155844 +vt 0.803195 0.155822 +vt 0.801945 0.155747 +vt 0.821180 0.546694 +vt 0.819940 0.546665 +vt 0.822633 0.546785 +vt 0.823910 0.546915 +vt 0.066950 0.239575 +vt 0.065677 0.239559 +vt 0.069629 0.230391 +vt 0.068379 0.230417 +vt 0.807447 0.268631 +vt 0.808689 0.268623 +vt 0.805994 0.268732 +vt 0.804721 0.268897 +vt 0.804609 0.164984 +vt 0.805881 0.164923 +vt 0.803152 0.165003 +vt 0.801903 0.164976 +vt 0.821767 0.537474 +vt 0.820525 0.537473 +vt 0.823220 0.537566 +vt 0.824495 0.537724 +vt 0.066923 0.230395 +vt 0.065650 0.230331 +vt 0.070001 0.219763 +vt 0.068753 0.219748 +vt 0.808238 0.279155 +vt 0.809481 0.279165 +vt 0.806786 0.279266 +vt 0.805515 0.279467 +vt 0.804966 0.175693 +vt 0.806236 0.175580 +vt 0.803511 0.175766 +vt 0.802263 0.175781 +vt 0.822511 0.526734 +vt 0.821268 0.526751 +vt 0.823963 0.526836 +vt 0.825236 0.527029 +vt 0.067298 0.219672 +vt 0.066028 0.219556 +vt 0.070891 0.207371 +vt 0.069645 0.207319 +vt 0.809287 0.291368 +vt 0.810533 0.291414 +vt 0.807833 0.291451 +vt 0.806562 0.291641 +vt 0.805831 0.188020 +vt 0.807101 0.187899 +vt 0.804378 0.188119 +vt 0.803131 0.188170 +vt 0.823494 0.514446 +vt 0.822249 0.514498 +vt 0.824948 0.514520 +vt 0.826222 0.514702 +vt 0.068192 0.207218 +vt 0.066922 0.207094 +vt 0.071823 0.193992 +vt 0.070579 0.193903 +vt 0.809776 0.304502 +vt 0.811023 0.304646 +vt 0.808320 0.304453 +vt 0.807046 0.304511 +vt 0.806714 0.200939 +vt 0.807990 0.200915 +vt 0.805259 0.201003 +vt 0.804015 0.201091 +vt 0.823904 0.501567 +vt 0.822658 0.501718 +vt 0.825359 0.501509 +vt 0.826634 0.501559 +vt 0.069125 0.193836 +vt 0.067849 0.193809 +vt 0.072036 0.183412 +vt 0.070792 0.183275 +vt 0.808719 0.314860 +vt 0.809947 0.315167 +vt 0.807290 0.314575 +vt 0.806045 0.314390 +vt 0.806897 0.210684 +vt 0.808175 0.210848 +vt 0.805441 0.210668 +vt 0.804197 0.210804 +vt 0.822851 0.491748 +vt 0.821625 0.492062 +vt 0.824278 0.491455 +vt 0.825523 0.491262 +vt 0.069336 0.183289 +vt 0.068058 0.183449 +vt 0.071618 0.175413 +vt 0.070371 0.175211 +vt 0.806364 0.322658 +vt 0.807523 0.323185 +vt 0.805037 0.322058 +vt 0.803897 0.321545 +vt 0.806534 0.217568 +vt 0.807797 0.217982 +vt 0.805084 0.217445 +vt 0.803837 0.217646 +vt 0.820686 0.484680 +vt 0.819532 0.485213 +vt 0.822009 0.484071 +vt 0.823147 0.483551 +vt 0.068921 0.175332 +vt 0.067657 0.175743 +vt 0.070648 0.169765 +vt 0.069387 0.169488 +vt 0.802936 0.328133 +vt 0.803924 0.328920 +vt 0.801853 0.327158 +vt 0.800966 0.326258 +vt 0.805791 0.221913 +vt 0.807001 0.222619 +vt 0.804365 0.221665 +vt 0.803103 0.221941 +vt 0.817783 0.480071 +vt 0.816801 0.480863 +vt 0.818860 0.479090 +vt 0.819742 0.478184 +vt 0.067960 0.169734 +vt 0.066749 0.170437 +vt 0.210256 0.142347 +vt 0.209707 0.146924 +vt 0.211064 0.146770 +vt 0.211623 0.142104 +vt 0.798696 0.331418 +vt 0.799392 0.332428 +vt 0.798034 0.330124 +vt 0.797581 0.328893 +vt 0.823210 0.789866 +vt 0.822831 0.786775 +vt 0.821703 0.787240 +vt 0.822121 0.790668 +vt 0.824628 0.789539 +vt 0.824267 0.786593 +vt 0.825996 0.789776 +vt 0.825625 0.786742 +vt 0.814477 0.477529 +vt 0.813789 0.478542 +vt 0.815132 0.476231 +vt 0.815578 0.474997 +vt 0.213043 0.142427 +vt 0.212500 0.146949 +vt 0.213631 0.147414 +vt 0.214134 0.143229 +vt 0.209566 0.152100 +vt 0.210920 0.152053 +vt 0.794053 0.332630 +vt 0.794399 0.333734 +vt 0.793892 0.331201 +vt 0.793958 0.329830 +vt 0.822735 0.783426 +vt 0.821594 0.783479 +vt 0.824176 0.783419 +vt 0.825531 0.783460 +vt 0.810959 0.476644 +vt 0.810621 0.477750 +vt 0.811112 0.475215 +vt 0.811038 0.473844 +vt 0.212361 0.152057 +vt 0.213503 0.152111 +vt 0.209772 0.157275 +vt 0.211130 0.157326 +vt 0.789465 0.332029 +vt 0.789502 0.333098 +vt 0.789746 0.330651 +vt 0.790269 0.329334 +vt 0.822870 0.779898 +vt 0.821742 0.779582 +vt 0.824306 0.780047 +vt 0.825664 0.779990 +vt 0.807368 0.477153 +vt 0.807339 0.478220 +vt 0.807079 0.475777 +vt 0.806548 0.474462 +vt 0.212565 0.157174 +vt 0.213694 0.156858 +vt 0.210244 0.162027 +vt 0.211609 0.162155 +vt 0.785282 0.329962 +vt 0.785082 0.330917 +vt 0.785902 0.328748 +vt 0.786775 0.327599 +vt 0.823207 0.776433 +vt 0.822105 0.775830 +vt 0.824631 0.776703 +vt 0.825996 0.776569 +vt 0.803953 0.478875 +vt 0.804161 0.479827 +vt 0.803326 0.477665 +vt 0.802446 0.476521 +vt 0.213033 0.161882 +vt 0.214134 0.161280 +vt 0.210914 0.166066 +vt 0.212289 0.166255 +vt 0.608485 0.216069 +vt 0.607084 0.212662 +vt 0.605834 0.213328 +vt 0.607307 0.216910 +vt 0.782656 0.325759 +vt 0.781779 0.326737 +vt 0.783794 0.324853 +vt 0.787668 0.326823 +vt 0.784889 0.324263 +vt 0.825111 0.773758 +vt 0.823702 0.773395 +vt 0.943568 0.431838 +vt 0.942507 0.434524 +vt 0.943920 0.434756 +vt 0.944960 0.432123 +vt 0.942379 0.431014 +vt 0.941248 0.433875 +vt 0.800155 0.480620 +vt 0.801038 0.481593 +vt 0.799012 0.479721 +vt 0.801550 0.475749 +vt 0.797914 0.479136 +vt 0.213697 0.165888 +vt 0.604685 0.208822 +vt 0.603258 0.209003 +vt 0.604425 0.213580 +vt 0.605993 0.208386 +vt 0.780306 0.321947 +vt 0.779237 0.322609 +vt 0.781641 0.321366 +vt 0.782886 0.321023 +vt 0.943134 0.438013 +vt 0.944296 0.437872 +vt 0.945107 0.434508 +vt 0.941704 0.437853 +vt 0.940390 0.437435 +vt 0.797868 0.484378 +vt 0.798941 0.485034 +vt 0.796529 0.483806 +vt 0.795283 0.483470 +vt 0.602094 0.208880 +vt 0.603234 0.213350 +vt 0.603996 0.203634 +vt 0.602557 0.203722 +vt 0.605342 0.203497 +vt 0.779152 0.317571 +vt 0.777980 0.317817 +vt 0.780595 0.317418 +vt 0.781921 0.317400 +vt 0.942705 0.441578 +vt 0.943852 0.441575 +vt 0.941265 0.441510 +vt 0.939917 0.441391 +vt 0.796761 0.488674 +vt 0.797936 0.488913 +vt 0.795317 0.488530 +vt 0.793992 0.488519 +vt 0.601411 0.203737 +vt 0.603911 0.198318 +vt 0.602471 0.198367 +vt 0.605266 0.198398 +vt 0.779501 0.312837 +vt 0.778340 0.312748 +vt 0.780930 0.313049 +vt 0.782246 0.313327 +vt 0.942732 0.445521 +vt 0.943875 0.445669 +vt 0.941291 0.445493 +vt 0.939937 0.445592 +vt 0.797128 0.493185 +vt 0.798289 0.493089 +vt 0.795699 0.493406 +vt 0.794386 0.493692 +vt 0.601330 0.198533 +vt 0.603878 0.193148 +vt 0.602440 0.193276 +vt 0.605232 0.193215 +vt 0.780789 0.307730 +vt 0.779640 0.307584 +vt 0.782195 0.308053 +vt 0.783483 0.308467 +vt 0.942780 0.450276 +vt 0.943920 0.450548 +vt 0.941340 0.450169 +vt 0.939986 0.450255 +vt 0.798360 0.497882 +vt 0.799509 0.497728 +vt 0.796955 0.498214 +vt 0.795671 0.498635 +vt 0.601303 0.193565 +vt 0.603358 0.188081 +vt 0.601930 0.188321 +vt 0.604702 0.188041 +vt 0.782093 0.302550 +vt 0.780926 0.302477 +vt 0.783505 0.302852 +vt 0.784783 0.303303 +vt 0.942326 0.455431 +vt 0.943459 0.455789 +vt 0.940895 0.455212 +vt 0.939550 0.455191 +vt 0.799593 0.502665 +vt 0.800761 0.502584 +vt 0.798183 0.502976 +vt 0.796909 0.503434 +vt 0.600802 0.188696 +vt 0.602460 0.182930 +vt 0.601045 0.183247 +vt 0.603791 0.182813 +vt 0.783364 0.297371 +vt 0.782183 0.297354 +vt 0.784781 0.297652 +vt 0.786054 0.298123 +vt 0.941489 0.460677 +vt 0.942614 0.461092 +vt 0.940070 0.460381 +vt 0.938737 0.460282 +vt 0.800828 0.507578 +vt 0.802010 0.507553 +vt 0.799412 0.507867 +vt 0.798143 0.508345 +vt 0.599927 0.183678 +vt 0.601299 0.177719 +vt 0.599895 0.178083 +vt 0.602619 0.177551 +vt 0.784577 0.292199 +vt 0.783387 0.292224 +vt 0.785999 0.292459 +vt 0.787271 0.292933 +vt 0.940385 0.465990 +vt 0.941504 0.466433 +vt 0.938976 0.465646 +vt 0.937654 0.465496 +vt 0.802034 0.512596 +vt 0.803226 0.512613 +vt 0.800614 0.512864 +vt 0.799345 0.513346 +vt 0.598782 0.178544 +vt 0.599989 0.172476 +vt 0.598589 0.172858 +vt 0.601302 0.172278 +vt 0.785710 0.287044 +vt 0.784513 0.287099 +vt 0.787137 0.287281 +vt 0.788412 0.287744 +vt 0.939129 0.471343 +vt 0.940247 0.471791 +vt 0.937724 0.470980 +vt 0.936409 0.470801 +vt 0.803185 0.517699 +vt 0.804383 0.517746 +vt 0.801759 0.517944 +vt 0.800488 0.518415 +vt 0.597478 0.173324 +vt 0.598642 0.167225 +vt 0.597240 0.167601 +vt 0.599953 0.167021 +vt 0.786738 0.281919 +vt 0.785538 0.281992 +vt 0.788170 0.282130 +vt 0.789450 0.282568 +vt 0.937835 0.476711 +vt 0.938957 0.477140 +vt 0.936428 0.476355 +vt 0.935114 0.476169 +vt 0.804252 0.522870 +vt 0.805454 0.522935 +vt 0.802821 0.523090 +vt 0.801545 0.523536 +vt 0.596124 0.168048 +vt 0.597371 0.161997 +vt 0.595962 0.162339 +vt 0.598686 0.161807 +vt 0.787638 0.276840 +vt 0.786436 0.276921 +vt 0.789075 0.277022 +vt 0.790362 0.277420 +vt 0.936614 0.482068 +vt 0.937746 0.482454 +vt 0.935200 0.481746 +vt 0.933883 0.481574 +vt 0.805207 0.528096 +vt 0.806411 0.528169 +vt 0.803771 0.528287 +vt 0.802487 0.528692 +vt 0.594835 0.162743 +vt 0.596288 0.156820 +vt 0.594865 0.157100 +vt 0.597610 0.156668 +vt 0.788386 0.271828 +vt 0.787185 0.271907 +vt 0.789828 0.271978 +vt 0.791124 0.272317 +vt 0.935581 0.487387 +vt 0.936727 0.487701 +vt 0.934155 0.487128 +vt 0.932831 0.486994 +vt 0.806024 0.533367 +vt 0.807227 0.533438 +vt 0.804582 0.533525 +vt 0.803290 0.533871 +vt 0.593724 0.157431 +vt 0.595501 0.151725 +vt 0.594065 0.151908 +vt 0.596833 0.151637 +vt 0.788959 0.266908 +vt 0.787759 0.266973 +vt 0.790406 0.267020 +vt 0.791711 0.267277 +vt 0.934848 0.492640 +vt 0.936007 0.492851 +vt 0.933409 0.492478 +vt 0.932076 0.492408 +vt 0.806672 0.538676 +vt 0.807873 0.538733 +vt 0.805226 0.538797 +vt 0.803923 0.539062 +vt 0.592908 0.152137 +vt 0.595118 0.146743 +vt 0.593672 0.146791 +vt 0.596457 0.146749 +vt 0.789337 0.262105 +vt 0.788139 0.262143 +vt 0.790787 0.262171 +vt 0.792100 0.262323 +vt 0.934526 0.497799 +vt 0.935694 0.497870 +vt 0.933080 0.497772 +vt 0.931742 0.497796 +vt 0.807122 0.544021 +vt 0.808321 0.544050 +vt 0.805672 0.544096 +vt 0.804361 0.544255 +vt 0.592506 0.146880 +vt 0.595243 0.141902 +vt 0.593802 0.141774 +vt 0.596577 0.142033 +vt 0.789500 0.257442 +vt 0.788303 0.257437 +vt 0.790951 0.257455 +vt 0.792269 0.257473 +vt 0.934729 0.502836 +vt 0.935888 0.502728 +vt 0.933291 0.502985 +vt 0.931959 0.503134 +vt 0.807340 0.549392 +vt 0.808537 0.549379 +vt 0.805888 0.549414 +vt 0.804572 0.549440 +vt 0.592642 0.141684 +vt 0.595992 0.137131 +vt 0.594576 0.136836 +vt 0.597306 0.137396 +vt 0.789426 0.252821 +vt 0.788229 0.252751 +vt 0.790877 0.252812 +vt 0.792195 0.252728 +vt 0.935559 0.507676 +vt 0.936693 0.507413 +vt 0.934148 0.507991 +vt 0.932838 0.508274 +vt 0.807296 0.554663 +vt 0.808494 0.554586 +vt 0.805845 0.554664 +vt 0.804528 0.554586 +vt 0.593439 0.136591 +vt 0.597444 0.131499 +vt 0.596054 0.131103 +vt 0.598730 0.131879 +vt 0.789342 0.247291 +vt 0.788145 0.247121 +vt 0.790793 0.247339 +vt 0.792111 0.247252 +vt 0.937038 0.513081 +vt 0.938156 0.512759 +vt 0.935653 0.513496 +vt 0.934373 0.513894 +vt 0.807249 0.560520 +vt 0.808446 0.560342 +vt 0.805798 0.560577 +vt 0.804481 0.560497 +vt 0.594931 0.130798 +vt 0.599005 0.126574 +vt 0.597637 0.126108 +vt 0.600254 0.127071 +vt 0.789594 0.242488 +vt 0.788405 0.242184 +vt 0.791039 0.242649 +vt 0.792352 0.242623 +vt 0.938531 0.517574 +vt 0.939647 0.517246 +vt 0.937170 0.518060 +vt 0.935928 0.518573 +vt 0.807541 0.565477 +vt 0.808729 0.565165 +vt 0.806097 0.565647 +vt 0.804784 0.565628 +vt 0.596516 0.125798 +vt 0.600642 0.122399 +vt 0.599306 0.121850 +vt 0.601835 0.123036 +vt 0.790160 0.238478 +vt 0.788996 0.238008 +vt 0.791584 0.238781 +vt 0.792886 0.238836 +vt 0.940017 0.521217 +vt 0.941132 0.520886 +vt 0.938690 0.521785 +vt 0.937506 0.522438 +vt 0.808161 0.569660 +vt 0.809323 0.569182 +vt 0.806738 0.569972 +vt 0.805438 0.570033 +vt 0.598187 0.121537 +vt 0.602351 0.118935 +vt 0.601064 0.118291 +vt 0.603461 0.119738 +vt 0.791019 0.235232 +vt 0.789910 0.234559 +vt 0.792395 0.235710 +vt 0.793669 0.235867 +vt 0.941454 0.524035 +vt 0.942569 0.523705 +vt 0.940176 0.524698 +vt 0.939078 0.525517 +vt 0.809097 0.573097 +vt 0.810202 0.572417 +vt 0.807724 0.573584 +vt 0.806452 0.573748 +vt 0.599944 0.117978 +vt 0.604134 0.116158 +vt 0.602914 0.115409 +vt 0.605122 0.117149 +vt 0.792148 0.232714 +vt 0.791148 0.231808 +vt 0.793429 0.233399 +vt 0.794645 0.233679 +vt 0.942797 0.526073 +vt 0.943916 0.525749 +vt 0.941588 0.526839 +vt 0.940614 0.527843 +vt 0.810340 0.575813 +vt 0.811336 0.574901 +vt 0.809064 0.576505 +vt 0.807850 0.576791 +vt 0.601790 0.115103 +vt 0.605981 0.114075 +vt 0.604851 0.113228 +vt 0.606805 0.115249 +vt 0.793526 0.230884 +vt 0.792709 0.229740 +vt 0.794643 0.231781 +vt 0.795759 0.232190 +vt 0.997834 0.197127 +vt 0.997547 0.195693 +vt 0.996102 0.195817 +vt 0.996391 0.197264 +vt 0.942893 0.528278 +vt 0.944011 0.527413 +vt 0.942085 0.529462 +vt 0.811879 0.577824 +vt 0.812690 0.576674 +vt 0.810768 0.578727 +vt 0.809655 0.579142 +vt 0.051939 0.015849 +vt 0.051410 0.018178 +vt 0.052850 0.018345 +vt 0.053377 0.016028 +vt 0.050164 0.018490 +vt 0.049737 0.021094 +vt 0.050960 0.020924 +vt 0.608485 0.114040 +vt 0.607854 0.112728 +vt 0.795142 0.229692 +vt 0.794587 0.228357 +vt 0.796021 0.230762 +vt 0.995893 0.194285 +vt 0.994603 0.194666 +vt 0.994836 0.196384 +vt 0.997341 0.194185 +vt 0.944091 0.529118 +vt 0.945107 0.528183 +vt 0.943479 0.530439 +vt 0.813692 0.579139 +vt 0.814239 0.577801 +vt 0.812820 0.580214 +vt 0.052404 0.021065 +vt 0.053683 0.021482 +vt 0.054100 0.018945 +vt 0.049420 0.023992 +vt 0.050626 0.023973 +vt 0.796749 0.227666 +vt 0.796917 0.226342 +vt 0.794506 0.227115 +vt 0.796998 0.229100 +vt 0.797597 0.230261 +vt 0.995757 0.192604 +vt 0.994450 0.192770 +vt 0.997208 0.192542 +vt 0.998559 0.194395 +vt 0.998414 0.192599 +vt 0.815985 0.578344 +vt 0.815810 0.577021 +vt 0.814314 0.576557 +vt 0.815745 0.579780 +vt 0.815154 0.580943 +vt 0.052075 0.024077 +vt 0.053377 0.024278 +vt 0.049238 0.027059 +vt 0.050437 0.027173 +vt 0.799143 0.227646 +vt 0.799546 0.226318 +vt 0.799098 0.229086 +vt 0.799424 0.230252 +vt 0.995699 0.190680 +vt 0.994385 0.190636 +vt 0.997151 0.190661 +vt 0.998353 0.190586 +vt 0.817947 0.578342 +vt 0.817536 0.577016 +vt 0.818000 0.579782 +vt 0.817682 0.580949 +vt 0.051888 0.027234 +vt 0.053203 0.027225 +vt 0.049203 0.030207 +vt 0.050400 0.030421 +vt 0.801724 0.228253 +vt 0.802320 0.226967 +vt 0.801435 0.229638 +vt 0.801529 0.230752 +vt 0.995739 0.188467 +vt 0.994428 0.188246 +vt 0.997191 0.188493 +vt 0.998394 0.188317 +vt 0.820135 0.577809 +vt 0.819532 0.576527 +vt 0.820434 0.579192 +vt 0.820347 0.580306 +vt 0.051852 0.030438 +vt 0.053169 0.030252 +vt 0.049320 0.033401 +vt 0.050519 0.033685 +vt 0.804468 0.229434 +vt 0.805210 0.228210 +vt 0.803988 0.230739 +vt 0.803899 0.231777 +vt 0.995902 0.185987 +vt 0.994600 0.185625 +vt 0.997351 0.186055 +vt 0.998559 0.185810 +vt 0.822544 0.576751 +vt 0.821795 0.575531 +vt 0.823032 0.578053 +vt 0.823129 0.579088 +vt 0.051969 0.033660 +vt 0.053281 0.033333 +vt 0.808238 0.230006 +vt 0.809103 0.229227 +vt 0.806015 0.227396 +vt 0.807364 0.231150 +vt 0.806714 0.232354 +vt 0.806463 0.233293 +vt 0.996203 0.183347 +vt 0.994915 0.182865 +vt 0.997649 0.183447 +vt 0.824269 0.574047 +vt 0.823402 0.573272 +vt 0.820987 0.574720 +vt 0.825150 0.575186 +vt 0.825808 0.576385 +vt 0.826067 0.577322 +vt 0.052249 0.036955 +vt 0.053551 0.036508 +vt 0.050801 0.037012 +vt 0.812220 0.233215 +vt 0.813179 0.232517 +vt 0.811165 0.234207 +vt 0.810296 0.235226 +vt 0.946463 0.774048 +vt 0.947710 0.776791 +vt 0.948884 0.776032 +vt 0.947564 0.773120 +vt 0.996756 0.179923 +vt 0.995488 0.179311 +vt 0.998198 0.180040 +vt 0.827595 0.571358 +vt 0.826632 0.570664 +vt 0.828656 0.572344 +vt 0.829531 0.573357 +vt 0.297328 0.115036 +vt 0.295809 0.118211 +vt 0.296965 0.118996 +vt 0.298409 0.115988 +vt 0.052815 0.041221 +vt 0.054100 0.040644 +vt 0.051370 0.041295 +vt 0.814914 0.236689 +vt 0.815993 0.236148 +vt 0.813647 0.237399 +vt 0.812531 0.238088 +vt 0.948249 0.779385 +vt 0.949480 0.778917 +vt 0.946294 0.777099 +vt 0.946799 0.779522 +vt 0.945014 0.776874 +vt 0.945518 0.779289 +vt 0.829583 0.568791 +vt 0.828502 0.568256 +vt 0.830854 0.569493 +vt 0.831976 0.570175 +vt 0.295019 0.121671 +vt 0.296239 0.122168 +vt 0.294400 0.117872 +vt 0.293573 0.121503 +vt 0.293115 0.118070 +vt 0.292287 0.121708 +vt 0.816351 0.240367 +vt 0.817517 0.240050 +vt 0.814937 0.240698 +vt 0.813651 0.240952 +vt 0.948277 0.781884 +vt 0.949513 0.781790 +vt 0.946824 0.781807 +vt 0.945543 0.781581 +vt 0.830549 0.566277 +vt 0.829383 0.565966 +vt 0.831966 0.566599 +vt 0.833254 0.566845 +vt 0.294892 0.125374 +vt 0.296126 0.125496 +vt 0.293438 0.125419 +vt 0.292152 0.125618 +vt 0.816643 0.244073 +vt 0.817829 0.243984 +vt 0.815194 0.244033 +vt 0.813871 0.243875 +vt 0.947929 0.784459 +vt 0.949123 0.784711 +vt 0.946498 0.784198 +vt 0.945214 0.783996 +vt 0.830727 0.563632 +vt 0.829542 0.563549 +vt 0.832176 0.563583 +vt 0.833499 0.563416 +vt 0.295302 0.129155 +vt 0.296502 0.128931 +vt 0.293866 0.129385 +vt 0.292578 0.129559 +vt 0.816041 0.247682 +vt 0.817200 0.247774 +vt 0.814633 0.247368 +vt 0.813353 0.246915 +vt 0.947281 0.787255 +vt 0.948424 0.787741 +vt 0.945875 0.786880 +vt 0.944583 0.786718 +vt 0.830211 0.560723 +vt 0.829053 0.560821 +vt 0.831617 0.560401 +vt 0.832894 0.559940 +vt 0.296065 0.132877 +vt 0.297218 0.132418 +vt 0.294650 0.133221 +vt 0.293354 0.133356 +vt 0.814814 0.251202 +vt 0.815931 0.251422 +vt 0.813463 0.250714 +vt 0.812241 0.250089 +vt 0.946424 0.790286 +vt 0.947533 0.790898 +vt 0.945029 0.789867 +vt 0.943724 0.789752 +vt 0.829077 0.557553 +vt 0.827962 0.557779 +vt 0.830424 0.557057 +vt 0.831643 0.556424 +vt 0.297004 0.136533 +vt 0.298126 0.135947 +vt 0.295601 0.136921 +vt 0.294293 0.137008 +vt 0.813178 0.254682 +vt 0.814254 0.254992 +vt 0.811873 0.254094 +vt 0.810689 0.253384 +vt 0.945477 0.793516 +vt 0.946574 0.794173 +vt 0.944082 0.793103 +vt 0.942761 0.793042 +vt 0.827456 0.554163 +vt 0.826382 0.554478 +vt 0.828757 0.553567 +vt 0.829937 0.552850 +vt 0.297977 0.140166 +vt 0.299087 0.139535 +vt 0.296572 0.140549 +vt 0.295250 0.140581 +vt 0.811319 0.258155 +vt 0.812361 0.258529 +vt 0.810040 0.257518 +vt 0.808865 0.256790 +vt 0.944578 0.796916 +vt 0.945679 0.797556 +vt 0.943170 0.796548 +vt 0.941833 0.796552 +vt 0.825508 0.550578 +vt 0.824470 0.550958 +vt 0.826784 0.549934 +vt 0.827954 0.549198 +vt 0.298853 0.143815 +vt 0.299967 0.143200 +vt 0.297437 0.144151 +vt 0.296100 0.144118 +vt 0.809411 0.261629 +vt 0.810427 0.262053 +vt 0.808135 0.260986 +vt 0.806941 0.260295 +vt 0.943864 0.800471 +vt 0.944978 0.801040 +vt 0.942440 0.800190 +vt 0.941088 0.800271 +vt 0.823407 0.546800 +vt 0.822395 0.547229 +vt 0.824679 0.546149 +vt 0.825869 0.545451 +vt 0.299506 0.147500 +vt 0.300633 0.146957 +vt 0.298076 0.147750 +vt 0.296726 0.147639 +vt 0.807623 0.265099 +vt 0.808620 0.265560 +vt 0.806330 0.264489 +vt 0.805088 0.263893 +vt 0.943476 0.804183 +vt 0.944603 0.804621 +vt 0.942039 0.804033 +vt 0.940678 0.804212 +vt 0.821329 0.542816 +vt 0.820336 0.543281 +vt 0.822618 0.542198 +vt 0.823857 0.541594 +vt 0.299812 0.151230 +vt 0.300948 0.150818 +vt 0.298373 0.151348 +vt 0.297015 0.151139 +vt 0.806110 0.268553 +vt 0.807096 0.269041 +vt 0.804785 0.268019 +vt 0.803475 0.267582 +vt 0.943557 0.808058 +vt 0.944678 0.808298 +vt 0.942126 0.808092 +vt 0.940768 0.808394 +vt 0.819465 0.538605 +vt 0.818483 0.539098 +vt 0.820786 0.538064 +vt 0.822094 0.537618 +vt 0.299650 0.155007 +vt 0.300776 0.154792 +vt 0.298220 0.154940 +vt 0.296869 0.154609 +vt 0.804969 0.272123 +vt 0.805962 0.272588 +vt 0.803605 0.271713 +vt 0.802236 0.271466 +vt 0.944260 0.812145 +vt 0.945349 0.812179 +vt 0.942854 0.812348 +vt 0.941509 0.812733 +vt 0.818064 0.534293 +vt 0.817075 0.534762 +vt 0.819425 0.533874 +vt 0.820794 0.533619 +vt 0.298908 0.158789 +vt 0.299997 0.158781 +vt 0.297507 0.158555 +vt 0.296171 0.158141 +vt 0.804193 0.276341 +vt 0.805206 0.276702 +vt 0.802801 0.276084 +vt 0.801401 0.275998 +vt 0.945364 0.816806 +vt 0.946427 0.816714 +vt 0.943971 0.817065 +vt 0.942620 0.817423 +vt 0.817193 0.529713 +vt 0.816184 0.530079 +vt 0.818584 0.529447 +vt 0.819984 0.529353 +vt 0.297821 0.162915 +vt 0.298881 0.163032 +vt 0.296434 0.162624 +vt 0.295091 0.162237 +vt 0.803866 0.280868 +vt 0.804888 0.281096 +vt 0.802462 0.280756 +vt 0.801053 0.280792 +vt 0.946358 0.821670 +vt 0.947408 0.821514 +vt 0.944963 0.821918 +vt 0.943595 0.822193 +vt 0.816831 0.525083 +vt 0.815811 0.525316 +vt 0.818234 0.524964 +vt 0.819644 0.524990 +vt 0.296846 0.167200 +vt 0.297892 0.167380 +vt 0.295456 0.166920 +vt 0.294095 0.166616 +vt 0.803954 0.285591 +vt 0.804975 0.285704 +vt 0.802552 0.285603 +vt 0.801145 0.285738 +vt 0.947220 0.826674 +vt 0.948261 0.826469 +vt 0.945821 0.826906 +vt 0.944440 0.827106 +vt 0.816893 0.520293 +vt 0.815874 0.520411 +vt 0.818295 0.520297 +vt 0.819704 0.520424 +vt 0.295967 0.171706 +vt 0.297003 0.171935 +vt 0.294574 0.171442 +vt 0.293198 0.171213 +vt 0.292207 0.171080 +vt 0.291401 0.175992 +vt 0.292408 0.176028 +vt 0.803012 0.290623 +vt 0.804406 0.290510 +vt 0.801611 0.290835 +vt 0.947947 0.831814 +vt 0.948983 0.831577 +vt 0.946546 0.832028 +vt 0.945155 0.832160 +vt 0.943447 0.827218 +vt 0.944148 0.832175 +vt 0.818711 0.515447 +vt 0.817318 0.515342 +vt 0.820114 0.515651 +vt 0.295191 0.176435 +vt 0.296222 0.176697 +vt 0.293795 0.176190 +vt 0.290714 0.181101 +vt 0.291731 0.181058 +vt 0.803782 0.295814 +vt 0.805164 0.295623 +vt 0.802389 0.296083 +vt 0.800578 0.291090 +vt 0.801359 0.296358 +vt 0.947134 0.837284 +vt 0.948538 0.837093 +vt 0.945737 0.837357 +vt 0.944721 0.837293 +vt 0.819428 0.510414 +vt 0.818045 0.510230 +vt 0.820823 0.510674 +vt 0.821150 0.515899 +vt 0.821856 0.510941 +vt 0.293127 0.181161 +vt 0.294526 0.181383 +vt 0.806173 0.300927 +vt 0.807162 0.300801 +vt 0.806165 0.295560 +vt 0.804802 0.301177 +vt 0.803416 0.301484 +vt 0.802387 0.301765 +vt 0.947587 0.842678 +vt 0.948993 0.842513 +vt 0.946185 0.842700 +vt 0.945164 0.842572 +vt 0.820389 0.505198 +vt 0.819017 0.504956 +vt 0.821776 0.505496 +vt 0.822808 0.505771 +vt 0.292576 0.186350 +vt 0.293977 0.186547 +vt 0.291175 0.186298 +vt 0.807375 0.306421 +vt 0.808354 0.306246 +vt 0.806013 0.306711 +vt 0.804632 0.307040 +vt 0.803602 0.307317 +vt 0.947901 0.848214 +vt 0.949308 0.848077 +vt 0.946497 0.848191 +vt 0.945472 0.848014 +vt 0.821537 0.499801 +vt 0.820173 0.499518 +vt 0.822920 0.500121 +vt 0.823953 0.500391 +vt 0.292149 0.191752 +vt 0.293553 0.191921 +vt 0.290745 0.191744 +vt 0.289717 0.191900 +vt 0.289417 0.197586 +vt 0.290447 0.197394 +vt 0.807357 0.312418 +vt 0.808714 0.312102 +vt 0.805978 0.312753 +vt 0.804945 0.313017 +vt 0.948074 0.853895 +vt 0.949483 0.853788 +vt 0.946669 0.853833 +vt 0.945644 0.853620 +vt 0.822815 0.494225 +vt 0.821458 0.493917 +vt 0.824197 0.494551 +vt 0.825233 0.494807 +vt 0.291853 0.197362 +vt 0.293259 0.197501 +vt 0.289257 0.203461 +vt 0.290287 0.203242 +vt 0.808776 0.318297 +vt 0.810130 0.317971 +vt 0.807395 0.318625 +vt 0.806356 0.318866 +vt 0.948105 0.859723 +vt 0.949513 0.859649 +vt 0.946699 0.859628 +vt 0.945674 0.859388 +vt 0.824168 0.488470 +vt 0.822812 0.488151 +vt 0.825551 0.488790 +vt 0.826592 0.489024 +vt 0.291694 0.203177 +vt 0.293101 0.203283 +vt 0.289240 0.209524 +vt 0.290271 0.209289 +vt 0.810211 0.324349 +vt 0.811565 0.324024 +vt 0.808825 0.324658 +vt 0.807779 0.324868 +vt 0.947989 0.865700 +vt 0.949397 0.865661 +vt 0.946584 0.865575 +vt 0.945559 0.865319 +vt 0.825536 0.482539 +vt 0.824181 0.482222 +vt 0.826924 0.482840 +vt 0.827972 0.483042 +vt 0.291678 0.209194 +vt 0.293084 0.209265 +vt 0.289372 0.215772 +vt 0.290402 0.215530 +vt 0.811603 0.330574 +vt 0.812961 0.330263 +vt 0.810211 0.330853 +vt 0.809157 0.331024 +vt 0.947724 0.871827 +vt 0.949130 0.871825 +vt 0.946320 0.871675 +vt 0.945295 0.871412 +vt 0.826864 0.476433 +vt 0.825506 0.476129 +vt 0.828258 0.476703 +vt 0.829315 0.476867 +vt 0.291809 0.215410 +vt 0.293215 0.215443 +vt 0.289662 0.222303 +vt 0.290694 0.222079 +vt 0.812905 0.337026 +vt 0.814274 0.336781 +vt 0.811495 0.337207 +vt 0.810422 0.337275 +vt 0.947315 0.878003 +vt 0.948715 0.878082 +vt 0.945914 0.877816 +vt 0.944888 0.877571 +vt 0.828086 0.470206 +vt 0.826715 0.469969 +vt 0.829497 0.470378 +vt 0.830572 0.470439 +vt 0.292099 0.221923 +vt 0.293500 0.221876 +vt 0.290365 0.228943 +vt 0.291405 0.228785 +vt 0.813522 0.343468 +vt 0.814904 0.343407 +vt 0.812095 0.343397 +vt 0.811005 0.343214 +vt 0.946589 0.883754 +vt 0.947963 0.884018 +vt 0.945198 0.883499 +vt 0.944162 0.883320 +vt 0.828632 0.464269 +vt 0.827251 0.464215 +vt 0.830059 0.464189 +vt 0.831149 0.463997 +vt 0.292802 0.228560 +vt 0.294181 0.228327 +vt 0.291627 0.234510 +vt 0.292691 0.234454 +vt 0.812839 0.348753 +vt 0.814183 0.348963 +vt 0.811464 0.348313 +vt 0.810426 0.347762 +vt 0.945530 0.888021 +vt 0.946835 0.888552 +vt 0.944163 0.887669 +vt 0.943102 0.887591 +vt 0.828023 0.459718 +vt 0.826682 0.459935 +vt 0.829396 0.459270 +vt 0.830432 0.458711 +vt 0.294065 0.234132 +vt 0.295382 0.233631 +vt 0.293353 0.238883 +vt 0.294458 0.238930 +vt 0.811031 0.352835 +vt 0.812249 0.353324 +vt 0.809827 0.352017 +vt 0.808959 0.351088 +vt 0.944260 0.891050 +vt 0.945450 0.891854 +vt 0.942936 0.890601 +vt 0.941830 0.890625 +vt 0.826531 0.456394 +vt 0.825317 0.456889 +vt 0.827730 0.455568 +vt 0.828593 0.454633 +vt 0.295792 0.238509 +vt 0.296999 0.237732 +vt 0.997826 0.222146 +vt 0.997460 0.218704 +vt 0.996028 0.218917 +vt 0.996404 0.222451 +vt 0.808327 0.355687 +vt 0.809335 0.356398 +vt 0.807408 0.354567 +vt 0.806825 0.353337 +vt 0.942860 0.893053 +vt 0.943899 0.894073 +vt 0.941589 0.892526 +vt 0.997075 0.748967 +vt 0.996792 0.751254 +vt 0.998221 0.751490 +vt 0.998492 0.749297 +vt 0.824373 0.454151 +vt 0.823371 0.454867 +vt 0.825285 0.453026 +vt 0.825862 0.451792 +vt 0.297844 0.241597 +vt 0.298905 0.240600 +vt 0.296562 0.242097 +vt 0.997248 0.214609 +vt 0.995810 0.214714 +vt 0.998576 0.218134 +vt 0.998379 0.214329 +vt 0.804431 0.356022 +vt 0.805008 0.357313 +vt 0.804189 0.354622 +vt 0.941370 0.894182 +vt 0.942254 0.895323 +vt 0.998040 0.754128 +vt 0.999401 0.754054 +vt 0.999589 0.751315 +vt 0.996604 0.754000 +vt 0.995686 0.750668 +vt 0.995478 0.753704 +vt 0.822286 0.451585 +vt 0.821718 0.452879 +vt 0.822521 0.450183 +vt 0.300039 0.243359 +vt 0.300948 0.242238 +vt 0.994451 0.214615 +vt 0.994663 0.218716 +vt 0.997183 0.210216 +vt 0.995744 0.210214 +vt 0.998318 0.210220 +vt 0.801120 0.356440 +vt 0.801353 0.357777 +vt 0.801219 0.354994 +vt 0.804345 0.353488 +vt 0.801623 0.353827 +vt 0.997946 0.757088 +vt 0.999304 0.757114 +vt 0.996507 0.757066 +vt 0.995371 0.757055 +vt 0.818958 0.451187 +vt 0.818733 0.452525 +vt 0.818850 0.449742 +vt 0.822359 0.449049 +vt 0.818440 0.448576 +vt 0.994386 0.210215 +vt 0.997255 0.205813 +vt 0.995817 0.205712 +vt 0.998386 0.206079 +vt 0.797698 0.355878 +vt 0.797610 0.357164 +vt 0.798117 0.354483 +vt 0.798754 0.353353 +vt 0.997945 0.760169 +vt 0.999303 0.760286 +vt 0.996505 0.760246 +vt 0.995370 0.760498 +vt 0.815523 0.451774 +vt 0.815621 0.453059 +vt 0.815096 0.450382 +vt 0.814453 0.449255 +vt 0.994458 0.205804 +vt 0.997457 0.201645 +vt 0.996023 0.201454 +vt 0.998576 0.202153 +vt 0.794390 0.354393 +vt 0.794001 0.355545 +vt 0.795106 0.353133 +vt 0.795959 0.352100 +vt 0.998038 0.763124 +vt 0.999398 0.763324 +vt 0.996601 0.763292 +vt 0.995473 0.763784 +vt 0.812208 0.453286 +vt 0.812604 0.454434 +vt 0.811484 0.452030 +vt 0.810625 0.451002 +vt 0.994660 0.201629 +vt 0.997783 0.197966 +vt 0.996356 0.197691 +vt 0.930326 0.291989 +vt 0.929145 0.289345 +vt 0.927787 0.289859 +vt 0.929041 0.292671 +vt 0.791419 0.352045 +vt 0.790755 0.352976 +vt 0.792409 0.351002 +vt 0.793461 0.350128 +vt 0.998223 0.765709 +vt 0.999589 0.765984 +vt 0.996793 0.765959 +vt 0.937099 0.604355 +vt 0.936178 0.606581 +vt 0.937551 0.607056 +vt 0.938402 0.604998 +vt 0.809235 0.455666 +vt 0.809906 0.456592 +vt 0.808238 0.454630 +vt 0.807182 0.453761 +vt 0.994986 0.197941 +vt 0.927084 0.286113 +vt 0.925679 0.286028 +vt 0.926399 0.289863 +vt 0.928485 0.285831 +vt 0.789009 0.348889 +vt 0.788111 0.349511 +vt 0.790231 0.348153 +vt 0.791451 0.347501 +vt 0.794291 0.349656 +vt 0.792341 0.347107 +vt 0.937124 0.609740 +vt 0.938525 0.609613 +vt 0.938938 0.607018 +vt 0.935715 0.609498 +vt 0.806830 0.458854 +vt 0.807733 0.459470 +vt 0.805602 0.458126 +vt 0.804380 0.457481 +vt 0.806350 0.453293 +vt 0.803489 0.457091 +vt 0.927065 0.281530 +vt 0.925660 0.281338 +vt 0.928467 0.281529 +vt 0.787383 0.344984 +vt 0.786327 0.345228 +vt 0.788761 0.344624 +vt 0.790093 0.344244 +vt 0.791022 0.343945 +vt 0.937206 0.613020 +vt 0.938604 0.612786 +vt 0.935804 0.613059 +vt 0.805217 0.462792 +vt 0.806275 0.463028 +vt 0.803836 0.462441 +vt 0.802502 0.462068 +vt 0.801573 0.461774 +vt 0.927811 0.276398 +vt 0.926413 0.276144 +vt 0.929188 0.276603 +vt 0.786755 0.340335 +vt 0.785651 0.340282 +vt 0.788184 0.340282 +vt 0.789555 0.340136 +vt 0.939328 0.616756 +vt 0.940365 0.616489 +vt 0.939626 0.612420 +vt 0.937939 0.617051 +vt 0.936569 0.617296 +vt 0.804630 0.467369 +vt 0.805736 0.467308 +vt 0.803201 0.467324 +vt 0.801829 0.467186 +vt 0.925370 0.275910 +vt 0.924629 0.281004 +vt 0.929025 0.269899 +vt 0.927621 0.269686 +vt 0.930398 0.270130 +vt 0.786815 0.333904 +vt 0.785709 0.333764 +vt 0.788246 0.333974 +vt 0.789620 0.333957 +vt 0.940644 0.622759 +vt 0.941699 0.622589 +vt 0.939246 0.623013 +vt 0.937881 0.623284 +vt 0.804733 0.473519 +vt 0.805840 0.473372 +vt 0.803302 0.473599 +vt 0.801929 0.473589 +vt 0.926561 0.269550 +vt 0.929825 0.263734 +vt 0.928410 0.263612 +vt 0.931206 0.263905 +vt 0.787106 0.327635 +vt 0.786000 0.327509 +vt 0.788536 0.327742 +vt 0.789906 0.327801 +vt 0.941603 0.628764 +vt 0.942673 0.628690 +vt 0.940191 0.628928 +vt 0.938816 0.629139 +vt 0.805043 0.479411 +vt 0.806150 0.479278 +vt 0.803614 0.479527 +vt 0.802245 0.479594 +vt 0.927337 0.263571 +vt 0.930273 0.257743 +vt 0.928851 0.257706 +vt 0.931658 0.257858 +vt 0.787605 0.321557 +vt 0.786497 0.321444 +vt 0.789031 0.321699 +vt 0.790395 0.321832 +vt 0.942212 0.634609 +vt 0.943292 0.634627 +vt 0.940791 0.634688 +vt 0.939411 0.634842 +vt 0.805547 0.485130 +vt 0.806655 0.485009 +vt 0.804121 0.485281 +vt 0.802759 0.485421 +vt 0.927772 0.257758 +vt 0.930410 0.251902 +vt 0.928986 0.251944 +vt 0.931796 0.251965 +vt 0.788290 0.315648 +vt 0.787181 0.315545 +vt 0.789712 0.315824 +vt 0.791068 0.316025 +vt 0.942513 0.640320 +vt 0.943598 0.640423 +vt 0.941088 0.640320 +vt 0.939705 0.640423 +vt 0.806228 0.490707 +vt 0.807337 0.490596 +vt 0.804806 0.490891 +vt 0.803452 0.491100 +vt 0.927905 0.252080 +vt 0.930279 0.246189 +vt 0.928856 0.246300 +vt 0.931664 0.246207 +vt 0.789140 0.309885 +vt 0.788031 0.309790 +vt 0.790559 0.310091 +vt 0.791906 0.310354 +vt 0.942549 0.645923 +vt 0.943634 0.646101 +vt 0.941123 0.645853 +vt 0.939740 0.645911 +vt 0.807068 0.496176 +vt 0.808179 0.496074 +vt 0.805651 0.496391 +vt 0.804306 0.496661 +vt 0.927777 0.246512 +vt 0.929923 0.240578 +vt 0.928504 0.240748 +vt 0.931306 0.240559 +vt 0.790136 0.304243 +vt 0.789026 0.304154 +vt 0.791550 0.304476 +vt 0.792888 0.304791 +vt 0.942361 0.651441 +vt 0.943444 0.651684 +vt 0.940937 0.651313 +vt 0.939555 0.651334 +vt 0.808053 0.501568 +vt 0.809164 0.501471 +vt 0.806640 0.501810 +vt 0.805305 0.502133 +vt 0.927428 0.241024 +vt 0.929385 0.235045 +vt 0.927971 0.235261 +vt 0.930765 0.234997 +vt 0.791256 0.298696 +vt 0.790145 0.298610 +vt 0.792665 0.298953 +vt 0.793994 0.299311 +vt 0.941991 0.656902 +vt 0.943071 0.657197 +vt 0.940570 0.656727 +vt 0.939190 0.656719 +vt 0.809164 0.506912 +vt 0.810277 0.506818 +vt 0.807757 0.507177 +vt 0.806431 0.507543 +vt 0.926900 0.235590 +vt 0.928708 0.229564 +vt 0.927297 0.229815 +vt 0.930086 0.229496 +vt 0.792480 0.293217 +vt 0.791368 0.293132 +vt 0.793885 0.293493 +vt 0.795206 0.293886 +vt 0.941481 0.662330 +vt 0.942557 0.662665 +vt 0.940064 0.662120 +vt 0.938685 0.662092 +vt 0.810386 0.512237 +vt 0.811498 0.512144 +vt 0.808983 0.512522 +vt 0.807664 0.512922 +vt 0.926232 0.230183 +vt 0.927934 0.224110 +vt 0.926526 0.224383 +vt 0.929310 0.224030 +vt 0.793787 0.287779 +vt 0.792676 0.287692 +vt 0.795188 0.288071 +vt 0.796504 0.288487 +vt 0.940874 0.667750 +vt 0.941947 0.668111 +vt 0.939459 0.667518 +vt 0.938081 0.667479 +vt 0.811700 0.517571 +vt 0.812812 0.517475 +vt 0.810301 0.517871 +vt 0.808988 0.518295 +vt 0.925464 0.224777 +vt 0.927105 0.218655 +vt 0.925699 0.218939 +vt 0.928481 0.218573 +vt 0.795158 0.282354 +vt 0.794048 0.282262 +vt 0.796556 0.282656 +vt 0.797868 0.283087 +vt 0.940210 0.673187 +vt 0.941281 0.673563 +vt 0.938796 0.672946 +vt 0.937419 0.672903 +vt 0.813090 0.522941 +vt 0.814201 0.522841 +vt 0.811693 0.523252 +vt 0.810384 0.523690 +vt 0.924639 0.219347 +vt 0.926263 0.213175 +vt 0.924857 0.213456 +vt 0.927640 0.213097 +vt 0.796573 0.276914 +vt 0.795464 0.276814 +vt 0.797969 0.277223 +vt 0.799280 0.277658 +vt 0.939532 0.678667 +vt 0.940603 0.679044 +vt 0.938118 0.678428 +vt 0.936740 0.678390 +vt 0.814536 0.528376 +vt 0.815645 0.528269 +vt 0.813141 0.528693 +vt 0.811834 0.529136 +vt 0.923797 0.213866 +vt 0.925453 0.207662 +vt 0.924044 0.207926 +vt 0.926831 0.207596 +vt 0.798010 0.271441 +vt 0.796902 0.271340 +vt 0.799408 0.271743 +vt 0.800723 0.272163 +vt 0.938880 0.684232 +vt 0.939954 0.684590 +vt 0.937464 0.684010 +vt 0.936085 0.683984 +vt 0.816024 0.533913 +vt 0.817132 0.533804 +vt 0.814627 0.534223 +vt 0.813316 0.534651 +vt 0.922982 0.208317 +vt 0.924686 0.201743 +vt 0.923272 0.201969 +vt 0.926066 0.201691 +vt 0.799445 0.265549 +vt 0.798334 0.265460 +vt 0.800852 0.265815 +vt 0.802178 0.266186 +vt 0.938274 0.690307 +vt 0.939352 0.690615 +vt 0.936854 0.690123 +vt 0.935474 0.690111 +vt 0.817535 0.539971 +vt 0.818646 0.539875 +vt 0.816130 0.540246 +vt 0.814806 0.540625 +vt 0.922203 0.202310 +vt 0.924173 0.196736 +vt 0.922754 0.196909 +vt 0.925554 0.196702 +vt 0.800437 0.260552 +vt 0.799322 0.260488 +vt 0.801855 0.260759 +vt 0.803197 0.261052 +vt 0.937892 0.695551 +vt 0.938976 0.695782 +vt 0.936468 0.695421 +vt 0.935087 0.695426 +vt 0.818609 0.545223 +vt 0.819725 0.545151 +vt 0.817191 0.545438 +vt 0.815852 0.545739 +vt 0.921677 0.197173 +vt 0.923882 0.192527 +vt 0.922458 0.192631 +vt 0.925265 0.192514 +vt 0.801036 0.256343 +vt 0.799916 0.256310 +vt 0.802465 0.256472 +vt 0.803821 0.256664 +vt 0.937714 0.700057 +vt 0.938801 0.700190 +vt 0.936288 0.699996 +vt 0.934905 0.700023 +vt 0.819281 0.549764 +vt 0.820401 0.549723 +vt 0.817852 0.549902 +vt 0.816498 0.550101 +vt 0.921375 0.192796 +vt 0.923782 0.189018 +vt 0.922356 0.189035 +vt 0.925166 0.189030 +vt 0.801292 0.252822 +vt 0.800169 0.252831 +vt 0.802728 0.252854 +vt 0.804092 0.252918 +vt 0.937718 0.703934 +vt 0.938805 0.703943 +vt 0.936292 0.703958 +vt 0.934910 0.704011 +vt 0.819588 0.553701 +vt 0.820712 0.553702 +vt 0.818153 0.553741 +vt 0.816789 0.553813 +vt 0.921270 0.189078 +vt 0.923841 0.186104 +vt 0.922417 0.186019 +vt 0.925224 0.186145 +vt 0.801257 0.249885 +vt 0.800135 0.249946 +vt 0.802691 0.249799 +vt 0.804053 0.249711 +vt 0.937884 0.707284 +vt 0.938964 0.707147 +vt 0.936464 0.707411 +vt 0.935082 0.707492 +vt 0.819566 0.557134 +vt 0.820689 0.557187 +vt 0.818131 0.557057 +vt 0.816770 0.556976 +vt 0.921334 0.185915 +vt 0.924025 0.183663 +vt 0.922610 0.183469 +vt 0.925406 0.183734 +vt 0.800982 0.247413 +vt 0.799867 0.247532 +vt 0.802401 0.247197 +vt 0.803744 0.246940 +vt 0.938192 0.710203 +vt 0.939254 0.709906 +vt 0.936783 0.710439 +vt 0.935405 0.710550 +vt 0.819248 0.560149 +vt 0.820366 0.560260 +vt 0.817828 0.559941 +vt 0.816484 0.559692 +vt 0.921539 0.183204 +vt 0.924310 0.181558 +vt 0.922909 0.181259 +vt 0.925687 0.181656 +vt 0.800510 0.245270 +vt 0.799408 0.245447 +vt 0.801901 0.244925 +vt 0.803209 0.244505 +vt 0.938615 0.712773 +vt 0.939653 0.712322 +vt 0.937223 0.713113 +vt 0.935850 0.713251 +vt 0.818680 0.562816 +vt 0.819784 0.562985 +vt 0.817286 0.562479 +vt 0.815977 0.562067 +vt 0.921858 0.180840 +vt 0.924677 0.179641 +vt 0.923292 0.179260 +vt 0.926051 0.179758 +vt 0.799869 0.243313 +vt 0.798783 0.243541 +vt 0.801226 0.242861 +vt 0.802490 0.242306 +vt 0.939125 0.715072 +vt 0.940135 0.714496 +vt 0.937751 0.715495 +vt 0.936381 0.715651 +vt 0.817919 0.565196 +vt 0.819007 0.565416 +vt 0.816559 0.564752 +vt 0.815292 0.564205 +vt 0.922265 0.178715 +vt 0.925115 0.177779 +vt 0.923741 0.177346 +vt 0.926487 0.177904 +vt 0.799076 0.241412 +vt 0.798005 0.241676 +vt 0.800404 0.240888 +vt 0.801632 0.240246 +vt 0.939686 0.717184 +vt 0.940676 0.716529 +vt 0.938325 0.717657 +vt 0.936957 0.717821 +vt 0.817033 0.567364 +vt 0.818107 0.567621 +vt 0.815702 0.566848 +vt 0.814470 0.566213 +vt 0.922732 0.176722 +vt 0.925609 0.175854 +vt 0.924238 0.175408 +vt 0.926981 0.175976 +vt 0.798155 0.239453 +vt 0.797093 0.239738 +vt 0.799469 0.238899 +vt 0.800682 0.238223 +vt 0.940267 0.719204 +vt 0.941249 0.718522 +vt 0.938910 0.719691 +vt 0.937542 0.719853 +vt 0.816087 0.569411 +vt 0.817152 0.569688 +vt 0.814770 0.568865 +vt 0.813553 0.568196 +vt 0.923236 0.174756 +vt 0.926132 0.173768 +vt 0.924757 0.173341 +vt 0.927508 0.173877 +vt 0.797144 0.237340 +vt 0.796083 0.237626 +vt 0.798462 0.236794 +vt 0.799684 0.236136 +vt 0.940842 0.721240 +vt 0.941831 0.720580 +vt 0.939480 0.721707 +vt 0.938108 0.721855 +vt 0.815128 0.571446 +vt 0.816192 0.571725 +vt 0.813807 0.570909 +vt 0.812582 0.570258 +vt 0.923749 0.172712 +vt 0.926684 0.171314 +vt 0.925308 0.170888 +vt 0.928045 0.171482 +vt 0.796121 0.235035 +vt 0.795018 0.235219 +vt 0.797487 0.234608 +vt 0.798750 0.234053 +vt 0.941345 0.723239 +vt 0.942350 0.722637 +vt 0.939983 0.723706 +vt 0.938627 0.723913 +vt 0.814167 0.573637 +vt 0.815272 0.573813 +vt 0.812798 0.573218 +vt 0.811532 0.572670 +vt 0.924287 0.170317 +vt 0.927701 0.167794 +vt 0.926360 0.167259 +vt 0.928976 0.168234 +vt 0.795326 0.232124 +vt 0.794143 0.231942 +vt 0.796772 0.232057 +vt 0.798091 0.231758 +vt 0.942002 0.725413 +vt 0.943036 0.724894 +vt 0.940677 0.725987 +vt 0.939417 0.726463 +vt 0.813380 0.576602 +vt 0.814564 0.576412 +vt 0.811934 0.576543 +vt 0.810613 0.576251 +vt 0.925312 0.166772 +vt 0.929218 0.164746 +vt 0.927976 0.164018 +vt 0.930273 0.165617 +vt 0.795544 0.230020 +vt 0.794433 0.229273 +vt 0.796921 0.230492 +vt 0.798193 0.230560 +vt 0.942549 0.726475 +vt 0.943634 0.726051 +vt 0.941328 0.727240 +vt 0.940299 0.728141 +vt 0.813639 0.578901 +vt 0.814746 0.578146 +vt 0.812266 0.579381 +vt 0.810995 0.579456 +vt 0.926878 0.163627 +vt 0.931044 0.162630 +vt 0.929940 0.161740 +vt 0.931796 0.163853 +vt 0.796548 0.228652 +vt 0.795774 0.227438 +vt 0.797605 0.229566 +vt 0.601038 0.784360 +vt 0.600847 0.783735 +vt 0.599549 0.784254 +vt 0.599833 0.785171 +vt 0.602447 0.784151 +vt 0.602280 0.783600 +vt 0.941947 0.727913 +vt 0.943024 0.726991 +vt 0.941231 0.729158 +vt 0.814785 0.580444 +vt 0.815552 0.579225 +vt 0.813735 0.581364 +vt 0.746495 0.002000 +vt 0.745843 0.004275 +vt 0.747154 0.004761 +vt 0.747720 0.002781 +vt 0.745081 0.001825 +vt 0.744407 0.004175 +vt 0.743232 0.004487 +vt 0.742966 0.007413 +vt 0.744121 0.007307 +vt 0.797847 0.226573 +vt 0.797927 0.225222 +vt 0.795490 0.226248 +vt 0.798162 0.227991 +vt 0.798786 0.229097 +vt 0.600736 0.782673 +vt 0.599396 0.782846 +vt 0.602179 0.782620 +vt 0.603463 0.783887 +vt 0.603337 0.782703 +vt 0.816915 0.579764 +vt 0.816828 0.578412 +vt 0.815830 0.578033 +vt 0.816609 0.581184 +vt 0.815992 0.582292 +vt 0.745565 0.007324 +vt 0.746909 0.007462 +vt 0.743009 0.010600 +vt 0.744166 0.010678 +vt 0.800330 0.226633 +vt 0.800747 0.225284 +vt 0.800224 0.228048 +vt 0.800456 0.229151 +vt 0.600726 0.781082 +vt 0.599381 0.780962 +vt 0.602170 0.781091 +vt 0.603325 0.780989 +vt 0.818773 0.579696 +vt 0.818348 0.578349 +vt 0.818888 0.581110 +vt 0.818663 0.582213 +vt 0.745609 0.010633 +vt 0.746951 0.010478 +vt 0.743299 0.013809 +vt 0.744469 0.014040 +vt 0.803010 0.227547 +vt 0.803711 0.226292 +vt 0.802553 0.228846 +vt 0.802463 0.229841 +vt 0.600857 0.779132 +vt 0.599526 0.778785 +vt 0.602298 0.779184 +vt 0.603463 0.778928 +vt 0.820953 0.578933 +vt 0.820245 0.577682 +vt 0.821418 0.580228 +vt 0.821516 0.581222 +vt 0.745908 0.013953 +vt 0.747231 0.013571 +vt 0.806649 0.228189 +vt 0.807530 0.227395 +vt 0.804468 0.225419 +vt 0.805708 0.229289 +vt 0.804958 0.230400 +vt 0.667613 0.408015 +vt 0.666947 0.406562 +vt 0.665729 0.407294 +vt 0.666479 0.408927 +vt 0.601144 0.777072 +vt 0.599837 0.776547 +vt 0.602581 0.777153 +vt 0.822301 0.576335 +vt 0.821417 0.575544 +vt 0.819484 0.576812 +vt 0.823249 0.577429 +vt 0.824006 0.578534 +vt 0.824370 0.579355 +vt 0.746426 0.017111 +vt 0.747720 0.016552 +vt 0.744992 0.017226 +vt 0.809384 0.230960 +vt 0.810369 0.230272 +vt 0.808243 0.231858 +vt 0.807251 0.232724 +vt 0.666582 0.404411 +vt 0.665324 0.404915 +vt 0.668377 0.406352 +vt 0.668036 0.404343 +vt 0.603019 0.775229 +vt 0.601586 0.775129 +vt 0.824311 0.574272 +vt 0.823323 0.573588 +vt 0.825458 0.575163 +vt 0.826456 0.576022 +vt 0.092727 0.252209 +vt 0.092290 0.254993 +vt 0.093554 0.255482 +vt 0.093955 0.252925 +vt 0.091295 0.252018 +vt 0.090835 0.254945 +vt 0.745709 0.020046 +vt 0.747139 0.019912 +vt 0.811715 0.234592 +vt 0.812781 0.234030 +vt 0.810421 0.235252 +vt 0.809245 0.235831 +vt 0.666615 0.401541 +vt 0.665360 0.401786 +vt 0.668068 0.401633 +vt 0.669297 0.404730 +vt 0.669329 0.402040 +vt 0.826090 0.571463 +vt 0.825021 0.570906 +vt 0.827388 0.572114 +vt 0.828568 0.572686 +vt 0.092379 0.258593 +vt 0.093637 0.258823 +vt 0.090928 0.258705 +vt 0.089579 0.255350 +vt 0.089672 0.259130 +vt 0.813441 0.239060 +vt 0.814560 0.238634 +vt 0.812048 0.239466 +vt 0.810754 0.239743 +vt 0.667149 0.397919 +vt 0.665933 0.397895 +vt 0.668578 0.398177 +vt 0.669837 0.398601 +vt 0.827453 0.567862 +vt 0.826333 0.567442 +vt 0.828848 0.568260 +vt 0.830145 0.568528 +vt 0.093084 0.262978 +vt 0.094300 0.262939 +vt 0.091659 0.263256 +vt 0.090406 0.263697 +vt 0.814373 0.244333 +vt 0.815516 0.244039 +vt 0.812936 0.244496 +vt 0.811589 0.244482 +vt 0.668294 0.393507 +vt 0.667144 0.393227 +vt 0.669683 0.393921 +vt 0.670938 0.394360 +vt 0.828206 0.563420 +vt 0.827062 0.563132 +vt 0.829644 0.563573 +vt 0.830991 0.563551 +vt 0.094488 0.268111 +vt 0.095634 0.267818 +vt 0.093105 0.268544 +vt 0.091856 0.269000 +vt 0.814338 0.250210 +vt 0.815481 0.250092 +vt 0.812900 0.250145 +vt 0.811553 0.249917 +vt 0.670156 0.388344 +vt 0.669051 0.387922 +vt 0.671533 0.388797 +vt 0.672812 0.389157 +vt 0.828135 0.557915 +vt 0.826992 0.557804 +vt 0.829572 0.557843 +vt 0.830918 0.557605 +vt 0.096676 0.274035 +vt 0.097776 0.273599 +vt 0.095306 0.274505 +vt 0.094031 0.274884 +vt 0.813995 0.252386 +vt 0.815108 0.252491 +vt 0.812583 0.252139 +vt 0.811249 0.251816 +vt 0.670696 0.386463 +vt 0.669586 0.386059 +vt 0.672106 0.386789 +vt 0.673438 0.386950 +vt 0.827735 0.555446 +vt 0.826625 0.555556 +vt 0.829146 0.555190 +vt 0.830478 0.554859 +vt 0.097462 0.276703 +vt 0.098567 0.276287 +vt 0.096056 0.277048 +vt 0.094727 0.277228 +vt 0.813339 0.255134 +vt 0.814411 0.255413 +vt 0.811953 0.254772 +vt 0.810625 0.254424 +vt 0.671047 0.383807 +vt 0.669926 0.383475 +vt 0.672479 0.383986 +vt 0.673838 0.383963 +vt 0.826958 0.552262 +vt 0.825889 0.552547 +vt 0.828342 0.551893 +vt 0.829668 0.551536 +vt 0.097940 0.279925 +vt 0.099056 0.279579 +vt 0.096510 0.280123 +vt 0.095151 0.280119 +vt 0.812375 0.258513 +vt 0.813417 0.258900 +vt 0.811008 0.258084 +vt 0.809683 0.257726 +vt 0.671183 0.380464 +vt 0.670060 0.380181 +vt 0.672619 0.380546 +vt 0.673984 0.380406 +vt 0.825890 0.548595 +vt 0.824852 0.548986 +vt 0.827254 0.548157 +vt 0.828578 0.547791 +vt 0.098142 0.283617 +vt 0.099261 0.283321 +vt 0.096707 0.283718 +vt 0.095340 0.283597 +vt 0.811153 0.262404 +vt 0.812173 0.262864 +vt 0.809800 0.261931 +vt 0.808475 0.261571 +vt 0.671086 0.376570 +vt 0.669963 0.376328 +vt 0.672521 0.376581 +vt 0.673884 0.376357 +vt 0.824575 0.544489 +vt 0.823560 0.544954 +vt 0.825925 0.544008 +vt 0.827248 0.543640 +vt 0.098095 0.287749 +vt 0.099214 0.287492 +vt 0.096660 0.287778 +vt 0.095294 0.287573 +vt 0.809721 0.266704 +vt 0.810723 0.267218 +vt 0.808378 0.266201 +vt 0.807052 0.265843 +vt 0.670752 0.372236 +vt 0.669632 0.372029 +vt 0.672183 0.372189 +vt 0.673541 0.371900 +vt 0.823056 0.540013 +vt 0.822059 0.540532 +vt 0.824396 0.539502 +vt 0.825720 0.539137 +vt 0.097808 0.292259 +vt 0.098925 0.292038 +vt 0.096377 0.292230 +vt 0.095015 0.291960 +vt 0.808127 0.271319 +vt 0.809114 0.271876 +vt 0.806791 0.270795 +vt 0.805463 0.270445 +vt 0.670184 0.367558 +vt 0.669068 0.367384 +vt 0.671608 0.367461 +vt 0.672960 0.367117 +vt 0.821378 0.535240 +vt 0.820395 0.535802 +vt 0.822710 0.534708 +vt 0.824037 0.534350 +vt 0.097288 0.297077 +vt 0.098402 0.296889 +vt 0.095862 0.296997 +vt 0.094507 0.296672 +vt 0.806419 0.276159 +vt 0.807393 0.276753 +vt 0.805088 0.275620 +vt 0.803757 0.275281 +vt 0.669383 0.362628 +vt 0.668273 0.362488 +vt 0.670800 0.362483 +vt 0.672144 0.362090 +vt 0.819585 0.530248 +vt 0.818616 0.530847 +vt 0.820912 0.529701 +vt 0.822242 0.529353 +vt 0.096538 0.302125 +vt 0.097647 0.301971 +vt 0.095120 0.301997 +vt 0.093771 0.301623 +vt 0.804644 0.281136 +vt 0.805606 0.281763 +vt 0.803317 0.280587 +vt 0.801980 0.280261 +vt 0.668355 0.357535 +vt 0.667252 0.357430 +vt 0.669762 0.357342 +vt 0.671097 0.356904 +vt 0.817722 0.525118 +vt 0.816765 0.525749 +vt 0.819046 0.524560 +vt 0.820381 0.524226 +vt 0.095561 0.307322 +vt 0.096663 0.307204 +vt 0.094152 0.307148 +vt 0.092812 0.306727 +vt 0.802848 0.286163 +vt 0.803799 0.286820 +vt 0.801523 0.285606 +vt 0.800180 0.285298 +vt 0.667103 0.352366 +vt 0.666009 0.352299 +vt 0.668498 0.352124 +vt 0.669822 0.351639 +vt 0.815836 0.519928 +vt 0.814890 0.520590 +vt 0.817157 0.519364 +vt 0.818499 0.519047 +vt 0.094361 0.312588 +vt 0.095453 0.312509 +vt 0.092962 0.312365 +vt 0.091633 0.311898 +vt 0.801078 0.291150 +vt 0.802019 0.291837 +vt 0.799756 0.290589 +vt 0.798405 0.290303 +vt 0.665631 0.347207 +vt 0.664550 0.347184 +vt 0.667012 0.346912 +vt 0.668321 0.346379 +vt 0.813972 0.514761 +vt 0.813036 0.515452 +vt 0.815291 0.514192 +vt 0.816640 0.513897 +vt 0.092939 0.317840 +vt 0.094020 0.317804 +vt 0.091554 0.317563 +vt 0.090238 0.317048 +vt 0.799383 0.296011 +vt 0.800313 0.296728 +vt 0.798060 0.295448 +vt 0.796700 0.295189 +vt 0.663944 0.342144 +vt 0.662880 0.342171 +vt 0.665305 0.341790 +vt 0.666597 0.341205 +vt 0.812174 0.509696 +vt 0.811249 0.510417 +vt 0.813493 0.509125 +vt 0.814852 0.508857 +vt 0.091298 0.322995 +vt 0.092362 0.323009 +vt 0.089933 0.322659 +vt 0.088633 0.322091 +vt 0.797790 0.300703 +vt 0.798724 0.301408 +vt 0.796457 0.300173 +vt 0.795083 0.299958 +vt 0.662016 0.337184 +vt 0.660969 0.337257 +vt 0.663365 0.336797 +vt 0.664652 0.336200 +vt 0.810506 0.504858 +vt 0.809577 0.505567 +vt 0.811835 0.504320 +vt 0.813209 0.504097 +vt 0.089469 0.327889 +vt 0.090518 0.327950 +vt 0.088116 0.327520 +vt 0.086821 0.326941 +vt 0.085931 0.326307 +vt 0.082856 0.334875 +vt 0.083786 0.335389 +vt 0.794142 0.308562 +vt 0.795504 0.308979 +vt 0.792746 0.308427 +vt 0.658749 0.328438 +vt 0.657711 0.328537 +vt 0.660110 0.328088 +vt 0.661429 0.327580 +vt 0.665534 0.335553 +vt 0.662353 0.327052 +vt 0.809540 0.496186 +vt 0.808181 0.496612 +vt 0.810935 0.496043 +vt 0.086477 0.336211 +vt 0.087517 0.336298 +vt 0.085112 0.335879 +vt 0.080787 0.342849 +vt 0.081769 0.343162 +vt 0.792899 0.316506 +vt 0.794288 0.316746 +vt 0.791487 0.316483 +vt 0.656491 0.320184 +vt 0.655456 0.320298 +vt 0.657875 0.319922 +vt 0.659239 0.319581 +vt 0.660217 0.319254 +vt 0.808332 0.488743 +vt 0.806945 0.488991 +vt 0.809745 0.488711 +vt 0.084525 0.343728 +vt 0.085561 0.343830 +vt 0.083137 0.343483 +vt 0.079650 0.350315 +vt 0.080667 0.350396 +vt 0.792655 0.324048 +vt 0.794051 0.324084 +vt 0.791239 0.324150 +vt 0.655197 0.312385 +vt 0.654165 0.312513 +vt 0.656598 0.312225 +vt 0.657994 0.312077 +vt 0.659009 0.311980 +vt 0.808067 0.481782 +vt 0.806672 0.481827 +vt 0.809484 0.481876 +vt 0.083467 0.350667 +vt 0.084501 0.350784 +vt 0.082064 0.350525 +vt 0.079353 0.357397 +vt 0.080380 0.357245 +vt 0.793309 0.331280 +vt 0.794687 0.331109 +vt 0.791904 0.331509 +vt 0.790182 0.324364 +vt 0.790848 0.331735 +vt 0.656194 0.304904 +vt 0.654786 0.304957 +vt 0.657600 0.304952 +vt 0.658629 0.305090 +vt 0.808629 0.475148 +vt 0.807251 0.474985 +vt 0.810035 0.475369 +vt 0.810544 0.482083 +vt 0.811094 0.475587 +vt 0.081785 0.357177 +vt 0.083194 0.357212 +vt 0.079802 0.364219 +vt 0.080816 0.363858 +vt 0.794745 0.338291 +vt 0.796085 0.337935 +vt 0.793362 0.338631 +vt 0.792307 0.338864 +vt 0.656562 0.297869 +vt 0.655159 0.297825 +vt 0.657960 0.298095 +vt 0.658978 0.298440 +vt 0.809916 0.468678 +vt 0.808574 0.468330 +vt 0.811301 0.469009 +vt 0.812358 0.469235 +vt 0.082211 0.363614 +vt 0.083613 0.363551 +vt 0.080899 0.370905 +vt 0.081887 0.370381 +vt 0.796836 0.345178 +vt 0.798133 0.344680 +vt 0.795478 0.345602 +vt 0.794424 0.345838 +vt 0.657591 0.291017 +vt 0.656200 0.290893 +vt 0.658969 0.291382 +vt 0.659964 0.291891 +vt 0.811836 0.462220 +vt 0.810536 0.461729 +vt 0.813197 0.462635 +vt 0.814253 0.462864 +vt 0.083260 0.369998 +vt 0.084649 0.369856 +vt 0.082545 0.377585 +vt 0.083506 0.376949 +vt 0.799457 0.352060 +vt 0.800718 0.351464 +vt 0.798120 0.352539 +vt 0.797065 0.352773 +vt 0.659169 0.284221 +vt 0.657790 0.284039 +vt 0.660524 0.284684 +vt 0.661493 0.285306 +vt 0.814298 0.455642 +vt 0.813033 0.455053 +vt 0.815638 0.456113 +vt 0.816695 0.456339 +vt 0.084855 0.376467 +vt 0.086231 0.376267 +vt 0.084641 0.384393 +vt 0.085582 0.383690 +vt 0.802490 0.359065 +vt 0.803728 0.358413 +vt 0.801165 0.359574 +vt 0.800108 0.359802 +vt 0.661185 0.277340 +vt 0.659818 0.277120 +vt 0.662523 0.277865 +vt 0.663473 0.278554 +vt 0.817201 0.448824 +vt 0.815961 0.448178 +vt 0.818530 0.449324 +vt 0.819589 0.449545 +vt 0.086913 0.383147 +vt 0.088277 0.382909 +vt 0.087091 0.391466 +vt 0.088022 0.390733 +vt 0.805824 0.366329 +vt 0.807051 0.365655 +vt 0.804503 0.366845 +vt 0.803442 0.367064 +vt 0.663540 0.270232 +vt 0.662181 0.269989 +vt 0.664868 0.270788 +vt 0.665809 0.271506 +vt 0.820441 0.441650 +vt 0.819210 0.440982 +vt 0.821766 0.442158 +vt 0.822830 0.442369 +vt 0.089343 0.390159 +vt 0.090699 0.389899 +vt 0.089800 0.398938 +vt 0.090731 0.398206 +vt 0.809351 0.373984 +vt 0.810581 0.373316 +vt 0.808025 0.374490 +vt 0.806959 0.374698 +vt 0.666137 0.262755 +vt 0.664780 0.262503 +vt 0.667463 0.263315 +vt 0.668404 0.264033 +vt 0.823907 0.434004 +vt 0.822673 0.433343 +vt 0.825236 0.434501 +vt 0.826305 0.434702 +vt 0.092050 0.397628 +vt 0.093403 0.397359 +vt 0.092672 0.406946 +vt 0.093612 0.406241 +vt 0.812966 0.382163 +vt 0.814210 0.381525 +vt 0.811629 0.382644 +vt 0.810557 0.382839 +vt 0.668880 0.254768 +vt 0.667522 0.254518 +vt 0.670212 0.255311 +vt 0.671161 0.256003 +vt 0.827486 0.425768 +vt 0.826239 0.425137 +vt 0.828826 0.426240 +vt 0.829901 0.426427 +vt 0.094937 0.405679 +vt 0.096291 0.405412 +vt 0.095613 0.415625 +vt 0.096569 0.414964 +vt 0.816566 0.391000 +vt 0.817829 0.390409 +vt 0.815215 0.391445 +vt 0.814137 0.391626 +vt 0.671678 0.246130 +vt 0.670317 0.245890 +vt 0.673020 0.246641 +vt 0.673984 0.247287 +vt 0.831064 0.416826 +vt 0.829799 0.416242 +vt 0.832419 0.417263 +vt 0.833499 0.417436 +vt 0.097904 0.414435 +vt 0.099261 0.414178 +vn -0.5003 -0.0499 -0.8644 +vn -0.5012 -0.0393 -0.8644 +vn -0.0035 -0.0019 -1.0000 +vn -0.0033 -0.0013 -1.0000 +vn -0.8628 -0.0850 -0.4983 +vn -0.8644 -0.0661 -0.4984 +vn -0.9952 -0.0974 0.0001 +vn -0.9972 -0.0752 0.0000 +vn -0.8628 -0.0840 0.4985 +vn -0.8645 -0.0644 0.4985 +vn -0.9952 -0.0975 0.0002 +vn -0.5003 -0.0481 0.8645 +vn -0.5014 -0.0364 0.8644 +vn -0.0036 0.0006 1.0000 +vn -0.0038 0.0014 1.0000 +vn 0.4949 0.0493 0.8676 +vn 0.4956 0.0389 0.8677 +vn 0.8609 0.0848 0.5016 +vn 0.8625 0.0660 0.5017 +vn 0.9952 0.0975 0.0002 +vn 0.9972 0.0753 0.0001 +vn 0.8612 0.0839 -0.5013 +vn 0.8628 0.0643 -0.5015 +vn 0.9972 0.0753 0.0002 +vn 0.4953 0.0477 -0.8674 +vn 0.4960 0.0360 -0.8676 +vn -0.5025 -0.0167 -0.8644 +vn -0.0036 -0.0022 -1.0000 +vn -0.8665 -0.0267 -0.4985 +vn -0.9996 -0.0295 -0.0002 +vn -0.8667 -0.0246 0.4982 +vn -0.5029 -0.0131 0.8643 +vn -0.0041 0.0019 1.0000 +vn 0.4967 0.0165 0.8678 +vn -0.0040 0.0020 1.0000 +vn 0.8646 0.0266 0.5018 +vn 0.9996 0.0295 0.0001 +vn 0.8648 0.0245 -0.5016 +vn 0.9996 0.0296 0.0001 +vn 0.4970 0.0129 -0.8676 +vn -0.5026 0.0087 -0.8645 +vn -0.0038 -0.0003 -1.0000 +vn -0.8667 0.0154 -0.4986 +vn -0.9998 0.0180 -0.0004 +vn -0.8671 0.0158 0.4979 +vn -0.5032 0.0094 0.8641 +vn -0.0042 0.0004 1.0000 +vn 0.4969 -0.0086 0.8678 +vn -0.0042 0.0005 1.0000 +vn 0.8649 -0.0154 0.5017 +vn 0.9998 -0.0180 -0.0000 +vn 0.8649 -0.0158 -0.5017 +vn 0.4970 -0.0093 -0.8677 +vn -0.0037 -0.0003 -1.0000 +vn -0.5014 0.0365 -0.8645 +vn -0.0036 0.0040 -1.0000 +vn -0.8647 0.0591 -0.4987 +vn -0.9978 0.0661 -0.0006 +vn -0.8655 0.0554 0.4979 +vn -0.9978 0.0661 -0.0005 +vn -0.5024 0.0300 0.8641 +vn -0.0043 -0.0035 1.0000 +vn 0.4958 -0.0361 0.8677 +vn -0.0043 -0.0034 1.0000 +vn 0.8631 -0.0590 0.5015 +vn 0.9978 -0.0661 -0.0003 +vn 0.8631 -0.0553 -0.5019 +vn 0.4961 -0.0296 -0.8678 +vn -0.4985 0.0659 -0.8644 +vn -0.0028 0.0109 -0.9999 +vn -0.8606 0.1032 -0.4986 +vn -0.9936 0.1131 -0.0004 +vn -0.8622 0.0928 0.4980 +vn -0.5008 0.0478 0.8643 +vn -0.0047 -0.0101 0.9999 +vn 0.4934 -0.0654 0.8674 +vn -0.0048 -0.0101 0.9999 +vn 0.8593 -0.1031 0.5009 +vn 0.9936 -0.1131 -0.0009 +vn 0.8597 -0.0925 -0.5023 +vn 0.4945 -0.0471 -0.8679 +vn -0.4940 0.0963 -0.8641 +vn -0.0012 0.0206 -0.9998 +vn -0.8546 0.1462 -0.4983 +vn -0.9876 0.1572 0.0000 +vn -0.8577 0.1263 0.4985 +vn -0.4987 0.0617 0.8645 +vn -0.0058 -0.0195 0.9998 +vn 0.4896 -0.0956 0.8667 +vn -0.0057 -0.0195 0.9998 +vn 0.8536 -0.1461 0.5000 +vn 0.9876 -0.1571 -0.0018 +vn 0.8551 -0.1259 -0.5029 +vn 0.9876 -0.1572 -0.0018 +vn 0.4927 -0.0607 -0.8680 +vn -0.4882 0.1266 -0.8635 +vn 0.0014 0.0328 -0.9995 +vn -0.8472 0.1865 -0.4976 +vn -0.9805 0.1967 0.0008 +vn -0.8526 0.1545 0.4992 +vn -0.4969 0.0710 0.8649 +vn -0.0075 -0.0316 0.9995 +vn 0.4845 -0.1259 0.8657 +vn 0.8466 -0.1864 0.4985 +vn 0.9805 -0.1967 -0.0031 +vn 0.8501 -0.1539 -0.5036 +vn 0.4913 -0.0698 -0.8682 +vn -0.4812 0.1559 -0.8626 +vn 0.0052 0.0474 -0.9989 +vn -0.8390 0.2227 -0.4964 +vn -0.9731 0.2302 0.0020 +vn -0.8478 0.1763 0.5002 +vn -0.4956 0.0752 0.8653 +vn -0.0101 -0.0462 0.9989 +vn 0.4786 -0.1554 0.8642 +vn 0.8389 -0.2227 0.4967 +vn 0.9732 -0.2301 -0.0046 +vn 0.8454 -0.1756 -0.5044 +vn 0.4908 -0.0739 -0.8681 +vn 0.0051 0.0474 -0.9989 +vn -0.4738 0.1833 -0.8613 +vn 0.0100 0.0639 -0.9979 +vn -0.8310 0.2538 -0.4950 +vn -0.9665 0.2565 0.0033 +vn -0.8440 0.1908 0.5012 +vn -0.4955 0.0739 0.8654 +vn -0.0137 -0.0629 0.9979 +vn 0.4722 -0.1830 0.8623 +vn 0.8313 -0.2538 0.4945 +vn 0.9666 -0.2563 -0.0063 +vn 0.8419 -0.1900 -0.5051 +vn 0.9666 -0.2564 -0.0063 +vn 0.4915 -0.0727 -0.8678 +vn 0.0099 0.0639 -0.9979 +vn -0.4664 0.2081 -0.8598 +vn 0.0156 0.0818 -0.9965 +vn -0.8238 0.2788 -0.4935 +vn -0.9614 0.2751 0.0046 +vn -0.8420 0.1978 0.5019 +vn -0.9614 0.2751 0.0047 +vn -0.4968 0.0674 0.8652 +vn -0.0180 -0.0811 0.9965 +vn 0.4659 -0.2080 0.8600 +vn 0.8246 -0.2789 0.4922 +vn 0.9615 -0.2749 -0.0078 +vn 0.8401 -0.1970 -0.5054 +vn 0.9615 -0.2749 -0.0079 +vn 0.4937 -0.0664 -0.8671 +vn -0.4594 0.2299 -0.8579 +vn 0.0218 0.1008 -0.9947 +vn -0.8181 0.2976 -0.4920 +vn -0.9583 0.2857 0.0055 +vn -0.8419 0.1974 0.5022 +vn -0.4996 0.0561 0.8644 +vn -0.0228 -0.1003 0.9947 +vn 0.4601 -0.2298 0.8576 +vn -0.0229 -0.1003 0.9947 +vn 0.8193 -0.2975 0.4900 +vn 0.9584 -0.2854 -0.0089 +vn 0.8403 -0.1966 -0.5051 +vn 0.4975 -0.0552 -0.8657 +vn -0.4678 0.2047 -0.8598 +vn 0.0179 0.0767 -0.9969 +vn -0.8267 0.2770 -0.4897 +vn -0.9615 0.2744 0.0119 +vn -0.8375 0.1982 0.5092 +vn -0.4901 0.0694 0.8689 +vn -0.0132 -0.0775 0.9969 +vn 0.4667 -0.2038 0.8606 +vn 0.8231 -0.2761 0.4963 +vn 0.9614 -0.2752 -0.0005 +vn 0.8433 -0.2007 -0.4985 +vn 0.4983 -0.0719 -0.8640 +vn 0.0180 0.0767 -0.9969 +vn -0.4919 0.1165 -0.8628 +vn -0.0030 -0.0060 -1.0000 +vn -0.8464 0.2071 -0.4907 +vn -0.9704 0.2413 0.0135 +vn -0.8328 0.2105 0.5119 +vn -0.4738 0.1237 0.8719 +vn 0.0094 0.0043 0.9999 +vn 0.4897 -0.1160 0.8641 +vn 0.0095 0.0043 0.9999 +vn 0.8410 -0.2058 0.5004 +vn 0.9705 -0.2412 0.0031 +vn 0.8415 -0.2125 -0.4966 +vn 0.9705 -0.2413 0.0031 +vn 0.4857 -0.1265 -0.8649 +vn -0.5099 0.0354 -0.8595 +vn -0.0220 -0.0809 -0.9965 +vn -0.8599 0.1422 -0.4902 +vn -0.9775 0.2105 0.0108 +vn -0.8323 0.2220 0.5080 +vn -0.4648 0.1739 0.8681 +vn 0.0257 0.0796 0.9965 +vn 0.5090 -0.0357 0.8600 +vn 0.8572 -0.1415 0.4951 +vn 0.9777 -0.2099 -0.0020 +vn 0.8372 -0.2224 -0.4997 +vn 0.4715 -0.1753 -0.8643 +vn -0.5182 -0.0075 -0.8552 +vn -0.0305 -0.1192 -0.9924 +vn -0.8665 0.1062 -0.4878 +vn -0.9815 0.1913 0.0106 +vn -0.8329 0.2250 0.5057 +vn -0.4614 0.1983 0.8647 +vn 0.0329 0.1186 0.9924 +vn 0.5183 0.0074 0.8552 +vn 0.0330 0.1186 0.9924 +vn 0.8653 -0.1058 0.4899 +vn 0.9816 -0.1908 -0.0063 +vn 0.8354 -0.2250 -0.5014 +vn 0.4651 -0.1988 -0.8626 +vn -0.5215 -0.0271 -0.8528 +vn -0.0338 -0.1346 -0.9903 +vn -0.8693 0.0877 -0.4864 +vn -0.9838 0.1790 0.0106 +vn -0.8342 0.2222 0.5046 +vn -0.4611 0.2058 0.8632 +vn 0.0354 0.1343 0.9903 +vn 0.5223 0.0269 0.8524 +vn 0.8693 -0.0877 0.4864 +vn 0.9838 -0.1788 -0.0096 +vn 0.8351 -0.2222 -0.5032 +vn 0.4627 -0.2060 -0.8622 +vn -0.0339 -0.1346 -0.9903 +vn -0.5214 -0.0286 -0.8528 +vn -0.0336 -0.1317 -0.9907 +vn -0.8697 0.0823 -0.4866 +vn -0.9852 0.1712 0.0102 +vn -0.8364 0.2142 0.5045 +vn -0.9852 0.1711 0.0102 +vn -0.4631 0.1997 0.8635 +vn 0.0346 0.1316 0.9907 +vn 0.5229 0.0282 0.8519 +vn 0.8707 -0.0827 0.4847 +vn 0.9851 -0.1714 -0.0121 +vn 0.8358 -0.2142 -0.5055 +vn 0.4629 -0.1997 -0.8636 +vn -0.0336 -0.1318 -0.9907 +vn -0.5181 -0.0122 -0.8552 +vn -0.0303 -0.1104 -0.9934 +vn -0.8679 0.0892 -0.4886 +vn -0.9859 0.1669 0.0090 +vn -0.8396 0.2000 0.5050 +vn -0.9859 0.1669 0.0091 +vn -0.4675 0.1794 0.8656 +vn 0.0307 0.1104 0.9934 +vn 0.5206 0.0118 0.8537 +vn 0.8701 -0.0900 0.4845 +vn 0.9858 -0.1675 -0.0143 +vn 0.8374 -0.2000 -0.5087 +vn 0.4655 -0.1791 -0.8667 +vn -0.0303 -0.1103 -0.9934 +vn -0.5108 0.0265 -0.8593 +vn -0.0230 -0.0651 -0.9976 +vn -0.8633 0.1112 -0.4923 +vn -0.9860 0.1663 0.0068 +vn -0.8446 0.1772 0.5053 +vn -0.4753 0.1404 0.8686 +vn 0.0229 0.0656 0.9976 +vn 0.5149 -0.0269 0.8568 +vn 0.8673 -0.1121 0.4849 +vn 0.9858 -0.1669 -0.0166 +vn 0.8402 -0.1768 -0.5127 +vn 0.9858 -0.1669 -0.0167 +vn 0.4709 -0.1395 -0.8711 +vn -0.4968 0.1004 -0.8620 +vn -0.0092 0.0182 -0.9998 +vn -0.8540 0.1561 -0.4963 +vn -0.9853 0.1707 0.0027 +vn -0.8528 0.1401 0.5032 +vn -0.4890 0.0718 0.8693 +vn 0.0085 -0.0160 0.9998 +vn 0.5038 -0.0997 0.8580 +vn 0.0086 -0.0160 0.9998 +vn 0.8613 -0.1563 0.4834 +vn 0.9852 -0.1703 -0.0204 +vn 0.8449 -0.1381 -0.5168 +vn 0.4808 -0.0690 -0.8741 +vn -0.0093 0.0182 -0.9998 +vn -0.4688 0.2391 -0.8504 +vn 0.0175 0.1720 -0.9849 +vn -0.8347 0.2437 -0.4938 +vn -0.9828 0.1848 -0.0037 +vn -0.8670 0.0777 0.4922 +vn -0.5135 -0.0489 0.8567 +vn -0.0182 -0.1620 0.9866 +vn 0.4817 -0.2320 0.8451 +vn 0.8489 -0.2387 0.4716 +vn 0.9835 -0.1785 -0.0286 +vn 0.8534 -0.0685 -0.5168 +vn 0.4993 0.0599 -0.8644 +vn -0.4115 0.4930 -0.7666 +vn 0.0725 0.4504 -0.8899 +vn -0.7944 0.4103 -0.4480 +vn -0.9753 0.2206 -0.0076 +vn -0.8951 -0.0265 0.4451 +vn -0.9753 0.2206 -0.0075 +vn -0.5633 -0.2618 0.7837 +vn -0.0716 -0.4221 0.9037 +vn -0.5135 -0.0490 0.8567 +vn 0.4385 -0.4694 0.7664 +vn 0.8247 -0.3863 0.4130 +vn 0.9805 -0.1904 -0.0484 +vn 0.8719 0.0600 -0.4860 +vn 0.5391 0.2936 -0.7895 +vn 0.4993 0.0599 -0.8643 +vn -0.3256 0.8170 -0.4760 +vn 0.1646 0.8025 -0.5735 +vn -0.7345 0.6271 -0.2596 +vn -0.9603 0.2780 0.0231 +vn -0.7344 0.6271 -0.2596 +vn -0.9410 -0.1490 0.3038 +vn -0.6624 -0.5492 0.5095 +vn -0.1759 -0.8013 0.5719 +vn 0.3687 -0.8082 0.4593 +vn 0.7876 -0.5775 0.2150 +vn 0.9770 -0.1978 -0.0797 +vn 0.7875 -0.5775 0.2150 +vn 0.8248 -0.3863 0.4130 +vn 0.9099 0.2245 -0.3489 +vn 0.6138 0.5873 -0.5275 +vn -0.3255 0.8170 -0.4760 +vn -0.2580 0.9637 -0.0683 +vn 0.2393 0.9610 -0.1389 +vn 0.1645 0.8025 -0.5735 +vn -0.6921 0.7215 0.0202 +vn -0.9523 0.2873 0.1030 +vn -0.9608 -0.2314 0.1527 +vn -0.7051 -0.6925 0.1522 +vn -0.2529 -0.9615 0.1075 +vn -0.7052 -0.6925 0.1521 +vn 0.3687 -0.8082 0.4592 +vn 0.2716 -0.9616 0.0397 +vn 0.7213 -0.6916 -0.0377 +vn 0.9664 -0.2313 -0.1123 +vn 0.9449 0.2837 -0.1633 +vn 0.6764 0.7159 -0.1734 +vn 0.6764 0.7158 -0.1734 +vn 0.6138 0.5874 -0.5275 +vn -0.2235 0.9470 0.2308 +vn 0.2779 0.9465 0.1639 +vn -0.6694 0.7035 0.2385 +vn -0.9443 0.2731 0.1837 +vn -0.9687 -0.2350 0.0795 +vn -0.7293 -0.6826 -0.0461 +vn -0.2898 -0.9438 -0.1586 +vn 0.2298 -0.9461 -0.2282 +vn 0.6880 -0.6865 -0.2355 +vn 0.9551 -0.2373 -0.1772 +vn 0.6879 -0.6865 -0.2355 +vn 0.9597 0.2723 -0.0701 +vn 0.7094 0.7027 0.0545 +vn 0.9596 0.2723 -0.0701 +vn 0.9449 0.2838 -0.1633 +vn -0.1827 0.8410 0.5092 +vn 0.3169 0.8390 0.4423 +vn -0.6372 0.6283 0.4464 +vn -0.9301 0.2509 0.2684 +vn -0.9798 -0.1989 0.0196 +vn -0.7627 -0.6024 -0.2353 +vn -0.3283 -0.8422 -0.4276 +vn 0.2021 -0.8412 -0.5016 +vn 0.6718 -0.6012 -0.4326 +vn 0.2299 -0.9461 -0.2283 +vn 0.9493 -0.2005 -0.2421 +vn 0.9691 0.2464 0.0129 +vn 0.7363 0.6237 0.2623 +vn -0.1513 0.6173 0.7720 +vn 0.3493 0.6025 0.7176 +vn -0.6150 0.4744 0.6299 +vn -0.9233 0.2067 0.3237 +vn -0.9903 -0.1182 -0.0734 +vn -0.7862 -0.4140 -0.4588 +vn -0.9903 -0.1182 -0.0735 +vn -0.3562 -0.5945 -0.7209 +vn 0.1772 -0.6056 -0.7758 +vn 0.6547 -0.4472 -0.6094 +vn 0.9453 -0.1682 -0.2794 +vn 0.9809 0.1540 0.1188 +vn 0.7617 0.4343 0.4808 +vn 0.9809 0.1540 0.1187 +vn -0.1517 0.3681 0.9173 +vn 0.3522 0.3256 0.8775 +vn -0.6185 0.3150 0.7199 +vn -0.9266 0.1792 0.3307 +vn -0.9882 -0.0037 -0.1534 +vn -0.7779 -0.1827 -0.6012 +vn -0.3502 -0.3109 -0.8836 +vn 0.1740 -0.3547 -0.9186 +vn 0.6479 -0.3017 -0.6994 +vn 0.9420 -0.1640 -0.2927 +vn 0.9822 0.0197 0.1867 +vn 0.7654 0.1986 0.6122 +vn -0.1704 0.2016 0.9645 +vn 0.3348 0.1254 0.9339 +vn -0.6327 0.2248 0.7410 +vn -0.9291 0.1887 0.3181 +vn -0.9757 0.1031 -0.1934 +vn -0.7563 -0.0095 -0.6542 +vn -0.3292 -0.1202 -0.9366 +vn 0.1867 -0.1984 -0.9622 +vn 0.6508 -0.2228 -0.7258 +vn 0.9372 -0.1856 -0.2954 +vn 0.9726 -0.0978 0.2109 +vn 0.7519 0.0161 0.6591 +vn 0.9726 -0.0978 0.2108 +vn -0.1865 0.1230 0.9747 +vn 0.3164 0.0157 0.9485 +vn -0.6414 0.1978 0.7412 +vn -0.9255 0.2201 0.3081 +vn -0.9605 0.1834 -0.2094 +vn -0.7351 0.0972 -0.6710 +vn -0.3103 -0.0156 -0.9505 +vn 0.1978 -0.1241 -0.9724 +vn 0.6515 -0.1990 -0.7321 +vn 0.9293 -0.2199 -0.2966 +vn 0.9592 -0.1819 0.2165 +vn 0.7350 -0.0957 0.6713 +vn -0.1943 0.0976 0.9761 +vn 0.3043 -0.0361 0.9519 +vn -0.6419 0.2053 0.7388 +vn -0.1942 0.0975 0.9761 +vn -0.9176 0.2582 0.3024 +vn -0.9460 0.2415 -0.2162 +vn -0.7190 0.1596 -0.6765 +vn -0.2981 0.0346 -0.9539 +vn 0.2022 -0.0994 -0.9743 +vn 0.6475 -0.2066 -0.7335 +vn 0.9191 -0.2583 -0.2974 +vn 0.9458 -0.2412 0.2174 +vn 0.7211 -0.1599 0.6741 +vn -0.1945 0.1004 0.9757 +vn 0.2987 -0.0553 0.9527 +vn -0.6362 0.2294 0.7366 +vn -0.1946 0.1004 0.9757 +vn -0.9070 0.2967 0.2988 +vn -0.9333 0.2841 -0.2197 +vn -0.7081 0.1949 -0.6787 +vn -0.2927 0.0534 -0.9547 +vn 0.2004 -0.1022 -0.9744 +vn 0.6394 -0.2303 -0.7336 +vn 0.9074 -0.2968 -0.2976 +vn 0.9337 -0.2842 0.2176 +vn 0.7113 -0.1960 0.6750 +vn 0.9337 -0.2843 0.2176 +vn -0.1893 0.1181 0.9748 +vn 0.2982 -0.0563 0.9528 +vn -0.6265 0.2610 0.7344 +vn -0.8950 0.3336 0.2960 +vn -0.9223 0.3162 -0.2221 +vn -0.7014 0.2139 -0.6799 +vn -0.9223 0.3162 -0.2220 +vn -0.2926 0.0542 -0.9547 +vn 0.1938 -0.1197 -0.9737 +vn 0.6281 -0.2615 -0.7329 +vn 0.1939 -0.1197 -0.9737 +vn 0.8948 -0.3335 -0.2970 +vn 0.9231 -0.3167 0.2182 +vn 0.7051 -0.2154 0.6756 +vn -0.1804 0.1434 0.9731 +vn 0.3015 -0.0470 0.9523 +vn -0.6142 0.2954 0.7318 +vn -0.8825 0.3678 0.2932 +vn -0.9129 0.3411 -0.2241 +vn -0.6980 0.2227 -0.6806 +vn -0.9129 0.3411 -0.2240 +vn -0.2963 0.0448 -0.9540 +vn 0.1840 -0.1448 -0.9722 +vn 0.6148 -0.2956 -0.7312 +vn 0.8818 -0.3677 -0.2954 +vn 0.9138 -0.3418 0.2193 +vn 0.7018 -0.2245 0.6761 +vn -0.1690 0.1723 0.9705 +vn 0.3074 -0.0320 0.9511 +vn -0.6003 0.3303 0.7284 +vn -0.8698 0.3992 0.2901 +vn -0.9049 0.3606 -0.2260 +vn -0.6970 0.2253 -0.6808 +vn -0.3027 0.0298 -0.9526 +vn 0.1718 -0.1734 -0.9698 +vn 0.6003 -0.3303 -0.7284 +vn 0.8688 -0.3991 -0.2930 +vn 0.9058 -0.3616 0.2208 +vn 0.7007 -0.2274 0.6763 +vn -0.1684 0.1707 0.9708 +vn 0.3002 -0.0441 0.9529 +vn -0.5928 0.3403 0.7299 +vn -0.8593 0.4191 0.2932 +vn -0.8954 0.3852 -0.2232 +vn -0.6900 0.2473 -0.6802 +vn -0.2988 0.0429 -0.9534 +vn 0.1731 -0.1731 -0.9696 +vn 0.5980 -0.3424 -0.7247 +vn 0.8616 -0.4194 -0.2859 +vn 0.8944 -0.3844 0.2287 +vn 0.6889 -0.2471 0.6815 +vn -0.2015 0.0952 0.9748 +vn 0.2580 -0.1296 0.9574 +vn -0.6091 0.2957 0.7360 +vn -0.8570 0.4184 0.3008 +vn -0.8765 0.4294 -0.2175 +vn -0.6586 0.3238 -0.6793 +vn -0.2598 0.1293 -0.9570 +vn 0.2103 -0.1006 -0.9725 +vn 0.6218 -0.3024 -0.7224 +vn 0.2103 -0.1006 -0.9724 +vn 0.8631 -0.4216 -0.2781 +vn 0.8720 -0.4276 0.2383 +vn 0.6501 -0.3205 0.6890 +vn -0.2706 -0.0439 0.9617 +vn 0.1790 -0.2826 0.9424 +vn -0.6513 0.2073 0.7300 +vn -0.8623 0.4050 0.3040 +vn -0.8438 0.4952 -0.2071 +vn -0.5955 0.4505 -0.6652 +vn -0.8438 0.4951 -0.2071 +vn -0.1820 0.2815 -0.9422 +vn 0.2820 0.0350 -0.9588 +vn 0.6671 -0.2204 -0.7116 +vn 0.8682 -0.4145 -0.2729 +vn 0.8353 -0.4968 0.2356 +vn 0.5826 -0.4479 0.6782 +vn 0.8353 -0.4968 0.2355 +vn -0.3728 -0.2263 0.8999 +vn 0.0630 -0.4828 0.8735 +vn -0.7143 0.0901 0.6940 +vn -0.8713 0.3852 0.3041 +vn -0.7967 0.5793 -0.1724 +vn -0.5034 0.6154 -0.6066 +vn -0.0679 0.4802 -0.8745 +vn 0.3869 0.2113 -0.8976 +vn 0.7324 -0.1152 -0.6711 +vn 0.8742 -0.4077 -0.2638 +vn 0.7803 -0.5893 0.2093 +vn 0.4832 -0.6154 0.6228 +vn -0.5108 -0.4315 0.7436 +vn -0.0921 -0.7081 0.7001 +vn -0.8007 -0.0434 0.5975 +vn -0.8855 0.3600 0.2937 +vn -0.7347 0.6719 -0.0938 +vn -0.3795 0.8018 -0.4616 +vn 0.0861 0.7063 -0.7026 +vn 0.5281 0.4105 -0.7434 +vn 0.8183 0.0017 -0.5748 +vn 0.8799 -0.4032 -0.2513 +vn 0.7057 -0.6958 0.1335 +vn 0.3504 -0.8049 0.4789 +vn -0.6573 -0.5890 0.4701 +vn -0.2551 -0.8814 0.3976 +vn -0.8942 -0.1454 0.4233 +vn -0.9017 0.3407 0.2662 +vn -0.6682 0.7431 0.0355 +vn -0.2460 0.9465 -0.2089 +vn -0.7346 0.6719 -0.0938 +vn 0.0861 0.7063 -0.7027 +vn 0.2512 0.8830 -0.3966 +vn 0.6769 0.5659 -0.4707 +vn 0.9070 0.0919 -0.4109 +vn 0.8846 -0.4002 -0.2394 +vn 0.6279 -0.7783 -0.0069 +vn 0.2115 -0.9512 0.2247 +vn 0.6278 -0.7783 -0.0069 +vn -0.7638 -0.6302 0.1398 +vn -0.3722 -0.9276 0.0319 +vn -0.9623 -0.1703 0.2123 +vn -0.7638 -0.6302 0.1397 +vn -0.9120 0.3391 0.2306 +vn -0.6164 0.7645 0.1886 +vn -0.1459 0.9847 0.0954 +vn 0.3699 0.9287 -0.0254 +vn 0.7811 0.6085 -0.1403 +vn 0.9693 0.1195 -0.2148 +vn 0.8895 -0.3958 -0.2284 +vn 0.5742 -0.7988 -0.1796 +vn 0.1139 -0.9899 -0.0843 +vn -0.8105 -0.5645 -0.1560 +vn -0.4226 -0.8565 -0.2964 +vn -0.9918 -0.1256 0.0252 +vn -0.8105 -0.5646 -0.1560 +vn -0.9147 0.3502 0.2019 +vn -0.5909 0.7372 0.3275 +vn -0.1013 0.9252 0.3658 +vn 0.4201 0.8558 0.3020 +vn 0.8238 0.5461 0.1524 +vn 0.9956 0.0856 -0.0391 +vn 0.8237 0.5461 0.1524 +vn 0.8932 -0.3939 -0.2168 +vn 0.5538 -0.7630 -0.3334 +vn 0.0737 -0.9295 -0.3613 +vn -0.8112 -0.4402 -0.3849 +vn -0.4223 -0.7195 -0.5513 +vn -0.9919 -0.0457 -0.1182 +vn -0.9134 0.3642 0.1821 +vn -0.5886 0.6802 0.4369 +vn -0.0995 0.8123 0.5747 +vn 0.4199 0.7193 0.5534 +vn 0.8224 0.4256 0.3774 +vn 0.9951 0.0153 0.0975 +vn 0.8947 -0.3961 -0.2064 +vn 0.5563 -0.6976 -0.4516 +vn 0.0753 -0.8139 -0.5761 +vn -0.7796 -0.2798 -0.5603 +vn -0.3870 -0.5411 -0.7466 +vn -0.9721 0.0551 -0.2281 +vn -0.9105 0.3784 0.1669 +vn -0.6037 0.6035 0.5209 +vn -0.1283 0.6654 0.7353 +vn 0.3850 0.5427 0.7465 +vn -0.1284 0.6654 0.7353 +vn 0.8224 0.4257 0.3774 +vn 0.7914 0.2684 0.5493 +vn 0.9951 0.0152 0.0974 +vn 0.9764 -0.0790 0.2010 +vn 0.8937 -0.4020 -0.1994 +vn 0.5732 -0.6140 -0.5426 +vn 0.1054 -0.6633 -0.7409 +vn -0.7163 -0.0778 -0.6934 +vn -0.3172 -0.3154 -0.8944 +vn -0.3870 -0.5411 -0.7467 +vn -0.9325 0.1809 -0.3127 +vn -0.9059 0.3948 0.1536 +vn -0.6354 0.5057 0.5835 +vn -0.1872 0.4795 0.8573 +vn 0.3160 0.3195 0.8934 +vn -0.1872 0.4796 0.8573 +vn 0.7307 0.0692 0.6791 +vn 0.9399 -0.1991 0.2774 +vn 0.8907 -0.4099 -0.1968 +vn 0.6046 -0.5082 -0.6134 +vn 0.1634 -0.4724 -0.8661 +vn -0.6153 0.1736 -0.7689 +vn -0.2052 -0.0352 -0.9781 +vn -0.8687 0.3385 -0.3616 +vn -0.8980 0.4161 0.1430 +vn -0.6888 0.3828 0.6157 +vn -0.2871 0.2429 0.9266 +vn 0.2006 0.0328 0.9791 +vn 0.6317 -0.1860 0.7525 +vn 0.8812 -0.3505 0.3173 +vn 0.8866 -0.4180 -0.1980 +vn 0.8812 -0.3504 0.3173 +vn 0.6569 -0.3750 -0.6541 +vn 0.2584 -0.2352 -0.9370 +vn 0.2583 -0.2352 -0.9370 +vn -0.5163 0.3886 -0.7632 +vn -0.0978 0.1904 -0.9768 +vn -0.8010 0.4861 -0.3494 +vn -0.8762 0.4551 0.1585 +vn -0.7186 0.3009 0.6269 +vn -0.3674 0.0632 0.9279 +vn 0.0849 -0.1928 0.9776 +vn 0.5162 -0.3955 0.7597 +vn 0.8062 -0.4894 0.3324 +vn 0.8736 -0.4502 -0.1846 +vn 0.7035 -0.2914 -0.6482 +vn 0.3473 -0.0574 -0.9360 +vn 0.3472 -0.0574 -0.9360 +vn -0.4769 0.4703 -0.7425 +vn -0.0676 0.2469 -0.9667 +vn -0.7580 0.5680 -0.3208 +vn -0.8372 0.5146 0.1850 +vn -0.7579 0.5680 -0.3208 +vn -0.6950 0.3248 0.6415 +vn -0.3689 0.0485 0.9282 +vn 0.0550 -0.2410 0.9690 +vn 0.4656 -0.4670 0.7518 +vn 0.7527 -0.5683 0.3323 +vn 0.8375 -0.5163 -0.1789 +vn 0.6942 -0.3239 -0.6427 +vn 0.3617 -0.0438 -0.9313 +vn -0.4714 0.4757 -0.7426 +vn -0.0848 0.2180 -0.9723 +vn -0.7310 0.6054 -0.3150 +vn -0.7954 0.5736 0.1955 +vn -0.6488 0.3898 0.6536 +vn -0.3301 0.1025 0.9384 +vn 0.0768 -0.2124 0.9742 +vn 0.4640 -0.4713 0.7500 +vn 0.7277 -0.6046 0.3239 +vn 0.7956 -0.5751 -0.1904 +vn 0.6484 -0.3899 -0.6539 +vn 0.3256 -0.0991 -0.9403 +vn -0.4704 0.4747 -0.7439 +vn -0.1013 0.1943 -0.9757 +vn -0.7130 0.6274 -0.3132 +vn -0.7648 0.6123 0.2003 +vn -0.6130 0.4343 0.6601 +vn -0.2981 0.1407 0.9441 +vn 0.0964 -0.1905 0.9769 +vn -0.2981 0.1408 0.9441 +vn 0.4658 -0.4714 0.7489 +vn 0.7109 -0.6265 0.3197 +vn 0.7651 -0.6133 -0.1961 +vn 0.7108 -0.6265 0.3197 +vn 0.6131 -0.4348 -0.6596 +vn 0.2956 -0.1388 -0.9452 +vn 0.2957 -0.1388 -0.9452 +vn -0.4739 0.4688 -0.7454 +vn -0.1157 0.1749 -0.9778 +vn -0.7045 0.6367 -0.3134 +vn -0.7465 0.6340 0.2021 +vn -0.5890 0.4620 0.6631 +vn -0.2744 0.1668 0.9470 +vn 0.1134 -0.1730 0.9784 +vn 0.4712 -0.4668 0.7484 +vn 0.7032 -0.6360 0.3178 +vn 0.7468 -0.6347 -0.1985 +vn 0.7033 -0.6360 0.3178 +vn 0.5897 -0.4629 -0.6619 +vn 0.2738 -0.1664 -0.9473 +vn -0.4815 0.4583 -0.7470 +vn -0.1279 0.1586 -0.9790 +vn -0.7058 0.6348 -0.3144 +vn -0.7405 0.6409 0.2022 +vn -0.7057 0.6349 -0.3145 +vn -0.5769 0.4753 0.6643 +vn -0.2590 0.1827 0.9484 +vn 0.1279 -0.1587 0.9790 +vn 0.4807 -0.4576 0.7480 +vn 0.7051 -0.6344 0.3169 +vn 0.7409 -0.6414 -0.1992 +vn 0.5781 -0.4766 -0.6623 +vn 0.2601 -0.1837 -0.9479 +vn -0.4934 0.4430 -0.7485 +vn -0.1378 0.1449 -0.9798 +vn -0.7165 0.6220 -0.3158 +vn -0.7468 0.6338 0.2017 +vn -0.7165 0.6220 -0.3159 +vn -0.5765 0.4752 0.6647 +vn -0.2517 0.1894 0.9491 +vn 0.1402 -0.1469 0.9792 +vn 0.4943 -0.4436 0.7476 +vn 0.7164 -0.6218 0.3165 +vn 0.7472 -0.6341 -0.1992 +vn 0.5783 -0.4769 -0.6619 +vn 0.2545 -0.1918 -0.9478 +vn -0.5094 0.4219 -0.7500 +vn -0.1455 0.1331 -0.9804 +vn -0.7365 0.5974 -0.3173 +vn -0.7651 0.6118 0.2010 +vn -0.7365 0.5973 -0.3173 +vn -0.5875 0.4613 0.6649 +vn -0.2521 0.1870 0.9495 +vn 0.1504 -0.1370 0.9791 +vn 0.5121 -0.4239 0.7470 +vn 0.7370 -0.5975 0.3161 +vn 0.7655 -0.6119 -0.1989 +vn 0.5901 -0.4633 -0.6611 +vn 0.2570 -0.1909 -0.9474 +vn 0.2569 -0.1908 -0.9474 +vn -0.5293 0.3938 -0.7515 +vn -0.1510 0.1231 -0.9808 +vn -0.7656 0.5587 -0.3189 +vn -0.7950 0.5727 0.2002 +vn -0.7656 0.5587 -0.3190 +vn -0.6094 0.4318 0.6650 +vn -0.2598 0.1746 0.9497 +vn 0.1588 -0.1288 0.9789 +vn 0.5341 -0.3970 0.7464 +vn 0.7667 -0.5591 0.3156 +vn 0.7954 -0.5726 -0.1985 +vn 0.7667 -0.5591 0.3157 +vn 0.6130 -0.4341 -0.6602 +vn 0.2671 -0.1798 -0.9467 +vn 0.2671 -0.1798 -0.9468 +vn -0.5525 0.3567 -0.7533 +vn -0.1541 0.1149 -0.9814 +vn -0.8026 0.5028 -0.3210 +vn -0.8352 0.5127 0.1990 +vn -0.6412 0.3834 0.6648 +vn -0.2741 0.1505 0.9499 +vn 0.1657 -0.1220 0.9786 +vn 0.5599 -0.3610 0.7458 +vn 0.8044 -0.5034 0.3155 +vn 0.8357 -0.5124 -0.1977 +vn 0.6459 -0.3859 -0.6587 +vn 0.2844 -0.1567 -0.9458 +vn 0.2844 -0.1568 -0.9458 +vn -0.5773 0.3086 -0.7560 +vn -0.1549 0.1089 -0.9819 +vn -0.8448 0.4256 -0.3244 +vn -0.8827 0.4269 0.1964 +vn -0.8448 0.4256 -0.3243 +vn -0.6801 0.3117 0.6636 +vn -0.2933 0.1122 0.9494 +vn 0.1712 -0.1167 0.9783 +vn 0.5880 -0.3133 0.7457 +vn 0.8476 -0.4260 0.3164 +vn 0.8832 -0.4262 -0.1956 +vn 0.8476 -0.4260 0.3163 +vn 0.6862 -0.3142 -0.6561 +vn 0.3072 -0.1189 -0.9442 +vn -0.6005 0.2473 -0.7605 +vn -0.1536 0.1058 -0.9824 +vn -0.8869 0.3226 -0.3306 +vn -0.9314 0.3099 0.1911 +vn -0.7206 0.2123 0.6601 +vn -0.3140 0.0571 0.9477 +vn 0.1753 -0.1128 0.9780 +vn 0.6152 -0.2518 0.7471 +vn 0.8904 -0.3237 0.3199 +vn 0.9313 -0.3102 -0.1907 +vn 0.7278 -0.2153 -0.6511 +vn 0.3321 -0.0635 -0.9411 +vn -0.6143 0.2060 -0.7617 +vn -0.1532 0.1228 -0.9805 +vn -0.9119 0.2339 -0.3372 +vn -0.9634 0.1987 0.1800 +vn -0.7529 0.1096 0.6489 +vn -0.3378 -0.0092 0.9412 +vn 0.1677 -0.1255 0.9778 +vn 0.6261 -0.2080 0.7515 +vn 0.9159 -0.2348 0.3256 +vn 0.9623 -0.1991 -0.1855 +vn 0.7545 -0.1108 -0.6469 +vn 0.3472 0.0069 -0.9378 +vn -0.6125 0.2258 -0.7575 +vn -0.1473 0.1789 -0.9728 +vn -0.9161 0.2127 -0.3400 +vn -0.9752 0.1426 0.1693 +vn -0.7718 0.0342 0.6349 +vn -0.3590 -0.0837 0.9296 +vn 0.1516 -0.1791 0.9721 +vn -0.3589 -0.0837 0.9296 +vn 0.6205 -0.2260 0.7509 +vn 0.9209 -0.2118 0.3274 +vn 0.9731 -0.1408 -0.1821 +vn 0.9209 -0.2117 0.3274 +vn 0.7662 -0.0323 -0.6418 +vn 0.3565 0.0846 -0.9305 +vn -0.6012 0.2879 -0.7454 +vn -0.1323 0.2660 -0.9548 +vn -0.9119 0.2334 -0.3376 +vn -0.9799 0.1165 0.1622 +vn -0.7838 -0.0322 0.6202 +vn -0.3743 -0.1724 0.9111 +vn 0.1374 -0.2658 0.9542 +vn 0.6112 -0.2870 0.7377 +vn 0.9182 -0.2303 0.3223 +vn 0.9776 -0.1120 -0.1779 +vn 0.9182 -0.2304 0.3223 +vn 0.7767 0.0359 -0.6289 +vn 0.3709 0.1740 -0.9122 +vn -0.5878 0.3668 -0.7210 +vn -0.1152 0.3746 -0.9200 +vn -0.9066 0.2621 -0.3306 +vn -0.9848 0.0870 0.1502 +vn -0.9067 0.2621 -0.3306 +vn -0.7973 -0.1120 0.5931 +vn -0.3919 -0.2811 0.8760 +vn 0.1212 -0.3736 0.9196 +vn 0.6004 -0.3641 0.7120 +vn 0.9150 -0.2558 0.3119 +vn 0.9823 -0.0789 -0.1698 +vn 0.7882 0.1184 -0.6039 +vn 0.3871 0.2838 -0.8773 +vn 0.3871 0.2839 -0.8773 +vn -0.5725 0.4656 -0.6749 +vn -0.0961 0.5075 -0.8563 +vn -0.9001 0.3010 -0.3149 +vn -0.9897 0.0554 0.1316 +vn -0.9002 0.3009 -0.3149 +vn -0.8121 -0.2061 0.5459 +vn -0.4114 -0.4121 0.8130 +vn 0.1033 -0.5053 0.8567 +vn 0.5885 -0.4599 0.6649 +vn 0.9113 -0.2892 0.2930 +vn 0.9870 -0.0413 -0.1551 +vn 0.9113 -0.2892 0.2929 +vn 0.8004 0.2166 -0.5589 +vn 0.4047 0.4167 -0.8140 +vn 0.4046 0.4167 -0.8140 +vn -0.5564 0.5818 -0.5932 +vn -0.0766 0.6607 -0.7468 +vn -0.8928 0.3501 -0.2834 +vn -0.9942 0.0239 0.1046 +vn -0.8271 -0.3108 0.4684 +vn -0.4314 -0.5615 0.7061 +vn 0.0847 -0.6577 0.7485 +vn 0.5764 -0.5721 0.5835 +vn 0.9074 -0.3303 0.2599 +vn 0.9915 -0.0007 -0.1304 +vn 0.8124 0.3272 -0.4826 +vn 0.4222 0.5679 -0.7065 +vn 0.4222 0.5680 -0.7065 +vn -0.5424 0.7012 -0.4627 +vn -0.0601 0.8152 -0.5760 +vn -0.8861 0.4036 -0.2280 +vn -0.9976 -0.0035 0.0695 +vn -0.8398 -0.4132 0.3521 +vn -0.4489 -0.7117 0.5403 +vn 0.0686 -0.8129 0.5783 +vn -0.4314 -0.5616 0.7061 +vn 0.5657 -0.6879 0.4547 +vn 0.9038 -0.3745 0.2070 +vn 0.9949 0.0374 -0.0933 +vn 0.8224 0.4360 -0.3656 +vn 0.4370 0.7188 -0.5408 +vn -0.0766 0.6607 -0.7467 +vn -0.5344 0.7960 -0.2842 +vn -0.0505 0.9364 -0.3474 +vn -0.8821 0.4476 -0.1468 +vn -0.9993 -0.0225 0.0306 +vn -0.8472 -0.4915 0.2016 +vn -0.4595 -0.8290 0.3188 +vn -0.8399 -0.4132 0.3520 +vn 0.0584 -0.9360 0.3472 +vn 0.5588 -0.7811 0.2785 +vn 0.9013 -0.4122 0.1335 +vn 0.9969 0.0641 -0.0461 +vn 0.9013 -0.4122 0.1334 +vn 0.8283 0.5188 -0.2118 +vn 0.4456 0.8357 -0.3211 +vn 0.8223 0.4360 -0.3655 +vn -0.5340 0.8414 -0.0827 +vn -0.0494 0.9944 -0.0935 +vn -0.8821 0.4684 -0.0505 +vn -0.5345 0.7960 -0.2842 +vn -0.9995 -0.0321 -0.0052 +vn -0.8478 -0.5288 0.0410 +vn -0.4611 -0.8841 0.0756 +vn 0.0556 -0.9944 0.0898 +vn 0.5563 -0.8272 0.0796 +vn 0.9000 -0.4333 0.0470 +vn 0.5562 -0.8272 0.0796 +vn 0.5588 -0.7811 0.2786 +vn 0.9973 0.0735 0.0007 +vn 0.8297 0.5564 -0.0456 +vn 0.4472 0.8908 -0.0800 +vn -0.5391 0.8355 0.1064 +vn -0.0544 0.9884 0.1415 +vn -0.8852 0.4633 0.0433 +vn -0.5392 0.8355 0.1064 +vn -0.9989 -0.0345 -0.0325 +vn -0.8438 -0.5269 -0.1014 +vn -0.4564 -0.8781 -0.1437 +vn -0.8439 -0.5269 -0.1014 +vn 0.0587 -0.9876 -0.1459 +vn 0.5572 -0.8235 -0.1069 +vn 0.9001 -0.4340 -0.0393 +vn 0.9969 0.0699 0.0373 +vn 0.8282 0.5511 0.1023 +vn 0.4439 0.8851 0.1400 +vn -0.5462 0.7957 0.2619 +vn -0.0615 0.9414 0.3317 +vn -0.8893 0.4404 0.1230 +vn -0.9982 -0.0337 -0.0499 +vn -0.8389 -0.5017 -0.2113 +vn -0.4495 -0.8354 -0.3163 +vn -0.8388 -0.5017 -0.2113 +vn 0.0640 -0.9402 -0.3347 +vn 0.5600 -0.7866 -0.2603 +vn 0.9010 -0.4183 -0.1152 +vn 0.9964 0.0609 0.0593 +vn 0.8258 0.5209 0.2161 +vn 0.4390 0.8414 0.3151 +vn -0.5525 0.7410 0.3816 +vn -0.0678 0.8771 0.4755 +vn -0.8931 0.4092 0.1868 +vn -0.9977 -0.0330 -0.0587 +vn -0.8344 -0.4687 -0.2899 +vn -0.4440 -0.7786 -0.4435 +vn 0.0688 -0.8767 -0.4762 +vn 0.5627 -0.7349 -0.3786 +vn 0.9021 -0.3932 -0.1780 +vn 0.9962 0.0531 0.0695 +vn 0.8237 0.4830 0.2971 +vn 0.4346 0.7832 0.4447 +vn 0.8237 0.4830 0.2970 +vn -0.5558 0.6758 0.4841 +vn -0.0721 0.7972 0.5994 +vn -0.8947 0.3760 0.2409 +vn -0.9974 -0.0262 -0.0674 +vn -0.8315 -0.4242 -0.3587 +vn -0.4387 -0.7083 -0.5531 +vn -0.8315 -0.4243 -0.3587 +vn 0.0751 -0.7989 -0.5968 +vn 0.5684 -0.6703 -0.4771 +vn 0.0688 -0.8767 -0.4761 +vn 0.9049 -0.3596 -0.2276 +vn 0.9955 0.0461 0.0828 +vn 0.8201 0.4367 0.3698 +vn 0.4299 0.7100 0.5578 +vn -0.5585 0.5720 0.6007 +vn -0.0794 0.6606 0.7465 +vn -0.8947 0.3333 0.2974 +vn -0.9962 0.0029 -0.0871 +vn -0.8285 -0.3326 -0.4506 +vn -0.9974 -0.0263 -0.0674 +vn -0.4308 -0.5793 -0.6920 +vn 0.0881 -0.6648 -0.7418 +vn 0.5814 -0.5648 -0.5857 +vn 0.0880 -0.6648 -0.7418 +vn 0.9115 -0.3108 -0.2693 +vn 0.9928 0.0234 0.1179 +vn 0.8109 0.3474 0.4709 +vn 0.9927 0.0234 0.1179 +vn 0.4194 0.5788 0.6993 +vn -0.5727 0.3987 0.7163 +vn -0.1004 0.4294 0.8975 +vn -0.8994 0.2643 0.3482 +vn -0.9916 0.0574 -0.1163 +vn -0.8149 -0.1689 -0.5545 +vn -0.9916 0.0573 -0.1163 +vn -0.4093 -0.3502 -0.8425 +vn 0.1134 -0.4328 -0.8943 +vn 0.6024 -0.3934 -0.6945 +vn 0.9200 -0.2464 -0.3046 +vn 0.9861 -0.0360 0.1623 +vn 0.7925 0.1813 0.5822 +vn 0.3962 0.3503 0.8487 +vn -0.6004 0.1837 0.7783 +vn -0.1384 0.1374 0.9808 +vn -0.9101 0.1825 0.3719 +vn -0.9815 0.1333 -0.1377 +vn -0.7859 0.0483 -0.6165 +vn -0.3685 -0.0502 -0.9283 +vn 0.1545 -0.1352 -0.9787 +vn 0.6313 -0.1825 -0.7538 +vn 0.1544 -0.1352 -0.9787 +vn 0.9292 -0.1791 -0.3234 +vn 0.9741 -0.1262 0.1876 +vn 0.7634 -0.0403 0.6446 +vn 0.3579 0.0559 0.9321 +vn -0.6359 -0.0066 0.7717 +vn -0.1853 -0.1302 0.9740 +vn -0.9230 0.1198 0.3656 +vn -0.9659 0.2169 -0.1415 +vn -0.7453 0.2578 -0.6148 +vn -0.9659 0.2169 -0.1416 +vn -0.3169 0.2286 -0.9205 +vn 0.2006 0.1344 -0.9704 +vn 0.6603 0.0025 -0.7510 +vn 0.9361 -0.1282 -0.3275 +vn 0.9585 -0.2212 0.1798 +vn 0.7289 -0.2539 0.6358 +vn 0.3118 -0.2203 0.9243 +vn -0.6666 -0.1281 0.7343 +vn -0.2273 -0.3138 0.9219 +vn -0.9316 0.0928 0.3514 +vn -0.9481 0.2913 -0.1277 +vn -0.7066 0.4130 -0.5745 +vn -0.2706 0.4222 -0.8652 +vn 0.2398 0.3146 -0.9184 +vn 0.6832 0.1208 -0.7202 +vn 0.2398 0.3147 -0.9184 +vn 0.9391 -0.1041 -0.3274 +vn 0.9424 -0.2984 0.1508 +vn 0.6970 -0.4121 0.5869 +vn 0.2700 -0.4173 0.8677 +vn -0.2274 -0.3138 0.9219 +vn -0.6858 -0.1855 0.7038 +vn -0.2568 -0.4153 0.8727 +vn -0.9332 0.0949 0.3466 +vn -0.9304 0.3513 -0.1050 +vn -0.6753 0.5137 -0.5292 +vn -0.9303 0.3513 -0.1050 +vn -0.2362 0.5367 -0.8100 +vn 0.2667 0.4134 -0.8706 +vn 0.6961 0.1785 -0.6954 +vn 0.9371 -0.1037 -0.3333 +vn 0.9270 -0.3564 0.1165 +vn 0.6714 -0.5136 0.5343 +vn 0.2390 -0.5349 0.8104 +vn -0.6924 -0.1977 0.6939 +vn -0.2722 -0.4582 0.8461 +vn -0.9275 0.1167 0.3552 +vn -0.9129 0.4004 -0.0799 +vn -0.6514 0.5762 -0.4936 +vn -0.9129 0.4004 -0.0798 +vn -0.2139 0.5961 -0.7739 +vn 0.2806 0.4550 -0.8451 +vn 0.6987 0.1920 -0.6891 +vn 0.2806 0.4551 -0.8451 +vn 0.9291 -0.1216 -0.3492 +vn 0.9118 -0.4021 0.0833 +vn 0.6523 -0.5755 0.4933 +vn 0.2195 -0.5961 0.7723 +vn -0.6856 -0.1767 0.7062 +vn -0.2730 -0.4595 0.8452 +vn -0.9135 0.1542 0.3765 +vn -0.8945 0.4436 -0.0550 +vn -0.6341 0.6130 -0.4714 +vn -0.2036 0.6169 -0.7603 +vn 0.2805 0.4555 -0.8449 +vn 0.6889 0.1729 -0.7040 +vn 0.9136 -0.1552 -0.3759 +vn 0.8955 -0.4419 0.0519 +vn 0.6393 -0.6114 0.4663 +vn 0.2120 -0.6182 0.7569 +vn -0.6624 -0.1262 0.7384 +vn -0.2563 -0.4257 0.8678 +vn -0.8887 0.2078 0.4086 +vn -0.8739 0.4851 -0.0315 +vn -0.6235 0.6306 -0.4622 +vn -0.2069 0.6064 -0.7678 +vn 0.2635 0.4208 -0.8680 +vn 0.6632 0.1241 -0.7381 +vn 0.8873 -0.2051 -0.4130 +vn 0.8767 -0.4805 0.0219 +vn 0.6327 -0.6288 0.4520 +vn 0.2182 -0.6094 0.7622 +vn -0.2564 -0.4257 0.8678 +vn -0.6172 -0.0444 0.7855 +vn -0.2165 -0.3568 0.9088 +vn -0.8491 0.2802 0.4479 +vn -0.8494 0.5276 -0.0107 +vn -0.6210 0.6313 -0.4646 +vn -0.2281 0.5657 -0.7924 +vn 0.2235 0.3506 -0.9095 +vn 0.6155 0.0439 -0.7869 +vn 0.2235 0.3506 -0.9094 +vn 0.8458 -0.2744 -0.4575 +vn 0.8535 -0.5211 -0.0064 +vn 0.6338 -0.6305 0.4482 +vn 0.2423 -0.5712 0.7842 +vn -0.2166 -0.3568 0.9087 +vn -0.5415 0.0736 0.8375 +vn -0.1448 -0.2489 0.9576 +vn -0.7888 0.3754 0.4867 +vn -0.8196 0.5728 0.0046 +vn -0.6297 0.6147 -0.4749 +vn -0.8197 0.5728 0.0046 +vn -0.2737 0.4932 -0.8257 +vn 0.1526 0.2430 -0.9580 +vn 0.5385 -0.0703 -0.8397 +vn 0.1526 0.2429 -0.9580 +vn 0.7841 -0.3658 -0.5014 +vn 0.8238 -0.5661 -0.0302 +vn 0.6445 -0.6170 0.4515 +vn 0.2905 -0.5020 0.8146 +vn -0.4633 0.1892 0.8658 +vn -0.0642 -0.1249 0.9901 +vn -0.7355 0.4504 0.5062 +vn -0.8081 0.5889 0.0121 +vn -0.6647 0.5701 -0.4829 +vn -0.3459 0.4013 -0.8481 +vn 0.0633 0.1275 -0.9898 +vn 0.4560 -0.1801 -0.8716 +vn 0.7290 -0.4410 -0.5236 +vn 0.8095 -0.5861 -0.0346 +vn 0.6729 -0.5741 0.4664 +vn 0.3529 -0.4054 0.8433 +vn -0.4273 0.2445 0.8704 +vn -0.0087 -0.0352 0.9993 +vn -0.7292 0.4573 0.5091 +vn -0.8364 0.5480 0.0132 +vn -0.7219 0.4937 -0.4850 +vn -0.4171 0.3096 -0.8545 +vn -0.0021 0.0436 -0.9990 +vn 0.4146 -0.2351 -0.8791 +vn 0.7220 -0.4517 -0.5240 +vn 0.8363 -0.5478 -0.0255 +vn 0.7233 -0.4947 0.4817 +vn 0.8362 -0.5478 -0.0255 +vn 0.4133 -0.3064 0.8575 +vn -0.4171 0.2594 0.8710 +vn 0.0261 0.0214 0.9994 +vn -0.7470 0.4270 0.5096 +vn -0.8769 0.4805 0.0138 +vn -0.7744 0.4068 -0.4845 +vn -0.4676 0.2257 -0.8547 +vn -0.0367 -0.0154 -0.9992 +vn 0.4051 -0.2531 -0.8785 +vn 0.7401 -0.4237 -0.5222 +vn 0.8767 -0.4805 -0.0238 +vn 0.7757 -0.4071 0.4823 +vn 0.4636 -0.2229 0.8575 +vn 0.0261 0.0215 0.9994 +vn -0.4111 0.2690 0.8710 +vn 0.0507 0.0684 0.9964 +vn -0.7613 0.3969 0.5127 +vn -0.9078 0.4189 0.0189 +vn -0.8134 0.3298 -0.4791 +vn -0.5038 0.1534 -0.8501 +vn -0.0602 -0.0638 -0.9961 +vn 0.4005 -0.2647 -0.8772 +vn -0.0601 -0.0638 -0.9961 +vn 0.7553 -0.3951 -0.5229 +vn 0.9075 -0.4193 -0.0265 +vn 0.8141 -0.3299 0.4779 +vn 0.4999 -0.1511 0.8528 +vn -0.4083 0.2728 0.8711 +vn 0.0668 0.1044 0.9923 +vn -0.7729 0.3679 0.5171 +vn -0.9307 0.3647 0.0260 +vn -0.8413 0.2648 -0.4713 +vn -0.9308 0.3647 0.0260 +vn -0.5286 0.0945 -0.8436 +vn -0.0751 -0.1011 -0.9920 +vn 0.3994 -0.2701 -0.8761 +vn 0.7680 -0.3670 -0.5249 +vn 0.9304 -0.3652 -0.0315 +vn 0.8415 -0.2646 0.4710 +vn 0.9304 -0.3652 -0.0314 +vn 0.5248 -0.0925 0.8462 +vn -0.4078 0.2713 0.8718 +vn 0.0766 0.1296 0.9886 +vn -0.7821 0.3402 0.5221 +vn -0.9474 0.3183 0.0337 +vn -0.8413 0.2647 -0.4714 +vn -0.8605 0.2117 -0.4633 +vn -0.5449 0.0489 -0.8371 +vn -0.0837 -0.1272 -0.9883 +vn 0.4007 -0.2695 -0.8757 +vn 0.7784 -0.3398 -0.5278 +vn 0.4006 -0.2695 -0.8757 +vn 0.9471 -0.3186 -0.0372 +vn 0.8415 -0.2646 0.4711 +vn 0.8603 -0.2114 0.4638 +vn 0.5412 -0.0471 0.8396 +vn -0.4089 0.2647 0.8733 +vn 0.0819 0.1447 0.9861 +vn -0.7896 0.3138 0.5273 +vn -0.9594 0.2791 0.0410 +vn -0.8735 0.1701 -0.4561 +vn -0.5549 0.0158 -0.8318 +vn -0.0878 -0.1430 -0.9858 +vn 0.4034 -0.2636 -0.8762 +vn 0.7871 -0.3137 -0.5312 +vn 0.9592 -0.2793 -0.0428 +vn 0.8730 -0.1696 0.4574 +vn 0.5514 -0.0143 0.8341 +vn 0.8729 -0.1696 0.4574 +vn -0.4108 0.2545 0.8755 +vn 0.0840 0.1505 0.9850 +vn -0.7958 0.2886 0.5324 +vn -0.9679 0.2467 0.0473 +vn -0.8819 0.1390 -0.4504 +vn -0.5605 -0.0058 -0.8281 +vn -0.8820 0.1390 -0.4504 +vn -0.0889 -0.1493 -0.9848 +vn 0.4071 -0.2528 -0.8777 +vn 0.7942 -0.2886 -0.5347 +vn 0.9679 -0.2467 -0.0476 +vn 0.8810 -0.1383 0.4524 +vn 0.5572 0.0071 0.8304 +vn 0.8811 -0.1383 0.4523 +vn 0.0837 0.1494 0.9852 +vn -0.4110 0.2534 0.8757 +vn -0.4139 0.2378 0.8787 +vn 0.0839 0.1478 0.9855 +vn -0.8009 0.2643 0.5373 +vn -0.9740 0.2202 0.0526 +vn -0.8872 0.1173 -0.4463 +vn -0.5631 -0.0170 -0.8262 +vn -0.8871 0.1173 -0.4463 +vn -0.0879 -0.1469 -0.9852 +vn 0.4113 -0.2375 -0.8800 +vn 0.8003 -0.2643 -0.5382 +vn 0.9741 -0.2200 -0.0514 +vn 0.8859 -0.1166 0.4490 +vn 0.5598 0.0181 0.8284 +vn -0.4173 0.2181 0.8822 +vn 0.0822 0.1372 0.9871 +vn -0.8053 0.2408 0.5417 +vn -0.4174 0.2181 0.8822 +vn -0.9783 0.1992 0.0566 +vn -0.8900 0.1043 -0.4439 +vn -0.5633 -0.0186 -0.8260 +vn -0.8900 0.1042 -0.4439 +vn -0.0853 -0.1366 -0.9869 +vn 0.4160 -0.2180 -0.8828 +vn 0.8056 -0.2408 -0.5413 +vn 0.9785 -0.1988 -0.0542 +vn 0.8885 -0.1034 0.4471 +vn 0.5602 0.0196 0.8282 +vn -0.4212 0.1945 0.8859 +vn 0.0793 0.1193 0.9897 +vn -0.8092 0.2178 0.5457 +vn -0.9813 0.1829 0.0596 +vn -0.8911 0.0991 -0.4429 +vn -0.5620 -0.0114 -0.8271 +vn -0.0816 -0.1189 -0.9895 +vn 0.4210 -0.1945 -0.8860 +vn 0.8103 -0.2178 -0.5440 +vn 0.4209 -0.1945 -0.8860 +vn 0.9816 -0.1825 -0.0560 +vn 0.8893 -0.0982 0.4467 +vn 0.5588 0.0122 0.8292 +vn -0.4253 0.1669 0.8895 +vn 0.0753 0.0942 0.9927 +vn -0.8127 0.1951 0.5490 +vn -0.9833 0.1711 0.0616 +vn -0.8908 0.1011 -0.4430 +vn -0.5592 0.0038 -0.8290 +vn -0.0770 -0.0946 -0.9925 +vn 0.4260 -0.1675 -0.8891 +vn 0.8145 -0.1954 -0.5463 +vn 0.9837 -0.1707 -0.0569 +vn 0.8887 -0.1005 0.4474 +vn 0.5561 -0.0035 0.8311 +vn -0.4324 0.1003 0.8961 +vn 0.0637 0.0214 0.9977 +vn -0.8160 0.1529 0.5574 +vn -0.9839 0.1647 0.0693 +vn -0.8883 0.1316 -0.4399 +vn -0.5521 0.0622 -0.8314 +vn -0.8883 0.1315 -0.4400 +vn -0.0647 -0.0244 -0.9976 +vn 0.4401 -0.1038 -0.8919 +vn 0.8248 -0.1550 -0.5437 +vn 0.4401 -0.1038 -0.8920 +vn 0.9851 -0.1645 -0.0501 +vn 0.8808 -0.1307 0.4551 +vn 0.5432 -0.0629 0.8372 +vn -0.4548 -0.0563 0.8888 +vn 0.0336 -0.1573 0.9870 +vn -0.8268 0.0598 0.5594 +vn -0.9838 0.1605 0.0796 +vn -0.8780 0.2180 -0.4261 +vn -0.5306 0.2153 -0.8198 +vn -0.0341 0.1529 -0.9876 +vn 0.4719 0.0486 -0.8803 +vn 0.8449 -0.0686 -0.5306 +vn 0.9851 -0.1671 -0.0397 +vn 0.8616 -0.2212 0.4568 +vn 0.5133 -0.2174 0.8302 +vn -0.4940 -0.2792 0.8234 +vn -0.0138 -0.4132 0.9105 +vn -0.8491 -0.0724 0.5232 +vn -0.9845 0.1550 0.0822 +vn -0.8566 0.3427 -0.3858 +vn -0.4914 0.4372 -0.7532 +vn 0.0135 0.4100 -0.9120 +vn 0.5146 0.2682 -0.8144 +vn 0.8695 0.0528 -0.4911 +vn 0.9838 -0.1755 -0.0377 +vn 0.8350 -0.3553 0.4202 +vn 0.4700 -0.4411 0.7645 +vn -0.5399 -0.5023 0.6754 +vn -0.0674 -0.6694 0.7399 +vn -0.8758 -0.2052 0.4369 +vn -0.9855 0.1487 0.0813 +vn -0.8316 0.4669 -0.3008 +vn -0.4460 0.6597 -0.6048 +vn 0.0676 0.6685 -0.7406 +vn 0.5623 0.4885 -0.6672 +vn 0.8962 0.1737 -0.4082 +vn 0.9819 -0.1851 -0.0411 +vn 0.8058 -0.4904 0.3321 +vn 0.4220 -0.6656 0.6155 +vn -0.5829 -0.6727 0.4556 +vn -0.1168 -0.8655 0.4870 +vn -0.0674 -0.6694 0.7398 +vn -0.9014 -0.3056 0.3067 +vn -0.5830 -0.6727 0.4556 +vn -0.9865 0.1454 0.0759 +vn -0.8071 0.5631 -0.1776 +vn -0.4029 0.8305 -0.3847 +vn 0.1175 0.8665 -0.4852 +vn 0.5624 0.4885 -0.6672 +vn 0.6046 0.6579 -0.4491 +vn 0.9195 0.2673 -0.2881 +vn 0.6046 0.6578 -0.4491 +vn 0.9802 -0.1914 -0.0500 +vn 0.7800 -0.5933 0.1989 +vn 0.3791 -0.8373 0.3939 +vn -0.1168 -0.8656 0.4870 +vn -0.6151 -0.7607 0.2072 +vn -0.1529 -0.9676 0.2010 +vn -0.9207 -0.3562 0.1598 +vn -0.9868 0.1460 0.0702 +vn -0.7880 0.6145 -0.0385 +vn -0.3700 0.9189 -0.1371 +vn -0.7879 0.6146 -0.0386 +vn 0.1536 0.9681 -0.1978 +vn -0.3701 0.9188 -0.1371 +vn 0.6342 0.7458 -0.2037 +vn 0.9357 0.3178 -0.1530 +vn 0.9794 -0.1925 -0.0604 +vn 0.9358 0.3177 -0.1530 +vn 0.7622 -0.6456 0.0480 +vn 0.3484 -0.9264 0.1432 +vn 0.3483 -0.9264 0.1432 +vn -0.6343 -0.7724 -0.0317 +vn -0.1740 -0.9819 -0.0745 +vn -0.9321 -0.3616 0.0195 +vn -0.9867 0.1481 0.0663 +vn -0.7763 0.6230 0.0962 +vn -0.3700 0.9188 -0.1371 +vn -0.3506 0.9311 0.1003 +vn 0.1745 0.9817 0.0767 +vn 0.6511 0.7583 0.0312 +vn 0.9450 0.3264 -0.0226 +vn 0.9792 -0.1906 -0.0694 +vn 0.7524 -0.6516 -0.0967 +vn 0.3308 -0.9386 -0.0983 +vn -0.6419 -0.7257 -0.2475 +vn -0.1824 -0.9284 -0.3239 +vn -0.9367 -0.3336 -0.1065 +vn -0.9867 0.1498 0.0638 +vn -0.7715 0.5974 0.2188 +vn -0.3429 0.8850 0.3150 +vn 0.1828 0.9281 0.3243 +vn 0.6577 0.7129 0.2432 +vn 0.9485 0.3020 0.0954 +vn 0.9792 -0.1877 -0.0771 +vn 0.7487 -0.6227 -0.2272 +vn 0.3241 -0.8914 -0.3167 +vn -0.6395 -0.6297 -0.4410 +vn -0.1797 -0.8173 -0.5475 +vn -0.9353 -0.2777 -0.2195 +vn -0.9867 0.1505 0.0618 +vn -0.7730 0.5425 0.3289 +vn -0.3454 0.7891 0.5079 +vn 0.1803 0.8177 0.5467 +vn 0.6556 0.6184 0.4333 +vn 0.9474 0.2493 0.2008 +vn 0.9792 -0.1843 -0.0845 +vn 0.7500 -0.5645 -0.3447 +vn 0.3264 -0.7941 -0.5128 +vn -0.6270 -0.4833 -0.6110 +vn -0.1658 -0.6476 -0.7438 +vn -0.9279 -0.1930 -0.3191 +vn -0.9868 0.1508 0.0592 +vn -0.7807 0.4579 0.4253 +vn -0.3580 0.6423 0.6777 +vn 0.1665 0.6487 0.7426 +vn -0.3581 0.6423 0.6777 +vn 0.6445 0.4737 0.6002 +vn 0.9413 0.1685 0.2924 +vn 0.6555 0.6184 0.4334 +vn 0.9794 -0.1794 -0.0922 +vn 0.7565 -0.4758 -0.4487 +vn 0.3380 -0.6452 -0.6852 +vn 0.3380 -0.6453 -0.6851 +vn -0.6038 -0.2851 -0.7444 +vn -0.1397 -0.4179 -0.8977 +vn -0.9142 -0.0778 -0.3977 +vn -0.9868 0.1519 0.0566 +vn -0.7945 0.3436 0.5007 +vn -0.3815 0.4429 0.8113 +vn 0.1404 0.4189 0.8971 +vn 0.6230 0.2774 0.7314 +vn 0.1405 0.4189 0.8971 +vn 0.9296 0.0597 0.3637 +vn 0.9801 -0.1717 -0.0993 +vn 0.7695 -0.3547 -0.5310 +vn 0.3603 -0.4436 -0.8206 +vn -0.1396 -0.4180 -0.8977 +vn -0.5716 -0.0497 -0.8190 +vn -0.1022 -0.1458 -0.9840 +vn -0.8954 0.0599 -0.4412 +vn -0.9866 0.1539 0.0549 +vn -0.8142 0.2067 0.5425 +vn -0.4159 0.2023 0.8866 +vn 0.1024 0.1413 0.9847 +vn 0.5915 0.0412 0.8053 +vn 0.9123 -0.0695 0.4035 +vn 0.9816 -0.1612 -0.1026 +vn 0.7898 -0.2101 -0.5762 +vn 0.3938 -0.2044 -0.8962 +vn -0.5465 0.1451 -0.8248 +vn -0.0701 0.0692 -0.9951 +vn -0.8803 0.1829 -0.4378 +vn -0.9828 0.1718 0.0672 +vn -0.8803 0.1829 -0.4377 +vn -0.8228 0.1134 0.5570 +vn -0.4399 0.0229 0.8977 +vn 0.0638 -0.0739 0.9952 +vn -0.4158 0.2023 0.8867 +vn 0.5513 -0.1498 0.8207 +vn 0.8877 -0.1847 0.4218 +vn 0.9812 -0.1704 -0.0907 +vn 0.8102 -0.1118 -0.5754 +vn 0.4249 -0.0244 -0.9049 +vn -0.5347 0.2354 -0.8116 +vn -0.0579 0.1456 -0.9877 +vn -0.8687 0.2626 -0.4200 +vn -0.9720 0.2200 0.0827 +vn -0.8687 0.2627 -0.4200 +vn -0.8175 0.1187 0.5636 +vn -0.4449 -0.0145 0.8955 +vn 0.0464 -0.1441 0.9885 +vn 0.5271 -0.2353 0.8166 +vn 0.8666 -0.2631 0.4240 +vn 0.9719 -0.2198 -0.0840 +vn 0.8138 -0.1174 -0.5691 +vn 0.4358 0.0166 -0.8999 +vn -0.5239 0.2746 -0.8063 +vn -0.0551 0.1539 -0.9865 +vn -0.8525 0.3220 -0.4118 +vn -0.9545 0.2839 0.0914 +vn -0.8525 0.3220 -0.4119 +vn -0.8033 0.1705 0.5707 +vn -0.4382 0.0115 0.8988 +vn 0.0448 -0.1509 0.9875 +vn 0.5170 -0.2731 0.8113 +vn 0.8506 -0.3220 0.4157 +vn 0.9544 -0.2838 -0.0928 +vn 0.7999 -0.1687 -0.5760 +vn 0.4297 -0.0083 -0.9029 +vn 0.4297 -0.0083 -0.9030 +vn -0.5110 0.3111 -0.8013 +vn -0.0520 0.1618 -0.9855 +vn -0.8332 0.3774 -0.4042 +vn -0.9338 0.3435 0.0998 +vn -0.7866 0.2183 0.5775 +vn -0.4299 0.0349 0.9022 +vn 0.0425 -0.1583 0.9865 +vn 0.5046 -0.3094 0.8060 +vn 0.8315 -0.3773 0.4077 +vn 0.9338 -0.3433 -0.1012 +vn 0.7835 -0.2164 -0.5826 +vn 0.4220 -0.0313 -0.9060 +vn 0.4220 -0.0313 -0.9061 +vn -0.4967 0.3445 -0.7966 +vn -0.0483 0.1694 -0.9844 +vn -0.8121 0.4276 -0.3970 +vn -0.9115 0.3970 0.1077 +vn -0.7687 0.2610 0.5840 +vn -0.4210 0.0552 0.9054 +vn 0.0400 -0.1657 0.9854 +vn 0.4911 -0.3426 0.8009 +vn 0.8106 -0.4275 0.4001 +vn 0.9114 -0.3969 -0.1091 +vn 0.7658 -0.2590 -0.5886 +vn 0.4140 -0.0515 -0.9088 +vn -0.4820 0.3740 -0.7924 +vn -0.0442 0.1765 -0.9833 +vn -0.7906 0.4715 -0.3906 +vn -0.8889 0.4435 0.1148 +vn -0.7907 0.4715 -0.3906 +vn -0.7507 0.2976 0.5899 +vn -0.4122 0.0721 0.9082 +vn 0.0371 -0.1730 0.9842 +vn -0.4122 0.0722 0.9082 +vn 0.4772 -0.3721 0.7961 +vn 0.7895 -0.4713 0.3932 +vn 0.8888 -0.4434 -0.1161 +vn 0.7482 -0.2957 -0.5940 +vn 0.4062 -0.0686 -0.9112 +vn -0.4677 0.3991 -0.7887 +vn -0.0398 0.1831 -0.9823 +vn -0.7703 0.5084 -0.3850 +vn -0.8677 0.4822 0.1210 +vn -0.7703 0.5084 -0.3849 +vn -0.7340 0.3276 0.5950 +vn -0.4043 0.0855 0.9106 +vn 0.0340 -0.1799 0.9831 +vn -0.4043 0.0854 0.9106 +vn 0.4639 -0.3974 0.7917 +vn 0.7694 -0.5082 0.3870 +vn 0.8676 -0.4820 -0.1223 +vn 0.7319 -0.3259 -0.5985 +vn 0.3993 -0.0822 -0.9131 +vn 0.3994 -0.0822 -0.9131 +vn -0.4547 0.4197 -0.7856 +vn -0.0353 0.1892 -0.9813 +vn -0.7522 0.5380 -0.3803 +vn -0.8492 0.5128 0.1262 +vn -0.7523 0.5380 -0.3803 +vn -0.7196 0.3509 0.5992 +vn -0.3978 0.0951 0.9125 +vn 0.0309 -0.1865 0.9820 +vn 0.4518 -0.4184 0.7879 +vn 0.7516 -0.5379 0.3818 +vn 0.8491 -0.5127 -0.1273 +vn 0.7180 -0.3494 -0.6020 +vn 0.3939 -0.0923 -0.9145 +vn -0.4436 0.4358 -0.7831 +vn -0.0309 0.1946 -0.9804 +vn -0.7376 0.5604 -0.3767 +vn -0.8345 0.5354 0.1301 +vn -0.7086 0.3674 0.6024 +vn -0.3932 0.1010 0.9139 +vn 0.0278 -0.1926 0.9809 +vn -0.3932 0.1011 0.9139 +vn 0.4417 -0.4348 0.7847 +vn 0.7372 -0.5604 0.3775 +vn 0.8345 -0.5352 -0.1312 +vn 0.7372 -0.5603 0.3776 +vn 0.7074 -0.3662 -0.6046 +vn 0.3904 -0.0990 -0.9153 +vn 0.3904 -0.0989 -0.9153 +vn -0.4351 0.4475 -0.7813 +vn -0.0267 0.1994 -0.9795 +vn -0.7269 0.5757 -0.3743 +vn -0.8244 0.5501 0.1328 +vn -0.7015 0.3774 0.6045 +vn -0.3908 0.1035 0.9146 +vn 0.0249 -0.1982 0.9798 +vn -0.3907 0.1035 0.9147 +vn 0.4341 -0.4469 0.7822 +vn 0.7268 -0.5758 0.3745 +vn 0.8244 -0.5500 -0.1338 +vn 0.7006 -0.3765 -0.6061 +vn 0.3890 -0.1022 -0.9156 +vn -0.4292 0.4549 -0.7803 +vn -0.0228 0.2037 -0.9788 +vn -0.7208 0.5843 -0.3729 +vn -0.8194 0.5573 0.1342 +vn -0.6986 0.3811 0.6056 +vn -0.3906 0.1027 0.9148 +vn 0.0222 -0.2033 0.9789 +vn -0.3905 0.1026 0.9148 +vn 0.4291 -0.4548 0.7804 +vn 0.7209 -0.5843 0.3726 +vn 0.8194 -0.5571 -0.1351 +vn 0.6981 -0.3806 -0.6065 +vn 0.3898 -0.1021 -0.9152 +vn 0.3898 -0.1020 -0.9152 +vn -0.4263 0.4582 -0.7800 +vn -0.0192 0.2075 -0.9781 +vn -0.7192 0.5863 -0.3728 +vn -0.8195 0.5572 0.1343 +vn -0.7000 0.3787 0.6055 +vn -0.3927 0.0986 0.9144 +vn 0.0199 -0.2079 0.9780 +vn 0.4270 -0.4586 0.7793 +vn 0.7197 -0.5863 0.3719 +vn 0.8195 -0.5570 -0.1351 +vn 0.6998 -0.3786 -0.6057 +vn 0.3929 -0.0988 -0.9143 +vn -0.4305 0.4511 -0.7817 +vn -0.0191 0.2051 -0.9786 +vn -0.7265 0.5761 -0.3747 +vn -0.8271 0.5460 0.1332 +vn -0.7265 0.5761 -0.3746 +vn -0.7053 0.3692 0.6051 +vn -0.3942 0.0934 0.9143 +vn 0.0222 -0.2071 0.9781 +vn -0.3943 0.0934 0.9142 +vn 0.4324 -0.4520 0.7802 +vn 0.7268 -0.5760 0.3741 +vn 0.8272 -0.5462 -0.1318 +vn 0.7067 -0.3706 -0.6027 +vn 0.3971 -0.0957 -0.9128 +vn -0.4473 0.4251 -0.7869 +vn -0.0274 0.1898 -0.9814 +vn -0.7468 0.5459 -0.3799 +vn -0.8447 0.5193 0.1298 +vn -0.7148 0.3527 0.6039 +vn -0.3930 0.0917 0.9149 +vn 0.0333 -0.1933 0.9806 +vn 0.4501 -0.4263 0.7847 +vn 0.7468 -0.5457 0.3802 +vn 0.8449 -0.5200 -0.1254 +vn 0.7181 -0.3558 -0.5981 +vn 0.3992 -0.0962 -0.9118 +vn 0.3992 -0.0961 -0.9118 +vn -0.4728 0.3822 -0.7940 +vn -0.0422 0.1634 -0.9856 +vn -0.7759 0.4979 -0.3874 +vn -0.8691 0.4788 0.1240 +vn -0.7275 0.3305 0.6012 +vn -0.3906 0.0936 0.9158 +vn 0.0499 -0.1676 0.9846 +vn -0.3907 0.0936 0.9158 +vn 0.4764 -0.3836 0.7911 +vn 0.7759 -0.4976 0.3879 +vn 0.8695 -0.4796 -0.1184 +vn 0.7758 -0.4976 0.3879 +vn 0.7320 -0.3340 -0.5938 +vn 0.3988 -0.0988 -0.9117 +vn -0.5022 0.3256 -0.8011 +vn -0.0594 0.1285 -0.9899 +vn -0.8094 0.4347 -0.3948 +vn -0.8970 0.4258 0.1185 +vn -0.7418 0.3018 0.5988 +vn -0.3875 0.0969 0.9168 +vn 0.0695 -0.1331 0.9887 +vn -0.3874 0.0969 0.9168 +vn 0.5068 -0.3271 0.7976 +vn 0.8093 -0.4342 0.3956 +vn 0.8976 -0.4265 -0.1112 +vn 0.7479 -0.3055 -0.5893 +vn 0.3982 -0.1027 -0.9116 +vn 0.3982 -0.1027 -0.9115 +vn -0.5339 0.2522 -0.8071 +vn -0.0781 0.0830 -0.9935 +vn -0.8454 0.3530 -0.4009 +vn -0.9268 0.3578 0.1142 +vn -0.7568 0.2656 0.5972 +vn -0.3836 0.1023 0.9178 +vn 0.0907 -0.0876 0.9920 +vn 0.5396 -0.2536 0.8029 +vn 0.8452 -0.3523 0.4020 +vn 0.9277 -0.3582 -0.1051 +vn 0.7647 -0.2692 -0.5854 +vn 0.3974 -0.1079 -0.9113 +vn 0.3974 -0.1080 -0.9113 +vn -0.5644 0.1611 -0.8097 +vn -0.0962 0.0263 -0.9950 +vn -0.8797 0.2521 -0.4033 +vn -0.9550 0.2744 0.1129 +vn -0.7708 0.2221 0.5971 +vn -0.3796 0.1103 0.9185 +vn 0.1111 -0.0303 0.9933 +vn -0.3796 0.1102 0.9185 +vn 0.5708 -0.1624 0.8049 +vn 0.8792 -0.2514 0.4046 +vn 0.9562 -0.2744 -0.1023 +vn 0.8792 -0.2515 0.4047 +vn 0.7805 -0.2248 -0.5833 +vn 0.3963 -0.1150 -0.9109 +vn -0.5884 0.0568 -0.8066 +vn -0.1109 -0.0389 -0.9931 +vn -0.9064 0.1372 -0.3996 +vn -0.9768 0.1801 0.1163 +vn -0.7816 0.1740 0.5991 +vn -0.3766 0.1211 0.9184 +vn 0.1269 0.0360 0.9913 +vn 0.5950 -0.0583 0.8016 +vn 0.9056 -0.1371 0.4013 +vn 0.9781 -0.1798 -0.1048 +vn 0.7923 -0.1752 -0.5844 +vn 0.3948 -0.1238 -0.9104 +vn 0.3947 -0.1238 -0.9104 +vn -0.6019 -0.0487 -0.7971 +vn -0.1199 -0.1057 -0.9871 +vn -0.9208 0.0217 -0.3894 +vn -0.9885 0.0863 0.1242 +vn -0.7878 0.1273 0.6027 +vn -0.3758 0.1337 0.9170 +vn 0.1347 0.1041 0.9854 +vn 0.6078 0.0470 0.7927 +vn 0.9200 -0.0225 0.3914 +vn 0.9898 -0.0860 -0.1133 +vn 0.9200 -0.0225 0.3913 +vn 0.7980 -0.1268 -0.5892 +vn 0.3927 -0.1342 -0.9098 +vn -0.6055 -0.1390 -0.7836 +vn -0.1236 -0.1642 -0.9786 +vn -0.9237 -0.0758 -0.3757 +vn -0.9909 0.0080 0.1340 +vn -0.7901 0.0895 0.6064 +vn -0.3775 0.1464 0.9144 +vn 0.1347 0.1636 0.9773 +vn 0.6097 0.1372 0.7807 +vn 0.9229 0.0746 0.3777 +vn 0.9921 -0.0077 -0.1253 +vn 0.7980 -0.0881 -0.5961 +vn 0.3904 -0.1454 -0.9091 +vn 0.3903 -0.1454 -0.9091 +vn -0.6041 -0.1997 -0.7715 +vn -0.1246 -0.2056 -0.9707 +vn -0.9209 -0.1398 -0.3640 +vn -0.9890 -0.0421 0.1415 +vn -0.7909 0.0668 0.6083 +vn -0.3809 0.1573 0.9112 +vn 0.1303 0.2054 0.9700 +vn -0.3809 0.1573 0.9111 +vn 0.6060 0.1986 0.7703 +vn 0.9203 0.1390 0.3658 +vn 0.9898 0.0425 -0.1363 +vn 0.7954 -0.0655 -0.6026 +vn 0.3878 -0.1563 -0.9084 +vn -0.6033 -0.2243 -0.7653 +vn -0.1259 -0.2251 -0.9662 +vn -0.9189 -0.1633 -0.3592 +vn -0.9880 -0.0585 0.1430 +vn -0.7925 0.0618 0.6068 +vn -0.3848 0.1655 0.9080 +vn 0.1258 0.2249 0.9662 +vn 0.6027 0.2241 0.7658 +vn 0.9184 0.1634 0.3604 +vn 0.9882 0.0589 -0.1417 +vn 0.7931 -0.0615 -0.6059 +vn 0.3853 -0.1655 -0.9078 +vn -0.6052 -0.2123 -0.7672 +vn -0.1289 -0.2211 -0.9667 +vn -0.9199 -0.1472 -0.3634 +vn -0.9896 -0.0424 0.1375 +vn -0.7949 0.0747 0.6021 +vn -0.3878 0.1724 0.9055 +vn 0.1233 0.2241 0.9667 +vn -0.3877 0.1724 0.9055 +vn 0.6022 0.2155 0.7687 +vn 0.9195 0.1486 0.3638 +vn 0.9893 0.0421 -0.1397 +vn 0.9196 0.1486 0.3638 +vn 0.7923 -0.0750 -0.6055 +vn 0.3823 -0.1709 -0.9081 +vn -0.6034 -0.1240 -0.7878 +vn -0.1321 -0.1304 -0.9826 +vn -0.9189 -0.0848 -0.3853 +vn -0.9923 -0.0205 0.1225 +vn -0.7986 0.0538 0.5995 +vn -0.3877 0.1170 0.9143 +vn 0.1287 0.1477 0.9806 +vn 0.6111 0.1355 0.7798 +vn 0.9269 0.0865 0.3652 +vn 0.9888 0.0181 -0.1483 +vn 0.7842 -0.0507 -0.6184 +vn 0.3740 -0.1041 -0.9216 +vn -0.6005 0.1120 -0.7917 +vn -0.1349 0.1456 -0.9801 +vn -0.9155 0.0498 -0.3992 +vn -0.9945 -0.0236 0.1025 +vn -0.8059 -0.0849 0.5859 +vn -0.3899 -0.1165 0.9135 +vn 0.1397 -0.1171 0.9832 +vn 0.6289 -0.0903 0.7722 +vn 0.9372 -0.0367 0.3467 +vn 0.9857 0.0341 -0.1653 +vn 0.7735 0.1006 -0.6258 +vn 0.3647 0.1414 -0.9203 +vn 0.3648 0.1413 -0.9203 +vn -0.5971 0.4456 -0.6670 +vn -0.1337 0.5451 -0.8276 +vn -0.9129 0.2325 -0.3355 +vn -0.9952 -0.0430 0.0875 +vn -0.8112 -0.3099 0.4959 +vn -0.3957 -0.4932 0.7747 +vn 0.1417 -0.5368 0.8317 +vn 0.6356 -0.4252 0.6444 +vn 0.9404 -0.1943 0.2791 +vn 0.9844 0.0870 -0.1532 +vn 0.7706 0.3422 -0.5377 +vn 0.3630 0.5078 -0.7812 +vn 0.3630 0.5079 -0.7812 +vn -0.5898 0.7076 -0.3891 +vn -0.1241 0.8615 -0.4923 +vn -0.9091 0.3727 -0.1860 +vn -0.9956 -0.0646 0.0675 +vn -0.8147 -0.4944 0.3030 +vn -0.4018 -0.7963 0.4522 +vn 0.1320 -0.8709 0.4734 +vn 0.6259 -0.6904 0.3627 +vn 0.1319 -0.8709 0.4734 +vn 0.9359 -0.3189 0.1498 +vn 0.9859 0.1297 -0.1053 +vn 0.7769 0.5351 -0.3317 +vn 0.3719 0.7995 -0.4716 +vn 0.7769 0.5351 -0.3318 +vn 0.7706 0.3423 -0.5377 +vn -0.1336 0.5452 -0.8276 +vn -0.5820 0.8102 -0.0692 +vn -0.1119 0.9883 -0.1031 +vn -0.9064 0.4222 -0.0169 +vn -0.5821 0.8102 -0.0693 +vn -0.5899 0.7076 -0.3891 +vn -0.9959 -0.0824 0.0385 +vn -0.8162 -0.5724 0.0786 +vn -0.4069 -0.9089 0.0913 +vn 0.1185 -0.9898 0.0797 +vn 0.6101 -0.7906 0.0513 +vn 0.9281 -0.3722 0.0068 +vn 0.9889 0.1418 -0.0453 +vn 0.7875 0.6099 -0.0891 +vn 0.3858 0.9160 -0.1103 +vn 0.7874 0.6099 -0.0891 +vn -0.5771 0.7924 0.1977 +vn -0.1031 0.9685 0.2267 +vn -0.9048 0.4092 0.1174 +vn -0.5772 0.7924 0.1976 +vn -0.9963 -0.0859 0.0039 +vn -0.8186 -0.5629 -0.1144 +vn -0.4130 -0.8875 -0.2044 +vn 0.1093 -0.9654 -0.2369 +vn 0.6008 -0.7737 -0.2008 +vn 0.9230 -0.3687 -0.1101 +vn 0.6008 -0.7738 -0.2009 +vn 0.9912 0.1322 0.0064 +vn 0.7962 0.5933 0.1184 +vn 0.3964 0.8965 0.1980 +vn -0.5747 0.7131 0.4015 +vn -0.0984 0.8703 0.4825 +vn -0.9041 0.3689 0.2154 +vn -0.9967 -0.0759 -0.0299 +vn -0.8201 -0.5043 -0.2703 +vn -0.4162 -0.7964 -0.4387 +vn 0.1051 -0.8680 -0.4853 +vn 0.5962 -0.6982 -0.3962 +vn 0.9203 -0.3370 -0.1986 +vn 0.9924 0.1124 0.0499 +vn 0.8010 0.5280 0.2823 +vn 0.4026 0.8031 0.4392 +vn 0.8010 0.5279 0.2823 +vn -0.5747 0.5982 0.5584 +vn -0.0977 0.7250 0.6818 +vn -0.0985 0.8703 0.4825 +vn -0.9043 0.3145 0.2885 +vn -0.9967 -0.0551 -0.0604 +vn -0.8199 -0.4130 -0.3963 +vn -0.9967 -0.0551 -0.0603 +vn -0.4161 -0.6597 -0.6258 +vn -0.8199 -0.4131 -0.3964 +vn 0.1047 -0.7238 -0.6820 +vn 0.5956 -0.5868 -0.5485 +vn 0.9198 -0.2894 -0.2651 +vn 0.9927 0.0836 0.0871 +vn 0.8021 0.4313 0.4131 +vn 0.4038 0.6643 0.6290 +vn 0.8021 0.4313 0.4130 +vn -0.5777 0.4567 0.6765 +vn -0.1013 0.5438 0.8331 +vn -0.9058 0.2498 0.3422 +vn -0.9960 -0.0252 -0.0858 +vn -0.8173 -0.2958 -0.4945 +vn -0.4122 -0.4868 -0.7701 +vn 0.1087 -0.5431 -0.8326 +vn 0.5985 -0.4486 -0.6637 +vn 0.9209 -0.2316 -0.3137 +vn 0.9920 0.0461 0.1178 +vn 0.7999 0.3093 0.5143 +vn 0.4005 0.4902 0.7741 +vn -0.1014 0.5438 0.8331 +vn -0.5843 0.2971 0.7552 +vn -0.1095 0.3379 0.9348 +vn -0.9089 0.1784 0.3770 +vn -0.9945 0.0113 -0.1044 +vn -0.8115 -0.1601 -0.5620 +vn -0.4039 -0.2885 -0.8681 +vn 0.1171 -0.3373 -0.9341 +vn 0.6046 -0.2925 -0.7409 +vn 0.9233 -0.1677 -0.3456 +vn 0.9902 0.0013 0.1393 +vn 0.7945 0.1688 0.5833 +vn 0.3928 0.2912 0.8723 +vn -0.5942 0.1327 0.7933 +vn -0.1218 0.1245 0.9847 +vn -0.9134 0.1061 0.3930 +vn -0.9921 0.0512 -0.1149 +vn -0.8028 -0.0176 -0.5960 +vn -0.9921 0.0513 -0.1149 +vn -0.3916 -0.0820 -0.9165 +vn 0.1292 -0.1239 -0.9839 +vn 0.6133 -0.1315 -0.7788 +vn 0.1292 -0.1238 -0.9839 +vn 0.9266 -0.1030 -0.3617 +vn 0.9877 -0.0468 0.1494 +vn 0.7867 0.0216 0.6170 +vn 0.3814 0.0841 0.9206 +vn -0.6071 -0.0210 0.7944 +vn -0.1372 -0.0761 0.9876 +vn -0.9194 0.0396 0.3914 +vn -0.9889 0.0903 -0.1181 +vn -0.7920 0.1177 -0.5990 +vn -0.9889 0.0903 -0.1182 +vn -0.3769 0.1136 -0.9193 +vn 0.1442 0.0777 -0.9865 +vn 0.6244 0.0199 -0.7809 +vn 0.9308 -0.0431 -0.3630 +vn 0.9844 -0.0936 0.1491 +vn 0.7774 -0.1182 0.6178 +vn 0.3679 -0.1116 0.9232 +vn -0.6120 -0.0904 0.7857 +vn -0.1440 -0.2073 0.9676 +vn -0.9186 0.0515 0.3918 +vn -0.9771 0.1813 -0.1112 +vn -0.7668 0.2628 -0.5856 +vn -0.3458 0.2718 -0.8981 +vn 0.1678 0.2051 -0.9643 +vn 0.6324 0.0833 -0.7701 +vn 0.9262 -0.0596 -0.3722 +vn 0.9750 -0.1854 0.1226 +vn 0.7679 -0.2619 0.5846 +vn 0.9750 -0.1854 0.1225 +vn 0.3596 -0.2698 0.8933 +vn -0.6016 -0.0411 0.7977 +vn -0.1481 -0.2361 0.9604 +vn -0.8940 0.1669 0.4159 +vn -0.9403 0.3305 -0.0807 +vn -0.7282 0.4029 -0.5544 +vn -0.3188 0.3644 -0.8750 +vn 0.1736 0.2279 -0.9581 +vn 0.6176 0.0317 -0.7858 +vn 0.1737 0.2279 -0.9581 +vn 0.8973 -0.1714 -0.4068 +vn 0.9412 -0.3287 0.0779 +vn 0.7389 -0.4000 0.5422 +vn 0.3421 -0.3665 0.8653 +vn -0.1480 -0.2361 0.9604 +vn -0.5768 0.0332 0.8162 +vn -0.1482 -0.2202 0.9641 +vn -0.8502 0.2785 0.4468 +vn -0.8928 0.4483 -0.0446 +vn -0.6927 0.4959 -0.5237 +vn -0.3053 0.4091 -0.8599 +vn 0.1629 0.2130 -0.9634 +vn 0.5862 -0.0387 -0.8092 +vn 0.1629 0.2131 -0.9634 +vn 0.8529 -0.2792 -0.4412 +vn 0.8941 -0.4458 0.0428 +vn 0.6993 -0.4950 0.5157 +vn 0.3190 -0.4130 0.8530 +vn -0.5537 0.0798 0.8289 +vn -0.1441 -0.2070 0.9677 +vn -0.8144 0.3457 0.4660 +vn -0.8549 0.5182 -0.0233 +vn -0.6640 0.5503 -0.5062 +vn -0.2943 0.4338 -0.8516 +vn 0.1536 0.2013 -0.9674 +vn 0.5594 -0.0843 -0.8246 +vn 0.8158 -0.3468 -0.4629 +vn 0.8556 -0.5172 0.0213 +vn 0.6685 -0.5506 0.5000 +vn 0.3031 -0.4375 0.8466 +vn -0.5329 0.1143 0.8384 +vn -0.1381 -0.1950 0.9710 +vn -0.7845 0.3931 0.4796 +vn -0.8244 0.5659 -0.0090 +vn -0.6417 0.5859 -0.4949 +vn -0.8244 0.5660 -0.0090 +vn -0.2865 0.4480 -0.8469 +vn 0.1449 0.1903 -0.9710 +vn 0.5368 -0.1177 -0.8355 +vn 0.7852 -0.3939 -0.4777 +vn 0.8248 -0.5653 0.0068 +vn 0.6451 -0.5865 0.4898 +vn 0.2930 -0.4513 0.8429 +vn -0.1380 -0.1950 0.9710 +vn -0.5135 0.1423 0.8462 +vn -0.1306 -0.1832 0.9743 +vn -0.7584 0.4299 0.4899 +vn -0.7988 0.6016 0.0013 +vn -0.6239 0.6110 -0.4873 +vn -0.2814 0.4562 -0.8442 +vn 0.1360 0.1793 -0.9744 +vn 0.5164 -0.1450 -0.8440 +vn 0.7588 -0.4304 -0.4889 +vn 0.7992 -0.6011 -0.0037 +vn 0.6267 -0.6118 0.4827 +vn 0.2867 -0.4591 0.8408 +vn -0.1307 -0.1832 0.9743 +vn -0.4946 0.1671 0.8529 +vn -0.1219 -0.1712 0.9777 +vn -0.7344 0.4608 0.4983 +vn -0.7763 0.6302 0.0093 +vn -0.6092 0.6299 -0.4818 +vn -0.2785 0.4603 -0.8429 +vn 0.1262 0.1677 -0.9777 +vn 0.4968 -0.1694 -0.8512 +vn 0.1262 0.1676 -0.9777 +vn 0.7346 -0.4610 -0.4978 +vn 0.7767 -0.6298 -0.0119 +vn 0.6117 -0.6307 0.4774 +vn 0.2831 -0.4632 0.8398 +vn -0.1218 -0.1712 0.9777 +vn -0.4751 0.1906 0.8590 +vn -0.1113 -0.1584 0.9811 +vn -0.7112 0.4885 0.5055 +vn -0.7556 0.6549 0.0158 +vn -0.5966 0.6448 -0.4778 +vn -0.2776 0.4616 -0.8425 +vn 0.1153 0.1550 -0.9812 +vn 0.4769 -0.1925 -0.8576 +vn 0.7112 -0.4885 -0.5055 +vn 0.7560 -0.6544 -0.0187 +vn 0.5991 -0.6458 0.4734 +vn 0.2818 -0.4645 0.8395 +vn -0.1114 -0.1584 0.9811 +vn -0.4543 0.2140 0.8647 +vn -0.0989 -0.1444 0.9846 +vn -0.6875 0.5150 0.5119 +vn -0.7355 0.6772 0.0212 +vn -0.5855 0.6571 -0.4748 +vn -0.2785 0.4606 -0.8428 +vn 0.1025 0.1411 -0.9847 +vn 0.4558 -0.2157 -0.8635 +vn 0.6874 -0.5148 -0.5123 +vn 0.7358 -0.6767 -0.0245 +vn 0.5880 -0.6582 0.4702 +vn 0.2826 -0.4636 0.8397 +vn -0.4312 0.2384 0.8702 +vn -0.0839 -0.1288 0.9881 +vn -0.6624 0.5415 0.5177 +vn -0.7151 0.6986 0.0257 +vn -0.5753 0.6676 -0.4726 +vn -0.2813 0.4575 -0.8435 +vn 0.0875 0.1253 -0.9883 +vn 0.4325 -0.2400 -0.8691 +vn 0.6621 -0.5411 -0.5185 +vn 0.7154 -0.6981 -0.0296 +vn 0.5778 -0.6690 0.4675 +vn 0.2854 -0.4609 0.8403 +vn -0.0840 -0.1288 0.9881 +vn -0.4046 0.2647 0.8754 +vn -0.0657 -0.1109 0.9917 +vn -0.6346 0.5691 0.5230 +vn -0.6934 0.7200 0.0297 +vn -0.5655 0.6770 -0.4711 +vn -0.6934 0.7200 0.0296 +vn -0.2862 0.4524 -0.8447 +vn 0.0693 0.1071 -0.9918 +vn 0.4058 -0.2662 -0.8743 +vn 0.6341 -0.5685 -0.5241 +vn 0.6936 -0.7195 -0.0342 +vn 0.5682 -0.6787 0.4653 +vn 0.2905 -0.4563 0.8411 +vn -0.3730 0.2939 0.8801 +vn -0.0430 -0.0903 0.9950 +vn -0.6024 0.5990 0.5275 +vn -0.6693 0.7423 0.0326 +vn -0.5558 0.6856 -0.4702 +vn -0.2935 0.4451 -0.8460 +vn 0.0468 0.0861 -0.9952 +vn 0.3742 -0.2953 -0.8790 +vn 0.6019 -0.5981 -0.5291 +vn 0.6695 -0.7418 -0.0381 +vn 0.5586 -0.6879 0.4634 +vn 0.2980 -0.4498 0.8419 +vn -0.0430 -0.0904 0.9950 +vn -0.3528 0.3185 0.8798 +vn -0.0198 -0.0618 0.9979 +vn -0.5903 0.6122 0.5260 +vn -0.6698 0.7419 0.0322 +vn -0.5708 0.6738 -0.4693 +vn -0.3200 0.4267 -0.8459 +vn 0.0159 0.0661 -0.9977 +vn 0.3481 -0.3128 -0.8837 +vn 0.5877 -0.6089 -0.5328 +vn 0.6695 -0.7418 -0.0386 +vn 0.5712 -0.6751 0.4669 +vn 0.6695 -0.7418 -0.0387 +vn 0.3186 -0.4259 0.8468 +vn -0.0199 -0.0618 0.9979 +vn -0.3528 0.3184 0.8798 +vn -0.3601 0.3192 0.8766 +vn 0.0045 -0.0273 0.9996 +vn -0.6273 0.5790 0.5207 +vn -0.7280 0.6850 0.0290 +vn -0.6372 0.6110 -0.4698 +vn -0.3789 0.3764 -0.8454 +vn -0.0198 0.0416 -0.9989 +vn 0.3462 -0.3059 -0.8869 +vn 0.6207 -0.5731 -0.5351 +vn 0.3461 -0.3059 -0.8869 +vn 0.7274 -0.6853 -0.0365 +vn 0.6353 -0.6103 0.4733 +vn 0.7273 -0.6853 -0.0365 +vn 0.3697 -0.3684 0.8530 +vn -0.3796 0.2980 0.8759 +vn 0.0326 0.0096 0.9994 +vn -0.6885 0.5053 0.5202 +vn -0.8149 0.5788 0.0292 +vn -0.7278 0.5007 -0.4686 +vn -0.4499 0.2913 -0.8442 +vn -0.0524 0.0044 -0.9986 +vn 0.3612 -0.2854 -0.8878 +vn 0.6798 -0.4999 -0.5366 +vn 0.3612 -0.2853 -0.8878 +vn 0.8144 -0.5791 -0.0375 +vn 0.7258 -0.4995 0.4730 +vn 0.4383 -0.2830 0.8531 +vn -0.3974 0.2693 0.8772 +vn 0.0573 0.0525 0.9970 +vn -0.7439 0.4134 0.5251 +vn -0.8932 0.4481 0.0366 +vn -0.8088 0.3656 -0.4606 +vn -0.5128 0.1874 -0.8378 +vn -0.0805 -0.0409 -0.9959 +vn 0.3758 -0.2596 -0.8896 +vn 0.7335 -0.4097 -0.5423 +vn 0.8926 -0.4485 -0.0452 +vn 0.8067 -0.3642 0.4654 +vn 0.8926 -0.4485 -0.0453 +vn 0.4994 -0.1799 0.8475 +vn -0.4102 0.2361 0.8809 +vn 0.0757 0.0966 0.9924 +vn -0.7844 0.3123 0.5359 +vn -0.9506 0.3060 0.0515 +vn -0.8088 0.3656 -0.4605 +vn -0.8679 0.2196 -0.4456 +vn -0.5577 0.0756 -0.8266 +vn -0.0993 -0.0889 -0.9911 +vn 0.3882 -0.2305 -0.8923 +vn 0.7739 -0.3107 -0.5519 +vn 0.9501 -0.3064 -0.0593 +vn 0.8658 -0.2179 0.4505 +vn 0.5441 -0.0699 0.8361 +vn -0.4163 0.2028 0.8863 +vn 0.0870 0.1359 0.9869 +vn -0.8066 0.2156 0.5504 +vn -0.4164 0.2028 0.8863 +vn -0.9826 0.1715 0.0707 +vn -0.9005 0.0824 -0.4270 +vn -0.5816 -0.0285 -0.8130 +vn -0.1078 -0.1322 -0.9853 +vn 0.3970 -0.2010 -0.8955 +vn 0.7974 -0.2158 -0.5636 +vn 0.3971 -0.2010 -0.8955 +vn 0.9821 -0.1718 -0.0770 +vn 0.8985 -0.0807 0.4315 +vn 0.5694 0.0321 0.8214 +vn -0.4170 0.1735 0.8922 +vn 0.0927 0.1662 0.9817 +vn -0.8138 0.1347 0.5653 +vn -0.9941 0.0604 0.0897 +vn -0.9120 -0.0298 -0.4091 +vn -0.5889 -0.1123 -0.8003 +vn -0.1087 -0.1652 -0.9803 +vn 0.4023 -0.1740 -0.8988 +vn 0.8069 -0.1358 -0.5748 +vn 0.9937 -0.0606 -0.0940 +vn 0.9103 0.0312 0.4129 +vn 0.5794 0.1142 0.8070 +vn 0.9103 0.0311 0.4128 +vn -0.4146 0.1502 0.8975 +vn 0.0954 0.1856 0.9780 +vn -0.8127 0.0748 0.5778 +vn -0.9942 -0.0203 0.1052 +vn -0.9120 -0.1100 -0.3951 +vn -0.5877 -0.1706 -0.7909 +vn -0.1062 -0.1858 -0.9768 +vn 0.4049 -0.1513 -0.9017 +vn 0.8083 -0.0758 -0.5838 +vn 0.9940 0.0202 -0.1076 +vn 0.9106 0.1108 0.3981 +vn 0.5810 0.1714 0.7957 +vn -0.4111 0.1328 0.9019 +vn 0.0972 0.1945 0.9761 +vn -0.8090 0.0357 0.5868 +vn -0.4112 0.1327 0.9018 +vn -0.9908 -0.0709 0.1155 +vn -0.9086 -0.1585 -0.3864 +vn -0.5841 -0.2040 -0.7856 +vn -0.1032 -0.1950 -0.9754 +vn 0.4060 -0.1336 -0.9040 +vn 0.8068 -0.0363 -0.5896 +vn 0.4060 -0.1337 -0.9040 +vn 0.9907 0.0709 -0.1162 +vn 0.9076 0.1590 0.3886 +vn 0.5801 0.2042 0.7885 +vn -0.4079 0.1207 0.9050 +vn 0.0993 0.1942 0.9759 +vn -0.8058 0.0149 0.5920 +vn -0.9881 -0.0948 0.1208 +vn -0.9063 -0.1791 -0.3828 +vn -0.5818 -0.2156 -0.7843 +vn -0.9063 -0.1792 -0.3829 +vn -0.1012 -0.1943 -0.9757 +vn 0.4067 -0.1209 -0.9055 +vn 0.8056 -0.0150 -0.5923 +vn 0.9882 0.0950 -0.1200 +vn 0.9056 0.1794 0.3844 +vn 0.5800 0.2157 0.7855 +vn -0.4053 0.1130 0.9072 +vn 0.1020 0.1859 0.9773 +vn -0.8043 0.0097 0.5942 +vn -0.9879 -0.0962 0.1216 +vn -0.9065 -0.1763 -0.3837 +vn -0.5816 -0.2091 -0.7862 +vn -0.1005 -0.1858 -0.9774 +vn 0.4074 -0.1125 -0.9063 +vn 0.8057 -0.0092 -0.5922 +vn 0.9881 0.0965 -0.1197 +vn 0.9061 0.1764 0.3847 +vn 0.5818 0.2091 0.7860 +vn 0.9061 0.1764 0.3846 +vn -0.4034 0.1089 0.9085 +vn 0.1050 0.1711 0.9796 +vn -0.8044 0.0174 0.5938 +vn -0.4035 0.1089 0.9085 +vn -0.9897 -0.0788 0.1192 +vn -0.9088 -0.1539 -0.3878 +vn -0.5831 -0.1876 -0.7904 +vn -0.1007 -0.1707 -0.9802 +vn 0.4082 -0.1081 -0.9065 +vn 0.8072 -0.0165 -0.5900 +vn 0.4082 -0.1080 -0.9065 +vn 0.9901 0.0793 -0.1162 +vn 0.9086 0.1539 0.3882 +vn 0.5849 0.1875 0.7891 +vn -0.4026 0.1076 0.9090 +vn 0.1067 0.1621 0.9810 +vn -0.8048 0.0242 0.5931 +vn -0.9909 -0.0659 0.1173 +vn -0.9102 -0.1383 -0.3905 +vn -0.5840 -0.1734 -0.7930 +vn -0.1009 -0.1618 -0.9817 +vn 0.4088 -0.1067 -0.9063 +vn 0.8083 -0.0232 -0.5884 +vn 0.4088 -0.1067 -0.9064 +vn 0.9913 0.0664 -0.1138 +vn 0.9101 0.1382 0.3906 +vn 0.5867 0.1733 0.7910 +usemtl Scene_-_Root +s 1 +f 31914/31914/22697 31915/31915/22698 31916/31916/22699 +f 31914/31914/22697 31916/31916/22699 31917/31917/22700 +f 31918/31918/22701 31919/31919/22702 31915/31915/22698 +f 31918/31918/22701 31915/31915/22698 31914/31914/22697 +f 31920/31920/22703 31921/31921/22704 31919/31919/22702 +f 31920/31920/22703 31919/31919/22702 31918/31918/22701 +f 31922/31922/22705 31923/31923/22706 31924/31924/22704 +f 31922/31922/22705 31924/31924/22704 31925/31925/22707 +f 31926/31926/22708 31927/31927/22709 31923/31923/22706 +f 31926/31926/22708 31923/31923/22706 31922/31922/22705 +f 31928/31928/22710 31929/31929/22711 31927/31927/22709 +f 31928/31928/22710 31927/31927/22709 31926/31926/22708 +f 31930/31930/22712 31931/31931/22713 31932/31932/22711 +f 31930/31930/22712 31932/31932/22711 31933/31933/22710 +f 31934/31934/22714 31935/31935/22715 31931/31931/22713 +f 31934/31934/22714 31931/31931/22713 31930/31930/22712 +f 31936/31936/22716 31937/31937/22717 31935/31935/22715 +f 31936/31936/22716 31935/31935/22715 31934/31934/22714 +f 31938/31938/22718 31939/31939/22719 31940/31940/22720 +f 31938/31938/22718 31940/31940/22720 31941/31941/22716 +f 31942/31942/22721 31943/31943/22722 31939/31939/22719 +f 31942/31942/22721 31939/31939/22719 31938/31938/22718 +f 31944/31944/22700 31945/31945/22699 31943/31943/22722 +f 31944/31944/22700 31943/31943/22722 31942/31942/22721 +f 31915/31915/22698 31946/31946/22723 31947/31947/22724 +f 31915/31915/22698 31947/31947/22724 31916/31916/22699 +f 31919/31919/22702 31948/31948/22725 31946/31946/22723 +f 31919/31919/22702 31946/31946/22723 31915/31915/22698 +f 31921/31921/22704 31949/31949/22726 31948/31948/22725 +f 31921/31921/22704 31948/31948/22725 31919/31919/22702 +f 31923/31923/22706 31950/31950/22727 31951/31951/22726 +f 31923/31923/22706 31951/31951/22726 31924/31924/22704 +f 31927/31927/22709 31952/31952/22728 31950/31950/22727 +f 31927/31927/22709 31950/31950/22727 31923/31923/22706 +f 31929/31929/22711 31953/31953/22729 31952/31952/22728 +f 31929/31929/22711 31952/31952/22728 31927/31927/22709 +f 31931/31931/22713 31954/31954/22730 31955/31955/22731 +f 31931/31931/22713 31955/31955/22731 31932/31932/22711 +f 31935/31935/22715 31956/31956/22732 31954/31954/22730 +f 31935/31935/22715 31954/31954/22730 31931/31931/22713 +f 31937/31937/22717 31957/31957/22733 31956/31956/22732 +f 31937/31937/22717 31956/31956/22732 31935/31935/22715 +f 31939/31939/22719 31958/31958/22734 31959/31959/22735 +f 31939/31939/22719 31959/31959/22735 31940/31940/22720 +f 31943/31943/22722 31960/31960/22736 31958/31958/22734 +f 31943/31943/22722 31958/31958/22734 31939/31939/22719 +f 31945/31945/22699 31961/31961/22724 31960/31960/22736 +f 31945/31945/22699 31960/31960/22736 31943/31943/22722 +f 31946/31946/22723 31962/31962/22737 31963/31963/22738 +f 31946/31946/22723 31963/31963/22738 31947/31947/22724 +f 31948/31948/22725 31964/31964/22739 31962/31962/22737 +f 31948/31948/22725 31962/31962/22737 31946/31946/22723 +f 31949/31949/22726 31965/31965/22740 31964/31964/22739 +f 31949/31949/22726 31964/31964/22739 31948/31948/22725 +f 31950/31950/22727 31966/31966/22741 31967/31967/22740 +f 31950/31950/22727 31967/31967/22740 31951/31951/22726 +f 31952/31952/22728 31968/31968/22742 31966/31966/22741 +f 31952/31952/22728 31966/31966/22741 31950/31950/22727 +f 31953/31953/22729 31969/31969/22743 31968/31968/22742 +f 31953/31953/22729 31968/31968/22742 31952/31952/22728 +f 31954/31954/22730 31970/31970/22744 31971/31971/22745 +f 31954/31954/22730 31971/31971/22745 31955/31955/22731 +f 31956/31956/22732 31972/31972/22746 31970/31970/22744 +f 31956/31956/22732 31970/31970/22744 31954/31954/22730 +f 31957/31957/22733 31973/31973/22747 31972/31972/22746 +f 31957/31957/22733 31972/31972/22746 31956/31956/22732 +f 31958/31958/22734 31974/31974/22748 31975/31975/22747 +f 31958/31958/22734 31975/31975/22747 31959/31959/22735 +f 31960/31960/22736 31976/31976/22749 31974/31974/22748 +f 31960/31960/22736 31974/31974/22748 31958/31958/22734 +f 31961/31961/22724 31977/31977/22750 31976/31976/22749 +f 31961/31961/22724 31976/31976/22749 31960/31960/22736 +f 31962/31962/22737 31978/31978/22751 31979/31979/22752 +f 31962/31962/22737 31979/31979/22752 31963/31963/22738 +f 31964/31964/22739 31980/31980/22753 31978/31978/22751 +f 31964/31964/22739 31978/31978/22751 31962/31962/22737 +f 31965/31965/22740 31981/31981/22754 31980/31980/22753 +f 31965/31965/22740 31980/31980/22753 31964/31964/22739 +f 31966/31966/22741 31982/31982/22755 31983/31983/22756 +f 31966/31966/22741 31983/31983/22756 31967/31967/22740 +f 31968/31968/22742 31984/31984/22757 31982/31982/22755 +f 31968/31968/22742 31982/31982/22755 31966/31966/22741 +f 31969/31969/22743 31985/31985/22758 31984/31984/22757 +f 31969/31969/22743 31984/31984/22757 31968/31968/22742 +f 31970/31970/22744 31986/31986/22759 31987/31987/22760 +f 31970/31970/22744 31987/31987/22760 31971/31971/22745 +f 31972/31972/22746 31988/31988/22761 31986/31986/22759 +f 31972/31972/22746 31986/31986/22759 31970/31970/22744 +f 31973/31973/22747 31989/31989/22762 31988/31988/22761 +f 31973/31973/22747 31988/31988/22761 31972/31972/22746 +f 31974/31974/22748 31990/31990/22763 31991/31991/22762 +f 31974/31974/22748 31991/31991/22762 31975/31975/22747 +f 31976/31976/22749 31992/31992/22764 31990/31990/22763 +f 31976/31976/22749 31990/31990/22763 31974/31974/22748 +f 31977/31977/22750 31993/31993/22752 31992/31992/22764 +f 31977/31977/22750 31992/31992/22764 31976/31976/22749 +f 31978/31978/22751 31994/31994/22765 31995/31995/22766 +f 31978/31978/22751 31995/31995/22766 31979/31979/22752 +f 31980/31980/22753 31996/31996/22767 31994/31994/22765 +f 31980/31980/22753 31994/31994/22765 31978/31978/22751 +f 31981/31981/22754 31997/31997/22768 31996/31996/22767 +f 31981/31981/22754 31996/31996/22767 31980/31980/22753 +f 31982/31982/22755 31998/31998/22769 31999/31999/22768 +f 31982/31982/22755 31999/31999/22768 31983/31983/22756 +f 31984/31984/22757 32000/32000/22770 31998/31998/22769 +f 31984/31984/22757 31998/31998/22769 31982/31982/22755 +f 31985/31985/22758 32001/32001/22771 32000/32000/22770 +f 31985/31985/22758 32000/32000/22770 31984/31984/22757 +f 31986/31986/22759 32002/32002/22772 32003/32003/22773 +f 31986/31986/22759 32003/32003/22773 31987/31987/22760 +f 31988/31988/22761 32004/32004/22774 32002/32002/22772 +f 31988/31988/22761 32002/32002/22772 31986/31986/22759 +f 31989/31989/22762 32005/32005/22775 32004/32004/22774 +f 31989/31989/22762 32004/32004/22774 31988/31988/22761 +f 31990/31990/22763 32006/32006/22776 32007/32007/22775 +f 31990/31990/22763 32007/32007/22775 31991/31991/22762 +f 31992/31992/22764 32008/32008/22777 32006/32006/22776 +f 31992/31992/22764 32006/32006/22776 31990/31990/22763 +f 31993/31993/22752 32009/32009/22766 32008/32008/22777 +f 31993/31993/22752 32008/32008/22777 31992/31992/22764 +f 31994/31994/22765 32010/32010/22778 32011/32011/22779 +f 31994/31994/22765 32011/32011/22779 31995/31995/22766 +f 31996/31996/22767 32012/32012/22780 32010/32010/22778 +f 31996/31996/22767 32010/32010/22778 31994/31994/22765 +f 31997/31997/22768 32013/32013/22781 32012/32012/22780 +f 31997/31997/22768 32012/32012/22780 31996/31996/22767 +f 31998/31998/22769 32014/32014/22782 32015/32015/22781 +f 31998/31998/22769 32015/32015/22781 31999/31999/22768 +f 32000/32000/22770 32016/32016/22783 32014/32014/22782 +f 32000/32000/22770 32014/32014/22782 31998/31998/22769 +f 32001/32001/22771 32017/32017/22784 32016/32016/22783 +f 32001/32001/22771 32016/32016/22783 32000/32000/22770 +f 32002/32002/22772 32018/32018/22785 32019/32019/22786 +f 32002/32002/22772 32019/32019/22786 32003/32003/22773 +f 32004/32004/22774 32020/32020/22787 32018/32018/22785 +f 32004/32004/22774 32018/32018/22785 32002/32002/22772 +f 32005/32005/22775 32021/32021/22788 32020/32020/22787 +f 32005/32005/22775 32020/32020/22787 32004/32004/22774 +f 32006/32006/22776 32022/32022/22789 32023/32023/22790 +f 32006/32006/22776 32023/32023/22790 32007/32007/22775 +f 32008/32008/22777 32024/32024/22791 32022/32022/22789 +f 32008/32008/22777 32022/32022/22789 32006/32006/22776 +f 32009/32009/22766 32025/32025/22779 32024/32024/22791 +f 32009/32009/22766 32024/32024/22791 32008/32008/22777 +f 32010/32010/22778 32026/32026/22792 32027/32027/22793 +f 32010/32010/22778 32027/32027/22793 32011/32011/22779 +f 32012/32012/22780 32028/32028/22794 32026/32026/22792 +f 32012/32012/22780 32026/32026/22792 32010/32010/22778 +f 32013/32013/22781 32029/32029/22795 32028/32028/22794 +f 32013/32013/22781 32028/32028/22794 32012/32012/22780 +f 32014/32014/22782 32030/32030/22796 32031/32031/22795 +f 32014/32014/22782 32031/32031/22795 32015/32015/22781 +f 32016/32016/22783 32032/32032/22797 32030/32030/22796 +f 32016/32016/22783 32030/32030/22796 32014/32014/22782 +f 32017/32017/22784 32033/32033/22798 32032/32032/22797 +f 32017/32017/22784 32032/32032/22797 32016/32016/22783 +f 32018/32018/22785 32034/32034/22799 32035/32035/22798 +f 32018/32018/22785 32035/32035/22798 32019/32019/22786 +f 32020/32020/22787 32036/32036/22800 32034/32034/22799 +f 32020/32020/22787 32034/32034/22799 32018/32018/22785 +f 32021/32021/22788 32037/32037/22801 32036/32036/22800 +f 32021/32021/22788 32036/32036/22800 32020/32020/22787 +f 32022/32022/22789 32038/32038/22802 32039/32039/22801 +f 32022/32022/22789 32039/32039/22801 32023/32023/22790 +f 32024/32024/22791 32040/32040/22803 32038/32038/22802 +f 32024/32024/22791 32038/32038/22802 32022/32022/22789 +f 32025/32025/22779 32041/32041/22793 32040/32040/22803 +f 32025/32025/22779 32040/32040/22803 32024/32024/22791 +f 32026/32026/22792 32042/32042/22804 32043/32043/22805 +f 32026/32026/22792 32043/32043/22805 32027/32027/22793 +f 32028/32028/22794 32044/32044/22806 32042/32042/22804 +f 32028/32028/22794 32042/32042/22804 32026/32026/22792 +f 32029/32029/22795 32045/32045/22807 32044/32044/22806 +f 32029/32029/22795 32044/32044/22806 32028/32028/22794 +f 32030/32030/22796 32046/32046/22808 32047/32047/22807 +f 32030/32030/22796 32047/32047/22807 32031/32031/22795 +f 32032/32032/22797 32048/32048/22809 32046/32046/22808 +f 32032/32032/22797 32046/32046/22808 32030/32030/22796 +f 32033/32033/22798 32049/32049/22810 32048/32048/22809 +f 32033/32033/22798 32048/32048/22809 32032/32032/22797 +f 32034/32034/22799 32050/32050/22811 32051/32051/22810 +f 32034/32034/22799 32051/32051/22810 32035/32035/22798 +f 32036/32036/22800 32052/32052/22812 32050/32050/22811 +f 32036/32036/22800 32050/32050/22811 32034/32034/22799 +f 32037/32037/22801 32053/32053/22813 32052/32052/22812 +f 32037/32037/22801 32052/32052/22812 32036/32036/22800 +f 32038/32038/22802 32054/32054/22814 32055/32055/22813 +f 32038/32038/22802 32055/32055/22813 32039/32039/22801 +f 32040/32040/22803 32056/32056/22815 32054/32054/22814 +f 32040/32040/22803 32054/32054/22814 32038/32038/22802 +f 32041/32041/22793 32057/32057/22816 32056/32056/22815 +f 32041/32041/22793 32056/32056/22815 32040/32040/22803 +f 32042/32042/22804 32058/32058/22817 32059/32059/22818 +f 32042/32042/22804 32059/32059/22818 32043/32043/22805 +f 32044/32044/22806 32060/32060/22819 32058/32058/22817 +f 32044/32044/22806 32058/32058/22817 32042/32042/22804 +f 32045/32045/22807 32061/32061/22820 32060/32060/22819 +f 32045/32045/22807 32060/32060/22819 32044/32044/22806 +f 32046/32046/22808 32062/32062/22821 32063/32063/22820 +f 32046/32046/22808 32063/32063/22820 32047/32047/22807 +f 32048/32048/22809 32064/32064/22822 32062/32062/22821 +f 32048/32048/22809 32062/32062/22821 32046/32046/22808 +f 32049/32049/22810 32065/32065/22823 32064/32064/22822 +f 32049/32049/22810 32064/32064/22822 32048/32048/22809 +f 32050/32050/22811 32066/32066/22824 32067/32067/22823 +f 32050/32050/22811 32067/32067/22823 32051/32051/22810 +f 32052/32052/22812 32068/32068/22825 32066/32066/22824 +f 32052/32052/22812 32066/32066/22824 32050/32050/22811 +f 32053/32053/22813 32069/32069/22826 32068/32068/22825 +f 32053/32053/22813 32068/32068/22825 32052/32052/22812 +f 32054/32054/22814 32070/32070/22827 32071/32071/22828 +f 32054/32054/22814 32071/32071/22828 32055/32055/22813 +f 32056/32056/22815 32072/32072/22829 32070/32070/22827 +f 32056/32056/22815 32070/32070/22827 32054/32054/22814 +f 32057/32057/22816 32073/32073/22830 32072/32072/22829 +f 32057/32057/22816 32072/32072/22829 32056/32056/22815 +f 32058/32058/22817 32074/32074/22831 32075/32075/22832 +f 32058/32058/22817 32075/32075/22832 32059/32059/22818 +f 32060/32060/22819 32076/32076/22833 32074/32074/22831 +f 32060/32060/22819 32074/32074/22831 32058/32058/22817 +f 32061/32061/22820 32077/32077/22834 32076/32076/22833 +f 32061/32061/22820 32076/32076/22833 32060/32060/22819 +f 32062/32062/22821 32078/32078/22835 32079/32079/22836 +f 32062/32062/22821 32079/32079/22836 32063/32063/22820 +f 32064/32064/22822 32080/32080/22837 32078/32078/22835 +f 32064/32064/22822 32078/32078/22835 32062/32062/22821 +f 32065/32065/22823 32081/32081/22838 32080/32080/22837 +f 32065/32065/22823 32080/32080/22837 32064/32064/22822 +f 32066/32066/22824 32082/32082/22839 32083/32083/22838 +f 32066/32066/22824 32083/32083/22838 32067/32067/22823 +f 32068/32068/22825 32084/32084/22840 32082/32082/22839 +f 32068/32068/22825 32082/32082/22839 32066/32066/22824 +f 32069/32069/22826 32085/32085/22841 32084/32084/22840 +f 32069/32069/22826 32084/32084/22840 32068/32068/22825 +f 32070/32070/22827 32086/32086/22842 32087/32087/22843 +f 32070/32070/22827 32087/32087/22843 32071/32071/22828 +f 32072/32072/22829 32088/32088/22844 32086/32086/22842 +f 32072/32072/22829 32086/32086/22842 32070/32070/22827 +f 32073/32073/22830 32089/32089/22832 32088/32088/22844 +f 32073/32073/22830 32088/32088/22844 32072/32072/22829 +f 32074/32074/22831 32090/32090/22845 32091/32091/22846 +f 32074/32074/22831 32091/32091/22846 32075/32075/22832 +f 32076/32076/22833 32092/32092/22847 32090/32090/22845 +f 32076/32076/22833 32090/32090/22845 32074/32074/22831 +f 32077/32077/22834 32093/32093/22848 32092/32092/22847 +f 32077/32077/22834 32092/32092/22847 32076/32076/22833 +f 32078/32078/22835 32094/32094/22849 32095/32095/22848 +f 32078/32078/22835 32095/32095/22848 32079/32079/22836 +f 32080/32080/22837 32096/32096/22850 32094/32094/22849 +f 32080/32080/22837 32094/32094/22849 32078/32078/22835 +f 32081/32081/22838 32097/32097/22851 32096/32096/22850 +f 32081/32081/22838 32096/32096/22850 32080/32080/22837 +f 32082/32082/22839 32098/32098/22852 32099/32099/22853 +f 32082/32082/22839 32099/32099/22853 32083/32083/22838 +f 32084/32084/22840 32100/32100/22854 32098/32098/22852 +f 32084/32084/22840 32098/32098/22852 32082/32082/22839 +f 32085/32085/22841 32101/32101/22855 32100/32100/22854 +f 32085/32085/22841 32100/32100/22854 32084/32084/22840 +f 32086/32086/22842 32102/32102/22856 32103/32103/22855 +f 32086/32086/22842 32103/32103/22855 32087/32087/22843 +f 32088/32088/22844 32104/32104/22857 32102/32102/22856 +f 32088/32088/22844 32102/32102/22856 32086/32086/22842 +f 32089/32089/22832 32105/32105/22846 32104/32104/22857 +f 32089/32089/22832 32104/32104/22857 32088/32088/22844 +f 32090/32090/22845 32106/32106/22858 32107/32107/22859 +f 32090/32090/22845 32107/32107/22859 32091/32091/22846 +f 32092/32092/22847 32108/32108/22860 32106/32106/22858 +f 32092/32092/22847 32106/32106/22858 32090/32090/22845 +f 32093/32093/22848 32109/32109/22861 32108/32108/22860 +f 32093/32093/22848 32108/32108/22860 32092/32092/22847 +f 32094/32094/22849 32110/32110/22862 32111/32111/22861 +f 32094/32094/22849 32111/32111/22861 32095/32095/22848 +f 32096/32096/22850 32112/32112/22863 32110/32110/22862 +f 32096/32096/22850 32110/32110/22862 32094/32094/22849 +f 32097/32097/22851 32113/32113/22864 32112/32112/22863 +f 32097/32097/22851 32112/32112/22863 32096/32096/22850 +f 32098/32098/22852 32114/32114/22865 32115/32115/22864 +f 32098/32098/22852 32115/32115/22864 32099/32099/22853 +f 32100/32100/22854 32116/32116/22866 32114/32114/22865 +f 32100/32100/22854 32114/32114/22865 32098/32098/22852 +f 32101/32101/22855 32117/32117/22867 32116/32116/22866 +f 32101/32101/22855 32116/32116/22866 32100/32100/22854 +f 32102/32102/22856 32118/32118/22868 32119/32119/22867 +f 32102/32102/22856 32119/32119/22867 32103/32103/22855 +f 32104/32104/22857 32120/32120/22869 32118/32118/22868 +f 32104/32104/22857 32118/32118/22868 32102/32102/22856 +f 32105/32105/22846 32121/32121/22870 32120/32120/22869 +f 32105/32105/22846 32120/32120/22869 32104/32104/22857 +f 32106/32106/22858 32122/32122/22871 32123/32123/22872 +f 32106/32106/22858 32123/32123/22872 32107/32107/22859 +f 32108/32108/22860 32124/32124/22873 32122/32122/22871 +f 32108/32108/22860 32122/32122/22871 32106/32106/22858 +f 32109/32109/22861 32125/32125/22874 32124/32124/22873 +f 32109/32109/22861 32124/32124/22873 32108/32108/22860 +f 32110/32110/22862 32126/32126/22875 32127/32127/22874 +f 32110/32110/22862 32127/32127/22874 32111/32111/22861 +f 32112/32112/22863 32128/32128/22876 32126/32126/22875 +f 32112/32112/22863 32126/32126/22875 32110/32110/22862 +f 32113/32113/22864 32129/32129/22877 32128/32128/22876 +f 32113/32113/22864 32128/32128/22876 32112/32112/22863 +f 32114/32114/22865 32130/32130/22878 32131/32131/22879 +f 32114/32114/22865 32131/32131/22879 32115/32115/22864 +f 32116/32116/22866 32132/32132/22880 32130/32130/22878 +f 32116/32116/22866 32130/32130/22878 32114/32114/22865 +f 32117/32117/22867 32133/32133/22881 32132/32132/22880 +f 32117/32117/22867 32132/32132/22880 32116/32116/22866 +f 32118/32118/22868 32134/32134/22882 32135/32135/22883 +f 32118/32118/22868 32135/32135/22883 32119/32119/22867 +f 32120/32120/22869 32136/32136/22884 32134/32134/22882 +f 32120/32120/22869 32134/32134/22882 32118/32118/22868 +f 32121/32121/22870 32137/32137/22872 32136/32136/22884 +f 32121/32121/22870 32136/32136/22884 32120/32120/22869 +f 32122/32122/22871 32138/32138/22885 32139/32139/22886 +f 32122/32122/22871 32139/32139/22886 32123/32123/22872 +f 32124/32124/22873 32140/32140/22887 32138/32138/22885 +f 32124/32124/22873 32138/32138/22885 32122/32122/22871 +f 32125/32125/22874 32141/32141/22888 32140/32140/22887 +f 32125/32125/22874 32140/32140/22887 32124/32124/22873 +f 32126/32126/22875 32142/32142/22889 32143/32143/22888 +f 32126/32126/22875 32143/32143/22888 32127/32127/22874 +f 32128/32128/22876 32144/32144/22890 32142/32142/22889 +f 32128/32128/22876 32142/32142/22889 32126/32126/22875 +f 32129/32129/22877 32145/32145/22891 32144/32144/22890 +f 32129/32129/22877 32144/32144/22890 32128/32128/22876 +f 32130/32130/22878 32146/32146/22892 32147/32147/22891 +f 32130/32130/22878 32147/32147/22891 32131/32131/22879 +f 32132/32132/22880 32148/32148/22893 32146/32146/22892 +f 32132/32132/22880 32146/32146/22892 32130/32130/22878 +f 32133/32133/22881 32149/32149/22894 32148/32148/22893 +f 32133/32133/22881 32148/32148/22893 32132/32132/22880 +f 32134/32134/22882 32150/32150/22895 32151/32151/22894 +f 32134/32134/22882 32151/32151/22894 32135/32135/22883 +f 32136/32136/22884 32152/32152/22896 32150/32150/22895 +f 32136/32136/22884 32150/32150/22895 32134/32134/22882 +f 32137/32137/22872 32153/32153/22886 32152/32152/22896 +f 32137/32137/22872 32152/32152/22896 32136/32136/22884 +f 32138/32138/22885 32154/32154/22897 32155/32155/22898 +f 32138/32138/22885 32155/32155/22898 32139/32139/22886 +f 32140/32140/22887 32156/32156/22899 32154/32154/22897 +f 32140/32140/22887 32154/32154/22897 32138/32138/22885 +f 32141/32141/22888 32157/32157/22900 32156/32156/22899 +f 32141/32141/22888 32156/32156/22899 32140/32140/22887 +f 32142/32142/22889 32158/32158/22901 32159/32159/22900 +f 32142/32142/22889 32159/32159/22900 32143/32143/22888 +f 32144/32144/22890 32160/32160/22902 32158/32158/22901 +f 32144/32144/22890 32158/32158/22901 32142/32142/22889 +f 32145/32145/22891 32161/32161/22903 32160/32160/22902 +f 32145/32145/22891 32160/32160/22902 32144/32144/22890 +f 32146/32146/22892 32162/32162/22904 32163/32163/22905 +f 32146/32146/22892 32163/32163/22905 32147/32147/22891 +f 32148/32148/22893 32164/32164/22906 32162/32162/22904 +f 32148/32148/22893 32162/32162/22904 32146/32146/22892 +f 32149/32149/22894 32165/32165/22907 32164/32164/22906 +f 32149/32149/22894 32164/32164/22906 32148/32148/22893 +f 32150/32150/22895 32166/32166/22908 32167/32167/22907 +f 32150/32150/22895 32167/32167/22907 32151/32151/22894 +f 32152/32152/22896 32168/32168/22909 32166/32166/22908 +f 32152/32152/22896 32166/32166/22908 32150/32150/22895 +f 32153/32153/22886 32169/32169/22898 32168/32168/22909 +f 32153/32153/22886 32168/32168/22909 32152/32152/22896 +f 32154/32154/22897 32170/32170/22910 32171/32171/22911 +f 32154/32154/22897 32171/32171/22911 32155/32155/22898 +f 32156/32156/22899 32172/32172/22912 32170/32170/22910 +f 32156/32156/22899 32170/32170/22910 32154/32154/22897 +f 32157/32157/22900 32173/32173/22913 32172/32172/22912 +f 32157/32157/22900 32172/32172/22912 32156/32156/22899 +f 32158/32158/22901 32174/32174/22914 32175/32175/22913 +f 32158/32158/22901 32175/32175/22913 32159/32159/22900 +f 32160/32160/22902 32176/32176/22915 32174/32174/22914 +f 32160/32160/22902 32174/32174/22914 32158/32158/22901 +f 32161/32161/22903 32177/32177/22916 32176/32176/22915 +f 32161/32161/22903 32176/32176/22915 32160/32160/22902 +f 32162/32162/22904 32178/32178/22917 32179/32179/22916 +f 32162/32162/22904 32179/32179/22916 32163/32163/22905 +f 32164/32164/22906 32180/32180/22918 32178/32178/22917 +f 32164/32164/22906 32178/32178/22917 32162/32162/22904 +f 32165/32165/22907 32181/32181/22919 32180/32180/22918 +f 32165/32165/22907 32180/32180/22918 32164/32164/22906 +f 32166/32166/22908 32182/32182/22920 32183/32183/22919 +f 32166/32166/22908 32183/32183/22919 32167/32167/22907 +f 32168/32168/22909 32184/32184/22921 32182/32182/22920 +f 32168/32168/22909 32182/32182/22920 32166/32166/22908 +f 32169/32169/22898 32185/32185/22922 32184/32184/22921 +f 32169/32169/22898 32184/32184/22921 32168/32168/22909 +f 32170/32170/22910 32186/32186/22923 32187/32187/22924 +f 32170/32170/22910 32187/32187/22924 32171/32171/22911 +f 32172/32172/22912 32188/32188/22925 32186/32186/22923 +f 32172/32172/22912 32186/32186/22923 32170/32170/22910 +f 32173/32173/22913 32189/32189/22926 32188/32188/22925 +f 32173/32173/22913 32188/32188/22925 32172/32172/22912 +f 32174/32174/22914 32190/32190/22927 32191/32191/22928 +f 32174/32174/22914 32191/32191/22928 32175/32175/22913 +f 32176/32176/22915 32192/32192/22929 32190/32190/22927 +f 32176/32176/22915 32190/32190/22927 32174/32174/22914 +f 32177/32177/22916 32193/32193/22930 32192/32192/22929 +f 32177/32177/22916 32192/32192/22929 32176/32176/22915 +f 32178/32178/22917 32194/32194/22931 32195/32195/22930 +f 32178/32178/22917 32195/32195/22930 32179/32179/22916 +f 32180/32180/22918 32196/32196/22932 32194/32194/22931 +f 32180/32180/22918 32194/32194/22931 32178/32178/22917 +f 32181/32181/22919 32197/32197/22933 32196/32196/22932 +f 32181/32181/22919 32196/32196/22932 32180/32180/22918 +f 32182/32182/22920 32198/32198/22934 32199/32199/22933 +f 32182/32182/22920 32199/32199/22933 32183/32183/22919 +f 32184/32184/22921 32200/32200/22935 32198/32198/22934 +f 32184/32184/22921 32198/32198/22934 32182/32182/22920 +f 32185/32185/22922 32201/32201/22936 32200/32200/22935 +f 32185/32185/22922 32200/32200/22935 32184/32184/22921 +f 32186/32186/22923 32202/32202/22937 32203/32203/22938 +f 32186/32186/22923 32203/32203/22938 32187/32187/22924 +f 32188/32188/22925 32204/32204/22939 32202/32202/22937 +f 32188/32188/22925 32202/32202/22937 32186/32186/22923 +f 32189/32189/22926 32205/32205/22940 32204/32204/22939 +f 32189/32189/22926 32204/32204/22939 32188/32188/22925 +f 32190/32190/22927 32206/32206/22941 32207/32207/22942 +f 32190/32190/22927 32207/32207/22942 32191/32191/22928 +f 32192/32192/22929 32208/32208/22943 32206/32206/22941 +f 32192/32192/22929 32206/32206/22941 32190/32190/22927 +f 32193/32193/22930 32209/32209/22944 32208/32208/22943 +f 32193/32193/22930 32208/32208/22943 32192/32192/22929 +f 32194/32194/22931 32210/32210/22945 32211/32211/22944 +f 32194/32194/22931 32211/32211/22944 32195/32195/22930 +f 32196/32196/22932 32212/32212/22946 32210/32210/22945 +f 32196/32196/22932 32210/32210/22945 32194/32194/22931 +f 32197/32197/22933 32213/32213/22947 32212/32212/22946 +f 32197/32197/22933 32212/32212/22946 32196/32196/22932 +f 32198/32198/22934 32214/32214/22948 32215/32215/22947 +f 32198/32198/22934 32215/32215/22947 32199/32199/22933 +f 32200/32200/22935 32216/32216/22949 32214/32214/22948 +f 32200/32200/22935 32214/32214/22948 32198/32198/22934 +f 32201/32201/22936 32217/32217/22950 32216/32216/22949 +f 32201/32201/22936 32216/32216/22949 32200/32200/22935 +f 32202/32202/22937 32218/32218/22951 32219/32219/22952 +f 32202/32202/22937 32219/32219/22952 32203/32203/22938 +f 32204/32204/22939 32220/32220/22953 32218/32218/22951 +f 32204/32204/22939 32218/32218/22951 32202/32202/22937 +f 32205/32205/22940 32221/32221/22954 32220/32220/22953 +f 32205/32205/22940 32220/32220/22953 32204/32204/22939 +f 32206/32206/22941 32222/32222/22955 32223/32223/22954 +f 32206/32206/22941 32223/32223/22954 32207/32207/22942 +f 32208/32208/22943 32224/32224/22956 32222/32222/22955 +f 32208/32208/22943 32222/32222/22955 32206/32206/22941 +f 32209/32209/22944 32225/32225/22957 32224/32224/22956 +f 32209/32209/22944 32224/32224/22956 32208/32208/22943 +f 32210/32210/22945 32226/32226/22958 32227/32227/22957 +f 32210/32210/22945 32227/32227/22957 32211/32211/22944 +f 32212/32212/22946 32228/32228/22959 32226/32226/22958 +f 32212/32212/22946 32226/32226/22958 32210/32210/22945 +f 32213/32213/22947 32229/32229/22960 32228/32228/22959 +f 32213/32213/22947 32228/32228/22959 32212/32212/22946 +f 32214/32214/22948 32230/32230/22961 32231/32231/22962 +f 32214/32214/22948 32231/32231/22962 32215/32215/22947 +f 32216/32216/22949 32232/32232/22963 32230/32230/22961 +f 32216/32216/22949 32230/32230/22961 32214/32214/22948 +f 32217/32217/22950 32233/32233/22952 32232/32232/22963 +f 32217/32217/22950 32232/32232/22963 32216/32216/22949 +f 32218/32218/22951 32234/32234/22964 32235/32235/22965 +f 32218/32218/22951 32235/32235/22965 32219/32219/22952 +f 32220/32220/22953 32236/32236/22966 32234/32234/22964 +f 32220/32220/22953 32234/32234/22964 32218/32218/22951 +f 32221/32221/22954 32237/32237/22967 32236/32236/22966 +f 32221/32221/22954 32236/32236/22966 32220/32220/22953 +f 32222/32222/22955 32238/32238/22968 32239/32239/22967 +f 32222/32222/22955 32239/32239/22967 32223/32223/22954 +f 32224/32224/22956 32240/32240/22969 32238/32238/22968 +f 32224/32224/22956 32238/32238/22968 32222/32222/22955 +f 32225/32225/22957 32241/32241/22970 32240/32240/22969 +f 32225/32225/22957 32240/32240/22969 32224/32224/22956 +f 32226/32226/22958 32242/32242/22971 32243/32243/22972 +f 32226/32226/22958 32243/32243/22972 32227/32227/22957 +f 32228/32228/22959 32244/32244/22973 32242/32242/22971 +f 32228/32228/22959 32242/32242/22971 32226/32226/22958 +f 32229/32229/22960 32245/32245/22974 32244/32244/22973 +f 32229/32229/22960 32244/32244/22973 32228/32228/22959 +f 32230/32230/22961 32246/32246/22975 32247/32247/22974 +f 32230/32230/22961 32247/32247/22974 32231/32231/22962 +f 32232/32232/22963 32248/32248/22976 32246/32246/22975 +f 32232/32232/22963 32246/32246/22975 32230/32230/22961 +f 32233/32233/22952 32249/32249/22977 32248/32248/22976 +f 32233/32233/22952 32248/32248/22976 32232/32232/22963 +f 32234/32234/22964 32250/32250/22978 32251/32251/22979 +f 32234/32234/22964 32251/32251/22979 32235/32235/22965 +f 32236/32236/22966 32252/32252/22980 32250/32250/22978 +f 32236/32236/22966 32250/32250/22978 32234/32234/22964 +f 32237/32237/22967 32253/32253/22981 32252/32252/22980 +f 32237/32237/22967 32252/32252/22980 32236/32236/22966 +f 32238/32238/22968 32254/32254/22982 32255/32255/22981 +f 32238/32238/22968 32255/32255/22981 32239/32239/22967 +f 32240/32240/22969 32256/32256/22983 32254/32254/22982 +f 32240/32240/22969 32254/32254/22982 32238/32238/22968 +f 32241/32241/22970 32257/32257/22984 32256/32256/22983 +f 32241/32241/22970 32256/32256/22983 32240/32240/22969 +f 32242/32242/22971 32258/32258/22985 32259/32259/22984 +f 32242/32242/22971 32259/32259/22984 32243/32243/22972 +f 32244/32244/22973 32260/32260/22986 32258/32258/22985 +f 32244/32244/22973 32258/32258/22985 32242/32242/22971 +f 32245/32245/22974 32261/32261/22987 32260/32260/22986 +f 32245/32245/22974 32260/32260/22986 32244/32244/22973 +f 32246/32246/22975 32262/32262/22988 32263/32263/22987 +f 32246/32246/22975 32263/32263/22987 32247/32247/22974 +f 32248/32248/22976 32264/32264/22989 32262/32262/22988 +f 32248/32248/22976 32262/32262/22988 32246/32246/22975 +f 32249/32249/22977 32265/32265/22979 32264/32264/22989 +f 32249/32249/22977 32264/32264/22989 32248/32248/22976 +f 32250/32250/22978 32266/32266/22990 32267/32267/22991 +f 32250/32250/22978 32267/32267/22991 32251/32251/22979 +f 32252/32252/22980 32268/32268/22992 32266/32266/22990 +f 32252/32252/22980 32266/32266/22990 32250/32250/22978 +f 32253/32253/22981 32269/32269/22993 32268/32268/22992 +f 32253/32253/22981 32268/32268/22992 32252/32252/22980 +f 32254/32254/22982 32270/32270/22994 32271/32271/22995 +f 32254/32254/22982 32271/32271/22995 32255/32255/22981 +f 32256/32256/22983 32272/32272/22996 32270/32270/22994 +f 32256/32256/22983 32270/32270/22994 32254/32254/22982 +f 32259/32259/22984 32273/32273/22997 32274/32274/22996 +f 32259/32259/22984 32274/32274/22996 32275/32275/22998 +f 32258/32258/22985 32276/32276/22999 32273/32273/22997 +f 32258/32258/22985 32273/32273/22997 32259/32259/22984 +f 32260/32260/22986 32277/32277/23000 32276/32276/22999 +f 32260/32260/22986 32276/32276/22999 32258/32258/22985 +f 32261/32261/22987 32278/32278/23001 32277/32277/23000 +f 32261/32261/22987 32277/32277/23000 32260/32260/22986 +f 32262/32262/22988 32279/32279/23002 32280/32280/23001 +f 32262/32262/22988 32280/32280/23001 32263/32263/22987 +f 32264/32264/22989 32281/32281/23003 32279/32279/23002 +f 32264/32264/22989 32279/32279/23002 32262/32262/22988 +f 32251/32251/22979 32267/32267/22991 32282/32282/23003 +f 32251/32251/22979 32282/32282/23003 32283/32283/23004 +f 32266/32266/22990 32284/32284/23005 32285/32285/23006 +f 32266/32266/22990 32285/32285/23006 32267/32267/22991 +f 32268/32268/22992 32286/32286/23007 32284/32284/23005 +f 32268/32268/22992 32284/32284/23005 32266/32266/22990 +f 32271/32271/22995 32287/32287/23008 32288/32288/23009 +f 32271/32271/22995 32288/32288/23009 32289/32289/22992 +f 32270/32270/22994 32290/32290/23010 32287/32287/23008 +f 32270/32270/22994 32287/32287/23008 32271/32271/22995 +f 32272/32272/22996 32291/32291/23011 32290/32290/23010 +f 32272/32272/22996 32290/32290/23010 32270/32270/22994 +f 32273/32273/22997 32292/32292/23012 32293/32293/23011 +f 32273/32273/22997 32293/32293/23011 32274/32274/22996 +f 32276/32276/22999 32294/32294/23013 32292/32292/23012 +f 32276/32276/22999 32292/32292/23012 32273/32273/22997 +f 32277/32277/23000 32295/32295/23014 32294/32294/23013 +f 32277/32277/23000 32294/32294/23013 32276/32276/22999 +f 32280/32280/23001 32296/32296/23015 32297/32297/23016 +f 32280/32280/23001 32297/32297/23016 32298/32298/23017 +f 32279/32279/23002 32299/32299/23018 32296/32296/23015 +f 32279/32279/23002 32296/32296/23015 32280/32280/23001 +f 32281/32281/23003 32300/32300/23019 32299/32299/23018 +f 32281/32281/23003 32299/32299/23018 32279/32279/23002 +f 32267/32267/22991 32285/32285/23006 32301/32301/23019 +f 32267/32267/22991 32301/32301/23019 32282/32282/23003 +f 32302/32302/23020 32303/32303/23021 32304/32304/23022 +f 32302/32302/23020 32304/32304/23022 32305/32305/23023 +f 32306/32306/23009 32307/32307/23024 32303/32303/23021 +f 32306/32306/23009 32303/32303/23021 32302/32302/23020 +f 32287/32287/23008 32308/32308/23025 32309/32309/23024 +f 32287/32287/23008 32309/32309/23024 32288/32288/23009 +f 32290/32290/23010 32310/32310/23026 32308/32308/23025 +f 32290/32290/23010 32308/32308/23025 32287/32287/23008 +f 32291/32291/23011 32311/32311/23027 32310/32310/23026 +f 32291/32291/23011 32310/32310/23026 32290/32290/23010 +f 32312/32312/23012 32313/32313/23028 32314/32314/23029 +f 32312/32312/23012 32314/32314/23029 32315/32315/23011 +f 32316/32316/23030 32317/32317/23031 32313/32313/23028 +f 32316/32316/23030 32313/32313/23028 32312/32312/23012 +f 32318/32318/23014 32319/32319/23032 32317/32317/23031 +f 32318/32318/23014 32317/32317/23031 32316/32316/23030 +f 32296/32296/23015 32320/32320/23033 32321/32321/23032 +f 32296/32296/23015 32321/32321/23032 32297/32297/23016 +f 32299/32299/23018 32322/32322/23034 32320/32320/23033 +f 32299/32299/23018 32320/32320/23033 32296/32296/23015 +f 32300/32300/23019 32323/32323/23035 32322/32322/23034 +f 32300/32300/23019 32322/32322/23034 32299/32299/23018 +f 32305/32305/23023 32304/32304/23022 32324/32324/23036 +f 32305/32305/23023 32324/32324/23036 32325/32325/23037 +f 32303/32303/23021 32326/32326/23038 32327/32327/23039 +f 32303/32303/23021 32327/32327/23039 32304/32304/23022 +f 32307/32307/23024 32328/32328/23040 32326/32326/23038 +f 32307/32307/23024 32326/32326/23038 32303/32303/23021 +f 32308/32308/23025 32329/32329/23041 32330/32330/23040 +f 32308/32308/23025 32330/32330/23040 32309/32309/23024 +f 32310/32310/23026 32331/32331/23042 32329/32329/23041 +f 32310/32310/23026 32329/32329/23041 32308/32308/23025 +f 32314/32314/23029 32332/32332/23043 32333/32333/23042 +f 32314/32314/23029 32333/32333/23042 32334/32334/23026 +f 32313/32313/23028 32335/32335/23044 32332/32332/23043 +f 32313/32313/23028 32332/32332/23043 32314/32314/23029 +f 32317/32317/23031 32336/32336/23045 32335/32335/23044 +f 32317/32317/23031 32335/32335/23044 32313/32313/23028 +f 32319/32319/23032 32337/32337/23046 32336/32336/23045 +f 32319/32319/23032 32336/32336/23045 32317/32317/23031 +f 32320/32320/23033 32338/32338/23047 32339/32339/23048 +f 32320/32320/23033 32339/32339/23048 32321/32321/23032 +f 32322/32322/23034 32340/32340/23049 32338/32338/23047 +f 32322/32322/23034 32338/32338/23047 32320/32320/23033 +f 32324/32324/23036 32341/32341/23050 32342/32342/23051 +f 32324/32324/23036 32342/32342/23051 32343/32343/23052 +f 32304/32304/23022 32327/32327/23039 32341/32341/23050 +f 32304/32304/23022 32341/32341/23050 32324/32324/23036 +f 32326/32326/23038 32344/32344/23053 32345/32345/23054 +f 32326/32326/23038 32345/32345/23054 32327/32327/23039 +f 32330/32330/23040 32346/32346/23055 32347/32347/23053 +f 32330/32330/23040 32347/32347/23053 32348/32348/23038 +f 32329/32329/23041 32349/32349/23056 32346/32346/23055 +f 32329/32329/23041 32346/32346/23055 32330/32330/23040 +f 32331/32331/23042 32350/32350/23057 32349/32349/23056 +f 32331/32331/23042 32349/32349/23056 32329/32329/23041 +f 32332/32332/23043 32351/32351/23058 32352/32352/23057 +f 32332/32332/23043 32352/32352/23057 32333/32333/23042 +f 32335/32335/23044 32353/32353/23059 32351/32351/23058 +f 32335/32335/23044 32351/32351/23058 32332/32332/23043 +f 32336/32336/23045 32354/32354/23060 32353/32353/23059 +f 32336/32336/23045 32353/32353/23059 32335/32335/23044 +f 32339/32339/23048 32355/32355/23061 32356/32356/23060 +f 32339/32339/23048 32356/32356/23060 32357/32357/23062 +f 32338/32338/23047 32358/32358/23063 32355/32355/23061 +f 32338/32338/23047 32355/32355/23061 32339/32339/23048 +f 32340/32340/23049 32359/32359/23064 32358/32358/23063 +f 32340/32340/23049 32358/32358/23063 32338/32338/23047 +f 32341/32341/23050 32360/32360/23065 32361/32361/23064 +f 32341/32341/23050 32361/32361/23064 32342/32342/23051 +f 32327/32327/23039 32345/32345/23054 32360/32360/23065 +f 32327/32327/23039 32360/32360/23065 32341/32341/23050 +f 32344/32344/23053 32362/32362/23066 32363/32363/23067 +f 32344/32344/23053 32363/32363/23067 32345/32345/23054 +f 32346/32346/23055 32364/32364/23068 32365/32365/23066 +f 32346/32346/23055 32365/32365/23066 32347/32347/23053 +f 32349/32349/23056 32366/32366/23069 32364/32364/23068 +f 32349/32349/23056 32364/32364/23068 32346/32346/23055 +f 32350/32350/23057 32367/32367/23070 32366/32366/23069 +f 32350/32350/23057 32366/32366/23069 32349/32349/23056 +f 32351/32351/23058 32368/32368/23071 32369/32369/23072 +f 32351/32351/23058 32369/32369/23072 32352/32352/23057 +f 32353/32353/23059 32370/32370/23073 32368/32368/23071 +f 32353/32353/23059 32368/32368/23071 32351/32351/23058 +f 32354/32354/23060 32371/32371/23074 32370/32370/23073 +f 32354/32354/23060 32370/32370/23073 32353/32353/23059 +f 32355/32355/23061 32372/32372/23075 32373/32373/23074 +f 32355/32355/23061 32373/32373/23074 32356/32356/23060 +f 32358/32358/23063 32374/32374/23076 32372/32372/23075 +f 32358/32358/23063 32372/32372/23075 32355/32355/23061 +f 32359/32359/23064 32375/32375/23077 32374/32374/23076 +f 32359/32359/23064 32374/32374/23076 32358/32358/23063 +f 32360/32360/23065 32376/32376/23078 32377/32377/23079 +f 32360/32360/23065 32377/32377/23079 32361/32361/23064 +f 32345/32345/23054 32363/32363/23067 32376/32376/23078 +f 32345/32345/23054 32376/32376/23078 32360/32360/23065 +f 32378/32378/23066 32379/32379/23080 32380/32380/23081 +f 32378/32378/23066 32380/32380/23081 32381/32381/23067 +f 32364/32364/23068 32382/32382/23082 32383/32383/23080 +f 32364/32364/23068 32383/32383/23080 32365/32365/23066 +f 32366/32366/23069 32384/32384/23083 32382/32382/23082 +f 32366/32366/23069 32382/32382/23082 32364/32364/23068 +f 32367/32367/23070 32385/32385/23084 32384/32384/23083 +f 32367/32367/23070 32384/32384/23083 32366/32366/23069 +f 32386/32386/23071 32387/32387/23085 32388/32388/23084 +f 32386/32386/23071 32388/32388/23084 32389/32389/23070 +f 32390/32390/23073 32391/32391/23086 32387/32387/23085 +f 32390/32390/23073 32387/32387/23085 32386/32386/23071 +f 32392/32392/23074 32393/32393/23087 32391/32391/23086 +f 32392/32392/23074 32391/32391/23086 32390/32390/23073 +f 32372/32372/23075 32394/32394/23088 32395/32395/23087 +f 32372/32372/23075 32395/32395/23087 32373/32373/23074 +f 32374/32374/23076 32396/32396/23089 32394/32394/23088 +f 32374/32374/23076 32394/32394/23088 32372/32372/23075 +f 32375/32375/23077 32397/32397/23090 32396/32396/23089 +f 32375/32375/23077 32396/32396/23089 32374/32374/23076 +f 32398/32398/23078 32399/32399/23091 32400/32400/23090 +f 32398/32398/23078 32400/32400/23090 32401/32401/23079 +f 32381/32381/23067 32380/32380/23081 32399/32399/23091 +f 32381/32381/23067 32399/32399/23091 32398/32398/23078 +f 32379/32379/23080 32402/32402/23092 32403/32403/23093 +f 32379/32379/23080 32403/32403/23093 32380/32380/23081 +f 32382/32382/23082 32404/32404/23094 32405/32405/23092 +f 32382/32382/23082 32405/32405/23092 32383/32383/23080 +f 32384/32384/23083 32406/32406/23095 32404/32404/23094 +f 32384/32384/23083 32404/32404/23094 32382/32382/23082 +f 32385/32385/23084 32407/32407/23096 32406/32406/23095 +f 32385/32385/23084 32406/32406/23095 32384/32384/23083 +f 32387/32387/23085 32408/32408/23097 32409/32409/23096 +f 32387/32387/23085 32409/32409/23096 32388/32388/23084 +f 32391/32391/23086 32410/32410/23098 32408/32408/23097 +f 32391/32391/23086 32408/32408/23097 32387/32387/23085 +f 32393/32393/23087 32411/32411/23099 32410/32410/23098 +f 32393/32393/23087 32410/32410/23098 32391/32391/23086 +f 32394/32394/23088 32412/32412/23100 32413/32413/23099 +f 32394/32394/23088 32413/32413/23099 32395/32395/23087 +f 32396/32396/23089 32414/32414/23101 32412/32412/23100 +f 32396/32396/23089 32412/32412/23100 32394/32394/23088 +f 32397/32397/23090 32415/32415/23102 32414/32414/23101 +f 32397/32397/23090 32414/32414/23101 32396/32396/23089 +f 32399/32399/23091 32416/32416/23103 32417/32417/23104 +f 32399/32399/23091 32417/32417/23104 32400/32400/23090 +f 32380/32380/23081 32403/32403/23093 32416/32416/23103 +f 32380/32380/23081 32416/32416/23103 32399/32399/23091 +f 32402/32402/23092 32418/32418/23105 32419/32419/23106 +f 32402/32402/23092 32419/32419/23106 32403/32403/23093 +f 32404/32404/23094 32420/32420/23107 32421/32421/23105 +f 32404/32404/23094 32421/32421/23105 32405/32405/23092 +f 32406/32406/23095 32422/32422/23108 32420/32420/23107 +f 32406/32406/23095 32420/32420/23107 32404/32404/23094 +f 32407/32407/23096 32423/32423/23109 32422/32422/23108 +f 32407/32407/23096 32422/32422/23108 32406/32406/23095 +f 32408/32408/23097 32424/32424/23110 32425/32425/23109 +f 32408/32408/23097 32425/32425/23109 32409/32409/23096 +f 32410/32410/23098 32426/32426/23111 32424/32424/23110 +f 32410/32410/23098 32424/32424/23110 32408/32408/23097 +f 32411/32411/23099 32427/32427/23112 32426/32426/23111 +f 32411/32411/23099 32426/32426/23111 32410/32410/23098 +f 32412/32412/23100 32428/32428/23113 32429/32429/23112 +f 32412/32412/23100 32429/32429/23112 32413/32413/23099 +f 32414/32414/23101 32430/32430/23114 32428/32428/23113 +f 32414/32414/23101 32428/32428/23113 32412/32412/23100 +f 32415/32415/23102 32431/32431/23115 32430/32430/23114 +f 32415/32415/23102 32430/32430/23114 32414/32414/23101 +f 32416/32416/23103 32432/32432/23116 32433/32433/23115 +f 32416/32416/23103 32433/32433/23115 32417/32417/23104 +f 32403/32403/23093 32419/32419/23106 32432/32432/23116 +f 32403/32403/23093 32432/32432/23116 32416/32416/23103 +f 32418/32418/23105 32434/32434/23117 32435/32435/23118 +f 32418/32418/23105 32435/32435/23118 32419/32419/23106 +f 32420/32420/23107 32436/32436/23119 32437/32437/23120 +f 32420/32420/23107 32437/32437/23120 32421/32421/23105 +f 32422/32422/23108 32438/32438/23121 32436/32436/23119 +f 32422/32422/23108 32436/32436/23119 32420/32420/23107 +f 32423/32423/23109 32439/32439/23122 32438/32438/23121 +f 32423/32423/23109 32438/32438/23121 32422/32422/23108 +f 32424/32424/23110 32440/32440/23123 32441/32441/23122 +f 32424/32424/23110 32441/32441/23122 32425/32425/23109 +f 32426/32426/23111 32442/32442/23124 32440/32440/23123 +f 32426/32426/23111 32440/32440/23123 32424/32424/23110 +f 32427/32427/23112 32443/32443/23125 32442/32442/23124 +f 32427/32427/23112 32442/32442/23124 32426/32426/23111 +f 32428/32428/23113 32444/32444/23126 32445/32445/23125 +f 32428/32428/23113 32445/32445/23125 32429/32429/23112 +f 32430/32430/23114 32446/32446/23127 32444/32444/23126 +f 32430/32430/23114 32444/32444/23126 32428/32428/23113 +f 32431/32431/23115 32447/32447/23128 32446/32446/23127 +f 32431/32431/23115 32446/32446/23127 32430/32430/23114 +f 32432/32432/23116 32448/32448/23129 32449/32449/23128 +f 32432/32432/23116 32449/32449/23128 32433/32433/23115 +f 32419/32419/23106 32435/32435/23118 32448/32448/23129 +f 32419/32419/23106 32448/32448/23129 32432/32432/23116 +f 32434/32434/23117 32450/32450/23130 32451/32451/23131 +f 32434/32434/23117 32451/32451/23131 32435/32435/23118 +f 32436/32436/23119 32452/32452/23132 32453/32453/23133 +f 32436/32436/23119 32453/32453/23133 32437/32437/23120 +f 32438/32438/23121 32454/32454/23134 32452/32452/23132 +f 32438/32438/23121 32452/32452/23132 32436/32436/23119 +f 32439/32439/23122 32455/32455/23135 32454/32454/23134 +f 32439/32439/23122 32454/32454/23134 32438/32438/23121 +f 32440/32440/23123 32456/32456/23136 32457/32457/23135 +f 32440/32440/23123 32457/32457/23135 32441/32441/23122 +f 32442/32442/23124 32458/32458/23137 32456/32456/23136 +f 32442/32442/23124 32456/32456/23136 32440/32440/23123 +f 32443/32443/23125 32459/32459/23138 32458/32458/23137 +f 32443/32443/23125 32458/32458/23137 32442/32442/23124 +f 32444/32444/23126 32460/32460/23139 32461/32461/23138 +f 32444/32444/23126 32461/32461/23138 32445/32445/23125 +f 32446/32446/23127 32462/32462/23140 32460/32460/23139 +f 32446/32446/23127 32460/32460/23139 32444/32444/23126 +f 32447/32447/23128 32463/32463/23141 32462/32462/23140 +f 32447/32447/23128 32462/32462/23140 32446/32446/23127 +f 32448/32448/23129 32464/32464/23142 32465/32465/23143 +f 32448/32448/23129 32465/32465/23143 32449/32449/23128 +f 32435/32435/23118 32451/32451/23131 32464/32464/23142 +f 32435/32435/23118 32464/32464/23142 32448/32448/23129 +f 32450/32450/23130 32466/32466/23144 32467/32467/23145 +f 32450/32450/23130 32467/32467/23145 32451/32451/23131 +f 32452/32452/23132 32468/32468/23146 32469/32469/23144 +f 32452/32452/23132 32469/32469/23144 32453/32453/23133 +f 32454/32454/23134 32470/32470/23147 32468/32468/23146 +f 32454/32454/23134 32468/32468/23146 32452/32452/23132 +f 32455/32455/23135 32471/32471/23148 32470/32470/23147 +f 32455/32455/23135 32470/32470/23147 32454/32454/23134 +f 32456/32456/23136 32472/32472/23149 32473/32473/23150 +f 32456/32456/23136 32473/32473/23150 32457/32457/23135 +f 32458/32458/23137 32474/32474/23151 32472/32472/23149 +f 32458/32458/23137 32472/32472/23149 32456/32456/23136 +f 32459/32459/23138 32475/32475/23152 32474/32474/23151 +f 32459/32459/23138 32474/32474/23151 32458/32458/23137 +f 32460/32460/23139 32476/32476/23153 32477/32477/23154 +f 32460/32460/23139 32477/32477/23154 32461/32461/23138 +f 32462/32462/23140 32478/32478/23155 32476/32476/23153 +f 32462/32462/23140 32476/32476/23153 32460/32460/23139 +f 32463/32463/23141 32479/32479/23156 32478/32478/23155 +f 32463/32463/23141 32478/32478/23155 32462/32462/23140 +f 32464/32464/23142 32480/32480/23157 32481/32481/23156 +f 32464/32464/23142 32481/32481/23156 32465/32465/23143 +f 32451/32451/23131 32467/32467/23145 32480/32480/23157 +f 32451/32451/23131 32480/32480/23157 32464/32464/23142 +f 32466/32466/23144 32482/32482/23158 32483/32483/23159 +f 32466/32466/23144 32483/32483/23159 32467/32467/23145 +f 32468/32468/23146 32484/32484/23160 32485/32485/23158 +f 32468/32468/23146 32485/32485/23158 32469/32469/23144 +f 32470/32470/23147 32486/32486/23161 32484/32484/23160 +f 32470/32470/23147 32484/32484/23160 32468/32468/23146 +f 32471/32471/23148 32487/32487/23162 32486/32486/23161 +f 32471/32471/23148 32486/32486/23161 32470/32470/23147 +f 32472/32472/23149 32488/32488/23163 32489/32489/23164 +f 32472/32472/23149 32489/32489/23164 32473/32473/23150 +f 32474/32474/23151 32490/32490/23165 32488/32488/23163 +f 32474/32474/23151 32488/32488/23163 32472/32472/23149 +f 32475/32475/23152 32491/32491/23166 32490/32490/23165 +f 32475/32475/23152 32490/32490/23165 32474/32474/23151 +f 32476/32476/23153 32492/32492/23167 32493/32493/23166 +f 32476/32476/23153 32493/32493/23166 32477/32477/23154 +f 32478/32478/23155 32494/32494/23168 32492/32492/23167 +f 32478/32478/23155 32492/32492/23167 32476/32476/23153 +f 32479/32479/23156 32495/32495/23169 32494/32494/23168 +f 32479/32479/23156 32494/32494/23168 32478/32478/23155 +f 32480/32480/23157 32496/32496/23170 32497/32497/23169 +f 32480/32480/23157 32497/32497/23169 32481/32481/23156 +f 32467/32467/23145 32483/32483/23159 32496/32496/23170 +f 32467/32467/23145 32496/32496/23170 32480/32480/23157 +f 32482/32482/23158 32498/32498/23171 32499/32499/23172 +f 32482/32482/23158 32499/32499/23172 32483/32483/23159 +f 32484/32484/23160 32500/32500/23173 32501/32501/23171 +f 32484/32484/23160 32501/32501/23171 32485/32485/23158 +f 32486/32486/23161 32502/32502/23174 32500/32500/23173 +f 32486/32486/23161 32500/32500/23173 32484/32484/23160 +f 32487/32487/23162 32503/32503/23175 32502/32502/23174 +f 32487/32487/23162 32502/32502/23174 32486/32486/23161 +f 32488/32488/23163 32504/32504/23176 32505/32505/23175 +f 32488/32488/23163 32505/32505/23175 32489/32489/23164 +f 32490/32490/23165 32506/32506/23177 32504/32504/23176 +f 32490/32490/23165 32504/32504/23176 32488/32488/23163 +f 32491/32491/23166 32507/32507/23178 32506/32506/23177 +f 32491/32491/23166 32506/32506/23177 32490/32490/23165 +f 32492/32492/23167 32508/32508/23179 32509/32509/23178 +f 32492/32492/23167 32509/32509/23178 32493/32493/23166 +f 32494/32494/23168 32510/32510/23180 32508/32508/23179 +f 32494/32494/23168 32508/32508/23179 32492/32492/23167 +f 32495/32495/23169 32511/32511/23181 32510/32510/23180 +f 32495/32495/23169 32510/32510/23180 32494/32494/23168 +f 32496/32496/23170 32512/32512/23182 32513/32513/23181 +f 32496/32496/23170 32513/32513/23181 32497/32497/23169 +f 32483/32483/23159 32499/32499/23172 32512/32512/23182 +f 32483/32483/23159 32512/32512/23182 32496/32496/23170 +f 32498/32498/23171 32514/32514/23183 32515/32515/23184 +f 32498/32498/23171 32515/32515/23184 32499/32499/23172 +f 32500/32500/23173 32516/32516/23185 32517/32517/23183 +f 32500/32500/23173 32517/32517/23183 32501/32501/23171 +f 32502/32502/23174 32518/32518/23186 32516/32516/23185 +f 32502/32502/23174 32516/32516/23185 32500/32500/23173 +f 32503/32503/23175 32519/32519/23187 32518/32518/23186 +f 32503/32503/23175 32518/32518/23186 32502/32502/23174 +f 32504/32504/23176 32520/32520/23188 32521/32521/23187 +f 32504/32504/23176 32521/32521/23187 32505/32505/23175 +f 32506/32506/23177 32522/32522/23189 32520/32520/23188 +f 32506/32506/23177 32520/32520/23188 32504/32504/23176 +f 32507/32507/23178 32523/32523/23190 32522/32522/23189 +f 32507/32507/23178 32522/32522/23189 32506/32506/23177 +f 32508/32508/23179 32524/32524/23191 32525/32525/23190 +f 32508/32508/23179 32525/32525/23190 32509/32509/23178 +f 32510/32510/23180 32526/32526/23192 32524/32524/23191 +f 32510/32510/23180 32524/32524/23191 32508/32508/23179 +f 32511/32511/23181 32527/32527/23193 32526/32526/23192 +f 32511/32511/23181 32526/32526/23192 32510/32510/23180 +f 32512/32512/23182 32528/32528/23194 32529/32529/23193 +f 32512/32512/23182 32529/32529/23193 32513/32513/23181 +f 32499/32499/23172 32515/32515/23184 32528/32528/23194 +f 32499/32499/23172 32528/32528/23194 32512/32512/23182 +f 32514/32514/23183 32530/32530/23195 32531/32531/23196 +f 32514/32514/23183 32531/32531/23196 32515/32515/23184 +f 32516/32516/23185 32532/32532/23197 32533/32533/23195 +f 32516/32516/23185 32533/32533/23195 32517/32517/23183 +f 32518/32518/23186 32534/32534/23198 32532/32532/23197 +f 32518/32518/23186 32532/32532/23197 32516/32516/23185 +f 32519/32519/23187 32535/32535/23199 32534/32534/23198 +f 32519/32519/23187 32534/32534/23198 32518/32518/23186 +f 32520/32520/23188 32536/32536/23200 32537/32537/23199 +f 32520/32520/23188 32537/32537/23199 32521/32521/23187 +f 32522/32522/23189 32538/32538/23201 32536/32536/23200 +f 32522/32522/23189 32536/32536/23200 32520/32520/23188 +f 32523/32523/23190 32539/32539/23202 32538/32538/23201 +f 32523/32523/23190 32538/32538/23201 32522/32522/23189 +f 32524/32524/23191 32540/32540/23203 32541/32541/23204 +f 32524/32524/23191 32541/32541/23204 32525/32525/23190 +f 32526/32526/23192 32542/32542/23205 32540/32540/23203 +f 32526/32526/23192 32540/32540/23203 32524/32524/23191 +f 32527/32527/23193 32543/32543/23206 32542/32542/23205 +f 32527/32527/23193 32542/32542/23205 32526/32526/23192 +f 32528/32528/23194 32544/32544/23207 32545/32545/23206 +f 32528/32528/23194 32545/32545/23206 32529/32529/23193 +f 32515/32515/23184 32531/32531/23196 32544/32544/23207 +f 32515/32515/23184 32544/32544/23207 32528/32528/23194 +f 32530/32530/23195 32546/32546/23208 32547/32547/23209 +f 32530/32530/23195 32547/32547/23209 32531/32531/23196 +f 32532/32532/23197 32548/32548/23210 32549/32549/23208 +f 32532/32532/23197 32549/32549/23208 32533/32533/23195 +f 32534/32534/23198 32550/32550/23211 32548/32548/23210 +f 32534/32534/23198 32548/32548/23210 32532/32532/23197 +f 32535/32535/23199 32551/32551/23212 32550/32550/23211 +f 32535/32535/23199 32550/32550/23211 32534/32534/23198 +f 32536/32536/23200 32552/32552/23213 32553/32553/23214 +f 32536/32536/23200 32553/32553/23214 32537/32537/23199 +f 32538/32538/23201 32554/32554/23215 32552/32552/23213 +f 32538/32538/23201 32552/32552/23213 32536/32536/23200 +f 32539/32539/23202 32555/32555/23216 32554/32554/23215 +f 32539/32539/23202 32554/32554/23215 32538/32538/23201 +f 32540/32540/23203 32556/32556/23217 32557/32557/23216 +f 32540/32540/23203 32557/32557/23216 32541/32541/23204 +f 32542/32542/23205 32558/32558/23218 32556/32556/23217 +f 32542/32542/23205 32556/32556/23217 32540/32540/23203 +f 32543/32543/23206 32559/32559/23219 32558/32558/23218 +f 32543/32543/23206 32558/32558/23218 32542/32542/23205 +f 32544/32544/23207 32560/32560/23220 32561/32561/23221 +f 32544/32544/23207 32561/32561/23221 32545/32545/23206 +f 32531/32531/23196 32547/32547/23209 32560/32560/23220 +f 32531/32531/23196 32560/32560/23220 32544/32544/23207 +f 32546/32546/23208 32562/32562/23222 32563/32563/23223 +f 32546/32546/23208 32563/32563/23223 32547/32547/23209 +f 32548/32548/23210 32564/32564/23224 32565/32565/23222 +f 32548/32548/23210 32565/32565/23222 32549/32549/23208 +f 32550/32550/23211 32566/32566/23225 32564/32564/23224 +f 32550/32550/23211 32564/32564/23224 32548/32548/23210 +f 32551/32551/23212 32567/32567/23226 32566/32566/23225 +f 32551/32551/23212 32566/32566/23225 32550/32550/23211 +f 32552/32552/23213 32568/32568/23227 32569/32569/23226 +f 32552/32552/23213 32569/32569/23226 32553/32553/23214 +f 32554/32554/23215 32570/32570/23228 32568/32568/23227 +f 32554/32554/23215 32568/32568/23227 32552/32552/23213 +f 32555/32555/23216 32571/32571/23229 32570/32570/23228 +f 32555/32555/23216 32570/32570/23228 32554/32554/23215 +f 32556/32556/23217 32572/32572/23230 32573/32573/23229 +f 32556/32556/23217 32573/32573/23229 32557/32557/23216 +f 32558/32558/23218 32574/32574/23231 32572/32572/23230 +f 32558/32558/23218 32572/32572/23230 32556/32556/23217 +f 32559/32559/23219 32575/32575/23232 32574/32574/23231 +f 32559/32559/23219 32574/32574/23231 32558/32558/23218 +f 32560/32560/23220 32576/32576/23233 32577/32577/23232 +f 32560/32560/23220 32577/32577/23232 32561/32561/23221 +f 32547/32547/23209 32563/32563/23223 32576/32576/23233 +f 32547/32547/23209 32576/32576/23233 32560/32560/23220 +f 32562/32562/23222 32578/32578/23234 32579/32579/23235 +f 32562/32562/23222 32579/32579/23235 32563/32563/23223 +f 32564/32564/23224 32580/32580/23236 32581/32581/23234 +f 32564/32564/23224 32581/32581/23234 32565/32565/23222 +f 32566/32566/23225 32582/32582/23237 32580/32580/23236 +f 32566/32566/23225 32580/32580/23236 32564/32564/23224 +f 32567/32567/23226 32583/32583/23238 32582/32582/23237 +f 32567/32567/23226 32582/32582/23237 32566/32566/23225 +f 32568/32568/23227 32584/32584/23239 32585/32585/23238 +f 32568/32568/23227 32585/32585/23238 32569/32569/23226 +f 32570/32570/23228 32586/32586/23240 32584/32584/23239 +f 32570/32570/23228 32584/32584/23239 32568/32568/23227 +f 32571/32571/23229 32587/32587/23241 32586/32586/23240 +f 32571/32571/23229 32586/32586/23240 32570/32570/23228 +f 32572/32572/23230 32588/32588/23242 32589/32589/23241 +f 32572/32572/23230 32589/32589/23241 32573/32573/23229 +f 32574/32574/23231 32590/32590/23243 32588/32588/23242 +f 32574/32574/23231 32588/32588/23242 32572/32572/23230 +f 32575/32575/23232 32591/32591/23244 32590/32590/23243 +f 32575/32575/23232 32590/32590/23243 32574/32574/23231 +f 32576/32576/23233 32592/32592/23245 32593/32593/23244 +f 32576/32576/23233 32593/32593/23244 32577/32577/23232 +f 32563/32563/23223 32579/32579/23235 32592/32592/23245 +f 32563/32563/23223 32592/32592/23245 32576/32576/23233 +f 32594/32594/23234 32595/32595/23246 32596/32596/23247 +f 32594/32594/23234 32596/32596/23247 32597/32597/23235 +f 32580/32580/23236 32598/32598/23248 32599/32599/23246 +f 32580/32580/23236 32599/32599/23246 32581/32581/23234 +f 32582/32582/23237 32600/32600/23249 32598/32598/23248 +f 32582/32582/23237 32598/32598/23248 32580/32580/23236 +f 32583/32583/23238 32601/32601/23250 32600/32600/23249 +f 32583/32583/23238 32600/32600/23249 32582/32582/23237 +f 32602/32602/23239 32603/32603/23251 32604/32604/23250 +f 32602/32602/23239 32604/32604/23250 32605/32605/23252 +f 32606/32606/23253 32607/32607/23254 32603/32603/23251 +f 32606/32606/23253 32603/32603/23251 32602/32602/23239 +f 32608/32608/23241 32609/32609/23255 32607/32607/23254 +f 32608/32608/23241 32607/32607/23254 32606/32606/23253 +f 32588/32588/23242 32610/32610/23256 32611/32611/23255 +f 32588/32588/23242 32611/32611/23255 32589/32589/23241 +f 32590/32590/23243 32612/32612/23257 32610/32610/23256 +f 32590/32590/23243 32610/32610/23256 32588/32588/23242 +f 32591/32591/23244 32613/32613/23258 32612/32612/23257 +f 32591/32591/23244 32612/32612/23257 32590/32590/23243 +f 32614/32614/23245 32615/32615/23259 32616/32616/23260 +f 32614/32614/23245 32616/32616/23260 32617/32617/23244 +f 32597/32597/23235 32596/32596/23247 32615/32615/23259 +f 32597/32597/23235 32615/32615/23259 32614/32614/23245 +f 32595/32595/23246 32618/32618/23261 32619/32619/23262 +f 32595/32595/23246 32619/32619/23262 32596/32596/23247 +f 32598/32598/23248 32620/32620/23263 32621/32621/23264 +f 32598/32598/23248 32621/32621/23264 32599/32599/23246 +f 32600/32600/23249 32622/32622/23265 32620/32620/23263 +f 32600/32600/23249 32620/32620/23263 32598/32598/23248 +f 32601/32601/23250 32623/32623/23266 32622/32622/23265 +f 32601/32601/23250 32622/32622/23265 32600/32600/23249 +f 32603/32603/23251 32624/32624/23267 32625/32625/23266 +f 32603/32603/23251 32625/32625/23266 32604/32604/23250 +f 32607/32607/23254 32626/32626/23268 32624/32624/23267 +f 32607/32607/23254 32624/32624/23267 32603/32603/23251 +f 32609/32609/23255 32627/32627/23269 32626/32626/23268 +f 32609/32609/23255 32626/32626/23268 32607/32607/23254 +f 32610/32610/23256 32628/32628/23270 32629/32629/23269 +f 32610/32610/23256 32629/32629/23269 32611/32611/23255 +f 32612/32612/23257 32630/32630/23271 32628/32628/23270 +f 32612/32612/23257 32628/32628/23270 32610/32610/23256 +f 32613/32613/23258 32631/32631/23272 32630/32630/23271 +f 32613/32613/23258 32630/32630/23271 32612/32612/23257 +f 32615/32615/23259 32632/32632/23273 32633/32633/23272 +f 32615/32615/23259 32633/32633/23272 32616/32616/23260 +f 32596/32596/23247 32619/32619/23262 32632/32632/23273 +f 32596/32596/23247 32632/32632/23273 32615/32615/23259 +f 32618/32618/23261 32634/32634/23274 32635/32635/23275 +f 32618/32618/23261 32635/32635/23275 32619/32619/23262 +f 32620/32620/23263 32636/32636/23276 32637/32637/23277 +f 32620/32620/23263 32637/32637/23277 32621/32621/23264 +f 32622/32622/23265 32638/32638/23278 32636/32636/23276 +f 32622/32622/23265 32636/32636/23276 32620/32620/23263 +f 32623/32623/23266 32639/32639/23279 32638/32638/23278 +f 32623/32623/23266 32638/32638/23278 32622/32622/23265 +f 32624/32624/23267 32640/32640/23280 32641/32641/23279 +f 32624/32624/23267 32641/32641/23279 32625/32625/23266 +f 32626/32626/23268 32642/32642/23281 32640/32640/23280 +f 32626/32626/23268 32640/32640/23280 32624/32624/23267 +f 32627/32627/23269 32643/32643/23282 32642/32642/23281 +f 32627/32627/23269 32642/32642/23281 32626/32626/23268 +f 32628/32628/23270 32644/32644/23283 32645/32645/23284 +f 32628/32628/23270 32645/32645/23284 32629/32629/23269 +f 32630/32630/23271 32646/32646/23285 32644/32644/23283 +f 32630/32630/23271 32644/32644/23283 32628/32628/23270 +f 32631/32631/23272 32647/32647/23286 32646/32646/23285 +f 32631/32631/23272 32646/32646/23285 32630/32630/23271 +f 32632/32632/23273 32648/32648/23287 32649/32649/23286 +f 32632/32632/23273 32649/32649/23286 32633/32633/23272 +f 32619/32619/23262 32635/32635/23275 32648/32648/23287 +f 32619/32619/23262 32648/32648/23287 32632/32632/23273 +f 32634/32634/23274 32650/32650/23288 32651/32651/23289 +f 32634/32634/23274 32651/32651/23289 32635/32635/23275 +f 32636/32636/23276 32652/32652/23290 32653/32653/23288 +f 32636/32636/23276 32653/32653/23288 32637/32637/23277 +f 32638/32638/23278 32654/32654/23291 32652/32652/23290 +f 32638/32638/23278 32652/32652/23290 32636/32636/23276 +f 32639/32639/23279 32655/32655/23292 32654/32654/23291 +f 32639/32639/23279 32654/32654/23291 32638/32638/23278 +f 32640/32640/23280 32656/32656/23293 32657/32657/23292 +f 32640/32640/23280 32657/32657/23292 32641/32641/23279 +f 32642/32642/23281 32658/32658/23294 32656/32656/23293 +f 32642/32642/23281 32656/32656/23293 32640/32640/23280 +f 32643/32643/23282 32659/32659/23295 32658/32658/23294 +f 32643/32643/23282 32658/32658/23294 32642/32642/23281 +f 32644/32644/23283 32660/32660/23296 32661/32661/23295 +f 32644/32644/23283 32661/32661/23295 32645/32645/23284 +f 32646/32646/23285 32662/32662/23297 32660/32660/23296 +f 32646/32646/23285 32660/32660/23296 32644/32644/23283 +f 32647/32647/23286 32663/32663/23298 32662/32662/23297 +f 32647/32647/23286 32662/32662/23297 32646/32646/23285 +f 32648/32648/23287 32664/32664/23299 32665/32665/23298 +f 32648/32648/23287 32665/32665/23298 32649/32649/23286 +f 32635/32635/23275 32651/32651/23289 32664/32664/23299 +f 32635/32635/23275 32664/32664/23299 32648/32648/23287 +f 32650/32650/23288 32666/32666/23300 32667/32667/23301 +f 32650/32650/23288 32667/32667/23301 32651/32651/23289 +f 32668/32668/23290 32669/32669/23302 32670/32670/23300 +f 32668/32668/23290 32670/32670/23300 32671/32671/23288 +f 32654/32654/23291 32672/32672/23303 32673/32673/23302 +f 32654/32654/23291 32673/32673/23302 32652/32652/23290 +f 32655/32655/23292 32674/32674/23304 32672/32672/23303 +f 32655/32655/23292 32672/32672/23303 32654/32654/23291 +f 32675/32675/23293 32676/32676/23305 32674/32674/23304 +f 32675/32675/23293 32674/32674/23304 32655/32655/23292 +f 32658/32658/23294 32677/32677/23306 32678/32678/23307 +f 32658/32658/23294 32678/32678/23307 32656/32656/23293 +f 32679/32679/23308 32680/32680/23309 32681/32681/23306 +f 32679/32679/23308 32681/32681/23306 32682/32682/23294 +f 32683/32683/23310 32684/32684/23311 32680/32680/23309 +f 32683/32683/23310 32680/32680/23309 32679/32679/23308 +f 32662/32662/23297 32685/32685/23312 32686/32686/23311 +f 32662/32662/23297 32686/32686/23311 32660/32660/23296 +f 32663/32663/23298 32687/32687/23313 32685/32685/23312 +f 32663/32663/23298 32685/32685/23312 32662/32662/23297 +f 32688/32688/23299 32689/32689/23314 32687/32687/23313 +f 32688/32688/23299 32687/32687/23313 32663/32663/23298 +f 32651/32651/23289 32667/32667/23301 32690/32690/23314 +f 32651/32651/23289 32690/32690/23314 32664/32664/23299 +f 32670/32670/23300 32691/32691/23315 32692/32692/23316 +f 32670/32670/23300 32692/32692/23316 32693/32693/23317 +f 32669/32669/23302 32694/32694/23318 32691/32691/23315 +f 32669/32669/23302 32691/32691/23315 32670/32670/23300 +f 32672/32672/23303 32695/32695/23319 32696/32696/23318 +f 32672/32672/23303 32696/32696/23318 32673/32673/23302 +f 32674/32674/23304 32697/32697/23320 32695/32695/23319 +f 32674/32674/23304 32695/32695/23319 32672/32672/23303 +f 32676/32676/23305 32698/32698/23321 32697/32697/23320 +f 32676/32676/23305 32697/32697/23320 32674/32674/23304 +f 32681/32681/23306 32699/32699/23322 32700/32700/23323 +f 32681/32681/23306 32700/32700/23323 32701/32701/23305 +f 32680/32680/23309 32702/32702/23324 32699/32699/23322 +f 32680/32680/23309 32699/32699/23322 32681/32681/23306 +f 32684/32684/23311 32703/32703/23325 32702/32702/23324 +f 32684/32684/23311 32702/32702/23324 32680/32680/23309 +f 32685/32685/23312 32704/32704/23326 32705/32705/23325 +f 32685/32685/23312 32705/32705/23325 32686/32686/23311 +f 32687/32687/23313 32706/32706/23327 32704/32704/23326 +f 32687/32687/23313 32704/32704/23326 32685/32685/23312 +f 32689/32689/23314 32707/32707/23328 32706/32706/23327 +f 32689/32689/23314 32706/32706/23327 32687/32687/23313 +f 32693/32693/23317 32692/32692/23316 32708/32708/23328 +f 32693/32693/23317 32708/32708/23328 32709/32709/23314 +f 32691/32691/23315 32710/32710/23329 32711/32711/23330 +f 32691/32691/23315 32711/32711/23330 32692/32692/23316 +f 32694/32694/23318 32712/32712/23331 32710/32710/23329 +f 32694/32694/23318 32710/32710/23329 32691/32691/23315 +f 32695/32695/23319 32713/32713/23332 32714/32714/23331 +f 32695/32695/23319 32714/32714/23331 32696/32696/23318 +f 32697/32697/23320 32715/32715/23333 32713/32713/23332 +f 32697/32697/23320 32713/32713/23332 32695/32695/23319 +f 32698/32698/23321 32716/32716/23334 32715/32715/23333 +f 32698/32698/23321 32715/32715/23333 32697/32697/23320 +f 32699/32699/23322 32717/32717/23335 32718/32718/23334 +f 32699/32699/23322 32718/32718/23334 32700/32700/23323 +f 32702/32702/23324 32719/32719/23336 32717/32717/23335 +f 32702/32702/23324 32717/32717/23335 32699/32699/23322 +f 32703/32703/23325 32720/32720/23337 32719/32719/23336 +f 32703/32703/23325 32719/32719/23336 32702/32702/23324 +f 32704/32704/23326 32721/32721/23338 32722/32722/23339 +f 32704/32704/23326 32722/32722/23339 32705/32705/23325 +f 32706/32706/23327 32723/32723/23340 32721/32721/23338 +f 32706/32706/23327 32721/32721/23338 32704/32704/23326 +f 32707/32707/23328 32724/32724/23341 32723/32723/23340 +f 32707/32707/23328 32723/32723/23340 32706/32706/23327 +f 32692/32692/23316 32711/32711/23330 32725/32725/23342 +f 32692/32692/23316 32725/32725/23342 32708/32708/23328 +f 32710/32710/23329 32726/32726/23343 32727/32727/23344 +f 32710/32710/23329 32727/32727/23344 32711/32711/23330 +f 32712/32712/23331 32728/32728/23345 32726/32726/23343 +f 32712/32712/23331 32726/32726/23343 32710/32710/23329 +f 32713/32713/23332 32729/32729/23346 32730/32730/23345 +f 32713/32713/23332 32730/32730/23345 32714/32714/23331 +f 32715/32715/23333 32731/32731/23347 32729/32729/23346 +f 32715/32715/23333 32729/32729/23346 32713/32713/23332 +f 32716/32716/23334 32732/32732/23348 32731/32731/23347 +f 32716/32716/23334 32731/32731/23347 32715/32715/23333 +f 32717/32717/23335 32733/32733/23349 32734/32734/23348 +f 32717/32717/23335 32734/32734/23348 32718/32718/23334 +f 32719/32719/23336 32735/32735/23350 32733/32733/23349 +f 32719/32719/23336 32733/32733/23349 32717/32717/23335 +f 32720/32720/23337 32736/32736/23351 32735/32735/23350 +f 32720/32720/23337 32735/32735/23350 32719/32719/23336 +f 32721/32721/23338 32737/32737/23352 32738/32738/23351 +f 32721/32721/23338 32738/32738/23351 32722/32722/23339 +f 32723/32723/23340 32739/32739/23353 32737/32737/23352 +f 32723/32723/23340 32737/32737/23352 32721/32721/23338 +f 32724/32724/23341 32740/32740/23354 32739/32739/23353 +f 32724/32724/23341 32739/32739/23353 32723/32723/23340 +f 32711/32711/23330 32727/32727/23344 32741/32741/23355 +f 32711/32711/23330 32741/32741/23355 32725/32725/23342 +f 32726/32726/23343 32742/32742/23356 32743/32743/23357 +f 32726/32726/23343 32743/32743/23357 32727/32727/23344 +f 32728/32728/23345 32744/32744/23358 32742/32742/23356 +f 32728/32728/23345 32742/32742/23356 32726/32726/23343 +f 32729/32729/23346 32745/32745/23359 32746/32746/23360 +f 32729/32729/23346 32746/32746/23360 32730/32730/23345 +f 32731/32731/23347 32747/32747/23361 32745/32745/23359 +f 32731/32731/23347 32745/32745/23359 32729/32729/23346 +f 32732/32732/23348 32748/32748/23362 32747/32747/23361 +f 32732/32732/23348 32747/32747/23361 32731/32731/23347 +f 32733/32733/23349 32749/32749/23363 32750/32750/23362 +f 32733/32733/23349 32750/32750/23362 32734/32734/23348 +f 32735/32735/23350 32751/32751/23364 32749/32749/23363 +f 32735/32735/23350 32749/32749/23363 32733/32733/23349 +f 32736/32736/23351 32752/32752/23365 32751/32751/23364 +f 32736/32736/23351 32751/32751/23364 32735/32735/23350 +f 32737/32737/23352 32753/32753/23366 32754/32754/23365 +f 32737/32737/23352 32754/32754/23365 32738/32738/23351 +f 32739/32739/23353 32755/32755/23367 32753/32753/23366 +f 32739/32739/23353 32753/32753/23366 32737/32737/23352 +f 32740/32740/23354 32756/32756/23368 32755/32755/23367 +f 32740/32740/23354 32755/32755/23367 32739/32739/23353 +f 32727/32727/23344 32743/32743/23357 32757/32757/23368 +f 32727/32727/23344 32757/32757/23368 32741/32741/23355 +f 32742/32742/23356 32758/32758/23369 32759/32759/23370 +f 32742/32742/23356 32759/32759/23370 32743/32743/23357 +f 32744/32744/23358 32760/32760/23371 32758/32758/23369 +f 32744/32744/23358 32758/32758/23369 32742/32742/23356 +f 32745/32745/23359 32761/32761/23372 32762/32762/23371 +f 32745/32745/23359 32762/32762/23371 32746/32746/23360 +f 32747/32747/23361 32763/32763/23373 32761/32761/23372 +f 32747/32747/23361 32761/32761/23372 32745/32745/23359 +f 32748/32748/23362 32764/32764/23374 32763/32763/23373 +f 32748/32748/23362 32763/32763/23373 32747/32747/23361 +f 32749/32749/23363 32765/32765/23375 32766/32766/23374 +f 32749/32749/23363 32766/32766/23374 32750/32750/23362 +f 32751/32751/23364 32767/32767/23376 32765/32765/23375 +f 32751/32751/23364 32765/32765/23375 32749/32749/23363 +f 32752/32752/23365 32768/32768/23377 32767/32767/23376 +f 32752/32752/23365 32767/32767/23376 32751/32751/23364 +f 32753/32753/23366 32769/32769/23378 32770/32770/23377 +f 32753/32753/23366 32770/32770/23377 32754/32754/23365 +f 32755/32755/23367 32771/32771/23379 32769/32769/23378 +f 32755/32755/23367 32769/32769/23378 32753/32753/23366 +f 32756/32756/23368 32772/32772/23380 32771/32771/23379 +f 32756/32756/23368 32771/32771/23379 32755/32755/23367 +f 32743/32743/23357 32759/32759/23370 32773/32773/23380 +f 32743/32743/23357 32773/32773/23380 32757/32757/23368 +f 32758/32758/23369 32774/32774/23381 32775/32775/23382 +f 32758/32758/23369 32775/32775/23382 32759/32759/23370 +f 32760/32760/23371 32776/32776/23383 32774/32774/23381 +f 32760/32760/23371 32774/32774/23381 32758/32758/23369 +f 32761/32761/23372 32777/32777/23384 32778/32778/23383 +f 32761/32761/23372 32778/32778/23383 32762/32762/23371 +f 32763/32763/23373 32779/32779/23385 32777/32777/23384 +f 32763/32763/23373 32777/32777/23384 32761/32761/23372 +f 32764/32764/23374 32780/32780/23386 32779/32779/23385 +f 32764/32764/23374 32779/32779/23385 32763/32763/23373 +f 32765/32765/23375 32781/32781/23387 32782/32782/23388 +f 32765/32765/23375 32782/32782/23388 32766/32766/23374 +f 32767/32767/23376 32783/32783/23389 32781/32781/23387 +f 32767/32767/23376 32781/32781/23387 32765/32765/23375 +f 32768/32768/23377 32784/32784/23390 32783/32783/23389 +f 32768/32768/23377 32783/32783/23389 32767/32767/23376 +f 32769/32769/23378 32785/32785/23391 32786/32786/23392 +f 32769/32769/23378 32786/32786/23392 32770/32770/23377 +f 32771/32771/23379 32787/32787/23393 32785/32785/23391 +f 32771/32771/23379 32785/32785/23391 32769/32769/23378 +f 32772/32772/23380 32788/32788/23394 32787/32787/23393 +f 32772/32772/23380 32787/32787/23393 32771/32771/23379 +f 32759/32759/23370 32775/32775/23382 32789/32789/23395 +f 32759/32759/23370 32789/32789/23395 32773/32773/23380 +f 32774/32774/23381 32790/32790/23396 32791/32791/23397 +f 32774/32774/23381 32791/32791/23397 32775/32775/23382 +f 32776/32776/23383 32792/32792/23398 32790/32790/23396 +f 32776/32776/23383 32790/32790/23396 32774/32774/23381 +f 32777/32777/23384 32793/32793/23399 32794/32794/23398 +f 32777/32777/23384 32794/32794/23398 32778/32778/23383 +f 32779/32779/23385 32795/32795/23400 32793/32793/23399 +f 32779/32779/23385 32793/32793/23399 32777/32777/23384 +f 32780/32780/23386 32796/32796/23401 32795/32795/23400 +f 32780/32780/23386 32795/32795/23400 32779/32779/23385 +f 32781/32781/23387 32797/32797/23402 32798/32798/23401 +f 32781/32781/23387 32798/32798/23401 32782/32782/23388 +f 32783/32783/23389 32799/32799/23403 32797/32797/23402 +f 32783/32783/23389 32797/32797/23402 32781/32781/23387 +f 32784/32784/23390 32800/32800/23404 32799/32799/23403 +f 32784/32784/23390 32799/32799/23403 32783/32783/23389 +f 32785/32785/23391 32801/32801/23405 32802/32802/23406 +f 32785/32785/23391 32802/32802/23406 32786/32786/23392 +f 32787/32787/23393 32803/32803/23407 32801/32801/23405 +f 32787/32787/23393 32801/32801/23405 32785/32785/23391 +f 32788/32788/23394 32804/32804/23408 32803/32803/23407 +f 32788/32788/23394 32803/32803/23407 32787/32787/23393 +f 32775/32775/23382 32791/32791/23397 32805/32805/23408 +f 32775/32775/23382 32805/32805/23408 32789/32789/23395 +f 32790/32790/23396 32806/32806/23409 32807/32807/23410 +f 32790/32790/23396 32807/32807/23410 32791/32791/23397 +f 32792/32792/23398 32808/32808/23411 32806/32806/23409 +f 32792/32792/23398 32806/32806/23409 32790/32790/23396 +f 32793/32793/23399 32809/32809/23412 32810/32810/23413 +f 32793/32793/23399 32810/32810/23413 32794/32794/23398 +f 32795/32795/23400 32811/32811/23414 32809/32809/23412 +f 32795/32795/23400 32809/32809/23412 32793/32793/23399 +f 32796/32796/23401 32812/32812/23415 32811/32811/23414 +f 32796/32796/23401 32811/32811/23414 32795/32795/23400 +f 32797/32797/23402 32813/32813/23416 32814/32814/23415 +f 32797/32797/23402 32814/32814/23415 32798/32798/23401 +f 32799/32799/23403 32815/32815/23417 32813/32813/23416 +f 32799/32799/23403 32813/32813/23416 32797/32797/23402 +f 32800/32800/23404 32816/32816/23418 32815/32815/23417 +f 32800/32800/23404 32815/32815/23417 32799/32799/23403 +f 32801/32801/23405 32817/32817/23419 32818/32818/23418 +f 32801/32801/23405 32818/32818/23418 32802/32802/23406 +f 32803/32803/23407 32819/32819/23420 32817/32817/23419 +f 32803/32803/23407 32817/32817/23419 32801/32801/23405 +f 32804/32804/23408 32820/32820/23421 32819/32819/23420 +f 32804/32804/23408 32819/32819/23420 32803/32803/23407 +f 32791/32791/23397 32807/32807/23410 32821/32821/23421 +f 32791/32791/23397 32821/32821/23421 32805/32805/23408 +f 32806/32806/23409 32822/32822/23422 32823/32823/23423 +f 32806/32806/23409 32823/32823/23423 32807/32807/23410 +f 32808/32808/23411 32824/32824/23424 32822/32822/23422 +f 32808/32808/23411 32822/32822/23422 32806/32806/23409 +f 32809/32809/23412 32825/32825/23425 32826/32826/23426 +f 32809/32809/23412 32826/32826/23426 32810/32810/23413 +f 32811/32811/23414 32827/32827/23427 32825/32825/23425 +f 32811/32811/23414 32825/32825/23425 32809/32809/23412 +f 32812/32812/23415 32828/32828/23428 32827/32827/23427 +f 32812/32812/23415 32827/32827/23427 32811/32811/23414 +f 32813/32813/23416 32829/32829/23429 32830/32830/23428 +f 32813/32813/23416 32830/32830/23428 32814/32814/23415 +f 32815/32815/23417 32831/32831/23430 32829/32829/23429 +f 32815/32815/23417 32829/32829/23429 32813/32813/23416 +f 32816/32816/23418 32832/32832/23431 32831/32831/23430 +f 32816/32816/23418 32831/32831/23430 32815/32815/23417 +f 32817/32817/23419 32833/32833/23432 32834/32834/23431 +f 32817/32817/23419 32834/32834/23431 32818/32818/23418 +f 32819/32819/23420 32835/32835/23433 32833/32833/23432 +f 32819/32819/23420 32833/32833/23432 32817/32817/23419 +f 32820/32820/23421 32836/32836/23434 32835/32835/23433 +f 32820/32820/23421 32835/32835/23433 32819/32819/23420 +f 32807/32807/23410 32823/32823/23423 32837/32837/23434 +f 32807/32807/23410 32837/32837/23434 32821/32821/23421 +f 32822/32822/23422 32838/32838/23435 32839/32839/23436 +f 32822/32822/23422 32839/32839/23436 32823/32823/23423 +f 32824/32824/23424 32840/32840/23437 32838/32838/23435 +f 32824/32824/23424 32838/32838/23435 32822/32822/23422 +f 32825/32825/23425 32841/32841/23438 32842/32842/23439 +f 32825/32825/23425 32842/32842/23439 32826/32826/23426 +f 32827/32827/23427 32843/32843/23440 32841/32841/23438 +f 32827/32827/23427 32841/32841/23438 32825/32825/23425 +f 32828/32828/23428 32844/32844/23441 32843/32843/23440 +f 32828/32828/23428 32843/32843/23440 32827/32827/23427 +f 32829/32829/23429 32845/32845/23442 32846/32846/23441 +f 32829/32829/23429 32846/32846/23441 32830/32830/23428 +f 32831/32831/23430 32847/32847/23443 32845/32845/23442 +f 32831/32831/23430 32845/32845/23442 32829/32829/23429 +f 32832/32832/23431 32848/32848/23444 32847/32847/23443 +f 32832/32832/23431 32847/32847/23443 32831/32831/23430 +f 32833/32833/23432 32849/32849/23445 32850/32850/23444 +f 32833/32833/23432 32850/32850/23444 32834/32834/23431 +f 32835/32835/23433 32851/32851/23446 32849/32849/23445 +f 32835/32835/23433 32849/32849/23445 32833/32833/23432 +f 32836/32836/23434 32852/32852/23447 32851/32851/23446 +f 32836/32836/23434 32851/32851/23446 32835/32835/23433 +f 32823/32823/23423 32839/32839/23436 32853/32853/23448 +f 32823/32823/23423 32853/32853/23448 32837/32837/23434 +f 32838/32838/23435 32854/32854/23449 32855/32855/23450 +f 32838/32838/23435 32855/32855/23450 32839/32839/23436 +f 32840/32840/23437 32856/32856/23451 32854/32854/23449 +f 32840/32840/23437 32854/32854/23449 32838/32838/23435 +f 32841/32841/23438 32857/32857/23452 32858/32858/23453 +f 32841/32841/23438 32858/32858/23453 32842/32842/23439 +f 32843/32843/23440 32859/32859/23454 32857/32857/23452 +f 32843/32843/23440 32857/32857/23452 32841/32841/23438 +f 32844/32844/23441 32860/32860/23455 32859/32859/23454 +f 32844/32844/23441 32859/32859/23454 32843/32843/23440 +f 32845/32845/23442 32861/32861/23456 32862/32862/23455 +f 32845/32845/23442 32862/32862/23455 32846/32846/23441 +f 32847/32847/23443 32863/32863/23457 32861/32861/23456 +f 32847/32847/23443 32861/32861/23456 32845/32845/23442 +f 32848/32848/23444 32864/32864/23458 32863/32863/23457 +f 32848/32848/23444 32863/32863/23457 32847/32847/23443 +f 32849/32849/23445 32865/32865/23459 32866/32866/23460 +f 32849/32849/23445 32866/32866/23460 32850/32850/23444 +f 32851/32851/23446 32867/32867/23461 32865/32865/23459 +f 32851/32851/23446 32865/32865/23459 32849/32849/23445 +f 32852/32852/23447 32868/32868/23462 32867/32867/23461 +f 32852/32852/23447 32867/32867/23461 32851/32851/23446 +f 32839/32839/23436 32855/32855/23450 32869/32869/23463 +f 32839/32839/23436 32869/32869/23463 32853/32853/23448 +f 32854/32854/23449 32870/32870/23464 32871/32871/23465 +f 32854/32854/23449 32871/32871/23465 32855/32855/23450 +f 32856/32856/23451 32872/32872/23466 32870/32870/23464 +f 32856/32856/23451 32870/32870/23464 32854/32854/23449 +f 32857/32857/23452 32873/32873/23467 32874/32874/23466 +f 32857/32857/23452 32874/32874/23466 32858/32858/23453 +f 32859/32859/23454 32875/32875/23468 32873/32873/23467 +f 32859/32859/23454 32873/32873/23467 32857/32857/23452 +f 32860/32860/23455 32876/32876/23469 32875/32875/23468 +f 32860/32860/23455 32875/32875/23468 32859/32859/23454 +f 32861/32861/23456 32877/32877/23470 32878/32878/23469 +f 32861/32861/23456 32878/32878/23469 32862/32862/23455 +f 32863/32863/23457 32879/32879/23471 32877/32877/23470 +f 32863/32863/23457 32877/32877/23470 32861/32861/23456 +f 32864/32864/23458 32880/32880/23472 32879/32879/23471 +f 32864/32864/23458 32879/32879/23471 32863/32863/23457 +f 32865/32865/23459 32881/32881/23473 32882/32882/23472 +f 32865/32865/23459 32882/32882/23472 32866/32866/23460 +f 32867/32867/23461 32883/32883/23474 32881/32881/23473 +f 32867/32867/23461 32881/32881/23473 32865/32865/23459 +f 32868/32868/23462 32884/32884/23475 32883/32883/23474 +f 32868/32868/23462 32883/32883/23474 32867/32867/23461 +f 32855/32855/23450 32871/32871/23465 32885/32885/23476 +f 32855/32855/23450 32885/32885/23476 32869/32869/23463 +f 32870/32870/23464 32886/32886/23477 32887/32887/23478 +f 32870/32870/23464 32887/32887/23478 32871/32871/23465 +f 32872/32872/23466 32888/32888/23479 32886/32886/23477 +f 32872/32872/23466 32886/32886/23477 32870/32870/23464 +f 32873/32873/23467 32889/32889/23480 32890/32890/23481 +f 32873/32873/23467 32890/32890/23481 32874/32874/23466 +f 32875/32875/23468 32891/32891/23482 32889/32889/23480 +f 32875/32875/23468 32889/32889/23480 32873/32873/23467 +f 32876/32876/23469 32892/32892/23483 32891/32891/23482 +f 32876/32876/23469 32891/32891/23482 32875/32875/23468 +f 32877/32877/23470 32893/32893/23484 32894/32894/23483 +f 32877/32877/23470 32894/32894/23483 32878/32878/23469 +f 32879/32879/23471 32895/32895/23485 32893/32893/23484 +f 32879/32879/23471 32893/32893/23484 32877/32877/23470 +f 32880/32880/23472 32896/32896/23486 32895/32895/23485 +f 32880/32880/23472 32895/32895/23485 32879/32879/23471 +f 32881/32881/23473 32897/32897/23487 32898/32898/23488 +f 32881/32881/23473 32898/32898/23488 32882/32882/23472 +f 32883/32883/23474 32899/32899/23489 32897/32897/23487 +f 32883/32883/23474 32897/32897/23487 32881/32881/23473 +f 32884/32884/23475 32900/32900/23490 32899/32899/23489 +f 32884/32884/23475 32899/32899/23489 32883/32883/23474 +f 32871/32871/23465 32887/32887/23478 32901/32901/23490 +f 32871/32871/23465 32901/32901/23490 32885/32885/23476 +f 32886/32886/23477 32902/32902/23491 32903/32903/23492 +f 32886/32886/23477 32903/32903/23492 32887/32887/23478 +f 32888/32888/23479 32904/32904/23493 32902/32902/23491 +f 32888/32888/23479 32902/32902/23491 32886/32886/23477 +f 32889/32889/23480 32905/32905/23494 32906/32906/23493 +f 32889/32889/23480 32906/32906/23493 32890/32890/23481 +f 32891/32891/23482 32907/32907/23495 32905/32905/23494 +f 32891/32891/23482 32905/32905/23494 32889/32889/23480 +f 32892/32892/23483 32908/32908/23496 32907/32907/23495 +f 32892/32892/23483 32907/32907/23495 32891/32891/23482 +f 32893/32893/23484 32909/32909/23497 32910/32910/23496 +f 32893/32893/23484 32910/32910/23496 32894/32894/23483 +f 32895/32895/23485 32911/32911/23498 32909/32909/23497 +f 32895/32895/23485 32909/32909/23497 32893/32893/23484 +f 32896/32896/23486 32912/32912/23499 32911/32911/23498 +f 32896/32896/23486 32911/32911/23498 32895/32895/23485 +f 32897/32897/23487 32913/32913/23500 32914/32914/23499 +f 32897/32897/23487 32914/32914/23499 32898/32898/23488 +f 32899/32899/23489 32915/32915/23501 32913/32913/23500 +f 32899/32899/23489 32913/32913/23500 32897/32897/23487 +f 32900/32900/23490 32916/32916/23502 32915/32915/23501 +f 32900/32900/23490 32915/32915/23501 32899/32899/23489 +f 32887/32887/23478 32903/32903/23492 32917/32917/23502 +f 32887/32887/23478 32917/32917/23502 32901/32901/23490 +f 32902/32902/23491 32918/32918/23503 32919/32919/23504 +f 32902/32902/23491 32919/32919/23504 32903/32903/23492 +f 32904/32904/23493 32920/32920/23505 32918/32918/23503 +f 32904/32904/23493 32918/32918/23503 32902/32902/23491 +f 32905/32905/23494 32921/32921/23506 32922/32922/23505 +f 32905/32905/23494 32922/32922/23505 32906/32906/23493 +f 32907/32907/23495 32923/32923/23507 32921/32921/23506 +f 32907/32907/23495 32921/32921/23506 32905/32905/23494 +f 32908/32908/23496 32924/32924/23508 32923/32923/23507 +f 32908/32908/23496 32923/32923/23507 32907/32907/23495 +f 32909/32909/23497 32925/32925/23509 32926/32926/23508 +f 32909/32909/23497 32926/32926/23508 32910/32910/23496 +f 32911/32911/23498 32927/32927/23510 32925/32925/23509 +f 32911/32911/23498 32925/32925/23509 32909/32909/23497 +f 32912/32912/23499 32928/32928/23511 32927/32927/23510 +f 32912/32912/23499 32927/32927/23510 32911/32911/23498 +f 32913/32913/23500 32929/32929/23512 32930/32930/23511 +f 32913/32913/23500 32930/32930/23511 32914/32914/23499 +f 32915/32915/23501 32931/32931/23513 32929/32929/23512 +f 32915/32915/23501 32929/32929/23512 32913/32913/23500 +f 32916/32916/23502 32932/32932/23514 32931/32931/23513 +f 32916/32916/23502 32931/32931/23513 32915/32915/23501 +f 32903/32903/23492 32919/32919/23504 32933/32933/23514 +f 32903/32903/23492 32933/32933/23514 32917/32917/23502 +f 32918/32918/23503 32934/32934/23515 32935/32935/23516 +f 32918/32918/23503 32935/32935/23516 32919/32919/23504 +f 32920/32920/23505 32936/32936/23517 32934/32934/23515 +f 32920/32920/23505 32934/32934/23515 32918/32918/23503 +f 32921/32921/23506 32937/32937/23518 32938/32938/23517 +f 32921/32921/23506 32938/32938/23517 32922/32922/23505 +f 32923/32923/23507 32939/32939/23519 32937/32937/23518 +f 32923/32923/23507 32937/32937/23518 32921/32921/23506 +f 32924/32924/23508 32940/32940/23520 32939/32939/23519 +f 32924/32924/23508 32939/32939/23519 32923/32923/23507 +f 32925/32925/23509 32941/32941/23521 32942/32942/23522 +f 32925/32925/23509 32942/32942/23522 32926/32926/23508 +f 32927/32927/23510 32943/32943/23523 32941/32941/23521 +f 32927/32927/23510 32941/32941/23521 32925/32925/23509 +f 32928/32928/23511 32944/32944/23524 32943/32943/23523 +f 32928/32928/23511 32943/32943/23523 32927/32927/23510 +f 32929/32929/23512 32945/32945/23525 32946/32946/23526 +f 32929/32929/23512 32946/32946/23526 32930/32930/23511 +f 32931/32931/23513 32947/32947/23527 32945/32945/23525 +f 32931/32931/23513 32945/32945/23525 32929/32929/23512 +f 32932/32932/23514 32948/32948/23528 32947/32947/23527 +f 32932/32932/23514 32947/32947/23527 32931/32931/23513 +f 32919/32919/23504 32935/32935/23516 32949/32949/23528 +f 32919/32919/23504 32949/32949/23528 32933/32933/23514 +f 32934/32934/23515 32950/32950/23529 32951/32951/23530 +f 32934/32934/23515 32951/32951/23530 32935/32935/23516 +f 32936/32936/23517 32952/32952/23531 32950/32950/23529 +f 32936/32936/23517 32950/32950/23529 32934/32934/23515 +f 32937/32937/23518 32953/32953/23532 32954/32954/23531 +f 32937/32937/23518 32954/32954/23531 32938/32938/23517 +f 32939/32939/23519 32955/32955/23533 32953/32953/23532 +f 32939/32939/23519 32953/32953/23532 32937/32937/23518 +f 32940/32940/23520 32956/32956/23534 32955/32955/23533 +f 32940/32940/23520 32955/32955/23533 32939/32939/23519 +f 32941/32941/23521 32957/32957/23535 32958/32958/23534 +f 32941/32941/23521 32958/32958/23534 32942/32942/23522 +f 32943/32943/23523 32959/32959/23536 32957/32957/23535 +f 32943/32943/23523 32957/32957/23535 32941/32941/23521 +f 32944/32944/23524 32960/32960/23537 32959/32959/23536 +f 32944/32944/23524 32959/32959/23536 32943/32943/23523 +f 32945/32945/23525 32961/32961/23538 32962/32962/23539 +f 32945/32945/23525 32962/32962/23539 32946/32946/23526 +f 32947/32947/23527 32963/32963/23540 32961/32961/23538 +f 32947/32947/23527 32961/32961/23538 32945/32945/23525 +f 32948/32948/23528 32964/32964/23541 32963/32963/23540 +f 32948/32948/23528 32963/32963/23540 32947/32947/23527 +f 32935/32935/23516 32951/32951/23530 32965/32965/23541 +f 32935/32935/23516 32965/32965/23541 32949/32949/23528 +f 32950/32950/23529 32966/32966/23542 32967/32967/23543 +f 32950/32950/23529 32967/32967/23543 32951/32951/23530 +f 32952/32952/23531 32968/32968/23544 32966/32966/23542 +f 32952/32952/23531 32966/32966/23542 32950/32950/23529 +f 32953/32953/23532 32969/32969/23545 32970/32970/23546 +f 32953/32953/23532 32970/32970/23546 32954/32954/23531 +f 32955/32955/23533 32971/32971/23547 32969/32969/23545 +f 32955/32955/23533 32969/32969/23545 32953/32953/23532 +f 32956/32956/23534 32972/32972/23548 32971/32971/23547 +f 32956/32956/23534 32971/32971/23547 32955/32955/23533 +f 32957/32957/23535 32973/32973/23549 32974/32974/23548 +f 32957/32957/23535 32974/32974/23548 32958/32958/23534 +f 32959/32959/23536 32975/32975/23550 32973/32973/23549 +f 32959/32959/23536 32973/32973/23549 32957/32957/23535 +f 32960/32960/23537 32976/32976/23551 32975/32975/23550 +f 32960/32960/23537 32975/32975/23550 32959/32959/23536 +f 32961/32961/23538 32977/32977/23552 32978/32978/23551 +f 32961/32961/23538 32978/32978/23551 32962/32962/23539 +f 32963/32963/23540 32979/32979/23553 32977/32977/23552 +f 32963/32963/23540 32977/32977/23552 32961/32961/23538 +f 32964/32964/23541 32980/32980/23554 32979/32979/23553 +f 32964/32964/23541 32979/32979/23553 32963/32963/23540 +f 32951/32951/23530 32967/32967/23543 32981/32981/23555 +f 32951/32951/23530 32981/32981/23555 32965/32965/23541 +f 32966/32966/23542 32982/32982/23556 32983/32983/23557 +f 32966/32966/23542 32983/32983/23557 32967/32967/23543 +f 32968/32968/23544 32984/32984/23558 32982/32982/23556 +f 32968/32968/23544 32982/32982/23556 32966/32966/23542 +f 32969/32969/23545 32985/32985/23559 32986/32986/23560 +f 32969/32969/23545 32986/32986/23560 32970/32970/23546 +f 32971/32971/23547 32987/32987/23561 32985/32985/23559 +f 32971/32971/23547 32985/32985/23559 32969/32969/23545 +f 32972/32972/23548 32988/32988/23562 32987/32987/23561 +f 32972/32972/23548 32987/32987/23561 32971/32971/23547 +f 32973/32973/23549 32989/32989/23563 32990/32990/23562 +f 32973/32973/23549 32990/32990/23562 32974/32974/23548 +f 32975/32975/23550 32991/32991/23564 32989/32989/23563 +f 32975/32975/23550 32989/32989/23563 32973/32973/23549 +f 32976/32976/23551 32992/32992/23565 32991/32991/23564 +f 32976/32976/23551 32991/32991/23564 32975/32975/23550 +f 32977/32977/23552 32993/32993/23566 32994/32994/23567 +f 32977/32977/23552 32994/32994/23567 32978/32978/23551 +f 32979/32979/23553 32995/32995/23568 32993/32993/23566 +f 32979/32979/23553 32993/32993/23566 32977/32977/23552 +f 32980/32980/23554 32996/32996/23569 32995/32995/23568 +f 32980/32980/23554 32995/32995/23568 32979/32979/23553 +f 32967/32967/23543 32983/32983/23557 32997/32997/23570 +f 32967/32967/23543 32997/32997/23570 32981/32981/23555 +f 32982/32982/23556 32998/32998/23571 32999/32999/23572 +f 32982/32982/23556 32999/32999/23572 32983/32983/23557 +f 32984/32984/23558 33000/33000/23573 32998/32998/23571 +f 32984/32984/23558 32998/32998/23571 32982/32982/23556 +f 32985/32985/23559 33001/33001/23574 33002/33002/23573 +f 32985/32985/23559 33002/33002/23573 32986/32986/23560 +f 32987/32987/23561 33003/33003/23575 33001/33001/23574 +f 32987/32987/23561 33001/33001/23574 32985/32985/23559 +f 32988/32988/23562 33004/33004/23576 33003/33003/23575 +f 32988/32988/23562 33003/33003/23575 32987/32987/23561 +f 32989/32989/23563 33005/33005/23577 33006/33006/23576 +f 32989/32989/23563 33006/33006/23576 32990/32990/23562 +f 32991/32991/23564 33007/33007/23578 33005/33005/23577 +f 32991/32991/23564 33005/33005/23577 32989/32989/23563 +f 32992/32992/23565 33008/33008/23579 33007/33007/23578 +f 32992/32992/23565 33007/33007/23578 32991/32991/23564 +f 32993/32993/23566 33009/33009/23580 33010/33010/23579 +f 32993/32993/23566 33010/33010/23579 32994/32994/23567 +f 32995/32995/23568 33011/33011/23581 33009/33009/23580 +f 32995/32995/23568 33009/33009/23580 32993/32993/23566 +f 32996/32996/23569 33012/33012/23582 33011/33011/23581 +f 32996/32996/23569 33011/33011/23581 32995/32995/23568 +f 32983/32983/23557 32999/32999/23572 33013/33013/23583 +f 32983/32983/23557 33013/33013/23583 32997/32997/23570 +f 32998/32998/23571 33014/33014/23584 33015/33015/23585 +f 32998/32998/23571 33015/33015/23585 32999/32999/23572 +f 33000/33000/23573 33016/33016/23586 33014/33014/23584 +f 33000/33000/23573 33014/33014/23584 32998/32998/23571 +f 33001/33001/23574 33017/33017/23587 33018/33018/23586 +f 33001/33001/23574 33018/33018/23586 33002/33002/23573 +f 33003/33003/23575 33019/33019/23588 33017/33017/23587 +f 33003/33003/23575 33017/33017/23587 33001/33001/23574 +f 33004/33004/23576 33020/33020/23589 33019/33019/23588 +f 33004/33004/23576 33019/33019/23588 33003/33003/23575 +f 33021/33021/23577 33022/33022/23590 33023/33023/23589 +f 33021/33021/23577 33023/33023/23589 33024/33024/23591 +f 33007/33007/23578 33025/33025/23592 33026/33026/23590 +f 33007/33007/23578 33026/33026/23590 33005/33005/23577 +f 33008/33008/23579 33027/33027/23593 33025/33025/23592 +f 33008/33008/23579 33025/33025/23592 33007/33007/23578 +f 33009/33009/23580 33028/33028/23594 33029/33029/23593 +f 33009/33009/23580 33029/33029/23593 33010/33010/23579 +f 33011/33011/23581 33030/33030/23595 33028/33028/23594 +f 33011/33011/23581 33028/33028/23594 33009/33009/23580 +f 33012/33012/23582 33031/33031/23596 33030/33030/23595 +f 33012/33012/23582 33030/33030/23595 33011/33011/23581 +f 33032/33032/23597 33033/33033/23585 33034/33034/23596 +f 33032/33032/23597 33034/33034/23596 33035/33035/23582 +f 33036/33036/23584 33037/33037/23598 33038/33038/23599 +f 33036/33036/23584 33038/33038/23599 33033/33033/23585 +f 33016/33016/23586 33039/33039/23600 33040/33040/23598 +f 33016/33016/23586 33040/33040/23598 33014/33014/23584 +f 33017/33017/23587 33041/33041/23601 33042/33042/23600 +f 33017/33017/23587 33042/33042/23600 33018/33018/23586 +f 33019/33019/23588 33043/33043/23602 33041/33041/23601 +f 33019/33019/23588 33041/33041/23601 33017/33017/23587 +f 33023/33023/23589 33044/33044/23603 33045/33045/23602 +f 33023/33023/23589 33045/33045/23602 33046/33046/23604 +f 33022/33022/23590 33047/33047/23605 33044/33044/23603 +f 33022/33022/23590 33044/33044/23603 33023/33023/23589 +f 33025/33025/23592 33048/33048/23606 33049/33049/23605 +f 33025/33025/23592 33049/33049/23605 33026/33026/23590 +f 33027/33027/23593 33050/33050/23607 33048/33048/23606 +f 33027/33027/23593 33048/33048/23606 33025/33025/23592 +f 33028/33028/23594 33051/33051/23608 33052/33052/23609 +f 33028/33028/23594 33052/33052/23609 33029/33029/23593 +f 33030/33030/23595 33053/33053/23610 33051/33051/23608 +f 33030/33030/23595 33051/33051/23608 33028/33028/23594 +f 33034/33034/23596 33054/33054/23611 33055/33055/23610 +f 33034/33034/23596 33055/33055/23610 33056/33056/23612 +f 33033/33033/23585 33038/33038/23599 33054/33054/23611 +f 33033/33033/23585 33054/33054/23611 33034/33034/23596 +f 33037/33037/23598 33057/33057/23613 33058/33058/23614 +f 33037/33037/23598 33058/33058/23614 33038/33038/23599 +f 33042/33042/23600 33059/33059/23615 33060/33060/23613 +f 33042/33042/23600 33060/33060/23613 33061/33061/23616 +f 33041/33041/23601 33062/33062/23617 33059/33059/23615 +f 33041/33041/23601 33059/33059/23615 33042/33042/23600 +f 33043/33043/23602 33063/33063/23618 33062/33062/23617 +f 33043/33043/23602 33062/33062/23617 33041/33041/23601 +f 33044/33044/23603 33064/33064/23619 33065/33065/23618 +f 33044/33044/23603 33065/33065/23618 33045/33045/23602 +f 33047/33047/23605 33066/33066/23620 33064/33064/23619 +f 33047/33047/23605 33064/33064/23619 33044/33044/23603 +f 33067/33067/23606 33068/33068/23621 33066/33066/23620 +f 33067/33067/23606 33066/33066/23620 33047/33047/23605 +f 33052/33052/23609 33069/33069/23622 33070/33070/23623 +f 33052/33052/23609 33070/33070/23623 33071/33071/23624 +f 33051/33051/23608 33072/33072/23625 33069/33069/23622 +f 33051/33051/23608 33069/33069/23622 33052/33052/23609 +f 33053/33053/23610 33073/33073/23626 33072/33072/23625 +f 33053/33053/23610 33072/33072/23625 33051/33051/23608 +f 33054/33054/23611 33074/33074/23627 33075/33075/23626 +f 33054/33054/23611 33075/33075/23626 33055/33055/23610 +f 33038/33038/23599 33058/33058/23614 33074/33074/23627 +f 33038/33038/23599 33074/33074/23627 33054/33054/23611 +f 33057/33057/23613 33076/33076/23628 33077/33077/23629 +f 33057/33057/23613 33077/33077/23629 33058/33058/23614 +f 33059/33059/23615 33078/33078/23630 33079/33079/23631 +f 33059/33059/23615 33079/33079/23631 33060/33060/23613 +f 33062/33062/23617 33080/33080/23632 33078/33078/23630 +f 33062/33062/23617 33078/33078/23630 33059/33059/23615 +f 33063/33063/23618 33081/33081/23633 33080/33080/23632 +f 33063/33063/23618 33080/33080/23632 33062/33062/23617 +f 33064/33064/23619 33082/33082/23634 33083/33083/23635 +f 33064/33064/23619 33083/33083/23635 33065/33065/23618 +f 33066/33066/23620 33084/33084/23636 33082/33082/23634 +f 33066/33066/23620 33082/33082/23634 33064/33064/23619 +f 33068/33068/23621 33085/33085/23637 33084/33084/23636 +f 33068/33068/23621 33084/33084/23636 33066/33066/23620 +f 33069/33069/23622 33086/33086/23638 33087/33087/23637 +f 33069/33069/23622 33087/33087/23637 33070/33070/23623 +f 33072/33072/23625 33088/33088/23639 33086/33086/23638 +f 33072/33072/23625 33086/33086/23638 33069/33069/23622 +f 33073/33073/23626 33089/33089/23640 33088/33088/23639 +f 33073/33073/23626 33088/33088/23639 33072/33072/23625 +f 33074/33074/23627 33090/33090/23641 33091/33091/23640 +f 33074/33074/23627 33091/33091/23640 33075/33075/23626 +f 33058/33058/23614 33077/33077/23629 33090/33090/23641 +f 33058/33058/23614 33090/33090/23641 33074/33074/23627 +f 33076/33076/23628 33092/33092/23642 33093/33093/23643 +f 33076/33076/23628 33093/33093/23643 33077/33077/23629 +f 33078/33078/23630 33094/33094/23644 33095/33095/23642 +f 33078/33078/23630 33095/33095/23642 33079/33079/23631 +f 33080/33080/23632 33096/33096/23645 33094/33094/23644 +f 33080/33080/23632 33094/33094/23644 33078/33078/23630 +f 33081/33081/23633 33097/33097/23646 33096/33096/23645 +f 33081/33081/23633 33096/33096/23645 33080/33080/23632 +f 33082/33082/23634 33098/33098/23647 33099/33099/23648 +f 33082/33082/23634 33099/33099/23648 33083/33083/23635 +f 33084/33084/23636 33100/33100/23649 33098/33098/23647 +f 33084/33084/23636 33098/33098/23647 33082/33082/23634 +f 33085/33085/23637 33101/33101/23650 33100/33100/23649 +f 33085/33085/23637 33100/33100/23649 33084/33084/23636 +f 33086/33086/23638 33102/33102/23651 33103/33103/23650 +f 33086/33086/23638 33103/33103/23650 33087/33087/23637 +f 33088/33088/23639 33104/33104/23652 33102/33102/23651 +f 33088/33088/23639 33102/33102/23651 33086/33086/23638 +f 33089/33089/23640 33105/33105/23653 33104/33104/23652 +f 33089/33089/23640 33104/33104/23652 33088/33088/23639 +f 33090/33090/23641 33106/33106/23654 33107/33107/23653 +f 33090/33090/23641 33107/33107/23653 33091/33091/23640 +f 33077/33077/23629 33093/33093/23643 33106/33106/23654 +f 33077/33077/23629 33106/33106/23654 33090/33090/23641 +f 33092/33092/23642 33108/33108/23655 33109/33109/23656 +f 33092/33092/23642 33109/33109/23656 33093/33093/23643 +f 33094/33094/23644 33110/33110/23657 33111/33111/23655 +f 33094/33094/23644 33111/33111/23655 33095/33095/23642 +f 33096/33096/23645 33112/33112/23658 33110/33110/23657 +f 33096/33096/23645 33110/33110/23657 33094/33094/23644 +f 33097/33097/23646 33113/33113/23659 33112/33112/23658 +f 33097/33097/23646 33112/33112/23658 33096/33096/23645 +f 33098/33098/23647 33114/33114/23660 33115/33115/23659 +f 33098/33098/23647 33115/33115/23659 33099/33099/23648 +f 33100/33100/23649 33116/33116/23661 33114/33114/23660 +f 33100/33100/23649 33114/33114/23660 33098/33098/23647 +f 33101/33101/23650 33117/33117/23662 33116/33116/23661 +f 33101/33101/23650 33116/33116/23661 33100/33100/23649 +f 33102/33102/23651 33118/33118/23663 33119/33119/23662 +f 33102/33102/23651 33119/33119/23662 33103/33103/23650 +f 33104/33104/23652 33120/33120/23664 33118/33118/23663 +f 33104/33104/23652 33118/33118/23663 33102/33102/23651 +f 33105/33105/23653 33121/33121/23665 33120/33120/23664 +f 33105/33105/23653 33120/33120/23664 33104/33104/23652 +f 33106/33106/23654 33122/33122/23666 33123/33123/23667 +f 33106/33106/23654 33123/33123/23667 33107/33107/23653 +f 33093/33093/23643 33109/33109/23656 33122/33122/23666 +f 33093/33093/23643 33122/33122/23666 33106/33106/23654 +f 33111/33111/23655 33124/33124/23668 33125/33125/23669 +f 33111/33111/23655 33125/33125/23669 33126/33126/23656 +f 33110/33110/23657 33127/33127/23670 33124/33124/23668 +f 33110/33110/23657 33124/33124/23668 33111/33111/23655 +f 33112/33112/23658 33128/33128/23671 33127/33127/23670 +f 33112/33112/23658 33127/33127/23670 33110/33110/23657 +f 33113/33113/23659 33129/33129/23672 33128/33128/23671 +f 33113/33113/23659 33128/33128/23671 33112/33112/23658 +f 33114/33114/23660 33130/33130/23673 33131/33131/23674 +f 33114/33114/23660 33131/33131/23674 33115/33115/23659 +f 33116/33116/23661 33132/33132/23675 33130/33130/23673 +f 33116/33116/23661 33130/33130/23673 33114/33114/23660 +f 33119/33119/23662 33133/33133/23676 33134/33134/23675 +f 33119/33119/23662 33134/33134/23675 33135/33135/23677 +f 33118/33118/23663 33136/33136/23678 33133/33133/23676 +f 33118/33118/23663 33133/33133/23676 33119/33119/23662 +f 33120/33120/23664 33137/33137/23679 33136/33136/23678 +f 33120/33120/23664 33136/33136/23678 33118/33118/23663 +f 33121/33121/23665 33138/33138/23680 33137/33137/23679 +f 33121/33121/23665 33137/33137/23679 33120/33120/23664 +f 33122/33122/23666 33139/33139/23681 33140/33140/23680 +f 33122/33122/23666 33140/33140/23680 33123/33123/23667 +f 33109/33109/23656 33141/33141/23669 33139/33139/23681 +f 33109/33109/23656 33139/33139/23681 33122/33122/23666 +f 33124/33124/23668 33142/33142/23682 33143/33143/23683 +f 33124/33124/23668 33143/33143/23683 33125/33125/23669 +f 33127/33127/23670 33144/33144/23684 33142/33142/23682 +f 33127/33127/23670 33142/33142/23682 33124/33124/23668 +f 33128/33128/23671 33145/33145/23685 33144/33144/23684 +f 33128/33128/23671 33144/33144/23684 33127/33127/23670 +f 33146/33146/23672 33147/33147/23686 33148/33148/23685 +f 33146/33146/23672 33148/33148/23685 33149/33149/23687 +f 33130/33130/23673 33150/33150/23688 33151/33151/23686 +f 33130/33130/23673 33151/33151/23686 33131/33131/23674 +f 33132/33132/23675 33152/33152/23689 33150/33150/23688 +f 33132/33132/23675 33150/33150/23688 33130/33130/23673 +f 33133/33133/23676 33153/33153/23690 33154/33154/23691 +f 33133/33133/23676 33154/33154/23691 33134/33134/23675 +f 33136/33136/23678 33155/33155/23692 33153/33153/23690 +f 33136/33136/23678 33153/33153/23690 33133/33133/23676 +f 33137/33137/23679 33156/33156/23693 33155/33155/23692 +f 33137/33137/23679 33155/33155/23692 33136/33136/23678 +f 33157/33157/23680 33158/33158/23694 33159/33159/23695 +f 33157/33157/23680 33159/33159/23695 33160/33160/23679 +f 33139/33139/23681 33161/33161/23696 33162/33162/23694 +f 33139/33139/23681 33162/33162/23694 33140/33140/23680 +f 33141/33141/23669 33163/33163/23683 33161/33161/23696 +f 33141/33141/23669 33161/33161/23696 33139/33139/23681 +f 33142/33142/23682 33164/33164/23697 33165/33165/23698 +f 33142/33142/23682 33165/33165/23698 33143/33143/23683 +f 33144/33144/23684 33166/33166/23699 33164/33164/23697 +f 33144/33144/23684 33164/33164/23697 33142/33142/23682 +f 33145/33145/23685 33167/33167/23700 33166/33166/23699 +f 33145/33145/23685 33166/33166/23699 33144/33144/23684 +f 33147/33147/23686 33168/33168/23701 33169/33169/23702 +f 33147/33147/23686 33169/33169/23702 33148/33148/23685 +f 33170/33170/23688 33171/33171/23703 33168/33168/23701 +f 33170/33170/23688 33168/33168/23701 33147/33147/23686 +f 33172/33172/23689 33173/33173/23704 33171/33171/23703 +f 33172/33172/23689 33171/33171/23703 33170/33170/23688 +f 33153/33153/23690 33174/33174/23705 33175/33175/23704 +f 33153/33153/23690 33175/33175/23704 33154/33154/23691 +f 33155/33155/23692 33176/33176/23706 33174/33174/23705 +f 33155/33155/23692 33174/33174/23705 33153/33153/23690 +f 33156/33156/23693 33177/33177/23707 33176/33176/23706 +f 33156/33156/23693 33176/33176/23706 33155/33155/23692 +f 33158/33158/23694 33178/33178/23708 33179/33179/23707 +f 33158/33158/23694 33179/33179/23707 33159/33159/23695 +f 33180/33180/23696 33181/33181/23709 33178/33178/23708 +f 33180/33180/23696 33178/33178/23708 33158/33158/23694 +f 33182/33182/23683 33183/33183/23698 33181/33181/23709 +f 33182/33182/23683 33181/33181/23709 33180/33180/23696 +f 33164/33164/23697 33184/33184/23710 33185/33185/23711 +f 33164/33164/23697 33185/33185/23711 33165/33165/23698 +f 33166/33166/23699 33186/33186/23712 33184/33184/23710 +f 33166/33166/23699 33184/33184/23710 33164/33164/23697 +f 33167/33167/23700 33187/33187/23713 33186/33186/23712 +f 33167/33167/23700 33186/33186/23712 33166/33166/23699 +f 33168/33168/23701 33188/33188/23714 33189/33189/23713 +f 33168/33168/23701 33189/33189/23713 33169/33169/23702 +f 33171/33171/23703 33190/33190/23715 33188/33188/23714 +f 33171/33171/23703 33188/33188/23714 33168/33168/23701 +f 33173/33173/23704 33191/33191/23716 33190/33190/23715 +f 33173/33173/23704 33190/33190/23715 33171/33171/23703 +f 33174/33174/23705 33192/33192/23717 33193/33193/23718 +f 33174/33174/23705 33193/33193/23718 33175/33175/23704 +f 33176/33176/23706 33194/33194/23719 33192/33192/23717 +f 33176/33176/23706 33192/33192/23717 33174/33174/23705 +f 33177/33177/23707 33195/33195/23720 33194/33194/23719 +f 33177/33177/23707 33194/33194/23719 33176/33176/23706 +f 33178/33178/23708 33196/33196/23721 33197/33197/23720 +f 33178/33178/23708 33197/33197/23720 33179/33179/23707 +f 33181/33181/23709 33198/33198/23722 33196/33196/23721 +f 33181/33181/23709 33196/33196/23721 33178/33178/23708 +f 33183/33183/23698 33199/33199/23711 33198/33198/23722 +f 33183/33183/23698 33198/33198/23722 33181/33181/23709 +f 33184/33184/23710 33200/33200/23723 33201/33201/23724 +f 33184/33184/23710 33201/33201/23724 33185/33185/23711 +f 33186/33186/23712 33202/33202/23725 33200/33200/23723 +f 33186/33186/23712 33200/33200/23723 33184/33184/23710 +f 33187/33187/23713 33203/33203/23726 33202/33202/23725 +f 33187/33187/23713 33202/33202/23725 33186/33186/23712 +f 33188/33188/23714 33204/33204/23727 33205/33205/23728 +f 33188/33188/23714 33205/33205/23728 33189/33189/23713 +f 33190/33190/23715 33206/33206/23729 33204/33204/23727 +f 33190/33190/23715 33204/33204/23727 33188/33188/23714 +f 33191/33191/23716 33207/33207/23730 33206/33206/23729 +f 33191/33191/23716 33206/33206/23729 33190/33190/23715 +f 33192/33192/23717 33208/33208/23731 33209/33209/23730 +f 33192/33192/23717 33209/33209/23730 33193/33193/23718 +f 33194/33194/23719 33210/33210/23732 33208/33208/23731 +f 33194/33194/23719 33208/33208/23731 33192/33192/23717 +f 33195/33195/23720 33211/33211/23733 33210/33210/23732 +f 33195/33195/23720 33210/33210/23732 33194/33194/23719 +f 33196/33196/23721 33212/33212/23734 33213/33213/23733 +f 33196/33196/23721 33213/33213/23733 33197/33197/23720 +f 33198/33198/23722 33214/33214/23735 33212/33212/23734 +f 33198/33198/23722 33212/33212/23734 33196/33196/23721 +f 33199/33199/23711 33215/33215/23724 33214/33214/23735 +f 33199/33199/23711 33214/33214/23735 33198/33198/23722 +f 33200/33200/23723 33216/33216/23736 33217/33217/23737 +f 33200/33200/23723 33217/33217/23737 33201/33201/23724 +f 33202/33202/23725 33218/33218/23738 33216/33216/23736 +f 33202/33202/23725 33216/33216/23736 33200/33200/23723 +f 33203/33203/23726 33219/33219/23739 33218/33218/23738 +f 33203/33203/23726 33218/33218/23738 33202/33202/23725 +f 33204/33204/23727 33220/33220/23740 33221/33221/23739 +f 33204/33204/23727 33221/33221/23739 33205/33205/23728 +f 33206/33206/23729 33222/33222/23741 33220/33220/23740 +f 33206/33206/23729 33220/33220/23740 33204/33204/23727 +f 33207/33207/23730 33223/33223/23742 33222/33222/23741 +f 33207/33207/23730 33222/33222/23741 33206/33206/23729 +f 33208/33208/23731 33224/33224/23743 33225/33225/23744 +f 33208/33208/23731 33225/33225/23744 33209/33209/23730 +f 33210/33210/23732 33226/33226/23745 33224/33224/23743 +f 33210/33210/23732 33224/33224/23743 33208/33208/23731 +f 33211/33211/23733 33227/33227/23746 33226/33226/23745 +f 33211/33211/23733 33226/33226/23745 33210/33210/23732 +f 33212/33212/23734 33228/33228/23747 33229/33229/23746 +f 33212/33212/23734 33229/33229/23746 33213/33213/23733 +f 33214/33214/23735 33230/33230/23748 33228/33228/23747 +f 33214/33214/23735 33228/33228/23747 33212/33212/23734 +f 33215/33215/23724 33231/33231/23749 33230/33230/23748 +f 33215/33215/23724 33230/33230/23748 33214/33214/23735 +f 33216/33216/23736 33232/33232/23750 33233/33233/23751 +f 33216/33216/23736 33233/33233/23751 33217/33217/23737 +f 33218/33218/23738 33234/33234/23752 33232/33232/23750 +f 33218/33218/23738 33232/33232/23750 33216/33216/23736 +f 33219/33219/23739 33235/33235/23753 33234/33234/23752 +f 33219/33219/23739 33234/33234/23752 33218/33218/23738 +f 33220/33220/23740 33236/33236/23754 33237/33237/23755 +f 33220/33220/23740 33237/33237/23755 33221/33221/23739 +f 33222/33222/23741 33238/33238/23756 33236/33236/23754 +f 33222/33222/23741 33236/33236/23754 33220/33220/23740 +f 33223/33223/23742 33239/33239/23757 33238/33238/23756 +f 33223/33223/23742 33238/33238/23756 33222/33222/23741 +f 33224/33224/23743 33240/33240/23758 33241/33241/23757 +f 33224/33224/23743 33241/33241/23757 33225/33225/23744 +f 33226/33226/23745 33242/33242/23759 33240/33240/23758 +f 33226/33226/23745 33240/33240/23758 33224/33224/23743 +f 33227/33227/23746 33243/33243/23760 33242/33242/23759 +f 33227/33227/23746 33242/33242/23759 33226/33226/23745 +f 33228/33228/23747 33244/33244/23761 33245/33245/23760 +f 33228/33228/23747 33245/33245/23760 33229/33229/23746 +f 33230/33230/23748 33246/33246/23762 33244/33244/23761 +f 33230/33230/23748 33244/33244/23761 33228/33228/23747 +f 33231/33231/23749 33247/33247/23751 33246/33246/23762 +f 33231/33231/23749 33246/33246/23762 33230/33230/23748 +f 33232/33232/23750 33248/33248/23763 33249/33249/23764 +f 33232/33232/23750 33249/33249/23764 33233/33233/23751 +f 33234/33234/23752 33250/33250/23765 33248/33248/23763 +f 33234/33234/23752 33248/33248/23763 33232/33232/23750 +f 33235/33235/23753 33251/33251/23766 33250/33250/23765 +f 33235/33235/23753 33250/33250/23765 33234/33234/23752 +f 33236/33236/23754 33252/33252/23767 33253/33253/23768 +f 33236/33236/23754 33253/33253/23768 33237/33237/23755 +f 33238/33238/23756 33254/33254/23769 33252/33252/23767 +f 33238/33238/23756 33252/33252/23767 33236/33236/23754 +f 33239/33239/23757 33255/33255/23770 33254/33254/23769 +f 33239/33239/23757 33254/33254/23769 33238/33238/23756 +f 33240/33240/23758 33256/33256/23771 33257/33257/23772 +f 33240/33240/23758 33257/33257/23772 33241/33241/23757 +f 33242/33242/23759 33258/33258/23773 33256/33256/23771 +f 33242/33242/23759 33256/33256/23771 33240/33240/23758 +f 33243/33243/23760 33259/33259/23774 33258/33258/23773 +f 33243/33243/23760 33258/33258/23773 33242/33242/23759 +f 33244/33244/23761 33260/33260/23775 33261/33261/23774 +f 33244/33244/23761 33261/33261/23774 33245/33245/23760 +f 33246/33246/23762 33262/33262/23776 33260/33260/23775 +f 33246/33246/23762 33260/33260/23775 33244/33244/23761 +f 33247/33247/23751 33263/33263/23764 33262/33262/23776 +f 33247/33247/23751 33262/33262/23776 33246/33246/23762 +f 33248/33248/23763 33264/33264/23777 33265/33265/23778 +f 33248/33248/23763 33265/33265/23778 33249/33249/23764 +f 33250/33250/23765 33266/33266/23779 33264/33264/23777 +f 33250/33250/23765 33264/33264/23777 33248/33248/23763 +f 33251/33251/23766 33267/33267/23780 33266/33266/23779 +f 33251/33251/23766 33266/33266/23779 33250/33250/23765 +f 33252/33252/23767 33268/33268/23781 33269/33269/23780 +f 33252/33252/23767 33269/33269/23780 33253/33253/23768 +f 33254/33254/23769 33270/33270/23782 33268/33268/23781 +f 33254/33254/23769 33268/33268/23781 33252/33252/23767 +f 33255/33255/23770 33271/33271/23783 33270/33270/23782 +f 33255/33255/23770 33270/33270/23782 33254/33254/23769 +f 33256/33256/23771 33272/33272/23784 33273/33273/23783 +f 33256/33256/23771 33273/33273/23783 33257/33257/23772 +f 33258/33258/23773 33274/33274/23785 33272/33272/23784 +f 33258/33258/23773 33272/33272/23784 33256/33256/23771 +f 33259/33259/23774 33275/33275/23786 33274/33274/23785 +f 33259/33259/23774 33274/33274/23785 33258/33258/23773 +f 33260/33260/23775 33276/33276/23787 33277/33277/23786 +f 33260/33260/23775 33277/33277/23786 33261/33261/23774 +f 33262/33262/23776 33278/33278/23788 33276/33276/23787 +f 33262/33262/23776 33276/33276/23787 33260/33260/23775 +f 33263/33263/23764 33279/33279/23778 33278/33278/23788 +f 33263/33263/23764 33278/33278/23788 33262/33262/23776 +f 33264/33264/23777 33280/33280/23789 33281/33281/23790 +f 33264/33264/23777 33281/33281/23790 33265/33265/23778 +f 33266/33266/23779 33282/33282/23791 33280/33280/23789 +f 33266/33266/23779 33280/33280/23789 33264/33264/23777 +f 33267/33267/23780 33283/33283/23792 33282/33282/23791 +f 33267/33267/23780 33282/33282/23791 33266/33266/23779 +f 33268/33268/23781 33284/33284/23793 33285/33285/23792 +f 33268/33268/23781 33285/33285/23792 33269/33269/23780 +f 33270/33270/23782 33286/33286/23794 33284/33284/23793 +f 33270/33270/23782 33284/33284/23793 33268/33268/23781 +f 33271/33271/23783 33287/33287/23795 33286/33286/23794 +f 33271/33271/23783 33286/33286/23794 33270/33270/23782 +f 33272/33272/23784 33288/33288/23796 33289/33289/23795 +f 33272/33272/23784 33289/33289/23795 33273/33273/23783 +f 33274/33274/23785 33290/33290/23797 33288/33288/23796 +f 33274/33274/23785 33288/33288/23796 33272/33272/23784 +f 33275/33275/23786 33291/33291/23798 33290/33290/23797 +f 33275/33275/23786 33290/33290/23797 33274/33274/23785 +f 33276/33276/23787 33292/33292/23799 33293/33293/23798 +f 33276/33276/23787 33293/33293/23798 33277/33277/23786 +f 33278/33278/23788 33294/33294/23800 33292/33292/23799 +f 33278/33278/23788 33292/33292/23799 33276/33276/23787 +f 33279/33279/23778 33295/33295/23801 33294/33294/23800 +f 33279/33279/23778 33294/33294/23800 33278/33278/23788 +f 33280/33280/23789 33296/33296/23802 33297/33297/23803 +f 33280/33280/23789 33297/33297/23803 33281/33281/23790 +f 33282/33282/23791 33298/33298/23804 33296/33296/23802 +f 33282/33282/23791 33296/33296/23802 33280/33280/23789 +f 33283/33283/23792 33299/33299/23805 33298/33298/23804 +f 33283/33283/23792 33298/33298/23804 33282/33282/23791 +f 33284/33284/23793 33300/33300/23806 33301/33301/23805 +f 33284/33284/23793 33301/33301/23805 33285/33285/23792 +f 33286/33286/23794 33302/33302/23807 33300/33300/23806 +f 33286/33286/23794 33300/33300/23806 33284/33284/23793 +f 33287/33287/23795 33303/33303/23808 33302/33302/23807 +f 33287/33287/23795 33302/33302/23807 33286/33286/23794 +f 33288/33288/23796 33304/33304/23809 33305/33305/23810 +f 33288/33288/23796 33305/33305/23810 33289/33289/23795 +f 33290/33290/23797 33306/33306/23811 33304/33304/23809 +f 33290/33290/23797 33304/33304/23809 33288/33288/23796 +f 33291/33291/23798 33307/33307/23812 33306/33306/23811 +f 33291/33291/23798 33306/33306/23811 33290/33290/23797 +f 33292/33292/23799 33308/33308/23813 33309/33309/23812 +f 33292/33292/23799 33309/33309/23812 33293/33293/23798 +f 33294/33294/23800 33310/33310/23814 33308/33308/23813 +f 33294/33294/23800 33308/33308/23813 33292/33292/23799 +f 33295/33295/23801 33311/33311/23815 33310/33310/23814 +f 33295/33295/23801 33310/33310/23814 33294/33294/23800 +f 33296/33296/23802 33312/33312/23816 33313/33313/23817 +f 33296/33296/23802 33313/33313/23817 33297/33297/23803 +f 33298/33298/23804 33314/33314/23818 33312/33312/23816 +f 33298/33298/23804 33312/33312/23816 33296/33296/23802 +f 33299/33299/23805 33315/33315/23819 33314/33314/23818 +f 33299/33299/23805 33314/33314/23818 33298/33298/23804 +f 33300/33300/23806 33316/33316/23820 33317/33317/23821 +f 33300/33300/23806 33317/33317/23821 33301/33301/23805 +f 33302/33302/23807 33318/33318/23822 33316/33316/23820 +f 33302/33302/23807 33316/33316/23820 33300/33300/23806 +f 33303/33303/23808 33319/33319/23823 33318/33318/23822 +f 33303/33303/23808 33318/33318/23822 33302/33302/23807 +f 33304/33304/23809 33320/33320/23824 33321/33321/23825 +f 33304/33304/23809 33321/33321/23825 33305/33305/23810 +f 33306/33306/23811 33322/33322/23826 33320/33320/23824 +f 33306/33306/23811 33320/33320/23824 33304/33304/23809 +f 33307/33307/23812 33323/33323/23827 33322/33322/23826 +f 33307/33307/23812 33322/33322/23826 33306/33306/23811 +f 33308/33308/23813 33324/33324/23828 33325/33325/23827 +f 33308/33308/23813 33325/33325/23827 33309/33309/23812 +f 33310/33310/23814 33326/33326/23829 33324/33324/23828 +f 33310/33310/23814 33324/33324/23828 33308/33308/23813 +f 33311/33311/23815 33327/33327/23817 33326/33326/23829 +f 33311/33311/23815 33326/33326/23829 33310/33310/23814 +f 33312/33312/23816 33328/33328/23830 33329/33329/23831 +f 33312/33312/23816 33329/33329/23831 33313/33313/23817 +f 33314/33314/23818 33330/33330/23832 33328/33328/23830 +f 33314/33314/23818 33328/33328/23830 33312/33312/23816 +f 33315/33315/23819 33331/33331/23833 33330/33330/23832 +f 33315/33315/23819 33330/33330/23832 33314/33314/23818 +f 33316/33316/23820 33332/33332/23834 33333/33333/23833 +f 33316/33316/23820 33333/33333/23833 33317/33317/23821 +f 33318/33318/23822 33334/33334/23835 33332/33332/23834 +f 33318/33318/23822 33332/33332/23834 33316/33316/23820 +f 33319/33319/23823 33335/33335/23836 33334/33334/23835 +f 33319/33319/23823 33334/33334/23835 33318/33318/23822 +f 33320/33320/23824 33336/33336/23837 33337/33337/23836 +f 33320/33320/23824 33337/33337/23836 33321/33321/23825 +f 33322/33322/23826 33338/33338/23838 33336/33336/23837 +f 33322/33322/23826 33336/33336/23837 33320/33320/23824 +f 33323/33323/23827 33339/33339/23839 33338/33338/23838 +f 33323/33323/23827 33338/33338/23838 33322/33322/23826 +f 33324/33324/23828 33340/33340/23840 33341/33341/23839 +f 33324/33324/23828 33341/33341/23839 33325/33325/23827 +f 33326/33326/23829 33342/33342/23841 33340/33340/23840 +f 33326/33326/23829 33340/33340/23840 33324/33324/23828 +f 33327/33327/23817 33343/33343/23831 33342/33342/23841 +f 33327/33327/23817 33342/33342/23841 33326/33326/23829 +f 33328/33328/23830 33344/33344/23842 33345/33345/23843 +f 33328/33328/23830 33345/33345/23843 33329/33329/23831 +f 33330/33330/23832 33346/33346/23844 33344/33344/23842 +f 33330/33330/23832 33344/33344/23842 33328/33328/23830 +f 33331/33331/23833 33347/33347/23845 33346/33346/23844 +f 33331/33331/23833 33346/33346/23844 33330/33330/23832 +f 33332/33332/23834 33348/33348/23846 33349/33349/23845 +f 33332/33332/23834 33349/33349/23845 33333/33333/23833 +f 33334/33334/23835 33350/33350/23847 33348/33348/23846 +f 33334/33334/23835 33348/33348/23846 33332/33332/23834 +f 33335/33335/23836 33351/33351/23848 33350/33350/23847 +f 33335/33335/23836 33350/33350/23847 33334/33334/23835 +f 33336/33336/23837 33352/33352/23849 33353/33353/23848 +f 33336/33336/23837 33353/33353/23848 33337/33337/23836 +f 33338/33338/23838 33354/33354/23850 33352/33352/23849 +f 33338/33338/23838 33352/33352/23849 33336/33336/23837 +f 33339/33339/23839 33355/33355/23851 33354/33354/23850 +f 33339/33339/23839 33354/33354/23850 33338/33338/23838 +f 33340/33340/23840 33356/33356/23852 33357/33357/23853 +f 33340/33340/23840 33357/33357/23853 33341/33341/23839 +f 33342/33342/23841 33358/33358/23854 33356/33356/23852 +f 33342/33342/23841 33356/33356/23852 33340/33340/23840 +f 33343/33343/23831 33359/33359/23843 33358/33358/23854 +f 33343/33343/23831 33358/33358/23854 33342/33342/23841 +f 33344/33344/23842 33360/33360/23855 33361/33361/23856 +f 33344/33344/23842 33361/33361/23856 33345/33345/23843 +f 33346/33346/23844 33362/33362/23857 33360/33360/23855 +f 33346/33346/23844 33360/33360/23855 33344/33344/23842 +f 33347/33347/23845 33363/33363/23858 33362/33362/23857 +f 33347/33347/23845 33362/33362/23857 33346/33346/23844 +f 33348/33348/23846 33364/33364/23859 33365/33365/23858 +f 33348/33348/23846 33365/33365/23858 33349/33349/23845 +f 33350/33350/23847 33366/33366/23860 33364/33364/23859 +f 33350/33350/23847 33364/33364/23859 33348/33348/23846 +f 33351/33351/23848 33367/33367/23861 33366/33366/23860 +f 33351/33351/23848 33366/33366/23860 33350/33350/23847 +f 33352/33352/23849 33368/33368/23862 33369/33369/23861 +f 33352/33352/23849 33369/33369/23861 33353/33353/23848 +f 33354/33354/23850 33370/33370/23863 33368/33368/23862 +f 33354/33354/23850 33368/33368/23862 33352/33352/23849 +f 33355/33355/23851 33371/33371/23864 33370/33370/23863 +f 33355/33355/23851 33370/33370/23863 33354/33354/23850 +f 33356/33356/23852 33372/33372/23865 33373/33373/23864 +f 33356/33356/23852 33373/33373/23864 33357/33357/23853 +f 33358/33358/23854 33374/33374/23866 33372/33372/23865 +f 33358/33358/23854 33372/33372/23865 33356/33356/23852 +f 33359/33359/23843 33375/33375/23867 33374/33374/23866 +f 33359/33359/23843 33374/33374/23866 33358/33358/23854 +f 33360/33360/23855 33376/33376/23868 33377/33377/23869 +f 33360/33360/23855 33377/33377/23869 33361/33361/23856 +f 33362/33362/23857 33378/33378/23870 33376/33376/23868 +f 33362/33362/23857 33376/33376/23868 33360/33360/23855 +f 33363/33363/23858 33379/33379/23871 33378/33378/23870 +f 33363/33363/23858 33378/33378/23870 33362/33362/23857 +f 33364/33364/23859 33380/33380/23872 33381/33381/23871 +f 33364/33364/23859 33381/33381/23871 33365/33365/23858 +f 33366/33366/23860 33382/33382/23873 33380/33380/23872 +f 33366/33366/23860 33380/33380/23872 33364/33364/23859 +f 33367/33367/23861 33383/33383/23874 33382/33382/23873 +f 33367/33367/23861 33382/33382/23873 33366/33366/23860 +f 33368/33368/23862 33384/33384/23875 33385/33385/23876 +f 33368/33368/23862 33385/33385/23876 33369/33369/23861 +f 33370/33370/23863 33386/33386/23877 33384/33384/23875 +f 33370/33370/23863 33384/33384/23875 33368/33368/23862 +f 33371/33371/23864 33387/33387/23878 33386/33386/23877 +f 33371/33371/23864 33386/33386/23877 33370/33370/23863 +f 33372/33372/23865 33388/33388/23879 33389/33389/23878 +f 33372/33372/23865 33389/33389/23878 33373/33373/23864 +f 33374/33374/23866 33390/33390/23880 33388/33388/23879 +f 33374/33374/23866 33388/33388/23879 33372/33372/23865 +f 33375/33375/23867 33391/33391/23869 33390/33390/23880 +f 33375/33375/23867 33390/33390/23880 33374/33374/23866 +f 33392/33392/23868 33393/33393/23881 33394/33394/23882 +f 33392/33392/23868 33394/33394/23882 33391/33391/23869 +f 33378/33378/23870 33395/33395/23883 33396/33396/23881 +f 33378/33378/23870 33396/33396/23881 33376/33376/23868 +f 33379/33379/23871 33397/33397/23884 33395/33395/23883 +f 33379/33379/23871 33395/33395/23883 33378/33378/23870 +f 33380/33380/23872 33398/33398/23885 33399/33399/23886 +f 33380/33380/23872 33399/33399/23886 33381/33381/23871 +f 33382/33382/23873 33400/33400/23887 33398/33398/23885 +f 33382/33382/23873 33398/33398/23885 33380/33380/23872 +f 33383/33383/23874 33401/33401/23888 33400/33400/23887 +f 33383/33383/23874 33400/33400/23887 33382/33382/23873 +f 33402/33402/23875 33403/33403/23889 33401/33401/23888 +f 33402/33402/23875 33401/33401/23888 33383/33383/23874 +f 33386/33386/23877 33404/33404/23890 33405/33405/23889 +f 33386/33386/23877 33405/33405/23889 33384/33384/23875 +f 33387/33387/23878 33406/33406/23891 33404/33404/23890 +f 33387/33387/23878 33404/33404/23890 33386/33386/23877 +f 33388/33388/23879 33407/33407/23892 33408/33408/23893 +f 33388/33388/23879 33408/33408/23893 33389/33389/23878 +f 33390/33390/23880 33409/33409/23894 33407/33407/23892 +f 33390/33390/23880 33407/33407/23892 33388/33388/23879 +f 33391/33391/23869 33394/33394/23882 33409/33409/23894 +f 33391/33391/23869 33409/33409/23894 33390/33390/23880 +f 33393/33393/23881 33410/33410/23895 33411/33411/23896 +f 33393/33393/23881 33411/33411/23896 33394/33394/23882 +f 33395/33395/23883 33412/33412/23897 33413/33413/23895 +f 33395/33395/23883 33413/33413/23895 33396/33396/23881 +f 33397/33397/23884 33414/33414/23898 33412/33412/23897 +f 33397/33397/23884 33412/33412/23897 33395/33395/23883 +f 33415/33415/23899 33416/33416/23900 33414/33414/23898 +f 33415/33415/23899 33414/33414/23898 33397/33397/23884 +f 33400/33400/23887 33417/33417/23901 33418/33418/23900 +f 33400/33400/23887 33418/33418/23900 33398/33398/23885 +f 33401/33401/23888 33419/33419/23902 33417/33417/23901 +f 33401/33401/23888 33417/33417/23901 33400/33400/23887 +f 33403/33403/23889 33420/33420/23903 33419/33419/23902 +f 33403/33403/23889 33419/33419/23902 33401/33401/23888 +f 33404/33404/23890 33421/33421/23904 33422/33422/23905 +f 33404/33404/23890 33422/33422/23905 33405/33405/23889 +f 33406/33406/23891 33423/33423/23906 33421/33421/23904 +f 33406/33406/23891 33421/33421/23904 33404/33404/23890 +f 33424/33424/23907 33425/33425/23908 33423/33423/23906 +f 33424/33424/23907 33423/33423/23906 33406/33406/23891 +f 33409/33409/23894 33426/33426/23909 33427/33427/23908 +f 33409/33409/23894 33427/33427/23908 33407/33407/23892 +f 33394/33394/23882 33411/33411/23896 33426/33426/23909 +f 33394/33394/23882 33426/33426/23909 33409/33409/23894 +f 33413/33413/23895 33428/33428/23910 33429/33429/23911 +f 33413/33413/23895 33429/33429/23911 33430/33430/23896 +f 33412/33412/23897 33431/33431/23912 33428/33428/23910 +f 33412/33412/23897 33428/33428/23910 33413/33413/23895 +f 33414/33414/23898 33432/33432/23913 33431/33431/23912 +f 33414/33414/23898 33431/33431/23912 33412/33412/23897 +f 33416/33416/23900 33433/33433/23914 33432/33432/23913 +f 33416/33416/23900 33432/33432/23913 33414/33414/23898 +f 33417/33417/23901 33434/33434/23915 33435/33435/23914 +f 33417/33417/23901 33435/33435/23914 33418/33418/23900 +f 33419/33419/23902 33436/33436/23916 33434/33434/23915 +f 33419/33419/23902 33434/33434/23915 33417/33417/23901 +f 33420/33420/23903 33437/33437/23917 33436/33436/23916 +f 33420/33420/23903 33436/33436/23916 33419/33419/23902 +f 33421/33421/23904 33438/33438/23918 33439/33439/23917 +f 33421/33421/23904 33439/33439/23917 33422/33422/23905 +f 33423/33423/23906 33440/33440/23919 33438/33438/23918 +f 33423/33423/23906 33438/33438/23918 33421/33421/23904 +f 33425/33425/23908 33441/33441/23920 33440/33440/23919 +f 33425/33425/23908 33440/33440/23919 33423/33423/23906 +f 33426/33426/23909 33442/33442/23921 33443/33443/23922 +f 33426/33426/23909 33443/33443/23922 33427/33427/23908 +f 33411/33411/23896 33444/33444/23911 33442/33442/23921 +f 33411/33411/23896 33442/33442/23921 33426/33426/23909 +f 33428/33428/23910 33445/33445/23923 33446/33446/23924 +f 33428/33428/23910 33446/33446/23924 33429/33429/23911 +f 33431/33431/23912 33447/33447/23925 33445/33445/23923 +f 33431/33431/23912 33445/33445/23923 33428/33428/23910 +f 33432/33432/23913 33448/33448/23926 33447/33447/23925 +f 33432/33432/23913 33447/33447/23925 33431/33431/23912 +f 33433/33433/23914 33449/33449/23927 33448/33448/23926 +f 33433/33433/23914 33448/33448/23926 33432/33432/23913 +f 33434/33434/23915 33450/33450/23928 33451/33451/23929 +f 33434/33434/23915 33451/33451/23929 33435/33435/23914 +f 33436/33436/23916 33452/33452/23930 33450/33450/23928 +f 33436/33436/23916 33450/33450/23928 33434/33434/23915 +f 33437/33437/23917 33453/33453/23931 33452/33452/23930 +f 33437/33437/23917 33452/33452/23930 33436/33436/23916 +f 33438/33438/23918 33454/33454/23932 33455/33455/23931 +f 33438/33438/23918 33455/33455/23931 33439/33439/23917 +f 33440/33440/23919 33456/33456/23933 33454/33454/23932 +f 33440/33440/23919 33454/33454/23932 33438/33438/23918 +f 33441/33441/23920 33457/33457/23934 33456/33456/23933 +f 33441/33441/23920 33456/33456/23933 33440/33440/23919 +f 33442/33442/23921 33458/33458/23935 33459/33459/23936 +f 33442/33442/23921 33459/33459/23936 33443/33443/23922 +f 33444/33444/23911 33460/33460/23937 33458/33458/23935 +f 33444/33444/23911 33458/33458/23935 33442/33442/23921 +f 33461/33461/23938 33462/33462/23939 33463/33463/23940 +f 33461/33461/23938 33463/33463/23940 33460/33460/23937 +f 33447/33447/23925 33464/33464/23941 33465/33465/23939 +f 33447/33447/23925 33465/33465/23939 33445/33445/23923 +f 33448/33448/23926 33466/33466/23942 33464/33464/23941 +f 33448/33448/23926 33464/33464/23941 33447/33447/23925 +f 33449/33449/23927 33467/33467/23943 33466/33466/23942 +f 33449/33449/23927 33466/33466/23942 33448/33448/23926 +f 33450/33450/23928 33468/33468/23944 33469/33469/23945 +f 33450/33450/23928 33469/33469/23945 33451/33451/23929 +f 33452/33452/23930 33470/33470/23946 33468/33468/23944 +f 33452/33452/23930 33468/33468/23944 33450/33450/23928 +f 33453/33453/23931 33471/33471/23947 33470/33470/23946 +f 33453/33453/23931 33470/33470/23946 33452/33452/23930 +f 33454/33454/23932 33472/33472/23948 33473/33473/23947 +f 33454/33454/23932 33473/33473/23947 33455/33455/23931 +f 33456/33456/23933 33474/33474/23949 33472/33472/23948 +f 33456/33456/23933 33472/33472/23948 33454/33454/23932 +f 33457/33457/23934 33475/33475/23950 33474/33474/23949 +f 33457/33457/23934 33474/33474/23949 33456/33456/23933 +f 33458/33458/23935 33476/33476/23951 33477/33477/23950 +f 33458/33458/23935 33477/33477/23950 33459/33459/23936 +f 33460/33460/23937 33463/33463/23940 33476/33476/23951 +f 33460/33460/23937 33476/33476/23951 33458/33458/23935 +f 33462/33462/23939 33478/33478/23952 33479/33479/23953 +f 33462/33462/23939 33479/33479/23953 33463/33463/23940 +f 33464/33464/23941 33480/33480/23954 33481/33481/23955 +f 33464/33464/23941 33481/33481/23955 33465/33465/23939 +f 33466/33466/23942 33482/33482/23956 33480/33480/23954 +f 33466/33466/23942 33480/33480/23954 33464/33464/23941 +f 33467/33467/23943 33483/33483/23957 33482/33482/23956 +f 33467/33467/23943 33482/33482/23956 33466/33466/23942 +f 33468/33468/23944 33484/33484/23958 33485/33485/23959 +f 33468/33468/23944 33485/33485/23959 33469/33469/23945 +f 33470/33470/23946 33486/33486/23960 33484/33484/23958 +f 33470/33470/23946 33484/33484/23958 33468/33468/23944 +f 33471/33471/23947 33487/33487/23961 33486/33486/23960 +f 33471/33471/23947 33486/33486/23960 33470/33470/23946 +f 33472/33472/23948 33488/33488/23962 33489/33489/23961 +f 33472/33472/23948 33489/33489/23961 33473/33473/23947 +f 33474/33474/23949 33490/33490/23963 33488/33488/23962 +f 33474/33474/23949 33488/33488/23962 33472/33472/23948 +f 33475/33475/23950 33491/33491/23964 33490/33490/23963 +f 33475/33475/23950 33490/33490/23963 33474/33474/23949 +f 33476/33476/23951 33492/33492/23965 33493/33493/23964 +f 33476/33476/23951 33493/33493/23964 33477/33477/23950 +f 33463/33463/23940 33479/33479/23953 33492/33492/23965 +f 33463/33463/23940 33492/33492/23965 33476/33476/23951 +f 33478/33478/23952 33494/33494/23966 33495/33495/23967 +f 33478/33478/23952 33495/33495/23967 33479/33479/23953 +f 33480/33480/23954 33496/33496/23968 33497/33497/23966 +f 33480/33480/23954 33497/33497/23966 33481/33481/23955 +f 33482/33482/23956 33498/33498/23969 33496/33496/23968 +f 33482/33482/23956 33496/33496/23968 33480/33480/23954 +f 33483/33483/23957 33499/33499/23970 33498/33498/23969 +f 33483/33483/23957 33498/33498/23969 33482/33482/23956 +f 33484/33484/23958 33500/33500/23971 33501/33501/23970 +f 33484/33484/23958 33501/33501/23970 33485/33485/23959 +f 33486/33486/23960 33502/33502/23972 33500/33500/23971 +f 33486/33486/23960 33500/33500/23971 33484/33484/23958 +f 33487/33487/23961 33503/33503/23973 33502/33502/23972 +f 33487/33487/23961 33502/33502/23972 33486/33486/23960 +f 33488/33488/23962 33504/33504/23974 33505/33505/23975 +f 33488/33488/23962 33505/33505/23975 33489/33489/23961 +f 33490/33490/23963 33506/33506/23976 33504/33504/23974 +f 33490/33490/23963 33504/33504/23974 33488/33488/23962 +f 33491/33491/23964 33507/33507/23977 33506/33506/23976 +f 33491/33491/23964 33506/33506/23976 33490/33490/23963 +f 33492/33492/23965 33508/33508/23978 33509/33509/23977 +f 33492/33492/23965 33509/33509/23977 33493/33493/23964 +f 33479/33479/23953 33495/33495/23967 33508/33508/23978 +f 33479/33479/23953 33508/33508/23978 33492/33492/23965 +f 33494/33494/23966 33510/33510/23979 33511/33511/23980 +f 33494/33494/23966 33511/33511/23980 33495/33495/23967 +f 33496/33496/23968 33512/33512/23981 33513/33513/23979 +f 33496/33496/23968 33513/33513/23979 33497/33497/23966 +f 33498/33498/23969 33514/33514/23982 33512/33512/23981 +f 33498/33498/23969 33512/33512/23981 33496/33496/23968 +f 33499/33499/23970 33515/33515/23983 33514/33514/23982 +f 33499/33499/23970 33514/33514/23982 33498/33498/23969 +f 33500/33500/23971 33516/33516/23984 33517/33517/23983 +f 33500/33500/23971 33517/33517/23983 33501/33501/23970 +f 33502/33502/23972 33518/33518/23985 33516/33516/23984 +f 33502/33502/23972 33516/33516/23984 33500/33500/23971 +f 33503/33503/23973 33519/33519/23986 33518/33518/23985 +f 33503/33503/23973 33518/33518/23985 33502/33502/23972 +f 33504/33504/23974 33520/33520/23987 33521/33521/23986 +f 33504/33504/23974 33521/33521/23986 33505/33505/23975 +f 33506/33506/23976 33522/33522/23988 33520/33520/23987 +f 33506/33506/23976 33520/33520/23987 33504/33504/23974 +f 33507/33507/23977 33523/33523/23989 33522/33522/23988 +f 33507/33507/23977 33522/33522/23988 33506/33506/23976 +f 33508/33508/23978 33524/33524/23990 33525/33525/23989 +f 33508/33508/23978 33525/33525/23989 33509/33509/23977 +f 33495/33495/23967 33511/33511/23980 33524/33524/23990 +f 33495/33495/23967 33524/33524/23990 33508/33508/23978 +f 33510/33510/23979 33526/33526/23991 33527/33527/23992 +f 33510/33510/23979 33527/33527/23992 33511/33511/23980 +f 33512/33512/23981 33528/33528/23993 33529/33529/23991 +f 33512/33512/23981 33529/33529/23991 33513/33513/23979 +f 33514/33514/23982 33530/33530/23994 33528/33528/23993 +f 33514/33514/23982 33528/33528/23993 33512/33512/23981 +f 33515/33515/23983 33531/33531/23995 33530/33530/23994 +f 33515/33515/23983 33530/33530/23994 33514/33514/23982 +f 33516/33516/23984 33532/33532/23996 33533/33533/23997 +f 33516/33516/23984 33533/33533/23997 33517/33517/23983 +f 33518/33518/23985 33534/33534/23998 33532/33532/23996 +f 33518/33518/23985 33532/33532/23996 33516/33516/23984 +f 33519/33519/23986 33535/33535/23999 33534/33534/23998 +f 33519/33519/23986 33534/33534/23998 33518/33518/23985 +f 33520/33520/23987 33536/33536/24000 33537/33537/24001 +f 33520/33520/23987 33537/33537/24001 33521/33521/23986 +f 33522/33522/23988 33538/33538/24002 33536/33536/24000 +f 33522/33522/23988 33536/33536/24000 33520/33520/23987 +f 33523/33523/23989 33539/33539/24003 33538/33538/24002 +f 33523/33523/23989 33538/33538/24002 33522/33522/23988 +f 33524/33524/23990 33540/33540/24004 33541/33541/24003 +f 33524/33524/23990 33541/33541/24003 33525/33525/23989 +f 33511/33511/23980 33527/33527/23992 33540/33540/24004 +f 33511/33511/23980 33540/33540/24004 33524/33524/23990 +f 33526/33526/23991 33542/33542/24005 33543/33543/24006 +f 33526/33526/23991 33543/33543/24006 33527/33527/23992 +f 33528/33528/23993 33544/33544/24007 33545/33545/24005 +f 33528/33528/23993 33545/33545/24005 33529/33529/23991 +f 33530/33530/23994 33546/33546/24008 33544/33544/24007 +f 33530/33530/23994 33544/33544/24007 33528/33528/23993 +f 33531/33531/23995 33547/33547/24009 33546/33546/24008 +f 33531/33531/23995 33546/33546/24008 33530/33530/23994 +f 33532/33532/23996 33548/33548/24010 33549/33549/24009 +f 33532/33532/23996 33549/33549/24009 33533/33533/23997 +f 33534/33534/23998 33550/33550/24011 33548/33548/24010 +f 33534/33534/23998 33548/33548/24010 33532/33532/23996 +f 33535/33535/23999 33551/33551/24012 33550/33550/24011 +f 33535/33535/23999 33550/33550/24011 33534/33534/23998 +f 33536/33536/24000 33552/33552/24013 33553/33553/24012 +f 33536/33536/24000 33553/33553/24012 33537/33537/24001 +f 33538/33538/24002 33554/33554/24014 33552/33552/24013 +f 33538/33538/24002 33552/33552/24013 33536/33536/24000 +f 33539/33539/24003 33555/33555/24015 33554/33554/24014 +f 33539/33539/24003 33554/33554/24014 33538/33538/24002 +f 33540/33540/24004 33556/33556/24016 33557/33557/24015 +f 33540/33540/24004 33557/33557/24015 33541/33541/24003 +f 33527/33527/23992 33543/33543/24006 33556/33556/24016 +f 33527/33527/23992 33556/33556/24016 33540/33540/24004 +f 33542/33542/24005 33558/33558/24017 33559/33559/24018 +f 33542/33542/24005 33559/33559/24018 33543/33543/24006 +f 33544/33544/24007 33560/33560/24019 33561/33561/24017 +f 33544/33544/24007 33561/33561/24017 33545/33545/24005 +f 33546/33546/24008 33562/33562/24020 33560/33560/24019 +f 33546/33546/24008 33560/33560/24019 33544/33544/24007 +f 33547/33547/24009 33563/33563/24021 33562/33562/24020 +f 33547/33547/24009 33562/33562/24020 33546/33546/24008 +f 33548/33548/24010 33564/33564/24022 33565/33565/24021 +f 33548/33548/24010 33565/33565/24021 33549/33549/24009 +f 33550/33550/24011 33566/33566/24023 33564/33564/24022 +f 33550/33550/24011 33564/33564/24022 33548/33548/24010 +f 33551/33551/24012 33567/33567/24024 33566/33566/24023 +f 33551/33551/24012 33566/33566/24023 33550/33550/24011 +f 33552/33552/24013 33568/33568/24025 33569/33569/24024 +f 33552/33552/24013 33569/33569/24024 33553/33553/24012 +f 33554/33554/24014 33570/33570/24026 33568/33568/24025 +f 33554/33554/24014 33568/33568/24025 33552/33552/24013 +f 33555/33555/24015 33571/33571/24027 33570/33570/24026 +f 33555/33555/24015 33570/33570/24026 33554/33554/24014 +f 33556/33556/24016 33572/33572/24028 33573/33573/24027 +f 33556/33556/24016 33573/33573/24027 33557/33557/24015 +f 33543/33543/24006 33559/33559/24018 33572/33572/24028 +f 33543/33543/24006 33572/33572/24028 33556/33556/24016 +f 33558/33558/24017 33574/33574/24029 33575/33575/24030 +f 33558/33558/24017 33575/33575/24030 33559/33559/24018 +f 33560/33560/24019 33576/33576/24031 33577/33577/24029 +f 33560/33560/24019 33577/33577/24029 33561/33561/24017 +f 33562/33562/24020 33578/33578/24032 33576/33576/24031 +f 33562/33562/24020 33576/33576/24031 33560/33560/24019 +f 33563/33563/24021 33579/33579/24033 33578/33578/24032 +f 33563/33563/24021 33578/33578/24032 33562/33562/24020 +f 33564/33564/24022 33580/33580/24034 33581/33581/24033 +f 33564/33564/24022 33581/33581/24033 33565/33565/24021 +f 33566/33566/24023 33582/33582/24035 33580/33580/24034 +f 33566/33566/24023 33580/33580/24034 33564/33564/24022 +f 33567/33567/24024 33583/33583/24036 33582/33582/24035 +f 33567/33567/24024 33582/33582/24035 33566/33566/24023 +f 33568/33568/24025 33584/33584/24037 33585/33585/24036 +f 33568/33568/24025 33585/33585/24036 33569/33569/24024 +f 33570/33570/24026 33586/33586/24038 33584/33584/24037 +f 33570/33570/24026 33584/33584/24037 33568/33568/24025 +f 33571/33571/24027 33587/33587/24039 33586/33586/24038 +f 33571/33571/24027 33586/33586/24038 33570/33570/24026 +f 33572/33572/24028 33588/33588/24040 33589/33589/24039 +f 33572/33572/24028 33589/33589/24039 33573/33573/24027 +f 33559/33559/24018 33575/33575/24030 33588/33588/24040 +f 33559/33559/24018 33588/33588/24040 33572/33572/24028 +f 33590/33590/24029 33591/33591/24041 33592/33592/24042 +f 33590/33590/24029 33592/33592/24042 33593/33593/24043 +f 33576/33576/24031 33594/33594/24044 33595/33595/24045 +f 33576/33576/24031 33595/33595/24045 33577/33577/24029 +f 33578/33578/24032 33596/33596/24046 33594/33594/24044 +f 33578/33578/24032 33594/33594/24044 33576/33576/24031 +f 33579/33579/24033 33597/33597/24047 33596/33596/24046 +f 33579/33579/24033 33596/33596/24046 33578/33578/24032 +f 33580/33580/24034 33598/33598/24048 33599/33599/24047 +f 33580/33580/24034 33599/33599/24047 33581/33581/24033 +f 33582/33582/24035 33600/33600/24049 33598/33598/24048 +f 33582/33582/24035 33598/33598/24048 33580/33580/24034 +f 33601/33601/24050 33602/33602/24051 33603/33603/24049 +f 33601/33601/24050 33603/33603/24049 33604/33604/24035 +f 33584/33584/24037 33605/33605/24052 33606/33606/24053 +f 33584/33584/24037 33606/33606/24053 33585/33585/24036 +f 33586/33586/24038 33607/33607/24054 33605/33605/24052 +f 33586/33586/24038 33605/33605/24052 33584/33584/24037 +f 33587/33587/24039 33608/33608/24055 33607/33607/24054 +f 33587/33587/24039 33607/33607/24054 33586/33586/24038 +f 33588/33588/24040 33609/33609/24056 33610/33610/24055 +f 33588/33588/24040 33610/33610/24055 33589/33589/24039 +f 33575/33575/24030 33611/33611/24057 33609/33609/24056 +f 33575/33575/24030 33609/33609/24056 33588/33588/24040 +f 33591/33591/24041 33612/33612/24058 33613/33613/24059 +f 33591/33591/24041 33613/33613/24059 33592/33592/24042 +f 33614/33614/24044 33615/33615/24060 33612/33612/24058 +f 33614/33614/24044 33612/33612/24058 33591/33591/24041 +f 33596/33596/24046 33616/33616/24061 33617/33617/24060 +f 33596/33596/24046 33617/33617/24060 33594/33594/24044 +f 33597/33597/24047 33618/33618/24062 33616/33616/24061 +f 33597/33597/24047 33616/33616/24061 33596/33596/24046 +f 33598/33598/24048 33619/33619/24063 33620/33620/24064 +f 33598/33598/24048 33620/33620/24064 33599/33599/24047 +f 33603/33603/24049 33621/33621/24065 33622/33622/24066 +f 33603/33603/24049 33622/33622/24066 33623/33623/24048 +f 33602/33602/24051 33624/33624/24067 33621/33621/24065 +f 33602/33602/24051 33621/33621/24065 33603/33603/24049 +f 33625/33625/24052 33626/33626/24068 33624/33624/24067 +f 33625/33625/24052 33624/33624/24067 33602/33602/24051 +f 33607/33607/24054 33627/33627/24069 33628/33628/24070 +f 33607/33607/24054 33628/33628/24070 33605/33605/24052 +f 33608/33608/24055 33629/33629/24071 33627/33627/24069 +f 33608/33608/24055 33627/33627/24069 33607/33607/24054 +f 33609/33609/24056 33630/33630/24072 33631/33631/24071 +f 33609/33609/24056 33631/33631/24071 33610/33610/24055 +f 33592/33592/24042 33613/33613/24059 33632/33632/24073 +f 33592/33592/24042 33632/33632/24073 33633/33633/24056 +f 33612/33612/24058 33634/33634/24074 33635/33635/24075 +f 33612/33612/24058 33635/33635/24075 33613/33613/24059 +f 33615/33615/24060 33636/33636/24076 33634/33634/24074 +f 33615/33615/24060 33634/33634/24074 33612/33612/24058 +f 33616/33616/24061 33637/33637/24077 33638/33638/24076 +f 33616/33616/24061 33638/33638/24076 33617/33617/24060 +f 33618/33618/24062 33639/33639/24078 33637/33637/24077 +f 33618/33618/24062 33637/33637/24077 33616/33616/24061 +f 33640/33640/24079 33641/33641/24080 33639/33639/24078 +f 33640/33640/24079 33639/33639/24078 33618/33618/24062 +f 33621/33621/24065 33642/33642/24081 33643/33643/24080 +f 33621/33621/24065 33643/33643/24080 33622/33622/24066 +f 33624/33624/24067 33644/33644/24082 33642/33642/24081 +f 33624/33624/24067 33642/33642/24081 33621/33621/24065 +f 33626/33626/24068 33645/33645/24083 33644/33644/24082 +f 33626/33626/24068 33644/33644/24082 33624/33624/24067 +f 33627/33627/24069 33646/33646/24084 33647/33647/24083 +f 33627/33627/24069 33647/33647/24083 33628/33628/24070 +f 33629/33629/24071 33648/33648/24085 33646/33646/24084 +f 33629/33629/24071 33646/33646/24084 33627/33627/24069 +f 33649/33649/24072 33650/33650/24086 33648/33648/24085 +f 33649/33649/24072 33648/33648/24085 33629/33629/24071 +f 33613/33613/24059 33635/33635/24075 33651/33651/24086 +f 33613/33613/24059 33651/33651/24086 33632/33632/24073 +f 33634/33634/24074 33652/33652/24087 33653/33653/24088 +f 33634/33634/24074 33653/33653/24088 33635/33635/24075 +f 33636/33636/24076 33654/33654/24089 33652/33652/24087 +f 33636/33636/24076 33652/33652/24087 33634/33634/24074 +f 33637/33637/24077 33655/33655/24090 33656/33656/24089 +f 33637/33637/24077 33656/33656/24089 33638/33638/24076 +f 33639/33639/24078 33657/33657/24091 33655/33655/24090 +f 33639/33639/24078 33655/33655/24090 33637/33637/24077 +f 33641/33641/24080 33658/33658/24092 33657/33657/24091 +f 33641/33641/24080 33657/33657/24091 33639/33639/24078 +f 33642/33642/24081 33659/33659/24093 33660/33660/24092 +f 33642/33642/24081 33660/33660/24092 33643/33643/24080 +f 33644/33644/24082 33661/33661/24094 33659/33659/24093 +f 33644/33644/24082 33659/33659/24093 33642/33642/24081 +f 33645/33645/24083 33662/33662/24095 33661/33661/24094 +f 33645/33645/24083 33661/33661/24094 33644/33644/24082 +f 33646/33646/24084 33663/33663/24096 33664/33664/24095 +f 33646/33646/24084 33664/33664/24095 33647/33647/24083 +f 33648/33648/24085 33665/33665/24097 33663/33663/24096 +f 33648/33648/24085 33663/33663/24096 33646/33646/24084 +f 33650/33650/24086 33666/33666/24098 33665/33665/24097 +f 33650/33650/24086 33665/33665/24097 33648/33648/24085 +f 33635/33635/24075 33653/33653/24088 33667/33667/24098 +f 33635/33635/24075 33667/33667/24098 33651/33651/24086 +f 33652/33652/24087 33668/33668/24099 33669/33669/24100 +f 33652/33652/24087 33669/33669/24100 33653/33653/24088 +f 33654/33654/24089 33670/33670/24101 33668/33668/24099 +f 33654/33654/24089 33668/33668/24099 33652/33652/24087 +f 33655/33655/24090 33671/33671/24102 33672/33672/24101 +f 33655/33655/24090 33672/33672/24101 33656/33656/24089 +f 33657/33657/24091 33673/33673/24103 33671/33671/24102 +f 33657/33657/24091 33671/33671/24102 33655/33655/24090 +f 33658/33658/24092 33674/33674/24104 33673/33673/24103 +f 33658/33658/24092 33673/33673/24103 33657/33657/24091 +f 33659/33659/24093 33675/33675/24105 33676/33676/24104 +f 33659/33659/24093 33676/33676/24104 33660/33660/24092 +f 33661/33661/24094 33677/33677/24106 33675/33675/24105 +f 33661/33661/24094 33675/33675/24105 33659/33659/24093 +f 33662/33662/24095 33678/33678/24107 33677/33677/24106 +f 33662/33662/24095 33677/33677/24106 33661/33661/24094 +f 33663/33663/24096 33679/33679/24108 33680/33680/24107 +f 33663/33663/24096 33680/33680/24107 33664/33664/24095 +f 33665/33665/24097 33681/33681/24109 33679/33679/24108 +f 33665/33665/24097 33679/33679/24108 33663/33663/24096 +f 33666/33666/24098 33682/33682/24110 33681/33681/24109 +f 33666/33666/24098 33681/33681/24109 33665/33665/24097 +f 33653/33653/24088 33669/33669/24100 33683/33683/24110 +f 33653/33653/24088 33683/33683/24110 33667/33667/24098 +f 33668/33668/24099 33684/33684/24111 33685/33685/24112 +f 33668/33668/24099 33685/33685/24112 33669/33669/24100 +f 33686/33686/24101 33687/33687/24113 33688/33688/24111 +f 33686/33686/24101 33688/33688/24111 33689/33689/24099 +f 33671/33671/24102 33690/33690/24114 33691/33691/24113 +f 33671/33671/24102 33691/33691/24113 33672/33672/24101 +f 33673/33673/24103 33692/33692/24115 33690/33690/24114 +f 33673/33673/24103 33690/33690/24114 33671/33671/24102 +f 33674/33674/24104 33693/33693/24116 33692/33692/24115 +f 33674/33674/24104 33692/33692/24115 33673/33673/24103 +f 33675/33675/24105 33694/33694/24117 33695/33695/24118 +f 33675/33675/24105 33695/33695/24118 33676/33676/24104 +f 33677/33677/24106 33696/33696/24119 33694/33694/24117 +f 33677/33677/24106 33694/33694/24117 33675/33675/24105 +f 33697/33697/24107 33698/33698/24120 33699/33699/24119 +f 33697/33697/24107 33699/33699/24119 33700/33700/24121 +f 33679/33679/24108 33701/33701/24122 33702/33702/24120 +f 33679/33679/24108 33702/33702/24120 33680/33680/24107 +f 33681/33681/24109 33703/33703/24123 33701/33701/24122 +f 33681/33681/24109 33701/33701/24122 33679/33679/24108 +f 33682/33682/24110 33704/33704/24124 33703/33703/24123 +f 33682/33682/24110 33703/33703/24123 33681/33681/24109 +f 33669/33669/24100 33685/33685/24112 33705/33705/24125 +f 33669/33669/24100 33705/33705/24125 33683/33683/24110 +f 33688/33688/24111 33706/33706/24126 33707/33707/24127 +f 33688/33688/24111 33707/33707/24127 33708/33708/24112 +f 33687/33687/24113 33709/33709/24128 33706/33706/24126 +f 33687/33687/24113 33706/33706/24126 33688/33688/24111 +f 33690/33690/24114 33710/33710/24129 33711/33711/24128 +f 33690/33690/24114 33711/33711/24128 33691/33691/24113 +f 33692/33692/24115 33712/33712/24130 33710/33710/24129 +f 33692/33692/24115 33710/33710/24129 33690/33690/24114 +f 33693/33693/24116 33713/33713/24131 33712/33712/24130 +f 33693/33693/24116 33712/33712/24130 33692/33692/24115 +f 33714/33714/24117 33715/33715/24132 33713/33713/24131 +f 33714/33714/24117 33713/33713/24131 33693/33693/24116 +f 33699/33699/24119 33716/33716/24133 33717/33717/24134 +f 33699/33699/24119 33717/33717/24134 33718/33718/24117 +f 33698/33698/24120 33719/33719/24135 33716/33716/24133 +f 33698/33698/24120 33716/33716/24133 33699/33699/24119 +f 33701/33701/24122 33720/33720/24136 33721/33721/24135 +f 33701/33701/24122 33721/33721/24135 33702/33702/24120 +f 33703/33703/24123 33722/33722/24137 33720/33720/24136 +f 33703/33703/24123 33720/33720/24136 33701/33701/24122 +f 33704/33704/24124 33723/33723/24138 33722/33722/24137 +f 33704/33704/24124 33722/33722/24137 33703/33703/24123 +f 33724/33724/24112 33725/33725/24139 33723/33723/24138 +f 33724/33724/24112 33723/33723/24138 33704/33704/24124 +f 33706/33706/24126 33726/33726/24140 33727/33727/24141 +f 33706/33706/24126 33727/33727/24141 33707/33707/24127 +f 33709/33709/24128 33728/33728/24142 33726/33726/24140 +f 33709/33709/24128 33726/33726/24140 33706/33706/24126 +f 33710/33710/24129 33729/33729/24143 33730/33730/24142 +f 33710/33710/24129 33730/33730/24142 33711/33711/24128 +f 33712/33712/24130 33731/33731/24144 33729/33729/24143 +f 33712/33712/24130 33729/33729/24143 33710/33710/24129 +f 33713/33713/24131 33732/33732/24145 33731/33731/24144 +f 33713/33713/24131 33731/33731/24144 33712/33712/24130 +f 33715/33715/24132 33733/33733/24146 33732/33732/24145 +f 33715/33715/24132 33732/33732/24145 33713/33713/24131 +f 33716/33716/24133 33734/33734/24147 33735/33735/24146 +f 33716/33716/24133 33735/33735/24146 33717/33717/24134 +f 33719/33719/24135 33736/33736/24148 33734/33734/24147 +f 33719/33719/24135 33734/33734/24147 33716/33716/24133 +f 33720/33720/24136 33737/33737/24149 33738/33738/24148 +f 33720/33720/24136 33738/33738/24148 33721/33721/24135 +f 33722/33722/24137 33739/33739/24150 33737/33737/24149 +f 33722/33722/24137 33737/33737/24149 33720/33720/24136 +f 33723/33723/24138 33740/33740/24151 33739/33739/24150 +f 33723/33723/24138 33739/33739/24150 33722/33722/24137 +f 33725/33725/24139 33741/33741/24141 33740/33740/24151 +f 33725/33725/24139 33740/33740/24151 33723/33723/24138 +f 33726/33726/24140 33742/33742/24152 33743/33743/24153 +f 33726/33726/24140 33743/33743/24153 33727/33727/24141 +f 33728/33728/24142 33744/33744/24154 33742/33742/24152 +f 33728/33728/24142 33742/33742/24152 33726/33726/24140 +f 33729/33729/24143 33745/33745/24155 33746/33746/24156 +f 33729/33729/24143 33746/33746/24156 33730/33730/24142 +f 33731/33731/24144 33747/33747/24157 33745/33745/24155 +f 33731/33731/24144 33745/33745/24155 33729/33729/24143 +f 33732/33732/24145 33748/33748/24158 33747/33747/24157 +f 33732/33732/24145 33747/33747/24157 33731/33731/24144 +f 33735/33735/24146 33749/33749/24159 33750/33750/24158 +f 33735/33735/24146 33750/33750/24158 33751/33751/24160 +f 33734/33734/24147 33752/33752/24161 33749/33749/24159 +f 33734/33734/24147 33749/33749/24159 33735/33735/24146 +f 33736/33736/24148 33753/33753/24162 33752/33752/24161 +f 33736/33736/24148 33752/33752/24161 33734/33734/24147 +f 33737/33737/24149 33754/33754/24163 33755/33755/24162 +f 33737/33737/24149 33755/33755/24162 33738/33738/24148 +f 33739/33739/24150 33756/33756/24164 33754/33754/24163 +f 33739/33739/24150 33754/33754/24163 33737/33737/24149 +f 33740/33740/24151 33757/33757/24165 33756/33756/24164 +f 33740/33740/24151 33756/33756/24164 33739/33739/24150 +f 33727/33727/24141 33743/33743/24153 33758/33758/24165 +f 33727/33727/24141 33758/33758/24165 33759/33759/24151 +f 33742/33742/24152 33760/33760/24166 33761/33761/24167 +f 33742/33742/24152 33761/33761/24167 33743/33743/24153 +f 33744/33744/24154 33762/33762/24168 33760/33760/24166 +f 33744/33744/24154 33760/33760/24166 33742/33742/24152 +f 33745/33745/24155 33763/33763/24169 33764/33764/24170 +f 33745/33745/24155 33764/33764/24170 33746/33746/24156 +f 33747/33747/24157 33765/33765/24171 33763/33763/24169 +f 33747/33747/24157 33763/33763/24169 33745/33745/24155 +f 33748/33748/24158 33766/33766/24172 33765/33765/24171 +f 33748/33748/24158 33765/33765/24171 33747/33747/24157 +f 33749/33749/24159 33767/33767/24173 33768/33768/24172 +f 33749/33749/24159 33768/33768/24172 33750/33750/24158 +f 33752/33752/24161 33769/33769/24174 33767/33767/24173 +f 33752/33752/24161 33767/33767/24173 33749/33749/24159 +f 33753/33753/24162 33770/33770/24175 33769/33769/24174 +f 33753/33753/24162 33769/33769/24174 33752/33752/24161 +f 33754/33754/24163 33771/33771/24176 33772/33772/24175 +f 33754/33754/24163 33772/33772/24175 33755/33755/24162 +f 33756/33756/24164 33773/33773/24177 33771/33771/24176 +f 33756/33756/24164 33771/33771/24176 33754/33754/24163 +f 33757/33757/24165 33774/33774/24178 33773/33773/24177 +f 33757/33757/24165 33773/33773/24177 33756/33756/24164 +f 33743/33743/24153 33761/33761/24167 33775/33775/24178 +f 33743/33743/24153 33775/33775/24178 33758/33758/24165 +f 33760/33760/24166 33776/33776/24179 33777/33777/24180 +f 33760/33760/24166 33777/33777/24180 33761/33761/24167 +f 33762/33762/24168 33778/33778/24181 33776/33776/24179 +f 33762/33762/24168 33776/33776/24179 33760/33760/24166 +f 33763/33763/24169 33779/33779/24182 33780/33780/24183 +f 33763/33763/24169 33780/33780/24183 33764/33764/24170 +f 33765/33765/24171 33781/33781/24184 33779/33779/24182 +f 33765/33765/24171 33779/33779/24182 33763/33763/24169 +f 33766/33766/24172 33782/33782/24185 33781/33781/24184 +f 33766/33766/24172 33781/33781/24184 33765/33765/24171 +f 33767/33767/24173 33783/33783/24186 33784/33784/24185 +f 33767/33767/24173 33784/33784/24185 33768/33768/24172 +f 33769/33769/24174 33785/33785/24187 33783/33783/24186 +f 33769/33769/24174 33783/33783/24186 33767/33767/24173 +f 33770/33770/24175 33786/33786/24188 33785/33785/24187 +f 33770/33770/24175 33785/33785/24187 33769/33769/24174 +f 33771/33771/24176 33787/33787/24189 33788/33788/24188 +f 33771/33771/24176 33788/33788/24188 33772/33772/24175 +f 33773/33773/24177 33789/33789/24190 33787/33787/24189 +f 33773/33773/24177 33787/33787/24189 33771/33771/24176 +f 33774/33774/24178 33790/33790/24191 33789/33789/24190 +f 33774/33774/24178 33789/33789/24190 33773/33773/24177 +f 33761/33761/24167 33777/33777/24180 33791/33791/24192 +f 33761/33761/24167 33791/33791/24192 33775/33775/24178 +f 33776/33776/24179 33792/33792/24193 33793/33793/24194 +f 33776/33776/24179 33793/33793/24194 33777/33777/24180 +f 33778/33778/24181 33794/33794/24195 33792/33792/24193 +f 33778/33778/24181 33792/33792/24193 33776/33776/24179 +f 33779/33779/24182 33795/33795/24196 33796/33796/24195 +f 33779/33779/24182 33796/33796/24195 33780/33780/24183 +f 33781/33781/24184 33797/33797/24197 33795/33795/24196 +f 33781/33781/24184 33795/33795/24196 33779/33779/24182 +f 33782/33782/24185 33798/33798/24198 33797/33797/24197 +f 33782/33782/24185 33797/33797/24197 33781/33781/24184 +f 33783/33783/24186 33799/33799/24199 33800/33800/24198 +f 33783/33783/24186 33800/33800/24198 33784/33784/24185 +f 33785/33785/24187 33801/33801/24200 33799/33799/24199 +f 33785/33785/24187 33799/33799/24199 33783/33783/24186 +f 33786/33786/24188 33802/33802/24201 33801/33801/24200 +f 33786/33786/24188 33801/33801/24200 33785/33785/24187 +f 33787/33787/24189 33803/33803/24202 33804/33804/24201 +f 33787/33787/24189 33804/33804/24201 33788/33788/24188 +f 33789/33789/24190 33805/33805/24203 33803/33803/24202 +f 33789/33789/24190 33803/33803/24202 33787/33787/24189 +f 33790/33790/24191 33806/33806/24204 33805/33805/24203 +f 33790/33790/24191 33805/33805/24203 33789/33789/24190 +f 33777/33777/24180 33793/33793/24194 33807/33807/24205 +f 33777/33777/24180 33807/33807/24205 33791/33791/24192 +f 33792/33792/24193 33808/33808/24206 33809/33809/24207 +f 33792/33792/24193 33809/33809/24207 33793/33793/24194 +f 33794/33794/24195 33810/33810/24208 33808/33808/24206 +f 33794/33794/24195 33808/33808/24206 33792/33792/24193 +f 33795/33795/24196 33811/33811/24209 33812/33812/24208 +f 33795/33795/24196 33812/33812/24208 33796/33796/24195 +f 33797/33797/24197 33813/33813/24210 33811/33811/24209 +f 33797/33797/24197 33811/33811/24209 33795/33795/24196 +f 33798/33798/24198 33814/33814/24211 33813/33813/24210 +f 33798/33798/24198 33813/33813/24210 33797/33797/24197 +f 33799/33799/24199 33815/33815/24212 33816/33816/24211 +f 33799/33799/24199 33816/33816/24211 33800/33800/24198 +f 33801/33801/24200 33817/33817/24213 33815/33815/24212 +f 33801/33801/24200 33815/33815/24212 33799/33799/24199 +f 33802/33802/24201 33818/33818/24214 33817/33817/24213 +f 33802/33802/24201 33817/33817/24213 33801/33801/24200 +f 33803/33803/24202 33819/33819/24215 33820/33820/24214 +f 33803/33803/24202 33820/33820/24214 33804/33804/24201 +f 33805/33805/24203 33821/33821/24216 33819/33819/24215 +f 33805/33805/24203 33819/33819/24215 33803/33803/24202 +f 33806/33806/24204 33822/33822/24217 33821/33821/24216 +f 33806/33806/24204 33821/33821/24216 33805/33805/24203 +f 33793/33793/24194 33809/33809/24207 33823/33823/24217 +f 33793/33793/24194 33823/33823/24217 33807/33807/24205 +f 33808/33808/24206 33824/33824/24218 33825/33825/24219 +f 33808/33808/24206 33825/33825/24219 33809/33809/24207 +f 33810/33810/24208 33826/33826/24220 33824/33824/24218 +f 33810/33810/24208 33824/33824/24218 33808/33808/24206 +f 33811/33811/24209 33827/33827/24221 33828/33828/24222 +f 33811/33811/24209 33828/33828/24222 33812/33812/24208 +f 33813/33813/24210 33829/33829/24223 33827/33827/24221 +f 33813/33813/24210 33827/33827/24221 33811/33811/24209 +f 33814/33814/24211 33830/33830/24224 33829/33829/24223 +f 33814/33814/24211 33829/33829/24223 33813/33813/24210 +f 33815/33815/24212 33831/33831/24225 33832/33832/24226 +f 33815/33815/24212 33832/33832/24226 33816/33816/24211 +f 33817/33817/24213 33833/33833/24227 33831/33831/24225 +f 33817/33817/24213 33831/33831/24225 33815/33815/24212 +f 33818/33818/24214 33834/33834/24228 33833/33833/24227 +f 33818/33818/24214 33833/33833/24227 33817/33817/24213 +f 33819/33819/24215 33835/33835/24229 33836/33836/24228 +f 33819/33819/24215 33836/33836/24228 33820/33820/24214 +f 33821/33821/24216 33837/33837/24230 33835/33835/24229 +f 33821/33821/24216 33835/33835/24229 33819/33819/24215 +f 33822/33822/24217 33838/33838/24231 33837/33837/24230 +f 33822/33822/24217 33837/33837/24230 33821/33821/24216 +f 33809/33809/24207 33825/33825/24219 33839/33839/24231 +f 33809/33809/24207 33839/33839/24231 33823/33823/24217 +f 33824/33824/24218 33840/33840/24232 33841/33841/24233 +f 33824/33824/24218 33841/33841/24233 33825/33825/24219 +f 33826/33826/24220 33842/33842/24234 33840/33840/24232 +f 33826/33826/24220 33840/33840/24232 33824/33824/24218 +f 33827/33827/24221 33843/33843/24235 33844/33844/24236 +f 33827/33827/24221 33844/33844/24236 33828/33828/24222 +f 33829/33829/24223 33845/33845/24237 33843/33843/24235 +f 33829/33829/24223 33843/33843/24235 33827/33827/24221 +f 33830/33830/24224 33846/33846/24238 33845/33845/24237 +f 33830/33830/24224 33845/33845/24237 33829/33829/24223 +f 33831/33831/24225 33847/33847/24239 33848/33848/24240 +f 33831/33831/24225 33848/33848/24240 33832/33832/24226 +f 33833/33833/24227 33849/33849/24241 33847/33847/24239 +f 33833/33833/24227 33847/33847/24239 33831/33831/24225 +f 33834/33834/24228 33850/33850/24242 33849/33849/24241 +f 33834/33834/24228 33849/33849/24241 33833/33833/24227 +f 33835/33835/24229 33851/33851/24243 33852/33852/24242 +f 33835/33835/24229 33852/33852/24242 33836/33836/24228 +f 33837/33837/24230 33853/33853/24244 33851/33851/24243 +f 33837/33837/24230 33851/33851/24243 33835/33835/24229 +f 33838/33838/24231 33854/33854/24245 33853/33853/24244 +f 33838/33838/24231 33853/33853/24244 33837/33837/24230 +f 33825/33825/24219 33841/33841/24233 33855/33855/24246 +f 33825/33825/24219 33855/33855/24246 33839/33839/24231 +f 33840/33840/24232 33856/33856/24247 33857/33857/24248 +f 33840/33840/24232 33857/33857/24248 33841/33841/24233 +f 33842/33842/24234 33858/33858/24249 33856/33856/24247 +f 33842/33842/24234 33856/33856/24247 33840/33840/24232 +f 33843/33843/24235 33859/33859/24250 33860/33860/24251 +f 33843/33843/24235 33860/33860/24251 33844/33844/24236 +f 33845/33845/24237 33861/33861/24252 33859/33859/24250 +f 33845/33845/24237 33859/33859/24250 33843/33843/24235 +f 33846/33846/24238 33862/33862/24253 33861/33861/24252 +f 33846/33846/24238 33861/33861/24252 33845/33845/24237 +f 33847/33847/24239 33863/33863/24254 33864/33864/24253 +f 33847/33847/24239 33864/33864/24253 33848/33848/24240 +f 33849/33849/24241 33865/33865/24255 33863/33863/24254 +f 33849/33849/24241 33863/33863/24254 33847/33847/24239 +f 33850/33850/24242 33866/33866/24256 33865/33865/24255 +f 33850/33850/24242 33865/33865/24255 33849/33849/24241 +f 33851/33851/24243 33867/33867/24257 33868/33868/24256 +f 33851/33851/24243 33868/33868/24256 33852/33852/24242 +f 33853/33853/24244 33869/33869/24258 33867/33867/24257 +f 33853/33853/24244 33867/33867/24257 33851/33851/24243 +f 33854/33854/24245 33870/33870/24259 33869/33869/24258 +f 33854/33854/24245 33869/33869/24258 33853/33853/24244 +f 33841/33841/24233 33857/33857/24248 33871/33871/24259 +f 33841/33841/24233 33871/33871/24259 33855/33855/24246 +f 33856/33856/24247 33872/33872/24260 33873/33873/24261 +f 33856/33856/24247 33873/33873/24261 33857/33857/24248 +f 33858/33858/24249 33874/33874/24262 33872/33872/24260 +f 33858/33858/24249 33872/33872/24260 33856/33856/24247 +f 33859/33859/24250 33875/33875/24263 33876/33876/24262 +f 33859/33859/24250 33876/33876/24262 33860/33860/24251 +f 33861/33861/24252 33877/33877/24264 33875/33875/24263 +f 33861/33861/24252 33875/33875/24263 33859/33859/24250 +f 33862/33862/24253 33878/33878/24265 33877/33877/24264 +f 33862/33862/24253 33877/33877/24264 33861/33861/24252 +f 33863/33863/24254 33879/33879/24266 33880/33880/24267 +f 33863/33863/24254 33880/33880/24267 33864/33864/24253 +f 33865/33865/24255 33881/33881/24268 33879/33879/24266 +f 33865/33865/24255 33879/33879/24266 33863/33863/24254 +f 33866/33866/24256 33882/33882/24269 33881/33881/24268 +f 33866/33866/24256 33881/33881/24268 33865/33865/24255 +f 33867/33867/24257 33883/33883/24270 33884/33884/24271 +f 33867/33867/24257 33884/33884/24271 33868/33868/24256 +f 33869/33869/24258 33885/33885/24272 33883/33883/24270 +f 33869/33869/24258 33883/33883/24270 33867/33867/24257 +f 33870/33870/24259 33886/33886/24273 33885/33885/24272 +f 33870/33870/24259 33885/33885/24272 33869/33869/24258 +f 33857/33857/24248 33873/33873/24261 33887/33887/24274 +f 33857/33857/24248 33887/33887/24274 33871/33871/24259 +f 33872/33872/24260 33888/33888/24275 33889/33889/24276 +f 33872/33872/24260 33889/33889/24276 33873/33873/24261 +f 33874/33874/24262 33890/33890/24277 33888/33888/24275 +f 33874/33874/24262 33888/33888/24275 33872/33872/24260 +f 33875/33875/24263 33891/33891/24278 33892/33892/24277 +f 33875/33875/24263 33892/33892/24277 33876/33876/24262 +f 33877/33877/24264 33893/33893/24279 33891/33891/24278 +f 33877/33877/24264 33891/33891/24278 33875/33875/24263 +f 33878/33878/24265 33894/33894/24280 33893/33893/24279 +f 33878/33878/24265 33893/33893/24279 33877/33877/24264 +f 33879/33879/24266 33895/33895/24281 33896/33896/24282 +f 33879/33879/24266 33896/33896/24282 33880/33880/24267 +f 33881/33881/24268 33897/33897/24283 33895/33895/24281 +f 33881/33881/24268 33895/33895/24281 33879/33879/24266 +f 33882/33882/24269 33898/33898/24284 33897/33897/24283 +f 33882/33882/24269 33897/33897/24283 33881/33881/24268 +f 33883/33883/24270 33899/33899/24285 33900/33900/24284 +f 33883/33883/24270 33900/33900/24284 33884/33884/24271 +f 33885/33885/24272 33901/33901/24286 33899/33899/24285 +f 33885/33885/24272 33899/33899/24285 33883/33883/24270 +f 33886/33886/24273 33902/33902/24287 33901/33901/24286 +f 33886/33886/24273 33901/33901/24286 33885/33885/24272 +f 33873/33873/24261 33889/33889/24276 33903/33903/24287 +f 33873/33873/24261 33903/33903/24287 33887/33887/24274 +f 33888/33888/24275 33904/33904/24288 33905/33905/24289 +f 33888/33888/24275 33905/33905/24289 33889/33889/24276 +f 33890/33890/24277 33906/33906/24290 33904/33904/24288 +f 33890/33890/24277 33904/33904/24288 33888/33888/24275 +f 33891/33891/24278 33907/33907/24291 33908/33908/24290 +f 33891/33891/24278 33908/33908/24290 33892/33892/24277 +f 33893/33893/24279 33909/33909/24292 33907/33907/24291 +f 33893/33893/24279 33907/33907/24291 33891/33891/24278 +f 33894/33894/24280 33910/33910/24293 33909/33909/24292 +f 33894/33894/24280 33909/33909/24292 33893/33893/24279 +f 33895/33895/24281 33911/33911/24294 33912/33912/24295 +f 33895/33895/24281 33912/33912/24295 33896/33896/24282 +f 33897/33897/24283 33913/33913/24296 33911/33911/24294 +f 33897/33897/24283 33911/33911/24294 33895/33895/24281 +f 33898/33898/24284 33914/33914/24297 33913/33913/24296 +f 33898/33898/24284 33913/33913/24296 33897/33897/24283 +f 33899/33899/24285 33915/33915/24298 33916/33916/24297 +f 33899/33899/24285 33916/33916/24297 33900/33900/24284 +f 33901/33901/24286 33917/33917/24299 33915/33915/24298 +f 33901/33901/24286 33915/33915/24298 33899/33899/24285 +f 33902/33902/24287 33918/33918/24300 33917/33917/24299 +f 33902/33902/24287 33917/33917/24299 33901/33901/24286 +f 33889/33889/24276 33905/33905/24289 33919/33919/24301 +f 33889/33889/24276 33919/33919/24301 33903/33903/24287 +f 33904/33904/24288 33920/33920/24302 33921/33921/24303 +f 33904/33904/24288 33921/33921/24303 33905/33905/24289 +f 33906/33906/24290 33922/33922/24304 33920/33920/24302 +f 33906/33906/24290 33920/33920/24302 33904/33904/24288 +f 33907/33907/24291 33923/33923/24305 33924/33924/24304 +f 33907/33907/24291 33924/33924/24304 33908/33908/24290 +f 33909/33909/24292 33925/33925/24306 33923/33923/24305 +f 33909/33909/24292 33923/33923/24305 33907/33907/24291 +f 33910/33910/24293 33926/33926/24307 33925/33925/24306 +f 33910/33910/24293 33925/33925/24306 33909/33909/24292 +f 33911/33911/24294 33927/33927/24308 33928/33928/24307 +f 33911/33911/24294 33928/33928/24307 33912/33912/24295 +f 33913/33913/24296 33929/33929/24309 33927/33927/24308 +f 33913/33913/24296 33927/33927/24308 33911/33911/24294 +f 33914/33914/24297 33930/33930/24310 33929/33929/24309 +f 33914/33914/24297 33929/33929/24309 33913/33913/24296 +f 33915/33915/24298 33931/33931/24311 33932/33932/24310 +f 33915/33915/24298 33932/33932/24310 33916/33916/24297 +f 33917/33917/24299 33933/33933/24312 33931/33931/24311 +f 33917/33917/24299 33931/33931/24311 33915/33915/24298 +f 33918/33918/24300 33934/33934/24313 33933/33933/24312 +f 33918/33918/24300 33933/33933/24312 33917/33917/24299 +f 33905/33905/24289 33921/33921/24303 33935/33935/24313 +f 33905/33905/24289 33935/33935/24313 33919/33919/24301 +f 33920/33920/24302 33936/33936/24314 33937/33937/24315 +f 33920/33920/24302 33937/33937/24315 33921/33921/24303 +f 33922/33922/24304 33938/33938/24316 33936/33936/24314 +f 33922/33922/24304 33936/33936/24314 33920/33920/24302 +f 33923/33923/24305 33939/33939/24317 33940/33940/24318 +f 33923/33923/24305 33940/33940/24318 33924/33924/24304 +f 33925/33925/24306 33941/33941/24319 33939/33939/24317 +f 33925/33925/24306 33939/33939/24317 33923/33923/24305 +f 33926/33926/24307 33942/33942/24320 33941/33941/24319 +f 33926/33926/24307 33941/33941/24319 33925/33925/24306 +f 33927/33927/24308 33943/33943/24321 33944/33944/24322 +f 33927/33927/24308 33944/33944/24322 33928/33928/24307 +f 33929/33929/24309 33945/33945/24323 33943/33943/24321 +f 33929/33929/24309 33943/33943/24321 33927/33927/24308 +f 33930/33930/24310 33946/33946/24324 33945/33945/24323 +f 33930/33930/24310 33945/33945/24323 33929/33929/24309 +f 33931/33931/24311 33947/33947/24325 33948/33948/24324 +f 33931/33931/24311 33948/33948/24324 33932/33932/24310 +f 33933/33933/24312 33949/33949/24326 33947/33947/24325 +f 33933/33933/24312 33947/33947/24325 33931/33931/24311 +f 33934/33934/24313 33950/33950/24327 33949/33949/24326 +f 33934/33934/24313 33949/33949/24326 33933/33933/24312 +f 33921/33921/24303 33937/33937/24315 33951/33951/24327 +f 33921/33921/24303 33951/33951/24327 33935/33935/24313 +f 33936/33936/24314 33952/33952/24328 33953/33953/24329 +f 33936/33936/24314 33953/33953/24329 33937/33937/24315 +f 33938/33938/24316 33954/33954/24330 33952/33952/24328 +f 33938/33938/24316 33952/33952/24328 33936/33936/24314 +f 33939/33939/24317 33955/33955/24331 33956/33956/24330 +f 33939/33939/24317 33956/33956/24330 33940/33940/24318 +f 33941/33941/24319 33957/33957/24332 33955/33955/24331 +f 33941/33941/24319 33955/33955/24331 33939/33939/24317 +f 33942/33942/24320 33958/33958/24333 33957/33957/24332 +f 33942/33942/24320 33957/33957/24332 33941/33941/24319 +f 33943/33943/24321 33959/33959/24334 33960/33960/24333 +f 33943/33943/24321 33960/33960/24333 33944/33944/24322 +f 33945/33945/24323 33961/33961/24335 33959/33959/24334 +f 33945/33945/24323 33959/33959/24334 33943/33943/24321 +f 33946/33946/24324 33962/33962/24336 33961/33961/24335 +f 33946/33946/24324 33961/33961/24335 33945/33945/24323 +f 33947/33947/24325 33963/33963/24337 33964/33964/24336 +f 33947/33947/24325 33964/33964/24336 33948/33948/24324 +f 33949/33949/24326 33965/33965/24338 33963/33963/24337 +f 33949/33949/24326 33963/33963/24337 33947/33947/24325 +f 33950/33950/24327 33966/33966/24339 33965/33965/24338 +f 33950/33950/24327 33965/33965/24338 33949/33949/24326 +f 33937/33937/24315 33953/33953/24329 33967/33967/24340 +f 33937/33937/24315 33967/33967/24340 33951/33951/24327 +f 33952/33952/24328 33968/33968/24341 33969/33969/24342 +f 33952/33952/24328 33969/33969/24342 33953/33953/24329 +f 33954/33954/24330 33970/33970/24343 33968/33968/24341 +f 33954/33954/24330 33968/33968/24341 33952/33952/24328 +f 33955/33955/24331 33971/33971/24344 33972/33972/24343 +f 33955/33955/24331 33972/33972/24343 33956/33956/24330 +f 33957/33957/24332 33973/33973/24345 33971/33971/24344 +f 33957/33957/24332 33971/33971/24344 33955/33955/24331 +f 33958/33958/24333 33974/33974/24346 33973/33973/24345 +f 33958/33958/24333 33973/33973/24345 33957/33957/24332 +f 33959/33959/24334 33975/33975/24347 33976/33976/24348 +f 33959/33959/24334 33976/33976/24348 33960/33960/24333 +f 33961/33961/24335 33977/33977/24349 33975/33975/24347 +f 33961/33961/24335 33975/33975/24347 33959/33959/24334 +f 33962/33962/24336 33978/33978/24350 33977/33977/24349 +f 33962/33962/24336 33977/33977/24349 33961/33961/24335 +f 33963/33963/24337 33979/33979/24351 33980/33980/24352 +f 33963/33963/24337 33980/33980/24352 33964/33964/24336 +f 33965/33965/24338 33981/33981/24353 33979/33979/24351 +f 33965/33965/24338 33979/33979/24351 33963/33963/24337 +f 33966/33966/24339 33982/33982/24354 33981/33981/24353 +f 33966/33966/24339 33981/33981/24353 33965/33965/24338 +f 33953/33953/24329 33969/33969/24342 33983/33983/24354 +f 33953/33953/24329 33983/33983/24354 33967/33967/24340 +f 33968/33968/24341 33984/33984/24355 33985/33985/24356 +f 33968/33968/24341 33985/33985/24356 33969/33969/24342 +f 33970/33970/24343 33986/33986/24357 33984/33984/24355 +f 33970/33970/24343 33984/33984/24355 33968/33968/24341 +f 33971/33971/24344 33987/33987/24358 33988/33988/24357 +f 33971/33971/24344 33988/33988/24357 33972/33972/24343 +f 33973/33973/24345 33989/33989/24359 33987/33987/24358 +f 33973/33973/24345 33987/33987/24358 33971/33971/24344 +f 33974/33974/24346 33990/33990/24360 33989/33989/24359 +f 33974/33974/24346 33989/33989/24359 33973/33973/24345 +f 33975/33975/24347 33991/33991/24361 33992/33992/24362 +f 33975/33975/24347 33992/33992/24362 33976/33976/24348 +f 33977/33977/24349 33993/33993/24363 33991/33991/24361 +f 33977/33977/24349 33991/33991/24361 33975/33975/24347 +f 33978/33978/24350 33994/33994/24364 33993/33993/24363 +f 33978/33978/24350 33993/33993/24363 33977/33977/24349 +f 33979/33979/24351 33995/33995/24365 33996/33996/24364 +f 33979/33979/24351 33996/33996/24364 33980/33980/24352 +f 33981/33981/24353 33997/33997/24366 33995/33995/24365 +f 33981/33981/24353 33995/33995/24365 33979/33979/24351 +f 33982/33982/24354 33998/33998/24367 33997/33997/24366 +f 33982/33982/24354 33997/33997/24366 33981/33981/24353 +f 33969/33969/24342 33985/33985/24356 33999/33999/24368 +f 33969/33969/24342 33999/33999/24368 33983/33983/24354 +f 33984/33984/24355 34000/34000/24369 34001/34001/24370 +f 33984/33984/24355 34001/34001/24370 33985/33985/24356 +f 33986/33986/24357 34002/34002/24371 34000/34000/24369 +f 33986/33986/24357 34000/34000/24369 33984/33984/24355 +f 33987/33987/24358 34003/34003/24372 34004/34004/24371 +f 33987/33987/24358 34004/34004/24371 33988/33988/24357 +f 33989/33989/24359 34005/34005/24373 34003/34003/24372 +f 33989/33989/24359 34003/34003/24372 33987/33987/24358 +f 33990/33990/24360 34006/34006/24374 34005/34005/24373 +f 33990/33990/24360 34005/34005/24373 33989/33989/24359 +f 33991/33991/24361 34007/34007/24375 34008/34008/24374 +f 33991/33991/24361 34008/34008/24374 33992/33992/24362 +f 33993/33993/24363 34009/34009/24376 34007/34007/24375 +f 33993/33993/24363 34007/34007/24375 33991/33991/24361 +f 33994/33994/24364 34010/34010/24377 34009/34009/24376 +f 33994/33994/24364 34009/34009/24376 33993/33993/24363 +f 33995/33995/24365 34011/34011/24378 34012/34012/24377 +f 33995/33995/24365 34012/34012/24377 33996/33996/24364 +f 33997/33997/24366 34013/34013/24379 34011/34011/24378 +f 33997/33997/24366 34011/34011/24378 33995/33995/24365 +f 33998/33998/24367 34014/34014/24380 34013/34013/24379 +f 33998/33998/24367 34013/34013/24379 33997/33997/24366 +f 33985/33985/24356 34001/34001/24370 34015/34015/24381 +f 33985/33985/24356 34015/34015/24381 33999/33999/24368 +f 34000/34000/24369 34016/34016/24382 34017/34017/24383 +f 34000/34000/24369 34017/34017/24383 34001/34001/24370 +f 34002/34002/24371 34018/34018/24384 34016/34016/24382 +f 34002/34002/24371 34016/34016/24382 34000/34000/24369 +f 34003/34003/24372 34019/34019/24385 34020/34020/24384 +f 34003/34003/24372 34020/34020/24384 34004/34004/24371 +f 34005/34005/24373 34021/34021/24386 34019/34019/24385 +f 34005/34005/24373 34019/34019/24385 34003/34003/24372 +f 34006/34006/24374 34022/34022/24387 34021/34021/24386 +f 34006/34006/24374 34021/34021/24386 34005/34005/24373 +f 34007/34007/24375 34023/34023/24388 34024/34024/24389 +f 34007/34007/24375 34024/34024/24389 34008/34008/24374 +f 34009/34009/24376 34025/34025/24390 34023/34023/24388 +f 34009/34009/24376 34023/34023/24388 34007/34007/24375 +f 34010/34010/24377 34026/34026/24391 34025/34025/24390 +f 34010/34010/24377 34025/34025/24390 34009/34009/24376 +f 34011/34011/24378 34027/34027/24392 34028/34028/24393 +f 34011/34011/24378 34028/34028/24393 34012/34012/24377 +f 34013/34013/24379 34029/34029/24394 34027/34027/24392 +f 34013/34013/24379 34027/34027/24392 34011/34011/24378 +f 34014/34014/24380 34030/34030/24395 34029/34029/24394 +f 34014/34014/24380 34029/34029/24394 34013/34013/24379 +f 34001/34001/24370 34017/34017/24383 34031/34031/24395 +f 34001/34001/24370 34031/34031/24395 34015/34015/24381 +f 34016/34016/24382 34032/34032/24396 34033/34033/24397 +f 34016/34016/24382 34033/34033/24397 34017/34017/24383 +f 34018/34018/24384 34034/34034/24398 34032/34032/24396 +f 34018/34018/24384 34032/34032/24396 34016/34016/24382 +f 34019/34019/24385 34035/34035/24399 34036/34036/24398 +f 34019/34019/24385 34036/34036/24398 34020/34020/24384 +f 34021/34021/24386 34037/34037/24400 34035/34035/24399 +f 34021/34021/24386 34035/34035/24399 34019/34019/24385 +f 34022/34022/24387 34038/34038/24401 34037/34037/24400 +f 34022/34022/24387 34037/34037/24400 34021/34021/24386 +f 34023/34023/24388 34039/34039/24402 34040/34040/24401 +f 34023/34023/24388 34040/34040/24401 34024/34024/24389 +f 34025/34025/24390 34041/34041/24403 34039/34039/24402 +f 34025/34025/24390 34039/34039/24402 34023/34023/24388 +f 34026/34026/24391 34042/34042/24404 34041/34041/24403 +f 34026/34026/24391 34041/34041/24403 34025/34025/24390 +f 34027/34027/24392 34043/34043/24405 34044/34044/24404 +f 34027/34027/24392 34044/34044/24404 34028/34028/24393 +f 34029/34029/24394 34045/34045/24406 34043/34043/24405 +f 34029/34029/24394 34043/34043/24405 34027/34027/24392 +f 34030/34030/24395 34046/34046/24407 34045/34045/24406 +f 34030/34030/24395 34045/34045/24406 34029/34029/24394 +f 34017/34017/24383 34033/34033/24397 34047/34047/24408 +f 34017/34017/24383 34047/34047/24408 34031/34031/24395 +f 34032/34032/24396 34048/34048/24409 34049/34049/24410 +f 34032/34032/24396 34049/34049/24410 34033/34033/24397 +f 34034/34034/24398 34050/34050/24411 34048/34048/24409 +f 34034/34034/24398 34048/34048/24409 34032/34032/24396 +f 34035/34035/24399 34051/34051/24412 34052/34052/24411 +f 34035/34035/24399 34052/34052/24411 34036/34036/24398 +f 34037/34037/24400 34053/34053/24413 34051/34051/24412 +f 34037/34037/24400 34051/34051/24412 34035/34035/24399 +f 34038/34038/24401 34054/34054/24414 34053/34053/24413 +f 34038/34038/24401 34053/34053/24413 34037/34037/24400 +f 34039/34039/24402 34055/34055/24415 34056/34056/24414 +f 34039/34039/24402 34056/34056/24414 34040/34040/24401 +f 34041/34041/24403 34057/34057/24416 34055/34055/24415 +f 34041/34041/24403 34055/34055/24415 34039/34039/24402 +f 34042/34042/24404 34058/34058/24417 34057/34057/24416 +f 34042/34042/24404 34057/34057/24416 34041/34041/24403 +f 34043/34043/24405 34059/34059/24418 34060/34060/24419 +f 34043/34043/24405 34060/34060/24419 34044/34044/24404 +f 34045/34045/24406 34061/34061/24420 34059/34059/24418 +f 34045/34045/24406 34059/34059/24418 34043/34043/24405 +f 34046/34046/24407 34062/34062/24421 34061/34061/24420 +f 34046/34046/24407 34061/34061/24420 34045/34045/24406 +f 34033/34033/24397 34049/34049/24410 34063/34063/24421 +f 34033/34033/24397 34063/34063/24421 34047/34047/24408 +f 34048/34048/24409 34064/34064/24422 34065/34065/24423 +f 34048/34048/24409 34065/34065/24423 34049/34049/24410 +f 34050/34050/24411 34066/34066/24424 34064/34064/24422 +f 34050/34050/24411 34064/34064/24422 34048/34048/24409 +f 34051/34051/24412 34067/34067/24425 34068/34068/24424 +f 34051/34051/24412 34068/34068/24424 34052/34052/24411 +f 34053/34053/24413 34069/34069/24426 34067/34067/24425 +f 34053/34053/24413 34067/34067/24425 34051/34051/24412 +f 34054/34054/24414 34070/34070/24427 34069/34069/24426 +f 34054/34054/24414 34069/34069/24426 34053/34053/24413 +f 34055/34055/24415 34071/34071/24428 34072/34072/24427 +f 34055/34055/24415 34072/34072/24427 34056/34056/24414 +f 34057/34057/24416 34073/34073/24429 34071/34071/24428 +f 34057/34057/24416 34071/34071/24428 34055/34055/24415 +f 34058/34058/24417 34074/34074/24430 34073/34073/24429 +f 34058/34058/24417 34073/34073/24429 34057/34057/24416 +f 34059/34059/24418 34075/34075/24431 34076/34076/24430 +f 34059/34059/24418 34076/34076/24430 34060/34060/24419 +f 34061/34061/24420 34077/34077/24432 34075/34075/24431 +f 34061/34061/24420 34075/34075/24431 34059/34059/24418 +f 34062/34062/24421 34078/34078/24433 34077/34077/24432 +f 34062/34062/24421 34077/34077/24432 34061/34061/24420 +f 34049/34049/24410 34065/34065/24423 34079/34079/24434 +f 34049/34049/24410 34079/34079/24434 34063/34063/24421 +f 34064/34064/24422 34080/34080/24435 34081/34081/24436 +f 34064/34064/24422 34081/34081/24436 34065/34065/24423 +f 34066/34066/24424 34082/34082/24437 34080/34080/24435 +f 34066/34066/24424 34080/34080/24435 34064/34064/24422 +f 34067/34067/24425 34083/34083/24438 34084/34084/24437 +f 34067/34067/24425 34084/34084/24437 34068/34068/24424 +f 34069/34069/24426 34085/34085/24439 34083/34083/24438 +f 34069/34069/24426 34083/34083/24438 34067/34067/24425 +f 34070/34070/24427 34086/34086/24440 34085/34085/24439 +f 34070/34070/24427 34085/34085/24439 34069/34069/24426 +f 34071/34071/24428 34087/34087/24441 34088/34088/24442 +f 34071/34071/24428 34088/34088/24442 34072/34072/24427 +f 34073/34073/24429 34089/34089/24443 34087/34087/24441 +f 34073/34073/24429 34087/34087/24441 34071/34071/24428 +f 34074/34074/24430 34090/34090/24444 34089/34089/24443 +f 34074/34074/24430 34089/34089/24443 34073/34073/24429 +f 34075/34075/24431 34091/34091/24445 34092/34092/24444 +f 34075/34075/24431 34092/34092/24444 34076/34076/24430 +f 34077/34077/24432 34093/34093/24446 34091/34091/24445 +f 34077/34077/24432 34091/34091/24445 34075/34075/24431 +f 34078/34078/24433 34094/34094/24447 34093/34093/24446 +f 34078/34078/24433 34093/34093/24446 34077/34077/24432 +f 34065/34065/24423 34081/34081/24436 34095/34095/24447 +f 34065/34065/24423 34095/34095/24447 34079/34079/24434 +f 34080/34080/24435 34096/34096/24448 34097/34097/24449 +f 34080/34080/24435 34097/34097/24449 34081/34081/24436 +f 34082/34082/24437 34098/34098/24450 34096/34096/24448 +f 34082/34082/24437 34096/34096/24448 34080/34080/24435 +f 34083/34083/24438 34099/34099/24451 34100/34100/24450 +f 34083/34083/24438 34100/34100/24450 34084/34084/24437 +f 34085/34085/24439 34101/34101/24452 34099/34099/24451 +f 34085/34085/24439 34099/34099/24451 34083/34083/24438 +f 34086/34086/24440 34102/34102/24453 34101/34101/24452 +f 34086/34086/24440 34101/34101/24452 34085/34085/24439 +f 34087/34087/24441 34103/34103/24454 34104/34104/24453 +f 34087/34087/24441 34104/34104/24453 34088/34088/24442 +f 34089/34089/24443 34105/34105/24455 34103/34103/24454 +f 34089/34089/24443 34103/34103/24454 34087/34087/24441 +f 34090/34090/24444 34106/34106/24456 34105/34105/24455 +f 34090/34090/24444 34105/34105/24455 34089/34089/24443 +f 34091/34091/24445 34107/34107/24457 34108/34108/24456 +f 34091/34091/24445 34108/34108/24456 34092/34092/24444 +f 34093/34093/24446 34109/34109/24458 34107/34107/24457 +f 34093/34093/24446 34107/34107/24457 34091/34091/24445 +f 34094/34094/24447 34110/34110/24459 34109/34109/24458 +f 34094/34094/24447 34109/34109/24458 34093/34093/24446 +f 34081/34081/24436 34097/34097/24449 34111/34111/24459 +f 34081/34081/24436 34111/34111/24459 34095/34095/24447 +f 34096/34096/24448 34112/34112/24460 34113/34113/24461 +f 34096/34096/24448 34113/34113/24461 34097/34097/24449 +f 34098/34098/24450 34114/34114/24462 34112/34112/24460 +f 34098/34098/24450 34112/34112/24460 34096/34096/24448 +f 34099/34099/24451 34115/34115/24463 34116/34116/24462 +f 34099/34099/24451 34116/34116/24462 34100/34100/24450 +f 34101/34101/24452 34117/34117/24464 34115/34115/24463 +f 34101/34101/24452 34115/34115/24463 34099/34099/24451 +f 34102/34102/24453 34118/34118/24465 34117/34117/24464 +f 34102/34102/24453 34117/34117/24464 34101/34101/24452 +f 34103/34103/24454 34119/34119/24466 34120/34120/24467 +f 34103/34103/24454 34120/34120/24467 34104/34104/24453 +f 34105/34105/24455 34121/34121/24468 34119/34119/24466 +f 34105/34105/24455 34119/34119/24466 34103/34103/24454 +f 34106/34106/24456 34122/34122/24469 34121/34121/24468 +f 34106/34106/24456 34121/34121/24468 34105/34105/24455 +f 34107/34107/24457 34123/34123/24470 34124/34124/24471 +f 34107/34107/24457 34124/34124/24471 34108/34108/24456 +f 34109/34109/24458 34125/34125/24472 34123/34123/24470 +f 34109/34109/24458 34123/34123/24470 34107/34107/24457 +f 34110/34110/24459 34126/34126/24473 34125/34125/24472 +f 34110/34110/24459 34125/34125/24472 34109/34109/24458 +f 34097/34097/24449 34113/34113/24461 34127/34127/24473 +f 34097/34097/24449 34127/34127/24473 34111/34111/24459 +f 34112/34112/24460 34128/34128/24474 34129/34129/24475 +f 34112/34112/24460 34129/34129/24475 34113/34113/24461 +f 34114/34114/24462 34130/34130/24476 34128/34128/24474 +f 34114/34114/24462 34128/34128/24474 34112/34112/24460 +f 34115/34115/24463 34131/34131/24477 34132/34132/24476 +f 34115/34115/24463 34132/34132/24476 34116/34116/24462 +f 34117/34117/24464 34133/34133/24478 34131/34131/24477 +f 34117/34117/24464 34131/34131/24477 34115/34115/24463 +f 34118/34118/24465 34134/34134/24479 34133/34133/24478 +f 34118/34118/24465 34133/34133/24478 34117/34117/24464 +f 34119/34119/24466 34135/34135/24480 34136/34136/24479 +f 34119/34119/24466 34136/34136/24479 34120/34120/24467 +f 34121/34121/24468 34137/34137/24481 34135/34135/24480 +f 34121/34121/24468 34135/34135/24480 34119/34119/24466 +f 34122/34122/24469 34138/34138/24482 34137/34137/24481 +f 34122/34122/24469 34137/34137/24481 34121/34121/24468 +f 34123/34123/24470 34139/34139/24483 34140/34140/24482 +f 34123/34123/24470 34140/34140/24482 34124/34124/24471 +f 34125/34125/24472 34141/34141/24484 34139/34139/24483 +f 34125/34125/24472 34139/34139/24483 34123/34123/24470 +f 34126/34126/24473 34142/34142/24485 34141/34141/24484 +f 34126/34126/24473 34141/34141/24484 34125/34125/24472 +f 34113/34113/24461 34129/34129/24475 34143/34143/24485 +f 34113/34113/24461 34143/34143/24485 34127/34127/24473 +f 34128/34128/24474 34144/34144/24486 34145/34145/24487 +f 34128/34128/24474 34145/34145/24487 34129/34129/24475 +f 34130/34130/24476 34146/34146/24488 34144/34144/24486 +f 34130/34130/24476 34144/34144/24486 34128/34128/24474 +f 34131/34131/24477 34147/34147/24489 34148/34148/24488 +f 34131/34131/24477 34148/34148/24488 34132/34132/24476 +f 34133/34133/24478 34149/34149/24490 34147/34147/24489 +f 34133/34133/24478 34147/34147/24489 34131/34131/24477 +f 34134/34134/24479 34150/34150/24491 34149/34149/24490 +f 34134/34134/24479 34149/34149/24490 34133/34133/24478 +f 34135/34135/24480 34151/34151/24492 34152/34152/24491 +f 34135/34135/24480 34152/34152/24491 34136/34136/24479 +f 34137/34137/24481 34153/34153/24493 34151/34151/24492 +f 34137/34137/24481 34151/34151/24492 34135/34135/24480 +f 34138/34138/24482 34154/34154/24494 34153/34153/24493 +f 34138/34138/24482 34153/34153/24493 34137/34137/24481 +f 34139/34139/24483 34155/34155/24495 34156/34156/24494 +f 34139/34139/24483 34156/34156/24494 34140/34140/24482 +f 34141/34141/24484 34157/34157/24496 34155/34155/24495 +f 34141/34141/24484 34155/34155/24495 34139/34139/24483 +f 34142/34142/24485 34158/34158/24497 34157/34157/24496 +f 34142/34142/24485 34157/34157/24496 34141/34141/24484 +f 34129/34129/24475 34145/34145/24487 34159/34159/24498 +f 34129/34129/24475 34159/34159/24498 34143/34143/24485 +f 34144/34144/24486 34160/34160/24499 34161/34161/24500 +f 34144/34144/24486 34161/34161/24500 34145/34145/24487 +f 34146/34146/24488 34162/34162/24501 34160/34160/24499 +f 34146/34146/24488 34160/34160/24499 34144/34144/24486 +f 34147/34147/24489 34163/34163/24502 34164/34164/24501 +f 34147/34147/24489 34164/34164/24501 34148/34148/24488 +f 34149/34149/24490 34165/34165/24503 34163/34163/24502 +f 34149/34149/24490 34163/34163/24502 34147/34147/24489 +f 34150/34150/24491 34166/34166/24504 34165/34165/24503 +f 34150/34150/24491 34165/34165/24503 34149/34149/24490 +f 34151/34151/24492 34167/34167/24505 34168/34168/24504 +f 34151/34151/24492 34168/34168/24504 34152/34152/24491 +f 34153/34153/24493 34169/34169/24506 34167/34167/24505 +f 34153/34153/24493 34167/34167/24505 34151/34151/24492 +f 34154/34154/24494 34170/34170/24507 34169/34169/24506 +f 34154/34154/24494 34169/34169/24506 34153/34153/24493 +f 34155/34155/24495 34171/34171/24508 34172/34172/24507 +f 34155/34155/24495 34172/34172/24507 34156/34156/24494 +f 34157/34157/24496 34173/34173/24509 34171/34171/24508 +f 34157/34157/24496 34171/34171/24508 34155/34155/24495 +f 34158/34158/24497 34174/34174/24510 34173/34173/24509 +f 34158/34158/24497 34173/34173/24509 34157/34157/24496 +f 34145/34145/24487 34161/34161/24500 34175/34175/24511 +f 34145/34145/24487 34175/34175/24511 34159/34159/24498 +f 34160/34160/24499 34176/34176/24512 34177/34177/24513 +f 34160/34160/24499 34177/34177/24513 34161/34161/24500 +f 34162/34162/24501 34178/34178/24514 34176/34176/24512 +f 34162/34162/24501 34176/34176/24512 34160/34160/24499 +f 34163/34163/24502 34179/34179/24515 34180/34180/24514 +f 34163/34163/24502 34180/34180/24514 34164/34164/24501 +f 34165/34165/24503 34181/34181/24516 34179/34179/24515 +f 34165/34165/24503 34179/34179/24515 34163/34163/24502 +f 34182/34182/24504 34183/34183/24517 34184/34184/24516 +f 34182/34182/24504 34184/34184/24516 34185/34185/24503 +f 34186/34186/24505 34187/34187/24518 34183/34183/24517 +f 34186/34186/24505 34183/34183/24517 34182/34182/24504 +f 34169/34169/24506 34188/34188/24519 34189/34189/24520 +f 34169/34169/24506 34189/34189/24520 34167/34167/24505 +f 34170/34170/24507 34190/34190/24521 34188/34188/24519 +f 34170/34170/24507 34188/34188/24519 34169/34169/24506 +f 34171/34171/24508 34191/34191/24522 34192/34192/24521 +f 34171/34171/24508 34192/34192/24521 34172/34172/24507 +f 34173/34173/24509 34193/34193/24523 34191/34191/24522 +f 34173/34173/24509 34191/34191/24522 34171/34171/24508 +f 34194/34194/24511 34195/34195/24524 34196/34196/24525 +f 34194/34194/24511 34196/34196/24525 34197/34197/24526 +f 34198/34198/24527 34199/34199/24513 34195/34195/24524 +f 34198/34198/24527 34195/34195/24524 34194/34194/24511 +f 34200/34200/24512 34201/34201/24528 34202/34202/24529 +f 34200/34200/24512 34202/34202/24529 34199/34199/24513 +f 34180/34180/24514 34203/34203/24530 34204/34204/24531 +f 34180/34180/24514 34204/34204/24531 34205/34205/24532 +f 34179/34179/24515 34206/34206/24533 34203/34203/24530 +f 34179/34179/24515 34203/34203/24530 34180/34180/24514 +f 34181/34181/24516 34207/34207/24534 34206/34206/24533 +f 34181/34181/24516 34206/34206/24533 34179/34179/24515 +f 34183/34183/24517 34208/34208/24535 34209/34209/24534 +f 34183/34183/24517 34209/34209/24534 34184/34184/24516 +f 34187/34187/24518 34210/34210/24536 34208/34208/24535 +f 34187/34187/24518 34208/34208/24535 34183/34183/24517 +f 34211/34211/24519 34212/34212/24537 34210/34210/24536 +f 34211/34211/24519 34210/34210/24536 34187/34187/24518 +f 34192/34192/24521 34213/34213/24538 34214/34214/24537 +f 34192/34192/24521 34214/34214/24537 34215/34215/24519 +f 34191/34191/24522 34216/34216/24539 34213/34213/24538 +f 34191/34191/24522 34213/34213/24538 34192/34192/24521 +f 34193/34193/24523 34217/34217/24540 34216/34216/24539 +f 34193/34193/24523 34216/34216/24539 34191/34191/24522 +f 34195/34195/24524 34218/34218/24541 34219/34219/24542 +f 34195/34195/24524 34219/34219/24542 34196/34196/24525 +f 34199/34199/24513 34202/34202/24529 34218/34218/24541 +f 34199/34199/24513 34218/34218/24541 34195/34195/24524 +f 34201/34201/24528 34220/34220/24543 34221/34221/24544 +f 34201/34201/24528 34221/34221/24544 34202/34202/24529 +f 34203/34203/24530 34222/34222/24545 34223/34223/24546 +f 34203/34203/24530 34223/34223/24546 34204/34204/24531 +f 34206/34206/24533 34224/34224/24547 34222/34222/24545 +f 34206/34206/24533 34222/34222/24545 34203/34203/24530 +f 34207/34207/24534 34225/34225/24548 34224/34224/24547 +f 34207/34207/24534 34224/34224/24547 34206/34206/24533 +f 34208/34208/24535 34226/34226/24549 34227/34227/24548 +f 34208/34208/24535 34227/34227/24548 34209/34209/24534 +f 34210/34210/24536 34228/34228/24550 34226/34226/24549 +f 34210/34210/24536 34226/34226/24549 34208/34208/24535 +f 34212/34212/24537 34229/34229/24551 34228/34228/24550 +f 34212/34212/24537 34228/34228/24550 34210/34210/24536 +f 34213/34213/24538 34230/34230/24552 34231/34231/24553 +f 34213/34213/24538 34231/34231/24553 34214/34214/24537 +f 34216/34216/24539 34232/34232/24554 34230/34230/24552 +f 34216/34216/24539 34230/34230/24552 34213/34213/24538 +f 34217/34217/24540 34233/34233/24555 34232/34232/24554 +f 34217/34217/24540 34232/34232/24554 34216/34216/24539 +f 34218/34218/24541 34234/34234/24556 34235/34235/24555 +f 34218/34218/24541 34235/34235/24555 34219/34219/24542 +f 34202/34202/24529 34221/34221/24544 34234/34234/24556 +f 34202/34202/24529 34234/34234/24556 34218/34218/24541 +f 34220/34220/24543 34236/34236/24557 34237/34237/24558 +f 34220/34220/24543 34237/34237/24558 34221/34221/24544 +f 34222/34222/24545 34238/34238/24559 34239/34239/24557 +f 34222/34222/24545 34239/34239/24557 34223/34223/24546 +f 34224/34224/24547 34240/34240/24560 34238/34238/24559 +f 34224/34224/24547 34238/34238/24559 34222/34222/24545 +f 34225/34225/24548 34241/34241/24561 34240/34240/24560 +f 34225/34225/24548 34240/34240/24560 34224/34224/24547 +f 34226/34226/24549 34242/34242/24562 34243/34243/24561 +f 34226/34226/24549 34243/34243/24561 34227/34227/24548 +f 34228/34228/24550 34244/34244/24563 34242/34242/24562 +f 34228/34228/24550 34242/34242/24562 34226/34226/24549 +f 34229/34229/24551 34245/34245/24564 34244/34244/24563 +f 34229/34229/24551 34244/34244/24563 34228/34228/24550 +f 34230/34230/24552 34246/34246/24565 34247/34247/24564 +f 34230/34230/24552 34247/34247/24564 34231/34231/24553 +f 34232/34232/24554 34248/34248/24566 34246/34246/24565 +f 34232/34232/24554 34246/34246/24565 34230/34230/24552 +f 34233/34233/24555 34249/34249/24567 34248/34248/24566 +f 34233/34233/24555 34248/34248/24566 34232/34232/24554 +f 34234/34234/24556 34250/34250/24568 34251/34251/24569 +f 34234/34234/24556 34251/34251/24569 34235/34235/24555 +f 34221/34221/24544 34237/34237/24558 34250/34250/24568 +f 34221/34221/24544 34250/34250/24568 34234/34234/24556 +f 34239/34239/24557 34252/34252/24570 34253/34253/24571 +f 34239/34239/24557 34253/34253/24571 34254/34254/24572 +f 34238/34238/24559 34255/34255/24573 34252/34252/24570 +f 34238/34238/24559 34252/34252/24570 34239/34239/24557 +f 34240/34240/24560 34256/34256/24574 34255/34255/24573 +f 34240/34240/24560 34255/34255/24573 34238/34238/24559 +f 34257/34257/24561 34258/34258/24575 34259/34259/24576 +f 34257/34257/24561 34259/34259/24576 34260/34260/24560 +f 34242/34242/24562 34261/34261/24577 34262/34262/24578 +f 34242/34242/24562 34262/34262/24578 34243/34243/24561 +f 34244/34244/24563 34263/34263/24579 34261/34261/24577 +f 34244/34244/24563 34261/34261/24577 34242/34242/24562 +f 34247/34247/24564 34264/34264/24580 34265/34265/24579 +f 34247/34247/24564 34265/34265/24579 34266/34266/24563 +f 34246/34246/24565 34267/34267/24581 34264/34264/24580 +f 34246/34246/24565 34264/34264/24580 34247/34247/24564 +f 34248/34248/24566 34268/34268/24582 34267/34267/24581 +f 34248/34248/24566 34267/34267/24581 34246/34246/24565 +f 34249/34249/24567 34269/34269/24583 34268/34268/24582 +f 34249/34249/24567 34268/34268/24582 34248/34248/24566 +f 34250/34250/24568 34270/34270/24584 34271/34271/24585 +f 34250/34250/24568 34271/34271/24585 34251/34251/24569 +f 34237/34237/24558 34272/34272/24571 34270/34270/24584 +f 34237/34237/24558 34270/34270/24584 34250/34250/24568 +f 34252/34252/24570 34273/34273/24586 34274/34274/24587 +f 34252/34252/24570 34274/34274/24587 34253/34253/24571 +f 34255/34255/24573 34275/34275/24588 34273/34273/24586 +f 34255/34255/24573 34273/34273/24586 34252/34252/24570 +f 34256/34256/24574 34276/34276/24589 34275/34275/24588 +f 34256/34256/24574 34275/34275/24588 34255/34255/24573 +f 34258/34258/24575 34277/34277/24590 34278/34278/24589 +f 34258/34258/24575 34278/34278/24589 34259/34259/24576 +f 34279/34279/24577 34280/34280/24591 34277/34277/24590 +f 34279/34279/24577 34277/34277/24590 34258/34258/24575 +f 34263/34263/24579 34281/34281/24592 34282/34282/24591 +f 34263/34263/24579 34282/34282/24591 34261/34261/24577 +f 34264/34264/24580 34283/34283/24593 34284/34284/24592 +f 34264/34264/24580 34284/34284/24592 34265/34265/24579 +f 34267/34267/24581 34285/34285/24594 34283/34283/24593 +f 34267/34267/24581 34283/34283/24593 34264/34264/24580 +f 34268/34268/24582 34286/34286/24595 34285/34285/24594 +f 34268/34268/24582 34285/34285/24594 34267/34267/24581 +f 34287/34287/24585 34288/34288/24596 34289/34289/24595 +f 34287/34287/24585 34289/34289/24595 34290/34290/24582 +f 34291/34291/24584 34292/34292/24597 34288/34288/24596 +f 34291/34291/24584 34288/34288/24596 34287/34287/24585 +f 34272/34272/24571 34293/34293/24598 34294/34294/24597 +f 34272/34272/24571 34294/34294/24597 34270/34270/24584 +f 34273/34273/24586 34295/34295/24599 34296/34296/24600 +f 34273/34273/24586 34296/34296/24600 34274/34274/24587 +f 34275/34275/24588 34297/34297/24601 34295/34295/24599 +f 34275/34275/24588 34295/34295/24599 34273/34273/24586 +f 34276/34276/24589 34298/34298/24602 34297/34297/24601 +f 34276/34276/24589 34297/34297/24601 34275/34275/24588 +f 34277/34277/24590 34299/34299/24603 34300/34300/24602 +f 34277/34277/24590 34300/34300/24602 34278/34278/24589 +f 34280/34280/24591 34301/34301/24604 34299/34299/24603 +f 34280/34280/24591 34299/34299/24603 34277/34277/24590 +f 34302/34302/24592 34303/34303/24605 34301/34301/24604 +f 34302/34302/24592 34301/34301/24604 34280/34280/24591 +f 34283/34283/24593 34304/34304/24606 34305/34305/24605 +f 34283/34283/24593 34305/34305/24605 34284/34284/24592 +f 34285/34285/24594 34306/34306/24607 34304/34304/24606 +f 34285/34285/24594 34304/34304/24606 34283/34283/24593 +f 34286/34286/24595 34307/34307/24608 34306/34306/24607 +f 34286/34286/24595 34306/34306/24607 34285/34285/24594 +f 34288/34288/24596 34308/34308/24609 34309/34309/24608 +f 34288/34288/24596 34309/34309/24608 34289/34289/24595 +f 34292/34292/24597 34310/34310/24610 34308/34308/24609 +f 34292/34292/24597 34308/34308/24609 34288/34288/24596 +f 34311/34311/24587 34312/34312/24600 34310/34310/24610 +f 34311/34311/24587 34310/34310/24610 34292/34292/24597 +f 34295/34295/24599 34313/34313/24611 34314/34314/24612 +f 34295/34295/24599 34314/34314/24612 34296/34296/24600 +f 34297/34297/24601 34315/34315/24613 34313/34313/24611 +f 34297/34297/24601 34313/34313/24611 34295/34295/24599 +f 34298/34298/24602 34316/34316/24614 34315/34315/24613 +f 34298/34298/24602 34315/34315/24613 34297/34297/24601 +f 34299/34299/24603 34317/34317/24615 34318/34318/24616 +f 34299/34299/24603 34318/34318/24616 34300/34300/24602 +f 34301/34301/24604 34319/34319/24617 34317/34317/24615 +f 34301/34301/24604 34317/34317/24615 34299/34299/24603 +f 34303/34303/24605 34320/34320/24618 34319/34319/24617 +f 34303/34303/24605 34319/34319/24617 34301/34301/24604 +f 34304/34304/24606 34321/34321/24619 34322/34322/24620 +f 34304/34304/24606 34322/34322/24620 34305/34305/24605 +f 34306/34306/24607 34323/34323/24621 34321/34321/24619 +f 34306/34306/24607 34321/34321/24619 34304/34304/24606 +f 34307/34307/24608 34324/34324/24622 34323/34323/24621 +f 34307/34307/24608 34323/34323/24621 34306/34306/24607 +f 34308/34308/24609 34325/34325/24623 34326/34326/24622 +f 34308/34308/24609 34326/34326/24622 34309/34309/24608 +f 34310/34310/24610 34327/34327/24624 34325/34325/24623 +f 34310/34310/24610 34325/34325/24623 34308/34308/24609 +f 34312/34312/24600 34328/34328/24612 34327/34327/24624 +f 34312/34312/24600 34327/34327/24624 34310/34310/24610 +f 34313/34313/24611 34329/34329/24625 34330/34330/24626 +f 34313/34313/24611 34330/34330/24626 34314/34314/24612 +f 34315/34315/24613 34331/34331/24627 34329/34329/24625 +f 34315/34315/24613 34329/34329/24625 34313/34313/24611 +f 34316/34316/24614 34332/34332/24628 34331/34331/24627 +f 34316/34316/24614 34331/34331/24627 34315/34315/24613 +f 34317/34317/24615 34333/34333/24629 34334/34334/24630 +f 34317/34317/24615 34334/34334/24630 34318/34318/24616 +f 34319/34319/24617 34335/34335/24631 34333/34333/24629 +f 34319/34319/24617 34333/34333/24629 34317/34317/24615 +f 34320/34320/24618 34336/34336/24632 34335/34335/24631 +f 34320/34320/24618 34335/34335/24631 34319/34319/24617 +f 34321/34321/24619 34337/34337/24633 34338/34338/24632 +f 34321/34321/24619 34338/34338/24632 34322/34322/24620 +f 34323/34323/24621 34339/34339/24634 34337/34337/24633 +f 34323/34323/24621 34337/34337/24633 34321/34321/24619 +f 34324/34324/24622 34340/34340/24635 34339/34339/24634 +f 34324/34324/24622 34339/34339/24634 34323/34323/24621 +f 34325/34325/24623 34341/34341/24636 34342/34342/24635 +f 34325/34325/24623 34342/34342/24635 34326/34326/24622 +f 34327/34327/24624 34343/34343/24637 34341/34341/24636 +f 34327/34327/24624 34341/34341/24636 34325/34325/24623 +f 34328/34328/24612 34344/34344/24626 34343/34343/24637 +f 34328/34328/24612 34343/34343/24637 34327/34327/24624 +f 34329/34329/24625 34345/34345/24638 34346/34346/24639 +f 34329/34329/24625 34346/34346/24639 34330/34330/24626 +f 34331/34331/24627 34347/34347/24640 34345/34345/24638 +f 34331/34331/24627 34345/34345/24638 34329/34329/24625 +f 34332/34332/24628 34348/34348/24641 34347/34347/24640 +f 34332/34332/24628 34347/34347/24640 34331/34331/24627 +f 34333/34333/24629 34349/34349/24642 34350/34350/24641 +f 34333/34333/24629 34350/34350/24641 34334/34334/24630 +f 34335/34335/24631 34351/34351/24643 34349/34349/24642 +f 34335/34335/24631 34349/34349/24642 34333/34333/24629 +f 34336/34336/24632 34352/34352/24644 34351/34351/24643 +f 34336/34336/24632 34351/34351/24643 34335/34335/24631 +f 34337/34337/24633 34353/34353/24645 34354/34354/24644 +f 34337/34337/24633 34354/34354/24644 34338/34338/24632 +f 34339/34339/24634 34355/34355/24646 34353/34353/24645 +f 34339/34339/24634 34353/34353/24645 34337/34337/24633 +f 34340/34340/24635 34356/34356/24647 34355/34355/24646 +f 34340/34340/24635 34355/34355/24646 34339/34339/24634 +f 34341/34341/24636 34357/34357/24648 34358/34358/24649 +f 34341/34341/24636 34358/34358/24649 34342/34342/24635 +f 34343/34343/24637 34359/34359/24650 34357/34357/24648 +f 34343/34343/24637 34357/34357/24648 34341/34341/24636 +f 34344/34344/24626 34360/34360/24639 34359/34359/24650 +f 34344/34344/24626 34359/34359/24650 34343/34343/24637 +f 34345/34345/24638 34361/34361/24651 34362/34362/24652 +f 34345/34345/24638 34362/34362/24652 34346/34346/24639 +f 34347/34347/24640 34363/34363/24653 34361/34361/24651 +f 34347/34347/24640 34361/34361/24651 34345/34345/24638 +f 34348/34348/24641 34364/34364/24654 34363/34363/24653 +f 34348/34348/24641 34363/34363/24653 34347/34347/24640 +f 34349/34349/24642 34365/34365/24655 34366/34366/24654 +f 34349/34349/24642 34366/34366/24654 34350/34350/24641 +f 34351/34351/24643 34367/34367/24656 34365/34365/24655 +f 34351/34351/24643 34365/34365/24655 34349/34349/24642 +f 34352/34352/24644 34368/34368/24657 34367/34367/24656 +f 34352/34352/24644 34367/34367/24656 34351/34351/24643 +f 34353/34353/24645 34369/34369/24658 34370/34370/24659 +f 34353/34353/24645 34370/34370/24659 34354/34354/24644 +f 34355/34355/24646 34371/34371/24660 34369/34369/24658 +f 34355/34355/24646 34369/34369/24658 34353/34353/24645 +f 34356/34356/24647 34372/34372/24661 34371/34371/24660 +f 34356/34356/24647 34371/34371/24660 34355/34355/24646 +f 34357/34357/24648 34373/34373/24662 34374/34374/24661 +f 34357/34357/24648 34374/34374/24661 34358/34358/24649 +f 34359/34359/24650 34375/34375/24663 34373/34373/24662 +f 34359/34359/24650 34373/34373/24662 34357/34357/24648 +f 34360/34360/24639 34376/34376/24664 34375/34375/24663 +f 34360/34360/24639 34375/34375/24663 34359/34359/24650 +f 34361/34361/24651 34377/34377/24665 34378/34378/24666 +f 34361/34361/24651 34378/34378/24666 34362/34362/24652 +f 34363/34363/24653 34379/34379/24667 34377/34377/24665 +f 34363/34363/24653 34377/34377/24665 34361/34361/24651 +f 34364/34364/24654 34380/34380/24668 34379/34379/24667 +f 34364/34364/24654 34379/34379/24667 34363/34363/24653 +f 34365/34365/24655 34381/34381/24669 34382/34382/24668 +f 34365/34365/24655 34382/34382/24668 34366/34366/24654 +f 34367/34367/24656 34383/34383/24670 34381/34381/24669 +f 34367/34367/24656 34381/34381/24669 34365/34365/24655 +f 34368/34368/24657 34384/34384/24671 34383/34383/24670 +f 34368/34368/24657 34383/34383/24670 34367/34367/24656 +f 34369/34369/24658 34385/34385/24672 34386/34386/24673 +f 34369/34369/24658 34386/34386/24673 34370/34370/24659 +f 34371/34371/24660 34387/34387/24674 34385/34385/24672 +f 34371/34371/24660 34385/34385/24672 34369/34369/24658 +f 34372/34372/24661 34388/34388/24675 34387/34387/24674 +f 34372/34372/24661 34387/34387/24674 34371/34371/24660 +f 34373/34373/24662 34389/34389/24676 34390/34390/24675 +f 34373/34373/24662 34390/34390/24675 34374/34374/24661 +f 34375/34375/24663 34391/34391/24677 34389/34389/24676 +f 34375/34375/24663 34389/34389/24676 34373/34373/24662 +f 34376/34376/24664 34392/34392/24666 34391/34391/24677 +f 34376/34376/24664 34391/34391/24677 34375/34375/24663 +f 34377/34377/24665 34393/34393/24678 34394/34394/24679 +f 34377/34377/24665 34394/34394/24679 34378/34378/24666 +f 34379/34379/24667 34395/34395/24680 34393/34393/24678 +f 34379/34379/24667 34393/34393/24678 34377/34377/24665 +f 34380/34380/24668 34396/34396/24681 34395/34395/24680 +f 34380/34380/24668 34395/34395/24680 34379/34379/24667 +f 34381/34381/24669 34397/34397/24682 34398/34398/24681 +f 34381/34381/24669 34398/34398/24681 34382/34382/24668 +f 34383/34383/24670 34399/34399/24683 34397/34397/24682 +f 34383/34383/24670 34397/34397/24682 34381/34381/24669 +f 34384/34384/24671 34400/34400/24684 34399/34399/24683 +f 34384/34384/24671 34399/34399/24683 34383/34383/24670 +f 34385/34385/24672 34401/34401/24685 34402/34402/24684 +f 34385/34385/24672 34402/34402/24684 34386/34386/24673 +f 34387/34387/24674 34403/34403/24686 34401/34401/24685 +f 34387/34387/24674 34401/34401/24685 34385/34385/24672 +f 34388/34388/24675 34404/34404/24687 34403/34403/24686 +f 34388/34388/24675 34403/34403/24686 34387/34387/24674 +f 34389/34389/24676 34405/34405/24688 34406/34406/24687 +f 34389/34389/24676 34406/34406/24687 34390/34390/24675 +f 34391/34391/24677 34407/34407/24689 34405/34405/24688 +f 34391/34391/24677 34405/34405/24688 34389/34389/24676 +f 34392/34392/24666 34408/34408/24679 34407/34407/24689 +f 34392/34392/24666 34407/34407/24689 34391/34391/24677 +f 34393/34393/24678 34409/34409/24690 34410/34410/24691 +f 34393/34393/24678 34410/34410/24691 34394/34394/24679 +f 34395/34395/24680 34411/34411/24692 34409/34409/24690 +f 34395/34395/24680 34409/34409/24690 34393/34393/24678 +f 34396/34396/24681 34412/34412/24693 34411/34411/24692 +f 34396/34396/24681 34411/34411/24692 34395/34395/24680 +f 34397/34397/24682 34413/34413/24694 34414/34414/24695 +f 34397/34397/24682 34414/34414/24695 34398/34398/24681 +f 34399/34399/24683 34415/34415/24696 34413/34413/24694 +f 34399/34399/24683 34413/34413/24694 34397/34397/24682 +f 34400/34400/24684 34416/34416/24697 34415/34415/24696 +f 34400/34400/24684 34415/34415/24696 34399/34399/24683 +f 34401/34401/24685 34417/34417/24698 34418/34418/24697 +f 34401/34401/24685 34418/34418/24697 34402/34402/24684 +f 34403/34403/24686 34419/34419/24699 34417/34417/24698 +f 34403/34403/24686 34417/34417/24698 34401/34401/24685 +f 34404/34404/24687 34420/34420/24700 34419/34419/24699 +f 34404/34404/24687 34419/34419/24699 34403/34403/24686 +f 34405/34405/24688 34421/34421/24701 34422/34422/24700 +f 34405/34405/24688 34422/34422/24700 34406/34406/24687 +f 34407/34407/24689 34423/34423/24702 34421/34421/24701 +f 34407/34407/24689 34421/34421/24701 34405/34405/24688 +f 34408/34408/24679 34424/34424/24703 34423/34423/24702 +f 34408/34408/24679 34423/34423/24702 34407/34407/24689 +f 34409/34409/24690 34425/34425/24704 34426/34426/24705 +f 34409/34409/24690 34426/34426/24705 34410/34410/24691 +f 34411/34411/24692 34427/34427/24706 34425/34425/24704 +f 34411/34411/24692 34425/34425/24704 34409/34409/24690 +f 34412/34412/24693 34428/34428/24707 34427/34427/24706 +f 34412/34412/24693 34427/34427/24706 34411/34411/24692 +f 34413/34413/24694 34429/34429/24708 34430/34430/24707 +f 34413/34413/24694 34430/34430/24707 34414/34414/24695 +f 34415/34415/24696 34431/34431/24709 34429/34429/24708 +f 34415/34415/24696 34429/34429/24708 34413/34413/24694 +f 34416/34416/24697 34432/34432/24710 34431/34431/24709 +f 34416/34416/24697 34431/34431/24709 34415/34415/24696 +f 34417/34417/24698 34433/34433/24711 34434/34434/24710 +f 34417/34417/24698 34434/34434/24710 34418/34418/24697 +f 34419/34419/24699 34435/34435/24712 34433/34433/24711 +f 34419/34419/24699 34433/34433/24711 34417/34417/24698 +f 34420/34420/24700 34436/34436/24713 34435/34435/24712 +f 34420/34420/24700 34435/34435/24712 34419/34419/24699 +f 34421/34421/24701 34437/34437/24714 34438/34438/24713 +f 34421/34421/24701 34438/34438/24713 34422/34422/24700 +f 34423/34423/24702 34439/34439/24715 34437/34437/24714 +f 34423/34423/24702 34437/34437/24714 34421/34421/24701 +f 34424/34424/24703 34440/34440/24716 34439/34439/24715 +f 34424/34424/24703 34439/34439/24715 34423/34423/24702 +f 34425/34425/24704 34441/34441/24717 34442/34442/24718 +f 34425/34425/24704 34442/34442/24718 34426/34426/24705 +f 34427/34427/24706 34443/34443/24719 34441/34441/24717 +f 34427/34427/24706 34441/34441/24717 34425/34425/24704 +f 34428/34428/24707 34444/34444/24720 34443/34443/24719 +f 34428/34428/24707 34443/34443/24719 34427/34427/24706 +f 34429/34429/24708 34445/34445/24721 34446/34446/24720 +f 34429/34429/24708 34446/34446/24720 34430/34430/24707 +f 34431/34431/24709 34447/34447/24722 34445/34445/24721 +f 34431/34431/24709 34445/34445/24721 34429/34429/24708 +f 34432/34432/24710 34448/34448/24723 34447/34447/24722 +f 34432/34432/24710 34447/34447/24722 34431/34431/24709 +f 34433/34433/24711 34449/34449/24724 34450/34450/24725 +f 34433/34433/24711 34450/34450/24725 34434/34434/24710 +f 34435/34435/24712 34451/34451/24726 34449/34449/24724 +f 34435/34435/24712 34449/34449/24724 34433/34433/24711 +f 34436/34436/24713 34452/34452/24727 34451/34451/24726 +f 34436/34436/24713 34451/34451/24726 34435/34435/24712 +f 34437/34437/24714 34453/34453/24728 34454/34454/24727 +f 34437/34437/24714 34454/34454/24727 34438/34438/24713 +f 34439/34439/24715 34455/34455/24729 34453/34453/24728 +f 34439/34439/24715 34453/34453/24728 34437/34437/24714 +f 34440/34440/24716 34456/34456/24730 34455/34455/24729 +f 34440/34440/24716 34455/34455/24729 34439/34439/24715 +f 34441/34441/24717 34457/34457/24731 34458/34458/24732 +f 34441/34441/24717 34458/34458/24732 34442/34442/24718 +f 34443/34443/24719 34459/34459/24733 34457/34457/24731 +f 34443/34443/24719 34457/34457/24731 34441/34441/24717 +f 34444/34444/24720 34460/34460/24734 34459/34459/24733 +f 34444/34444/24720 34459/34459/24733 34443/34443/24719 +f 34445/34445/24721 34461/34461/24735 34462/34462/24734 +f 34445/34445/24721 34462/34462/24734 34446/34446/24720 +f 34447/34447/24722 34463/34463/24736 34461/34461/24735 +f 34447/34447/24722 34461/34461/24735 34445/34445/24721 +f 34448/34448/24723 34464/34464/24737 34463/34463/24736 +f 34448/34448/24723 34463/34463/24736 34447/34447/24722 +f 34449/34449/24724 34465/34465/24738 34466/34466/24737 +f 34449/34449/24724 34466/34466/24737 34450/34450/24725 +f 34451/34451/24726 34467/34467/24739 34465/34465/24738 +f 34451/34451/24726 34465/34465/24738 34449/34449/24724 +f 34452/34452/24727 34468/34468/24740 34467/34467/24739 +f 34452/34452/24727 34467/34467/24739 34451/34451/24726 +f 34453/34453/24728 34469/34469/24741 34470/34470/24740 +f 34453/34453/24728 34470/34470/24740 34454/34454/24727 +f 34455/34455/24729 34471/34471/24742 34469/34469/24741 +f 34455/34455/24729 34469/34469/24741 34453/34453/24728 +f 34456/34456/24730 34472/34472/24743 34471/34471/24742 +f 34456/34456/24730 34471/34471/24742 34455/34455/24729 +f 34457/34457/24731 34473/34473/24744 34474/34474/24745 +f 34457/34457/24731 34474/34474/24745 34458/34458/24732 +f 34459/34459/24733 34475/34475/24746 34473/34473/24744 +f 34459/34459/24733 34473/34473/24744 34457/34457/24731 +f 34460/34460/24734 34476/34476/24747 34475/34475/24746 +f 34460/34460/24734 34475/34475/24746 34459/34459/24733 +f 34461/34461/24735 34477/34477/24748 34478/34478/24747 +f 34461/34461/24735 34478/34478/24747 34462/34462/24734 +f 34463/34463/24736 34479/34479/24749 34477/34477/24748 +f 34463/34463/24736 34477/34477/24748 34461/34461/24735 +f 34464/34464/24737 34480/34480/24750 34479/34479/24749 +f 34464/34464/24737 34479/34479/24749 34463/34463/24736 +f 34465/34465/24738 34481/34481/24751 34482/34482/24750 +f 34465/34465/24738 34482/34482/24750 34466/34466/24737 +f 34467/34467/24739 34483/34483/24752 34481/34481/24751 +f 34467/34467/24739 34481/34481/24751 34465/34465/24738 +f 34468/34468/24740 34484/34484/24753 34483/34483/24752 +f 34468/34468/24740 34483/34483/24752 34467/34467/24739 +f 34469/34469/24741 34485/34485/24754 34486/34486/24753 +f 34469/34469/24741 34486/34486/24753 34470/34470/24740 +f 34471/34471/24742 34487/34487/24755 34485/34485/24754 +f 34471/34471/24742 34485/34485/24754 34469/34469/24741 +f 34472/34472/24743 34488/34488/24745 34487/34487/24755 +f 34472/34472/24743 34487/34487/24755 34471/34471/24742 +f 34473/34473/24744 34489/34489/24756 34490/34490/24757 +f 34473/34473/24744 34490/34490/24757 34474/34474/24745 +f 34475/34475/24746 34491/34491/24758 34489/34489/24756 +f 34475/34475/24746 34489/34489/24756 34473/34473/24744 +f 34476/34476/24747 34492/34492/24759 34491/34491/24758 +f 34476/34476/24747 34491/34491/24758 34475/34475/24746 +f 34477/34477/24748 34493/34493/24760 34494/34494/24759 +f 34477/34477/24748 34494/34494/24759 34478/34478/24747 +f 34479/34479/24749 34495/34495/24761 34493/34493/24760 +f 34479/34479/24749 34493/34493/24760 34477/34477/24748 +f 34480/34480/24750 34496/34496/24762 34495/34495/24761 +f 34480/34480/24750 34495/34495/24761 34479/34479/24749 +f 34481/34481/24751 34497/34497/24763 34498/34498/24762 +f 34481/34481/24751 34498/34498/24762 34482/34482/24750 +f 34483/34483/24752 34499/34499/24764 34497/34497/24763 +f 34483/34483/24752 34497/34497/24763 34481/34481/24751 +f 34484/34484/24753 34500/34500/24765 34499/34499/24764 +f 34484/34484/24753 34499/34499/24764 34483/34483/24752 +f 34485/34485/24754 34501/34501/24766 34502/34502/24765 +f 34485/34485/24754 34502/34502/24765 34486/34486/24753 +f 34487/34487/24755 34503/34503/24767 34501/34501/24766 +f 34487/34487/24755 34501/34501/24766 34485/34485/24754 +f 34488/34488/24745 34504/34504/24768 34503/34503/24767 +f 34488/34488/24745 34503/34503/24767 34487/34487/24755 +f 34489/34489/24756 34505/34505/24769 34506/34506/24770 +f 34489/34489/24756 34506/34506/24770 34490/34490/24757 +f 34491/34491/24758 34507/34507/24771 34505/34505/24769 +f 34491/34491/24758 34505/34505/24769 34489/34489/24756 +f 34492/34492/24759 34508/34508/24772 34507/34507/24771 +f 34492/34492/24759 34507/34507/24771 34491/34491/24758 +f 34493/34493/24760 34509/34509/24773 34510/34510/24774 +f 34493/34493/24760 34510/34510/24774 34494/34494/24759 +f 34495/34495/24761 34511/34511/24775 34509/34509/24773 +f 34495/34495/24761 34509/34509/24773 34493/34493/24760 +f 34496/34496/24762 34512/34512/24776 34511/34511/24775 +f 34496/34496/24762 34511/34511/24775 34495/34495/24761 +f 34497/34497/24763 34513/34513/24777 34514/34514/24776 +f 34497/34497/24763 34514/34514/24776 34498/34498/24762 +f 34499/34499/24764 34515/34515/24778 34513/34513/24777 +f 34499/34499/24764 34513/34513/24777 34497/34497/24763 +f 34500/34500/24765 34516/34516/24779 34515/34515/24778 +f 34500/34500/24765 34515/34515/24778 34499/34499/24764 +f 34501/34501/24766 34517/34517/24780 34518/34518/24779 +f 34501/34501/24766 34518/34518/24779 34502/34502/24765 +f 34503/34503/24767 34519/34519/24781 34517/34517/24780 +f 34503/34503/24767 34517/34517/24780 34501/34501/24766 +f 34504/34504/24768 34520/34520/24770 34519/34519/24781 +f 34504/34504/24768 34519/34519/24781 34503/34503/24767 +f 34505/34505/24769 34521/34521/24782 34522/34522/24783 +f 34505/34505/24769 34522/34522/24783 34506/34506/24770 +f 34507/34507/24771 34523/34523/24784 34521/34521/24782 +f 34507/34507/24771 34521/34521/24782 34505/34505/24769 +f 34508/34508/24772 34524/34524/24785 34523/34523/24784 +f 34508/34508/24772 34523/34523/24784 34507/34507/24771 +f 34509/34509/24773 34525/34525/24786 34526/34526/24785 +f 34509/34509/24773 34526/34526/24785 34510/34510/24774 +f 34511/34511/24775 34527/34527/24787 34525/34525/24786 +f 34511/34511/24775 34525/34525/24786 34509/34509/24773 +f 34512/34512/24776 34528/34528/24788 34527/34527/24787 +f 34512/34512/24776 34527/34527/24787 34511/34511/24775 +f 34513/34513/24777 34529/34529/24789 34530/34530/24788 +f 34513/34513/24777 34530/34530/24788 34514/34514/24776 +f 34515/34515/24778 34531/34531/24790 34529/34529/24789 +f 34515/34515/24778 34529/34529/24789 34513/34513/24777 +f 34516/34516/24779 34532/34532/24791 34531/34531/24790 +f 34516/34516/24779 34531/34531/24790 34515/34515/24778 +f 34517/34517/24780 34533/34533/24792 34534/34534/24791 +f 34517/34517/24780 34534/34534/24791 34518/34518/24779 +f 34519/34519/24781 34535/34535/24793 34533/34533/24792 +f 34519/34519/24781 34533/34533/24792 34517/34517/24780 +f 34520/34520/24770 34536/34536/24794 34535/34535/24793 +f 34520/34520/24770 34535/34535/24793 34519/34519/24781 +f 34521/34521/24782 34537/34537/24795 34538/34538/24796 +f 34521/34521/24782 34538/34538/24796 34522/34522/24783 +f 34523/34523/24784 34539/34539/24797 34537/34537/24795 +f 34523/34523/24784 34537/34537/24795 34521/34521/24782 +f 34524/34524/24785 34540/34540/24798 34539/34539/24797 +f 34524/34524/24785 34539/34539/24797 34523/34523/24784 +f 34525/34525/24786 34541/34541/24799 34542/34542/24798 +f 34525/34525/24786 34542/34542/24798 34526/34526/24785 +f 34527/34527/24787 34543/34543/24800 34541/34541/24799 +f 34527/34527/24787 34541/34541/24799 34525/34525/24786 +f 34528/34528/24788 34544/34544/24801 34543/34543/24800 +f 34528/34528/24788 34543/34543/24800 34527/34527/24787 +f 34529/34529/24789 34545/34545/24802 34546/34546/24801 +f 34529/34529/24789 34546/34546/24801 34530/34530/24788 +f 34531/34531/24790 34547/34547/24803 34545/34545/24802 +f 34531/34531/24790 34545/34545/24802 34529/34529/24789 +f 34532/34532/24791 34548/34548/24804 34547/34547/24803 +f 34532/34532/24791 34547/34547/24803 34531/34531/24790 +f 34533/34533/24792 34549/34549/24805 34550/34550/24806 +f 34533/34533/24792 34550/34550/24806 34534/34534/24791 +f 34535/34535/24793 34551/34551/24807 34549/34549/24805 +f 34535/34535/24793 34549/34549/24805 34533/34533/24792 +f 34536/34536/24794 34552/34552/24808 34551/34551/24807 +f 34536/34536/24794 34551/34551/24807 34535/34535/24793 +f 34553/34553/24809 34554/34554/24810 34555/34555/24811 +f 34553/34553/24809 34555/34555/24811 34552/34552/24808 +f 34539/34539/24797 34556/34556/24812 34557/34557/24810 +f 34539/34539/24797 34557/34557/24810 34537/34537/24795 +f 34540/34540/24798 34558/34558/24813 34556/34556/24812 +f 34540/34540/24798 34556/34556/24812 34539/34539/24797 +f 34541/34541/24799 34559/34559/24814 34560/34560/24813 +f 34541/34541/24799 34560/34560/24813 34542/34542/24798 +f 34543/34543/24800 34561/34561/24815 34559/34559/24814 +f 34543/34543/24800 34559/34559/24814 34541/34541/24799 +f 34544/34544/24801 34562/34562/24816 34561/34561/24815 +f 34544/34544/24801 34561/34561/24815 34543/34543/24800 +f 34563/34563/24802 34564/34564/24817 34562/34562/24816 +f 34563/34563/24802 34562/34562/24816 34544/34544/24801 +f 34547/34547/24803 34565/34565/24818 34566/34566/24819 +f 34547/34547/24803 34566/34566/24819 34545/34545/24802 +f 34548/34548/24804 34567/34567/24820 34565/34565/24818 +f 34548/34548/24804 34565/34565/24818 34547/34547/24803 +f 34549/34549/24805 34568/34568/24821 34569/34569/24822 +f 34549/34549/24805 34569/34569/24822 34550/34550/24806 +f 34551/34551/24807 34570/34570/24823 34568/34568/24821 +f 34551/34551/24807 34568/34568/24821 34549/34549/24805 +f 34552/34552/24808 34555/34555/24811 34570/34570/24823 +f 34552/34552/24808 34570/34570/24823 34551/34551/24807 +f 34554/34554/24810 34571/34571/24824 34572/34572/24825 +f 34554/34554/24810 34572/34572/24825 34555/34555/24811 +f 34556/34556/24812 34573/34573/24826 34574/34574/24824 +f 34556/34556/24812 34574/34574/24824 34557/34557/24810 +f 34558/34558/24813 34575/34575/24827 34573/34573/24826 +f 34558/34558/24813 34573/34573/24826 34556/34556/24812 +f 34559/34559/24814 34576/34576/24828 34577/34577/24827 +f 34559/34559/24814 34577/34577/24827 34560/34560/24813 +f 34561/34561/24815 34578/34578/24829 34576/34576/24828 +f 34561/34561/24815 34576/34576/24828 34559/34559/24814 +f 34562/34562/24816 34579/34579/24830 34578/34578/24829 +f 34562/34562/24816 34578/34578/24829 34561/34561/24815 +f 34564/34564/24817 34580/34580/24831 34579/34579/24830 +f 34564/34564/24817 34579/34579/24830 34562/34562/24816 +f 34565/34565/24818 34581/34581/24832 34582/34582/24833 +f 34565/34565/24818 34582/34582/24833 34566/34566/24819 +f 34567/34567/24820 34583/34583/24834 34581/34581/24832 +f 34567/34567/24820 34581/34581/24832 34565/34565/24818 +f 34568/34568/24821 34584/34584/24835 34585/34585/24834 +f 34568/34568/24821 34585/34585/24834 34569/34569/24822 +f 34570/34570/24823 34586/34586/24836 34584/34584/24835 +f 34570/34570/24823 34584/34584/24835 34568/34568/24821 +f 34555/34555/24811 34572/34572/24825 34586/34586/24836 +f 34555/34555/24811 34586/34586/24836 34570/34570/24823 +f 34571/34571/24824 34587/34587/24837 34588/34588/24838 +f 34571/34571/24824 34588/34588/24838 34572/34572/24825 +f 34573/34573/24826 34589/34589/24839 34590/34590/24837 +f 34573/34573/24826 34590/34590/24837 34574/34574/24824 +f 34575/34575/24827 34591/34591/24840 34589/34589/24839 +f 34575/34575/24827 34589/34589/24839 34573/34573/24826 +f 34576/34576/24828 34592/34592/24841 34593/34593/24840 +f 34576/34576/24828 34593/34593/24840 34577/34577/24827 +f 34578/34578/24829 34594/34594/24842 34592/34592/24841 +f 34578/34578/24829 34592/34592/24841 34576/34576/24828 +f 34579/34579/24830 34595/34595/24843 34594/34594/24842 +f 34579/34579/24830 34594/34594/24842 34578/34578/24829 +f 34580/34580/24831 34596/34596/24844 34595/34595/24843 +f 34580/34580/24831 34595/34595/24843 34579/34579/24830 +f 34581/34581/24832 34597/34597/24845 34598/34598/24844 +f 34581/34581/24832 34598/34598/24844 34582/34582/24833 +f 34583/34583/24834 34599/34599/24846 34597/34597/24845 +f 34583/34583/24834 34597/34597/24845 34581/34581/24832 +f 34584/34584/24835 34600/34600/24847 34601/34601/24848 +f 34584/34584/24835 34601/34601/24848 34585/34585/24834 +f 34586/34586/24836 34602/34602/24849 34600/34600/24847 +f 34586/34586/24836 34600/34600/24847 34584/34584/24835 +f 34572/34572/24825 34588/34588/24838 34602/34602/24849 +f 34572/34572/24825 34602/34602/24849 34586/34586/24836 +f 34587/34587/24837 34603/34603/24850 34604/34604/24851 +f 34587/34587/24837 34604/34604/24851 34588/34588/24838 +f 34589/34589/24839 34605/34605/24852 34606/34606/24850 +f 34589/34589/24839 34606/34606/24850 34590/34590/24837 +f 34591/34591/24840 34607/34607/24853 34605/34605/24852 +f 34591/34591/24840 34605/34605/24852 34589/34589/24839 +f 34608/34608/24854 34609/34609/24855 34607/34607/24853 +f 34608/34608/24854 34607/34607/24853 34591/34591/24840 +f 34594/34594/24842 34610/34610/24856 34611/34611/24855 +f 34594/34594/24842 34611/34611/24855 34592/34592/24841 +f 34595/34595/24843 34612/34612/24857 34610/34610/24856 +f 34595/34595/24843 34610/34610/24856 34594/34594/24842 +f 34596/34596/24844 34613/34613/24858 34612/34612/24857 +f 34596/34596/24844 34612/34612/24857 34595/34595/24843 +f 34597/34597/24845 34614/34614/24859 34615/34615/24858 +f 34597/34597/24845 34615/34615/24858 34598/34598/24844 +f 34599/34599/24846 34616/34616/24860 34614/34614/24859 +f 34599/34599/24846 34614/34614/24859 34597/34597/24845 +f 34617/34617/24847 34618/34618/24861 34616/34616/24860 +f 34617/34617/24847 34616/34616/24860 34599/34599/24846 +f 34602/34602/24849 34619/34619/24862 34620/34620/24861 +f 34602/34602/24849 34620/34620/24861 34600/34600/24847 +f 34588/34588/24838 34604/34604/24851 34619/34619/24862 +f 34588/34588/24838 34619/34619/24862 34602/34602/24849 +f 34603/34603/24850 34621/34621/24863 34622/34622/24864 +f 34603/34603/24850 34622/34622/24864 34604/34604/24851 +f 34605/34605/24852 34623/34623/24865 34624/34624/24866 +f 34605/34605/24852 34624/34624/24866 34606/34606/24850 +f 34607/34607/24853 34625/34625/24867 34623/34623/24865 +f 34607/34607/24853 34623/34623/24865 34605/34605/24852 +f 34609/34609/24855 34626/34626/24868 34625/34625/24867 +f 34609/34609/24855 34625/34625/24867 34607/34607/24853 +f 34610/34610/24856 34627/34627/24869 34628/34628/24868 +f 34610/34610/24856 34628/34628/24868 34611/34611/24855 +f 34612/34612/24857 34629/34629/24870 34627/34627/24869 +f 34612/34612/24857 34627/34627/24869 34610/34610/24856 +f 34613/34613/24858 34630/34630/24871 34629/34629/24870 +f 34613/34613/24858 34629/34629/24870 34612/34612/24857 +f 34614/34614/24859 34631/34631/24872 34632/34632/24873 +f 34614/34614/24859 34632/34632/24873 34615/34615/24858 +f 34616/34616/24860 34633/34633/24874 34631/34631/24872 +f 34616/34616/24860 34631/34631/24872 34614/34614/24859 +f 34618/34618/24861 34634/34634/24875 34633/34633/24874 +f 34618/34618/24861 34633/34633/24874 34616/34616/24860 +f 34619/34619/24862 34635/34635/24876 34636/34636/24875 +f 34619/34619/24862 34636/34636/24875 34620/34620/24861 +f 34604/34604/24851 34622/34622/24864 34635/34635/24876 +f 34604/34604/24851 34635/34635/24876 34619/34619/24862 +f 34621/34621/24863 34637/34637/24877 34638/34638/24878 +f 34621/34621/24863 34638/34638/24878 34622/34622/24864 +f 34623/34623/24865 34639/34639/24879 34640/34640/24877 +f 34623/34623/24865 34640/34640/24877 34624/34624/24866 +f 34625/34625/24867 34641/34641/24880 34639/34639/24879 +f 34625/34625/24867 34639/34639/24879 34623/34623/24865 +f 34626/34626/24868 34642/34642/24881 34641/34641/24880 +f 34626/34626/24868 34641/34641/24880 34625/34625/24867 +f 34627/34627/24869 34643/34643/24882 34644/34644/24881 +f 34627/34627/24869 34644/34644/24881 34628/34628/24868 +f 34629/34629/24870 34645/34645/24883 34643/34643/24882 +f 34629/34629/24870 34643/34643/24882 34627/34627/24869 +f 34630/34630/24871 34646/34646/24884 34645/34645/24883 +f 34630/34630/24871 34645/34645/24883 34629/34629/24870 +f 34631/34631/24872 34647/34647/24885 34648/34648/24884 +f 34631/34631/24872 34648/34648/24884 34632/34632/24873 +f 34633/34633/24874 34649/34649/24886 34647/34647/24885 +f 34633/34633/24874 34647/34647/24885 34631/34631/24872 +f 34634/34634/24875 34650/34650/24887 34649/34649/24886 +f 34634/34634/24875 34649/34649/24886 34633/34633/24874 +f 34635/34635/24876 34651/34651/24888 34652/34652/24889 +f 34635/34635/24876 34652/34652/24889 34636/34636/24875 +f 34622/34622/24864 34638/34638/24878 34651/34651/24888 +f 34622/34622/24864 34651/34651/24888 34635/34635/24876 +f 34637/34637/24877 34653/34653/24890 34654/34654/24891 +f 34637/34637/24877 34654/34654/24891 34638/34638/24878 +f 34639/34639/24879 34655/34655/24892 34656/34656/24890 +f 34639/34639/24879 34656/34656/24890 34640/34640/24877 +f 34641/34641/24880 34657/34657/24893 34655/34655/24892 +f 34641/34641/24880 34655/34655/24892 34639/34639/24879 +f 34642/34642/24881 34658/34658/24894 34657/34657/24893 +f 34642/34642/24881 34657/34657/24893 34641/34641/24880 +f 34643/34643/24882 34659/34659/24895 34660/34660/24894 +f 34643/34643/24882 34660/34660/24894 34644/34644/24881 +f 34645/34645/24883 34661/34661/24896 34659/34659/24895 +f 34645/34645/24883 34659/34659/24895 34643/34643/24882 +f 34646/34646/24884 34662/34662/24897 34661/34661/24896 +f 34646/34646/24884 34661/34661/24896 34645/34645/24883 +f 34647/34647/24885 34663/34663/24898 34664/34664/24897 +f 34647/34647/24885 34664/34664/24897 34648/34648/24884 +f 34649/34649/24886 34665/34665/24899 34663/34663/24898 +f 34649/34649/24886 34663/34663/24898 34647/34647/24885 +f 34650/34650/24887 34666/34666/24900 34665/34665/24899 +f 34650/34650/24887 34665/34665/24899 34649/34649/24886 +f 34651/34651/24888 34667/34667/24901 34668/34668/24900 +f 34651/34651/24888 34668/34668/24900 34652/34652/24889 +f 34638/34638/24878 34654/34654/24891 34667/34667/24901 +f 34638/34638/24878 34667/34667/24901 34651/34651/24888 +f 34653/34653/24890 34669/34669/24902 34670/34670/24903 +f 34653/34653/24890 34670/34670/24903 34654/34654/24891 +f 34655/34655/24892 34671/34671/24904 34672/34672/24905 +f 34655/34655/24892 34672/34672/24905 34656/34656/24890 +f 34657/34657/24893 34673/34673/24906 34671/34671/24904 +f 34657/34657/24893 34671/34671/24904 34655/34655/24892 +f 34658/34658/24894 34674/34674/24907 34673/34673/24906 +f 34658/34658/24894 34673/34673/24906 34657/34657/24893 +f 34659/34659/24895 34675/34675/24908 34676/34676/24907 +f 34659/34659/24895 34676/34676/24907 34660/34660/24894 +f 34661/34661/24896 34677/34677/24909 34675/34675/24908 +f 34661/34661/24896 34675/34675/24908 34659/34659/24895 +f 34662/34662/24897 34678/34678/24910 34677/34677/24909 +f 34662/34662/24897 34677/34677/24909 34661/34661/24896 +f 34663/34663/24898 34679/34679/24911 34680/34680/24912 +f 34663/34663/24898 34680/34680/24912 34664/34664/24897 +f 34665/34665/24899 34681/34681/24913 34679/34679/24911 +f 34665/34665/24899 34679/34679/24911 34663/34663/24898 +f 34666/34666/24900 34682/34682/24914 34681/34681/24913 +f 34666/34666/24900 34681/34681/24913 34665/34665/24899 +f 34667/34667/24901 34683/34683/24915 34684/34684/24914 +f 34667/34667/24901 34684/34684/24914 34668/34668/24900 +f 34654/34654/24891 34670/34670/24903 34683/34683/24915 +f 34654/34654/24891 34683/34683/24915 34667/34667/24901 +f 34669/34669/24902 34685/34685/24916 34686/34686/24917 +f 34669/34669/24902 34686/34686/24917 34670/34670/24903 +f 34671/34671/24904 34687/34687/24918 34688/34688/24916 +f 34671/34671/24904 34688/34688/24916 34672/34672/24905 +f 34673/34673/24906 34689/34689/24919 34687/34687/24918 +f 34673/34673/24906 34687/34687/24918 34671/34671/24904 +f 34674/34674/24907 34690/34690/24920 34689/34689/24919 +f 34674/34674/24907 34689/34689/24919 34673/34673/24906 +f 34675/34675/24908 34691/34691/24921 34692/34692/24922 +f 34675/34675/24908 34692/34692/24922 34676/34676/24907 +f 34677/34677/24909 34693/34693/24923 34691/34691/24921 +f 34677/34677/24909 34691/34691/24921 34675/34675/24908 +f 34678/34678/24910 34694/34694/24924 34693/34693/24923 +f 34678/34678/24910 34693/34693/24923 34677/34677/24909 +f 34679/34679/24911 34695/34695/24925 34696/34696/24924 +f 34679/34679/24911 34696/34696/24924 34680/34680/24912 +f 34681/34681/24913 34697/34697/24926 34695/34695/24925 +f 34681/34681/24913 34695/34695/24925 34679/34679/24911 +f 34682/34682/24914 34698/34698/24927 34697/34697/24926 +f 34682/34682/24914 34697/34697/24926 34681/34681/24913 +f 34683/34683/24915 34699/34699/24928 34700/34700/24927 +f 34683/34683/24915 34700/34700/24927 34684/34684/24914 +f 34670/34670/24903 34686/34686/24917 34699/34699/24928 +f 34670/34670/24903 34699/34699/24928 34683/34683/24915 +f 34685/34685/24916 34701/34701/24929 34702/34702/24930 +f 34685/34685/24916 34702/34702/24930 34686/34686/24917 +f 34687/34687/24918 34703/34703/24931 34704/34704/24929 +f 34687/34687/24918 34704/34704/24929 34688/34688/24916 +f 34689/34689/24919 34705/34705/24932 34703/34703/24931 +f 34689/34689/24919 34703/34703/24931 34687/34687/24918 +f 34690/34690/24920 34706/34706/24933 34705/34705/24932 +f 34690/34690/24920 34705/34705/24932 34689/34689/24919 +f 34691/34691/24921 34707/34707/24934 34708/34708/24933 +f 34691/34691/24921 34708/34708/24933 34692/34692/24922 +f 34693/34693/24923 34709/34709/24935 34707/34707/24934 +f 34693/34693/24923 34707/34707/24934 34691/34691/24921 +f 34694/34694/24924 34710/34710/24936 34709/34709/24935 +f 34694/34694/24924 34709/34709/24935 34693/34693/24923 +f 34695/34695/24925 34711/34711/24937 34712/34712/24936 +f 34695/34695/24925 34712/34712/24936 34696/34696/24924 +f 34697/34697/24926 34713/34713/24938 34711/34711/24937 +f 34697/34697/24926 34711/34711/24937 34695/34695/24925 +f 34698/34698/24927 34714/34714/24939 34713/34713/24938 +f 34698/34698/24927 34713/34713/24938 34697/34697/24926 +f 34699/34699/24928 34715/34715/24940 34716/34716/24941 +f 34699/34699/24928 34716/34716/24941 34700/34700/24927 +f 34686/34686/24917 34702/34702/24930 34715/34715/24940 +f 34686/34686/24917 34715/34715/24940 34699/34699/24928 +f 34701/34701/24929 34717/34717/24942 34718/34718/24943 +f 34701/34701/24929 34718/34718/24943 34702/34702/24930 +f 34703/34703/24931 34719/34719/24944 34720/34720/24945 +f 34703/34703/24931 34720/34720/24945 34704/34704/24929 +f 34705/34705/24932 34721/34721/24946 34719/34719/24944 +f 34705/34705/24932 34719/34719/24944 34703/34703/24931 +f 34706/34706/24933 34722/34722/24947 34721/34721/24946 +f 34706/34706/24933 34721/34721/24946 34705/34705/24932 +f 34707/34707/24934 34723/34723/24948 34724/34724/24947 +f 34707/34707/24934 34724/34724/24947 34708/34708/24933 +f 34709/34709/24935 34725/34725/24949 34723/34723/24948 +f 34709/34709/24935 34723/34723/24948 34707/34707/24934 +f 34710/34710/24936 34726/34726/24950 34725/34725/24949 +f 34710/34710/24936 34725/34725/24949 34709/34709/24935 +f 34711/34711/24937 34727/34727/24951 34728/34728/24952 +f 34711/34711/24937 34728/34728/24952 34712/34712/24936 +f 34713/34713/24938 34729/34729/24953 34727/34727/24951 +f 34713/34713/24938 34727/34727/24951 34711/34711/24937 +f 34714/34714/24939 34730/34730/24954 34729/34729/24953 +f 34714/34714/24939 34729/34729/24953 34713/34713/24938 +f 34715/34715/24940 34731/34731/24955 34732/34732/24954 +f 34715/34715/24940 34732/34732/24954 34716/34716/24941 +f 34702/34702/24930 34718/34718/24943 34731/34731/24955 +f 34702/34702/24930 34731/34731/24955 34715/34715/24940 +f 34717/34717/24942 34733/34733/24956 34734/34734/24957 +f 34717/34717/24942 34734/34734/24957 34718/34718/24943 +f 34719/34719/24944 34735/34735/24958 34736/34736/24956 +f 34719/34719/24944 34736/34736/24956 34720/34720/24945 +f 34721/34721/24946 34737/34737/24959 34735/34735/24958 +f 34721/34721/24946 34735/34735/24958 34719/34719/24944 +f 34722/34722/24947 34738/34738/24960 34737/34737/24959 +f 34722/34722/24947 34737/34737/24959 34721/34721/24946 +f 34723/34723/24948 34739/34739/24961 34740/34740/24960 +f 34723/34723/24948 34740/34740/24960 34724/34724/24947 +f 34725/34725/24949 34741/34741/24962 34739/34739/24961 +f 34725/34725/24949 34739/34739/24961 34723/34723/24948 +f 34726/34726/24950 34742/34742/24963 34741/34741/24962 +f 34726/34726/24950 34741/34741/24962 34725/34725/24949 +f 34727/34727/24951 34743/34743/24964 34744/34744/24965 +f 34727/34727/24951 34744/34744/24965 34728/34728/24952 +f 34729/34729/24953 34745/34745/24966 34743/34743/24964 +f 34729/34729/24953 34743/34743/24964 34727/34727/24951 +f 34730/34730/24954 34746/34746/24967 34745/34745/24966 +f 34730/34730/24954 34745/34745/24966 34729/34729/24953 +f 34731/34731/24955 34747/34747/24968 34748/34748/24967 +f 34731/34731/24955 34748/34748/24967 34732/34732/24954 +f 34718/34718/24943 34734/34734/24957 34747/34747/24968 +f 34718/34718/24943 34747/34747/24968 34731/34731/24955 +o Cube.049__0 +v -0.949634 0.949154 -0.634111 +v -0.956482 0.946799 -0.633684 +v -0.958205 0.955644 -0.581120 +v -0.951371 0.958071 -0.581120 +v -0.962052 0.942943 -0.632523 +v -0.963737 0.951592 -0.581120 +v -0.956482 0.946799 -0.528556 +v -0.949634 0.949154 -0.528128 +v -0.962052 0.942943 -0.529717 +v -0.936930 0.923978 -0.678130 +v -0.944423 0.922404 -0.678019 +v -0.949634 0.949154 -0.634111 +v -0.942148 0.950759 -0.634173 +v -0.951313 0.920265 -0.677237 +v -0.956482 0.946799 -0.633684 +v -0.956997 0.916995 -0.675113 +v -0.962052 0.942943 -0.632523 +v -0.956997 0.916995 -0.675113 +v -0.960872 0.912028 -0.670979 +v -0.965705 0.936834 -0.630262 +v -0.962052 0.942943 -0.632523 +v -0.967315 0.945103 -0.581120 +v -0.963737 0.951592 -0.581120 +v -0.965705 0.936834 -0.531978 +v -0.962052 0.942943 -0.529717 +v -0.960872 0.912028 -0.491261 +v -0.956997 0.916995 -0.487126 +v -0.956997 0.916995 -0.487126 +v -0.951312 0.920265 -0.485003 +v -0.944423 0.922404 -0.484221 +v -0.942147 0.950759 -0.528067 +v -0.936930 0.923978 -0.484110 +v -0.943887 0.959686 -0.581120 +v -0.942148 0.950759 -0.634173 +v -0.936027 0.879308 -0.456969 +v -0.942984 0.877516 -0.457971 +v -0.932933 0.825922 -0.448960 +v -0.925894 0.827294 -0.447884 +v -0.948852 0.875190 -0.460691 +v -0.939023 0.824736 -0.451879 +v -0.922882 0.774329 -0.457971 +v -0.915761 0.775280 -0.456969 +v -0.929194 0.774282 -0.460691 +v -0.936027 0.879308 -0.456969 +v -0.928524 0.880831 -0.456825 +v -0.942984 0.877516 -0.457971 +v -0.948852 0.875190 -0.460691 +v -0.953086 0.872062 -0.465988 +v -0.948852 0.875190 -0.460691 +v -0.943689 0.823827 -0.457564 +v -0.939023 0.824736 -0.451879 +v -0.943689 0.823827 -0.457564 +v -0.934292 0.775592 -0.465988 +v -0.926506 0.735626 -0.491261 +v -0.921050 0.732477 -0.487126 +v -0.914554 0.731580 -0.485003 +v -0.907365 0.732183 -0.484221 +v -0.908235 0.776684 -0.456825 +v -0.899829 0.733537 -0.484110 +v -0.918380 0.828758 -0.447731 +v -0.928524 0.880831 -0.456825 +v -0.902153 0.705433 -0.528128 +v -0.909384 0.705046 -0.528556 +v -0.907661 0.696201 -0.581120 +v -0.900417 0.696517 -0.581120 +v -0.915995 0.706529 -0.529717 +v -0.914310 0.697880 -0.581120 +v -0.909384 0.705046 -0.633684 +v -0.902154 0.705433 -0.634111 +v -0.915995 0.706529 -0.632523 +v -0.902153 0.705433 -0.528128 +v -0.894612 0.706756 -0.528067 +v -0.909384 0.705046 -0.528556 +v -0.915995 0.706529 -0.529717 +v -0.921050 0.732477 -0.487126 +v -0.926506 0.735626 -0.491261 +v -0.921673 0.710819 -0.531978 +v -0.915995 0.706529 -0.529717 +v -0.920063 0.702551 -0.581120 +v -0.914310 0.697880 -0.581120 +v -0.921674 0.710819 -0.630262 +v -0.915995 0.706529 -0.632523 +v -0.926506 0.735626 -0.670979 +v -0.921050 0.732477 -0.675113 +v -0.921050 0.732477 -0.675113 +v -0.914554 0.731580 -0.677237 +v -0.907365 0.732183 -0.678019 +v -0.894612 0.706756 -0.634173 +v -0.899830 0.733537 -0.678130 +v -0.892873 0.697829 -0.581120 +v -0.894612 0.706756 -0.528067 +v -0.915761 0.775280 -0.705271 +v -0.922882 0.774329 -0.704269 +v -0.932933 0.825922 -0.713280 +v -0.925894 0.827294 -0.714356 +v -0.929194 0.774282 -0.701549 +v -0.939023 0.824736 -0.710361 +v -0.942984 0.877516 -0.704269 +v -0.936027 0.879308 -0.705271 +v -0.948853 0.875190 -0.701549 +v -0.915761 0.775280 -0.705271 +v -0.908235 0.776684 -0.705415 +v -0.922882 0.774329 -0.704269 +v -0.929194 0.774282 -0.701549 +v -0.934292 0.775592 -0.696252 +v -0.929194 0.774282 -0.701549 +v -0.943689 0.823827 -0.704676 +v -0.939023 0.824736 -0.710361 +v -0.953086 0.872062 -0.696252 +v -0.948853 0.875190 -0.701549 +v -0.928525 0.880831 -0.705415 +v -0.918380 0.828758 -0.714509 +v -0.908235 0.776684 -0.705415 +v -0.946836 0.802066 -0.532487 +v -0.950805 0.822441 -0.528928 +v -0.951984 0.822211 -0.530576 +v -0.948139 0.802479 -0.534022 +v -0.954775 0.842816 -0.532487 +v -0.955828 0.841943 -0.534022 +v -0.953163 0.821981 -0.532284 +v -0.949449 0.802917 -0.535614 +v -0.956877 0.841046 -0.535614 +v -0.942242 0.783689 -0.541445 +v -0.945680 0.801334 -0.530287 +v -0.943547 0.785184 -0.543162 +v -0.949829 0.822631 -0.526567 +v -0.953978 0.843928 -0.530287 +v -0.957415 0.861573 -0.541445 +v -0.958064 0.859698 -0.543162 +v -0.959013 0.858292 -0.544361 +v -0.959954 0.856843 -0.545603 +v -0.960577 0.854837 -0.547453 +v -0.957660 0.839863 -0.537984 +v -0.954139 0.821791 -0.534828 +v -0.950619 0.803719 -0.537984 +v -0.946371 0.787120 -0.545603 +v -0.947701 0.788745 -0.547453 +v -0.944954 0.786130 -0.544361 +v -0.964969 0.906509 -0.617496 +v -0.966161 0.912630 -0.581120 +v -0.967889 0.924450 -0.581120 +v -0.966541 0.917531 -0.622243 +v -0.964969 0.906509 -0.544743 +v -0.966541 0.917531 -0.539997 +v -0.968526 0.935725 -0.581120 +v -0.967032 0.928057 -0.626693 +v -0.967032 0.928057 -0.535547 +v -0.959912 0.880132 -0.639488 +v -0.963051 0.896245 -0.613040 +v -0.961391 0.888146 -0.647637 +v -0.964098 0.901616 -0.581120 +v -0.963051 0.896245 -0.549200 +v -0.959912 0.880132 -0.522752 +v -0.961391 0.888146 -0.514603 +v -0.962497 0.896772 -0.505924 +v -0.962550 0.905052 -0.497787 +v -0.962550 0.905052 -0.664453 +v -0.962497 0.896772 -0.656316 +v -0.955628 0.858562 -0.495895 +v -0.948672 0.822856 -0.489659 +v -0.948118 0.822964 -0.477726 +v -0.955982 0.863328 -0.484775 +v -0.941716 0.787151 -0.495895 +v -0.940255 0.782600 -0.484775 +v -0.946615 0.823257 -0.466537 +v -0.955330 0.867989 -0.474349 +v -0.937901 0.778525 -0.474349 +v -0.954855 0.854172 -0.506336 +v -0.948751 0.822841 -0.500864 +v -0.942647 0.791510 -0.506336 +v -0.937590 0.765550 -0.522752 +v -0.935952 0.757567 -0.514603 +v -0.933739 0.749156 -0.505924 +v -0.930680 0.741462 -0.497787 +v -0.934292 0.775592 -0.465988 +v -0.932375 0.739204 -0.544743 +v -0.931183 0.733083 -0.581120 +v -0.928347 0.721478 -0.581120 +v -0.929695 0.728398 -0.539997 +v -0.932375 0.739204 -0.617496 +v -0.929695 0.728398 -0.622243 +v -0.924705 0.710788 -0.581120 +v -0.926199 0.718457 -0.535547 +v -0.926199 0.718457 -0.626693 +v -0.934451 0.749437 -0.549200 +v -0.933404 0.744066 -0.581120 +v -0.934451 0.749437 -0.613040 +v -0.937590 0.765550 -0.639488 +v -0.935953 0.757567 -0.647637 +v -0.933739 0.749156 -0.656316 +v -0.930681 0.741462 -0.664453 +v -0.941716 0.787151 -0.666345 +v -0.948672 0.822856 -0.672581 +v -0.948118 0.822964 -0.684514 +v -0.940255 0.782600 -0.677464 +v -0.955628 0.858562 -0.666345 +v -0.955982 0.863328 -0.677464 +v -0.946615 0.823257 -0.695703 +v -0.937901 0.778525 -0.687891 +v -0.955330 0.867989 -0.687891 +v -0.942647 0.791510 -0.655904 +v -0.948751 0.822841 -0.661376 +v -0.954855 0.854172 -0.655904 +v -0.959594 0.876076 -0.604308 +v -0.960354 0.879978 -0.581120 +v -0.961070 0.885356 -0.581120 +v -0.960239 0.881091 -0.606462 +v -0.959594 0.876076 -0.557932 +v -0.960239 0.881091 -0.555778 +v -0.962340 0.892503 -0.581120 +v -0.961414 0.887753 -0.609349 +v -0.961414 0.887753 -0.552891 +v -0.957415 0.861573 -0.620794 +v -0.959549 0.872526 -0.602817 +v -0.957314 0.864371 -0.623521 +v -0.960260 0.876177 -0.581120 +v -0.959549 0.872526 -0.559423 +v -0.957314 0.864371 -0.538719 +v -0.957747 0.868299 -0.534781 +v -0.958638 0.873504 -0.529501 +v -0.958638 0.873504 -0.632739 +v -0.957747 0.868299 -0.627460 +v -0.953640 0.845513 -0.526793 +v -0.949206 0.822752 -0.522818 +v -0.948886 0.822815 -0.517403 +v -0.953732 0.847689 -0.521747 +v -0.944772 0.799992 -0.526793 +v -0.944040 0.797940 -0.521747 +v -0.948768 0.822838 -0.510144 +v -0.954166 0.850546 -0.514983 +v -0.943370 0.795129 -0.514983 +v -0.941097 0.781133 -0.538719 +v -0.940025 0.777330 -0.534781 +v -0.938897 0.772171 -0.529501 +v -0.938817 0.769428 -0.557932 +v -0.938057 0.765526 -0.581120 +v -0.936702 0.760274 -0.581120 +v -0.937533 0.764538 -0.555778 +v -0.938817 0.769428 -0.604308 +v -0.937533 0.764538 -0.606462 +v -0.935196 0.753171 -0.581120 +v -0.936121 0.757922 -0.552891 +v -0.936121 0.757922 -0.609349 +v -0.940109 0.772736 -0.559423 +v -0.939397 0.769085 -0.581120 +v -0.940109 0.772736 -0.602817 +v -0.942242 0.783689 -0.620794 +v -0.941098 0.781133 -0.623521 +v -0.940025 0.777330 -0.627460 +v -0.938897 0.772171 -0.632739 +v -0.944772 0.799992 -0.635447 +v -0.949206 0.822752 -0.639422 +v -0.948886 0.822815 -0.644837 +v -0.944040 0.797940 -0.640492 +v -0.953640 0.845513 -0.635447 +v -0.953732 0.847689 -0.640492 +v -0.948768 0.822838 -0.652096 +v -0.943370 0.795129 -0.647256 +v -0.954166 0.850546 -0.647256 +v -0.945680 0.801334 -0.631953 +v -0.949829 0.822631 -0.635672 +v -0.953978 0.843928 -0.631953 +v -1.201988 0.853341 -0.604054 +v -1.209600 0.845715 -0.605882 +v -1.220529 0.877702 -0.605547 +v -1.212080 0.883868 -0.603750 +v -1.217211 0.838090 -0.604323 +v -1.228978 0.871536 -0.603958 +v -1.229245 0.910052 -0.605196 +v -1.220249 0.914707 -0.603435 +v -1.238241 0.905397 -0.603571 +v -1.184843 0.835479 -0.599086 +v -1.190146 0.828234 -0.604289 +v -1.195682 0.859660 -0.598864 +v -1.196547 0.819490 -0.606133 +v -1.202948 0.810746 -0.604589 +v -1.208252 0.803502 -0.599635 +v -1.223518 0.831771 -0.599356 +v -1.235979 0.866427 -0.598965 +v -1.245695 0.901541 -0.598549 +v -1.252720 0.931184 -0.598194 +v -1.244988 0.933986 -0.603243 +v -1.235655 0.937368 -0.604900 +v -1.226323 0.940750 -0.603171 +v -1.212795 0.918564 -0.598300 +v -1.218590 0.943552 -0.598062 +v -1.205079 0.888978 -0.598584 +v -0.941506 0.774705 -0.601878 +v -0.940825 0.771212 -0.581120 +v -0.942318 0.772599 -0.581120 +v -0.942977 0.775982 -0.601223 +v -0.941506 0.774705 -0.560362 +v -0.942977 0.775982 -0.561017 +v -0.943824 0.774047 -0.581120 +v -0.944461 0.777315 -0.600543 +v -0.944461 0.777315 -0.561697 +v -0.943547 0.785184 -0.619077 +v -0.945891 0.779451 -0.562708 +v -0.945287 0.776353 -0.581120 +v -0.945891 0.779451 -0.599532 +v -0.946371 0.787120 -0.616637 +v -0.947701 0.788745 -0.614787 +v -0.944955 0.786130 -0.617879 +v -0.960105 0.870177 -0.560362 +v -0.960785 0.873669 -0.581120 +v -0.961649 0.871823 -0.581120 +v -0.960990 0.868440 -0.561017 +v -0.960105 0.870177 -0.601878 +v -0.960990 0.868440 -0.601223 +v -0.962501 0.869916 -0.581120 +v -0.961864 0.866648 -0.561697 +v -0.961864 0.866648 -0.600543 +v -0.958064 0.859698 -0.619077 +v -0.959013 0.858292 -0.617879 +v -0.959955 0.856843 -0.616637 +v -0.960577 0.854837 -0.614787 +v -0.962388 0.864131 -0.599532 +v -0.962991 0.867229 -0.581120 +v -0.962388 0.864131 -0.562708 +v -0.954775 0.842816 -0.629753 +v -0.950805 0.822441 -0.633312 +v -0.951984 0.822211 -0.631664 +v -0.955828 0.841943 -0.628218 +v -0.946836 0.802066 -0.629753 +v -0.948140 0.802479 -0.628218 +v -0.953163 0.821981 -0.629956 +v -0.956877 0.841046 -0.626626 +v -0.949449 0.802917 -0.626626 +v -0.950619 0.803719 -0.624256 +v -0.954139 0.821791 -0.627412 +v -0.957660 0.839863 -0.624256 +v -0.973300 0.849606 -0.594251 +v -0.973728 0.851804 -0.581120 +v -0.965912 0.857972 -0.581120 +v -0.965421 0.855452 -0.596117 +v -0.973300 0.849606 -0.567991 +v -0.965421 0.855452 -0.566123 +v -0.965421 0.855452 -0.596117 +v -0.965912 0.857972 -0.581120 +v -0.963323 0.863209 -0.581120 +v -0.962770 0.860371 -0.597985 +v -0.965421 0.855452 -0.566123 +v -0.962770 0.860371 -0.564255 +v -0.988240 0.837299 -0.602306 +v -0.989365 0.843067 -0.592705 +v -0.973300 0.849606 -0.594251 +v -0.972014 0.843011 -0.605132 +v -0.989365 0.843067 -0.592705 +v -0.989740 0.844990 -0.581121 +v -0.989365 0.843067 -0.569540 +v -0.988240 0.837299 -0.559945 +v -0.972014 0.843011 -0.557113 +v -0.963948 0.847891 -0.553697 +v -0.963948 0.847891 -0.553697 +v -0.961112 0.851859 -0.550282 +v -0.961112 0.851859 -0.611958 +v -0.963948 0.847891 -0.608544 +v -0.965421 0.855452 -0.596117 +v -0.963948 0.847891 -0.608544 +v -0.969944 0.832386 -0.550363 +v -0.967446 0.819563 -0.548114 +v -0.958711 0.821008 -0.543415 +v -0.961575 0.835710 -0.545985 +v -0.964947 0.806739 -0.550368 +v -0.955847 0.806307 -0.545986 +v -0.961575 0.835710 -0.545985 +v -0.958711 0.821008 -0.543415 +v -0.955216 0.821595 -0.538718 +v -0.958441 0.838145 -0.541609 +v -0.955847 0.806307 -0.545986 +v -0.951992 0.805044 -0.541609 +v -0.986430 0.828005 -0.553994 +v -0.969944 0.832386 -0.550363 +v -0.986430 0.828005 -0.553994 +v -0.984244 0.816789 -0.552015 +v -0.982059 0.805573 -0.554007 +v -0.980248 0.796279 -0.559969 +v -0.962878 0.796114 -0.557123 +v -0.953473 0.794126 -0.553700 +v -0.953473 0.794126 -0.553700 +v -0.949320 0.791330 -0.550282 +v -0.961575 0.835710 -0.545985 +v -0.961593 0.789519 -0.568003 +v -0.961164 0.787321 -0.581134 +v -0.951509 0.784045 -0.581124 +v -0.952000 0.786565 -0.566127 +v -0.961593 0.789519 -0.594264 +v -0.952000 0.786565 -0.596121 +v -0.952000 0.786565 -0.566127 +v -0.951509 0.784045 -0.581124 +v -0.947109 0.779981 -0.581120 +v -0.947662 0.782818 -0.564256 +v -0.952000 0.786565 -0.596121 +v -0.947662 0.782818 -0.597985 +v -0.979123 0.790511 -0.569569 +v -0.961593 0.789519 -0.568003 +v -0.979123 0.790511 -0.569569 +v -0.978748 0.788588 -0.581153 +v -0.979123 0.790511 -0.592735 +v -0.980248 0.796279 -0.602329 +v -0.962878 0.796114 -0.605141 +v -0.953474 0.794126 -0.608547 +v -0.953474 0.794126 -0.608547 +v -0.949320 0.791330 -0.611959 +v -0.952000 0.786565 -0.566127 +v -0.964947 0.806739 -0.611892 +v -0.967446 0.819563 -0.614140 +v -0.958711 0.821008 -0.618830 +v -0.955847 0.806307 -0.616259 +v -0.969944 0.832386 -0.611887 +v -0.961575 0.835710 -0.616258 +v -0.955847 0.806307 -0.616259 +v -0.958711 0.821008 -0.618830 +v -0.955216 0.821595 -0.623523 +v -0.951992 0.805044 -0.620632 +v -0.961575 0.835710 -0.616258 +v -0.958441 0.838145 -0.620631 +v -0.982058 0.805573 -0.608281 +v -0.964947 0.806739 -0.611892 +v -0.982058 0.805573 -0.608281 +v -0.984244 0.816789 -0.610260 +v -0.986430 0.828005 -0.608268 +v -0.955847 0.806307 -0.616259 +v -1.262156 0.949539 -0.589811 +v -1.263793 0.949099 -0.579918 +v -1.266693 0.960319 -0.579794 +v -1.265015 0.960692 -0.589827 +v -1.262156 0.949539 -0.570020 +v -1.265015 0.960692 -0.569759 +v -1.268762 0.965271 -0.579748 +v -1.267015 0.965632 -0.590158 +v -1.267015 0.965632 -0.569337 +v -1.252720 0.931184 -0.598194 +v -1.257520 0.929445 -0.590030 +v -1.257245 0.950861 -0.598002 +v -1.259120 0.928865 -0.580160 +v -1.257520 0.929445 -0.570278 +v -1.252720 0.931184 -0.562077 +v -1.257245 0.950861 -0.561813 +v -1.259981 0.961813 -0.561442 +v -1.261771 0.966712 -0.560712 +v -1.267015 0.965632 -0.569337 +v -1.261771 0.966712 -0.560712 +v -1.263460 0.968231 -0.559366 +v -1.269075 0.967087 -0.568599 +v -1.269075 0.967087 -0.568599 +v -1.270947 0.966705 -0.579741 +v -1.269075 0.967087 -0.590884 +v -1.261771 0.966712 -0.598783 +v -1.267015 0.965632 -0.590158 +v -1.269075 0.967087 -0.590884 +v -1.263460 0.968231 -0.600116 +v -1.259981 0.961813 -0.598139 +v -1.261771 0.966712 -0.598783 +v -1.217211 0.838090 -0.558048 +v -1.209600 0.845715 -0.556221 +v -1.220529 0.877702 -0.555886 +v -1.228978 0.871536 -0.557683 +v -1.201988 0.853341 -0.557779 +v -1.212080 0.883868 -0.557475 +v -1.229245 0.910052 -0.555536 +v -1.238241 0.905397 -0.557297 +v -1.220249 0.914707 -0.557160 +v -1.208252 0.803502 -0.563518 +v -1.202948 0.810746 -0.558315 +v -1.223518 0.831771 -0.563239 +v -1.196547 0.819490 -0.556472 +v -1.190146 0.828234 -0.558014 +v -1.190146 0.828234 -0.558014 +v -1.184843 0.835479 -0.562969 +v -1.195682 0.859660 -0.562747 +v -1.201988 0.853341 -0.557779 +v -1.205079 0.888978 -0.562467 +v -1.212080 0.883868 -0.557475 +v -1.212795 0.918564 -0.562183 +v -1.220249 0.914707 -0.557160 +v -1.218590 0.943552 -0.561945 +v -1.226323 0.940750 -0.556896 +v -1.226323 0.940750 -0.556896 +v -1.235655 0.937368 -0.555239 +v -1.244988 0.933986 -0.556968 +v -1.245695 0.901541 -0.562432 +v -1.252720 0.931184 -0.562077 +v -1.235979 0.866427 -0.562848 +v -1.227432 0.827849 -0.591243 +v -1.228737 0.826542 -0.581390 +v -1.241773 0.862199 -0.580978 +v -1.240324 0.863256 -0.590836 +v -1.227432 0.827849 -0.571491 +v -1.240324 0.863256 -0.571084 +v -1.251863 0.898349 -0.580537 +v -1.250321 0.899147 -0.590401 +v -1.250321 0.899147 -0.570650 +v -1.208252 0.803502 -0.599635 +v -1.211544 0.799005 -0.591530 +v -1.223518 0.831771 -0.599356 +v -1.212641 0.797506 -0.581679 +v -1.211544 0.799005 -0.571778 +v -1.208252 0.803502 -0.563518 +v -1.223518 0.831771 -0.563239 +v -1.235979 0.866427 -0.562848 +v -1.245695 0.901541 -0.562432 +v -1.245695 0.901541 -0.598549 +v -1.235979 0.866427 -0.598965 +v -1.191767 0.863582 -0.570860 +v -1.190463 0.864889 -0.580713 +v -1.199285 0.893206 -0.580454 +v -1.200734 0.892149 -0.570596 +v -1.191767 0.863582 -0.590612 +v -1.200734 0.892149 -0.590348 +v -1.206626 0.921756 -0.580195 +v -1.208169 0.920958 -0.570331 +v -1.208169 0.920958 -0.590082 +v -1.181551 0.839976 -0.571074 +v -1.180454 0.841475 -0.580925 +v -1.181551 0.839976 -0.590826 +v -1.184843 0.835479 -0.599086 +v -1.195682 0.859660 -0.598864 +v -1.205079 0.888978 -0.598584 +v -1.212795 0.918564 -0.598300 +v -1.218590 0.943552 -0.598062 +v -1.213791 0.945291 -0.589861 +v -1.212191 0.945871 -0.579979 +v -1.213791 0.945291 -0.570110 +v -1.241665 1.020367 -0.553839 +v -1.252830 1.018091 -0.552118 +v -1.252665 1.017280 -0.546315 +v -1.239568 1.019950 -0.548552 +v -1.263995 1.015815 -0.553839 +v -1.265762 1.014611 -0.548552 +v -1.252216 1.015079 -0.541991 +v -1.237495 1.018080 -0.544559 +v -1.266937 1.012079 -0.544559 +v -1.236178 1.021607 -0.562722 +v -1.243047 1.020206 -0.560691 +v -1.232680 1.022199 -0.559177 +v -1.252854 1.018207 -0.559706 +v -1.262661 1.016208 -0.560691 +v -1.269529 1.014808 -0.562722 +v -1.272981 1.013984 -0.559177 +v -1.276577 1.012406 -0.555337 +v -1.279129 1.009593 -0.552275 +v -1.280386 1.004873 -0.550100 +v -1.267226 1.007555 -0.541763 +v -1.251342 1.010793 -0.538984 +v -1.235459 1.014031 -0.541763 +v -1.225303 1.020566 -0.552275 +v -1.222298 1.016714 -0.550100 +v -1.228753 1.022155 -0.555337 +v -1.217404 0.961587 -0.569949 +v -1.215767 0.962028 -0.579842 +v -1.217469 0.971283 -0.579771 +v -1.219147 0.970909 -0.569738 +v -1.217404 0.961587 -0.589740 +v -1.219147 0.970909 -0.589806 +v -1.217495 0.975838 -0.579745 +v -1.219243 0.975478 -0.569335 +v -1.219243 0.975478 -0.590155 +v -1.222316 0.960264 -0.561757 +v -1.222316 0.960264 -0.597947 +v -1.224181 0.969788 -0.598122 +v -1.224486 0.974397 -0.598781 +v -1.219243 0.975478 -0.590155 +v -1.224486 0.974397 -0.598781 +v -1.223531 0.976371 -0.600116 +v -1.217916 0.977515 -0.590884 +v -1.217495 0.975838 -0.579745 +v -1.216045 0.977897 -0.579741 +v -1.216045 0.977897 -0.579741 +v -1.217916 0.977515 -0.568599 +v -1.224486 0.974397 -0.560709 +v -1.223531 0.976371 -0.559366 +v -1.224181 0.969788 -0.561426 +v -1.230229 0.958134 -0.603049 +v -1.239780 0.955563 -0.604760 +v -1.242081 0.965801 -0.605011 +v -1.232292 0.967981 -0.603286 +v -1.249331 0.952992 -0.603079 +v -1.251870 0.963620 -0.603295 +v -1.243128 0.970555 -0.605921 +v -1.232934 0.972656 -0.604136 +v -1.253324 0.968453 -0.604136 +v -1.222316 0.960264 -0.597947 +v -1.257245 0.950861 -0.598002 +v -1.259981 0.961813 -0.598139 +v -1.261771 0.966712 -0.598783 +v -1.253324 0.968453 -0.604136 +v -1.254414 0.970075 -0.605847 +v -1.243128 0.970555 -0.605921 +v -1.243495 0.972301 -0.607757 +v -1.232934 0.972656 -0.604136 +v -1.232577 0.974527 -0.605847 +v -1.224181 0.969788 -0.598122 +v -1.224486 0.974397 -0.598781 +v -1.249331 0.952992 -0.556711 +v -1.239780 0.955563 -0.555000 +v -1.242081 0.965801 -0.554554 +v -1.251870 0.963620 -0.556278 +v -1.230229 0.958134 -0.556681 +v -1.232292 0.967981 -0.556269 +v -1.243128 0.970555 -0.553572 +v -1.253324 0.968453 -0.555357 +v -1.232934 0.972656 -0.555356 +v -1.257245 0.950861 -0.561813 +v -1.230229 0.958134 -0.556681 +v -1.232292 0.967981 -0.556269 +v -1.224181 0.969788 -0.561426 +v -1.224486 0.974397 -0.560709 +v -1.223531 0.976371 -0.559366 +v -1.232577 0.974527 -0.553636 +v -1.243495 0.972301 -0.551725 +v -1.254414 0.970075 -0.553636 +v -1.259981 0.961813 -0.561442 +v -1.262832 1.016173 -0.569558 +v -1.252854 1.018207 -0.569191 +v -1.252854 1.018207 -0.579741 +v -1.263192 1.016100 -0.579741 +v -1.242876 1.020241 -0.569558 +v -1.242516 1.020314 -0.579741 +v -1.252854 1.018207 -0.590292 +v -1.262832 1.016173 -0.589924 +v -1.242876 1.020241 -0.589924 +v -1.271520 1.014402 -0.569733 +v -1.234188 1.022012 -0.569733 +v -1.233223 1.022209 -0.579741 +v -1.234188 1.022012 -0.589750 +v -1.236178 1.021607 -0.596760 +v -1.243047 1.020206 -0.598791 +v -1.252854 1.018207 -0.599776 +v -1.262661 1.016208 -0.598791 +v -1.271520 1.014402 -0.589750 +v -1.269529 1.014808 -0.596760 +v -1.272485 1.014205 -0.579741 +v -1.215472 0.978991 -0.567451 +v -1.213407 0.979412 -0.579741 +v -1.210245 0.981341 -0.579741 +v -1.212543 0.980872 -0.566065 +v -1.215472 0.978991 -0.592032 +v -1.212543 0.980872 -0.593418 +v -1.207311 0.984393 -0.579741 +v -1.209841 0.983877 -0.564679 +v -1.209841 0.983877 -0.594803 +v -1.223531 0.976371 -0.559366 +v -1.217916 0.977515 -0.568599 +v -1.221665 0.977728 -0.557267 +v -1.221665 0.977728 -0.602216 +v -1.219434 0.979468 -0.604750 +v -1.217432 0.982330 -0.607283 +v -1.216253 0.987058 -0.609383 +v -1.208084 0.988723 -0.595951 +v -1.207311 0.984393 -0.579741 +v -1.209841 0.983877 -0.594803 +v -1.208084 0.988723 -0.595951 +v -1.205362 0.989279 -0.579741 +v -1.209841 0.983877 -0.564679 +v -1.208084 0.988723 -0.563531 +v -1.217432 0.982330 -0.552199 +v -1.216253 0.987058 -0.550100 +v -1.219434 0.979468 -0.554733 +v -1.212543 0.980872 -0.566065 +v -1.209841 0.983877 -0.564679 +v -1.217432 0.982330 -0.552199 +v -1.219434 0.979468 -0.554733 +v -1.263996 1.015815 -0.605643 +v -1.252830 1.018091 -0.607365 +v -1.252665 1.017280 -0.613167 +v -1.265763 1.014611 -0.610930 +v -1.241665 1.020368 -0.605643 +v -1.239568 1.019950 -0.610930 +v -1.265763 1.014611 -0.610930 +v -1.252665 1.017280 -0.613167 +v -1.252216 1.015079 -0.617491 +v -1.266937 1.012079 -0.614923 +v -1.239568 1.019950 -0.610930 +v -1.237495 1.018080 -0.614923 +v -1.272981 1.013984 -0.600306 +v -1.232680 1.022199 -0.600306 +v -1.228753 1.022155 -0.604145 +v -1.228753 1.022155 -0.604145 +v -1.225303 1.020566 -0.607208 +v -1.222299 1.016714 -0.609383 +v -1.235459 1.014031 -0.617719 +v -1.251342 1.010793 -0.620498 +v -1.267226 1.007555 -0.617719 +v -1.279129 1.009593 -0.607208 +v -1.280386 1.004873 -0.609383 +v -1.276577 1.012406 -0.604145 +v -1.276577 1.012406 -0.604145 +v -1.271902 0.967487 -0.592032 +v -1.273967 0.967067 -0.579741 +v -1.277632 0.967604 -0.579741 +v -1.275335 0.968072 -0.593418 +v -1.271902 0.967487 -0.567451 +v -1.275335 0.968072 -0.566065 +v -1.281527 0.969265 -0.579741 +v -1.278996 0.969780 -0.594803 +v -1.278996 0.969780 -0.564679 +v -1.265708 0.968750 -0.602216 +v -1.270947 0.966705 -0.579741 +v -1.269075 0.967087 -0.568599 +v -1.263460 0.968231 -0.559366 +v -1.265708 0.968750 -0.557267 +v -1.268443 0.969477 -0.554733 +v -1.275335 0.968072 -0.566065 +v -1.268443 0.969477 -0.554733 +v -1.271406 0.971328 -0.552199 +v -1.278996 0.969780 -0.564679 +v -1.274341 0.975217 -0.550100 +v -1.282510 0.973552 -0.563531 +v -1.281527 0.969265 -0.579741 +v -1.278996 0.969780 -0.564679 +v -1.282510 0.973552 -0.563531 +v -1.285233 0.972996 -0.579741 +v -1.278996 0.969780 -0.594803 +v -1.282510 0.973552 -0.595951 +v -1.271406 0.971328 -0.607283 +v -1.274341 0.975217 -0.609383 +v -1.268443 0.969477 -0.604750 +v -1.271406 0.971328 -0.607283 +v -1.285515 0.979937 -0.596664 +v -1.288358 0.979357 -0.579741 +v -1.290596 0.987347 -0.579741 +v -1.287714 0.987935 -0.596902 +v -1.285515 0.979937 -0.562818 +v -1.287714 0.987935 -0.562581 +v -1.291664 0.995575 -0.579741 +v -1.288822 0.996155 -0.596664 +v -1.288822 0.996155 -0.562818 +v -1.276988 0.981675 -0.610686 +v -1.274341 0.975217 -0.550100 +v -1.276988 0.981675 -0.548796 +v -1.279067 0.989698 -0.548362 +v -1.280294 0.997893 -0.548796 +v -1.280386 1.004873 -0.550100 +v -1.288556 1.003207 -0.563531 +v -1.291278 1.002652 -0.579741 +v -1.288556 1.003207 -0.595951 +v -1.280294 0.997893 -0.610686 +v -1.280386 1.004873 -0.609383 +v -1.279067 0.989697 -0.611120 +v -1.207818 0.995776 -0.562818 +v -1.204976 0.996355 -0.579741 +v -1.206043 1.004583 -0.579741 +v -1.208926 1.003996 -0.562581 +v -1.207818 0.995776 -0.596664 +v -1.208926 1.003996 -0.596902 +v -1.208282 1.012573 -0.579741 +v -1.211124 1.011994 -0.562818 +v -1.211124 1.011994 -0.596664 +v -1.216345 0.994037 -0.548796 +v -1.216253 0.987058 -0.609383 +v -1.216346 0.994037 -0.610686 +v -1.217573 1.002233 -0.611120 +v -1.219651 1.010255 -0.610686 +v -1.222299 1.016714 -0.609383 +v -1.214130 1.018379 -0.595951 +v -1.211407 1.018934 -0.579741 +v -1.214130 1.018379 -0.563531 +v -1.219651 1.010255 -0.548796 +v -1.222298 1.016714 -0.550100 +v -1.217573 1.002233 -0.548362 +v -1.230085 0.991236 -0.619389 +v -1.246666 0.987856 -0.622290 +v -1.248320 0.995965 -0.622888 +v -1.231505 0.999393 -0.619946 +v -1.263249 0.984476 -0.619389 +v -1.265134 0.992538 -0.619946 +v -1.249973 1.004074 -0.622290 +v -1.233391 1.007455 -0.619389 +v -1.266555 1.000694 -0.619389 +v -1.229414 0.984375 -0.617719 +v -1.230085 0.991236 -0.619389 +v -1.216346 0.994037 -0.610686 +v -1.229414 0.984375 -0.617719 +v -1.245297 0.981137 -0.620498 +v -1.245297 0.981137 -0.620498 +v -1.261180 0.977899 -0.617719 +v -1.263249 0.984476 -0.619389 +v -1.246666 0.987856 -0.622290 +v -1.274341 0.975217 -0.609383 +v -1.276988 0.981675 -0.610686 +v -1.276988 0.981675 -0.610686 +v -1.279067 0.989697 -0.611120 +v -1.280294 0.997893 -0.610686 +v -1.219651 1.010255 -0.610686 +v -1.217573 1.002233 -0.611120 +v -1.216346 0.994037 -0.610686 +v -1.263248 0.984476 -0.540093 +v -1.246666 0.987856 -0.537192 +v -1.248320 0.995965 -0.536595 +v -1.265134 0.992538 -0.539537 +v -1.230085 0.991237 -0.540093 +v -1.231505 0.999393 -0.539537 +v -1.249973 1.004074 -0.537192 +v -1.266555 1.000694 -0.540093 +v -1.233391 1.007455 -0.540093 +v -1.261180 0.977899 -0.541763 +v -1.276988 0.981675 -0.548796 +v -1.245297 0.981137 -0.538984 +v -1.229414 0.984375 -0.541763 +v -1.216253 0.987058 -0.550100 +v -1.216345 0.994037 -0.548796 +v -1.217573 1.002233 -0.548362 +v -1.231505 0.999393 -0.539537 +v -1.233391 1.007455 -0.540093 +v -1.235459 1.014031 -0.541763 +v -1.235459 1.014031 -0.541763 +v -1.251342 1.010793 -0.538984 +v -1.267226 1.007555 -0.541763 +v -1.280294 0.997893 -0.548796 +v -1.280386 1.004873 -0.550100 +v -1.279067 0.989698 -0.548362 +v -1.231644 0.975694 -0.608537 +v -1.243687 0.973239 -0.610644 +v -1.243938 0.974473 -0.614128 +v -1.230538 0.977204 -0.611783 +v -1.255730 0.970784 -0.608537 +v -1.257339 0.971740 -0.611783 +v -1.244419 0.976829 -0.617612 +v -1.229660 0.979838 -0.615030 +v -1.259178 0.973820 -0.615030 +v -1.255730 0.970784 -0.550946 +v -1.243687 0.973239 -0.548839 +v -1.243938 0.974472 -0.545355 +v -1.257339 0.971740 -0.547699 +v -1.231644 0.975694 -0.550946 +v -1.230538 0.977204 -0.547699 +v -1.244419 0.976829 -0.541871 +v -1.259178 0.973820 -0.544453 +v -1.229660 0.979838 -0.544453 +v -1.265708 0.968750 -0.557267 +v -1.232577 0.974527 -0.553636 +v -1.231644 0.975694 -0.550946 +v -1.230538 0.977204 -0.547699 +v -1.278210 1.012918 -0.568347 +v -1.279897 1.012574 -0.579741 +v -1.285418 1.010604 -0.579741 +v -1.283226 1.011051 -0.566375 +v -1.278210 1.012918 -0.591136 +v -1.283226 1.011051 -0.593108 +v -1.289206 1.007539 -0.579741 +v -1.286689 1.008052 -0.564718 +v -1.286689 1.008052 -0.594765 +v -1.279129 1.009593 -0.607208 +v -1.286689 1.008052 -0.594765 +v -1.279129 1.009593 -0.607208 +v -1.289206 1.007539 -0.579741 +v -1.286689 1.008052 -0.564718 +v -1.288556 1.003207 -0.563531 +v -1.227450 1.023265 -0.591136 +v -1.225763 1.023609 -0.579741 +v -1.219913 1.023957 -0.579741 +v -1.222105 1.023510 -0.593108 +v -1.227450 1.023265 -0.568347 +v -1.222105 1.023510 -0.566375 +v -1.215227 1.022620 -0.579741 +v -1.217743 1.022107 -0.594765 +v -1.217743 1.022107 -0.564718 +v -1.217743 1.022107 -0.564718 +v -1.225303 1.020566 -0.552275 +v -1.215227 1.022620 -0.579741 +v -1.217743 1.022107 -0.594765 +v -1.217743 1.022107 -0.594765 +v -1.214130 1.018379 -0.595951 +v -1.225303 1.020566 -0.607208 +v -1.015299 0.836131 -0.570529 +v -1.015633 0.837865 -0.581123 +v -1.047953 0.830971 -0.581125 +v -1.047671 0.829346 -0.571040 +v -1.015299 0.836131 -0.591721 +v -1.047671 0.829346 -0.591218 +v -1.081963 0.824900 -0.581129 +v -1.081771 0.823322 -0.571233 +v -1.081771 0.823322 -0.591038 +v -1.014298 0.830930 -0.561756 +v -1.014298 0.830930 -0.600507 +v -1.015299 0.836131 -0.591721 +v -1.046823 0.824472 -0.599589 +v -1.047671 0.829346 -0.591218 +v -1.081196 0.818585 -0.599262 +v -1.081771 0.823322 -0.591038 +v -1.112795 0.813934 -0.599235 +v -1.112892 0.818667 -0.591020 +v -1.112892 0.818667 -0.591020 +v -1.112925 0.820245 -0.581134 +v -1.112892 0.818667 -0.571269 +v -1.081196 0.818585 -0.563048 +v -1.112795 0.813934 -0.563118 +v -1.046823 0.824472 -0.562692 +v -1.006180 0.788744 -0.591780 +v -1.005846 0.787011 -0.581186 +v -1.039669 0.783308 -0.581239 +v -1.039952 0.784933 -0.591325 +v -1.006180 0.788744 -0.570588 +v -1.039952 0.784933 -0.571146 +v -1.076339 0.778589 -0.581322 +v -1.076530 0.780168 -0.591218 +v -1.076530 0.780168 -0.571413 +v -1.007180 0.793945 -0.600553 +v -1.007180 0.793945 -0.561802 +v -1.006180 0.788744 -0.570588 +v -1.040798 0.789808 -0.562775 +v -1.039952 0.784933 -0.571146 +v -1.077105 0.784904 -0.563189 +v -1.076530 0.780168 -0.571413 +v -1.112106 0.780273 -0.563342 +v -1.112009 0.775540 -0.571556 +v -1.112009 0.775540 -0.571556 +v -1.111976 0.773962 -0.581442 +v -1.112009 0.775540 -0.591307 +v -1.077105 0.784904 -0.599403 +v -1.112106 0.780273 -0.599459 +v -1.040798 0.789808 -0.599673 +v -1.008793 0.802325 -0.556342 +v -1.010739 0.812438 -0.554513 +v -1.043811 0.807140 -0.555815 +v -1.042163 0.797661 -0.557568 +v -1.012685 0.822551 -0.556317 +v -1.045458 0.816618 -0.557522 +v -1.079151 0.801745 -0.556328 +v -1.078032 0.792535 -0.558064 +v -1.080269 0.810954 -0.557987 +v -1.012685 0.822551 -0.556317 +v -1.045458 0.816618 -0.557522 +v -1.080269 0.810954 -0.557987 +v -1.112639 0.806308 -0.558089 +v -1.112639 0.806308 -0.558089 +v -1.112450 0.797103 -0.556458 +v -1.112261 0.787899 -0.558212 +v -1.012685 0.822551 -0.605967 +v -1.010739 0.812438 -0.607796 +v -1.043811 0.807140 -0.606549 +v -1.045458 0.816618 -0.604797 +v -1.008793 0.802325 -0.605992 +v -1.042163 0.797661 -0.604842 +v -1.079151 0.801745 -0.606123 +v -1.080269 0.810954 -0.604387 +v -1.078032 0.792535 -0.604464 +v -1.008793 0.802325 -0.605992 +v -1.042163 0.797661 -0.604842 +v -1.078032 0.792535 -0.604464 +v -1.112261 0.787899 -0.604487 +v -1.112261 0.787899 -0.604487 +v -1.112450 0.797103 -0.606118 +v -1.112639 0.806308 -0.604364 +v -1.137389 0.816212 -0.571277 +v -1.137177 0.817814 -0.581137 +v -1.155366 0.819281 -0.581119 +v -1.155879 0.817662 -0.571264 +v -1.137389 0.816212 -0.591029 +v -1.155879 0.817662 -0.591016 +v -1.169218 0.826538 -0.581056 +v -1.170039 0.824942 -0.571205 +v -1.170039 0.824942 -0.590956 +v -1.138029 0.811407 -0.563141 +v -1.138029 0.811407 -0.599258 +v -1.137389 0.816212 -0.591029 +v -1.157415 0.812804 -0.599261 +v -1.155879 0.817662 -0.591016 +v -1.172504 0.820153 -0.599213 +v -1.170039 0.824942 -0.590956 +v -1.170039 0.824942 -0.590956 +v -1.172504 0.820153 -0.599213 +v -1.169218 0.826538 -0.581056 +v -1.170039 0.824942 -0.571205 +v -1.172504 0.820153 -0.563096 +v -1.157415 0.812804 -0.563144 +v -1.172504 0.820153 -0.563096 +v -1.143209 0.772432 -0.591456 +v -1.143422 0.770831 -0.581596 +v -1.170392 0.771786 -0.581730 +v -1.169880 0.773405 -0.591585 +v -1.143209 0.772432 -0.571705 +v -1.169880 0.773405 -0.571834 +v -1.193320 0.779716 -0.581780 +v -1.192498 0.781312 -0.591631 +v -1.192498 0.781312 -0.571879 +v -1.142571 0.777237 -0.599592 +v -1.142571 0.777237 -0.563475 +v -1.143209 0.772432 -0.571705 +v -1.168343 0.778263 -0.563589 +v -1.169880 0.773405 -0.571834 +v -1.190033 0.786100 -0.563623 +v -1.192498 0.781312 -0.571879 +v -1.211544 0.799005 -0.571778 +v -1.193320 0.779716 -0.581780 +v -1.192498 0.781312 -0.571879 +v -1.192498 0.781312 -0.591631 +v -1.190033 0.786100 -0.599740 +v -1.168343 0.778263 -0.599705 +v -1.190033 0.786100 -0.599740 +v -1.141542 0.784979 -0.558321 +v -1.140300 0.794322 -0.556536 +v -1.162879 0.795533 -0.556594 +v -1.165867 0.786088 -0.558409 +v -1.139058 0.803665 -0.558138 +v -1.159891 0.804979 -0.558166 +v -1.181268 0.803127 -0.556587 +v -1.186061 0.793816 -0.558424 +v -1.176476 0.812438 -0.558136 +v -1.139058 0.803665 -0.558138 +v -1.159891 0.804979 -0.558166 +v -1.176476 0.812438 -0.558136 +v -1.176476 0.812438 -0.558136 +v -1.139058 0.803665 -0.604413 +v -1.140300 0.794322 -0.606197 +v -1.162879 0.795533 -0.606255 +v -1.159891 0.804979 -0.604441 +v -1.141542 0.784979 -0.604595 +v -1.165867 0.786088 -0.604684 +v -1.181268 0.803127 -0.606248 +v -1.176476 0.812438 -0.604411 +v -1.186061 0.793816 -0.604699 +v -1.141542 0.784979 -0.604595 +v -1.165867 0.786088 -0.604684 +v -1.186061 0.793816 -0.604699 +v -1.208252 0.803502 -0.599635 +v -1.202948 0.810746 -0.604589 +vt 0.733142 0.605767 +vt 0.733045 0.605020 +vt 0.732301 0.605152 +vt 0.732428 0.605921 +vt 0.732896 0.604283 +vt 0.732173 0.604383 +vt 0.731557 0.605283 +vt 0.731706 0.606021 +vt 0.731459 0.604536 +vt 0.733707 0.606180 +vt 0.733765 0.605644 +vt 0.733714 0.604902 +vt 0.733523 0.604185 +vt 0.732776 0.603638 +vt 0.732058 0.603691 +vt 0.731364 0.603888 +vt 0.732543 0.606612 +vt 0.733237 0.606416 +vt 0.998008 0.313836 +vt 0.998541 0.313784 +vt 0.998438 0.310187 +vt 0.997905 0.310210 +vt 0.999007 0.313647 +vt 0.998906 0.310130 +vt 0.998397 0.306257 +vt 0.997863 0.306248 +vt 0.998866 0.306287 +vt 0.735923 0.189890 +vt 0.735357 0.189889 +vt 0.735392 0.193261 +vt 0.735958 0.193266 +vt 0.734828 0.189869 +vt 0.734862 0.193214 +vt 0.734372 0.189813 +vt 0.734406 0.193084 +vt 0.951505 0.421930 +vt 0.951128 0.421692 +vt 0.948487 0.424041 +vt 0.948741 0.424388 +vt 0.945020 0.425269 +vt 0.945115 0.425672 +vt 0.941340 0.425269 +vt 0.941266 0.425672 +vt 0.938060 0.423936 +vt 0.937835 0.424278 +vt 0.998898 0.302749 +vt 0.998429 0.302639 +vt 0.997896 0.302601 +vt 0.997297 0.306250 +vt 0.997330 0.302598 +vt 0.997339 0.310217 +vt 0.997442 0.313847 +vt 0.920923 0.051359 +vt 0.921456 0.051308 +vt 0.921111 0.048173 +vt 0.920575 0.048199 +vt 0.921935 0.051149 +vt 0.921598 0.048083 +vt 0.920982 0.044421 +vt 0.920446 0.044416 +vt 0.921472 0.044414 +vt 0.998008 0.299838 +vt 0.997442 0.299832 +vt 0.998541 0.299898 +vt 0.999007 0.300068 +vt 0.935708 0.421286 +vt 0.935375 0.421505 +vt 0.934475 0.417811 +vt 0.934085 0.417871 +vt 0.922012 0.047896 +vt 0.921892 0.044388 +vt 0.922012 0.040855 +vt 0.921598 0.040718 +vt 0.921111 0.040642 +vt 0.920575 0.040606 +vt 0.919886 0.044404 +vt 0.920016 0.040590 +vt 0.920016 0.048192 +vt 0.920364 0.051356 +vt 0.734959 0.207518 +vt 0.735492 0.207457 +vt 0.735406 0.204440 +vt 0.734873 0.204477 +vt 0.735957 0.207284 +vt 0.735873 0.204334 +vt 0.735372 0.200749 +vt 0.734838 0.200756 +vt 0.735839 0.200725 +vt 0.920980 0.037316 +vt 0.920421 0.037297 +vt 0.921512 0.037379 +vt 0.921990 0.037527 +vt 0.935462 0.410584 +vt 0.935791 0.410845 +vt 0.938433 0.408495 +vt 0.938225 0.408126 +vt 0.941900 0.407268 +vt 0.941851 0.406842 +vt 0.945580 0.407268 +vt 0.945700 0.406842 +vt 0.948860 0.408600 +vt 0.949131 0.408236 +vt 0.735866 0.197019 +vt 0.735399 0.196960 +vt 0.734866 0.196936 +vt 0.734272 0.200754 +vt 0.734300 0.196930 +vt 0.734307 0.204479 +vt 0.734393 0.207524 +vt 0.735392 0.179289 +vt 0.734862 0.179355 +vt 0.734830 0.182383 +vt 0.735360 0.182342 +vt 0.734406 0.179531 +vt 0.734375 0.182493 +vt 0.734818 0.186080 +vt 0.735347 0.186069 +vt 0.734362 0.186108 +vt 0.734959 0.193556 +vt 0.734393 0.193546 +vt 0.735492 0.193608 +vt 0.735957 0.193741 +vt 0.951211 0.411251 +vt 0.951591 0.411009 +vt 0.952444 0.414725 +vt 0.952881 0.414643 +vt 0.952452 0.418410 +vt 0.952889 0.418498 +vt 0.735913 0.186066 +vt 0.735926 0.182335 +vt 0.735958 0.179279 +vt 0.939626 0.415381 +vt 0.939629 0.416937 +vt 0.939743 0.416919 +vt 0.939740 0.415412 +vt 0.940150 0.418405 +vt 0.940247 0.418341 +vt 0.939861 0.416901 +vt 0.939858 0.415444 +vt 0.940349 0.418274 +vt 0.940043 0.413888 +vt 0.939459 0.415337 +vt 0.940185 0.413994 +vt 0.939462 0.416964 +vt 0.940007 0.418498 +vt 0.941045 0.419669 +vt 0.941143 0.419524 +vt 0.941209 0.419425 +vt 0.941278 0.419322 +vt 0.941385 0.419166 +vt 0.940503 0.418173 +vt 0.940041 0.416872 +vt 0.940039 0.415491 +vt 0.940382 0.414147 +vt 0.940535 0.414261 +vt 0.940281 0.414070 +vt 0.947156 0.422034 +vt 0.944590 0.422943 +vt 0.944743 0.423811 +vt 0.947644 0.422784 +vt 0.941866 0.422943 +vt 0.941664 0.423811 +vt 0.944892 0.424622 +vt 0.948107 0.423484 +vt 0.941479 0.424622 +vt 0.948416 0.419803 +vt 0.946700 0.421330 +vt 0.949112 0.420295 +vt 0.944448 0.422127 +vt 0.942058 0.422127 +vt 0.939927 0.421261 +vt 0.939438 0.421956 +vt 0.938919 0.422696 +vt 0.938438 0.423386 +vt 0.950557 0.421305 +vt 0.949855 0.420818 +vt 0.937697 0.419994 +vt 0.936784 0.417422 +vt 0.935919 0.417570 +vt 0.936951 0.420478 +vt 0.936778 0.414695 +vt 0.935913 0.414486 +vt 0.935113 0.417706 +vt 0.936257 0.420928 +vt 0.935106 0.414289 +vt 0.938400 0.419540 +vt 0.937599 0.417283 +vt 0.937594 0.414889 +vt 0.938453 0.412757 +vt 0.937758 0.412265 +vt 0.937020 0.411740 +vt 0.936333 0.411245 +vt 0.934467 0.414126 +vt 0.939714 0.410526 +vt 0.942280 0.409618 +vt 0.942132 0.408747 +vt 0.939231 0.409774 +vt 0.945004 0.409618 +vt 0.945212 0.408747 +vt 0.941999 0.407928 +vt 0.938783 0.409067 +vt 0.945411 0.407928 +vt 0.940169 0.411231 +vt 0.942421 0.410434 +vt 0.944812 0.410434 +vt 0.946942 0.411300 +vt 0.947432 0.410604 +vt 0.947956 0.409862 +vt 0.948453 0.409164 +vt 0.949173 0.412566 +vt 0.950086 0.415138 +vt 0.950956 0.414988 +vt 0.949924 0.412080 +vt 0.950091 0.417866 +vt 0.950963 0.418071 +vt 0.951777 0.414844 +vt 0.950634 0.411622 +vt 0.951784 0.418262 +vt 0.948470 0.413021 +vt 0.949270 0.415278 +vt 0.949276 0.417672 +vt 0.945804 0.419949 +vt 0.944168 0.420529 +vt 0.944238 0.420922 +vt 0.946026 0.420289 +vt 0.942432 0.420529 +vt 0.942341 0.420922 +vt 0.944331 0.421451 +vt 0.946322 0.420746 +vt 0.942217 0.421451 +vt 0.946815 0.418678 +vt 0.945649 0.419715 +vt 0.947051 0.418841 +vt 0.944118 0.420257 +vt 0.942493 0.420257 +vt 0.940884 0.419900 +vt 0.940649 0.420235 +vt 0.940333 0.420685 +vt 0.947840 0.419396 +vt 0.947389 0.419078 +vt 0.939775 0.418649 +vt 0.939193 0.417010 +vt 0.938801 0.417076 +vt 0.939436 0.418868 +vt 0.939189 0.415271 +vt 0.938797 0.415176 +vt 0.938273 0.417167 +vt 0.938982 0.419163 +vt 0.938269 0.415050 +vt 0.939814 0.413722 +vt 0.939479 0.413484 +vt 0.939029 0.413165 +vt 0.941060 0.412614 +vt 0.942696 0.412034 +vt 0.942629 0.411639 +vt 0.940842 0.412272 +vt 0.944433 0.412034 +vt 0.944527 0.411639 +vt 0.942538 0.411110 +vt 0.940547 0.411815 +vt 0.944652 0.411110 +vt 0.941210 0.412851 +vt 0.942740 0.412309 +vt 0.944365 0.412309 +vt 0.945813 0.412897 +vt 0.945980 0.412663 +vt 0.946218 0.412326 +vt 0.946536 0.411876 +vt 0.947090 0.413914 +vt 0.947672 0.415553 +vt 0.948067 0.415485 +vt 0.947431 0.413693 +vt 0.947675 0.417292 +vt 0.948071 0.417385 +vt 0.948596 0.415394 +vt 0.947887 0.413398 +vt 0.948600 0.417511 +vt 0.946852 0.414068 +vt 0.947396 0.415602 +vt 0.947399 0.417229 +vt 0.989588 0.626098 +vt 0.988857 0.626423 +vt 0.990507 0.627855 +vt 0.991171 0.627441 +vt 0.988235 0.626811 +vt 0.989952 0.628331 +vt 0.992241 0.629143 +vt 0.992827 0.628659 +vt 0.991763 0.629689 +vt 0.989136 0.624640 +vt 0.988383 0.624752 +vt 0.990311 0.625897 +vt 0.987617 0.624970 +vt 0.986960 0.625251 +vt 0.986534 0.625552 +vt 0.987838 0.627200 +vt 0.989610 0.628794 +vt 0.991486 0.630210 +vt 0.993102 0.631326 +vt 0.993322 0.630763 +vt 0.993731 0.630166 +vt 0.994249 0.629631 +vt 0.993432 0.628326 +vt 0.994796 0.629257 +vt 0.991840 0.627166 +vt 0.944320 0.412483 +vt 0.942765 0.412483 +vt 0.942780 0.412606 +vt 0.944286 0.412606 +vt 0.941301 0.413002 +vt 0.941362 0.413108 +vt 0.942796 0.412734 +vt 0.944250 0.412734 +vt 0.941426 0.413219 +vt 0.945705 0.413046 +vt 0.941524 0.413381 +vt 0.942823 0.412921 +vt 0.944202 0.412921 +vt 0.945547 0.413260 +vt 0.945431 0.413420 +vt 0.945627 0.413151 +vt 0.942529 0.420087 +vt 0.944083 0.420087 +vt 0.944057 0.419970 +vt 0.942551 0.419970 +vt 0.945548 0.419569 +vt 0.945475 0.419468 +vt 0.944029 0.419849 +vt 0.942575 0.419849 +vt 0.945399 0.419363 +vt 0.946664 0.418576 +vt 0.946555 0.418507 +vt 0.946444 0.418435 +vt 0.946281 0.418326 +vt 0.945291 0.419206 +vt 0.943992 0.419666 +vt 0.942613 0.419666 +vt 0.947223 0.417190 +vt 0.947219 0.415634 +vt 0.947094 0.415657 +vt 0.947097 0.417165 +vt 0.946699 0.414166 +vt 0.946589 0.414236 +vt 0.946964 0.415681 +vt 0.946967 0.417138 +vt 0.946476 0.414308 +vt 0.946312 0.414414 +vt 0.946774 0.415715 +vt 0.946777 0.417096 +vt 0.995624 0.712950 +vt 0.996520 0.712869 +vt 0.996390 0.712206 +vt 0.995367 0.712299 +vt 0.997499 0.712797 +vt 0.997508 0.712125 +vt 0.944920 0.418681 +vt 0.943862 0.419055 +vt 0.943938 0.419385 +vt 0.945128 0.418964 +vt 0.942739 0.419056 +vt 0.942675 0.419385 +vt 0.994553 0.611175 +vt 0.995181 0.611552 +vt 0.995970 0.610564 +vt 0.995255 0.610135 +vt 0.995883 0.714203 +vt 0.996673 0.714131 +vt 0.997537 0.714068 +vt 0.998332 0.714025 +vt 0.998401 0.712749 +vt 0.998539 0.712070 +vt 0.941738 0.418650 +vt 0.941549 0.418928 +vt 0.946034 0.418158 +vt 0.945726 0.417965 +vt 0.996481 0.610115 +vt 0.995664 0.609623 +vt 0.338390 0.031353 +vt 0.337853 0.031923 +vt 0.338408 0.032373 +vt 0.339024 0.031718 +vt 0.337163 0.032553 +vt 0.337618 0.033095 +vt 0.941021 0.417842 +vt 0.940645 0.416783 +vt 0.940319 0.416826 +vt 0.940742 0.418019 +vt 0.940642 0.415660 +vt 0.940317 0.415562 +vt 0.998933 0.714012 +vt 0.999085 0.712734 +vt 0.337429 0.030492 +vt 0.336960 0.030991 +vt 0.336356 0.031543 +vt 0.335710 0.032056 +vt 0.336427 0.033139 +vt 0.336774 0.033766 +vt 0.941047 0.414659 +vt 0.940771 0.414436 +vt 0.999322 0.712053 +vt 0.995141 0.160544 +vt 0.995895 0.160568 +vt 0.995750 0.159890 +vt 0.994888 0.159863 +vt 0.996816 0.160614 +vt 0.996801 0.159942 +vt 0.941853 0.413943 +vt 0.942911 0.413569 +vt 0.942867 0.413209 +vt 0.941677 0.413630 +vt 0.944034 0.413569 +vt 0.944130 0.413209 +vt 0.335109 0.032452 +vt 0.335743 0.033590 +vt 0.995319 0.161825 +vt 0.995985 0.161846 +vt 0.996796 0.161886 +vt 0.997627 0.161942 +vt 0.997759 0.160677 +vt 0.997880 0.160015 +vt 0.945035 0.413975 +vt 0.945256 0.413666 +vt 0.335992 0.034283 +vt 0.993032 0.608757 +vt 0.993669 0.609158 +vt 0.993846 0.608505 +vt 0.993116 0.608045 +vt 0.994451 0.609643 +vt 0.994742 0.609060 +vt 0.945752 0.414782 +vt 0.946128 0.415841 +vt 0.946486 0.415767 +vt 0.946063 0.414575 +vt 0.946131 0.416964 +vt 0.946488 0.417032 +vt 0.998358 0.162006 +vt 0.998592 0.160750 +vt 0.992607 0.609969 +vt 0.993163 0.610320 +vt 0.993847 0.610744 +vt 0.998833 0.160098 +vt 0.515243 0.015503 +vt 0.514504 0.015509 +vt 0.514507 0.016366 +vt 0.515256 0.016354 +vt 0.513783 0.015528 +vt 0.513776 0.016379 +vt 0.514505 0.016756 +vt 0.515282 0.016742 +vt 0.513746 0.016767 +vt 0.515865 0.014018 +vt 0.515235 0.013978 +vt 0.515874 0.015511 +vt 0.514498 0.013974 +vt 0.513778 0.014003 +vt 0.513200 0.014063 +vt 0.513204 0.015556 +vt 0.513189 0.016391 +vt 0.513138 0.016774 +vt 0.334291 0.007963 +vt 0.334832 0.008150 +vt 0.334900 0.007971 +vt 0.334321 0.007771 +vt 0.513685 0.016906 +vt 0.514497 0.016894 +vt 0.515329 0.016878 +vt 0.740650 0.560240 +vt 0.741258 0.559920 +vt 0.741165 0.559771 +vt 0.740514 0.560114 +vt 0.515896 0.016345 +vt 0.515946 0.016727 +vt 0.329480 0.015388 +vt 0.330236 0.015591 +vt 0.331606 0.013787 +vt 0.330901 0.013480 +vt 0.330878 0.015838 +vt 0.332197 0.014139 +vt 0.333077 0.012113 +vt 0.332436 0.011719 +vt 0.333604 0.012552 +vt 0.327722 0.017221 +vt 0.328488 0.017245 +vt 0.328729 0.015268 +vt 0.329262 0.017331 +vt 0.329921 0.017462 +vt 0.183995 0.014003 +vt 0.184457 0.013590 +vt 0.184411 0.011657 +vt 0.183939 0.011985 +vt 0.184403 0.009384 +vt 0.183926 0.009613 +vt 0.184417 0.007123 +vt 0.183938 0.007253 +vt 0.184439 0.005226 +vt 0.183959 0.005277 +vt 0.334822 0.011265 +vt 0.334354 0.010761 +vt 0.333771 0.010301 +vt 0.331781 0.011440 +vt 0.333164 0.009967 +vt 0.330192 0.013274 +vt 0.515235 0.006164 +vt 0.514499 0.006102 +vt 0.514488 0.008884 +vt 0.515225 0.008925 +vt 0.513778 0.006188 +vt 0.513767 0.008950 +vt 0.514490 0.011654 +vt 0.515227 0.011676 +vt 0.513770 0.011700 +vt 0.515891 0.004093 +vt 0.515266 0.003830 +vt 0.515862 0.006376 +vt 0.514531 0.003751 +vt 0.513809 0.003855 +vt 0.513226 0.004138 +vt 0.513197 0.006421 +vt 0.513188 0.009121 +vt 0.513192 0.011811 +vt 0.515856 0.011766 +vt 0.515853 0.009076 +vt 0.185069 0.011459 +vt 0.185808 0.011401 +vt 0.185804 0.009210 +vt 0.185064 0.009247 +vt 0.186505 0.011482 +vt 0.186500 0.009271 +vt 0.185821 0.007031 +vt 0.185080 0.007047 +vt 0.186516 0.007070 +vt 0.185109 0.013339 +vt 0.185846 0.013264 +vt 0.186545 0.013362 +vt 0.187082 0.013632 +vt 0.187036 0.011699 +vt 0.187027 0.009426 +vt 0.187042 0.007165 +vt 0.187064 0.005269 +vt 0.186538 0.005224 +vt 0.185843 0.005201 +vt 0.185103 0.005201 +vt 0.733992 0.603998 +vt 0.734251 0.604808 +vt 0.734676 0.604735 +vt 0.734357 0.603789 +vt 0.734268 0.605660 +vt 0.734680 0.605737 +vt 0.735023 0.604681 +vt 0.734660 0.603618 +vt 0.735024 0.605808 +vt 0.733295 0.603699 +vt 0.733505 0.603397 +vt 0.734002 0.606394 +vt 0.734335 0.606626 +vt 0.734630 0.606811 +vt 0.734891 0.606942 +vt 0.735317 0.605859 +vt 0.735317 0.604643 +vt 0.734925 0.603496 +vt 0.733966 0.602807 +vt 0.734175 0.602621 +vt 0.733745 0.603069 +vt 0.185119 0.003968 +vt 0.185861 0.003978 +vt 0.185876 0.003284 +vt 0.185123 0.003268 +vt 0.186557 0.003991 +vt 0.186582 0.003292 +vt 0.185895 0.002958 +vt 0.185114 0.002939 +vt 0.186627 0.002963 +vt 0.184454 0.003961 +vt 0.187084 0.004003 +vt 0.187116 0.003288 +vt 0.187181 0.002953 +vt 0.740693 0.563477 +vt 0.740209 0.563017 +vt 0.740045 0.563087 +vt 0.740564 0.563581 +vt 0.741331 0.563692 +vt 0.741247 0.563811 +vt 0.185923 0.002838 +vt 0.185087 0.002817 +vt 0.184414 0.002908 +vt 0.184338 0.002783 +vt 0.184449 0.003245 +vt 0.995199 0.630269 +vt 0.994726 0.630836 +vt 0.995275 0.631205 +vt 0.995732 0.630614 +vt 0.994361 0.631466 +vt 0.994929 0.631860 +vt 0.995506 0.631361 +vt 0.995971 0.630742 +vt 0.995155 0.632047 +vt 0.995711 0.629868 +vt 0.994177 0.632056 +vt 0.994762 0.632472 +vt 0.994989 0.632687 +vt 0.740211 0.560825 +vt 0.740045 0.560741 +vt 0.739977 0.561570 +vt 0.739796 0.561539 +vt 0.739970 0.562344 +vt 0.739789 0.562367 +vt 0.996231 0.630194 +vt 0.996481 0.630300 +vt 0.334666 0.009366 +vt 0.335211 0.009869 +vt 0.335704 0.009364 +vt 0.335171 0.008833 +vt 0.335641 0.010415 +vt 0.336121 0.009940 +vt 0.335960 0.009121 +vt 0.335415 0.008562 +vt 0.336385 0.009726 +vt 0.334089 0.008998 +vt 0.183972 0.003960 +vt 0.183961 0.003216 +vt 0.336339 0.010466 +vt 0.336605 0.010279 +vt 0.336794 0.010255 +vt 0.336559 0.009662 +vt 0.336105 0.009013 +vt 0.335523 0.008414 +vt 0.334603 0.008442 +vt 0.730895 0.604123 +vt 0.730836 0.604659 +vt 0.730888 0.605401 +vt 0.731078 0.606119 +vt 0.731825 0.606665 +vt 0.731306 0.606604 +vt 0.741981 0.563959 +vt 0.741179 0.564013 +vt 0.741093 0.564256 +vt 0.741986 0.564196 +vt 0.740425 0.563759 +vt 0.740254 0.563973 +vt 0.740965 0.564489 +vt 0.741949 0.564423 +vt 0.740041 0.564178 +vt 0.742625 0.563419 +vt 0.741975 0.563762 +vt 0.742699 0.563581 +vt 0.739853 0.563215 +vt 0.739618 0.563368 +vt 0.739341 0.563511 +vt 0.739023 0.563608 +vt 0.739777 0.564325 +vt 0.304789 0.248152 +vt 0.304809 0.249211 +vt 0.305125 0.249331 +vt 0.305104 0.248192 +vt 0.304789 0.247022 +vt 0.305103 0.246976 +vt 0.304809 0.246009 +vt 0.305125 0.245885 +vt 0.337269 0.010351 +vt 0.337212 0.010893 +vt 0.337522 0.010945 +vt 0.337584 0.010348 +vt 0.742784 0.563775 +vt 0.730614 0.606305 +vt 0.730354 0.605496 +vt 0.729961 0.605568 +vt 0.730280 0.606514 +vt 0.730338 0.604644 +vt 0.729957 0.604566 +vt 0.310511 0.248966 +vt 0.310383 0.247985 +vt 0.310079 0.248003 +vt 0.310226 0.249105 +vt 0.310420 0.246992 +vt 0.310123 0.246886 +vt 0.731101 0.606907 +vt 0.730604 0.603909 +vt 0.730302 0.603677 +vt 0.310633 0.246156 +vt 0.310366 0.245944 +vt 0.309998 0.245800 +vt 0.309736 0.246817 +vt 0.309688 0.248022 +vt 0.309846 0.249211 +vt 0.310554 0.250001 +vt 0.310201 0.250178 +vt 0.310800 0.249761 +vt 0.730892 0.607234 +vt 0.741088 0.559557 +vt 0.741890 0.559504 +vt 0.741885 0.559238 +vt 0.740992 0.559298 +vt 0.742644 0.559758 +vt 0.742724 0.559521 +vt 0.741837 0.558963 +vt 0.740854 0.559029 +vt 0.742761 0.559274 +vt 0.740371 0.559936 +vt 0.741892 0.559723 +vt 0.742576 0.559953 +vt 0.743094 0.560446 +vt 0.743216 0.560302 +vt 0.743360 0.560126 +vt 0.334234 0.007303 +vt 0.334944 0.007548 +vt 0.335024 0.007261 +vt 0.334242 0.006991 +vt 0.335202 0.006912 +vt 0.334360 0.006621 +vt 0.669716 0.235435 +vt 0.669720 0.234337 +vt 0.669393 0.234238 +vt 0.669388 0.235419 +vt 0.669715 0.236559 +vt 0.669388 0.236629 +vt 0.669720 0.237520 +vt 0.669393 0.237664 +vt 0.740194 0.559719 +vt 0.739975 0.559492 +vt 0.668879 0.236672 +vt 0.668879 0.235409 +vt 0.668267 0.235405 +vt 0.668266 0.236686 +vt 0.668884 0.234176 +vt 0.668272 0.234155 +vt 0.667655 0.235407 +vt 0.667655 0.236671 +vt 0.667660 0.234174 +vt 0.668884 0.237752 +vt 0.669402 0.233291 +vt 0.668894 0.233187 +vt 0.668282 0.233152 +vt 0.667670 0.233186 +vt 0.667163 0.233288 +vt 0.667154 0.234235 +vt 0.667149 0.235416 +vt 0.667149 0.236626 +vt 0.667660 0.237751 +vt 0.667154 0.237661 +vt 0.668272 0.237781 +vt 0.305603 0.246947 +vt 0.305604 0.248216 +vt 0.306213 0.248225 +vt 0.306212 0.246937 +vt 0.305626 0.249406 +vt 0.306235 0.249431 +vt 0.306826 0.248217 +vt 0.306826 0.246947 +vt 0.306848 0.249407 +vt 0.305626 0.245809 +vt 0.305164 0.250193 +vt 0.305667 0.250306 +vt 0.306277 0.250343 +vt 0.306890 0.250306 +vt 0.307400 0.250194 +vt 0.307361 0.249332 +vt 0.307340 0.248192 +vt 0.307339 0.246976 +vt 0.306848 0.245809 +vt 0.307361 0.245886 +vt 0.306235 0.245783 +vt 0.308174 0.246821 +vt 0.308125 0.248079 +vt 0.308632 0.248063 +vt 0.308682 0.246787 +vt 0.308290 0.249321 +vt 0.308799 0.249321 +vt 0.309183 0.248043 +vt 0.309233 0.246784 +vt 0.309349 0.249284 +vt 0.738650 0.562560 +vt 0.738286 0.562537 +vt 0.738675 0.563631 +vt 0.307800 0.246884 +vt 0.307753 0.248089 +vt 0.738661 0.561355 +vt 0.739023 0.560195 +vt 0.738675 0.560068 +vt 0.738297 0.561279 +vt 0.739705 0.559283 +vt 0.739388 0.559116 +vt 0.308660 0.250330 +vt 0.309175 0.250345 +vt 0.309718 0.250293 +vt 0.309507 0.245723 +vt 0.308960 0.245710 +vt 0.308449 0.245760 +vt 0.336451 0.007175 +vt 0.337336 0.008085 +vt 0.337741 0.007693 +vt 0.336844 0.006770 +vt 0.338024 0.009072 +vt 0.338439 0.008693 +vt 0.338106 0.007317 +vt 0.337221 0.006406 +vt 0.338794 0.008303 +vt 0.336109 0.007555 +vt 0.335505 0.006503 +vt 0.336956 0.008427 +vt 0.337616 0.009372 +vt 0.337958 0.010234 +vt 0.338381 0.009971 +vt 0.338801 0.009606 +vt 0.306281 0.244947 +vt 0.306894 0.244984 +vt 0.307404 0.245096 +vt 0.339024 0.007966 +vt 0.338364 0.007022 +vt 0.337517 0.006150 +vt 0.336275 0.005735 +vt 0.336610 0.005506 +vt 0.335884 0.006089 +vt 0.739570 0.562420 +vt 0.739578 0.561507 +vt 0.739312 0.561467 +vt 0.739303 0.562484 +vt 0.739853 0.560627 +vt 0.739618 0.560488 +vt 0.739004 0.561417 +vt 0.738994 0.562537 +vt 0.739341 0.560339 +vt 0.335605 0.008270 +vt 0.336248 0.008931 +vt 0.336424 0.008827 +vt 0.335709 0.008091 +vt 0.336747 0.009647 +vt 0.336980 0.009624 +vt 0.336654 0.008669 +vt 0.335867 0.007859 +vt 0.337267 0.009547 +vt 0.334918 0.007782 +vt 0.743094 0.562792 +vt 0.743216 0.562890 +vt 0.743360 0.563006 +vt 0.733420 0.606898 +vt 0.732637 0.607165 +vt 0.732723 0.607588 +vt 0.733638 0.607258 +vt 0.731812 0.607182 +vt 0.731753 0.607591 +vt 0.732817 0.607903 +vt 0.733846 0.607528 +vt 0.731726 0.607903 +vt 0.730755 0.607495 +vt 0.666828 0.236553 +vt 0.666833 0.237511 +vt 0.666828 0.235431 +vt 0.666833 0.234337 +vt 0.734045 0.607717 +vt 0.731186 0.603406 +vt 0.731969 0.603138 +vt 0.731914 0.602715 +vt 0.730998 0.603045 +vt 0.732793 0.603122 +vt 0.732884 0.602712 +vt 0.731904 0.602400 +vt 0.730875 0.602774 +vt 0.732995 0.602400 +vt 0.307673 0.247024 +vt 0.307693 0.246014 +vt 0.307674 0.248151 +vt 0.307693 0.249208 +vt 0.310800 0.245338 +vt 0.310467 0.245144 +vt 0.730091 0.603491 +vt 0.997636 0.716051 +vt 0.996847 0.716109 +vt 0.997025 0.718545 +vt 0.997776 0.718492 +vt 0.996123 0.716174 +vt 0.996335 0.718609 +vt 0.997189 0.721089 +vt 0.997926 0.721043 +vt 0.996512 0.721158 +vt 0.998362 0.716013 +vt 0.993508 0.612855 +vt 0.994078 0.613197 +vt 0.992250 0.614960 +vt 0.992792 0.615276 +vt 0.990958 0.617191 +vt 0.991494 0.617483 +vt 0.989807 0.619254 +vt 0.990355 0.619513 +vt 0.996646 0.723471 +vt 0.997322 0.723391 +vt 0.998057 0.723357 +vt 0.998601 0.721031 +vt 0.998730 0.723379 +vt 0.998465 0.718462 +vt 0.996733 0.163884 +vt 0.995992 0.163847 +vt 0.995936 0.166362 +vt 0.996640 0.166394 +vt 0.995381 0.163828 +vt 0.995353 0.166341 +vt 0.995850 0.169094 +vt 0.996541 0.169120 +vt 0.995278 0.169067 +vt 0.997489 0.163933 +vt 0.334543 0.030432 +vt 0.333997 0.030789 +vt 0.333065 0.028429 +vt 0.332545 0.028760 +vt 0.331466 0.026272 +vt 0.330948 0.026579 +vt 0.329938 0.024187 +vt 0.329404 0.024463 +vt 0.995197 0.171712 +vt 0.995768 0.171750 +vt 0.996457 0.171764 +vt 0.997241 0.169141 +vt 0.997154 0.171750 +vt 0.997357 0.166434 +vt 0.335130 0.029969 +vt 0.335676 0.029473 +vt 0.334142 0.027549 +vt 0.333623 0.028003 +vt 0.336099 0.029025 +vt 0.334545 0.027141 +vt 0.332548 0.025473 +vt 0.332025 0.025884 +vt 0.332957 0.025107 +vt 0.998909 0.716002 +vt 0.998983 0.718462 +vt 0.999108 0.721060 +vt 0.999236 0.723463 +vt 0.331525 0.023190 +vt 0.331082 0.023497 +vt 0.330525 0.023848 +vt 0.992868 0.612466 +vt 0.992249 0.612085 +vt 0.991058 0.614257 +vt 0.991644 0.614603 +vt 0.991747 0.611771 +vt 0.990583 0.613975 +vt 0.989772 0.616567 +vt 0.990356 0.616871 +vt 0.989297 0.616326 +vt 0.998153 0.163990 +vt 0.997983 0.166476 +vt 0.997852 0.169152 +vt 0.997760 0.171705 +vt 0.988073 0.618568 +vt 0.988574 0.618746 +vt 0.989184 0.618986 +vt 0.998137 0.725158 +vt 0.997402 0.725174 +vt 0.997401 0.726458 +vt 0.998136 0.726464 +vt 0.996727 0.725273 +vt 0.996726 0.726578 +vt 0.997285 0.727335 +vt 0.998020 0.727363 +vt 0.996610 0.727477 +vt 0.998812 0.725235 +vt 0.988958 0.620925 +vt 0.989532 0.621136 +vt 0.988510 0.622280 +vt 0.989112 0.622431 +vt 0.988542 0.623469 +vt 0.989165 0.623555 +vt 0.186635 0.014653 +vt 0.187181 0.014959 +vt 0.185933 0.014542 +vt 0.185199 0.014629 +vt 0.184556 0.014917 +vt 0.998812 0.726606 +vt 0.998694 0.727571 +vt 0.996423 0.174081 +vt 0.995735 0.174085 +vt 0.995842 0.176054 +vt 0.996530 0.176028 +vt 0.995163 0.174028 +vt 0.995270 0.175976 +vt 0.996195 0.177664 +vt 0.996881 0.177615 +vt 0.995622 0.177562 +vt 0.997120 0.174012 +vt 0.328663 0.022337 +vt 0.328097 0.022569 +vt 0.327781 0.020649 +vt 0.327180 0.020825 +vt 0.327424 0.018989 +vt 0.326792 0.019103 +vt 0.327076 0.017272 +vt 0.514591 0.002163 +vt 0.513868 0.002277 +vt 0.515325 0.002253 +vt 0.515946 0.002550 +vt 0.997226 0.175893 +vt 0.997572 0.177412 +vt 0.329299 0.022070 +vt 0.329917 0.021806 +vt 0.329163 0.020316 +vt 0.328476 0.020472 +vt 0.330421 0.021586 +vt 0.329737 0.020204 +vt 0.328914 0.018875 +vt 0.328167 0.018911 +vt 0.329546 0.018883 +vt 0.999320 0.725406 +vt 0.999322 0.726883 +vt 0.999203 0.727953 +vt 0.184109 0.015388 +vt 0.988295 0.620736 +vt 0.987636 0.620590 +vt 0.987087 0.622158 +vt 0.987800 0.622188 +vt 0.987087 0.620506 +vt 0.986482 0.622191 +vt 0.987041 0.623577 +vt 0.987797 0.623480 +vt 0.986394 0.623736 +vt 0.997726 0.173879 +vt 0.997830 0.175653 +vt 0.998167 0.177064 +vt 0.998258 0.178589 +vt 0.998833 0.178147 +vn -0.1998 0.9798 0.0000 +vn -0.1997 0.9799 0.0000 +vn -0.2085 0.9780 0.0090 +vn -0.2024 0.9793 0.0092 +vn -0.2025 0.9792 0.0092 +vn -0.1997 0.9798 0.0086 +vn -0.1970 0.9804 0.0092 +vn -0.1907 0.9816 0.0028 +vn -0.1914 0.9815 0.0000 +vn -0.1907 0.9816 -0.0028 +vn -0.2082 0.9781 -0.0000 +vn -0.2088 0.9780 0.0028 +vn -0.2613 0.8981 -0.3538 +vn -0.4542 0.8234 -0.3401 +vn -0.4638 0.8859 0.0000 +vn -0.2728 0.9621 0.0000 +vn -0.7341 0.6173 -0.2830 +vn -0.7417 0.6707 -0.0000 +vn -0.4542 0.8234 0.3401 +vn -0.2613 0.8981 0.3537 +vn -0.7341 0.6173 0.2830 +vn -0.1555 0.6900 -0.7070 +vn -0.2190 0.6751 -0.7045 +vn -0.1987 0.9136 -0.3548 +vn -0.4153 0.6082 -0.6764 +vn -0.7020 0.4365 -0.5627 +vn -0.7021 0.4365 -0.5627 +vn -0.9187 0.1794 -0.3518 +vn -0.9396 0.2934 -0.1764 +vn -0.7341 0.6172 -0.2830 +vn -0.9449 0.3274 -0.0000 +vn -0.7418 0.6706 -0.0000 +vn -0.9396 0.2934 0.1764 +vn -0.7341 0.6172 0.2830 +vn -0.9187 0.1794 0.3518 +vn -0.7021 0.4365 0.5627 +vn -0.7020 0.4365 0.5627 +vn -0.4153 0.6082 0.6764 +vn -0.2190 0.6751 0.7045 +vn -0.1987 0.9136 0.3548 +vn -0.1555 0.6900 0.7070 +vn -0.2109 0.9775 -0.0000 +vn -0.1987 0.9136 -0.3547 +vn -0.1508 0.3310 0.9315 +vn -0.3480 0.2787 0.8951 +vn -0.2806 -0.0547 0.9583 +vn -0.0822 -0.0160 0.9965 +vn -0.6455 0.1626 0.7463 +vn -0.5887 -0.1147 0.8002 +vn -0.2180 -0.3890 0.8951 +vn -0.0155 -0.3634 0.9315 +vn -0.5373 -0.3930 0.7462 +vn -0.0878 0.3443 0.9347 +vn -0.8839 0.0075 0.4677 +vn -0.6455 0.1626 0.7462 +vn -0.8489 -0.1654 0.5020 +vn -0.5888 -0.1147 0.8001 +vn -0.8164 -0.3387 0.4677 +vn -0.7842 -0.5112 0.3518 +vn -0.4869 -0.6681 0.5627 +vn -0.1566 -0.7197 0.6764 +vn 0.0504 -0.7079 0.7045 +vn 0.0479 -0.3521 0.9347 +vn 0.1149 -0.6979 0.7070 +vn -0.0197 -0.0038 0.9998 +vn 0.0950 -0.9305 0.3538 +vn -0.1118 -0.9337 0.3401 +vn -0.0973 -0.9953 -0.0000 +vn 0.1083 -0.9941 -0.0000 +vn -0.4487 -0.8477 0.2830 +vn -0.4357 -0.9001 0.0000 +vn -0.1119 -0.9337 -0.3401 +vn 0.0949 -0.9305 -0.3538 +vn -0.4487 -0.8477 -0.2830 +vn 0.1588 -0.9214 0.3548 +vn -0.7607 -0.6247 0.1764 +vn -0.7529 -0.6581 0.0000 +vn -0.4358 -0.9001 -0.0000 +vn -0.7607 -0.6247 -0.1764 +vn -0.7842 -0.5112 -0.3518 +vn -0.4869 -0.6681 -0.5627 +vn -0.4868 -0.6681 -0.5627 +vn -0.1566 -0.7197 -0.6764 +vn 0.0504 -0.7079 -0.7045 +vn 0.1588 -0.9214 -0.3548 +vn 0.1149 -0.6979 -0.7070 +vn 0.1715 -0.9852 -0.0000 +vn 0.1588 -0.9214 0.3547 +vn -0.0155 -0.3634 -0.9315 +vn -0.2179 -0.3889 -0.8951 +vn -0.2806 -0.0547 -0.9583 +vn -0.0822 -0.0160 -0.9965 +vn -0.5372 -0.3930 -0.7463 +vn -0.5887 -0.1147 -0.8002 +vn -0.3480 0.2787 -0.8951 +vn -0.1508 0.3310 -0.9315 +vn -0.6455 0.1626 -0.7463 +vn 0.0479 -0.3521 -0.9347 +vn -0.2179 -0.3890 -0.8951 +vn -0.8164 -0.3387 -0.4677 +vn -0.5373 -0.3930 -0.7462 +vn -0.8489 -0.1654 -0.5020 +vn -0.5888 -0.1147 -0.8001 +vn -0.8839 0.0075 -0.4677 +vn -0.6456 0.1626 -0.7462 +vn -0.0878 0.3443 -0.9347 +vn -0.0197 -0.0038 -0.9998 +vn -0.8306 -0.3338 0.4457 +vn -0.8598 -0.1675 0.4824 +vn -0.7977 -0.1554 0.5827 +vn -0.7618 -0.3568 0.5407 +vn -0.8951 -0.0024 0.4458 +vn -0.8400 0.0447 0.5407 +vn -0.8594 -0.1674 0.4831 +vn -0.8286 -0.3341 0.4491 +vn -0.8935 -0.0014 0.4491 +vn -0.9138 -0.3633 0.1818 +vn -0.9290 -0.2763 0.2462 +vn -0.8036 -0.4943 0.3315 +vn -0.9457 -0.1842 0.2680 +vn -0.9648 -0.0926 0.2463 +vn -0.9833 -0.0063 0.1819 +vn -0.9304 0.1564 0.3315 +vn -0.8824 0.2402 0.4045 +vn -0.9274 0.1626 0.3369 +vn -0.9739 0.0383 0.2239 +vn -0.9515 -0.0704 0.2994 +vn -0.9290 -0.1810 0.3227 +vn -0.9084 -0.2920 0.2992 +vn -0.7985 -0.4989 0.3370 +vn -0.8885 -0.4008 0.2234 +vn -0.7277 -0.5539 0.4045 +vn -0.9864 -0.1642 -0.0103 +vn -0.9867 -0.1623 0.0000 +vn -0.9954 -0.0959 0.0000 +vn -0.9942 -0.1024 -0.0336 +vn -0.9864 -0.1642 0.0103 +vn -0.9942 -0.1023 0.0336 +vn -0.9990 0.0456 0.0000 +vn -0.9962 0.0295 -0.0825 +vn -0.9962 0.0295 0.0825 +vn -0.9822 -0.1879 -0.0034 +vn -0.9824 -0.1868 -0.0017 +vn -0.9851 -0.1708 -0.0207 +vn -0.9825 -0.1865 -0.0000 +vn -0.9824 -0.1868 0.0017 +vn -0.9822 -0.1879 0.0034 +vn -0.9851 -0.1708 0.0207 +vn -0.9900 -0.1242 0.0673 +vn -0.9860 -0.0243 0.1647 +vn -0.9860 -0.0243 -0.1647 +vn -0.9900 -0.1242 -0.0673 +vn -0.9831 -0.1811 0.0275 +vn -0.9811 -0.1911 0.0294 +vn -0.9770 -0.1903 0.0962 +vn -0.9835 -0.1573 0.0896 +vn -0.9792 -0.2012 0.0275 +vn -0.9706 -0.2233 0.0896 +vn -0.9539 -0.1858 0.2358 +vn -0.9700 -0.1050 0.2195 +vn -0.9384 -0.2668 0.2195 +vn -0.9819 -0.1896 0.0045 +vn -0.9815 -0.1912 0.0048 +vn -0.9812 -0.1929 0.0045 +vn -0.9809 -0.1945 0.0034 +vn -0.9772 -0.2115 0.0207 +vn -0.9642 -0.2565 0.0673 +vn -0.9230 -0.3477 0.1647 +vn -0.9759 -0.2181 0.0103 +vn -0.9755 -0.2200 -0.0000 +vn -0.9586 -0.2848 0.0000 +vn -0.9599 -0.2783 0.0336 +vn -0.9759 -0.2181 -0.0103 +vn -0.9599 -0.2783 -0.0336 +vn -0.9088 -0.4173 0.0000 +vn -0.9122 -0.4013 0.0825 +vn -0.9122 -0.4013 -0.0825 +vn -0.9807 -0.1956 0.0017 +vn -0.9806 -0.1959 -0.0000 +vn -0.9807 -0.1956 -0.0017 +vn -0.9809 -0.1945 -0.0034 +vn -0.9772 -0.2115 -0.0207 +vn -0.9642 -0.2565 -0.0673 +vn -0.9230 -0.3477 -0.1647 +vn -0.9792 -0.2012 -0.0275 +vn -0.9811 -0.1911 -0.0294 +vn -0.9770 -0.1903 -0.0962 +vn -0.9706 -0.2233 -0.0896 +vn -0.9831 -0.1811 -0.0275 +vn -0.9835 -0.1573 -0.0896 +vn -0.9539 -0.1858 -0.2358 +vn -0.9384 -0.2668 -0.2195 +vn -0.9700 -0.1049 -0.2195 +vn -0.9812 -0.1929 -0.0045 +vn -0.9815 -0.1912 -0.0048 +vn -0.9819 -0.1896 -0.0045 +vn -0.9949 -0.0931 -0.0376 +vn -0.9964 -0.0842 0.0000 +vn -0.9878 -0.1558 0.0000 +vn -0.9872 -0.1588 -0.0125 +vn -0.9949 -0.0931 0.0376 +vn -0.9872 -0.1588 0.0125 +vn -0.9831 -0.1829 0.0000 +vn -0.9830 -0.1837 -0.0029 +vn -0.9830 -0.1837 0.0029 +vn -0.9833 -0.0063 -0.1818 +vn -0.9940 0.0572 -0.0936 +vn -0.9903 -0.1187 -0.0728 +vn -0.9969 0.0788 -0.0000 +vn -0.9940 0.0572 0.0936 +vn -0.9903 -0.1187 0.0728 +vn -0.9856 -0.1674 0.0242 +vn -0.9826 -0.1857 0.0056 +vn -0.9826 -0.1857 -0.0056 +vn -0.9856 -0.1674 -0.0242 +vn -0.9832 -0.1532 0.0989 +vn -0.9758 -0.1901 0.1079 +vn -0.9809 -0.1911 0.0360 +vn -0.9833 -0.1788 0.0329 +vn -0.9688 -0.2271 0.0989 +vn -0.9785 -0.2034 0.0329 +vn -0.9815 -0.1912 0.0084 +vn -0.9821 -0.1883 0.0077 +vn -0.9810 -0.1941 0.0077 +vn -0.9624 -0.2617 0.0728 +vn -0.9764 -0.2148 0.0242 +vn -0.9804 -0.1967 0.0056 +vn -0.9571 -0.2872 0.0376 +vn -0.9552 -0.2960 -0.0000 +vn -0.9740 -0.2264 -0.0000 +vn -0.9746 -0.2234 0.0125 +vn -0.9571 -0.2872 -0.0376 +vn -0.9746 -0.2234 -0.0125 +vn -0.9799 -0.1995 0.0000 +vn -0.9800 -0.1987 0.0029 +vn -0.9800 -0.1987 -0.0029 +vn -0.8998 -0.4262 0.0935 +vn -0.8944 -0.4472 0.0000 +vn -0.8998 -0.4261 -0.0935 +vn -0.9138 -0.3633 -0.1818 +vn -0.9624 -0.2616 -0.0728 +vn -0.9764 -0.2148 -0.0242 +vn -0.9804 -0.1967 -0.0056 +vn -0.9688 -0.2271 -0.0989 +vn -0.9758 -0.1901 -0.1079 +vn -0.9809 -0.1911 -0.0360 +vn -0.9785 -0.2034 -0.0329 +vn -0.9832 -0.1532 -0.0989 +vn -0.9833 -0.1788 -0.0329 +vn -0.9815 -0.1912 -0.0084 +vn -0.9810 -0.1941 -0.0077 +vn -0.9821 -0.1883 -0.0077 +vn -0.9290 -0.2763 -0.2462 +vn -0.9457 -0.1842 -0.2680 +vn -0.9648 -0.0926 -0.2462 +vn 0.3285 0.1414 -0.9339 +vn -0.0018 0.0110 -0.9999 +vn 0.0001 0.0114 -0.9999 +vn 0.3415 0.1114 -0.9333 +vn -0.3275 -0.1305 -0.9358 +vn -0.3407 -0.0952 -0.9353 +vn -0.0000 0.0110 -0.9999 +vn 0.3454 0.0957 -0.9336 +vn -0.3456 -0.0771 -0.9352 +vn 0.5934 0.3692 -0.7152 +vn 0.2837 0.1951 -0.9389 +vn 0.6607 0.2596 -0.7043 +vn -0.0082 0.0063 -0.9999 +vn -0.2873 -0.1987 -0.9370 +vn -0.5591 -0.4197 -0.7151 +vn -0.6468 -0.2811 -0.7090 +vn -0.6766 -0.2067 -0.7068 +vn -0.6876 -0.1681 -0.7064 +vn -0.6905 -0.1535 -0.7069 +vn -0.3467 -0.0711 -0.9353 +vn 0.0000 0.0093 -1.0000 +vn 0.3464 0.0873 -0.9340 +vn 0.6873 0.1761 -0.7047 +vn 0.6899 0.1627 -0.7054 +vn 0.6805 0.2044 -0.7037 +vn -0.7777 -0.6056 -0.1688 +vn -0.7676 -0.6410 0.0000 +vn -0.6863 -0.7274 -0.0000 +vn -0.6975 -0.6868 -0.2045 +vn -0.7777 -0.6056 0.1688 +vn -0.6975 -0.6868 0.2045 +vn -0.7671 -0.6416 -0.0000 +vn -0.7751 -0.6086 -0.1695 +vn -0.7752 -0.6086 0.1695 +vn -0.8036 -0.4943 -0.3315 +vn -0.8730 -0.4746 0.1127 +vn -0.8676 -0.4973 -0.0000 +vn -0.8730 -0.4746 -0.1127 +vn -0.7985 -0.4988 -0.3369 +vn -0.8885 -0.4008 -0.2235 +vn -0.7277 -0.5539 -0.4045 +vn -0.9481 0.2694 0.1688 +vn -0.9520 0.3060 0.0000 +vn -0.9091 0.4166 -0.0000 +vn -0.9043 0.3747 0.2045 +vn -0.9481 0.2694 -0.1688 +vn -0.9043 0.3747 -0.2045 +vn -0.9518 0.3068 -0.0000 +vn -0.9469 0.2731 0.1695 +vn -0.9469 0.2731 -0.1695 +vn -0.9304 0.1565 -0.3315 +vn -0.8824 0.2402 -0.4045 +vn -0.9274 0.1626 -0.3370 +vn -0.9739 0.0383 -0.2238 +vn -0.9872 0.1128 -0.1130 +vn -0.9907 0.1360 0.0000 +vn -0.9872 0.1128 0.1130 +vn -0.8952 -0.0024 -0.4457 +vn -0.8598 -0.1675 -0.4824 +vn -0.7977 -0.1554 -0.5827 +vn -0.8400 0.0447 -0.5407 +vn -0.8306 -0.3338 -0.4457 +vn -0.7618 -0.3568 -0.5407 +vn -0.8594 -0.1674 -0.4831 +vn -0.8934 -0.0014 -0.4492 +vn -0.8287 -0.3341 -0.4491 +vn -0.9084 -0.2920 -0.2991 +vn -0.9290 -0.1810 -0.3227 +vn -0.9515 -0.0704 -0.2994 +vn -0.5065 0.7963 -0.3307 +vn -0.5138 0.8579 -0.0000 +vn -0.7866 0.6175 -0.0000 +vn -0.7822 0.5636 -0.2656 +vn -0.5065 0.7963 0.3307 +vn -0.7822 0.5635 0.2656 +vn -0.9683 0.2498 0.0000 +vn -0.9647 0.2159 -0.1505 +vn -0.7822 0.5636 0.2656 +vn -0.9648 0.2158 0.1505 +vn -0.2819 0.6621 -0.6943 +vn -0.3198 0.8819 -0.3463 +vn -0.4731 0.5839 -0.6597 +vn -0.3298 0.9440 0.0003 +vn -0.3199 0.8818 0.3466 +vn -0.2822 0.6617 0.6946 +vn -0.4733 0.5833 0.6601 +vn -0.7574 0.3880 0.5252 +vn -0.9492 0.1138 0.2934 +vn -0.9492 0.1139 -0.2935 +vn -0.7573 0.3882 -0.5252 +vn -0.4088 0.2595 0.8749 +vn -0.3476 -0.0677 0.9352 +vn -0.6488 -0.1269 0.7503 +vn -0.7018 0.1331 0.6999 +vn -0.2982 -0.3949 0.8690 +vn -0.6090 -0.3866 0.6926 +vn -0.7018 0.1332 0.6999 +vn -0.8871 -0.1732 0.4278 +vn -0.9181 -0.0262 0.3954 +vn -0.6091 -0.3866 0.6925 +vn -0.8623 -0.3202 0.3923 +vn -0.2184 0.3180 0.9226 +vn -0.2184 0.3181 0.9226 +vn -0.1569 -0.0308 0.9871 +vn -0.1032 -0.3805 0.9190 +vn -0.0537 -0.7220 0.6898 +vn -0.2537 -0.7156 0.6508 +vn -0.5739 -0.6372 0.5143 +vn -0.5740 -0.6372 0.5143 +vn -0.8403 -0.4587 0.2889 +vn -0.7018 0.1331 0.6998 +vn -0.2162 -0.9208 0.3247 +vn -0.2032 -0.9791 -0.0002 +vn -0.5239 -0.8518 -0.0000 +vn -0.5379 -0.8024 0.2585 +vn -0.2159 -0.9207 -0.3251 +vn -0.5376 -0.8026 -0.2586 +vn -0.5380 -0.8024 0.2585 +vn -0.8094 -0.5873 -0.0000 +vn -0.8182 -0.5558 0.1474 +vn -0.5376 -0.8025 -0.2586 +vn -0.8181 -0.5558 -0.1474 +vn -0.0188 -0.9391 0.3432 +vn -0.0079 -1.0000 -0.0003 +vn -0.0182 -0.9388 -0.3439 +vn -0.0524 -0.7219 -0.6900 +vn -0.2529 -0.7155 -0.6512 +vn -0.5734 -0.6374 -0.5147 +vn -0.5735 -0.6374 -0.5146 +vn -0.8403 -0.4588 -0.2890 +vn -0.2973 -0.3948 -0.8693 +vn -0.3467 -0.0676 -0.9356 +vn -0.6483 -0.1267 -0.7507 +vn -0.6084 -0.3867 -0.6931 +vn -0.4082 0.2599 -0.8751 +vn -0.7015 0.1334 -0.7001 +vn -0.6085 -0.3866 -0.6930 +vn -0.6483 -0.1267 -0.7508 +vn -0.8870 -0.1732 -0.4280 +vn -0.8622 -0.3202 -0.3924 +vn -0.9181 -0.0262 -0.3955 +vn -0.1019 -0.3792 -0.9197 +vn -0.2973 -0.3949 -0.8693 +vn -0.1558 -0.0301 -0.9873 +vn -0.2178 0.3192 -0.9223 +vn -0.9089 -0.2195 -0.3545 +vn -0.9714 -0.2376 0.0000 +vn -0.9474 -0.3200 0.0002 +vn -0.8852 -0.3039 -0.3522 +vn -0.9071 -0.2273 0.3542 +vn -0.8831 -0.3105 0.3518 +vn -0.7593 -0.6507 0.0002 +vn -0.7008 -0.6436 -0.3078 +vn -0.6983 -0.6462 0.3078 +vn -0.9114 -0.2093 -0.3543 +vn -0.6873 -0.1658 -0.7072 +vn -0.9736 -0.2282 -0.0000 +vn -0.9099 -0.2174 0.3533 +vn -0.6884 -0.1696 0.7052 +vn -0.6846 -0.1808 0.7061 +vn -0.6606 -0.2673 0.7015 +vn -0.4976 -0.6156 0.6110 +vn -0.6984 -0.6461 0.3078 +vn -0.1631 -0.9245 0.3444 +vn -0.2828 -0.9428 0.1766 +vn -0.3225 -0.9466 0.0001 +vn -0.2834 -0.9426 -0.1767 +vn -0.5014 -0.6105 -0.6131 +vn -0.7008 -0.6435 -0.3078 +vn -0.2832 -0.9427 -0.1766 +vn -0.1638 -0.9242 -0.3451 +vn -0.6642 -0.2549 -0.7028 +vn -0.5014 -0.6105 -0.6130 +vn -0.3342 -0.1527 0.9300 +vn -0.0117 -0.0133 0.9998 +vn -0.0070 -0.0121 0.9999 +vn -0.3451 -0.1173 0.9312 +vn 0.3208 0.1200 0.9395 +vn 0.3362 0.0908 0.9374 +vn -0.0035 -0.0115 0.9999 +vn -0.3471 -0.0988 0.9326 +vn 0.3428 0.0758 0.9364 +vn -0.5609 -0.4322 0.7061 +vn -0.2955 -0.2201 0.9297 +vn -0.6476 -0.2961 0.7021 +vn -0.0194 -0.0185 0.9996 +vn 0.2753 0.1732 0.9456 +vn 0.5918 0.3554 0.7235 +vn 0.6591 0.2455 0.7109 +vn 0.3209 0.1200 0.9395 +vn 0.6794 0.1903 0.7087 +vn 0.6873 0.1624 0.7080 +vn 0.3428 0.0758 0.9363 +vn 0.6908 0.1497 0.7074 +vn 0.3466 0.0687 0.9355 +vn 0.0001 -0.0120 0.9999 +vn -0.3457 -0.0920 0.9338 +vn -0.6865 -0.1845 0.7033 +vn -0.6885 -0.1696 0.7051 +vn -0.6766 -0.2227 0.7019 +vn -0.8510 -0.3847 -0.3574 +vn -0.9088 -0.4173 -0.0003 +vn -0.9516 -0.3073 0.0001 +vn -0.8913 -0.2826 -0.3546 +vn -0.8493 -0.3913 0.3544 +vn -0.8896 -0.2903 0.3526 +vn -0.9681 -0.2505 -0.0000 +vn -0.9066 -0.2298 -0.3539 +vn -0.9050 -0.2380 0.3527 +vn -0.7338 -0.5732 -0.3647 +vn -0.6467 -0.2811 -0.7090 +vn -0.7840 -0.6208 -0.0005 +vn -0.7324 -0.5775 0.3605 +vn -0.5609 -0.4322 0.7062 +vn -0.6475 -0.2961 0.7021 +vn -0.6765 -0.2228 0.7019 +vn -0.6875 -0.1681 -0.7064 +vn -0.6765 -0.2067 -0.7068 +vn 0.8779 0.3224 0.3540 +vn 0.9386 0.3449 0.0002 +vn 0.9620 0.2730 0.0001 +vn 0.9002 0.2536 0.3539 +vn 0.8767 0.3286 -0.3513 +vn 0.8993 0.2600 -0.3518 +vn 0.9715 0.2369 -0.0000 +vn 0.9092 0.2189 0.3542 +vn 0.9081 0.2252 -0.3532 +vn 0.8066 0.4674 0.3619 +vn 0.8668 0.4986 0.0002 +vn 0.8048 0.4729 -0.3588 +vn 0.5933 0.3692 -0.7153 +vn 0.6899 0.1627 -0.7053 +vn 0.9116 0.2093 -0.3537 +vn 0.9754 0.2205 0.0000 +vn 0.9127 0.2033 0.3544 +vn -0.1692 0.9820 0.0844 +vn -0.1990 0.9762 0.0860 +vn -0.1890 0.9272 0.3235 +vn -0.0779 0.9490 0.3056 +vn -0.2284 0.9699 0.0841 +vn -0.3003 0.9036 0.3055 +vn -0.1470 0.7208 0.6774 +vn 0.0871 0.7690 0.6333 +vn -0.3811 0.6739 0.6330 +vn -0.1909 0.9816 0.0090 +vn -0.1339 0.9888 0.0662 +vn -0.2085 0.9780 0.0089 +vn -0.2637 0.9623 0.0662 +vn -0.4162 0.8791 0.2322 +vn -0.6154 0.6268 0.4778 +vn -0.7133 0.2778 0.6434 +vn -0.3992 0.3385 0.8521 +vn -0.0816 0.4005 0.9127 +vn 0.2348 0.4677 0.8521 +vn 0.3210 0.8177 0.4778 +vn 0.5477 0.5348 0.6435 +vn 0.0389 0.9719 0.2322 +vn 0.9174 0.1815 0.3542 +vn 0.9801 0.1985 -0.0000 +vn 0.9957 0.0927 -0.0001 +vn 0.9331 0.0759 0.3516 +vn 0.9163 0.1873 -0.3539 +vn 0.9326 0.0806 -0.3517 +vn 0.9492 -0.3146 0.0002 +vn 0.8922 -0.3330 0.3050 +vn 0.8931 -0.3304 -0.3053 +vn 0.6957 0.1291 0.7066 +vn 0.6941 0.1413 -0.7059 +vn 0.7114 0.0351 -0.7019 +vn 0.6987 -0.3758 -0.6088 +vn 0.6987 -0.3759 -0.6087 +vn 0.5081 -0.7915 -0.3397 +vn 0.6220 -0.7636 -0.1733 +vn 0.6586 -0.7525 0.0000 +vn 0.6587 -0.7524 0.0000 +vn 0.6220 -0.7636 0.1734 +vn 0.6974 -0.3805 0.6073 +vn 0.5078 -0.7917 0.3396 +vn 0.7122 0.0250 0.7015 +vn 0.3500 0.0680 -0.9343 +vn 0.0034 -0.0076 -1.0000 +vn 0.0227 -0.1023 -0.9945 +vn 0.3680 -0.0326 -0.9293 +vn -0.3433 -0.0856 -0.9353 +vn -0.3220 -0.1770 -0.9301 +vn 0.0978 -0.4768 -0.8735 +vn 0.4004 -0.4246 -0.8120 +vn -0.2037 -0.5418 -0.8154 +vn -0.6641 -0.2549 -0.7028 +vn -0.2037 -0.5419 -0.8154 +vn 0.0011 -0.8859 -0.4638 +vn 0.0978 -0.4769 -0.8735 +vn 0.1731 -0.8482 -0.5007 +vn 0.3450 -0.8183 -0.4598 +vn 0.6987 -0.3758 -0.6087 +vn -0.3406 -0.1051 0.9343 +vn 0.0055 -0.0274 0.9996 +vn 0.0254 -0.1191 0.9926 +vn -0.3185 -0.1935 0.9280 +vn 0.3516 0.0508 0.9348 +vn 0.3696 -0.0469 0.9280 +vn 0.0992 -0.4840 0.8695 +vn -0.2007 -0.5488 0.8115 +vn 0.4000 -0.4311 0.8088 +vn -0.6846 -0.1808 0.7062 +vn 0.6974 -0.3806 0.6073 +vn 0.3447 -0.8187 0.4592 +vn 0.1731 -0.8486 0.4999 +vn 0.0015 -0.8863 0.4631 +vn -0.2089 0.9779 0.0026 +vn -0.1913 0.9815 -0.0000 +vn -0.1906 0.9817 -0.0027 +vn -0.1997 0.9798 0.0000 +vn -0.1910 0.9816 -0.0090 +vn -0.1971 0.9803 -0.0092 +vn -0.1996 0.9798 -0.0084 +vn -0.2025 0.9792 -0.0092 +vn -0.2088 0.9780 -0.0027 +vn -0.2086 0.9780 -0.0089 +vn -0.2081 0.9781 0.0000 +vn 0.4870 -0.8658 0.1149 +vn 0.5106 -0.8598 -0.0000 +vn 0.6355 -0.7721 -0.0000 +vn 0.6037 -0.7801 0.1643 +vn 0.4870 -0.8658 -0.1149 +vn 0.6037 -0.7801 -0.1643 +vn 0.8480 -0.5300 0.0000 +vn 0.8002 -0.5425 0.2559 +vn 0.8002 -0.5425 -0.2559 +vn 0.5079 -0.7917 0.3396 +vn 0.4115 -0.8827 0.2269 +vn 0.4115 -0.8827 -0.2269 +vn 0.4975 -0.8034 -0.3270 +vn 0.6373 -0.5787 -0.5088 +vn 0.7142 -0.2692 -0.6461 +vn 0.9189 -0.2238 -0.3250 +vn 0.8481 -0.5298 0.0000 +vn 0.9780 -0.2087 -0.0000 +vn 0.8002 -0.5424 0.2559 +vn 0.9189 -0.2238 0.3250 +vn 0.6373 -0.5787 0.5088 +vn 0.7142 -0.2693 0.6461 +vn 0.4975 -0.8034 0.3270 +vn 0.8002 -0.5425 0.2558 +vn 0.6373 -0.5788 0.5088 +vn -0.2287 0.9698 -0.0844 +vn -0.1989 0.9762 -0.0859 +vn -0.1890 0.9271 -0.3236 +vn -0.3002 0.9036 -0.3055 +vn -0.1695 0.9819 -0.0841 +vn -0.0775 0.9490 -0.3055 +vn -0.1469 0.7209 -0.6773 +vn -0.3811 0.6736 -0.6333 +vn 0.0869 0.7693 -0.6330 +vn -0.2638 0.9623 -0.0662 +vn -0.1340 0.9888 -0.0662 +vn 0.0388 0.9719 -0.2321 +vn 0.0388 0.9719 -0.2322 +vn 0.3210 0.8177 -0.4779 +vn 0.5477 0.5348 -0.6435 +vn 0.2348 0.4678 -0.8521 +vn -0.0816 0.4007 -0.9126 +vn -0.3992 0.3385 -0.8521 +vn -0.6155 0.6268 -0.4778 +vn -0.7133 0.2778 -0.6434 +vn -0.4162 0.8792 -0.2321 +vn -0.4162 0.8791 -0.2322 +vn -0.1092 -0.9874 -0.1149 +vn -0.1333 -0.9911 -0.0000 +vn -0.2826 -0.9592 -0.0000 +vn -0.2502 -0.9541 -0.1644 +vn -0.1092 -0.9874 0.1149 +vn -0.2502 -0.9541 0.1643 +vn -0.5729 -0.8196 0.0000 +vn -0.5240 -0.8124 -0.2559 +vn -0.5240 -0.8124 0.2559 +vn -0.0331 -0.9734 -0.2269 +vn -0.3224 -0.9466 0.0000 +vn -0.2826 -0.9428 0.1766 +vn -0.1632 -0.9245 0.3445 +vn -0.0331 -0.9734 0.2269 +vn -0.1432 -0.9341 0.3270 +vn -0.2502 -0.9541 0.1644 +vn -0.1433 -0.9341 0.3270 +vn -0.3599 -0.7820 0.5088 +vn -0.5518 -0.5273 0.6461 +vn -0.7579 -0.5657 0.3250 +vn -0.5241 -0.8123 0.2559 +vn -0.7579 -0.5656 0.3250 +vn -0.8183 -0.5749 -0.0000 +vn -0.5240 -0.8123 -0.2559 +vn -0.7579 -0.5656 -0.3250 +vn -0.3599 -0.7820 -0.5088 +vn -0.5518 -0.5273 -0.6461 +vn -0.1433 -0.9341 -0.3270 +vn -0.8711 -0.3441 -0.3503 +vn -0.9347 -0.3554 -0.0000 +vn -0.9798 -0.1997 -0.0000 +vn -0.9160 -0.1867 -0.3551 +vn -0.8711 -0.3441 0.3504 +vn -0.9160 -0.1867 0.3551 +vn -0.9992 -0.0389 -0.0000 +vn -0.9363 -0.0243 -0.3503 +vn -0.9363 -0.0243 0.3504 +vn -0.6503 -0.3013 -0.6973 +vn -0.5519 -0.5273 0.6461 +vn -0.6503 -0.3013 0.6974 +vn -0.6929 -0.1412 0.7071 +vn -0.7164 0.0227 0.6974 +vn -0.9171 0.2330 0.3236 +vn -0.9759 0.2184 -0.0001 +vn -0.9171 0.2330 -0.3235 +vn -0.7163 0.0227 -0.6974 +vn -0.6929 -0.1412 -0.7071 +vn 0.9363 0.0243 0.3503 +vn 0.9992 0.0388 -0.0000 +vn 0.9799 0.1997 -0.0000 +vn 0.9160 0.1867 0.3551 +vn 0.9363 0.0243 -0.3503 +vn 0.9160 0.1867 -0.3551 +vn 0.9347 0.3554 -0.0000 +vn 0.8711 0.3441 0.3503 +vn 0.8711 0.3441 -0.3503 +vn 0.7164 -0.0227 0.6973 +vn 0.7142 -0.2693 -0.6461 +vn 0.7164 -0.0227 -0.6974 +vn 0.6929 0.1412 -0.7071 +vn 0.6503 0.3013 -0.6973 +vn 0.5477 0.5349 -0.6434 +vn 0.7528 0.5733 -0.3235 +vn 0.8125 0.5830 0.0001 +vn 0.7527 0.5733 0.3235 +vn 0.6503 0.3013 0.6974 +vn 0.5477 0.5348 0.6434 +vn 0.6929 0.1412 0.7071 +vn 0.3759 -0.0899 -0.9223 +vn 0.0323 -0.1583 -0.9869 +vn 0.0000 0.0000 -1.0000 +vn 0.3479 0.0709 -0.9348 +vn -0.3107 -0.2298 -0.9223 +vn -0.3479 -0.0709 -0.9348 +vn -0.0323 0.1583 -0.9869 +vn 0.3107 0.2299 -0.9223 +vn -0.3759 0.0899 -0.9223 +vn 0.3989 -0.3298 -0.8556 +vn 0.3759 -0.0900 -0.9223 +vn 0.7163 -0.0227 -0.6974 +vn 0.0799 -0.3918 -0.9166 +vn 0.0798 -0.3918 -0.9166 +vn -0.2380 -0.4597 -0.8556 +vn -0.3107 -0.2299 -0.9223 +vn 0.0323 -0.1582 -0.9869 +vn -0.6503 -0.3013 -0.6974 +vn -0.7164 0.0227 -0.6974 +vn -0.3107 -0.2299 0.9223 +vn 0.0323 -0.1583 0.9869 +vn 0.0000 0.0000 1.0000 +vn -0.3479 -0.0709 0.9348 +vn 0.3759 -0.0899 0.9223 +vn 0.3479 0.0709 0.9348 +vn -0.0323 0.1583 0.9869 +vn -0.3759 0.0899 0.9223 +vn 0.3107 0.2299 0.9223 +vn -0.2380 -0.4596 0.8556 +vn 0.0799 -0.3918 0.9166 +vn 0.3989 -0.3298 0.8556 +vn 0.7142 -0.2693 0.6460 +vn 0.7163 -0.0227 0.6974 +vn 0.6928 0.1413 0.7071 +vn 0.2348 0.4678 0.8521 +vn -0.0816 0.4005 0.9126 +vn -0.7163 0.0227 0.6974 +vn 0.3015 -0.9036 -0.3043 +vn 0.1887 -0.9254 -0.3286 +vn 0.1765 -0.8656 -0.4685 +vn 0.3378 -0.8343 -0.4358 +vn 0.0763 -0.9495 -0.3042 +vn 0.0157 -0.8999 -0.4358 +vn 0.1376 -0.6748 -0.7251 +vn 0.3888 -0.6263 -0.6757 +vn -0.1126 -0.7285 -0.6757 +vn 0.0763 -0.9495 0.3043 +vn 0.1887 -0.9254 0.3286 +vn 0.1765 -0.8656 0.4686 +vn 0.0157 -0.8999 0.4358 +vn 0.3015 -0.9036 0.3042 +vn 0.3378 -0.8343 0.4357 +vn 0.1376 -0.6748 0.7251 +vn -0.1126 -0.7285 0.6757 +vn 0.3888 -0.6263 0.6757 +vn -0.2815 0.9591 0.0302 +vn -0.2833 0.9590 -0.0000 +vn -0.5061 0.8625 0.0000 +vn -0.4883 0.8653 0.1132 +vn -0.2814 0.9591 -0.0301 +vn -0.4881 0.8654 -0.1133 +vn -0.8108 0.5854 -0.0000 +vn -0.7674 0.5949 0.2390 +vn -0.7674 0.5949 -0.2390 +vn -0.6154 0.6268 -0.4779 +vn -0.7674 0.5950 -0.2390 +vn -0.6155 0.6268 -0.4779 +vn -0.8107 0.5854 -0.0000 +vn -0.7673 0.5950 0.2390 +vn -0.9171 0.2330 0.3235 +vn -0.1164 0.9927 -0.0302 +vn -0.1148 0.9934 0.0001 +vn 0.1280 0.9918 0.0000 +vn 0.1106 0.9874 -0.1132 +vn -0.1163 0.9928 0.0303 +vn 0.1103 0.9874 0.1133 +vn 0.5168 0.8561 0.0000 +vn 0.4732 0.8479 -0.2390 +vn 0.4732 0.8479 0.2390 +vn 0.4733 0.8479 0.2390 +vn 0.3210 0.8177 0.4779 +vn 0.5169 0.8560 0.0000 +vn 0.4734 0.8478 -0.2390 +vn 0.4733 0.8478 -0.2390 +vn 0.7528 0.5733 -0.3236 +vn 0.3210 0.8177 -0.4778 +vn -0.2261 0.9105 0.3462 +vn -0.2368 0.9716 0.0003 +vn -0.1918 0.9814 0.0004 +vn -0.1814 0.9221 0.3418 +vn -0.2260 0.9107 -0.3458 +vn -0.1813 0.9224 -0.3410 +vn -0.1620 0.9868 0.0003 +vn -0.1524 0.9291 0.3371 +vn -0.1522 0.9294 -0.3362 +vn -0.1876 0.6919 0.6972 +vn -0.1873 0.6925 -0.6967 +vn -0.2260 0.9107 -0.3457 +vn -0.1440 0.7082 -0.6912 +vn -0.1179 0.7185 -0.6854 +vn -0.1523 0.9294 -0.3362 +vn -0.0895 0.7248 -0.6831 +vn -0.1168 0.9352 -0.3342 +vn -0.1244 0.9922 0.0003 +vn -0.1171 0.9346 0.3360 +vn -0.1183 0.7156 0.6884 +vn -0.0902 0.7204 0.6876 +vn -0.1441 0.7065 0.6929 +vn 0.0749 -0.9357 -0.3447 +vn 0.0836 -0.9965 -0.0003 +vn 0.1185 -0.9930 -0.0003 +vn 0.1109 -0.9334 -0.3411 +vn 0.0741 -0.9359 0.3443 +vn 0.1098 -0.9338 0.3405 +vn 0.1286 -0.9917 0.0001 +vn 0.1219 -0.9337 -0.3368 +vn 0.1202 -0.9342 0.3360 +vn 0.0428 -0.7174 -0.6954 +vn 0.0412 -0.7184 0.6944 +vn 0.0788 -0.7193 0.6902 +vn 0.1097 -0.9338 0.3404 +vn 0.0913 -0.7230 0.6848 +vn 0.0815 -0.7282 0.6805 +vn 0.1063 -0.9369 0.3330 +vn 0.1139 -0.9935 -0.0002 +vn 0.1090 -0.9363 -0.3340 +vn 0.0943 -0.7201 -0.6874 +vn 0.0859 -0.7237 -0.6848 +vn 0.0810 -0.7175 -0.6919 +vn -0.0097 -0.3714 0.9284 +vn -0.0650 -0.0136 0.9978 +vn -0.0262 -0.0074 0.9996 +vn 0.0286 -0.3708 0.9283 +vn -0.1256 0.3438 0.9306 +vn -0.0850 0.3566 0.9304 +vn -0.0086 -0.0060 0.9999 +vn 0.0435 -0.3749 0.9261 +vn -0.0637 0.3639 0.9292 +vn -0.1256 0.3437 0.9306 +vn -0.0468 0.3655 0.9296 +vn -0.0468 0.3654 0.9297 +vn -0.0023 -0.0092 1.0000 +vn 0.0411 -0.3805 0.9239 +vn -0.1250 0.3460 -0.9299 +vn -0.0641 -0.0111 -0.9979 +vn -0.0250 -0.0024 -0.9997 +vn -0.0843 0.3605 -0.9289 +vn -0.0082 -0.3692 -0.9293 +vn 0.0305 -0.3668 -0.9298 +vn -0.0067 0.0023 -1.0000 +vn -0.0629 0.3710 -0.9265 +vn 0.0463 -0.3678 -0.9288 +vn 0.0455 -0.3700 -0.9279 +vn 0.0455 -0.3699 -0.9279 +vn 0.0010 0.0042 -1.0000 +vn -0.0451 0.3761 -0.9255 +vn -0.0120 0.9386 0.3449 +vn -0.0114 0.9999 -0.0001 +vn 0.2747 0.9615 0.0002 +vn 0.2512 0.8949 0.3689 +vn -0.0119 0.9395 -0.3423 +vn 0.2502 0.8966 -0.3655 +vn 0.6486 0.7611 0.0002 +vn 0.5962 0.7082 0.3782 +vn 0.5940 0.7120 -0.3745 +vn -0.0110 0.7139 0.7001 +vn -0.0100 0.7204 -0.6935 +vn 0.1771 0.6701 -0.7208 +vn 0.2502 0.8966 -0.3654 +vn 0.4212 0.5344 -0.7328 +vn 0.4211 0.5344 -0.7328 +vn 0.5961 0.7082 0.3782 +vn 0.4201 0.5222 0.7421 +vn 0.1762 0.6609 0.7295 +vn 0.0300 -0.9407 -0.3378 +vn 0.0306 -0.9995 -0.0001 +vn -0.1860 -0.9825 -0.0005 +vn -0.1742 -0.9197 -0.3519 +vn 0.0269 -0.9417 0.3355 +vn -0.1766 -0.9206 0.3484 +vn -0.5132 -0.8583 -0.0007 +vn -0.4805 -0.7969 -0.3661 +vn -0.4808 -0.7988 0.3615 +vn 0.0248 -0.7257 -0.6876 +vn 0.0191 -0.7317 0.6813 +vn 0.0269 -0.9417 0.3354 +vn -0.1387 -0.7070 0.6935 +vn -0.1766 -0.9206 0.3483 +vn -0.3710 -0.6027 0.7065 +vn -0.4807 -0.7989 0.3615 +vn -0.7324 -0.5776 0.3606 +vn -0.4808 -0.7989 0.3615 +vn -0.4804 -0.7970 -0.3661 +vn -0.3673 -0.5934 -0.7162 +vn -0.1332 -0.6997 -0.7019 +vn 0.0086 -0.3856 0.9226 +vn -0.0006 -0.0184 0.9998 +vn -0.0049 -0.0299 0.9995 +vn -0.0754 -0.3718 0.9252 +vn -0.0070 0.3533 0.9355 +vn 0.0781 0.3126 0.9467 +vn -0.0175 -0.0296 0.9994 +vn -0.1992 -0.3115 0.9291 +vn 0.1850 0.2448 0.9518 +vn -0.0040 0.3682 -0.9297 +vn 0.0043 0.0004 -1.0000 +vn 0.0028 -0.0075 -1.0000 +vn 0.0831 0.3316 -0.9397 +vn 0.0150 -0.3714 -0.9284 +vn -0.0674 -0.3546 -0.9326 +vn -0.0072 -0.0052 -1.0000 +vn 0.1924 0.2663 -0.9445 +vn -0.1907 -0.2919 -0.9373 +vn 0.0150 -0.3713 -0.9284 +vn -0.0674 -0.3545 -0.9326 +vn -0.5591 -0.4197 -0.7150 +usemtl Scene_-_Root +s off +f 35362/34749/24969 35363/34750/24969 35364/34751/24969 +f 35362/34749/24969 35364/34751/24969 35365/34752/24969 +f 35363/34750/24970 35366/34753/24970 35367/34754/24970 +f 35363/34750/24970 35367/34754/24970 35364/34751/24970 +f 35365/34752/24969 35364/34751/24969 35368/34755/24969 +f 35365/34752/24969 35368/34755/24969 35369/34756/24969 +f 35364/34751/24970 35367/34754/24970 35370/34757/24970 +f 35364/34751/24970 35370/34757/24970 35368/34755/24970 +f 35287/34758/24971 35286/34759/24972 35362/34749/24970 +f 35286/34759/24973 35285/34760/24974 35363/34750/24969 +f 35286/34759/24973 35363/34750/24969 35362/34749/24969 +f 35285/34760/24974 35283/34761/24975 35366/34753/24970 +f 35285/34760/24974 35366/34753/24970 35363/34750/24970 +f 35283/34761/24975 35372/34762/24976 35366/34753/24969 +f 35366/34753/24969 35373/34763/24977 35367/34754/24969 +f 35367/34754/24969 35374/34764/24978 35370/34757/24969 +f 35381/34765/24979 35365/34752/24969 35369/34756/24969 +f 35371/34766/24980 35362/34749/24969 35365/34752/24969 +s 1 +f 34749/34767/24981 34750/34768/24982 34751/34769/24983 +f 34749/34767/24981 34751/34769/24983 34752/34770/24984 +f 34750/34768/24982 34753/34771/24985 34754/34772/24986 +f 34750/34768/24982 34754/34772/24986 34751/34769/24983 +f 34752/34770/24984 34751/34769/24983 34755/34773/24987 +f 34752/34770/24984 34755/34773/24987 34756/34774/24988 +f 34751/34769/24983 34754/34772/24986 34757/34775/24989 +f 34751/34769/24983 34757/34775/24989 34755/34773/24987 +f 34758/34776/24990 34759/34777/24991 34760/34778/24981 +f 34758/34776/24990 34760/34778/24981 34761/34779/24992 +f 34759/34777/24991 34762/34780/24993 34763/34781/24982 +f 34759/34777/24991 34763/34781/24982 34760/34778/24981 +f 34762/34780/24993 34764/34782/24994 34765/34783/24985 +f 34762/34780/24993 34765/34783/24985 34763/34781/24982 +f 34766/34784/24995 34767/34785/24996 34768/34786/24997 +f 34766/34784/24995 34768/34786/24997 34769/34787/24998 +f 34769/34787/24998 34768/34786/24997 34770/34788/24999 +f 34769/34787/24998 34770/34788/24999 34771/34789/25000 +f 34771/34789/25000 34770/34788/24999 34772/34790/25001 +f 34771/34789/25000 34772/34790/25001 34773/34791/25002 +f 34773/34791/25002 34772/34790/25001 34774/34792/25003 +f 34773/34791/25002 34774/34792/25003 34775/34793/25004 +f 34755/34773/24987 34757/34775/24989 34776/34794/25005 +f 34755/34773/24987 34776/34794/25005 34777/34795/25006 +f 34756/34774/24988 34755/34773/24987 34777/34795/25006 +f 34756/34774/24988 34777/34795/25006 34778/34796/25007 +f 34779/34797/25008 34756/34774/24988 34778/34796/25007 +f 34779/34797/25008 34778/34796/25007 34780/34798/25009 +f 34781/34799/25010 34752/34770/24984 34756/34774/24988 +f 34781/34799/25010 34756/34774/24988 34779/34797/25008 +f 34782/34800/25011 34749/34767/24981 34752/34770/24984 +f 34782/34800/25011 34752/34770/24984 34781/34799/25010 +f 34783/34801/25012 34784/34802/25013 34785/34803/25014 +f 34783/34801/25012 34785/34803/25014 34786/34804/25015 +f 34784/34802/25013 34787/34805/25016 34788/34806/25017 +f 34784/34802/25013 34788/34806/25017 34785/34803/25014 +f 34786/34804/25015 34785/34803/25014 34789/34807/25018 +f 34786/34804/25015 34789/34807/25018 34790/34808/25019 +f 34785/34803/25014 34788/34806/25017 34791/34809/25020 +f 34785/34803/25014 34791/34809/25020 34789/34807/25018 +f 34780/34798/25009 34778/34796/25007 34792/34810/25012 +f 34780/34798/25009 34792/34810/25012 34793/34811/25021 +f 34778/34796/25007 34777/34795/25006 34794/34812/25013 +f 34778/34796/25007 34794/34812/25013 34792/34810/25012 +f 34777/34795/25006 34776/34794/25005 34795/34813/25016 +f 34777/34795/25006 34795/34813/25016 34794/34812/25013 +f 34775/34793/25004 34774/34792/25003 34796/34814/25022 +f 34775/34793/25004 34796/34814/25022 34797/34815/25023 +f 34797/34815/25023 34796/34814/25022 34798/34816/25024 +f 34797/34815/25023 34798/34816/25024 34799/34817/25025 +f 34788/34806/25017 34800/34818/25024 34801/34819/25026 +f 34788/34806/25017 34801/34819/25026 34791/34809/25020 +f 34791/34809/25020 34801/34819/25026 34802/34820/25027 +f 34791/34809/25020 34802/34820/25027 34803/34821/25028 +f 34789/34807/25018 34791/34809/25020 34803/34821/25028 +f 34789/34807/25018 34803/34821/25028 34804/34822/25029 +f 34790/34808/25019 34789/34807/25018 34804/34822/25029 +f 34790/34808/25019 34804/34822/25029 34805/34823/25030 +f 34806/34824/25031 34790/34808/25019 34805/34823/25030 +f 34806/34824/25031 34805/34823/25030 34807/34825/25032 +f 34808/34826/25033 34786/34804/25015 34790/34808/25019 +f 34808/34826/25033 34790/34808/25019 34806/34824/25031 +f 34809/34827/25021 34783/34801/25012 34786/34804/25015 +f 34809/34827/25021 34786/34804/25015 34808/34826/25033 +f 34810/34828/25034 34811/34829/25035 34812/34830/25036 +f 34810/34828/25034 34812/34830/25036 34813/34831/25037 +f 34811/34829/25035 34814/34832/25038 34815/34833/25039 +f 34811/34829/25035 34815/34833/25039 34812/34830/25036 +f 34813/34831/25037 34812/34830/25036 34816/34834/25040 +f 34813/34831/25037 34816/34834/25040 34817/34835/25041 +f 34812/34830/25036 34815/34833/25039 34818/34836/25042 +f 34812/34830/25036 34818/34836/25042 34816/34834/25040 +f 34807/34825/25032 34805/34823/25030 34819/34837/25034 +f 34807/34825/25032 34819/34837/25034 34820/34838/25043 +f 34805/34823/25030 34804/34822/25029 34821/34839/25035 +f 34805/34823/25030 34821/34839/25035 34819/34837/25034 +f 34804/34822/25029 34803/34821/25028 34822/34840/25038 +f 34804/34822/25029 34822/34840/25038 34821/34839/25035 +f 34823/34841/25028 34824/34842/25027 34825/34843/25044 +f 34823/34841/25028 34825/34843/25044 34826/34844/25038 +f 34826/34844/25038 34825/34843/25044 34827/34845/25045 +f 34826/34844/25038 34827/34845/25045 34828/34846/25046 +f 34828/34846/25046 34827/34845/25045 34829/34847/25047 +f 34828/34846/25046 34829/34847/25047 34830/34848/25042 +f 34830/34848/25042 34829/34847/25047 34831/34849/25048 +f 34830/34848/25042 34831/34849/25048 34832/34850/25049 +f 34816/34834/25040 34818/34836/25042 34833/34851/25050 +f 34816/34834/25040 34833/34851/25050 34834/34852/25051 +f 34817/34835/25041 34816/34834/25040 34834/34852/25051 +f 34817/34835/25041 34834/34852/25051 34835/34853/25052 +f 34836/34854/25053 34817/34835/25041 34835/34853/25052 +f 34836/34854/25053 34835/34853/25052 34837/34855/25054 +f 34838/34856/25055 34813/34831/25037 34817/34835/25041 +f 34838/34856/25055 34817/34835/25041 34836/34854/25053 +f 34839/34857/25056 34810/34828/25034 34813/34831/25037 +f 34839/34857/25056 34813/34831/25037 34838/34856/25055 +f 34840/34858/25057 34841/34859/25058 34842/34860/25059 +f 34840/34858/25057 34842/34860/25059 34843/34861/25060 +f 34841/34859/25058 34844/34862/25061 34845/34863/25062 +f 34841/34859/25058 34845/34863/25062 34842/34860/25059 +f 34843/34861/25060 34842/34860/25059 34846/34864/25063 +f 34843/34861/25060 34846/34864/25063 34847/34865/25064 +f 34842/34860/25059 34845/34863/25062 34848/34866/25065 +f 34842/34860/25059 34848/34866/25065 34846/34864/25063 +f 34837/34855/25054 34835/34853/25052 34849/34867/25057 +f 34837/34855/25054 34849/34867/25057 34850/34868/25066 +f 34835/34853/25052 34834/34852/25051 34851/34869/25067 +f 34835/34853/25052 34851/34869/25067 34849/34867/25057 +f 34834/34852/25051 34833/34851/25050 34852/34870/25061 +f 34834/34852/25051 34852/34870/25061 34851/34869/25067 +f 34832/34850/25049 34831/34849/25048 34853/34871/25068 +f 34832/34850/25049 34853/34871/25068 34854/34872/25069 +f 34854/34872/25069 34853/34871/25068 34855/34873/25070 +f 34854/34872/25069 34855/34873/25070 34856/34874/25071 +f 34856/34874/25071 34855/34873/25070 34857/34875/25072 +f 34856/34874/25071 34857/34875/25072 34858/34876/25073 +f 34858/34876/25073 34857/34875/25072 34767/34785/24996 +f 34858/34876/25073 34767/34785/24996 34766/34784/24995 +f 34846/34864/25063 34848/34866/25065 34764/34782/24994 +f 34846/34864/25063 34764/34782/24994 34762/34780/24993 +f 34847/34865/25064 34846/34864/25063 34762/34780/24993 +f 34847/34865/25064 34762/34780/24993 34759/34777/24991 +f 34859/34877/25074 34847/34865/25064 34759/34777/24991 +f 34859/34877/25074 34759/34777/24991 34758/34776/24990 +f 34860/34878/25075 34843/34861/25060 34847/34865/25064 +f 34860/34878/25075 34847/34865/25064 34859/34877/25074 +f 34861/34879/25066 34840/34858/25057 34843/34861/25060 +f 34861/34879/25066 34843/34861/25060 34860/34878/25075 +f 34862/34880/25076 34863/34881/25077 34864/34882/25078 +f 34862/34880/25076 34864/34882/25078 34865/34883/25079 +f 34863/34881/25077 34866/34884/25080 34867/34885/25081 +f 34863/34881/25077 34867/34885/25081 34864/34882/25078 +f 34865/34883/25079 34864/34882/25078 34868/34886/25082 +f 34865/34883/25079 34868/34886/25082 34869/34887/25083 +f 34864/34882/25078 34867/34885/25081 34870/34888/25084 +f 34864/34882/25078 34870/34888/25084 34868/34886/25082 +f 34871/34889/25085 34872/34890/25086 34862/34880/25076 +f 34871/34889/25085 34862/34880/25076 34873/34891/25087 +f 34872/34890/25086 34874/34892/25088 34863/34881/25077 +f 34872/34890/25086 34863/34881/25077 34862/34880/25076 +f 34874/34892/25088 34875/34893/25089 34866/34884/25080 +f 34874/34892/25088 34866/34884/25080 34863/34881/25077 +f 34875/34893/25089 34876/34894/25090 34877/34895/25091 +f 34875/34893/25089 34877/34895/25091 34866/34884/25080 +f 34866/34884/25080 34877/34895/25091 34878/34896/25092 +f 34866/34884/25080 34878/34896/25092 34867/34885/25081 +f 34867/34885/25081 34878/34896/25092 34879/34897/25093 +f 34867/34885/25081 34879/34897/25093 34870/34888/25084 +f 34870/34888/25084 34879/34897/25093 34880/34898/25094 +f 34870/34888/25084 34880/34898/25094 34881/34899/25095 +f 34868/34886/25082 34870/34888/25084 34881/34899/25095 +f 34868/34886/25082 34881/34899/25095 34882/34900/25096 +f 34869/34887/25083 34868/34886/25082 34882/34900/25096 +f 34869/34887/25083 34882/34900/25096 34883/34901/25097 +f 34884/34902/25098 34869/34887/25083 34883/34901/25097 +f 34884/34902/25098 34883/34901/25097 34885/34903/25099 +f 34886/34904/25100 34865/34883/25079 34869/34887/25083 +f 34886/34904/25100 34869/34887/25083 34884/34902/25098 +f 34873/34891/25087 34862/34880/25076 34865/34883/25079 +f 34873/34891/25087 34865/34883/25079 34886/34904/25100 +f 34887/34905/25101 34888/34906/25102 34889/34907/25103 +f 34887/34905/25101 34889/34907/25103 34890/34908/25104 +f 34888/34906/25102 34891/34909/25105 34892/34910/25106 +f 34888/34906/25102 34892/34910/25106 34889/34907/25103 +f 34890/34908/25104 34889/34907/25103 34893/34911/25107 +f 34890/34908/25104 34893/34911/25107 34894/34912/25108 +f 34889/34907/25103 34892/34910/25106 34895/34913/25109 +f 34889/34907/25103 34895/34913/25109 34893/34911/25107 +f 34896/34914/25110 34897/34915/25111 34887/34905/25101 +f 34896/34914/25110 34887/34905/25101 34898/34916/25112 +f 34897/34915/25111 34899/34917/25113 34888/34906/25102 +f 34897/34915/25111 34888/34906/25102 34887/34905/25101 +f 34899/34917/25113 34900/34918/25114 34891/34909/25105 +f 34899/34917/25113 34891/34909/25105 34888/34906/25102 +f 34900/34918/25114 34901/34919/25115 34902/34920/25116 +f 34900/34918/25114 34902/34920/25116 34891/34909/25105 +f 34891/34909/25105 34902/34920/25116 34903/34921/25117 +f 34891/34909/25105 34903/34921/25117 34892/34910/25106 +f 34892/34910/25106 34903/34921/25117 34904/34922/25118 +f 34892/34910/25106 34904/34922/25118 34895/34913/25109 +f 34895/34913/25109 34904/34922/25118 34774/34792/25003 +f 34895/34913/25109 34774/34792/25003 34772/34790/25001 +f 34893/34911/25107 34895/34913/25109 34772/34790/25001 +f 34893/34911/25107 34772/34790/25001 34770/34788/24999 +f 34894/34912/25108 34893/34911/25107 34770/34788/24999 +f 34894/34912/25108 34770/34788/24999 34768/34786/24997 +f 34905/34923/25119 34894/34912/25108 34768/34786/24997 +f 34905/34923/25119 34768/34786/24997 34767/34785/24996 +f 34906/34924/25120 34890/34908/25104 34894/34912/25108 +f 34906/34924/25120 34894/34912/25108 34905/34923/25119 +f 34898/34916/25112 34887/34905/25101 34890/34908/25104 +f 34898/34916/25112 34890/34908/25104 34906/34924/25120 +f 34907/34925/25121 34908/34926/25122 34909/34927/25123 +f 34907/34925/25121 34909/34927/25123 34910/34928/25124 +f 34908/34926/25122 34911/34929/25125 34912/34930/25126 +f 34908/34926/25122 34912/34930/25126 34909/34927/25123 +f 34910/34928/25124 34909/34927/25123 34913/34931/25127 +f 34910/34928/25124 34913/34931/25127 34914/34932/25128 +f 34909/34927/25123 34912/34930/25126 34915/34933/25129 +f 34909/34927/25123 34915/34933/25129 34913/34931/25127 +f 34901/34919/25115 34916/34934/25130 34907/34925/25121 +f 34901/34919/25115 34907/34925/25121 34902/34920/25116 +f 34916/34934/25130 34917/34935/25131 34908/34926/25122 +f 34916/34934/25130 34908/34926/25122 34907/34925/25121 +f 34917/34935/25131 34918/34936/25132 34911/34929/25125 +f 34917/34935/25131 34911/34929/25125 34908/34926/25122 +f 34918/34936/25132 34919/34937/25133 34920/34938/25134 +f 34918/34936/25132 34920/34938/25134 34911/34929/25125 +f 34911/34929/25125 34920/34938/25134 34921/34939/25135 +f 34911/34929/25125 34921/34939/25135 34912/34930/25126 +f 34912/34930/25126 34921/34939/25135 34922/34940/25136 +f 34912/34930/25126 34922/34940/25136 34915/34933/25129 +f 34915/34933/25129 34922/34940/25136 34824/34842/25027 +f 34915/34933/25129 34824/34842/25027 34923/34941/25026 +f 34913/34931/25127 34915/34933/25129 34923/34941/25026 +f 34913/34931/25127 34923/34941/25026 34798/34816/25024 +f 34914/34932/25128 34913/34931/25127 34798/34816/25024 +f 34914/34932/25128 34798/34816/25024 34796/34814/25022 +f 34904/34922/25118 34914/34932/25128 34796/34814/25022 +f 34904/34922/25118 34796/34814/25022 34774/34792/25003 +f 34903/34921/25117 34910/34928/25124 34914/34932/25128 +f 34903/34921/25117 34914/34932/25128 34904/34922/25118 +f 34902/34920/25116 34907/34925/25121 34910/34928/25124 +f 34902/34920/25116 34910/34928/25124 34903/34921/25117 +f 34924/34942/25137 34925/34943/25138 34926/34944/25139 +f 34924/34942/25137 34926/34944/25139 34927/34945/25140 +f 34925/34943/25138 34928/34946/25141 34929/34947/25142 +f 34925/34943/25138 34929/34947/25142 34926/34944/25139 +f 34927/34945/25140 34926/34944/25139 34930/34948/25143 +f 34927/34945/25140 34930/34948/25143 34931/34949/25144 +f 34926/34944/25139 34929/34947/25142 34932/34950/25145 +f 34926/34944/25139 34932/34950/25145 34930/34948/25143 +f 34919/34937/25133 34933/34951/25146 34924/34942/25137 +f 34919/34937/25133 34924/34942/25137 34920/34938/25134 +f 34933/34951/25146 34934/34952/25147 34925/34943/25138 +f 34933/34951/25146 34925/34943/25138 34924/34942/25137 +f 34934/34952/25147 34935/34953/25148 34928/34946/25141 +f 34934/34952/25147 34928/34946/25141 34925/34943/25138 +f 34935/34953/25148 34936/34954/25149 34937/34955/25150 +f 34935/34953/25148 34937/34955/25150 34928/34946/25141 +f 34928/34946/25141 34937/34955/25150 34938/34956/25151 +f 34928/34946/25141 34938/34956/25151 34929/34947/25142 +f 34929/34947/25142 34938/34956/25151 34939/34957/25152 +f 34929/34947/25142 34939/34957/25152 34932/34950/25145 +f 34932/34950/25145 34939/34957/25152 34831/34849/25048 +f 34932/34950/25145 34831/34849/25048 34829/34847/25047 +f 34930/34948/25143 34932/34950/25145 34829/34847/25047 +f 34930/34948/25143 34829/34847/25047 34827/34845/25045 +f 34931/34949/25144 34930/34948/25143 34827/34845/25045 +f 34931/34949/25144 34827/34845/25045 34825/34843/25044 +f 34922/34940/25136 34931/34949/25144 34825/34843/25044 +f 34922/34940/25136 34825/34843/25044 34824/34842/25027 +f 34921/34939/25135 34927/34945/25140 34931/34949/25144 +f 34921/34939/25135 34931/34949/25144 34922/34940/25136 +f 34920/34938/25134 34924/34942/25137 34927/34945/25140 +f 34920/34938/25134 34927/34945/25140 34921/34939/25135 +f 34940/34958/25153 34941/34959/25154 34942/34960/25155 +f 34940/34958/25153 34942/34960/25155 34943/34961/25156 +f 34941/34959/25154 34944/34962/25157 34945/34963/25158 +f 34941/34959/25154 34945/34963/25158 34942/34960/25155 +f 34943/34961/25156 34942/34960/25155 34946/34964/25159 +f 34943/34961/25156 34946/34964/25159 34947/34965/25160 +f 34942/34960/25155 34945/34963/25158 34948/34966/25161 +f 34942/34960/25155 34948/34966/25161 34946/34964/25159 +f 34936/34954/25149 34949/34967/25162 34940/34958/25153 +f 34936/34954/25149 34940/34958/25153 34937/34955/25150 +f 34949/34967/25162 34950/34968/25163 34941/34959/25154 +f 34949/34967/25162 34941/34959/25154 34940/34958/25153 +f 34950/34968/25163 34951/34969/25164 34944/34962/25157 +f 34950/34968/25163 34944/34962/25157 34941/34959/25154 +f 34951/34969/25164 34896/34914/25110 34898/34916/25112 +f 34951/34969/25164 34898/34916/25112 34944/34962/25157 +f 34944/34962/25157 34898/34916/25112 34906/34924/25120 +f 34944/34962/25157 34906/34924/25120 34945/34963/25158 +f 34945/34963/25158 34906/34924/25120 34905/34923/25119 +f 34945/34963/25158 34905/34923/25119 34948/34966/25161 +f 34948/34966/25161 34905/34923/25119 34767/34785/24996 +f 34948/34966/25161 34767/34785/24996 34857/34875/25072 +f 34946/34964/25159 34948/34966/25161 34857/34875/25072 +f 34946/34964/25159 34857/34875/25072 34855/34873/25070 +f 34947/34965/25160 34946/34964/25159 34855/34873/25070 +f 34947/34965/25160 34855/34873/25070 34853/34871/25068 +f 34939/34957/25152 34947/34965/25160 34853/34871/25068 +f 34939/34957/25152 34853/34871/25068 34831/34849/25048 +f 34938/34956/25151 34943/34961/25156 34947/34965/25160 +f 34938/34956/25151 34947/34965/25160 34939/34957/25152 +f 34937/34955/25150 34940/34958/25153 34943/34961/25156 +f 34937/34955/25150 34943/34961/25156 34938/34956/25151 +f 34952/34970/25165 34953/34971/25166 34954/34972/25167 +f 34952/34970/25165 34954/34972/25167 34955/34973/25168 +f 34953/34971/25166 34956/34974/25169 34957/34975/25170 +f 34953/34971/25166 34957/34975/25170 34954/34972/25167 +f 34955/34973/25168 34954/34972/25167 34958/34976/25171 +f 34955/34973/25168 34958/34976/25171 34959/34977/25172 +f 34954/34972/25167 34957/34975/25170 34960/34978/25173 +f 34954/34972/25167 34960/34978/25173 34958/34976/25171 +f 34961/34979/25174 34962/34980/25175 34952/34970/25165 +f 34961/34979/25174 34952/34970/25165 34963/34981/25176 +f 34962/34980/25175 34964/34982/25177 34953/34971/25166 +f 34962/34980/25175 34953/34971/25166 34952/34970/25165 +f 34964/34982/25177 34965/34983/25178 34956/34974/25169 +f 34964/34982/25177 34956/34974/25169 34953/34971/25166 +f 34965/34983/25178 34876/34894/25090 34966/34984/25179 +f 34965/34983/25178 34966/34984/25179 34956/34974/25169 +f 34956/34974/25169 34966/34984/25179 34967/34985/25180 +f 34956/34974/25169 34967/34985/25180 34957/34975/25170 +f 34957/34975/25170 34967/34985/25180 34968/34986/25181 +f 34957/34975/25170 34968/34986/25181 34960/34978/25173 +f 34960/34978/25173 34968/34986/25181 34901/34919/25115 +f 34960/34978/25173 34901/34919/25115 34900/34918/25114 +f 34958/34976/25171 34960/34978/25173 34900/34918/25114 +f 34958/34976/25171 34900/34918/25114 34899/34917/25113 +f 34959/34977/25172 34958/34976/25171 34899/34917/25113 +f 34959/34977/25172 34899/34917/25113 34897/34915/25111 +f 34969/34987/25182 34959/34977/25172 34897/34915/25111 +f 34969/34987/25182 34897/34915/25111 34896/34914/25110 +f 34970/34988/25183 34955/34973/25168 34959/34977/25172 +f 34970/34988/25183 34959/34977/25172 34969/34987/25182 +f 34963/34981/25176 34952/34970/25165 34955/34973/25168 +f 34963/34981/25176 34955/34973/25168 34970/34988/25183 +f 34971/34989/25184 34972/34990/25185 34973/34991/25186 +f 34971/34989/25184 34973/34991/25186 34974/34992/25187 +f 34972/34990/25185 34975/34993/25188 34976/34994/25189 +f 34972/34990/25185 34976/34994/25189 34973/34991/25186 +f 34974/34992/25187 34973/34991/25186 34977/34995/25190 +f 34974/34992/25187 34977/34995/25190 34978/34996/25191 +f 34973/34991/25186 34976/34994/25189 34979/34997/25192 +f 34973/34991/25186 34979/34997/25192 34977/34995/25190 +f 34876/34894/25090 34875/34893/25089 34971/34989/25184 +f 34876/34894/25090 34971/34989/25184 34966/34984/25179 +f 34875/34893/25089 34874/34892/25088 34972/34990/25185 +f 34875/34893/25089 34972/34990/25185 34971/34989/25184 +f 34874/34892/25088 34872/34890/25086 34975/34993/25188 +f 34874/34892/25088 34975/34993/25188 34972/34990/25185 +f 34872/34890/25086 34871/34889/25085 34980/34998/25193 +f 34872/34890/25086 34980/34998/25193 34975/34993/25188 +f 34975/34993/25188 34980/34998/25193 34981/34999/25194 +f 34975/34993/25188 34981/34999/25194 34976/34994/25189 +f 34976/34994/25189 34981/34999/25194 34982/35000/25195 +f 34976/34994/25189 34982/35000/25195 34979/34997/25192 +f 34979/34997/25192 34982/35000/25195 34919/34937/25133 +f 34979/34997/25192 34919/34937/25133 34918/34936/25132 +f 34977/34995/25190 34979/34997/25192 34918/34936/25132 +f 34977/34995/25190 34918/34936/25132 34917/34935/25131 +f 34978/34996/25191 34977/34995/25190 34917/34935/25131 +f 34978/34996/25191 34917/34935/25131 34916/34934/25130 +f 34968/34986/25181 34978/34996/25191 34916/34934/25130 +f 34968/34986/25181 34916/34934/25130 34901/34919/25115 +f 34967/34985/25180 34974/34992/25187 34978/34996/25191 +f 34967/34985/25180 34978/34996/25191 34968/34986/25181 +f 34966/34984/25179 34971/34989/25184 34974/34992/25187 +f 34966/34984/25179 34974/34992/25187 34967/34985/25180 +f 34983/35001/25196 34984/35002/25197 34985/35003/25198 +f 34983/35001/25196 34985/35003/25198 34986/35004/25199 +f 34984/35002/25197 34987/35005/25200 34988/35006/25201 +f 34984/35002/25197 34988/35006/25201 34985/35003/25198 +f 34986/35004/25199 34985/35003/25198 34989/35007/25202 +f 34986/35004/25199 34989/35007/25202 34990/35008/25203 +f 34985/35003/25198 34988/35006/25201 34991/35009/25204 +f 34985/35003/25198 34991/35009/25204 34989/35007/25202 +f 34871/34889/25085 34992/35010/25205 34983/35001/25196 +f 34871/34889/25085 34983/35001/25196 34980/34998/25193 +f 34992/35010/25205 34993/35011/25206 34984/35002/25197 +f 34992/35010/25205 34984/35002/25197 34983/35001/25196 +f 34993/35011/25206 34994/35012/25207 34987/35005/25200 +f 34993/35011/25206 34987/35005/25200 34984/35002/25197 +f 34994/35012/25207 34995/35013/25208 34996/35014/25209 +f 34994/35012/25207 34996/35014/25209 34987/35005/25200 +f 34987/35005/25200 34996/35014/25209 34997/35015/25210 +f 34987/35005/25200 34997/35015/25210 34988/35006/25201 +f 34988/35006/25201 34997/35015/25210 34998/35016/25211 +f 34988/35006/25201 34998/35016/25211 34991/35009/25204 +f 34991/35009/25204 34998/35016/25211 34936/34954/25149 +f 34991/35009/25204 34936/34954/25149 34935/34953/25148 +f 34989/35007/25202 34991/35009/25204 34935/34953/25148 +f 34989/35007/25202 34935/34953/25148 34934/34952/25147 +f 34990/35008/25203 34989/35007/25202 34934/34952/25147 +f 34990/35008/25203 34934/34952/25147 34933/34951/25146 +f 34982/35000/25195 34990/35008/25203 34933/34951/25146 +f 34982/35000/25195 34933/34951/25146 34919/34937/25133 +f 34981/34999/25194 34986/35004/25199 34990/35008/25203 +f 34981/34999/25194 34990/35008/25203 34982/35000/25195 +f 34980/34998/25193 34983/35001/25196 34986/35004/25199 +f 34980/34998/25193 34986/35004/25199 34981/34999/25194 +f 34999/35017/25212 35000/35018/25213 35001/35019/25214 +f 34999/35017/25212 35001/35019/25214 35002/35020/25215 +f 35000/35018/25213 35003/35021/25216 35004/35022/25217 +f 35000/35018/25213 35004/35022/25217 35001/35019/25214 +f 35002/35020/25215 35001/35019/25214 35005/35023/25218 +f 35002/35020/25215 35005/35023/25218 35006/35024/25219 +f 35001/35019/25214 35004/35022/25217 35007/35025/25220 +f 35001/35019/25214 35007/35025/25220 35005/35023/25218 +f 34995/35013/25208 35008/35026/25221 34999/35017/25212 +f 34995/35013/25208 34999/35017/25212 34996/35014/25209 +f 35008/35026/25221 35009/35027/25222 35000/35018/25213 +f 35008/35026/25221 35000/35018/25213 34999/35017/25212 +f 35009/35027/25222 35010/35028/25223 35003/35021/25216 +f 35009/35027/25222 35003/35021/25216 35000/35018/25213 +f 35010/35028/25223 34961/34979/25174 34963/34981/25176 +f 35010/35028/25223 34963/34981/25176 35003/35021/25216 +f 35003/35021/25216 34963/34981/25176 34970/34988/25183 +f 35003/35021/25216 34970/34988/25183 35004/35022/25217 +f 35004/35022/25217 34970/34988/25183 34969/34987/25182 +f 35004/35022/25217 34969/34987/25182 35007/35025/25220 +f 35007/35025/25220 34969/34987/25182 34896/34914/25110 +f 35007/35025/25220 34896/34914/25110 34951/34969/25164 +f 35005/35023/25218 35007/35025/25220 34951/34969/25164 +f 35005/35023/25218 34951/34969/25164 34950/34968/25163 +f 35006/35024/25219 35005/35023/25218 34950/34968/25163 +f 35006/35024/25219 34950/34968/25163 34949/34967/25162 +f 34998/35016/25211 35006/35024/25219 34949/34967/25162 +f 34998/35016/25211 34949/34967/25162 34936/34954/25149 +f 34997/35015/25210 35002/35020/25215 35006/35024/25219 +f 34997/35015/25210 35006/35024/25219 34998/35016/25211 +f 34996/35014/25209 34999/35017/25212 35002/35020/25215 +f 34996/35014/25209 35002/35020/25215 34997/35015/25210 +f 35011/35029/25224 35012/35030/25225 35013/35031/25226 +f 35011/35029/25224 35013/35031/25226 35014/35032/25227 +f 35012/35030/25225 35015/35033/25228 35016/35034/25229 +f 35012/35030/25225 35016/35034/25229 35013/35031/25226 +f 35014/35032/25227 35013/35031/25226 35017/35035/25230 +f 35014/35032/25227 35017/35035/25230 35018/35036/25231 +f 35013/35031/25226 35016/35034/25229 35019/35037/25232 +f 35013/35031/25226 35019/35037/25232 35017/35035/25230 +f 35020/35038/25233 35021/35039/25234 35011/35029/25224 +f 35020/35038/25233 35011/35029/25224 35022/35040/25235 +f 35021/35039/25234 35023/35041/25236 35012/35030/25225 +f 35021/35039/25234 35012/35030/25225 35011/35029/25224 +f 35023/35041/25236 35024/35042/25237 35015/35033/25228 +f 35023/35041/25236 35015/35033/25228 35012/35030/25225 +f 35024/35042/25237 35025/35043/25238 35026/35044/25239 +f 35024/35042/25237 35026/35044/25239 35015/35033/25228 +f 35015/35033/25228 35026/35044/25239 35027/35045/25240 +f 35015/35033/25228 35027/35045/25240 35016/35034/25229 +f 35016/35034/25229 35027/35045/25240 35028/35046/25241 +f 35016/35034/25229 35028/35046/25241 35019/35037/25232 +f 35019/35037/25232 35028/35046/25241 35029/35047/25242 +f 35019/35037/25232 35029/35047/25242 35030/35048/25243 +f 35017/35035/25230 35019/35037/25232 35030/35048/25243 +f 35017/35035/25230 35030/35048/25243 35031/35049/25244 +f 35018/35036/25231 35017/35035/25230 35031/35049/25244 +f 35018/35036/25231 35031/35049/25244 35032/35050/25245 +f 35033/35051/25246 35018/35036/25231 35032/35050/25245 +f 35033/35051/25246 35032/35050/25245 35034/35052/25247 +f 35035/35053/25248 35014/35032/25227 35018/35036/25231 +f 35035/35053/25248 35018/35036/25231 35033/35051/25246 +f 35022/35040/25235 35011/35029/25224 35014/35032/25227 +f 35022/35040/25235 35014/35032/25227 35035/35053/25248 +f 35036/35054/25249 35037/35055/25250 35038/35056/25251 +f 35036/35054/25249 35038/35056/25251 35039/35057/25252 +f 35037/35055/25250 35040/35058/25253 35041/35059/25254 +f 35037/35055/25250 35041/35059/25254 35038/35056/25251 +f 35039/35057/25252 35038/35056/25251 35042/35060/25255 +f 35039/35057/25252 35042/35060/25255 35043/35061/25256 +f 35038/35056/25251 35041/35059/25254 35044/35062/25257 +f 35038/35056/25251 35044/35062/25257 35042/35060/25255 +f 34995/35013/25208 34994/35012/25207 35036/35054/25249 +f 34995/35013/25208 35036/35054/25249 35045/35063/25258 +f 34994/35012/25207 34993/35011/25206 35037/35055/25250 +f 34994/35012/25207 35037/35055/25250 35036/35054/25249 +f 34993/35011/25206 34992/35010/25205 35040/35058/25253 +f 34993/35011/25206 35040/35058/25253 35037/35055/25250 +f 34992/35010/25205 34871/34889/25085 34873/34891/25087 +f 34992/35010/25205 34873/34891/25087 35040/35058/25253 +f 35040/35058/25253 34873/34891/25087 34886/34904/25100 +f 35040/35058/25253 34886/34904/25100 35041/35059/25254 +f 35041/35059/25254 34886/34904/25100 34884/34902/25098 +f 35041/35059/25254 34884/34902/25098 35044/35062/25257 +f 35044/35062/25257 34884/34902/25098 34885/34903/25099 +f 35044/35062/25257 34885/34903/25099 35046/35064/25259 +f 35042/35060/25255 35044/35062/25257 35046/35064/25259 +f 35042/35060/25255 35046/35064/25259 35047/35065/25260 +f 35043/35061/25256 35042/35060/25255 35047/35065/25260 +f 35043/35061/25256 35047/35065/25260 35048/35066/25261 +f 35049/35067/25262 35043/35061/25256 35048/35066/25261 +f 35049/35067/25262 35048/35066/25261 35050/35068/25263 +f 35051/35069/25264 35039/35057/25252 35043/35061/25256 +f 35051/35069/25264 35043/35061/25256 35049/35067/25262 +f 35045/35063/25258 35036/35054/25249 35039/35057/25252 +f 35045/35063/25258 35039/35057/25252 35051/35069/25264 +f 35052/35070/25265 35053/35071/25266 35054/35072/25267 +f 35052/35070/25265 35054/35072/25267 35055/35073/25268 +f 35053/35071/25266 35056/35074/25269 35057/35075/25270 +f 35053/35071/25266 35057/35075/25270 35054/35072/25267 +f 35055/35073/25268 35054/35072/25267 35058/35076/25271 +f 35055/35073/25268 35058/35076/25271 35059/35077/25272 +f 35054/35072/25267 35057/35075/25270 35060/35078/25273 +f 35054/35072/25267 35060/35078/25273 35058/35076/25271 +f 34876/34894/25090 34965/34983/25178 35052/35070/25265 +f 34876/34894/25090 35052/35070/25265 34877/34895/25091 +f 34965/34983/25178 34964/34982/25177 35053/35071/25266 +f 34965/34983/25178 35053/35071/25266 35052/35070/25265 +f 34964/34982/25177 34962/34980/25175 35056/35074/25269 +f 34964/34982/25177 35056/35074/25269 35053/35071/25266 +f 34962/34980/25175 34961/34979/25174 35061/35079/25274 +f 34962/34980/25175 35061/35079/25274 35056/35074/25269 +f 35056/35074/25269 35061/35079/25274 35062/35080/25275 +f 35056/35074/25269 35062/35080/25275 35057/35075/25270 +f 35057/35075/25270 35062/35080/25275 35063/35081/25276 +f 35057/35075/25270 35063/35081/25276 35060/35078/25273 +f 35060/35078/25273 35063/35081/25276 35064/35082/25277 +f 35060/35078/25273 35064/35082/25277 35065/35083/25278 +f 35058/35076/25271 35060/35078/25273 35065/35083/25278 +f 35058/35076/25271 35065/35083/25278 35066/35084/25279 +f 35059/35077/25272 35058/35076/25271 35066/35084/25279 +f 35059/35077/25272 35066/35084/25279 35067/35085/25280 +f 34879/34897/25093 35059/35077/25272 35067/35085/25280 +f 34879/34897/25093 35067/35085/25280 34880/34898/25094 +f 34878/34896/25092 35055/35073/25268 35059/35077/25272 +f 34878/34896/25092 35059/35077/25272 34879/34897/25093 +f 34877/34895/25091 35052/35070/25265 35055/35073/25268 +f 34877/34895/25091 35055/35073/25268 34878/34896/25092 +f 35068/35086/25281 35069/35087/25282 35070/35088/25283 +f 35068/35086/25281 35070/35088/25283 35071/35089/25284 +f 35069/35087/25282 35072/35090/25285 35073/35091/25286 +f 35069/35087/25282 35073/35091/25286 35070/35088/25283 +f 35071/35089/25284 35070/35088/25283 35074/35092/25287 +f 35071/35089/25284 35074/35092/25287 35075/35093/25288 +f 35070/35088/25283 35073/35091/25286 35076/35094/25289 +f 35070/35088/25283 35076/35094/25289 35074/35092/25287 +f 34961/34979/25174 35010/35028/25223 35068/35086/25281 +f 34961/34979/25174 35068/35086/25281 35061/35079/25274 +f 35010/35028/25223 35009/35027/25222 35069/35087/25282 +f 35010/35028/25223 35069/35087/25282 35068/35086/25281 +f 35009/35027/25222 35008/35026/25221 35072/35090/25285 +f 35009/35027/25222 35072/35090/25285 35069/35087/25282 +f 35008/35026/25221 34995/35013/25208 35045/35063/25258 +f 35008/35026/25221 35045/35063/25258 35072/35090/25285 +f 35072/35090/25285 35045/35063/25258 35051/35069/25264 +f 35072/35090/25285 35051/35069/25264 35073/35091/25286 +f 35073/35091/25286 35051/35069/25264 35049/35067/25262 +f 35073/35091/25286 35049/35067/25262 35076/35094/25289 +f 35076/35094/25289 35049/35067/25262 35050/35068/25263 +f 35076/35094/25289 35050/35068/25263 35077/35095/25290 +f 35074/35092/25287 35076/35094/25289 35077/35095/25290 +f 35074/35092/25287 35077/35095/25290 35078/35096/25291 +f 35075/35093/25288 35074/35092/25287 35078/35096/25291 +f 35075/35093/25288 35078/35096/25291 35079/35097/25292 +f 35063/35081/25276 35075/35093/25288 35079/35097/25292 +f 35063/35081/25276 35079/35097/25292 35064/35082/25277 +f 35062/35080/25275 35071/35089/25284 35075/35093/25288 +f 35062/35080/25275 35075/35093/25288 35063/35081/25276 +f 35061/35079/25274 35068/35086/25281 35071/35089/25284 +f 35061/35079/25274 35071/35089/25284 35062/35080/25275 +f 35080/35098/25293 35081/35099/25294 35082/35100/25295 +f 35080/35098/25293 35082/35100/25295 35083/35101/25296 +f 35081/35099/25294 35084/35102/25297 35085/35103/25298 +f 35081/35099/25294 35085/35103/25298 35082/35100/25295 +f 35086/35104/25296 35087/35105/25295 35088/35106/25299 +f 35086/35104/25296 35088/35106/25299 35089/35107/25300 +f 35087/35105/25295 35090/35108/25301 35091/35109/25302 +f 35087/35105/25295 35091/35109/25302 35088/35106/25299 +f 35092/35110/25303 35093/35111/25304 35094/35112/25293 +f 35092/35110/25303 35094/35112/25293 35095/35113/25305 +f 35096/35114/25304 35097/35115/25306 35081/35099/25294 +f 35096/35114/25304 35081/35099/25294 35080/35098/25293 +f 35097/35115/25306 35098/35116/25307 35084/35102/25297 +f 35097/35115/25306 35084/35102/25297 35081/35099/25294 +f 35098/35116/25307 35099/35117/25308 35100/35118/25309 +f 35098/35116/25307 35100/35118/25309 35084/35102/25297 +f 35084/35102/25297 35100/35118/25309 35101/35119/25310 +f 35084/35102/25297 35101/35119/25310 35085/35103/25298 +f 35090/35108/25301 35102/35120/25310 35103/35121/25311 +f 35090/35108/25301 35103/35121/25311 35091/35109/25302 +f 35091/35109/25302 35103/35121/25311 34880/34898/25094 +f 35091/35109/25302 34880/34898/25094 35067/35085/25280 +f 35088/35106/25299 35091/35109/25302 35067/35085/25280 +f 35088/35106/25299 35067/35085/25280 35066/35084/25279 +f 35089/35107/25300 35088/35106/25299 35066/35084/25279 +f 35089/35107/25300 35066/35084/25279 35065/35083/25278 +f 35104/35122/25312 35089/35107/25300 35065/35083/25278 +f 35104/35122/25312 35065/35083/25278 35064/35082/25277 +f 35105/35123/25313 35086/35104/25296 35089/35107/25300 +f 35105/35123/25313 35089/35107/25300 35104/35122/25312 +f 35095/35113/25305 35094/35112/25293 35106/35124/25296 +f 35095/35113/25305 35106/35124/25296 35107/35125/25313 +f 35108/35126/25314 35109/35127/25315 35110/35128/25316 +f 35108/35126/25314 35110/35128/25316 35111/35129/25317 +f 35109/35127/25315 35112/35130/25318 35113/35131/25319 +f 35109/35127/25315 35113/35131/25319 35110/35128/25316 +f 35114/35132/25320 35115/35133/25316 35116/35134/25321 +f 35114/35132/25320 35116/35134/25321 35117/35135/25322 +f 35115/35133/25316 35118/35136/25323 35119/35137/25324 +f 35115/35133/25316 35119/35137/25324 35116/35134/25321 +f 35099/35117/25308 35120/35138/25325 35121/35139/25314 +f 35099/35117/25308 35121/35139/25314 35100/35118/25309 +f 35122/35140/25326 35123/35141/25327 35109/35127/25315 +f 35122/35140/25326 35109/35127/25315 35108/35126/25314 +f 35123/35141/25327 35124/35142/25328 35112/35130/25318 +f 35123/35141/25327 35112/35130/25318 35109/35127/25315 +f 35124/35142/25328 35125/35143/25329 35126/35144/25330 +f 35124/35142/25328 35126/35144/25330 35112/35130/25318 +f 35112/35130/25318 35126/35144/25330 35127/35145/25331 +f 35112/35130/25318 35127/35145/25331 35113/35131/25319 +f 35118/35136/25323 35128/35146/25332 35129/35147/25333 +f 35118/35136/25323 35129/35147/25333 35119/35137/25324 +f 35119/35137/25324 35129/35147/25333 34885/34903/25099 +f 35119/35137/25324 34885/34903/25099 34883/34901/25097 +f 35116/35134/25321 35119/35137/25324 34883/34901/25097 +f 35116/35134/25321 34883/34901/25097 34882/34900/25096 +f 35117/35135/25322 35116/35134/25321 34882/34900/25096 +f 35117/35135/25322 34882/34900/25096 34881/34899/25095 +f 35103/35121/25311 35117/35135/25322 34881/34899/25095 +f 35103/35121/25311 34881/34899/25095 34880/34898/25094 +f 35102/35120/25310 35114/35132/25320 35117/35135/25322 +f 35102/35120/25310 35117/35135/25322 35103/35121/25311 +f 35100/35118/25309 35121/35139/25314 35130/35148/25334 +f 35100/35118/25309 35130/35148/25334 35101/35119/25310 +f 35131/35149/25335 35132/35150/25336 35133/35151/25337 +f 35131/35149/25335 35133/35151/25337 35134/35152/25338 +f 35132/35150/25336 35135/35153/25339 35136/35154/25340 +f 35132/35150/25336 35136/35154/25340 35133/35151/25337 +f 35137/35155/25341 35138/35156/25337 35139/35157/25342 +f 35137/35155/25341 35139/35157/25342 35140/35158/25343 +f 35138/35156/25337 35141/35159/25344 35142/35160/25345 +f 35138/35156/25337 35142/35160/25345 35139/35157/25342 +f 35125/35143/25329 35143/35161/25346 35144/35162/25335 +f 35125/35143/25329 35144/35162/25335 35126/35144/25330 +f 35145/35163/25346 35146/35164/25347 35132/35150/25336 +f 35145/35163/25346 35132/35150/25336 35131/35149/25335 +f 35146/35164/25347 35147/35165/25348 35135/35153/25339 +f 35146/35164/25347 35135/35153/25339 35132/35150/25336 +f 35147/35165/25348 35148/35166/25349 35149/35167/25350 +f 35147/35165/25348 35149/35167/25350 35135/35153/25339 +f 35135/35153/25339 35149/35167/25350 35150/35168/25351 +f 35135/35153/25339 35150/35168/25351 35136/35154/25340 +f 35141/35159/25344 35151/35169/25352 35152/35170/25353 +f 35141/35159/25344 35152/35170/25353 35142/35160/25345 +f 35142/35160/25345 35152/35170/25353 35050/35068/25263 +f 35142/35160/25345 35050/35068/25263 35048/35066/25261 +f 35139/35157/25342 35142/35160/25345 35048/35066/25261 +f 35139/35157/25342 35048/35066/25261 35047/35065/25260 +f 35140/35158/25343 35139/35157/25342 35047/35065/25260 +f 35140/35158/25343 35047/35065/25260 35046/35064/25259 +f 35129/35147/25333 35140/35158/25343 35046/35064/25259 +f 35129/35147/25333 35046/35064/25259 34885/34903/25099 +f 35128/35146/25332 35137/35155/25341 35140/35158/25343 +f 35128/35146/25332 35140/35158/25343 35129/35147/25333 +f 35126/35144/25330 35144/35162/25335 35153/35171/25338 +f 35126/35144/25330 35153/35171/25338 35127/35145/25331 +f 35154/35172/25354 35155/35173/25355 35156/35174/25356 +f 35154/35172/25354 35156/35174/25356 35157/35175/25357 +f 35155/35173/25355 35158/35176/25358 35159/35177/25359 +f 35155/35173/25355 35159/35177/25359 35156/35174/25356 +f 35160/35178/25360 35161/35179/25361 35162/35180/25362 +f 35160/35178/25360 35162/35180/25362 35163/35181/25363 +f 35161/35179/25361 35164/35182/25359 35165/35183/25364 +f 35161/35179/25361 35165/35183/25364 35162/35180/25362 +f 35148/35166/25349 35166/35184/25365 35167/35185/25366 +f 35148/35166/25349 35167/35185/25366 35149/35167/25350 +f 35168/35186/25365 35169/35187/25367 35155/35173/25355 +f 35168/35186/25365 35155/35173/25355 35154/35172/25354 +f 35169/35187/25367 35170/35188/25368 35158/35176/25358 +f 35169/35187/25367 35158/35176/25358 35155/35173/25355 +f 35170/35188/25368 35092/35110/25303 35095/35113/25305 +f 35170/35188/25368 35095/35113/25305 35158/35176/25358 +f 35158/35176/25358 35095/35113/25305 35107/35125/25313 +f 35158/35176/25358 35107/35125/25313 35159/35177/25359 +f 35164/35182/25359 35105/35123/25313 35104/35122/25312 +f 35164/35182/25359 35104/35122/25312 35165/35183/25364 +f 35165/35183/25364 35104/35122/25312 35064/35082/25277 +f 35165/35183/25364 35064/35082/25277 35079/35097/25292 +f 35162/35180/25362 35165/35183/25364 35079/35097/25292 +f 35162/35180/25362 35079/35097/25292 35078/35096/25291 +f 35163/35181/25363 35162/35180/25362 35078/35096/25291 +f 35163/35181/25363 35078/35096/25291 35077/35095/25290 +f 35152/35170/25353 35163/35181/25363 35077/35095/25290 +f 35152/35170/25353 35077/35095/25290 35050/35068/25263 +f 35151/35169/25352 35160/35178/25360 35163/35181/25363 +f 35151/35169/25352 35163/35181/25363 35152/35170/25353 +f 35149/35167/25350 35167/35185/25366 35171/35189/25357 +f 35149/35167/25350 35171/35189/25357 35150/35168/25351 +f 35172/35190/25369 35173/35191/25370 35174/35192/25371 +f 35172/35190/25369 35174/35192/25371 35175/35193/25372 +f 35173/35191/25370 35176/35194/25373 35177/35195/25374 +f 35173/35191/25370 35177/35195/25374 35174/35192/25371 +f 35175/35193/25372 35174/35192/25371 35178/35196/25375 +f 35175/35193/25372 35178/35196/25375 35179/35197/25376 +f 35174/35192/25371 35177/35195/25374 35180/35198/25377 +f 35174/35192/25371 35180/35198/25377 35178/35196/25375 +f 35181/35199/25242 35182/35200/25378 35172/35190/25369 +f 35181/35199/25242 35172/35190/25369 35183/35201/25379 +f 35182/35200/25378 35184/35202/25380 35173/35191/25370 +f 35182/35200/25378 35173/35191/25370 35172/35190/25369 +f 35184/35202/25380 35185/35203/25381 35176/35194/25373 +f 35184/35202/25380 35176/35194/25373 35173/35191/25370 +f 35185/35203/25381 35186/35204/25382 35187/35205/25383 +f 35185/35203/25381 35187/35205/25383 35176/35194/25373 +f 35176/35194/25373 35187/35205/25383 35188/35206/25384 +f 35176/35194/25373 35188/35206/25384 35177/35195/25374 +f 35177/35195/25374 35188/35206/25384 35189/35207/25385 +f 35177/35195/25374 35189/35207/25385 35180/35198/25377 +f 35190/35208/25386 35191/35209/25385 35192/35210/25387 +f 35190/35208/25386 35192/35210/25387 35193/35211/25388 +f 35178/35196/25375 35180/35198/25377 35194/35212/25388 +f 35178/35196/25375 35194/35212/25388 35195/35213/25389 +f 35179/35197/25376 35178/35196/25375 35195/35213/25389 +f 35179/35197/25376 35195/35213/25389 35196/35214/25390 +f 35197/35215/25391 35198/35216/25392 35199/35217/25393 +f 35197/35215/25391 35199/35217/25393 35200/35218/25394 +f 35201/35219/25395 35175/35193/25372 35179/35197/25376 +f 35201/35219/25395 35179/35197/25376 35202/35220/25396 +f 35183/35201/25379 35172/35190/25369 35175/35193/25372 +f 35183/35201/25379 35175/35193/25372 35201/35219/25395 +f 35203/35221/25397 35204/35222/25398 35205/35223/25399 +f 35203/35221/25397 35205/35223/25399 35206/35224/25400 +f 35204/35222/25398 35207/35225/25401 35208/35226/25402 +f 35204/35222/25398 35208/35226/25402 35205/35223/25399 +f 35206/35224/25400 35205/35223/25399 35209/35227/25403 +f 35206/35224/25400 35209/35227/25403 35210/35228/25404 +f 35205/35223/25399 35208/35226/25402 35211/35229/25405 +f 35205/35223/25399 35211/35229/25405 35209/35227/25403 +f 35212/35230/25406 35213/35231/25407 35203/35221/25397 +f 35212/35230/25406 35203/35221/25397 35214/35232/25408 +f 35213/35231/25407 35215/35233/25409 35204/35222/25398 +f 35213/35231/25407 35204/35222/25398 35203/35221/25397 +f 35215/35233/25409 35216/35234/25410 35207/35225/25401 +f 35215/35233/25409 35207/35225/25401 35204/35222/25398 +f 35217/35235/25410 35218/35236/25411 35219/35237/25412 +f 35217/35235/25410 35219/35237/25412 35220/35238/25413 +f 35220/35238/25413 35219/35237/25412 35221/35239/25414 +f 35220/35238/25413 35221/35239/25414 35222/35240/25402 +f 35222/35240/25402 35221/35239/25414 35223/35241/25415 +f 35222/35240/25402 35223/35241/25415 35224/35242/25416 +f 35224/35242/25416 35223/35241/25415 35225/35243/25417 +f 35224/35242/25416 35225/35243/25417 35226/35244/25418 +f 35209/35227/25403 35211/35229/25405 35227/35245/25418 +f 35209/35227/25403 35227/35245/25418 35228/35246/25419 +f 35210/35228/25404 35209/35227/25403 35228/35246/25419 +f 35210/35228/25404 35228/35246/25419 35229/35247/25420 +f 35230/35248/25421 35210/35228/25404 35229/35247/25420 +f 35230/35248/25421 35229/35247/25420 35231/35249/25422 +f 35232/35250/25423 35206/35224/25400 35210/35228/25404 +f 35232/35250/25423 35210/35228/25404 35230/35248/25421 +f 35214/35232/25408 35203/35221/25397 35206/35224/25400 +f 35214/35232/25408 35206/35224/25400 35232/35250/25423 +f 35233/35251/25424 35234/35252/25425 35235/35253/25426 +f 35233/35251/25424 35235/35253/25426 35236/35254/25427 +f 35234/35252/25425 35237/35255/25428 35238/35256/25429 +f 35234/35252/25425 35238/35256/25429 35235/35253/25426 +f 35236/35254/25427 35235/35253/25426 35239/35257/25430 +f 35236/35254/25427 35239/35257/25430 35240/35258/25431 +f 35235/35253/25426 35238/35256/25429 35241/35259/25432 +f 35235/35253/25426 35241/35259/25432 35239/35257/25430 +f 35242/35260/25238 35243/35261/25433 35233/35251/25424 +f 35242/35260/25238 35233/35251/25424 35244/35262/25434 +f 35243/35261/25433 35245/35263/25435 35234/35252/25425 +f 35243/35261/25433 35234/35252/25425 35233/35251/25424 +f 35245/35263/25435 35246/35264/25436 35237/35255/25428 +f 35245/35263/25435 35237/35255/25428 35234/35252/25425 +f 35246/35264/25436 35247/35265/25437 35248/35266/25438 +f 35246/35264/25436 35248/35266/25438 35237/35255/25428 +f 35237/35255/25428 35248/35266/25438 35249/35267/25439 +f 35237/35255/25428 35249/35267/25439 35238/35256/25429 +f 35238/35256/25429 35249/35267/25439 35250/35268/25421 +f 35238/35256/25429 35250/35268/25421 35241/35259/25432 +f 35241/35259/25432 35250/35268/25421 35186/35204/25382 +f 35241/35259/25432 35186/35204/25382 35185/35203/25381 +f 35239/35257/25430 35241/35259/25432 35185/35203/25381 +f 35239/35257/25430 35185/35203/25381 35184/35202/25380 +f 35240/35258/25431 35239/35257/25430 35184/35202/25380 +f 35240/35258/25431 35184/35202/25380 35182/35200/25378 +f 35251/35269/25440 35240/35258/25431 35182/35200/25378 +f 35251/35269/25440 35182/35200/25378 35181/35199/25242 +f 35252/35270/25441 35236/35254/25427 35240/35258/25431 +f 35252/35270/25441 35240/35258/25431 35251/35269/25440 +f 35244/35262/25434 35233/35251/25424 35236/35254/25427 +f 35244/35262/25434 35236/35254/25427 35252/35270/25441 +f 35253/35271/25442 35254/35272/25443 35255/35273/25444 +f 35253/35271/25442 35255/35273/25444 35256/35274/25445 +f 35254/35272/25443 35257/35275/25446 35258/35276/25447 +f 35254/35272/25443 35258/35276/25447 35255/35273/25444 +f 35256/35274/25445 35255/35273/25444 35259/35277/25448 +f 35256/35274/25445 35259/35277/25448 35260/35278/25449 +f 35255/35273/25444 35258/35276/25447 35261/35279/25450 +f 35255/35273/25444 35261/35279/25450 35259/35277/25448 +f 35218/35236/25411 35262/35280/25451 35253/35271/25442 +f 35218/35236/25411 35253/35271/25442 35219/35237/25412 +f 35262/35280/25451 35263/35281/25452 35254/35272/25443 +f 35262/35280/25451 35254/35272/25443 35253/35271/25442 +f 35263/35281/25452 35264/35282/25453 35257/35275/25446 +f 35263/35281/25452 35257/35275/25446 35254/35272/25443 +f 35264/35282/25453 35265/35283/25454 35266/35284/25235 +f 35264/35282/25453 35266/35284/25235 35257/35275/25446 +f 35257/35275/25446 35266/35284/25235 35267/35285/25248 +f 35257/35275/25446 35267/35285/25248 35258/35276/25447 +f 35258/35276/25447 35267/35285/25248 35268/35286/25246 +f 35258/35276/25447 35268/35286/25246 35261/35279/25450 +f 35261/35279/25450 35268/35286/25246 35269/35287/25455 +f 35261/35279/25450 35269/35287/25455 35270/35288/25456 +f 35259/35277/25448 35261/35279/25450 35270/35288/25456 +f 35259/35277/25448 35270/35288/25456 35271/35289/25457 +f 35260/35278/25449 35259/35277/25448 35271/35289/25457 +f 35260/35278/25449 35271/35289/25457 35272/35290/25458 +f 35223/35241/25415 35260/35278/25449 35272/35290/25458 +f 35223/35241/25415 35272/35290/25458 35225/35243/25417 +f 35221/35239/25414 35256/35274/25445 35260/35278/25449 +f 35221/35239/25414 35260/35278/25449 35223/35241/25415 +f 35219/35237/25412 35253/35271/25442 35256/35274/25445 +f 35219/35237/25412 35256/35274/25445 35221/35239/25414 +f 35273/35291/25459 35274/35292/25460 35275/35293/25461 +f 35273/35291/25459 35275/35293/25461 35276/35294/25462 +f 35274/35292/25460 35277/35295/25463 35278/35296/25464 +f 35274/35292/25460 35278/35296/25464 35275/35293/25461 +f 35276/35294/25462 35275/35293/25461 35279/35297/25465 +f 35276/35294/25462 35279/35297/25465 35280/35298/25466 +f 35275/35293/25461 35278/35296/25464 35281/35299/25467 +f 35275/35293/25461 35281/35299/25467 35279/35297/25465 +f 35282/35300/25468 35283/34761/24975 35273/35291/25459 +f 35282/35300/25468 35273/35291/25459 35284/35301/25469 +f 35283/34761/24975 35285/34760/24974 35274/35292/25460 +f 35283/34761/24975 35274/35292/25460 35273/35291/25459 +f 35285/34760/24974 35286/34759/24972 35277/35295/25463 +f 35285/34760/24974 35277/35295/25463 35274/35292/25460 +f 35286/34759/24972 35287/34758/25470 35288/35302/25471 +f 35286/34759/24972 35288/35302/25471 35277/35295/25463 +f 35277/35295/25463 35288/35302/25471 35289/35303/25472 +f 35277/35295/25463 35289/35303/25472 35278/35296/25464 +f 35278/35296/25464 35289/35303/25472 35290/35304/25473 +f 35278/35296/25464 35290/35304/25473 35281/35299/25467 +f 35281/35299/25467 35290/35304/25473 35291/35305/25474 +f 35281/35299/25467 35291/35305/25474 35292/35306/25475 +f 35279/35297/25465 35281/35299/25467 35292/35306/25475 +f 35279/35297/25465 35292/35306/25475 35293/35307/25476 +f 35280/35298/25466 35279/35297/25465 35293/35307/25476 +f 35280/35298/25466 35293/35307/25476 35294/35308/25477 +f 35295/35309/25478 35280/35298/25466 35294/35308/25477 +f 35295/35309/25478 35294/35308/25477 35296/35310/25479 +f 35297/35311/25480 35276/35294/25462 35280/35298/25466 +f 35297/35311/25480 35280/35298/25466 35295/35309/25478 +f 35284/35301/25469 35273/35291/25459 35276/35294/25462 +f 35284/35301/25469 35276/35294/25462 35297/35311/25480 +f 35298/35312/25481 35299/35313/25482 35300/35314/25483 +f 35298/35312/25481 35300/35314/25483 35301/35315/25484 +f 35299/35313/25482 35302/35316/25485 35303/35317/25486 +f 35299/35313/25482 35303/35317/25486 35300/35314/25483 +f 35301/35315/25484 35300/35314/25483 35304/35318/25487 +f 35301/35315/25484 35304/35318/25487 35305/35319/25488 +f 35300/35314/25483 35303/35317/25486 35306/35320/25489 +f 35300/35314/25483 35306/35320/25489 35304/35318/25487 +f 35225/35243/25417 35272/35290/25458 35298/35312/25481 +f 35225/35243/25417 35298/35312/25481 35307/35321/25490 +f 35272/35290/25458 35271/35289/25457 35299/35313/25482 +f 35272/35290/25458 35299/35313/25482 35298/35312/25481 +f 35271/35289/25457 35270/35288/25456 35302/35316/25485 +f 35271/35289/25457 35302/35316/25485 35299/35313/25482 +f 35270/35288/25456 35269/35287/25455 35308/35322/25491 +f 35270/35288/25456 35308/35322/25491 35302/35316/25485 +f 35302/35316/25485 35308/35322/25491 35309/35323/25492 +f 35302/35316/25485 35309/35323/25492 35303/35317/25486 +f 35303/35317/25486 35309/35323/25492 35310/35324/25493 +f 35303/35317/25486 35310/35324/25493 35306/35320/25489 +f 35311/35325/25489 35312/35326/25494 35313/35327/25495 +f 35311/35325/25489 35313/35327/25495 35314/35328/25496 +f 35315/35329/25487 35311/35325/25489 35314/35328/25496 +f 35315/35329/25487 35314/35328/25496 35316/35330/25497 +f 35305/35319/25488 35304/35318/25487 35317/35331/25498 +f 35305/35319/25488 35317/35331/25498 35318/35332/25499 +f 35319/35333/25500 35305/35319/25488 35318/35332/25499 +f 35319/35333/25500 35318/35332/25499 35320/35334/25501 +f 35321/35335/25502 35301/35315/25484 35305/35319/25488 +f 35321/35335/25502 35305/35319/25488 35319/35333/25500 +f 35307/35321/25490 35298/35312/25481 35301/35315/25484 +f 35307/35321/25490 35301/35315/25484 35321/35335/25502 +f 35322/35336/25503 35323/35337/25504 35324/35338/25505 +f 35322/35336/25503 35324/35338/25505 35325/35339/25506 +f 35323/35337/25504 35326/35340/25507 35327/35341/25508 +f 35323/35337/25504 35327/35341/25508 35324/35338/25505 +f 35325/35339/25506 35324/35338/25505 35328/35342/25509 +f 35325/35339/25506 35328/35342/25509 35329/35343/25510 +f 35324/35338/25505 35327/35341/25508 35330/35344/25511 +f 35324/35338/25505 35330/35344/25511 35328/35342/25509 +f 35034/35052/25247 35032/35050/25245 35322/35336/25503 +f 35034/35052/25247 35322/35336/25503 35331/35345/25491 +f 35032/35050/25245 35031/35049/25244 35323/35337/25504 +f 35032/35050/25245 35323/35337/25504 35322/35336/25503 +f 35031/35049/25244 35030/35048/25243 35326/35340/25507 +f 35031/35049/25244 35326/35340/25507 35323/35337/25504 +f 35030/35048/25243 35029/35047/25242 35332/35346/25379 +f 35030/35048/25243 35332/35346/25379 35326/35340/25507 +f 35326/35340/25507 35332/35346/25379 35333/35347/25512 +f 35326/35340/25507 35333/35347/25512 35327/35341/25508 +f 35327/35341/25508 35333/35347/25512 35334/35348/25396 +f 35327/35341/25508 35334/35348/25396 35330/35344/25511 +f 35335/35349/25513 35197/35215/25391 35200/35218/25394 +f 35335/35349/25513 35200/35218/25394 35336/35350/25514 +f 35337/35351/25515 35335/35349/25513 35336/35350/25514 +f 35337/35351/25515 35336/35350/25514 35338/35352/25516 +f 35339/35353/25510 35337/35351/25515 35338/35352/25516 +f 35339/35353/25510 35338/35352/25516 35340/35354/25517 +f 35312/35326/25494 35339/35353/25510 35340/35354/25517 +f 35312/35326/25494 35340/35354/25517 35313/35327/25495 +f 35341/35355/25492 35325/35339/25506 35329/35343/25510 +f 35341/35355/25492 35329/35343/25510 35342/35356/25518 +f 35331/35345/25491 35322/35336/25503 35325/35339/25506 +f 35331/35345/25491 35325/35339/25506 35341/35355/25492 +f 35343/35357/25519 35344/35358/25520 35345/35359/25521 +f 35343/35357/25519 35345/35359/25521 35346/35360/25522 +f 35344/35358/25520 35347/35361/25523 35348/35362/25524 +f 35344/35358/25520 35348/35362/25524 35345/35359/25521 +f 35346/35360/25522 35345/35359/25521 35349/35363/25525 +f 35346/35360/25522 35349/35363/25525 35350/35364/25526 +f 35345/35359/25521 35348/35362/25524 35351/35365/25527 +f 35345/35359/25521 35351/35365/25527 35349/35363/25525 +f 35231/35249/25422 35229/35247/25420 35343/35357/25519 +f 35231/35249/25422 35343/35357/25519 35352/35366/25528 +f 35229/35247/25420 35228/35246/25419 35344/35358/25520 +f 35229/35247/25420 35344/35358/25520 35343/35357/25519 +f 35228/35246/25419 35227/35245/25418 35347/35361/25523 +f 35228/35246/25419 35347/35361/25523 35344/35358/25520 +f 35226/35244/25418 35225/35243/25417 35307/35321/25490 +f 35226/35244/25418 35307/35321/25490 35353/35367/25523 +f 35353/35367/25523 35307/35321/25490 35321/35335/25502 +f 35353/35367/25523 35321/35335/25502 35354/35368/25524 +f 35348/35362/25524 35355/35369/25502 35356/35370/25529 +f 35348/35362/25524 35356/35370/25529 35351/35365/25527 +f 35351/35365/25527 35356/35370/25529 35357/35371/25501 +f 35351/35365/25527 35357/35371/25501 35358/35372/25530 +f 35349/35363/25525 35351/35365/25527 35358/35372/25530 +f 35349/35363/25525 35358/35372/25530 35359/35373/25531 +f 35350/35364/25526 35349/35363/25525 35359/35373/25531 +f 35350/35364/25526 35359/35373/25531 35360/35374/25532 +f 35191/35209/25385 35350/35364/25526 35360/35374/25532 +f 35191/35209/25385 35360/35374/25532 35192/35210/25387 +f 35361/35375/25384 35346/35360/25522 35350/35364/25526 +f 35361/35375/25384 35350/35364/25526 35191/35209/25385 +f 35352/35366/25528 35343/35357/25519 35346/35360/25522 +f 35352/35366/25528 35346/35360/25522 35361/35375/25384 +f 35287/34758/25470 35362/34749/24969 35371/34766/25533 +f 35283/34761/24975 35282/35300/25468 35372/34762/24976 +f 35366/34753/24969 35372/34762/24976 35373/34763/25534 +f 35367/34754/24969 35373/34763/25534 35374/34764/25535 +f 35370/34757/25536 35374/34764/25535 35375/35376/25537 +f 35370/34757/25536 35375/35376/25537 35376/35377/25538 +f 35368/34755/25536 35370/34757/25536 35376/35377/25538 +f 35368/34755/25536 35376/35377/25538 35377/35378/25539 +f 35369/34756/24969 35368/34755/25536 35377/35378/25539 +f 35369/34756/24969 35377/35378/25539 35378/35379/25540 +f 35379/35380/25541 35369/34756/24969 35378/35379/25540 +f 35379/35380/25541 35378/35379/25540 35380/35381/25542 +f 35381/34765/25543 35369/34756/24969 35379/35380/25541 +f 35371/34766/25533 35365/34752/24969 35381/34765/25543 +f 35382/35382/25544 35383/35383/25545 35384/35384/25546 +f 35382/35382/25544 35384/35384/25546 35385/35385/25547 +f 35383/35383/25545 35386/35386/25548 35387/35387/25549 +f 35383/35383/25545 35387/35387/25549 35384/35384/25546 +f 35385/35385/25547 35384/35384/25546 35388/35388/25550 +f 35385/35385/25547 35388/35388/25550 35389/35389/25551 +f 35384/35384/25546 35387/35387/25549 35390/35390/25552 +f 35384/35384/25546 35390/35390/25552 35388/35388/25550 +f 35391/35391/25553 35392/35392/25499 35382/35382/25544 +f 35391/35391/25553 35382/35382/25544 35393/35393/25554 +f 35392/35392/25499 35316/35330/25497 35383/35383/25545 +f 35392/35392/25499 35383/35383/25545 35382/35382/25544 +f 35316/35330/25497 35314/35328/25496 35386/35386/25548 +f 35316/35330/25497 35386/35386/25548 35383/35383/25545 +f 35314/35328/25496 35313/35327/25495 35394/35394/25555 +f 35314/35328/25496 35394/35394/25555 35386/35386/25548 +f 35386/35386/25548 35394/35394/25555 35395/35395/25556 +f 35386/35386/25548 35395/35395/25556 35387/35387/25549 +f 35387/35387/25549 35395/35395/25556 35396/35396/25557 +f 35387/35387/25549 35396/35396/25557 35390/35390/25552 +f 35390/35390/25552 35396/35396/25557 35397/35397/25558 +f 35390/35390/25552 35397/35397/25558 35398/35398/25559 +f 35399/35399/25560 35400/35400/25552 35401/35401/25559 +f 35399/35399/25560 35401/35401/25559 35402/35402/25561 +f 35403/35403/25562 35399/35399/25560 35402/35402/25561 +f 35403/35403/25562 35402/35402/25561 35404/35404/25563 +f 35405/35405/25564 35403/35403/25562 35404/35404/25563 +f 35405/35405/25564 35404/35404/25563 35406/35406/25565 +f 35407/35407/25566 35408/35408/25547 35409/35409/25567 +f 35407/35407/25566 35409/35409/25567 35410/35410/25568 +f 35393/35393/25554 35382/35382/25544 35385/35385/25547 +f 35393/35393/25554 35385/35385/25547 35411/35411/25566 +f 35412/35412/25569 35413/35413/25570 35414/35414/25571 +f 35412/35412/25569 35414/35414/25571 35415/35415/25572 +f 35413/35413/25570 35416/35416/25573 35417/35417/25574 +f 35413/35413/25570 35417/35417/25574 35414/35414/25571 +f 35418/35418/25572 35419/35419/25571 35420/35420/25575 +f 35418/35418/25572 35420/35420/25575 35421/35421/25576 +f 35419/35419/25571 35422/35422/25574 35423/35423/25577 +f 35419/35419/25571 35423/35423/25577 35420/35420/25575 +f 35380/35381/25542 35378/35379/25540 35412/35412/25569 +f 35380/35381/25542 35412/35412/25569 35424/35424/25578 +f 35378/35379/25540 35377/35378/25539 35413/35413/25570 +f 35378/35379/25540 35413/35413/25570 35412/35412/25569 +f 35377/35378/25539 35376/35377/25538 35416/35416/25573 +f 35377/35378/25539 35416/35416/25573 35413/35413/25570 +f 35376/35377/25538 35375/35376/25537 35425/35425/25579 +f 35376/35377/25538 35425/35425/25579 35416/35416/25573 +f 35416/35416/25573 35425/35425/25579 35426/35426/25580 +f 35416/35416/25573 35426/35426/25580 35417/35417/25574 +f 35422/35422/25574 35427/35427/25581 35428/35428/25582 +f 35422/35422/25574 35428/35428/25582 35423/35423/25577 +f 35423/35423/25577 35428/35428/25582 35429/35429/25583 +f 35423/35423/25577 35429/35429/25583 35430/35430/25584 +f 35420/35420/25575 35423/35423/25577 35430/35430/25584 +f 35420/35420/25575 35430/35430/25584 35431/35431/25585 +f 35421/35421/25576 35420/35420/25575 35431/35431/25585 +f 35421/35421/25576 35431/35431/25585 35432/35432/25586 +f 35433/35433/25587 35421/35421/25576 35432/35432/25586 +f 35433/35433/25587 35432/35432/25586 35434/35434/25588 +f 35435/35435/25589 35418/35418/25572 35421/35421/25576 +f 35435/35435/25589 35421/35421/25576 35433/35433/25587 +f 35424/35424/25578 35412/35412/25569 35415/35415/25572 +f 35424/35424/25578 35415/35415/25572 35436/35436/25590 +f 35437/35437/25591 35438/35438/25592 35439/35439/25593 +f 35437/35437/25591 35439/35439/25593 35440/35440/25594 +f 35438/35438/25592 35441/35441/25595 35442/35442/25596 +f 35438/35438/25592 35442/35442/25596 35439/35439/25593 +f 35440/35440/25594 35439/35439/25593 35443/35443/25597 +f 35440/35440/25594 35443/35443/25597 35444/35444/25598 +f 35439/35439/25593 35442/35442/25596 35445/35445/25599 +f 35439/35439/25593 35445/35445/25599 35443/35443/25597 +f 35200/35218/25394 35199/35217/25393 35437/35437/25591 +f 35200/35218/25394 35437/35437/25591 35446/35446/25600 +f 35199/35217/25393 35447/35447/25601 35438/35438/25592 +f 35199/35217/25393 35438/35438/25592 35437/35437/25591 +f 35447/35447/25601 35448/35448/25602 35441/35441/25595 +f 35447/35447/25601 35441/35441/25595 35438/35438/25592 +f 35448/35448/25602 35449/35449/25603 35450/35450/25604 +f 35448/35448/25602 35450/35450/25604 35441/35441/25595 +f 35441/35441/25595 35450/35450/25604 35451/35451/25605 +f 35441/35441/25595 35451/35451/25605 35442/35442/25596 +f 35452/35452/25606 35453/35453/25607 35454/35454/25608 +f 35452/35452/25606 35454/35454/25608 35455/35455/25599 +f 35455/35455/25599 35454/35454/25608 35456/35456/25609 +f 35455/35455/25599 35456/35456/25609 35457/35457/25610 +f 35458/35458/25597 35459/35459/25611 35460/35460/25612 +f 35458/35458/25597 35460/35460/25612 35461/35461/25613 +f 35462/35462/25614 35458/35458/25597 35461/35461/25613 +f 35462/35462/25614 35461/35461/25613 35463/35463/25615 +f 35464/35464/25616 35462/35462/25614 35463/35463/25615 +f 35464/35464/25616 35463/35463/25615 35465/35465/25617 +f 35466/35466/25618 35440/35440/25594 35444/35444/25598 +f 35466/35466/25618 35444/35444/25598 35467/35467/25616 +f 35446/35446/25600 35437/35437/25591 35440/35440/25594 +f 35446/35446/25600 35440/35440/25594 35466/35466/25618 +f 35468/35468/25619 35469/35469/25620 35470/35470/25621 +f 35468/35468/25619 35470/35470/25621 35471/35471/25622 +f 35469/35469/25620 35472/35472/25623 35473/35473/25624 +f 35469/35469/25620 35473/35473/25624 35470/35470/25621 +f 35471/35471/25622 35470/35470/25621 35474/35474/25625 +f 35471/35471/25622 35474/35474/25625 35475/35475/25626 +f 35470/35470/25621 35473/35473/25624 35476/35476/25627 +f 35470/35470/25621 35476/35476/25627 35474/35474/25625 +f 35465/35465/25617 35463/35463/25615 35468/35468/25619 +f 35465/35465/25617 35468/35468/25619 35477/35477/25628 +f 35463/35463/25615 35461/35461/25613 35469/35469/25620 +f 35463/35463/25615 35469/35469/25620 35468/35468/25619 +f 35461/35461/25613 35460/35460/25612 35472/35472/25623 +f 35461/35461/25613 35472/35472/25623 35469/35469/25620 +f 35460/35460/25612 35478/35478/25629 35479/35479/25630 +f 35460/35460/25612 35479/35479/25630 35472/35472/25623 +f 35472/35472/25623 35479/35479/25630 35480/35480/25631 +f 35472/35472/25623 35480/35480/25631 35473/35473/25624 +f 35473/35473/25624 35480/35480/25631 35481/35481/25632 +f 35473/35473/25624 35481/35481/25632 35476/35476/25627 +f 35476/35476/25627 35481/35481/25632 35482/35482/25474 +f 35476/35476/25627 35482/35482/25474 35483/35483/25633 +f 35474/35474/25625 35476/35476/25627 35483/35483/25633 +f 35474/35474/25625 35483/35483/25633 35484/35484/25634 +f 35475/35475/25626 35474/35474/25625 35484/35484/25634 +f 35475/35475/25626 35484/35484/25634 35485/35485/25635 +f 35486/35486/25636 35475/35475/25626 35485/35485/25635 +f 35486/35486/25636 35485/35485/25635 35487/35487/25588 +f 35488/35488/25637 35471/35471/25622 35475/35475/25626 +f 35488/35488/25637 35475/35475/25626 35486/35486/25636 +f 35477/35477/25628 35468/35468/25619 35471/35471/25622 +f 35477/35477/25628 35471/35471/25622 35488/35488/25637 +f 35489/35489/25638 35490/35490/25639 35491/35491/25640 +f 35489/35489/25638 35491/35491/25640 35492/35492/25641 +f 35490/35490/25639 35493/35493/25642 35494/35494/25643 +f 35490/35490/25639 35494/35494/25643 35491/35491/25640 +f 35492/35492/25641 35491/35491/25640 35495/35495/25644 +f 35492/35492/25641 35495/35495/25644 35496/35496/25645 +f 35491/35491/25640 35494/35494/25643 35497/35497/25646 +f 35491/35491/25640 35497/35497/25646 35495/35495/25644 +f 35406/35406/25565 35404/35404/25563 35489/35489/25638 +f 35406/35406/25565 35489/35489/25638 35498/35498/25647 +f 35404/35404/25563 35402/35402/25561 35490/35490/25639 +f 35404/35404/25563 35490/35490/25639 35489/35489/25638 +f 35402/35402/25561 35401/35401/25559 35493/35493/25642 +f 35402/35402/25561 35493/35493/25642 35490/35490/25639 +f 35401/35401/25559 35499/35499/25648 35500/35500/25649 +f 35401/35401/25559 35500/35500/25649 35493/35493/25642 +f 35493/35493/25642 35500/35500/25649 35501/35501/25650 +f 35493/35493/25642 35501/35501/25650 35494/35494/25643 +f 35494/35494/25643 35501/35501/25650 35502/35502/25651 +f 35494/35494/25643 35502/35502/25651 35497/35497/25646 +f 35497/35497/25646 35502/35502/25651 35503/35503/25652 +f 35497/35497/25646 35503/35503/25652 35504/35504/25653 +f 35495/35495/25644 35497/35497/25646 35504/35504/25653 +f 35495/35495/25644 35504/35504/25653 35505/35505/25654 +f 35496/35496/25645 35495/35495/25644 35505/35505/25654 +f 35496/35496/25645 35505/35505/25654 35506/35506/25655 +f 35507/35507/25656 35496/35496/25645 35506/35506/25655 +f 35507/35507/25656 35506/35506/25655 35508/35508/25657 +f 35509/35509/25658 35492/35492/25641 35496/35496/25645 +f 35509/35509/25658 35496/35496/25645 35507/35507/25656 +f 35498/35498/25647 35489/35489/25638 35492/35492/25641 +f 35498/35498/25647 35492/35492/25641 35509/35509/25658 +f 35510/35510/25659 35511/35511/25660 35512/35512/25661 +f 35510/35510/25659 35512/35512/25661 35513/35513/25662 +f 35511/35511/25660 35514/35514/25663 35515/35515/25664 +f 35511/35511/25660 35515/35515/25664 35512/35512/25661 +f 35513/35513/25662 35512/35512/25661 35516/35516/25665 +f 35513/35513/25662 35516/35516/25665 35517/35517/25666 +f 35512/35512/25661 35515/35515/25664 35518/35518/25667 +f 35512/35512/25661 35518/35518/25667 35516/35516/25665 +f 35397/35397/25558 35519/35519/25668 35520/35520/25669 +f 35397/35397/25558 35520/35520/25669 35521/35521/25670 +f 35522/35522/25668 35523/35523/25671 35511/35511/25660 +f 35522/35522/25668 35511/35511/25660 35510/35510/25659 +f 35524/35524/25672 35525/35525/25673 35526/35526/25674 +f 35524/35524/25672 35526/35526/25674 35527/35527/25675 +f 35525/35525/25673 35528/35528/25617 35529/35529/25628 +f 35525/35525/25673 35529/35529/25628 35526/35526/25674 +f 35514/35514/25663 35530/35530/25676 35531/35531/25637 +f 35514/35514/25663 35531/35531/25637 35515/35515/25664 +f 35515/35515/25664 35531/35531/25637 35532/35532/25677 +f 35515/35515/25664 35532/35532/25677 35518/35518/25667 +f 35518/35518/25667 35532/35532/25677 35434/35434/25588 +f 35518/35518/25667 35434/35434/25588 35432/35432/25586 +f 35516/35516/25665 35518/35518/25667 35432/35432/25586 +f 35516/35516/25665 35432/35432/25586 35431/35431/25585 +f 35517/35517/25666 35516/35516/25665 35431/35431/25585 +f 35517/35517/25666 35431/35431/25585 35430/35430/25584 +f 35533/35533/25651 35517/35517/25666 35430/35430/25584 +f 35533/35533/25651 35430/35430/25584 35429/35429/25583 +f 35534/35534/25650 35513/35513/25662 35517/35517/25666 +f 35534/35534/25650 35517/35517/25666 35533/35533/25651 +f 35535/35535/25649 35510/35510/25659 35513/35513/25662 +f 35535/35535/25649 35513/35513/25662 35534/35534/25650 +f 35536/35536/25678 35537/35537/25679 35538/35538/25680 +f 35536/35536/25678 35538/35538/25680 35539/35539/25681 +f 35537/35537/25679 35540/35540/25682 35541/35541/25683 +f 35537/35537/25679 35541/35541/25683 35538/35538/25680 +f 35539/35539/25681 35538/35538/25680 35542/35542/25684 +f 35539/35539/25681 35542/35542/25684 35543/35543/25685 +f 35538/35538/25680 35541/35541/25683 35544/35544/25686 +f 35538/35538/25680 35544/35544/25686 35542/35542/25684 +f 35456/35456/25609 35545/35545/25687 35536/35536/25678 +f 35456/35456/25609 35536/35536/25678 35546/35546/25630 +f 35545/35545/25687 35547/35547/25688 35537/35537/25679 +f 35545/35545/25687 35537/35537/25679 35536/35536/25678 +f 35547/35547/25688 35548/35548/25689 35540/35540/25682 +f 35547/35547/25688 35540/35540/25682 35537/35537/25679 +f 35548/35548/25689 35549/35549/25690 35550/35550/25691 +f 35548/35548/25689 35550/35550/25691 35540/35540/25682 +f 35540/35540/25682 35550/35550/25691 35551/35551/25692 +f 35540/35540/25682 35551/35551/25692 35541/35541/25683 +f 35552/35552/25683 35509/35509/25658 35507/35507/25656 +f 35552/35552/25683 35507/35507/25656 35553/35553/25686 +f 35553/35553/25686 35507/35507/25656 35508/35508/25657 +f 35553/35553/25686 35508/35508/25657 35554/35554/25693 +f 35542/35542/25684 35544/35544/25686 35555/35555/25477 +f 35542/35542/25684 35555/35555/25477 35556/35556/25694 +f 35543/35543/25685 35542/35542/25684 35556/35556/25694 +f 35543/35543/25685 35556/35556/25694 35557/35557/25475 +f 35558/35558/25695 35543/35543/25685 35557/35557/25475 +f 35558/35558/25695 35557/35557/25475 35559/35559/25474 +f 35560/35560/25631 35539/35539/25681 35543/35543/25685 +f 35560/35560/25631 35543/35543/25685 35558/35558/25695 +f 35546/35546/25630 35536/35536/25678 35539/35539/25681 +f 35546/35546/25630 35539/35539/25681 35560/35560/25631 +f 35561/35561/25696 35562/35562/25697 35563/35563/25698 +f 35561/35561/25696 35563/35563/25698 35564/35564/25699 +f 35562/35562/25697 35565/35565/25700 35566/35566/25701 +f 35562/35562/25697 35566/35566/25701 35563/35563/25698 +f 35564/35564/25699 35563/35563/25698 35567/35567/25702 +f 35564/35564/25699 35567/35567/25702 35568/35568/25703 +f 35563/35563/25698 35566/35566/25701 35569/35569/25704 +f 35563/35563/25698 35569/35569/25704 35567/35567/25702 +f 35313/35327/25495 35340/35354/25517 35561/35561/25696 +f 35313/35327/25495 35561/35561/25696 35394/35394/25555 +f 35340/35354/25517 35338/35352/25516 35562/35562/25697 +f 35340/35354/25517 35562/35562/25697 35561/35561/25696 +f 35338/35352/25516 35336/35350/25514 35565/35565/25700 +f 35338/35352/25516 35565/35565/25700 35562/35562/25697 +f 35336/35350/25514 35200/35218/25394 35446/35446/25600 +f 35336/35350/25514 35446/35446/25600 35565/35565/25700 +f 35565/35565/25700 35446/35446/25600 35466/35466/25618 +f 35565/35565/25700 35466/35466/25618 35566/35566/25701 +f 35566/35566/25701 35466/35466/25618 35467/35467/25616 +f 35566/35566/25701 35467/35467/25616 35569/35569/25704 +f 35569/35569/25704 35467/35467/25616 35528/35528/25617 +f 35569/35569/25704 35528/35528/25617 35525/35525/25673 +f 35567/35567/25702 35569/35569/25704 35525/35525/25673 +f 35567/35567/25702 35525/35525/25673 35524/35524/25672 +f 35568/35568/25703 35567/35567/25702 35524/35524/25672 +f 35568/35568/25703 35524/35524/25672 35519/35519/25668 +f 35396/35396/25557 35568/35568/25703 35519/35519/25668 +f 35396/35396/25557 35519/35519/25668 35397/35397/25558 +f 35395/35395/25556 35564/35564/25699 35568/35568/25703 +f 35395/35395/25556 35568/35568/25703 35396/35396/25557 +f 35394/35394/25555 35561/35561/25696 35564/35564/25699 +f 35394/35394/25555 35564/35564/25699 35395/35395/25556 +f 35570/35570/25705 35571/35571/25706 35572/35572/25707 +f 35570/35570/25705 35572/35572/25707 35573/35573/25708 +f 35571/35571/25706 35574/35574/25709 35575/35575/25710 +f 35571/35571/25706 35575/35575/25710 35572/35572/25707 +f 35573/35573/25708 35572/35572/25707 35576/35576/25711 +f 35573/35573/25708 35576/35576/25711 35577/35577/25712 +f 35572/35572/25707 35575/35575/25710 35578/35578/25713 +f 35572/35572/25707 35578/35578/25713 35576/35576/25711 +f 35192/35210/25387 35360/35374/25532 35570/35570/25705 +f 35192/35210/25387 35570/35570/25705 35579/35579/25604 +f 35360/35374/25532 35359/35373/25531 35571/35571/25706 +f 35360/35374/25532 35571/35571/25706 35570/35570/25705 +f 35359/35373/25531 35358/35372/25530 35574/35574/25709 +f 35359/35373/25531 35574/35574/25709 35571/35571/25706 +f 35580/35580/25530 35391/35391/25553 35393/35393/25554 +f 35580/35580/25530 35393/35393/25554 35581/35581/25709 +f 35581/35581/25709 35393/35393/25554 35411/35411/25566 +f 35581/35581/25709 35411/35411/25566 35582/35582/25710 +f 35575/35575/25710 35407/35407/25566 35410/35410/25568 +f 35575/35575/25710 35410/35410/25568 35578/35578/25713 +f 35578/35578/25713 35410/35410/25568 35549/35549/25690 +f 35578/35578/25713 35549/35549/25690 35548/35548/25689 +f 35576/35576/25711 35578/35578/25713 35548/35548/25689 +f 35576/35576/25711 35548/35548/25689 35547/35547/25688 +f 35577/35577/25712 35576/35576/25711 35547/35547/25688 +f 35577/35577/25712 35547/35547/25688 35545/35545/25687 +f 35454/35454/25608 35577/35577/25712 35545/35545/25687 +f 35454/35454/25608 35545/35545/25687 35456/35456/25609 +f 35453/35453/25607 35573/35573/25708 35577/35577/25712 +f 35453/35453/25607 35577/35577/25712 35454/35454/25608 +f 35579/35579/25604 35570/35570/25705 35573/35573/25708 +f 35579/35579/25604 35573/35573/25708 35453/35453/25607 +f 35583/35583/25714 35584/35584/25715 35585/35585/25716 +f 35583/35583/25714 35585/35585/25716 35586/35586/25717 +f 35584/35584/25715 35587/35587/25718 35588/35588/25719 +f 35584/35584/25715 35588/35588/25719 35585/35585/25716 +f 35586/35586/25717 35585/35585/25716 35589/35589/25720 +f 35586/35586/25717 35589/35589/25720 35590/35590/25721 +f 35585/35585/25716 35588/35588/25719 35591/35591/25722 +f 35585/35585/25716 35591/35591/25722 35589/35589/25720 +f 35287/34758/25470 35371/34766/25533 35583/35583/25714 +f 35287/34758/25470 35583/35583/25714 35288/35302/25471 +f 35371/34766/25533 35381/34765/25543 35584/35584/25715 +f 35371/34766/25533 35584/35584/25715 35583/35583/25714 +f 35381/34765/25543 35379/35380/25541 35587/35587/25718 +f 35381/34765/25543 35587/35587/25718 35584/35584/25715 +f 35379/35380/25541 35380/35381/25542 35424/35424/25578 +f 35379/35380/25541 35424/35424/25578 35587/35587/25718 +f 35587/35587/25718 35424/35424/25578 35436/35436/25590 +f 35587/35587/25718 35436/35436/25590 35588/35588/25719 +f 35588/35588/25719 35436/35436/25590 35592/35592/25723 +f 35588/35588/25719 35592/35592/25723 35591/35591/25722 +f 35593/35593/25724 35594/35594/25725 35487/35487/25588 +f 35593/35593/25724 35487/35487/25588 35485/35485/25635 +f 35595/35595/25726 35593/35593/25724 35485/35485/25635 +f 35595/35595/25726 35485/35485/25635 35484/35484/25634 +f 35596/35596/25727 35595/35595/25726 35484/35484/25634 +f 35596/35596/25727 35484/35484/25634 35483/35483/25633 +f 35290/35304/25473 35590/35590/25721 35597/35597/25728 +f 35290/35304/25473 35597/35597/25728 35291/35305/25474 +f 35289/35303/25472 35586/35586/25717 35590/35590/25721 +f 35289/35303/25472 35590/35590/25721 35290/35304/25473 +f 35288/35302/25471 35583/35583/25714 35586/35586/25717 +f 35288/35302/25471 35586/35586/25717 35289/35303/25472 +f 35598/35598/25729 35599/35599/25730 35600/35600/25731 +f 35598/35598/25729 35600/35600/25731 35601/35601/25732 +f 35599/35599/25730 35602/35602/25733 35603/35603/25734 +f 35599/35599/25730 35603/35603/25734 35600/35600/25731 +f 35601/35601/25732 35600/35600/25731 35604/35604/25735 +f 35601/35601/25732 35604/35604/25735 35605/35605/25736 +f 35600/35600/25731 35603/35603/25734 35606/35606/25737 +f 35600/35600/25731 35606/35606/25737 35604/35604/25735 +f 35375/35376/25537 35374/34764/25535 35598/35598/25729 +f 35375/35376/25537 35598/35598/25729 35425/35425/25579 +f 35374/34764/25535 35373/34763/25534 35599/35599/25730 +f 35374/34764/25535 35599/35599/25730 35598/35598/25729 +f 35373/34763/25534 35372/34762/24976 35602/35602/25733 +f 35373/34763/25534 35602/35602/25733 35599/35599/25730 +f 35372/34762/24976 35282/35300/25468 35284/35301/25469 +f 35372/34762/24976 35284/35301/25469 35602/35602/25733 +f 35602/35602/25733 35284/35301/25469 35297/35311/25480 +f 35602/35602/25733 35297/35311/25480 35603/35603/25734 +f 35603/35603/25734 35297/35311/25480 35295/35309/25478 +f 35603/35603/25734 35295/35309/25478 35606/35606/25737 +f 35607/35607/25738 35608/35608/25739 35508/35508/25657 +f 35607/35607/25738 35508/35508/25657 35506/35506/25655 +f 35609/35609/25740 35607/35607/25738 35506/35506/25655 +f 35609/35609/25740 35506/35506/25655 35505/35505/25654 +f 35610/35610/25741 35609/35609/25740 35505/35505/25654 +f 35610/35610/25741 35505/35505/25654 35504/35504/25653 +f 35428/35428/25582 35611/35611/25742 35612/35612/25743 +f 35428/35428/25582 35612/35612/25743 35429/35429/25583 +f 35426/35426/25580 35601/35601/25732 35605/35605/25736 +f 35426/35426/25580 35605/35605/25736 35613/35613/25744 +f 35425/35425/25579 35598/35598/25729 35601/35601/25732 +f 35425/35425/25579 35601/35601/25732 35426/35426/25580 +f 35614/35614/25745 35615/35615/25746 35616/35616/25747 +f 35614/35614/25745 35616/35616/25747 35617/35617/25748 +f 35615/35615/25746 35618/35618/25749 35619/35619/25750 +f 35615/35615/25746 35619/35619/25750 35616/35616/25747 +f 35617/35617/25748 35616/35616/25747 35620/35620/25751 +f 35617/35617/25748 35620/35620/25751 35621/35621/25752 +f 35616/35616/25747 35619/35619/25750 35622/35622/25753 +f 35616/35616/25747 35622/35622/25753 35620/35620/25751 +f 35099/35117/25308 35098/35116/25307 35614/35614/25745 +f 35099/35117/25308 35614/35614/25745 35623/35623/25754 +f 35098/35116/25307 35097/35115/25306 35615/35615/25746 +f 35098/35116/25307 35615/35615/25746 35614/35614/25745 +f 35097/35115/25306 35096/35114/25304 35618/35618/25749 +f 35097/35115/25306 35618/35618/25749 35615/35615/25746 +f 35093/35111/25304 35092/35110/25303 35624/35624/25755 +f 35093/35111/25304 35624/35624/25755 35625/35625/25756 +f 35625/35625/25756 35624/35624/25755 35626/35626/25757 +f 35625/35625/25756 35626/35626/25757 35627/35627/25750 +f 35627/35627/25750 35626/35626/25757 35628/35628/25758 +f 35627/35627/25750 35628/35628/25758 35629/35629/25759 +f 35629/35629/25759 35628/35628/25758 35630/35630/25760 +f 35629/35629/25759 35630/35630/25760 35631/35631/25761 +f 35620/35620/25751 35622/35622/25753 35632/35632/25761 +f 35620/35620/25751 35632/35632/25761 35633/35633/25762 +f 35621/35621/25752 35620/35620/25751 35633/35633/25762 +f 35621/35621/25752 35633/35633/25762 35634/35634/25763 +f 35635/35635/25764 35621/35621/25752 35634/35634/25763 +f 35635/35635/25764 35634/35634/25763 35636/35636/25765 +f 35637/35637/25766 35617/35617/25748 35621/35621/25752 +f 35637/35637/25766 35621/35621/25752 35635/35635/25764 +f 35623/35623/25754 35614/35614/25745 35617/35617/25748 +f 35623/35623/25754 35617/35617/25748 35637/35637/25766 +f 35638/35638/25767 35639/35639/25768 35640/35640/25769 +f 35638/35638/25767 35640/35640/25769 35641/35641/25770 +f 35639/35639/25768 35642/35642/25771 35643/35643/25772 +f 35639/35639/25768 35643/35643/25772 35640/35640/25769 +f 35641/35641/25770 35640/35640/25769 35644/35644/25773 +f 35641/35641/25770 35644/35644/25773 35645/35645/25774 +f 35640/35640/25769 35643/35643/25772 35646/35646/25775 +f 35640/35640/25769 35646/35646/25775 35644/35644/25773 +f 35148/35166/25349 35147/35165/25348 35638/35638/25767 +f 35148/35166/25349 35638/35638/25767 35647/35647/25776 +f 35147/35165/25348 35146/35164/25347 35639/35639/25768 +f 35147/35165/25348 35639/35639/25768 35638/35638/25767 +f 35146/35164/25347 35145/35163/25346 35642/35642/25771 +f 35146/35164/25347 35642/35642/25771 35639/35639/25768 +f 35143/35161/25346 35125/35143/25329 35648/35648/25777 +f 35143/35161/25346 35648/35648/25777 35649/35649/25771 +f 35649/35649/25771 35648/35648/25777 35650/35650/25778 +f 35649/35649/25771 35650/35650/25778 35651/35651/25779 +f 35651/35651/25779 35650/35650/25778 35652/35652/25780 +f 35651/35651/25779 35652/35652/25780 35653/35653/25775 +f 35653/35653/25775 35652/35652/25780 35654/35654/25781 +f 35653/35653/25775 35654/35654/25781 35655/35655/25782 +f 35644/35644/25773 35646/35646/25775 35656/35656/25782 +f 35644/35644/25773 35656/35656/25782 35657/35657/25783 +f 35645/35645/25774 35644/35644/25773 35657/35657/25783 +f 35645/35645/25774 35657/35657/25783 35658/35658/25784 +f 35659/35659/25785 35645/35645/25774 35658/35658/25784 +f 35659/35659/25785 35658/35658/25784 35660/35660/25786 +f 35661/35661/25787 35641/35641/25770 35645/35645/25774 +f 35661/35661/25787 35645/35645/25774 35659/35659/25785 +f 35647/35647/25776 35638/35638/25767 35641/35641/25770 +f 35647/35647/25776 35641/35641/25770 35661/35661/25787 +f 35662/35662/25788 35663/35663/25789 35664/35664/25790 +f 35662/35662/25788 35664/35664/25790 35665/35665/25791 +f 35663/35663/25789 35666/35666/25792 35667/35667/25793 +f 35663/35663/25789 35667/35667/25793 35664/35664/25790 +f 35665/35665/25791 35664/35664/25790 35668/35668/25794 +f 35665/35665/25791 35668/35668/25794 35669/35669/25795 +f 35664/35664/25790 35667/35667/25793 35670/35670/25796 +f 35664/35664/25790 35670/35670/25796 35668/35668/25794 +f 35125/35143/25329 35124/35142/25328 35662/35662/25788 +f 35125/35143/25329 35662/35662/25788 35648/35648/25777 +f 35124/35142/25328 35123/35141/25327 35663/35663/25789 +f 35124/35142/25328 35663/35663/25789 35662/35662/25788 +f 35123/35141/25327 35122/35140/25326 35666/35666/25792 +f 35123/35141/25327 35666/35666/25792 35663/35663/25789 +f 35120/35138/25325 35099/35117/25308 35623/35623/25754 +f 35120/35138/25325 35623/35623/25754 35671/35671/25797 +f 35671/35671/25797 35623/35623/25754 35637/35637/25766 +f 35671/35671/25797 35637/35637/25766 35672/35672/25793 +f 35672/35672/25793 35637/35637/25766 35635/35635/25764 +f 35672/35672/25793 35635/35635/25764 35673/35673/25796 +f 35673/35673/25796 35635/35635/25764 35636/35636/25765 +f 35673/35673/25796 35636/35636/25765 35674/35674/25798 +f 35668/35668/25794 35670/35670/25796 35675/35675/25799 +f 35668/35668/25794 35675/35675/25799 35676/35676/25800 +f 35669/35669/25795 35668/35668/25794 35676/35676/25800 +f 35669/35669/25795 35676/35676/25800 35677/35677/25801 +f 35652/35652/25780 35669/35669/25795 35677/35677/25801 +f 35652/35652/25780 35677/35677/25801 35654/35654/25781 +f 35650/35650/25778 35665/35665/25791 35669/35669/25795 +f 35650/35650/25778 35669/35669/25795 35652/35652/25780 +f 35648/35648/25777 35662/35662/25788 35665/35665/25791 +f 35648/35648/25777 35665/35665/25791 35650/35650/25778 +f 35678/35678/25802 35679/35679/25803 35680/35680/25804 +f 35678/35678/25802 35680/35680/25804 35681/35681/25805 +f 35679/35679/25803 35682/35682/25806 35683/35683/25807 +f 35679/35679/25803 35683/35683/25807 35680/35680/25804 +f 35681/35681/25805 35680/35680/25804 35684/35684/25808 +f 35681/35681/25805 35684/35684/25808 35685/35685/25809 +f 35680/35680/25804 35683/35683/25807 35686/35686/25810 +f 35680/35680/25804 35686/35686/25810 35684/35684/25808 +f 35092/35110/25303 35170/35188/25368 35678/35678/25802 +f 35092/35110/25303 35678/35678/25802 35624/35624/25755 +f 35170/35188/25368 35169/35187/25367 35679/35679/25803 +f 35170/35188/25368 35679/35679/25803 35678/35678/25802 +f 35169/35187/25367 35168/35186/25365 35682/35682/25806 +f 35169/35187/25367 35682/35682/25806 35679/35679/25803 +f 35166/35184/25365 35148/35166/25349 35647/35647/25776 +f 35166/35184/25365 35647/35647/25776 35687/35687/25806 +f 35687/35687/25806 35647/35647/25776 35661/35661/25787 +f 35687/35687/25806 35661/35661/25787 35688/35688/25807 +f 35688/35688/25807 35661/35661/25787 35659/35659/25785 +f 35688/35688/25807 35659/35659/25785 35689/35689/25810 +f 35689/35689/25810 35659/35659/25785 35660/35660/25786 +f 35689/35689/25810 35660/35660/25786 35690/35690/25811 +f 35684/35684/25808 35686/35686/25810 35691/35691/25812 +f 35684/35684/25808 35691/35691/25812 35692/35692/25813 +f 35685/35685/25809 35684/35684/25808 35692/35692/25813 +f 35685/35685/25809 35692/35692/25813 35693/35693/25814 +f 35628/35628/25758 35685/35685/25809 35693/35693/25814 +f 35628/35628/25758 35693/35693/25814 35630/35630/25760 +f 35626/35626/25757 35681/35681/25805 35685/35685/25809 +f 35626/35626/25757 35685/35685/25809 35628/35628/25758 +f 35624/35624/25755 35678/35678/25802 35681/35681/25805 +f 35624/35624/25755 35681/35681/25805 35626/35626/25757 +f 35694/35694/25815 35695/35695/25816 35696/35696/25817 +f 35694/35694/25815 35696/35696/25817 35697/35697/25818 +f 35695/35695/25816 35698/35698/25819 35699/35699/25820 +f 35695/35695/25816 35699/35699/25820 35696/35696/25817 +f 35697/35697/25818 35696/35696/25817 35700/35700/25821 +f 35697/35697/25818 35700/35700/25821 35701/35701/25822 +f 35696/35696/25817 35699/35699/25820 35702/35702/25823 +f 35696/35696/25817 35702/35702/25823 35700/35700/25821 +f 35636/35636/25765 35634/35634/25763 35694/35694/25815 +f 35636/35636/25765 35694/35694/25815 35703/35703/25824 +f 35634/35634/25763 35633/35633/25762 35695/35695/25816 +f 35634/35634/25763 35695/35695/25816 35694/35694/25815 +f 35633/35633/25762 35632/35632/25761 35698/35698/25819 +f 35633/35633/25762 35698/35698/25819 35695/35695/25816 +f 35631/35631/25761 35630/35630/25760 35704/35704/25825 +f 35631/35631/25761 35704/35704/25825 35705/35705/25819 +f 35705/35705/25819 35704/35704/25825 35706/35706/25826 +f 35705/35705/25819 35706/35706/25826 35707/35707/25827 +f 35707/35707/25827 35706/35706/25826 35708/35708/25828 +f 35707/35707/25827 35708/35708/25828 35709/35709/25823 +f 35710/35710/25823 35711/35711/25829 35265/35283/25454 +f 35710/35710/25823 35265/35283/25454 35264/35282/25453 +f 35712/35712/25821 35710/35710/25823 35264/35282/25453 +f 35712/35712/25821 35264/35282/25453 35263/35281/25452 +f 35713/35713/25830 35712/35712/25821 35263/35281/25452 +f 35713/35713/25830 35263/35281/25452 35262/35280/25451 +f 35714/35714/25831 35713/35713/25830 35262/35280/25451 +f 35714/35714/25831 35262/35280/25451 35218/35236/25411 +f 35715/35715/25832 35697/35697/25818 35701/35701/25822 +f 35715/35715/25832 35701/35701/25822 35716/35716/25831 +f 35703/35703/25824 35694/35694/25815 35697/35697/25818 +f 35703/35703/25824 35697/35697/25818 35715/35715/25832 +f 35717/35717/25833 35718/35718/25834 35719/35719/25835 +f 35717/35717/25833 35719/35719/25835 35720/35720/25836 +f 35718/35718/25834 35721/35721/25837 35722/35722/25838 +f 35718/35718/25834 35722/35722/25838 35719/35719/25835 +f 35720/35720/25836 35719/35719/25835 35723/35723/25839 +f 35720/35720/25836 35723/35723/25839 35724/35724/25840 +f 35719/35719/25835 35722/35722/25838 35725/35725/25841 +f 35719/35719/25835 35725/35725/25841 35723/35723/25839 +f 35660/35660/25786 35658/35658/25784 35717/35717/25833 +f 35660/35660/25786 35717/35717/25833 35726/35726/25842 +f 35658/35658/25784 35657/35657/25783 35718/35718/25834 +f 35658/35658/25784 35718/35718/25834 35717/35717/25833 +f 35657/35657/25783 35656/35656/25782 35721/35721/25837 +f 35657/35657/25783 35721/35721/25837 35718/35718/25834 +f 35655/35655/25782 35654/35654/25781 35727/35727/25843 +f 35655/35655/25782 35727/35727/25843 35728/35728/25844 +f 35728/35728/25844 35727/35727/25843 35729/35729/25845 +f 35728/35728/25844 35729/35729/25845 35730/35730/25846 +f 35730/35730/25846 35729/35729/25845 35731/35731/25847 +f 35730/35730/25846 35731/35731/25847 35732/35732/25848 +f 35732/35732/25848 35731/35731/25847 35212/35230/25406 +f 35732/35732/25848 35212/35230/25406 35733/35733/25849 +f 35734/35734/25839 35735/35735/25850 35246/35264/25436 +f 35734/35734/25839 35246/35264/25436 35245/35263/25435 +f 35736/35736/25851 35734/35734/25839 35245/35263/25435 +f 35736/35736/25851 35245/35263/25435 35243/35261/25433 +f 35737/35737/25852 35736/35736/25851 35243/35261/25433 +f 35737/35737/25852 35243/35261/25433 35242/35260/25238 +f 35738/35738/25853 35720/35720/25836 35724/35724/25840 +f 35738/35738/25853 35724/35724/25840 35739/35739/25852 +f 35726/35726/25842 35717/35717/25833 35720/35720/25836 +f 35726/35726/25842 35720/35720/25836 35738/35738/25853 +f 35740/35740/25854 35741/35741/25855 35742/35742/25856 +f 35740/35740/25854 35742/35742/25856 35743/35743/25857 +f 35741/35741/25855 35744/35744/25858 35745/35745/25859 +f 35741/35741/25855 35745/35745/25859 35742/35742/25856 +f 35743/35743/25857 35742/35742/25856 35746/35746/25860 +f 35743/35743/25857 35746/35746/25860 35747/35747/25861 +f 35742/35742/25856 35745/35745/25859 35748/35748/25862 +f 35742/35742/25856 35748/35748/25862 35746/35746/25860 +f 35654/35654/25781 35677/35677/25801 35740/35740/25854 +f 35654/35654/25781 35740/35740/25854 35727/35727/25843 +f 35677/35677/25801 35676/35676/25800 35741/35741/25855 +f 35677/35677/25801 35741/35741/25855 35740/35740/25854 +f 35676/35676/25800 35675/35675/25799 35744/35744/25858 +f 35676/35676/25800 35744/35744/25858 35741/35741/25855 +f 35674/35674/25798 35636/35636/25765 35703/35703/25824 +f 35674/35674/25798 35703/35703/25824 35749/35749/25858 +f 35749/35749/25858 35703/35703/25824 35715/35715/25832 +f 35749/35749/25858 35715/35715/25832 35750/35750/25859 +f 35750/35750/25859 35715/35715/25832 35716/35716/25831 +f 35750/35750/25859 35716/35716/25831 35751/35751/25862 +f 35752/35752/25862 35714/35714/25831 35218/35236/25411 +f 35752/35752/25862 35218/35236/25411 35217/35235/25410 +f 35746/35746/25860 35748/35748/25862 35216/35234/25410 +f 35746/35746/25860 35216/35234/25410 35215/35233/25409 +f 35747/35747/25861 35746/35746/25860 35215/35233/25409 +f 35747/35747/25861 35215/35233/25409 35213/35231/25407 +f 35731/35731/25847 35747/35747/25861 35213/35231/25407 +f 35731/35731/25847 35213/35231/25407 35212/35230/25406 +f 35729/35729/25845 35743/35743/25857 35747/35747/25861 +f 35729/35729/25845 35747/35747/25861 35731/35731/25847 +f 35727/35727/25843 35740/35740/25854 35743/35743/25857 +f 35727/35727/25843 35743/35743/25857 35729/35729/25845 +f 35753/35753/25863 35754/35754/25864 35755/35755/25865 +f 35753/35753/25863 35755/35755/25865 35756/35756/25866 +f 35754/35754/25864 35757/35757/25867 35758/35758/25868 +f 35754/35754/25864 35758/35758/25868 35755/35755/25865 +f 35756/35756/25866 35755/35755/25865 35759/35759/25869 +f 35756/35756/25866 35759/35759/25869 35760/35760/25870 +f 35755/35755/25865 35758/35758/25868 35761/35761/25871 +f 35755/35755/25865 35761/35761/25871 35759/35759/25869 +f 35630/35630/25760 35693/35693/25814 35753/35753/25863 +f 35630/35630/25760 35753/35753/25863 35704/35704/25825 +f 35693/35693/25814 35692/35692/25813 35754/35754/25864 +f 35693/35693/25814 35754/35754/25864 35753/35753/25863 +f 35692/35692/25813 35691/35691/25812 35757/35757/25867 +f 35692/35692/25813 35757/35757/25867 35754/35754/25864 +f 35690/35690/25811 35660/35660/25786 35726/35726/25842 +f 35690/35690/25811 35726/35726/25842 35762/35762/25872 +f 35762/35762/25872 35726/35726/25842 35738/35738/25853 +f 35762/35762/25872 35738/35738/25853 35763/35763/25873 +f 35763/35763/25873 35738/35738/25853 35739/35739/25852 +f 35763/35763/25873 35739/35739/25852 35764/35764/25871 +f 35764/35764/25871 35739/35739/25852 35765/35765/25874 +f 35764/35764/25871 35765/35765/25874 35766/35766/25237 +f 35759/35759/25869 35761/35761/25871 35024/35042/25237 +f 35759/35759/25869 35024/35042/25237 35023/35041/25236 +f 35760/35760/25870 35759/35759/25869 35023/35041/25236 +f 35760/35760/25870 35023/35041/25236 35021/35039/25234 +f 35708/35708/25828 35760/35760/25870 35021/35039/25234 +f 35708/35708/25828 35021/35039/25234 35020/35038/25233 +f 35706/35706/25826 35756/35756/25866 35760/35760/25870 +f 35706/35706/25826 35760/35760/25870 35708/35708/25828 +f 35704/35704/25825 35753/35753/25863 35756/35756/25866 +f 35704/35704/25825 35756/35756/25866 35706/35706/25826 +o Cylinder.055__0 +v -0.319404 0.317672 -0.112781 +v -0.319368 0.317734 -0.094217 +v -0.347124 0.304336 -0.094119 +v -0.347160 0.304273 -0.112683 +v -0.347160 0.304273 -0.112683 +v -0.347124 0.304336 -0.094119 +v -0.376225 0.314488 -0.094098 +v -0.376261 0.314426 -0.112662 +v -0.376261 0.314426 -0.112662 +v -0.376225 0.314488 -0.094098 +v -0.389624 0.342244 -0.094165 +v -0.389659 0.342182 -0.112730 +v -0.389659 0.342182 -0.112730 +v -0.389624 0.342244 -0.094165 +v -0.379472 0.371344 -0.094282 +v -0.379507 0.371282 -0.112846 +v -0.379507 0.371282 -0.112846 +v -0.379472 0.371344 -0.094282 +v -0.351715 0.384743 -0.094380 +v -0.351751 0.384681 -0.112944 +v -0.351751 0.384681 -0.112944 +v -0.351715 0.384743 -0.094380 +v -0.322614 0.374591 -0.094401 +v -0.322650 0.374529 -0.112965 +v -0.322650 0.374529 -0.112965 +v -0.322614 0.374591 -0.094401 +v -0.309216 0.346835 -0.094334 +v -0.309252 0.346772 -0.112898 +v -0.309252 0.346772 -0.112898 +v -0.309216 0.346835 -0.094334 +v -0.319368 0.317734 -0.094217 +v -0.319404 0.317672 -0.112781 +v -0.347124 0.304336 -0.094119 +v -0.319368 0.317734 -0.094217 +v -0.309216 0.346835 -0.094334 +v -0.322614 0.374591 -0.094401 +v -0.351715 0.384743 -0.094380 +v -0.379472 0.371344 -0.094282 +v -0.389624 0.342244 -0.094165 +v -0.376225 0.314488 -0.094098 +v -0.319404 0.317672 -0.112781 +v -0.347160 0.304273 -0.112683 +v -0.376261 0.314426 -0.112662 +v -0.389659 0.342182 -0.112730 +v -0.379507 0.371282 -0.112846 +v -0.351751 0.384681 -0.112944 +v -0.322650 0.374529 -0.112965 +v -0.309252 0.346772 -0.112898 +vt 0.950294 0.931740 +vt 0.951667 0.931740 +vt 0.951667 0.929461 +vt 0.950294 0.929461 +vt 0.950294 0.929461 +vt 0.951667 0.929461 +vt 0.951667 0.927850 +vt 0.950294 0.927850 +vt 0.215379 0.048592 +vt 0.214006 0.048592 +vt 0.214006 0.050204 +vt 0.215379 0.050204 +vt 0.215379 0.050204 +vt 0.214006 0.050204 +vt 0.214006 0.052483 +vt 0.215379 0.052483 +vt 0.215379 0.052483 +vt 0.214006 0.052483 +vt 0.214006 0.054095 +vt 0.215379 0.054095 +vt 0.140843 0.064073 +vt 0.142216 0.064073 +vt 0.142216 0.062461 +vt 0.140843 0.062461 +vt 0.140843 0.062461 +vt 0.142216 0.062461 +vt 0.142216 0.060182 +vt 0.140843 0.060182 +vt 0.140843 0.060182 +vt 0.142216 0.060182 +vt 0.142216 0.058571 +vt 0.140843 0.058571 +vt 0.579279 0.772967 +vt 0.583171 0.774579 +vt 0.581559 0.772967 +vt 0.577667 0.774579 +vt 0.583171 0.776858 +vt 0.577667 0.776858 +vt 0.581559 0.778469 +vt 0.579279 0.778469 +vt 0.725691 0.558987 +vt 0.727303 0.562877 +vt 0.727303 0.560598 +vt 0.723412 0.558987 +vt 0.725691 0.564489 +vt 0.723412 0.564489 +vt 0.721800 0.560598 +vt 0.721800 0.562877 +vn 0.4347 -0.9006 0.0022 +vn -0.3294 -0.9442 0.0038 +vn -0.9006 -0.4347 0.0032 +vn -0.9442 0.3294 0.0007 +vn -0.4347 0.9006 -0.0022 +vn 0.3294 0.9442 -0.0038 +vn 0.9006 0.4347 -0.0032 +vn 0.9442 -0.3294 -0.0007 +vn 0.0019 0.0034 1.0000 +vn 0.0019 0.0033 1.0000 +vn -0.0019 -0.0034 -1.0000 +vn -0.0019 -0.0033 -1.0000 +usemtl Scene_-_Root +s off +f 35767/35767/25875 35768/35768/25875 35769/35769/25875 +f 35767/35767/25875 35769/35769/25875 35770/35770/25875 +f 35771/35771/25876 35772/35772/25876 35773/35773/25876 +f 35771/35771/25876 35773/35773/25876 35774/35774/25876 +f 35775/35775/25877 35776/35776/25877 35777/35777/25877 +f 35775/35775/25877 35777/35777/25877 35778/35778/25877 +f 35779/35779/25878 35780/35780/25878 35781/35781/25878 +f 35779/35779/25878 35781/35781/25878 35782/35782/25878 +f 35783/35783/25879 35784/35784/25879 35785/35785/25879 +f 35783/35783/25879 35785/35785/25879 35786/35786/25879 +f 35787/35787/25880 35788/35788/25880 35789/35789/25880 +f 35787/35787/25880 35789/35789/25880 35790/35790/25880 +f 35791/35791/25881 35792/35792/25881 35793/35793/25881 +f 35791/35791/25881 35793/35793/25881 35794/35794/25881 +f 35795/35795/25882 35796/35796/25882 35797/35797/25882 +f 35795/35795/25882 35797/35797/25882 35798/35798/25882 +f 35803/35799/25883 35801/35800/25883 35802/35801/25883 +f 35801/35800/25884 35803/35799/25884 35804/35802/25884 +f 35801/35800/25884 35804/35802/25884 35800/35803/25884 +f 35800/35803/25884 35804/35802/25884 35805/35804/25884 +f 35800/35803/25883 35805/35804/25883 35799/35805/25883 +f 35799/35805/25884 35805/35804/25884 35806/35806/25884 +f 35814/35807/25885 35812/35808/25885 35813/35809/25885 +f 35812/35808/25886 35814/35807/25886 35807/35810/25886 +f 35812/35808/25886 35807/35810/25886 35811/35811/25886 +f 35811/35811/25886 35807/35810/25886 35810/35812/25886 +f 35810/35812/25885 35807/35810/25885 35808/35813/25885 +f 35810/35812/25886 35808/35813/25886 35809/35814/25886 +o Cylinder.056__0 +v -0.142067 0.086482 -0.131949 +v -0.142149 0.085349 -0.113420 +v -0.160361 0.060535 -0.115018 +v -0.160279 0.061668 -0.133547 +v -0.160279 0.061668 -0.133547 +v -0.160361 0.060535 -0.115018 +v -0.190820 0.055847 -0.115439 +v -0.190738 0.056980 -0.133969 +v -0.190738 0.056980 -0.133969 +v -0.190820 0.055847 -0.115439 +v -0.215685 0.074032 -0.114438 +v -0.215603 0.075165 -0.132967 +v -0.215603 0.075165 -0.132967 +v -0.215685 0.074032 -0.114438 +v -0.220389 0.104436 -0.112600 +v -0.220307 0.105569 -0.131130 +v -0.220307 0.105569 -0.131130 +v -0.220389 0.104436 -0.112600 +v -0.202178 0.129250 -0.111002 +v -0.202096 0.130382 -0.129532 +v -0.202096 0.130382 -0.129532 +v -0.202178 0.129250 -0.111002 +v -0.171719 0.133937 -0.110581 +v -0.171637 0.135070 -0.129110 +v -0.171637 0.135070 -0.129110 +v -0.171719 0.133937 -0.110581 +v -0.146854 0.115753 -0.111582 +v -0.146772 0.116885 -0.130111 +v -0.146772 0.116885 -0.130111 +v -0.146854 0.115753 -0.111582 +v -0.142149 0.085349 -0.113420 +v -0.142067 0.086482 -0.131949 +v -0.160361 0.060535 -0.115018 +v -0.142149 0.085349 -0.113420 +v -0.146854 0.115753 -0.111582 +v -0.171719 0.133937 -0.110581 +v -0.202178 0.129250 -0.111002 +v -0.220389 0.104436 -0.112600 +v -0.215685 0.074032 -0.114438 +v -0.190820 0.055847 -0.115439 +v -0.142067 0.086482 -0.131949 +v -0.160279 0.061668 -0.133547 +v -0.190738 0.056980 -0.133969 +v -0.215603 0.075165 -0.132967 +v -0.220307 0.105569 -0.131130 +v -0.202096 0.130382 -0.129532 +v -0.171637 0.135070 -0.129110 +v -0.146772 0.116885 -0.130111 +vt 0.948894 0.931740 +vt 0.950267 0.931740 +vt 0.950267 0.929461 +vt 0.948894 0.929461 +vt 0.948894 0.929461 +vt 0.950267 0.929461 +vt 0.950267 0.927850 +vt 0.948894 0.927850 +vt 0.072110 0.046823 +vt 0.070737 0.046823 +vt 0.070737 0.048434 +vt 0.072110 0.048434 +vt 0.072110 0.048434 +vt 0.070737 0.048434 +vt 0.070737 0.050713 +vt 0.072110 0.050713 +vt 0.072110 0.050713 +vt 0.070737 0.050713 +vt 0.070737 0.052325 +vt 0.072110 0.052325 +vt 0.140843 0.069685 +vt 0.142216 0.069685 +vt 0.142216 0.068074 +vt 0.140843 0.068074 +vt 0.140843 0.068074 +vt 0.142216 0.068074 +vt 0.142216 0.065795 +vt 0.140843 0.065795 +vt 0.140843 0.065795 +vt 0.142216 0.065795 +vt 0.142216 0.064183 +vt 0.140843 0.064183 +vt 0.586028 0.772873 +vt 0.589920 0.774484 +vt 0.588308 0.772873 +vt 0.584416 0.774484 +vt 0.589920 0.776763 +vt 0.584416 0.776763 +vt 0.588308 0.778375 +vt 0.586028 0.778375 +vt 0.717009 0.602401 +vt 0.718621 0.606291 +vt 0.718621 0.604012 +vt 0.714729 0.602401 +vt 0.717009 0.607903 +vt 0.714729 0.607903 +vt 0.713117 0.604012 +vt 0.713117 0.606291 +vn 0.8067 -0.5900 -0.0325 +vn 0.1526 -0.9865 -0.0596 +vn -0.5909 -0.8051 -0.0518 +vn -0.9883 -0.1521 -0.0137 +vn -0.8067 0.5900 0.0325 +vn -0.1526 0.9865 0.0596 +vn 0.5909 0.8051 0.0518 +vn 0.9883 0.1521 0.0137 +vn -0.0044 -0.0610 0.9981 +vn 0.0044 0.0610 -0.9981 +usemtl Scene_-_Root +s off +f 35815/35815/25887 35816/35816/25887 35817/35817/25887 +f 35815/35815/25887 35817/35817/25887 35818/35818/25887 +f 35819/35819/25888 35820/35820/25888 35821/35821/25888 +f 35819/35819/25888 35821/35821/25888 35822/35822/25888 +f 35823/35823/25889 35824/35824/25889 35825/35825/25889 +f 35823/35823/25889 35825/35825/25889 35826/35826/25889 +f 35827/35827/25890 35828/35828/25890 35829/35829/25890 +f 35827/35827/25890 35829/35829/25890 35830/35830/25890 +f 35831/35831/25891 35832/35832/25891 35833/35833/25891 +f 35831/35831/25891 35833/35833/25891 35834/35834/25891 +f 35835/35835/25892 35836/35836/25892 35837/35837/25892 +f 35835/35835/25892 35837/35837/25892 35838/35838/25892 +f 35839/35839/25893 35840/35840/25893 35841/35841/25893 +f 35839/35839/25893 35841/35841/25893 35842/35842/25893 +f 35843/35843/25894 35844/35844/25894 35845/35845/25894 +f 35843/35843/25894 35845/35845/25894 35846/35846/25894 +f 35851/35847/25895 35849/35848/25895 35850/35849/25895 +f 35849/35848/25895 35851/35847/25895 35852/35850/25895 +f 35849/35848/25895 35852/35850/25895 35848/35851/25895 +f 35848/35851/25895 35852/35850/25895 35853/35852/25895 +f 35848/35851/25895 35853/35852/25895 35847/35853/25895 +f 35847/35853/25895 35853/35852/25895 35854/35854/25895 +f 35862/35855/25896 35860/35856/25896 35861/35857/25896 +f 35860/35856/25896 35862/35855/25896 35855/35858/25896 +f 35860/35856/25896 35855/35858/25896 35859/35859/25896 +f 35859/35859/25896 35855/35858/25896 35858/35860/25896 +f 35858/35860/25896 35855/35858/25896 35856/35861/25896 +f 35858/35860/25896 35856/35861/25896 35857/35862/25896 +o Cube.050__0 +v -0.595228 1.003455 -1.000390 +v -0.615746 1.087653 -1.044044 +v -0.661977 1.088349 -1.044918 +v -0.641221 1.003275 -1.000251 +v -0.652364 1.203934 -1.107113 +v -0.697510 1.203787 -1.110983 +v -0.722788 1.201897 -1.114222 +v -0.688040 1.086892 -1.047974 +v -0.667370 1.002141 -1.003321 +v -0.581957 0.816377 -1.017895 +v -0.584460 0.871354 -1.021479 +v -0.519510 0.871382 -1.022355 +v -0.517018 0.816406 -1.018788 +v -0.587431 0.918205 -1.024887 +v -0.522471 0.918231 -1.025743 +v -0.457378 0.918258 -1.026587 +v -0.454448 0.871409 -1.023221 +v -0.451986 0.816433 -1.019671 +v -0.945234 1.391153 -2.447943 +v -0.942962 1.478149 -2.375876 +v -0.920442 1.475878 -2.372510 +v -0.922777 1.389219 -2.444382 +v -0.934498 1.558720 -2.273344 +v -0.911889 1.556125 -2.270419 +v -0.889124 1.553063 -2.267096 +v -0.897816 1.473183 -2.368632 +v -0.900277 1.386874 -2.440303 +v -0.448188 0.820357 -0.970271 +v -0.450250 0.878700 -0.974322 +v -0.515281 0.878670 -0.973400 +v -0.513185 0.820327 -0.969341 +v -0.452774 0.929064 -0.978254 +v -0.517839 0.929036 -0.977344 +v -0.582805 0.929007 -0.976421 +v -0.580228 0.878641 -0.972469 +v -0.578112 0.820298 -0.968405 +v -0.653436 0.816673 -1.012753 +v -0.627881 0.816399 -1.016734 +v -0.626585 0.770216 -1.013677 +v -0.651389 0.771054 -1.009865 +v -0.580834 0.769985 -1.014811 +v -0.626585 0.770216 -1.013677 +v -0.580834 0.769985 -1.014811 +v -0.580387 0.739633 -1.009738 +v -0.625604 0.740822 -1.008797 +v -0.651389 0.771054 -1.009865 +v -0.646435 0.746664 -1.007038 +v -0.465166 1.003508 -1.002102 +v -0.456007 0.960467 -0.983234 +v -0.409788 0.960351 -0.984355 +v -0.418917 1.003366 -1.003179 +v -0.406579 0.928972 -0.979393 +v -0.380806 0.928195 -0.983264 +v -0.384008 0.959419 -0.988180 +v -0.393115 1.002253 -1.006909 +v -0.972814 1.359693 -2.408537 +v -0.975045 1.273831 -2.469714 +v -0.929028 1.274181 -2.468529 +v -0.926716 1.360122 -2.407003 +v -0.976947 1.172631 -2.520159 +v -0.930994 1.172902 -2.519368 +v -0.904958 1.174394 -2.521887 +v -0.902998 1.276051 -2.470634 +v -0.900714 1.362335 -2.408676 +v -0.630369 0.871410 -1.020333 +v -0.633323 0.918297 -1.023759 +v -0.655880 0.871930 -1.016389 +v -0.658787 0.919073 -1.019859 +v -0.530264 1.003482 -1.001253 +v -0.549272 1.085081 -1.043027 +v -0.484756 1.087698 -1.045563 +v -0.513684 1.203946 -1.108270 +v -0.569941 1.170800 -1.085941 +v -0.470108 0.988109 -1.048917 +v -0.535228 0.988086 -1.048160 +v -0.556147 1.068559 -1.090677 +v -0.491014 1.068579 -1.091303 +v -0.600179 0.988062 -1.047386 +v -0.621070 1.068539 -1.090031 +v -0.655636 1.178088 -1.153078 +v -0.590776 1.178107 -1.153511 +v -0.525661 1.178123 -1.153914 +v -0.879181 1.663291 -1.942399 +v -0.914261 1.624988 -2.120845 +v -0.924126 1.630928 -2.123359 +v -0.889146 1.669577 -1.943286 +v -0.944260 1.564076 -2.277292 +v -0.924126 1.630928 -2.123359 +v -0.944260 1.564076 -2.277292 +v -0.945491 1.570748 -2.281597 +v -0.925445 1.638327 -2.125912 +v -0.889146 1.669577 -1.943286 +v -0.890550 1.677406 -1.943895 +v -0.951157 0.912122 -2.624815 +v -0.952574 0.760517 -2.644126 +v -0.962393 0.760880 -2.650648 +v -0.960935 0.913099 -2.631360 +v -0.952272 0.607590 -2.650384 +v -0.962105 0.607415 -2.656875 +v -0.962393 0.760880 -2.650648 +v -0.962105 0.607415 -2.656875 +v -0.963505 0.607198 -2.664999 +v -0.963776 0.761332 -2.658763 +v -0.960935 0.913099 -2.631360 +v -0.962269 0.914313 -2.639389 +v -0.639858 1.297116 -1.231697 +v -0.574817 1.297134 -1.231777 +v -0.704614 1.297087 -1.231578 +v -0.767087 1.410156 -1.333346 +v -0.702410 1.410222 -1.333035 +v -0.637449 1.410267 -1.332675 +v -0.934358 -0.042009 -2.510762 +v -0.936066 -0.043488 -2.522835 +v -0.912024 -0.039987 -2.523314 +v -0.911997 -0.038652 -2.511459 +v -0.936066 -0.043488 -2.522835 +v -0.955676 -0.041417 -2.534258 +v -0.914118 -0.037633 -2.532676 +v -0.912024 -0.039987 -2.523314 +v -0.894425 -0.035178 -2.530620 +v -0.890079 -0.035892 -2.523177 +v -0.890079 -0.035892 -2.523177 +v -0.889701 -0.034458 -2.511572 +v -1.033526 1.612759 -1.949274 +v -0.980868 1.610626 -1.781495 +v -1.027043 1.610870 -1.782862 +v -1.079853 1.612972 -1.951162 +v -0.914637 1.573032 -1.618570 +v -0.960564 1.573313 -1.619401 +v -0.986603 1.576527 -1.618798 +v -1.053274 1.614177 -1.783003 +v -1.106123 1.616215 -1.952191 +v -0.775458 1.504593 -1.464512 +v -0.710518 1.504705 -1.463594 +v -0.840155 1.504452 -1.465370 +v -0.849787 1.573264 -1.617091 +v -0.784760 1.573464 -1.615546 +v -0.444561 1.068802 -1.091267 +v -0.423707 0.988287 -1.048957 +v -0.479182 1.178403 -1.153753 +v -0.452549 1.180304 -1.150893 +v -0.417943 1.070273 -1.088253 +v -0.397152 0.989419 -1.045841 +v -1.102709 1.359339 -2.413955 +v -1.099678 1.441433 -2.347305 +v -1.145726 1.441624 -2.349869 +v -1.148674 1.359528 -2.416287 +v -1.090485 1.516919 -2.253496 +v -1.136642 1.517112 -2.256108 +v -1.162643 1.519815 -2.259378 +v -1.171599 1.444020 -2.353637 +v -1.174447 1.361629 -2.420195 +v -0.944889 1.621744 -1.602903 +v -0.868474 1.549381 -1.441195 +v -0.858768 1.555102 -1.438135 +v -0.935117 1.627957 -1.600954 +v -0.792820 1.449972 -1.300605 +v -0.783137 1.455048 -1.296591 +v -0.858768 1.555102 -1.438135 +v -0.783137 1.455048 -1.296591 +v -0.781777 1.461318 -1.291616 +v -0.857422 1.562155 -1.434437 +v -0.935117 1.627957 -1.600954 +v -0.933762 1.635603 -1.598749 +v -1.011543 1.661091 -1.773103 +v -1.034066 1.657778 -1.774081 +v -0.967259 1.618566 -1.604239 +v -1.063582 1.662382 -1.950428 +v -1.086203 1.659115 -1.950974 +v -1.108624 1.655189 -1.951883 +v -1.056364 1.653793 -1.775463 +v -0.989432 1.614740 -1.605909 +v -0.609754 1.449938 -1.299866 +v -0.685523 1.549555 -1.438745 +v -0.695575 1.554884 -1.435337 +v -0.619790 1.454603 -1.295411 +v -0.761687 1.622226 -1.598538 +v -0.771741 1.628158 -1.596444 +v -0.695575 1.554884 -1.435337 +v -0.771741 1.628158 -1.596444 +v -0.773217 1.635524 -1.593566 +v -0.697041 1.561491 -1.430954 +v -0.619790 1.454603 -1.295411 +v -0.621234 1.460385 -1.289840 +v -0.915750 1.610939 -1.779378 +v -0.850518 1.611220 -1.777207 +v -0.968196 1.613114 -1.946580 +v -0.902797 1.613442 -1.943849 +v -1.037784 1.359515 -2.411246 +v -1.039875 1.273705 -2.471989 +v -1.104671 1.273583 -2.474266 +v -1.106376 1.172472 -2.523699 +v -1.041674 1.172548 -2.521927 +v -0.902797 1.613442 -1.943849 +v -0.968196 1.613114 -1.946580 +v -1.004207 1.578417 -2.111434 +v -0.938820 1.578738 -2.108291 +v -1.033526 1.612759 -1.949274 +v -1.069539 1.578078 -2.114558 +v -1.025281 1.517208 -2.250215 +v -0.960021 1.517488 -2.246924 +v -0.626251 0.878544 -0.972310 +v -0.624131 0.820237 -0.968248 +v -0.628829 0.928873 -0.976261 +v -0.654995 0.928074 -0.979417 +v -0.652399 0.878001 -0.975505 +v -0.650262 0.819939 -0.971476 +v -1.116663 -0.042009 -2.517685 +v -1.114996 -0.039696 -2.505834 +v -1.139115 -0.036291 -2.508422 +v -1.139093 -0.038652 -2.520063 +v -1.095603 -0.034561 -2.496282 +v -1.137262 -0.031277 -2.500539 +v -1.157034 -0.029404 -2.503572 +v -1.161243 -0.032282 -2.510340 +v -1.161578 -0.034458 -2.521799 +v -0.879181 1.663291 -1.942399 +v -0.827685 1.661849 -1.766814 +v -0.804765 1.658763 -1.766516 +v -0.856337 1.660225 -1.941201 +v -0.738734 1.619281 -1.599097 +v -0.715560 1.615614 -1.599758 +v -0.781593 1.654979 -1.766412 +v -0.833269 1.656518 -1.940197 +v -0.528379 1.297470 -1.231429 +v -0.591081 1.410672 -1.332068 +v -0.564736 1.413398 -1.329671 +v -0.501849 1.299796 -1.228771 +v -0.623068 0.772578 -0.965989 +v -0.577235 0.772398 -0.966151 +v -0.648400 0.773071 -0.969131 +v -0.623068 0.772578 -0.965989 +v -0.648400 0.773071 -0.969131 +v -0.643712 0.748351 -0.969719 +v -0.622620 0.742665 -0.968049 +v -0.577235 0.772398 -0.966151 +v -0.577344 0.741508 -0.968300 +v -0.725687 1.331695 -1.192346 +v -0.716040 1.339467 -1.189466 +v -0.649068 1.244049 -1.121807 +v -0.716040 1.339467 -1.189466 +v -0.649068 1.244049 -1.121807 +v -0.648667 1.253101 -1.117603 +v -0.714802 1.345775 -1.184010 +v -1.093878 -0.018235 -2.549763 +v -1.024959 -0.020835 -2.547524 +v -1.024709 -0.029963 -2.542907 +v -1.090142 -0.029669 -2.545090 +v -0.956218 -0.018235 -2.544851 +v -0.959291 -0.029668 -2.540284 +v -1.024404 -0.041554 -2.539001 +v -1.093318 -0.041417 -2.539441 +v -1.108675 0.903702 -2.575433 +v -1.107654 1.045765 -2.555005 +v -1.153482 1.045890 -2.556304 +v -1.154517 0.903770 -2.576245 +v -1.152215 1.172638 -2.525426 +v -1.177851 1.174094 -2.529400 +v -1.179136 1.046928 -2.560149 +v -1.180228 0.904346 -2.579887 +v -1.118340 0.045607 -2.563010 +v -1.121983 0.153501 -2.582515 +v -1.112083 0.152306 -2.588780 +v -1.108421 0.044391 -2.569184 +v -1.126881 0.298598 -2.608742 +v -1.117006 0.297556 -2.615142 +v -1.112083 0.152306 -2.588780 +v -1.117006 0.297556 -2.615142 +v -1.115527 0.296265 -2.623182 +v -1.110557 0.150826 -2.596783 +v -1.108421 0.044391 -2.569184 +v -1.106860 0.042884 -2.577171 +v -0.979326 0.903770 -2.574550 +v -1.044006 0.903734 -2.574990 +v -1.044745 0.758629 -2.592291 +v -0.980066 0.758647 -2.592499 +v -1.109420 0.758613 -2.592084 +v -1.108765 0.610713 -2.596948 +v -1.044098 0.610718 -2.597420 +v -0.979429 0.610724 -2.597892 +v -0.944301 -0.131524 -2.465374 +v -0.948147 -0.128894 -2.454002 +v -0.944556 -0.287798 -2.369774 +v -0.940896 -0.291781 -2.380672 +v -0.948147 -0.128894 -2.454002 +v -0.971777 -0.126951 -2.446482 +v -0.967915 -0.284854 -2.362746 +v -0.944556 -0.287798 -2.369774 +v -0.956714 -0.464849 -2.251648 +v -0.933700 -0.468981 -2.258161 +v -0.933700 -0.468981 -2.258161 +v -0.930326 -0.474571 -2.268361 +v -0.963052 -0.010661 -2.493578 +v -1.027588 -0.010661 -2.495892 +v -1.027252 -0.022053 -2.493746 +v -0.962245 -0.022035 -2.491596 +v -1.092101 -0.010661 -2.498209 +v -1.092216 -0.022035 -2.496380 +v -1.095603 -0.034561 -2.496282 +v -1.026906 -0.033931 -2.491173 +v -0.957916 -0.034561 -2.491092 +v -0.804121 1.611881 -1.775507 +v -0.738430 1.574050 -1.614223 +v -0.856358 1.614132 -1.941855 +v -0.830379 1.617632 -1.940662 +v -0.778159 1.615416 -1.773906 +v -0.712434 1.577432 -1.612418 +v -0.546978 1.331639 -1.192911 +v -0.522253 1.328929 -1.195226 +v -0.586838 1.447585 -1.301970 +v -0.473310 1.203857 -1.112940 +v -0.448724 1.201989 -1.116591 +v -0.499196 1.326405 -1.198309 +v -0.563982 1.444574 -1.304350 +v -0.844833 -0.835618 -1.906735 +v -0.847157 -0.823494 -1.897923 +v -0.841475 -0.834410 -1.883542 +v -0.839256 -0.845394 -1.891386 +v -0.847157 -0.823494 -1.897923 +v -0.869894 -0.814561 -1.890819 +v -0.863612 -0.826295 -1.877171 +v -0.841475 -0.834410 -1.883542 +v -0.822318 -0.886605 -1.793550 +v -0.800237 -0.894230 -1.799508 +v -0.800237 -0.894230 -1.799508 +v -0.798087 -0.904545 -1.806288 +v -1.103661 -0.131524 -2.472206 +v -1.099809 -0.134153 -2.483597 +v -1.095621 -0.295764 -2.399616 +v -1.099270 -0.291781 -2.388666 +v -1.099809 -0.134153 -2.483597 +v -1.076179 -0.136096 -2.491120 +v -1.072263 -0.298707 -2.406652 +v -1.095621 -0.295764 -2.399616 +v -1.061324 -0.484294 -2.293240 +v -1.084335 -0.480162 -2.286716 +v -1.084335 -0.480162 -2.286716 +v -1.087689 -0.474571 -2.276431 +v -1.022924 -0.136782 -2.491838 +v -1.019373 -0.299747 -2.406850 +v -0.969945 -0.136096 -2.486544 +v -0.966668 -0.298707 -2.401263 +v -0.956392 -0.484294 -2.287762 +v -1.008836 -0.485752 -2.293217 +v -1.025038 -0.126266 -2.445743 +v -1.020793 -0.283814 -2.362487 +v -1.078023 -0.126951 -2.451015 +v -1.073485 -0.284854 -2.368015 +v -1.061599 -0.464849 -2.256931 +v -1.009178 -0.463391 -2.251574 +v -0.950583 -0.906368 -1.838202 +v -0.880852 -0.923295 -1.818771 +v -0.787181 -1.059779 -1.618704 +v -0.841136 -1.056010 -1.614671 +v -0.831485 -0.906559 -1.842504 +v -0.734112 -1.056026 -1.623435 +v -0.631144 -1.197145 -1.399836 +v -0.684479 -1.200059 -1.393995 +v -0.737418 -1.197145 -1.386686 +v -1.005862 -0.836030 -1.902592 +v -1.004823 -0.848726 -1.911668 +v -0.996972 -0.856400 -1.895805 +v -0.996310 -0.845445 -1.887230 +v -0.988261 -0.861998 -1.919706 +v -0.996625 -0.864864 -1.905419 +v -0.950583 -0.906368 -1.838202 +v -0.955575 -0.913135 -1.808914 +v -0.955102 -0.904545 -1.799241 +v -0.988261 -0.861998 -1.919706 +v -0.928652 -0.866134 -1.924387 +v -0.929576 -0.878175 -1.923276 +v -0.981695 -0.876004 -1.919869 +v -0.867240 -0.861896 -1.922366 +v -0.875734 -0.876674 -1.921806 +v -0.929576 -0.878175 -1.923276 +v -0.875734 -0.876674 -1.921806 +v -0.877369 -0.892945 -1.919118 +v -0.930406 -0.894453 -1.921144 +v -0.981695 -0.876004 -1.919869 +v -0.981581 -0.891710 -1.917496 +v -0.923339 -0.811473 -1.887041 +v -0.915719 -0.823439 -1.873689 +v -0.977308 -0.814738 -1.887860 +v -0.968363 -0.826318 -1.874281 +v -0.927036 -0.886605 -1.788747 +v -0.874390 -0.883914 -1.789406 +v -0.603241 -1.177719 -1.398291 +v -0.605796 -1.166549 -1.395099 +v -0.539369 -1.233012 -1.245206 +v -0.536177 -1.244435 -1.246065 +v -0.605796 -1.166549 -1.395099 +v -0.628485 -1.158293 -1.390132 +v -0.562583 -1.224570 -1.241547 +v -0.539369 -1.233012 -1.245206 +v -0.539369 -1.233012 -1.245206 +v -0.562583 -1.224570 -1.241547 +v -0.526377 -1.233463 -1.146772 +v -0.502615 -1.241440 -1.148349 +v -0.502615 -1.241440 -1.148349 +v -0.498701 -1.252250 -1.146523 +v -0.782340 -1.018301 -1.597723 +v -0.729850 -1.021055 -1.603516 +v -0.835384 -1.021055 -1.594525 +v -0.734796 -1.158293 -1.376825 +v -0.681443 -1.155379 -1.382745 +v -0.707556 -1.028858 -1.609133 +v -0.705332 -1.039416 -1.614343 +v -0.707556 -1.028858 -1.609133 +v -0.861867 -1.049523 -1.607002 +v -0.863589 -1.039416 -1.601000 +v -0.955575 -0.913135 -1.808914 +v -0.861867 -1.049523 -1.607002 +v -0.760110 -1.188889 -1.381708 +v -0.760110 -1.188889 -1.381708 +v -0.762681 -1.177719 -1.378449 +v -0.658655 -1.252337 -1.124127 +v -0.654721 -1.263146 -1.122318 +v -0.631419 -1.242620 -1.047452 +v -0.635919 -1.233546 -1.052272 +v -0.654721 -1.263146 -1.122318 +v -0.630957 -1.271123 -1.123897 +v -0.607187 -1.249292 -1.046281 +v -0.631419 -1.242620 -1.047452 +v -0.593599 -1.221903 -0.991255 +v -0.618145 -1.216950 -0.995057 +v -0.618145 -1.216950 -0.995057 +v -0.622993 -1.210172 -1.002668 +v -0.692816 -1.255871 -1.223869 +v -0.696023 -1.244447 -1.222968 +v -0.669601 -1.264313 -1.227535 +v -0.692816 -1.255871 -1.223869 +v -0.630957 -1.271123 -1.123897 +v -0.654721 -1.263146 -1.122318 +v -0.616361 -1.267290 -1.235314 +v -0.563053 -1.264306 -1.242884 +v -0.524343 -1.271065 -1.138810 +v -0.577495 -1.273914 -1.130758 +v -0.615839 -1.221593 -1.233719 +v -0.669163 -1.224577 -1.226100 +v -0.633035 -1.233521 -1.131822 +v -0.579860 -1.230672 -1.139893 +v -0.526377 -1.233463 -1.146772 +v -0.539633 -1.223527 -0.993852 +v -0.533746 -1.201351 -0.961558 +v -0.587815 -1.200328 -0.960130 +v -0.486440 -1.221611 -1.000567 +v -0.480520 -1.199986 -0.968152 +v -0.479763 -1.157384 -0.954946 +v -0.533000 -1.158244 -0.948122 +v -0.587099 -1.157733 -0.947112 +v -0.577495 -1.273914 -1.130758 +v -0.553455 -1.251573 -1.051036 +v -0.524343 -1.271065 -1.138810 +v -0.500323 -1.249116 -1.058505 +v -0.579860 -1.230672 -1.139893 +v -0.558045 -1.215258 -1.071838 +v -0.504285 -1.217539 -1.076589 +v -0.633035 -1.233521 -1.131822 +v -0.611205 -1.217714 -1.064373 +v -0.598790 -1.198297 -1.018728 +v -0.545565 -1.196382 -1.025429 +v -0.491566 -1.198007 -1.028010 +v -0.480057 -1.224211 -1.075419 +v -0.475581 -1.233285 -1.070602 +v -0.480057 -1.224211 -1.075419 +v -0.467024 -1.202960 -1.024210 +v -0.467024 -1.202960 -1.024210 +v -0.462205 -1.209736 -1.016612 +v -0.455778 -1.152730 -0.976278 +v -0.460772 -1.150115 -0.987172 +v -0.462512 -1.069230 -0.986483 +v -0.457476 -1.070233 -0.975029 +v -0.460772 -1.150115 -0.987172 +v -0.485479 -1.148251 -0.993696 +v -0.487262 -1.068556 -0.993419 +v -0.462512 -1.069230 -0.986483 +v -0.489436 -0.981445 -0.996347 +v -0.464645 -0.981318 -0.989294 +v -0.464645 -0.981318 -0.989294 +v -0.459565 -0.981240 -0.977686 +v -0.540212 -1.183041 -1.001157 +v -0.486109 -1.184064 -1.002571 +v -0.593473 -1.184406 -0.994578 +v -0.592886 -1.148600 -0.985879 +v -0.539614 -1.147740 -0.992694 +v -0.461438 -1.187373 -0.997007 +v -0.456482 -1.191940 -0.987363 +v -0.461438 -1.187373 -0.997007 +v -0.612490 -1.197020 -0.965696 +v -0.617476 -1.192453 -0.975352 +v -0.612490 -1.197020 -0.965696 +v -0.611811 -1.155869 -0.953637 +v -0.611811 -1.155869 -0.953637 +v -0.616835 -1.153254 -0.964539 +v -0.543642 -0.981638 -0.995537 +v -0.544668 -0.927713 -0.997300 +v -0.492765 -0.927746 -0.998040 +v -0.596943 -0.981795 -0.988542 +v -0.595689 -0.928081 -0.990573 +v -0.584539 -0.907357 -0.990585 +v -0.544438 -0.903990 -0.995024 +v -0.503892 -0.907095 -0.996435 +v -0.613544 -1.071759 -0.951842 +v -0.618610 -1.070756 -0.963300 +v -0.588790 -1.072433 -0.944905 +v -0.613544 -1.071759 -0.951842 +v -0.590873 -0.981558 -0.947305 +v -0.615668 -0.981685 -0.954358 +v -0.615668 -0.981685 -0.954358 +v -0.620776 -0.981764 -0.965971 +v -0.534653 -1.072523 -0.945765 +v -0.481401 -1.072084 -0.952730 +v -0.483432 -0.981209 -0.955120 +v -0.536699 -0.981366 -0.948120 +v -0.541432 -1.068466 -0.992564 +v -0.594719 -1.068905 -0.985605 +v -0.663093 0.818301 -0.991950 +v -0.665377 0.874960 -0.995783 +v -0.664969 0.873216 -1.007559 +v -0.662598 0.817362 -1.003839 +v -0.668120 0.923568 -0.999475 +v -0.667802 0.920981 -1.011124 +v -0.658787 0.919073 -1.019859 +v -0.655880 0.871930 -1.016389 +v -0.653436 0.816673 -1.012753 +v -0.366491 0.818431 -0.996113 +v -0.368665 0.875090 -0.999894 +v -0.369108 0.876835 -0.988177 +v -0.367026 0.819371 -0.984273 +v -0.371299 0.923695 -1.003520 +v -0.371648 0.926284 -0.991941 +v -0.380806 0.928195 -0.983264 +v -0.378322 0.878123 -0.979395 +v -0.376297 0.820062 -0.975398 +v -0.383723 0.995840 -1.026508 +v -0.386305 0.992150 -1.037681 +v -0.407048 1.073828 -1.080457 +v -0.404431 1.078636 -1.069803 +v -0.397152 0.989419 -1.045841 +v -0.417943 1.070273 -1.088253 +v -0.452549 1.180304 -1.150893 +v -0.441702 1.184913 -1.143662 +v -0.439174 1.191148 -1.133816 +v -0.735848 1.191052 -1.131520 +v -0.733355 1.197284 -1.121520 +v -0.783118 1.320626 -1.203740 +v -0.785280 1.312976 -1.212657 +v -0.733355 1.197284 -1.121520 +v -0.772830 1.326291 -1.197205 +v -0.783118 1.320626 -1.203740 +v -0.837255 1.444335 -1.305113 +v -0.847144 1.437689 -1.310610 +v -0.847144 1.437689 -1.310610 +v -0.848779 1.428721 -1.318049 +v -0.680608 0.995724 -1.022786 +v -0.678045 0.999412 -1.011521 +v -0.698711 1.083337 -1.055824 +v -0.701299 1.078532 -1.066600 +v -0.678045 0.999412 -1.011521 +v -0.698711 1.083337 -1.055824 +v -0.491247 1.305449 -1.222305 +v -0.489053 1.313099 -1.213556 +v -0.501849 1.299796 -1.228771 +v -0.491247 1.305449 -1.222305 +v -0.554543 1.420021 -1.324225 +v -0.554543 1.420021 -1.324225 +v -0.552895 1.428984 -1.316944 +v -0.702543 1.596538 -1.605786 +v -0.703074 1.585559 -1.609460 +v -0.768873 1.623848 -1.771950 +v -0.768434 1.635226 -1.769745 +v -0.703074 1.585559 -1.609460 +v -0.768873 1.623848 -1.771950 +v -0.820996 1.625930 -1.940120 +v -0.820996 1.625930 -1.940120 +v -0.820405 1.637114 -1.939922 +v -0.628341 1.515775 -1.456390 +v -0.627336 1.525896 -1.450941 +v -0.638056 1.508291 -1.460568 +v -0.628341 1.515775 -1.456390 +v -0.922338 1.535455 -1.449136 +v -0.923367 1.525325 -1.454702 +v -0.912865 1.542974 -1.444946 +v -0.922338 1.535455 -1.449136 +v -0.998643 1.606570 -1.608840 +v -0.998643 1.606570 -1.608840 +v -0.999234 1.595576 -1.612575 +v -1.065584 1.645315 -1.777369 +v -1.066111 1.633915 -1.779580 +v -1.065584 1.645315 -1.777369 +v -1.118001 1.646845 -1.952357 +v -1.118001 1.646845 -1.952357 +v -1.118703 1.635629 -1.952501 +v -0.856954 1.590343 -2.107565 +v -0.856156 1.600703 -2.110562 +v -0.830379 1.617632 -1.940662 +v -0.866461 1.582650 -2.105794 +v -0.856954 1.590343 -2.107565 +v -0.866461 1.582650 -2.105794 +v -0.887779 1.520978 -2.245392 +v -0.878135 1.527831 -2.249485 +v -0.878135 1.527831 -2.249485 +v -0.877110 1.537058 -2.255645 +v -1.153215 1.609713 -2.128334 +v -1.154146 1.599307 -2.125215 +v -1.108624 1.655189 -1.951883 +v -1.143685 1.617450 -2.130198 +v -1.163484 1.552081 -2.281635 +v -1.173159 1.545185 -2.277430 +v -1.174331 1.535900 -2.271098 +v -0.895659 0.907743 -2.597636 +v -0.897387 0.905863 -2.586316 +v -0.898310 0.759109 -2.605362 +v -0.896730 0.759511 -2.616958 +v -0.897387 0.905863 -2.586316 +v -0.907475 0.904467 -2.578006 +v -0.908284 0.758810 -2.596763 +v -0.898310 0.759109 -2.605362 +v -0.907697 0.610476 -2.602511 +v -0.897781 0.609936 -2.611287 +v -0.897781 0.609936 -2.611287 +v -0.896272 0.609204 -2.623075 +v -0.889206 1.374629 -2.424000 +v -0.890735 1.367573 -2.414975 +v -0.892855 1.280491 -2.477611 +v -0.891083 1.286473 -2.487472 +v -0.890735 1.367573 -2.414975 +v -0.892855 1.280491 -2.477611 +v -0.894726 1.177947 -2.529448 +v -0.894726 1.177947 -2.529448 +v -0.892816 1.182736 -2.540000 +v -1.185255 1.373974 -2.436766 +v -1.183598 1.381090 -2.445958 +v -1.184774 1.292099 -2.508200 +v -1.186656 1.286058 -2.498195 +v -1.183598 1.381090 -2.445958 +v -1.173581 1.386365 -2.452357 +v -1.174591 1.296572 -2.515265 +v -1.184774 1.292099 -2.508200 +v -1.175781 1.190932 -2.566647 +v -1.186053 1.187350 -2.559015 +v -1.186053 1.187350 -2.559015 +v -1.188053 1.182508 -2.548343 +v -1.190830 0.907663 -2.599756 +v -1.189056 0.909571 -2.611125 +v -1.190345 0.759887 -2.627646 +v -1.191948 0.759470 -2.616038 +v -1.178947 0.910981 -2.619463 +v -1.180359 0.760194 -2.636253 +v -1.180025 0.607926 -2.641435 +v -1.189945 0.608463 -2.632668 +v -1.191461 0.609190 -2.620894 +v -0.879105 -0.014474 -2.515150 +v -0.881094 -0.012648 -2.503437 +v -0.882116 -0.023561 -2.501371 +v -0.880169 -0.025459 -2.513002 +v -0.881094 -0.012648 -2.503437 +v -0.891339 -0.011297 -2.495096 +v -0.891970 -0.022038 -2.493352 +v -0.882116 -0.023561 -2.501371 +v -0.882116 -0.023561 -2.501371 +v -0.891970 -0.022038 -2.493352 +v -0.896319 -0.029404 -2.493807 +v -0.891265 -0.032282 -2.500188 +v -0.880169 -0.025459 -2.513002 +v -1.173399 -0.014474 -2.525753 +v -1.171396 -0.016302 -2.537457 +v -1.169692 -0.027217 -2.535414 +v -1.171648 -0.025460 -2.523763 +v -1.171396 -0.016302 -2.537457 +v -1.161165 -0.017652 -2.545789 +v -1.159865 -0.028319 -2.543503 +v -1.169692 -0.027217 -2.535414 +v -1.155083 -0.035178 -2.540369 +v -1.160022 -0.035892 -2.533317 +v -1.160022 -0.035892 -2.533317 +v -1.161578 -0.034458 -2.521799 +v -0.944321 0.298597 -2.606959 +v -0.949121 0.452746 -2.634988 +v -0.926663 0.453086 -2.631769 +v -0.921903 0.299101 -2.603494 +v -0.949121 0.452746 -2.634988 +v -0.929791 0.607696 -2.647283 +v -0.926663 0.453086 -2.631769 +v -0.907337 0.607930 -2.643472 +v -0.904238 0.453521 -2.627815 +v -0.904238 0.453521 -2.627815 +v -0.899537 0.299622 -2.599285 +v -0.662580 1.546884 -1.440141 +v -0.639536 1.543493 -1.441672 +v -1.128458 1.390805 -2.456053 +v -1.129396 1.300258 -2.519797 +v -1.151965 1.298624 -2.517823 +v -1.151024 1.388805 -2.454479 +v -1.130557 1.193811 -2.571961 +v -1.153120 1.192560 -2.569615 +v -0.590887 0.947483 -1.029411 +v -0.636764 0.947598 -1.028303 +v -0.646028 0.988204 -1.046325 +v -0.587431 0.918205 -1.024887 +v -0.633323 0.918297 -1.023759 +v -0.658787 0.919073 -1.019859 +v -0.662200 0.948529 -1.024445 +v -0.671428 0.989316 -1.042558 +v -1.134992 -0.029144 -2.546025 +v -1.136304 -0.018201 -2.548705 +v -1.135114 -0.037634 -2.540967 +v -0.408153 0.871503 -1.023317 +v -0.405736 0.816494 -1.019776 +v -0.411036 0.918389 -1.026673 +v -0.384560 0.919187 -1.023481 +v -0.381742 0.872046 -1.020093 +v -0.379388 0.816791 -1.016522 +v -0.890710 1.546475 -1.442881 +v -0.815001 1.447413 -1.302611 +v -1.101470 0.305382 -2.556076 +v -1.105788 0.458461 -2.582224 +v -1.151610 0.458405 -2.582671 +v -1.147242 0.305317 -2.557055 +v -1.108765 0.610713 -2.596948 +v -1.154620 0.610679 -2.597126 +v -1.180411 0.610456 -2.600518 +v -1.177361 0.458012 -2.586231 +v -1.172918 0.304859 -2.560913 +v -0.367495 0.772097 -0.981628 +v -0.366968 0.771284 -0.993443 +v -0.376418 0.773193 -0.973036 +v -0.367495 0.772097 -0.981628 +v -0.376418 0.773193 -0.973036 +v -0.381092 0.748469 -0.973486 +v -0.376884 0.742380 -0.980274 +v -0.376884 0.742380 -0.980274 +v -0.376733 0.740660 -0.991849 +v -0.885863 1.504764 -1.465672 +v -0.812678 1.410477 -1.333182 +v -0.838126 1.413154 -1.330971 +v -0.911596 1.507756 -1.464250 +v -0.891533 1.622107 -2.118704 +v -0.856337 1.660225 -1.941201 +v -0.833269 1.656518 -1.940197 +v -0.868612 1.618674 -2.116483 +v -0.916997 -0.021780 -2.490732 +v -0.917273 -0.010741 -2.492445 +v -0.962245 -0.022035 -2.491596 +v -0.957916 -0.034561 -2.491092 +v -0.916207 -0.031277 -2.492232 +v -0.916997 -0.021780 -2.490732 +v -0.664197 1.505198 -1.462650 +v -1.063582 1.662382 -1.950428 +v -1.098619 1.624116 -2.130195 +v -1.121233 1.621083 -2.130181 +v -1.086203 1.659115 -1.950974 +v -1.118466 1.558001 -2.283198 +v -1.141035 1.555305 -2.282592 +v -1.163484 1.552081 -2.281635 +v -1.143685 1.617450 -2.130198 +v -1.108624 1.655189 -1.951883 +v -0.404092 0.878643 -0.975476 +v -0.402065 0.820337 -0.971437 +v -0.376297 0.820062 -0.975398 +v -0.378322 0.878123 -0.979395 +v -1.115827 1.578275 -2.116908 +v -1.079853 1.612972 -1.951162 +v -1.106123 1.616215 -1.952191 +v -1.141990 1.581289 -2.119124 +v -0.934180 0.758679 -2.593151 +v -0.933425 0.903880 -2.574732 +v -0.933559 0.610697 -2.598738 +v -0.749866 1.328853 -1.194303 +v -0.892433 1.579395 -2.106159 +v -0.856358 1.614132 -1.941855 +v -0.913739 1.518075 -2.244838 +v -0.830379 1.617632 -1.940662 +v -0.949470 1.060916 -2.601405 +v -0.927063 1.060056 -2.597854 +v -0.928717 0.911634 -2.621434 +v -0.947892 1.193891 -2.566640 +v -0.925501 1.192649 -2.562991 +v -0.903184 1.191056 -2.558749 +v -0.904739 1.058928 -2.593691 +v -0.906340 0.911007 -2.617427 +v -0.750226 1.297385 -1.231056 +v -0.701341 1.178339 -1.152299 +v -0.726628 1.180221 -1.149035 +v -0.775531 1.299686 -1.228233 +v -1.133822 0.912112 -2.626193 +v -1.135300 0.760517 -2.643573 +v -1.157807 0.760343 -2.640247 +v -1.156347 0.911621 -2.623147 +v -1.135011 0.607594 -2.649014 +v -1.157504 0.607695 -2.645577 +v -1.180025 0.607926 -2.641435 +v -1.180359 0.760194 -2.636253 +v -1.178947 0.910981 -2.619463 +v -0.666862 1.068732 -1.089076 +v -0.692198 1.070183 -1.085501 +v -0.665631 0.926157 -0.987866 +v -0.668912 0.957008 -0.992768 +v -0.671446 0.953910 -1.004263 +v -0.654995 0.928074 -0.979417 +v -0.658248 0.959301 -0.984402 +v -0.668912 0.957008 -0.992768 +v -0.658248 0.959301 -0.984402 +v -0.373796 0.921105 -1.015061 +v -0.377122 0.950935 -1.019637 +v -0.374575 0.954034 -1.008218 +v -0.384560 0.919187 -1.023481 +v -0.387933 0.948641 -1.027970 +v -0.457378 0.918258 -1.026587 +v -0.460816 0.947535 -1.031062 +v -0.414447 0.947687 -1.031135 +v -0.411036 0.918389 -1.026673 +v -0.387933 0.948641 -1.027970 +v -0.384560 0.919187 -1.023481 +v -0.522471 0.918231 -1.025743 +v -0.525925 0.947509 -1.030244 +v -0.521090 0.960439 -0.982340 +v -0.586062 0.960411 -0.981432 +v -0.439449 1.088430 -1.047504 +v -0.413795 1.086992 -1.051132 +v -0.632080 0.960256 -0.981276 +v -0.578851 0.726637 -0.988389 +v -0.513925 0.726666 -0.989309 +v -0.513056 0.728947 -0.977484 +v -0.577978 0.728918 -0.976554 +v -0.448927 0.726695 -0.990221 +v -0.448066 0.728976 -0.978406 +v -0.447443 0.741567 -0.970166 +v -0.512425 0.741538 -0.969237 +v -0.623779 0.730571 -0.976033 +v -0.624827 0.728358 -0.987807 +v -0.648878 0.742258 -0.976395 +v -0.650690 0.740538 -0.987981 +v -0.448927 0.726695 -0.990221 +v -0.449791 0.727897 -1.002195 +v -0.403793 0.729596 -1.002834 +v -0.402762 0.728457 -0.990941 +v -0.450441 0.739689 -1.011538 +v -0.404966 0.740918 -1.011855 +v -0.383733 0.746778 -1.010687 +v -0.378529 0.741324 -1.003505 +v -0.376733 0.740660 -0.991849 +v -0.512315 0.772427 -0.967090 +v -0.447333 0.772456 -0.968022 +v -0.512315 0.772427 -0.967090 +v -0.447333 0.772456 -0.968022 +v -0.515900 0.770014 -1.015711 +v -0.450882 0.770042 -1.016603 +v -0.515900 0.770014 -1.015711 +v -0.450882 0.770042 -1.016603 +v -0.515455 0.739662 -1.010642 +v -0.376297 0.820062 -0.975398 +v -0.402065 0.820337 -0.971437 +v -0.401407 0.772678 -0.969181 +v -0.401407 0.772678 -0.969181 +v -0.402057 0.742764 -0.971217 +v -0.660212 0.770795 -1.001178 +v -0.660698 0.771155 -0.989298 +v -0.651389 0.771054 -1.009865 +v -0.646435 0.746664 -1.007038 +v -0.650577 0.741205 -0.999702 +v -0.650690 0.740538 -0.987981 +v -0.404838 0.770312 -1.016738 +v -0.379316 0.771173 -1.013635 +v -0.404838 0.770312 -1.016738 +v -0.379316 0.771173 -1.013635 +v -0.487750 -0.901146 -0.979023 +v -0.541550 -0.893790 -0.975471 +v -0.539806 -0.894393 -0.963653 +v -0.488339 -0.901461 -0.967188 +v -0.595250 -0.901495 -0.971218 +v -0.591217 -0.901795 -0.959714 +v -0.579019 -0.905588 -0.953335 +v -0.538539 -0.902092 -0.955058 +v -0.498416 -0.905326 -0.959193 +v -0.468935 -0.926827 -0.991200 +v -0.463971 -0.926154 -0.979619 +v -0.468935 -0.926827 -0.991200 +v -0.491754 -0.902566 -0.990445 +v -0.491754 -0.902566 -0.990445 +v -0.487750 -0.901146 -0.979023 +v -0.613504 -0.926308 -0.956797 +v -0.618497 -0.926656 -0.968398 +v -0.615668 -0.981685 -0.954358 +v -0.590873 -0.981558 -0.947305 +v -0.589664 -0.926365 -0.949912 +v -0.613504 -0.926308 -0.956797 +v -0.591217 -0.901795 -0.959714 +v -0.595250 -0.901495 -0.971218 +v -0.536699 -0.981366 -0.948120 +v -0.537796 -0.925747 -0.950687 +v -0.486801 -0.926031 -0.957389 +v -0.537796 -0.925747 -0.950687 +v -0.486801 -0.926031 -0.957389 +v -0.867240 -0.861896 -1.922366 +v -0.928652 -0.866134 -1.924387 +v -0.928512 -0.861376 -1.926412 +v -0.870334 -0.857089 -1.925392 +v -0.988261 -0.861998 -1.919706 +v -0.985978 -0.858276 -1.921925 +v -0.928512 -0.861376 -1.926412 +v -0.985978 -0.858276 -1.921925 +v -0.991112 -0.860358 -1.924635 +v -0.928638 -0.863161 -1.930480 +v -0.870334 -0.857089 -1.925392 +v -0.865454 -0.857714 -1.929752 +v -0.844833 -0.835618 -1.906735 +v -0.848012 -0.848280 -1.915496 +v -0.844965 -0.846468 -1.918540 +v -0.840388 -0.832952 -1.908549 +v -0.848012 -0.848280 -1.915496 +v -0.844965 -0.846468 -1.918540 +v -0.836919 -0.845640 -1.921759 +v -0.831559 -0.830063 -1.909655 +v -1.049957 -0.684566 -2.078012 +v -1.047107 -0.693057 -2.087569 +v -1.044052 -0.724960 -2.053234 +v -1.047012 -0.714351 -2.042367 +v -1.047107 -0.693057 -2.087569 +v -1.023988 -0.699303 -2.094322 +v -1.019552 -0.732697 -2.061380 +v -1.044052 -0.724960 -2.053234 +v -1.044052 -0.724960 -2.053234 +v -1.019552 -0.732697 -2.061380 +v -1.024709 -0.743164 -2.060091 +v -1.051652 -0.733305 -2.049565 +v -1.051652 -0.733305 -2.049565 +v -1.054965 -0.719654 -2.036103 +v -0.914563 -0.669248 -2.059433 +v -0.968222 -0.667229 -2.057682 +v -0.959733 -0.691988 -2.020844 +v -0.902581 -0.694114 -2.023826 +v -1.022167 -0.669672 -2.060934 +v -1.017268 -0.695497 -2.023556 +v -0.959733 -0.691988 -2.020844 +v -1.017268 -0.695497 -2.023556 +v -1.022250 -0.695031 -2.013310 +v -0.958775 -0.689857 -2.010761 +v -0.902581 -0.694114 -2.023826 +v -0.895752 -0.692020 -2.015291 +v -0.855353 -0.887572 -1.911940 +v -0.855432 -0.907282 -1.905353 +v -0.877370 -0.912439 -1.914165 +v -0.855353 -0.887572 -1.911940 +v -0.872414 -0.881702 -1.904109 +v -0.872571 -0.901479 -1.896003 +v -0.855432 -0.907282 -1.905353 +v -0.872768 -0.928676 -1.887585 +v -0.855433 -0.933561 -1.898185 +v -0.855433 -0.933561 -1.898185 +v -0.877174 -0.937724 -1.908326 +v -0.996625 -0.864864 -1.905419 +v -0.997877 -0.872452 -1.911771 +v -0.973709 -0.872545 -1.900072 +v -0.981695 -0.876004 -1.919869 +v -0.997877 -0.872452 -1.911771 +v -0.997877 -0.872452 -1.911771 +v -0.998633 -0.885747 -1.909544 +v -0.973709 -0.872545 -1.900072 +v -0.997877 -0.872452 -1.911771 +v -0.998633 -0.885747 -1.909544 +v -0.976609 -0.880284 -1.902245 +v -0.847715 -0.865152 -1.908850 +v -0.853762 -0.873476 -1.914611 +v -0.847715 -0.865152 -1.908850 +v -0.867924 -0.873340 -1.902407 +v -0.853762 -0.873476 -1.914611 +v -0.853762 -0.873476 -1.914611 +v -0.867924 -0.873340 -1.902407 +v -0.872414 -0.881702 -1.904109 +v -0.855353 -0.887572 -1.911940 +v -0.853762 -0.873476 -1.914611 +v -0.918396 -0.874006 -1.895620 +v -0.918396 -0.874006 -1.895620 +v -0.973709 -0.872545 -1.900072 +v -0.976609 -0.880284 -1.902245 +v -0.923581 -0.878868 -1.900340 +v -0.924038 -0.925925 -1.883023 +v -0.924525 -0.962217 -1.876558 +v -0.873220 -0.964610 -1.881342 +v -0.976964 -0.926618 -1.886272 +v -0.977415 -0.962544 -1.880043 +v -0.978067 -1.011835 -1.876977 +v -0.925183 -1.012051 -1.873598 +v -0.873871 -1.013625 -1.878489 +v -0.923581 -0.878868 -1.900340 +v -0.923767 -0.898479 -1.891810 +v -0.976766 -0.899634 -1.894464 +v -0.930378 -0.913713 -1.916919 +v -0.981582 -0.910832 -1.912825 +v -0.930108 -0.938550 -1.911660 +v -0.981386 -0.935932 -1.907183 +v -0.998712 -0.904910 -1.903375 +v -0.998712 -0.904910 -1.903375 +v -0.998713 -0.930914 -1.896497 +v -0.998713 -0.930914 -1.896497 +v -0.982273 -1.015577 -1.899131 +v -0.930954 -1.017036 -1.903924 +v -0.931690 -1.072763 -1.904575 +v -0.983010 -1.072778 -1.899754 +v -0.878061 -1.017135 -1.900447 +v -0.878797 -1.073839 -1.901405 +v -0.879534 -1.130742 -1.909534 +v -0.932427 -1.128823 -1.912454 +v -0.983746 -1.130105 -1.907587 +v -0.930334 -0.972186 -1.906877 +v -0.981648 -0.969927 -1.902178 +v -0.877436 -0.971726 -1.903309 +v -0.930334 -0.972186 -1.906877 +v -0.877436 -0.971726 -1.903309 +v -0.981648 -0.969927 -1.902178 +v -0.999070 -0.965873 -1.890883 +v -0.999070 -0.965873 -1.890883 +v -0.999070 -0.965873 -1.890883 +v -0.999708 -1.013392 -1.887789 +v -0.999708 -1.013392 -1.887789 +v -0.855790 -0.968531 -1.892553 +v -0.855790 -0.968531 -1.892553 +v -0.855790 -0.968531 -1.892553 +v -0.873220 -0.964610 -1.881342 +v -0.873871 -1.013625 -1.878489 +v -0.856428 -1.015694 -1.889733 +v -0.855790 -0.968531 -1.892553 +v -0.856428 -1.015694 -1.889733 +v -0.857901 -1.135162 -1.899616 +v -0.861561 -1.180366 -1.915664 +v -0.882313 -1.175141 -1.925034 +v -0.857901 -1.135162 -1.899616 +v -0.875345 -1.139324 -1.888913 +v -0.878303 -1.184556 -1.905000 +v -0.861561 -1.180366 -1.915664 +v -0.889893 -1.205743 -1.919053 +v -0.882971 -1.206446 -1.929810 +v -0.882971 -1.206446 -1.929810 +v -0.893037 -1.198816 -1.935095 +v -0.978067 -1.011835 -1.876977 +v -0.999708 -1.013392 -1.887789 +v -1.000445 -1.073977 -1.888704 +v -0.978804 -1.075604 -1.878320 +v -1.000445 -1.073977 -1.888704 +v -1.001182 -1.134220 -1.896740 +v -1.001182 -1.134220 -1.896740 +v -0.979540 -1.138592 -1.886677 +v -0.857165 -1.075544 -1.891143 +v -0.874609 -1.076822 -1.880217 +v -0.857165 -1.075544 -1.891143 +v -0.925183 -1.012051 -1.873598 +v -0.925919 -1.076758 -1.875273 +v -0.926656 -1.140558 -1.883902 +v -0.971194 -1.198326 -1.933530 +v -0.932529 -1.202038 -1.938699 +v -0.930755 -1.214719 -1.934183 +v -0.978250 -1.205797 -1.927816 +v -0.893037 -1.198816 -1.935095 +v -0.882971 -1.206446 -1.929810 +v -0.930755 -1.214719 -1.934183 +v -0.928691 -1.210204 -1.918927 +v -0.978250 -1.205797 -1.927816 +v -0.968041 -1.205212 -1.917335 +v -0.927422 -1.186385 -1.900327 +v -0.978037 -1.183935 -1.902762 +v -0.932950 -1.173536 -1.928111 +v -0.982062 -1.174594 -1.923072 +v -0.932529 -1.202038 -1.938699 +v -0.971194 -1.198326 -1.933530 +v -0.998811 -1.179556 -1.912775 +v -0.998811 -1.179556 -1.912775 +v -0.978250 -1.205797 -1.927816 +v -0.912944 -0.601142 -2.147676 +v -0.909910 -0.608138 -2.157169 +v -0.935716 -0.595983 -2.141377 +v -0.912944 -0.601142 -2.147676 +v -0.891454 -0.675508 -2.066181 +v -0.891454 -0.675508 -2.066181 +v -0.888680 -0.684100 -2.075705 +v -1.064289 -0.615179 -2.172466 +v -1.067320 -0.608196 -2.162882 +v -1.041517 -0.620336 -2.178778 +v -1.064289 -0.615179 -2.172466 +v -0.989110 -0.622147 -2.179341 +v -0.936574 -0.620311 -2.174866 +v -0.916556 -0.699105 -2.092746 +v -0.970415 -0.701435 -2.096035 +v -0.988119 -0.594186 -2.140710 +v -1.040652 -0.596036 -2.145082 +v -0.986548 -0.804694 -1.880105 +v -0.923206 -0.799921 -1.880088 +v -0.923028 -0.789209 -1.876004 +v -0.993969 -0.795491 -1.875455 +v -0.860573 -0.803397 -1.886644 +v -0.852909 -0.793123 -1.884879 +v -0.923028 -0.789209 -1.876004 +v -0.852909 -0.793123 -1.884879 +v -0.851285 -0.770187 -1.899773 +v -0.927833 -0.766152 -1.889290 +v -0.993969 -0.795491 -1.875455 +v -1.005246 -0.774036 -1.888754 +v -1.020284 -0.833019 -1.900913 +v -1.015064 -0.816853 -1.888186 +v -1.025921 -0.810751 -1.885487 +v -1.031788 -0.830863 -1.901646 +v -1.025921 -0.810751 -1.885487 +v -1.040019 -0.792019 -1.900713 +v -1.031788 -0.830863 -1.901646 +v -1.025921 -0.810751 -1.885487 +v -1.040019 -0.792019 -1.900713 +v -1.046269 -0.815407 -1.919895 +v -0.866056 -0.716311 -2.039692 +v -0.868879 -0.701976 -2.025869 +v -0.857691 -0.699028 -2.021455 +v -0.854691 -0.717721 -2.038972 +v -0.887708 -0.686283 -2.007730 +v -0.857691 -0.699028 -2.021455 +v -0.887708 -0.686283 -2.007730 +v -0.876052 -0.695749 -1.984987 +v -0.843431 -0.710960 -2.001349 +v -0.854691 -0.717721 -2.038972 +v -0.857691 -0.699028 -2.021455 +v -0.843431 -0.710960 -2.001349 +v -0.840307 -0.733302 -2.021696 +v -0.962246 -0.746109 -2.065034 +v -0.962429 -0.757144 -2.069374 +v -1.032188 -0.753677 -2.062103 +v -0.899330 -0.741717 -2.062897 +v -0.892137 -0.751078 -2.067750 +v -0.962429 -0.757144 -2.069374 +v -0.892137 -0.751078 -2.067750 +v -0.881355 -0.773418 -2.054618 +v -0.957967 -0.781146 -2.055706 +v -1.032188 -0.753677 -2.062103 +v -1.033934 -0.777396 -2.046440 +v -0.962678 -0.735189 -2.064494 +v -0.905420 -0.732047 -2.061914 +v -0.962678 -0.735189 -2.064494 +v -0.905420 -0.732047 -2.061914 +v -0.878116 -0.701898 -2.031988 +v -0.875398 -0.712826 -2.042971 +v -0.878116 -0.701898 -2.031988 +v -0.878116 -0.701898 -2.031988 +v -0.875398 -0.712826 -2.042971 +v -1.005862 -0.836030 -1.902592 +v -1.001529 -0.823804 -1.893781 +v -1.007151 -0.820617 -1.892472 +v -1.011811 -0.834300 -1.902773 +v -0.977308 -0.814738 -1.887860 +v -0.981322 -0.810410 -1.885713 +v -0.923339 -0.811473 -1.887041 +v -0.923837 -0.806592 -1.885160 +v -0.869894 -0.814561 -1.890819 +v -0.866943 -0.809827 -1.889955 +v -0.953025 -0.693147 -1.976326 +v -0.940337 -0.727112 -1.930706 +v -0.861254 -0.730522 -1.940954 +v -1.030642 -0.702024 -1.978020 +v -1.020200 -0.736073 -1.931171 +v -0.946327 -0.821961 -2.012836 +v -1.024614 -0.818414 -2.002784 +v -0.867259 -0.813137 -2.012176 +v -0.857509 -0.848755 -1.965103 +v -0.934458 -0.857539 -1.965551 +v -1.010544 -0.854402 -1.956053 +v -1.070685 -0.740991 -2.010336 +v -1.066681 -0.762328 -2.030153 +v -1.058153 -0.802081 -1.985498 +v -1.061945 -0.778597 -1.964580 +v -1.066681 -0.762328 -2.030153 +v -1.058153 -0.802081 -1.985498 +v -1.042926 -0.838498 -1.939705 +v -1.042926 -0.838498 -1.939705 +v -0.827815 -0.746872 -1.958215 +v -0.824719 -0.770476 -1.978962 +v -0.827815 -0.746872 -1.958215 +v -0.818960 -0.785979 -1.915998 +v -0.818960 -0.785979 -1.915998 +v -0.816022 -0.808284 -1.934946 +v -0.958340 -0.684053 -2.001174 +v -1.029506 -0.691357 -2.003514 +v -0.958340 -0.684053 -2.001174 +v -1.029506 -0.691357 -2.003514 +v -1.054965 -0.719654 -2.036103 +v -1.062314 -0.741088 -2.048467 +v -1.066078 -0.723476 -2.031576 +v -1.062314 -0.741088 -2.048467 +v -1.066078 -0.723476 -2.031576 +v -1.062314 -0.741088 -2.048467 +v -0.826675 -0.844925 -1.929425 +v -0.820583 -0.825734 -1.914193 +v -0.858660 -0.860054 -1.939324 +v -0.826675 -0.844925 -1.929425 +v -0.858660 -0.860054 -1.939324 +v -0.822679 -0.830886 -1.953267 +v -0.820583 -0.825734 -1.914193 +v -0.826675 -0.844925 -1.929425 +v -0.822679 -0.830886 -1.953267 +v -0.929344 -0.867389 -1.939835 +v -0.999206 -0.864525 -1.932020 +v -0.929344 -0.867389 -1.939835 +v -0.999206 -0.864525 -1.932020 +v -1.026472 -0.053467 -2.482729 +v -0.971403 -0.054090 -2.483591 +v -1.081225 -0.054090 -2.487844 +v -1.024058 -0.061534 -2.529685 +v -1.079102 -0.061126 -2.528816 +v -0.969312 -0.061126 -2.524558 +v -1.116663 -0.042009 -2.517685 +v -1.113731 -0.043488 -2.529575 +v -1.102735 -0.059962 -2.520885 +v -1.106557 -0.058025 -2.509247 +v -1.113731 -0.043488 -2.529575 +v -1.102735 -0.059962 -2.520885 +v -0.934358 -0.042009 -2.510762 +v -0.937298 -0.039696 -2.499090 +v -0.947752 -0.055927 -2.491349 +v -0.943939 -0.058025 -2.502938 +v -0.937298 -0.039696 -2.499090 +v -0.947752 -0.055927 -2.491349 +v -0.964923 0.053544 -2.506011 +v -0.963496 0.004571 -2.496528 +v -0.917714 0.004493 -2.495452 +v -0.919134 0.053467 -2.505120 +v -0.891783 0.003941 -2.498137 +v -0.893210 0.052931 -2.507910 +v -1.092216 -0.022035 -2.496380 +v -1.137348 -0.021780 -2.498856 +v -1.137766 -0.010741 -2.500378 +v -1.137348 -0.021780 -2.498856 +v -1.163274 -0.011297 -2.504896 +v -1.161972 -0.022038 -2.503316 +v -1.161972 -0.022038 -2.503316 +v -1.114374 -0.003415 -2.553967 +v -1.138691 -0.002967 -2.551638 +v -1.140793 0.046194 -2.560474 +v -1.161681 -0.002360 -2.548497 +v -1.163341 0.046803 -2.557202 +v -0.914477 -0.029144 -2.537912 +v -0.913840 -0.018201 -2.540722 +v -0.889291 -0.017653 -2.536012 +v -0.889922 -0.028319 -2.533560 +v -1.175474 0.049867 -2.537089 +v -1.173532 0.048105 -2.548811 +v -1.171902 -0.001021 -2.540151 +v -1.173892 0.000790 -2.528442 +v -1.163341 0.046803 -2.557202 +v -1.161681 -0.002360 -2.548497 +v -1.161165 -0.017652 -2.545789 +v -0.881077 0.049867 -2.528043 +v -0.883007 0.051629 -2.516311 +v -0.881548 0.002602 -2.506491 +v -0.879572 0.000790 -2.518209 +v -0.883007 0.051629 -2.516311 +v -0.881548 0.002602 -2.506491 +v -1.029474 0.053543 -2.507987 +v -1.028036 0.004572 -2.498761 +v -1.094004 0.053544 -2.509965 +v -1.092553 0.004572 -2.500998 +v -1.024937 -0.018242 -2.554865 +v -0.970071 -0.016127 -2.553276 +v -1.079946 -0.016127 -2.557155 +v -1.024937 -0.018242 -2.554865 +v -1.079946 -0.016127 -2.557155 +v -1.078146 -0.017249 -2.565294 +v -1.024772 -0.019239 -2.563039 +v -0.970071 -0.016127 -2.553276 +v -0.971532 -0.017249 -2.561535 +v -0.579026 1.210252 -1.099748 +v -0.538444 1.243951 -1.122470 +v -0.579026 1.210252 -1.099748 +v -0.538444 1.243951 -1.122470 +v -0.541330 1.252889 -1.118103 +v -0.580279 1.219759 -1.095635 +v -0.649068 1.244049 -1.121807 +v -0.648667 1.253101 -1.117603 +v -0.979429 0.610724 -2.597892 +v -1.044098 0.610718 -2.597420 +v -1.041149 0.458462 -2.582323 +v -0.976504 0.458462 -2.582422 +v -1.036870 0.305382 -2.555427 +v -0.972260 0.305382 -2.554780 +v -0.894842 0.457060 -2.595410 +v -0.893277 0.455768 -2.607249 +v -0.907697 0.610476 -2.602511 +v -0.904793 0.458014 -2.586647 +v -0.894842 0.457060 -2.595410 +v -0.904793 0.458014 -2.586647 +v -0.900550 0.304859 -2.558170 +v -0.890509 0.303746 -2.566808 +v -0.890509 0.303746 -2.566808 +v -0.888814 0.302240 -2.578615 +v -1.186740 0.454474 -2.618581 +v -1.188308 0.455765 -2.606764 +v -1.176790 0.453520 -2.627330 +v -1.171878 0.299622 -2.601970 +v -1.181912 0.300735 -2.593345 +v -1.183614 0.302240 -2.581556 +v -1.131795 0.452749 -2.634653 +v -1.154275 0.453086 -2.631356 +v -1.131795 0.452749 -2.634653 +v -1.149351 0.299101 -2.605725 +v -1.154275 0.453086 -2.631356 +v -1.171878 0.299622 -2.601970 +v -1.176790 0.453520 -2.627330 +v -1.176790 0.453520 -2.627330 +v -0.930655 0.458407 -2.583006 +v -0.933559 0.610697 -2.598738 +v -0.926434 0.305317 -2.554833 +v -0.907697 0.610476 -2.602511 +v -1.097189 0.160972 -2.529635 +v -1.142912 0.160900 -2.531157 +v -1.139691 0.053467 -2.511891 +v -1.168512 0.160397 -2.535317 +v -1.165233 0.052931 -2.516276 +v -0.935980 0.045607 -2.557447 +v -0.939538 0.153501 -2.578566 +v -0.917159 0.154074 -2.574841 +v -0.913631 0.046194 -2.553526 +v -0.894855 0.154648 -2.570373 +v -0.891372 0.046803 -2.548865 +v -1.132082 1.060889 -2.604864 +v -1.154627 1.060029 -2.602157 +v -1.177274 1.058880 -2.598818 +v -0.930103 0.760349 -2.640937 +v -0.907671 0.760208 -2.637084 +v -0.978301 1.045869 -2.552720 +v -0.932383 1.046059 -2.552394 +v -0.906378 1.047118 -2.555299 +v -1.187503 1.056340 -2.590784 +v -1.189443 1.052902 -2.579690 +v -1.187503 1.056340 -2.590784 +v -1.189056 0.909571 -2.611125 +v -0.896181 1.049636 -2.563282 +v -0.894310 1.053030 -2.574290 +v -0.896181 1.049636 -2.563282 +v -1.042986 1.045814 -2.553861 +v -0.935980 0.045607 -2.557447 +v -0.936678 -0.003415 -2.547838 +v -0.947256 -0.004319 -2.554823 +v -0.945661 0.044391 -2.564228 +v -0.936678 -0.003415 -2.547838 +v -0.947256 -0.004319 -2.554823 +v -0.971532 -0.017249 -2.561535 +v -0.948596 -0.005752 -2.562945 +v -0.948596 -0.005752 -2.562945 +v -0.946900 0.042884 -2.572302 +v -1.155277 0.758623 -2.592443 +v -1.154620 0.610679 -2.597126 +v -1.181047 0.758746 -2.595894 +v -1.180411 0.610456 -2.600518 +v -1.126540 1.477618 -2.385163 +v -1.149097 1.475267 -2.384037 +v -1.171584 1.472444 -2.382396 +v -1.181424 1.466376 -2.376782 +v -1.182838 1.458198 -2.368577 +v -1.173159 1.545185 -2.277430 +v -1.181424 1.466376 -2.376782 +v -0.887539 1.450984 -2.345961 +v -0.886268 1.459101 -2.353984 +v -0.897344 1.444957 -2.340459 +v -0.887539 1.450984 -2.345961 +v -1.119375 1.303484 -2.525095 +v -1.120571 1.196277 -2.577712 +v -1.118422 1.394757 -2.460801 +v -1.119375 1.303484 -2.525095 +v -1.118422 1.394757 -2.460801 +v -1.116760 1.399636 -2.467167 +v -1.117734 1.307473 -2.532065 +v -1.120571 1.196277 -2.577712 +v -1.118975 1.199329 -2.585155 +v -1.034616 1.441667 -2.344210 +v -0.969501 1.441897 -2.341112 +v -1.150561 1.273769 -2.476325 +v -1.176245 1.275569 -2.480303 +v -0.923317 1.442405 -2.339252 +v -0.946503 1.300448 -2.512979 +v -0.924092 1.298851 -2.509329 +v -0.901707 1.296861 -2.505129 +v -0.951655 -0.006989 -2.569888 +v -0.950094 0.041598 -2.579261 +v -0.973670 -0.018282 -2.568382 +v -0.951655 -0.006989 -2.569888 +v -0.984669 -0.017863 -2.572607 +v -0.973960 -0.007681 -2.575064 +v -0.950094 0.041598 -2.579261 +v -0.973330 0.040750 -2.584496 +v -0.700412 1.567163 -1.427290 +v -0.624590 1.465358 -1.285135 +v -0.776601 1.641827 -1.591211 +v -0.700412 1.567163 -1.427290 +v -0.776601 1.641827 -1.591211 +v -0.800039 1.646057 -1.590505 +v -0.723824 1.571091 -1.425492 +v -0.624590 1.465358 -1.285135 +v -0.648015 1.468871 -1.282399 +v -1.106848 1.569821 -2.290806 +v -1.087097 1.637315 -2.134991 +v -1.083622 1.643553 -2.137320 +v -1.103315 1.575414 -2.294485 +v -1.052185 1.676539 -1.952078 +v -1.048780 1.683217 -1.952890 +v -1.083622 1.643553 -2.137320 +v -1.048780 1.683217 -1.952890 +v -1.025189 1.687745 -1.952206 +v -1.059982 1.647831 -2.137549 +v -1.103315 1.575414 -2.294485 +v -1.079673 1.579262 -2.295623 +v -1.120511 0.451251 -2.649306 +v -1.117149 0.450543 -2.656229 +v -1.112125 0.295163 -2.630027 +v -1.123761 0.607223 -2.663797 +v -1.120419 0.607047 -2.670769 +v -1.117149 0.450543 -2.656229 +v -1.120419 0.607047 -2.670769 +v -1.097045 0.606925 -2.675528 +v -1.093768 0.450071 -2.660835 +v -1.112125 0.295163 -2.630027 +v -1.117149 0.450543 -2.656229 +v -1.093768 0.450071 -2.660835 +v -1.088730 0.294435 -2.634339 +v -1.122454 0.914294 -2.640604 +v -1.120606 1.064677 -2.618770 +v -1.117157 1.066469 -2.625378 +v -1.119058 0.915326 -2.647429 +v -1.115474 1.201940 -2.591446 +v -1.117157 1.066469 -2.625378 +v -1.115474 1.201940 -2.591446 +v -1.092003 1.203688 -2.594974 +v -1.093729 1.067667 -2.629333 +v -1.119058 0.915326 -2.647429 +v -1.095658 0.916012 -2.651771 +v -0.928723 1.644625 -2.128236 +v -0.893898 1.684075 -1.944553 +v -0.948694 1.576427 -2.285408 +v -0.928723 1.644625 -2.128236 +v -0.948694 1.576427 -2.285408 +v -0.972116 1.580017 -2.289209 +v -0.952234 1.648619 -2.131076 +v -0.893898 1.684075 -1.944553 +v -0.917452 1.688354 -1.946208 +v -1.124017 0.761345 -2.658279 +v -1.120660 0.761737 -2.665224 +v -1.120660 0.761737 -2.665224 +v -1.097279 0.761993 -2.669870 +v -0.541330 1.252889 -1.118103 +v -0.560697 1.345123 -1.183786 +v -0.564238 1.350231 -1.178936 +v -0.545300 1.260674 -1.115080 +v -0.564238 1.350231 -1.178936 +v -0.587717 1.355380 -1.177073 +v -0.545300 1.260674 -1.115080 +v -0.564562 1.281332 -1.124389 +v -0.967096 0.761719 -2.665688 +v -0.965546 0.915349 -2.646261 +v -0.966840 0.607015 -2.671920 +v -0.967096 0.761719 -2.665688 +v -0.966840 0.607015 -2.671920 +v -0.990207 0.606899 -2.676329 +v -0.990452 0.761979 -2.670192 +v -0.965546 0.915349 -2.646261 +v -0.988867 0.916030 -2.650957 +v -0.958782 1.199466 -2.580461 +v -0.960466 1.064746 -2.615716 +v -0.963688 1.066557 -2.622443 +v -0.961954 1.202100 -2.586936 +v -0.963688 1.066557 -2.622443 +v -0.986967 1.067737 -2.627287 +v -0.961954 1.202100 -2.586936 +v -0.985207 1.203812 -2.591832 +v -0.558890 1.339139 -1.189619 +v -0.558890 1.339139 -1.189619 +v -0.538444 1.243951 -1.122470 +v -0.837714 1.668128 -1.766153 +v -0.827685 1.661849 -1.766814 +v -0.837714 1.668128 -1.766153 +v -0.837714 1.668128 -1.766153 +v -0.839172 1.675936 -1.764941 +v -1.122142 1.062581 -2.610983 +v -1.123929 0.913087 -2.632592 +v -1.122142 1.062581 -2.610983 +v -1.123929 0.913087 -2.632592 +v -1.088634 1.630035 -2.132094 +v -1.108456 1.563297 -2.286336 +v -1.098619 1.624116 -2.130195 +v -1.053644 1.668734 -1.950963 +v -1.088634 1.630035 -2.132094 +v -1.088634 1.630035 -2.132094 +v -1.053644 1.668734 -1.950963 +v -1.108456 1.563297 -2.286336 +v -1.001683 1.667535 -1.772349 +v -1.001683 1.667535 -1.772349 +v -1.000289 1.675458 -1.771750 +v -0.958929 0.452070 -2.641505 +v -0.949121 0.452746 -2.634988 +v -0.944321 0.298597 -2.606959 +v -0.954082 0.297553 -2.613555 +v -0.958929 0.452070 -2.641505 +v -0.955405 0.296259 -2.621623 +v -0.960303 0.451232 -2.649602 +v -0.956158 1.303680 -2.519001 +v -0.954893 1.395108 -2.453527 +v -0.957570 1.196377 -2.572953 +v -0.956158 1.303680 -2.519001 +v -0.957570 1.196377 -2.572953 +v -0.957327 1.307698 -2.526060 +v -0.954893 1.395108 -2.453527 +v -0.956046 1.400028 -2.459964 +v -0.959194 1.062625 -2.607887 +v -0.959194 1.062625 -2.607887 +v -0.952655 1.482822 -2.380818 +v -0.952655 1.482822 -2.380818 +v -0.953829 1.488642 -2.386390 +v -1.121944 0.452080 -2.641204 +v -1.135011 0.607594 -2.649014 +v -1.125170 0.607428 -2.655651 +v -1.121944 0.452080 -2.641204 +v -1.125170 0.607428 -2.655651 +v -1.116510 1.482253 -2.389228 +v -1.116510 1.482253 -2.389228 +v -1.114860 1.487971 -2.394818 +v -1.125443 0.760886 -2.650155 +v -1.125170 0.607428 -2.655651 +v -1.125443 0.760886 -2.650155 +v -0.755055 1.469914 -1.284104 +v -0.701539 1.470556 -1.282233 +v -0.777297 1.572822 -1.426183 +v -0.830754 1.571915 -1.428436 +v -0.853563 1.647650 -1.592059 +v -0.907069 1.646344 -1.594596 +v -0.645039 1.281695 -1.124308 +v -0.598346 1.267264 -1.113978 +v -0.638389 1.355287 -1.175222 +v -0.690332 1.356115 -1.177568 +v -0.971314 1.689559 -1.949374 +v -1.006085 1.649643 -2.134838 +v -1.025856 1.580915 -2.293263 +v -0.919765 1.688361 -1.766884 +v -0.973462 1.686727 -1.769635 +v -0.866061 1.686958 -1.764483 +v -0.917452 1.688354 -1.946208 +v -0.971314 1.689559 -1.949374 +v -1.025189 1.687745 -1.952206 +v -1.089610 1.406628 -2.475063 +v -1.035989 1.407726 -2.473874 +v -1.037147 1.314034 -2.540360 +v -1.090663 1.313172 -2.541015 +v -0.982468 1.406930 -2.470213 +v -0.983724 1.313349 -2.536995 +v -1.038568 1.204343 -2.594847 +v -1.042249 0.916255 -2.652913 +v -1.043861 0.762074 -2.671599 +v -1.043625 0.606872 -2.677499 +v -1.079971 0.040750 -2.587742 +v -1.026619 0.040459 -2.587670 +v -1.024951 -0.008046 -2.578290 +v -1.076014 -0.007681 -2.578570 +v -1.024605 -0.018862 -2.574528 +v -1.064631 -0.017863 -2.575418 +v -1.040359 0.449901 -2.662498 +v -0.986961 0.450052 -2.661033 +v -1.040359 0.449901 -2.662498 +v -0.986961 0.450052 -2.661033 +v -0.981980 0.294429 -2.633299 +v -1.035340 0.294182 -2.635375 +v -1.040322 1.068110 -2.629818 +v -1.033952 1.497601 -2.399587 +v -1.087672 1.496215 -2.401390 +v -0.980326 1.496757 -2.395631 +v -0.960465 1.311124 -2.532168 +v -0.959176 1.404223 -2.465559 +v -0.960465 1.311124 -2.532168 +v -0.959176 1.404223 -2.465559 +v -0.854120 1.568147 -1.431194 +v -0.930457 1.642117 -1.596757 +v -0.778455 1.466636 -1.287312 +v -0.854120 1.568147 -1.431194 +v -0.778455 1.466636 -1.287312 +v -0.930457 1.642117 -1.596757 +v -1.024628 -0.020205 -2.569888 +v -0.973670 -0.018282 -2.568382 +v -1.075719 -0.018282 -2.571979 +v -1.024628 -0.020205 -2.569888 +v -1.075719 -0.018282 -2.571979 +v -0.956980 1.493598 -2.391266 +v -0.956980 1.493598 -2.391266 +v -1.111295 1.492870 -2.399470 +v -1.113192 1.403811 -2.472505 +v -1.111295 1.492870 -2.399470 +v -1.113192 1.403811 -2.472505 +v -1.107116 0.149562 -2.603572 +v -1.103390 0.041598 -2.583927 +v -1.107116 0.149562 -2.603572 +v -1.083707 0.148728 -2.607594 +v -1.103390 0.041598 -2.583927 +v -0.582536 1.228826 -1.093403 +v -0.648037 1.260983 -1.114731 +v -0.545300 1.260674 -1.115080 +v -0.582536 1.228826 -1.093403 +v -0.648037 1.260983 -1.114731 +v -1.114190 1.310884 -2.537937 +v -1.114190 1.310884 -2.537937 +v -0.842553 1.682601 -1.764028 +v -0.842553 1.682601 -1.764028 +v -0.893898 1.684075 -1.944553 +v -0.963614 0.450519 -2.656512 +v -0.958673 0.295156 -2.628533 +v -0.963614 0.450519 -2.656512 +v -0.958673 0.295156 -2.628533 +v -0.963614 0.450519 -2.656512 +v -0.996946 1.682223 -1.771111 +v -0.996946 1.682223 -1.771111 +v -1.048780 1.683217 -1.952890 +v -0.711898 1.351117 -1.179442 +v -0.648037 1.260983 -1.114731 +v -0.711898 1.351117 -1.179442 +v -1.078146 -0.017249 -2.565294 +v -1.101862 -0.005752 -2.568213 +v -1.098504 -0.006989 -2.574935 +v -1.101862 -0.005752 -2.568213 +v -1.098504 -0.006989 -2.574935 +v -1.030338 0.148442 -2.607993 +v -0.977018 0.148728 -2.605289 +v -0.950527 0.150825 -2.593326 +v -0.953752 0.149561 -2.600258 +v -0.953752 0.149561 -2.600258 +v -0.939538 0.153501 -2.578566 +v -0.949252 0.152305 -2.585261 +v -0.912463 -0.002967 -2.543805 +v -0.889785 -0.002360 -2.539062 +v -1.138222 0.004493 -2.503109 +v -1.163739 0.003941 -2.507596 +v -1.032629 0.160972 -2.528223 +v -0.968053 0.160972 -2.526815 +v -0.886207 0.159175 -2.537852 +v -0.884377 0.157523 -2.549616 +v -0.896341 0.160397 -2.529350 +v -0.886207 0.159175 -2.537852 +v -1.177107 0.155870 -2.567808 +v -1.178946 0.157523 -2.556058 +v -1.166982 0.154648 -2.576299 +v -1.144444 0.154074 -2.579777 +v -1.166982 0.154648 -2.576299 +v -0.922248 0.160900 -2.526326 +v -1.103552 -0.004319 -2.560199 +v -1.103552 -0.004319 -2.560199 +v -1.172918 0.304859 -2.560913 +v -1.182511 0.303746 -2.569739 +v -1.177986 0.159175 -2.544245 +v -1.168512 0.160397 -2.535317 +v -1.174620 0.051629 -2.525280 +v -1.165233 0.052931 -2.516276 +v -0.899537 0.299622 -2.599285 +v -0.889927 0.300735 -2.590450 +v -0.885353 0.155870 -2.561441 +v -0.894855 0.154648 -2.570373 +v -0.881950 0.048105 -2.539862 +v -0.891372 0.046803 -2.548865 +v -0.878921 1.546277 -2.261954 +v -0.887825 1.467210 -2.362148 +v -0.878921 1.546277 -2.261954 +v -0.887825 1.467210 -2.362148 +v -0.890499 1.381679 -2.433148 +v -0.890499 1.381679 -2.433148 +v -1.172686 1.526627 -2.264618 +v -1.181441 1.450028 -2.360231 +v -1.172686 1.526627 -2.264618 +v -1.181441 1.450028 -2.360231 +v -1.184101 1.366863 -2.427452 +v -1.184101 1.366863 -2.427452 +v -0.903184 1.191056 -2.558749 +v -0.893720 1.187523 -2.550633 +v -0.895250 1.056423 -2.585350 +v -0.904739 1.058928 -2.593691 +v -0.896743 0.909621 -2.608977 +v -0.906340 0.911007 -2.617427 +v -1.177851 1.174094 -2.529400 +v -1.187244 1.177667 -2.537591 +v -1.188574 1.049465 -2.568544 +v -1.179136 1.046928 -2.560149 +v -1.189793 0.905755 -2.588367 +v -1.180228 0.904346 -2.579887 +v -1.180411 0.610456 -2.600518 +v -1.190166 0.609919 -2.609141 +v -1.187068 0.457057 -2.594950 +v -1.177361 0.458012 -2.586231 +v -0.907337 0.607930 -2.643472 +v -0.897575 0.608472 -2.634841 +v -0.894522 0.454475 -2.619083 +v -0.904238 0.453521 -2.627815 +v -0.880399 -0.001021 -2.530024 +v -0.889785 -0.002360 -2.539062 +v -0.879917 -0.016302 -2.526964 +v -0.889291 -0.017653 -2.536012 +v -1.173085 0.002602 -2.516634 +v -1.163739 0.003941 -2.507596 +v -1.172608 -0.012647 -2.513945 +v -1.163274 -0.011297 -2.504896 +v -0.946558 -0.059961 -2.514824 +v -0.936066 -0.043488 -2.522835 +v -0.946558 -0.059961 -2.514824 +v -0.947096 -0.134153 -2.477031 +v -0.947096 -0.134153 -2.477031 +v -1.114996 -0.039696 -2.505834 +v -1.103956 -0.055927 -2.497405 +v -1.114996 -0.039696 -2.505834 +v -1.103956 -0.055927 -2.497405 +v -1.100872 -0.128894 -2.460531 +v -1.100872 -0.128894 -2.460531 +v -0.834064 -0.814609 -1.897186 +v -0.823292 -0.806756 -1.898437 +v -0.823292 -0.806756 -1.898437 +v -0.823292 -0.806756 -1.898437 +v -1.050406 -0.705864 -2.022790 +v -1.061034 -0.705624 -2.014993 +v -1.061034 -0.705624 -2.014993 +v -1.065089 -0.719334 -1.990993 +v -1.061034 -0.705624 -2.014993 +v -1.065089 -0.719334 -1.990993 +v -0.846782 -0.755965 -2.041569 +v -0.831506 -0.794417 -1.999110 +v -0.846782 -0.755965 -2.041569 +v -0.831506 -0.794417 -1.999110 +v -1.055853 -0.754776 -1.944261 +v -1.055853 -0.754776 -1.944261 +v -1.004823 -0.848726 -1.911668 +v -1.009525 -0.848030 -1.913346 +v -1.004823 -0.848726 -1.911668 +v -1.009525 -0.848030 -1.913346 +v -1.017641 -0.849061 -1.914004 +v -0.892625 -0.692710 -2.085324 +v -0.879831 -0.723820 -2.053928 +v -0.892625 -0.692710 -2.085324 +v -0.879831 -0.723820 -2.053928 +v -0.879831 -0.723820 -2.053928 +v -0.871104 -0.730786 -2.053367 +v -0.860500 -0.736655 -2.056181 +v -0.860500 -0.736655 -2.056181 +v -0.860500 -0.736655 -2.056181 +v -1.028855 -0.850762 -1.918329 +v -1.028855 -0.850762 -1.918329 +v -1.028855 -0.850762 -1.918329 +v -1.084486 -0.468981 -2.265810 +v -1.063791 -0.601211 -2.153060 +v -1.084486 -0.468981 -2.265810 +v -1.063791 -0.601211 -2.153060 +v -1.046087 -0.676054 -2.068359 +v -1.046087 -0.676054 -2.068359 +v -0.933508 -0.480162 -2.278897 +v -0.913435 -0.615135 -2.166901 +v -0.933508 -0.480162 -2.278897 +v -0.913435 -0.615135 -2.166901 +v -1.042822 -0.703680 -2.031525 +v -1.042822 -0.703680 -2.031525 +v -1.050406 -0.705864 -2.022790 +v -1.042822 -0.703680 -2.031525 +v -0.847157 -0.823494 -1.897923 +v -0.842786 -0.819602 -1.898349 +v -0.619168 -0.981821 -0.978071 +v -0.617019 -0.927308 -0.980453 +v -0.619168 -0.981821 -0.978071 +v -0.617019 -0.927308 -0.980453 +v -0.594668 -0.902900 -0.982976 +v -0.594668 -0.902900 -0.982976 +v -0.483432 -0.981209 -0.955120 +v -0.461203 -0.981183 -0.965590 +v -0.465475 -0.925828 -0.967553 +v -0.461203 -0.981183 -0.965590 +v -0.465475 -0.925828 -0.967553 +v -0.488339 -0.901461 -0.967188 +v -0.543279 -0.895511 -0.987181 +v -0.595250 -0.901495 -0.971218 +v -0.541550 -0.893790 -0.975471 +v -0.487750 -0.901146 -0.979023 +v -0.650262 0.819939 -0.971476 +v -0.660778 0.819241 -0.980102 +v -0.658477 0.771967 -0.977480 +v -0.648400 0.773071 -0.969131 +v -0.648878 0.742258 -0.976395 +v -0.643712 0.748351 -0.969719 +v -0.402102 0.730670 -0.979194 +v -0.402762 0.728457 -0.990941 +v -0.376733 0.740660 -0.991849 +v -0.579727 0.727840 -1.000381 +v -0.625514 0.729499 -0.999737 +v -0.578851 0.726637 -0.988389 +v -0.624827 0.728358 -0.987807 +v -0.650690 0.740538 -0.987981 +v -0.650577 0.741205 -0.999702 +v -0.514798 0.727868 -1.001292 +v -0.513925 0.726666 -0.989309 +v -0.374877 0.957133 -0.996763 +v -0.384008 0.959419 -0.988180 +v -0.383994 0.999530 -1.015302 +v -0.374877 0.957133 -0.996763 +v -0.383994 0.999530 -1.015302 +v -0.671174 0.950814 -1.015798 +v -0.662200 0.948529 -1.024445 +v -0.680368 0.992038 -1.034089 +v -0.671174 0.950814 -1.015798 +v -0.680368 0.992038 -1.034089 +v -0.379388 0.816791 -1.016522 +v -0.368794 0.817490 -1.007915 +v -0.369172 0.770923 -1.005242 +v -0.379316 0.771173 -1.013635 +v -0.378529 0.741324 -1.003505 +v -0.383733 0.746778 -1.010687 +v -1.170918 -0.023561 -2.512037 +v -1.161972 -0.022038 -2.503316 +v -1.161243 -0.032282 -2.510340 +v -1.170918 -0.023561 -2.512037 +v -0.880924 -0.027217 -2.524761 +v -0.889922 -0.028319 -2.533560 +v -0.889701 -0.034458 -2.511572 +v -0.890079 -0.035892 -2.523177 +v -0.880924 -0.027217 -2.524761 +v -1.190740 0.759054 -2.604440 +v -1.181047 0.758746 -2.595894 +v -1.174447 1.361629 -2.420195 +v -1.185728 1.280020 -2.488087 +v -1.176245 1.275569 -2.480303 +v -0.892128 1.292452 -2.497435 +v -0.892128 1.292452 -2.497435 +v -0.893720 1.187523 -2.550633 +v -0.897962 0.759912 -2.628546 +v -0.907671 0.760208 -2.637084 +v -1.116573 1.624432 -1.952528 +v -1.152251 1.588916 -2.121956 +v -1.116573 1.624432 -1.952528 +v -1.152251 1.588916 -2.121956 +v -0.822668 1.648288 -1.939851 +v -0.858203 1.611054 -2.113704 +v -0.822668 1.648288 -1.939851 +v -0.858203 1.611054 -2.113704 +v -0.986603 1.576527 -1.618798 +v -0.997021 1.584596 -1.616253 +v -1.063815 1.622534 -1.781703 +v -1.053274 1.614177 -1.783003 +v -1.106123 1.616215 -1.952191 +v -0.847644 1.419759 -1.325487 +v -0.921611 1.515204 -1.460242 +v -0.847644 1.419759 -1.325487 +v -0.921611 1.515204 -1.460242 +v -0.997021 1.584596 -1.616253 +v -0.554113 1.437948 -1.309679 +v -0.629196 1.536016 -1.445536 +v -0.554113 1.437948 -1.309679 +v -0.629196 1.536016 -1.445536 +v -0.704876 1.607513 -1.602188 +v -0.639536 1.543493 -1.441672 +v -0.715560 1.615614 -1.599758 +v -0.770855 1.646597 -1.767644 +v -0.781593 1.654979 -1.766412 +v -0.781593 1.654979 -1.766412 +v -0.770855 1.646597 -1.767644 +v -0.439511 1.197382 -1.123951 +v -0.489727 1.320749 -1.204804 +v -0.439511 1.197382 -1.123951 +v -0.489727 1.320749 -1.204804 +v -0.701093 1.073729 -1.077410 +v -0.701093 1.073729 -1.077410 +v -0.735556 1.184821 -1.141547 +v -0.735556 1.184821 -1.141547 +v -0.784667 1.305328 -1.221591 +v -0.784667 1.305328 -1.221591 +v -0.404674 1.083442 -1.059122 +v -0.404674 1.083442 -1.059122 +v -0.381742 0.872046 -1.020093 +v -0.371064 0.873342 -1.011574 +v -0.652399 0.878001 -0.975505 +v -0.662975 0.876706 -0.984047 +v -0.615149 -1.150617 -0.975930 +v -0.616963 -1.069731 -0.975247 +v -0.615149 -1.150617 -0.975930 +v -0.616963 -1.069731 -0.975247 +v -0.621140 -1.203376 -1.010859 +v -0.615754 -1.187864 -0.985509 +v -0.621140 -1.203376 -1.010859 +v -0.615754 -1.187864 -0.985509 +v -0.464087 -1.216531 -1.008434 +v -0.458235 -1.196528 -0.977219 +v -0.464087 -1.216531 -1.008434 +v -0.458235 -1.196528 -0.977219 +v -0.457495 -1.155366 -0.964894 +v -0.457495 -1.155366 -0.964894 +v -0.459153 -1.071257 -0.963088 +v -0.459153 -1.071257 -0.963088 +v -0.461203 -0.981183 -0.965590 +v -0.501451 -1.263062 -1.143765 +v -0.477786 -1.242368 -1.065022 +v -0.501451 -1.263062 -1.143765 +v -0.477786 -1.242368 -1.065022 +v -0.758607 -1.166549 -1.376016 +v -0.692570 -1.233023 -1.223029 +v -0.758607 -1.166549 -1.376016 +v -0.692570 -1.233023 -1.223029 +v -0.655923 -1.241525 -1.126869 +v -0.655923 -1.241525 -1.126869 +v -0.655923 -1.241525 -1.126869 +v -0.633738 -1.224462 -1.057856 +v -0.633738 -1.224462 -1.057856 +v -0.950747 -0.894230 -1.792663 +v -0.859245 -1.028858 -1.596262 +v -0.950747 -0.894230 -1.792663 +v -0.859245 -1.028858 -1.596262 +v -0.802505 -0.913158 -1.815561 +v -0.709842 -1.049527 -1.619695 +v -0.802505 -0.913158 -1.815561 +v -0.709842 -1.049527 -1.619695 +v -0.607330 -1.188889 -1.400656 +v -0.607330 -1.188889 -1.400656 +v -0.539645 -1.255860 -1.245961 +v -0.539645 -1.255860 -1.245961 +v -0.501451 -1.263062 -1.143765 +v -1.001529 -0.823804 -1.893781 +v -0.992027 -0.834448 -1.879454 +v -1.001529 -0.823804 -1.893781 +v -0.992027 -0.834448 -1.879454 +v -1.096320 -0.287798 -2.377383 +v -1.096320 -0.287798 -2.377383 +v -0.867240 -0.861896 -1.922366 +v -0.848012 -0.848280 -1.915496 +v -0.841410 -0.856382 -1.899761 +v -0.847715 -0.865152 -1.908850 +v -0.841410 -0.856382 -1.899761 +v -0.943835 -0.295764 -2.391903 +v -0.943835 -0.295764 -2.391903 +v -1.137862 -0.039986 -2.531857 +v -1.116663 -0.042009 -2.517685 +v -1.139093 -0.038652 -2.520063 +v -1.161578 -0.034458 -2.521799 +v -0.937298 -0.039696 -2.499090 +v -0.913242 -0.036291 -2.499870 +vt 0.993351 0.949236 +vt 0.996400 0.944893 +vt 0.993349 0.944456 +vt 0.867964 0.899716 +vt 0.867065 0.906499 +vt 0.870254 0.907732 +vt 0.871170 0.900850 +vt 0.866356 0.916212 +vt 0.869437 0.917526 +vt 0.871180 0.918227 +vt 0.872046 0.908465 +vt 0.872962 0.901601 +vt 0.996401 0.949674 +vt 0.998983 0.950111 +vt 0.998983 0.945329 +vt 0.998984 0.940538 +vt 0.996400 0.940104 +vt 0.993348 0.939669 +vt 0.920271 0.482551 +vt 0.919733 0.490885 +vt 0.921410 0.491051 +vt 0.921941 0.482745 +vt 0.919739 0.500274 +vt 0.921425 0.500402 +vt 0.923127 0.500522 +vt 0.923099 0.491217 +vt 0.923618 0.482940 +vt 0.861751 0.885628 +vt 0.860704 0.888722 +vt 0.865243 0.890300 +vt 0.866288 0.887205 +vt 0.859845 0.891432 +vt 0.864386 0.893012 +vt 0.868922 0.894589 +vt 0.869777 0.891876 +vt 0.870821 0.888780 +vt 0.993560 0.954480 +vt 0.993378 0.952614 +vt 0.990818 0.952306 +vt 0.991025 0.954119 +vt 0.990779 0.948939 +vt 0.995380 0.730151 +vt 0.995363 0.733534 +vt 0.997057 0.733545 +vt 0.997019 0.730202 +vt 0.995540 0.728315 +vt 0.996833 0.728665 +vt 0.858887 0.896553 +vt 0.859384 0.893290 +vt 0.856152 0.892185 +vt 0.855655 0.895443 +vt 0.856614 0.890330 +vt 0.854774 0.889840 +vt 0.854315 0.891685 +vt 0.853821 0.894930 +vt 0.578901 0.122665 +vt 0.579180 0.130433 +vt 0.582569 0.130154 +vt 0.582295 0.122364 +vt 0.579457 0.138561 +vt 0.582843 0.138304 +vt 0.584774 0.138224 +vt 0.584497 0.130032 +vt 0.584218 0.122203 +vt 0.996429 0.953052 +vt 0.999013 0.953488 +vt 0.996624 0.954915 +vt 0.999221 0.955349 +vt 0.863430 0.898136 +vt 0.862507 0.904662 +vt 0.857927 0.903303 +vt 0.856689 0.912804 +vt 0.861601 0.911486 +vt 0.825756 0.193804 +vt 0.830275 0.192138 +vt 0.829529 0.185823 +vt 0.825011 0.187496 +vt 0.834783 0.190478 +vt 0.834032 0.184156 +vt 0.833332 0.175120 +vt 0.828837 0.176797 +vt 0.824325 0.178482 +vt 0.923202 0.521752 +vt 0.920787 0.511185 +vt 0.920007 0.511351 +vt 0.922414 0.522012 +vt 0.918970 0.500342 +vt 0.536432 0.515339 +vt 0.532775 0.503394 +vt 0.532186 0.503465 +vt 0.535884 0.515543 +vt 0.543025 0.527475 +vt 0.542545 0.527808 +vt 0.923940 0.446718 +vt 0.925172 0.437049 +vt 0.924441 0.436710 +vt 0.923207 0.446413 +vt 0.926556 0.427909 +vt 0.925829 0.427540 +vt 0.560286 0.443939 +vt 0.568649 0.436260 +vt 0.568267 0.435786 +vt 0.559867 0.443497 +vt 0.552624 0.452301 +vt 0.552166 0.451901 +vt 0.828676 0.166154 +vt 0.824175 0.167854 +vt 0.833157 0.164463 +vt 0.833537 0.152450 +vt 0.829070 0.154160 +vt 0.824584 0.155881 +vt 0.930083 0.537678 +vt 0.929427 0.537563 +vt 0.929573 0.539349 +vt 0.930213 0.539340 +vt 0.899860 0.670908 +vt 0.901301 0.670133 +vt 0.898226 0.670091 +vt 0.898079 0.670743 +vt 0.896769 0.670116 +vt 0.896453 0.670584 +vt 0.929784 0.540981 +vt 0.930417 0.540999 +vt 0.836047 0.103430 +vt 0.835868 0.113974 +vt 0.839029 0.112678 +vt 0.839209 0.102103 +vt 0.835234 0.126140 +vt 0.838389 0.124878 +vt 0.840149 0.124089 +vt 0.840786 0.111840 +vt 0.840951 0.101219 +vt 0.829883 0.141069 +vt 0.825408 0.142817 +vt 0.834342 0.139332 +vt 0.830776 0.127910 +vt 0.826307 0.129691 +vt 0.821796 0.188707 +vt 0.822543 0.195011 +vt 0.821110 0.179697 +vt 0.819295 0.180469 +vt 0.819992 0.189505 +vt 0.820752 0.195827 +vt 0.569344 0.123516 +vt 0.569104 0.115698 +vt 0.565718 0.116013 +vt 0.565963 0.123820 +vt 0.569197 0.106941 +vt 0.565804 0.107258 +vt 0.563897 0.107375 +vt 0.563824 0.116170 +vt 0.564077 0.124000 +vt 0.870672 0.968521 +vt 0.869353 0.955046 +vt 0.868617 0.954930 +vt 0.869904 0.968482 +vt 0.868269 0.941324 +vt 0.867562 0.941130 +vt 0.678353 0.859383 +vt 0.691000 0.856113 +vt 0.690890 0.855531 +vt 0.678137 0.858835 +vt 0.666216 0.865155 +vt 0.665895 0.864663 +vt 0.871813 0.980566 +vt 0.873428 0.981017 +vt 0.872268 0.968992 +vt 0.872555 0.990748 +vt 0.874183 0.991181 +vt 0.875804 0.991596 +vt 0.875034 0.981449 +vt 0.873858 0.969443 +vt 0.855545 0.936710 +vt 0.856661 0.950360 +vt 0.857312 0.950701 +vt 0.856225 0.936966 +vt 0.857988 0.963748 +vt 0.858606 0.964184 +vt 0.574947 0.551445 +vt 0.562632 0.545539 +vt 0.562341 0.546046 +vt 0.574771 0.552000 +vt 0.587781 0.554867 +vt 0.587708 0.555450 +vt 0.831403 0.115783 +vt 0.826931 0.117599 +vt 0.831578 0.105273 +vt 0.827106 0.107122 +vt 0.574121 0.123091 +vt 0.574408 0.130835 +vt 0.569638 0.131237 +vt 0.569924 0.139310 +vt 0.574690 0.138936 +vt 0.581374 0.085981 +vt 0.576563 0.086418 +vt 0.574767 0.096349 +vt 0.579576 0.095893 +vt 0.571756 0.086855 +vt 0.569963 0.096806 +vt 0.573992 0.106481 +vt 0.578791 0.106020 +vt 0.872984 0.893013 +vt 0.874026 0.889920 +vt 0.872129 0.895725 +vt 0.873914 0.896497 +vt 0.874762 0.893799 +vt 0.875798 0.890719 +vt 0.804137 0.588176 +vt 0.804828 0.588300 +vt 0.804953 0.586532 +vt 0.804265 0.586532 +vt 0.805529 0.589745 +vt 0.805607 0.586682 +vt 0.805614 0.585229 +vt 0.805139 0.584912 +vt 0.804471 0.584886 +vt 0.859838 0.985783 +vt 0.859108 0.975695 +vt 0.857578 0.974956 +vt 0.858327 0.985003 +vt 0.856439 0.963058 +vt 0.854886 0.962334 +vt 0.856040 0.974188 +vt 0.856810 0.984196 +vt 0.820966 0.169076 +vt 0.821383 0.157112 +vt 0.819565 0.157815 +vt 0.819147 0.169816 +vt 0.874908 0.887460 +vt 0.871720 0.886314 +vt 0.876610 0.888274 +vt 0.562368 0.042915 +vt 0.562507 0.041052 +vt 0.561051 0.041156 +vt 0.560596 0.042653 +vt 0.561880 0.046267 +vt 0.560054 0.045954 +vt 0.867621 0.928504 +vt 0.866847 0.928498 +vt 0.865116 0.918814 +vt 0.702848 0.855537 +vt 0.711670 0.856215 +vt 0.711363 0.855544 +vt 0.702757 0.854925 +vt 0.911495 0.668032 +vt 0.906401 0.668349 +vt 0.906393 0.669037 +vt 0.911230 0.668833 +vt 0.901317 0.668451 +vt 0.901556 0.669240 +vt 0.906381 0.669798 +vt 0.911478 0.669698 +vt 0.570462 0.156988 +vt 0.570197 0.147972 +vt 0.566822 0.148230 +vt 0.567083 0.157225 +vt 0.566550 0.139585 +vt 0.564676 0.139805 +vt 0.564946 0.148466 +vt 0.565203 0.157479 +vt 0.913249 0.664297 +vt 0.913428 0.658190 +vt 0.912692 0.657893 +vt 0.912512 0.664006 +vt 0.913668 0.649977 +vt 0.912934 0.649665 +vt 0.701457 0.991720 +vt 0.692002 0.986249 +vt 0.691694 0.986761 +vt 0.701162 0.992240 +vt 0.708482 0.995785 +vt 0.708190 0.996305 +vt 0.580002 0.156369 +vt 0.575231 0.156679 +vt 0.575507 0.165717 +vt 0.580280 0.165439 +vt 0.570734 0.165994 +vt 0.571056 0.174595 +vt 0.575830 0.174331 +vt 0.580604 0.174067 +vt 0.988955 0.467127 +vt 0.989731 0.466830 +vt 0.988003 0.453670 +vt 0.987196 0.453866 +vt 0.911462 0.578978 +vt 0.909728 0.579246 +vt 0.909725 0.591886 +vt 0.911437 0.591695 +vt 0.910239 0.607119 +vt 0.911924 0.607017 +vt 0.987003 0.437958 +vt 0.986168 0.438029 +vt 0.910600 0.570710 +vt 0.905827 0.570527 +vt 0.905827 0.571236 +vt 0.910635 0.571410 +vt 0.901056 0.570344 +vt 0.901022 0.571035 +vt 0.900742 0.571692 +vt 0.905827 0.571992 +vt 0.910926 0.572095 +vt 0.823746 0.118879 +vt 0.823120 0.130952 +vt 0.823924 0.108418 +vt 0.822094 0.109013 +vt 0.821925 0.119494 +vt 0.821304 0.131586 +vt 0.855180 0.924062 +vt 0.853475 0.923427 +vt 0.853963 0.936127 +vt 0.853806 0.912022 +vt 0.852073 0.911498 +vt 0.851870 0.922881 +vt 0.852392 0.935527 +vt 0.389821 0.168090 +vt 0.390779 0.167546 +vt 0.390064 0.166373 +vt 0.389197 0.166855 +vt 0.971524 0.933939 +vt 0.970034 0.933213 +vt 0.969955 0.934618 +vt 0.971407 0.935323 +vt 0.969912 0.942753 +vt 0.971363 0.943453 +vt 0.386161 0.159478 +vt 0.385350 0.159887 +vt 0.496028 0.110966 +vt 0.495238 0.110640 +vt 0.493235 0.123960 +vt 0.494058 0.124186 +vt 0.912063 0.677196 +vt 0.910311 0.676874 +vt 0.910197 0.689260 +vt 0.911927 0.689508 +vt 0.909599 0.704385 +vt 0.911302 0.704548 +vt 0.491981 0.139920 +vt 0.492834 0.140022 +vt 0.906373 0.676917 +vt 0.906285 0.689348 +vt 0.902457 0.677244 +vt 0.902391 0.689676 +vt 0.901842 0.704805 +vt 0.905718 0.704505 +vt 0.905793 0.579198 +vt 0.905819 0.591795 +vt 0.901869 0.578908 +vt 0.901915 0.591510 +vt 0.902481 0.606742 +vt 0.906365 0.606996 +vt 0.956097 0.524014 +vt 0.960169 0.520322 +vt 0.959923 0.501167 +vt 0.956200 0.502603 +vt 0.964357 0.520946 +vt 0.963731 0.500115 +vt 0.963536 0.479244 +vt 0.959700 0.480280 +vt 0.955961 0.481475 +vt 0.027044 0.093768 +vt 0.026046 0.093188 +vt 0.025577 0.094431 +vt 0.026441 0.094991 +vt 0.024993 0.092737 +vt 0.024889 0.093781 +vt 0.022224 0.099148 +vt 0.021929 0.101333 +vt 0.022626 0.101989 +vt 0.430450 0.181220 +vt 0.429867 0.176851 +vt 0.429214 0.176886 +vt 0.429608 0.180707 +vt 0.430073 0.172324 +vt 0.429252 0.172915 +vt 0.540492 0.779556 +vt 0.540498 0.783538 +vt 0.541404 0.783418 +vt 0.541366 0.779495 +vt 0.540598 0.775703 +vt 0.541460 0.775712 +vt 0.966384 0.931730 +vt 0.966397 0.933170 +vt 0.962646 0.930310 +vt 0.962753 0.931780 +vt 0.962677 0.940008 +vt 0.966340 0.941346 +vt 0.367681 0.126573 +vt 0.368531 0.126435 +vt 0.364545 0.114466 +vt 0.363692 0.114425 +vt 0.971215 0.981723 +vt 0.969754 0.980927 +vt 0.970055 0.993220 +vt 0.971524 0.994104 +vt 0.974036 0.178457 +vt 0.975816 0.177965 +vt 0.973013 0.173910 +vt 0.971196 0.174278 +vt 0.364523 0.107013 +vt 0.363732 0.106775 +vt 0.966147 0.959735 +vt 0.969776 0.961076 +vt 0.962409 0.958513 +vt 0.962254 0.978552 +vt 0.966067 0.979642 +vt 0.377386 0.143870 +vt 0.376568 0.144162 +vt 0.971232 0.961808 +vt 0.013119 0.117393 +vt 0.013906 0.117762 +vt 0.955006 0.522292 +vt 0.954725 0.503042 +vt 0.954440 0.482188 +vt 0.004237 0.135219 +vt 0.005085 0.135377 +vt 0.001163 0.154915 +vt 0.000374 0.155132 +vt 0.002359 0.160578 +vt 0.003001 0.160148 +vt 0.910758 0.007145 +vt 0.908959 0.006842 +vt 0.907954 0.011936 +vt 0.909757 0.012033 +vt 0.907544 0.016189 +vt 0.909341 0.016062 +vt 0.004584 0.164304 +vt 0.005039 0.163683 +vt 0.000277 0.147491 +vt 0.001129 0.147472 +vt 0.956024 0.468193 +vt 0.954498 0.468999 +vt 0.956326 0.461275 +vt 0.954800 0.462188 +vt 0.959792 0.467012 +vt 0.963664 0.466073 +vt 0.963963 0.459132 +vt 0.960093 0.460047 +vt 0.966341 0.991946 +vt 0.962496 0.990943 +vt 0.963017 0.997003 +vt 0.966857 0.997986 +vt 0.970574 0.999305 +vt 0.903557 0.016476 +vt 0.903503 0.019297 +vt 0.907485 0.018920 +vt 0.899613 0.016762 +vt 0.899555 0.019557 +vt 0.899835 0.022586 +vt 0.903789 0.022365 +vt 0.907767 0.021939 +vt 0.904969 0.006858 +vt 0.903963 0.012082 +vt 0.901022 0.007133 +vt 0.900020 0.012363 +vt 0.976959 0.173810 +vt 0.975458 0.169667 +vt 0.971496 0.169639 +vt 0.980828 0.173979 +vt 0.979330 0.169841 +vt 0.978571 0.166552 +vt 0.974689 0.166375 +vt 0.970713 0.166208 +vt 0.366252 0.101603 +vt 0.365609 0.101152 +vt 0.969655 0.169802 +vt 0.968864 0.166150 +vt 0.368146 0.097888 +vt 0.367690 0.097247 +vt 0.372154 0.094622 +vt 0.372281 0.095479 +vt 0.378243 0.095983 +vt 0.378239 0.095096 +vt 0.968877 0.161363 +vt 0.970711 0.161725 +vt 0.971591 0.157115 +vt 0.969764 0.156665 +vt 0.972570 0.152225 +vt 0.970748 0.151723 +vt 0.384699 0.096794 +vt 0.384775 0.095902 +vt 0.974405 0.164460 +vt 0.970427 0.164205 +vt 0.978295 0.164612 +vt 0.978583 0.162141 +vt 0.974687 0.162029 +vt 0.369471 0.095955 +vt 0.369192 0.095177 +vt 0.968582 0.163971 +vt 0.006242 0.166349 +vt 0.006520 0.165593 +vt 0.909268 0.018617 +vt 0.909538 0.021509 +vt 0.009353 0.166965 +vt 0.009479 0.166129 +vt 0.976545 0.152578 +vt 0.977128 0.149547 +vt 0.973320 0.149219 +vt 0.980449 0.152642 +vt 0.980863 0.149618 +vt 0.980240 0.148342 +vt 0.977332 0.148069 +vt 0.974330 0.148029 +vt 0.015562 0.166531 +vt 0.015565 0.165666 +vt 0.908371 0.026837 +vt 0.910134 0.026320 +vt 0.908996 0.031829 +vt 0.910758 0.031261 +vt 0.022182 0.165740 +vt 0.022104 0.164870 +vt 0.904393 0.027293 +vt 0.900435 0.027485 +vt 0.901057 0.032478 +vt 0.905018 0.032304 +vt 0.975565 0.157450 +vt 0.979466 0.157531 +vt 0.308480 0.424486 +vt 0.304589 0.422895 +vt 0.304323 0.423732 +vt 0.308156 0.425304 +vt 0.301237 0.421558 +vt 0.301030 0.422415 +vt 0.300896 0.423038 +vt 0.304145 0.424341 +vt 0.307937 0.425899 +vt 0.192134 0.550873 +vt 0.188231 0.552432 +vt 0.188484 0.553262 +vt 0.192444 0.551685 +vt 0.184866 0.553739 +vt 0.185059 0.554587 +vt 0.185151 0.555168 +vt 0.188621 0.553829 +vt 0.192623 0.552239 +vt 0.179260 0.554459 +vt 0.179136 0.553583 +vt 0.172218 0.553247 +vt 0.172252 0.554124 +vt 0.178993 0.552887 +vt 0.172141 0.552548 +vt 0.162622 0.551721 +vt 0.162610 0.552416 +vt 0.162523 0.553285 +vt 0.279001 0.421719 +vt 0.278920 0.420847 +vt 0.267921 0.422373 +vt 0.268132 0.423218 +vt 0.871887 0.918629 +vt 0.870927 0.929661 +vt 0.871647 0.929967 +vt 0.871396 0.942385 +vt 0.872124 0.942582 +vt 0.256496 0.425767 +vt 0.256844 0.426557 +vt 0.295655 0.420774 +vt 0.295785 0.419901 +vt 0.288716 0.420141 +vt 0.288677 0.421017 +vt 0.873625 0.902143 +vt 0.872731 0.908949 +vt 0.151794 0.550774 +vt 0.151575 0.551613 +vt 0.151900 0.550098 +vt 0.818453 0.170200 +vt 0.818862 0.158092 +vt 0.140552 0.547311 +vt 0.140196 0.548093 +vt 0.118975 0.533409 +vt 0.119585 0.532809 +vt 0.111483 0.522862 +vt 0.110799 0.523377 +vt 0.820583 0.131641 +vt 0.821184 0.119480 +vt 0.821319 0.108931 +vt 0.105693 0.511458 +vt 0.104959 0.511835 +vt 0.129539 0.541174 +vt 0.129044 0.541867 +vt 0.820400 0.144726 +vt 0.819690 0.144884 +vt 0.245289 0.431914 +vt 0.245777 0.432616 +vt 0.872505 0.956030 +vt 0.873241 0.956110 +vt 0.874609 0.969421 +vt 0.235158 0.440337 +vt 0.235764 0.440945 +vt 0.226912 0.450384 +vt 0.227595 0.450904 +vt 0.875808 0.981361 +vt 0.876610 0.991447 +vt 0.220965 0.462045 +vt 0.221702 0.462422 +vt 0.102531 0.498991 +vt 0.101751 0.499130 +vt 0.106171 0.511098 +vt 0.103041 0.498802 +vt 0.585594 0.094839 +vt 0.584896 0.095233 +vt 0.584108 0.105430 +vt 0.584828 0.105194 +vt 0.102060 0.487440 +vt 0.101257 0.487335 +vt 0.217598 0.474999 +vt 0.218387 0.475133 +vt 0.220452 0.461722 +vt 0.217050 0.474850 +vt 0.216399 0.487068 +vt 0.216966 0.487033 +vt 0.217786 0.486919 +vt 0.132172 0.444304 +vt 0.132646 0.444983 +vt 0.141801 0.438994 +vt 0.141416 0.438248 +vt 0.586101 0.156446 +vt 0.585319 0.156176 +vt 0.585597 0.165314 +vt 0.586375 0.165660 +vt 0.585920 0.173982 +vt 0.586695 0.174385 +vt 0.151543 0.433806 +vt 0.151227 0.433011 +vt 0.106652 0.470874 +vt 0.107398 0.471236 +vt 0.111193 0.464269 +vt 0.110493 0.463819 +vt 0.584976 0.122160 +vt 0.585272 0.130067 +vt 0.585560 0.138336 +vt 0.116361 0.457522 +vt 0.115719 0.456989 +vt 0.223101 0.503215 +vt 0.222334 0.503588 +vt 0.226207 0.510624 +vt 0.226929 0.510162 +vt 0.945455 0.491185 +vt 0.946140 0.491229 +vt 0.946398 0.483135 +vt 0.945699 0.483168 +vt 0.946777 0.474640 +vt 0.946067 0.474750 +vt 0.231498 0.517417 +vt 0.232161 0.516871 +vt 0.248714 0.529260 +vt 0.248222 0.529948 +vt 0.257611 0.535934 +vt 0.258012 0.535181 +vt 0.247884 0.530435 +vt 0.257338 0.536474 +vt 0.267272 0.541789 +vt 0.267495 0.541210 +vt 0.267826 0.540408 +vt 0.196255 0.420209 +vt 0.196493 0.421032 +vt 0.197279 0.420812 +vt 0.197048 0.419992 +vt 0.916644 0.570378 +vt 0.915898 0.570733 +vt 0.915828 0.571385 +vt 0.916544 0.571056 +vt 0.931510 0.541575 +vt 0.931990 0.540841 +vt 0.931557 0.540501 +vt 0.931084 0.540875 +vt 0.930847 0.541728 +vt 0.312354 0.554425 +vt 0.312099 0.555257 +vt 0.312895 0.555474 +vt 0.313152 0.554648 +vt 0.917235 0.668577 +vt 0.916474 0.668168 +vt 0.916387 0.668793 +vt 0.917119 0.669200 +vt 0.916041 0.669296 +vt 0.916411 0.669731 +vt 0.313565 0.555599 +vt 0.313841 0.554792 +vt 0.900167 0.650261 +vt 0.900392 0.641526 +vt 0.898733 0.641719 +vt 0.898511 0.650460 +vt 0.928187 0.419663 +vt 0.928208 0.428201 +vt 0.929836 0.419973 +vt 0.929859 0.428532 +vt 0.931483 0.420322 +vt 0.897077 0.641949 +vt 0.896860 0.650701 +vt 0.855094 0.949726 +vt 0.853532 0.949061 +vt 0.949424 0.491443 +vt 0.949689 0.483267 +vt 0.948044 0.483200 +vt 0.947779 0.491337 +vt 0.950073 0.474690 +vt 0.948426 0.474662 +vt 0.835176 0.193442 +vt 0.838369 0.192294 +vt 0.837973 0.189326 +vt 0.835511 0.195039 +vt 0.838706 0.193892 +vt 0.840534 0.193402 +vt 0.840192 0.191795 +vt 0.839789 0.188816 +vt 0.914546 0.668710 +vt 0.914634 0.668049 +vt 0.914565 0.669394 +vt 0.996427 0.936694 +vt 0.993374 0.936262 +vt 0.999014 0.937124 +vt 0.999221 0.935162 +vt 0.996620 0.934736 +vt 0.993553 0.934307 +vt 0.870929 0.955545 +vt 0.869829 0.941854 +vt 0.901051 0.550778 +vt 0.901067 0.541399 +vt 0.897679 0.541335 +vt 0.897666 0.550686 +vt 0.901191 0.532662 +vt 0.897801 0.532610 +vt 0.895891 0.532420 +vt 0.895771 0.541144 +vt 0.895763 0.550484 +vt 0.195671 0.550337 +vt 0.195353 0.549531 +vt 0.195816 0.550887 +vt 0.558975 0.061542 +vt 0.559535 0.060939 +vt 0.558181 0.060359 +vt 0.557476 0.060577 +vt 0.197634 0.549413 +vt 0.197382 0.548591 +vt 0.837491 0.138103 +vt 0.836688 0.151249 +vt 0.838449 0.150586 +vt 0.839251 0.137376 +vt 0.922484 0.511261 +vt 0.924908 0.521776 +vt 0.926636 0.521755 +vt 0.924200 0.511311 +vt 0.913981 0.571485 +vt 0.913985 0.570817 +vt 0.932160 0.535646 +vt 0.931470 0.535933 +vt 0.931551 0.539024 +vt 0.932160 0.538989 +vt 0.822216 0.144061 +vt 0.954238 0.530416 +vt 0.951294 0.519925 +vt 0.949646 0.519687 +vt 0.952590 0.530139 +vt 0.949724 0.509067 +vt 0.948080 0.508876 +vt 0.946450 0.508670 +vt 0.948015 0.519413 +vt 0.950959 0.529807 +vt 0.857475 0.887622 +vt 0.858524 0.884532 +vt 0.856672 0.884072 +vt 0.855629 0.887148 +vt 0.566558 0.097111 +vt 0.568346 0.087137 +vt 0.566408 0.087119 +vt 0.564633 0.097161 +vt 0.583669 0.165265 +vt 0.583389 0.156169 +vt 0.583993 0.173906 +vt 0.869327 0.929067 +vt 0.582987 0.095549 +vt 0.584790 0.085642 +vt 0.582195 0.105683 +vt 0.586695 0.085272 +vt 0.922757 0.456412 +vt 0.924413 0.456667 +vt 0.925595 0.446987 +vt 0.921719 0.465706 +vt 0.923378 0.465944 +vt 0.925035 0.466188 +vt 0.926067 0.456935 +vt 0.927248 0.447277 +vt 0.836317 0.163282 +vt 0.836504 0.173952 +vt 0.838289 0.173385 +vt 0.838087 0.162672 +vt 0.951350 0.455798 +vt 0.952096 0.446168 +vt 0.950451 0.446247 +vt 0.949704 0.455846 +vt 0.953021 0.437007 +vt 0.951375 0.437108 +vt 0.949729 0.437248 +vt 0.948804 0.446358 +vt 0.948055 0.455914 +vt 0.837215 0.182998 +vt 0.839017 0.182465 +vt 0.301450 0.420699 +vt 0.299234 0.420023 +vt 0.299058 0.420892 +vt 0.301627 0.420054 +vt 0.299384 0.419372 +vt 0.874109 0.898917 +vt 0.873458 0.898347 +vt 0.184657 0.552875 +vt 0.182507 0.553510 +vt 0.182678 0.554383 +vt 0.184452 0.552188 +vt 0.182329 0.552817 +vt 0.826481 0.198355 +vt 0.826146 0.196762 +vt 0.822935 0.197967 +vt 0.823272 0.199561 +vt 0.821150 0.198793 +vt 0.821493 0.200393 +vt 0.831001 0.196695 +vt 0.830666 0.195099 +vt 0.863927 0.894871 +vt 0.868462 0.896448 +vt 0.854730 0.902302 +vt 0.852914 0.901771 +vt 0.871669 0.897583 +vt 0.558287 0.045609 +vt 0.557578 0.050357 +vt 0.558257 0.050497 +vt 0.558966 0.045749 +vt 0.556868 0.055109 +vt 0.557547 0.055249 +vt 0.558634 0.055452 +vt 0.559344 0.050701 +vt 0.559554 0.042416 +vt 0.558883 0.042264 +vt 0.560447 0.040689 +vt 0.559820 0.040487 +vt 0.998892 0.743247 +vt 0.998144 0.743190 +vt 0.998067 0.746593 +vt 0.998808 0.746662 +vt 0.997059 0.743155 +vt 0.997022 0.746518 +vt 0.996837 0.748091 +vt 0.997508 0.748469 +vt 0.998214 0.748594 +vt 0.867188 0.884739 +vt 0.862651 0.883163 +vt 0.561170 0.051014 +vt 0.560460 0.055765 +vt 0.990777 0.944159 +vt 0.990776 0.939373 +vt 0.995364 0.738336 +vt 0.995365 0.743144 +vt 0.997057 0.738347 +vt 0.562039 0.061385 +vt 0.562507 0.059520 +vt 0.559946 0.059123 +vt 0.859433 0.882083 +vt 0.558185 0.058780 +vt 0.311339 0.426643 +vt 0.311701 0.425845 +vt 0.311063 0.427193 +vt 0.312787 0.427792 +vt 0.313377 0.427492 +vt 0.313803 0.426737 +vt 0.990812 0.935983 +vt 0.991018 0.934092 +vt 0.995384 0.746549 +vt 0.995544 0.748435 +vt 0.528525 0.775538 +vt 0.528274 0.779493 +vt 0.528925 0.779354 +vt 0.529160 0.775571 +vt 0.528847 0.783476 +vt 0.529468 0.783167 +vt 0.530012 0.782268 +vt 0.529778 0.779270 +vt 0.529770 0.776316 +vt 0.388706 0.097333 +vt 0.388826 0.096448 +vt 0.971576 0.148688 +vt 0.973478 0.147410 +vt 0.390543 0.097632 +vt 0.390719 0.096772 +vt 0.026241 0.165198 +vt 0.026144 0.164331 +vt 0.533904 0.785158 +vt 0.534291 0.783318 +vt 0.531267 0.783100 +vt 0.530881 0.784869 +vt 0.027998 0.164891 +vt 0.027948 0.164030 +vt 0.534291 0.779315 +vt 0.531245 0.779267 +vt 0.901585 0.035451 +vt 0.905379 0.035309 +vt 0.530959 0.775505 +vt 0.497737 0.407540 +vt 0.497797 0.412082 +vt 0.498133 0.412061 +vt 0.498141 0.407757 +vt 0.497852 0.416490 +vt 0.498147 0.416312 +vt 0.654186 0.011277 +vt 0.654840 0.007059 +vt 0.654617 0.006667 +vt 0.653892 0.011254 +vt 0.654207 0.015591 +vt 0.653941 0.015943 +vt 0.656188 0.017602 +vt 0.655072 0.017293 +vt 0.655015 0.017524 +vt 0.656232 0.017942 +vt 0.497925 0.406110 +vt 0.498177 0.405877 +vt 0.654871 0.018119 +vt 0.656301 0.018607 +vt 0.495620 0.161306 +vt 0.494683 0.161407 +vt 0.495353 0.164815 +vt 0.496460 0.164643 +vt 0.908839 0.725914 +vt 0.907129 0.725834 +vt 0.906848 0.729282 +vt 0.908660 0.729372 +vt 0.509932 0.002863 +vt 0.510899 0.004584 +vt 0.511423 0.004206 +vt 0.510210 0.002329 +vt 0.495198 0.165450 +vt 0.496592 0.165208 +vt 0.913066 0.627896 +vt 0.909106 0.627830 +vt 0.909712 0.631059 +vt 0.913929 0.631069 +vt 0.905109 0.627736 +vt 0.905448 0.631045 +vt 0.507065 0.009369 +vt 0.507041 0.005117 +vt 0.506525 0.004841 +vt 0.506495 0.009529 +vt 0.507671 0.013537 +vt 0.507208 0.014115 +vt 0.541567 0.785047 +vt 0.542857 0.785043 +vt 0.542590 0.783419 +vt 0.453056 0.774596 +vt 0.453217 0.775827 +vt 0.454676 0.775789 +vt 0.454432 0.774558 +vt 0.456540 0.775745 +vt 0.456182 0.774506 +vt 0.544484 0.785045 +vt 0.544094 0.783435 +vt 0.955104 0.530666 +vt 0.955023 0.530717 +vt 0.956428 0.529418 +vt 0.023952 0.092839 +vt 0.024289 0.093360 +vt 0.540905 0.774508 +vt 0.541648 0.774453 +vt 0.453307 0.783296 +vt 0.452778 0.785129 +vt 0.453593 0.785165 +vt 0.453609 0.783513 +vt 0.430450 0.170794 +vt 0.429716 0.171258 +vt 0.965389 0.526723 +vt 0.963722 0.526586 +vt 0.964954 0.526844 +vt 0.687106 0.243891 +vt 0.686624 0.245015 +vt 0.687209 0.245302 +vt 0.687788 0.243973 +vt 0.540762 0.785164 +vt 0.960102 0.527588 +vt 0.686704 0.248769 +vt 0.687227 0.252814 +vt 0.687788 0.252983 +vt 0.687238 0.249101 +vt 0.456815 0.779514 +vt 0.459055 0.779492 +vt 0.458749 0.775723 +vt 0.456870 0.783434 +vt 0.459078 0.783411 +vt 0.461821 0.783406 +vt 0.461821 0.779487 +vt 0.461467 0.775718 +vt 0.453447 0.779591 +vt 0.454919 0.779553 +vt 0.455029 0.783476 +vt 0.542499 0.779499 +vt 0.542612 0.775713 +vt 0.543949 0.779520 +vt 0.544096 0.775729 +vt 0.454919 0.785129 +vt 0.542888 0.774449 +vt 0.544486 0.774450 +vt 0.456639 0.785079 +vt 0.741576 0.007166 +vt 0.737830 0.007641 +vt 0.737824 0.010933 +vt 0.741568 0.010543 +vt 0.733912 0.007670 +vt 0.733906 0.011032 +vt 0.733952 0.014729 +vt 0.737868 0.014569 +vt 0.741611 0.014252 +vt 0.545778 0.779505 +vt 0.545954 0.775711 +vt 0.545953 0.783417 +vt 0.737858 0.005148 +vt 0.733939 0.005140 +vt 0.741605 0.004631 +vt 0.458764 0.785052 +vt 0.546424 0.774426 +vt 0.742813 0.003826 +vt 0.742782 0.006469 +vt 0.461416 0.785047 +vt 0.546424 0.785020 +vt 0.458308 0.774480 +vt 0.411693 0.004286 +vt 0.410357 0.003588 +vt 0.410334 0.006231 +vt 0.411670 0.006825 +vt 0.732273 0.004542 +vt 0.732245 0.007176 +vt 0.732284 0.014615 +vt 0.732614 0.017973 +vt 0.734214 0.018019 +vt 0.411693 0.014065 +vt 0.410364 0.013849 +vt 0.410246 0.017184 +vt 0.411523 0.017399 +vt 0.409464 0.019088 +vt 0.410019 0.019615 +vt 0.734259 0.020065 +vt 0.735047 0.019822 +vt 0.402632 0.006393 +vt 0.401079 0.007063 +vt 0.401075 0.010540 +vt 0.402632 0.010071 +vt 0.742772 0.010057 +vt 0.742813 0.013946 +vt 0.401099 0.014336 +vt 0.402659 0.014037 +vt 0.732239 0.010744 +vt 0.410335 0.009895 +vt 0.411667 0.010284 +vt 0.406524 0.006075 +vt 0.406526 0.009821 +vt 0.406555 0.013847 +vt 0.214648 0.309053 +vt 0.214485 0.311909 +vt 0.215329 0.312050 +vt 0.215329 0.308539 +vt 0.214508 0.314831 +vt 0.215156 0.315583 +vt 0.406515 0.020445 +vt 0.406601 0.019459 +vt 0.402974 0.019790 +vt 0.403685 0.019227 +vt 0.406601 0.017224 +vt 0.402871 0.017363 +vt 0.737965 0.017892 +vt 0.741544 0.017561 +vt 0.737976 0.020039 +vt 0.740790 0.019459 +vt 0.401374 0.017657 +vt 0.742698 0.017332 +vt 0.741260 0.019615 +vt 0.988086 0.425176 +vt 0.987231 0.425135 +vt 0.911593 0.619761 +vt 0.913258 0.619724 +vt 0.914753 0.627893 +vt 0.989906 0.417096 +vt 0.988980 0.416963 +vt 0.492969 0.153013 +vt 0.493841 0.153003 +vt 0.908311 0.717294 +vt 0.909996 0.717398 +vt 0.904436 0.717397 +vt 0.900552 0.717622 +vt 0.899184 0.726022 +vt 0.903167 0.725886 +vt 0.907724 0.619652 +vt 0.903832 0.619469 +vt 0.659857 0.007338 +vt 0.659834 0.012034 +vt 0.660632 0.012108 +vt 0.660632 0.006843 +vt 0.659036 0.016629 +vt 0.659664 0.017250 +vt 0.243025 0.012076 +vt 0.243071 0.006909 +vt 0.241104 0.006659 +vt 0.241107 0.012302 +vt 0.243071 0.017341 +vt 0.241208 0.018052 +vt 0.657424 0.004681 +vt 0.658918 0.005163 +vt 0.659441 0.004397 +vt 0.657564 0.003843 +vt 0.243203 0.019757 +vt 0.241369 0.020687 +vt 0.977991 0.077419 +vt 0.976078 0.077429 +vt 0.975741 0.079226 +vt 0.977982 0.079234 +vt 0.509904 0.016059 +vt 0.508428 0.015986 +vt 0.508126 0.016849 +vt 0.510023 0.016899 +vt 0.506583 0.014777 +vt 0.231005 0.006621 +vt 0.230926 0.008794 +vt 0.232659 0.008012 +vt 0.232740 0.005654 +vt 0.173487 0.003789 +vt 0.171605 0.003810 +vt 0.171234 0.005611 +vt 0.173456 0.005614 +vt 0.512197 0.008746 +vt 0.513037 0.008684 +vt 0.512084 0.003629 +vt 0.512227 0.013389 +vt 0.513037 0.013866 +vt 0.954753 0.152515 +vt 0.954883 0.157715 +vt 0.956718 0.158401 +vt 0.956667 0.152727 +vt 0.954699 0.147351 +vt 0.956688 0.147099 +vt 0.902641 0.729274 +vt 0.898406 0.729334 +vt 0.511530 0.008730 +vt 0.511580 0.012960 +vt 0.990898 0.413966 +vt 0.989783 0.413754 +vt 0.915711 0.631073 +vt 0.508641 0.015255 +vt 0.509789 0.015348 +vt 0.657108 0.005727 +vt 0.658197 0.006119 +vt 0.658465 0.005723 +vt 0.657224 0.005297 +vt 0.658878 0.007959 +vt 0.659243 0.007688 +vt 0.658851 0.011957 +vt 0.659219 0.011948 +vt 0.658250 0.015879 +vt 0.658545 0.016123 +vt 0.232640 0.013690 +vt 0.236851 0.012980 +vt 0.236839 0.007148 +vt 0.232675 0.019457 +vt 0.236945 0.018915 +vt 0.961073 0.153321 +vt 0.961138 0.147518 +vt 0.961060 0.159180 +vt 0.965461 0.159635 +vt 0.965493 0.153931 +vt 0.965555 0.148292 +vt 0.978032 0.087967 +vt 0.980179 0.088074 +vt 0.980329 0.083632 +vt 0.978007 0.083563 +vt 0.956786 0.144670 +vt 0.961232 0.145031 +vt 0.965620 0.145892 +vt 0.980230 0.079260 +vt 0.171059 0.009860 +vt 0.173370 0.009902 +vt 0.236936 0.004734 +vt 0.241221 0.004327 +vt 0.171128 0.014160 +vt 0.173281 0.014236 +vt 0.505729 0.009650 +vt 0.505828 0.004398 +vt 0.230844 0.014004 +vt 0.230792 0.019286 +vt 0.508788 0.002216 +vt 0.510552 0.001548 +vt 0.508742 0.001436 +vt 0.954771 0.145117 +vt 0.978033 0.089986 +vt 0.979831 0.090102 +vt 0.654499 0.018871 +vt 0.656279 0.019435 +vt 0.653322 0.016423 +vt 0.967482 0.161799 +vt 0.967463 0.159428 +vt 0.965477 0.162217 +vt 0.173246 0.016192 +vt 0.175075 0.016248 +vt 0.175451 0.014285 +vt 0.653211 0.011171 +vt 0.654068 0.006041 +vt 0.967454 0.154192 +vt 0.967459 0.149017 +vt 0.905822 0.573456 +vt 0.909890 0.573496 +vt 0.901767 0.573168 +vt 0.906376 0.671258 +vt 0.910448 0.671235 +vt 0.902331 0.671589 +vt 0.497183 0.103600 +vt 0.496412 0.103181 +vt 0.496232 0.104577 +vt 0.497006 0.104955 +vt 0.912996 0.670344 +vt 0.912200 0.671616 +vt 0.990112 0.474369 +vt 0.990898 0.474035 +vt 0.990615 0.472803 +vt 0.989848 0.473140 +vt 0.912429 0.571966 +vt 0.911626 0.573209 +vt 0.910601 0.566700 +vt 0.910600 0.569759 +vt 0.913985 0.569863 +vt 0.913986 0.566794 +vt 0.915898 0.569777 +vt 0.915898 0.566702 +vt 0.806225 0.590039 +vt 0.806225 0.586707 +vt 0.897678 0.570191 +vt 0.897684 0.570849 +vt 0.895786 0.569960 +vt 0.895859 0.570606 +vt 0.806054 0.584890 +vt 0.912998 0.667085 +vt 0.914797 0.667175 +vt 0.914911 0.664395 +vt 0.916499 0.667306 +vt 0.916581 0.664533 +vt 0.898243 0.669397 +vt 0.898186 0.668730 +vt 0.896373 0.669001 +vt 0.896429 0.669635 +vt 0.307710 0.553080 +vt 0.307450 0.553911 +vt 0.310996 0.554938 +vt 0.311252 0.554106 +vt 0.307291 0.554490 +vt 0.310841 0.555514 +vt 0.311945 0.555833 +vt 0.191553 0.421412 +vt 0.191796 0.422235 +vt 0.195379 0.421318 +vt 0.195140 0.420495 +vt 0.916641 0.566340 +vt 0.916643 0.569420 +vt 0.905827 0.566535 +vt 0.905827 0.569580 +vt 0.901055 0.566369 +vt 0.901055 0.569401 +vt 0.906393 0.667805 +vt 0.902335 0.667854 +vt 0.910458 0.667521 +vt 0.408645 0.323497 +vt 0.408748 0.319442 +vt 0.408294 0.319579 +vt 0.408199 0.323514 +vt 0.408748 0.327556 +vt 0.408294 0.327452 +vt 0.861250 0.914320 +vt 0.857411 0.916077 +vt 0.070191 0.078223 +vt 0.071032 0.081322 +vt 0.071745 0.081112 +vt 0.070925 0.078135 +vt 0.071033 0.073146 +vt 0.071745 0.073179 +vt 0.910751 0.532736 +vt 0.905971 0.532699 +vt 0.905845 0.541456 +vt 0.910623 0.541513 +vt 0.905827 0.550874 +vt 0.910604 0.550970 +vt 0.162237 0.429959 +vt 0.161957 0.429143 +vt 0.151725 0.434344 +vt 0.162391 0.430510 +vt 0.916644 0.540986 +vt 0.915919 0.541384 +vt 0.915900 0.550889 +vt 0.916631 0.550505 +vt 0.173372 0.426951 +vt 0.173108 0.426130 +vt 0.278179 0.545297 +vt 0.278474 0.544474 +vt 0.277985 0.545888 +vt 0.289035 0.549221 +vt 0.289215 0.548633 +vt 0.289494 0.547806 +vt 0.954238 0.428642 +vt 0.952591 0.428750 +vt 0.913903 0.641365 +vt 0.915332 0.650106 +vt 0.915568 0.641518 +vt 0.917000 0.650277 +vt 0.917235 0.641708 +vt 0.950944 0.428897 +vt 0.914012 0.541529 +vt 0.914141 0.532737 +vt 0.913991 0.551014 +vt 0.916048 0.532577 +vt 0.901053 0.559718 +vt 0.897671 0.559599 +vt 0.897675 0.566229 +vt 0.895774 0.559383 +vt 0.895781 0.566003 +vt 0.899766 0.664799 +vt 0.899937 0.658599 +vt 0.898284 0.658809 +vt 0.898115 0.665020 +vt 0.896637 0.659063 +vt 0.896472 0.665284 +vt 0.950652 0.465443 +vt 0.949006 0.465455 +vt 0.947356 0.465478 +vt 0.926826 0.437329 +vt 0.928479 0.437640 +vt 0.579730 0.147286 +vt 0.583117 0.147056 +vt 0.585048 0.147019 +vt 0.239151 0.523804 +vt 0.239735 0.523184 +vt 0.946645 0.465667 +vt 0.947347 0.456183 +vt 0.123817 0.451143 +vt 0.123253 0.450534 +vt 0.585835 0.147209 +vt 0.574963 0.147629 +vt 0.605228 0.415138 +vt 0.608442 0.413334 +vt 0.608084 0.412850 +vt 0.604904 0.414655 +vt 0.899859 0.667615 +vt 0.900638 0.667242 +vt 0.902438 0.667427 +vt 0.900732 0.666837 +vt 0.607771 0.412319 +vt 0.604598 0.414123 +vt 0.567352 0.166214 +vt 0.567674 0.174809 +vt 0.565467 0.166484 +vt 0.565788 0.175096 +vt 0.949277 0.499729 +vt 0.947633 0.499581 +vt 0.946000 0.499430 +vt 0.218935 0.496212 +vt 0.219741 0.495938 +vt 0.945793 0.508433 +vt 0.945330 0.499304 +vt 0.104056 0.478514 +vt 0.103269 0.478251 +vt 0.583994 0.114279 +vt 0.584734 0.114155 +vt 0.950391 0.483242 +vt 0.950774 0.474600 +vt 0.950124 0.491485 +vt 0.639668 0.932968 +vt 0.637609 0.924973 +vt 0.637035 0.925095 +vt 0.639115 0.933167 +vt 0.643181 0.941070 +vt 0.642658 0.941341 +vt 0.573889 0.115251 +vt 0.578678 0.114803 +vt 0.566262 0.131527 +vt 0.564383 0.131727 +vt 0.582076 0.114481 +vt 0.920923 0.474329 +vt 0.922586 0.474546 +vt 0.924251 0.474766 +vt 0.607490 0.411856 +vt 0.604318 0.413656 +vt 0.902592 0.667076 +vt 0.900955 0.666490 +vt 0.903402 0.666802 +vt 0.902601 0.666201 +vt 0.900798 0.663709 +vt 0.902513 0.663423 +vt 0.574599 0.552462 +vt 0.587625 0.555938 +vt 0.562072 0.546464 +vt 0.949708 0.776268 +vt 0.949910 0.790012 +vt 0.951410 0.790883 +vt 0.951234 0.777071 +vt 0.949721 0.762310 +vt 0.951276 0.763048 +vt 0.635926 0.906997 +vt 0.639646 0.894965 +vt 0.639195 0.894793 +vt 0.635446 0.906932 +vt 0.646303 0.882743 +vt 0.645899 0.882465 +vt 0.200755 0.544397 +vt 0.203686 0.555182 +vt 0.205398 0.555542 +vt 0.202469 0.544701 +vt 0.199202 0.533232 +vt 0.200916 0.533470 +vt 0.681702 0.980810 +vt 0.681421 0.981229 +vt 0.691439 0.987195 +vt 0.672216 0.974154 +vt 0.671903 0.974551 +vt 0.203808 0.451197 +vt 0.202572 0.459650 +vt 0.204278 0.459491 +vt 0.205518 0.451025 +vt 0.912565 0.648920 +vt 0.912807 0.640234 +vt 0.911075 0.640013 +vt 0.910832 0.648728 +vt 0.656042 0.958129 +vt 0.648626 0.949689 +vt 0.648219 0.949971 +vt 0.655668 0.958459 +vt 0.642221 0.941566 +vt 0.200179 0.488499 +vt 0.199594 0.497941 +vt 0.201300 0.497948 +vt 0.201884 0.488454 +vt 0.200882 0.478683 +vt 0.202587 0.478590 +vt 0.535394 0.515698 +vt 0.542112 0.528075 +vt 0.531661 0.503507 +vt 0.212186 0.545301 +vt 0.210613 0.534131 +vt 0.208853 0.534103 +vt 0.210421 0.545339 +vt 0.215114 0.556040 +vt 0.213348 0.556149 +vt 0.663802 0.966457 +vt 0.663458 0.966825 +vt 0.201636 0.468918 +vt 0.203341 0.468786 +vt 0.608123 0.555560 +vt 0.599672 0.556183 +vt 0.599587 0.556684 +vt 0.607797 0.556085 +vt 0.950373 0.749929 +vt 0.951878 0.750788 +vt 0.952402 0.742049 +vt 0.953047 0.744053 +vt 0.559493 0.443112 +vt 0.551759 0.451550 +vt 0.567925 0.435373 +vt 0.212943 0.469321 +vt 0.213879 0.460021 +vt 0.212144 0.459749 +vt 0.211207 0.469067 +vt 0.212191 0.479162 +vt 0.210454 0.478924 +vt 0.538897 0.468853 +vt 0.544815 0.460427 +vt 0.544371 0.460120 +vt 0.538418 0.468600 +vt 0.211490 0.489063 +vt 0.209753 0.488847 +vt 0.210914 0.498581 +vt 0.209175 0.498394 +vt 0.855917 0.924561 +vt 0.599747 0.555577 +vt 0.608442 0.554901 +vt 0.859695 0.976218 +vt 0.927175 0.529993 +vt 0.926383 0.530323 +vt 0.551864 0.537603 +vt 0.551470 0.538038 +vt 0.951354 0.465291 +vt 0.952051 0.455591 +vt 0.649111 0.949353 +vt 0.656488 0.957738 +vt 0.951987 0.520211 +vt 0.950419 0.509261 +vt 0.872839 0.998699 +vt 0.871733 0.990835 +vt 0.872000 0.998833 +vt 0.640190 0.895153 +vt 0.646792 0.883056 +vt 0.636502 0.907060 +vt 0.871014 0.980596 +vt 0.655573 0.872992 +vt 0.655160 0.872577 +vt 0.927467 0.419264 +vt 0.578503 0.430162 +vt 0.588557 0.424398 +vt 0.588232 0.423933 +vt 0.578160 0.429719 +vt 0.587914 0.423412 +vt 0.577814 0.429217 +vt 0.920179 0.474180 +vt 0.919521 0.482464 +vt 0.920980 0.465500 +vt 0.535944 0.477301 +vt 0.539435 0.469133 +vt 0.535375 0.477090 +vt 0.533893 0.485358 +vt 0.533303 0.485226 +vt 0.922021 0.456153 +vt 0.545314 0.460772 +vt 0.918975 0.490869 +vt 0.532400 0.493649 +vt 0.531800 0.493608 +vt 0.913170 0.641027 +vt 0.914020 0.633390 +vt 0.913288 0.633024 +vt 0.682038 0.980316 +vt 0.672590 0.973688 +vt 0.949974 0.499842 +vt 0.636115 0.916747 +vt 0.635530 0.916786 +vt 0.952798 0.445917 +vt 0.953725 0.436723 +vt 0.664212 0.966023 +vt 0.958446 0.766401 +vt 0.954855 0.764730 +vt 0.954791 0.778796 +vt 0.958377 0.780471 +vt 0.954956 0.792644 +vt 0.958549 0.794316 +vt 0.958474 0.746488 +vt 0.955855 0.743903 +vt 0.955338 0.752220 +vt 0.958780 0.753935 +vt 0.209364 0.555926 +vt 0.206437 0.545079 +vt 0.204877 0.533823 +vt 0.955045 0.805015 +vt 0.958654 0.806688 +vt 0.951498 0.803217 +vt 0.951349 0.813624 +vt 0.954896 0.815455 +vt 0.958519 0.817128 +vt 0.200641 0.515230 +vt 0.204587 0.515496 +vt 0.204851 0.507012 +vt 0.200913 0.506784 +vt 0.208545 0.515764 +vt 0.208800 0.507273 +vt 0.205232 0.498140 +vt 0.206515 0.478700 +vt 0.207268 0.468860 +vt 0.208206 0.459547 +vt 0.910398 0.663130 +vt 0.906453 0.663200 +vt 0.906370 0.665981 +vt 0.910147 0.665898 +vt 0.906355 0.666698 +vt 0.909314 0.666561 +vt 0.209447 0.451088 +vt 0.213383 0.451311 +vt 0.907123 0.639978 +vt 0.903175 0.640108 +vt 0.902937 0.648893 +vt 0.906883 0.648732 +vt 0.205813 0.488606 +vt 0.204436 0.524115 +vt 0.200483 0.523803 +vt 0.208404 0.524394 +vt 0.534870 0.476896 +vt 0.532778 0.485097 +vt 0.210543 0.507427 +vt 0.210292 0.515883 +vt 0.677965 0.858361 +vt 0.665634 0.864234 +vt 0.690807 0.855030 +vt 0.959986 0.781130 +vt 0.960038 0.767106 +vt 0.960182 0.794925 +vt 0.407818 0.323528 +vt 0.407913 0.327297 +vt 0.407913 0.319761 +vt 0.906361 0.667028 +vt 0.910137 0.666768 +vt 0.531267 0.493557 +vt 0.210157 0.524472 +vt 0.635043 0.916808 +vt 0.636556 0.925191 +vt 0.198770 0.523630 +vt 0.198930 0.515116 +vt 0.700919 0.992678 +vt 0.707950 0.996742 +vt 0.912317 0.657170 +vt 0.910583 0.656999 +vt 0.912132 0.663288 +vt 0.071544 0.077977 +vt 0.072329 0.073230 +vt 0.072329 0.080823 +vt 0.956072 0.740620 +vt 0.959339 0.745139 +vt 0.638653 0.933330 +vt 0.199204 0.506725 +vt 0.551112 0.538392 +vt 0.950020 0.802282 +vt 0.949889 0.812633 +vt 0.577503 0.428779 +vt 0.587625 0.422955 +vt 0.901451 0.640371 +vt 0.901216 0.649158 +vt 0.215114 0.451608 +vt 0.654820 0.872212 +vt 0.960313 0.807254 +vt 0.960202 0.817658 +vt 0.702685 0.854409 +vt 0.711059 0.855004 +vt 0.960313 0.754440 +vt 0.910320 0.667104 +vt 0.912064 0.666382 +vt 0.911812 0.666054 +vt 0.711373 0.998125 +vt 0.711131 0.998559 +vt 0.906636 0.657041 +vt 0.902694 0.657237 +vt 0.597490 0.418079 +vt 0.597209 0.417615 +vt 0.900976 0.657512 +vt 0.598118 0.419087 +vt 0.597797 0.418610 +vt 0.898071 0.667851 +vt 0.896397 0.668119 +vt 0.897677 0.569251 +vt 0.895785 0.569021 +vt 0.905827 0.559854 +vt 0.910602 0.559990 +vt 0.183937 0.424246 +vt 0.183685 0.423425 +vt 0.915899 0.559956 +vt 0.916637 0.559586 +vt 0.299671 0.551660 +vt 0.299940 0.550830 +vt 0.299504 0.552242 +vt 0.915091 0.658300 +vt 0.916760 0.658452 +vt 0.913988 0.560063 +vt 0.912193 0.666777 +vt 0.711670 0.997607 +vt 0.290023 0.546330 +vt 0.289783 0.546971 +vt 0.300217 0.549991 +vt 0.300453 0.549340 +vt 0.307980 0.552238 +vt 0.308213 0.551579 +vt 0.172562 0.424609 +vt 0.172826 0.425290 +vt 0.183414 0.422581 +vt 0.183154 0.421891 +vt 0.191290 0.420567 +vt 0.191034 0.419870 +vt 0.923942 0.500429 +vt 0.923893 0.491231 +vt 0.100432 0.487202 +vt 0.102461 0.477961 +vt 0.105884 0.470486 +vt 0.924389 0.483028 +vt 0.563170 0.107282 +vt 0.563119 0.116186 +vt 0.218616 0.486789 +vt 0.220559 0.495648 +vt 0.223880 0.502827 +vt 0.563391 0.124090 +vt 0.114508 0.455949 +vt 0.115058 0.456432 +vt 0.122671 0.449904 +vt 0.122182 0.449373 +vt 0.131681 0.443606 +vt 0.131262 0.443031 +vt 0.233365 0.515869 +vt 0.232835 0.516315 +vt 0.240329 0.522556 +vt 0.240797 0.522063 +vt 0.249214 0.528565 +vt 0.249610 0.528029 +vt 0.268436 0.538993 +vt 0.268164 0.539603 +vt 0.278777 0.543646 +vt 0.279024 0.543017 +vt 0.150597 0.431549 +vt 0.150894 0.432199 +vt 0.161660 0.428309 +vt 0.161388 0.427639 +vt 0.194881 0.419648 +vt 0.194626 0.418948 +vt 0.195997 0.419362 +vt 0.195743 0.418661 +vt 0.311519 0.553262 +vt 0.311750 0.552600 +vt 0.312619 0.553581 +vt 0.312850 0.552918 +vt 0.900654 0.672121 +vt 0.989315 0.474803 +vt 0.989037 0.473545 +vt 0.988127 0.467481 +vt 0.900773 0.677726 +vt 0.899287 0.571443 +vt 0.900073 0.572743 +vt 0.497995 0.103981 +vt 0.497810 0.105351 +vt 0.496845 0.111324 +vt 0.900166 0.578490 +vt 0.657778 0.018516 +vt 0.658112 0.019350 +vt 0.171434 0.016106 +vt 0.243203 0.004770 +vt 0.507413 0.002681 +vt 0.506985 0.001969 +vt 0.976231 0.089868 +vt 0.975881 0.087871 +vt 0.230798 0.021664 +vt 0.232750 0.022063 +vt 0.956823 0.160958 +vt 0.961113 0.161828 +vt 0.175705 0.005582 +vt 0.175705 0.009915 +vt 0.237081 0.021616 +vt 0.975687 0.083511 +vt 0.498037 0.417707 +vt 0.498177 0.418051 +vt 0.655954 0.005729 +vt 0.655936 0.005384 +vt 0.655884 0.004779 +vt 0.897415 0.726180 +vt 0.896513 0.729442 +vt 0.988013 0.416879 +vt 0.988632 0.413587 +vt 0.510896 0.014916 +vt 0.511333 0.015555 +vt 0.511867 0.016304 +vt 0.175397 0.003726 +vt 0.955029 0.160052 +vt 0.655634 0.003939 +vt 0.979909 0.077419 +vt 0.967482 0.146821 +vt 0.900770 0.606472 +vt 0.902101 0.619301 +vt 0.493717 0.140159 +vt 0.494738 0.153022 +vt 0.496574 0.161228 +vt 0.903319 0.627659 +vt 0.900153 0.705149 +vt 0.898842 0.717867 +vt 0.985280 0.438161 +vt 0.986329 0.425151 +vt 0.903532 0.631032 +vt 0.497579 0.164489 +vt 0.497995 0.164975 +vt 0.507721 0.003164 +vt 0.657303 0.017503 +vt 0.657482 0.017845 +vt 0.982072 0.152322 +vt 0.982428 0.149262 +vt 0.022017 0.163985 +vt 0.026013 0.163453 +vt 0.027764 0.163176 +vt 0.981020 0.147809 +vt 0.533968 0.775385 +vt 0.533441 0.773752 +vt 0.530438 0.773939 +vt 0.384867 0.095031 +vt 0.388937 0.095580 +vt 0.390779 0.095909 +vt 0.977322 0.147213 +vt 0.981068 0.147196 +vt 0.977203 0.146569 +vt 0.973190 0.146780 +vt 0.309073 0.423049 +vt 0.308810 0.423665 +vt 0.312038 0.425030 +vt 0.312265 0.424420 +vt 0.314071 0.425909 +vt 0.313898 0.425256 +vt 0.557132 0.058625 +vt 0.556459 0.058501 +vt 0.556830 0.060519 +vt 0.998142 0.733582 +vt 0.998065 0.730197 +vt 0.998892 0.733639 +vt 0.998808 0.730240 +vt 0.998214 0.728335 +vt 0.997506 0.728351 +vt 0.998143 0.738383 +vt 0.998892 0.738440 +vt 0.182833 0.555240 +vt 0.182898 0.555826 +vt 0.179369 0.555318 +vt 0.853586 0.891772 +vt 0.853104 0.894986 +vt 0.298889 0.421757 +vt 0.298783 0.422387 +vt 0.295532 0.421643 +vt 0.840951 0.191929 +vt 0.840535 0.188922 +vt 0.191518 0.549388 +vt 0.191809 0.550046 +vt 0.194990 0.548723 +vt 0.194645 0.548112 +vt 0.196958 0.547829 +vt 0.196335 0.547496 +vt 0.313410 0.553807 +vt 0.313618 0.553161 +vt 0.314071 0.553960 +vt 0.805573 0.584229 +vt 0.196787 0.419151 +vt 0.196527 0.418477 +vt 0.197634 0.419738 +vt 0.197359 0.418921 +vt 0.895769 0.670101 +vt 0.258421 0.534423 +vt 0.258747 0.533846 +vt 0.224490 0.502497 +vt 0.227661 0.509687 +vt 0.228236 0.509297 +vt 0.925002 0.474923 +vt 0.109773 0.463344 +vt 0.925769 0.466414 +vt 0.141015 0.437485 +vt 0.140665 0.436869 +vt 0.565624 0.086716 +vt 0.563877 0.096909 +vt 0.222450 0.462785 +vt 0.219188 0.475253 +vt 0.927488 0.521362 +vt 0.925035 0.511063 +vt 0.104204 0.512185 +vt 0.100951 0.499242 +vt 0.236860 0.441954 +vt 0.236378 0.441543 +vt 0.228287 0.451412 +vt 0.228828 0.451749 +vt 0.223035 0.463010 +vt 0.839111 0.150348 +vt 0.839903 0.137009 +vt 0.257200 0.427340 +vt 0.246273 0.433310 +vt 0.840789 0.123606 +vt 0.851748 0.935223 +vt 0.852894 0.948630 +vt 0.139823 0.548855 +vt 0.128531 0.542539 +vt 0.118344 0.533987 +vt 0.128093 0.542972 +vt 0.117817 0.534342 +vt 0.110094 0.523867 +vt 0.109510 0.524152 +vt 0.930621 0.529910 +vt 0.931483 0.529437 +vt 0.851403 0.911410 +vt 0.851216 0.922692 +vt 0.162419 0.554137 +vt 0.151340 0.552435 +vt 0.839739 0.182516 +vt 0.288644 0.421890 +vt 0.279089 0.422586 +vt 0.838984 0.173357 +vt 0.838761 0.162548 +vt 0.268350 0.424059 +vt 0.852220 0.901768 +vt 0.172269 0.554985 +vt 0.187713 0.550914 +vt 0.187962 0.551586 +vt 0.305084 0.421425 +vt 0.304863 0.422055 +vt 0.980191 0.161960 +vt 0.981083 0.157263 +vt 0.009594 0.165279 +vt 0.015558 0.164785 +vt 0.980158 0.166644 +vt 0.979891 0.164555 +vt 0.005482 0.163041 +vt 0.006787 0.164820 +vt 0.897939 0.016886 +vt 0.897867 0.019533 +vt 0.367251 0.096619 +vt 0.368928 0.094419 +vt 0.372043 0.093786 +vt 0.898134 0.022440 +vt 0.898725 0.027251 +vt 0.378250 0.094230 +vt 0.899343 0.032194 +vt 0.899347 0.007564 +vt 0.898352 0.012646 +vt 0.362961 0.106524 +vt 0.364984 0.100702 +vt 0.960435 0.978308 +vt 0.960659 0.990830 +vt 0.005919 0.135494 +vt 0.001965 0.147402 +vt 0.001938 0.154650 +vt 0.961190 0.996976 +vt 0.982428 0.174376 +vt 0.980915 0.170092 +vt 0.003629 0.159684 +vt 0.960967 0.939506 +vt 0.960644 0.958122 +vt 0.023424 0.102418 +vt 0.014710 0.118054 +vt 0.965651 0.518418 +vt 0.965428 0.499522 +vt 0.384661 0.160545 +vt 0.375796 0.144525 +vt 0.366851 0.126705 +vt 0.965330 0.478983 +vt 0.965483 0.465952 +vt 0.362859 0.114371 +vt 0.965778 0.459107 +vt 0.960907 0.929764 +vt 0.961058 0.931242 +vt 0.027998 0.094348 +vt 0.027297 0.095503 +vt 0.900211 0.591152 +vt 0.494910 0.124447 +vt 0.387824 0.169247 +vt 0.388835 0.168673 +vt 0.388334 0.167412 +vt 0.387638 0.168072 +vt 0.965778 0.526437 +vt 0.900706 0.690103 +vt 0.986336 0.454122 +vt 0.914776 0.670026 +vt 0.913220 0.670960 +vt 0.914874 0.670645 +vt 0.916533 0.670329 +vt 0.930773 0.537452 +vt 0.930900 0.539240 +vn -0.0194 -0.0663 -0.9976 +vn -0.0133 -0.0691 -0.9975 +vn -0.0136 -0.0657 -0.9977 +vn 0.0045 0.4325 0.9016 +vn -0.0150 0.4636 0.8859 +vn -0.0781 0.4597 0.8846 +vn -0.0629 0.4214 0.9047 +vn -0.1076 0.4257 0.8984 +vn -0.1082 0.4912 0.8643 +vn -0.3928 0.3826 0.8363 +vn -0.3903 0.3609 0.8470 +vn -0.3892 0.3279 0.8608 +vn -0.0195 -0.0663 -0.9976 +vn -0.0192 -0.0698 -0.9974 +vn -0.0133 -0.0693 -0.9975 +vn -0.0187 -0.1143 -0.9933 +vn -0.0129 -0.1132 -0.9935 +vn -0.0071 -0.1121 -0.9937 +vn -0.0076 -0.0685 -0.9976 +vn -0.0136 -0.0660 -0.9977 +vn -0.0078 -0.0654 -0.9978 +vn 0.3869 0.5583 -0.7339 +vn 0.3900 0.6474 -0.6548 +vn 0.1862 0.6982 -0.6913 +vn 0.1885 0.5980 -0.7791 +vn 0.3808 0.7748 -0.5046 +vn 0.1749 0.8370 -0.5185 +vn 0.4159 0.7610 -0.4979 +vn 0.4347 0.6324 -0.6411 +vn 0.4494 0.5404 -0.7114 +vn 0.0198 0.0586 0.9981 +vn 0.0196 0.0744 0.9970 +vn 0.0142 0.0743 0.9971 +vn 0.0143 0.0586 0.9982 +vn 0.0194 0.1187 0.9927 +vn 0.0139 0.1187 0.9928 +vn 0.0086 0.1186 0.9929 +vn 0.0088 0.0742 0.9972 +vn 0.0089 0.0585 0.9982 +vn -0.4479 -0.0774 -0.8907 +vn -0.0892 -0.0686 -0.9936 +vn -0.0867 -0.1146 -0.9896 +vn -0.4607 -0.1432 -0.8759 +vn -0.0194 -0.1160 -0.9931 +vn -0.0867 -0.1147 -0.9896 +vn -0.0215 -0.4082 -0.9126 +vn -0.1256 -0.4280 -0.8950 +vn -0.4608 -0.1432 -0.8759 +vn -0.4083 -0.3601 -0.8388 +vn 0.0187 0.4338 0.9008 +vn 0.0187 0.2839 0.9587 +vn 0.0888 0.2922 0.9522 +vn 0.0863 0.4456 0.8910 +vn 0.0890 0.1233 0.9884 +vn 0.4460 0.1383 0.8843 +vn 0.4406 0.3112 0.8421 +vn 0.4315 0.4667 0.7720 +vn -0.0258 -0.6067 0.7945 +vn -0.0233 -0.5140 0.8575 +vn 0.0439 -0.5171 0.8548 +vn 0.0407 -0.6095 0.7917 +vn -0.0188 -0.3488 0.9370 +vn 0.0487 -0.3520 0.9347 +vn 0.3942 -0.3297 0.8579 +vn 0.3906 -0.4835 0.7834 +vn 0.3861 -0.5709 0.7246 +vn -0.0893 -0.0736 -0.9933 +vn -0.0885 -0.1203 -0.9888 +vn -0.4477 -0.0853 -0.8901 +vn -0.4502 -0.1397 -0.8819 +vn 0.0118 0.4322 0.9017 +vn 0.0123 0.4629 0.8863 +vn 0.0366 0.4738 0.8799 +vn 0.1268 0.4933 0.8606 +vn 0.0168 0.4322 0.9016 +vn -0.0044 -0.4355 -0.9002 +vn -0.0104 -0.4379 -0.8990 +vn -0.0084 -0.4843 -0.8749 +vn -0.0022 -0.4816 -0.8764 +vn -0.0165 -0.4401 -0.8978 +vn -0.0140 -0.4865 -0.8736 +vn -0.0111 -0.5276 -0.8494 +vn -0.0053 -0.5250 -0.8511 +vn 0.0010 -0.5217 -0.8531 +vn 0.3551 0.9167 -0.1834 +vn 0.3648 0.8667 -0.3401 +vn 0.8427 0.4562 -0.2860 +vn 0.8260 0.5035 -0.2534 +vn 0.8585 0.3931 -0.3293 +vn 0.8426 0.4563 -0.2860 +vn 0.8585 0.3930 -0.3293 +vn 0.9495 0.2171 -0.2265 +vn 0.9397 0.2534 -0.2297 +vn 0.9213 0.2997 -0.2479 +vn 0.3653 0.1276 -0.9221 +vn 0.3598 0.0770 -0.9298 +vn 0.8443 0.0411 -0.5343 +vn 0.8437 0.0666 -0.5326 +vn 0.3595 -0.0231 -0.9329 +vn 0.8468 -0.0058 -0.5319 +vn 0.8443 0.0411 -0.5342 +vn 0.9510 0.0016 -0.3093 +vn 0.9521 0.0216 -0.3049 +vn 0.9544 0.0317 -0.2970 +vn -0.0006 -0.6100 -0.7924 +vn 0.0054 -0.6065 -0.7951 +vn -0.0068 -0.6133 -0.7898 +vn -0.0016 -0.7461 -0.6659 +vn 0.0041 -0.7431 -0.6692 +vn 0.0103 -0.7396 -0.6730 +vn 0.5284 -0.8364 0.1454 +vn 0.3496 -0.8900 -0.2928 +vn 0.1552 -0.9842 -0.0848 +vn 0.1654 -0.9728 0.1619 +vn 0.1511 -0.5405 -0.8277 +vn 0.1313 -0.7717 -0.6222 +vn 0.1552 -0.9842 -0.0849 +vn 0.3033 -0.7659 -0.5669 +vn 0.4648 -0.8740 -0.1419 +vn 0.4648 -0.8740 -0.1418 +vn 0.4650 -0.8705 0.1613 +vn -0.0044 -0.9952 0.0980 +vn 0.0027 -0.9927 -0.1204 +vn -0.0654 -0.9934 -0.0946 +vn -0.0708 -0.9907 0.1160 +vn 0.0048 -0.9474 -0.3200 +vn -0.0633 -0.9547 -0.2906 +vn -0.3934 -0.9110 -0.1238 +vn -0.3925 -0.9190 0.0369 +vn -0.3950 -0.8974 0.1966 +vn 0.0085 -0.8645 -0.5025 +vn 0.0139 -0.8623 -0.5063 +vn 0.0027 -0.8669 -0.4985 +vn 0.0100 -0.9461 -0.3236 +vn 0.0155 -0.9448 -0.3273 +vn 0.0649 -0.4648 -0.8830 +vn 0.0627 -0.4206 -0.9051 +vn 0.0682 -0.5014 -0.8625 +vn 0.3876 -0.3717 -0.8436 +vn 0.3884 -0.3535 -0.8510 +vn 0.3906 -0.3203 -0.8630 +vn -0.0371 -0.6022 0.7975 +vn -0.0361 -0.7070 0.7063 +vn -0.1047 -0.7005 0.7060 +vn -0.1057 -0.5965 0.7956 +vn -0.0272 -0.8529 0.5214 +vn -0.0943 -0.8459 0.5249 +vn -0.4289 -0.7481 0.5063 +vn -0.4451 -0.6177 0.6483 +vn -0.4448 -0.5306 0.7216 +vn -0.3556 0.8284 0.4328 +vn -0.3555 0.7222 0.5933 +vn -0.7869 0.2720 0.5539 +vn -0.7923 0.3849 0.4733 +vn -0.3524 0.5897 0.7267 +vn -0.7834 0.1617 0.6002 +vn -0.8749 -0.0108 0.4842 +vn -0.8776 0.0783 0.4730 +vn -0.8860 0.1782 0.4281 +vn -0.3539 0.9069 0.2286 +vn -0.1663 0.9711 0.1713 +vn -0.1682 0.9106 0.3774 +vn -0.3461 0.9381 -0.0099 +vn -0.1557 0.9859 -0.0609 +vn -0.4360 0.8998 0.0151 +vn -0.4464 0.8592 0.2501 +vn -0.4396 0.7800 0.4454 +vn 0.3481 0.7895 0.5055 +vn 0.3357 0.8804 0.3351 +vn 0.7752 0.6309 -0.0324 +vn 0.7875 0.6092 0.0930 +vn 0.3377 0.9264 0.1665 +vn 0.7844 0.6057 -0.1336 +vn 0.8803 0.4167 -0.2269 +vn 0.8714 0.4626 -0.1632 +vn 0.8828 0.4646 -0.0698 +vn 0.0080 -0.9924 -0.1231 +vn 0.0128 -0.9920 -0.1254 +vn 0.0006 -0.9953 0.0967 +vn 0.0051 -0.9954 0.0957 +vn -0.0312 -0.6045 0.7960 +vn -0.0288 -0.5111 0.8590 +vn -0.0346 -0.5082 0.8605 +vn -0.0304 -0.3412 0.9395 +vn -0.0245 -0.3450 0.9383 +vn -0.0100 -0.9514 0.3078 +vn -0.0056 -0.9515 0.3077 +vn -0.0044 -0.9952 0.0979 +vn -0.0151 -0.9512 0.3081 +vn -0.0218 -0.8532 0.5211 +vn -0.0170 -0.8536 0.5207 +vn -0.0593 0.0711 0.9957 +vn -0.0596 0.0566 0.9966 +vn -0.0586 0.1137 0.9918 +vn -0.3833 0.0798 0.9202 +vn -0.3900 0.0502 0.9194 +vn -0.3939 0.0394 0.9183 +vn -0.5154 -0.8516 0.0961 +vn -0.4573 -0.6838 0.5686 +vn -0.1737 -0.9049 0.3885 +vn -0.1748 -0.9740 0.1442 +vn -0.1993 0.0455 0.9789 +vn -0.1533 -0.4931 0.8563 +vn -0.3113 -0.5345 0.7857 +vn -0.4654 -0.7881 0.4028 +vn -0.4575 -0.8818 0.1146 +vn 0.3459 0.9382 -0.0090 +vn 0.1458 0.9868 0.0700 +vn 0.1508 0.9792 -0.1359 +vn 0.1434 0.9537 0.2644 +vn 0.3894 0.9090 0.1486 +vn 0.3844 0.9231 -0.0133 +vn 0.3842 0.9053 -0.1812 +vn 0.0722 -0.5830 -0.8092 +vn 0.0768 -0.7164 -0.6935 +vn 0.4005 -0.5446 -0.7369 +vn 0.3906 -0.4291 -0.8144 +vn -0.0564 -0.0092 0.9984 +vn 0.0090 -0.0111 0.9999 +vn -0.4083 -0.0427 0.9119 +vn -0.3608 -0.2707 0.8925 +vn -0.0942 -0.3369 0.9368 +vn 0.0052 -0.3212 0.9470 +vn -0.2989 0.4696 0.8308 +vn -0.7263 0.0866 0.6819 +vn -0.4883 0.0369 0.8719 +vn -0.7262 0.0866 0.6820 +vn -0.6445 -0.2738 0.7139 +vn -0.8467 -0.1165 0.5191 +vn -0.1168 -0.5398 -0.8336 +vn 0.0247 -0.7351 -0.6775 +vn 0.0336 -0.3964 -0.9175 +vn 0.0109 -0.3947 -0.9187 +vn 0.1753 -0.5360 -0.8258 +vn 0.0568 -0.3986 -0.9154 +vn 0.0340 -0.4166 -0.9084 +vn -0.0888 -0.5406 -0.8366 +vn -0.0124 -0.1284 0.9916 +vn -0.0224 -0.1914 0.9813 +vn -0.0908 -0.1866 0.9782 +vn -0.0802 -0.1243 0.9890 +vn -0.1002 -0.3358 0.9366 +vn -0.4521 -0.2946 0.8419 +vn -0.4374 -0.1632 0.8843 +vn -0.4245 -0.1089 0.8989 +vn -0.3258 -0.1874 -0.9267 +vn -0.3414 -0.1781 -0.9229 +vn -0.8297 -0.1267 -0.5436 +vn -0.8197 -0.1547 -0.5515 +vn -0.3504 -0.1718 -0.9207 +vn -0.8338 -0.1217 -0.5385 +vn -0.9492 -0.0845 -0.3033 +vn -0.9477 -0.0881 -0.3068 +vn -0.9451 -0.1196 -0.3042 +vn -0.0013 -0.1369 0.9906 +vn -0.0068 -0.1328 0.9911 +vn 0.0018 -0.0766 0.9971 +vn 0.0072 -0.0794 0.9968 +vn -0.0035 -0.0737 0.9973 +vn -0.0008 0.0317 0.9995 +vn 0.0048 0.0321 0.9995 +vn 0.0104 0.0324 0.9994 +vn 0.9990 0.0260 0.0352 +vn 0.7025 0.3340 0.6285 +vn 0.7105 0.3719 0.5973 +vn 0.9990 0.0431 0.0087 +vn 0.1627 0.4564 0.8747 +vn 0.1633 0.4959 0.8529 +vn 0.7106 0.3719 0.5973 +vn 0.1698 0.5903 0.7891 +vn 0.7235 0.4544 0.5198 +vn 0.7234 0.4544 0.5198 +vn 0.9967 0.0689 -0.0438 +vn -0.0282 0.1793 0.9834 +vn -0.0352 0.1791 0.9832 +vn -0.0366 0.1466 0.9885 +vn -0.0177 0.1129 0.9935 +vn -0.0421 0.1692 0.9847 +vn -0.0557 0.1012 0.9933 +vn -0.0368 0.2481 0.9680 +vn 0.1216 0.0668 0.9903 +vn 0.0788 -0.9858 -0.1481 +vn 0.0829 -0.9317 -0.3538 +vn 0.0685 -0.9945 0.0798 +vn 0.4150 -0.9096 -0.0195 +vn 0.4286 -0.8651 -0.2607 +vn 0.4239 -0.7805 -0.4595 +vn 0.3389 0.6493 0.6809 +vn 0.1453 0.6443 0.7508 +vn 0.1510 0.7774 0.6106 +vn 0.1238 0.5459 0.8286 +vn 0.4383 0.5765 0.6896 +vn 0.4308 0.6676 0.6073 +vn 0.4138 0.7798 0.4698 +vn 0.9449 -0.2287 0.2343 +vn 0.6778 0.0968 0.7289 +vn 0.7597 0.6362 0.1347 +vn 0.9419 0.1845 -0.2809 +vn 0.6778 0.0969 0.7289 +vn 0.2104 0.2786 0.9371 +vn 0.2567 0.8176 0.5154 +vn 0.2490 0.8426 0.4776 +vn 0.7478 0.6562 0.1011 +vn 0.9288 0.1597 -0.3345 +vn -0.9982 -0.0505 -0.0324 +vn -0.6985 -0.3440 -0.6275 +vn -0.7052 -0.3705 -0.6044 +vn -0.9984 -0.0540 -0.0154 +vn -0.6985 -0.3440 -0.6274 +vn -0.1622 -0.4533 -0.8765 +vn -0.1647 -0.4898 -0.8561 +vn -0.7052 -0.3705 -0.6045 +vn -0.1730 -0.5861 -0.7916 +vn -0.7115 -0.4547 -0.5357 +vn -0.9960 -0.0860 0.0257 +vn 0.0389 -0.4556 -0.8893 +vn 0.0423 -0.4905 -0.8704 +vn 0.2386 -0.4435 -0.8639 +vn 0.2441 -0.4712 -0.8476 +vn 0.2402 -0.5495 -0.8002 +vn 0.0380 -0.5800 -0.8137 +vn -0.0388 0.4586 0.8878 +vn -0.0425 0.4947 0.8680 +vn -0.2410 0.4386 0.8658 +vn -0.2480 0.4714 0.8463 +vn -0.2486 0.5522 0.7957 +vn -0.0392 0.5846 0.8104 +vn -0.3654 -0.8664 -0.3405 +vn -0.0309 -0.8446 -0.5345 +vn -0.0445 -0.8467 -0.5302 +vn -0.2584 -0.8612 -0.4377 +vn 0.3007 -0.7494 -0.5898 +vn 0.1665 -0.7871 -0.5940 +vn 0.1329 -0.8530 -0.5047 +vn -0.0515 -0.8952 -0.4427 +vn -0.2435 -0.9009 -0.3593 +vn -0.5792 -0.4331 0.6906 +vn -0.7547 -0.6501 0.0888 +vn -0.8814 -0.4573 0.1187 +vn -0.9034 -0.1243 0.4105 +vn -0.5514 -0.3695 -0.7480 +vn -0.7013 -0.6331 -0.3276 +vn -0.3654 -0.8663 -0.3405 +vn -0.8113 -0.5846 0.0000 +vn -0.9235 -0.0870 0.3736 +vn -0.0207 -0.2498 -0.9681 +vn -0.0201 -0.1041 -0.9944 +vn -0.2836 -0.0796 -0.9556 +vn 0.3799 -0.3155 -0.8696 +vn 0.1854 -0.1291 -0.9741 +vn 0.2012 -0.2134 -0.9560 +vn -0.0193 -0.1867 -0.9822 +vn -0.2878 -0.1892 -0.9388 +vn 0.0237 0.2332 0.9721 +vn 0.0207 0.7882 0.6151 +vn -0.1511 0.0929 0.9841 +vn -0.2040 0.7159 0.6677 +vn -0.1808 0.7637 0.6197 +vn 0.0298 0.8227 0.5677 +vn 0.9167 0.0374 -0.3978 +vn 0.7519 0.6593 0.0043 +vn 0.7370 0.6607 -0.1426 +vn 0.9239 -0.0184 -0.3822 +vn 0.2483 0.8951 0.3703 +vn 0.2250 0.9610 0.1609 +vn 0.2250 0.9610 0.1610 +vn 0.1806 0.9753 -0.1275 +vn 0.7015 0.6478 -0.2971 +vn 0.9470 -0.0458 -0.3179 +vn 0.0465 0.8405 0.5398 +vn 0.2504 0.8545 0.4551 +vn -0.1496 0.7908 0.5934 +vn -0.1330 0.8485 0.5122 +vn 0.0539 0.8896 0.4535 +vn 0.7515 0.6550 0.0786 +vn 0.9227 0.0986 -0.3726 +vn -0.7700 -0.6355 -0.0570 +vn -0.9242 -0.0763 0.3742 +vn -0.7378 -0.6742 -0.0335 +vn -0.9251 -0.0550 0.3757 +vn -0.9453 -0.0114 0.3259 +vn -0.6512 -0.7040 0.2834 +vn -0.6318 -0.6509 0.4209 +vn -0.9625 0.0160 0.2708 +vn -0.1659 -0.9735 0.1575 +vn -0.1324 -0.9125 0.3871 +vn -0.1207 -0.8436 0.5232 +vn -0.6249 -0.6081 0.4896 +vn -0.6248 -0.6081 0.4896 +vn -0.9766 0.0190 0.2142 +vn -0.6973 -0.7107 0.0931 +vn -0.9321 -0.0347 0.3605 +vn -0.2144 -0.9660 -0.1443 +vn -0.0289 -0.9754 -0.2187 +vn 0.1541 -0.9465 -0.2834 +vn 0.1973 -0.9797 0.0363 +vn 0.0142 -0.9949 0.1003 +vn 0.0336 0.9698 0.2416 +vn -0.1521 0.9390 0.3083 +vn -0.1907 0.9817 0.0002 +vn -0.0068 0.9980 -0.0625 +vn 0.0474 -0.8674 0.4953 +vn 0.0647 -0.5946 0.8014 +vn -0.1182 -0.5749 0.8096 +vn 0.2184 -0.8673 0.4472 +vn 0.2564 -0.5897 0.7659 +vn 0.2725 -0.1558 0.9495 +vn 0.0733 -0.1627 0.9840 +vn -0.1203 -0.1593 0.9799 +vn 0.0406 -0.9374 0.3458 +vn 0.1973 -0.9797 0.0364 +vn 0.2175 -0.9325 0.2883 +vn -0.0329 0.9556 -0.2930 +vn 0.1444 0.9311 -0.3349 +vn -0.2090 0.9461 -0.2473 +vn -0.2082 0.8952 -0.3942 +vn -0.0395 0.9046 -0.4244 +vn 0.1288 0.8831 -0.4512 +vn 0.6666 0.6316 -0.3959 +vn 0.9667 -0.0427 -0.2524 +vn 0.6665 0.6317 -0.3959 +vn 0.6527 0.6085 -0.4514 +vn 0.9791 -0.0371 -0.2000 +vn 0.9933 0.0189 -0.1141 +vn 0.6686 0.1001 -0.7369 +vn 0.6569 0.0057 -0.7539 +vn 0.9910 0.0206 -0.1324 +vn 0.6685 0.1001 -0.7369 +vn 0.1256 0.1227 -0.9845 +vn 0.1272 -0.0116 -0.9918 +vn 0.6569 0.0058 -0.7539 +vn 0.1323 -0.0262 -0.9909 +vn 0.6620 0.0091 -0.7494 +vn 0.9895 0.0461 -0.1373 +vn -0.0599 0.6112 -0.7892 +vn 0.1405 0.5972 -0.7897 +vn -0.2600 0.6060 -0.7518 +vn -0.2749 0.1154 -0.9545 +vn -0.0727 0.1189 -0.9902 +vn 0.7165 0.3641 -0.5950 +vn 0.9922 -0.0571 -0.1111 +vn 0.7165 0.3642 -0.5950 +vn -0.5939 -0.4381 0.6748 +vn -0.9768 -0.0536 0.2074 +vn -0.6282 -0.1213 0.7686 +vn -0.6281 -0.1213 0.7686 +vn -0.9866 -0.0258 0.1609 +vn -0.0728 -0.0348 -0.9967 +vn -0.0730 0.0244 -0.9970 +vn 0.1554 0.0890 -0.9838 +vn -0.2837 -0.0343 -0.9583 +vn -0.3084 0.0892 -0.9471 +vn -0.2241 0.4086 -0.8848 +vn -0.0685 0.4361 -0.8973 +vn 0.0842 0.4055 -0.9102 +vn -0.6499 -0.0123 0.7599 +vn -0.9897 -0.0218 0.1415 +vn -0.1266 -0.0022 0.9920 +vn -0.6499 -0.0122 0.7599 +vn -0.1324 0.0366 0.9905 +vn -0.6611 0.0317 0.7496 +vn -0.6612 0.0317 0.7496 +vn -0.9901 0.0129 0.1399 +vn 0.0732 0.0010 0.9973 +vn 0.2771 0.0061 0.9608 +vn 0.2825 0.0444 0.9582 +vn 0.0725 0.0376 0.9967 +vn -0.0726 -0.0174 -0.9972 +vn -0.2776 -0.0209 -0.9605 +vn -0.9960 -0.0402 0.0804 +vn -0.9950 -0.0416 0.0903 +vn -0.9153 -0.0741 -0.3959 +vn -0.9138 -0.0673 -0.4006 +vn -0.9916 -0.0693 0.1094 +vn -0.9193 -0.1225 -0.3740 +vn -0.4502 -0.1397 -0.8820 +vn 0.9971 0.0096 -0.0758 +vn 0.9953 0.0397 -0.0878 +vn 0.9127 0.0695 0.4026 +vn 0.9121 0.0376 0.4082 +vn 0.9925 0.0679 -0.1020 +vn 0.9120 0.1162 0.3933 +vn 0.4460 0.1384 0.8843 +vn 0.4442 0.0843 0.8920 +vn 0.4456 0.0604 0.8932 +vn 0.9761 0.1559 -0.1514 +vn 0.8439 -0.0541 -0.5338 +vn 0.8345 -0.0631 -0.5475 +vn 0.9684 0.1701 -0.1824 +vn 0.8214 -0.0503 -0.5681 +vn 0.9530 0.2009 -0.2269 +vn -0.9534 -0.1971 0.2283 +vn -0.8207 0.0639 0.5678 +vn -0.8079 0.0810 0.5837 +vn -0.9340 -0.2236 0.2786 +vn -0.8207 0.0640 0.5678 +vn -0.3986 0.4463 0.8013 +vn -0.8079 0.0811 0.5837 +vn -0.4096 0.5629 0.7178 +vn -0.8090 0.1385 0.5713 +vn -0.8090 0.1384 0.5713 +vn -0.9189 -0.2295 0.3208 +vn -0.9760 -0.1527 0.1552 +vn -0.8414 0.0674 0.5361 +vn -0.8351 0.0721 0.5454 +vn -0.9686 -0.1681 0.1832 +vn -0.8414 0.0674 0.5362 +vn 0.8127 -0.0531 -0.5803 +vn 0.9334 0.2315 -0.2742 +vn 0.8151 -0.0961 -0.5713 +vn 0.9180 0.2421 -0.3142 +vn 0.9207 0.1924 -0.3395 +vn 0.8487 -0.2462 -0.4681 +vn 0.8746 -0.3273 -0.3577 +vn 0.9393 0.1433 -0.3117 +vn 0.8907 -0.4096 -0.1974 +vn 0.9640 0.0801 -0.2534 +vn 0.8272 -0.1691 -0.5359 +vn 0.9129 0.2268 -0.3394 +vn 0.4117 -0.6739 -0.6134 +vn 0.8272 -0.1692 -0.5359 +vn -0.8232 0.2098 0.5276 +vn -0.9143 -0.2123 0.3450 +vn -0.4254 0.6820 0.5949 +vn -0.8437 0.2877 0.4531 +vn -0.8438 0.2877 0.4531 +vn -0.9225 -0.1740 0.3445 +vn -0.8658 0.3750 0.3313 +vn -0.9426 -0.1179 0.3125 +vn -0.8776 0.4513 0.1614 +vn -0.9682 -0.0500 0.2451 +vn 0.8906 -0.4543 -0.0183 +vn 0.9839 0.0190 -0.1778 +vn 0.4151 -0.9096 -0.0195 +vn 0.3979 -0.8922 0.2138 +vn 0.8907 -0.4543 -0.0183 +vn 0.3940 -0.8084 0.4374 +vn 0.8926 -0.4269 0.1452 +vn 0.8925 -0.4269 0.1453 +vn 0.9940 -0.0121 -0.1085 +vn -0.8743 0.4851 -0.0155 +vn -0.9866 0.0094 0.1628 +vn -0.4148 0.8841 -0.2152 +vn -0.4049 0.8019 -0.4393 +vn -0.8690 0.4591 -0.1844 +vn -0.9954 0.0406 0.0868 +vn 0.9996 -0.0119 0.0249 +vn 0.8731 -0.0763 0.4815 +vn 0.8823 -0.0408 0.4689 +vn 0.9999 -0.0031 0.0124 +vn 0.4009 -0.1329 0.9064 +vn 0.4136 -0.0764 0.9072 +vn 0.8823 -0.0408 0.4690 +vn 0.4231 0.0339 0.9055 +vn 0.8891 0.0249 0.4569 +vn 0.9999 0.0116 0.0049 +vn 0.9997 -0.0216 -0.0074 +vn 0.8767 -0.3104 0.3674 +vn 0.8764 -0.2631 0.4033 +vn 0.9996 -0.0251 0.0118 +vn 0.8764 -0.2631 0.4034 +vn 0.8768 -0.1825 0.4449 +vn 0.9995 -0.0231 0.0237 +vn -0.9996 0.0281 -0.0085 +vn -0.8694 0.3079 -0.3866 +vn -0.8603 0.2658 -0.4351 +vn -0.9990 0.0326 -0.0320 +vn -0.8693 0.3079 -0.3866 +vn -0.4018 0.5564 -0.7274 +vn -0.3990 0.4685 -0.7882 +vn -0.8603 0.2657 -0.4350 +vn -0.3987 0.3157 -0.8610 +vn -0.8554 0.1825 -0.4848 +vn -0.8554 0.1825 -0.4847 +vn -0.9985 0.0280 -0.0471 +vn -0.9994 0.0124 -0.0310 +vn -0.8698 0.0698 -0.4885 +vn -0.8746 0.0375 -0.4833 +vn -0.9998 0.0040 -0.0210 +vn -0.4161 0.1176 -0.9017 +vn -0.4263 0.0669 -0.9021 +vn -0.4328 -0.0309 -0.9010 +vn -0.8772 -0.0236 -0.4796 +vn -0.9998 -0.0120 -0.0159 +vn 0.9984 -0.0217 0.0529 +vn 0.8690 0.0674 0.4901 +vn 0.8137 -0.2948 0.5010 +vn 0.9038 -0.4132 0.1112 +vn 0.8690 0.0673 0.4901 +vn 0.3923 0.1578 0.9062 +vn 0.4031 -0.0979 0.9099 +vn 0.4030 -0.0979 0.9099 +vn 0.2570 -0.5137 0.8186 +vn 0.4479 -0.7686 0.4568 +vn -0.9944 -0.0999 -0.0353 +vn -0.8651 -0.1666 -0.4732 +vn -0.7941 -0.4841 -0.3674 +vn -0.8845 -0.4658 0.0275 +vn -0.3988 -0.2130 -0.8920 +vn -0.3948 -0.4390 -0.8071 +vn -0.7941 -0.4841 -0.3675 +vn -0.2506 -0.7666 -0.5912 +vn -0.4357 -0.8818 -0.1806 +vn -0.4576 -0.8817 0.1145 +vn 0.3688 -0.1612 -0.9154 +vn 0.3618 -0.1206 -0.9244 +vn 0.1598 -0.1345 -0.9779 +vn 0.1701 -0.1792 -0.9690 +vn 0.3617 -0.1206 -0.9244 +vn 0.1545 -0.0273 -0.9876 +vn 0.1598 -0.1345 -0.9780 +vn 0.4279 -0.0222 -0.9035 +vn 0.4369 -0.1164 -0.8919 +vn 0.4370 -0.1164 -0.8919 +vn 0.4496 -0.1549 -0.8797 +vn 0.1454 0.8863 0.4397 +vn 0.3980 0.8651 0.3054 +vn -0.3247 0.5750 -0.7510 +vn -0.3309 0.4835 -0.8104 +vn -0.1272 0.5053 -0.8535 +vn -0.1238 0.6002 -0.7902 +vn -0.3375 0.3251 -0.8834 +vn -0.1316 0.3391 -0.9315 +vn -0.0180 -0.2840 -0.9587 +vn -0.0876 -0.2942 -0.9517 +vn -0.0858 -0.4527 -0.8875 +vn -0.4501 -0.1397 -0.8820 +vn -0.4530 -0.3223 -0.8312 +vn -0.4395 -0.4775 -0.7608 +vn -0.0504 -0.3804 -0.9234 +vn -0.0737 -0.2528 -0.9647 +vn -0.0831 -0.7687 -0.6342 +vn 0.0605 -0.0646 -0.9961 +vn 0.0609 -0.0629 -0.9962 +vn 0.0616 -0.1054 -0.9925 +vn 0.3920 -0.0684 -0.9174 +vn 0.3898 -0.0433 -0.9199 +vn 0.3953 -0.0504 -0.9172 +vn -0.1645 0.8196 0.5488 +vn -0.1582 0.6949 0.7015 +vn -0.0156 0.1741 0.9846 +vn -0.0055 0.1325 0.9912 +vn -0.0755 0.1279 0.9889 +vn -0.0858 0.1680 0.9820 +vn -0.0703 0.0304 0.9971 +vn -0.4227 0.0227 0.9060 +vn -0.4270 0.1057 0.8981 +vn -0.4345 0.1396 0.8898 +vn 0.9106 -0.1188 0.3959 +vn 0.9850 -0.1611 -0.0613 +vn 0.4600 -0.0378 0.8871 +vn 0.9105 -0.1188 0.3960 +vn 0.4072 -0.2757 0.8707 +vn 0.6864 -0.5790 0.4400 +vn 0.7468 -0.6648 -0.0201 +vn -0.0657 -0.8807 -0.4691 +vn -0.0711 -0.7647 -0.6405 +vn -0.4174 -0.7873 -0.4538 +vn -0.4009 -0.8709 -0.2842 +vn 0.1602 0.9319 -0.3255 +vn 0.3962 0.8539 -0.3373 +vn 0.0455 0.0365 0.9983 +vn 0.0409 0.1763 0.9835 +vn 0.0902 -0.4785 0.8735 +vn 0.0807 -0.8430 -0.5319 +vn -0.3461 0.9382 -0.0099 +vn -0.3365 0.9120 -0.2346 +vn -0.1415 0.9498 -0.2791 +vn -0.3319 0.8261 -0.4554 +vn -0.1312 0.8574 -0.4977 +vn 0.0887 0.0768 0.9931 +vn 0.0890 0.0601 0.9942 +vn -0.0794 -0.9449 0.3177 +vn -0.0707 -0.9907 0.1160 +vn -0.3950 -0.8974 0.1965 +vn -0.4047 -0.8463 0.3464 +vn 0.0748 -0.0816 0.9939 +vn 0.0656 -0.1404 0.9879 +vn 0.0791 0.0332 0.9963 +vn -0.1402 0.5662 0.8123 +vn 0.0567 -0.9531 0.2973 +vn 0.0685 -0.9944 0.0799 +vn 0.0469 -0.8565 0.5140 +vn 0.3749 0.1852 -0.9084 +vn 0.1750 0.2008 -0.9639 +vn 0.1644 0.1388 -0.9766 +vn 0.3864 0.3214 -0.8645 +vn 0.1836 0.3467 -0.9199 +vn 0.4494 0.3134 -0.8366 +vn 0.4446 0.1811 -0.8772 +vn 0.4374 0.1250 -0.8905 +vn -0.0765 -0.6328 -0.7705 +vn -0.0810 -0.5447 -0.8347 +vn -0.4346 -0.5818 -0.6874 +vn -0.4302 -0.6733 -0.6013 +vn -0.3498 0.1233 -0.9287 +vn -0.3596 0.0711 -0.9304 +vn -0.1590 0.0732 -0.9846 +vn -0.1493 0.1264 -0.9807 +vn -0.3641 -0.0307 -0.9308 +vn -0.1638 -0.0300 -0.9860 +vn -0.4161 0.1182 -0.9016 +vn -0.0837 -0.5006 -0.8616 +vn -0.4362 -0.5278 -0.7288 +vn -0.8431 -0.0046 0.5377 +vn -0.8323 0.0351 0.5532 +vn -0.9834 -0.1179 0.1383 +vn -0.3778 0.2103 0.9017 +vn 0.8511 0.0112 -0.5249 +vn 0.8571 -0.0057 -0.5151 +vn 0.9852 0.1229 -0.1198 +vn 0.4028 -0.1898 -0.8954 +vn -0.0070 -0.1121 -0.9937 +vn -0.0062 -0.2804 -0.9599 +vn 0.0638 -0.2679 -0.9613 +vn -0.0120 -0.2822 -0.9593 +vn 0.0131 0.2838 0.9588 +vn 0.0078 0.2837 0.9589 +vn 0.0980 0.4937 0.8641 +vn 0.4351 0.5194 0.7355 +vn -0.0589 0.2744 0.9598 +vn -0.0175 -0.9988 0.0464 +vn 0.0011 -0.9990 0.0451 +vn 0.0083 -0.8307 0.5566 +vn -0.0074 -0.8319 0.5548 +vn 0.0196 -0.9988 0.0439 +vn 0.0244 -0.8325 0.5535 +vn 0.0224 -0.3208 0.9469 +vn 0.0137 -0.3192 0.9476 +vn -0.1881 -0.8257 0.5318 +vn -0.2327 -0.9707 0.0602 +vn -0.6480 -0.5674 0.5080 +vn -0.7444 -0.6626 0.0824 +vn 0.0095 -0.8784 -0.4779 +vn 0.1892 -0.8699 -0.4555 +vn 0.2335 -0.9719 0.0282 +vn -0.0040 -0.4073 -0.9133 +vn 0.0953 -0.4215 -0.9018 +vn 0.3611 -0.3509 -0.8640 +vn 0.6498 -0.6094 -0.4544 +vn 0.7467 -0.6648 -0.0201 +vn 0.0144 -0.0111 0.9998 +vn 0.0198 -0.0110 0.9997 +vn -0.0136 -0.1158 -0.9932 +vn -0.0079 -0.1156 -0.9933 +vn -0.0079 -0.1155 -0.9933 +vn -0.0125 -0.4061 -0.9137 +vn 0.0861 -0.0079 0.9963 +vn 0.0862 -0.0079 0.9962 +vn 0.1252 -0.3414 0.9316 +vn -0.9085 -0.1821 -0.3760 +vn -0.9809 -0.1772 0.0801 +vn -0.6851 -0.6205 -0.3817 +vn 0.0579 -0.1118 -0.9920 +vn 0.4099 -0.1277 -0.9031 +vn 0.4744 0.8735 -0.1096 +vn -0.0066 0.9989 -0.0464 +vn 0.0243 0.9371 0.3481 +vn 0.4490 0.7845 0.4276 +vn -0.4877 0.8724 0.0317 +vn -0.3620 0.7718 0.5227 +vn -0.0908 0.4838 0.8705 +vn 0.0623 0.5161 0.8542 +vn 0.2181 0.4896 0.8442 +vn 0.6538 0.2881 -0.6996 +vn 0.9120 0.3847 -0.1425 +vn 0.6538 0.2882 -0.6996 +vn 0.3504 0.7278 -0.5895 +vn -0.6618 0.3257 0.6752 +vn -0.9222 0.3698 0.1132 +vn -0.6611 0.0318 0.7496 +vn -0.1580 0.1650 0.9735 +vn -0.3620 0.7719 0.5227 +vn 0.0719 0.1089 0.9914 +vn 0.3056 0.1756 0.9358 +vn 0.3799 -0.3154 -0.8696 +vn -0.0207 -0.2499 -0.9681 +vn 0.0123 -0.9422 -0.3349 +vn 0.2342 -0.9324 -0.2752 +vn -0.2052 -0.9753 -0.0812 +vn 0.0123 -0.9421 -0.3350 +vn -0.2051 -0.9754 -0.0812 +vn -0.0271 -0.8173 0.5756 +vn 0.0421 -0.9149 0.4016 +vn 0.2342 -0.9324 -0.2753 +vn 0.1832 -0.9101 0.3717 +vn 0.9449 -0.2287 0.2344 +vn 0.8001 -0.4353 -0.4128 +vn 0.4661 -0.7929 0.3926 +vn 0.4255 -0.5689 0.7038 +vn 0.8000 -0.4353 -0.4128 +vn 0.4660 -0.7929 0.3926 +vn 0.3559 -0.7665 0.5345 +vn 0.3992 -0.5919 0.7002 +vn -0.9943 -0.0579 0.0891 +vn -0.7483 -0.5368 -0.3896 +vn -0.7071 -0.1306 -0.6949 +vn -0.9236 0.2952 -0.2447 +vn -0.7484 -0.5368 -0.3895 +vn -0.2122 -0.7185 -0.6623 +vn -0.2179 -0.3727 -0.9020 +vn -0.7071 -0.1306 -0.6950 +vn -0.2179 -0.3728 -0.9020 +vn -0.1909 0.1650 -0.9677 +vn -0.4541 0.3561 -0.8167 +vn -0.5748 0.5821 -0.5751 +vn 0.2065 0.7958 0.5692 +vn -0.0143 0.7888 0.6145 +vn -0.0149 0.9804 0.1965 +vn 0.1734 0.9799 0.0981 +vn -0.2318 0.7465 0.6237 +vn -0.2056 0.9535 0.2204 +vn -0.1646 0.9379 -0.3055 +vn -0.0323 0.9331 -0.3581 +vn 0.0614 0.8826 -0.4662 +vn 0.9832 -0.1335 -0.1241 +vn 0.9976 0.0271 -0.0631 +vn 0.2352 -0.2348 -0.9432 +vn 0.3087 -0.0116 0.9511 +vn 0.3157 0.3136 0.8955 +vn 0.3288 0.2167 0.9192 +vn 0.9994 0.0030 -0.0343 +vn 0.9994 0.0030 -0.0344 +vn 0.2581 -0.1822 -0.9488 +vn -0.7012 -0.6332 -0.3276 +vn -0.8280 -0.3101 -0.4672 +vn -0.2624 -0.8968 0.3562 +vn -0.9996 0.0265 -0.0042 +vn -0.2624 -0.8968 0.3563 +vn -0.8280 -0.3102 -0.4672 +vn -0.9996 0.0266 -0.0041 +vn -0.2593 0.1137 0.9591 +vn 0.5343 -0.4939 -0.6860 +vn 0.5814 -0.4549 -0.6746 +vn 0.3285 -0.9291 0.1699 +vn 0.3284 -0.9291 0.1698 +vn 0.0120 -0.9764 0.2157 +vn 0.0055 -0.0541 0.9985 +vn 0.0184 0.2370 0.9713 +vn 0.0162 0.1171 0.9930 +vn 0.3301 0.1051 0.9381 +vn -0.2553 0.2239 0.9406 +vn -0.2624 0.1161 0.9579 +vn -0.2586 0.0237 0.9657 +vn 0.0163 0.0174 0.9997 +vn 0.3256 0.0120 0.9454 +vn 0.0055 -0.0542 0.9985 +vn 0.0210 0.3439 0.9388 +vn -0.2366 0.3185 0.9179 +vn -0.0174 -0.2214 -0.9750 +vn -0.3165 -0.2238 -0.9218 +vn -0.0150 -0.1787 -0.9838 +vn -0.3313 -0.1737 -0.9274 +vn -0.9961 0.0676 0.0572 +vn -0.9961 0.0676 0.0573 +vn -0.9960 0.0380 0.0802 +vn -0.9960 0.0381 0.0803 +vn -0.3308 -0.0204 -0.9435 +vn -0.0147 -0.0260 -0.9996 +vn -0.0163 0.0758 -0.9970 +vn -0.3298 0.0736 -0.9412 +vn 0.2599 -0.0248 -0.9653 +vn 0.2554 0.0728 -0.9641 +vn 0.2638 0.2169 -0.9399 +vn -0.0173 0.2341 -0.9721 +vn -0.3421 0.2135 -0.9151 +vn -0.0140 -0.1037 -0.9945 +vn -0.3347 -0.0957 -0.9375 +vn 0.2647 -0.1035 -0.9588 +vn -0.0140 -0.1038 -0.9945 +vn -0.3347 -0.0956 -0.9375 +vn -0.9965 0.0198 0.0815 +vn -0.9965 0.0197 0.0815 +vn -0.9968 0.0083 0.0792 +vn -0.9968 0.0083 0.0791 +vn 0.9995 -0.0164 -0.0282 +vn 0.9995 -0.0163 -0.0283 +vn 0.9993 -0.0201 -0.0328 +vn 0.9993 -0.0200 -0.0327 +vn 0.9995 -0.0293 -0.0138 +vn 0.9555 -0.2587 -0.1419 +vn 0.2898 0.2633 -0.9201 +vn 0.3332 -0.2383 0.9123 +vn 0.3619 -0.5105 0.7800 +vn 0.9554 -0.2588 -0.1419 +vn 0.2571 -0.8047 0.5351 +vn 0.5977 -0.6870 -0.4132 +vn 0.2122 0.0122 -0.9771 +vn -0.9958 0.0056 0.0914 +vn -0.2525 -0.0717 0.9649 +vn -0.9958 0.0056 0.0915 +vn -0.9937 -0.0326 0.1076 +vn -0.2601 -0.2316 0.9374 +vn 0.9996 -0.0097 -0.0262 +vn 0.3229 -0.0816 0.9429 +vn 0.9996 -0.0097 -0.0263 +vn 0.0181 -0.0800 0.9966 +vn 0.0198 -0.2385 0.9709 +vn -0.2845 -0.0116 -0.9586 +vn -0.0288 -0.0403 -0.9988 +vn -0.0126 -0.8911 -0.4537 +vn -0.6211 -0.7139 -0.3234 +vn 0.5978 -0.6870 -0.4132 +vn -0.0126 -0.8911 -0.4536 +vn 0.0119 -0.8446 0.5353 +vn -0.6212 -0.7138 -0.3234 +vn -0.2132 -0.7978 0.5639 +vn 0.0178 -0.4754 0.8796 +vn -0.2904 -0.4997 0.8160 +vn -0.0180 0.3423 -0.9394 +vn -0.3736 0.2397 -0.8961 +vn -0.9596 -0.2801 -0.0254 +vn 0.7321 0.5503 0.4016 +vn 0.9884 0.1032 -0.1114 +vn 0.1859 0.7057 0.6837 +vn 0.7320 0.5503 0.4016 +vn 0.7337 0.6228 0.2718 +vn 0.7337 0.6228 0.2717 +vn 0.9696 0.1520 -0.1919 +vn -0.7220 -0.5403 -0.4322 +vn -0.9911 -0.1044 0.0829 +vn -0.1887 -0.6932 -0.6957 +vn 0.0254 -0.6815 -0.7313 +vn 0.2315 -0.6392 -0.7334 +vn 0.2298 -0.6514 -0.7231 +vn 0.0118 -0.7045 -0.7096 +vn -0.0266 0.6976 0.7160 +vn -0.2384 0.6570 0.7152 +vn 0.0287 -0.5331 0.8456 +vn 0.0559 -0.4708 0.8805 +vn 0.0672 0.1125 0.9914 +vn -0.1386 0.0395 0.9896 +vn 0.1328 -0.3964 0.9084 +vn 0.3106 0.1462 0.9392 +vn 0.0671 0.1125 0.9914 +vn 0.3699 0.6156 0.6959 +vn 0.0378 0.6309 0.7749 +vn -0.2836 0.5440 0.7897 +vn -0.0586 -0.6243 0.7790 +vn -0.0283 -0.5773 0.8161 +vn -0.4761 -0.1878 0.8591 +vn -0.5855 -0.4898 0.6460 +vn -0.7529 0.1872 0.6310 +vn -0.7528 0.1872 0.6310 +vn -0.9194 -0.2191 0.3267 +vn 0.2724 0.6510 -0.7085 +vn 0.1701 0.7711 -0.6136 +vn 0.4919 0.7959 -0.3529 +vn 0.5699 0.5323 -0.6260 +vn 0.1572 0.9779 -0.1378 +vn 0.1572 0.9779 -0.1379 +vn 0.3140 0.8663 0.3885 +vn 0.7837 0.6201 0.0356 +vn 0.4919 0.7959 -0.3530 +vn 0.9165 0.2267 -0.3296 +vn -0.0287 0.2059 -0.9781 +vn -0.0429 -0.1008 -0.9940 +vn -0.2971 -0.1414 -0.9443 +vn 0.0851 0.3349 -0.9384 +vn 0.1663 -0.0078 -0.9860 +vn 0.1663 -0.0079 -0.9860 +vn 0.2950 -0.5270 -0.7970 +vn -0.0252 -0.6245 -0.7806 +vn -0.3575 -0.6200 -0.6984 +vn -0.0034 -0.3467 -0.9380 +vn 0.1978 -0.2382 -0.9509 +vn -0.0034 -0.3468 -0.9379 +vn 0.5256 0.8207 -0.2239 +vn 0.7362 0.4508 -0.5048 +vn 0.7362 0.4508 -0.5047 +vn -0.5793 -0.4330 0.6906 +vn -0.3913 -0.2473 0.8864 +vn 0.0148 -0.6054 0.7958 +vn -0.0513 -0.6063 0.7936 +vn -0.1512 0.0928 0.9841 +vn 0.0199 -0.5656 0.8244 +vn 0.0236 0.2333 0.9721 +vn 0.0402 -0.4854 0.8734 +vn 0.1116 -0.4163 0.9023 +vn -0.0111 0.8747 0.4845 +vn 0.0128 0.7678 0.6406 +vn 0.3522 0.7554 0.5525 +vn -0.3325 0.8043 0.4924 +vn -0.3190 0.6885 0.6514 +vn -0.0128 -0.7645 -0.6446 +vn -0.3515 -0.7570 -0.5508 +vn 0.3181 -0.6804 -0.6603 +vn 0.3260 -0.8004 -0.5030 +vn 0.0025 -0.8714 -0.4905 +vn -0.3261 -0.8627 -0.3866 +vn -0.9995 0.0318 0.0094 +vn -0.8519 -0.3615 -0.3788 +vn -0.8404 -0.5020 -0.2040 +vn -0.9789 -0.1051 0.1755 +vn -0.8404 -0.5020 -0.2041 +vn -0.7908 -0.6110 -0.0354 +vn 0.8460 0.4960 0.1955 +vn 0.9771 0.0913 -0.1924 +vn 0.8641 0.3462 0.3654 +vn 0.9981 -0.0538 -0.0301 +vn -0.0400 0.9972 -0.0628 +vn -0.2703 0.9628 -0.0045 +vn -0.0400 0.9972 -0.0629 +vn -0.5749 0.5821 -0.5750 +vn -0.7074 0.0614 -0.7041 +vn -0.8227 0.4039 -0.3999 +vn -0.7075 0.0614 -0.7041 +vn 0.6889 -0.7144 0.1227 +vn 0.8302 -0.3909 0.3974 +vn 0.2863 -0.9575 -0.0355 +vn 0.2863 -0.9575 -0.0356 +vn 0.8159 -0.4753 -0.3293 +vn 0.8303 -0.3909 0.3974 +vn 0.6888 -0.7145 0.1227 +vn 0.0344 -0.9994 0.0017 +vn -0.1908 -0.9760 0.1048 +vn -0.0360 0.4127 0.9101 +vn 0.1456 0.3817 0.9127 +vn -0.2199 0.3668 0.9039 +vn 0.0351 -0.4504 -0.8922 +vn -0.1327 -0.4805 -0.8669 +vn 0.2018 -0.4763 -0.8558 +vn -0.5153 -0.8516 0.0961 +vn -0.3187 -0.8941 -0.3147 +vn -0.6142 -0.5285 -0.5861 +vn -0.9476 -0.3195 0.0013 +vn -0.6141 -0.5285 -0.5861 +vn 0.4269 -0.6548 0.6237 +vn 0.6875 0.1351 0.7135 +vn 0.9640 -0.2521 0.0848 +vn 0.6876 0.1351 0.7134 +vn -0.0233 0.1890 0.9817 +vn -0.0278 0.1889 0.9816 +vn 0.0419 0.1943 0.9801 +vn 0.0462 0.1944 0.9798 +vn 0.3876 0.1911 0.9018 +vn 0.3917 0.1907 0.9001 +vn -0.0557 0.1011 0.9933 +vn -0.1191 0.0138 0.9928 +vn -0.1124 0.1544 0.9816 +vn -0.4637 0.1074 0.8795 +vn -0.4665 -0.1449 0.8726 +vn -0.2253 -0.3010 -0.9266 +vn -0.1083 -0.2042 -0.9729 +vn -0.1294 -0.1803 -0.9751 +vn -0.4016 -0.1768 -0.8986 +vn -0.4086 -0.1730 -0.8962 +vn 0.1187 -0.3872 -0.9143 +vn 0.1427 -0.2610 -0.9547 +vn 0.4684 -0.1978 -0.8611 +vn 0.4644 -0.4263 -0.7762 +vn -0.9985 -0.0390 -0.0390 +vn -0.8680 -0.1140 -0.4833 +vn -0.8659 -0.1145 -0.4869 +vn -0.9983 -0.0398 -0.0433 +vn 0.9986 0.0382 0.0377 +vn 0.8680 0.1222 0.4812 +vn 0.8660 0.1228 0.4847 +vn 0.9984 0.0390 0.0419 +vn -0.0291 0.1843 0.9824 +vn -0.0335 0.1842 0.9823 +vn -0.0347 0.1792 0.9832 +vn -0.0391 0.1791 0.9830 +vn 0.0036 -0.9946 -0.1039 +vn 0.2056 -0.9622 -0.1787 +vn -0.1870 -0.9651 -0.1833 +vn -0.2556 -0.9647 0.0635 +vn -0.0046 -0.9913 0.1316 +vn 0.2055 -0.9622 -0.1786 +vn 0.2582 -0.9634 0.0716 +vn 0.0501 0.1388 0.9891 +vn 0.6191 0.3217 0.7164 +vn 0.6191 0.3216 0.7164 +vn 0.8488 0.0889 0.5212 +vn 0.1029 -0.2943 0.9502 +vn 0.0104 0.0325 0.9994 +vn 0.0001 0.1359 0.9907 +vn 0.0059 0.1394 0.9902 +vn -0.0099 0.1787 0.9838 +vn -0.0044 0.1834 0.9830 +vn 0.8851 0.0874 0.4571 +vn 0.9996 0.0257 0.0091 +vn 0.4193 0.1397 0.8970 +vn 0.4089 0.1837 0.8939 +vn 0.8773 0.1155 0.4658 +vn 0.9992 0.0338 0.0199 +vn -0.8784 -0.0829 -0.4707 +vn -0.9995 -0.0276 -0.0152 +vn -0.4322 -0.1256 -0.8930 +vn -0.4253 -0.1662 -0.8897 +vn -0.8764 -0.1082 -0.4693 +vn -0.9992 -0.0350 -0.0211 +vn -0.3592 -0.1298 -0.9242 +vn -0.1598 -0.1305 -0.9785 +vn -0.3593 -0.1298 -0.9242 +vn -0.1503 -0.1730 -0.9734 +vn -0.4253 -0.1662 -0.8896 +vn -0.4323 -0.1256 -0.8930 +vn 0.0751 0.1430 0.9869 +vn 0.0654 0.1885 0.9799 +vn -0.0264 0.1796 0.9834 +vn -0.0965 0.1732 0.9801 +vn -0.1051 0.1728 0.9793 +vn -0.4443 0.1434 0.8843 +vn -0.4522 0.1425 0.8805 +vn 0.3769 -0.1752 -0.9096 +vn 0.3783 -0.1660 -0.9107 +vn 0.1812 -0.1849 -0.9659 +vn 0.1870 -0.1860 -0.9646 +vn 0.4601 -0.1591 -0.8735 +vn 0.4671 -0.1585 -0.8699 +vn -0.3414 0.1832 -0.9219 +vn -0.1387 0.1893 -0.9721 +vn -0.4047 0.1768 -0.8972 +vn 0.1563 0.0831 -0.9842 +vn 0.4290 0.0756 -0.9001 +vn -0.0111 -0.2001 0.9797 +vn 0.0558 -0.2035 0.9775 +vn 0.3941 -0.1921 0.8988 +vn -0.8612 0.1034 -0.4977 +vn -0.9989 0.0182 -0.0437 +vn -0.8611 0.1034 -0.4977 +vn -0.8698 0.0692 -0.4885 +vn 0.8718 -0.1102 0.4774 +vn 0.9994 -0.0173 0.0302 +vn -0.0171 -0.1957 0.9805 +vn 0.2826 -0.2968 -0.9122 +vn 0.6693 -0.5527 -0.4965 +vn 0.8459 -0.1006 -0.5238 +vn 0.8247 -0.5462 -0.1466 +vn 0.8247 -0.5462 -0.1467 +vn 0.9592 -0.0538 -0.2776 +vn -0.0723 -0.0714 0.9948 +vn -0.4202 -0.0637 0.9052 +vn -0.3271 0.6832 -0.6529 +vn -0.1247 0.7104 -0.6926 +vn -0.4030 0.6623 -0.6316 +vn -0.8693 0.3750 -0.3219 +vn -0.9990 0.0362 0.0259 +vn 0.8889 -0.3584 0.2853 +vn 0.9986 -0.0181 -0.0499 +vn 0.3910 -0.6713 0.6297 +vn -0.8300 0.2913 -0.4756 +vn -0.8367 0.1972 -0.5110 +vn -0.8225 0.3525 -0.4464 +vn -0.9402 0.2153 -0.2638 +vn -0.9404 0.1811 -0.2879 +vn -0.9418 0.1251 -0.3121 +vn -0.0304 -0.7083 0.7053 +vn -0.0252 -0.7097 0.7041 +vn -0.1041 -0.5027 0.8581 +vn -0.4516 -0.4451 0.7732 +vn 0.0403 -0.7129 0.7001 +vn 0.3883 0.4734 -0.7906 +vn 0.1877 0.5077 -0.8408 +vn 0.4517 0.4588 -0.7651 +vn 0.6135 -0.5438 -0.5727 +vn 0.6393 -0.1455 -0.7551 +vn 0.2416 -0.8987 -0.3661 +vn 0.6134 -0.5438 -0.5727 +vn 0.0875 -0.7254 -0.6828 +vn 0.1701 -0.3305 -0.9283 +vn 0.6392 -0.1455 -0.7551 +vn 0.1414 -0.1862 -0.9723 +vn 0.5562 0.8054 0.2051 +vn 0.5731 0.7388 0.3547 +vn 0.5561 0.8287 0.0632 +vn 0.0982 0.9535 0.2850 +vn 0.1015 0.8822 0.4597 +vn 0.5731 0.7387 0.3547 +vn 0.1077 0.7744 0.6234 +vn -0.9354 0.3372 -0.1063 +vn -0.9309 0.3642 0.0285 +vn -0.5802 0.7963 -0.1713 +vn -0.5731 0.7253 -0.3814 +vn -0.9218 0.3435 0.1794 +vn -0.5860 0.8090 0.0450 +vn -0.5803 0.7962 -0.1713 +vn -0.1091 0.9911 -0.0768 +vn -0.0966 0.9519 -0.2907 +vn -0.5731 0.7253 -0.3813 +vn -0.0854 0.8595 -0.5040 +vn -0.9501 -0.0650 -0.3052 +vn -0.6063 -0.1187 -0.7863 +vn -0.6037 -0.1574 -0.7815 +vn -0.9507 -0.0194 -0.3094 +vn -0.6068 -0.0291 -0.7943 +vn -0.6067 -0.0292 -0.7944 +vn -0.1164 -0.0295 -0.9928 +vn -0.1118 -0.1331 -0.9848 +vn -0.1118 -0.1330 -0.9848 +vn -0.1020 -0.1771 -0.9789 +vn -0.9490 0.0512 -0.3111 +vn -0.9454 0.0737 -0.3173 +vn -0.5894 0.1643 -0.7909 +vn -0.6023 0.1107 -0.7905 +vn -0.5767 0.2872 -0.7649 +vn -0.5895 0.1642 -0.7909 +vn -0.5766 0.2872 -0.7649 +vn -0.0840 0.3455 -0.9346 +vn -0.0924 0.1968 -0.9761 +vn -0.6024 0.1107 -0.7905 +vn -0.1032 0.1325 -0.9858 +vn 0.5891 0.7404 -0.3236 +vn 0.5712 0.7946 -0.2055 +vn 0.6001 0.6620 -0.4489 +vn 0.6002 0.6620 -0.4489 +vn 0.1302 0.8465 -0.5162 +vn 0.1166 0.9405 -0.3193 +vn 0.5713 0.7946 -0.2055 +vn 0.1056 0.9866 -0.1243 +vn -0.9506 0.0275 -0.3093 +vn -0.6067 0.0629 -0.7925 +vn -0.6067 0.0629 -0.7924 +vn -0.1127 0.0770 -0.9906 +vn 0.8488 0.0890 0.5212 +vn 0.9214 0.3819 0.0726 +vn 0.6214 0.6154 0.4848 +vn 0.5901 0.3627 0.7212 +vn 0.6214 0.6155 0.4848 +vn 0.1206 0.6564 0.7447 +vn 0.5901 0.3627 0.7213 +vn 0.1275 0.5667 0.8140 +vn 0.6050 0.0632 -0.7937 +vn 0.6148 0.1038 -0.7818 +vn 0.5992 -0.0167 -0.8004 +vn 0.6051 0.0632 -0.7937 +vn 0.5993 -0.0167 -0.8004 +vn 0.1057 -0.0275 -0.9940 +vn 0.1091 0.0804 -0.9908 +vn 0.6148 0.1037 -0.7818 +vn 0.1184 0.1362 -0.9836 +vn 0.9564 0.0921 -0.2773 +vn 0.9554 0.0490 -0.2913 +vn 0.6167 0.1538 -0.7721 +vn 0.6162 0.2714 -0.7394 +vn 0.1284 0.1997 -0.9714 +vn 0.1363 0.3466 -0.9280 +vn 0.8088 0.5217 0.2715 +vn 0.8088 0.5217 0.2716 +vn 0.8045 0.5562 -0.2083 +vn 0.3458 0.9383 -0.0090 +vn 0.8991 0.3566 -0.2539 +vn -0.8336 0.1163 -0.5399 +vn -0.8344 0.0800 -0.5454 +vn -0.8337 0.1163 -0.5399 +vn -0.8344 0.0799 -0.5454 +vn -0.8236 0.5655 -0.0442 +vn -0.8310 0.5129 -0.2153 +vn -0.8192 0.5544 0.1466 +vn -0.8236 0.5654 -0.0441 +vn -0.8192 0.5545 0.1466 +vn -0.8064 0.4866 0.3360 +vn -0.9035 0.2760 0.3279 +vn 0.8450 -0.0521 -0.5322 +vn 0.3689 -0.1612 -0.9154 +vn 0.8449 -0.0723 -0.5300 +vn 0.9553 -0.0242 -0.2947 +vn 0.9527 -0.0175 -0.3035 +vn 0.8614 0.2536 -0.4401 +vn 0.8566 0.3042 -0.4167 +vn 0.8623 0.1688 -0.4775 +vn 0.8622 0.1688 -0.4775 +vn 0.9584 0.1380 -0.2497 +vn 0.8567 0.3042 -0.4166 +vn 0.9592 0.1610 -0.2324 +vn 0.8515 0.0973 -0.5152 +vn 0.8515 0.0974 -0.5152 +vn 0.8630 0.3353 -0.3779 +vn 0.9552 0.1837 -0.2320 +vn -0.8405 -0.0920 -0.5339 +vn -0.3641 -0.0307 -0.9309 +vn -0.8456 -0.0248 -0.5333 +vn -0.8307 0.4205 -0.3649 +vn -0.8307 0.4204 -0.3648 +vn -0.9388 0.2695 -0.2146 +vn -0.8413 0.0441 -0.5388 +vn -0.1147 0.7164 0.6882 +vn -0.0033 0.7511 0.6601 +vn -0.0072 0.8659 0.5002 +vn -0.1163 0.8375 0.5340 +vn -0.0098 0.9459 0.3243 +vn -0.1191 0.9253 0.3602 +vn -0.1112 0.5041 0.8565 +vn -0.0015 0.5051 0.8630 +vn 0.0011 0.6285 0.7778 +vn -0.1207 0.5849 0.8021 +vn -0.0001 0.9948 -0.1020 +vn 0.0109 0.9517 -0.3070 +vn 0.0239 0.8581 -0.5129 +vn -0.0079 0.9927 0.1202 +vn -0.1172 0.9812 0.1532 +vn 0.0989 0.9912 0.0876 +vn 0.1056 0.9866 -0.1244 +vn -0.0762 0.6055 -0.7922 +vn 0.0341 0.6076 -0.7935 +vn 0.0313 0.5129 -0.8579 +vn -0.0795 0.5101 -0.8564 +vn 0.1429 0.6020 -0.7856 +vn 0.1407 0.5089 -0.8492 +vn 0.0270 0.3484 -0.9370 +vn 0.0076 0.1352 -0.9908 +vn -0.0017 0.0791 -0.9969 +vn -0.0051 -0.0287 -0.9996 +vn -0.0849 -0.1882 -0.9785 +vn 0.0289 -0.1863 -0.9821 +vn 0.0325 -0.2496 -0.9678 +vn -0.1072 -0.3365 -0.9356 +vn 0.0237 -0.7327 -0.6801 +vn -0.0386 -0.7253 -0.6873 +vn -0.0005 -0.1334 -0.9911 +vn 0.1106 -0.1322 -0.9850 +vn 0.1211 -0.1763 -0.9769 +vn 0.0096 -0.1779 -0.9840 +vn 0.0183 0.1995 -0.9797 +vn 0.0327 0.7150 -0.6983 +vn -0.0772 0.7151 -0.6947 +vn 0.1403 0.7064 -0.6938 +vn 0.6229 0.3984 -0.6733 +vn 0.6279 0.4681 -0.6218 +vn 0.6228 0.3984 -0.6733 +vn 0.6279 0.4682 -0.6218 +vn -0.5694 0.5723 0.5901 +vn -0.5760 0.6788 0.4555 +vn -0.5664 0.4473 0.6922 +vn -0.5694 0.5724 0.5901 +vn -0.5664 0.4473 0.6921 +vn -0.5759 0.6789 0.4554 +vn 0.0020 -0.9986 -0.0521 +vn -0.2135 -0.9017 -0.3759 +vn -0.2136 -0.9017 -0.3760 +vn 0.6126 0.5516 -0.5660 +vn -0.5731 0.5990 -0.5593 +vn -0.5781 0.4996 -0.6451 +vn -0.5983 -0.1636 -0.7844 +vn -0.5999 -0.1841 -0.7786 +vn -0.5982 -0.1636 -0.7844 +vn -0.0915 -0.1836 -0.9787 +vn -0.5999 -0.1842 -0.7786 +vn 0.0301 0.0192 0.9994 +vn -0.4601 0.0985 0.8824 +vn 0.0302 0.0192 0.9994 +vn -0.4601 0.0984 0.8824 +vn -0.5753 0.4215 -0.7010 +vn 0.5606 0.8249 -0.0727 +vn 0.6070 -0.0937 -0.7892 +vn 0.6190 -0.1244 -0.7755 +vn 0.6070 -0.0937 -0.7891 +vn -0.5828 0.7666 0.2695 +vn -0.5860 0.8090 0.0449 +vn -0.5722 0.2782 0.7715 +vn -0.5721 0.2783 0.7715 +vn -0.7967 -0.5795 -0.1717 +vn -0.5627 -0.5675 -0.6011 +vn -0.7967 -0.5794 -0.1717 +vn 0.0205 -0.1841 -0.9827 +vn 0.1319 -0.1826 -0.9743 +vn 0.9572 -0.0240 -0.2884 +vn 0.6272 -0.1277 -0.7684 +vn 0.6271 -0.1277 -0.7684 +vn 0.8485 -0.0740 -0.5240 +vn 0.1742 -0.2115 -0.9617 +vn 0.4680 -0.1620 -0.8688 +vn -0.1099 0.1723 0.9789 +vn -0.4563 0.1419 0.8784 +vn -0.0209 0.1845 0.9826 +vn -0.0150 0.1893 0.9818 +vn 0.8718 0.1210 0.4747 +vn 0.9989 0.0367 0.0302 +vn 0.3987 0.1904 0.8971 +vn -0.8719 -0.1129 -0.4765 +vn -0.9988 -0.0377 -0.0310 +vn -0.4163 -0.1723 -0.8927 +vn -0.1396 -0.1790 -0.9739 +vn -0.4163 -0.1724 -0.8928 +vn 0.0540 0.1946 0.9794 +vn -0.6305 -0.5867 -0.5082 +vn -0.6305 -0.5868 -0.5081 +vn -0.4345 0.1397 0.8898 +vn -0.8976 0.0473 0.4383 +vn -0.9020 0.0475 0.4290 +vn -0.9057 0.0460 0.4215 +vn 0.4495 -0.1549 -0.8797 +vn 0.8962 -0.0575 -0.4400 +vn 0.9016 -0.0573 -0.4288 +vn 0.9052 -0.0557 -0.4213 +vn 0.8514 0.4049 -0.3333 +vn 0.8688 0.3269 -0.3720 +vn 0.8514 0.4049 -0.3334 +vn 0.8687 0.3269 -0.3720 +vn 0.8861 0.2701 -0.3767 +vn 0.8861 0.2701 -0.3768 +vn -0.8856 -0.3426 0.3135 +vn -0.8971 -0.2811 0.3408 +vn -0.8986 -0.2494 0.3611 +vn 0.8899 0.1515 -0.4303 +vn 0.8922 0.0838 -0.4438 +vn 0.8909 0.0575 -0.4506 +vn -0.4522 -0.2946 0.8419 +vn -0.9127 -0.1284 0.3880 +vn -0.9039 -0.0717 0.4216 +vn -0.8953 -0.0481 0.4428 +vn -0.8952 0.0031 0.4457 +vn -0.8955 0.0343 0.4438 +vn -0.4269 0.1057 0.8981 +vn 0.4279 -0.0222 -0.9036 +vn 0.8817 -0.0039 -0.4718 +vn 0.8880 -0.0440 -0.4577 +vn 0.9071 -0.0549 -0.4174 +vn 0.4680 -0.1620 -0.8687 +vn 0.9094 -0.1079 -0.4017 +vn 0.4685 -0.1978 -0.8611 +vn -0.9076 0.0452 0.4173 +vn -0.4564 0.1420 0.8784 +vn -0.9083 -0.0105 0.4182 +vn 0.6766 -0.4988 -0.5417 +vn 0.3496 -0.8900 -0.2927 +vn 0.7576 -0.2966 -0.5814 +vn 0.7577 -0.2966 -0.5814 +vn -0.4572 -0.6838 0.5686 +vn -0.7482 0.0740 0.6594 +vn -0.4572 -0.6839 0.5685 +vn -0.7482 0.0740 0.6593 +vn -0.7627 0.2749 0.5854 +vn 0.3077 -0.4551 0.8356 +vn 0.7165 -0.0563 0.6953 +vn -0.4068 0.8118 -0.4188 +vn -0.6764 0.7240 -0.1355 +vn -0.8263 0.4671 0.3147 +vn -0.8263 0.4670 0.3147 +vn 0.7549 -0.1739 -0.6324 +vn 0.8042 -0.3282 -0.4956 +vn 0.7548 -0.1740 -0.6324 +vn 0.8042 -0.3281 -0.4956 +vn -0.8116 0.3257 0.4849 +vn -0.7547 -0.6501 0.0889 +vn -0.1416 -0.7167 0.6829 +vn -0.7547 -0.6500 0.0890 +vn -0.1417 -0.7167 0.6829 +vn -0.0810 -0.7082 0.7013 +vn 0.7302 -0.3507 -0.5864 +vn 0.5610 0.1117 -0.8202 +vn 0.7302 -0.3507 -0.5863 +vn 0.5611 0.1117 -0.8202 +vn 0.2069 0.5213 -0.8279 +vn 0.4880 0.2277 -0.8426 +vn 0.4880 0.2277 -0.8427 +vn -0.5263 -0.7713 0.3580 +vn -0.5263 -0.7712 0.3580 +vn -0.7675 0.3185 0.5563 +vn -0.7564 0.3757 0.5355 +vn -0.7675 0.3185 0.5564 +vn -0.7467 0.4596 0.4807 +vn -0.7467 0.4597 0.4808 +vn 0.7396 -0.3446 -0.5782 +vn 0.7314 -0.3828 -0.5644 +vn 0.7396 -0.3446 -0.5781 +vn -0.6467 0.7605 0.0579 +vn -0.4068 0.8118 -0.4189 +vn -0.6467 0.7605 0.0578 +vn 0.6777 0.0969 0.7289 +vn 0.2562 -0.4719 0.8436 +vn -0.8113 -0.0160 -0.5844 +vn -0.7947 0.2844 -0.5363 +vn -0.8113 -0.0159 -0.5844 +vn -0.4601 0.7364 -0.4961 +vn 0.8077 0.0586 0.5867 +vn 0.7853 0.3483 0.5119 +vn 0.7853 0.3482 0.5120 +vn 0.4490 0.7845 0.4277 +vn -0.0364 0.9004 -0.4335 +vn -0.4877 0.8724 0.0318 +vn -0.8576 -0.0055 0.5143 +vn -0.8595 -0.1292 0.4945 +vn -0.4083 -0.0426 0.9119 +vn -0.6481 -0.5674 0.5080 +vn -0.3609 -0.2707 0.8925 +vn 0.2102 -0.8328 0.5122 +vn 0.2335 -0.9720 0.0281 +vn -0.0227 -0.8793 -0.4758 +vn -0.2099 -0.8762 -0.4337 +vn -0.0063 -0.8776 -0.4793 +vn 0.0011 -0.9990 0.0452 +vn 0.8979 0.2433 0.3669 +vn 0.8888 0.3472 0.2993 +vn 0.8979 0.2433 0.3668 +vn 0.8887 0.3472 0.2993 +vn -0.9173 -0.2466 -0.3126 +vn -0.8955 -0.3484 -0.2770 +vn -0.9173 -0.2465 -0.3127 +vn 0.3952 -0.0504 -0.9172 +vn 0.8591 -0.0178 -0.5115 +vn 0.8629 -0.1598 -0.4794 +vn 0.6498 -0.6093 -0.4544 +vn -0.8348 -0.3508 0.4244 +vn 0.8448 -0.4440 -0.2985 +vn 0.4651 -0.8705 0.1614 +vn 0.8448 -0.4441 -0.2986 +vn -0.8937 -0.0299 0.4477 +vn -0.4448 -0.5305 0.7216 +vn -0.9085 -0.2002 0.3668 +vn 0.8896 0.2273 -0.3962 +vn 0.8899 0.1516 -0.4303 +vn 0.8844 0.0378 -0.4652 +vn -0.8399 -0.4746 0.2634 +vn -0.8621 -0.4182 0.2862 +vn -0.8398 -0.4747 0.2634 +vn -0.8621 -0.4181 0.2862 +vn 0.8099 0.5290 -0.2535 +vn 0.8327 0.4716 -0.2902 +vn 0.8326 0.4717 -0.2903 +vn -0.8130 -0.5542 0.1787 +vn -0.8212 -0.5216 0.2315 +vn -0.3924 -0.9190 0.0369 +vn -0.3949 -0.8974 0.1965 +vn -0.8400 -0.5425 0.0107 +vn -0.8186 -0.5646 0.1058 +vn -0.8130 -0.5542 0.1788 +vn 0.8261 0.5620 0.0423 +vn 0.8042 0.5914 -0.0599 +vn 0.8260 0.5620 0.0423 +vn 0.8042 0.5914 -0.0598 +vn 0.7960 0.5890 -0.1393 +vn 0.3894 0.9090 0.1485 +vn 0.7977 0.5680 -0.2025 +vn 0.8773 0.4335 0.2060 +vn 0.8551 0.5001 0.1368 +vn -0.8903 -0.3858 -0.2417 +vn -0.8824 -0.4328 -0.1846 +vn -0.8654 -0.4916 -0.0963 +vn -0.8654 -0.4917 -0.0963 +vn 0.8867 0.3836 0.2581 +vn 0.8867 0.3836 0.2582 +vn 0.3899 -0.0433 -0.9199 +vn 0.8526 0.0051 -0.5226 +vn -0.8528 -0.0016 0.5222 +vn -0.8158 0.0708 -0.5740 +vn -0.8051 -0.0266 -0.5925 +vn -0.7258 0.6669 -0.1687 +vn -0.8322 0.4031 -0.3807 +vn -0.8323 0.4030 -0.3807 +vn 0.7215 -0.6590 0.2124 +vn 0.7446 -0.4503 0.4928 +vn 0.7822 -0.0978 0.6152 +vn 0.7822 -0.0978 0.6153 +vn 0.7984 0.0183 0.6019 +vn 0.6793 -0.7189 -0.1473 +vn 0.7130 -0.6983 0.0638 +vn 0.7130 -0.6983 0.0637 +vn -0.6246 0.5386 0.5654 +vn -0.6557 0.6192 0.4320 +vn -0.6246 0.5386 0.5655 +vn -0.7041 0.6808 0.2017 +vn -0.7041 0.6808 0.2018 +vn -0.7226 0.6910 -0.0190 +vn -0.7226 0.6910 -0.0191 +vn -0.6680 0.4271 0.6095 +vn -0.6374 0.4747 0.6069 +vn -0.6680 0.4270 0.6095 +vn 0.7288 -0.3592 -0.5829 +vn 0.6456 -0.4633 -0.6071 +vn 0.7289 -0.3592 -0.5829 +vn 0.6040 -0.5640 -0.5631 +vn 0.6251 -0.6701 -0.4002 +vn 0.6793 -0.7189 -0.1474 +vn -0.3913 -0.2472 0.8864 +vn -0.6779 0.3509 0.6460 +vn -0.6780 0.3508 0.6459 +vn -0.7659 0.2897 0.5739 +vn -0.7660 0.2897 0.5739 +vn 0.8321 -0.1970 -0.5185 +vn 0.7531 -0.3045 -0.5832 +vn 0.7530 -0.3045 -0.5832 +vn -0.1467 -0.9842 -0.0990 +vn -0.4576 -0.8818 0.1146 +vn 0.4268 -0.6549 0.6237 +vn 0.1457 -0.9013 0.4079 +usemtl Scene_-_Root +s off +f 35872/35863/25897 35874/35864/25898 35875/35865/25899 +s 1 +f 35863/35866/25900 35864/35867/25901 35865/35868/25902 +f 35863/35866/25900 35865/35868/25902 35866/35869/25903 +f 35864/35867/25901 35867/35870/25904 35868/35871/25905 +f 35864/35867/25901 35868/35871/25905 35865/35868/25902 +f 35865/35868/25902 35868/35871/25905 35869/35872/25906 +f 35865/35868/25902 35869/35872/25906 35870/35873/25907 +f 35866/35869/25903 35865/35868/25902 35870/35873/25907 +f 35866/35869/25903 35870/35873/25907 35871/35874/25908 +f 35872/35863/25909 35873/35875/25910 35874/35864/25911 +f 35873/35875/25910 35876/35876/25912 35877/35877/25913 +f 35873/35875/25910 35877/35877/25913 35874/35864/25911 +f 35874/35864/25911 35877/35877/25913 35878/35878/25914 +f 35874/35864/25911 35878/35878/25914 35879/35879/25915 +f 35875/35865/25916 35874/35864/25911 35879/35879/25915 +f 35875/35865/25916 35879/35879/25915 35880/35880/25917 +f 35881/35881/25918 35882/35882/25919 35883/35883/25920 +f 35881/35881/25918 35883/35883/25920 35884/35884/25921 +f 35882/35882/25919 35885/35885/25922 35886/35886/25923 +f 35882/35882/25919 35886/35886/25923 35883/35883/25920 +f 35883/35883/25920 35886/35886/25923 35887/35887/25924 +f 35883/35883/25920 35887/35887/25924 35888/35888/25925 +f 35884/35884/25921 35883/35883/25920 35888/35888/25925 +f 35884/35884/25921 35888/35888/25925 35889/35889/25926 +f 35890/35890/25927 35891/35891/25928 35892/35892/25929 +f 35890/35890/25927 35892/35892/25929 35893/35893/25930 +f 35891/35891/25928 35894/35894/25931 35895/35895/25932 +f 35891/35891/25928 35895/35895/25932 35892/35892/25929 +f 35892/35892/25929 35895/35895/25932 35896/35896/25933 +f 35892/35892/25929 35896/35896/25933 35897/35897/25934 +f 35893/35893/25930 35892/35892/25929 35897/35897/25934 +f 35893/35893/25930 35897/35897/25934 35898/35898/25935 +f 35899/35899/25936 35900/35900/25937 35901/35901/25938 +f 35899/35899/25936 35901/35901/25938 35902/35902/25939 +f 35900/35900/25937 35872/35863/25909 35903/35903/25940 +f 35900/35900/25937 35903/35903/25940 35901/35901/25938 +f 35904/35904/25941 35905/35905/25940 35906/35906/25942 +f 35904/35904/25941 35906/35906/25942 35907/35907/25943 +f 35908/35908/25944 35904/35904/25941 35907/35907/25943 +f 35908/35908/25944 35907/35907/25943 35909/35909/25945 +f 35910/35910/25946 35911/35911/25947 35912/35912/25948 +f 35910/35910/25946 35912/35912/25948 35913/35913/25949 +f 35911/35911/25947 35894/35894/25931 35914/35914/25950 +f 35911/35911/25947 35914/35914/25950 35912/35912/25948 +f 35912/35912/25948 35914/35914/25950 35915/35915/25951 +f 35912/35912/25948 35915/35915/25951 35916/35916/25952 +f 35913/35913/25949 35912/35912/25948 35916/35916/25952 +f 35913/35913/25949 35916/35916/25952 35917/35917/25953 +f 35918/35918/25954 35919/35919/25955 35920/35920/25956 +f 35918/35918/25954 35920/35920/25956 35921/35921/25957 +f 35919/35919/25955 35922/35922/25958 35923/35923/25959 +f 35919/35919/25955 35923/35923/25959 35920/35920/25956 +f 35920/35920/25956 35923/35923/25959 35924/35924/25960 +f 35920/35920/25956 35924/35924/25960 35925/35925/25961 +f 35921/35921/25957 35920/35920/25956 35925/35925/25961 +f 35921/35921/25957 35925/35925/25961 35926/35926/25962 +f 35876/35876/25912 35873/35875/25910 35927/35927/25963 +f 35876/35876/25912 35927/35927/25963 35928/35928/25964 +f 35873/35875/25910 35872/35863/25909 35900/35900/25937 +f 35873/35875/25910 35900/35900/25937 35927/35927/25963 +f 35927/35927/25963 35900/35900/25937 35899/35899/25936 +f 35927/35927/25963 35899/35899/25936 35929/35929/25965 +f 35928/35928/25964 35927/35927/25963 35929/35929/25965 +f 35928/35928/25964 35929/35929/25965 35930/35930/25966 +f 35863/35866/25900 35931/35931/25967 35932/35932/25968 +f 35863/35866/25900 35932/35932/25968 35864/35867/25901 +f 35931/35931/25967 35910/35910/25946 35933/35933/25969 +f 35931/35931/25967 35933/35933/25969 35932/35932/25968 +f 35932/35932/25968 35933/35933/25969 35934/35934/25970 +f 35932/35932/25968 35934/35934/25970 35935/35935/25971 +f 35864/35867/25901 35932/35932/25968 35935/35935/25971 +f 35864/35867/25901 35935/35935/25971 35867/35870/25904 +f 35936/35936/25972 35937/35937/25973 35938/35938/25974 +f 35936/35936/25972 35938/35938/25974 35939/35939/25975 +f 35937/35937/25973 35940/35940/25976 35941/35941/25977 +f 35937/35937/25973 35941/35941/25977 35938/35938/25974 +f 35938/35938/25974 35941/35941/25977 35942/35942/25978 +f 35938/35938/25974 35942/35942/25978 35943/35943/25979 +f 35939/35939/25975 35938/35938/25974 35943/35943/25979 +f 35939/35939/25975 35943/35943/25979 35944/35944/25980 +f 35945/35945/25981 35946/35946/25982 35947/35947/25983 +f 35945/35945/25981 35947/35947/25983 35948/35948/25984 +f 35946/35946/25982 35885/35885/25922 35949/35949/25985 +f 35946/35946/25982 35949/35949/25985 35947/35947/25983 +f 35950/35950/25986 35951/35951/25987 35952/35952/25988 +f 35950/35950/25986 35952/35952/25988 35953/35953/25989 +f 35954/35954/25984 35950/35950/25986 35953/35953/25989 +f 35954/35954/25984 35953/35953/25989 35955/35955/25990 +f 35956/35956/25991 35957/35957/25992 35958/35958/25993 +f 35956/35956/25991 35958/35958/25993 35959/35959/25994 +f 35957/35957/25992 35960/35960/25995 35961/35961/25996 +f 35957/35957/25992 35961/35961/25996 35958/35958/25993 +f 35962/35962/25997 35963/35963/25996 35964/35964/25998 +f 35962/35962/25997 35964/35964/25998 35965/35965/25999 +f 35966/35966/25994 35962/35962/25997 35965/35965/25999 +f 35966/35966/25994 35965/35965/25999 35967/35967/26000 +f 35944/35944/25980 35943/35943/25979 35968/35968/26001 +f 35944/35944/25980 35968/35968/26001 35969/35969/26002 +f 35943/35943/25979 35942/35942/25978 35970/35970/26003 +f 35943/35943/25979 35970/35970/26003 35968/35968/26001 +f 35968/35968/26001 35970/35970/26003 35971/35971/26004 +f 35968/35968/26001 35971/35971/26004 35972/35972/26005 +f 35969/35969/26002 35968/35968/26001 35972/35972/26005 +f 35969/35969/26002 35972/35972/26005 35973/35973/26006 +f 35974/35974/26007 35975/35975/26008 35976/35976/26009 +f 35974/35974/26007 35976/35976/26009 35977/35977/26010 +f 35978/35978/26008 35979/35979/26011 35980/35980/26012 +f 35978/35978/26008 35980/35980/26012 35981/35981/26013 +f 35981/35981/26013 35980/35980/26012 35982/35982/26014 +f 35981/35981/26013 35982/35982/26014 35983/35983/26015 +f 35977/35977/26010 35976/35976/26009 35984/35984/26016 +f 35977/35977/26010 35984/35984/26016 35985/35985/26017 +f 35986/35986/26018 35987/35987/26019 35988/35988/26020 +f 35986/35986/26018 35988/35988/26020 35989/35989/26021 +f 35987/35987/26019 35990/35990/26022 35991/35991/26023 +f 35987/35987/26019 35991/35991/26023 35988/35988/26020 +f 35988/35988/26020 35991/35991/26023 35992/35992/26024 +f 35988/35988/26020 35992/35992/26024 35993/35993/26025 +f 35989/35989/26021 35988/35988/26020 35993/35993/26025 +f 35989/35989/26021 35993/35993/26025 35994/35994/26026 +f 35973/35973/26006 35972/35972/26005 35995/35995/26027 +f 35973/35973/26006 35995/35995/26027 35996/35996/26028 +f 35972/35972/26005 35971/35971/26004 35997/35997/26029 +f 35972/35972/26005 35997/35997/26029 35995/35995/26027 +f 35995/35995/26027 35997/35997/26029 35990/35990/26022 +f 35995/35995/26027 35990/35990/26022 35998/35998/26030 +f 35996/35996/26028 35995/35995/26027 35998/35998/26030 +f 35996/35996/26028 35998/35998/26030 35999/35999/26031 +f 35936/35936/25972 35939/35939/25975 36000/36000/26032 +f 35936/35936/25972 36000/36000/26032 36001/36001/26033 +f 35939/35939/25975 35944/35944/25980 36002/36002/26034 +f 35939/35939/25975 36002/36002/26034 36000/36000/26032 +f 36000/36000/26032 36002/36002/26034 36003/36003/26035 +f 36000/36000/26032 36003/36003/26035 36004/36004/26036 +f 36001/36001/26033 36000/36000/26032 36004/36004/26036 +f 36001/36001/26033 36004/36004/26036 36005/36005/26037 +f 36006/36006/26038 36007/36007/26039 36008/36008/26040 +f 36006/36006/26038 36008/36008/26040 36009/36009/26041 +f 36007/36007/26039 36010/36010/26042 36011/36011/26043 +f 36007/36007/26039 36011/36011/26043 36008/36008/26040 +f 36008/36008/26040 36011/36011/26043 36012/36012/26044 +f 36008/36008/26040 36012/36012/26044 36013/36013/26045 +f 36009/36009/26041 36008/36008/26040 36013/36013/26045 +f 36009/36009/26041 36013/36013/26045 36014/36014/26046 +f 36015/36015/26047 36016/36016/26048 36017/36017/26049 +f 36015/36015/26047 36017/36017/26049 36018/36018/26050 +f 36016/36016/26048 36019/36019/26051 36020/36020/26052 +f 36016/36016/26048 36020/36020/26052 36017/36017/26049 +f 36021/36021/26049 36022/36022/26052 36023/36023/26053 +f 36021/36021/26049 36023/36023/26053 36024/36024/26054 +f 36025/36025/26050 36021/36021/26049 36024/36024/26054 +f 36025/36025/26050 36024/36024/26054 36026/36026/26055 +f 36015/36015/26047 36027/36027/26056 36028/36028/26057 +f 36015/36015/26047 36028/36028/26057 36029/36029/26058 +f 36027/36027/26056 36030/36030/26059 36031/36031/26060 +f 36027/36027/26056 36031/36031/26060 36028/36028/26057 +f 36028/36028/26057 36031/36031/26060 36032/36032/26061 +f 36028/36028/26057 36032/36032/26061 36033/36033/26062 +f 36029/36029/26058 36028/36028/26057 36033/36033/26062 +f 36029/36029/26058 36033/36033/26062 36034/36034/26063 +f 36035/36035/26064 36036/36036/26065 36037/36037/26066 +f 36035/36035/26064 36037/36037/26066 36038/36038/26067 +f 36036/36036/26065 36039/36039/26068 36040/36040/26069 +f 36036/36036/26065 36040/36040/26069 36037/36037/26066 +f 36041/36041/26066 36042/36042/26069 36043/36043/26070 +f 36041/36041/26066 36043/36043/26070 36044/36044/26071 +f 36045/36045/26067 36041/36041/26066 36044/36044/26071 +f 36045/36045/26067 36044/36044/26071 36046/36046/26072 +f 35999/35999/26031 35998/35998/26030 36047/36047/26073 +f 35999/35999/26031 36047/36047/26073 36048/36048/26074 +f 35998/35998/26030 35990/35990/26022 35987/35987/26019 +f 35998/35998/26030 35987/35987/26019 36047/36047/26073 +f 36047/36047/26073 35987/35987/26019 35986/35986/26018 +f 36047/36047/26073 35986/35986/26018 36049/36049/26075 +f 36048/36048/26074 36047/36047/26073 36049/36049/26075 +f 36048/36048/26074 36049/36049/26075 36050/36050/26076 +f 35918/35918/25954 36051/36051/26077 36052/36052/26078 +f 35918/35918/25954 36052/36052/26078 35919/35919/25955 +f 36051/36051/26077 36006/36006/26038 36053/36053/26079 +f 36051/36051/26077 36053/36053/26079 36052/36052/26078 +f 36052/36052/26078 36053/36053/26079 36054/36054/26080 +f 36052/36052/26078 36054/36054/26080 36055/36055/26081 +f 35919/35919/25955 36052/36052/26078 36055/36055/26081 +f 35919/35919/25955 36055/36055/26081 35922/35922/25958 +f 36056/36056/26076 36057/36057/26075 36058/36058/26082 +f 36056/36056/26076 36058/36058/26082 36059/36059/26083 +f 36057/36057/26075 36060/36060/26084 36061/36061/26085 +f 36057/36057/26075 36061/36061/26085 36058/36058/26082 +f 36058/36058/26082 36061/36061/26085 36010/36010/26042 +f 36058/36058/26082 36010/36010/26042 36062/36062/26086 +f 36059/36059/26083 36058/36058/26082 36062/36062/26086 +f 36059/36059/26083 36062/36062/26086 36063/36063/26087 +f 35898/35898/25935 35897/35897/25934 36064/36064/26088 +f 35898/35898/25935 36064/36064/26088 36065/36065/26089 +f 35897/35897/25934 35896/35896/25933 36066/36066/26090 +f 35897/35897/25934 36066/36066/26090 36064/36064/26088 +f 36064/36064/26088 36066/36066/26090 36067/36067/26091 +f 36064/36064/26088 36067/36067/26091 36068/36068/26092 +f 36065/36065/26089 36064/36064/26088 36068/36068/26092 +f 36065/36065/26089 36068/36068/26092 36069/36069/26093 +f 36070/36070/26094 36071/36071/26095 36072/36072/26096 +f 36070/36070/26094 36072/36072/26096 36073/36073/26097 +f 36071/36071/26095 36074/36074/26098 36075/36075/26099 +f 36071/36071/26095 36075/36075/26099 36072/36072/26096 +f 36072/36072/26096 36075/36075/26099 36076/36076/26100 +f 36072/36072/26096 36076/36076/26100 36077/36077/26101 +f 36073/36073/26097 36072/36072/26096 36077/36077/26101 +f 36073/36073/26097 36077/36077/26101 36078/36078/26102 +f 36079/36079/25981 36080/36080/26103 36081/36081/26104 +f 36079/36079/25981 36081/36081/26104 36082/36082/26105 +f 36080/36080/26103 36039/36039/26068 36083/36083/26106 +f 36080/36080/26103 36083/36083/26106 36081/36081/26104 +f 36081/36081/26104 36083/36083/26106 36084/36084/26107 +f 36081/36081/26104 36084/36084/26107 36085/36085/26108 +f 36082/36082/26105 36081/36081/26104 36085/36085/26108 +f 36082/36082/26105 36085/36085/26108 36086/36086/26109 +f 35944/35944/25980 35969/35969/26002 36087/36087/26110 +f 35944/35944/25980 36087/36087/26110 36002/36002/26034 +f 35969/35969/26002 35973/35973/26006 36088/36088/26111 +f 35969/35969/26002 36088/36088/26111 36087/36087/26110 +f 36087/36087/26110 36088/36088/26111 36089/36089/26112 +f 36087/36087/26110 36089/36089/26112 36090/36090/26113 +f 36002/36002/26034 36087/36087/26110 36090/36090/26113 +f 36002/36002/26034 36090/36090/26113 36003/36003/26035 +f 35898/35898/25935 36065/36065/26089 36091/36091/26114 +f 35898/35898/25935 36091/36091/26114 36092/36092/26115 +f 36065/36065/26089 36069/36069/26093 36093/36093/26116 +f 36065/36065/26089 36093/36093/26116 36091/36091/26114 +f 36094/36094/26114 36095/36095/26116 36096/36096/26117 +f 36094/36094/26114 36096/36096/26117 36097/36097/26118 +f 36098/36098/26115 36094/36094/26114 36097/36097/26118 +f 36098/36098/26115 36097/36097/26118 36099/36099/26119 +f 36019/36019/26051 36100/36100/26120 36101/36101/26121 +f 36019/36019/26051 36101/36101/26121 36020/36020/26052 +f 36100/36100/26120 35867/35870/25904 36102/36102/26122 +f 36100/36100/26120 36102/36102/26122 36101/36101/26121 +f 36103/36103/26123 36104/36104/26122 36105/36105/26124 +f 36103/36103/26123 36105/36105/26124 36106/36106/26125 +f 36022/36022/26052 36103/36103/26123 36106/36106/26125 +f 36022/36022/26052 36106/36106/26125 36023/36023/26053 +f 36107/36107/26126 36108/36108/26127 36109/36109/26128 +f 36107/36107/26126 36109/36109/26128 36110/36110/26129 +f 36108/36108/26127 36111/36111/26130 36112/36112/26131 +f 36108/36108/26127 36112/36112/26131 36109/36109/26128 +f 36109/36109/26128 36112/36112/26131 35979/35979/26011 +f 36109/36109/26128 35979/35979/26011 36113/36113/26132 +f 36110/36110/26129 36109/36109/26128 36113/36113/26132 +f 36110/36110/26129 36113/36113/26132 36114/36114/26133 +f 36115/36115/26134 36116/36116/26135 36117/36117/26136 +f 36115/36115/26134 36117/36117/26136 36118/36118/26137 +f 36116/36116/26135 36054/36054/26080 36119/36119/26138 +f 36116/36116/26135 36119/36119/26138 36117/36117/26136 +f 36117/36117/26136 36119/36119/26138 36120/36120/26139 +f 36117/36117/26136 36120/36120/26139 36121/36121/26140 +f 36118/36118/26137 36117/36117/26136 36121/36121/26140 +f 36118/36118/26137 36121/36121/26140 36122/36122/26141 +f 36123/36123/26142 36124/36124/26143 36125/36125/26144 +f 36123/36123/26142 36125/36125/26144 36126/36126/26145 +f 36124/36124/26143 36127/36127/26146 36128/36128/26147 +f 36124/36124/26143 36128/36128/26147 36125/36125/26144 +f 36129/36129/26144 36130/36130/26147 36131/36131/26148 +f 36129/36129/26144 36131/36131/26148 36132/36132/26149 +f 36133/36133/26145 36129/36129/26144 36132/36132/26149 +f 36133/36133/26145 36132/36132/26149 36134/36134/26150 +f 36135/36135/26151 36136/36136/26152 36137/36137/26153 +f 36135/36135/26151 36137/36137/26153 36138/36138/26154 +f 36136/36136/26152 36115/36115/26134 36139/36139/26155 +f 36136/36136/26152 36139/36139/26155 36137/36137/26153 +f 36137/36137/26153 36139/36139/26155 36140/36140/26156 +f 36137/36137/26153 36140/36140/26156 36141/36141/26157 +f 36138/36138/26154 36137/36137/26153 36141/36141/26157 +f 36138/36138/26154 36141/36141/26157 36142/36142/26158 +f 36143/36143/26159 36144/36144/26160 36145/36145/26161 +f 36143/36143/26159 36145/36145/26161 36146/36146/26162 +f 36147/36147/26160 36148/36148/26163 36149/36149/26164 +f 36147/36147/26160 36149/36149/26164 36150/36150/26165 +f 36150/36150/26165 36149/36149/26164 36151/36151/26166 +f 36150/36150/26165 36151/36151/26166 36152/36152/26167 +f 36146/36146/26162 36145/36145/26161 36153/36153/26168 +f 36146/36146/26162 36153/36153/26168 36154/36154/26169 +f 36155/36155/26170 36156/36156/26171 36157/36157/26172 +f 36155/36155/26170 36157/36157/26172 36158/36158/26173 +f 36156/36156/26171 36159/36159/26174 36160/36160/26175 +f 36156/36156/26171 36160/36160/26175 36157/36157/26172 +f 36157/36157/26172 36160/36160/26175 36161/36161/26098 +f 36157/36157/26172 36161/36161/26098 36162/36162/26176 +f 36158/36158/26173 36157/36157/26172 36162/36162/26176 +f 36158/36158/26173 36162/36162/26176 36163/36163/26177 +f 35999/35999/26031 36048/36048/26074 36164/36164/26178 +f 35999/35999/26031 36164/36164/26178 36165/36165/26179 +f 36048/36048/26074 36050/36050/26076 36166/36166/26180 +f 36048/36048/26074 36166/36166/26180 36164/36164/26178 +f 36164/36164/26178 36166/36166/26180 36167/36167/26181 +f 36164/36164/26178 36167/36167/26181 36168/36168/26182 +f 36165/36165/26179 36164/36164/26178 36168/36168/26182 +f 36165/36165/26179 36168/36168/26182 36169/36169/26183 +f 36035/36035/26064 36170/36170/26184 36171/36171/26185 +f 36035/36035/26064 36171/36171/26185 36172/36172/26186 +f 36170/36170/26184 35934/35934/25970 36173/36173/26187 +f 36170/36170/26184 36173/36173/26187 36171/36171/26185 +f 36171/36171/26185 36173/36173/26187 36174/36174/26188 +f 36171/36171/26185 36174/36174/26188 36175/36175/26189 +f 36172/36172/26186 36171/36171/26185 36175/36175/26189 +f 36172/36172/26186 36175/36175/26189 36176/36176/26190 +f 36177/36177/26191 36178/36178/26192 36179/36179/26193 +f 36177/36177/26191 36179/36179/26193 36180/36180/26194 +f 36181/36181/26195 36182/36182/26196 36183/36183/26197 +f 36181/36181/26195 36183/36183/26197 36184/36184/26193 +f 36184/36184/26193 36183/36183/26197 36185/36185/26198 +f 36184/36184/26193 36185/36185/26198 36186/36186/26199 +f 36180/36180/26194 36179/36179/26193 36187/36187/26199 +f 36180/36180/26194 36187/36187/26199 36188/36188/26200 +f 36189/36189/26201 36190/36190/26202 36191/36191/26203 +f 36189/36189/26201 36191/36191/26203 36192/36192/26204 +f 36193/36193/26205 36194/36194/26206 36195/36195/26207 +f 36193/36193/26205 36195/36195/26207 36196/36196/26208 +f 36196/36196/26208 36195/36195/26207 36197/36197/26209 +f 36196/36196/26208 36197/36197/26209 36198/36198/26210 +f 36192/36192/26204 36191/36191/26203 36199/36199/26210 +f 36192/36192/26204 36199/36199/26210 36200/36200/26211 +f 36194/36194/26206 36201/36201/26212 36202/36202/26213 +f 36194/36194/26206 36202/36202/26213 36195/36195/26207 +f 36201/36201/26212 36203/36203/26214 36204/36204/26215 +f 36201/36201/26212 36204/36204/26215 36202/36202/26213 +f 36202/36202/26213 36204/36204/26215 36205/36205/26216 +f 36202/36202/26213 36205/36205/26216 36206/36206/26217 +f 36195/36195/26207 36202/36202/26213 36206/36206/26217 +f 36195/36195/26207 36206/36206/26217 36197/36197/26209 +f 36148/36148/26163 36207/36207/26218 36208/36208/26219 +f 36148/36148/26163 36208/36208/26219 36149/36149/26164 +f 36207/36207/26218 36209/36209/26220 36210/36210/26221 +f 36207/36207/26218 36210/36210/26221 36208/36208/26219 +f 36208/36208/26219 36210/36210/26221 36211/36211/26222 +f 36208/36208/26219 36211/36211/26222 36212/36212/26223 +f 36149/36149/26164 36208/36208/26219 36212/36212/26223 +f 36149/36149/26164 36212/36212/26223 36151/36151/26166 +f 36213/36213/26224 36214/36214/26225 36215/36215/26226 +f 36213/36213/26224 36215/36215/26226 36216/36216/26227 +f 36214/36214/26225 36217/36217/26228 36218/36218/26229 +f 36214/36214/26225 36218/36218/26229 36215/36215/26226 +f 36215/36215/26226 36218/36218/26229 36219/36219/26230 +f 36215/36215/26226 36219/36219/26230 36220/36220/26231 +f 36216/36216/26227 36215/36215/26226 36220/36220/26231 +f 36216/36216/26227 36220/36220/26231 36221/36221/26232 +f 36222/36222/26233 36223/36223/26234 36224/36224/26235 +f 36222/36222/26233 36224/36224/26235 36225/36225/26236 +f 36223/36223/26234 36226/36226/26237 36227/36227/26238 +f 36223/36223/26234 36227/36227/26238 36224/36224/26235 +f 36224/36224/26235 36227/36227/26238 36228/36228/26239 +f 36224/36224/26235 36228/36228/26239 36229/36229/26240 +f 36225/36225/26236 36224/36224/26235 36229/36229/26240 +f 36225/36225/26236 36229/36229/26240 36230/36230/26241 +f 36231/36231/26237 36232/36232/26242 36233/36233/26243 +f 36231/36231/26237 36233/36233/26243 36234/36234/26244 +f 36232/36232/26242 36235/36235/26245 36236/36236/26246 +f 36232/36232/26242 36236/36236/26246 36233/36233/26243 +f 36237/36237/26243 36238/36238/26246 36239/36239/26247 +f 36237/36237/26243 36239/36239/26247 36240/36240/26248 +f 36241/36241/26244 36237/36237/26243 36240/36240/26248 +f 36241/36241/26244 36240/36240/26248 36242/36242/26249 +f 36182/36182/26196 36243/36243/26250 36244/36244/26251 +f 36182/36182/26196 36244/36244/26251 36183/36183/26197 +f 36243/36243/26250 36245/36245/26252 36246/36246/26253 +f 36243/36243/26250 36246/36246/26253 36244/36244/26251 +f 36244/36244/26251 36246/36246/26253 36247/36247/26254 +f 36244/36244/26251 36247/36247/26254 36248/36248/26255 +f 36183/36183/26197 36244/36244/26251 36248/36248/26255 +f 36183/36183/26197 36248/36248/26255 36185/36185/26198 +f 36249/36249/26256 36250/36250/26257 36251/36251/26258 +f 36249/36249/26256 36251/36251/26258 36252/36252/26259 +f 36253/36253/26257 36254/36254/26260 36255/36255/26261 +f 36253/36253/26257 36255/36255/26261 36256/36256/26258 +f 36257/36257/26258 36258/36258/26262 36259/36259/26263 +f 36257/36257/26258 36259/36259/26263 36260/36260/26264 +f 36252/36252/26259 36251/36251/26258 36261/36261/26264 +f 36252/36252/26259 36261/36261/26264 36262/36262/26265 +f 36185/36185/26198 36248/36248/26255 36263/36263/26266 +f 36185/36185/26198 36263/36263/26266 36264/36264/26267 +f 36248/36248/26255 36247/36247/26254 36265/36265/26268 +f 36248/36248/26255 36265/36265/26268 36263/36263/26266 +f 36263/36263/26266 36265/36265/26268 36266/36266/26269 +f 36263/36263/26266 36266/36266/26269 36267/36267/26270 +f 36264/36264/26267 36263/36263/26266 36267/36267/26270 +f 36264/36264/26267 36267/36267/26270 36254/36254/26260 +f 36188/36188/26200 36187/36187/26199 36268/36268/26271 +f 36188/36188/26200 36268/36268/26271 36269/36269/26272 +f 36186/36186/26199 36185/36185/26198 36264/36264/26267 +f 36186/36186/26199 36264/36264/26267 36270/36270/26271 +f 36270/36270/26271 36264/36264/26267 36254/36254/26260 +f 36270/36270/26271 36254/36254/26260 36253/36253/26257 +f 36269/36269/26272 36268/36268/26271 36250/36250/26257 +f 36269/36269/26272 36250/36250/26257 36249/36249/26256 +f 36230/36230/26241 36229/36229/26240 36271/36271/26273 +f 36230/36230/26241 36271/36271/26273 36272/36272/26274 +f 36273/36273/26240 36213/36213/26224 36216/36216/26227 +f 36273/36273/26240 36216/36216/26227 36274/36274/26273 +f 36274/36274/26273 36216/36216/26227 36221/36221/26232 +f 36274/36274/26273 36221/36221/26232 36275/36275/26275 +f 36272/36272/26274 36271/36271/26273 36276/36276/26275 +f 36272/36272/26274 36276/36276/26275 36277/36277/26276 +f 36278/36278/26277 36279/36279/26278 36280/36280/26279 +f 36278/36278/26277 36280/36280/26279 36281/36281/26280 +f 36282/36282/26278 36283/36283/26281 36284/36284/26282 +f 36282/36282/26278 36284/36284/26282 36285/36285/26279 +f 36285/36285/26279 36284/36284/26282 36286/36286/26283 +f 36285/36285/26279 36286/36286/26283 36287/36287/26284 +f 36281/36281/26280 36280/36280/26279 36288/36288/26285 +f 36281/36281/26280 36288/36288/26285 36289/36289/26286 +f 36277/36277/26276 36276/36276/26275 36290/36290/26287 +f 36277/36277/26276 36290/36290/26287 36291/36291/26288 +f 36275/36275/26275 36221/36221/26232 36292/36292/26289 +f 36275/36275/26275 36292/36292/26289 36293/36293/26287 +f 36293/36293/26287 36292/36292/26289 36294/36294/26281 +f 36293/36293/26287 36294/36294/26281 36295/36295/26278 +f 36291/36291/26288 36290/36290/26287 36279/36279/26278 +f 36291/36291/26288 36279/36279/26278 36278/36278/26277 +f 36221/36221/26232 36220/36220/26231 36296/36296/26290 +f 36221/36221/26232 36296/36296/26290 36292/36292/26289 +f 36220/36220/26231 36219/36219/26230 36297/36297/26291 +f 36220/36220/26231 36297/36297/26291 36296/36296/26290 +f 36296/36296/26290 36297/36297/26291 36298/36298/26292 +f 36296/36296/26290 36298/36298/26292 36299/36299/26293 +f 36292/36292/26289 36296/36296/26290 36299/36299/26293 +f 36292/36292/26289 36299/36299/26293 36294/36294/26281 +f 36254/36254/26260 36267/36267/26270 36300/36300/26294 +f 36254/36254/26260 36300/36300/26294 36255/36255/26261 +f 36267/36267/26270 36266/36266/26269 36301/36301/26295 +f 36267/36267/26270 36301/36301/26295 36300/36300/26294 +f 36300/36300/26294 36301/36301/26295 36302/36302/26296 +f 36300/36300/26294 36302/36302/26296 36303/36303/26297 +f 36255/36255/26261 36300/36300/26294 36303/36303/26297 +f 36255/36255/26261 36303/36303/26297 36304/36304/26263 +f 36286/36286/26283 36305/36305/26298 36306/36306/26299 +f 36286/36286/26283 36306/36306/26299 36307/36307/26300 +f 36305/36305/26298 36308/36308/26301 36309/36309/26302 +f 36305/36305/26298 36309/36309/26302 36306/36306/26299 +f 36306/36306/26299 36309/36309/26302 36310/36310/26303 +f 36306/36306/26299 36310/36310/26303 36311/36311/26304 +f 36307/36307/26300 36306/36306/26299 36311/36311/26304 +f 36307/36307/26300 36311/36311/26304 36312/36312/26305 +f 36283/36283/26281 36313/36313/26293 36314/36314/26306 +f 36283/36283/26281 36314/36314/26306 36284/36284/26282 +f 36313/36313/26293 36315/36315/26307 36316/36316/26308 +f 36313/36313/26293 36316/36316/26308 36314/36314/26306 +f 36314/36314/26306 36316/36316/26308 36308/36308/26301 +f 36314/36314/26306 36308/36308/26301 36305/36305/26298 +f 36284/36284/26282 36314/36314/26306 36305/36305/26298 +f 36284/36284/26282 36305/36305/26298 36286/36286/26283 +f 36259/36259/26263 36317/36317/26297 36318/36318/26309 +f 36259/36259/26263 36318/36318/26309 36319/36319/26310 +f 36317/36317/26297 36320/36320/26296 36321/36321/26311 +f 36317/36317/26297 36321/36321/26311 36318/36318/26309 +f 36318/36318/26309 36321/36321/26311 36322/36322/26312 +f 36318/36318/26309 36322/36322/26312 36323/36323/26313 +f 36319/36319/26310 36318/36318/26309 36323/36323/26313 +f 36319/36319/26310 36323/36323/26313 36324/36324/26314 +f 36262/36262/26265 36261/36261/26264 36325/36325/26315 +f 36262/36262/26265 36325/36325/26315 36326/36326/26316 +f 36260/36260/26264 36259/36259/26263 36319/36319/26310 +f 36260/36260/26264 36319/36319/26310 36327/36327/26317 +f 36327/36327/26317 36319/36319/26310 36324/36324/26314 +f 36327/36327/26317 36324/36324/26314 36328/36328/26318 +f 36326/36326/26316 36325/36325/26315 36329/36329/26318 +f 36326/36326/26316 36329/36329/26318 36330/36330/26319 +f 36331/36331/26320 36332/36332/26321 36333/36333/26322 +f 36331/36331/26320 36333/36333/26322 36334/36334/26323 +f 36335/36335/26324 36336/36336/26325 36337/36337/26326 +f 36335/36335/26324 36337/36337/26326 36338/36338/26327 +f 36338/36338/26327 36337/36337/26326 36339/36339/26328 +f 36338/36338/26327 36339/36339/26328 36340/36340/26329 +f 36334/36334/26323 36333/36333/26322 36341/36341/26329 +f 36334/36334/26323 36341/36341/26329 36342/36342/26330 +f 36324/36324/26314 36323/36323/26313 36343/36343/26331 +f 36324/36324/26314 36343/36343/26331 36344/36344/26332 +f 36323/36323/26313 36322/36322/26312 36345/36345/26333 +f 36323/36323/26313 36345/36345/26333 36343/36343/26331 +f 36343/36343/26331 36345/36345/26333 36346/36346/26334 +f 36343/36343/26331 36346/36346/26334 36347/36347/26335 +f 36344/36344/26332 36343/36343/26331 36347/36347/26335 +f 36344/36344/26332 36347/36347/26335 36336/36336/26325 +f 36330/36330/26319 36329/36329/26318 36348/36348/26336 +f 36330/36330/26319 36348/36348/26336 36349/36349/26337 +f 36328/36328/26318 36324/36324/26314 36344/36344/26332 +f 36328/36328/26318 36344/36344/26332 36350/36350/26338 +f 36350/36350/26338 36344/36344/26332 36336/36336/26325 +f 36350/36350/26338 36336/36336/26325 36335/36335/26324 +f 36349/36349/26337 36348/36348/26336 36332/36332/26321 +f 36349/36349/26337 36332/36332/26321 36331/36331/26320 +f 36289/36289/26286 36288/36288/26285 36351/36351/26339 +f 36289/36289/26286 36351/36351/26339 36352/36352/26340 +f 36287/36287/26284 36286/36286/26283 36307/36307/26300 +f 36287/36287/26284 36307/36307/26300 36353/36353/26339 +f 36353/36353/26339 36307/36307/26300 36312/36312/26305 +f 36353/36353/26339 36312/36312/26305 36354/36354/26341 +f 36352/36352/26340 36351/36351/26339 36355/36355/26342 +f 36352/36352/26340 36355/36355/26342 36356/36356/26343 +f 36339/36339/26328 36357/36357/26344 36358/36358/26345 +f 36339/36339/26328 36358/36358/26345 36359/36359/26346 +f 36357/36357/26344 36360/36360/26347 36361/36361/26348 +f 36357/36357/26344 36361/36361/26348 36358/36358/26345 +f 36358/36358/26345 36361/36361/26348 36362/36362/26349 +f 36358/36358/26345 36362/36362/26349 36363/36363/26350 +f 36359/36359/26346 36358/36358/26345 36363/36363/26350 +f 36359/36359/26346 36363/36363/26350 36364/36364/26351 +f 36356/36356/26343 36355/36355/26342 36365/36365/26352 +f 36356/36356/26343 36365/36365/26352 36366/36366/26353 +f 36354/36354/26341 36312/36312/26305 36367/36367/26354 +f 36354/36354/26341 36367/36367/26354 36368/36368/26355 +f 36368/36368/26355 36367/36367/26354 36369/36369/26356 +f 36368/36368/26355 36369/36369/26356 36370/36370/26357 +f 36366/36366/26353 36365/36365/26352 36371/36371/26358 +f 36366/36366/26353 36371/36371/26358 36372/36372/26359 +f 36312/36312/26305 36311/36311/26304 36373/36373/26360 +f 36312/36312/26305 36373/36373/26360 36367/36367/26354 +f 36311/36311/26304 36310/36310/26303 36374/36374/26361 +f 36311/36311/26304 36374/36374/26361 36373/36373/26360 +f 36373/36373/26360 36374/36374/26361 36375/36375/26362 +f 36373/36373/26360 36375/36375/26362 36376/36376/26363 +f 36367/36367/26354 36373/36373/26360 36376/36376/26363 +f 36367/36367/26354 36376/36376/26363 36369/36369/26356 +f 36336/36336/26325 36347/36347/26335 36377/36377/26364 +f 36336/36336/26325 36377/36377/26364 36337/36337/26326 +f 36347/36347/26335 36346/36346/26334 36378/36378/26365 +f 36347/36347/26335 36378/36378/26365 36377/36377/26364 +f 36377/36377/26364 36378/36378/26365 36360/36360/26347 +f 36377/36377/26364 36360/36360/26347 36357/36357/26344 +f 36337/36337/26326 36377/36377/26364 36357/36357/26344 +f 36337/36337/26326 36357/36357/26344 36339/36339/26328 +f 36379/36379/26366 36380/36380/26367 36381/36381/26368 +f 36379/36379/26366 36381/36381/26368 36382/36382/26369 +f 36380/36380/26367 36383/36383/26370 36384/36384/26371 +f 36380/36380/26367 36384/36384/26371 36381/36381/26368 +f 36381/36381/26368 36384/36384/26371 36385/36385/26372 +f 36381/36381/26368 36385/36385/26372 36386/36386/25965 +f 36382/36382/26369 36381/36381/26368 36386/36386/25965 +f 36382/36382/26369 36386/36386/25965 36387/36387/25936 +f 36388/36388/26373 36389/36389/26374 36390/36390/26375 +f 36388/36388/26373 36390/36390/26375 36391/36391/26376 +f 36389/36389/26374 36392/36392/26377 36393/36393/26378 +f 36389/36389/26374 36393/36393/26378 36390/36390/26375 +f 36390/36390/26375 36393/36393/26378 36394/36394/26379 +f 36390/36390/26375 36394/36394/26379 36395/36395/26380 +f 36391/36391/26376 36390/36390/26375 36395/36395/26380 +f 36391/36391/26376 36395/36395/26380 36396/36396/26381 +f 36397/36397/26382 36398/36398/26383 36399/36399/26384 +f 36397/36397/26382 36399/36399/26384 36400/36400/26385 +f 36398/36398/26383 36401/36401/26037 36402/36402/26036 +f 36398/36398/26383 36402/36402/26036 36399/36399/26384 +f 36399/36399/26384 36402/36402/26036 36403/36403/26035 +f 36399/36399/26384 36403/36403/26035 36404/36404/26386 +f 36400/36400/26385 36399/36399/26384 36404/36404/26386 +f 36400/36400/26385 36404/36404/26386 36405/36405/26387 +f 36406/36406/26388 36407/36407/26389 36408/36408/26390 +f 36406/36406/26388 36408/36408/26390 36409/36409/26391 +f 36410/36410/26392 35869/35872/25906 36411/36411/26393 +f 36410/36410/26392 36411/36411/26393 36412/36412/26394 +f 36412/36412/26394 36411/36411/26393 36413/36413/26395 +f 36412/36412/26394 36413/36413/26395 36414/36414/26396 +f 36409/36409/26391 36408/36408/26390 36415/36415/26397 +f 36409/36409/26391 36415/36415/26397 36416/36416/26398 +f 36417/36417/26399 36418/36418/26400 36419/36419/26401 +f 36417/36417/26399 36419/36419/26401 36420/36420/26402 +f 36421/36421/26403 35871/35874/25908 35870/35873/25907 +f 36421/36421/26403 35870/35873/25907 36422/36422/26401 +f 36422/36422/26401 35870/35873/25907 35869/35872/25906 +f 36422/36422/26401 35869/35872/25906 36410/36410/26392 +f 36420/36420/26402 36419/36419/26401 36407/36407/26389 +f 36420/36420/26402 36407/36407/26389 36406/36406/26388 +f 36405/36405/26387 36404/36404/26386 36423/36423/26404 +f 36405/36405/26387 36423/36423/26404 36424/36424/26405 +f 36404/36404/26386 36403/36403/26035 36425/36425/26113 +f 36404/36404/26386 36425/36425/26113 36423/36423/26404 +f 36426/36426/26404 36090/36090/26113 36089/36089/26112 +f 36426/36426/26404 36089/36089/26112 36427/36427/26406 +f 36424/36424/26405 36423/36423/26404 36428/36428/26406 +f 36424/36424/26405 36428/36428/26406 36429/36429/26407 +f 36430/36430/26408 36431/36431/26409 36432/36432/26410 +f 36430/36430/26408 36432/36432/26410 36433/36433/26411 +f 36434/36434/26409 36169/36169/26183 36168/36168/26182 +f 36434/36434/26409 36168/36168/26182 36435/36435/26410 +f 36435/36435/26410 36168/36168/26182 36167/36167/26181 +f 36435/36435/26410 36167/36167/26181 36436/36436/26412 +f 36433/36433/26411 36432/36432/26410 36437/36437/26412 +f 36433/36433/26411 36437/36437/26412 36438/36438/26413 +f 36429/36429/26407 36428/36428/26406 36439/36439/26414 +f 36429/36429/26407 36439/36439/26414 36440/36440/26415 +f 36427/36427/26406 36089/36089/26112 36441/36441/26416 +f 36427/36427/26406 36441/36441/26416 36442/36442/26417 +f 36442/36442/26417 36441/36441/26416 36169/36169/26183 +f 36442/36442/26417 36169/36169/26183 36434/36434/26409 +f 36440/36440/26415 36439/36439/26414 36431/36431/26409 +f 36440/36440/26415 36431/36431/26409 36430/36430/26408 +f 36416/36416/26398 36415/36415/26397 36443/36443/26418 +f 36416/36416/26398 36443/36443/26418 36444/36444/26419 +f 36414/36414/26396 36413/36413/26395 36445/36445/26420 +f 36414/36414/26396 36445/36445/26420 36446/36446/26418 +f 36446/36446/26418 36445/36445/26420 36034/36034/26063 +f 36446/36446/26418 36034/36034/26063 36447/36447/26421 +f 36444/36444/26419 36443/36443/26418 36448/36448/26422 +f 36444/36444/26419 36448/36448/26422 36449/36449/26423 +f 36449/36449/26423 36448/36448/26422 36450/36450/26424 +f 36449/36449/26423 36450/36450/26424 36451/36451/26425 +f 36447/36447/26421 36034/36034/26063 36033/36033/26062 +f 36447/36447/26421 36033/36033/26062 36452/36452/26424 +f 36452/36452/26424 36033/36033/26062 36032/36032/26061 +f 36452/36452/26424 36032/36032/26061 36453/36453/26426 +f 36451/36451/26425 36450/36450/26424 36454/36454/26426 +f 36451/36451/26425 36454/36454/26426 36455/36455/26427 +f 36438/36438/26413 36437/36437/26412 36456/36456/26428 +f 36438/36438/26413 36456/36456/26428 36457/36457/26429 +f 36437/36437/26412 36458/36458/26430 36459/36459/26431 +f 36437/36437/26412 36459/36459/26431 36456/36456/26428 +f 36460/36460/26432 36461/36461/26431 36462/36462/26433 +f 36460/36460/26432 36462/36462/26433 36463/36463/26434 +f 36457/36457/26429 36456/36456/26428 36464/36464/26435 +f 36457/36457/26429 36464/36464/26435 36465/36465/26436 +f 36455/36455/26427 36454/36454/26426 36466/36466/26437 +f 36455/36455/26427 36466/36466/26437 36467/36467/26438 +f 36454/36454/26426 36468/36468/26061 36469/36469/26439 +f 36454/36454/26426 36469/36469/26439 36466/36466/26437 +f 36466/36466/26437 36469/36469/26439 36470/36470/26440 +f 36466/36466/26437 36470/36470/26440 36471/36471/26441 +f 36467/36467/26438 36466/36466/26437 36471/36471/26441 +f 36467/36467/26438 36471/36471/26441 36472/36472/26442 +f 36473/36473/26443 36474/36474/26444 36475/36475/26445 +f 36473/36473/26443 36475/36475/26445 36476/36476/26446 +f 36477/36477/26444 36478/36478/26447 36479/36479/26448 +f 36477/36477/26444 36479/36479/26448 36480/36480/26449 +f 36480/36480/26449 36479/36479/26448 36481/36481/26450 +f 36480/36480/26449 36481/36481/26450 36482/36482/26451 +f 36476/36476/26446 36475/36475/26445 36483/36483/26451 +f 36476/36476/26446 36483/36483/26451 36484/36484/26452 +f 36485/36485/26453 36486/36486/26454 36487/36487/26455 +f 36485/36485/26453 36487/36487/26455 36488/36488/26456 +f 36489/36489/26454 35926/35926/25962 35925/35925/25961 +f 36489/36489/26454 35925/35925/25961 36490/36490/26457 +f 36490/36490/26457 35925/35925/25961 35924/35924/25960 +f 36490/36490/26457 35924/35924/25960 36491/36491/26458 +f 36488/36488/26456 36487/36487/26455 36492/36492/26458 +f 36488/36488/26456 36492/36492/26458 36493/36493/26459 +f 36494/36494/26460 36495/36495/26461 36496/36496/26462 +f 36494/36494/26460 36496/36496/26462 36497/36497/26463 +f 36498/36498/26464 36499/36499/26465 36500/36500/26466 +f 36498/36498/26464 36500/36500/26466 36501/36501/26467 +f 36501/36501/26467 36500/36500/26466 36502/36502/26468 +f 36501/36501/26467 36502/36502/26468 36503/36503/26469 +f 36497/36497/26463 36496/36496/26462 36504/36504/26470 +f 36497/36497/26463 36504/36504/26470 36505/36505/26471 +f 36506/36506/26472 36507/36507/26473 36508/36508/26474 +f 36506/36506/26472 36508/36508/26474 36509/36509/26475 +f 36507/36507/26473 36510/36510/26476 36511/36511/26477 +f 36507/36507/26473 36511/36511/26477 36508/36508/26474 +f 36508/36508/26474 36511/36511/26477 36512/36512/26478 +f 36508/36508/26474 36512/36512/26478 36513/36513/26479 +f 36509/36509/26475 36508/36508/26474 36513/36513/26479 +f 36509/36509/26475 36513/36513/26479 36514/36514/26480 +f 36515/36515/26481 36516/36516/26482 36517/36517/26483 +f 36515/36515/26481 36517/36517/26483 36518/36518/26484 +f 36519/36519/26485 36520/36520/26486 36521/36521/26487 +f 36519/36519/26485 36521/36521/26487 36522/36522/26483 +f 36523/36523/26483 36524/36524/26488 36525/36525/26489 +f 36523/36523/26483 36525/36525/26489 36526/36526/26490 +f 36527/36527/26484 36523/36523/26483 36526/36526/26490 +f 36527/36527/26484 36526/36526/26490 35985/35985/26017 +f 36528/36528/26491 36529/36529/26492 36530/36530/26493 +f 36528/36528/26491 36530/36530/26493 36531/36531/26494 +f 36532/36532/26492 36533/36533/26495 36534/36534/26496 +f 36532/36532/26492 36534/36534/26496 36535/36535/26497 +f 36535/36535/26497 36534/36534/26496 36536/36536/26498 +f 36535/36535/26497 36536/36536/26498 36537/36537/26499 +f 36531/36531/26494 36530/36530/26493 36538/36538/26499 +f 36531/36531/26494 36538/36538/26499 36539/36539/26500 +f 36540/36540/26501 36541/36541/26502 36542/36542/26503 +f 36540/36540/26501 36542/36542/26503 36543/36543/26504 +f 36544/36544/26505 35960/35960/25995 36545/36545/26506 +f 36544/36544/26505 36545/36545/26506 36546/36546/26507 +f 36546/36546/26507 36545/36545/26506 36547/36547/26508 +f 36546/36546/26507 36547/36547/26508 36548/36548/26509 +f 36543/36543/26504 36542/36542/26503 36549/36549/26510 +f 36543/36543/26504 36549/36549/26510 36550/36550/26511 +f 36039/36039/26068 36036/36036/26065 36551/36551/26512 +f 36039/36039/26068 36551/36551/26512 36083/36083/26106 +f 36036/36036/26065 36035/36035/26064 36172/36172/26186 +f 36036/36036/26065 36172/36172/26186 36551/36551/26512 +f 36551/36551/26512 36172/36172/26186 36176/36176/26190 +f 36551/36551/26512 36176/36176/26190 36552/36552/26513 +f 36083/36083/26106 36551/36551/26512 36552/36552/26513 +f 36083/36083/26106 36552/36552/26513 36084/36084/26107 +f 36553/36553/26514 36554/36554/26515 36555/36555/26516 +f 36553/36553/26514 36555/36555/26516 36556/36556/26517 +f 36554/36554/26515 36557/36557/26518 36558/36558/26519 +f 36554/36554/26515 36558/36558/26519 36555/36555/26516 +f 36555/36555/26516 36558/36558/26519 36502/36502/26468 +f 36555/36555/26516 36502/36502/26468 36500/36500/26466 +f 36556/36556/26517 36555/36555/26516 36500/36500/26466 +f 36556/36556/26517 36500/36500/26466 36499/36499/26465 +f 35940/35940/25976 36559/36559/26520 36560/36560/26521 +f 35940/35940/25976 36560/36560/26521 36561/36561/26522 +f 36559/36559/26520 36562/36562/25912 36563/36563/25964 +f 36559/36559/26520 36563/36563/25964 36560/36560/26521 +f 36560/36560/26521 36563/36563/25964 36564/36564/26523 +f 36560/36560/26521 36564/36564/26523 36565/36565/26524 +f 36561/36561/26522 36560/36560/26521 36565/36565/26524 +f 36561/36561/26522 36565/36565/26524 36566/36566/26525 +f 36107/36107/26126 36110/36110/26129 36567/36567/26526 +f 36107/36107/26126 36567/36567/26526 36568/36568/26527 +f 36110/36110/26129 36114/36114/26133 36569/36569/26528 +f 36110/36110/26129 36569/36569/26528 36567/36567/26526 +f 36567/36567/26526 36569/36569/26528 36536/36536/26498 +f 36567/36567/26526 36536/36536/26498 36534/36534/26496 +f 36568/36568/26527 36567/36567/26526 36534/36534/26496 +f 36568/36568/26527 36534/36534/26496 36533/36533/26495 +f 35880/35880/25917 35879/35879/25915 36570/36570/26529 +f 35880/35880/25917 36570/36570/26529 36571/36571/26530 +f 35879/35879/25915 35878/35878/25914 36572/36572/26531 +f 35879/35879/25915 36572/36572/26531 36570/36570/26529 +f 36570/36570/26529 36572/36572/26531 36573/36573/26532 +f 36570/36570/26529 36573/36573/26532 36574/36574/26533 +f 36571/36571/26530 36570/36570/26529 36574/36574/26533 +f 36571/36571/26530 36574/36574/26533 36575/36575/26534 +f 36019/36019/26051 36016/36016/26048 36576/36576/26535 +f 36019/36019/26051 36576/36576/26535 36577/36577/26536 +f 36016/36016/26048 36015/36015/26047 36029/36029/26058 +f 36016/36016/26048 36029/36029/26058 36576/36576/26535 +f 36576/36576/26535 36029/36029/26058 36034/36034/26063 +f 36576/36576/26535 36034/36034/26063 36445/36445/26420 +f 36577/36577/26536 36576/36576/26535 36445/36445/26420 +f 36577/36577/26536 36445/36445/26420 36413/36413/26395 +f 36578/36578/26537 36579/36579/26538 36580/36580/26539 +f 36578/36578/26537 36580/36580/26539 36581/36581/26540 +f 36579/36579/26538 36582/36582/26156 36583/36583/26541 +f 36579/36579/26538 36583/36583/26541 36580/36580/26539 +f 36580/36580/26539 36583/36583/26541 36584/36584/26542 +f 36580/36580/26539 36584/36584/26542 36585/36585/26543 +f 36581/36581/26540 36580/36580/26539 36585/36585/26543 +f 36581/36581/26540 36585/36585/26543 36586/36586/26544 +f 36388/36388/26373 36391/36391/26376 36587/36587/26545 +f 36388/36388/26373 36587/36587/26545 36588/36588/26546 +f 36391/36391/26376 36396/36396/26381 36589/36589/26547 +f 36391/36391/26376 36589/36589/26547 36587/36587/26545 +f 36590/36590/26548 36591/36591/26547 36592/36592/26549 +f 36590/36590/26548 36592/36592/26549 36593/36593/26550 +f 36588/36588/26546 36587/36587/26545 36594/36594/26550 +f 36588/36588/26546 36594/36594/26550 36595/36595/26551 +f 35990/35990/26022 35997/35997/26029 36596/36596/26552 +f 35990/35990/26022 36596/36596/26552 35991/35991/26023 +f 35997/35997/26029 35971/35971/26004 36597/36597/26553 +f 35997/35997/26029 36597/36597/26553 36596/36596/26552 +f 36596/36596/26552 36597/36597/26553 36598/36598/26554 +f 36596/36596/26552 36598/36598/26554 36599/36599/26555 +f 35991/35991/26023 36596/36596/26552 36599/36599/26555 +f 35991/35991/26023 36599/36599/26555 35992/35992/26024 +f 35885/35885/25922 35946/35946/25982 36600/36600/26556 +f 35885/35885/25922 36600/36600/26556 35886/35886/25923 +f 35946/35946/25982 35945/35945/25981 36601/36601/26105 +f 35946/35946/25982 36601/36601/26105 36600/36600/26556 +f 36600/36600/26556 36601/36601/26105 36602/36602/26109 +f 36600/36600/26556 36602/36602/26109 36603/36603/26557 +f 35886/35886/25923 36600/36600/26556 36603/36603/26557 +f 35886/35886/25923 36603/36603/26557 35887/35887/25924 +f 36155/36155/26170 36158/36158/26173 36604/36604/26558 +f 36155/36155/26170 36604/36604/26558 36605/36605/26559 +f 36606/36606/26173 36607/36607/26177 36608/36608/26560 +f 36606/36606/26173 36608/36608/26560 36609/36609/26558 +f 36609/36609/26558 36608/36608/26560 36525/36525/26489 +f 36609/36609/26558 36525/36525/26489 36524/36524/26488 +f 36605/36605/26559 36604/36604/26558 36521/36521/26487 +f 36605/36605/26559 36521/36521/26487 36520/36520/26486 +f 35973/35973/26006 35996/35996/26028 36610/36610/26561 +f 35973/35973/26006 36610/36610/26561 36088/36088/26111 +f 35996/35996/26028 35999/35999/26031 36165/36165/26179 +f 35996/35996/26028 36165/36165/26179 36610/36610/26561 +f 36610/36610/26561 36165/36165/26179 36169/36169/26183 +f 36610/36610/26561 36169/36169/26183 36441/36441/26416 +f 36088/36088/26111 36610/36610/26561 36441/36441/26416 +f 36088/36088/26111 36441/36441/26416 36089/36089/26112 +f 36611/36611/26562 36612/36612/26563 36613/36613/26564 +f 36611/36611/26562 36613/36613/26564 36614/36614/26060 +f 36612/36612/26563 36615/36615/26565 36616/36616/26566 +f 36612/36612/26563 36616/36616/26566 36613/36613/26564 +f 36613/36613/26564 36616/36616/26566 36617/36617/26440 +f 36613/36613/26564 36617/36617/26440 36618/36618/26439 +f 36614/36614/26060 36613/36613/26564 36618/36618/26439 +f 36614/36614/26060 36618/36618/26439 36619/36619/26061 +f 35894/35894/25931 35891/35891/25928 36620/36620/26567 +f 35894/35894/25931 36620/36620/26567 35914/35914/25950 +f 35891/35891/25928 35890/35890/25927 36621/36621/26568 +f 35891/35891/25928 36621/36621/26568 36620/36620/26567 +f 36620/36620/26567 36621/36621/26568 36622/36622/26381 +f 36620/36620/26567 36622/36622/26381 36623/36623/26380 +f 35914/35914/25950 36620/36620/26567 36623/36623/26380 +f 35914/35914/25950 36623/36623/26380 35915/35915/25951 +f 36010/36010/26042 36061/36061/26085 36624/36624/26569 +f 36010/36010/26042 36624/36624/26569 36011/36011/26043 +f 36061/36061/26085 36060/36060/26084 36625/36625/26570 +f 36061/36061/26085 36625/36625/26570 36624/36624/26569 +f 36624/36624/26569 36625/36625/26570 36626/36626/26571 +f 36624/36624/26569 36626/36626/26571 36627/36627/26572 +f 36011/36011/26043 36624/36624/26569 36627/36627/26572 +f 36011/36011/26043 36627/36627/26572 36012/36012/26044 +f 36135/36135/26151 36138/36138/26154 36628/36628/26573 +f 36135/36135/26151 36628/36628/26573 36629/36629/26574 +f 36138/36138/26154 36142/36142/26158 36630/36630/26575 +f 36138/36138/26154 36630/36630/26575 36628/36628/26573 +f 36628/36628/26573 36630/36630/26575 36481/36481/26450 +f 36628/36628/26573 36481/36481/26450 36479/36479/26448 +f 36629/36629/26574 36628/36628/26573 36479/36479/26448 +f 36629/36629/26574 36479/36479/26448 36478/36478/26447 +f 35867/35870/25904 36100/36100/26120 36631/36631/26576 +f 35867/35870/25904 36631/36631/26576 35868/35871/25905 +f 36100/36100/26120 36019/36019/26051 36577/36577/26536 +f 36100/36100/26120 36577/36577/26536 36631/36631/26576 +f 36631/36631/26576 36577/36577/26536 36413/36413/26395 +f 36631/36631/26576 36413/36413/26395 36411/36411/26393 +f 35868/35871/25905 36631/36631/26576 36411/36411/26393 +f 35868/35871/25905 36411/36411/26393 35869/35872/25906 +f 36056/36056/26076 36059/36059/26083 36632/36632/26577 +f 36056/36056/26076 36632/36632/26577 36633/36633/26578 +f 36059/36059/26083 36063/36063/26087 36634/36634/26579 +f 36059/36059/26083 36634/36634/26579 36632/36632/26577 +f 36632/36632/26577 36634/36634/26579 36462/36462/26433 +f 36632/36632/26577 36462/36462/26433 36461/36461/26431 +f 36633/36633/26578 36632/36632/26577 36461/36461/26431 +f 36633/36633/26578 36461/36461/26431 36635/36635/26430 +f 35956/35956/25991 36636/36636/26580 36637/36637/26581 +f 35956/35956/25991 36637/36637/26581 36638/36638/26582 +f 36636/36636/26580 36639/36639/26583 36640/36640/26584 +f 36636/36636/26580 36640/36640/26584 36637/36637/26581 +f 36637/36637/26581 36640/36640/26584 36641/36641/26585 +f 36637/36637/26581 36641/36641/26585 36642/36642/26586 +f 36638/36638/26582 36637/36637/26581 36642/36642/26586 +f 36638/36638/26582 36642/36642/26586 36643/36643/26587 +f 35971/35971/26004 35970/35970/26003 36644/36644/26588 +f 35971/35971/26004 36644/36644/26588 36597/36597/26553 +f 35970/35970/26003 35942/35942/25978 36645/36645/26589 +f 35970/35970/26003 36645/36645/26589 36644/36644/26588 +f 36644/36644/26588 36645/36645/26589 36646/36646/26590 +f 36644/36644/26588 36646/36646/26590 36647/36647/26591 +f 36597/36597/26553 36644/36644/26588 36647/36647/26591 +f 36597/36597/26553 36647/36647/26591 36598/36598/26554 +f 36648/36648/26592 36649/36649/26593 36650/36650/26594 +f 36648/36648/26592 36650/36650/26594 36651/36651/26595 +f 36649/36649/26593 36652/36652/26596 36653/36653/26597 +f 36649/36649/26593 36653/36653/26597 36650/36650/26594 +f 36650/36650/26594 36653/36653/26597 36654/36654/26478 +f 36650/36650/26594 36654/36654/26478 36655/36655/26477 +f 36651/36651/26595 36650/36650/26594 36655/36655/26477 +f 36651/36651/26595 36655/36655/26477 36656/36656/26598 +f 35942/35942/25978 35941/35941/25977 36657/36657/26599 +f 35942/35942/25978 36657/36657/26599 36645/36645/26589 +f 35941/35941/25977 35940/35940/25976 36561/36561/26522 +f 35941/35941/25977 36561/36561/26522 36657/36657/26599 +f 36657/36657/26599 36561/36561/26522 36566/36566/26525 +f 36657/36657/26599 36566/36566/26525 36658/36658/26600 +f 36645/36645/26589 36657/36657/26599 36658/36658/26600 +f 36645/36645/26589 36658/36658/26600 36646/36646/26590 +f 36383/36383/26370 36659/36659/26601 36660/36660/26602 +f 36383/36383/26370 36660/36660/26602 36661/36661/26603 +f 36659/36659/26601 36662/36662/26091 36663/36663/26604 +f 36659/36659/26601 36663/36663/26604 36660/36660/26602 +f 36664/36664/26602 36665/36665/26604 35871/35874/25908 +f 36664/36664/26602 35871/35874/25908 36421/36421/26403 +f 36661/36661/26603 36660/36660/26602 36418/36418/26400 +f 36661/36661/26603 36418/36418/26400 36417/36417/26399 +f 36392/36392/26377 36666/36666/26605 36667/36667/26606 +f 36392/36392/26377 36667/36667/26606 36668/36668/26607 +f 36666/36666/26605 36669/36669/26532 36670/36670/26608 +f 36666/36666/26605 36670/36670/26608 36667/36667/26606 +f 36667/36667/26606 36670/36670/26608 36401/36401/26037 +f 36667/36667/26606 36401/36401/26037 36398/36398/26383 +f 36668/36668/26607 36667/36667/26606 36398/36398/26383 +f 36668/36668/26607 36398/36398/26383 36397/36397/26382 +f 36671/36671/26609 36672/36672/26610 36673/36673/26611 +f 36671/36671/26609 36673/36673/26611 36674/36674/26531 +f 36672/36672/26610 35936/35936/25972 36001/36001/26033 +f 36672/36672/26610 36001/36001/26033 36673/36673/26611 +f 36673/36673/26611 36001/36001/26033 36005/36005/26037 +f 36673/36673/26611 36005/36005/26037 36675/36675/26608 +f 36674/36674/26531 36673/36673/26611 36675/36675/26608 +f 36674/36674/26531 36675/36675/26608 36676/36676/26532 +f 36671/36671/26609 36677/36677/25913 36678/36678/26612 +f 36671/36671/26609 36678/36678/26612 36672/36672/26610 +f 36677/36677/25913 36562/36562/25912 36559/36559/26520 +f 36677/36677/25913 36559/36559/26520 36678/36678/26612 +f 36678/36678/26612 36559/36559/26520 35940/35940/25976 +f 36678/36678/26612 35940/35940/25976 35937/35937/25973 +f 36672/36672/26610 36678/36678/26612 35937/35937/25973 +f 36672/36672/26610 35937/35937/25973 35936/35936/25972 +f 35896/35896/25933 35895/35895/25932 36679/36679/26613 +f 35896/35896/25933 36679/36679/26613 36680/36680/26614 +f 35895/35895/25932 35894/35894/25931 35911/35911/25947 +f 35895/35895/25932 35911/35911/25947 36679/36679/26613 +f 36679/36679/26613 35911/35911/25947 35910/35910/25946 +f 36679/36679/26613 35910/35910/25946 35931/35931/25967 +f 36680/36680/26614 36679/36679/26613 35931/35931/25967 +f 36680/36680/26614 35931/35931/25967 35863/35866/25900 +f 35934/35934/25970 35933/35933/25969 36681/36681/26615 +f 35934/35934/25970 36681/36681/26615 36173/36173/26187 +f 35933/35933/25969 35910/35910/25946 35913/35913/25949 +f 35933/35933/25969 35913/35913/25949 36681/36681/26615 +f 36681/36681/26615 35913/35913/25949 35917/35917/25953 +f 36681/36681/26615 35917/35917/25953 36682/36682/26616 +f 36173/36173/26187 36681/36681/26615 36682/36682/26616 +f 36173/36173/26187 36682/36682/26616 36174/36174/26188 +f 35896/35896/25933 36680/36680/26614 36683/36683/26617 +f 35896/35896/25933 36683/36683/26617 36066/36066/26090 +f 36680/36680/26614 35863/35866/25900 35866/35869/25903 +f 36680/36680/26614 35866/35869/25903 36683/36683/26617 +f 36683/36683/26617 35866/35869/25903 35871/35874/25908 +f 36683/36683/26617 35871/35874/25908 36665/36665/26604 +f 36066/36066/26090 36683/36683/26617 36665/36665/26604 +f 36066/36066/26090 36665/36665/26604 36067/36067/26091 +f 36684/36684/26618 36685/36685/26619 36686/36686/26620 +f 36684/36684/26618 36686/36686/26620 36687/36687/26621 +f 36685/36685/26619 36688/36688/26622 36689/36689/26623 +f 36685/36685/26619 36689/36689/26623 36686/36686/26620 +f 36686/36686/26620 36689/36689/26623 36690/36690/26624 +f 36686/36686/26620 36690/36690/26624 36691/36691/26625 +f 36687/36687/26621 36686/36686/26620 36691/36691/26625 +f 36687/36687/26621 36691/36691/26625 36099/36099/26119 +f 36684/36684/26618 36687/36687/26621 36692/36692/26626 +f 36684/36684/26618 36692/36692/26626 36693/36693/26627 +f 36687/36687/26621 36099/36099/26119 36097/36097/26118 +f 36687/36687/26621 36097/36097/26118 36692/36692/26626 +f 36692/36692/26626 36097/36097/26118 36096/36096/26117 +f 36692/36692/26626 36096/36096/26117 36694/36694/26628 +f 36693/36693/26627 36692/36692/26626 36694/36694/26628 +f 36693/36693/26627 36694/36694/26628 36695/36695/26629 +f 36696/36696/26622 36697/36697/26630 36698/36698/26631 +f 36696/36696/26622 36698/36698/26631 36699/36699/26632 +f 36697/36697/26630 36700/36700/26633 36701/36701/26634 +f 36697/36697/26630 36701/36701/26634 36698/36698/26631 +f 36698/36698/26631 36701/36701/26634 36702/36702/26635 +f 36698/36698/26631 36702/36702/26635 36703/36703/26636 +f 36699/36699/26632 36698/36698/26631 36703/36703/26636 +f 36699/36699/26632 36703/36703/26636 36704/36704/26637 +f 35890/35890/25927 35893/35893/25930 36705/36705/26638 +f 35890/35890/25927 36705/36705/26638 36706/36706/26639 +f 35893/35893/25930 35898/35898/25935 36092/36092/26115 +f 35893/35893/25930 36092/36092/26115 36705/36705/26638 +f 36707/36707/26638 36098/36098/26115 36099/36099/26119 +f 36707/36707/26638 36099/36099/26119 36691/36691/26625 +f 36708/36708/26639 36707/36707/26638 36691/36691/26625 +f 36708/36708/26639 36691/36691/26625 36690/36690/26624 +f 35872/35863/25909 35875/35865/25916 36709/36709/26640 +f 35872/35863/25909 36709/36709/26640 35903/35903/25940 +f 35875/35865/25916 35880/35880/25917 36710/36710/26641 +f 35875/35865/25916 36710/36710/26641 36709/36709/26640 +f 36711/36711/26640 36712/36712/26642 36700/36700/26633 +f 36711/36711/26640 36700/36700/26633 36713/36713/26643 +f 35905/35905/25940 36711/36711/26640 36713/36713/26643 +f 35905/35905/25940 36713/36713/26643 35906/35906/25942 +f 36714/36714/26381 36715/36715/26568 36716/36716/26644 +f 36714/36714/26381 36716/36716/26644 36591/36591/26547 +f 36621/36621/26568 35890/35890/25927 36706/36706/26639 +f 36621/36621/26568 36706/36706/26639 36717/36717/26645 +f 36716/36716/26644 36708/36708/26639 36690/36690/26624 +f 36716/36716/26644 36690/36690/26624 36718/36718/26646 +f 36591/36591/26547 36716/36716/26644 36718/36718/26646 +f 36591/36591/26547 36718/36718/26646 36592/36592/26549 +f 36379/36379/26366 36382/36382/26369 36719/36719/26647 +f 36379/36379/26366 36719/36719/26647 36720/36720/26648 +f 36382/36382/26369 36387/36387/25936 36721/36721/25939 +f 36382/36382/26369 36721/36721/25939 36719/36719/26647 +f 36719/36719/26647 36721/36721/25939 36722/36722/25945 +f 36719/36719/26647 36722/36722/25945 36723/36723/26649 +f 36720/36720/26648 36719/36719/26647 36723/36723/26649 +f 36720/36720/26648 36723/36723/26649 36724/36724/26629 +f 35880/35880/25917 36571/36571/26530 36725/36725/26650 +f 35880/35880/25917 36725/36725/26650 36710/36710/26641 +f 36571/36571/26530 36575/36575/26534 36726/36726/26651 +f 36571/36571/26530 36726/36726/26651 36725/36725/26650 +f 36727/36727/26650 36728/36728/26651 36702/36702/26635 +f 36727/36727/26650 36702/36702/26635 36701/36701/26634 +f 36712/36712/26642 36727/36727/26650 36701/36701/26634 +f 36712/36712/26642 36701/36701/26634 36700/36700/26633 +f 36729/36729/26652 36730/36730/26653 36731/36731/26654 +f 36729/36729/26652 36731/36731/26654 36732/36732/26655 +f 36730/36730/26653 36733/36733/26656 36734/36734/26657 +f 36730/36730/26653 36734/36734/26657 36731/36731/26654 +f 36731/36731/26654 36734/36734/26657 36735/36735/26658 +f 36731/36731/26654 36735/36735/26658 36736/36736/26659 +f 36732/36732/26655 36731/36731/26654 36736/36736/26659 +f 36732/36732/26655 36736/36736/26659 36737/36737/26660 +f 36342/36342/26330 36341/36341/26329 36738/36738/26661 +f 36342/36342/26330 36738/36738/26661 36739/36739/26662 +f 36340/36340/26329 36339/36339/26328 36359/36359/26346 +f 36340/36340/26329 36359/36359/26346 36740/36740/26663 +f 36740/36740/26663 36359/36359/26346 36364/36364/26351 +f 36740/36740/26663 36364/36364/26351 36741/36741/26664 +f 36739/36739/26662 36738/36738/26661 36742/36742/26664 +f 36739/36739/26662 36742/36742/26664 36743/36743/26652 +f 36372/36372/26359 36371/36371/26358 36744/36744/26665 +f 36372/36372/26359 36744/36744/26665 36745/36745/26666 +f 36746/36746/26667 36747/36747/26356 36748/36748/26668 +f 36746/36746/26667 36748/36748/26668 36749/36749/26665 +f 36749/36749/26665 36748/36748/26668 36735/36735/26658 +f 36749/36749/26665 36735/36735/26658 36734/36734/26657 +f 36745/36745/26666 36744/36744/26665 36750/36750/26669 +f 36745/36745/26666 36750/36750/26669 36751/36751/26656 +f 36747/36747/26356 36752/36752/26363 36753/36753/26670 +f 36747/36747/26356 36753/36753/26670 36748/36748/26668 +f 36376/36376/26363 36375/36375/26362 36754/36754/26671 +f 36376/36376/26363 36754/36754/26671 36755/36755/26670 +f 36753/36753/26670 36756/36756/26671 36737/36737/26660 +f 36753/36753/26670 36737/36737/26660 36736/36736/26659 +f 36748/36748/26668 36753/36753/26670 36736/36736/26659 +f 36748/36748/26668 36736/36736/26659 36735/36735/26658 +f 36757/36757/26672 36758/36758/26673 36759/36759/26674 +f 36757/36757/26672 36759/36759/26674 36760/36760/26675 +f 36758/36758/26673 36761/36761/26237 36762/36762/26676 +f 36758/36758/26673 36762/36762/26676 36759/36759/26674 +f 36763/36763/26677 36764/36764/26678 36765/36765/26679 +f 36763/36763/26677 36765/36765/26679 36766/36766/26680 +f 36767/36767/26681 36763/36763/26677 36766/36766/26680 +f 36767/36767/26681 36766/36766/26680 36768/36768/26682 +f 36769/36769/26683 36770/36770/26684 36771/36771/26685 +f 36769/36769/26683 36771/36771/26685 36772/36772/26686 +f 36773/36773/26687 36757/36757/26672 36760/36760/26675 +f 36773/36773/26687 36760/36760/26675 36774/36774/26688 +f 36771/36771/26685 36767/36767/26681 36768/36768/26682 +f 36771/36771/26685 36768/36768/26682 36775/36775/26689 +f 36772/36772/26686 36771/36771/26685 36775/36775/26689 +f 36772/36772/26686 36775/36775/26689 36776/36776/26690 +f 36777/36777/26691 36778/36778/26692 36779/36779/26693 +f 36777/36777/26691 36779/36779/26693 36780/36780/26694 +f 36781/36781/26695 36782/36782/26696 36783/36783/26697 +f 36781/36781/26695 36783/36783/26697 36784/36784/26698 +f 36785/36785/26698 36786/36786/26699 36787/36787/26700 +f 36785/36785/26698 36787/36787/26700 36788/36788/26701 +f 36780/36780/26694 36779/36779/26693 36789/36789/26701 +f 36780/36780/26694 36789/36789/26701 36790/36790/26702 +f 36791/36791/26703 36792/36792/26704 36793/36793/26705 +f 36791/36791/26703 36793/36793/26705 36794/36794/26706 +f 36792/36792/26704 36795/36795/26707 36796/36796/26708 +f 36792/36792/26704 36796/36796/26708 36793/36793/26705 +f 36797/36797/26705 36798/36798/26708 36799/36799/26709 +f 36797/36797/26705 36799/36799/26709 36800/36800/26710 +f 36801/36801/26706 36797/36797/26705 36800/36800/26710 +f 36801/36801/26706 36800/36800/26710 36802/36802/26711 +f 36239/36239/26247 36803/36803/26712 36804/36804/26713 +f 36239/36239/26247 36804/36804/26713 36805/36805/26714 +f 36806/36806/26712 36807/36807/26715 36808/36808/26716 +f 36806/36806/26712 36808/36808/26716 36809/36809/26713 +f 36809/36809/26713 36808/36808/26716 36810/36810/26717 +f 36809/36809/26713 36810/36810/26717 36811/36811/26718 +f 36805/36805/26714 36804/36804/26713 36812/36812/26719 +f 36805/36805/26714 36812/36812/26719 36813/36813/26720 +f 36213/36213/26224 36814/36814/26721 36815/36815/26722 +f 36213/36213/26224 36815/36815/26722 36816/36816/26723 +f 36227/36227/26238 36226/36226/26237 36817/36817/26244 +f 36227/36227/26238 36817/36817/26244 36818/36818/26722 +f 36819/36819/26722 36241/36241/26244 36242/36242/26249 +f 36819/36819/26722 36242/36242/26249 36820/36820/26724 +f 36821/36821/26725 36822/36822/26726 36823/36823/26727 +f 36821/36821/26725 36823/36823/26727 36824/36824/26728 +f 36235/36235/26245 36825/36825/26729 36826/36826/26730 +f 36235/36235/26245 36826/36826/26730 36236/36236/26246 +f 36827/36827/26729 36217/36217/26228 36828/36828/26731 +f 36827/36827/26729 36828/36828/26731 36829/36829/26730 +f 36830/36830/26730 36831/36831/26732 36832/36832/26715 +f 36830/36830/26730 36832/36832/26715 36833/36833/26712 +f 36238/36238/26246 36834/36834/26730 36803/36803/26712 +f 36238/36238/26246 36803/36803/26712 36239/36239/26247 +f 36217/36217/26228 36214/36214/26225 36835/36835/26733 +f 36217/36217/26228 36835/36835/26733 36828/36828/26731 +f 36214/36214/26225 36213/36213/26224 36816/36816/26723 +f 36214/36214/26225 36816/36816/26723 36835/36835/26733 +f 36836/36836/26733 36837/36837/26723 36838/36838/26728 +f 36836/36836/26733 36838/36838/26728 36839/36839/26734 +f 36831/36831/26732 36836/36836/26733 36839/36839/26734 +f 36831/36831/26732 36839/36839/26734 36832/36832/26715 +f 36810/36810/26717 36840/36840/26735 36841/36841/26736 +f 36810/36810/26717 36841/36841/26736 36842/36842/26737 +f 36840/36840/26735 36843/36843/26738 36844/36844/26739 +f 36840/36840/26735 36844/36844/26739 36841/36841/26736 +f 36841/36841/26736 36844/36844/26739 36845/36845/26740 +f 36841/36841/26736 36845/36845/26740 36846/36846/26741 +f 36842/36842/26737 36841/36841/26736 36846/36846/26741 +f 36842/36842/26737 36846/36846/26741 36847/36847/26742 +f 36807/36807/26715 36848/36848/26743 36849/36849/26744 +f 36807/36807/26715 36849/36849/26744 36808/36808/26716 +f 36848/36848/26743 36824/36824/26728 36850/36850/26745 +f 36848/36848/26743 36850/36850/26745 36849/36849/26744 +f 36849/36849/26744 36850/36850/26745 36843/36843/26738 +f 36849/36849/26744 36843/36843/26738 36840/36840/26735 +f 36808/36808/26716 36849/36849/26744 36840/36840/26735 +f 36808/36808/26716 36840/36840/26735 36810/36810/26717 +f 36242/36242/26249 36240/36240/26248 36851/36851/26746 +f 36242/36242/26249 36851/36851/26746 36852/36852/26747 +f 36240/36240/26248 36239/36239/26247 36805/36805/26714 +f 36240/36240/26248 36805/36805/26714 36851/36851/26746 +f 36851/36851/26746 36805/36805/26714 36813/36813/26720 +f 36851/36851/26746 36813/36813/26720 36853/36853/26748 +f 36852/36852/26747 36851/36851/26746 36853/36853/26748 +f 36852/36852/26747 36853/36853/26748 36854/36854/26749 +f 36824/36824/26728 36823/36823/26727 36855/36855/26750 +f 36824/36824/26728 36855/36855/26750 36850/36850/26745 +f 36820/36820/26724 36242/36242/26249 36852/36852/26747 +f 36820/36820/26724 36852/36852/26747 36856/36856/26751 +f 36856/36856/26751 36852/36852/26747 36854/36854/26749 +f 36856/36856/26751 36854/36854/26749 36857/36857/26752 +f 36850/36850/26745 36855/36855/26750 36858/36858/26753 +f 36850/36850/26745 36858/36858/26753 36843/36843/26738 +f 36859/36859/26754 36860/36860/26755 36861/36861/26756 +f 36859/36859/26754 36861/36861/26756 36862/36862/26757 +f 36860/36860/26755 36863/36863/26758 36864/36864/26759 +f 36860/36860/26755 36864/36864/26759 36861/36861/26756 +f 36861/36861/26756 36864/36864/26759 36865/36865/26760 +f 36861/36861/26756 36865/36865/26760 36866/36866/26761 +f 36862/36862/26757 36861/36861/26756 36866/36866/26761 +f 36862/36862/26757 36866/36866/26761 36867/36867/26762 +f 36854/36854/26749 36853/36853/26748 36868/36868/26763 +f 36854/36854/26749 36868/36868/26763 36869/36869/26764 +f 36853/36853/26748 36813/36813/26720 36870/36870/26765 +f 36853/36853/26748 36870/36870/26765 36868/36868/26763 +f 36871/36871/26766 36872/36872/26765 36863/36863/26758 +f 36871/36871/26766 36863/36863/26758 36860/36860/26755 +f 36873/36873/26767 36871/36871/26766 36860/36860/26755 +f 36873/36873/26767 36860/36860/26755 36859/36859/26754 +f 36843/36843/26738 36858/36858/26753 36874/36874/26768 +f 36843/36843/26738 36874/36874/26768 36844/36844/26739 +f 36857/36857/26752 36854/36854/26749 36869/36869/26764 +f 36857/36857/26752 36869/36869/26764 36875/36875/26769 +f 36876/36876/26769 36873/36873/26767 36859/36859/26754 +f 36876/36876/26769 36859/36859/26754 36877/36877/26770 +f 36844/36844/26739 36874/36874/26768 36878/36878/26771 +f 36844/36844/26739 36878/36878/26771 36845/36845/26740 +f 36813/36813/26720 36812/36812/26719 36879/36879/26772 +f 36813/36813/26720 36879/36879/26772 36870/36870/26765 +f 36811/36811/26718 36810/36810/26717 36842/36842/26737 +f 36811/36811/26718 36842/36842/26737 36880/36880/26773 +f 36881/36881/26773 36882/36882/26737 36883/36883/26742 +f 36881/36881/26773 36883/36883/26742 36884/36884/26774 +f 36872/36872/26765 36885/36885/26773 36886/36886/26775 +f 36872/36872/26765 36886/36886/26775 36863/36863/26758 +f 36865/36865/26760 36887/36887/26776 36888/36888/26777 +f 36865/36865/26760 36888/36888/26777 36889/36889/26778 +f 36890/36890/26776 36891/36891/26779 36892/36892/26780 +f 36890/36890/26776 36892/36892/26780 36893/36893/26781 +f 36893/36893/26781 36892/36892/26780 36894/36894/26782 +f 36893/36893/26781 36894/36894/26782 36895/36895/26783 +f 36889/36889/26778 36888/36888/26777 36896/36896/26783 +f 36889/36889/26778 36896/36896/26783 36897/36897/26784 +f 36898/36898/26740 36899/36899/26771 36900/36900/26785 +f 36898/36898/26740 36900/36900/26785 36901/36901/26786 +f 36877/36877/26770 36859/36859/26754 36862/36862/26757 +f 36877/36877/26770 36862/36862/26757 36902/36902/26787 +f 36902/36902/26787 36862/36862/26757 36867/36867/26762 +f 36902/36902/26787 36867/36867/26762 36903/36903/26788 +f 36901/36901/26786 36900/36900/26785 36904/36904/26788 +f 36901/36901/26786 36904/36904/26788 36905/36905/26789 +f 36863/36863/26758 36886/36886/26775 36906/36906/26790 +f 36863/36863/26758 36906/36906/26790 36864/36864/26759 +f 36884/36884/26774 36883/36883/26742 36907/36907/26791 +f 36884/36884/26774 36907/36907/26791 36908/36908/26792 +f 36908/36908/26792 36907/36907/26791 36891/36891/26779 +f 36908/36908/26792 36891/36891/26779 36890/36890/26776 +f 36864/36864/26759 36906/36906/26790 36887/36887/26776 +f 36864/36864/26759 36887/36887/26776 36865/36865/26760 +f 36883/36883/26742 36909/36909/26741 36910/36910/26793 +f 36883/36883/26742 36910/36910/26793 36907/36907/26791 +f 36909/36909/26741 36898/36898/26740 36901/36901/26786 +f 36909/36909/26741 36901/36901/26786 36910/36910/26793 +f 36910/36910/26793 36901/36901/26786 36905/36905/26789 +f 36910/36910/26793 36905/36905/26789 36911/36911/26794 +f 36907/36907/26791 36910/36910/26793 36911/36911/26794 +f 36907/36907/26791 36911/36911/26794 36891/36891/26779 +f 36912/36912/26795 36913/36913/26796 36914/36914/26797 +f 36912/36912/26795 36914/36914/26797 36915/36915/26798 +f 36913/36913/26796 36916/36916/26784 36917/36917/26799 +f 36913/36913/26796 36917/36917/26799 36914/36914/26797 +f 36918/36918/26800 36895/36895/26783 36894/36894/26782 +f 36918/36918/26800 36894/36894/26782 36919/36919/26801 +f 36920/36920/26802 36918/36918/26800 36919/36919/26801 +f 36920/36920/26802 36919/36919/26801 36921/36921/26803 +f 36891/36891/26779 36911/36911/26794 36922/36922/26804 +f 36891/36891/26779 36922/36922/26804 36892/36892/26780 +f 36911/36911/26794 36905/36905/26789 36923/36923/26805 +f 36911/36911/26794 36923/36923/26805 36922/36922/26804 +f 36922/36922/26804 36923/36923/26805 36921/36921/26803 +f 36922/36922/26804 36921/36921/26803 36919/36919/26801 +f 36892/36892/26780 36922/36922/26804 36919/36919/26801 +f 36892/36892/26780 36919/36919/26801 36894/36894/26782 +f 36867/36867/26762 36866/36866/26761 36924/36924/26806 +f 36867/36867/26762 36924/36924/26806 36925/36925/26807 +f 36866/36866/26761 36865/36865/26760 36889/36889/26778 +f 36866/36866/26761 36889/36889/26778 36924/36924/26806 +f 36924/36924/26806 36889/36889/26778 36897/36897/26784 +f 36924/36924/26806 36897/36897/26784 36926/36926/26796 +f 36925/36925/26807 36924/36924/26806 36926/36926/26796 +f 36925/36925/26807 36926/36926/26796 36927/36927/26795 +f 36905/36905/26789 36904/36904/26788 36928/36928/26808 +f 36905/36905/26789 36928/36928/26808 36923/36923/26805 +f 36903/36903/26788 36867/36867/26762 36925/36925/26807 +f 36903/36903/26788 36925/36925/26807 36929/36929/26808 +f 36929/36929/26808 36925/36925/26807 36927/36927/26795 +f 36929/36929/26808 36927/36927/26795 36930/36930/26802 +f 36923/36923/26805 36928/36928/26808 36920/36920/26802 +f 36923/36923/26805 36920/36920/26802 36921/36921/26803 +f 36154/36154/26169 36153/36153/26168 36931/36931/26809 +f 36154/36154/26169 36931/36931/26809 36932/36932/26810 +f 36152/36152/26167 36151/36151/26166 36933/36933/26811 +f 36152/36152/26167 36933/36933/26811 36934/36934/26812 +f 36934/36934/26812 36933/36933/26811 36791/36791/26703 +f 36934/36934/26812 36791/36791/26703 36935/36935/26813 +f 36932/36932/26810 36931/36931/26809 36936/36936/26814 +f 36932/36932/26810 36936/36936/26814 36937/36937/26815 +f 36200/36200/26211 36199/36199/26210 36938/36938/26816 +f 36200/36200/26211 36938/36938/26816 36939/36939/26817 +f 36198/36198/26210 36197/36197/26209 36940/36940/26818 +f 36198/36198/26210 36940/36940/26818 36941/36941/26816 +f 36941/36941/26816 36940/36940/26818 36782/36782/26696 +f 36941/36941/26816 36782/36782/26696 36781/36781/26695 +f 36939/36939/26817 36938/36938/26816 36778/36778/26692 +f 36939/36939/26817 36778/36778/26692 36777/36777/26691 +f 36197/36197/26209 36206/36206/26217 36942/36942/26819 +f 36197/36197/26209 36942/36942/26819 36940/36940/26818 +f 36206/36206/26217 36205/36205/26216 36943/36943/26820 +f 36206/36206/26217 36943/36943/26820 36942/36942/26819 +f 36942/36942/26819 36943/36943/26820 36944/36944/26821 +f 36942/36942/26819 36944/36944/26821 36945/36945/26822 +f 36940/36940/26818 36942/36942/26819 36945/36945/26822 +f 36940/36940/26818 36945/36945/26822 36782/36782/26696 +f 36151/36151/26166 36212/36212/26223 36946/36946/26823 +f 36151/36151/26166 36946/36946/26823 36933/36933/26811 +f 36212/36212/26223 36211/36211/26222 36947/36947/26824 +f 36212/36212/26223 36947/36947/26824 36946/36946/26823 +f 36946/36946/26823 36947/36947/26824 36795/36795/26707 +f 36946/36946/26823 36795/36795/26707 36792/36792/26704 +f 36933/36933/26811 36946/36946/26823 36792/36792/26704 +f 36933/36933/26811 36792/36792/26704 36791/36791/26703 +f 36948/36948/26825 36949/36949/26826 36950/36950/26827 +f 36948/36948/26825 36950/36950/26827 36951/36951/26828 +f 36949/36949/26826 36952/36952/26829 36953/36953/26830 +f 36949/36949/26826 36953/36953/26830 36950/36950/26827 +f 36954/36954/26831 36955/36955/26830 36956/36956/26832 +f 36954/36954/26831 36956/36956/26832 36957/36957/26833 +f 36958/36958/26828 36954/36954/26831 36957/36957/26833 +f 36958/36958/26828 36957/36957/26833 36959/36959/26834 +f 36960/36960/26835 36961/36961/26836 36962/36962/26837 +f 36960/36960/26835 36962/36962/26837 36963/36963/26838 +f 36961/36961/26836 36948/36948/26825 36951/36951/26828 +f 36961/36961/26836 36951/36951/26828 36962/36962/26837 +f 36964/36964/26837 36958/36958/26828 36959/36959/26834 +f 36964/36964/26837 36959/36959/26834 36965/36965/26839 +f 36966/36966/26838 36967/36967/26837 36968/36968/26840 +f 36966/36966/26838 36968/36968/26840 36969/36969/26841 +f 36970/36970/26842 36971/36971/26843 36972/36972/26844 +f 36970/36970/26842 36972/36972/26844 36973/36973/26845 +f 36971/36971/26843 36802/36802/26711 36974/36974/26846 +f 36971/36971/26843 36974/36974/26846 36972/36972/26844 +f 36975/36975/26844 36976/36976/26847 36977/36977/26848 +f 36975/36975/26844 36977/36977/26848 36978/36978/26849 +f 36979/36979/26845 36980/36980/26850 36981/36981/26849 +f 36979/36979/26845 36981/36981/26849 36982/36982/26851 +f 36787/36787/26700 36983/36983/26852 36984/36984/26853 +f 36787/36787/26700 36984/36984/26853 36985/36985/26854 +f 36983/36983/26852 36986/36986/26855 36987/36987/26856 +f 36983/36983/26852 36987/36987/26856 36984/36984/26853 +f 36988/36988/26853 36989/36989/26857 36990/36990/26858 +f 36988/36988/26853 36990/36990/26858 36991/36991/26859 +f 36992/36992/26854 36988/36988/26853 36991/36991/26859 +f 36992/36992/26854 36991/36991/26859 36993/36993/26860 +f 36782/36782/26696 36945/36945/26822 36994/36994/26861 +f 36782/36782/26696 36994/36994/26861 36783/36783/26697 +f 36945/36945/26822 36944/36944/26821 36995/36995/26862 +f 36945/36945/26822 36995/36995/26862 36994/36994/26861 +f 36996/36996/26863 36997/36997/26862 36986/36986/26855 +f 36996/36996/26863 36986/36986/26855 36983/36983/26852 +f 36786/36786/26699 36996/36996/26863 36983/36983/26852 +f 36786/36786/26699 36983/36983/26852 36787/36787/26700 +f 36937/36937/26815 36936/36936/26814 36998/36998/26864 +f 36937/36937/26815 36998/36998/26864 36999/36999/26865 +f 36935/36935/26813 36791/36791/26703 36794/36794/26706 +f 36935/36935/26813 36794/36794/26706 37000/37000/26864 +f 37001/37001/26864 36801/36801/26706 36802/36802/26711 +f 37001/37001/26864 36802/36802/26711 36971/36971/26843 +f 37002/37002/26866 37001/37001/26864 36971/36971/26843 +f 37002/37002/26866 36971/36971/26843 36970/36970/26842 +f 37003/37003/26867 37004/37004/26868 37005/37005/26869 +f 37003/37003/26867 37005/37005/26869 37006/37006/26870 +f 37004/37004/26868 37007/37007/26871 37008/37008/26872 +f 37004/37004/26868 37008/37008/26872 37005/37005/26869 +f 37005/37005/26869 37008/37008/26872 36948/36948/26825 +f 37005/37005/26869 36948/36948/26825 36961/36961/26836 +f 37006/37006/26870 37005/37005/26869 36961/36961/26836 +f 37006/37006/26870 36961/36961/26836 36960/36960/26835 +f 37007/37007/26871 37009/37009/26873 37010/37010/26874 +f 37007/37007/26871 37010/37010/26874 37008/37008/26872 +f 37009/37009/26873 37011/37011/26196 37012/37012/26875 +f 37009/37009/26873 37012/37012/26875 37010/37010/26874 +f 37010/37010/26874 37012/37012/26875 36952/36952/26829 +f 37010/37010/26874 36952/36952/26829 36949/36949/26826 +f 37008/37008/26872 37010/37010/26874 36949/36949/26826 +f 37008/37008/26872 36949/36949/26826 36948/36948/26825 +f 36977/36977/26848 37013/37013/26876 37014/37014/26877 +f 36977/36977/26848 37014/37014/26877 37015/37015/26878 +f 37013/37013/26876 37016/37016/26879 37017/37017/26880 +f 37013/37013/26876 37017/37017/26880 37014/37014/26877 +f 37014/37014/26877 37017/37017/26880 36959/36959/26834 +f 37014/37014/26877 36959/36959/26834 36957/36957/26833 +f 37015/37015/26878 37014/37014/26877 36957/36957/26833 +f 37015/37015/26878 36957/36957/26833 36956/36956/26832 +f 36993/36993/26860 36991/36991/26859 37018/37018/26881 +f 36993/36993/26860 37018/37018/26881 37019/37019/26882 +f 36991/36991/26859 36990/36990/26858 37020/37020/26883 +f 36991/36991/26859 37020/37020/26883 37018/37018/26881 +f 37018/37018/26881 37020/37020/26883 37021/37021/26884 +f 37018/37018/26881 37021/37021/26884 37022/37022/26885 +f 37019/37019/26882 37018/37018/26881 37022/37022/26885 +f 37019/37019/26882 37022/37022/26885 37023/37023/26886 +f 37024/37024/26887 37025/37025/26888 37026/37026/26889 +f 37024/37024/26887 37026/37026/26889 37027/37027/26890 +f 37028/37028/26888 36993/36993/26860 37019/37019/26882 +f 37028/37028/26888 37019/37019/26882 37029/37029/26891 +f 37029/37029/26891 37019/37019/26882 37023/37023/26886 +f 37029/37029/26891 37023/37023/26886 37030/37030/26892 +f 37027/37027/26890 37026/37026/26889 37031/37031/26892 +f 37027/37027/26890 37031/37031/26892 36969/36969/26841 +f 36982/36982/26851 36981/36981/26849 37032/37032/26893 +f 36982/36982/26851 37032/37032/26893 37033/37033/26894 +f 36978/36978/26849 36977/36977/26848 37015/37015/26878 +f 36978/36978/26849 37015/37015/26878 37034/37034/26893 +f 37034/37034/26893 37015/37015/26878 36956/36956/26832 +f 37034/37034/26893 36956/36956/26832 37035/37035/26895 +f 37033/37033/26894 37032/37032/26893 37036/37036/26895 +f 37033/37033/26894 37036/37036/26895 37037/37037/26896 +f 36802/36802/26711 36800/36800/26710 37038/37038/26897 +f 36802/36802/26711 37038/37038/26897 36974/36974/26846 +f 36800/36800/26710 36799/36799/26709 37039/37039/26898 +f 36800/36800/26710 37039/37039/26898 37038/37038/26897 +f 37040/37040/26899 37041/37041/26898 37016/37016/26879 +f 37040/37040/26899 37016/37016/26879 37013/37013/26876 +f 36976/36976/26847 37040/37040/26899 37013/37013/26876 +f 36976/36976/26847 37013/37013/26876 36977/36977/26848 +f 37042/37042/26900 36788/36788/26701 37043/37043/26901 +f 37042/37042/26900 37043/37043/26901 37044/37044/26902 +f 36788/36788/26701 36787/36787/26700 36985/36985/26854 +f 36788/36788/26701 36985/36985/26854 37043/37043/26901 +f 37045/37045/26903 36992/36992/26854 36993/36993/26860 +f 37045/37045/26903 36993/36993/26860 37028/37028/26888 +f 37046/37046/26902 37047/37047/26903 37025/37025/26888 +f 37046/37046/26902 37025/37025/26888 37024/37024/26887 +f 36776/36776/26690 36775/36775/26689 37048/37048/26904 +f 36776/36776/26690 37048/37048/26904 37049/37049/26905 +f 36775/36775/26689 36768/36768/26682 37050/37050/26906 +f 36775/36775/26689 37050/37050/26906 37048/37048/26904 +f 37051/37051/26904 37052/37052/26907 37021/37021/26884 +f 37051/37051/26904 37021/37021/26884 37053/37053/26908 +f 37054/37054/26909 37055/37055/26910 37056/37056/26908 +f 37054/37054/26909 37056/37056/26908 37037/37037/26896 +f 36768/36768/26682 36766/36766/26680 37057/37057/26911 +f 36768/36768/26682 37057/37057/26911 37050/37050/26906 +f 36766/36766/26680 36765/36765/26679 37058/37058/26912 +f 36766/36766/26680 37058/37058/26912 37057/37057/26911 +f 37059/37059/26911 37060/37060/26912 37023/37023/26886 +f 37059/37059/26911 37023/37023/26886 37022/37022/26885 +f 37052/37052/26907 37059/37059/26911 37022/37022/26885 +f 37052/37052/26907 37022/37022/26885 37021/37021/26884 +f 36163/36163/26177 36162/36162/26176 37061/37061/26913 +f 36163/36163/26177 37061/37061/26913 37062/37062/26914 +f 36162/36162/26176 36161/36161/26098 37063/37063/26915 +f 36162/36162/26176 37063/37063/26915 37061/37061/26913 +f 37061/37061/26913 37063/37063/26915 36209/36209/26220 +f 37061/37061/26913 36209/36209/26220 36207/36207/26218 +f 37062/37062/26914 37061/37061/26913 36207/36207/26218 +f 37062/37062/26914 36207/36207/26218 36148/36148/26163 +f 36114/36114/26133 36113/36113/26132 37064/37064/26916 +f 36114/36114/26133 37064/37064/26916 37065/37065/26917 +f 36113/36113/26132 35979/35979/26011 37066/37066/26918 +f 36113/36113/26132 37066/37066/26918 37064/37064/26916 +f 37064/37064/26916 37066/37066/26918 36203/36203/26214 +f 37064/37064/26916 36203/36203/26214 36201/36201/26212 +f 37065/37065/26917 37064/37064/26916 36201/36201/26212 +f 37065/37065/26917 36201/36201/26212 36194/36194/26206 +f 37067/37067/26919 37068/37068/26920 37069/37069/26921 +f 37067/37067/26919 37069/37069/26921 37070/37070/26922 +f 37071/37071/26920 36114/36114/26133 37065/37065/26917 +f 37071/37071/26920 37065/37065/26917 37072/37072/26923 +f 37072/37072/26923 37065/37065/26917 36194/36194/26206 +f 37072/37072/26923 36194/36194/26206 36193/36193/26205 +f 37070/37070/26922 37069/37069/26921 36190/36190/26202 +f 37070/37070/26922 36190/36190/26202 36189/36189/26201 +f 37073/37073/26007 37074/37074/26924 37075/37075/26925 +f 37073/37073/26007 37075/37075/26925 37076/37076/26926 +f 37077/37077/26924 36163/36163/26177 37062/37062/26914 +f 37077/37077/26924 37062/37062/26914 37078/37078/26927 +f 37078/37078/26927 37062/37062/26914 36148/36148/26163 +f 37078/37078/26927 36148/36148/26163 36147/36147/26160 +f 37076/37076/26926 37075/37075/26925 36144/36144/26160 +f 37076/37076/26926 36144/36144/26160 36143/36143/26159 +f 37079/37079/26928 37080/37080/26929 37081/37081/26930 +f 37079/37079/26928 37081/37081/26930 37082/37082/26931 +f 37080/37080/26929 36155/36155/26170 36605/36605/26559 +f 37080/37080/26929 36605/36605/26559 37081/37081/26930 +f 37081/37081/26930 36605/36605/26559 36520/36520/26486 +f 37081/37081/26930 36520/36520/26486 37083/37083/26932 +f 37082/37082/26931 37081/37081/26930 37083/37083/26932 +f 37082/37082/26931 37083/37083/26932 37084/37084/26933 +f 36074/36074/26098 37085/37085/26934 37086/37086/26935 +f 36074/36074/26098 37086/37086/26935 36075/36075/26099 +f 36160/36160/26175 36159/36159/26174 37087/37087/26936 +f 36160/36160/26175 37087/37087/26936 37088/37088/26935 +f 37088/37088/26935 37087/37087/26936 37089/37089/26937 +f 37088/37088/26935 37089/37089/26937 37090/37090/26938 +f 36075/36075/26099 37086/37086/26935 37091/37091/26938 +f 36075/36075/26099 37091/37091/26938 36076/36076/26100 +f 36123/36123/26142 37092/37092/26939 37093/37093/26940 +f 36123/36123/26142 37093/37093/26940 37094/37094/26941 +f 37092/37092/26939 36107/36107/26126 36568/36568/26527 +f 37092/37092/26939 36568/36568/26527 37093/37093/26940 +f 37093/37093/26940 36568/36568/26527 36533/36533/26495 +f 37093/37093/26940 36533/36533/26495 37095/37095/26942 +f 37094/37094/26941 37093/37093/26940 37095/37095/26942 +f 37094/37094/26941 37095/37095/26942 37096/37096/26943 +f 35979/35979/26011 36112/36112/26131 37097/37097/26944 +f 35979/35979/26011 37097/37097/26944 35980/35980/26012 +f 36112/36112/26131 36111/36111/26130 37098/37098/26945 +f 36112/36112/26131 37098/37098/26945 37097/37097/26944 +f 37097/37097/26944 37098/37098/26945 37099/37099/26946 +f 37097/37097/26944 37099/37099/26946 37100/37100/26947 +f 35980/35980/26012 37097/37097/26944 37100/37100/26947 +f 35980/35980/26012 37100/37100/26947 35982/35982/26014 +f 37101/37101/26948 37102/37102/26949 37103/37103/26950 +f 37101/37101/26948 37103/37103/26950 37104/37104/26951 +f 37102/37102/26949 37105/37105/26943 37106/37106/26942 +f 37102/37102/26949 37106/37106/26942 37103/37103/26950 +f 37103/37103/26950 37106/37106/26942 37107/37107/26495 +f 37103/37103/26950 37107/37107/26495 36529/36529/26492 +f 37104/37104/26951 37103/37103/26950 36529/36529/26492 +f 37104/37104/26951 36529/36529/26492 36528/36528/26491 +f 37108/37108/26952 37109/37109/26953 37110/37110/26954 +f 37108/37108/26952 37110/37110/26954 37111/37111/26955 +f 37112/37112/26953 37084/37084/26933 37083/37083/26932 +f 37112/37112/26953 37083/37083/26932 37113/37113/26954 +f 37113/37113/26954 37083/37083/26932 36520/36520/26486 +f 37113/37113/26954 36520/36520/26486 36519/36519/26485 +f 37111/37111/26955 37110/37110/26954 36516/36516/26482 +f 37111/37111/26955 36516/36516/26482 36515/36515/26481 +f 37079/37079/26928 37114/37114/26956 37115/37115/26957 +f 37079/37079/26928 37115/37115/26957 37080/37080/26929 +f 37114/37114/26956 37116/37116/26958 37117/37117/26959 +f 37114/37114/26956 37117/37117/26959 37115/37115/26957 +f 37115/37115/26957 37117/37117/26959 36159/36159/26174 +f 37115/37115/26957 36159/36159/26174 36156/36156/26171 +f 37080/37080/26929 37115/37115/26957 36156/36156/26171 +f 37080/37080/26929 36156/36156/26171 36155/36155/26170 +f 36111/36111/26130 36108/36108/26127 37118/37118/26960 +f 36111/36111/26130 37118/37118/26960 37119/37119/26961 +f 36108/36108/26127 36107/36107/26126 37120/37120/26962 +f 36108/36108/26127 37120/37120/26962 37118/37118/26960 +f 37121/37121/26960 37122/37122/26962 37123/37123/26963 +f 37121/37121/26960 37123/37123/26963 37124/37124/26964 +f 37125/37125/26965 37121/37121/26960 37124/37124/26964 +f 37125/37125/26965 37124/37124/26964 37126/37126/26966 +f 35867/35870/25904 35935/35935/25971 37127/37127/26967 +f 35867/35870/25904 37127/37127/26967 36102/36102/26122 +f 35935/35935/25971 35934/35934/25970 37128/37128/26968 +f 35935/35935/25971 37128/37128/26968 37127/37127/26967 +f 37129/37129/26967 37130/37130/26969 37131/37131/26970 +f 37129/37129/26967 37131/37131/26970 37132/37132/26971 +f 37133/37133/26122 37129/37129/26967 37132/37132/26971 +f 37133/37133/26122 37132/37132/26971 37134/37134/26124 +f 37135/37135/26972 37136/37136/26157 37137/37137/26973 +f 37135/37135/26972 37137/37137/26973 37138/37138/26974 +f 37136/37136/26157 36582/36582/26156 36579/36579/26538 +f 37136/37136/26157 36579/36579/26538 37137/37137/26973 +f 37137/37137/26973 36579/36579/26538 36578/36578/26537 +f 37137/37137/26973 36578/36578/26537 37139/37139/26975 +f 37138/37138/26974 37137/37137/26973 37139/37139/26975 +f 37138/37138/26974 37139/37139/26975 37140/37140/26976 +f 36484/36484/26452 36483/36483/26451 37141/37141/26977 +f 36484/36484/26452 37141/37141/26977 37142/37142/26978 +f 36483/36483/26451 37143/37143/26450 37144/37144/26979 +f 36483/36483/26451 37144/37144/26979 37141/37141/26977 +f 37145/37145/26977 37146/37146/26979 37147/37147/26980 +f 37145/37145/26977 37147/37147/26980 37148/37148/26981 +f 37142/37142/26978 37141/37141/26977 37149/37149/26981 +f 37142/37142/26978 37149/37149/26981 37150/37150/26982 +f 36514/36514/26480 36513/36513/26479 37151/37151/26983 +f 36514/36514/26480 37151/37151/26983 37152/37152/26984 +f 36513/36513/26479 36512/36512/26478 37153/37153/26985 +f 36513/36513/26479 37153/37153/26985 37151/37151/26983 +f 37151/37151/26983 37153/37153/26985 37154/37154/26986 +f 37151/37151/26983 37154/37154/26986 37155/37155/26987 +f 37152/37152/26984 37151/37151/26983 37155/37155/26987 +f 37152/37152/26984 37155/37155/26987 37156/37156/26988 +f 36652/36652/26596 37157/37157/26989 37158/37158/26990 +f 36652/36652/26596 37158/37158/26990 36653/36653/26597 +f 37159/37159/26991 36127/36127/26146 37160/37160/26992 +f 37159/37159/26991 37160/37160/26992 37161/37161/26990 +f 37161/37161/26990 37160/37160/26992 37162/37162/26993 +f 37161/37161/26990 37162/37162/26993 37163/37163/26994 +f 36653/36653/26597 37158/37158/26990 37164/37164/26994 +f 36653/36653/26597 37164/37164/26994 36654/36654/26478 +f 37135/37135/26972 37138/37138/26974 37165/37165/26995 +f 37135/37135/26972 37165/37165/26995 37166/37166/26575 +f 37138/37138/26974 37140/37140/26976 37167/37167/26996 +f 37138/37138/26974 37167/37167/26996 37165/37165/26995 +f 37165/37165/26995 37167/37167/26996 37147/37147/26980 +f 37165/37165/26995 37147/37147/26980 37146/37146/26979 +f 37166/37166/26575 37165/37165/26995 37146/37146/26979 +f 37166/37166/26575 37146/37146/26979 37168/37168/26450 +f 37116/37116/26958 37169/37169/26997 37170/37170/26998 +f 37116/37116/26958 37170/37170/26998 37171/37171/26999 +f 37169/37169/26997 36578/36578/26537 36581/36581/26540 +f 37169/37169/26997 36581/36581/26540 37170/37170/26998 +f 37170/37170/26998 36581/36581/26540 36586/36586/26544 +f 37170/37170/26998 36586/36586/26544 37172/37172/27000 +f 37171/37171/26999 37170/37170/26998 37172/37172/27000 +f 37171/37171/26999 37172/37172/27000 37173/37173/27001 +f 37174/37174/27002 37175/37175/27003 37176/37176/27004 +f 37174/37174/27002 37176/37176/27004 37177/37177/27005 +f 37175/37175/27003 36540/36540/26501 36543/36543/26504 +f 37175/37175/27003 36543/36543/26504 37176/37176/27004 +f 37176/37176/27004 36543/36543/26504 36550/36550/26511 +f 37176/37176/27004 36550/36550/26511 37178/37178/27006 +f 37177/37177/27005 37176/37176/27004 37178/37178/27006 +f 37177/37177/27005 37178/37178/27006 37179/37179/27007 +f 36557/36557/26518 37180/37180/27008 37181/37181/27009 +f 36557/36557/26518 37181/37181/27009 36558/36558/26519 +f 37180/37180/27008 36648/36648/26592 36651/36651/26595 +f 37180/37180/27008 36651/36651/26595 37181/37181/27009 +f 37181/37181/27009 36651/36651/26595 36656/36656/26598 +f 37181/37181/27009 36656/36656/26598 37182/37182/27010 +f 36558/36558/26519 37181/37181/27009 37182/37182/27010 +f 36558/36558/26519 37182/37182/27010 36502/36502/26468 +f 35960/35960/25995 35957/35957/25992 37183/37183/27011 +f 35960/35960/25995 37183/37183/27011 36545/36545/26506 +f 35957/35957/25992 35956/35956/25991 36638/36638/26582 +f 35957/35957/25992 36638/36638/26582 37183/37183/27011 +f 37183/37183/27011 36638/36638/26582 36643/36643/26587 +f 37183/37183/27011 36643/36643/26587 37184/37184/27012 +f 36545/36545/26506 37183/37183/27011 37184/37184/27012 +f 36545/36545/26506 37184/37184/27012 36547/36547/26508 +f 35922/35922/25958 37185/37185/27013 37186/37186/27014 +f 35922/35922/25958 37186/37186/27014 35923/35923/25959 +f 37185/37185/27013 36135/36135/26151 36629/36629/26574 +f 37185/37185/27013 36629/36629/26574 37186/37186/27014 +f 37186/37186/27014 36629/36629/26574 36478/36478/26447 +f 37186/37186/27014 36478/36478/26447 37187/37187/27015 +f 35923/35923/25959 37186/37186/27014 37187/37187/27015 +f 35923/35923/25959 37187/37187/27015 35924/35924/25960 +f 36505/36505/26471 36504/36504/26470 37188/37188/27016 +f 36505/36505/26471 37188/37188/27016 37189/37189/27017 +f 36503/36503/26469 36502/36502/26468 37182/37182/27010 +f 36503/36503/26469 37182/37182/27010 37190/37190/27018 +f 37190/37190/27018 37182/37182/27010 36656/36656/26598 +f 37190/37190/27018 36656/36656/26598 37191/37191/27019 +f 37189/37189/27017 37188/37188/27016 36507/36507/26473 +f 37189/37189/27017 36507/36507/26473 36506/36506/26472 +f 36493/36493/26459 36492/36492/26458 37192/37192/27020 +f 36493/36493/26459 37192/37192/27020 37193/37193/27021 +f 36491/36491/26458 35924/35924/25960 37187/37187/27015 +f 36491/36491/26458 37187/37187/27015 37194/37194/27020 +f 37194/37194/27020 37187/37187/27015 36478/36478/26447 +f 37194/37194/27020 36478/36478/26447 36477/36477/26444 +f 37193/37193/27021 37192/37192/27020 36474/36474/26444 +f 37193/37193/27021 36474/36474/26444 36473/36473/26443 +f 35922/35922/25958 36055/36055/26081 37195/37195/27022 +f 35922/35922/25958 37195/37195/27022 37185/37185/27013 +f 36055/36055/26081 36054/36054/26080 36116/36116/26135 +f 36055/36055/26081 36116/36116/26135 37195/37195/27022 +f 37195/37195/27022 36116/36116/26135 36115/36115/26134 +f 37195/37195/27022 36115/36115/26134 36136/36136/26152 +f 37185/37185/27013 37195/37195/27022 36136/36136/26152 +f 37185/37185/27013 36136/36136/26152 36135/36135/26151 +f 37196/37196/27002 37197/37197/27023 37198/37198/27024 +f 37196/37196/27002 37198/37198/27024 37199/37199/27025 +f 37200/37200/27023 36111/36111/26130 37119/37119/26961 +f 37200/37200/27023 37119/37119/26961 37201/37201/27024 +f 37201/37201/27024 37119/37119/26961 37202/37202/26966 +f 37201/37201/27024 37202/37202/26966 37203/37203/27026 +f 37199/37199/27025 37198/37198/27024 37204/37204/27027 +f 37199/37199/27025 37204/37204/27027 37205/37205/27028 +f 36140/36140/26156 36139/36139/26155 37206/37206/27029 +f 36140/36140/26156 37206/37206/27029 37207/37207/26541 +f 36139/36139/26155 36115/36115/26134 36118/36118/26137 +f 36139/36139/26155 36118/36118/26137 37206/37206/27029 +f 37206/37206/27029 36118/36118/26137 36122/36122/26141 +f 37206/37206/27029 36122/36122/26141 37208/37208/27030 +f 37207/37207/26541 37206/37206/27029 37208/37208/27030 +f 37207/37207/26541 37208/37208/27030 37209/37209/26542 +f 36615/36615/26565 37210/37210/27031 37211/37211/27032 +f 36615/36615/26565 37211/37211/27032 36616/36616/26566 +f 37210/37210/27031 36553/36553/26514 36556/36556/26517 +f 37210/37210/27031 36556/36556/26517 37211/37211/27032 +f 37211/37211/27032 36556/36556/26517 36499/36499/26465 +f 37211/37211/27032 36499/36499/26465 37212/37212/27033 +f 36616/36616/26566 37211/37211/27032 37212/37212/27033 +f 36616/36616/26566 37212/37212/27033 36617/36617/26440 +f 36472/36472/26442 36471/36471/26441 37213/37213/27034 +f 36472/36472/26442 37213/37213/27034 37214/37214/27035 +f 37215/37215/26441 36617/36617/26440 37212/37212/27033 +f 37215/37215/26441 37212/37212/27033 37216/37216/27034 +f 37216/37216/27034 37212/37212/27033 36499/36499/26465 +f 37216/37216/27034 36499/36499/26465 36498/36498/26464 +f 37214/37214/27035 37213/37213/27034 36495/36495/26461 +f 37214/37214/27035 36495/36495/26461 36494/36494/26460 +f 36465/36465/26436 36464/36464/26435 37217/37217/27036 +f 36465/36465/26436 37217/37217/27036 37218/37218/27037 +f 36463/36463/26434 36462/36462/26433 37219/37219/27038 +f 36463/36463/26434 37219/37219/27038 37220/37220/27036 +f 37220/37220/27036 37219/37219/27038 35926/35926/25962 +f 37220/37220/27036 35926/35926/25962 36489/36489/26454 +f 37218/37218/27037 37217/37217/27036 36486/36486/26454 +f 37218/37218/27037 36486/36486/26454 36485/36485/26453 +f 36557/36557/26518 36554/36554/26515 37221/37221/27039 +f 36557/36557/26518 37221/37221/27039 37222/37222/27040 +f 36554/36554/26515 36553/36553/26514 37223/37223/27041 +f 36554/36554/26515 37223/37223/27041 37221/37221/27039 +f 37224/37224/27039 37225/37225/27041 37226/37226/27042 +f 37224/37224/27039 37226/37226/27042 37227/37227/27043 +f 37228/37228/27040 37224/37224/27039 37227/37227/27043 +f 37228/37228/27040 37227/37227/27043 37229/37229/27044 +f 36063/36063/26087 36062/36062/26086 37230/37230/27045 +f 36063/36063/26087 37230/37230/27045 37231/37231/27046 +f 36062/36062/26086 36010/36010/26042 36007/36007/26039 +f 36062/36062/26086 36007/36007/26039 37230/37230/27045 +f 37230/37230/27045 36007/36007/26039 36006/36006/26038 +f 37230/37230/27045 36006/36006/26038 36051/36051/26077 +f 37231/37231/27046 37230/37230/27045 36051/36051/26077 +f 37231/37231/27046 36051/36051/26077 35918/35918/25954 +f 36054/36054/26080 36053/36053/26079 37232/37232/27047 +f 36054/36054/26080 37232/37232/27047 36119/36119/26138 +f 36053/36053/26079 36006/36006/26038 36009/36009/26041 +f 36053/36053/26079 36009/36009/26041 37232/37232/27047 +f 37232/37232/27047 36009/36009/26041 36014/36014/26046 +f 37232/37232/27047 36014/36014/26046 37233/37233/27048 +f 36119/36119/26138 37232/37232/27047 37233/37233/27048 +f 36119/36119/26138 37233/37233/27048 36120/36120/26139 +f 36063/36063/26087 37231/37231/27046 37234/37234/27049 +f 36063/36063/26087 37234/37234/27049 36634/36634/26579 +f 37231/37231/27046 35918/35918/25954 35921/35921/25957 +f 37231/37231/27046 35921/35921/25957 37234/37234/27049 +f 37234/37234/27049 35921/35921/25957 35926/35926/25962 +f 37234/37234/27049 35926/35926/25962 37219/37219/27038 +f 36634/36634/26579 37234/37234/27049 37219/37219/27038 +f 36634/36634/26579 37219/37219/27038 36462/36462/26433 +f 36639/36639/26583 37235/37235/27050 37236/37236/27051 +f 36639/36639/26583 37236/37236/27051 36640/36640/26584 +f 37235/37235/27050 35881/35881/25918 35884/35884/25921 +f 37235/37235/27050 35884/35884/25921 37236/37236/27051 +f 37236/37236/27051 35884/35884/25921 35889/35889/25926 +f 37236/37236/27051 35889/35889/25926 37237/37237/27052 +f 36640/36640/26584 37236/37236/27051 37237/37237/27052 +f 36640/36640/26584 37237/37237/27052 36641/36641/26585 +f 37205/37205/27028 37204/37204/27027 37238/37238/27053 +f 37205/37205/27028 37238/37238/27053 37239/37239/27054 +f 37203/37203/27026 37202/37202/26966 37240/37240/27055 +f 37203/37203/27026 37240/37240/27055 37241/37241/27056 +f 37241/37241/27056 37240/37240/27055 37242/37242/27057 +f 37241/37241/27056 37242/37242/27057 37243/37243/27058 +f 37244/37244/27059 37241/37241/27056 37243/37243/27058 +f 37244/37244/27059 37243/37243/27058 37245/37245/27060 +f 36046/36046/26072 36044/36044/26071 37246/37246/27061 +f 36046/36046/26072 37246/37246/27061 37247/37247/27062 +f 36044/36044/26071 36043/36043/26070 37248/37248/27063 +f 36044/36044/26071 37248/37248/27063 37246/37246/27061 +f 37249/37249/27061 37250/37250/27063 37251/37251/27064 +f 37249/37249/27061 37251/37251/27064 37252/37252/27065 +f 37253/37253/27066 37249/37249/27061 37252/37252/27065 +f 37253/37253/27066 37252/37252/27065 37254/37254/27067 +f 37255/37255/27068 37256/37256/27069 37257/37257/27070 +f 37255/37255/27068 37257/37257/27070 37258/37258/27071 +f 37256/37256/27069 37259/37259/27072 37260/37260/27073 +f 37256/37256/27069 37260/37260/27073 37257/37257/27070 +f 37261/37261/27074 37262/37262/27073 37263/37263/27075 +f 37261/37261/27074 37263/37263/27075 37264/37264/27076 +f 37265/37265/27077 37261/37261/27074 37264/37264/27076 +f 37265/37265/27077 37264/37264/27076 37266/37266/27078 +f 36131/36131/26148 37267/37267/27079 37268/37268/27080 +f 36131/36131/26148 37268/37268/27080 37269/37269/27081 +f 37267/37267/27079 37270/37270/27082 37271/37271/27083 +f 37267/37267/27079 37271/37271/27083 37268/37268/27080 +f 37272/37272/27080 37273/37273/27084 37274/37274/27085 +f 37272/37272/27080 37274/37274/27085 37275/37275/27086 +f 37276/37276/27081 37277/37277/27080 37278/37278/27087 +f 37276/37276/27081 37278/37278/27087 37279/37279/27088 +f 37280/37280/27089 37281/37281/27090 37282/37282/27091 +f 37280/37280/27089 37282/37282/27091 37283/37283/27092 +f 37281/37281/27090 37229/37229/27044 37284/37284/27093 +f 37281/37281/27090 37284/37284/27093 37282/37282/27091 +f 37285/37285/27094 37286/37286/27095 37287/37287/27096 +f 37285/37285/27094 37287/37287/27096 37288/37288/27097 +f 37289/37289/27098 37285/37285/27094 37288/37288/27097 +f 37289/37289/27098 37288/37288/27097 37290/37290/27099 +f 35955/35955/25990 35953/35953/25989 37291/37291/27100 +f 35955/35955/25990 37291/37291/27100 37292/37292/27101 +f 35953/35953/25989 35952/35952/25988 37293/37293/27102 +f 35953/35953/25989 37293/37293/27102 37291/37291/27100 +f 37294/37294/27100 37295/37295/27103 37296/37296/27104 +f 37294/37294/27100 37296/37296/27104 37297/37297/27105 +f 37298/37298/27106 37294/37294/27100 37297/37297/27105 +f 37298/37298/27106 37297/37297/27105 37299/37299/27107 +f 37270/37270/27082 37300/37300/27108 37301/37301/27109 +f 37270/37270/27082 37301/37301/27109 37271/37271/27083 +f 37300/37300/27108 37280/37280/27089 37283/37283/27092 +f 37300/37300/27108 37283/37283/27092 37301/37301/27109 +f 37302/37302/27110 37289/37289/27098 37290/37290/27099 +f 37302/37302/27110 37290/37290/27099 37303/37303/27111 +f 37273/37273/27084 37302/37302/27110 37303/37303/27111 +f 37273/37273/27084 37303/37303/27111 37274/37274/27085 +f 37304/37304/27112 37305/37305/27113 37306/37306/27114 +f 37304/37304/27112 37306/37306/27114 37307/37307/27115 +f 37305/37305/27113 36046/36046/26072 37247/37247/27062 +f 37305/37305/27113 37247/37247/27062 37306/37306/27114 +f 37308/37308/27116 37253/37253/27066 37254/37254/27067 +f 37308/37308/27116 37254/37254/27067 37309/37309/27117 +f 37310/37310/27118 37308/37308/27116 37309/37309/27117 +f 37310/37310/27118 37309/37309/27117 37311/37311/27119 +f 35967/35967/26000 35965/35965/25999 37312/37312/27120 +f 35967/35967/26000 37312/37312/27120 37313/37313/27121 +f 35965/35965/25999 35964/35964/25998 37314/37314/27122 +f 35965/35965/25999 37314/37314/27122 37312/37312/27120 +f 37315/37315/27123 37316/37316/27124 37317/37317/27125 +f 37315/37315/27123 37317/37317/27125 37318/37318/27126 +f 37319/37319/27127 37315/37315/27123 37318/37318/27126 +f 37319/37319/27127 37318/37318/27126 37320/37320/27128 +f 37321/37321/27129 37322/37322/27130 37323/37323/27131 +f 37321/37321/27129 37323/37323/27131 37324/37324/27132 +f 37322/37322/27130 35967/35967/26000 37313/37313/27121 +f 37322/37322/27130 37313/37313/27121 37323/37323/27131 +f 37325/37325/27131 37319/37319/27127 37320/37320/27128 +f 37325/37325/27131 37320/37320/27128 37326/37326/27133 +f 37327/37327/27132 37325/37325/27131 37326/37326/27133 +f 37327/37327/27132 37326/37326/27133 37328/37328/27134 +f 35934/35934/25970 36170/36170/26184 37329/37329/27135 +f 35934/35934/25970 37329/37329/27135 37128/37128/26968 +f 36170/36170/26184 36035/36035/26064 36038/36038/26067 +f 36170/36170/26184 36038/36038/26067 37329/37329/27135 +f 37330/37330/27136 36045/36045/26067 36046/36046/26072 +f 37330/37330/27136 36046/36046/26072 37305/37305/27113 +f 37331/37331/26969 37330/37330/27136 37305/37305/27113 +f 37331/37331/26969 37305/37305/27113 37304/37304/27112 +f 36039/36039/26068 36080/36080/26103 37332/37332/27137 +f 36039/36039/26068 37332/37332/27137 36040/36040/26069 +f 37333/37333/27138 35945/35945/25981 35948/35948/25984 +f 37333/37333/27138 35948/35948/25984 37334/37334/27137 +f 37335/37335/27137 35954/35954/25984 35955/35955/25990 +f 37335/37335/27137 35955/35955/25990 37336/37336/27139 +f 36042/36042/26069 37335/37335/27137 37336/37336/27139 +f 36042/36042/26069 37336/37336/27139 36043/36043/26070 +f 36648/36648/26592 37180/37180/27008 37337/37337/27140 +f 36648/36648/26592 37337/37337/27140 37338/37338/27141 +f 37180/37180/27008 36557/36557/26518 37222/37222/27040 +f 37180/37180/27008 37222/37222/27040 37337/37337/27140 +f 37339/37339/27142 37228/37228/27040 37229/37229/27044 +f 37339/37339/27142 37229/37229/27044 37281/37281/27090 +f 37340/37340/27143 37339/37339/27142 37281/37281/27090 +f 37340/37340/27143 37281/37281/27090 37280/37280/27089 +f 36615/36615/26565 36612/36612/26563 37341/37341/27144 +f 36615/36615/26565 37341/37341/27144 37342/37342/27145 +f 37343/37343/26563 36030/36030/26059 37344/37344/27146 +f 37343/37343/26563 37344/37344/27146 37345/37345/27147 +f 37346/37346/27147 37347/37347/27148 37259/37259/27072 +f 37346/37346/27147 37259/37259/27072 37256/37256/27069 +f 37348/37348/27145 37346/37346/27147 37256/37256/27069 +f 37348/37348/27145 37256/37256/27069 37255/37255/27068 +f 36030/36030/26059 36027/36027/26056 37349/37349/27149 +f 36030/36030/26059 37349/37349/27149 37344/37344/27146 +f 36027/36027/26056 36015/36015/26047 36018/36018/26050 +f 36027/36027/26056 36018/36018/26050 37349/37349/27149 +f 37350/37350/27149 36025/36025/26050 36026/36026/26055 +f 37350/37350/27149 36026/36026/26055 37351/37351/27150 +f 37347/37347/27148 37350/37350/27149 37351/37351/27150 +f 37347/37347/27148 37351/37351/27150 37259/37259/27072 +f 35960/35960/25995 36544/36544/26505 37352/37352/27151 +f 35960/35960/25995 37352/37352/27151 35961/35961/25996 +f 37353/37353/26502 37354/37354/27152 37355/37355/27153 +f 37353/37353/26502 37355/37355/27153 37356/37356/27151 +f 37356/37356/27151 37355/37355/27153 37357/37357/27154 +f 37356/37356/27151 37357/37357/27154 37358/37358/27155 +f 35963/35963/25996 37356/37356/27151 37358/37358/27155 +f 35963/35963/25996 37358/37358/27155 35964/35964/25998 +f 35881/35881/25918 37235/37235/27050 37359/37359/27156 +f 35881/35881/25918 37359/37359/27156 37360/37360/27157 +f 37235/37235/27050 36639/36639/26583 37361/37361/27158 +f 37235/37235/27050 37361/37361/27158 37359/37359/27156 +f 37362/37362/27156 37363/37363/27159 37321/37321/27129 +f 37362/37362/27156 37321/37321/27129 37364/37364/27160 +f 37365/37365/27161 37362/37362/27156 37364/37364/27160 +f 37365/37365/27161 37364/37364/27160 37366/37366/27162 +f 36639/36639/26583 36636/36636/26580 37367/37367/27163 +f 36639/36639/26583 37367/37367/27163 37361/37361/27158 +f 36636/36636/26580 35956/35956/25991 35959/35959/25994 +f 36636/36636/26580 35959/35959/25994 37367/37367/27163 +f 37368/37368/27164 35966/35966/25994 35967/35967/26000 +f 37368/37368/27164 35967/35967/26000 37322/37322/27130 +f 37363/37363/27159 37368/37368/27164 37322/37322/27130 +f 37363/37363/27159 37322/37322/27130 37321/37321/27129 +f 35885/35885/25922 35882/35882/25919 37369/37369/27165 +f 35885/35885/25922 37369/37369/27165 35949/35949/25985 +f 35882/35882/25919 35881/35881/25918 37360/37360/27157 +f 35882/35882/25919 37360/37360/27157 37369/37369/27165 +f 37370/37370/27165 37365/37365/27161 37366/37366/27162 +f 37370/37370/27165 37366/37366/27162 37371/37371/27166 +f 35951/35951/25987 37370/37370/27165 37371/37371/27166 +f 35951/35951/25987 37371/37371/27166 35952/35952/25988 +f 36127/36127/26146 37159/37159/26991 37372/37372/27167 +f 36127/36127/26146 37372/37372/27167 36128/36128/26147 +f 37159/37159/26991 37373/37373/27168 37374/37374/27169 +f 37159/37159/26991 37374/37374/27169 37372/37372/27167 +f 37375/37375/27167 37376/37376/27169 37270/37270/27082 +f 37375/37375/27167 37270/37270/27082 37267/37267/27079 +f 36130/36130/26147 37375/37375/27167 37267/37267/27079 +f 36130/36130/26147 37267/37267/27079 36131/36131/26148 +f 36553/36553/26514 37210/37210/27031 37377/37377/27170 +f 36553/36553/26514 37377/37377/27170 37223/37223/27041 +f 37210/37210/27031 36615/36615/26565 37342/37342/27145 +f 37210/37210/27031 37342/37342/27145 37377/37377/27170 +f 37378/37378/27171 37348/37348/27145 37255/37255/27068 +f 37378/37378/27171 37255/37255/27068 37379/37379/27172 +f 37225/37225/27041 37378/37378/27171 37379/37379/27172 +f 37225/37225/27041 37379/37379/27172 37226/37226/27042 +f 36652/36652/26596 36649/36649/26593 37380/37380/27173 +f 36652/36652/26596 37380/37380/27173 37381/37381/27169 +f 36649/36649/26593 36648/36648/26592 37338/37338/27141 +f 36649/36649/26593 37338/37338/27141 37380/37380/27173 +f 37382/37382/27173 37340/37340/27143 37280/37280/27089 +f 37382/37382/27173 37280/37280/27089 37300/37300/27108 +f 37376/37376/27169 37382/37382/27173 37300/37300/27108 +f 37376/37376/27169 37300/37300/27108 37270/37270/27082 +f 37383/37383/27174 37384/37384/27175 37385/37385/27176 +f 37383/37383/27174 37385/37385/27176 37386/37386/27177 +f 37384/37384/27175 37254/37254/27067 37252/37252/27065 +f 37384/37384/27175 37252/37252/27065 37385/37385/27176 +f 37385/37385/27176 37252/37252/27065 37251/37251/27064 +f 37385/37385/27176 37251/37251/27064 37387/37387/27178 +f 37386/37386/27177 37385/37385/27176 37387/37387/27178 +f 37386/37386/27177 37387/37387/27178 37388/37388/27179 +f 37389/37389/27180 37390/37390/27181 37391/37391/27182 +f 37389/37389/27180 37391/37391/27182 37392/37392/27183 +f 37390/37390/27181 37311/37311/27119 37309/37309/27117 +f 37390/37390/27181 37309/37309/27117 37391/37391/27182 +f 37391/37391/27182 37309/37309/27117 37254/37254/27067 +f 37391/37391/27182 37254/37254/27067 37384/37384/27175 +f 37392/37392/27183 37391/37391/27182 37384/37384/27175 +f 37392/37392/27183 37384/37384/27175 37383/37383/27174 +f 37263/37263/27075 37393/37393/27184 37394/37394/27185 +f 37263/37263/27075 37394/37394/27185 37264/37264/27076 +f 37393/37393/27184 37299/37299/27107 37297/37297/27105 +f 37393/37393/27184 37297/37297/27105 37394/37394/27185 +f 37394/37394/27185 37297/37297/27105 37296/37296/27104 +f 37394/37394/27185 37296/37296/27104 37395/37395/27186 +f 37264/37264/27076 37394/37394/27185 37395/37395/27186 +f 37264/37264/27076 37395/37395/27186 37266/37266/27078 +f 37388/37388/27179 37387/37387/27178 37396/37396/27187 +f 37388/37388/27179 37396/37396/27187 37397/37397/27188 +f 37387/37387/27178 37251/37251/27064 37398/37398/27189 +f 37387/37387/27178 37398/37398/27189 37396/37396/27187 +f 37396/37396/27187 37398/37398/27189 37399/37399/27190 +f 37396/37396/27187 37399/37399/27190 37400/37400/27184 +f 37397/37397/27188 37396/37396/27187 37400/37400/27184 +f 37397/37397/27188 37400/37400/27184 37401/37401/27075 +f 37402/37402/27191 37403/37403/27192 37404/37404/27193 +f 37402/37402/27191 37404/37404/27193 37405/37405/27194 +f 37403/37403/27192 37406/37406/27195 37407/37407/27196 +f 37403/37403/27192 37407/37407/27196 37404/37404/27193 +f 37404/37404/27193 37407/37407/27196 37328/37328/27134 +f 37404/37404/27193 37328/37328/27134 37408/37408/27197 +f 37405/37405/27194 37404/37404/27193 37408/37408/27197 +f 37405/37405/27194 37408/37408/27197 37287/37287/27096 +f 37290/37290/27099 37409/37409/27198 37410/37410/27199 +f 37290/37290/27099 37410/37410/27199 37303/37303/27111 +f 37409/37409/27198 37320/37320/27128 37318/37318/27126 +f 37409/37409/27198 37318/37318/27126 37410/37410/27199 +f 37410/37410/27199 37318/37318/27126 37317/37317/27125 +f 37410/37410/27199 37317/37317/27125 37411/37411/27200 +f 37303/37303/27111 37410/37410/27199 37411/37411/27200 +f 37303/37303/27111 37411/37411/27200 37274/37274/27085 +f 37412/37412/27201 37413/37413/27202 37414/37414/27203 +f 37412/37412/27201 37414/37414/27203 37415/37415/27204 +f 37413/37413/27202 37245/37245/27060 37243/37243/27058 +f 37413/37413/27202 37243/37243/27058 37414/37414/27203 +f 37414/37414/27203 37243/37243/27058 37242/37242/27057 +f 37414/37414/27203 37242/37242/27057 37416/37416/27205 +f 37415/37415/27204 37414/37414/27203 37416/37416/27205 +f 37415/37415/27204 37416/37416/27205 37417/37417/27206 +f 37274/37274/27085 37411/37411/27200 37418/37418/27207 +f 37274/37274/27085 37418/37418/27207 37275/37275/27086 +f 37411/37411/27200 37317/37317/27125 37419/37419/27208 +f 37411/37411/27200 37419/37419/27208 37418/37418/27207 +f 37420/37420/27207 37421/37421/27208 37422/37422/27209 +f 37420/37420/27207 37422/37422/27209 37423/37423/27210 +f 37278/37278/27087 37420/37420/27207 37423/37423/27210 +f 37278/37278/27087 37423/37423/27210 37279/37279/27088 +f 37287/37287/27096 37408/37408/27197 37424/37424/27211 +f 37287/37287/27096 37424/37424/27211 37288/37288/27097 +f 37408/37408/27197 37328/37328/27134 37326/37326/27133 +f 37408/37408/27197 37326/37326/27133 37424/37424/27211 +f 37424/37424/27211 37326/37326/27133 37320/37320/27128 +f 37424/37424/27211 37320/37320/27128 37409/37409/27198 +f 37288/37288/27097 37424/37424/27211 37409/37409/27198 +f 37288/37288/27097 37409/37409/27198 37290/37290/27099 +f 37266/37266/27078 37395/37395/27186 37425/37425/27212 +f 37266/37266/27078 37425/37425/27212 37426/37426/27213 +f 37395/37395/27186 37296/37296/27104 37427/37427/27214 +f 37395/37395/27186 37427/37427/27214 37425/37425/27212 +f 37425/37425/27212 37427/37427/27214 37406/37406/27195 +f 37425/37425/27212 37406/37406/27195 37403/37403/27192 +f 37426/37426/27213 37425/37425/27212 37403/37403/27192 +f 37426/37426/27213 37403/37403/27192 37402/37402/27191 +f 37366/37366/27162 37364/37364/27160 37428/37428/27215 +f 37366/37366/27162 37428/37428/27215 37429/37429/27216 +f 37364/37364/27160 37321/37321/27129 37324/37324/27132 +f 37364/37364/27160 37324/37324/27132 37428/37428/27215 +f 37430/37430/27217 37327/37327/27132 37328/37328/27134 +f 37430/37430/27217 37328/37328/27134 37407/37407/27196 +f 37431/37431/27218 37430/37430/27217 37407/37407/27196 +f 37431/37431/27218 37407/37407/27196 37406/37406/27195 +f 36026/36026/26055 36024/36024/26054 37432/37432/27219 +f 36026/36026/26055 37432/37432/27219 37433/37433/27220 +f 36024/36024/26054 36023/36023/26053 37434/37434/27221 +f 36024/36024/26054 37434/37434/27221 37432/37432/27219 +f 37435/37435/27222 37436/37436/27223 37383/37383/27174 +f 37435/37435/27222 37383/37383/27174 37386/37386/27177 +f 37437/37437/27224 37435/37435/27222 37386/37386/27177 +f 37437/37437/27224 37386/37386/27177 37388/37388/27179 +f 37126/37126/26966 37124/37124/26964 37438/37438/27225 +f 37126/37126/26966 37438/37438/27225 37439/37439/27055 +f 37124/37124/26964 37123/37123/26963 37440/37440/27226 +f 37124/37124/26964 37440/37440/27226 37438/37438/27225 +f 37441/37441/27225 37442/37442/27227 37417/37417/27206 +f 37441/37441/27225 37417/37417/27206 37416/37416/27205 +f 37240/37240/27055 37441/37441/27225 37416/37416/27205 +f 37240/37240/27055 37416/37416/27205 37242/37242/27057 +f 35952/35952/25988 37371/37371/27166 37443/37443/27228 +f 35952/35952/25988 37443/37443/27228 37293/37293/27102 +f 37371/37371/27166 37366/37366/27162 37429/37429/27216 +f 37371/37371/27166 37429/37429/27216 37443/37443/27228 +f 37444/37444/27228 37431/37431/27218 37406/37406/27195 +f 37444/37444/27228 37406/37406/27195 37427/37427/27214 +f 37295/37295/27103 37444/37444/27228 37427/37427/27214 +f 37295/37295/27103 37427/37427/27214 37296/37296/27104 +f 37226/37226/27042 37379/37379/27172 37445/37445/27229 +f 37226/37226/27042 37445/37445/27229 37446/37446/27230 +f 37379/37379/27172 37255/37255/27068 37258/37258/27071 +f 37379/37379/27172 37258/37258/27071 37445/37445/27229 +f 37447/37447/27229 37265/37265/27077 37266/37266/27078 +f 37447/37447/27229 37266/37266/27078 37426/37426/27213 +f 37448/37448/27230 37447/37447/27229 37426/37426/27213 +f 37448/37448/27230 37426/37426/27213 37402/37402/27191 +f 36134/36134/26150 36132/36132/26149 37449/37449/27231 +f 36134/36134/26150 37449/37449/27231 37450/37450/27232 +f 36132/36132/26149 36131/36131/26148 37269/37269/27081 +f 36132/36132/26149 37269/37269/27081 37449/37449/27231 +f 37451/37451/27233 37276/37276/27081 37279/37279/27088 +f 37451/37451/27233 37279/37279/27088 37452/37452/27234 +f 37453/37453/27235 37451/37451/27233 37452/37452/27234 +f 37453/37453/27235 37452/37452/27234 37412/37412/27201 +f 37134/37134/26124 37132/37132/26971 37454/37454/27236 +f 37134/37134/26124 37454/37454/27236 37455/37455/27237 +f 37132/37132/26971 37131/37131/26970 37456/37456/27115 +f 37132/37132/26971 37456/37456/27115 37454/37454/27236 +f 37457/37457/27238 37310/37310/27118 37311/37311/27119 +f 37457/37457/27238 37311/37311/27119 37390/37390/27181 +f 37458/37458/27239 37457/37457/27238 37390/37390/27181 +f 37458/37458/27239 37390/37390/27181 37389/37389/27180 +f 37229/37229/27044 37227/37227/27043 37459/37459/27240 +f 37229/37229/27044 37459/37459/27240 37284/37284/27093 +f 37227/37227/27043 37226/37226/27042 37446/37446/27230 +f 37227/37227/27043 37446/37446/27230 37459/37459/27240 +f 37460/37460/27240 37448/37448/27230 37402/37402/27191 +f 37460/37460/27240 37402/37402/27191 37405/37405/27194 +f 37286/37286/27095 37460/37460/27240 37405/37405/27194 +f 37286/37286/27095 37405/37405/27194 37287/37287/27096 +f 36043/36043/26070 37336/37336/27139 37461/37461/27241 +f 36043/36043/26070 37461/37461/27241 37248/37248/27063 +f 37336/37336/27139 35955/35955/25990 37292/37292/27101 +f 37336/37336/27139 37292/37292/27101 37461/37461/27241 +f 37462/37462/27241 37463/37463/27106 37399/37399/27190 +f 37462/37462/27241 37399/37399/27190 37398/37398/27189 +f 37250/37250/27063 37462/37462/27241 37398/37398/27189 +f 37250/37250/27063 37398/37398/27189 37251/37251/27064 +f 35964/35964/25998 37358/37358/27155 37464/37464/27242 +f 35964/35964/25998 37464/37464/27242 37314/37314/27122 +f 37358/37358/27155 37357/37357/27154 37465/37465/27243 +f 37358/37358/27155 37465/37465/27243 37464/37464/27242 +f 37466/37466/27244 37467/37467/27243 37422/37422/27209 +f 37466/37466/27244 37422/37422/27209 37421/37421/27208 +f 37316/37316/27124 37468/37468/27242 37419/37419/27208 +f 37316/37316/27124 37419/37419/27208 37317/37317/27125 +f 37259/37259/27072 37351/37351/27150 37469/37469/27245 +f 37259/37259/27072 37469/37469/27245 37260/37260/27073 +f 37351/37351/27150 36026/36026/26055 37433/37433/27220 +f 37351/37351/27150 37433/37433/27220 37469/37469/27245 +f 37470/37470/27245 37437/37437/27224 37388/37388/27179 +f 37470/37470/27245 37388/37388/27179 37397/37397/27188 +f 37471/37471/27246 37470/37470/27245 37397/37397/27188 +f 37471/37471/27246 37397/37397/27188 37401/37401/27075 +f 36023/36023/26053 36106/36106/26125 37472/37472/27247 +f 36023/36023/26053 37472/37472/27247 37434/37434/27221 +f 36106/36106/26125 36105/36105/26124 37473/37473/27239 +f 36106/36106/26125 37473/37473/27239 37472/37472/27247 +f 37474/37474/27248 37458/37458/27239 37389/37389/27180 +f 37474/37474/27248 37389/37389/27180 37392/37392/27183 +f 37436/37436/27223 37474/37474/27248 37392/37392/27183 +f 37436/37436/27223 37392/37392/27183 37383/37383/27174 +f 37475/37475/26963 37476/37476/27249 37477/37477/27250 +f 37475/37475/26963 37477/37477/27250 37442/37442/27227 +f 37478/37478/27251 36134/36134/26150 37450/37450/27232 +f 37478/37478/27251 37450/37450/27232 37479/37479/27250 +f 37477/37477/27250 37453/37453/27235 37412/37412/27201 +f 37477/37477/27250 37412/37412/27201 37415/37415/27204 +f 37442/37442/27227 37477/37477/27250 37415/37415/27204 +f 37442/37442/27227 37415/37415/27204 37417/37417/27206 +f 37279/37279/27088 37423/37423/27210 37480/37480/27252 +f 37279/37279/27088 37480/37480/27252 37452/37452/27234 +f 37423/37423/27210 37422/37422/27209 37481/37481/27253 +f 37423/37423/27210 37481/37481/27253 37480/37480/27252 +f 37480/37480/27252 37481/37481/27253 37245/37245/27060 +f 37480/37480/27252 37245/37245/27060 37413/37413/27202 +f 37452/37452/27234 37480/37480/27252 37413/37413/27202 +f 37452/37452/27234 37413/37413/27202 37412/37412/27201 +f 37357/37357/27154 37482/37482/27254 37483/37483/27255 +f 37357/37357/27154 37483/37483/27255 37465/37465/27243 +f 37482/37482/27254 37205/37205/27028 37239/37239/27054 +f 37482/37482/27254 37239/37239/27054 37483/37483/27255 +f 37484/37484/27256 37244/37244/27059 37245/37245/27060 +f 37484/37484/27256 37245/37245/27060 37481/37481/27253 +f 37467/37467/27243 37484/37484/27256 37481/37481/27253 +f 37467/37467/27243 37481/37481/27253 37422/37422/27209 +f 37354/37354/27152 37485/37485/27003 37486/37486/27257 +f 37354/37354/27152 37486/37486/27257 37355/37355/27153 +f 37485/37485/27003 37196/37196/27002 37199/37199/27025 +f 37485/37485/27003 37199/37199/27025 37486/37486/27257 +f 37486/37486/27257 37199/37199/27025 37205/37205/27028 +f 37486/37486/27257 37205/37205/27028 37482/37482/27254 +f 37355/37355/27153 37486/37486/27257 37482/37482/27254 +f 37355/37355/27153 37482/37482/27254 37357/37357/27154 +f 36111/36111/26130 37200/37200/27023 37487/37487/27258 +f 36111/36111/26130 37487/37487/27258 37098/37098/26945 +f 37200/37200/27023 37174/37174/27002 37177/37177/27005 +f 37200/37200/27023 37177/37177/27005 37487/37487/27258 +f 37487/37487/27258 37177/37177/27005 37179/37179/27007 +f 37487/37487/27258 37179/37179/27007 37488/37488/27259 +f 37098/37098/26945 37487/37487/27258 37488/37488/27259 +f 37098/37098/26945 37488/37488/27259 37099/37099/26946 +f 36159/36159/26174 37117/37117/26959 37489/37489/27260 +f 36159/36159/26174 37489/37489/27260 37087/37087/26936 +f 37117/37117/26959 37116/37116/26958 37171/37171/26999 +f 37117/37117/26959 37171/37171/26999 37489/37489/27260 +f 37489/37489/27260 37171/37171/26999 37173/37173/27001 +f 37489/37489/27260 37173/37173/27001 37490/37490/27261 +f 37087/37087/26936 37489/37489/27260 37490/37490/27261 +f 37087/37087/26936 37490/37490/27261 37089/37089/26937 +f 37140/37140/26976 37139/37139/26975 37491/37491/27262 +f 37140/37140/26976 37491/37491/27262 37492/37492/27263 +f 37139/37139/26975 36578/36578/26537 37169/37169/26997 +f 37139/37139/26975 37169/37169/26997 37491/37491/27262 +f 37491/37491/27262 37169/37169/26997 37116/37116/26958 +f 37491/37491/27262 37116/37116/26958 37114/37114/26956 +f 37492/37492/27263 37491/37491/27262 37114/37114/26956 +f 37492/37492/27263 37114/37114/26956 37079/37079/26928 +f 37150/37150/26982 37149/37149/26981 37493/37493/27264 +f 37150/37150/26982 37493/37493/27264 37494/37494/27265 +f 37148/37148/26981 37147/37147/26980 37495/37495/27266 +f 37148/37148/26981 37495/37495/27266 37496/37496/27264 +f 37496/37496/27264 37495/37495/27266 37084/37084/26933 +f 37496/37496/27264 37084/37084/26933 37112/37112/26953 +f 37494/37494/27265 37493/37493/27264 37109/37109/26953 +f 37494/37494/27265 37109/37109/26953 37108/37108/26952 +f 37156/37156/26988 37155/37155/26987 37497/37497/27267 +f 37156/37156/26988 37497/37497/27267 37498/37498/27268 +f 37155/37155/26987 37154/37154/26986 37499/37499/27269 +f 37155/37155/26987 37499/37499/27269 37497/37497/27267 +f 37497/37497/27267 37499/37499/27269 37105/37105/26943 +f 37497/37497/27267 37105/37105/26943 37102/37102/26949 +f 37498/37498/27268 37497/37497/27267 37102/37102/26949 +f 37498/37498/27268 37102/37102/26949 37101/37101/26948 +f 36127/36127/26146 36124/36124/26143 37500/37500/27270 +f 36127/36127/26146 37500/37500/27270 37160/37160/26992 +f 36124/36124/26143 36123/36123/26142 37094/37094/26941 +f 36124/36124/26143 37094/37094/26941 37500/37500/27270 +f 37500/37500/27270 37094/37094/26941 37096/37096/26943 +f 37500/37500/27270 37096/37096/26943 37501/37501/27271 +f 37160/37160/26992 37500/37500/27270 37501/37501/27271 +f 37160/37160/26992 37501/37501/27271 37162/37162/26993 +f 37140/37140/26976 37492/37492/27263 37502/37502/27272 +f 37140/37140/26976 37502/37502/27272 37167/37167/26996 +f 37492/37492/27263 37079/37079/26928 37082/37082/26931 +f 37492/37492/27263 37082/37082/26931 37502/37502/27272 +f 37502/37502/27272 37082/37082/26931 37084/37084/26933 +f 37502/37502/27272 37084/37084/26933 37495/37495/27266 +f 37167/37167/26996 37502/37502/27272 37495/37495/27266 +f 37167/37167/26996 37495/37495/27266 37147/37147/26980 +f 36107/36107/26126 37092/37092/26939 37503/37503/27273 +f 36107/36107/26126 37503/37503/27273 37120/37120/26962 +f 37092/37092/26939 36123/36123/26142 36126/36126/26145 +f 37092/37092/26939 36126/36126/26145 37503/37503/27273 +f 37504/37504/27274 36133/36133/26145 36134/36134/26150 +f 37504/37504/27274 36134/36134/26150 37478/37478/27251 +f 37120/37120/26962 37503/37503/27273 37476/37476/27249 +f 37120/37120/26962 37476/37476/27249 37475/37475/26963 +f 37505/37505/27275 37506/37506/27276 37507/37507/27277 +f 37505/37505/27275 37507/37507/27277 37508/37508/27000 +f 37506/37506/27276 37156/37156/26988 37498/37498/27268 +f 37506/37506/27276 37498/37498/27268 37507/37507/27277 +f 37507/37507/27277 37498/37498/27268 37101/37101/26948 +f 37507/37507/27277 37101/37101/26948 37509/37509/27278 +f 37508/37508/27000 37507/37507/27277 37509/37509/27278 +f 37508/37508/27000 37509/37509/27278 37510/37510/27001 +f 37511/37511/27279 37512/37512/27280 37513/37513/27281 +f 37511/37511/27279 37513/37513/27281 37514/37514/27006 +f 37512/37512/27280 37150/37150/26982 37494/37494/27265 +f 37512/37512/27280 37494/37494/27265 37513/37513/27281 +f 37513/37513/27281 37494/37494/27265 37108/37108/26952 +f 37513/37513/27281 37108/37108/26952 37515/37515/27282 +f 37514/37514/27006 37513/37513/27281 37515/37515/27282 +f 37514/37514/27006 37515/37515/27282 37516/37516/27007 +f 35887/35887/25924 37517/37517/27283 37518/37518/27284 +f 35887/35887/25924 37518/37518/27284 35888/35888/25925 +f 37519/37519/27285 36465/36465/26436 37218/37218/27037 +f 37519/37519/27285 37218/37218/27037 37520/37520/27286 +f 37520/37520/27286 37218/37218/27037 36485/36485/26453 +f 37520/37520/27286 36485/36485/26453 37521/37521/27287 +f 35888/35888/25925 37518/37518/27284 37522/37522/27288 +f 35888/35888/25925 37522/37522/27288 35889/35889/25926 +f 36012/36012/26044 37523/37523/27289 37524/37524/27290 +f 36012/36012/26044 37524/37524/27290 36013/36013/26045 +f 37525/37525/27289 36472/36472/26442 37214/37214/27035 +f 37525/37525/27289 37214/37214/27035 37526/37526/27290 +f 37526/37526/27290 37214/37214/27035 36494/36494/26460 +f 37526/37526/27290 36494/36494/26460 37527/37527/27291 +f 36013/36013/26045 37524/37524/27290 37528/37528/27291 +f 36013/36013/26045 37528/37528/27291 36014/36014/26046 +f 37529/37529/26585 37530/37530/27292 37531/37531/27293 +f 37529/37529/26585 37531/37531/27293 37532/37532/26586 +f 37530/37530/27292 36493/36493/26459 37193/37193/27021 +f 37530/37530/27292 37193/37193/27021 37531/37531/27293 +f 37531/37531/27293 37193/37193/27021 36473/36473/26443 +f 37531/37531/27293 36473/36473/26443 37533/37533/27294 +f 37532/37532/26586 37531/37531/27293 37533/37533/27294 +f 37532/37532/26586 37533/37533/27294 37534/37534/26587 +f 37535/37535/27295 37536/37536/27296 37537/37537/27297 +f 37535/37535/27295 37537/37537/27297 37538/37538/26140 +f 37536/37536/27296 36505/36505/26471 37189/37189/27017 +f 37536/37536/27296 37189/37189/27017 37537/37537/27297 +f 37537/37537/27297 37189/37189/27017 36506/36506/26472 +f 37537/37537/27297 36506/36506/26472 37539/37539/27298 +f 37538/37538/26140 37537/37537/27297 37539/37539/27298 +f 37538/37538/26140 37539/37539/27298 37540/37540/26141 +f 37541/37541/26542 37542/37542/27299 37543/37543/27300 +f 37541/37541/26542 37543/37543/27300 37544/37544/27301 +f 37542/37542/27299 36514/36514/26480 37152/37152/26984 +f 37542/37542/27299 37152/37152/26984 37543/37543/27300 +f 37543/37543/27300 37152/37152/26984 37156/37156/26988 +f 37543/37543/27300 37156/37156/26988 37506/37506/27276 +f 37544/37544/27301 37543/37543/27300 37506/37506/27276 +f 37544/37544/27301 37506/37506/27276 37505/37505/27275 +f 37545/37545/27302 37546/37546/27303 37547/37547/27304 +f 37545/37545/27302 37547/37547/27304 37548/37548/26510 +f 37546/37546/27303 36484/36484/26452 37142/37142/26978 +f 37546/37546/27303 37142/37142/26978 37547/37547/27304 +f 37547/37547/27304 37142/37142/26978 37150/37150/26982 +f 37547/37547/27304 37150/37150/26982 37512/37512/27280 +f 37548/37548/26510 37547/37547/27304 37512/37512/27280 +f 37548/37548/26510 37512/37512/27280 37511/37511/27279 +f 37516/37516/27007 37515/37515/27282 37549/37549/27305 +f 37516/37516/27007 37549/37549/27305 37550/37550/27306 +f 37515/37515/27282 37108/37108/26952 37111/37111/26955 +f 37515/37515/27282 37111/37111/26955 37549/37549/27305 +f 37549/37549/27305 37111/37111/26955 36515/36515/26481 +f 37549/37549/27305 36515/36515/26481 37551/37551/27307 +f 37550/37550/27306 37549/37549/27305 37551/37551/27307 +f 37550/37550/27306 37551/37551/27307 37552/37552/27308 +f 37510/37510/27001 37509/37509/27278 37553/37553/27309 +f 37510/37510/27001 37553/37553/27309 37554/37554/27310 +f 37509/37509/27278 37101/37101/26948 37104/37104/26951 +f 37509/37509/27278 37104/37104/26951 37553/37553/27309 +f 37553/37553/27309 37104/37104/26951 36528/36528/26491 +f 37553/37553/27309 36528/36528/26491 37555/37555/27311 +f 37554/37554/27310 37553/37553/27309 37555/37555/27311 +f 37554/37554/27310 37555/37555/27311 37556/37556/26937 +f 35979/35979/26011 35978/35978/26008 37557/37557/27312 +f 35979/35979/26011 37557/37557/27312 37066/37066/26918 +f 37558/37558/27313 37073/37073/26007 37076/37076/26926 +f 37558/37558/27313 37076/37076/26926 37559/37559/27312 +f 37559/37559/27312 37076/37076/26926 36143/36143/26159 +f 37559/37559/27312 36143/36143/26159 37560/37560/27314 +f 37066/37066/26918 37557/37557/27312 37561/37561/27315 +f 37066/37066/26918 37561/37561/27315 36203/36203/26214 +f 36161/36161/26098 37562/37562/27316 37563/37563/27317 +f 36161/36161/26098 37563/37563/27317 37063/37063/26915 +f 37564/37564/27318 37067/37067/26919 37070/37070/26922 +f 37564/37564/27318 37070/37070/26922 37565/37565/27319 +f 37565/37565/27319 37070/37070/26922 36189/36189/26201 +f 37565/37565/27319 36189/36189/26201 37566/37566/27320 +f 37063/37063/26915 37563/37563/27317 37567/37567/27320 +f 37063/37063/26915 37567/37567/27320 36209/36209/26220 +f 36952/36952/26829 37568/37568/27321 37569/37569/27322 +f 36952/36952/26829 37569/37569/27322 36953/36953/26830 +f 37568/37568/27321 36776/36776/26690 37049/37049/26905 +f 37568/37568/27321 37049/37049/26905 37569/37569/27322 +f 37570/37570/27322 37054/37054/26909 37037/37037/26896 +f 37570/37570/27322 37037/37037/26896 37036/37036/26895 +f 36955/36955/26830 37571/37571/27322 37035/37035/26895 +f 36955/36955/26830 37035/37035/26895 36956/36956/26832 +f 36799/36799/26709 37572/37572/27323 37573/37573/27324 +f 36799/36799/26709 37573/37573/27324 37039/37039/26898 +f 37572/37572/27323 37042/37042/26900 37044/37044/26902 +f 37572/37572/27323 37044/37044/26902 37573/37573/27324 +f 37574/37574/27324 37046/37046/26902 37024/37024/26887 +f 37574/37574/27324 37024/37024/26887 37575/37575/27325 +f 37041/37041/26898 37576/37576/27324 37577/37577/27326 +f 37041/37041/26898 37577/37577/27326 37016/37016/26879 +f 36990/36990/26858 37578/37578/27327 37579/37579/27328 +f 36990/36990/26858 37579/37579/27328 37020/37020/26883 +f 37580/37580/27329 36982/36982/26851 37033/37033/26894 +f 37580/37580/27329 37033/37033/26894 37581/37581/27330 +f 37581/37581/27330 37033/37033/26894 37037/37037/26896 +f 37581/37581/27330 37037/37037/26896 37056/37056/26908 +f 37020/37020/26883 37579/37579/27328 37053/37053/26908 +f 37020/37020/26883 37053/37053/26908 37021/37021/26884 +f 37016/37016/26879 37577/37577/27326 37582/37582/27331 +f 37016/37016/26879 37582/37582/27331 37017/37017/26880 +f 37575/37575/27325 37024/37024/26887 37027/37027/26890 +f 37575/37575/27325 37027/37027/26890 37583/37583/27331 +f 37583/37583/27331 37027/37027/26890 36969/36969/26841 +f 37583/37583/27331 36969/36969/26841 36968/36968/26840 +f 37017/37017/26880 37582/37582/27331 36965/36965/26839 +f 37017/37017/26880 36965/36965/26839 36959/36959/26834 +f 36761/36761/26237 37584/37584/27332 37585/37585/27333 +f 36761/36761/26237 37585/37585/27333 36762/36762/26676 +f 37586/37586/27334 37003/37003/26867 37006/37006/26870 +f 37586/37586/27334 37006/37006/26870 37587/37587/27335 +f 37587/37587/27335 37006/37006/26870 36960/36960/26835 +f 37587/37587/27335 36960/36960/26835 37588/37588/27336 +f 36764/36764/26678 37587/37587/27335 37588/37588/27336 +f 36764/36764/26678 37588/37588/27336 36765/36765/26679 +f 36944/36944/26821 37589/37589/27337 37590/37590/27338 +f 36944/36944/26821 37590/37590/27338 36995/36995/26862 +f 37591/37591/27339 36937/36937/26815 36999/36999/26865 +f 37591/37591/27339 36999/36999/26865 37592/37592/27340 +f 37593/37593/27340 37002/37002/26866 36970/36970/26842 +f 37593/37593/27340 36970/36970/26842 37594/37594/27341 +f 36997/36997/26862 37593/37593/27340 37594/37594/27341 +f 36997/36997/26862 37594/37594/27341 36986/36986/26855 +f 36986/36986/26855 37594/37594/27341 37595/37595/27342 +f 36986/36986/26855 37595/37595/27342 36987/36987/26856 +f 37594/37594/27341 36970/36970/26842 36973/36973/26845 +f 37594/37594/27341 36973/36973/26845 37595/37595/27342 +f 37596/37596/27343 36979/36979/26845 36982/36982/26851 +f 37596/37596/27343 36982/36982/26851 37580/37580/27329 +f 36989/36989/26857 37597/37597/27342 37578/37578/27327 +f 36989/36989/26857 37578/37578/27327 36990/36990/26858 +f 36765/36765/26679 37588/37588/27336 37598/37598/27344 +f 36765/36765/26679 37598/37598/27344 37058/37058/26912 +f 37588/37588/27336 36960/36960/26835 36963/36963/26838 +f 37588/37588/27336 36963/36963/26838 37598/37598/27344 +f 37599/37599/27345 36966/36966/26838 36969/36969/26841 +f 37599/37599/27345 36969/36969/26841 37031/37031/26892 +f 37060/37060/26912 37600/37600/27344 37030/37030/26892 +f 37060/37060/26912 37030/37030/26892 37023/37023/26886 +f 36211/36211/26222 37601/37601/27346 37602/37602/27347 +f 36211/36211/26222 37602/37602/27347 36947/36947/26824 +f 37603/37603/27348 36200/36200/26211 36939/36939/26817 +f 37603/37603/27348 36939/36939/26817 37604/37604/27347 +f 37604/37604/27347 36939/36939/26817 36777/36777/26691 +f 37604/37604/27347 36777/36777/26691 37605/37605/27349 +f 36947/36947/26824 37602/37602/27347 37606/37606/27350 +f 36947/36947/26824 37606/37606/27350 36795/36795/26707 +f 36205/36205/26216 37607/37607/27351 37608/37608/27352 +f 36205/36205/26216 37608/37608/27352 36943/36943/26820 +f 37609/37609/27353 36154/36154/26169 36932/36932/26810 +f 37609/37609/27353 36932/36932/26810 37610/37610/27352 +f 37610/37610/27352 36932/36932/26810 36937/36937/26815 +f 37610/37610/27352 36937/36937/26815 37591/37591/27339 +f 36943/36943/26820 37608/37608/27352 37589/37589/27337 +f 36943/36943/26820 37589/37589/27337 36944/36944/26821 +f 36795/36795/26707 37606/37606/27350 37611/37611/27354 +f 36795/36795/26707 37611/37611/27354 36796/36796/26708 +f 37605/37605/27349 36777/36777/26691 36780/36780/26694 +f 37605/37605/27349 36780/36780/26694 37612/37612/27354 +f 37612/37612/27354 36780/36780/26694 36790/36790/26702 +f 37612/37612/27354 36790/36790/26702 37613/37613/27355 +f 36798/36798/26708 37614/37614/27356 37572/37572/27323 +f 36798/36798/26708 37572/37572/27323 36799/36799/26709 +f 37011/37011/26196 37615/37615/27357 37616/37616/27358 +f 37011/37011/26196 37616/37616/27358 37012/37012/26875 +f 37615/37615/27357 36769/36769/26683 36772/36772/26686 +f 37615/37615/27357 36772/36772/26686 37616/37616/27358 +f 37616/37616/27358 36772/36772/26686 36776/36776/26690 +f 37616/37616/27358 36776/36776/26690 37568/37568/27321 +f 37012/37012/26875 37616/37616/27358 37568/37568/27321 +f 37012/37012/26875 37568/37568/27321 36952/36952/26829 +f 36360/36360/26347 37617/37617/27359 37618/37618/27360 +f 36360/36360/26347 37618/37618/27360 36361/36361/26348 +f 37619/37619/27361 36372/36372/26359 36745/36745/26666 +f 37619/37619/27361 36745/36745/26666 37620/37620/27360 +f 37620/37620/27360 36745/36745/26666 36751/36751/26656 +f 37620/37620/27360 36751/36751/26656 37621/37621/27362 +f 36361/36361/26348 37618/37618/27360 37622/37622/27362 +f 36361/36361/26348 37622/37622/27362 36362/36362/26349 +f 37623/37623/26362 37624/37624/27363 37625/37625/27364 +f 37623/37623/26362 37625/37625/27364 36756/36756/26671 +f 37626/37626/27363 36342/36342/26330 36739/36739/26662 +f 37626/37626/27363 36739/36739/26662 37627/37627/27365 +f 37627/37627/27365 36739/36739/26662 36743/36743/26652 +f 37627/37627/27365 36743/36743/26652 37628/37628/27366 +f 36756/36756/26671 37625/37625/27364 36732/36732/26655 +f 36756/36756/26671 36732/36732/26655 36737/36737/26660 +f 36364/36364/26351 36363/36363/26350 37629/37629/27367 +f 36364/36364/26351 37629/37629/27367 36741/36741/26664 +f 36363/36363/26350 36362/36362/26349 37622/37622/27362 +f 36363/36363/26350 37622/37622/27362 37629/37629/27367 +f 37629/37629/27367 37622/37622/27362 37630/37630/27368 +f 37629/37629/27367 37630/37630/27368 37631/37631/26653 +f 36741/36741/26664 37629/37629/27367 37631/37631/26653 +f 36741/36741/26664 37631/37631/26653 37632/37632/26652 +f 37633/37633/26093 37634/37634/27369 37635/37635/27370 +f 37633/37633/26093 37635/37635/27370 37636/37636/27371 +f 37634/37634/27369 36379/36379/26366 36720/36720/26648 +f 37634/37634/27369 36720/36720/26648 37635/37635/27370 +f 37635/37635/27370 36720/36720/26648 36724/36724/26629 +f 37635/37635/27370 36724/36724/26629 37637/37637/27372 +f 37636/37636/27371 37635/37635/27370 37637/37637/27372 +f 37636/37636/27371 37637/37637/27372 37638/37638/27373 +f 36690/36690/26624 36689/36689/26623 37639/37639/27374 +f 36690/36690/26624 37639/37639/27374 36718/36718/26646 +f 36689/36689/26623 36688/36688/26622 37640/37640/27375 +f 36689/36689/26623 37640/37640/27375 37639/37639/27374 +f 37639/37639/27374 37640/37640/27375 37641/37641/26551 +f 37639/37639/27374 37641/37641/26551 36593/36593/26550 +f 36718/36718/26646 37639/37639/27374 36593/36593/26550 +f 36718/36718/26646 36593/36593/26550 36592/36592/26549 +f 35906/35906/25942 37642/37642/27376 37643/37643/27377 +f 35906/35906/25942 37643/37643/27377 35907/35907/25943 +f 37642/37642/27376 37644/37644/26618 37645/37645/26627 +f 37642/37642/27376 37645/37645/26627 37643/37643/27377 +f 37643/37643/27377 37645/37645/26627 37646/37646/26629 +f 37643/37643/27377 37646/37646/26629 37647/37647/26649 +f 35907/35907/25943 37643/37643/27377 37647/37647/26649 +f 35907/35907/25943 37647/37647/26649 35909/35909/25945 +f 35906/35906/25942 36713/36713/26643 37648/37648/27378 +f 35906/35906/25942 37648/37648/27378 37642/37642/27376 +f 36713/36713/26643 36700/36700/26633 36697/36697/26630 +f 36713/36713/26643 36697/36697/26630 37648/37648/27378 +f 37648/37648/27378 36697/36697/26630 36696/36696/26622 +f 37648/37648/27378 36696/36696/26622 37649/37649/27379 +f 37642/37642/27376 37648/37648/27378 37649/37649/27379 +f 37642/37642/27376 37649/37649/27379 37644/37644/26618 +f 36394/36394/26379 36393/36393/26378 37650/37650/27380 +f 36394/36394/26379 37650/37650/27380 37651/37651/25952 +f 36393/36393/26378 36392/36392/26377 36668/36668/26607 +f 36393/36393/26378 36668/36668/26607 37650/37650/27380 +f 37650/37650/27380 36668/36668/26607 36397/36397/26382 +f 37650/37650/27380 36397/36397/26382 37652/37652/27381 +f 35916/35916/25952 37653/37653/27382 37654/37654/27383 +f 35916/35916/25952 37654/37654/27383 35917/35917/25953 +f 36385/36385/26372 36384/36384/26371 37655/37655/27384 +f 36385/36385/26372 37655/37655/27384 37656/37656/26524 +f 36384/36384/26371 36383/36383/26370 36661/36661/26603 +f 36384/36384/26371 36661/36661/26603 37655/37655/27384 +f 37655/37655/27384 36661/36661/26603 36417/36417/26399 +f 37655/37655/27384 36417/36417/26399 37657/37657/27385 +f 36565/36565/26524 37658/37658/27386 37659/37659/27385 +f 36565/36565/26524 37659/37659/27385 36566/36566/26525 +f 37660/37660/27387 37661/37661/27388 37662/37662/27389 +f 37660/37660/27387 37662/37662/27389 37663/37663/26651 +f 37661/37661/27388 36388/36388/26373 36588/36588/26546 +f 37661/37661/27388 36588/36588/26546 37662/37662/27389 +f 37662/37662/27389 36588/36588/26546 36595/36595/26551 +f 37662/37662/27389 36595/36595/26551 37664/37664/27390 +f 37663/37663/26651 37662/37662/27389 37664/37664/27390 +f 37663/37663/26651 37664/37664/27390 37665/37665/26635 +f 37556/37556/26937 37555/37555/27311 37666/37666/27391 +f 37556/37556/26937 37666/37666/27391 37667/37667/26938 +f 37555/37555/27311 36528/36528/26491 36531/36531/26494 +f 37555/37555/27311 36531/36531/26494 37666/37666/27391 +f 37666/37666/27391 36531/36531/26494 36539/36539/26500 +f 37666/37666/27391 36539/36539/26500 37668/37668/26101 +f 37091/37091/26938 37669/37669/27391 36077/36077/26101 +f 37091/37091/26938 36077/36077/26101 36076/36076/26100 +f 37552/37552/27308 37551/37551/27307 37670/37670/27392 +f 37552/37552/27308 37670/37670/27392 37671/37671/26947 +f 37551/37551/27307 36515/36515/26481 36518/36518/26484 +f 37551/37551/27307 36518/36518/26484 37670/37670/27392 +f 37670/37670/27392 36518/36518/26484 37672/37672/27393 +f 37670/37670/27392 37672/37672/27393 37673/37673/26015 +f 37100/37100/26947 37674/37674/27394 35983/35983/26015 +f 37100/37100/26947 35983/35983/26015 35982/35982/26014 +f 37540/37540/26141 37539/37539/27298 37675/37675/27395 +f 37540/37540/26141 37675/37675/27395 37676/37676/27030 +f 37539/37539/27298 36506/36506/26472 36509/36509/26475 +f 37539/37539/27298 36509/36509/26475 37675/37675/27395 +f 37675/37675/27395 36509/36509/26475 36514/36514/26480 +f 37675/37675/27395 36514/36514/26480 37542/37542/27299 +f 37676/37676/27030 37675/37675/27395 37542/37542/27299 +f 37676/37676/27030 37542/37542/27299 37541/37541/26542 +f 37677/37677/27396 37527/37527/27291 37678/37678/27397 +f 37677/37677/27396 37678/37678/27397 37679/37679/27048 +f 37527/37527/27291 36494/36494/26460 36497/36497/26463 +f 37527/37527/27291 36497/36497/26463 37678/37678/27397 +f 37678/37678/27397 36497/36497/26463 36505/36505/26471 +f 37678/37678/27397 36505/36505/26471 37536/37536/27296 +f 37679/37679/27048 37678/37678/27397 37536/37536/27296 +f 37679/37679/27048 37536/37536/27296 37535/37535/27295 +f 35889/35889/25926 37522/37522/27288 37680/37680/27398 +f 35889/35889/25926 37680/37680/27398 37237/37237/27052 +f 37521/37521/27287 36485/36485/26453 36488/36488/26456 +f 37521/37521/27287 36488/36488/26456 37681/37681/27398 +f 37681/37681/27398 36488/36488/26456 36493/36493/26459 +f 37681/37681/27398 36493/36493/26459 37530/37530/27292 +f 37237/37237/27052 37680/37680/27398 37682/37682/27399 +f 37237/37237/27052 37682/37682/27399 36641/36641/26585 +f 37534/37534/26587 37533/37533/27294 37683/37683/27400 +f 37534/37534/26587 37683/37683/27400 37684/37684/27012 +f 37533/37533/27294 36473/36473/26443 36476/36476/26446 +f 37533/37533/27294 36476/36476/26446 37683/37683/27400 +f 37683/37683/27400 36476/36476/26446 36484/36484/26452 +f 37683/37683/27400 36484/36484/26452 37546/37546/27303 +f 37684/37684/27012 37683/37683/27400 37546/37546/27303 +f 37684/37684/27012 37546/37546/27303 37545/37545/27302 +f 36626/36626/26571 37685/37685/27401 37686/37686/27402 +f 36626/36626/26571 37686/37686/27402 36627/36627/26572 +f 37687/37687/27403 36455/36455/26427 36467/36467/26438 +f 37687/37687/27403 36467/36467/26438 37688/37688/27404 +f 37688/37688/27404 36467/36467/26438 36472/36472/26442 +f 37688/37688/27404 36472/36472/26442 37525/37525/27289 +f 36627/36627/26572 37686/37686/27402 37523/37523/27289 +f 36627/36627/26572 37523/37523/27289 36012/36012/26044 +f 36602/36602/26109 37689/37689/27405 37690/37690/27406 +f 36602/36602/26109 37690/37690/27406 36603/36603/26557 +f 37691/37691/27405 36438/36438/26413 36457/36457/26429 +f 37691/37691/27405 36457/36457/26429 37692/37692/27407 +f 37692/37692/27407 36457/36457/26429 36465/36465/26436 +f 37692/37692/27407 36465/36465/26436 37519/37519/27285 +f 36603/36603/26557 37690/37690/27406 37517/37517/27283 +f 36603/36603/26557 37517/37517/27283 35887/35887/25924 +f 37693/37693/26024 37694/37694/27408 37695/37695/27409 +f 37693/37693/26024 37695/37695/27409 37696/37696/27410 +f 37694/37694/27408 36449/36449/26423 36451/36451/26425 +f 37694/37694/27408 36451/36451/26425 37695/37695/27409 +f 37695/37695/27409 36451/36451/26425 36455/36455/26427 +f 37695/37695/27409 36455/36455/26427 37687/37687/27403 +f 37696/37696/27410 37695/37695/27409 37687/37687/27403 +f 37696/37696/27410 37687/37687/27403 37697/37697/27411 +f 36598/36598/26554 37698/37698/27412 37699/37699/27413 +f 36598/36598/26554 37699/37699/27413 36599/36599/26555 +f 37700/37700/27412 36416/36416/26398 36444/36444/26419 +f 37700/37700/27412 36444/36444/26419 37701/37701/27413 +f 37701/37701/27413 36444/36444/26419 36449/36449/26423 +f 37701/37701/27413 36449/36449/26423 37694/37694/27408 +f 36599/36599/26555 37699/37699/27413 37702/37702/27414 +f 36599/36599/26555 37702/37702/27414 35992/35992/26024 +f 36176/36176/26190 37703/37703/27415 37704/37704/27416 +f 36176/36176/26190 37704/37704/27416 36552/36552/26513 +f 37705/37705/27417 36429/36429/26407 36440/36440/26415 +f 37705/37705/27417 36440/36440/26415 37706/37706/27418 +f 37706/37706/27418 36440/36440/26415 36430/36430/26408 +f 37706/37706/27418 36430/36430/26408 37707/37707/27419 +f 37708/37708/26513 37706/37706/27418 37707/37707/27419 +f 37708/37708/26513 37707/37707/27419 37709/37709/27420 +f 37709/37709/27420 37707/37707/27419 37710/37710/27421 +f 37709/37709/27420 37710/37710/27421 37711/37711/26108 +f 37707/37707/27419 36430/36430/26408 36433/36433/26411 +f 37707/37707/27419 36433/36433/26411 37710/37710/27421 +f 37710/37710/27421 36433/36433/26411 36438/36438/26413 +f 37710/37710/27421 36438/36438/26413 37691/37691/27405 +f 37712/37712/26108 37713/37713/27421 37689/37689/27405 +f 37712/37712/26108 37689/37689/27405 36602/36602/26109 +f 36174/36174/26188 37714/37714/27422 37715/37715/27423 +f 36174/36174/26188 37715/37715/27423 36175/36175/26189 +f 37716/37716/27422 36405/36405/26387 36424/36424/26405 +f 37716/37716/27422 36424/36424/26405 37717/37717/27423 +f 37717/37717/27423 36424/36424/26405 36429/36429/26407 +f 37717/37717/27423 36429/36429/26407 37705/37705/27417 +f 36175/36175/26189 37715/37715/27423 37703/37703/27415 +f 36175/36175/26189 37703/37703/27415 36176/36176/26190 +f 36566/36566/26525 37659/37659/27385 37718/37718/27424 +f 36566/36566/26525 37718/37718/27424 36658/36658/26600 +f 37657/37657/27385 36417/36417/26399 36420/36420/26402 +f 37657/37657/27385 36420/36420/26402 37719/37719/27424 +f 37719/37719/27424 36420/36420/26402 36406/36406/26388 +f 37719/37719/27424 36406/36406/26388 37720/37720/27425 +f 36658/36658/26600 37718/37718/27424 37721/37721/27425 +f 36658/36658/26600 37721/37721/27425 36646/36646/26590 +f 36646/36646/26590 37721/37721/27425 37722/37722/27426 +f 36646/36646/26590 37722/37722/27426 36647/36647/26591 +f 37720/37720/27425 36406/36406/26388 36409/36409/26391 +f 37720/37720/27425 36409/36409/26391 37723/37723/27427 +f 37723/37723/27427 36409/36409/26391 36416/36416/26398 +f 37723/37723/27427 36416/36416/26398 37700/37700/27412 +f 36647/36647/26591 37722/37722/27426 37698/37698/27412 +f 36647/36647/26591 37698/37698/27412 36598/36598/26554 +f 35917/35917/25953 37654/37654/27383 37724/37724/27428 +f 35917/35917/25953 37724/37724/27428 36682/36682/26616 +f 37652/37652/27381 36397/36397/26382 36400/36400/26385 +f 37652/37652/27381 36400/36400/26385 37725/37725/27429 +f 37725/37725/27429 36400/36400/26385 36405/36405/26387 +f 37725/37725/27429 36405/36405/26387 37716/37716/27422 +f 36682/36682/26616 37724/37724/27428 37714/37714/27422 +f 36682/36682/26616 37714/37714/27422 36174/36174/26188 +f 37660/37660/27387 37726/37726/27430 37727/37727/27431 +f 37660/37660/27387 37727/37727/27431 37661/37661/27388 +f 37726/37726/27430 36669/36669/26532 36666/36666/26605 +f 37726/37726/27430 36666/36666/26605 37727/37727/27431 +f 37727/37727/27431 36666/36666/26605 36392/36392/26377 +f 37727/37727/27431 36392/36392/26377 36389/36389/26374 +f 37661/37661/27388 37727/37727/27431 36389/36389/26374 +f 37661/37661/27388 36389/36389/26374 36388/36388/26373 +f 37633/37633/26093 37728/37728/26092 37729/37729/27432 +f 37633/37633/26093 37729/37729/27432 37634/37634/27369 +f 37728/37728/26092 36662/36662/26091 36659/36659/26601 +f 37728/37728/26092 36659/36659/26601 37729/37729/27432 +f 37729/37729/27432 36659/36659/26601 36383/36383/26370 +f 37729/37729/27432 36383/36383/26370 36380/36380/26367 +f 37634/37634/27369 37729/37729/27432 36380/36380/26367 +f 37634/37634/27369 36380/36380/26367 36379/36379/26366 +f 36346/36346/26334 37730/37730/27433 37731/37731/27434 +f 36346/36346/26334 37731/37731/27434 36378/36378/26365 +f 37732/37732/27433 36356/36356/26343 36366/36366/26353 +f 37732/37732/27433 36366/36366/26353 37733/37733/27434 +f 37733/37733/27434 36366/36366/26353 36372/36372/26359 +f 37733/37733/27434 36372/36372/26359 37619/37619/27361 +f 36378/36378/26365 37731/37731/27434 37617/37617/27359 +f 36378/36378/26365 37617/37617/27359 36360/36360/26347 +f 36322/36322/26312 37734/37734/27435 37735/37735/27436 +f 36322/36322/26312 37735/37735/27436 36345/36345/26333 +f 37736/37736/27435 36289/36289/26286 36352/36352/26340 +f 37736/37736/27435 36352/36352/26340 37737/37737/27437 +f 37737/37737/27437 36352/36352/26340 36356/36356/26343 +f 37737/37737/27437 36356/36356/26343 37732/37732/27433 +f 36345/36345/26333 37735/37735/27436 37730/37730/27433 +f 36345/36345/26333 37730/37730/27433 36346/36346/26334 +f 36308/36308/26301 37738/37738/27438 37739/37739/27439 +f 36308/36308/26301 37739/37739/27439 36309/36309/26302 +f 37740/37740/27438 36330/36330/26319 36349/36349/26337 +f 37740/37740/27438 36349/36349/26337 37741/37741/27439 +f 37741/37741/27439 36349/36349/26337 36331/36331/26320 +f 37741/37741/27439 36331/36331/26320 37742/37742/27440 +f 36309/36309/26302 37739/37739/27439 37743/37743/27441 +f 36309/36309/26302 37743/37743/27441 36310/36310/26303 +f 36310/36310/26303 37743/37743/27441 37744/37744/27442 +f 36310/36310/26303 37744/37744/27442 36374/36374/26361 +f 37742/37742/27440 36331/36331/26320 36334/36334/26323 +f 37742/37742/27440 36334/36334/26323 37745/37745/27442 +f 37745/37745/27442 36334/36334/26323 36342/36342/26330 +f 37745/37745/27442 36342/36342/26330 37626/37626/27363 +f 36374/36374/26361 37744/37744/27442 37746/37746/27363 +f 36374/36374/26361 37746/37746/27363 36375/36375/26362 +f 36315/36315/26307 37747/37747/27443 37748/37748/27444 +f 36315/36315/26307 37748/37748/27444 36316/36316/26308 +f 37749/37749/27443 36262/36262/26265 36326/36326/26316 +f 37749/37749/27443 36326/36326/26316 37750/37750/27445 +f 37750/37750/27445 36326/36326/26316 36330/36330/26319 +f 37750/37750/27445 36330/36330/26319 37740/37740/27438 +f 36316/36316/26308 37748/37748/27444 37738/37738/27438 +f 36316/36316/26308 37738/37738/27438 36308/36308/26301 +f 36266/36266/26269 37751/37751/27446 37752/37752/27447 +f 36266/36266/26269 37752/37752/27447 36301/36301/26295 +f 37753/37753/27448 36277/36277/26276 36291/36291/26288 +f 37753/37753/27448 36291/36291/26288 37754/37754/27447 +f 37754/37754/27447 36291/36291/26288 36278/36278/26277 +f 37754/37754/27447 36278/36278/26277 37755/37755/27449 +f 36301/36301/26295 37752/37752/27447 37756/37756/27450 +f 36301/36301/26295 37756/37756/27450 36302/36302/26296 +f 36320/36320/26296 37757/37757/27450 37758/37758/27451 +f 36320/36320/26296 37758/37758/27451 36321/36321/26311 +f 37755/37755/27449 36278/36278/26277 36281/36281/26280 +f 37755/37755/27449 36281/36281/26280 37759/37759/27452 +f 37759/37759/27452 36281/36281/26280 36289/36289/26286 +f 37759/37759/27452 36289/36289/26286 37736/37736/27435 +f 36321/36321/26311 37758/37758/27451 37734/37734/27435 +f 36321/36321/26311 37734/37734/27435 36322/36322/26312 +f 36247/36247/26254 37760/37760/27453 37761/37761/27454 +f 36247/36247/26254 37761/37761/27454 36265/36265/26268 +f 37762/37762/27455 36230/36230/26241 36272/36272/26274 +f 37762/37762/27455 36272/36272/26274 37763/37763/27454 +f 37763/37763/27454 36272/36272/26274 36277/36277/26276 +f 37763/37763/27454 36277/36277/26276 37753/37753/27448 +f 36265/36265/26268 37761/37761/27454 37751/37751/27446 +f 36265/36265/26268 37751/37751/27446 36266/36266/26269 +f 36217/36217/26228 37764/37764/27456 37765/37765/27457 +f 36217/36217/26228 37765/37765/27457 36218/36218/26229 +f 37766/37766/27458 36188/36188/26200 36269/36269/26272 +f 37766/37766/27458 36269/36269/26272 37767/37767/27457 +f 37767/37767/27457 36269/36269/26272 36249/36249/26256 +f 37767/37767/27457 36249/36249/26256 37768/37768/27459 +f 36218/36218/26229 37765/37765/27457 37769/37769/27459 +f 36218/36218/26229 37769/37769/27459 36219/36219/26230 +f 36219/36219/26230 37769/37769/27459 37770/37770/27460 +f 36219/36219/26230 37770/37770/27460 36297/36297/26291 +f 37768/37768/27459 36249/36249/26256 36252/36252/26259 +f 37768/37768/27459 36252/36252/26259 37771/37771/27460 +f 37771/37771/27460 36252/36252/26259 36262/36262/26265 +f 37771/37771/27460 36262/36262/26265 37749/37749/27443 +f 36297/36297/26291 37770/37770/27460 37772/37772/27461 +f 36297/36297/26291 37772/37772/27461 36298/36298/26292 +f 36245/36245/26252 37773/37773/27462 37774/37774/27463 +f 36245/36245/26252 37774/37774/27463 36246/36246/26253 +f 37775/37775/26868 36222/36222/26233 36225/36225/26236 +f 37775/37775/26868 36225/36225/26236 37776/37776/27464 +f 37776/37776/27464 36225/36225/26236 36230/36230/26241 +f 37776/37776/27464 36230/36230/26241 37762/37762/27455 +f 36246/36246/26253 37774/37774/27463 37760/37760/27453 +f 36246/36246/26253 37760/37760/27453 36247/36247/26254 +f 36209/36209/26220 37567/37567/27320 37777/37777/27465 +f 36209/36209/26220 37777/37777/27465 36210/36210/26221 +f 37566/37566/27320 36189/36189/26201 36192/36192/26204 +f 37566/37566/27320 36192/36192/26204 37778/37778/27466 +f 37778/37778/27466 36192/36192/26204 36200/36200/26211 +f 37778/37778/27466 36200/36200/26211 37603/37603/27348 +f 36210/36210/26221 37777/37777/27465 37601/37601/27346 +f 36210/36210/26221 37601/37601/27346 36211/36211/26222 +f 37779/37779/26245 37780/37780/26687 37781/37781/27467 +f 37779/37779/26245 37781/37781/27467 37782/37782/26729 +f 37780/37780/26687 36177/36177/26191 36180/36180/26194 +f 37780/37780/26687 36180/36180/26194 37781/37781/27467 +f 37781/37781/27467 36180/36180/26194 36188/36188/26200 +f 37781/37781/27467 36188/36188/26200 37766/37766/27458 +f 36827/36827/26729 37783/37783/27467 37764/37764/27456 +f 36827/36827/26729 37764/37764/27456 36217/36217/26228 +f 36203/36203/26214 37561/37561/27315 37784/37784/27468 +f 36203/36203/26214 37784/37784/27468 36204/36204/26215 +f 37560/37560/27314 36143/36143/26159 36146/36146/26162 +f 37560/37560/27314 36146/36146/26162 37785/37785/27469 +f 37785/37785/27469 36146/36146/26162 36154/36154/26169 +f 37785/37785/27469 36154/36154/26169 37609/37609/27353 +f 36204/36204/26215 37784/37784/27468 37607/37607/27351 +f 36204/36204/26215 37607/37607/27351 36205/36205/26216 +f 36114/36114/26133 37071/37071/26920 37786/37786/27470 +f 36114/36114/26133 37786/37786/27470 36569/36569/26528 +f 37071/37071/26920 37787/37787/26094 37788/37788/26097 +f 37071/37071/26920 37788/37788/26097 37786/37786/27470 +f 37786/37786/27470 37788/37788/26097 37789/37789/27471 +f 37786/37786/27470 37789/37789/27471 36537/36537/26499 +f 36569/36569/26528 37786/37786/27470 36537/36537/26499 +f 36569/36569/26528 36537/36537/26499 36536/36536/26498 +f 36607/36607/26177 37790/37790/27472 37791/37791/27473 +f 36607/36607/26177 37791/37791/27473 36608/36608/26560 +f 37790/37790/27472 35974/35974/26007 35977/35977/26010 +f 37790/37790/27472 35977/35977/26010 37791/37791/27473 +f 37791/37791/27473 35977/35977/26010 35985/35985/26017 +f 37791/37791/27473 35985/35985/26017 36526/36526/26490 +f 36608/36608/26560 37791/37791/27473 36526/36526/26490 +f 36608/36608/26560 36526/36526/26490 36525/36525/26489 +o Sphere.014__0 +v -0.568390 0.868483 -1.037403 +v -0.568390 0.877439 -1.037813 +v -0.566656 0.877268 -1.037797 +v -0.564989 0.876760 -1.037750 +v -0.563453 0.875936 -1.037674 +v -0.562107 0.874827 -1.037572 +v -0.561002 0.873476 -1.037447 +v -0.560181 0.871934 -1.037304 +v -0.559675 0.870261 -1.037150 +v -0.559505 0.868521 -1.036989 +v -0.559675 0.866781 -1.036829 +v -0.560181 0.865108 -1.036674 +v -0.561002 0.863566 -1.036532 +v -0.562107 0.862215 -1.036407 +v -0.563453 0.861106 -1.036305 +v -0.564989 0.860282 -1.036228 +v -0.566656 0.859774 -1.036182 +v -0.568390 0.859603 -1.036166 +v -0.570123 0.859774 -1.036182 +v -0.571790 0.860282 -1.036228 +v -0.573325 0.861106 -1.036305 +v -0.574672 0.862215 -1.036407 +v -0.575777 0.863566 -1.036532 +v -0.576598 0.865108 -1.036674 +v -0.577104 0.866781 -1.036829 +v -0.577275 0.868521 -1.036989 +v -0.577104 0.870261 -1.037150 +v -0.576598 0.871934 -1.037304 +v -0.575777 0.873476 -1.037447 +v -0.574672 0.874827 -1.037572 +v -0.573325 0.875936 -1.037674 +v -0.571790 0.876760 -1.037750 +v -0.570123 0.877268 -1.037797 +v -0.568390 0.911943 -1.028011 +v -0.568390 0.914917 -1.024212 +v -0.559675 0.914056 -1.024133 +v -0.560181 0.911131 -1.027936 +v -0.568390 0.907375 -1.031344 +v -0.561002 0.906645 -1.031276 +v -0.568390 0.901389 -1.034081 +v -0.562107 0.900768 -1.034024 +v -0.568390 0.894214 -1.036119 +v -0.563453 0.893726 -1.036074 +v -0.568390 0.886127 -1.037379 +v -0.564989 0.885791 -1.037348 +v -0.561720 0.884796 -1.037256 +v -0.551296 0.911505 -1.023897 +v -0.552288 0.908728 -1.027714 +v -0.553899 0.904482 -1.031076 +v -0.556066 0.898928 -1.033854 +v -0.558707 0.892281 -1.035941 +v -0.545014 0.904825 -1.027354 +v -0.547352 0.900969 -1.030752 +v -0.550498 0.895941 -1.033578 +v -0.554332 0.889934 -1.035724 +v -0.558707 0.883179 -1.037107 +v -0.543574 0.907361 -1.023515 +v -0.556066 0.881004 -1.036906 +v -0.536805 0.901786 -1.023000 +v -0.538637 0.899573 -1.026869 +v -0.541614 0.896242 -1.030316 +v -0.545618 0.891921 -1.033207 +v -0.550498 0.886776 -1.035433 +v -0.536904 0.890483 -1.029784 +v -0.541614 0.887023 -1.032755 +v -0.547352 0.882927 -1.035077 +v -0.553899 0.878353 -1.036661 +v -0.531250 0.894992 -1.022372 +v -0.533405 0.893173 -1.026278 +v -0.527122 0.887240 -1.021657 +v -0.529516 0.885872 -1.025604 +v -0.533405 0.883912 -1.029177 +v -0.538637 0.881435 -1.032239 +v -0.545014 0.878537 -1.034672 +v -0.552288 0.875329 -1.036382 +v -0.536805 0.875371 -1.031679 +v -0.543574 0.873773 -1.034232 +v -0.551296 0.872047 -1.036079 +v -0.524581 0.878830 -1.020880 +v -0.527122 0.877949 -1.024872 +v -0.531250 0.876782 -1.028519 +v -0.523722 0.870083 -1.020073 +v -0.526314 0.869710 -1.024112 +v -0.530522 0.869366 -1.027834 +v -0.536186 0.869065 -1.031097 +v -0.543087 0.868818 -1.033775 +v -0.550961 0.868634 -1.035764 +v -0.536805 0.862759 -1.030514 +v -0.543574 0.863863 -1.033317 +v -0.551296 0.865221 -1.035449 +v -0.524581 0.861336 -1.019265 +v -0.527122 0.861471 -1.023351 +v -0.531250 0.861951 -1.027149 +v -0.527122 0.852926 -1.018488 +v -0.529516 0.853548 -1.022619 +v -0.533405 0.854821 -1.026491 +v -0.538637 0.856695 -1.029955 +v -0.545014 0.859099 -1.032877 +v -0.552288 0.861940 -1.035146 +v -0.547352 0.854708 -1.032472 +v -0.553899 0.858915 -1.034867 +v -0.531250 0.845175 -1.017773 +v -0.533405 0.846247 -1.021945 +v -0.536904 0.848250 -1.025884 +v -0.541614 0.851107 -1.029439 +v -0.536805 0.838381 -1.017145 +v -0.538637 0.839847 -1.021354 +v -0.541614 0.842490 -1.025352 +v -0.545618 0.846209 -1.028986 +v -0.550498 0.850860 -1.032116 +v -0.556066 0.856264 -1.034622 +v -0.554332 0.847702 -1.031825 +v -0.558707 0.854089 -1.034421 +v -0.543574 0.832805 -1.016630 +v -0.545014 0.834595 -1.020869 +v -0.547352 0.837764 -1.024916 +v -0.550498 0.842189 -1.028615 +v -0.552288 0.830692 -1.020509 +v -0.553899 0.834251 -1.024592 +v -0.556066 0.839202 -1.028339 +v -0.558707 0.845355 -1.031608 +v -0.561720 0.852472 -1.034272 +v -0.551296 0.828662 -1.016248 +v -0.564989 0.851477 -1.034180 +v -0.559675 0.826111 -1.016012 +v -0.560181 0.828289 -1.020287 +v -0.561002 0.832088 -1.024392 +v -0.562107 0.837363 -1.028169 +v -0.563453 0.843910 -1.031475 +v -0.568390 0.831358 -1.024324 +v -0.568390 0.836742 -1.028112 +v -0.568390 0.843421 -1.031430 +v -0.568390 0.851141 -1.034149 +v -0.568390 0.825249 -1.015933 +v -0.568390 0.827477 -1.020212 +v -0.568390 0.827477 -1.020212 +v -0.568390 0.825249 -1.015933 +v -0.577104 0.826111 -1.016012 +v -0.576598 0.828289 -1.020287 +v -0.576598 0.828289 -1.020287 +v -0.575777 0.832088 -1.024392 +v -0.574672 0.837363 -1.028169 +v -0.573325 0.843910 -1.031475 +v -0.571790 0.851477 -1.034180 +v -0.582881 0.834251 -1.024592 +v -0.580713 0.839202 -1.028339 +v -0.578072 0.845355 -1.031608 +v -0.575059 0.852472 -1.034272 +v -0.585483 0.828662 -1.016248 +v -0.584491 0.830692 -1.020509 +v -0.575777 0.832088 -1.024392 +v -0.582881 0.834251 -1.024592 +v -0.593205 0.832805 -1.016630 +v -0.591765 0.834595 -1.020869 +v -0.589427 0.837764 -1.024916 +v -0.580713 0.839202 -1.028339 +v -0.586281 0.842189 -1.028615 +v -0.586281 0.842189 -1.028615 +v -0.582446 0.847702 -1.031825 +v -0.578072 0.854089 -1.034421 +v -0.582446 0.847702 -1.031825 +v -0.591161 0.846209 -1.028986 +v -0.586281 0.850860 -1.032116 +v -0.586281 0.850860 -1.032116 +v -0.580713 0.856264 -1.034622 +v -0.599974 0.838381 -1.017145 +v -0.598141 0.839847 -1.021354 +v -0.595166 0.842490 -1.025352 +v -0.605529 0.845175 -1.017773 +v -0.603374 0.846247 -1.021945 +v -0.599875 0.848250 -1.025884 +v -0.595166 0.851107 -1.029439 +v -0.589427 0.854708 -1.032472 +v -0.589427 0.854708 -1.032472 +v -0.582881 0.858915 -1.034867 +v -0.598141 0.856695 -1.029955 +v -0.591765 0.859099 -1.032877 +v -0.591765 0.859099 -1.032877 +v -0.584491 0.861940 -1.035146 +v -0.609657 0.852926 -1.018488 +v -0.607262 0.853548 -1.022619 +v -0.603374 0.854821 -1.026491 +v -0.612199 0.861336 -1.019265 +v -0.609657 0.861471 -1.023351 +v -0.605529 0.861951 -1.027149 +v -0.599974 0.862759 -1.030514 +v -0.593205 0.863863 -1.033317 +v -0.593205 0.863863 -1.033317 +v -0.585483 0.865222 -1.035449 +v -0.593691 0.868818 -1.033775 +v -0.585818 0.868634 -1.035764 +v -0.613057 0.870083 -1.020073 +v -0.610465 0.869710 -1.024112 +v -0.606256 0.869366 -1.027834 +v -0.600593 0.869065 -1.031097 +v -0.593691 0.868818 -1.033775 +v -0.609657 0.877949 -1.024872 +v -0.605529 0.876782 -1.028519 +v -0.599974 0.875371 -1.031679 +v -0.593205 0.873773 -1.034232 +v -0.593205 0.873773 -1.034232 +v -0.585483 0.872047 -1.036079 +v -0.612199 0.878830 -1.020880 +v -0.584491 0.875329 -1.036382 +v -0.609657 0.887240 -1.021657 +v -0.607262 0.885872 -1.025604 +v -0.603374 0.883912 -1.029177 +v -0.598141 0.881435 -1.032239 +v -0.591765 0.878537 -1.034672 +v -0.591765 0.878537 -1.034672 +v -0.603374 0.893173 -1.026278 +v -0.599875 0.890483 -1.029784 +v -0.595166 0.887023 -1.032755 +v -0.589427 0.882927 -1.035077 +v -0.589427 0.882927 -1.035077 +v -0.582881 0.878353 -1.036661 +v -0.605529 0.894992 -1.022372 +v -0.580713 0.881004 -1.036906 +v -0.599974 0.901786 -1.023000 +v -0.598141 0.899573 -1.026869 +v -0.595166 0.896242 -1.030316 +v -0.591161 0.891921 -1.033207 +v -0.586281 0.886776 -1.035433 +v -0.586281 0.886776 -1.035433 +v -0.589427 0.900969 -1.030752 +v -0.586281 0.895941 -1.033578 +v -0.591161 0.891921 -1.033207 +v -0.586281 0.895941 -1.033578 +v -0.582446 0.889934 -1.035724 +v -0.578072 0.883179 -1.037107 +v -0.593205 0.907361 -1.023515 +v -0.591765 0.904825 -1.027354 +v -0.585483 0.911505 -1.023897 +v -0.584491 0.908728 -1.027714 +v -0.582881 0.904482 -1.031076 +v -0.589427 0.900969 -1.030752 +v -0.582881 0.904482 -1.031076 +v -0.580713 0.898928 -1.033854 +v -0.578072 0.892281 -1.035941 +v -0.575059 0.884796 -1.037256 +v -0.575777 0.906645 -1.031276 +v -0.574672 0.900768 -1.034024 +v -0.573325 0.893726 -1.036074 +v -0.571790 0.885791 -1.037348 +v -0.577104 0.914056 -1.024133 +v -0.576598 0.911131 -1.027936 +v -0.584491 0.908728 -1.027714 +v -0.576598 0.911131 -1.027936 +v -0.577104 0.914056 -1.024133 +vt 0.646501 0.776980 +vt 0.646564 0.776320 +vt 0.646438 0.776320 +vt 0.646315 0.776345 +vt 0.646198 0.776395 +vt 0.646092 0.776467 +vt 0.646002 0.776559 +vt 0.645931 0.776667 +vt 0.645881 0.776786 +vt 0.645856 0.776914 +vt 0.645854 0.777043 +vt 0.645877 0.777170 +vt 0.645924 0.777290 +vt 0.645993 0.777398 +vt 0.646081 0.777490 +vt 0.646185 0.777562 +vt 0.646301 0.777611 +vt 0.646425 0.777637 +vt 0.646551 0.777637 +vt 0.646674 0.777611 +vt 0.646791 0.777562 +vt 0.646897 0.777490 +vt 0.646987 0.777398 +vt 0.647058 0.777290 +vt 0.647107 0.777170 +vt 0.647133 0.777043 +vt 0.647135 0.776914 +vt 0.647111 0.776786 +vt 0.647065 0.776667 +vt 0.646996 0.776559 +vt 0.646908 0.776467 +vt 0.646803 0.776395 +vt 0.646688 0.776345 +vt 0.646625 0.773820 +vt 0.646583 0.773615 +vt 0.645950 0.773615 +vt 0.646029 0.773820 +vt 0.646650 0.774143 +vt 0.646113 0.774143 +vt 0.646656 0.774573 +vt 0.646200 0.774573 +vt 0.646644 0.775093 +vt 0.646285 0.775093 +vt 0.646612 0.775683 +vt 0.646365 0.775683 +vt 0.646122 0.775733 +vt 0.645327 0.773742 +vt 0.645442 0.773939 +vt 0.645585 0.774251 +vt 0.645751 0.774665 +vt 0.645932 0.775165 +vt 0.644889 0.774174 +vt 0.645087 0.774463 +vt 0.645327 0.774845 +vt 0.645599 0.775307 +vt 0.645893 0.775830 +vt 0.644739 0.773991 +vt 0.645686 0.775971 +vt 0.644209 0.774354 +vt 0.644389 0.774516 +vt 0.644637 0.774770 +vt 0.644945 0.775106 +vt 0.645299 0.775512 +vt 0.644254 0.775161 +vt 0.644618 0.775438 +vt 0.645042 0.775773 +vt 0.645510 0.776151 +vt 0.643756 0.774815 +vt 0.643963 0.774950 +vt 0.643399 0.775357 +vt 0.643626 0.775461 +vt 0.643951 0.775620 +vt 0.644360 0.775829 +vt 0.644840 0.776080 +vt 0.645370 0.776363 +vt 0.644181 0.776264 +vt 0.644699 0.776421 +vt 0.645273 0.776598 +vt 0.643150 0.775959 +vt 0.643391 0.776028 +vt 0.643740 0.776131 +vt 0.643020 0.776599 +vt 0.643269 0.776631 +vt 0.643629 0.776673 +vt 0.644087 0.776725 +vt 0.644625 0.776784 +vt 0.645222 0.776847 +vt 0.644082 0.777195 +vt 0.644621 0.777153 +vt 0.645220 0.777102 +vt 0.643013 0.777251 +vt 0.643262 0.777245 +vt 0.643623 0.777226 +vt 0.643130 0.777890 +vt 0.643372 0.777847 +vt 0.643723 0.777768 +vt 0.644167 0.777656 +vt 0.644687 0.777515 +vt 0.645265 0.777351 +vt 0.644821 0.777856 +vt 0.645357 0.777586 +vt 0.643366 0.778493 +vt 0.643595 0.778415 +vt 0.643923 0.778279 +vt 0.644337 0.778090 +vt 0.643712 0.779035 +vt 0.643921 0.778925 +vt 0.644216 0.778738 +vt 0.644586 0.778481 +vt 0.645017 0.778163 +vt 0.645492 0.777798 +vt 0.645268 0.778425 +vt 0.645665 0.777978 +vt 0.644155 0.779496 +vt 0.644338 0.779360 +vt 0.644592 0.779129 +vt 0.644906 0.778813 +vt 0.644831 0.779701 +vt 0.645035 0.779436 +vt 0.645283 0.779075 +vt 0.645564 0.778630 +vt 0.645869 0.778119 +vt 0.644678 0.779858 +vt 0.646096 0.778216 +vt 0.645261 0.780108 +vt 0.645380 0.779936 +vt 0.645529 0.779648 +vt 0.645703 0.779254 +vt 0.645894 0.778771 +vt 0.646054 0.779756 +vt 0.646150 0.779346 +vt 0.646246 0.778843 +vt 0.646338 0.778266 +vt 0.645880 0.780235 +vt 0.645963 0.780056 +vt 0.934614 0.535289 +vt 0.934397 0.535097 +vt 0.933929 0.535223 +vt 0.934173 0.535408 +vt 0.646560 0.780056 +vt 0.646591 0.779756 +vt 0.646606 0.779346 +vt 0.646604 0.778843 +vt 0.646585 0.778266 +vt 0.647119 0.779648 +vt 0.647055 0.779254 +vt 0.646957 0.778771 +vt 0.646828 0.778216 +vt 0.933488 0.535472 +vt 0.933757 0.535642 +vt 0.934426 0.535708 +vt 0.934052 0.535919 +vt 0.933091 0.535834 +vt 0.933383 0.535983 +vt 0.933715 0.536226 +vt 0.934361 0.536292 +vt 0.934075 0.536553 +vt 0.647479 0.779075 +vt 0.647290 0.778630 +vt 0.647058 0.778119 +vt 0.934448 0.536951 +vt 0.933832 0.536885 +vt 0.934257 0.537212 +vt 0.647590 0.778425 +vt 0.647265 0.777978 +vt 0.932753 0.536294 +vt 0.933065 0.536417 +vt 0.933429 0.536617 +vt 0.932488 0.536837 +vt 0.932815 0.536928 +vt 0.933204 0.537076 +vt 0.933640 0.537276 +vt 0.934107 0.537519 +vt 0.647847 0.778163 +vt 0.647441 0.777798 +vt 0.933509 0.537710 +vt 0.934003 0.537860 +vt 0.648049 0.777856 +vt 0.647581 0.777586 +vt 0.932305 0.537439 +vt 0.932643 0.537495 +vt 0.933049 0.537587 +vt 0.932212 0.538079 +vt 0.932555 0.538098 +vt 0.932970 0.538129 +vt 0.933441 0.538171 +vt 0.933950 0.538223 +vt 0.648190 0.777515 +vt 0.647678 0.777351 +vt 0.648264 0.777153 +vt 0.647729 0.777102 +vt 0.932212 0.538732 +vt 0.932555 0.538713 +vt 0.932970 0.538683 +vt 0.933441 0.538642 +vt 0.933950 0.538592 +vt 0.932643 0.539316 +vt 0.933049 0.539226 +vt 0.933509 0.539104 +vt 0.934003 0.538955 +vt 0.648268 0.776784 +vt 0.647731 0.776847 +vt 0.932305 0.539372 +vt 0.647686 0.776598 +vt 0.932488 0.539975 +vt 0.932815 0.539884 +vt 0.933204 0.539737 +vt 0.933640 0.539539 +vt 0.934107 0.539297 +vt 0.648202 0.776421 +vt 0.933065 0.540396 +vt 0.933429 0.540197 +vt 0.933832 0.539930 +vt 0.934257 0.539604 +vt 0.648068 0.776080 +vt 0.647594 0.776363 +vt 0.932753 0.540518 +vt 0.647458 0.776151 +vt 0.933091 0.540981 +vt 0.933383 0.540831 +vt 0.933715 0.540589 +vt 0.934075 0.540263 +vt 0.934448 0.539866 +vt 0.647872 0.775773 +vt 0.934052 0.540897 +vt 0.934361 0.540525 +vt 0.648219 0.775438 +vt 0.647900 0.775106 +vt 0.647621 0.775512 +vt 0.647286 0.775971 +vt 0.933488 0.541344 +vt 0.933757 0.541174 +vt 0.933929 0.541595 +vt 0.934173 0.541410 +vt 0.934426 0.541110 +vt 0.648113 0.774770 +vt 0.647669 0.774463 +vt 0.647523 0.774845 +vt 0.647325 0.775307 +vt 0.647082 0.775830 +vt 0.647176 0.774251 +vt 0.647103 0.774665 +vt 0.646995 0.775165 +vt 0.646854 0.775733 +vt 0.934397 0.541723 +vt 0.934614 0.541531 +vt 0.647758 0.774174 +vt 0.647209 0.773939 +vt 0.647203 0.773742 +vn -0.0000 -0.0919 -0.9958 +vn -0.0000 0.0051 -1.0000 +vn 0.0191 0.0032 -0.9998 +vn 0.0374 -0.0023 -0.9993 +vn 0.0543 -0.0112 -0.9985 +vn 0.0691 -0.0233 -0.9973 +vn 0.0813 -0.0379 -0.9960 +vn 0.0903 -0.0546 -0.9944 +vn 0.0958 -0.0726 -0.9927 +vn 0.0977 -0.0915 -0.9910 +vn 0.0958 -0.1103 -0.9893 +vn 0.0903 -0.1284 -0.9876 +vn 0.0812 -0.1451 -0.9861 +vn 0.0691 -0.1598 -0.9847 +vn 0.0543 -0.1718 -0.9836 +vn 0.0374 -0.1807 -0.9828 +vn 0.0192 -0.1862 -0.9823 +vn 0.0000 -0.1881 -0.9822 +vn -0.0191 -0.1862 -0.9823 +vn -0.0374 -0.1807 -0.9828 +vn -0.0543 -0.1718 -0.9836 +vn -0.0691 -0.1598 -0.9847 +vn -0.0812 -0.1451 -0.9861 +vn -0.0903 -0.1284 -0.9876 +vn -0.0958 -0.1104 -0.9893 +vn -0.0977 -0.0915 -0.9910 +vn -0.0958 -0.0726 -0.9927 +vn -0.0903 -0.0546 -0.9944 +vn -0.0813 -0.0379 -0.9960 +vn -0.0691 -0.0233 -0.9973 +vn -0.0543 -0.0112 -0.9985 +vn -0.0375 -0.0023 -0.9993 +vn -0.0191 0.0032 -0.9998 +vn -0.0000 0.6990 -0.7151 +vn -0.0000 0.7874 -0.6165 +vn 0.1652 0.7711 -0.6149 +vn 0.1498 0.6843 -0.7137 +vn 0.0000 0.5096 -0.8604 +vn 0.1153 0.4983 -0.8593 +vn -0.0000 0.3496 -0.9369 +vn 0.0854 0.3413 -0.9361 +vn 0.0000 0.2176 -0.9760 +vn 0.0603 0.2117 -0.9755 +vn 0.0000 0.1052 -0.9944 +vn 0.0386 0.1015 -0.9941 +vn 0.0757 0.0904 -0.9930 +vn 0.3238 0.7231 -0.6101 +vn 0.2936 0.6408 -0.7093 +vn 0.2262 0.4649 -0.8560 +vn 0.1675 0.3166 -0.9336 +vn 0.1182 0.1943 -0.9738 +vn 0.4259 0.5703 -0.7024 +vn 0.3282 0.4108 -0.8506 +vn 0.2431 0.2766 -0.9297 +vn 0.1716 0.1661 -0.9711 +vn 0.1099 0.0723 -0.9913 +vn 0.4698 0.6453 -0.6024 +vn 0.1399 0.0479 -0.9890 +vn 0.5973 0.5408 -0.5922 +vn 0.5416 0.4757 -0.6931 +vn 0.4174 0.3380 -0.8435 +vn 0.3093 0.2228 -0.9245 +vn 0.2183 0.1281 -0.9674 +vn 0.4906 0.2495 -0.8349 +vn 0.3636 0.1572 -0.9182 +vn 0.2566 0.0819 -0.9630 +vn 0.1644 0.0183 -0.9862 +vn 0.7018 0.4139 -0.5799 +vn 0.6363 0.3607 -0.6819 +vn 0.7791 0.2695 -0.5660 +vn 0.7065 0.2298 -0.6694 +vn 0.5448 0.1486 -0.8253 +vn 0.4038 0.0825 -0.9111 +vn 0.2851 0.0292 -0.9581 +vn 0.1827 -0.0154 -0.9831 +vn 0.4286 0.0015 -0.9035 +vn 0.3026 -0.0280 -0.9527 +vn 0.1939 -0.0520 -0.9796 +vn 0.8266 0.1130 -0.5512 +vn 0.7496 0.0880 -0.6560 +vn 0.5782 0.0394 -0.8149 +vn 0.8427 -0.0495 -0.5361 +vn 0.7642 -0.0593 -0.6423 +vn 0.5895 -0.0743 -0.8044 +vn 0.4370 -0.0827 -0.8957 +vn 0.3085 -0.0874 -0.9472 +vn 0.1977 -0.0901 -0.9761 +vn 0.4287 -0.1669 -0.8879 +vn 0.3026 -0.1469 -0.9417 +vn 0.1939 -0.1282 -0.9726 +vn 0.8267 -0.2121 -0.5212 +vn 0.7496 -0.2066 -0.6288 +vn 0.5782 -0.1879 -0.7940 +vn 0.7791 -0.3685 -0.5071 +vn 0.7065 -0.3485 -0.6160 +vn 0.5448 -0.2973 -0.7841 +vn 0.4039 -0.2480 -0.8806 +vn 0.2851 -0.2041 -0.9365 +vn 0.1826 -0.1649 -0.9693 +vn 0.2566 -0.2569 -0.9318 +vn 0.1644 -0.1986 -0.9662 +vn 0.7017 -0.5131 -0.4943 +vn 0.6363 -0.4794 -0.6044 +vn 0.4906 -0.3982 -0.7751 +vn 0.3636 -0.3227 -0.8739 +vn 0.5973 -0.6401 -0.4831 +vn 0.5416 -0.5945 -0.5943 +vn 0.4174 -0.4867 -0.7673 +vn 0.3093 -0.3883 -0.8681 +vn 0.2183 -0.3031 -0.9276 +vn 0.1398 -0.2282 -0.9635 +vn 0.1715 -0.3411 -0.9242 +vn 0.1099 -0.2526 -0.9613 +vn 0.4698 -0.7447 -0.4741 +vn 0.4259 -0.6893 -0.5861 +vn 0.3282 -0.5596 -0.7610 +vn 0.2431 -0.4421 -0.8634 +vn 0.2936 -0.7599 -0.5800 +vn 0.2262 -0.6138 -0.7564 +vn 0.1675 -0.4822 -0.8599 +vn 0.1182 -0.3693 -0.9217 +vn 0.0757 -0.2706 -0.9597 +vn 0.3238 -0.8226 -0.4674 +vn 0.0386 -0.2818 -0.9587 +vn 0.1652 -0.8707 -0.4632 +vn 0.1498 -0.8034 -0.5763 +vn 0.1153 -0.6472 -0.7535 +vn 0.0854 -0.5069 -0.8577 +vn 0.0603 -0.3867 -0.9202 +vn -0.0000 -0.6585 -0.7525 +vn 0.0000 -0.5153 -0.8570 +vn 0.0000 -0.3926 -0.9197 +vn -0.0000 -0.2855 -0.9584 +vn 0.0000 -0.8869 -0.4619 +vn -0.0000 -0.8181 -0.5750 +vn -0.0000 -0.8181 -0.5751 +vn -0.1652 -0.8707 -0.4632 +vn -0.1498 -0.8034 -0.5763 +vn -0.1154 -0.6472 -0.7535 +vn -0.0854 -0.5069 -0.8577 +vn -0.0603 -0.3867 -0.9202 +vn -0.0386 -0.2818 -0.9587 +vn -0.2261 -0.6138 -0.7564 +vn -0.1675 -0.4822 -0.8599 +vn -0.1182 -0.3693 -0.9217 +vn -0.0757 -0.2706 -0.9597 +vn -0.3239 -0.8226 -0.4674 +vn -0.2936 -0.7599 -0.5800 +vn -0.1153 -0.6472 -0.7535 +vn -0.2262 -0.6138 -0.7564 +vn -0.4698 -0.7447 -0.4740 +vn -0.4259 -0.6893 -0.5861 +vn -0.3282 -0.5596 -0.7610 +vn -0.2431 -0.4421 -0.8634 +vn -0.1716 -0.3411 -0.9243 +vn -0.1099 -0.2526 -0.9613 +vn -0.1716 -0.3411 -0.9242 +vn -0.3093 -0.3883 -0.8681 +vn -0.2183 -0.3031 -0.9276 +vn -0.1398 -0.2282 -0.9635 +vn -0.5974 -0.6401 -0.4831 +vn -0.5416 -0.5946 -0.5943 +vn -0.4174 -0.4867 -0.7673 +vn -0.7017 -0.5131 -0.4942 +vn -0.6363 -0.4794 -0.6044 +vn -0.4906 -0.3982 -0.7751 +vn -0.3636 -0.3227 -0.8739 +vn -0.2566 -0.2569 -0.9318 +vn -0.1644 -0.1986 -0.9662 +vn -0.4038 -0.2479 -0.8806 +vn -0.2851 -0.2041 -0.9365 +vn -0.1826 -0.1649 -0.9693 +vn -0.7791 -0.3685 -0.5071 +vn -0.7065 -0.3485 -0.6160 +vn -0.5449 -0.2973 -0.7841 +vn -0.8267 -0.2121 -0.5212 +vn -0.7496 -0.2066 -0.6288 +vn -0.5782 -0.1879 -0.7940 +vn -0.4286 -0.1669 -0.8879 +vn -0.3026 -0.1469 -0.9417 +vn -0.1939 -0.1282 -0.9726 +vn -0.3085 -0.0874 -0.9472 +vn -0.1977 -0.0901 -0.9761 +vn -0.8427 -0.0495 -0.5361 +vn -0.7642 -0.0593 -0.6423 +vn -0.5895 -0.0743 -0.8044 +vn -0.4370 -0.0827 -0.8956 +vn -0.3085 -0.0875 -0.9472 +vn -0.7496 0.0880 -0.6560 +vn -0.5782 0.0393 -0.8149 +vn -0.4286 0.0015 -0.9035 +vn -0.3026 -0.0280 -0.9527 +vn -0.1939 -0.0520 -0.9796 +vn -0.8266 0.1130 -0.5513 +vn -0.1827 -0.0154 -0.9831 +vn -0.7791 0.2695 -0.5660 +vn -0.7065 0.2298 -0.6694 +vn -0.5449 0.1486 -0.8253 +vn -0.4038 0.0825 -0.9111 +vn -0.2851 0.0292 -0.9581 +vn -0.6363 0.3607 -0.6819 +vn -0.4906 0.2495 -0.8349 +vn -0.3636 0.1572 -0.9182 +vn -0.2566 0.0819 -0.9630 +vn -0.1644 0.0184 -0.9862 +vn -0.7018 0.4139 -0.5798 +vn -0.1399 0.0479 -0.9890 +vn -0.5973 0.5408 -0.5922 +vn -0.5416 0.4757 -0.6931 +vn -0.4174 0.3380 -0.8435 +vn -0.3093 0.2228 -0.9245 +vn -0.2183 0.1281 -0.9674 +vn -0.3282 0.4108 -0.8506 +vn -0.2430 0.2766 -0.9298 +vn -0.2431 0.2766 -0.9297 +vn -0.1716 0.1661 -0.9711 +vn -0.1099 0.0723 -0.9913 +vn -0.4698 0.6453 -0.6024 +vn -0.4259 0.5703 -0.7024 +vn -0.3239 0.7231 -0.6101 +vn -0.2936 0.6408 -0.7093 +vn -0.2261 0.4649 -0.8560 +vn -0.1675 0.3166 -0.9336 +vn -0.1182 0.1943 -0.9738 +vn -0.0757 0.0903 -0.9930 +vn -0.1153 0.4983 -0.8593 +vn -0.0854 0.3413 -0.9361 +vn -0.0603 0.2117 -0.9755 +vn -0.0386 0.1015 -0.9941 +vn -0.1652 0.7711 -0.6149 +vn -0.1497 0.6843 -0.7137 +vn -0.1498 0.6843 -0.7137 +usemtl Scene_-_Root +s 1 +f 37792/37792/27474 37793/37793/27475 37794/37794/27476 +f 37792/37792/27474 37794/37794/27476 37795/37795/27477 +f 37792/37792/27474 37795/37795/27477 37796/37796/27478 +f 37792/37792/27474 37796/37796/27478 37797/37797/27479 +f 37792/37792/27474 37797/37797/27479 37798/37798/27480 +f 37792/37792/27474 37798/37798/27480 37799/37799/27481 +f 37792/37792/27474 37799/37799/27481 37800/37800/27482 +f 37792/37792/27474 37800/37800/27482 37801/37801/27483 +f 37792/37792/27474 37801/37801/27483 37802/37802/27484 +f 37792/37792/27474 37802/37802/27484 37803/37803/27485 +f 37792/37792/27474 37803/37803/27485 37804/37804/27486 +f 37792/37792/27474 37804/37804/27486 37805/37805/27487 +f 37792/37792/27474 37805/37805/27487 37806/37806/27488 +f 37792/37792/27474 37806/37806/27488 37807/37807/27489 +f 37792/37792/27474 37807/37807/27489 37808/37808/27490 +f 37792/37792/27474 37808/37808/27490 37809/37809/27491 +f 37792/37792/27474 37809/37809/27491 37810/37810/27492 +f 37792/37792/27474 37810/37810/27492 37811/37811/27493 +f 37792/37792/27474 37811/37811/27493 37812/37812/27494 +f 37792/37792/27474 37812/37812/27494 37813/37813/27495 +f 37792/37792/27474 37813/37813/27495 37814/37814/27496 +f 37792/37792/27474 37814/37814/27496 37815/37815/27497 +f 37792/37792/27474 37815/37815/27497 37816/37816/27498 +f 37792/37792/27474 37816/37816/27498 37817/37817/27499 +f 37792/37792/27474 37817/37817/27499 37818/37818/27500 +f 37792/37792/27474 37818/37818/27500 37819/37819/27501 +f 37792/37792/27474 37819/37819/27501 37820/37820/27502 +f 37792/37792/27474 37820/37820/27502 37821/37821/27503 +f 37792/37792/27474 37821/37821/27503 37822/37822/27504 +f 37792/37792/27474 37822/37822/27504 37823/37823/27505 +f 37792/37792/27474 37823/37823/27505 37824/37824/27506 +f 37792/37792/27474 37824/37824/27506 37793/37793/27475 +f 37825/37825/27507 37826/37826/27508 37827/37827/27509 +f 37825/37825/27507 37827/37827/27509 37828/37828/27510 +f 37829/37829/27511 37825/37825/27507 37828/37828/27510 +f 37829/37829/27511 37828/37828/27510 37830/37830/27512 +f 37831/37831/27513 37829/37829/27511 37830/37830/27512 +f 37831/37831/27513 37830/37830/27512 37832/37832/27514 +f 37833/37833/27515 37831/37831/27513 37832/37832/27514 +f 37833/37833/27515 37832/37832/27514 37834/37834/27516 +f 37835/37835/27517 37833/37833/27515 37834/37834/27516 +f 37835/37835/27517 37834/37834/27516 37836/37836/27518 +f 37793/37793/27475 37835/37835/27517 37836/37836/27518 +f 37793/37793/27475 37836/37836/27518 37794/37794/27476 +f 37794/37794/27476 37836/37836/27518 37837/37837/27519 +f 37794/37794/27476 37837/37837/27519 37795/37795/27477 +f 37828/37828/27510 37827/37827/27509 37838/37838/27520 +f 37828/37828/27510 37838/37838/27520 37839/37839/27521 +f 37830/37830/27512 37828/37828/27510 37839/37839/27521 +f 37830/37830/27512 37839/37839/27521 37840/37840/27522 +f 37832/37832/27514 37830/37830/27512 37840/37840/27522 +f 37832/37832/27514 37840/37840/27522 37841/37841/27523 +f 37834/37834/27516 37832/37832/27514 37841/37841/27523 +f 37834/37834/27516 37841/37841/27523 37842/37842/27524 +f 37836/37836/27518 37834/37834/27516 37842/37842/27524 +f 37836/37836/27518 37842/37842/27524 37837/37837/27519 +f 37840/37840/27522 37839/37839/27521 37843/37843/27525 +f 37840/37840/27522 37843/37843/27525 37844/37844/27526 +f 37841/37841/27523 37840/37840/27522 37844/37844/27526 +f 37841/37841/27523 37844/37844/27526 37845/37845/27527 +f 37842/37842/27524 37841/37841/27523 37845/37845/27527 +f 37842/37842/27524 37845/37845/27527 37846/37846/27528 +f 37837/37837/27519 37842/37842/27524 37846/37846/27528 +f 37837/37837/27519 37846/37846/27528 37847/37847/27529 +f 37795/37795/27477 37837/37837/27519 37847/37847/27529 +f 37795/37795/27477 37847/37847/27529 37796/37796/27478 +f 37839/37839/27521 37838/37838/27520 37848/37848/27530 +f 37839/37839/27521 37848/37848/27530 37843/37843/27525 +f 37796/37796/27478 37847/37847/27529 37849/37849/27531 +f 37796/37796/27478 37849/37849/27531 37797/37797/27479 +f 37843/37843/27525 37848/37848/27530 37850/37850/27532 +f 37843/37843/27525 37850/37850/27532 37851/37851/27533 +f 37844/37844/27526 37843/37843/27525 37851/37851/27533 +f 37844/37844/27526 37851/37851/27533 37852/37852/27534 +f 37845/37845/27527 37844/37844/27526 37852/37852/27534 +f 37845/37845/27527 37852/37852/27534 37853/37853/27535 +f 37846/37846/27528 37845/37845/27527 37853/37853/27535 +f 37846/37846/27528 37853/37853/27535 37854/37854/27536 +f 37847/37847/27529 37846/37846/27528 37854/37854/27536 +f 37847/37847/27529 37854/37854/27536 37849/37849/27531 +f 37853/37853/27535 37852/37852/27534 37855/37855/27537 +f 37853/37853/27535 37855/37855/27537 37856/37856/27538 +f 37854/37854/27536 37853/37853/27535 37856/37856/27538 +f 37854/37854/27536 37856/37856/27538 37857/37857/27539 +f 37849/37849/27531 37854/37854/27536 37857/37857/27539 +f 37849/37849/27531 37857/37857/27539 37858/37858/27540 +f 37797/37797/27479 37849/37849/27531 37858/37858/27540 +f 37797/37797/27479 37858/37858/27540 37798/37798/27480 +f 37851/37851/27533 37850/37850/27532 37859/37859/27541 +f 37851/37851/27533 37859/37859/27541 37860/37860/27542 +f 37852/37852/27534 37851/37851/27533 37860/37860/27542 +f 37852/37852/27534 37860/37860/27542 37855/37855/27537 +f 37860/37860/27542 37859/37859/27541 37861/37861/27543 +f 37860/37860/27542 37861/37861/27543 37862/37862/27544 +f 37855/37855/27537 37860/37860/27542 37862/37862/27544 +f 37855/37855/27537 37862/37862/27544 37863/37863/27545 +f 37856/37856/27538 37855/37855/27537 37863/37863/27545 +f 37856/37856/27538 37863/37863/27545 37864/37864/27546 +f 37857/37857/27539 37856/37856/27538 37864/37864/27546 +f 37857/37857/27539 37864/37864/27546 37865/37865/27547 +f 37858/37858/27540 37857/37857/27539 37865/37865/27547 +f 37858/37858/27540 37865/37865/27547 37866/37866/27548 +f 37798/37798/27480 37858/37858/27540 37866/37866/27548 +f 37798/37798/27480 37866/37866/27548 37799/37799/27481 +f 37865/37865/27547 37864/37864/27546 37867/37867/27549 +f 37865/37865/27547 37867/37867/27549 37868/37868/27550 +f 37866/37866/27548 37865/37865/27547 37868/37868/27550 +f 37866/37866/27548 37868/37868/27550 37869/37869/27551 +f 37799/37799/27481 37866/37866/27548 37869/37869/27551 +f 37799/37799/27481 37869/37869/27551 37800/37800/27482 +f 37862/37862/27544 37861/37861/27543 37870/37870/27552 +f 37862/37862/27544 37870/37870/27552 37871/37871/27553 +f 37863/37863/27545 37862/37862/27544 37871/37871/27553 +f 37863/37863/27545 37871/37871/27553 37872/37872/27554 +f 37864/37864/27546 37863/37863/27545 37872/37872/27554 +f 37864/37864/27546 37872/37872/27554 37867/37867/27549 +f 37871/37871/27553 37870/37870/27552 37873/37873/27555 +f 37871/37871/27553 37873/37873/27555 37874/37874/27556 +f 37872/37872/27554 37871/37871/27553 37874/37874/27556 +f 37872/37872/27554 37874/37874/27556 37875/37875/27557 +f 37867/37867/27549 37872/37872/27554 37875/37875/27557 +f 37867/37867/27549 37875/37875/27557 37876/37876/27558 +f 37868/37868/27550 37867/37867/27549 37876/37876/27558 +f 37868/37868/27550 37876/37876/27558 37877/37877/27559 +f 37869/37869/27551 37868/37868/27550 37877/37877/27559 +f 37869/37869/27551 37877/37877/27559 37878/37878/27560 +f 37800/37800/27482 37869/37869/27551 37878/37878/27560 +f 37800/37800/27482 37878/37878/27560 37801/37801/27483 +f 37877/37877/27559 37876/37876/27558 37879/37879/27561 +f 37877/37877/27559 37879/37879/27561 37880/37880/27562 +f 37878/37878/27560 37877/37877/27559 37880/37880/27562 +f 37878/37878/27560 37880/37880/27562 37881/37881/27563 +f 37801/37801/27483 37878/37878/27560 37881/37881/27563 +f 37801/37801/27483 37881/37881/27563 37802/37802/27484 +f 37874/37874/27556 37873/37873/27555 37882/37882/27564 +f 37874/37874/27556 37882/37882/27564 37883/37883/27565 +f 37875/37875/27557 37874/37874/27556 37883/37883/27565 +f 37875/37875/27557 37883/37883/27565 37884/37884/27566 +f 37876/37876/27558 37875/37875/27557 37884/37884/27566 +f 37876/37876/27558 37884/37884/27566 37879/37879/27561 +f 37883/37883/27565 37882/37882/27564 37885/37885/27567 +f 37883/37883/27565 37885/37885/27567 37886/37886/27568 +f 37884/37884/27566 37883/37883/27565 37886/37886/27568 +f 37884/37884/27566 37886/37886/27568 37887/37887/27569 +f 37879/37879/27561 37884/37884/27566 37887/37887/27569 +f 37879/37879/27561 37887/37887/27569 37888/37888/27570 +f 37880/37880/27562 37879/37879/27561 37888/37888/27570 +f 37880/37880/27562 37888/37888/27570 37889/37889/27571 +f 37881/37881/27563 37880/37880/27562 37889/37889/27571 +f 37881/37881/27563 37889/37889/27571 37890/37890/27572 +f 37802/37802/27484 37881/37881/27563 37890/37890/27572 +f 37802/37802/27484 37890/37890/27572 37803/37803/27485 +f 37890/37890/27572 37889/37889/27571 37891/37891/27573 +f 37890/37890/27572 37891/37891/27573 37892/37892/27574 +f 37803/37803/27485 37890/37890/27572 37892/37892/27574 +f 37803/37803/27485 37892/37892/27574 37804/37804/27486 +f 37886/37886/27568 37885/37885/27567 37893/37893/27575 +f 37886/37886/27568 37893/37893/27575 37894/37894/27576 +f 37887/37887/27569 37886/37886/27568 37894/37894/27576 +f 37887/37887/27569 37894/37894/27576 37895/37895/27577 +f 37888/37888/27570 37887/37887/27569 37895/37895/27577 +f 37888/37888/27570 37895/37895/27577 37896/37896/27578 +f 37889/37889/27571 37888/37888/27570 37896/37896/27578 +f 37889/37889/27571 37896/37896/27578 37891/37891/27573 +f 37894/37894/27576 37893/37893/27575 37897/37897/27579 +f 37894/37894/27576 37897/37897/27579 37898/37898/27580 +f 37895/37895/27577 37894/37894/27576 37898/37898/27580 +f 37895/37895/27577 37898/37898/27580 37899/37899/27581 +f 37896/37896/27578 37895/37895/27577 37899/37899/27581 +f 37896/37896/27578 37899/37899/27581 37900/37900/27582 +f 37891/37891/27573 37896/37896/27578 37900/37900/27582 +f 37891/37891/27573 37900/37900/27582 37901/37901/27583 +f 37892/37892/27574 37891/37891/27573 37901/37901/27583 +f 37892/37892/27574 37901/37901/27583 37902/37902/27584 +f 37804/37804/27486 37892/37892/27574 37902/37902/27584 +f 37804/37804/27486 37902/37902/27584 37805/37805/27487 +f 37902/37902/27584 37901/37901/27583 37903/37903/27585 +f 37902/37902/27584 37903/37903/27585 37904/37904/27586 +f 37805/37805/27487 37902/37902/27584 37904/37904/27586 +f 37805/37805/27487 37904/37904/27586 37806/37806/27488 +f 37898/37898/27580 37897/37897/27579 37905/37905/27587 +f 37898/37898/27580 37905/37905/27587 37906/37906/27588 +f 37899/37899/27581 37898/37898/27580 37906/37906/27588 +f 37899/37899/27581 37906/37906/27588 37907/37907/27589 +f 37900/37900/27582 37899/37899/27581 37907/37907/27589 +f 37900/37900/27582 37907/37907/27589 37908/37908/27590 +f 37901/37901/27583 37900/37900/27582 37908/37908/27590 +f 37901/37901/27583 37908/37908/27590 37903/37903/27585 +f 37907/37907/27589 37906/37906/27588 37909/37909/27591 +f 37907/37907/27589 37909/37909/27591 37910/37910/27592 +f 37908/37908/27590 37907/37907/27589 37910/37910/27592 +f 37908/37908/27590 37910/37910/27592 37911/37911/27593 +f 37903/37903/27585 37908/37908/27590 37911/37911/27593 +f 37903/37903/27585 37911/37911/27593 37912/37912/27594 +f 37904/37904/27586 37903/37903/27585 37912/37912/27594 +f 37904/37904/27586 37912/37912/27594 37913/37913/27595 +f 37806/37806/27488 37904/37904/27586 37913/37913/27595 +f 37806/37806/27488 37913/37913/27595 37807/37807/27489 +f 37906/37906/27588 37905/37905/27587 37914/37914/27596 +f 37906/37906/27588 37914/37914/27596 37909/37909/27591 +f 37807/37807/27489 37913/37913/27595 37915/37915/27597 +f 37807/37807/27489 37915/37915/27597 37808/37808/27490 +f 37909/37909/27591 37914/37914/27596 37916/37916/27598 +f 37909/37909/27591 37916/37916/27598 37917/37917/27599 +f 37910/37910/27592 37909/37909/27591 37917/37917/27599 +f 37910/37910/27592 37917/37917/27599 37918/37918/27600 +f 37911/37911/27593 37910/37910/27592 37918/37918/27600 +f 37911/37911/27593 37918/37918/27600 37919/37919/27601 +f 37912/37912/27594 37911/37911/27593 37919/37919/27601 +f 37912/37912/27594 37919/37919/27601 37920/37920/27602 +f 37913/37913/27595 37912/37912/27594 37920/37920/27602 +f 37913/37913/27595 37920/37920/27602 37915/37915/27597 +f 37919/37919/27601 37918/37918/27600 37921/37921/27603 +f 37919/37919/27601 37921/37921/27603 37922/37922/27604 +f 37920/37920/27602 37919/37919/27601 37922/37922/27604 +f 37920/37920/27602 37922/37922/27604 37923/37923/27605 +f 37915/37915/27597 37920/37920/27602 37923/37923/27605 +f 37915/37915/27597 37923/37923/27605 37924/37924/27606 +f 37808/37808/27490 37915/37915/27597 37924/37924/27606 +f 37808/37808/27490 37924/37924/27606 37809/37809/27491 +f 37917/37917/27599 37916/37916/27598 37925/37925/27607 +f 37917/37917/27599 37925/37925/27607 37926/37926/27608 +f 37918/37918/27600 37917/37917/27599 37926/37926/27608 +f 37918/37918/27600 37926/37926/27608 37921/37921/27603 +f 37927/37927/27609 37928/37928/27607 37929/37929/27610 +f 37927/37927/27609 37929/37929/27610 37930/37930/27611 +f 37921/37921/27603 37926/37926/27608 37931/37931/27611 +f 37921/37921/27603 37931/37931/27611 37932/37932/27612 +f 37922/37922/27604 37921/37921/27603 37932/37932/27612 +f 37922/37922/27604 37932/37932/27612 37933/37933/27613 +f 37923/37923/27605 37922/37922/27604 37933/37933/27613 +f 37923/37923/27605 37933/37933/27613 37934/37934/27614 +f 37924/37924/27606 37923/37923/27605 37934/37934/27614 +f 37924/37924/27606 37934/37934/27614 37935/37935/27615 +f 37809/37809/27491 37924/37924/27606 37935/37935/27615 +f 37809/37809/27491 37935/37935/27615 37810/37810/27492 +f 37933/37933/27613 37932/37932/27612 37936/37936/27616 +f 37933/37933/27613 37936/37936/27616 37937/37937/27617 +f 37934/37934/27614 37933/37933/27613 37937/37937/27617 +f 37934/37934/27614 37937/37937/27617 37938/37938/27618 +f 37935/37935/27615 37934/37934/27614 37938/37938/27618 +f 37935/37935/27615 37938/37938/27618 37939/37939/27619 +f 37810/37810/27492 37935/37935/27615 37939/37939/27619 +f 37810/37810/27492 37939/37939/27619 37811/37811/27493 +f 37930/37930/27611 37929/37929/27610 37940/37940/27620 +f 37930/37930/27611 37940/37940/27620 37941/37941/27621 +f 37942/37942/27622 37930/37930/27611 37941/37941/27621 +f 37942/37942/27622 37941/37941/27621 37943/37943/27623 +f 37941/37941/27621 37940/37940/27620 37944/37944/27624 +f 37941/37941/27621 37944/37944/27624 37945/37945/27625 +f 37943/37943/27623 37941/37941/27621 37945/37945/27625 +f 37943/37943/27623 37945/37945/27625 37946/37946/27626 +f 37947/37947/27617 37943/37943/27623 37946/37946/27626 +f 37947/37947/27617 37946/37946/27626 37948/37948/27627 +f 37938/37938/27618 37937/37937/27617 37949/37949/27627 +f 37938/37938/27618 37949/37949/27627 37950/37950/27628 +f 37939/37939/27619 37938/37938/27618 37950/37950/27628 +f 37939/37939/27619 37950/37950/27628 37951/37951/27629 +f 37811/37811/27493 37939/37939/27619 37951/37951/27629 +f 37811/37811/27493 37951/37951/27629 37812/37812/27494 +f 37952/37952/27630 37948/37948/27627 37953/37953/27631 +f 37952/37952/27630 37953/37953/27631 37954/37954/27632 +f 37951/37951/27629 37950/37950/27628 37955/37955/27632 +f 37951/37951/27629 37955/37955/27632 37956/37956/27633 +f 37812/37812/27494 37951/37951/27629 37956/37956/27633 +f 37812/37812/27494 37956/37956/27633 37813/37813/27495 +f 37945/37945/27625 37944/37944/27624 37957/37957/27634 +f 37945/37945/27625 37957/37957/27634 37958/37958/27635 +f 37946/37946/27626 37945/37945/27625 37958/37958/27635 +f 37946/37946/27626 37958/37958/27635 37959/37959/27636 +f 37948/37948/27627 37946/37946/27626 37959/37959/27636 +f 37948/37948/27627 37959/37959/27636 37953/37953/27631 +f 37958/37958/27635 37957/37957/27634 37960/37960/27637 +f 37958/37958/27635 37960/37960/27637 37961/37961/27638 +f 37959/37959/27636 37958/37958/27635 37961/37961/27638 +f 37959/37959/27636 37961/37961/27638 37962/37962/27639 +f 37953/37953/27631 37959/37959/27636 37962/37962/27639 +f 37953/37953/27631 37962/37962/27639 37963/37963/27640 +f 37954/37954/27632 37953/37953/27631 37963/37963/27640 +f 37954/37954/27632 37963/37963/27640 37964/37964/27641 +f 37956/37956/27633 37955/37955/27632 37965/37965/27641 +f 37956/37956/27633 37965/37965/27641 37966/37966/27642 +f 37813/37813/27495 37956/37956/27633 37966/37966/27642 +f 37813/37813/27495 37966/37966/27642 37814/37814/27496 +f 37964/37964/27641 37963/37963/27640 37967/37967/27643 +f 37964/37964/27641 37967/37967/27643 37968/37968/27644 +f 37966/37966/27642 37965/37965/27641 37969/37969/27644 +f 37966/37966/27642 37969/37969/27644 37970/37970/27645 +f 37814/37814/27496 37966/37966/27642 37970/37970/27645 +f 37814/37814/27496 37970/37970/27645 37815/37815/27497 +f 37961/37961/27638 37960/37960/27637 37971/37971/27646 +f 37961/37961/27638 37971/37971/27646 37972/37972/27647 +f 37962/37962/27639 37961/37961/27638 37972/37972/27647 +f 37962/37962/27639 37972/37972/27647 37973/37973/27648 +f 37963/37963/27640 37962/37962/27639 37973/37973/27648 +f 37963/37963/27640 37973/37973/27648 37967/37967/27643 +f 37972/37972/27647 37971/37971/27646 37974/37974/27649 +f 37972/37972/27647 37974/37974/27649 37975/37975/27650 +f 37973/37973/27648 37972/37972/27647 37975/37975/27650 +f 37973/37973/27648 37975/37975/27650 37976/37976/27651 +f 37967/37967/27643 37973/37973/27648 37976/37976/27651 +f 37967/37967/27643 37976/37976/27651 37977/37977/27652 +f 37968/37968/27644 37967/37967/27643 37977/37977/27652 +f 37968/37968/27644 37977/37977/27652 37978/37978/27653 +f 37970/37970/27645 37969/37969/27644 37979/37979/27653 +f 37970/37970/27645 37979/37979/27653 37980/37980/27654 +f 37815/37815/27497 37970/37970/27645 37980/37980/27654 +f 37815/37815/27497 37980/37980/27654 37816/37816/27498 +f 37980/37980/27654 37979/37979/27653 37981/37981/27655 +f 37980/37980/27654 37981/37981/27655 37982/37982/27656 +f 37816/37816/27498 37980/37980/27654 37982/37982/27656 +f 37816/37816/27498 37982/37982/27656 37817/37817/27499 +f 37975/37975/27650 37974/37974/27649 37983/37983/27657 +f 37975/37975/27650 37983/37983/27657 37984/37984/27658 +f 37976/37976/27651 37975/37975/27650 37984/37984/27658 +f 37976/37976/27651 37984/37984/27658 37985/37985/27659 +f 37977/37977/27652 37976/37976/27651 37985/37985/27659 +f 37977/37977/27652 37985/37985/27659 37986/37986/27660 +f 37978/37978/27653 37977/37977/27652 37986/37986/27660 +f 37978/37978/27653 37986/37986/27660 37987/37987/27661 +f 37985/37985/27659 37984/37984/27658 37988/37988/27662 +f 37985/37985/27659 37988/37988/27662 37989/37989/27663 +f 37986/37986/27660 37985/37985/27659 37989/37989/27663 +f 37986/37986/27660 37989/37989/27663 37990/37990/27664 +f 37987/37987/27661 37986/37986/27660 37990/37990/27664 +f 37987/37987/27661 37990/37990/27664 37991/37991/27665 +f 37982/37982/27656 37981/37981/27655 37992/37992/27665 +f 37982/37982/27656 37992/37992/27665 37993/37993/27666 +f 37817/37817/27499 37982/37982/27656 37993/37993/27666 +f 37817/37817/27499 37993/37993/27666 37818/37818/27500 +f 37984/37984/27658 37983/37983/27657 37994/37994/27667 +f 37984/37984/27658 37994/37994/27667 37988/37988/27662 +f 37818/37818/27500 37993/37993/27666 37995/37995/27668 +f 37818/37818/27500 37995/37995/27668 37819/37819/27501 +f 37988/37988/27662 37994/37994/27667 37996/37996/27669 +f 37988/37988/27662 37996/37996/27669 37997/37997/27670 +f 37989/37989/27663 37988/37988/27662 37997/37997/27670 +f 37989/37989/27663 37997/37997/27670 37998/37998/27671 +f 37990/37990/27664 37989/37989/27663 37998/37998/27671 +f 37990/37990/27664 37998/37998/27671 37999/37999/27672 +f 37991/37991/27665 37990/37990/27664 37999/37999/27672 +f 37991/37991/27665 37999/37999/27672 38000/38000/27673 +f 37993/37993/27666 37992/37992/27665 38001/38001/27673 +f 37993/37993/27666 38001/38001/27673 37995/37995/27668 +f 37998/37998/27671 37997/37997/27670 38002/38002/27674 +f 37998/37998/27671 38002/38002/27674 38003/38003/27675 +f 37999/37999/27672 37998/37998/27671 38003/38003/27675 +f 37999/37999/27672 38003/38003/27675 38004/38004/27676 +f 38000/38000/27673 37999/37999/27672 38004/38004/27676 +f 38000/38000/27673 38004/38004/27676 38005/38005/27677 +f 37995/37995/27668 38001/38001/27673 38006/38006/27677 +f 37995/37995/27668 38006/38006/27677 38007/38007/27678 +f 37819/37819/27501 37995/37995/27668 38007/38007/27678 +f 37819/37819/27501 38007/38007/27678 37820/37820/27502 +f 37997/37997/27670 37996/37996/27669 38008/38008/27679 +f 37997/37997/27670 38008/38008/27679 38002/38002/27674 +f 37820/37820/27502 38007/38007/27678 38009/38009/27680 +f 37820/37820/27502 38009/38009/27680 37821/37821/27503 +f 38002/38002/27674 38008/38008/27679 38010/38010/27681 +f 38002/38002/27674 38010/38010/27681 38011/38011/27682 +f 38003/38003/27675 38002/38002/27674 38011/38011/27682 +f 38003/38003/27675 38011/38011/27682 38012/38012/27683 +f 38004/38004/27676 38003/38003/27675 38012/38012/27683 +f 38004/38004/27676 38012/38012/27683 38013/38013/27684 +f 38005/38005/27677 38004/38004/27676 38013/38013/27684 +f 38005/38005/27677 38013/38013/27684 38014/38014/27685 +f 38007/38007/27678 38006/38006/27677 38015/38015/27685 +f 38007/38007/27678 38015/38015/27685 38009/38009/27680 +f 38013/38013/27684 38012/38012/27683 38016/38016/27686 +f 38013/38013/27684 38016/38016/27686 38017/38017/27687 +f 38015/38015/27685 38018/38018/27684 38019/38019/27688 +f 38015/38015/27685 38019/38019/27688 38020/38020/27689 +f 38009/38009/27680 38015/38015/27685 38020/38020/27689 +f 38009/38009/27680 38020/38020/27689 38021/38021/27690 +f 37821/37821/27503 38009/38009/27680 38021/38021/27690 +f 37821/37821/27503 38021/38021/27690 37822/37822/27504 +f 38011/38011/27682 38010/38010/27681 38022/38022/27691 +f 38011/38011/27682 38022/38022/27691 38023/38023/27692 +f 38012/38012/27683 38011/38011/27682 38023/38023/27692 +f 38012/38012/27683 38023/38023/27692 38016/38016/27686 +f 38023/38023/27692 38022/38022/27691 38024/38024/27693 +f 38023/38023/27692 38024/38024/27693 38025/38025/27694 +f 38016/38016/27686 38023/38023/27692 38025/38025/27694 +f 38016/38016/27686 38025/38025/27694 38026/38026/27695 +f 38019/38019/27688 38027/38027/27686 38028/38028/27695 +f 38019/38019/27688 38028/38028/27695 38029/38029/27696 +f 38020/38020/27689 38019/38019/27688 38029/38029/27696 +f 38020/38020/27689 38029/38029/27696 38030/38030/27697 +f 38021/38021/27690 38020/38020/27689 38030/38030/27697 +f 38021/38021/27690 38030/38030/27697 38031/38031/27698 +f 37822/37822/27504 38021/38021/27690 38031/38031/27698 +f 37822/37822/27504 38031/38031/27698 37823/37823/27505 +f 38029/38029/27696 38028/38028/27695 38032/38032/27699 +f 38029/38029/27696 38032/38032/27699 38033/38033/27700 +f 38030/38030/27697 38029/38029/27696 38033/38033/27700 +f 38030/38030/27697 38033/38033/27700 38034/38034/27701 +f 38031/38031/27698 38030/38030/27697 38034/38034/27701 +f 38031/38031/27698 38034/38034/27701 38035/38035/27702 +f 37823/37823/27505 38031/38031/27698 38035/38035/27702 +f 37823/37823/27505 38035/38035/27702 37824/37824/27506 +f 38025/38025/27694 38024/38024/27693 38036/38036/27703 +f 38025/38025/27694 38036/38036/27703 38037/38037/27704 +f 38028/38028/27695 38038/38038/27694 38039/38039/27705 +f 38028/38028/27695 38039/38039/27705 38032/38032/27699 +f 38039/38039/27705 38040/38040/27703 37826/37826/27508 +f 38039/38039/27705 37826/37826/27508 37825/37825/27507 +f 38032/38032/27699 38039/38039/27705 37825/37825/27507 +f 38032/38032/27699 37825/37825/27507 37829/37829/27511 +f 38033/38033/27700 38032/38032/27699 37829/37829/27511 +f 38033/38033/27700 37829/37829/27511 37831/37831/27513 +f 38034/38034/27701 38033/38033/27700 37831/37831/27513 +f 38034/38034/27701 37831/37831/27513 37833/37833/27515 +f 38035/38035/27702 38034/38034/27701 37833/37833/27515 +f 38035/38035/27702 37833/37833/27515 37835/37835/27517 +f 37824/37824/27506 38035/38035/27702 37835/37835/27517 +f 37824/37824/27506 37835/37835/27517 37793/37793/27475 +o Sphere.015__0 +v -0.531227 -0.984910 -1.013809 +v -0.531227 -0.976372 -1.013966 +v -0.529576 -0.976535 -1.013956 +v -0.527988 -0.977019 -1.013924 +v -0.526525 -0.977806 -1.013873 +v -0.525243 -0.978865 -1.013805 +v -0.524190 -0.980155 -1.013721 +v -0.523408 -0.981626 -1.013626 +v -0.522926 -0.983223 -1.013522 +v -0.522764 -0.984884 -1.013414 +v -0.522926 -0.986545 -1.013306 +v -0.523408 -0.988142 -1.013203 +v -0.524190 -0.989614 -1.013107 +v -0.525243 -0.990904 -1.013023 +v -0.526525 -0.991962 -1.012955 +v -0.527988 -0.992749 -1.012904 +v -0.529576 -0.993233 -1.012872 +v -0.531227 -0.993397 -1.012862 +v -0.532878 -0.993233 -1.012872 +v -0.534465 -0.992749 -1.012904 +v -0.535928 -0.991962 -1.012955 +v -0.537211 -0.990904 -1.013023 +v -0.538263 -0.989614 -1.013107 +v -0.539046 -0.988142 -1.013203 +v -0.539527 -0.986545 -1.013306 +v -0.539690 -0.984884 -1.013414 +v -0.539527 -0.983223 -1.013522 +v -0.539046 -0.981626 -1.013626 +v -0.538263 -0.980155 -1.013721 +v -0.537211 -0.978865 -1.013805 +v -0.535928 -0.977806 -1.013873 +v -0.534465 -0.977019 -1.013924 +v -0.532878 -0.976535 -1.013956 +v -0.531227 -0.943774 -1.003738 +v -0.531227 -0.941040 -1.000043 +v -0.522926 -0.941863 -0.999990 +v -0.523408 -0.944548 -1.003688 +v -0.531227 -0.948036 -1.007029 +v -0.524190 -0.948733 -1.006984 +v -0.531227 -0.953665 -1.009791 +v -0.525243 -0.954258 -1.009753 +v -0.531227 -0.960443 -1.011918 +v -0.526525 -0.960909 -1.011888 +v -0.531227 -0.968110 -1.013328 +v -0.527988 -0.968431 -1.013307 +v -0.524874 -0.969381 -1.013245 +v -0.514945 -0.944298 -0.999832 +v -0.515890 -0.946842 -1.003539 +v -0.517424 -0.950798 -1.006850 +v -0.519488 -0.956013 -1.009639 +v -0.522004 -0.962288 -1.011799 +v -0.508961 -0.950567 -1.003297 +v -0.511188 -0.954151 -1.006632 +v -0.514185 -0.958865 -1.009454 +v -0.517838 -0.964528 -1.011653 +v -0.522004 -0.970924 -1.013145 +v -0.507590 -0.948253 -0.999575 +v -0.519488 -0.973001 -1.013011 +v -0.501143 -0.953575 -0.999230 +v -0.502888 -0.955581 -1.002972 +v -0.505723 -0.958663 -1.006340 +v -0.509537 -0.962702 -1.009205 +v -0.514185 -0.967543 -1.011458 +v -0.501237 -0.964160 -1.005983 +v -0.505723 -0.967377 -1.008901 +v -0.511188 -0.971217 -1.011219 +v -0.517424 -0.975531 -1.012846 +v -0.495851 -0.960060 -0.998809 +v -0.497904 -0.961690 -1.002575 +v -0.491920 -0.967459 -0.998329 +v -0.494200 -0.968659 -1.002123 +v -0.497904 -0.970433 -1.005576 +v -0.502888 -0.972712 -1.008556 +v -0.508961 -0.975408 -1.010947 +v -0.515890 -0.978418 -1.012659 +v -0.501143 -0.978500 -1.008180 +v -0.507590 -0.979955 -1.010652 +v -0.514945 -0.981550 -1.012456 +v -0.489499 -0.975487 -0.997808 +v -0.491920 -0.976222 -1.001632 +v -0.495851 -0.977239 -1.005134 +v -0.488681 -0.983836 -0.997266 +v -0.491150 -0.984087 -1.001122 +v -0.495158 -0.984317 -1.004675 +v -0.500553 -0.984519 -1.007789 +v -0.507127 -0.984685 -1.010345 +v -0.514626 -0.984808 -1.012244 +v -0.501143 -0.990539 -1.007399 +v -0.507590 -0.989414 -1.010038 +v -0.514945 -0.988066 -1.012033 +v -0.489499 -0.992186 -0.996725 +v -0.491920 -0.991951 -1.000612 +v -0.495851 -0.991395 -1.004216 +v -0.491920 -1.000214 -0.996204 +v -0.494200 -0.999514 -1.000121 +v -0.497904 -0.998201 -1.003774 +v -0.502888 -0.996327 -1.007023 +v -0.508961 -0.993962 -1.009743 +v -0.515890 -0.991198 -1.011830 +v -0.511188 -0.998153 -1.009471 +v -0.517424 -0.994085 -1.011642 +v -0.495851 -1.007613 -0.995724 +v -0.497904 -1.006483 -0.999668 +v -0.501237 -1.004474 -1.003367 +v -0.505723 -1.001661 -1.006677 +v -0.501143 -1.014098 -0.995303 +v -0.502888 -1.012592 -0.999272 +v -0.505723 -1.009971 -1.003010 +v -0.509537 -1.006336 -1.006374 +v -0.514185 -1.001827 -1.009233 +v -0.519488 -0.996616 -1.011478 +v -0.517838 -1.004842 -1.009037 +v -0.522004 -0.998692 -1.011343 +v -0.507590 -1.019420 -0.994957 +v -0.508961 -1.017606 -0.998947 +v -0.511188 -1.014483 -1.002718 +v -0.514185 -1.010174 -1.006125 +v -0.515890 -1.021331 -0.998705 +v -0.517424 -1.017836 -1.002500 +v -0.519488 -1.013025 -1.005940 +v -0.522004 -1.007082 -1.008892 +v -0.524874 -1.000236 -1.011243 +v -0.514945 -1.023375 -0.994701 +v -0.527988 -1.001186 -1.011182 +v -0.522927 -1.025810 -0.994543 +v -0.523408 -1.023625 -0.998556 +v -0.524190 -1.019901 -1.002366 +v -0.525243 -1.014781 -1.005826 +v -0.526525 -1.008461 -1.008803 +v -0.531227 -1.020598 -1.002321 +v -0.531227 -1.015374 -1.005787 +v -0.531227 -1.008927 -1.008772 +v -0.531227 -1.001507 -1.011161 +v -0.531227 -1.026633 -0.994490 +v -0.531227 -1.024400 -0.998506 +v -0.531227 -1.024400 -0.998506 +v -0.531227 -1.026633 -0.994490 +v -0.539527 -1.025810 -0.994543 +v -0.539046 -1.023625 -0.998556 +v -0.539046 -1.023625 -0.998556 +v -0.538263 -1.019901 -1.002366 +v -0.537211 -1.014781 -1.005826 +v -0.535928 -1.008461 -1.008803 +v -0.534465 -1.001186 -1.011182 +v -0.545030 -1.017836 -1.002500 +v -0.542965 -1.013025 -1.005940 +v -0.540450 -1.007082 -1.008892 +v -0.537579 -1.000235 -1.011243 +v -0.547508 -1.023375 -0.994701 +v -0.546564 -1.021331 -0.998705 +v -0.538263 -1.019901 -1.002366 +v -0.545030 -1.017836 -1.002500 +v -0.554864 -1.019420 -0.994957 +v -0.553493 -1.017606 -0.998947 +v -0.551265 -1.014483 -1.002718 +v -0.542965 -1.013025 -1.005940 +v -0.548268 -1.010174 -1.006125 +v -0.548268 -1.010174 -1.006125 +v -0.544616 -1.004842 -1.009037 +v -0.540450 -0.998692 -1.011343 +v -0.544616 -1.004842 -1.009037 +v -0.552916 -1.006336 -1.006374 +v -0.548268 -1.001827 -1.009233 +v -0.548268 -1.001827 -1.009233 +v -0.542965 -0.996616 -1.011478 +v -0.561311 -1.014098 -0.995303 +v -0.559566 -1.012592 -0.999272 +v -0.556731 -1.009971 -1.003010 +v -0.566602 -1.007613 -0.995724 +v -0.564549 -1.006483 -0.999668 +v -0.561217 -1.004474 -1.003367 +v -0.556731 -1.001661 -1.006677 +v -0.551265 -0.998153 -1.009471 +v -0.551265 -0.998153 -1.009471 +v -0.545030 -0.994085 -1.011642 +v -0.559566 -0.996327 -1.007023 +v -0.553493 -0.993962 -1.009743 +v -0.553493 -0.993962 -1.009743 +v -0.546564 -0.991198 -1.011830 +v -0.570534 -1.000214 -0.996204 +v -0.568253 -0.999514 -1.000121 +v -0.564549 -0.998201 -1.003774 +v -0.572955 -0.992186 -0.996725 +v -0.570534 -0.991951 -1.000612 +v -0.566602 -0.991395 -1.004216 +v -0.561311 -0.990539 -1.007399 +v -0.554864 -0.989414 -1.010038 +v -0.554864 -0.989414 -1.010038 +v -0.547508 -0.988066 -1.012033 +v -0.555327 -0.984685 -1.010345 +v -0.547827 -0.984808 -1.012244 +v -0.573772 -0.983836 -0.997266 +v -0.571304 -0.984087 -1.001122 +v -0.567295 -0.984317 -1.004675 +v -0.561901 -0.984519 -1.007789 +v -0.555327 -0.984685 -1.010345 +v -0.570534 -0.976222 -1.001632 +v -0.566602 -0.977239 -1.005134 +v -0.561311 -0.978500 -1.008180 +v -0.554864 -0.979955 -1.010652 +v -0.554864 -0.979955 -1.010652 +v -0.547508 -0.981550 -1.012456 +v -0.572955 -0.975487 -0.997808 +v -0.546564 -0.978418 -1.012659 +v -0.570534 -0.967459 -0.998329 +v -0.568253 -0.968659 -1.002123 +v -0.564549 -0.970433 -1.005576 +v -0.559566 -0.972712 -1.008556 +v -0.553493 -0.975408 -1.010947 +v -0.553493 -0.975408 -1.010947 +v -0.564549 -0.961690 -1.002575 +v -0.561217 -0.964160 -1.005983 +v -0.556731 -0.967377 -1.008901 +v -0.551265 -0.971217 -1.011219 +v -0.551265 -0.971217 -1.011219 +v -0.545030 -0.975531 -1.012846 +v -0.566602 -0.960060 -0.998809 +v -0.542965 -0.973001 -1.013011 +v -0.561311 -0.953575 -0.999230 +v -0.559566 -0.955581 -1.002972 +v -0.556731 -0.958663 -1.006340 +v -0.552916 -0.962702 -1.009205 +v -0.548268 -0.967543 -1.011458 +v -0.548268 -0.967543 -1.011458 +v -0.551265 -0.954151 -1.006632 +v -0.548268 -0.958865 -1.009454 +v -0.552916 -0.962702 -1.009205 +v -0.548268 -0.958865 -1.009454 +v -0.544616 -0.964528 -1.011653 +v -0.540450 -0.970924 -1.013145 +v -0.554864 -0.948253 -0.999575 +v -0.553493 -0.950567 -1.003297 +v -0.547508 -0.944298 -0.999832 +v -0.546564 -0.946842 -1.003539 +v -0.545030 -0.950798 -1.006850 +v -0.551265 -0.954151 -1.006632 +v -0.545030 -0.950798 -1.006850 +v -0.542965 -0.956013 -1.009639 +v -0.540450 -0.962288 -1.011799 +v -0.537579 -0.969381 -1.013245 +v -0.538263 -0.948733 -1.006984 +v -0.537211 -0.954258 -1.009753 +v -0.535928 -0.960909 -1.011888 +v -0.534465 -0.968431 -1.013307 +v -0.539527 -0.941863 -0.999990 +v -0.539046 -0.944548 -1.003688 +v -0.546564 -0.946842 -1.003539 +v -0.539046 -0.944548 -1.003688 +v -0.539527 -0.941863 -0.999990 +vt 0.670172 0.241096 +vt 0.670232 0.240467 +vt 0.670112 0.240467 +vt 0.669994 0.240491 +vt 0.669883 0.240539 +vt 0.669782 0.240607 +vt 0.669697 0.240695 +vt 0.669629 0.240797 +vt 0.669582 0.240912 +vt 0.669557 0.241033 +vt 0.669556 0.241156 +vt 0.669578 0.241277 +vt 0.669623 0.241392 +vt 0.669688 0.241494 +vt 0.669772 0.241582 +vt 0.669871 0.241650 +vt 0.669982 0.241697 +vt 0.670099 0.241722 +vt 0.670219 0.241722 +vt 0.670337 0.241697 +vt 0.670448 0.241650 +vt 0.670549 0.241582 +vt 0.670635 0.241494 +vt 0.670702 0.241392 +vt 0.670750 0.241277 +vt 0.670774 0.241156 +vt 0.670775 0.241033 +vt 0.670753 0.240912 +vt 0.670709 0.240797 +vt 0.670643 0.240695 +vt 0.670559 0.240607 +vt 0.670460 0.240539 +vt 0.670350 0.240491 +vt 0.670290 0.238086 +vt 0.670250 0.237891 +vt 0.669647 0.237891 +vt 0.669722 0.238086 +vt 0.670314 0.238394 +vt 0.669802 0.238394 +vt 0.670320 0.238804 +vt 0.669885 0.238804 +vt 0.670308 0.239299 +vt 0.669966 0.239299 +vt 0.670278 0.239861 +vt 0.670043 0.239861 +vt 0.669811 0.239908 +vt 0.669054 0.238012 +vt 0.669163 0.238200 +vt 0.669300 0.238497 +vt 0.669457 0.238891 +vt 0.669630 0.239367 +vt 0.668636 0.238424 +vt 0.668825 0.238698 +vt 0.669054 0.239062 +vt 0.669313 0.239502 +vt 0.669593 0.240001 +vt 0.668494 0.238249 +vt 0.669396 0.240135 +vt 0.667989 0.238594 +vt 0.668160 0.238749 +vt 0.668397 0.238991 +vt 0.668689 0.239311 +vt 0.669027 0.239698 +vt 0.668031 0.239363 +vt 0.668379 0.239628 +vt 0.668782 0.239946 +vt 0.669228 0.240307 +vt 0.667557 0.239034 +vt 0.667754 0.239162 +vt 0.667217 0.239550 +vt 0.667433 0.239649 +vt 0.667743 0.239801 +vt 0.668133 0.240000 +vt 0.668590 0.240239 +vt 0.669095 0.240508 +vt 0.667962 0.240414 +vt 0.668455 0.240564 +vt 0.669002 0.240732 +vt 0.666980 0.240124 +vt 0.667210 0.240189 +vt 0.667542 0.240287 +vt 0.666856 0.240733 +vt 0.667093 0.240763 +vt 0.667437 0.240804 +vt 0.667873 0.240853 +vt 0.668385 0.240909 +vt 0.668954 0.240970 +vt 0.667868 0.241301 +vt 0.668381 0.241261 +vt 0.668951 0.241212 +vt 0.666849 0.241354 +vt 0.667087 0.241348 +vt 0.667431 0.241330 +vt 0.666961 0.241963 +vt 0.667192 0.241922 +vt 0.667525 0.241847 +vt 0.667948 0.241740 +vt 0.668444 0.241606 +vt 0.668995 0.241450 +vt 0.668572 0.241931 +vt 0.669082 0.241673 +vt 0.667186 0.242537 +vt 0.667404 0.242462 +vt 0.667716 0.242333 +vt 0.668110 0.242153 +vt 0.667515 0.243053 +vt 0.667714 0.242949 +vt 0.667996 0.242771 +vt 0.668348 0.242526 +vt 0.668759 0.242223 +vt 0.669211 0.241875 +vt 0.668998 0.242472 +vt 0.669376 0.242046 +vt 0.667937 0.243492 +vt 0.668112 0.243363 +vt 0.668353 0.243143 +vt 0.668652 0.242842 +vt 0.668581 0.243688 +vt 0.668776 0.243436 +vt 0.669012 0.243091 +vt 0.669280 0.242667 +vt 0.669570 0.242181 +vt 0.668435 0.243838 +vt 0.669787 0.242274 +vt 0.668990 0.244075 +vt 0.669104 0.243912 +vt 0.669246 0.243637 +vt 0.669412 0.243262 +vt 0.669594 0.242802 +vt 0.669747 0.243740 +vt 0.669837 0.243350 +vt 0.669929 0.242871 +vt 0.670017 0.242321 +vt 0.669581 0.244196 +vt 0.669660 0.244026 +vt 0.951053 0.732576 +vt 0.950847 0.732393 +vt 0.950401 0.732513 +vt 0.950633 0.732689 +vt 0.670228 0.244026 +vt 0.670258 0.243740 +vt 0.670272 0.243350 +vt 0.670270 0.242871 +vt 0.670252 0.242321 +vt 0.670761 0.243637 +vt 0.670700 0.243262 +vt 0.670606 0.242802 +vt 0.670484 0.242274 +vt 0.949980 0.732750 +vt 0.950237 0.732912 +vt 0.950874 0.732975 +vt 0.950518 0.733176 +vt 0.949602 0.733095 +vt 0.949881 0.733237 +vt 0.950197 0.733468 +vt 0.950813 0.733531 +vt 0.950540 0.733779 +vt 0.671103 0.243091 +vt 0.670923 0.242667 +vt 0.670702 0.242181 +vt 0.950895 0.734159 +vt 0.950308 0.734096 +vt 0.950713 0.734407 +vt 0.671209 0.242472 +vt 0.670899 0.242046 +vt 0.949281 0.733534 +vt 0.949578 0.733650 +vt 0.949925 0.733840 +vt 0.949028 0.734050 +vt 0.949340 0.734137 +vt 0.949710 0.734278 +vt 0.950126 0.734468 +vt 0.950570 0.734700 +vt 0.671454 0.242223 +vt 0.671068 0.241875 +vt 0.950000 0.734882 +vt 0.950471 0.735025 +vt 0.671647 0.241931 +vt 0.671200 0.241673 +vt 0.948854 0.734624 +vt 0.949176 0.734677 +vt 0.949563 0.734765 +vt 0.948765 0.735233 +vt 0.949092 0.735252 +vt 0.949488 0.735281 +vt 0.949936 0.735321 +vt 0.950421 0.735370 +vt 0.671781 0.241606 +vt 0.671293 0.241450 +vt 0.671851 0.241261 +vt 0.671341 0.241212 +vt 0.948765 0.735855 +vt 0.949092 0.735837 +vt 0.949488 0.735808 +vt 0.949936 0.735770 +vt 0.950421 0.735722 +vt 0.949176 0.736412 +vt 0.949563 0.736325 +vt 0.950000 0.736209 +vt 0.950471 0.736068 +vt 0.671855 0.240909 +vt 0.671344 0.240970 +vt 0.948854 0.736465 +vt 0.671300 0.240732 +vt 0.949028 0.737040 +vt 0.949340 0.736953 +vt 0.949710 0.736813 +vt 0.950126 0.736624 +vt 0.950570 0.736393 +vt 0.671792 0.240564 +vt 0.949578 0.737440 +vt 0.949925 0.737251 +vt 0.950308 0.736997 +vt 0.950713 0.736686 +vt 0.671664 0.240239 +vt 0.671213 0.240508 +vt 0.949281 0.737557 +vt 0.671084 0.240307 +vt 0.949602 0.737997 +vt 0.949881 0.737855 +vt 0.950197 0.737624 +vt 0.950540 0.737314 +vt 0.950895 0.736936 +vt 0.671477 0.239946 +vt 0.950518 0.737918 +vt 0.950813 0.737563 +vt 0.671809 0.239628 +vt 0.671504 0.239311 +vt 0.671238 0.239698 +vt 0.670919 0.240135 +vt 0.949980 0.738343 +vt 0.950237 0.738181 +vt 0.950401 0.738582 +vt 0.950633 0.738406 +vt 0.950874 0.738120 +vt 0.671707 0.238991 +vt 0.671285 0.238698 +vt 0.671145 0.239062 +vt 0.670956 0.239502 +vt 0.670725 0.240001 +vt 0.670814 0.238497 +vt 0.670745 0.238891 +vt 0.670642 0.239367 +vt 0.670508 0.239908 +vt 0.950847 0.738704 +vt 0.951053 0.738521 +vt 0.671369 0.238424 +vt 0.670846 0.238200 +vt 0.670840 0.238012 +vn -0.0000 -0.0647 -0.9979 +vn -0.0000 0.0323 -0.9995 +vn 0.0191 0.0305 -0.9994 +vn 0.0374 0.0249 -0.9990 +vn 0.0544 0.0160 -0.9984 +vn 0.0691 0.0039 -0.9976 +vn 0.0812 -0.0107 -0.9966 +vn 0.0902 -0.0274 -0.9955 +vn 0.0958 -0.0456 -0.9944 +vn 0.0977 -0.0644 -0.9931 +vn 0.0958 -0.0833 -0.9919 +vn 0.0903 -0.1014 -0.9907 +vn 0.0813 -0.1181 -0.9897 +vn 0.0691 -0.1328 -0.9887 +vn 0.0544 -0.1449 -0.9880 +vn 0.0374 -0.1538 -0.9874 +vn 0.0190 -0.1594 -0.9870 +vn -0.0000 -0.1612 -0.9869 +vn -0.0190 -0.1594 -0.9870 +vn -0.0374 -0.1538 -0.9874 +vn -0.0543 -0.1449 -0.9880 +vn -0.0691 -0.1328 -0.9887 +vn -0.0813 -0.1181 -0.9897 +vn -0.0903 -0.1014 -0.9907 +vn -0.0958 -0.0833 -0.9919 +vn -0.0977 -0.0644 -0.9931 +vn -0.0958 -0.0456 -0.9944 +vn -0.0902 -0.0274 -0.9955 +vn -0.0812 -0.0107 -0.9966 +vn -0.0691 0.0039 -0.9976 +vn -0.0544 0.0160 -0.9984 +vn -0.0374 0.0249 -0.9990 +vn -0.0190 0.0305 -0.9994 +vn -0.0000 0.7182 -0.6958 +vn -0.0000 0.8039 -0.5947 +vn 0.1652 0.7876 -0.5936 +vn 0.1498 0.7035 -0.6947 +vn -0.0000 0.5329 -0.8462 +vn 0.1153 0.5216 -0.8454 +vn -0.0000 0.3750 -0.9270 +vn 0.0854 0.3667 -0.9264 +vn -0.0000 0.2441 -0.9697 +vn 0.0603 0.2382 -0.9693 +vn -0.0000 0.1323 -0.9912 +vn 0.0386 0.1285 -0.9910 +vn 0.0757 0.1174 -0.9902 +vn 0.3239 0.7395 -0.5901 +vn 0.2936 0.6599 -0.6916 +vn 0.2262 0.4881 -0.8430 +vn 0.1675 0.3420 -0.9247 +vn 0.1182 0.2208 -0.9681 +vn 0.4259 0.5892 -0.6866 +vn 0.3282 0.4338 -0.8391 +vn 0.2431 0.3018 -0.9218 +vn 0.1716 0.1925 -0.9662 +vn 0.1099 0.0993 -0.9890 +vn 0.4698 0.6615 -0.5846 +vn 0.1398 0.0749 -0.9873 +vn 0.5974 0.5568 -0.5772 +vn 0.5416 0.4944 -0.6799 +vn 0.4174 0.3609 -0.8340 +vn 0.3093 0.2479 -0.9181 +vn 0.2183 0.1545 -0.9636 +vn 0.4906 0.2722 -0.8278 +vn 0.3636 0.1822 -0.9136 +vn 0.2566 0.1081 -0.9604 +vn 0.1644 0.0452 -0.9854 +vn 0.7017 0.4296 -0.5683 +vn 0.6363 0.3791 -0.6718 +vn 0.7791 0.2848 -0.5585 +vn 0.7065 0.2479 -0.6629 +vn 0.5448 0.1711 -0.8209 +vn 0.4038 0.1073 -0.9085 +vn 0.2851 0.0553 -0.9569 +vn 0.1826 0.0114 -0.9831 +vn 0.4286 0.0261 -0.9031 +vn 0.3026 -0.0020 -0.9531 +vn 0.1939 -0.0253 -0.9807 +vn 0.8267 0.1280 -0.5479 +vn 0.7496 0.1059 -0.6533 +vn 0.5782 0.0615 -0.8136 +vn 0.8427 -0.0349 -0.5373 +vn 0.7642 -0.0418 -0.6437 +vn 0.5895 -0.0523 -0.8061 +vn 0.4370 -0.0582 -0.8976 +vn 0.3085 -0.0616 -0.9492 +vn 0.1977 -0.0635 -0.9782 +vn 0.4286 -0.1426 -0.8922 +vn 0.3026 -0.1212 -0.9454 +vn 0.1939 -0.1016 -0.9757 +vn 0.8267 -0.1978 -0.5268 +vn 0.7496 -0.1894 -0.6342 +vn 0.5782 -0.1662 -0.7988 +vn 0.7791 -0.3546 -0.5170 +vn 0.7065 -0.3315 -0.6253 +vn 0.5448 -0.2757 -0.7919 +vn 0.4038 -0.2238 -0.8870 +vn 0.2851 -0.1785 -0.9417 +vn 0.1826 -0.1383 -0.9734 +vn 0.2566 -0.2313 -0.9384 +vn 0.1644 -0.1722 -0.9712 +vn 0.7017 -0.4994 -0.5081 +vn 0.6363 -0.4628 -0.6172 +vn 0.4906 -0.3769 -0.7857 +vn 0.3635 -0.2987 -0.8824 +vn 0.5973 -0.6267 -0.5004 +vn 0.5416 -0.5781 -0.6103 +vn 0.4174 -0.4656 -0.7803 +vn 0.3093 -0.3644 -0.8784 +vn 0.2183 -0.2777 -0.9355 +vn 0.1398 -0.2019 -0.9694 +vn 0.1715 -0.3158 -0.9332 +vn 0.1099 -0.2263 -0.9678 +vn 0.4698 -0.7315 -0.4942 +vn 0.4259 -0.6730 -0.6046 +vn 0.3282 -0.5386 -0.7760 +vn 0.2431 -0.4184 -0.8751 +vn 0.2936 -0.7437 -0.6005 +vn 0.2261 -0.5929 -0.7728 +vn 0.1675 -0.4586 -0.8727 +vn 0.1182 -0.3441 -0.9315 +vn 0.0757 -0.2444 -0.9667 +vn 0.3239 -0.8096 -0.4896 +vn 0.0386 -0.2555 -0.9660 +vn 0.1652 -0.8577 -0.4868 +vn 0.1498 -0.7874 -0.5980 +vn 0.1153 -0.6264 -0.7709 +vn 0.0854 -0.4833 -0.8713 +vn 0.0603 -0.3615 -0.9304 +vn 0.0000 -0.6378 -0.7702 +vn -0.0000 -0.4917 -0.8708 +vn -0.0000 -0.3674 -0.9301 +vn -0.0000 -0.2593 -0.9658 +vn 0.0000 -0.8740 -0.4859 +vn -0.0000 -0.8021 -0.5971 +vn -0.0000 -0.8021 -0.5972 +vn -0.1652 -0.8577 -0.4868 +vn -0.1498 -0.7874 -0.5980 +vn -0.1154 -0.6265 -0.7709 +vn -0.0854 -0.4833 -0.8713 +vn -0.0603 -0.3615 -0.9304 +vn -0.0386 -0.2555 -0.9660 +vn -0.2262 -0.5929 -0.7728 +vn -0.1675 -0.4586 -0.8727 +vn -0.1182 -0.3441 -0.9315 +vn -0.0757 -0.2444 -0.9667 +vn -0.3239 -0.8096 -0.4896 +vn -0.2936 -0.7437 -0.6005 +vn -0.1153 -0.6264 -0.7709 +vn -0.2261 -0.5929 -0.7728 +vn -0.4698 -0.7315 -0.4942 +vn -0.4259 -0.6730 -0.6046 +vn -0.3282 -0.5386 -0.7760 +vn -0.2431 -0.4184 -0.8751 +vn -0.1715 -0.3157 -0.9332 +vn -0.1099 -0.2263 -0.9678 +vn -0.1716 -0.3158 -0.9332 +vn -0.3093 -0.3645 -0.8784 +vn -0.2183 -0.2777 -0.9355 +vn -0.2183 -0.2776 -0.9356 +vn -0.1398 -0.2019 -0.9694 +vn -0.5973 -0.6267 -0.5004 +vn -0.5416 -0.5781 -0.6103 +vn -0.4174 -0.4656 -0.7803 +vn -0.7017 -0.4994 -0.5081 +vn -0.6363 -0.4628 -0.6172 +vn -0.4906 -0.3769 -0.7857 +vn -0.3636 -0.2987 -0.8824 +vn -0.2566 -0.2313 -0.9384 +vn -0.1644 -0.1722 -0.9712 +vn -0.4038 -0.2239 -0.8870 +vn -0.2851 -0.1785 -0.9417 +vn -0.2850 -0.1785 -0.9417 +vn -0.1826 -0.1383 -0.9734 +vn -0.7791 -0.3546 -0.5170 +vn -0.7065 -0.3315 -0.6253 +vn -0.5448 -0.2758 -0.7919 +vn -0.8267 -0.1978 -0.5268 +vn -0.7496 -0.1894 -0.6342 +vn -0.5782 -0.1662 -0.7988 +vn -0.4286 -0.1426 -0.8921 +vn -0.3027 -0.1212 -0.9454 +vn -0.3026 -0.1212 -0.9454 +vn -0.1939 -0.1016 -0.9757 +vn -0.3085 -0.0616 -0.9492 +vn -0.1977 -0.0635 -0.9782 +vn -0.8427 -0.0348 -0.5373 +vn -0.7642 -0.0418 -0.6437 +vn -0.5895 -0.0523 -0.8061 +vn -0.4370 -0.0582 -0.8976 +vn -0.7496 0.1058 -0.6534 +vn -0.5782 0.0616 -0.8136 +vn -0.4286 0.0262 -0.9031 +vn -0.3026 -0.0020 -0.9531 +vn -0.1939 -0.0253 -0.9807 +vn -0.8267 0.1280 -0.5479 +vn -0.1826 0.0114 -0.9831 +vn -0.7791 0.2848 -0.5585 +vn -0.7065 0.2480 -0.6629 +vn -0.5448 0.1711 -0.8209 +vn -0.4038 0.1073 -0.9085 +vn -0.2851 0.0553 -0.9569 +vn -0.6363 0.3791 -0.6719 +vn -0.4906 0.2722 -0.8278 +vn -0.3635 0.1822 -0.9136 +vn -0.2567 0.1082 -0.9604 +vn -0.2566 0.1081 -0.9605 +vn -0.1644 0.0452 -0.9854 +vn -0.7017 0.4296 -0.5684 +vn -0.1398 0.0749 -0.9873 +vn -0.5974 0.5568 -0.5772 +vn -0.5416 0.4944 -0.6799 +vn -0.4174 0.3609 -0.8340 +vn -0.3093 0.2479 -0.9181 +vn -0.2183 0.1545 -0.9636 +vn -0.2183 0.1544 -0.9636 +vn -0.3282 0.4338 -0.8391 +vn -0.2431 0.3018 -0.9219 +vn -0.1716 0.1925 -0.9662 +vn -0.1099 0.0993 -0.9890 +vn -0.4698 0.6615 -0.5846 +vn -0.4259 0.5893 -0.6866 +vn -0.3239 0.7395 -0.5901 +vn -0.2936 0.6599 -0.6916 +vn -0.2261 0.4881 -0.8430 +vn -0.1675 0.3420 -0.9247 +vn -0.1182 0.2208 -0.9681 +vn -0.0757 0.1174 -0.9902 +vn -0.1153 0.5216 -0.8454 +vn -0.0854 0.3667 -0.9264 +vn -0.0603 0.2382 -0.9693 +vn -0.0386 0.1285 -0.9910 +vn -0.1652 0.7876 -0.5936 +vn -0.1497 0.7035 -0.6947 +usemtl Scene_-_Root +s 1 +f 38041/38041/27706 38042/38042/27707 38043/38043/27708 +f 38041/38041/27706 38043/38043/27708 38044/38044/27709 +f 38041/38041/27706 38044/38044/27709 38045/38045/27710 +f 38041/38041/27706 38045/38045/27710 38046/38046/27711 +f 38041/38041/27706 38046/38046/27711 38047/38047/27712 +f 38041/38041/27706 38047/38047/27712 38048/38048/27713 +f 38041/38041/27706 38048/38048/27713 38049/38049/27714 +f 38041/38041/27706 38049/38049/27714 38050/38050/27715 +f 38041/38041/27706 38050/38050/27715 38051/38051/27716 +f 38041/38041/27706 38051/38051/27716 38052/38052/27717 +f 38041/38041/27706 38052/38052/27717 38053/38053/27718 +f 38041/38041/27706 38053/38053/27718 38054/38054/27719 +f 38041/38041/27706 38054/38054/27719 38055/38055/27720 +f 38041/38041/27706 38055/38055/27720 38056/38056/27721 +f 38041/38041/27706 38056/38056/27721 38057/38057/27722 +f 38041/38041/27706 38057/38057/27722 38058/38058/27723 +f 38041/38041/27706 38058/38058/27723 38059/38059/27724 +f 38041/38041/27706 38059/38059/27724 38060/38060/27725 +f 38041/38041/27706 38060/38060/27725 38061/38061/27726 +f 38041/38041/27706 38061/38061/27726 38062/38062/27727 +f 38041/38041/27706 38062/38062/27727 38063/38063/27728 +f 38041/38041/27706 38063/38063/27728 38064/38064/27729 +f 38041/38041/27706 38064/38064/27729 38065/38065/27730 +f 38041/38041/27706 38065/38065/27730 38066/38066/27731 +f 38041/38041/27706 38066/38066/27731 38067/38067/27732 +f 38041/38041/27706 38067/38067/27732 38068/38068/27733 +f 38041/38041/27706 38068/38068/27733 38069/38069/27734 +f 38041/38041/27706 38069/38069/27734 38070/38070/27735 +f 38041/38041/27706 38070/38070/27735 38071/38071/27736 +f 38041/38041/27706 38071/38071/27736 38072/38072/27737 +f 38041/38041/27706 38072/38072/27737 38073/38073/27738 +f 38041/38041/27706 38073/38073/27738 38042/38042/27707 +f 38074/38074/27739 38075/38075/27740 38076/38076/27741 +f 38074/38074/27739 38076/38076/27741 38077/38077/27742 +f 38078/38078/27743 38074/38074/27739 38077/38077/27742 +f 38078/38078/27743 38077/38077/27742 38079/38079/27744 +f 38080/38080/27745 38078/38078/27743 38079/38079/27744 +f 38080/38080/27745 38079/38079/27744 38081/38081/27746 +f 38082/38082/27747 38080/38080/27745 38081/38081/27746 +f 38082/38082/27747 38081/38081/27746 38083/38083/27748 +f 38084/38084/27749 38082/38082/27747 38083/38083/27748 +f 38084/38084/27749 38083/38083/27748 38085/38085/27750 +f 38042/38042/27707 38084/38084/27749 38085/38085/27750 +f 38042/38042/27707 38085/38085/27750 38043/38043/27708 +f 38043/38043/27708 38085/38085/27750 38086/38086/27751 +f 38043/38043/27708 38086/38086/27751 38044/38044/27709 +f 38077/38077/27742 38076/38076/27741 38087/38087/27752 +f 38077/38077/27742 38087/38087/27752 38088/38088/27753 +f 38079/38079/27744 38077/38077/27742 38088/38088/27753 +f 38079/38079/27744 38088/38088/27753 38089/38089/27754 +f 38081/38081/27746 38079/38079/27744 38089/38089/27754 +f 38081/38081/27746 38089/38089/27754 38090/38090/27755 +f 38083/38083/27748 38081/38081/27746 38090/38090/27755 +f 38083/38083/27748 38090/38090/27755 38091/38091/27756 +f 38085/38085/27750 38083/38083/27748 38091/38091/27756 +f 38085/38085/27750 38091/38091/27756 38086/38086/27751 +f 38089/38089/27754 38088/38088/27753 38092/38092/27757 +f 38089/38089/27754 38092/38092/27757 38093/38093/27758 +f 38090/38090/27755 38089/38089/27754 38093/38093/27758 +f 38090/38090/27755 38093/38093/27758 38094/38094/27759 +f 38091/38091/27756 38090/38090/27755 38094/38094/27759 +f 38091/38091/27756 38094/38094/27759 38095/38095/27760 +f 38086/38086/27751 38091/38091/27756 38095/38095/27760 +f 38086/38086/27751 38095/38095/27760 38096/38096/27761 +f 38044/38044/27709 38086/38086/27751 38096/38096/27761 +f 38044/38044/27709 38096/38096/27761 38045/38045/27710 +f 38088/38088/27753 38087/38087/27752 38097/38097/27762 +f 38088/38088/27753 38097/38097/27762 38092/38092/27757 +f 38045/38045/27710 38096/38096/27761 38098/38098/27763 +f 38045/38045/27710 38098/38098/27763 38046/38046/27711 +f 38092/38092/27757 38097/38097/27762 38099/38099/27764 +f 38092/38092/27757 38099/38099/27764 38100/38100/27765 +f 38093/38093/27758 38092/38092/27757 38100/38100/27765 +f 38093/38093/27758 38100/38100/27765 38101/38101/27766 +f 38094/38094/27759 38093/38093/27758 38101/38101/27766 +f 38094/38094/27759 38101/38101/27766 38102/38102/27767 +f 38095/38095/27760 38094/38094/27759 38102/38102/27767 +f 38095/38095/27760 38102/38102/27767 38103/38103/27768 +f 38096/38096/27761 38095/38095/27760 38103/38103/27768 +f 38096/38096/27761 38103/38103/27768 38098/38098/27763 +f 38102/38102/27767 38101/38101/27766 38104/38104/27769 +f 38102/38102/27767 38104/38104/27769 38105/38105/27770 +f 38103/38103/27768 38102/38102/27767 38105/38105/27770 +f 38103/38103/27768 38105/38105/27770 38106/38106/27771 +f 38098/38098/27763 38103/38103/27768 38106/38106/27771 +f 38098/38098/27763 38106/38106/27771 38107/38107/27772 +f 38046/38046/27711 38098/38098/27763 38107/38107/27772 +f 38046/38046/27711 38107/38107/27772 38047/38047/27712 +f 38100/38100/27765 38099/38099/27764 38108/38108/27773 +f 38100/38100/27765 38108/38108/27773 38109/38109/27774 +f 38101/38101/27766 38100/38100/27765 38109/38109/27774 +f 38101/38101/27766 38109/38109/27774 38104/38104/27769 +f 38109/38109/27774 38108/38108/27773 38110/38110/27775 +f 38109/38109/27774 38110/38110/27775 38111/38111/27776 +f 38104/38104/27769 38109/38109/27774 38111/38111/27776 +f 38104/38104/27769 38111/38111/27776 38112/38112/27777 +f 38105/38105/27770 38104/38104/27769 38112/38112/27777 +f 38105/38105/27770 38112/38112/27777 38113/38113/27778 +f 38106/38106/27771 38105/38105/27770 38113/38113/27778 +f 38106/38106/27771 38113/38113/27778 38114/38114/27779 +f 38107/38107/27772 38106/38106/27771 38114/38114/27779 +f 38107/38107/27772 38114/38114/27779 38115/38115/27780 +f 38047/38047/27712 38107/38107/27772 38115/38115/27780 +f 38047/38047/27712 38115/38115/27780 38048/38048/27713 +f 38114/38114/27779 38113/38113/27778 38116/38116/27781 +f 38114/38114/27779 38116/38116/27781 38117/38117/27782 +f 38115/38115/27780 38114/38114/27779 38117/38117/27782 +f 38115/38115/27780 38117/38117/27782 38118/38118/27783 +f 38048/38048/27713 38115/38115/27780 38118/38118/27783 +f 38048/38048/27713 38118/38118/27783 38049/38049/27714 +f 38111/38111/27776 38110/38110/27775 38119/38119/27784 +f 38111/38111/27776 38119/38119/27784 38120/38120/27785 +f 38112/38112/27777 38111/38111/27776 38120/38120/27785 +f 38112/38112/27777 38120/38120/27785 38121/38121/27786 +f 38113/38113/27778 38112/38112/27777 38121/38121/27786 +f 38113/38113/27778 38121/38121/27786 38116/38116/27781 +f 38120/38120/27785 38119/38119/27784 38122/38122/27787 +f 38120/38120/27785 38122/38122/27787 38123/38123/27788 +f 38121/38121/27786 38120/38120/27785 38123/38123/27788 +f 38121/38121/27786 38123/38123/27788 38124/38124/27789 +f 38116/38116/27781 38121/38121/27786 38124/38124/27789 +f 38116/38116/27781 38124/38124/27789 38125/38125/27790 +f 38117/38117/27782 38116/38116/27781 38125/38125/27790 +f 38117/38117/27782 38125/38125/27790 38126/38126/27791 +f 38118/38118/27783 38117/38117/27782 38126/38126/27791 +f 38118/38118/27783 38126/38126/27791 38127/38127/27792 +f 38049/38049/27714 38118/38118/27783 38127/38127/27792 +f 38049/38049/27714 38127/38127/27792 38050/38050/27715 +f 38126/38126/27791 38125/38125/27790 38128/38128/27793 +f 38126/38126/27791 38128/38128/27793 38129/38129/27794 +f 38127/38127/27792 38126/38126/27791 38129/38129/27794 +f 38127/38127/27792 38129/38129/27794 38130/38130/27795 +f 38050/38050/27715 38127/38127/27792 38130/38130/27795 +f 38050/38050/27715 38130/38130/27795 38051/38051/27716 +f 38123/38123/27788 38122/38122/27787 38131/38131/27796 +f 38123/38123/27788 38131/38131/27796 38132/38132/27797 +f 38124/38124/27789 38123/38123/27788 38132/38132/27797 +f 38124/38124/27789 38132/38132/27797 38133/38133/27798 +f 38125/38125/27790 38124/38124/27789 38133/38133/27798 +f 38125/38125/27790 38133/38133/27798 38128/38128/27793 +f 38132/38132/27797 38131/38131/27796 38134/38134/27799 +f 38132/38132/27797 38134/38134/27799 38135/38135/27800 +f 38133/38133/27798 38132/38132/27797 38135/38135/27800 +f 38133/38133/27798 38135/38135/27800 38136/38136/27801 +f 38128/38128/27793 38133/38133/27798 38136/38136/27801 +f 38128/38128/27793 38136/38136/27801 38137/38137/27802 +f 38129/38129/27794 38128/38128/27793 38137/38137/27802 +f 38129/38129/27794 38137/38137/27802 38138/38138/27803 +f 38130/38130/27795 38129/38129/27794 38138/38138/27803 +f 38130/38130/27795 38138/38138/27803 38139/38139/27804 +f 38051/38051/27716 38130/38130/27795 38139/38139/27804 +f 38051/38051/27716 38139/38139/27804 38052/38052/27717 +f 38139/38139/27804 38138/38138/27803 38140/38140/27805 +f 38139/38139/27804 38140/38140/27805 38141/38141/27806 +f 38052/38052/27717 38139/38139/27804 38141/38141/27806 +f 38052/38052/27717 38141/38141/27806 38053/38053/27718 +f 38135/38135/27800 38134/38134/27799 38142/38142/27807 +f 38135/38135/27800 38142/38142/27807 38143/38143/27808 +f 38136/38136/27801 38135/38135/27800 38143/38143/27808 +f 38136/38136/27801 38143/38143/27808 38144/38144/27809 +f 38137/38137/27802 38136/38136/27801 38144/38144/27809 +f 38137/38137/27802 38144/38144/27809 38145/38145/27810 +f 38138/38138/27803 38137/38137/27802 38145/38145/27810 +f 38138/38138/27803 38145/38145/27810 38140/38140/27805 +f 38143/38143/27808 38142/38142/27807 38146/38146/27811 +f 38143/38143/27808 38146/38146/27811 38147/38147/27812 +f 38144/38144/27809 38143/38143/27808 38147/38147/27812 +f 38144/38144/27809 38147/38147/27812 38148/38148/27813 +f 38145/38145/27810 38144/38144/27809 38148/38148/27813 +f 38145/38145/27810 38148/38148/27813 38149/38149/27814 +f 38140/38140/27805 38145/38145/27810 38149/38149/27814 +f 38140/38140/27805 38149/38149/27814 38150/38150/27815 +f 38141/38141/27806 38140/38140/27805 38150/38150/27815 +f 38141/38141/27806 38150/38150/27815 38151/38151/27816 +f 38053/38053/27718 38141/38141/27806 38151/38151/27816 +f 38053/38053/27718 38151/38151/27816 38054/38054/27719 +f 38151/38151/27816 38150/38150/27815 38152/38152/27817 +f 38151/38151/27816 38152/38152/27817 38153/38153/27818 +f 38054/38054/27719 38151/38151/27816 38153/38153/27818 +f 38054/38054/27719 38153/38153/27818 38055/38055/27720 +f 38147/38147/27812 38146/38146/27811 38154/38154/27819 +f 38147/38147/27812 38154/38154/27819 38155/38155/27820 +f 38148/38148/27813 38147/38147/27812 38155/38155/27820 +f 38148/38148/27813 38155/38155/27820 38156/38156/27821 +f 38149/38149/27814 38148/38148/27813 38156/38156/27821 +f 38149/38149/27814 38156/38156/27821 38157/38157/27822 +f 38150/38150/27815 38149/38149/27814 38157/38157/27822 +f 38150/38150/27815 38157/38157/27822 38152/38152/27817 +f 38156/38156/27821 38155/38155/27820 38158/38158/27823 +f 38156/38156/27821 38158/38158/27823 38159/38159/27824 +f 38157/38157/27822 38156/38156/27821 38159/38159/27824 +f 38157/38157/27822 38159/38159/27824 38160/38160/27825 +f 38152/38152/27817 38157/38157/27822 38160/38160/27825 +f 38152/38152/27817 38160/38160/27825 38161/38161/27826 +f 38153/38153/27818 38152/38152/27817 38161/38161/27826 +f 38153/38153/27818 38161/38161/27826 38162/38162/27827 +f 38055/38055/27720 38153/38153/27818 38162/38162/27827 +f 38055/38055/27720 38162/38162/27827 38056/38056/27721 +f 38155/38155/27820 38154/38154/27819 38163/38163/27828 +f 38155/38155/27820 38163/38163/27828 38158/38158/27823 +f 38056/38056/27721 38162/38162/27827 38164/38164/27829 +f 38056/38056/27721 38164/38164/27829 38057/38057/27722 +f 38158/38158/27823 38163/38163/27828 38165/38165/27830 +f 38158/38158/27823 38165/38165/27830 38166/38166/27831 +f 38159/38159/27824 38158/38158/27823 38166/38166/27831 +f 38159/38159/27824 38166/38166/27831 38167/38167/27832 +f 38160/38160/27825 38159/38159/27824 38167/38167/27832 +f 38160/38160/27825 38167/38167/27832 38168/38168/27833 +f 38161/38161/27826 38160/38160/27825 38168/38168/27833 +f 38161/38161/27826 38168/38168/27833 38169/38169/27834 +f 38162/38162/27827 38161/38161/27826 38169/38169/27834 +f 38162/38162/27827 38169/38169/27834 38164/38164/27829 +f 38168/38168/27833 38167/38167/27832 38170/38170/27835 +f 38168/38168/27833 38170/38170/27835 38171/38171/27836 +f 38169/38169/27834 38168/38168/27833 38171/38171/27836 +f 38169/38169/27834 38171/38171/27836 38172/38172/27837 +f 38164/38164/27829 38169/38169/27834 38172/38172/27837 +f 38164/38164/27829 38172/38172/27837 38173/38173/27838 +f 38057/38057/27722 38164/38164/27829 38173/38173/27838 +f 38057/38057/27722 38173/38173/27838 38058/38058/27723 +f 38166/38166/27831 38165/38165/27830 38174/38174/27839 +f 38166/38166/27831 38174/38174/27839 38175/38175/27840 +f 38167/38167/27832 38166/38166/27831 38175/38175/27840 +f 38167/38167/27832 38175/38175/27840 38170/38170/27835 +f 38176/38176/27841 38177/38177/27839 38178/38178/27842 +f 38176/38176/27841 38178/38178/27842 38179/38179/27843 +f 38170/38170/27835 38175/38175/27840 38180/38180/27843 +f 38170/38170/27835 38180/38180/27843 38181/38181/27844 +f 38171/38171/27836 38170/38170/27835 38181/38181/27844 +f 38171/38171/27836 38181/38181/27844 38182/38182/27845 +f 38172/38172/27837 38171/38171/27836 38182/38182/27845 +f 38172/38172/27837 38182/38182/27845 38183/38183/27846 +f 38173/38173/27838 38172/38172/27837 38183/38183/27846 +f 38173/38173/27838 38183/38183/27846 38184/38184/27847 +f 38058/38058/27723 38173/38173/27838 38184/38184/27847 +f 38058/38058/27723 38184/38184/27847 38059/38059/27724 +f 38182/38182/27845 38181/38181/27844 38185/38185/27848 +f 38182/38182/27845 38185/38185/27848 38186/38186/27849 +f 38183/38183/27846 38182/38182/27845 38186/38186/27849 +f 38183/38183/27846 38186/38186/27849 38187/38187/27850 +f 38184/38184/27847 38183/38183/27846 38187/38187/27850 +f 38184/38184/27847 38187/38187/27850 38188/38188/27851 +f 38059/38059/27724 38184/38184/27847 38188/38188/27851 +f 38059/38059/27724 38188/38188/27851 38060/38060/27725 +f 38179/38179/27843 38178/38178/27842 38189/38189/27852 +f 38179/38179/27843 38189/38189/27852 38190/38190/27853 +f 38191/38191/27854 38179/38179/27843 38190/38190/27853 +f 38191/38191/27854 38190/38190/27853 38192/38192/27855 +f 38190/38190/27853 38189/38189/27852 38193/38193/27856 +f 38190/38190/27853 38193/38193/27856 38194/38194/27857 +f 38192/38192/27855 38190/38190/27853 38194/38194/27857 +f 38192/38192/27855 38194/38194/27857 38195/38195/27858 +f 38196/38196/27849 38192/38192/27855 38195/38195/27858 +f 38196/38196/27849 38195/38195/27858 38197/38197/27859 +f 38187/38187/27850 38186/38186/27849 38198/38198/27859 +f 38187/38187/27850 38198/38198/27859 38199/38199/27860 +f 38188/38188/27851 38187/38187/27850 38199/38199/27860 +f 38188/38188/27851 38199/38199/27860 38200/38200/27861 +f 38060/38060/27725 38188/38188/27851 38200/38200/27861 +f 38060/38060/27725 38200/38200/27861 38061/38061/27726 +f 38201/38201/27862 38197/38197/27859 38202/38202/27863 +f 38201/38201/27862 38202/38202/27863 38203/38203/27864 +f 38200/38200/27861 38199/38199/27860 38204/38204/27865 +f 38200/38200/27861 38204/38204/27865 38205/38205/27866 +f 38061/38061/27726 38200/38200/27861 38205/38205/27866 +f 38061/38061/27726 38205/38205/27866 38062/38062/27727 +f 38194/38194/27857 38193/38193/27856 38206/38206/27867 +f 38194/38194/27857 38206/38206/27867 38207/38207/27868 +f 38195/38195/27858 38194/38194/27857 38207/38207/27868 +f 38195/38195/27858 38207/38207/27868 38208/38208/27869 +f 38197/38197/27859 38195/38195/27858 38208/38208/27869 +f 38197/38197/27859 38208/38208/27869 38202/38202/27863 +f 38207/38207/27868 38206/38206/27867 38209/38209/27870 +f 38207/38207/27868 38209/38209/27870 38210/38210/27871 +f 38208/38208/27869 38207/38207/27868 38210/38210/27871 +f 38208/38208/27869 38210/38210/27871 38211/38211/27872 +f 38202/38202/27863 38208/38208/27869 38211/38211/27872 +f 38202/38202/27863 38211/38211/27872 38212/38212/27873 +f 38203/38203/27864 38202/38202/27863 38212/38212/27873 +f 38203/38203/27864 38212/38212/27873 38213/38213/27874 +f 38205/38205/27866 38204/38204/27865 38214/38214/27874 +f 38205/38205/27866 38214/38214/27874 38215/38215/27875 +f 38062/38062/27727 38205/38205/27866 38215/38215/27875 +f 38062/38062/27727 38215/38215/27875 38063/38063/27728 +f 38213/38213/27874 38212/38212/27873 38216/38216/27876 +f 38213/38213/27874 38216/38216/27876 38217/38217/27877 +f 38215/38215/27875 38214/38214/27874 38218/38218/27878 +f 38215/38215/27875 38218/38218/27878 38219/38219/27879 +f 38063/38063/27728 38215/38215/27875 38219/38219/27879 +f 38063/38063/27728 38219/38219/27879 38064/38064/27729 +f 38210/38210/27871 38209/38209/27870 38220/38220/27880 +f 38210/38210/27871 38220/38220/27880 38221/38221/27881 +f 38211/38211/27872 38210/38210/27871 38221/38221/27881 +f 38211/38211/27872 38221/38221/27881 38222/38222/27882 +f 38212/38212/27873 38211/38211/27872 38222/38222/27882 +f 38212/38212/27873 38222/38222/27882 38216/38216/27876 +f 38221/38221/27881 38220/38220/27880 38223/38223/27883 +f 38221/38221/27881 38223/38223/27883 38224/38224/27884 +f 38222/38222/27882 38221/38221/27881 38224/38224/27884 +f 38222/38222/27882 38224/38224/27884 38225/38225/27885 +f 38216/38216/27876 38222/38222/27882 38225/38225/27885 +f 38216/38216/27876 38225/38225/27885 38226/38226/27886 +f 38217/38217/27877 38216/38216/27876 38226/38226/27886 +f 38217/38217/27877 38226/38226/27886 38227/38227/27887 +f 38219/38219/27879 38218/38218/27878 38228/38228/27888 +f 38219/38219/27879 38228/38228/27888 38229/38229/27889 +f 38064/38064/27729 38219/38219/27879 38229/38229/27889 +f 38064/38064/27729 38229/38229/27889 38065/38065/27730 +f 38229/38229/27889 38228/38228/27888 38230/38230/27890 +f 38229/38229/27889 38230/38230/27890 38231/38231/27891 +f 38065/38065/27730 38229/38229/27889 38231/38231/27891 +f 38065/38065/27730 38231/38231/27891 38066/38066/27731 +f 38224/38224/27884 38223/38223/27883 38232/38232/27892 +f 38224/38224/27884 38232/38232/27892 38233/38233/27893 +f 38225/38225/27885 38224/38224/27884 38233/38233/27893 +f 38225/38225/27885 38233/38233/27893 38234/38234/27894 +f 38226/38226/27886 38225/38225/27885 38234/38234/27894 +f 38226/38226/27886 38234/38234/27894 38235/38235/27895 +f 38227/38227/27887 38226/38226/27886 38235/38235/27895 +f 38227/38227/27887 38235/38235/27895 38236/38236/27890 +f 38234/38234/27894 38233/38233/27893 38237/38237/27896 +f 38234/38234/27894 38237/38237/27896 38238/38238/27897 +f 38235/38235/27895 38234/38234/27894 38238/38238/27897 +f 38235/38235/27895 38238/38238/27897 38239/38239/27898 +f 38236/38236/27890 38235/38235/27895 38239/38239/27898 +f 38236/38236/27890 38239/38239/27898 38240/38240/27899 +f 38231/38231/27891 38230/38230/27890 38241/38241/27899 +f 38231/38231/27891 38241/38241/27899 38242/38242/27900 +f 38066/38066/27731 38231/38231/27891 38242/38242/27900 +f 38066/38066/27731 38242/38242/27900 38067/38067/27732 +f 38233/38233/27893 38232/38232/27892 38243/38243/27901 +f 38233/38233/27893 38243/38243/27901 38237/38237/27896 +f 38067/38067/27732 38242/38242/27900 38244/38244/27902 +f 38067/38067/27732 38244/38244/27902 38068/38068/27733 +f 38237/38237/27896 38243/38243/27901 38245/38245/27903 +f 38237/38237/27896 38245/38245/27903 38246/38246/27904 +f 38238/38238/27897 38237/38237/27896 38246/38246/27904 +f 38238/38238/27897 38246/38246/27904 38247/38247/27905 +f 38239/38239/27898 38238/38238/27897 38247/38247/27905 +f 38239/38239/27898 38247/38247/27905 38248/38248/27906 +f 38240/38240/27899 38239/38239/27898 38248/38248/27906 +f 38240/38240/27899 38248/38248/27906 38249/38249/27907 +f 38242/38242/27900 38241/38241/27899 38250/38250/27907 +f 38242/38242/27900 38250/38250/27907 38244/38244/27902 +f 38247/38247/27905 38246/38246/27904 38251/38251/27908 +f 38247/38247/27905 38251/38251/27908 38252/38252/27909 +f 38248/38248/27906 38247/38247/27905 38252/38252/27909 +f 38248/38248/27906 38252/38252/27909 38253/38253/27910 +f 38249/38249/27907 38248/38248/27906 38253/38253/27910 +f 38249/38249/27907 38253/38253/27910 38254/38254/27911 +f 38244/38244/27902 38250/38250/27907 38255/38255/27912 +f 38244/38244/27902 38255/38255/27912 38256/38256/27913 +f 38068/38068/27733 38244/38244/27902 38256/38256/27913 +f 38068/38068/27733 38256/38256/27913 38069/38069/27734 +f 38246/38246/27904 38245/38245/27903 38257/38257/27914 +f 38246/38246/27904 38257/38257/27914 38251/38251/27908 +f 38069/38069/27734 38256/38256/27913 38258/38258/27915 +f 38069/38069/27734 38258/38258/27915 38070/38070/27735 +f 38251/38251/27908 38257/38257/27914 38259/38259/27916 +f 38251/38251/27908 38259/38259/27916 38260/38260/27917 +f 38252/38252/27909 38251/38251/27908 38260/38260/27917 +f 38252/38252/27909 38260/38260/27917 38261/38261/27918 +f 38253/38253/27910 38252/38252/27909 38261/38261/27918 +f 38253/38253/27910 38261/38261/27918 38262/38262/27919 +f 38254/38254/27911 38253/38253/27910 38262/38262/27919 +f 38254/38254/27911 38262/38262/27919 38263/38263/27920 +f 38256/38256/27913 38255/38255/27912 38264/38264/27921 +f 38256/38256/27913 38264/38264/27921 38258/38258/27915 +f 38262/38262/27919 38261/38261/27918 38265/38265/27922 +f 38262/38262/27919 38265/38265/27922 38266/38266/27923 +f 38264/38264/27921 38267/38267/27919 38268/38268/27923 +f 38264/38264/27921 38268/38268/27923 38269/38269/27924 +f 38258/38258/27915 38264/38264/27921 38269/38269/27924 +f 38258/38258/27915 38269/38269/27924 38270/38270/27925 +f 38070/38070/27735 38258/38258/27915 38270/38270/27925 +f 38070/38070/27735 38270/38270/27925 38071/38071/27736 +f 38260/38260/27917 38259/38259/27916 38271/38271/27926 +f 38260/38260/27917 38271/38271/27926 38272/38272/27927 +f 38261/38261/27918 38260/38260/27917 38272/38272/27927 +f 38261/38261/27918 38272/38272/27927 38265/38265/27922 +f 38272/38272/27927 38271/38271/27926 38273/38273/27928 +f 38272/38272/27927 38273/38273/27928 38274/38274/27929 +f 38265/38265/27922 38272/38272/27927 38274/38274/27929 +f 38265/38265/27922 38274/38274/27929 38275/38275/27930 +f 38268/38268/27923 38276/38276/27922 38277/38277/27930 +f 38268/38268/27923 38277/38277/27930 38278/38278/27931 +f 38269/38269/27924 38268/38268/27923 38278/38278/27931 +f 38269/38269/27924 38278/38278/27931 38279/38279/27932 +f 38270/38270/27925 38269/38269/27924 38279/38279/27932 +f 38270/38270/27925 38279/38279/27932 38280/38280/27933 +f 38071/38071/27736 38270/38270/27925 38280/38280/27933 +f 38071/38071/27736 38280/38280/27933 38072/38072/27737 +f 38278/38278/27931 38277/38277/27930 38281/38281/27934 +f 38278/38278/27931 38281/38281/27934 38282/38282/27935 +f 38279/38279/27932 38278/38278/27931 38282/38282/27935 +f 38279/38279/27932 38282/38282/27935 38283/38283/27936 +f 38280/38280/27933 38279/38279/27932 38283/38283/27936 +f 38280/38280/27933 38283/38283/27936 38284/38284/27937 +f 38072/38072/27737 38280/38280/27933 38284/38284/27937 +f 38072/38072/27737 38284/38284/27937 38073/38073/27738 +f 38274/38274/27929 38273/38273/27928 38285/38285/27938 +f 38274/38274/27929 38285/38285/27938 38286/38286/27939 +f 38277/38277/27930 38287/38287/27929 38288/38288/27939 +f 38277/38277/27930 38288/38288/27939 38281/38281/27934 +f 38288/38288/27939 38289/38289/27938 38075/38075/27740 +f 38288/38288/27939 38075/38075/27740 38074/38074/27739 +f 38281/38281/27934 38288/38288/27939 38074/38074/27739 +f 38281/38281/27934 38074/38074/27739 38078/38078/27743 +f 38282/38282/27935 38281/38281/27934 38078/38078/27743 +f 38282/38282/27935 38078/38078/27743 38080/38080/27745 +f 38283/38283/27936 38282/38282/27935 38080/38080/27745 +f 38283/38283/27936 38080/38080/27745 38082/38082/27747 +f 38284/38284/27937 38283/38283/27936 38082/38082/27747 +f 38284/38284/27937 38082/38082/27747 38084/38084/27749 +f 38073/38073/27738 38284/38284/27937 38084/38084/27749 +f 38073/38073/27738 38084/38084/27749 38042/38042/27707 +o Sphere.016__0 +v -0.531227 -1.104919 -1.010480 +v -0.531227 -1.096379 -1.010469 +v -0.529576 -1.096542 -1.010461 +v -0.527988 -1.097028 -1.010439 +v -0.526525 -1.097815 -1.010404 +v -0.525243 -1.098875 -1.010356 +v -0.524190 -1.100166 -1.010298 +v -0.523408 -1.101639 -1.010232 +v -0.522926 -1.103238 -1.010160 +v -0.522764 -1.104901 -1.010085 +v -0.522926 -1.106563 -1.010010 +v -0.523408 -1.108162 -1.009938 +v -0.524190 -1.109635 -1.009872 +v -0.525243 -1.110927 -1.009814 +v -0.526525 -1.111987 -1.009766 +v -0.527988 -1.112774 -1.009731 +v -0.529576 -1.113259 -1.009709 +v -0.531227 -1.113423 -1.009702 +v -0.532878 -1.113259 -1.009709 +v -0.534465 -1.112774 -1.009731 +v -0.535928 -1.111987 -1.009766 +v -0.537211 -1.110927 -1.009814 +v -0.538263 -1.109635 -1.009872 +v -0.539046 -1.108162 -1.009938 +v -0.539527 -1.106563 -1.010010 +v -0.539690 -1.104901 -1.010085 +v -0.539527 -1.103238 -1.010160 +v -0.539046 -1.101639 -1.010232 +v -0.538263 -1.100166 -1.010298 +v -0.537211 -1.098875 -1.010356 +v -0.535928 -1.097815 -1.010404 +v -0.534465 -1.097028 -1.010439 +v -0.532878 -1.096542 -1.010461 +v -0.531227 -1.063990 -0.999595 +v -0.531227 -1.061331 -0.995848 +v -0.522926 -1.062154 -0.995811 +v -0.523408 -1.064765 -0.999560 +v -0.531227 -1.068187 -1.002971 +v -0.524190 -1.068885 -1.002939 +v -0.531227 -1.073759 -1.005844 +v -0.525243 -1.074353 -1.005817 +v -0.531227 -1.080494 -1.008105 +v -0.526525 -1.080960 -1.008084 +v -0.531227 -1.088132 -1.009666 +v -0.527988 -1.088453 -1.009652 +v -0.524874 -1.089404 -1.009609 +v -0.514945 -1.064592 -0.995701 +v -0.515890 -1.067062 -0.999457 +v -0.517424 -1.070952 -1.002846 +v -0.519488 -1.076111 -1.005738 +v -0.522004 -1.082342 -1.008022 +v -0.508961 -1.070791 -0.999289 +v -0.511188 -1.074308 -1.002695 +v -0.514185 -1.078965 -1.005610 +v -0.517838 -1.084584 -1.007921 +v -0.522004 -1.090949 -1.009540 +v -0.507590 -1.068551 -0.995523 +v -0.519488 -1.093028 -1.009446 +v -0.501143 -1.073879 -0.995283 +v -0.502888 -1.075810 -0.999063 +v -0.505723 -1.078825 -1.002492 +v -0.509537 -1.082806 -1.005437 +v -0.514185 -1.087602 -1.007785 +v -0.501237 -1.084329 -1.002244 +v -0.505723 -1.087487 -1.005226 +v -0.511188 -1.091280 -1.007620 +v -0.517424 -1.095561 -1.009332 +v -0.495851 -1.080371 -0.994991 +v -0.497904 -1.081926 -0.998788 +v -0.491920 -1.087778 -0.994658 +v -0.494200 -1.088903 -0.998474 +v -0.497904 -1.090608 -1.001962 +v -0.502888 -1.092827 -1.004986 +v -0.508961 -1.095475 -1.007431 +v -0.515890 -1.098451 -1.009202 +v -0.501143 -1.098621 -1.004725 +v -0.507590 -1.100028 -1.007226 +v -0.514945 -1.101587 -1.009061 +v -0.489499 -1.095815 -0.994296 +v -0.491920 -1.096474 -0.998134 +v -0.495851 -1.097421 -1.001655 +v -0.488681 -1.104174 -0.993920 +v -0.491150 -1.104347 -0.997779 +v -0.495158 -1.104507 -1.001336 +v -0.500553 -1.104648 -1.004454 +v -0.507127 -1.104763 -1.007013 +v -0.514626 -1.104848 -1.008914 +v -0.501143 -1.110673 -1.004183 +v -0.507590 -1.109497 -1.006800 +v -0.514945 -1.108109 -1.008768 +v -0.489499 -1.112532 -0.993544 +v -0.491920 -1.112220 -0.997425 +v -0.495851 -1.111593 -1.001018 +v -0.491920 -1.120569 -0.993182 +v -0.494200 -1.119791 -0.997085 +v -0.497904 -1.118406 -1.000711 +v -0.502888 -1.116468 -1.003922 +v -0.508961 -1.114050 -1.006595 +v -0.515890 -1.111245 -1.008626 +v -0.511188 -1.118245 -1.006407 +v -0.517424 -1.114135 -1.008497 +v -0.495851 -1.127975 -0.992849 +v -0.497904 -1.126768 -0.996771 +v -0.501237 -1.124686 -1.000428 +v -0.505723 -1.121808 -1.003682 +v -0.501143 -1.134468 -0.992557 +v -0.502888 -1.132884 -0.996495 +v -0.505723 -1.130190 -1.000181 +v -0.509537 -1.126488 -1.003472 +v -0.514185 -1.121923 -1.006241 +v -0.519488 -1.116668 -1.008383 +v -0.517838 -1.124941 -1.006105 +v -0.522004 -1.118747 -1.008289 +v -0.507590 -1.139796 -0.992317 +v -0.508961 -1.137903 -0.996270 +v -0.511188 -1.134706 -0.999978 +v -0.514185 -1.130330 -1.003299 +v -0.515890 -1.141632 -0.996102 +v -0.517424 -1.138063 -0.999827 +v -0.519488 -1.133184 -1.003170 +v -0.522004 -1.127184 -1.006004 +v -0.524874 -1.120292 -1.008219 +v -0.514945 -1.143755 -0.992139 +v -0.527988 -1.121243 -1.008177 +v -0.522927 -1.146193 -0.992029 +v -0.523408 -1.143928 -0.995999 +v -0.524190 -1.140130 -0.999734 +v -0.525243 -1.134942 -1.003091 +v -0.526525 -1.128564 -1.005942 +v -0.531227 -1.140828 -0.999702 +v -0.531227 -1.135535 -1.003064 +v -0.531227 -1.129031 -1.005921 +v -0.531227 -1.121565 -1.008162 +v -0.531227 -1.147016 -0.991992 +v -0.531227 -1.144704 -0.995964 +v -0.531227 -1.144704 -0.995964 +v -0.531227 -1.147016 -0.991992 +v -0.539527 -1.146193 -0.992029 +v -0.539046 -1.143928 -0.995999 +v -0.539046 -1.143928 -0.995999 +v -0.538263 -1.140130 -0.999734 +v -0.537211 -1.134942 -1.003091 +v -0.535928 -1.128564 -1.005942 +v -0.534465 -1.121243 -1.008177 +v -0.545030 -1.138063 -0.999827 +v -0.542965 -1.133184 -1.003170 +v -0.540450 -1.127184 -1.006004 +v -0.537579 -1.120292 -1.008219 +v -0.547508 -1.143755 -0.992139 +v -0.546564 -1.141632 -0.996102 +v -0.538263 -1.140130 -0.999734 +v -0.545030 -1.138063 -0.999827 +v -0.554864 -1.139796 -0.992317 +v -0.553493 -1.137903 -0.996270 +v -0.551265 -1.134706 -0.999978 +v -0.542965 -1.133184 -1.003170 +v -0.548268 -1.130330 -1.003299 +v -0.548268 -1.130330 -1.003299 +v -0.544616 -1.124941 -1.006105 +v -0.540450 -1.118747 -1.008289 +v -0.544616 -1.124941 -1.006105 +v -0.552916 -1.126488 -1.003472 +v -0.548268 -1.121923 -1.006241 +v -0.548268 -1.121923 -1.006241 +v -0.542965 -1.116668 -1.008383 +v -0.561311 -1.134468 -0.992557 +v -0.559566 -1.132884 -0.996495 +v -0.556731 -1.130190 -1.000181 +v -0.566602 -1.127975 -0.992849 +v -0.564549 -1.126768 -0.996771 +v -0.561217 -1.124686 -1.000428 +v -0.556731 -1.121808 -1.003682 +v -0.551265 -1.118245 -1.006407 +v -0.551265 -1.118245 -1.006407 +v -0.545030 -1.114135 -1.008497 +v -0.559566 -1.116468 -1.003922 +v -0.553493 -1.114050 -1.006595 +v -0.553493 -1.114050 -1.006595 +v -0.546564 -1.111245 -1.008626 +v -0.570534 -1.120569 -0.993182 +v -0.568253 -1.119791 -0.997085 +v -0.564549 -1.118406 -1.000711 +v -0.572955 -1.112532 -0.993544 +v -0.570534 -1.112220 -0.997425 +v -0.566602 -1.111593 -1.001018 +v -0.561311 -1.110673 -1.004183 +v -0.554864 -1.109497 -1.006800 +v -0.554864 -1.109497 -1.006800 +v -0.547508 -1.108109 -1.008768 +v -0.555327 -1.104763 -1.007013 +v -0.547827 -1.104848 -1.008914 +v -0.573772 -1.104174 -0.993920 +v -0.571304 -1.104347 -0.997779 +v -0.567295 -1.104507 -1.001336 +v -0.561901 -1.104648 -1.004454 +v -0.555327 -1.104763 -1.007013 +v -0.570534 -1.096474 -0.998134 +v -0.566602 -1.097421 -1.001655 +v -0.561311 -1.098621 -1.004725 +v -0.554864 -1.100028 -1.007226 +v -0.554864 -1.100028 -1.007226 +v -0.547508 -1.101587 -1.009061 +v -0.572955 -1.095815 -0.994296 +v -0.546564 -1.098451 -1.009202 +v -0.570534 -1.087778 -0.994658 +v -0.568253 -1.088903 -0.998474 +v -0.564549 -1.090608 -1.001962 +v -0.559566 -1.092827 -1.004986 +v -0.553493 -1.095475 -1.007431 +v -0.553493 -1.095475 -1.007431 +v -0.564549 -1.081926 -0.998788 +v -0.561217 -1.084329 -1.002244 +v -0.556731 -1.087487 -1.005226 +v -0.551265 -1.091280 -1.007620 +v -0.551265 -1.091280 -1.007620 +v -0.545030 -1.095561 -1.009332 +v -0.566602 -1.080371 -0.994991 +v -0.542965 -1.093028 -1.009446 +v -0.561311 -1.073879 -0.995283 +v -0.559566 -1.075810 -0.999063 +v -0.556731 -1.078825 -1.002492 +v -0.552916 -1.082806 -1.005437 +v -0.548268 -1.087602 -1.007785 +v -0.548268 -1.087602 -1.007785 +v -0.551265 -1.074308 -1.002695 +v -0.548268 -1.078965 -1.005610 +v -0.552916 -1.082806 -1.005437 +v -0.548268 -1.078965 -1.005610 +v -0.544616 -1.084584 -1.007921 +v -0.540450 -1.090949 -1.009540 +v -0.554864 -1.068551 -0.995523 +v -0.553493 -1.070791 -0.999289 +v -0.547508 -1.064592 -0.995701 +v -0.546564 -1.067062 -0.999457 +v -0.545030 -1.070952 -1.002846 +v -0.551265 -1.074308 -1.002695 +v -0.545030 -1.070952 -1.002846 +v -0.542965 -1.076111 -1.005738 +v -0.540450 -1.082342 -1.008022 +v -0.537579 -1.089404 -1.009609 +v -0.538263 -1.068885 -1.002939 +v -0.537211 -1.074353 -1.005817 +v -0.535928 -1.080960 -1.008084 +v -0.534465 -1.088453 -1.009652 +v -0.539527 -1.062154 -0.995811 +v -0.539046 -1.064765 -0.999560 +v -0.546564 -1.067062 -0.999457 +v -0.539046 -1.064765 -0.999560 +v -0.539527 -1.062154 -0.995811 +vt 0.697896 0.777137 +vt 0.697956 0.776509 +vt 0.697836 0.776509 +vt 0.697718 0.776533 +vt 0.697607 0.776580 +vt 0.697506 0.776649 +vt 0.697421 0.776736 +vt 0.697353 0.776839 +vt 0.697306 0.776953 +vt 0.697281 0.777074 +vt 0.697280 0.777198 +vt 0.697302 0.777319 +vt 0.697347 0.777433 +vt 0.697412 0.777536 +vt 0.697496 0.777623 +vt 0.697595 0.777692 +vt 0.697706 0.777739 +vt 0.697823 0.777763 +vt 0.697943 0.777763 +vt 0.698061 0.777739 +vt 0.698172 0.777692 +vt 0.698273 0.777623 +vt 0.698359 0.777536 +vt 0.698426 0.777433 +vt 0.698474 0.777319 +vt 0.698498 0.777198 +vt 0.698500 0.777074 +vt 0.698477 0.776953 +vt 0.698433 0.776839 +vt 0.698367 0.776736 +vt 0.698283 0.776649 +vt 0.698184 0.776580 +vt 0.698074 0.776533 +vt 0.698014 0.774127 +vt 0.697974 0.773932 +vt 0.697371 0.773932 +vt 0.697446 0.774127 +vt 0.698038 0.774436 +vt 0.697526 0.774436 +vt 0.698044 0.774845 +vt 0.697609 0.774845 +vt 0.698032 0.775341 +vt 0.697690 0.775341 +vt 0.698002 0.775902 +vt 0.697767 0.775902 +vt 0.697535 0.775950 +vt 0.696778 0.774053 +vt 0.696887 0.774242 +vt 0.697024 0.774538 +vt 0.697181 0.774933 +vt 0.697354 0.775409 +vt 0.696360 0.774465 +vt 0.696549 0.774740 +vt 0.696778 0.775104 +vt 0.697037 0.775544 +vt 0.697317 0.776042 +vt 0.696218 0.774291 +vt 0.697120 0.776177 +vt 0.695713 0.774636 +vt 0.695884 0.774790 +vt 0.696121 0.775032 +vt 0.696413 0.775353 +vt 0.696751 0.775739 +vt 0.695755 0.775405 +vt 0.696103 0.775669 +vt 0.696507 0.775988 +vt 0.696952 0.776348 +vt 0.695282 0.775075 +vt 0.695478 0.775204 +vt 0.694941 0.775592 +vt 0.695157 0.775691 +vt 0.695467 0.775843 +vt 0.695857 0.776042 +vt 0.696314 0.776281 +vt 0.696819 0.776550 +vt 0.695686 0.776455 +vt 0.696179 0.776606 +vt 0.696726 0.776774 +vt 0.694704 0.776166 +vt 0.694934 0.776231 +vt 0.695266 0.776329 +vt 0.694580 0.776775 +vt 0.694817 0.776805 +vt 0.695161 0.776845 +vt 0.695597 0.776895 +vt 0.696109 0.776951 +vt 0.696678 0.777011 +vt 0.695592 0.777342 +vt 0.696105 0.777302 +vt 0.696675 0.777254 +vt 0.694574 0.777396 +vt 0.694811 0.777390 +vt 0.695155 0.777372 +vt 0.694685 0.778005 +vt 0.694916 0.777964 +vt 0.695249 0.777888 +vt 0.695672 0.777781 +vt 0.696169 0.777647 +vt 0.696719 0.777491 +vt 0.696296 0.777973 +vt 0.696807 0.777715 +vt 0.694910 0.778579 +vt 0.695128 0.778504 +vt 0.695440 0.778375 +vt 0.695835 0.778195 +vt 0.695239 0.779095 +vt 0.695439 0.778991 +vt 0.695720 0.778813 +vt 0.696072 0.778567 +vt 0.696483 0.778265 +vt 0.696935 0.777917 +vt 0.696722 0.778514 +vt 0.697100 0.778088 +vt 0.695661 0.779534 +vt 0.695836 0.779404 +vt 0.696077 0.779185 +vt 0.696377 0.778884 +vt 0.696305 0.779729 +vt 0.696500 0.779477 +vt 0.696736 0.779133 +vt 0.697004 0.778709 +vt 0.697294 0.778223 +vt 0.696159 0.779879 +vt 0.697511 0.778315 +vt 0.696714 0.780117 +vt 0.696828 0.779953 +vt 0.696970 0.779679 +vt 0.697136 0.779304 +vt 0.697318 0.778844 +vt 0.697471 0.779782 +vt 0.697561 0.779392 +vt 0.697653 0.778912 +vt 0.697741 0.778363 +vt 0.697305 0.780238 +vt 0.697384 0.780067 +vt 0.952219 0.146492 +vt 0.952012 0.146309 +vt 0.951566 0.146430 +vt 0.951798 0.146606 +vt 0.697952 0.780067 +vt 0.697982 0.779782 +vt 0.697996 0.779392 +vt 0.697994 0.778912 +vt 0.697976 0.778363 +vt 0.698485 0.779679 +vt 0.698424 0.779304 +vt 0.698330 0.778844 +vt 0.698208 0.778315 +vt 0.951146 0.146667 +vt 0.951403 0.146829 +vt 0.952040 0.146892 +vt 0.951684 0.147093 +vt 0.950768 0.147011 +vt 0.951046 0.147154 +vt 0.951363 0.147385 +vt 0.951978 0.147448 +vt 0.951706 0.147696 +vt 0.698827 0.779133 +vt 0.698647 0.778709 +vt 0.698426 0.778223 +vt 0.952061 0.148075 +vt 0.951474 0.148013 +vt 0.951879 0.148324 +vt 0.698934 0.778514 +vt 0.698623 0.778088 +vt 0.950446 0.147450 +vt 0.950743 0.147567 +vt 0.951090 0.147757 +vt 0.950194 0.147967 +vt 0.950505 0.148054 +vt 0.950876 0.148195 +vt 0.951292 0.148385 +vt 0.951736 0.148616 +vt 0.699178 0.778265 +vt 0.698792 0.777917 +vt 0.951166 0.148799 +vt 0.951637 0.148942 +vt 0.699371 0.777973 +vt 0.698924 0.777715 +vt 0.950019 0.148540 +vt 0.950341 0.148594 +vt 0.950728 0.148681 +vt 0.949931 0.149150 +vt 0.950258 0.149168 +vt 0.950653 0.149198 +vt 0.951102 0.149238 +vt 0.951587 0.149287 +vt 0.699505 0.777647 +vt 0.699017 0.777491 +vt 0.699575 0.777302 +vt 0.699065 0.777254 +vt 0.949931 0.149772 +vt 0.950258 0.149754 +vt 0.950653 0.149725 +vt 0.951102 0.149686 +vt 0.951587 0.149639 +vt 0.950341 0.150328 +vt 0.950728 0.150242 +vt 0.951166 0.150126 +vt 0.951637 0.149984 +vt 0.699579 0.776951 +vt 0.699068 0.777011 +vt 0.950019 0.150382 +vt 0.699024 0.776774 +vt 0.950194 0.150956 +vt 0.950505 0.150870 +vt 0.950876 0.150729 +vt 0.951292 0.150540 +vt 0.951736 0.150310 +vt 0.699516 0.776606 +vt 0.950743 0.151357 +vt 0.951090 0.151168 +vt 0.951474 0.150913 +vt 0.951879 0.150603 +vt 0.699388 0.776281 +vt 0.698937 0.776550 +vt 0.950446 0.151474 +vt 0.698808 0.776348 +vt 0.950768 0.151914 +vt 0.951046 0.151772 +vt 0.951363 0.151541 +vt 0.951706 0.151231 +vt 0.952061 0.150852 +vt 0.699202 0.775988 +vt 0.951684 0.151835 +vt 0.951978 0.151480 +vt 0.699533 0.775669 +vt 0.699229 0.775353 +vt 0.698963 0.775739 +vt 0.698643 0.776177 +vt 0.951146 0.152260 +vt 0.951403 0.152098 +vt 0.951566 0.152499 +vt 0.951798 0.152323 +vt 0.952040 0.152037 +vt 0.699431 0.775032 +vt 0.699009 0.774740 +vt 0.698869 0.775104 +vt 0.698680 0.775544 +vt 0.698449 0.776042 +vt 0.698538 0.774538 +vt 0.698469 0.774933 +vt 0.698366 0.775409 +vt 0.698233 0.775950 +vt 0.952012 0.152621 +vt 0.952219 0.152438 +vt 0.699093 0.774465 +vt 0.698570 0.774242 +vt 0.698564 0.774053 +vn -0.0000 -0.0450 -0.9990 +vn 0.0000 0.0521 -0.9986 +vn 0.0191 0.0503 -0.9986 +vn 0.0374 0.0447 -0.9983 +vn 0.0543 0.0358 -0.9979 +vn 0.0691 0.0237 -0.9973 +vn 0.0813 0.0090 -0.9967 +vn 0.0902 -0.0077 -0.9959 +vn 0.0958 -0.0259 -0.9951 +vn 0.0977 -0.0447 -0.9942 +vn 0.0958 -0.0636 -0.9934 +vn 0.0902 -0.0818 -0.9926 +vn 0.0812 -0.0985 -0.9918 +vn 0.0691 -0.1132 -0.9912 +vn 0.0544 -0.1252 -0.9906 +vn 0.0374 -0.1342 -0.9902 +vn 0.0190 -0.1397 -0.9900 +vn -0.0000 -0.1416 -0.9899 +vn -0.0190 -0.1397 -0.9900 +vn -0.0374 -0.1342 -0.9902 +vn -0.0543 -0.1252 -0.9906 +vn -0.0691 -0.1132 -0.9912 +vn -0.0812 -0.0985 -0.9918 +vn -0.0902 -0.0818 -0.9926 +vn -0.0958 -0.0636 -0.9934 +vn -0.0977 -0.0447 -0.9942 +vn -0.0958 -0.0259 -0.9951 +vn -0.0903 -0.0077 -0.9959 +vn -0.0812 0.0090 -0.9967 +vn -0.0691 0.0237 -0.9973 +vn -0.0543 0.0358 -0.9979 +vn -0.0374 0.0448 -0.9983 +vn -0.0191 0.0503 -0.9986 +vn -0.0000 0.7319 -0.6814 +vn -0.0000 0.8155 -0.5787 +vn 0.1652 0.7992 -0.5779 +vn 0.1498 0.7171 -0.6807 +vn -0.0000 0.5495 -0.8355 +vn 0.1153 0.5382 -0.8349 +vn 0.0000 0.3934 -0.9194 +vn 0.0854 0.3850 -0.9190 +vn -0.0000 0.2633 -0.9647 +vn 0.0602 0.2574 -0.9644 +vn 0.0000 0.1520 -0.9884 +vn 0.0386 0.1482 -0.9882 +vn 0.0757 0.1370 -0.9877 +vn 0.3239 0.7510 -0.5754 +vn 0.2936 0.6735 -0.6784 +vn 0.2261 0.5047 -0.8331 +vn 0.1675 0.3603 -0.9177 +vn 0.1182 0.2400 -0.9636 +vn 0.4259 0.6027 -0.6747 +vn 0.3282 0.4504 -0.8303 +vn 0.2431 0.3201 -0.9157 +vn 0.1716 0.2116 -0.9622 +vn 0.1099 0.1189 -0.9868 +vn 0.4698 0.6729 -0.5713 +vn 0.1398 0.0945 -0.9857 +vn 0.5974 0.5681 -0.5660 +vn 0.5416 0.5078 -0.6699 +vn 0.4174 0.3774 -0.8266 +vn 0.3093 0.2661 -0.9130 +vn 0.2183 0.1736 -0.9603 +vn 0.4906 0.2885 -0.8222 +vn 0.3636 0.2003 -0.9098 +vn 0.2566 0.1271 -0.9581 +vn 0.1644 0.0648 -0.9843 +vn 0.7017 0.4408 -0.5597 +vn 0.6363 0.3924 -0.6642 +vn 0.7791 0.2958 -0.5527 +vn 0.7065 0.2610 -0.6578 +vn 0.5448 0.1873 -0.8173 +vn 0.4039 0.1253 -0.9062 +vn 0.2851 0.0743 -0.9556 +vn 0.1826 0.0309 -0.9827 +vn 0.4286 0.0441 -0.9024 +vn 0.3026 0.0169 -0.9530 +vn 0.1939 -0.0059 -0.9810 +vn 0.8266 0.1389 -0.5453 +vn 0.7496 0.1188 -0.6511 +vn 0.5782 0.0777 -0.8122 +vn 0.8427 -0.0242 -0.5379 +vn 0.7642 -0.0290 -0.6444 +vn 0.5895 -0.0363 -0.8070 +vn 0.4370 -0.0404 -0.8985 +vn 0.3086 -0.0428 -0.9502 +vn 0.1977 -0.0441 -0.9793 +vn 0.4286 -0.1249 -0.8948 +vn 0.3026 -0.1024 -0.9476 +vn 0.1939 -0.0823 -0.9776 +vn 0.8267 -0.1873 -0.5306 +vn 0.7496 -0.1768 -0.6378 +vn 0.5782 -0.1503 -0.8019 +vn 0.7791 -0.3443 -0.5239 +vn 0.7065 -0.3191 -0.6317 +vn 0.5448 -0.2600 -0.7972 +vn 0.4039 -0.2062 -0.8913 +vn 0.2851 -0.1598 -0.9451 +vn 0.1826 -0.1190 -0.9759 +vn 0.2566 -0.2127 -0.9428 +vn 0.1644 -0.1529 -0.9745 +vn 0.7017 -0.4892 -0.5179 +vn 0.6363 -0.4505 -0.6263 +vn 0.4906 -0.3612 -0.7930 +vn 0.3636 -0.2812 -0.8881 +vn 0.5973 -0.6167 -0.5127 +vn 0.5416 -0.5659 -0.6216 +vn 0.4175 -0.4501 -0.7894 +vn 0.3093 -0.3470 -0.8854 +vn 0.2183 -0.2591 -0.9409 +vn 0.1398 -0.1826 -0.9732 +vn 0.1715 -0.2972 -0.9393 +vn 0.1099 -0.2070 -0.9721 +vn 0.4698 -0.7215 -0.5086 +vn 0.4259 -0.6609 -0.6179 +vn 0.3282 -0.5231 -0.7865 +vn 0.2431 -0.4010 -0.8832 +vn 0.2936 -0.7317 -0.6152 +vn 0.2262 -0.5775 -0.7844 +vn 0.1675 -0.4412 -0.8816 +vn 0.1182 -0.3255 -0.9381 +vn 0.0757 -0.2251 -0.9714 +vn 0.3239 -0.7997 -0.5056 +vn 0.0386 -0.2363 -0.9709 +vn 0.1652 -0.8479 -0.5038 +vn 0.1498 -0.7754 -0.6135 +vn 0.1153 -0.6110 -0.7832 +vn 0.0854 -0.4660 -0.8807 +vn 0.0603 -0.3430 -0.9374 +vn 0.0000 -0.6224 -0.7827 +vn 0.0000 -0.4744 -0.8803 +vn -0.0000 -0.3489 -0.9372 +vn 0.0000 -0.2401 -0.9708 +vn -0.0000 -0.8642 -0.5031 +vn -0.0000 -0.7902 -0.6129 +vn 0.0000 -0.7901 -0.6130 +vn -0.1652 -0.8479 -0.5038 +vn -0.1498 -0.7754 -0.6135 +vn -0.1153 -0.6110 -0.7832 +vn -0.0854 -0.4660 -0.8807 +vn -0.0603 -0.3430 -0.9374 +vn -0.0386 -0.2363 -0.9709 +vn -0.2261 -0.5775 -0.7845 +vn -0.1675 -0.4412 -0.8816 +vn -0.1182 -0.3255 -0.9381 +vn -0.0757 -0.2252 -0.9714 +vn -0.3239 -0.7997 -0.5056 +vn -0.2936 -0.7317 -0.6151 +vn -0.2262 -0.5775 -0.7844 +vn -0.4698 -0.7216 -0.5086 +vn -0.4259 -0.6609 -0.6179 +vn -0.3282 -0.5231 -0.7865 +vn -0.2431 -0.4010 -0.8832 +vn -0.1716 -0.2972 -0.9393 +vn -0.1099 -0.2070 -0.9721 +vn -0.3093 -0.3470 -0.8854 +vn -0.2183 -0.2591 -0.9409 +vn -0.1398 -0.1826 -0.9732 +vn -0.5973 -0.6167 -0.5128 +vn -0.5416 -0.5659 -0.6216 +vn -0.4174 -0.4501 -0.7894 +vn -0.7017 -0.4892 -0.5179 +vn -0.6363 -0.4504 -0.6263 +vn -0.4906 -0.3612 -0.7930 +vn -0.3636 -0.2812 -0.8881 +vn -0.2567 -0.2127 -0.9428 +vn -0.2566 -0.2127 -0.9428 +vn -0.1644 -0.1529 -0.9745 +vn -0.4039 -0.2062 -0.8913 +vn -0.2851 -0.1598 -0.9451 +vn -0.1827 -0.1190 -0.9759 +vn -0.7791 -0.3442 -0.5240 +vn -0.7065 -0.3191 -0.6318 +vn -0.5448 -0.2600 -0.7972 +vn -0.8266 -0.1873 -0.5306 +vn -0.7496 -0.1768 -0.6378 +vn -0.5782 -0.1503 -0.8019 +vn -0.4287 -0.1249 -0.8948 +vn -0.3027 -0.1024 -0.9476 +vn -0.3026 -0.1024 -0.9476 +vn -0.1939 -0.0823 -0.9776 +vn -0.3085 -0.0428 -0.9503 +vn -0.1977 -0.0441 -0.9793 +vn -0.8427 -0.0242 -0.5379 +vn -0.7642 -0.0290 -0.6444 +vn -0.5895 -0.0363 -0.8070 +vn -0.4370 -0.0404 -0.8985 +vn -0.7496 0.1188 -0.6511 +vn -0.5782 0.0777 -0.8122 +vn -0.4286 0.0441 -0.9024 +vn -0.3026 0.0169 -0.9530 +vn -0.1939 -0.0059 -0.9810 +vn -0.8266 0.1388 -0.5453 +vn -0.1826 0.0309 -0.9827 +vn -0.7791 0.2958 -0.5527 +vn -0.7065 0.2610 -0.6579 +vn -0.5448 0.1874 -0.8173 +vn -0.4039 0.1254 -0.9062 +vn -0.2851 0.0743 -0.9556 +vn -0.2851 0.0742 -0.9556 +vn -0.6363 0.3924 -0.6642 +vn -0.4906 0.2885 -0.8222 +vn -0.3636 0.2003 -0.9098 +vn -0.2567 0.1272 -0.9581 +vn -0.2566 0.1271 -0.9581 +vn -0.1644 0.0648 -0.9843 +vn -0.7017 0.4407 -0.5598 +vn -0.1398 0.0945 -0.9857 +vn -0.5973 0.5681 -0.5661 +vn -0.5416 0.5078 -0.6699 +vn -0.4174 0.3773 -0.8267 +vn -0.3093 0.2661 -0.9130 +vn -0.2183 0.1735 -0.9603 +vn -0.2182 0.1735 -0.9603 +vn -0.3282 0.4504 -0.8303 +vn -0.2431 0.3201 -0.9157 +vn -0.1715 0.2116 -0.9622 +vn -0.1099 0.1189 -0.9868 +vn -0.4698 0.6730 -0.5713 +vn -0.4259 0.6028 -0.6747 +vn -0.3238 0.7510 -0.5754 +vn -0.2936 0.6735 -0.6784 +vn -0.2261 0.5047 -0.8331 +vn -0.1675 0.3603 -0.9177 +vn -0.1182 0.2400 -0.9636 +vn -0.0757 0.1370 -0.9877 +vn -0.1153 0.5382 -0.8349 +vn -0.0854 0.3850 -0.9190 +vn -0.0603 0.2574 -0.9644 +vn -0.0386 0.1482 -0.9882 +vn -0.1652 0.7993 -0.5778 +vn -0.1498 0.7172 -0.6806 +vn -0.1497 0.7171 -0.6807 +usemtl Scene_-_Root +s 1 +f 38290/38290/27940 38291/38291/27941 38292/38292/27942 +f 38290/38290/27940 38292/38292/27942 38293/38293/27943 +f 38290/38290/27940 38293/38293/27943 38294/38294/27944 +f 38290/38290/27940 38294/38294/27944 38295/38295/27945 +f 38290/38290/27940 38295/38295/27945 38296/38296/27946 +f 38290/38290/27940 38296/38296/27946 38297/38297/27947 +f 38290/38290/27940 38297/38297/27947 38298/38298/27948 +f 38290/38290/27940 38298/38298/27948 38299/38299/27949 +f 38290/38290/27940 38299/38299/27949 38300/38300/27950 +f 38290/38290/27940 38300/38300/27950 38301/38301/27951 +f 38290/38290/27940 38301/38301/27951 38302/38302/27952 +f 38290/38290/27940 38302/38302/27952 38303/38303/27953 +f 38290/38290/27940 38303/38303/27953 38304/38304/27954 +f 38290/38290/27940 38304/38304/27954 38305/38305/27955 +f 38290/38290/27940 38305/38305/27955 38306/38306/27956 +f 38290/38290/27940 38306/38306/27956 38307/38307/27957 +f 38290/38290/27940 38307/38307/27957 38308/38308/27958 +f 38290/38290/27940 38308/38308/27958 38309/38309/27959 +f 38290/38290/27940 38309/38309/27959 38310/38310/27960 +f 38290/38290/27940 38310/38310/27960 38311/38311/27961 +f 38290/38290/27940 38311/38311/27961 38312/38312/27962 +f 38290/38290/27940 38312/38312/27962 38313/38313/27963 +f 38290/38290/27940 38313/38313/27963 38314/38314/27964 +f 38290/38290/27940 38314/38314/27964 38315/38315/27965 +f 38290/38290/27940 38315/38315/27965 38316/38316/27966 +f 38290/38290/27940 38316/38316/27966 38317/38317/27967 +f 38290/38290/27940 38317/38317/27967 38318/38318/27968 +f 38290/38290/27940 38318/38318/27968 38319/38319/27969 +f 38290/38290/27940 38319/38319/27969 38320/38320/27970 +f 38290/38290/27940 38320/38320/27970 38321/38321/27971 +f 38290/38290/27940 38321/38321/27971 38322/38322/27972 +f 38290/38290/27940 38322/38322/27972 38291/38291/27941 +f 38323/38323/27973 38324/38324/27974 38325/38325/27975 +f 38323/38323/27973 38325/38325/27975 38326/38326/27976 +f 38327/38327/27977 38323/38323/27973 38326/38326/27976 +f 38327/38327/27977 38326/38326/27976 38328/38328/27978 +f 38329/38329/27979 38327/38327/27977 38328/38328/27978 +f 38329/38329/27979 38328/38328/27978 38330/38330/27980 +f 38331/38331/27981 38329/38329/27979 38330/38330/27980 +f 38331/38331/27981 38330/38330/27980 38332/38332/27982 +f 38333/38333/27983 38331/38331/27981 38332/38332/27982 +f 38333/38333/27983 38332/38332/27982 38334/38334/27984 +f 38291/38291/27941 38333/38333/27983 38334/38334/27984 +f 38291/38291/27941 38334/38334/27984 38292/38292/27942 +f 38292/38292/27942 38334/38334/27984 38335/38335/27985 +f 38292/38292/27942 38335/38335/27985 38293/38293/27943 +f 38326/38326/27976 38325/38325/27975 38336/38336/27986 +f 38326/38326/27976 38336/38336/27986 38337/38337/27987 +f 38328/38328/27978 38326/38326/27976 38337/38337/27987 +f 38328/38328/27978 38337/38337/27987 38338/38338/27988 +f 38330/38330/27980 38328/38328/27978 38338/38338/27988 +f 38330/38330/27980 38338/38338/27988 38339/38339/27989 +f 38332/38332/27982 38330/38330/27980 38339/38339/27989 +f 38332/38332/27982 38339/38339/27989 38340/38340/27990 +f 38334/38334/27984 38332/38332/27982 38340/38340/27990 +f 38334/38334/27984 38340/38340/27990 38335/38335/27985 +f 38338/38338/27988 38337/38337/27987 38341/38341/27991 +f 38338/38338/27988 38341/38341/27991 38342/38342/27992 +f 38339/38339/27989 38338/38338/27988 38342/38342/27992 +f 38339/38339/27989 38342/38342/27992 38343/38343/27993 +f 38340/38340/27990 38339/38339/27989 38343/38343/27993 +f 38340/38340/27990 38343/38343/27993 38344/38344/27994 +f 38335/38335/27985 38340/38340/27990 38344/38344/27994 +f 38335/38335/27985 38344/38344/27994 38345/38345/27995 +f 38293/38293/27943 38335/38335/27985 38345/38345/27995 +f 38293/38293/27943 38345/38345/27995 38294/38294/27944 +f 38337/38337/27987 38336/38336/27986 38346/38346/27996 +f 38337/38337/27987 38346/38346/27996 38341/38341/27991 +f 38294/38294/27944 38345/38345/27995 38347/38347/27997 +f 38294/38294/27944 38347/38347/27997 38295/38295/27945 +f 38341/38341/27991 38346/38346/27996 38348/38348/27998 +f 38341/38341/27991 38348/38348/27998 38349/38349/27999 +f 38342/38342/27992 38341/38341/27991 38349/38349/27999 +f 38342/38342/27992 38349/38349/27999 38350/38350/28000 +f 38343/38343/27993 38342/38342/27992 38350/38350/28000 +f 38343/38343/27993 38350/38350/28000 38351/38351/28001 +f 38344/38344/27994 38343/38343/27993 38351/38351/28001 +f 38344/38344/27994 38351/38351/28001 38352/38352/28002 +f 38345/38345/27995 38344/38344/27994 38352/38352/28002 +f 38345/38345/27995 38352/38352/28002 38347/38347/27997 +f 38351/38351/28001 38350/38350/28000 38353/38353/28003 +f 38351/38351/28001 38353/38353/28003 38354/38354/28004 +f 38352/38352/28002 38351/38351/28001 38354/38354/28004 +f 38352/38352/28002 38354/38354/28004 38355/38355/28005 +f 38347/38347/27997 38352/38352/28002 38355/38355/28005 +f 38347/38347/27997 38355/38355/28005 38356/38356/28006 +f 38295/38295/27945 38347/38347/27997 38356/38356/28006 +f 38295/38295/27945 38356/38356/28006 38296/38296/27946 +f 38349/38349/27999 38348/38348/27998 38357/38357/28007 +f 38349/38349/27999 38357/38357/28007 38358/38358/28008 +f 38350/38350/28000 38349/38349/27999 38358/38358/28008 +f 38350/38350/28000 38358/38358/28008 38353/38353/28003 +f 38358/38358/28008 38357/38357/28007 38359/38359/28009 +f 38358/38358/28008 38359/38359/28009 38360/38360/28010 +f 38353/38353/28003 38358/38358/28008 38360/38360/28010 +f 38353/38353/28003 38360/38360/28010 38361/38361/28011 +f 38354/38354/28004 38353/38353/28003 38361/38361/28011 +f 38354/38354/28004 38361/38361/28011 38362/38362/28012 +f 38355/38355/28005 38354/38354/28004 38362/38362/28012 +f 38355/38355/28005 38362/38362/28012 38363/38363/28013 +f 38356/38356/28006 38355/38355/28005 38363/38363/28013 +f 38356/38356/28006 38363/38363/28013 38364/38364/28014 +f 38296/38296/27946 38356/38356/28006 38364/38364/28014 +f 38296/38296/27946 38364/38364/28014 38297/38297/27947 +f 38363/38363/28013 38362/38362/28012 38365/38365/28015 +f 38363/38363/28013 38365/38365/28015 38366/38366/28016 +f 38364/38364/28014 38363/38363/28013 38366/38366/28016 +f 38364/38364/28014 38366/38366/28016 38367/38367/28017 +f 38297/38297/27947 38364/38364/28014 38367/38367/28017 +f 38297/38297/27947 38367/38367/28017 38298/38298/27948 +f 38360/38360/28010 38359/38359/28009 38368/38368/28018 +f 38360/38360/28010 38368/38368/28018 38369/38369/28019 +f 38361/38361/28011 38360/38360/28010 38369/38369/28019 +f 38361/38361/28011 38369/38369/28019 38370/38370/28020 +f 38362/38362/28012 38361/38361/28011 38370/38370/28020 +f 38362/38362/28012 38370/38370/28020 38365/38365/28015 +f 38369/38369/28019 38368/38368/28018 38371/38371/28021 +f 38369/38369/28019 38371/38371/28021 38372/38372/28022 +f 38370/38370/28020 38369/38369/28019 38372/38372/28022 +f 38370/38370/28020 38372/38372/28022 38373/38373/28023 +f 38365/38365/28015 38370/38370/28020 38373/38373/28023 +f 38365/38365/28015 38373/38373/28023 38374/38374/28024 +f 38366/38366/28016 38365/38365/28015 38374/38374/28024 +f 38366/38366/28016 38374/38374/28024 38375/38375/28025 +f 38367/38367/28017 38366/38366/28016 38375/38375/28025 +f 38367/38367/28017 38375/38375/28025 38376/38376/28026 +f 38298/38298/27948 38367/38367/28017 38376/38376/28026 +f 38298/38298/27948 38376/38376/28026 38299/38299/27949 +f 38375/38375/28025 38374/38374/28024 38377/38377/28027 +f 38375/38375/28025 38377/38377/28027 38378/38378/28028 +f 38376/38376/28026 38375/38375/28025 38378/38378/28028 +f 38376/38376/28026 38378/38378/28028 38379/38379/28029 +f 38299/38299/27949 38376/38376/28026 38379/38379/28029 +f 38299/38299/27949 38379/38379/28029 38300/38300/27950 +f 38372/38372/28022 38371/38371/28021 38380/38380/28030 +f 38372/38372/28022 38380/38380/28030 38381/38381/28031 +f 38373/38373/28023 38372/38372/28022 38381/38381/28031 +f 38373/38373/28023 38381/38381/28031 38382/38382/28032 +f 38374/38374/28024 38373/38373/28023 38382/38382/28032 +f 38374/38374/28024 38382/38382/28032 38377/38377/28027 +f 38381/38381/28031 38380/38380/28030 38383/38383/28033 +f 38381/38381/28031 38383/38383/28033 38384/38384/28034 +f 38382/38382/28032 38381/38381/28031 38384/38384/28034 +f 38382/38382/28032 38384/38384/28034 38385/38385/28035 +f 38377/38377/28027 38382/38382/28032 38385/38385/28035 +f 38377/38377/28027 38385/38385/28035 38386/38386/28036 +f 38378/38378/28028 38377/38377/28027 38386/38386/28036 +f 38378/38378/28028 38386/38386/28036 38387/38387/28037 +f 38379/38379/28029 38378/38378/28028 38387/38387/28037 +f 38379/38379/28029 38387/38387/28037 38388/38388/28038 +f 38300/38300/27950 38379/38379/28029 38388/38388/28038 +f 38300/38300/27950 38388/38388/28038 38301/38301/27951 +f 38388/38388/28038 38387/38387/28037 38389/38389/28039 +f 38388/38388/28038 38389/38389/28039 38390/38390/28040 +f 38301/38301/27951 38388/38388/28038 38390/38390/28040 +f 38301/38301/27951 38390/38390/28040 38302/38302/27952 +f 38384/38384/28034 38383/38383/28033 38391/38391/28041 +f 38384/38384/28034 38391/38391/28041 38392/38392/28042 +f 38385/38385/28035 38384/38384/28034 38392/38392/28042 +f 38385/38385/28035 38392/38392/28042 38393/38393/28043 +f 38386/38386/28036 38385/38385/28035 38393/38393/28043 +f 38386/38386/28036 38393/38393/28043 38394/38394/28044 +f 38387/38387/28037 38386/38386/28036 38394/38394/28044 +f 38387/38387/28037 38394/38394/28044 38389/38389/28039 +f 38392/38392/28042 38391/38391/28041 38395/38395/28045 +f 38392/38392/28042 38395/38395/28045 38396/38396/28046 +f 38393/38393/28043 38392/38392/28042 38396/38396/28046 +f 38393/38393/28043 38396/38396/28046 38397/38397/28047 +f 38394/38394/28044 38393/38393/28043 38397/38397/28047 +f 38394/38394/28044 38397/38397/28047 38398/38398/28048 +f 38389/38389/28039 38394/38394/28044 38398/38398/28048 +f 38389/38389/28039 38398/38398/28048 38399/38399/28049 +f 38390/38390/28040 38389/38389/28039 38399/38399/28049 +f 38390/38390/28040 38399/38399/28049 38400/38400/28050 +f 38302/38302/27952 38390/38390/28040 38400/38400/28050 +f 38302/38302/27952 38400/38400/28050 38303/38303/27953 +f 38400/38400/28050 38399/38399/28049 38401/38401/28051 +f 38400/38400/28050 38401/38401/28051 38402/38402/28052 +f 38303/38303/27953 38400/38400/28050 38402/38402/28052 +f 38303/38303/27953 38402/38402/28052 38304/38304/27954 +f 38396/38396/28046 38395/38395/28045 38403/38403/28053 +f 38396/38396/28046 38403/38403/28053 38404/38404/28054 +f 38397/38397/28047 38396/38396/28046 38404/38404/28054 +f 38397/38397/28047 38404/38404/28054 38405/38405/28055 +f 38398/38398/28048 38397/38397/28047 38405/38405/28055 +f 38398/38398/28048 38405/38405/28055 38406/38406/28056 +f 38399/38399/28049 38398/38398/28048 38406/38406/28056 +f 38399/38399/28049 38406/38406/28056 38401/38401/28051 +f 38405/38405/28055 38404/38404/28054 38407/38407/28057 +f 38405/38405/28055 38407/38407/28057 38408/38408/28058 +f 38406/38406/28056 38405/38405/28055 38408/38408/28058 +f 38406/38406/28056 38408/38408/28058 38409/38409/28059 +f 38401/38401/28051 38406/38406/28056 38409/38409/28059 +f 38401/38401/28051 38409/38409/28059 38410/38410/28060 +f 38402/38402/28052 38401/38401/28051 38410/38410/28060 +f 38402/38402/28052 38410/38410/28060 38411/38411/28061 +f 38304/38304/27954 38402/38402/28052 38411/38411/28061 +f 38304/38304/27954 38411/38411/28061 38305/38305/27955 +f 38404/38404/28054 38403/38403/28053 38412/38412/28062 +f 38404/38404/28054 38412/38412/28062 38407/38407/28057 +f 38305/38305/27955 38411/38411/28061 38413/38413/28063 +f 38305/38305/27955 38413/38413/28063 38306/38306/27956 +f 38407/38407/28057 38412/38412/28062 38414/38414/28064 +f 38407/38407/28057 38414/38414/28064 38415/38415/28065 +f 38408/38408/28058 38407/38407/28057 38415/38415/28065 +f 38408/38408/28058 38415/38415/28065 38416/38416/28066 +f 38409/38409/28059 38408/38408/28058 38416/38416/28066 +f 38409/38409/28059 38416/38416/28066 38417/38417/28067 +f 38410/38410/28060 38409/38409/28059 38417/38417/28067 +f 38410/38410/28060 38417/38417/28067 38418/38418/28068 +f 38411/38411/28061 38410/38410/28060 38418/38418/28068 +f 38411/38411/28061 38418/38418/28068 38413/38413/28063 +f 38417/38417/28067 38416/38416/28066 38419/38419/28069 +f 38417/38417/28067 38419/38419/28069 38420/38420/28070 +f 38418/38418/28068 38417/38417/28067 38420/38420/28070 +f 38418/38418/28068 38420/38420/28070 38421/38421/28071 +f 38413/38413/28063 38418/38418/28068 38421/38421/28071 +f 38413/38413/28063 38421/38421/28071 38422/38422/28072 +f 38306/38306/27956 38413/38413/28063 38422/38422/28072 +f 38306/38306/27956 38422/38422/28072 38307/38307/27957 +f 38415/38415/28065 38414/38414/28064 38423/38423/28073 +f 38415/38415/28065 38423/38423/28073 38424/38424/28074 +f 38416/38416/28066 38415/38415/28065 38424/38424/28074 +f 38416/38416/28066 38424/38424/28074 38419/38419/28069 +f 38425/38425/28075 38426/38426/28073 38427/38427/28076 +f 38425/38425/28075 38427/38427/28076 38428/38428/28077 +f 38419/38419/28069 38424/38424/28074 38429/38429/28077 +f 38419/38419/28069 38429/38429/28077 38430/38430/28078 +f 38420/38420/28070 38419/38419/28069 38430/38430/28078 +f 38420/38420/28070 38430/38430/28078 38431/38431/28079 +f 38421/38421/28071 38420/38420/28070 38431/38431/28079 +f 38421/38421/28071 38431/38431/28079 38432/38432/28080 +f 38422/38422/28072 38421/38421/28071 38432/38432/28080 +f 38422/38422/28072 38432/38432/28080 38433/38433/28081 +f 38307/38307/27957 38422/38422/28072 38433/38433/28081 +f 38307/38307/27957 38433/38433/28081 38308/38308/27958 +f 38431/38431/28079 38430/38430/28078 38434/38434/28082 +f 38431/38431/28079 38434/38434/28082 38435/38435/28083 +f 38432/38432/28080 38431/38431/28079 38435/38435/28083 +f 38432/38432/28080 38435/38435/28083 38436/38436/28084 +f 38433/38433/28081 38432/38432/28080 38436/38436/28084 +f 38433/38433/28081 38436/38436/28084 38437/38437/28085 +f 38308/38308/27958 38433/38433/28081 38437/38437/28085 +f 38308/38308/27958 38437/38437/28085 38309/38309/27959 +f 38428/38428/28077 38427/38427/28076 38438/38438/28086 +f 38428/38428/28077 38438/38438/28086 38439/38439/28087 +f 38440/38440/28078 38428/38428/28077 38439/38439/28087 +f 38440/38440/28078 38439/38439/28087 38441/38441/28088 +f 38439/38439/28087 38438/38438/28086 38442/38442/28089 +f 38439/38439/28087 38442/38442/28089 38443/38443/28090 +f 38441/38441/28088 38439/38439/28087 38443/38443/28090 +f 38441/38441/28088 38443/38443/28090 38444/38444/28091 +f 38445/38445/28083 38441/38441/28088 38444/38444/28091 +f 38445/38445/28083 38444/38444/28091 38446/38446/28092 +f 38436/38436/28084 38435/38435/28083 38447/38447/28092 +f 38436/38436/28084 38447/38447/28092 38448/38448/28093 +f 38437/38437/28085 38436/38436/28084 38448/38448/28093 +f 38437/38437/28085 38448/38448/28093 38449/38449/28094 +f 38309/38309/27959 38437/38437/28085 38449/38449/28094 +f 38309/38309/27959 38449/38449/28094 38310/38310/27960 +f 38450/38450/28093 38446/38446/28092 38451/38451/28095 +f 38450/38450/28093 38451/38451/28095 38452/38452/28096 +f 38449/38449/28094 38448/38448/28093 38453/38453/28096 +f 38449/38449/28094 38453/38453/28096 38454/38454/28097 +f 38310/38310/27960 38449/38449/28094 38454/38454/28097 +f 38310/38310/27960 38454/38454/28097 38311/38311/27961 +f 38443/38443/28090 38442/38442/28089 38455/38455/28098 +f 38443/38443/28090 38455/38455/28098 38456/38456/28099 +f 38444/38444/28091 38443/38443/28090 38456/38456/28099 +f 38444/38444/28091 38456/38456/28099 38457/38457/28100 +f 38446/38446/28092 38444/38444/28091 38457/38457/28100 +f 38446/38446/28092 38457/38457/28100 38451/38451/28095 +f 38456/38456/28099 38455/38455/28098 38458/38458/28101 +f 38456/38456/28099 38458/38458/28101 38459/38459/28102 +f 38457/38457/28100 38456/38456/28099 38459/38459/28102 +f 38457/38457/28100 38459/38459/28102 38460/38460/28103 +f 38451/38451/28095 38457/38457/28100 38460/38460/28103 +f 38451/38451/28095 38460/38460/28103 38461/38461/28104 +f 38452/38452/28096 38451/38451/28095 38461/38461/28104 +f 38452/38452/28096 38461/38461/28104 38462/38462/28105 +f 38454/38454/28097 38453/38453/28096 38463/38463/28106 +f 38454/38454/28097 38463/38463/28106 38464/38464/28107 +f 38311/38311/27961 38454/38454/28097 38464/38464/28107 +f 38311/38311/27961 38464/38464/28107 38312/38312/27962 +f 38462/38462/28105 38461/38461/28104 38465/38465/28108 +f 38462/38462/28105 38465/38465/28108 38466/38466/28109 +f 38464/38464/28107 38463/38463/28106 38467/38467/28109 +f 38464/38464/28107 38467/38467/28109 38468/38468/28110 +f 38312/38312/27962 38464/38464/28107 38468/38468/28110 +f 38312/38312/27962 38468/38468/28110 38313/38313/27963 +f 38459/38459/28102 38458/38458/28101 38469/38469/28111 +f 38459/38459/28102 38469/38469/28111 38470/38470/28112 +f 38460/38460/28103 38459/38459/28102 38470/38470/28112 +f 38460/38460/28103 38470/38470/28112 38471/38471/28113 +f 38461/38461/28104 38460/38460/28103 38471/38471/28113 +f 38461/38461/28104 38471/38471/28113 38465/38465/28108 +f 38470/38470/28112 38469/38469/28111 38472/38472/28114 +f 38470/38470/28112 38472/38472/28114 38473/38473/28115 +f 38471/38471/28113 38470/38470/28112 38473/38473/28115 +f 38471/38471/28113 38473/38473/28115 38474/38474/28116 +f 38465/38465/28108 38471/38471/28113 38474/38474/28116 +f 38465/38465/28108 38474/38474/28116 38475/38475/28117 +f 38466/38466/28109 38465/38465/28108 38475/38475/28117 +f 38466/38466/28109 38475/38475/28117 38476/38476/28118 +f 38468/38468/28110 38467/38467/28109 38477/38477/28119 +f 38468/38468/28110 38477/38477/28119 38478/38478/28120 +f 38313/38313/27963 38468/38468/28110 38478/38478/28120 +f 38313/38313/27963 38478/38478/28120 38314/38314/27964 +f 38478/38478/28120 38477/38477/28119 38479/38479/28121 +f 38478/38478/28120 38479/38479/28121 38480/38480/28122 +f 38314/38314/27964 38478/38478/28120 38480/38480/28122 +f 38314/38314/27964 38480/38480/28122 38315/38315/27965 +f 38473/38473/28115 38472/38472/28114 38481/38481/28123 +f 38473/38473/28115 38481/38481/28123 38482/38482/28124 +f 38474/38474/28116 38473/38473/28115 38482/38482/28124 +f 38474/38474/28116 38482/38482/28124 38483/38483/28125 +f 38475/38475/28117 38474/38474/28116 38483/38483/28125 +f 38475/38475/28117 38483/38483/28125 38484/38484/28126 +f 38476/38476/28118 38475/38475/28117 38484/38484/28126 +f 38476/38476/28118 38484/38484/28126 38485/38485/28121 +f 38483/38483/28125 38482/38482/28124 38486/38486/28127 +f 38483/38483/28125 38486/38486/28127 38487/38487/28128 +f 38484/38484/28126 38483/38483/28125 38487/38487/28128 +f 38484/38484/28126 38487/38487/28128 38488/38488/28129 +f 38485/38485/28121 38484/38484/28126 38488/38488/28129 +f 38485/38485/28121 38488/38488/28129 38489/38489/28130 +f 38480/38480/28122 38479/38479/28121 38490/38490/28130 +f 38480/38480/28122 38490/38490/28130 38491/38491/28131 +f 38315/38315/27965 38480/38480/28122 38491/38491/28131 +f 38315/38315/27965 38491/38491/28131 38316/38316/27966 +f 38482/38482/28124 38481/38481/28123 38492/38492/28132 +f 38482/38482/28124 38492/38492/28132 38486/38486/28127 +f 38316/38316/27966 38491/38491/28131 38493/38493/28133 +f 38316/38316/27966 38493/38493/28133 38317/38317/27967 +f 38486/38486/28127 38492/38492/28132 38494/38494/28134 +f 38486/38486/28127 38494/38494/28134 38495/38495/28135 +f 38487/38487/28128 38486/38486/28127 38495/38495/28135 +f 38487/38487/28128 38495/38495/28135 38496/38496/28136 +f 38488/38488/28129 38487/38487/28128 38496/38496/28136 +f 38488/38488/28129 38496/38496/28136 38497/38497/28137 +f 38489/38489/28130 38488/38488/28129 38497/38497/28137 +f 38489/38489/28130 38497/38497/28137 38498/38498/28138 +f 38491/38491/28131 38490/38490/28130 38499/38499/28139 +f 38491/38491/28131 38499/38499/28139 38493/38493/28133 +f 38496/38496/28136 38495/38495/28135 38500/38500/28140 +f 38496/38496/28136 38500/38500/28140 38501/38501/28141 +f 38497/38497/28137 38496/38496/28136 38501/38501/28141 +f 38497/38497/28137 38501/38501/28141 38502/38502/28142 +f 38498/38498/28138 38497/38497/28137 38502/38502/28142 +f 38498/38498/28138 38502/38502/28142 38503/38503/28143 +f 38493/38493/28133 38499/38499/28139 38504/38504/28144 +f 38493/38493/28133 38504/38504/28144 38505/38505/28145 +f 38317/38317/27967 38493/38493/28133 38505/38505/28145 +f 38317/38317/27967 38505/38505/28145 38318/38318/27968 +f 38495/38495/28135 38494/38494/28134 38506/38506/28146 +f 38495/38495/28135 38506/38506/28146 38500/38500/28140 +f 38318/38318/27968 38505/38505/28145 38507/38507/28147 +f 38318/38318/27968 38507/38507/28147 38319/38319/27969 +f 38500/38500/28140 38506/38506/28146 38508/38508/28148 +f 38500/38500/28140 38508/38508/28148 38509/38509/28149 +f 38501/38501/28141 38500/38500/28140 38509/38509/28149 +f 38501/38501/28141 38509/38509/28149 38510/38510/28150 +f 38502/38502/28142 38501/38501/28141 38510/38510/28150 +f 38502/38502/28142 38510/38510/28150 38511/38511/28151 +f 38503/38503/28143 38502/38502/28142 38511/38511/28151 +f 38503/38503/28143 38511/38511/28151 38512/38512/28152 +f 38505/38505/28145 38504/38504/28144 38513/38513/28153 +f 38505/38505/28145 38513/38513/28153 38507/38507/28147 +f 38511/38511/28151 38510/38510/28150 38514/38514/28154 +f 38511/38511/28151 38514/38514/28154 38515/38515/28155 +f 38513/38513/28153 38516/38516/28151 38517/38517/28155 +f 38513/38513/28153 38517/38517/28155 38518/38518/28156 +f 38507/38507/28147 38513/38513/28153 38518/38518/28156 +f 38507/38507/28147 38518/38518/28156 38519/38519/28157 +f 38319/38319/27969 38507/38507/28147 38519/38519/28157 +f 38319/38319/27969 38519/38519/28157 38320/38320/27970 +f 38509/38509/28149 38508/38508/28148 38520/38520/28158 +f 38509/38509/28149 38520/38520/28158 38521/38521/28159 +f 38510/38510/28150 38509/38509/28149 38521/38521/28159 +f 38510/38510/28150 38521/38521/28159 38514/38514/28154 +f 38521/38521/28159 38520/38520/28158 38522/38522/28160 +f 38521/38521/28159 38522/38522/28160 38523/38523/28161 +f 38514/38514/28154 38521/38521/28159 38523/38523/28161 +f 38514/38514/28154 38523/38523/28161 38524/38524/28162 +f 38517/38517/28155 38525/38525/28154 38526/38526/28162 +f 38517/38517/28155 38526/38526/28162 38527/38527/28163 +f 38518/38518/28156 38517/38517/28155 38527/38527/28163 +f 38518/38518/28156 38527/38527/28163 38528/38528/28164 +f 38519/38519/28157 38518/38518/28156 38528/38528/28164 +f 38519/38519/28157 38528/38528/28164 38529/38529/28165 +f 38320/38320/27970 38519/38519/28157 38529/38529/28165 +f 38320/38320/27970 38529/38529/28165 38321/38321/27971 +f 38527/38527/28163 38526/38526/28162 38530/38530/28166 +f 38527/38527/28163 38530/38530/28166 38531/38531/28167 +f 38528/38528/28164 38527/38527/28163 38531/38531/28167 +f 38528/38528/28164 38531/38531/28167 38532/38532/28168 +f 38529/38529/28165 38528/38528/28164 38532/38532/28168 +f 38529/38529/28165 38532/38532/28168 38533/38533/28169 +f 38321/38321/27971 38529/38529/28165 38533/38533/28169 +f 38321/38321/27971 38533/38533/28169 38322/38322/27972 +f 38523/38523/28161 38522/38522/28160 38534/38534/28170 +f 38523/38523/28161 38534/38534/28170 38535/38535/28171 +f 38526/38526/28162 38536/38536/28161 38537/38537/28172 +f 38526/38526/28162 38537/38537/28172 38530/38530/28166 +f 38537/38537/28172 38538/38538/28170 38324/38324/27974 +f 38537/38537/28172 38324/38324/27974 38323/38323/27973 +f 38530/38530/28166 38537/38537/28172 38323/38323/27973 +f 38530/38530/28166 38323/38323/27973 38327/38327/27977 +f 38531/38531/28167 38530/38530/28166 38327/38327/27977 +f 38531/38531/28167 38327/38327/27977 38329/38329/27979 +f 38532/38532/28168 38531/38531/28167 38329/38329/27979 +f 38532/38532/28168 38329/38329/27979 38331/38331/27981 +f 38533/38533/28169 38532/38532/28168 38331/38331/27981 +f 38533/38533/28169 38331/38331/27981 38333/38333/27983 +f 38322/38322/27972 38533/38533/28169 38333/38333/27983 +f 38322/38322/27972 38333/38333/27983 38291/38291/27941 +o Sphere.017__0 +v -0.467419 0.868483 -1.037403 +v -0.467419 0.877439 -1.037813 +v -0.465685 0.877268 -1.037797 +v -0.464018 0.876760 -1.037750 +v -0.462482 0.875936 -1.037674 +v -0.461136 0.874827 -1.037572 +v -0.460031 0.873476 -1.037447 +v -0.459210 0.871934 -1.037304 +v -0.458704 0.870261 -1.037150 +v -0.458534 0.868521 -1.036989 +v -0.458704 0.866781 -1.036829 +v -0.459210 0.865108 -1.036674 +v -0.460031 0.863566 -1.036532 +v -0.461136 0.862215 -1.036407 +v -0.462482 0.861106 -1.036305 +v -0.464018 0.860282 -1.036228 +v -0.465685 0.859774 -1.036182 +v -0.467419 0.859603 -1.036166 +v -0.469152 0.859774 -1.036182 +v -0.470819 0.860282 -1.036228 +v -0.472354 0.861106 -1.036305 +v -0.473701 0.862215 -1.036407 +v -0.474806 0.863566 -1.036532 +v -0.475627 0.865108 -1.036674 +v -0.476133 0.866781 -1.036829 +v -0.476304 0.868521 -1.036989 +v -0.476133 0.870261 -1.037150 +v -0.475627 0.871934 -1.037304 +v -0.474806 0.873476 -1.037447 +v -0.473701 0.874827 -1.037572 +v -0.472354 0.875936 -1.037674 +v -0.470819 0.876760 -1.037750 +v -0.469152 0.877268 -1.037797 +v -0.467419 0.911943 -1.028011 +v -0.467419 0.914917 -1.024212 +v -0.458704 0.914056 -1.024133 +v -0.459210 0.911131 -1.027936 +v -0.467419 0.907375 -1.031344 +v -0.460031 0.906645 -1.031276 +v -0.467419 0.901389 -1.034081 +v -0.461136 0.900768 -1.034024 +v -0.467419 0.894214 -1.036119 +v -0.462482 0.893726 -1.036074 +v -0.467419 0.886127 -1.037379 +v -0.464018 0.885791 -1.037348 +v -0.460749 0.884796 -1.037256 +v -0.450325 0.911505 -1.023897 +v -0.451317 0.908728 -1.027714 +v -0.452928 0.904482 -1.031076 +v -0.455095 0.898928 -1.033854 +v -0.457736 0.892281 -1.035941 +v -0.444043 0.904825 -1.027354 +v -0.446381 0.900969 -1.030752 +v -0.449527 0.895941 -1.033578 +v -0.453362 0.889934 -1.035724 +v -0.457736 0.883179 -1.037107 +v -0.442603 0.907361 -1.023515 +v -0.455095 0.881004 -1.036906 +v -0.435834 0.901786 -1.023000 +v -0.437666 0.899573 -1.026869 +v -0.440643 0.896242 -1.030316 +v -0.444647 0.891921 -1.033207 +v -0.449527 0.886776 -1.035433 +v -0.435933 0.890483 -1.029784 +v -0.440643 0.887023 -1.032755 +v -0.446381 0.882927 -1.035077 +v -0.452928 0.878353 -1.036661 +v -0.430279 0.894992 -1.022372 +v -0.432434 0.893173 -1.026278 +v -0.426152 0.887240 -1.021657 +v -0.428545 0.885872 -1.025604 +v -0.432434 0.883912 -1.029177 +v -0.437666 0.881435 -1.032239 +v -0.444043 0.878537 -1.034672 +v -0.451317 0.875329 -1.036382 +v -0.435834 0.875371 -1.031679 +v -0.442603 0.873773 -1.034232 +v -0.450325 0.872047 -1.036079 +v -0.423610 0.878830 -1.020880 +v -0.426152 0.877949 -1.024872 +v -0.430279 0.876782 -1.028519 +v -0.422751 0.870083 -1.020073 +v -0.425343 0.869710 -1.024112 +v -0.429551 0.869366 -1.027834 +v -0.435215 0.869065 -1.031097 +v -0.442116 0.868818 -1.033775 +v -0.449990 0.868634 -1.035764 +v -0.435834 0.862759 -1.030514 +v -0.442603 0.863863 -1.033317 +v -0.450325 0.865221 -1.035449 +v -0.423610 0.861336 -1.019265 +v -0.426152 0.861471 -1.023351 +v -0.430279 0.861951 -1.027149 +v -0.426152 0.852926 -1.018488 +v -0.428545 0.853548 -1.022619 +v -0.432434 0.854821 -1.026491 +v -0.437666 0.856695 -1.029955 +v -0.444043 0.859099 -1.032877 +v -0.451317 0.861940 -1.035146 +v -0.446381 0.854708 -1.032472 +v -0.452928 0.858915 -1.034867 +v -0.430279 0.845175 -1.017773 +v -0.432434 0.846247 -1.021945 +v -0.435933 0.848250 -1.025884 +v -0.440643 0.851107 -1.029439 +v -0.435834 0.838381 -1.017145 +v -0.437666 0.839847 -1.021354 +v -0.440643 0.842490 -1.025352 +v -0.444647 0.846209 -1.028986 +v -0.449527 0.850860 -1.032116 +v -0.455095 0.856264 -1.034622 +v -0.453362 0.847702 -1.031825 +v -0.457736 0.854089 -1.034421 +v -0.442603 0.832805 -1.016630 +v -0.444043 0.834595 -1.020869 +v -0.446381 0.837764 -1.024916 +v -0.449527 0.842189 -1.028615 +v -0.451317 0.830692 -1.020509 +v -0.452928 0.834251 -1.024592 +v -0.455095 0.839202 -1.028339 +v -0.457736 0.845355 -1.031608 +v -0.460749 0.852472 -1.034272 +v -0.450325 0.828662 -1.016248 +v -0.464018 0.851477 -1.034180 +v -0.458704 0.826111 -1.016012 +v -0.459210 0.828289 -1.020287 +v -0.460031 0.832088 -1.024392 +v -0.461136 0.837363 -1.028169 +v -0.462482 0.843910 -1.031475 +v -0.467419 0.831358 -1.024324 +v -0.467419 0.836742 -1.028112 +v -0.467419 0.843421 -1.031430 +v -0.467419 0.851141 -1.034149 +v -0.467419 0.825249 -1.015933 +v -0.467419 0.827477 -1.020212 +v -0.467419 0.827477 -1.020212 +v -0.467419 0.825249 -1.015933 +v -0.476133 0.826111 -1.016012 +v -0.475627 0.828289 -1.020287 +v -0.475627 0.828289 -1.020287 +v -0.474806 0.832088 -1.024392 +v -0.473701 0.837363 -1.028169 +v -0.472354 0.843910 -1.031475 +v -0.470819 0.851477 -1.034180 +v -0.481910 0.834251 -1.024592 +v -0.479742 0.839202 -1.028339 +v -0.477101 0.845355 -1.031608 +v -0.474088 0.852472 -1.034272 +v -0.484512 0.828662 -1.016248 +v -0.483520 0.830692 -1.020509 +v -0.474806 0.832088 -1.024392 +v -0.481910 0.834251 -1.024592 +v -0.492234 0.832805 -1.016630 +v -0.490794 0.834595 -1.020869 +v -0.488456 0.837764 -1.024916 +v -0.479742 0.839202 -1.028339 +v -0.485310 0.842189 -1.028615 +v -0.485310 0.842189 -1.028615 +v -0.481475 0.847702 -1.031825 +v -0.477101 0.854089 -1.034421 +v -0.481475 0.847702 -1.031825 +v -0.490190 0.846209 -1.028986 +v -0.485310 0.850860 -1.032116 +v -0.485310 0.850860 -1.032116 +v -0.479742 0.856264 -1.034622 +v -0.499003 0.838381 -1.017145 +v -0.497170 0.839847 -1.021354 +v -0.494195 0.842490 -1.025352 +v -0.504558 0.845175 -1.017773 +v -0.502403 0.846247 -1.021945 +v -0.498904 0.848250 -1.025884 +v -0.494195 0.851107 -1.029439 +v -0.488456 0.854708 -1.032472 +v -0.488456 0.854708 -1.032472 +v -0.481910 0.858915 -1.034867 +v -0.497170 0.856695 -1.029955 +v -0.490794 0.859099 -1.032877 +v -0.490794 0.859099 -1.032877 +v -0.483520 0.861940 -1.035146 +v -0.508686 0.852926 -1.018488 +v -0.506291 0.853548 -1.022619 +v -0.502403 0.854821 -1.026491 +v -0.511228 0.861336 -1.019265 +v -0.508686 0.861471 -1.023351 +v -0.504558 0.861951 -1.027149 +v -0.499003 0.862759 -1.030514 +v -0.492234 0.863863 -1.033317 +v -0.492234 0.863863 -1.033317 +v -0.484512 0.865222 -1.035449 +v -0.492720 0.868818 -1.033775 +v -0.484847 0.868634 -1.035764 +v -0.512086 0.870083 -1.020073 +v -0.509494 0.869710 -1.024112 +v -0.505286 0.869366 -1.027834 +v -0.499622 0.869065 -1.031097 +v -0.492720 0.868818 -1.033775 +v -0.508686 0.877949 -1.024872 +v -0.504558 0.876782 -1.028519 +v -0.499003 0.875371 -1.031679 +v -0.492234 0.873773 -1.034232 +v -0.492234 0.873773 -1.034232 +v -0.484512 0.872047 -1.036079 +v -0.511228 0.878830 -1.020880 +v -0.483520 0.875329 -1.036382 +v -0.508686 0.887240 -1.021657 +v -0.506291 0.885872 -1.025604 +v -0.502403 0.883912 -1.029177 +v -0.497170 0.881435 -1.032239 +v -0.490794 0.878537 -1.034672 +v -0.490794 0.878537 -1.034672 +v -0.502403 0.893173 -1.026278 +v -0.498904 0.890483 -1.029784 +v -0.494195 0.887023 -1.032755 +v -0.488456 0.882927 -1.035077 +v -0.488456 0.882927 -1.035077 +v -0.481910 0.878353 -1.036661 +v -0.504558 0.894992 -1.022372 +v -0.479742 0.881004 -1.036906 +v -0.499003 0.901786 -1.023000 +v -0.497170 0.899573 -1.026869 +v -0.494195 0.896242 -1.030316 +v -0.490190 0.891921 -1.033207 +v -0.485310 0.886776 -1.035433 +v -0.485310 0.886776 -1.035433 +v -0.488456 0.900969 -1.030752 +v -0.485310 0.895941 -1.033578 +v -0.490190 0.891921 -1.033207 +v -0.485310 0.895941 -1.033578 +v -0.481475 0.889934 -1.035724 +v -0.477101 0.883179 -1.037107 +v -0.492234 0.907361 -1.023515 +v -0.490794 0.904825 -1.027354 +v -0.484512 0.911505 -1.023897 +v -0.483520 0.908728 -1.027714 +v -0.481910 0.904482 -1.031076 +v -0.488456 0.900969 -1.030752 +v -0.481910 0.904482 -1.031076 +v -0.479742 0.898928 -1.033854 +v -0.477101 0.892281 -1.035941 +v -0.474088 0.884796 -1.037256 +v -0.474806 0.906645 -1.031276 +v -0.473701 0.900768 -1.034024 +v -0.472354 0.893726 -1.036074 +v -0.470819 0.885791 -1.037348 +v -0.476133 0.914056 -1.024133 +v -0.475627 0.911131 -1.027936 +v -0.483520 0.908728 -1.027714 +v -0.475627 0.911131 -1.027936 +v -0.476133 0.914056 -1.024133 +vt 0.641141 0.776980 +vt 0.641204 0.776320 +vt 0.641078 0.776320 +vt 0.640954 0.776345 +vt 0.640838 0.776395 +vt 0.640732 0.776467 +vt 0.640642 0.776559 +vt 0.640571 0.776667 +vt 0.640521 0.776786 +vt 0.640496 0.776914 +vt 0.640494 0.777043 +vt 0.640517 0.777170 +vt 0.640564 0.777290 +vt 0.640633 0.777398 +vt 0.640721 0.777490 +vt 0.640825 0.777562 +vt 0.640941 0.777611 +vt 0.641065 0.777637 +vt 0.641191 0.777637 +vt 0.641314 0.777611 +vt 0.641431 0.777562 +vt 0.641537 0.777490 +vt 0.641627 0.777398 +vt 0.641698 0.777290 +vt 0.641747 0.777170 +vt 0.641773 0.777043 +vt 0.641775 0.776914 +vt 0.641751 0.776786 +vt 0.641704 0.776667 +vt 0.641636 0.776559 +vt 0.641548 0.776467 +vt 0.641443 0.776395 +vt 0.641328 0.776345 +vt 0.641265 0.773820 +vt 0.641223 0.773615 +vt 0.640590 0.773615 +vt 0.640669 0.773820 +vt 0.641290 0.774143 +vt 0.640753 0.774143 +vt 0.641296 0.774573 +vt 0.640840 0.774573 +vt 0.641284 0.775093 +vt 0.640925 0.775093 +vt 0.641252 0.775683 +vt 0.641005 0.775683 +vt 0.640762 0.775733 +vt 0.639967 0.773742 +vt 0.640082 0.773939 +vt 0.640225 0.774251 +vt 0.640391 0.774665 +vt 0.640572 0.775165 +vt 0.639529 0.774174 +vt 0.639727 0.774463 +vt 0.639967 0.774845 +vt 0.640239 0.775307 +vt 0.640533 0.775830 +vt 0.639379 0.773991 +vt 0.640326 0.775971 +vt 0.638849 0.774354 +vt 0.639029 0.774516 +vt 0.639277 0.774770 +vt 0.639585 0.775106 +vt 0.639939 0.775512 +vt 0.638894 0.775161 +vt 0.639258 0.775438 +vt 0.639682 0.775773 +vt 0.640150 0.776151 +vt 0.638396 0.774815 +vt 0.638603 0.774950 +vt 0.638039 0.775357 +vt 0.638266 0.775461 +vt 0.638591 0.775620 +vt 0.639000 0.775829 +vt 0.639480 0.776080 +vt 0.640010 0.776363 +vt 0.638821 0.776264 +vt 0.639339 0.776421 +vt 0.639913 0.776598 +vt 0.637790 0.775959 +vt 0.638031 0.776028 +vt 0.638380 0.776131 +vt 0.637660 0.776599 +vt 0.637909 0.776631 +vt 0.638269 0.776673 +vt 0.638727 0.776725 +vt 0.639265 0.776784 +vt 0.639862 0.776847 +vt 0.638722 0.777195 +vt 0.639261 0.777153 +vt 0.639859 0.777102 +vt 0.637653 0.777251 +vt 0.637902 0.777245 +vt 0.638263 0.777226 +vt 0.637770 0.777890 +vt 0.638012 0.777847 +vt 0.638363 0.777768 +vt 0.638807 0.777656 +vt 0.639327 0.777515 +vt 0.639905 0.777351 +vt 0.639461 0.777856 +vt 0.639997 0.777586 +vt 0.638006 0.778493 +vt 0.638235 0.778415 +vt 0.638563 0.778279 +vt 0.638977 0.778090 +vt 0.638352 0.779035 +vt 0.638561 0.778925 +vt 0.638856 0.778738 +vt 0.639226 0.778481 +vt 0.639657 0.778163 +vt 0.640132 0.777798 +vt 0.639908 0.778425 +vt 0.640305 0.777978 +vt 0.638795 0.779496 +vt 0.638978 0.779360 +vt 0.639232 0.779129 +vt 0.639546 0.778813 +vt 0.639471 0.779701 +vt 0.639675 0.779436 +vt 0.639923 0.779075 +vt 0.640204 0.778630 +vt 0.640509 0.778119 +vt 0.639318 0.779858 +vt 0.640737 0.778216 +vt 0.639901 0.780108 +vt 0.640020 0.779936 +vt 0.640169 0.779648 +vt 0.640343 0.779254 +vt 0.640534 0.778771 +vt 0.640694 0.779756 +vt 0.640790 0.779346 +vt 0.640886 0.778843 +vt 0.640978 0.778266 +vt 0.640520 0.780235 +vt 0.640603 0.780056 +vt 0.852389 0.065643 +vt 0.852173 0.065451 +vt 0.851704 0.065577 +vt 0.851948 0.065762 +vt 0.641200 0.780056 +vt 0.641231 0.779756 +vt 0.641246 0.779346 +vt 0.641244 0.778843 +vt 0.641226 0.778266 +vt 0.641759 0.779648 +vt 0.641695 0.779254 +vt 0.641597 0.778771 +vt 0.641468 0.778216 +vt 0.851263 0.065826 +vt 0.851532 0.065996 +vt 0.852201 0.066062 +vt 0.851827 0.066273 +vt 0.850866 0.066188 +vt 0.851158 0.066337 +vt 0.851491 0.066580 +vt 0.852137 0.066646 +vt 0.851850 0.066907 +vt 0.642119 0.779075 +vt 0.641930 0.778630 +vt 0.641698 0.778119 +vt 0.852224 0.067305 +vt 0.851607 0.067239 +vt 0.852032 0.067566 +vt 0.642230 0.778425 +vt 0.641905 0.777978 +vt 0.850528 0.066648 +vt 0.850840 0.066771 +vt 0.851204 0.066971 +vt 0.850263 0.067191 +vt 0.850590 0.067282 +vt 0.850980 0.067430 +vt 0.851416 0.067630 +vt 0.851882 0.067873 +vt 0.642487 0.778163 +vt 0.642081 0.777798 +vt 0.851284 0.068064 +vt 0.851778 0.068214 +vt 0.642689 0.777856 +vt 0.642221 0.777586 +vt 0.850080 0.067793 +vt 0.850418 0.067849 +vt 0.850825 0.067941 +vt 0.849987 0.068433 +vt 0.850330 0.068452 +vt 0.850746 0.068483 +vt 0.851217 0.068525 +vt 0.851726 0.068577 +vt 0.642830 0.777515 +vt 0.642318 0.777351 +vt 0.642904 0.777153 +vt 0.642369 0.777102 +vt 0.849987 0.069086 +vt 0.850330 0.069067 +vt 0.850746 0.069037 +vt 0.851217 0.068996 +vt 0.851726 0.068946 +vt 0.850418 0.069670 +vt 0.850825 0.069580 +vt 0.851284 0.069458 +vt 0.851778 0.069309 +vt 0.642908 0.776784 +vt 0.642371 0.776847 +vt 0.850080 0.069726 +vt 0.642326 0.776598 +vt 0.850263 0.070329 +vt 0.850590 0.070238 +vt 0.850980 0.070091 +vt 0.851416 0.069893 +vt 0.851882 0.069651 +vt 0.642842 0.776421 +vt 0.850840 0.070750 +vt 0.851204 0.070552 +vt 0.851607 0.070284 +vt 0.852032 0.069959 +vt 0.642708 0.776080 +vt 0.642234 0.776363 +vt 0.850528 0.070872 +vt 0.642098 0.776151 +vt 0.850866 0.071335 +vt 0.851158 0.071185 +vt 0.851491 0.070943 +vt 0.851850 0.070617 +vt 0.852224 0.070220 +vt 0.642512 0.775773 +vt 0.851827 0.071251 +vt 0.852137 0.070879 +vt 0.642859 0.775438 +vt 0.642540 0.775106 +vt 0.642261 0.775512 +vt 0.641926 0.775971 +vt 0.851263 0.071698 +vt 0.851532 0.071528 +vt 0.851704 0.071949 +vt 0.851948 0.071764 +vt 0.852201 0.071464 +vt 0.642753 0.774770 +vt 0.642309 0.774463 +vt 0.642163 0.774845 +vt 0.641965 0.775307 +vt 0.641722 0.775830 +vt 0.641816 0.774251 +vt 0.641743 0.774665 +vt 0.641635 0.775165 +vt 0.641494 0.775733 +vt 0.852173 0.072077 +vt 0.852389 0.071885 +vt 0.642398 0.774174 +vt 0.641849 0.773939 +vt 0.641843 0.773742 +vn -0.0000 -0.0919 -0.9958 +vn -0.0000 0.0051 -1.0000 +vn 0.0191 0.0032 -0.9998 +vn 0.0374 -0.0023 -0.9993 +vn 0.0543 -0.0112 -0.9985 +vn 0.0691 -0.0233 -0.9973 +vn 0.0813 -0.0379 -0.9960 +vn 0.0903 -0.0546 -0.9944 +vn 0.0958 -0.0726 -0.9927 +vn 0.0977 -0.0915 -0.9910 +vn 0.0958 -0.1103 -0.9893 +vn 0.0903 -0.1284 -0.9876 +vn 0.0812 -0.1451 -0.9861 +vn 0.0691 -0.1598 -0.9847 +vn 0.0543 -0.1718 -0.9836 +vn 0.0374 -0.1807 -0.9828 +vn 0.0192 -0.1862 -0.9823 +vn 0.0000 -0.1881 -0.9822 +vn -0.0191 -0.1862 -0.9823 +vn -0.0374 -0.1807 -0.9828 +vn -0.0543 -0.1718 -0.9836 +vn -0.0691 -0.1598 -0.9847 +vn -0.0812 -0.1451 -0.9861 +vn -0.0903 -0.1284 -0.9876 +vn -0.0958 -0.1104 -0.9893 +vn -0.0977 -0.0915 -0.9910 +vn -0.0958 -0.0726 -0.9927 +vn -0.0903 -0.0546 -0.9944 +vn -0.0813 -0.0379 -0.9960 +vn -0.0691 -0.0233 -0.9973 +vn -0.0543 -0.0112 -0.9985 +vn -0.0375 -0.0023 -0.9993 +vn -0.0191 0.0032 -0.9998 +vn -0.0000 0.6990 -0.7151 +vn -0.0000 0.7874 -0.6165 +vn 0.1652 0.7711 -0.6149 +vn 0.1498 0.6843 -0.7137 +vn 0.0000 0.5096 -0.8604 +vn 0.1153 0.4983 -0.8593 +vn -0.0000 0.3496 -0.9369 +vn 0.0854 0.3413 -0.9361 +vn 0.0000 0.2176 -0.9760 +vn 0.0603 0.2117 -0.9755 +vn 0.0000 0.1052 -0.9944 +vn 0.0386 0.1015 -0.9941 +vn 0.0757 0.0904 -0.9930 +vn 0.3238 0.7231 -0.6101 +vn 0.2936 0.6408 -0.7093 +vn 0.2262 0.4649 -0.8560 +vn 0.1675 0.3166 -0.9336 +vn 0.1182 0.1943 -0.9738 +vn 0.4259 0.5703 -0.7024 +vn 0.3282 0.4108 -0.8506 +vn 0.2431 0.2766 -0.9297 +vn 0.1716 0.1661 -0.9711 +vn 0.1099 0.0723 -0.9913 +vn 0.4698 0.6453 -0.6024 +vn 0.1399 0.0479 -0.9890 +vn 0.5973 0.5408 -0.5922 +vn 0.5416 0.4757 -0.6931 +vn 0.4174 0.3380 -0.8435 +vn 0.3093 0.2228 -0.9245 +vn 0.2183 0.1281 -0.9674 +vn 0.4906 0.2495 -0.8349 +vn 0.3636 0.1572 -0.9182 +vn 0.2566 0.0819 -0.9630 +vn 0.1644 0.0183 -0.9862 +vn 0.7018 0.4139 -0.5799 +vn 0.6363 0.3607 -0.6819 +vn 0.7791 0.2695 -0.5660 +vn 0.7065 0.2298 -0.6694 +vn 0.5448 0.1486 -0.8253 +vn 0.4038 0.0825 -0.9111 +vn 0.2851 0.0292 -0.9581 +vn 0.1827 -0.0154 -0.9831 +vn 0.4286 0.0015 -0.9035 +vn 0.3026 -0.0280 -0.9527 +vn 0.1939 -0.0520 -0.9796 +vn 0.8266 0.1130 -0.5512 +vn 0.7496 0.0880 -0.6560 +vn 0.5782 0.0394 -0.8149 +vn 0.8427 -0.0495 -0.5361 +vn 0.7642 -0.0593 -0.6423 +vn 0.5895 -0.0743 -0.8044 +vn 0.4370 -0.0827 -0.8957 +vn 0.3085 -0.0874 -0.9472 +vn 0.1977 -0.0901 -0.9761 +vn 0.4287 -0.1669 -0.8879 +vn 0.3026 -0.1469 -0.9417 +vn 0.1939 -0.1282 -0.9726 +vn 0.8267 -0.2121 -0.5212 +vn 0.7496 -0.2066 -0.6288 +vn 0.5782 -0.1879 -0.7940 +vn 0.7791 -0.3685 -0.5071 +vn 0.7065 -0.3485 -0.6160 +vn 0.5448 -0.2973 -0.7841 +vn 0.4039 -0.2480 -0.8806 +vn 0.2851 -0.2041 -0.9365 +vn 0.1826 -0.1649 -0.9693 +vn 0.2566 -0.2569 -0.9318 +vn 0.1644 -0.1986 -0.9662 +vn 0.7017 -0.5131 -0.4943 +vn 0.6363 -0.4794 -0.6044 +vn 0.4906 -0.3982 -0.7751 +vn 0.3636 -0.3227 -0.8739 +vn 0.5973 -0.6401 -0.4831 +vn 0.5416 -0.5945 -0.5943 +vn 0.4174 -0.4867 -0.7673 +vn 0.3093 -0.3883 -0.8681 +vn 0.2183 -0.3031 -0.9276 +vn 0.1398 -0.2282 -0.9635 +vn 0.1715 -0.3411 -0.9242 +vn 0.1099 -0.2526 -0.9613 +vn 0.4698 -0.7447 -0.4741 +vn 0.4259 -0.6893 -0.5861 +vn 0.3282 -0.5596 -0.7610 +vn 0.2431 -0.4421 -0.8634 +vn 0.2936 -0.7599 -0.5800 +vn 0.2262 -0.6138 -0.7564 +vn 0.1675 -0.4822 -0.8599 +vn 0.1182 -0.3693 -0.9217 +vn 0.0757 -0.2707 -0.9597 +vn 0.3238 -0.8226 -0.4674 +vn 0.0386 -0.2818 -0.9587 +vn 0.1652 -0.8707 -0.4632 +vn 0.1498 -0.8034 -0.5763 +vn 0.1153 -0.6472 -0.7535 +vn 0.0854 -0.5069 -0.8577 +vn 0.0603 -0.3867 -0.9202 +vn -0.0000 -0.6585 -0.7525 +vn 0.0000 -0.5153 -0.8570 +vn 0.0000 -0.3926 -0.9197 +vn -0.0000 -0.2855 -0.9584 +vn 0.0000 -0.8869 -0.4619 +vn -0.0000 -0.8181 -0.5750 +vn -0.0000 -0.8181 -0.5751 +vn -0.1652 -0.8707 -0.4632 +vn -0.1498 -0.8034 -0.5763 +vn -0.1154 -0.6472 -0.7535 +vn -0.0854 -0.5069 -0.8577 +vn -0.0603 -0.3867 -0.9202 +vn -0.0386 -0.2818 -0.9587 +vn -0.2261 -0.6138 -0.7564 +vn -0.1675 -0.4822 -0.8599 +vn -0.1182 -0.3693 -0.9217 +vn -0.0757 -0.2706 -0.9597 +vn -0.3239 -0.8226 -0.4674 +vn -0.2936 -0.7599 -0.5800 +vn -0.1153 -0.6472 -0.7535 +vn -0.2262 -0.6138 -0.7564 +vn -0.4698 -0.7447 -0.4740 +vn -0.4259 -0.6893 -0.5861 +vn -0.3282 -0.5596 -0.7610 +vn -0.2431 -0.4421 -0.8634 +vn -0.1716 -0.3411 -0.9242 +vn -0.1099 -0.2526 -0.9613 +vn -0.3093 -0.3883 -0.8681 +vn -0.2183 -0.3031 -0.9276 +vn -0.1398 -0.2282 -0.9635 +vn -0.5974 -0.6401 -0.4831 +vn -0.5416 -0.5946 -0.5943 +vn -0.4174 -0.4867 -0.7673 +vn -0.7017 -0.5131 -0.4942 +vn -0.6363 -0.4794 -0.6044 +vn -0.4906 -0.3982 -0.7751 +vn -0.3636 -0.3227 -0.8739 +vn -0.2566 -0.2568 -0.9318 +vn -0.2566 -0.2569 -0.9318 +vn -0.1644 -0.1986 -0.9662 +vn -0.4038 -0.2479 -0.8806 +vn -0.2851 -0.2041 -0.9365 +vn -0.1826 -0.1649 -0.9693 +vn -0.7791 -0.3685 -0.5071 +vn -0.7065 -0.3485 -0.6160 +vn -0.5449 -0.2973 -0.7841 +vn -0.8267 -0.2121 -0.5212 +vn -0.7496 -0.2066 -0.6288 +vn -0.5782 -0.1879 -0.7940 +vn -0.4286 -0.1669 -0.8879 +vn -0.3026 -0.1469 -0.9417 +vn -0.1939 -0.1282 -0.9726 +vn -0.3085 -0.0874 -0.9472 +vn -0.1977 -0.0901 -0.9761 +vn -0.8427 -0.0495 -0.5361 +vn -0.7642 -0.0593 -0.6423 +vn -0.5895 -0.0743 -0.8044 +vn -0.4370 -0.0827 -0.8956 +vn -0.3085 -0.0875 -0.9472 +vn -0.7496 0.0880 -0.6560 +vn -0.5782 0.0393 -0.8149 +vn -0.4286 0.0015 -0.9035 +vn -0.3026 -0.0280 -0.9527 +vn -0.1939 -0.0521 -0.9796 +vn -0.8266 0.1130 -0.5513 +vn -0.1827 -0.0154 -0.9831 +vn -0.7791 0.2695 -0.5660 +vn -0.7065 0.2298 -0.6694 +vn -0.5449 0.1486 -0.8253 +vn -0.4038 0.0825 -0.9111 +vn -0.2851 0.0292 -0.9581 +vn -0.6363 0.3607 -0.6819 +vn -0.4906 0.2495 -0.8349 +vn -0.3636 0.1572 -0.9182 +vn -0.2566 0.0819 -0.9630 +vn -0.1644 0.0184 -0.9862 +vn -0.7018 0.4139 -0.5798 +vn -0.1399 0.0479 -0.9890 +vn -0.5973 0.5409 -0.5922 +vn -0.5416 0.4757 -0.6931 +vn -0.4174 0.3380 -0.8435 +vn -0.3093 0.2228 -0.9245 +vn -0.2183 0.1281 -0.9674 +vn -0.3282 0.4108 -0.8506 +vn -0.2430 0.2766 -0.9298 +vn -0.2431 0.2766 -0.9297 +vn -0.1716 0.1661 -0.9711 +vn -0.1099 0.0723 -0.9913 +vn -0.4698 0.6453 -0.6024 +vn -0.4259 0.5703 -0.7024 +vn -0.3239 0.7231 -0.6101 +vn -0.2936 0.6408 -0.7093 +vn -0.2261 0.4649 -0.8560 +vn -0.1675 0.3166 -0.9336 +vn -0.1182 0.1943 -0.9738 +vn -0.0757 0.0903 -0.9930 +vn -0.1153 0.4983 -0.8593 +vn -0.0854 0.3413 -0.9361 +vn -0.0603 0.2117 -0.9755 +vn -0.0386 0.1015 -0.9941 +vn -0.1652 0.7711 -0.6149 +vn -0.1497 0.6843 -0.7137 +vn -0.1498 0.6843 -0.7137 +usemtl Scene_-_Root +s 1 +f 38539/38539/28173 38540/38540/28174 38541/38541/28175 +f 38539/38539/28173 38541/38541/28175 38542/38542/28176 +f 38539/38539/28173 38542/38542/28176 38543/38543/28177 +f 38539/38539/28173 38543/38543/28177 38544/38544/28178 +f 38539/38539/28173 38544/38544/28178 38545/38545/28179 +f 38539/38539/28173 38545/38545/28179 38546/38546/28180 +f 38539/38539/28173 38546/38546/28180 38547/38547/28181 +f 38539/38539/28173 38547/38547/28181 38548/38548/28182 +f 38539/38539/28173 38548/38548/28182 38549/38549/28183 +f 38539/38539/28173 38549/38549/28183 38550/38550/28184 +f 38539/38539/28173 38550/38550/28184 38551/38551/28185 +f 38539/38539/28173 38551/38551/28185 38552/38552/28186 +f 38539/38539/28173 38552/38552/28186 38553/38553/28187 +f 38539/38539/28173 38553/38553/28187 38554/38554/28188 +f 38539/38539/28173 38554/38554/28188 38555/38555/28189 +f 38539/38539/28173 38555/38555/28189 38556/38556/28190 +f 38539/38539/28173 38556/38556/28190 38557/38557/28191 +f 38539/38539/28173 38557/38557/28191 38558/38558/28192 +f 38539/38539/28173 38558/38558/28192 38559/38559/28193 +f 38539/38539/28173 38559/38559/28193 38560/38560/28194 +f 38539/38539/28173 38560/38560/28194 38561/38561/28195 +f 38539/38539/28173 38561/38561/28195 38562/38562/28196 +f 38539/38539/28173 38562/38562/28196 38563/38563/28197 +f 38539/38539/28173 38563/38563/28197 38564/38564/28198 +f 38539/38539/28173 38564/38564/28198 38565/38565/28199 +f 38539/38539/28173 38565/38565/28199 38566/38566/28200 +f 38539/38539/28173 38566/38566/28200 38567/38567/28201 +f 38539/38539/28173 38567/38567/28201 38568/38568/28202 +f 38539/38539/28173 38568/38568/28202 38569/38569/28203 +f 38539/38539/28173 38569/38569/28203 38570/38570/28204 +f 38539/38539/28173 38570/38570/28204 38571/38571/28205 +f 38539/38539/28173 38571/38571/28205 38540/38540/28174 +f 38572/38572/28206 38573/38573/28207 38574/38574/28208 +f 38572/38572/28206 38574/38574/28208 38575/38575/28209 +f 38576/38576/28210 38572/38572/28206 38575/38575/28209 +f 38576/38576/28210 38575/38575/28209 38577/38577/28211 +f 38578/38578/28212 38576/38576/28210 38577/38577/28211 +f 38578/38578/28212 38577/38577/28211 38579/38579/28213 +f 38580/38580/28214 38578/38578/28212 38579/38579/28213 +f 38580/38580/28214 38579/38579/28213 38581/38581/28215 +f 38582/38582/28216 38580/38580/28214 38581/38581/28215 +f 38582/38582/28216 38581/38581/28215 38583/38583/28217 +f 38540/38540/28174 38582/38582/28216 38583/38583/28217 +f 38540/38540/28174 38583/38583/28217 38541/38541/28175 +f 38541/38541/28175 38583/38583/28217 38584/38584/28218 +f 38541/38541/28175 38584/38584/28218 38542/38542/28176 +f 38575/38575/28209 38574/38574/28208 38585/38585/28219 +f 38575/38575/28209 38585/38585/28219 38586/38586/28220 +f 38577/38577/28211 38575/38575/28209 38586/38586/28220 +f 38577/38577/28211 38586/38586/28220 38587/38587/28221 +f 38579/38579/28213 38577/38577/28211 38587/38587/28221 +f 38579/38579/28213 38587/38587/28221 38588/38588/28222 +f 38581/38581/28215 38579/38579/28213 38588/38588/28222 +f 38581/38581/28215 38588/38588/28222 38589/38589/28223 +f 38583/38583/28217 38581/38581/28215 38589/38589/28223 +f 38583/38583/28217 38589/38589/28223 38584/38584/28218 +f 38587/38587/28221 38586/38586/28220 38590/38590/28224 +f 38587/38587/28221 38590/38590/28224 38591/38591/28225 +f 38588/38588/28222 38587/38587/28221 38591/38591/28225 +f 38588/38588/28222 38591/38591/28225 38592/38592/28226 +f 38589/38589/28223 38588/38588/28222 38592/38592/28226 +f 38589/38589/28223 38592/38592/28226 38593/38593/28227 +f 38584/38584/28218 38589/38589/28223 38593/38593/28227 +f 38584/38584/28218 38593/38593/28227 38594/38594/28228 +f 38542/38542/28176 38584/38584/28218 38594/38594/28228 +f 38542/38542/28176 38594/38594/28228 38543/38543/28177 +f 38586/38586/28220 38585/38585/28219 38595/38595/28229 +f 38586/38586/28220 38595/38595/28229 38590/38590/28224 +f 38543/38543/28177 38594/38594/28228 38596/38596/28230 +f 38543/38543/28177 38596/38596/28230 38544/38544/28178 +f 38590/38590/28224 38595/38595/28229 38597/38597/28231 +f 38590/38590/28224 38597/38597/28231 38598/38598/28232 +f 38591/38591/28225 38590/38590/28224 38598/38598/28232 +f 38591/38591/28225 38598/38598/28232 38599/38599/28233 +f 38592/38592/28226 38591/38591/28225 38599/38599/28233 +f 38592/38592/28226 38599/38599/28233 38600/38600/28234 +f 38593/38593/28227 38592/38592/28226 38600/38600/28234 +f 38593/38593/28227 38600/38600/28234 38601/38601/28235 +f 38594/38594/28228 38593/38593/28227 38601/38601/28235 +f 38594/38594/28228 38601/38601/28235 38596/38596/28230 +f 38600/38600/28234 38599/38599/28233 38602/38602/28236 +f 38600/38600/28234 38602/38602/28236 38603/38603/28237 +f 38601/38601/28235 38600/38600/28234 38603/38603/28237 +f 38601/38601/28235 38603/38603/28237 38604/38604/28238 +f 38596/38596/28230 38601/38601/28235 38604/38604/28238 +f 38596/38596/28230 38604/38604/28238 38605/38605/28239 +f 38544/38544/28178 38596/38596/28230 38605/38605/28239 +f 38544/38544/28178 38605/38605/28239 38545/38545/28179 +f 38598/38598/28232 38597/38597/28231 38606/38606/28240 +f 38598/38598/28232 38606/38606/28240 38607/38607/28241 +f 38599/38599/28233 38598/38598/28232 38607/38607/28241 +f 38599/38599/28233 38607/38607/28241 38602/38602/28236 +f 38607/38607/28241 38606/38606/28240 38608/38608/28242 +f 38607/38607/28241 38608/38608/28242 38609/38609/28243 +f 38602/38602/28236 38607/38607/28241 38609/38609/28243 +f 38602/38602/28236 38609/38609/28243 38610/38610/28244 +f 38603/38603/28237 38602/38602/28236 38610/38610/28244 +f 38603/38603/28237 38610/38610/28244 38611/38611/28245 +f 38604/38604/28238 38603/38603/28237 38611/38611/28245 +f 38604/38604/28238 38611/38611/28245 38612/38612/28246 +f 38605/38605/28239 38604/38604/28238 38612/38612/28246 +f 38605/38605/28239 38612/38612/28246 38613/38613/28247 +f 38545/38545/28179 38605/38605/28239 38613/38613/28247 +f 38545/38545/28179 38613/38613/28247 38546/38546/28180 +f 38612/38612/28246 38611/38611/28245 38614/38614/28248 +f 38612/38612/28246 38614/38614/28248 38615/38615/28249 +f 38613/38613/28247 38612/38612/28246 38615/38615/28249 +f 38613/38613/28247 38615/38615/28249 38616/38616/28250 +f 38546/38546/28180 38613/38613/28247 38616/38616/28250 +f 38546/38546/28180 38616/38616/28250 38547/38547/28181 +f 38609/38609/28243 38608/38608/28242 38617/38617/28251 +f 38609/38609/28243 38617/38617/28251 38618/38618/28252 +f 38610/38610/28244 38609/38609/28243 38618/38618/28252 +f 38610/38610/28244 38618/38618/28252 38619/38619/28253 +f 38611/38611/28245 38610/38610/28244 38619/38619/28253 +f 38611/38611/28245 38619/38619/28253 38614/38614/28248 +f 38618/38618/28252 38617/38617/28251 38620/38620/28254 +f 38618/38618/28252 38620/38620/28254 38621/38621/28255 +f 38619/38619/28253 38618/38618/28252 38621/38621/28255 +f 38619/38619/28253 38621/38621/28255 38622/38622/28256 +f 38614/38614/28248 38619/38619/28253 38622/38622/28256 +f 38614/38614/28248 38622/38622/28256 38623/38623/28257 +f 38615/38615/28249 38614/38614/28248 38623/38623/28257 +f 38615/38615/28249 38623/38623/28257 38624/38624/28258 +f 38616/38616/28250 38615/38615/28249 38624/38624/28258 +f 38616/38616/28250 38624/38624/28258 38625/38625/28259 +f 38547/38547/28181 38616/38616/28250 38625/38625/28259 +f 38547/38547/28181 38625/38625/28259 38548/38548/28182 +f 38624/38624/28258 38623/38623/28257 38626/38626/28260 +f 38624/38624/28258 38626/38626/28260 38627/38627/28261 +f 38625/38625/28259 38624/38624/28258 38627/38627/28261 +f 38625/38625/28259 38627/38627/28261 38628/38628/28262 +f 38548/38548/28182 38625/38625/28259 38628/38628/28262 +f 38548/38548/28182 38628/38628/28262 38549/38549/28183 +f 38621/38621/28255 38620/38620/28254 38629/38629/28263 +f 38621/38621/28255 38629/38629/28263 38630/38630/28264 +f 38622/38622/28256 38621/38621/28255 38630/38630/28264 +f 38622/38622/28256 38630/38630/28264 38631/38631/28265 +f 38623/38623/28257 38622/38622/28256 38631/38631/28265 +f 38623/38623/28257 38631/38631/28265 38626/38626/28260 +f 38630/38630/28264 38629/38629/28263 38632/38632/28266 +f 38630/38630/28264 38632/38632/28266 38633/38633/28267 +f 38631/38631/28265 38630/38630/28264 38633/38633/28267 +f 38631/38631/28265 38633/38633/28267 38634/38634/28268 +f 38626/38626/28260 38631/38631/28265 38634/38634/28268 +f 38626/38626/28260 38634/38634/28268 38635/38635/28269 +f 38627/38627/28261 38626/38626/28260 38635/38635/28269 +f 38627/38627/28261 38635/38635/28269 38636/38636/28270 +f 38628/38628/28262 38627/38627/28261 38636/38636/28270 +f 38628/38628/28262 38636/38636/28270 38637/38637/28271 +f 38549/38549/28183 38628/38628/28262 38637/38637/28271 +f 38549/38549/28183 38637/38637/28271 38550/38550/28184 +f 38637/38637/28271 38636/38636/28270 38638/38638/28272 +f 38637/38637/28271 38638/38638/28272 38639/38639/28273 +f 38550/38550/28184 38637/38637/28271 38639/38639/28273 +f 38550/38550/28184 38639/38639/28273 38551/38551/28185 +f 38633/38633/28267 38632/38632/28266 38640/38640/28274 +f 38633/38633/28267 38640/38640/28274 38641/38641/28275 +f 38634/38634/28268 38633/38633/28267 38641/38641/28275 +f 38634/38634/28268 38641/38641/28275 38642/38642/28276 +f 38635/38635/28269 38634/38634/28268 38642/38642/28276 +f 38635/38635/28269 38642/38642/28276 38643/38643/28277 +f 38636/38636/28270 38635/38635/28269 38643/38643/28277 +f 38636/38636/28270 38643/38643/28277 38638/38638/28272 +f 38641/38641/28275 38640/38640/28274 38644/38644/28278 +f 38641/38641/28275 38644/38644/28278 38645/38645/28279 +f 38642/38642/28276 38641/38641/28275 38645/38645/28279 +f 38642/38642/28276 38645/38645/28279 38646/38646/28280 +f 38643/38643/28277 38642/38642/28276 38646/38646/28280 +f 38643/38643/28277 38646/38646/28280 38647/38647/28281 +f 38638/38638/28272 38643/38643/28277 38647/38647/28281 +f 38638/38638/28272 38647/38647/28281 38648/38648/28282 +f 38639/38639/28273 38638/38638/28272 38648/38648/28282 +f 38639/38639/28273 38648/38648/28282 38649/38649/28283 +f 38551/38551/28185 38639/38639/28273 38649/38649/28283 +f 38551/38551/28185 38649/38649/28283 38552/38552/28186 +f 38649/38649/28283 38648/38648/28282 38650/38650/28284 +f 38649/38649/28283 38650/38650/28284 38651/38651/28285 +f 38552/38552/28186 38649/38649/28283 38651/38651/28285 +f 38552/38552/28186 38651/38651/28285 38553/38553/28187 +f 38645/38645/28279 38644/38644/28278 38652/38652/28286 +f 38645/38645/28279 38652/38652/28286 38653/38653/28287 +f 38646/38646/28280 38645/38645/28279 38653/38653/28287 +f 38646/38646/28280 38653/38653/28287 38654/38654/28288 +f 38647/38647/28281 38646/38646/28280 38654/38654/28288 +f 38647/38647/28281 38654/38654/28288 38655/38655/28289 +f 38648/38648/28282 38647/38647/28281 38655/38655/28289 +f 38648/38648/28282 38655/38655/28289 38650/38650/28284 +f 38654/38654/28288 38653/38653/28287 38656/38656/28290 +f 38654/38654/28288 38656/38656/28290 38657/38657/28291 +f 38655/38655/28289 38654/38654/28288 38657/38657/28291 +f 38655/38655/28289 38657/38657/28291 38658/38658/28292 +f 38650/38650/28284 38655/38655/28289 38658/38658/28292 +f 38650/38650/28284 38658/38658/28292 38659/38659/28293 +f 38651/38651/28285 38650/38650/28284 38659/38659/28293 +f 38651/38651/28285 38659/38659/28293 38660/38660/28294 +f 38553/38553/28187 38651/38651/28285 38660/38660/28294 +f 38553/38553/28187 38660/38660/28294 38554/38554/28188 +f 38653/38653/28287 38652/38652/28286 38661/38661/28295 +f 38653/38653/28287 38661/38661/28295 38656/38656/28290 +f 38554/38554/28188 38660/38660/28294 38662/38662/28296 +f 38554/38554/28188 38662/38662/28296 38555/38555/28189 +f 38656/38656/28290 38661/38661/28295 38663/38663/28297 +f 38656/38656/28290 38663/38663/28297 38664/38664/28298 +f 38657/38657/28291 38656/38656/28290 38664/38664/28298 +f 38657/38657/28291 38664/38664/28298 38665/38665/28299 +f 38658/38658/28292 38657/38657/28291 38665/38665/28299 +f 38658/38658/28292 38665/38665/28299 38666/38666/28300 +f 38659/38659/28293 38658/38658/28292 38666/38666/28300 +f 38659/38659/28293 38666/38666/28300 38667/38667/28301 +f 38660/38660/28294 38659/38659/28293 38667/38667/28301 +f 38660/38660/28294 38667/38667/28301 38662/38662/28296 +f 38666/38666/28300 38665/38665/28299 38668/38668/28302 +f 38666/38666/28300 38668/38668/28302 38669/38669/28303 +f 38667/38667/28301 38666/38666/28300 38669/38669/28303 +f 38667/38667/28301 38669/38669/28303 38670/38670/28304 +f 38662/38662/28296 38667/38667/28301 38670/38670/28304 +f 38662/38662/28296 38670/38670/28304 38671/38671/28305 +f 38555/38555/28189 38662/38662/28296 38671/38671/28305 +f 38555/38555/28189 38671/38671/28305 38556/38556/28190 +f 38664/38664/28298 38663/38663/28297 38672/38672/28306 +f 38664/38664/28298 38672/38672/28306 38673/38673/28307 +f 38665/38665/28299 38664/38664/28298 38673/38673/28307 +f 38665/38665/28299 38673/38673/28307 38668/38668/28302 +f 38674/38674/28308 38675/38675/28306 38676/38676/28309 +f 38674/38674/28308 38676/38676/28309 38677/38677/28310 +f 38668/38668/28302 38673/38673/28307 38678/38678/28310 +f 38668/38668/28302 38678/38678/28310 38679/38679/28311 +f 38669/38669/28303 38668/38668/28302 38679/38679/28311 +f 38669/38669/28303 38679/38679/28311 38680/38680/28312 +f 38670/38670/28304 38669/38669/28303 38680/38680/28312 +f 38670/38670/28304 38680/38680/28312 38681/38681/28313 +f 38671/38671/28305 38670/38670/28304 38681/38681/28313 +f 38671/38671/28305 38681/38681/28313 38682/38682/28314 +f 38556/38556/28190 38671/38671/28305 38682/38682/28314 +f 38556/38556/28190 38682/38682/28314 38557/38557/28191 +f 38680/38680/28312 38679/38679/28311 38683/38683/28315 +f 38680/38680/28312 38683/38683/28315 38684/38684/28316 +f 38681/38681/28313 38680/38680/28312 38684/38684/28316 +f 38681/38681/28313 38684/38684/28316 38685/38685/28317 +f 38682/38682/28314 38681/38681/28313 38685/38685/28317 +f 38682/38682/28314 38685/38685/28317 38686/38686/28318 +f 38557/38557/28191 38682/38682/28314 38686/38686/28318 +f 38557/38557/28191 38686/38686/28318 38558/38558/28192 +f 38677/38677/28310 38676/38676/28309 38687/38687/28319 +f 38677/38677/28310 38687/38687/28319 38688/38688/28320 +f 38689/38689/28321 38677/38677/28310 38688/38688/28320 +f 38689/38689/28321 38688/38688/28320 38690/38690/28322 +f 38688/38688/28320 38687/38687/28319 38691/38691/28323 +f 38688/38688/28320 38691/38691/28323 38692/38692/28324 +f 38690/38690/28322 38688/38688/28320 38692/38692/28324 +f 38690/38690/28322 38692/38692/28324 38693/38693/28325 +f 38694/38694/28316 38690/38690/28322 38693/38693/28325 +f 38694/38694/28316 38693/38693/28325 38695/38695/28326 +f 38685/38685/28317 38684/38684/28316 38696/38696/28326 +f 38685/38685/28317 38696/38696/28326 38697/38697/28327 +f 38686/38686/28318 38685/38685/28317 38697/38697/28327 +f 38686/38686/28318 38697/38697/28327 38698/38698/28328 +f 38558/38558/28192 38686/38686/28318 38698/38698/28328 +f 38558/38558/28192 38698/38698/28328 38559/38559/28193 +f 38699/38699/28327 38695/38695/28326 38700/38700/28329 +f 38699/38699/28327 38700/38700/28329 38701/38701/28330 +f 38698/38698/28328 38697/38697/28327 38702/38702/28330 +f 38698/38698/28328 38702/38702/28330 38703/38703/28331 +f 38559/38559/28193 38698/38698/28328 38703/38703/28331 +f 38559/38559/28193 38703/38703/28331 38560/38560/28194 +f 38692/38692/28324 38691/38691/28323 38704/38704/28332 +f 38692/38692/28324 38704/38704/28332 38705/38705/28333 +f 38693/38693/28325 38692/38692/28324 38705/38705/28333 +f 38693/38693/28325 38705/38705/28333 38706/38706/28334 +f 38695/38695/28326 38693/38693/28325 38706/38706/28334 +f 38695/38695/28326 38706/38706/28334 38700/38700/28329 +f 38705/38705/28333 38704/38704/28332 38707/38707/28335 +f 38705/38705/28333 38707/38707/28335 38708/38708/28336 +f 38706/38706/28334 38705/38705/28333 38708/38708/28336 +f 38706/38706/28334 38708/38708/28336 38709/38709/28337 +f 38700/38700/28329 38706/38706/28334 38709/38709/28337 +f 38700/38700/28329 38709/38709/28337 38710/38710/28338 +f 38701/38701/28330 38700/38700/28329 38710/38710/28338 +f 38701/38701/28330 38710/38710/28338 38711/38711/28339 +f 38703/38703/28331 38702/38702/28330 38712/38712/28340 +f 38703/38703/28331 38712/38712/28340 38713/38713/28341 +f 38560/38560/28194 38703/38703/28331 38713/38713/28341 +f 38560/38560/28194 38713/38713/28341 38561/38561/28195 +f 38711/38711/28339 38710/38710/28338 38714/38714/28342 +f 38711/38711/28339 38714/38714/28342 38715/38715/28343 +f 38713/38713/28341 38712/38712/28340 38716/38716/28343 +f 38713/38713/28341 38716/38716/28343 38717/38717/28344 +f 38561/38561/28195 38713/38713/28341 38717/38717/28344 +f 38561/38561/28195 38717/38717/28344 38562/38562/28196 +f 38708/38708/28336 38707/38707/28335 38718/38718/28345 +f 38708/38708/28336 38718/38718/28345 38719/38719/28346 +f 38709/38709/28337 38708/38708/28336 38719/38719/28346 +f 38709/38709/28337 38719/38719/28346 38720/38720/28347 +f 38710/38710/28338 38709/38709/28337 38720/38720/28347 +f 38710/38710/28338 38720/38720/28347 38714/38714/28342 +f 38719/38719/28346 38718/38718/28345 38721/38721/28348 +f 38719/38719/28346 38721/38721/28348 38722/38722/28349 +f 38720/38720/28347 38719/38719/28346 38722/38722/28349 +f 38720/38720/28347 38722/38722/28349 38723/38723/28350 +f 38714/38714/28342 38720/38720/28347 38723/38723/28350 +f 38714/38714/28342 38723/38723/28350 38724/38724/28351 +f 38715/38715/28343 38714/38714/28342 38724/38724/28351 +f 38715/38715/28343 38724/38724/28351 38725/38725/28352 +f 38717/38717/28344 38716/38716/28343 38726/38726/28352 +f 38717/38717/28344 38726/38726/28352 38727/38727/28353 +f 38562/38562/28196 38717/38717/28344 38727/38727/28353 +f 38562/38562/28196 38727/38727/28353 38563/38563/28197 +f 38727/38727/28353 38726/38726/28352 38728/38728/28354 +f 38727/38727/28353 38728/38728/28354 38729/38729/28355 +f 38563/38563/28197 38727/38727/28353 38729/38729/28355 +f 38563/38563/28197 38729/38729/28355 38564/38564/28198 +f 38722/38722/28349 38721/38721/28348 38730/38730/28356 +f 38722/38722/28349 38730/38730/28356 38731/38731/28357 +f 38723/38723/28350 38722/38722/28349 38731/38731/28357 +f 38723/38723/28350 38731/38731/28357 38732/38732/28358 +f 38724/38724/28351 38723/38723/28350 38732/38732/28358 +f 38724/38724/28351 38732/38732/28358 38733/38733/28359 +f 38725/38725/28352 38724/38724/28351 38733/38733/28359 +f 38725/38725/28352 38733/38733/28359 38734/38734/28360 +f 38732/38732/28358 38731/38731/28357 38735/38735/28361 +f 38732/38732/28358 38735/38735/28361 38736/38736/28362 +f 38733/38733/28359 38732/38732/28358 38736/38736/28362 +f 38733/38733/28359 38736/38736/28362 38737/38737/28363 +f 38734/38734/28360 38733/38733/28359 38737/38737/28363 +f 38734/38734/28360 38737/38737/28363 38738/38738/28364 +f 38729/38729/28355 38728/38728/28354 38739/38739/28364 +f 38729/38729/28355 38739/38739/28364 38740/38740/28365 +f 38564/38564/28198 38729/38729/28355 38740/38740/28365 +f 38564/38564/28198 38740/38740/28365 38565/38565/28199 +f 38731/38731/28357 38730/38730/28356 38741/38741/28366 +f 38731/38731/28357 38741/38741/28366 38735/38735/28361 +f 38565/38565/28199 38740/38740/28365 38742/38742/28367 +f 38565/38565/28199 38742/38742/28367 38566/38566/28200 +f 38735/38735/28361 38741/38741/28366 38743/38743/28368 +f 38735/38735/28361 38743/38743/28368 38744/38744/28369 +f 38736/38736/28362 38735/38735/28361 38744/38744/28369 +f 38736/38736/28362 38744/38744/28369 38745/38745/28370 +f 38737/38737/28363 38736/38736/28362 38745/38745/28370 +f 38737/38737/28363 38745/38745/28370 38746/38746/28371 +f 38738/38738/28364 38737/38737/28363 38746/38746/28371 +f 38738/38738/28364 38746/38746/28371 38747/38747/28372 +f 38740/38740/28365 38739/38739/28364 38748/38748/28372 +f 38740/38740/28365 38748/38748/28372 38742/38742/28367 +f 38745/38745/28370 38744/38744/28369 38749/38749/28373 +f 38745/38745/28370 38749/38749/28373 38750/38750/28374 +f 38746/38746/28371 38745/38745/28370 38750/38750/28374 +f 38746/38746/28371 38750/38750/28374 38751/38751/28375 +f 38747/38747/28372 38746/38746/28371 38751/38751/28375 +f 38747/38747/28372 38751/38751/28375 38752/38752/28376 +f 38742/38742/28367 38748/38748/28372 38753/38753/28376 +f 38742/38742/28367 38753/38753/28376 38754/38754/28377 +f 38566/38566/28200 38742/38742/28367 38754/38754/28377 +f 38566/38566/28200 38754/38754/28377 38567/38567/28201 +f 38744/38744/28369 38743/38743/28368 38755/38755/28378 +f 38744/38744/28369 38755/38755/28378 38749/38749/28373 +f 38567/38567/28201 38754/38754/28377 38756/38756/28379 +f 38567/38567/28201 38756/38756/28379 38568/38568/28202 +f 38749/38749/28373 38755/38755/28378 38757/38757/28380 +f 38749/38749/28373 38757/38757/28380 38758/38758/28381 +f 38750/38750/28374 38749/38749/28373 38758/38758/28381 +f 38750/38750/28374 38758/38758/28381 38759/38759/28382 +f 38751/38751/28375 38750/38750/28374 38759/38759/28382 +f 38751/38751/28375 38759/38759/28382 38760/38760/28383 +f 38752/38752/28376 38751/38751/28375 38760/38760/28383 +f 38752/38752/28376 38760/38760/28383 38761/38761/28384 +f 38754/38754/28377 38753/38753/28376 38762/38762/28384 +f 38754/38754/28377 38762/38762/28384 38756/38756/28379 +f 38760/38760/28383 38759/38759/28382 38763/38763/28385 +f 38760/38760/28383 38763/38763/28385 38764/38764/28386 +f 38762/38762/28384 38765/38765/28383 38766/38766/28387 +f 38762/38762/28384 38766/38766/28387 38767/38767/28388 +f 38756/38756/28379 38762/38762/28384 38767/38767/28388 +f 38756/38756/28379 38767/38767/28388 38768/38768/28389 +f 38568/38568/28202 38756/38756/28379 38768/38768/28389 +f 38568/38568/28202 38768/38768/28389 38569/38569/28203 +f 38758/38758/28381 38757/38757/28380 38769/38769/28390 +f 38758/38758/28381 38769/38769/28390 38770/38770/28391 +f 38759/38759/28382 38758/38758/28381 38770/38770/28391 +f 38759/38759/28382 38770/38770/28391 38763/38763/28385 +f 38770/38770/28391 38769/38769/28390 38771/38771/28392 +f 38770/38770/28391 38771/38771/28392 38772/38772/28393 +f 38763/38763/28385 38770/38770/28391 38772/38772/28393 +f 38763/38763/28385 38772/38772/28393 38773/38773/28394 +f 38766/38766/28387 38774/38774/28385 38775/38775/28394 +f 38766/38766/28387 38775/38775/28394 38776/38776/28395 +f 38767/38767/28388 38766/38766/28387 38776/38776/28395 +f 38767/38767/28388 38776/38776/28395 38777/38777/28396 +f 38768/38768/28389 38767/38767/28388 38777/38777/28396 +f 38768/38768/28389 38777/38777/28396 38778/38778/28397 +f 38569/38569/28203 38768/38768/28389 38778/38778/28397 +f 38569/38569/28203 38778/38778/28397 38570/38570/28204 +f 38776/38776/28395 38775/38775/28394 38779/38779/28398 +f 38776/38776/28395 38779/38779/28398 38780/38780/28399 +f 38777/38777/28396 38776/38776/28395 38780/38780/28399 +f 38777/38777/28396 38780/38780/28399 38781/38781/28400 +f 38778/38778/28397 38777/38777/28396 38781/38781/28400 +f 38778/38778/28397 38781/38781/28400 38782/38782/28401 +f 38570/38570/28204 38778/38778/28397 38782/38782/28401 +f 38570/38570/28204 38782/38782/28401 38571/38571/28205 +f 38772/38772/28393 38771/38771/28392 38783/38783/28402 +f 38772/38772/28393 38783/38783/28402 38784/38784/28403 +f 38775/38775/28394 38785/38785/28393 38786/38786/28404 +f 38775/38775/28394 38786/38786/28404 38779/38779/28398 +f 38786/38786/28404 38787/38787/28402 38573/38573/28207 +f 38786/38786/28404 38573/38573/28207 38572/38572/28206 +f 38779/38779/28398 38786/38786/28404 38572/38572/28206 +f 38779/38779/28398 38572/38572/28206 38576/38576/28210 +f 38780/38780/28399 38779/38779/28398 38576/38576/28210 +f 38780/38780/28399 38576/38576/28210 38578/38578/28212 +f 38781/38781/28400 38780/38780/28399 38578/38578/28212 +f 38781/38781/28400 38578/38578/28212 38580/38580/28214 +f 38782/38782/28401 38781/38781/28400 38580/38580/28214 +f 38782/38782/28401 38580/38580/28214 38582/38582/28216 +f 38571/38571/28205 38782/38782/28401 38582/38582/28216 +f 38571/38571/28205 38582/38582/28216 38540/38540/28174 +o Cube.051__0 +v 0.595203 1.003455 -1.000390 +v 0.641196 1.003275 -1.000251 +v 0.661952 1.088349 -1.044918 +v 0.615722 1.087653 -1.044044 +v 0.667346 1.002141 -1.003321 +v 0.688015 1.086892 -1.047974 +v 0.722763 1.201897 -1.114222 +v 0.697485 1.203787 -1.110983 +v 0.652339 1.203934 -1.107113 +v 0.581932 0.816377 -1.017895 +v 0.516993 0.816406 -1.018788 +v 0.519485 0.871382 -1.022355 +v 0.584435 0.871354 -1.021479 +v 0.451961 0.816433 -1.019671 +v 0.454423 0.871409 -1.023221 +v 0.457353 0.918258 -1.026587 +v 0.522446 0.918231 -1.025743 +v 0.587406 0.918205 -1.024887 +v 0.945209 1.391153 -2.447943 +v 0.922753 1.389219 -2.444382 +v 0.920418 1.475878 -2.372511 +v 0.942937 1.478149 -2.375877 +v 0.900252 1.386874 -2.440303 +v 0.897792 1.473183 -2.368632 +v 0.889099 1.553063 -2.267096 +v 0.911864 1.556125 -2.270419 +v 0.934473 1.558720 -2.273344 +v 0.448164 0.820357 -0.970271 +v 0.513159 0.820327 -0.969342 +v 0.515256 0.878670 -0.973400 +v 0.450225 0.878700 -0.974322 +v 0.578087 0.820298 -0.968405 +v 0.580204 0.878641 -0.972469 +v 0.582780 0.929007 -0.976421 +v 0.517814 0.929036 -0.977344 +v 0.452749 0.929064 -0.978254 +v 0.653412 0.816673 -1.012753 +v 0.651365 0.771054 -1.009865 +v 0.626560 0.770216 -1.013677 +v 0.627856 0.816399 -1.016734 +v 0.651365 0.771054 -1.009865 +v 0.646410 0.746664 -1.007038 +v 0.625579 0.740822 -1.008797 +v 0.626560 0.770216 -1.013677 +v 0.580362 0.739633 -1.009738 +v 0.580809 0.769985 -1.014811 +v 0.580809 0.769985 -1.014811 +v 0.465141 1.003508 -1.002102 +v 0.418892 1.003366 -1.003179 +v 0.409764 0.960351 -0.984355 +v 0.455982 0.960467 -0.983234 +v 0.393090 1.002253 -1.006909 +v 0.383983 0.959419 -0.988180 +v 0.380781 0.928195 -0.983264 +v 0.406554 0.928972 -0.979393 +v 0.968488 1.358998 -2.407463 +v 0.925672 1.360052 -2.406870 +v 0.926548 1.274231 -2.468406 +v 0.952960 1.273996 -2.468440 +v 0.900689 1.362335 -2.408676 +v 0.902973 1.276051 -2.470634 +v 0.904933 1.174394 -2.521887 +v 0.929964 1.173444 -2.519664 +v 0.972738 1.177664 -2.523062 +v 0.633298 0.918297 -1.023759 +v 0.630344 0.871410 -1.020333 +v 0.633298 0.918297 -1.023759 +v 0.658763 0.919073 -1.019859 +v 0.655855 0.871930 -1.016389 +v 0.630344 0.871410 -1.020333 +v 0.655855 0.871930 -1.016389 +v 0.549247 1.085081 -1.043027 +v 0.530240 1.003482 -1.001253 +v 0.569916 1.170800 -1.085941 +v 0.513659 1.203946 -1.108270 +v 0.484731 1.087698 -1.045563 +v 1.097181 1.518252 -2.263461 +v 1.077464 1.539219 -2.228978 +v 1.030483 1.525057 -2.267008 +v 1.032844 1.501295 -2.296847 +v 1.060653 1.547288 -2.200683 +v 1.023105 1.540756 -2.217143 +v 0.979670 1.547688 -2.196607 +v 0.970847 1.539729 -2.223524 +v 0.957926 1.518873 -2.256348 +v 0.879157 1.663291 -1.942399 +v 0.889121 1.669577 -1.943286 +v 0.924101 1.630928 -2.123359 +v 0.914236 1.624988 -2.120845 +v 0.889121 1.669577 -1.943286 +v 0.890526 1.677406 -1.943895 +v 0.925420 1.638327 -2.125912 +v 0.924101 1.630928 -2.123359 +v 0.945467 1.570748 -2.281597 +v 0.944235 1.564076 -2.277292 +v 0.944235 1.564076 -2.277292 +v 0.951133 0.912122 -2.624815 +v 0.960910 0.913099 -2.631360 +v 0.962369 0.760880 -2.650648 +v 0.952549 0.760517 -2.644126 +v 0.960910 0.913099 -2.631360 +v 0.962244 0.914313 -2.639389 +v 0.963752 0.761332 -2.658763 +v 0.962369 0.760880 -2.650648 +v 0.963481 0.607198 -2.664999 +v 0.962080 0.607415 -2.656875 +v 0.962080 0.607415 -2.656875 +v 0.952247 0.607590 -2.650384 +v 0.518551 1.176002 -1.152748 +v 0.572960 1.297372 -1.230379 +v 0.638073 1.297650 -1.228908 +v 0.597311 1.205758 -1.169709 +v 0.630895 1.413027 -1.326833 +v 0.680571 1.387223 -1.292656 +v 0.769181 1.412912 -1.327620 +v 0.704619 1.297326 -1.230173 +v 0.657257 1.175967 -1.151780 +v 0.934333 -0.042009 -2.510763 +v 0.911972 -0.038652 -2.511459 +v 0.911999 -0.039987 -2.523314 +v 0.936041 -0.043488 -2.522835 +v 0.889676 -0.034458 -2.511572 +v 0.890054 -0.035892 -2.523177 +v 0.911999 -0.039987 -2.523314 +v 0.890054 -0.035892 -2.523177 +v 0.894400 -0.035178 -2.530620 +v 0.914094 -0.037634 -2.532676 +v 0.936041 -0.043488 -2.522835 +v 0.955652 -0.041417 -2.534258 +v 1.041214 1.619050 -1.948824 +v 1.081218 1.613647 -1.951141 +v 1.027388 1.611184 -1.782825 +v 0.982697 1.612809 -1.781217 +v 1.106098 1.616215 -1.952191 +v 1.053250 1.614177 -1.783003 +v 0.986578 1.576527 -1.618797 +v 0.961747 1.573830 -1.619315 +v 0.920691 1.577837 -1.617694 +v 0.602210 0.978220 -1.043056 +v 0.589426 0.990719 -1.053171 +v 0.626547 1.061938 -1.091170 +v 0.642338 1.065840 -1.089779 +v 0.580727 1.005841 -1.064256 +v 0.603061 1.059985 -1.093730 +v 0.607726 1.114639 -1.122438 +v 0.625865 1.135083 -1.130708 +v 0.463429 0.978270 -1.044690 +v 0.422410 0.987235 -1.048506 +v 0.441931 1.068427 -1.091247 +v 0.467882 1.065892 -1.091498 +v 0.397128 0.989419 -1.045841 +v 0.417919 1.070273 -1.088253 +v 0.452525 1.180304 -1.150893 +v 0.477839 1.178178 -1.153628 +v 1.107065 1.358629 -2.413156 +v 1.149677 1.359453 -2.416226 +v 1.145999 1.441656 -2.350127 +v 1.101014 1.441691 -2.349046 +v 1.174422 1.361629 -2.420195 +v 1.171574 1.444020 -2.353637 +v 1.162618 1.519815 -2.259378 +v 1.137900 1.517256 -2.257207 +v 0.944864 1.621744 -1.602903 +v 0.935092 1.627957 -1.600954 +v 0.858744 1.555102 -1.438135 +v 0.868449 1.549381 -1.441195 +v 0.935092 1.627957 -1.600954 +v 0.933737 1.635603 -1.598749 +v 0.857397 1.562155 -1.434437 +v 0.858744 1.555102 -1.438135 +v 0.781752 1.461318 -1.291616 +v 0.783112 1.455048 -1.296591 +v 0.783112 1.455048 -1.296591 +v 0.792795 1.449972 -1.300605 +v 0.967235 1.618566 -1.604239 +v 1.034042 1.657778 -1.774081 +v 1.011518 1.661091 -1.773103 +v 0.989407 1.614740 -1.605909 +v 1.056339 1.653793 -1.775463 +v 1.108600 1.655189 -1.951883 +v 1.086178 1.659115 -1.950974 +v 1.063558 1.662382 -1.950428 +v 0.609729 1.449938 -1.299866 +v 0.619765 1.454603 -1.295411 +v 0.695550 1.554884 -1.435337 +v 0.685498 1.549555 -1.438745 +v 0.619765 1.454603 -1.295411 +v 0.621209 1.460385 -1.289840 +v 0.697016 1.561491 -1.430954 +v 0.695550 1.554884 -1.435337 +v 0.773193 1.635524 -1.593566 +v 0.771716 1.628158 -1.596444 +v 0.771716 1.628158 -1.596444 +v 0.761662 1.622226 -1.598538 +v 0.782246 1.578283 -1.614600 +v 0.850482 1.613413 -1.776866 +v 0.917500 1.615269 -1.778767 +v 0.871482 1.595665 -1.657305 +v 0.901655 1.619800 -1.942907 +v 0.961818 1.628250 -1.901064 +v 0.901655 1.619800 -1.942907 +v 0.934420 1.614909 -1.997311 +v 0.980786 1.627621 -1.957680 +v 0.961818 1.628250 -1.901064 +v 0.952813 1.604524 -2.026383 +v 0.990420 1.610022 -2.009429 +v 1.033891 1.604084 -2.030151 +v 1.041223 1.614321 -2.002150 +v 0.980786 1.627621 -1.957680 +v 1.041223 1.614321 -2.002150 +v 0.882001 1.560405 -1.566138 +v 0.848893 1.580770 -1.602605 +v 0.855752 1.545017 -1.540668 +v 0.824485 1.553982 -1.556775 +v 0.775507 1.545210 -1.539323 +v 0.776295 1.560690 -1.564175 +v 0.624106 0.820237 -0.968248 +v 0.626226 0.878544 -0.972310 +v 0.650237 0.819939 -0.971476 +v 0.652375 0.878001 -0.975505 +v 0.654970 0.928074 -0.979417 +v 0.628804 0.928873 -0.976261 +v 1.116638 -0.042009 -2.517686 +v 1.139068 -0.038652 -2.520063 +v 1.139090 -0.036291 -2.508422 +v 1.114971 -0.039696 -2.505834 +v 1.161553 -0.034458 -2.521799 +v 1.161219 -0.032282 -2.510340 +v 1.157009 -0.029404 -2.503572 +v 1.137237 -0.031277 -2.500539 +v 1.095578 -0.034561 -2.496282 +v 0.879157 1.663291 -1.942399 +v 0.856312 1.660225 -1.941201 +v 0.804740 1.658763 -1.766516 +v 0.827661 1.661849 -1.766814 +v 0.833244 1.656518 -1.940197 +v 0.781569 1.654979 -1.766412 +v 0.715536 1.615614 -1.599758 +v 0.738710 1.619281 -1.599097 +v 0.527990 1.297500 -1.231228 +v 0.501823 1.299796 -1.228771 +v 0.564711 1.413398 -1.329671 +v 0.589800 1.410972 -1.331436 +v 0.577210 0.772398 -0.966151 +v 0.623044 0.772578 -0.965989 +v 0.577210 0.772398 -0.966151 +v 0.577319 0.741508 -0.968300 +v 0.622595 0.742665 -0.968049 +v 0.623044 0.772578 -0.965989 +v 0.643687 0.748351 -0.969719 +v 0.648375 0.773071 -0.969131 +v 0.648375 0.773071 -0.969131 +v 0.716016 1.339467 -1.189466 +v 0.725662 1.331695 -1.192346 +v 0.714777 1.345775 -1.184010 +v 0.716016 1.339467 -1.189466 +v 0.648642 1.253101 -1.117603 +v 0.649044 1.244049 -1.121807 +v 0.649044 1.244049 -1.121807 +v 1.093858 -0.018108 -2.549786 +v 1.090118 -0.029656 -2.545092 +v 1.024684 -0.029959 -2.542908 +v 1.024935 -0.020810 -2.547529 +v 1.093293 -0.041416 -2.539441 +v 1.024379 -0.041554 -2.539001 +v 0.959267 -0.029655 -2.540286 +v 0.956198 -0.018108 -2.544876 +v 1.112978 0.903546 -2.574231 +v 1.155513 0.903754 -2.576121 +v 1.153693 1.046027 -2.556376 +v 1.108579 1.046716 -2.555539 +v 1.180204 0.904346 -2.579887 +v 1.179111 1.046928 -2.560149 +v 1.177826 1.174094 -2.529400 +v 1.153226 1.173178 -2.525801 +v 1.110827 1.177489 -2.526989 +v 1.118339 0.046309 -2.563136 +v 1.108420 0.045094 -2.569312 +v 1.112075 0.152811 -2.588871 +v 1.121975 0.154006 -2.582606 +v 1.108420 0.045094 -2.569312 +v 1.106860 0.043587 -2.577299 +v 1.110550 0.151330 -2.596874 +v 1.112075 0.152811 -2.588871 +v 1.115508 0.296441 -2.623214 +v 1.116987 0.297732 -2.615173 +v 1.116987 0.297732 -2.615173 +v 1.126862 0.298773 -2.608774 +v 0.933657 1.578187 -2.110271 +v 0.917498 1.579202 -2.108482 +v 0.957369 1.575645 -2.110896 +v 0.944277 -0.131524 -2.465374 +v 0.940871 -0.291781 -2.380672 +v 0.944531 -0.287798 -2.369773 +v 0.948123 -0.128894 -2.454002 +v 0.930301 -0.474571 -2.268361 +v 0.933676 -0.468981 -2.258161 +v 0.944531 -0.287798 -2.369773 +v 0.933676 -0.468981 -2.258161 +v 0.956689 -0.464849 -2.251648 +v 0.967891 -0.284854 -2.362746 +v 0.948123 -0.128894 -2.454002 +v 0.971752 -0.126951 -2.446482 +v 0.963032 -0.010487 -2.493612 +v 0.962221 -0.022013 -2.491600 +v 1.027228 -0.022031 -2.493750 +v 1.027569 -0.010487 -2.495925 +v 0.957891 -0.034561 -2.491092 +v 1.026881 -0.033931 -2.491173 +v 1.095578 -0.034561 -2.496282 +v 1.092191 -0.022013 -2.496384 +v 1.092082 -0.010487 -2.498242 +v 0.737581 1.574572 -1.614108 +v 0.804000 1.612198 -1.775454 +v 0.712410 1.577432 -1.612418 +v 0.778134 1.615416 -1.773906 +v 0.830354 1.617632 -1.940662 +v 0.855649 1.614821 -1.941730 +v 0.586814 1.447585 -1.301970 +v 0.522229 1.328929 -1.195226 +v 0.546953 1.331639 -1.192911 +v 0.563957 1.444574 -1.304350 +v 0.499171 1.326405 -1.198309 +v 0.448699 1.201989 -1.116591 +v 0.473286 1.203857 -1.112940 +v 0.844808 -0.835619 -1.906735 +v 0.839231 -0.845394 -1.891386 +v 0.841450 -0.834410 -1.883542 +v 0.847132 -0.823494 -1.897923 +v 0.798062 -0.904545 -1.806288 +v 0.800213 -0.894230 -1.799508 +v 0.841450 -0.834410 -1.883542 +v 0.800213 -0.894230 -1.799508 +v 0.822293 -0.886605 -1.793549 +v 0.863588 -0.826295 -1.877171 +v 0.847132 -0.823494 -1.897923 +v 0.869870 -0.814561 -1.890819 +v 1.103636 -0.131524 -2.472206 +v 1.099245 -0.291781 -2.388666 +v 1.095597 -0.295764 -2.399616 +v 1.099785 -0.134153 -2.483597 +v 1.087664 -0.474571 -2.276431 +v 1.084311 -0.480162 -2.286716 +v 1.095597 -0.295764 -2.399616 +v 1.084311 -0.480162 -2.286716 +v 1.061300 -0.484294 -2.293240 +v 1.072239 -0.298707 -2.406652 +v 1.099785 -0.134153 -2.483597 +v 1.076154 -0.136096 -2.491120 +v 1.019349 -0.299747 -2.406850 +v 1.022900 -0.136782 -2.491838 +v 1.008811 -0.485752 -2.293217 +v 0.956367 -0.484294 -2.287762 +v 0.966644 -0.298707 -2.401263 +v 0.969921 -0.136096 -2.486544 +v 1.020768 -0.283815 -2.362487 +v 1.025013 -0.126266 -2.445743 +v 1.009154 -0.463391 -2.251574 +v 1.061574 -0.464849 -2.256931 +v 1.073461 -0.284854 -2.368015 +v 1.077998 -0.126951 -2.451016 +v 0.950559 -0.906368 -1.838202 +v 0.841111 -1.056010 -1.614671 +v 0.787156 -1.059779 -1.618704 +v 0.880827 -0.923295 -1.818771 +v 0.737394 -1.197146 -1.386686 +v 0.684455 -1.200059 -1.393995 +v 0.631119 -1.197145 -1.399836 +v 0.734087 -1.056026 -1.623435 +v 0.831461 -0.906559 -1.842504 +v 1.005837 -0.836030 -1.902592 +v 0.996285 -0.845445 -1.887230 +v 0.996948 -0.856400 -1.895805 +v 1.004798 -0.848725 -1.911668 +v 0.955077 -0.904545 -1.799241 +v 0.955551 -0.913135 -1.808914 +v 0.950559 -0.906368 -1.838202 +v 0.996600 -0.864863 -1.905419 +v 0.988236 -0.861998 -1.919706 +v 0.988236 -0.861998 -1.919706 +v 0.981371 -0.876200 -1.919451 +v 0.929260 -0.878220 -1.922898 +v 0.928627 -0.866135 -1.924387 +v 0.979165 -0.893278 -1.914154 +v 0.928049 -0.894802 -1.918117 +v 0.875147 -0.891759 -1.916565 +v 0.875435 -0.876525 -1.921488 +v 0.867216 -0.861896 -1.922367 +v 0.915694 -0.823440 -1.873689 +v 0.923314 -0.811473 -1.887041 +v 0.874365 -0.883914 -1.789406 +v 0.927012 -0.886605 -1.788747 +v 0.968338 -0.826318 -1.874281 +v 0.977283 -0.814738 -1.887860 +v 0.603217 -1.177719 -1.398291 +v 0.536137 -1.244427 -1.245838 +v 0.539319 -1.233008 -1.244989 +v 0.605771 -1.166549 -1.395099 +v 0.498551 -1.252180 -1.144710 +v 0.502381 -1.241405 -1.146609 +v 0.539319 -1.233008 -1.244989 +v 0.502381 -1.241405 -1.146609 +v 0.526091 -1.233441 -1.145291 +v 0.562525 -1.224568 -1.241361 +v 0.605771 -1.166549 -1.395099 +v 0.628461 -1.158293 -1.390132 +v 0.729825 -1.021055 -1.603516 +v 0.782315 -1.018301 -1.597723 +v 0.681418 -1.155379 -1.382745 +v 0.734771 -1.158293 -1.376825 +v 0.835359 -1.021055 -1.594525 +v 0.705307 -1.039416 -1.614343 +v 0.707531 -1.028858 -1.609132 +v 0.707531 -1.028858 -1.609132 +v 0.863564 -1.039416 -1.601000 +v 0.861842 -1.049523 -1.607002 +v 0.762656 -1.177719 -1.378448 +v 0.760086 -1.188889 -1.381708 +v 0.861842 -1.049523 -1.607002 +v 0.760086 -1.188889 -1.381708 +v 0.955551 -0.913135 -1.808914 +v 0.658574 -1.252180 -1.123882 +v 0.635758 -1.233063 -1.051538 +v 0.631515 -1.242032 -1.046498 +v 0.654724 -1.262956 -1.121999 +v 0.622957 -1.209270 -1.001459 +v 0.618560 -1.215865 -0.993497 +v 0.631515 -1.242032 -1.046498 +v 0.618560 -1.215865 -0.993497 +v 0.594302 -1.220738 -0.988414 +v 0.607444 -1.248662 -1.044552 +v 0.654724 -1.262956 -1.121999 +v 0.631012 -1.270919 -1.123319 +v 0.695992 -1.244427 -1.222937 +v 0.692795 -1.255847 -1.223829 +v 0.692795 -1.255847 -1.223829 +v 0.654724 -1.262956 -1.121999 +v 0.631012 -1.270919 -1.123319 +v 0.669586 -1.264287 -1.227463 +v 0.616346 -1.267267 -1.235175 +v 0.577551 -1.273730 -1.129646 +v 0.524353 -1.270919 -1.137186 +v 0.563033 -1.264288 -1.242681 +v 0.615781 -1.221588 -1.233601 +v 0.579574 -1.230631 -1.138946 +v 0.632793 -1.233441 -1.131388 +v 0.669111 -1.224568 -1.226045 +v 0.589212 -1.198705 -0.957022 +v 0.535162 -1.199833 -0.955332 +v 0.540340 -1.222459 -0.988349 +v 0.588981 -1.155838 -0.944993 +v 0.534916 -1.156449 -0.942831 +v 0.481369 -1.155838 -0.946556 +v 0.481648 -1.198705 -0.958903 +v 0.486914 -1.220738 -0.992500 +v 0.553712 -1.251001 -1.047708 +v 0.577551 -1.273730 -1.129646 +v 0.500443 -1.248662 -1.053640 +v 0.524353 -1.270919 -1.137186 +v 0.526091 -1.233441 -1.145291 +v 0.503502 -1.217463 -1.072146 +v 0.557261 -1.215124 -1.068994 +v 0.579574 -1.230631 -1.138946 +v 0.490453 -1.197803 -1.020592 +v 0.544446 -1.196084 -1.020674 +v 0.597904 -1.197803 -1.016539 +v 0.610558 -1.217463 -1.063067 +v 0.632793 -1.233441 -1.131388 +v 0.475215 -1.233063 -1.065164 +v 0.479435 -1.224092 -1.070199 +v 0.461829 -1.209270 -1.007563 +v 0.466198 -1.202677 -1.015510 +v 0.479435 -1.224092 -1.070199 +v 0.466198 -1.202677 -1.015510 +v 0.502381 -1.241405 -1.146609 +v 0.456169 -1.151764 -0.966562 +v 0.457699 -1.069260 -0.967512 +v 0.462056 -1.068542 -0.979261 +v 0.460512 -1.149421 -0.977792 +v 0.459373 -0.980361 -0.972547 +v 0.463768 -0.980729 -0.984426 +v 0.462056 -1.068542 -0.979261 +v 0.463768 -0.980729 -0.984426 +v 0.488105 -0.981000 -0.992908 +v 0.486357 -1.068011 -0.987646 +v 0.460512 -1.149421 -0.977792 +v 0.484791 -1.147689 -0.985793 +v 0.485185 -1.183655 -0.993960 +v 0.539268 -1.182526 -0.995666 +v 0.538890 -1.147079 -0.987966 +v 0.592471 -1.147689 -0.984252 +v 0.592817 -1.183655 -0.992110 +v 0.456518 -1.191180 -0.976898 +v 0.460891 -1.186853 -0.986916 +v 0.460891 -1.186853 -0.986916 +v 0.617914 -1.191180 -0.974100 +v 0.613510 -1.195507 -0.964068 +v 0.617637 -1.151763 -0.964234 +v 0.613265 -1.154106 -0.952995 +v 0.613510 -1.195507 -0.964068 +v 0.613265 -1.154106 -0.952995 +v 0.491176 -0.927358 -0.996157 +v 0.543034 -0.927234 -0.998448 +v 0.542267 -0.981097 -0.995259 +v 0.502318 -0.906657 -0.995730 +v 0.542869 -0.903461 -0.996766 +v 0.583169 -0.906657 -0.994591 +v 0.594361 -0.927358 -0.994704 +v 0.595886 -0.981001 -0.991385 +v 0.619244 -1.069259 -0.965199 +v 0.614857 -1.069976 -0.953443 +v 0.620994 -0.980361 -0.970252 +v 0.616571 -0.979992 -0.958367 +v 0.614857 -1.069976 -0.953443 +v 0.616571 -0.979992 -0.958367 +v 0.592229 -0.979720 -0.949883 +v 0.590552 -1.070507 -0.945057 +v 0.614857 -1.069976 -0.953443 +v 0.590552 -1.070507 -0.945057 +v 0.536458 -1.070693 -0.942754 +v 0.538101 -0.979624 -0.947540 +v 0.536458 -1.070693 -0.942754 +v 0.484515 -0.979720 -0.951421 +v 0.482889 -1.070507 -0.946607 +v 0.482889 -1.070507 -0.946607 +v 0.540485 -1.067824 -0.989957 +v 0.594087 -1.068011 -0.986111 +v 0.663068 0.818301 -0.991950 +v 0.662573 0.817362 -1.003839 +v 0.664944 0.873216 -1.007559 +v 0.665352 0.874960 -0.995783 +v 0.653412 0.816673 -1.012753 +v 0.655855 0.871930 -1.016389 +v 0.658763 0.919073 -1.019859 +v 0.667778 0.920981 -1.011124 +v 0.668096 0.923568 -0.999475 +v 0.366466 0.818431 -0.996113 +v 0.367001 0.819371 -0.984273 +v 0.369083 0.876835 -0.988177 +v 0.368640 0.875090 -0.999894 +v 0.376272 0.820062 -0.975398 +v 0.378298 0.878123 -0.979395 +v 0.380781 0.928195 -0.983264 +v 0.371624 0.926284 -0.991941 +v 0.371274 0.923695 -1.003520 +v 0.383698 0.995840 -1.026508 +v 0.404406 1.078636 -1.069803 +v 0.407023 1.073829 -1.080457 +v 0.386280 0.992150 -1.037681 +v 0.439149 1.191148 -1.133816 +v 0.441678 1.184913 -1.143662 +v 0.452525 1.180304 -1.150893 +v 0.417919 1.070273 -1.088253 +v 0.397128 0.989419 -1.045841 +v 0.735824 1.191052 -1.131520 +v 0.785255 1.312976 -1.212657 +v 0.783093 1.320626 -1.203740 +v 0.733331 1.197284 -1.121520 +v 0.848755 1.428721 -1.318049 +v 0.847119 1.437689 -1.310610 +v 0.783093 1.320626 -1.203740 +v 0.847119 1.437689 -1.310610 +v 0.837231 1.444335 -1.305113 +v 0.772805 1.326291 -1.197205 +v 0.733331 1.197284 -1.121520 +v 0.680583 0.995724 -1.022786 +v 0.701275 1.078532 -1.066600 +v 0.698686 1.083337 -1.055824 +v 0.678020 0.999412 -1.011521 +v 0.722763 1.201897 -1.114222 +v 0.688015 1.086892 -1.047974 +v 0.667346 1.002141 -1.003321 +v 0.489028 1.313099 -1.213556 +v 0.491222 1.305449 -1.222305 +v 0.552870 1.428984 -1.316944 +v 0.554518 1.420021 -1.324225 +v 0.491222 1.305449 -1.222305 +v 0.554518 1.420021 -1.324225 +v 0.501823 1.299796 -1.228771 +v 0.702518 1.596538 -1.605786 +v 0.768409 1.635226 -1.769745 +v 0.768848 1.623848 -1.771950 +v 0.703048 1.585559 -1.609460 +v 0.820380 1.637114 -1.939922 +v 0.820972 1.625930 -1.940120 +v 0.768848 1.623848 -1.771950 +v 0.820972 1.625930 -1.940120 +v 0.703048 1.585559 -1.609460 +v 0.627311 1.525896 -1.450941 +v 0.628316 1.515775 -1.456390 +v 0.628316 1.515775 -1.456390 +v 0.638031 1.508291 -1.460568 +v 0.923342 1.525325 -1.454702 +v 0.922314 1.535455 -1.449136 +v 0.999209 1.595576 -1.612574 +v 0.998618 1.606570 -1.608840 +v 0.922314 1.535455 -1.449136 +v 0.998618 1.606570 -1.608840 +v 0.912840 1.542974 -1.444946 +v 1.066086 1.633915 -1.779580 +v 1.065559 1.645315 -1.777369 +v 1.118678 1.635629 -1.952501 +v 1.117976 1.646845 -1.952357 +v 1.108600 1.655189 -1.951883 +v 1.056339 1.653793 -1.775463 +v 1.065559 1.645315 -1.777369 +v 0.856131 1.600703 -2.110562 +v 0.856929 1.590343 -2.107565 +v 0.877085 1.537058 -2.255645 +v 0.878110 1.527831 -2.249485 +v 0.856929 1.590343 -2.107565 +v 0.878110 1.527831 -2.249485 +v 0.887754 1.520978 -2.245392 +v 0.866436 1.582650 -2.105794 +v 0.866436 1.582650 -2.105794 +v 0.830354 1.617632 -1.940662 +v 1.154122 1.599307 -2.125215 +v 1.153190 1.609713 -2.128334 +v 1.174306 1.535900 -2.271098 +v 1.173135 1.545185 -2.277430 +v 1.163460 1.552081 -2.281635 +v 1.143661 1.617450 -2.130198 +v 0.895634 0.907743 -2.597636 +v 0.896705 0.759511 -2.616958 +v 0.898285 0.759109 -2.605362 +v 0.897363 0.905863 -2.586316 +v 0.896248 0.609204 -2.623075 +v 0.897756 0.609936 -2.611287 +v 0.898285 0.759109 -2.605362 +v 0.897756 0.609936 -2.611287 +v 0.907672 0.610476 -2.602510 +v 0.908259 0.758810 -2.596763 +v 0.897363 0.905863 -2.586316 +v 0.907449 0.904467 -2.578007 +v 0.889181 1.374629 -2.424000 +v 0.891058 1.286473 -2.487472 +v 0.892830 1.280491 -2.477611 +v 0.890711 1.367573 -2.414975 +v 0.892792 1.182736 -2.540000 +v 0.894701 1.177947 -2.529448 +v 0.892830 1.280491 -2.477611 +v 0.894701 1.177947 -2.529448 +v 0.890711 1.367573 -2.414975 +v 1.185230 1.373974 -2.436766 +v 1.186631 1.286058 -2.498195 +v 1.184749 1.292099 -2.508200 +v 1.183573 1.381090 -2.445958 +v 1.188028 1.182508 -2.548343 +v 1.186028 1.187350 -2.559015 +v 1.184749 1.292099 -2.508200 +v 1.186028 1.187350 -2.559015 +v 1.175756 1.190932 -2.566647 +v 1.174566 1.296572 -2.515265 +v 1.183573 1.381090 -2.445958 +v 1.173557 1.386365 -2.452357 +v 1.190805 0.907663 -2.599757 +v 1.191923 0.759470 -2.616038 +v 1.190320 0.759887 -2.627646 +v 1.189032 0.909571 -2.611126 +v 1.191436 0.609190 -2.620894 +v 1.189920 0.608463 -2.632668 +v 1.180000 0.607926 -2.641435 +v 1.180334 0.760194 -2.636253 +v 1.189032 0.909571 -2.611126 +v 1.190320 0.759887 -2.627646 +v 1.180334 0.760194 -2.636253 +v 1.178922 0.910981 -2.619463 +v 0.879085 -0.014299 -2.515185 +v 0.880145 -0.025437 -2.513007 +v 0.882092 -0.023539 -2.501375 +v 0.881075 -0.012472 -2.503472 +v 0.880145 -0.025437 -2.513007 +v 0.891240 -0.032282 -2.500187 +v 0.882092 -0.023539 -2.501375 +v 0.896294 -0.029404 -2.493807 +v 0.891945 -0.022015 -2.493356 +v 0.881075 -0.012472 -2.503472 +v 0.882092 -0.023539 -2.501375 +v 0.891945 -0.022015 -2.493356 +v 0.891319 -0.011122 -2.495131 +v 1.173380 -0.014299 -2.525784 +v 1.171624 -0.025437 -2.523767 +v 1.169667 -0.027194 -2.535418 +v 1.171377 -0.016127 -2.537488 +v 1.161553 -0.034458 -2.521799 +v 1.159997 -0.035892 -2.533317 +v 1.169667 -0.027194 -2.535418 +v 1.159997 -0.035892 -2.533317 +v 1.155058 -0.035178 -2.540369 +v 1.159840 -0.028298 -2.543507 +v 1.171377 -0.016127 -2.537488 +v 1.161146 -0.017477 -2.545820 +v 0.944302 0.298772 -2.606994 +v 0.921883 0.299276 -2.603529 +v 0.926639 0.453109 -2.631773 +v 0.949097 0.452768 -2.634993 +v 0.899518 0.299797 -2.599320 +v 0.904213 0.453542 -2.627819 +v 0.926639 0.453109 -2.631773 +v 0.904213 0.453542 -2.627819 +v 0.907312 0.607930 -2.643472 +v 0.929767 0.607696 -2.647283 +v 0.949097 0.452768 -2.634993 +v 0.662556 1.546884 -1.440141 +v 0.639512 1.543493 -1.441672 +v 1.128433 1.390805 -2.456053 +v 1.150999 1.388805 -2.454479 +v 1.151941 1.298624 -2.517823 +v 1.129371 1.300258 -2.519797 +v 1.153095 1.192560 -2.569615 +v 1.130533 1.193811 -2.571961 +v 0.646783 0.987153 -1.045851 +v 0.636795 0.947339 -1.028178 +v 0.590895 0.945675 -1.028539 +v 0.671403 0.989316 -1.042558 +v 0.662175 0.948530 -1.024445 +v 0.587406 0.918205 -1.024887 +v 1.136285 -0.018031 -2.548736 +v 1.134968 -0.029123 -2.546029 +v 1.135089 -0.037634 -2.540967 +v 0.405711 0.816494 -1.019776 +v 0.408128 0.871503 -1.023317 +v 0.379363 0.816791 -1.016522 +v 0.381718 0.872046 -1.020093 +v 0.384536 0.919187 -1.023481 +v 0.411012 0.918389 -1.026673 +v 0.814977 1.447413 -1.302611 +v 0.890685 1.546475 -1.442881 +v 1.105783 0.304985 -2.554932 +v 1.148243 0.305429 -2.556973 +v 1.151831 0.458435 -2.582747 +v 1.106784 0.458537 -2.582778 +v 1.172899 0.305033 -2.560944 +v 1.177337 0.458034 -2.586235 +v 1.180386 0.610457 -2.600518 +v 1.155671 0.610775 -2.597471 +v 1.113589 0.611605 -2.600192 +v 0.366943 0.771285 -0.993443 +v 0.367470 0.772097 -0.981628 +v 0.376709 0.740660 -0.991849 +v 0.376859 0.742380 -0.980274 +v 0.367470 0.772097 -0.981628 +v 0.376859 0.742380 -0.980274 +v 0.381067 0.748468 -0.973486 +v 0.376393 0.773193 -0.973036 +v 0.376393 0.773193 -0.973036 +v 0.888285 1.504861 -1.465583 +v 0.862139 1.504826 -1.464997 +v 0.911571 1.507756 -1.464250 +v 0.838101 1.413154 -1.330970 +v 0.813437 1.410776 -1.332570 +v 0.891508 1.622107 -2.118704 +v 0.868587 1.618674 -2.116483 +v 0.833244 1.656518 -1.940197 +v 0.856312 1.660225 -1.941201 +v 0.917253 -0.010566 -2.492480 +v 0.916973 -0.021758 -2.490736 +v 0.916973 -0.021758 -2.490736 +v 0.916182 -0.031277 -2.492232 +v 0.962221 -0.022013 -2.491600 +v 0.957891 -0.034561 -2.491092 +v 0.661700 1.505304 -1.462496 +v 0.688304 1.505160 -1.462626 +v 1.063558 1.662382 -1.950428 +v 1.086178 1.659115 -1.950974 +v 1.121208 1.621083 -2.130181 +v 1.098594 1.624116 -2.130195 +v 1.108600 1.655189 -1.951883 +v 1.143661 1.617450 -2.130198 +v 1.163460 1.552081 -2.281635 +v 1.141010 1.555305 -2.282592 +v 1.118442 1.558001 -2.283198 +v 0.404068 0.878644 -0.975476 +v 0.378298 0.878123 -0.979395 +v 0.376272 0.820062 -0.975398 +v 0.402040 0.820337 -0.971437 +v 1.118441 1.578358 -2.117235 +v 1.092872 1.578308 -2.116930 +v 1.141965 1.581289 -2.119124 +v 1.106098 1.616215 -1.952191 +v 1.081218 1.613647 -1.951141 +v 1.041214 1.619050 -1.948824 +v 0.974968 0.903615 -2.573430 +v 0.932379 0.903863 -2.574615 +v 0.931710 0.758684 -2.593109 +v 0.958051 0.758641 -2.591916 +v 0.932568 0.610793 -2.599127 +v 0.975582 0.611616 -2.601413 +v 0.749841 1.328853 -1.194303 +v 0.855649 1.614821 -1.941730 +v 0.890074 1.579504 -2.106240 +v 0.830354 1.617632 -1.940662 +v 0.912930 1.518231 -2.245819 +v 0.928692 0.911634 -2.621434 +v 0.927038 1.060056 -2.597854 +v 0.949445 1.060916 -2.601405 +v 0.906315 0.911007 -2.617427 +v 0.904714 1.058928 -2.593691 +v 0.903160 1.191056 -2.558749 +v 0.925476 1.192649 -2.562991 +v 0.947867 1.193891 -2.566640 +v 0.750302 1.297415 -1.230854 +v 0.775507 1.299686 -1.228233 +v 0.726603 1.180221 -1.149035 +v 0.702052 1.178114 -1.152151 +v 1.133798 0.912112 -2.626193 +v 1.156322 0.911621 -2.623147 +v 1.157782 0.760343 -2.640247 +v 1.135276 0.760516 -2.643573 +v 1.180000 0.607926 -2.641435 +v 1.157480 0.607695 -2.645577 +v 1.134987 0.607593 -2.649014 +v 0.669176 1.068356 -1.089005 +v 0.692173 1.070183 -1.085501 +v 0.671422 0.953910 -1.004263 +v 0.668888 0.957008 -0.992768 +v 0.665606 0.926157 -0.987866 +v 0.658224 0.959301 -0.984402 +v 0.654970 0.928074 -0.979417 +v 0.374550 0.954034 -1.008218 +v 0.377098 0.950935 -1.019637 +v 0.373771 0.921105 -1.015061 +v 0.387908 0.948641 -1.027970 +v 0.384536 0.919187 -1.023481 +v 0.457353 0.918258 -1.026587 +v 0.411012 0.918389 -1.026673 +v 0.414244 0.947428 -1.031014 +v 0.459891 0.945727 -1.030203 +v 0.384536 0.919187 -1.023481 +v 0.387908 0.948641 -1.027970 +v 0.525028 0.943905 -1.028503 +v 0.522446 0.918231 -1.025743 +v 0.527602 0.956663 -1.033035 +v 0.586038 0.960411 -0.981432 +v 0.521066 0.960439 -0.982340 +v 0.439424 1.088430 -1.047504 +v 0.413770 1.086992 -1.051132 +v 0.632056 0.960256 -0.981276 +v 0.658224 0.959301 -0.984402 +v 0.578826 0.726637 -0.988389 +v 0.577953 0.728918 -0.976554 +v 0.513031 0.728947 -0.977484 +v 0.513900 0.726666 -0.989309 +v 0.512400 0.741538 -0.969237 +v 0.447418 0.741567 -0.970166 +v 0.448042 0.728976 -0.978406 +v 0.448902 0.726695 -0.990221 +v 0.624802 0.728358 -0.987807 +v 0.623754 0.730571 -0.976033 +v 0.650665 0.740538 -0.987981 +v 0.648854 0.742258 -0.976395 +v 0.448902 0.726695 -0.990221 +v 0.402737 0.728457 -0.990941 +v 0.403769 0.729597 -1.002834 +v 0.449766 0.727897 -1.002195 +v 0.376709 0.740660 -0.991849 +v 0.378503 0.741324 -1.003505 +v 0.383708 0.746778 -1.010687 +v 0.404941 0.740918 -1.011855 +v 0.450417 0.739689 -1.011538 +v 0.447309 0.772456 -0.968022 +v 0.512290 0.772427 -0.967090 +v 0.447309 0.772456 -0.968022 +v 0.512290 0.772427 -0.967090 +v 0.515875 0.770014 -1.015711 +v 0.515429 0.739662 -1.010642 +v 0.515875 0.770014 -1.015711 +v 0.450857 0.770042 -1.016603 +v 0.450857 0.770042 -1.016603 +v 0.376393 0.773193 -0.973036 +v 0.401382 0.772678 -0.969181 +v 0.402032 0.742764 -0.971217 +v 0.401382 0.772678 -0.969181 +v 0.660674 0.771155 -0.989298 +v 0.660187 0.770795 -1.001178 +v 0.650665 0.740538 -0.987981 +v 0.650552 0.741205 -0.999702 +v 0.646410 0.746664 -1.007038 +v 0.651365 0.771054 -1.009865 +v 0.404813 0.770312 -1.016738 +v 0.404813 0.770312 -1.016738 +v 0.379291 0.771173 -1.013635 +v 0.379291 0.771173 -1.013635 +v 0.487202 -0.900289 -0.977562 +v 0.488481 -0.900300 -0.965777 +v 0.540046 -0.893073 -0.965433 +v 0.541096 -0.892768 -0.977344 +v 0.499018 -0.903945 -0.958288 +v 0.539304 -0.900550 -0.956585 +v 0.579826 -0.903945 -0.957141 +v 0.591619 -0.900300 -0.964314 +v 0.594974 -0.900289 -0.976038 +v 0.463500 -0.925336 -0.976133 +v 0.467782 -0.926297 -0.987963 +v 0.487202 -0.900289 -0.977562 +v 0.490537 -0.901993 -0.989158 +v 0.467782 -0.926297 -0.987963 +v 0.490537 -0.901993 -0.989158 +v 0.618419 -0.925336 -0.973941 +v 0.614110 -0.924699 -0.962082 +v 0.594974 -0.900289 -0.976038 +v 0.591619 -0.900300 -0.964314 +v 0.614110 -0.924699 -0.962082 +v 0.590711 -0.924613 -0.953817 +v 0.538885 -0.924088 -0.951579 +v 0.487588 -0.924613 -0.955283 +v 0.870310 -0.857089 -1.925392 +v 0.928487 -0.861376 -1.926412 +v 0.870310 -0.857089 -1.925392 +v 0.865430 -0.857714 -1.929751 +v 0.928613 -0.863161 -1.930480 +v 0.928487 -0.861376 -1.926412 +v 0.991088 -0.860358 -1.924635 +v 0.985953 -0.858276 -1.921925 +v 0.985953 -0.858276 -1.921925 +v 0.844808 -0.835619 -1.906735 +v 0.840363 -0.832952 -1.908549 +v 0.844940 -0.846468 -1.918540 +v 0.847987 -0.848280 -1.915495 +v 0.831535 -0.830063 -1.909655 +v 0.836894 -0.845640 -1.921759 +v 0.847987 -0.848280 -1.915495 +v 0.844940 -0.846468 -1.918540 +v 1.049932 -0.684565 -2.078012 +v 1.046988 -0.714351 -2.042367 +v 1.044028 -0.724960 -2.053234 +v 1.047083 -0.693057 -2.087569 +v 1.054940 -0.719654 -2.036103 +v 1.051628 -0.733306 -2.049565 +v 1.044028 -0.724960 -2.053234 +v 1.051628 -0.733306 -2.049565 +v 1.024685 -0.743164 -2.060091 +v 1.019527 -0.732697 -2.061380 +v 1.047083 -0.693057 -2.087569 +v 1.044028 -0.724960 -2.053234 +v 1.019527 -0.732697 -2.061380 +v 1.023963 -0.699303 -2.094322 +v 0.914538 -0.669248 -2.059433 +v 0.902557 -0.694114 -2.023826 +v 0.959708 -0.691988 -2.020844 +v 0.968197 -0.667229 -2.057682 +v 0.902557 -0.694114 -2.023826 +v 0.895727 -0.692020 -2.015292 +v 0.958750 -0.689857 -2.010761 +v 0.959708 -0.691988 -2.020844 +v 1.022225 -0.695031 -2.013310 +v 1.017243 -0.695497 -2.023556 +v 1.017243 -0.695497 -2.023556 +v 1.022143 -0.669672 -2.060934 +v 0.870220 -0.908120 -1.905504 +v 0.848666 -0.900200 -1.897747 +v 0.853265 -0.885450 -1.909742 +v 0.861888 -0.925708 -1.887544 +v 0.840681 -0.917220 -1.879080 +v 0.848666 -0.900200 -1.897747 +v 0.840681 -0.917220 -1.879080 +v 0.858264 -0.912118 -1.869025 +v 0.865982 -0.894598 -1.888611 +v 0.853265 -0.885450 -1.909742 +v 0.870388 -0.879677 -1.901973 +v 0.973411 -0.872636 -1.899708 +v 0.997562 -0.872659 -1.911362 +v 0.996600 -0.864863 -1.905419 +v 0.973411 -0.872636 -1.899708 +v 0.974396 -0.881008 -1.899332 +v 0.996282 -0.887411 -1.906270 +v 0.997562 -0.872659 -1.911362 +v 0.997562 -0.872659 -1.911362 +v 0.996282 -0.887411 -1.906270 +v 0.997562 -0.872659 -1.911362 +v 0.981371 -0.876200 -1.919451 +v 0.867216 -0.861896 -1.922367 +v 0.875435 -0.876525 -1.921488 +v 0.853479 -0.873211 -1.914336 +v 0.847690 -0.865152 -1.908850 +v 0.853479 -0.873211 -1.914336 +v 0.853479 -0.873211 -1.914336 +v 0.867649 -0.873087 -1.902140 +v 0.847690 -0.865152 -1.908850 +v 0.853479 -0.873211 -1.914336 +v 0.867649 -0.873087 -1.902140 +v 0.918114 -0.873905 -1.895315 +v 0.867649 -0.873087 -1.902140 +v 0.870388 -0.879677 -1.901973 +v 0.921498 -0.878059 -1.897895 +v 0.918114 -0.873905 -1.895315 +v 0.974396 -0.881008 -1.899332 +v 0.973411 -0.872636 -1.899708 +v 0.845593 -0.934135 -1.840274 +v 0.896609 -0.934488 -1.834669 +v 0.909309 -0.913987 -1.863393 +v 0.820056 -0.975011 -1.787247 +v 0.870292 -0.973383 -1.779400 +v 0.922513 -0.976587 -1.778722 +v 0.949056 -0.939919 -1.836256 +v 0.961710 -0.921005 -1.864725 +v 0.917017 -0.895066 -1.883548 +v 0.921498 -0.878059 -1.897895 +v 0.969639 -0.900652 -1.884851 +v 0.973872 -0.914426 -1.901911 +v 0.922840 -0.913833 -1.906891 +v 0.965321 -0.934886 -1.883355 +v 0.914283 -0.932872 -1.888932 +v 0.991191 -0.908699 -1.892692 +v 0.982910 -0.929639 -1.873245 +v 0.991191 -0.908699 -1.892692 +v 0.982910 -0.929639 -1.873245 +v 0.927813 -0.989626 -1.797884 +v 0.885038 -1.057171 -1.699038 +v 0.836768 -1.058449 -1.713428 +v 0.877569 -0.991102 -1.805686 +v 0.841787 -1.131224 -1.600397 +v 0.795514 -1.131324 -1.621661 +v 0.745283 -1.127447 -1.636061 +v 0.785483 -1.055382 -1.720776 +v 0.825341 -0.987745 -1.806319 +v 0.952868 -0.953609 -1.855483 +v 0.901853 -0.953102 -1.861045 +v 0.849409 -0.947520 -1.859413 +v 0.970360 -0.947876 -1.845125 +v 0.944376 -0.983430 -1.786713 +v 0.970360 -0.947876 -1.845125 +v 0.944376 -0.983430 -1.786713 +v 0.828102 -0.939713 -1.850589 +v 0.803487 -0.981055 -1.798373 +v 0.828102 -0.939713 -1.850589 +v 0.803487 -0.981055 -1.798373 +v 0.706724 -1.233691 -1.552651 +v 0.699536 -1.295098 -1.521985 +v 0.677105 -1.288957 -1.521324 +v 0.683284 -1.226918 -1.552078 +v 0.703654 -1.336686 -1.497116 +v 0.690954 -1.339823 -1.490776 +v 0.677105 -1.288957 -1.521324 +v 0.690954 -1.339823 -1.490776 +v 0.695559 -1.326635 -1.484865 +v 0.689062 -1.282819 -1.506107 +v 0.683284 -1.226918 -1.552078 +v 0.695477 -1.221919 -1.535543 +v 0.876980 -1.045437 -1.680207 +v 0.899673 -1.051611 -1.685537 +v 0.831212 -1.120472 -1.582037 +v 0.854589 -1.126529 -1.584519 +v 0.899673 -1.051611 -1.685537 +v 0.854589 -1.126529 -1.584519 +v 0.762808 -1.049356 -1.715498 +v 0.721928 -1.121538 -1.633637 +v 0.762808 -1.049356 -1.715498 +v 0.721928 -1.121538 -1.633637 +v 0.734754 -1.116989 -1.617817 +v 0.777460 -1.043946 -1.702049 +v 0.825712 -1.042519 -1.687607 +v 0.781004 -1.116743 -1.596496 +v 0.774982 -1.340265 -1.465326 +v 0.777910 -1.344089 -1.452006 +v 0.732680 -1.359887 -1.463637 +v 0.739353 -1.348190 -1.478841 +v 0.777910 -1.344089 -1.452006 +v 0.766872 -1.330062 -1.453034 +v 0.729511 -1.335722 -1.463941 +v 0.732680 -1.359887 -1.463637 +v 0.695559 -1.326635 -1.484865 +v 0.690954 -1.339823 -1.490776 +v 0.695477 -1.221919 -1.535543 +v 0.689062 -1.282819 -1.506107 +v 0.732503 -1.283489 -1.482413 +v 0.740866 -1.221974 -1.511017 +v 0.695559 -1.326635 -1.484865 +v 0.729511 -1.335722 -1.463941 +v 0.766872 -1.330062 -1.453034 +v 0.780045 -1.287171 -1.465421 +v 0.790480 -1.226500 -1.492926 +v 0.801767 -1.238570 -1.510132 +v 0.790550 -1.299726 -1.481377 +v 0.746929 -1.300602 -1.504303 +v 0.756358 -1.238366 -1.534608 +v 0.802326 -1.295135 -1.465393 +v 0.813940 -1.233422 -1.493547 +v 0.777910 -1.344089 -1.452006 +v 0.802326 -1.295135 -1.465393 +v 0.777910 -1.344089 -1.452006 +v 0.774982 -1.340265 -1.465326 +v 0.790550 -1.299726 -1.481377 +v 0.813940 -1.233422 -1.493547 +v 0.801767 -1.238570 -1.510132 +v 0.909886 -0.608138 -2.157169 +v 0.912919 -0.601142 -2.147676 +v 0.888655 -0.684099 -2.075705 +v 0.891429 -0.675508 -2.066181 +v 0.912919 -0.601142 -2.147676 +v 0.891429 -0.675508 -2.066181 +v 0.935692 -0.595983 -2.141377 +v 1.067295 -0.608196 -2.162882 +v 1.064265 -0.615179 -2.172466 +v 1.064265 -0.615179 -2.172466 +v 1.041492 -0.620336 -2.178778 +v 0.989086 -0.622147 -2.179341 +v 0.970390 -0.701435 -2.096035 +v 0.916531 -0.699105 -2.092746 +v 0.936549 -0.620311 -2.174866 +v 0.988095 -0.594186 -2.140710 +v 1.040627 -0.596036 -2.145082 +v 0.986523 -0.804694 -1.880105 +v 0.993945 -0.795491 -1.875455 +v 0.923002 -0.789208 -1.876004 +v 0.923182 -0.799921 -1.880088 +v 0.993945 -0.795491 -1.875455 +v 1.005221 -0.774036 -1.888754 +v 0.927808 -0.766152 -1.889290 +v 0.923002 -0.789208 -1.876004 +v 0.851260 -0.770187 -1.899773 +v 0.852884 -0.793123 -1.884879 +v 0.852884 -0.793123 -1.884879 +v 0.860548 -0.803396 -1.886644 +v 1.020260 -0.833019 -1.900913 +v 1.031763 -0.830863 -1.901646 +v 1.025897 -0.810751 -1.885487 +v 1.015039 -0.816853 -1.888186 +v 1.031763 -0.830863 -1.901646 +v 1.046244 -0.815407 -1.919895 +v 1.039994 -0.792019 -1.900713 +v 1.025897 -0.810751 -1.885487 +v 1.025897 -0.810751 -1.885487 +v 1.039994 -0.792019 -1.900713 +v 0.866032 -0.716311 -2.039692 +v 0.854667 -0.717721 -2.038972 +v 0.857666 -0.699028 -2.021455 +v 0.868855 -0.701976 -2.025869 +v 0.854667 -0.717721 -2.038972 +v 0.840282 -0.733302 -2.021696 +v 0.843407 -0.710960 -2.001349 +v 0.857666 -0.699028 -2.021455 +v 0.857666 -0.699028 -2.021455 +v 0.843407 -0.710960 -2.001349 +v 0.876027 -0.695750 -1.984986 +v 0.887683 -0.686283 -2.007730 +v 0.887683 -0.686283 -2.007730 +v 1.032164 -0.753677 -2.062103 +v 0.962404 -0.757144 -2.069374 +v 0.962221 -0.746109 -2.065034 +v 1.032164 -0.753677 -2.062103 +v 1.033910 -0.777396 -2.046440 +v 0.957942 -0.781146 -2.055706 +v 0.962404 -0.757144 -2.069374 +v 0.881330 -0.773418 -2.054618 +v 0.892112 -0.751078 -2.067750 +v 0.892112 -0.751078 -2.067750 +v 0.899305 -0.741717 -2.062897 +v 0.962653 -0.735189 -2.064494 +v 0.962653 -0.735189 -2.064494 +v 0.905395 -0.732047 -2.061914 +v 0.905395 -0.732047 -2.061914 +v 0.875373 -0.712826 -2.042971 +v 0.878091 -0.701898 -2.031988 +v 0.875373 -0.712826 -2.042971 +v 0.878091 -0.701898 -2.031988 +v 0.878091 -0.701898 -2.031988 +v 1.005837 -0.836030 -1.902592 +v 1.011786 -0.834300 -1.902774 +v 1.007126 -0.820617 -1.892472 +v 1.001505 -0.823804 -1.893781 +v 0.981297 -0.810410 -1.885713 +v 0.977283 -0.814738 -1.887860 +v 0.923813 -0.806592 -1.885160 +v 0.923314 -0.811473 -1.887041 +v 0.866918 -0.809827 -1.889955 +v 0.869870 -0.814561 -1.890819 +v 0.861229 -0.730522 -1.940954 +v 0.940312 -0.727112 -1.930706 +v 0.953000 -0.693147 -1.976326 +v 1.020176 -0.736073 -1.931171 +v 1.030617 -0.702024 -1.978020 +v 1.024590 -0.818414 -2.002784 +v 0.946303 -0.821961 -2.012836 +v 1.010519 -0.854402 -1.956053 +v 0.934434 -0.857539 -1.965551 +v 0.857484 -0.848755 -1.965103 +v 0.867234 -0.813137 -2.012176 +v 1.070660 -0.740991 -2.010336 +v 1.061920 -0.778597 -1.964580 +v 1.058128 -0.802081 -1.985498 +v 1.066656 -0.762328 -2.030153 +v 1.042901 -0.838498 -1.939705 +v 1.058128 -0.802081 -1.985498 +v 1.042901 -0.838498 -1.939705 +v 1.066656 -0.762328 -2.030153 +v 0.824694 -0.770475 -1.978962 +v 0.827790 -0.746873 -1.958215 +v 0.815998 -0.808285 -1.934946 +v 0.818935 -0.785979 -1.915998 +v 0.827790 -0.746873 -1.958215 +v 0.818935 -0.785979 -1.915998 +v 0.958315 -0.684053 -2.001174 +v 0.958315 -0.684053 -2.001174 +v 1.029481 -0.691357 -2.003515 +v 1.029481 -0.691357 -2.003515 +v 1.054940 -0.719654 -2.036103 +v 1.066053 -0.723476 -2.031576 +v 1.062290 -0.741088 -2.048467 +v 1.066053 -0.723476 -2.031576 +v 1.062290 -0.741088 -2.048467 +v 1.062290 -0.741088 -2.048467 +v 0.820559 -0.825734 -1.914193 +v 0.826651 -0.844926 -1.929425 +v 0.820559 -0.825734 -1.914193 +v 0.822654 -0.830886 -1.953267 +v 0.826651 -0.844926 -1.929425 +v 0.826651 -0.844926 -1.929425 +v 0.822654 -0.830886 -1.953267 +v 0.858635 -0.860054 -1.939324 +v 0.858635 -0.860054 -1.939324 +v 0.929320 -0.867389 -1.939835 +v 0.929320 -0.867389 -1.939835 +v 0.999181 -0.864525 -1.932020 +v 0.999181 -0.864525 -1.932020 +v 0.971378 -0.054090 -2.483591 +v 1.026448 -0.053467 -2.482729 +v 1.081201 -0.054090 -2.487844 +v 1.079077 -0.061126 -2.528816 +v 1.024034 -0.061534 -2.529685 +v 0.969287 -0.061126 -2.524558 +v 1.116638 -0.042009 -2.517686 +v 1.106532 -0.058025 -2.509247 +v 1.102710 -0.059961 -2.520885 +v 1.113706 -0.043488 -2.529575 +v 1.102710 -0.059961 -2.520885 +v 1.113706 -0.043488 -2.529575 +v 0.934333 -0.042009 -2.510763 +v 0.943914 -0.058025 -2.502939 +v 0.947727 -0.055927 -2.491349 +v 0.937274 -0.039696 -2.499090 +v 0.947727 -0.055927 -2.491349 +v 0.937274 -0.039696 -2.499090 +v 0.960236 0.041491 -2.502414 +v 0.918072 0.052800 -2.504846 +v 0.917579 0.004653 -2.495460 +v 0.962954 0.002684 -2.496033 +v 0.893206 0.053631 -2.508049 +v 0.891773 0.004444 -2.498237 +v 1.137324 -0.021758 -2.498859 +v 1.092191 -0.022013 -2.496384 +v 1.161948 -0.022015 -2.503320 +v 1.137324 -0.021758 -2.498859 +v 1.161948 -0.022015 -2.503320 +v 1.163255 -0.011122 -2.504927 +v 1.137747 -0.010566 -2.500409 +v 1.140792 0.046896 -2.560600 +v 1.138683 -0.002464 -2.551728 +v 1.114366 -0.002916 -2.554058 +v 1.163340 0.047505 -2.557327 +v 1.161674 -0.001855 -2.548586 +v 0.914453 -0.029123 -2.537916 +v 0.889898 -0.028298 -2.533564 +v 0.889271 -0.017477 -2.536047 +v 0.913821 -0.018031 -2.540756 +v 1.175472 0.050568 -2.537212 +v 1.173883 0.001294 -2.528531 +v 1.171895 -0.000517 -2.540240 +v 1.173531 0.048807 -2.548935 +v 1.171895 -0.000517 -2.540240 +v 1.173531 0.048807 -2.548935 +v 0.881074 0.050568 -2.528184 +v 0.879563 0.001294 -2.518310 +v 0.881538 0.003105 -2.506592 +v 0.883003 0.052329 -2.516451 +v 0.881538 0.003105 -2.506592 +v 0.883003 0.052329 -2.516451 +v 1.027889 0.000318 -2.497778 +v 1.028280 0.012846 -2.498764 +v 1.092939 0.002684 -2.500536 +v 1.097980 0.041491 -2.506636 +v 0.970052 -0.015957 -2.553309 +v 1.024914 -0.018201 -2.554873 +v 0.970052 -0.015957 -2.553309 +v 0.971513 -0.017074 -2.561569 +v 1.024748 -0.019195 -2.563048 +v 1.024914 -0.018201 -2.554873 +v 1.078128 -0.017074 -2.565326 +v 1.079927 -0.015957 -2.557186 +v 1.079927 -0.015957 -2.557186 +v 0.579000 1.210252 -1.099748 +v 0.649044 1.244049 -1.121807 +v 0.648642 1.253101 -1.117603 +v 0.580255 1.219759 -1.095636 +v 0.579000 1.210252 -1.099748 +v 0.541306 1.252889 -1.118103 +v 0.538419 1.243951 -1.122470 +v 0.538419 1.243951 -1.122470 +v 0.975582 0.611616 -2.601413 +v 0.975644 0.458538 -2.582996 +v 1.041301 0.458584 -2.583517 +v 1.044434 0.572572 -2.601978 +v 0.967917 0.304985 -2.553390 +v 1.038022 0.344569 -2.561253 +v 0.893253 0.455789 -2.607253 +v 0.894818 0.457081 -2.595414 +v 0.888795 0.302415 -2.578650 +v 0.890490 0.303920 -2.566843 +v 0.894818 0.457081 -2.595414 +v 0.890490 0.303920 -2.566843 +v 0.900530 0.305033 -2.558205 +v 0.904768 0.458036 -2.586650 +v 0.897756 0.609936 -2.611287 +v 0.907672 0.610476 -2.602510 +v 1.188284 0.455788 -2.606768 +v 1.186716 0.454496 -2.618585 +v 1.183594 0.302415 -2.581587 +v 1.181893 0.300910 -2.593376 +v 1.171859 0.299797 -2.602001 +v 1.176767 0.453541 -2.627334 +v 1.134987 0.607593 -2.649014 +v 1.157480 0.607695 -2.645577 +v 1.154251 0.453109 -2.631361 +v 1.131771 0.452771 -2.634657 +v 1.180000 0.607926 -2.641435 +v 1.176767 0.453541 -2.627334 +v 1.171859 0.299797 -2.602001 +v 1.149333 0.299276 -2.605757 +v 0.932568 0.610793 -2.599127 +v 0.930413 0.458436 -2.583087 +v 0.925395 0.305429 -2.554711 +v 1.140669 0.052800 -2.511668 +v 1.145351 0.161067 -2.531058 +v 1.119188 0.159258 -2.528251 +v 1.165230 0.053631 -2.516400 +v 1.168502 0.160900 -2.535406 +v 0.935978 0.046309 -2.557585 +v 0.913629 0.046896 -2.553665 +v 0.917151 0.154579 -2.574941 +v 0.939529 0.154005 -2.578664 +v 0.891370 0.047505 -2.549006 +v 0.894847 0.155153 -2.570474 +v 1.154602 1.060029 -2.602156 +v 1.132057 1.060889 -2.604865 +v 1.177249 1.058880 -2.598818 +v 0.930078 0.760349 -2.640937 +v 0.907647 0.760208 -2.637084 +v 0.932130 1.046197 -2.552458 +v 0.977372 1.046822 -2.553218 +v 0.906353 1.047118 -2.555299 +v 1.189419 1.052902 -2.579690 +v 1.187478 1.056340 -2.590784 +v 1.187478 1.056340 -2.590784 +v 0.894285 1.053030 -2.574290 +v 0.896157 1.049636 -2.563282 +v 0.896157 1.049636 -2.563282 +v 1.043004 1.047695 -2.554956 +v 1.042280 1.150888 -2.538073 +v 1.043719 0.941700 -2.568374 +v 0.935978 0.046309 -2.557585 +v 0.945660 0.045094 -2.564365 +v 0.947248 -0.003815 -2.554922 +v 0.936670 -0.002916 -2.547936 +v 0.946899 0.043587 -2.572438 +v 0.948589 -0.005247 -2.563043 +v 0.947248 -0.003815 -2.554922 +v 0.948589 -0.005247 -2.563043 +v 0.936670 -0.002916 -2.547936 +v 0.947248 -0.003815 -2.554922 +v 1.113589 0.611605 -2.600192 +v 1.155671 0.610775 -2.597471 +v 1.157724 0.758626 -2.592374 +v 1.131561 0.758594 -2.591285 +v 1.180386 0.610457 -2.600518 +v 1.181022 0.758746 -2.595894 +v 1.149072 1.475267 -2.384037 +v 1.126516 1.477618 -2.385163 +v 1.171560 1.472444 -2.382396 +v 1.182813 1.458198 -2.368577 +v 1.181399 1.466376 -2.376782 +v 1.181399 1.466376 -2.376782 +v 1.173135 1.545185 -2.277430 +v 0.886243 1.459101 -2.353984 +v 0.887515 1.450984 -2.345961 +v 0.887515 1.450984 -2.345961 +v 0.897319 1.444957 -2.340459 +v 1.120547 1.196277 -2.577712 +v 1.119350 1.303484 -2.525095 +v 1.120547 1.196277 -2.577712 +v 1.118950 1.199329 -2.585155 +v 1.117709 1.307473 -2.532065 +v 1.119350 1.303484 -2.525095 +v 1.116736 1.399636 -2.467167 +v 1.118397 1.394757 -2.460800 +v 1.118397 1.394757 -2.460800 +v 0.968964 1.442162 -2.342756 +v 1.035407 1.442256 -2.347545 +v 1.037239 1.380567 -2.393518 +v 1.153007 1.273810 -2.476377 +v 1.126832 1.273663 -2.474557 +v 1.176220 1.275569 -2.480303 +v 0.923121 1.442438 -2.339485 +v 0.924068 1.298851 -2.509329 +v 0.946478 1.300448 -2.512979 +v 0.901683 1.296861 -2.505129 +v 0.950093 0.042301 -2.579397 +v 0.951648 -0.006481 -2.569986 +v 0.950093 0.042301 -2.579397 +v 0.973329 0.041453 -2.584631 +v 0.973953 -0.007165 -2.575163 +v 0.951648 -0.006481 -2.569986 +v 0.984654 -0.017599 -2.572658 +v 0.973652 -0.018092 -2.568419 +v 0.948589 -0.005247 -2.563043 +v 0.971513 -0.017074 -2.561569 +v 0.624566 1.465358 -1.285135 +v 0.700387 1.567163 -1.427290 +v 0.624566 1.465358 -1.285135 +v 0.647990 1.468871 -1.282399 +v 0.723799 1.571091 -1.425492 +v 0.700387 1.567163 -1.427290 +v 0.800014 1.646057 -1.590505 +v 0.776576 1.641827 -1.591211 +v 0.776576 1.641827 -1.591211 +v 1.106823 1.569821 -2.290806 +v 1.103290 1.575414 -2.294485 +v 1.083597 1.643553 -2.137320 +v 1.087072 1.637315 -2.134991 +v 1.103290 1.575414 -2.294485 +v 1.079648 1.579262 -2.295624 +v 1.059957 1.647831 -2.137549 +v 1.083597 1.643553 -2.137320 +v 1.025164 1.687745 -1.952206 +v 1.048756 1.683217 -1.952890 +v 1.048756 1.683217 -1.952890 +v 1.052161 1.676539 -1.952078 +v 1.112107 0.295339 -2.630060 +v 1.117125 0.450564 -2.656232 +v 1.120487 0.451272 -2.649310 +v 1.112107 0.295339 -2.630060 +v 1.088712 0.294611 -2.634371 +v 1.093744 0.450093 -2.660840 +v 1.117125 0.450564 -2.656232 +v 1.097021 0.606925 -2.675528 +v 1.120394 0.607047 -2.670769 +v 1.120394 0.607047 -2.670769 +v 1.123736 0.607223 -2.663797 +v 1.122430 0.914294 -2.640604 +v 1.119033 0.915326 -2.647429 +v 1.117133 1.066469 -2.625378 +v 1.120581 1.064677 -2.618770 +v 1.119033 0.915326 -2.647429 +v 1.095633 0.916012 -2.651771 +v 1.093704 1.067667 -2.629333 +v 1.117133 1.066469 -2.625378 +v 1.091979 1.203688 -2.594974 +v 1.115449 1.201940 -2.591446 +v 1.115449 1.201940 -2.591446 +v 0.893874 1.684075 -1.944553 +v 0.928699 1.644625 -2.128236 +v 0.893874 1.684075 -1.944553 +v 0.917428 1.688354 -1.946208 +v 0.952209 1.648619 -2.131075 +v 0.928699 1.644625 -2.128236 +v 0.972091 1.580017 -2.289209 +v 0.948669 1.576427 -2.285408 +v 0.948669 1.576427 -2.285408 +v 1.120635 0.761737 -2.665224 +v 1.123991 0.761345 -2.658279 +v 1.120394 0.607047 -2.670769 +v 1.097021 0.606925 -2.675528 +v 1.097255 0.761993 -2.669870 +v 1.120635 0.761737 -2.665224 +v 0.541306 1.252889 -1.118103 +v 0.545275 1.260674 -1.115080 +v 0.564213 1.350231 -1.178936 +v 0.560672 1.345123 -1.183786 +v 0.545275 1.260674 -1.115080 +v 0.564537 1.281332 -1.124389 +v 0.587692 1.355380 -1.177073 +v 0.564213 1.350231 -1.178936 +v 0.965521 0.915349 -2.646261 +v 0.967071 0.761719 -2.665688 +v 0.965521 0.915349 -2.646261 +v 0.988842 0.916030 -2.650957 +v 0.990427 0.761978 -2.670192 +v 0.967071 0.761719 -2.665688 +v 0.990183 0.606899 -2.676329 +v 0.966815 0.607015 -2.671920 +v 0.966815 0.607015 -2.671920 +v 0.958757 1.199466 -2.580461 +v 0.961930 1.202100 -2.586936 +v 0.963664 1.066557 -2.622443 +v 0.960441 1.064746 -2.615716 +v 0.961930 1.202100 -2.586936 +v 0.985182 1.203812 -2.591832 +v 0.986943 1.067737 -2.627287 +v 0.963664 1.066557 -2.622443 +v 0.558865 1.339139 -1.189619 +v 0.538419 1.243951 -1.122470 +v 0.558865 1.339139 -1.189619 +v 0.837689 1.668128 -1.766153 +v 0.839148 1.675936 -1.764941 +v 0.837689 1.668128 -1.766153 +v 0.827661 1.661849 -1.766814 +v 0.837689 1.668128 -1.766153 +v 1.123904 0.913087 -2.632592 +v 1.122118 1.062581 -2.610983 +v 1.123904 0.913087 -2.632592 +v 1.122118 1.062581 -2.610983 +v 1.108431 1.563297 -2.286335 +v 1.088609 1.630035 -2.132094 +v 1.108431 1.563297 -2.286335 +v 1.088609 1.630035 -2.132094 +v 1.053619 1.668734 -1.950963 +v 1.053619 1.668734 -1.950963 +v 1.053619 1.668734 -1.950963 +v 1.001659 1.667535 -1.772349 +v 1.000264 1.675458 -1.771750 +v 1.001659 1.667535 -1.772349 +v 0.952247 0.607590 -2.650384 +v 0.958905 0.452093 -2.641510 +v 0.949097 0.452768 -2.634993 +v 0.960279 0.451255 -2.649606 +v 0.955387 0.296434 -2.621657 +v 0.954062 0.297728 -2.613589 +v 0.944302 0.298772 -2.606994 +v 0.954868 1.395108 -2.453527 +v 0.956133 1.303680 -2.519001 +v 0.954868 1.395108 -2.453527 +v 0.956022 1.400028 -2.459964 +v 0.957302 1.307698 -2.526060 +v 0.956133 1.303680 -2.519001 +v 0.957546 1.196377 -2.572953 +v 0.957546 1.196377 -2.572953 +v 0.959169 1.062625 -2.607887 +v 0.959169 1.062625 -2.607887 +v 0.952631 1.482822 -2.380818 +v 0.953805 1.488642 -2.386390 +v 0.952631 1.482822 -2.380818 +v 1.121919 0.452102 -2.641208 +v 1.121919 0.452102 -2.641208 +v 1.125146 0.607428 -2.655652 +v 1.125146 0.607428 -2.655652 +v 1.116486 1.482253 -2.389228 +v 1.114835 1.487971 -2.394818 +v 1.116486 1.482253 -2.389228 +v 1.125146 0.607428 -2.655652 +v 1.125418 0.760886 -2.650155 +v 1.125418 0.760886 -2.650155 +v 0.755030 1.469914 -1.284104 +v 0.830729 1.571915 -1.428436 +v 0.777272 1.572822 -1.426183 +v 0.701514 1.470556 -1.282233 +v 0.907045 1.646344 -1.594596 +v 0.853538 1.647650 -1.592059 +v 0.645014 1.281695 -1.124308 +v 0.690308 1.356115 -1.177568 +v 0.638364 1.355287 -1.175222 +v 0.598321 1.267264 -1.113978 +v 1.006061 1.649643 -2.134838 +v 0.971289 1.689559 -1.949374 +v 1.025832 1.580915 -2.293263 +v 0.973437 1.686727 -1.769635 +v 0.919741 1.688361 -1.766883 +v 1.025164 1.687745 -1.952206 +v 0.971289 1.689559 -1.949374 +v 0.917428 1.688354 -1.946208 +v 0.866037 1.686958 -1.764483 +v 1.089585 1.406628 -2.475063 +v 1.090638 1.313172 -2.541015 +v 1.037122 1.314034 -2.540359 +v 1.035964 1.407726 -2.473874 +v 1.038543 1.204343 -2.594847 +v 0.983699 1.313349 -2.536995 +v 0.982443 1.406930 -2.470213 +v 1.043836 0.762074 -2.671599 +v 1.042224 0.916255 -2.652913 +v 1.043601 0.606872 -2.677499 +v 1.079970 0.041453 -2.587872 +v 1.076007 -0.007165 -2.578665 +v 1.024944 -0.007535 -2.578385 +v 1.026618 0.041162 -2.587802 +v 1.064616 -0.017600 -2.575466 +v 1.024587 -0.018657 -2.574567 +v 1.040335 0.449924 -2.662503 +v 1.043601 0.606872 -2.677499 +v 1.035322 0.294358 -2.635408 +v 0.981961 0.294605 -2.633333 +v 0.986937 0.450074 -2.661037 +v 0.990183 0.606899 -2.676329 +v 1.040298 1.068110 -2.629818 +v 1.087648 1.496215 -2.401390 +v 1.033927 1.497601 -2.399587 +v 0.980301 1.496757 -2.395631 +v 0.959151 1.404223 -2.465559 +v 0.960440 1.311124 -2.532168 +v 0.959151 1.404223 -2.465559 +v 0.960440 1.311124 -2.532168 +v 0.930432 1.642117 -1.596757 +v 0.854095 1.568147 -1.431195 +v 0.930432 1.642117 -1.596757 +v 0.854095 1.568147 -1.431195 +v 0.778430 1.466636 -1.287312 +v 0.778430 1.466636 -1.287312 +v 0.973652 -0.018092 -2.568419 +v 1.024605 -0.020142 -2.569901 +v 1.024605 -0.020142 -2.569901 +v 1.075701 -0.018092 -2.572014 +v 1.075701 -0.018092 -2.572014 +v 0.956955 1.493598 -2.391266 +v 0.956955 1.493598 -2.391266 +v 1.113168 1.403811 -2.472505 +v 1.111269 1.492870 -2.399470 +v 1.113168 1.403811 -2.472505 +v 1.111269 1.492870 -2.399470 +v 1.103389 0.042301 -2.584055 +v 1.107109 0.150067 -2.603663 +v 1.103389 0.042301 -2.584055 +v 1.083700 0.149233 -2.607687 +v 1.107109 0.150067 -2.603663 +v 0.648013 1.260983 -1.114731 +v 0.582512 1.228826 -1.093403 +v 0.648013 1.260983 -1.114731 +v 0.582512 1.228826 -1.093403 +v 0.545275 1.260674 -1.115080 +v 1.114165 1.310884 -2.537937 +v 1.114165 1.310884 -2.537937 +v 0.842528 1.682601 -1.764028 +v 0.842528 1.682601 -1.764028 +v 0.893874 1.684075 -1.944553 +v 0.963590 0.450541 -2.656517 +v 0.986937 0.450074 -2.661037 +v 0.963590 0.450541 -2.656517 +v 0.963590 0.450541 -2.656517 +v 0.958654 0.295331 -2.628568 +v 0.958654 0.295331 -2.628568 +v 0.996922 1.682223 -1.771111 +v 1.048756 1.683217 -1.952890 +v 0.996922 1.682223 -1.771111 +v 0.711873 1.351117 -1.179442 +v 0.711873 1.351117 -1.179442 +v 0.648013 1.260983 -1.114731 +v 0.804007 -1.175817 -1.524805 +v 0.827581 -1.182191 -1.525870 +v 0.827581 -1.182191 -1.525870 +v 0.815468 -1.186831 -1.542609 +v 0.827581 -1.182191 -1.525870 +v 0.815468 -1.186831 -1.542609 +v 0.770019 -1.186481 -1.566808 +v 0.720281 -1.182057 -1.584351 +v 0.708865 -1.171338 -1.566660 +v 0.754291 -1.171540 -1.542405 +v 0.696729 -1.175829 -1.583343 +v 0.696729 -1.175829 -1.583343 +v 0.708865 -1.171338 -1.566660 +v 0.696729 -1.175829 -1.583343 +v 0.887800 1.467210 -2.362148 +v 0.878896 1.546277 -2.261954 +v 0.890474 1.381679 -2.433148 +v 0.887800 1.467210 -2.362148 +v 0.890474 1.381679 -2.433148 +v 0.878896 1.546277 -2.261954 +v 1.181416 1.450028 -2.360231 +v 1.172662 1.526627 -2.264618 +v 1.171574 1.444020 -2.353637 +v 1.174422 1.361629 -2.420195 +v 1.184077 1.366863 -2.427452 +v 1.181416 1.450028 -2.360231 +v 1.172662 1.526627 -2.264618 +v 0.903160 1.191056 -2.558749 +v 0.904714 1.058928 -2.593691 +v 0.895225 1.056423 -2.585350 +v 0.893695 1.187523 -2.550633 +v 0.906315 0.911007 -2.617427 +v 0.896718 0.909621 -2.608977 +v 1.177826 1.174094 -2.529400 +v 1.179111 1.046928 -2.560149 +v 1.188549 1.049465 -2.568544 +v 1.187219 1.177667 -2.537591 +v 1.180204 0.904346 -2.579887 +v 1.189769 0.905755 -2.588367 +v 1.180386 0.610457 -2.600518 +v 1.177337 0.458034 -2.586235 +v 1.187044 0.457079 -2.594954 +v 1.190141 0.609918 -2.609141 +v 1.172899 0.305033 -2.560944 +v 1.182491 0.303920 -2.569770 +v 0.907312 0.607930 -2.643472 +v 0.904213 0.453542 -2.627819 +v 0.894498 0.454497 -2.619087 +v 0.897550 0.608472 -2.634841 +v 0.899518 0.299797 -2.599320 +v 0.889908 0.300910 -2.590486 +v 0.891370 0.047505 -2.549006 +v 0.889776 -0.001856 -2.539162 +v 0.880391 -0.000517 -2.530125 +v 0.881948 0.048807 -2.540002 +v 0.889271 -0.017477 -2.536047 +v 0.879898 -0.016126 -2.526999 +v 1.165230 0.053631 -2.516400 +v 1.163729 0.004444 -2.507685 +v 1.173077 0.003105 -2.516723 +v 1.174617 0.052329 -2.525403 +v 1.163255 -0.011122 -2.504927 +v 1.172589 -0.012472 -2.513976 +v 0.946533 -0.059961 -2.514824 +v 0.947071 -0.134153 -2.477031 +v 0.946533 -0.059961 -2.514824 +v 0.947071 -0.134153 -2.477031 +v 0.936041 -0.043488 -2.522835 +v 1.103931 -0.055927 -2.497405 +v 1.114971 -0.039696 -2.505834 +v 1.100847 -0.128894 -2.460531 +v 1.103931 -0.055927 -2.497405 +v 1.100847 -0.128894 -2.460531 +v 1.114971 -0.039696 -2.505834 +v 0.823267 -0.806756 -1.898437 +v 0.834039 -0.814609 -1.897186 +v 0.823267 -0.806756 -1.898437 +v 0.823267 -0.806756 -1.898437 +v 1.061009 -0.705624 -2.014993 +v 1.050381 -0.705864 -2.022790 +v 1.065065 -0.719334 -1.990993 +v 1.061009 -0.705624 -2.014993 +v 1.061009 -0.705624 -2.014993 +v 1.065065 -0.719334 -1.990993 +v 0.831482 -0.794417 -1.999110 +v 0.846757 -0.755965 -2.041569 +v 0.831482 -0.794417 -1.999110 +v 0.846757 -0.755965 -2.041569 +v 1.055829 -0.754776 -1.944261 +v 1.055829 -0.754776 -1.944261 +v 1.009501 -0.848030 -1.913346 +v 1.004798 -0.848725 -1.911668 +v 1.017616 -0.849061 -1.914004 +v 1.009501 -0.848030 -1.913346 +v 1.004798 -0.848725 -1.911668 +v 0.879807 -0.723819 -2.053928 +v 0.892601 -0.692710 -2.085324 +v 0.871080 -0.730786 -2.053366 +v 0.879807 -0.723819 -2.053928 +v 0.892601 -0.692710 -2.085324 +v 0.879807 -0.723819 -2.053928 +v 0.860475 -0.736655 -2.056181 +v 0.860475 -0.736655 -2.056181 +v 0.860475 -0.736655 -2.056181 +v 1.028830 -0.850762 -1.918329 +v 1.028830 -0.850762 -1.918329 +v 1.028830 -0.850762 -1.918329 +v 1.063766 -0.601211 -2.153060 +v 1.084461 -0.468981 -2.265810 +v 1.046062 -0.676054 -2.068359 +v 1.063766 -0.601211 -2.153060 +v 1.046062 -0.676054 -2.068359 +v 1.084461 -0.468981 -2.265810 +v 0.913411 -0.615135 -2.166901 +v 0.933483 -0.480162 -2.278897 +v 0.913411 -0.615135 -2.166901 +v 0.933483 -0.480162 -2.278897 +v 1.042797 -0.703679 -2.031525 +v 1.042797 -0.703679 -2.031525 +v 1.046988 -0.714351 -2.042367 +v 1.042797 -0.703679 -2.031525 +v 0.842761 -0.819602 -1.898349 +v 0.847132 -0.823494 -1.897923 +v 0.616242 -0.926298 -0.985869 +v 0.618683 -0.980729 -0.982232 +v 0.593712 -0.901993 -0.987703 +v 0.616242 -0.926298 -0.985869 +v 0.593712 -0.901993 -0.987703 +v 0.618683 -0.980729 -0.982232 +v 0.465704 -0.924699 -0.964188 +v 0.461713 -0.979992 -0.960573 +v 0.465704 -0.924699 -0.964188 +v 0.488481 -0.900300 -0.965777 +v 0.461713 -0.979992 -0.960573 +v 0.542144 -0.894786 -0.989087 +v 0.487202 -0.900289 -0.977562 +v 0.541096 -0.892768 -0.977344 +v 0.594974 -0.900289 -0.976038 +v 0.650237 0.819939 -0.971476 +v 0.648375 0.773071 -0.969131 +v 0.658453 0.771967 -0.977480 +v 0.660753 0.819241 -0.980102 +v 0.643687 0.748351 -0.969719 +v 0.648854 0.742258 -0.976395 +v 0.402077 0.730670 -0.979194 +v 0.376709 0.740660 -0.991849 +v 0.402737 0.728457 -0.990941 +v 0.625489 0.729499 -0.999737 +v 0.579702 0.727840 -1.000381 +v 0.650552 0.741205 -0.999702 +v 0.650665 0.740538 -0.987981 +v 0.624802 0.728358 -0.987807 +v 0.578826 0.726637 -0.988389 +v 0.514773 0.727868 -1.001292 +v 0.513900 0.726666 -0.989309 +v 0.374852 0.957133 -0.996763 +v 0.371624 0.926284 -0.991941 +v 0.383969 0.999530 -1.015302 +v 0.374852 0.957133 -0.996763 +v 0.383969 0.999530 -1.015302 +v 0.662175 0.948530 -1.024445 +v 0.671150 0.950814 -1.015798 +v 0.680343 0.992038 -1.034089 +v 0.671150 0.950814 -1.015798 +v 0.680343 0.992038 -1.034089 +v 0.379363 0.816791 -1.016522 +v 0.379291 0.771173 -1.013635 +v 0.369147 0.770923 -1.005242 +v 0.368769 0.817490 -1.007915 +v 0.383708 0.746778 -1.010687 +v 0.378503 0.741324 -1.003505 +v 1.161948 -0.022015 -2.503320 +v 1.170894 -0.023539 -2.512040 +v 1.170894 -0.023539 -2.512040 +v 1.161219 -0.032282 -2.510340 +v 0.889898 -0.028298 -2.533564 +v 0.880901 -0.027194 -2.524765 +v 0.880901 -0.027194 -2.524765 +v 0.890054 -0.035892 -2.523177 +v 0.889676 -0.034458 -2.511572 +v 1.181022 0.758746 -2.595894 +v 1.190716 0.759054 -2.604440 +v 1.176220 1.275569 -2.480303 +v 1.185704 1.280020 -2.488087 +v 0.892103 1.292452 -2.497435 +v 0.901683 1.296861 -2.505129 +v 0.892103 1.292452 -2.497435 +v 0.907647 0.760208 -2.637084 +v 0.897937 0.759912 -2.628546 +v 1.152226 1.588916 -2.121956 +v 1.116548 1.624432 -1.952528 +v 1.152226 1.588916 -2.121956 +v 1.116548 1.624432 -1.952528 +v 0.858178 1.611054 -2.113704 +v 0.822644 1.648288 -1.939851 +v 0.858178 1.611054 -2.113704 +v 0.822644 1.648288 -1.939851 +v 0.986578 1.576527 -1.618797 +v 1.053250 1.614177 -1.783003 +v 1.063790 1.622534 -1.781703 +v 0.996996 1.584596 -1.616253 +v 1.053250 1.614177 -1.783003 +v 1.063790 1.622534 -1.781703 +v 0.921586 1.515204 -1.460242 +v 0.847619 1.419759 -1.325487 +v 0.996996 1.584596 -1.616253 +v 0.921586 1.515204 -1.460242 +v 0.847619 1.419759 -1.325487 +v 0.629171 1.536016 -1.445536 +v 0.554088 1.437948 -1.309679 +v 0.639512 1.543493 -1.441672 +v 0.715536 1.615614 -1.599758 +v 0.704851 1.607513 -1.602188 +v 0.629171 1.536016 -1.445536 +v 0.554088 1.437948 -1.309679 +v 0.781569 1.654979 -1.766412 +v 0.770830 1.646597 -1.767644 +v 0.781569 1.654979 -1.766412 +v 0.770830 1.646597 -1.767644 +v 0.489702 1.320750 -1.204804 +v 0.439486 1.197382 -1.123951 +v 0.489702 1.320750 -1.204804 +v 0.439486 1.197382 -1.123951 +v 0.701068 1.073730 -1.077410 +v 0.735532 1.184821 -1.141547 +v 0.701068 1.073730 -1.077410 +v 0.735532 1.184821 -1.141547 +v 0.784643 1.305328 -1.221591 +v 0.784643 1.305328 -1.221591 +v 0.404649 1.083442 -1.059122 +v 0.404649 1.083442 -1.059122 +v 0.371039 0.873342 -1.011574 +v 0.381718 0.872046 -1.020093 +v 0.662950 0.876706 -0.984047 +v 0.652375 0.878001 -0.975505 +v 0.616899 -1.068542 -0.977051 +v 0.615282 -1.149421 -0.975572 +v 0.594087 -1.068011 -0.986111 +v 0.595886 -0.981001 -0.991385 +v 0.618683 -0.980729 -0.982232 +v 0.616899 -1.068542 -0.977051 +v 0.616899 -1.068542 -0.977051 +v 0.615282 -1.149421 -0.975572 +v 0.615593 -1.186853 -0.984249 +v 0.620641 -1.202677 -1.009675 +v 0.615593 -1.186853 -0.984249 +v 0.620641 -1.202677 -1.009675 +v 0.458868 -1.195507 -0.966763 +v 0.464173 -1.215865 -0.999362 +v 0.458554 -1.154106 -0.955234 +v 0.458868 -1.195507 -0.966763 +v 0.458554 -1.154106 -0.955234 +v 0.464173 -1.215865 -0.999362 +v 0.460073 -1.069976 -0.955667 +v 0.460073 -1.069976 -0.955667 +v 0.460073 -1.069976 -0.955667 +v 0.477684 -1.242032 -1.059561 +v 0.501389 -1.262955 -1.141943 +v 0.477684 -1.242032 -1.059561 +v 0.501389 -1.262955 -1.141943 +v 0.692527 -1.233008 -1.222999 +v 0.758583 -1.166549 -1.376016 +v 0.655755 -1.241405 -1.126633 +v 0.692527 -1.233008 -1.222999 +v 0.655755 -1.241405 -1.126633 +v 0.758583 -1.166549 -1.376016 +v 0.633313 -1.224093 -1.057146 +v 0.655755 -1.241405 -1.126633 +v 0.633313 -1.224093 -1.057146 +v 0.859220 -1.028858 -1.596262 +v 0.950722 -0.894230 -1.792663 +v 0.859220 -1.028858 -1.596262 +v 0.950722 -0.894230 -1.792663 +v 0.709818 -1.049526 -1.619695 +v 0.802481 -0.913158 -1.815561 +v 0.607305 -1.188889 -1.400656 +v 0.709818 -1.049526 -1.619695 +v 0.607305 -1.188889 -1.400656 +v 0.802481 -0.913158 -1.815561 +v 0.539615 -1.255847 -1.245733 +v 0.501389 -1.262955 -1.141943 +v 0.539615 -1.255847 -1.245733 +v 0.992002 -0.834449 -1.879454 +v 1.001505 -0.823804 -1.893781 +v 0.992002 -0.834449 -1.879454 +v 1.001505 -0.823804 -1.893781 +v 1.096295 -0.287798 -2.377383 +v 1.096295 -0.287798 -2.377383 +v 0.867216 -0.861896 -1.922367 +v 0.847690 -0.865152 -1.908850 +v 0.841385 -0.856382 -1.899761 +v 0.847987 -0.848280 -1.915495 +v 0.841385 -0.856382 -1.899761 +v 0.943810 -0.295764 -2.391903 +v 0.943810 -0.295764 -2.391903 +v 1.137837 -0.039986 -2.531857 +v 1.137837 -0.039986 -2.531857 +v 1.159997 -0.035892 -2.533317 +v 1.113706 -0.043488 -2.529575 +v 0.913217 -0.036291 -2.499870 +v 0.937274 -0.039696 -2.499090 +v 1.168502 0.160900 -2.535406 +v 1.177977 0.159679 -2.544333 +v 1.178938 0.158026 -2.556147 +v 0.894847 0.155153 -2.570474 +v 0.885344 0.156374 -2.561543 +v 0.884368 0.158026 -2.549717 +v 1.078128 -0.017074 -2.565326 +v 1.098497 -0.006481 -2.575027 +v 1.101855 -0.005247 -2.568305 +v 1.101855 -0.005247 -2.568305 +v 1.098497 -0.006481 -2.575027 +v 1.030331 0.148948 -2.608088 +v 0.977011 0.149233 -2.605387 +v 0.953744 0.150066 -2.600357 +v 0.950519 0.151330 -2.593424 +v 0.953744 0.150066 -2.600357 +v 0.949244 0.152811 -2.585360 +v 0.939529 0.154005 -2.578664 +v 0.912454 -0.002464 -2.543904 +v 0.889776 -0.001856 -2.539162 +v 1.138319 0.004653 -2.503117 +v 1.163729 0.004444 -2.507685 +v 0.668542 1.446517 -1.363160 +v 0.701727 1.424875 -1.327259 +v 0.694642 1.459982 -1.388853 +v 0.725905 1.450129 -1.373021 +v 0.774897 1.459872 -1.389688 +v 0.774252 1.446399 -1.364079 +v 0.886197 0.159679 -2.537953 +v 0.886197 0.159679 -2.537953 +v 0.896331 0.160900 -2.529450 +v 1.177099 0.156374 -2.567897 +v 1.177099 0.156374 -2.567897 +v 1.166975 0.155154 -2.576388 +v 1.181893 0.300910 -2.593376 +v 1.144436 0.154579 -2.579867 +v 0.919776 0.161067 -2.526124 +v 0.945955 0.159258 -2.524441 +v 1.103544 -0.003815 -2.560290 +v 1.103544 -0.003815 -2.560290 +v 0.500142 1.005868 -1.065125 +v 0.504818 1.060013 -1.094706 +v 0.553949 1.059468 -1.095208 +v 0.537481 0.993681 -1.058795 +v 0.527144 1.114659 -1.123169 +v 0.570398 1.126317 -1.129642 +v 0.726277 1.502148 -1.464234 +v 0.775186 1.501081 -1.465454 +v 0.824113 1.501963 -1.465563 +v 0.998844 1.313584 -2.435161 +v 0.991159 1.271643 -2.465780 +v 1.040148 1.270874 -2.466609 +v 1.038814 1.322296 -2.429382 +v 1.001046 1.230308 -2.497876 +v 1.041420 1.220799 -2.505630 +v 1.081298 1.230175 -2.500535 +v 1.089075 1.271453 -2.469232 +v 1.079223 1.313406 -2.438165 +v 1.006774 1.574325 -2.112930 +v 1.056156 1.575133 -2.115677 +v 1.004366 0.830459 -2.577418 +v 0.996067 0.758069 -2.586737 +v 1.044915 0.757906 -2.585419 +v 1.044329 0.846221 -2.574749 +v 1.005334 0.685814 -2.597042 +v 1.045511 0.669888 -2.598315 +v 1.085480 0.685800 -2.596411 +v 1.093773 0.758041 -2.586327 +v 1.084508 0.830430 -2.577376 +v 0.994741 0.230387 -2.533121 +v 0.983825 0.156782 -2.518356 +v 1.032637 0.156989 -2.518336 +v 1.035251 0.246636 -2.536366 +v 0.990425 0.082980 -2.505032 +v 1.029975 0.066926 -2.502513 +v 1.070449 0.082980 -2.507131 +v 1.081400 0.156782 -2.520524 +v 1.074790 0.230387 -2.534578 +v 0.991505 0.855809 -2.576547 +v 1.044040 0.891490 -2.571779 +v 1.097055 0.855766 -2.576711 +v 0.985637 1.329567 -2.425885 +v 1.038067 1.349952 -2.412423 +v 1.091545 1.329316 -2.429970 +v 0.519742 1.135108 -1.131614 +v 0.481736 1.061980 -1.092606 +v 0.483288 0.990755 -1.054362 +v 1.094268 1.215812 -2.512703 +v 1.041958 1.194556 -2.525886 +v 0.988614 1.215972 -2.509340 +v 1.098227 0.660868 -2.600941 +v 1.045621 0.625017 -2.605551 +v 1.098227 0.660868 -2.600941 +v 1.045621 0.625017 -2.605551 +v 0.992670 0.660881 -2.601932 +v 0.992670 0.660881 -2.601932 +v 0.529996 0.965027 -1.040166 +v 0.977041 0.060458 -2.502991 +v 0.960653 0.156873 -2.520968 +v 0.982745 0.255595 -2.540398 +v 1.036536 0.292107 -2.548038 +v 1.088179 0.255595 -2.542078 +v 1.097980 0.041491 -2.506636 +v 1.082423 0.060458 -2.505967 +v 1.028714 0.025735 -2.497859 +v 1.028280 0.012846 -2.498764 +v 1.082423 0.060458 -2.505967 +v 1.028714 0.025735 -2.497859 +v 0.977041 0.060458 -2.502991 +v 0.960236 0.041491 -2.502414 +v 1.112192 1.272967 -2.472298 +v 0.847338 1.504112 -1.464737 +v 1.104476 0.156873 -2.524158 +v 0.967862 1.273246 -2.467213 +v 0.972896 0.758430 -2.589636 +v 0.703113 1.504385 -1.462776 +v 1.116919 0.758390 -2.589047 +v 0.579834 1.162122 -1.145869 +v 1.079265 1.577435 -2.117311 +vt 0.874510 0.387454 +vt 0.877722 0.386340 +vt 0.876990 0.379427 +vt 0.873795 0.380641 +vt 0.879504 0.385602 +vt 0.878771 0.378708 +vt 0.878135 0.368911 +vt 0.876406 0.369599 +vt 0.873331 0.370892 +vt 0.582296 0.006698 +vt 0.582239 0.011478 +vt 0.585213 0.011063 +vt 0.585269 0.006283 +vt 0.582183 0.016264 +vt 0.585157 0.015851 +vt 0.587676 0.015437 +vt 0.587731 0.010646 +vt 0.587787 0.005865 +vt 0.922594 0.343624 +vt 0.924263 0.343425 +vt 0.923732 0.335115 +vt 0.922055 0.335286 +vt 0.925940 0.343225 +vt 0.925421 0.334943 +vt 0.925446 0.325575 +vt 0.923744 0.325701 +vt 0.922058 0.325834 +vt 0.867679 0.401598 +vt 0.872228 0.400047 +vt 0.871391 0.396914 +vt 0.866840 0.398465 +vt 0.876773 0.398499 +vt 0.875938 0.395364 +vt 0.875260 0.392618 +vt 0.870713 0.394168 +vt 0.866159 0.395721 +vt 0.582573 0.001458 +vt 0.580102 0.001800 +vt 0.579869 0.003611 +vt 0.582364 0.003321 +vt 0.024808 0.024046 +vt 0.026134 0.023682 +vt 0.026330 0.022140 +vt 0.024653 0.022208 +vt 0.026371 0.018796 +vt 0.024637 0.018824 +vt 0.579791 0.006977 +vt 0.865410 0.390565 +vt 0.862167 0.391655 +vt 0.862560 0.394932 +vt 0.865802 0.393845 +vt 0.860313 0.392161 +vt 0.860703 0.395423 +vt 0.861059 0.397287 +vt 0.862918 0.396805 +vt 0.793929 0.177491 +vt 0.797085 0.177767 +vt 0.797463 0.170023 +vt 0.795514 0.169892 +vt 0.798932 0.177912 +vt 0.799208 0.170116 +vt 0.799496 0.162016 +vt 0.797641 0.161964 +vt 0.794489 0.161836 +vt 0.587857 0.002490 +vt 0.585338 0.002906 +vt 0.846999 0.780254 +vt 0.848829 0.780747 +vt 0.849466 0.778377 +vt 0.847628 0.777897 +vt 0.585560 0.001045 +vt 0.869220 0.382452 +vt 0.869964 0.389007 +vt 0.868506 0.375597 +vt 0.863640 0.374243 +vt 0.864633 0.383784 +vt 0.783483 0.192770 +vt 0.784748 0.195717 +vt 0.788406 0.193259 +vt 0.788409 0.190468 +vt 0.785852 0.197641 +vt 0.788707 0.196631 +vt 0.791811 0.198223 +vt 0.792593 0.196488 +vt 0.793730 0.193774 +vt 0.925504 0.303942 +vt 0.924716 0.303691 +vt 0.922320 0.314601 +vt 0.923099 0.314756 +vt 0.327447 0.440461 +vt 0.326962 0.440130 +vt 0.320332 0.452441 +vt 0.320883 0.452641 +vt 0.316691 0.464542 +vt 0.317281 0.464609 +vt 0.921290 0.325778 +vt 0.926251 0.379105 +vt 0.925519 0.379420 +vt 0.926747 0.388948 +vt 0.927477 0.388599 +vt 0.337401 0.515594 +vt 0.336944 0.515997 +vt 0.344673 0.524363 +vt 0.345091 0.523919 +vt 0.353098 0.532032 +vt 0.353478 0.531556 +vt 0.928127 0.397919 +vt 0.928854 0.397541 +vt 0.832234 0.795611 +vt 0.832444 0.806559 +vt 0.836977 0.808190 +vt 0.836856 0.799890 +vt 0.832608 0.818337 +vt 0.837162 0.816672 +vt 0.842166 0.821975 +vt 0.841563 0.809976 +vt 0.841856 0.799171 +vt 0.427962 0.113659 +vt 0.428082 0.111999 +vt 0.427416 0.112000 +vt 0.427280 0.113784 +vt 0.428276 0.110343 +vt 0.427619 0.110369 +vt 0.427988 0.305227 +vt 0.429618 0.305149 +vt 0.429331 0.304674 +vt 0.427880 0.304577 +vt 0.426202 0.305301 +vt 0.424809 0.304461 +vt 0.844997 0.871073 +vt 0.847807 0.871995 +vt 0.847546 0.861601 +vt 0.844459 0.860424 +vt 0.849466 0.872814 +vt 0.849284 0.862418 +vt 0.848624 0.850330 +vt 0.846938 0.849590 +vt 0.844064 0.848614 +vt 0.843479 0.783146 +vt 0.842184 0.783906 +vt 0.842821 0.790067 +vt 0.843879 0.790580 +vt 0.841110 0.784942 +vt 0.841175 0.789503 +vt 0.840023 0.793587 +vt 0.840778 0.795411 +vt 0.833838 0.779619 +vt 0.830775 0.779153 +vt 0.829934 0.785553 +vt 0.831767 0.786129 +vt 0.829044 0.778452 +vt 0.828303 0.784852 +vt 0.827632 0.793986 +vt 0.829363 0.794694 +vt 0.783725 0.176575 +vt 0.780591 0.176279 +vt 0.780408 0.184065 +vt 0.783724 0.184320 +vt 0.778776 0.176090 +vt 0.778530 0.183906 +vt 0.778632 0.192770 +vt 0.780453 0.192848 +vt 0.877701 0.318654 +vt 0.876961 0.318684 +vt 0.875902 0.332174 +vt 0.876609 0.332067 +vt 0.641115 0.545373 +vt 0.640794 0.545866 +vt 0.653135 0.551884 +vt 0.653351 0.551335 +vt 0.666002 0.555382 +vt 0.666114 0.554799 +vt 0.874906 0.345943 +vt 0.875583 0.345759 +vt 0.879284 0.318196 +vt 0.880064 0.306256 +vt 0.878461 0.306695 +vt 0.880857 0.317757 +vt 0.881654 0.305837 +vt 0.881879 0.295800 +vt 0.880273 0.296202 +vt 0.878656 0.296623 +vt 0.862835 0.350297 +vt 0.863548 0.350039 +vt 0.864583 0.336334 +vt 0.863899 0.336676 +vt 0.372523 0.412709 +vt 0.372441 0.412127 +vt 0.359382 0.415683 +vt 0.359566 0.416236 +vt 0.346847 0.421739 +vt 0.347144 0.422243 +vt 0.865655 0.322912 +vt 0.865006 0.323349 +vt 0.834537 0.844864 +vt 0.835385 0.856778 +vt 0.839956 0.858707 +vt 0.839561 0.850221 +vt 0.835444 0.867159 +vt 0.840323 0.866896 +vt 0.796344 0.215132 +vt 0.794166 0.212012 +vt 0.790549 0.214473 +vt 0.791708 0.217411 +vt 0.792953 0.209916 +vt 0.790094 0.210894 +vt 0.786985 0.209347 +vt 0.786304 0.211266 +vt 0.840494 0.870350 +vt 0.843989 0.873676 +vt 0.842719 0.844105 +vt 0.839354 0.846079 +vt 0.841671 0.841388 +vt 0.839033 0.841825 +vt 0.836141 0.839236 +vt 0.835437 0.841261 +vt 0.879985 0.397379 +vt 0.879150 0.394246 +vt 0.881749 0.396592 +vt 0.880920 0.393473 +vt 0.880250 0.390742 +vt 0.878474 0.391501 +vt 0.799368 0.586086 +vt 0.799487 0.587734 +vt 0.800197 0.587725 +vt 0.800082 0.585951 +vt 0.799683 0.589384 +vt 0.800373 0.589349 +vt 0.800858 0.589026 +vt 0.800860 0.587570 +vt 0.800793 0.584500 +vt 0.865941 0.301507 +vt 0.864419 0.302279 +vt 0.864209 0.312217 +vt 0.865753 0.311486 +vt 0.862887 0.303078 +vt 0.862654 0.312978 +vt 0.861869 0.324749 +vt 0.863441 0.324031 +vt 0.829312 0.805438 +vt 0.827513 0.804730 +vt 0.827963 0.816779 +vt 0.829703 0.817417 +vt 0.877498 0.400998 +vt 0.880693 0.399871 +vt 0.352409 0.028949 +vt 0.350617 0.028972 +vt 0.350661 0.032319 +vt 0.352395 0.032337 +vt 0.350873 0.033872 +vt 0.352247 0.034204 +vt 0.882391 0.399069 +vt 0.874083 0.358576 +vt 0.874820 0.358581 +vt 0.677986 0.556164 +vt 0.678078 0.555552 +vt 0.686720 0.555706 +vt 0.687031 0.555036 +vt 0.872196 0.368267 +vt 0.414739 0.301790 +vt 0.414964 0.302622 +vt 0.419782 0.303085 +vt 0.419808 0.302388 +vt 0.414674 0.303485 +vt 0.419757 0.303859 +vt 0.424600 0.303544 +vt 0.424876 0.302751 +vt 0.784936 0.143734 +vt 0.781803 0.143463 +vt 0.781552 0.152205 +vt 0.784877 0.152484 +vt 0.779996 0.143199 +vt 0.779690 0.151954 +vt 0.779385 0.160419 +vt 0.781188 0.160657 +vt 0.784313 0.161021 +vt 0.413161 0.297851 +vt 0.413916 0.297610 +vt 0.414016 0.291365 +vt 0.413262 0.291612 +vt 0.683812 0.414753 +vt 0.683527 0.414235 +vt 0.676488 0.418250 +vt 0.676775 0.418767 +vt 0.667008 0.423658 +vt 0.667309 0.424169 +vt 0.414152 0.282963 +vt 0.413399 0.283225 +vt 0.794778 0.204388 +vt 0.795961 0.204604 +vt 0.793036 0.204114 +vt 0.583336 0.030267 +vt 0.581571 0.043488 +vt 0.582373 0.043671 +vt 0.584108 0.030549 +vt 0.580539 0.059292 +vt 0.581370 0.059352 +vt 0.907746 0.937056 +vt 0.907803 0.921756 +vt 0.906079 0.921724 +vt 0.905991 0.936938 +vt 0.908067 0.949731 +vt 0.906289 0.949536 +vt 0.907292 0.958009 +vt 0.907329 0.957303 +vt 0.902542 0.957690 +vt 0.902540 0.958403 +vt 0.907632 0.956608 +vt 0.902541 0.956937 +vt 0.897495 0.957463 +vt 0.897760 0.958104 +vt 0.897790 0.958798 +vt 0.831515 0.843509 +vt 0.832216 0.855438 +vt 0.829761 0.842892 +vt 0.830405 0.854827 +vt 0.830590 0.865086 +vt 0.832365 0.865675 +vt 0.861234 0.350873 +vt 0.860626 0.363577 +vt 0.862352 0.362949 +vt 0.859641 0.351466 +vt 0.858998 0.364117 +vt 0.858982 0.375527 +vt 0.860737 0.375010 +vt 0.861239 0.410059 +vt 0.860614 0.411304 +vt 0.861487 0.411776 +vt 0.862203 0.410593 +vt 0.856752 0.418349 +vt 0.857568 0.418749 +vt 0.970419 0.724242 +vt 0.970369 0.716130 +vt 0.968865 0.716828 +vt 0.968910 0.724945 +vt 0.970533 0.725625 +vt 0.968982 0.726349 +vt 0.213452 0.221631 +vt 0.211553 0.208407 +vt 0.210737 0.208620 +vt 0.212670 0.221943 +vt 0.210424 0.192564 +vt 0.209578 0.192653 +vt 0.413231 0.323458 +vt 0.413092 0.338653 +vt 0.414807 0.338596 +vt 0.414977 0.323317 +vt 0.413710 0.311013 +vt 0.415481 0.310799 +vt 0.418878 0.323618 +vt 0.419412 0.311056 +vt 0.418676 0.338927 +vt 0.422527 0.339426 +vt 0.422746 0.324146 +vt 0.423301 0.311585 +vt 0.902089 0.937201 +vt 0.902355 0.949757 +vt 0.902208 0.922018 +vt 0.898363 0.922446 +vt 0.898225 0.937661 +vt 0.898470 0.950223 +vt 0.956073 0.538775 +vt 0.956189 0.560130 +vt 0.959913 0.561574 +vt 0.960148 0.542466 +vt 0.955962 0.581182 +vt 0.959702 0.582389 +vt 0.963538 0.583425 +vt 0.963721 0.562624 +vt 0.964336 0.541843 +vt 0.418160 0.168268 +vt 0.417556 0.167022 +vt 0.416692 0.167584 +vt 0.417163 0.168845 +vt 0.413733 0.159930 +vt 0.413036 0.160587 +vt 0.413330 0.162752 +vt 0.416004 0.168232 +vt 0.416107 0.169250 +vt 0.671603 0.163323 +vt 0.671326 0.162507 +vt 0.667626 0.161414 +vt 0.667384 0.162030 +vt 0.671507 0.161396 +vt 0.667861 0.160376 +vt 0.664123 0.159227 +vt 0.663839 0.160190 +vt 0.663038 0.160716 +vt 0.965317 0.726365 +vt 0.965295 0.727803 +vt 0.965257 0.718206 +vt 0.961589 0.719508 +vt 0.961673 0.727717 +vt 0.961559 0.729185 +vt 0.839011 0.452026 +vt 0.835001 0.464308 +vt 0.835858 0.464258 +vt 0.839864 0.452155 +vt 0.835048 0.472132 +vt 0.835839 0.471879 +vt 0.970271 0.665634 +vt 0.970533 0.659450 +vt 0.969023 0.660433 +vt 0.968754 0.666515 +vt 0.970134 0.677960 +vt 0.968620 0.678752 +vt 0.968714 0.698545 +vt 0.965043 0.699859 +vt 0.964886 0.680010 +vt 0.961052 0.681067 +vt 0.961292 0.701046 +vt 0.847935 0.434247 +vt 0.848757 0.434531 +vt 0.970223 0.697817 +vt 0.404996 0.143949 +vt 0.404209 0.144313 +vt 0.396156 0.126105 +vt 0.395307 0.126255 +vt 0.954713 0.559671 +vt 0.954440 0.580450 +vt 0.954984 0.540469 +vt 0.392227 0.106311 +vt 0.394087 0.100991 +vt 0.393454 0.100537 +vt 0.391440 0.106079 +vt 0.396157 0.097395 +vt 0.395718 0.096742 +vt 0.111200 0.021978 +vt 0.110918 0.017810 +vt 0.109155 0.017547 +vt 0.109410 0.021966 +vt 0.112068 0.027087 +vt 0.110266 0.027312 +vt 0.392188 0.113855 +vt 0.391336 0.113827 +vt 0.954503 0.593537 +vt 0.954802 0.600229 +vt 0.956320 0.601167 +vt 0.956029 0.594362 +vt 0.959797 0.595559 +vt 0.960076 0.602436 +vt 0.963938 0.603384 +vt 0.963668 0.596504 +vt 0.964992 0.667766 +vt 0.965273 0.661751 +vt 0.961416 0.662729 +vt 0.961124 0.668740 +vt 0.109224 0.014755 +vt 0.105282 0.014116 +vt 0.105201 0.017021 +vt 0.109627 0.011844 +vt 0.105692 0.011154 +vt 0.101751 0.010694 +vt 0.101349 0.013620 +vt 0.101273 0.016523 +vt 0.105439 0.021635 +vt 0.106283 0.027165 +vt 0.101511 0.021193 +vt 0.102349 0.026777 +vt 0.535057 0.008515 +vt 0.533514 0.013029 +vt 0.537478 0.012938 +vt 0.539004 0.008603 +vt 0.532716 0.016665 +vt 0.536693 0.016384 +vt 0.540596 0.016112 +vt 0.541363 0.012716 +vt 0.542878 0.008432 +vt 0.836960 0.478048 +vt 0.837597 0.477574 +vt 0.839088 0.482226 +vt 0.839530 0.481555 +vt 0.531685 0.012913 +vt 0.530888 0.016798 +vt 0.533244 0.008167 +vt 0.843599 0.484882 +vt 0.849663 0.484235 +vt 0.849644 0.483327 +vt 0.843704 0.484001 +vt 0.856167 0.483245 +vt 0.856068 0.482335 +vt 0.531830 0.026113 +vt 0.532786 0.030815 +vt 0.534573 0.030231 +vt 0.533622 0.025578 +vt 0.530954 0.021626 +vt 0.532755 0.021178 +vt 0.532449 0.018759 +vt 0.536428 0.018367 +vt 0.536731 0.020735 +vt 0.540654 0.020505 +vt 0.540344 0.018100 +vt 0.840627 0.484393 +vt 0.840886 0.483587 +vt 0.530633 0.019079 +vt 0.397665 0.095476 +vt 0.397407 0.094685 +vt 0.400634 0.095010 +vt 0.400530 0.094143 +vt 0.110960 0.015205 +vt 0.111343 0.012421 +vt 0.535306 0.033085 +vt 0.539112 0.032624 +vt 0.538547 0.029739 +vt 0.536318 0.034197 +vt 0.539323 0.034047 +vt 0.542249 0.033690 +vt 0.542875 0.032439 +vt 0.542479 0.029556 +vt 0.406706 0.095633 +vt 0.406725 0.094739 +vt 0.413221 0.096599 +vt 0.413322 0.095703 +vt 0.431766 0.785152 +vt 0.436692 0.785157 +vt 0.436159 0.783401 +vt 0.431197 0.783399 +vt 0.112068 0.007916 +vt 0.110363 0.007255 +vt 0.106430 0.006535 +vt 0.435816 0.779418 +vt 0.430842 0.779419 +vt 0.435794 0.775446 +vt 0.430832 0.775447 +vt 0.102483 0.006103 +vt 0.537596 0.025105 +vt 0.541524 0.024905 +vt 0.523898 0.551587 +vt 0.523581 0.550770 +vt 0.519737 0.552319 +vt 0.519998 0.553156 +vt 0.523380 0.550195 +vt 0.519579 0.551731 +vt 0.516320 0.553013 +vt 0.516435 0.553616 +vt 0.516636 0.554471 +vt 0.093015 0.422985 +vt 0.093315 0.422174 +vt 0.089347 0.420622 +vt 0.089104 0.421451 +vt 0.093465 0.421632 +vt 0.089455 0.420067 +vt 0.085978 0.418751 +vt 0.085914 0.419319 +vt 0.085731 0.420166 +vt 0.080106 0.419491 +vt 0.073073 0.419887 +vt 0.073041 0.420767 +vt 0.079984 0.420369 +vt 0.063299 0.420818 +vt 0.063388 0.421689 +vt 0.063380 0.422396 +vt 0.072945 0.421479 +vt 0.079822 0.421079 +vt 0.494317 0.554070 +vt 0.483391 0.552417 +vt 0.483178 0.553266 +vt 0.494235 0.554946 +vt 0.472035 0.548895 +vt 0.471685 0.549686 +vt 0.878776 0.357156 +vt 0.879367 0.344538 +vt 0.878681 0.344723 +vt 0.878097 0.357450 +vt 0.878803 0.368520 +vt 0.511036 0.555204 +vt 0.504033 0.554887 +vt 0.504071 0.555768 +vt 0.511163 0.556082 +vt 0.494209 0.555624 +vt 0.504133 0.556450 +vt 0.511292 0.556760 +vt 0.052281 0.422606 +vt 0.052502 0.423447 +vt 0.040817 0.426261 +vt 0.041175 0.427041 +vt 0.826819 0.804365 +vt 0.827260 0.816523 +vt 0.052588 0.424135 +vt 0.019440 0.441221 +vt 0.011227 0.451363 +vt 0.011913 0.451874 +vt 0.020054 0.441817 +vt 0.005391 0.462983 +vt 0.006125 0.463356 +vt 0.829665 0.854859 +vt 0.829816 0.865185 +vt 0.829041 0.842856 +vt 0.029580 0.432629 +vt 0.030077 0.433320 +vt 0.828119 0.829707 +vt 0.828829 0.829845 +vt 0.460900 0.542632 +vt 0.460410 0.543334 +vt 0.450830 0.534103 +vt 0.450221 0.534709 +vt 0.880427 0.331041 +vt 0.881569 0.317791 +vt 0.879731 0.331108 +vt 0.442626 0.523974 +vt 0.441942 0.524492 +vt 0.436730 0.512329 +vt 0.435992 0.512704 +vt 0.435493 0.513046 +vt 0.441479 0.524932 +vt 0.882391 0.305936 +vt 0.002230 0.475730 +vt 0.003006 0.475866 +vt 0.001800 0.487535 +vt 0.002597 0.487427 +vt 0.800404 0.205525 +vt 0.799574 0.194957 +vt 0.798859 0.194745 +vt 0.799711 0.205152 +vt 0.003493 0.476064 +vt 0.006582 0.463726 +vt 0.433443 0.499541 +vt 0.432654 0.499675 +vt 0.432884 0.487723 +vt 0.432068 0.487608 +vt 0.431517 0.487594 +vt 0.432121 0.499842 +vt 0.032986 0.530367 +vt 0.042256 0.536369 +vt 0.042629 0.535624 +vt 0.033447 0.529689 +vt 0.052086 0.541549 +vt 0.052390 0.540755 +vt 0.801221 0.135264 +vt 0.801602 0.126844 +vt 0.800832 0.127267 +vt 0.800449 0.135632 +vt 0.800897 0.144211 +vt 0.800121 0.144505 +vt 0.007307 0.503958 +vt 0.011200 0.510985 +vt 0.011889 0.510535 +vt 0.008044 0.503595 +vt 0.016471 0.517781 +vt 0.017101 0.517247 +vt 0.799977 0.170055 +vt 0.800276 0.161878 +vt 0.799684 0.177928 +vt 0.438280 0.471445 +vt 0.442146 0.464519 +vt 0.441431 0.464059 +vt 0.437519 0.471073 +vt 0.447413 0.457836 +vt 0.446757 0.457293 +vt 0.948473 0.360049 +vt 0.948950 0.368405 +vt 0.949661 0.368526 +vt 0.949173 0.360093 +vt 0.948127 0.352051 +vt 0.948811 0.352018 +vt 0.464022 0.445523 +vt 0.473347 0.439644 +vt 0.472953 0.438894 +vt 0.463538 0.444838 +vt 0.483184 0.434464 +vt 0.482861 0.433665 +vt 0.482658 0.433108 +vt 0.472700 0.438376 +vt 0.950467 0.386663 +vt 0.951340 0.395956 +vt 0.952050 0.396309 +vt 0.951179 0.386941 +vt 0.097120 0.554082 +vt 0.097921 0.554300 +vt 0.098138 0.553483 +vt 0.097344 0.553262 +vt 0.428684 0.109619 +vt 0.428966 0.110458 +vt 0.429372 0.109763 +vt 0.429448 0.110828 +vt 0.429868 0.110492 +vt 0.913386 0.958079 +vt 0.913288 0.957400 +vt 0.912524 0.957098 +vt 0.912591 0.957753 +vt 0.527771 0.420686 +vt 0.528583 0.420467 +vt 0.528334 0.419645 +vt 0.527525 0.419859 +vt 0.529290 0.420349 +vt 0.529022 0.419545 +vt 0.409059 0.302656 +vt 0.409740 0.303236 +vt 0.410137 0.302829 +vt 0.409815 0.302301 +vt 0.408971 0.302004 +vt 0.409758 0.301649 +vt 0.426864 0.284233 +vt 0.428505 0.284516 +vt 0.428684 0.275582 +vt 0.427040 0.275305 +vt 0.430139 0.284840 +vt 0.430323 0.275896 +vt 0.932126 0.405238 +vt 0.933772 0.404887 +vt 0.932157 0.396915 +vt 0.930506 0.397248 +vt 0.930477 0.405549 +vt 0.862314 0.337304 +vt 0.860731 0.337962 +vt 0.952092 0.351783 +vt 0.950449 0.351901 +vt 0.950818 0.360018 +vt 0.952463 0.359940 +vt 0.951310 0.368494 +vt 0.952956 0.368455 +vt 0.846362 0.784854 +vt 0.846678 0.781879 +vt 0.843521 0.780628 +vt 0.848098 0.785419 +vt 0.848492 0.782396 +vt 0.843801 0.779114 +vt 0.411603 0.301634 +vt 0.411659 0.302321 +vt 0.411606 0.303011 +vt 0.582170 0.019670 +vt 0.585146 0.019261 +vt 0.582333 0.021627 +vt 0.585322 0.021221 +vt 0.587857 0.020814 +vt 0.587668 0.018850 +vt 0.877130 0.345241 +vt 0.878172 0.331581 +vt 0.897413 0.978172 +vt 0.894290 0.978482 +vt 0.894324 0.987774 +vt 0.897649 0.987591 +vt 0.892489 0.978774 +vt 0.892458 0.988045 +vt 0.892476 0.996701 +vt 0.894286 0.996452 +vt 0.897406 0.996461 +vt 0.096235 0.424310 +vt 0.096543 0.423504 +vt 0.098243 0.425251 +vt 0.098485 0.424430 +vt 0.351765 0.013417 +vt 0.350205 0.014132 +vt 0.350874 0.014451 +vt 0.352248 0.014091 +vt 0.096660 0.422967 +vt 0.846105 0.836475 +vt 0.844308 0.835762 +vt 0.847697 0.837141 +vt 0.846865 0.823958 +vt 0.845164 0.823294 +vt 0.924796 0.314676 +vt 0.926511 0.314623 +vt 0.928937 0.303935 +vt 0.927210 0.303917 +vt 0.910665 0.957752 +vt 0.910665 0.957079 +vt 0.430045 0.112342 +vt 0.429450 0.112303 +vt 0.430045 0.115687 +vt 0.429381 0.115393 +vt 0.830476 0.830430 +vt 0.832318 0.831123 +vt 0.956406 0.312270 +vt 0.954761 0.312560 +vt 0.951953 0.323297 +vt 0.953597 0.323047 +vt 0.953135 0.312904 +vt 0.950325 0.323583 +vt 0.948898 0.334510 +vt 0.950526 0.334294 +vt 0.952167 0.334091 +vt 0.863601 0.399546 +vt 0.861737 0.400012 +vt 0.862573 0.403127 +vt 0.864441 0.402675 +vt 0.781167 0.203234 +vt 0.783053 0.203359 +vt 0.779433 0.203196 +vt 0.781300 0.213571 +vt 0.783137 0.213593 +vt 0.786069 0.214180 +vt 0.795119 0.144388 +vt 0.798267 0.144530 +vt 0.798703 0.135703 +vt 0.796754 0.135644 +vt 0.798979 0.127342 +vt 0.795812 0.127083 +vt 0.876512 0.358031 +vt 0.799745 0.215123 +vt 0.797975 0.204853 +vt 0.801602 0.215441 +vt 0.797008 0.194462 +vt 0.927907 0.378833 +vt 0.926730 0.369316 +vt 0.925074 0.369574 +vt 0.929559 0.378539 +vt 0.928383 0.369043 +vt 0.927356 0.359911 +vt 0.925699 0.360161 +vt 0.924040 0.360403 +vt 0.844710 0.811206 +vt 0.846471 0.811826 +vt 0.846643 0.801023 +vt 0.844914 0.800454 +vt 0.954474 0.387037 +vt 0.952828 0.387000 +vt 0.953698 0.396411 +vt 0.955344 0.396479 +vt 0.953091 0.405208 +vt 0.954739 0.405338 +vt 0.956385 0.405428 +vt 0.845711 0.791351 +vt 0.847345 0.791847 +vt 0.514450 0.555120 +vt 0.514625 0.555994 +vt 0.516847 0.555336 +vt 0.514787 0.556669 +vt 0.517037 0.556004 +vt 0.083536 0.419538 +vt 0.083367 0.420413 +vt 0.085525 0.421033 +vt 0.083171 0.421120 +vt 0.085301 0.421734 +vt 0.834763 0.775819 +vt 0.831551 0.774622 +vt 0.831214 0.776235 +vt 0.834418 0.777305 +vt 0.829771 0.773799 +vt 0.829433 0.775443 +vt 0.838991 0.778831 +vt 0.839287 0.777468 +vt 0.838869 0.779708 +vt 0.874904 0.390740 +vt 0.870356 0.392291 +vt 0.861426 0.384766 +vt 0.859590 0.385289 +vt 0.878117 0.389624 +vt 0.879896 0.388874 +vt 0.348801 0.029059 +vt 0.349517 0.029013 +vt 0.349518 0.024212 +vt 0.348802 0.024257 +vt 0.350617 0.024172 +vt 0.350617 0.019366 +vt 0.349518 0.019406 +vt 0.348803 0.019451 +vt 0.348892 0.032457 +vt 0.349602 0.032399 +vt 0.349530 0.034361 +vt 0.350204 0.034246 +vt 0.028199 0.009097 +vt 0.028112 0.005683 +vt 0.027384 0.005746 +vt 0.027464 0.009148 +vt 0.027500 0.003757 +vt 0.026808 0.003877 +vt 0.026138 0.004255 +vt 0.026333 0.005823 +vt 0.026373 0.009186 +vt 0.868405 0.404096 +vt 0.872954 0.402546 +vt 0.352409 0.019342 +vt 0.352409 0.024148 +vt 0.579733 0.011755 +vt 0.026371 0.013994 +vt 0.024638 0.014022 +vt 0.024639 0.009213 +vt 0.579677 0.016541 +vt 0.863353 0.405556 +vt 0.865178 0.405157 +vt 0.350661 0.016009 +vt 0.352395 0.015945 +vt 0.527128 0.550248 +vt 0.526772 0.549450 +vt 0.529249 0.549388 +vt 0.528829 0.548633 +vt 0.528248 0.548340 +vt 0.526514 0.548920 +vt 0.579674 0.019931 +vt 0.024657 0.005809 +vt 0.024812 0.003925 +vt 0.579862 0.021823 +vt 0.441295 0.775434 +vt 0.440679 0.775584 +vt 0.441249 0.779383 +vt 0.441896 0.779403 +vt 0.440140 0.776401 +vt 0.440393 0.779378 +vt 0.440414 0.782369 +vt 0.441029 0.783201 +vt 0.441661 0.783393 +vt 0.860200 0.482565 +vt 0.860057 0.481663 +vt 0.862112 0.482035 +vt 0.861913 0.481166 +vt 0.533595 0.033694 +vt 0.535494 0.034852 +vt 0.417245 0.097216 +vt 0.417365 0.096325 +vt 0.419041 0.097397 +vt 0.419114 0.096516 +vt 0.439741 0.784898 +vt 0.439214 0.783211 +vt 0.438908 0.779396 +vt 0.438864 0.775594 +vt 0.663134 0.161168 +vt 0.667270 0.162352 +vt 0.639261 0.005741 +vt 0.638987 0.005391 +vt 0.638934 0.010079 +vt 0.639234 0.010055 +vt 0.639655 0.014667 +vt 0.639881 0.014274 +vt 0.671350 0.163560 +vt 0.641247 0.003732 +vt 0.641282 0.003395 +vt 0.640068 0.003810 +vt 0.640135 0.004037 +vt 0.641344 0.002733 +vt 0.639917 0.003218 +vt 0.661615 0.160529 +vt 0.661321 0.160705 +vt 0.213378 0.171257 +vt 0.214238 0.167924 +vt 0.213139 0.167740 +vt 0.212448 0.171143 +vt 0.214357 0.167377 +vt 0.212972 0.167119 +vt 0.502499 0.015472 +vt 0.502761 0.016003 +vt 0.503976 0.014123 +vt 0.503468 0.013749 +vt 0.414425 0.360196 +vt 0.414419 0.363665 +vt 0.416241 0.363696 +vt 0.416143 0.360227 +vt 0.908033 0.900848 +vt 0.908718 0.897636 +vt 0.904488 0.897830 +vt 0.904067 0.901087 +vt 0.500218 0.004809 +vt 0.499743 0.004231 +vt 0.499030 0.008817 +vt 0.499614 0.008977 +vt 0.499063 0.013503 +vt 0.499595 0.013228 +vt 0.900251 0.898035 +vt 0.900098 0.901360 +vt 0.664205 0.157777 +vt 0.662715 0.157230 +vt 0.662615 0.158649 +vt 0.664188 0.155823 +vt 0.662727 0.155272 +vt 0.191619 0.042228 +vt 0.191643 0.044185 +vt 0.192987 0.044025 +vt 0.192921 0.042004 +vt 0.191512 0.040793 +vt 0.192772 0.040497 +vt 0.956412 0.533429 +vt 0.955005 0.532155 +vt 0.955077 0.532146 +vt 0.199947 0.037884 +vt 0.200144 0.038296 +vt 0.201648 0.037766 +vt 0.201432 0.036750 +vt 0.672560 0.162603 +vt 0.672769 0.161629 +vt 0.415392 0.168622 +vt 0.415052 0.169097 +vt 0.279534 0.323101 +vt 0.280125 0.323859 +vt 0.280125 0.322138 +vt 0.279570 0.321518 +vt 0.662375 0.159458 +vt 0.191267 0.039952 +vt 0.192482 0.040224 +vt 0.965365 0.536086 +vt 0.964947 0.535998 +vt 0.963714 0.536239 +vt 0.960090 0.535241 +vt 0.211390 0.386170 +vt 0.211743 0.385962 +vt 0.211480 0.382178 +vt 0.211122 0.382427 +vt 0.211743 0.378268 +vt 0.211304 0.378347 +vt 0.192937 0.046839 +vt 0.196627 0.045959 +vt 0.196702 0.043221 +vt 0.192697 0.052092 +vt 0.196344 0.051243 +vt 0.200071 0.050232 +vt 0.200360 0.044941 +vt 0.200459 0.042296 +vt 0.196604 0.041102 +vt 0.196413 0.039441 +vt 0.200357 0.040102 +vt 0.671652 0.159656 +vt 0.667964 0.158789 +vt 0.671672 0.157535 +vt 0.667952 0.156764 +vt 0.201844 0.039616 +vt 0.201918 0.041813 +vt 0.672955 0.159816 +vt 0.673015 0.157632 +vt 0.671332 0.149604 +vt 0.671043 0.140252 +vt 0.667407 0.139868 +vt 0.667678 0.148812 +vt 0.670808 0.130605 +vt 0.667174 0.130688 +vt 0.663327 0.130494 +vt 0.663624 0.139234 +vt 0.663944 0.147810 +vt 0.671558 0.154904 +vt 0.667861 0.154064 +vt 0.664121 0.153037 +vt 0.201810 0.044405 +vt 0.201559 0.049672 +vt 0.672892 0.155007 +vt 0.672610 0.149663 +vt 0.662668 0.152433 +vt 0.662453 0.147190 +vt 0.191602 0.047008 +vt 0.191418 0.052223 +vt 0.663606 0.120306 +vt 0.664517 0.115704 +vt 0.662864 0.115437 +vt 0.661871 0.120050 +vt 0.665840 0.112571 +vt 0.665104 0.111799 +vt 0.215251 0.116760 +vt 0.215237 0.112531 +vt 0.214411 0.113211 +vt 0.214135 0.116722 +vt 0.215010 0.121893 +vt 0.213854 0.121737 +vt 0.199656 0.059595 +vt 0.201242 0.059115 +vt 0.199308 0.069254 +vt 0.200992 0.068893 +vt 0.672235 0.140114 +vt 0.671926 0.130258 +vt 0.662037 0.138709 +vt 0.661643 0.130101 +vt 0.191052 0.060671 +vt 0.190710 0.069266 +vt 0.191832 0.069529 +vt 0.192248 0.060731 +vt 0.195879 0.060265 +vt 0.195465 0.069509 +vt 0.671477 0.112325 +vt 0.671975 0.111503 +vt 0.668808 0.110379 +vt 0.668841 0.111879 +vt 0.077813 0.277518 +vt 0.078716 0.276895 +vt 0.078597 0.274000 +vt 0.077271 0.273921 +vt 0.078716 0.271397 +vt 0.077820 0.270816 +vt 0.192082 0.079736 +vt 0.193045 0.084374 +vt 0.196536 0.084582 +vt 0.195717 0.079910 +vt 0.194520 0.087458 +vt 0.197415 0.088165 +vt 0.200156 0.087564 +vt 0.200237 0.084512 +vt 0.199595 0.079889 +vt 0.671122 0.119966 +vt 0.671712 0.115385 +vt 0.668246 0.115583 +vt 0.667487 0.120255 +vt 0.201918 0.084396 +vt 0.201332 0.079662 +vt 0.201152 0.088058 +vt 0.734537 0.175231 +vt 0.735227 0.179004 +vt 0.735957 0.178315 +vt 0.735691 0.175043 +vt 0.734326 0.170179 +vt 0.735537 0.170009 +vt 0.581608 0.072185 +vt 0.582459 0.072134 +vt 0.583366 0.080376 +vt 0.584289 0.080232 +vt 0.908654 0.909011 +vt 0.909764 0.900781 +vt 0.906949 0.909043 +vt 0.211529 0.179569 +vt 0.210664 0.179547 +vt 0.413725 0.351618 +vt 0.415419 0.351621 +vt 0.419284 0.351936 +vt 0.420098 0.360498 +vt 0.424065 0.360841 +vt 0.423147 0.352362 +vt 0.903080 0.909322 +vt 0.899222 0.909679 +vt 0.644886 0.014007 +vt 0.645652 0.014506 +vt 0.645651 0.009244 +vt 0.644866 0.009311 +vt 0.227838 0.008920 +vt 0.225978 0.008180 +vt 0.225881 0.013904 +vt 0.227795 0.014164 +vt 0.225873 0.019597 +vt 0.227838 0.019376 +vt 0.644685 0.004102 +vt 0.644072 0.004716 +vt 0.642456 0.016658 +vt 0.642588 0.017498 +vt 0.644462 0.016948 +vt 0.643948 0.016179 +vt 0.149461 0.003772 +vt 0.149454 0.005617 +vt 0.151704 0.005592 +vt 0.151381 0.003766 +vt 0.227960 0.006593 +vt 0.226127 0.005651 +vt 0.502446 0.002279 +vt 0.502561 0.001439 +vt 0.500659 0.001495 +vt 0.500966 0.002357 +vt 0.982850 0.090027 +vt 0.982817 0.088171 +vt 0.980596 0.088185 +vt 0.980969 0.090017 +vt 0.215756 0.019812 +vt 0.217495 0.020750 +vt 0.217425 0.018282 +vt 0.215687 0.017546 +vt 0.499112 0.003571 +vt 0.504627 0.014696 +vt 0.505582 0.009640 +vt 0.504750 0.009582 +vt 0.264449 0.019999 +vt 0.266454 0.020242 +vt 0.266441 0.014608 +vt 0.264508 0.014831 +vt 0.266469 0.008939 +vt 0.264617 0.009634 +vt 0.505582 0.004461 +vt 0.504778 0.004941 +vt 0.420445 0.363921 +vt 0.504097 0.009602 +vt 0.504142 0.005374 +vt 0.424667 0.364202 +vt 0.584178 0.083604 +vt 0.585289 0.083382 +vt 0.502342 0.002992 +vt 0.501190 0.003088 +vt 0.910554 0.897559 +vt 0.642145 0.015609 +vt 0.642256 0.016041 +vt 0.643494 0.015619 +vt 0.643230 0.015220 +vt 0.644272 0.013656 +vt 0.643912 0.013383 +vt 0.644253 0.009396 +vt 0.643891 0.009384 +vt 0.643585 0.005220 +vt 0.643298 0.005461 +vt 0.221608 0.019114 +vt 0.221624 0.013234 +vt 0.217409 0.012564 +vt 0.221714 0.007333 +vt 0.217439 0.006835 +vt 0.270912 0.019812 +vt 0.270855 0.014004 +vt 0.275324 0.019033 +vt 0.275269 0.013388 +vt 0.275212 0.007689 +vt 0.270817 0.008150 +vt 0.149394 0.014392 +vt 0.149419 0.009975 +vt 0.147104 0.010037 +vt 0.147253 0.014491 +vt 0.147212 0.005637 +vt 0.270963 0.022316 +vt 0.275348 0.021449 +vt 0.266513 0.022686 +vt 0.982732 0.083860 +vt 0.980422 0.083914 +vt 0.982644 0.079522 +vt 0.980493 0.079609 +vt 0.221693 0.021645 +vt 0.225979 0.022042 +vt 0.498255 0.008698 +vt 0.215607 0.012306 +vt 0.215550 0.007058 +vt 0.498354 0.013948 +vt 0.501334 0.016120 +vt 0.501276 0.016899 +vt 0.503091 0.016781 +vt 0.149404 0.016395 +vt 0.147613 0.016504 +vt 0.264488 0.022246 +vt 0.641304 0.001912 +vt 0.639527 0.002473 +vt 0.982612 0.077588 +vt 0.984815 0.079489 +vt 0.984442 0.077548 +vt 0.277178 0.005540 +vt 0.275181 0.005122 +vt 0.277200 0.007898 +vt 0.638352 0.004917 +vt 0.638240 0.010166 +vt 0.277212 0.013130 +vt 0.277212 0.018310 +vt 0.639096 0.015295 +vt 0.906578 0.955259 +vt 0.902511 0.955479 +vt 0.898494 0.955947 +vt 0.415625 0.305092 +vt 0.419690 0.305336 +vt 0.423709 0.305878 +vt 0.214548 0.229019 +vt 0.214397 0.227645 +vt 0.213629 0.228010 +vt 0.213782 0.229426 +vt 0.413851 0.305367 +vt 0.413120 0.304038 +vt 0.584507 0.023077 +vt 0.584233 0.024276 +vt 0.584996 0.024599 +vt 0.585289 0.023399 +vt 0.908359 0.955473 +vt 0.909186 0.956676 +vt 0.907600 0.961151 +vt 0.910737 0.961687 +vt 0.910673 0.958698 +vt 0.907325 0.958818 +vt 0.912588 0.961793 +vt 0.912591 0.958724 +vt 0.801462 0.587548 +vt 0.801462 0.584213 +vt 0.801285 0.589370 +vt 0.894441 0.958438 +vt 0.892645 0.958763 +vt 0.892569 0.959418 +vt 0.894431 0.959101 +vt 0.411494 0.297854 +vt 0.411481 0.300713 +vt 0.413284 0.300724 +vt 0.409818 0.297898 +vt 0.409772 0.300747 +vt 0.427898 0.303875 +vt 0.429694 0.304203 +vt 0.429779 0.303551 +vt 0.427986 0.303190 +vt 0.523082 0.422017 +vt 0.526643 0.421006 +vt 0.526396 0.420179 +vt 0.522831 0.421190 +vt 0.408986 0.301103 +vt 0.409034 0.298259 +vt 0.092378 0.552898 +vt 0.095980 0.553798 +vt 0.096205 0.552977 +vt 0.092608 0.552078 +vt 0.913384 0.959051 +vt 0.913380 0.962125 +vt 0.902538 0.959062 +vt 0.902528 0.959764 +vt 0.897753 0.959604 +vt 0.897455 0.961955 +vt 0.423896 0.302104 +vt 0.419848 0.301850 +vt 0.863345 0.409252 +vt 0.862881 0.409388 +vt 0.863002 0.413327 +vt 0.863465 0.413312 +vt 0.863314 0.417256 +vt 0.863791 0.417360 +vt 0.415804 0.301339 +vt 0.868262 0.372745 +vt 0.930249 0.641645 +vt 0.930953 0.641614 +vt 0.930256 0.636620 +vt 0.929532 0.636530 +vt 0.930952 0.633678 +vt 0.930248 0.633466 +vt 0.864473 0.370959 +vt 0.907597 0.995943 +vt 0.907328 0.987049 +vt 0.902485 0.987356 +vt 0.902473 0.994242 +vt 0.907580 0.977508 +vt 0.902490 0.980267 +vt 0.062824 0.545354 +vt 0.063092 0.544539 +vt 0.073968 0.548298 +vt 0.074219 0.547480 +vt 0.913351 0.987285 +vt 0.913358 0.977834 +vt 0.912577 0.977479 +vt 0.912576 0.986915 +vt 0.913386 0.996046 +vt 0.912612 0.995654 +vt 0.493851 0.430453 +vt 0.493564 0.429633 +vt 0.504877 0.427183 +vt 0.504606 0.426359 +vt 0.504446 0.425794 +vt 0.493389 0.429065 +vt 0.413794 0.266226 +vt 0.412120 0.266303 +vt 0.411885 0.274474 +vt 0.413558 0.274416 +vt 0.410441 0.266413 +vt 0.410208 0.274569 +vt 0.410052 0.283335 +vt 0.411729 0.283260 +vt 0.910759 0.995598 +vt 0.910667 0.986857 +vt 0.910725 0.977421 +vt 0.894342 0.962986 +vt 0.894213 0.969632 +vt 0.896129 0.969280 +vt 0.892553 0.963382 +vt 0.892525 0.969950 +vt 0.426594 0.299070 +vt 0.428229 0.299374 +vt 0.428346 0.293035 +vt 0.426709 0.292741 +vt 0.429853 0.299719 +vt 0.429975 0.293370 +vt 0.952007 0.377568 +vt 0.953653 0.377568 +vt 0.950357 0.377555 +vt 0.929132 0.388318 +vt 0.930784 0.388004 +vt 0.797890 0.153389 +vt 0.794552 0.153185 +vt 0.799803 0.153412 +vt 0.455017 0.451558 +vt 0.454440 0.450941 +vt 0.949643 0.377356 +vt 0.024039 0.524190 +vt 0.024591 0.523582 +vt 0.800584 0.153197 +vt 0.789713 0.152856 +vt 0.789476 0.159322 +vt 0.789942 0.146410 +vt 0.390088 0.552461 +vt 0.389743 0.552951 +vt 0.392932 0.554748 +vt 0.393314 0.554257 +vt 0.389440 0.553485 +vt 0.392621 0.555282 +vt 0.863791 0.407510 +vt 0.863316 0.407638 +vt 0.426371 0.301952 +vt 0.425618 0.301549 +vt 0.785620 0.126533 +vt 0.782504 0.126438 +vt 0.782017 0.134737 +vt 0.783944 0.134906 +vt 0.780693 0.126159 +vt 0.780312 0.134466 +vt 0.950198 0.343657 +vt 0.951839 0.343498 +vt 0.948566 0.343818 +vt 0.434882 0.478705 +vt 0.434081 0.478431 +vt 0.947898 0.343933 +vt 0.948243 0.334738 +vt 0.003872 0.496606 +vt 0.004650 0.496341 +vt 0.799451 0.185924 +vt 0.798717 0.185826 +vt 0.953658 0.368551 +vt 0.953164 0.359971 +vt 0.618258 0.469071 +vt 0.617741 0.468801 +vt 0.614149 0.476954 +vt 0.614696 0.477152 +vt 0.612019 0.485012 +vt 0.612588 0.485134 +vt 0.952792 0.351747 +vt 0.793444 0.185243 +vt 0.788559 0.184716 +vt 0.788750 0.179057 +vt 0.780781 0.168602 +vt 0.782706 0.168801 +vt 0.779081 0.168400 +vt 0.796813 0.185623 +vt 0.924909 0.351612 +vt 0.923246 0.351834 +vt 0.926574 0.351386 +vt 0.389156 0.553955 +vt 0.392336 0.555748 +vt 0.425635 0.297961 +vt 0.423940 0.297590 +vt 0.423724 0.300434 +vt 0.425350 0.300804 +vt 0.422896 0.301018 +vt 0.423689 0.301335 +vt 0.425549 0.301152 +vt 0.423820 0.301684 +vt 0.372346 0.411643 +vt 0.359198 0.415224 +vt 0.960575 0.841081 +vt 0.958979 0.841783 +vt 0.958786 0.855771 +vt 0.960353 0.855004 +vt 0.958551 0.869503 +vt 0.960090 0.868668 +vt 0.346567 0.421324 +vt 0.610806 0.503109 +vt 0.610334 0.503179 +vt 0.614034 0.515362 +vt 0.614478 0.515186 +vt 0.062642 0.335184 +vt 0.064356 0.334958 +vt 0.065912 0.323554 +vt 0.064198 0.323848 +vt 0.068844 0.312457 +vt 0.067132 0.312808 +vt 0.620714 0.527776 +vt 0.621113 0.527493 +vt 0.666764 0.423230 +vt 0.656720 0.429129 +vt 0.656991 0.429543 +vt 0.414569 0.282262 +vt 0.416312 0.282169 +vt 0.416468 0.273256 +vt 0.414724 0.273377 +vt 0.416707 0.264951 +vt 0.414962 0.265097 +vt 0.647166 0.435751 +vt 0.647469 0.436143 +vt 0.631212 0.452082 +vt 0.630848 0.451756 +vt 0.623357 0.460206 +vt 0.623753 0.460484 +vt 0.064323 0.389433 +vt 0.066028 0.389539 +vt 0.065324 0.379844 +vt 0.063619 0.379786 +vt 0.064739 0.370477 +vt 0.063033 0.370471 +vt 0.617314 0.468580 +vt 0.326521 0.439868 +vt 0.319835 0.452290 +vt 0.078560 0.311967 +vt 0.076794 0.311862 +vt 0.073864 0.322926 +vt 0.075629 0.322959 +vt 0.072294 0.334336 +vt 0.074053 0.334301 +vt 0.316160 0.464504 +vt 0.638681 0.443431 +vt 0.639014 0.443794 +vt 0.066016 0.408085 +vt 0.067722 0.408256 +vt 0.066783 0.399163 +vt 0.065078 0.399019 +vt 0.392983 0.411874 +vt 0.392644 0.411355 +vt 0.384413 0.410804 +vt 0.384512 0.411302 +vt 0.958557 0.820728 +vt 0.957820 0.822723 +vt 0.958734 0.829504 +vt 0.960285 0.828680 +vt 0.336532 0.516353 +vt 0.344295 0.524752 +vt 0.075632 0.388981 +vt 0.073895 0.389224 +vt 0.074649 0.398904 +vt 0.076386 0.398646 +vt 0.075588 0.408020 +vt 0.077323 0.407745 +vt 0.352752 0.532449 +vt 0.323609 0.499112 +vt 0.323126 0.499369 +vt 0.329114 0.507818 +vt 0.329563 0.507508 +vt 0.074352 0.369854 +vt 0.072613 0.370047 +vt 0.073192 0.379468 +vt 0.074930 0.379247 +vt 0.863129 0.362448 +vt 0.393314 0.412531 +vt 0.384596 0.411906 +vt 0.866368 0.310962 +vt 0.335907 0.429834 +vt 0.336307 0.430265 +vt 0.929465 0.295408 +vt 0.928673 0.295085 +vt 0.955178 0.387249 +vt 0.954357 0.377726 +vt 0.631652 0.452473 +vt 0.624233 0.460819 +vt 0.952859 0.333903 +vt 0.954286 0.322765 +vt 0.611379 0.503046 +vt 0.615019 0.514998 +vt 0.621599 0.527180 +vt 0.957093 0.311900 +vt 0.877854 0.296528 +vt 0.877689 0.306656 +vt 0.629992 0.537787 +vt 0.630405 0.537372 +vt 0.353870 0.531131 +vt 0.363007 0.538048 +vt 0.363371 0.537597 +vt 0.362663 0.538552 +vt 0.372767 0.544300 +vt 0.373083 0.543777 +vt 0.373430 0.543305 +vt 0.921844 0.343725 +vt 0.922502 0.351996 +vt 0.318508 0.482636 +vt 0.317918 0.482772 +vt 0.320042 0.490894 +vt 0.320610 0.490680 +vt 0.324145 0.498829 +vt 0.923302 0.360621 +vt 0.924339 0.369845 +vt 0.330061 0.507160 +vt 0.921297 0.335316 +vt 0.316362 0.474399 +vt 0.316962 0.474355 +vt 0.414311 0.274127 +vt 0.657320 0.430036 +vt 0.647836 0.436608 +vt 0.414548 0.265908 +vt 0.952535 0.343391 +vt 0.610463 0.493311 +vt 0.611042 0.493350 +vt 0.957093 0.405716 +vt 0.956049 0.396734 +vt 0.639418 0.444227 +vt 0.951726 0.844944 +vt 0.951564 0.858978 +vt 0.955181 0.857401 +vt 0.955351 0.843371 +vt 0.951337 0.872742 +vt 0.954959 0.871169 +vt 0.952329 0.825014 +vt 0.951751 0.832467 +vt 0.955232 0.830845 +vt 0.955030 0.822495 +vt 0.069879 0.323184 +vt 0.072810 0.312081 +vt 0.068317 0.334614 +vt 0.951364 0.885001 +vt 0.955000 0.883429 +vt 0.951843 0.895298 +vt 0.955493 0.893725 +vt 0.959080 0.891991 +vt 0.958590 0.881725 +vt 0.064080 0.353268 +vt 0.064351 0.361699 +vt 0.068289 0.361481 +vt 0.068026 0.353011 +vt 0.068670 0.370296 +vt 0.072239 0.361223 +vt 0.071984 0.352746 +vt 0.070711 0.399102 +vt 0.069956 0.389441 +vt 0.071650 0.408214 +vt 0.416084 0.296878 +vt 0.416208 0.299729 +vt 0.419974 0.300016 +vt 0.420020 0.297160 +vt 0.417007 0.300462 +vt 0.419954 0.300762 +vt 0.420416 0.273435 +vt 0.420657 0.265108 +vt 0.420256 0.282388 +vt 0.424185 0.282759 +vt 0.424351 0.273776 +vt 0.424594 0.265438 +vt 0.069252 0.379704 +vt 0.063922 0.344691 +vt 0.067876 0.344389 +vt 0.071843 0.344112 +vt 0.317388 0.482905 +vt 0.319532 0.491092 +vt 0.073731 0.352620 +vt 0.073981 0.361063 +vt 0.640538 0.546299 +vt 0.652967 0.552363 +vt 0.949710 0.873303 +vt 0.949960 0.859589 +vt 0.950138 0.845602 +vt 0.665923 0.555889 +vt 0.862496 0.409570 +vt 0.862607 0.413340 +vt 0.419929 0.301096 +vt 0.416173 0.300626 +vt 0.862910 0.417100 +vt 0.315822 0.474455 +vt 0.073596 0.344026 +vt 0.611548 0.484920 +vt 0.609984 0.493293 +vt 0.062368 0.353368 +vt 0.062209 0.344852 +vt 0.683298 0.413803 +vt 0.676255 0.417817 +vt 0.414342 0.296936 +vt 0.416181 0.290615 +vt 0.414438 0.290685 +vt 0.931527 0.641564 +vt 0.930861 0.636782 +vt 0.951539 0.823633 +vt 0.954962 0.819194 +vt 0.931527 0.633969 +vt 0.613696 0.476796 +vt 0.062643 0.361744 +vt 0.335539 0.429483 +vt 0.960106 0.880827 +vt 0.960575 0.891037 +vt 0.362347 0.538993 +vt 0.076829 0.416217 +vt 0.078560 0.415917 +vt 0.426056 0.274125 +vt 0.425887 0.283109 +vt 0.372474 0.544760 +vt 0.629658 0.538156 +vt 0.950165 0.895779 +vt 0.949711 0.885518 +vt 0.677916 0.556686 +vt 0.950228 0.832925 +vt 0.686414 0.556245 +vt 0.199235 0.075474 +vt 0.200963 0.075195 +vt 0.734753 0.165663 +vt 0.735957 0.165455 +vt 0.671860 0.123963 +vt 0.670774 0.124375 +vt 0.667139 0.124655 +vt 0.663264 0.124665 +vt 0.191728 0.075368 +vt 0.195362 0.075534 +vt 0.661536 0.124358 +vt 0.215251 0.126405 +vt 0.214102 0.126211 +vt 0.190637 0.075043 +vt 0.926214 0.334912 +vt 0.926260 0.325653 +vt 0.926711 0.343120 +vt 0.003065 0.496902 +vt 0.006543 0.504351 +vt 0.000975 0.487674 +vt 0.777819 0.183862 +vt 0.777898 0.192836 +vt 0.436353 0.479286 +vt 0.439680 0.472192 +vt 0.439057 0.471838 +vt 0.435699 0.479000 +vt 0.433716 0.487860 +vt 0.015248 0.518838 +vt 0.022957 0.525368 +vt 0.023463 0.524823 +vt 0.015815 0.518341 +vt 0.032065 0.531657 +vt 0.032501 0.531068 +vt 0.448625 0.458865 +vt 0.456086 0.452706 +vt 0.455607 0.452190 +vt 0.448084 0.458397 +vt 0.464927 0.446779 +vt 0.464520 0.446221 +vt 0.483803 0.435904 +vt 0.494408 0.431935 +vt 0.494150 0.431284 +vt 0.483519 0.435272 +vt 0.505412 0.428683 +vt 0.505161 0.428021 +vt 0.051446 0.543026 +vt 0.062244 0.546872 +vt 0.062533 0.546189 +vt 0.051760 0.542363 +vt 0.073411 0.549833 +vt 0.073692 0.549140 +vt 0.091850 0.554454 +vt 0.095458 0.555358 +vt 0.095728 0.554645 +vt 0.092122 0.553744 +vt 0.096599 0.555644 +vt 0.096869 0.554930 +vt 0.523591 0.423541 +vt 0.527148 0.422534 +vt 0.526906 0.421851 +vt 0.523348 0.422861 +vt 0.528273 0.422216 +vt 0.528032 0.421532 +vt 0.425350 0.306484 +vt 0.424952 0.312142 +vt 0.583422 0.023868 +vt 0.582507 0.029909 +vt 0.583709 0.022642 +vt 0.896860 0.956451 +vt 0.896104 0.957782 +vt 0.896827 0.950720 +vt 0.215207 0.227250 +vt 0.214276 0.221273 +vt 0.215364 0.228641 +vt 0.643135 0.002001 +vt 0.642818 0.002828 +vt 0.227960 0.021610 +vt 0.980801 0.077684 +vt 0.499514 0.016372 +vt 0.499954 0.015660 +vt 0.217501 0.004336 +vt 0.215546 0.004770 +vt 0.151213 0.016264 +vt 0.151551 0.014280 +vt 0.270819 0.005517 +vt 0.266526 0.006397 +vt 0.985068 0.083863 +vt 0.985068 0.088218 +vt 0.221837 0.004744 +vt 0.151747 0.009907 +vt 0.673015 0.164102 +vt 0.672724 0.163873 +vt 0.640918 0.016556 +vt 0.640971 0.015951 +vt 0.640996 0.015604 +vt 0.426544 0.364388 +vt 0.425816 0.361074 +vt 0.503879 0.002778 +vt 0.503454 0.003420 +vt 0.582397 0.080451 +vt 0.583023 0.083763 +vt 0.504410 0.002028 +vt 0.264722 0.007310 +vt 0.984761 0.090104 +vt 0.640659 0.017399 +vt 0.277200 0.020519 +vt 0.147547 0.003766 +vt 0.897547 0.909929 +vt 0.896712 0.922796 +vt 0.898361 0.901521 +vt 0.212432 0.179549 +vt 0.214338 0.171333 +vt 0.211314 0.192427 +vt 0.424834 0.352680 +vt 0.424189 0.339843 +vt 0.580703 0.072163 +vt 0.579648 0.059155 +vt 0.898394 0.898138 +vt 0.500280 0.015179 +vt 0.501369 0.015588 +vt 0.215364 0.168078 +vt 0.642528 0.003495 +vt 0.642357 0.003834 +vt 0.544485 0.032764 +vt 0.544150 0.029846 +vt 0.543063 0.034206 +vt 0.417091 0.098073 +vt 0.418835 0.098235 +vt 0.413110 0.097462 +vt 0.439237 0.773938 +vt 0.436167 0.773720 +vt 0.860343 0.483407 +vt 0.862203 0.482879 +vt 0.856291 0.484089 +vt 0.539348 0.034905 +vt 0.535260 0.035519 +vt 0.539284 0.035581 +vt 0.543165 0.034845 +vt 0.524502 0.553054 +vt 0.527702 0.551701 +vt 0.527463 0.551068 +vt 0.524226 0.552414 +vt 0.529347 0.550883 +vt 0.529515 0.550221 +vt 0.349603 0.016006 +vt 0.349533 0.014102 +vt 0.348895 0.016036 +vt 0.027382 0.022143 +vt 0.027463 0.018757 +vt 0.026806 0.023996 +vt 0.027501 0.024017 +vt 0.028112 0.022105 +vt 0.028199 0.018705 +vt 0.027463 0.013955 +vt 0.028199 0.013904 +vt 0.859937 0.395338 +vt 0.860283 0.397179 +vt 0.859558 0.392107 +vt 0.083682 0.418682 +vt 0.080205 0.418633 +vt 0.514200 0.553647 +vt 0.514287 0.554256 +vt 0.848845 0.785327 +vt 0.849252 0.782276 +vt 0.510919 0.554336 +vt 0.092383 0.424488 +vt 0.095513 0.425746 +vt 0.095875 0.425121 +vt 0.092693 0.423815 +vt 0.097192 0.426359 +vt 0.097822 0.426017 +vt 0.529055 0.421976 +vt 0.528837 0.421310 +vt 0.800788 0.590039 +vt 0.529515 0.421181 +vt 0.097392 0.555828 +vt 0.097667 0.555142 +vt 0.430323 0.304691 +vt 0.098218 0.555381 +vt 0.098485 0.554563 +vt 0.474089 0.441004 +vt 0.473753 0.440406 +vt 0.443463 0.465412 +vt 0.442876 0.464999 +vt 0.927324 0.351212 +vt 0.009871 0.511906 +vt 0.010484 0.511464 +vt 0.041494 0.537764 +vt 0.041860 0.537134 +vt 0.778671 0.203425 +vt 0.780512 0.213956 +vt 0.434246 0.499430 +vt 0.437482 0.511974 +vt 0.927346 0.314857 +vt 0.929789 0.304318 +vt 0.001425 0.475624 +vt 0.004629 0.462640 +vt 0.451951 0.533128 +vt 0.443884 0.523163 +vt 0.443325 0.523475 +vt 0.451451 0.533513 +vt 0.784489 0.222120 +vt 0.783688 0.222594 +vt 0.848351 0.837524 +vt 0.847528 0.824213 +vt 0.849265 0.850828 +vt 0.461403 0.541945 +vt 0.472397 0.548117 +vt 0.860052 0.338396 +vt 0.858953 0.351774 +vt 0.028591 0.431546 +vt 0.018246 0.440312 +vt 0.018801 0.440651 +vt 0.029057 0.431963 +vt 0.040435 0.425503 +vt 0.009902 0.450613 +vt 0.010514 0.450880 +vt 0.932911 0.295490 +vt 0.933772 0.295955 +vt 0.858301 0.364309 +vt 0.858269 0.375619 +vt 0.052037 0.421788 +vt 0.063187 0.419968 +vt 0.848067 0.791810 +vt 0.847338 0.801067 +vt 0.504006 0.554015 +vt 0.494411 0.553204 +vt 0.847146 0.811966 +vt 0.483615 0.551580 +vt 0.858855 0.385296 +vt 0.073082 0.419028 +vt 0.088839 0.422300 +vt 0.088571 0.422986 +vt 0.520269 0.554001 +vt 0.520503 0.554655 +vt 0.543188 0.025145 +vt 0.542307 0.020659 +vt 0.674132 0.169955 +vt 0.674132 0.165508 +vt 0.672423 0.165945 +vt 0.672421 0.170425 +vt 0.406676 0.096494 +vt 0.400727 0.095843 +vt 0.541981 0.018133 +vt 0.542215 0.016004 +vt 0.397912 0.096236 +vt 0.396583 0.098028 +vt 0.099637 0.013574 +vt 0.099585 0.016338 +vt 0.100019 0.010767 +vt 0.840391 0.485136 +vt 0.843519 0.485697 +vt 0.838672 0.482843 +vt 0.100739 0.006260 +vt 0.431242 0.773720 +vt 0.849706 0.485077 +vt 0.099844 0.020866 +vt 0.100687 0.026319 +vt 0.836351 0.478490 +vt 0.834286 0.472376 +vt 0.959304 0.668833 +vt 0.959257 0.681288 +vt 0.959599 0.662751 +vt 0.393024 0.113915 +vt 0.392998 0.106567 +vt 0.396988 0.125975 +vt 0.542967 0.012464 +vt 0.544485 0.008048 +vt 0.394706 0.101447 +vt 0.959557 0.701414 +vt 0.959914 0.719985 +vt 0.405799 0.143645 +vt 0.414531 0.159490 +vt 0.965419 0.563200 +vt 0.965631 0.544344 +vt 0.965332 0.583673 +vt 0.847167 0.433878 +vt 0.838186 0.451886 +vt 0.856066 0.417684 +vt 0.965487 0.596616 +vt 0.965754 0.603415 +vt 0.834174 0.464356 +vt 0.960019 0.728230 +vt 0.959866 0.729703 +vt 0.418412 0.166499 +vt 0.419114 0.167676 +vt 0.896582 0.938098 +vt 0.212411 0.208147 +vt 0.859268 0.408858 +vt 0.859062 0.410075 +vt 0.859752 0.410745 +vt 0.860254 0.409473 +vt 0.965754 0.536346 +vt 0.424399 0.324647 +vt 0.580709 0.043228 +vt 0.411358 0.303623 +vt 0.798821 0.587652 +vt 0.799025 0.589278 +vt 0.798686 0.585879 +vt 0.428791 0.112091 +vt 0.428675 0.113877 +vt 0.515834 0.425735 +vt 0.515588 0.425062 +vt 0.515314 0.424221 +vt 0.083983 0.552482 +vt 0.084258 0.551780 +vt 0.084523 0.550935 +vt 0.415968 0.300942 +vt 0.414535 0.299790 +vt 0.414262 0.300094 +vt 0.686741 0.412433 +vt 0.686510 0.412005 +vt 0.420120 0.290871 +vt 0.424044 0.291274 +vt 0.382050 0.550040 +vt 0.382334 0.549572 +vt 0.425742 0.291634 +vt 0.382639 0.549040 +vt 0.382982 0.548555 +vt 0.428142 0.302279 +vt 0.429797 0.302630 +vt 0.894419 0.960034 +vt 0.892565 0.960371 +vt 0.833929 0.822734 +vt 0.837309 0.820735 +vt 0.834994 0.825373 +vt 0.837640 0.824910 +vt 0.840534 0.827502 +vt 0.841230 0.825531 +vt 0.084762 0.550116 +vt 0.913371 0.968828 +vt 0.912583 0.968486 +vt 0.515054 0.423396 +vt 0.409138 0.292055 +vt 0.409918 0.291684 +vt 0.409278 0.283719 +vt 0.411595 0.291627 +vt 0.910837 0.968419 +vt 0.908895 0.968347 +vt 0.414107 0.300469 +vt 0.687031 0.412948 +vt 0.835514 0.782890 +vt 0.834354 0.786997 +vt 0.837753 0.788279 +vt 0.838426 0.782983 +vt 0.834430 0.791527 +vt 0.837103 0.793517 +vt 0.834963 0.832062 +vt 0.838341 0.833353 +vt 0.841711 0.834673 +vt 0.791902 0.173503 +vt 0.792688 0.169727 +vt 0.789077 0.169428 +vt 0.788909 0.174089 +vt 0.792181 0.165833 +vt 0.789254 0.164751 +vt 0.786269 0.165339 +vt 0.785475 0.169112 +vt 0.785982 0.172989 +vt 0.789400 0.203722 +vt 0.785765 0.203411 +vt 0.793121 0.140074 +vt 0.793927 0.135702 +vt 0.790316 0.135543 +vt 0.790127 0.140889 +vt 0.793440 0.131212 +vt 0.790513 0.130103 +vt 0.787521 0.130888 +vt 0.786713 0.135289 +vt 0.787206 0.139720 +vt 0.905418 0.972693 +vt 0.906068 0.968059 +vt 0.902466 0.968275 +vt 0.902462 0.973876 +vt 0.905433 0.963565 +vt 0.902483 0.962768 +vt 0.899537 0.964013 +vt 0.898877 0.968585 +vt 0.899517 0.973108 +vt 0.794013 0.141555 +vt 0.790039 0.143504 +vt 0.786223 0.141078 +vt 0.792804 0.174895 +vt 0.788833 0.176444 +vt 0.785004 0.174209 +vt 0.833413 0.792696 +vt 0.832767 0.786373 +vt 0.834812 0.781206 +vt 0.785394 0.163893 +vt 0.789356 0.162310 +vt 0.793178 0.164536 +vt 0.898600 0.998986 +vt 0.902463 0.997150 +vt 0.786652 0.129248 +vt 0.790631 0.127298 +vt 0.794448 0.129666 +vt 0.906395 0.998593 +vt 0.838754 0.780522 +vt 0.906385 0.962235 +vt 0.907791 0.968103 +vt 0.906367 0.974330 +vt 0.902476 0.976850 +vt 0.898594 0.974864 +vt 0.922650 0.418051 +vt 0.923695 0.416860 +vt 0.922132 0.412969 +vt 0.921384 0.412964 +vt 0.898622 0.962837 +vt 0.902507 0.960385 +vt 0.923695 0.409072 +vt 0.922666 0.407871 +vt 0.783778 0.168940 +vt 0.843300 0.835331 +vt 0.897192 0.968879 +vt 0.794410 0.169846 +vt 0.795649 0.135680 +vt 0.833352 0.831482 +vt 0.785015 0.135071 +vt 0.836842 0.796223 +vt 0.784061 0.203353 +vn -0.0045 0.4325 0.9016 +vn 0.0630 0.4213 0.9047 +vn 0.0781 0.4597 0.8846 +vn 0.0149 0.4636 0.8859 +vn 0.3893 0.3278 0.8608 +vn 0.3904 0.3608 0.8470 +vn 0.3927 0.3827 0.8363 +vn 0.1082 0.4913 0.8642 +vn 0.1076 0.4257 0.8984 +vn 0.0194 -0.0663 -0.9976 +vn 0.0136 -0.0659 -0.9977 +vn 0.0133 -0.0691 -0.9975 +vn 0.0192 -0.0698 -0.9974 +vn 0.0078 -0.0654 -0.9978 +vn 0.0076 -0.0685 -0.9976 +vn 0.0098 -0.1016 -0.9948 +vn 0.0131 -0.0968 -0.9952 +vn 0.0161 -0.1025 -0.9946 +vn -0.3868 0.5584 -0.7339 +vn -0.1886 0.5979 -0.7791 +vn -0.1862 0.6982 -0.6913 +vn -0.3900 0.6474 -0.6548 +vn -0.4495 0.5403 -0.7113 +vn -0.4347 0.6324 -0.6411 +vn -0.4159 0.7610 -0.4979 +vn -0.1747 0.8371 -0.5185 +vn -0.3808 0.7748 -0.5046 +vn -0.0198 0.0586 0.9981 +vn -0.0143 0.0586 0.9982 +vn -0.0142 0.0743 0.9971 +vn -0.0196 0.0744 0.9970 +vn -0.0089 0.0585 0.9982 +vn -0.0088 0.0742 0.9972 +vn -0.0086 0.1186 0.9929 +vn -0.0139 0.1187 0.9928 +vn -0.0194 0.1187 0.9927 +vn 0.4479 -0.0774 -0.8907 +vn 0.4607 -0.1432 -0.8759 +vn 0.0867 -0.1147 -0.9896 +vn 0.0892 -0.0686 -0.9936 +vn 0.4608 -0.1432 -0.8759 +vn 0.4083 -0.3601 -0.8388 +vn 0.1256 -0.4280 -0.8950 +vn 0.0215 -0.4082 -0.9126 +vn 0.0194 -0.1160 -0.9931 +vn -0.0187 0.4338 0.9008 +vn -0.0863 0.4456 0.8910 +vn -0.0888 0.2922 0.9522 +vn -0.0187 0.2839 0.9587 +vn -0.4316 0.4667 0.7720 +vn -0.4402 0.3112 0.8422 +vn -0.4460 0.1383 0.8843 +vn -0.0890 0.1233 0.9884 +vn 0.0022 -0.5844 0.8115 +vn -0.0490 -0.6064 0.7937 +vn -0.0402 -0.5227 0.8516 +vn 0.0376 -0.5294 0.8476 +vn -0.3892 -0.5696 0.7240 +vn -0.3931 -0.4835 0.7821 +vn -0.3922 -0.3300 0.8586 +vn -0.0205 -0.3523 0.9357 +vn 0.0927 -0.3278 0.9402 +vn 0.0866 -0.1167 -0.9894 +vn 0.0892 -0.0736 -0.9933 +vn 0.0867 -0.1167 -0.9894 +vn 0.4498 -0.1393 -0.8822 +vn 0.4477 -0.0853 -0.8901 +vn -0.0123 0.4628 0.8864 +vn -0.0118 0.4322 0.9017 +vn -0.0168 0.4322 0.9016 +vn -0.1268 0.4933 0.8606 +vn -0.0366 0.4738 0.8799 +vn -0.0829 -0.8294 0.5525 +vn -0.0885 -0.9220 0.3770 +vn 0.0191 -0.8748 0.4841 +vn 0.0237 -0.7532 0.6574 +vn 0.0633 -0.9480 0.3119 +vn 0.0104 -0.9532 0.3021 +vn -0.0403 -0.9534 0.2989 +vn 0.0935 -0.9153 0.3917 +vn 0.1264 -0.8123 0.5693 +vn -0.3551 0.9167 -0.1834 +vn -0.8260 0.5035 -0.2534 +vn -0.8427 0.4562 -0.2860 +vn -0.3647 0.8668 -0.3401 +vn -0.9213 0.2997 -0.2479 +vn -0.9397 0.2533 -0.2298 +vn -0.8426 0.4562 -0.2860 +vn -0.9495 0.2170 -0.2265 +vn -0.8585 0.3931 -0.3293 +vn -0.3649 0.1277 -0.9223 +vn -0.8437 0.0666 -0.5326 +vn -0.8443 0.0411 -0.5342 +vn -0.3598 0.0770 -0.9299 +vn -0.9543 0.0317 -0.2973 +vn -0.9521 0.0216 -0.3049 +vn -0.9509 0.0016 -0.3094 +vn -0.8468 -0.0058 -0.5319 +vn -0.3595 -0.0231 -0.9328 +vn -0.0106 -0.5020 -0.8648 +vn 0.0452 -0.6035 -0.7960 +vn 0.0109 -0.5823 -0.8129 +vn 0.0075 -0.5193 -0.8545 +vn 0.0920 -0.7482 -0.6571 +vn 0.0033 -0.6517 -0.7585 +vn -0.0993 -0.6817 -0.7248 +vn -0.0430 -0.5744 -0.8175 +vn 0.0195 -0.5116 -0.8590 +vn -0.5284 -0.8365 0.1454 +vn -0.1654 -0.9729 0.1619 +vn -0.1552 -0.9842 -0.0848 +vn -0.3496 -0.8900 -0.2927 +vn -0.4656 -0.8702 0.1613 +vn -0.4653 -0.8737 -0.1421 +vn -0.1552 -0.9842 -0.0849 +vn -0.4654 -0.8736 -0.1421 +vn -0.3036 -0.7656 -0.5672 +vn -0.1314 -0.7716 -0.6224 +vn -0.1511 -0.5404 -0.8278 +vn -0.1167 -0.9928 0.0265 +vn 0.0222 -0.9941 0.1059 +vn 0.0173 -0.9933 -0.1141 +vn -0.0940 -0.9824 -0.1614 +vn 0.3907 -0.8994 0.1961 +vn 0.3862 -0.9218 0.0344 +vn 0.3892 -0.9124 -0.1262 +vn 0.0247 -0.9517 -0.3061 +vn -0.0931 -0.9352 -0.3416 +vn 0.0614 -0.4804 -0.8749 +vn 0.1143 -0.5601 -0.8205 +vn 0.1427 -0.5037 -0.8520 +vn 0.0840 -0.4969 -0.8637 +vn 0.0800 -0.5210 -0.8498 +vn 0.0889 -0.4890 -0.8677 +vn 0.0769 -0.4536 -0.8879 +vn 0.0720 -0.4678 -0.8809 +vn -0.0347 -0.4546 -0.8900 +vn -0.0755 -0.4223 -0.9033 +vn -0.0853 -0.4599 -0.8839 +vn -0.0765 -0.4641 -0.8825 +vn -0.3941 -0.3201 -0.8615 +vn -0.3944 -0.3511 -0.8492 +vn -0.3911 -0.3696 -0.8429 +vn -0.0750 -0.4964 -0.8649 +vn 0.0638 -0.5772 0.8141 +vn 0.1151 -0.5927 0.7972 +vn 0.0803 -0.6954 0.7141 +vn -0.0160 -0.6767 0.7361 +vn 0.4481 -0.5290 0.7207 +vn 0.4426 -0.6182 0.6495 +vn 0.4242 -0.7508 0.5062 +vn 0.0492 -0.8517 0.5216 +vn 0.3556 0.8284 0.4328 +vn 0.7924 0.3849 0.4733 +vn 0.7869 0.2720 0.5539 +vn 0.3555 0.7222 0.5933 +vn 0.7923 0.3849 0.4733 +vn 0.8860 0.1782 0.4281 +vn 0.8776 0.0783 0.4730 +vn 0.8749 -0.0108 0.4842 +vn 0.7834 0.1617 0.6002 +vn 0.7834 0.1617 0.6001 +vn 0.3525 0.5896 0.7267 +vn 0.1683 0.9106 0.3775 +vn 0.1662 0.9711 0.1713 +vn 0.3539 0.9069 0.2286 +vn 0.4396 0.7800 0.4454 +vn 0.4464 0.8592 0.2501 +vn 0.4360 0.8998 0.0152 +vn 0.1557 0.9859 -0.0609 +vn 0.3461 0.9382 -0.0099 +vn -0.3481 0.7895 0.5055 +vn -0.7875 0.6092 0.0930 +vn -0.7752 0.6309 -0.0324 +vn -0.3357 0.8804 0.3351 +vn -0.7876 0.6092 0.0930 +vn -0.8828 0.4646 -0.0698 +vn -0.8714 0.4627 -0.1632 +vn -0.7752 0.6308 -0.0324 +vn -0.8803 0.4167 -0.2269 +vn -0.7844 0.6057 -0.1336 +vn -0.7844 0.6058 -0.1336 +vn -0.3377 0.9264 0.1666 +vn 0.0707 -0.9616 -0.2653 +vn 0.0715 -0.9928 -0.0965 +vn -0.0104 -0.9912 -0.1322 +vn -0.0137 -0.9729 -0.2306 +vn 0.0971 -0.9901 0.1014 +vn -0.0111 -0.9995 -0.0285 +vn 0.0985 -0.9620 0.2548 +vn -0.0198 -0.9905 0.1361 +vn -0.0360 -0.9469 0.3194 +vn 0.0103 -0.9451 0.3267 +vn 0.0584 -0.9413 0.3324 +vn -0.1301 -0.9674 0.2174 +vn -0.1031 -0.8763 -0.4707 +vn -0.0042 -0.9309 -0.3653 +vn 0.0428 -0.8739 -0.4843 +vn -0.0115 -0.8604 -0.5096 +vn -0.0605 -0.8483 -0.5261 +vn 0.0596 -0.9037 -0.4239 +vn 0.0596 0.0566 0.9966 +vn 0.0593 0.0711 0.9957 +vn 0.3939 0.0394 0.9183 +vn 0.3900 0.0502 0.9194 +vn 0.3833 0.0798 0.9202 +vn 0.0586 0.1137 0.9918 +vn 0.5154 -0.8516 0.0961 +vn 0.1749 -0.9740 0.1441 +vn 0.1737 -0.9049 0.3885 +vn 0.4573 -0.6838 0.5686 +vn 0.4581 -0.8815 0.1144 +vn 0.4659 -0.7877 0.4029 +vn 0.3116 -0.5341 0.7859 +vn 0.1534 -0.4929 0.8565 +vn 0.1993 0.0457 0.9789 +vn -0.1508 0.9792 -0.1359 +vn -0.1458 0.9868 0.0700 +vn -0.3459 0.9382 -0.0090 +vn -0.3842 0.9053 -0.1812 +vn -0.3844 0.9231 -0.0133 +vn -0.3894 0.9090 0.1486 +vn -0.1436 0.9537 0.2642 +vn -0.0511 -0.5860 -0.8087 +vn -0.3887 -0.4299 -0.8149 +vn -0.3960 -0.5478 -0.7369 +vn -0.0349 -0.7294 -0.6832 +vn -0.0090 -0.0111 0.9999 +vn 0.0564 -0.0091 0.9984 +vn -0.0053 -0.3211 0.9470 +vn 0.0942 -0.3369 0.9368 +vn 0.0564 -0.0092 0.9984 +vn 0.3608 -0.2707 0.8925 +vn 0.4083 -0.0427 0.9119 +vn 0.7263 0.0866 0.6819 +vn 0.2989 0.4696 0.8308 +vn 0.8467 -0.1165 0.5191 +vn 0.7262 0.0866 0.6820 +vn 0.6445 -0.2738 0.7139 +vn 0.4883 0.0370 0.8719 +vn 0.4883 0.0369 0.8719 +vn 0.1175 -0.5350 -0.8366 +vn -0.0108 -0.3939 -0.9191 +vn -0.0336 -0.3956 -0.9178 +vn -0.0248 -0.7328 -0.6799 +vn 0.0887 -0.5405 -0.8367 +vn -0.0340 -0.4166 -0.9085 +vn -0.0569 -0.3978 -0.9157 +vn -0.1761 -0.5311 -0.8288 +vn 0.0429 -0.1061 0.9934 +vn 0.0941 -0.1215 0.9881 +vn 0.0792 -0.1806 0.9804 +vn -0.0043 -0.1686 0.9857 +vn 0.4286 -0.1082 0.8970 +vn 0.4366 -0.1627 0.8848 +vn 0.4501 -0.2950 0.8429 +vn 0.0704 -0.3367 0.9390 +vn -0.0443 -0.3231 0.9453 +vn 0.3258 -0.1874 -0.9267 +vn 0.8197 -0.1545 -0.5515 +vn 0.8297 -0.1267 -0.5436 +vn 0.3410 -0.1781 -0.9230 +vn 0.8197 -0.1546 -0.5516 +vn 0.9451 -0.1195 -0.3042 +vn 0.9476 -0.0882 -0.3071 +vn 0.9492 -0.0845 -0.3032 +vn 0.8338 -0.1217 -0.5385 +vn 0.8337 -0.1217 -0.5386 +vn 0.3504 -0.1718 -0.9207 +vn 0.0738 -0.9411 0.3299 +vn 0.1324 -0.9352 0.3283 +vn -0.0446 -0.9500 0.3092 +vn -0.9990 0.0260 0.0352 +vn -0.9990 0.0431 0.0087 +vn -0.7105 0.3719 0.5973 +vn -0.7024 0.3340 0.6285 +vn -0.9967 0.0689 -0.0438 +vn -0.7234 0.4544 0.5198 +vn -0.7235 0.4544 0.5198 +vn -0.1698 0.5903 0.7891 +vn -0.1632 0.4959 0.8529 +vn -0.7025 0.3340 0.6285 +vn -0.1627 0.4564 0.8747 +vn 0.0280 0.1754 0.9841 +vn 0.0177 0.1132 0.9934 +vn 0.0366 0.1467 0.9885 +vn 0.0353 0.1731 0.9843 +vn -0.1216 0.0670 0.9903 +vn 0.0368 0.2481 0.9680 +vn 0.0557 0.1014 0.9933 +vn 0.0425 0.1647 0.9854 +vn -0.0439 -0.9390 -0.3411 +vn -0.0324 -0.9907 -0.1320 +vn -0.4203 -0.7825 -0.4593 +vn -0.4216 -0.8691 -0.2588 +vn -0.4085 -0.9126 -0.0170 +vn -0.0206 -0.9955 0.0929 +vn -0.1510 0.7774 0.6106 +vn -0.1453 0.6443 0.7508 +vn -0.3388 0.6493 0.6809 +vn -0.4137 0.7798 0.4699 +vn -0.4308 0.6676 0.6073 +vn -0.4384 0.5765 0.6896 +vn -0.1238 0.5459 0.8286 +vn -0.9449 -0.2287 0.2343 +vn -0.9419 0.1845 -0.2809 +vn -0.7597 0.6362 0.1347 +vn -0.6777 0.0970 0.7289 +vn -0.9288 0.1597 -0.3345 +vn -0.7477 0.6562 0.1011 +vn -0.7478 0.6562 0.1011 +vn -0.2489 0.8426 0.4776 +vn -0.2566 0.8176 0.5154 +vn -0.6778 0.0969 0.7289 +vn -0.2104 0.2786 0.9371 +vn 0.9982 -0.0505 -0.0325 +vn 0.9984 -0.0540 -0.0154 +vn 0.7052 -0.3705 -0.6044 +vn 0.6985 -0.3440 -0.6275 +vn 0.9960 -0.0860 0.0257 +vn 0.7115 -0.4548 -0.5357 +vn 0.7052 -0.3705 -0.6045 +vn 0.1730 -0.5861 -0.7916 +vn 0.1647 -0.4898 -0.8562 +vn 0.6985 -0.3440 -0.6274 +vn 0.1622 -0.4533 -0.8765 +vn -0.0423 -0.4905 -0.8704 +vn -0.0386 -0.4554 -0.8895 +vn -0.0381 -0.5800 -0.8137 +vn -0.2401 -0.5495 -0.8002 +vn -0.2441 -0.4712 -0.8476 +vn -0.2387 -0.4434 -0.8639 +vn 0.0424 0.4947 0.8680 +vn 0.0388 0.4586 0.8878 +vn 0.0392 0.5846 0.8104 +vn 0.2486 0.5522 0.7957 +vn 0.2481 0.4714 0.8463 +vn 0.2410 0.4386 0.8658 +vn 0.3648 -0.8662 -0.3416 +vn 0.2584 -0.8612 -0.4377 +vn 0.0446 -0.8467 -0.5302 +vn 0.0307 -0.8440 -0.5355 +vn 0.2434 -0.9010 -0.3592 +vn 0.0514 -0.8953 -0.4426 +vn -0.1330 -0.8531 -0.5044 +vn -0.1665 -0.7871 -0.5940 +vn -0.2999 -0.7490 -0.5908 +vn 0.5793 -0.4331 0.6906 +vn 0.9034 -0.1243 0.4105 +vn 0.8814 -0.4573 0.1187 +vn 0.7547 -0.6501 0.0889 +vn 0.9235 -0.0870 0.3736 +vn 0.8113 -0.5846 -0.0001 +vn 0.3647 -0.8662 -0.3417 +vn 0.7000 -0.6341 -0.3285 +vn 0.5480 -0.3880 -0.7411 +vn 0.2983 -0.1911 -0.9351 +vn 0.0226 -0.1945 -0.9806 +vn 0.0213 -0.2642 -0.9642 +vn 0.3014 -0.4344 -0.8488 +vn 0.0169 -0.4102 -0.9118 +vn -0.2072 -0.4040 -0.8910 +vn -0.1836 -0.2022 -0.9620 +vn -0.3782 -0.3236 -0.8673 +vn -0.0207 0.7882 0.6151 +vn -0.0237 0.2333 0.9721 +vn -0.0298 0.8227 0.5677 +vn 0.1808 0.7637 0.6197 +vn 0.2040 0.7159 0.6677 +vn 0.1511 0.0929 0.9841 +vn -0.9168 0.0371 -0.3977 +vn -0.9247 -0.0209 -0.3802 +vn -0.7381 0.6595 -0.1424 +vn -0.7520 0.6592 0.0041 +vn -0.9493 -0.0536 -0.3097 +vn -0.7068 0.6447 -0.2912 +vn -0.7381 0.6595 -0.1423 +vn -0.1837 0.9751 -0.1247 +vn -0.2251 0.9610 0.1604 +vn -0.7520 0.6592 0.0042 +vn -0.2482 0.8952 0.3702 +vn -0.2504 0.8545 0.4551 +vn -0.0465 0.8405 0.5398 +vn -0.0539 0.8897 0.4534 +vn 0.1331 0.8485 0.5122 +vn 0.1496 0.7909 0.5934 +vn -0.9227 0.0985 -0.3727 +vn -0.7515 0.6550 0.0786 +vn 0.9242 -0.0763 0.3741 +vn 0.7700 -0.6355 -0.0570 +vn 0.9251 -0.0548 0.3757 +vn 0.7378 -0.6741 -0.0334 +vn 0.8113 -0.5846 -0.0000 +vn 0.9461 -0.0013 0.3237 +vn 0.9650 0.0394 0.2593 +vn 0.6462 -0.6393 0.4168 +vn 0.6560 -0.6995 0.2834 +vn 0.9812 0.0510 0.1860 +vn 0.6496 -0.5913 0.4778 +vn 0.6496 -0.5913 0.4779 +vn 0.1460 -0.8388 0.5246 +vn 0.1453 -0.9102 0.3879 +vn 0.1690 -0.9727 0.1588 +vn 0.9321 -0.0326 0.3607 +vn 0.6980 -0.7099 0.0936 +vn 0.2143 -0.9662 -0.1435 +vn 0.0286 -0.9756 -0.2177 +vn -0.0113 -0.9948 0.1011 +vn -0.1942 -0.9803 0.0372 +vn -0.1546 -0.9469 -0.2819 +vn -0.0333 0.9700 0.2410 +vn 0.0041 0.9981 -0.0618 +vn 0.1877 0.9822 -0.0009 +vn 0.1522 0.9392 0.3077 +vn 0.1638 -0.5601 0.8121 +vn -0.0183 -0.5847 0.8111 +vn -0.0219 -0.8680 0.4961 +vn 0.1773 -0.1350 0.9748 +vn -0.0157 -0.1392 0.9901 +vn -0.2171 -0.1349 0.9668 +vn -0.2114 -0.5847 0.7832 +vn -0.1918 -0.8731 0.4483 +vn -0.0284 -0.9386 0.3438 +vn -0.2040 -0.9363 0.2858 +vn -0.1837 0.9750 -0.1247 +vn -0.1563 0.9329 -0.3244 +vn 0.0211 0.9571 -0.2889 +vn -0.1509 0.8853 -0.4398 +vn 0.0170 0.9066 -0.4217 +vn 0.1842 0.8973 -0.4011 +vn 0.1970 0.9482 -0.2492 +vn -0.9702 -0.0612 -0.2345 +vn -0.6806 0.6260 -0.3807 +vn -0.9835 -0.0662 -0.1687 +vn -0.6772 0.5976 -0.4293 +vn -0.9983 0.0126 -0.0565 +vn -0.9971 0.0158 -0.0748 +vn -0.6998 -0.0144 -0.7142 +vn -0.7112 0.0806 -0.6983 +vn -0.9959 0.0409 -0.0811 +vn -0.7046 -0.0109 -0.7095 +vn -0.1898 -0.0517 -0.9805 +vn -0.1848 -0.0371 -0.9821 +vn -0.1831 0.0994 -0.9781 +vn -0.1872 0.5896 -0.7857 +vn 0.0135 0.6032 -0.7974 +vn 0.0146 0.0956 -0.9953 +vn 0.2187 0.0927 -0.9714 +vn 0.2141 0.5987 -0.7719 +vn -0.9949 -0.0803 -0.0610 +vn -0.7541 0.3421 -0.5607 +vn -0.7540 0.3421 -0.5607 +vn 0.9862 -0.0334 0.1619 +vn 0.6297 -0.4202 0.6534 +vn 0.9944 -0.0186 0.1044 +vn 0.6717 -0.1003 0.7340 +vn 0.6298 -0.4202 0.6534 +vn 0.6716 -0.1003 0.7341 +vn -0.2127 0.0636 -0.9750 +vn 0.0147 -0.0009 -0.9999 +vn 0.0146 -0.0602 -0.9981 +vn -0.1383 0.3819 -0.9138 +vn 0.0148 0.4132 -0.9105 +vn 0.1709 0.3862 -0.9064 +vn 0.2524 0.0654 -0.9654 +vn 0.2270 -0.0583 -0.9722 +vn 0.9963 -0.0168 0.0840 +vn 0.6931 0.0080 0.7208 +vn 0.9965 0.0178 0.0817 +vn 0.7037 0.0518 0.7087 +vn 0.7036 0.0518 0.7087 +vn 0.1899 0.0620 0.9798 +vn 0.1842 0.0233 0.9826 +vn -0.0146 0.0265 0.9995 +vn -0.0145 0.0629 0.9979 +vn -0.2267 0.0684 0.9716 +vn -0.2206 0.0303 0.9749 +vn 0.0148 -0.0431 -0.9990 +vn 0.2211 -0.0450 -0.9742 +vn 0.9960 -0.0402 0.0804 +vn 0.9137 -0.0674 -0.4007 +vn 0.9153 -0.0741 -0.3960 +vn 0.9950 -0.0415 0.0904 +vn 0.4498 -0.1394 -0.8822 +vn 0.9193 -0.1225 -0.3740 +vn 0.9916 -0.0694 0.1094 +vn -0.9971 0.0096 -0.0758 +vn -0.9121 0.0376 0.4083 +vn -0.9125 0.0693 0.4031 +vn -0.9953 0.0398 -0.0878 +vn -0.4456 0.0604 0.8932 +vn -0.4442 0.0843 0.8920 +vn -0.4459 0.1383 0.8843 +vn -0.9120 0.1160 0.3934 +vn -0.9925 0.0680 -0.1021 +vn -0.9761 0.1559 -0.1514 +vn -0.9684 0.1700 -0.1826 +vn -0.8344 -0.0631 -0.5475 +vn -0.8439 -0.0541 -0.5338 +vn -0.9530 0.2009 -0.2269 +vn -0.8214 -0.0503 -0.5681 +vn 0.9534 -0.1971 0.2284 +vn 0.9341 -0.2235 0.2786 +vn 0.8079 0.0811 0.5837 +vn 0.8207 0.0639 0.5678 +vn 0.9189 -0.2295 0.3208 +vn 0.8090 0.1384 0.5713 +vn 0.8079 0.0811 0.5838 +vn 0.8090 0.1385 0.5713 +vn 0.4096 0.5629 0.7178 +vn 0.3987 0.4462 0.8013 +vn 0.9760 -0.1526 0.1552 +vn 0.9686 -0.1681 0.1833 +vn 0.8350 0.0722 0.5454 +vn 0.8415 0.0673 0.5361 +vn 0.3928 0.3827 0.8362 +vn -0.9334 0.2315 -0.2743 +vn -0.8127 -0.0530 -0.5803 +vn -0.9180 0.2421 -0.3142 +vn -0.8151 -0.0961 -0.5713 +vn -0.8127 -0.0531 -0.5803 +vn -0.9207 0.1925 -0.3395 +vn -0.9393 0.1434 -0.3117 +vn -0.8746 -0.3273 -0.3577 +vn -0.8487 -0.2461 -0.4681 +vn -0.9640 0.0801 -0.2535 +vn -0.8907 -0.4096 -0.1974 +vn -0.8746 -0.3274 -0.3577 +vn -0.8487 -0.2462 -0.4681 +vn -0.9129 0.2268 -0.3394 +vn -0.8272 -0.1691 -0.5359 +vn -0.8272 -0.1692 -0.5359 +vn -0.4094 -0.6759 -0.6128 +vn 0.9143 -0.2123 0.3450 +vn 0.8232 0.2098 0.5275 +vn 0.9225 -0.1739 0.3445 +vn 0.8438 0.2877 0.4531 +vn 0.8232 0.2098 0.5276 +vn 0.8437 0.2877 0.4531 +vn 0.4254 0.6820 0.5949 +vn 0.9426 -0.1179 0.3125 +vn 0.8658 0.3750 0.3313 +vn 0.9682 -0.0501 0.2451 +vn 0.8776 0.4513 0.1613 +vn -0.9839 0.0190 -0.1778 +vn -0.8906 -0.4543 -0.0183 +vn -0.9940 -0.0121 -0.1085 +vn -0.8926 -0.4269 0.1453 +vn -0.8907 -0.4543 -0.0183 +vn -0.3890 -0.8106 0.4377 +vn -0.3945 -0.8934 0.2148 +vn 0.9866 0.0094 0.1628 +vn 0.8743 0.4851 -0.0155 +vn 0.9954 0.0405 0.0868 +vn 0.8690 0.4591 -0.1844 +vn 0.4049 0.8019 -0.4393 +vn 0.4148 0.8841 -0.2152 +vn -0.9996 -0.0119 0.0250 +vn -0.9999 -0.0031 0.0125 +vn -0.8823 -0.0408 0.4690 +vn -0.8731 -0.0763 0.4815 +vn -0.9999 0.0116 0.0049 +vn -0.8892 0.0249 0.4569 +vn -0.8891 0.0249 0.4569 +vn -0.4224 0.0336 0.9058 +vn -0.4171 -0.0768 0.9056 +vn -0.4046 -0.1322 0.9049 +vn -0.9997 -0.0216 -0.0074 +vn -0.9996 -0.0251 0.0118 +vn -0.8764 -0.2631 0.4033 +vn -0.8767 -0.3104 0.3674 +vn -0.9995 -0.0231 0.0237 +vn -0.8768 -0.1825 0.4449 +vn 0.9996 0.0284 -0.0086 +vn 0.9990 0.0327 -0.0320 +vn 0.8603 0.2657 -0.4350 +vn 0.8693 0.3079 -0.3866 +vn 0.9985 0.0280 -0.0471 +vn 0.8554 0.1825 -0.4847 +vn 0.8554 0.1825 -0.4848 +vn 0.3988 0.3157 -0.8610 +vn 0.3990 0.4685 -0.7882 +vn 0.8694 0.3079 -0.3865 +vn 0.4018 0.5563 -0.7273 +vn 0.9994 0.0124 -0.0310 +vn 0.9998 0.0040 -0.0210 +vn 0.8745 0.0376 -0.4835 +vn 0.8698 0.0692 -0.4885 +vn 0.9998 -0.0120 -0.0159 +vn 0.8772 -0.0236 -0.4796 +vn 0.4328 -0.0309 -0.9010 +vn 0.4263 0.0669 -0.9021 +vn 0.8698 0.0692 -0.4886 +vn 0.8745 0.0376 -0.4836 +vn 0.4162 0.1176 -0.9016 +vn -0.9984 -0.0212 0.0527 +vn -0.9044 -0.4119 0.1110 +vn -0.8142 -0.2935 0.5009 +vn -0.8690 0.0682 0.4901 +vn -0.4485 -0.7682 0.4570 +vn -0.2572 -0.5132 0.8188 +vn -0.4032 -0.0969 0.9099 +vn -0.8690 0.0681 0.4901 +vn -0.8143 -0.2935 0.5009 +vn -0.4032 -0.0969 0.9100 +vn -0.3925 0.1581 0.9061 +vn 0.9944 -0.0995 -0.0351 +vn 0.8851 -0.4646 0.0272 +vn 0.7946 -0.4830 -0.3677 +vn 0.8651 -0.1659 -0.4733 +vn 0.4581 -0.8815 0.1145 +vn 0.4362 -0.8815 -0.1809 +vn 0.7946 -0.4830 -0.3678 +vn 0.2509 -0.7662 -0.5916 +vn 0.3950 -0.4381 -0.8075 +vn 0.8651 -0.1659 -0.4734 +vn 0.3987 -0.2124 -0.8921 +vn -0.3688 -0.1611 -0.9154 +vn -0.1701 -0.1792 -0.9690 +vn -0.1598 -0.1345 -0.9779 +vn -0.3618 -0.1206 -0.9244 +vn -0.4495 -0.1549 -0.8797 +vn -0.4370 -0.1164 -0.8919 +vn -0.4279 -0.0222 -0.9035 +vn -0.1544 -0.0273 -0.9876 +vn -0.3617 -0.1206 -0.9244 +vn -0.1453 0.8863 0.4398 +vn -0.3980 0.8651 0.3054 +vn 0.3247 0.5750 -0.7510 +vn 0.1238 0.6002 -0.7902 +vn 0.1274 0.5053 -0.8535 +vn 0.3311 0.4835 -0.8103 +vn 0.1317 0.3391 -0.9315 +vn 0.3375 0.3251 -0.8834 +vn 0.1003 -0.4596 -0.8824 +vn 0.0867 -0.2934 -0.9520 +vn 0.0112 -0.2674 -0.9635 +vn 0.4437 -0.4785 -0.7577 +vn 0.4535 -0.3230 -0.8307 +vn 0.0738 -0.2517 -0.9650 +vn 0.0505 -0.3796 -0.9238 +vn 0.0831 -0.7685 -0.6344 +vn -0.0609 -0.0629 -0.9962 +vn -0.0605 -0.0646 -0.9961 +vn -0.3953 -0.0504 -0.9172 +vn -0.3898 -0.0433 -0.9199 +vn -0.3917 -0.0682 -0.9176 +vn -0.0598 -0.1026 -0.9929 +vn 0.1582 0.6949 0.7015 +vn 0.1645 0.8196 0.5488 +vn 0.0484 0.1967 0.9793 +vn 0.1010 0.1703 0.9802 +vn 0.0675 0.1324 0.9889 +vn -0.0160 0.1495 0.9886 +vn 0.4389 0.1396 0.8876 +vn 0.4268 0.1061 0.8981 +vn 0.4225 0.0224 0.9061 +vn 0.0533 0.0297 0.9981 +vn -0.0482 0.0421 0.9979 +vn -0.9850 -0.1611 -0.0614 +vn -0.9105 -0.1188 0.3960 +vn -0.7468 -0.6648 -0.0201 +vn -0.6864 -0.5790 0.4400 +vn -0.9106 -0.1188 0.3959 +vn -0.4072 -0.2757 0.8707 +vn -0.4601 -0.0379 0.8871 +vn -0.4601 -0.0378 0.8871 +vn 0.0286 -0.8741 -0.4849 +vn -0.1344 -0.8281 -0.5442 +vn 0.3993 -0.8713 -0.2854 +vn 0.4133 -0.7883 -0.4559 +vn 0.0276 -0.7553 -0.6548 +vn -0.1601 0.9319 -0.3254 +vn -0.3962 0.8539 -0.3373 +vn -0.0413 0.1752 0.9837 +vn -0.0455 0.0371 0.9983 +vn -0.0902 -0.4782 0.8736 +vn -0.1216 0.0669 0.9903 +vn -0.0427 -0.8551 -0.5167 +vn 0.1178 -0.8867 -0.4470 +vn 0.1416 0.9498 -0.2790 +vn 0.3365 0.9120 -0.2346 +vn 0.1313 0.8574 -0.4976 +vn 0.3319 0.8261 -0.4554 +vn -0.0887 0.0768 0.9931 +vn -0.0888 0.0601 0.9942 +vn 0.0391 -0.9497 0.3107 +vn -0.1423 -0.9498 0.2786 +vn 0.4024 -0.8475 0.3460 +vn -0.0269 -0.1161 0.9929 +vn -0.0773 -0.1381 0.9874 +vn -0.0774 -0.0856 0.9933 +vn -0.0219 -0.0906 0.9956 +vn -0.0602 0.0321 0.9977 +vn 0.0373 0.0414 0.9984 +vn 0.1402 0.5662 0.8123 +vn -0.0159 -0.9521 0.3055 +vn -0.0022 -0.8559 0.5171 +vn -0.1644 0.1388 -0.9766 +vn -0.1747 0.2008 -0.9639 +vn -0.3750 0.1852 -0.9083 +vn -0.4374 0.1250 -0.8905 +vn -0.4446 0.1811 -0.8772 +vn -0.4494 0.3134 -0.8366 +vn -0.1836 0.3467 -0.9199 +vn -0.3864 0.3214 -0.8645 +vn 0.0484 -0.6194 -0.7836 +vn 0.4264 -0.6731 -0.6043 +vn 0.4367 -0.5813 -0.6866 +vn 0.0839 -0.5420 -0.8362 +vn 0.3499 0.1233 -0.9286 +vn 0.1493 0.1264 -0.9807 +vn 0.1590 0.0733 -0.9846 +vn 0.3596 0.0711 -0.9304 +vn 0.1637 -0.0300 -0.9861 +vn 0.3641 -0.0307 -0.9309 +vn 0.1027 -0.5031 -0.8581 +vn 0.4422 -0.5276 -0.7254 +vn 0.9834 -0.1178 0.1383 +vn 0.8323 0.0350 0.5532 +vn 0.8431 -0.0046 0.5377 +vn 0.3778 0.2103 0.9017 +vn -0.9852 0.1230 -0.1197 +vn -0.8571 -0.0057 -0.5151 +vn -0.8511 0.0112 -0.5249 +vn -0.4031 -0.1901 -0.8952 +vn -0.0629 -0.2669 -0.9617 +vn 0.0120 -0.2660 -0.9639 +vn 0.0128 -0.2546 -0.9670 +vn 0.0131 -0.0969 -0.9952 +vn 0.0058 -0.4744 -0.8803 +vn -0.0078 0.2837 0.9589 +vn -0.0131 0.2838 0.9588 +vn -0.0980 0.4937 0.8641 +vn -0.4350 0.5194 0.7355 +vn 0.0589 0.2744 0.9598 +vn 0.3779 0.2103 0.9017 +vn 0.0175 -0.9988 0.0464 +vn 0.0074 -0.8319 0.5548 +vn -0.0083 -0.8307 0.5566 +vn -0.0011 -0.9990 0.0451 +vn -0.0137 -0.3192 0.9476 +vn -0.0224 -0.3208 0.9469 +vn -0.0244 -0.8325 0.5535 +vn -0.0196 -0.9988 0.0439 +vn 0.2327 -0.9707 0.0602 +vn 0.1881 -0.8257 0.5318 +vn 0.7444 -0.6626 0.0824 +vn 0.6480 -0.5674 0.5080 +vn -0.2335 -0.9720 0.0282 +vn -0.1891 -0.8699 -0.4555 +vn -0.0095 -0.8784 -0.4779 +vn -0.7468 -0.6648 -0.0200 +vn -0.6498 -0.6094 -0.4544 +vn -0.3611 -0.3509 -0.8640 +vn -0.0953 -0.4215 -0.9018 +vn 0.0040 -0.4073 -0.9133 +vn -0.0198 -0.0110 0.9997 +vn -0.0144 -0.0111 0.9998 +vn 0.0136 -0.1158 -0.9932 +vn 0.0125 -0.4061 -0.9137 +vn 0.0079 -0.1155 -0.9933 +vn 0.0079 -0.1156 -0.9933 +vn -0.4600 -0.0379 0.8871 +vn -0.0862 -0.0079 0.9963 +vn -0.1252 -0.3414 0.9316 +vn 0.9809 -0.1772 0.0804 +vn 0.9085 -0.1820 -0.3761 +vn 0.6851 -0.6205 -0.3817 +vn -0.0579 -0.1118 -0.9920 +vn -0.4099 -0.1277 -0.9031 +vn -0.4825 0.8697 -0.1040 +vn -0.4256 0.7946 0.4330 +vn -0.0067 0.9457 0.3250 +vn 0.0010 0.9974 -0.0721 +vn -0.1699 0.5107 0.8428 +vn -0.0138 0.5377 0.8430 +vn 0.1400 0.5059 0.8511 +vn 0.3896 0.7854 0.4809 +vn 0.4862 0.8736 -0.0189 +vn -0.9199 0.3796 -0.0988 +vn -0.6943 0.2693 -0.6674 +vn -0.4825 0.8697 -0.1039 +vn -0.3863 0.7121 -0.5863 +vn 0.9261 0.3740 0.0502 +vn 0.6991 0.3437 0.6270 +vn 0.4862 0.8737 -0.0189 +vn 0.3897 0.7854 0.4809 +vn 0.6991 0.3438 0.6270 +vn 0.2140 0.1900 0.9582 +vn -0.0143 0.1341 0.9909 +vn -0.2510 0.1990 0.9473 +vn -0.2342 -0.9324 -0.2753 +vn -0.0123 -0.9422 -0.3349 +vn -0.2342 -0.9324 -0.2754 +vn -0.1832 -0.9101 0.3716 +vn -0.0421 -0.9149 0.4016 +vn -0.0123 -0.9421 -0.3350 +vn 0.0271 -0.8173 0.5756 +vn 0.2052 -0.9753 -0.0812 +vn 0.2052 -0.9754 -0.0812 +vn -0.9449 -0.2286 0.2343 +vn -0.4255 -0.5689 0.7038 +vn -0.4660 -0.7929 0.3926 +vn -0.8000 -0.4353 -0.4129 +vn -0.3992 -0.5919 0.7002 +vn -0.3560 -0.7665 0.5345 +vn -0.8000 -0.4353 -0.4128 +vn -0.4661 -0.7929 0.3926 +vn 0.9943 -0.0579 0.0891 +vn 0.9236 0.2952 -0.2447 +vn 0.7071 -0.1306 -0.6950 +vn 0.7484 -0.5368 -0.3896 +vn 0.5749 0.5821 -0.5750 +vn 0.4541 0.3561 -0.8167 +vn 0.7071 -0.1306 -0.6949 +vn 0.1909 0.1650 -0.9677 +vn 0.2179 -0.3728 -0.9020 +vn 0.7484 -0.5368 -0.3895 +vn 0.2179 -0.3727 -0.9020 +vn 0.2122 -0.7185 -0.6624 +vn -0.2065 0.7958 0.5692 +vn -0.1734 0.9799 0.0982 +vn 0.0149 0.9804 0.1965 +vn 0.0143 0.7888 0.6145 +vn -0.1734 0.9799 0.0981 +vn -0.0614 0.8825 -0.4662 +vn 0.0323 0.9331 -0.3581 +vn 0.1646 0.9379 -0.3054 +vn 0.2056 0.9535 0.2204 +vn 0.2318 0.7464 0.6238 +vn -0.2609 -0.5603 -0.7861 +vn -0.9509 0.1755 -0.2551 +vn -0.9724 0.0019 -0.2332 +vn -0.2963 -0.6533 -0.6967 +vn -0.9473 0.1936 -0.2553 +vn -0.9508 0.1755 -0.2551 +vn -0.9473 0.1936 -0.2552 +vn -0.2695 0.7953 0.5430 +vn -0.2827 0.7212 0.6325 +vn -0.3200 0.3038 0.8974 +vn 0.3338 -0.8182 0.4682 +vn 0.7948 -0.3654 -0.4846 +vn 0.3338 -0.8181 0.4682 +vn 0.2690 0.2941 0.9171 +vn 0.9914 -0.1246 0.0399 +vn 0.9914 -0.1247 0.0399 +vn 0.2984 -0.1911 -0.9351 +vn -0.5851 -0.4237 -0.6915 +vn -0.5306 -0.4963 -0.6871 +vn -0.5852 -0.4237 -0.6914 +vn -0.4026 -0.8836 0.2390 +vn -0.5851 -0.4237 -0.6914 +vn -0.4026 -0.8836 0.2389 +vn -0.0251 -0.9443 0.3281 +vn -0.4027 -0.8836 0.2389 +vn 0.0047 0.2348 0.9720 +vn -0.0251 -0.9443 0.3280 +vn -0.2832 0.8225 0.4933 +vn 0.0132 0.8134 0.5816 +vn 0.0306 0.7670 0.6409 +vn -0.3325 0.8155 0.4737 +vn -0.0418 0.8171 0.5750 +vn 0.2318 0.7525 0.6165 +vn 0.2911 0.7327 0.6151 +vn 0.3108 0.6643 0.6797 +vn 0.0132 0.6806 0.7325 +vn 0.2784 0.5706 0.7726 +vn 0.3013 -0.6289 -0.7168 +vn -0.0056 -0.6057 -0.7957 +vn 0.2737 -0.7821 -0.5599 +vn -0.0285 -0.7471 -0.6641 +vn 0.9787 -0.1668 0.1198 +vn 0.9472 -0.2509 0.1996 +vn 0.9787 -0.1669 0.1198 +vn 0.3148 -0.8491 -0.4242 +vn 0.3803 -0.8209 -0.4261 +vn 0.1071 -0.8128 -0.5726 +vn 0.0350 -0.8221 -0.5683 +vn 0.4572 -0.7679 -0.4487 +vn 0.1851 -0.7731 -0.6066 +vn -0.0722 -0.7094 -0.7011 +vn -0.1549 -0.7295 -0.6662 +vn -0.2362 -0.7165 -0.6564 +vn 0.2685 -0.8546 -0.4445 +vn -0.0173 -0.8136 -0.5812 +vn -0.2889 -0.6981 -0.6551 +vn 0.9352 -0.2047 0.2890 +vn 0.9354 -0.1424 0.3237 +vn -0.9409 0.1987 -0.2743 +vn -0.9347 0.1639 -0.3154 +vn 0.0421 -0.4914 -0.8699 +vn 0.0291 -0.4900 -0.8712 +vn -0.9256 -0.2161 -0.3107 +vn -0.9275 -0.0370 -0.3719 +vn 0.0266 -0.6383 -0.7693 +vn -0.7604 -0.6494 -0.0005 +vn -0.9256 -0.2160 -0.3107 +vn -0.6398 0.1310 0.7573 +vn -0.6607 0.3094 0.6840 +vn -0.6219 0.4601 0.6337 +vn 0.1514 0.7602 0.6318 +vn 0.9308 -0.0792 0.3569 +vn 0.0714 0.7348 0.6745 +vn 0.9165 -0.0007 0.4000 +vn -0.9253 0.1114 -0.3625 +vn -0.9154 0.0805 -0.3943 +vn -0.9253 0.1115 -0.3625 +vn -0.9155 0.0805 -0.3943 +vn -0.4699 0.7441 0.4749 +vn -0.3969 0.7943 0.4601 +vn -0.1143 0.8083 0.5775 +vn -0.1908 0.7705 0.6083 +vn 0.5550 -0.6289 -0.5445 +vn 0.5329 -0.6198 0.5760 +vn -0.1911 -0.8963 0.4001 +vn 0.2629 -0.7091 -0.6543 +vn 0.5330 -0.6198 0.5760 +vn -0.1404 0.1697 0.9754 +vn -0.4083 0.1031 0.9070 +vn -0.1912 -0.8963 0.4001 +vn -0.7604 -0.6495 -0.0005 +vn -0.6606 0.3094 0.6840 +vn -0.3626 0.3851 0.8487 +vn -0.3357 0.4984 0.7994 +vn -0.0716 0.3577 0.9311 +vn -0.0559 0.4812 0.8748 +vn 0.6180 -0.4774 -0.6246 +vn 0.6383 -0.4584 -0.6185 +vn 0.3415 -0.4667 -0.8158 +vn 0.3286 -0.5071 -0.7968 +vn 0.8690 -0.1045 0.4836 +vn 0.8934 0.0390 0.4475 +vn 0.5550 -0.6290 -0.5445 +vn 0.6383 -0.4584 -0.6184 +vn 0.8934 0.0391 0.4475 +vn -0.9884 0.1032 -0.1114 +vn -0.7321 0.5503 0.4016 +vn -0.9696 0.1520 -0.1919 +vn -0.7337 0.6228 0.2717 +vn -0.7320 0.5503 0.4016 +vn -0.1859 0.7057 0.6837 +vn 0.9911 -0.1044 0.0829 +vn 0.7220 -0.5403 -0.4322 +vn 0.1887 -0.6932 -0.6957 +vn -0.0254 -0.6815 -0.7313 +vn -0.0118 -0.7045 -0.7096 +vn -0.2295 -0.6515 -0.7231 +vn -0.2315 -0.6392 -0.7334 +vn 0.0266 0.6976 0.7160 +vn 0.2385 0.6570 0.7152 +vn -0.0287 -0.5331 0.8456 +vn 0.1386 0.0394 0.9896 +vn -0.0671 0.1126 0.9914 +vn -0.0559 -0.4708 0.8805 +vn 0.1386 0.0395 0.9896 +vn 0.2837 0.5440 0.7897 +vn -0.0378 0.6309 0.7749 +vn -0.0671 0.1125 0.9914 +vn -0.3699 0.6156 0.6959 +vn -0.3106 0.1462 0.9392 +vn -0.1328 -0.3964 0.9084 +vn 0.0585 -0.6243 0.7790 +vn 0.5855 -0.4898 0.6460 +vn 0.4761 -0.1878 0.8591 +vn 0.0283 -0.5773 0.8161 +vn 0.5855 -0.4897 0.6460 +vn 0.9194 -0.2192 0.3267 +vn 0.7528 0.1872 0.6310 +vn 0.7529 0.1872 0.6310 +vn -0.2724 0.6510 -0.7085 +vn -0.5699 0.5323 -0.6260 +vn -0.4919 0.7959 -0.3530 +vn -0.1701 0.7711 -0.6136 +vn -0.5699 0.5323 -0.6261 +vn -0.9165 0.2267 -0.3296 +vn -0.7837 0.6201 0.0356 +vn -0.3140 0.8663 0.3885 +vn -0.1572 0.9779 -0.1378 +vn 0.2971 -0.1414 -0.9443 +vn 0.0429 -0.1009 -0.9940 +vn 0.0287 0.2060 -0.9781 +vn 0.3574 -0.6200 -0.6984 +vn 0.0252 -0.6245 -0.7806 +vn 0.0428 -0.1009 -0.9940 +vn -0.2950 -0.5270 -0.7970 +vn -0.1663 -0.0079 -0.9860 +vn -0.1663 -0.0078 -0.9860 +vn -0.0851 0.3349 -0.9384 +vn 0.0034 -0.3467 -0.9380 +vn 0.0034 -0.3468 -0.9379 +vn -0.1978 -0.2382 -0.9509 +vn -0.7362 0.4508 -0.5048 +vn -0.5256 0.8207 -0.2239 +vn -0.7362 0.4508 -0.5047 +vn 0.0513 -0.6063 0.7936 +vn -0.0148 -0.6054 0.7958 +vn 0.3913 -0.2473 0.8864 +vn -0.0199 -0.5657 0.8244 +vn -0.0403 -0.4854 0.8734 +vn -0.0236 0.2333 0.9721 +vn -0.1116 -0.4163 0.9024 +vn -0.3522 0.7554 0.5525 +vn -0.0128 0.7678 0.6406 +vn 0.0111 0.8747 0.4845 +vn 0.3189 0.6884 0.6514 +vn 0.3325 0.8043 0.4924 +vn 0.3515 -0.7570 -0.5508 +vn 0.0130 -0.7646 -0.6443 +vn 0.3261 -0.8627 -0.3866 +vn -0.0025 -0.8714 -0.4905 +vn -0.3260 -0.8004 -0.5030 +vn -0.3183 -0.6802 -0.6604 +vn 0.9994 0.0319 0.0094 +vn 0.9789 -0.1051 0.1755 +vn 0.8404 -0.5020 -0.2040 +vn 0.8520 -0.3615 -0.3788 +vn 0.7908 -0.6110 -0.0354 +vn 0.8404 -0.5020 -0.2041 +vn 0.8519 -0.3615 -0.3788 +vn -0.9771 0.0913 -0.1924 +vn -0.8460 0.4960 0.1955 +vn -0.9981 -0.0538 -0.0301 +vn -0.8641 0.3462 0.3654 +vn 0.0400 0.9972 -0.0628 +vn 0.0400 0.9972 -0.0629 +vn 0.2703 0.9628 -0.0045 +vn 0.2703 0.9628 -0.0044 +vn 0.8227 0.4039 -0.3999 +vn 0.7074 0.0614 -0.7041 +vn 0.8227 0.4040 -0.3999 +vn -0.8302 -0.3909 0.3974 +vn -0.6888 -0.7145 0.1228 +vn -0.8159 -0.4753 -0.3293 +vn -0.6888 -0.7144 0.1227 +vn -0.6889 -0.7144 0.1227 +vn -0.2862 -0.9575 -0.0356 +vn -0.2862 -0.9575 -0.0355 +vn -0.0344 -0.9994 0.0018 +vn -0.0344 -0.9994 0.0017 +vn 0.1908 -0.9760 0.1048 +vn -0.1456 0.3817 0.9127 +vn 0.0360 0.4127 0.9101 +vn 0.2199 0.3668 0.9039 +vn 0.1327 -0.4805 -0.8669 +vn -0.0351 -0.4504 -0.8921 +vn -0.2018 -0.4763 -0.8558 +vn 0.5153 -0.8516 0.0961 +vn 0.9476 -0.3195 0.0013 +vn 0.6141 -0.5285 -0.5861 +vn 0.3187 -0.8941 -0.3147 +vn 0.3187 -0.8941 -0.3148 +vn -0.5284 -0.8364 0.1454 +vn -0.9640 -0.2521 0.0847 +vn -0.6876 0.1351 0.7134 +vn -0.4269 -0.6548 0.6237 +vn -0.6876 0.1350 0.7135 +vn -0.0347 0.1407 0.9894 +vn -0.0659 0.1894 0.9797 +vn -0.0472 0.1891 0.9808 +vn 0.0206 0.1703 0.9852 +vn -0.3965 0.1897 0.8982 +vn -0.3893 0.1900 0.9013 +vn 0.1191 0.0143 0.9928 +vn 0.4667 -0.1440 0.8726 +vn 0.4667 -0.1439 0.8726 +vn 0.4638 0.1075 0.8794 +vn 0.1128 0.1528 0.9818 +vn 0.1294 -0.1803 -0.9751 +vn 0.1083 -0.2036 -0.9730 +vn 0.2260 -0.2995 -0.9269 +vn 0.4085 -0.1727 -0.8963 +vn 0.4016 -0.1767 -0.8986 +vn -0.1188 -0.3863 -0.9147 +vn -0.4647 -0.4254 -0.7766 +vn -0.4684 -0.1972 -0.8612 +vn -0.1428 -0.2599 -0.9550 +vn 0.9985 -0.0390 -0.0389 +vn 0.9983 -0.0398 -0.0434 +vn 0.8660 -0.1145 -0.4867 +vn 0.8681 -0.1140 -0.4832 +vn 0.8681 -0.1139 -0.4831 +vn -0.9986 0.0382 0.0378 +vn -0.9983 0.0391 0.0421 +vn -0.8660 0.1228 0.4847 +vn -0.8681 0.1222 0.4812 +vn -0.8681 0.1222 0.4811 +vn 0.0340 0.1550 0.9873 +vn 0.0321 0.0921 0.9952 +vn 0.0478 0.1574 0.9864 +vn 0.0982 0.1235 0.9875 +vn -0.2109 -0.9601 -0.1835 +vn -0.0037 -0.9943 -0.1068 +vn -0.2109 -0.9601 -0.1836 +vn -0.2652 -0.9618 0.0685 +vn 0.0045 -0.9915 0.1298 +vn 0.2619 -0.9632 0.0602 +vn 0.1918 -0.9632 -0.1883 +vn 0.1918 -0.9632 -0.1882 +vn -0.0500 0.1388 0.9891 +vn -0.1029 -0.2943 0.9502 +vn -0.0501 0.1388 0.9890 +vn -0.8488 0.0889 0.5212 +vn -0.6191 0.3217 0.7164 +vn 0.0154 0.1563 0.9876 +vn -0.0002 0.1614 0.9869 +vn -0.0066 0.1007 0.9949 +vn -0.0306 0.2090 0.9774 +vn 0.0066 0.2054 0.9787 +vn -0.9996 0.0257 0.0091 +vn -0.8851 0.0874 0.4572 +vn -0.9992 0.0336 0.0196 +vn -0.8774 0.1155 0.4657 +vn -0.8851 0.0874 0.4571 +vn -0.4140 0.1839 0.8915 +vn -0.4192 0.1402 0.8970 +vn -0.8891 0.0250 0.4569 +vn 0.9995 -0.0276 -0.0151 +vn 0.8784 -0.0829 -0.4707 +vn 0.9992 -0.0350 -0.0211 +vn 0.8763 -0.1082 -0.4694 +vn 0.4254 -0.1662 -0.8896 +vn 0.4322 -0.1256 -0.8930 +vn 0.3641 -0.0307 -0.9308 +vn 0.1598 -0.1305 -0.9785 +vn 0.3593 -0.1298 -0.9241 +vn 0.1500 -0.1730 -0.9734 +vn -0.0670 0.1477 0.9868 +vn -0.0829 0.1920 0.9779 +vn 0.1264 0.1658 0.9780 +vn 0.1244 0.1714 0.9773 +vn 0.1324 0.1734 0.9759 +vn 0.4573 0.1409 0.8781 +vn 0.4515 0.1425 0.8808 +vn -0.3769 -0.1751 -0.9096 +vn -0.1870 -0.1860 -0.9646 +vn -0.1810 -0.1849 -0.9659 +vn -0.3783 -0.1660 -0.9107 +vn -0.4670 -0.1585 -0.8699 +vn -0.4600 -0.1591 -0.8735 +vn 0.1383 0.1893 -0.9721 +vn 0.3414 0.1832 -0.9219 +vn 0.4048 0.1768 -0.8971 +vn -0.1563 0.0831 -0.9842 +vn -0.4290 0.0756 -0.9001 +vn -0.0442 -0.1975 0.9793 +vn 0.0384 -0.1776 0.9834 +vn -0.3932 -0.1916 0.8993 +vn 0.9989 0.0182 -0.0437 +vn 0.8612 0.1034 -0.4977 +vn 0.8611 0.1034 -0.4977 +vn -0.9994 -0.0173 0.0302 +vn -0.8718 -0.1102 0.4774 +vn -0.8718 -0.1102 0.4773 +vn 0.0169 -0.1620 0.9866 +vn 0.0233 -0.2409 0.9703 +vn 0.0099 -0.1102 0.9939 +vn -0.8458 -0.1004 -0.5239 +vn -0.6723 -0.5469 -0.4988 +vn -0.2834 -0.2952 -0.9124 +vn -0.9592 -0.0537 -0.2776 +vn -0.8275 -0.5414 -0.1485 +vn -0.6724 -0.5469 -0.4988 +vn -0.8275 -0.5415 -0.1484 +vn -0.2834 -0.2953 -0.9124 +vn -0.0482 0.0421 0.9980 +vn 0.0532 0.0297 0.9981 +vn 0.0773 -0.0747 0.9942 +vn 0.0218 -0.0818 0.9964 +vn 0.4242 -0.0639 0.9033 +vn 0.1243 0.7104 -0.6927 +vn 0.3269 0.6832 -0.6529 +vn 0.4029 0.6624 -0.6316 +vn 0.9990 0.0362 0.0259 +vn 0.8693 0.3750 -0.3219 +vn -0.9986 -0.0181 -0.0499 +vn -0.8889 -0.3584 0.2853 +vn -0.3874 -0.6717 0.6315 +vn 0.8367 0.1972 -0.5110 +vn 0.8300 0.2913 -0.4756 +vn 0.9418 0.1251 -0.3121 +vn 0.9403 0.1812 -0.2880 +vn 0.9402 0.2153 -0.2638 +vn 0.8225 0.3525 -0.4464 +vn 0.0783 -0.6715 0.7368 +vn 0.0290 -0.6573 0.7531 +vn 0.0329 -0.5763 0.8166 +vn 0.0985 -0.5085 0.8554 +vn 0.0157 -0.5228 0.8523 +vn 0.4541 -0.4450 0.7719 +vn -0.0133 -0.7036 0.7105 +vn -0.1877 0.5077 -0.8408 +vn -0.3883 0.4734 -0.7906 +vn -0.4516 0.4589 -0.7652 +vn -0.6392 -0.1454 -0.7551 +vn -0.6154 -0.5389 -0.5753 +vn -0.6392 -0.1454 -0.7552 +vn -0.1416 -0.1864 -0.9722 +vn -0.1698 -0.3265 -0.9298 +vn -0.6154 -0.5389 -0.5752 +vn -0.0890 -0.7154 -0.6930 +vn -0.2457 -0.8954 -0.3713 +vn -0.8275 -0.5414 -0.1484 +vn -0.5730 0.7388 0.3547 +vn -0.5562 0.8054 0.2051 +vn -0.5731 0.7388 0.3547 +vn -0.1077 0.7744 0.6234 +vn -0.1015 0.8822 0.4597 +vn -0.0982 0.9535 0.2850 +vn -0.5561 0.8287 0.0632 +vn 0.9354 0.3372 -0.1064 +vn 0.5731 0.7253 -0.3814 +vn 0.5802 0.7962 -0.1713 +vn 0.9309 0.3642 0.0285 +vn 0.5731 0.7253 -0.3813 +vn 0.0855 0.8595 -0.5039 +vn 0.0966 0.9519 -0.2907 +vn 0.5803 0.7962 -0.1713 +vn 0.1091 0.9911 -0.0768 +vn 0.5860 0.8090 0.0450 +vn 0.9219 0.3435 0.1794 +vn 0.6037 -0.1574 -0.7815 +vn 0.6063 -0.1187 -0.7863 +vn 0.9501 -0.0650 -0.3050 +vn 0.1019 -0.1771 -0.9789 +vn 0.1118 -0.1331 -0.9848 +vn 0.1164 -0.0295 -0.9928 +vn 0.6068 -0.0291 -0.7943 +vn 0.6067 -0.0291 -0.7944 +vn 0.9508 -0.0194 -0.3093 +vn 0.9490 0.0513 -0.3111 +vn 0.6023 0.1107 -0.7905 +vn 0.5895 0.1642 -0.7909 +vn 0.9454 0.0737 -0.3173 +vn 0.6023 0.1108 -0.7905 +vn 0.1033 0.1325 -0.9858 +vn 0.0922 0.1968 -0.9761 +vn 0.0840 0.3455 -0.9346 +vn 0.5767 0.2872 -0.7649 +vn 0.5766 0.2872 -0.7649 +vn -0.5712 0.7946 -0.2055 +vn -0.5891 0.7404 -0.3236 +vn -0.5713 0.7946 -0.2055 +vn -0.1056 0.9866 -0.1244 +vn -0.1163 0.9405 -0.3193 +vn -0.5891 0.7405 -0.3236 +vn -0.1297 0.8465 -0.5163 +vn -0.6002 0.6620 -0.4489 +vn 0.6068 0.0629 -0.7924 +vn 0.9506 0.0275 -0.3093 +vn 0.6068 -0.0291 -0.7944 +vn 0.1164 -0.0296 -0.9928 +vn 0.1126 0.0770 -0.9907 +vn 0.6067 0.0629 -0.7924 +vn -0.8488 0.0890 0.5212 +vn -0.5902 0.3627 0.7212 +vn -0.6214 0.6154 0.4848 +vn -0.9214 0.3819 0.0726 +vn -0.5901 0.3627 0.7212 +vn -0.1275 0.5667 0.8140 +vn -0.1206 0.6564 0.7447 +vn -0.6214 0.6155 0.4848 +vn -0.6148 0.1038 -0.7818 +vn -0.6051 0.0632 -0.7936 +vn -0.1182 0.1362 -0.9836 +vn -0.1092 0.0804 -0.9908 +vn -0.6051 0.0632 -0.7937 +vn -0.1058 -0.0274 -0.9940 +vn -0.5993 -0.0167 -0.8004 +vn -0.5992 -0.0166 -0.8004 +vn -0.9564 0.0921 -0.2773 +vn -0.6162 0.2714 -0.7394 +vn -0.6166 0.1538 -0.7721 +vn -0.9554 0.0490 -0.2913 +vn -0.1362 0.3466 -0.9281 +vn -0.1283 0.1997 -0.9714 +vn -0.6167 0.1538 -0.7721 +vn -0.8088 0.5216 0.2716 +vn -0.6191 0.3216 0.7164 +vn -0.8088 0.5217 0.2716 +vn -0.8045 0.5562 -0.2084 +vn -0.8991 0.3566 -0.2539 +vn -0.8045 0.5562 -0.2083 +vn 0.8344 0.0800 -0.5454 +vn 0.8336 0.1163 -0.5399 +vn 0.8344 0.0799 -0.5454 +vn 0.8310 0.5129 -0.2153 +vn 0.8236 0.5655 -0.0441 +vn 0.8192 0.5545 0.1466 +vn 0.8064 0.4866 0.3360 +vn 0.9035 0.2760 0.3279 +vn -0.8449 -0.0521 -0.5323 +vn -0.9526 -0.0176 -0.3037 +vn -0.9553 -0.0242 -0.2947 +vn -0.8449 -0.0723 -0.5301 +vn -0.8567 0.3042 -0.4166 +vn -0.8614 0.2536 -0.4401 +vn -0.8566 0.3042 -0.4166 +vn -0.9592 0.1610 -0.2325 +vn -0.9584 0.1380 -0.2497 +vn -0.8623 0.1688 -0.4775 +vn -0.8622 0.1688 -0.4775 +vn -0.8515 0.0973 -0.5152 +vn -0.8630 0.3353 -0.3779 +vn -0.9552 0.1837 -0.2320 +vn 0.8405 -0.0920 -0.5339 +vn 0.8456 -0.0248 -0.5333 +vn 0.8307 0.4205 -0.3649 +vn 0.9388 0.2695 -0.2146 +vn 0.8307 0.4205 -0.3648 +vn 0.8413 0.0441 -0.5388 +vn 0.1147 0.7163 0.6883 +vn 0.1163 0.8375 0.5340 +vn 0.0072 0.8659 0.5002 +vn 0.0031 0.7512 0.6601 +vn 0.1190 0.9253 0.3601 +vn 0.0102 0.9459 0.3244 +vn 0.1112 0.5041 0.8565 +vn 0.1207 0.5849 0.8021 +vn -0.0011 0.6285 0.7778 +vn 0.0015 0.5051 0.8630 +vn -0.0109 0.9517 -0.3070 +vn 0.0001 0.9948 -0.1020 +vn -0.0239 0.8581 -0.5129 +vn 0.1172 0.9812 0.1532 +vn 0.0078 0.9927 0.1202 +vn 0.0001 0.9948 -0.1021 +vn -0.0992 0.9912 0.0876 +vn 0.0760 0.6056 -0.7922 +vn 0.0795 0.5101 -0.8564 +vn -0.0310 0.5128 -0.8580 +vn -0.0341 0.6076 -0.7935 +vn -0.0266 0.3483 -0.9370 +vn -0.1406 0.5089 -0.8493 +vn -0.1429 0.6020 -0.7856 +vn 0.0017 0.0791 -0.9969 +vn -0.0076 0.1352 -0.9908 +vn 0.0051 -0.0286 -0.9996 +vn 0.0850 -0.1882 -0.9785 +vn 0.1069 -0.3325 -0.9370 +vn -0.0324 -0.2480 -0.9682 +vn -0.0285 -0.1864 -0.9821 +vn 0.0394 -0.7155 -0.6975 +vn -0.0241 -0.7233 -0.6901 +vn 0.0006 -0.1335 -0.9911 +vn -0.0096 -0.1779 -0.9840 +vn -0.1209 -0.1764 -0.9769 +vn -0.1106 -0.1322 -0.9850 +vn -0.0181 0.1995 -0.9797 +vn 0.0772 0.7151 -0.6947 +vn -0.0327 0.7150 -0.6983 +vn -0.1403 0.7064 -0.6938 +vn -0.6279 0.4681 -0.6218 +vn -0.6229 0.3983 -0.6733 +vn -0.6279 0.4682 -0.6218 +vn -0.6228 0.3984 -0.6733 +vn 0.5759 0.6789 0.4554 +vn 0.5693 0.5724 0.5901 +vn 0.5664 0.4473 0.6921 +vn 0.5664 0.4473 0.6922 +vn -0.0024 -0.9978 -0.0656 +vn -0.0025 -0.9978 -0.0658 +vn 0.2172 -0.8986 -0.3814 +vn 0.2171 -0.8986 -0.3813 +vn -0.6127 0.5516 -0.5660 +vn -0.6126 0.5516 -0.5661 +vn 0.5781 0.4996 -0.6451 +vn 0.5730 0.5990 -0.5593 +vn 0.5731 0.5990 -0.5593 +vn 0.5999 -0.1840 -0.7786 +vn 0.5983 -0.1636 -0.7844 +vn 0.0915 -0.1835 -0.9787 +vn 0.5983 -0.1637 -0.7844 +vn 0.4601 0.0984 0.8824 +vn -0.0301 0.0192 0.9994 +vn -0.0302 0.0192 0.9994 +vn 0.5753 0.4215 -0.7010 +vn -0.5606 0.8249 -0.0727 +vn -0.6070 -0.0937 -0.7892 +vn -0.1106 -0.1321 -0.9850 +vn -0.6190 -0.1244 -0.7755 +vn 0.5828 0.7666 0.2695 +vn 0.5860 0.8090 0.0449 +vn 0.5722 0.2782 0.7715 +vn 0.5721 0.2783 0.7715 +vn -0.0055 0.6256 0.7802 +vn 0.8919 0.0634 0.4478 +vn 0.8919 0.0633 0.4478 +vn 0.5547 -0.6365 -0.5359 +vn 0.5547 -0.6364 -0.5359 +vn 0.2697 -0.6538 -0.7069 +vn -0.0035 -0.6100 -0.7924 +vn -0.5576 0.6203 0.5517 +vn -0.2751 0.6527 0.7059 +vn -0.9218 0.0569 -0.3834 +vn -0.9219 0.0569 -0.3833 +vn -0.5575 0.6203 0.5517 +vn -0.9218 0.0570 -0.3834 +vn -0.8688 0.3269 -0.3720 +vn -0.8514 0.4049 -0.3333 +vn -0.8861 0.2701 -0.3768 +vn -0.8861 0.2701 -0.3767 +vn -0.8514 0.4049 -0.3334 +vn 0.8971 -0.2811 0.3408 +vn 0.8856 -0.3426 0.3135 +vn 0.4425 -0.6183 0.6495 +vn 0.8986 -0.2492 0.3610 +vn -0.8922 0.0838 -0.4439 +vn -0.8899 0.1516 -0.4303 +vn -0.8909 0.0575 -0.4506 +vn 0.4501 -0.2950 0.8428 +vn 0.9039 -0.0717 0.4216 +vn 0.9127 -0.1284 0.3880 +vn 0.8953 -0.0481 0.4428 +vn 0.8954 0.0343 0.4439 +vn 0.8951 0.0031 0.4458 +vn 0.8976 0.0473 0.4384 +vn -0.4279 -0.0222 -0.9036 +vn -0.4369 -0.1164 -0.8919 +vn -0.8879 -0.0441 -0.4579 +vn -0.8817 -0.0039 -0.4718 +vn -0.8962 -0.0575 -0.4400 +vn -0.4680 -0.1620 -0.8688 +vn -0.9070 -0.0549 -0.4176 +vn -0.9051 -0.0558 -0.4215 +vn -0.9094 -0.1072 -0.4019 +vn 0.4580 0.1408 0.8777 +vn 0.9076 0.0452 0.4174 +vn 0.9056 0.0460 0.4216 +vn 0.9084 -0.0095 0.4180 +vn -0.6766 -0.4988 -0.5417 +vn -0.7577 -0.2966 -0.5814 +vn -0.6765 -0.4989 -0.5417 +vn -0.7577 -0.2965 -0.5814 +vn 0.7482 0.0740 0.6594 +vn 0.4572 -0.6839 0.5686 +vn 0.7627 0.2749 0.5854 +vn 0.7482 0.0740 0.6593 +vn 0.4573 -0.6839 0.5685 +vn -0.7165 -0.0564 0.6953 +vn -0.3077 -0.4551 0.8356 +vn 0.6764 0.7240 -0.1355 +vn 0.4068 0.8118 -0.4188 +vn 0.8263 0.4670 0.3147 +vn 0.6764 0.7240 -0.1354 +vn 0.8263 0.4670 0.3148 +vn -0.8042 -0.3282 -0.4956 +vn -0.7549 -0.1739 -0.6324 +vn 0.8116 0.3257 0.4849 +vn 0.1415 -0.7166 0.6829 +vn 0.7546 -0.6501 0.0890 +vn 0.0810 -0.7082 0.7014 +vn 0.1416 -0.7167 0.6829 +vn 0.7547 -0.6500 0.0890 +vn -0.5611 0.1117 -0.8202 +vn -0.7302 -0.3507 -0.5864 +vn -0.2069 0.5213 -0.8279 +vn -0.4880 0.2277 -0.8426 +vn -0.4880 0.2277 -0.8427 +vn 0.5263 -0.7713 0.3580 +vn 0.5263 -0.7712 0.3580 +vn 0.7564 0.3757 0.5355 +vn 0.7675 0.3185 0.5563 +vn 0.7467 0.4597 0.4808 +vn 0.7468 0.4596 0.4807 +vn -0.7314 -0.3828 -0.5644 +vn -0.7396 -0.3446 -0.5782 +vn -0.7396 -0.3446 -0.5781 +vn 0.6467 0.7605 0.0579 +vn -0.2561 -0.4719 0.8436 +vn -0.6777 0.0969 0.7289 +vn 0.7612 0.2718 -0.5888 +vn 0.7759 -0.0298 -0.6301 +vn 0.4282 0.7241 -0.5406 +vn 0.7613 0.2718 -0.5888 +vn -0.7551 0.3601 0.5479 +vn -0.7722 0.0724 0.6312 +vn 0.0085 0.8891 -0.4577 +vn -0.4825 0.8697 -0.1038 +vn 0.4083 -0.0426 0.9119 +vn 0.8595 -0.1292 0.4945 +vn 0.8576 -0.0055 0.5143 +vn 0.6481 -0.5674 0.5080 +vn -0.2102 -0.8327 0.5122 +vn -0.7467 -0.6648 -0.0201 +vn -0.2335 -0.9720 0.0281 +vn 0.2099 -0.8762 -0.4337 +vn 0.0227 -0.8793 -0.4757 +vn 0.0063 -0.8776 -0.4793 +vn -0.0011 -0.9990 0.0452 +vn -0.8979 0.2433 0.3669 +vn -0.8887 0.3472 0.2994 +vn -0.8887 0.3472 0.2993 +vn 0.9173 -0.2466 -0.3127 +vn 0.8955 -0.3484 -0.2770 +vn -0.3952 -0.0504 -0.9172 +vn -0.8629 -0.1598 -0.4794 +vn -0.8591 -0.0178 -0.5115 +vn -0.3610 -0.3509 -0.8640 +vn 0.8353 -0.3496 0.4243 +vn 0.4660 -0.7877 0.4029 +vn -0.8453 -0.4428 -0.2988 +vn -0.8454 -0.4428 -0.2988 +vn -0.4654 -0.8736 -0.1420 +vn -0.4656 -0.8701 0.1613 +vn 0.8936 -0.0299 0.4478 +vn 0.4541 -0.4450 0.7718 +vn 0.9085 -0.2002 0.3668 +vn -0.8896 0.2273 -0.3962 +vn -0.8844 0.0378 -0.4652 +vn 0.8621 -0.4181 0.2862 +vn 0.8399 -0.4746 0.2634 +vn -0.8327 0.4716 -0.2902 +vn -0.8099 0.5290 -0.2535 +vn -0.8326 0.4717 -0.2902 +vn -0.8098 0.5291 -0.2535 +vn 0.3892 -0.9125 -0.1262 +vn 0.8212 -0.5215 0.2315 +vn 0.8130 -0.5542 0.1787 +vn 0.8185 -0.5646 0.1058 +vn 0.8400 -0.5425 0.0107 +vn 0.8130 -0.5542 0.1788 +vn 0.8186 -0.5646 0.1058 +vn -0.8042 0.5914 -0.0599 +vn -0.8260 0.5620 0.0423 +vn -0.3894 0.9090 0.1485 +vn -0.7960 0.5890 -0.1394 +vn -0.8042 0.5914 -0.0598 +vn -0.7977 0.5680 -0.2025 +vn -0.8551 0.5001 0.1368 +vn -0.8773 0.4335 0.2060 +vn -0.8551 0.5002 0.1369 +vn 0.8903 -0.3858 -0.2417 +vn 0.8824 -0.4328 -0.1846 +vn 0.8654 -0.4917 -0.0963 +vn -0.8867 0.3836 0.2581 +vn -0.8867 0.3836 0.2582 +vn -0.8526 0.0051 -0.5226 +vn 0.8528 -0.0016 0.5222 +vn 0.7693 -0.0406 -0.6376 +vn 0.7808 0.0592 -0.6220 +vn 0.2212 -0.0450 -0.9742 +vn 0.7692 -0.0406 -0.6377 +vn 0.8044 0.4144 -0.4258 +vn 0.7034 0.6847 -0.1909 +vn -0.7126 -0.4559 0.5333 +vn -0.6974 -0.6781 0.2318 +vn -0.7449 -0.0864 0.6615 +vn -0.6975 -0.6781 0.2317 +vn -0.7619 0.0326 0.6468 +vn -0.7619 0.0325 0.6468 +vn -0.7004 -0.7101 0.0722 +vn -0.6768 -0.7224 -0.1421 +vn -0.6767 -0.7224 -0.1421 +vn 0.6551 0.6201 0.4316 +vn 0.6246 0.5387 0.5654 +vn 0.6998 0.6860 0.1991 +vn 0.6998 0.6860 0.1992 +vn 0.7098 0.7039 -0.0282 +vn 0.7097 0.7039 -0.0282 +vn 0.6374 0.4747 0.6069 +vn 0.6680 0.4270 0.6094 +vn 0.6680 0.4271 0.6094 +vn -0.6456 -0.4633 -0.6071 +vn -0.7288 -0.3592 -0.5829 +vn -0.6041 -0.5642 -0.5628 +vn -0.6255 -0.6713 -0.3976 +vn 0.6779 0.3509 0.6460 +vn 0.6779 0.3508 0.6460 +vn 0.7659 0.2897 0.5739 +vn 0.7660 0.2897 0.5739 +vn -0.8321 -0.1970 -0.5185 +vn -0.7531 -0.3045 -0.5832 +vn -0.7530 -0.3046 -0.5833 +vn 0.1467 -0.9842 -0.0990 +vn 0.4361 -0.8815 -0.1809 +vn -0.1457 -0.9013 0.4079 +vn 0.9020 0.0475 0.4291 +vn 0.9988 -0.0376 -0.0309 +vn -0.9016 -0.0573 -0.4287 +vn -0.9989 0.0367 0.0303 +vn 0.2620 -0.9632 0.0602 +vn 0.5646 -0.5630 -0.6036 +vn 0.7995 -0.5751 -0.1734 +vn 0.7995 -0.5751 -0.1735 +vn 0.5645 -0.5630 -0.6036 +vn -0.0204 -0.1841 -0.9827 +vn -0.1319 -0.1826 -0.9743 +vn -0.6271 -0.1277 -0.7684 +vn -0.9574 -0.0239 -0.2879 +vn -0.8483 -0.0741 -0.5243 +vn -0.1741 -0.2110 -0.9619 +vn -0.4679 -0.1620 -0.8688 +vn 0.1158 0.1660 0.9793 +vn 0.4579 0.1408 0.8778 +vn 0.1053 -0.8468 -0.5213 +vn -0.0127 -0.7657 -0.6431 +vn -0.0573 -0.8607 -0.5059 +vn -0.0056 -0.8753 -0.4836 +vn 0.0421 -0.8845 -0.4646 +vn -0.0978 -0.8085 -0.5804 +vn -0.8718 0.1210 0.4746 +vn -0.4063 0.1898 0.8938 +vn 0.8719 -0.1129 -0.4765 +vn 0.4160 -0.1723 -0.8929 +vn 0.1398 -0.1790 -0.9739 +vn -0.0825 0.1948 0.9774 +vn -0.0905 0.1924 0.9771 +vn 0.6334 -0.5813 -0.5108 +vn 0.6334 -0.5813 -0.5107 +vn -0.0658 -0.4962 -0.8657 +vn -0.0724 -0.4554 -0.8873 +vn 0.0086 -0.4728 -0.8811 +vn 0.0107 -0.5256 -0.8507 +vn -0.0603 -0.4280 -0.9018 +vn 0.0063 -0.4300 -0.9028 +vn -0.0645 -0.8529 -0.5181 +vn -0.0084 -0.8686 -0.4954 +vn 0.0475 -0.8806 -0.4715 +vn -0.0399 -0.5612 0.8267 +vn -0.0428 -0.5968 0.8012 +vn 0.0270 -0.6000 0.7996 +vn 0.0305 -0.5463 0.8370 +vn -0.0227 -0.6145 0.7886 +vn 0.0249 -0.6140 0.7889 +vn 0.0738 -0.6098 0.7891 +vn 0.0976 -0.5900 0.8015 +vn 0.0980 -0.5552 0.8259 +vn 0.0105 -0.9481 0.3178 +vn 0.0667 -0.9437 0.3241 +vn -0.0738 -0.1012 0.9921 +vn -0.0772 -0.1315 0.9883 +vn -0.0042 -0.1325 0.9912 +vn -0.0001 -0.0841 0.9965 +vn -0.0642 -0.1520 0.9863 +vn -0.0079 -0.1559 0.9877 +vn 0.0515 -0.1483 0.9876 +vn 0.0697 -0.1267 0.9895 +vn 0.0714 -0.0967 0.9927 +vn -0.0564 0.2195 0.9740 +vn -0.0624 0.1883 0.9801 +vn 0.0218 0.1845 0.9826 +vn 0.0170 0.2308 0.9728 +vn -0.0517 0.1532 0.9868 +vn 0.0267 0.1320 0.9909 +vn 0.1013 0.1448 0.9843 +vn 0.1060 0.1784 0.9782 +vn 0.0939 0.2113 0.9729 +vn -0.0919 -0.0886 0.9918 +vn 0.0039 -0.0675 0.9977 +vn 0.0965 -0.0811 0.9920 +vn -0.0569 -0.5487 0.8341 +vn 0.0329 -0.5237 0.8513 +vn 0.1193 -0.5391 0.8337 +vn -0.0717 -0.4306 -0.8997 +vn -0.1304 -0.4489 -0.8840 +vn -0.0999 -0.5205 -0.8480 +vn -0.0426 -0.4986 0.8658 +vn 0.0265 -0.4315 0.9017 +vn 0.0908 -0.5016 0.8603 +vn -0.0285 -0.0840 0.9961 +vn -0.0099 -0.0291 0.9995 +vn 0.0159 -0.0869 0.9961 +vn 0.0103 -0.5839 -0.8118 +vn -0.0971 0.1096 0.9892 +vn -0.1435 0.1871 0.9718 +vn -0.0915 0.2339 0.9679 +vn 0.0127 0.2452 0.9694 +vn 0.1225 0.2211 0.9675 +vn 0.1524 0.0946 0.9838 +vn 0.0305 0.0448 0.9985 +vn -0.0972 0.1095 0.9892 +vn -0.0347 0.1406 0.9895 +vn 0.0668 -0.5535 0.8302 +vn -0.0788 -0.8428 -0.5325 +vn 0.1873 0.1681 0.9678 +vn -0.0093 -0.5597 0.8286 +vn -0.0743 -0.1095 0.9912 +vn 0.0550 -0.8836 -0.4650 +vn 0.0715 -0.1021 0.9922 +vn 0.0074 -0.4525 -0.8917 +vn -0.0904 -0.9524 0.2911 +usemtl Scene_-_Root +s 1 +f 38788/38788/28405 38789/38789/28406 38790/38790/28407 +f 38788/38788/28405 38790/38790/28407 38791/38791/28408 +f 38789/38789/28406 38792/38792/28409 38793/38793/28410 +f 38789/38789/28406 38793/38793/28410 38790/38790/28407 +f 38790/38790/28407 38793/38793/28410 38794/38794/28411 +f 38790/38790/28407 38794/38794/28411 38795/38795/28412 +f 38791/38791/28408 38790/38790/28407 38795/38795/28412 +f 38791/38791/28408 38795/38795/28412 38796/38796/28413 +f 38797/38797/28414 38798/38798/28415 38799/38799/28416 +f 38797/38797/28414 38799/38799/28416 38800/38800/28417 +f 38798/38798/28415 38801/38801/28418 38802/38802/28419 +f 38798/38798/28415 38802/38802/28419 38799/38799/28416 +f 38799/38799/28416 38802/38802/28419 38803/38803/28420 +f 38799/38799/28416 38803/38803/28420 38804/38804/28421 +f 38800/38800/28417 38799/38799/28416 38804/38804/28421 +f 38800/38800/28417 38804/38804/28421 38805/38805/28422 +f 38806/38806/28423 38807/38807/28424 38808/38808/28425 +f 38806/38806/28423 38808/38808/28425 38809/38809/28426 +f 38807/38807/28424 38810/38810/28427 38811/38811/28428 +f 38807/38807/28424 38811/38811/28428 38808/38808/28425 +f 38808/38808/28425 38811/38811/28428 38812/38812/28429 +f 38808/38808/28425 38812/38812/28429 38813/38813/28430 +f 38809/38809/28426 38808/38808/28425 38813/38813/28430 +f 38809/38809/28426 38813/38813/28430 38814/38814/28431 +f 38815/38815/28432 38816/38816/28433 38817/38817/28434 +f 38815/38815/28432 38817/38817/28434 38818/38818/28435 +f 38816/38816/28433 38819/38819/28436 38820/38820/28437 +f 38816/38816/28433 38820/38820/28437 38817/38817/28434 +f 38817/38817/28434 38820/38820/28437 38821/38821/28438 +f 38817/38817/28434 38821/38821/28438 38822/38822/28439 +f 38818/38818/28435 38817/38817/28434 38822/38822/28439 +f 38818/38818/28435 38822/38822/28439 38823/38823/28440 +f 38824/38824/28441 38825/38825/28442 38826/38826/28443 +f 38824/38824/28441 38826/38826/28443 38827/38827/28444 +f 38828/38828/28445 38829/38829/28446 38830/38830/28447 +f 38828/38828/28445 38830/38830/28447 38831/38831/28443 +f 38831/38831/28443 38830/38830/28447 38832/38832/28448 +f 38831/38831/28443 38832/38832/28448 38833/38833/28449 +f 38827/38827/28444 38826/38826/28443 38834/38834/28449 +f 38827/38827/28444 38834/38834/28449 38797/38797/28414 +f 38835/38835/28450 38836/38836/28451 38837/38837/28452 +f 38835/38835/28450 38837/38837/28452 38838/38838/28453 +f 38836/38836/28451 38839/38839/28454 38840/38840/28455 +f 38836/38836/28451 38840/38840/28455 38837/38837/28452 +f 38837/38837/28452 38840/38840/28455 38841/38841/28456 +f 38837/38837/28452 38841/38841/28456 38842/38842/28457 +f 38838/38838/28453 38837/38837/28452 38842/38842/28457 +f 38838/38838/28453 38842/38842/28457 38823/38823/28440 +f 38843/38843/28458 38844/38844/28459 38845/38845/28460 +f 38843/38843/28458 38845/38845/28460 38846/38846/28461 +f 38844/38844/28459 38847/38847/28462 38848/38848/28463 +f 38844/38844/28459 38848/38848/28463 38845/38845/28460 +f 38845/38845/28460 38848/38848/28463 38849/38849/28464 +f 38845/38845/28460 38849/38849/28464 38850/38850/28465 +f 38846/38846/28461 38845/38845/28460 38850/38850/28465 +f 38846/38846/28461 38850/38850/28465 38851/38851/28466 +f 38805/38805/28422 38852/38852/28467 38853/38853/28468 +f 38805/38805/28422 38853/38853/28468 38800/38800/28417 +f 38854/38854/28469 38855/38855/28470 38856/38856/28471 +f 38854/38854/28469 38856/38856/28471 38857/38857/28468 +f 38853/38853/28468 38858/38858/28471 38824/38824/28441 +f 38853/38853/28468 38824/38824/28441 38827/38827/28444 +f 38800/38800/28417 38853/38853/28468 38827/38827/28444 +f 38800/38800/28417 38827/38827/28444 38797/38797/28414 +f 38788/38788/28405 38791/38791/28408 38859/38859/28472 +f 38788/38788/28405 38859/38859/28472 38860/38860/28473 +f 38791/38791/28408 38796/38796/28413 38861/38861/28474 +f 38791/38791/28408 38861/38861/28474 38859/38859/28472 +f 38859/38859/28472 38861/38861/28474 38862/38862/28475 +f 38859/38859/28472 38862/38862/28475 38863/38863/28476 +f 38860/38860/28473 38859/38859/28472 38863/38863/28476 +f 38860/38860/28473 38863/38863/28476 38835/38835/28450 +f 38864/38864/28477 38865/38865/28478 38866/38866/28479 +f 38864/38864/28477 38866/38866/28479 38867/38867/28480 +f 38865/38865/28478 38868/38868/28481 38869/38869/28482 +f 38865/38865/28478 38869/38869/28482 38866/38866/28479 +f 38866/38866/28479 38869/38869/28482 38870/38870/28483 +f 38866/38866/28479 38870/38870/28483 38871/38871/28484 +f 38867/38867/28480 38866/38866/28479 38871/38871/28484 +f 38867/38867/28480 38871/38871/28484 38872/38872/28485 +f 38873/38873/28486 38874/38874/28487 38875/38875/28488 +f 38873/38873/28486 38875/38875/28488 38876/38876/28489 +f 38877/38877/28487 38878/38878/28490 38879/38879/28491 +f 38877/38877/28487 38879/38879/28491 38880/38880/28492 +f 38880/38880/28492 38879/38879/28491 38881/38881/28493 +f 38880/38880/28492 38881/38881/28493 38882/38882/28494 +f 38876/38876/28489 38875/38875/28488 38883/38883/28494 +f 38876/38876/28489 38883/38883/28494 38814/38814/28431 +f 38884/38884/28495 38885/38885/28496 38886/38886/28497 +f 38884/38884/28495 38886/38886/28497 38887/38887/28498 +f 38888/38888/28496 38889/38889/28499 38890/38890/28500 +f 38888/38888/28496 38890/38890/28500 38891/38891/28497 +f 38891/38891/28497 38890/38890/28500 38892/38892/28501 +f 38891/38891/28497 38892/38892/28501 38893/38893/28502 +f 38887/38887/28498 38886/38886/28497 38894/38894/28502 +f 38887/38887/28498 38894/38894/28502 38895/38895/28503 +f 38896/38896/28504 38897/38897/28505 38898/38898/28506 +f 38896/38896/28504 38898/38898/28506 38899/38899/28507 +f 38897/38897/28505 38900/38900/28508 38901/38901/28509 +f 38897/38897/28505 38901/38901/28509 38898/38898/28506 +f 38898/38898/28506 38901/38901/28509 38902/38902/28510 +f 38898/38898/28506 38902/38902/28510 38903/38903/28511 +f 38899/38899/28507 38898/38898/28506 38903/38903/28511 +f 38899/38899/28507 38903/38903/28511 38904/38904/28512 +f 38905/38905/28513 38906/38906/28514 38907/38907/28515 +f 38905/38905/28513 38907/38907/28515 38908/38908/28516 +f 38906/38906/28514 38909/38909/28517 38910/38910/28518 +f 38906/38906/28514 38910/38910/28518 38907/38907/28515 +f 38911/38911/28519 38912/38912/28520 38913/38913/28521 +f 38911/38911/28519 38913/38913/28521 38914/38914/28522 +f 38915/38915/28516 38911/38911/28519 38914/38914/28522 +f 38915/38915/28516 38914/38914/28522 38916/38916/28523 +f 38917/38917/28524 38918/38918/28525 38919/38919/28526 +f 38917/38917/28524 38919/38919/28526 38920/38920/28527 +f 38918/38918/28525 38921/38921/28528 38922/38922/28529 +f 38918/38918/28525 38922/38922/28529 38919/38919/28526 +f 38919/38919/28526 38922/38922/28529 38923/38923/28530 +f 38919/38919/28526 38923/38923/28530 38924/38924/28531 +f 38920/38920/28527 38919/38919/28526 38924/38924/28531 +f 38920/38920/28527 38924/38924/28531 38925/38925/28532 +f 38926/38926/28533 38927/38927/28534 38928/38928/28535 +f 38926/38926/28533 38928/38928/28535 38929/38929/28536 +f 38927/38927/28534 38930/38930/28537 38931/38931/28538 +f 38927/38927/28534 38931/38931/28538 38928/38928/28535 +f 38928/38928/28535 38931/38931/28538 38932/38932/28539 +f 38928/38928/28535 38932/38932/28539 38933/38933/28540 +f 38929/38929/28536 38928/38928/28535 38933/38933/28540 +f 38929/38929/28536 38933/38933/28540 38904/38904/28512 +f 38934/38934/28541 38935/38935/28542 38936/38936/28543 +f 38934/38934/28541 38936/38936/28543 38937/38937/28544 +f 38935/38935/28542 38938/38938/28545 38939/38939/28546 +f 38935/38935/28542 38939/38939/28546 38936/38936/28543 +f 38936/38936/28543 38939/38939/28546 38940/38940/28547 +f 38936/38936/28543 38940/38940/28547 38941/38941/28548 +f 38937/38937/28544 38936/38936/28543 38941/38941/28548 +f 38937/38937/28544 38941/38941/28548 38896/38896/28504 +f 38942/38942/28549 38943/38943/28550 38944/38944/28551 +f 38942/38942/28549 38944/38944/28551 38945/38945/28552 +f 38943/38943/28550 38946/38946/28553 38947/38947/28554 +f 38943/38943/28550 38947/38947/28554 38944/38944/28551 +f 38944/38944/28551 38947/38947/28554 38948/38948/28555 +f 38944/38944/28551 38948/38948/28555 38949/38949/28556 +f 38945/38945/28552 38944/38944/28551 38949/38949/28556 +f 38945/38945/28552 38949/38949/28556 38864/38864/28477 +f 38950/38950/28557 38951/38951/28558 38952/38952/28559 +f 38950/38950/28557 38952/38952/28559 38953/38953/28560 +f 38954/38954/28561 38955/38955/28562 38956/38956/28563 +f 38954/38954/28561 38956/38956/28563 38957/38957/28559 +f 38957/38957/28559 38956/38956/28563 38958/38958/28564 +f 38957/38957/28559 38958/38958/28564 38959/38959/28565 +f 38953/38953/28560 38952/38952/28559 38960/38960/28566 +f 38953/38953/28560 38960/38960/28566 38961/38961/28567 +f 38950/38950/28557 38962/38962/28568 38963/38963/28569 +f 38950/38950/28557 38963/38963/28569 38964/38964/28570 +f 38962/38962/28568 38965/38965/28571 38966/38966/28572 +f 38962/38962/28568 38966/38966/28572 38963/38963/28569 +f 38963/38963/28569 38966/38966/28572 38967/38967/28573 +f 38963/38963/28569 38967/38967/28573 38968/38968/28574 +f 38964/38964/28570 38963/38963/28569 38968/38968/28574 +f 38964/38964/28570 38968/38968/28574 38969/38969/28575 +f 38970/38970/28576 38971/38971/28577 38972/38972/28578 +f 38970/38970/28576 38972/38972/28578 38973/38973/28579 +f 38974/38974/28580 38975/38975/28581 38976/38976/28582 +f 38974/38974/28580 38976/38976/28582 38977/38977/28583 +f 38977/38977/28583 38976/38976/28582 38978/38978/28584 +f 38977/38977/28583 38978/38978/28584 38979/38979/28585 +f 38973/38973/28579 38972/38972/28578 38980/38980/28586 +f 38973/38973/28579 38980/38980/28586 38981/38981/28587 +f 38982/38982/28588 38983/38983/28589 38984/38984/28590 +f 38982/38982/28588 38984/38984/28590 38985/38985/28591 +f 38983/38983/28589 38986/38986/28592 38987/38987/28593 +f 38983/38983/28589 38987/38987/28593 38984/38984/28590 +f 38984/38984/28590 38987/38987/28593 38917/38917/28524 +f 38984/38984/28590 38917/38917/28524 38920/38920/28527 +f 38985/38985/28591 38984/38984/28590 38920/38920/28527 +f 38985/38985/28591 38920/38920/28527 38925/38925/28532 +f 38988/38988/28592 38989/38989/28594 38990/38990/28595 +f 38988/38988/28592 38990/38990/28595 38991/38991/28593 +f 38989/38989/28594 38992/38992/28596 38993/38993/28597 +f 38989/38989/28594 38993/38993/28597 38990/38990/28595 +f 38990/38990/28595 38993/38993/28597 38994/38994/28598 +f 38990/38990/28595 38994/38994/28598 38995/38995/28599 +f 38987/38987/28593 38996/38996/28595 38997/38997/28599 +f 38987/38987/28593 38997/38997/28599 38917/38917/28524 +f 38925/38925/28532 38998/38998/28600 38999/38999/28601 +f 38925/38925/28532 38999/38999/28601 38985/38985/28591 +f 38998/38998/28600 39000/39000/28602 39001/39001/28603 +f 38998/38998/28600 39001/39001/28603 38999/38999/28601 +f 38999/38999/28601 39001/39001/28603 39002/39002/28604 +f 38999/38999/28601 39002/39002/28604 39003/39003/28605 +f 38985/38985/28591 38999/38999/28601 39003/39003/28605 +f 38985/38985/28591 39003/39003/28605 38982/38982/28588 +f 38819/38819/28436 39004/39004/28606 39005/39005/28607 +f 38819/38819/28436 39005/39005/28607 38820/38820/28437 +f 39004/39004/28606 39006/39006/28608 39007/39007/28609 +f 39004/39004/28606 39007/39007/28609 39005/39005/28607 +f 39005/39005/28607 39007/39007/28609 39008/39008/28610 +f 39005/39005/28607 39008/39008/28610 39009/39009/28611 +f 38820/38820/28437 39005/39005/28607 39009/39009/28611 +f 38820/38820/28437 39009/39009/28611 38821/38821/28438 +f 39010/39010/28612 39011/39011/28613 39012/39012/28614 +f 39010/39010/28612 39012/39012/28614 39013/39013/28615 +f 39011/39011/28613 39014/39014/28616 39015/39015/28617 +f 39011/39011/28613 39015/39015/28617 39012/39012/28614 +f 39012/39012/28614 39015/39015/28617 39016/39016/28618 +f 39012/39012/28614 39016/39016/28618 39017/39017/28619 +f 39013/39013/28615 39012/39012/28614 39017/39017/28619 +f 39013/39013/28615 39017/39017/28619 39018/39018/28620 +f 39019/39019/28486 39020/39020/28621 39021/39021/28622 +f 39019/39019/28486 39021/39021/28622 39022/39022/28623 +f 39020/39020/28621 39023/39023/28624 39024/39024/28625 +f 39020/39020/28621 39024/39024/28625 39021/39021/28622 +f 39021/39021/28622 39024/39024/28625 39025/39025/28626 +f 39021/39021/28622 39025/39025/28626 39026/39026/28627 +f 39022/39022/28623 39021/39021/28622 39026/39026/28627 +f 39022/39022/28623 39026/39026/28627 38981/38981/28587 +f 38896/38896/28504 38941/38941/28548 39027/39027/28628 +f 38896/38896/28504 39027/39027/28628 38897/38897/28505 +f 38941/38941/28548 38940/38940/28547 39028/39028/28629 +f 38941/38941/28548 39028/39028/28629 39027/39027/28628 +f 39027/39027/28628 39028/39028/28629 39029/39029/28630 +f 39027/39027/28628 39029/39029/28630 39030/39030/28631 +f 38897/38897/28505 39027/39027/28628 39030/39030/28631 +f 38897/38897/28505 39030/39030/28631 38900/38900/28508 +f 38819/38819/28436 39031/39031/28632 39032/39032/28633 +f 38819/38819/28436 39032/39032/28633 39004/39004/28606 +f 39033/39033/28632 39034/39034/28634 39035/39035/28635 +f 39033/39033/28632 39035/39035/28635 39036/39036/28636 +f 39036/39036/28636 39035/39035/28635 39037/39037/28637 +f 39036/39036/28636 39037/39037/28637 39038/39038/28638 +f 39004/39004/28606 39032/39032/28633 39039/39039/28638 +f 39004/39004/28606 39039/39039/28638 39006/39006/28608 +f 38961/38961/28567 38960/38960/28566 39040/39040/28639 +f 38961/38961/28567 39040/39040/28639 39041/39041/28640 +f 38959/38959/28565 38958/38958/28564 39042/39042/28641 +f 38959/38959/28565 39042/39042/28641 39043/39043/28642 +f 39043/39043/28642 39042/39042/28641 39044/39044/28643 +f 39043/39043/28642 39044/39044/28643 39045/39045/28644 +f 39041/39041/28640 39040/39040/28639 39046/39046/28645 +f 39041/39041/28640 39046/39046/28645 38796/38796/28413 +f 39047/39047/28646 39048/39048/28647 39049/39049/28648 +f 39047/39047/28646 39049/39049/28648 39050/39050/28649 +f 39048/39048/28647 39051/39051/28650 39052/39052/28651 +f 39048/39048/28647 39052/39052/28651 39049/39049/28648 +f 39049/39049/28648 39052/39052/28651 38916/38916/28523 +f 39049/39049/28648 38916/38916/28523 39053/39053/28652 +f 39050/39050/28649 39049/39049/28648 39053/39053/28652 +f 39050/39050/28649 39053/39053/28652 39054/39054/28653 +f 39055/39055/28654 39056/39056/28655 39057/39057/28656 +f 39055/39055/28654 39057/39057/28656 39058/39058/28657 +f 39056/39056/28655 39059/39059/28658 39060/39060/28659 +f 39056/39056/28655 39060/39060/28659 39057/39057/28656 +f 39057/39057/28656 39060/39060/28659 39061/39061/28660 +f 39057/39057/28656 39061/39061/28660 39062/39062/28661 +f 39058/39058/28657 39057/39057/28656 39062/39062/28661 +f 39058/39058/28657 39062/39062/28661 39063/39063/28662 +f 39064/39064/28663 39065/39065/28664 39066/39066/28665 +f 39064/39064/28663 39066/39066/28665 39067/39067/28666 +f 39068/39068/28667 39069/39069/28668 39070/39070/28669 +f 39068/39068/28667 39070/39070/28669 39071/39071/28665 +f 39071/39071/28665 39070/39070/28669 39072/39072/28670 +f 39071/39071/28665 39072/39072/28670 39073/39073/28671 +f 39067/39067/28666 39066/39066/28665 39074/39074/28672 +f 39067/39067/28666 39074/39074/28672 39075/39075/28673 +f 38872/38872/28485 38871/38871/28484 39076/39076/28674 +f 38872/38872/28485 39076/39076/28674 39077/39077/28675 +f 38871/38871/28484 38870/38870/28483 39078/39078/28676 +f 38871/38871/28484 39078/39078/28676 39076/39076/28674 +f 39076/39076/28674 39078/39078/28676 38992/38992/28596 +f 39076/39076/28674 38992/38992/28596 38989/38989/28594 +f 39077/39077/28675 39076/39076/28674 38989/38989/28594 +f 39077/39077/28675 38989/38989/28594 38988/38988/28592 +f 39079/39079/28677 39080/39080/28678 39081/39081/28679 +f 39079/39079/28677 39081/39081/28679 39082/39082/28680 +f 39080/39080/28678 39083/39083/28681 39084/39084/28682 +f 39080/39080/28678 39084/39084/28682 39081/39081/28679 +f 39085/39085/28679 39086/39086/28683 39087/39087/28684 +f 39085/39085/28679 39087/39087/28684 39088/39088/28685 +f 39089/39089/28686 39085/39085/28679 39088/39088/28685 +f 39089/39089/28686 39088/39088/28685 39090/39090/28687 +f 39091/39091/28688 39092/39092/28689 39093/39093/28690 +f 39091/39091/28688 39093/39093/28690 39094/39094/28691 +f 39092/39092/28689 39095/39095/28692 39096/39096/28693 +f 39092/39092/28689 39096/39096/28693 39093/39093/28690 +f 39093/39093/28690 39096/39096/28693 39097/39097/28620 +f 39093/39093/28690 39097/39097/28620 39098/39098/28694 +f 39094/39094/28691 39093/39093/28690 39098/39098/28694 +f 39094/39094/28691 39098/39098/28694 39099/39099/28695 +f 38982/38982/28588 39100/39100/28696 39101/39101/28697 +f 38982/38982/28588 39101/39101/28697 38983/38983/28589 +f 39100/39100/28696 39102/39102/28698 39103/39103/28699 +f 39100/39100/28696 39103/39103/28699 39101/39101/28697 +f 39101/39101/28697 39103/39103/28699 39104/39104/28700 +f 39101/39101/28697 39104/39104/28700 39105/39105/28701 +f 38983/38983/28589 39101/39101/28697 39105/39105/28701 +f 38983/38983/28589 39105/39105/28701 38986/38986/28592 +f 38970/38970/28576 39106/39106/28702 39107/39107/28703 +f 38970/38970/28576 39107/39107/28703 39108/39108/28704 +f 39106/39106/28702 39109/39109/28705 39110/39110/28706 +f 39106/39106/28702 39110/39110/28706 39107/39107/28703 +f 39107/39107/28703 39110/39110/28706 39111/39111/28707 +f 39107/39107/28703 39111/39111/28707 39112/39112/28708 +f 39108/39108/28704 39107/39107/28703 39112/39112/28708 +f 39108/39108/28704 39112/39112/28708 38862/38862/28475 +f 39113/39113/28709 39114/39114/28710 39115/39115/28711 +f 39113/39113/28709 39115/39115/28711 39116/39116/28712 +f 39114/39114/28710 39117/39117/28713 39118/39118/28714 +f 39114/39114/28710 39118/39118/28714 39115/39115/28711 +f 39119/39119/28711 39120/39120/28715 39121/39121/28716 +f 39119/39119/28711 39121/39121/28716 39122/39122/28717 +f 39123/39123/28718 39119/39119/28711 39122/39122/28717 +f 39123/39123/28718 39122/39122/28717 39124/39124/28719 +f 39125/39125/28720 39126/39126/28721 39127/39127/28722 +f 39125/39125/28720 39127/39127/28722 39128/39128/28723 +f 39126/39126/28721 39129/39129/28724 39130/39130/28725 +f 39126/39126/28721 39130/39130/28725 39127/39127/28722 +f 39131/39131/28726 39132/39132/28725 39133/39133/28727 +f 39131/39131/28726 39133/39133/28727 39134/39134/28728 +f 39135/39135/28729 39131/39131/28726 39134/39134/28728 +f 39135/39135/28729 39134/39134/28728 39136/39136/28730 +f 39136/39136/28730 39134/39134/28728 39137/39137/28731 +f 39136/39136/28730 39137/39137/28731 39138/39138/28732 +f 39134/39134/28728 39133/39133/28727 39139/39139/28733 +f 39134/39134/28728 39139/39139/28733 39137/39137/28731 +f 39137/39137/28731 39139/39139/28733 39140/39140/28734 +f 39137/39137/28731 39140/39140/28734 39141/39141/28735 +f 39138/39138/28732 39137/39137/28731 39141/39141/28735 +f 39138/39138/28732 39141/39141/28735 39142/39142/28736 +f 39090/39090/28687 39088/39088/28685 39143/39143/28737 +f 39090/39090/28687 39143/39143/28737 39144/39144/28738 +f 39088/39088/28685 39087/39087/28684 39145/39145/28739 +f 39088/39088/28685 39145/39145/28739 39143/39143/28737 +f 39143/39143/28737 39145/39145/28739 39146/39146/28740 +f 39143/39143/28737 39146/39146/28740 39147/39147/28741 +f 39144/39144/28738 39143/39143/28737 39147/39147/28741 +f 39144/39144/28738 39147/39147/28741 39148/39148/28742 +f 39149/39149/28743 39150/39150/28744 39151/39151/28745 +f 39149/39149/28743 39151/39151/28745 39152/39152/28746 +f 39150/39150/28744 39153/39153/28747 39154/39154/28748 +f 39150/39150/28744 39154/39154/28748 39151/39151/28745 +f 39151/39151/28745 39154/39154/28748 39155/39155/28749 +f 39151/39151/28745 39155/39155/28749 39156/39156/28750 +f 39152/39152/28746 39151/39151/28745 39156/39156/28750 +f 39152/39152/28746 39156/39156/28750 39157/39157/28751 +f 39158/39158/28752 39159/39159/28753 39160/39160/28754 +f 39158/39158/28752 39160/39160/28754 39161/39161/28755 +f 39159/39159/28753 39162/39162/28756 39163/39163/28757 +f 39159/39159/28753 39163/39163/28757 39160/39160/28754 +f 39160/39160/28754 39163/39163/28757 39164/39164/28758 +f 39160/39160/28754 39164/39164/28758 39165/39165/28759 +f 39161/39161/28755 39160/39160/28754 39165/39165/28759 +f 39161/39161/28755 39165/39165/28759 39166/39166/28760 +f 39167/39167/28760 39168/39168/28761 39169/39169/28762 +f 39167/39167/28760 39169/39169/28762 39170/39170/28763 +f 39168/39168/28761 39171/39171/28764 39172/39172/28765 +f 39168/39168/28761 39172/39172/28765 39169/39169/28762 +f 39169/39169/28762 39172/39172/28765 39173/39173/28766 +f 39169/39169/28762 39173/39173/28766 39174/39174/28767 +f 39170/39170/28763 39169/39169/28762 39174/39174/28767 +f 39170/39170/28763 39174/39174/28767 39175/39175/28768 +f 39124/39124/28719 39122/39122/28717 39176/39176/28769 +f 39124/39124/28719 39176/39176/28769 39177/39177/28770 +f 39122/39122/28717 39121/39121/28716 39178/39178/28771 +f 39122/39122/28717 39178/39178/28771 39176/39176/28769 +f 39176/39176/28769 39178/39178/28771 39179/39179/28772 +f 39176/39176/28769 39179/39179/28772 39180/39180/28773 +f 39177/39177/28770 39176/39176/28769 39180/39180/28773 +f 39177/39177/28770 39180/39180/28773 39181/39181/28774 +f 39182/39182/28775 39183/39183/28776 39184/39184/28777 +f 39182/39182/28775 39184/39184/28777 39185/39185/28778 +f 39183/39183/28776 39186/39186/28779 39187/39187/28780 +f 39183/39183/28776 39187/39187/28780 39184/39184/28777 +f 39188/39188/28781 39189/39189/28780 39190/39190/28782 +f 39188/39188/28781 39190/39190/28782 39191/39191/28783 +f 39192/39192/28784 39188/39188/28781 39191/39191/28783 +f 39192/39192/28784 39191/39191/28783 39193/39193/28785 +f 39121/39121/28716 39194/39194/28786 39195/39195/28787 +f 39121/39121/28716 39195/39195/28787 39178/39178/28771 +f 39194/39194/28786 39193/39193/28785 39196/39196/28788 +f 39194/39194/28786 39196/39196/28788 39195/39195/28787 +f 39195/39195/28787 39196/39196/28788 39197/39197/28789 +f 39195/39195/28787 39197/39197/28789 39198/39198/28790 +f 39178/39178/28771 39195/39195/28787 39198/39198/28790 +f 39178/39178/28771 39198/39198/28790 39179/39179/28772 +f 39117/39117/28713 39199/39199/28791 39200/39200/28792 +f 39117/39117/28713 39200/39200/28792 39118/39118/28714 +f 39199/39199/28791 39182/39182/28775 39185/39185/28778 +f 39199/39199/28791 39185/39185/28778 39200/39200/28792 +f 39201/39201/28792 39192/39192/28784 39193/39193/28785 +f 39201/39201/28792 39193/39193/28785 39194/39194/28786 +f 39120/39120/28715 39201/39201/28792 39194/39194/28786 +f 39120/39120/28715 39194/39194/28786 39121/39121/28716 +f 39162/39162/28756 39202/39202/28793 39203/39203/28794 +f 39162/39162/28756 39203/39203/28794 39163/39163/28757 +f 39202/39202/28793 39204/39204/28795 39205/39205/28796 +f 39202/39202/28793 39205/39205/28796 39203/39203/28794 +f 39206/39206/28794 39207/39207/28796 39153/39153/28747 +f 39206/39206/28794 39153/39153/28747 39150/39150/28744 +f 39208/39208/28797 39206/39206/28794 39150/39150/28744 +f 39208/39208/28797 39150/39150/28744 39149/39149/28743 +f 39209/39209/28798 39210/39210/28799 39211/39211/28800 +f 39209/39209/28798 39211/39211/28800 39212/39212/28801 +f 39210/39210/28799 39213/39213/28802 39214/39214/28803 +f 39210/39210/28799 39214/39214/28803 39211/39211/28800 +f 39215/39215/28800 39216/39216/28804 39217/39217/28805 +f 39215/39215/28800 39217/39217/28805 39218/39218/28806 +f 39219/39219/28801 39215/39215/28800 39218/39218/28806 +f 39219/39219/28801 39218/39218/28806 39220/39220/28807 +f 39204/39204/28795 39221/39221/28808 39222/39222/28809 +f 39204/39204/28795 39222/39222/28809 39205/39205/28796 +f 39221/39221/28808 39209/39209/28798 39212/39212/28801 +f 39221/39221/28808 39212/39212/28801 39222/39222/28809 +f 39223/39223/28809 39224/39224/28801 39225/39225/28807 +f 39223/39223/28809 39225/39225/28807 39226/39226/28810 +f 39207/39207/28796 39223/39223/28809 39226/39226/28810 +f 39207/39207/28796 39226/39226/28810 39153/39153/28747 +f 39153/39153/28747 39226/39226/28810 39227/39227/28811 +f 39153/39153/28747 39227/39227/28811 39154/39154/28748 +f 39226/39226/28810 39225/39225/28807 39228/39228/28812 +f 39226/39226/28810 39228/39228/28812 39227/39227/28811 +f 39227/39227/28811 39228/39228/28812 39229/39229/28813 +f 39227/39227/28811 39229/39229/28813 39230/39230/28814 +f 39154/39154/28748 39227/39227/28811 39230/39230/28814 +f 39154/39154/28748 39230/39230/28814 39155/39155/28749 +f 39193/39193/28785 39191/39191/28783 39231/39231/28815 +f 39193/39193/28785 39231/39231/28815 39196/39196/28788 +f 39191/39191/28783 39190/39190/28782 39232/39232/28816 +f 39191/39191/28783 39232/39232/28816 39231/39231/28815 +f 39231/39231/28815 39232/39232/28816 39233/39233/28817 +f 39231/39231/28815 39233/39233/28817 39234/39234/28818 +f 39196/39196/28788 39231/39231/28815 39234/39234/28818 +f 39196/39196/28788 39234/39234/28818 39197/39197/28789 +f 39217/39217/28805 39235/39235/28819 39236/39236/28820 +f 39217/39217/28805 39236/39236/28820 39237/39237/28821 +f 39235/39235/28819 39238/39238/28822 39239/39239/28823 +f 39235/39235/28819 39239/39239/28823 39236/39236/28820 +f 39236/39236/28820 39239/39239/28823 39240/39240/28824 +f 39236/39236/28820 39240/39240/28824 39241/39241/28825 +f 39237/39237/28821 39236/39236/28820 39241/39241/28825 +f 39237/39237/28821 39241/39241/28825 39242/39242/28826 +f 39220/39220/28807 39218/39218/28806 39243/39243/28827 +f 39220/39220/28807 39243/39243/28827 39244/39244/28812 +f 39218/39218/28806 39217/39217/28805 39237/39237/28821 +f 39218/39218/28806 39237/39237/28821 39243/39243/28827 +f 39243/39243/28827 39237/39237/28821 39242/39242/28826 +f 39243/39243/28827 39242/39242/28826 39245/39245/28828 +f 39244/39244/28812 39243/39243/28827 39245/39245/28828 +f 39244/39244/28812 39245/39245/28828 39246/39246/28813 +f 39247/39247/28829 39248/39248/28830 39249/39249/28831 +f 39247/39247/28829 39249/39249/28831 39250/39250/28816 +f 39248/39248/28830 39251/39251/28832 39252/39252/28833 +f 39248/39248/28830 39252/39252/28833 39249/39249/28831 +f 39249/39249/28831 39252/39252/28833 39253/39253/28834 +f 39249/39249/28831 39253/39253/28834 39254/39254/28835 +f 39250/39250/28816 39249/39249/28831 39254/39254/28835 +f 39250/39250/28816 39254/39254/28835 39255/39255/28817 +f 39186/39186/28779 39256/39256/28836 39257/39257/28837 +f 39186/39186/28779 39257/39257/28837 39187/39187/28780 +f 39256/39256/28836 39258/39258/28838 39259/39259/28839 +f 39256/39256/28836 39259/39259/28839 39257/39257/28837 +f 39260/39260/28837 39261/39261/28839 39251/39251/28832 +f 39260/39260/28837 39251/39251/28832 39248/39248/28830 +f 39262/39262/28780 39260/39260/28837 39248/39248/28830 +f 39262/39262/28780 39248/39248/28830 39247/39247/28829 +f 39263/39263/28840 39264/39264/28841 39265/39265/28842 +f 39263/39263/28840 39265/39265/28842 39266/39266/28843 +f 39264/39264/28841 39267/39267/28844 39268/39268/28845 +f 39264/39264/28841 39268/39268/28845 39265/39265/28842 +f 39269/39269/28842 39270/39270/28845 39271/39271/28846 +f 39269/39269/28842 39271/39271/28846 39272/39272/28847 +f 39273/39273/28843 39269/39269/28842 39272/39272/28847 +f 39273/39273/28843 39272/39272/28847 39274/39274/28848 +f 39251/39251/28832 39275/39275/28849 39276/39276/28850 +f 39251/39251/28832 39276/39276/28850 39252/39252/28833 +f 39275/39275/28849 39274/39274/28848 39277/39277/28851 +f 39275/39275/28849 39277/39277/28851 39276/39276/28850 +f 39276/39276/28850 39277/39277/28851 39278/39278/28852 +f 39276/39276/28850 39278/39278/28852 39279/39279/28853 +f 39252/39252/28833 39276/39276/28850 39279/39279/28853 +f 39252/39252/28833 39279/39279/28853 39253/39253/28834 +f 39258/39258/28838 39280/39280/28854 39281/39281/28855 +f 39258/39258/28838 39281/39281/28855 39259/39259/28839 +f 39280/39280/28854 39263/39263/28840 39266/39266/28843 +f 39280/39280/28854 39266/39266/28843 39281/39281/28855 +f 39282/39282/28856 39273/39273/28843 39274/39274/28848 +f 39282/39282/28856 39274/39274/28848 39275/39275/28849 +f 39261/39261/28839 39282/39282/28856 39275/39275/28849 +f 39261/39261/28839 39275/39275/28849 39251/39251/28832 +f 39213/39213/28802 39283/39283/28857 39284/39284/28858 +f 39213/39213/28802 39284/39284/28858 39214/39214/28803 +f 39283/39283/28857 39285/39285/28859 39286/39286/28860 +f 39283/39283/28857 39286/39286/28860 39284/39284/28858 +f 39287/39287/28861 39288/39288/28862 39238/39238/28822 +f 39287/39287/28861 39238/39238/28822 39235/39235/28819 +f 39216/39216/28804 39287/39287/28861 39235/39235/28819 +f 39216/39216/28804 39235/39235/28819 39217/39217/28805 +f 39271/39271/28846 39289/39289/28863 39290/39290/28864 +f 39271/39271/28846 39290/39290/28864 39291/39291/28865 +f 39289/39289/28863 39292/39292/28866 39293/39293/28867 +f 39289/39289/28863 39293/39293/28867 39290/39290/28864 +f 39290/39290/28864 39293/39293/28867 39294/39294/28868 +f 39290/39290/28864 39294/39294/28868 39295/39295/28869 +f 39291/39291/28865 39290/39290/28864 39295/39295/28869 +f 39291/39291/28865 39295/39295/28869 39296/39296/28870 +f 39285/39285/28859 39297/39297/28871 39298/39298/28872 +f 39285/39285/28859 39298/39298/28872 39286/39286/28860 +f 39297/39297/28871 39299/39299/28873 39300/39300/28874 +f 39297/39297/28871 39300/39300/28874 39298/39298/28872 +f 39301/39301/28872 39302/39302/28875 39303/39303/28876 +f 39301/39301/28872 39303/39303/28876 39304/39304/28877 +f 39288/39288/28862 39305/39305/28872 39306/39306/28877 +f 39288/39288/28862 39306/39306/28877 39238/39238/28822 +f 39238/39238/28822 39306/39306/28877 39307/39307/28878 +f 39238/39238/28822 39307/39307/28878 39239/39239/28823 +f 39304/39304/28877 39303/39303/28876 39308/39308/28879 +f 39304/39304/28877 39308/39308/28879 39309/39309/28878 +f 39309/39309/28878 39308/39308/28879 39310/39310/28880 +f 39309/39309/28878 39310/39310/28880 39311/39311/28881 +f 39239/39239/28823 39307/39307/28878 39312/39312/28881 +f 39239/39239/28823 39312/39312/28881 39240/39240/28824 +f 39274/39274/28848 39272/39272/28847 39313/39313/28882 +f 39274/39274/28848 39313/39313/28882 39277/39277/28851 +f 39272/39272/28847 39271/39271/28846 39291/39291/28865 +f 39272/39272/28847 39291/39291/28865 39313/39313/28882 +f 39313/39313/28882 39291/39291/28865 39296/39296/28870 +f 39313/39313/28882 39296/39296/28870 39314/39314/28883 +f 39277/39277/28851 39313/39313/28882 39314/39314/28883 +f 39277/39277/28851 39314/39314/28883 39278/39278/28852 +f 39315/39315/28884 39316/39316/28885 39317/39317/28886 +f 39315/39315/28884 39317/39317/28886 39318/39318/28887 +f 39316/39316/28885 39319/39319/28441 39320/39320/28471 +f 39316/39316/28885 39320/39320/28471 39317/39317/28886 +f 39317/39317/28886 39320/39320/28471 39321/39321/28888 +f 39317/39317/28886 39321/39321/28888 39322/39322/28889 +f 39318/39318/28887 39317/39317/28886 39322/39322/28889 +f 39318/39318/28887 39322/39322/28889 39323/39323/28890 +f 39324/39324/28891 39325/39325/28892 39326/39326/28893 +f 39324/39324/28891 39326/39326/28893 39327/39327/28894 +f 39325/39325/28892 39328/39328/28895 39329/39329/28896 +f 39325/39325/28892 39329/39329/28896 39326/39326/28893 +f 39326/39326/28893 39329/39329/28896 39330/39330/28897 +f 39326/39326/28893 39330/39330/28897 39331/39331/28898 +f 39327/39327/28894 39326/39326/28893 39331/39331/28898 +f 39327/39327/28894 39331/39331/28898 39332/39332/28899 +f 39333/39333/28900 39334/39334/28901 39335/39335/28902 +f 39333/39333/28900 39335/39335/28902 39336/39336/28903 +f 39334/39334/28901 39337/39337/28904 39338/39338/28905 +f 39334/39334/28901 39338/39338/28905 39335/39335/28902 +f 39335/39335/28902 39338/39338/28905 39339/39339/28547 +f 39335/39335/28902 39339/39339/28547 39340/39340/28546 +f 39336/39336/28903 39335/39335/28902 39340/39340/28546 +f 39336/39336/28903 39340/39340/28546 39341/39341/28545 +f 39342/39342/28906 39343/39343/28907 39344/39344/28908 +f 39342/39342/28906 39344/39344/28908 39345/39345/28909 +f 39343/39343/28907 39346/39346/28910 39347/39347/28911 +f 39343/39343/28907 39347/39347/28911 39344/39344/28908 +f 39348/39348/28912 39349/39349/28913 39350/39350/28914 +f 39348/39348/28912 39350/39350/28914 39351/39351/28915 +f 39352/39352/28909 39348/39348/28912 39351/39351/28915 +f 39352/39352/28909 39351/39351/28915 38794/38794/28411 +f 39353/39353/28916 39354/39354/28917 39355/39355/28918 +f 39353/39353/28916 39355/39355/28918 39356/39356/28919 +f 39354/39354/28917 39342/39342/28906 39345/39345/28909 +f 39354/39354/28917 39345/39345/28909 39355/39355/28918 +f 39355/39355/28918 39345/39345/28909 39357/39357/28920 +f 39355/39355/28918 39357/39357/28920 39358/39358/28410 +f 39356/39356/28919 39355/39355/28918 39358/39358/28410 +f 39356/39356/28919 39358/39358/28410 39359/39359/28409 +f 39337/39337/28904 39360/39360/28921 39361/39361/28922 +f 39337/39337/28904 39361/39361/28922 39338/39338/28905 +f 39360/39360/28921 39362/39362/28923 39363/39363/28924 +f 39360/39360/28921 39363/39363/28924 39361/39361/28922 +f 39364/39364/28925 39365/39365/28924 39029/39029/28630 +f 39364/39364/28925 39029/39029/28630 39028/39028/28629 +f 39338/39338/28905 39361/39361/28922 39366/39366/28629 +f 39338/39338/28905 39366/39366/28629 39339/39339/28547 +f 39367/39367/28926 39368/39368/28927 39369/39369/28928 +f 39367/39367/28926 39369/39369/28928 39370/39370/28929 +f 39368/39368/28927 39371/39371/28930 39372/39372/28931 +f 39368/39368/28927 39372/39372/28931 39369/39369/28928 +f 39373/39373/28932 39374/39374/28931 39104/39104/28700 +f 39373/39373/28932 39104/39104/28700 39103/39103/28699 +f 39375/39375/28933 39373/39373/28932 39103/39103/28699 +f 39375/39375/28933 39103/39103/28699 39102/39102/28698 +f 39362/39362/28923 39376/39376/28934 39377/39377/28935 +f 39362/39362/28923 39377/39377/28935 39363/39363/28924 +f 39376/39376/28934 39367/39367/28926 39370/39370/28929 +f 39376/39376/28934 39370/39370/28929 39377/39377/28935 +f 39378/39378/28936 39375/39375/28933 39102/39102/28698 +f 39378/39378/28936 39102/39102/28698 39379/39379/28937 +f 39365/39365/28924 39378/39378/28936 39379/39379/28937 +f 39365/39365/28924 39379/39379/28937 39029/39029/28630 +f 39346/39346/28910 39380/39380/28938 39381/39381/28939 +f 39346/39346/28910 39381/39381/28939 39347/39347/28911 +f 39380/39380/28938 39382/39382/28940 39383/39383/28941 +f 39380/39380/28938 39383/39383/28941 39381/39381/28939 +f 39384/39384/28942 39385/39385/28943 38965/38965/28571 +f 39384/39384/28942 38965/38965/28571 39386/39386/28944 +f 39349/39349/28913 39384/39384/28942 39386/39386/28944 +f 39349/39349/28913 39386/39386/28944 39350/39350/28914 +f 39382/39382/28940 39387/39387/28945 39388/39388/28946 +f 39382/39382/28940 39388/39388/28946 39383/39383/28941 +f 39387/39387/28945 39389/39389/28947 39390/39390/28948 +f 39387/39387/28945 39390/39390/28948 39388/39388/28946 +f 39388/39388/28946 39390/39390/28948 39391/39391/28573 +f 39388/39388/28946 39391/39391/28573 39392/39392/28572 +f 39385/39385/28943 39393/39393/28946 38966/38966/28572 +f 39385/39385/28943 38966/38966/28572 38965/38965/28571 +f 39371/39371/28930 39394/39394/28949 39395/39395/28950 +f 39371/39371/28930 39395/39395/28950 39372/39372/28931 +f 39394/39394/28949 39396/39396/28951 39397/39397/28952 +f 39394/39394/28949 39397/39397/28952 39395/39395/28950 +f 39398/39398/28953 39399/39399/28952 39400/39400/28954 +f 39398/39398/28953 39400/39400/28954 39401/39401/28955 +f 39372/39372/28931 39395/39395/28950 39402/39402/28955 +f 39372/39372/28931 39402/39402/28955 39403/39403/28700 +f 39389/39389/28947 39404/39404/28956 39405/39405/28957 +f 39389/39389/28947 39405/39405/28957 39390/39390/28948 +f 39404/39404/28956 39406/39406/28958 39407/39407/28959 +f 39404/39404/28956 39407/39407/28959 39405/39405/28957 +f 39405/39405/28957 39407/39407/28959 39408/39408/28960 +f 39405/39405/28957 39408/39408/28960 39409/39409/28961 +f 39390/39390/28948 39405/39405/28957 39409/39409/28961 +f 39390/39390/28948 39409/39409/28961 39391/39391/28573 +f 39410/39410/28962 39411/39411/28963 39412/39412/28964 +f 39410/39410/28962 39412/39412/28964 39413/39413/28965 +f 39411/39411/28963 39414/39414/28966 39415/39415/28967 +f 39411/39411/28963 39415/39415/28967 39412/39412/28964 +f 39416/39416/28964 39417/39417/28968 39418/39418/28969 +f 39416/39416/28964 39418/39418/28969 39419/39419/28970 +f 39420/39420/28965 39416/39416/28964 39419/39419/28970 +f 39420/39420/28965 39419/39419/28970 39421/39421/28971 +f 39422/39422/28972 39423/39423/28973 39424/39424/28974 +f 39422/39422/28972 39424/39424/28974 39425/39425/28975 +f 39423/39423/28973 39426/39426/28976 39427/39427/28977 +f 39423/39423/28973 39427/39427/28977 39424/39424/28974 +f 39428/39428/28974 39429/39429/28977 38849/38849/28464 +f 39428/39428/28974 38849/38849/28464 38848/38848/28463 +f 39430/39430/28975 39428/39428/28974 38848/38848/28463 +f 39430/39430/28975 38848/38848/28463 38847/38847/28462 +f 39431/39431/28978 39432/39432/28979 39433/39433/28980 +f 39431/39431/28978 39433/39433/28980 39434/39434/28981 +f 39432/39432/28979 39435/39435/28982 39436/39436/28983 +f 39432/39432/28979 39436/39436/28983 39433/39433/28980 +f 39437/39437/28980 39438/39438/28984 39439/39439/28985 +f 39437/39437/28980 39439/39439/28985 39440/39440/28986 +f 39441/39441/28987 39437/39437/28980 39440/39440/28986 +f 39441/39441/28987 39440/39440/28986 39442/39442/28988 +f 39443/39443/28989 39444/39444/28990 39445/39445/28991 +f 39443/39443/28989 39445/39445/28991 39446/39446/28992 +f 39444/39444/28990 39447/39447/28993 39448/39448/28994 +f 39444/39444/28990 39448/39448/28994 39445/39445/28991 +f 39445/39445/28991 39448/39448/28994 39449/39449/28995 +f 39445/39445/28991 39449/39449/28995 39450/39450/28996 +f 39451/39451/28997 39452/39452/28998 39453/39453/28996 +f 39451/39451/28997 39453/39453/28996 39454/39454/28999 +f 39455/39455/29000 39456/39456/29001 39457/39457/29002 +f 39455/39455/29000 39457/39457/29002 39458/39458/29003 +f 39459/39459/29001 38909/38909/28517 39460/39460/29004 +f 39459/39459/29001 39460/39460/29004 39461/39461/29002 +f 39461/39461/29002 39460/39460/29004 39462/39462/29005 +f 39461/39461/29002 39462/39462/29005 39463/39463/29006 +f 39464/39464/29007 39465/39465/29008 39466/39466/29009 +f 39464/39464/29007 39466/39466/29009 39467/39467/29010 +f 39468/39468/29011 39469/39469/29012 39470/39470/29013 +f 39468/39468/29011 39470/39470/29013 39471/39471/29014 +f 39469/39469/29012 39472/39472/29015 39473/39473/29016 +f 39469/39469/29012 39473/39473/29016 39470/39470/29013 +f 39474/39474/29017 39475/39475/29016 39476/39476/29018 +f 39474/39474/29017 39476/39476/29018 39477/39477/29019 +f 39478/39478/29020 39474/39474/29017 39477/39477/29019 +f 39478/39478/29020 39477/39477/29019 39479/39479/29021 +f 39480/39480/29022 39481/39481/29023 39482/39482/29024 +f 39480/39480/29022 39482/39482/29024 39483/39483/29025 +f 39481/39481/29023 39484/39484/29026 39485/39485/29027 +f 39481/39481/29023 39485/39485/29027 39482/39482/29024 +f 39486/39486/29024 39487/39487/29027 39488/39488/29028 +f 39486/39486/29024 39488/39488/29028 39489/39489/29029 +f 39490/39490/29030 39486/39486/29024 39489/39489/29029 +f 39490/39490/29030 39489/39489/29029 38895/38895/28503 +f 38981/38981/28587 39026/39026/28627 39491/39491/29031 +f 38981/38981/28587 39491/39491/29031 38973/38973/28579 +f 39026/39026/28627 39025/39025/28626 39492/39492/29032 +f 39026/39026/28627 39492/39492/29032 39491/39491/29031 +f 39491/39491/29031 39492/39492/29032 39109/39109/28705 +f 39491/39491/29031 39109/39109/28705 39106/39106/28702 +f 38973/38973/28579 39491/39491/29031 39106/39106/28702 +f 38973/38973/28579 39106/39106/28702 38970/38970/28576 +f 39493/39493/29033 39494/39494/29034 39495/39495/29035 +f 39493/39493/29033 39495/39495/29035 39496/39496/29036 +f 39494/39494/29034 39442/39442/28988 39440/39440/28986 +f 39494/39494/29034 39440/39440/28986 39495/39495/29035 +f 39495/39495/29035 39440/39440/28986 39439/39439/28985 +f 39495/39495/29035 39439/39439/28985 39497/39497/29037 +f 39496/39496/29036 39495/39495/29035 39497/39497/29037 +f 39496/39496/29036 39497/39497/29037 39498/39498/29038 +f 38926/38926/28533 39499/39499/29039 39500/39500/29040 +f 38926/38926/28533 39500/39500/29040 39501/39501/29041 +f 39499/39499/29039 39502/39502/29042 39503/39503/29043 +f 39499/39499/29039 39503/39503/29043 39500/39500/29040 +f 39500/39500/29040 39503/39503/29043 38855/38855/28470 +f 39500/39500/29040 38855/38855/28470 38854/38854/28469 +f 39501/39501/29041 39500/39500/29040 38854/38854/28469 +f 39501/39501/29041 38854/38854/28469 39504/39504/28422 +f 39047/39047/28646 39505/39505/29044 39506/39506/29045 +f 39047/39047/28646 39506/39506/29045 39048/39048/28647 +f 39505/39505/29044 39479/39479/29021 39477/39477/29019 +f 39505/39505/29044 39477/39477/29019 39506/39506/29045 +f 39506/39506/29045 39477/39477/29019 39476/39476/29018 +f 39506/39506/29045 39476/39476/29018 39507/39507/29046 +f 39048/39048/28647 39506/39506/29045 39507/39507/29046 +f 39048/39048/28647 39507/39507/29046 39051/39051/28650 +f 38801/38801/28418 39508/39508/29047 39509/39509/29048 +f 38801/38801/28418 39509/39509/29048 38802/38802/28419 +f 39508/39508/29047 39510/39510/29049 39511/39511/29050 +f 39508/39508/29047 39511/39511/29050 39509/39509/29048 +f 39509/39509/29048 39511/39511/29050 39512/39512/29051 +f 39509/39509/29048 39512/39512/29051 39513/39513/29052 +f 38802/38802/28419 39509/39509/29048 39513/39513/29052 +f 38802/38802/28419 39513/39513/29052 38803/38803/28420 +f 38961/38961/28567 39514/39514/29053 39515/39515/29054 +f 38961/38961/28567 39515/39515/29054 38953/38953/28560 +f 39514/39514/29053 39350/39350/28914 39386/39386/28944 +f 39514/39514/29053 39386/39386/28944 39515/39515/29054 +f 39515/39515/29054 39386/39386/28944 38965/38965/28571 +f 39515/39515/29054 38965/38965/28571 38962/38962/28568 +f 38953/38953/28560 39515/39515/29054 38962/38962/28568 +f 38953/38953/28560 38962/38962/28568 38950/38950/28557 +f 39516/39516/29055 39517/39517/29056 39518/39518/29057 +f 39516/39516/29055 39518/39518/29057 39519/39519/29058 +f 39517/39517/29056 39520/39520/29059 39521/39521/29060 +f 39517/39517/29056 39521/39521/29060 39518/39518/29057 +f 39518/39518/29057 39521/39521/29060 39522/39522/29061 +f 39518/39518/29057 39522/39522/29061 39523/39523/29062 +f 39519/39519/29058 39518/39518/29057 39523/39523/29062 +f 39519/39519/29058 39523/39523/29062 39524/39524/29063 +f 39324/39324/28891 39525/39525/29064 39526/39526/29065 +f 39324/39324/28891 39526/39526/29065 39325/39325/28892 +f 39525/39525/29064 39527/39527/29066 39528/39528/29067 +f 39525/39525/29064 39528/39528/29067 39526/39526/29065 +f 39529/39529/29068 39530/39530/29067 39531/39531/29069 +f 39529/39529/29068 39531/39531/29069 39532/39532/29070 +f 39325/39325/28892 39526/39526/29065 39533/39533/29071 +f 39325/39325/28892 39533/39533/29071 39328/39328/28895 +f 38925/38925/28532 38924/38924/28531 39534/39534/29072 +f 38925/38925/28532 39534/39534/29072 39535/39535/29073 +f 38924/38924/28531 38923/38923/28530 39536/39536/29074 +f 38924/38924/28531 39536/39536/29074 39534/39534/29072 +f 39534/39534/29072 39536/39536/29074 39537/39537/29075 +f 39534/39534/29072 39537/39537/29075 39538/39538/29076 +f 39535/39535/29073 39534/39534/29072 39538/39538/29076 +f 39535/39535/29073 39538/39538/29076 38902/38902/28510 +f 38814/38814/28431 38813/38813/28430 39539/39539/29077 +f 38814/38814/28431 39539/39539/29077 38876/38876/28489 +f 38813/38813/28430 38812/38812/28429 39540/39540/29078 +f 38813/38813/28430 39540/39540/29078 39539/39539/29077 +f 39539/39539/29077 39540/39540/29078 39541/39541/28624 +f 39539/39539/29077 39541/39541/28624 39542/39542/28621 +f 38876/38876/28489 39539/39539/29077 39542/39542/28621 +f 38876/38876/28489 39542/39542/28621 38873/38873/28486 +f 39091/39091/28688 39543/39543/29079 39544/39544/29080 +f 39091/39091/28688 39544/39544/29080 39092/39092/28689 +f 39543/39543/29079 39467/39467/29010 39466/39466/29009 +f 39543/39543/29079 39466/39466/29009 39544/39544/29080 +f 39545/39545/29080 39463/39463/29006 39462/39462/29005 +f 39545/39545/29080 39462/39462/29005 39546/39546/29081 +f 39547/39547/28689 39545/39545/29080 39546/39546/29081 +f 39547/39547/28689 39546/39546/29081 39548/39548/29082 +f 38900/38900/28508 39030/39030/28631 39549/39549/29083 +f 38900/38900/28508 39549/39549/29083 39550/39550/29084 +f 39030/39030/28631 39029/39029/28630 39379/39379/28937 +f 39030/39030/28631 39379/39379/28937 39549/39549/29083 +f 39549/39549/29083 39379/39379/28937 39102/39102/28698 +f 39549/39549/29083 39102/39102/28698 39100/39100/28696 +f 39550/39550/29084 39549/39549/29083 39100/39100/28696 +f 39550/39550/29084 39100/39100/28696 38982/38982/28588 +f 39551/39551/28575 39552/39552/28574 39553/39553/29085 +f 39551/39551/28575 39553/39553/29085 39554/39554/29086 +f 39552/39552/28574 39555/39555/28573 39556/39556/28961 +f 39552/39552/28574 39556/39556/28961 39553/39553/29085 +f 39553/39553/29085 39556/39556/28961 39557/39557/28960 +f 39553/39553/29085 39557/39557/28960 39558/39558/29087 +f 39554/39554/29086 39553/39553/29085 39558/39558/29087 +f 39554/39554/29086 39558/39558/29087 39559/39559/29088 +f 38823/38823/28440 38842/38842/28457 39560/39560/29089 +f 38823/38823/28440 39560/39560/29089 38818/38818/28435 +f 38842/38842/28457 38841/38841/28456 39561/39561/28896 +f 38842/38842/28457 39561/39561/28896 39560/39560/29089 +f 39560/39560/29089 39561/39561/28896 39562/39562/28895 +f 39560/39560/29089 39562/39562/28895 39563/39563/29090 +f 38818/38818/28435 39560/39560/29089 39563/39563/29090 +f 38818/38818/28435 39563/39563/29090 38815/38815/28432 +f 38864/38864/28477 38949/38949/28556 39564/39564/29091 +f 38864/38864/28477 39564/39564/29091 39565/39565/29092 +f 38949/38949/28556 38948/38948/28555 39566/39566/29093 +f 38949/38949/28556 39566/39566/29093 39564/39564/29091 +f 39564/39564/29091 39566/39566/29093 39567/39567/28528 +f 39564/39564/29091 39567/39567/28528 39568/39568/28525 +f 39565/39565/29092 39564/39564/29091 39568/39568/28525 +f 39565/39565/29092 39568/39568/28525 39569/39569/28524 +f 39570/39570/29094 39571/39571/29095 39572/39572/29096 +f 39570/39570/29094 39572/39572/29096 39573/39573/29097 +f 39571/39571/29095 39421/39421/28971 39419/39419/28970 +f 39571/39571/29095 39419/39419/28970 39572/39572/29096 +f 39572/39572/29096 39419/39419/28970 39418/39418/28969 +f 39572/39572/29096 39418/39418/28969 39574/39574/29098 +f 39573/39573/29097 39572/39572/29096 39574/39574/29098 +f 39573/39573/29097 39574/39574/29098 39575/39575/29099 +f 38796/38796/28413 38795/38795/28412 39576/39576/29100 +f 38796/38796/28413 39576/39576/29100 39041/39041/28640 +f 38795/38795/28412 38794/38794/28411 39351/39351/28915 +f 38795/38795/28412 39351/39351/28915 39576/39576/29100 +f 39576/39576/29100 39351/39351/28915 39350/39350/28914 +f 39576/39576/29100 39350/39350/28914 39514/39514/29053 +f 39041/39041/28640 39576/39576/29100 39514/39514/29053 +f 39041/39041/28640 39514/39514/29053 38961/38961/28567 +f 38988/38988/28592 39577/39577/28701 39578/39578/29101 +f 38988/38988/28592 39578/39578/29101 39077/39077/28675 +f 39577/39577/28701 39579/39579/28700 39401/39401/28955 +f 39577/39577/28701 39401/39401/28955 39578/39578/29101 +f 39578/39578/29101 39401/39401/28955 39400/39400/28954 +f 39578/39578/29101 39400/39400/28954 39580/39580/29102 +f 39077/39077/28675 39578/39578/29101 39580/39580/29102 +f 39077/39077/28675 39580/39580/29102 38872/38872/28485 +f 38884/38884/28495 39581/39581/29103 39582/39582/29104 +f 38884/38884/28495 39582/39582/29104 39583/39583/29105 +f 39581/39581/29103 39584/39584/29106 39585/39585/29107 +f 39581/39581/29103 39585/39585/29107 39582/39582/29104 +f 39582/39582/29104 39585/39585/29107 39586/39586/29108 +f 39582/39582/29104 39586/39586/29108 39587/39587/29109 +f 39583/39583/29105 39582/39582/29104 39587/39587/29109 +f 39583/39583/29105 39587/39587/29109 39588/39588/29110 +f 38902/38902/28510 39538/39538/29076 39589/39589/29111 +f 38902/38902/28510 39589/39589/29111 38903/38903/28511 +f 39538/39538/29076 39537/39537/29075 39590/39590/29112 +f 39538/39538/29076 39590/39590/29112 39589/39589/29111 +f 39589/39589/29111 39590/39590/29112 39591/39591/29113 +f 39589/39589/29111 39591/39591/29113 39592/39592/29114 +f 38903/38903/28511 39589/39589/29111 39592/39592/29114 +f 38903/38903/28511 39592/39592/29114 38904/38904/28512 +f 39593/39593/29115 39594/39594/29116 39595/39595/29117 +f 39593/39593/29115 39595/39595/29117 39596/39596/29118 +f 39594/39594/29116 39454/39454/28999 39453/39453/28996 +f 39594/39594/29116 39453/39453/28996 39595/39595/29117 +f 39595/39595/29117 39453/39453/28996 39597/39597/28995 +f 39595/39595/29117 39597/39597/28995 39598/39598/29119 +f 39596/39596/29118 39595/39595/29117 39598/39598/29119 +f 39596/39596/29118 39598/39598/29119 39599/39599/29120 +f 38904/38904/28512 39592/39592/29114 39600/39600/29121 +f 38904/38904/28512 39600/39600/29121 38929/38929/28536 +f 39592/39592/29114 39591/39591/29113 39601/39601/29122 +f 39592/39592/29114 39601/39601/29122 39600/39600/29121 +f 39600/39600/29121 39601/39601/29122 39502/39502/29042 +f 39600/39600/29121 39502/39502/29042 39499/39499/29039 +f 38929/38929/28536 39600/39600/29121 39499/39499/29039 +f 38929/38929/28536 39499/39499/29039 38926/38926/28533 +f 39323/39323/28890 39602/39602/29123 39603/39603/29124 +f 39323/39323/28890 39603/39603/29124 39604/39604/29125 +f 39602/39602/29123 39353/39353/28916 39356/39356/28919 +f 39602/39602/29123 39356/39356/28919 39603/39603/29124 +f 39603/39603/29124 39356/39356/28919 39359/39359/28409 +f 39603/39603/29124 39359/39359/28409 39605/39605/29126 +f 39604/39604/29125 39603/39603/29124 39605/39605/29126 +f 39604/39604/29125 39605/39605/29126 39606/39606/28610 +f 39332/39332/28899 39607/39607/29127 39608/39608/29128 +f 39332/39332/28899 39608/39608/29128 39609/39609/29129 +f 39607/39607/29127 39333/39333/28900 39336/39336/28903 +f 39607/39607/29127 39336/39336/28903 39608/39608/29128 +f 39608/39608/29128 39336/39336/28903 39341/39341/28545 +f 39608/39608/29128 39341/39341/28545 39610/39610/29130 +f 39609/39609/29129 39608/39608/29128 39610/39610/29130 +f 39609/39609/29129 39610/39610/29130 39611/39611/29051 +f 39612/39612/28420 39613/39613/29052 39614/39614/29131 +f 39612/39612/28420 39614/39614/29131 39615/39615/29132 +f 39613/39613/29052 39616/39616/29051 39617/39617/29130 +f 39613/39613/29052 39617/39617/29130 39614/39614/29131 +f 39614/39614/29131 39617/39617/29130 38938/38938/28545 +f 39614/39614/29131 38938/38938/28545 38935/38935/28542 +f 39615/39615/29132 39614/39614/29131 38935/38935/28542 +f 39615/39615/29132 38935/38935/28542 38934/38934/28541 +f 39612/39612/28420 39615/39615/29132 39618/39618/29133 +f 39612/39612/28420 39618/39618/29133 39619/39619/29134 +f 39615/39615/29132 38934/38934/28541 39620/39620/29135 +f 39615/39615/29132 39620/39620/29135 39618/39618/29133 +f 39618/39618/29133 39620/39620/29135 38926/38926/28533 +f 39618/39618/29133 38926/38926/28533 39501/39501/29041 +f 39619/39619/29134 39618/39618/29133 39501/39501/29041 +f 39619/39619/29134 39501/39501/29041 39504/39504/28422 +f 38821/38821/28438 39621/39621/29136 39622/39622/29137 +f 38821/38821/28438 39622/39622/29137 38822/38822/28439 +f 39621/39621/29136 38788/38788/28405 38860/38860/28473 +f 39621/39621/29136 38860/38860/28473 39622/39622/29137 +f 39622/39622/29137 38860/38860/28473 38835/38835/28450 +f 39622/39622/29137 38835/38835/28450 38838/38838/28453 +f 38822/38822/28439 39622/39622/29137 38838/38838/28453 +f 38822/38822/28439 38838/38838/28453 38823/38823/28440 +f 38862/38862/28475 39112/39112/28708 39623/39623/29138 +f 38862/38862/28475 39623/39623/29138 38863/38863/28476 +f 39112/39112/28708 39111/39111/28707 39624/39624/29139 +f 39112/39112/28708 39624/39624/29139 39623/39623/29138 +f 39623/39623/29138 39624/39624/29139 38839/38839/28454 +f 39623/39623/29138 38839/38839/28454 38836/38836/28451 +f 38863/38863/28476 39623/39623/29138 38836/38836/28451 +f 38863/38863/28476 38836/38836/28451 38835/38835/28450 +f 38821/38821/28438 39009/39009/28611 39625/39625/29140 +f 38821/38821/28438 39625/39625/29140 39621/39621/29136 +f 39009/39009/28611 39008/39008/28610 39626/39626/29141 +f 39009/39009/28611 39626/39626/29141 39625/39625/29140 +f 39625/39625/29140 39626/39626/29141 38792/38792/28409 +f 39625/39625/29140 38792/38792/28409 38789/38789/28406 +f 39621/39621/29136 39625/39625/29140 38789/38789/28406 +f 39621/39621/29136 38789/38789/28406 38788/38788/28405 +f 39627/39627/29142 39628/39628/29143 39629/39629/29144 +f 39627/39627/29142 39629/39629/29144 39630/39630/29145 +f 39628/39628/29143 39034/39034/28634 39631/39631/29146 +f 39628/39628/29143 39631/39631/29146 39629/39629/29144 +f 39629/39629/29144 39631/39631/29146 39632/39632/29147 +f 39629/39629/29144 39632/39632/29147 39633/39633/29148 +f 39630/39630/29145 39629/39629/29144 39633/39633/29148 +f 39630/39630/29145 39633/39633/29148 39634/39634/29149 +f 39627/39627/29142 39635/39635/29150 39636/39636/29151 +f 39627/39627/29142 39636/39636/29151 39628/39628/29143 +f 39635/39635/29150 39637/39637/29152 39638/39638/29153 +f 39635/39635/29150 39638/39638/29153 39636/39636/29151 +f 39636/39636/29151 39638/39638/29153 39037/39037/28637 +f 39636/39636/29151 39037/39037/28637 39035/39035/28635 +f 39628/39628/29143 39636/39636/29151 39035/39035/28635 +f 39628/39628/29143 39035/39035/28635 39034/39034/28634 +f 39639/39639/29149 39640/39640/29154 39641/39641/29155 +f 39639/39639/29149 39641/39641/29155 39642/39642/29156 +f 39640/39640/29154 39643/39643/29157 39644/39644/29158 +f 39640/39640/29154 39644/39644/29158 39641/39641/29155 +f 39641/39641/29155 39644/39644/29158 39645/39645/29159 +f 39641/39641/29155 39645/39645/29159 39646/39646/29160 +f 39642/39642/29156 39641/39641/29155 39646/39646/29160 +f 39642/39642/29156 39646/39646/29160 39647/39647/29161 +f 38815/38815/28432 39648/39648/29162 39649/39649/29163 +f 38815/38815/28432 39649/39649/29163 38816/38816/28433 +f 39650/39650/29162 39632/39632/29147 39631/39631/29146 +f 39650/39650/29162 39631/39631/29146 39651/39651/29163 +f 39651/39651/29163 39631/39631/29146 39034/39034/28634 +f 39651/39651/29163 39034/39034/28634 39033/39033/28632 +f 38816/38816/28433 39649/39649/29163 39031/39031/28632 +f 38816/38816/28433 39031/39031/28632 38819/38819/28436 +f 38797/38797/28414 38834/38834/28449 39652/39652/29164 +f 38797/38797/28414 39652/39652/29164 38798/38798/28415 +f 38833/38833/28449 38832/38832/28448 39653/39653/29165 +f 38833/38833/28449 39653/39653/29165 39654/39654/29164 +f 39654/39654/29164 39653/39653/29165 39647/39647/29161 +f 39654/39654/29164 39647/39647/29161 39655/39655/29166 +f 38798/38798/28415 39652/39652/29164 39656/39656/29167 +f 38798/38798/28415 39656/39656/29167 38801/38801/28418 +f 39562/39562/28895 39657/39657/29168 39658/39658/29169 +f 39562/39562/28895 39658/39658/29169 39563/39563/29090 +f 39532/39532/29070 39531/39531/29069 39659/39659/29170 +f 39532/39532/29070 39659/39659/29170 39660/39660/29169 +f 39660/39660/29169 39659/39659/29170 39632/39632/29147 +f 39660/39660/29169 39632/39632/29147 39650/39650/29162 +f 39563/39563/29090 39658/39658/29169 39648/39648/29162 +f 39563/39563/29090 39648/39648/29162 38815/38815/28432 +f 39315/39315/28884 39661/39661/29171 39662/39662/29172 +f 39315/39315/28884 39662/39662/29172 39316/39316/28885 +f 39661/39661/29171 39663/39663/29152 39664/39664/29173 +f 39661/39661/29171 39664/39664/29173 39662/39662/29172 +f 39662/39662/29172 39664/39664/29173 39665/39665/28446 +f 39662/39662/29172 39665/39665/28446 39666/39666/28445 +f 39316/39316/28885 39662/39662/29172 39666/39666/28445 +f 39316/39316/28885 39666/39666/28445 39319/39319/28441 +f 38801/38801/28418 39656/39656/29167 39667/39667/29174 +f 38801/38801/28418 39667/39667/29174 39508/39508/29047 +f 39655/39655/29166 39647/39647/29161 39646/39646/29160 +f 39655/39655/29166 39646/39646/29160 39668/39668/29174 +f 39668/39668/29174 39646/39646/29160 39645/39645/29159 +f 39668/39668/29174 39645/39645/29159 39669/39669/29175 +f 39508/39508/29047 39667/39667/29174 39670/39670/29175 +f 39508/39508/29047 39670/39670/29175 39510/39510/29049 +f 39671/39671/29176 39672/39672/29177 39673/39673/29178 +f 39671/39671/29176 39673/39673/29178 39674/39674/29179 +f 39672/39672/29177 39675/39675/29180 39676/39676/29181 +f 39672/39672/29177 39676/39676/29181 39673/39673/29178 +f 39673/39673/29178 39676/39676/29181 39677/39677/29182 +f 39673/39673/29178 39677/39677/29182 39678/39678/29183 +f 39674/39674/29179 39673/39673/29178 39678/39678/29183 +f 39674/39674/29179 39678/39678/29183 39679/39679/29184 +f 39267/39267/28844 39680/39680/29185 39681/39681/29186 +f 39267/39267/28844 39681/39681/29186 39268/39268/28845 +f 39680/39680/29185 39682/39682/29187 39683/39683/29188 +f 39680/39680/29185 39683/39683/29188 39681/39681/29186 +f 39684/39684/29186 39685/39685/29188 39292/39292/28866 +f 39684/39684/29186 39292/39292/28866 39289/39289/28863 +f 39270/39270/28845 39684/39684/29186 39289/39289/28863 +f 39270/39270/28845 39289/39289/28863 39271/39271/28846 +f 39299/39299/28873 39686/39686/29189 39687/39687/29190 +f 39299/39299/28873 39687/39687/29190 39300/39300/28874 +f 39686/39686/29189 39688/39688/29191 39689/39689/29192 +f 39686/39686/29189 39689/39689/29192 39687/39687/29190 +f 39690/39690/29193 39678/39678/29183 39677/39677/29182 +f 39690/39690/29193 39677/39677/29182 39691/39691/29194 +f 39302/39302/28875 39690/39690/29193 39691/39691/29194 +f 39302/39302/28875 39691/39691/29194 39303/39303/28876 +f 39303/39303/28876 39691/39691/29194 39692/39692/29195 +f 39303/39303/28876 39692/39692/29195 39308/39308/28879 +f 39691/39691/29194 39677/39677/29182 39676/39676/29181 +f 39691/39691/29194 39676/39676/29181 39692/39692/29195 +f 39692/39692/29195 39676/39676/29181 39675/39675/29180 +f 39692/39692/29195 39675/39675/29180 39693/39693/29196 +f 39308/39308/28879 39692/39692/29195 39693/39693/29196 +f 39308/39308/28879 39693/39693/29196 39310/39310/28880 +f 39175/39175/28768 39694/39694/29197 39695/39695/29198 +f 39175/39175/28768 39695/39695/29198 39170/39170/28763 +f 39696/39696/29199 39697/39697/29200 39698/39698/29201 +f 39696/39696/29199 39698/39698/29201 39699/39699/29202 +f 39699/39699/29202 39698/39698/29201 39700/39700/29203 +f 39699/39699/29202 39700/39700/29203 39701/39701/29204 +f 39170/39170/28763 39695/39695/29198 39702/39702/29205 +f 39170/39170/28763 39702/39702/29205 39167/39167/28760 +f 39703/39703/29206 39704/39704/29207 39705/39705/29208 +f 39703/39703/29206 39705/39705/29208 39706/39706/29209 +f 39704/39704/29207 39707/39707/29210 39708/39708/29211 +f 39704/39704/29207 39708/39708/29211 39705/39705/29208 +f 39705/39705/29208 39708/39708/29211 39697/39697/29200 +f 39705/39705/29208 39697/39697/29200 39696/39696/29199 +f 39709/39709/29212 39710/39710/29213 39694/39694/29197 +f 39709/39709/29212 39694/39694/29197 39175/39175/28768 +f 39711/39711/29214 39712/39712/29215 39713/39713/29216 +f 39711/39711/29214 39713/39713/29216 39714/39714/29217 +f 39712/39712/29215 39715/39715/29218 39716/39716/29219 +f 39712/39712/29215 39716/39716/29219 39713/39713/29216 +f 39717/39717/29220 39718/39718/29219 39719/39719/29221 +f 39717/39717/29220 39719/39719/29221 39720/39720/29222 +f 39721/39721/29223 39722/39722/29216 39723/39723/29224 +f 39721/39721/29223 39723/39723/29224 39724/39724/29225 +f 39725/39725/29226 39726/39726/29227 39727/39727/29228 +f 39725/39725/29226 39727/39727/29228 39728/39728/29229 +f 39729/39729/29230 39730/39730/29231 39731/39731/29232 +f 39729/39729/29230 39731/39731/29232 39732/39732/29228 +f 39732/39732/29228 39731/39731/29232 39733/39733/29233 +f 39732/39732/29228 39733/39733/29233 39734/39734/29234 +f 39728/39728/29229 39727/39727/29228 39735/39735/29234 +f 39728/39728/29229 39735/39735/29234 39736/39736/29235 +f 39173/39173/28766 39737/39737/29236 39738/39738/29237 +f 39173/39173/28766 39738/39738/29237 39739/39739/29238 +f 39737/39737/29236 39740/39740/29239 39741/39741/29240 +f 39737/39737/29236 39741/39741/29240 39738/39738/29237 +f 39742/39742/29241 39743/39743/29242 39744/39744/29243 +f 39742/39742/29241 39744/39744/29243 39745/39745/29244 +f 39746/39746/29238 39742/39742/29241 39745/39745/29244 +f 39746/39746/29238 39745/39745/29244 39747/39747/29245 +f 39149/39149/28743 39748/39748/29246 39749/39749/29247 +f 39149/39149/28743 39749/39749/29247 39750/39750/28759 +f 39751/39751/29248 39752/39752/29249 39753/39753/29250 +f 39751/39751/29248 39753/39753/29250 39754/39754/29247 +f 39755/39755/29247 39756/39756/29251 39171/39171/28764 +f 39755/39755/29247 39171/39171/28764 39168/39168/28761 +f 39165/39165/28759 39757/39757/29247 39758/39758/29252 +f 39165/39165/28759 39758/39758/29252 39166/39166/28760 +f 39759/39759/28768 39760/39760/28767 39761/39761/29253 +f 39759/39759/28768 39761/39761/29253 39762/39762/29254 +f 39174/39174/28767 39173/39173/28766 39739/39739/29238 +f 39174/39174/28767 39739/39739/29238 39763/39763/29255 +f 39764/39764/29255 39746/39746/29238 39747/39747/29245 +f 39764/39764/29255 39747/39747/29245 39765/39765/29256 +f 39766/39766/29254 39767/39767/29257 39768/39768/29258 +f 39766/39766/29254 39768/39768/29258 39157/39157/28751 +f 39157/39157/28751 39768/39768/29258 39769/39769/29259 +f 39157/39157/28751 39769/39769/29259 39152/39152/28746 +f 39770/39770/29260 39771/39771/29245 39772/39772/29261 +f 39770/39770/29260 39772/39772/29261 39773/39773/29262 +f 39773/39773/29262 39772/39772/29261 39774/39774/29249 +f 39773/39773/29262 39774/39774/29249 39775/39775/29246 +f 39152/39152/28746 39769/39769/29259 39748/39748/29246 +f 39152/39152/28746 39748/39748/29246 39149/39149/28743 +f 39744/39744/29243 39776/39776/29263 39777/39777/29264 +f 39744/39744/29243 39777/39777/29264 39778/39778/29265 +f 39776/39776/29263 39779/39779/29266 39780/39780/29267 +f 39776/39776/29263 39780/39780/29267 39777/39777/29264 +f 39777/39777/29264 39780/39780/29267 39781/39781/29268 +f 39777/39777/29264 39781/39781/29268 39782/39782/29269 +f 39778/39778/29265 39777/39777/29264 39782/39782/29269 +f 39778/39778/29265 39782/39782/29269 39783/39783/29270 +f 39747/39747/29245 39745/39745/29244 39784/39784/29271 +f 39747/39747/29245 39784/39784/29271 39785/39785/29261 +f 39745/39745/29244 39744/39744/29243 39778/39778/29265 +f 39745/39745/29244 39778/39778/29265 39784/39784/29271 +f 39784/39784/29271 39778/39778/29265 39783/39783/29270 +f 39784/39784/29271 39783/39783/29270 39786/39786/29272 +f 39785/39785/29261 39784/39784/29271 39786/39786/29272 +f 39785/39785/29261 39786/39786/29272 39752/39752/29249 +f 39171/39171/28764 39787/39787/29273 39788/39788/29274 +f 39171/39171/28764 39788/39788/29274 39172/39172/28765 +f 39787/39787/29273 39789/39789/29275 39790/39790/29276 +f 39787/39787/29273 39790/39790/29276 39788/39788/29274 +f 39788/39788/29274 39790/39790/29276 39740/39740/29239 +f 39788/39788/29274 39740/39740/29239 39737/39737/29236 +f 39172/39172/28765 39788/39788/29274 39737/39737/29236 +f 39172/39172/28765 39737/39737/29236 39173/39173/28766 +f 39752/39752/29249 39786/39786/29272 39791/39791/29277 +f 39752/39752/29249 39791/39791/29277 39753/39753/29250 +f 39786/39786/29272 39783/39783/29270 39792/39792/29278 +f 39786/39786/29272 39792/39792/29278 39791/39791/29277 +f 39793/39793/29279 39794/39794/29278 39789/39789/29275 +f 39793/39793/29279 39789/39789/29275 39787/39787/29273 +f 39756/39756/29251 39793/39793/29279 39787/39787/29273 +f 39756/39756/29251 39787/39787/29273 39171/39171/28764 +f 39795/39795/29280 39796/39796/29281 39797/39797/29282 +f 39795/39795/29280 39797/39797/29282 39798/39798/29283 +f 39796/39796/29281 39799/39799/29284 39800/39800/29285 +f 39796/39796/29281 39800/39800/29285 39797/39797/29282 +f 39797/39797/29282 39800/39800/29285 39801/39801/29286 +f 39797/39797/29282 39801/39801/29286 39802/39802/29287 +f 39798/39798/29283 39797/39797/29282 39802/39802/29287 +f 39798/39798/29283 39802/39802/29287 39803/39803/29288 +f 39789/39789/29275 39804/39804/29289 39805/39805/29290 +f 39789/39789/29275 39805/39805/29290 39790/39790/29276 +f 39804/39804/29289 39795/39795/29280 39798/39798/29283 +f 39804/39804/29289 39798/39798/29283 39805/39805/29290 +f 39805/39805/29290 39798/39798/29283 39803/39803/29288 +f 39805/39805/29290 39803/39803/29288 39806/39806/29291 +f 39790/39790/29276 39805/39805/29290 39806/39806/29291 +f 39790/39790/29276 39806/39806/29291 39740/39740/29239 +f 39783/39783/29270 39782/39782/29269 39807/39807/29292 +f 39783/39783/29270 39807/39807/29292 39792/39792/29278 +f 39782/39782/29269 39781/39781/29268 39808/39808/29293 +f 39782/39782/29269 39808/39808/29293 39807/39807/29292 +f 39809/39809/29292 39810/39810/29293 39795/39795/29280 +f 39809/39809/29292 39795/39795/29280 39804/39804/29289 +f 39794/39794/29278 39809/39809/29292 39804/39804/29289 +f 39794/39794/29278 39804/39804/29289 39789/39789/29275 +f 39740/39740/29239 39806/39806/29291 39811/39811/29294 +f 39740/39740/29239 39811/39811/29294 39741/39741/29240 +f 39806/39806/29291 39803/39803/29288 39812/39812/29295 +f 39806/39806/29291 39812/39812/29295 39811/39811/29294 +f 39813/39813/29294 39814/39814/29295 39779/39779/29266 +f 39813/39813/29294 39779/39779/29266 39776/39776/29263 +f 39743/39743/29242 39813/39813/29294 39776/39776/29263 +f 39743/39743/29242 39776/39776/29263 39744/39744/29243 +f 39815/39815/29296 39816/39816/29297 39817/39817/29298 +f 39815/39815/29296 39817/39817/29298 39818/39818/29299 +f 39816/39816/29297 39819/39819/29300 39820/39820/29301 +f 39816/39816/29297 39820/39820/29301 39817/39817/29298 +f 39821/39821/29302 39822/39822/29301 39823/39823/29303 +f 39821/39821/29302 39823/39823/29303 39824/39824/29304 +f 39825/39825/29299 39821/39821/29302 39824/39824/29304 +f 39825/39825/29299 39824/39824/29304 39826/39826/29305 +f 39781/39781/29268 39827/39827/29306 39828/39828/29307 +f 39781/39781/29268 39828/39828/29307 39808/39808/29293 +f 39827/39827/29306 39829/39829/29308 39830/39830/29309 +f 39827/39827/29306 39830/39830/29309 39828/39828/29307 +f 39831/39831/29307 39832/39832/29309 39799/39799/29284 +f 39831/39831/29307 39799/39799/29284 39796/39796/29281 +f 39810/39810/29293 39831/39831/29307 39796/39796/29281 +f 39810/39810/29293 39796/39796/29281 39795/39795/29280 +f 39803/39803/29288 39802/39802/29287 39833/39833/29310 +f 39803/39803/29288 39833/39833/29310 39812/39812/29295 +f 39802/39802/29287 39801/39801/29286 39834/39834/29311 +f 39802/39802/29287 39834/39834/29311 39833/39833/29310 +f 39835/39835/29312 39836/39836/29313 39837/39837/29314 +f 39835/39835/29312 39837/39837/29314 39838/39838/29315 +f 39814/39814/29295 39835/39835/29312 39838/39838/29315 +f 39814/39814/29295 39838/39838/29315 39779/39779/29266 +f 39779/39779/29266 39838/39838/29315 39839/39839/29316 +f 39779/39779/29266 39839/39839/29316 39780/39780/29267 +f 39838/39838/29315 39837/39837/29314 39840/39840/29317 +f 39838/39838/29315 39840/39840/29317 39839/39839/29316 +f 39839/39839/29316 39840/39840/29317 39829/39829/29308 +f 39839/39839/29316 39829/39829/29308 39827/39827/29306 +f 39780/39780/29267 39839/39839/29316 39827/39827/29306 +f 39780/39780/29267 39827/39827/29306 39781/39781/29268 +f 39841/39841/29318 39842/39842/29319 39843/39843/29320 +f 39841/39841/29318 39843/39843/29320 39844/39844/29321 +f 39845/39845/29322 39846/39846/29323 39847/39847/29324 +f 39845/39845/29322 39847/39847/29324 39848/39848/29325 +f 39848/39848/29325 39847/39847/29324 39849/39849/29303 +f 39848/39848/29325 39849/39849/29303 39850/39850/29326 +f 39844/39844/29321 39843/39843/29320 39820/39820/29301 +f 39844/39844/29321 39820/39820/29301 39819/39819/29300 +f 39851/39851/29305 39852/39852/29327 39853/39853/29328 +f 39851/39851/29305 39853/39853/29328 39854/39854/29329 +f 39852/39852/29327 39855/39855/29303 39856/39856/29324 +f 39852/39852/29327 39856/39856/29324 39853/39853/29328 +f 39853/39853/29328 39856/39856/29324 39857/39857/29323 +f 39853/39853/29328 39857/39857/29323 39858/39858/29330 +f 39854/39854/29329 39853/39853/29328 39858/39858/29330 +f 39854/39854/29329 39858/39858/29330 39859/39859/29331 +f 39860/39860/29332 39861/39861/29333 39862/39862/29334 +f 39860/39860/29332 39862/39862/29334 39863/39863/29335 +f 39861/39861/29333 39841/39841/29318 39844/39844/29321 +f 39861/39861/29333 39844/39844/29321 39862/39862/29334 +f 39862/39862/29334 39844/39844/29321 39819/39819/29300 +f 39862/39862/29334 39819/39819/29300 39816/39816/29297 +f 39863/39863/29335 39862/39862/29334 39816/39816/29297 +f 39863/39863/29335 39816/39816/29297 39815/39815/29296 +f 39859/39859/29331 39858/39858/29330 39864/39864/29336 +f 39859/39859/29331 39864/39864/29336 39865/39865/29337 +f 39858/39858/29330 39857/39857/29323 39866/39866/29319 +f 39858/39858/29330 39866/39866/29319 39864/39864/29336 +f 39867/39867/29336 39868/39868/29322 39869/39869/29338 +f 39867/39867/29336 39869/39869/29338 39870/39870/29339 +f 39871/39871/29340 39867/39867/29336 39870/39870/29339 +f 39871/39871/29340 39870/39870/29339 39872/39872/29332 +f 39083/39083/28681 39873/39873/29341 39874/39874/29342 +f 39083/39083/28681 39874/39874/29342 39084/39084/28682 +f 39873/39873/29341 39875/39875/29343 39876/39876/29344 +f 39873/39873/29341 39876/39876/29344 39874/39874/29342 +f 39877/39877/29345 39878/39878/29344 39725/39725/29226 +f 39877/39877/29345 39725/39725/29226 39879/39879/29346 +f 39086/39086/28683 39877/39877/29345 39879/39879/29346 +f 39086/39086/28683 39879/39879/29346 39087/39087/28684 +f 39129/39129/28724 39880/39880/29347 39881/39881/29348 +f 39129/39129/28724 39881/39881/29348 39130/39130/28725 +f 39880/39880/29347 39711/39711/29214 39714/39714/29217 +f 39880/39880/29347 39714/39714/29217 39881/39881/29348 +f 39882/39882/29348 39721/39721/29223 39724/39724/29225 +f 39882/39882/29348 39724/39724/29225 39883/39883/29349 +f 39132/39132/28725 39882/39882/29348 39883/39883/29349 +f 39132/39132/28725 39883/39883/29349 39133/39133/28727 +f 39133/39133/28727 39883/39883/29349 39884/39884/29350 +f 39133/39133/28727 39884/39884/29350 39139/39139/28733 +f 39883/39883/29349 39724/39724/29225 39885/39885/29351 +f 39883/39883/29349 39885/39885/29351 39884/39884/29350 +f 39884/39884/29350 39885/39885/29351 39886/39886/29352 +f 39884/39884/29350 39886/39886/29352 39887/39887/29353 +f 39139/39139/28733 39884/39884/29350 39887/39887/29353 +f 39139/39139/28733 39887/39887/29353 39140/39140/28734 +f 39087/39087/28684 39879/39879/29346 39888/39888/29354 +f 39087/39087/28684 39888/39888/29354 39145/39145/28739 +f 39879/39879/29346 39725/39725/29226 39728/39728/29229 +f 39879/39879/29346 39728/39728/29229 39888/39888/29354 +f 39888/39888/29354 39728/39728/29229 39736/39736/29235 +f 39888/39888/29354 39736/39736/29235 39889/39889/29355 +f 39145/39145/28739 39888/39888/29354 39889/39889/29355 +f 39145/39145/28739 39889/39889/29355 39146/39146/28740 +f 39890/39890/29356 39891/39891/29357 39892/39892/29358 +f 39890/39890/29356 39892/39892/29358 39893/39893/29359 +f 39894/39894/29360 39895/39895/29361 39896/39896/29362 +f 39894/39894/29360 39896/39896/29362 39897/39897/29363 +f 39897/39897/29363 39896/39896/29362 39898/39898/29364 +f 39897/39897/29363 39898/39898/29364 39899/39899/29365 +f 39893/39893/29359 39892/39892/29358 39900/39900/29365 +f 39893/39893/29359 39900/39900/29365 39901/39901/29366 +f 39902/39902/29367 39903/39903/29368 39904/39904/29369 +f 39902/39902/29367 39904/39904/29369 39905/39905/29370 +f 39906/39906/29371 39907/39907/29372 39908/39908/29373 +f 39906/39906/29371 39908/39908/29373 39909/39909/29369 +f 39910/39910/29369 39911/39911/29374 39895/39895/29361 +f 39910/39910/29369 39895/39895/29361 39894/39894/29360 +f 39905/39905/29370 39904/39904/29369 39891/39891/29357 +f 39905/39905/29370 39891/39891/29357 39890/39890/29356 +f 39912/39912/29375 39913/39913/29376 39914/39914/29377 +f 39912/39912/29375 39914/39914/29377 39915/39915/29378 +f 39916/39916/29379 39917/39917/29380 39918/39918/29381 +f 39916/39916/29379 39918/39918/29381 39919/39919/29377 +f 39920/39920/29377 39921/39921/29381 39922/39922/29382 +f 39920/39920/29377 39922/39922/29382 39923/39923/29383 +f 39915/39915/29378 39914/39914/29377 39924/39924/29383 +f 39915/39915/29378 39924/39924/29383 39730/39730/29231 +f 39719/39719/29221 39925/39925/29384 39926/39926/29385 +f 39719/39719/29221 39926/39926/29385 39927/39927/29386 +f 39928/39928/29384 39929/39929/29387 39930/39930/29388 +f 39928/39928/29384 39930/39930/29388 39931/39931/29389 +f 39931/39931/29389 39930/39930/29388 39932/39932/29390 +f 39931/39931/29389 39932/39932/29390 39933/39933/29391 +f 39927/39927/29386 39926/39926/29385 39934/39934/29392 +f 39927/39927/29386 39934/39934/29392 39935/39935/29393 +f 39724/39724/29225 39723/39723/29224 39936/39936/29394 +f 39724/39724/29225 39936/39936/29394 39885/39885/29351 +f 39720/39720/29222 39719/39719/29221 39927/39927/29386 +f 39720/39720/29222 39927/39927/29386 39937/39937/29395 +f 39937/39937/29395 39927/39927/29386 39935/39935/29393 +f 39937/39937/29395 39935/39935/29393 39938/39938/29396 +f 39885/39885/29351 39936/39936/29394 39939/39939/29396 +f 39885/39885/29351 39939/39939/29396 39886/39886/29352 +f 39875/39875/29343 39940/39940/29397 39941/39941/29398 +f 39875/39875/29343 39941/39941/29398 39876/39876/29344 +f 39942/39942/29399 39912/39912/29375 39915/39915/29378 +f 39942/39942/29399 39915/39915/29378 39943/39943/29398 +f 39943/39943/29398 39915/39915/29378 39730/39730/29231 +f 39943/39943/29398 39730/39730/29231 39729/39729/29230 +f 39878/39878/29344 39944/39944/29398 39726/39726/29227 +f 39878/39878/29344 39726/39726/29227 39725/39725/29226 +f 39945/39945/28752 39946/39946/29400 39947/39947/29401 +f 39945/39945/28752 39947/39947/29401 39948/39948/29402 +f 39946/39946/29400 39902/39902/29367 39905/39905/29370 +f 39946/39946/29400 39905/39905/29370 39947/39947/29401 +f 39947/39947/29401 39905/39905/29370 39890/39890/29356 +f 39947/39947/29401 39890/39890/29356 39949/39949/29403 +f 39948/39948/29402 39947/39947/29401 39949/39949/29403 +f 39948/39948/29402 39949/39949/29403 39950/39950/28774 +f 39950/39950/28774 39949/39949/29403 39951/39951/29404 +f 39950/39950/28774 39951/39951/29404 39952/39952/29405 +f 39949/39949/29403 39890/39890/29356 39893/39893/29359 +f 39949/39949/29403 39893/39893/29359 39951/39951/29404 +f 39951/39951/29404 39893/39893/29359 39901/39901/29366 +f 39951/39951/29404 39901/39901/29366 39953/39953/29406 +f 39952/39952/29405 39951/39951/29404 39953/39953/29406 +f 39952/39952/29405 39953/39953/29406 39954/39954/28719 +f 39922/39922/29382 39955/39955/29407 39956/39956/29408 +f 39922/39922/29382 39956/39956/29408 39957/39957/29409 +f 39955/39955/29407 39898/39898/29364 39896/39896/29362 +f 39955/39955/29407 39896/39896/29362 39956/39956/29408 +f 39956/39956/29408 39896/39896/29362 39895/39895/29361 +f 39956/39956/29408 39895/39895/29361 39958/39958/29410 +f 39957/39957/29409 39956/39956/29408 39958/39958/29410 +f 39957/39957/29409 39958/39958/29410 39959/39959/29411 +f 39929/39929/29387 39960/39960/29412 39961/39961/29413 +f 39929/39929/29387 39961/39961/29413 39930/39930/29388 +f 39960/39960/29412 39962/39962/29414 39963/39963/29415 +f 39960/39960/29412 39963/39963/29415 39961/39961/29413 +f 39961/39961/29413 39963/39963/29415 39964/39964/29416 +f 39961/39961/29413 39964/39964/29416 39965/39965/29417 +f 39930/39930/29388 39961/39961/29413 39965/39965/29417 +f 39930/39930/29388 39965/39965/29417 39932/39932/29390 +f 39966/39966/29418 39967/39967/29419 39968/39968/29420 +f 39966/39966/29418 39968/39968/29420 39969/39969/29421 +f 39967/39967/29419 39907/39907/29372 39970/39970/29422 +f 39967/39967/29419 39970/39970/29422 39968/39968/29420 +f 39971/39971/29423 39972/39972/29422 39962/39962/29414 +f 39971/39971/29423 39962/39962/29414 39960/39960/29412 +f 39973/39973/29424 39971/39971/29423 39960/39960/29412 +f 39973/39973/29424 39960/39960/29412 39929/39929/29387 +f 39917/39917/29380 39974/39974/29425 39975/39975/29426 +f 39917/39917/29380 39975/39975/29426 39918/39918/29381 +f 39974/39974/29425 39976/39976/29427 39977/39977/29428 +f 39974/39974/29425 39977/39977/29428 39975/39975/29426 +f 39978/39978/29426 39979/39979/29428 39898/39898/29364 +f 39978/39978/29426 39898/39898/29364 39955/39955/29407 +f 39921/39921/29381 39978/39978/29426 39955/39955/29407 +f 39921/39921/29381 39955/39955/29407 39922/39922/29382 +f 39730/39730/29231 39924/39924/29383 39980/39980/29429 +f 39730/39730/29231 39980/39980/29429 39731/39731/29232 +f 39923/39923/29383 39922/39922/29382 39957/39957/29409 +f 39923/39923/29383 39957/39957/29409 39981/39981/29430 +f 39981/39981/29430 39957/39957/29409 39959/39959/29411 +f 39981/39981/29430 39959/39959/29411 39982/39982/29431 +f 39731/39731/29232 39980/39980/29429 39983/39983/29432 +f 39731/39731/29232 39983/39983/29432 39733/39733/29233 +f 39984/39984/29218 39985/39985/29433 39986/39986/29434 +f 39984/39984/29218 39986/39986/29434 39718/39718/29219 +f 39987/39987/29435 39966/39966/29418 39969/39969/29421 +f 39987/39987/29435 39969/39969/29421 39988/39988/29434 +f 39989/39989/29434 39973/39973/29424 39929/39929/29387 +f 39989/39989/29434 39929/39929/29387 39928/39928/29384 +f 39718/39718/29219 39986/39986/29434 39925/39925/29384 +f 39718/39718/29219 39925/39925/29384 39719/39719/29221 +f 39707/39707/29210 39990/39990/29436 39991/39991/29437 +f 39707/39707/29210 39991/39991/29437 39708/39708/29211 +f 39992/39992/29436 39976/39976/29427 39993/39993/29438 +f 39992/39992/29436 39993/39993/29438 39994/39994/29439 +f 39995/39995/29440 39996/39996/29438 39964/39964/29416 +f 39995/39995/29440 39964/39964/29416 39997/39997/29441 +f 39708/39708/29211 39991/39991/29437 39998/39998/29442 +f 39708/39708/29211 39998/39998/29442 39697/39697/29200 +f 39697/39697/29200 39998/39998/29442 39999/39999/29443 +f 39697/39697/29200 39999/39999/29443 39698/39698/29201 +f 39997/39997/29441 39964/39964/29416 39963/39963/29415 +f 39997/39997/29441 39963/39963/29415 40000/40000/29444 +f 40000/40000/29444 39963/39963/29415 39962/39962/29414 +f 40000/40000/29444 39962/39962/29414 40001/40001/29445 +f 39698/39698/29201 39999/39999/29443 40002/40002/29445 +f 39698/39698/29201 40002/40002/29445 39700/39700/29203 +f 39095/39095/28692 40003/40003/29446 40004/40004/29447 +f 39095/39095/28692 40004/40004/29447 39096/39096/28693 +f 40003/40003/29446 39090/39090/28687 39144/39144/28738 +f 40003/40003/29446 39144/39144/28738 40004/40004/29447 +f 40004/40004/29447 39144/39144/28738 39148/39148/28742 +f 40004/40004/29447 39148/39148/28742 40005/40005/29448 +f 39096/39096/28693 40004/40004/29447 40005/40005/29448 +f 39096/39096/28693 40005/40005/29448 39097/39097/28620 +f 39051/39051/28650 40006/40006/29449 40007/40007/29450 +f 39051/39051/28650 40007/40007/29450 39052/39052/28651 +f 40006/40006/29449 39136/39136/28730 39138/39138/28732 +f 40006/40006/29449 39138/39138/28732 40007/40007/29450 +f 40007/40007/29450 39138/39138/28732 39142/39142/28736 +f 40007/40007/29450 39142/39142/28736 40008/40008/29451 +f 39052/39052/28651 40007/40007/29450 40008/40008/29451 +f 39052/39052/28651 40008/40008/29451 38916/38916/28523 +f 40009/40009/29452 40010/40010/29453 40011/40011/29454 +f 40009/40009/29452 40011/40011/29454 40012/40012/29455 +f 40010/40010/29453 39125/39125/28720 39128/39128/28723 +f 40010/40010/29453 39128/39128/28723 40011/40011/29454 +f 40013/40013/29454 39135/39135/28729 39136/39136/28730 +f 40013/40013/29454 39136/39136/28730 40006/40006/29449 +f 40014/40014/29456 40013/40013/29454 40006/40006/29449 +f 40014/40014/29456 40006/40006/29449 39051/39051/28650 +f 40015/40015/29457 40016/40016/29458 40017/40017/29459 +f 40015/40015/29457 40017/40017/29459 40018/40018/29460 +f 40016/40016/29458 39079/39079/28677 39082/39082/28680 +f 40016/40016/29458 39082/39082/28680 40017/40017/29459 +f 40019/40019/29461 39089/39089/28686 39090/39090/28687 +f 40019/40019/29461 39090/39090/28687 40003/40003/29446 +f 40020/40020/29460 40019/40019/29461 40003/40003/29446 +f 40020/40020/29460 40003/40003/29446 39095/39095/28692 +f 40021/40021/29462 40022/40022/29463 40023/40023/29464 +f 40021/40021/29462 40023/40023/29464 40024/40024/29465 +f 40022/40022/29463 40025/40025/29466 40026/40026/29467 +f 40022/40022/29463 40026/40026/29467 40023/40023/29464 +f 40023/40023/29464 40026/40026/29467 39467/39467/29010 +f 40023/40023/29464 39467/39467/29010 39543/39543/29079 +f 40024/40024/29465 40023/40023/29464 39543/39543/29079 +f 40024/40024/29465 39543/39543/29079 39091/39091/28688 +f 39018/39018/28620 39017/39017/28619 40027/40027/29468 +f 39018/39018/28620 40027/40027/29468 40028/40028/28694 +f 39017/39017/28619 39016/39016/28618 40029/40029/29469 +f 39017/39017/28619 40029/40029/29469 40027/40027/29468 +f 40030/40030/29468 40031/40031/29470 40032/40032/29471 +f 40030/40030/29468 40032/40032/29471 40033/40033/29472 +f 39098/39098/28694 40030/40030/29468 40033/40033/29472 +f 39098/39098/28694 40033/40033/29472 39099/39099/28695 +f 39064/39064/28663 40034/40034/29473 40035/40035/29474 +f 39064/39064/28663 40035/40035/29474 40036/40036/29475 +f 40034/40034/29473 40037/40037/29476 40038/40038/29477 +f 40034/40034/29473 40038/40038/29477 40035/40035/29474 +f 40035/40035/29474 40038/40038/29477 39479/39479/29021 +f 40035/40035/29474 39479/39479/29021 39505/39505/29044 +f 40036/40036/29475 40035/40035/29474 39505/39505/29044 +f 40036/40036/29475 39505/39505/29044 39047/39047/28646 +f 38916/38916/28523 38914/38914/28522 40039/40039/29478 +f 38916/38916/28523 40039/40039/29478 39053/39053/28652 +f 38914/38914/28522 38913/38913/28521 40040/40040/29479 +f 38914/38914/28522 40040/40040/29479 40039/40039/29478 +f 40039/40039/29478 40040/40040/29479 40041/40041/29480 +f 40039/40039/29478 40041/40041/29480 40042/40042/29481 +f 39053/39053/28652 40039/40039/29478 40042/40042/29481 +f 39053/39053/28652 40042/40042/29481 39054/39054/28653 +f 40043/40043/29482 40044/40044/29483 40045/40045/29484 +f 40043/40043/29482 40045/40045/29484 40046/40046/29485 +f 40044/40044/29483 39468/39468/29011 39471/39471/29014 +f 40044/40044/29483 39471/39471/29014 40045/40045/29484 +f 40047/40047/29484 39478/39478/29020 39479/39479/29021 +f 40047/40047/29484 39479/39479/29021 40038/40038/29477 +f 40048/40048/29486 40047/40047/29484 40038/40038/29477 +f 40048/40048/29486 40038/40038/29477 40037/40037/29476 +f 40049/40049/29487 40050/40050/29488 40051/40051/29489 +f 40049/40049/29487 40051/40051/29489 40052/40052/29490 +f 40050/40050/29488 39455/39455/29000 39458/39458/29003 +f 40050/40050/29488 39458/39458/29003 40051/40051/29489 +f 40053/40053/29489 39464/39464/29007 39467/39467/29010 +f 40053/40053/29489 39467/39467/29010 40026/40026/29467 +f 40054/40054/29491 40053/40053/29489 40026/40026/29467 +f 40054/40054/29491 40026/40026/29467 40025/40025/29466 +f 40021/40021/29462 40024/40024/29465 40055/40055/29492 +f 40021/40021/29462 40055/40055/29492 40056/40056/29493 +f 40024/40024/29465 39091/39091/28688 39094/39094/28691 +f 40024/40024/29465 39094/39094/28691 40055/40055/29492 +f 40055/40055/29492 39094/39094/28691 39099/39099/28695 +f 40055/40055/29492 39099/39099/28695 40057/40057/29494 +f 40056/40056/29493 40055/40055/29492 40057/40057/29494 +f 40056/40056/29493 40057/40057/29494 40058/40058/29495 +f 39054/39054/28653 40059/40059/29496 40060/40060/29497 +f 39054/39054/28653 40060/40060/29497 39050/39050/28649 +f 40061/40061/29498 40062/40062/29499 40063/40063/29500 +f 40061/40061/29498 40063/40063/29500 40064/40064/29497 +f 40064/40064/29497 40063/40063/29500 40065/40065/29501 +f 40064/40064/29497 40065/40065/29501 40066/40066/29502 +f 39050/39050/28649 40060/40060/29497 40067/40067/29503 +f 39050/39050/28649 40067/40067/29503 39047/39047/28646 +f 38796/38796/28413 39046/39046/28645 40068/40068/29504 +f 38796/38796/28413 40068/40068/29504 38861/38861/28474 +f 40069/40069/28645 40070/40070/28643 40071/40071/29505 +f 40069/40069/28645 40071/40071/29505 40072/40072/29506 +f 40072/40072/29506 40071/40071/29505 40073/40073/29507 +f 40072/40072/29506 40073/40073/29507 40074/40074/29508 +f 38861/38861/28474 40068/40068/29504 40075/40075/29508 +f 38861/38861/28474 40075/40075/29508 38862/38862/28475 +f 40076/40076/29099 40077/40077/29509 40078/40078/29510 +f 40076/40076/29099 40078/40078/29510 40079/40079/29511 +f 40077/40077/29509 40080/40080/29512 40081/40081/29513 +f 40077/40077/29509 40081/40081/29513 40078/40078/29510 +f 40078/40078/29510 40081/40081/29513 39516/39516/29055 +f 40078/40078/29510 39516/39516/29055 39519/39519/29058 +f 40079/40079/29511 40078/40078/29510 39519/39519/29058 +f 40079/40079/29511 39519/39519/29058 39524/39524/29063 +f 39414/39414/28966 40082/40082/29514 40083/40083/29515 +f 39414/39414/28966 40083/40083/29515 39415/39415/28967 +f 40082/40082/29514 40084/40084/29516 40085/40085/29517 +f 40082/40082/29514 40085/40085/29517 40083/40083/29515 +f 40086/40086/29518 40087/40087/29517 40088/40088/29519 +f 40086/40086/29518 40088/40088/29519 40089/40089/29520 +f 40090/40090/29521 40086/40086/29518 40089/40089/29520 +f 40090/40090/29521 40089/40089/29520 40091/40091/28969 +f 39447/39447/28993 40092/40092/29522 40093/40093/29523 +f 39447/39447/28993 40093/40093/29523 39448/39448/28994 +f 40092/40092/29522 40094/40094/29524 40095/40095/29525 +f 40092/40092/29522 40095/40095/29525 40093/40093/29523 +f 40093/40093/29523 40095/40095/29525 40096/40096/29526 +f 40093/40093/29523 40096/40096/29526 40097/40097/29527 +f 39448/39448/28994 40093/40093/29523 40097/40097/29527 +f 39448/39448/28994 40097/40097/29527 39449/39449/28995 +f 40098/40098/29528 40099/40099/29119 40100/40100/29529 +f 40098/40098/29528 40100/40100/29529 40101/40101/29530 +f 40099/40099/29119 40102/40102/28995 40103/40103/29527 +f 40099/40099/29119 40103/40103/29527 40100/40100/29529 +f 40100/40100/29529 40103/40103/29527 40104/40104/29526 +f 40100/40100/29529 40104/40104/29526 40105/40105/29531 +f 40101/40101/29530 40100/40100/29529 40105/40105/29531 +f 40101/40101/29530 40105/40105/29531 39075/39075/28673 +f 40076/40076/29099 40106/40106/29098 40107/40107/29532 +f 40076/40076/29099 40107/40107/29532 40077/40077/29509 +f 40106/40106/29098 40091/40091/28969 40089/40089/29520 +f 40106/40106/29098 40089/40089/29520 40107/40107/29532 +f 40107/40107/29532 40089/40089/29520 40088/40088/29519 +f 40107/40107/29532 40088/40088/29519 40108/40108/29533 +f 40077/40077/29509 40107/40107/29532 40108/40108/29533 +f 40077/40077/29509 40108/40108/29533 40080/40080/29512 +f 40058/40058/29495 40109/40109/29534 40110/40110/29535 +f 40058/40058/29495 40110/40110/29535 40111/40111/29536 +f 40109/40109/29534 40112/40112/29537 40113/40113/29538 +f 40109/40109/29534 40113/40113/29538 40110/40110/29535 +f 40110/40110/29535 40113/40113/29538 39520/39520/29059 +f 40110/40110/29535 39520/39520/29059 39517/39517/29056 +f 40111/40111/29536 40110/40110/29535 39517/39517/29056 +f 40111/40111/29536 39517/39517/29056 39516/39516/29055 +f 40114/40114/29539 40115/40115/29540 40116/40116/29541 +f 40114/40114/29539 40116/40116/29541 40117/40117/29542 +f 40115/40115/29540 40118/40118/29543 40119/40119/29544 +f 40115/40115/29540 40119/40119/29544 40116/40116/29541 +f 40116/40116/29541 40119/40119/29544 39484/39484/29026 +f 40116/40116/29541 39484/39484/29026 39481/39481/29023 +f 40117/40117/29542 40116/40116/29541 39481/39481/29023 +f 40117/40117/29542 39481/39481/29023 39480/39480/29022 +f 39498/39498/29038 39497/39497/29037 40120/40120/29545 +f 39498/39498/29038 40120/40120/29545 40121/40121/29546 +f 39497/39497/29037 39439/39439/28985 40122/40122/29547 +f 39497/39497/29037 40122/40122/29547 40120/40120/29545 +f 40120/40120/29545 40122/40122/29547 39454/39454/28999 +f 40120/40120/29545 39454/39454/28999 39594/39594/29116 +f 40121/40121/29546 40120/40120/29545 39594/39594/29116 +f 40121/40121/29546 39594/39594/29116 39593/39593/29115 +f 38895/38895/28503 39489/39489/29029 40123/40123/29548 +f 38895/38895/28503 40123/40123/29548 38887/38887/28498 +f 39489/39489/29029 39488/39488/29028 40124/40124/29549 +f 39489/39489/29029 40124/40124/29549 40123/40123/29548 +f 40123/40123/29548 40124/40124/29549 39584/39584/29106 +f 40123/40123/29548 39584/39584/29106 39581/39581/29103 +f 38887/38887/28498 40123/40123/29548 39581/39581/29103 +f 38887/38887/28498 39581/39581/29103 38884/38884/28495 +f 38851/38851/28466 38850/38850/28465 40125/40125/29550 +f 38851/38851/28466 40125/40125/29550 40126/40126/29551 +f 38850/38850/28465 38849/38849/28464 40127/40127/29552 +f 38850/38850/28465 40127/40127/29552 40125/40125/29550 +f 40125/40125/29550 40127/40127/29552 39421/39421/28971 +f 40125/40125/29550 39421/39421/28971 39571/39571/29095 +f 40126/40126/29551 40125/40125/29550 39571/39571/29095 +f 40126/40126/29551 39571/39571/29095 39570/39570/29094 +f 39435/39435/28982 40128/40128/29553 40129/40129/29554 +f 39435/39435/28982 40129/40129/29554 39436/39436/28983 +f 40128/40128/29553 39443/39443/28989 39446/39446/28992 +f 40128/40128/29553 39446/39446/28992 40129/40129/29554 +f 40130/40130/29555 39451/39451/28997 39454/39454/28999 +f 40130/40130/29555 39454/39454/28999 40122/40122/29547 +f 39438/39438/28984 40130/40130/29555 40122/40122/29547 +f 39438/39438/28984 40122/40122/29547 39439/39439/28985 +f 39426/39426/28976 40131/40131/29556 40132/40132/29557 +f 39426/39426/28976 40132/40132/29557 39427/39427/28977 +f 40131/40131/29556 39410/39410/28962 39413/39413/28965 +f 40131/40131/29556 39413/39413/28965 40132/40132/29557 +f 40133/40133/29558 39420/39420/28965 39421/39421/28971 +f 40133/40133/29558 39421/39421/28971 40127/40127/29552 +f 39429/39429/28977 40133/40133/29558 40127/40127/29552 +f 39429/39429/28977 40127/40127/29552 38849/38849/28464 +f 38851/38851/28466 40126/40126/29551 40134/40134/29559 +f 38851/38851/28466 40134/40134/29559 40135/40135/29560 +f 40126/40126/29551 39570/39570/29094 40136/40136/29561 +f 40126/40126/29551 40136/40136/29561 40134/40134/29559 +f 40134/40134/29559 40136/40136/29561 39055/39055/28654 +f 40134/40134/29559 39055/39055/28654 39058/39058/28657 +f 40135/40135/29560 40134/40134/29559 39058/39058/28657 +f 40135/40135/29560 39058/39058/28657 39063/39063/28662 +f 40137/40137/29539 40138/40138/29562 40139/40139/29563 +f 40137/40137/29539 40139/40139/29563 40140/40140/29564 +f 40138/40138/29562 40141/40141/29565 40142/40142/29566 +f 40138/40138/29562 40142/40142/29566 40139/40139/29563 +f 40143/40143/29567 40144/40144/29568 40062/40062/29499 +f 40143/40143/29567 40062/40062/29499 40061/40061/29498 +f 40145/40145/29569 40146/40146/29567 40059/40059/29496 +f 40145/40145/29569 40059/40059/29496 39054/39054/28653 +f 40147/40147/29570 40148/40148/29571 40149/40149/29572 +f 40147/40147/29570 40149/40149/29572 40150/40150/29573 +f 40148/40148/29571 40151/40151/29061 40152/40152/29574 +f 40148/40148/29571 40152/40152/29574 40149/40149/29572 +f 40149/40149/29572 40152/40152/29574 39059/39059/28658 +f 40149/40149/29572 39059/39059/28658 39056/39056/28655 +f 40150/40150/29573 40149/40149/29572 39056/39056/28655 +f 40150/40150/29573 39056/39056/28655 39055/39055/28654 +f 39559/39559/29088 39558/39558/29087 40153/40153/29575 +f 39559/39559/29088 40153/40153/29575 40154/40154/29576 +f 39558/39558/29087 39557/39557/28960 40155/40155/29577 +f 39558/39558/29087 40155/40155/29577 40153/40153/29575 +f 40153/40153/29575 40155/40155/29577 39442/39442/28988 +f 40153/40153/29575 39442/39442/28988 39494/39494/29034 +f 40154/40154/29576 40153/40153/29575 39494/39494/29034 +f 40154/40154/29576 39494/39494/29034 39493/39493/29033 +f 39406/39406/28958 40156/40156/29578 40157/40157/29579 +f 39406/39406/28958 40157/40157/29579 39407/39407/28959 +f 40156/40156/29578 39431/39431/28978 39434/39434/28981 +f 40156/40156/29578 39434/39434/28981 40157/40157/29579 +f 40158/40158/29579 39441/39441/28987 39442/39442/28988 +f 40158/40158/29579 39442/39442/28988 40155/40155/29577 +f 40159/40159/28959 40158/40158/29579 40155/40155/29577 +f 40159/40159/28959 40155/40155/29577 39557/39557/28960 +f 39396/39396/28951 40160/40160/29580 40161/40161/29581 +f 39396/39396/28951 40161/40161/29581 39397/39397/28952 +f 40160/40160/29580 39422/39422/28972 39425/39425/28975 +f 40160/40160/29580 39425/39425/28975 40161/40161/29581 +f 40162/40162/29581 39430/39430/28975 38847/38847/28462 +f 40162/40162/29581 38847/38847/28462 40163/40163/29582 +f 39399/39399/28952 40162/40162/29581 40163/40163/29582 +f 39399/39399/28952 40163/40163/29582 39400/39400/28954 +f 39498/39498/29038 40164/40164/29583 40165/40165/29584 +f 39498/39498/29038 40165/40165/29584 39496/39496/29036 +f 40166/40166/29583 40167/40167/29585 40168/40168/29586 +f 40166/40166/29583 40168/40168/29586 40169/40169/29584 +f 40169/40169/29584 40168/40168/29586 40170/40170/29587 +f 40169/40169/29584 40170/40170/29587 40171/40171/29588 +f 39496/39496/29036 40165/40165/29584 40172/40172/29588 +f 39496/39496/29036 40172/40172/29588 39493/39493/29033 +f 38872/38872/28485 40173/40173/29589 40174/40174/29590 +f 38872/38872/28485 40174/40174/29590 38867/38867/28480 +f 40173/40173/29589 38843/38843/28458 40175/40175/29591 +f 40173/40173/29589 40175/40175/29591 40174/40174/29590 +f 40174/40174/29590 40175/40175/29591 38942/38942/28549 +f 40174/40174/29590 38942/38942/28549 38945/38945/28552 +f 38867/38867/28480 40174/40174/29590 38945/38945/28552 +f 38867/38867/28480 38945/38945/28552 38864/38864/28477 +f 39063/39063/28662 39062/39062/28661 40176/40176/29592 +f 39063/39063/28662 40176/40176/29592 40177/40177/29593 +f 39062/39062/28661 39061/39061/28660 40178/40178/29594 +f 39062/39062/28661 40178/40178/29594 40176/40176/29592 +f 40176/40176/29592 40178/40178/29594 38946/38946/28553 +f 40176/40176/29592 38946/38946/28553 38943/38943/28550 +f 40177/40177/29593 40176/40176/29592 38943/38943/28550 +f 40177/40177/29593 38943/38943/28550 38942/38942/28549 +f 38872/38872/28485 39580/39580/29102 40179/40179/29595 +f 38872/38872/28485 40179/40179/29595 40173/40173/29589 +f 39580/39580/29102 39400/39400/28954 40163/40163/29582 +f 39580/39580/29102 40163/40163/29582 40179/40179/29595 +f 40179/40179/29595 40163/40163/29582 38847/38847/28462 +f 40179/40179/29595 38847/38847/28462 38844/38844/28459 +f 40173/40173/29589 40179/40179/29595 38844/38844/28459 +f 40173/40173/29589 38844/38844/28459 38843/38843/28458 +f 39588/39588/29110 39587/39587/29109 40180/40180/29596 +f 39588/39588/29110 40180/40180/29596 40181/40181/29597 +f 39587/39587/29109 39586/39586/29108 40182/40182/29598 +f 39587/39587/29109 40182/40182/29598 40180/40180/29596 +f 40180/40180/29596 40182/40182/29598 38810/38810/28427 +f 40180/40180/29596 38810/38810/28427 38807/38807/28424 +f 40181/40181/29597 40180/40180/29596 38807/38807/28424 +f 40181/40181/29597 38807/38807/28424 38806/38806/28423 +f 40141/40141/29565 40183/40183/29599 40184/40184/29600 +f 40141/40141/29565 40184/40184/29600 40142/40142/29566 +f 40185/40185/29601 40186/40186/29602 40187/40187/29603 +f 40185/40185/29601 40187/40187/29603 40188/40188/29604 +f 40188/40188/29604 40187/40187/29603 40189/40189/29605 +f 40188/40188/29604 40189/40189/29605 40190/40190/29606 +f 40191/40191/29607 40188/40188/29604 40190/40190/29606 +f 40191/40191/29607 40190/40190/29606 40192/40192/29499 +f 38975/38975/28581 40193/40193/29608 40194/40194/29609 +f 38975/38975/28581 40194/40194/29609 38976/38976/28582 +f 40195/40195/29610 40196/40196/29611 40197/40197/29612 +f 40195/40195/29610 40197/40197/29612 40198/40198/29609 +f 40198/40198/29609 40197/40197/29612 40199/40199/29613 +f 40198/40198/29609 40199/40199/29613 40200/40200/29614 +f 38976/38976/28582 40194/40194/29609 40201/40201/29614 +f 38976/38976/28582 40201/40201/29614 38978/38978/28584 +f 40202/40202/29615 40203/40203/29616 40204/40204/29617 +f 40202/40202/29615 40204/40204/29617 40205/40205/29618 +f 40206/40206/29619 40207/40207/29620 40208/40208/29621 +f 40206/40206/29619 40208/40208/29621 40209/40209/29622 +f 40209/40209/29622 40208/40208/29621 40210/40210/29623 +f 40209/40209/29622 40210/40210/29623 40211/40211/29624 +f 40205/40205/29618 40204/40204/29617 40212/40212/29624 +f 40205/40205/29618 40212/40212/29624 40213/40213/29625 +f 39072/39072/28670 40214/40214/29626 40215/40215/29627 +f 39072/39072/28670 40215/40215/29627 40216/40216/29628 +f 40217/40217/29626 40218/40218/29629 40219/40219/29630 +f 40217/40217/29626 40219/40219/29630 40220/40220/29627 +f 40220/40220/29627 40219/40219/29630 40221/40221/29631 +f 40220/40220/29627 40221/40221/29631 40222/40222/29632 +f 40216/40216/29628 40215/40215/29627 40223/40223/29633 +f 40216/40216/29628 40223/40223/29633 40224/40224/29634 +f 40225/40225/29635 40226/40226/29636 40227/40227/29637 +f 40225/40225/29635 40227/40227/29637 40228/40228/29638 +f 40229/40229/29639 40230/40230/29640 40231/40231/29641 +f 40229/40229/29639 40231/40231/29641 40232/40232/29637 +f 40232/40232/29637 40231/40231/29641 40233/40233/29642 +f 40232/40232/29637 40233/40233/29642 40234/40234/29643 +f 40228/40228/29638 40227/40227/29637 40235/40235/29644 +f 40228/40228/29638 40235/40235/29644 40167/40167/29585 +f 38878/38878/28490 40236/40236/29645 40237/40237/29646 +f 38878/38878/28490 40237/40237/29646 38879/38879/28491 +f 40238/40238/29647 40239/40239/29648 40240/40240/29649 +f 40238/40238/29647 40240/40240/29649 40241/40241/29650 +f 40241/40241/29650 40240/40240/29649 40242/40242/29651 +f 40241/40241/29650 40242/40242/29651 40243/40243/29652 +f 38879/38879/28491 40237/40237/29646 40244/40244/29652 +f 38879/38879/28491 40244/40244/29652 38881/38881/28493 +f 40224/40224/29634 40223/40223/29633 40245/40245/29653 +f 40224/40224/29634 40245/40245/29653 40246/40246/29654 +f 40247/40247/29655 40248/40248/29656 40249/40249/29657 +f 40247/40247/29655 40249/40249/29657 40250/40250/29658 +f 40250/40250/29658 40249/40249/29657 40230/40230/29640 +f 40250/40250/29658 40230/40230/29640 40229/40229/29639 +f 40246/40246/29654 40245/40245/29653 40226/40226/29636 +f 40246/40246/29654 40226/40226/29636 40225/40225/29635 +f 40251/40251/29659 40252/40252/29660 40253/40253/29661 +f 40251/40251/29659 40253/40253/29661 40254/40254/29662 +f 40255/40255/29663 40256/40256/29664 40257/40257/29665 +f 40255/40255/29663 40257/40257/29665 40258/40258/29666 +f 40258/40258/29666 40257/40257/29665 40196/40196/29611 +f 40258/40258/29666 40196/40196/29611 40195/40195/29610 +f 40254/40254/29662 40253/40253/29661 40193/40193/29608 +f 40254/40254/29662 40193/40193/29608 38975/38975/28581 +f 38889/38889/28499 40259/40259/29667 40260/40260/29668 +f 38889/38889/28499 40260/40260/29668 38890/38890/28500 +f 40261/40261/29667 40262/40262/29669 40263/40263/29670 +f 40261/40261/29667 40263/40263/29670 40264/40264/29671 +f 40264/40264/29671 40263/40263/29670 40265/40265/29672 +f 40264/40264/29671 40265/40265/29672 40266/40266/29673 +f 38890/38890/28500 40260/40260/29668 40267/40267/29674 +f 38890/38890/28500 40267/40267/29674 38892/38892/28501 +f 40268/40268/29675 40269/40269/29676 40270/40270/29677 +f 40268/40268/29675 40270/40270/29677 40271/40271/29678 +f 40272/40272/29676 40273/40273/29679 40274/40274/29680 +f 40272/40272/29676 40274/40274/29680 40275/40275/29681 +f 40275/40275/29681 40274/40274/29680 40262/40262/29669 +f 40275/40275/29681 40262/40262/29669 40261/40261/29667 +f 40271/40271/29678 40270/40270/29677 40259/40259/29667 +f 40271/40271/29678 40259/40259/29667 38889/38889/28499 +f 38862/38862/28475 40075/40075/29508 40276/40276/29682 +f 38862/38862/28475 40276/40276/29682 39108/39108/28704 +f 40277/40277/29683 40251/40251/29659 40254/40254/29662 +f 40277/40277/29683 40254/40254/29662 40278/40278/29684 +f 40278/40278/29684 40254/40254/29662 38975/38975/28581 +f 40278/40278/29684 38975/38975/28581 38974/38974/28580 +f 39108/39108/28704 40276/40276/29682 38971/38971/28577 +f 39108/39108/28704 38971/38971/28577 38970/38970/28576 +f 38981/38981/28587 38980/38980/28586 40279/40279/29685 +f 38981/38981/28587 40279/40279/29685 39022/39022/28623 +f 38979/38979/28585 38978/38978/28584 40280/40280/29686 +f 38979/38979/28585 40280/40280/29686 40281/40281/29687 +f 40281/40281/29687 40280/40280/29686 38878/38878/28490 +f 40281/40281/29687 38878/38878/28490 38877/38877/28487 +f 40282/40282/28623 40283/40283/29687 38874/38874/28487 +f 40282/40282/28623 38874/38874/28487 38873/38873/28486 +f 39593/39593/29115 40284/40284/29688 40285/40285/29689 +f 39593/39593/29115 40285/40285/29689 40121/40121/29546 +f 40286/40286/29690 40225/40225/29635 40228/40228/29638 +f 40286/40286/29690 40228/40228/29638 40287/40287/29689 +f 40287/40287/29689 40228/40228/29638 40167/40167/29585 +f 40287/40287/29689 40167/40167/29585 40166/40166/29583 +f 40121/40121/29546 40285/40285/29689 40164/40164/29583 +f 40121/40121/29546 40164/40164/29583 39498/39498/29038 +f 39559/39559/29088 40288/40288/29691 40289/40289/29692 +f 39559/39559/29088 40289/40289/29692 39554/39554/29086 +f 40290/40290/29691 40202/40202/29615 40205/40205/29618 +f 40290/40290/29691 40205/40205/29618 40291/40291/29692 +f 40291/40291/29692 40205/40205/29618 40213/40213/29625 +f 40291/40291/29692 40213/40213/29625 40292/40292/29693 +f 39554/39554/29086 40289/40289/29692 40293/40293/29693 +f 39554/39554/29086 40293/40293/29693 39551/39551/28575 +f 38969/38969/28575 40294/40294/29693 40295/40295/29694 +f 38969/38969/28575 40295/40295/29694 38964/38964/28570 +f 40292/40292/29693 40213/40213/29625 40296/40296/29695 +f 40292/40292/29693 40296/40296/29695 40297/40297/29694 +f 40297/40297/29694 40296/40296/29695 38955/38955/28562 +f 40297/40297/29694 38955/38955/28562 38954/38954/28561 +f 38964/38964/28570 40295/40295/29694 38951/38951/28558 +f 38964/38964/28570 38951/38951/28558 38950/38950/28557 +f 40298/40298/28503 38893/38893/28502 40299/40299/29696 +f 40298/40298/28503 40299/40299/29696 40300/40300/29025 +f 38893/38893/28502 38892/38892/28501 40301/40301/29697 +f 38893/38893/28502 40301/40301/29697 40299/40299/29696 +f 40299/40299/29696 40301/40301/29697 40302/40302/29698 +f 40299/40299/29696 40302/40302/29698 40303/40303/29699 +f 40300/40300/29025 40299/40299/29696 40303/40303/29699 +f 40300/40300/29025 40303/40303/29699 40304/40304/29022 +f 38806/38806/28423 40305/40305/29700 40306/40306/29701 +f 38806/38806/28423 40306/40306/29701 40181/40181/29597 +f 40307/40307/29702 40308/40308/29703 40309/40309/29704 +f 40307/40307/29702 40309/40309/29704 40310/40310/29701 +f 40310/40310/29701 40309/40309/29704 40268/40268/29675 +f 40310/40310/29701 40268/40268/29675 40311/40311/29705 +f 40181/40181/29597 40306/40306/29701 40312/40312/29706 +f 40181/40181/29597 40312/40312/29706 39588/39588/29110 +f 39588/39588/29110 40312/40312/29706 40313/40313/29707 +f 39588/39588/29110 40313/40313/29707 39583/39583/29105 +f 40311/40311/29705 40268/40268/29675 40271/40271/29678 +f 40311/40311/29705 40271/40271/29678 40314/40314/29707 +f 40314/40314/29707 40271/40271/29678 38889/38889/28499 +f 40314/40314/29707 38889/38889/28499 38888/38888/28496 +f 39583/39583/29105 40313/40313/29707 38885/38885/28496 +f 39583/39583/29105 38885/38885/28496 38884/38884/28495 +f 38814/38814/28431 38883/38883/28494 40315/40315/29708 +f 38814/38814/28431 40315/40315/29708 38809/38809/28426 +f 38882/38882/28494 38881/38881/28493 40316/40316/29709 +f 38882/38882/28494 40316/40316/29709 40317/40317/29708 +f 40317/40317/29708 40316/40316/29709 40308/40308/29703 +f 40317/40317/29708 40308/40308/29703 40307/40307/29702 +f 38809/38809/28426 40315/40315/29708 40305/40305/29700 +f 38809/38809/28426 40305/40305/29700 38806/38806/28423 +f 39075/39075/28673 39074/39074/28672 40318/40318/29710 +f 39075/39075/28673 40318/40318/29710 40101/40101/29530 +f 39073/39073/28671 39072/39072/28670 40216/40216/29628 +f 39073/39073/28671 40216/40216/29628 40319/40319/29710 +f 40319/40319/29710 40216/40216/29628 40224/40224/29634 +f 40319/40319/29710 40224/40224/29634 40320/40320/29711 +f 40101/40101/29530 40318/40318/29710 40321/40321/29711 +f 40101/40101/29530 40321/40321/29711 40098/40098/29528 +f 39493/39493/29033 40172/40172/29588 40322/40322/29712 +f 39493/39493/29033 40322/40322/29712 40154/40154/29576 +f 40171/40171/29588 40170/40170/29587 40323/40323/29713 +f 40171/40171/29588 40323/40323/29713 40324/40324/29714 +f 40324/40324/29714 40323/40323/29713 40202/40202/29615 +f 40324/40324/29714 40202/40202/29615 40290/40290/29691 +f 40154/40154/29576 40322/40322/29712 40288/40288/29691 +f 40154/40154/29576 40288/40288/29691 39559/39559/29088 +f 39599/39599/29120 40325/40325/29711 40326/40326/29715 +f 39599/39599/29120 40326/40326/29715 39596/39596/29118 +f 40320/40320/29711 40224/40224/29634 40246/40246/29654 +f 40320/40320/29711 40246/40246/29654 40327/40327/29715 +f 40327/40327/29715 40246/40246/29654 40225/40225/29635 +f 40327/40327/29715 40225/40225/29635 40286/40286/29690 +f 39596/39596/29118 40326/40326/29715 40284/40284/29688 +f 39596/39596/29118 40284/40284/29688 39593/39593/29115 +f 40328/40328/29716 40329/40329/29717 40330/40330/29718 +f 40328/40328/29716 40330/40330/29718 40331/40331/29719 +f 40329/40329/29717 40332/40332/29720 40333/40333/29721 +f 40329/40329/29717 40333/40333/29721 40330/40330/29718 +f 40330/40330/29718 40333/40333/29721 40199/40199/29613 +f 40330/40330/29718 40199/40199/29613 40197/40197/29612 +f 40331/40331/29719 40330/40330/29718 40197/40197/29612 +f 40331/40331/29719 40197/40197/29612 40196/40196/29611 +f 40334/40334/29722 40335/40335/29723 40336/40336/29724 +f 40334/40334/29722 40336/40336/29724 40337/40337/29725 +f 40335/40335/29723 40328/40328/29716 40331/40331/29719 +f 40335/40335/29723 40331/40331/29719 40336/40336/29724 +f 40336/40336/29724 40331/40331/29719 40196/40196/29611 +f 40336/40336/29724 40196/40196/29611 40257/40257/29665 +f 40337/40337/29725 40336/40336/29724 40257/40257/29665 +f 40337/40337/29725 40257/40257/29665 40256/40256/29664 +f 40210/40210/29623 40208/40208/29621 40338/40338/29726 +f 40210/40210/29623 40338/40338/29726 40339/40339/29727 +f 40208/40208/29621 40207/40207/29620 40340/40340/29728 +f 40208/40208/29621 40340/40340/29728 40338/40338/29726 +f 40338/40338/29726 40340/40340/29728 40242/40242/29651 +f 40338/40338/29726 40242/40242/29651 40240/40240/29649 +f 40339/40339/29727 40338/40338/29726 40240/40240/29649 +f 40339/40339/29727 40240/40240/29649 40239/40239/29648 +f 40332/40332/29720 40341/40341/29729 40342/40342/29730 +f 40332/40332/29720 40342/40342/29730 40333/40333/29721 +f 40341/40341/29729 40343/40343/29623 40344/40344/29731 +f 40341/40341/29729 40344/40344/29731 40342/40342/29730 +f 40342/40342/29730 40344/40344/29731 40345/40345/29648 +f 40342/40342/29730 40345/40345/29648 40346/40346/29732 +f 40333/40333/29721 40342/40342/29730 40346/40346/29732 +f 40333/40333/29721 40346/40346/29732 40199/40199/29613 +f 40347/40347/29733 40348/40348/29734 40349/40349/29735 +f 40347/40347/29733 40349/40349/29735 40350/40350/29736 +f 40348/40348/29734 40233/40233/29642 40351/40351/29737 +f 40348/40348/29734 40351/40351/29737 40349/40349/29735 +f 40349/40349/29735 40351/40351/29737 40273/40273/29679 +f 40349/40349/29735 40273/40273/29679 40352/40352/29738 +f 40350/40350/29736 40349/40349/29735 40352/40352/29738 +f 40350/40350/29736 40352/40352/29738 40353/40353/29739 +f 40230/40230/29640 40249/40249/29657 40354/40354/29740 +f 40230/40230/29640 40354/40354/29740 40355/40355/29741 +f 40249/40249/29657 40248/40248/29656 40356/40356/29742 +f 40249/40249/29657 40356/40356/29742 40354/40354/29740 +f 40354/40354/29740 40356/40356/29742 40265/40265/29672 +f 40354/40354/29740 40265/40265/29672 40263/40263/29670 +f 40355/40355/29741 40354/40354/29740 40263/40263/29670 +f 40355/40355/29741 40263/40263/29670 40262/40262/29669 +f 40357/40357/29743 40358/40358/29744 40359/40359/29745 +f 40357/40357/29743 40359/40359/29745 40360/40360/29746 +f 40358/40358/29744 40361/40361/29747 40362/40362/29748 +f 40358/40358/29744 40362/40362/29748 40359/40359/29745 +f 40359/40359/29745 40362/40362/29748 40189/40189/29605 +f 40359/40359/29745 40189/40189/29605 40187/40187/29603 +f 40360/40360/29746 40359/40359/29745 40187/40187/29603 +f 40360/40360/29746 40187/40187/29603 40186/40186/29602 +f 40221/40221/29631 40219/40219/29630 40363/40363/29749 +f 40221/40221/29631 40363/40363/29749 40364/40364/29742 +f 40219/40219/29630 40218/40218/29629 40365/40365/29750 +f 40219/40219/29630 40365/40365/29750 40363/40363/29749 +f 40363/40363/29749 40365/40365/29750 40366/40366/29751 +f 40363/40363/29749 40366/40366/29751 40367/40367/29752 +f 40364/40364/29742 40363/40363/29749 40367/40367/29752 +f 40364/40364/29742 40367/40367/29752 40368/40368/29672 +f 40233/40233/29642 40231/40231/29641 40369/40369/29753 +f 40233/40233/29642 40369/40369/29753 40351/40351/29737 +f 40231/40231/29641 40230/40230/29640 40355/40355/29741 +f 40231/40231/29641 40355/40355/29741 40369/40369/29753 +f 40369/40369/29753 40355/40355/29741 40262/40262/29669 +f 40369/40369/29753 40262/40262/29669 40274/40274/29680 +f 40351/40351/29737 40369/40369/29753 40274/40274/29680 +f 40351/40351/29737 40274/40274/29680 40273/40273/29679 +f 40207/40207/29620 40370/40370/29754 40371/40371/29755 +f 40207/40207/29620 40371/40371/29755 40340/40340/29728 +f 40370/40370/29754 40347/40347/29733 40350/40350/29736 +f 40370/40370/29754 40350/40350/29736 40371/40371/29755 +f 40371/40371/29755 40350/40350/29736 40353/40353/29739 +f 40371/40371/29755 40353/40353/29739 40372/40372/29756 +f 40340/40340/29728 40371/40371/29755 40372/40372/29756 +f 40340/40340/29728 40372/40372/29756 40242/40242/29651 +f 40308/40308/29703 40373/40373/29757 40374/40374/29758 +f 40308/40308/29703 40374/40374/29758 40309/40309/29704 +f 40375/40375/29759 40353/40353/29739 40352/40352/29738 +f 40375/40375/29759 40352/40352/29738 40376/40376/29760 +f 40376/40376/29760 40352/40352/29738 40273/40273/29679 +f 40376/40376/29760 40273/40273/29679 40272/40272/29676 +f 40309/40309/29704 40374/40374/29758 40269/40269/29676 +f 40309/40309/29704 40269/40269/29676 40268/40268/29675 +f 38955/38955/28562 40377/40377/29761 40378/40378/29762 +f 38955/38955/28562 40378/40378/29762 38956/38956/28563 +f 40379/40379/29761 40332/40332/29720 40329/40329/29717 +f 40379/40379/29761 40329/40329/29717 40380/40380/29762 +f 40380/40380/29762 40329/40329/29717 40328/40328/29716 +f 40380/40380/29762 40328/40328/29716 40381/40381/29763 +f 38956/38956/28563 40378/40378/29762 40382/40382/29764 +f 38956/38956/28563 40382/40382/29764 38958/38958/28564 +f 40062/40062/29499 40383/40383/29606 40384/40384/29765 +f 40062/40062/29499 40384/40384/29765 40063/40063/29500 +f 40190/40190/29606 40189/40189/29605 40362/40362/29748 +f 40190/40190/29606 40362/40362/29748 40385/40385/29766 +f 40385/40385/29766 40362/40362/29748 40361/40361/29747 +f 40385/40385/29766 40361/40361/29747 40386/40386/29767 +f 40063/40063/29500 40384/40384/29765 40387/40387/29768 +f 40063/40063/29500 40387/40387/29768 40065/40065/29501 +f 38881/38881/28493 40244/40244/29652 40388/40388/29769 +f 38881/38881/28493 40388/40388/29769 40316/40316/29709 +f 40243/40243/29652 40242/40242/29651 40372/40372/29756 +f 40243/40243/29652 40372/40372/29756 40389/40389/29770 +f 40389/40389/29770 40372/40372/29756 40353/40353/29739 +f 40389/40389/29770 40353/40353/29739 40375/40375/29759 +f 40316/40316/29709 40388/40388/29769 40373/40373/29757 +f 40316/40316/29709 40373/40373/29757 40308/40308/29703 +f 40170/40170/29587 40390/40390/29771 40391/40391/29772 +f 40170/40170/29587 40391/40391/29772 40323/40323/29713 +f 40392/40392/29771 40347/40347/29733 40370/40370/29754 +f 40392/40392/29771 40370/40370/29754 40393/40393/29773 +f 40393/40393/29773 40370/40370/29754 40207/40207/29620 +f 40393/40393/29773 40207/40207/29620 40206/40206/29619 +f 40323/40323/29713 40391/40391/29772 40203/40203/29616 +f 40323/40323/29713 40203/40203/29616 40202/40202/29615 +f 39069/39069/28668 40394/40394/29774 40395/40395/29775 +f 39069/39069/28668 40395/40395/29775 39070/39070/28669 +f 40396/40396/29774 40357/40357/29743 40397/40397/29776 +f 40396/40396/29774 40397/40397/29776 40398/40398/29777 +f 40398/40398/29777 40397/40397/29776 40218/40218/29629 +f 40398/40398/29777 40218/40218/29629 40217/40217/29626 +f 39070/39070/28669 40395/40395/29775 40214/40214/29626 +f 39070/39070/28669 40214/40214/29626 39072/39072/28670 +f 40070/40070/28643 40399/40399/29778 40400/40400/29779 +f 40070/40070/28643 40400/40400/29779 40071/40071/29505 +f 40401/40401/29778 40334/40334/29722 40337/40337/29725 +f 40401/40401/29778 40337/40337/29725 40402/40402/29780 +f 40402/40402/29780 40337/40337/29725 40256/40256/29664 +f 40402/40402/29780 40256/40256/29664 40255/40255/29663 +f 40071/40071/29505 40400/40400/29779 40403/40403/29660 +f 40071/40071/29505 40403/40403/29660 40073/40073/29507 +f 40167/40167/29585 40235/40235/29644 40404/40404/29781 +f 40167/40167/29585 40404/40404/29781 40168/40168/29586 +f 40234/40234/29643 40233/40233/29642 40348/40348/29734 +f 40234/40234/29643 40348/40348/29734 40405/40405/29781 +f 40405/40405/29781 40348/40348/29734 40347/40347/29733 +f 40405/40405/29781 40347/40347/29733 40392/40392/29771 +f 40168/40168/29586 40404/40404/29781 40390/40390/29771 +f 40168/40168/29586 40390/40390/29771 40170/40170/29587 +f 38978/38978/28584 40201/40201/29614 40406/40406/29782 +f 38978/38978/28584 40406/40406/29782 40280/40280/29686 +f 40200/40200/29614 40199/40199/29613 40346/40346/29732 +f 40200/40200/29614 40346/40346/29732 40407/40407/29782 +f 40407/40407/29782 40346/40346/29732 40345/40345/29648 +f 40407/40407/29782 40345/40345/29648 40408/40408/29647 +f 40280/40280/29686 40406/40406/29782 40236/40236/29645 +f 40280/40280/29686 40236/40236/29645 38878/38878/28490 +f 38892/38892/28501 40267/40267/29674 40409/40409/29783 +f 38892/38892/28501 40409/40409/29783 40301/40301/29697 +f 40266/40266/29673 40265/40265/29672 40410/40410/29784 +f 40266/40266/29673 40410/40410/29784 40411/40411/29783 +f 40412/40412/29783 40367/40367/29752 40366/40366/29751 +f 40412/40412/29783 40366/40366/29751 40413/40413/29785 +f 40301/40301/29697 40409/40409/29783 40414/40414/29785 +f 40301/40301/29697 40414/40414/29785 40302/40302/29698 +f 40213/40213/29625 40212/40212/29624 40415/40415/29786 +f 40213/40213/29625 40415/40415/29786 40296/40296/29695 +f 40416/40416/29787 40343/40343/29623 40341/40341/29729 +f 40416/40416/29787 40341/40341/29729 40417/40417/29786 +f 40417/40417/29786 40341/40341/29729 40332/40332/29720 +f 40417/40417/29786 40332/40332/29720 40379/40379/29761 +f 40296/40296/29695 40415/40415/29786 40377/40377/29761 +f 40296/40296/29695 40377/40377/29761 38955/38955/28562 +f 38958/38958/28564 40382/40382/29764 40418/40418/29788 +f 38958/38958/28564 40418/40418/29788 39042/39042/28641 +f 40381/40381/29763 40328/40328/29716 40335/40335/29723 +f 40381/40381/29763 40335/40335/29723 40419/40419/29789 +f 40419/40419/29789 40335/40335/29723 40334/40334/29722 +f 40419/40419/29789 40334/40334/29722 40401/40401/29778 +f 39042/39042/28641 40418/40418/29788 40420/40420/29778 +f 39042/39042/28641 40420/40420/29778 39044/39044/28643 +f 39829/39829/29308 40421/40421/29790 40422/40422/29791 +f 39829/39829/29308 40422/40422/29791 39830/39830/29309 +f 40421/40421/29790 39859/39859/29331 39865/39865/29337 +f 40421/40421/29790 39865/39865/29337 40422/40422/29791 +f 40423/40423/29792 39871/39871/29340 39872/39872/29332 +f 40423/40423/29792 39872/39872/29332 40424/40424/29793 +f 39832/39832/29309 40425/40425/29792 40426/40426/29794 +f 39832/39832/29309 40426/40426/29794 39799/39799/29284 +f 39799/39799/29284 40426/40426/29794 40427/40427/29795 +f 39799/39799/29284 40427/40427/29795 39800/39800/29285 +f 40426/40426/29794 39860/39860/29332 39863/39863/29335 +f 40426/40426/29794 39863/39863/29335 40427/40427/29795 +f 40427/40427/29795 39863/39863/29335 39815/39815/29296 +f 40427/40427/29795 39815/39815/29296 40428/40428/29796 +f 39800/39800/29285 40427/40427/29795 40428/40428/29796 +f 39800/39800/29285 40428/40428/29796 39801/39801/29286 +f 39837/39837/29314 40429/40429/29797 40430/40430/29798 +f 39837/39837/29314 40430/40430/29798 39840/39840/29317 +f 40429/40429/29797 39851/39851/29305 39854/39854/29329 +f 40429/40429/29797 39854/39854/29329 40430/40430/29798 +f 40430/40430/29798 39854/39854/29329 39859/39859/29331 +f 40430/40430/29798 39859/39859/29331 40421/40421/29790 +f 39840/39840/29317 40430/40430/29798 40421/40421/29790 +f 39840/39840/29317 40421/40421/29790 39829/39829/29308 +f 39801/39801/29286 40428/40428/29796 40431/40431/29799 +f 39801/39801/29286 40431/40431/29799 39834/39834/29311 +f 40428/40428/29796 39815/39815/29296 39818/39818/29299 +f 40428/40428/29796 39818/39818/29299 40431/40431/29799 +f 40432/40432/29800 39825/39825/29299 39826/39826/29305 +f 40432/40432/29800 39826/39826/29305 40433/40433/29801 +f 39836/39836/29313 40434/40434/29802 40429/40429/29797 +f 39836/39836/29313 40429/40429/29797 39837/39837/29314 +f 38812/38812/28429 38811/38811/28428 40435/40435/29803 +f 38812/38812/28429 40435/40435/29803 40436/40436/29804 +f 38811/38811/28428 38810/38810/28427 40437/40437/29805 +f 38811/38811/28428 40437/40437/29805 40435/40435/29803 +f 40438/40438/29803 40439/40439/29806 39422/39422/28972 +f 40438/40438/29803 39422/39422/28972 40160/40160/29580 +f 40440/40440/29807 40438/40438/29803 40160/40160/29580 +f 40440/40440/29807 40160/40160/29580 39396/39396/28951 +f 38948/38948/28555 38947/38947/28554 40441/40441/29808 +f 38948/38948/28555 40441/40441/29808 40442/40442/29809 +f 40443/40443/29810 40444/40444/28553 40445/40445/29811 +f 40443/40443/29810 40445/40445/29811 40446/40446/29808 +f 40446/40446/29808 40445/40445/29811 39431/39431/28978 +f 40446/40446/29808 39431/39431/28978 40156/40156/29578 +f 40447/40447/29809 40446/40446/29808 40156/40156/29578 +f 40447/40447/29809 40156/40156/29578 39406/39406/28958 +f 40448/40448/29108 40449/40449/29107 40450/40450/29812 +f 40448/40448/29108 40450/40450/29812 40451/40451/29813 +f 40449/40449/29107 40452/40452/29106 40453/40453/29814 +f 40449/40449/29107 40453/40453/29814 40450/40450/29812 +f 40450/40450/29812 40453/40453/29814 39410/39410/28962 +f 40450/40450/29812 39410/39410/28962 40131/40131/29556 +f 40451/40451/29813 40450/40450/29812 40131/40131/29556 +f 40451/40451/29813 40131/40131/29556 39426/39426/28976 +f 40454/40454/29815 40455/40455/28659 40456/40456/29816 +f 40454/40454/29815 40456/40456/29816 40457/40457/29817 +f 40455/40455/28659 40458/40458/28658 40459/40459/29818 +f 40455/40455/28659 40459/40459/29818 40456/40456/29816 +f 40456/40456/29816 40459/40459/29818 39443/39443/28989 +f 40456/40456/29816 39443/39443/28989 40128/40128/29553 +f 40457/40457/29817 40456/40456/29816 40128/40128/29553 +f 40457/40457/29817 40128/40128/29553 39435/39435/28982 +f 40460/40460/29061 40461/40461/29060 40462/40462/29819 +f 40460/40460/29061 40462/40462/29819 40463/40463/29820 +f 40461/40461/29060 40464/40464/29059 40465/40465/29821 +f 40461/40461/29060 40465/40465/29821 40462/40462/29819 +f 40462/40462/29819 40465/40465/29821 40094/40094/29524 +f 40462/40462/29819 40094/40094/29524 40092/40092/29522 +f 40463/40463/29820 40462/40462/29819 40092/40092/29522 +f 40463/40463/29820 40092/40092/29522 39447/39447/28993 +f 40466/40466/29822 40467/40467/29823 40468/40468/29824 +f 40466/40466/29822 40468/40468/29824 40469/40469/29825 +f 40467/40467/29823 40470/40470/29026 40471/40471/29826 +f 40467/40467/29823 40471/40471/29826 40468/40468/29824 +f 40468/40468/29824 40471/40471/29826 40084/40084/29516 +f 40468/40468/29824 40084/40084/29516 40082/40082/29514 +f 40469/40469/29825 40468/40468/29824 40082/40082/29514 +f 40469/40469/29825 40082/40082/29514 39414/39414/28966 +f 40472/40472/29543 40473/40473/29827 40474/40474/29828 +f 40472/40472/29543 40474/40474/29828 40475/40475/29829 +f 40473/40473/29827 40476/40476/29480 40477/40477/29830 +f 40473/40473/29827 40477/40477/29830 40474/40474/29828 +f 40474/40474/29828 40477/40477/29830 39455/39455/29000 +f 40474/40474/29828 39455/39455/29000 40050/40050/29488 +f 40475/40475/29829 40474/40474/29828 40050/40050/29488 +f 40475/40475/29829 40050/40050/29488 40049/40049/29487 +f 40478/40478/29537 40479/40479/29831 40480/40480/29832 +f 40478/40478/29537 40480/40480/29832 40481/40481/29833 +f 40479/40479/29831 40482/40482/29471 40483/40483/29834 +f 40479/40479/29831 40483/40483/29834 40480/40480/29832 +f 40480/40480/29832 40483/40483/29834 39468/39468/29011 +f 40480/40480/29832 39468/39468/29011 40044/40044/29483 +f 40481/40481/29833 40480/40480/29832 40044/40044/29483 +f 40481/40481/29833 40044/40044/29483 40043/40043/29482 +f 38916/38916/28523 40008/40008/29451 40484/40484/29835 +f 38916/38916/28523 40484/40484/29835 38915/38915/28516 +f 40008/40008/29451 39142/39142/28736 40485/40485/29836 +f 40008/40008/29451 40485/40485/29836 40484/40484/29835 +f 40486/40486/29837 40487/40487/29838 39079/39079/28677 +f 40486/40486/29837 39079/39079/28677 40016/40016/29458 +f 40488/40488/28516 40486/40486/29837 40016/40016/29458 +f 40488/40488/28516 40016/40016/29458 40015/40015/29457 +f 39097/39097/28620 40005/40005/29448 40489/40489/29839 +f 39097/39097/28620 40489/40489/29839 40490/40490/29840 +f 40005/40005/29448 39148/39148/28742 40491/40491/29841 +f 40005/40005/29448 40491/40491/29841 40489/40489/29839 +f 40492/40492/29842 40493/40493/29841 39125/39125/28720 +f 40492/40492/29842 39125/39125/28720 40010/40010/29453 +f 40494/40494/29843 40492/40492/29842 40010/40010/29453 +f 40494/40494/29843 40010/40010/29453 40009/40009/29452 +f 39901/39901/29366 39900/39900/29365 40495/40495/29844 +f 39901/39901/29366 40495/40495/29844 40496/40496/29845 +f 39899/39899/29365 39898/39898/29364 39979/39979/29428 +f 39899/39899/29365 39979/39979/29428 40497/40497/29844 +f 40498/40498/29844 39977/39977/29428 39976/39976/29427 +f 40498/40498/29844 39976/39976/29427 39992/39992/29436 +f 40496/40496/29845 40495/40495/29844 39990/39990/29436 +f 40496/40496/29845 39990/39990/29436 39707/39707/29210 +f 39733/39733/29233 39983/39983/29432 40499/40499/29846 +f 39733/39733/29233 40499/40499/29846 40500/40500/29847 +f 39982/39982/29431 39959/39959/29411 40501/40501/29848 +f 39982/39982/29431 40501/40501/29848 40502/40502/29849 +f 40503/40503/29846 40504/40504/29850 39966/39966/29418 +f 40503/40503/29846 39966/39966/29418 39987/39987/29435 +f 40500/40500/29847 40499/40499/29846 39985/39985/29433 +f 40500/40500/29847 39985/39985/29433 39984/39984/29218 +f 39932/39932/29390 39965/39965/29417 40505/40505/29851 +f 39932/39932/29390 40505/40505/29851 40506/40506/29852 +f 39965/39965/29417 39964/39964/29416 39996/39996/29438 +f 39965/39965/29417 39996/39996/29438 40505/40505/29851 +f 40507/40507/29851 39993/39993/29438 39976/39976/29427 +f 40507/40507/29851 39976/39976/29427 39974/39974/29425 +f 40508/40508/29852 40507/40507/29851 39974/39974/29425 +f 40508/40508/29852 39974/39974/29425 39917/39917/29380 +f 39959/39959/29411 39958/39958/29410 40509/40509/29853 +f 39959/39959/29411 40509/40509/29853 40501/40501/29848 +f 39958/39958/29410 39895/39895/29361 39911/39911/29374 +f 39958/39958/29410 39911/39911/29374 40509/40509/29853 +f 40510/40510/29853 39908/39908/29373 39907/39907/29372 +f 40510/40510/29853 39907/39907/29372 39967/39967/29419 +f 40504/40504/29850 40510/40510/29853 39967/39967/29419 +f 40504/40504/29850 39967/39967/29419 39966/39966/29418 +f 39167/39167/28760 39702/39702/29205 40511/40511/29854 +f 39167/39167/28760 40511/40511/29854 40512/40512/29855 +f 39701/39701/29204 39700/39700/29203 40513/40513/29856 +f 39701/39701/29204 40513/40513/29856 40514/40514/29857 +f 40514/40514/29857 40513/40513/29856 39902/39902/29367 +f 40514/40514/29857 39902/39902/29367 39946/39946/29400 +f 40515/40515/29858 40514/40514/29857 39946/39946/29400 +f 40515/40515/29858 39946/39946/29400 39945/39945/28752 +f 39886/39886/29352 39939/39939/29396 40516/40516/29859 +f 39886/39886/29352 40516/40516/29859 40517/40517/29860 +f 39938/39938/29396 39935/39935/29393 40518/40518/29861 +f 39938/39938/29396 40518/40518/29861 40519/40519/29859 +f 40519/40519/29859 40518/40518/29861 39912/39912/29375 +f 40519/40519/29859 39912/39912/29375 39942/39942/29399 +f 40520/40520/29860 40521/40521/29859 39940/39940/29397 +f 40520/40520/29860 39940/39940/29397 39875/39875/29343 +f 39935/39935/29393 39934/39934/29392 40522/40522/29862 +f 39935/39935/29393 40522/40522/29862 40518/40518/29861 +f 39933/39933/29391 39932/39932/29390 40506/40506/29852 +f 39933/39933/29391 40506/40506/29852 40523/40523/29862 +f 40524/40524/29863 40508/40508/29852 39917/39917/29380 +f 40524/40524/29863 39917/39917/29380 39916/39916/29379 +f 40518/40518/29861 40522/40522/29862 39913/39913/29376 +f 40518/40518/29861 39913/39913/29376 39912/39912/29375 +f 39700/39700/29203 40002/40002/29445 40525/40525/29864 +f 39700/39700/29203 40525/40525/29864 40513/40513/29856 +f 40001/40001/29445 39962/39962/29414 39972/39972/29422 +f 40001/40001/29445 39972/39972/29422 40526/40526/29864 +f 40527/40527/29865 39970/39970/29422 39907/39907/29372 +f 40527/40527/29865 39907/39907/29372 39906/39906/29371 +f 40513/40513/29856 40525/40525/29864 39903/39903/29368 +f 40513/40513/29856 39903/39903/29368 39902/39902/29367 +f 39146/39146/28740 39889/39889/29355 40528/40528/29866 +f 39146/39146/28740 40528/40528/29866 40529/40529/29867 +f 39889/39889/29355 39736/39736/29235 40530/40530/29868 +f 39889/39889/29355 40530/40530/29868 40528/40528/29866 +f 40531/40531/29866 40532/40532/29869 39711/39711/29214 +f 40531/40531/29866 39711/39711/29214 39880/39880/29347 +f 40533/40533/29867 40531/40531/29866 39880/39880/29347 +f 40533/40533/29867 39880/39880/29347 39129/39129/28724 +f 39140/39140/28734 39887/39887/29353 40534/40534/29870 +f 39140/39140/28734 40534/40534/29870 40535/40535/29871 +f 39887/39887/29353 39886/39886/29352 40517/40517/29860 +f 39887/39887/29353 40517/40517/29860 40534/40534/29870 +f 40536/40536/29870 40520/40520/29860 39875/39875/29343 +f 40536/40536/29870 39875/39875/29343 39873/39873/29341 +f 40537/40537/29872 40536/40536/29870 39873/39873/29341 +f 40537/40537/29872 39873/39873/29341 39083/39083/28681 +f 39736/39736/29235 39735/39735/29234 40538/40538/29873 +f 39736/39736/29235 40538/40538/29873 40530/40530/29868 +f 39734/39734/29234 39733/39733/29233 40500/40500/29847 +f 39734/39734/29234 40500/40500/29847 40539/40539/29873 +f 40539/40539/29873 40500/40500/29847 39984/39984/29218 +f 40539/40539/29873 39984/39984/29218 40540/40540/29215 +f 40532/40532/29869 40541/40541/29873 39712/39712/29215 +f 40532/40532/29869 39712/39712/29215 39711/39711/29214 +f 39954/39954/28719 39953/39953/29406 40542/40542/29874 +f 39954/39954/28719 40542/40542/29874 40543/40543/29875 +f 39953/39953/29406 39901/39901/29366 40496/40496/29845 +f 39953/39953/29406 40496/40496/29845 40542/40542/29874 +f 40542/40542/29874 40496/40496/29845 39707/39707/29210 +f 40542/40542/29874 39707/39707/29210 39704/39704/29207 +f 40543/40543/29875 40542/40542/29874 39704/39704/29207 +f 40543/40543/29875 39704/39704/29207 39703/39703/29206 +f 39296/39296/28870 39295/39295/28869 40544/40544/29876 +f 39296/39296/28870 40544/40544/29876 40545/40545/29877 +f 39295/39295/28869 39294/39294/28868 40546/40546/29878 +f 39295/39295/28869 40546/40546/29878 40544/40544/29876 +f 40547/40547/29879 40548/40548/29878 39688/39688/29191 +f 40547/40547/29879 39688/39688/29191 39686/39686/29189 +f 40549/40549/29877 40547/40547/29879 39686/39686/29189 +f 40549/40549/29877 39686/39686/29189 39299/39299/28873 +f 39310/39310/28880 39693/39693/29196 40550/40550/29880 +f 39310/39310/28880 40550/40550/29880 40551/40551/29881 +f 39693/39693/29196 39675/39675/29180 39672/39672/29177 +f 39693/39693/29196 39672/39672/29177 40550/40550/29880 +f 40552/40552/29880 40553/40553/29177 39682/39682/29187 +f 40552/40552/29880 39682/39682/29187 39680/39680/29185 +f 40554/40554/29881 40552/40552/29880 39680/39680/29185 +f 40554/40554/29881 39680/39680/29185 39267/39267/28844 +f 39292/39292/28866 39685/39685/29188 40555/40555/29882 +f 39292/39292/28866 40555/40555/29882 39293/39293/28867 +f 39685/39685/29188 40556/40556/29883 40557/40557/29179 +f 39685/39685/29188 40557/40557/29179 40555/40555/29882 +f 40555/40555/29882 40557/40557/29179 40558/40558/29191 +f 40555/40555/29882 40558/40558/29191 40546/40546/29878 +f 39293/39293/28867 40555/40555/29882 40546/40546/29878 +f 39293/39293/28867 40546/40546/29878 39294/39294/28868 +f 40559/40559/28608 40560/40560/29884 40561/40561/29885 +f 40559/40559/28608 40561/40561/29885 40562/40562/29886 +f 40560/40560/29884 40563/40563/28637 40564/40564/29887 +f 40560/40560/29884 40564/40564/29887 40561/40561/29885 +f 40561/40561/29885 40564/40564/29887 39663/39663/29152 +f 40561/40561/29885 39663/39663/29152 39661/39661/29171 +f 40562/40562/29886 40561/40561/29885 39661/39661/29171 +f 40562/40562/29886 39661/39661/29171 39315/39315/28884 +f 39632/39632/29147 39659/39659/29170 40565/40565/29888 +f 39632/39632/29147 40565/40565/29888 39633/39633/29148 +f 39659/39659/29170 39531/39531/29069 39530/39530/29067 +f 39659/39659/29170 39530/39530/29067 40565/40565/29888 +f 40565/40565/29888 39530/39530/29067 40566/40566/29889 +f 40565/40565/29888 40566/40566/29889 40567/40567/29890 +f 39633/39633/29148 40565/40565/29888 40567/40567/29890 +f 39633/39633/29148 40567/40567/29890 39634/39634/29149 +f 38832/38832/28448 38830/38830/28447 40568/40568/29891 +f 38832/38832/28448 40568/40568/29891 40569/40569/29892 +f 38830/38830/28447 38829/38829/28446 40570/40570/29173 +f 38830/38830/28447 40570/40570/29173 40568/40568/29891 +f 40568/40568/29891 40570/40570/29173 40571/40571/29152 +f 40568/40568/29891 40571/40571/29152 40572/40572/29150 +f 40569/40569/29892 40568/40568/29891 40572/40572/29150 +f 40569/40569/29892 40572/40572/29150 40573/40573/29142 +f 38832/38832/28448 40569/40569/29892 40574/40574/29893 +f 38832/38832/28448 40574/40574/29893 39653/39653/29165 +f 40569/40569/29892 40573/40573/29142 40575/40575/29894 +f 40569/40569/29892 40575/40575/29894 40574/40574/29893 +f 40574/40574/29893 40575/40575/29894 39639/39639/29149 +f 40574/40574/29893 39639/39639/29149 39642/39642/29156 +f 39653/39653/29165 40574/40574/29893 39642/39642/29156 +f 39653/39653/29165 39642/39642/29156 39647/39647/29161 +f 38841/38841/28456 38840/38840/28455 40576/40576/29895 +f 38841/38841/28456 40576/40576/29895 40577/40577/28898 +f 38840/38840/28455 38839/38839/28454 40578/40578/29896 +f 38840/38840/28455 40578/40578/29896 40576/40576/29895 +f 40579/40579/29895 40580/40580/29897 39333/39333/28900 +f 40579/40579/29895 39333/39333/28900 39607/39607/29127 +f 39331/39331/28898 40579/40579/29895 39607/39607/29127 +f 39331/39331/28898 39607/39607/29127 39332/39332/28899 +f 39321/39321/28888 40581/40581/29043 40582/40582/29898 +f 39321/39321/28888 40582/40582/29898 39322/39322/28889 +f 39503/39503/29043 39502/39502/29042 40583/40583/29899 +f 39503/39503/29043 40583/40583/29899 40584/40584/29898 +f 40582/40582/29898 40585/40585/29899 39353/39353/28916 +f 40582/40582/29898 39353/39353/28916 39602/39602/29123 +f 39322/39322/28889 40582/40582/29898 39602/39602/29123 +f 39322/39322/28889 39602/39602/29123 39323/39323/28890 +f 40586/40586/29900 40587/40587/29175 40588/40588/29901 +f 40586/40586/29900 40588/40588/29901 40589/40589/29902 +f 40587/40587/29175 40590/40590/29903 40591/40591/29158 +f 40587/40587/29175 40591/40591/29158 40588/40588/29901 +f 40588/40588/29901 40591/40591/29158 39527/39527/29066 +f 40588/40588/29901 39527/39527/29066 39525/39525/29064 +f 40589/40589/29902 40588/40588/29901 39525/39525/29064 +f 40589/40589/29902 39525/39525/29064 39324/39324/28891 +f 40482/40482/29471 40592/40592/29469 40593/40593/29904 +f 40482/40482/29471 40593/40593/29904 40483/40483/29834 +f 40029/40029/29469 39016/39016/28618 39015/39015/28617 +f 40029/40029/29469 39015/39015/28617 40594/40594/29904 +f 40593/40593/29904 40595/40595/29905 39472/39472/29015 +f 40593/40593/29904 39472/39472/29015 39469/39469/29012 +f 40483/40483/29834 40593/40593/29904 39469/39469/29012 +f 40483/40483/29834 39469/39469/29012 39468/39468/29011 +f 40476/40476/29480 40596/40596/29479 40597/40597/29906 +f 40476/40476/29480 40597/40597/29906 40477/40477/29830 +f 40040/40040/29479 38913/38913/28521 38912/38912/28520 +f 40040/40040/29479 38912/38912/28520 40598/40598/29907 +f 40597/40597/29906 40599/40599/29908 40600/40600/29909 +f 40597/40597/29906 40600/40600/29909 39456/39456/29001 +f 40477/40477/29830 40597/40597/29906 39456/39456/29001 +f 40477/40477/29830 39456/39456/29001 39455/39455/29000 +f 40458/40458/28658 40601/40601/29574 40602/40602/29910 +f 40458/40458/28658 40602/40602/29910 40459/40459/29818 +f 40601/40601/29574 40460/40460/29061 40463/40463/29820 +f 40601/40601/29574 40463/40463/29820 40602/40602/29910 +f 40602/40602/29910 40463/40463/29820 39447/39447/28993 +f 40602/40602/29910 39447/39447/28993 39444/39444/28990 +f 40459/40459/29818 40602/40602/29910 39444/39444/28990 +f 40459/40459/29818 39444/39444/28990 39443/39443/28989 +f 40444/40444/28553 40603/40603/29911 40604/40604/29912 +f 40444/40444/28553 40604/40604/29912 40445/40445/29811 +f 40603/40603/29911 40454/40454/29815 40457/40457/29817 +f 40603/40603/29911 40457/40457/29817 40604/40604/29912 +f 40604/40604/29912 40457/40457/29817 39435/39435/28982 +f 40604/40604/29912 39435/39435/28982 39432/39432/28979 +f 40445/40445/29811 40604/40604/29912 39432/39432/28979 +f 40445/40445/29811 39432/39432/28979 39431/39431/28978 +f 38810/38810/28427 40182/40182/29598 40605/40605/29913 +f 38810/38810/28427 40605/40605/29913 40437/40437/29805 +f 40606/40606/29598 40448/40448/29108 40451/40451/29813 +f 40606/40606/29598 40451/40451/29813 40607/40607/29913 +f 40607/40607/29913 40451/40451/29813 39426/39426/28976 +f 40607/40607/29913 39426/39426/28976 39423/39423/28973 +f 40439/40439/29806 40607/40607/29913 39423/39423/28973 +f 40439/40439/29806 39423/39423/28973 39422/39422/28972 +f 40452/40452/29106 40608/40608/29549 40609/40609/29914 +f 40452/40452/29106 40609/40609/29914 40453/40453/29814 +f 40608/40608/29549 40466/40466/29822 40469/40469/29825 +f 40608/40608/29549 40469/40469/29825 40609/40609/29914 +f 40609/40609/29914 40469/40469/29825 39414/39414/28966 +f 40609/40609/29914 39414/39414/28966 39411/39411/28963 +f 40453/40453/29814 40609/40609/29914 39411/39411/28963 +f 40453/40453/29814 39411/39411/28963 39410/39410/28962 +f 39567/39567/28528 39566/39566/29093 40610/40610/29915 +f 39567/39567/28528 40610/40610/29915 40611/40611/29916 +f 39566/39566/29093 38948/38948/28555 40442/40442/29809 +f 39566/39566/29093 40442/40442/29809 40610/40610/29915 +f 40612/40612/29915 40447/40447/29809 39406/39406/28958 +f 40612/40612/29915 39406/39406/28958 39404/39404/28956 +f 40613/40613/29916 40612/40612/29915 39404/39404/28956 +f 40613/40613/29916 39404/39404/28956 39389/39389/28947 +f 39541/39541/28624 39540/39540/29078 40614/40614/29917 +f 39541/39541/28624 40614/40614/29917 40615/40615/29918 +f 39540/39540/29078 38812/38812/28429 40436/40436/29804 +f 39540/39540/29078 40436/40436/29804 40614/40614/29917 +f 40616/40616/29919 40440/40440/29807 39396/39396/28951 +f 40616/40616/29919 39396/39396/28951 39394/39394/28949 +f 40617/40617/29920 40616/40616/29919 39394/39394/28949 +f 40617/40617/29920 39394/39394/28949 39371/39371/28930 +f 40618/40618/29921 40619/40619/28529 40620/40620/29922 +f 40618/40618/29921 40620/40620/29922 40621/40621/29923 +f 40622/40622/28529 39567/39567/28528 40611/40611/29916 +f 40622/40622/28529 40611/40611/29916 40623/40623/29922 +f 40620/40620/29922 40613/40613/29916 39389/39389/28947 +f 40620/40620/29922 39389/39389/28947 39387/39387/28945 +f 40621/40621/29923 40620/40620/29922 39387/39387/28945 +f 40621/40621/29923 39387/39387/28945 39382/39382/28940 +f 39537/39537/29075 39536/39536/29074 40624/40624/29924 +f 39537/39537/29075 40624/40624/29924 40625/40625/29925 +f 39536/39536/29074 38923/38923/28530 40626/40626/29926 +f 39536/39536/29074 40626/40626/29926 40624/40624/29924 +f 40627/40627/29927 40621/40621/29923 39382/39382/28940 +f 40627/40627/29927 39382/39382/28940 39380/39380/28938 +f 40628/40628/29925 40627/40627/29927 39380/39380/28938 +f 40628/40628/29925 39380/39380/28938 39346/39346/28910 +f 39109/39109/28705 39492/39492/29032 40629/40629/29928 +f 39109/39109/28705 40629/40629/29928 40630/40630/29929 +f 40631/40631/29032 40632/40632/29930 40633/40633/29931 +f 40631/40631/29032 40633/40633/29931 40634/40634/29932 +f 40634/40634/29932 40633/40633/29931 39367/39367/28926 +f 40634/40634/29932 39367/39367/28926 39376/39376/28934 +f 40635/40635/29929 40634/40634/29932 39376/39376/28934 +f 40635/40635/29929 39376/39376/28934 39362/39362/28923 +f 40632/40632/29930 40636/40636/28625 40637/40637/29933 +f 40632/40632/29930 40637/40637/29933 40633/40633/29931 +f 40638/40638/28625 39541/39541/28624 40615/40615/29918 +f 40638/40638/28625 40615/40615/29918 40639/40639/29933 +f 40637/40637/29933 40617/40617/29920 39371/39371/28930 +f 40637/40637/29933 39371/39371/28930 39368/39368/28927 +f 40633/40633/29931 40637/40637/29933 39368/39368/28927 +f 40633/40633/29931 39368/39368/28927 39367/39367/28926 +f 39111/39111/28707 39110/39110/28706 40640/40640/29934 +f 39111/39111/28707 40640/40640/29934 40641/40641/29935 +f 39110/39110/28706 39109/39109/28705 40630/40630/29929 +f 39110/39110/28706 40630/40630/29929 40640/40640/29934 +f 40642/40642/29936 40635/40635/29929 39362/39362/28923 +f 40642/40642/29936 39362/39362/28923 39360/39360/28921 +f 40643/40643/29935 40642/40642/29936 39360/39360/28921 +f 40643/40643/29935 39360/39360/28921 39337/39337/28904 +f 39502/39502/29042 39601/39601/29122 40644/40644/29937 +f 39502/39502/29042 40644/40644/29937 40583/40583/29899 +f 39601/39601/29122 39591/39591/29113 40645/40645/29938 +f 39601/39601/29122 40645/40645/29938 40644/40644/29937 +f 40646/40646/29937 40647/40647/29938 39342/39342/28906 +f 40646/40646/29937 39342/39342/28906 39354/39354/28917 +f 40585/40585/29899 40646/40646/29937 39354/39354/28917 +f 40585/40585/29899 39354/39354/28917 39353/39353/28916 +f 39591/39591/29113 39590/39590/29112 40648/40648/29939 +f 39591/39591/29113 40648/40648/29939 40645/40645/29938 +f 39590/39590/29112 39537/39537/29075 40625/40625/29925 +f 39590/39590/29112 40625/40625/29925 40648/40648/29939 +f 40649/40649/29939 40628/40628/29925 39346/39346/28910 +f 40649/40649/29939 39346/39346/28910 39343/39343/28907 +f 40647/40647/29938 40649/40649/29939 39343/39343/28907 +f 40647/40647/29938 39343/39343/28907 39342/39342/28906 +f 38839/38839/28454 39624/39624/29139 40650/40650/29940 +f 38839/38839/28454 40650/40650/29940 40578/40578/29896 +f 39624/39624/29139 39111/39111/28707 40641/40641/29935 +f 39624/39624/29139 40641/40641/29935 40650/40650/29940 +f 40651/40651/29941 40643/40643/29935 39337/39337/28904 +f 40651/40651/29941 39337/39337/28904 39334/39334/28901 +f 40580/40580/29897 40651/40651/29941 39334/39334/28901 +f 40580/40580/29897 39334/39334/28901 39333/39333/28900 +f 40586/40586/29900 40589/40589/29902 40652/40652/29942 +f 40586/40586/29900 40652/40652/29942 40653/40653/29050 +f 40589/40589/29902 39324/39324/28891 39327/39327/28894 +f 40589/40589/29902 39327/39327/28894 40652/40652/29942 +f 40652/40652/29942 39327/39327/28894 39332/39332/28899 +f 40652/40652/29942 39332/39332/28899 39609/39609/29129 +f 40653/40653/29050 40652/40652/29942 39609/39609/29129 +f 40653/40653/29050 39609/39609/29129 39611/39611/29051 +f 40559/40559/28608 40562/40562/29886 40654/40654/29943 +f 40559/40559/28608 40654/40654/29943 40655/40655/28609 +f 40562/40562/29886 39315/39315/28884 39318/39318/28887 +f 40562/40562/29886 39318/39318/28887 40654/40654/29943 +f 40654/40654/29943 39318/39318/28887 39323/39323/28890 +f 40654/40654/29943 39323/39323/28890 39604/39604/29125 +f 40655/40655/28609 40654/40654/29943 39604/39604/29125 +f 40655/40655/28609 39604/39604/29125 39606/39606/28610 +f 39278/39278/28852 39314/39314/28883 40656/40656/29944 +f 39278/39278/28852 40656/40656/29944 40657/40657/29945 +f 40658/40658/29946 40659/40659/28870 40660/40660/29877 +f 40658/40658/29946 40660/40660/29877 40661/40661/29944 +f 40662/40662/29947 40549/40549/29877 39299/39299/28873 +f 40662/40662/29947 39299/39299/28873 39297/39297/28871 +f 40663/40663/29945 40662/40662/29947 39297/39297/28871 +f 40663/40663/29945 39297/39297/28871 39285/39285/28859 +f 39253/39253/28834 39279/39279/28853 40664/40664/29948 +f 39253/39253/28834 40664/40664/29948 40665/40665/29949 +f 39279/39279/28853 39278/39278/28852 40657/40657/29945 +f 39279/39279/28853 40657/40657/29945 40664/40664/29948 +f 40666/40666/29948 40663/40663/29945 39285/39285/28859 +f 40666/40666/29948 39285/39285/28859 39283/39283/28857 +f 40667/40667/29949 40666/40666/29948 39283/39283/28857 +f 40667/40667/29949 39283/39283/28857 39213/39213/28802 +f 39242/39242/28826 39241/39241/28825 40668/40668/29950 +f 39242/39242/28826 40668/40668/29950 40669/40669/29951 +f 39241/39241/28825 39240/39240/28824 40670/40670/29952 +f 39241/39241/28825 40670/40670/29952 40668/40668/29950 +f 40671/40671/29950 40672/40672/29952 39263/39263/28840 +f 40671/40671/29950 39263/39263/28840 39280/39280/28854 +f 40673/40673/29953 40671/40671/29950 39280/39280/28854 +f 40673/40673/29953 39280/39280/28854 39258/39258/28838 +f 39240/39240/28824 39312/39312/28881 40674/40674/29954 +f 39240/39240/28824 40674/40674/29954 40670/40670/29952 +f 39311/39311/28881 39310/39310/28880 40551/40551/29881 +f 39311/39311/28881 40551/40551/29881 40675/40675/29954 +f 40676/40676/29955 40554/40554/29881 39267/39267/28844 +f 40676/40676/29955 39267/39267/28844 39264/39264/28841 +f 40672/40672/29952 40676/40676/29955 39264/39264/28841 +f 40672/40672/29952 39264/39264/28841 39263/39263/28840 +f 39246/39246/28813 39245/39245/28828 40677/40677/29956 +f 39246/39246/28813 40677/40677/29956 40678/40678/29957 +f 39245/39245/28828 39242/39242/28826 40669/40669/29951 +f 39245/39245/28828 40669/40669/29951 40677/40677/29956 +f 40679/40679/29956 40673/40673/29953 39258/39258/28838 +f 40679/40679/29956 39258/39258/28838 39256/39256/28836 +f 40680/40680/29958 40679/40679/29956 39256/39256/28836 +f 40680/40680/29958 39256/39256/28836 39186/39186/28779 +f 39197/39197/28789 39234/39234/28818 40681/40681/29959 +f 39197/39197/28789 40681/40681/29959 40682/40682/29960 +f 39234/39234/28818 39233/39233/28817 40683/40683/29961 +f 39234/39234/28818 40683/40683/29961 40681/40681/29959 +f 40684/40684/29959 40685/40685/29962 39209/39209/28798 +f 40684/40684/29959 39209/39209/28798 39221/39221/28808 +f 40686/40686/29960 40684/40684/29959 39221/39221/28808 +f 40686/40686/29960 39221/39221/28808 39204/39204/28795 +f 39255/39255/28817 39254/39254/28835 40687/40687/29963 +f 39255/39255/28817 40687/40687/29963 40688/40688/29962 +f 39254/39254/28835 39253/39253/28834 40665/40665/29949 +f 39254/39254/28835 40665/40665/29949 40687/40687/29963 +f 40689/40689/29964 40667/40667/29949 39213/39213/28802 +f 40689/40689/29964 39213/39213/28802 39210/39210/28799 +f 40685/40685/29962 40689/40689/29964 39210/39210/28799 +f 40685/40685/29962 39210/39210/28799 39209/39209/28798 +f 39179/39179/28772 39198/39198/28790 40690/40690/29965 +f 39179/39179/28772 40690/40690/29965 40691/40691/29966 +f 39198/39198/28790 39197/39197/28789 40682/40682/29960 +f 39198/39198/28790 40682/40682/29960 40690/40690/29965 +f 40692/40692/29965 40686/40686/29960 39204/39204/28795 +f 40692/40692/29965 39204/39204/28795 39202/39202/28793 +f 40693/40693/29967 40692/40692/29965 39202/39202/28793 +f 40693/40693/29967 39202/39202/28793 39162/39162/28756 +f 39157/39157/28751 39156/39156/28750 40694/40694/29968 +f 39157/39157/28751 40694/40694/29968 40695/40695/29969 +f 39156/39156/28750 39155/39155/28749 40696/40696/29970 +f 39156/39156/28750 40696/40696/29970 40694/40694/29968 +f 40697/40697/29968 40698/40698/29970 39182/39182/28775 +f 40697/40697/29968 39182/39182/28775 39199/39199/28791 +f 40699/40699/29969 40697/40697/29968 39199/39199/28791 +f 40699/40699/29969 39199/39199/28791 39117/39117/28713 +f 39155/39155/28749 39230/39230/28814 40700/40700/29971 +f 39155/39155/28749 40700/40700/29971 40696/40696/29970 +f 39230/39230/28814 39229/39229/28813 40701/40701/29958 +f 39230/39230/28814 40701/40701/29958 40700/40700/29971 +f 40702/40702/29971 40680/40680/29958 39186/39186/28779 +f 40702/40702/29971 39186/39186/28779 39183/39183/28776 +f 40698/40698/29970 40702/40702/29971 39183/39183/28776 +f 40698/40698/29970 39183/39183/28776 39182/39182/28775 +f 39181/39181/28774 39180/39180/28773 40703/40703/29972 +f 39181/39181/28774 40703/40703/29972 40704/40704/29402 +f 39180/39180/28773 39179/39179/28772 40691/40691/29966 +f 39180/39180/28773 40691/40691/29966 40703/40703/29972 +f 40705/40705/29973 40693/40693/29967 39162/39162/28756 +f 40705/40705/29973 39162/39162/28756 39159/39159/28753 +f 40706/40706/29402 40705/40705/29973 39159/39159/28753 +f 40706/40706/29402 39159/39159/28753 39158/39158/28752 +f 39148/39148/28742 39147/39147/28741 40707/40707/29974 +f 39148/39148/28742 40707/40707/29974 40491/40491/29841 +f 39147/39147/28741 39146/39146/28740 40529/40529/29867 +f 39147/39147/28741 40529/40529/29867 40707/40707/29974 +f 40708/40708/29975 40533/40533/29867 39129/39129/28724 +f 40708/40708/29975 39129/39129/28724 39126/39126/28721 +f 40493/40493/29841 40708/40708/29975 39126/39126/28721 +f 40493/40493/29841 39126/39126/28721 39125/39125/28720 +f 40709/40709/28768 40710/40710/29254 40711/40711/29976 +f 40709/40709/28768 40711/40711/29976 40712/40712/29212 +f 39766/39766/29254 39157/39157/28751 40695/40695/29969 +f 39766/39766/29254 40695/40695/29969 40713/40713/29976 +f 40711/40711/29976 40699/40699/29969 39117/39117/28713 +f 40711/40711/29976 39117/39117/28713 39114/39114/28710 +f 40712/40712/29212 40711/40711/29976 39114/39114/28710 +f 40712/40712/29212 39114/39114/28710 39113/39113/28709 +f 39142/39142/28736 39141/39141/28735 40714/40714/29977 +f 39142/39142/28736 40714/40714/29977 40485/40485/29836 +f 39141/39141/28735 39140/39140/28734 40535/40535/29871 +f 39141/39141/28735 40535/40535/29871 40714/40714/29977 +f 40715/40715/29978 40537/40537/29872 39083/39083/28681 +f 40715/40715/29978 39083/39083/28681 39080/39080/28678 +f 40487/40487/29838 40715/40715/29978 39080/39080/28678 +f 40487/40487/29838 39080/39080/28678 39079/39079/28677 +f 39051/39051/28650 39507/39507/29046 40716/40716/29979 +f 39051/39051/28650 40716/40716/29979 40014/40014/29456 +f 39507/39507/29046 39476/39476/29018 39475/39475/29016 +f 39507/39507/29046 39475/39475/29016 40716/40716/29979 +f 40717/40717/29979 40718/40718/29980 39014/39014/28616 +f 40717/40717/29979 39014/39014/28616 39011/39011/28613 +f 40719/40719/29455 40717/40717/29979 39011/39011/28613 +f 40719/40719/29455 39011/39011/28613 39010/39010/28612 +f 39548/39548/29082 39546/39546/29081 40720/40720/29981 +f 39548/39548/29082 40720/40720/29981 40721/40721/29460 +f 39546/39546/29081 39462/39462/29005 39460/39460/29004 +f 39546/39546/29081 39460/39460/29004 40720/40720/29981 +f 40720/40720/29981 39460/39460/29004 38909/38909/28517 +f 40720/40720/29981 38909/38909/28517 38906/38906/28514 +f 40721/40721/29460 40720/40720/29981 38906/38906/28514 +f 40721/40721/29460 38906/38906/28514 38905/38905/28513 +f 40464/40464/29059 40722/40722/29538 40723/40723/29982 +f 40464/40464/29059 40723/40723/29982 40465/40465/29821 +f 40722/40722/29538 40478/40478/29537 40481/40481/29833 +f 40722/40722/29538 40481/40481/29833 40723/40723/29982 +f 40723/40723/29982 40481/40481/29833 40043/40043/29482 +f 40723/40723/29982 40043/40043/29482 40724/40724/29983 +f 40465/40465/29821 40723/40723/29982 40724/40724/29983 +f 40465/40465/29821 40724/40724/29983 40094/40094/29524 +f 40470/40470/29026 40725/40725/29544 40726/40726/29984 +f 40470/40470/29026 40726/40726/29984 40471/40471/29826 +f 40725/40725/29544 40472/40472/29543 40475/40475/29829 +f 40725/40725/29544 40475/40475/29829 40726/40726/29984 +f 40726/40726/29984 40475/40475/29829 40049/40049/29487 +f 40726/40726/29984 40049/40049/29487 40727/40727/29985 +f 40471/40471/29826 40726/40726/29984 40727/40727/29985 +f 40471/40471/29826 40727/40727/29985 40084/40084/29516 +f 40728/40728/29986 40386/40386/29767 40729/40729/29987 +f 40728/40728/29986 40729/40729/29987 40730/40730/29988 +f 40386/40386/29767 40361/40361/29747 40358/40358/29744 +f 40386/40386/29767 40358/40358/29744 40729/40729/29987 +f 40729/40729/29987 40358/40358/29744 40357/40357/29743 +f 40729/40729/29987 40357/40357/29743 40396/40396/29774 +f 40731/40731/29989 40732/40732/29990 40394/40394/29774 +f 40731/40731/29989 40394/40394/29774 39069/39069/28668 +f 40218/40218/29629 40397/40397/29776 40733/40733/29991 +f 40218/40218/29629 40733/40733/29991 40365/40365/29750 +f 40397/40397/29776 40357/40357/29743 40360/40360/29746 +f 40397/40397/29776 40360/40360/29746 40733/40733/29991 +f 40733/40733/29991 40360/40360/29746 40186/40186/29602 +f 40733/40733/29991 40186/40186/29602 40734/40734/29992 +f 40365/40365/29750 40733/40733/29991 40734/40734/29992 +f 40365/40365/29750 40734/40734/29992 40366/40366/29751 +f 40302/40302/29698 40414/40414/29785 40735/40735/29993 +f 40302/40302/29698 40735/40735/29993 40736/40736/29994 +f 40413/40413/29785 40366/40366/29751 40734/40734/29992 +f 40413/40413/29785 40734/40734/29992 40737/40737/29993 +f 40737/40737/29993 40734/40734/29992 40186/40186/29602 +f 40737/40737/29993 40186/40186/29602 40185/40185/29601 +f 40736/40736/29994 40735/40735/29993 40183/40183/29599 +f 40736/40736/29994 40183/40183/29599 40141/40141/29565 +f 40304/40304/29022 40303/40303/29699 40738/40738/29995 +f 40304/40304/29022 40738/40738/29995 40739/40739/29542 +f 40303/40303/29699 40302/40302/29698 40736/40736/29994 +f 40303/40303/29699 40736/40736/29994 40738/40738/29995 +f 40738/40738/29995 40736/40736/29994 40141/40141/29565 +f 40738/40738/29995 40141/40141/29565 40138/40138/29562 +f 40739/40739/29542 40738/40738/29995 40138/40138/29562 +f 40739/40739/29542 40138/40138/29562 40137/40137/29539 +f 39054/39054/28653 40042/40042/29481 40740/40740/29996 +f 39054/39054/28653 40740/40740/29996 40145/40145/29569 +f 40042/40042/29481 40041/40041/29480 40741/40741/29997 +f 40042/40042/29481 40741/40741/29997 40740/40740/29996 +f 40740/40740/29996 40741/40741/29997 40118/40118/29543 +f 40740/40740/29996 40118/40118/29543 40115/40115/29540 +f 40145/40145/29569 40740/40740/29996 40115/40115/29540 +f 40145/40145/29569 40115/40115/29540 40114/40114/29539 +f 39099/39099/28695 40033/40033/29472 40742/40742/29998 +f 39099/39099/28695 40742/40742/29998 40057/40057/29494 +f 40033/40033/29472 40032/40032/29471 40743/40743/29999 +f 40033/40033/29472 40743/40743/29999 40742/40742/29998 +f 40742/40742/29998 40743/40743/29999 40112/40112/29537 +f 40742/40742/29998 40112/40112/29537 40109/40109/29534 +f 40057/40057/29494 40742/40742/29998 40109/40109/29534 +f 40057/40057/29494 40109/40109/29534 40058/40058/29495 +f 38900/38900/28508 40744/40744/30000 40745/40745/30001 +f 38900/38900/28508 40745/40745/30001 38901/38901/28509 +f 40744/40744/30000 40746/40746/30002 40747/40747/30003 +f 40744/40744/30000 40747/40747/30003 40745/40745/30001 +f 40745/40745/30001 40747/40747/30003 40748/40748/30004 +f 40745/40745/30001 40748/40748/30004 40749/40749/30005 +f 38901/38901/28509 40745/40745/30001 40749/40749/30005 +f 38901/38901/28509 40749/40749/30005 38902/38902/28510 +f 40084/40084/29516 40727/40727/29985 40750/40750/30006 +f 40084/40084/29516 40750/40750/30006 40085/40085/29517 +f 40727/40727/29985 40049/40049/29487 40052/40052/29490 +f 40727/40727/29985 40052/40052/29490 40750/40750/30006 +f 40751/40751/30006 40054/40054/29491 40025/40025/29466 +f 40751/40751/30006 40025/40025/29466 40752/40752/30007 +f 40087/40087/29517 40751/40751/30006 40752/40752/30007 +f 40087/40087/29517 40752/40752/30007 40088/40088/29519 +f 40094/40094/29524 40724/40724/29983 40753/40753/30008 +f 40094/40094/29524 40753/40753/30008 40095/40095/29525 +f 40724/40724/29983 40043/40043/29482 40046/40046/29485 +f 40724/40724/29983 40046/40046/29485 40753/40753/30008 +f 40754/40754/30008 40048/40048/29486 40037/40037/29476 +f 40754/40754/30008 40037/40037/29476 40755/40755/30009 +f 40756/40756/29525 40754/40754/30008 40755/40755/30009 +f 40756/40756/29525 40755/40755/30009 40104/40104/29526 +f 39075/39075/28673 40105/40105/29531 40757/40757/30010 +f 39075/39075/28673 40757/40757/30010 39067/39067/28666 +f 40105/40105/29531 40104/40104/29526 40755/40755/30009 +f 40105/40105/29531 40755/40755/30009 40757/40757/30010 +f 40757/40757/30010 40755/40755/30009 40037/40037/29476 +f 40757/40757/30010 40037/40037/29476 40034/40034/29473 +f 39067/39067/28666 40757/40757/30010 40034/40034/29473 +f 39067/39067/28666 40034/40034/29473 39064/39064/28663 +f 40080/40080/29512 40108/40108/29533 40758/40758/30011 +f 40080/40080/29512 40758/40758/30011 40759/40759/30012 +f 40108/40108/29533 40088/40088/29519 40752/40752/30007 +f 40108/40108/29533 40752/40752/30007 40758/40758/30011 +f 40758/40758/30011 40752/40752/30007 40025/40025/29466 +f 40758/40758/30011 40025/40025/29466 40022/40022/29463 +f 40759/40759/30012 40758/40758/30011 40022/40022/29463 +f 40759/40759/30012 40022/40022/29463 40021/40021/29462 +f 39047/39047/28646 40067/40067/29503 40760/40760/30013 +f 39047/39047/28646 40760/40760/30013 40036/40036/29475 +f 40067/40067/29503 40728/40728/29986 40730/40730/29988 +f 40067/40067/29503 40730/40730/29988 40760/40760/30013 +f 40761/40761/30014 40731/40731/29989 39069/39069/28668 +f 40761/40761/30014 39069/39069/28668 39068/39068/28667 +f 40036/40036/29475 40760/40760/30013 39065/39065/28664 +f 40036/40036/29475 39065/39065/28664 39064/39064/28663 +f 40762/40762/30015 40763/40763/30016 40764/40764/30017 +f 40762/40762/30015 40764/40764/30017 40765/40765/30018 +f 40763/40763/30016 40766/40766/30019 40767/40767/30020 +f 40763/40763/30016 40767/40767/30020 40764/40764/30017 +f 40764/40764/30017 40767/40767/30020 38932/38932/28539 +f 40764/40764/30017 38932/38932/28539 38931/38931/28538 +f 40765/40765/30018 40764/40764/30017 38931/38931/28538 +f 40765/40765/30018 38931/38931/28538 38930/38930/28537 +f 40746/40746/30002 40768/40768/30021 40769/40769/30022 +f 40746/40746/30002 40769/40769/30022 40747/40747/30003 +f 40768/40768/30021 39002/39002/28604 39001/39001/28603 +f 40768/40768/30021 39001/39001/28603 40769/40769/30022 +f 40769/40769/30022 39001/39001/28603 39000/39000/28602 +f 40769/40769/30022 39000/39000/28602 40770/40770/30023 +f 40747/40747/30003 40769/40769/30022 40770/40770/30023 +f 40747/40747/30003 40770/40770/30023 40748/40748/30004 +f 40771/40771/30024 40772/40772/30025 40773/40773/30026 +f 40771/40771/30024 40773/40773/30026 40774/40774/30027 +f 40772/40772/30025 40775/40775/30028 40776/40776/30029 +f 40772/40772/30025 40776/40776/30029 40773/40773/30026 +f 40773/40773/30026 40776/40776/30029 40777/40777/30030 +f 40773/40773/30026 40777/40777/30030 40778/40778/30031 +f 40774/40774/30027 40773/40773/30026 40778/40778/30031 +f 40774/40774/30027 40778/40778/30031 40779/40779/30032 +f 38992/38992/28596 39078/39078/28676 40780/40780/30033 +f 38992/38992/28596 40780/40780/30033 38993/38993/28597 +f 39078/39078/28676 38870/38870/28483 38869/38869/28482 +f 39078/39078/28676 38869/38869/28482 40780/40780/30033 +f 40780/40780/30033 38869/38869/28482 38868/38868/28481 +f 40780/40780/30033 38868/38868/28481 40781/40781/30034 +f 38993/38993/28597 40780/40780/30033 40781/40781/30034 +f 38993/38993/28597 40781/40781/30034 38994/38994/28598 +f 40782/40782/30035 40783/40783/30036 40784/40784/30037 +f 40782/40782/30035 40784/40784/30037 40785/40785/30038 +f 40783/40783/30036 40786/40786/30039 40787/40787/30040 +f 40783/40783/30036 40787/40787/30040 40784/40784/30037 +f 40784/40784/30037 40787/40787/30040 40788/40788/30041 +f 40784/40784/30037 40788/40788/30041 40789/40789/30042 +f 40785/40785/30038 40784/40784/30037 40789/40789/30042 +f 40785/40785/30038 40789/40789/30042 40790/40790/30043 +f 40791/40791/30044 40792/40792/30045 40793/40793/30046 +f 40791/40791/30044 40793/40793/30046 40794/40794/30047 +f 40792/40792/30045 40795/40795/30048 40796/40796/30049 +f 40792/40792/30045 40796/40796/30049 40793/40793/30046 +f 40793/40793/30046 40796/40796/30049 40797/40797/30050 +f 40793/40793/30046 40797/40797/30050 40798/40798/30051 +f 40794/40794/30047 40793/40793/30046 40798/40798/30051 +f 40794/40794/30047 40798/40798/30051 40799/40799/30052 +f 39570/39570/29094 40800/40800/30053 40801/40801/30054 +f 39570/39570/29094 40801/40801/30054 40136/40136/29561 +f 40800/40800/30053 40782/40782/30035 40785/40785/30038 +f 40800/40800/30053 40785/40785/30038 40801/40801/30054 +f 40801/40801/30054 40785/40785/30038 40790/40790/30043 +f 40801/40801/30054 40790/40790/30043 40802/40802/30055 +f 40136/40136/29561 40801/40801/30054 40802/40802/30055 +f 40136/40136/29561 40802/40802/30055 39055/39055/28654 +f 38843/38843/28458 40803/40803/30056 40804/40804/30057 +f 38843/38843/28458 40804/40804/30057 40175/40175/29591 +f 40803/40803/30056 40771/40771/30024 40774/40774/30027 +f 40803/40803/30056 40774/40774/30027 40804/40804/30057 +f 40804/40804/30057 40774/40774/30027 40779/40779/30032 +f 40804/40804/30057 40779/40779/30032 40805/40805/30058 +f 40175/40175/29591 40804/40804/30057 40805/40805/30058 +f 40175/40175/29591 40805/40805/30058 38942/38942/28549 +f 38896/38896/28504 40806/40806/30059 40807/40807/30060 +f 38896/38896/28504 40807/40807/30060 38937/38937/28544 +f 40806/40806/30059 40766/40766/30019 40763/40763/30016 +f 40806/40806/30059 40763/40763/30016 40807/40807/30060 +f 40807/40807/30060 40763/40763/30016 40762/40762/30015 +f 40807/40807/30060 40762/40762/30015 40808/40808/30061 +f 38937/38937/28544 40807/40807/30060 40808/40808/30061 +f 38937/38937/28544 40808/40808/30061 38934/38934/28541 +f 39063/39063/28662 40809/40809/30062 40810/40810/30063 +f 39063/39063/28662 40810/40810/30063 40135/40135/29560 +f 40809/40809/30062 40777/40777/30030 40776/40776/30029 +f 40809/40809/30062 40776/40776/30029 40810/40810/30063 +f 40810/40810/30063 40776/40776/30029 40775/40775/30028 +f 40810/40810/30063 40775/40775/30028 40811/40811/30064 +f 40135/40135/29560 40810/40810/30063 40811/40811/30064 +f 40135/40135/29560 40811/40811/30064 38851/38851/28466 +f 39524/39524/29063 40812/40812/30065 40813/40813/30066 +f 39524/39524/29063 40813/40813/30066 40079/40079/29511 +f 40814/40814/30065 40788/40788/30041 40787/40787/30040 +f 40814/40814/30065 40787/40787/30040 40815/40815/30066 +f 40815/40815/30066 40787/40787/30040 40786/40786/30039 +f 40815/40815/30066 40786/40786/30039 40816/40816/30067 +f 40079/40079/29511 40813/40813/30066 40817/40817/30067 +f 40079/40079/29511 40817/40817/30067 40076/40076/29099 +f 38934/38934/28541 40808/40808/30061 40818/40818/30068 +f 38934/38934/28541 40818/40818/30068 39620/39620/29135 +f 40808/40808/30061 40762/40762/30015 40765/40765/30018 +f 40808/40808/30061 40765/40765/30018 40818/40818/30068 +f 40818/40818/30068 40765/40765/30018 38930/38930/28537 +f 40818/40818/30068 38930/38930/28537 38927/38927/28534 +f 39620/39620/29135 40818/40818/30068 38927/38927/28534 +f 39620/39620/29135 38927/38927/28534 38926/38926/28533 +f 40021/40021/29462 40819/40819/30069 40820/40820/30070 +f 40021/40021/29462 40820/40820/30070 40759/40759/30012 +f 40819/40819/30069 40795/40795/30048 40792/40792/30045 +f 40819/40819/30069 40792/40792/30045 40820/40820/30070 +f 40820/40820/30070 40792/40792/30045 40791/40791/30044 +f 40820/40820/30070 40791/40791/30044 40821/40821/30071 +f 40759/40759/30012 40820/40820/30070 40821/40821/30071 +f 40759/40759/30012 40821/40821/30071 40080/40080/29512 +f 40080/40080/29512 40821/40821/30071 40822/40822/30072 +f 40080/40080/29512 40822/40822/30072 40081/40081/29513 +f 40821/40821/30071 40791/40791/30044 40794/40794/30047 +f 40821/40821/30071 40794/40794/30047 40822/40822/30072 +f 40822/40822/30072 40794/40794/30047 40799/40799/30052 +f 40822/40822/30072 40799/40799/30052 40823/40823/30073 +f 40081/40081/29513 40822/40822/30072 40823/40823/30073 +f 40081/40081/29513 40823/40823/30073 39516/39516/29055 +f 40824/40824/29495 40825/40825/30074 40826/40826/30075 +f 40824/40824/29495 40826/40826/30075 40827/40827/29493 +f 40828/40828/30074 40797/40797/30050 40796/40796/30049 +f 40828/40828/30074 40796/40796/30049 40829/40829/30075 +f 40829/40829/30075 40796/40796/30049 40795/40795/30048 +f 40829/40829/30075 40795/40795/30048 40819/40819/30069 +f 40827/40827/29493 40826/40826/30075 40830/40830/30076 +f 40827/40827/29493 40830/40830/30076 40831/40831/30077 +f 38942/38942/28549 40805/40805/30058 40832/40832/30078 +f 38942/38942/28549 40832/40832/30078 40177/40177/29593 +f 40805/40805/30058 40779/40779/30032 40778/40778/30031 +f 40805/40805/30058 40778/40778/30031 40832/40832/30078 +f 40832/40832/30078 40778/40778/30031 40777/40777/30030 +f 40832/40832/30078 40777/40777/30030 40809/40809/30062 +f 40177/40177/29593 40832/40832/30078 40809/40809/30062 +f 40177/40177/29593 40809/40809/30062 39063/39063/28662 +f 38902/38902/28510 40749/40749/30005 40833/40833/30079 +f 38902/38902/28510 40833/40833/30079 39535/39535/29073 +f 40749/40749/30005 40748/40748/30004 40770/40770/30023 +f 40749/40749/30005 40770/40770/30023 40833/40833/30079 +f 40833/40833/30079 40770/40770/30023 39000/39000/28602 +f 40833/40833/30079 39000/39000/28602 38998/38998/28600 +f 39535/39535/29073 40833/40833/30079 38998/38998/28600 +f 39535/39535/29073 38998/38998/28600 38925/38925/28532 +f 39516/39516/29055 40823/40823/30073 40834/40834/30080 +f 39516/39516/29055 40834/40834/30080 40111/40111/29536 +f 40823/40823/30073 40799/40799/30052 40798/40798/30051 +f 40823/40823/30073 40798/40798/30051 40834/40834/30080 +f 40834/40834/30080 40798/40798/30051 40797/40797/30050 +f 40834/40834/30080 40797/40797/30050 40828/40828/30074 +f 40111/40111/29536 40834/40834/30080 40828/40828/30074 +f 40111/40111/29536 40828/40828/30074 40058/40058/29495 +f 38851/38851/28466 40811/40811/30064 40835/40835/30081 +f 38851/38851/28466 40835/40835/30081 38846/38846/28461 +f 40811/40811/30064 40775/40775/30028 40772/40772/30025 +f 40811/40811/30064 40772/40772/30025 40835/40835/30081 +f 40835/40835/30081 40772/40772/30025 40771/40771/30024 +f 40835/40835/30081 40771/40771/30024 40803/40803/30056 +f 38846/38846/28461 40835/40835/30081 40803/40803/30056 +f 38846/38846/28461 40803/40803/30056 38843/38843/28458 +f 39575/39575/29099 40816/40816/30067 40836/40836/30082 +f 39575/39575/29099 40836/40836/30082 39573/39573/29097 +f 40816/40816/30067 40786/40786/30039 40783/40783/30036 +f 40816/40816/30067 40783/40783/30036 40836/40836/30082 +f 40836/40836/30082 40783/40783/30036 40782/40782/30035 +f 40836/40836/30082 40782/40782/30035 40800/40800/30053 +f 39573/39573/29097 40836/40836/30082 40800/40800/30053 +f 39573/39573/29097 40800/40800/30053 39570/39570/29094 +f 38982/38982/28588 39003/39003/28605 40837/40837/30083 +f 38982/38982/28588 40837/40837/30083 39550/39550/29084 +f 39003/39003/28605 39002/39002/28604 40768/40768/30021 +f 39003/39003/28605 40768/40768/30021 40837/40837/30083 +f 40837/40837/30083 40768/40768/30021 40746/40746/30002 +f 40837/40837/30083 40746/40746/30002 40744/40744/30000 +f 39550/39550/29084 40837/40837/30083 40744/40744/30000 +f 39550/39550/29084 40744/40744/30000 38900/38900/28508 +f 39055/39055/28654 40802/40802/30055 40838/40838/30084 +f 39055/39055/28654 40838/40838/30084 40150/40150/29573 +f 40802/40802/30055 40790/40790/30043 40789/40789/30042 +f 40802/40802/30055 40789/40789/30042 40838/40838/30084 +f 40838/40838/30084 40789/40789/30042 40788/40788/30041 +f 40838/40838/30084 40788/40788/30041 40814/40814/30065 +f 40150/40150/29573 40838/40838/30084 40814/40814/30065 +f 40150/40150/29573 40814/40814/30065 40147/40147/29570 +f 38904/38904/28512 38933/38933/28540 40839/40839/30085 +f 38904/38904/28512 40839/40839/30085 38899/38899/28507 +f 38933/38933/28540 38932/38932/28539 40767/40767/30020 +f 38933/38933/28540 40767/40767/30020 40839/40839/30085 +f 40839/40839/30085 40767/40767/30020 40766/40766/30019 +f 40839/40839/30085 40766/40766/30019 40806/40806/30059 +f 38899/38899/28507 40839/40839/30085 40806/40806/30059 +f 38899/38899/28507 40806/40806/30059 38896/38896/28504 +f 39569/39569/28524 38995/38995/28599 40840/40840/30086 +f 39569/39569/28524 40840/40840/30086 39565/39565/29092 +f 38995/38995/28599 38994/38994/28598 40781/40781/30034 +f 38995/38995/28599 40781/40781/30034 40840/40840/30086 +f 40840/40840/30086 40781/40781/30034 38868/38868/28481 +f 40840/40840/30086 38868/38868/28481 38865/38865/28478 +f 39565/39565/29092 40840/40840/30086 38865/38865/28478 +f 39565/39565/29092 38865/38865/28478 38864/38864/28477 +o Sphere.018__0 +v 0.568364 0.868483 -1.037403 +v 0.566631 0.877268 -1.037797 +v 0.568364 0.877439 -1.037813 +v 0.564965 0.876760 -1.037750 +v 0.563429 0.875936 -1.037674 +v 0.562082 0.874827 -1.037572 +v 0.560977 0.873476 -1.037447 +v 0.560156 0.871934 -1.037304 +v 0.559650 0.870261 -1.037150 +v 0.559479 0.868521 -1.036989 +v 0.559650 0.866781 -1.036829 +v 0.560156 0.865108 -1.036674 +v 0.560977 0.863566 -1.036532 +v 0.562082 0.862215 -1.036407 +v 0.563429 0.861106 -1.036305 +v 0.564965 0.860282 -1.036228 +v 0.566631 0.859774 -1.036182 +v 0.568364 0.859603 -1.036166 +v 0.570098 0.859774 -1.036182 +v 0.571765 0.860282 -1.036228 +v 0.573301 0.861106 -1.036305 +v 0.574647 0.862215 -1.036407 +v 0.575752 0.863566 -1.036532 +v 0.576573 0.865108 -1.036674 +v 0.577079 0.866781 -1.036829 +v 0.577249 0.868521 -1.036989 +v 0.577079 0.870261 -1.037150 +v 0.576573 0.871934 -1.037304 +v 0.575752 0.873476 -1.037447 +v 0.574647 0.874827 -1.037572 +v 0.573301 0.875936 -1.037674 +v 0.571765 0.876760 -1.037750 +v 0.570098 0.877268 -1.037797 +v 0.568364 0.911943 -1.028011 +v 0.560156 0.911131 -1.027936 +v 0.559650 0.914056 -1.024133 +v 0.568364 0.914917 -1.024212 +v 0.568364 0.907375 -1.031344 +v 0.560977 0.906645 -1.031276 +v 0.568364 0.901389 -1.034081 +v 0.562082 0.900768 -1.034024 +v 0.568364 0.894214 -1.036119 +v 0.563429 0.893726 -1.036074 +v 0.568364 0.886127 -1.037379 +v 0.564965 0.885791 -1.037348 +v 0.561695 0.884796 -1.037256 +v 0.552263 0.908728 -1.027714 +v 0.551271 0.911505 -1.023897 +v 0.553873 0.904482 -1.031076 +v 0.556041 0.898928 -1.033854 +v 0.558682 0.892281 -1.035941 +v 0.547327 0.900969 -1.030752 +v 0.544989 0.904825 -1.027354 +v 0.550473 0.895941 -1.033578 +v 0.554308 0.889934 -1.035724 +v 0.558682 0.883179 -1.037107 +v 0.543549 0.907361 -1.023515 +v 0.556041 0.881004 -1.036906 +v 0.538613 0.899573 -1.026869 +v 0.536780 0.901786 -1.023000 +v 0.541588 0.896242 -1.030316 +v 0.545593 0.891921 -1.033207 +v 0.550473 0.886776 -1.035433 +v 0.541588 0.887023 -1.032755 +v 0.536879 0.890483 -1.029784 +v 0.547327 0.882927 -1.035077 +v 0.553873 0.878353 -1.036661 +v 0.533380 0.893173 -1.026278 +v 0.531225 0.894992 -1.022372 +v 0.529492 0.885872 -1.025604 +v 0.527097 0.887240 -1.021657 +v 0.533380 0.883912 -1.029177 +v 0.538613 0.881435 -1.032239 +v 0.544989 0.878537 -1.034672 +v 0.552263 0.875329 -1.036382 +v 0.543549 0.873773 -1.034232 +v 0.536780 0.875371 -1.031679 +v 0.551271 0.872047 -1.036079 +v 0.527097 0.877949 -1.024872 +v 0.524555 0.878830 -1.020880 +v 0.531225 0.876782 -1.028519 +v 0.526289 0.869710 -1.024112 +v 0.523697 0.870083 -1.020073 +v 0.530498 0.869366 -1.027834 +v 0.536161 0.869065 -1.031097 +v 0.543063 0.868818 -1.033775 +v 0.550936 0.868634 -1.035764 +v 0.543549 0.863863 -1.033317 +v 0.536780 0.862759 -1.030514 +v 0.551271 0.865221 -1.035449 +v 0.527097 0.861471 -1.023351 +v 0.524555 0.861336 -1.019265 +v 0.531225 0.861951 -1.027149 +v 0.529492 0.853548 -1.022619 +v 0.527097 0.852926 -1.018488 +v 0.533380 0.854821 -1.026491 +v 0.538613 0.856695 -1.029955 +v 0.544989 0.859099 -1.032877 +v 0.552263 0.861940 -1.035146 +v 0.553873 0.858915 -1.034867 +v 0.547327 0.854708 -1.032472 +v 0.533380 0.846247 -1.021945 +v 0.531225 0.845175 -1.017773 +v 0.536879 0.848250 -1.025884 +v 0.541588 0.851107 -1.029439 +v 0.538613 0.839847 -1.021354 +v 0.536780 0.838381 -1.017145 +v 0.541588 0.842490 -1.025352 +v 0.545593 0.846209 -1.028986 +v 0.550473 0.850860 -1.032116 +v 0.556041 0.856264 -1.034622 +v 0.558682 0.854089 -1.034421 +v 0.554308 0.847702 -1.031825 +v 0.544989 0.834595 -1.020869 +v 0.543549 0.832805 -1.016630 +v 0.547327 0.837764 -1.024916 +v 0.550473 0.842189 -1.028615 +v 0.553873 0.834251 -1.024592 +v 0.552263 0.830692 -1.020509 +v 0.556041 0.839202 -1.028339 +v 0.558682 0.845355 -1.031608 +v 0.561695 0.852472 -1.034272 +v 0.551271 0.828662 -1.016248 +v 0.564965 0.851477 -1.034180 +v 0.560156 0.828289 -1.020287 +v 0.559650 0.826111 -1.016012 +v 0.560977 0.832088 -1.024392 +v 0.562082 0.837363 -1.028169 +v 0.563429 0.843910 -1.031475 +v 0.568364 0.836742 -1.028112 +v 0.568364 0.831358 -1.024324 +v 0.568364 0.843421 -1.031430 +v 0.568364 0.851141 -1.034149 +v 0.568364 0.827477 -1.020212 +v 0.568364 0.825249 -1.015933 +v 0.568364 0.827477 -1.020212 +v 0.576573 0.828289 -1.020287 +v 0.577079 0.826111 -1.016012 +v 0.568364 0.825249 -1.015933 +v 0.575752 0.832088 -1.024392 +v 0.576573 0.828289 -1.020287 +v 0.574647 0.837363 -1.028169 +v 0.573301 0.843910 -1.031475 +v 0.571765 0.851477 -1.034180 +v 0.580688 0.839202 -1.028339 +v 0.582855 0.834251 -1.024592 +v 0.578047 0.845355 -1.031608 +v 0.575034 0.852472 -1.034272 +v 0.584466 0.830692 -1.020509 +v 0.585458 0.828662 -1.016248 +v 0.575752 0.832088 -1.024392 +v 0.582855 0.834251 -1.024592 +v 0.591740 0.834595 -1.020869 +v 0.593180 0.832805 -1.016630 +v 0.589402 0.837764 -1.024916 +v 0.580688 0.839202 -1.028339 +v 0.586256 0.842189 -1.028615 +v 0.582422 0.847702 -1.031825 +v 0.586256 0.842189 -1.028615 +v 0.578047 0.854089 -1.034421 +v 0.582422 0.847702 -1.031825 +v 0.586256 0.850860 -1.032116 +v 0.591136 0.846209 -1.028986 +v 0.580688 0.856264 -1.034622 +v 0.586256 0.850860 -1.032116 +v 0.598117 0.839847 -1.021354 +v 0.599949 0.838381 -1.017145 +v 0.595140 0.842490 -1.025352 +v 0.603349 0.846247 -1.021945 +v 0.605504 0.845175 -1.017773 +v 0.599850 0.848250 -1.025884 +v 0.595140 0.851107 -1.029439 +v 0.589402 0.854708 -1.032472 +v 0.582855 0.858915 -1.034867 +v 0.589402 0.854708 -1.032472 +v 0.591740 0.859099 -1.032877 +v 0.598117 0.856695 -1.029955 +v 0.584466 0.861940 -1.035146 +v 0.591740 0.859099 -1.032877 +v 0.607238 0.853548 -1.022619 +v 0.609632 0.852926 -1.018488 +v 0.603349 0.854821 -1.026491 +v 0.609632 0.861471 -1.023351 +v 0.612173 0.861336 -1.019265 +v 0.605504 0.861951 -1.027149 +v 0.599949 0.862759 -1.030514 +v 0.593180 0.863863 -1.033317 +v 0.585458 0.865222 -1.035449 +v 0.593180 0.863863 -1.033317 +v 0.585793 0.868634 -1.035764 +v 0.593667 0.868818 -1.033775 +v 0.610440 0.869710 -1.024112 +v 0.613032 0.870083 -1.020073 +v 0.606232 0.869366 -1.027834 +v 0.600568 0.869065 -1.031097 +v 0.593667 0.868818 -1.033775 +v 0.605504 0.876782 -1.028519 +v 0.609632 0.877949 -1.024872 +v 0.599949 0.875371 -1.031679 +v 0.593180 0.873773 -1.034232 +v 0.585458 0.872047 -1.036079 +v 0.593180 0.873773 -1.034232 +v 0.612173 0.878830 -1.020880 +v 0.584466 0.875329 -1.036382 +v 0.607238 0.885872 -1.025604 +v 0.609632 0.887240 -1.021657 +v 0.603349 0.883912 -1.029177 +v 0.598116 0.881435 -1.032239 +v 0.591740 0.878537 -1.034672 +v 0.591740 0.878537 -1.034672 +v 0.599850 0.890483 -1.029784 +v 0.603349 0.893173 -1.026278 +v 0.595140 0.887023 -1.032755 +v 0.589402 0.882927 -1.035077 +v 0.582855 0.878353 -1.036661 +v 0.589402 0.882927 -1.035077 +v 0.605504 0.894992 -1.022372 +v 0.580688 0.881004 -1.036906 +v 0.598117 0.899573 -1.026869 +v 0.599949 0.901786 -1.023000 +v 0.595140 0.896242 -1.030316 +v 0.591136 0.891921 -1.033207 +v 0.586256 0.886776 -1.035433 +v 0.586256 0.886776 -1.035433 +v 0.586256 0.895941 -1.033578 +v 0.589402 0.900969 -1.030752 +v 0.582422 0.889934 -1.035724 +v 0.586256 0.895941 -1.033578 +v 0.591136 0.891921 -1.033207 +v 0.578047 0.883179 -1.037107 +v 0.591740 0.904825 -1.027354 +v 0.593180 0.907361 -1.023515 +v 0.584466 0.908728 -1.027714 +v 0.585458 0.911505 -1.023897 +v 0.582855 0.904482 -1.031076 +v 0.580688 0.898928 -1.033854 +v 0.582855 0.904482 -1.031076 +v 0.589402 0.900969 -1.030752 +v 0.578047 0.892281 -1.035941 +v 0.575034 0.884796 -1.037256 +v 0.574647 0.900768 -1.034024 +v 0.575752 0.906645 -1.031276 +v 0.573301 0.893726 -1.036074 +v 0.571765 0.885791 -1.037348 +v 0.576573 0.911131 -1.027936 +v 0.577079 0.914056 -1.024133 +v 0.576573 0.911131 -1.027936 +v 0.584466 0.908728 -1.027714 +v 0.577079 0.914056 -1.024133 +vt 0.650140 0.776980 +vt 0.650202 0.776320 +vt 0.650076 0.776320 +vt 0.650326 0.776345 +vt 0.650443 0.776395 +vt 0.650549 0.776467 +vt 0.650639 0.776559 +vt 0.650710 0.776667 +vt 0.650759 0.776786 +vt 0.650785 0.776914 +vt 0.650786 0.777043 +vt 0.650763 0.777170 +vt 0.650716 0.777290 +vt 0.650647 0.777398 +vt 0.650559 0.777490 +vt 0.650455 0.777562 +vt 0.650339 0.777611 +vt 0.650216 0.777637 +vt 0.650090 0.777637 +vt 0.649966 0.777611 +vt 0.649849 0.777562 +vt 0.649744 0.777490 +vt 0.649654 0.777398 +vt 0.649583 0.777290 +vt 0.649533 0.777170 +vt 0.649507 0.777043 +vt 0.649506 0.776914 +vt 0.649529 0.776786 +vt 0.649576 0.776667 +vt 0.649645 0.776559 +vt 0.649733 0.776467 +vt 0.649837 0.776395 +vt 0.649953 0.776345 +vt 0.650015 0.773820 +vt 0.650612 0.773820 +vt 0.650691 0.773615 +vt 0.650058 0.773615 +vt 0.649991 0.774143 +vt 0.650528 0.774143 +vt 0.649984 0.774573 +vt 0.650441 0.774573 +vt 0.649997 0.775093 +vt 0.650356 0.775093 +vt 0.650028 0.775683 +vt 0.650275 0.775683 +vt 0.650518 0.775733 +vt 0.651198 0.773939 +vt 0.651314 0.773742 +vt 0.651055 0.774251 +vt 0.650890 0.774665 +vt 0.650709 0.775165 +vt 0.651554 0.774463 +vt 0.651752 0.774174 +vt 0.651314 0.774845 +vt 0.651042 0.775307 +vt 0.650748 0.775830 +vt 0.651901 0.773991 +vt 0.650954 0.775971 +vt 0.652252 0.774516 +vt 0.652432 0.774354 +vt 0.652003 0.774770 +vt 0.651696 0.775106 +vt 0.651342 0.775512 +vt 0.652022 0.775438 +vt 0.652387 0.775161 +vt 0.651598 0.775773 +vt 0.651131 0.776151 +vt 0.652678 0.774950 +vt 0.652884 0.774815 +vt 0.653015 0.775461 +vt 0.653242 0.775357 +vt 0.652690 0.775620 +vt 0.652280 0.775829 +vt 0.651801 0.776080 +vt 0.651271 0.776363 +vt 0.651942 0.776421 +vt 0.652460 0.776264 +vt 0.651368 0.776598 +vt 0.653249 0.776028 +vt 0.653491 0.775959 +vt 0.652901 0.776131 +vt 0.653372 0.776631 +vt 0.653621 0.776599 +vt 0.653011 0.776673 +vt 0.652553 0.776725 +vt 0.652016 0.776784 +vt 0.651419 0.776847 +vt 0.652019 0.777153 +vt 0.652558 0.777195 +vt 0.651421 0.777102 +vt 0.653378 0.777245 +vt 0.653628 0.777251 +vt 0.653017 0.777226 +vt 0.653268 0.777847 +vt 0.653511 0.777890 +vt 0.652918 0.777768 +vt 0.652474 0.777656 +vt 0.651953 0.777515 +vt 0.651376 0.777351 +vt 0.651283 0.777586 +vt 0.651820 0.777856 +vt 0.653046 0.778415 +vt 0.653275 0.778493 +vt 0.652718 0.778279 +vt 0.652304 0.778090 +vt 0.652720 0.778925 +vt 0.652929 0.779035 +vt 0.652424 0.778738 +vt 0.652054 0.778481 +vt 0.651623 0.778163 +vt 0.651148 0.777798 +vt 0.650975 0.777978 +vt 0.651372 0.778425 +vt 0.652302 0.779360 +vt 0.652486 0.779496 +vt 0.652049 0.779129 +vt 0.651735 0.778813 +vt 0.651606 0.779436 +vt 0.651810 0.779701 +vt 0.651358 0.779075 +vt 0.651076 0.778630 +vt 0.650771 0.778119 +vt 0.651963 0.779858 +vt 0.650544 0.778216 +vt 0.651261 0.779936 +vt 0.651380 0.780108 +vt 0.651112 0.779648 +vt 0.650938 0.779254 +vt 0.650746 0.778771 +vt 0.650491 0.779346 +vt 0.650586 0.779756 +vt 0.650395 0.778843 +vt 0.650302 0.778266 +vt 0.650677 0.780056 +vt 0.650760 0.780235 +vt 0.934180 0.907561 +vt 0.933739 0.907442 +vt 0.933495 0.907627 +vt 0.933963 0.907753 +vt 0.650049 0.779756 +vt 0.650081 0.780056 +vt 0.650034 0.779346 +vt 0.650036 0.778843 +vt 0.650055 0.778266 +vt 0.649586 0.779254 +vt 0.649522 0.779648 +vt 0.649684 0.778771 +vt 0.649812 0.778216 +vt 0.933323 0.907208 +vt 0.933054 0.907378 +vt 0.933992 0.907142 +vt 0.933618 0.906931 +vt 0.932949 0.906867 +vt 0.932657 0.907016 +vt 0.933281 0.906624 +vt 0.933927 0.906558 +vt 0.933641 0.906297 +vt 0.649351 0.778630 +vt 0.649162 0.779075 +vt 0.649583 0.778119 +vt 0.934014 0.905899 +vt 0.933823 0.905638 +vt 0.933398 0.905965 +vt 0.649376 0.777978 +vt 0.649050 0.778425 +vt 0.932631 0.906433 +vt 0.932319 0.906555 +vt 0.932995 0.906233 +vt 0.932381 0.905922 +vt 0.932054 0.906013 +vt 0.932770 0.905774 +vt 0.933206 0.905574 +vt 0.933673 0.905331 +vt 0.649199 0.777798 +vt 0.648794 0.778163 +vt 0.933569 0.904990 +vt 0.933075 0.905140 +vt 0.649060 0.777586 +vt 0.648591 0.777856 +vt 0.932209 0.905354 +vt 0.931871 0.905411 +vt 0.932615 0.905263 +vt 0.932121 0.904752 +vt 0.931778 0.904771 +vt 0.932536 0.904720 +vt 0.933007 0.904678 +vt 0.933516 0.904627 +vt 0.648963 0.777351 +vt 0.648451 0.777515 +vt 0.648912 0.777102 +vt 0.648377 0.777153 +vt 0.932121 0.904137 +vt 0.931778 0.904118 +vt 0.932536 0.904167 +vt 0.933007 0.904208 +vt 0.933516 0.904258 +vt 0.932615 0.903624 +vt 0.932209 0.903534 +vt 0.933075 0.903746 +vt 0.933569 0.903895 +vt 0.648909 0.776847 +vt 0.648373 0.776784 +vt 0.931871 0.903478 +vt 0.648955 0.776598 +vt 0.932381 0.902965 +vt 0.932054 0.902875 +vt 0.932770 0.903113 +vt 0.933206 0.903311 +vt 0.933673 0.903553 +vt 0.648439 0.776421 +vt 0.932995 0.902652 +vt 0.932631 0.902454 +vt 0.933398 0.902920 +vt 0.933823 0.903245 +vt 0.649047 0.776363 +vt 0.648573 0.776080 +vt 0.932319 0.902331 +vt 0.649182 0.776151 +vt 0.932949 0.902018 +vt 0.932657 0.901869 +vt 0.933281 0.902261 +vt 0.933641 0.902586 +vt 0.934014 0.902984 +vt 0.648769 0.775773 +vt 0.933927 0.902324 +vt 0.933618 0.901953 +vt 0.649020 0.775512 +vt 0.648741 0.775106 +vt 0.648421 0.775438 +vt 0.649355 0.775971 +vt 0.933323 0.901676 +vt 0.933054 0.901506 +vt 0.933739 0.901440 +vt 0.933495 0.901255 +vt 0.933992 0.901740 +vt 0.649118 0.774845 +vt 0.648971 0.774463 +vt 0.648528 0.774770 +vt 0.649316 0.775307 +vt 0.649559 0.775830 +vt 0.649538 0.774665 +vt 0.649465 0.774251 +vt 0.649646 0.775165 +vt 0.649786 0.775733 +vt 0.934180 0.901319 +vt 0.933963 0.901127 +vt 0.649431 0.773939 +vt 0.648883 0.774174 +vt 0.649438 0.773742 +vn -0.0000 -0.0919 -0.9958 +vn -0.0191 0.0032 -0.9998 +vn 0.0000 0.0051 -1.0000 +vn -0.0374 -0.0023 -0.9993 +vn -0.0543 -0.0112 -0.9985 +vn -0.0691 -0.0233 -0.9973 +vn -0.0813 -0.0379 -0.9960 +vn -0.0903 -0.0546 -0.9944 +vn -0.0958 -0.0726 -0.9927 +vn -0.0977 -0.0915 -0.9910 +vn -0.0958 -0.1103 -0.9893 +vn -0.0903 -0.1284 -0.9876 +vn -0.0812 -0.1451 -0.9861 +vn -0.0691 -0.1598 -0.9847 +vn -0.0543 -0.1718 -0.9836 +vn -0.0374 -0.1807 -0.9828 +vn -0.0192 -0.1862 -0.9823 +vn -0.0000 -0.1881 -0.9822 +vn 0.0191 -0.1862 -0.9823 +vn 0.0374 -0.1807 -0.9828 +vn 0.0543 -0.1718 -0.9836 +vn 0.0691 -0.1598 -0.9847 +vn 0.0812 -0.1451 -0.9861 +vn 0.0903 -0.1284 -0.9876 +vn 0.0958 -0.1104 -0.9893 +vn 0.0977 -0.0915 -0.9910 +vn 0.0958 -0.0726 -0.9927 +vn 0.0903 -0.0546 -0.9944 +vn 0.0813 -0.0379 -0.9960 +vn 0.0691 -0.0233 -0.9973 +vn 0.0543 -0.0112 -0.9985 +vn 0.0375 -0.0023 -0.9993 +vn 0.0191 0.0032 -0.9998 +vn -0.0000 0.6990 -0.7151 +vn -0.1498 0.6843 -0.7137 +vn -0.1652 0.7711 -0.6149 +vn 0.0000 0.7874 -0.6165 +vn -0.0000 0.5096 -0.8604 +vn -0.1153 0.4983 -0.8593 +vn 0.0000 0.3496 -0.9369 +vn -0.0854 0.3413 -0.9361 +vn -0.0000 0.2176 -0.9760 +vn -0.0603 0.2117 -0.9755 +vn -0.0000 0.1052 -0.9944 +vn -0.0386 0.1015 -0.9941 +vn -0.0757 0.0904 -0.9930 +vn -0.2936 0.6408 -0.7093 +vn -0.3238 0.7231 -0.6101 +vn -0.2262 0.4649 -0.8560 +vn -0.1675 0.3166 -0.9336 +vn -0.1182 0.1943 -0.9738 +vn -0.3282 0.4108 -0.8506 +vn -0.4259 0.5703 -0.7024 +vn -0.2431 0.2766 -0.9297 +vn -0.1715 0.1661 -0.9711 +vn -0.1099 0.0723 -0.9913 +vn -0.4698 0.6453 -0.6024 +vn -0.1399 0.0479 -0.9890 +vn -0.5416 0.4757 -0.6931 +vn -0.5974 0.5408 -0.5922 +vn -0.4174 0.3380 -0.8435 +vn -0.3093 0.2228 -0.9245 +vn -0.2183 0.1281 -0.9674 +vn -0.3635 0.1572 -0.9182 +vn -0.4906 0.2495 -0.8349 +vn -0.2566 0.0819 -0.9630 +vn -0.1644 0.0183 -0.9862 +vn -0.6363 0.3607 -0.6819 +vn -0.7018 0.4139 -0.5798 +vn -0.7065 0.2298 -0.6694 +vn -0.7791 0.2695 -0.5660 +vn -0.5448 0.1486 -0.8253 +vn -0.4038 0.0825 -0.9111 +vn -0.2851 0.0292 -0.9581 +vn -0.1827 -0.0154 -0.9831 +vn -0.3026 -0.0280 -0.9527 +vn -0.4286 0.0015 -0.9035 +vn -0.1939 -0.0521 -0.9796 +vn -0.7496 0.0880 -0.6560 +vn -0.8266 0.1130 -0.5513 +vn -0.5782 0.0393 -0.8149 +vn -0.7642 -0.0593 -0.6423 +vn -0.8427 -0.0495 -0.5361 +vn -0.5895 -0.0743 -0.8044 +vn -0.4370 -0.0827 -0.8956 +vn -0.3085 -0.0874 -0.9472 +vn -0.1977 -0.0901 -0.9761 +vn -0.3026 -0.1469 -0.9417 +vn -0.4286 -0.1669 -0.8879 +vn -0.1939 -0.1282 -0.9726 +vn -0.7496 -0.2066 -0.6288 +vn -0.8267 -0.2120 -0.5212 +vn -0.5782 -0.1879 -0.7940 +vn -0.7065 -0.3485 -0.6160 +vn -0.7791 -0.3686 -0.5071 +vn -0.5448 -0.2972 -0.7841 +vn -0.4039 -0.2479 -0.8806 +vn -0.2851 -0.2041 -0.9365 +vn -0.1826 -0.1649 -0.9693 +vn -0.1644 -0.1986 -0.9662 +vn -0.2566 -0.2569 -0.9318 +vn -0.6363 -0.4794 -0.6043 +vn -0.7018 -0.5131 -0.4942 +vn -0.4906 -0.3982 -0.7751 +vn -0.3636 -0.3227 -0.8739 +vn -0.5416 -0.5946 -0.5943 +vn -0.5973 -0.6401 -0.4831 +vn -0.4174 -0.4868 -0.7673 +vn -0.3093 -0.3883 -0.8681 +vn -0.2183 -0.3031 -0.9276 +vn -0.1398 -0.2282 -0.9635 +vn -0.1099 -0.2526 -0.9613 +vn -0.1715 -0.3411 -0.9242 +vn -0.4259 -0.6893 -0.5861 +vn -0.4698 -0.7447 -0.4741 +vn -0.3282 -0.5596 -0.7610 +vn -0.2431 -0.4421 -0.8634 +vn -0.2262 -0.6138 -0.7564 +vn -0.2936 -0.7599 -0.5800 +vn -0.1675 -0.4822 -0.8599 +vn -0.1182 -0.3693 -0.9217 +vn -0.0757 -0.2706 -0.9597 +vn -0.3238 -0.8226 -0.4674 +vn -0.0386 -0.2818 -0.9587 +vn -0.1498 -0.8034 -0.5763 +vn -0.1652 -0.8707 -0.4632 +vn -0.1153 -0.6472 -0.7535 +vn -0.0854 -0.5069 -0.8577 +vn -0.0603 -0.3867 -0.9202 +vn -0.0000 -0.5153 -0.8570 +vn -0.0000 -0.6585 -0.7525 +vn -0.0000 -0.3926 -0.9197 +vn -0.0000 -0.2855 -0.9584 +vn 0.0000 -0.8181 -0.5750 +vn -0.0000 -0.8869 -0.4619 +vn 0.0000 -0.8181 -0.5751 +vn 0.1498 -0.8034 -0.5763 +vn 0.1652 -0.8707 -0.4632 +vn 0.1154 -0.6472 -0.7535 +vn 0.0854 -0.5069 -0.8577 +vn 0.0603 -0.3867 -0.9202 +vn 0.0386 -0.2818 -0.9587 +vn 0.1675 -0.4822 -0.8599 +vn 0.2261 -0.6138 -0.7564 +vn 0.1182 -0.3693 -0.9217 +vn 0.0757 -0.2706 -0.9597 +vn 0.2936 -0.7599 -0.5800 +vn 0.3239 -0.8226 -0.4674 +vn 0.1153 -0.6472 -0.7535 +vn 0.2262 -0.6138 -0.7564 +vn 0.4259 -0.6893 -0.5861 +vn 0.4698 -0.7447 -0.4741 +vn 0.3282 -0.5596 -0.7610 +vn 0.2431 -0.4421 -0.8634 +vn 0.1716 -0.3411 -0.9242 +vn 0.1099 -0.2526 -0.9613 +vn 0.1716 -0.3411 -0.9243 +vn 0.2183 -0.3031 -0.9276 +vn 0.3093 -0.3883 -0.8681 +vn 0.1398 -0.2282 -0.9635 +vn 0.5416 -0.5945 -0.5943 +vn 0.5973 -0.6401 -0.4831 +vn 0.4174 -0.4867 -0.7674 +vn 0.6363 -0.4794 -0.6044 +vn 0.7017 -0.5131 -0.4943 +vn 0.4906 -0.3982 -0.7751 +vn 0.3636 -0.3227 -0.8739 +vn 0.2566 -0.2569 -0.9318 +vn 0.1644 -0.1986 -0.9662 +vn 0.2851 -0.2041 -0.9365 +vn 0.4039 -0.2480 -0.8806 +vn 0.1826 -0.1649 -0.9693 +vn 0.7065 -0.3485 -0.6160 +vn 0.7791 -0.3686 -0.5071 +vn 0.5448 -0.2973 -0.7841 +vn 0.7496 -0.2066 -0.6288 +vn 0.8267 -0.2121 -0.5212 +vn 0.5782 -0.1879 -0.7939 +vn 0.4286 -0.1669 -0.8879 +vn 0.3027 -0.1469 -0.9417 +vn 0.1939 -0.1282 -0.9726 +vn 0.3026 -0.1469 -0.9417 +vn 0.1977 -0.0901 -0.9761 +vn 0.3085 -0.0874 -0.9472 +vn 0.7642 -0.0593 -0.6423 +vn 0.8427 -0.0495 -0.5361 +vn 0.5895 -0.0743 -0.8044 +vn 0.4370 -0.0827 -0.8956 +vn 0.3085 -0.0875 -0.9472 +vn 0.5782 0.0393 -0.8149 +vn 0.7496 0.0880 -0.6560 +vn 0.4287 0.0015 -0.9035 +vn 0.3026 -0.0280 -0.9527 +vn 0.1939 -0.0520 -0.9796 +vn 0.8266 0.1130 -0.5513 +vn 0.1826 -0.0154 -0.9831 +vn 0.7065 0.2298 -0.6694 +vn 0.7792 0.2695 -0.5660 +vn 0.5448 0.1486 -0.8253 +vn 0.4038 0.0825 -0.9111 +vn 0.2851 0.0292 -0.9581 +vn 0.4906 0.2495 -0.8349 +vn 0.6363 0.3607 -0.6819 +vn 0.3636 0.1572 -0.9182 +vn 0.2566 0.0819 -0.9630 +vn 0.1644 0.0184 -0.9862 +vn 0.7018 0.4139 -0.5798 +vn 0.1399 0.0479 -0.9890 +vn 0.5416 0.4757 -0.6931 +vn 0.5974 0.5408 -0.5922 +vn 0.4174 0.3380 -0.8435 +vn 0.3093 0.2228 -0.9245 +vn 0.2183 0.1281 -0.9674 +vn 0.2430 0.2766 -0.9298 +vn 0.3282 0.4108 -0.8506 +vn 0.1716 0.1661 -0.9711 +vn 0.2431 0.2766 -0.9297 +vn 0.1099 0.0723 -0.9913 +vn 0.4259 0.5703 -0.7024 +vn 0.4698 0.6453 -0.6024 +vn 0.2936 0.6408 -0.7093 +vn 0.3239 0.7231 -0.6101 +vn 0.2261 0.4649 -0.8560 +vn 0.1675 0.3166 -0.9336 +vn 0.1182 0.1943 -0.9738 +vn 0.0757 0.0903 -0.9930 +vn 0.0854 0.3413 -0.9361 +vn 0.1153 0.4983 -0.8593 +vn 0.0603 0.2117 -0.9755 +vn 0.0386 0.1015 -0.9941 +vn 0.1497 0.6843 -0.7137 +vn 0.1652 0.7711 -0.6149 +vn 0.1498 0.6843 -0.7137 +usemtl Scene_-_Root +s 1 +f 40841/40841/30087 40842/40842/30088 40843/40843/30089 +f 40841/40841/30087 40844/40844/30090 40842/40842/30088 +f 40841/40841/30087 40845/40845/30091 40844/40844/30090 +f 40841/40841/30087 40846/40846/30092 40845/40845/30091 +f 40841/40841/30087 40847/40847/30093 40846/40846/30092 +f 40841/40841/30087 40848/40848/30094 40847/40847/30093 +f 40841/40841/30087 40849/40849/30095 40848/40848/30094 +f 40841/40841/30087 40850/40850/30096 40849/40849/30095 +f 40841/40841/30087 40851/40851/30097 40850/40850/30096 +f 40841/40841/30087 40852/40852/30098 40851/40851/30097 +f 40841/40841/30087 40853/40853/30099 40852/40852/30098 +f 40841/40841/30087 40854/40854/30100 40853/40853/30099 +f 40841/40841/30087 40855/40855/30101 40854/40854/30100 +f 40841/40841/30087 40856/40856/30102 40855/40855/30101 +f 40841/40841/30087 40857/40857/30103 40856/40856/30102 +f 40841/40841/30087 40858/40858/30104 40857/40857/30103 +f 40841/40841/30087 40859/40859/30105 40858/40858/30104 +f 40841/40841/30087 40860/40860/30106 40859/40859/30105 +f 40841/40841/30087 40861/40861/30107 40860/40860/30106 +f 40841/40841/30087 40862/40862/30108 40861/40861/30107 +f 40841/40841/30087 40863/40863/30109 40862/40862/30108 +f 40841/40841/30087 40864/40864/30110 40863/40863/30109 +f 40841/40841/30087 40865/40865/30111 40864/40864/30110 +f 40841/40841/30087 40866/40866/30112 40865/40865/30111 +f 40841/40841/30087 40867/40867/30113 40866/40866/30112 +f 40841/40841/30087 40868/40868/30114 40867/40867/30113 +f 40841/40841/30087 40869/40869/30115 40868/40868/30114 +f 40841/40841/30087 40870/40870/30116 40869/40869/30115 +f 40841/40841/30087 40871/40871/30117 40870/40870/30116 +f 40841/40841/30087 40872/40872/30118 40871/40871/30117 +f 40841/40841/30087 40873/40873/30119 40872/40872/30118 +f 40841/40841/30087 40843/40843/30089 40873/40873/30119 +f 40874/40874/30120 40875/40875/30121 40876/40876/30122 +f 40874/40874/30120 40876/40876/30122 40877/40877/30123 +f 40878/40878/30124 40879/40879/30125 40875/40875/30121 +f 40878/40878/30124 40875/40875/30121 40874/40874/30120 +f 40880/40880/30126 40881/40881/30127 40879/40879/30125 +f 40880/40880/30126 40879/40879/30125 40878/40878/30124 +f 40882/40882/30128 40883/40883/30129 40881/40881/30127 +f 40882/40882/30128 40881/40881/30127 40880/40880/30126 +f 40884/40884/30130 40885/40885/30131 40883/40883/30129 +f 40884/40884/30130 40883/40883/30129 40882/40882/30128 +f 40843/40843/30089 40842/40842/30088 40885/40885/30131 +f 40843/40843/30089 40885/40885/30131 40884/40884/30130 +f 40842/40842/30088 40844/40844/30090 40886/40886/30132 +f 40842/40842/30088 40886/40886/30132 40885/40885/30131 +f 40875/40875/30121 40887/40887/30133 40888/40888/30134 +f 40875/40875/30121 40888/40888/30134 40876/40876/30122 +f 40879/40879/30125 40889/40889/30135 40887/40887/30133 +f 40879/40879/30125 40887/40887/30133 40875/40875/30121 +f 40881/40881/30127 40890/40890/30136 40889/40889/30135 +f 40881/40881/30127 40889/40889/30135 40879/40879/30125 +f 40883/40883/30129 40891/40891/30137 40890/40890/30136 +f 40883/40883/30129 40890/40890/30136 40881/40881/30127 +f 40885/40885/30131 40886/40886/30132 40891/40891/30137 +f 40885/40885/30131 40891/40891/30137 40883/40883/30129 +f 40889/40889/30135 40892/40892/30138 40893/40893/30139 +f 40889/40889/30135 40893/40893/30139 40887/40887/30133 +f 40890/40890/30136 40894/40894/30140 40892/40892/30138 +f 40890/40890/30136 40892/40892/30138 40889/40889/30135 +f 40891/40891/30137 40895/40895/30141 40894/40894/30140 +f 40891/40891/30137 40894/40894/30140 40890/40890/30136 +f 40886/40886/30132 40896/40896/30142 40895/40895/30141 +f 40886/40886/30132 40895/40895/30141 40891/40891/30137 +f 40844/40844/30090 40845/40845/30091 40896/40896/30142 +f 40844/40844/30090 40896/40896/30142 40886/40886/30132 +f 40887/40887/30133 40893/40893/30139 40897/40897/30143 +f 40887/40887/30133 40897/40897/30143 40888/40888/30134 +f 40845/40845/30091 40846/40846/30092 40898/40898/30144 +f 40845/40845/30091 40898/40898/30144 40896/40896/30142 +f 40893/40893/30139 40899/40899/30145 40900/40900/30146 +f 40893/40893/30139 40900/40900/30146 40897/40897/30143 +f 40892/40892/30138 40901/40901/30147 40899/40899/30145 +f 40892/40892/30138 40899/40899/30145 40893/40893/30139 +f 40894/40894/30140 40902/40902/30148 40901/40901/30147 +f 40894/40894/30140 40901/40901/30147 40892/40892/30138 +f 40895/40895/30141 40903/40903/30149 40902/40902/30148 +f 40895/40895/30141 40902/40902/30148 40894/40894/30140 +f 40896/40896/30142 40898/40898/30144 40903/40903/30149 +f 40896/40896/30142 40903/40903/30149 40895/40895/30141 +f 40902/40902/30148 40904/40904/30150 40905/40905/30151 +f 40902/40902/30148 40905/40905/30151 40901/40901/30147 +f 40903/40903/30149 40906/40906/30152 40904/40904/30150 +f 40903/40903/30149 40904/40904/30150 40902/40902/30148 +f 40898/40898/30144 40907/40907/30153 40906/40906/30152 +f 40898/40898/30144 40906/40906/30152 40903/40903/30149 +f 40846/40846/30092 40847/40847/30093 40907/40907/30153 +f 40846/40846/30092 40907/40907/30153 40898/40898/30144 +f 40899/40899/30145 40908/40908/30154 40909/40909/30155 +f 40899/40899/30145 40909/40909/30155 40900/40900/30146 +f 40901/40901/30147 40905/40905/30151 40908/40908/30154 +f 40901/40901/30147 40908/40908/30154 40899/40899/30145 +f 40908/40908/30154 40910/40910/30156 40911/40911/30157 +f 40908/40908/30154 40911/40911/30157 40909/40909/30155 +f 40905/40905/30151 40912/40912/30158 40910/40910/30156 +f 40905/40905/30151 40910/40910/30156 40908/40908/30154 +f 40904/40904/30150 40913/40913/30159 40912/40912/30158 +f 40904/40904/30150 40912/40912/30158 40905/40905/30151 +f 40906/40906/30152 40914/40914/30160 40913/40913/30159 +f 40906/40906/30152 40913/40913/30159 40904/40904/30150 +f 40907/40907/30153 40915/40915/30161 40914/40914/30160 +f 40907/40907/30153 40914/40914/30160 40906/40906/30152 +f 40847/40847/30093 40848/40848/30094 40915/40915/30161 +f 40847/40847/30093 40915/40915/30161 40907/40907/30153 +f 40914/40914/30160 40916/40916/30162 40917/40917/30163 +f 40914/40914/30160 40917/40917/30163 40913/40913/30159 +f 40915/40915/30161 40918/40918/30164 40916/40916/30162 +f 40915/40915/30161 40916/40916/30162 40914/40914/30160 +f 40848/40848/30094 40849/40849/30095 40918/40918/30164 +f 40848/40848/30094 40918/40918/30164 40915/40915/30161 +f 40910/40910/30156 40919/40919/30165 40920/40920/30166 +f 40910/40910/30156 40920/40920/30166 40911/40911/30157 +f 40912/40912/30158 40921/40921/30167 40919/40919/30165 +f 40912/40912/30158 40919/40919/30165 40910/40910/30156 +f 40913/40913/30159 40917/40917/30163 40921/40921/30167 +f 40913/40913/30159 40921/40921/30167 40912/40912/30158 +f 40919/40919/30165 40922/40922/30168 40923/40923/30169 +f 40919/40919/30165 40923/40923/30169 40920/40920/30166 +f 40921/40921/30167 40924/40924/30170 40922/40922/30168 +f 40921/40921/30167 40922/40922/30168 40919/40919/30165 +f 40917/40917/30163 40925/40925/30171 40924/40924/30170 +f 40917/40917/30163 40924/40924/30170 40921/40921/30167 +f 40916/40916/30162 40926/40926/30172 40925/40925/30171 +f 40916/40916/30162 40925/40925/30171 40917/40917/30163 +f 40918/40918/30164 40927/40927/30173 40926/40926/30172 +f 40918/40918/30164 40926/40926/30172 40916/40916/30162 +f 40849/40849/30095 40850/40850/30096 40927/40927/30173 +f 40849/40849/30095 40927/40927/30173 40918/40918/30164 +f 40926/40926/30172 40928/40928/30174 40929/40929/30175 +f 40926/40926/30172 40929/40929/30175 40925/40925/30171 +f 40927/40927/30173 40930/40930/30176 40928/40928/30174 +f 40927/40927/30173 40928/40928/30174 40926/40926/30172 +f 40850/40850/30096 40851/40851/30097 40930/40930/30176 +f 40850/40850/30096 40930/40930/30176 40927/40927/30173 +f 40922/40922/30168 40931/40931/30177 40932/40932/30178 +f 40922/40922/30168 40932/40932/30178 40923/40923/30169 +f 40924/40924/30170 40933/40933/30179 40931/40931/30177 +f 40924/40924/30170 40931/40931/30177 40922/40922/30168 +f 40925/40925/30171 40929/40929/30175 40933/40933/30179 +f 40925/40925/30171 40933/40933/30179 40924/40924/30170 +f 40931/40931/30177 40934/40934/30180 40935/40935/30181 +f 40931/40931/30177 40935/40935/30181 40932/40932/30178 +f 40933/40933/30179 40936/40936/30182 40934/40934/30180 +f 40933/40933/30179 40934/40934/30180 40931/40931/30177 +f 40929/40929/30175 40937/40937/30183 40936/40936/30182 +f 40929/40929/30175 40936/40936/30182 40933/40933/30179 +f 40928/40928/30174 40938/40938/30184 40937/40937/30183 +f 40928/40928/30174 40937/40937/30183 40929/40929/30175 +f 40930/40930/30176 40939/40939/30185 40938/40938/30184 +f 40930/40930/30176 40938/40938/30184 40928/40928/30174 +f 40851/40851/30097 40852/40852/30098 40939/40939/30185 +f 40851/40851/30097 40939/40939/30185 40930/40930/30176 +f 40939/40939/30185 40940/40940/30186 40941/40941/30187 +f 40939/40939/30185 40941/40941/30187 40938/40938/30184 +f 40852/40852/30098 40853/40853/30099 40940/40940/30186 +f 40852/40852/30098 40940/40940/30186 40939/40939/30185 +f 40934/40934/30180 40942/40942/30188 40943/40943/30189 +f 40934/40934/30180 40943/40943/30189 40935/40935/30181 +f 40936/40936/30182 40944/40944/30190 40942/40942/30188 +f 40936/40936/30182 40942/40942/30188 40934/40934/30180 +f 40937/40937/30183 40945/40945/30191 40944/40944/30190 +f 40937/40937/30183 40944/40944/30190 40936/40936/30182 +f 40938/40938/30184 40941/40941/30187 40945/40945/30191 +f 40938/40938/30184 40945/40945/30191 40937/40937/30183 +f 40942/40942/30188 40946/40946/30192 40947/40947/30193 +f 40942/40942/30188 40947/40947/30193 40943/40943/30189 +f 40944/40944/30190 40948/40948/30194 40946/40946/30192 +f 40944/40944/30190 40946/40946/30192 40942/40942/30188 +f 40945/40945/30191 40949/40949/30195 40948/40948/30194 +f 40945/40945/30191 40948/40948/30194 40944/40944/30190 +f 40941/40941/30187 40950/40950/30196 40949/40949/30195 +f 40941/40941/30187 40949/40949/30195 40945/40945/30191 +f 40940/40940/30186 40951/40951/30197 40950/40950/30196 +f 40940/40940/30186 40950/40950/30196 40941/40941/30187 +f 40853/40853/30099 40854/40854/30100 40951/40951/30197 +f 40853/40853/30099 40951/40951/30197 40940/40940/30186 +f 40951/40951/30197 40952/40952/30198 40953/40953/30199 +f 40951/40951/30197 40953/40953/30199 40950/40950/30196 +f 40854/40854/30100 40855/40855/30101 40952/40952/30198 +f 40854/40854/30100 40952/40952/30198 40951/40951/30197 +f 40946/40946/30192 40954/40954/30200 40955/40955/30201 +f 40946/40946/30192 40955/40955/30201 40947/40947/30193 +f 40948/40948/30194 40956/40956/30202 40954/40954/30200 +f 40948/40948/30194 40954/40954/30200 40946/40946/30192 +f 40949/40949/30195 40957/40957/30203 40956/40956/30202 +f 40949/40949/30195 40956/40956/30202 40948/40948/30194 +f 40950/40950/30196 40953/40953/30199 40957/40957/30203 +f 40950/40950/30196 40957/40957/30203 40949/40949/30195 +f 40956/40956/30202 40958/40958/30204 40959/40959/30205 +f 40956/40956/30202 40959/40959/30205 40954/40954/30200 +f 40957/40957/30203 40960/40960/30206 40958/40958/30204 +f 40957/40957/30203 40958/40958/30204 40956/40956/30202 +f 40953/40953/30199 40961/40961/30207 40960/40960/30206 +f 40953/40953/30199 40960/40960/30206 40957/40957/30203 +f 40952/40952/30198 40962/40962/30208 40961/40961/30207 +f 40952/40952/30198 40961/40961/30207 40953/40953/30199 +f 40855/40855/30101 40856/40856/30102 40962/40962/30208 +f 40855/40855/30101 40962/40962/30208 40952/40952/30198 +f 40954/40954/30200 40959/40959/30205 40963/40963/30209 +f 40954/40954/30200 40963/40963/30209 40955/40955/30201 +f 40856/40856/30102 40857/40857/30103 40964/40964/30210 +f 40856/40856/30102 40964/40964/30210 40962/40962/30208 +f 40959/40959/30205 40965/40965/30211 40966/40966/30212 +f 40959/40959/30205 40966/40966/30212 40963/40963/30209 +f 40958/40958/30204 40967/40967/30213 40965/40965/30211 +f 40958/40958/30204 40965/40965/30211 40959/40959/30205 +f 40960/40960/30206 40968/40968/30214 40967/40967/30213 +f 40960/40960/30206 40967/40967/30213 40958/40958/30204 +f 40961/40961/30207 40969/40969/30215 40968/40968/30214 +f 40961/40961/30207 40968/40968/30214 40960/40960/30206 +f 40962/40962/30208 40964/40964/30210 40969/40969/30215 +f 40962/40962/30208 40969/40969/30215 40961/40961/30207 +f 40968/40968/30214 40970/40970/30216 40971/40971/30217 +f 40968/40968/30214 40971/40971/30217 40967/40967/30213 +f 40969/40969/30215 40972/40972/30218 40970/40970/30216 +f 40969/40969/30215 40970/40970/30216 40968/40968/30214 +f 40964/40964/30210 40973/40973/30219 40972/40972/30218 +f 40964/40964/30210 40972/40972/30218 40969/40969/30215 +f 40857/40857/30103 40858/40858/30104 40973/40973/30219 +f 40857/40857/30103 40973/40973/30219 40964/40964/30210 +f 40965/40965/30211 40974/40974/30220 40975/40975/30221 +f 40965/40965/30211 40975/40975/30221 40966/40966/30212 +f 40967/40967/30213 40971/40971/30217 40974/40974/30220 +f 40967/40967/30213 40974/40974/30220 40965/40965/30211 +f 40976/40976/30222 40977/40977/30223 40978/40978/30224 +f 40976/40976/30222 40978/40978/30224 40979/40979/30221 +f 40971/40971/30217 40980/40980/30225 40981/40981/30223 +f 40971/40971/30217 40981/40981/30223 40974/40974/30220 +f 40970/40970/30216 40982/40982/30226 40980/40980/30225 +f 40970/40970/30216 40980/40980/30225 40971/40971/30217 +f 40972/40972/30218 40983/40983/30227 40982/40982/30226 +f 40972/40972/30218 40982/40982/30226 40970/40970/30216 +f 40973/40973/30219 40984/40984/30228 40983/40983/30227 +f 40973/40973/30219 40983/40983/30227 40972/40972/30218 +f 40858/40858/30104 40859/40859/30105 40984/40984/30228 +f 40858/40858/30104 40984/40984/30228 40973/40973/30219 +f 40982/40982/30226 40985/40985/30229 40986/40986/30230 +f 40982/40982/30226 40986/40986/30230 40980/40980/30225 +f 40983/40983/30227 40987/40987/30231 40985/40985/30229 +f 40983/40983/30227 40985/40985/30229 40982/40982/30226 +f 40984/40984/30228 40988/40988/30232 40987/40987/30231 +f 40984/40984/30228 40987/40987/30231 40983/40983/30227 +f 40859/40859/30105 40860/40860/30106 40988/40988/30232 +f 40859/40859/30105 40988/40988/30232 40984/40984/30228 +f 40977/40977/30223 40989/40989/30233 40990/40990/30234 +f 40977/40977/30223 40990/40990/30234 40978/40978/30224 +f 40991/40991/30235 40992/40992/30236 40989/40989/30233 +f 40991/40991/30235 40989/40989/30233 40977/40977/30223 +f 40989/40989/30233 40993/40993/30237 40994/40994/30238 +f 40989/40989/30233 40994/40994/30238 40990/40990/30234 +f 40992/40992/30236 40995/40995/30239 40993/40993/30237 +f 40992/40992/30236 40993/40993/30237 40989/40989/30233 +f 40996/40996/30229 40997/40997/30240 40995/40995/30239 +f 40996/40996/30229 40995/40995/30239 40992/40992/30236 +f 40987/40987/30231 40998/40998/30241 40999/40999/30240 +f 40987/40987/30231 40999/40999/30240 40985/40985/30229 +f 40988/40988/30232 41000/41000/30242 40998/40998/30241 +f 40988/40988/30232 40998/40998/30241 40987/40987/30231 +f 40860/40860/30106 40861/40861/30107 41000/41000/30242 +f 40860/40860/30106 41000/41000/30242 40988/40988/30232 +f 41001/41001/30243 41002/41002/30244 41003/41003/30245 +f 41001/41001/30243 41003/41003/30245 40997/40997/30240 +f 41000/41000/30242 41004/41004/30246 41005/41005/30244 +f 41000/41000/30242 41005/41005/30244 40998/40998/30241 +f 40861/40861/30107 40862/40862/30108 41004/41004/30246 +f 40861/40861/30107 41004/41004/30246 41000/41000/30242 +f 40993/40993/30237 41006/41006/30247 41007/41007/30248 +f 40993/40993/30237 41007/41007/30248 40994/40994/30238 +f 40995/40995/30239 41008/41008/30249 41006/41006/30247 +f 40995/40995/30239 41006/41006/30247 40993/40993/30237 +f 40997/40997/30240 41003/41003/30245 41008/41008/30249 +f 40997/40997/30240 41008/41008/30249 40995/40995/30239 +f 41006/41006/30247 41009/41009/30250 41010/41010/30251 +f 41006/41006/30247 41010/41010/30251 41007/41007/30248 +f 41008/41008/30249 41011/41011/30252 41009/41009/30250 +f 41008/41008/30249 41009/41009/30250 41006/41006/30247 +f 41003/41003/30245 41012/41012/30253 41011/41011/30252 +f 41003/41003/30245 41011/41011/30252 41008/41008/30249 +f 41002/41002/30244 41013/41013/30254 41012/41012/30253 +f 41002/41002/30244 41012/41012/30253 41003/41003/30245 +f 41004/41004/30246 41014/41014/30255 41015/41015/30254 +f 41004/41004/30246 41015/41015/30254 41005/41005/30244 +f 40862/40862/30108 40863/40863/30109 41014/41014/30255 +f 40862/40862/30108 41014/41014/30255 41004/41004/30246 +f 41013/41013/30254 41016/41016/30256 41017/41017/30257 +f 41013/41013/30254 41017/41017/30257 41012/41012/30253 +f 41014/41014/30255 41018/41018/30258 41019/41019/30256 +f 41014/41014/30255 41019/41019/30256 41015/41015/30254 +f 40863/40863/30109 40864/40864/30110 41018/41018/30258 +f 40863/40863/30109 41018/41018/30258 41014/41014/30255 +f 41009/41009/30250 41020/41020/30259 41021/41021/30260 +f 41009/41009/30250 41021/41021/30260 41010/41010/30251 +f 41011/41011/30252 41022/41022/30261 41020/41020/30259 +f 41011/41011/30252 41020/41020/30259 41009/41009/30250 +f 41012/41012/30253 41017/41017/30257 41022/41022/30261 +f 41012/41012/30253 41022/41022/30261 41011/41011/30252 +f 41020/41020/30259 41023/41023/30262 41024/41024/30263 +f 41020/41020/30259 41024/41024/30263 41021/41021/30260 +f 41022/41022/30261 41025/41025/30264 41023/41023/30262 +f 41022/41022/30261 41023/41023/30262 41020/41020/30259 +f 41017/41017/30257 41026/41026/30265 41025/41025/30264 +f 41017/41017/30257 41025/41025/30264 41022/41022/30261 +f 41016/41016/30256 41027/41027/30266 41026/41026/30265 +f 41016/41016/30256 41026/41026/30265 41017/41017/30257 +f 41018/41018/30258 41028/41028/30267 41029/41029/30268 +f 41018/41018/30258 41029/41029/30268 41019/41019/30256 +f 40864/40864/30110 40865/40865/30111 41028/41028/30267 +f 40864/40864/30110 41028/41028/30267 41018/41018/30258 +f 41028/41028/30267 41030/41030/30269 41031/41031/30270 +f 41028/41028/30267 41031/41031/30270 41029/41029/30268 +f 40865/40865/30111 40866/40866/30112 41030/41030/30269 +f 40865/40865/30111 41030/41030/30269 41028/41028/30267 +f 41023/41023/30262 41032/41032/30271 41033/41033/30272 +f 41023/41023/30262 41033/41033/30272 41024/41024/30263 +f 41025/41025/30264 41034/41034/30273 41032/41032/30271 +f 41025/41025/30264 41032/41032/30271 41023/41023/30262 +f 41026/41026/30265 41035/41035/30274 41034/41034/30273 +f 41026/41026/30265 41034/41034/30273 41025/41025/30264 +f 41027/41027/30266 41036/41036/30275 41035/41035/30274 +f 41027/41027/30266 41035/41035/30274 41026/41026/30265 +f 41034/41034/30273 41037/41037/30276 41038/41038/30277 +f 41034/41034/30273 41038/41038/30277 41032/41032/30271 +f 41035/41035/30274 41039/41039/30278 41037/41037/30276 +f 41035/41035/30274 41037/41037/30276 41034/41034/30273 +f 41036/41036/30275 41040/41040/30279 41039/41039/30278 +f 41036/41036/30275 41039/41039/30278 41035/41035/30274 +f 41030/41030/30269 41041/41041/30280 41042/41042/30279 +f 41030/41030/30269 41042/41042/30279 41031/41031/30270 +f 40866/40866/30112 40867/40867/30113 41041/41041/30280 +f 40866/40866/30112 41041/41041/30280 41030/41030/30269 +f 41032/41032/30271 41038/41038/30277 41043/41043/30281 +f 41032/41032/30271 41043/41043/30281 41033/41033/30272 +f 40867/40867/30113 40868/40868/30114 41044/41044/30282 +f 40867/40867/30113 41044/41044/30282 41041/41041/30280 +f 41038/41038/30277 41045/41045/30283 41046/41046/30284 +f 41038/41038/30277 41046/41046/30284 41043/41043/30281 +f 41037/41037/30276 41047/41047/30285 41045/41045/30283 +f 41037/41037/30276 41045/41045/30283 41038/41038/30277 +f 41039/41039/30278 41048/41048/30286 41047/41047/30285 +f 41039/41039/30278 41047/41047/30285 41037/41037/30276 +f 41040/41040/30279 41049/41049/30287 41048/41048/30286 +f 41040/41040/30279 41048/41048/30286 41039/41039/30278 +f 41041/41041/30280 41044/41044/30282 41050/41050/30287 +f 41041/41041/30280 41050/41050/30287 41042/41042/30279 +f 41047/41047/30285 41051/41051/30288 41052/41052/30289 +f 41047/41047/30285 41052/41052/30289 41045/41045/30283 +f 41048/41048/30286 41053/41053/30290 41051/41051/30288 +f 41048/41048/30286 41051/41051/30288 41047/41047/30285 +f 41049/41049/30287 41054/41054/30291 41053/41053/30290 +f 41049/41049/30287 41053/41053/30290 41048/41048/30286 +f 41044/41044/30282 41055/41055/30292 41056/41056/30291 +f 41044/41044/30282 41056/41056/30291 41050/41050/30287 +f 40868/40868/30114 40869/40869/30115 41055/41055/30292 +f 40868/40868/30114 41055/41055/30292 41044/41044/30282 +f 41045/41045/30283 41052/41052/30289 41057/41057/30293 +f 41045/41045/30283 41057/41057/30293 41046/41046/30284 +f 40869/40869/30115 40870/40870/30116 41058/41058/30294 +f 40869/40869/30115 41058/41058/30294 41055/41055/30292 +f 41052/41052/30289 41059/41059/30295 41060/41060/30296 +f 41052/41052/30289 41060/41060/30296 41057/41057/30293 +f 41051/41051/30288 41061/41061/30297 41059/41059/30295 +f 41051/41051/30288 41059/41059/30295 41052/41052/30289 +f 41053/41053/30290 41062/41062/30298 41061/41061/30297 +f 41053/41053/30290 41061/41061/30297 41051/41051/30288 +f 41054/41054/30291 41063/41063/30299 41062/41062/30298 +f 41054/41054/30291 41062/41062/30298 41053/41053/30290 +f 41055/41055/30292 41058/41058/30294 41064/41064/30299 +f 41055/41055/30292 41064/41064/30299 41056/41056/30291 +f 41062/41062/30298 41065/41065/30300 41066/41066/30301 +f 41062/41062/30298 41066/41066/30301 41061/41061/30297 +f 41064/41064/30299 41067/41067/30302 41068/41068/30303 +f 41064/41064/30299 41068/41068/30303 41069/41069/30298 +f 41058/41058/30294 41070/41070/30304 41067/41067/30302 +f 41058/41058/30294 41067/41067/30302 41064/41064/30299 +f 40870/40870/30116 40871/40871/30117 41070/41070/30304 +f 40870/40870/30116 41070/41070/30304 41058/41058/30294 +f 41059/41059/30295 41071/41071/30305 41072/41072/30306 +f 41059/41059/30295 41072/41072/30306 41060/41060/30296 +f 41061/41061/30297 41066/41066/30301 41071/41071/30305 +f 41061/41061/30297 41071/41071/30305 41059/41059/30295 +f 41071/41071/30305 41073/41073/30307 41074/41074/30308 +f 41071/41071/30305 41074/41074/30308 41072/41072/30306 +f 41066/41066/30301 41075/41075/30309 41073/41073/30307 +f 41066/41066/30301 41073/41073/30307 41071/41071/30305 +f 41068/41068/30303 41076/41076/30310 41077/41077/30309 +f 41068/41068/30303 41077/41077/30309 41078/41078/30301 +f 41067/41067/30302 41079/41079/30311 41076/41076/30310 +f 41067/41067/30302 41076/41076/30310 41068/41068/30303 +f 41070/41070/30304 41080/41080/30312 41079/41079/30311 +f 41070/41070/30304 41079/41079/30311 41067/41067/30302 +f 40871/40871/30117 40872/40872/30118 41080/41080/30312 +f 40871/40871/30117 41080/41080/30312 41070/41070/30304 +f 41076/41076/30310 41081/41081/30313 41082/41082/30314 +f 41076/41076/30310 41082/41082/30314 41077/41077/30309 +f 41079/41079/30311 41083/41083/30315 41081/41081/30313 +f 41079/41079/30311 41081/41081/30313 41076/41076/30310 +f 41080/41080/30312 41084/41084/30316 41083/41083/30315 +f 41080/41080/30312 41083/41083/30315 41079/41079/30311 +f 40872/40872/30118 40873/40873/30119 41084/41084/30316 +f 40872/40872/30118 41084/41084/30316 41080/41080/30312 +f 41073/41073/30307 41085/41085/30317 41086/41086/30318 +f 41073/41073/30307 41086/41086/30318 41074/41074/30308 +f 41077/41077/30309 41082/41082/30314 41087/41087/30319 +f 41077/41077/30309 41087/41087/30319 41088/41088/30307 +f 41087/41087/30319 40874/40874/30120 40877/40877/30123 +f 41087/41087/30319 40877/40877/30123 41089/41089/30318 +f 41082/41082/30314 40878/40878/30124 40874/40874/30120 +f 41082/41082/30314 40874/40874/30120 41087/41087/30319 +f 41081/41081/30313 40880/40880/30126 40878/40878/30124 +f 41081/41081/30313 40878/40878/30124 41082/41082/30314 +f 41083/41083/30315 40882/40882/30128 40880/40880/30126 +f 41083/41083/30315 40880/40880/30126 41081/41081/30313 +f 41084/41084/30316 40884/40884/30130 40882/40882/30128 +f 41084/41084/30316 40882/40882/30128 41083/41083/30315 +f 40873/40873/30119 40843/40843/30089 40884/40884/30130 +f 40873/40873/30119 40884/40884/30130 41084/41084/30316 +o Sphere.019__0 +v 0.539754 -0.985471 -1.009781 +v 0.538096 -0.977103 -1.010126 +v 0.539747 -0.976940 -1.010171 +v 0.536510 -0.977586 -1.010052 +v 0.535048 -0.978371 -1.009953 +v 0.533768 -0.979428 -1.009832 +v 0.532718 -0.980715 -1.009694 +v 0.531938 -0.982183 -1.009545 +v 0.531459 -0.983777 -1.009389 +v 0.531299 -0.985434 -1.009233 +v 0.531465 -0.987091 -1.009083 +v 0.531949 -0.988685 -1.008945 +v 0.532734 -0.990153 -1.008823 +v 0.533788 -0.991441 -1.008723 +v 0.535072 -0.992497 -1.008649 +v 0.536536 -0.993282 -1.008603 +v 0.538124 -0.993765 -1.008588 +v 0.539775 -0.993928 -1.008603 +v 0.541425 -0.993765 -1.008648 +v 0.543012 -0.993282 -1.008721 +v 0.544474 -0.992497 -1.008820 +v 0.545754 -0.991441 -1.008941 +v 0.546804 -0.990153 -1.009079 +v 0.547584 -0.988685 -1.009229 +v 0.548063 -0.987091 -1.009385 +v 0.548222 -0.985434 -1.009541 +v 0.548057 -0.983777 -1.009691 +v 0.547573 -0.982183 -1.009829 +v 0.546788 -0.980715 -1.009951 +v 0.545734 -0.979428 -1.010050 +v 0.544450 -0.978371 -1.010124 +v 0.542985 -0.977586 -1.010170 +v 0.541398 -0.977103 -1.010186 +v 0.539917 -0.944075 -1.000837 +v 0.532101 -0.944847 -1.000623 +v 0.531685 -0.942062 -0.996992 +v 0.539983 -0.941242 -0.997219 +v 0.539859 -0.948426 -1.004010 +v 0.532825 -0.949121 -1.003818 +v 0.539811 -0.954128 -1.006618 +v 0.533829 -0.954719 -1.006454 +v 0.539776 -0.960961 -1.008559 +v 0.535076 -0.961426 -1.008430 +v 0.539754 -0.968664 -1.009758 +v 0.536516 -0.968984 -1.009670 +v 0.533405 -0.969932 -1.009526 +v 0.524587 -0.947137 -1.000275 +v 0.523709 -0.944492 -0.996622 +v 0.526063 -0.951181 -1.003505 +v 0.528079 -0.956471 -1.006187 +v 0.530558 -0.962802 -1.008221 +v 0.519834 -0.954527 -1.003082 +v 0.517666 -0.950854 -0.999806 +v 0.522782 -0.959316 -1.005828 +v 0.526396 -0.965038 -1.007938 +v 0.530538 -0.971472 -1.009331 +v 0.516361 -0.948438 -0.996124 +v 0.528026 -0.973544 -1.009094 +v 0.511603 -0.955857 -0.999233 +v 0.509924 -0.953749 -0.995517 +v 0.514377 -0.959029 -1.002567 +v 0.518141 -0.963145 -1.005390 +v 0.522749 -0.968046 -1.007594 +v 0.514334 -0.967811 -1.004890 +v 0.509901 -0.964515 -1.001979 +v 0.519759 -0.971712 -1.007201 +v 0.525966 -0.976069 -1.008823 +v 0.506629 -0.961952 -0.998580 +v 0.504645 -0.960221 -0.994823 +v 0.502938 -0.968907 -0.997870 +v 0.500726 -0.967604 -0.994070 +v 0.506579 -0.970774 -1.001340 +v 0.511509 -0.973134 -1.004347 +v 0.517539 -0.975894 -1.006775 +v 0.524437 -0.978950 -1.008529 +v 0.516176 -0.980432 -1.006331 +v 0.509774 -0.978909 -1.003782 +v 0.523498 -0.982076 -1.008224 +v 0.500671 -0.976454 -0.997132 +v 0.498319 -0.975615 -0.993286 +v 0.504538 -0.977566 -1.000676 +v 0.499914 -0.984301 -0.996393 +v 0.497516 -0.983946 -0.992502 +v 0.503857 -0.984629 -1.000011 +v 0.509195 -0.984916 -1.003217 +v 0.515720 -0.985151 -1.005887 +v 0.523184 -0.985326 -1.007918 +v 0.516191 -0.989871 -1.005459 +v 0.509794 -0.990922 -1.002673 +v 0.523509 -0.988577 -1.007623 +v 0.500697 -0.992149 -0.995683 +v 0.498347 -0.992277 -0.991748 +v 0.504562 -0.991691 -0.999372 +v 0.502990 -0.999695 -0.995028 +v 0.500782 -1.000288 -0.991052 +v 0.506626 -0.998483 -0.998782 +v 0.511549 -0.996698 -1.002172 +v 0.517570 -0.994408 -1.005065 +v 0.524458 -0.991703 -1.007352 +v 0.525997 -0.994583 -1.007114 +v 0.519804 -0.998590 -1.004720 +v 0.506705 -1.006650 -0.994453 +v 0.504725 -1.007672 -0.990442 +v 0.509969 -1.004742 -0.998265 +v 0.514392 -1.002021 -1.001732 +v 0.511698 -1.012746 -0.993981 +v 0.510026 -1.014143 -0.989941 +v 0.514463 -1.010228 -0.997840 +v 0.518214 -1.006686 -1.001370 +v 0.522807 -1.002256 -1.004436 +v 0.528065 -0.997108 -1.006919 +v 0.530584 -0.999181 -1.006773 +v 0.526464 -1.005265 -1.004225 +v 0.517779 -1.017748 -0.993630 +v 0.516481 -1.019453 -0.989568 +v 0.519935 -1.014730 -0.997524 +v 0.522868 -1.010515 -1.001101 +v 0.526175 -1.018076 -0.997329 +v 0.524712 -1.021466 -0.993413 +v 0.528175 -1.013360 -1.000936 +v 0.530633 -1.007500 -1.004094 +v 0.533456 -1.000720 -1.006683 +v 0.523842 -1.023400 -0.989337 +v 0.536572 -1.001668 -1.006652 +v 0.532233 -1.023755 -0.993338 +v 0.531826 -1.025830 -0.989259 +v 0.532944 -1.020136 -0.997262 +v 0.533931 -1.015112 -1.000878 +v 0.535156 -1.008877 -1.004049 +v 0.539915 -1.015704 -1.000933 +v 0.539981 -1.020832 -0.997326 +v 0.539857 -1.009341 -1.004092 +v 0.539810 -1.001989 -1.006682 +v 0.540052 -1.024528 -0.993409 +v 0.540126 -1.026651 -0.989334 +v 0.540052 -1.024528 -0.993409 +v 0.547868 -1.023755 -0.993623 +v 0.548424 -1.025830 -0.989561 +v 0.540126 -1.026651 -0.989334 +v 0.547015 -1.020136 -0.997518 +v 0.547868 -1.023755 -0.993623 +v 0.545897 -1.015112 -1.001096 +v 0.544558 -1.008877 -1.004220 +v 0.543047 -1.001668 -1.006770 +v 0.551647 -1.013360 -1.001363 +v 0.553776 -1.018076 -0.997831 +v 0.549076 -1.007500 -1.004430 +v 0.546160 -1.000720 -1.006914 +v 0.555381 -1.021466 -0.993971 +v 0.556400 -1.023400 -0.989930 +v 0.547015 -1.020136 -0.997518 +v 0.553776 -1.018076 -0.997831 +v 0.562302 -1.017748 -0.994441 +v 0.563747 -1.019453 -0.990429 +v 0.560006 -1.014730 -0.998254 +v 0.551647 -1.013360 -1.001363 +v 0.556945 -1.010515 -1.001722 +v 0.553238 -1.005265 -1.004712 +v 0.556945 -1.010515 -1.001722 +v 0.549027 -0.999181 -1.007109 +v 0.553238 -1.005265 -1.004712 +v 0.556884 -1.002256 -1.005056 +v 0.561586 -1.006686 -1.002160 +v 0.551538 -0.997108 -1.007346 +v 0.556884 -1.002256 -1.005056 +v 0.568366 -1.012746 -0.995013 +v 0.570184 -1.014143 -0.991036 +v 0.565463 -1.010228 -0.998769 +v 0.573339 -1.006650 -0.995667 +v 0.575464 -1.007672 -0.991730 +v 0.569938 -1.004742 -0.999357 +v 0.565392 -1.002021 -1.002660 +v 0.559875 -0.998590 -1.005449 +v 0.553598 -0.994583 -1.007617 +v 0.559875 -0.998590 -1.005449 +v 0.562094 -0.994408 -1.005876 +v 0.568217 -0.996698 -1.003203 +v 0.555127 -0.991703 -1.007910 +v 0.562094 -0.994408 -1.005876 +v 0.577030 -0.999695 -0.996376 +v 0.579383 -1.000288 -0.992483 +v 0.573260 -0.998483 -0.999995 +v 0.579298 -0.992149 -0.997114 +v 0.581789 -0.992277 -0.993267 +v 0.575301 -0.991691 -1.000660 +v 0.569953 -0.990922 -1.003768 +v 0.563458 -0.989871 -1.006320 +v 0.556067 -0.988577 -1.008216 +v 0.563458 -0.989871 -1.006320 +v 0.556380 -0.985326 -1.008522 +v 0.563913 -0.985151 -1.006764 +v 0.580055 -0.984301 -0.997853 +v 0.582593 -0.983946 -0.994051 +v 0.575982 -0.984629 -1.001325 +v 0.570532 -0.984916 -1.004333 +v 0.563913 -0.985151 -1.006764 +v 0.575277 -0.977566 -1.001964 +v 0.579272 -0.976454 -0.998563 +v 0.569932 -0.978909 -1.004877 +v 0.563442 -0.980432 -1.007191 +v 0.556056 -0.982076 -1.008816 +v 0.563442 -0.980432 -1.007191 +v 0.581762 -0.975615 -0.994805 +v 0.555105 -0.978950 -1.009088 +v 0.576978 -0.968907 -0.999218 +v 0.579328 -0.967604 -0.995501 +v 0.573214 -0.970774 -1.002553 +v 0.568177 -0.973134 -1.005379 +v 0.562063 -0.975894 -1.007585 +v 0.562063 -0.975894 -1.007585 +v 0.569870 -0.964515 -1.003071 +v 0.573264 -0.961952 -0.999793 +v 0.565334 -0.967811 -1.005819 +v 0.559829 -0.971712 -1.007931 +v 0.553567 -0.976069 -1.009326 +v 0.559829 -0.971712 -1.007931 +v 0.575384 -0.960221 -0.996111 +v 0.551498 -0.973544 -1.009521 +v 0.568271 -0.955857 -1.000265 +v 0.570083 -0.953749 -0.996612 +v 0.565377 -0.959029 -1.003496 +v 0.561512 -0.963145 -1.006180 +v 0.556827 -0.968046 -1.008215 +v 0.556827 -0.968046 -1.008215 +v 0.556859 -0.959316 -1.006449 +v 0.559904 -0.954527 -1.003812 +v 0.553170 -0.965038 -1.008426 +v 0.556859 -0.959316 -1.006449 +v 0.561512 -0.963145 -1.006180 +v 0.548980 -0.971472 -1.009667 +v 0.562190 -0.950854 -1.000616 +v 0.563628 -0.948439 -0.996985 +v 0.555256 -0.947137 -1.000834 +v 0.556267 -0.944493 -0.997215 +v 0.553664 -0.951182 -1.004007 +v 0.551552 -0.956471 -1.006615 +v 0.553664 -0.951182 -1.004007 +v 0.559904 -0.954527 -1.003812 +v 0.549001 -0.962802 -1.008556 +v 0.546108 -0.969932 -1.009757 +v 0.545795 -0.954719 -1.006672 +v 0.546896 -0.949121 -1.004074 +v 0.544478 -0.961426 -1.008601 +v 0.542992 -0.968984 -1.009788 +v 0.547735 -0.944847 -1.000908 +v 0.548283 -0.942062 -0.997294 +v 0.547735 -0.944847 -1.000908 +v 0.555256 -0.947137 -1.000834 +v 0.548283 -0.942062 -0.997294 +vt 0.660519 0.777137 +vt 0.660578 0.776509 +vt 0.660458 0.776509 +vt 0.660696 0.776533 +vt 0.660808 0.776580 +vt 0.660908 0.776649 +vt 0.660994 0.776736 +vt 0.661062 0.776839 +vt 0.661109 0.776953 +vt 0.661133 0.777074 +vt 0.661135 0.777198 +vt 0.661113 0.777319 +vt 0.661068 0.777433 +vt 0.661002 0.777536 +vt 0.660918 0.777623 +vt 0.660819 0.777692 +vt 0.660709 0.777739 +vt 0.660591 0.777763 +vt 0.660471 0.777763 +vt 0.660353 0.777739 +vt 0.660242 0.777692 +vt 0.660142 0.777623 +vt 0.660056 0.777536 +vt 0.659988 0.777433 +vt 0.659941 0.777319 +vt 0.659916 0.777198 +vt 0.659915 0.777074 +vt 0.659937 0.776953 +vt 0.659982 0.776839 +vt 0.660048 0.776736 +vt 0.660131 0.776649 +vt 0.660231 0.776580 +vt 0.660341 0.776533 +vt 0.660400 0.774127 +vt 0.660969 0.774127 +vt 0.661044 0.773932 +vt 0.660441 0.773932 +vt 0.660377 0.774436 +vt 0.660888 0.774436 +vt 0.660371 0.774845 +vt 0.660806 0.774845 +vt 0.660383 0.775341 +vt 0.660725 0.775341 +vt 0.660412 0.775902 +vt 0.660648 0.775902 +vt 0.660879 0.775950 +vt 0.661527 0.774242 +vt 0.661637 0.774053 +vt 0.661391 0.774538 +vt 0.661233 0.774933 +vt 0.661061 0.775409 +vt 0.661865 0.774740 +vt 0.662054 0.774465 +vt 0.661637 0.775104 +vt 0.661378 0.775544 +vt 0.661098 0.776042 +vt 0.662197 0.774291 +vt 0.661295 0.776177 +vt 0.662530 0.774790 +vt 0.662702 0.774636 +vt 0.662294 0.775032 +vt 0.662001 0.775353 +vt 0.661664 0.775739 +vt 0.662312 0.775669 +vt 0.662659 0.775405 +vt 0.661908 0.775988 +vt 0.661463 0.776348 +vt 0.662937 0.775204 +vt 0.663133 0.775075 +vt 0.663257 0.775691 +vt 0.663474 0.775592 +vt 0.662948 0.775843 +vt 0.662558 0.776042 +vt 0.662101 0.776281 +vt 0.661596 0.776550 +vt 0.662235 0.776606 +vt 0.662728 0.776455 +vt 0.661688 0.776774 +vt 0.663480 0.776231 +vt 0.663711 0.776166 +vt 0.663149 0.776329 +vt 0.663597 0.776805 +vt 0.663835 0.776775 +vt 0.663254 0.776845 +vt 0.662818 0.776895 +vt 0.662305 0.776951 +vt 0.661737 0.777011 +vt 0.662309 0.777302 +vt 0.662822 0.777342 +vt 0.661739 0.777254 +vt 0.663603 0.777390 +vt 0.663841 0.777396 +vt 0.663260 0.777372 +vt 0.663499 0.777964 +vt 0.663730 0.778005 +vt 0.663165 0.777888 +vt 0.662742 0.777781 +vt 0.662246 0.777647 +vt 0.661696 0.777491 +vt 0.661608 0.777715 +vt 0.662119 0.777973 +vt 0.663287 0.778504 +vt 0.663505 0.778579 +vt 0.662974 0.778375 +vt 0.662580 0.778195 +vt 0.662976 0.778991 +vt 0.663175 0.779095 +vt 0.662695 0.778813 +vt 0.662342 0.778567 +vt 0.661932 0.778265 +vt 0.661479 0.777917 +vt 0.661315 0.778088 +vt 0.661693 0.778514 +vt 0.662579 0.779404 +vt 0.662753 0.779534 +vt 0.662337 0.779185 +vt 0.662038 0.778884 +vt 0.661915 0.779477 +vt 0.662109 0.779729 +vt 0.661679 0.779133 +vt 0.661411 0.778709 +vt 0.661120 0.778223 +vt 0.662255 0.779879 +vt 0.660904 0.778315 +vt 0.661587 0.779953 +vt 0.661700 0.780117 +vt 0.661445 0.779679 +vt 0.661279 0.779304 +vt 0.661096 0.778844 +vt 0.660853 0.779392 +vt 0.660944 0.779782 +vt 0.660762 0.778912 +vt 0.660674 0.778363 +vt 0.661031 0.780067 +vt 0.661110 0.780238 +vt 0.947551 0.152438 +vt 0.947131 0.152324 +vt 0.946899 0.152501 +vt 0.947345 0.152621 +vt 0.660433 0.779782 +vt 0.660462 0.780067 +vt 0.660418 0.779392 +vt 0.660420 0.778912 +vt 0.660438 0.778363 +vt 0.659991 0.779304 +vt 0.659930 0.779679 +vt 0.660084 0.778844 +vt 0.660207 0.778315 +vt 0.946735 0.152101 +vt 0.946479 0.152263 +vt 0.947372 0.152038 +vt 0.947016 0.151837 +vt 0.946379 0.151776 +vt 0.946100 0.151919 +vt 0.946696 0.151545 +vt 0.947311 0.151482 +vt 0.947038 0.151234 +vt 0.659767 0.778709 +vt 0.659587 0.779133 +vt 0.659988 0.778223 +vt 0.947394 0.150855 +vt 0.947211 0.150606 +vt 0.946806 0.150918 +vt 0.659791 0.778088 +vt 0.659481 0.778514 +vt 0.946076 0.151363 +vt 0.945779 0.151480 +vt 0.946423 0.151173 +vt 0.945838 0.150877 +vt 0.945526 0.150964 +vt 0.946209 0.150735 +vt 0.946624 0.150545 +vt 0.947068 0.150314 +vt 0.659623 0.777917 +vt 0.659237 0.778265 +vt 0.946970 0.149989 +vt 0.946499 0.150131 +vt 0.659490 0.777715 +vt 0.659044 0.777973 +vt 0.945674 0.150336 +vt 0.945352 0.150390 +vt 0.946061 0.150249 +vt 0.945590 0.149762 +vt 0.945263 0.149780 +vt 0.945986 0.149732 +vt 0.946435 0.149692 +vt 0.946919 0.149643 +vt 0.659398 0.777491 +vt 0.658910 0.777647 +vt 0.659349 0.777254 +vt 0.658839 0.777302 +vt 0.945590 0.149176 +vt 0.945263 0.149158 +vt 0.945986 0.149205 +vt 0.946435 0.149244 +vt 0.946919 0.149291 +vt 0.946061 0.148688 +vt 0.945674 0.148602 +vt 0.946499 0.148804 +vt 0.946970 0.148946 +vt 0.659347 0.777011 +vt 0.658836 0.776951 +vt 0.945352 0.148549 +vt 0.659390 0.776774 +vt 0.945838 0.148060 +vt 0.945526 0.147974 +vt 0.946209 0.148201 +vt 0.946624 0.148390 +vt 0.947068 0.148620 +vt 0.658899 0.776606 +vt 0.946423 0.147762 +vt 0.946076 0.147573 +vt 0.946806 0.148017 +vt 0.947211 0.148327 +vt 0.659478 0.776550 +vt 0.659026 0.776281 +vt 0.945779 0.147457 +vt 0.659607 0.776348 +vt 0.946379 0.147158 +vt 0.946100 0.147016 +vt 0.946696 0.147389 +vt 0.947038 0.147699 +vt 0.947394 0.148078 +vt 0.659213 0.775988 +vt 0.947311 0.147450 +vt 0.947016 0.147096 +vt 0.659452 0.775739 +vt 0.659186 0.775353 +vt 0.658882 0.775669 +vt 0.659771 0.776177 +vt 0.946735 0.146832 +vt 0.946479 0.146670 +vt 0.947131 0.146607 +vt 0.946899 0.146431 +vt 0.947372 0.146893 +vt 0.659545 0.775104 +vt 0.659406 0.774740 +vt 0.658984 0.775032 +vt 0.659734 0.775544 +vt 0.659966 0.776042 +vt 0.659945 0.774933 +vt 0.659876 0.774538 +vt 0.660048 0.775409 +vt 0.660182 0.775950 +vt 0.947551 0.146492 +vt 0.947345 0.146309 +vt 0.659844 0.774242 +vt 0.659321 0.774465 +vt 0.659850 0.774053 +vn -0.0181 -0.0919 -0.9956 +vn -0.0373 0.0032 -0.9993 +vn -0.0182 0.0051 -0.9998 +vn -0.0556 -0.0023 -0.9985 +vn -0.0725 -0.0113 -0.9973 +vn -0.0873 -0.0233 -0.9959 +vn -0.0994 -0.0379 -0.9943 +vn -0.1083 -0.0546 -0.9926 +vn -0.1139 -0.0727 -0.9908 +vn -0.1157 -0.0915 -0.9891 +vn -0.1138 -0.1103 -0.9874 +vn -0.1082 -0.1285 -0.9858 +vn -0.0992 -0.1452 -0.9844 +vn -0.0870 -0.1597 -0.9833 +vn -0.0723 -0.1718 -0.9825 +vn -0.0553 -0.1807 -0.9820 +vn -0.0370 -0.1862 -0.9818 +vn -0.0179 -0.1881 -0.9820 +vn 0.0012 -0.1862 -0.9825 +vn 0.0195 -0.1807 -0.9833 +vn 0.0364 -0.1718 -0.9845 +vn 0.0512 -0.1598 -0.9858 +vn 0.0633 -0.1452 -0.9874 +vn 0.0723 -0.1284 -0.9891 +vn 0.0778 -0.1103 -0.9908 +vn 0.0796 -0.0916 -0.9926 +vn 0.0777 -0.0727 -0.9943 +vn 0.0721 -0.0546 -0.9959 +vn 0.0631 -0.0379 -0.9973 +vn 0.0509 -0.0233 -0.9984 +vn 0.0361 -0.0112 -0.9993 +vn 0.0192 -0.0023 -0.9998 +vn 0.0009 0.0032 -1.0000 +vn -0.0130 0.6990 -0.7150 +vn -0.1627 0.6843 -0.7108 +vn -0.1764 0.7712 -0.6117 +vn -0.0112 0.7874 -0.6164 +vn -0.0157 0.5096 -0.8603 +vn -0.1310 0.4983 -0.8571 +vn -0.0171 0.3496 -0.9367 +vn -0.1024 0.3413 -0.9344 +vn -0.0178 0.2176 -0.9759 +vn -0.0780 0.2117 -0.9742 +vn -0.0181 0.1052 -0.9943 +vn -0.0567 0.1015 -0.9932 +vn -0.0938 0.0903 -0.9915 +vn -0.3065 0.6408 -0.7039 +vn -0.3349 0.7231 -0.6041 +vn -0.2417 0.4649 -0.8517 +vn -0.1845 0.3166 -0.9304 +vn -0.1359 0.1943 -0.9715 +vn -0.3436 0.4107 -0.8445 +vn -0.4387 0.5703 -0.6945 +vn -0.2600 0.2766 -0.9252 +vn -0.1892 0.1661 -0.9678 +vn -0.1279 0.0723 -0.9891 +vn -0.4807 0.6453 -0.5937 +vn -0.1578 0.0480 -0.9863 +vn -0.5541 0.4757 -0.6831 +vn -0.6080 0.5408 -0.5812 +vn -0.4327 0.3380 -0.8358 +vn -0.3261 0.2228 -0.9187 +vn -0.2359 0.1281 -0.9633 +vn -0.3802 0.1572 -0.9114 +vn -0.5057 0.2495 -0.8259 +vn -0.2741 0.0819 -0.9582 +vn -0.1823 0.0183 -0.9831 +vn -0.6486 0.3607 -0.6702 +vn -0.7122 0.4139 -0.5670 +vn -0.7186 0.2298 -0.6564 +vn -0.7893 0.2695 -0.5517 +vn -0.5598 0.1486 -0.8152 +vn -0.4204 0.0825 -0.9036 +vn -0.3025 0.0292 -0.9527 +vn -0.2005 -0.0154 -0.9796 +vn -0.3199 -0.0280 -0.9470 +vn -0.4450 0.0015 -0.8955 +vn -0.2117 -0.0520 -0.9760 +vn -0.7614 0.0880 -0.6422 +vn -0.8366 0.1130 -0.5361 +vn -0.5930 0.0394 -0.8043 +vn -0.7757 -0.0593 -0.6283 +vn -0.8523 -0.0495 -0.5207 +vn -0.6040 -0.0743 -0.7935 +vn -0.4532 -0.0827 -0.8875 +vn -0.3257 -0.0875 -0.9414 +vn -0.2154 -0.0901 -0.9724 +vn -0.3197 -0.1469 -0.9361 +vn -0.4447 -0.1669 -0.8800 +vn -0.2116 -0.1282 -0.9689 +vn -0.7609 -0.2066 -0.6150 +vn -0.8360 -0.2121 -0.5061 +vn -0.5926 -0.1879 -0.7833 +vn -0.7176 -0.3485 -0.6030 +vn -0.7882 -0.3685 -0.4928 +vn -0.5590 -0.2972 -0.7740 +vn -0.4198 -0.2480 -0.8731 +vn -0.3021 -0.2041 -0.9312 +vn -0.2003 -0.1648 -0.9658 +vn -0.1820 -0.1986 -0.9630 +vn -0.2736 -0.2569 -0.9269 +vn -0.6472 -0.4794 -0.5927 +vn -0.7106 -0.5131 -0.4814 +vn -0.5046 -0.3981 -0.7661 +vn -0.3794 -0.3227 -0.8671 +vn -0.5523 -0.5945 -0.5843 +vn -0.6060 -0.6401 -0.4722 +vn -0.4313 -0.4867 -0.7596 +vn -0.3251 -0.3883 -0.8623 +vn -0.2352 -0.3031 -0.9235 +vn -0.1573 -0.2282 -0.9608 +vn -0.1273 -0.2526 -0.9592 +vn -0.1883 -0.3411 -0.9210 +vn -0.4365 -0.6893 -0.5782 +vn -0.4783 -0.7447 -0.4654 +vn -0.3420 -0.5596 -0.7549 +vn -0.2588 -0.4422 -0.8588 +vn -0.2399 -0.6138 -0.7521 +vn -0.3041 -0.7599 -0.5745 +vn -0.1831 -0.4822 -0.8567 +vn -0.1349 -0.3693 -0.9194 +vn -0.0932 -0.2706 -0.9582 +vn -0.3324 -0.8226 -0.4613 +vn -0.0561 -0.2818 -0.9578 +vn -0.1602 -0.8034 -0.5735 +vn -0.1736 -0.8707 -0.4602 +vn -0.1290 -0.6472 -0.7513 +vn -0.1010 -0.5069 -0.8560 +vn -0.0770 -0.3868 -0.9190 +vn -0.0156 -0.5153 -0.8569 +vn -0.0137 -0.6585 -0.7524 +vn -0.0167 -0.3926 -0.9195 +vn -0.0174 -0.2855 -0.9582 +vn -0.0105 -0.8181 -0.5749 +vn -0.0084 -0.8869 -0.4618 +vn -0.0105 -0.8181 -0.5750 +vn 0.1393 -0.8034 -0.5789 +vn 0.1567 -0.8707 -0.4662 +vn -0.0084 -0.8870 -0.4618 +vn 0.1016 -0.6472 -0.7555 +vn 0.0698 -0.5069 -0.8592 +vn 0.0435 -0.3867 -0.9212 +vn 0.0211 -0.2818 -0.9592 +vn 0.1518 -0.4822 -0.8628 +vn 0.2123 -0.6138 -0.7604 +vn 0.1014 -0.3693 -0.9238 +vn 0.0582 -0.2707 -0.9609 +vn 0.2830 -0.7599 -0.5853 +vn 0.3153 -0.8226 -0.4732 +vn 0.4152 -0.6893 -0.5937 +vn 0.4611 -0.7447 -0.4825 +vn 0.3143 -0.5596 -0.7669 +vn 0.2273 -0.4422 -0.8676 +vn 0.1547 -0.3411 -0.9272 +vn 0.2273 -0.4422 -0.8677 +vn 0.0924 -0.2526 -0.9632 +vn 0.2013 -0.3031 -0.9314 +vn 0.2934 -0.3883 -0.8736 +vn 0.1223 -0.2282 -0.9659 +vn 0.2013 -0.3031 -0.9315 +vn 0.5307 -0.5945 -0.6041 +vn 0.5884 -0.6401 -0.4939 +vn 0.4034 -0.4867 -0.7748 +vn 0.6252 -0.4794 -0.6159 +vn 0.6926 -0.5131 -0.5070 +vn 0.4764 -0.3981 -0.7839 +vn 0.3476 -0.3227 -0.8804 +vn 0.2396 -0.2569 -0.9363 +vn 0.1468 -0.1986 -0.9690 +vn 0.2680 -0.2041 -0.9416 +vn 0.3878 -0.2480 -0.8878 +vn 0.1650 -0.1649 -0.9724 +vn 0.6951 -0.3485 -0.6288 +vn 0.7697 -0.3685 -0.5213 +vn 0.5305 -0.2973 -0.7939 +vn 0.7380 -0.2066 -0.6423 +vn 0.8170 -0.2121 -0.5362 +vn 0.5637 -0.1879 -0.8044 +vn 0.4124 -0.1669 -0.8956 +vn 0.2854 -0.1469 -0.9471 +vn 0.1761 -0.1282 -0.9760 +vn 0.1799 -0.0901 -0.9796 +vn 0.2912 -0.0875 -0.9526 +vn 0.7523 -0.0593 -0.6561 +vn 0.8328 -0.0495 -0.5514 +vn 0.5747 -0.0743 -0.8150 +vn 0.4206 -0.0827 -0.9035 +vn 0.5633 0.0393 -0.8253 +vn 0.7375 0.0880 -0.6695 +vn 0.4121 0.0015 -0.9111 +vn 0.2852 -0.0280 -0.9581 +vn 0.1760 -0.0521 -0.9830 +vn 0.8165 0.1130 -0.5662 +vn 0.1647 -0.0154 -0.9862 +vn 0.6941 0.2298 -0.6822 +vn 0.7686 0.2695 -0.5801 +vn 0.5297 0.1486 -0.8350 +vn 0.3872 0.0825 -0.9183 +vn 0.2676 0.0292 -0.9631 +vn 0.4753 0.2495 -0.8437 +vn 0.6238 0.3607 -0.6934 +vn 0.3468 0.1572 -0.9247 +vn 0.2390 0.0819 -0.9675 +vn 0.1464 0.0184 -0.9891 +vn 0.2390 0.0819 -0.9676 +vn 0.6910 0.4139 -0.5926 +vn 0.1218 0.0480 -0.9914 +vn 0.5289 0.4757 -0.7028 +vn 0.5865 0.5409 -0.6029 +vn 0.4020 0.3380 -0.8510 +vn 0.2924 0.2228 -0.9300 +vn 0.2006 0.1281 -0.9713 +vn 0.2261 0.2766 -0.9340 +vn 0.3126 0.4108 -0.8565 +vn 0.1538 0.1661 -0.9740 +vn 0.0918 0.0723 -0.9932 +vn 0.4131 0.5703 -0.7100 +vn 0.4588 0.6453 -0.6108 +vn 0.2806 0.6408 -0.7145 +vn 0.3127 0.7231 -0.6158 +vn 0.2105 0.4649 -0.8600 +vn 0.1505 0.3166 -0.9365 +vn 0.1004 0.1943 -0.9758 +vn 0.0576 0.0903 -0.9942 +vn 0.0683 0.3413 -0.9375 +vn 0.0997 0.4983 -0.8613 +vn 0.0425 0.2117 -0.9764 +vn 0.0205 0.1015 -0.9946 +vn 0.1368 0.6843 -0.7162 +vn 0.1540 0.7712 -0.6177 +vn 0.1367 0.6843 -0.7163 +vn 0.2806 0.6408 -0.7146 +usemtl Scene_-_Root +s 1 +f 41090/41090/30320 41091/41091/30321 41092/41092/30322 +f 41090/41090/30320 41093/41093/30323 41091/41091/30321 +f 41090/41090/30320 41094/41094/30324 41093/41093/30323 +f 41090/41090/30320 41095/41095/30325 41094/41094/30324 +f 41090/41090/30320 41096/41096/30326 41095/41095/30325 +f 41090/41090/30320 41097/41097/30327 41096/41096/30326 +f 41090/41090/30320 41098/41098/30328 41097/41097/30327 +f 41090/41090/30320 41099/41099/30329 41098/41098/30328 +f 41090/41090/30320 41100/41100/30330 41099/41099/30329 +f 41090/41090/30320 41101/41101/30331 41100/41100/30330 +f 41090/41090/30320 41102/41102/30332 41101/41101/30331 +f 41090/41090/30320 41103/41103/30333 41102/41102/30332 +f 41090/41090/30320 41104/41104/30334 41103/41103/30333 +f 41090/41090/30320 41105/41105/30335 41104/41104/30334 +f 41090/41090/30320 41106/41106/30336 41105/41105/30335 +f 41090/41090/30320 41107/41107/30337 41106/41106/30336 +f 41090/41090/30320 41108/41108/30338 41107/41107/30337 +f 41090/41090/30320 41109/41109/30339 41108/41108/30338 +f 41090/41090/30320 41110/41110/30340 41109/41109/30339 +f 41090/41090/30320 41111/41111/30341 41110/41110/30340 +f 41090/41090/30320 41112/41112/30342 41111/41111/30341 +f 41090/41090/30320 41113/41113/30343 41112/41112/30342 +f 41090/41090/30320 41114/41114/30344 41113/41113/30343 +f 41090/41090/30320 41115/41115/30345 41114/41114/30344 +f 41090/41090/30320 41116/41116/30346 41115/41115/30345 +f 41090/41090/30320 41117/41117/30347 41116/41116/30346 +f 41090/41090/30320 41118/41118/30348 41117/41117/30347 +f 41090/41090/30320 41119/41119/30349 41118/41118/30348 +f 41090/41090/30320 41120/41120/30350 41119/41119/30349 +f 41090/41090/30320 41121/41121/30351 41120/41120/30350 +f 41090/41090/30320 41122/41122/30352 41121/41121/30351 +f 41090/41090/30320 41092/41092/30322 41122/41122/30352 +f 41123/41123/30353 41124/41124/30354 41125/41125/30355 +f 41123/41123/30353 41125/41125/30355 41126/41126/30356 +f 41127/41127/30357 41128/41128/30358 41124/41124/30354 +f 41127/41127/30357 41124/41124/30354 41123/41123/30353 +f 41129/41129/30359 41130/41130/30360 41128/41128/30358 +f 41129/41129/30359 41128/41128/30358 41127/41127/30357 +f 41131/41131/30361 41132/41132/30362 41130/41130/30360 +f 41131/41131/30361 41130/41130/30360 41129/41129/30359 +f 41133/41133/30363 41134/41134/30364 41132/41132/30362 +f 41133/41133/30363 41132/41132/30362 41131/41131/30361 +f 41092/41092/30322 41091/41091/30321 41134/41134/30364 +f 41092/41092/30322 41134/41134/30364 41133/41133/30363 +f 41091/41091/30321 41093/41093/30323 41135/41135/30365 +f 41091/41091/30321 41135/41135/30365 41134/41134/30364 +f 41124/41124/30354 41136/41136/30366 41137/41137/30367 +f 41124/41124/30354 41137/41137/30367 41125/41125/30355 +f 41128/41128/30358 41138/41138/30368 41136/41136/30366 +f 41128/41128/30358 41136/41136/30366 41124/41124/30354 +f 41130/41130/30360 41139/41139/30369 41138/41138/30368 +f 41130/41130/30360 41138/41138/30368 41128/41128/30358 +f 41132/41132/30362 41140/41140/30370 41139/41139/30369 +f 41132/41132/30362 41139/41139/30369 41130/41130/30360 +f 41134/41134/30364 41135/41135/30365 41140/41140/30370 +f 41134/41134/30364 41140/41140/30370 41132/41132/30362 +f 41138/41138/30368 41141/41141/30371 41142/41142/30372 +f 41138/41138/30368 41142/41142/30372 41136/41136/30366 +f 41139/41139/30369 41143/41143/30373 41141/41141/30371 +f 41139/41139/30369 41141/41141/30371 41138/41138/30368 +f 41140/41140/30370 41144/41144/30374 41143/41143/30373 +f 41140/41140/30370 41143/41143/30373 41139/41139/30369 +f 41135/41135/30365 41145/41145/30375 41144/41144/30374 +f 41135/41135/30365 41144/41144/30374 41140/41140/30370 +f 41093/41093/30323 41094/41094/30324 41145/41145/30375 +f 41093/41093/30323 41145/41145/30375 41135/41135/30365 +f 41136/41136/30366 41142/41142/30372 41146/41146/30376 +f 41136/41136/30366 41146/41146/30376 41137/41137/30367 +f 41094/41094/30324 41095/41095/30325 41147/41147/30377 +f 41094/41094/30324 41147/41147/30377 41145/41145/30375 +f 41142/41142/30372 41148/41148/30378 41149/41149/30379 +f 41142/41142/30372 41149/41149/30379 41146/41146/30376 +f 41141/41141/30371 41150/41150/30380 41148/41148/30378 +f 41141/41141/30371 41148/41148/30378 41142/41142/30372 +f 41143/41143/30373 41151/41151/30381 41150/41150/30380 +f 41143/41143/30373 41150/41150/30380 41141/41141/30371 +f 41144/41144/30374 41152/41152/30382 41151/41151/30381 +f 41144/41144/30374 41151/41151/30381 41143/41143/30373 +f 41145/41145/30375 41147/41147/30377 41152/41152/30382 +f 41145/41145/30375 41152/41152/30382 41144/41144/30374 +f 41151/41151/30381 41153/41153/30383 41154/41154/30384 +f 41151/41151/30381 41154/41154/30384 41150/41150/30380 +f 41152/41152/30382 41155/41155/30385 41153/41153/30383 +f 41152/41152/30382 41153/41153/30383 41151/41151/30381 +f 41147/41147/30377 41156/41156/30386 41155/41155/30385 +f 41147/41147/30377 41155/41155/30385 41152/41152/30382 +f 41095/41095/30325 41096/41096/30326 41156/41156/30386 +f 41095/41095/30325 41156/41156/30386 41147/41147/30377 +f 41148/41148/30378 41157/41157/30387 41158/41158/30388 +f 41148/41148/30378 41158/41158/30388 41149/41149/30379 +f 41150/41150/30380 41154/41154/30384 41157/41157/30387 +f 41150/41150/30380 41157/41157/30387 41148/41148/30378 +f 41157/41157/30387 41159/41159/30389 41160/41160/30390 +f 41157/41157/30387 41160/41160/30390 41158/41158/30388 +f 41154/41154/30384 41161/41161/30391 41159/41159/30389 +f 41154/41154/30384 41159/41159/30389 41157/41157/30387 +f 41153/41153/30383 41162/41162/30392 41161/41161/30391 +f 41153/41153/30383 41161/41161/30391 41154/41154/30384 +f 41155/41155/30385 41163/41163/30393 41162/41162/30392 +f 41155/41155/30385 41162/41162/30392 41153/41153/30383 +f 41156/41156/30386 41164/41164/30394 41163/41163/30393 +f 41156/41156/30386 41163/41163/30393 41155/41155/30385 +f 41096/41096/30326 41097/41097/30327 41164/41164/30394 +f 41096/41096/30326 41164/41164/30394 41156/41156/30386 +f 41163/41163/30393 41165/41165/30395 41166/41166/30396 +f 41163/41163/30393 41166/41166/30396 41162/41162/30392 +f 41164/41164/30394 41167/41167/30397 41165/41165/30395 +f 41164/41164/30394 41165/41165/30395 41163/41163/30393 +f 41097/41097/30327 41098/41098/30328 41167/41167/30397 +f 41097/41097/30327 41167/41167/30397 41164/41164/30394 +f 41159/41159/30389 41168/41168/30398 41169/41169/30399 +f 41159/41159/30389 41169/41169/30399 41160/41160/30390 +f 41161/41161/30391 41170/41170/30400 41168/41168/30398 +f 41161/41161/30391 41168/41168/30398 41159/41159/30389 +f 41162/41162/30392 41166/41166/30396 41170/41170/30400 +f 41162/41162/30392 41170/41170/30400 41161/41161/30391 +f 41168/41168/30398 41171/41171/30401 41172/41172/30402 +f 41168/41168/30398 41172/41172/30402 41169/41169/30399 +f 41170/41170/30400 41173/41173/30403 41171/41171/30401 +f 41170/41170/30400 41171/41171/30401 41168/41168/30398 +f 41166/41166/30396 41174/41174/30404 41173/41173/30403 +f 41166/41166/30396 41173/41173/30403 41170/41170/30400 +f 41165/41165/30395 41175/41175/30405 41174/41174/30404 +f 41165/41165/30395 41174/41174/30404 41166/41166/30396 +f 41167/41167/30397 41176/41176/30406 41175/41175/30405 +f 41167/41167/30397 41175/41175/30405 41165/41165/30395 +f 41098/41098/30328 41099/41099/30329 41176/41176/30406 +f 41098/41098/30328 41176/41176/30406 41167/41167/30397 +f 41175/41175/30405 41177/41177/30407 41178/41178/30408 +f 41175/41175/30405 41178/41178/30408 41174/41174/30404 +f 41176/41176/30406 41179/41179/30409 41177/41177/30407 +f 41176/41176/30406 41177/41177/30407 41175/41175/30405 +f 41099/41099/30329 41100/41100/30330 41179/41179/30409 +f 41099/41099/30329 41179/41179/30409 41176/41176/30406 +f 41171/41171/30401 41180/41180/30410 41181/41181/30411 +f 41171/41171/30401 41181/41181/30411 41172/41172/30402 +f 41173/41173/30403 41182/41182/30412 41180/41180/30410 +f 41173/41173/30403 41180/41180/30410 41171/41171/30401 +f 41174/41174/30404 41178/41178/30408 41182/41182/30412 +f 41174/41174/30404 41182/41182/30412 41173/41173/30403 +f 41180/41180/30410 41183/41183/30413 41184/41184/30414 +f 41180/41180/30410 41184/41184/30414 41181/41181/30411 +f 41182/41182/30412 41185/41185/30415 41183/41183/30413 +f 41182/41182/30412 41183/41183/30413 41180/41180/30410 +f 41178/41178/30408 41186/41186/30416 41185/41185/30415 +f 41178/41178/30408 41185/41185/30415 41182/41182/30412 +f 41177/41177/30407 41187/41187/30417 41186/41186/30416 +f 41177/41177/30407 41186/41186/30416 41178/41178/30408 +f 41179/41179/30409 41188/41188/30418 41187/41187/30417 +f 41179/41179/30409 41187/41187/30417 41177/41177/30407 +f 41100/41100/30330 41101/41101/30331 41188/41188/30418 +f 41100/41100/30330 41188/41188/30418 41179/41179/30409 +f 41188/41188/30418 41189/41189/30419 41190/41190/30420 +f 41188/41188/30418 41190/41190/30420 41187/41187/30417 +f 41101/41101/30331 41102/41102/30332 41189/41189/30419 +f 41101/41101/30331 41189/41189/30419 41188/41188/30418 +f 41183/41183/30413 41191/41191/30421 41192/41192/30422 +f 41183/41183/30413 41192/41192/30422 41184/41184/30414 +f 41185/41185/30415 41193/41193/30423 41191/41191/30421 +f 41185/41185/30415 41191/41191/30421 41183/41183/30413 +f 41186/41186/30416 41194/41194/30424 41193/41193/30423 +f 41186/41186/30416 41193/41193/30423 41185/41185/30415 +f 41187/41187/30417 41190/41190/30420 41194/41194/30424 +f 41187/41187/30417 41194/41194/30424 41186/41186/30416 +f 41191/41191/30421 41195/41195/30425 41196/41196/30426 +f 41191/41191/30421 41196/41196/30426 41192/41192/30422 +f 41193/41193/30423 41197/41197/30427 41195/41195/30425 +f 41193/41193/30423 41195/41195/30425 41191/41191/30421 +f 41194/41194/30424 41198/41198/30428 41197/41197/30427 +f 41194/41194/30424 41197/41197/30427 41193/41193/30423 +f 41190/41190/30420 41199/41199/30429 41198/41198/30428 +f 41190/41190/30420 41198/41198/30428 41194/41194/30424 +f 41189/41189/30419 41200/41200/30430 41199/41199/30429 +f 41189/41189/30419 41199/41199/30429 41190/41190/30420 +f 41102/41102/30332 41103/41103/30333 41200/41200/30430 +f 41102/41102/30332 41200/41200/30430 41189/41189/30419 +f 41200/41200/30430 41201/41201/30431 41202/41202/30432 +f 41200/41200/30430 41202/41202/30432 41199/41199/30429 +f 41103/41103/30333 41104/41104/30334 41201/41201/30431 +f 41103/41103/30333 41201/41201/30431 41200/41200/30430 +f 41195/41195/30425 41203/41203/30433 41204/41204/30434 +f 41195/41195/30425 41204/41204/30434 41196/41196/30426 +f 41197/41197/30427 41205/41205/30435 41203/41203/30433 +f 41197/41197/30427 41203/41203/30433 41195/41195/30425 +f 41198/41198/30428 41206/41206/30436 41205/41205/30435 +f 41198/41198/30428 41205/41205/30435 41197/41197/30427 +f 41199/41199/30429 41202/41202/30432 41206/41206/30436 +f 41199/41199/30429 41206/41206/30436 41198/41198/30428 +f 41205/41205/30435 41207/41207/30437 41208/41208/30438 +f 41205/41205/30435 41208/41208/30438 41203/41203/30433 +f 41206/41206/30436 41209/41209/30439 41207/41207/30437 +f 41206/41206/30436 41207/41207/30437 41205/41205/30435 +f 41202/41202/30432 41210/41210/30440 41209/41209/30439 +f 41202/41202/30432 41209/41209/30439 41206/41206/30436 +f 41201/41201/30431 41211/41211/30441 41210/41210/30440 +f 41201/41201/30431 41210/41210/30440 41202/41202/30432 +f 41104/41104/30334 41105/41105/30335 41211/41211/30441 +f 41104/41104/30334 41211/41211/30441 41201/41201/30431 +f 41203/41203/30433 41208/41208/30438 41212/41212/30442 +f 41203/41203/30433 41212/41212/30442 41204/41204/30434 +f 41105/41105/30335 41106/41106/30336 41213/41213/30443 +f 41105/41105/30335 41213/41213/30443 41211/41211/30441 +f 41208/41208/30438 41214/41214/30444 41215/41215/30445 +f 41208/41208/30438 41215/41215/30445 41212/41212/30442 +f 41207/41207/30437 41216/41216/30446 41214/41214/30444 +f 41207/41207/30437 41214/41214/30444 41208/41208/30438 +f 41209/41209/30439 41217/41217/30447 41216/41216/30446 +f 41209/41209/30439 41216/41216/30446 41207/41207/30437 +f 41210/41210/30440 41218/41218/30448 41217/41217/30447 +f 41210/41210/30440 41217/41217/30447 41209/41209/30439 +f 41211/41211/30441 41213/41213/30443 41218/41218/30448 +f 41211/41211/30441 41218/41218/30448 41210/41210/30440 +f 41217/41217/30447 41219/41219/30449 41220/41220/30450 +f 41217/41217/30447 41220/41220/30450 41216/41216/30446 +f 41218/41218/30448 41221/41221/30451 41219/41219/30449 +f 41218/41218/30448 41219/41219/30449 41217/41217/30447 +f 41213/41213/30443 41222/41222/30452 41221/41221/30451 +f 41213/41213/30443 41221/41221/30451 41218/41218/30448 +f 41106/41106/30336 41107/41107/30337 41222/41222/30452 +f 41106/41106/30336 41222/41222/30452 41213/41213/30443 +f 41214/41214/30444 41223/41223/30453 41224/41224/30454 +f 41214/41214/30444 41224/41224/30454 41215/41215/30445 +f 41216/41216/30446 41220/41220/30450 41223/41223/30453 +f 41216/41216/30446 41223/41223/30453 41214/41214/30444 +f 41225/41225/30455 41226/41226/30456 41227/41227/30457 +f 41225/41225/30455 41227/41227/30457 41228/41228/30458 +f 41220/41220/30450 41229/41229/30459 41230/41230/30456 +f 41220/41220/30450 41230/41230/30456 41223/41223/30453 +f 41219/41219/30449 41231/41231/30460 41229/41229/30459 +f 41219/41219/30449 41229/41229/30459 41220/41220/30450 +f 41221/41221/30451 41232/41232/30461 41231/41231/30460 +f 41221/41221/30451 41231/41231/30460 41219/41219/30449 +f 41222/41222/30452 41233/41233/30462 41232/41232/30461 +f 41222/41222/30452 41232/41232/30461 41221/41221/30451 +f 41107/41107/30337 41108/41108/30338 41233/41233/30462 +f 41107/41107/30337 41233/41233/30462 41222/41222/30452 +f 41231/41231/30460 41234/41234/30463 41235/41235/30464 +f 41231/41231/30460 41235/41235/30464 41229/41229/30459 +f 41232/41232/30461 41236/41236/30465 41234/41234/30463 +f 41232/41232/30461 41234/41234/30463 41231/41231/30460 +f 41233/41233/30462 41237/41237/30466 41236/41236/30465 +f 41233/41233/30462 41236/41236/30465 41232/41232/30461 +f 41108/41108/30338 41109/41109/30339 41237/41237/30466 +f 41108/41108/30338 41237/41237/30466 41233/41233/30462 +f 41226/41226/30456 41238/41238/30467 41239/41239/30468 +f 41226/41226/30456 41239/41239/30468 41227/41227/30457 +f 41240/41240/30459 41241/41241/30464 41238/41238/30467 +f 41240/41240/30459 41238/41238/30467 41226/41226/30456 +f 41238/41238/30467 41242/41242/30469 41243/41243/30470 +f 41238/41238/30467 41243/41243/30470 41239/41239/30468 +f 41241/41241/30464 41244/41244/30471 41242/41242/30469 +f 41241/41241/30464 41242/41242/30469 41238/41238/30467 +f 41245/41245/30463 41246/41246/30472 41244/41244/30471 +f 41245/41245/30463 41244/41244/30471 41241/41241/30464 +f 41236/41236/30465 41247/41247/30473 41248/41248/30474 +f 41236/41236/30465 41248/41248/30474 41234/41234/30463 +f 41237/41237/30466 41249/41249/30475 41247/41247/30473 +f 41237/41237/30466 41247/41247/30473 41236/41236/30465 +f 41109/41109/30339 41110/41110/30340 41249/41249/30475 +f 41109/41109/30339 41249/41249/30475 41237/41237/30466 +f 41250/41250/30473 41251/41251/30476 41252/41252/30477 +f 41250/41250/30473 41252/41252/30477 41246/41246/30472 +f 41249/41249/30475 41253/41253/30478 41254/41254/30479 +f 41249/41249/30475 41254/41254/30479 41247/41247/30473 +f 41110/41110/30340 41111/41111/30341 41253/41253/30478 +f 41110/41110/30340 41253/41253/30478 41249/41249/30475 +f 41242/41242/30469 41255/41255/30480 41256/41256/30481 +f 41242/41242/30469 41256/41256/30481 41243/41243/30470 +f 41244/41244/30471 41257/41257/30482 41255/41255/30480 +f 41244/41244/30471 41255/41255/30480 41242/41242/30469 +f 41246/41246/30472 41252/41252/30477 41257/41257/30482 +f 41246/41246/30472 41257/41257/30482 41244/41244/30471 +f 41255/41255/30480 41258/41258/30483 41259/41259/30484 +f 41255/41255/30480 41259/41259/30484 41256/41256/30481 +f 41257/41257/30482 41260/41260/30485 41258/41258/30483 +f 41257/41257/30482 41258/41258/30483 41255/41255/30480 +f 41252/41252/30477 41261/41261/30486 41260/41260/30485 +f 41252/41252/30477 41260/41260/30485 41257/41257/30482 +f 41251/41251/30476 41262/41262/30487 41261/41261/30486 +f 41251/41251/30476 41261/41261/30486 41252/41252/30477 +f 41253/41253/30478 41263/41263/30488 41264/41264/30487 +f 41253/41253/30478 41264/41264/30487 41254/41254/30479 +f 41111/41111/30341 41112/41112/30342 41263/41263/30488 +f 41111/41111/30341 41263/41263/30488 41253/41253/30478 +f 41262/41262/30487 41265/41265/30489 41266/41266/30490 +f 41262/41262/30487 41266/41266/30490 41261/41261/30486 +f 41263/41263/30488 41267/41267/30491 41268/41268/30489 +f 41263/41263/30488 41268/41268/30489 41264/41264/30487 +f 41112/41112/30342 41113/41113/30343 41267/41267/30491 +f 41112/41112/30342 41267/41267/30491 41263/41263/30488 +f 41258/41258/30483 41269/41269/30492 41270/41270/30493 +f 41258/41258/30483 41270/41270/30493 41259/41259/30484 +f 41260/41260/30485 41271/41271/30494 41269/41269/30492 +f 41260/41260/30485 41269/41269/30492 41258/41258/30483 +f 41261/41261/30486 41266/41266/30490 41271/41271/30494 +f 41261/41261/30486 41271/41271/30494 41260/41260/30485 +f 41269/41269/30492 41272/41272/30495 41273/41273/30496 +f 41269/41269/30492 41273/41273/30496 41270/41270/30493 +f 41271/41271/30494 41274/41274/30497 41272/41272/30495 +f 41271/41271/30494 41272/41272/30495 41269/41269/30492 +f 41266/41266/30490 41275/41275/30498 41274/41274/30497 +f 41266/41266/30490 41274/41274/30497 41271/41271/30494 +f 41265/41265/30489 41276/41276/30499 41275/41275/30498 +f 41265/41265/30489 41275/41275/30498 41266/41266/30490 +f 41267/41267/30491 41277/41277/30500 41278/41278/30499 +f 41267/41267/30491 41278/41278/30499 41268/41268/30489 +f 41113/41113/30343 41114/41114/30344 41277/41277/30500 +f 41113/41113/30343 41277/41277/30500 41267/41267/30491 +f 41277/41277/30500 41279/41279/30501 41280/41280/30502 +f 41277/41277/30500 41280/41280/30502 41278/41278/30499 +f 41114/41114/30344 41115/41115/30345 41279/41279/30501 +f 41114/41114/30344 41279/41279/30501 41277/41277/30500 +f 41272/41272/30495 41281/41281/30503 41282/41282/30504 +f 41272/41272/30495 41282/41282/30504 41273/41273/30496 +f 41274/41274/30497 41283/41283/30505 41281/41281/30503 +f 41274/41274/30497 41281/41281/30503 41272/41272/30495 +f 41275/41275/30498 41284/41284/30506 41283/41283/30505 +f 41275/41275/30498 41283/41283/30505 41274/41274/30497 +f 41276/41276/30499 41285/41285/30502 41284/41284/30506 +f 41276/41276/30499 41284/41284/30506 41275/41275/30498 +f 41283/41283/30505 41286/41286/30507 41287/41287/30508 +f 41283/41283/30505 41287/41287/30508 41281/41281/30503 +f 41284/41284/30506 41288/41288/30509 41286/41286/30507 +f 41284/41284/30506 41286/41286/30507 41283/41283/30505 +f 41285/41285/30502 41289/41289/30510 41288/41288/30509 +f 41285/41285/30502 41288/41288/30509 41284/41284/30506 +f 41279/41279/30501 41290/41290/30511 41291/41291/30510 +f 41279/41279/30501 41291/41291/30510 41280/41280/30502 +f 41115/41115/30345 41116/41116/30346 41290/41290/30511 +f 41115/41115/30345 41290/41290/30511 41279/41279/30501 +f 41281/41281/30503 41287/41287/30508 41292/41292/30512 +f 41281/41281/30503 41292/41292/30512 41282/41282/30504 +f 41116/41116/30346 41117/41117/30347 41293/41293/30513 +f 41116/41116/30346 41293/41293/30513 41290/41290/30511 +f 41287/41287/30508 41294/41294/30514 41295/41295/30515 +f 41287/41287/30508 41295/41295/30515 41292/41292/30512 +f 41286/41286/30507 41296/41296/30516 41294/41294/30514 +f 41286/41286/30507 41294/41294/30514 41287/41287/30508 +f 41288/41288/30509 41297/41297/30517 41296/41296/30516 +f 41288/41288/30509 41296/41296/30516 41286/41286/30507 +f 41289/41289/30510 41298/41298/30518 41297/41297/30517 +f 41289/41289/30510 41297/41297/30517 41288/41288/30509 +f 41290/41290/30511 41293/41293/30513 41299/41299/30518 +f 41290/41290/30511 41299/41299/30518 41291/41291/30510 +f 41296/41296/30516 41300/41300/30519 41301/41301/30520 +f 41296/41296/30516 41301/41301/30520 41294/41294/30514 +f 41297/41297/30517 41302/41302/30521 41300/41300/30519 +f 41297/41297/30517 41300/41300/30519 41296/41296/30516 +f 41298/41298/30518 41303/41303/30522 41302/41302/30521 +f 41298/41298/30518 41302/41302/30521 41297/41297/30517 +f 41293/41293/30513 41304/41304/30523 41305/41305/30524 +f 41293/41293/30513 41305/41305/30524 41299/41299/30518 +f 41117/41117/30347 41118/41118/30348 41304/41304/30523 +f 41117/41117/30347 41304/41304/30523 41293/41293/30513 +f 41294/41294/30514 41301/41301/30520 41306/41306/30525 +f 41294/41294/30514 41306/41306/30525 41295/41295/30515 +f 41118/41118/30348 41119/41119/30349 41307/41307/30526 +f 41118/41118/30348 41307/41307/30526 41304/41304/30523 +f 41301/41301/30520 41308/41308/30527 41309/41309/30528 +f 41301/41301/30520 41309/41309/30528 41306/41306/30525 +f 41300/41300/30519 41310/41310/30529 41308/41308/30527 +f 41300/41300/30519 41308/41308/30527 41301/41301/30520 +f 41302/41302/30521 41311/41311/30530 41310/41310/30529 +f 41302/41302/30521 41310/41310/30529 41300/41300/30519 +f 41303/41303/30522 41312/41312/30531 41311/41311/30530 +f 41303/41303/30522 41311/41311/30530 41302/41302/30521 +f 41304/41304/30523 41307/41307/30526 41313/41313/30531 +f 41304/41304/30523 41313/41313/30531 41305/41305/30524 +f 41311/41311/30530 41314/41314/30532 41315/41315/30533 +f 41311/41311/30530 41315/41315/30533 41310/41310/30529 +f 41313/41313/30531 41316/41316/30534 41317/41317/30532 +f 41313/41313/30531 41317/41317/30532 41318/41318/30530 +f 41307/41307/30526 41319/41319/30535 41316/41316/30534 +f 41307/41307/30526 41316/41316/30534 41313/41313/30531 +f 41119/41119/30349 41120/41120/30350 41319/41319/30535 +f 41119/41119/30349 41319/41319/30535 41307/41307/30526 +f 41308/41308/30527 41320/41320/30536 41321/41321/30537 +f 41308/41308/30527 41321/41321/30537 41309/41309/30528 +f 41310/41310/30529 41315/41315/30533 41320/41320/30536 +f 41310/41310/30529 41320/41320/30536 41308/41308/30527 +f 41320/41320/30536 41322/41322/30538 41323/41323/30539 +f 41320/41320/30536 41323/41323/30539 41321/41321/30537 +f 41315/41315/30533 41324/41324/30540 41322/41322/30538 +f 41315/41315/30533 41322/41322/30538 41320/41320/30536 +f 41317/41317/30532 41325/41325/30541 41326/41326/30540 +f 41317/41317/30532 41326/41326/30540 41327/41327/30533 +f 41316/41316/30534 41328/41328/30542 41325/41325/30541 +f 41316/41316/30534 41325/41325/30541 41317/41317/30532 +f 41319/41319/30535 41329/41329/30543 41328/41328/30542 +f 41319/41319/30535 41328/41328/30542 41316/41316/30534 +f 41120/41120/30350 41121/41121/30351 41329/41329/30543 +f 41120/41120/30350 41329/41329/30543 41319/41319/30535 +f 41325/41325/30541 41330/41330/30544 41331/41331/30545 +f 41325/41325/30541 41331/41331/30545 41326/41326/30540 +f 41328/41328/30542 41332/41332/30546 41330/41330/30544 +f 41328/41328/30542 41330/41330/30544 41325/41325/30541 +f 41329/41329/30543 41333/41333/30547 41332/41332/30546 +f 41329/41329/30543 41332/41332/30546 41328/41328/30542 +f 41121/41121/30351 41122/41122/30352 41333/41333/30547 +f 41121/41121/30351 41333/41333/30547 41329/41329/30543 +f 41322/41322/30538 41334/41334/30548 41335/41335/30549 +f 41322/41322/30538 41335/41335/30549 41323/41323/30539 +f 41326/41326/30540 41331/41331/30545 41336/41336/30550 +f 41326/41326/30540 41336/41336/30550 41337/41337/30551 +f 41336/41336/30550 41123/41123/30353 41126/41126/30356 +f 41336/41336/30550 41126/41126/30356 41338/41338/30549 +f 41331/41331/30545 41127/41127/30357 41123/41123/30353 +f 41331/41331/30545 41123/41123/30353 41336/41336/30550 +f 41330/41330/30544 41129/41129/30359 41127/41127/30357 +f 41330/41330/30544 41127/41127/30357 41331/41331/30545 +f 41332/41332/30546 41131/41131/30361 41129/41129/30359 +f 41332/41332/30546 41129/41129/30359 41330/41330/30544 +f 41333/41333/30547 41133/41133/30363 41131/41131/30361 +f 41333/41333/30547 41131/41131/30361 41332/41332/30546 +f 41122/41122/30352 41092/41092/30322 41133/41133/30363 +f 41122/41122/30352 41133/41133/30363 41333/41333/30547 +o Sphere.020__0 +v 0.539754 -1.105887 -1.009781 +v 0.538096 -1.097520 -1.010126 +v 0.539747 -1.097356 -1.010171 +v 0.536510 -1.098003 -1.010052 +v 0.535048 -1.098788 -1.009953 +v 0.533768 -1.099844 -1.009832 +v 0.532718 -1.101132 -1.009694 +v 0.531938 -1.102600 -1.009545 +v 0.531459 -1.104194 -1.009389 +v 0.531299 -1.105851 -1.009233 +v 0.531465 -1.107508 -1.009083 +v 0.531949 -1.109101 -1.008945 +v 0.532734 -1.110570 -1.008823 +v 0.533788 -1.111857 -1.008723 +v 0.535072 -1.112913 -1.008649 +v 0.536536 -1.113699 -1.008603 +v 0.538124 -1.114182 -1.008588 +v 0.539775 -1.114345 -1.008603 +v 0.541425 -1.114182 -1.008648 +v 0.543012 -1.113699 -1.008721 +v 0.544474 -1.112913 -1.008820 +v 0.545754 -1.111857 -1.008941 +v 0.546804 -1.110570 -1.009079 +v 0.547584 -1.109101 -1.009229 +v 0.548063 -1.107508 -1.009385 +v 0.548222 -1.105851 -1.009541 +v 0.548057 -1.104194 -1.009691 +v 0.547573 -1.102600 -1.009829 +v 0.546788 -1.101132 -1.009951 +v 0.545734 -1.099844 -1.010050 +v 0.544450 -1.098788 -1.010124 +v 0.542985 -1.098003 -1.010170 +v 0.541398 -1.097520 -1.010186 +v 0.539917 -1.064491 -1.000837 +v 0.532101 -1.065264 -1.000623 +v 0.531685 -1.062479 -0.996992 +v 0.539983 -1.061658 -0.997219 +v 0.539859 -1.068842 -1.004010 +v 0.532825 -1.069538 -1.003818 +v 0.539811 -1.074544 -1.006618 +v 0.533829 -1.075136 -1.006454 +v 0.539776 -1.081378 -1.008559 +v 0.535076 -1.081843 -1.008430 +v 0.539754 -1.089081 -1.009758 +v 0.536516 -1.089401 -1.009670 +v 0.533405 -1.090349 -1.009526 +v 0.524587 -1.067553 -1.000275 +v 0.523709 -1.064909 -0.996622 +v 0.526063 -1.071598 -1.003505 +v 0.528079 -1.076888 -1.006187 +v 0.530558 -1.083219 -1.008221 +v 0.519834 -1.074944 -1.003082 +v 0.517666 -1.071271 -0.999806 +v 0.522782 -1.079733 -1.005828 +v 0.526396 -1.085455 -1.007938 +v 0.530538 -1.091889 -1.009331 +v 0.516361 -1.068855 -0.996124 +v 0.528026 -1.093961 -1.009094 +v 0.511603 -1.076274 -0.999233 +v 0.509924 -1.074166 -0.995517 +v 0.514377 -1.079446 -1.002567 +v 0.518141 -1.083562 -1.005390 +v 0.522749 -1.088463 -1.007594 +v 0.514334 -1.088227 -1.004890 +v 0.509901 -1.084932 -1.001979 +v 0.519759 -1.092129 -1.007201 +v 0.525966 -1.096486 -1.008823 +v 0.506629 -1.082369 -0.998580 +v 0.504645 -1.080637 -0.994823 +v 0.502938 -1.089324 -0.997870 +v 0.500726 -1.088021 -0.994070 +v 0.506579 -1.091191 -1.001340 +v 0.511509 -1.093550 -1.004347 +v 0.517539 -1.096311 -1.006775 +v 0.524437 -1.099367 -1.008529 +v 0.516176 -1.100849 -1.006331 +v 0.509774 -1.099326 -1.003782 +v 0.523498 -1.102492 -1.008224 +v 0.500671 -1.096870 -0.997132 +v 0.498319 -1.096032 -0.993286 +v 0.504538 -1.097983 -1.000676 +v 0.499914 -1.104718 -0.996393 +v 0.497516 -1.104363 -0.992502 +v 0.503857 -1.105046 -1.000011 +v 0.509195 -1.105332 -1.003217 +v 0.515720 -1.105568 -1.005887 +v 0.523184 -1.105743 -1.007918 +v 0.516191 -1.110287 -1.005459 +v 0.509794 -1.111339 -1.002673 +v 0.523509 -1.108994 -1.007623 +v 0.500697 -1.112566 -0.995683 +v 0.498347 -1.112694 -0.991748 +v 0.504562 -1.112108 -0.999372 +v 0.502990 -1.120112 -0.995028 +v 0.500782 -1.120705 -0.991052 +v 0.506626 -1.118900 -0.998782 +v 0.511549 -1.117115 -1.002172 +v 0.517570 -1.114825 -1.005065 +v 0.524458 -1.112120 -1.007352 +v 0.525997 -1.115000 -1.007114 +v 0.519804 -1.119007 -1.004720 +v 0.506705 -1.127067 -0.994453 +v 0.504725 -1.128088 -0.990442 +v 0.509969 -1.125159 -0.998265 +v 0.514392 -1.122437 -1.001732 +v 0.511698 -1.133163 -0.993981 +v 0.510026 -1.134560 -0.989941 +v 0.514463 -1.130645 -0.997840 +v 0.518214 -1.127103 -1.001370 +v 0.522807 -1.122673 -1.004436 +v 0.528065 -1.117525 -1.006919 +v 0.530584 -1.119597 -1.006773 +v 0.526464 -1.125681 -1.004225 +v 0.517779 -1.138165 -0.993630 +v 0.516481 -1.139870 -0.989568 +v 0.519935 -1.135147 -0.997524 +v 0.522868 -1.130932 -1.001101 +v 0.526175 -1.138492 -0.997329 +v 0.524712 -1.141883 -0.993413 +v 0.528175 -1.133777 -1.000936 +v 0.530633 -1.127917 -1.004094 +v 0.533456 -1.121137 -1.006683 +v 0.523842 -1.143816 -0.989337 +v 0.536572 -1.122085 -1.006652 +v 0.532233 -1.144172 -0.993338 +v 0.531826 -1.146247 -0.989259 +v 0.532944 -1.140553 -0.997262 +v 0.533931 -1.135529 -1.000878 +v 0.535156 -1.129293 -1.004049 +v 0.539915 -1.136121 -1.000933 +v 0.539981 -1.141249 -0.997326 +v 0.539857 -1.129758 -1.004092 +v 0.539810 -1.122405 -1.006682 +v 0.540052 -1.144945 -0.993409 +v 0.540126 -1.147067 -0.989334 +v 0.540052 -1.144945 -0.993409 +v 0.547868 -1.144172 -0.993623 +v 0.548424 -1.146247 -0.989561 +v 0.540126 -1.147067 -0.989334 +v 0.547015 -1.140553 -0.997518 +v 0.547868 -1.144172 -0.993623 +v 0.545897 -1.135529 -1.001096 +v 0.544558 -1.129293 -1.004220 +v 0.543047 -1.122085 -1.006770 +v 0.551647 -1.133777 -1.001363 +v 0.553776 -1.138492 -0.997831 +v 0.549076 -1.127917 -1.004430 +v 0.546160 -1.121137 -1.006914 +v 0.555381 -1.141883 -0.993971 +v 0.556400 -1.143816 -0.989930 +v 0.547015 -1.140553 -0.997518 +v 0.553776 -1.138492 -0.997831 +v 0.562302 -1.138165 -0.994441 +v 0.563747 -1.139870 -0.990429 +v 0.560006 -1.135147 -0.998254 +v 0.551647 -1.133777 -1.001363 +v 0.556945 -1.130932 -1.001722 +v 0.553238 -1.125681 -1.004712 +v 0.556945 -1.130932 -1.001722 +v 0.549027 -1.119597 -1.007109 +v 0.553238 -1.125681 -1.004712 +v 0.556884 -1.122673 -1.005056 +v 0.561586 -1.127103 -1.002160 +v 0.551538 -1.117525 -1.007346 +v 0.556884 -1.122673 -1.005056 +v 0.568366 -1.133163 -0.995013 +v 0.570184 -1.134560 -0.991036 +v 0.565463 -1.130645 -0.998769 +v 0.573339 -1.127067 -0.995667 +v 0.575464 -1.128088 -0.991730 +v 0.569938 -1.125159 -0.999357 +v 0.565392 -1.122437 -1.002660 +v 0.559875 -1.119007 -1.005449 +v 0.553598 -1.115000 -1.007617 +v 0.559875 -1.119007 -1.005449 +v 0.562094 -1.114825 -1.005876 +v 0.568217 -1.117115 -1.003203 +v 0.555127 -1.112120 -1.007910 +v 0.562094 -1.114825 -1.005876 +v 0.577030 -1.120112 -0.996376 +v 0.579383 -1.120705 -0.992483 +v 0.573260 -1.118900 -0.999995 +v 0.579298 -1.112566 -0.997114 +v 0.581789 -1.112694 -0.993267 +v 0.575301 -1.112108 -1.000660 +v 0.569953 -1.111339 -1.003768 +v 0.563458 -1.110287 -1.006320 +v 0.556067 -1.108994 -1.008216 +v 0.563458 -1.110287 -1.006320 +v 0.556380 -1.105743 -1.008522 +v 0.563913 -1.105568 -1.006764 +v 0.580055 -1.104718 -0.997853 +v 0.582593 -1.104363 -0.994051 +v 0.575982 -1.105046 -1.001325 +v 0.570532 -1.105332 -1.004333 +v 0.563913 -1.105568 -1.006764 +v 0.575277 -1.097983 -1.001964 +v 0.579272 -1.096870 -0.998563 +v 0.569932 -1.099326 -1.004877 +v 0.563442 -1.100849 -1.007191 +v 0.556056 -1.102492 -1.008816 +v 0.563442 -1.100849 -1.007191 +v 0.581762 -1.096032 -0.994805 +v 0.555105 -1.099367 -1.009088 +v 0.576978 -1.089324 -0.999218 +v 0.579328 -1.088021 -0.995501 +v 0.573214 -1.091191 -1.002553 +v 0.568177 -1.093550 -1.005379 +v 0.562063 -1.096311 -1.007585 +v 0.562063 -1.096311 -1.007585 +v 0.569870 -1.084932 -1.003071 +v 0.573264 -1.082369 -0.999793 +v 0.565334 -1.088227 -1.005819 +v 0.559829 -1.092129 -1.007931 +v 0.553567 -1.096486 -1.009326 +v 0.559829 -1.092129 -1.007931 +v 0.575384 -1.080637 -0.996111 +v 0.551498 -1.093961 -1.009521 +v 0.568271 -1.076274 -1.000265 +v 0.570083 -1.074166 -0.996612 +v 0.565377 -1.079446 -1.003496 +v 0.561512 -1.083562 -1.006180 +v 0.556827 -1.088463 -1.008215 +v 0.556827 -1.088463 -1.008215 +v 0.556859 -1.079733 -1.006449 +v 0.559904 -1.074944 -1.003812 +v 0.553170 -1.085455 -1.008426 +v 0.556859 -1.079733 -1.006449 +v 0.561512 -1.083562 -1.006180 +v 0.548980 -1.091889 -1.009667 +v 0.562190 -1.071271 -1.000616 +v 0.563628 -1.068856 -0.996985 +v 0.555256 -1.067553 -1.000834 +v 0.556267 -1.064909 -0.997215 +v 0.553664 -1.071598 -1.004007 +v 0.551552 -1.076888 -1.006615 +v 0.553664 -1.071598 -1.004007 +v 0.559904 -1.074944 -1.003812 +v 0.549001 -1.083219 -1.008556 +v 0.546108 -1.090349 -1.009757 +v 0.545795 -1.075136 -1.006672 +v 0.546896 -1.069538 -1.004074 +v 0.544478 -1.081843 -1.008601 +v 0.542992 -1.089401 -1.009788 +v 0.547735 -1.065264 -1.000908 +v 0.548283 -1.062479 -0.997294 +v 0.547735 -1.065264 -1.000908 +v 0.555256 -1.067553 -1.000834 +v 0.548283 -1.062479 -0.997294 +vt 0.691151 0.777137 +vt 0.691211 0.776509 +vt 0.691091 0.776509 +vt 0.691329 0.776533 +vt 0.691440 0.776580 +vt 0.691540 0.776649 +vt 0.691626 0.776736 +vt 0.691694 0.776839 +vt 0.691741 0.776953 +vt 0.691766 0.777074 +vt 0.691767 0.777198 +vt 0.691745 0.777319 +vt 0.691700 0.777433 +vt 0.691635 0.777536 +vt 0.691551 0.777623 +vt 0.691452 0.777692 +vt 0.691341 0.777739 +vt 0.691224 0.777763 +vt 0.691104 0.777763 +vt 0.690986 0.777739 +vt 0.690874 0.777692 +vt 0.690774 0.777623 +vt 0.690688 0.777536 +vt 0.690620 0.777433 +vt 0.690573 0.777319 +vt 0.690549 0.777198 +vt 0.690547 0.777074 +vt 0.690570 0.776953 +vt 0.690614 0.776839 +vt 0.690680 0.776736 +vt 0.690764 0.776649 +vt 0.690863 0.776580 +vt 0.690973 0.776533 +vt 0.691033 0.774127 +vt 0.691601 0.774127 +vt 0.691676 0.773932 +vt 0.691073 0.773932 +vt 0.691009 0.774436 +vt 0.691521 0.774436 +vt 0.691003 0.774845 +vt 0.691438 0.774845 +vt 0.691015 0.775341 +vt 0.691357 0.775341 +vt 0.691045 0.775902 +vt 0.691280 0.775902 +vt 0.691512 0.775950 +vt 0.692159 0.774242 +vt 0.692269 0.774053 +vt 0.692023 0.774538 +vt 0.691866 0.774933 +vt 0.691693 0.775409 +vt 0.692498 0.774740 +vt 0.692687 0.774465 +vt 0.692269 0.775104 +vt 0.692010 0.775544 +vt 0.691730 0.776042 +vt 0.692829 0.774291 +vt 0.691927 0.776177 +vt 0.693163 0.774790 +vt 0.693334 0.774636 +vt 0.692926 0.775032 +vt 0.692634 0.775353 +vt 0.692296 0.775739 +vt 0.692944 0.775669 +vt 0.693292 0.775405 +vt 0.692540 0.775988 +vt 0.692095 0.776348 +vt 0.693569 0.775204 +vt 0.693765 0.775075 +vt 0.693890 0.775691 +vt 0.694106 0.775592 +vt 0.693580 0.775843 +vt 0.693190 0.776042 +vt 0.692733 0.776281 +vt 0.692228 0.776550 +vt 0.692868 0.776606 +vt 0.693361 0.776455 +vt 0.692321 0.776774 +vt 0.694113 0.776231 +vt 0.694343 0.776166 +vt 0.693781 0.776329 +vt 0.694230 0.776805 +vt 0.694467 0.776775 +vt 0.693886 0.776845 +vt 0.693450 0.776895 +vt 0.692938 0.776951 +vt 0.692369 0.777011 +vt 0.692941 0.777302 +vt 0.693455 0.777342 +vt 0.692372 0.777254 +vt 0.694236 0.777390 +vt 0.694473 0.777396 +vt 0.693892 0.777372 +vt 0.694131 0.777964 +vt 0.694362 0.778005 +vt 0.693797 0.777888 +vt 0.693375 0.777781 +vt 0.692878 0.777647 +vt 0.692328 0.777491 +vt 0.692240 0.777715 +vt 0.692751 0.777973 +vt 0.693919 0.778504 +vt 0.694137 0.778579 +vt 0.693607 0.778375 +vt 0.693212 0.778195 +vt 0.693608 0.778991 +vt 0.693807 0.779095 +vt 0.693327 0.778813 +vt 0.692975 0.778567 +vt 0.692564 0.778265 +vt 0.692112 0.777917 +vt 0.691947 0.778088 +vt 0.692325 0.778514 +vt 0.693211 0.779404 +vt 0.693385 0.779534 +vt 0.692970 0.779185 +vt 0.692670 0.778884 +vt 0.692547 0.779477 +vt 0.692742 0.779729 +vt 0.692311 0.779133 +vt 0.692043 0.778709 +vt 0.691753 0.778223 +vt 0.692887 0.779879 +vt 0.691536 0.778315 +vt 0.692219 0.779953 +vt 0.692333 0.780117 +vt 0.692077 0.779679 +vt 0.691911 0.779304 +vt 0.691729 0.778844 +vt 0.691486 0.779392 +vt 0.691576 0.779782 +vt 0.691394 0.778912 +vt 0.691306 0.778363 +vt 0.691663 0.780067 +vt 0.691742 0.780238 +vt 0.949885 0.152438 +vt 0.949465 0.152324 +vt 0.949233 0.152501 +vt 0.949679 0.152621 +vt 0.691065 0.779782 +vt 0.691095 0.780067 +vt 0.691051 0.779392 +vt 0.691053 0.778912 +vt 0.691071 0.778363 +vt 0.690623 0.779304 +vt 0.690562 0.779679 +vt 0.690717 0.778844 +vt 0.690839 0.778315 +vt 0.949069 0.152101 +vt 0.948812 0.152263 +vt 0.949706 0.152038 +vt 0.949350 0.151837 +vt 0.948713 0.151776 +vt 0.948434 0.151919 +vt 0.949029 0.151545 +vt 0.949645 0.151482 +vt 0.949372 0.151234 +vt 0.690400 0.778709 +vt 0.690220 0.779133 +vt 0.690621 0.778223 +vt 0.949727 0.150855 +vt 0.949545 0.150606 +vt 0.949140 0.150918 +vt 0.690424 0.778088 +vt 0.690113 0.778514 +vt 0.948410 0.151363 +vt 0.948113 0.151480 +vt 0.948757 0.151173 +vt 0.948172 0.150877 +vt 0.947860 0.150964 +vt 0.948542 0.150735 +vt 0.948958 0.150545 +vt 0.949402 0.150314 +vt 0.690255 0.777917 +vt 0.689869 0.778265 +vt 0.949303 0.149989 +vt 0.948832 0.150131 +vt 0.690122 0.777715 +vt 0.689676 0.777973 +vt 0.948008 0.150336 +vt 0.947686 0.150390 +vt 0.948395 0.150249 +vt 0.947924 0.149762 +vt 0.947597 0.149780 +vt 0.948320 0.149732 +vt 0.948768 0.149692 +vt 0.949253 0.149643 +vt 0.690030 0.777491 +vt 0.689542 0.777647 +vt 0.689982 0.777254 +vt 0.689472 0.777302 +vt 0.947924 0.149176 +vt 0.947597 0.149158 +vt 0.948320 0.149205 +vt 0.948768 0.149244 +vt 0.949253 0.149291 +vt 0.948395 0.148688 +vt 0.948008 0.148602 +vt 0.948832 0.148804 +vt 0.949303 0.148946 +vt 0.689979 0.777011 +vt 0.689468 0.776951 +vt 0.947686 0.148549 +vt 0.690023 0.776774 +vt 0.948172 0.148060 +vt 0.947860 0.147974 +vt 0.948542 0.148201 +vt 0.948958 0.148390 +vt 0.949402 0.148620 +vt 0.689531 0.776606 +vt 0.948757 0.147762 +vt 0.948410 0.147573 +vt 0.949140 0.148017 +vt 0.949545 0.148327 +vt 0.690110 0.776550 +vt 0.689659 0.776281 +vt 0.948113 0.147457 +vt 0.690239 0.776348 +vt 0.948713 0.147158 +vt 0.948434 0.147016 +vt 0.949029 0.147389 +vt 0.949372 0.147699 +vt 0.949727 0.148078 +vt 0.689845 0.775988 +vt 0.949645 0.147450 +vt 0.949350 0.147096 +vt 0.690084 0.775739 +vt 0.689818 0.775353 +vt 0.689514 0.775669 +vt 0.690404 0.776177 +vt 0.949069 0.146832 +vt 0.948812 0.146670 +vt 0.949465 0.146607 +vt 0.949233 0.146431 +vt 0.949706 0.146893 +vt 0.690178 0.775104 +vt 0.690038 0.774740 +vt 0.689616 0.775032 +vt 0.690367 0.775544 +vt 0.690598 0.776042 +vt 0.690578 0.774933 +vt 0.690509 0.774538 +vt 0.690681 0.775409 +vt 0.690814 0.775950 +vt 0.949885 0.146492 +vt 0.949679 0.146309 +vt 0.690476 0.774242 +vt 0.689954 0.774465 +vt 0.690483 0.774053 +vn -0.0181 -0.0919 -0.9956 +vn -0.0373 0.0032 -0.9993 +vn -0.0182 0.0051 -0.9998 +vn -0.0556 -0.0023 -0.9985 +vn -0.0725 -0.0113 -0.9973 +vn -0.0873 -0.0233 -0.9959 +vn -0.0994 -0.0379 -0.9943 +vn -0.1084 -0.0546 -0.9926 +vn -0.1139 -0.0727 -0.9908 +vn -0.1157 -0.0915 -0.9891 +vn -0.1138 -0.1103 -0.9874 +vn -0.1082 -0.1285 -0.9858 +vn -0.0992 -0.1452 -0.9844 +vn -0.0870 -0.1597 -0.9833 +vn -0.0723 -0.1718 -0.9825 +vn -0.0553 -0.1807 -0.9820 +vn -0.0370 -0.1862 -0.9818 +vn -0.0179 -0.1881 -0.9820 +vn 0.0012 -0.1862 -0.9825 +vn 0.0195 -0.1807 -0.9833 +vn 0.0364 -0.1717 -0.9845 +vn 0.0512 -0.1598 -0.9858 +vn 0.0633 -0.1452 -0.9874 +vn 0.0723 -0.1284 -0.9891 +vn 0.0778 -0.1103 -0.9908 +vn 0.0796 -0.0916 -0.9926 +vn 0.0777 -0.0727 -0.9943 +vn 0.0722 -0.0546 -0.9959 +vn 0.0631 -0.0379 -0.9973 +vn 0.0509 -0.0233 -0.9984 +vn 0.0361 -0.0112 -0.9993 +vn 0.0192 -0.0023 -0.9998 +vn 0.0009 0.0032 -1.0000 +vn -0.0130 0.6990 -0.7150 +vn -0.1627 0.6843 -0.7108 +vn -0.1764 0.7712 -0.6117 +vn -0.0112 0.7874 -0.6164 +vn -0.0157 0.5096 -0.8603 +vn -0.1310 0.4983 -0.8571 +vn -0.0171 0.3496 -0.9367 +vn -0.1024 0.3413 -0.9344 +vn -0.0178 0.2176 -0.9759 +vn -0.0780 0.2117 -0.9742 +vn -0.0181 0.1052 -0.9943 +vn -0.0567 0.1015 -0.9932 +vn -0.0938 0.0903 -0.9915 +vn -0.3065 0.6408 -0.7039 +vn -0.3349 0.7231 -0.6041 +vn -0.2417 0.4649 -0.8517 +vn -0.1845 0.3166 -0.9304 +vn -0.1359 0.1943 -0.9715 +vn -0.3436 0.4107 -0.8445 +vn -0.4387 0.5703 -0.6945 +vn -0.2600 0.2766 -0.9251 +vn -0.1892 0.1661 -0.9678 +vn -0.1279 0.0723 -0.9891 +vn -0.4807 0.6453 -0.5937 +vn -0.1578 0.0480 -0.9863 +vn -0.5541 0.4757 -0.6831 +vn -0.6080 0.5408 -0.5812 +vn -0.4327 0.3380 -0.8358 +vn -0.3261 0.2228 -0.9187 +vn -0.2359 0.1281 -0.9633 +vn -0.3802 0.1572 -0.9114 +vn -0.5057 0.2495 -0.8259 +vn -0.2741 0.0819 -0.9582 +vn -0.1823 0.0183 -0.9831 +vn -0.6486 0.3607 -0.6702 +vn -0.7122 0.4139 -0.5670 +vn -0.7186 0.2298 -0.6564 +vn -0.7893 0.2695 -0.5517 +vn -0.5598 0.1486 -0.8152 +vn -0.4204 0.0825 -0.9036 +vn -0.3025 0.0292 -0.9527 +vn -0.2005 -0.0154 -0.9796 +vn -0.3199 -0.0280 -0.9470 +vn -0.4450 0.0015 -0.8955 +vn -0.2117 -0.0520 -0.9760 +vn -0.7614 0.0880 -0.6422 +vn -0.8366 0.1130 -0.5361 +vn -0.5930 0.0394 -0.8043 +vn -0.7757 -0.0593 -0.6283 +vn -0.8523 -0.0495 -0.5207 +vn -0.6040 -0.0743 -0.7935 +vn -0.4532 -0.0827 -0.8875 +vn -0.3257 -0.0875 -0.9414 +vn -0.2154 -0.0901 -0.9724 +vn -0.3197 -0.1469 -0.9361 +vn -0.4447 -0.1669 -0.8800 +vn -0.2116 -0.1282 -0.9689 +vn -0.7609 -0.2066 -0.6150 +vn -0.8360 -0.2121 -0.5061 +vn -0.5926 -0.1879 -0.7833 +vn -0.7176 -0.3485 -0.6030 +vn -0.7882 -0.3685 -0.4928 +vn -0.5590 -0.2972 -0.7740 +vn -0.4198 -0.2480 -0.8731 +vn -0.3021 -0.2041 -0.9312 +vn -0.2003 -0.1648 -0.9658 +vn -0.1820 -0.1986 -0.9630 +vn -0.2736 -0.2569 -0.9269 +vn -0.6472 -0.4794 -0.5927 +vn -0.7106 -0.5131 -0.4814 +vn -0.5046 -0.3981 -0.7661 +vn -0.3794 -0.3227 -0.8671 +vn -0.5523 -0.5945 -0.5843 +vn -0.6060 -0.6401 -0.4722 +vn -0.4313 -0.4867 -0.7596 +vn -0.3251 -0.3883 -0.8623 +vn -0.2352 -0.3031 -0.9235 +vn -0.1573 -0.2282 -0.9608 +vn -0.1273 -0.2526 -0.9592 +vn -0.1883 -0.3411 -0.9210 +vn -0.4365 -0.6893 -0.5782 +vn -0.4783 -0.7447 -0.4654 +vn -0.3420 -0.5596 -0.7549 +vn -0.2588 -0.4422 -0.8588 +vn -0.2399 -0.6138 -0.7521 +vn -0.3041 -0.7599 -0.5745 +vn -0.1831 -0.4822 -0.8567 +vn -0.1349 -0.3693 -0.9194 +vn -0.0932 -0.2706 -0.9582 +vn -0.3324 -0.8226 -0.4613 +vn -0.0561 -0.2818 -0.9578 +vn -0.1602 -0.8034 -0.5735 +vn -0.1736 -0.8707 -0.4602 +vn -0.1290 -0.6472 -0.7513 +vn -0.1010 -0.5069 -0.8560 +vn -0.0770 -0.3867 -0.9190 +vn -0.0156 -0.5153 -0.8569 +vn -0.0137 -0.6585 -0.7524 +vn -0.0167 -0.3926 -0.9195 +vn -0.0174 -0.2855 -0.9582 +vn -0.0105 -0.8181 -0.5749 +vn -0.0084 -0.8869 -0.4618 +vn -0.0105 -0.8181 -0.5750 +vn 0.1393 -0.8034 -0.5789 +vn 0.1567 -0.8707 -0.4662 +vn -0.0084 -0.8870 -0.4618 +vn 0.1016 -0.6472 -0.7555 +vn 0.0698 -0.5069 -0.8592 +vn 0.0435 -0.3867 -0.9212 +vn 0.0211 -0.2818 -0.9592 +vn 0.1518 -0.4822 -0.8628 +vn 0.2123 -0.6138 -0.7604 +vn 0.1014 -0.3693 -0.9237 +vn 0.0582 -0.2707 -0.9609 +vn 0.2830 -0.7599 -0.5852 +vn 0.3153 -0.8226 -0.4731 +vn 0.4152 -0.6893 -0.5937 +vn 0.4611 -0.7447 -0.4825 +vn 0.3143 -0.5596 -0.7669 +vn 0.2273 -0.4422 -0.8676 +vn 0.1547 -0.3411 -0.9272 +vn 0.2273 -0.4422 -0.8677 +vn 0.0924 -0.2526 -0.9632 +vn 0.2014 -0.3031 -0.9314 +vn 0.2935 -0.3883 -0.8736 +vn 0.1223 -0.2282 -0.9659 +vn 0.2013 -0.3031 -0.9315 +vn 0.5307 -0.5945 -0.6041 +vn 0.5884 -0.6401 -0.4939 +vn 0.4034 -0.4867 -0.7748 +vn 0.6252 -0.4794 -0.6159 +vn 0.6926 -0.5131 -0.5070 +vn 0.4764 -0.3981 -0.7839 +vn 0.3476 -0.3227 -0.8804 +vn 0.2396 -0.2569 -0.9363 +vn 0.1468 -0.1986 -0.9690 +vn 0.2680 -0.2041 -0.9416 +vn 0.3878 -0.2480 -0.8878 +vn 0.1650 -0.1649 -0.9724 +vn 0.6951 -0.3485 -0.6288 +vn 0.7697 -0.3685 -0.5213 +vn 0.5305 -0.2972 -0.7939 +vn 0.7380 -0.2066 -0.6423 +vn 0.8170 -0.2121 -0.5362 +vn 0.5637 -0.1879 -0.8044 +vn 0.4124 -0.1669 -0.8956 +vn 0.2854 -0.1469 -0.9471 +vn 0.1761 -0.1282 -0.9760 +vn 0.1799 -0.0901 -0.9796 +vn 0.2912 -0.0875 -0.9527 +vn 0.7523 -0.0593 -0.6561 +vn 0.8328 -0.0495 -0.5514 +vn 0.5747 -0.0743 -0.8150 +vn 0.4206 -0.0827 -0.9035 +vn 0.2912 -0.0875 -0.9526 +vn 0.5633 0.0393 -0.8253 +vn 0.7375 0.0880 -0.6695 +vn 0.4121 0.0015 -0.9111 +vn 0.2852 -0.0280 -0.9581 +vn 0.1760 -0.0521 -0.9830 +vn 0.8165 0.1130 -0.5662 +vn 0.1647 -0.0154 -0.9862 +vn 0.6941 0.2298 -0.6822 +vn 0.7687 0.2695 -0.5801 +vn 0.5297 0.1486 -0.8350 +vn 0.3872 0.0825 -0.9183 +vn 0.2676 0.0292 -0.9631 +vn 0.4753 0.2495 -0.8437 +vn 0.6238 0.3607 -0.6934 +vn 0.3468 0.1572 -0.9247 +vn 0.2391 0.0819 -0.9675 +vn 0.1464 0.0184 -0.9891 +vn 0.2390 0.0819 -0.9676 +vn 0.6910 0.4139 -0.5926 +vn 0.1218 0.0480 -0.9914 +vn 0.5289 0.4757 -0.7028 +vn 0.5865 0.5409 -0.6029 +vn 0.4020 0.3380 -0.8510 +vn 0.2924 0.2228 -0.9300 +vn 0.2006 0.1281 -0.9713 +vn 0.2261 0.2766 -0.9340 +vn 0.3126 0.4108 -0.8565 +vn 0.1538 0.1661 -0.9740 +vn 0.0918 0.0723 -0.9932 +vn 0.4131 0.5703 -0.7100 +vn 0.4588 0.6453 -0.6108 +vn 0.2806 0.6408 -0.7146 +vn 0.3127 0.7232 -0.6158 +vn 0.2105 0.4649 -0.8600 +vn 0.1505 0.3166 -0.9365 +vn 0.1004 0.1943 -0.9758 +vn 0.0576 0.0903 -0.9942 +vn 0.0683 0.3413 -0.9375 +vn 0.0997 0.4983 -0.8613 +vn 0.0425 0.2117 -0.9764 +vn 0.0205 0.1015 -0.9946 +vn 0.1368 0.6843 -0.7162 +vn 0.1540 0.7712 -0.6177 +vn 0.1367 0.6843 -0.7163 +usemtl Scene_-_Root +s 1 +f 41339/41339/30552 41340/41340/30553 41341/41341/30554 +f 41339/41339/30552 41342/41342/30555 41340/41340/30553 +f 41339/41339/30552 41343/41343/30556 41342/41342/30555 +f 41339/41339/30552 41344/41344/30557 41343/41343/30556 +f 41339/41339/30552 41345/41345/30558 41344/41344/30557 +f 41339/41339/30552 41346/41346/30559 41345/41345/30558 +f 41339/41339/30552 41347/41347/30560 41346/41346/30559 +f 41339/41339/30552 41348/41348/30561 41347/41347/30560 +f 41339/41339/30552 41349/41349/30562 41348/41348/30561 +f 41339/41339/30552 41350/41350/30563 41349/41349/30562 +f 41339/41339/30552 41351/41351/30564 41350/41350/30563 +f 41339/41339/30552 41352/41352/30565 41351/41351/30564 +f 41339/41339/30552 41353/41353/30566 41352/41352/30565 +f 41339/41339/30552 41354/41354/30567 41353/41353/30566 +f 41339/41339/30552 41355/41355/30568 41354/41354/30567 +f 41339/41339/30552 41356/41356/30569 41355/41355/30568 +f 41339/41339/30552 41357/41357/30570 41356/41356/30569 +f 41339/41339/30552 41358/41358/30571 41357/41357/30570 +f 41339/41339/30552 41359/41359/30572 41358/41358/30571 +f 41339/41339/30552 41360/41360/30573 41359/41359/30572 +f 41339/41339/30552 41361/41361/30574 41360/41360/30573 +f 41339/41339/30552 41362/41362/30575 41361/41361/30574 +f 41339/41339/30552 41363/41363/30576 41362/41362/30575 +f 41339/41339/30552 41364/41364/30577 41363/41363/30576 +f 41339/41339/30552 41365/41365/30578 41364/41364/30577 +f 41339/41339/30552 41366/41366/30579 41365/41365/30578 +f 41339/41339/30552 41367/41367/30580 41366/41366/30579 +f 41339/41339/30552 41368/41368/30581 41367/41367/30580 +f 41339/41339/30552 41369/41369/30582 41368/41368/30581 +f 41339/41339/30552 41370/41370/30583 41369/41369/30582 +f 41339/41339/30552 41371/41371/30584 41370/41370/30583 +f 41339/41339/30552 41341/41341/30554 41371/41371/30584 +f 41372/41372/30585 41373/41373/30586 41374/41374/30587 +f 41372/41372/30585 41374/41374/30587 41375/41375/30588 +f 41376/41376/30589 41377/41377/30590 41373/41373/30586 +f 41376/41376/30589 41373/41373/30586 41372/41372/30585 +f 41378/41378/30591 41379/41379/30592 41377/41377/30590 +f 41378/41378/30591 41377/41377/30590 41376/41376/30589 +f 41380/41380/30593 41381/41381/30594 41379/41379/30592 +f 41380/41380/30593 41379/41379/30592 41378/41378/30591 +f 41382/41382/30595 41383/41383/30596 41381/41381/30594 +f 41382/41382/30595 41381/41381/30594 41380/41380/30593 +f 41341/41341/30554 41340/41340/30553 41383/41383/30596 +f 41341/41341/30554 41383/41383/30596 41382/41382/30595 +f 41340/41340/30553 41342/41342/30555 41384/41384/30597 +f 41340/41340/30553 41384/41384/30597 41383/41383/30596 +f 41373/41373/30586 41385/41385/30598 41386/41386/30599 +f 41373/41373/30586 41386/41386/30599 41374/41374/30587 +f 41377/41377/30590 41387/41387/30600 41385/41385/30598 +f 41377/41377/30590 41385/41385/30598 41373/41373/30586 +f 41379/41379/30592 41388/41388/30601 41387/41387/30600 +f 41379/41379/30592 41387/41387/30600 41377/41377/30590 +f 41381/41381/30594 41389/41389/30602 41388/41388/30601 +f 41381/41381/30594 41388/41388/30601 41379/41379/30592 +f 41383/41383/30596 41384/41384/30597 41389/41389/30602 +f 41383/41383/30596 41389/41389/30602 41381/41381/30594 +f 41387/41387/30600 41390/41390/30603 41391/41391/30604 +f 41387/41387/30600 41391/41391/30604 41385/41385/30598 +f 41388/41388/30601 41392/41392/30605 41390/41390/30603 +f 41388/41388/30601 41390/41390/30603 41387/41387/30600 +f 41389/41389/30602 41393/41393/30606 41392/41392/30605 +f 41389/41389/30602 41392/41392/30605 41388/41388/30601 +f 41384/41384/30597 41394/41394/30607 41393/41393/30606 +f 41384/41384/30597 41393/41393/30606 41389/41389/30602 +f 41342/41342/30555 41343/41343/30556 41394/41394/30607 +f 41342/41342/30555 41394/41394/30607 41384/41384/30597 +f 41385/41385/30598 41391/41391/30604 41395/41395/30608 +f 41385/41385/30598 41395/41395/30608 41386/41386/30599 +f 41343/41343/30556 41344/41344/30557 41396/41396/30609 +f 41343/41343/30556 41396/41396/30609 41394/41394/30607 +f 41391/41391/30604 41397/41397/30610 41398/41398/30611 +f 41391/41391/30604 41398/41398/30611 41395/41395/30608 +f 41390/41390/30603 41399/41399/30612 41397/41397/30610 +f 41390/41390/30603 41397/41397/30610 41391/41391/30604 +f 41392/41392/30605 41400/41400/30613 41399/41399/30612 +f 41392/41392/30605 41399/41399/30612 41390/41390/30603 +f 41393/41393/30606 41401/41401/30614 41400/41400/30613 +f 41393/41393/30606 41400/41400/30613 41392/41392/30605 +f 41394/41394/30607 41396/41396/30609 41401/41401/30614 +f 41394/41394/30607 41401/41401/30614 41393/41393/30606 +f 41400/41400/30613 41402/41402/30615 41403/41403/30616 +f 41400/41400/30613 41403/41403/30616 41399/41399/30612 +f 41401/41401/30614 41404/41404/30617 41402/41402/30615 +f 41401/41401/30614 41402/41402/30615 41400/41400/30613 +f 41396/41396/30609 41405/41405/30618 41404/41404/30617 +f 41396/41396/30609 41404/41404/30617 41401/41401/30614 +f 41344/41344/30557 41345/41345/30558 41405/41405/30618 +f 41344/41344/30557 41405/41405/30618 41396/41396/30609 +f 41397/41397/30610 41406/41406/30619 41407/41407/30620 +f 41397/41397/30610 41407/41407/30620 41398/41398/30611 +f 41399/41399/30612 41403/41403/30616 41406/41406/30619 +f 41399/41399/30612 41406/41406/30619 41397/41397/30610 +f 41406/41406/30619 41408/41408/30621 41409/41409/30622 +f 41406/41406/30619 41409/41409/30622 41407/41407/30620 +f 41403/41403/30616 41410/41410/30623 41408/41408/30621 +f 41403/41403/30616 41408/41408/30621 41406/41406/30619 +f 41402/41402/30615 41411/41411/30624 41410/41410/30623 +f 41402/41402/30615 41410/41410/30623 41403/41403/30616 +f 41404/41404/30617 41412/41412/30625 41411/41411/30624 +f 41404/41404/30617 41411/41411/30624 41402/41402/30615 +f 41405/41405/30618 41413/41413/30626 41412/41412/30625 +f 41405/41405/30618 41412/41412/30625 41404/41404/30617 +f 41345/41345/30558 41346/41346/30559 41413/41413/30626 +f 41345/41345/30558 41413/41413/30626 41405/41405/30618 +f 41412/41412/30625 41414/41414/30627 41415/41415/30628 +f 41412/41412/30625 41415/41415/30628 41411/41411/30624 +f 41413/41413/30626 41416/41416/30629 41414/41414/30627 +f 41413/41413/30626 41414/41414/30627 41412/41412/30625 +f 41346/41346/30559 41347/41347/30560 41416/41416/30629 +f 41346/41346/30559 41416/41416/30629 41413/41413/30626 +f 41408/41408/30621 41417/41417/30630 41418/41418/30631 +f 41408/41408/30621 41418/41418/30631 41409/41409/30622 +f 41410/41410/30623 41419/41419/30632 41417/41417/30630 +f 41410/41410/30623 41417/41417/30630 41408/41408/30621 +f 41411/41411/30624 41415/41415/30628 41419/41419/30632 +f 41411/41411/30624 41419/41419/30632 41410/41410/30623 +f 41417/41417/30630 41420/41420/30633 41421/41421/30634 +f 41417/41417/30630 41421/41421/30634 41418/41418/30631 +f 41419/41419/30632 41422/41422/30635 41420/41420/30633 +f 41419/41419/30632 41420/41420/30633 41417/41417/30630 +f 41415/41415/30628 41423/41423/30636 41422/41422/30635 +f 41415/41415/30628 41422/41422/30635 41419/41419/30632 +f 41414/41414/30627 41424/41424/30637 41423/41423/30636 +f 41414/41414/30627 41423/41423/30636 41415/41415/30628 +f 41416/41416/30629 41425/41425/30638 41424/41424/30637 +f 41416/41416/30629 41424/41424/30637 41414/41414/30627 +f 41347/41347/30560 41348/41348/30561 41425/41425/30638 +f 41347/41347/30560 41425/41425/30638 41416/41416/30629 +f 41424/41424/30637 41426/41426/30639 41427/41427/30640 +f 41424/41424/30637 41427/41427/30640 41423/41423/30636 +f 41425/41425/30638 41428/41428/30641 41426/41426/30639 +f 41425/41425/30638 41426/41426/30639 41424/41424/30637 +f 41348/41348/30561 41349/41349/30562 41428/41428/30641 +f 41348/41348/30561 41428/41428/30641 41425/41425/30638 +f 41420/41420/30633 41429/41429/30642 41430/41430/30643 +f 41420/41420/30633 41430/41430/30643 41421/41421/30634 +f 41422/41422/30635 41431/41431/30644 41429/41429/30642 +f 41422/41422/30635 41429/41429/30642 41420/41420/30633 +f 41423/41423/30636 41427/41427/30640 41431/41431/30644 +f 41423/41423/30636 41431/41431/30644 41422/41422/30635 +f 41429/41429/30642 41432/41432/30645 41433/41433/30646 +f 41429/41429/30642 41433/41433/30646 41430/41430/30643 +f 41431/41431/30644 41434/41434/30647 41432/41432/30645 +f 41431/41431/30644 41432/41432/30645 41429/41429/30642 +f 41427/41427/30640 41435/41435/30648 41434/41434/30647 +f 41427/41427/30640 41434/41434/30647 41431/41431/30644 +f 41426/41426/30639 41436/41436/30649 41435/41435/30648 +f 41426/41426/30639 41435/41435/30648 41427/41427/30640 +f 41428/41428/30641 41437/41437/30650 41436/41436/30649 +f 41428/41428/30641 41436/41436/30649 41426/41426/30639 +f 41349/41349/30562 41350/41350/30563 41437/41437/30650 +f 41349/41349/30562 41437/41437/30650 41428/41428/30641 +f 41437/41437/30650 41438/41438/30651 41439/41439/30652 +f 41437/41437/30650 41439/41439/30652 41436/41436/30649 +f 41350/41350/30563 41351/41351/30564 41438/41438/30651 +f 41350/41350/30563 41438/41438/30651 41437/41437/30650 +f 41432/41432/30645 41440/41440/30653 41441/41441/30654 +f 41432/41432/30645 41441/41441/30654 41433/41433/30646 +f 41434/41434/30647 41442/41442/30655 41440/41440/30653 +f 41434/41434/30647 41440/41440/30653 41432/41432/30645 +f 41435/41435/30648 41443/41443/30656 41442/41442/30655 +f 41435/41435/30648 41442/41442/30655 41434/41434/30647 +f 41436/41436/30649 41439/41439/30652 41443/41443/30656 +f 41436/41436/30649 41443/41443/30656 41435/41435/30648 +f 41440/41440/30653 41444/41444/30657 41445/41445/30658 +f 41440/41440/30653 41445/41445/30658 41441/41441/30654 +f 41442/41442/30655 41446/41446/30659 41444/41444/30657 +f 41442/41442/30655 41444/41444/30657 41440/41440/30653 +f 41443/41443/30656 41447/41447/30660 41446/41446/30659 +f 41443/41443/30656 41446/41446/30659 41442/41442/30655 +f 41439/41439/30652 41448/41448/30661 41447/41447/30660 +f 41439/41439/30652 41447/41447/30660 41443/41443/30656 +f 41438/41438/30651 41449/41449/30662 41448/41448/30661 +f 41438/41438/30651 41448/41448/30661 41439/41439/30652 +f 41351/41351/30564 41352/41352/30565 41449/41449/30662 +f 41351/41351/30564 41449/41449/30662 41438/41438/30651 +f 41449/41449/30662 41450/41450/30663 41451/41451/30664 +f 41449/41449/30662 41451/41451/30664 41448/41448/30661 +f 41352/41352/30565 41353/41353/30566 41450/41450/30663 +f 41352/41352/30565 41450/41450/30663 41449/41449/30662 +f 41444/41444/30657 41452/41452/30665 41453/41453/30666 +f 41444/41444/30657 41453/41453/30666 41445/41445/30658 +f 41446/41446/30659 41454/41454/30667 41452/41452/30665 +f 41446/41446/30659 41452/41452/30665 41444/41444/30657 +f 41447/41447/30660 41455/41455/30668 41454/41454/30667 +f 41447/41447/30660 41454/41454/30667 41446/41446/30659 +f 41448/41448/30661 41451/41451/30664 41455/41455/30668 +f 41448/41448/30661 41455/41455/30668 41447/41447/30660 +f 41454/41454/30667 41456/41456/30669 41457/41457/30670 +f 41454/41454/30667 41457/41457/30670 41452/41452/30665 +f 41455/41455/30668 41458/41458/30671 41456/41456/30669 +f 41455/41455/30668 41456/41456/30669 41454/41454/30667 +f 41451/41451/30664 41459/41459/30672 41458/41458/30671 +f 41451/41451/30664 41458/41458/30671 41455/41455/30668 +f 41450/41450/30663 41460/41460/30673 41459/41459/30672 +f 41450/41450/30663 41459/41459/30672 41451/41451/30664 +f 41353/41353/30566 41354/41354/30567 41460/41460/30673 +f 41353/41353/30566 41460/41460/30673 41450/41450/30663 +f 41452/41452/30665 41457/41457/30670 41461/41461/30674 +f 41452/41452/30665 41461/41461/30674 41453/41453/30666 +f 41354/41354/30567 41355/41355/30568 41462/41462/30675 +f 41354/41354/30567 41462/41462/30675 41460/41460/30673 +f 41457/41457/30670 41463/41463/30676 41464/41464/30677 +f 41457/41457/30670 41464/41464/30677 41461/41461/30674 +f 41456/41456/30669 41465/41465/30678 41463/41463/30676 +f 41456/41456/30669 41463/41463/30676 41457/41457/30670 +f 41458/41458/30671 41466/41466/30679 41465/41465/30678 +f 41458/41458/30671 41465/41465/30678 41456/41456/30669 +f 41459/41459/30672 41467/41467/30680 41466/41466/30679 +f 41459/41459/30672 41466/41466/30679 41458/41458/30671 +f 41460/41460/30673 41462/41462/30675 41467/41467/30680 +f 41460/41460/30673 41467/41467/30680 41459/41459/30672 +f 41466/41466/30679 41468/41468/30681 41469/41469/30682 +f 41466/41466/30679 41469/41469/30682 41465/41465/30678 +f 41467/41467/30680 41470/41470/30683 41468/41468/30681 +f 41467/41467/30680 41468/41468/30681 41466/41466/30679 +f 41462/41462/30675 41471/41471/30684 41470/41470/30683 +f 41462/41462/30675 41470/41470/30683 41467/41467/30680 +f 41355/41355/30568 41356/41356/30569 41471/41471/30684 +f 41355/41355/30568 41471/41471/30684 41462/41462/30675 +f 41463/41463/30676 41472/41472/30685 41473/41473/30686 +f 41463/41463/30676 41473/41473/30686 41464/41464/30677 +f 41465/41465/30678 41469/41469/30682 41472/41472/30685 +f 41465/41465/30678 41472/41472/30685 41463/41463/30676 +f 41474/41474/30687 41475/41475/30688 41476/41476/30689 +f 41474/41474/30687 41476/41476/30689 41477/41477/30690 +f 41469/41469/30682 41478/41478/30691 41479/41479/30688 +f 41469/41469/30682 41479/41479/30688 41472/41472/30685 +f 41468/41468/30681 41480/41480/30692 41478/41478/30691 +f 41468/41468/30681 41478/41478/30691 41469/41469/30682 +f 41470/41470/30683 41481/41481/30693 41480/41480/30692 +f 41470/41470/30683 41480/41480/30692 41468/41468/30681 +f 41471/41471/30684 41482/41482/30694 41481/41481/30693 +f 41471/41471/30684 41481/41481/30693 41470/41470/30683 +f 41356/41356/30569 41357/41357/30570 41482/41482/30694 +f 41356/41356/30569 41482/41482/30694 41471/41471/30684 +f 41480/41480/30692 41483/41483/30695 41484/41484/30696 +f 41480/41480/30692 41484/41484/30696 41478/41478/30691 +f 41481/41481/30693 41485/41485/30697 41483/41483/30695 +f 41481/41481/30693 41483/41483/30695 41480/41480/30692 +f 41482/41482/30694 41486/41486/30698 41485/41485/30697 +f 41482/41482/30694 41485/41485/30697 41481/41481/30693 +f 41357/41357/30570 41358/41358/30571 41486/41486/30698 +f 41357/41357/30570 41486/41486/30698 41482/41482/30694 +f 41475/41475/30688 41487/41487/30699 41488/41488/30700 +f 41475/41475/30688 41488/41488/30700 41476/41476/30689 +f 41489/41489/30691 41490/41490/30696 41487/41487/30699 +f 41489/41489/30691 41487/41487/30699 41475/41475/30688 +f 41487/41487/30699 41491/41491/30701 41492/41492/30702 +f 41487/41487/30699 41492/41492/30702 41488/41488/30700 +f 41490/41490/30696 41493/41493/30703 41491/41491/30701 +f 41490/41490/30696 41491/41491/30701 41487/41487/30699 +f 41494/41494/30695 41495/41495/30704 41493/41493/30703 +f 41494/41494/30695 41493/41493/30703 41490/41490/30696 +f 41485/41485/30697 41496/41496/30705 41497/41497/30706 +f 41485/41485/30697 41497/41497/30706 41483/41483/30695 +f 41486/41486/30698 41498/41498/30707 41496/41496/30705 +f 41486/41486/30698 41496/41496/30705 41485/41485/30697 +f 41358/41358/30571 41359/41359/30572 41498/41498/30707 +f 41358/41358/30571 41498/41498/30707 41486/41486/30698 +f 41499/41499/30705 41500/41500/30708 41501/41501/30709 +f 41499/41499/30705 41501/41501/30709 41495/41495/30704 +f 41498/41498/30707 41502/41502/30710 41503/41503/30711 +f 41498/41498/30707 41503/41503/30711 41496/41496/30705 +f 41359/41359/30572 41360/41360/30573 41502/41502/30710 +f 41359/41359/30572 41502/41502/30710 41498/41498/30707 +f 41491/41491/30701 41504/41504/30712 41505/41505/30713 +f 41491/41491/30701 41505/41505/30713 41492/41492/30702 +f 41493/41493/30703 41506/41506/30714 41504/41504/30712 +f 41493/41493/30703 41504/41504/30712 41491/41491/30701 +f 41495/41495/30704 41501/41501/30709 41506/41506/30714 +f 41495/41495/30704 41506/41506/30714 41493/41493/30703 +f 41504/41504/30712 41507/41507/30715 41508/41508/30716 +f 41504/41504/30712 41508/41508/30716 41505/41505/30713 +f 41506/41506/30714 41509/41509/30717 41507/41507/30715 +f 41506/41506/30714 41507/41507/30715 41504/41504/30712 +f 41501/41501/30709 41510/41510/30718 41509/41509/30717 +f 41501/41501/30709 41509/41509/30717 41506/41506/30714 +f 41500/41500/30708 41511/41511/30719 41510/41510/30718 +f 41500/41500/30708 41510/41510/30718 41501/41501/30709 +f 41502/41502/30710 41512/41512/30720 41513/41513/30719 +f 41502/41502/30710 41513/41513/30719 41503/41503/30711 +f 41360/41360/30573 41361/41361/30574 41512/41512/30720 +f 41360/41360/30573 41512/41512/30720 41502/41502/30710 +f 41511/41511/30719 41514/41514/30721 41515/41515/30722 +f 41511/41511/30719 41515/41515/30722 41510/41510/30718 +f 41512/41512/30720 41516/41516/30723 41517/41517/30721 +f 41512/41512/30720 41517/41517/30721 41513/41513/30719 +f 41361/41361/30574 41362/41362/30575 41516/41516/30723 +f 41361/41361/30574 41516/41516/30723 41512/41512/30720 +f 41507/41507/30715 41518/41518/30724 41519/41519/30725 +f 41507/41507/30715 41519/41519/30725 41508/41508/30716 +f 41509/41509/30717 41520/41520/30726 41518/41518/30724 +f 41509/41509/30717 41518/41518/30724 41507/41507/30715 +f 41510/41510/30718 41515/41515/30722 41520/41520/30726 +f 41510/41510/30718 41520/41520/30726 41509/41509/30717 +f 41518/41518/30724 41521/41521/30727 41522/41522/30728 +f 41518/41518/30724 41522/41522/30728 41519/41519/30725 +f 41520/41520/30726 41523/41523/30729 41521/41521/30727 +f 41520/41520/30726 41521/41521/30727 41518/41518/30724 +f 41515/41515/30722 41524/41524/30730 41523/41523/30729 +f 41515/41515/30722 41523/41523/30729 41520/41520/30726 +f 41514/41514/30721 41525/41525/30731 41524/41524/30730 +f 41514/41514/30721 41524/41524/30730 41515/41515/30722 +f 41516/41516/30723 41526/41526/30732 41527/41527/30731 +f 41516/41516/30723 41527/41527/30731 41517/41517/30721 +f 41362/41362/30575 41363/41363/30576 41526/41526/30732 +f 41362/41362/30575 41526/41526/30732 41516/41516/30723 +f 41526/41526/30732 41528/41528/30733 41529/41529/30734 +f 41526/41526/30732 41529/41529/30734 41527/41527/30731 +f 41363/41363/30576 41364/41364/30577 41528/41528/30733 +f 41363/41363/30576 41528/41528/30733 41526/41526/30732 +f 41521/41521/30727 41530/41530/30735 41531/41531/30736 +f 41521/41521/30727 41531/41531/30736 41522/41522/30728 +f 41523/41523/30729 41532/41532/30737 41530/41530/30735 +f 41523/41523/30729 41530/41530/30735 41521/41521/30727 +f 41524/41524/30730 41533/41533/30738 41532/41532/30737 +f 41524/41524/30730 41532/41532/30737 41523/41523/30729 +f 41525/41525/30731 41534/41534/30739 41533/41533/30738 +f 41525/41525/30731 41533/41533/30738 41524/41524/30730 +f 41532/41532/30737 41535/41535/30740 41536/41536/30741 +f 41532/41532/30737 41536/41536/30741 41530/41530/30735 +f 41533/41533/30738 41537/41537/30742 41535/41535/30740 +f 41533/41533/30738 41535/41535/30740 41532/41532/30737 +f 41534/41534/30739 41538/41538/30743 41537/41537/30742 +f 41534/41534/30739 41537/41537/30742 41533/41533/30738 +f 41528/41528/30733 41539/41539/30744 41540/41540/30743 +f 41528/41528/30733 41540/41540/30743 41529/41529/30734 +f 41364/41364/30577 41365/41365/30578 41539/41539/30744 +f 41364/41364/30577 41539/41539/30744 41528/41528/30733 +f 41530/41530/30735 41536/41536/30741 41541/41541/30745 +f 41530/41530/30735 41541/41541/30745 41531/41531/30736 +f 41365/41365/30578 41366/41366/30579 41542/41542/30746 +f 41365/41365/30578 41542/41542/30746 41539/41539/30744 +f 41536/41536/30741 41543/41543/30747 41544/41544/30748 +f 41536/41536/30741 41544/41544/30748 41541/41541/30745 +f 41535/41535/30740 41545/41545/30749 41543/41543/30747 +f 41535/41535/30740 41543/41543/30747 41536/41536/30741 +f 41537/41537/30742 41546/41546/30750 41545/41545/30749 +f 41537/41537/30742 41545/41545/30749 41535/41535/30740 +f 41538/41538/30743 41547/41547/30751 41546/41546/30750 +f 41538/41538/30743 41546/41546/30750 41537/41537/30742 +f 41539/41539/30744 41542/41542/30746 41548/41548/30751 +f 41539/41539/30744 41548/41548/30751 41540/41540/30743 +f 41545/41545/30749 41549/41549/30752 41550/41550/30753 +f 41545/41545/30749 41550/41550/30753 41543/41543/30747 +f 41546/41546/30750 41551/41551/30754 41549/41549/30752 +f 41546/41546/30750 41549/41549/30752 41545/41545/30749 +f 41547/41547/30751 41552/41552/30755 41551/41551/30754 +f 41547/41547/30751 41551/41551/30754 41546/41546/30750 +f 41542/41542/30746 41553/41553/30756 41554/41554/30757 +f 41542/41542/30746 41554/41554/30757 41548/41548/30751 +f 41366/41366/30579 41367/41367/30580 41553/41553/30756 +f 41366/41366/30579 41553/41553/30756 41542/41542/30746 +f 41543/41543/30747 41550/41550/30753 41555/41555/30758 +f 41543/41543/30747 41555/41555/30758 41544/41544/30748 +f 41367/41367/30580 41368/41368/30581 41556/41556/30759 +f 41367/41367/30580 41556/41556/30759 41553/41553/30756 +f 41550/41550/30753 41557/41557/30760 41558/41558/30761 +f 41550/41550/30753 41558/41558/30761 41555/41555/30758 +f 41549/41549/30752 41559/41559/30762 41557/41557/30760 +f 41549/41549/30752 41557/41557/30760 41550/41550/30753 +f 41551/41551/30754 41560/41560/30763 41559/41559/30762 +f 41551/41551/30754 41559/41559/30762 41549/41549/30752 +f 41552/41552/30755 41561/41561/30764 41560/41560/30763 +f 41552/41552/30755 41560/41560/30763 41551/41551/30754 +f 41553/41553/30756 41556/41556/30759 41562/41562/30764 +f 41553/41553/30756 41562/41562/30764 41554/41554/30757 +f 41560/41560/30763 41563/41563/30765 41564/41564/30766 +f 41560/41560/30763 41564/41564/30766 41559/41559/30762 +f 41562/41562/30764 41565/41565/30767 41566/41566/30765 +f 41562/41562/30764 41566/41566/30765 41567/41567/30763 +f 41556/41556/30759 41568/41568/30768 41565/41565/30767 +f 41556/41556/30759 41565/41565/30767 41562/41562/30764 +f 41368/41368/30581 41369/41369/30582 41568/41568/30768 +f 41368/41368/30581 41568/41568/30768 41556/41556/30759 +f 41557/41557/30760 41569/41569/30769 41570/41570/30770 +f 41557/41557/30760 41570/41570/30770 41558/41558/30761 +f 41559/41559/30762 41564/41564/30766 41569/41569/30769 +f 41559/41559/30762 41569/41569/30769 41557/41557/30760 +f 41569/41569/30769 41571/41571/30771 41572/41572/30772 +f 41569/41569/30769 41572/41572/30772 41570/41570/30770 +f 41564/41564/30766 41573/41573/30773 41571/41571/30771 +f 41564/41564/30766 41571/41571/30771 41569/41569/30769 +f 41566/41566/30765 41574/41574/30774 41575/41575/30773 +f 41566/41566/30765 41575/41575/30773 41576/41576/30766 +f 41565/41565/30767 41577/41577/30775 41574/41574/30774 +f 41565/41565/30767 41574/41574/30774 41566/41566/30765 +f 41568/41568/30768 41578/41578/30776 41577/41577/30775 +f 41568/41568/30768 41577/41577/30775 41565/41565/30767 +f 41369/41369/30582 41370/41370/30583 41578/41578/30776 +f 41369/41369/30582 41578/41578/30776 41568/41568/30768 +f 41574/41574/30774 41579/41579/30777 41580/41580/30778 +f 41574/41574/30774 41580/41580/30778 41575/41575/30773 +f 41577/41577/30775 41581/41581/30779 41579/41579/30777 +f 41577/41577/30775 41579/41579/30777 41574/41574/30774 +f 41578/41578/30776 41582/41582/30780 41581/41581/30779 +f 41578/41578/30776 41581/41581/30779 41577/41577/30775 +f 41370/41370/30583 41371/41371/30584 41582/41582/30780 +f 41370/41370/30583 41582/41582/30780 41578/41578/30776 +f 41571/41571/30771 41583/41583/30781 41584/41584/30782 +f 41571/41571/30771 41584/41584/30782 41572/41572/30772 +f 41575/41575/30773 41580/41580/30778 41585/41585/30783 +f 41575/41575/30773 41585/41585/30783 41586/41586/30771 +f 41585/41585/30783 41372/41372/30585 41375/41375/30588 +f 41585/41585/30783 41375/41375/30588 41587/41587/30782 +f 41580/41580/30778 41376/41376/30589 41372/41372/30585 +f 41580/41580/30778 41372/41372/30585 41585/41585/30783 +f 41579/41579/30777 41378/41378/30591 41376/41376/30589 +f 41579/41579/30777 41376/41376/30589 41580/41580/30778 +f 41581/41581/30779 41380/41380/30593 41378/41378/30591 +f 41581/41581/30779 41378/41378/30591 41579/41579/30777 +f 41582/41582/30780 41382/41382/30595 41380/41380/30593 +f 41582/41582/30780 41380/41380/30593 41581/41581/30779 +f 41371/41371/30584 41341/41341/30554 41382/41382/30595 +f 41371/41371/30584 41382/41382/30595 41582/41582/30780 +o Sphere.021__0 +v 0.467394 0.868483 -1.037403 +v 0.465661 0.877268 -1.037797 +v 0.467394 0.877439 -1.037813 +v 0.463994 0.876760 -1.037750 +v 0.462458 0.875936 -1.037674 +v 0.461111 0.874827 -1.037572 +v 0.460006 0.873476 -1.037447 +v 0.459185 0.871934 -1.037304 +v 0.458680 0.870261 -1.037150 +v 0.458509 0.868521 -1.036989 +v 0.458680 0.866781 -1.036829 +v 0.459185 0.865108 -1.036674 +v 0.460006 0.863566 -1.036532 +v 0.461111 0.862215 -1.036407 +v 0.462458 0.861106 -1.036305 +v 0.463994 0.860282 -1.036228 +v 0.465661 0.859774 -1.036182 +v 0.467394 0.859603 -1.036166 +v 0.469127 0.859774 -1.036182 +v 0.470794 0.860282 -1.036228 +v 0.472330 0.861106 -1.036305 +v 0.473676 0.862215 -1.036407 +v 0.474782 0.863566 -1.036532 +v 0.475602 0.865108 -1.036674 +v 0.476108 0.866781 -1.036829 +v 0.476279 0.868521 -1.036989 +v 0.476108 0.870261 -1.037150 +v 0.475602 0.871934 -1.037304 +v 0.474782 0.873476 -1.037447 +v 0.473676 0.874827 -1.037572 +v 0.472330 0.875936 -1.037674 +v 0.470794 0.876760 -1.037750 +v 0.469127 0.877268 -1.037797 +v 0.467394 0.911943 -1.028011 +v 0.459185 0.911131 -1.027936 +v 0.458680 0.914056 -1.024133 +v 0.467394 0.914917 -1.024212 +v 0.467394 0.907375 -1.031344 +v 0.460006 0.906645 -1.031276 +v 0.467394 0.901389 -1.034081 +v 0.461111 0.900768 -1.034024 +v 0.467394 0.894214 -1.036119 +v 0.462458 0.893726 -1.036074 +v 0.467394 0.886127 -1.037379 +v 0.463994 0.885791 -1.037348 +v 0.460724 0.884796 -1.037256 +v 0.451292 0.908728 -1.027714 +v 0.450300 0.911505 -1.023897 +v 0.452903 0.904482 -1.031076 +v 0.455070 0.898928 -1.033854 +v 0.457711 0.892281 -1.035941 +v 0.446356 0.900969 -1.030752 +v 0.444018 0.904825 -1.027354 +v 0.449502 0.895941 -1.033578 +v 0.453337 0.889934 -1.035724 +v 0.457711 0.883179 -1.037107 +v 0.442578 0.907361 -1.023515 +v 0.455070 0.881004 -1.036906 +v 0.437642 0.899573 -1.026869 +v 0.435809 0.901786 -1.023000 +v 0.440618 0.896242 -1.030316 +v 0.444623 0.891921 -1.033207 +v 0.449502 0.886776 -1.035433 +v 0.440618 0.887023 -1.032755 +v 0.435908 0.890483 -1.029784 +v 0.446356 0.882927 -1.035077 +v 0.452903 0.878353 -1.036661 +v 0.432409 0.893173 -1.026278 +v 0.430254 0.894992 -1.022372 +v 0.428521 0.885872 -1.025604 +v 0.426126 0.887240 -1.021657 +v 0.432409 0.883912 -1.029177 +v 0.437642 0.881435 -1.032239 +v 0.444018 0.878537 -1.034672 +v 0.451292 0.875329 -1.036382 +v 0.442578 0.873773 -1.034232 +v 0.435809 0.875371 -1.031679 +v 0.450300 0.872047 -1.036079 +v 0.426126 0.877949 -1.024872 +v 0.423585 0.878830 -1.020880 +v 0.430254 0.876782 -1.028519 +v 0.425318 0.869710 -1.024112 +v 0.422727 0.870083 -1.020073 +v 0.429527 0.869366 -1.027834 +v 0.435190 0.869065 -1.031097 +v 0.442092 0.868818 -1.033775 +v 0.449965 0.868634 -1.035764 +v 0.442578 0.863863 -1.033317 +v 0.435809 0.862759 -1.030514 +v 0.450300 0.865221 -1.035449 +v 0.426126 0.861471 -1.023351 +v 0.423585 0.861336 -1.019265 +v 0.430254 0.861951 -1.027149 +v 0.428521 0.853548 -1.022619 +v 0.426126 0.852926 -1.018488 +v 0.432409 0.854821 -1.026491 +v 0.437642 0.856695 -1.029955 +v 0.444018 0.859099 -1.032877 +v 0.451292 0.861940 -1.035146 +v 0.452903 0.858915 -1.034867 +v 0.446356 0.854708 -1.032472 +v 0.432409 0.846247 -1.021945 +v 0.430254 0.845175 -1.017773 +v 0.435908 0.848250 -1.025884 +v 0.440618 0.851107 -1.029439 +v 0.437642 0.839847 -1.021354 +v 0.435809 0.838381 -1.017145 +v 0.440618 0.842490 -1.025352 +v 0.444623 0.846209 -1.028986 +v 0.449502 0.850860 -1.032116 +v 0.455070 0.856264 -1.034622 +v 0.457711 0.854089 -1.034421 +v 0.453337 0.847702 -1.031825 +v 0.444018 0.834595 -1.020869 +v 0.442578 0.832805 -1.016630 +v 0.446356 0.837764 -1.024916 +v 0.449502 0.842189 -1.028615 +v 0.452903 0.834251 -1.024592 +v 0.451292 0.830692 -1.020509 +v 0.455070 0.839202 -1.028339 +v 0.457711 0.845355 -1.031608 +v 0.460724 0.852472 -1.034272 +v 0.450300 0.828662 -1.016248 +v 0.463994 0.851477 -1.034180 +v 0.459185 0.828289 -1.020287 +v 0.458680 0.826111 -1.016012 +v 0.460006 0.832088 -1.024392 +v 0.461111 0.837363 -1.028169 +v 0.462458 0.843910 -1.031475 +v 0.467394 0.836742 -1.028112 +v 0.467394 0.831358 -1.024324 +v 0.467394 0.843421 -1.031430 +v 0.467394 0.851141 -1.034149 +v 0.467394 0.827477 -1.020212 +v 0.467394 0.825249 -1.015933 +v 0.467394 0.827477 -1.020212 +v 0.475602 0.828289 -1.020287 +v 0.476108 0.826111 -1.016012 +v 0.467394 0.825249 -1.015933 +v 0.474782 0.832088 -1.024392 +v 0.475602 0.828289 -1.020287 +v 0.473676 0.837363 -1.028169 +v 0.472330 0.843910 -1.031475 +v 0.470794 0.851477 -1.034180 +v 0.479717 0.839202 -1.028339 +v 0.481885 0.834251 -1.024592 +v 0.477077 0.845355 -1.031608 +v 0.474063 0.852472 -1.034272 +v 0.483495 0.830692 -1.020509 +v 0.484487 0.828662 -1.016248 +v 0.474782 0.832088 -1.024392 +v 0.481885 0.834251 -1.024592 +v 0.490770 0.834595 -1.020869 +v 0.492210 0.832805 -1.016630 +v 0.488432 0.837764 -1.024916 +v 0.479717 0.839202 -1.028339 +v 0.485285 0.842189 -1.028615 +v 0.481451 0.847702 -1.031825 +v 0.485285 0.842189 -1.028615 +v 0.477077 0.854089 -1.034421 +v 0.481451 0.847702 -1.031825 +v 0.485285 0.850860 -1.032116 +v 0.490165 0.846209 -1.028986 +v 0.479717 0.856264 -1.034622 +v 0.485285 0.850860 -1.032116 +v 0.497146 0.839847 -1.021354 +v 0.498978 0.838381 -1.017145 +v 0.494170 0.842490 -1.025352 +v 0.502378 0.846247 -1.021945 +v 0.504533 0.845175 -1.017773 +v 0.498879 0.848250 -1.025884 +v 0.494170 0.851107 -1.029439 +v 0.488432 0.854708 -1.032472 +v 0.481885 0.858915 -1.034867 +v 0.488432 0.854708 -1.032472 +v 0.490770 0.859099 -1.032877 +v 0.497146 0.856695 -1.029955 +v 0.483495 0.861940 -1.035146 +v 0.490770 0.859099 -1.032877 +v 0.506267 0.853548 -1.022619 +v 0.508661 0.852926 -1.018488 +v 0.502378 0.854821 -1.026491 +v 0.508661 0.861471 -1.023351 +v 0.511203 0.861336 -1.019265 +v 0.504533 0.861951 -1.027149 +v 0.498978 0.862759 -1.030514 +v 0.492210 0.863863 -1.033317 +v 0.484487 0.865222 -1.035449 +v 0.492210 0.863863 -1.033317 +v 0.484822 0.868634 -1.035764 +v 0.492696 0.868818 -1.033775 +v 0.509470 0.869710 -1.024112 +v 0.512061 0.870083 -1.020073 +v 0.505261 0.869366 -1.027834 +v 0.499597 0.869065 -1.031097 +v 0.492696 0.868818 -1.033775 +v 0.504533 0.876782 -1.028519 +v 0.508661 0.877949 -1.024872 +v 0.498978 0.875371 -1.031679 +v 0.492210 0.873773 -1.034232 +v 0.484487 0.872047 -1.036079 +v 0.492210 0.873773 -1.034232 +v 0.511203 0.878830 -1.020880 +v 0.483495 0.875329 -1.036382 +v 0.506267 0.885872 -1.025604 +v 0.508661 0.887240 -1.021657 +v 0.502378 0.883912 -1.029177 +v 0.497146 0.881435 -1.032239 +v 0.490770 0.878537 -1.034672 +v 0.490770 0.878537 -1.034672 +v 0.498879 0.890483 -1.029784 +v 0.502378 0.893173 -1.026278 +v 0.494170 0.887023 -1.032755 +v 0.488432 0.882927 -1.035077 +v 0.481885 0.878353 -1.036661 +v 0.488432 0.882927 -1.035077 +v 0.504533 0.894992 -1.022372 +v 0.479717 0.881004 -1.036906 +v 0.497146 0.899573 -1.026869 +v 0.498978 0.901786 -1.023000 +v 0.494170 0.896242 -1.030316 +v 0.490165 0.891921 -1.033207 +v 0.485285 0.886776 -1.035433 +v 0.485285 0.886776 -1.035433 +v 0.485285 0.895941 -1.033578 +v 0.488432 0.900969 -1.030752 +v 0.481451 0.889934 -1.035724 +v 0.485285 0.895941 -1.033578 +v 0.490165 0.891921 -1.033207 +v 0.477077 0.883179 -1.037107 +v 0.490770 0.904825 -1.027354 +v 0.492210 0.907361 -1.023515 +v 0.483495 0.908728 -1.027714 +v 0.484487 0.911505 -1.023897 +v 0.481885 0.904482 -1.031076 +v 0.479717 0.898928 -1.033854 +v 0.481885 0.904482 -1.031076 +v 0.488432 0.900969 -1.030752 +v 0.477077 0.892281 -1.035941 +v 0.474063 0.884796 -1.037256 +v 0.473676 0.900768 -1.034024 +v 0.474782 0.906645 -1.031276 +v 0.472330 0.893726 -1.036074 +v 0.470794 0.885791 -1.037348 +v 0.475602 0.911131 -1.027936 +v 0.476108 0.914056 -1.024133 +v 0.475602 0.911131 -1.027936 +v 0.483495 0.908728 -1.027714 +v 0.476108 0.914056 -1.024133 +vt 0.634060 0.776980 +vt 0.634122 0.776320 +vt 0.633996 0.776320 +vt 0.634246 0.776345 +vt 0.634363 0.776395 +vt 0.634469 0.776467 +vt 0.634559 0.776559 +vt 0.634630 0.776667 +vt 0.634679 0.776786 +vt 0.634705 0.776914 +vt 0.634706 0.777043 +vt 0.634683 0.777170 +vt 0.634636 0.777290 +vt 0.634567 0.777398 +vt 0.634479 0.777490 +vt 0.634375 0.777562 +vt 0.634259 0.777611 +vt 0.634136 0.777637 +vt 0.634010 0.777637 +vt 0.633886 0.777611 +vt 0.633769 0.777562 +vt 0.633664 0.777490 +vt 0.633574 0.777398 +vt 0.633503 0.777290 +vt 0.633453 0.777170 +vt 0.633427 0.777043 +vt 0.633426 0.776914 +vt 0.633449 0.776786 +vt 0.633496 0.776667 +vt 0.633565 0.776559 +vt 0.633653 0.776467 +vt 0.633757 0.776395 +vt 0.633873 0.776345 +vt 0.633935 0.773820 +vt 0.634532 0.773820 +vt 0.634611 0.773615 +vt 0.633978 0.773615 +vt 0.633911 0.774143 +vt 0.634448 0.774143 +vt 0.633905 0.774573 +vt 0.634361 0.774573 +vt 0.633917 0.775093 +vt 0.634276 0.775093 +vt 0.633948 0.775683 +vt 0.634195 0.775683 +vt 0.634438 0.775733 +vt 0.635118 0.773939 +vt 0.635234 0.773742 +vt 0.634975 0.774251 +vt 0.634810 0.774665 +vt 0.634629 0.775165 +vt 0.635474 0.774463 +vt 0.635672 0.774174 +vt 0.635234 0.774845 +vt 0.634962 0.775307 +vt 0.634668 0.775830 +vt 0.635821 0.773991 +vt 0.634875 0.775971 +vt 0.636172 0.774516 +vt 0.636352 0.774354 +vt 0.635923 0.774770 +vt 0.635616 0.775106 +vt 0.635262 0.775512 +vt 0.635942 0.775438 +vt 0.636307 0.775161 +vt 0.635518 0.775773 +vt 0.635051 0.776151 +vt 0.636598 0.774950 +vt 0.636805 0.774815 +vt 0.636935 0.775461 +vt 0.637162 0.775357 +vt 0.636610 0.775620 +vt 0.636200 0.775829 +vt 0.635721 0.776080 +vt 0.635191 0.776363 +vt 0.635862 0.776421 +vt 0.636380 0.776264 +vt 0.635288 0.776598 +vt 0.637169 0.776028 +vt 0.637411 0.775959 +vt 0.636821 0.776131 +vt 0.637292 0.776631 +vt 0.637541 0.776599 +vt 0.636931 0.776673 +vt 0.636473 0.776725 +vt 0.635936 0.776784 +vt 0.635338 0.776847 +vt 0.635939 0.777153 +vt 0.636478 0.777195 +vt 0.635341 0.777102 +vt 0.637298 0.777245 +vt 0.637548 0.777251 +vt 0.636937 0.777226 +vt 0.637188 0.777847 +vt 0.637431 0.777890 +vt 0.636838 0.777768 +vt 0.636394 0.777656 +vt 0.635873 0.777515 +vt 0.635296 0.777351 +vt 0.635203 0.777586 +vt 0.635740 0.777856 +vt 0.636966 0.778415 +vt 0.637195 0.778493 +vt 0.636638 0.778279 +vt 0.636224 0.778090 +vt 0.636640 0.778925 +vt 0.636849 0.779035 +vt 0.636344 0.778738 +vt 0.635974 0.778481 +vt 0.635543 0.778163 +vt 0.635068 0.777798 +vt 0.634896 0.777978 +vt 0.635292 0.778425 +vt 0.636222 0.779360 +vt 0.636406 0.779496 +vt 0.635969 0.779129 +vt 0.635655 0.778813 +vt 0.635526 0.779436 +vt 0.635730 0.779701 +vt 0.635278 0.779075 +vt 0.634996 0.778630 +vt 0.634691 0.778119 +vt 0.635883 0.779858 +vt 0.634464 0.778216 +vt 0.635181 0.779936 +vt 0.635300 0.780108 +vt 0.635032 0.779648 +vt 0.634858 0.779254 +vt 0.634666 0.778771 +vt 0.634411 0.779346 +vt 0.634506 0.779756 +vt 0.634315 0.778843 +vt 0.634222 0.778266 +vt 0.634597 0.780056 +vt 0.634680 0.780235 +vt 0.933973 0.641469 +vt 0.933531 0.641350 +vt 0.933288 0.641535 +vt 0.933756 0.641661 +vt 0.633969 0.779756 +vt 0.634001 0.780056 +vt 0.633954 0.779346 +vt 0.633956 0.778843 +vt 0.633975 0.778266 +vt 0.633506 0.779254 +vt 0.633442 0.779648 +vt 0.633604 0.778771 +vt 0.633732 0.778216 +vt 0.933116 0.641115 +vt 0.932847 0.641286 +vt 0.933785 0.641049 +vt 0.933411 0.640838 +vt 0.932742 0.640774 +vt 0.932449 0.640924 +vt 0.933074 0.640532 +vt 0.933720 0.640466 +vt 0.933434 0.640205 +vt 0.633271 0.778630 +vt 0.633082 0.779075 +vt 0.633503 0.778119 +vt 0.933807 0.639807 +vt 0.933616 0.639546 +vt 0.933190 0.639873 +vt 0.633296 0.777978 +vt 0.632970 0.778425 +vt 0.932424 0.640340 +vt 0.932112 0.640463 +vt 0.932788 0.640141 +vt 0.932174 0.639830 +vt 0.931846 0.639921 +vt 0.932563 0.639681 +vt 0.932999 0.639482 +vt 0.933465 0.639239 +vt 0.633119 0.777798 +vt 0.632714 0.778163 +vt 0.933362 0.638897 +vt 0.932867 0.639048 +vt 0.632980 0.777586 +vt 0.632511 0.777856 +vt 0.932002 0.639262 +vt 0.931664 0.639319 +vt 0.932408 0.639171 +vt 0.931914 0.638659 +vt 0.931571 0.638679 +vt 0.932329 0.638628 +vt 0.932800 0.638586 +vt 0.933309 0.638535 +vt 0.632883 0.777351 +vt 0.632371 0.777515 +vt 0.632832 0.777102 +vt 0.632297 0.777153 +vt 0.931914 0.638045 +vt 0.931571 0.638026 +vt 0.932329 0.638075 +vt 0.932800 0.638116 +vt 0.933309 0.638165 +vt 0.932408 0.637532 +vt 0.932002 0.637442 +vt 0.932867 0.637654 +vt 0.933362 0.637803 +vt 0.632829 0.776847 +vt 0.632293 0.776784 +vt 0.931664 0.637386 +vt 0.632875 0.776598 +vt 0.932174 0.636873 +vt 0.931846 0.636782 +vt 0.932563 0.637021 +vt 0.932999 0.637219 +vt 0.933465 0.637461 +vt 0.632359 0.776421 +vt 0.932788 0.636560 +vt 0.932424 0.636361 +vt 0.933190 0.636827 +vt 0.933616 0.637153 +vt 0.632967 0.776363 +vt 0.632493 0.776080 +vt 0.932112 0.636239 +vt 0.633102 0.776151 +vt 0.932742 0.635926 +vt 0.932449 0.635777 +vt 0.933074 0.636168 +vt 0.933434 0.636494 +vt 0.933807 0.636891 +vt 0.632689 0.775773 +vt 0.933720 0.636232 +vt 0.933411 0.635860 +vt 0.632940 0.775512 +vt 0.632661 0.775106 +vt 0.632341 0.775438 +vt 0.633275 0.775971 +vt 0.933116 0.635584 +vt 0.932847 0.635414 +vt 0.933531 0.635348 +vt 0.933288 0.635163 +vt 0.933785 0.635648 +vt 0.633038 0.774845 +vt 0.632891 0.774463 +vt 0.632448 0.774770 +vt 0.633236 0.775307 +vt 0.633479 0.775830 +vt 0.633458 0.774665 +vt 0.633385 0.774251 +vt 0.633566 0.775165 +vt 0.633706 0.775733 +vt 0.933973 0.635227 +vt 0.933756 0.635035 +vt 0.633352 0.773939 +vt 0.632803 0.774174 +vt 0.633358 0.773742 +vn -0.0000 -0.0919 -0.9958 +vn -0.0191 0.0032 -0.9998 +vn 0.0000 0.0051 -1.0000 +vn -0.0374 -0.0023 -0.9993 +vn -0.0543 -0.0112 -0.9985 +vn -0.0691 -0.0233 -0.9973 +vn -0.0813 -0.0379 -0.9960 +vn -0.0903 -0.0546 -0.9944 +vn -0.0958 -0.0726 -0.9927 +vn -0.0977 -0.0915 -0.9910 +vn -0.0958 -0.1103 -0.9893 +vn -0.0903 -0.1284 -0.9876 +vn -0.0812 -0.1451 -0.9861 +vn -0.0691 -0.1598 -0.9847 +vn -0.0543 -0.1718 -0.9836 +vn -0.0374 -0.1807 -0.9828 +vn -0.0192 -0.1862 -0.9823 +vn -0.0000 -0.1881 -0.9822 +vn 0.0191 -0.1862 -0.9823 +vn 0.0374 -0.1807 -0.9828 +vn 0.0543 -0.1718 -0.9836 +vn 0.0691 -0.1598 -0.9847 +vn 0.0812 -0.1451 -0.9861 +vn 0.0903 -0.1284 -0.9876 +vn 0.0958 -0.1103 -0.9893 +vn 0.0977 -0.0915 -0.9910 +vn 0.0958 -0.0726 -0.9927 +vn 0.0903 -0.0546 -0.9944 +vn 0.0813 -0.0379 -0.9960 +vn 0.0691 -0.0233 -0.9973 +vn 0.0543 -0.0112 -0.9985 +vn 0.0375 -0.0023 -0.9993 +vn 0.0191 0.0032 -0.9998 +vn -0.0000 0.6990 -0.7151 +vn -0.1498 0.6843 -0.7137 +vn -0.1652 0.7711 -0.6149 +vn 0.0000 0.7874 -0.6165 +vn -0.0000 0.5096 -0.8604 +vn -0.1153 0.4983 -0.8593 +vn 0.0000 0.3496 -0.9369 +vn -0.0854 0.3413 -0.9361 +vn -0.0000 0.2176 -0.9760 +vn -0.0603 0.2117 -0.9755 +vn -0.0000 0.1052 -0.9944 +vn -0.0386 0.1015 -0.9941 +vn -0.0757 0.0904 -0.9930 +vn -0.2936 0.6408 -0.7093 +vn -0.3238 0.7231 -0.6101 +vn -0.2262 0.4649 -0.8560 +vn -0.1675 0.3166 -0.9336 +vn -0.1182 0.1943 -0.9738 +vn -0.3282 0.4108 -0.8506 +vn -0.4259 0.5703 -0.7024 +vn -0.2431 0.2766 -0.9297 +vn -0.1715 0.1661 -0.9711 +vn -0.1099 0.0723 -0.9913 +vn -0.4698 0.6453 -0.6024 +vn -0.1399 0.0479 -0.9890 +vn -0.5416 0.4757 -0.6931 +vn -0.5974 0.5408 -0.5922 +vn -0.4174 0.3380 -0.8435 +vn -0.3093 0.2228 -0.9245 +vn -0.2183 0.1281 -0.9674 +vn -0.3635 0.1572 -0.9182 +vn -0.4906 0.2495 -0.8349 +vn -0.2566 0.0819 -0.9630 +vn -0.1644 0.0183 -0.9862 +vn -0.6363 0.3607 -0.6819 +vn -0.7018 0.4139 -0.5798 +vn -0.7065 0.2298 -0.6694 +vn -0.7791 0.2695 -0.5660 +vn -0.5448 0.1486 -0.8253 +vn -0.4038 0.0825 -0.9111 +vn -0.2851 0.0292 -0.9581 +vn -0.1827 -0.0154 -0.9831 +vn -0.3026 -0.0280 -0.9527 +vn -0.4286 0.0015 -0.9035 +vn -0.1939 -0.0521 -0.9796 +vn -0.7496 0.0880 -0.6560 +vn -0.8266 0.1130 -0.5513 +vn -0.5782 0.0393 -0.8149 +vn -0.7642 -0.0593 -0.6423 +vn -0.8427 -0.0495 -0.5361 +vn -0.5895 -0.0743 -0.8044 +vn -0.4370 -0.0827 -0.8956 +vn -0.3085 -0.0874 -0.9472 +vn -0.1977 -0.0901 -0.9761 +vn -0.3026 -0.1469 -0.9417 +vn -0.4286 -0.1669 -0.8879 +vn -0.1939 -0.1282 -0.9726 +vn -0.7496 -0.2066 -0.6288 +vn -0.8267 -0.2120 -0.5212 +vn -0.5782 -0.1879 -0.7940 +vn -0.7065 -0.3485 -0.6160 +vn -0.7791 -0.3686 -0.5071 +vn -0.5448 -0.2972 -0.7841 +vn -0.4039 -0.2479 -0.8806 +vn -0.2851 -0.2041 -0.9365 +vn -0.1826 -0.1649 -0.9693 +vn -0.1644 -0.1986 -0.9662 +vn -0.2566 -0.2569 -0.9318 +vn -0.6363 -0.4794 -0.6043 +vn -0.7018 -0.5131 -0.4942 +vn -0.4906 -0.3982 -0.7751 +vn -0.3636 -0.3227 -0.8739 +vn -0.5416 -0.5946 -0.5943 +vn -0.5973 -0.6401 -0.4831 +vn -0.4174 -0.4868 -0.7673 +vn -0.3093 -0.3883 -0.8681 +vn -0.2183 -0.3031 -0.9276 +vn -0.1398 -0.2282 -0.9635 +vn -0.1099 -0.2526 -0.9613 +vn -0.1715 -0.3411 -0.9242 +vn -0.4259 -0.6893 -0.5861 +vn -0.4698 -0.7447 -0.4741 +vn -0.3282 -0.5596 -0.7610 +vn -0.2431 -0.4421 -0.8634 +vn -0.2262 -0.6138 -0.7564 +vn -0.2936 -0.7599 -0.5800 +vn -0.1675 -0.4822 -0.8599 +vn -0.1182 -0.3693 -0.9217 +vn -0.0757 -0.2706 -0.9597 +vn -0.3238 -0.8226 -0.4674 +vn -0.0386 -0.2818 -0.9587 +vn -0.1498 -0.8034 -0.5763 +vn -0.1652 -0.8707 -0.4632 +vn -0.1153 -0.6472 -0.7535 +vn -0.0854 -0.5069 -0.8577 +vn -0.0603 -0.3867 -0.9202 +vn -0.0000 -0.5153 -0.8570 +vn -0.0000 -0.6585 -0.7525 +vn -0.0000 -0.3926 -0.9197 +vn -0.0000 -0.2855 -0.9584 +vn 0.0000 -0.8181 -0.5750 +vn -0.0000 -0.8869 -0.4619 +vn 0.0000 -0.8181 -0.5751 +vn 0.1498 -0.8034 -0.5763 +vn 0.1652 -0.8707 -0.4632 +vn 0.1154 -0.6472 -0.7535 +vn 0.0854 -0.5069 -0.8577 +vn 0.0603 -0.3867 -0.9202 +vn 0.0386 -0.2818 -0.9587 +vn 0.1675 -0.4822 -0.8599 +vn 0.2261 -0.6138 -0.7564 +vn 0.1182 -0.3693 -0.9217 +vn 0.0757 -0.2706 -0.9597 +vn 0.2936 -0.7599 -0.5800 +vn 0.3239 -0.8226 -0.4674 +vn 0.1153 -0.6472 -0.7535 +vn 0.2262 -0.6138 -0.7564 +vn 0.4259 -0.6893 -0.5861 +vn 0.4698 -0.7447 -0.4741 +vn 0.3282 -0.5596 -0.7610 +vn 0.2431 -0.4421 -0.8634 +vn 0.1716 -0.3411 -0.9242 +vn 0.2431 -0.4422 -0.8634 +vn 0.1099 -0.2526 -0.9613 +vn 0.1716 -0.3411 -0.9243 +vn 0.2183 -0.3031 -0.9276 +vn 0.3093 -0.3883 -0.8681 +vn 0.1398 -0.2282 -0.9635 +vn 0.5416 -0.5945 -0.5943 +vn 0.5973 -0.6401 -0.4831 +vn 0.4174 -0.4867 -0.7673 +vn 0.6363 -0.4794 -0.6044 +vn 0.7017 -0.5131 -0.4943 +vn 0.4906 -0.3982 -0.7751 +vn 0.3636 -0.3227 -0.8739 +vn 0.2566 -0.2569 -0.9318 +vn 0.1644 -0.1986 -0.9662 +vn 0.2851 -0.2041 -0.9365 +vn 0.4039 -0.2480 -0.8806 +vn 0.1826 -0.1649 -0.9693 +vn 0.7065 -0.3485 -0.6160 +vn 0.7791 -0.3686 -0.5071 +vn 0.5448 -0.2973 -0.7841 +vn 0.7496 -0.2066 -0.6288 +vn 0.8267 -0.2121 -0.5212 +vn 0.5782 -0.1879 -0.7939 +vn 0.4286 -0.1669 -0.8879 +vn 0.3027 -0.1469 -0.9417 +vn 0.1939 -0.1282 -0.9726 +vn 0.3026 -0.1469 -0.9417 +vn 0.1977 -0.0901 -0.9761 +vn 0.3085 -0.0874 -0.9472 +vn 0.7642 -0.0593 -0.6423 +vn 0.8427 -0.0495 -0.5361 +vn 0.5895 -0.0743 -0.8044 +vn 0.4370 -0.0827 -0.8956 +vn 0.3085 -0.0875 -0.9472 +vn 0.5782 0.0393 -0.8149 +vn 0.7496 0.0880 -0.6560 +vn 0.4287 0.0015 -0.9035 +vn 0.3026 -0.0280 -0.9527 +vn 0.1939 -0.0520 -0.9796 +vn 0.8266 0.1130 -0.5513 +vn 0.1826 -0.0154 -0.9831 +vn 0.7065 0.2298 -0.6694 +vn 0.7792 0.2695 -0.5660 +vn 0.5448 0.1486 -0.8253 +vn 0.4038 0.0825 -0.9111 +vn 0.2851 0.0292 -0.9581 +vn 0.4906 0.2495 -0.8349 +vn 0.6363 0.3607 -0.6819 +vn 0.3636 0.1572 -0.9182 +vn 0.2566 0.0819 -0.9630 +vn 0.1644 0.0183 -0.9862 +vn 0.7018 0.4139 -0.5798 +vn 0.1399 0.0479 -0.9890 +vn 0.5416 0.4757 -0.6931 +vn 0.5974 0.5408 -0.5922 +vn 0.4174 0.3380 -0.8435 +vn 0.3093 0.2228 -0.9245 +vn 0.2183 0.1281 -0.9674 +vn 0.2430 0.2766 -0.9298 +vn 0.3282 0.4108 -0.8506 +vn 0.1716 0.1661 -0.9711 +vn 0.2431 0.2766 -0.9297 +vn 0.1099 0.0723 -0.9913 +vn 0.4259 0.5703 -0.7024 +vn 0.4698 0.6453 -0.6024 +vn 0.2936 0.6408 -0.7093 +vn 0.3239 0.7231 -0.6101 +vn 0.2261 0.4649 -0.8560 +vn 0.1675 0.3166 -0.9336 +vn 0.1182 0.1943 -0.9738 +vn 0.0757 0.0903 -0.9930 +vn 0.0854 0.3413 -0.9361 +vn 0.1153 0.4983 -0.8593 +vn 0.0603 0.2117 -0.9755 +vn 0.0386 0.1015 -0.9941 +vn 0.1497 0.6843 -0.7137 +vn 0.1652 0.7711 -0.6149 +vn 0.1498 0.6843 -0.7137 +usemtl Scene_-_Root +s 1 +f 41588/41588/30784 41589/41589/30785 41590/41590/30786 +f 41588/41588/30784 41591/41591/30787 41589/41589/30785 +f 41588/41588/30784 41592/41592/30788 41591/41591/30787 +f 41588/41588/30784 41593/41593/30789 41592/41592/30788 +f 41588/41588/30784 41594/41594/30790 41593/41593/30789 +f 41588/41588/30784 41595/41595/30791 41594/41594/30790 +f 41588/41588/30784 41596/41596/30792 41595/41595/30791 +f 41588/41588/30784 41597/41597/30793 41596/41596/30792 +f 41588/41588/30784 41598/41598/30794 41597/41597/30793 +f 41588/41588/30784 41599/41599/30795 41598/41598/30794 +f 41588/41588/30784 41600/41600/30796 41599/41599/30795 +f 41588/41588/30784 41601/41601/30797 41600/41600/30796 +f 41588/41588/30784 41602/41602/30798 41601/41601/30797 +f 41588/41588/30784 41603/41603/30799 41602/41602/30798 +f 41588/41588/30784 41604/41604/30800 41603/41603/30799 +f 41588/41588/30784 41605/41605/30801 41604/41604/30800 +f 41588/41588/30784 41606/41606/30802 41605/41605/30801 +f 41588/41588/30784 41607/41607/30803 41606/41606/30802 +f 41588/41588/30784 41608/41608/30804 41607/41607/30803 +f 41588/41588/30784 41609/41609/30805 41608/41608/30804 +f 41588/41588/30784 41610/41610/30806 41609/41609/30805 +f 41588/41588/30784 41611/41611/30807 41610/41610/30806 +f 41588/41588/30784 41612/41612/30808 41611/41611/30807 +f 41588/41588/30784 41613/41613/30809 41612/41612/30808 +f 41588/41588/30784 41614/41614/30810 41613/41613/30809 +f 41588/41588/30784 41615/41615/30811 41614/41614/30810 +f 41588/41588/30784 41616/41616/30812 41615/41615/30811 +f 41588/41588/30784 41617/41617/30813 41616/41616/30812 +f 41588/41588/30784 41618/41618/30814 41617/41617/30813 +f 41588/41588/30784 41619/41619/30815 41618/41618/30814 +f 41588/41588/30784 41620/41620/30816 41619/41619/30815 +f 41588/41588/30784 41590/41590/30786 41620/41620/30816 +f 41621/41621/30817 41622/41622/30818 41623/41623/30819 +f 41621/41621/30817 41623/41623/30819 41624/41624/30820 +f 41625/41625/30821 41626/41626/30822 41622/41622/30818 +f 41625/41625/30821 41622/41622/30818 41621/41621/30817 +f 41627/41627/30823 41628/41628/30824 41626/41626/30822 +f 41627/41627/30823 41626/41626/30822 41625/41625/30821 +f 41629/41629/30825 41630/41630/30826 41628/41628/30824 +f 41629/41629/30825 41628/41628/30824 41627/41627/30823 +f 41631/41631/30827 41632/41632/30828 41630/41630/30826 +f 41631/41631/30827 41630/41630/30826 41629/41629/30825 +f 41590/41590/30786 41589/41589/30785 41632/41632/30828 +f 41590/41590/30786 41632/41632/30828 41631/41631/30827 +f 41589/41589/30785 41591/41591/30787 41633/41633/30829 +f 41589/41589/30785 41633/41633/30829 41632/41632/30828 +f 41622/41622/30818 41634/41634/30830 41635/41635/30831 +f 41622/41622/30818 41635/41635/30831 41623/41623/30819 +f 41626/41626/30822 41636/41636/30832 41634/41634/30830 +f 41626/41626/30822 41634/41634/30830 41622/41622/30818 +f 41628/41628/30824 41637/41637/30833 41636/41636/30832 +f 41628/41628/30824 41636/41636/30832 41626/41626/30822 +f 41630/41630/30826 41638/41638/30834 41637/41637/30833 +f 41630/41630/30826 41637/41637/30833 41628/41628/30824 +f 41632/41632/30828 41633/41633/30829 41638/41638/30834 +f 41632/41632/30828 41638/41638/30834 41630/41630/30826 +f 41636/41636/30832 41639/41639/30835 41640/41640/30836 +f 41636/41636/30832 41640/41640/30836 41634/41634/30830 +f 41637/41637/30833 41641/41641/30837 41639/41639/30835 +f 41637/41637/30833 41639/41639/30835 41636/41636/30832 +f 41638/41638/30834 41642/41642/30838 41641/41641/30837 +f 41638/41638/30834 41641/41641/30837 41637/41637/30833 +f 41633/41633/30829 41643/41643/30839 41642/41642/30838 +f 41633/41633/30829 41642/41642/30838 41638/41638/30834 +f 41591/41591/30787 41592/41592/30788 41643/41643/30839 +f 41591/41591/30787 41643/41643/30839 41633/41633/30829 +f 41634/41634/30830 41640/41640/30836 41644/41644/30840 +f 41634/41634/30830 41644/41644/30840 41635/41635/30831 +f 41592/41592/30788 41593/41593/30789 41645/41645/30841 +f 41592/41592/30788 41645/41645/30841 41643/41643/30839 +f 41640/41640/30836 41646/41646/30842 41647/41647/30843 +f 41640/41640/30836 41647/41647/30843 41644/41644/30840 +f 41639/41639/30835 41648/41648/30844 41646/41646/30842 +f 41639/41639/30835 41646/41646/30842 41640/41640/30836 +f 41641/41641/30837 41649/41649/30845 41648/41648/30844 +f 41641/41641/30837 41648/41648/30844 41639/41639/30835 +f 41642/41642/30838 41650/41650/30846 41649/41649/30845 +f 41642/41642/30838 41649/41649/30845 41641/41641/30837 +f 41643/41643/30839 41645/41645/30841 41650/41650/30846 +f 41643/41643/30839 41650/41650/30846 41642/41642/30838 +f 41649/41649/30845 41651/41651/30847 41652/41652/30848 +f 41649/41649/30845 41652/41652/30848 41648/41648/30844 +f 41650/41650/30846 41653/41653/30849 41651/41651/30847 +f 41650/41650/30846 41651/41651/30847 41649/41649/30845 +f 41645/41645/30841 41654/41654/30850 41653/41653/30849 +f 41645/41645/30841 41653/41653/30849 41650/41650/30846 +f 41593/41593/30789 41594/41594/30790 41654/41654/30850 +f 41593/41593/30789 41654/41654/30850 41645/41645/30841 +f 41646/41646/30842 41655/41655/30851 41656/41656/30852 +f 41646/41646/30842 41656/41656/30852 41647/41647/30843 +f 41648/41648/30844 41652/41652/30848 41655/41655/30851 +f 41648/41648/30844 41655/41655/30851 41646/41646/30842 +f 41655/41655/30851 41657/41657/30853 41658/41658/30854 +f 41655/41655/30851 41658/41658/30854 41656/41656/30852 +f 41652/41652/30848 41659/41659/30855 41657/41657/30853 +f 41652/41652/30848 41657/41657/30853 41655/41655/30851 +f 41651/41651/30847 41660/41660/30856 41659/41659/30855 +f 41651/41651/30847 41659/41659/30855 41652/41652/30848 +f 41653/41653/30849 41661/41661/30857 41660/41660/30856 +f 41653/41653/30849 41660/41660/30856 41651/41651/30847 +f 41654/41654/30850 41662/41662/30858 41661/41661/30857 +f 41654/41654/30850 41661/41661/30857 41653/41653/30849 +f 41594/41594/30790 41595/41595/30791 41662/41662/30858 +f 41594/41594/30790 41662/41662/30858 41654/41654/30850 +f 41661/41661/30857 41663/41663/30859 41664/41664/30860 +f 41661/41661/30857 41664/41664/30860 41660/41660/30856 +f 41662/41662/30858 41665/41665/30861 41663/41663/30859 +f 41662/41662/30858 41663/41663/30859 41661/41661/30857 +f 41595/41595/30791 41596/41596/30792 41665/41665/30861 +f 41595/41595/30791 41665/41665/30861 41662/41662/30858 +f 41657/41657/30853 41666/41666/30862 41667/41667/30863 +f 41657/41657/30853 41667/41667/30863 41658/41658/30854 +f 41659/41659/30855 41668/41668/30864 41666/41666/30862 +f 41659/41659/30855 41666/41666/30862 41657/41657/30853 +f 41660/41660/30856 41664/41664/30860 41668/41668/30864 +f 41660/41660/30856 41668/41668/30864 41659/41659/30855 +f 41666/41666/30862 41669/41669/30865 41670/41670/30866 +f 41666/41666/30862 41670/41670/30866 41667/41667/30863 +f 41668/41668/30864 41671/41671/30867 41669/41669/30865 +f 41668/41668/30864 41669/41669/30865 41666/41666/30862 +f 41664/41664/30860 41672/41672/30868 41671/41671/30867 +f 41664/41664/30860 41671/41671/30867 41668/41668/30864 +f 41663/41663/30859 41673/41673/30869 41672/41672/30868 +f 41663/41663/30859 41672/41672/30868 41664/41664/30860 +f 41665/41665/30861 41674/41674/30870 41673/41673/30869 +f 41665/41665/30861 41673/41673/30869 41663/41663/30859 +f 41596/41596/30792 41597/41597/30793 41674/41674/30870 +f 41596/41596/30792 41674/41674/30870 41665/41665/30861 +f 41673/41673/30869 41675/41675/30871 41676/41676/30872 +f 41673/41673/30869 41676/41676/30872 41672/41672/30868 +f 41674/41674/30870 41677/41677/30873 41675/41675/30871 +f 41674/41674/30870 41675/41675/30871 41673/41673/30869 +f 41597/41597/30793 41598/41598/30794 41677/41677/30873 +f 41597/41597/30793 41677/41677/30873 41674/41674/30870 +f 41669/41669/30865 41678/41678/30874 41679/41679/30875 +f 41669/41669/30865 41679/41679/30875 41670/41670/30866 +f 41671/41671/30867 41680/41680/30876 41678/41678/30874 +f 41671/41671/30867 41678/41678/30874 41669/41669/30865 +f 41672/41672/30868 41676/41676/30872 41680/41680/30876 +f 41672/41672/30868 41680/41680/30876 41671/41671/30867 +f 41678/41678/30874 41681/41681/30877 41682/41682/30878 +f 41678/41678/30874 41682/41682/30878 41679/41679/30875 +f 41680/41680/30876 41683/41683/30879 41681/41681/30877 +f 41680/41680/30876 41681/41681/30877 41678/41678/30874 +f 41676/41676/30872 41684/41684/30880 41683/41683/30879 +f 41676/41676/30872 41683/41683/30879 41680/41680/30876 +f 41675/41675/30871 41685/41685/30881 41684/41684/30880 +f 41675/41675/30871 41684/41684/30880 41676/41676/30872 +f 41677/41677/30873 41686/41686/30882 41685/41685/30881 +f 41677/41677/30873 41685/41685/30881 41675/41675/30871 +f 41598/41598/30794 41599/41599/30795 41686/41686/30882 +f 41598/41598/30794 41686/41686/30882 41677/41677/30873 +f 41686/41686/30882 41687/41687/30883 41688/41688/30884 +f 41686/41686/30882 41688/41688/30884 41685/41685/30881 +f 41599/41599/30795 41600/41600/30796 41687/41687/30883 +f 41599/41599/30795 41687/41687/30883 41686/41686/30882 +f 41681/41681/30877 41689/41689/30885 41690/41690/30886 +f 41681/41681/30877 41690/41690/30886 41682/41682/30878 +f 41683/41683/30879 41691/41691/30887 41689/41689/30885 +f 41683/41683/30879 41689/41689/30885 41681/41681/30877 +f 41684/41684/30880 41692/41692/30888 41691/41691/30887 +f 41684/41684/30880 41691/41691/30887 41683/41683/30879 +f 41685/41685/30881 41688/41688/30884 41692/41692/30888 +f 41685/41685/30881 41692/41692/30888 41684/41684/30880 +f 41689/41689/30885 41693/41693/30889 41694/41694/30890 +f 41689/41689/30885 41694/41694/30890 41690/41690/30886 +f 41691/41691/30887 41695/41695/30891 41693/41693/30889 +f 41691/41691/30887 41693/41693/30889 41689/41689/30885 +f 41692/41692/30888 41696/41696/30892 41695/41695/30891 +f 41692/41692/30888 41695/41695/30891 41691/41691/30887 +f 41688/41688/30884 41697/41697/30893 41696/41696/30892 +f 41688/41688/30884 41696/41696/30892 41692/41692/30888 +f 41687/41687/30883 41698/41698/30894 41697/41697/30893 +f 41687/41687/30883 41697/41697/30893 41688/41688/30884 +f 41600/41600/30796 41601/41601/30797 41698/41698/30894 +f 41600/41600/30796 41698/41698/30894 41687/41687/30883 +f 41698/41698/30894 41699/41699/30895 41700/41700/30896 +f 41698/41698/30894 41700/41700/30896 41697/41697/30893 +f 41601/41601/30797 41602/41602/30798 41699/41699/30895 +f 41601/41601/30797 41699/41699/30895 41698/41698/30894 +f 41693/41693/30889 41701/41701/30897 41702/41702/30898 +f 41693/41693/30889 41702/41702/30898 41694/41694/30890 +f 41695/41695/30891 41703/41703/30899 41701/41701/30897 +f 41695/41695/30891 41701/41701/30897 41693/41693/30889 +f 41696/41696/30892 41704/41704/30900 41703/41703/30899 +f 41696/41696/30892 41703/41703/30899 41695/41695/30891 +f 41697/41697/30893 41700/41700/30896 41704/41704/30900 +f 41697/41697/30893 41704/41704/30900 41696/41696/30892 +f 41703/41703/30899 41705/41705/30901 41706/41706/30902 +f 41703/41703/30899 41706/41706/30902 41701/41701/30897 +f 41704/41704/30900 41707/41707/30903 41705/41705/30901 +f 41704/41704/30900 41705/41705/30901 41703/41703/30899 +f 41700/41700/30896 41708/41708/30904 41707/41707/30903 +f 41700/41700/30896 41707/41707/30903 41704/41704/30900 +f 41699/41699/30895 41709/41709/30905 41708/41708/30904 +f 41699/41699/30895 41708/41708/30904 41700/41700/30896 +f 41602/41602/30798 41603/41603/30799 41709/41709/30905 +f 41602/41602/30798 41709/41709/30905 41699/41699/30895 +f 41701/41701/30897 41706/41706/30902 41710/41710/30906 +f 41701/41701/30897 41710/41710/30906 41702/41702/30898 +f 41603/41603/30799 41604/41604/30800 41711/41711/30907 +f 41603/41603/30799 41711/41711/30907 41709/41709/30905 +f 41706/41706/30902 41712/41712/30908 41713/41713/30909 +f 41706/41706/30902 41713/41713/30909 41710/41710/30906 +f 41705/41705/30901 41714/41714/30910 41712/41712/30908 +f 41705/41705/30901 41712/41712/30908 41706/41706/30902 +f 41707/41707/30903 41715/41715/30911 41714/41714/30910 +f 41707/41707/30903 41714/41714/30910 41705/41705/30901 +f 41708/41708/30904 41716/41716/30912 41715/41715/30911 +f 41708/41708/30904 41715/41715/30911 41707/41707/30903 +f 41709/41709/30905 41711/41711/30907 41716/41716/30912 +f 41709/41709/30905 41716/41716/30912 41708/41708/30904 +f 41715/41715/30911 41717/41717/30913 41718/41718/30914 +f 41715/41715/30911 41718/41718/30914 41714/41714/30910 +f 41716/41716/30912 41719/41719/30915 41717/41717/30913 +f 41716/41716/30912 41717/41717/30913 41715/41715/30911 +f 41711/41711/30907 41720/41720/30916 41719/41719/30915 +f 41711/41711/30907 41719/41719/30915 41716/41716/30912 +f 41604/41604/30800 41605/41605/30801 41720/41720/30916 +f 41604/41604/30800 41720/41720/30916 41711/41711/30907 +f 41712/41712/30908 41721/41721/30917 41722/41722/30918 +f 41712/41712/30908 41722/41722/30918 41713/41713/30909 +f 41714/41714/30910 41718/41718/30914 41721/41721/30917 +f 41714/41714/30910 41721/41721/30917 41712/41712/30908 +f 41723/41723/30919 41724/41724/30920 41725/41725/30921 +f 41723/41723/30919 41725/41725/30921 41726/41726/30918 +f 41718/41718/30914 41727/41727/30922 41728/41728/30920 +f 41718/41718/30914 41728/41728/30920 41721/41721/30917 +f 41717/41717/30913 41729/41729/30923 41727/41727/30922 +f 41717/41717/30913 41727/41727/30922 41718/41718/30914 +f 41719/41719/30915 41730/41730/30924 41729/41729/30923 +f 41719/41719/30915 41729/41729/30923 41717/41717/30913 +f 41720/41720/30916 41731/41731/30925 41730/41730/30924 +f 41720/41720/30916 41730/41730/30924 41719/41719/30915 +f 41605/41605/30801 41606/41606/30802 41731/41731/30925 +f 41605/41605/30801 41731/41731/30925 41720/41720/30916 +f 41729/41729/30923 41732/41732/30926 41733/41733/30927 +f 41729/41729/30923 41733/41733/30927 41727/41727/30922 +f 41730/41730/30924 41734/41734/30928 41732/41732/30926 +f 41730/41730/30924 41732/41732/30926 41729/41729/30923 +f 41731/41731/30925 41735/41735/30929 41734/41734/30928 +f 41731/41731/30925 41734/41734/30928 41730/41730/30924 +f 41606/41606/30802 41607/41607/30803 41735/41735/30929 +f 41606/41606/30802 41735/41735/30929 41731/41731/30925 +f 41724/41724/30920 41736/41736/30930 41737/41737/30931 +f 41724/41724/30920 41737/41737/30931 41725/41725/30921 +f 41738/41738/30932 41739/41739/30933 41736/41736/30930 +f 41738/41738/30932 41736/41736/30930 41724/41724/30920 +f 41736/41736/30930 41740/41740/30934 41741/41741/30935 +f 41736/41736/30930 41741/41741/30935 41737/41737/30931 +f 41739/41739/30933 41742/41742/30936 41740/41740/30934 +f 41739/41739/30933 41740/41740/30934 41736/41736/30930 +f 41743/41743/30926 41744/41744/30937 41742/41742/30936 +f 41743/41743/30926 41742/41742/30936 41739/41739/30933 +f 41734/41734/30928 41745/41745/30938 41746/41746/30939 +f 41734/41734/30928 41746/41746/30939 41732/41732/30926 +f 41735/41735/30929 41747/41747/30940 41745/41745/30938 +f 41735/41735/30929 41745/41745/30938 41734/41734/30928 +f 41607/41607/30803 41608/41608/30804 41747/41747/30940 +f 41607/41607/30803 41747/41747/30940 41735/41735/30929 +f 41748/41748/30941 41749/41749/30942 41750/41750/30943 +f 41748/41748/30941 41750/41750/30943 41744/41744/30937 +f 41747/41747/30940 41751/41751/30944 41752/41752/30942 +f 41747/41747/30940 41752/41752/30942 41745/41745/30938 +f 41608/41608/30804 41609/41609/30805 41751/41751/30944 +f 41608/41608/30804 41751/41751/30944 41747/41747/30940 +f 41740/41740/30934 41753/41753/30945 41754/41754/30946 +f 41740/41740/30934 41754/41754/30946 41741/41741/30935 +f 41742/41742/30936 41755/41755/30947 41753/41753/30945 +f 41742/41742/30936 41753/41753/30945 41740/41740/30934 +f 41744/41744/30937 41750/41750/30943 41755/41755/30947 +f 41744/41744/30937 41755/41755/30947 41742/41742/30936 +f 41753/41753/30945 41756/41756/30948 41757/41757/30949 +f 41753/41753/30945 41757/41757/30949 41754/41754/30946 +f 41755/41755/30947 41758/41758/30950 41756/41756/30948 +f 41755/41755/30947 41756/41756/30948 41753/41753/30945 +f 41750/41750/30943 41759/41759/30951 41758/41758/30950 +f 41750/41750/30943 41758/41758/30950 41755/41755/30947 +f 41749/41749/30942 41760/41760/30952 41759/41759/30951 +f 41749/41749/30942 41759/41759/30951 41750/41750/30943 +f 41751/41751/30944 41761/41761/30953 41762/41762/30952 +f 41751/41751/30944 41762/41762/30952 41752/41752/30942 +f 41609/41609/30805 41610/41610/30806 41761/41761/30953 +f 41609/41609/30805 41761/41761/30953 41751/41751/30944 +f 41760/41760/30952 41763/41763/30954 41764/41764/30955 +f 41760/41760/30952 41764/41764/30955 41759/41759/30951 +f 41761/41761/30953 41765/41765/30956 41766/41766/30954 +f 41761/41761/30953 41766/41766/30954 41762/41762/30952 +f 41610/41610/30806 41611/41611/30807 41765/41765/30956 +f 41610/41610/30806 41765/41765/30956 41761/41761/30953 +f 41756/41756/30948 41767/41767/30957 41768/41768/30958 +f 41756/41756/30948 41768/41768/30958 41757/41757/30949 +f 41758/41758/30950 41769/41769/30959 41767/41767/30957 +f 41758/41758/30950 41767/41767/30957 41756/41756/30948 +f 41759/41759/30951 41764/41764/30955 41769/41769/30959 +f 41759/41759/30951 41769/41769/30959 41758/41758/30950 +f 41767/41767/30957 41770/41770/30960 41771/41771/30961 +f 41767/41767/30957 41771/41771/30961 41768/41768/30958 +f 41769/41769/30959 41772/41772/30962 41770/41770/30960 +f 41769/41769/30959 41770/41770/30960 41767/41767/30957 +f 41764/41764/30955 41773/41773/30963 41772/41772/30962 +f 41764/41764/30955 41772/41772/30962 41769/41769/30959 +f 41763/41763/30954 41774/41774/30964 41773/41773/30963 +f 41763/41763/30954 41773/41773/30963 41764/41764/30955 +f 41765/41765/30956 41775/41775/30965 41776/41776/30966 +f 41765/41765/30956 41776/41776/30966 41766/41766/30954 +f 41611/41611/30807 41612/41612/30808 41775/41775/30965 +f 41611/41611/30807 41775/41775/30965 41765/41765/30956 +f 41775/41775/30965 41777/41777/30967 41778/41778/30968 +f 41775/41775/30965 41778/41778/30968 41776/41776/30966 +f 41612/41612/30808 41613/41613/30809 41777/41777/30967 +f 41612/41612/30808 41777/41777/30967 41775/41775/30965 +f 41770/41770/30960 41779/41779/30969 41780/41780/30970 +f 41770/41770/30960 41780/41780/30970 41771/41771/30961 +f 41772/41772/30962 41781/41781/30971 41779/41779/30969 +f 41772/41772/30962 41779/41779/30969 41770/41770/30960 +f 41773/41773/30963 41782/41782/30972 41781/41781/30971 +f 41773/41773/30963 41781/41781/30971 41772/41772/30962 +f 41774/41774/30964 41783/41783/30973 41782/41782/30972 +f 41774/41774/30964 41782/41782/30972 41773/41773/30963 +f 41781/41781/30971 41784/41784/30974 41785/41785/30975 +f 41781/41781/30971 41785/41785/30975 41779/41779/30969 +f 41782/41782/30972 41786/41786/30976 41784/41784/30974 +f 41782/41782/30972 41784/41784/30974 41781/41781/30971 +f 41783/41783/30973 41787/41787/30977 41786/41786/30976 +f 41783/41783/30973 41786/41786/30976 41782/41782/30972 +f 41777/41777/30967 41788/41788/30978 41789/41789/30977 +f 41777/41777/30967 41789/41789/30977 41778/41778/30968 +f 41613/41613/30809 41614/41614/30810 41788/41788/30978 +f 41613/41613/30809 41788/41788/30978 41777/41777/30967 +f 41779/41779/30969 41785/41785/30975 41790/41790/30979 +f 41779/41779/30969 41790/41790/30979 41780/41780/30970 +f 41614/41614/30810 41615/41615/30811 41791/41791/30980 +f 41614/41614/30810 41791/41791/30980 41788/41788/30978 +f 41785/41785/30975 41792/41792/30981 41793/41793/30982 +f 41785/41785/30975 41793/41793/30982 41790/41790/30979 +f 41784/41784/30974 41794/41794/30983 41792/41792/30981 +f 41784/41784/30974 41792/41792/30981 41785/41785/30975 +f 41786/41786/30976 41795/41795/30984 41794/41794/30983 +f 41786/41786/30976 41794/41794/30983 41784/41784/30974 +f 41787/41787/30977 41796/41796/30985 41795/41795/30984 +f 41787/41787/30977 41795/41795/30984 41786/41786/30976 +f 41788/41788/30978 41791/41791/30980 41797/41797/30985 +f 41788/41788/30978 41797/41797/30985 41789/41789/30977 +f 41794/41794/30983 41798/41798/30986 41799/41799/30987 +f 41794/41794/30983 41799/41799/30987 41792/41792/30981 +f 41795/41795/30984 41800/41800/30988 41798/41798/30986 +f 41795/41795/30984 41798/41798/30986 41794/41794/30983 +f 41796/41796/30985 41801/41801/30989 41800/41800/30988 +f 41796/41796/30985 41800/41800/30988 41795/41795/30984 +f 41791/41791/30980 41802/41802/30990 41803/41803/30989 +f 41791/41791/30980 41803/41803/30989 41797/41797/30985 +f 41615/41615/30811 41616/41616/30812 41802/41802/30990 +f 41615/41615/30811 41802/41802/30990 41791/41791/30980 +f 41792/41792/30981 41799/41799/30987 41804/41804/30991 +f 41792/41792/30981 41804/41804/30991 41793/41793/30982 +f 41616/41616/30812 41617/41617/30813 41805/41805/30992 +f 41616/41616/30812 41805/41805/30992 41802/41802/30990 +f 41799/41799/30987 41806/41806/30993 41807/41807/30994 +f 41799/41799/30987 41807/41807/30994 41804/41804/30991 +f 41798/41798/30986 41808/41808/30995 41806/41806/30993 +f 41798/41798/30986 41806/41806/30993 41799/41799/30987 +f 41800/41800/30988 41809/41809/30996 41808/41808/30995 +f 41800/41800/30988 41808/41808/30995 41798/41798/30986 +f 41801/41801/30989 41810/41810/30997 41809/41809/30996 +f 41801/41801/30989 41809/41809/30996 41800/41800/30988 +f 41802/41802/30990 41805/41805/30992 41811/41811/30997 +f 41802/41802/30990 41811/41811/30997 41803/41803/30989 +f 41809/41809/30996 41812/41812/30998 41813/41813/30999 +f 41809/41809/30996 41813/41813/30999 41808/41808/30995 +f 41811/41811/30997 41814/41814/31000 41815/41815/31001 +f 41811/41811/30997 41815/41815/31001 41816/41816/30996 +f 41805/41805/30992 41817/41817/31002 41814/41814/31000 +f 41805/41805/30992 41814/41814/31000 41811/41811/30997 +f 41617/41617/30813 41618/41618/30814 41817/41817/31002 +f 41617/41617/30813 41817/41817/31002 41805/41805/30992 +f 41806/41806/30993 41818/41818/31003 41819/41819/31004 +f 41806/41806/30993 41819/41819/31004 41807/41807/30994 +f 41808/41808/30995 41813/41813/30999 41818/41818/31003 +f 41808/41808/30995 41818/41818/31003 41806/41806/30993 +f 41818/41818/31003 41820/41820/31005 41821/41821/31006 +f 41818/41818/31003 41821/41821/31006 41819/41819/31004 +f 41813/41813/30999 41822/41822/31007 41820/41820/31005 +f 41813/41813/30999 41820/41820/31005 41818/41818/31003 +f 41815/41815/31001 41823/41823/31008 41824/41824/31007 +f 41815/41815/31001 41824/41824/31007 41825/41825/30999 +f 41814/41814/31000 41826/41826/31009 41823/41823/31008 +f 41814/41814/31000 41823/41823/31008 41815/41815/31001 +f 41817/41817/31002 41827/41827/31010 41826/41826/31009 +f 41817/41817/31002 41826/41826/31009 41814/41814/31000 +f 41618/41618/30814 41619/41619/30815 41827/41827/31010 +f 41618/41618/30814 41827/41827/31010 41817/41817/31002 +f 41823/41823/31008 41828/41828/31011 41829/41829/31012 +f 41823/41823/31008 41829/41829/31012 41824/41824/31007 +f 41826/41826/31009 41830/41830/31013 41828/41828/31011 +f 41826/41826/31009 41828/41828/31011 41823/41823/31008 +f 41827/41827/31010 41831/41831/31014 41830/41830/31013 +f 41827/41827/31010 41830/41830/31013 41826/41826/31009 +f 41619/41619/30815 41620/41620/30816 41831/41831/31014 +f 41619/41619/30815 41831/41831/31014 41827/41827/31010 +f 41820/41820/31005 41832/41832/31015 41833/41833/31016 +f 41820/41820/31005 41833/41833/31016 41821/41821/31006 +f 41824/41824/31007 41829/41829/31012 41834/41834/31017 +f 41824/41824/31007 41834/41834/31017 41835/41835/31005 +f 41834/41834/31017 41621/41621/30817 41624/41624/30820 +f 41834/41834/31017 41624/41624/30820 41836/41836/31016 +f 41829/41829/31012 41625/41625/30821 41621/41621/30817 +f 41829/41829/31012 41621/41621/30817 41834/41834/31017 +f 41828/41828/31011 41627/41627/30823 41625/41625/30821 +f 41828/41828/31011 41625/41625/30821 41829/41829/31012 +f 41830/41830/31013 41629/41629/30825 41627/41627/30823 +f 41830/41830/31013 41627/41627/30823 41828/41828/31011 +f 41831/41831/31014 41631/41631/30827 41629/41629/30825 +f 41831/41831/31014 41629/41629/30825 41830/41830/31013 +f 41620/41620/30816 41590/41590/30786 41631/41631/30827 +f 41620/41620/30816 41631/41631/30827 41831/41831/31014 +o Cube.052__0 +v 0.692764 -1.064596 -1.660099 +v 0.691216 -1.035060 -1.640464 +v 0.703572 -1.009459 -1.677789 +v 0.705127 -1.039166 -1.697538 +v 0.691216 -1.035060 -1.640464 +v 0.718282 -1.013404 -1.616223 +v 0.730795 -0.987677 -1.653407 +v 0.703572 -1.009459 -1.677789 +v 0.744031 -0.962403 -1.690648 +v 0.716888 -0.984121 -1.714959 +v 0.716888 -0.984121 -1.714959 +v 0.718439 -1.013741 -1.734651 +v 0.912080 -1.014941 -1.667876 +v 0.913298 -1.038212 -1.683346 +v 0.899982 -1.063549 -1.646176 +v 0.898768 -1.040365 -1.630763 +v 0.913298 -1.038212 -1.683346 +v 0.891973 -1.055274 -1.702445 +v 0.878737 -1.080547 -1.665204 +v 0.899982 -1.063549 -1.646176 +v 0.866225 -1.106275 -1.628020 +v 0.887627 -1.089151 -1.608851 +v 0.887627 -1.089151 -1.608851 +v 0.886404 -1.065795 -1.593324 +v 0.935328 -1.015085 -1.659859 +v 0.924740 -0.985409 -1.643283 +v 0.912034 -1.010750 -1.605903 +v 0.922652 -1.040513 -1.622527 +v 0.924740 -0.985409 -1.643283 +v 0.888624 -0.963299 -1.640787 +v 0.875812 -0.988575 -1.603399 +v 0.912034 -1.010750 -1.605903 +v 0.862460 -1.014297 -1.566504 +v 0.898472 -1.036344 -1.568993 +v 0.898472 -1.036344 -1.568993 +v 0.909031 -1.065936 -1.585522 +v 0.761793 -0.973553 -1.692065 +v 0.817347 -0.967829 -1.668762 +v 0.804389 -0.993428 -1.631646 +v 0.749043 -0.999132 -1.654862 +v 0.875388 -0.974257 -1.652893 +v 0.862213 -0.999833 -1.615836 +v 0.849578 -1.024962 -1.578286 +v 0.791325 -1.018511 -1.594214 +v 0.735569 -1.024256 -1.617601 +v 0.765143 -1.065528 -1.753723 +v 0.839023 -1.073710 -1.733523 +v 0.826065 -1.099310 -1.696407 +v 0.751969 -1.091105 -1.716666 +v 0.909736 -1.066423 -1.703861 +v 0.896986 -1.092003 -1.666659 +v 0.883512 -1.117127 -1.629398 +v 0.813002 -1.124393 -1.658975 +v 0.739333 -1.116234 -1.679117 +v 0.814744 -0.955116 -1.660987 +v 0.801715 -0.980369 -1.623658 +v 0.788792 -1.006139 -1.586646 +v 0.716070 -1.028807 -1.597953 +v 0.782924 -1.021918 -1.569911 +v 0.783319 -1.018291 -1.570991 +v 0.714035 -1.025431 -1.600053 +v 0.852771 -1.029654 -1.550813 +v 0.855705 -1.026308 -1.551199 +v 0.774478 -1.050465 -1.769738 +v 0.844961 -1.058271 -1.750466 +v 0.844558 -1.061855 -1.749360 +v 0.771589 -1.053774 -1.769311 +v 0.912423 -1.051319 -1.722169 +v 0.914398 -1.054658 -1.720065 +v 0.778379 -1.054570 -1.741617 +v 0.836421 -1.060998 -1.725748 +v 0.842255 -1.050605 -1.742480 +v 0.783302 -1.044076 -1.758598 +v 0.898680 -1.044791 -1.718811 +v 0.902279 -1.044952 -1.721360 +v 0.843475 -1.051011 -1.746026 +v 0.782037 -1.044207 -1.762825 +v 0.822881 -0.955973 -1.684599 +v 0.881834 -0.962502 -1.668481 +v 0.766456 -0.961787 -1.708268 +v 0.764481 -0.958448 -1.710372 +v 0.823285 -0.952389 -1.685706 +v 0.884723 -0.959193 -1.668907 +v 0.903761 -0.991627 -1.654853 +v 0.910652 -0.980145 -1.670473 +v 0.919101 -1.003825 -1.683699 +v 0.903761 -0.991627 -1.654853 +v 0.910652 -0.980145 -1.670473 +v 0.910652 -0.980145 -1.670473 +v 0.881834 -0.962502 -1.668481 +v 0.884723 -0.959193 -1.668907 +v 0.914756 -0.977580 -1.670983 +v 0.919101 -1.003825 -1.683699 +v 0.923562 -1.002259 -1.684767 +v 0.810469 -1.112020 -1.651407 +v 0.804995 -1.124173 -1.635752 +v 0.861978 -1.118302 -1.611850 +v 0.752216 -1.105569 -1.667335 +v 0.745460 -1.117580 -1.652030 +v 0.742527 -1.120925 -1.651643 +v 0.804600 -1.127800 -1.634671 +v 0.864012 -1.121678 -1.609750 +v 0.785430 -1.028606 -1.577300 +v 0.728447 -1.034478 -1.601202 +v 0.844965 -1.035200 -1.561022 +v 0.846274 -1.035033 -1.556756 +v 0.784201 -1.028158 -1.573727 +v 0.724789 -1.034280 -1.598649 +v 0.823391 -1.086250 -1.688419 +v 0.765567 -1.079846 -1.704229 +v 0.741688 -1.013885 -1.726634 +v 0.740469 -0.990615 -1.711163 +v 0.727798 -1.016130 -1.673889 +v 0.729013 -1.039314 -1.689302 +v 0.740469 -0.990615 -1.711163 +v 0.727798 -1.016130 -1.673889 +v 0.714167 -1.041381 -1.636770 +v 0.714167 -1.041381 -1.636770 +v 0.715390 -1.064736 -1.652297 +v 0.729921 -1.001059 -1.751543 +v 0.740023 -1.029371 -1.767356 +v 0.735919 -1.031936 -1.766846 +v 0.725461 -1.002626 -1.750474 +v 0.774478 -1.050465 -1.769738 +v 0.771589 -1.053774 -1.769311 +v 0.735919 -1.031936 -1.766846 +v 0.729028 -1.043418 -1.751227 +v 0.725461 -1.002626 -1.750474 +v 0.735919 -1.031936 -1.766846 +v 0.729028 -1.043418 -1.751227 +v 0.936838 -1.002341 -1.680189 +v 0.926737 -0.974029 -1.664375 +v 0.929218 -0.974642 -1.660233 +v 0.939675 -1.003953 -1.676605 +v 0.892282 -0.952935 -1.661994 +v 0.893547 -0.952805 -1.657768 +v 0.929218 -0.974642 -1.660233 +v 0.893547 -0.952805 -1.657768 +v 0.939675 -1.003953 -1.676605 +v 0.929218 -0.974642 -1.660233 +v 0.892282 -0.952935 -1.661994 +v 0.821799 -0.945129 -1.681265 +v 0.820578 -0.944724 -1.677719 +v 0.754337 -0.952081 -1.709563 +v 0.750738 -0.951920 -1.707014 +v 0.883851 -1.100800 -1.592259 +v 0.882601 -1.076931 -1.576391 +v 0.883851 -1.100800 -1.592259 +v 0.883851 -1.100800 -1.592259 +v 0.861978 -1.118302 -1.611850 +v 0.864012 -1.121678 -1.609750 +v 0.886817 -1.103430 -1.589324 +v 0.882601 -1.076931 -1.576391 +v 0.885514 -1.078543 -1.572780 +v 0.691874 -1.077344 -1.639555 +v 0.690407 -1.049340 -1.620937 +v 0.687440 -1.046710 -1.623872 +v 0.688960 -1.075732 -1.643166 +v 0.716070 -1.028807 -1.597953 +v 0.714035 -1.025431 -1.600053 +v 0.687440 -1.046710 -1.623872 +v 0.688960 -1.075732 -1.643166 +v 0.687440 -1.046710 -1.623872 +v 0.896927 -1.078614 -1.568844 +v 0.898393 -1.106618 -1.587461 +v 0.902985 -1.106070 -1.589180 +v 0.901465 -1.077048 -1.569886 +v 0.872731 -1.127151 -1.610445 +v 0.876390 -1.127349 -1.612999 +v 0.902985 -1.106070 -1.589180 +v 0.876390 -1.127349 -1.612999 +v 0.910577 -1.095471 -1.605157 +v 0.901465 -1.077048 -1.569886 +v 0.902985 -1.106070 -1.589180 +v 0.910577 -1.095471 -1.605157 +v 0.872731 -1.127151 -1.610445 +v 0.805877 -1.134040 -1.638488 +v 0.807106 -1.134488 -1.642061 +v 0.736030 -1.126304 -1.657586 +v 0.734720 -1.126471 -1.661852 +v 0.852771 -1.029654 -1.550813 +v 0.782924 -1.021918 -1.569911 +v 0.783562 -1.025038 -1.571819 +v 0.849523 -1.032343 -1.553784 +v 0.720429 -1.031544 -1.598301 +v 0.724789 -1.034280 -1.598649 +v 0.784201 -1.028158 -1.573727 +v 0.846274 -1.035033 -1.556756 +v 0.736030 -1.126304 -1.657586 +v 0.805877 -1.134040 -1.638488 +v 0.805239 -1.130919 -1.636580 +v 0.739278 -1.123614 -1.654614 +v 0.868372 -1.124414 -1.610098 +v 0.804600 -1.127800 -1.634671 +v 0.742527 -1.120925 -1.651643 +v 0.886916 -1.050557 -1.553173 +v 0.881767 -1.052083 -1.556013 +v 0.891220 -1.078579 -1.570812 +v 0.876618 -1.053610 -1.558853 +v 0.701884 -1.105401 -1.655226 +v 0.707033 -1.103875 -1.652386 +v 0.697580 -1.077379 -1.637587 +v 0.712183 -1.102348 -1.649546 +v 0.703286 -1.077415 -1.635619 +v 0.706575 -1.051980 -1.620792 +v 0.707824 -1.075849 -1.636661 +v 0.706575 -1.051980 -1.620792 +v 0.706575 -1.051980 -1.620792 +v 0.728447 -1.034478 -1.601202 +v 0.701983 -1.052528 -1.619074 +v 0.707824 -1.075849 -1.636661 +v 0.938318 -1.030600 -1.698976 +v 0.931585 -1.028745 -1.700060 +v 0.930200 -1.002300 -1.682478 +v 0.912423 -1.051319 -1.722169 +v 0.907351 -1.048135 -1.721764 +v 0.902279 -1.044952 -1.721360 +v 0.924851 -1.026891 -1.701143 +v 0.754337 -0.952081 -1.709563 +v 0.821799 -0.945129 -1.681265 +v 0.822542 -0.948759 -1.683486 +v 0.759409 -0.955265 -1.709968 +v 0.888503 -0.956064 -1.665451 +v 0.823285 -0.952389 -1.685706 +v 0.764481 -0.958448 -1.710372 +v 0.844961 -1.058271 -1.750466 +v 0.844218 -1.054641 -1.748246 +v 0.778258 -1.047336 -1.766281 +v 0.782037 -1.044207 -1.762825 +v 0.843475 -1.051011 -1.746026 +v 0.728442 -0.972800 -1.732756 +v 0.735175 -0.974655 -1.731672 +v 0.736560 -1.001101 -1.749253 +v 0.741909 -0.976510 -1.730588 +v 0.743199 -1.001142 -1.746964 +v 0.750006 -1.037200 -1.739656 +v 0.754483 -1.026433 -1.756606 +v 0.746034 -1.002753 -1.743380 +v 0.750006 -1.037200 -1.739656 +v 0.754483 -1.026433 -1.756606 +v 0.754483 -1.026433 -1.756606 +v 0.783302 -1.044076 -1.758598 +v 0.752004 -1.025820 -1.760748 +v 0.746034 -1.002753 -1.743380 +v 0.920747 -0.975805 -1.667679 +v 0.892605 -1.105024 -1.588393 +v 0.891091 -1.047971 -1.553645 +v 0.855705 -1.026308 -1.551199 +v 0.891091 -1.047971 -1.553645 +v 0.891091 -1.047971 -1.553645 +v 0.878055 -1.042396 -1.580254 +v 0.874068 -1.053017 -1.563034 +v 0.878055 -1.042396 -1.580254 +v 0.874068 -1.053017 -1.563034 +v 0.874068 -1.053017 -1.563034 +v 0.844965 -1.035200 -1.561022 +v 0.941207 -1.033208 -1.696054 +v 0.914398 -1.054658 -1.720065 +v 0.941207 -1.033208 -1.696054 +v 0.936879 -1.044706 -1.679551 +v 0.941207 -1.033208 -1.696054 +v 0.936879 -1.044706 -1.679551 +v 0.920339 -1.027461 -1.699413 +v 0.920339 -1.027461 -1.699413 +v 0.920339 -1.027461 -1.699413 +v 0.898680 -1.044791 -1.718811 +v 0.924209 -1.070221 -1.642277 +v 0.924209 -1.070221 -1.642277 +v 0.890481 -1.017138 -1.617790 +v 0.890481 -1.017138 -1.617790 +v 0.744797 -0.979118 -1.727666 +v 0.744797 -0.979118 -1.727666 +v 0.744797 -0.979118 -1.727666 +v 0.766456 -0.961787 -1.708268 +v 0.746013 -1.027596 -1.764052 +v 0.723739 -1.088136 -1.665367 +v 0.716357 -1.099762 -1.650018 +v 0.723739 -1.088136 -1.665367 +v 0.716357 -1.099762 -1.650018 +v 0.716357 -1.099762 -1.650018 +v 0.745460 -1.117580 -1.652030 +v 0.696195 -1.050934 -1.620006 +v 0.699334 -1.104808 -1.659407 +v 0.734720 -1.126471 -1.661852 +v 0.699334 -1.104808 -1.659407 +v 0.703321 -1.094187 -1.676628 +v 0.699334 -1.104808 -1.659407 +v 0.703321 -1.094187 -1.676628 +v 0.723929 -0.973371 -1.731025 +v 0.750738 -0.951920 -1.707014 +v 0.723929 -0.973371 -1.731025 +v 0.723929 -0.973371 -1.731025 +v 0.737300 -1.062541 -1.702276 +v 0.737300 -1.062541 -1.702276 +v 0.715747 -1.068929 -1.714163 +v 0.715747 -1.068929 -1.714163 +vt 0.853951 0.004738 +vt 0.853779 0.010120 +vt 0.854052 0.010096 +vt 0.854215 0.005013 +vt 0.854889 0.015390 +vt 0.855100 0.015072 +vt 0.863437 0.014638 +vt 0.863609 0.009255 +vt 0.863336 0.009279 +vt 0.863173 0.014362 +vt 0.862499 0.003986 +vt 0.862288 0.004303 +vt 0.857991 0.001699 +vt 0.855563 0.002248 +vt 0.855737 0.002662 +vt 0.858030 0.002144 +vt 0.859397 0.017677 +vt 0.861826 0.017128 +vt 0.861651 0.016714 +vt 0.859358 0.017232 +vt 0.044673 0.019057 +vt 0.047123 0.018501 +vt 0.046920 0.018019 +vt 0.044627 0.018540 +vt 0.048747 0.015987 +vt 0.048439 0.015666 +vt 0.039165 0.006005 +vt 0.038996 0.011437 +vt 0.039315 0.011409 +vt 0.039473 0.006326 +vt 0.040121 0.016753 +vt 0.040367 0.016384 +vt 0.048916 0.010555 +vt 0.048597 0.010583 +vt 0.047791 0.005239 +vt 0.047545 0.005608 +vt 0.043239 0.002935 +vt 0.040789 0.003491 +vt 0.040992 0.003973 +vt 0.043285 0.003452 +vt 0.042163 0.018941 +vt 0.042278 0.018432 +vt 0.860478 0.001816 +vt 0.860379 0.002254 +vt 0.045749 0.003051 +vt 0.045634 0.003560 +vt 0.856910 0.017560 +vt 0.857010 0.017122 +vt 0.554314 0.776717 +vt 0.551712 0.776714 +vt 0.551697 0.780183 +vt 0.554314 0.780186 +vt 0.037069 0.019304 +vt 0.037057 0.017312 +vt 0.033586 0.017344 +vt 0.033599 0.019349 +vt 0.030117 0.017320 +vt 0.030129 0.019319 +vt 0.551704 0.783652 +vt 0.554314 0.783655 +vt 0.597195 0.776715 +vt 0.595145 0.776712 +vt 0.595152 0.780181 +vt 0.597195 0.780184 +vt 0.911664 0.857373 +vt 0.911655 0.855803 +vt 0.908185 0.855779 +vt 0.908195 0.857343 +vt 0.904715 0.855812 +vt 0.904725 0.857388 +vt 0.595137 0.783651 +vt 0.597195 0.783653 +vt 0.559653 0.783655 +vt 0.562263 0.783652 +vt 0.562270 0.780183 +vt 0.559653 0.780186 +vt 0.030129 0.003445 +vt 0.030117 0.006278 +vt 0.033586 0.006269 +vt 0.033599 0.003428 +vt 0.037057 0.006301 +vt 0.037069 0.003476 +vt 0.562255 0.776714 +vt 0.559653 0.776717 +vt 0.901033 0.855803 +vt 0.901029 0.851581 +vt 0.897559 0.851573 +vt 0.897563 0.855779 +vt 0.901033 0.847128 +vt 0.897563 0.847136 +vt 0.894093 0.847105 +vt 0.894089 0.851574 +vt 0.894093 0.855812 +vt 0.923906 0.006603 +vt 0.923902 0.012271 +vt 0.927372 0.012279 +vt 0.927376 0.006594 +vt 0.923906 0.017645 +vt 0.927376 0.017669 +vt 0.930846 0.017636 +vt 0.930842 0.012278 +vt 0.930846 0.006625 +vt 0.030112 0.011946 +vt 0.033582 0.011954 +vt 0.037052 0.011953 +vt 0.038793 0.016978 +vt 0.038789 0.011897 +vt 0.038571 0.011935 +vt 0.038575 0.017201 +vt 0.038793 0.006538 +vt 0.038575 0.006381 +vt 0.922173 0.006809 +vt 0.922169 0.012217 +vt 0.922384 0.012255 +vt 0.922389 0.006656 +vt 0.922173 0.017344 +vt 0.922389 0.017563 +vt 0.911655 0.847128 +vt 0.911651 0.851581 +vt 0.913169 0.851597 +vt 0.913172 0.847074 +vt 0.913172 0.855885 +vt 0.913388 0.856104 +vt 0.913384 0.851635 +vt 0.913388 0.846921 +vt 0.902547 0.851597 +vt 0.902550 0.847074 +vt 0.902550 0.855885 +vt 0.902766 0.856104 +vt 0.902763 0.851635 +vt 0.902766 0.846921 +vt 0.599245 0.776712 +vt 0.599277 0.775196 +vt 0.597195 0.775198 +vt 0.901043 0.844902 +vt 0.902560 0.844813 +vt 0.042456 0.017642 +vt 0.040749 0.015811 +vt 0.040613 0.016014 +vt 0.042393 0.017922 +vt 0.044556 0.017738 +vt 0.044581 0.018022 +vt 0.904711 0.851574 +vt 0.903193 0.851592 +vt 0.903196 0.855922 +vt 0.904715 0.847105 +vt 0.903196 0.847024 +vt 0.902978 0.846868 +vt 0.902975 0.851630 +vt 0.902978 0.856146 +vt 0.892571 0.851592 +vt 0.892574 0.855922 +vt 0.892574 0.847024 +vt 0.892356 0.846868 +vt 0.892353 0.851630 +vt 0.892356 0.856146 +vt 0.908181 0.851573 +vt 0.908185 0.847136 +vt 0.592905 0.776715 +vt 0.590855 0.776712 +vt 0.590863 0.780181 +vt 0.592905 0.780184 +vt 0.901043 0.857373 +vt 0.897573 0.857343 +vt 0.894103 0.857388 +vt 0.590847 0.783651 +vt 0.592905 0.783653 +vt 0.045812 0.002770 +vt 0.043214 0.002651 +vt 0.047926 0.005036 +vt 0.922401 0.003859 +vt 0.923919 0.003770 +vt 0.554314 0.785172 +vt 0.556891 0.785169 +vt 0.556924 0.783652 +vt 0.042100 0.019222 +vt 0.044698 0.019341 +vt 0.039986 0.016956 +vt 0.028611 0.003534 +vt 0.028599 0.006332 +vt 0.559653 0.785172 +vt 0.562231 0.785169 +vt 0.028383 0.006484 +vt 0.028379 0.011892 +vt 0.028595 0.011930 +vt 0.028383 0.017019 +vt 0.028599 0.017238 +vt 0.595092 0.785169 +vt 0.597195 0.785172 +vt 0.903206 0.857533 +vt 0.860214 0.002978 +vt 0.861938 0.004828 +vt 0.862076 0.004621 +vt 0.860279 0.002692 +vt 0.858095 0.002878 +vt 0.858069 0.002588 +vt 0.856845 0.017846 +vt 0.859423 0.017967 +vt 0.854750 0.015597 +vt 0.038587 0.019159 +vt 0.554314 0.775198 +vt 0.551757 0.775195 +vt 0.860543 0.001530 +vt 0.857965 0.001409 +vt 0.862638 0.003779 +vt 0.932377 0.019484 +vt 0.932365 0.017526 +vt 0.930859 0.019629 +vt 0.559653 0.775198 +vt 0.557096 0.775195 +vt 0.557051 0.776714 +vt 0.932583 0.017303 +vt 0.932579 0.012222 +vt 0.932361 0.012260 +vt 0.932583 0.006863 +vt 0.932365 0.006706 +vt 0.855312 0.014755 +vt 0.854326 0.010072 +vt 0.854479 0.005289 +vt 0.863062 0.009304 +vt 0.862909 0.014087 +vt 0.855911 0.003076 +vt 0.861477 0.016299 +vt 0.859319 0.016787 +vt 0.590802 0.785169 +vt 0.592905 0.785172 +vt 0.892584 0.857533 +vt 0.857174 0.016398 +vt 0.855451 0.014548 +vt 0.857109 0.016684 +vt 0.859293 0.016497 +vt 0.048132 0.015346 +vt 0.046716 0.017538 +vt 0.039633 0.011380 +vt 0.039780 0.006646 +vt 0.047299 0.005978 +vt 0.048279 0.010612 +vt 0.041195 0.004455 +vt 0.043331 0.003970 +vt 0.594955 0.776712 +vt 0.594987 0.775196 +vt 0.592905 0.775198 +vt 0.911664 0.844902 +vt 0.913182 0.844813 +vt 0.045455 0.004350 +vt 0.047163 0.006181 +vt 0.045519 0.004070 +vt 0.043356 0.004254 +vt 0.855449 0.001978 +vt 0.853779 0.004558 +vt 0.562210 0.775195 +vt 0.038587 0.003606 +vt 0.894103 0.844871 +vt 0.892584 0.844741 +vt 0.599253 0.783651 +vt 0.599298 0.785169 +vt 0.856025 0.003347 +vt 0.854651 0.005469 +vt 0.047234 0.018765 +vt 0.048916 0.016163 +vt 0.557076 0.785169 +vt 0.557044 0.783652 +vt 0.922401 0.019537 +vt 0.923919 0.019644 +vt 0.913182 0.857480 +vt 0.595113 0.775196 +vt 0.046605 0.017273 +vt 0.047963 0.015170 +vt 0.927389 0.019674 +vt 0.557036 0.780183 +vt 0.897573 0.844919 +vt 0.599237 0.780181 +vt 0.902560 0.857480 +vt 0.590823 0.775196 +vt 0.041307 0.004719 +vt 0.039949 0.006822 +vt 0.904725 0.844871 +vt 0.903206 0.844741 +vt 0.594963 0.783651 +vt 0.595008 0.785169 +vt 0.861363 0.016029 +vt 0.862737 0.013907 +vt 0.861939 0.017398 +vt 0.863609 0.014818 +vt 0.556871 0.775195 +vt 0.556916 0.776714 +vt 0.932377 0.003931 +vt 0.930859 0.003801 +vt 0.040677 0.003227 +vt 0.038996 0.005830 +vt 0.551737 0.785169 +vt 0.028611 0.019212 +vt 0.908195 0.844919 +vt 0.594948 0.780181 +vt 0.927389 0.003753 +vt 0.556931 0.780183 +vn -0.1906 -0.1292 0.9731 +vn -0.3248 -0.1039 0.9401 +vn -0.2770 -0.5420 0.7934 +vn -0.3248 -0.1040 0.9401 +vn -0.4512 -0.1276 0.8833 +vn -0.3052 -0.8409 0.4470 +vn -0.1694 -0.8631 0.4757 +vn -0.2770 -0.5420 0.7935 +vn -0.3051 -0.8409 0.4470 +vn -0.2770 -0.5419 0.7935 +vn -0.0445 -0.8425 0.5369 +vn -0.1694 -0.8632 0.4757 +vn 0.0591 -0.5120 0.8569 +vn 0.0156 -0.3230 0.9463 +vn 0.0592 -0.5120 0.8569 +vn -0.2769 -0.5420 0.7934 +vn -0.2769 -0.5420 0.7935 +vn -0.5804 -0.5080 0.6364 +vn -0.5260 -0.6759 0.5161 +vn -0.5804 -0.5081 0.6364 +vn -0.5261 -0.6759 0.5161 +vn 0.5846 0.5071 -0.6333 +vn 0.6033 0.3156 -0.7324 +vn 0.2769 0.5420 -0.7934 +vn 0.5847 0.5070 -0.6333 +vn 0.2770 0.5420 -0.7934 +vn 0.4531 0.1223 -0.8830 +vn 0.0412 0.8451 -0.5331 +vn 0.1679 0.8659 -0.4712 +vn 0.0411 0.8451 -0.5330 +vn 0.2769 0.5421 -0.7934 +vn 0.1679 0.8659 -0.4713 +vn 0.3055 0.8434 -0.4420 +vn 0.2770 0.5420 -0.7935 +vn 0.3249 0.0985 -0.9406 +vn 0.3250 0.0985 -0.9406 +vn 0.1889 0.1238 -0.9742 +vn 0.2770 0.5419 -0.7935 +vn -0.0644 0.5110 -0.8571 +vn -0.0942 0.6809 -0.7263 +vn -0.0644 0.5111 -0.8571 +vn 0.5294 0.6770 -0.5113 +vn -0.0446 -0.8425 0.5368 +vn 0.0886 -0.6798 0.7281 +vn -0.0446 -0.8425 0.5369 +vn 0.0887 -0.6798 0.7281 +vn 0.0886 -0.6798 0.7280 +vn 0.1888 0.1240 -0.9742 +vn -0.0202 0.3195 -0.9474 +vn 0.1888 0.1239 -0.9742 +vn 0.2769 0.5420 -0.7935 +vn -0.0201 0.3194 -0.9474 +vn -0.0202 0.3194 -0.9474 +vn -0.4512 -0.1275 0.8833 +vn -0.5991 -0.3192 0.7343 +vn -0.9592 -0.0241 -0.2817 +vn -0.9196 0.3925 0.0152 +vn -0.9064 0.4216 -0.0241 +vn -0.9463 0.0040 -0.3232 +vn -0.9196 0.3926 0.0152 +vn -0.5326 0.7552 0.3822 +vn -0.5206 0.7775 0.3527 +vn -0.5129 0.7936 0.3273 +vn -0.8949 0.4426 -0.0568 +vn -0.8949 0.4426 -0.0569 +vn -0.9342 0.0264 -0.3558 +vn -0.9341 0.0265 -0.3560 +vn -0.8938 0.4451 -0.0553 +vn -0.9061 0.4224 -0.0234 +vn -0.8937 0.4452 -0.0553 +vn -0.5094 0.7950 0.3294 +vn -0.5194 0.7780 0.3535 +vn -0.5279 0.7569 0.3852 +vn -0.9185 0.3950 0.0185 +vn -0.9593 -0.0243 -0.2814 +vn 0.9552 0.0147 0.2957 +vn 0.7446 0.4325 0.5085 +vn 0.7332 0.4115 0.5414 +vn 0.9444 -0.0078 0.3288 +vn 0.2109 0.7891 0.5769 +vn 0.2011 0.7731 0.6016 +vn 0.7332 0.4115 0.5413 +vn 0.1921 0.7507 0.6321 +vn 0.7191 0.3824 0.5803 +vn 0.7190 0.3824 0.5803 +vn 0.9286 -0.0358 0.3693 +vn 0.5252 -0.7641 -0.3746 +vn 0.1785 -0.8274 -0.5324 +vn 0.1714 -0.8415 -0.5123 +vn 0.5179 -0.7809 -0.3493 +vn -0.1911 -0.7597 -0.6216 +vn -0.2012 -0.7764 -0.5973 +vn -0.2097 -0.7976 -0.5656 +vn 0.1625 -0.8584 -0.4865 +vn 0.5049 -0.8020 -0.3192 +vn -0.1952 -0.7583 -0.6220 +vn 0.1785 -0.8275 -0.5324 +vn -0.2026 -0.7759 -0.5974 +vn 0.5286 -0.7628 -0.3724 +vn 0.5191 -0.7804 -0.3486 +vn 0.5096 -0.8001 -0.3164 +vn 0.1625 -0.8583 -0.4867 +vn -0.2151 -0.7956 -0.5663 +vn -0.1655 0.8528 0.4953 +vn -0.1726 0.8392 0.5157 +vn -0.1814 0.8214 0.5407 +vn -0.2599 0.5901 0.7644 +vn -0.5988 0.4908 0.6329 +vn -0.1906 -0.1293 0.9731 +vn 0.0868 0.4866 0.8693 +vn 0.3250 0.0986 -0.9406 +vn 0.2572 -0.6009 -0.7568 +vn -0.0931 -0.4984 -0.8619 +vn 0.4531 0.1222 -0.8830 +vn 0.5991 -0.5027 -0.6232 +vn 0.2069 0.7906 0.5763 +vn -0.0602 0.9795 0.1921 +vn 0.2707 0.9391 0.2118 +vn -0.3332 0.9428 0.0035 +vn 0.0819 0.7577 -0.6475 +vn 0.1841 0.8347 -0.5190 +vn 0.3429 0.7561 -0.5575 +vn 0.2606 -0.5874 -0.7662 +vn -0.0403 -0.4882 -0.8718 +vn 0.5637 -0.4920 -0.6635 +vn 0.4427 0.2688 -0.8554 +vn 0.3228 0.1572 -0.9333 +vn 0.1817 0.2705 -0.9454 +vn -0.7219 -0.3942 -0.5687 +vn -0.4746 -0.0902 -0.8756 +vn -0.6881 0.2708 -0.6732 +vn 0.1816 0.2705 -0.9454 +vn 0.0822 0.4287 -0.8997 +vn -0.6880 0.2709 -0.6732 +vn -0.0134 0.5197 -0.8542 +vn -0.1814 0.8213 0.5408 +vn -0.2633 0.5760 0.7739 +vn -0.5648 0.4785 0.6723 +vn 0.1866 0.7525 0.6316 +vn 0.0356 0.4747 0.8794 +vn -0.1830 -0.2746 0.9440 +vn -0.3226 -0.1621 0.9325 +vn -0.4408 -0.2729 0.8551 +vn 0.0557 -0.9822 -0.1792 +vn 0.3264 -0.9452 0.0109 +vn -0.2742 -0.9415 -0.1961 +vn -0.3424 -0.7536 0.5612 +vn -0.1854 -0.8321 0.5228 +vn -0.0846 -0.7551 0.6501 +vn 0.1997 0.7736 0.6014 +vn 0.9552 0.0148 0.2955 +vn 0.9146 -0.4044 -0.0044 +vn 0.9042 -0.4261 0.0289 +vn 0.8880 -0.4546 0.0688 +vn 0.8880 -0.4546 0.0687 +vn 0.9285 -0.0360 0.3696 +vn -0.5446 -0.1310 -0.8284 +vn -0.7114 0.2549 -0.6549 +vn -0.5447 -0.1310 -0.8284 +vn -0.7240 -0.3922 -0.5674 +vn -0.7114 0.2550 -0.6549 +vn -0.7240 -0.3922 -0.5675 +vn 0.7858 0.6030 0.1374 +vn 0.9666 0.2446 -0.0763 +vn 0.3055 0.8434 -0.4419 +vn 0.3080 0.9189 0.2463 +vn 0.3080 0.9190 0.2462 +vn 0.9666 0.2445 -0.0763 +vn 0.7859 0.6029 0.1374 +vn -0.0656 0.9760 0.2077 +vn 0.0412 0.8450 -0.5331 +vn -0.3842 0.9232 0.0076 +vn -0.9080 0.0850 0.4103 +vn -0.9552 -0.2698 0.1213 +vn -0.9080 0.0851 0.4102 +vn -0.4408 -0.2730 0.8551 +vn -0.4913 -0.4282 0.7584 +vn -0.9553 -0.2697 0.1213 +vn -0.5390 -0.5171 0.6650 +vn -0.9349 0.1288 0.3307 +vn -0.9629 -0.2536 0.0923 +vn -0.5988 0.4909 0.6329 +vn -0.9349 0.1288 0.3308 +vn -0.9629 -0.2536 0.0922 +vn 0.0886 -0.6797 0.7281 +vn 0.6848 -0.6183 0.3858 +vn 0.6985 -0.2639 0.6652 +vn 0.3761 -0.9265 0.0050 +vn 0.3761 -0.9266 0.0050 +vn 0.8897 -0.4511 0.0705 +vn 0.6985 -0.2638 0.6652 +vn 0.0612 -0.9788 -0.1952 +vn -0.3095 -0.9223 -0.2315 +vn -0.0846 -0.7552 0.6501 +vn -0.1855 -0.8320 0.5228 +vn -0.2769 -0.5421 0.7934 +vn -0.3226 -0.1622 0.9325 +vn -0.4519 -0.6207 0.6407 +vn -0.0853 -0.4307 0.8984 +vn 0.0088 -0.5205 0.8538 +vn 0.6139 -0.6605 0.4322 +vn 0.6744 -0.2799 0.6833 +vn 0.3263 -0.9452 0.0109 +vn -0.0459 -0.6232 0.7807 +vn 0.0422 0.6242 -0.7801 +vn 0.3228 0.1573 -0.9333 +vn 0.4427 0.2689 -0.8554 +vn 0.3430 0.7561 -0.5574 +vn 0.1841 0.8348 -0.5189 +vn 0.4946 0.4261 -0.7575 +vn 0.5428 0.5163 -0.6624 +vn 0.7427 0.4350 0.5090 +vn 0.7595 0.6478 0.0593 +vn 0.9597 0.2607 -0.1049 +vn 0.2706 0.9391 0.2118 +vn 0.4546 0.6217 -0.6379 +vn 0.0155 -0.3230 0.9463 +vn 0.5336 0.1196 0.8372 +vn 0.0868 0.4865 0.8693 +vn 0.5337 0.1197 0.8372 +vn -0.7466 -0.4445 -0.4949 +vn -0.7571 -0.6520 -0.0405 +vn -0.7466 -0.4445 -0.4950 +vn -0.7571 -0.6521 -0.0405 +vn -0.2741 -0.9415 -0.1962 +vn 0.9380 -0.1401 -0.3172 +vn 0.9380 -0.1401 -0.3171 +vn 0.9155 -0.4024 -0.0021 +vn 0.9380 -0.1402 -0.3171 +vn -0.6274 0.6564 -0.4190 +vn -0.6274 0.6563 -0.4190 +vn 0.9046 -0.4253 0.0295 +vn 0.9045 -0.4253 0.0295 +vn -0.7345 -0.4160 -0.5362 +vn 0.9124 -0.0988 -0.3973 +vn 0.7161 0.3849 0.5822 +vn 0.4630 0.0765 0.8830 +vn 0.7162 0.3849 0.5822 +vn 0.4630 0.0765 0.8831 +vn 0.0357 0.4748 0.8794 +vn -0.7838 -0.6092 -0.1206 +vn -0.7490 -0.4410 -0.4946 +vn -0.6968 0.6122 -0.3739 +vn -0.3842 0.9232 0.0075 +vn -0.6968 0.6121 -0.3739 +vn -0.6968 0.6121 -0.3738 +vn 0.7325 0.4123 0.5417 +vn 0.7326 0.4122 0.5417 +vn -0.7351 -0.4152 -0.5359 +usemtl Scene_-_Root +s off +f 42017/41837/31018 42018/41838/31019 42019/41839/31020 +f 42017/41837/31018 42019/41839/31020 42020/41840/31020 +f 42018/41838/31021 41995/41841/31022 42021/41842/31020 +f 42018/41838/31019 42021/41842/31020 42019/41839/31020 +f 42025/41843/31023 42026/41844/31024 42027/41845/31025 +f 42025/41843/31026 42027/41845/31027 42028/41846/31027 +f 42026/41844/31024 42004/41847/31028 42029/41848/31025 +f 42026/41844/31029 42029/41848/31020 42027/41845/31020 +f 42000/41849/31030 42032/41850/31031 42033/41851/31020 +f 42000/41849/31032 42033/41851/31033 42034/41852/31033 +f 42032/41850/31031 42017/41837/31018 42020/41840/31033 +f 42032/41850/31031 42020/41840/31034 42033/41851/31034 +f 41991/41853/31035 42036/41854/31036 42037/41855/31033 +f 41991/41853/31037 42037/41855/31033 42038/41856/31033 +f 42036/41854/31038 42025/41843/31026 42028/41846/31025 +f 42036/41854/31038 42028/41846/31025 42037/41855/31025 +f 41967/41857/31039 42048/41858/31040 42049/41859/31041 +f 41967/41857/31042 42049/41859/31043 42050/41860/31043 +f 42048/41858/31040 42051/41861/31044 42052/41862/31041 +f 42048/41858/31040 42052/41862/31043 42049/41859/31043 +f 42055/41863/31045 42056/41864/31046 42057/41865/31043 +f 42055/41863/31047 42057/41865/31048 42058/41866/31048 +f 42056/41864/31049 41971/41867/31050 42059/41868/31051 +f 42056/41864/31046 42059/41868/31043 42057/41865/31043 +f 42051/41861/31044 42062/41869/31052 42063/41870/31043 +f 42051/41861/31044 42063/41870/31043 42052/41862/31043 +f 42062/41869/31053 41960/41871/31054 42064/41872/31055 +f 42062/41869/31053 42064/41872/31043 42063/41870/31043 +f 41956/41873/31056 42067/41874/31057 42068/41875/31041 +f 41956/41873/31058 42068/41875/31043 42069/41876/31043 +f 42067/41874/31057 42055/41863/31045 42058/41866/31041 +f 42067/41874/31057 42058/41866/31043 42068/41875/31043 +f 41971/41867/31050 41968/41877/31059 42081/41878/31043 +f 41971/41867/31050 42081/41878/31043 42059/41868/31043 +f 41968/41877/31059 41967/41857/31042 42050/41860/31043 +f 41968/41877/31059 42050/41860/31043 42081/41878/31043 +f 42004/41847/31060 42001/41879/31061 42082/41880/31020 +f 42004/41847/31062 42082/41880/31020 42029/41848/31020 +f 42001/41879/31063 42000/41849/31032 42034/41852/31033 +f 42001/41879/31064 42034/41852/31020 42082/41880/31020 +f 41960/41871/31065 41957/41881/31066 42111/41882/31043 +f 41960/41871/31067 42111/41882/31068 42064/41872/31068 +f 41957/41881/31069 41956/41873/31058 42069/41876/31043 +f 41957/41881/31070 42069/41876/31043 42111/41882/31043 +f 41995/41841/31071 41992/41883/31072 42118/41884/31020 +f 41995/41841/31022 42118/41884/31020 42021/41842/31020 +f 41992/41883/31072 41991/41853/31037 42038/41856/31033 +f 41992/41883/31072 42038/41856/31020 42118/41884/31020 +s 1 +f 41837/41885/31073 41838/41886/31074 41839/41887/31075 +f 41837/41885/31073 41839/41887/31075 41840/41888/31076 +f 41841/41889/31077 41842/41890/31078 41843/41891/31079 +f 41841/41889/31077 41843/41891/31079 41844/41892/31075 +f 41844/41892/31075 41843/41891/31079 41845/41893/31080 +f 41844/41892/31075 41845/41893/31080 41846/41894/31081 +f 41840/41888/31076 41839/41887/31075 41847/41895/31082 +f 41840/41888/31076 41847/41895/31082 41848/41896/31083 +f 41849/41897/31084 41850/41898/31085 41851/41899/31086 +f 41849/41897/31084 41851/41899/31086 41852/41900/31076 +f 41853/41901/31087 41854/41902/31088 41855/41903/31089 +f 41853/41901/31087 41855/41903/31089 41856/41904/31086 +f 41856/41904/31086 41855/41903/31089 41857/41905/31090 +f 41856/41904/31086 41857/41905/31090 41858/41906/31091 +f 41852/41900/31076 41851/41899/31086 41859/41907/31091 +f 41852/41900/31076 41859/41907/31091 41860/41908/31092 +f 41861/41909/31093 41862/41910/31094 41863/41911/31095 +f 41861/41909/31093 41863/41911/31095 41864/41912/31096 +f 41865/41913/31094 41866/41914/31097 41867/41915/31098 +f 41865/41913/31094 41867/41915/31098 41868/41916/31099 +f 41868/41916/31099 41867/41915/31098 41869/41917/31100 +f 41868/41916/31099 41869/41917/31100 41870/41918/31101 +f 41864/41912/31096 41863/41911/31095 41871/41919/31102 +f 41864/41912/31096 41871/41919/31102 41872/41920/31103 +f 41873/41921/31104 41874/41922/31105 41875/41923/31106 +f 41873/41921/31104 41875/41923/31106 41876/41924/31107 +f 41874/41922/31105 41877/41925/31108 41878/41926/31109 +f 41874/41922/31105 41878/41926/31109 41875/41923/31106 +f 41875/41923/31106 41878/41926/31109 41879/41927/31110 +f 41875/41923/31106 41879/41927/31110 41880/41928/31111 +f 41876/41924/31107 41875/41923/31106 41880/41928/31111 +f 41876/41924/31107 41880/41928/31111 41881/41929/31112 +f 41882/41930/31113 41883/41931/31114 41884/41932/31106 +f 41882/41930/31113 41884/41932/31106 41885/41933/31115 +f 41883/41931/31114 41886/41934/31116 41887/41935/31117 +f 41883/41931/31114 41887/41935/31117 41884/41932/31106 +f 41884/41932/31106 41887/41935/31117 41888/41936/31118 +f 41884/41932/31106 41888/41936/31118 41889/41937/31119 +f 41885/41933/31115 41884/41932/31106 41889/41937/31119 +f 41885/41933/31115 41889/41937/31119 41890/41938/31120 +f 41866/41914/31097 41891/41939/31121 41892/41940/31122 +f 41866/41914/31097 41892/41940/31122 41867/41915/31098 +f 41891/41939/31121 41845/41893/31080 41843/41891/31079 +f 41891/41939/31121 41843/41891/31079 41892/41940/31122 +f 41892/41940/31122 41843/41891/31079 41842/41890/31078 +f 41892/41940/31122 41842/41890/31078 41893/41941/31123 +f 41867/41915/31098 41892/41940/31122 41893/41941/31123 +f 41867/41915/31098 41893/41941/31123 41869/41917/31100 +f 41894/41942/31022 41895/41943/31019 41896/41944/31124 +f 41894/41942/31022 41896/41944/31124 41897/41945/31125 +f 41895/41943/31019 41898/41946/31126 41899/41947/31127 +f 41895/41943/31019 41899/41947/31127 41896/41944/31124 +f 41896/41944/31124 41899/41947/31127 41869/41917/31100 +f 41896/41944/31124 41869/41917/31100 41893/41941/31123 +f 41897/41945/31125 41896/41944/31124 41893/41941/31123 +f 41897/41945/31125 41893/41941/31123 41842/41890/31078 +f 41900/41948/31067 41901/41949/31128 41902/41950/31129 +f 41900/41948/31067 41902/41950/31129 41903/41951/31130 +f 41901/41949/31128 41904/41952/31131 41905/41953/31132 +f 41901/41949/31128 41905/41953/31132 41902/41950/31129 +f 41902/41950/31129 41905/41953/31132 41886/41934/31116 +f 41902/41950/31129 41886/41934/31116 41883/41931/31114 +f 41903/41951/31130 41902/41950/31129 41883/41931/31114 +f 41903/41951/31130 41883/41931/31114 41882/41930/31113 +f 41906/41954/31133 41907/41955/31121 41908/41956/31134 +f 41906/41954/31133 41908/41956/31134 41909/41957/31135 +f 41907/41955/31121 41854/41902/31088 41910/41958/31136 +f 41907/41955/31121 41910/41958/31136 41908/41956/31134 +f 41908/41956/31134 41910/41958/31136 41911/41959/31137 +f 41908/41956/31134 41911/41959/31137 41912/41960/31138 +f 41909/41957/31135 41908/41956/31134 41912/41960/31138 +f 41909/41957/31135 41912/41960/31138 41913/41961/31139 +f 41877/41925/31108 41874/41922/31105 41914/41962/31140 +f 41877/41925/31108 41914/41962/31140 41915/41963/31141 +f 41874/41922/31105 41873/41921/31104 41916/41964/31142 +f 41874/41922/31105 41916/41964/31142 41914/41962/31140 +f 41914/41962/31140 41916/41964/31142 41917/41965/31143 +f 41914/41962/31140 41917/41965/31143 41918/41966/31144 +f 41915/41963/31141 41914/41962/31140 41918/41966/31144 +f 41915/41963/31141 41918/41966/31144 41919/41967/31145 +f 41849/41897/31084 41920/41968/31146 41921/41969/31147 +f 41849/41897/31084 41921/41969/31147 41922/41970/31148 +f 41923/41971/31146 41877/41925/31108 41915/41963/31141 +f 41923/41971/31146 41915/41963/31141 41924/41972/31147 +f 41925/41973/31147 41926/41974/31141 41927/41975/31149 +f 41925/41973/31147 41927/41975/31149 41928/41976/31150 +f 41929/41977/31151 41925/41973/31147 41928/41976/31150 +f 41929/41977/31151 41928/41976/31150 41930/41978/31152 +f 41857/41905/31090 41931/41979/31153 41932/41980/31154 +f 41857/41905/31090 41932/41980/31154 41933/41981/31155 +f 41931/41979/31153 41934/41982/31156 41935/41983/31157 +f 41931/41979/31153 41935/41983/31157 41932/41980/31154 +f 41932/41980/31154 41935/41983/31157 41936/41984/31158 +f 41932/41980/31154 41936/41984/31158 41937/41985/31159 +f 41933/41981/31155 41932/41980/31154 41937/41985/31159 +f 41933/41981/31155 41937/41985/31159 41938/41986/31160 +f 41881/41929/31112 41880/41928/31111 41939/41987/31161 +f 41881/41929/31112 41939/41987/31161 41940/41988/31162 +f 41880/41928/31111 41879/41927/31110 41941/41989/31163 +f 41880/41928/31111 41941/41989/31163 41939/41987/31161 +f 41939/41987/31161 41941/41989/31163 41942/41990/31164 +f 41939/41987/31161 41942/41990/31164 41943/41991/31165 +f 41940/41988/31162 41939/41987/31161 41943/41991/31165 +f 41940/41988/31162 41943/41991/31165 41944/41992/31166 +f 41854/41902/31088 41907/41955/31121 41945/41993/31122 +f 41854/41902/31088 41945/41993/31122 41855/41903/31089 +f 41907/41955/31121 41906/41954/31133 41946/41994/31167 +f 41907/41955/31121 41946/41994/31167 41945/41993/31122 +f 41945/41993/31122 41946/41994/31167 41934/41982/31156 +f 41945/41993/31122 41934/41982/31156 41931/41979/31153 +f 41855/41903/31089 41945/41993/31122 41931/41979/31153 +f 41855/41903/31089 41931/41979/31153 41857/41905/31090 +f 41947/41995/31168 41948/41996/31169 41949/41997/31170 +f 41947/41995/31168 41949/41997/31170 41950/41998/31096 +f 41951/41999/31169 41873/41921/31104 41876/41924/31107 +f 41951/41999/31169 41876/41924/31107 41952/42000/31170 +f 41952/42000/31170 41876/41924/31107 41881/41929/31112 +f 41952/42000/31170 41881/41929/31112 41953/42001/31171 +f 41950/41998/31096 41949/41997/31170 41954/42002/31172 +f 41950/41998/31096 41954/42002/31172 41955/42003/31173 +f 41956/41873/31056 41957/41881/31066 41958/42004/31174 +f 41956/41873/31056 41958/42004/31174 41959/42005/31175 +f 41957/41881/31066 41960/41871/31067 41961/42006/31130 +f 41957/41881/31066 41961/42006/31130 41958/42004/31174 +f 41962/42007/31176 41903/41951/31130 41882/41930/31113 +f 41962/42007/31176 41882/41930/31113 41963/42008/31177 +f 41964/42009/31178 41965/42010/31176 41966/42011/31179 +f 41964/42009/31178 41966/42011/31179 41848/41896/31083 +f 41967/41857/31042 41968/41877/31059 41969/42012/31180 +f 41967/41857/31042 41969/42012/31180 41970/42013/31181 +f 41968/41877/31059 41971/41867/31182 41972/42014/31183 +f 41968/41877/31059 41972/42014/31183 41969/42012/31180 +f 41973/42015/31180 41974/42016/31184 41866/41914/31097 +f 41973/42015/31180 41866/41914/31097 41865/41913/31094 +f 41975/42017/31185 41976/42018/31186 41862/41910/31094 +f 41975/42017/31185 41862/41910/31094 41861/41909/31093 +f 41977/42019/31050 41978/42020/31049 41979/42021/31187 +f 41977/42019/31050 41979/42021/31187 41974/42016/31184 +f 41978/42020/31049 41980/42022/31188 41981/42023/31189 +f 41978/42020/31049 41981/42023/31189 41979/42021/31187 +f 41979/42021/31187 41981/42023/31189 41845/41893/31080 +f 41979/42021/31187 41845/41893/31080 41891/41939/31121 +f 41974/42016/31184 41979/42021/31187 41891/41939/31121 +f 41974/42016/31184 41891/41939/31121 41866/41914/31097 +f 41860/41908/31092 41859/41907/31091 41982/42024/31190 +f 41860/41908/31092 41982/42024/31190 41983/42025/31191 +f 41858/41906/31091 41857/41905/31090 41933/41981/31155 +f 41858/41906/31091 41933/41981/31155 41984/42026/31190 +f 41985/42027/31192 41986/42028/31155 41987/42029/31193 +f 41985/42027/31192 41987/42029/31193 41988/42030/31194 +f 41989/42031/31195 41985/42027/31192 41988/42030/31194 +f 41989/42031/31195 41988/42030/31194 41990/42032/31196 +f 41991/41853/31037 41992/41883/31072 41993/42033/31197 +f 41991/41853/31037 41993/42033/31197 41994/42034/31198 +f 41992/41883/31072 41995/41841/31022 41996/42035/31199 +f 41992/41883/31072 41996/42035/31199 41993/42033/31197 +f 41997/42036/31200 41897/41945/31125 41842/41890/31078 +f 41997/42036/31200 41842/41890/31078 41841/41889/31077 +f 41998/42037/31201 41999/42038/31200 41838/41886/31074 +f 41998/42037/31201 41838/41886/31074 41837/41885/31073 +f 42000/41849/31030 42001/41879/31202 42002/42039/31203 +f 42000/41849/31030 42002/42039/31203 42003/42040/31204 +f 42001/41879/31202 42004/41847/31028 42005/42041/31205 +f 42001/41879/31202 42005/42041/31205 42002/42039/31203 +f 42006/42042/31203 42007/42043/31206 41888/41936/31118 +f 42006/42042/31203 41888/41936/31118 42008/42044/31207 +f 42009/42045/31208 42010/42046/31203 42011/42047/31207 +f 42009/42045/31208 42011/42047/31207 41872/41920/31103 +f 42012/42048/31028 42013/42049/31029 42014/42050/31209 +f 42012/42048/31028 42014/42050/31209 42007/42043/31206 +f 42013/42049/31029 42015/42051/31023 42016/42052/31210 +f 42013/42049/31029 42016/42052/31210 42014/42050/31209 +f 42014/42050/31209 42016/42052/31210 41890/41938/31120 +f 42014/42050/31209 41890/41938/31120 41889/41937/31119 +f 42007/42043/31206 42014/42050/31209 41889/41937/31119 +f 42007/42043/31206 41889/41937/31119 41888/41936/31118 +f 42019/41839/31020 42021/41842/31020 42022/42053/31211 +f 42019/41839/31020 42022/42053/31211 42023/42054/31212 +f 42020/41840/31025 42019/41839/31020 42023/42054/31212 +f 42020/41840/31025 42023/42054/31212 42024/42055/31164 +f 42027/41845/31213 42029/41848/31033 41987/42029/31193 +f 42027/41845/31213 41987/42029/31193 42030/42056/31214 +f 42028/41846/31020 42027/41845/31213 42030/42056/31214 +f 42028/41846/31020 42030/42056/31214 42031/42057/31158 +f 42033/41851/31033 42020/41840/31025 42024/42055/31164 +f 42033/41851/31033 42024/42055/31164 42035/42058/31215 +f 42034/41852/31020 42033/41851/31033 42035/42058/31215 +f 42034/41852/31020 42035/42058/31215 41990/42032/31196 +f 42037/41855/31020 42028/41846/31020 42031/42057/31158 +f 42037/41855/31020 42031/42057/31158 42039/42059/31216 +f 42038/41856/31020 42037/41855/31020 42039/42059/31216 +f 42038/41856/31020 42039/42059/31216 42040/42060/31217 +f 41955/42003/31173 41954/42002/31172 42041/42061/31218 +f 41955/42003/31173 42041/42061/31218 42042/42062/31219 +f 41953/42001/31171 41881/41929/31112 41940/41988/31162 +f 41953/42001/31171 41940/41988/31162 42043/42063/31218 +f 42044/42064/31218 42045/42065/31220 42022/42053/31211 +f 42044/42064/31218 42022/42053/31211 42046/42066/31221 +f 42047/42067/31219 42044/42064/31218 42046/42066/31221 +f 42047/42067/31219 42046/42066/31221 42040/42060/31217 +f 42049/41859/31043 42052/41862/31051 42053/42068/31137 +f 42049/41859/31043 42053/42068/31137 42054/42069/31222 +f 42050/41860/31043 42049/41859/31043 42054/42069/31222 +f 42050/41860/31043 42054/42069/31222 41930/41978/31152 +f 42057/41865/31043 42059/41868/31043 41927/41975/31149 +f 42057/41865/31043 41927/41975/31149 42060/42070/31223 +f 42058/41866/31043 42057/41865/31043 42060/42070/31223 +f 42058/41866/31043 42060/42070/31223 42061/42071/31224 +f 42063/41870/31043 42064/41872/31043 42065/42072/31225 +f 42063/41870/31043 42065/42072/31225 42066/42073/31226 +f 42052/41862/31051 42063/41870/31043 42066/42073/31226 +f 42052/41862/31051 42066/42073/31226 42053/42068/31137 +f 42068/41875/31043 42058/41866/31043 42061/42071/31224 +f 42068/41875/31043 42061/42071/31224 42070/42074/31227 +f 42069/41876/31043 42068/41875/31043 42070/42074/31227 +f 42069/41876/31043 42070/42074/31227 42071/42075/31228 +f 41947/41995/31168 42072/42076/31229 42073/42077/31230 +f 41947/41995/31168 42073/42077/31230 42074/42078/31231 +f 42075/42079/31229 41906/41954/31133 41909/41957/31135 +f 42075/42079/31229 41909/41957/31135 42076/42080/31230 +f 42077/42081/31230 42078/42082/31232 42065/42072/31225 +f 42077/42081/31230 42065/42072/31225 42079/42083/31233 +f 42080/42084/31231 42077/42081/31230 42079/42083/31233 +f 42080/42084/31231 42079/42083/31233 42071/42075/31228 +f 42081/41878/31043 42050/41860/31043 41930/41978/31152 +f 42081/41878/31043 41930/41978/31152 41928/41976/31150 +f 42059/41868/31043 42081/41878/31043 41928/41976/31150 +f 42059/41868/31043 41928/41976/31150 41927/41975/31149 +f 42082/41880/31033 42034/41852/31020 41990/42032/31196 +f 42082/41880/31033 41990/42032/31196 41988/42030/31194 +f 42029/41848/31033 42082/41880/31033 41988/42030/31194 +f 42029/41848/31033 41988/42030/31194 41987/42029/31193 +f 42017/41837/31126 42032/41850/31234 42083/42085/31235 +f 42017/41837/31126 42083/42085/31235 42084/42086/31236 +f 42032/41850/31234 42000/41849/31030 42003/42040/31204 +f 42032/41850/31234 42003/42040/31204 42083/42085/31235 +f 42085/42087/31237 42009/42045/31208 41872/41920/31103 +f 42085/42087/31237 41872/41920/31103 41871/41919/31102 +f 41899/41947/31127 42086/42088/31237 41870/41918/31101 +f 41899/41947/31127 41870/41918/31101 41869/41917/31100 +f 41879/41927/31110 42087/42089/31238 42088/42090/31239 +f 41879/41927/31110 42088/42090/31239 41941/41989/31163 +f 42089/42091/31240 41860/41908/31092 41983/42025/31191 +f 42089/42091/31240 41983/42025/31191 42090/42092/31241 +f 42091/42093/31241 41989/42031/31195 41990/42032/31196 +f 42091/42093/31241 41990/42032/31196 42035/42058/31215 +f 42092/42094/31242 42091/42093/31241 42035/42058/31215 +f 42092/42094/31242 42035/42058/31215 42024/42055/31164 +f 42051/41861/31044 42048/41858/31040 42093/42095/31243 +f 42051/41861/31044 42093/42095/31243 42094/42096/31132 +f 42048/41858/31040 41967/41857/31042 41970/42013/31181 +f 42048/41858/31040 41970/42013/31181 42093/42095/31243 +f 42095/42097/31244 41975/42017/31185 41861/41909/31093 +f 42095/42097/31244 41861/41909/31093 42096/42098/31245 +f 41905/41953/31132 42097/42099/31246 42098/42100/31245 +f 41905/41953/31132 42098/42100/31245 41886/41934/31116 +f 41854/41902/31088 41853/41901/31087 42099/42101/31247 +f 41854/41902/31088 42099/42101/31247 41910/41958/31136 +f 41850/41898/31085 41849/41897/31084 41922/41970/31148 +f 41850/41898/31085 41922/41970/31148 42100/42102/31248 +f 42101/42103/31247 41929/41977/31151 41930/41978/31152 +f 42101/42103/31247 41930/41978/31152 42054/42069/31222 +f 42102/42104/31136 42101/42103/31247 42054/42069/31222 +f 42102/42104/31136 42054/42069/31222 42053/42068/31137 +f 41886/41934/31116 42098/42100/31245 42103/42105/31249 +f 41886/41934/31116 42103/42105/31249 41887/41935/31117 +f 42096/42098/31245 41861/41909/31093 41864/41912/31096 +f 42096/42098/31245 41864/41912/31096 42104/42106/31250 +f 42104/42106/31250 41864/41912/31096 41872/41920/31103 +f 42104/42106/31250 41872/41920/31103 42011/42047/31207 +f 41887/41935/31117 42103/42105/31249 42008/42044/31207 +f 41887/41935/31117 42008/42044/31207 41888/41936/31118 +f 41877/41925/31108 41923/41971/31146 42105/42107/31251 +f 41877/41925/31108 42105/42107/31251 41878/41926/31109 +f 41920/41968/31146 41849/41897/31084 41852/41900/31076 +f 41920/41968/31146 41852/41900/31076 42106/42108/31251 +f 42106/42108/31251 41852/41900/31076 41860/41908/31092 +f 42106/42108/31251 41860/41908/31092 42089/42091/31240 +f 41878/41926/31109 42105/42107/31251 42087/42089/31238 +f 41878/41926/31109 42087/42089/31238 41879/41927/31110 +f 41873/41921/31104 41951/41999/31169 42107/42109/31252 +f 41873/41921/31104 42107/42109/31252 41916/41964/31142 +f 41948/41996/31169 41947/41995/31168 42074/42078/31231 +f 41948/41996/31169 42074/42078/31231 42108/42110/31252 +f 42109/42111/31252 42080/42084/31231 42071/42075/31228 +f 42109/42111/31252 42071/42075/31228 42070/42074/31227 +f 42110/42112/31142 42109/42111/31252 42070/42074/31227 +f 42110/42112/31142 42070/42074/31227 42061/42071/31224 +f 42111/41882/31043 42069/41876/31043 42071/42075/31228 +f 42111/41882/31043 42071/42075/31228 42079/42083/31233 +f 42064/41872/31043 42111/41882/31043 42079/42083/31233 +f 42064/41872/31043 42079/42083/31233 42065/42072/31225 +f 41934/41982/31156 42112/42113/31253 42113/42114/31254 +f 41934/41982/31156 42113/42114/31254 41935/41983/31157 +f 42114/42115/31255 41955/42003/31173 42042/42062/31219 +f 42114/42115/31255 42042/42062/31219 42115/42116/31256 +f 42116/42117/31256 42047/42067/31219 42040/42060/31217 +f 42116/42117/31256 42040/42060/31217 42039/42059/31216 +f 42117/42118/31257 42116/42117/31256 42039/42059/31216 +f 42117/42118/31257 42039/42059/31216 42031/42057/31158 +f 42118/41884/31033 42038/41856/31020 42040/42060/31217 +f 42118/41884/31033 42040/42060/31217 42046/42066/31221 +f 42021/41842/31020 42118/41884/31033 42046/42066/31221 +f 42021/41842/31020 42046/42066/31221 42022/42053/31211 +f 42025/41843/31026 42036/41854/31036 42119/42119/31258 +f 42025/41843/31026 42119/42119/31258 42120/42120/31210 +f 42036/41854/31036 41991/41853/31037 41994/42034/31198 +f 42036/41854/31036 41994/42034/31198 42119/42119/31258 +f 42121/42121/31258 41998/42037/31201 41837/41885/31073 +f 42121/42121/31258 41837/41885/31073 42122/42122/31259 +f 42016/42052/31210 42123/42123/31258 42124/42124/31259 +f 42016/42052/31210 42124/42124/31259 41890/41938/31120 +f 42055/41863/31045 42067/41874/31057 42125/42125/31260 +f 42055/41863/31045 42125/42125/31260 42126/42126/31261 +f 42067/41874/31057 41956/41873/31056 41959/42005/31175 +f 42067/41874/31057 41959/42005/31175 42125/42125/31260 +f 42127/42127/31262 41964/42009/31178 41848/41896/31083 +f 42127/42127/31262 41848/41896/31083 41847/41895/31082 +f 41981/42023/31189 42128/42128/31263 41846/41894/31081 +f 41981/42023/31189 41846/41894/31081 41845/41893/31080 +f 41906/41954/31133 42075/42079/31229 42129/42129/31264 +f 41906/41954/31133 42129/42129/31264 41946/41994/31167 +f 42072/42076/31229 41947/41995/31168 41950/41998/31096 +f 42072/42076/31229 41950/41998/31096 42130/42130/31265 +f 42130/42130/31265 41950/41998/31096 41955/42003/31173 +f 42130/42130/31265 41955/42003/31173 42114/42115/31255 +f 41946/41994/31167 42129/42129/31264 42112/42113/31253 +f 41946/41994/31167 42112/42113/31253 41934/41982/31156 +f 41890/41938/31120 42124/42124/31259 42131/42131/31266 +f 41890/41938/31120 42131/42131/31266 41885/41933/31115 +f 42122/42122/31259 41837/41885/31073 41840/41888/31076 +f 42122/42122/31259 41840/41888/31076 42132/42132/31266 +f 42132/42132/31266 41840/41888/31076 41848/41896/31083 +f 42132/42132/31266 41848/41896/31083 41966/42011/31179 +f 41885/41933/31115 42131/42131/31266 41963/42008/31177 +f 41885/41933/31115 41963/42008/31177 41882/41930/31113 +o Cube.053__0 +v 1.418608 -0.601532 -0.778395 +v 1.417029 -0.550094 -0.778771 +v 1.416462 -0.548181 -0.788883 +v 1.418542 -0.600579 -0.788565 +v 1.414456 -0.500849 -0.779279 +v 1.413202 -0.497672 -0.789436 +v 1.412977 -0.495422 -0.793782 +v 1.416938 -0.546456 -0.793313 +v 1.419772 -0.599470 -0.794003 +v 1.537361 -0.608042 -0.790218 +v 1.534183 -0.568206 -0.790530 +v 1.546462 -0.570416 -0.792793 +v 1.549777 -0.607348 -0.792252 +v 1.529448 -0.534713 -0.790951 +v 1.541475 -0.540318 -0.793288 +v 1.548348 -0.550456 -0.794367 +v 1.553653 -0.570648 -0.794175 +v 1.557356 -0.590312 -0.792228 +v 1.427423 -0.568741 -0.327515 +v 1.425616 -0.532599 -0.327985 +v 1.421661 -0.532520 -0.327258 +v 1.423501 -0.570806 -0.326756 +v 1.423422 -0.483707 -0.327557 +v 1.419378 -0.482594 -0.326802 +v 1.415832 -0.480939 -0.327638 +v 1.418409 -0.533396 -0.328115 +v 1.420115 -0.588729 -0.327447 +v 1.481988 -1.000019 -0.347619 +v 1.493510 -1.008224 -0.345534 +v 1.493529 -1.008887 -0.335075 +v 1.482039 -1.000632 -0.337229 +v 1.498864 -1.009451 -0.344469 +v 1.498733 -1.010115 -0.334081 +v 1.498096 -1.009211 -0.330512 +v 1.493782 -1.007593 -0.330708 +v 1.482395 -0.999356 -0.332749 +v 1.384326 -0.927717 -0.328302 +v 1.395043 -0.888159 -0.328326 +v 1.391382 -0.886925 -0.327617 +v 1.380682 -0.926312 -0.327590 +v 1.405686 -0.849558 -0.327620 +v 1.402180 -0.847274 -0.326864 +v 1.401859 -0.829792 -0.327530 +v 1.388857 -0.884700 -0.328483 +v 1.377989 -0.925274 -0.328449 +v 1.440486 -0.600404 -0.791003 +v 1.443376 -0.656805 -0.790628 +v 1.435820 -0.658143 -0.795663 +v 1.435333 -0.615569 -0.795975 +v 1.440863 -0.714181 -0.790585 +v 1.433080 -0.714165 -0.795612 +v 1.435820 -0.658143 -0.795663 +v 1.433080 -0.714165 -0.795612 +v 1.431067 -0.714401 -0.810838 +v 1.433879 -0.658653 -0.810945 +v 1.435333 -0.615569 -0.795975 +v 1.433839 -0.617454 -0.811220 +v 1.405686 -0.849559 -0.793878 +v 1.402180 -0.847279 -0.794629 +v 1.407002 -0.830384 -0.798478 +v 1.410516 -0.832841 -0.797613 +v 1.401859 -0.829843 -0.793921 +v 1.406463 -0.812995 -0.799015 +v 1.407002 -0.830384 -0.798478 +v 1.406463 -0.812995 -0.799015 +v 1.406072 -0.811424 -0.813702 +v 1.406759 -0.828438 -0.813049 +v 1.410516 -0.832841 -0.797613 +v 1.407002 -0.830384 -0.798478 +v 1.406759 -0.828438 -0.813049 +v 1.410299 -0.830869 -0.812228 +v 1.508362 -0.982192 -0.342310 +v 1.523895 -0.914766 -0.336713 +v 1.522486 -0.914135 -0.332977 +v 1.508657 -0.976001 -0.333399 +v 1.539283 -0.839401 -0.336097 +v 1.537707 -0.839263 -0.332922 +v 1.535714 -0.839157 -0.329865 +v 1.520586 -0.913626 -0.329774 +v 1.506994 -0.974743 -0.329634 +v 1.549953 -0.772577 -0.336112 +v 1.548376 -0.772459 -0.332947 +v 1.556144 -0.712702 -0.336113 +v 1.554568 -0.712612 -0.332951 +v 1.552557 -0.712660 -0.329906 +v 1.546368 -0.772472 -0.329901 +v 1.559237 -0.654693 -0.336903 +v 1.557781 -0.654097 -0.333095 +v 1.559596 -0.595477 -0.343741 +v 1.559430 -0.595024 -0.333817 +v 1.558009 -0.587393 -0.329205 +v 1.555787 -0.653804 -0.329843 +v 1.490311 -0.965657 -0.790285 +v 1.503549 -0.908275 -0.790176 +v 1.515423 -0.912370 -0.792109 +v 1.501939 -0.972524 -0.792247 +v 1.518333 -0.837831 -0.790103 +v 1.530448 -0.839217 -0.792017 +v 1.535714 -0.839667 -0.791566 +v 1.520586 -0.913688 -0.791656 +v 1.506994 -0.974738 -0.791795 +v 1.528825 -0.773681 -0.790075 +v 1.541044 -0.773923 -0.791981 +v 1.534910 -0.715117 -0.790071 +v 1.547143 -0.715245 -0.791976 +v 1.552462 -0.715331 -0.791527 +v 1.546356 -0.774018 -0.791531 +v 1.537686 -0.658442 -0.790090 +v 1.549963 -0.658301 -0.792010 +v 1.555484 -0.657086 -0.791589 +v 1.376721 -0.924786 -0.778151 +v 1.387557 -0.883990 -0.778193 +v 1.387732 -0.884031 -0.788502 +v 1.376880 -0.924847 -0.788615 +v 1.399996 -0.829553 -0.778210 +v 1.400191 -0.829581 -0.788450 +v 1.401859 -0.829843 -0.793921 +v 1.388857 -0.884706 -0.792951 +v 1.377989 -0.925274 -0.792982 +v 1.409466 -0.772033 -0.778217 +v 1.409531 -0.772013 -0.788400 +v 1.415405 -0.714092 -0.778218 +v 1.415434 -0.713981 -0.788388 +v 1.415642 -0.713947 -0.793846 +v 1.409980 -0.771651 -0.793854 +v 1.418274 -0.656649 -0.778240 +v 1.418304 -0.656296 -0.788414 +v 1.418631 -0.656446 -0.793864 +v 1.415405 -0.711576 -0.343015 +v 1.418230 -0.649812 -0.342991 +v 1.418247 -0.649809 -0.360453 +v 1.415405 -0.711480 -0.360471 +v 1.418252 -0.589136 -0.342826 +v 1.418385 -0.589469 -0.360322 +v 1.418608 -0.590531 -0.383687 +v 1.418274 -0.650146 -0.383775 +v 1.415405 -0.711478 -0.383787 +v 1.418287 -0.651032 -0.410642 +v 1.415405 -0.711685 -0.410649 +v 1.418712 -0.592375 -0.410597 +v 1.418727 -0.594793 -0.439584 +v 1.418290 -0.652374 -0.439598 +v 1.415405 -0.712128 -0.439600 +v 1.418290 -0.654003 -0.469535 +v 1.415405 -0.712785 -0.469535 +v 1.418727 -0.597526 -0.469532 +v 1.418727 -0.600354 -0.499893 +v 1.418290 -0.655738 -0.499893 +v 1.415405 -0.713552 -0.499893 +v 1.418287 -0.657388 -0.530321 +v 1.415405 -0.714300 -0.530321 +v 1.418712 -0.603031 -0.530321 +v 1.418608 -0.605177 -0.560750 +v 1.418274 -0.658740 -0.560750 +v 1.415405 -0.714884 -0.560750 +v 1.418245 -0.659611 -0.591178 +v 1.415405 -0.715194 -0.591178 +v 1.418371 -0.606464 -0.591178 +v 1.418133 -0.606932 -0.621607 +v 1.418216 -0.659972 -0.621607 +v 1.415405 -0.715269 -0.621607 +v 1.418204 -0.659854 -0.651965 +v 1.415405 -0.715184 -0.651965 +v 1.418044 -0.606721 -0.651967 +v 1.418133 -0.606011 -0.681912 +v 1.418216 -0.659369 -0.681901 +v 1.415405 -0.715003 -0.681900 +v 1.418245 -0.658657 -0.710848 +v 1.415405 -0.714777 -0.710842 +v 1.418371 -0.604986 -0.710883 +v 1.418608 -0.603806 -0.737728 +v 1.418274 -0.657878 -0.737657 +v 1.415405 -0.714531 -0.737646 +v 1.399996 -0.829451 -0.343021 +v 1.409466 -0.771475 -0.343016 +v 1.409466 -0.771399 -0.360499 +v 1.399996 -0.829424 -0.360688 +v 1.409466 -0.771325 -0.383844 +v 1.399996 -0.829392 -0.384242 +v 1.409466 -0.771294 -0.410725 +v 1.399996 -0.829369 -0.411260 +v 1.409466 -0.771353 -0.439681 +v 1.399996 -0.829370 -0.440244 +v 1.409466 -0.771532 -0.469602 +v 1.399996 -0.829411 -0.470076 +v 1.409466 -0.771783 -0.499938 +v 1.399996 -0.829476 -0.500258 +v 1.409466 -0.772038 -0.530344 +v 1.399996 -0.829544 -0.530502 +v 1.409466 -0.772218 -0.560750 +v 1.399996 -0.829589 -0.560750 +v 1.409466 -0.772266 -0.591156 +v 1.399996 -0.829593 -0.590997 +v 1.409466 -0.772232 -0.621561 +v 1.399996 -0.829575 -0.621242 +v 1.409466 -0.772182 -0.651897 +v 1.399996 -0.829559 -0.651423 +v 1.409466 -0.772147 -0.681819 +v 1.399996 -0.829553 -0.681256 +v 1.409466 -0.772136 -0.710766 +v 1.399996 -0.829560 -0.710231 +v 1.409466 -0.772122 -0.737589 +v 1.399996 -0.829567 -0.737191 +v 1.376721 -0.924786 -0.343081 +v 1.387557 -0.883977 -0.343038 +v 1.387557 -0.883974 -0.361126 +v 1.376721 -0.924786 -0.361593 +v 1.387557 -0.883970 -0.385156 +v 1.376721 -0.924786 -0.386099 +v 1.387557 -0.883967 -0.412488 +v 1.376721 -0.924785 -0.413742 +v 1.387557 -0.883967 -0.441535 +v 1.376721 -0.924785 -0.442846 +v 1.387557 -0.883972 -0.471161 +v 1.376721 -0.924785 -0.472261 +v 1.387557 -0.883980 -0.500989 +v 1.376721 -0.924786 -0.501732 +v 1.387557 -0.883989 -0.530865 +v 1.376721 -0.924786 -0.531234 +v 1.387557 -0.883994 -0.560750 +v 1.376721 -0.924786 -0.560749 +v 1.387557 -0.883995 -0.590634 +v 1.376721 -0.924786 -0.590265 +v 1.387557 -0.883992 -0.620510 +v 1.376721 -0.924786 -0.619766 +v 1.387557 -0.883991 -0.650338 +v 1.376721 -0.924785 -0.649238 +v 1.387557 -0.883990 -0.679964 +v 1.376721 -0.924785 -0.678652 +v 1.387557 -0.883991 -0.709002 +v 1.376721 -0.924785 -0.707748 +v 1.387557 -0.883991 -0.736276 +v 1.376721 -0.924786 -0.735332 +v 1.556051 -0.716859 -0.730196 +v 1.549942 -0.774521 -0.730109 +v 1.552952 -0.774839 -0.739704 +v 1.559062 -0.717018 -0.739782 +v 1.539283 -0.839093 -0.729526 +v 1.542293 -0.839574 -0.739186 +v 1.545304 -0.840074 -0.747299 +v 1.555963 -0.775184 -0.747714 +v 1.562072 -0.717236 -0.747777 +v 1.558952 -0.661330 -0.730944 +v 1.557738 -0.661868 -0.709907 +v 1.554734 -0.717170 -0.709755 +v 1.559073 -0.604817 -0.737268 +v 1.559073 -0.607090 -0.710648 +v 1.559073 -0.609052 -0.681837 +v 1.557581 -0.663031 -0.681835 +v 1.554545 -0.717736 -0.681834 +v 1.557738 -0.663861 -0.653013 +v 1.554734 -0.718261 -0.653224 +v 1.559073 -0.610152 -0.651957 +v 1.559073 -0.610137 -0.621607 +v 1.558952 -0.664780 -0.630693 +v 1.556051 -0.718755 -0.631749 +v 1.559073 -0.606540 -0.560750 +v 1.559073 -0.603308 -0.530321 +v 1.563285 -0.608257 -0.531541 +v 1.563350 -0.609382 -0.560749 +v 1.559073 -0.603308 -0.530321 +v 1.559073 -0.599572 -0.499893 +v 1.562923 -0.620594 -0.509847 +v 1.563285 -0.608257 -0.531541 +v 1.563285 -0.608257 -0.531541 +v 1.562923 -0.620594 -0.509847 +v 1.565230 -0.630924 -0.515105 +v 1.566024 -0.624864 -0.532245 +v 1.563350 -0.609382 -0.560749 +v 1.563285 -0.608257 -0.531541 +v 1.566024 -0.624864 -0.532245 +v 1.566188 -0.625867 -0.560748 +v 1.539283 -0.838787 -0.490233 +v 1.523895 -0.912061 -0.492228 +v 1.527191 -0.911659 -0.502216 +v 1.542293 -0.839371 -0.500275 +v 1.508362 -0.978616 -0.502042 +v 1.514097 -0.969175 -0.511382 +v 1.519408 -0.957255 -0.516289 +v 1.530478 -0.910863 -0.511744 +v 1.545304 -0.839967 -0.510329 +v 1.556051 -0.714444 -0.489749 +v 1.558953 -0.656981 -0.490806 +v 1.557741 -0.654500 -0.468486 +v 1.554735 -0.713176 -0.468275 +v 1.559073 -0.599572 -0.499893 +v 1.559080 -0.595855 -0.469543 +v 1.559128 -0.593123 -0.439667 +v 1.557609 -0.652608 -0.439667 +v 1.554555 -0.711988 -0.439666 +v 1.557824 -0.651784 -0.411598 +v 1.554761 -0.711372 -0.411746 +v 1.559241 -0.592178 -0.410857 +v 1.559383 -0.592718 -0.384184 +v 1.559096 -0.652227 -0.390559 +v 1.556096 -0.711306 -0.391306 +v 1.504001 -1.002627 -0.560749 +v 1.504450 -0.999399 -0.589777 +v 1.508888 -0.993666 -0.588918 +v 1.508189 -0.997830 -0.560748 +v 1.508362 -0.978616 -0.619456 +v 1.514097 -0.969175 -0.610114 +v 1.519408 -0.957255 -0.605207 +v 1.517347 -0.969941 -0.588446 +v 1.516921 -0.973143 -0.560747 +v 1.548625 -0.774500 -0.709660 +v 1.537965 -0.838747 -0.709010 +v 1.548436 -0.774697 -0.681739 +v 1.537777 -0.838655 -0.681081 +v 1.548625 -0.774981 -0.653145 +v 1.537965 -0.838892 -0.652588 +v 1.549942 -0.775357 -0.631689 +v 1.539283 -0.839345 -0.631266 +v 1.508362 -0.982173 -0.778874 +v 1.523895 -0.914824 -0.784448 +v 1.527191 -0.913862 -0.782276 +v 1.514097 -0.971494 -0.775707 +v 1.539283 -0.839954 -0.785066 +v 1.542293 -0.840305 -0.783195 +v 1.527191 -0.913862 -0.782276 +v 1.542293 -0.840305 -0.783195 +v 1.545304 -0.840573 -0.777085 +v 1.530478 -0.912266 -0.776212 +v 1.514097 -0.971494 -0.775707 +v 1.519408 -0.958760 -0.772664 +v 1.562155 -0.654612 -0.380832 +v 1.559115 -0.711641 -0.381712 +v 1.563223 -0.613173 -0.374466 +v 1.565514 -0.623508 -0.370056 +v 1.565076 -0.656683 -0.373041 +v 1.562131 -0.712214 -0.373658 +v 1.549942 -0.773492 -0.489810 +v 1.548625 -0.772764 -0.468355 +v 1.537965 -0.838226 -0.468912 +v 1.548438 -0.772142 -0.439761 +v 1.537777 -0.837882 -0.440419 +v 1.548628 -0.771824 -0.411839 +v 1.537965 -0.837925 -0.412489 +v 1.549948 -0.771857 -0.391390 +v 1.539283 -0.838263 -0.391972 +v 1.559073 -0.610137 -0.621607 +v 1.559073 -0.608891 -0.591178 +v 1.563284 -0.613477 -0.589957 +v 1.562922 -0.628671 -0.611651 +v 1.559073 -0.608891 -0.591178 +v 1.559073 -0.606540 -0.560750 +v 1.563350 -0.609382 -0.560749 +v 1.563284 -0.613477 -0.589957 +v 1.563284 -0.613477 -0.589957 +v 1.563350 -0.609382 -0.560749 +v 1.566188 -0.625867 -0.560748 +v 1.566024 -0.629413 -0.589251 +v 1.562922 -0.628671 -0.611651 +v 1.563284 -0.613477 -0.589957 +v 1.566024 -0.629413 -0.589251 +v 1.565230 -0.637711 -0.606391 +v 1.508362 -0.978544 -0.735038 +v 1.523895 -0.912092 -0.729048 +v 1.522739 -0.910644 -0.707701 +v 1.508904 -0.970125 -0.706915 +v 1.522607 -0.910009 -0.679579 +v 1.508975 -0.968569 -0.678094 +v 1.522739 -0.910664 -0.651109 +v 1.508904 -0.970132 -0.649026 +v 1.523895 -0.912131 -0.629270 +v 1.552959 -0.772208 -0.381786 +v 1.542293 -0.838750 -0.382303 +v 1.555971 -0.772689 -0.373717 +v 1.545304 -0.839289 -0.374130 +v 1.504450 -0.999399 -0.531721 +v 1.508888 -0.993665 -0.532578 +v 1.517347 -0.969941 -0.533049 +v 1.522739 -0.910580 -0.470389 +v 1.508904 -0.970132 -0.472472 +v 1.522607 -0.909913 -0.441920 +v 1.508975 -0.968569 -0.443404 +v 1.522739 -0.910541 -0.413797 +v 1.508904 -0.970125 -0.414578 +v 1.523895 -0.911989 -0.392445 +v 1.508362 -0.978547 -0.386410 +v 1.481988 -1.000002 -0.773606 +v 1.493510 -1.008205 -0.775689 +v 1.493510 -1.006414 -0.757165 +v 1.481988 -0.998341 -0.755270 +v 1.498864 -1.009432 -0.776752 +v 1.498864 -1.007622 -0.758139 +v 1.498864 -1.005340 -0.733635 +v 1.493510 -1.004154 -0.732780 +v 1.481988 -0.996243 -0.731131 +v 1.493510 -1.002092 -0.705364 +v 1.481988 -0.994321 -0.703986 +v 1.498864 -1.003257 -0.706084 +v 1.498864 -1.002334 -0.677175 +v 1.493510 -1.001177 -0.676597 +v 1.481988 -0.993467 -0.675498 +v 1.493510 -1.002104 -0.647637 +v 1.481988 -0.994333 -0.646812 +v 1.498864 -1.003270 -0.648070 +v 1.498864 -1.005441 -0.618976 +v 1.493510 -1.004254 -0.618688 +v 1.481988 -0.996335 -0.618135 +v 1.493510 -1.006587 -0.589724 +v 1.481988 -0.998502 -0.589447 +v 1.498864 -1.007797 -0.589868 +v 1.498864 -1.008919 -0.560749 +v 1.493510 -1.007697 -0.560749 +v 1.481988 -0.999531 -0.560749 +v 1.493510 -1.006587 -0.531774 +v 1.481988 -0.998502 -0.532051 +v 1.498864 -1.007797 -0.531630 +v 1.498864 -1.005441 -0.502522 +v 1.493510 -1.004254 -0.502810 +v 1.481988 -0.996335 -0.503362 +v 1.493510 -1.002104 -0.473861 +v 1.481988 -0.994333 -0.474685 +v 1.498864 -1.003270 -0.473428 +v 1.498864 -1.002334 -0.444323 +v 1.493510 -1.001177 -0.444900 +v 1.481988 -0.993467 -0.446000 +v 1.493510 -1.002092 -0.416126 +v 1.481988 -0.994322 -0.417503 +v 1.498864 -1.003258 -0.415406 +v 1.498864 -1.005345 -0.387794 +v 1.493510 -1.004159 -0.388649 +v 1.481988 -0.996247 -0.390298 +v 1.415915 -0.532210 -0.342425 +v 1.416333 -0.533212 -0.360003 +v 1.412318 -0.477664 -0.341883 +v 1.413119 -0.479529 -0.359573 +v 1.414456 -0.483159 -0.383185 +v 1.417029 -0.535435 -0.383474 +v 1.417354 -0.538307 -0.410486 +v 1.415080 -0.487077 -0.410337 +v 1.415169 -0.491115 -0.439500 +v 1.417400 -0.541609 -0.439548 +v 1.417400 -0.545201 -0.469528 +v 1.415170 -0.495387 -0.469522 +v 1.415169 -0.499817 -0.499893 +v 1.417400 -0.548908 -0.499893 +v 1.417354 -0.552439 -0.530321 +v 1.415080 -0.504071 -0.530321 +v 1.414456 -0.506972 -0.560750 +v 1.417029 -0.555066 -0.560750 +v 1.416286 -0.556206 -0.591178 +v 1.413030 -0.507604 -0.591178 +v 1.411604 -0.506956 -0.621607 +v 1.415544 -0.556275 -0.621607 +v 1.415265 -0.555859 -0.651970 +v 1.411070 -0.506267 -0.651974 +v 1.411604 -0.505893 -0.681974 +v 1.415544 -0.555223 -0.681939 +v 1.416286 -0.554475 -0.710967 +v 1.413030 -0.505799 -0.711082 +v 1.414456 -0.505252 -0.738137 +v 1.417029 -0.553438 -0.737902 +v 1.377446 -0.953017 -0.444605 +v 1.382121 -0.954742 -0.445158 +v 1.382121 -0.954817 -0.416445 +v 1.377446 -0.953062 -0.415753 +v 1.392341 -0.956222 -0.446093 +v 1.392341 -0.956374 -0.417620 +v 1.392341 -0.956675 -0.390439 +v 1.382121 -0.954950 -0.389033 +v 1.377446 -0.953139 -0.388208 +v 1.377446 -0.953139 -0.502660 +v 1.382121 -0.954951 -0.502938 +v 1.382121 -0.954818 -0.474054 +v 1.377446 -0.953062 -0.473639 +v 1.392341 -0.956683 -0.503408 +v 1.392341 -0.956375 -0.474756 +v 1.377446 -0.953182 -0.560749 +v 1.382121 -0.955051 -0.560749 +v 1.382121 -0.955030 -0.531837 +v 1.377446 -0.953176 -0.531698 +v 1.392341 -0.957046 -0.560749 +v 1.392341 -0.956942 -0.532074 +v 1.377446 -0.953139 -0.618838 +v 1.382121 -0.954951 -0.618560 +v 1.382121 -0.955030 -0.589660 +v 1.377446 -0.953176 -0.589800 +v 1.392341 -0.956683 -0.618089 +v 1.392341 -0.956942 -0.589424 +v 1.377446 -0.953017 -0.676893 +v 1.382121 -0.954742 -0.676340 +v 1.382121 -0.954818 -0.647444 +v 1.377446 -0.953062 -0.647859 +v 1.392341 -0.956222 -0.675404 +v 1.392341 -0.956375 -0.646742 +v 1.377446 -0.953139 -0.733223 +v 1.382121 -0.954950 -0.732398 +v 1.382121 -0.954817 -0.705044 +v 1.377446 -0.953062 -0.705737 +v 1.392341 -0.956675 -0.730992 +v 1.392341 -0.956374 -0.703869 +v 1.377446 -0.953183 -0.776176 +v 1.382121 -0.955058 -0.775153 +v 1.382121 -0.955029 -0.756717 +v 1.377446 -0.953176 -0.757656 +v 1.392341 -0.957090 -0.773387 +v 1.392341 -0.956927 -0.755105 +v 1.440874 -0.711590 -0.330912 +v 1.443448 -0.650284 -0.330870 +v 1.435982 -0.651474 -0.327043 +v 1.433229 -0.711550 -0.327121 +v 1.440961 -0.589482 -0.330495 +v 1.435529 -0.604938 -0.326603 +v 1.435982 -0.651474 -0.327043 +v 1.435529 -0.604938 -0.326603 +v 1.434941 -0.606689 -0.318918 +v 1.435045 -0.651779 -0.320215 +v 1.433229 -0.711550 -0.327121 +v 1.432238 -0.711537 -0.320547 +v 1.426703 -0.580953 -0.793984 +v 1.431289 -0.583197 -0.792921 +v 1.432198 -0.598273 -0.796756 +v 1.428267 -0.595786 -0.797681 +v 1.432198 -0.598273 -0.796756 +v 1.435333 -0.615569 -0.795975 +v 1.433839 -0.617454 -0.811220 +v 1.431354 -0.600455 -0.811831 +v 1.428267 -0.595786 -0.797681 +v 1.427557 -0.597974 -0.812645 +v 1.384326 -0.927717 -0.793196 +v 1.395043 -0.888159 -0.793172 +v 1.399895 -0.888629 -0.792079 +v 1.389065 -0.929198 -0.792090 +v 1.410531 -0.847818 -0.792826 +v 1.422420 -0.830653 -0.790946 +v 1.410558 -0.887923 -0.790191 +v 1.399427 -0.930768 -0.790197 +v 1.486778 -0.712005 -0.335864 +v 1.489723 -0.652214 -0.335857 +v 1.463122 -0.650902 -0.334242 +v 1.460277 -0.711746 -0.334258 +v 1.489961 -0.596648 -0.335808 +v 1.463230 -0.593096 -0.334163 +v 1.470621 -0.832323 -0.335845 +v 1.480706 -0.771741 -0.335861 +v 1.454191 -0.771626 -0.334248 +v 1.444102 -0.831048 -0.334209 +v 1.434709 -0.771211 -0.330875 +v 1.422420 -0.830547 -0.330552 +v 1.444512 -0.939809 -0.335765 +v 1.456782 -0.892825 -0.335806 +v 1.430857 -0.888907 -0.334208 +v 1.419159 -0.933177 -0.334162 +v 1.410558 -0.887911 -0.331306 +v 1.399427 -0.930768 -0.331300 +v 1.377446 -0.953183 -0.345055 +v 1.382121 -0.955058 -0.346078 +v 1.382163 -0.954910 -0.335687 +v 1.377488 -0.953029 -0.334614 +v 1.392341 -0.957092 -0.347844 +v 1.392385 -0.957004 -0.337533 +v 1.392688 -0.955873 -0.333070 +v 1.382461 -0.953803 -0.331191 +v 1.377783 -0.951938 -0.330093 +v 1.487942 -0.549137 -0.335689 +v 1.461761 -0.542276 -0.334050 +v 1.484720 -0.506526 -0.335528 +v 1.459208 -0.495513 -0.333817 +v 1.439173 -0.488446 -0.330739 +v 1.441200 -0.537309 -0.331053 +v 1.423376 -0.544972 -0.793513 +v 1.428382 -0.546220 -0.792394 +v 1.419127 -0.496298 -0.793941 +v 1.424260 -0.497896 -0.792779 +v 1.435480 -0.501391 -0.790759 +v 1.439269 -0.549658 -0.790445 +v 1.558009 -0.587393 -0.329205 +v 1.554473 -0.569502 -0.327315 +v 1.547273 -0.568839 -0.328704 +v 1.550338 -0.604399 -0.329240 +v 1.549336 -0.550791 -0.327132 +v 1.542525 -0.540651 -0.328210 +v 1.530441 -0.532862 -0.330546 +v 1.534942 -0.565068 -0.330968 +v 1.537878 -0.604208 -0.331280 +v 1.506994 -0.974743 -0.329634 +v 1.520586 -0.913626 -0.329774 +v 1.515423 -0.912310 -0.329381 +v 1.501939 -0.972525 -0.329242 +v 1.535714 -0.839157 -0.329865 +v 1.530448 -0.838732 -0.329472 +v 1.518333 -0.837386 -0.331394 +v 1.503549 -0.908219 -0.331322 +v 1.490311 -0.965657 -0.331212 +v 1.546368 -0.772472 -0.329901 +v 1.541055 -0.772450 -0.329509 +v 1.552557 -0.712660 -0.329906 +v 1.547238 -0.712673 -0.329514 +v 1.534998 -0.712568 -0.331427 +v 1.528836 -0.772306 -0.331423 +v 1.555787 -0.653804 -0.329843 +v 1.550258 -0.655092 -0.329480 +v 1.537959 -0.654910 -0.331408 +v 1.436813 -0.964736 -0.448275 +v 1.461910 -0.978839 -0.447486 +v 1.461910 -0.979546 -0.419370 +v 1.436813 -0.965243 -0.420362 +v 1.461910 -0.981129 -0.392540 +v 1.436813 -0.966363 -0.393733 +v 1.436813 -0.966411 -0.504507 +v 1.461910 -0.981200 -0.504110 +v 1.461910 -0.979555 -0.475801 +v 1.436813 -0.965249 -0.476393 +v 1.436813 -0.968194 -0.560748 +v 1.461910 -0.983795 -0.560748 +v 1.461910 -0.982962 -0.532426 +v 1.436813 -0.967626 -0.532626 +v 1.436813 -0.966411 -0.616990 +v 1.461910 -0.981200 -0.617387 +v 1.461910 -0.982962 -0.589071 +v 1.436813 -0.967626 -0.588871 +v 1.436813 -0.964736 -0.673221 +v 1.461910 -0.978839 -0.674011 +v 1.461910 -0.979555 -0.645696 +v 1.436813 -0.965249 -0.645104 +v 1.436813 -0.966361 -0.727697 +v 1.461910 -0.981125 -0.728890 +v 1.461910 -0.979545 -0.702119 +v 1.436813 -0.965243 -0.701127 +v 1.436813 -0.968451 -0.769227 +v 1.461910 -0.984175 -0.770754 +v 1.461910 -0.982833 -0.752685 +v 1.436813 -0.967539 -0.751307 +v 1.486726 -0.714630 -0.785633 +v 1.489547 -0.657460 -0.785640 +v 1.516294 -0.658003 -0.787185 +v 1.513494 -0.714901 -0.787174 +v 1.489536 -0.604529 -0.785689 +v 1.516138 -0.606461 -0.787263 +v 1.470621 -0.832616 -0.785652 +v 1.480700 -0.772763 -0.785635 +v 1.507435 -0.773236 -0.787177 +v 1.497127 -0.835215 -0.787194 +v 1.444512 -0.939809 -0.785732 +v 1.456782 -0.892861 -0.785690 +v 1.482763 -0.900528 -0.787239 +v 1.469955 -0.952676 -0.787305 +v 1.436813 -0.968461 -0.352005 +v 1.461910 -0.984189 -0.350475 +v 1.461959 -0.984654 -0.340234 +v 1.436860 -0.968724 -0.341856 +v 1.462303 -0.983414 -0.335803 +v 1.437190 -0.967522 -0.337453 +v 1.487119 -0.558698 -0.785808 +v 1.513369 -0.563918 -0.787450 +v 1.483415 -0.517130 -0.785969 +v 1.509186 -0.526779 -0.787704 +v 1.437190 -0.967520 -0.783978 +v 1.462303 -0.983410 -0.785627 +v 1.461959 -0.984644 -0.781070 +v 1.436860 -0.968717 -0.779450 +v 1.482395 -0.999352 -0.788680 +v 1.482039 -1.000620 -0.784073 +v 1.377783 -0.951938 -0.791338 +v 1.382461 -0.953803 -0.790240 +v 1.382163 -0.954910 -0.785618 +v 1.377488 -0.953029 -0.786692 +v 1.392688 -0.955873 -0.788361 +v 1.392385 -0.957003 -0.783773 +v 1.493782 -1.007588 -0.790715 +v 1.493528 -1.008874 -0.786224 +v 1.498096 -1.009203 -0.790882 +v 1.498733 -1.010101 -0.787214 +v 1.506994 -0.974738 -0.791795 +v 1.520586 -0.913688 -0.791656 +v 1.522486 -0.914195 -0.788319 +v 1.508657 -0.975990 -0.787896 +v 1.535714 -0.839667 -0.791566 +v 1.537707 -0.839797 -0.788376 +v 1.539283 -0.839954 -0.785066 +v 1.523895 -0.914824 -0.784448 +v 1.508362 -0.982173 -0.778874 +v 1.546356 -0.774018 -0.791531 +v 1.548364 -0.774086 -0.788352 +v 1.552462 -0.715331 -0.791527 +v 1.554473 -0.715445 -0.788349 +v 1.556051 -0.715685 -0.785054 +v 1.549942 -0.774273 -0.785054 +v 1.555484 -0.657086 -0.791589 +v 1.557485 -0.657728 -0.788208 +v 1.557356 -0.590312 -0.792228 +v 1.558858 -0.599201 -0.787495 +v 1.559073 -0.601275 -0.777501 +v 1.558953 -0.658711 -0.784274 +v 1.418286 -0.657184 -0.760853 +v 1.415405 -0.714288 -0.760836 +v 1.418697 -0.602621 -0.760969 +v 1.409466 -0.772081 -0.760809 +v 1.399996 -0.829563 -0.760619 +v 1.387557 -0.883991 -0.760180 +v 1.376721 -0.924786 -0.759713 +v 1.417307 -0.551938 -0.761250 +v 1.414991 -0.503559 -0.761631 +v 1.461910 -0.982843 -0.368619 +v 1.436813 -0.967546 -0.369998 +v 1.481988 -0.998353 -0.366031 +v 1.382121 -0.955029 -0.364588 +v 1.377446 -0.953176 -0.363650 +v 1.392341 -0.956928 -0.366201 +v 1.420115 -0.588729 -0.327447 +v 1.418409 -0.533396 -0.328115 +v 1.416505 -0.532739 -0.332406 +v 1.418541 -0.589250 -0.332738 +v 1.415832 -0.480939 -0.327638 +v 1.413291 -0.478680 -0.331836 +v 1.377989 -0.925274 -0.328449 +v 1.388857 -0.884700 -0.328483 +v 1.387732 -0.884021 -0.332805 +v 1.376880 -0.924847 -0.332692 +v 1.401859 -0.829792 -0.327530 +v 1.400191 -0.829503 -0.332859 +v 1.409980 -0.771205 -0.327579 +v 1.409531 -0.771532 -0.332907 +v 1.415642 -0.711705 -0.327586 +v 1.415434 -0.711651 -0.332919 +v 1.418660 -0.650262 -0.327570 +v 1.418303 -0.649882 -0.332892 +v 1.527191 -0.911722 -0.619281 +v 1.542293 -0.839872 -0.621222 +v 1.545304 -0.840388 -0.611167 +v 1.530478 -0.910916 -0.609751 +v 1.561992 -0.660195 -0.501113 +v 1.562923 -0.620594 -0.509847 +v 1.559062 -0.715361 -0.499892 +v 1.562072 -0.716223 -0.510034 +v 1.564901 -0.662677 -0.510903 +v 1.565230 -0.630924 -0.515105 +v 1.552952 -0.774143 -0.499940 +v 1.555963 -0.774764 -0.510071 +v 1.493510 -1.006427 -0.364136 +v 1.498864 -1.007636 -0.363161 +v 1.498864 -1.005345 -0.387794 +v 1.502017 -1.000373 -0.387418 +v 1.501757 -1.004004 -0.362782 +v 1.498864 -1.007636 -0.363161 +v 1.504898 -0.997077 -0.362202 +v 1.502017 -1.004429 -0.343969 +v 1.498864 -1.009451 -0.344469 +v 1.372319 -0.948588 -0.329509 +v 1.372962 -0.944088 -0.328606 +v 1.371892 -0.943656 -0.332748 +v 1.371663 -0.948842 -0.333150 +v 1.371736 -0.943605 -0.343191 +v 1.371527 -0.948894 -0.343522 +v 1.371527 -0.948886 -0.734477 +v 1.371736 -0.943604 -0.734825 +v 1.371736 -0.943605 -0.759414 +v 1.371527 -0.948893 -0.759071 +v 1.371736 -0.943605 -0.778040 +v 1.371527 -0.948894 -0.777709 +v 1.498096 -1.009203 -0.790882 +v 1.500367 -1.003183 -0.791757 +v 1.501968 -1.003955 -0.787643 +v 1.498733 -1.010101 -0.787214 +v 1.502017 -1.004411 -0.777249 +v 1.498864 -1.009432 -0.776752 +v 1.437190 -0.967520 -0.783978 +v 1.438671 -0.961781 -0.785534 +v 1.463850 -0.977125 -0.787153 +v 1.462303 -0.983410 -0.785627 +v 1.483995 -0.992559 -0.790185 +v 1.482395 -0.999352 -0.788680 +v 1.498096 -1.009211 -0.330512 +v 1.500367 -1.003188 -0.329666 +v 1.495479 -1.000689 -0.329305 +v 1.493782 -1.007593 -0.330708 +v 1.483995 -0.992559 -0.331304 +v 1.482395 -0.999356 -0.332749 +v 1.437190 -0.967522 -0.337453 +v 1.438671 -0.961782 -0.335955 +v 1.413578 -0.953765 -0.334372 +v 1.412164 -0.959114 -0.335903 +v 1.394051 -0.950761 -0.331511 +v 1.392688 -0.955873 -0.333070 +v 1.377783 -0.951938 -0.791338 +v 1.379106 -0.947041 -0.792982 +v 1.383796 -0.948823 -0.791873 +v 1.382461 -0.953803 -0.790240 +v 1.394051 -0.950761 -0.789978 +v 1.392688 -0.955873 -0.788361 +v 1.498864 -1.002334 -0.444323 +v 1.502223 -0.996044 -0.444049 +v 1.502197 -0.997146 -0.415082 +v 1.498864 -1.003258 -0.415406 +v 1.498864 -1.005441 -0.502522 +v 1.502017 -1.000467 -0.502390 +v 1.502197 -0.997157 -0.473216 +v 1.498864 -1.003270 -0.473428 +v 1.498864 -1.008919 -0.560749 +v 1.501601 -1.006063 -0.560749 +v 1.501679 -1.004555 -0.531576 +v 1.498864 -1.007797 -0.531630 +v 1.498864 -1.005441 -0.618976 +v 1.502017 -1.000467 -0.619107 +v 1.501679 -1.004555 -0.589922 +v 1.498864 -1.007797 -0.589868 +v 1.498864 -1.002334 -0.677175 +v 1.502223 -0.996044 -0.677449 +v 1.502197 -0.997157 -0.648282 +v 1.498864 -1.003270 -0.648070 +v 1.498864 -1.005340 -0.733635 +v 1.502017 -1.000369 -0.734013 +v 1.502197 -0.997146 -0.706409 +v 1.498864 -1.003257 -0.706084 +v 1.501757 -1.003990 -0.758516 +v 1.498864 -1.007622 -0.758139 +v 1.504898 -0.997064 -0.759093 +v 1.371527 -0.948865 -0.677736 +v 1.371736 -0.943601 -0.678014 +v 1.371736 -0.943602 -0.707118 +v 1.371527 -0.948873 -0.706793 +v 1.371527 -0.948886 -0.619262 +v 1.371736 -0.943604 -0.619408 +v 1.371736 -0.943602 -0.648708 +v 1.371527 -0.948873 -0.648492 +v 1.371527 -0.948894 -0.560749 +v 1.371736 -0.943605 -0.560749 +v 1.371736 -0.943605 -0.590086 +v 1.371527 -0.948893 -0.590013 +v 1.371527 -0.948886 -0.502236 +v 1.371736 -0.943604 -0.502090 +v 1.371736 -0.943605 -0.531412 +v 1.371527 -0.948893 -0.531486 +v 1.371527 -0.948865 -0.443762 +v 1.371736 -0.943601 -0.443484 +v 1.371736 -0.943602 -0.472791 +v 1.371527 -0.948873 -0.473006 +v 1.371527 -0.948886 -0.386955 +v 1.371736 -0.943604 -0.386606 +v 1.371736 -0.943602 -0.414372 +v 1.371527 -0.948873 -0.414697 +v 1.371736 -0.943605 -0.361892 +v 1.371527 -0.948893 -0.362236 +v 1.371892 -0.943656 -0.788557 +v 1.371663 -0.948842 -0.788152 +v 1.372962 -0.944088 -0.792820 +v 1.372319 -0.948588 -0.791889 +v 1.495479 -1.000688 -0.792176 +v 1.493782 -1.007588 -0.790715 +v 1.500367 -1.003183 -0.791757 +v 1.498096 -1.009203 -0.790882 +v 1.501968 -1.003968 -0.333654 +v 1.498733 -1.010115 -0.334081 +v 1.500367 -1.003188 -0.329666 +v 1.498096 -1.009211 -0.330512 +v 1.377783 -0.951938 -0.330093 +v 1.379106 -0.947041 -0.328507 +v 1.375525 -0.945348 -0.327789 +v 1.374296 -0.950120 -0.329334 +v 1.372962 -0.944088 -0.328606 +v 1.372319 -0.948588 -0.329509 +v 1.562072 -0.716630 -0.777173 +v 1.564901 -0.663120 -0.776522 +v 1.565998 -0.663279 -0.762641 +v 1.563201 -0.717075 -0.762664 +v 1.565230 -0.631139 -0.773360 +v 1.565860 -0.625679 -0.762444 +v 1.565230 -0.632480 -0.751360 +v 1.564901 -0.664387 -0.748397 +v 1.562072 -0.719485 -0.611462 +v 1.564901 -0.668381 -0.610594 +v 1.566186 -0.666872 -0.589744 +v 1.563390 -0.719237 -0.589908 +v 1.565230 -0.637711 -0.606391 +v 1.566024 -0.629413 -0.589251 +v 1.566188 -0.625867 -0.560748 +v 1.566374 -0.665157 -0.560748 +v 1.563578 -0.718490 -0.560748 +v 1.566186 -0.663504 -0.531751 +v 1.563390 -0.717361 -0.531587 +v 1.566024 -0.624864 -0.532245 +v 1.555963 -0.775068 -0.777159 +v 1.557092 -0.775268 -0.762626 +v 1.546433 -0.840466 -0.762386 +v 1.555963 -0.776171 -0.611426 +v 1.557281 -0.776217 -0.589888 +v 1.546621 -0.840796 -0.589745 +v 1.557469 -0.775944 -0.560748 +v 1.546809 -0.840898 -0.560748 +v 1.557281 -0.775408 -0.531608 +v 1.546621 -0.840554 -0.531750 +v 1.531352 -0.912593 -0.761816 +v 1.517773 -0.967269 -0.761069 +v 1.530478 -0.910820 -0.747041 +v 1.519408 -0.957129 -0.749470 +v 1.531428 -0.913220 -0.589260 +v 1.531504 -0.914183 -0.560747 +v 1.531428 -0.913190 -0.532235 +v 1.566208 -0.656947 -0.358666 +v 1.563272 -0.712830 -0.358637 +v 1.566204 -0.617876 -0.358869 +v 1.565589 -0.625004 -0.347848 +v 1.565144 -0.658221 -0.344654 +v 1.562156 -0.713166 -0.343993 +v 1.557101 -0.773078 -0.358670 +v 1.546433 -0.839769 -0.358907 +v 1.555974 -0.773185 -0.344003 +v 1.545304 -0.839966 -0.344074 +v 1.519408 -0.957135 -0.371922 +v 1.530478 -0.910725 -0.374380 +v 1.531352 -0.912512 -0.359474 +v 1.517773 -0.967280 -0.360219 +v 1.530478 -0.912201 -0.344948 +v 1.519408 -0.958775 -0.348521 +v 1.549942 -0.774273 -0.785054 +v 1.552952 -0.774663 -0.783198 +v 1.556051 -0.715685 -0.785054 +v 1.559062 -0.716114 -0.783200 +v 1.552952 -0.774663 -0.783198 +v 1.559062 -0.716114 -0.783200 +v 1.561992 -0.663073 -0.740664 +v 1.562923 -0.623154 -0.746980 +v 1.558953 -0.658711 -0.784274 +v 1.561992 -0.661130 -0.782312 +v 1.559073 -0.601275 -0.777501 +v 1.562922 -0.621147 -0.776101 +v 1.561992 -0.661130 -0.782312 +v 1.562922 -0.621147 -0.776101 +v 1.527191 -0.911566 -0.382511 +v 1.514097 -0.969077 -0.376744 +v 1.559383 -0.592718 -0.384184 +v 1.559509 -0.594106 -0.361055 +v 1.563628 -0.600939 -0.359531 +v 1.563223 -0.613173 -0.374466 +v 1.559509 -0.594106 -0.361055 +v 1.559596 -0.595477 -0.343741 +v 1.563339 -0.615264 -0.345086 +v 1.563628 -0.600939 -0.359531 +v 1.563628 -0.600939 -0.359531 +v 1.563339 -0.615264 -0.345086 +v 1.565589 -0.625004 -0.347848 +v 1.566204 -0.617876 -0.358869 +v 1.563223 -0.613173 -0.374466 +v 1.563628 -0.600939 -0.359531 +v 1.566204 -0.617876 -0.358869 +v 1.565514 -0.623508 -0.370056 +v 1.559596 -0.595477 -0.343741 +v 1.559237 -0.654693 -0.336903 +v 1.562260 -0.656878 -0.338815 +v 1.563339 -0.615264 -0.345086 +v 1.556144 -0.712702 -0.336113 +v 1.559152 -0.713009 -0.337916 +v 1.562260 -0.656878 -0.338815 +v 1.559152 -0.713009 -0.337916 +v 1.563339 -0.615264 -0.345086 +v 1.552952 -0.775819 -0.621558 +v 1.559062 -0.719243 -0.621606 +v 1.539283 -0.839401 -0.336097 +v 1.523895 -0.914766 -0.336713 +v 1.527191 -0.913803 -0.338837 +v 1.542293 -0.839738 -0.337916 +v 1.508362 -0.982192 -0.342310 +v 1.514097 -0.971512 -0.345454 +v 1.527191 -0.913803 -0.338837 +v 1.514097 -0.971512 -0.345454 +v 1.542293 -0.839738 -0.337916 +v 1.561992 -0.667052 -0.620385 +v 1.562922 -0.628671 -0.611651 +v 1.509587 -0.990232 -0.760186 +v 1.514097 -0.969073 -0.744679 +v 1.549953 -0.772577 -0.336112 +v 1.552964 -0.772918 -0.337916 +v 1.552964 -0.772918 -0.337916 +v 1.527191 -0.911668 -0.738969 +v 1.559073 -0.601275 -0.777501 +v 1.559073 -0.602786 -0.760269 +v 1.563219 -0.609357 -0.761786 +v 1.562922 -0.621147 -0.776101 +v 1.559073 -0.602786 -0.760269 +v 1.559073 -0.604817 -0.737268 +v 1.562923 -0.623154 -0.746980 +v 1.563219 -0.609357 -0.761786 +v 1.563219 -0.609357 -0.761786 +v 1.562923 -0.623154 -0.746980 +v 1.565230 -0.632480 -0.751360 +v 1.565860 -0.625679 -0.762444 +v 1.562922 -0.621147 -0.776101 +v 1.563219 -0.609357 -0.761786 +v 1.565860 -0.625679 -0.762444 +v 1.565230 -0.631139 -0.773360 +v 1.509587 -0.990245 -0.361103 +v 1.463850 -0.977125 -0.334335 +v 1.462303 -0.983414 -0.335803 +v 1.469955 -0.952676 -0.334192 +v 1.413578 -0.953765 -0.787117 +v 1.412164 -0.959113 -0.785527 +v 1.419159 -0.933177 -0.787334 +v 1.411804 -0.959082 -0.392558 +v 1.411804 -0.959733 -0.368644 +v 1.411804 -0.960217 -0.350524 +v 1.412164 -0.959113 -0.785527 +v 1.411849 -0.960274 -0.780981 +v 1.411804 -0.960212 -0.770708 +v 1.460401 -0.553784 -0.787447 +v 1.462724 -0.602608 -0.787334 +v 1.456738 -0.508112 -0.787680 +v 1.411849 -0.960278 -0.340325 +v 1.412164 -0.959114 -0.335903 +v 1.430857 -0.888932 -0.787289 +v 1.444102 -0.831252 -0.787287 +v 1.434707 -0.771879 -0.790622 +v 1.454187 -0.772447 -0.787249 +v 1.460248 -0.714364 -0.787239 +v 1.462994 -0.656910 -0.787255 +v 1.411804 -0.959730 -0.752662 +v 1.411804 -0.959081 -0.728872 +v 1.411804 -0.958427 -0.702104 +v 1.411804 -0.958121 -0.673999 +v 1.411804 -0.958431 -0.645687 +v 1.411804 -0.959107 -0.617381 +v 1.411804 -0.959775 -0.589068 +v 1.411804 -0.960076 -0.560748 +v 1.411804 -0.959775 -0.532429 +v 1.411804 -0.959107 -0.504115 +v 1.411804 -0.958431 -0.475809 +v 1.411804 -0.958121 -0.447498 +v 1.411804 -0.958428 -0.419384 +v 1.514047 -0.557637 -0.334047 +v 1.516582 -0.600727 -0.334234 +v 1.510104 -0.520500 -0.333793 +v 1.482763 -0.900481 -0.334258 +v 1.497127 -0.834838 -0.334302 +v 1.507445 -0.772017 -0.334320 +v 1.513567 -0.712315 -0.334323 +v 1.516523 -0.653690 -0.334312 +v 1.430129 -0.711275 -0.286527 +v 1.432880 -0.651365 -0.284750 +v 1.430718 -0.650993 -0.253493 +v 1.427982 -0.711030 -0.256080 +v 1.432550 -0.606121 -0.280044 +v 1.430442 -0.605671 -0.249241 +v 1.428623 -0.605338 -0.221757 +v 1.428828 -0.650719 -0.224786 +v 1.426101 -0.710869 -0.227967 +v 1.415947 -0.606025 -0.236239 +v 1.413388 -0.651227 -0.234264 +v 1.412048 -0.650862 -0.217730 +v 1.414481 -0.605109 -0.218061 +v 1.410264 -0.711134 -0.236510 +v 1.408964 -0.711002 -0.220704 +v 1.408232 -0.710936 -0.217449 +v 1.411162 -0.650313 -0.213938 +v 1.412664 -0.599688 -0.210630 +v 1.425063 -0.715414 -0.872872 +v 1.419640 -0.771564 -0.872247 +v 1.418045 -0.771916 -0.888050 +v 1.423458 -0.715674 -0.888814 +v 1.413505 -0.813093 -0.871773 +v 1.411914 -0.813515 -0.887421 +v 1.411524 -0.813664 -0.892958 +v 1.417653 -0.772041 -0.893632 +v 1.423064 -0.715767 -0.894437 +v 1.407640 -0.830498 -0.266450 +v 1.412666 -0.828048 -0.277440 +v 1.410821 -0.828061 -0.252786 +v 1.405986 -0.830512 -0.245037 +v 1.418295 -0.810927 -0.285155 +v 1.416294 -0.810904 -0.257780 +v 1.414563 -0.810941 -0.233166 +v 1.409279 -0.828119 -0.232275 +v 1.404682 -0.830553 -0.229691 +v 1.424529 -0.586380 -0.322974 +v 1.428452 -0.583606 -0.324222 +v 1.423501 -0.570806 -0.326756 +v 1.421315 -0.605340 -0.322179 +v 1.424529 -0.586380 -0.322974 +v 1.420800 -0.607060 -0.305478 +v 1.424164 -0.588360 -0.308208 +v 1.428452 -0.583606 -0.324222 +v 1.428282 -0.585572 -0.312086 +v 1.419041 -0.657920 -0.799260 +v 1.415919 -0.713997 -0.799278 +v 1.421227 -0.615313 -0.799068 +v 1.420455 -0.617263 -0.814049 +v 1.418153 -0.658458 -0.814269 +v 1.415006 -0.714251 -0.814232 +v 1.427609 -0.769620 -0.327091 +v 1.420691 -0.812929 -0.326704 +v 1.427609 -0.769620 -0.327091 +v 1.426767 -0.769239 -0.320579 +v 1.420691 -0.812929 -0.326704 +v 1.420550 -0.810933 -0.319664 +v 1.410727 -0.769677 -0.322059 +v 1.415954 -0.711737 -0.321936 +v 1.406510 -0.812878 -0.322428 +v 1.406453 -0.810943 -0.307394 +v 1.410188 -0.769274 -0.305836 +v 1.415288 -0.711658 -0.305056 +v 1.427464 -0.770273 -0.795635 +v 1.420554 -0.813096 -0.795924 +v 1.427464 -0.770273 -0.795635 +v 1.420554 -0.813096 -0.795924 +v 1.419456 -0.811451 -0.810874 +v 1.425610 -0.770192 -0.810745 +v 1.410688 -0.770163 -0.799232 +v 1.409883 -0.770109 -0.814069 +v 1.410532 -0.847808 -0.328671 +v 1.414926 -0.830384 -0.325691 +v 1.410609 -0.832788 -0.324436 +v 1.414926 -0.830384 -0.325691 +v 1.415398 -0.828007 -0.317153 +v 1.410609 -0.832788 -0.324436 +v 1.411038 -0.830448 -0.313683 +v 1.419084 -0.651826 -0.321911 +v 1.418436 -0.652061 -0.304669 +v 1.425168 -0.711120 -0.205478 +v 1.427860 -0.650882 -0.202016 +v 1.427582 -0.651418 -0.196551 +v 1.424906 -0.711323 -0.199966 +v 1.427477 -0.605448 -0.199661 +v 1.427106 -0.607458 -0.194366 +v 1.426004 -0.616480 -0.191574 +v 1.425846 -0.652602 -0.192661 +v 1.423129 -0.711450 -0.195890 +v 1.371618 -0.712177 -0.896213 +v 1.374183 -0.655637 -0.896580 +v 1.318842 -0.649200 -0.896562 +v 1.316999 -0.706541 -0.896660 +v 1.375001 -0.613546 -0.897814 +v 1.318965 -0.605904 -0.897421 +v 1.246812 -0.600154 -0.897380 +v 1.247152 -0.643410 -0.896851 +v 1.245812 -0.700198 -0.897333 +v 1.423368 -0.715886 -0.901587 +v 1.417959 -0.772203 -0.900770 +v 1.418088 -0.771959 -0.904092 +v 1.423454 -0.715941 -0.904922 +v 1.411829 -0.813858 -0.900082 +v 1.412171 -0.812265 -0.903370 +v 1.412767 -0.804187 -0.905526 +v 1.417242 -0.771056 -0.906574 +v 1.422448 -0.715976 -0.907470 +v 1.402586 -0.830751 -0.213907 +v 1.407760 -0.828428 -0.213747 +v 1.407522 -0.826236 -0.208094 +v 1.401944 -0.828409 -0.208217 +v 1.413464 -0.811308 -0.212471 +v 1.413335 -0.809830 -0.206961 +v 1.407522 -0.826236 -0.208094 +v 1.413335 -0.809830 -0.206961 +v 1.413397 -0.801772 -0.203108 +v 1.409077 -0.809835 -0.202915 +v 1.401944 -0.828409 -0.208217 +v 1.403346 -0.811313 -0.202856 +v 1.408757 -0.715303 -0.874696 +v 1.411886 -0.659151 -0.875042 +v 1.409962 -0.659168 -0.890542 +v 1.406831 -0.715550 -0.890090 +v 1.414198 -0.617687 -0.875049 +v 1.412344 -0.617203 -0.890713 +v 1.410353 -0.612303 -0.896421 +v 1.407734 -0.658686 -0.895180 +v 1.404611 -0.715485 -0.894600 +v 1.421401 -0.598271 -0.874340 +v 1.425256 -0.600766 -0.873897 +v 1.423627 -0.600847 -0.889846 +v 1.419757 -0.598347 -0.890194 +v 1.427786 -0.617868 -0.873529 +v 1.426168 -0.617974 -0.889541 +v 1.425771 -0.618012 -0.895185 +v 1.423226 -0.600875 -0.895472 +v 1.419351 -0.598374 -0.895791 +v 1.424655 -0.584686 -0.257512 +v 1.419829 -0.587335 -0.244886 +v 1.418258 -0.586838 -0.223831 +v 1.422897 -0.584289 -0.232778 +v 1.417055 -0.585788 -0.212238 +v 1.421525 -0.584076 -0.215306 +v 1.424675 -0.769124 -0.287426 +v 1.422577 -0.769007 -0.258214 +v 1.420742 -0.768964 -0.231282 +v 1.399917 -0.813075 -0.873293 +v 1.403674 -0.771508 -0.874032 +v 1.401745 -0.771987 -0.889321 +v 1.398004 -0.814069 -0.888580 +v 1.399466 -0.772348 -0.893902 +v 1.395320 -0.818954 -0.894082 +v 1.427786 -0.617868 -0.873529 +v 1.427852 -0.659319 -0.873256 +v 1.426241 -0.659490 -0.889269 +v 1.426168 -0.617974 -0.889541 +v 1.425846 -0.659550 -0.894913 +v 1.425771 -0.618012 -0.895185 +v 1.405287 -0.769039 -0.240153 +v 1.403962 -0.769117 -0.224778 +v 1.401845 -0.810907 -0.246024 +v 1.400361 -0.811473 -0.230036 +v 1.397876 -0.816270 -0.223963 +v 1.403025 -0.769486 -0.221308 +v 1.404263 -0.832639 -0.872233 +v 1.400662 -0.830194 -0.872708 +v 1.398977 -0.830788 -0.888035 +v 1.402650 -0.833094 -0.887650 +v 1.400662 -0.830194 -0.872708 +v 1.398977 -0.830788 -0.888035 +v 1.398315 -0.831781 -0.893476 +v 1.398315 -0.831781 -0.893476 +v 1.402255 -0.833255 -0.893119 +v 1.407905 -0.769399 -0.198092 +v 1.401167 -0.769115 -0.198061 +v 1.396813 -0.810973 -0.202818 +v 1.413009 -0.711373 -0.193955 +v 1.406235 -0.711207 -0.193933 +v 1.395237 -0.710580 -0.193847 +v 1.390265 -0.768233 -0.197953 +v 1.386479 -0.809978 -0.202699 +v 1.415946 -0.651299 -0.190742 +v 1.409196 -0.651266 -0.190730 +v 1.417333 -0.605913 -0.190073 +v 1.410780 -0.605987 -0.190065 +v 1.400394 -0.605858 -0.190017 +v 1.398262 -0.650917 -0.190665 +v 1.415706 -0.715958 -0.909152 +v 1.418647 -0.659629 -0.909477 +v 1.422535 -0.659982 -0.909036 +v 1.419622 -0.715977 -0.908705 +v 1.419690 -0.618016 -0.908647 +v 1.423486 -0.619741 -0.908246 +v 1.425589 -0.627872 -0.907562 +v 1.425248 -0.660948 -0.907846 +v 1.422448 -0.715976 -0.907470 +v 1.405444 -0.814006 -0.906384 +v 1.410456 -0.772336 -0.908176 +v 1.414390 -0.772025 -0.907743 +v 1.409484 -0.812326 -0.906023 +v 1.417242 -0.771056 -0.906574 +v 1.412767 -0.804187 -0.905526 +v 1.350789 -0.824374 -0.213116 +v 1.342751 -0.821028 -0.207320 +v 1.296599 -0.814322 -0.206668 +v 1.302100 -0.817242 -0.212418 +v 1.342751 -0.821028 -0.207320 +v 1.338643 -0.803682 -0.201928 +v 1.294291 -0.797645 -0.201319 +v 1.296599 -0.814322 -0.206668 +v 1.238813 -0.790106 -0.201316 +v 1.238688 -0.805861 -0.206769 +v 1.238688 -0.805861 -0.206769 +v 1.240423 -0.808152 -0.212475 +v 1.419652 -0.598410 -0.902936 +v 1.423529 -0.600912 -0.902624 +v 1.423712 -0.603284 -0.905921 +v 1.419858 -0.600873 -0.906249 +v 1.426075 -0.618061 -0.902343 +v 1.426173 -0.619758 -0.905593 +v 1.423712 -0.603284 -0.905921 +v 1.426173 -0.619758 -0.905593 +v 1.419858 -0.600873 -0.906249 +v 1.419384 -0.584214 -0.198563 +v 1.413985 -0.584363 -0.198550 +v 1.412321 -0.587169 -0.193187 +v 1.418384 -0.587041 -0.193195 +v 1.406775 -0.584402 -0.198519 +v 1.403283 -0.587155 -0.193149 +v 1.412321 -0.587169 -0.193187 +v 1.403283 -0.587155 -0.193149 +v 1.418384 -0.587041 -0.193195 +v 1.419801 -0.769299 -0.209384 +v 1.419569 -0.769195 -0.203882 +v 1.417972 -0.768347 -0.199866 +v 1.413397 -0.801772 -0.203108 +v 1.345615 -0.707189 -0.193204 +v 1.349026 -0.650281 -0.189988 +v 1.305630 -0.651577 -0.189115 +v 1.301980 -0.704756 -0.192544 +v 1.352871 -0.607630 -0.189278 +v 1.309116 -0.612303 -0.188179 +v 1.251979 -0.614264 -0.187074 +v 1.249485 -0.650923 -0.188133 +v 1.246159 -0.701028 -0.191810 +v 1.426075 -0.618061 -0.902343 +v 1.426149 -0.659629 -0.902070 +v 1.426233 -0.659981 -0.905385 +v 1.426173 -0.619758 -0.905593 +v 1.425248 -0.660948 -0.907846 +v 1.425589 -0.627872 -0.907562 +v 1.382077 -0.608026 -0.208554 +v 1.383309 -0.651392 -0.212689 +v 1.329420 -0.652117 -0.211718 +v 1.329382 -0.612393 -0.207385 +v 1.380568 -0.709254 -0.216467 +v 1.326235 -0.705930 -0.215681 +v 1.254383 -0.700865 -0.214759 +v 1.257553 -0.650604 -0.210589 +v 1.258853 -0.613895 -0.206177 +v 1.402558 -0.833463 -0.900223 +v 1.398384 -0.833427 -0.900581 +v 1.398944 -0.831071 -0.903975 +v 1.403119 -0.831107 -0.903592 +v 1.393758 -0.833180 -0.901197 +v 1.394315 -0.830825 -0.904763 +v 1.398944 -0.831071 -0.903975 +v 1.394315 -0.830825 -0.904763 +v 1.396636 -0.813737 -0.907700 +v 1.401269 -0.813970 -0.906786 +v 1.403119 -0.831107 -0.903592 +v 1.246612 -0.579602 -0.904793 +v 1.246721 -0.582134 -0.909361 +v 1.177229 -0.584749 -0.910188 +v 1.177168 -0.582393 -0.905633 +v 1.246721 -0.582134 -0.909361 +v 1.247055 -0.600068 -0.913078 +v 1.177406 -0.601498 -0.913884 +v 1.177229 -0.584749 -0.910188 +v 1.126362 -0.605893 -0.914607 +v 1.126438 -0.590577 -0.911058 +v 1.126438 -0.590577 -0.911058 +v 1.126417 -0.588427 -0.906601 +v 1.178845 -0.797051 -0.208347 +v 1.178936 -0.799002 -0.214057 +v 1.179432 -0.782067 -0.202521 +v 1.178845 -0.797051 -0.208347 +v 1.132609 -0.775756 -0.204443 +v 1.132668 -0.790241 -0.210573 +v 1.132668 -0.790241 -0.210573 +v 1.132626 -0.792087 -0.216183 +v 1.247437 -0.643364 -0.915297 +v 1.177480 -0.642018 -0.916072 +v 1.246102 -0.700230 -0.916172 +v 1.175896 -0.695627 -0.916941 +v 1.123756 -0.693007 -0.917259 +v 1.125870 -0.643079 -0.916578 +v 1.249952 -0.752007 -0.218807 +v 1.181931 -0.744544 -0.218908 +v 1.184196 -0.694812 -0.214050 +v 1.245638 -0.790202 -0.220465 +v 1.180114 -0.781346 -0.221491 +v 1.132412 -0.774918 -0.222854 +v 1.132216 -0.739113 -0.219280 +v 1.132341 -0.689827 -0.213607 +v 1.375726 -0.613589 -0.912805 +v 1.375034 -0.655743 -0.914195 +v 1.319406 -0.649230 -0.914894 +v 1.319446 -0.605881 -0.913024 +v 1.372488 -0.712365 -0.914202 +v 1.317575 -0.706651 -0.915383 +v 1.359818 -0.828511 -0.903547 +v 1.359911 -0.826019 -0.899281 +v 1.305850 -0.818401 -0.900431 +v 1.305695 -0.820808 -0.904881 +v 1.359911 -0.826019 -0.899281 +v 1.361858 -0.809101 -0.896397 +v 1.307795 -0.801963 -0.897363 +v 1.305850 -0.818401 -0.900431 +v 1.237104 -0.792920 -0.898457 +v 1.235175 -0.808752 -0.901599 +v 1.235175 -0.808752 -0.901599 +v 1.234961 -0.811057 -0.906085 +v 1.366625 -0.768069 -0.895766 +v 1.312418 -0.761922 -0.896528 +v 1.241570 -0.754238 -0.897470 +v 1.375591 -0.593710 -0.905249 +v 1.375771 -0.596198 -0.909567 +v 1.319252 -0.587951 -0.909472 +v 1.319100 -0.585402 -0.904953 +v 1.375771 -0.596198 -0.909567 +v 1.319252 -0.587951 -0.909472 +v 1.367476 -0.768329 -0.913378 +v 1.312982 -0.762105 -0.914859 +v 1.362582 -0.809368 -0.911386 +v 1.308274 -0.802165 -0.912963 +v 1.237345 -0.793059 -0.914155 +v 1.241854 -0.754347 -0.915915 +v 1.375005 -0.765795 -0.220113 +v 1.320810 -0.759810 -0.219375 +v 1.367654 -0.806728 -0.221441 +v 1.314423 -0.799513 -0.220687 +v 1.367980 -0.587522 -0.197794 +v 1.376317 -0.590100 -0.203470 +v 1.325709 -0.596064 -0.202224 +v 1.319970 -0.593765 -0.196553 +v 1.376317 -0.590100 -0.203470 +v 1.325709 -0.596064 -0.202224 +v 1.258124 -0.598895 -0.201007 +v 1.258124 -0.598895 -0.201007 +v 1.256252 -0.596862 -0.195357 +v 1.340856 -0.762861 -0.197249 +v 1.297113 -0.758049 -0.196662 +v 1.241918 -0.752006 -0.196320 +v 1.083758 -0.791695 -0.906742 +v 1.083988 -0.789571 -0.902842 +v 1.081419 -0.787212 -0.902607 +v 1.081183 -0.789254 -0.906206 +v 1.083988 -0.789571 -0.902842 +v 1.085821 -0.774941 -0.900103 +v 1.083225 -0.773190 -0.900152 +v 1.081419 -0.787212 -0.902607 +v 1.081419 -0.787212 -0.902607 +v 1.083225 -0.773190 -0.900152 +v 1.082438 -0.766105 -0.900669 +v 1.081170 -0.772974 -0.902614 +v 1.081183 -0.789254 -0.906206 +v 1.080938 -0.774421 -0.905953 +v 1.103709 -0.687978 -0.194947 +v 1.103726 -0.636611 -0.190985 +v 1.100878 -0.636780 -0.193198 +v 1.100852 -0.687771 -0.197179 +v 1.104174 -0.597549 -0.190252 +v 1.101354 -0.599056 -0.192299 +v 1.100878 -0.636780 -0.193198 +v 1.101354 -0.599056 -0.192299 +v 1.099553 -0.606623 -0.194262 +v 1.098804 -0.637531 -0.195698 +v 1.100852 -0.687771 -0.197179 +v 1.098726 -0.687562 -0.199734 +v 1.094576 -0.691554 -0.899201 +v 1.096974 -0.643696 -0.898990 +v 1.094130 -0.643835 -0.899153 +v 1.091724 -0.691350 -0.899377 +v 1.097788 -0.608341 -0.899665 +v 1.094970 -0.609688 -0.899721 +v 1.093183 -0.616509 -0.900274 +v 1.092083 -0.644541 -0.900156 +v 1.089626 -0.691198 -0.900414 +v 1.105794 -0.772228 -0.208438 +v 1.104658 -0.737064 -0.201442 +v 1.101814 -0.736517 -0.203586 +v 1.102963 -0.770493 -0.210155 +v 1.101814 -0.736517 -0.203586 +v 1.099732 -0.735459 -0.205901 +v 1.102963 -0.770493 -0.210155 +v 1.101037 -0.763467 -0.210603 +v 1.186253 -0.645064 -0.209746 +v 1.187629 -0.608323 -0.205557 +v 1.133059 -0.639068 -0.209246 +v 1.133877 -0.600905 -0.205403 +v 1.171648 -0.747283 -0.916729 +v 1.167263 -0.784547 -0.915028 +v 1.115025 -0.778430 -0.915306 +v 1.119351 -0.742300 -0.916980 +v 1.181129 -0.745356 -0.196616 +v 1.183374 -0.695591 -0.191281 +v 1.132576 -0.690693 -0.191505 +v 1.132447 -0.740040 -0.197643 +v 1.177317 -0.642097 -0.897671 +v 1.175729 -0.695630 -0.898148 +v 1.177267 -0.601612 -0.898224 +v 1.126238 -0.606011 -0.899246 +v 1.125724 -0.643165 -0.898529 +v 1.123608 -0.693017 -0.898825 +v 1.185445 -0.645779 -0.187449 +v 1.186941 -0.608903 -0.186580 +v 1.134072 -0.601515 -0.186978 +v 1.133288 -0.639839 -0.187600 +v 1.165232 -0.799700 -0.902528 +v 1.164998 -0.801916 -0.907006 +v 1.167125 -0.784436 -0.899368 +v 1.165232 -0.799700 -0.902528 +v 1.114902 -0.778323 -0.899945 +v 1.113047 -0.793179 -0.903048 +v 1.113047 -0.793179 -0.903048 +v 1.112813 -0.795336 -0.907441 +v 1.171485 -0.747208 -0.898329 +v 1.119206 -0.742232 -0.898931 +v 1.188066 -0.593292 -0.200530 +v 1.187951 -0.591290 -0.194932 +v 1.188066 -0.593292 -0.200530 +v 1.134275 -0.585225 -0.200649 +v 1.134275 -0.585225 -0.200649 +v 1.134383 -0.583135 -0.195232 +v 1.099102 -0.597119 -0.199685 +v 1.097771 -0.635973 -0.202059 +v 1.097942 -0.636464 -0.198656 +v 1.099218 -0.598871 -0.196267 +v 1.097635 -0.687133 -0.206244 +v 1.097816 -0.687348 -0.202828 +v 1.088695 -0.691123 -0.906220 +v 1.091206 -0.643385 -0.905862 +v 1.091357 -0.643638 -0.909240 +v 1.088855 -0.691129 -0.909602 +v 1.092875 -0.608145 -0.905513 +v 1.092972 -0.609536 -0.908924 +v 1.093295 -0.616412 -0.911218 +v 1.092205 -0.644469 -0.911978 +v 1.089749 -0.691189 -0.912415 +v 1.084346 -0.738945 -0.906115 +v 1.084536 -0.738703 -0.909491 +v 1.081239 -0.773034 -0.909356 +v 1.085496 -0.737985 -0.912225 +v 1.082549 -0.766190 -0.911614 +v 1.098723 -0.736045 -0.212490 +v 1.098889 -0.736016 -0.209031 +v 1.100752 -0.771245 -0.217832 +v 1.100841 -0.770084 -0.214109 +v 1.090093 -0.739478 -0.899242 +v 1.087297 -0.738932 -0.899404 +v 1.085375 -0.737930 -0.900403 +v 1.082438 -0.766105 -0.900669 +v 1.104346 -0.578780 -0.197045 +v 1.104257 -0.580919 -0.201555 +v 1.101379 -0.583092 -0.202148 +v 1.101451 -0.581042 -0.198177 +v 1.104257 -0.580919 -0.201555 +v 1.103979 -0.596938 -0.205563 +v 1.101161 -0.598455 -0.205662 +v 1.101379 -0.583092 -0.202148 +v 1.101161 -0.598455 -0.205662 +v 1.099377 -0.606065 -0.205611 +v 1.099109 -0.598528 -0.203188 +v 1.103474 -0.687114 -0.213312 +v 1.104427 -0.736138 -0.219419 +v 1.101588 -0.735610 -0.219190 +v 1.100622 -0.686925 -0.213105 +v 1.105598 -0.771390 -0.223734 +v 1.102770 -0.769672 -0.223504 +v 1.100860 -0.762724 -0.221941 +v 1.099540 -0.734686 -0.218047 +v 1.098530 -0.686841 -0.212048 +v 1.097912 -0.608222 -0.913311 +v 1.097120 -0.643609 -0.915025 +v 1.094272 -0.643750 -0.913756 +v 1.095092 -0.609573 -0.912206 +v 1.094725 -0.691543 -0.915577 +v 1.091870 -0.691339 -0.914280 +v 1.089749 -0.691189 -0.912415 +v 1.092205 -0.644469 -0.911978 +v 1.093295 -0.616412 -0.911218 +v 1.106290 -0.788259 -0.218859 +v 1.106272 -0.786450 -0.214115 +v 1.103376 -0.784124 -0.215307 +v 1.103376 -0.785854 -0.219515 +v 1.106272 -0.786450 -0.214115 +v 1.103376 -0.784124 -0.215307 +v 1.103376 -0.784124 -0.215307 +v 1.103376 -0.785854 -0.219515 +v 1.098119 -0.591640 -0.906217 +v 1.098121 -0.593680 -0.910175 +v 1.095243 -0.595628 -0.909350 +v 1.095223 -0.593667 -0.905690 +v 1.098121 -0.593680 -0.910175 +v 1.095243 -0.595628 -0.909350 +v 1.095092 -0.609573 -0.912206 +v 1.103497 -0.635841 -0.208972 +v 1.100652 -0.636025 -0.208812 +v 1.098612 -0.636886 -0.207851 +v 1.099377 -0.606065 -0.205611 +v 1.090239 -0.739546 -0.915276 +v 1.087440 -0.738998 -0.914007 +v 1.085945 -0.775047 -0.913749 +v 1.083346 -0.773293 -0.912637 +v 1.082549 -0.766190 -0.911614 +v 1.085496 -0.737985 -0.912225 +v 1.407847 -0.769166 -0.272871 +v 1.412882 -0.711404 -0.270623 +v 1.404280 -0.810936 -0.276889 +v 1.426144 -0.769211 -0.308244 +v 1.419817 -0.810946 -0.306202 +v 1.431616 -0.711453 -0.307999 +v 1.422189 -0.587874 -0.277681 +v 1.426741 -0.585174 -0.287112 +v 1.418508 -0.606555 -0.271120 +v 1.414369 -0.828038 -0.300277 +v 1.409601 -0.830483 -0.292018 +v 1.416021 -0.651652 -0.269365 +v 1.434396 -0.651636 -0.307049 +v 1.434156 -0.606477 -0.303794 +v 1.371230 -0.766227 -0.197695 +v 1.368473 -0.807707 -0.202422 +v 1.376032 -0.709169 -0.193629 +v 1.410205 -0.585901 -0.204318 +v 1.401176 -0.587179 -0.204069 +v 1.394479 -0.584697 -0.198384 +v 1.410205 -0.585901 -0.204318 +v 1.412664 -0.599688 -0.210630 +v 1.405789 -0.605309 -0.209189 +v 1.401176 -0.587179 -0.204069 +v 1.408232 -0.710936 -0.217449 +v 1.403025 -0.769486 -0.221308 +v 1.398486 -0.768543 -0.220562 +v 1.403921 -0.710653 -0.216883 +v 1.397876 -0.816270 -0.223963 +v 1.391670 -0.810576 -0.222022 +v 1.411162 -0.650313 -0.213938 +v 1.406586 -0.650800 -0.213198 +v 1.379202 -0.650220 -0.190473 +v 1.382352 -0.605752 -0.189843 +v 1.390028 -0.829915 -0.213790 +v 1.386913 -0.827228 -0.208072 +v 1.371340 -0.825147 -0.207820 +v 1.377731 -0.828291 -0.213591 +v 1.386913 -0.827228 -0.208072 +v 1.371340 -0.825147 -0.207820 +v 1.406888 -0.715755 -0.910522 +v 1.401643 -0.772097 -0.909546 +v 1.393373 -0.771289 -0.911369 +v 1.398581 -0.715075 -0.912326 +v 1.388390 -0.812794 -0.909422 +v 1.410832 -0.598260 -0.903871 +v 1.411035 -0.600722 -0.907383 +v 1.402614 -0.600065 -0.908646 +v 1.402419 -0.597605 -0.904736 +v 1.411035 -0.600722 -0.907383 +v 1.410866 -0.617857 -0.909930 +v 1.402459 -0.617208 -0.911503 +v 1.402614 -0.600065 -0.908646 +v 1.395320 -0.818954 -0.894082 +v 1.399466 -0.772348 -0.893902 +v 1.392239 -0.771135 -0.895218 +v 1.387468 -0.813087 -0.895669 +v 1.404611 -0.715485 -0.894600 +v 1.397412 -0.714843 -0.895836 +v 1.393712 -0.831636 -0.897575 +v 1.385583 -0.829788 -0.898346 +v 1.385536 -0.832173 -0.902241 +v 1.393712 -0.831636 -0.897575 +v 1.385583 -0.829788 -0.898346 +v 1.409824 -0.659454 -0.910829 +v 1.401464 -0.658815 -0.912566 +v 1.407734 -0.658686 -0.895180 +v 1.400351 -0.658520 -0.896414 +v 1.410353 -0.612303 -0.896421 +v 1.401623 -0.616546 -0.897759 +v 1.403853 -0.829313 -0.842760 +v 1.407423 -0.831750 -0.842110 +v 1.403138 -0.812246 -0.843380 +v 1.403853 -0.829313 -0.842760 +v 1.431007 -0.658985 -0.841960 +v 1.430954 -0.617660 -0.842234 +v 1.428207 -0.714906 -0.841717 +v 1.406922 -0.770806 -0.843930 +v 1.412025 -0.714775 -0.844339 +v 1.428448 -0.600610 -0.842725 +v 1.424622 -0.598122 -0.843358 +v 1.430954 -0.617660 -0.842234 +v 1.415164 -0.658803 -0.844528 +v 1.417470 -0.617474 -0.844420 +v 1.422766 -0.770875 -0.841362 +v 1.416622 -0.812269 -0.841195 +v 1.386083 -0.829824 -0.906201 +v 1.386083 -0.829824 -0.906201 +v 1.360327 -0.826185 -0.907899 +v 1.360327 -0.826185 -0.907899 +v 1.410576 -0.599693 -0.900214 +v 1.402136 -0.599889 -0.900791 +v 1.410576 -0.599693 -0.900214 +v 1.402136 -0.599889 -0.900791 +v 1.375354 -0.596187 -0.900947 +v 1.375354 -0.596187 -0.900947 +v 1.098050 -0.593760 -0.902328 +v 1.095172 -0.595706 -0.902102 +v 1.098050 -0.593760 -0.902328 +v 1.095172 -0.595706 -0.902102 +v 1.092903 -0.609603 -0.902182 +v 1.094970 -0.609688 -0.899721 +v 1.093183 -0.616509 -0.900274 +v 1.085375 -0.737930 -0.900403 +v 1.084465 -0.738670 -0.902792 +v 1.089626 -0.691198 -0.900414 +v 1.088784 -0.691134 -0.902887 +v 1.092083 -0.644541 -0.900156 +v 1.091286 -0.643681 -0.902540 +v 1.235313 -0.808845 -0.910625 +v 1.165312 -0.799776 -0.911532 +v 1.235313 -0.808845 -0.910625 +v 1.165312 -0.799776 -0.911532 +v 1.113118 -0.793254 -0.911880 +v 1.113118 -0.793254 -0.911880 +v 1.084059 -0.789645 -0.910688 +v 1.081490 -0.787285 -0.909855 +v 1.084059 -0.789645 -0.910688 +v 1.081490 -0.787285 -0.909855 +v 1.081490 -0.787285 -0.909855 +v 1.083346 -0.773293 -0.912637 +v 1.318975 -0.587977 -0.900501 +v 1.318975 -0.587977 -0.900501 +v 1.246582 -0.582196 -0.900334 +v 1.246582 -0.582196 -0.900334 +v 1.306125 -0.818529 -0.909402 +v 1.306125 -0.818529 -0.909402 +v 1.177149 -0.584827 -0.901184 +v 1.177149 -0.584827 -0.901184 +v 1.126367 -0.590657 -0.902226 +v 1.126367 -0.590657 -0.902226 +v 1.398181 -0.833066 -0.897077 +v 1.402319 -0.833361 -0.896735 +v 1.398315 -0.831781 -0.893476 +v 1.398181 -0.833066 -0.897077 +v 1.425911 -0.659590 -0.898576 +v 1.425837 -0.618037 -0.898848 +v 1.423131 -0.715827 -0.898094 +v 1.423291 -0.600894 -0.899130 +v 1.419415 -0.598392 -0.899442 +v 1.425837 -0.618037 -0.898848 +v 1.417720 -0.772124 -0.897279 +v 1.411591 -0.813763 -0.896592 +v 1.415199 -0.599761 -0.896114 +v 1.415236 -0.598588 -0.899774 +v 1.415199 -0.599761 -0.896114 +v 1.415236 -0.598588 -0.899774 +v 1.415476 -0.598345 -0.903289 +v 1.406486 -0.830806 -0.892855 +v 1.406552 -0.830911 -0.896480 +v 1.402255 -0.833255 -0.893119 +v 1.402319 -0.833361 -0.896735 +v 1.402558 -0.833463 -0.900223 +v 1.406790 -0.831012 -0.899968 +v 1.423658 -0.600340 -0.813457 +v 1.420694 -0.600495 -0.843982 +v 1.427557 -0.597974 -0.812645 +v 1.424622 -0.598122 -0.843358 +v 1.421401 -0.598271 -0.874340 +v 1.417443 -0.600652 -0.874771 +v 1.414455 -0.828442 -0.811423 +v 1.411606 -0.829315 -0.841504 +v 1.410299 -0.830869 -0.812228 +v 1.407423 -0.831750 -0.842110 +v 1.404263 -0.832639 -0.872233 +v 1.408475 -0.830196 -0.871834 +v 1.407295 -0.828011 -0.310174 +v 1.405445 -0.828042 -0.283641 +v 1.407295 -0.828011 -0.310174 +v 1.411038 -0.830448 -0.313683 +v 1.409601 -0.830483 -0.292018 +v 1.405445 -0.828042 -0.283641 +v 1.407640 -0.830498 -0.266450 +v 1.403221 -0.828053 -0.255244 +v 1.403221 -0.828053 -0.255244 +v 1.434941 -0.606689 -0.318918 +v 1.432297 -0.588109 -0.315992 +v 1.431190 -0.587810 -0.296628 +v 1.434156 -0.606477 -0.303794 +v 1.428282 -0.585572 -0.312086 +v 1.426741 -0.585174 -0.287112 +v 1.424655 -0.584686 -0.257512 +v 1.429379 -0.587383 -0.270295 +v 1.432550 -0.606121 -0.280044 +v 1.407316 -0.828746 -0.903318 +v 1.403119 -0.831107 -0.903592 +v 1.407316 -0.828746 -0.903318 +v 1.412171 -0.812265 -0.903370 +v 1.427477 -0.605448 -0.199661 +v 1.424218 -0.586743 -0.198707 +v 1.423638 -0.589486 -0.193359 +v 1.427106 -0.607458 -0.194366 +v 1.423638 -0.589486 -0.193359 +v 1.422837 -0.607650 -0.190330 +v 1.427106 -0.607458 -0.194366 +v 1.426004 -0.616480 -0.191574 +v 1.415681 -0.600809 -0.906628 +v 1.415681 -0.600809 -0.906628 +v 1.415513 -0.617956 -0.909045 +v 1.406280 -0.772299 -0.908584 +v 1.411530 -0.715916 -0.909560 +v 1.414471 -0.659578 -0.909883 +v 1.423129 -0.711450 -0.195890 +v 1.425846 -0.652602 -0.192661 +v 1.421710 -0.651622 -0.190995 +v 1.418827 -0.711449 -0.194205 +v 1.417972 -0.768347 -0.199866 +v 1.413705 -0.769245 -0.198316 +v 1.406878 -0.830646 -0.887355 +v 1.402650 -0.833094 -0.887650 +v 1.427418 -0.586936 -0.241935 +v 1.430442 -0.605671 -0.249241 +v 1.422897 -0.584289 -0.232778 +v 1.421525 -0.584076 -0.215306 +v 1.425787 -0.586635 -0.218587 +v 1.428623 -0.605338 -0.221757 +v 1.415748 -0.600585 -0.890530 +v 1.419757 -0.598347 -0.890194 +v 1.415748 -0.600585 -0.890530 +v 1.415199 -0.599761 -0.896114 +v 1.397201 -0.830539 -0.213872 +v 1.395900 -0.828106 -0.208179 +v 1.402586 -0.830751 -0.213907 +v 1.401944 -0.828409 -0.208217 +v 1.395900 -0.828106 -0.208179 +v 1.407070 -0.830323 -0.323235 +v 1.406510 -0.812878 -0.322428 +v 1.407070 -0.830323 -0.323235 +v 1.410609 -0.832788 -0.324436 +v 1.407070 -0.830323 -0.323235 +v 1.431983 -0.570921 -0.328577 +v 1.432406 -0.586098 -0.325533 +v 1.432406 -0.586098 -0.325533 +v 1.428452 -0.583606 -0.324222 +v 1.435529 -0.604938 -0.326603 +v 1.401717 -0.828205 -0.237008 +v 1.405986 -0.830512 -0.245037 +v 1.401717 -0.828205 -0.237008 +v 1.404682 -0.830553 -0.229691 +v 1.400437 -0.829061 -0.226854 +v 1.400437 -0.829061 -0.226854 +v 1.383796 -0.948823 -0.329616 +v 1.382461 -0.953803 -0.331191 +v 1.389065 -0.929198 -0.329407 +v 1.372319 -0.948588 -0.791889 +v 1.372962 -0.944088 -0.792820 +v 1.375525 -0.945348 -0.793693 +v 1.374296 -0.950120 -0.792091 +v 1.377989 -0.925274 -0.792982 +v 1.380682 -0.926312 -0.793900 +v 1.371527 -0.948886 -0.386955 +v 1.373893 -0.951237 -0.387505 +v 1.373893 -0.951257 -0.362854 +v 1.371527 -0.948893 -0.362236 +v 1.373893 -0.951261 -0.344188 +v 1.371527 -0.948894 -0.343522 +v 1.372319 -0.948588 -0.791889 +v 1.374296 -0.950120 -0.792091 +v 1.373954 -0.951123 -0.787567 +v 1.371663 -0.948842 -0.788152 +v 1.373893 -0.951261 -0.777043 +v 1.371527 -0.948894 -0.777709 +v 1.419772 -0.599470 -0.794003 +v 1.416938 -0.546456 -0.793313 +v 1.419524 -0.544777 -0.794232 +v 1.422830 -0.582679 -0.794738 +v 1.412977 -0.495422 -0.793782 +v 1.415270 -0.495227 -0.794686 +v 1.373954 -0.951123 -0.333738 +v 1.371663 -0.948842 -0.333150 +v 1.374296 -0.950120 -0.329334 +v 1.372319 -0.948588 -0.329509 +v 1.388857 -0.884706 -0.792951 +v 1.391382 -0.886925 -0.793873 +v 1.422830 -0.582679 -0.794738 +v 1.424381 -0.598110 -0.798544 +v 1.424381 -0.598110 -0.798544 +v 1.428267 -0.595786 -0.797681 +v 1.373893 -0.951257 -0.758452 +v 1.371527 -0.948893 -0.759071 +v 1.373893 -0.951237 -0.733927 +v 1.371527 -0.948886 -0.734477 +v 1.373893 -0.951197 -0.706328 +v 1.371527 -0.948873 -0.706793 +v 1.373893 -0.951173 -0.677366 +v 1.371527 -0.948865 -0.677736 +v 1.373893 -0.951197 -0.648214 +v 1.371527 -0.948873 -0.648492 +v 1.373893 -0.951237 -0.619075 +v 1.371527 -0.948886 -0.619262 +v 1.373893 -0.951257 -0.589919 +v 1.371527 -0.948893 -0.590013 +v 1.373893 -0.951260 -0.560749 +v 1.371527 -0.948894 -0.560749 +v 1.373893 -0.951257 -0.531579 +v 1.371527 -0.948893 -0.531486 +v 1.373893 -0.951237 -0.502423 +v 1.371527 -0.948886 -0.502236 +v 1.373893 -0.951197 -0.473284 +v 1.371527 -0.948873 -0.473006 +v 1.373893 -0.951173 -0.444132 +v 1.371527 -0.948865 -0.443762 +v 1.373893 -0.951197 -0.415161 +v 1.371527 -0.948873 -0.414697 +v 1.414807 -0.830451 -0.796692 +v 1.414807 -0.830451 -0.796692 +v 1.410516 -0.832841 -0.797613 +v 1.399895 -0.888628 -0.329418 +v 1.430585 -0.533665 -0.329104 +v 1.428485 -0.485067 -0.328719 +v 1.089913 -0.790376 -0.911497 +v 1.091804 -0.775732 -0.914767 +v 1.089612 -0.792433 -0.907267 +v 1.089913 -0.790376 -0.911497 +v 1.103829 -0.593412 -0.902533 +v 1.103584 -0.608107 -0.899666 +v 1.103896 -0.591275 -0.906705 +v 1.103829 -0.593412 -0.902533 +v 1.098119 -0.591640 -0.906217 +v 1.098050 -0.593760 -0.902328 +v 1.096106 -0.740108 -0.916381 +v 1.100587 -0.691885 -0.916689 +v 1.103900 -0.593332 -0.910946 +v 1.103708 -0.607988 -0.914299 +v 1.103900 -0.593332 -0.910946 +v 1.098121 -0.593680 -0.910175 +v 1.102951 -0.643643 -0.916111 +v 1.095961 -0.740041 -0.899188 +v 1.091681 -0.775626 -0.900135 +v 1.100439 -0.691896 -0.899129 +v 1.102805 -0.643730 -0.898918 +v 1.089843 -0.790301 -0.903083 +v 1.089843 -0.790301 -0.903083 +v 1.398867 -0.830263 -0.219803 +v 1.393637 -0.828714 -0.219410 +v 1.403584 -0.830638 -0.220188 +v 1.398867 -0.830263 -0.219803 +v 1.393637 -0.828714 -0.219410 +v 1.424805 -0.586607 -0.205503 +v 1.427750 -0.605301 -0.206738 +v 1.420394 -0.584083 -0.204962 +v 1.393637 -0.828714 -0.219410 +v 1.384703 -0.826721 -0.219040 +v 1.384703 -0.826721 -0.219040 +v 1.359417 -0.822929 -0.218555 +v 1.359417 -0.822929 -0.218555 +v 1.387686 -0.587343 -0.192994 +v 1.387686 -0.587343 -0.192994 +v 1.359516 -0.590021 -0.192398 +v 1.359516 -0.590021 -0.192398 +v 1.106160 -0.785955 -0.222909 +v 1.103264 -0.783633 -0.223044 +v 1.106160 -0.785955 -0.222909 +v 1.103264 -0.783633 -0.223044 +v 1.103264 -0.783633 -0.223044 +v 1.100730 -0.769614 -0.221021 +v 1.102770 -0.769672 -0.223504 +v 1.100860 -0.762724 -0.221941 +v 1.104369 -0.581258 -0.192751 +v 1.101490 -0.583431 -0.194401 +v 1.104369 -0.581258 -0.192751 +v 1.101490 -0.583431 -0.194401 +v 1.098530 -0.686841 -0.212048 +v 1.099540 -0.734686 -0.218047 +v 1.098777 -0.735565 -0.215775 +v 1.097703 -0.686934 -0.209571 +v 1.098612 -0.636886 -0.207851 +v 1.097830 -0.636089 -0.205405 +v 1.254170 -0.599133 -0.190025 +v 1.187670 -0.593618 -0.189618 +v 1.254170 -0.599133 -0.190025 +v 1.187670 -0.593618 -0.189618 +v 1.134388 -0.585564 -0.190054 +v 1.134388 -0.585564 -0.190054 +v 1.314051 -0.596112 -0.191189 +v 1.314051 -0.596112 -0.191189 +v 1.242609 -0.805943 -0.217783 +v 1.179237 -0.796628 -0.219254 +v 1.242609 -0.805943 -0.217783 +v 1.179237 -0.796628 -0.219254 +v 1.132555 -0.789746 -0.221159 +v 1.132555 -0.789746 -0.221159 +v 1.419941 -0.769082 -0.216432 +v 1.413730 -0.811091 -0.219367 +v 1.425292 -0.710927 -0.212602 +v 1.417055 -0.585788 -0.212238 +v 1.415629 -0.584525 -0.204571 +v 1.410205 -0.585901 -0.204318 +v 1.415629 -0.584525 -0.204571 +v 1.308165 -0.815496 -0.217814 +v 1.308165 -0.815496 -0.217814 +v 1.408337 -0.828251 -0.220371 +v 1.403584 -0.830638 -0.220188 +v 1.428004 -0.650716 -0.209177 +v 1.427750 -0.605301 -0.206738 +v 1.110361 -0.581830 -0.191210 +v 1.110150 -0.598096 -0.188342 +v 1.110341 -0.579356 -0.196017 +v 1.110361 -0.581830 -0.191210 +v 1.104346 -0.578780 -0.197045 +v 1.104369 -0.581258 -0.192751 +v 1.111681 -0.786705 -0.222309 +v 1.111174 -0.772089 -0.223539 +v 1.111804 -0.789016 -0.217740 +v 1.111681 -0.786705 -0.222309 +v 1.109429 -0.636340 -0.209033 +v 1.109955 -0.597486 -0.205444 +v 1.109315 -0.687608 -0.213397 +v 1.111794 -0.787200 -0.212485 +v 1.111371 -0.772927 -0.206452 +v 1.111794 -0.787200 -0.212485 +v 1.110129 -0.736724 -0.219437 +v 1.110249 -0.581491 -0.201044 +v 1.110249 -0.581491 -0.201044 +v 1.104257 -0.580919 -0.201555 +v 1.110360 -0.737650 -0.199356 +v 1.109551 -0.688473 -0.192883 +v 1.109658 -0.637110 -0.188941 +vt 0.199921 0.099454 +vt 0.196845 0.100785 +vt 0.199921 0.100823 +vt 0.196844 0.102562 +vt 0.199921 0.102635 +vt 0.196844 0.104583 +vt 0.199921 0.104679 +vt 0.196844 0.106731 +vt 0.199921 0.106832 +vt 0.196844 0.108921 +vt 0.199921 0.109007 +vt 0.196845 0.111127 +vt 0.199921 0.111186 +vt 0.196846 0.113336 +vt 0.199921 0.113367 +vt 0.196846 0.115546 +vt 0.199921 0.115550 +vt 0.196846 0.117756 +vt 0.199921 0.117732 +vt 0.196846 0.119965 +vt 0.199921 0.119914 +vt 0.196846 0.122171 +vt 0.199921 0.122093 +vt 0.196846 0.124361 +vt 0.199921 0.124268 +vt 0.196846 0.126509 +vt 0.199921 0.126420 +vt 0.196846 0.128525 +vt 0.199921 0.128459 +vt 0.196846 0.130293 +vt 0.199921 0.130262 +vt 0.201339 0.128424 +vt 0.201339 0.124223 +vt 0.201339 0.126375 +vt 0.201339 0.119889 +vt 0.201339 0.122056 +vt 0.201339 0.115552 +vt 0.201339 0.117721 +vt 0.201339 0.111214 +vt 0.201339 0.113382 +vt 0.201339 0.106881 +vt 0.201339 0.109048 +vt 0.201339 0.102675 +vt 0.201339 0.104728 +vt 0.201339 0.099464 +vt 0.201339 0.100847 +vt 0.175833 0.131636 +vt 0.172053 0.131667 +vt 0.171915 0.132415 +vt 0.175764 0.132388 +vt 0.168440 0.131708 +vt 0.168214 0.132460 +vt 0.168049 0.132782 +vt 0.171785 0.132743 +vt 0.175674 0.132790 +vt 0.884253 0.015451 +vt 0.884751 0.012538 +vt 0.883833 0.012621 +vt 0.883344 0.015318 +vt 0.885321 0.010103 +vt 0.884399 0.010437 +vt 0.883826 0.011139 +vt 0.883302 0.012591 +vt 0.882898 0.014014 +vt 0.988709 0.070526 +vt 0.989089 0.073172 +vt 0.989381 0.073153 +vt 0.988983 0.070350 +vt 0.989586 0.076755 +vt 0.989891 0.076811 +vt 0.990164 0.076907 +vt 0.989615 0.073063 +vt 0.989110 0.069006 +vt 0.710746 0.007277 +vt 0.711769 0.007115 +vt 0.711790 0.006341 +vt 0.710767 0.006508 +vt 0.712169 0.007039 +vt 0.712179 0.006270 +vt 0.712109 0.006008 +vt 0.711769 0.006021 +vt 0.710754 0.006181 +vt 0.989423 0.043818 +vt 0.988905 0.046802 +vt 0.989183 0.046869 +vt 0.989701 0.043898 +vt 0.988385 0.049717 +vt 0.988659 0.049863 +vt 0.988803 0.051145 +vt 0.989384 0.047013 +vt 0.989906 0.043954 +vt 0.891441 0.015528 +vt 0.890855 0.019663 +vt 0.891405 0.019813 +vt 0.891723 0.016681 +vt 0.890661 0.023905 +vt 0.891237 0.023958 +vt 0.794660 0.014683 +vt 0.794634 0.011644 +vt 0.793508 0.011530 +vt 0.793530 0.014558 +vt 0.794660 0.016856 +vt 0.793532 0.016683 +vt 0.892359 0.034109 +vt 0.892633 0.033965 +vt 0.892391 0.032691 +vt 0.892116 0.032848 +vt 0.892772 0.032683 +vt 0.892546 0.031414 +vt 0.192772 0.133117 +vt 0.191494 0.133158 +vt 0.191381 0.134244 +vt 0.192630 0.134194 +vt 0.998319 0.450842 +vt 0.998350 0.450526 +vt 0.997342 0.450127 +vt 0.997307 0.450443 +vt 0.874236 0.879481 +vt 0.869931 0.879914 +vt 0.869973 0.880191 +vt 0.873901 0.880143 +vt 0.865223 0.879980 +vt 0.865299 0.880216 +vt 0.865399 0.880443 +vt 0.870047 0.880428 +vt 0.873924 0.880422 +vt 0.861205 0.879999 +vt 0.861283 0.880234 +vt 0.857784 0.880018 +vt 0.857863 0.880252 +vt 0.857972 0.880478 +vt 0.861390 0.880460 +vt 0.854624 0.879979 +vt 0.854670 0.880261 +vt 0.851545 0.879494 +vt 0.851531 0.880228 +vt 0.851212 0.880572 +vt 0.854760 0.880502 +vt 0.885356 0.042100 +vt 0.884760 0.037786 +vt 0.883859 0.038010 +vt 0.884455 0.042530 +vt 0.884137 0.032500 +vt 0.883236 0.032523 +vt 0.882845 0.032521 +vt 0.883470 0.038073 +vt 0.884068 0.042659 +vt 0.883788 0.027706 +vt 0.882887 0.027644 +vt 0.883726 0.023353 +vt 0.882825 0.023282 +vt 0.882432 0.023253 +vt 0.882495 0.027616 +vt 0.883896 0.019160 +vt 0.882994 0.019070 +vt 0.882595 0.018944 +vt 0.199921 0.131626 +vt 0.196846 0.131625 +vt 0.196848 0.132387 +vt 0.199924 0.132399 +vt 0.192755 0.131622 +vt 0.192756 0.132379 +vt 0.192765 0.132783 +vt 0.196890 0.132715 +vt 0.199949 0.132722 +vt 0.188456 0.131620 +vt 0.188454 0.132373 +vt 0.184149 0.131619 +vt 0.184140 0.132372 +vt 0.184136 0.132775 +vt 0.188425 0.132776 +vt 0.179897 0.131622 +vt 0.179871 0.132375 +vt 0.179880 0.132777 +vt 0.183963 0.099439 +vt 0.179394 0.099438 +vt 0.179393 0.100729 +vt 0.183956 0.100729 +vt 0.174922 0.099429 +vt 0.174946 0.100722 +vt 0.175023 0.102450 +vt 0.179418 0.102454 +vt 0.183956 0.102453 +vt 0.179483 0.104441 +vt 0.183971 0.104440 +vt 0.175158 0.104440 +vt 0.175336 0.106583 +vt 0.179582 0.106582 +vt 0.184004 0.106581 +vt 0.179702 0.108795 +vt 0.184052 0.108794 +vt 0.175537 0.108797 +vt 0.175746 0.111042 +vt 0.179830 0.111040 +vt 0.184109 0.111039 +vt 0.179952 0.113290 +vt 0.184164 0.113289 +vt 0.175943 0.113292 +vt 0.176102 0.115542 +vt 0.180051 0.115540 +vt 0.184207 0.115539 +vt 0.180116 0.117790 +vt 0.184230 0.117789 +vt 0.176198 0.117792 +vt 0.176234 0.120042 +vt 0.180143 0.120040 +vt 0.184235 0.120039 +vt 0.180134 0.122285 +vt 0.184229 0.122284 +vt 0.176219 0.122287 +vt 0.176167 0.124502 +vt 0.180098 0.124498 +vt 0.184216 0.124497 +vt 0.180045 0.126639 +vt 0.184199 0.126637 +vt 0.176089 0.126644 +vt 0.176001 0.128629 +vt 0.179988 0.128621 +vt 0.184181 0.128619 +vt 0.192748 0.099442 +vt 0.188415 0.099439 +vt 0.188410 0.100732 +vt 0.192746 0.100748 +vt 0.188404 0.102458 +vt 0.192743 0.102490 +vt 0.188402 0.104446 +vt 0.192742 0.104488 +vt 0.188406 0.106587 +vt 0.192742 0.106631 +vt 0.188419 0.108800 +vt 0.192745 0.108837 +vt 0.188438 0.111043 +vt 0.192750 0.111069 +vt 0.188457 0.113291 +vt 0.192755 0.113305 +vt 0.188470 0.115539 +vt 0.192758 0.115542 +vt 0.188473 0.117788 +vt 0.192758 0.117778 +vt 0.188471 0.120036 +vt 0.192757 0.120015 +vt 0.188467 0.122279 +vt 0.192756 0.122247 +vt 0.188465 0.124492 +vt 0.192755 0.124453 +vt 0.188464 0.126632 +vt 0.192756 0.126595 +vt 0.188463 0.128616 +vt 0.192756 0.128589 +vt 0.196845 0.099447 +vt 0.858005 0.850876 +vt 0.861307 0.850864 +vt 0.861164 0.850154 +vt 0.857854 0.850166 +vt 0.865207 0.850888 +vt 0.865073 0.850173 +vt 0.864939 0.849572 +vt 0.861023 0.849560 +vt 0.857705 0.849574 +vt 0.854982 0.850839 +vt 0.855074 0.852395 +vt 0.858090 0.852388 +vt 0.852056 0.850391 +vt 0.852174 0.852359 +vt 0.852275 0.854489 +vt 0.855143 0.854470 +vt 0.858130 0.854452 +vt 0.855177 0.856601 +vt 0.858147 0.856568 +vt 0.852332 0.856698 +vt 0.852331 0.858942 +vt 0.855160 0.858251 +vt 0.858103 0.858155 +vt 0.215342 0.073506 +vt 0.215364 0.071246 +vt 0.214912 0.071363 +vt 0.214962 0.073523 +vt 0.215364 0.071246 +vt 0.215406 0.068983 +vt 0.214388 0.069816 +vt 0.214912 0.071363 +vt 0.214912 0.071363 +vt 0.214388 0.069816 +vt 0.213862 0.070253 +vt 0.214103 0.071492 +vt 0.214962 0.073523 +vt 0.214912 0.071363 +vt 0.214103 0.071492 +vt 0.214149 0.073600 +vt 0.865191 0.868583 +vt 0.869791 0.868415 +vt 0.869596 0.867676 +vt 0.865062 0.867839 +vt 0.874052 0.867671 +vt 0.873260 0.866982 +vt 0.872364 0.866622 +vt 0.869381 0.866970 +vt 0.864933 0.867095 +vt 0.857880 0.868657 +vt 0.854757 0.868598 +vt 0.854693 0.870250 +vt 0.857884 0.870246 +vt 0.851785 0.867946 +vt 0.851592 0.870192 +vt 0.851449 0.872402 +vt 0.854602 0.872381 +vt 0.857832 0.872362 +vt 0.854548 0.874457 +vt 0.857789 0.874426 +vt 0.851394 0.874532 +vt 0.851414 0.876504 +vt 0.854504 0.876012 +vt 0.857715 0.875937 +vt 0.875523 0.863323 +vt 0.875333 0.861178 +vt 0.874802 0.861242 +vt 0.875054 0.863324 +vt 0.874052 0.858989 +vt 0.873261 0.859681 +vt 0.872364 0.860047 +vt 0.873128 0.861282 +vt 0.873316 0.863329 +vt 0.861376 0.852377 +vt 0.865259 0.852406 +vt 0.861396 0.854442 +vt 0.865264 0.854471 +vt 0.861400 0.856556 +vt 0.865266 0.856578 +vt 0.861350 0.858142 +vt 0.865220 0.858154 +vt 0.592145 0.380726 +vt 0.591667 0.375641 +vt 0.591433 0.375537 +vt 0.591828 0.379886 +vt 0.591270 0.370003 +vt 0.591045 0.369998 +vt 0.869710 0.846966 +vt 0.865111 0.846918 +vt 0.864965 0.847369 +vt 0.869454 0.847413 +vt 0.873381 0.847436 +vt 0.872442 0.847663 +vt 0.854465 0.876730 +vt 0.857572 0.876646 +vt 0.852268 0.877215 +vt 0.852680 0.877536 +vt 0.854418 0.877304 +vt 0.857442 0.877240 +vt 0.861253 0.868634 +vt 0.861286 0.870221 +vt 0.865232 0.870160 +vt 0.861263 0.872336 +vt 0.865224 0.872267 +vt 0.861237 0.874400 +vt 0.865216 0.874333 +vt 0.861169 0.875912 +vt 0.865164 0.875849 +vt 0.215406 0.078013 +vt 0.215353 0.075762 +vt 0.214906 0.075697 +vt 0.214417 0.077366 +vt 0.215353 0.075762 +vt 0.215342 0.073506 +vt 0.214962 0.073523 +vt 0.214906 0.075697 +vt 0.214906 0.075697 +vt 0.214962 0.073523 +vt 0.214149 0.073600 +vt 0.214118 0.075719 +vt 0.214417 0.077366 +vt 0.214906 0.075697 +vt 0.214118 0.075719 +vt 0.213906 0.077020 +vt 0.874048 0.850442 +vt 0.869793 0.850903 +vt 0.869779 0.852483 +vt 0.873585 0.852525 +vt 0.869754 0.854563 +vt 0.873501 0.854656 +vt 0.869780 0.856668 +vt 0.873585 0.856805 +vt 0.869795 0.858281 +vt 0.861027 0.876621 +vt 0.865030 0.876563 +vt 0.860893 0.877216 +vt 0.864898 0.877166 +vt 0.875333 0.865471 +vt 0.874802 0.865408 +vt 0.873128 0.865378 +vt 0.869776 0.870031 +vt 0.873585 0.869861 +vt 0.869748 0.872136 +vt 0.873500 0.872011 +vt 0.869774 0.874216 +vt 0.873584 0.874142 +vt 0.869787 0.875794 +vt 0.874048 0.876222 +vt 0.710746 0.038756 +vt 0.711769 0.038902 +vt 0.711716 0.037538 +vt 0.710697 0.037405 +vt 0.712168 0.038983 +vt 0.712115 0.037612 +vt 0.712048 0.035807 +vt 0.711650 0.035741 +vt 0.710635 0.035627 +vt 0.711589 0.033720 +vt 0.710579 0.033626 +vt 0.711987 0.033777 +vt 0.711960 0.031643 +vt 0.711562 0.031597 +vt 0.710554 0.031523 +vt 0.711590 0.029455 +vt 0.710579 0.029401 +vt 0.711987 0.029490 +vt 0.712051 0.027334 +vt 0.711653 0.027310 +vt 0.710638 0.027277 +vt 0.711721 0.025164 +vt 0.710701 0.025151 +vt 0.712120 0.025177 +vt 0.712153 0.023023 +vt 0.711754 0.023020 +vt 0.710732 0.023028 +vt 0.711721 0.020882 +vt 0.710701 0.020910 +vt 0.712120 0.020874 +vt 0.712051 0.018729 +vt 0.711653 0.018747 +vt 0.710638 0.018795 +vt 0.711589 0.016613 +vt 0.710579 0.016681 +vt 0.711987 0.016584 +vt 0.711960 0.014436 +vt 0.711562 0.014476 +vt 0.710553 0.014564 +vt 0.711589 0.012347 +vt 0.710579 0.012456 +vt 0.711987 0.012297 +vt 0.712048 0.010251 +vt 0.711650 0.010311 +vt 0.710635 0.010441 +vt 0.170742 0.099403 +vt 0.170813 0.100703 +vt 0.166745 0.099367 +vt 0.166877 0.100675 +vt 0.167136 0.102420 +vt 0.170972 0.102438 +vt 0.171182 0.104435 +vt 0.167421 0.104427 +vt 0.167718 0.106584 +vt 0.171425 0.106584 +vt 0.171690 0.108800 +vt 0.168033 0.108803 +vt 0.168359 0.111049 +vt 0.171963 0.111045 +vt 0.172223 0.113295 +vt 0.168674 0.113299 +vt 0.168891 0.115549 +vt 0.172419 0.115545 +vt 0.172508 0.117796 +vt 0.168947 0.117800 +vt 0.168908 0.120051 +vt 0.172518 0.120046 +vt 0.172489 0.122292 +vt 0.168861 0.122296 +vt 0.168830 0.124515 +vt 0.172440 0.124507 +vt 0.172380 0.126654 +vt 0.168814 0.126666 +vt 0.168765 0.128666 +vt 0.172299 0.128645 +vt 0.702269 0.014449 +vt 0.702637 0.014490 +vt 0.702639 0.012369 +vt 0.702270 0.012317 +vt 0.703374 0.014567 +vt 0.703378 0.012462 +vt 0.703387 0.010453 +vt 0.702643 0.010342 +vt 0.702272 0.010281 +vt 0.702272 0.018739 +vt 0.702643 0.018760 +vt 0.702639 0.016625 +vt 0.702270 0.016594 +vt 0.703387 0.018801 +vt 0.703378 0.016685 +vt 0.702274 0.023031 +vt 0.702646 0.023031 +vt 0.702645 0.020895 +vt 0.702273 0.020884 +vt 0.703398 0.023037 +vt 0.703395 0.020919 +vt 0.702272 0.027324 +vt 0.702643 0.027304 +vt 0.702645 0.025168 +vt 0.702273 0.025178 +vt 0.703388 0.027276 +vt 0.703395 0.025157 +vt 0.702269 0.031614 +vt 0.702637 0.031574 +vt 0.702639 0.029438 +vt 0.702270 0.029468 +vt 0.703374 0.031512 +vt 0.703379 0.029394 +vt 0.702272 0.035776 +vt 0.702643 0.035716 +vt 0.702639 0.033695 +vt 0.702270 0.033745 +vt 0.703387 0.035619 +vt 0.703379 0.033615 +vt 0.702274 0.038950 +vt 0.702646 0.038875 +vt 0.702645 0.037513 +vt 0.702274 0.037582 +vt 0.703400 0.038750 +vt 0.703395 0.037400 +vt 0.986739 0.060099 +vt 0.986969 0.064627 +vt 0.987511 0.064499 +vt 0.987303 0.060060 +vt 0.987569 0.069085 +vt 0.987864 0.067921 +vt 0.847913 0.405159 +vt 0.847869 0.407539 +vt 0.848441 0.407439 +vt 0.848420 0.405114 +vt 0.848014 0.401912 +vt 0.848502 0.401879 +vt 0.892586 0.014188 +vt 0.892233 0.014322 +vt 0.892068 0.015428 +vt 0.892375 0.015272 +vt 0.998739 0.452141 +vt 0.998435 0.451330 +vt 0.997388 0.451768 +vt 0.997685 0.452525 +vt 0.998802 0.452486 +vt 0.997753 0.452859 +vt 0.893416 0.040007 +vt 0.892888 0.037022 +vt 0.892527 0.037024 +vt 0.893057 0.040084 +vt 0.892013 0.033949 +vt 0.891250 0.032605 +vt 0.891745 0.036901 +vt 0.892282 0.040130 +vt 0.983354 0.060369 +vt 0.983547 0.064788 +vt 0.985516 0.064707 +vt 0.985308 0.060211 +vt 0.983911 0.068878 +vt 0.985904 0.068961 +vt 0.983720 0.051406 +vt 0.983392 0.055932 +vt 0.985346 0.055764 +vt 0.985682 0.051323 +vt 0.986784 0.055670 +vt 0.987283 0.051222 +vt 0.984906 0.043319 +vt 0.984325 0.046860 +vt 0.986261 0.046975 +vt 0.986819 0.043638 +vt 0.987763 0.046918 +vt 0.988289 0.043688 +vt 0.702273 0.007092 +vt 0.702646 0.007168 +vt 0.702644 0.006401 +vt 0.702272 0.006321 +vt 0.703399 0.007305 +vt 0.703400 0.006543 +vt 0.703387 0.006216 +vt 0.702632 0.006072 +vt 0.702260 0.005990 +vt 0.984385 0.072360 +vt 0.986360 0.072690 +vt 0.984914 0.075473 +vt 0.986869 0.076114 +vt 0.988393 0.076505 +vt 0.987909 0.072923 +vt 0.893069 0.011560 +vt 0.892691 0.011618 +vt 0.893704 0.008003 +vt 0.893314 0.008086 +vt 0.892464 0.008269 +vt 0.891865 0.011798 +vt 0.978963 0.070044 +vt 0.979346 0.071341 +vt 0.979881 0.071337 +vt 0.979412 0.068740 +vt 0.979853 0.072683 +vt 0.980424 0.073380 +vt 0.981367 0.073863 +vt 0.980815 0.071523 +vt 0.980330 0.068663 +vt 0.980066 0.041195 +vt 0.979484 0.045784 +vt 0.979873 0.045846 +vt 0.980454 0.041324 +vt 0.978880 0.051366 +vt 0.979271 0.051362 +vt 0.980172 0.051373 +vt 0.980775 0.046061 +vt 0.981357 0.041744 +vt 0.978552 0.056345 +vt 0.978944 0.056312 +vt 0.978506 0.060788 +vt 0.978898 0.060752 +vt 0.979800 0.060670 +vt 0.979844 0.056233 +vt 0.978672 0.065141 +vt 0.979070 0.065009 +vt 0.979977 0.064933 +vt 0.706643 0.014755 +vt 0.708761 0.014689 +vt 0.708781 0.012609 +vt 0.706658 0.012691 +vt 0.708828 0.010623 +vt 0.706691 0.010721 +vt 0.706692 0.018906 +vt 0.708830 0.018867 +vt 0.708782 0.016779 +vt 0.706658 0.016832 +vt 0.706744 0.023058 +vt 0.708906 0.023046 +vt 0.708882 0.020955 +vt 0.706728 0.020981 +vt 0.706692 0.027218 +vt 0.708830 0.027238 +vt 0.708882 0.025141 +vt 0.706728 0.025137 +vt 0.706643 0.031378 +vt 0.708761 0.031428 +vt 0.708782 0.029334 +vt 0.706658 0.029299 +vt 0.706691 0.035399 +vt 0.708828 0.035477 +vt 0.708782 0.033503 +vt 0.706658 0.033439 +vt 0.706752 0.038463 +vt 0.708918 0.038563 +vt 0.708878 0.037232 +vt 0.706725 0.037141 +vt 0.887277 0.023633 +vt 0.887447 0.019404 +vt 0.885474 0.019268 +vt 0.885304 0.023477 +vt 0.887797 0.015506 +vt 0.885826 0.015473 +vt 0.887684 0.032429 +vt 0.887337 0.027954 +vt 0.885365 0.027813 +vt 0.885715 0.032446 +vt 0.888899 0.040496 +vt 0.888305 0.036958 +vt 0.886341 0.037351 +vt 0.886940 0.041277 +vt 0.706752 0.007632 +vt 0.708918 0.007506 +vt 0.708935 0.006749 +vt 0.706763 0.006881 +vt 0.708922 0.006425 +vt 0.706750 0.006559 +vt 0.888278 0.012146 +vt 0.886311 0.012358 +vt 0.888826 0.009109 +vt 0.886865 0.009651 +vt 0.706751 0.039556 +vt 0.708922 0.039665 +vt 0.708935 0.039325 +vt 0.706763 0.039218 +vt 0.710754 0.039872 +vt 0.710767 0.039528 +vt 0.702260 0.040074 +vt 0.702632 0.039993 +vt 0.702645 0.039649 +vt 0.702272 0.039728 +vt 0.703387 0.039860 +vt 0.703400 0.039518 +vt 0.711769 0.040014 +vt 0.711790 0.039679 +vt 0.712110 0.040027 +vt 0.712179 0.039754 +vt 0.873924 0.846247 +vt 0.870051 0.846274 +vt 0.869976 0.846520 +vt 0.873901 0.846535 +vt 0.865426 0.846302 +vt 0.865327 0.846537 +vt 0.865252 0.846781 +vt 0.869934 0.846806 +vt 0.874236 0.847200 +vt 0.861471 0.846324 +vt 0.861368 0.846558 +vt 0.858116 0.846343 +vt 0.858015 0.846577 +vt 0.857944 0.846820 +vt 0.861294 0.846801 +vt 0.854947 0.846358 +vt 0.854874 0.846607 +vt 0.851398 0.846333 +vt 0.851778 0.846679 +vt 0.851873 0.847418 +vt 0.854847 0.846897 +vt 0.179937 0.130337 +vt 0.184163 0.130334 +vt 0.175913 0.130347 +vt 0.188460 0.130333 +vt 0.192756 0.130321 +vt 0.172187 0.130371 +vt 0.168636 0.130403 +vt 0.708878 0.008851 +vt 0.706725 0.008964 +vt 0.710697 0.008642 +vt 0.702645 0.008536 +vt 0.702273 0.008466 +vt 0.703395 0.008662 +vt 0.174880 0.098291 +vt 0.170813 0.098343 +vt 0.170777 0.098662 +vt 0.174929 0.098683 +vt 0.166964 0.098312 +vt 0.166814 0.098624 +vt 0.199949 0.098372 +vt 0.196890 0.098370 +vt 0.196847 0.098691 +vt 0.199924 0.098686 +vt 0.192761 0.098295 +vt 0.192750 0.098690 +vt 0.188392 0.098297 +vt 0.188419 0.098692 +vt 0.183971 0.098298 +vt 0.183969 0.098692 +vt 0.179424 0.098298 +vt 0.179398 0.098691 +vt 0.869599 0.859019 +vt 0.865088 0.858896 +vt 0.864955 0.859638 +vt 0.869384 0.859723 +vt 0.854762 0.867834 +vt 0.852667 0.867201 +vt 0.857768 0.867905 +vt 0.857653 0.867154 +vt 0.854737 0.867108 +vt 0.853079 0.866808 +vt 0.861128 0.867883 +vt 0.861000 0.867133 +vt 0.711716 0.008494 +vt 0.712115 0.008425 +vt 0.875935 0.876113 +vt 0.875512 0.876142 +vt 0.875713 0.877962 +vt 0.876054 0.877934 +vt 0.875189 0.878007 +vt 0.875721 0.879353 +vt 0.876147 0.879316 +vt 0.201703 0.098452 +vt 0.201367 0.098385 +vt 0.201342 0.098692 +vt 0.201726 0.098722 +vt 0.201730 0.099489 +vt 0.201730 0.128398 +vt 0.201339 0.130242 +vt 0.201730 0.130216 +vt 0.201339 0.131619 +vt 0.201730 0.131595 +vt 0.876176 0.846306 +vt 0.875745 0.846242 +vt 0.875700 0.846546 +vt 0.876189 0.846577 +vt 0.875721 0.847314 +vt 0.876147 0.847350 +vt 0.889254 0.042585 +vt 0.889184 0.042153 +vt 0.887228 0.043118 +vt 0.887300 0.043590 +vt 0.885644 0.044123 +vt 0.885716 0.044633 +vt 0.980485 0.038595 +vt 0.980359 0.039056 +vt 0.980736 0.039208 +vt 0.980814 0.038684 +vt 0.981638 0.039721 +vt 0.981709 0.039206 +vt 0.985255 0.041225 +vt 0.985186 0.041662 +vt 0.987089 0.042084 +vt 0.987156 0.041677 +vt 0.988548 0.042180 +vt 0.988613 0.041790 +vt 0.893737 0.041833 +vt 0.893673 0.041464 +vt 0.893315 0.041564 +vt 0.893380 0.041939 +vt 0.892546 0.041638 +vt 0.892612 0.042023 +vt 0.875780 0.871934 +vt 0.875277 0.871956 +vt 0.875335 0.874097 +vt 0.875827 0.874072 +vt 0.875940 0.867630 +vt 0.875517 0.867640 +vt 0.875336 0.869799 +vt 0.875828 0.869782 +vt 0.876120 0.863323 +vt 0.875828 0.863323 +vt 0.875746 0.865481 +vt 0.876062 0.865476 +vt 0.875941 0.859019 +vt 0.875517 0.859009 +vt 0.875746 0.861166 +vt 0.876062 0.861170 +vt 0.875780 0.854716 +vt 0.875277 0.854697 +vt 0.875336 0.856853 +vt 0.875828 0.856868 +vt 0.875936 0.850540 +vt 0.875512 0.850513 +vt 0.875336 0.852555 +vt 0.875828 0.852578 +vt 0.875713 0.848700 +vt 0.876054 0.848727 +vt 0.875189 0.848658 +vt 0.201728 0.124202 +vt 0.201729 0.126351 +vt 0.201730 0.119878 +vt 0.201729 0.122040 +vt 0.201730 0.115552 +vt 0.201730 0.117715 +vt 0.201730 0.111225 +vt 0.201730 0.113388 +vt 0.201728 0.106901 +vt 0.201729 0.109063 +vt 0.201730 0.102700 +vt 0.201729 0.104752 +vt 0.201730 0.100873 +vt 0.201342 0.132397 +vt 0.201726 0.132367 +vt 0.201367 0.132711 +vt 0.201703 0.132643 +vt 0.884745 0.044646 +vt 0.884824 0.045165 +vt 0.884368 0.044798 +vt 0.884495 0.045256 +vt 0.875700 0.880116 +vt 0.876189 0.880084 +vt 0.875744 0.880412 +vt 0.876176 0.880348 +vt 0.989738 0.041986 +vt 0.989675 0.042360 +vt 0.989950 0.042462 +vt 0.990008 0.042098 +vt 0.990147 0.042535 +vt 0.990164 0.042197 +vt 0.857674 0.847400 +vt 0.854760 0.847466 +vt 0.854710 0.848492 +vt 0.857637 0.848473 +vt 0.853090 0.847711 +vt 0.852775 0.848520 +vt 0.853160 0.849338 +vt 0.854825 0.849546 +vt 0.857821 0.859653 +vt 0.855032 0.859734 +vt 0.854886 0.861276 +vt 0.857739 0.861246 +vt 0.853430 0.860056 +vt 0.852959 0.861326 +vt 0.852767 0.863434 +vt 0.854787 0.863421 +vt 0.857690 0.863403 +vt 0.854711 0.865565 +vt 0.857642 0.865560 +vt 0.852724 0.865542 +vt 0.861017 0.847383 +vt 0.860967 0.848457 +vt 0.864900 0.848456 +vt 0.861073 0.859638 +vt 0.861006 0.861230 +vt 0.864907 0.861221 +vt 0.860982 0.863385 +vt 0.864902 0.863366 +vt 0.860964 0.865540 +vt 0.864894 0.865510 +vt 0.869424 0.848478 +vt 0.872968 0.848518 +vt 0.869379 0.849571 +vt 0.872357 0.849379 +vt 0.869452 0.861237 +vt 0.869498 0.863345 +vt 0.869451 0.865454 +vt 0.854371 0.878366 +vt 0.857414 0.878350 +vt 0.852353 0.878365 +vt 0.852754 0.879178 +vt 0.854493 0.879403 +vt 0.857490 0.879433 +vt 0.860853 0.878328 +vt 0.864863 0.878291 +vt 0.860918 0.879413 +vt 0.864933 0.879388 +vt 0.872357 0.877297 +vt 0.869374 0.877128 +vt 0.869420 0.878229 +vt 0.872968 0.878159 +vt 0.869450 0.879303 +vt 0.872442 0.879027 +vt 0.591129 0.365085 +vt 0.590904 0.365083 +vt 0.591254 0.360731 +vt 0.591028 0.360732 +vt 0.861155 0.846938 +vt 0.857807 0.846956 +vt 0.854911 0.850119 +vt 0.852800 0.849666 +vt 0.591597 0.356526 +vt 0.591349 0.356673 +vt 0.592145 0.352311 +vt 0.591669 0.353730 +vt 0.854811 0.847040 +vt 0.852696 0.847513 +vt 0.869591 0.876527 +vt 0.873255 0.876938 +vt 0.572571 0.773138 +vt 0.572567 0.774844 +vt 0.573087 0.774965 +vt 0.573577 0.773846 +vt 0.572567 0.774844 +vt 0.572577 0.776121 +vt 0.573583 0.776013 +vt 0.573087 0.774965 +vt 0.573087 0.774965 +vt 0.573583 0.776013 +vt 0.574109 0.775806 +vt 0.573903 0.775004 +vt 0.573577 0.773846 +vt 0.573087 0.774965 +vt 0.573903 0.775004 +vt 0.574109 0.774168 +vt 0.592140 0.410119 +vt 0.591593 0.405798 +vt 0.591349 0.405662 +vt 0.591673 0.408702 +vt 0.591256 0.401521 +vt 0.591032 0.401522 +vt 0.854577 0.879836 +vt 0.857641 0.879884 +vt 0.852370 0.879386 +vt 0.861215 0.858890 +vt 0.857968 0.858904 +vt 0.591262 0.392076 +vt 0.591658 0.386404 +vt 0.591425 0.386501 +vt 0.591037 0.392076 +vt 0.592140 0.381299 +vt 0.591823 0.382128 +vt 0.869706 0.879756 +vt 0.873381 0.879251 +vt 0.865081 0.879845 +vt 0.855117 0.859012 +vt 0.853085 0.859671 +vt 0.874587 0.848578 +vt 0.873256 0.849731 +vt 0.591128 0.397075 +vt 0.590904 0.397074 +vt 0.861064 0.879865 +vt 0.869597 0.850169 +vt 0.575670 0.776104 +vt 0.575670 0.774834 +vt 0.575149 0.774933 +vt 0.574663 0.776002 +vt 0.575670 0.774834 +vt 0.575669 0.773138 +vt 0.574684 0.773854 +vt 0.575149 0.774933 +vt 0.575149 0.774933 +vt 0.574684 0.773854 +vt 0.574163 0.774176 +vt 0.574349 0.774985 +vt 0.574663 0.776002 +vt 0.575149 0.774933 +vt 0.574349 0.774985 +vt 0.574140 0.775798 +vt 0.874588 0.878089 +vt 0.983227 0.040710 +vt 0.983297 0.040233 +vt 0.982944 0.042551 +vt 0.891086 0.041729 +vt 0.891154 0.042132 +vt 0.890811 0.040176 +vt 0.704779 0.010625 +vt 0.704798 0.008856 +vt 0.704812 0.007516 +vt 0.704805 0.039664 +vt 0.704817 0.039325 +vt 0.704813 0.038566 +vt 0.890280 0.011961 +vt 0.889786 0.015542 +vt 0.890852 0.008622 +vt 0.704817 0.006762 +vt 0.704804 0.006439 +vt 0.890242 0.036840 +vt 0.889647 0.032505 +vt 0.890733 0.028195 +vt 0.889293 0.028107 +vt 0.889230 0.023789 +vt 0.889407 0.019540 +vt 0.704798 0.037233 +vt 0.704779 0.035477 +vt 0.704760 0.033501 +vt 0.704751 0.031425 +vt 0.704760 0.029332 +vt 0.704780 0.027238 +vt 0.704800 0.025144 +vt 0.704808 0.023051 +vt 0.704800 0.020959 +vt 0.704780 0.018869 +vt 0.704760 0.016779 +vt 0.704751 0.014687 +vt 0.704760 0.012609 +vt 0.982404 0.071918 +vt 0.981922 0.068765 +vt 0.982949 0.074624 +vt 0.982359 0.046479 +vt 0.981751 0.051407 +vt 0.981421 0.056099 +vt 0.981380 0.060534 +vt 0.981564 0.064867 +vt 0.851021 0.401879 +vt 0.851046 0.405123 +vt 0.853361 0.405118 +vt 0.853276 0.401866 +vt 0.851319 0.407455 +vt 0.853600 0.407455 +vt 0.855635 0.407456 +vt 0.855487 0.405115 +vt 0.855358 0.401856 +vt 0.176181 0.091548 +vt 0.179529 0.091401 +vt 0.179510 0.090179 +vt 0.176123 0.090204 +vt 0.183963 0.091566 +vt 0.183962 0.090398 +vt 0.183962 0.090158 +vt 0.179476 0.089899 +vt 0.175735 0.089656 +vt 0.788920 0.011176 +vt 0.788937 0.007989 +vt 0.787768 0.007891 +vt 0.787741 0.011082 +vt 0.788950 0.005519 +vt 0.787793 0.005418 +vt 0.787383 0.005391 +vt 0.787355 0.007865 +vt 0.787325 0.011058 +vt 0.852758 0.394594 +vt 0.851929 0.394954 +vt 0.853756 0.394927 +vt 0.854344 0.394567 +vt 0.851317 0.396113 +vt 0.853345 0.396088 +vt 0.855168 0.396065 +vt 0.855275 0.394902 +vt 0.855482 0.394541 +vt 0.988802 0.069222 +vt 0.988532 0.069449 +vt 0.173538 0.098239 +vt 0.176097 0.097900 +vt 0.174679 0.097958 +vt 0.176227 0.096665 +vt 0.174827 0.096866 +vt 0.174450 0.098048 +vt 0.174596 0.097150 +vt 0.179986 0.133176 +vt 0.184138 0.133177 +vt 0.176832 0.133163 +vt 0.176981 0.134271 +vt 0.180031 0.134286 +vt 0.184163 0.134283 +vt 0.987319 0.055750 +vt 0.987531 0.052517 +vt 0.848126 0.398617 +vt 0.848609 0.398611 +vt 0.848244 0.396017 +vt 0.848761 0.396133 +vt 0.188275 0.097889 +vt 0.183972 0.097880 +vt 0.191485 0.097916 +vt 0.191343 0.096805 +vt 0.188248 0.096690 +vt 0.183970 0.096632 +vt 0.891280 0.028127 +vt 0.891506 0.031327 +vt 0.794603 0.008449 +vt 0.794559 0.005872 +vt 0.793455 0.005903 +vt 0.793486 0.008359 +vt 0.188311 0.133173 +vt 0.188312 0.134271 +vt 0.988040 0.049875 +vt 0.987837 0.051196 +vt 0.988138 0.050993 +vt 0.848361 0.394814 +vt 0.848987 0.394986 +vt 0.848469 0.394465 +vt 0.849258 0.394640 +vt 0.179537 0.097879 +vt 0.179558 0.096604 +vt 0.857023 0.401859 +vt 0.857172 0.405121 +vt 0.857578 0.405095 +vt 0.857431 0.401851 +vt 0.857271 0.407453 +vt 0.857667 0.407345 +vt 0.857891 0.406829 +vt 0.857871 0.404953 +vt 0.857737 0.401762 +vt 0.507110 0.038378 +vt 0.511290 0.038234 +vt 0.511438 0.034117 +vt 0.507202 0.034318 +vt 0.514392 0.038046 +vt 0.514626 0.033871 +vt 0.514625 0.028518 +vt 0.511442 0.028798 +vt 0.507249 0.029034 +vt 0.786796 0.011070 +vt 0.786827 0.007875 +vt 0.786581 0.007895 +vt 0.786550 0.011073 +vt 0.786856 0.005399 +vt 0.786614 0.005500 +vt 0.786459 0.005949 +vt 0.786398 0.007898 +vt 0.786361 0.011018 +vt 0.856654 0.394465 +vt 0.856649 0.394859 +vt 0.857064 0.394976 +vt 0.857072 0.394569 +vt 0.856701 0.396048 +vt 0.857106 0.396133 +vt 0.072730 0.040503 +vt 0.073954 0.040911 +vt 0.074561 0.040905 +vt 0.073959 0.040596 +vt 0.072562 0.040094 +vt 0.073842 0.040174 +vt 0.184280 0.138757 +vt 0.180122 0.138784 +vt 0.180136 0.139931 +vt 0.184311 0.139896 +vt 0.177052 0.138785 +vt 0.177028 0.139944 +vt 0.176679 0.140367 +vt 0.180114 0.140275 +vt 0.184320 0.140231 +vt 0.993642 0.454891 +vt 0.993547 0.454564 +vt 0.992486 0.455091 +vt 0.992588 0.455417 +vt 0.993231 0.453807 +vt 0.992165 0.454334 +vt 0.991785 0.454510 +vt 0.992107 0.455267 +vt 0.992211 0.455592 +vt 0.174554 0.093117 +vt 0.174779 0.092186 +vt 0.174753 0.090630 +vt 0.174536 0.091289 +vt 0.174683 0.089773 +vt 0.174529 0.089998 +vt 0.851064 0.398602 +vt 0.853228 0.398582 +vt 0.855223 0.398565 +vt 0.191541 0.138654 +vt 0.188454 0.138708 +vt 0.188502 0.139840 +vt 0.191627 0.139785 +vt 0.188543 0.140180 +vt 0.192004 0.140193 +vt 0.788924 0.016359 +vt 0.788922 0.014221 +vt 0.787737 0.014131 +vt 0.787740 0.016272 +vt 0.787320 0.014109 +vt 0.787323 0.016250 +vt 0.188262 0.091835 +vt 0.188276 0.090699 +vt 0.191369 0.092269 +vt 0.191420 0.091088 +vt 0.191790 0.090640 +vt 0.188309 0.090443 +vt 0.993201 0.448759 +vt 0.993261 0.448447 +vt 0.992215 0.448011 +vt 0.992147 0.448323 +vt 0.192798 0.138609 +vt 0.192853 0.139743 +vt 0.192930 0.140146 +vt 0.991839 0.447875 +vt 0.991769 0.448179 +vt 0.076960 0.040455 +vt 0.076972 0.039956 +vt 0.073859 0.039691 +vt 0.081267 0.040753 +vt 0.081270 0.040252 +vt 0.081301 0.039438 +vt 0.077022 0.039149 +vt 0.073919 0.038926 +vt 0.085719 0.040888 +vt 0.085712 0.040389 +vt 0.089077 0.040928 +vt 0.089062 0.040444 +vt 0.089058 0.039676 +vt 0.085723 0.039580 +vt 0.175191 0.017235 +vt 0.179353 0.017526 +vt 0.179362 0.017237 +vt 0.175225 0.016947 +vt 0.182418 0.017823 +vt 0.182326 0.017529 +vt 0.181748 0.017301 +vt 0.179316 0.017029 +vt 0.175251 0.016739 +vt 0.167902 0.017105 +vt 0.171006 0.017113 +vt 0.171064 0.016826 +vt 0.168062 0.016823 +vt 0.171161 0.016625 +vt 0.168689 0.016655 +vt 0.704227 0.781491 +vt 0.704033 0.782240 +vt 0.705045 0.785412 +vt 0.705295 0.784840 +vt 0.073029 0.035707 +vt 0.074321 0.035380 +vt 0.074708 0.032093 +vt 0.073463 0.032286 +vt 0.075189 0.027981 +vt 0.074009 0.027993 +vt 0.706381 0.789372 +vt 0.706715 0.789060 +vt 0.991713 0.455768 +vt 0.991609 0.455442 +vt 0.991338 0.455438 +vt 0.991440 0.455760 +vt 0.991286 0.454685 +vt 0.991032 0.454708 +vt 0.183537 0.017659 +vt 0.182350 0.017330 +vt 0.183679 0.017964 +vt 0.995897 0.634936 +vt 0.995891 0.635270 +vt 0.996277 0.635264 +vt 0.996284 0.634887 +vt 0.995884 0.635724 +vt 0.996269 0.635835 +vt 0.090446 0.040532 +vt 0.090435 0.039864 +vt 0.090464 0.040980 +vt 0.856844 0.398561 +vt 0.857251 0.398570 +vt 0.857550 0.398541 +vt 0.857377 0.396564 +vt 0.081486 0.035764 +vt 0.085705 0.035939 +vt 0.085553 0.032732 +vt 0.081608 0.032535 +vt 0.088864 0.036165 +vt 0.088462 0.032936 +vt 0.088243 0.028715 +vt 0.085527 0.028581 +vt 0.081809 0.028403 +vt 0.786793 0.016266 +vt 0.786791 0.014123 +vt 0.786545 0.014110 +vt 0.786552 0.016184 +vt 0.786363 0.014009 +vt 0.786402 0.015735 +vt 0.794056 0.019458 +vt 0.790851 0.019273 +vt 0.790678 0.023253 +vt 0.793616 0.023342 +vt 0.786565 0.019348 +vt 0.786690 0.023371 +vt 0.786905 0.028693 +vt 0.790630 0.028568 +vt 0.793349 0.028551 +vt 0.991261 0.448045 +vt 0.991327 0.447767 +vt 0.991091 0.447660 +vt 0.991027 0.447938 +vt 0.991385 0.447449 +vt 0.991137 0.447337 +vt 0.166592 0.017427 +vt 0.166568 0.017770 +vt 0.167842 0.017754 +vt 0.167867 0.017412 +vt 0.166627 0.017120 +vt 0.995651 0.466725 +vt 0.995292 0.466755 +vt 0.996697 0.470803 +vt 0.997051 0.470765 +vt 0.183496 0.030841 +vt 0.182181 0.030657 +vt 0.181449 0.035757 +vt 0.182679 0.035919 +vt 0.180667 0.039464 +vt 0.181794 0.039595 +vt 0.997641 0.473632 +vt 0.997983 0.473587 +vt 0.707865 0.793430 +vt 0.708238 0.793233 +vt 0.075699 0.023580 +vt 0.074574 0.023556 +vt 0.076096 0.020109 +vt 0.075008 0.020133 +vt 0.709081 0.796537 +vt 0.709451 0.796354 +vt 0.179005 0.030241 +vt 0.178474 0.035388 +vt 0.174817 0.029828 +vt 0.174524 0.035022 +vt 0.174247 0.038873 +vt 0.177932 0.039167 +vt 0.783113 0.028908 +vt 0.783513 0.033952 +vt 0.787197 0.033893 +vt 0.780279 0.029143 +vt 0.780787 0.034006 +vt 0.781156 0.037547 +vt 0.783804 0.037639 +vt 0.787451 0.037737 +vt 0.182346 0.021092 +vt 0.179244 0.020764 +vt 0.179222 0.024906 +vt 0.182405 0.025292 +vt 0.175064 0.020441 +vt 0.174989 0.024524 +vt 0.991985 0.445079 +vt 0.992300 0.445109 +vt 0.993439 0.441387 +vt 0.993114 0.441346 +vt 0.498645 0.038185 +vt 0.499911 0.038229 +vt 0.500116 0.034202 +vt 0.498885 0.034156 +vt 0.500363 0.028938 +vt 0.499176 0.028889 +vt 0.994951 0.436537 +vt 0.994624 0.436489 +vt 0.502964 0.038339 +vt 0.503096 0.034307 +vt 0.503242 0.029039 +vt 0.992588 0.458605 +vt 0.992246 0.458625 +vt 0.993615 0.462258 +vt 0.993972 0.462233 +vt 0.183624 0.021243 +vt 0.183721 0.025466 +vt 0.170911 0.020306 +vt 0.170877 0.024362 +vt 0.167855 0.020295 +vt 0.167894 0.024346 +vt 0.167924 0.029635 +vt 0.170806 0.029653 +vt 0.782371 0.019635 +vt 0.782693 0.023654 +vt 0.779328 0.020088 +vt 0.779743 0.024038 +vt 0.995882 0.638049 +vt 0.995465 0.637427 +vt 0.995478 0.640388 +vt 0.995897 0.640835 +vt 0.795370 0.019921 +vt 0.794817 0.023648 +vt 0.794458 0.028636 +vt 0.995478 0.644540 +vt 0.995899 0.644733 +vt 0.077354 0.035488 +vt 0.077651 0.032248 +vt 0.078023 0.028159 +vt 0.997979 0.426191 +vt 0.998263 0.426232 +vt 0.998350 0.426004 +vt 0.998089 0.425967 +vt 0.499695 0.017632 +vt 0.500792 0.017681 +vt 0.500905 0.017479 +vt 0.499854 0.017429 +vt 0.214524 0.360632 +vt 0.214345 0.361677 +vt 0.214386 0.362193 +vt 0.214528 0.361679 +vt 0.214790 0.360479 +vt 0.214775 0.361570 +vt 0.082570 0.017853 +vt 0.086378 0.017784 +vt 0.086355 0.017574 +vt 0.082575 0.017641 +vt 0.089267 0.017764 +vt 0.089146 0.017557 +vt 0.862594 0.428721 +vt 0.862817 0.431495 +vt 0.862904 0.430914 +vt 0.862772 0.428634 +vt 0.862496 0.424954 +vt 0.862686 0.424936 +vt 0.506989 0.017835 +vt 0.510530 0.017730 +vt 0.510503 0.017521 +vt 0.506987 0.017624 +vt 0.513138 0.017582 +vt 0.513022 0.017382 +vt 0.512507 0.017291 +vt 0.510436 0.017375 +vt 0.506983 0.017468 +vt 0.076309 0.018121 +vt 0.078926 0.017990 +vt 0.078956 0.017779 +vt 0.076428 0.017910 +vt 0.862594 0.421339 +vt 0.862772 0.421386 +vt 0.862817 0.418807 +vt 0.862903 0.419306 +vt 0.790881 0.033850 +vt 0.793603 0.033828 +vt 0.791207 0.037795 +vt 0.794032 0.037817 +vt 0.170693 0.034869 +vt 0.167919 0.034855 +vt 0.167898 0.038745 +vt 0.170588 0.038753 +vt 0.078431 0.023655 +vt 0.082127 0.023754 +vt 0.082419 0.019991 +vt 0.078755 0.020049 +vt 0.511125 0.023643 +vt 0.507170 0.023841 +vt 0.514106 0.023401 +vt 0.513478 0.019665 +vt 0.510740 0.019846 +vt 0.507054 0.019984 +vt 0.085822 0.023839 +vt 0.088551 0.023899 +vt 0.089024 0.019980 +vt 0.086189 0.019974 +vt 0.996459 0.431757 +vt 0.996134 0.431705 +vt 0.500573 0.023730 +vt 0.499428 0.023681 +vt 0.500714 0.019844 +vt 0.499600 0.019795 +vt 0.997595 0.428201 +vt 0.997277 0.428149 +vt 0.503344 0.023832 +vt 0.503401 0.019949 +vt 0.995445 0.649174 +vt 0.995865 0.649256 +vt 0.794717 0.033826 +vt 0.795194 0.037820 +vt 0.995396 0.652878 +vt 0.995803 0.652949 +vt 0.863375 0.431566 +vt 0.863252 0.428693 +vt 0.862998 0.428684 +vt 0.863111 0.431465 +vt 0.863168 0.424911 +vt 0.862915 0.424922 +vt 0.214810 0.367756 +vt 0.214794 0.371289 +vt 0.215043 0.371271 +vt 0.215060 0.367756 +vt 0.214775 0.373896 +vt 0.215027 0.373794 +vt 0.215195 0.373289 +vt 0.215245 0.371215 +vt 0.215268 0.367757 +vt 0.214794 0.364205 +vt 0.215043 0.364224 +vt 0.215027 0.361674 +vt 0.215245 0.364282 +vt 0.215195 0.362186 +vt 0.863252 0.421286 +vt 0.862998 0.421316 +vt 0.863376 0.418679 +vt 0.863111 0.418793 +vt 0.503432 0.017787 +vt 0.503455 0.017578 +vt 0.503515 0.017430 +vt 0.501421 0.017380 +vt 0.863322 0.432963 +vt 0.863638 0.432772 +vt 0.863664 0.432590 +vt 0.863388 0.432771 +vt 0.795445 0.040049 +vt 0.794258 0.040036 +vt 0.794140 0.040241 +vt 0.795277 0.040257 +vt 0.863805 0.431436 +vt 0.863743 0.430867 +vt 0.863622 0.431436 +vt 0.787587 0.039876 +vt 0.783962 0.039700 +vt 0.783995 0.039911 +vt 0.787595 0.040087 +vt 0.781357 0.039537 +vt 0.781478 0.039750 +vt 0.781988 0.039906 +vt 0.784059 0.040064 +vt 0.787597 0.040242 +vt 0.180241 0.041531 +vt 0.177635 0.041271 +vt 0.177600 0.041478 +vt 0.180117 0.041725 +vt 0.174094 0.041016 +vt 0.174084 0.041227 +vt 0.174077 0.041383 +vt 0.177529 0.041623 +vt 0.179599 0.041795 +vt 0.710242 0.798091 +vt 0.709933 0.798255 +vt 0.710105 0.798476 +vt 0.710378 0.798327 +vt 0.075242 0.018176 +vt 0.075407 0.017958 +vt 0.863091 0.417771 +vt 0.863388 0.417612 +vt 0.214828 0.375145 +vt 0.215120 0.374994 +vt 0.215061 0.374833 +vt 0.214790 0.374978 +vt 0.181312 0.041645 +vt 0.181143 0.041838 +vt 0.215269 0.373804 +vt 0.791380 0.039987 +vt 0.791360 0.040196 +vt 0.791292 0.040345 +vt 0.793573 0.040356 +vt 0.170530 0.040914 +vt 0.170545 0.041123 +vt 0.167885 0.040909 +vt 0.167991 0.041115 +vt 0.168506 0.041237 +vt 0.170603 0.041274 +vt 0.188255 0.094253 +vt 0.183967 0.094087 +vt 0.191356 0.094550 +vt 0.849522 0.398615 +vt 0.849758 0.396132 +vt 0.849431 0.401887 +vt 0.174804 0.094610 +vt 0.174576 0.095305 +vt 0.176204 0.094126 +vt 0.850237 0.394979 +vt 0.850863 0.394624 +vt 0.179543 0.093995 +vt 0.849395 0.405125 +vt 0.849561 0.407453 +vt 0.077145 0.037739 +vt 0.074063 0.037591 +vt 0.081380 0.038016 +vt 0.995455 0.635452 +vt 0.995459 0.635972 +vt 0.995879 0.636487 +vt 0.795756 0.017426 +vt 0.794739 0.017217 +vt 0.794309 0.017712 +vt 0.795641 0.018090 +vt 0.786502 0.017300 +vt 0.782160 0.017557 +vt 0.782220 0.017894 +vt 0.786513 0.017619 +vt 0.778689 0.017835 +vt 0.779097 0.018305 +vt 0.790992 0.017217 +vt 0.790946 0.017554 +vt 0.085749 0.038170 +vt 0.089042 0.038342 +vt 0.703376 0.778796 +vt 0.703075 0.779207 +vt 0.703412 0.780273 +vt 0.703642 0.779637 +vt 0.072629 0.038981 +vt 0.072762 0.037827 +vt 0.175126 0.017884 +vt 0.170943 0.017762 +vt 0.170927 0.018377 +vt 0.175101 0.018501 +vt 0.167836 0.018369 +vt 0.991843 0.456321 +vt 0.991556 0.456318 +vt 0.991662 0.456874 +vt 0.991976 0.456866 +vt 0.183610 0.018613 +vt 0.182350 0.018473 +vt 0.182321 0.019096 +vt 0.183582 0.019238 +vt 0.499389 0.040753 +vt 0.502848 0.040784 +vt 0.502891 0.040245 +vt 0.499770 0.040140 +vt 0.507065 0.040829 +vt 0.507067 0.040295 +vt 0.991651 0.447483 +vt 0.991785 0.446890 +vt 0.991496 0.446868 +vt 0.498435 0.040710 +vt 0.498521 0.040100 +vt 0.179286 0.018175 +vt 0.179257 0.018796 +vt 0.511267 0.040725 +vt 0.511232 0.040180 +vt 0.514696 0.040645 +vt 0.514328 0.040026 +vt 0.995307 0.449299 +vt 0.995260 0.449613 +vt 0.191460 0.136440 +vt 0.192713 0.136393 +vt 0.791236 0.014397 +vt 0.791238 0.016529 +vt 0.791224 0.011360 +vt 0.188382 0.136481 +vt 0.184220 0.136511 +vt 0.995623 0.453532 +vt 0.995704 0.453863 +vt 0.995316 0.452775 +vt 0.180076 0.136526 +vt 0.177015 0.136518 +vt 0.791221 0.008182 +vt 0.791212 0.005719 +vt 0.166567 0.018383 +vt 0.991221 0.446746 +vt 0.991683 0.444947 +vt 0.166601 0.020307 +vt 0.515615 0.040587 +vt 0.515550 0.039966 +vt 0.992075 0.456186 +vt 0.992215 0.456695 +vt 0.992847 0.458415 +vt 0.515664 0.037971 +vt 0.514206 0.017516 +vt 0.514046 0.017315 +vt 0.214540 0.374989 +vt 0.214524 0.374828 +vt 0.214528 0.373790 +vt 0.214345 0.373797 +vt 0.214385 0.373283 +vt 0.214371 0.364288 +vt 0.214548 0.364227 +vt 0.214380 0.367758 +vt 0.214564 0.367757 +vt 0.214371 0.371211 +vt 0.214548 0.371269 +vt 0.166749 0.029640 +vt 0.166785 0.034860 +vt 0.994311 0.436346 +vt 0.995823 0.431562 +vt 0.996971 0.428009 +vt 0.166794 0.038750 +vt 0.166798 0.040914 +vt 0.166949 0.041124 +vt 0.997708 0.426063 +vt 0.997838 0.425848 +vt 0.215061 0.360625 +vt 0.215269 0.361667 +vt 0.515938 0.033766 +vt 0.994237 0.462030 +vt 0.995914 0.466515 +vt 0.515938 0.028396 +vt 0.166675 0.024355 +vt 0.992801 0.441207 +vt 0.515333 0.023294 +vt 0.997316 0.470560 +vt 0.998248 0.473393 +vt 0.514602 0.019585 +vt 0.991580 0.447823 +vt 0.991513 0.448105 +vt 0.498463 0.041049 +vt 0.498357 0.041048 +vt 0.787049 0.014111 +vt 0.787052 0.016254 +vt 0.787055 0.011059 +vt 0.991854 0.455362 +vt 0.991959 0.455687 +vt 0.991531 0.454605 +vt 0.787085 0.007865 +vt 0.787114 0.005390 +vt 0.515649 0.040928 +vt 0.515725 0.040924 +vt 0.992256 0.455799 +vt 0.992023 0.455937 +vt 0.991781 0.456027 +vt 0.787382 0.004239 +vt 0.787114 0.004238 +vt 0.787362 0.003888 +vt 0.787095 0.003887 +vt 0.786837 0.003896 +vt 0.786856 0.004246 +vt 0.175714 0.134226 +vt 0.175744 0.136485 +vt 0.175514 0.134164 +vt 0.175544 0.136437 +vt 0.175575 0.138729 +vt 0.175776 0.138763 +vt 0.793406 0.004761 +vt 0.791181 0.004573 +vt 0.793345 0.004416 +vt 0.791135 0.004226 +vt 0.788907 0.004021 +vt 0.788937 0.004370 +vt 0.192595 0.097009 +vt 0.192609 0.095048 +vt 0.709765 0.775402 +vt 0.709901 0.775010 +vt 0.708418 0.775626 +vt 0.707950 0.776162 +vt 0.706674 0.776370 +vt 0.706014 0.776992 +vt 0.192624 0.092950 +vt 0.986954 0.633152 +vt 0.987223 0.634034 +vt 0.988654 0.634105 +vt 0.988072 0.633201 +vt 0.987515 0.634383 +vt 0.989359 0.634482 +vt 0.991546 0.634617 +vt 0.990599 0.634222 +vt 0.989826 0.633303 +vt 0.786610 0.004392 +vt 0.786589 0.004048 +vt 0.166838 0.016833 +vt 0.168092 0.016625 +vt 0.995762 0.633606 +vt 0.995884 0.634533 +vt 0.996271 0.634461 +vt 0.996147 0.633549 +vt 0.090290 0.041372 +vt 0.088955 0.041338 +vt 0.088964 0.041653 +vt 0.088303 0.041584 +vt 0.991505 0.456020 +vt 0.183646 0.018271 +vt 0.182385 0.018130 +vt 0.170970 0.017420 +vt 0.175157 0.017542 +vt 0.179319 0.017833 +vt 0.081269 0.041501 +vt 0.085631 0.041622 +vt 0.085702 0.041314 +vt 0.081268 0.041183 +vt 0.077046 0.041197 +vt 0.076978 0.040883 +vt 0.787789 0.004266 +vt 0.787767 0.003916 +vt 0.992693 0.634347 +vt 0.992101 0.633437 +vt 0.993372 0.634730 +vt 0.994663 0.634815 +vt 0.994418 0.634449 +vt 0.994131 0.633550 +vt 0.175782 0.139929 +vt 0.175591 0.139903 +vt 0.992614 0.455586 +vt 0.175725 0.140343 +vt 0.703222 0.778314 +vt 0.702882 0.778601 +vt 0.703108 0.777960 +vt 0.702752 0.778203 +vt 0.072576 0.039647 +vt 0.988416 0.051154 +vt 0.988577 0.052436 +vt 0.710654 0.775038 +vt 0.710633 0.774715 +vt 0.192767 0.097975 +vt 0.988358 0.070394 +vt 0.988223 0.069289 +vt 0.986524 0.634110 +vt 0.986624 0.634455 +vt 0.986392 0.633186 +vt 0.192645 0.091602 +vt 0.705213 0.776995 +vt 0.704771 0.777526 +vt 0.704169 0.777449 +vt 0.704078 0.777831 +vt 0.192716 0.090852 +vt 0.989317 0.042258 +vt 0.989381 0.041878 +vt 0.989063 0.043738 +vt 0.894162 0.041622 +vt 0.894145 0.041287 +vt 0.893948 0.041363 +vt 0.894007 0.041722 +vt 0.893899 0.039868 +vt 0.893694 0.039927 +vt 0.701745 0.010193 +vt 0.701975 0.010230 +vt 0.701976 0.008408 +vt 0.701746 0.008366 +vt 0.701976 0.007029 +vt 0.701746 0.006983 +vt 0.701791 0.040117 +vt 0.701970 0.040130 +vt 0.701976 0.039793 +vt 0.701754 0.039840 +vt 0.701976 0.039015 +vt 0.701746 0.039068 +vt 0.892974 0.015597 +vt 0.893533 0.011711 +vt 0.893354 0.011571 +vt 0.892860 0.014341 +vt 0.894162 0.007979 +vt 0.893995 0.007950 +vt 0.701976 0.006257 +vt 0.701753 0.006217 +vt 0.701970 0.005935 +vt 0.701790 0.005949 +vt 0.893367 0.036809 +vt 0.893166 0.036956 +vt 0.174417 0.132843 +vt 0.175545 0.133123 +vt 0.892646 0.015469 +vt 0.175349 0.133057 +vt 0.701976 0.037641 +vt 0.701746 0.037690 +vt 0.701975 0.035829 +vt 0.701746 0.035873 +vt 0.701974 0.033790 +vt 0.701745 0.033827 +vt 0.701973 0.031650 +vt 0.701745 0.031680 +vt 0.701974 0.029495 +vt 0.701745 0.029519 +vt 0.701975 0.027342 +vt 0.701746 0.027359 +vt 0.701976 0.025187 +vt 0.701746 0.025198 +vt 0.701976 0.023032 +vt 0.701746 0.023035 +vt 0.701976 0.020876 +vt 0.701746 0.020873 +vt 0.701975 0.018722 +vt 0.701746 0.018711 +vt 0.701974 0.016569 +vt 0.701745 0.016551 +vt 0.701973 0.014415 +vt 0.701745 0.014390 +vt 0.701974 0.012274 +vt 0.701745 0.012243 +vt 0.891815 0.032643 +vt 0.794494 0.004672 +vt 0.794425 0.004321 +vt 0.988544 0.046797 +vt 0.988716 0.073124 +vt 0.989204 0.076686 +vt 0.166797 0.040478 +vt 0.167887 0.040473 +vt 0.997811 0.426577 +vt 0.997520 0.426442 +vt 0.514265 0.017940 +vt 0.513189 0.018008 +vt 0.998417 0.474824 +vt 0.998669 0.474640 +vt 0.998569 0.475140 +vt 0.998802 0.474965 +vt 0.170541 0.040478 +vt 0.174121 0.040583 +vt 0.998091 0.474867 +vt 0.180310 0.041108 +vt 0.181389 0.041224 +vt 0.998263 0.475177 +vt 0.177684 0.040843 +vt 0.503425 0.018223 +vt 0.500776 0.018117 +vt 0.506999 0.018269 +vt 0.510562 0.018160 +vt 0.998114 0.426624 +vt 0.499675 0.018068 +vt 0.192815 0.090331 +vt 0.192734 0.090305 +vt 0.703527 0.777747 +vt 0.703605 0.778071 +vt 0.703707 0.778459 +vt 0.995383 0.634505 +vt 0.995239 0.633598 +vt 0.995426 0.634880 +vt 0.777761 0.018118 +vt 0.777889 0.018782 +vt 0.703894 0.779098 +vt 0.704441 0.780842 +vt 0.778113 0.020660 +vt 0.090400 0.038711 +vt 0.996261 0.636811 +vt 0.996263 0.638484 +vt 0.090166 0.036632 +vt 0.780281 0.039463 +vt 0.780447 0.039682 +vt 0.710555 0.798063 +vt 0.710654 0.798309 +vt 0.863664 0.417747 +vt 0.863623 0.418774 +vt 0.863805 0.418764 +vt 0.863743 0.419272 +vt 0.090464 0.017756 +vt 0.090295 0.017546 +vt 0.862988 0.432815 +vt 0.863092 0.432625 +vt 0.863597 0.424894 +vt 0.863672 0.421348 +vt 0.863498 0.421296 +vt 0.863414 0.424900 +vt 0.863671 0.428587 +vt 0.863497 0.428659 +vt 0.089355 0.028856 +vt 0.089673 0.023932 +vt 0.996284 0.644774 +vt 0.996250 0.649181 +vt 0.996178 0.652852 +vt 0.090194 0.019981 +vt 0.089657 0.033279 +vt 0.996279 0.641115 +vt 0.779109 0.029330 +vt 0.779656 0.034036 +vt 0.707066 0.788850 +vt 0.708624 0.793152 +vt 0.709828 0.796301 +vt 0.780061 0.037502 +vt 0.856322 0.398559 +vt 0.856190 0.396053 +vt 0.856496 0.401855 +vt 0.994879 0.635029 +vt 0.995447 0.635164 +vt 0.174735 0.089191 +vt 0.174599 0.089207 +vt 0.778549 0.024464 +vt 0.705565 0.784365 +vt 0.856158 0.394880 +vt 0.856187 0.394506 +vt 0.856642 0.405117 +vt 0.856748 0.407455 +vt 0.090434 0.018200 +vt 0.089240 0.018207 +vt 0.995727 0.654611 +vt 0.996075 0.654512 +vt 0.995645 0.655012 +vt 0.995955 0.654913 +vt 0.780239 0.039053 +vt 0.781318 0.039123 +vt 0.710038 0.797742 +vt 0.710387 0.797701 +vt 0.791356 0.039547 +vt 0.794231 0.039593 +vt 0.787564 0.039444 +vt 0.709693 0.797918 +vt 0.076270 0.018535 +vt 0.075199 0.018585 +vt 0.783931 0.039277 +vt 0.995349 0.654537 +vt 0.795416 0.039605 +vt 0.995306 0.654938 +vt 0.078896 0.018412 +vt 0.082548 0.018286 +vt 0.086355 0.018224 +vn -0.9665 0.2564 0.0082 +vn -0.9709 0.2395 0.0001 +vn -0.9666 0.2563 -0.0000 +vn -0.9665 0.2566 0.0000 +vn -0.9709 0.2394 0.0001 +vn -0.9709 0.2394 0.0000 +vn -0.9709 0.2395 -0.0001 +vn -0.9709 0.2396 -0.0003 +vn -0.9665 0.2567 0.0000 +vn -0.9708 0.2398 -0.0002 +vn -0.9708 0.2398 0.0000 +vn -0.9708 0.2398 0.0002 +vn -0.9666 0.2564 0.0000 +vn -0.9666 0.2562 0.0000 +vn -0.9889 0.1487 0.0000 +vn -0.9667 0.2561 0.0000 +vn -0.9889 0.1488 0.0000 +vn -0.9666 0.2561 0.0000 +vn -0.9888 0.1491 0.0077 +vn -0.9999 -0.0128 0.0095 +vn -0.9986 -0.0425 0.0301 +vn -0.9978 -0.0517 -0.0413 +vn -0.9973 -0.0147 -0.0724 +vn -0.9973 -0.0542 0.0501 +vn -0.9978 -0.0663 -0.0094 +vn -0.7188 -0.0600 -0.6927 +vn -0.7686 -0.0463 -0.6380 +vn -0.8945 0.0479 -0.4445 +vn -0.1530 -0.0120 -0.9882 +vn -0.1700 -0.0298 -0.9850 +vn -0.1582 -0.0435 -0.9865 +vn -0.0643 -0.0148 -0.9978 +vn -0.1735 -0.0346 -0.9842 +vn -0.2018 -0.0467 -0.9783 +vn -0.2126 -0.0568 -0.9755 +vn -0.1113 -0.0522 -0.9924 +vn 0.1227 -0.0436 -0.9915 +vn 0.2182 0.0941 0.9713 +vn 0.2034 0.0109 0.9790 +vn -0.0306 -0.0000 0.9995 +vn -0.0880 0.0891 0.9921 +vn 0.1983 0.0003 0.9801 +vn -0.0829 -0.0131 0.9965 +vn -0.7231 -0.0452 0.6892 +vn -0.6478 -0.0266 0.7613 +vn -0.8787 0.0566 0.4740 +vn -0.5919 -0.8040 -0.0573 +vn -0.3970 -0.9150 -0.0723 +vn -0.4281 -0.8985 0.0967 +vn -0.6094 -0.7855 0.1073 +vn 0.3870 -0.9203 -0.0582 +vn 0.3877 -0.9066 0.1665 +vn 0.2454 -0.6903 0.6806 +vn -0.3587 -0.6022 0.7132 +vn -0.5047 -0.5157 0.6923 +vn 0.1904 -0.0565 0.9801 +vn 0.1950 -0.0608 0.9789 +vn -0.0444 0.0032 0.9990 +vn -0.0522 0.0093 0.9986 +vn 0.2066 -0.1334 0.9693 +vn -0.0783 -0.0654 0.9948 +vn -0.8420 0.0922 0.5316 +vn -0.6759 0.1637 0.7186 +vn -0.6874 0.1811 0.7034 +vn 0.3606 0.0601 -0.9308 +vn 0.3782 -0.0038 -0.9257 +vn 0.8559 -0.0158 -0.5169 +vn 0.8616 0.0676 -0.5031 +vn 0.3643 -0.0272 -0.9309 +vn 0.8448 -0.0632 -0.5313 +vn 0.8448 -0.0632 -0.5314 +vn 0.9914 -0.0736 -0.1086 +vn 0.9941 -0.0236 -0.1059 +vn 0.8617 0.0676 -0.5030 +vn 0.9923 0.0737 -0.0992 +vn 0.1938 -0.1405 -0.9709 +vn -0.1022 -0.0661 -0.9926 +vn -0.7313 -0.3329 -0.5953 +vn 0.1799 -0.6372 -0.7494 +vn -0.8518 0.0954 -0.5151 +vn -0.9852 0.0648 -0.1585 +vn -0.7313 -0.3328 -0.5954 +vn -0.9852 0.0648 -0.1586 +vn -0.9974 0.0316 0.0655 +vn -0.8830 -0.4681 0.0344 +vn 0.1799 -0.6371 -0.7495 +vn -0.0181 -0.9982 -0.0569 +vn 0.9253 -0.3295 0.1880 +vn 0.8157 -0.2046 0.5411 +vn 0.8897 -0.1937 0.4134 +vn 0.9239 -0.2209 0.3123 +vn 0.7339 -0.1363 0.6654 +vn 0.8615 -0.1567 0.4831 +vn 0.5088 -0.0921 0.8559 +vn 0.5175 -0.1095 0.8486 +vn 0.5366 -0.1236 0.8347 +vn 0.7249 -0.0951 0.6823 +vn 0.8604 -0.1127 0.4971 +vn 0.7392 -0.0536 0.6713 +vn 0.8722 -0.0674 0.4844 +vn 0.5128 -0.0410 0.8575 +vn 0.5098 -0.0673 0.8577 +vn 0.8307 0.0122 0.5567 +vn 0.9283 -0.0321 0.3703 +vn 0.9725 0.1397 0.1863 +vn 0.9501 -0.0210 0.3113 +vn 0.1341 -0.0458 0.9899 +vn 0.5342 -0.0248 0.8450 +vn -0.1376 0.0310 -0.9900 +vn -0.1389 0.0322 -0.9898 +vn -0.0324 0.0089 -0.9994 +vn -0.0337 0.0076 -0.9994 +vn -0.1427 0.0276 -0.9894 +vn -0.0330 0.0069 -0.9994 +vn 0.5205 -0.0952 -0.8485 +vn 0.5290 -0.1124 -0.8412 +vn 0.5470 -0.1261 -0.8276 +vn -0.1439 0.0196 -0.9894 +vn -0.0328 0.0045 -0.9995 +vn -0.1441 0.0108 -0.9895 +vn -0.0341 0.0021 -0.9994 +vn 0.5244 -0.0410 -0.8505 +vn 0.5216 -0.0695 -0.8503 +vn -0.1457 0.0016 -0.9893 +vn -0.0437 -0.0026 -0.9990 +vn 0.5437 -0.0227 -0.8390 +vn -0.9665 0.2564 -0.0081 +vn -0.9708 0.2398 -0.0088 +vn -0.9600 0.2376 -0.1480 +vn -0.9568 0.2542 -0.1413 +vn -0.9813 0.1925 -0.0076 +vn -0.9740 0.1880 -0.1268 +vn -0.6838 0.1657 -0.7106 +vn -0.6960 0.1834 -0.6942 +vn -0.9913 0.1319 -0.0038 +vn -0.9895 0.1282 -0.0667 +vn -0.9971 0.0759 -0.0009 +vn -0.9968 0.0754 -0.0278 +vn -0.9952 0.0745 -0.0636 +vn -0.9806 0.1151 -0.1585 +vn -0.9996 0.0280 0.0010 +vn -0.9984 0.0290 -0.0478 +vn -0.9910 0.0365 -0.1286 +vn -0.9974 0.0722 0.0026 +vn -0.9997 0.0238 0.0047 +vn -0.9997 0.0243 -0.0026 +vn -0.9974 0.0725 0.0001 +vn -0.9998 -0.0187 0.0102 +vn -0.9998 -0.0166 -0.0103 +vn -0.9999 -0.0123 -0.0076 +vn -0.9997 0.0259 -0.0024 +vn -0.9974 0.0727 -0.0007 +vn -0.9996 0.0272 -0.0013 +vn -0.9973 0.0733 -0.0009 +vn -1.0000 -0.0096 -0.0018 +vn -1.0000 -0.0089 0.0006 +vn -0.9996 0.0277 -0.0013 +vn -0.9973 0.0740 -0.0014 +vn -0.9996 0.0282 -0.0015 +vn -0.9972 0.0748 -0.0018 +vn -1.0000 -0.0089 0.0009 +vn -1.0000 -0.0089 0.0015 +vn -0.9996 0.0287 -0.0014 +vn -0.9971 0.0757 -0.0019 +vn -0.9996 0.0291 -0.0004 +vn -0.9971 0.0764 -0.0016 +vn -0.9999 -0.0102 0.0034 +vn -0.9999 -0.0137 0.0078 +vn -0.9996 0.0284 0.0009 +vn -0.9970 0.0770 -0.0010 +vn -0.9996 0.0267 0.0020 +vn -0.9970 0.0772 -0.0004 +vn -0.9998 -0.0193 0.0106 +vn -0.9997 -0.0251 0.0069 +vn -0.9997 0.0249 0.0014 +vn -0.9970 0.0772 0.0001 +vn -0.9997 0.0243 0.0003 +vn -0.9970 0.0771 0.0003 +vn -0.9996 -0.0274 -0.0004 +vn -0.9997 -0.0250 -0.0078 +vn -0.9997 0.0248 -0.0014 +vn -0.9970 0.0770 0.0005 +vn -0.9996 0.0264 -0.0022 +vn -0.9971 0.0767 0.0003 +vn -0.9997 -0.0194 -0.0117 +vn -0.9999 -0.0136 -0.0090 +vn -0.9996 0.0280 -0.0013 +vn -0.9971 0.0767 0.0007 +vn -0.9814 0.1916 0.0082 +vn -0.9916 0.1296 0.0049 +vn -0.9915 0.1300 0.0005 +vn -0.9814 0.1918 0.0003 +vn -0.9915 0.1300 0.0002 +vn -0.9815 0.1917 0.0002 +vn -0.9915 0.1302 -0.0002 +vn -0.9815 0.1917 0.0000 +vn -0.9914 0.1306 -0.0006 +vn -0.9814 0.1918 -0.0002 +vn -0.9914 0.1312 -0.0010 +vn -0.9814 0.1920 -0.0004 +vn -0.9913 0.1318 -0.0012 +vn -0.9813 0.1924 -0.0005 +vn -0.9912 0.1325 -0.0010 +vn -0.9813 0.1927 -0.0004 +vn -0.9911 0.1331 -0.0005 +vn -0.9812 0.1930 -0.0002 +vn -0.9911 0.1333 -0.0000 +vn -0.9812 0.1930 0.0001 +vn -0.9911 0.1334 0.0002 +vn -0.9911 0.1333 0.0002 +vn -0.9812 0.1929 0.0001 +vn -0.9911 0.1331 0.0001 +vn -0.9812 0.1928 -0.0000 +vn -0.9911 0.1328 0.0001 +vn -0.9912 0.1326 0.0002 +vn -0.9665 0.2564 0.0083 +vn -0.9708 0.2396 0.0093 +vn -0.9709 0.2394 -0.0001 +vn -0.9709 0.2396 -0.0002 +vn -0.9665 0.2566 -0.0001 +vn -0.9665 0.2567 -0.0001 +vn -0.9708 0.2397 -0.0001 +vn -0.9708 0.2397 0.0000 +vn 0.9803 -0.0765 0.1823 +vn 0.9741 -0.1310 0.1842 +vn 0.9367 -0.1249 0.3270 +vn 0.9418 -0.0723 0.3283 +vn 0.9661 -0.1802 0.1849 +vn 0.9294 -0.1720 0.3267 +vn 0.9597 -0.1779 0.2174 +vn 0.9677 -0.1295 0.2162 +vn 0.9733 -0.0758 0.2168 +vn 0.9851 -0.0189 0.1711 +vn 0.9991 -0.0363 0.0227 +vn 0.9962 -0.0799 0.0334 +vn 0.9886 0.0973 0.1150 +vn 0.9997 -0.0183 0.0137 +vn 0.9997 -0.0263 -0.0007 +vn 0.9992 -0.0409 -0.0008 +vn 0.9967 -0.0809 -0.0013 +vn 0.9991 -0.0365 -0.0231 +vn 0.9961 -0.0807 -0.0346 +vn 0.9997 -0.0187 -0.0134 +vn 0.9888 0.1059 -0.1051 +vn 0.9871 -0.0159 -0.1591 +vn 0.9813 -0.0778 -0.1759 +vn 0.6711 0.7395 -0.0533 +vn 0.6710 0.7395 -0.0533 +vn 0.9599 0.2755 0.0521 +vn 0.9599 0.2756 0.0521 +vn 0.9814 0.1607 0.1054 +vn 0.9814 0.1606 0.1053 +vn 0.9814 0.1605 0.1052 +vn 0.9861 0.1662 -0.0023 +vn 0.9861 0.1663 -0.0022 +vn 0.9861 0.1662 -0.0022 +vn 0.9664 -0.1832 0.1803 +vn 0.9578 -0.2271 0.1761 +vn 0.9249 -0.2299 0.3030 +vn 0.9388 -0.1793 0.2940 +vn 0.9436 -0.3054 0.1282 +vn 0.9157 -0.3246 0.2369 +vn 0.9439 -0.2679 0.1930 +vn 0.9552 -0.2255 0.1919 +vn 0.9663 -0.1822 0.1818 +vn 0.9812 -0.0742 0.1781 +vn 0.9870 -0.0141 0.1600 +vn 0.9992 -0.0336 0.0237 +vn 0.9964 -0.0762 0.0363 +vn 0.9922 0.0922 0.0837 +vn 0.9998 -0.0177 0.0131 +vn 0.9997 -0.0244 -0.0008 +vn 0.9993 -0.0376 -0.0000 +vn 0.9971 -0.0763 0.0018 +vn 0.9991 -0.0345 -0.0259 +vn 0.9965 -0.0757 -0.0351 +vn 0.9997 -0.0184 -0.0176 +vn 0.9913 0.0846 -0.1004 +vn 0.9845 -0.0189 -0.1744 +vn 0.9800 -0.0735 -0.1847 +vn 0.8212 -0.5707 -0.0000 +vn 0.8796 -0.4674 -0.0889 +vn 0.8848 -0.4490 -0.1243 +vn 0.8646 -0.5025 0.0000 +vn 0.9435 -0.3055 -0.1282 +vn 0.9157 -0.3247 -0.2368 +vn 0.9439 -0.2680 -0.1928 +vn 0.9522 -0.2969 -0.0720 +vn 0.9568 -0.2909 0.0002 +vn 0.9903 -0.1346 0.0349 +vn 0.9821 -0.1848 0.0364 +vn 0.9908 -0.1355 -0.0010 +vn 0.9825 -0.1860 -0.0003 +vn 0.9901 -0.1360 -0.0355 +vn 0.9818 -0.1865 -0.0362 +vn 0.9749 -0.1344 -0.1773 +vn 0.9662 -0.1855 -0.1793 +vn 0.9254 -0.3293 -0.1875 +vn 0.8198 -0.2057 -0.5344 +vn 0.7554 -0.1951 -0.6255 +vn 0.8469 -0.3198 -0.4248 +vn 0.7422 -0.1393 -0.6556 +vn 0.7343 -0.1390 -0.6645 +vn 0.7554 -0.1951 -0.6256 +vn 0.9488 -0.1769 -0.2615 +vn 0.9414 -0.2194 -0.2561 +vn 0.8469 -0.3199 -0.4248 +vn 0.9329 -0.2649 -0.2441 +vn 0.9425 -0.0090 -0.3342 +vn 0.9415 -0.0699 -0.3298 +vn 0.9694 0.1098 -0.2194 +vn 0.9755 0.0469 -0.2148 +vn 0.9743 -0.0206 -0.2241 +vn 0.9729 -0.0739 -0.2191 +vn 0.9751 -0.1304 0.1792 +vn 0.9906 -0.1316 0.0379 +vn 0.9823 -0.1838 0.0375 +vn 0.9914 -0.1307 0.0020 +vn 0.9831 -0.1829 0.0010 +vn 0.9909 -0.1299 -0.0352 +vn 0.9827 -0.1818 -0.0363 +vn 0.9746 -0.1268 -0.1847 +vn 0.9667 -0.1771 -0.1849 +vn 0.9534 0.2857 -0.0967 +vn 0.9534 0.2856 -0.0967 +vn 0.6630 0.7442 -0.0812 +vn 0.6629 0.7443 -0.0812 +vn 0.9853 0.1687 -0.0264 +vn 0.9852 0.1691 -0.0262 +vn 0.9852 0.1692 -0.0262 +vn 0.9775 0.1665 -0.1298 +vn 0.9774 0.1665 -0.1298 +vn 0.9462 -0.2960 0.1304 +vn 0.9586 -0.2203 0.1802 +vn 0.9755 -0.2170 0.0356 +vn 0.9711 -0.2369 0.0303 +vn 0.9761 -0.2171 0.0001 +vn 0.9725 -0.2328 -0.0003 +vn 0.9752 -0.2186 -0.0351 +vn 0.9707 -0.2382 -0.0298 +vn 0.9577 -0.2279 -0.1756 +vn 0.9371 -0.1211 -0.3273 +vn 0.9301 -0.1693 -0.3259 +vn 0.9680 -0.1259 -0.2170 +vn 0.9604 -0.1752 -0.2169 +vn 0.8795 -0.4674 0.0889 +vn 0.8848 -0.4490 0.1243 +vn 0.9522 -0.2968 0.0717 +vn 0.9754 -0.2177 0.0353 +vn 0.9708 -0.2381 0.0297 +vn 0.9764 -0.2159 0.0002 +vn 0.9725 -0.2328 -0.0000 +vn 0.9758 -0.2159 -0.0355 +vn 0.9711 -0.2367 -0.0302 +vn 0.9590 -0.2191 -0.1799 +vn 0.9463 -0.2959 -0.1299 +vn -0.5918 -0.8040 0.0574 +vn -0.3969 -0.9150 0.0722 +vn -0.3913 -0.9163 0.0857 +vn -0.5842 -0.8086 0.0698 +vn 0.3869 -0.9203 0.0584 +vn 0.3697 -0.9251 0.0867 +vn 0.3886 -0.9176 0.0837 +vn -0.3888 -0.9181 0.0762 +vn -0.5779 -0.8137 0.0625 +vn -0.3893 -0.9198 0.0484 +vn -0.5737 -0.8181 0.0400 +vn 0.4164 -0.9076 0.0528 +vn 0.4230 -0.9061 0.0009 +vn -0.3929 -0.9196 -0.0005 +vn -0.5743 -0.8186 -0.0003 +vn -0.3971 -0.9165 -0.0484 +vn -0.5785 -0.8147 -0.0398 +vn 0.4097 -0.9108 -0.0511 +vn 0.3730 -0.9245 -0.0780 +vn -0.4010 -0.9134 -0.0698 +vn -0.5852 -0.8088 -0.0573 +vn -0.4042 -0.9131 -0.0534 +vn -0.5925 -0.8044 -0.0437 +vn 0.3217 -0.9449 -0.0602 +vn 0.2960 -0.9552 0.0000 +vn -0.4053 -0.9142 0.0000 +vn -0.5955 -0.8033 0.0000 +vn -0.4042 -0.9131 0.0534 +vn -0.5923 -0.8045 0.0437 +vn 0.3216 -0.9449 0.0603 +vn 0.3730 -0.9245 0.0781 +vn -0.4010 -0.9134 0.0698 +vn -0.5853 -0.8088 0.0573 +vn -0.3973 -0.9164 0.0484 +vn -0.5783 -0.8149 0.0398 +vn 0.4097 -0.9108 0.0511 +vn 0.4230 -0.9061 -0.0010 +vn -0.3927 -0.9197 0.0004 +vn -0.5743 -0.8186 0.0002 +vn -0.3890 -0.9200 -0.0483 +vn -0.5739 -0.8180 -0.0399 +vn 0.4164 -0.9077 -0.0528 +vn 0.3886 -0.9176 -0.0837 +vn -0.3885 -0.9183 -0.0759 +vn -0.5778 -0.8138 -0.0624 +vn -0.9985 -0.0512 0.0179 +vn -0.9986 -0.0471 -0.0245 +vn -0.9978 -0.0629 0.0221 +vn -0.9977 -0.0588 -0.0326 +vn -0.9984 -0.0509 -0.0252 +vn -0.9990 -0.0400 -0.0174 +vn -0.9994 -0.0357 -0.0030 +vn -0.9989 -0.0456 -0.0049 +vn -0.9990 -0.0442 0.0046 +vn -0.9994 -0.0347 0.0034 +vn -0.9994 -0.0351 0.0043 +vn -0.9990 -0.0445 0.0062 +vn -0.9989 -0.0455 0.0070 +vn -0.9993 -0.0358 0.0052 +vn -0.9992 -0.0377 0.0107 +vn -0.9988 -0.0480 0.0137 +vn -0.9981 -0.0550 0.0284 +vn -0.9988 -0.0437 0.0214 +vn -0.9982 -0.0540 0.0262 +vn -0.9971 -0.0667 0.0361 +vn -0.9967 -0.0776 0.0231 +vn -0.9978 -0.0635 0.0172 +vn -0.9977 -0.0673 -0.0011 +vn -0.9966 -0.0820 -0.0017 +vn -0.9966 -0.0775 -0.0266 +vn -0.9978 -0.0638 -0.0202 +vn -0.9981 -0.0538 -0.0293 +vn -0.9970 -0.0666 -0.0400 +vn -0.9980 -0.0553 -0.0310 +vn -0.9988 -0.0441 -0.0230 +vn -0.4066 -0.9136 -0.0000 +vn -0.2493 -0.9684 -0.0000 +vn -0.2546 -0.9670 -0.0044 +vn -0.4099 -0.9121 -0.0022 +vn -0.1241 -0.9923 -0.0001 +vn -0.1308 -0.9914 -0.0095 +vn -0.1464 -0.9891 -0.0127 +vn -0.2658 -0.9640 -0.0051 +vn -0.4171 -0.9088 -0.0021 +vn -0.4166 -0.9091 0.0020 +vn -0.2648 -0.9643 0.0045 +vn -0.2539 -0.9672 0.0042 +vn -0.4098 -0.9122 0.0020 +vn -0.1452 -0.9893 0.0116 +vn -0.1298 -0.9915 0.0091 +vn -0.4235 -0.9059 0.0000 +vn -0.2800 -0.9600 -0.0000 +vn -0.2759 -0.9612 0.0026 +vn -0.4217 -0.9067 0.0008 +vn -0.1684 -0.9857 0.0000 +vn -0.1613 -0.9869 0.0077 +vn -0.4165 -0.9091 -0.0020 +vn -0.2652 -0.9642 -0.0046 +vn -0.2757 -0.9612 -0.0026 +vn -0.4218 -0.9067 -0.0008 +vn -0.1452 -0.9893 -0.0116 +vn -0.1613 -0.9869 -0.0078 +vn -0.2539 -0.9672 -0.0042 +vn -0.4098 -0.9122 -0.0020 +vn -0.1241 -0.9923 0.0000 +vn -0.1298 -0.9915 -0.0092 +vn -0.4175 -0.9087 0.0022 +vn -0.2658 -0.9640 0.0052 +vn -0.2546 -0.9670 0.0043 +vn -0.4101 -0.9121 0.0021 +vn -0.1463 -0.9892 0.0127 +vn -0.1310 -0.9913 0.0094 +vn -0.4229 -0.9062 -0.0070 +vn -0.2830 -0.9591 -0.0055 +vn -0.2766 -0.9610 0.0036 +vn -0.4221 -0.9065 0.0011 +vn -0.1750 -0.9846 0.0023 +vn -0.1632 -0.9865 0.0120 +vn 0.3116 -0.0226 0.9499 +vn 0.3250 -0.0048 0.9457 +vn 0.8229 -0.0160 0.5680 +vn 0.8085 -0.0581 0.5856 +vn 0.3290 0.0418 0.9434 +vn 0.8354 0.0590 0.5465 +vn 0.8228 -0.0160 0.5680 +vn 0.8354 0.0590 0.5464 +vn 0.9952 0.0663 0.0715 +vn 0.9959 -0.0225 0.0872 +vn 0.9929 -0.0708 0.0958 +vn 0.2095 0.1130 -0.9713 +vn 0.2962 0.1104 -0.9487 +vn 0.7225 0.3494 -0.5966 +vn 0.2169 0.6234 -0.7512 +vn 0.8495 0.5159 -0.1105 +vn 0.2169 0.6235 -0.7512 +vn 0.0367 0.9959 -0.0824 +vn 0.1895 -0.0564 -0.9803 +vn 0.1941 -0.0606 -0.9791 +vn 0.2048 -0.0607 -0.9769 +vn 0.1910 -0.0566 -0.9800 +vn 0.2828 -0.1546 -0.9466 +vn 0.3616 -0.1210 -0.9244 +vn 0.1713 -0.0470 -0.9841 +vn 0.1558 -0.0467 -0.9867 +vn 0.0005 -0.0000 1.0000 +vn 0.0004 -0.0007 1.0000 +vn 0.1137 -0.0031 0.9935 +vn 0.1143 -0.0084 0.9934 +vn -0.0003 -0.0023 1.0000 +vn 0.1107 0.0009 0.9939 +vn 0.0009 0.0003 1.0000 +vn 0.0004 0.0003 1.0000 +vn 0.1141 -0.0150 0.9934 +vn 0.1101 -0.0225 0.9937 +vn 0.3305 -0.0465 0.9427 +vn 0.3323 -0.1053 0.9373 +vn 0.0006 -0.0038 1.0000 +vn 0.0016 0.0002 1.0000 +vn 0.1029 -0.0260 0.9943 +vn 0.0981 -0.0304 0.9947 +vn 0.1714 -0.0470 0.9841 +vn 0.1553 -0.0465 0.9868 +vn -0.4231 -0.9061 0.0072 +vn -0.2829 -0.9591 0.0052 +vn -0.2604 -0.9567 0.1297 +vn -0.3945 -0.9099 0.1283 +vn -0.1752 -0.9845 -0.0022 +vn -0.1595 -0.9786 0.1298 +vn -0.0232 -0.7329 0.6800 +vn -0.0874 -0.7400 0.6669 +vn -0.1763 -0.7117 0.6800 +vn -0.0029 -0.0049 1.0000 +vn 0.1075 0.0020 0.9942 +vn 0.0206 -0.0039 0.9998 +vn 0.1183 0.0008 0.9930 +vn 0.1700 0.0010 0.9855 +vn 0.1749 0.0063 0.9846 +vn 0.2056 0.0196 -0.9784 +vn 0.2099 0.0187 -0.9775 +vn 0.2011 0.0088 -0.9795 +vn 0.2061 0.0097 -0.9785 +vn 0.1655 0.0068 -0.9862 +vn 0.1726 0.0118 -0.9849 +vn -0.1117 -0.0544 0.9923 +vn -0.1633 -0.0447 0.9856 +vn -0.0688 -0.0145 0.9975 +vn -0.2176 -0.0599 0.9742 +vn -0.2080 -0.0485 0.9769 +vn -0.1769 -0.0344 0.9836 +vn -0.1740 -0.0298 0.9843 +vn -0.1538 -0.0114 0.9880 +vn -0.0383 0.0102 0.9992 +vn -0.0389 0.0091 0.9992 +vn 0.5088 -0.0922 0.8559 +vn -0.0388 0.0079 0.9992 +vn -0.1433 0.0272 0.9893 +vn -0.1390 0.0322 0.9898 +vn -0.1380 0.0313 0.9899 +vn -0.0387 0.0052 0.9992 +vn -0.0396 0.0026 0.9992 +vn -0.1442 0.0110 0.9895 +vn -0.1444 0.0193 0.9893 +vn 0.5342 -0.0249 0.8450 +vn -0.0489 -0.0021 0.9988 +vn -0.1457 0.0022 0.9893 +vn -0.3784 -0.9256 0.0003 +vn -0.5421 -0.8403 0.0003 +vn -0.5440 -0.8384 -0.0341 +vn -0.3833 -0.9232 -0.0271 +vn -0.5517 -0.8324 -0.0527 +vn -0.3958 -0.9174 -0.0418 +vn -0.3974 -0.9169 0.0380 +vn -0.5564 -0.8295 0.0488 +vn -0.5468 -0.8366 0.0340 +vn -0.3840 -0.9229 0.0271 +vn -0.4181 -0.9084 0.0000 +vn -0.5711 -0.8209 0.0000 +vn -0.5664 -0.8233 0.0368 +vn -0.4117 -0.9109 0.0284 +vn -0.3972 -0.9169 -0.0382 +vn -0.5561 -0.8297 -0.0487 +vn -0.5667 -0.8231 -0.0364 +vn -0.4117 -0.9109 -0.0283 +vn -0.3784 -0.9256 -0.0004 +vn -0.5421 -0.8403 -0.0003 +vn -0.5468 -0.8366 -0.0340 +vn -0.3840 -0.9229 -0.0271 +vn -0.3959 -0.9174 0.0414 +vn -0.5517 -0.8324 0.0529 +vn -0.5438 -0.8385 0.0338 +vn -0.3833 -0.9232 0.0269 +vn -0.4228 -0.9056 0.0337 +vn -0.5710 -0.8197 0.0466 +vn -0.5614 -0.8255 0.0586 +vn -0.4107 -0.9107 0.0452 +vn 0.0005 -0.0000 -1.0000 +vn 0.0005 -0.0007 -1.0000 +vn -0.0970 0.0011 -0.9953 +vn -0.0964 0.0073 -0.9953 +vn -0.0005 -0.0024 -1.0000 +vn -0.1009 -0.0072 -0.9949 +vn 0.0008 0.0003 -1.0000 +vn 0.0005 0.0003 -1.0000 +vn -0.0964 0.0133 -0.9953 +vn -0.0955 0.0190 -0.9953 +vn 0.0006 -0.0042 -1.0000 +vn 0.0014 0.0003 -1.0000 +vn -0.0925 0.0223 -0.9955 +vn -0.0923 0.0201 -0.9955 +vn -0.4230 -0.9055 -0.0335 +vn -0.5711 -0.8196 -0.0465 +vn -0.5847 -0.8034 0.1127 +vn -0.4280 -0.8957 0.1209 +vn -0.4626 -0.5377 0.7049 +vn -0.2973 -0.6216 0.7248 +vn -0.0026 -0.0046 -1.0000 +vn -0.1098 -0.0171 -0.9938 +vn 0.0154 -0.0038 -0.9999 +vn -0.1006 -0.0182 -0.9948 +vn -0.3001 -0.6275 -0.7185 +vn -0.4657 -0.5430 -0.6988 +vn -0.5846 -0.8040 -0.1087 +vn -0.4280 -0.8962 -0.1169 +vn -0.5073 -0.5209 -0.6865 +vn -0.6093 -0.7862 -0.1033 +vn -0.1801 -0.7162 -0.6742 +vn -0.0900 -0.7450 -0.6610 +vn -0.2611 -0.9570 -0.1263 +vn -0.3952 -0.9100 -0.1250 +vn -0.0252 -0.7384 -0.6739 +vn -0.1600 -0.9790 -0.1262 +vn -0.3575 -0.6079 -0.7090 +vn -0.4277 -0.8991 -0.0929 +vn 0.2500 -0.6962 -0.6730 +vn 0.3886 -0.9072 -0.1612 +vn 0.5290 -0.1124 -0.8411 +vn 0.8948 -0.1954 -0.4014 +vn 0.9266 -0.2215 -0.3040 +vn 0.8686 -0.1596 -0.4691 +vn 0.7422 -0.1393 -0.6555 +vn 0.8677 -0.1150 -0.4836 +vn 0.8787 -0.0670 -0.4726 +vn 0.7462 -0.0537 -0.6636 +vn 0.7331 -0.0975 -0.6731 +vn 0.9314 -0.0286 -0.3630 +vn 0.1228 -0.0436 -0.9915 +vn 0.9474 -0.0171 -0.3197 +vn 0.9770 0.1308 -0.1682 +vn 0.8337 0.0153 -0.5520 +vn -0.9996 0.0287 0.0012 +vn -0.9971 0.0763 0.0009 +vn -0.9999 -0.0110 0.0000 +vn -0.9912 0.1324 0.0003 +vn -0.9812 0.1927 0.0001 +vn -0.9992 -0.0396 -0.0017 +vn -0.9987 -0.0502 -0.0006 +vn -0.5615 -0.8254 -0.0585 +vn -0.4108 -0.9106 -0.0450 +vn -0.5842 -0.8086 -0.0697 +vn -0.2767 -0.9609 -0.0038 +vn -0.4220 -0.9066 -0.0011 +vn -0.1633 -0.9865 -0.0120 +vn -0.8787 0.0565 0.4740 +vn -0.6478 -0.0266 0.7614 +vn -0.9715 -0.0475 0.2324 +vn -0.9895 -0.0128 0.1439 +vn -0.7232 -0.0452 0.6892 +vn -0.9718 -0.0602 0.2280 +vn -0.6873 0.1811 0.7034 +vn -0.6758 0.1636 0.7187 +vn -0.9595 0.2373 0.1522 +vn -0.9563 0.2540 0.1451 +vn -0.9736 0.1872 0.1305 +vn -0.9802 0.1130 0.1629 +vn -0.9896 0.1261 0.0693 +vn -0.9952 0.0716 0.0669 +vn -0.9969 0.0721 0.0310 +vn -0.9907 0.0360 0.1312 +vn -0.9975 0.0270 0.0657 +vn 0.9249 -0.2306 -0.3024 +vn 0.9389 -0.1813 -0.2925 +vn 0.9664 -0.1838 -0.1799 +vn 0.9552 -0.2261 -0.1911 +vn 0.9569 -0.0033 0.2903 +vn 0.9745 0.1283 0.1840 +vn 0.9540 -0.0718 0.2910 +vn 0.9810 -0.0756 0.1787 +vn 0.9831 -0.0167 0.1823 +vn 0.9840 0.0597 0.1677 +vn 0.9483 -0.1275 0.2905 +vn 0.9752 -0.1309 0.1786 +vn -0.3911 -0.9164 -0.0855 +vn 0.3697 -0.9251 -0.0866 +vn 0.9091 -0.4128 -0.0554 +vn 0.8923 -0.4498 -0.0377 +vn 0.3697 -0.9251 -0.0867 +vn 0.9353 -0.3532 -0.0204 +vn 0.9102 -0.4138 0.0153 +vn 0.3870 -0.9202 -0.0582 +vn -0.7574 -0.3291 0.5639 +vn -0.7155 0.0645 0.6956 +vn -0.9791 0.1543 0.1321 +vn -0.9190 -0.3750 0.1220 +vn -0.9310 -0.3650 0.0077 +vn -0.9306 -0.3661 0.0003 +vn -0.9311 -0.3648 0.0001 +vn -0.9888 0.1491 -0.0076 +vn -0.9310 -0.3650 -0.0076 +vn 0.2500 -0.6961 -0.6730 +vn 0.5273 -0.2442 -0.8138 +vn 0.9120 -0.3520 -0.2105 +vn 0.9103 -0.4138 -0.0151 +vn 0.3870 -0.9202 0.0583 +vn -0.3001 -0.6274 -0.7185 +vn -0.0501 -0.1152 -0.9921 +vn -0.1590 -0.0794 -0.9841 +vn -0.2062 -0.0620 -0.9765 +vn 0.2453 -0.6903 0.6807 +vn 0.5202 -0.2399 0.8196 +vn -0.1020 -0.0742 0.9920 +vn -0.3587 -0.6022 0.7133 +vn -0.2039 -0.0584 0.9773 +vn -0.2972 -0.6215 0.7248 +vn -0.0479 -0.1109 0.9927 +vn 0.0670 -0.1546 0.9857 +vn -0.0966 -0.6987 0.7088 +vn 0.1287 -0.1859 0.9741 +vn 0.1239 -0.2014 -0.9717 +vn 0.1427 -0.2071 -0.9679 +vn -0.0900 -0.7450 -0.6609 +vn 0.1274 -0.1908 -0.9733 +vn -0.0251 -0.7384 -0.6739 +vn 0.9339 -0.3574 -0.0001 +vn 0.9291 -0.3686 -0.0284 +vn 0.4164 -0.9076 -0.0527 +vn 0.3730 -0.9245 0.0780 +vn 0.9056 -0.4208 0.0538 +vn 0.9286 -0.3701 0.0279 +vn 0.4097 -0.9108 0.0512 +vn 0.8005 -0.5993 -0.0000 +vn 0.8448 -0.5330 0.0482 +vn 0.3217 -0.9449 0.0603 +vn 0.9056 -0.4208 -0.0538 +vn 0.8448 -0.5330 -0.0482 +vn 0.3216 -0.9449 -0.0603 +vn 0.4230 -0.9061 0.0010 +vn 0.9339 -0.3574 0.0001 +vn 0.9286 -0.3701 -0.0279 +vn 0.9091 -0.4127 0.0555 +vn 0.9292 -0.3686 0.0284 +vn 0.4164 -0.9077 0.0527 +vn 0.8923 -0.4499 0.0378 +vn 0.9354 -0.3530 0.0204 +vn -0.9294 -0.3692 -0.0000 +vn -0.9298 -0.3681 0.0003 +vn -0.9305 -0.3663 -0.0003 +vn -0.9297 -0.3683 -0.0003 +vn -0.9312 -0.3645 -0.0000 +vn -0.9889 0.1486 -0.0000 +vn -0.9311 -0.3649 -0.0001 +vn -0.9305 -0.3663 0.0002 +vn -0.9310 -0.3649 0.0001 +vn -0.9293 -0.3692 -0.0000 +vn -0.9297 -0.3683 0.0003 +vn -0.9306 -0.3661 -0.0003 +vn -0.9298 -0.3681 -0.0003 +vn -0.9311 -0.3648 -0.0001 +vn -0.9796 0.1544 -0.1288 +vn -0.9194 -0.3748 -0.1190 +vn -0.7236 0.0648 -0.6872 +vn -0.7644 -0.3298 -0.5540 +vn -0.0988 -0.0790 -0.9920 +vn 0.2499 -0.6962 -0.6730 +vn 0.9107 -0.3518 0.2163 +vn 0.3877 -0.9066 0.1666 +vn -0.1764 -0.7117 0.6800 +vn 0.1272 -0.1966 0.9722 +vn -0.0944 -0.1240 0.9878 +vn -0.3699 -0.6232 0.6890 +vn -0.7575 -0.3291 0.5638 +vn 0.9598 -0.0739 -0.2707 +vn 0.9603 -0.0151 -0.2787 +vn 0.9997 -0.0253 -0.0019 +vn 0.9969 -0.0783 -0.0026 +vn 0.9612 0.0597 -0.2693 +vn 0.9940 0.1094 0.0013 +vn 0.9749 0.0505 0.2167 +vn 0.9746 -0.0187 0.2231 +vn 0.9815 -0.0784 -0.1747 +vn 0.9832 -0.0168 -0.1817 +vn 0.9992 -0.0250 -0.0313 +vn 0.9963 -0.0799 -0.0321 +vn 0.9831 0.0604 -0.1731 +vn 0.9938 0.0943 -0.0586 +vn 0.9960 0.0887 -0.0076 +vn 0.9997 -0.0238 0.0008 +vn 0.9969 -0.0792 0.0025 +vn 0.9991 -0.0244 0.0336 +vn 0.9962 -0.0785 0.0371 +vn 0.9947 0.0930 0.0429 +vn 0.9551 -0.1277 -0.2672 +vn 0.9911 -0.1328 -0.0015 +vn 0.9831 -0.1828 0.0028 +vn 0.9754 -0.1338 -0.1751 +vn 0.9903 -0.1348 -0.0330 +vn 0.9822 -0.1843 -0.0355 +vn 0.9910 -0.1339 0.0019 +vn 0.9830 -0.1836 0.0011 +vn 0.9904 -0.1330 0.0367 +vn 0.9824 -0.1833 0.0374 +vn 0.9750 -0.2221 0.0095 +vn 0.9499 -0.3122 0.0169 +vn 0.9501 -0.2180 0.2233 +vn 0.9400 -0.2586 0.2225 +vn 0.9740 -0.2232 -0.0387 +vn 0.9748 -0.2229 -0.0001 +vn 0.9740 -0.2230 0.0391 +vn 0.9996 -0.0272 -0.0026 +vn 0.9970 -0.0773 -0.0024 +vn 0.9946 0.1034 0.0123 +vn 0.9616 0.0517 0.2694 +vn 0.9615 -0.0173 0.2741 +vn 0.9616 -0.0739 0.2645 +vn 0.9915 -0.1299 -0.0020 +vn 0.9836 -0.1803 -0.0040 +vn 0.9567 -0.1257 0.2625 +vn 0.9501 -0.1749 0.2583 +vn 0.9404 -0.2584 -0.2211 +vn 0.9506 -0.2169 -0.2222 +vn 0.9752 -0.2211 -0.0097 +vn 0.9500 -0.3119 -0.0169 +vn 0.9421 -0.2186 0.2541 +vn 0.9334 -0.2648 0.2423 +vn 0.7332 -0.0976 -0.6729 +vn 0.7323 -0.0977 -0.6739 +vn 0.7350 -0.0528 -0.6760 +vn 0.7322 -0.0977 -0.6740 +vn 0.7351 -0.0528 -0.6759 +vn 0.9427 -0.0077 0.3336 +vn 0.9659 0.1160 0.2314 +vn 0.8338 0.0153 -0.5519 +vn 0.7476 0.0157 -0.6639 +vn 0.8724 0.1527 -0.4644 +vn 0.7475 0.0157 -0.6640 +vn 0.9192 -0.2162 -0.3291 +vn 0.9177 -0.3102 -0.2481 +vn 0.9654 0.2470 -0.0839 +vn 0.9486 0.2812 0.1450 +vn 0.9718 0.1623 0.1712 +vn 0.9718 0.1623 0.1713 +vn 0.9787 0.1482 -0.1424 +vn 0.9786 0.1483 -0.1423 +vn 0.8307 0.0122 0.5566 +vn 0.7464 0.0125 0.6654 +vn 0.8643 0.1442 0.4820 +vn 0.7341 -0.0532 0.6770 +vn 0.7463 0.0125 0.6654 +vn 0.8643 0.1442 0.4819 +vn 0.9486 -0.1309 -0.2880 +vn 0.9548 -0.0752 -0.2877 +vn 0.7340 -0.1363 0.6653 +vn 0.7535 -0.1942 0.6281 +vn 0.7322 -0.1371 0.6671 +vn 0.8461 -0.3200 0.4263 +vn 0.8460 -0.3201 0.4263 +vn 0.7322 -0.1371 0.6672 +vn 0.9569 -0.0039 -0.2905 +vn 0.9701 0.1324 -0.2034 +vn 0.9019 -0.4317 -0.0137 +vn 0.9175 -0.3101 0.2489 +vn 0.7248 -0.0951 0.6824 +vn 0.7306 -0.0961 0.6760 +vn 0.9186 -0.2171 0.3301 +vn 0.9520 0.2883 -0.1029 +vn 0.9597 0.2563 0.1148 +vn 0.9597 0.2563 0.1149 +vn 0.9747 0.1567 0.1596 +vn 0.9747 0.1567 0.1595 +vn 0.9734 0.1710 -0.1526 +vn 0.9734 0.1710 -0.1527 +vn 0.9018 -0.4319 0.0136 +vn -0.1565 -0.0757 0.9848 +vn -0.0922 0.0203 0.9955 +vn 0.0662 -0.1592 -0.9850 +vn -0.0987 -0.7046 -0.7027 +vn 0.0982 -0.0308 -0.9947 +vn -0.2037 -0.9787 -0.0263 +vn -0.2219 -0.9747 -0.0275 +vn -0.2355 -0.9717 -0.0168 +vn -0.2275 -0.9659 -0.1237 +vn -0.2354 -0.9718 0.0168 +vn 0.1053 0.0044 -0.9944 +vn 0.1102 0.0023 -0.9939 +vn 0.1133 0.0038 -0.9935 +vn -0.2272 -0.9655 0.1275 +vn -0.0966 -0.6987 0.7089 +vn 0.1030 -0.0260 -0.9943 +vn 0.1100 -0.0226 -0.9937 +vn 0.3812 -0.0550 -0.9228 +vn 0.1137 -0.0153 -0.9934 +vn 0.1145 -0.0087 -0.9934 +vn 0.1137 -0.0030 -0.9935 +vn -0.2218 -0.9747 0.0275 +vn -0.2037 -0.9787 0.0262 +vn -0.1878 -0.9821 0.0179 +vn -0.1807 -0.9835 -0.0001 +vn -0.1865 -0.9823 -0.0178 +vn -0.2026 -0.9790 -0.0243 +vn -0.2198 -0.9754 -0.0175 +vn -0.2273 -0.9738 -0.0000 +vn -0.2199 -0.9754 0.0175 +vn -0.2026 -0.9789 0.0243 +vn -0.1866 -0.9823 0.0177 +vn -0.1807 -0.9835 0.0000 +vn -0.1878 -0.9821 -0.0179 +vn -0.1126 -0.0166 0.9935 +vn -0.1016 -0.0066 0.9948 +vn -0.0989 -0.0170 0.9950 +vn -0.0923 0.0222 0.9955 +vn -0.0955 0.0186 0.9953 +vn -0.0965 0.0131 0.9952 +vn -0.0963 0.0074 0.9953 +vn -0.0970 0.0016 0.9953 +vn 0.9950 -0.0713 0.0701 +vn 0.9974 -0.0238 0.0687 +vn 0.9974 -0.0242 0.0677 +vn 0.9950 -0.0717 0.0689 +vn 0.9955 0.0667 0.0670 +vn 0.9955 0.0675 0.0666 +vn 0.9955 0.0709 0.0629 +vn 0.9979 -0.0236 0.0600 +vn 0.9956 -0.0716 0.0597 +vn -0.9907 0.1110 -0.0790 +vn -0.9955 0.0538 -0.0785 +vn -0.9850 0.0544 -0.1638 +vn -0.9796 0.1049 -0.1714 +vn -0.9942 0.0725 -0.0799 +vn -0.9844 0.0771 -0.1583 +vn -0.6737 0.0911 -0.7334 +vn -0.6876 0.0736 -0.7223 +vn -0.6987 0.2360 -0.6754 +vn 0.9924 -0.0734 -0.0988 +vn 0.9878 -0.1217 -0.0972 +vn 0.9892 -0.1216 -0.0819 +vn 0.9938 -0.0733 -0.0836 +vn 0.9723 -0.2142 -0.0933 +vn 0.9736 -0.2147 -0.0781 +vn 0.9764 -0.2149 -0.0197 +vn 0.9924 -0.1211 -0.0229 +vn 0.9970 -0.0729 -0.0246 +vn -0.0394 -0.9992 -0.0044 +vn 0.7854 -0.6162 0.0585 +vn 0.7829 -0.6194 0.0576 +vn -0.0316 -0.9995 -0.0093 +vn 0.9740 -0.2150 0.0712 +vn 0.9738 -0.2165 0.0700 +vn 0.9733 -0.2204 0.0639 +vn 0.7757 -0.6288 0.0550 +vn 0.0362 -0.9989 -0.0298 +vn -0.7435 0.4230 0.5179 +vn 0.2493 0.5894 0.7684 +vn -0.9895 0.0817 0.1191 +vn -0.7435 0.4231 0.5179 +vn -0.9931 0.1083 -0.0452 +vn -0.8499 0.5265 -0.0222 +vn 0.0237 0.9968 0.0767 +vn -0.9979 0.0500 -0.0408 +vn -0.9972 0.0742 -0.0084 +vn -0.9882 0.0858 -0.1271 +vn -0.9909 0.1164 0.0674 +vn -0.9956 0.0551 0.0761 +vn -0.9943 0.0738 0.0775 +vn 0.8225 -0.1066 0.5586 +vn 0.8277 -0.1893 0.5283 +vn 0.9889 -0.1212 0.0858 +vn 0.8276 -0.1893 0.5284 +vn 0.9746 -0.2134 0.0686 +vn -0.9930 0.0971 0.0669 +vn -0.9973 0.0712 0.0195 +vn -0.9829 0.0608 0.1740 +vn -0.9987 0.0290 -0.0415 +vn -0.9945 0.0909 -0.0515 +vn -0.9960 0.0711 -0.0539 +vn 0.8540 -0.1132 -0.5078 +vn 0.8527 -0.1934 -0.4853 +vn 0.8540 -0.1132 -0.5077 +vn 0.9723 -0.2158 -0.0902 +vn 0.9871 -0.1233 -0.1023 +vn -0.9935 0.0994 -0.0551 +vn -0.9930 0.0927 0.0738 +vn 0.2834 -0.1411 0.9486 +vn 0.6766 -0.4165 0.6072 +vn 0.2353 -0.5975 0.7666 +vn 0.6766 -0.4165 0.6073 +vn 0.8139 -0.5728 0.0969 +vn 0.0322 -0.9927 0.1160 +vn -0.9978 0.0475 0.0455 +vn -0.9973 0.0519 -0.0518 +vn 0.9971 -0.0700 0.0306 +vn 0.9991 -0.0197 0.0388 +vn 0.9748 -0.0279 0.2215 +vn 0.9717 -0.0801 0.2222 +vn 0.9919 0.0944 0.0848 +vn 0.9070 0.0879 0.4119 +vn 0.6932 -0.0065 0.7207 +vn 0.6944 -0.0497 0.7179 +vn 0.6938 -0.0917 0.7143 +vn -0.0101 0.0075 0.9999 +vn -0.0018 0.0166 0.9999 +vn -0.0011 0.0096 1.0000 +vn -0.0081 0.0012 1.0000 +vn 0.0139 0.1012 0.9948 +vn 0.0138 0.0967 0.9952 +vn -0.0035 0.0932 0.9956 +vn -0.0078 0.0041 1.0000 +vn -0.0106 -0.0036 0.9999 +vn 0.9962 -0.0718 0.0488 +vn 0.9915 -0.1204 0.0501 +vn 0.9802 -0.1222 -0.1559 +vn 0.9830 -0.0732 -0.1685 +vn 0.9741 -0.2241 0.0290 +vn 0.9120 -0.2166 -0.3483 +vn 0.7182 -0.1296 -0.6836 +vn 0.7206 -0.0961 -0.6867 +vn 0.7215 -0.0603 -0.6898 +vn 0.1679 -0.9686 0.1835 +vn 0.7033 -0.6908 0.1678 +vn 0.5718 -0.5438 0.6142 +vn 0.1092 -0.6978 0.7079 +vn 0.9667 -0.2456 0.0715 +vn 0.8828 -0.2682 0.3856 +vn 0.5718 -0.5439 0.6142 +vn 0.8828 -0.2682 0.3857 +vn 0.6824 -0.1824 0.7079 +vn 0.3517 -0.2475 0.9028 +vn 0.1093 -0.6978 0.7079 +vn 0.0338 -0.2188 0.9752 +vn -0.9908 0.0734 0.1141 +vn -0.9919 0.0559 0.1143 +vn -0.9596 0.0565 0.2755 +vn -0.9558 0.0727 0.2848 +vn -0.9864 0.1212 0.1108 +vn -0.9593 0.1221 0.2547 +vn -0.6126 0.2185 0.7596 +vn -0.6067 0.0474 0.7935 +vn -0.6006 0.0525 0.7978 +vn 0.0200 0.9998 -0.0053 +vn 0.8395 0.5361 -0.0886 +vn 0.8383 0.5399 -0.0758 +vn 0.0434 0.9990 0.0140 +vn 0.9923 0.0722 -0.1009 +vn 0.9936 0.0731 -0.0858 +vn 0.9969 0.0743 -0.0268 +vn 0.8372 0.5462 -0.0259 +vn 0.1178 0.9912 0.0610 +vn -0.0269 0.9995 -0.0188 +vn -0.8447 0.5303 -0.0728 +vn -0.8200 0.5598 -0.1195 +vn -0.0155 0.9997 -0.0198 +vn -0.6651 0.6894 -0.2870 +vn 0.0551 0.9981 -0.0267 +vn 0.9901 -0.1207 0.0710 +vn 0.9902 -0.1212 0.0697 +vn 0.9907 -0.1216 0.0608 +vn -0.9933 0.0252 0.1130 +vn -0.9894 0.0912 0.1133 +vn -0.9571 0.0890 0.2757 +vn -0.9656 0.0234 0.2589 +vn -0.6096 0.0585 0.7906 +vn -0.6421 -0.1107 0.7586 +vn 0.9947 -0.0246 -0.0999 +vn 0.9961 -0.0244 -0.0847 +vn 0.9994 -0.0240 -0.0257 +vn -0.9924 0.0919 -0.0817 +vn -0.9797 0.1014 -0.1728 +vn -0.9961 0.0285 -0.0836 +vn -0.9816 0.0472 -0.1851 +vn -0.7053 -0.0718 -0.7053 +vn -0.6723 0.1091 -0.7322 +vn -0.0346 -0.9988 0.0347 +vn -0.8682 -0.4835 0.1114 +vn -0.8328 -0.5160 0.2007 +vn -0.0075 -0.9985 0.0541 +vn -0.6508 -0.6307 0.4228 +vn -0.6507 -0.6307 0.4228 +vn 0.0740 -0.9924 0.0986 +vn 0.0209 -0.0945 0.9953 +vn 0.0016 -0.0924 0.9957 +vn -0.0070 -0.2077 0.9782 +vn 0.0220 -0.0637 0.9977 +vn 0.0029 -0.0625 0.9980 +vn 0.0055 -0.0626 0.9980 +vn 0.0031 -0.0925 0.9957 +vn -0.0100 -0.2073 0.9782 +vn 0.0218 -0.0346 0.9992 +vn 0.0032 -0.0343 0.9994 +vn 0.0374 0.0819 0.9959 +vn 0.0029 0.0738 0.9973 +vn 0.0074 0.0752 0.9971 +vn 0.0068 -0.0342 0.9994 +vn 0.1048 -0.0191 -0.9943 +vn 0.1049 0.0033 -0.9945 +vn 0.2517 -0.0023 -0.9678 +vn 0.2593 -0.0301 -0.9653 +vn 0.1208 0.0847 -0.9891 +vn 0.4192 0.0803 -0.9044 +vn 0.7247 0.0098 -0.6890 +vn 0.7233 -0.0243 -0.6901 +vn 0.7214 -0.0603 -0.6899 +vn 0.1200 -0.1244 -0.9850 +vn 0.1046 -0.0415 -0.9936 +vn 0.2508 -0.0564 -0.9664 +vn 0.4137 -0.1585 -0.8965 +vn 0.7182 -0.1297 -0.6836 +vn -0.1442 -0.9884 -0.0468 +vn -0.0872 -0.6831 0.7251 +vn -0.0954 -0.6892 0.7182 +vn -0.1434 -0.9886 -0.0455 +vn -0.0872 -0.6830 0.7252 +vn -0.0139 -0.2103 0.9775 +vn -0.0226 -0.2169 0.9759 +vn -0.0399 -0.2327 0.9717 +vn -0.1107 -0.6988 0.7067 +vn -0.1106 -0.6988 0.7068 +vn -0.1443 -0.9884 -0.0478 +vn 0.2807 0.9229 -0.2637 +vn 0.8057 0.5720 -0.1537 +vn 0.7035 0.3291 -0.6299 +vn 0.2456 0.5405 -0.8047 +vn 0.9961 0.0856 0.0227 +vn 0.9299 0.0778 -0.3596 +vn 0.7034 0.3290 -0.6301 +vn 0.9300 0.0778 -0.3593 +vn 0.2043 0.9460 0.2519 +vn -0.0538 0.9819 0.1814 +vn -0.0035 0.5859 0.8104 +vn 0.1349 0.6043 0.7852 +vn -0.0496 0.9961 0.0724 +vn -0.0000 0.5959 0.8031 +vn -0.0000 0.5959 0.8030 +vn 0.1349 0.6044 0.7852 +vn 0.9918 -0.1232 0.0347 +vn 0.9673 -0.1340 0.2155 +vn 0.6898 -0.1356 0.7112 +vn 0.0114 -0.0661 0.9977 +vn 0.0182 -0.0388 0.9991 +vn 0.0180 -0.0454 0.9988 +vn 0.0101 -0.0718 0.9974 +vn 0.0130 0.0793 0.9968 +vn 0.0152 0.0764 0.9970 +vn 0.0147 0.0767 0.9969 +vn 0.0104 -0.0501 0.9987 +vn 0.0026 -0.0810 0.9967 +vn 0.9986 -0.0227 0.0478 +vn 0.9870 -0.0237 -0.1589 +vn 0.7232 -0.0243 -0.6902 +vn 0.7248 0.0098 -0.6889 +vn -0.0401 0.1797 -0.9829 +vn -0.0222 0.0812 -0.9964 +vn -0.0168 0.0906 -0.9957 +vn -0.0300 0.1977 -0.9798 +vn -0.0135 0.0665 -0.9977 +vn -0.0093 0.0723 -0.9973 +vn -0.0036 0.0813 -0.9967 +vn -0.0080 0.0981 -0.9951 +vn -0.0071 0.2134 -0.9769 +vn 0.2421 -0.9424 -0.2307 +vn -0.0479 -0.9761 -0.2121 +vn 0.0928 -0.5539 -0.8274 +vn 0.2308 -0.5794 -0.7817 +vn -0.1100 -0.9881 -0.1074 +vn 0.0925 -0.5666 -0.8188 +vn 0.0928 -0.5538 -0.8274 +vn 0.0925 -0.5667 -0.8187 +vn 0.1820 -0.1308 -0.9746 +vn 0.1380 -0.1211 -0.9830 +vn 0.0196 0.9997 0.0122 +vn 0.0174 0.6063 -0.7951 +vn -0.0357 0.6147 -0.7880 +vn -0.0774 0.9969 0.0112 +vn 0.0098 0.1299 -0.9915 +vn 0.0046 0.1362 -0.9907 +vn -0.0127 0.1383 -0.9903 +vn -0.0679 0.6168 -0.7842 +vn -0.0680 0.6167 -0.7842 +vn -0.1210 0.9926 0.0082 +vn -0.1277 -0.7118 0.6907 +vn -0.1450 -0.9881 -0.0521 +vn -0.0616 -0.2586 0.9640 +vn -0.0978 -0.2822 0.9544 +vn -0.1496 -0.7187 0.6790 +vn -0.1447 -0.9878 -0.0568 +vn 0.0097 0.0322 -0.9994 +vn 0.0098 0.0346 -0.9994 +vn 0.0108 0.0037 -0.9999 +vn 0.0090 0.0049 -0.9999 +vn -0.0085 0.0048 -1.0000 +vn -0.0060 0.0333 -0.9994 +vn 0.0036 0.0636 -0.9980 +vn 0.0144 0.0832 -0.9964 +vn 0.0026 0.0911 -0.9958 +vn -0.0037 -0.0575 -0.9983 +vn 0.0142 -0.0370 -0.9992 +vn 0.0269 -0.0088 -0.9996 +vn 0.0203 0.1041 -0.9944 +vn 0.0052 0.0989 -0.9951 +vn 0.0409 0.1070 -0.9934 +vn 0.0389 0.0158 -0.9991 +vn 0.0112 0.0254 -0.9996 +vn 0.0160 0.1199 -0.9927 +vn 0.0450 -0.0096 -0.9989 +vn 0.0155 -0.0020 -0.9999 +vn -0.1387 -0.9903 0.0057 +vn -0.1040 -0.5634 0.8196 +vn -0.0952 -0.5795 0.8094 +vn -0.1379 -0.9904 0.0098 +vn -0.0356 -0.0881 0.9955 +vn -0.0295 -0.0983 0.9947 +vn -0.0274 -0.1062 0.9940 +vn -0.0904 -0.5930 0.8001 +vn -0.1326 -0.9911 0.0085 +vn -0.0179 -0.0021 0.9998 +vn -0.0141 -0.0075 0.9999 +vn -0.0138 -0.0117 0.9998 +vn 0.1456 0.9893 -0.0012 +vn 0.0965 0.5696 -0.8162 +vn 0.0665 0.5906 -0.8042 +vn 0.1117 0.9937 0.0083 +vn 0.0665 0.5907 -0.8042 +vn 0.0468 -0.0357 -0.9983 +vn 0.0171 -0.0306 -0.9994 +vn 0.0335 -0.1288 -0.9911 +vn 0.0050 -0.1304 -0.9915 +vn -0.0025 -0.1321 -0.9912 +vn 0.0099 -0.0265 -0.9996 +vn -0.0119 0.0508 -0.9986 +vn -0.0057 0.0533 -0.9986 +vn -0.0276 -0.0611 -0.9977 +vn -0.0185 -0.0633 -0.9978 +vn -0.1150 0.9874 -0.1089 +vn -0.0866 0.5994 -0.7957 +vn -0.0735 0.6232 -0.7786 +vn -0.0899 0.9937 -0.0667 +vn -0.0866 0.5995 -0.7957 +vn -0.0018 0.6816 -0.7318 +vn 0.0170 0.9996 0.0220 +vn 0.0041 -0.0941 0.9956 +vn -0.0006 -0.0989 0.9951 +vn -0.0117 -0.1110 0.9937 +vn -0.4136 -0.9104 0.0066 +vn -0.2540 -0.5959 0.7618 +vn -0.7025 -0.2760 0.6560 +vn -0.8730 -0.4867 0.0329 +vn -0.2539 -0.5960 0.7618 +vn -0.0407 -0.1112 0.9930 +vn -0.4299 -0.0478 0.9016 +vn -0.7025 -0.2761 0.6559 +vn -0.4300 -0.0478 0.9016 +vn -0.7429 0.0613 0.6666 +vn -0.9392 0.0229 0.3425 +vn -0.8730 -0.4866 0.0329 +vn -0.9996 0.0256 -0.0085 +vn -0.4827 -0.0949 0.8706 +vn -0.4707 -0.0380 0.8815 +vn -0.6836 -0.0316 0.7291 +vn -0.6933 -0.0815 0.7160 +vn -0.4452 0.0769 0.8921 +vn -0.7425 0.0544 0.6677 +vn -0.6835 -0.0316 0.7292 +vn -0.7422 0.0544 0.6679 +vn -0.8797 0.0093 0.4755 +vn -0.8809 -0.0204 0.4728 +vn -0.6934 -0.0815 0.7159 +vn -0.8814 -0.0575 0.4689 +vn -0.0351 -0.0002 0.9994 +vn -0.0300 0.0086 0.9995 +vn -0.2416 0.0148 0.9703 +vn -0.2540 0.0157 0.9671 +vn -0.0306 0.1100 0.9935 +vn -0.4181 0.1049 0.9023 +vn -0.7436 0.0419 0.6673 +vn -0.7462 0.0351 0.6648 +vn -0.7468 0.0519 0.6630 +vn -0.4727 -0.2709 0.8385 +vn -0.4829 -0.1545 0.8620 +vn -0.6840 -0.1354 0.7168 +vn -0.7393 -0.2155 0.6380 +vn -0.6839 -0.1354 0.7169 +vn -0.8801 -0.0968 0.4649 +vn -0.7392 -0.2156 0.6380 +vn -0.8782 -0.1300 0.4604 +vn 0.0004 0.0983 -0.9952 +vn 0.0165 0.2111 -0.9773 +vn 0.0039 0.0935 -0.9956 +vn 0.0273 0.1962 -0.9802 +vn 0.0056 -0.0255 -0.9997 +vn -0.0073 -0.1337 -0.9910 +vn -0.0236 -0.1322 -0.9909 +vn -0.0123 -0.0243 -0.9996 +vn -0.0281 -0.1312 0.9910 +vn -0.0101 -0.0908 0.9958 +vn -0.0457 -0.0986 0.9941 +vn -0.0658 -0.1516 0.9862 +vn -0.0146 0.0036 0.9999 +vn -0.0131 -0.0050 0.9999 +vn -0.0219 0.0965 0.9951 +vn -0.0282 0.1031 0.9943 +vn -0.0170 0.0064 0.9998 +vn -0.0136 -0.0034 0.9999 +vn -0.0022 -0.0496 0.9988 +vn 0.0101 0.0828 0.9965 +vn -0.0178 0.0851 0.9962 +vn -0.0361 -0.0467 0.9983 +vn -0.0856 -0.6019 0.7939 +vn -0.1271 -0.9919 0.0071 +vn -0.0254 -0.1116 0.9934 +vn -0.0856 -0.6019 0.7940 +vn -0.0225 -0.1127 0.9934 +vn -0.0799 -0.6043 0.7927 +vn -0.0800 -0.6043 0.7928 +vn -0.1254 -0.9921 0.0059 +vn -0.0137 -0.0139 0.9998 +vn -0.0127 -0.0136 0.9998 +vn 0.0762 0.6903 -0.7195 +vn 0.1157 0.9924 0.0425 +vn 0.0762 0.6904 -0.7194 +vn 0.1078 0.6737 -0.7311 +vn 0.1491 0.9880 0.0393 +vn -0.9946 0.1025 0.0174 +vn -0.9997 0.0180 0.0170 +vn -0.9870 0.0067 0.1603 +vn -0.9624 0.0715 0.2620 +vn -0.9998 -0.0114 0.0161 +vn -0.9858 -0.0269 0.1655 +vn -0.9974 0.0716 -0.0103 +vn -0.9987 0.0499 -0.0100 +vn -0.9833 0.0501 -0.1750 +vn -0.9812 0.0708 -0.1796 +vn -0.9930 0.1178 -0.0070 +vn -0.9500 0.1071 -0.2932 +vn -0.8318 0.0564 -0.5522 +vn -0.8327 0.0490 -0.5515 +vn -0.8324 0.0611 -0.5508 +vn -0.9956 0.0931 -0.0107 +vn -0.9802 0.0915 -0.1756 +vn -0.9551 0.0316 -0.2946 +vn -0.8308 0.0731 -0.5518 +vn -0.8306 0.0658 -0.5529 +vn -0.9990 -0.0424 0.0131 +vn -0.9861 -0.0607 0.1545 +vn -0.9912 -0.1322 0.0053 +vn -0.9587 -0.1505 0.2413 +vn -0.0299 -0.0098 0.9995 +vn -0.2421 0.0148 0.9701 +vn -0.7443 0.0683 0.6643 +vn -0.7430 0.0613 0.6665 +vn -0.2802 0.9592 0.0370 +vn -0.1329 0.6839 -0.7174 +vn -0.6485 0.3979 -0.6489 +vn -0.8141 0.5801 -0.0258 +vn 0.0053 0.1797 -0.9837 +vn -0.4153 0.1585 -0.8958 +vn -0.4154 0.1585 -0.8957 +vn -0.7521 0.0761 -0.6546 +vn -0.9358 0.1198 -0.3314 +vn -0.0321 0.1035 -0.9941 +vn -0.0147 0.1219 -0.9924 +vn -0.2424 0.1147 -0.9634 +vn -0.2628 0.0978 -0.9599 +vn 0.0001 0.0209 -0.9998 +vn -0.4217 0.0155 -0.9066 +vn -0.7534 0.0441 -0.6561 +vn -0.7584 0.0593 -0.6491 +vn -0.7600 0.0598 -0.6472 +vn -0.2880 0.1377 -0.9477 +vn -0.2925 0.0394 -0.9554 +vn -0.5305 0.0437 -0.8466 +vn -0.6271 0.1166 -0.7701 +vn -0.2975 0.0238 -0.9544 +vn -0.5386 0.0409 -0.8415 +vn -0.8322 0.0611 -0.5510 +vn -0.8326 0.0491 -0.5516 +vn -0.8317 0.0564 -0.5523 +vn -0.3769 -0.9227 -0.0812 +vn -0.4646 -0.6618 0.5884 +vn -0.8211 -0.3977 0.4095 +vn -0.8156 -0.5732 -0.0791 +vn -0.4645 -0.6618 0.5884 +vn -0.8155 -0.5733 -0.0791 +vn -0.3159 0.9487 0.0093 +vn -0.3393 0.6008 -0.7239 +vn -0.7661 0.3569 -0.5345 +vn -0.7930 0.6082 0.0350 +vn -0.3393 0.6007 -0.7239 +vn -0.7661 0.3569 -0.5346 +vn -0.6271 0.1166 -0.7702 +vn -0.0229 0.0861 -0.9960 +vn -0.2450 0.0829 -0.9660 +vn -0.7567 0.0609 -0.6509 +vn -0.7523 0.0761 -0.6544 +vn -0.2943 0.0076 -0.9557 +vn -0.5307 0.0369 -0.8467 +vn -0.3007 -0.0916 -0.9493 +vn -0.6367 -0.0210 -0.7708 +vn -0.8308 0.0658 -0.5527 +vn -0.9931 0.0907 -0.0745 +vn -0.9947 0.0717 -0.0735 +vn -0.9968 0.0269 -0.0751 +vn 0.9909 -0.1204 0.0603 +vn 0.9747 -0.2150 0.0617 +vn 0.9957 -0.0709 0.0596 +vn -0.8479 0.5259 -0.0671 +vn -0.0243 0.9996 -0.0164 +vn -0.9913 0.1105 -0.0714 +vn 0.7859 -0.6162 0.0518 +vn -0.0358 -0.9994 -0.0022 +vn -0.9960 0.0530 -0.0721 +vn 0.9980 -0.0233 0.0590 +vn 0.9960 0.0675 0.0585 +vn 0.0042 -0.0927 0.9957 +vn -0.0118 -0.2079 0.9781 +vn 0.0087 -0.0633 0.9980 +vn -0.3279 0.7353 -0.5931 +vn -0.1185 0.6443 -0.7556 +vn -0.0712 0.9966 -0.0412 +vn -0.3280 0.7353 -0.5931 +vn -0.6987 0.2360 -0.6753 +vn -0.1417 0.1615 -0.9766 +vn -0.1185 0.6443 -0.7555 +vn -0.6738 0.0911 -0.7332 +vn -0.0923 0.0631 -0.9937 +vn -0.0796 0.0680 -0.9945 +vn -0.1294 -0.0329 -0.9910 +vn -0.1060 0.0742 -0.9916 +vn 0.0123 -0.0350 0.9993 +vn 0.0105 0.0783 0.9969 +vn -0.1403 -0.9897 0.0271 +vn -0.0695 -0.6772 0.7325 +vn -0.0830 -0.6792 0.7293 +vn -0.1439 -0.9890 -0.0340 +vn -0.0830 -0.6792 0.7292 +vn 0.2050 -0.0260 -0.9784 +vn 0.2023 -0.0520 -0.9779 +vn 0.1395 -0.0461 -0.9891 +vn 0.1401 -0.0201 -0.9899 +vn 0.1196 -0.1309 -0.9842 +vn 0.0270 0.9907 -0.1333 +vn 0.1593 0.5202 -0.8391 +vn 0.1380 0.5370 -0.8322 +vn 0.1098 0.9930 -0.0435 +vn 0.1593 0.5202 -0.8390 +vn 0.1854 0.0803 -0.9794 +vn 0.1238 0.0914 -0.9881 +vn -0.1002 0.0101 0.9949 +vn -0.1210 -0.0690 0.9903 +vn -0.6005 0.0525 0.7979 +vn -0.0920 0.0166 0.9956 +vn -0.3718 -0.6399 0.6726 +vn -0.1752 -0.5632 0.8075 +vn -0.1321 -0.9908 -0.0310 +vn -0.3718 -0.6399 0.6725 +vn -0.1752 -0.5633 0.8075 +vn 0.1991 0.0004 -0.9800 +vn 0.1324 0.0061 -0.9912 +vn -0.0865 0.0235 0.9960 +vn -0.0799 0.1032 0.9914 +vn -0.8729 -0.4769 0.1034 +vn -0.0384 -0.9987 0.0333 +vn -0.9944 0.0271 0.1019 +vn -0.8729 -0.4768 0.1035 +vn 0.9951 -0.0248 -0.0960 +vn 0.9927 0.0715 -0.0969 +vn 0.9928 -0.0736 -0.0949 +vn -0.9907 0.0914 0.1004 +vn -0.9921 0.0735 0.1012 +vn 0.8416 0.5333 -0.0852 +vn 0.0183 0.9998 -0.0066 +vn -0.9933 0.0556 0.1017 +vn -0.9877 0.1195 0.1004 +vn 0.9882 -0.1218 -0.0932 +vn 0.9728 -0.2137 -0.0894 +vn 0.0251 -0.5729 -0.8192 +vn -0.0446 -0.5892 -0.8067 +vn -0.2763 0.6952 0.6636 +vn -0.0134 0.5893 0.8078 +vn 0.0813 0.5691 0.8183 +vn -0.1891 0.6155 0.7651 +vn -0.6546 0.3736 0.6572 +vn -0.1892 0.6155 0.7651 +vn -0.6546 0.3736 0.6571 +vn -0.9327 0.1103 0.3435 +vn -0.4180 0.1050 0.9024 +vn -0.7439 0.0419 0.6670 +vn -0.7442 0.0683 0.6645 +vn -0.9803 0.0928 0.1742 +vn -0.7469 0.0519 0.6629 +vn -0.9813 0.0699 0.1795 +vn -0.7463 0.0351 0.6647 +vn -0.9835 0.0471 0.1748 +vn -0.0695 -0.6124 -0.7875 +vn -0.0709 -0.6183 -0.7827 +vn -0.0695 -0.6123 -0.7875 +vn -0.0709 -0.6184 -0.7827 +vn -0.0809 -0.6168 -0.7829 +vn -0.4012 -0.5568 -0.7273 +vn -0.8090 -0.2382 -0.5373 +vn -0.8091 -0.2382 -0.5373 +vn -0.6367 -0.0210 -0.7709 +vn 0.0682 0.5735 0.8164 +vn 0.0079 0.5817 0.8134 +vn 0.0079 0.5818 0.8133 +vn -0.0658 -0.6032 -0.7949 +vn -0.0579 0.5885 0.8064 +vn -0.0837 0.5951 0.7992 +vn -0.0837 0.5951 0.7993 +vn -0.3153 -0.8853 0.3417 +vn 0.1865 -0.9781 0.0926 +vn -0.6508 -0.6306 0.4228 +vn 0.9988 -0.0235 0.0432 +vn 0.9963 0.0750 0.0423 +vn 0.9964 -0.0720 0.0442 +vn 0.8375 0.5455 0.0329 +vn 0.2248 0.9726 0.0598 +vn 0.9917 -0.1199 0.0457 +vn 0.9757 -0.2138 0.0481 +vn -0.6049 0.6973 0.3846 +vn -0.2640 0.9157 0.3029 +vn -0.6048 0.6973 0.3847 +vn 0.0021 0.9699 -0.2436 +vn 0.7820 -0.6233 -0.0029 +vn 0.7823 -0.6207 0.0518 +vn 0.2422 -0.9424 -0.2307 +vn 0.7499 -0.6491 -0.1272 +vn -0.8276 0.5608 0.0235 +vn -0.8202 0.5664 0.0803 +vn 0.0366 0.9959 -0.0823 +vn 0.0201 0.9998 -0.0053 +vn -0.8157 0.5718 0.0876 +vn 0.7972 -0.5974 -0.0876 +vn 0.7869 -0.6141 -0.0600 +vn 0.7853 -0.6159 -0.0630 +vn -0.8766 -0.4811 -0.0027 +vn -0.8744 -0.4807 -0.0654 +vn -0.8767 -0.4811 -0.0026 +vn -0.8722 -0.4837 -0.0723 +vn -0.8722 -0.4838 -0.0724 +vn 0.9952 0.0663 0.0714 +vn 0.8671 0.4892 0.0942 +vn 0.8441 0.5344 0.0443 +vn 0.0236 0.9968 0.0766 +vn -0.0244 0.9996 -0.0164 +vn -0.0270 0.9995 -0.0187 +vn 0.8440 0.5341 0.0496 +vn 0.6677 -0.4204 -0.6143 +vn 0.9120 -0.2166 -0.3482 +vn 0.7688 0.5991 0.2237 +vn 0.6226 0.3945 0.6758 +vn 0.6227 0.3945 0.6757 +vn 0.3664 0.0776 0.9272 +vn 0.6931 -0.0065 0.7208 +vn 0.1169 0.5173 -0.8478 +vn 0.1168 0.5173 -0.8478 +vn 0.1400 0.0778 -0.9871 +vn 0.1472 -0.0458 -0.9881 +vn 0.1484 -0.0222 -0.9887 +vn 0.1466 0.0016 -0.9892 +vn 0.6937 -0.0917 0.7144 +vn 0.6943 -0.0496 0.7180 +vn 0.1988 -0.0406 0.9792 +vn 0.2057 -0.0750 0.9757 +vn 0.6897 -0.1356 0.7113 +vn 0.1967 -0.1098 0.9743 +vn 0.7839 -0.6188 -0.0504 +vn 0.8425 0.5364 0.0506 +vn 0.0550 0.9981 -0.0267 +vn 0.8376 0.5436 0.0546 +vn -0.7812 0.6004 0.1709 +vn -0.0966 -0.9874 0.1252 +vn -0.0428 -0.6776 0.7342 +vn -0.6776 -0.3579 0.6424 +vn -0.6776 -0.3579 0.6425 +vn 0.2914 0.0852 0.9528 +vn 0.7092 0.3133 0.6316 +vn 0.2494 0.5893 0.7684 +vn -0.8510 -0.5094 -0.1277 +vn -0.8510 -0.5093 -0.1277 +vn -0.6991 -0.6400 -0.3190 +vn 0.1445 -0.2019 0.9687 +vn 0.1910 -0.0564 0.9800 +vn -0.7643 -0.3299 -0.5541 +vn -0.7236 0.0649 -0.6871 +vn -0.1052 -0.1258 -0.9865 +vn -0.3761 -0.6254 -0.6837 +vn -0.0620 0.0118 -0.9980 +vn -0.5941 -0.8044 -0.0010 +vn -0.5969 -0.8023 -0.0004 +vn -0.5959 -0.8030 0.0069 +vn -0.7643 -0.3299 -0.5540 +vn -0.3761 -0.6254 -0.6836 +vn -0.5657 -0.8165 -0.1154 +vn -0.9195 -0.3747 -0.1190 +vn -0.5962 -0.8028 -0.0069 +vn -0.0660 -0.0041 -0.9978 +vn -0.1102 0.0883 -0.9900 +vn -0.7186 -0.0600 -0.6928 +vn -0.1118 -0.0177 -0.9936 +vn -0.5649 -0.8166 0.1183 +vn -0.9190 -0.3750 0.1221 +vn -0.0530 0.0054 -0.9986 +vn -0.1101 0.0883 -0.9900 +vn -0.7236 0.4287 -0.5410 +vn 0.2169 0.6235 -0.7511 +vn -0.5970 -0.8023 0.0005 +vn -0.5942 -0.8043 0.0010 +vn -0.5897 -0.8076 0.0010 +vn -0.5873 -0.8093 -0.0000 +vn -0.5895 -0.8078 -0.0010 +vn -0.5940 -0.8045 -0.0009 +vn -0.9305 -0.3663 -0.0002 +vn -0.5966 -0.8025 -0.0003 +vn -0.5977 -0.8017 0.0000 +vn -0.9312 -0.3644 0.0000 +vn -0.5966 -0.8025 0.0003 +vn -0.9311 -0.3649 0.0001 +vn -0.5939 -0.8046 0.0009 +vn -0.5895 -0.8078 0.0009 +vn -0.5874 -0.8093 -0.0000 +vn -0.5897 -0.8076 -0.0010 +vn 0.6960 -0.4396 -0.5677 +vn 0.1799 -0.6371 -0.7494 +vn 0.2048 -0.0607 0.9769 +vn 0.2102 0.0101 0.9776 +vn 0.2068 0.0012 0.9784 +vn -0.1374 -0.5954 -0.7916 +vn -0.1071 -0.1170 -0.9873 +vn -0.1321 -0.9912 -0.0036 +vn -0.1374 -0.5953 -0.7916 +vn -0.0467 0.5946 0.8026 +vn -0.0131 0.1033 0.9946 +vn -0.1014 0.9948 -0.0016 +vn -0.0467 0.5946 0.8027 +vn -0.3159 0.9488 0.0092 +vn -0.1891 0.6154 0.7652 +vn -0.1044 -0.0143 -0.9944 +vn -0.1034 0.0104 -0.9946 +vn -0.1101 0.6026 -0.7905 +vn -0.0964 0.1352 -0.9861 +vn -0.1100 0.6025 -0.7905 +vn -0.1002 0.0347 -0.9944 +vn -0.0100 -0.0128 0.9999 +vn -0.0114 -0.1101 0.9939 +vn -0.0125 -0.0024 0.9999 +vn -0.0131 0.0080 0.9999 +vn -0.0605 -0.6009 0.7970 +vn -0.0606 -0.6009 0.7970 +vn -0.3579 -0.8828 -0.3043 +vn -0.3757 -0.6729 -0.6373 +vn 0.1531 -0.9879 -0.0259 +vn -0.3579 -0.8828 -0.3042 +vn -0.3757 -0.6729 -0.6372 +vn 0.8237 0.5629 0.0686 +vn 0.9955 0.0786 0.0535 +vn 0.1780 0.9840 -0.0005 +vn -0.1609 -0.5986 -0.7847 +vn -0.1609 -0.5985 -0.7848 +vn -0.1002 -0.5865 -0.8037 +vn -0.0370 0.6435 0.7646 +vn -0.0370 0.6434 0.7646 +vn -0.0641 0.6669 0.7424 +vn -0.0641 0.6669 0.7423 +vn -0.2069 -0.5551 -0.8057 +vn -0.6528 -0.2980 -0.6964 +vn -0.2069 -0.5550 -0.8057 +vn -0.9382 -0.0790 -0.3370 +vn -0.4216 0.0155 -0.9067 +vn -0.7530 0.0442 -0.6565 +vn -0.3981 0.5693 0.7193 +vn -0.8306 0.2867 0.4774 +vn -0.7599 0.0598 -0.6473 +vn -0.9869 -0.0169 -0.1604 +vn -0.9860 0.0077 -0.1666 +vn -0.7568 0.0609 -0.6507 +vn -0.9870 0.0294 -0.1583 +vn 0.0273 0.6121 0.7903 +vn 0.0705 0.6101 0.7892 +vn 0.0691 0.6054 0.7929 +vn -0.0283 0.6332 0.7735 +vn -0.0283 0.6331 0.7735 +vn -0.0800 -0.5983 -0.7973 +vn -0.0644 -0.5949 -0.8012 +vn -0.0497 -0.5808 -0.8125 +vn 0.9919 -0.1213 0.0368 +vn 0.9728 -0.2267 0.0482 +vn 0.9969 -0.0702 0.0345 +vn -0.6652 0.6893 -0.2870 +vn -0.3276 0.9082 -0.2603 +vn -0.0924 -0.5913 -0.8011 +vn -0.0924 -0.5912 -0.8012 +vn 0.7607 -0.6473 0.0490 +vn 0.9990 -0.0215 0.0386 +vn -0.0541 0.5870 0.8078 +vn -0.1657 0.0812 0.9828 +vn 0.1035 0.9930 0.0571 +vn -0.0542 0.5870 0.8078 +vn -0.3980 0.5694 0.7193 +vn -0.0165 -0.5597 -0.8286 +vn 0.0395 0.0161 -0.9991 +vn -0.1467 -0.9878 -0.0528 +vn -0.0165 -0.5596 -0.8286 +vn 0.0039 0.0889 -0.9960 +vn 0.0368 0.1809 -0.9828 +vn 0.0020 0.1027 -0.9947 +vn -0.2273 -0.6998 0.6772 +vn -0.2325 -0.2859 0.9296 +vn -0.2273 -0.6999 0.6772 +vn 0.0188 0.1172 -0.9929 +vn 0.1167 0.6596 -0.7425 +vn 0.1167 0.6597 -0.7425 +vn -0.2231 -0.1615 0.9613 +vn -0.2090 -0.1016 0.9726 +vn -0.1955 -0.0437 0.9797 +usemtl Scene_-_Root +s off +f 42336/42133/31267 42338/42134/31268 42339/42135/31269 +f 42339/42135/31270 42340/42136/31271 42341/42137/31270 +f 42341/42137/31270 42342/42138/31272 42343/42139/31270 +f 42343/42139/31270 42344/42140/31272 42345/42141/31270 +f 42345/42141/31270 42346/42142/31273 42347/42143/31270 +f 42347/42143/31270 42348/42144/31274 42349/42145/31270 +f 42349/42145/31275 42350/42146/31276 42351/42147/31275 +f 42351/42147/31275 42352/42148/31277 42353/42149/31275 +f 42353/42149/31275 42354/42150/31278 42355/42151/31275 +f 42355/42151/31275 42356/42152/31277 42357/42153/31275 +f 42357/42153/31275 42358/42154/31277 42359/42155/31275 +f 42359/42155/31279 42360/42156/31277 42361/42157/31280 +f 42361/42157/31269 42362/42158/31277 42363/42159/31279 +f 42363/42159/31275 42364/42160/31277 42365/42161/31275 +f 42365/42161/31275 42825/42162/31278 42826/42163/31275 +f 42881/42164/31281 42365/42161/31282 42826/42163/31282 +f 42944/42165/31283 42361/42157/31270 42363/42159/31284 +f 42945/42166/31283 42363/42159/31284 42365/42161/31284 +f 42948/42167/31281 42357/42153/31284 42359/42155/31284 +f 42949/42168/31283 42359/42155/31284 42361/42157/31284 +f 42952/42169/31281 42353/42149/31284 42355/42151/31284 +f 42953/42170/31281 42355/42151/31282 42357/42153/31282 +f 42956/42171/31281 42349/42145/31284 42351/42147/31284 +f 42957/42172/31281 42351/42147/31284 42353/42149/31284 +f 42960/42173/31283 42345/42141/31284 42347/42143/31284 +f 42961/42174/31283 42347/42143/31284 42349/42145/31284 +f 42964/42175/31281 42341/42137/31284 42343/42139/31284 +f 42965/42176/31283 42343/42139/31284 42345/42141/31284 +f 42878/42177/31285 42336/42133/31267 42339/42135/31282 +f 42967/42178/31281 42339/42135/31282 42341/42137/31282 +s 1 +f 42133/42179/31286 42134/42180/31287 42135/42181/31288 +f 42133/42179/31286 42135/42181/31288 42136/42182/31289 +f 42134/42180/31287 42137/42183/31290 42138/42184/31291 +f 42134/42180/31287 42138/42184/31291 42135/42181/31288 +f 42135/42181/31288 42138/42184/31291 42139/42185/31292 +f 42135/42181/31288 42139/42185/31292 42140/42186/31293 +f 42136/42182/31289 42135/42181/31288 42140/42186/31293 +f 42136/42182/31289 42140/42186/31293 42141/42187/31294 +f 42142/42188/31295 42143/42189/31296 42144/42190/31297 +f 42142/42188/31295 42144/42190/31297 42145/42191/31298 +f 42143/42189/31296 42146/42192/31299 42147/42193/31300 +f 42143/42189/31296 42147/42193/31300 42144/42190/31297 +f 42144/42190/31297 42147/42193/31300 42148/42194/31301 +f 42144/42190/31297 42148/42194/31301 42149/42195/31302 +f 42145/42191/31298 42144/42190/31297 42149/42195/31302 +f 42145/42191/31298 42149/42195/31302 42150/42196/31303 +f 42151/42197/31304 42152/42198/31305 42153/42199/31306 +f 42151/42197/31304 42153/42199/31306 42154/42200/31307 +f 42152/42198/31305 42155/42201/31308 42156/42202/31309 +f 42152/42198/31305 42156/42202/31309 42153/42199/31306 +f 42153/42199/31306 42156/42202/31309 42157/42203/31310 +f 42153/42199/31306 42157/42203/31310 42158/42204/31311 +f 42154/42200/31307 42153/42199/31306 42158/42204/31311 +f 42154/42200/31307 42158/42204/31311 42159/42205/31312 +f 42160/42206/31313 42161/42207/31314 42162/42208/31315 +f 42160/42206/31313 42162/42208/31315 42163/42209/31316 +f 42161/42207/31314 42164/42210/31317 42165/42211/31318 +f 42161/42207/31314 42165/42211/31318 42162/42208/31315 +f 42162/42208/31315 42165/42211/31318 42166/42212/31319 +f 42162/42208/31315 42166/42212/31319 42167/42213/31320 +f 42163/42209/31316 42162/42208/31315 42167/42213/31320 +f 42163/42209/31316 42167/42213/31320 42168/42214/31321 +f 42169/42215/31322 42170/42216/31323 42171/42217/31324 +f 42169/42215/31322 42171/42217/31324 42172/42218/31325 +f 42170/42216/31323 42173/42219/31326 42174/42220/31327 +f 42170/42216/31323 42174/42220/31327 42171/42217/31324 +f 42171/42217/31324 42174/42220/31327 42175/42221/31328 +f 42171/42217/31324 42175/42221/31328 42176/42222/31329 +f 42172/42218/31325 42171/42217/31324 42176/42222/31329 +f 42172/42218/31325 42176/42222/31329 42177/42223/31330 +f 42178/42224/31331 42179/42225/31332 42180/42226/31333 +f 42178/42224/31331 42180/42226/31333 42181/42227/31334 +f 42179/42225/31332 42182/42228/31335 42183/42229/31336 +f 42179/42225/31332 42183/42229/31336 42180/42226/31333 +f 42184/42230/31333 42185/42231/31337 42186/42232/31338 +f 42184/42230/31333 42186/42232/31338 42187/42233/31339 +f 42188/42234/31340 42184/42230/31333 42187/42233/31339 +f 42188/42234/31340 42187/42233/31339 42189/42235/31341 +f 42190/42236/31342 42191/42237/31343 42192/42238/31344 +f 42190/42236/31342 42192/42238/31344 42193/42239/31345 +f 42191/42237/31343 42194/42240/31346 42195/42241/31347 +f 42191/42237/31343 42195/42241/31347 42192/42238/31344 +f 42196/42242/31348 42197/42243/31349 42198/42244/31350 +f 42196/42242/31348 42198/42244/31350 42199/42245/31351 +f 42200/42246/31352 42201/42247/31348 42202/42248/31351 +f 42200/42246/31352 42202/42248/31351 42203/42249/31353 +f 42204/42250/31354 42205/42251/31355 42206/42252/31356 +f 42204/42250/31354 42206/42252/31356 42207/42253/31357 +f 42205/42251/31355 42208/42254/31358 42209/42255/31359 +f 42205/42251/31355 42209/42255/31359 42206/42252/31356 +f 42206/42252/31356 42209/42255/31359 42210/42256/31360 +f 42206/42252/31356 42210/42256/31360 42211/42257/31361 +f 42207/42253/31357 42206/42252/31356 42211/42257/31361 +f 42207/42253/31357 42211/42257/31361 42212/42258/31362 +f 42208/42254/31358 42213/42259/31363 42214/42260/31364 +f 42208/42254/31358 42214/42260/31364 42209/42255/31359 +f 42213/42259/31363 42215/42261/31365 42216/42262/31366 +f 42213/42259/31363 42216/42262/31366 42214/42260/31364 +f 42214/42260/31364 42216/42262/31366 42217/42263/31367 +f 42214/42260/31364 42217/42263/31367 42218/42264/31368 +f 42209/42255/31359 42214/42260/31364 42218/42264/31368 +f 42209/42255/31359 42218/42264/31368 42210/42256/31360 +f 42215/42261/31365 42219/42265/31369 42220/42266/31370 +f 42215/42261/31365 42220/42266/31370 42216/42262/31366 +f 42219/42265/31369 42221/42267/31371 42222/42268/31372 +f 42219/42265/31369 42222/42268/31372 42220/42266/31370 +f 42220/42266/31370 42222/42268/31372 42223/42269/31373 +f 42220/42266/31370 42223/42269/31373 42224/42270/31374 +f 42216/42262/31366 42220/42266/31370 42224/42270/31374 +f 42216/42262/31366 42224/42270/31374 42217/42263/31367 +f 42225/42271/31375 42226/42272/31376 42227/42273/31377 +f 42225/42271/31375 42227/42273/31377 42228/42274/31378 +f 42226/42272/31376 42229/42275/31379 42230/42276/31380 +f 42226/42272/31376 42230/42276/31380 42227/42273/31377 +f 42227/42273/31377 42230/42276/31380 42231/42277/31381 +f 42227/42273/31377 42231/42277/31381 42232/42278/31382 +f 42228/42274/31378 42227/42273/31377 42232/42278/31382 +f 42228/42274/31378 42232/42278/31382 42233/42279/31383 +f 42229/42275/31379 42234/42280/31384 42235/42281/31385 +f 42229/42275/31379 42235/42281/31385 42230/42276/31380 +f 42234/42280/31384 42236/42282/31386 42237/42283/31387 +f 42234/42280/31384 42237/42283/31387 42235/42281/31385 +f 42235/42281/31385 42237/42283/31387 42238/42284/31388 +f 42235/42281/31385 42238/42284/31388 42239/42285/31389 +f 42230/42276/31380 42235/42281/31385 42239/42285/31389 +f 42230/42276/31380 42239/42285/31389 42231/42277/31381 +f 42236/42282/31386 42240/42286/31390 42241/42287/31391 +f 42236/42282/31386 42241/42287/31391 42237/42283/31387 +f 42240/42286/31390 42142/42188/31295 42145/42191/31298 +f 42240/42286/31390 42145/42191/31298 42241/42287/31391 +f 42241/42287/31391 42145/42191/31298 42150/42196/31303 +f 42241/42287/31391 42150/42196/31303 42242/42288/31392 +f 42237/42283/31387 42241/42287/31391 42242/42288/31392 +f 42237/42283/31387 42242/42288/31392 42238/42284/31388 +f 42243/42289/31393 42244/42290/31394 42245/42291/31395 +f 42243/42289/31393 42245/42291/31395 42246/42292/31396 +f 42244/42290/31394 42247/42293/31397 42248/42294/31398 +f 42244/42290/31394 42248/42294/31398 42245/42291/31395 +f 42245/42291/31395 42248/42294/31398 42249/42295/31346 +f 42245/42291/31395 42249/42295/31346 42250/42296/31399 +f 42246/42292/31396 42245/42291/31395 42250/42296/31399 +f 42246/42292/31396 42250/42296/31399 42251/42297/31400 +f 42247/42293/31397 42252/42298/31401 42253/42299/31402 +f 42247/42293/31397 42253/42299/31402 42248/42294/31398 +f 42252/42298/31401 42254/42300/31403 42255/42301/31404 +f 42252/42298/31401 42255/42301/31404 42253/42299/31402 +f 42253/42299/31402 42255/42301/31404 42256/42302/31405 +f 42253/42299/31402 42256/42302/31405 42257/42303/31406 +f 42248/42294/31398 42253/42299/31402 42257/42303/31406 +f 42248/42294/31398 42257/42303/31406 42249/42295/31346 +f 42254/42300/31403 42258/42304/31407 42259/42305/31408 +f 42254/42300/31403 42259/42305/31408 42255/42301/31404 +f 42258/42304/31407 42133/42179/31286 42136/42182/31289 +f 42258/42304/31407 42136/42182/31289 42259/42305/31408 +f 42259/42305/31408 42136/42182/31289 42141/42187/31294 +f 42259/42305/31408 42141/42187/31294 42260/42306/31409 +f 42255/42301/31404 42259/42305/31408 42260/42306/31409 +f 42255/42301/31404 42260/42306/31409 42256/42302/31405 +f 42261/42307/31410 42262/42308/31411 42263/42309/31412 +f 42261/42307/31410 42263/42309/31412 42264/42310/31413 +f 42262/42308/31411 42265/42311/31414 42266/42312/31415 +f 42262/42308/31411 42266/42312/31415 42263/42309/31412 +f 42263/42309/31412 42266/42312/31415 42267/42313/31416 +f 42263/42309/31412 42267/42313/31416 42268/42314/31417 +f 42264/42310/31413 42263/42309/31412 42268/42314/31417 +f 42264/42310/31413 42268/42314/31417 42269/42315/31418 +f 42269/42315/31418 42268/42314/31417 42270/42316/31419 +f 42269/42315/31418 42270/42316/31419 42271/42317/31420 +f 42268/42314/31417 42267/42313/31416 42272/42318/31421 +f 42268/42314/31417 42272/42318/31421 42270/42316/31419 +f 42270/42316/31419 42272/42318/31421 42273/42319/31422 +f 42270/42316/31419 42273/42319/31422 42274/42320/31423 +f 42271/42317/31420 42270/42316/31419 42274/42320/31423 +f 42271/42317/31420 42274/42320/31423 42275/42321/31424 +f 42275/42321/31424 42274/42320/31423 42276/42322/31425 +f 42275/42321/31424 42276/42322/31425 42277/42323/31426 +f 42274/42320/31423 42273/42319/31422 42278/42324/31427 +f 42274/42320/31423 42278/42324/31427 42276/42322/31425 +f 42276/42322/31425 42278/42324/31427 42279/42325/31428 +f 42276/42322/31425 42279/42325/31428 42280/42326/31429 +f 42277/42323/31426 42276/42322/31425 42280/42326/31429 +f 42277/42323/31426 42280/42326/31429 42281/42327/31430 +f 42281/42327/31430 42280/42326/31429 42282/42328/31431 +f 42281/42327/31430 42282/42328/31431 42283/42329/31432 +f 42280/42326/31429 42279/42325/31428 42284/42330/31433 +f 42280/42326/31429 42284/42330/31433 42282/42328/31431 +f 42282/42328/31431 42284/42330/31433 42285/42331/31434 +f 42282/42328/31431 42285/42331/31434 42286/42332/31435 +f 42283/42329/31432 42282/42328/31431 42286/42332/31435 +f 42283/42329/31432 42286/42332/31435 42287/42333/31436 +f 42287/42333/31436 42286/42332/31435 42288/42334/31437 +f 42287/42333/31436 42288/42334/31437 42289/42335/31438 +f 42286/42332/31435 42285/42331/31434 42290/42336/31439 +f 42286/42332/31435 42290/42336/31439 42288/42334/31437 +f 42288/42334/31437 42290/42336/31439 42291/42337/31440 +f 42288/42334/31437 42291/42337/31440 42292/42338/31441 +f 42289/42335/31438 42288/42334/31437 42292/42338/31441 +f 42289/42335/31438 42292/42338/31441 42293/42339/31442 +f 42293/42339/31442 42292/42338/31441 42294/42340/31443 +f 42293/42339/31442 42294/42340/31443 42295/42341/31444 +f 42292/42338/31441 42291/42337/31440 42296/42342/31445 +f 42292/42338/31441 42296/42342/31445 42294/42340/31443 +f 42294/42340/31443 42296/42342/31445 42297/42343/31446 +f 42294/42340/31443 42297/42343/31446 42298/42344/31447 +f 42295/42341/31444 42294/42340/31443 42298/42344/31447 +f 42295/42341/31444 42298/42344/31447 42299/42345/31448 +f 42299/42345/31448 42298/42344/31447 42300/42346/31449 +f 42299/42345/31448 42300/42346/31449 42301/42347/31450 +f 42298/42344/31447 42297/42343/31446 42302/42348/31451 +f 42298/42344/31447 42302/42348/31451 42300/42346/31449 +f 42300/42346/31449 42302/42348/31451 42303/42349/31452 +f 42300/42346/31449 42303/42349/31452 42304/42350/31453 +f 42301/42347/31450 42300/42346/31449 42304/42350/31453 +f 42301/42347/31450 42304/42350/31453 42305/42351/31454 +f 42306/42352/31455 42307/42353/31456 42308/42354/31457 +f 42306/42352/31455 42308/42354/31457 42309/42355/31458 +f 42307/42353/31456 42261/42307/31410 42264/42310/31413 +f 42307/42353/31456 42264/42310/31413 42308/42354/31457 +f 42308/42354/31457 42264/42310/31413 42269/42315/31418 +f 42308/42354/31457 42269/42315/31418 42310/42356/31459 +f 42309/42355/31458 42308/42354/31457 42310/42356/31459 +f 42309/42355/31458 42310/42356/31459 42311/42357/31460 +f 42311/42357/31460 42310/42356/31459 42312/42358/31461 +f 42311/42357/31460 42312/42358/31461 42313/42359/31462 +f 42310/42356/31459 42269/42315/31418 42271/42317/31420 +f 42310/42356/31459 42271/42317/31420 42312/42358/31461 +f 42312/42358/31461 42271/42317/31420 42275/42321/31424 +f 42312/42358/31461 42275/42321/31424 42314/42360/31463 +f 42313/42359/31462 42312/42358/31461 42314/42360/31463 +f 42313/42359/31462 42314/42360/31463 42315/42361/31464 +f 42315/42361/31464 42314/42360/31463 42316/42362/31465 +f 42315/42361/31464 42316/42362/31465 42317/42363/31466 +f 42314/42360/31463 42275/42321/31424 42277/42323/31426 +f 42314/42360/31463 42277/42323/31426 42316/42362/31465 +f 42316/42362/31465 42277/42323/31426 42281/42327/31430 +f 42316/42362/31465 42281/42327/31430 42318/42364/31467 +f 42317/42363/31466 42316/42362/31465 42318/42364/31467 +f 42317/42363/31466 42318/42364/31467 42319/42365/31468 +f 42319/42365/31468 42318/42364/31467 42320/42366/31469 +f 42319/42365/31468 42320/42366/31469 42321/42367/31470 +f 42318/42364/31467 42281/42327/31430 42283/42329/31432 +f 42318/42364/31467 42283/42329/31432 42320/42366/31469 +f 42320/42366/31469 42283/42329/31432 42287/42333/31436 +f 42320/42366/31469 42287/42333/31436 42322/42368/31471 +f 42321/42367/31470 42320/42366/31469 42322/42368/31471 +f 42321/42367/31470 42322/42368/31471 42323/42369/31472 +f 42323/42369/31472 42322/42368/31471 42324/42370/31473 +f 42323/42369/31472 42324/42370/31473 42325/42371/31474 +f 42322/42368/31471 42287/42333/31436 42289/42335/31438 +f 42322/42368/31471 42289/42335/31438 42324/42370/31473 +f 42324/42370/31473 42289/42335/31438 42293/42339/31442 +f 42324/42370/31473 42293/42339/31442 42326/42372/31475 +f 42325/42371/31474 42324/42370/31473 42326/42372/31475 +f 42325/42371/31474 42326/42372/31475 42327/42373/31474 +f 42327/42373/31474 42326/42372/31475 42328/42374/31476 +f 42327/42373/31474 42328/42374/31476 42329/42375/31477 +f 42326/42372/31475 42293/42339/31442 42295/42341/31444 +f 42326/42372/31475 42295/42341/31444 42328/42374/31476 +f 42328/42374/31476 42295/42341/31444 42299/42345/31448 +f 42328/42374/31476 42299/42345/31448 42330/42376/31478 +f 42329/42375/31477 42328/42374/31476 42330/42376/31478 +f 42329/42375/31477 42330/42376/31478 42331/42377/31479 +f 42331/42377/31479 42330/42376/31478 42332/42378/31480 +f 42331/42377/31479 42332/42378/31480 42333/42379/31479 +f 42330/42376/31478 42299/42345/31448 42301/42347/31450 +f 42330/42376/31478 42301/42347/31450 42332/42378/31480 +f 42332/42378/31480 42301/42347/31450 42305/42351/31454 +f 42332/42378/31480 42305/42351/31454 42334/42380/31481 +f 42333/42379/31479 42332/42378/31480 42334/42380/31481 +f 42333/42379/31479 42334/42380/31481 42335/42381/31479 +f 42336/42133/31482 42337/42382/31483 42338/42134/31271 +f 42337/42382/31483 42306/42352/31455 42309/42355/31458 +f 42337/42382/31483 42309/42355/31458 42338/42134/31271 +f 42338/42134/31271 42309/42355/31458 42311/42357/31460 +f 42338/42134/31271 42311/42357/31460 42340/42136/31271 +f 42339/42135/31270 42338/42134/31271 42340/42136/31271 +f 42341/42137/31270 42340/42136/31271 42342/42138/31272 +f 42340/42136/31271 42311/42357/31460 42313/42359/31462 +f 42340/42136/31271 42313/42359/31462 42342/42138/31272 +f 42342/42138/31272 42313/42359/31462 42315/42361/31464 +f 42342/42138/31272 42315/42361/31464 42344/42140/31272 +f 42343/42139/31270 42342/42138/31272 42344/42140/31272 +f 42345/42141/31270 42344/42140/31272 42346/42142/31484 +f 42344/42140/31272 42315/42361/31464 42317/42363/31466 +f 42344/42140/31272 42317/42363/31466 42346/42142/31484 +f 42346/42142/31484 42317/42363/31466 42319/42365/31468 +f 42346/42142/31484 42319/42365/31468 42348/42144/31485 +f 42347/42143/31486 42346/42142/31484 42348/42144/31485 +f 42349/42145/31487 42348/42144/31485 42350/42146/31488 +f 42348/42144/31485 42319/42365/31468 42321/42367/31470 +f 42348/42144/31485 42321/42367/31470 42350/42146/31488 +f 42350/42146/31488 42321/42367/31470 42323/42369/31472 +f 42350/42146/31488 42323/42369/31472 42352/42148/31277 +f 42351/42147/31275 42350/42146/31488 42352/42148/31277 +f 42353/42149/31275 42352/42148/31277 42354/42150/31277 +f 42352/42148/31277 42323/42369/31472 42325/42371/31474 +f 42352/42148/31277 42325/42371/31474 42354/42150/31277 +f 42354/42150/31277 42325/42371/31474 42327/42373/31474 +f 42354/42150/31277 42327/42373/31474 42356/42152/31277 +f 42355/42151/31275 42354/42150/31277 42356/42152/31277 +f 42357/42153/31275 42356/42152/31277 42358/42154/31489 +f 42356/42152/31277 42327/42373/31474 42329/42375/31477 +f 42356/42152/31277 42329/42375/31477 42358/42154/31489 +f 42358/42154/31489 42329/42375/31477 42331/42377/31479 +f 42358/42154/31489 42331/42377/31479 42360/42156/31489 +f 42359/42155/31275 42358/42154/31489 42360/42156/31489 +f 42361/42157/31275 42360/42156/31489 42362/42158/31489 +f 42360/42156/31489 42331/42377/31479 42333/42379/31479 +f 42360/42156/31489 42333/42379/31479 42362/42158/31489 +f 42362/42158/31489 42333/42379/31479 42335/42381/31479 +f 42362/42158/31489 42335/42381/31479 42364/42160/31277 +f 42363/42159/31275 42362/42158/31489 42364/42160/31277 +f 42366/42383/31490 42367/42384/31491 42368/42385/31492 +f 42366/42383/31490 42368/42385/31492 42369/42386/31493 +f 42367/42384/31491 42370/42387/31494 42371/42388/31495 +f 42367/42384/31491 42371/42388/31495 42368/42385/31492 +f 42368/42385/31492 42371/42388/31495 42372/42389/31496 +f 42368/42385/31492 42372/42389/31496 42373/42390/31497 +f 42369/42386/31493 42368/42385/31492 42373/42390/31497 +f 42369/42386/31493 42373/42390/31497 42374/42391/31498 +f 42366/42383/31490 42375/42392/31499 42376/42393/31500 +f 42366/42383/31490 42376/42393/31500 42377/42394/31501 +f 42375/42392/31499 42378/42395/31502 42379/42396/31503 +f 42375/42392/31499 42379/42396/31503 42376/42393/31500 +f 42376/42393/31500 42379/42396/31503 42380/42397/31504 +f 42376/42393/31500 42380/42397/31504 42381/42398/31505 +f 42377/42394/31501 42376/42393/31500 42381/42398/31505 +f 42377/42394/31501 42381/42398/31505 42382/42399/31506 +f 42382/42399/31506 42381/42398/31505 42383/42400/31507 +f 42382/42399/31506 42383/42400/31507 42384/42401/31508 +f 42381/42398/31505 42380/42397/31504 42385/42402/31509 +f 42381/42398/31505 42385/42402/31509 42383/42400/31507 +f 42383/42400/31507 42385/42402/31509 42386/42403/31510 +f 42383/42400/31507 42386/42403/31510 42387/42404/31511 +f 42384/42401/31508 42383/42400/31507 42387/42404/31511 +f 42384/42401/31508 42387/42404/31511 42388/42405/31512 +f 42389/42406/31513 42390/42407/31514 42391/42408/31514 +f 42389/42406/31513 42391/42408/31514 42392/42409/31513 +f 42393/42410/31515 42394/42411/31515 42395/42412/31515 +f 42393/42410/31515 42395/42412/31515 42396/42413/31516 +f 42397/42414/31517 42398/42415/31518 42399/42416/31519 +f 42397/42414/31517 42399/42416/31519 42400/42417/31518 +f 42401/42418/31520 42402/42419/31521 42403/42420/31522 +f 42401/42418/31520 42403/42420/31522 42404/42421/31521 +f 42405/42422/31523 42406/42423/31524 42407/42424/31525 +f 42405/42422/31523 42407/42424/31525 42408/42425/31526 +f 42406/42423/31524 42409/42426/31527 42410/42427/31528 +f 42406/42423/31524 42410/42427/31528 42407/42424/31525 +f 42407/42424/31525 42410/42427/31528 42411/42428/31529 +f 42407/42424/31525 42411/42428/31529 42412/42429/31530 +f 42408/42425/31526 42407/42424/31525 42412/42429/31530 +f 42408/42425/31526 42412/42429/31530 42413/42430/31531 +f 42414/42431/31532 42415/42432/31533 42416/42433/31534 +f 42414/42431/31532 42416/42433/31534 42417/42434/31535 +f 42415/42432/31533 42418/42435/31536 42419/42436/31537 +f 42415/42432/31533 42419/42436/31537 42416/42433/31534 +f 42416/42433/31534 42419/42436/31537 42420/42437/31538 +f 42416/42433/31534 42420/42437/31538 42421/42438/31539 +f 42417/42434/31535 42416/42433/31534 42421/42438/31539 +f 42417/42434/31535 42421/42438/31539 42422/42439/31540 +f 42422/42439/31540 42421/42438/31539 42423/42440/31541 +f 42422/42439/31540 42423/42440/31541 42424/42441/31542 +f 42421/42438/31539 42420/42437/31538 42425/42442/31543 +f 42421/42438/31539 42425/42442/31543 42423/42440/31541 +f 42423/42440/31541 42425/42442/31543 42426/42443/31544 +f 42423/42440/31541 42426/42443/31544 42427/42444/31545 +f 42424/42441/31542 42423/42440/31541 42427/42444/31545 +f 42424/42441/31542 42427/42444/31545 42428/42445/31546 +f 42429/42446/31547 42430/42447/31548 42431/42448/31549 +f 42429/42446/31547 42431/42448/31549 42432/42449/31550 +f 42430/42447/31548 42433/42450/31551 42434/42451/31552 +f 42430/42447/31548 42434/42451/31552 42431/42448/31549 +f 42431/42448/31549 42434/42451/31552 42435/42452/31553 +f 42431/42448/31549 42435/42452/31553 42436/42453/31554 +f 42432/42449/31550 42431/42448/31549 42436/42453/31554 +f 42432/42449/31550 42436/42453/31554 42437/42454/31555 +f 42370/42387/31494 42367/42384/31491 42438/42455/31556 +f 42370/42387/31494 42438/42455/31556 42439/42456/31557 +f 42367/42384/31491 42366/42383/31490 42377/42394/31501 +f 42367/42384/31491 42377/42394/31501 42438/42455/31556 +f 42438/42455/31556 42377/42394/31501 42382/42399/31506 +f 42438/42455/31556 42382/42399/31506 42440/42457/31558 +f 42439/42456/31557 42438/42455/31556 42440/42457/31558 +f 42439/42456/31557 42440/42457/31558 42441/42458/31559 +f 42441/42458/31559 42440/42457/31558 42442/42459/31560 +f 42441/42458/31559 42442/42459/31560 42443/42460/31561 +f 42440/42457/31558 42382/42399/31506 42384/42401/31508 +f 42440/42457/31558 42384/42401/31508 42442/42459/31560 +f 42442/42459/31560 42384/42401/31508 42388/42405/31512 +f 42442/42459/31560 42388/42405/31512 42444/42461/31562 +f 42443/42460/31561 42442/42459/31560 42444/42461/31562 +f 42443/42460/31561 42444/42461/31562 42445/42462/31563 +f 42446/42463/31564 42447/42464/31565 42448/42465/31566 +f 42446/42463/31564 42448/42465/31566 42449/42466/31567 +f 42447/42464/31565 42450/42467/31568 42451/42468/31569 +f 42447/42464/31565 42451/42468/31569 42448/42465/31566 +f 42452/42469/31570 42453/42470/31569 42454/42471/31571 +f 42452/42469/31570 42454/42471/31571 42455/42472/31572 +f 42456/42473/31573 42452/42469/31570 42455/42472/31572 +f 42456/42473/31573 42455/42472/31572 42457/42474/31574 +f 42428/42445/31546 42427/42444/31545 42458/42475/31575 +f 42428/42445/31546 42458/42475/31575 42459/42476/31576 +f 42427/42444/31545 42426/42443/31544 42460/42477/31577 +f 42427/42444/31545 42460/42477/31577 42458/42475/31575 +f 42458/42475/31575 42460/42477/31577 42461/42478/31578 +f 42458/42475/31575 42461/42478/31578 42462/42479/31579 +f 42459/42476/31576 42458/42475/31575 42462/42479/31579 +f 42459/42476/31576 42462/42479/31579 42463/42480/31580 +f 42405/42422/31523 42464/42481/31581 42465/42482/31582 +f 42405/42422/31523 42465/42482/31582 42466/42483/31583 +f 42464/42481/31581 42414/42431/31532 42417/42434/31535 +f 42464/42481/31581 42417/42434/31535 42465/42482/31582 +f 42465/42482/31582 42417/42434/31535 42422/42439/31540 +f 42465/42482/31582 42422/42439/31540 42467/42484/31584 +f 42466/42483/31583 42465/42482/31582 42467/42484/31584 +f 42466/42483/31583 42467/42484/31584 42468/42485/31585 +f 42468/42485/31585 42467/42484/31584 42469/42486/31586 +f 42468/42485/31585 42469/42486/31586 42470/42487/31587 +f 42467/42484/31584 42422/42439/31540 42424/42441/31542 +f 42467/42484/31584 42424/42441/31542 42469/42486/31586 +f 42469/42486/31586 42424/42441/31542 42428/42445/31546 +f 42469/42486/31586 42428/42445/31546 42471/42488/31588 +f 42470/42487/31587 42469/42486/31586 42471/42488/31588 +f 42470/42487/31587 42471/42488/31588 42472/42489/31589 +f 42473/42490/31590 42474/42491/31590 42475/42492/31590 +f 42473/42490/31590 42475/42492/31590 42476/42493/31591 +f 42477/42494/31592 42478/42495/31593 42479/42496/31592 +f 42477/42494/31592 42479/42496/31592 42480/42497/31592 +f 42481/42498/31594 42482/42499/31595 42483/42500/31596 +f 42481/42498/31594 42483/42500/31596 42484/42501/31594 +f 42485/42502/31597 42486/42503/31597 42487/42504/31597 +f 42485/42502/31597 42487/42504/31597 42488/42505/31598 +f 42489/42506/31599 42490/42507/31600 42491/42508/31601 +f 42489/42506/31599 42491/42508/31601 42492/42509/31602 +f 42490/42507/31600 42370/42387/31494 42439/42456/31557 +f 42490/42507/31600 42439/42456/31557 42491/42508/31601 +f 42491/42508/31601 42439/42456/31557 42441/42458/31559 +f 42491/42508/31601 42441/42458/31559 42493/42510/31603 +f 42492/42509/31602 42491/42508/31601 42493/42510/31603 +f 42492/42509/31602 42493/42510/31603 42494/42511/31604 +f 42494/42511/31604 42493/42510/31603 42495/42512/31605 +f 42494/42511/31604 42495/42512/31605 42496/42513/31606 +f 42493/42510/31603 42441/42458/31559 42443/42460/31561 +f 42493/42510/31603 42443/42460/31561 42495/42512/31605 +f 42495/42512/31605 42443/42460/31561 42445/42462/31563 +f 42495/42512/31605 42445/42462/31563 42497/42514/31607 +f 42496/42513/31606 42495/42512/31605 42497/42514/31607 +f 42496/42513/31606 42497/42514/31607 42433/42450/31551 +f 42472/42489/31589 42471/42488/31588 42498/42515/31608 +f 42472/42489/31589 42498/42515/31608 42499/42516/31609 +f 42471/42488/31588 42428/42445/31546 42459/42476/31576 +f 42471/42488/31588 42459/42476/31576 42498/42515/31608 +f 42498/42515/31608 42459/42476/31576 42463/42480/31580 +f 42498/42515/31608 42463/42480/31580 42500/42517/31610 +f 42499/42516/31609 42498/42515/31608 42500/42517/31610 +f 42499/42516/31609 42500/42517/31610 42501/42518/31611 +f 42409/42426/31527 42502/42519/31612 42503/42520/31613 +f 42409/42426/31527 42503/42520/31613 42410/42427/31528 +f 42502/42519/31612 42429/42446/31547 42432/42449/31550 +f 42502/42519/31612 42432/42449/31550 42503/42520/31613 +f 42503/42520/31613 42432/42449/31550 42437/42454/31555 +f 42503/42520/31613 42437/42454/31555 42504/42521/31614 +f 42410/42427/31528 42503/42520/31613 42504/42521/31614 +f 42410/42427/31528 42504/42521/31614 42411/42428/31529 +f 42409/42426/31527 42406/42423/31524 42505/42522/31615 +f 42409/42426/31527 42505/42522/31615 42506/42523/31616 +f 42406/42423/31524 42405/42422/31523 42466/42483/31583 +f 42406/42423/31524 42466/42483/31583 42505/42522/31615 +f 42505/42522/31615 42466/42483/31583 42468/42485/31585 +f 42505/42522/31615 42468/42485/31585 42507/42524/31617 +f 42506/42523/31616 42505/42522/31615 42507/42524/31617 +f 42506/42523/31616 42507/42524/31617 42508/42525/31618 +f 42508/42525/31618 42507/42524/31617 42509/42526/31619 +f 42508/42525/31618 42509/42526/31619 42510/42527/31620 +f 42507/42524/31617 42468/42485/31585 42470/42487/31587 +f 42507/42524/31617 42470/42487/31587 42509/42526/31619 +f 42509/42526/31619 42470/42487/31587 42472/42489/31589 +f 42509/42526/31619 42472/42489/31589 42511/42528/31621 +f 42510/42527/31620 42509/42526/31619 42511/42528/31621 +f 42510/42527/31620 42511/42528/31621 42512/42529/31622 +f 42513/42530/31623 42514/42531/31624 42515/42532/31625 +f 42513/42530/31623 42515/42532/31625 42516/42533/31626 +f 42514/42531/31624 42517/42534/31627 42518/42535/31628 +f 42514/42531/31624 42518/42535/31628 42515/42532/31625 +f 42515/42532/31625 42518/42535/31628 42519/42536/31629 +f 42515/42532/31625 42519/42536/31629 42520/42537/31630 +f 42516/42533/31626 42515/42532/31625 42520/42537/31630 +f 42516/42533/31626 42520/42537/31630 42521/42538/31631 +f 42521/42538/31631 42520/42537/31630 42522/42539/31632 +f 42521/42538/31631 42522/42539/31632 42523/42540/31633 +f 42520/42537/31630 42519/42536/31629 42524/42541/31634 +f 42520/42537/31630 42524/42541/31634 42522/42539/31632 +f 42522/42539/31632 42524/42541/31634 42525/42542/31635 +f 42522/42539/31632 42525/42542/31635 42526/42543/31636 +f 42523/42540/31633 42522/42539/31632 42526/42543/31636 +f 42523/42540/31633 42526/42543/31636 42527/42544/31637 +f 42527/42544/31637 42526/42543/31636 42528/42545/31638 +f 42527/42544/31637 42528/42545/31638 42529/42546/31639 +f 42526/42543/31636 42525/42542/31635 42530/42547/31640 +f 42526/42543/31636 42530/42547/31640 42528/42545/31638 +f 42528/42545/31638 42530/42547/31640 42531/42548/31641 +f 42528/42545/31638 42531/42548/31641 42532/42549/31642 +f 42529/42546/31639 42528/42545/31638 42532/42549/31642 +f 42529/42546/31639 42532/42549/31642 42533/42550/31643 +f 42533/42550/31643 42532/42549/31642 42534/42551/31644 +f 42533/42550/31643 42534/42551/31644 42535/42552/31645 +f 42532/42549/31642 42531/42548/31641 42536/42553/31646 +f 42532/42549/31642 42536/42553/31646 42534/42551/31644 +f 42534/42551/31644 42536/42553/31646 42537/42554/31647 +f 42534/42551/31644 42537/42554/31647 42538/42555/31648 +f 42535/42552/31645 42534/42551/31644 42538/42555/31648 +f 42535/42552/31645 42538/42555/31648 42539/42556/31649 +f 42539/42556/31649 42538/42555/31648 42540/42557/31650 +f 42539/42556/31649 42540/42557/31650 42541/42558/31651 +f 42538/42555/31648 42537/42554/31647 42542/42559/31652 +f 42538/42555/31648 42542/42559/31652 42540/42557/31650 +f 42540/42557/31650 42542/42559/31652 42543/42560/31653 +f 42540/42557/31650 42543/42560/31653 42544/42561/31654 +f 42541/42558/31651 42540/42557/31650 42544/42561/31654 +f 42541/42558/31651 42544/42561/31654 42545/42562/31655 +f 42545/42562/31655 42544/42561/31654 42546/42563/31656 +f 42545/42562/31655 42546/42563/31656 42547/42564/31657 +f 42544/42561/31654 42543/42560/31653 42548/42565/31658 +f 42544/42561/31654 42548/42565/31658 42546/42563/31656 +f 42546/42563/31656 42548/42565/31658 42549/42566/31659 +f 42546/42563/31656 42549/42566/31659 42550/42567/31660 +f 42547/42564/31657 42546/42563/31656 42550/42567/31660 +f 42547/42564/31657 42550/42567/31660 42551/42568/31661 +f 42551/42568/31661 42550/42567/31660 42552/42569/31662 +f 42551/42568/31661 42552/42569/31662 42553/42570/31663 +f 42550/42567/31660 42549/42566/31659 42554/42571/31664 +f 42550/42567/31660 42554/42571/31664 42552/42569/31662 +f 42552/42569/31662 42554/42571/31664 42555/42572/31665 +f 42552/42569/31662 42555/42572/31665 42556/42573/31666 +f 42553/42570/31663 42552/42569/31662 42556/42573/31666 +f 42553/42570/31663 42556/42573/31666 42557/42574/31667 +f 42265/42311/31414 42558/42575/31668 42559/42576/31669 +f 42265/42311/31414 42559/42576/31669 42266/42312/31415 +f 42558/42575/31668 42560/42577/31670 42561/42578/31671 +f 42558/42575/31668 42561/42578/31671 42559/42576/31669 +f 42559/42576/31669 42561/42578/31671 42562/42579/31672 +f 42559/42576/31669 42562/42579/31672 42563/42580/31673 +f 42266/42312/31415 42559/42576/31669 42563/42580/31673 +f 42266/42312/31415 42563/42580/31673 42267/42313/31416 +f 42267/42313/31416 42563/42580/31673 42564/42581/31674 +f 42267/42313/31416 42564/42581/31674 42272/42318/31421 +f 42563/42580/31673 42562/42579/31672 42565/42582/31675 +f 42563/42580/31673 42565/42582/31675 42564/42581/31674 +f 42564/42581/31674 42565/42582/31675 42566/42583/31676 +f 42564/42581/31674 42566/42583/31676 42567/42584/31677 +f 42272/42318/31421 42564/42581/31674 42567/42584/31677 +f 42272/42318/31421 42567/42584/31677 42273/42319/31422 +f 42273/42319/31422 42567/42584/31677 42568/42585/31678 +f 42273/42319/31422 42568/42585/31678 42278/42324/31427 +f 42567/42584/31677 42566/42583/31676 42569/42586/31679 +f 42567/42584/31677 42569/42586/31679 42568/42585/31678 +f 42568/42585/31678 42569/42586/31679 42570/42587/31680 +f 42568/42585/31678 42570/42587/31680 42571/42588/31681 +f 42278/42324/31427 42568/42585/31678 42571/42588/31681 +f 42278/42324/31427 42571/42588/31681 42279/42325/31428 +f 42279/42325/31428 42571/42588/31681 42572/42589/31682 +f 42279/42325/31428 42572/42589/31682 42284/42330/31433 +f 42571/42588/31681 42570/42587/31680 42573/42590/31683 +f 42571/42588/31681 42573/42590/31683 42572/42589/31682 +f 42572/42589/31682 42573/42590/31683 42574/42591/31684 +f 42572/42589/31682 42574/42591/31684 42575/42592/31685 +f 42284/42330/31433 42572/42589/31682 42575/42592/31685 +f 42284/42330/31433 42575/42592/31685 42285/42331/31434 +f 42285/42331/31434 42575/42592/31685 42576/42593/31686 +f 42285/42331/31434 42576/42593/31686 42290/42336/31439 +f 42575/42592/31685 42574/42591/31684 42577/42594/31687 +f 42575/42592/31685 42577/42594/31687 42576/42593/31686 +f 42576/42593/31686 42577/42594/31687 42578/42595/31688 +f 42576/42593/31686 42578/42595/31688 42579/42596/31689 +f 42290/42336/31439 42576/42593/31686 42579/42596/31689 +f 42290/42336/31439 42579/42596/31689 42291/42337/31440 +f 42291/42337/31440 42579/42596/31689 42580/42597/31690 +f 42291/42337/31440 42580/42597/31690 42296/42342/31445 +f 42579/42596/31689 42578/42595/31688 42581/42598/31691 +f 42579/42596/31689 42581/42598/31691 42580/42597/31690 +f 42580/42597/31690 42581/42598/31691 42582/42599/31692 +f 42580/42597/31690 42582/42599/31692 42583/42600/31693 +f 42296/42342/31445 42580/42597/31690 42583/42600/31693 +f 42296/42342/31445 42583/42600/31693 42297/42343/31446 +f 42297/42343/31446 42583/42600/31693 42584/42601/31694 +f 42297/42343/31446 42584/42601/31694 42302/42348/31451 +f 42583/42600/31693 42582/42599/31692 42585/42602/31695 +f 42583/42600/31693 42585/42602/31695 42584/42601/31694 +f 42584/42601/31694 42585/42602/31695 42586/42603/31696 +f 42584/42601/31694 42586/42603/31696 42587/42604/31697 +f 42302/42348/31451 42584/42601/31694 42587/42604/31697 +f 42302/42348/31451 42587/42604/31697 42303/42349/31452 +f 42588/42605/31698 42589/42606/31699 42590/42607/31700 +f 42588/42605/31698 42590/42607/31700 42591/42608/31701 +f 42589/42606/31699 42592/42609/31702 42593/42610/31703 +f 42589/42606/31699 42593/42610/31703 42590/42607/31700 +f 42590/42607/31700 42593/42610/31703 42594/42611/31704 +f 42590/42607/31700 42594/42611/31704 42595/42612/31705 +f 42591/42608/31701 42590/42607/31700 42595/42612/31705 +f 42591/42608/31701 42595/42612/31705 42596/42613/31706 +f 42597/42614/31707 42598/42615/31708 42599/42616/31709 +f 42597/42614/31707 42599/42616/31709 42600/42617/31710 +f 42598/42615/31708 42601/42618/31711 42602/42619/31712 +f 42598/42615/31708 42602/42619/31712 42599/42616/31709 +f 42599/42616/31709 42602/42619/31712 42592/42609/31702 +f 42599/42616/31709 42592/42609/31702 42589/42606/31699 +f 42600/42617/31710 42599/42616/31709 42589/42606/31699 +f 42600/42617/31710 42589/42606/31699 42588/42605/31698 +f 42603/42620/31713 42604/42621/31714 42605/42622/31715 +f 42603/42620/31713 42605/42622/31715 42606/42623/31716 +f 42604/42621/31714 42607/42624/31717 42608/42625/31718 +f 42604/42621/31714 42608/42625/31718 42605/42622/31715 +f 42605/42622/31715 42608/42625/31718 42601/42618/31711 +f 42605/42622/31715 42601/42618/31711 42598/42615/31708 +f 42606/42623/31716 42605/42622/31715 42598/42615/31708 +f 42606/42623/31716 42598/42615/31708 42597/42614/31707 +f 42609/42626/31719 42610/42627/31720 42611/42628/31721 +f 42609/42626/31719 42611/42628/31721 42612/42629/31722 +f 42610/42627/31720 42613/42630/31723 42614/42631/31724 +f 42610/42627/31720 42614/42631/31724 42611/42628/31721 +f 42611/42628/31721 42614/42631/31724 42607/42624/31717 +f 42611/42628/31721 42607/42624/31717 42604/42621/31714 +f 42612/42629/31722 42611/42628/31721 42604/42621/31714 +f 42612/42629/31722 42604/42621/31714 42603/42620/31713 +f 42615/42632/31698 42616/42633/31699 42617/42634/31725 +f 42615/42632/31698 42617/42634/31725 42618/42635/31726 +f 42616/42633/31699 42619/42636/31727 42620/42637/31728 +f 42616/42633/31699 42620/42637/31728 42617/42634/31725 +f 42617/42634/31725 42620/42637/31728 42613/42630/31723 +f 42617/42634/31725 42613/42630/31723 42610/42627/31720 +f 42618/42635/31726 42617/42634/31725 42610/42627/31720 +f 42618/42635/31726 42610/42627/31720 42609/42626/31719 +f 42621/42638/31729 42622/42639/31730 42623/42640/31731 +f 42621/42638/31729 42623/42640/31731 42624/42641/31732 +f 42622/42639/31730 42625/42642/31733 42626/42643/31734 +f 42622/42639/31730 42626/42643/31734 42623/42640/31731 +f 42623/42640/31731 42626/42643/31734 42619/42636/31727 +f 42623/42640/31731 42619/42636/31727 42616/42633/31699 +f 42624/42641/31732 42623/42640/31731 42616/42633/31699 +f 42624/42641/31732 42616/42633/31699 42615/42632/31698 +f 42627/42644/31735 42628/42645/31736 42629/42646/31737 +f 42627/42644/31735 42629/42646/31737 42630/42647/31738 +f 42628/42645/31736 42631/42648/31739 42632/42649/31740 +f 42628/42645/31736 42632/42649/31740 42629/42646/31737 +f 42629/42646/31737 42632/42649/31740 42625/42642/31733 +f 42629/42646/31737 42625/42642/31733 42622/42639/31730 +f 42630/42647/31738 42629/42646/31737 42622/42639/31730 +f 42630/42647/31738 42622/42639/31730 42621/42638/31729 +f 42633/42650/31741 42634/42651/31742 42635/42652/31743 +f 42633/42650/31741 42635/42652/31743 42636/42653/31744 +f 42634/42651/31742 42637/42654/31745 42638/42655/31746 +f 42634/42651/31742 42638/42655/31746 42635/42652/31743 +f 42639/42656/31747 42640/42657/31748 42641/42658/31749 +f 42639/42656/31747 42641/42658/31749 42642/42659/31750 +f 42643/42660/31744 42639/42656/31747 42642/42659/31750 +f 42643/42660/31744 42642/42659/31750 42644/42661/31751 +f 42645/42662/31752 42646/42663/31753 42647/42664/31754 +f 42645/42662/31752 42647/42664/31754 42648/42665/31755 +f 42646/42663/31753 42178/42224/31331 42181/42227/31334 +f 42646/42663/31753 42181/42227/31334 42647/42664/31754 +f 42649/42666/31754 42650/42667/31340 42651/42668/31341 +f 42649/42666/31754 42651/42668/31341 42652/42669/31756 +f 42653/42670/31757 42649/42666/31754 42652/42669/31756 +f 42653/42670/31757 42652/42669/31756 42654/42671/31758 +f 42655/42672/31759 42656/42673/31760 42657/42674/31761 +f 42655/42672/31759 42657/42674/31761 42658/42675/31762 +f 42656/42673/31760 42190/42236/31342 42659/42676/31763 +f 42656/42673/31760 42659/42676/31763 42657/42674/31761 +f 42657/42674/31761 42659/42676/31763 42660/42677/31764 +f 42657/42674/31761 42660/42677/31764 42661/42678/31765 +f 42658/42675/31762 42657/42674/31761 42661/42678/31765 +f 42658/42675/31762 42661/42678/31765 42662/42679/31766 +f 42663/42680/31767 42664/42681/31768 42665/42682/31769 +f 42663/42680/31767 42665/42682/31769 42666/42683/31770 +f 42664/42681/31768 42667/42684/31771 42668/42685/31772 +f 42664/42681/31768 42668/42685/31772 42665/42682/31769 +f 42665/42682/31769 42668/42685/31772 42637/42654/31745 +f 42665/42682/31769 42637/42654/31745 42634/42651/31742 +f 42666/42683/31770 42665/42682/31769 42634/42651/31742 +f 42666/42683/31770 42634/42651/31742 42633/42650/31741 +f 42669/42686/31773 42670/42687/31774 42671/42688/31775 +f 42669/42686/31773 42671/42688/31775 42672/42689/31776 +f 42670/42687/31774 42663/42680/31767 42666/42683/31770 +f 42670/42687/31774 42666/42683/31770 42671/42688/31775 +f 42671/42688/31775 42666/42683/31770 42633/42650/31741 +f 42671/42688/31775 42633/42650/31741 42673/42690/31777 +f 42672/42689/31776 42671/42688/31775 42673/42690/31777 +f 42672/42689/31776 42673/42690/31777 42674/42691/31778 +f 42675/42692/31779 42676/42693/31780 42677/42694/31781 +f 42675/42692/31779 42677/42694/31781 42678/42695/31782 +f 42676/42693/31780 42669/42686/31773 42672/42689/31776 +f 42676/42693/31780 42672/42689/31776 42677/42694/31781 +f 42677/42694/31781 42672/42689/31776 42674/42691/31778 +f 42677/42694/31781 42674/42691/31778 42679/42696/31783 +f 42678/42695/31782 42677/42694/31781 42679/42696/31783 +f 42678/42695/31782 42679/42696/31783 42680/42697/31784 +f 42681/42698/31785 42682/42699/31786 42683/42700/31787 +f 42681/42698/31785 42683/42700/31787 42684/42701/31788 +f 42682/42699/31786 42685/42702/31789 42686/42703/31790 +f 42682/42699/31786 42686/42703/31790 42683/42700/31787 +f 42683/42700/31787 42686/42703/31790 42687/42704/31791 +f 42683/42700/31787 42687/42704/31791 42688/42705/31792 +f 42684/42701/31788 42683/42700/31787 42688/42705/31792 +f 42684/42701/31788 42688/42705/31792 42689/42706/31793 +f 42667/42684/31771 42690/42707/31794 42691/42708/31795 +f 42667/42684/31771 42691/42708/31795 42668/42685/31772 +f 42690/42707/31794 42692/42709/31796 42693/42710/31797 +f 42690/42707/31794 42693/42710/31797 42691/42708/31795 +f 42691/42708/31795 42693/42710/31797 42694/42711/31798 +f 42691/42708/31795 42694/42711/31798 42695/42712/31799 +f 42668/42685/31772 42691/42708/31795 42695/42712/31799 +f 42668/42685/31772 42695/42712/31799 42637/42654/31745 +f 42645/42662/31752 42696/42713/31800 42697/42714/31801 +f 42645/42662/31752 42697/42714/31801 42646/42663/31753 +f 42696/42713/31800 42698/42715/31802 42699/42716/31803 +f 42696/42713/31800 42699/42716/31803 42697/42714/31801 +f 42697/42714/31801 42699/42716/31803 42700/42717/31804 +f 42697/42714/31801 42700/42717/31804 42701/42718/31805 +f 42646/42663/31753 42697/42714/31801 42701/42718/31805 +f 42646/42663/31753 42701/42718/31805 42178/42224/31331 +f 42702/42719/31373 42703/42720/31806 42704/42721/31807 +f 42702/42719/31373 42704/42721/31807 42705/42722/31808 +f 42703/42720/31806 42706/42723/31809 42707/42724/31810 +f 42703/42720/31806 42707/42724/31810 42704/42721/31807 +f 42704/42721/31807 42707/42724/31810 42708/42725/31811 +f 42704/42721/31807 42708/42725/31811 42709/42726/31812 +f 42705/42722/31808 42704/42721/31807 42709/42726/31812 +f 42705/42722/31808 42709/42726/31812 42710/42727/31813 +f 42711/42728/31362 42712/42729/31361 42713/42730/31814 +f 42711/42728/31362 42713/42730/31814 42714/42731/31815 +f 42712/42729/31361 42715/42732/31816 42716/42733/31817 +f 42712/42729/31361 42716/42733/31817 42713/42730/31814 +f 42713/42730/31814 42716/42733/31817 42717/42734/31818 +f 42713/42730/31814 42717/42734/31818 42718/42735/31819 +f 42714/42731/31815 42713/42730/31814 42718/42735/31819 +f 42714/42731/31815 42718/42735/31819 42719/42736/31820 +f 42715/42732/31816 42720/42737/31368 42721/42738/31821 +f 42715/42732/31816 42721/42738/31821 42716/42733/31817 +f 42720/42737/31368 42722/42739/31367 42723/42740/31822 +f 42720/42737/31368 42723/42740/31822 42721/42738/31821 +f 42721/42738/31821 42723/42740/31822 42724/42741/31823 +f 42721/42738/31821 42724/42741/31823 42725/42742/31824 +f 42716/42733/31817 42721/42738/31821 42725/42742/31824 +f 42716/42733/31817 42725/42742/31824 42717/42734/31818 +f 42722/42739/31367 42726/42743/31825 42727/42744/31826 +f 42722/42739/31367 42727/42744/31826 42723/42740/31822 +f 42726/42743/31825 42702/42719/31373 42705/42722/31808 +f 42726/42743/31825 42705/42722/31808 42727/42744/31826 +f 42727/42744/31826 42705/42722/31808 42710/42727/31813 +f 42727/42744/31826 42710/42727/31813 42728/42745/31827 +f 42723/42740/31822 42727/42744/31826 42728/42745/31827 +f 42723/42740/31822 42728/42745/31827 42724/42741/31823 +f 42729/42746/31828 42730/42747/31829 42731/42748/31830 +f 42729/42746/31828 42731/42748/31830 42732/42749/31831 +f 42730/42747/31829 42551/42568/31661 42553/42570/31663 +f 42730/42747/31829 42553/42570/31663 42731/42748/31830 +f 42731/42748/31830 42553/42570/31663 42557/42574/31667 +f 42731/42748/31830 42557/42574/31667 42733/42750/31832 +f 42732/42749/31831 42731/42748/31830 42733/42750/31832 +f 42732/42749/31831 42733/42750/31832 42734/42751/31833 +f 42735/42752/31834 42736/42753/31835 42737/42754/31836 +f 42735/42752/31834 42737/42754/31836 42738/42755/31837 +f 42736/42753/31835 42545/42562/31655 42547/42564/31657 +f 42736/42753/31835 42547/42564/31657 42737/42754/31836 +f 42737/42754/31836 42547/42564/31657 42551/42568/31661 +f 42737/42754/31836 42551/42568/31661 42730/42747/31829 +f 42738/42755/31837 42737/42754/31836 42730/42747/31829 +f 42738/42755/31837 42730/42747/31829 42729/42746/31828 +f 42739/42756/31838 42740/42757/31839 42741/42758/31840 +f 42739/42756/31838 42741/42758/31840 42742/42759/31841 +f 42740/42757/31839 42539/42556/31649 42541/42558/31651 +f 42740/42757/31839 42541/42558/31651 42741/42758/31840 +f 42741/42758/31840 42541/42558/31651 42545/42562/31655 +f 42741/42758/31840 42545/42562/31655 42736/42753/31835 +f 42742/42759/31841 42741/42758/31840 42736/42753/31835 +f 42742/42759/31841 42736/42753/31835 42735/42752/31834 +f 42743/42760/31842 42744/42761/31843 42745/42762/31844 +f 42743/42760/31842 42745/42762/31844 42746/42763/31845 +f 42744/42761/31843 42533/42550/31643 42535/42552/31645 +f 42744/42761/31843 42535/42552/31645 42745/42762/31844 +f 42745/42762/31844 42535/42552/31645 42539/42556/31649 +f 42745/42762/31844 42539/42556/31649 42740/42757/31839 +f 42746/42763/31845 42745/42762/31844 42740/42757/31839 +f 42746/42763/31845 42740/42757/31839 42739/42756/31838 +f 42747/42764/31846 42748/42765/31847 42749/42766/31848 +f 42747/42764/31846 42749/42766/31848 42750/42767/31849 +f 42748/42765/31847 42527/42544/31637 42529/42546/31639 +f 42748/42765/31847 42529/42546/31639 42749/42766/31848 +f 42749/42766/31848 42529/42546/31639 42533/42550/31643 +f 42749/42766/31848 42533/42550/31643 42744/42761/31843 +f 42750/42767/31849 42749/42766/31848 42744/42761/31843 +f 42750/42767/31849 42744/42761/31843 42743/42760/31842 +f 42751/42768/31850 42752/42769/31851 42753/42770/31852 +f 42751/42768/31850 42753/42770/31852 42754/42771/31853 +f 42752/42769/31851 42521/42538/31631 42523/42540/31633 +f 42752/42769/31851 42523/42540/31633 42753/42770/31852 +f 42753/42770/31852 42523/42540/31633 42527/42544/31637 +f 42753/42770/31852 42527/42544/31637 42748/42765/31847 +f 42754/42771/31853 42753/42770/31852 42748/42765/31847 +f 42754/42771/31853 42748/42765/31847 42747/42764/31846 +f 42755/42772/31854 42756/42773/31855 42757/42774/31856 +f 42755/42772/31854 42757/42774/31856 42758/42775/31857 +f 42756/42773/31855 42513/42530/31623 42516/42533/31626 +f 42756/42773/31855 42516/42533/31626 42757/42774/31856 +f 42757/42774/31856 42516/42533/31626 42521/42538/31631 +f 42757/42774/31856 42521/42538/31631 42752/42769/31851 +f 42758/42775/31857 42757/42774/31856 42752/42769/31851 +f 42758/42775/31857 42752/42769/31851 42751/42768/31850 +f 42759/42776/31858 42760/42777/31859 42761/42778/31860 +f 42759/42776/31858 42761/42778/31860 42762/42779/31861 +f 42760/42777/31859 42763/42780/31862 42764/42781/31863 +f 42760/42777/31859 42764/42781/31863 42761/42778/31860 +f 42761/42778/31860 42764/42781/31863 42142/42188/31295 +f 42761/42778/31860 42142/42188/31295 42240/42286/31390 +f 42762/42779/31861 42761/42778/31860 42240/42286/31390 +f 42762/42779/31861 42240/42286/31390 42236/42282/31386 +f 42765/42782/31864 42766/42783/31865 42767/42784/31866 +f 42765/42782/31864 42767/42784/31866 42768/42785/31867 +f 42766/42783/31865 42759/42776/31858 42762/42779/31861 +f 42766/42783/31865 42762/42779/31861 42767/42784/31866 +f 42767/42784/31866 42762/42779/31861 42236/42282/31386 +f 42767/42784/31866 42236/42282/31386 42234/42280/31384 +f 42768/42785/31867 42767/42784/31866 42234/42280/31384 +f 42768/42785/31867 42234/42280/31384 42229/42275/31379 +f 42769/42786/31868 42770/42787/31869 42771/42788/31870 +f 42769/42786/31868 42771/42788/31870 42772/42789/31871 +f 42770/42787/31869 42765/42782/31864 42768/42785/31867 +f 42770/42787/31869 42768/42785/31867 42771/42788/31870 +f 42771/42788/31870 42768/42785/31867 42229/42275/31379 +f 42771/42788/31870 42229/42275/31379 42226/42272/31376 +f 42772/42789/31871 42771/42788/31870 42226/42272/31376 +f 42772/42789/31871 42226/42272/31376 42225/42271/31375 +f 42773/42790/31872 42774/42791/31873 42775/42792/31874 +f 42773/42790/31872 42775/42792/31874 42776/42793/31875 +f 42774/42791/31873 42160/42206/31313 42163/42209/31316 +f 42774/42791/31873 42163/42209/31316 42775/42792/31874 +f 42775/42792/31874 42163/42209/31316 42168/42214/31321 +f 42775/42792/31874 42168/42214/31321 42777/42794/31876 +f 42776/42793/31875 42775/42792/31874 42777/42794/31876 +f 42776/42793/31875 42777/42794/31876 42778/42795/31877 +f 42763/42780/31862 42779/42796/31878 42780/42797/31879 +f 42763/42780/31862 42780/42797/31879 42764/42781/31863 +f 42779/42796/31878 42781/42798/31880 42782/42799/31881 +f 42779/42796/31878 42782/42799/31881 42780/42797/31879 +f 42780/42797/31879 42782/42799/31881 42146/42192/31299 +f 42780/42797/31879 42146/42192/31299 42143/42189/31296 +f 42764/42781/31863 42780/42797/31879 42143/42189/31296 +f 42764/42781/31863 42143/42189/31296 42142/42188/31295 +f 42783/42800/31882 42784/42801/31883 42785/42802/31884 +f 42783/42800/31882 42785/42802/31884 42786/42803/31885 +f 42784/42801/31883 42787/42804/31886 42788/42805/31887 +f 42784/42801/31883 42788/42805/31887 42785/42802/31884 +f 42785/42802/31884 42788/42805/31887 42513/42530/31623 +f 42785/42802/31884 42513/42530/31623 42756/42773/31855 +f 42786/42803/31885 42785/42802/31884 42756/42773/31855 +f 42786/42803/31885 42756/42773/31855 42755/42772/31854 +f 42789/42806/31888 42790/42807/31889 42791/42808/31890 +f 42789/42806/31888 42791/42808/31890 42792/42809/31891 +f 42790/42807/31889 42793/42810/31892 42794/42811/31893 +f 42790/42807/31889 42794/42811/31893 42791/42808/31890 +f 42791/42808/31890 42794/42811/31893 42631/42648/31739 +f 42791/42808/31890 42631/42648/31739 42628/42645/31736 +f 42792/42809/31891 42791/42808/31890 42628/42645/31736 +f 42792/42809/31891 42628/42645/31736 42627/42644/31735 +f 42787/42804/31886 42795/42812/31894 42796/42813/31895 +f 42787/42804/31886 42796/42813/31895 42788/42805/31887 +f 42795/42812/31894 42797/42814/31896 42798/42815/31897 +f 42795/42812/31894 42798/42815/31897 42796/42813/31895 +f 42796/42813/31895 42798/42815/31897 42517/42534/31627 +f 42796/42813/31895 42517/42534/31627 42514/42531/31624 +f 42788/42805/31887 42796/42813/31895 42514/42531/31624 +f 42788/42805/31887 42514/42531/31624 42513/42530/31623 +f 42799/42816/31383 42800/42817/31898 42801/42818/31899 +f 42799/42816/31383 42801/42818/31899 42802/42819/31900 +f 42800/42817/31898 42803/42820/31381 42804/42821/31901 +f 42800/42817/31898 42804/42821/31901 42801/42818/31899 +f 42801/42818/31899 42804/42821/31901 42805/42822/31902 +f 42801/42818/31899 42805/42822/31902 42806/42823/31565 +f 42802/42819/31900 42801/42818/31899 42806/42823/31565 +f 42802/42819/31900 42806/42823/31565 42807/42824/31564 +f 42803/42820/31381 42808/42825/31389 42809/42826/31903 +f 42803/42820/31381 42809/42826/31903 42804/42821/31901 +f 42808/42825/31389 42810/42827/31388 42811/42828/31904 +f 42808/42825/31389 42811/42828/31904 42809/42826/31903 +f 42809/42826/31903 42811/42828/31904 42812/42829/31905 +f 42809/42826/31903 42812/42829/31905 42813/42830/31906 +f 42804/42821/31901 42809/42826/31903 42813/42830/31906 +f 42804/42821/31901 42813/42830/31906 42805/42822/31902 +f 42810/42827/31388 42814/42831/31392 42815/42832/31907 +f 42810/42827/31388 42815/42832/31907 42811/42828/31904 +f 42814/42831/31392 42816/42833/31908 42817/42834/31909 +f 42814/42831/31392 42817/42834/31909 42815/42832/31907 +f 42815/42832/31907 42817/42834/31909 42818/42835/31910 +f 42815/42832/31907 42818/42835/31910 42819/42836/31911 +f 42811/42828/31904 42815/42832/31907 42819/42836/31911 +f 42811/42828/31904 42819/42836/31911 42812/42829/31905 +f 42305/42351/31454 42304/42350/31453 42820/42837/31912 +f 42305/42351/31454 42820/42837/31912 42821/42838/31913 +f 42304/42350/31453 42303/42349/31452 42822/42839/31914 +f 42304/42350/31453 42822/42839/31914 42820/42837/31912 +f 42820/42837/31912 42822/42839/31914 42133/42179/31286 +f 42820/42837/31912 42133/42179/31286 42258/42304/31407 +f 42821/42838/31913 42820/42837/31912 42258/42304/31407 +f 42821/42838/31913 42258/42304/31407 42254/42300/31403 +f 42335/42381/31479 42334/42380/31481 42823/42840/31915 +f 42335/42381/31479 42823/42840/31915 42824/42841/31916 +f 42334/42380/31481 42305/42351/31454 42821/42838/31913 +f 42334/42380/31481 42821/42838/31913 42823/42840/31915 +f 42823/42840/31915 42821/42838/31913 42254/42300/31403 +f 42823/42840/31915 42254/42300/31403 42252/42298/31401 +f 42824/42841/31916 42823/42840/31915 42252/42298/31401 +f 42824/42841/31916 42252/42298/31401 42247/42293/31397 +f 42365/42161/31275 42364/42160/31277 42825/42162/31489 +f 42364/42160/31277 42335/42381/31479 42824/42841/31916 +f 42364/42160/31277 42824/42841/31916 42825/42162/31489 +f 42825/42162/31489 42824/42841/31916 42247/42293/31397 +f 42825/42162/31489 42247/42293/31397 42244/42290/31394 +f 42826/42163/31269 42825/42162/31489 42244/42290/31394 +f 42826/42163/31269 42244/42290/31394 42243/42289/31393 +f 42303/42349/31452 42587/42604/31697 42827/42842/31917 +f 42303/42349/31452 42827/42842/31917 42822/42839/31914 +f 42587/42604/31697 42586/42603/31696 42828/42843/31918 +f 42587/42604/31697 42828/42843/31918 42827/42842/31917 +f 42827/42842/31917 42828/42843/31918 42137/42183/31290 +f 42827/42842/31917 42137/42183/31290 42134/42180/31287 +f 42822/42839/31914 42827/42842/31917 42134/42180/31287 +f 42822/42839/31914 42134/42180/31287 42133/42179/31286 +f 42734/42751/31833 42733/42750/31832 42829/42844/31919 +f 42734/42751/31833 42829/42844/31919 42830/42845/31920 +f 42733/42750/31832 42557/42574/31667 42831/42846/31921 +f 42733/42750/31832 42831/42846/31921 42829/42844/31919 +f 42829/42844/31919 42831/42846/31921 42160/42206/31313 +f 42829/42844/31919 42160/42206/31313 42774/42791/31873 +f 42830/42845/31920 42829/42844/31919 42774/42791/31873 +f 42830/42845/31920 42774/42791/31873 42773/42790/31872 +f 42596/42613/31706 42595/42612/31705 42832/42847/31922 +f 42596/42613/31706 42832/42847/31922 42833/42848/31923 +f 42595/42612/31705 42594/42611/31704 42834/42849/31924 +f 42595/42612/31705 42834/42849/31924 42832/42847/31922 +f 42832/42847/31922 42834/42849/31924 42685/42702/31789 +f 42832/42847/31922 42685/42702/31789 42682/42699/31786 +f 42833/42848/31923 42832/42847/31922 42682/42699/31786 +f 42833/42848/31923 42682/42699/31786 42681/42698/31785 +f 42835/42850/31925 42836/42851/31926 42837/42852/31927 +f 42835/42850/31925 42837/42852/31927 42838/42853/31928 +f 42836/42851/31926 42839/42854/31929 42840/42855/31930 +f 42836/42851/31926 42840/42855/31930 42837/42852/31927 +f 42837/42852/31927 42840/42855/31930 42560/42577/31670 +f 42837/42852/31927 42560/42577/31670 42558/42575/31668 +f 42838/42853/31928 42837/42852/31927 42558/42575/31668 +f 42838/42853/31928 42558/42575/31668 42265/42311/31414 +f 42841/42856/31931 42842/42857/31932 42843/42858/31933 +f 42841/42856/31931 42843/42858/31933 42844/42859/31934 +f 42842/42857/31932 42845/42860/31328 42846/42861/31935 +f 42842/42857/31932 42846/42861/31935 42843/42858/31933 +f 42843/42858/31933 42846/42861/31935 42306/42352/31455 +f 42843/42858/31933 42306/42352/31455 42337/42382/31483 +f 42844/42859/31934 42843/42858/31933 42337/42382/31483 +f 42844/42859/31934 42337/42382/31483 42336/42133/31482 +f 42845/42860/31328 42847/42862/31936 42848/42863/31937 +f 42845/42860/31328 42848/42863/31937 42846/42861/31935 +f 42847/42862/31936 42849/42864/31938 42850/42865/31939 +f 42847/42862/31936 42850/42865/31939 42848/42863/31937 +f 42848/42863/31937 42850/42865/31939 42261/42307/31410 +f 42848/42863/31937 42261/42307/31410 42307/42353/31456 +f 42846/42861/31935 42848/42863/31937 42307/42353/31456 +f 42846/42861/31935 42307/42353/31456 42306/42352/31455 +f 42849/42864/31938 42851/42866/31940 42852/42867/31941 +f 42849/42864/31938 42852/42867/31941 42850/42865/31939 +f 42851/42866/31940 42835/42850/31925 42838/42853/31928 +f 42851/42866/31940 42838/42853/31928 42852/42867/31941 +f 42852/42867/31941 42838/42853/31928 42265/42311/31414 +f 42852/42867/31941 42265/42311/31414 42262/42308/31411 +f 42850/42865/31939 42852/42867/31941 42262/42308/31411 +f 42850/42865/31939 42262/42308/31411 42261/42307/31410 +f 42433/42450/31551 42497/42514/31607 42853/42868/31942 +f 42433/42450/31551 42853/42868/31942 42434/42451/31552 +f 42497/42514/31607 42445/42462/31563 42854/42869/31943 +f 42497/42514/31607 42854/42869/31943 42853/42868/31942 +f 42853/42868/31942 42854/42869/31943 42855/42870/31944 +f 42853/42868/31942 42855/42870/31944 42856/42871/31945 +f 42434/42451/31552 42853/42868/31942 42856/42871/31945 +f 42434/42451/31552 42856/42871/31945 42435/42452/31553 +f 42418/42435/31536 42415/42432/31533 42857/42872/31946 +f 42418/42435/31536 42857/42872/31946 42858/42873/31947 +f 42415/42432/31533 42414/42431/31532 42859/42874/31948 +f 42415/42432/31533 42859/42874/31948 42857/42872/31946 +f 42857/42872/31946 42859/42874/31948 42860/42875/31949 +f 42857/42872/31946 42860/42875/31949 42861/42876/31950 +f 42858/42873/31947 42857/42872/31946 42861/42876/31950 +f 42858/42873/31947 42861/42876/31950 42862/42877/31951 +f 42414/42431/31532 42464/42481/31581 42863/42878/31952 +f 42414/42431/31532 42863/42878/31952 42859/42874/31948 +f 42464/42481/31581 42405/42422/31523 42408/42425/31526 +f 42464/42481/31581 42408/42425/31526 42863/42878/31952 +f 42863/42878/31952 42408/42425/31526 42413/42430/31531 +f 42863/42878/31952 42413/42430/31531 42864/42879/31953 +f 42859/42874/31948 42863/42878/31952 42864/42879/31953 +f 42859/42874/31948 42864/42879/31953 42860/42875/31949 +f 42557/42574/31667 42556/42573/31666 42865/42880/31954 +f 42557/42574/31667 42865/42880/31954 42831/42846/31921 +f 42556/42573/31666 42555/42572/31665 42866/42881/31955 +f 42556/42573/31666 42866/42881/31955 42865/42880/31954 +f 42865/42880/31954 42866/42881/31955 42164/42210/31317 +f 42865/42880/31954 42164/42210/31317 42161/42207/31314 +f 42831/42846/31921 42865/42880/31954 42161/42207/31314 +f 42831/42846/31921 42161/42207/31314 42160/42206/31313 +f 42867/42882/31665 42868/42883/31956 42869/42884/31957 +f 42867/42882/31665 42869/42884/31957 42870/42885/31958 +f 42868/42883/31956 42512/42529/31622 42871/42886/31959 +f 42868/42883/31956 42871/42886/31959 42869/42884/31957 +f 42869/42884/31957 42871/42886/31959 42204/42250/31354 +f 42869/42884/31957 42204/42250/31354 42872/42887/31960 +f 42870/42885/31958 42869/42884/31957 42872/42887/31960 +f 42870/42885/31958 42872/42887/31960 42873/42888/31961 +f 42874/42889/31962 42875/42890/31963 42876/42891/31964 +f 42874/42889/31962 42876/42891/31964 42877/42892/31965 +f 42875/42890/31963 42841/42856/31931 42844/42859/31934 +f 42875/42890/31963 42844/42859/31934 42876/42891/31964 +f 42876/42891/31964 42844/42859/31934 42336/42133/31482 +f 42876/42891/31964 42336/42133/31482 42878/42177/31285 +f 42877/42892/31965 42876/42891/31964 42878/42177/31285 +f 42877/42892/31965 42878/42177/31285 42879/42893/31966 +f 42880/42894/31967 42881/42164/31281 42882/42895/31281 +f 42880/42894/31967 42882/42895/31281 42883/42896/31968 +f 42881/42164/31281 42826/42163/31269 42882/42895/31281 +f 42882/42895/31281 42826/42163/31269 42243/42289/31393 +f 42882/42895/31281 42243/42289/31393 42884/42897/31969 +f 42883/42896/31968 42882/42895/31281 42884/42897/31969 +f 42883/42896/31968 42884/42897/31969 42885/42898/31970 +f 42886/42899/31971 42887/42900/31972 42888/42901/31973 +f 42886/42899/31971 42888/42901/31973 42889/42902/31897 +f 42887/42900/31972 42799/42816/31383 42802/42819/31900 +f 42887/42900/31972 42802/42819/31900 42888/42901/31973 +f 42888/42901/31973 42802/42819/31900 42807/42824/31564 +f 42888/42901/31973 42807/42824/31564 42890/42903/31974 +f 42889/42902/31897 42888/42901/31973 42890/42903/31974 +f 42889/42902/31897 42890/42903/31974 42891/42904/31975 +f 42892/42905/31976 42893/42906/31977 42894/42907/31978 +f 42892/42905/31976 42894/42907/31978 42895/42908/31883 +f 42893/42906/31977 42769/42786/31868 42772/42789/31871 +f 42893/42906/31977 42772/42789/31871 42894/42907/31978 +f 42894/42907/31978 42772/42789/31871 42225/42271/31375 +f 42894/42907/31978 42225/42271/31375 42896/42909/31979 +f 42895/42908/31883 42894/42907/31978 42896/42909/31979 +f 42895/42908/31883 42896/42909/31979 42897/42910/31886 +f 42898/42911/31980 42899/42912/31981 42900/42913/31982 +f 42898/42911/31980 42900/42913/31982 42901/42914/31983 +f 42899/42912/31981 42711/42728/31362 42714/42731/31815 +f 42899/42912/31981 42714/42731/31815 42900/42913/31982 +f 42900/42913/31982 42714/42731/31815 42719/42736/31820 +f 42900/42913/31982 42719/42736/31820 42902/42915/31984 +f 42901/42914/31983 42900/42913/31982 42902/42915/31984 +f 42901/42914/31983 42902/42915/31984 42903/42916/31321 +f 42904/42917/31985 42905/42918/31986 42906/42919/31987 +f 42904/42917/31985 42906/42919/31987 42907/42920/31988 +f 42905/42918/31986 42675/42692/31779 42678/42695/31782 +f 42905/42918/31986 42678/42695/31782 42906/42919/31987 +f 42906/42919/31987 42678/42695/31782 42680/42697/31784 +f 42906/42919/31987 42680/42697/31784 42908/42921/31989 +f 42907/42920/31988 42906/42919/31987 42908/42921/31989 +f 42907/42920/31988 42908/42921/31989 42909/42922/31791 +f 42910/42923/31888 42911/42924/31990 42912/42925/31991 +f 42910/42923/31888 42912/42925/31991 42913/42926/31992 +f 42911/42924/31990 42655/42672/31759 42658/42675/31762 +f 42911/42924/31990 42658/42675/31762 42912/42925/31991 +f 42912/42925/31991 42658/42675/31762 42662/42679/31766 +f 42912/42925/31991 42662/42679/31766 42914/42927/31993 +f 42913/42926/31992 42912/42925/31991 42914/42927/31993 +f 42913/42926/31992 42914/42927/31993 42915/42928/31994 +f 42916/42929/31659 42917/42930/31995 42918/42931/31996 +f 42916/42929/31659 42918/42931/31996 42919/42932/31997 +f 42917/42930/31995 42508/42525/31618 42510/42527/31620 +f 42917/42930/31995 42510/42527/31620 42918/42931/31996 +f 42918/42931/31996 42510/42527/31620 42512/42529/31622 +f 42918/42931/31996 42512/42529/31622 42868/42883/31956 +f 42919/42932/31997 42918/42931/31996 42868/42883/31956 +f 42919/42932/31997 42868/42883/31956 42867/42882/31665 +f 42920/42933/31998 42921/42934/31999 42922/42935/32000 +f 42920/42933/31998 42922/42935/32000 42923/42936/32001 +f 42921/42934/31999 42409/42426/31527 42506/42523/31616 +f 42921/42934/31999 42506/42523/31616 42922/42935/32000 +f 42922/42935/32000 42506/42523/31616 42508/42525/31618 +f 42922/42935/32000 42508/42525/31618 42917/42930/31995 +f 42923/42936/32001 42922/42935/32000 42917/42930/31995 +f 42923/42936/32001 42917/42930/31995 42916/42929/31659 +f 42924/42937/31647 42925/42938/32002 42926/42939/32003 +f 42924/42937/31647 42926/42939/32003 42927/42940/32004 +f 42925/42938/32002 42429/42446/31547 42502/42519/31612 +f 42925/42938/32002 42502/42519/31612 42926/42939/32003 +f 42926/42939/32003 42502/42519/31612 42409/42426/31527 +f 42926/42939/32003 42409/42426/31527 42921/42934/31999 +f 42927/42940/32004 42926/42939/32003 42921/42934/31999 +f 42927/42940/32004 42921/42934/31999 42920/42933/31998 +f 42928/42941/31641 42929/42942/32005 42930/42943/32006 +f 42928/42941/31641 42930/42943/32006 42931/42944/32007 +f 42929/42942/32005 42433/42450/31551 42430/42447/31548 +f 42929/42942/32005 42430/42447/31548 42930/42943/32006 +f 42930/42943/32006 42430/42447/31548 42429/42446/31547 +f 42930/42943/32006 42429/42446/31547 42925/42938/32002 +f 42931/42944/32007 42930/42943/32006 42925/42938/32002 +f 42931/42944/32007 42925/42938/32002 42924/42937/31647 +f 42932/42945/32008 42933/42946/32009 42934/42947/32010 +f 42932/42945/32008 42934/42947/32010 42935/42948/31640 +f 42933/42946/32009 42494/42511/31604 42496/42513/31606 +f 42933/42946/32009 42496/42513/31606 42934/42947/32010 +f 42934/42947/32010 42496/42513/31606 42433/42450/31551 +f 42934/42947/32010 42433/42450/31551 42929/42942/32005 +f 42935/42948/31640 42934/42947/32010 42929/42942/32005 +f 42935/42948/31640 42929/42942/32005 42928/42941/31641 +f 42936/42949/31629 42937/42950/32011 42938/42951/32012 +f 42936/42949/31629 42938/42951/32012 42939/42952/32013 +f 42937/42950/32011 42489/42506/31599 42492/42509/31602 +f 42937/42950/32011 42492/42509/31602 42938/42951/32012 +f 42938/42951/32012 42492/42509/31602 42494/42511/31604 +f 42938/42951/32012 42494/42511/31604 42933/42946/32009 +f 42939/42952/32013 42938/42951/32012 42933/42946/32009 +f 42939/42952/32013 42933/42946/32009 42932/42945/32008 +f 42891/42904/31975 42890/42903/31974 42940/42953/32014 +f 42891/42904/31975 42940/42953/32014 42941/42954/31628 +f 42890/42903/31974 42807/42824/31564 42942/42955/32015 +f 42890/42903/31974 42942/42955/32015 42940/42953/32014 +f 42940/42953/32014 42942/42955/32015 42489/42506/31599 +f 42940/42953/32014 42489/42506/31599 42937/42950/32011 +f 42941/42954/31628 42940/42953/32014 42937/42950/32011 +f 42941/42954/31628 42937/42950/32011 42936/42949/31629 +f 42943/42956/32016 42944/42165/31281 42945/42166/31281 +f 42943/42956/32016 42945/42166/31281 42946/42957/32017 +f 42944/42165/31281 42363/42159/31284 42945/42166/31281 +f 42945/42166/31281 42365/42161/31284 42881/42164/31281 +f 42946/42957/32017 42945/42166/31281 42881/42164/31281 +f 42946/42957/32017 42881/42164/31281 42880/42894/31967 +f 42947/42958/32018 42948/42167/31281 42949/42168/31281 +f 42947/42958/32018 42949/42168/31281 42950/42959/32019 +f 42948/42167/31281 42359/42155/31284 42949/42168/31281 +f 42949/42168/31281 42361/42157/31284 42944/42165/31281 +f 42950/42959/32019 42949/42168/31281 42944/42165/31281 +f 42950/42959/32019 42944/42165/31281 42943/42956/32016 +f 42951/42960/32020 42952/42169/31281 42953/42170/32021 +f 42951/42960/32020 42953/42170/32021 42954/42961/32022 +f 42952/42169/31281 42355/42151/31282 42953/42170/32021 +f 42953/42170/32021 42357/42153/31284 42948/42167/31281 +f 42954/42961/32022 42953/42170/32021 42948/42167/31281 +f 42954/42961/32022 42948/42167/31281 42947/42958/32018 +f 42955/42962/32023 42956/42171/31281 42957/42172/31281 +f 42955/42962/32023 42957/42172/31281 42958/42963/32024 +f 42956/42171/31281 42351/42147/31282 42957/42172/31281 +f 42957/42172/31281 42353/42149/31282 42952/42169/31281 +f 42958/42963/32024 42957/42172/31281 42952/42169/31281 +f 42958/42963/32024 42952/42169/31281 42951/42960/32020 +f 42959/42964/32025 42960/42173/31283 42961/42174/31281 +f 42959/42964/32025 42961/42174/31281 42962/42965/32026 +f 42960/42173/31283 42347/42143/31284 42961/42174/31281 +f 42961/42174/31281 42349/42145/31284 42956/42171/31281 +f 42962/42965/32026 42961/42174/31281 42956/42171/31281 +f 42962/42965/32026 42956/42171/31281 42955/42962/32023 +f 42963/42966/32027 42964/42175/31281 42965/42176/31281 +f 42963/42966/32027 42965/42176/31281 42966/42967/32028 +f 42964/42175/31281 42343/42139/31284 42965/42176/31281 +f 42965/42176/31281 42345/42141/31284 42960/42173/31283 +f 42966/42967/32028 42965/42176/31281 42960/42173/31283 +f 42966/42967/32028 42960/42173/31283 42959/42964/32025 +f 42879/42893/31966 42878/42177/31285 42967/42178/32021 +f 42879/42893/31966 42967/42178/32021 42968/42968/32029 +f 42878/42177/31285 42339/42135/31282 42967/42178/32021 +f 42967/42178/32021 42341/42137/31284 42964/42175/31281 +f 42968/42968/32029 42967/42178/32021 42964/42175/31281 +f 42968/42968/32029 42964/42175/31281 42963/42966/32027 +f 42885/42898/31970 42884/42897/31969 42969/42969/32030 +f 42885/42898/31970 42969/42969/32030 42970/42970/32031 +f 42884/42897/31969 42243/42289/31393 42246/42292/31396 +f 42884/42897/31969 42246/42292/31396 42969/42969/32030 +f 42969/42969/32030 42246/42292/31396 42251/42297/31400 +f 42969/42969/32030 42251/42297/31400 42971/42971/32032 +f 42970/42970/32031 42969/42969/32030 42971/42971/32032 +f 42970/42970/32031 42971/42971/32032 42972/42972/32033 +f 42897/42910/31886 42896/42909/31979 42973/42973/32034 +f 42897/42910/31886 42973/42973/32034 42974/42974/31894 +f 42896/42909/31979 42225/42271/31375 42228/42274/31378 +f 42896/42909/31979 42228/42274/31378 42973/42973/32034 +f 42973/42973/32034 42228/42274/31378 42233/42279/31383 +f 42973/42973/32034 42233/42279/31383 42975/42975/31972 +f 42974/42974/31894 42973/42973/32034 42975/42975/31972 +f 42974/42974/31894 42975/42975/31972 42976/42976/32035 +f 42873/42888/31961 42872/42887/31960 42977/42977/32036 +f 42873/42888/31961 42977/42977/32036 42978/42978/32037 +f 42872/42887/31960 42204/42250/31354 42207/42253/31357 +f 42872/42887/31960 42207/42253/31357 42977/42977/32036 +f 42977/42977/32036 42207/42253/31357 42212/42258/31362 +f 42977/42977/32036 42212/42258/31362 42979/42979/31981 +f 42978/42978/32037 42977/42977/32036 42979/42979/31981 +f 42978/42978/32037 42979/42979/31981 42980/42980/31980 +f 42981/42981/32038 42982/42982/32039 42983/42983/32040 +f 42981/42981/32038 42983/42983/32040 42984/42984/32041 +f 42982/42982/32039 42169/42215/31322 42172/42218/31325 +f 42982/42982/32039 42172/42218/31325 42983/42983/32040 +f 42983/42983/32040 42172/42218/31325 42177/42223/31330 +f 42983/42983/32040 42177/42223/31330 42985/42985/31963 +f 42984/42984/32041 42983/42983/32040 42985/42985/31963 +f 42984/42984/32041 42985/42985/31963 42986/42986/32042 +f 42987/42987/32043 42988/42988/32044 42989/42989/32045 +f 42987/42987/32043 42989/42989/32045 42990/42990/32046 +f 42988/42988/32044 42991/42991/32047 42992/42992/32048 +f 42988/42988/32044 42992/42992/32048 42989/42989/32045 +f 42989/42989/32045 42992/42992/32048 42993/42993/32049 +f 42989/42989/32045 42993/42993/32049 42994/42994/32050 +f 42990/42990/32046 42989/42989/32045 42994/42994/32050 +f 42990/42990/32046 42994/42994/32050 42374/42391/31498 +f 42995/42995/32051 42996/42996/32052 42997/42997/32053 +f 42995/42995/32051 42997/42997/32053 42998/42998/32054 +f 42996/42996/32052 42999/42999/32055 43000/43000/32056 +f 42996/42996/32052 43000/43000/32056 42997/42997/32053 +f 42997/42997/32053 43000/43000/32056 43001/43001/32057 +f 42997/42997/32053 43001/43001/32057 43002/43002/32058 +f 42998/42998/32054 42997/42997/32053 43002/43002/32058 +f 42998/42998/32054 43002/43002/32058 43003/43003/32059 +f 43003/43003/32059 43002/43002/32058 43004/43004/32060 +f 43003/43003/32059 43004/43004/32060 43005/43005/32061 +f 43002/43002/32058 43001/43001/32057 43006/43006/32062 +f 43002/43002/32058 43006/43006/32062 43004/43004/32060 +f 43004/43004/32060 43006/43006/32062 42862/42877/31951 +f 43004/43004/32060 42862/42877/31951 42861/42876/31950 +f 43005/43005/32061 43004/43004/32060 42861/42876/31950 +f 43005/43005/32061 42861/42876/31950 42860/42875/31949 +f 42454/42471/31571 43007/43007/32063 43008/43008/32064 +f 42454/42471/31571 43008/43008/32064 43009/43009/32065 +f 43007/43007/32063 42987/42987/32043 42990/42990/32046 +f 43007/43007/32063 42990/42990/32046 43008/43008/32064 +f 43008/43008/32064 42990/42990/32046 42374/42391/31498 +f 43008/43008/32064 42374/42391/31498 42373/42390/31497 +f 43009/43009/32065 43008/43008/32064 42373/42390/31497 +f 43009/43009/32065 42373/42390/31497 42372/42389/31496 +f 42855/42870/31944 43010/43010/32066 43011/43011/32067 +f 42855/42870/31944 43011/43011/32067 43012/43012/32068 +f 43010/43010/32066 42995/42995/32051 42998/42998/32054 +f 43010/43010/32066 42998/42998/32054 43011/43011/32067 +f 43011/43011/32067 42998/42998/32054 43003/43003/32059 +f 43011/43011/32067 43003/43003/32059 43013/43013/32069 +f 43012/43012/32068 43011/43011/32067 43013/43013/32069 +f 43012/43012/32068 43013/43013/32069 43014/43014/32070 +f 43014/43014/32070 43013/43013/32069 43015/43015/32071 +f 43014/43014/32070 43015/43015/32071 43016/43016/32072 +f 43013/43013/32069 43003/43003/32059 43005/43005/32061 +f 43013/43013/32069 43005/43005/32061 43015/43015/32071 +f 43015/43015/32071 43005/43005/32061 42860/42875/31949 +f 43015/43015/32071 42860/42875/31949 42864/42879/31953 +f 43016/43016/32072 43015/43015/32071 42864/42879/31953 +f 43016/43016/32072 42864/42879/31953 42413/42430/31531 +f 42457/42474/31574 42455/42472/31572 43017/43017/32073 +f 42457/42474/31574 43017/43017/32073 43018/43018/32074 +f 42455/42472/31572 42454/42471/31571 43009/43009/32065 +f 42455/42472/31572 43009/43009/32065 43017/43017/32073 +f 43017/43017/32073 43009/43009/32065 42372/42389/31496 +f 43017/43017/32073 42372/42389/31496 43019/43019/32075 +f 43018/43018/32074 43017/43017/32073 43019/43019/32075 +f 43018/43018/32074 43019/43019/32075 43020/43020/32076 +f 42435/42452/31553 42856/42871/31945 43021/43021/32077 +f 42435/42452/31553 43021/43021/32077 42436/42453/31554 +f 42856/42871/31945 42855/42870/31944 43012/43012/32068 +f 42856/42871/31945 43012/43012/32068 43021/43021/32077 +f 43021/43021/32077 43012/43012/32068 43014/43014/32070 +f 43021/43021/32077 43014/43014/32070 43022/43022/32078 +f 42436/42453/31554 43021/43021/32077 43022/43022/32078 +f 42436/42453/31554 43022/43022/32078 42437/42454/31555 +f 42437/42454/31555 43022/43022/32078 43023/43023/32079 +f 42437/42454/31555 43023/43023/32079 42504/42521/31614 +f 43022/43022/32078 43014/43014/32070 43016/43016/32072 +f 43022/43022/32078 43016/43016/32072 43023/43023/32079 +f 43023/43023/32079 43016/43016/32072 42413/42430/31531 +f 43023/43023/32079 42413/42430/31531 42412/42429/31530 +f 42504/42521/31614 43023/43023/32079 42412/42429/31530 +f 42504/42521/31614 42412/42429/31530 42411/42428/31529 +f 42463/42480/31580 42462/42479/31579 43024/43024/32080 +f 42463/42480/31580 43024/43024/32080 43025/43025/32081 +f 42462/42479/31579 42461/42478/31578 43026/43026/32082 +f 42462/42479/31579 43026/43026/32082 43024/43024/32080 +f 43024/43024/32080 43026/43026/32082 43027/43027/32083 +f 43024/43024/32080 43027/43027/32083 43028/43028/32084 +f 43025/43025/32081 43024/43024/32080 43028/43028/32084 +f 43025/43025/32081 43028/43028/32084 43029/43029/32085 +f 42501/42518/31611 42500/42517/31610 43030/43030/32086 +f 42501/42518/31611 43030/43030/32086 43031/43031/32087 +f 42500/42517/31610 42463/42480/31580 43025/43025/32081 +f 42500/42517/31610 43025/43025/32081 43030/43030/32086 +f 43030/43030/32086 43025/43025/32081 43029/43029/32085 +f 43030/43030/32086 43029/43029/32085 43032/43032/32088 +f 43031/43031/32087 43030/43030/32086 43032/43032/32088 +f 43031/43031/32087 43032/43032/32088 43033/43033/32089 +f 43034/43034/32090 43035/43035/32091 43036/43036/32092 +f 43034/43034/32090 43036/43036/32092 43037/43037/32093 +f 43035/43035/32091 42501/42518/31611 43031/43031/32087 +f 43035/43035/32091 43031/43031/32087 43036/43036/32092 +f 43036/43036/32092 43031/43031/32087 43033/43033/32089 +f 43036/43036/32092 43033/43033/32089 43038/43038/32094 +f 43037/43037/32093 43036/43036/32092 43038/43038/32094 +f 43037/43037/32093 43038/43038/32094 43039/43039/32095 +f 42450/42467/31568 43040/43040/32096 43041/43041/32097 +f 42450/42467/31568 43041/43041/32097 42451/42468/31569 +f 43040/43040/32096 43042/43042/31905 43043/43043/32098 +f 43040/43040/32096 43043/43043/32098 43041/43041/32097 +f 43044/43044/32099 43045/43045/32100 42987/42987/32043 +f 43044/43044/32099 42987/42987/32043 43007/43007/32063 +f 42453/42470/31569 43044/43044/32099 43007/43007/32063 +f 42453/42470/31569 43007/43007/32063 42454/42471/31571 +f 42378/42395/31502 42375/42392/31499 43046/43046/32101 +f 42378/42395/31502 43046/43046/32101 43047/43047/32102 +f 42375/42392/31499 42366/42383/31490 42369/42386/31493 +f 42375/42392/31499 42369/42386/31493 43046/43046/32101 +f 43046/43046/32101 42369/42386/31493 42374/42391/31498 +f 43046/43046/32101 42374/42391/31498 42994/42994/32050 +f 43047/43047/32102 43046/43046/32101 42994/42994/32050 +f 43047/43047/32102 42994/42994/32050 42993/42993/32049 +f 43042/43042/31905 43048/43048/32103 43049/43049/32104 +f 43042/43042/31905 43049/43049/32104 43043/43043/32098 +f 43048/43048/32103 43050/43050/31910 43051/43051/32105 +f 43048/43048/32103 43051/43051/32105 43049/43049/32104 +f 43052/43052/32106 43053/43053/32105 42991/42991/32047 +f 43052/43052/32106 42991/42991/32047 42988/42988/32044 +f 43045/43045/32100 43052/43052/32106 42988/42988/32044 +f 43045/43045/32100 42988/42988/32044 42987/42987/32043 +f 42512/42529/31622 42511/42528/31621 43054/43054/32107 +f 42512/42529/31622 43054/43054/32107 43055/43055/32108 +f 42511/42528/31621 42472/42489/31589 42499/42516/31609 +f 42511/42528/31621 42499/42516/31609 43054/43054/32107 +f 43054/43054/32107 42499/42516/31609 42501/42518/31611 +f 43054/43054/32107 42501/42518/31611 43035/43035/32091 +f 43055/43055/32108 43054/43054/32107 43035/43035/32091 +f 43055/43055/32108 43035/43035/32091 43034/43034/32090 +f 43056/43056/32109 43057/43057/32109 43058/43058/32109 +f 43056/43056/32109 43058/43058/32109 43059/43059/32109 +f 43060/43060/32110 43061/43061/32110 43062/43062/32110 +f 43060/43060/32110 43062/43062/32110 43063/43063/32110 +f 43064/43064/32111 43065/43065/32111 43066/43066/32111 +f 43064/43064/32111 43066/43066/32111 43067/43067/32112 +f 43068/43068/32113 43069/43069/32113 43070/43070/32114 +f 43068/43068/32113 43070/43070/32114 43071/43071/32113 +f 43072/43072/31371 43073/43073/32115 43074/43074/32116 +f 43072/43072/31371 43074/43074/32116 43075/43075/32117 +f 43073/43073/32115 43076/43076/31365 43077/43077/32118 +f 43073/43073/32115 43077/43077/32118 43074/43074/32116 +f 43078/43078/32119 43079/43079/32118 43029/43029/32085 +f 43078/43078/32119 43029/43029/32085 43028/43028/32084 +f 43080/43080/32120 43078/43078/32119 43028/43028/32084 +f 43080/43080/32120 43028/43028/32084 43027/43027/32083 +f 42445/42462/31563 42444/42461/31562 43081/43081/32121 +f 42445/42462/31563 43081/43081/32121 42854/42869/31943 +f 42444/42461/31562 42388/42405/31512 43082/43082/32122 +f 42444/42461/31562 43082/43082/32122 43081/43081/32121 +f 43081/43081/32121 43082/43082/32122 42995/42995/32051 +f 43081/43081/32121 42995/42995/32051 43010/43010/32066 +f 42854/42869/31943 43081/43081/32121 43010/43010/32066 +f 42854/42869/31943 43010/43010/32066 42855/42870/31944 +f 43083/43083/32123 43084/43084/31355 43085/43085/32124 +f 43083/43083/32123 43085/43085/32124 43086/43086/32125 +f 43084/43084/31355 43087/43087/31354 43088/43088/32126 +f 43084/43084/31355 43088/43088/32126 43085/43085/32124 +f 43089/43089/32124 43090/43090/32127 43039/43039/32095 +f 43089/43089/32124 43039/43039/32095 43038/43038/32094 +f 43091/43091/32128 43089/43089/32124 43038/43038/32094 +f 43091/43091/32128 43038/43038/32094 43033/43033/32089 +f 42388/42405/31512 42387/42404/31511 43092/43092/32129 +f 42388/42405/31512 43092/43092/32129 43082/43082/32122 +f 42387/42404/31511 42386/42403/31510 43093/43093/32130 +f 42387/42404/31511 43093/43093/32130 43092/43092/32129 +f 43092/43092/32129 43093/43093/32130 42999/42999/32055 +f 43092/43092/32129 42999/42999/32055 42996/42996/32052 +f 43082/43082/32122 43092/43092/32129 42996/42996/32052 +f 43082/43082/32122 42996/42996/32052 42995/42995/32051 +f 42489/42506/31599 42942/42955/32015 43094/43094/32131 +f 42489/42506/31599 43094/43094/32131 43095/43095/32132 +f 42942/42955/32015 42807/42824/31564 42456/42473/31573 +f 42942/42955/32015 42456/42473/31573 43094/43094/32131 +f 43094/43094/32131 42456/42473/31573 42457/42474/31574 +f 43094/43094/32131 42457/42474/31574 43018/43018/32074 +f 43095/43095/32132 43094/43094/32131 43018/43018/32074 +f 43095/43095/32132 43018/43018/32074 43020/43020/32076 +f 43076/43076/31365 43096/43096/32133 43097/43097/32134 +f 43076/43076/31365 43097/43097/32134 43077/43077/32118 +f 43096/43096/32133 43083/43083/32123 43086/43086/32125 +f 43096/43096/32133 43086/43086/32125 43097/43097/32134 +f 43098/43098/32134 43091/43091/32128 43033/43033/32089 +f 43098/43098/32134 43033/43033/32089 43032/43032/32088 +f 43079/43079/32118 43098/43098/32134 43032/43032/32088 +f 43079/43079/32118 43032/43032/32088 43029/43029/32085 +f 42370/42387/31494 42490/42507/31600 43099/43099/32135 +f 42370/42387/31494 43099/43099/32135 42371/42388/31495 +f 42490/42507/31600 42489/42506/31599 43095/43095/32132 +f 42490/42507/31600 43095/43095/32132 43099/43099/32135 +f 43099/43099/32135 43095/43095/32132 43020/43020/32076 +f 43099/43099/32135 43020/43020/32076 43019/43019/32075 +f 42371/42388/31495 43099/43099/32135 43019/43019/32075 +f 42371/42388/31495 43019/43019/32075 42372/42389/31496 +f 43100/43100/32136 43101/43101/32136 43102/43102/32136 +f 43100/43100/32136 43102/43102/32136 43103/43103/32136 +f 43104/43104/32137 43105/43105/32137 43106/43106/32137 +f 43104/43104/32137 43106/43106/32137 43107/43107/32138 +f 43108/43108/32139 43109/43109/32140 43110/43110/32140 +f 43108/43108/32139 43110/43110/32140 43111/43111/32139 +f 43112/43112/32141 43113/43113/32142 43114/43114/32142 +f 43112/43112/32141 43114/43114/32142 43115/43115/32142 +f 42204/42250/31354 42871/42886/31959 43116/43116/32143 +f 42204/42250/31354 43116/43116/32143 43090/43090/32127 +f 42871/42886/31959 42512/42529/31622 43055/43055/32108 +f 42871/42886/31959 43055/43055/32108 43116/43116/32143 +f 43116/43116/32143 43055/43055/32108 43034/43034/32090 +f 43116/43116/32143 43034/43034/32090 43037/43037/32093 +f 43090/43090/32127 43116/43116/32143 43037/43037/32093 +f 43090/43090/32127 43037/43037/32093 43039/43039/32095 +f 42903/42916/31321 42902/42915/31984 43117/43117/32144 +f 42903/42916/31321 43117/43117/32144 43118/43118/31876 +f 42902/42915/31984 42719/42736/31820 43119/43119/32145 +f 42902/42915/31984 43119/43119/32145 43117/43117/32144 +f 43117/43117/32144 43119/43119/32145 42675/42692/31779 +f 43117/43117/32144 42675/42692/31779 42905/42918/31986 +f 43118/43118/31876 43117/43117/32144 42905/42918/31986 +f 43118/43118/31876 42905/42918/31986 42904/42917/31985 +f 42915/42928/31994 42914/42927/31993 43120/43120/32146 +f 42915/42928/31994 43120/43120/32146 43121/43121/32147 +f 42914/42927/31993 42662/42679/31766 43122/43122/32148 +f 42914/42927/31993 43122/43122/32148 43120/43120/32146 +f 43120/43120/32146 43122/43122/32148 42769/42786/31868 +f 43120/43120/32146 42769/42786/31868 42893/42906/31977 +f 43121/43121/32147 43120/43120/32146 42893/42906/31977 +f 43121/43121/32147 42893/42906/31977 42892/42905/31976 +f 42594/42611/31704 43123/43123/32149 43124/43124/32150 +f 42594/42611/31704 43124/43124/32150 42834/42849/31924 +f 43123/43123/32149 42734/42751/31833 42830/42845/31920 +f 43123/43123/32149 42830/42845/31920 43124/43124/32150 +f 43124/43124/32150 42830/42845/31920 42773/42790/31872 +f 43124/43124/32150 42773/42790/31872 43125/43125/32151 +f 42834/42849/31924 43124/43124/32150 43125/43125/32151 +f 42834/42849/31924 43125/43125/32151 42685/42702/31789 +f 42793/42810/31892 43126/43126/32147 43127/43127/32152 +f 42793/42810/31892 43127/43127/32152 42794/42811/31893 +f 43126/43126/32147 42783/42800/31882 42786/42803/31885 +f 43126/43126/32147 42786/42803/31885 43127/43127/32152 +f 43127/43127/32152 42786/42803/31885 42755/42772/31854 +f 43127/43127/32152 42755/42772/31854 43128/43128/32153 +f 42794/42811/31893 43127/43127/32152 43128/43128/32153 +f 42794/42811/31893 43128/43128/32153 42631/42648/31739 +f 42178/42224/31331 42701/42718/31805 43129/43129/32154 +f 42178/42224/31331 43129/43129/32154 43130/43130/32155 +f 42701/42718/31805 42700/42717/31804 43131/43131/32156 +f 42701/42718/31805 43131/43131/32156 43129/43129/32154 +f 43129/43129/32154 43131/43131/32156 42781/42798/31880 +f 43129/43129/32154 42781/42798/31880 42779/42796/31878 +f 43130/43130/32155 43129/43129/32154 42779/42796/31878 +f 43130/43130/32155 42779/42796/31878 42763/42780/31862 +f 42685/42702/31789 43125/43125/32151 43132/43132/32157 +f 42685/42702/31789 43132/43132/32157 42686/42703/31790 +f 43125/43125/32151 42773/42790/31872 42776/42793/31875 +f 43125/43125/32151 42776/42793/31875 43132/43132/32157 +f 43132/43132/32157 42776/42793/31875 42778/42795/31877 +f 43132/43132/32157 42778/42795/31877 43133/43133/32158 +f 42686/42703/31790 43132/43132/32157 43133/43133/32158 +f 42686/42703/31790 43133/43133/32158 42687/42704/31791 +f 42662/42679/31766 42661/42678/31765 43134/43134/32159 +f 42662/42679/31766 43134/43134/32159 43122/43122/32148 +f 42661/42678/31765 42660/42677/31764 43135/43135/32160 +f 42661/42678/31765 43135/43135/32160 43134/43134/32159 +f 43134/43134/32159 43135/43135/32160 42765/42782/31864 +f 43134/43134/32159 42765/42782/31864 42770/42787/31869 +f 43122/43122/32148 43134/43134/32159 42770/42787/31869 +f 43122/43122/32148 42770/42787/31869 42769/42786/31868 +f 42660/42677/31764 43136/43136/32161 43137/43137/32162 +f 42660/42677/31764 43137/43137/32162 43135/43135/32160 +f 43136/43136/32161 42182/42228/31335 43138/43138/32163 +f 43136/43136/32161 43138/43138/32163 43137/43137/32162 +f 43137/43137/32162 43138/43138/32163 42759/42776/31858 +f 43137/43137/32162 42759/42776/31858 42766/42783/31865 +f 43135/43135/32160 43137/43137/32162 42766/42783/31865 +f 43135/43135/32160 42766/42783/31865 42765/42782/31864 +f 42182/42228/31335 42179/42225/31332 43139/43139/32164 +f 42182/42228/31335 43139/43139/32164 43138/43138/32163 +f 42179/42225/31332 42178/42224/31331 43130/43130/32155 +f 42179/42225/31332 43130/43130/32155 43139/43139/32164 +f 43139/43139/32164 43130/43130/32155 42763/42780/31862 +f 43139/43139/32164 42763/42780/31862 42760/42777/31859 +f 43138/43138/32163 43139/43139/32164 42760/42777/31859 +f 43138/43138/32163 42760/42777/31859 42759/42776/31858 +f 42631/42648/31739 43128/43128/32153 43140/43140/32165 +f 42631/42648/31739 43140/43140/32165 42632/42649/31740 +f 43128/43128/32153 42755/42772/31854 42758/42775/31857 +f 43128/43128/32153 42758/42775/31857 43140/43140/32165 +f 43140/43140/32165 42758/42775/31857 42751/42768/31850 +f 43140/43140/32165 42751/42768/31850 43141/43141/32166 +f 42632/42649/31740 43140/43140/32165 43141/43141/32166 +f 42632/42649/31740 43141/43141/32166 42625/42642/31733 +f 42625/42642/31733 43141/43141/32166 43142/43142/32167 +f 42625/42642/31733 43142/43142/32167 42626/42643/31734 +f 43141/43141/32166 42751/42768/31850 42754/42771/31853 +f 43141/43141/32166 42754/42771/31853 43142/43142/32167 +f 43142/43142/32167 42754/42771/31853 42747/42764/31846 +f 43142/43142/32167 42747/42764/31846 43143/43143/32168 +f 42626/42643/31734 43142/43142/32167 43143/43143/32168 +f 42626/42643/31734 43143/43143/32168 42619/42636/31727 +f 42619/42636/31727 43143/43143/32168 43144/43144/32169 +f 42619/42636/31727 43144/43144/32169 42620/42637/31728 +f 43143/43143/32168 42747/42764/31846 42750/42767/31849 +f 43143/43143/32168 42750/42767/31849 43144/43144/32169 +f 43144/43144/32169 42750/42767/31849 42743/42760/31842 +f 43144/43144/32169 42743/42760/31842 43145/43145/32170 +f 42620/42637/31728 43144/43144/32169 43145/43145/32170 +f 42620/42637/31728 43145/43145/32170 42613/42630/31723 +f 42613/42630/31723 43145/43145/32170 43146/43146/32171 +f 42613/42630/31723 43146/43146/32171 42614/42631/31724 +f 43145/43145/32170 42743/42760/31842 42746/42763/31845 +f 43145/43145/32170 42746/42763/31845 43146/43146/32171 +f 43146/43146/32171 42746/42763/31845 42739/42756/31838 +f 43146/43146/32171 42739/42756/31838 43147/43147/32172 +f 42614/42631/31724 43146/43146/32171 43147/43147/32172 +f 42614/42631/31724 43147/43147/32172 42607/42624/31717 +f 42607/42624/31717 43147/43147/32172 43148/43148/32173 +f 42607/42624/31717 43148/43148/32173 42608/42625/31718 +f 43147/43147/32172 42739/42756/31838 42742/42759/31841 +f 43147/43147/32172 42742/42759/31841 43148/43148/32173 +f 43148/43148/32173 42742/42759/31841 42735/42752/31834 +f 43148/43148/32173 42735/42752/31834 43149/43149/32174 +f 42608/42625/31718 43148/43148/32173 43149/43149/32174 +f 42608/42625/31718 43149/43149/32174 42601/42618/31711 +f 42601/42618/31711 43149/43149/32174 43150/43150/32175 +f 42601/42618/31711 43150/43150/32175 42602/42619/31712 +f 43149/43149/32174 42735/42752/31834 42738/42755/31837 +f 43149/43149/32174 42738/42755/31837 43150/43150/32175 +f 43150/43150/32175 42738/42755/31837 42729/42746/31828 +f 43150/43150/32175 42729/42746/31828 43151/43151/32176 +f 42602/42619/31712 43150/43150/32175 43151/43151/32176 +f 42602/42619/31712 43151/43151/32176 42592/42609/31702 +f 42592/42609/31702 43151/43151/32176 43152/43152/32177 +f 42592/42609/31702 43152/43152/32177 42593/42610/31703 +f 43151/43151/32176 42729/42746/31828 42732/42749/31831 +f 43151/43151/32176 42732/42749/31831 43152/43152/32177 +f 43152/43152/32177 42732/42749/31831 42734/42751/31833 +f 43152/43152/32177 42734/42751/31833 43123/43123/32149 +f 42593/42610/31703 43152/43152/32177 43123/43123/32149 +f 42593/42610/31703 43123/43123/32149 42594/42611/31704 +f 42710/42727/31813 42709/42726/31812 43153/43153/32178 +f 42710/42727/31813 43153/43153/32178 43154/43154/32179 +f 42709/42726/31812 42708/42725/31811 43155/43155/32180 +f 42709/42726/31812 43155/43155/32180 43153/43153/32178 +f 43153/43153/32178 43155/43155/32180 42692/42709/31796 +f 43153/43153/32178 42692/42709/31796 42690/42707/31794 +f 43154/43154/32179 43153/43153/32178 42690/42707/31794 +f 43154/43154/32179 42690/42707/31794 42667/42684/31771 +f 42719/42736/31820 42718/42735/31819 43156/43156/32181 +f 42719/42736/31820 43156/43156/32181 43119/43119/32145 +f 42718/42735/31819 42717/42734/31818 43157/43157/32182 +f 42718/42735/31819 43157/43157/32182 43156/43156/32181 +f 43156/43156/32181 43157/43157/32182 42669/42686/31773 +f 43156/43156/32181 42669/42686/31773 42676/42693/31780 +f 43119/43119/32145 43156/43156/32181 42676/42693/31780 +f 43119/43119/32145 42676/42693/31780 42675/42692/31779 +f 42717/42734/31818 42725/42742/31824 43158/43158/32183 +f 42717/42734/31818 43158/43158/32183 43157/43157/32182 +f 42725/42742/31824 42724/42741/31823 43159/43159/32184 +f 42725/42742/31824 43159/43159/32184 43158/43158/32183 +f 43158/43158/32183 43159/43159/32184 42663/42680/31767 +f 43158/43158/32183 42663/42680/31767 42670/42687/31774 +f 43157/43157/32182 43158/43158/32183 42670/42687/31774 +f 43157/43157/32182 42670/42687/31774 42669/42686/31773 +f 42724/42741/31823 42728/42745/31827 43160/43160/32185 +f 42724/42741/31823 43160/43160/32185 43159/43159/32184 +f 42728/42745/31827 42710/42727/31813 43154/43154/32179 +f 42728/42745/31827 43154/43154/32179 43160/43160/32185 +f 43160/43160/32185 43154/43154/32179 42667/42684/31771 +f 43160/43160/32185 42667/42684/31771 42664/42681/31768 +f 43159/43159/32184 43160/43160/32185 42664/42681/31768 +f 43159/43159/32184 42664/42681/31768 42663/42680/31767 +f 43161/43161/32186 43162/43162/32187 43163/43163/32188 +f 43161/43161/32186 43163/43163/32188 43164/43164/32189 +f 43162/43162/32187 43165/43165/32190 43166/43166/32191 +f 43162/43162/32187 43166/43166/32191 43163/43163/32188 +f 43163/43163/32188 43166/43166/32191 43167/43167/32192 +f 43163/43163/32188 43167/43167/32192 43168/43168/32193 +f 43164/43164/32189 43163/43163/32188 43168/43168/32193 +f 43164/43164/32189 43168/43168/32193 43169/43169/32194 +f 43170/43170/32195 43171/43171/32196 43172/43172/32197 +f 43170/43170/32195 43172/43172/32197 43173/43173/32198 +f 43171/43171/32196 43174/43174/32199 43175/43175/32200 +f 43171/43171/32196 43175/43175/32200 43172/43172/32197 +f 43172/43172/32197 43175/43175/32200 43176/43176/32201 +f 43172/43172/32197 43176/43176/32201 43177/43177/32202 +f 43173/43173/32198 43172/43172/32197 43177/43177/32202 +f 43173/43173/32198 43177/43177/32202 43178/43178/32203 +f 43179/43179/32204 43180/43180/32205 43181/43181/32206 +f 43179/43179/32204 43181/43181/32206 43182/43182/32207 +f 43180/43180/32205 43183/43183/32208 43184/43184/32209 +f 43180/43180/32205 43184/43184/32209 43181/43181/32206 +f 43181/43181/32206 43184/43184/32209 43185/43185/32210 +f 43181/43181/32206 43185/43185/32210 43186/43186/32211 +f 43182/43182/32207 43181/43181/32206 43186/43186/32211 +f 43182/43182/32207 43186/43186/32211 43187/43187/32212 +f 43188/43188/32213 43189/43189/32214 43190/43190/32215 +f 43188/43188/32213 43190/43190/32215 43191/43191/32216 +f 43189/43189/32214 43192/43192/32217 43193/43193/32218 +f 43189/43189/32214 43193/43193/32218 43190/43190/32215 +f 43190/43190/32215 43193/43193/32218 43194/43194/32219 +f 43190/43190/32215 43194/43194/32219 43195/43195/32220 +f 43191/43191/32216 43190/43190/32215 43195/43195/32220 +f 43191/43191/32216 43195/43195/32220 43196/43196/32221 +f 42151/42197/31304 42154/42200/31307 43197/43197/32222 +f 42151/42197/31304 43197/43197/32222 43198/43198/32223 +f 43199/43199/31307 42835/42850/31925 43200/43200/32224 +f 43199/43199/31307 43200/43200/32224 43201/43201/32225 +f 43201/43201/32225 43200/43200/32224 43202/43202/32226 +f 43201/43201/32225 43202/43202/32226 43203/43203/32227 +f 43204/43204/32223 43201/43201/32225 43203/43203/32227 +f 43204/43204/32223 43203/43203/32227 43205/43205/32228 +f 42256/42302/31405 42260/42306/31409 43206/43206/32229 +f 42256/42302/31405 43206/43206/32229 43207/43207/32230 +f 42260/42306/31409 42141/42187/31294 43208/43208/32231 +f 42260/42306/31409 43208/43208/32231 43206/43206/32229 +f 43206/43206/32229 43208/43208/32231 43209/43209/32232 +f 43206/43206/32229 43209/43209/32232 43210/43210/32233 +f 43207/43207/32230 43206/43206/32229 43210/43210/32233 +f 43207/43207/32230 43210/43210/32233 43211/43211/32234 +f 42674/42691/31778 42673/42690/31777 43212/43212/32235 +f 42674/42691/31778 43212/43212/32235 43213/43213/32236 +f 42673/42690/31777 42633/42650/31741 42636/42653/31744 +f 42673/42690/31777 42636/42653/31744 43212/43212/32235 +f 43214/43214/32235 42643/42660/31744 42644/42661/31751 +f 43214/43214/32235 42644/42661/31751 43215/43215/32237 +f 43216/43216/32238 43214/43214/32235 43215/43215/32237 +f 43216/43216/32238 43215/43215/32237 43217/43217/32239 +f 42849/42864/31938 42847/42862/31936 43218/43218/32240 +f 42849/42864/31938 43218/43218/32240 43219/43219/32241 +f 42847/42862/31936 42845/42860/31328 43220/43220/32242 +f 42847/42862/31936 43220/43220/32242 43218/43218/32240 +f 43218/43218/32240 43220/43220/32242 43221/43221/32243 +f 43218/43218/32240 43221/43221/32243 43222/43222/32244 +f 43219/43219/32241 43218/43218/32240 43222/43222/32244 +f 43219/43219/32241 43222/43222/32244 43223/43223/32245 +f 42182/42228/31335 43136/43136/32161 43224/43224/32246 +f 42182/42228/31335 43224/43224/32246 42183/42229/31336 +f 43136/43136/32161 42660/42677/31764 43225/43225/32247 +f 43136/43136/32161 43225/43225/32247 43224/43224/32246 +f 43226/43226/32248 43227/43227/32247 43228/43228/32249 +f 43226/43226/32248 43228/43228/32249 43229/43229/32250 +f 42185/42231/31337 43226/43226/32248 43229/43229/32250 +f 42185/42231/31337 43229/43229/32250 42186/42232/31338 +f 42249/42295/31346 42257/42303/31406 43230/43230/32251 +f 42249/42295/31346 43230/43230/32251 42197/42243/31349 +f 42257/42303/31406 42256/42302/31405 43207/43207/32230 +f 42257/42303/31406 43207/43207/32230 43230/43230/32251 +f 43230/43230/32251 43207/43207/32230 43211/43211/32234 +f 43230/43230/32251 43211/43211/32234 43231/43231/32252 +f 42197/42243/31349 43230/43230/32251 43231/43231/32252 +f 42197/42243/31349 43231/43231/32252 42198/42244/31350 +f 42173/42219/31326 43232/43232/32253 43233/43233/32254 +f 42173/42219/31326 43233/43233/32254 43234/43234/32255 +f 43232/43232/32253 42674/42691/31778 43213/43213/32236 +f 43232/43232/32253 43213/43213/32236 43233/43233/32254 +f 43235/43235/32256 43216/43216/32238 43217/43217/32239 +f 43235/43235/32256 43217/43217/32239 43236/43236/32257 +f 43237/43237/32255 43235/43235/32256 43236/43236/32257 +f 43237/43237/32255 43236/43236/32257 43238/43238/32258 +f 42835/42850/31925 42851/42866/31940 43239/43239/32259 +f 42835/42850/31925 43239/43239/32259 43200/43200/32224 +f 42851/42866/31940 42849/42864/31938 43219/43219/32241 +f 42851/42866/31940 43219/43219/32241 43239/43239/32259 +f 43239/43239/32259 43219/43219/32241 43223/43223/32245 +f 43239/43239/32259 43223/43223/32245 43240/43240/32260 +f 43200/43200/32224 43239/43239/32259 43240/43240/32260 +f 43200/43200/32224 43240/43240/32260 43202/43202/32226 +f 43241/43241/32261 43242/43242/32262 43243/43243/32263 +f 43241/43241/32261 43243/43243/32263 43244/43244/32264 +f 43242/43242/32262 43245/43245/32265 43246/43246/32266 +f 43242/43242/32262 43246/43246/32266 43243/43243/32263 +f 43243/43243/32263 43246/43246/32266 43247/43247/32267 +f 43243/43243/32263 43247/43247/32267 43248/43248/32268 +f 43244/43244/32264 43243/43243/32263 43248/43248/32268 +f 43244/43244/32264 43248/43248/32268 43249/43249/32269 +f 43250/43250/32270 43251/43251/32271 43252/43252/32272 +f 43250/43250/32270 43252/43252/32272 43253/43253/32273 +f 43251/43251/32271 43254/43254/32274 43255/43255/32275 +f 43251/43251/32271 43255/43255/32275 43252/43252/32272 +f 43252/43252/32272 43255/43255/32275 43256/43256/32276 +f 43252/43252/32272 43256/43256/32276 43257/43257/32277 +f 43253/43253/32273 43252/43252/32272 43257/43257/32277 +f 43253/43253/32273 43257/43257/32277 43258/43258/32278 +f 43259/43259/32279 43260/43260/32280 43261/43261/32281 +f 43259/43259/32279 43261/43261/32281 43262/43262/32282 +f 43260/43260/32280 43263/43263/32283 43264/43264/32284 +f 43260/43260/32280 43264/43264/32284 43261/43261/32281 +f 43261/43261/32281 43264/43264/32284 43265/43265/32285 +f 43261/43261/32281 43265/43265/32285 43266/43266/32286 +f 43262/43262/32282 43261/43261/32281 43266/43266/32286 +f 43262/43262/32282 43266/43266/32286 43267/43267/32287 +f 43268/43268/32288 43269/43269/32289 43270/43270/32290 +f 43268/43268/32288 43270/43270/32290 43271/43271/32291 +f 43269/43269/32289 43272/43272/32292 43273/43273/32293 +f 43269/43269/32289 43273/43273/32293 43270/43270/32290 +f 43274/43274/32294 43275/43275/32295 43276/43276/32296 +f 43274/43274/32294 43276/43276/32296 43277/43277/32297 +f 43278/43278/32298 43274/43274/32294 43277/43277/32297 +f 43278/43278/32298 43277/43277/32297 43279/43279/32299 +f 43280/43280/32300 43281/43281/32301 43282/43282/32302 +f 43280/43280/32300 43282/43282/32302 43283/43283/32303 +f 43281/43281/32301 43284/43284/32304 43285/43285/32305 +f 43281/43281/32301 43285/43285/32305 43282/43282/32302 +f 43282/43282/32302 43285/43285/32305 43286/43286/32306 +f 43282/43282/32302 43286/43286/32306 43287/43287/32307 +f 43283/43283/32303 43282/43282/32302 43287/43287/32307 +f 43283/43283/32303 43287/43287/32307 43288/43288/32308 +f 43289/43289/32309 43290/43290/32310 43291/43291/32311 +f 43289/43289/32309 43291/43291/32311 43292/43292/32312 +f 43290/43290/32310 43293/43293/32313 43294/43294/32314 +f 43290/43290/32310 43294/43294/32314 43291/43291/32311 +f 43291/43291/32311 43294/43294/32314 43295/43295/32315 +f 43291/43291/32311 43295/43295/32315 43296/43296/32316 +f 43292/43292/32312 43291/43291/32311 43296/43296/32316 +f 43292/43292/32312 43296/43296/32316 43297/43297/32317 +f 43298/43298/32318 43299/43299/32319 43300/43300/32320 +f 43298/43298/32318 43300/43300/32320 43301/43301/32321 +f 43299/43299/32319 43170/43170/32195 43173/43173/32198 +f 43299/43299/32319 43173/43173/32198 43300/43300/32320 +f 43300/43300/32320 43173/43173/32198 43178/43178/32203 +f 43300/43300/32320 43178/43178/32203 43302/43302/32322 +f 43301/43301/32321 43300/43300/32320 43302/43302/32322 +f 43301/43301/32321 43302/43302/32322 43303/43303/32323 +f 43192/43192/32217 43304/43304/32324 43305/43305/32325 +f 43192/43192/32217 43305/43305/32325 43193/43193/32218 +f 43304/43304/32324 43161/43161/32186 43164/43164/32189 +f 43304/43304/32324 43164/43164/32189 43305/43305/32325 +f 43305/43305/32325 43164/43164/32189 43169/43169/32194 +f 43305/43305/32325 43169/43169/32194 43306/43306/32326 +f 43193/43193/32218 43305/43305/32325 43306/43306/32326 +f 43193/43193/32218 43306/43306/32326 43194/43194/32219 +f 43307/43307/32327 43308/43308/32328 43309/43309/32329 +f 43307/43307/32327 43309/43309/32329 43310/43310/32330 +f 43308/43308/32328 43280/43280/32300 43283/43283/32303 +f 43308/43308/32328 43283/43283/32303 43309/43309/32329 +f 43309/43309/32329 43283/43283/32303 43288/43288/32308 +f 43309/43309/32329 43288/43288/32308 43311/43311/32331 +f 43310/43310/32330 43309/43309/32329 43311/43311/32331 +f 43310/43310/32330 43311/43311/32331 43312/43312/32332 +f 43313/43313/32313 43314/43314/32333 43315/43315/32334 +f 43313/43313/32313 43315/43315/32334 43316/43316/32314 +f 43314/43314/32333 43179/43179/32204 43182/43182/32207 +f 43314/43314/32333 43182/43182/32207 43315/43315/32334 +f 43315/43315/32334 43182/43182/32207 43187/43187/32212 +f 43315/43315/32334 43187/43187/32212 43317/43317/32335 +f 43316/43316/32314 43315/43315/32334 43317/43317/32335 +f 43316/43316/32314 43317/43317/32335 43318/43318/32315 +f 43174/43174/32199 43319/43319/32336 43320/43320/32337 +f 43174/43174/32199 43320/43320/32337 43175/43175/32200 +f 43319/43319/32336 43321/43321/32338 43322/43322/32339 +f 43319/43319/32336 43322/43322/32339 43320/43320/32337 +f 43320/43320/32337 43322/43322/32339 43323/43323/32340 +f 43320/43320/32337 43323/43323/32340 43324/43324/32341 +f 43175/43175/32200 43320/43320/32337 43324/43324/32341 +f 43175/43175/32200 43324/43324/32341 43176/43176/32201 +f 43325/43325/32342 43326/43326/32343 43327/43327/32344 +f 43325/43325/32342 43327/43327/32344 43328/43328/32345 +f 43329/43329/32343 43307/43307/32327 43310/43310/32330 +f 43329/43329/32343 43310/43310/32330 43330/43330/32344 +f 43330/43330/32344 43310/43310/32330 43312/43312/32332 +f 43330/43330/32344 43312/43312/32332 43331/43331/32346 +f 43328/43328/32345 43327/43327/32344 43332/43332/32347 +f 43328/43328/32345 43332/43332/32347 43333/43333/32348 +f 43279/43279/32299 43334/43334/32349 43335/43335/32350 +f 43279/43279/32299 43335/43335/32350 43336/43336/32351 +f 43334/43334/32349 43337/43337/32352 43338/43338/32353 +f 43334/43334/32349 43338/43338/32353 43335/43335/32350 +f 43335/43335/32350 43338/43338/32353 43339/43339/32354 +f 43335/43335/32350 43339/43339/32354 43340/43340/32355 +f 43336/43336/32351 43335/43335/32350 43340/43340/32355 +f 43336/43336/32351 43340/43340/32355 43341/43341/32356 +f 43337/43337/32352 43342/43342/32357 43343/43343/32358 +f 43337/43337/32352 43343/43343/32358 43338/43338/32353 +f 43342/43342/32357 43344/43344/32359 43345/43345/32360 +f 43342/43342/32357 43345/43345/32360 43343/43343/32358 +f 43343/43343/32358 43345/43345/32360 43346/43346/32361 +f 43343/43343/32358 43346/43346/32361 43347/43347/32362 +f 43338/43338/32353 43343/43343/32358 43347/43347/32362 +f 43338/43338/32353 43347/43347/32362 43339/43339/32354 +f 43348/43348/32363 43349/43349/32364 43350/43350/32365 +f 43348/43348/32363 43350/43350/32365 43351/43351/32366 +f 43349/43349/32364 43352/43352/32367 43353/43353/32368 +f 43349/43349/32364 43353/43353/32368 43350/43350/32365 +f 43350/43350/32365 43353/43353/32368 43354/43354/32369 +f 43350/43350/32365 43354/43354/32369 43355/43355/32370 +f 43351/43351/32366 43350/43350/32365 43355/43355/32370 +f 43351/43351/32366 43355/43355/32370 43356/43356/32371 +f 43357/43357/32372 43358/43358/32373 43359/43359/32374 +f 43357/43357/32372 43359/43359/32374 43360/43360/32375 +f 43358/43358/32373 43348/43348/32363 43351/43351/32366 +f 43358/43358/32373 43351/43351/32366 43359/43359/32374 +f 43359/43359/32374 43351/43351/32366 43356/43356/32371 +f 43359/43359/32374 43356/43356/32371 43361/43361/32286 +f 43360/43360/32375 43359/43359/32374 43361/43361/32286 +f 43360/43360/32375 43361/43361/32286 43362/43362/32376 +f 43363/43363/32377 43364/43364/32378 43365/43365/32379 +f 43363/43363/32377 43365/43365/32379 43366/43366/32380 +f 43367/43367/32381 43368/43368/32382 43369/43369/32383 +f 43367/43367/32381 43369/43369/32383 43370/43370/32379 +f 43370/43370/32379 43369/43369/32383 43371/43371/32384 +f 43370/43370/32379 43371/43371/32384 43372/43372/32385 +f 43366/43366/32380 43365/43365/32379 43373/43373/32386 +f 43366/43366/32380 43373/43373/32386 43374/43374/32387 +f 43375/43375/32388 43376/43376/32389 43377/43377/32390 +f 43375/43375/32388 43377/43377/32390 43378/43378/32391 +f 43376/43376/32389 43379/43379/32392 43380/43380/32393 +f 43376/43376/32389 43380/43380/32393 43377/43377/32390 +f 43381/43381/32394 43382/43382/32395 43354/43354/32369 +f 43381/43381/32394 43354/43354/32369 43353/43353/32368 +f 43383/43383/32391 43381/43381/32394 43353/43353/32368 +f 43383/43383/32391 43353/43353/32368 43352/43352/32367 +f 43384/43384/32396 43385/43385/32397 43386/43386/32398 +f 43384/43384/32396 43386/43386/32398 43387/43387/32399 +f 43385/43385/32397 43388/43388/32400 43389/43389/32401 +f 43385/43385/32397 43389/43389/32401 43386/43386/32398 +f 43390/43390/32398 43391/43391/32402 43346/43346/32361 +f 43390/43390/32398 43346/43346/32361 43345/43345/32360 +f 43392/43392/32403 43390/43390/32398 43345/43345/32360 +f 43392/43392/32403 43345/43345/32360 43344/43344/32359 +f 43272/43272/32292 43393/43393/32404 43394/43394/32405 +f 43272/43272/32292 43394/43394/32405 43273/43273/32293 +f 43393/43393/32404 43241/43241/32261 43244/43244/32264 +f 43393/43393/32404 43244/43244/32264 43394/43394/32405 +f 43394/43394/32405 43244/43244/32264 43249/43249/32269 +f 43394/43394/32405 43249/43249/32269 43395/43395/32406 +f 43273/43273/32293 43394/43394/32405 43395/43395/32406 +f 43273/43273/32293 43395/43395/32406 43396/43396/32296 +f 43397/43397/32407 43398/43398/32408 43399/43399/32409 +f 43397/43397/32407 43399/43399/32409 43400/43400/32410 +f 43398/43398/32408 43401/43401/32411 43402/43402/32412 +f 43398/43398/32408 43402/43402/32412 43399/43399/32409 +f 43399/43399/32409 43402/43402/32412 43403/43403/32413 +f 43399/43399/32409 43403/43403/32413 43404/43404/32414 +f 43400/43400/32410 43399/43399/32409 43404/43404/32414 +f 43400/43400/32410 43404/43404/32414 43405/43405/32415 +f 43406/43406/32392 43407/43407/32416 43408/43408/32417 +f 43406/43406/32392 43408/43408/32417 43409/43409/32393 +f 43407/43407/32416 43259/43259/32279 43262/43262/32282 +f 43407/43407/32416 43262/43262/32282 43408/43408/32417 +f 43408/43408/32417 43262/43262/32282 43267/43267/32287 +f 43408/43408/32417 43267/43267/32287 43410/43410/32418 +f 43409/43409/32393 43408/43408/32417 43410/43410/32418 +f 43409/43409/32393 43410/43410/32418 43411/43411/32419 +f 43412/43412/32420 43413/43413/32421 43414/43414/32422 +f 43412/43412/32420 43414/43414/32422 43415/43415/32423 +f 43413/43413/32421 43416/43416/32424 43417/43417/32425 +f 43413/43413/32421 43417/43417/32425 43414/43414/32422 +f 43414/43414/32422 43417/43417/32425 43418/43418/32426 +f 43414/43414/32422 43418/43418/32426 43419/43419/32427 +f 43415/43415/32423 43414/43414/32422 43419/43419/32427 +f 43415/43415/32423 43419/43419/32427 43420/43420/32428 +f 43421/43421/32429 43422/43422/32430 43423/43423/32431 +f 43421/43421/32429 43423/43423/32431 43424/43424/32432 +f 43422/43422/32430 43425/43425/32433 43426/43426/32434 +f 43422/43422/32430 43426/43426/32434 43423/43423/32431 +f 43427/43427/32435 43428/43428/32436 43429/43429/32437 +f 43427/43427/32435 43429/43429/32437 43430/43430/32438 +f 43431/43431/32432 43427/43427/32435 43430/43430/32438 +f 43431/43431/32432 43430/43430/32438 43357/43357/32372 +f 43432/43432/32439 43433/43433/32440 43434/43434/32441 +f 43432/43432/32439 43434/43434/32441 43435/43435/32442 +f 43436/43436/32440 43437/43437/32443 43438/43438/32444 +f 43436/43436/32440 43438/43438/32444 43439/43439/32441 +f 43439/43439/32441 43438/43438/32444 43440/43440/32445 +f 43439/43439/32441 43440/43440/32445 43441/43441/32446 +f 43435/43435/32442 43434/43434/32441 43442/43442/32447 +f 43435/43435/32442 43442/43442/32447 43443/43443/32448 +f 43374/43374/32387 43373/43373/32386 43444/43444/32449 +f 43374/43374/32387 43444/43444/32449 43445/43445/32450 +f 43372/43372/32385 43371/43371/32384 43446/43446/32451 +f 43372/43372/32385 43446/43446/32451 43447/43447/32449 +f 43447/43447/32449 43446/43446/32451 43448/43448/32452 +f 43447/43447/32449 43448/43448/32452 43449/43449/32453 +f 43445/43445/32450 43444/43444/32449 43450/43450/32453 +f 43445/43445/32450 43450/43450/32453 43451/43451/32454 +f 43437/43437/32443 43452/43452/32455 43453/43453/32456 +f 43437/43437/32443 43453/43453/32456 43438/43438/32444 +f 43452/43452/32455 43454/43454/32457 43455/43455/32458 +f 43452/43452/32455 43455/43455/32458 43453/43453/32456 +f 43453/43453/32456 43455/43455/32458 43456/43456/32459 +f 43453/43453/32456 43456/43456/32459 43457/43457/32460 +f 43438/43438/32444 43453/43453/32456 43457/43457/32460 +f 43438/43438/32444 43457/43457/32460 43440/43440/32445 +f 43418/43418/32426 43458/43458/32461 43459/43459/32462 +f 43418/43418/32426 43459/43459/32462 43460/43460/32463 +f 43458/43458/32461 43461/43461/32464 43462/43462/32465 +f 43458/43458/32461 43462/43462/32465 43459/43459/32462 +f 43459/43459/32462 43462/43462/32465 43463/43463/32466 +f 43459/43459/32462 43463/43463/32466 43464/43464/32467 +f 43460/43460/32463 43459/43459/32462 43464/43464/32467 +f 43460/43460/32463 43464/43464/32467 43465/43465/32468 +f 43466/43466/32469 43467/43467/32470 43468/43468/32471 +f 43466/43466/32469 43468/43468/32471 43469/43469/32472 +f 43467/43467/32470 43470/43470/32473 43471/43471/32474 +f 43467/43467/32470 43471/43471/32474 43468/43468/32471 +f 43468/43468/32471 43471/43471/32474 43454/43454/32457 +f 43468/43468/32471 43454/43454/32457 43452/43452/32455 +f 43469/43469/32472 43468/43468/32471 43452/43452/32455 +f 43469/43469/32472 43452/43452/32455 43437/43437/32443 +f 43472/43472/32475 43473/43473/32476 43474/43474/32477 +f 43472/43472/32475 43474/43474/32477 43475/43475/32478 +f 43476/43476/32476 43477/43477/32479 43478/43478/32480 +f 43476/43476/32476 43478/43478/32480 43479/43479/32477 +f 43479/43479/32477 43478/43478/32480 43480/43480/32481 +f 43479/43479/32477 43480/43480/32481 43481/43481/32482 +f 43475/43475/32478 43474/43474/32477 43482/43482/32482 +f 43475/43475/32478 43482/43482/32482 43483/43483/32483 +f 43477/43477/32479 43484/43484/32484 43485/43485/32485 +f 43477/43477/32479 43485/43485/32485 43478/43478/32480 +f 43484/43484/32484 43250/43250/32270 43253/43253/32273 +f 43484/43484/32484 43253/43253/32273 43485/43485/32485 +f 43485/43485/32485 43253/43253/32273 43258/43258/32278 +f 43485/43485/32485 43258/43258/32278 43486/43486/32486 +f 43478/43478/32480 43485/43485/32485 43486/43486/32486 +f 43478/43478/32480 43486/43486/32486 43480/43480/32481 +f 43487/43487/32487 43488/43488/32488 43489/43489/32489 +f 43487/43487/32487 43489/43489/32489 43490/43490/32490 +f 43491/43491/32488 43466/43466/32469 43469/43469/32472 +f 43491/43491/32488 43469/43469/32472 43492/43492/32491 +f 43492/43492/32491 43469/43469/32472 43437/43437/32443 +f 43492/43492/32491 43437/43437/32443 43436/43436/32440 +f 43490/43490/32490 43489/43489/32489 43433/43433/32440 +f 43490/43490/32490 43433/43433/32440 43432/43432/32439 +f 43470/43470/32473 43493/43493/32492 43494/43494/32493 +f 43470/43470/32473 43494/43494/32493 43471/43471/32474 +f 43493/43493/32492 43495/43495/32494 43496/43496/32495 +f 43493/43493/32492 43496/43496/32495 43494/43494/32493 +f 43494/43494/32493 43496/43496/32495 43497/43497/32496 +f 43494/43494/32493 43497/43497/32496 43498/43498/32497 +f 43471/43471/32474 43494/43494/32493 43498/43498/32497 +f 43471/43471/32474 43498/43498/32497 43454/43454/32457 +f 43416/43416/32424 43499/43499/32498 43500/43500/32499 +f 43416/43416/32424 43500/43500/32499 43417/43417/32425 +f 43499/43499/32498 43501/43501/32500 43502/43502/32501 +f 43499/43499/32498 43502/43502/32501 43500/43500/32499 +f 43500/43500/32499 43502/43502/32501 43461/43461/32464 +f 43500/43500/32499 43461/43461/32464 43458/43458/32461 +f 43417/43417/32425 43500/43500/32499 43458/43458/32461 +f 43417/43417/32425 43458/43458/32461 43418/43418/32426 +f 43503/43503/32502 43504/43504/32503 43505/43505/32504 +f 43503/43503/32502 43505/43505/32504 43506/43506/32505 +f 43507/43507/32506 43412/43412/32420 43415/43415/32423 +f 43507/43507/32506 43415/43415/32423 43508/43508/32504 +f 43508/43508/32504 43415/43415/32423 43420/43420/32428 +f 43508/43508/32504 43420/43420/32428 43509/43509/32507 +f 43506/43506/32505 43505/43505/32504 43510/43510/32507 +f 43506/43506/32505 43510/43510/32507 43511/43511/32508 +f 43368/43368/32382 43512/43512/32509 43513/43513/32510 +f 43368/43368/32382 43513/43513/32510 43369/43369/32383 +f 43512/43512/32509 43397/43397/32407 43400/43400/32410 +f 43512/43512/32509 43400/43400/32410 43513/43513/32510 +f 43513/43513/32510 43400/43400/32410 43405/43405/32415 +f 43513/43513/32510 43405/43405/32415 43514/43514/32511 +f 43369/43369/32383 43513/43513/32510 43514/43514/32511 +f 43369/43369/32383 43514/43514/32511 43371/43371/32384 +f 43515/43515/32512 43516/43516/32513 43517/43517/32514 +f 43515/43515/32512 43517/43517/32514 43518/43518/32515 +f 43519/43519/32516 43520/43520/32517 43521/43521/32518 +f 43519/43519/32516 43521/43521/32518 43522/43522/32519 +f 43523/43523/32514 43524/43524/32520 43525/43525/32521 +f 43523/43523/32514 43525/43525/32521 43526/43526/32522 +f 43527/43527/32523 43523/43523/32514 43526/43526/32522 +f 43527/43527/32523 43526/43526/32522 43528/43528/32524 +f 43529/43529/32525 43530/43530/32526 43531/43531/32527 +f 43529/43529/32525 43531/43531/32527 43532/43532/32528 +f 43530/43530/32526 43533/43533/32529 43534/43534/32530 +f 43530/43530/32526 43534/43534/32530 43531/43531/32527 +f 43535/43535/32531 43536/43536/32532 43537/43537/32533 +f 43535/43535/32531 43537/43537/32533 43538/43538/32534 +f 43539/43539/32535 43535/43535/32531 43538/43538/32534 +f 43539/43539/32535 43538/43538/32534 43540/43540/32536 +f 43541/43541/32537 43542/43542/32538 43543/43543/32539 +f 43541/43541/32537 43543/43543/32539 43544/43544/32540 +f 43542/43542/32538 43545/43545/32541 43546/43546/32542 +f 43542/43542/32538 43546/43546/32542 43543/43543/32539 +f 43543/43543/32539 43546/43546/32542 43547/43547/32543 +f 43543/43543/32539 43547/43547/32543 43548/43548/32544 +f 43544/43544/32540 43543/43543/32539 43548/43548/32544 +f 43544/43544/32540 43548/43548/32544 43549/43549/32545 +f 43550/43550/32546 43551/43551/32547 43552/43552/32548 +f 43550/43550/32546 43552/43552/32548 43553/43553/32549 +f 43551/43551/32547 43529/43529/32525 43532/43532/32528 +f 43551/43551/32547 43532/43532/32528 43552/43552/32548 +f 43554/43554/32550 43539/43539/32535 43540/43540/32536 +f 43554/43554/32550 43540/43540/32536 43555/43555/32551 +f 43556/43556/32552 43554/43554/32550 43555/43555/32551 +f 43556/43556/32552 43555/43555/32551 43557/43557/32553 +f 43420/43420/32428 43419/43419/32427 43558/43558/32554 +f 43420/43420/32428 43558/43558/32554 43559/43559/32555 +f 43419/43419/32427 43418/43418/32426 43460/43460/32463 +f 43419/43419/32427 43460/43460/32463 43558/43558/32554 +f 43558/43558/32554 43460/43460/32463 43465/43465/32468 +f 43558/43558/32554 43465/43465/32468 43560/43560/32556 +f 43559/43559/32555 43558/43558/32554 43560/43560/32556 +f 43559/43559/32555 43560/43560/32556 43561/43561/32557 +f 43454/43454/32457 43498/43498/32497 43562/43562/32558 +f 43454/43454/32457 43562/43562/32558 43455/43455/32458 +f 43498/43498/32497 43497/43497/32496 43563/43563/32559 +f 43498/43498/32497 43563/43563/32559 43562/43562/32558 +f 43562/43562/32558 43563/43563/32559 43564/43564/32560 +f 43562/43562/32558 43564/43564/32560 43565/43565/32561 +f 43455/43455/32458 43562/43562/32558 43565/43565/32561 +f 43455/43455/32458 43565/43565/32561 43456/43456/32459 +f 43371/43371/32384 43514/43514/32511 43566/43566/32562 +f 43371/43371/32384 43566/43566/32562 43446/43446/32451 +f 43514/43514/32511 43405/43405/32415 43567/43567/32563 +f 43514/43514/32511 43567/43567/32563 43566/43566/32562 +f 43566/43566/32562 43567/43567/32563 43568/43568/32564 +f 43566/43566/32562 43568/43568/32564 43569/43569/32565 +f 43446/43446/32451 43566/43566/32562 43569/43569/32565 +f 43446/43446/32451 43569/43569/32565 43448/43448/32452 +f 43258/43258/32278 43257/43257/32277 43570/43570/32566 +f 43258/43258/32278 43570/43570/32566 43571/43571/32567 +f 43257/43257/32277 43256/43256/32276 43572/43572/32568 +f 43257/43257/32277 43572/43572/32568 43570/43570/32566 +f 43570/43570/32566 43572/43572/32568 43573/43573/32569 +f 43570/43570/32566 43573/43573/32569 43574/43574/32570 +f 43571/43571/32567 43570/43570/32566 43574/43574/32570 +f 43571/43571/32567 43574/43574/32570 43575/43575/32571 +f 43405/43405/32415 43404/43404/32414 43576/43576/32572 +f 43405/43405/32415 43576/43576/32572 43567/43567/32563 +f 43404/43404/32414 43403/43403/32413 43577/43577/32573 +f 43404/43404/32414 43577/43577/32573 43576/43576/32572 +f 43576/43576/32572 43577/43577/32573 43578/43578/32574 +f 43576/43576/32572 43578/43578/32574 43579/43579/32575 +f 43567/43567/32563 43576/43576/32572 43579/43579/32575 +f 43567/43567/32563 43579/43579/32575 43568/43568/32564 +f 43483/43483/32483 43482/43482/32482 43580/43580/32576 +f 43483/43483/32483 43580/43580/32576 43581/43581/32577 +f 43481/43481/32482 43480/43480/32481 43582/43582/32578 +f 43481/43481/32482 43582/43582/32578 43583/43583/32579 +f 43583/43583/32579 43582/43582/32578 43584/43584/32580 +f 43583/43583/32579 43584/43584/32580 43585/43585/32581 +f 43581/43581/32577 43580/43580/32576 43586/43586/32582 +f 43581/43581/32577 43586/43586/32582 43587/43587/32583 +f 43480/43480/32481 43486/43486/32486 43588/43588/32584 +f 43480/43480/32481 43588/43588/32584 43582/43582/32578 +f 43486/43486/32486 43258/43258/32278 43571/43571/32567 +f 43486/43486/32486 43571/43571/32567 43588/43588/32584 +f 43588/43588/32584 43571/43571/32567 43575/43575/32571 +f 43588/43588/32584 43575/43575/32571 43589/43589/32585 +f 43582/43582/32578 43588/43588/32584 43589/43589/32585 +f 43582/43582/32578 43589/43589/32585 43584/43584/32580 +f 43511/43511/32508 43510/43510/32507 43590/43590/32586 +f 43511/43511/32508 43590/43590/32586 43591/43591/32587 +f 43509/43509/32507 43420/43420/32428 43559/43559/32555 +f 43509/43509/32507 43559/43559/32555 43592/43592/32588 +f 43592/43592/32588 43559/43559/32555 43561/43561/32557 +f 43592/43592/32588 43561/43561/32557 43593/43593/32589 +f 43591/43591/32587 43590/43590/32586 43594/43594/32589 +f 43591/43591/32587 43594/43594/32589 43595/43595/32590 +f 43596/43596/32591 43597/43597/32592 43598/43598/32593 +f 43596/43596/32591 43598/43598/32593 43599/43599/32594 +f 43597/43597/32592 43600/43600/32595 43601/43601/32596 +f 43597/43597/32592 43601/43601/32596 43598/43598/32593 +f 43598/43598/32593 43601/43601/32596 43540/43540/32536 +f 43598/43598/32593 43540/43540/32536 43538/43538/32534 +f 43599/43599/32594 43598/43598/32593 43538/43538/32534 +f 43599/43599/32594 43538/43538/32534 43537/43537/32533 +f 43602/43602/32597 43603/43603/32598 43604/43604/32599 +f 43602/43602/32597 43604/43604/32599 43605/43605/32600 +f 43603/43603/32598 43606/43606/32601 43607/43607/32602 +f 43603/43603/32598 43607/43607/32602 43604/43604/32599 +f 43604/43604/32599 43607/43607/32602 43608/43608/32603 +f 43604/43604/32599 43608/43608/32603 43609/43609/32604 +f 43605/43605/32600 43604/43604/32599 43609/43609/32604 +f 43605/43605/32600 43609/43609/32604 43610/43610/32605 +f 43528/43528/32524 43611/43611/32606 43612/43612/32607 +f 43528/43528/32524 43612/43612/32607 43613/43613/32608 +f 43611/43611/32606 43602/43602/32597 43605/43605/32600 +f 43611/43611/32606 43605/43605/32600 43612/43612/32607 +f 43612/43612/32607 43605/43605/32600 43610/43610/32605 +f 43612/43612/32607 43610/43610/32605 43614/43614/32609 +f 43613/43613/32608 43612/43612/32607 43614/43614/32609 +f 43613/43613/32608 43614/43614/32609 43615/43615/32610 +f 43600/43600/32595 43616/43616/32611 43617/43617/32612 +f 43600/43600/32595 43617/43617/32612 43601/43601/32596 +f 43616/43616/32611 43618/43618/32613 43619/43619/32614 +f 43616/43616/32611 43619/43619/32614 43617/43617/32612 +f 43617/43617/32612 43619/43619/32614 43557/43557/32553 +f 43617/43617/32612 43557/43557/32553 43555/43555/32551 +f 43601/43601/32596 43617/43617/32612 43555/43555/32551 +f 43601/43601/32596 43555/43555/32551 43540/43540/32536 +f 43520/43520/32517 43620/43620/32615 43621/43621/32616 +f 43520/43520/32517 43621/43621/32616 43521/43521/32518 +f 43620/43620/32615 43541/43541/32537 43544/43544/32540 +f 43620/43620/32615 43544/43544/32540 43621/43621/32616 +f 43621/43621/32616 43544/43544/32540 43549/43549/32545 +f 43621/43621/32616 43549/43549/32545 43622/43622/32617 +f 43521/43521/32518 43621/43621/32616 43622/43622/32617 +f 43521/43521/32518 43622/43622/32617 43623/43623/32618 +f 43624/43624/32619 43625/43625/32620 43626/43626/32621 +f 43624/43624/32619 43626/43626/32621 43627/43627/32622 +f 43628/43628/32620 43629/43629/32623 43630/43630/32624 +f 43628/43628/32620 43630/43630/32624 43631/43631/32621 +f 43626/43626/32621 43632/43632/32625 43633/43633/32626 +f 43626/43626/32621 43633/43633/32626 43634/43634/32627 +f 43627/43627/32622 43626/43626/32621 43634/43634/32627 +f 43627/43627/32622 43634/43634/32627 43596/43596/32591 +f 43635/43635/32628 43636/43636/32629 43637/43637/32630 +f 43635/43635/32628 43637/43637/32630 43638/43638/32631 +f 43636/43636/32629 43639/43639/32632 43640/43640/32633 +f 43636/43636/32629 43640/43640/32633 43637/43637/32630 +f 43637/43637/32630 43640/43640/32633 43641/43641/32634 +f 43637/43637/32630 43641/43641/32634 43642/43642/32635 +f 43638/43638/32631 43637/43637/32630 43642/43642/32635 +f 43638/43638/32631 43642/43642/32635 43643/43643/32636 +f 43644/43644/32637 43645/43645/32638 43646/43646/32639 +f 43644/43644/32637 43646/43646/32639 43647/43647/32640 +f 43645/43645/32638 43648/43648/32641 43649/43649/32642 +f 43645/43645/32638 43649/43649/32642 43646/43646/32639 +f 43646/43646/32639 43649/43649/32642 43650/43650/32643 +f 43646/43646/32639 43650/43650/32643 43651/43651/32644 +f 43647/43647/32640 43646/43646/32639 43651/43651/32644 +f 43647/43647/32640 43651/43651/32644 43652/43652/32645 +f 43653/43653/32646 43654/43654/32647 43655/43655/32648 +f 43653/43653/32646 43655/43655/32648 43656/43656/32649 +f 43657/43657/32650 43550/43550/32546 43553/43553/32549 +f 43657/43657/32650 43553/43553/32549 43658/43658/32648 +f 43659/43659/32648 43556/43556/32552 43557/43557/32553 +f 43659/43659/32648 43557/43557/32553 43619/43619/32614 +f 43660/43660/32651 43659/43659/32648 43619/43619/32614 +f 43660/43660/32651 43619/43619/32614 43618/43618/32613 +f 43661/43661/32652 43662/43662/32653 43663/43663/32654 +f 43661/43661/32652 43663/43663/32654 43664/43664/32655 +f 43665/43665/32656 43644/43644/32637 43647/43647/32640 +f 43665/43665/32656 43647/43647/32640 43666/43666/32657 +f 43663/43663/32654 43667/43667/32658 43608/43608/32603 +f 43663/43663/32654 43608/43608/32603 43607/43607/32602 +f 43664/43664/32655 43663/43663/32654 43607/43607/32602 +f 43664/43664/32655 43607/43607/32602 43606/43606/32601 +f 43629/43629/32623 43668/43668/32659 43669/43669/32660 +f 43629/43629/32623 43669/43669/32660 43630/43630/32624 +f 43668/43668/32659 43635/43635/32628 43638/43638/32631 +f 43668/43668/32659 43638/43638/32631 43669/43669/32660 +f 43669/43669/32660 43638/43638/32631 43643/43643/32636 +f 43669/43669/32660 43643/43643/32636 43670/43670/32661 +f 43630/43630/32624 43669/43669/32660 43670/43670/32661 +f 43630/43630/32624 43670/43670/32661 43671/43671/32662 +f 43648/43648/32641 43672/43672/32663 43673/43673/32664 +f 43648/43648/32641 43673/43673/32664 43649/43649/32642 +f 43672/43672/32663 43674/43674/32665 43675/43675/32666 +f 43672/43672/32663 43675/43675/32666 43673/43673/32664 +f 43673/43673/32664 43675/43675/32666 43676/43676/32667 +f 43673/43673/32664 43676/43676/32667 43677/43677/32609 +f 43649/43649/32642 43673/43673/32664 43677/43677/32609 +f 43649/43649/32642 43677/43677/32609 43650/43650/32643 +f 43223/43223/32245 43222/43222/32244 43678/43678/32668 +f 43223/43223/32245 43678/43678/32668 43679/43679/32669 +f 43222/43222/32244 43221/43221/32243 43680/43680/32670 +f 43222/43222/32244 43680/43680/32670 43678/43678/32668 +f 43678/43678/32668 43680/43680/32670 43321/43321/32338 +f 43678/43678/32668 43321/43321/32338 43319/43319/32336 +f 43679/43679/32669 43678/43678/32668 43319/43319/32336 +f 43679/43679/32669 43319/43319/32336 43174/43174/32199 +f 43217/43217/32239 43215/43215/32237 43681/43681/32671 +f 43217/43217/32239 43681/43681/32671 43682/43682/32672 +f 43215/43215/32237 42644/42661/31751 43683/43683/32673 +f 43215/43215/32237 43683/43683/32673 43681/43681/32671 +f 43681/43681/32671 43683/43683/32673 43161/43161/32186 +f 43681/43681/32671 43161/43161/32186 43304/43304/32324 +f 43682/43682/32672 43681/43681/32671 43304/43304/32324 +f 43682/43682/32672 43304/43304/32324 43192/43192/32217 +f 43205/43205/32228 43203/43203/32227 43684/43684/32674 +f 43205/43205/32228 43684/43684/32674 43685/43685/32675 +f 43203/43203/32227 43202/43202/32226 43686/43686/32676 +f 43203/43203/32227 43686/43686/32676 43684/43684/32674 +f 43684/43684/32674 43686/43686/32676 43170/43170/32195 +f 43684/43684/32674 43170/43170/32195 43299/43299/32319 +f 43685/43685/32675 43684/43684/32674 43299/43299/32319 +f 43685/43685/32675 43299/43299/32319 43298/43298/32318 +f 43238/43238/32258 43236/43236/32257 43687/43687/32677 +f 43238/43238/32258 43687/43687/32677 43688/43688/32678 +f 43236/43236/32257 43217/43217/32239 43682/43682/32672 +f 43236/43236/32257 43682/43682/32672 43687/43687/32677 +f 43687/43687/32677 43682/43682/32672 43192/43192/32217 +f 43687/43687/32677 43192/43192/32217 43189/43189/32214 +f 43688/43688/32678 43687/43687/32677 43189/43189/32214 +f 43688/43688/32678 43189/43189/32214 43188/43188/32213 +f 43202/43202/32226 43240/43240/32260 43689/43689/32679 +f 43202/43202/32226 43689/43689/32679 43686/43686/32676 +f 43240/43240/32260 43223/43223/32245 43679/43679/32669 +f 43240/43240/32260 43679/43679/32669 43689/43689/32679 +f 43689/43689/32679 43679/43679/32669 43174/43174/32199 +f 43689/43689/32679 43174/43174/32199 43171/43171/32196 +f 43686/43686/32676 43689/43689/32679 43171/43171/32196 +f 43686/43686/32676 43171/43171/32196 43170/43170/32195 +f 42644/42661/31751 42642/42659/31750 43690/43690/32680 +f 42644/42661/31751 43690/43690/32680 43683/43683/32673 +f 42642/42659/31750 42641/42658/31749 43691/43691/32681 +f 42642/42659/31750 43691/43691/32681 43690/43690/32680 +f 43690/43690/32680 43691/43691/32681 43165/43165/32190 +f 43690/43690/32680 43165/43165/32190 43162/43162/32187 +f 43683/43683/32673 43690/43690/32680 43162/43162/32187 +f 43683/43683/32673 43162/43162/32187 43161/43161/32186 +f 43341/43341/32356 43340/43340/32355 43692/43692/32682 +f 43341/43341/32356 43692/43692/32682 43693/43693/32683 +f 43340/43340/32355 43339/43339/32354 43694/43694/32684 +f 43340/43340/32355 43694/43694/32684 43692/43692/32682 +f 43692/43692/32682 43694/43694/32684 43397/43397/32407 +f 43692/43692/32682 43397/43397/32407 43512/43512/32509 +f 43693/43693/32683 43692/43692/32682 43512/43512/32509 +f 43693/43693/32683 43512/43512/32509 43368/43368/32382 +f 43388/43388/32400 43695/43695/32685 43696/43696/32686 +f 43388/43388/32400 43696/43696/32686 43697/43697/32687 +f 43698/43698/32688 43699/43699/32689 43700/43700/32690 +f 43698/43698/32688 43700/43700/32690 43701/43701/32691 +f 43701/43701/32691 43700/43700/32690 43412/43412/32420 +f 43701/43701/32691 43412/43412/32420 43507/43507/32506 +f 43697/43697/32687 43696/43696/32686 43504/43504/32503 +f 43697/43697/32687 43504/43504/32503 43503/43503/32502 +f 43702/43702/32692 43703/43703/32341 43704/43704/32693 +f 43702/43702/32692 43704/43704/32693 43705/43705/32694 +f 43703/43703/32341 43706/43706/32340 43707/43707/32695 +f 43703/43703/32341 43707/43707/32695 43704/43704/32693 +f 43704/43704/32693 43707/43707/32695 43501/43501/32500 +f 43704/43704/32693 43501/43501/32500 43499/43499/32498 +f 43705/43705/32694 43704/43704/32693 43499/43499/32498 +f 43705/43705/32694 43499/43499/32498 43416/43416/32424 +f 43699/43699/32689 43708/43708/32202 43709/43709/32696 +f 43699/43699/32689 43709/43709/32696 43700/43700/32690 +f 43708/43708/32202 43702/43702/32692 43705/43705/32694 +f 43708/43708/32202 43705/43705/32694 43709/43709/32696 +f 43709/43709/32696 43705/43705/32694 43416/43416/32424 +f 43709/43709/32696 43416/43416/32424 43413/43413/32421 +f 43700/43700/32690 43709/43709/32696 43413/43413/32421 +f 43700/43700/32690 43413/43413/32421 43412/43412/32420 +f 43339/43339/32354 43347/43347/32362 43710/43710/32697 +f 43339/43339/32354 43710/43710/32697 43694/43694/32684 +f 43347/43347/32362 43346/43346/32361 43711/43711/32698 +f 43347/43347/32362 43711/43711/32698 43710/43710/32697 +f 43710/43710/32697 43711/43711/32698 43401/43401/32411 +f 43710/43710/32697 43401/43401/32411 43398/43398/32408 +f 43694/43694/32684 43710/43710/32697 43398/43398/32408 +f 43694/43694/32684 43398/43398/32408 43397/43397/32407 +f 43712/43712/32699 43713/43713/32700 43714/43714/32701 +f 43712/43712/32699 43714/43714/32701 43715/43715/32702 +f 43716/43716/32700 43341/43341/32356 43693/43693/32683 +f 43716/43716/32700 43693/43693/32683 43717/43717/32703 +f 43717/43717/32703 43693/43693/32683 43368/43368/32382 +f 43717/43717/32703 43368/43368/32382 43367/43367/32381 +f 43715/43715/32702 43714/43714/32701 43364/43364/32378 +f 43715/43715/32702 43364/43364/32378 43363/43363/32377 +f 43718/43718/32704 43719/43719/32705 43720/43720/32706 +f 43718/43718/32704 43720/43720/32706 43721/43721/32707 +f 43719/43719/32705 43429/43429/32437 43722/43722/32708 +f 43719/43719/32705 43722/43722/32708 43720/43720/32706 +f 43720/43720/32706 43722/43722/32708 43495/43495/32494 +f 43720/43720/32706 43495/43495/32494 43493/43493/32492 +f 43721/43721/32707 43720/43720/32706 43493/43493/32492 +f 43721/43721/32707 43493/43493/32492 43470/43470/32473 +f 43723/43723/32709 43724/43724/32710 43725/43725/32711 +f 43723/43723/32709 43725/43725/32711 43726/43726/32712 +f 43727/43727/32713 43728/43728/32714 43729/43729/32715 +f 43727/43727/32713 43729/43729/32715 43730/43730/32711 +f 43730/43730/32711 43729/43729/32715 43466/43466/32469 +f 43730/43730/32711 43466/43466/32469 43491/43491/32488 +f 43726/43726/32712 43725/43725/32711 43488/43488/32488 +f 43726/43726/32712 43488/43488/32488 43487/43487/32487 +f 43731/43731/32332 43732/43732/32331 43733/43733/32716 +f 43731/43731/32332 43733/43733/32716 43734/43734/32717 +f 43732/43732/32331 43735/43735/32718 43736/43736/32719 +f 43732/43732/32331 43736/43736/32719 43733/43733/32716 +f 43733/43733/32716 43736/43736/32719 43250/43250/32270 +f 43733/43733/32716 43250/43250/32270 43484/43484/32484 +f 43734/43734/32717 43733/43733/32716 43484/43484/32484 +f 43734/43734/32717 43484/43484/32484 43477/43477/32479 +f 43425/43425/32433 43737/43737/32720 43738/43738/32721 +f 43425/43425/32433 43738/43738/32721 43739/43739/32722 +f 43740/43740/32723 43731/43731/32332 43734/43734/32717 +f 43740/43740/32723 43734/43734/32717 43741/43741/32724 +f 43741/43741/32724 43734/43734/32717 43477/43477/32479 +f 43741/43741/32724 43477/43477/32479 43476/43476/32476 +f 43739/43739/32722 43738/43738/32721 43473/43473/32476 +f 43739/43739/32722 43473/43473/32476 43472/43472/32475 +f 43728/43728/32714 43742/43742/32725 43743/43743/32726 +f 43728/43728/32714 43743/43743/32726 43729/43729/32715 +f 43742/43742/32725 43718/43718/32704 43721/43721/32707 +f 43742/43742/32725 43721/43721/32707 43743/43743/32726 +f 43743/43743/32726 43721/43721/32707 43470/43470/32473 +f 43743/43743/32726 43470/43470/32473 43467/43467/32470 +f 43729/43729/32715 43743/43743/32726 43467/43467/32470 +f 43729/43729/32715 43467/43467/32470 43466/43466/32469 +f 43735/43735/32718 43744/43744/32307 43745/43745/32727 +f 43735/43735/32718 43745/43745/32727 43736/43736/32719 +f 43744/43744/32307 43746/43746/32306 43747/43747/32728 +f 43744/43744/32307 43747/43747/32728 43745/43745/32727 +f 43745/43745/32727 43747/43747/32728 43254/43254/32274 +f 43745/43745/32727 43254/43254/32274 43251/43251/32271 +f 43736/43736/32719 43745/43745/32727 43251/43251/32271 +f 43736/43736/32719 43251/43251/32271 43250/43250/32270 +f 42203/42249/31353 42202/42248/31351 43748/43748/32729 +f 42203/42249/31353 43748/43748/32729 43749/43749/32730 +f 42199/42245/31351 42198/42244/31350 43750/43750/32731 +f 42199/42245/31351 43750/43750/32731 43751/43751/32732 +f 43751/43751/32732 43750/43750/32731 43307/43307/32327 +f 43751/43751/32732 43307/43307/32327 43329/43329/32343 +f 43749/43749/32730 43748/43748/32729 43326/43326/32343 +f 43749/43749/32730 43326/43326/32343 43325/43325/32342 +f 42189/42235/31341 42187/42233/31339 43752/43752/32733 +f 42189/42235/31341 43752/43752/32733 43753/43753/32734 +f 42187/42233/31339 42186/42232/31338 43754/43754/32735 +f 42187/42233/31339 43754/43754/32735 43752/43752/32733 +f 43752/43752/32733 43754/43754/32735 43179/43179/32204 +f 43752/43752/32733 43179/43179/32204 43314/43314/32333 +f 43753/43753/32734 43752/43752/32733 43314/43314/32333 +f 43753/43753/32734 43314/43314/32333 43313/43313/32313 +f 42198/42244/31350 43231/43231/32252 43755/43755/32736 +f 42198/42244/31350 43755/43755/32736 43750/43750/32731 +f 43231/43231/32252 43211/43211/32234 43756/43756/32737 +f 43231/43231/32252 43756/43756/32737 43755/43755/32736 +f 43755/43755/32736 43756/43756/32737 43280/43280/32300 +f 43755/43755/32736 43280/43280/32300 43308/43308/32328 +f 43750/43750/32731 43755/43755/32736 43308/43308/32328 +f 43750/43750/32731 43308/43308/32328 43307/43307/32327 +f 42654/42671/31758 42652/42669/31756 43757/43757/32738 +f 42654/42671/31758 43757/43757/32738 43758/43758/32739 +f 42652/42669/31756 42651/42668/31341 43759/43759/32734 +f 42652/42669/31756 43759/43759/32734 43757/43757/32738 +f 43757/43757/32738 43759/43759/32734 43293/43293/32313 +f 43757/43757/32738 43293/43293/32313 43290/43290/32310 +f 43758/43758/32739 43757/43757/32738 43290/43290/32310 +f 43758/43758/32739 43290/43290/32310 43289/43289/32309 +f 43211/43211/32234 43210/43210/32233 43760/43760/32740 +f 43211/43211/32234 43760/43760/32740 43756/43756/32737 +f 43210/43210/32233 43209/43209/32232 43761/43761/32741 +f 43210/43210/32233 43761/43761/32741 43760/43760/32740 +f 43760/43760/32740 43761/43761/32741 43284/43284/32304 +f 43760/43760/32740 43284/43284/32304 43281/43281/32301 +f 43756/43756/32737 43760/43760/32740 43281/43281/32301 +f 43756/43756/32737 43281/43281/32301 43280/43280/32300 +f 42186/42232/31338 43229/43229/32250 43762/43762/32742 +f 42186/42232/31338 43762/43762/32742 43754/43754/32735 +f 43229/43229/32250 43228/43228/32249 43763/43763/32743 +f 43229/43229/32250 43763/43763/32743 43762/43762/32742 +f 43762/43762/32742 43763/43763/32743 43183/43183/32208 +f 43762/43762/32742 43183/43183/32208 43180/43180/32205 +f 43754/43754/32735 43762/43762/32742 43180/43180/32205 +f 43754/43754/32735 43180/43180/32205 43179/43179/32204 +f 43429/43429/32437 43428/43428/32436 43764/43764/32744 +f 43429/43429/32437 43764/43764/32744 43722/43722/32708 +f 43426/43426/32434 43425/43425/32433 43739/43739/32722 +f 43426/43426/32434 43739/43739/32722 43765/43765/32744 +f 43765/43765/32744 43739/43739/32722 43472/43472/32475 +f 43765/43765/32744 43472/43472/32475 43766/43766/32745 +f 43722/43722/32708 43764/43764/32744 43767/43767/32745 +f 43722/43722/32708 43767/43767/32745 43495/43495/32494 +f 43746/43746/32306 43768/43768/32746 43769/43769/32747 +f 43746/43746/32306 43769/43769/32747 43747/43747/32728 +f 43770/43770/32746 43723/43723/32709 43726/43726/32712 +f 43770/43770/32746 43726/43726/32712 43771/43771/32747 +f 43771/43771/32747 43726/43726/32712 43487/43487/32487 +f 43771/43771/32747 43487/43487/32487 43772/43772/32748 +f 43747/43747/32728 43769/43769/32747 43773/43773/32748 +f 43747/43747/32728 43773/43773/32748 43254/43254/32274 +f 43545/43545/32541 43774/43774/32749 43775/43775/32750 +f 43545/43545/32541 43775/43775/32750 43546/43546/32542 +f 43776/43776/32751 43661/43661/32652 43664/43664/32655 +f 43776/43776/32751 43664/43664/32655 43777/43777/32752 +f 43777/43777/32752 43664/43664/32655 43606/43606/32601 +f 43777/43777/32752 43606/43606/32601 43778/43778/32753 +f 43779/43779/32754 43777/43777/32752 43778/43778/32753 +f 43779/43779/32754 43778/43778/32753 43780/43780/32755 +f 43525/43525/32521 43781/43781/32756 43782/43782/32757 +f 43525/43525/32521 43782/43782/32757 43526/43526/32522 +f 43781/43781/32756 43783/43783/32758 43784/43784/32759 +f 43781/43781/32756 43784/43784/32759 43782/43782/32757 +f 43782/43782/32757 43784/43784/32759 43602/43602/32597 +f 43782/43782/32757 43602/43602/32597 43611/43611/32606 +f 43526/43526/32522 43782/43782/32757 43611/43611/32606 +f 43526/43526/32522 43611/43611/32606 43528/43528/32524 +f 43783/43783/32758 43785/43785/32760 43786/43786/32761 +f 43783/43783/32758 43786/43786/32761 43784/43784/32759 +f 43785/43785/32760 43780/43780/32755 43778/43778/32753 +f 43785/43785/32760 43778/43778/32753 43786/43786/32761 +f 43786/43786/32761 43778/43778/32753 43606/43606/32601 +f 43786/43786/32761 43606/43606/32601 43603/43603/32598 +f 43784/43784/32759 43786/43786/32761 43603/43603/32598 +f 43784/43784/32759 43603/43603/32598 43602/43602/32597 +f 43497/43497/32496 43787/43787/32762 43788/43788/32763 +f 43497/43497/32496 43788/43788/32763 43563/43563/32559 +f 43789/43789/32764 43483/43483/32483 43581/43581/32577 +f 43789/43789/32764 43581/43581/32577 43790/43790/32765 +f 43790/43790/32765 43581/43581/32577 43587/43587/32583 +f 43790/43790/32765 43587/43587/32583 43791/43791/32766 +f 43563/43563/32559 43788/43788/32763 43792/43792/32766 +f 43563/43563/32559 43792/43792/32766 43564/43564/32560 +f 43674/43674/32665 43793/43793/32767 43794/43794/32768 +f 43674/43674/32665 43794/43794/32768 43675/43675/32666 +f 43795/43795/32767 43515/43515/32512 43518/43518/32515 +f 43795/43795/32767 43518/43518/32515 43796/43796/32768 +f 43797/43797/32769 43527/43527/32523 43528/43528/32524 +f 43797/43797/32769 43528/43528/32524 43613/43613/32608 +f 43798/43798/32770 43797/43797/32769 43613/43613/32608 +f 43798/43798/32770 43613/43613/32608 43615/43615/32610 +f 43254/43254/32274 43773/43773/32748 43799/43799/32771 +f 43254/43254/32274 43799/43799/32771 43255/43255/32275 +f 43772/43772/32748 43487/43487/32487 43490/43490/32490 +f 43772/43772/32748 43490/43490/32490 43800/43800/32771 +f 43800/43800/32771 43490/43490/32490 43432/43432/32439 +f 43800/43800/32771 43432/43432/32439 43801/43801/32772 +f 43255/43255/32275 43799/43799/32771 43802/43802/32773 +f 43255/43255/32275 43802/43802/32773 43256/43256/32276 +f 43495/43495/32494 43767/43767/32745 43803/43803/32774 +f 43495/43495/32494 43803/43803/32774 43496/43496/32495 +f 43766/43766/32745 43472/43472/32475 43475/43475/32478 +f 43766/43766/32745 43475/43475/32478 43804/43804/32774 +f 43804/43804/32774 43475/43475/32478 43483/43483/32483 +f 43804/43804/32774 43483/43483/32483 43789/43789/32764 +f 43496/43496/32495 43803/43803/32774 43787/43787/32762 +f 43496/43496/32495 43787/43787/32762 43497/43497/32496 +f 43256/43256/32276 43802/43802/32773 43805/43805/32775 +f 43256/43256/32276 43805/43805/32775 43572/43572/32568 +f 43801/43801/32772 43432/43432/32439 43435/43435/32442 +f 43801/43801/32772 43435/43435/32442 43806/43806/32775 +f 43806/43806/32775 43435/43435/32442 43443/43443/32448 +f 43806/43806/32775 43443/43443/32448 43807/43807/32776 +f 43572/43572/32568 43805/43805/32775 43808/43808/32777 +f 43572/43572/32568 43808/43808/32777 43573/43573/32569 +f 43333/43333/32348 43332/43332/32347 43809/43809/32778 +f 43333/43333/32348 43809/43809/32778 43810/43810/32779 +f 43811/43811/32780 43731/43731/32332 43740/43740/32723 +f 43811/43811/32780 43740/43740/32723 43812/43812/32778 +f 43809/43809/32778 43737/43737/32720 43425/43425/32433 +f 43809/43809/32778 43425/43425/32433 43422/43422/32430 +f 43810/43810/32779 43809/43809/32778 43422/43422/32430 +f 43810/43810/32779 43422/43422/32430 43421/43421/32429 +f 43318/43318/32315 43317/43317/32335 43813/43813/32781 +f 43318/43318/32315 43813/43813/32781 43814/43814/32782 +f 43317/43317/32335 43187/43187/32212 43815/43815/32783 +f 43317/43317/32335 43815/43815/32783 43813/43813/32781 +f 43813/43813/32781 43815/43815/32783 43259/43259/32279 +f 43813/43813/32781 43259/43259/32279 43407/43407/32416 +f 43814/43814/32782 43813/43813/32781 43407/43407/32416 +f 43814/43814/32782 43407/43407/32416 43406/43406/32392 +f 43297/43297/32317 43296/43296/32316 43816/43816/32784 +f 43297/43297/32317 43816/43816/32784 43817/43817/32785 +f 43296/43296/32316 43295/43295/32315 43818/43818/32782 +f 43296/43296/32316 43818/43818/32782 43816/43816/32784 +f 43816/43816/32784 43818/43818/32782 43379/43379/32392 +f 43816/43816/32784 43379/43379/32392 43376/43376/32389 +f 43817/43817/32785 43816/43816/32784 43376/43376/32389 +f 43817/43817/32785 43376/43376/32389 43375/43375/32388 +f 43187/43187/32212 43186/43186/32211 43819/43819/32786 +f 43187/43187/32212 43819/43819/32786 43815/43815/32783 +f 43186/43186/32211 43185/43185/32210 43820/43820/32787 +f 43186/43186/32211 43820/43820/32787 43819/43819/32786 +f 43819/43819/32786 43820/43820/32787 43263/43263/32283 +f 43819/43819/32786 43263/43263/32283 43260/43260/32280 +f 43815/43815/32783 43819/43819/32786 43260/43260/32280 +f 43815/43815/32783 43260/43260/32280 43259/43259/32279 +f 43746/43746/32306 43821/43821/32788 43822/43822/32789 +f 43746/43746/32306 43822/43822/32789 43768/43768/32746 +f 43823/43823/32790 43297/43297/32317 43817/43817/32785 +f 43823/43823/32790 43817/43817/32785 43824/43824/32789 +f 43824/43824/32789 43817/43817/32785 43375/43375/32388 +f 43824/43824/32789 43375/43375/32388 43825/43825/32791 +f 43770/43770/32746 43824/43824/32789 43825/43825/32791 +f 43770/43770/32746 43825/43825/32791 43723/43723/32709 +f 43185/43185/32210 43826/43826/32792 43827/43827/32793 +f 43185/43185/32210 43827/43827/32793 43820/43820/32787 +f 43826/43826/32792 43828/43828/32348 43829/43829/32779 +f 43826/43826/32792 43829/43829/32779 43827/43827/32793 +f 43827/43827/32793 43829/43829/32779 43830/43830/32794 +f 43827/43827/32793 43830/43830/32794 43831/43831/32795 +f 43820/43820/32787 43827/43827/32793 43831/43831/32795 +f 43820/43820/32787 43831/43831/32795 43263/43263/32283 +f 43209/43209/32232 43832/43832/32796 43833/43833/32797 +f 43209/43209/32232 43833/43833/32797 43761/43761/32741 +f 43832/43832/32796 43834/43834/32798 43835/43835/32739 +f 43832/43832/32796 43835/43835/32739 43833/43833/32797 +f 43833/43833/32797 43835/43835/32739 43836/43836/32799 +f 43833/43833/32797 43836/43836/32799 43837/43837/32800 +f 43761/43761/32741 43833/43833/32797 43837/43837/32800 +f 43761/43761/32741 43837/43837/32800 43284/43284/32304 +f 43228/43228/32249 43838/43838/32801 43839/43839/32802 +f 43228/43228/32249 43839/43839/32802 43763/43763/32743 +f 43838/43838/32801 43840/43840/31353 43841/43841/32730 +f 43838/43838/32801 43841/43841/32730 43839/43839/32802 +f 43839/43839/32802 43841/43841/32730 43842/43842/32342 +f 43839/43839/32802 43842/43842/32342 43843/43843/32803 +f 43763/43763/32743 43839/43839/32802 43843/43843/32803 +f 43763/43763/32743 43843/43843/32803 43183/43183/32208 +f 43221/43221/32243 43844/43844/32804 43845/43845/32805 +f 43221/43221/32243 43845/43845/32805 43680/43680/32670 +f 43846/43846/32806 43847/43847/32258 43848/43848/32678 +f 43846/43846/32806 43848/43848/32678 43849/43849/32805 +f 43849/43849/32805 43848/43848/32678 43850/43850/32213 +f 43849/43849/32805 43850/43850/32213 43851/43851/32807 +f 43680/43680/32670 43845/43845/32805 43852/43852/32808 +f 43680/43680/32670 43852/43852/32808 43321/43321/32338 +f 43853/43853/32809 43854/43854/32810 43855/43855/32811 +f 43853/43853/32809 43855/43855/32811 43856/43856/32681 +f 43854/43854/32810 43857/43857/32812 43858/43858/32813 +f 43854/43854/32810 43858/43858/32813 43855/43855/32811 +f 43855/43855/32811 43858/43858/32813 43859/43859/32814 +f 43855/43855/32811 43859/43859/32814 43860/43860/32815 +f 43856/43856/32681 43855/43855/32811 43860/43860/32815 +f 43856/43856/32681 43860/43860/32815 43861/43861/32190 +f 43263/43263/32283 43831/43831/32795 43862/43862/32816 +f 43263/43263/32283 43862/43862/32816 43264/43264/32284 +f 43831/43831/32795 43830/43830/32794 43863/43863/32432 +f 43831/43831/32795 43863/43863/32432 43862/43862/32816 +f 43864/43864/32816 43431/43431/32432 43357/43357/32372 +f 43864/43864/32816 43357/43357/32372 43360/43360/32375 +f 43865/43865/32817 43864/43864/32816 43360/43360/32375 +f 43865/43865/32817 43360/43360/32375 43362/43362/32376 +f 43866/43866/32265 43867/43867/32818 43868/43868/32819 +f 43866/43866/32265 43868/43868/32819 43869/43869/32266 +f 43867/43867/32818 43384/43384/32396 43387/43387/32399 +f 43867/43867/32818 43387/43387/32399 43868/43868/32819 +f 43870/43870/32820 43392/43392/32403 43344/43344/32359 +f 43870/43870/32820 43344/43344/32359 43871/43871/32821 +f 43872/43872/32266 43870/43870/32820 43871/43871/32821 +f 43872/43872/32266 43871/43871/32821 43873/43873/32822 +f 43723/43723/32709 43825/43825/32791 43874/43874/32823 +f 43723/43723/32709 43874/43874/32823 43724/43724/32710 +f 43825/43825/32791 43375/43375/32388 43378/43378/32391 +f 43825/43825/32791 43378/43378/32391 43874/43874/32823 +f 43875/43875/32824 43383/43383/32391 43352/43352/32367 +f 43875/43875/32824 43352/43352/32367 43876/43876/32825 +f 43727/43727/32713 43875/43875/32824 43876/43876/32825 +f 43727/43727/32713 43876/43876/32825 43728/43728/32714 +f 43429/43429/32437 43719/43719/32705 43877/43877/32826 +f 43429/43429/32437 43877/43877/32826 43430/43430/32438 +f 43719/43719/32705 43718/43718/32704 43878/43878/32827 +f 43719/43719/32705 43878/43878/32827 43877/43877/32826 +f 43877/43877/32826 43878/43878/32827 43348/43348/32363 +f 43877/43877/32826 43348/43348/32363 43358/43358/32373 +f 43430/43430/32438 43877/43877/32826 43358/43358/32373 +f 43430/43430/32438 43358/43358/32373 43357/43357/32372 +f 43718/43718/32704 43742/43742/32725 43879/43879/32828 +f 43718/43718/32704 43879/43879/32828 43878/43878/32827 +f 43742/43742/32725 43728/43728/32714 43876/43876/32825 +f 43742/43742/32725 43876/43876/32825 43879/43879/32828 +f 43879/43879/32828 43876/43876/32825 43352/43352/32367 +f 43879/43879/32828 43352/43352/32367 43349/43349/32364 +f 43878/43878/32827 43879/43879/32828 43349/43349/32364 +f 43878/43878/32827 43349/43349/32364 43348/43348/32363 +f 43880/43880/32829 43881/43881/32830 43882/43882/32831 +f 43880/43880/32829 43882/43882/32831 43883/43883/32832 +f 43881/43881/32830 43873/43873/32822 43871/43871/32821 +f 43881/43881/32830 43871/43871/32821 43882/43882/32831 +f 43882/43882/32831 43871/43871/32821 43344/43344/32359 +f 43882/43882/32831 43344/43344/32359 43342/43342/32357 +f 43883/43883/32832 43882/43882/32831 43342/43342/32357 +f 43883/43883/32832 43342/43342/32357 43337/43337/32352 +f 43276/43276/32296 43884/43884/32833 43885/43885/32834 +f 43276/43276/32296 43885/43885/32834 43277/43277/32297 +f 43884/43884/32833 43880/43880/32829 43883/43883/32832 +f 43884/43884/32833 43883/43883/32832 43885/43885/32834 +f 43885/43885/32834 43883/43883/32832 43337/43337/32352 +f 43885/43885/32834 43337/43337/32352 43334/43334/32349 +f 43277/43277/32297 43885/43885/32834 43334/43334/32349 +f 43277/43277/32297 43334/43334/32349 43279/43279/32299 +f 43183/43183/32208 43843/43843/32803 43886/43886/32835 +f 43183/43183/32208 43886/43886/32835 43184/43184/32209 +f 43843/43843/32803 43842/43842/32342 43887/43887/32345 +f 43843/43843/32803 43887/43887/32345 43886/43886/32835 +f 43886/43886/32835 43887/43887/32345 43828/43828/32348 +f 43886/43886/32835 43828/43828/32348 43826/43826/32792 +f 43184/43184/32209 43886/43886/32835 43826/43826/32792 +f 43184/43184/32209 43826/43826/32792 43185/43185/32210 +f 43861/43861/32190 43860/43860/32815 43888/43888/32836 +f 43861/43861/32190 43888/43888/32836 43889/43889/32191 +f 43860/43860/32815 43859/43859/32814 43890/43890/32321 +f 43860/43860/32815 43890/43890/32321 43888/43888/32836 +f 43888/43888/32836 43890/43890/32321 43891/43891/32837 +f 43888/43888/32836 43891/43891/32837 43892/43892/32838 +f 43889/43889/32191 43888/43888/32836 43892/43892/32838 +f 43889/43889/32191 43892/43892/32838 43893/43893/32192 +f 43284/43284/32304 43837/43837/32800 43894/43894/32839 +f 43284/43284/32304 43894/43894/32839 43285/43285/32305 +f 43837/43837/32800 43836/43836/32799 43895/43895/32312 +f 43837/43837/32800 43895/43895/32312 43894/43894/32839 +f 43896/43896/32839 43292/43292/32312 43297/43297/32317 +f 43896/43896/32839 43297/43297/32317 43823/43823/32790 +f 43285/43285/32305 43894/43894/32839 43897/43897/32790 +f 43285/43285/32305 43897/43897/32790 43286/43286/32306 +f 43712/43712/32699 43898/43898/32840 43899/43899/32841 +f 43712/43712/32699 43899/43899/32841 43713/43713/32700 +f 43898/43898/32840 43900/43900/32288 43901/43901/32291 +f 43898/43898/32840 43901/43901/32291 43899/43899/32841 +f 43902/43902/32841 43278/43278/32298 43279/43279/32299 +f 43902/43902/32841 43279/43279/32299 43336/43336/32351 +f 43716/43716/32700 43902/43902/32841 43336/43336/32351 +f 43716/43716/32700 43336/43336/32351 43341/43341/32356 +f 42175/42221/31328 42174/42220/31327 43903/43903/32842 +f 42175/42221/31328 43903/43903/32842 43904/43904/32242 +f 42174/42220/31327 42173/42219/31326 43234/43234/32255 +f 42174/42220/31327 43234/43234/32255 43903/43903/32842 +f 43905/43905/32843 43906/43906/32255 43847/43847/32258 +f 43905/43905/32843 43847/43847/32258 43846/43846/32806 +f 43220/43220/32242 43907/43907/32843 43844/43844/32804 +f 43220/43220/32242 43844/43844/32804 43221/43221/32243 +f 42637/42654/31745 43908/43908/32844 43909/43909/32845 +f 42637/42654/31745 43909/43909/32845 42638/42655/31746 +f 43908/43908/32844 42151/42197/31304 43198/43198/32223 +f 43908/43908/32844 43198/43198/32223 43909/43909/32845 +f 43910/43910/32845 43911/43911/32846 43857/43857/32812 +f 43910/43910/32845 43857/43857/32812 43854/43854/32810 +f 43912/43912/31748 43910/43910/32845 43854/43854/32810 +f 43912/43912/31748 43854/43854/32810 43853/43853/32809 +f 43321/43321/32338 43852/43852/32808 43913/43913/32847 +f 43321/43321/32338 43913/43913/32847 43322/43322/32339 +f 43851/43851/32807 43850/43850/32213 43914/43914/32216 +f 43851/43851/32807 43914/43914/32216 43915/43915/32848 +f 43915/43915/32848 43914/43914/32216 43916/43916/32221 +f 43915/43915/32848 43916/43916/32221 43917/43917/32849 +f 43322/43322/32339 43913/43913/32847 43918/43918/32849 +f 43322/43322/32339 43918/43918/32849 43323/43323/32340 +f 42909/42922/31791 42908/42921/31989 43919/43919/32850 +f 42909/42922/31791 43919/43919/32850 43920/43920/31792 +f 42908/42921/31989 42680/42697/31784 43921/43921/32851 +f 42908/42921/31989 43921/43921/32851 43919/43919/32850 +f 43919/43919/32850 43921/43921/32851 42169/42215/31322 +f 43919/43919/32850 42169/42215/31322 42982/42982/32039 +f 43920/43920/31792 43919/43919/32850 42982/42982/32039 +f 43920/43920/31792 42982/42982/32039 42981/42981/32038 +f 43922/43922/32852 43923/43923/32853 43924/43924/32854 +f 43922/43922/32852 43924/43924/32854 43925/43925/32855 +f 43923/43923/32853 43926/43926/31400 43927/43927/32856 +f 43923/43923/32853 43927/43927/32856 43924/43924/32854 +f 43924/43924/32854 43927/43927/32856 42655/42672/31759 +f 43924/43924/32854 42655/42672/31759 42911/42924/31990 +f 43925/43925/32855 43924/43924/32854 42911/42924/31990 +f 43925/43925/32855 42911/42924/31990 42910/42923/31888 +f 43928/43928/32027 43929/43929/32857 43930/43930/32858 +f 43928/43928/32027 43930/43930/32858 43931/43931/32029 +f 43929/43929/32857 42596/42613/31706 42833/42848/31923 +f 43929/43929/32857 42833/42848/31923 43930/43930/32858 +f 43930/43930/32858 42833/42848/31923 42681/42698/31785 +f 43930/43930/32858 42681/42698/31785 43932/43932/32859 +f 43931/43931/32029 43930/43930/32858 43932/43932/32859 +f 43931/43931/32029 43932/43932/32859 43933/43933/31966 +f 43934/43934/32860 43935/43935/32861 43936/43936/32862 +f 43934/43934/32860 43936/43936/32862 43937/43937/32863 +f 43935/43935/32861 42789/42806/31888 42792/42809/31891 +f 43935/43935/32861 42792/42809/31891 43936/43936/32862 +f 43936/43936/32862 42792/42809/31891 42627/42644/31735 +f 43936/43936/32862 42627/42644/31735 43938/43938/32864 +f 43937/43937/32863 43936/43936/32862 43938/43938/32864 +f 43937/43937/32863 43938/43938/32864 43939/43939/31970 +f 43940/43940/31294 43941/43941/31293 43942/43942/32865 +f 43940/43940/31294 43942/43942/32865 43943/43943/32866 +f 43941/43941/31293 43944/43944/32867 43945/43945/32868 +f 43941/43941/31293 43945/43945/32868 43942/43942/32865 +f 43942/43942/32865 43945/43945/32868 42698/42715/31802 +f 43942/43942/32865 42698/42715/31802 42696/42713/31800 +f 43943/43943/32866 43942/43942/32865 42696/42713/31800 +f 43943/43943/32866 42696/42713/31800 42645/42662/31752 +f 43933/43933/31966 43932/43932/32859 43946/43946/32869 +f 43933/43933/31966 43946/43946/32869 43947/43947/32870 +f 43932/43932/32859 42681/42698/31785 42684/42701/31788 +f 43932/43932/32859 42684/42701/31788 43946/43946/32869 +f 43946/43946/32869 42684/42701/31788 42689/42706/31793 +f 43946/43946/32869 42689/42706/31793 43948/43948/32041 +f 43947/43947/32870 43946/43946/32869 43948/43948/32041 +f 43947/43947/32870 43948/43948/32041 43949/43949/32042 +f 43926/43926/31400 43950/43950/31399 43951/43951/32871 +f 43926/43926/31400 43951/43951/32871 43927/43927/32856 +f 43950/43950/31399 42194/42240/31346 42191/42237/31343 +f 43950/43950/31399 42191/42237/31343 43951/43951/32871 +f 43951/43951/32871 42191/42237/31343 42190/42236/31342 +f 43951/43951/32871 42190/42236/31342 42656/42673/31760 +f 43927/43927/32856 43951/43951/32871 42656/42673/31760 +f 43927/43927/32856 42656/42673/31760 42655/42672/31759 +f 42141/42187/31294 43952/43952/32872 43953/43953/32873 +f 42141/42187/31294 43953/43953/32873 43208/43208/32231 +f 43943/43943/32866 42645/42662/31752 42648/42665/31755 +f 43943/43943/32866 42648/42665/31755 43954/43954/32873 +f 43953/43953/32873 43955/43955/32874 43834/43834/32798 +f 43953/43953/32873 43834/43834/32798 43832/43832/32796 +f 43208/43208/32231 43953/43953/32873 43832/43832/32796 +f 43208/43208/32231 43832/43832/32796 43209/43209/32232 +f 43939/43939/31970 43938/43938/32864 43956/43956/32875 +f 43939/43939/31970 43956/43956/32875 43957/43957/31968 +f 43938/43938/32864 42627/42644/31735 42630/42647/31738 +f 43938/43938/32864 42630/42647/31738 43956/43956/32875 +f 43956/43956/32875 42630/42647/31738 42621/42638/31729 +f 43956/43956/32875 42621/42638/31729 43958/43958/32876 +f 43957/43957/31968 43956/43956/32875 43958/43958/32876 +f 43957/43957/31968 43958/43958/32876 43959/43959/31967 +f 43959/43959/31967 43958/43958/32876 43960/43960/32877 +f 43959/43959/31967 43960/43960/32877 43961/43961/32017 +f 43958/43958/32876 42621/42638/31729 42624/42641/31732 +f 43958/43958/32876 42624/42641/31732 43960/43960/32877 +f 43960/43960/32877 42624/42641/31732 42615/42632/31698 +f 43960/43960/32877 42615/42632/31698 43962/43962/32878 +f 43961/43961/32017 43960/43960/32877 43962/43962/32878 +f 43961/43961/32017 43962/43962/32878 43963/43963/32025 +f 43963/43963/32025 43962/43962/32878 43964/43964/32879 +f 43963/43963/32025 43964/43964/32879 43965/43965/32019 +f 43962/43962/32878 42615/42632/31698 42618/42635/31726 +f 43962/43962/32878 42618/42635/31726 43964/43964/32879 +f 43964/43964/32879 42618/42635/31726 42609/42626/31719 +f 43964/43964/32879 42609/42626/31719 43966/43966/32880 +f 43965/43965/32019 43964/43964/32879 43966/43966/32880 +f 43965/43965/32019 43966/43966/32880 43967/43967/32881 +f 43967/43967/32881 43966/43966/32880 43968/43968/32882 +f 43967/43967/32881 43968/43968/32882 43969/43969/32029 +f 43966/43966/32880 42609/42626/31719 42612/42629/31722 +f 43966/43966/32880 42612/42629/31722 43968/43968/32882 +f 43968/43968/32882 42612/42629/31722 42603/42620/31713 +f 43968/43968/32882 42603/42620/31713 43970/43970/32883 +f 43969/43969/32029 43968/43968/32882 43970/43970/32883 +f 43969/43969/32029 43970/43970/32883 43971/43971/32884 +f 43971/43971/32884 43970/43970/32883 43972/43972/32885 +f 43971/43971/32884 43972/43972/32885 43973/43973/32886 +f 43970/43970/32883 42603/42620/31713 42606/42623/31716 +f 43970/43970/32883 42606/42623/31716 43972/43972/32885 +f 43972/43972/32885 42606/42623/31716 42597/42614/31707 +f 43972/43972/32885 42597/42614/31707 43974/43974/32887 +f 43973/43973/32886 43972/43972/32885 43974/43974/32887 +f 43973/43973/32886 43974/43974/32887 43975/43975/32023 +f 43975/43975/32023 43974/43974/32887 43976/43976/32888 +f 43975/43975/32023 43976/43976/32888 43977/43977/32026 +f 43974/43974/32887 42597/42614/31707 42600/42617/31710 +f 43974/43974/32887 42600/42617/31710 43976/43976/32888 +f 43976/43976/32888 42600/42617/31710 42588/42605/31698 +f 43976/43976/32888 42588/42605/31698 43978/43978/32889 +f 43977/43977/32026 43976/43976/32888 43978/43978/32889 +f 43977/43977/32026 43978/43978/32889 43979/43979/32025 +f 43979/43979/32025 43978/43978/32889 43980/43980/32890 +f 43979/43979/32025 43980/43980/32890 43981/43981/32028 +f 43978/43978/32889 42588/42605/31698 42591/42608/31701 +f 43978/43978/32889 42591/42608/31701 43980/43980/32890 +f 43980/43980/32890 42591/42608/31701 42596/42613/31706 +f 43980/43980/32890 42596/42613/31706 43929/43929/32857 +f 43981/43981/32028 43980/43980/32890 43929/43929/32857 +f 43981/43981/32028 43929/43929/32857 43928/43928/32027 +f 42660/42677/31764 42659/42676/31763 43982/43982/32891 +f 42660/42677/31764 43982/43982/32891 43225/43225/32247 +f 42659/42676/31763 42190/42236/31342 42193/42239/31345 +f 42659/42676/31763 42193/42239/31345 43982/43982/32891 +f 43983/43983/32891 43984/43984/32892 43840/43840/31353 +f 43983/43983/32891 43840/43840/31353 43838/43838/32801 +f 43227/43227/32247 43983/43983/32891 43838/43838/32801 +f 43227/43227/32247 43838/43838/32801 43228/43228/32249 +f 42680/42697/31784 42679/42696/31783 43985/43985/32893 +f 42680/42697/31784 43985/43985/32893 43921/43921/32851 +f 42679/42696/31783 42674/42691/31778 43232/43232/32253 +f 42679/42696/31783 43232/43232/32253 43985/43985/32893 +f 43985/43985/32893 43232/43232/32253 42173/42219/31326 +f 43985/43985/32893 42173/42219/31326 42170/42216/31323 +f 43921/43921/32851 43985/43985/32893 42170/42216/31323 +f 43921/43921/32851 42170/42216/31323 42169/42215/31322 +f 42637/42654/31745 42695/42712/31799 43986/43986/32894 +f 42637/42654/31745 43986/43986/32894 43908/43908/32844 +f 42695/42712/31799 42694/42711/31798 43987/43987/32895 +f 42695/42712/31799 43987/43987/32895 43986/43986/32894 +f 43986/43986/32894 43987/43987/32895 42155/42201/31308 +f 43986/43986/32894 42155/42201/31308 42152/42198/31305 +f 43908/43908/32844 43986/43986/32894 42152/42198/31305 +f 43908/43908/32844 42152/42198/31305 42151/42197/31304 +f 43564/43564/32560 43792/43792/32766 43988/43988/32896 +f 43564/43564/32560 43988/43988/32896 43989/43989/32897 +f 43791/43791/32766 43587/43587/32583 43990/43990/32898 +f 43791/43791/32766 43990/43990/32898 43991/43991/32899 +f 43991/43991/32899 43990/43990/32898 43515/43515/32512 +f 43991/43991/32899 43515/43515/32512 43795/43795/32767 +f 43989/43989/32897 43988/43988/32896 43793/43793/32767 +f 43989/43989/32897 43793/43793/32767 43674/43674/32665 +f 43573/43573/32569 43808/43808/32777 43992/43992/32900 +f 43573/43573/32569 43992/43992/32900 43993/43993/32901 +f 43807/43807/32776 43443/43443/32448 43994/43994/32902 +f 43807/43807/32776 43994/43994/32902 43995/43995/32903 +f 43995/43995/32903 43994/43994/32902 43996/43996/32904 +f 43995/43995/32903 43996/43996/32904 43997/43997/32905 +f 43993/43993/32901 43992/43992/32900 43774/43774/32749 +f 43993/43993/32901 43774/43774/32749 43545/43545/32541 +f 43456/43456/32459 43565/43565/32561 43998/43998/32906 +f 43456/43456/32459 43998/43998/32906 43999/43999/32907 +f 43565/43565/32561 43564/43564/32560 43989/43989/32897 +f 43565/43565/32561 43989/43989/32897 43998/43998/32906 +f 43998/43998/32906 43989/43989/32897 43674/43674/32665 +f 43998/43998/32906 43674/43674/32665 43672/43672/32663 +f 43999/43999/32907 43998/43998/32906 43672/43672/32663 +f 43999/43999/32907 43672/43672/32663 43648/43648/32641 +f 43443/43443/32448 43442/43442/32447 44000/44000/32908 +f 43443/43443/32448 44000/44000/32908 43994/43994/32902 +f 43441/43441/32446 43440/43440/32445 44001/44001/32909 +f 43441/43441/32446 44001/44001/32909 44002/44002/32910 +f 44002/44002/32910 44001/44001/32909 43644/43644/32637 +f 44002/44002/32910 43644/43644/32637 43665/43665/32656 +f 43994/43994/32902 44000/44000/32908 44003/44003/32656 +f 43994/43994/32902 44003/44003/32656 43996/43996/32904 +f 43440/43440/32445 43457/43457/32460 44004/44004/32911 +f 43440/43440/32445 44004/44004/32911 44001/44001/32909 +f 43457/43457/32460 43456/43456/32459 43999/43999/32907 +f 43457/43457/32460 43999/43999/32907 44004/44004/32911 +f 44004/44004/32911 43999/43999/32907 43648/43648/32641 +f 44004/44004/32911 43648/43648/32641 43645/43645/32638 +f 44001/44001/32909 44004/44004/32911 43645/43645/32638 +f 44001/44001/32909 43645/43645/32638 43644/43644/32637 +f 43584/43584/32580 43589/43589/32585 44005/44005/32912 +f 43584/43584/32580 44005/44005/32912 44006/44006/32913 +f 43589/43589/32585 43575/43575/32571 44007/44007/32914 +f 43589/43589/32585 44007/44007/32914 44005/44005/32912 +f 44005/44005/32912 44007/44007/32914 43541/43541/32537 +f 44005/44005/32912 43541/43541/32537 43620/43620/32615 +f 44006/44006/32913 44005/44005/32912 43620/43620/32615 +f 44006/44006/32913 43620/43620/32615 43520/43520/32517 +f 43575/43575/32571 43574/43574/32570 44008/44008/32915 +f 43575/43575/32571 44008/44008/32915 44007/44007/32914 +f 43574/43574/32570 43573/43573/32569 43993/43993/32901 +f 43574/43574/32570 43993/43993/32901 44008/44008/32915 +f 44008/44008/32915 43993/43993/32901 43545/43545/32541 +f 44008/44008/32915 43545/43545/32541 43542/43542/32538 +f 44007/44007/32914 44008/44008/32915 43542/43542/32538 +f 44007/44007/32914 43542/43542/32538 43541/43541/32537 +f 43587/43587/32583 43586/43586/32582 44009/44009/32916 +f 43587/43587/32583 44009/44009/32916 43990/43990/32898 +f 43585/43585/32581 43584/43584/32580 44006/44006/32913 +f 43585/43585/32581 44006/44006/32913 44010/44010/32917 +f 44010/44010/32917 44006/44006/32913 43520/43520/32517 +f 44010/44010/32917 43520/43520/32517 43519/43519/32516 +f 43990/43990/32898 44009/44009/32916 43516/43516/32513 +f 43990/43990/32898 43516/43516/32513 43515/43515/32512 +f 43323/43323/32340 43918/43918/32849 44011/44011/32918 +f 43323/43323/32340 44011/44011/32918 44012/44012/32919 +f 43917/43917/32849 43916/43916/32221 44013/44013/32920 +f 43917/43917/32849 44013/44013/32920 44014/44014/32921 +f 44014/44014/32921 44013/44013/32920 43900/43900/32288 +f 44014/44014/32921 43900/43900/32288 43898/43898/32840 +f 44015/44015/32922 44014/44014/32921 43898/43898/32840 +f 44015/44015/32922 43898/43898/32840 43712/43712/32699 +f 43893/43893/32192 43892/43892/32838 44016/44016/32923 +f 43893/43893/32192 44016/44016/32923 44017/44017/32924 +f 43892/43892/32838 43891/43891/32837 44018/44018/32925 +f 43892/43892/32838 44018/44018/32925 44016/44016/32923 +f 44016/44016/32923 44018/44018/32925 43384/43384/32396 +f 44016/44016/32923 43384/43384/32396 43867/43867/32818 +f 44017/44017/32924 44016/44016/32923 43867/43867/32818 +f 44017/44017/32924 43867/43867/32818 43866/43866/32265 +f 43706/43706/32340 44019/44019/32922 44020/44020/32926 +f 43706/43706/32340 44020/44020/32926 43707/43707/32695 +f 44015/44015/32922 43712/43712/32699 43715/43715/32702 +f 44015/44015/32922 43715/43715/32702 44021/44021/32927 +f 44021/44021/32927 43715/43715/32702 43363/43363/32377 +f 44021/44021/32927 43363/43363/32377 44022/44022/32928 +f 43707/43707/32695 44020/44020/32926 44023/44023/32928 +f 43707/43707/32695 44023/44023/32928 43501/43501/32500 +f 43346/43346/32361 43391/43391/32402 44024/44024/32929 +f 43346/43346/32361 44024/44024/32929 43711/43711/32698 +f 43389/43389/32401 43388/43388/32400 43697/43697/32687 +f 43389/43389/32401 43697/43697/32687 44025/44025/32930 +f 44025/44025/32930 43697/43697/32687 43503/43503/32502 +f 44025/44025/32930 43503/43503/32502 44026/44026/32931 +f 43711/43711/32698 44024/44024/32929 44027/44027/32932 +f 43711/43711/32698 44027/44027/32932 43401/43401/32411 +f 43639/43639/32632 44028/44028/32933 44029/44029/32934 +f 43639/43639/32632 44029/44029/32934 43640/43640/32633 +f 44030/44030/32935 43653/43653/32646 43656/43656/32649 +f 44030/44030/32935 43656/43656/32649 44031/44031/32934 +f 44032/44032/32934 43660/43660/32651 43618/43618/32613 +f 44032/44032/32934 43618/43618/32613 44033/44033/32936 +f 44034/44034/32937 44032/44032/32934 44033/44033/32936 +f 44034/44034/32937 44033/44033/32936 44035/44035/32938 +f 43533/43533/32529 44036/44036/32939 44037/44037/32940 +f 43533/43533/32529 44037/44037/32940 43534/43534/32530 +f 44038/44038/32939 43624/43624/32619 43627/43627/32622 +f 44038/44038/32939 43627/43627/32622 44039/44039/32940 +f 44039/44039/32940 43627/43627/32622 43596/43596/32591 +f 44039/44039/32940 43596/43596/32591 43599/43599/32594 +f 43536/43536/32532 44039/44039/32940 43599/43599/32594 +f 43536/43536/32532 43599/43599/32594 43537/43537/32533 +f 44040/44040/32941 44041/44041/32635 44042/44042/32942 +f 44040/44040/32941 44042/44042/32942 44043/44043/32943 +f 44041/44041/32635 44035/44035/32938 44033/44033/32936 +f 44041/44041/32635 44033/44033/32936 44042/44042/32942 +f 44042/44042/32942 44033/44033/32936 43618/43618/32613 +f 44042/44042/32942 43618/43618/32613 43616/43616/32611 +f 44043/44043/32943 44042/44042/32942 43616/43616/32611 +f 44043/44043/32943 43616/43616/32611 43600/43600/32595 +f 43633/43633/32626 44044/44044/32944 44045/44045/32945 +f 43633/43633/32626 44045/44045/32945 43634/43634/32627 +f 44044/44044/32944 44040/44040/32941 44043/44043/32943 +f 44044/44044/32944 44043/44043/32943 44045/44045/32945 +f 44045/44045/32945 44043/44043/32943 43600/43600/32595 +f 44045/44045/32945 43600/43600/32595 43597/43597/32592 +f 43634/43634/32627 44045/44045/32945 43597/43597/32592 +f 43634/43634/32627 43597/43597/32592 43596/43596/32591 +f 43403/43403/32413 44046/44046/32946 44047/44047/32947 +f 43403/43403/32413 44047/44047/32947 43577/43577/32573 +f 44048/44048/32946 43511/43511/32508 43591/43591/32587 +f 44048/44048/32946 43591/43591/32587 44049/44049/32947 +f 44049/44049/32947 43591/43591/32587 43595/43595/32590 +f 44049/44049/32947 43595/43595/32590 44050/44050/32948 +f 43577/43577/32573 44047/44047/32947 44051/44051/32948 +f 43577/43577/32573 44051/44051/32948 43578/43578/32574 +f 43401/43401/32411 44027/44027/32932 44052/44052/32949 +f 43401/43401/32411 44052/44052/32949 43402/43402/32412 +f 44026/44026/32931 43503/43503/32502 43506/43506/32505 +f 44026/44026/32931 43506/43506/32505 44053/44053/32950 +f 44053/44053/32950 43506/43506/32505 43511/43511/32508 +f 44053/44053/32950 43511/43511/32508 44048/44048/32946 +f 43402/43402/32412 44052/44052/32949 44046/44046/32946 +f 43402/43402/32412 44046/44046/32946 43403/43403/32413 +f 43461/43461/32464 44054/44054/32951 44055/44055/32952 +f 43461/43461/32464 44055/44055/32952 43462/43462/32465 +f 44056/44056/32951 43374/43374/32387 43445/43445/32450 +f 44056/44056/32951 43445/43445/32450 44057/44057/32952 +f 44057/44057/32952 43445/43445/32450 43451/43451/32454 +f 44057/44057/32952 43451/43451/32454 44058/44058/32953 +f 43462/43462/32465 44055/44055/32952 44059/44059/32953 +f 43462/43462/32465 44059/44059/32953 43463/43463/32466 +f 43194/43194/32219 43306/43306/32326 44060/44060/32954 +f 43194/43194/32219 44060/44060/32954 44061/44061/32955 +f 43306/43306/32326 43169/43169/32194 44062/44062/32956 +f 43306/43306/32326 44062/44062/32956 44060/44060/32954 +f 44060/44060/32954 44062/44062/32956 43241/43241/32261 +f 44060/44060/32954 43241/43241/32261 43393/43393/32404 +f 44061/44061/32955 44060/44060/32954 43393/43393/32404 +f 44061/44061/32955 43393/43393/32404 43272/43272/32292 +f 43891/43891/32837 44063/44063/32957 44064/44064/32958 +f 43891/43891/32837 44064/44064/32958 44018/44018/32925 +f 43302/43302/32322 43178/43178/32203 44065/44065/32685 +f 43302/43302/32322 44065/44065/32685 44066/44066/32958 +f 44064/44064/32958 43695/43695/32685 43388/43388/32400 +f 44064/44064/32958 43388/43388/32400 43385/43385/32397 +f 44018/44018/32925 44064/44064/32958 43385/43385/32397 +f 44018/44018/32925 43385/43385/32397 43384/43384/32396 +f 43501/43501/32500 44023/44023/32928 44067/44067/32959 +f 43501/43501/32500 44067/44067/32959 43502/43502/32501 +f 44022/44022/32928 43363/43363/32377 43366/43366/32380 +f 44022/44022/32928 43366/43366/32380 44068/44068/32960 +f 44068/44068/32960 43366/43366/32380 43374/43374/32387 +f 44068/44068/32960 43374/43374/32387 44056/44056/32951 +f 43502/43502/32501 44067/44067/32959 44054/44054/32951 +f 43502/43502/32501 44054/44054/32951 43461/43461/32464 +f 43196/43196/32221 43195/43195/32220 44069/44069/32961 +f 43196/43196/32221 44069/44069/32961 44070/44070/32920 +f 43195/43195/32220 43194/43194/32219 44061/44061/32955 +f 43195/43195/32220 44061/44061/32955 44069/44069/32961 +f 44069/44069/32961 44061/44061/32955 43272/43272/32292 +f 44069/44069/32961 43272/43272/32292 43269/43269/32289 +f 44070/44070/32920 44069/44069/32961 43269/43269/32289 +f 44070/44070/32920 43269/43269/32289 43268/43268/32288 +f 43169/43169/32194 43168/43168/32193 44071/44071/32962 +f 43169/43169/32194 44071/44071/32962 44062/44062/32956 +f 43168/43168/32193 43167/43167/32192 44072/44072/32924 +f 43168/43168/32193 44072/44072/32924 44071/44071/32962 +f 44071/44071/32962 44072/44072/32924 43245/43245/32265 +f 44071/44071/32962 43245/43245/32265 43242/43242/32262 +f 44062/44062/32956 44071/44071/32962 43242/43242/32262 +f 44062/44062/32956 43242/43242/32262 43241/43241/32261 +f 43578/43578/32574 44051/44051/32948 44073/44073/32963 +f 43578/43578/32574 44073/44073/32963 44074/44074/32964 +f 44050/44050/32948 43595/43595/32590 44075/44075/32965 +f 44050/44050/32948 44075/44075/32965 44076/44076/32966 +f 44076/44076/32966 44075/44075/32965 44077/44077/32619 +f 44076/44076/32966 44077/44077/32619 44078/44078/32967 +f 44074/44074/32964 44073/44073/32963 44036/44036/32939 +f 44074/44074/32964 44036/44036/32939 43533/43533/32529 +f 43463/43463/32466 44059/44059/32953 44079/44079/32968 +f 43463/43463/32466 44079/44079/32968 44080/44080/32969 +f 44058/44058/32953 43451/43451/32454 44081/44081/32970 +f 44058/44058/32953 44081/44081/32970 44082/44082/32971 +f 44082/44082/32971 44081/44081/32970 43653/43653/32646 +f 44082/44082/32971 43653/43653/32646 44030/44030/32935 +f 44080/44080/32969 44079/44079/32968 44028/44028/32933 +f 44080/44080/32969 44028/44028/32933 43639/43639/32632 +f 43561/43561/32557 43560/43560/32556 44083/44083/32972 +f 43561/43561/32557 44083/44083/32972 44084/44084/32973 +f 43560/43560/32556 43465/43465/32468 44085/44085/32974 +f 43560/43560/32556 44085/44085/32974 44083/44083/32972 +f 44083/44083/32972 44085/44085/32974 43635/43635/32628 +f 44083/44083/32972 43635/43635/32628 43668/43668/32659 +f 44084/44084/32973 44083/44083/32972 43668/43668/32659 +f 44084/44084/32973 43668/43668/32659 43629/43629/32623 +f 43451/43451/32454 43450/43450/32453 44086/44086/32975 +f 43451/43451/32454 44086/44086/32975 44081/44081/32970 +f 43449/43449/32453 43448/43448/32452 44087/44087/32976 +f 43449/43449/32453 44087/44087/32976 44088/44088/32977 +f 44088/44088/32977 44087/44087/32976 43550/43550/32546 +f 44088/44088/32977 43550/43550/32546 43657/43657/32650 +f 44081/44081/32970 44086/44086/32975 43654/43654/32647 +f 44081/44081/32970 43654/43654/32647 43653/43653/32646 +f 43465/43465/32468 43464/43464/32467 44089/44089/32978 +f 43465/43465/32468 44089/44089/32978 44085/44085/32974 +f 43464/43464/32467 43463/43463/32466 44080/44080/32969 +f 43464/43464/32467 44080/44080/32969 44089/44089/32978 +f 44089/44089/32978 44080/44080/32969 43639/43639/32632 +f 44089/44089/32978 43639/43639/32632 43636/43636/32629 +f 44085/44085/32974 44089/44089/32978 43636/43636/32629 +f 44085/44085/32974 43636/43636/32629 43635/43635/32628 +f 43595/43595/32590 43594/43594/32589 44090/44090/32979 +f 43595/43595/32590 44090/44090/32979 44075/44075/32965 +f 43593/43593/32589 43561/43561/32557 44084/44084/32973 +f 43593/43593/32589 44084/44084/32973 44091/44091/32980 +f 44091/44091/32980 44084/44084/32973 43629/43629/32623 +f 44091/44091/32980 43629/43629/32623 43628/43628/32620 +f 44075/44075/32965 44090/44090/32979 44092/44092/32620 +f 44075/44075/32965 44092/44092/32620 44077/44077/32619 +f 43448/43448/32452 43569/43569/32565 44093/44093/32981 +f 43448/43448/32452 44093/44093/32981 44087/44087/32976 +f 43569/43569/32565 43568/43568/32564 44094/44094/32982 +f 43569/43569/32565 44094/44094/32982 44093/44093/32981 +f 44093/44093/32981 44094/44094/32982 43529/43529/32525 +f 44093/44093/32981 43529/43529/32525 43551/43551/32547 +f 44087/44087/32976 44093/44093/32981 43551/43551/32547 +f 44087/44087/32976 43551/43551/32547 43550/43550/32546 +f 43568/43568/32564 43579/43579/32575 44095/44095/32983 +f 43568/43568/32564 44095/44095/32983 44094/44094/32982 +f 43579/43579/32575 43578/43578/32574 44074/44074/32964 +f 43579/43579/32575 44074/44074/32964 44095/44095/32983 +f 44095/44095/32983 44074/44074/32964 43533/43533/32529 +f 44095/44095/32983 43533/43533/32529 43530/43530/32526 +f 44094/44094/32982 44095/44095/32983 43530/43530/32526 +f 44094/44094/32982 43530/43530/32526 43529/43529/32525 +o Cube.054__0 +v 1.568413 -0.615685 -0.374393 +v 1.568481 -0.617846 -0.343319 +v 1.568882 -0.580686 -0.341040 +v 1.568765 -0.579577 -0.372354 +v 1.568628 -0.619897 -0.320276 +v 1.569020 -0.581886 -0.317924 +v 1.567788 -0.555805 -0.318091 +v 1.567670 -0.554980 -0.341209 +v 1.567523 -0.554313 -0.372563 +v 1.566790 -0.689257 -0.385799 +v 1.566781 -0.693198 -0.356194 +v 1.567521 -0.660270 -0.349578 +v 1.567508 -0.656653 -0.380001 +v 1.567014 -0.689786 -0.336815 +v 1.567670 -0.662731 -0.327298 +v 1.567456 -0.685676 -0.800176 +v 1.567426 -0.687087 -0.781984 +v 1.567500 -0.658704 -0.784795 +v 1.567581 -0.661948 -0.807129 +v 1.567580 -0.681429 -0.751786 +v 1.567581 -0.654272 -0.752896 +v 1.567581 -0.619794 -0.753638 +v 1.567598 -0.621596 -0.787027 +v 1.567743 -0.623200 -0.811211 +v 1.567775 -0.676859 -0.717746 +v 1.567707 -0.651211 -0.717984 +v 1.567936 -0.675236 -0.683678 +v 1.567821 -0.650150 -0.683557 +v 1.567667 -0.618363 -0.683232 +v 1.567616 -0.618635 -0.717923 +v 1.568021 -0.676044 -0.651687 +v 1.567892 -0.650849 -0.651564 +v 1.568020 -0.678602 -0.621134 +v 1.567907 -0.652696 -0.621131 +v 1.567752 -0.619951 -0.621051 +v 1.567716 -0.618960 -0.651312 +v 1.567934 -0.682076 -0.590891 +v 1.567868 -0.654948 -0.590924 +v 1.567784 -0.685170 -0.560621 +v 1.567793 -0.656728 -0.560605 +v 1.567797 -0.621022 -0.560567 +v 1.567773 -0.620781 -0.590916 +v 1.567599 -0.686702 -0.530360 +v 1.567710 -0.657282 -0.530192 +v 1.567403 -0.686433 -0.500852 +v 1.567636 -0.656495 -0.500140 +v 1.567925 -0.618834 -0.499448 +v 1.567845 -0.620365 -0.530012 +v 1.567218 -0.684763 -0.472634 +v 1.567584 -0.654703 -0.470756 +v 1.567049 -0.683722 -0.444704 +v 1.567549 -0.653408 -0.441343 +v 1.568177 -0.614994 -0.438163 +v 1.568041 -0.616715 -0.468981 +v 1.566902 -0.685241 -0.415881 +v 1.567525 -0.654051 -0.411123 +v 1.568311 -0.614621 -0.406566 +v 1.567225 -0.588317 -0.787127 +v 1.567407 -0.587970 -0.811927 +v 1.567129 -0.588779 -0.753144 +v 1.565333 -0.566664 -0.752076 +v 1.565479 -0.564833 -0.786134 +v 1.565671 -0.563350 -0.811086 +v 1.567083 -0.589300 -0.717229 +v 1.567075 -0.589868 -0.682633 +v 1.565180 -0.569549 -0.681967 +v 1.565231 -0.568331 -0.716305 +v 1.567101 -0.590432 -0.650912 +v 1.567155 -0.590739 -0.620842 +v 1.565253 -0.570007 -0.620579 +v 1.565188 -0.570124 -0.650474 +v 1.567234 -0.590515 -0.590819 +v 1.567350 -0.589598 -0.560503 +v 1.565557 -0.567573 -0.560433 +v 1.565374 -0.569175 -0.590680 +v 1.567518 -0.587905 -0.529907 +v 1.567737 -0.585558 -0.499193 +v 1.566125 -0.562192 -0.499219 +v 1.565809 -0.565187 -0.529865 +v 1.568001 -0.582854 -0.468431 +v 1.568286 -0.580574 -0.437167 +v 1.566879 -0.556160 -0.437484 +v 1.566492 -0.558924 -0.468619 +v 1.568559 -0.579456 -0.405010 +v 1.567246 -0.554614 -0.405305 +v 1.492564 -0.500855 -0.442316 +v 1.492693 -0.498149 -0.411257 +v 1.459065 -0.484916 -0.414513 +v 1.459152 -0.488091 -0.444942 +v 1.492817 -0.497018 -0.379271 +v 1.459049 -0.483414 -0.383020 +v 1.432100 -0.475528 -0.386099 +v 1.432236 -0.477320 -0.417174 +v 1.432512 -0.480839 -0.447088 +v 1.492314 -0.508034 -0.501314 +v 1.492437 -0.504394 -0.472092 +v 1.459265 -0.491928 -0.474064 +v 1.459366 -0.495639 -0.502636 +v 1.432833 -0.484917 -0.475690 +v 1.433128 -0.488698 -0.503753 +v 1.492101 -0.513746 -0.560283 +v 1.492198 -0.511178 -0.530755 +v 1.459433 -0.498652 -0.531452 +v 1.459484 -0.501067 -0.560420 +v 1.433353 -0.491611 -0.532068 +v 1.433531 -0.493895 -0.560581 +v 1.491999 -0.516941 -0.618562 +v 1.492038 -0.515736 -0.589592 +v 1.459537 -0.503034 -0.589268 +v 1.459570 -0.504255 -0.617875 +v 1.433684 -0.495830 -0.589058 +v 1.433780 -0.497054 -0.617393 +v 1.491952 -0.516294 -0.677690 +v 1.491971 -0.517142 -0.647432 +v 1.459559 -0.504394 -0.646447 +v 1.459499 -0.503410 -0.676343 +v 1.433781 -0.497142 -0.645772 +v 1.433681 -0.496046 -0.675439 +v 1.491963 -0.512108 -0.745364 +v 1.491946 -0.514478 -0.710608 +v 1.459401 -0.501422 -0.708715 +v 1.459292 -0.498906 -0.742732 +v 1.433495 -0.493911 -0.707415 +v 1.433268 -0.491254 -0.740776 +v 1.492073 -0.507809 -0.804557 +v 1.492008 -0.509696 -0.779305 +v 1.459201 -0.496424 -0.775816 +v 1.459154 -0.494527 -0.800375 +v 1.433053 -0.488675 -0.772949 +v 1.432902 -0.486729 -0.796712 +v 1.492925 -0.497782 -0.348262 +v 1.459130 -0.484129 -0.352278 +v 1.493021 -0.499070 -0.325240 +v 1.459243 -0.485538 -0.329359 +v 1.432290 -0.477565 -0.332777 +v 1.432159 -0.476144 -0.355594 +v 1.562995 -0.541866 -0.341718 +v 1.562838 -0.541344 -0.373062 +v 1.563102 -0.542554 -0.318608 +v 1.562995 -0.541866 -0.341718 +v 1.563102 -0.542554 -0.318608 +v 1.550194 -0.532529 -0.319661 +v 1.550094 -0.531773 -0.342761 +v 1.562838 -0.541344 -0.373062 +v 1.549942 -0.531218 -0.374058 +v 1.560610 -0.552641 -0.785228 +v 1.560803 -0.550686 -0.810223 +v 1.560442 -0.555024 -0.751177 +v 1.560610 -0.552641 -0.785228 +v 1.560442 -0.555024 -0.751177 +v 1.547707 -0.545337 -0.749989 +v 1.547869 -0.542875 -0.784091 +v 1.560803 -0.550686 -0.810223 +v 1.548049 -0.540849 -0.809204 +v 1.560315 -0.557170 -0.715536 +v 1.560245 -0.558676 -0.681389 +v 1.560315 -0.557170 -0.715536 +v 1.560245 -0.558676 -0.681389 +v 1.547514 -0.549171 -0.680578 +v 1.547584 -0.547580 -0.714485 +v 1.560243 -0.559274 -0.650073 +v 1.560312 -0.558996 -0.620324 +v 1.560243 -0.559274 -0.650073 +v 1.560312 -0.558996 -0.620324 +v 1.547574 -0.549531 -0.619941 +v 1.547511 -0.549814 -0.649492 +v 1.560449 -0.557924 -0.590540 +v 1.560658 -0.556044 -0.560377 +v 1.560449 -0.557924 -0.590540 +v 1.560658 -0.556044 -0.560377 +v 1.547898 -0.546460 -0.560322 +v 1.547701 -0.548404 -0.590328 +v 1.560945 -0.553364 -0.529869 +v 1.561300 -0.550079 -0.499315 +v 1.560945 -0.553364 -0.529869 +v 1.561300 -0.550079 -0.499315 +v 1.548502 -0.540417 -0.499606 +v 1.548168 -0.543739 -0.529976 +v 1.561707 -0.546540 -0.468871 +v 1.562133 -0.543540 -0.437888 +v 1.561707 -0.546540 -0.468871 +v 1.562133 -0.543540 -0.437888 +v 1.549282 -0.533696 -0.438605 +v 1.548883 -0.536814 -0.469377 +v 1.562536 -0.541803 -0.405783 +v 1.562536 -0.541803 -0.405783 +v 1.549658 -0.531790 -0.406669 +v 1.418269 -0.476973 -0.333908 +v 1.418348 -0.476731 -0.356894 +v 1.418269 -0.476973 -0.333908 +v 1.413446 -0.495291 -0.331178 +v 1.415148 -0.500439 -0.356486 +v 1.418348 -0.476731 -0.356894 +v 1.415316 -0.500671 -0.387167 +v 1.418346 -0.476364 -0.387367 +v 1.418346 -0.476364 -0.387367 +v 1.420427 -0.497079 -0.675026 +v 1.420201 -0.494873 -0.706854 +v 1.420427 -0.497079 -0.675026 +v 1.417489 -0.521396 -0.674562 +v 1.417255 -0.519171 -0.706385 +v 1.420201 -0.494873 -0.706854 +v 1.416965 -0.516421 -0.739453 +v 1.419921 -0.492144 -0.739947 +v 1.419921 -0.492144 -0.739947 +v 1.420217 -0.495008 -0.560604 +v 1.420414 -0.496933 -0.588920 +v 1.420217 -0.495008 -0.560604 +v 1.417267 -0.519332 -0.560204 +v 1.417473 -0.521262 -0.588490 +v 1.420414 -0.496933 -0.588920 +v 1.417602 -0.522492 -0.616688 +v 1.420539 -0.498160 -0.617138 +v 1.420539 -0.498160 -0.617138 +v 1.418895 -0.481917 -0.447957 +v 1.419307 -0.486086 -0.476341 +v 1.418895 -0.481917 -0.447957 +v 1.415890 -0.506237 -0.447694 +v 1.416319 -0.510407 -0.476045 +v 1.419307 -0.486086 -0.476341 +v 1.416717 -0.514218 -0.503859 +v 1.419690 -0.489895 -0.504188 +v 1.419690 -0.489895 -0.504188 +v 1.419600 -0.489300 -0.771808 +v 1.416460 -0.512932 -0.771524 +v 1.419600 -0.489300 -0.771808 +v 1.414367 -0.503959 -0.797761 +v 1.419179 -0.486116 -0.795487 +v 1.419179 -0.486116 -0.795487 +v 1.420545 -0.498225 -0.645441 +v 1.417609 -0.522553 -0.644982 +v 1.420545 -0.498225 -0.645441 +v 1.419985 -0.492772 -0.532288 +v 1.417025 -0.517095 -0.531923 +v 1.419985 -0.492772 -0.532288 +v 1.418536 -0.478269 -0.418261 +v 1.415515 -0.502583 -0.418031 +v 1.418536 -0.478269 -0.418261 +v 1.574974 -0.615177 -0.374354 +v 1.574841 -0.577570 -0.372363 +v 1.574934 -0.578692 -0.340984 +v 1.575008 -0.617340 -0.343248 +v 1.572758 -0.550409 -0.372681 +v 1.572889 -0.551101 -0.341228 +v 1.572862 -0.552053 -0.318043 +v 1.574866 -0.579948 -0.317828 +v 1.574894 -0.619402 -0.320188 +v 1.573232 -0.689452 -0.385861 +v 1.574203 -0.656769 -0.380001 +v 1.574180 -0.660384 -0.349569 +v 1.573192 -0.693393 -0.356257 +v 1.574061 -0.662840 -0.327282 +v 1.573292 -0.689977 -0.336862 +v 1.573717 -0.685889 -0.800305 +v 1.573952 -0.662087 -0.807384 +v 1.574138 -0.658859 -0.785059 +v 1.573820 -0.687303 -0.782085 +v 1.573981 -0.622724 -0.811603 +v 1.574098 -0.621132 -0.787434 +v 1.574114 -0.619349 -0.754025 +v 1.574251 -0.654436 -0.753150 +v 1.574002 -0.681647 -0.751878 +v 1.574370 -0.651379 -0.718199 +v 1.574199 -0.677075 -0.717820 +v 1.574139 -0.618199 -0.718254 +v 1.574183 -0.617931 -0.683484 +v 1.574479 -0.650318 -0.683714 +v 1.574361 -0.675450 -0.683727 +v 1.574546 -0.651019 -0.651664 +v 1.574447 -0.676256 -0.651715 +v 1.574226 -0.618531 -0.651484 +v 1.574260 -0.619525 -0.621159 +v 1.574561 -0.652868 -0.621185 +v 1.574448 -0.678815 -0.621148 +v 1.574522 -0.655122 -0.590953 +v 1.574363 -0.682290 -0.590897 +v 1.574283 -0.620358 -0.590993 +v 1.574312 -0.620598 -0.560644 +v 1.574452 -0.656899 -0.560629 +v 1.574216 -0.685382 -0.560626 +v 1.574375 -0.657444 -0.530226 +v 1.574034 -0.686909 -0.530370 +v 1.574368 -0.619931 -0.530109 +v 1.574459 -0.618383 -0.499557 +v 1.574308 -0.656644 -0.500182 +v 1.573841 -0.686634 -0.500870 +v 1.574264 -0.654838 -0.470792 +v 1.573658 -0.684960 -0.472662 +v 1.574585 -0.616244 -0.469070 +v 1.574729 -0.614505 -0.438211 +v 1.574236 -0.653532 -0.441366 +v 1.573491 -0.683916 -0.444743 +v 1.574217 -0.654169 -0.411133 +v 1.573344 -0.685436 -0.415933 +v 1.574868 -0.614119 -0.406568 +v 1.573206 -0.585998 -0.812322 +v 1.573243 -0.586327 -0.787528 +v 1.570683 -0.559518 -0.811350 +v 1.570656 -0.560918 -0.786393 +v 1.570537 -0.562766 -0.752311 +v 1.573180 -0.586814 -0.753520 +v 1.573128 -0.587350 -0.717551 +v 1.570429 -0.564446 -0.716506 +v 1.570366 -0.565662 -0.682140 +v 1.573111 -0.587920 -0.682888 +v 1.573131 -0.588484 -0.651108 +v 1.570364 -0.566233 -0.650642 +v 1.570426 -0.566116 -0.620768 +v 1.573182 -0.588793 -0.621001 +v 1.573263 -0.588575 -0.590974 +v 1.570550 -0.565290 -0.590914 +v 1.570742 -0.563698 -0.560729 +v 1.573386 -0.587661 -0.560681 +v 1.573562 -0.585965 -0.530121 +v 1.571007 -0.561320 -0.530222 +v 1.571336 -0.558329 -0.499614 +v 1.573792 -0.583609 -0.499429 +v 1.574065 -0.580890 -0.468647 +v 1.571714 -0.555058 -0.469004 +v 1.572108 -0.552282 -0.437811 +v 1.574357 -0.578593 -0.437328 +v 1.574632 -0.577458 -0.405097 +v 1.572478 -0.550719 -0.405535 +v 1.494172 -0.494196 -0.443004 +v 1.460137 -0.481510 -0.445664 +v 1.460067 -0.478315 -0.415079 +v 1.494325 -0.491483 -0.411793 +v 1.432869 -0.474249 -0.447850 +v 1.432601 -0.470695 -0.417778 +v 1.432470 -0.468878 -0.386528 +v 1.460061 -0.476795 -0.383410 +v 1.494462 -0.490342 -0.379634 +v 1.494167 -0.499816 -0.492277 +v 1.460255 -0.487608 -0.494836 +v 1.460176 -0.485168 -0.473871 +v 1.494052 -0.497534 -0.471637 +v 1.430821 -0.480917 -0.504665 +v 1.432892 -0.478200 -0.476350 +v 1.561892 -0.546222 -0.560855 +v 1.560775 -0.547603 -0.590612 +v 1.559172 -0.544742 -0.589853 +v 1.560702 -0.543644 -0.560964 +v 1.553014 -0.544074 -0.620217 +v 1.549715 -0.539886 -0.611496 +v 1.550169 -0.538012 -0.610571 +v 1.559796 -0.542992 -0.589752 +v 1.561392 -0.541944 -0.561089 +v 1.431435 -0.489165 -0.617545 +v 1.423317 -0.485556 -0.589209 +v 1.425815 -0.484136 -0.588532 +v 1.436020 -0.488293 -0.609382 +v 1.422210 -0.483385 -0.561318 +v 1.424238 -0.481836 -0.561403 +v 1.425815 -0.484136 -0.588532 +v 1.424238 -0.481836 -0.561403 +v 1.424947 -0.480087 -0.561530 +v 1.426607 -0.482407 -0.588459 +v 1.436020 -0.488293 -0.609382 +v 1.437036 -0.486644 -0.608534 +v 1.493423 -0.509485 -0.677469 +v 1.460365 -0.496702 -0.676088 +v 1.460361 -0.497648 -0.647365 +v 1.493453 -0.510319 -0.648585 +v 1.433949 -0.489366 -0.675154 +v 1.433757 -0.490341 -0.645873 +v 1.460389 -0.497409 -0.626570 +v 1.493693 -0.510108 -0.628383 +v 1.493498 -0.505351 -0.744925 +v 1.460213 -0.492240 -0.742228 +v 1.460294 -0.494734 -0.708315 +v 1.493448 -0.507693 -0.710258 +v 1.433578 -0.484602 -0.740224 +v 1.433784 -0.487245 -0.706975 +v 1.493601 -0.501309 -0.804075 +v 1.460085 -0.488080 -0.799807 +v 1.460143 -0.489799 -0.775258 +v 1.493564 -0.502990 -0.778824 +v 1.433228 -0.480274 -0.796087 +v 1.433378 -0.482056 -0.772336 +v 1.460144 -0.477536 -0.352523 +v 1.494571 -0.491135 -0.348479 +v 1.432531 -0.469518 -0.355877 +v 1.432656 -0.471110 -0.332964 +v 1.460234 -0.479117 -0.329508 +v 1.494622 -0.492616 -0.325359 +v 1.566932 -0.535768 -0.373303 +v 1.567078 -0.536325 -0.341833 +v 1.566932 -0.535768 -0.373303 +v 1.552938 -0.524601 -0.374389 +v 1.553080 -0.525195 -0.342950 +v 1.567078 -0.536325 -0.341833 +v 1.553081 -0.526203 -0.319749 +v 1.567069 -0.537218 -0.318634 +v 1.567069 -0.537218 -0.318634 +v 1.564703 -0.545282 -0.810266 +v 1.564634 -0.547058 -0.785256 +v 1.564703 -0.545282 -0.810266 +v 1.550869 -0.534481 -0.809014 +v 1.550779 -0.536257 -0.783885 +v 1.564634 -0.547058 -0.785256 +v 1.550610 -0.538676 -0.749787 +v 1.564478 -0.549428 -0.751192 +v 1.564478 -0.549428 -0.751192 +v 1.564334 -0.551574 -0.715551 +v 1.550457 -0.540902 -0.714319 +v 1.564334 -0.551574 -0.715551 +v 1.550358 -0.542476 -0.680484 +v 1.564242 -0.553070 -0.681427 +v 1.564242 -0.553070 -0.681427 +v 1.564294 -0.553697 -0.650172 +v 1.550612 -0.543255 -0.649726 +v 1.564294 -0.553697 -0.650172 +v 1.553014 -0.544074 -0.620217 +v 1.564793 -0.553663 -0.620522 +v 1.564793 -0.553663 -0.620522 +v 1.565659 -0.553025 -0.590847 +v 1.560775 -0.547603 -0.590612 +v 1.565659 -0.553025 -0.590847 +v 1.566050 -0.551258 -0.560781 +v 1.566196 -0.548494 -0.530354 +v 1.561332 -0.542989 -0.530719 +v 1.566196 -0.548494 -0.530354 +v 1.561332 -0.542989 -0.530719 +v 1.554060 -0.534952 -0.500236 +v 1.565850 -0.544791 -0.499854 +v 1.565850 -0.544791 -0.499854 +v 1.565838 -0.541023 -0.469420 +v 1.552107 -0.530309 -0.469837 +v 1.565838 -0.541023 -0.469420 +v 1.552247 -0.527092 -0.439219 +v 1.566211 -0.537984 -0.438380 +v 1.566211 -0.537984 -0.438380 +v 1.566623 -0.536235 -0.406161 +v 1.552641 -0.525178 -0.407156 +v 1.566623 -0.536235 -0.406161 +v 1.417766 -0.466848 -0.357342 +v 1.417910 -0.468432 -0.334479 +v 1.417714 -0.466260 -0.387885 +v 1.411165 -0.466470 -0.388125 +v 1.411215 -0.467046 -0.357604 +v 1.411366 -0.468622 -0.334755 +v 1.419530 -0.484780 -0.706440 +v 1.419744 -0.486975 -0.674775 +v 1.419261 -0.482062 -0.739418 +v 1.412812 -0.482247 -0.739326 +v 1.413100 -0.484987 -0.706372 +v 1.413329 -0.487202 -0.674716 +v 1.418453 -0.486414 -0.589363 +v 1.418090 -0.484466 -0.561310 +v 1.419323 -0.487862 -0.617319 +v 1.413441 -0.488298 -0.617296 +v 1.413314 -0.487087 -0.589372 +v 1.413113 -0.485185 -0.561337 +v 1.418596 -0.476047 -0.477291 +v 1.418261 -0.471884 -0.448813 +v 1.418510 -0.479694 -0.505157 +v 1.412572 -0.480116 -0.505262 +v 1.412176 -0.476304 -0.477442 +v 1.411745 -0.472109 -0.448996 +v 1.418998 -0.479458 -0.771135 +v 1.418806 -0.477641 -0.794536 +v 1.412333 -0.477795 -0.794354 +v 1.412532 -0.479623 -0.770996 +v 1.419783 -0.488088 -0.645389 +v 1.413447 -0.488354 -0.645344 +v 1.422935 -0.481492 -0.533334 +v 1.418036 -0.482316 -0.533187 +v 1.412876 -0.482975 -0.533237 +v 1.417903 -0.468195 -0.418957 +v 1.411366 -0.468414 -0.419170 +v 1.567723 -0.699113 -0.781438 +v 1.567915 -0.692787 -0.751273 +v 1.567722 -0.693113 -0.803714 +v 1.568715 -0.694695 -0.804451 +v 1.568724 -0.700898 -0.781455 +v 1.568923 -0.694440 -0.751202 +v 1.421543 -0.614251 -0.332122 +v 1.418964 -0.615156 -0.324067 +v 1.420998 -0.639978 -0.324874 +v 1.423464 -0.639099 -0.332606 +v 1.418964 -0.615156 -0.324067 +v 1.416267 -0.614843 -0.332122 +v 1.418414 -0.639665 -0.332605 +v 1.420998 -0.639978 -0.324874 +v 1.419256 -0.643270 -0.336985 +v 1.421270 -0.643429 -0.333453 +v 1.421270 -0.643429 -0.333453 +v 1.423213 -0.642826 -0.336985 +v 1.408574 -0.483503 -0.533255 +v 1.408264 -0.480640 -0.505283 +v 1.408816 -0.485717 -0.561350 +v 1.405955 -0.486139 -0.561343 +v 1.405711 -0.483922 -0.533245 +v 1.405399 -0.481059 -0.505273 +v 1.561067 -0.549596 -0.820499 +v 1.565985 -0.562556 -0.821349 +v 1.548267 -0.539670 -0.819526 +v 1.561067 -0.549596 -0.820499 +v 1.561067 -0.549596 -0.820499 +v 1.548267 -0.539670 -0.819526 +v 1.548719 -0.538552 -0.820973 +v 1.561682 -0.548635 -0.821974 +v 1.561682 -0.548635 -0.821974 +v 1.566771 -0.561873 -0.822856 +v 1.411556 -0.470743 -0.323934 +v 1.411463 -0.469650 -0.325310 +v 1.407156 -0.470078 -0.326639 +v 1.407251 -0.471168 -0.325311 +v 1.407120 -0.469076 -0.335708 +v 1.404785 -0.469045 -0.340178 +v 1.404302 -0.469719 -0.335700 +v 1.407251 -0.471168 -0.325311 +v 1.407156 -0.470078 -0.326639 +v 1.404302 -0.469719 -0.335700 +v 1.404305 -0.470787 -0.334741 +v 1.569689 -0.559621 -0.823015 +v 1.563951 -0.545554 -0.822009 +v 1.564550 -0.544815 -0.820547 +v 1.570461 -0.559110 -0.821592 +v 1.563951 -0.545554 -0.822009 +v 1.550328 -0.534968 -0.820870 +v 1.550763 -0.534076 -0.819364 +v 1.564550 -0.544815 -0.820547 +v 1.422517 -0.623380 -0.792631 +v 1.423878 -0.625169 -0.769262 +v 1.425764 -0.650122 -0.768648 +v 1.424454 -0.648374 -0.791254 +v 1.424328 -0.627798 -0.737532 +v 1.426207 -0.652744 -0.737095 +v 1.425395 -0.657026 -0.737023 +v 1.425001 -0.654419 -0.768041 +v 1.424277 -0.652810 -0.786631 +v 1.568286 -0.693442 -0.590873 +v 1.568105 -0.697093 -0.560626 +v 1.568393 -0.689446 -0.621129 +v 1.569405 -0.691024 -0.621128 +v 1.569296 -0.695094 -0.590871 +v 1.569111 -0.698825 -0.560627 +v 1.412671 -0.482028 -0.805874 +v 1.412918 -0.485143 -0.805128 +v 1.408855 -0.486879 -0.804425 +v 1.408484 -0.482623 -0.804523 +v 1.414367 -0.503959 -0.797761 +v 1.410785 -0.510867 -0.803378 +v 1.408855 -0.486879 -0.804425 +v 1.410785 -0.510867 -0.803378 +v 1.408127 -0.512729 -0.794565 +v 1.406105 -0.488177 -0.794956 +v 1.408484 -0.482623 -0.804523 +v 1.405711 -0.483725 -0.794913 +v 1.432653 -0.473221 -0.322124 +v 1.460087 -0.481213 -0.318636 +v 1.460233 -0.480127 -0.320009 +v 1.432701 -0.472129 -0.323498 +v 1.494324 -0.494682 -0.314453 +v 1.494568 -0.493592 -0.315826 +v 1.407861 -0.476830 -0.477464 +v 1.407423 -0.472641 -0.449017 +v 1.404994 -0.477248 -0.477454 +v 1.404555 -0.473060 -0.449009 +v 1.568055 -0.664969 -0.318385 +v 1.569033 -0.620770 -0.310775 +v 1.567170 -0.697701 -0.333713 +v 1.568143 -0.699373 -0.333083 +v 1.569067 -0.665465 -0.317136 +v 1.570029 -0.620822 -0.309403 +v 1.573503 -0.620515 -0.309349 +v 1.572597 -0.665520 -0.317128 +v 1.573625 -0.665060 -0.318372 +v 1.574498 -0.620313 -0.310691 +v 1.571697 -0.699481 -0.333122 +v 1.572750 -0.697870 -0.333771 +v 1.417075 -0.634769 -0.614743 +v 1.417082 -0.634830 -0.643038 +v 1.419290 -0.659738 -0.642601 +v 1.419283 -0.659677 -0.614307 +v 1.416960 -0.633670 -0.672623 +v 1.419168 -0.658578 -0.672187 +v 1.420660 -0.662602 -0.672114 +v 1.420781 -0.663762 -0.642529 +v 1.420774 -0.663701 -0.614234 +v 1.569367 -0.582341 -0.308403 +v 1.568062 -0.556014 -0.308574 +v 1.570287 -0.582122 -0.307026 +v 1.568851 -0.555491 -0.307202 +v 1.571342 -0.709239 -0.358626 +v 1.572414 -0.707259 -0.358429 +v 1.571383 -0.705011 -0.388789 +v 1.572455 -0.703091 -0.388436 +v 1.525477 -0.516732 -0.321870 +v 1.525620 -0.516887 -0.312368 +v 1.493134 -0.499394 -0.315753 +v 1.550374 -0.532554 -0.310155 +v 1.550829 -0.531615 -0.308803 +v 1.525961 -0.515935 -0.311020 +v 1.493387 -0.498490 -0.314409 +v 1.407041 -0.468953 -0.419191 +v 1.406837 -0.467012 -0.388148 +v 1.404171 -0.469374 -0.419185 +v 1.403965 -0.467435 -0.388144 +v 1.566805 -0.707088 -0.358344 +v 1.566828 -0.702921 -0.388355 +v 1.567795 -0.704902 -0.388735 +v 1.567770 -0.709130 -0.358568 +v 1.527193 -0.512168 -0.311057 +v 1.527529 -0.511065 -0.312430 +v 1.552480 -0.528050 -0.308826 +v 1.552931 -0.526994 -0.310197 +v 1.527633 -0.510166 -0.321980 +v 1.424620 -0.630555 -0.704454 +v 1.426499 -0.655501 -0.704018 +v 1.424854 -0.632785 -0.672624 +v 1.426733 -0.657731 -0.672187 +v 1.425922 -0.662012 -0.672114 +v 1.425688 -0.659782 -0.703945 +v 1.567878 -0.699036 -0.530432 +v 1.567633 -0.698977 -0.501166 +v 1.568878 -0.700826 -0.530443 +v 1.568626 -0.700796 -0.501212 +v 1.567780 -0.587746 -0.822127 +v 1.568153 -0.623870 -0.821142 +v 1.568697 -0.587422 -0.823643 +v 1.569147 -0.623895 -0.822619 +v 1.568137 -0.687585 -0.717619 +v 1.568314 -0.685733 -0.683716 +v 1.569148 -0.689147 -0.717602 +v 1.569327 -0.687262 -0.683720 +v 1.567393 -0.697346 -0.473464 +v 1.567171 -0.696403 -0.446190 +v 1.568379 -0.699172 -0.473587 +v 1.568149 -0.698243 -0.446410 +v 1.406907 -0.467569 -0.357805 +v 1.404123 -0.467937 -0.358328 +v 1.402792 -0.468903 -0.388048 +v 1.403006 -0.469440 -0.357563 +v 1.403053 -0.468415 -0.357788 +v 1.402846 -0.467889 -0.388120 +v 1.403053 -0.468415 -0.357788 +v 1.402846 -0.467889 -0.388120 +v 1.459336 -0.485948 -0.319907 +v 1.432367 -0.477992 -0.323361 +v 1.459495 -0.485064 -0.318572 +v 1.432432 -0.477107 -0.322037 +v 1.527483 -0.508202 -0.376501 +v 1.527613 -0.508916 -0.345160 +v 1.525887 -0.518628 -0.807122 +v 1.525804 -0.520338 -0.781779 +v 1.525658 -0.522707 -0.747611 +v 1.525531 -0.524966 -0.712432 +v 1.525450 -0.526624 -0.679065 +v 1.525523 -0.527373 -0.649534 +v 1.525939 -0.527164 -0.628245 +v 1.461247 -0.496261 -0.618311 +v 1.494261 -0.508951 -0.620239 +v 1.461247 -0.496261 -0.618311 +v 1.436020 -0.488293 -0.609382 +v 1.437036 -0.486644 -0.608534 +v 1.461975 -0.494622 -0.617254 +v 1.494261 -0.508951 -0.620239 +v 1.494995 -0.507346 -0.619164 +v 1.461134 -0.487598 -0.503371 +v 1.435558 -0.481194 -0.512952 +v 1.494675 -0.499749 -0.500818 +v 1.461134 -0.487598 -0.503371 +v 1.494675 -0.499749 -0.500818 +v 1.495389 -0.498299 -0.502175 +v 1.461854 -0.486115 -0.504695 +v 1.435558 -0.481194 -0.512952 +v 1.436581 -0.479677 -0.514050 +v 1.526861 -0.516808 -0.492063 +v 1.526707 -0.514404 -0.470156 +v 1.526932 -0.511256 -0.440764 +v 1.527243 -0.509007 -0.409038 +v 1.525383 -0.515716 -0.344949 +v 1.525250 -0.515038 -0.376143 +v 1.523663 -0.527192 -0.782151 +v 1.523804 -0.525235 -0.807485 +v 1.523536 -0.529616 -0.747959 +v 1.523443 -0.531901 -0.712714 +v 1.523395 -0.533582 -0.679240 +v 1.523395 -0.534310 -0.648542 +v 1.523442 -0.534059 -0.619311 +v 1.523537 -0.532893 -0.589983 +v 1.523685 -0.530916 -0.560268 +v 1.523892 -0.528242 -0.530255 +v 1.524147 -0.524985 -0.500266 +v 1.524435 -0.521371 -0.470457 +v 1.524737 -0.518082 -0.440097 +v 1.525024 -0.515837 -0.408513 +v 1.405633 -0.501711 -0.387194 +v 1.405848 -0.502255 -0.356821 +v 1.403825 -0.477697 -0.357262 +v 1.403610 -0.477150 -0.387642 +v 1.407145 -0.503600 -0.334070 +v 1.405123 -0.479047 -0.334506 +v 1.404729 -0.474592 -0.334603 +v 1.403430 -0.473239 -0.357373 +v 1.403215 -0.472693 -0.387774 +v 1.407055 -0.515238 -0.503887 +v 1.406651 -0.511430 -0.476075 +v 1.404629 -0.486875 -0.476545 +v 1.405033 -0.490682 -0.504357 +v 1.406215 -0.507266 -0.447723 +v 1.404192 -0.482710 -0.448188 +v 1.403800 -0.478263 -0.448372 +v 1.404236 -0.482432 -0.476743 +v 1.404640 -0.486239 -0.504557 +v 1.407613 -0.520357 -0.560221 +v 1.407367 -0.518116 -0.531947 +v 1.405345 -0.493558 -0.532413 +v 1.405591 -0.495796 -0.560678 +v 1.404952 -0.489112 -0.532599 +v 1.405197 -0.491346 -0.560837 +v 1.405290 -0.479930 -0.794514 +v 1.404347 -0.481982 -0.771159 +v 1.404398 -0.480991 -0.770880 +v 1.405302 -0.479012 -0.793470 +v 1.404471 -0.484649 -0.739472 +v 1.404526 -0.483640 -0.739378 +v 1.404398 -0.480991 -0.770880 +v 1.404526 -0.483640 -0.739378 +v 1.405643 -0.483189 -0.739348 +v 1.405476 -0.480598 -0.770314 +v 1.405302 -0.479012 -0.793470 +v 1.405859 -0.479051 -0.788891 +v 1.407838 -0.522422 -0.674563 +v 1.407960 -0.523581 -0.644981 +v 1.405937 -0.499017 -0.645399 +v 1.405816 -0.497859 -0.674971 +v 1.407953 -0.523520 -0.616690 +v 1.405930 -0.498955 -0.617121 +v 1.405536 -0.494498 -0.617200 +v 1.405544 -0.494559 -0.645440 +v 1.405422 -0.493402 -0.674980 +v 1.407307 -0.517438 -0.739467 +v 1.407602 -0.520194 -0.706391 +v 1.405579 -0.495633 -0.706791 +v 1.405284 -0.492880 -0.739861 +v 1.405186 -0.491178 -0.706775 +v 1.404891 -0.488427 -0.739828 +v 1.407184 -0.514774 -0.771197 +v 1.405162 -0.490219 -0.771588 +v 1.404768 -0.485767 -0.771547 +v 1.409021 -0.487623 -0.589379 +v 1.409150 -0.488835 -0.617297 +v 1.406291 -0.489258 -0.617295 +v 1.406161 -0.488045 -0.589374 +v 1.416735 -0.631605 -0.558265 +v 1.416944 -0.633538 -0.586548 +v 1.419151 -0.658446 -0.586111 +v 1.418943 -0.656513 -0.557829 +v 1.420643 -0.662470 -0.586039 +v 1.420435 -0.660537 -0.557756 +v 1.409157 -0.488891 -0.645341 +v 1.409036 -0.487736 -0.674715 +v 1.406175 -0.488158 -0.674719 +v 1.406297 -0.489313 -0.645342 +v 1.418169 -0.475688 -0.324782 +v 1.412112 -0.477572 -0.324556 +v 1.418169 -0.475688 -0.324782 +v 1.418125 -0.474423 -0.323552 +v 1.412112 -0.477572 -0.324556 +v 1.418169 -0.475688 -0.324782 +v 1.418125 -0.474423 -0.323552 +v 1.411878 -0.474582 -0.323823 +v 1.417248 -0.623971 -0.792630 +v 1.419809 -0.623002 -0.800871 +v 1.421863 -0.648021 -0.799163 +v 1.419411 -0.648939 -0.791254 +v 1.419809 -0.623002 -0.800871 +v 1.421863 -0.648021 -0.799163 +v 1.422278 -0.652850 -0.790241 +v 1.422278 -0.652850 -0.790241 +v 1.420326 -0.653253 -0.786631 +v 1.408801 -0.485517 -0.706377 +v 1.408507 -0.482770 -0.739338 +v 1.405939 -0.485937 -0.706384 +v 1.424975 -0.633945 -0.643038 +v 1.426854 -0.658890 -0.642602 +v 1.424968 -0.633884 -0.614743 +v 1.426847 -0.658829 -0.614307 +v 1.426036 -0.663111 -0.614234 +v 1.426043 -0.663172 -0.642529 +v 1.459176 -0.493479 -0.810475 +v 1.492173 -0.506738 -0.814950 +v 1.432854 -0.485668 -0.806471 +v 1.432896 -0.484570 -0.807771 +v 1.459317 -0.492382 -0.811833 +v 1.492415 -0.505626 -0.816363 +v 1.408245 -0.480152 -0.770837 +v 1.408115 -0.478374 -0.793434 +v 1.416177 -0.626483 -0.501927 +v 1.416489 -0.629362 -0.529988 +v 1.418697 -0.654271 -0.529552 +v 1.418385 -0.651391 -0.501491 +v 1.420189 -0.658295 -0.529479 +v 1.419878 -0.655415 -0.501418 +v 1.423734 -0.641298 -0.384732 +v 1.423663 -0.641789 -0.355059 +v 1.421160 -0.642347 -0.354706 +v 1.421117 -0.641853 -0.384727 +v 1.423213 -0.642826 -0.336985 +v 1.421270 -0.643429 -0.333453 +v 1.419256 -0.643270 -0.336985 +v 1.418612 -0.642355 -0.355058 +v 1.418458 -0.641890 -0.384732 +v 1.424277 -0.652810 -0.786631 +v 1.425001 -0.654419 -0.768041 +v 1.422497 -0.654921 -0.768393 +v 1.422278 -0.652850 -0.790241 +v 1.425395 -0.657026 -0.737023 +v 1.422783 -0.657580 -0.737018 +v 1.420129 -0.657616 -0.737022 +v 1.419959 -0.654984 -0.768041 +v 1.420326 -0.653253 -0.786631 +v 1.425688 -0.659782 -0.703945 +v 1.423077 -0.660336 -0.703941 +v 1.425922 -0.662012 -0.672114 +v 1.423312 -0.662566 -0.672110 +v 1.420660 -0.662602 -0.672114 +v 1.420424 -0.660372 -0.703945 +v 1.426043 -0.663172 -0.642529 +v 1.423434 -0.663726 -0.642524 +v 1.426036 -0.663111 -0.614234 +v 1.423426 -0.663665 -0.614229 +v 1.420774 -0.663701 -0.614234 +v 1.420781 -0.663762 -0.642529 +v 1.424312 -0.646851 -0.445256 +v 1.423934 -0.643206 -0.415594 +v 1.421318 -0.643761 -0.415590 +v 1.421696 -0.647406 -0.445251 +v 1.418659 -0.643798 -0.415594 +v 1.419039 -0.647442 -0.445256 +v 1.425145 -0.654824 -0.501419 +v 1.424745 -0.651016 -0.473607 +v 1.422131 -0.651570 -0.473602 +v 1.422533 -0.655378 -0.501414 +v 1.419475 -0.651606 -0.473606 +v 1.419878 -0.655415 -0.501418 +v 1.425699 -0.659947 -0.557757 +v 1.425455 -0.657704 -0.529480 +v 1.422843 -0.658258 -0.529475 +v 1.423088 -0.660501 -0.557752 +v 1.420189 -0.658295 -0.529479 +v 1.420435 -0.660537 -0.557756 +v 1.425906 -0.661880 -0.586039 +v 1.423296 -0.662434 -0.586035 +v 1.420643 -0.662470 -0.586039 +v 1.416724 -0.631440 -0.704454 +v 1.418931 -0.656349 -0.704018 +v 1.416429 -0.628684 -0.737531 +v 1.418637 -0.653592 -0.737095 +v 1.420129 -0.657616 -0.737022 +v 1.420424 -0.660372 -0.703945 +v 1.422670 -0.612071 -0.385241 +v 1.422554 -0.612650 -0.354871 +v 1.424437 -0.637576 -0.354609 +v 1.424548 -0.637016 -0.384805 +v 1.423663 -0.641789 -0.355059 +v 1.423734 -0.641298 -0.384732 +v 1.423246 -0.617624 -0.445765 +v 1.422870 -0.613979 -0.416103 +v 1.424748 -0.638924 -0.415667 +v 1.425125 -0.642569 -0.445329 +v 1.423934 -0.643206 -0.415594 +v 1.424312 -0.646851 -0.445256 +v 1.416306 -0.626018 -0.769262 +v 1.418509 -0.650936 -0.768647 +v 1.419959 -0.654984 -0.768041 +v 1.424078 -0.625597 -0.501928 +v 1.423678 -0.621788 -0.474116 +v 1.425557 -0.646734 -0.473680 +v 1.425957 -0.650542 -0.501491 +v 1.424745 -0.651016 -0.473607 +v 1.425145 -0.654824 -0.501419 +v 1.414969 -0.613500 -0.354871 +v 1.417170 -0.638390 -0.354609 +v 1.414755 -0.612958 -0.385241 +v 1.416963 -0.637866 -0.384805 +v 1.418458 -0.641890 -0.384732 +v 1.418612 -0.642355 -0.355058 +v 1.414957 -0.614866 -0.416103 +v 1.417165 -0.639774 -0.415666 +v 1.415337 -0.618510 -0.445765 +v 1.417545 -0.643419 -0.445328 +v 1.419039 -0.647442 -0.445256 +v 1.418659 -0.643798 -0.415594 +v 1.424631 -0.630720 -0.558266 +v 1.424387 -0.628477 -0.529989 +v 1.426266 -0.653422 -0.529552 +v 1.426510 -0.655665 -0.557829 +v 1.425455 -0.657704 -0.529480 +v 1.425699 -0.659947 -0.557757 +v 1.415773 -0.622674 -0.474115 +v 1.417981 -0.647583 -0.473679 +v 1.419475 -0.651606 -0.473606 +v 1.424838 -0.632653 -0.586548 +v 1.426716 -0.657598 -0.586112 +v 1.425906 -0.661880 -0.586039 +v 1.420490 -0.576922 -0.587523 +v 1.420620 -0.578153 -0.615718 +v 1.420284 -0.574989 -0.559240 +v 1.411206 -0.566962 -0.475092 +v 1.410770 -0.562798 -0.446741 +v 1.411610 -0.570770 -0.502904 +v 1.420040 -0.572747 -0.530962 +v 1.419731 -0.569868 -0.502901 +v 1.405835 -0.503620 -0.418059 +v 1.410389 -0.559153 -0.417079 +v 1.410187 -0.557245 -0.386217 +v 1.410402 -0.557787 -0.355846 +v 1.411700 -0.559130 -0.333097 +v 1.419332 -0.566059 -0.475089 +v 1.418900 -0.561893 -0.446738 +v 1.411739 -0.570305 -0.770235 +v 1.411861 -0.572971 -0.738505 +v 1.412681 -0.568259 -0.793604 +v 1.418523 -0.558247 -0.417076 +v 1.418324 -0.556339 -0.386214 +v 1.418188 -0.556716 -0.355767 +v 1.417080 -0.557715 -0.332787 +v 1.412157 -0.575728 -0.705428 +v 1.412393 -0.577957 -0.673597 +v 1.411922 -0.573650 -0.530965 +v 1.412168 -0.575892 -0.559242 +v 1.420628 -0.578214 -0.644013 +v 1.420506 -0.577055 -0.673598 +v 1.415257 -0.567072 -0.801931 +v 1.410785 -0.510867 -0.803378 +v 1.418049 -0.566794 -0.793947 +v 1.415257 -0.567072 -0.801931 +v 1.407822 -0.522289 -0.588500 +v 1.412377 -0.577825 -0.587524 +v 1.412508 -0.579056 -0.615718 +v 1.420272 -0.574825 -0.705428 +v 1.419981 -0.572069 -0.738504 +v 1.412515 -0.579117 -0.644012 +v 1.419510 -0.569225 -0.770320 +v 1.409949 -0.503106 -0.325482 +v 1.414414 -0.559239 -0.324965 +v 1.409949 -0.503106 -0.325482 +v 1.414414 -0.559239 -0.324965 +v 1.418934 -0.483373 -0.804873 +v 1.412918 -0.485143 -0.805128 +v 1.418934 -0.483373 -0.804873 +v 1.418934 -0.483373 -0.804873 +v 1.418867 -0.481908 -0.806071 +v 1.432854 -0.485668 -0.806471 +v 1.432896 -0.484570 -0.807771 +v 1.418024 -0.470549 -0.323654 +v 1.417987 -0.469456 -0.325030 +v 1.405798 -0.497725 -0.588944 +v 1.405406 -0.493271 -0.589065 +v 1.404768 -0.487402 -0.706485 +v 1.404822 -0.486391 -0.706409 +v 1.405005 -0.489626 -0.674787 +v 1.405059 -0.488614 -0.674736 +v 1.404822 -0.486391 -0.706409 +v 1.405059 -0.488614 -0.674736 +v 1.405127 -0.490784 -0.645368 +v 1.405182 -0.489771 -0.645349 +v 1.405120 -0.490729 -0.617270 +v 1.405175 -0.489716 -0.617289 +v 1.405182 -0.489771 -0.645349 +v 1.405175 -0.489716 -0.617289 +v 1.404990 -0.489512 -0.589293 +v 1.405046 -0.488502 -0.589354 +v 1.404783 -0.487599 -0.561212 +v 1.404838 -0.486593 -0.561310 +v 1.405046 -0.488502 -0.589354 +v 1.404838 -0.486593 -0.561310 +v 1.404538 -0.485375 -0.533078 +v 1.404593 -0.484374 -0.533204 +v 1.404226 -0.482506 -0.505088 +v 1.404281 -0.481508 -0.505228 +v 1.404593 -0.484374 -0.533204 +v 1.404281 -0.481508 -0.505228 +v 1.403820 -0.478695 -0.477271 +v 1.403876 -0.477696 -0.477409 +v 1.403381 -0.474512 -0.448845 +v 1.403436 -0.473509 -0.448968 +v 1.403876 -0.477696 -0.477409 +v 1.403436 -0.473509 -0.448968 +v 1.402997 -0.470836 -0.419053 +v 1.403051 -0.469827 -0.419152 +v 1.403051 -0.469827 -0.419152 +v 1.403812 -0.479060 -0.418515 +v 1.403418 -0.474608 -0.418675 +v 1.412274 -0.477318 -0.803994 +v 1.408001 -0.477932 -0.802695 +v 1.412347 -0.478195 -0.805471 +v 1.408074 -0.478814 -0.804121 +v 1.408001 -0.477932 -0.802695 +v 1.408074 -0.478814 -0.804121 +v 1.525495 -0.519173 -0.819130 +v 1.525816 -0.518246 -0.817582 +v 1.493309 -0.501809 -0.816074 +v 1.493545 -0.500907 -0.814511 +v 1.566262 -0.538782 -0.307726 +v 1.566876 -0.537893 -0.309088 +v 1.566262 -0.538782 -0.307726 +v 1.571828 -0.553291 -0.307155 +v 1.572614 -0.552652 -0.308505 +v 1.566876 -0.537893 -0.309088 +v 1.568403 -0.686588 -0.651731 +v 1.569417 -0.688123 -0.651736 +v 1.567961 -0.664401 -0.816072 +v 1.568974 -0.664916 -0.817371 +v 1.459873 -0.488526 -0.811486 +v 1.460021 -0.487642 -0.809952 +v 1.433094 -0.480686 -0.807388 +v 1.433153 -0.479806 -0.805894 +v 1.571547 -0.700298 -0.418336 +v 1.572612 -0.698465 -0.418046 +v 1.571759 -0.698349 -0.446440 +v 1.572816 -0.696569 -0.446234 +v 1.566974 -0.698297 -0.417982 +v 1.567946 -0.700190 -0.418293 +v 1.523969 -0.524094 -0.817906 +v 1.524304 -0.522950 -0.819341 +v 1.548719 -0.538552 -0.820973 +v 1.571996 -0.699276 -0.473603 +v 1.573044 -0.697511 -0.473489 +v 1.572247 -0.700901 -0.501218 +v 1.573286 -0.699142 -0.501175 +v 1.563322 -0.542607 -0.309097 +v 1.563322 -0.542607 -0.309097 +v 1.563941 -0.541822 -0.307736 +v 1.550374 -0.532554 -0.310155 +v 1.563322 -0.542607 -0.309097 +v 1.563941 -0.541822 -0.307736 +v 1.550829 -0.531615 -0.308803 +v 1.572502 -0.700932 -0.530443 +v 1.573533 -0.699204 -0.530434 +v 1.572735 -0.698933 -0.560626 +v 1.573759 -0.697264 -0.560626 +v 1.573622 -0.580958 -0.306960 +v 1.574539 -0.580584 -0.308303 +v 1.572918 -0.695202 -0.590869 +v 1.573938 -0.693613 -0.590872 +v 1.573024 -0.691132 -0.621125 +v 1.574041 -0.689617 -0.621127 +v 1.418755 -0.478040 -0.805671 +v 1.418736 -0.477162 -0.804194 +v 1.572258 -0.694811 -0.804497 +v 1.572486 -0.664986 -0.817505 +v 1.573511 -0.664515 -0.816287 +v 1.573286 -0.693297 -0.803795 +v 1.572593 -0.623594 -0.822835 +v 1.573584 -0.623423 -0.821482 +v 1.413446 -0.495291 -0.331178 +v 1.408031 -0.479220 -0.325250 +v 1.409949 -0.503106 -0.325482 +v 1.407662 -0.474985 -0.325194 +v 1.408031 -0.479220 -0.325250 +v 1.407662 -0.474985 -0.325194 +v 1.573029 -0.688231 -0.651731 +v 1.574045 -0.686759 -0.651728 +v 1.572931 -0.687371 -0.683716 +v 1.573949 -0.685906 -0.683717 +v 1.571986 -0.586231 -0.823869 +v 1.572894 -0.585947 -0.822477 +v 1.572741 -0.689258 -0.717603 +v 1.573762 -0.687761 -0.717630 +v 1.572502 -0.694553 -0.751207 +v 1.573529 -0.692966 -0.751292 +v 1.408279 -0.480718 -0.804322 +v 1.412508 -0.480112 -0.805672 +v 1.405500 -0.481828 -0.794713 +v 1.408279 -0.480718 -0.804322 +v 1.408074 -0.478814 -0.804121 +v 1.412347 -0.478195 -0.805471 +v 1.411556 -0.470743 -0.323934 +v 1.407251 -0.471168 -0.325311 +v 1.407456 -0.473077 -0.325252 +v 1.411717 -0.472662 -0.323878 +v 1.404517 -0.472690 -0.334672 +v 1.407456 -0.473077 -0.325252 +v 1.404558 -0.483874 -0.771353 +v 1.404681 -0.486538 -0.739650 +v 1.404976 -0.489290 -0.706630 +v 1.405213 -0.491514 -0.674884 +v 1.405335 -0.492672 -0.645404 +v 1.405328 -0.492613 -0.617235 +v 1.405198 -0.491392 -0.589179 +v 1.404990 -0.489472 -0.561024 +v 1.404745 -0.487244 -0.532839 +v 1.404433 -0.484373 -0.504823 +v 1.404028 -0.480564 -0.477007 +v 1.403590 -0.476388 -0.448608 +v 1.403207 -0.472722 -0.418864 +v 1.403004 -0.470798 -0.387912 +v 1.403218 -0.471340 -0.357468 +v 1.494324 -0.494682 -0.314453 +v 1.460087 -0.481213 -0.318636 +v 1.459791 -0.483139 -0.318604 +v 1.493855 -0.496586 -0.314431 +v 1.432653 -0.473221 -0.322124 +v 1.432542 -0.475164 -0.322081 +v 1.432432 -0.477107 -0.322037 +v 1.459495 -0.485064 -0.318572 +v 1.493387 -0.498490 -0.314409 +v 1.493309 -0.501809 -0.816074 +v 1.525495 -0.519173 -0.819130 +v 1.524899 -0.521062 -0.819235 +v 1.492862 -0.503717 -0.816219 +v 1.550328 -0.534968 -0.820870 +v 1.549523 -0.536760 -0.820921 +v 1.524304 -0.522950 -0.819341 +v 1.492415 -0.505626 -0.816363 +v 1.571828 -0.553291 -0.307155 +v 1.566262 -0.538782 -0.307726 +v 1.565101 -0.540302 -0.307731 +v 1.570339 -0.554391 -0.307178 +v 1.552480 -0.528050 -0.308826 +v 1.551655 -0.529833 -0.308814 +v 1.568851 -0.555491 -0.307202 +v 1.572258 -0.694811 -0.804497 +v 1.572286 -0.701012 -0.781464 +v 1.570505 -0.700955 -0.781460 +v 1.570487 -0.694753 -0.804473 +v 1.572502 -0.694553 -0.751207 +v 1.570712 -0.694496 -0.751204 +v 1.568923 -0.694440 -0.751202 +v 1.568724 -0.700898 -0.781455 +v 1.568715 -0.694695 -0.804451 +v 1.563951 -0.545554 -0.822009 +v 1.562816 -0.547094 -0.821991 +v 1.569689 -0.559621 -0.823015 +v 1.568230 -0.560747 -0.822935 +v 1.566771 -0.561873 -0.822856 +v 1.433094 -0.480686 -0.807388 +v 1.459873 -0.488526 -0.811486 +v 1.459595 -0.490454 -0.811660 +v 1.432994 -0.482628 -0.807580 +v 1.459317 -0.492382 -0.811833 +v 1.571759 -0.698349 -0.446440 +v 1.571547 -0.700298 -0.418336 +v 1.569746 -0.700244 -0.418315 +v 1.569954 -0.698296 -0.446425 +v 1.571383 -0.705011 -0.388789 +v 1.569589 -0.704957 -0.388762 +v 1.567795 -0.704902 -0.388735 +v 1.567946 -0.700190 -0.418293 +v 1.568149 -0.698243 -0.446410 +v 1.571342 -0.709239 -0.358626 +v 1.569556 -0.709184 -0.358597 +v 1.571697 -0.699481 -0.333122 +v 1.569920 -0.699427 -0.333102 +v 1.568143 -0.699373 -0.333083 +v 1.567770 -0.709130 -0.358568 +v 1.527193 -0.512168 -0.311057 +v 1.526577 -0.514051 -0.311038 +v 1.525961 -0.515935 -0.311020 +v 1.572247 -0.700901 -0.501218 +v 1.571996 -0.699276 -0.473603 +v 1.570188 -0.699224 -0.473595 +v 1.570436 -0.700849 -0.501215 +v 1.568379 -0.699172 -0.473587 +v 1.568626 -0.700796 -0.501212 +v 1.571697 -0.699481 -0.333122 +v 1.572597 -0.665520 -0.317128 +v 1.570832 -0.665492 -0.317132 +v 1.569920 -0.699427 -0.333102 +v 1.573503 -0.620515 -0.309349 +v 1.571766 -0.620669 -0.309376 +v 1.570029 -0.620822 -0.309403 +v 1.569067 -0.665465 -0.317136 +v 1.568143 -0.699373 -0.333083 +v 1.572735 -0.698933 -0.560626 +v 1.572502 -0.700932 -0.530443 +v 1.570690 -0.700879 -0.530443 +v 1.570923 -0.698879 -0.560627 +v 1.568878 -0.700826 -0.530443 +v 1.569111 -0.698825 -0.560627 +v 1.573622 -0.580958 -0.306960 +v 1.571954 -0.581540 -0.306993 +v 1.570287 -0.582122 -0.307026 +v 1.573024 -0.691132 -0.621125 +v 1.572918 -0.695202 -0.590869 +v 1.571107 -0.695148 -0.590870 +v 1.571215 -0.691078 -0.621126 +v 1.569296 -0.695094 -0.590871 +v 1.569405 -0.691024 -0.621128 +v 1.418755 -0.478040 -0.805671 +v 1.418810 -0.479974 -0.805871 +v 1.572593 -0.623594 -0.822835 +v 1.572486 -0.664986 -0.817505 +v 1.570730 -0.664951 -0.817438 +v 1.570870 -0.623744 -0.822727 +v 1.572258 -0.694811 -0.804497 +v 1.570487 -0.694753 -0.804473 +v 1.568715 -0.694695 -0.804451 +v 1.568974 -0.664916 -0.817371 +v 1.569147 -0.623895 -0.822619 +v 1.418024 -0.470549 -0.323654 +v 1.418074 -0.472486 -0.323603 +v 1.572931 -0.687371 -0.683716 +v 1.573029 -0.688231 -0.651731 +v 1.571223 -0.688176 -0.651734 +v 1.571129 -0.687316 -0.683718 +v 1.569417 -0.688123 -0.651736 +v 1.569327 -0.687262 -0.683720 +v 1.571986 -0.586231 -0.823869 +v 1.570342 -0.586827 -0.823756 +v 1.568697 -0.587422 -0.823643 +v 1.572741 -0.689258 -0.717603 +v 1.570944 -0.689202 -0.717602 +v 1.569148 -0.689147 -0.717602 +v 1.572286 -0.701012 -0.781464 +v 1.573318 -0.699294 -0.781464 +v 1.551023 -0.530237 -0.510687 +v 1.560336 -0.538509 -0.532073 +v 1.559900 -0.536290 -0.532381 +v 1.550913 -0.528343 -0.511710 +v 1.560921 -0.539666 -0.561201 +v 1.559900 -0.536290 -0.532381 +v 1.560921 -0.539666 -0.561201 +v 1.551968 -0.532495 -0.561268 +v 1.551275 -0.529468 -0.533061 +v 1.550913 -0.528343 -0.511710 +v 1.546791 -0.525071 -0.516063 +v 1.437036 -0.486644 -0.608534 +v 1.426607 -0.482407 -0.588459 +v 1.428482 -0.481208 -0.588428 +v 1.438522 -0.485324 -0.607846 +v 1.424947 -0.480087 -0.561530 +v 1.426879 -0.478901 -0.561639 +v 1.437637 -0.480668 -0.561645 +v 1.438778 -0.482881 -0.588116 +v 1.443695 -0.485546 -0.604077 +v 1.559372 -0.540745 -0.589675 +v 1.550086 -0.535981 -0.609800 +v 1.559372 -0.540745 -0.589675 +v 1.550086 -0.535981 -0.609800 +v 1.546069 -0.532057 -0.605700 +v 1.550800 -0.533837 -0.589154 +v 1.462733 -0.493058 -0.616211 +v 1.495679 -0.505767 -0.618053 +v 1.438522 -0.485324 -0.607846 +v 1.462733 -0.493058 -0.616211 +v 1.463684 -0.491645 -0.608304 +v 1.495679 -0.505767 -0.618053 +v 1.496172 -0.504195 -0.609689 +v 1.425456 -0.480181 -0.534169 +v 1.425456 -0.480181 -0.534169 +v 1.435558 -0.481194 -0.512952 +v 1.436581 -0.479677 -0.514050 +v 1.426246 -0.478479 -0.534494 +v 1.527033 -0.516507 -0.501011 +v 1.550593 -0.531971 -0.509476 +v 1.527033 -0.516507 -0.501011 +v 1.550593 -0.531971 -0.509476 +v 1.551023 -0.530237 -0.510687 +v 1.527748 -0.515029 -0.502400 +v 1.554060 -0.534952 -0.500236 +v 1.559717 -0.540231 -0.531717 +v 1.550593 -0.531971 -0.509476 +v 1.526229 -0.525727 -0.619771 +v 1.549715 -0.539886 -0.611496 +v 1.526229 -0.525727 -0.619771 +v 1.526970 -0.524091 -0.618672 +v 1.549715 -0.539886 -0.611496 +v 1.550169 -0.538012 -0.610571 +v 1.496499 -0.500442 -0.561338 +v 1.463013 -0.487706 -0.561501 +v 1.463157 -0.485629 -0.534050 +v 1.496579 -0.498144 -0.533208 +v 1.438512 -0.478965 -0.535046 +v 1.443348 -0.479214 -0.518804 +v 1.463577 -0.484520 -0.514171 +v 1.496484 -0.496654 -0.512268 +v 1.463229 -0.489768 -0.588774 +v 1.496401 -0.502481 -0.589217 +v 1.527621 -0.520672 -0.609438 +v 1.528455 -0.519434 -0.589396 +v 1.528821 -0.517537 -0.561283 +v 1.528826 -0.515025 -0.532866 +v 1.528254 -0.513093 -0.512281 +v 1.528334 -0.513589 -0.503754 +v 1.496053 -0.496907 -0.503550 +v 1.550913 -0.528343 -0.511710 +v 1.528334 -0.513589 -0.503754 +v 1.496053 -0.496907 -0.503550 +v 1.527582 -0.522464 -0.617582 +v 1.550086 -0.535981 -0.609800 +v 1.527582 -0.522464 -0.617582 +v 1.426246 -0.478479 -0.534494 +v 1.428131 -0.477293 -0.534741 +v 1.436581 -0.479677 -0.514050 +v 1.438080 -0.478464 -0.514960 +v 1.462605 -0.484722 -0.505989 +v 1.438080 -0.478464 -0.514960 +v 1.462605 -0.484722 -0.505989 +vt 0.750562 0.023422 +vt 0.752549 0.025932 +vt 0.752448 0.023387 +vt 0.750665 0.028306 +vt 0.750497 0.030567 +vt 0.752403 0.030549 +vt 0.750057 0.035046 +vt 0.752129 0.037277 +vt 0.752148 0.035028 +vt 0.749966 0.037284 +vt 0.752207 0.039498 +vt 0.750008 0.039466 +vt 0.752359 0.041670 +vt 0.750151 0.041552 +vt 0.752475 0.043844 +vt 0.750248 0.043616 +vt 0.752448 0.046079 +vt 0.750157 0.045748 +vt 0.752278 0.048382 +vt 0.309968 0.041983 +vt 0.309712 0.039879 +vt 0.305591 0.039847 +vt 0.305848 0.041951 +vt 0.309481 0.037816 +vt 0.305361 0.037784 +vt 0.310183 0.044183 +vt 0.309267 0.025186 +vt 0.309493 0.022837 +vt 0.305373 0.022804 +vt 0.305147 0.025152 +vt 0.305640 0.020364 +vt 0.309319 0.035736 +vt 0.305199 0.035704 +vt 0.305086 0.033610 +vt 0.309206 0.033642 +vt 0.309115 0.031548 +vt 0.304995 0.031515 +vt 0.309077 0.029462 +vt 0.304957 0.029429 +vt 0.305005 0.027337 +vt 0.309126 0.027370 +vt 0.311701 0.025231 +vt 0.311926 0.022892 +vt 0.311786 0.022878 +vt 0.311561 0.025220 +vt 0.312053 0.020442 +vt 0.311511 0.029481 +vt 0.311560 0.027403 +vt 0.311419 0.027397 +vt 0.311371 0.029480 +vt 0.311638 0.033630 +vt 0.311549 0.031551 +vt 0.311409 0.031556 +vt 0.311499 0.033641 +vt 0.311912 0.037789 +vt 0.311751 0.035714 +vt 0.311611 0.035729 +vt 0.311772 0.037805 +vt 0.312400 0.041962 +vt 0.312143 0.039852 +vt 0.312003 0.039868 +vt 0.312260 0.041976 +vt 0.312703 0.046467 +vt 0.312617 0.044171 +vt 0.312477 0.044181 +vt 0.755286 0.048769 +vt 0.755148 0.051068 +vt 0.757878 0.051211 +vt 0.757939 0.048895 +vt 0.755011 0.052773 +vt 0.757804 0.052921 +vt 0.759731 0.052891 +vt 0.759777 0.051181 +vt 0.759807 0.048863 +vt 0.749883 0.047975 +vt 0.749613 0.050167 +vt 0.752032 0.050634 +vt 0.749875 0.051598 +vt 0.751865 0.052283 +vt 0.749861 0.017332 +vt 0.749770 0.018679 +vt 0.751854 0.018452 +vt 0.751600 0.016802 +vt 0.750205 0.020908 +vt 0.752201 0.020807 +vt 0.754735 0.020729 +vt 0.754580 0.018261 +vt 0.754444 0.016474 +vt 0.750703 0.025940 +vt 0.754887 0.025934 +vt 0.754844 0.023369 +vt 0.752518 0.028298 +vt 0.754811 0.030533 +vt 0.754864 0.028295 +vt 0.750263 0.032805 +vt 0.752258 0.032784 +vt 0.754773 0.035006 +vt 0.754771 0.032762 +vt 0.754974 0.039524 +vt 0.754842 0.037265 +vt 0.755296 0.044053 +vt 0.755150 0.041775 +vt 0.755343 0.046389 +vt 0.757029 0.018231 +vt 0.757037 0.016397 +vt 0.757019 0.020744 +vt 0.758660 0.020808 +vt 0.758771 0.018289 +vt 0.758861 0.016443 +vt 0.757005 0.023400 +vt 0.756987 0.025959 +vt 0.758497 0.025994 +vt 0.758563 0.023454 +vt 0.756967 0.028305 +vt 0.756964 0.030529 +vt 0.758504 0.030534 +vt 0.758475 0.028323 +vt 0.757000 0.032748 +vt 0.757087 0.034989 +vt 0.758721 0.034980 +vt 0.758584 0.032744 +vt 0.757231 0.037251 +vt 0.757422 0.039520 +vt 0.759153 0.039502 +vt 0.758915 0.037238 +vt 0.757640 0.041793 +vt 0.757826 0.044103 +vt 0.759632 0.044063 +vt 0.759411 0.041763 +vt 0.757928 0.046480 +vt 0.759765 0.046442 +vt 0.988657 0.378276 +vt 0.988642 0.375978 +vt 0.986084 0.376223 +vt 0.986117 0.378474 +vt 0.988637 0.373612 +vt 0.986066 0.373893 +vt 0.984032 0.374125 +vt 0.984061 0.376424 +vt 0.984110 0.378637 +vt 0.988696 0.382641 +vt 0.988676 0.380479 +vt 0.986156 0.380629 +vt 0.986192 0.382743 +vt 0.984165 0.380754 +vt 0.984217 0.382830 +vt 0.988729 0.387004 +vt 0.988714 0.384820 +vt 0.986223 0.384875 +vt 0.986248 0.387018 +vt 0.984258 0.384925 +vt 0.984291 0.387034 +vt 0.988755 0.391315 +vt 0.988744 0.389172 +vt 0.986271 0.389152 +vt 0.986288 0.391268 +vt 0.984321 0.389141 +vt 0.984343 0.391236 +vt 0.988762 0.395687 +vt 0.988761 0.393450 +vt 0.986295 0.393381 +vt 0.986291 0.395591 +vt 0.984350 0.393335 +vt 0.984343 0.395528 +vt 0.988754 0.400689 +vt 0.988759 0.398120 +vt 0.986280 0.397984 +vt 0.986265 0.400498 +vt 0.984324 0.397892 +vt 0.984300 0.400358 +vt 0.988750 0.405065 +vt 0.988751 0.403198 +vt 0.986251 0.402944 +vt 0.986242 0.404759 +vt 0.984276 0.402736 +vt 0.984259 0.404492 +vt 0.988642 0.371320 +vt 0.986069 0.371620 +vt 0.988651 0.369618 +vt 0.986080 0.369926 +vt 0.984046 0.370183 +vt 0.984033 0.371870 +vt 0.760779 0.051135 +vt 0.760798 0.048817 +vt 0.760743 0.052844 +vt 0.994073 0.370834 +vt 0.994079 0.369125 +vt 0.993067 0.369203 +vt 0.993061 0.370911 +vt 0.994066 0.373151 +vt 0.993054 0.373225 +vt 0.759707 0.018347 +vt 0.759832 0.016498 +vt 0.759556 0.020867 +vt 0.994070 0.403634 +vt 0.994064 0.401117 +vt 0.993066 0.401029 +vt 0.993071 0.403550 +vt 0.994078 0.405482 +vt 0.993078 0.405406 +vt 0.759423 0.023504 +vt 0.759336 0.026030 +vt 0.994059 0.398483 +vt 0.994054 0.395958 +vt 0.993058 0.395898 +vt 0.993062 0.398405 +vt 0.759314 0.028346 +vt 0.759353 0.030545 +vt 0.994050 0.393643 +vt 0.994046 0.391443 +vt 0.993050 0.391415 +vt 0.993054 0.393600 +vt 0.759451 0.032747 +vt 0.759608 0.034976 +vt 0.994043 0.389240 +vt 0.994039 0.387009 +vt 0.993041 0.387005 +vt 0.993045 0.389224 +vt 0.759823 0.037230 +vt 0.760083 0.039487 +vt 0.994037 0.384752 +vt 0.994036 0.382491 +vt 0.993034 0.382512 +vt 0.993037 0.384760 +vt 0.760360 0.041736 +vt 0.760598 0.044025 +vt 0.994037 0.380239 +vt 0.994043 0.377946 +vt 0.993036 0.377999 +vt 0.993033 0.380276 +vt 0.760744 0.046398 +vt 0.994054 0.375571 +vt 0.993044 0.375636 +vt 0.983009 0.370270 +vt 0.983019 0.371970 +vt 0.480949 0.014894 +vt 0.479606 0.014716 +vt 0.479252 0.016593 +vt 0.480996 0.016593 +vt 0.479273 0.018862 +vt 0.481061 0.018845 +vt 0.983024 0.374223 +vt 0.983373 0.395502 +vt 0.983350 0.397855 +vt 0.479882 0.040139 +vt 0.478093 0.040136 +vt 0.478297 0.042486 +vt 0.480085 0.042490 +vt 0.478543 0.044928 +vt 0.480329 0.044933 +vt 0.983321 0.400301 +vt 0.983317 0.387040 +vt 0.983350 0.389135 +vt 0.479893 0.031677 +vt 0.478103 0.031678 +vt 0.477995 0.033772 +vt 0.479786 0.033773 +vt 0.477939 0.035858 +vt 0.479730 0.035861 +vt 0.983373 0.391222 +vt 0.983113 0.378706 +vt 0.983175 0.380806 +vt 0.480724 0.023332 +vt 0.478935 0.023344 +vt 0.478661 0.025445 +vt 0.480450 0.025436 +vt 0.478413 0.027506 +vt 0.480202 0.027499 +vt 0.983233 0.382867 +vt 0.983288 0.402656 +vt 0.478842 0.047295 +vt 0.480580 0.047285 +vt 0.479543 0.049224 +vt 0.480846 0.049032 +vt 0.983243 0.404405 +vt 0.983381 0.393315 +vt 0.477970 0.037950 +vt 0.479760 0.037953 +vt 0.983279 0.384946 +vt 0.478234 0.029585 +vt 0.480024 0.029581 +vt 0.983057 0.376508 +vt 0.479169 0.021146 +vt 0.480958 0.021132 +vt 0.630319 0.048132 +vt 0.627536 0.048225 +vt 0.627575 0.050547 +vt 0.630434 0.050434 +vt 0.625524 0.048163 +vt 0.625530 0.050489 +vt 0.625567 0.052204 +vt 0.627634 0.052261 +vt 0.630553 0.052142 +vt 0.635819 0.047386 +vt 0.633398 0.047773 +vt 0.633622 0.050028 +vt 0.636068 0.049580 +vt 0.633771 0.051679 +vt 0.635788 0.051009 +vt 0.636150 0.016740 +vt 0.634402 0.016183 +vt 0.634132 0.017829 +vt 0.636229 0.018089 +vt 0.631499 0.015815 +vt 0.631347 0.017600 +vt 0.631168 0.020067 +vt 0.633760 0.020182 +vt 0.635768 0.020314 +vt 0.633484 0.022761 +vt 0.635382 0.022826 +vt 0.631032 0.022710 +vt 0.630962 0.025280 +vt 0.633357 0.025309 +vt 0.635214 0.025344 +vt 0.633363 0.027680 +vt 0.635228 0.027712 +vt 0.630961 0.027647 +vt 0.630991 0.029891 +vt 0.633456 0.029936 +vt 0.635373 0.029976 +vt 0.633579 0.032174 +vt 0.635586 0.032217 +vt 0.631010 0.032122 +vt 0.630984 0.034366 +vt 0.633667 0.034419 +vt 0.635771 0.034459 +vt 0.633664 0.036667 +vt 0.635840 0.036698 +vt 0.630891 0.036623 +vt 0.630733 0.038879 +vt 0.633561 0.038887 +vt 0.635777 0.038879 +vt 0.633386 0.041058 +vt 0.635612 0.040962 +vt 0.630532 0.041130 +vt 0.630360 0.043409 +vt 0.633247 0.043231 +vt 0.635495 0.043025 +vt 0.633251 0.045467 +vt 0.635566 0.045157 +vt 0.630286 0.045748 +vt 0.628784 0.015709 +vt 0.628773 0.017543 +vt 0.626819 0.015743 +vt 0.626887 0.017590 +vt 0.626974 0.020112 +vt 0.628760 0.020058 +vt 0.628748 0.022718 +vt 0.627047 0.022762 +vt 0.627087 0.025304 +vt 0.628741 0.025281 +vt 0.628737 0.027632 +vt 0.627084 0.027634 +vt 0.627033 0.029842 +vt 0.628717 0.029858 +vt 0.628658 0.032078 +vt 0.626930 0.032048 +vt 0.626769 0.034278 +vt 0.628547 0.034316 +vt 0.628379 0.036573 +vt 0.626551 0.036530 +vt 0.626287 0.038789 +vt 0.628161 0.038839 +vt 0.627917 0.041111 +vt 0.626002 0.041047 +vt 0.625754 0.043350 +vt 0.627703 0.043424 +vt 0.627574 0.045805 +vt 0.625593 0.045734 +vt 0.319858 0.041196 +vt 0.317317 0.041028 +vt 0.317299 0.043297 +vt 0.319857 0.043510 +vt 0.315286 0.040881 +vt 0.315253 0.043113 +vt 0.315233 0.045428 +vt 0.317288 0.045642 +vt 0.319858 0.045889 +vt 0.319880 0.037538 +vt 0.317348 0.037376 +vt 0.317333 0.038933 +vt 0.319862 0.039070 +vt 0.315161 0.036662 +vt 0.315302 0.038763 +vt 0.625453 0.034241 +vt 0.625595 0.032043 +vt 0.625378 0.032094 +vt 0.625259 0.034229 +vt 0.625354 0.029846 +vt 0.625023 0.030484 +vt 0.624885 0.030550 +vt 0.625250 0.032099 +vt 0.625136 0.034217 +vt 0.315247 0.028297 +vt 0.314633 0.030399 +vt 0.314815 0.030454 +vt 0.315583 0.028904 +vt 0.314541 0.032466 +vt 0.314688 0.032465 +vt 0.497903 0.381758 +vt 0.497870 0.379744 +vt 0.497746 0.379744 +vt 0.497783 0.381744 +vt 0.498177 0.383325 +vt 0.498069 0.383254 +vt 0.319884 0.023825 +vt 0.317414 0.023957 +vt 0.317409 0.026076 +vt 0.319882 0.025957 +vt 0.315446 0.024041 +vt 0.315427 0.026201 +vt 0.317406 0.027613 +vt 0.319895 0.027450 +vt 0.319896 0.018854 +vt 0.317408 0.019084 +vt 0.317412 0.021582 +vt 0.319889 0.021408 +vt 0.315423 0.019248 +vt 0.315436 0.021696 +vt 0.319908 0.014497 +vt 0.317403 0.014843 +vt 0.317405 0.016651 +vt 0.319903 0.016357 +vt 0.315400 0.015134 +vt 0.315410 0.016883 +vt 0.317289 0.047922 +vt 0.319861 0.048189 +vt 0.315232 0.047690 +vt 0.315240 0.049378 +vt 0.317294 0.049617 +vt 0.319863 0.049892 +vt 0.624426 0.048094 +vt 0.624423 0.050421 +vt 0.325306 0.046239 +vt 0.324249 0.046189 +vt 0.324254 0.048510 +vt 0.325311 0.048562 +vt 0.324251 0.050221 +vt 0.325307 0.050274 +vt 0.624456 0.052138 +vt 0.625749 0.015801 +vt 0.625844 0.017652 +vt 0.325255 0.013925 +vt 0.324210 0.014047 +vt 0.324202 0.015898 +vt 0.325248 0.015768 +vt 0.324187 0.018410 +vt 0.325234 0.018277 +vt 0.625970 0.020174 +vt 0.626077 0.022812 +vt 0.324172 0.021023 +vt 0.325220 0.020904 +vt 0.324161 0.023518 +vt 0.325209 0.023420 +vt 0.626138 0.025337 +vt 0.626140 0.027649 +vt 0.324174 0.025788 +vt 0.325207 0.025727 +vt 0.324347 0.027967 +vt 0.325238 0.027918 +vt 0.626096 0.029841 +vt 0.626009 0.032034 +vt 0.324922 0.030146 +vt 0.325294 0.030113 +vt 0.625837 0.034255 +vt 0.625589 0.036501 +vt 0.625169 0.036464 +vt 0.325311 0.034596 +vt 0.324941 0.034585 +vt 0.324380 0.036860 +vt 0.325272 0.036861 +vt 0.625271 0.038750 +vt 0.624949 0.040995 +vt 0.324220 0.039119 +vt 0.325257 0.039121 +vt 0.324217 0.041391 +vt 0.325272 0.041424 +vt 0.624681 0.043285 +vt 0.624507 0.045665 +vt 0.324236 0.043766 +vt 0.325291 0.043810 +vt 0.314135 0.047586 +vt 0.314144 0.049270 +vt 0.314137 0.045331 +vt 0.313653 0.045311 +vt 0.313651 0.047564 +vt 0.313661 0.049247 +vt 0.314377 0.021739 +vt 0.314391 0.024072 +vt 0.314359 0.019311 +vt 0.313883 0.019315 +vt 0.313902 0.021741 +vt 0.313917 0.024073 +vt 0.314276 0.030383 +vt 0.314239 0.032462 +vt 0.314349 0.028314 +vt 0.313915 0.028312 +vt 0.313897 0.030379 +vt 0.313872 0.032456 +vt 0.314241 0.038696 +vt 0.314202 0.040812 +vt 0.314248 0.036626 +vt 0.313810 0.036615 +vt 0.313767 0.038682 +vt 0.313721 0.040796 +vt 0.314341 0.016975 +vt 0.314328 0.015252 +vt 0.313850 0.015263 +vt 0.313863 0.016983 +vt 0.314389 0.026239 +vt 0.313922 0.026240 +vt 0.314585 0.034540 +vt 0.314224 0.034546 +vt 0.313844 0.034539 +vt 0.314162 0.043029 +vt 0.313679 0.043011 +vt 0.748884 0.018727 +vt 0.749367 0.020953 +vt 0.749310 0.017076 +vt 0.749185 0.017022 +vt 0.748744 0.018727 +vt 0.749238 0.020960 +vt 0.470793 0.014933 +vt 0.470723 0.014339 +vt 0.468884 0.014430 +vt 0.468952 0.015000 +vt 0.301702 0.050920 +vt 0.301762 0.050325 +vt 0.299921 0.050243 +vt 0.299863 0.050813 +vt 0.299658 0.049912 +vt 0.299623 0.050172 +vt 0.468639 0.015068 +vt 0.468682 0.015328 +vt 0.313527 0.034535 +vt 0.313492 0.036610 +vt 0.313556 0.032452 +vt 0.313345 0.032451 +vt 0.313316 0.034533 +vt 0.313281 0.036609 +vt 0.759903 0.015737 +vt 0.758910 0.015683 +vt 0.993090 0.406169 +vt 0.994093 0.406241 +vt 0.460250 0.017058 +vt 0.460494 0.015883 +vt 0.460408 0.015847 +vt 0.460162 0.017039 +vt 0.759968 0.015628 +vt 0.758953 0.015571 +vt 0.313677 0.050040 +vt 0.313668 0.049942 +vt 0.313351 0.049841 +vt 0.313360 0.049936 +vt 0.313348 0.049174 +vt 0.313176 0.048843 +vt 0.313141 0.049172 +vt 0.312382 0.051099 +vt 0.312466 0.051003 +vt 0.312532 0.050334 +vt 0.312452 0.050403 +vt 0.626840 0.014880 +vt 0.625783 0.014933 +vt 0.625728 0.015040 +vt 0.626803 0.014985 +vt 0.325203 0.013057 +vt 0.324174 0.013169 +vt 0.324204 0.013283 +vt 0.325245 0.013167 +vt 0.470689 0.048992 +vt 0.470523 0.047267 +vt 0.468673 0.047252 +vt 0.468834 0.048921 +vt 0.470288 0.044924 +vt 0.468439 0.044922 +vt 0.468125 0.044922 +vt 0.468357 0.047213 +vt 0.468501 0.048585 +vt 0.749425 0.032814 +vt 0.749178 0.035053 +vt 0.749697 0.030574 +vt 0.749573 0.030576 +vt 0.749295 0.032816 +vt 0.749043 0.035055 +vt 0.465378 0.006093 +vt 0.465518 0.006277 +vt 0.465832 0.006177 +vt 0.465648 0.005920 +vt 0.466379 0.007376 +vt 0.466883 0.007613 +vt 0.312116 0.015652 +vt 0.310335 0.015684 +vt 0.310203 0.016333 +vt 0.312025 0.016350 +vt 0.312432 0.015652 +vt 0.312355 0.016362 +vt 0.315241 0.050173 +vt 0.317285 0.050414 +vt 0.317294 0.050316 +vt 0.315243 0.050074 +vt 0.319843 0.050692 +vt 0.319859 0.050594 +vt 0.313449 0.038677 +vt 0.313402 0.040792 +vt 0.313238 0.038676 +vt 0.313191 0.040790 +vt 0.751704 0.052944 +vt 0.754950 0.053477 +vt 0.749294 0.051833 +vt 0.749164 0.051880 +vt 0.751660 0.053037 +vt 0.754939 0.053578 +vt 0.630616 0.052945 +vt 0.633950 0.052433 +vt 0.633921 0.052341 +vt 0.630606 0.052845 +vt 0.636480 0.051298 +vt 0.636365 0.051249 +vt 0.300823 0.029396 +vt 0.300872 0.027304 +vt 0.299022 0.027290 +vt 0.298974 0.029381 +vt 0.301014 0.025119 +vt 0.299164 0.025105 +vt 0.298856 0.025102 +vt 0.298714 0.027287 +vt 0.298666 0.029379 +vt 0.757774 0.053626 +vt 0.759720 0.053595 +vt 0.757784 0.053727 +vt 0.759753 0.053696 +vt 0.637237 0.049427 +vt 0.637093 0.049439 +vt 0.636968 0.047191 +vt 0.636828 0.047214 +vt 0.991150 0.369367 +vt 0.991159 0.368664 +vt 0.988659 0.368916 +vt 0.993078 0.368500 +vt 0.993106 0.368399 +vt 0.991178 0.368564 +vt 0.988672 0.368816 +vt 0.313360 0.043006 +vt 0.313334 0.045306 +vt 0.313149 0.043005 +vt 0.313123 0.045304 +vt 0.748590 0.050018 +vt 0.748876 0.047796 +vt 0.748722 0.047769 +vt 0.748432 0.050003 +vt 0.322307 0.050899 +vt 0.322330 0.050801 +vt 0.324208 0.051022 +vt 0.324240 0.050924 +vt 0.322338 0.050098 +vt 0.470043 0.042482 +vt 0.468193 0.042480 +vt 0.469838 0.040131 +vt 0.467988 0.040129 +vt 0.467674 0.040130 +vt 0.467879 0.042480 +vt 0.749057 0.037287 +vt 0.749083 0.039451 +vt 0.748918 0.037288 +vt 0.748942 0.039449 +vt 0.757043 0.015643 +vt 0.754385 0.015740 +vt 0.757059 0.015530 +vt 0.754374 0.015631 +vt 0.749771 0.023438 +vt 0.749928 0.025944 +vt 0.749648 0.023441 +vt 0.749808 0.025945 +vt 0.749224 0.041499 +vt 0.749314 0.043515 +vt 0.749082 0.041491 +vt 0.749170 0.043500 +vt 0.313334 0.047546 +vt 0.313129 0.047505 +vt 0.312604 0.048719 +vt 0.312680 0.048704 +vt 0.312777 0.046463 +vt 0.313051 0.047544 +vt 0.313041 0.045304 +vt 0.986087 0.369227 +vt 0.984052 0.369487 +vt 0.986093 0.369128 +vt 0.984051 0.369389 +vt 0.322335 0.046076 +vt 0.322339 0.048389 +vt 0.322331 0.014228 +vt 0.322323 0.016095 +vt 0.322309 0.018612 +vt 0.322297 0.021204 +vt 0.322287 0.023664 +vt 0.322287 0.025844 +vt 0.322313 0.027418 +vt 0.317466 0.028227 +vt 0.319933 0.028056 +vt 0.279923 0.410681 +vt 0.280183 0.408696 +vt 0.280044 0.408709 +vt 0.279794 0.410674 +vt 0.279765 0.413295 +vt 0.279638 0.413289 +vt 0.317415 0.036746 +vt 0.315513 0.036050 +vt 0.319919 0.036907 +vt 0.407718 0.428007 +vt 0.407530 0.425369 +vt 0.407419 0.425369 +vt 0.407604 0.428007 +vt 0.408097 0.429960 +vt 0.407970 0.429940 +vt 0.322331 0.037511 +vt 0.322310 0.039137 +vt 0.322314 0.041318 +vt 0.322326 0.043669 +vt 0.991143 0.371073 +vt 0.991136 0.373379 +vt 0.991191 0.403407 +vt 0.991196 0.405279 +vt 0.991188 0.400880 +vt 0.991187 0.398274 +vt 0.991185 0.395800 +vt 0.991182 0.393530 +vt 0.991177 0.391368 +vt 0.991170 0.389199 +vt 0.991162 0.387001 +vt 0.991153 0.384781 +vt 0.991145 0.382562 +vt 0.991137 0.380356 +vt 0.991132 0.378110 +vt 0.991132 0.375773 +vt 0.310267 0.046468 +vt 0.310168 0.048712 +vt 0.311990 0.048726 +vt 0.312089 0.046481 +vt 0.310016 0.050391 +vt 0.311838 0.050405 +vt 0.312169 0.050406 +vt 0.312321 0.048726 +vt 0.312420 0.046480 +vt 0.311534 0.039891 +vt 0.311303 0.037828 +vt 0.311790 0.041995 +vt 0.312120 0.041990 +vt 0.311864 0.039884 +vt 0.311633 0.037821 +vt 0.311142 0.035748 +vt 0.311028 0.033654 +vt 0.311472 0.035743 +vt 0.311359 0.033651 +vt 0.312637 0.016398 +vt 0.312450 0.018121 +vt 0.312522 0.018144 +vt 0.312702 0.016477 +vt 0.312193 0.020459 +vt 0.312267 0.020467 +vt 0.313265 0.016985 +vt 0.313273 0.019304 +vt 0.313354 0.019308 +vt 0.313344 0.017028 +vt 0.313332 0.015322 +vt 0.313373 0.015661 +vt 0.310948 0.027386 +vt 0.311090 0.025202 +vt 0.310900 0.029476 +vt 0.311231 0.029479 +vt 0.311279 0.027391 +vt 0.311421 0.025209 +vt 0.309760 0.020397 +vt 0.311315 0.022854 +vt 0.311582 0.020414 +vt 0.311646 0.022863 +vt 0.311913 0.020425 +vt 0.310017 0.018057 +vt 0.311839 0.018074 +vt 0.312169 0.018085 +vt 0.313581 0.030376 +vt 0.313599 0.028309 +vt 0.313388 0.028307 +vt 0.313370 0.030374 +vt 0.300952 0.033577 +vt 0.300861 0.031483 +vt 0.299012 0.031468 +vt 0.299103 0.033562 +vt 0.298704 0.031465 +vt 0.298795 0.033560 +vt 0.313605 0.026237 +vt 0.313600 0.024071 +vt 0.313390 0.024068 +vt 0.313395 0.026235 +vt 0.481033 0.014217 +vt 0.480911 0.014204 +vt 0.982992 0.369595 +vt 0.982980 0.369504 +vt 0.425617 0.114945 +vt 0.425183 0.114774 +vt 0.425119 0.114848 +vt 0.425488 0.115128 +vt 0.301950 0.016266 +vt 0.302016 0.015658 +vt 0.300157 0.015737 +vt 0.300095 0.016321 +vt 0.470734 0.049602 +vt 0.468877 0.049506 +vt 0.468508 0.048853 +vt 0.299782 0.016388 +vt 0.299761 0.016654 +vt 0.313585 0.021738 +vt 0.313565 0.019311 +vt 0.313375 0.021735 +vt 0.469715 0.037945 +vt 0.467865 0.037943 +vt 0.469684 0.035853 +vt 0.467835 0.035851 +vt 0.467520 0.035851 +vt 0.467551 0.037944 +vt 0.986240 0.405506 +vt 0.988754 0.405833 +vt 0.984251 0.405214 +vt 0.984248 0.405309 +vt 0.986244 0.405606 +vt 0.988765 0.405937 +vt 0.313547 0.016992 +vt 0.313539 0.015328 +vt 0.301227 0.037751 +vt 0.301066 0.035671 +vt 0.299216 0.035657 +vt 0.299378 0.037737 +vt 0.298908 0.035654 +vt 0.299070 0.037734 +vt 0.407729 0.553068 +vt 0.407716 0.555262 +vt 0.407897 0.555289 +vt 0.407918 0.553069 +vt 0.407734 0.556598 +vt 0.407872 0.556860 +vt 0.408023 0.556599 +vt 0.408085 0.555264 +vt 0.408114 0.553070 +vt 0.407818 0.523344 +vt 0.407746 0.524718 +vt 0.407928 0.524693 +vt 0.407967 0.523078 +vt 0.407686 0.527010 +vt 0.407875 0.527011 +vt 0.408070 0.527012 +vt 0.408114 0.524720 +vt 0.408107 0.523346 +vt 0.407631 0.529454 +vt 0.407820 0.529456 +vt 0.407584 0.531807 +vt 0.407773 0.531808 +vt 0.407969 0.531809 +vt 0.408015 0.529457 +vt 0.407554 0.533994 +vt 0.407743 0.533995 +vt 0.407541 0.536086 +vt 0.407730 0.536088 +vt 0.407925 0.536089 +vt 0.407938 0.533996 +vt 0.407682 0.548590 +vt 0.407718 0.550785 +vt 0.407907 0.550786 +vt 0.407872 0.548591 +vt 0.408103 0.550787 +vt 0.408068 0.548592 +vt 0.407601 0.544433 +vt 0.407639 0.546491 +vt 0.407829 0.546492 +vt 0.407790 0.544434 +vt 0.408024 0.546493 +vt 0.407985 0.544435 +vt 0.407557 0.540264 +vt 0.407574 0.542356 +vt 0.407763 0.542358 +vt 0.407746 0.540266 +vt 0.407959 0.542358 +vt 0.407941 0.540266 +vt 0.407544 0.538172 +vt 0.407733 0.538173 +vt 0.407928 0.538174 +vt 0.301239 0.022771 +vt 0.299390 0.022756 +vt 0.301506 0.020331 +vt 0.299657 0.020316 +vt 0.299349 0.020313 +vt 0.299082 0.022753 +vt 0.471017 0.018857 +vt 0.470937 0.016613 +vt 0.469089 0.016624 +vt 0.469168 0.018856 +vt 0.468780 0.016663 +vt 0.468853 0.018856 +vt 0.470680 0.023339 +vt 0.470914 0.021142 +vt 0.469064 0.021140 +vt 0.468831 0.023338 +vt 0.468750 0.021140 +vt 0.468517 0.023338 +vt 0.301763 0.017990 +vt 0.299913 0.017988 +vt 0.299602 0.018025 +vt 0.470158 0.027501 +vt 0.470406 0.025440 +vt 0.468557 0.025439 +vt 0.468309 0.027500 +vt 0.468243 0.025439 +vt 0.467995 0.027500 +vt 0.301914 0.048647 +vt 0.300067 0.048619 +vt 0.302013 0.046403 +vt 0.300164 0.046388 +vt 0.299856 0.046385 +vt 0.299764 0.048578 +vt 0.301929 0.044118 +vt 0.300080 0.044103 +vt 0.301714 0.041918 +vt 0.299865 0.041903 +vt 0.299557 0.041901 +vt 0.299772 0.044100 +vt 0.469848 0.031673 +vt 0.469980 0.029580 +vt 0.468130 0.029578 +vt 0.467999 0.031672 +vt 0.467816 0.029578 +vt 0.467685 0.031672 +vt 0.301458 0.039814 +vt 0.299608 0.039800 +vt 0.299300 0.039797 +vt 0.469740 0.033767 +vt 0.467891 0.033765 +vt 0.467577 0.033765 +vt 0.473872 0.033770 +vt 0.473816 0.035856 +vt 0.473980 0.031676 +vt 0.474112 0.029583 +vt 0.474290 0.027504 +vt 0.306063 0.044150 +vt 0.306147 0.046435 +vt 0.306048 0.048679 +vt 0.305896 0.050358 +vt 0.474538 0.025443 +vt 0.474812 0.023342 +vt 0.305897 0.018023 +vt 0.306083 0.016299 +vt 0.475046 0.021145 +vt 0.475149 0.018860 +vt 0.475084 0.016610 +vt 0.474984 0.014912 +vt 0.473847 0.037948 +vt 0.473970 0.040134 +vt 0.306165 0.015685 +vt 0.479050 0.049649 +vt 0.474885 0.049020 +vt 0.474882 0.049611 +vt 0.474175 0.042485 +vt 0.474420 0.044927 +vt 0.474671 0.047276 +vt 0.479031 0.014305 +vt 0.474869 0.014336 +vt 0.310013 0.051026 +vt 0.305851 0.050958 +vt 0.983211 0.405098 +vt 0.480947 0.049745 +vt 0.481061 0.049723 +vt 0.465097 0.006465 +vt 0.465024 0.006384 +vt 0.464421 0.007267 +vt 0.464359 0.007212 +vt 0.314155 0.050063 +vt 0.314150 0.049965 +vt 0.310938 0.031561 +vt 0.311269 0.031561 +vt 0.312000 0.022899 +vt 0.311775 0.025236 +vt 0.313293 0.021732 +vt 0.313308 0.024065 +vt 0.311634 0.027407 +vt 0.311585 0.029481 +vt 0.313313 0.026233 +vt 0.313307 0.028306 +vt 0.311623 0.031548 +vt 0.311712 0.033625 +vt 0.313288 0.030374 +vt 0.313263 0.032451 +vt 0.311824 0.035707 +vt 0.311985 0.037780 +vt 0.313235 0.034535 +vt 0.313200 0.036610 +vt 0.312216 0.039844 +vt 0.312474 0.041954 +vt 0.313156 0.038677 +vt 0.313109 0.040791 +vt 0.312691 0.044165 +vt 0.313067 0.043005 +vt 0.312005 0.044195 +vt 0.312336 0.044192 +vt 0.313847 0.014552 +vt 0.313532 0.014645 +vt 0.313854 0.014440 +vt 0.313539 0.014537 +vt 0.312777 0.015796 +vt 0.312714 0.015689 +vt 0.322306 0.013339 +vt 0.322327 0.013456 +vt 0.319890 0.013609 +vt 0.319906 0.013727 +vt 0.325249 0.051075 +vt 0.325293 0.050977 +vt 0.624553 0.052946 +vt 0.625640 0.053011 +vt 0.625597 0.052910 +vt 0.624491 0.052844 +vt 0.749886 0.028310 +vt 0.749765 0.028310 +vt 0.751410 0.016143 +vt 0.751363 0.016047 +vt 0.317390 0.013978 +vt 0.317399 0.014095 +vt 0.315394 0.014297 +vt 0.315396 0.014410 +vt 0.636662 0.044999 +vt 0.636529 0.045019 +vt 0.636559 0.042919 +vt 0.636430 0.042932 +vt 0.749195 0.045602 +vt 0.749048 0.045580 +vt 0.991204 0.406049 +vt 0.991222 0.406155 +vt 0.993116 0.406275 +vt 0.636667 0.040912 +vt 0.636540 0.040918 +vt 0.636827 0.038873 +vt 0.636700 0.038874 +vt 0.994093 0.368422 +vt 0.760744 0.053548 +vt 0.760798 0.053648 +vt 0.420108 0.105374 +vt 0.419820 0.104194 +vt 0.419739 0.104210 +vt 0.420030 0.105406 +vt 0.636872 0.036712 +vt 0.636747 0.036711 +vt 0.636768 0.034478 +vt 0.636648 0.034476 +vt 0.627690 0.053065 +vt 0.627666 0.052966 +vt 0.636536 0.032237 +vt 0.636422 0.032235 +vt 0.636279 0.029994 +vt 0.636170 0.029992 +vt 0.314328 0.014428 +vt 0.314324 0.014540 +vt 0.636812 0.016442 +vt 0.634627 0.015438 +vt 0.634593 0.015528 +vt 0.636702 0.016492 +vt 0.631576 0.014985 +vt 0.631564 0.015085 +vt 0.426400 0.113865 +vt 0.425932 0.115039 +vt 0.426924 0.113572 +vt 0.425758 0.115300 +vt 0.311784 0.051088 +vt 0.312098 0.051100 +vt 0.636109 0.027727 +vt 0.636003 0.027726 +vt 0.636091 0.025361 +vt 0.635985 0.025360 +vt 0.628815 0.014856 +vt 0.628794 0.014958 +vt 0.636278 0.022859 +vt 0.636170 0.022855 +vt 0.636717 0.020382 +vt 0.636603 0.020373 +vt 0.465568 0.005803 +vt 0.465296 0.005976 +vt 0.312496 0.016380 +vt 0.312573 0.015671 +vt 0.465489 0.005685 +vt 0.465214 0.005860 +vt 0.425330 0.115365 +vt 0.425606 0.115540 +vt 0.425682 0.115420 +vt 0.425409 0.115246 +vt 0.312310 0.050405 +vt 0.312240 0.051100 +vt 0.312309 0.018103 +vt 0.312562 0.046473 +vt 0.312463 0.048723 +vt 0.421613 0.110152 +vt 0.422988 0.112514 +vt 0.423093 0.112417 +vt 0.421728 0.110064 +vt 0.424220 0.114246 +vt 0.424315 0.114139 +vt 0.424411 0.114031 +vt 0.423199 0.112319 +vt 0.421842 0.109976 +vt 0.461765 0.011108 +vt 0.460784 0.013638 +vt 0.460908 0.013716 +vt 0.461882 0.011194 +vt 0.460146 0.015722 +vt 0.460277 0.015785 +vt 0.461032 0.013794 +vt 0.461998 0.011281 +vt 0.419811 0.103183 +vt 0.419466 0.104278 +vt 0.419603 0.104244 +vt 0.419947 0.103189 +vt 0.419771 0.105535 +vt 0.419900 0.105471 +vt 0.420084 0.103194 +vt 0.215091 0.737592 +vt 0.215050 0.739292 +vt 0.215182 0.739293 +vt 0.215222 0.737594 +vt 0.215071 0.741532 +vt 0.215204 0.741533 +vt 0.215336 0.741533 +vt 0.215313 0.739293 +vt 0.215353 0.737595 +vt 0.459887 0.016975 +vt 0.460025 0.017007 +vt 0.460237 0.018044 +vt 0.460374 0.018036 +vt 0.460510 0.018030 +vt 0.464163 0.007002 +vt 0.463021 0.008742 +vt 0.463128 0.008837 +vt 0.464261 0.007107 +vt 0.463236 0.008933 +vt 0.215085 0.764067 +vt 0.215087 0.766144 +vt 0.215220 0.766146 +vt 0.215218 0.764068 +vt 0.215069 0.768327 +vt 0.215201 0.768329 +vt 0.215334 0.768331 +vt 0.215353 0.766148 +vt 0.215351 0.764069 +vt 0.215044 0.770556 +vt 0.215176 0.770558 +vt 0.215075 0.772446 +vt 0.215207 0.772447 +vt 0.215338 0.772449 +vt 0.215308 0.770560 +vt 0.420507 0.107622 +vt 0.420629 0.107542 +vt 0.420751 0.107462 +vt 0.215037 0.760015 +vt 0.215063 0.762058 +vt 0.215197 0.762059 +vt 0.215170 0.760016 +vt 0.215330 0.762059 +vt 0.215304 0.760016 +vt 0.426725 0.094766 +vt 0.425003 0.096675 +vt 0.425104 0.096758 +vt 0.426824 0.094851 +vt 0.422827 0.099226 +vt 0.422934 0.099298 +vt 0.423041 0.099369 +vt 0.425204 0.096841 +vt 0.426924 0.094936 +vt 0.215016 0.755623 +vt 0.215019 0.757854 +vt 0.215153 0.757854 +vt 0.215150 0.755623 +vt 0.215287 0.757854 +vt 0.215284 0.755623 +vt 0.420981 0.101503 +vt 0.421104 0.101547 +vt 0.421227 0.101590 +vt 0.215046 0.751153 +vt 0.215027 0.753388 +vt 0.215161 0.753388 +vt 0.215179 0.751153 +vt 0.215295 0.753388 +vt 0.215313 0.751153 +vt 0.464847 0.006160 +vt 0.464936 0.006272 +vt 0.463153 0.021775 +vt 0.465177 0.024076 +vt 0.465274 0.023989 +vt 0.463257 0.021701 +vt 0.466691 0.025693 +vt 0.466787 0.025604 +vt 0.466883 0.025516 +vt 0.465371 0.023903 +vt 0.463362 0.021626 +vt 0.424947 0.115077 +vt 0.425033 0.114963 +vt 0.215079 0.746526 +vt 0.215065 0.748891 +vt 0.215198 0.748891 +vt 0.215212 0.746526 +vt 0.215332 0.748891 +vt 0.215345 0.746526 +vt 0.461385 0.019652 +vt 0.461506 0.019606 +vt 0.461627 0.019560 +vt 0.215084 0.744020 +vt 0.215217 0.744020 +vt 0.215349 0.744020 +vt 0.637237 0.018154 +vt 0.637113 0.018152 +vt 0.624170 0.037924 +vt 0.624838 0.036357 +vt 0.624673 0.036331 +vt 0.624031 0.037845 +vt 0.624966 0.034206 +vt 0.507699 0.775138 +vt 0.505562 0.774999 +vt 0.505561 0.775676 +vt 0.507652 0.775788 +vt 0.509232 0.775859 +vt 0.508912 0.776162 +vt 0.501974 0.784171 +vt 0.503449 0.784990 +vt 0.503458 0.784854 +vt 0.502032 0.784066 +vt 0.505442 0.785170 +vt 0.505441 0.785029 +vt 0.505457 0.784231 +vt 0.503497 0.784090 +vt 0.502320 0.783690 +vt 0.625083 0.032102 +vt 0.624733 0.030604 +vt 0.503452 0.775056 +vt 0.501961 0.775713 +vt 0.502268 0.776026 +vt 0.503494 0.775705 +vt 0.279669 0.410671 +vt 0.279514 0.413281 +vt 0.279912 0.408765 +vt 0.501440 0.782244 +vt 0.502030 0.782192 +vt 0.501332 0.779780 +vt 0.501956 0.779763 +vt 0.314769 0.034483 +vt 0.497906 0.377727 +vt 0.498177 0.376175 +vt 0.498068 0.376248 +vt 0.497786 0.377743 +vt 0.322345 0.036851 +vt 0.324120 0.036185 +vt 0.407704 0.422683 +vt 0.408097 0.420660 +vt 0.407973 0.420687 +vt 0.407591 0.422684 +vt 0.624511 0.038704 +vt 0.624963 0.036386 +vt 0.624295 0.038016 +vt 0.322330 0.028048 +vt 0.324093 0.028623 +vt 0.279921 0.415951 +vt 0.279792 0.415945 +vt 0.280183 0.417915 +vt 0.280046 0.417883 +vt 0.505540 0.779841 +vt 0.505498 0.782341 +vt 0.507533 0.782389 +vt 0.507625 0.779895 +vt 0.507429 0.784222 +vt 0.508638 0.783895 +vt 0.509006 0.782399 +vt 0.509176 0.779946 +vt 0.503478 0.782268 +vt 0.503474 0.779790 +vt 0.501988 0.777405 +vt 0.503474 0.777385 +vt 0.505558 0.777417 +vt 0.507665 0.777477 +vt 0.509190 0.777564 +vt 0.407483 0.422693 +vt 0.407312 0.425371 +vt 0.407854 0.420755 +vt 0.509819 0.777573 +vt 0.509819 0.779994 +vt 0.279667 0.415930 +vt 0.279914 0.417811 +vt 0.501381 0.777389 +vt 0.507447 0.785130 +vt 0.507436 0.784993 +vt 0.508974 0.784404 +vt 0.508914 0.784294 +vt 0.407495 0.428003 +vt 0.407849 0.429878 +vt 0.509607 0.782486 +vn -0.9998 -0.0173 0.0065 +vn -1.0000 -0.0043 0.0027 +vn -1.0000 -0.0026 0.0034 +vn -0.9998 -0.0200 0.0002 +vn -0.9998 -0.0188 -0.0032 +vn -1.0000 -0.0043 -0.0004 +vn -0.9999 -0.0134 -0.0063 +vn -1.0000 0.0039 -0.0024 +vn -1.0000 0.0004 -0.0024 +vn -0.9999 -0.0095 -0.0062 +vn -1.0000 0.0079 -0.0023 +vn -1.0000 0.0040 -0.0023 +vn -1.0000 -0.0052 -0.0058 +vn -0.9999 0.0122 -0.0018 +vn -1.0000 0.0078 -0.0023 +vn -1.0000 -0.0004 -0.0056 +vn -0.9999 0.0163 -0.0008 +vn -0.9999 0.0123 -0.0017 +vn -1.0000 0.0042 -0.0048 +vn -0.9998 0.0196 0.0007 +vn -1.0000 0.0077 -0.0032 +vn -0.9998 0.0213 0.0022 +vn -0.9998 0.0197 0.0008 +vn -0.9966 -0.0818 -0.0033 +vn -0.9966 -0.0820 -0.0020 +vn -0.9966 -0.0818 -0.0027 +vn -0.9966 -0.0819 0.0012 +vn -0.9966 -0.0819 0.0020 +vn -0.9967 -0.0816 0.0020 +vn -0.9967 -0.0817 0.0013 +vn -0.9967 -0.0817 0.0021 +vn -0.9967 -0.0817 -0.0004 +vn -0.9966 -0.0819 -0.0024 +vn -0.9966 -0.0818 -0.0022 +vn -0.9966 -0.0819 -0.0015 +vn -0.9967 -0.0817 -0.0014 +vn -0.9966 -0.0818 -0.0018 +vn -0.9966 -0.0819 -0.0014 +vn -0.9966 -0.0819 -0.0005 +vn -0.9967 -0.0817 -0.0006 +vn -0.9967 -0.0818 -0.0010 +vn -0.9967 -0.0817 -0.0007 +vn -0.9966 -0.0818 -0.0004 +vn -0.9967 -0.0817 0.0002 +vn -0.9967 -0.0817 -0.0001 +vn -0.9966 -0.0819 0.0005 +vn -0.9967 -0.0817 0.0009 +vn -0.9996 -0.0289 0.0042 +vn -0.9996 -0.0287 0.0060 +vn -0.9939 -0.1099 -0.0003 +vn -0.9940 -0.1097 -0.0003 +vn -0.9939 -0.1098 -0.0028 +vn -0.9996 -0.0288 -0.0018 +vn -0.9996 -0.0289 0.0014 +vn -0.9940 -0.1095 -0.0000 +vn -0.9996 -0.0291 -0.0018 +vn -0.9940 -0.1098 -0.0000 +vn -0.9996 -0.0290 0.0014 +vn -0.9940 -0.1097 -0.0002 +vn -0.9940 -0.1095 -0.0002 +vn -0.9996 -0.0286 -0.0059 +vn -0.9996 -0.0288 -0.0044 +vn -0.9939 -0.1099 0.0001 +vn -0.9996 -0.0284 -0.0060 +vn -0.9939 -0.1099 0.0002 +vn -0.9996 -0.0286 -0.0044 +vn -0.9996 -0.0290 -0.0018 +vn -0.9940 -0.1096 0.0001 +vn -0.9996 -0.0287 -0.0044 +vn -0.9940 -0.1098 0.0002 +vn -0.9995 -0.0296 -0.0093 +vn -0.9996 -0.0289 -0.0073 +vn -0.9939 -0.1101 0.0002 +vn -0.9995 -0.0294 -0.0093 +vn -0.9940 -0.1097 0.0000 +vn -0.9996 -0.0291 -0.0073 +vn -0.9996 -0.0285 -0.0059 +vn -0.9939 -0.1101 0.0000 +vn -0.9996 -0.0287 -0.0073 +vn -0.9939 -0.1100 0.0000 +vn -0.9995 -0.0287 -0.0103 +vn -0.9995 -0.0294 -0.0108 +vn -0.9939 -0.1105 0.0009 +vn -0.9995 -0.0284 -0.0103 +vn -0.9939 -0.1104 0.0009 +vn -0.9995 -0.0292 -0.0108 +vn -0.9995 -0.0294 -0.0094 +vn -0.9939 -0.1101 0.0006 +vn -0.9939 -0.1104 0.0007 +vn -0.9996 -0.0275 0.0008 +vn -0.9996 -0.0276 -0.0071 +vn -0.9938 -0.1108 0.0003 +vn -0.9996 -0.0276 -0.0072 +vn -0.9995 -0.0286 -0.0103 +vn -0.9939 -0.1106 0.0008 +vn -0.9939 -0.1107 0.0009 +vn -0.9939 -0.1107 0.0004 +vn -0.9999 0.0151 0.0036 +vn -0.9999 0.0156 0.0058 +vn -0.9998 -0.0189 0.0041 +vn -0.9998 -0.0202 0.0045 +vn -0.9996 0.0132 0.0264 +vn -0.9996 -0.0193 0.0209 +vn -0.9813 -0.1923 0.0121 +vn -0.9809 -0.1943 -0.0007 +vn -0.9802 -0.1979 0.0051 +vn -1.0000 0.0097 -0.0009 +vn -1.0000 0.0068 0.0069 +vn -0.9998 0.0214 0.0060 +vn -0.9998 0.0215 0.0022 +vn -0.9996 0.0068 0.0264 +vn -0.9995 0.0153 0.0287 +vn -0.9997 -0.0113 -0.0197 +vn -0.9999 -0.0136 0.0016 +vn -1.0000 0.0025 -0.0010 +vn -0.9997 -0.0009 -0.0246 +vn -0.9999 -0.0141 0.0077 +vn -1.0000 0.0001 0.0030 +vn -1.0000 -0.0074 0.0005 +vn -1.0000 -0.0046 -0.0032 +vn -0.9997 -0.0047 -0.0235 +vn -1.0000 -0.0025 0.0035 +vn -0.9998 -0.0199 0.0040 +vn -1.0000 -0.0048 0.0029 +vn -0.9999 -0.0127 0.0016 +vn -0.9999 -0.0102 0.0013 +vn -1.0000 -0.0052 0.0013 +vn -1.0000 -0.0044 -0.0005 +vn -0.9999 -0.0123 0.0008 +vn -0.9999 -0.0134 0.0012 +vn -0.9998 -0.0189 -0.0032 +vn -0.9998 -0.0166 -0.0056 +vn -1.0000 -0.0024 -0.0019 +vn -1.0000 -0.0069 0.0014 +vn -0.9999 -0.0100 0.0008 +vn -0.9999 -0.0096 -0.0062 +vn -1.0000 0.0039 -0.0025 +vn -1.0000 -0.0053 -0.0059 +vn -1.0000 0.0010 0.0032 +vn -1.0000 -0.0031 0.0023 +vn -1.0000 -0.0005 -0.0056 +vn -0.9999 0.0123 -0.0018 +vn -0.9999 0.0094 0.0040 +vn -1.0000 0.0054 0.0035 +vn -1.0000 0.0078 -0.0031 +vn -0.9998 0.0198 0.0007 +vn -0.9999 0.0130 0.0038 +vn -0.9991 -0.0431 -0.0059 +vn -0.9989 -0.0403 -0.0233 +vn -0.9989 -0.0478 -0.0030 +vn -0.9716 -0.2360 -0.0157 +vn -0.9744 -0.2242 -0.0193 +vn -0.9758 -0.2159 -0.0350 +vn -0.9986 -0.0531 -0.0016 +vn -0.9984 -0.0567 -0.0005 +vn -0.9672 -0.2537 -0.0075 +vn -0.9691 -0.2465 -0.0125 +vn -0.9984 -0.0569 0.0006 +vn -0.9985 -0.0555 0.0025 +vn -0.9677 -0.2521 0.0070 +vn -0.9668 -0.2554 -0.0006 +vn -0.9986 -0.0519 0.0045 +vn -0.9989 -0.0473 0.0069 +vn -0.9710 -0.2378 0.0222 +vn -0.9692 -0.2457 0.0148 +vn -0.9991 -0.0423 0.0092 +vn -0.9993 -0.0371 0.0110 +vn -0.9746 -0.2212 0.0336 +vn -0.9729 -0.2294 0.0293 +vn -0.9994 -0.0322 0.0115 +vn -0.9996 -0.0276 0.0103 +vn -0.9777 -0.2083 0.0260 +vn -0.9761 -0.2146 0.0330 +vn -0.9997 -0.0234 0.0077 +vn -0.9791 -0.2026 0.0154 +vn -0.4198 -0.9026 0.0954 +vn -0.4266 -0.9026 0.0570 +vn -0.3244 -0.9433 0.0706 +vn -0.3168 -0.9421 0.1098 +vn -0.4288 -0.9034 0.0067 +vn -0.3270 -0.9450 0.0115 +vn -0.1131 -0.9934 0.0186 +vn -0.1088 -0.9905 0.0846 +vn -0.1018 -0.9868 0.1260 +vn -0.4140 -0.9040 0.1064 +vn -0.4149 -0.9029 0.1121 +vn -0.3103 -0.9428 0.1222 +vn -0.3080 -0.9450 0.1102 +vn -0.0942 -0.9863 0.1352 +vn -0.0901 -0.9890 0.1171 +vn -0.4195 -0.9050 0.0707 +vn -0.4164 -0.9048 0.0889 +vn -0.3102 -0.9466 0.0885 +vn -0.3135 -0.9469 0.0713 +vn -0.0907 -0.9917 0.0906 +vn -0.0923 -0.9930 0.0736 +vn -0.4220 -0.9063 0.0227 +vn -0.4210 -0.9057 0.0501 +vn -0.3158 -0.9474 0.0519 +vn -0.3170 -0.9482 0.0227 +vn -0.0938 -0.9941 0.0550 +vn -0.0946 -0.9952 0.0230 +vn -0.4275 -0.9033 -0.0374 +vn -0.4242 -0.9055 -0.0090 +vn -0.3199 -0.9474 -0.0128 +vn -0.3235 -0.9452 -0.0437 +vn -0.0977 -0.9951 -0.0166 +vn -0.1023 -0.9935 -0.0508 +vn -0.4334 -0.8990 -0.0636 +vn -0.4310 -0.9006 -0.0559 +vn -0.3282 -0.9425 -0.0629 +vn -0.3325 -0.9405 -0.0694 +vn -0.1081 -0.9916 -0.0715 +vn -0.1162 -0.9901 -0.0791 +vn -0.4345 -0.8968 -0.0837 +vn -0.4340 -0.8984 -0.0669 +vn -0.3356 -0.9393 -0.0712 +vn -0.3387 -0.9370 -0.0854 +vn -0.1373 -0.9868 -0.0862 +vn -0.1829 -0.9758 -0.1201 +vn -0.4255 -0.9043 -0.0339 +vn -0.3242 -0.9452 -0.0382 +vn -0.4224 -0.9057 -0.0357 +vn -0.3228 -0.9454 -0.0460 +vn -0.1674 -0.9857 -0.0215 +vn -0.1271 -0.9914 -0.0325 +vn -0.8099 -0.5864 -0.0107 +vn -0.8088 -0.5881 0.0044 +vn -0.8113 -0.5846 0.0005 +vn -0.5766 -0.8169 -0.0102 +vn -0.5792 -0.8150 -0.0192 +vn -0.5817 -0.8134 0.0037 +vn -0.7981 -0.6006 -0.0482 +vn -0.8027 -0.5926 -0.0672 +vn -0.7920 -0.6090 -0.0419 +vn -0.5777 -0.8143 -0.0569 +vn -0.5788 -0.8129 -0.0645 +vn -0.8026 -0.5927 -0.0672 +vn -0.5789 -0.8109 -0.0853 +vn -0.7858 -0.6175 -0.0337 +vn -0.7813 -0.6238 -0.0204 +vn -0.5719 -0.8198 -0.0282 +vn -0.5754 -0.8165 -0.0465 +vn -0.7797 -0.6262 -0.0026 +vn -0.7808 -0.6246 0.0162 +vn -0.7808 -0.6246 0.0161 +vn -0.5681 -0.8227 0.0215 +vn -0.5695 -0.8220 -0.0042 +vn -0.7837 -0.6201 0.0343 +vn -0.7874 -0.6143 0.0516 +vn -0.7838 -0.6201 0.0342 +vn -0.7873 -0.6144 0.0516 +vn -0.5691 -0.8195 0.0672 +vn -0.5686 -0.8214 0.0452 +vn -0.7908 -0.6084 0.0667 +vn -0.7942 -0.6028 0.0765 +vn -0.7942 -0.6029 0.0765 +vn -0.5686 -0.8166 0.0994 +vn -0.5685 -0.8181 0.0866 +vn -0.7975 -0.5988 0.0741 +vn -0.8015 -0.5954 0.0553 +vn -0.5745 -0.8152 0.0732 +vn -0.5703 -0.8157 0.0971 +vn -0.8060 -0.5913 0.0288 +vn -0.8059 -0.5913 0.0289 +vn -0.5799 -0.8138 0.0380 +vn 0.5595 -0.8095 0.1779 +vn 0.6605 -0.7508 0.0016 +vn 0.9066 -0.0941 0.4114 +vn 0.9986 -0.0439 0.0293 +vn 0.6605 -0.7508 0.0017 +vn 0.9993 -0.0376 0.0061 +vn 0.6752 -0.7373 0.0210 +vn 0.6936 -0.7191 -0.0420 +vn 0.6892 -0.7221 -0.0592 +vn 0.6936 -0.7192 -0.0419 +vn 0.9995 -0.0323 -0.0074 +vn 0.9994 -0.0330 -0.0105 +vn 0.6892 -0.7221 -0.0593 +vn 0.9993 -0.0342 -0.0145 +vn 0.6831 -0.7271 -0.0682 +vn 0.6832 -0.7271 -0.0683 +vn 0.6946 -0.7170 0.0582 +vn 0.6960 -0.7167 0.0441 +vn 0.9994 -0.0328 0.0103 +vn 0.9994 -0.0323 0.0077 +vn 0.6961 -0.7166 0.0440 +vn 0.9995 -0.0318 0.0031 +vn 0.6976 -0.7162 0.0182 +vn 0.6976 -0.7162 0.0183 +vn 0.6849 -0.7210 0.1052 +vn 0.6910 -0.7144 0.1102 +vn 0.6849 -0.7210 0.1051 +vn 0.9992 -0.0349 0.0186 +vn 0.9992 -0.0336 0.0194 +vn 0.6910 -0.7144 0.1101 +vn 0.9993 -0.0326 0.0164 +vn 0.6957 -0.7123 0.0933 +vn 0.6957 -0.7123 0.0934 +vn 0.6583 -0.7458 -0.1024 +vn 0.9981 -0.0415 -0.0458 +vn 0.9008 -0.1082 -0.4204 +vn 0.5259 -0.7944 -0.3038 +vn 0.5260 -0.7944 -0.3038 +vn 0.6967 -0.7173 -0.0138 +vn 0.9995 -0.0319 -0.0025 +vn 0.6966 -0.7173 -0.0139 +vn 0.6957 -0.7148 0.0716 +vn 0.9994 -0.0327 0.0126 +vn 0.6793 -0.7302 0.0728 +vn 0.9993 -0.0361 0.0128 +vn 0.6793 -0.7303 0.0728 +vn 1.0000 -0.0071 -0.0025 +vn 0.9992 0.0405 -0.0038 +vn 0.9993 0.0380 0.0017 +vn 1.0000 -0.0088 0.0012 +vn 0.9739 0.2270 -0.0046 +vn 0.9747 0.2235 0.0057 +vn 0.9748 0.2215 0.0257 +vn 0.9992 0.0354 0.0208 +vn 0.9997 -0.0121 0.0225 +vn 0.9991 -0.0422 -0.0034 +vn 0.9997 -0.0237 -0.0017 +vn 0.9997 -0.0244 0.0001 +vn 0.9990 -0.0451 0.0003 +vn 0.9993 -0.0303 0.0232 +vn 0.9988 -0.0443 0.0192 +vn 0.9993 -0.0283 -0.0244 +vn 0.9996 -0.0110 -0.0278 +vn 1.0000 -0.0051 -0.0045 +vn 0.9996 -0.0289 -0.0049 +vn 0.9997 0.0087 -0.0229 +vn 0.9999 0.0129 -0.0033 +vn 0.9999 0.0164 -0.0012 +vn 1.0000 -0.0025 -0.0031 +vn 0.9997 -0.0251 -0.0014 +vn 1.0000 0.0000 -0.0030 +vn 0.9997 -0.0234 -0.0027 +vn 0.9998 0.0199 -0.0014 +vn 0.9997 0.0224 -0.0014 +vn 1.0000 0.0022 -0.0028 +vn 0.9998 -0.0215 -0.0035 +vn 1.0000 0.0029 -0.0014 +vn 0.9998 -0.0208 -0.0026 +vn 0.9997 0.0229 -0.0009 +vn 0.9998 0.0217 -0.0006 +vn 1.0000 0.0021 0.0003 +vn 0.9998 -0.0210 -0.0009 +vn 1.0000 0.0002 0.0016 +vn 0.9998 -0.0221 0.0012 +vn 0.9998 0.0192 -0.0007 +vn 0.9999 0.0157 -0.0017 +vn 1.0000 -0.0025 0.0021 +vn 0.9997 -0.0242 0.0033 +vn 1.0000 -0.0060 0.0023 +vn 0.9996 -0.0267 0.0052 +vn 0.9999 0.0118 -0.0029 +vn 1.0000 0.0076 -0.0040 +vn 0.9999 -0.0100 0.0019 +vn 0.9995 -0.0304 0.0068 +vn 0.9999 -0.0143 0.0020 +vn 0.9994 -0.0349 0.0072 +vn 1.0000 0.0034 -0.0046 +vn 1.0000 -0.0007 -0.0045 +vn 0.9998 -0.0183 0.0006 +vn 0.9992 -0.0386 0.0044 +vn 0.9998 -0.0216 -0.0008 +vn 0.9991 -0.0413 0.0001 +vn 1.0000 -0.0042 -0.0041 +vn 0.9982 0.0584 -0.0154 +vn 0.9980 0.0631 0.0014 +vn 0.9695 0.2449 0.0013 +vn 0.9675 0.2522 0.0163 +vn 0.9646 0.2633 0.0168 +vn 0.9976 0.0691 0.0029 +vn 0.9972 0.0745 0.0024 +vn 0.9617 0.2738 0.0138 +vn 0.9598 0.2805 0.0083 +vn 0.9969 0.0786 0.0012 +vn 0.9968 0.0795 -0.0004 +vn 0.9603 0.2791 -0.0003 +vn 0.9639 0.2660 -0.0105 +vn 0.9970 0.0774 -0.0025 +vn 0.9973 0.0734 -0.0050 +vn 0.9687 0.2475 -0.0174 +vn 0.9720 0.2340 -0.0224 +vn 0.9976 0.0684 -0.0080 +vn 0.9980 0.0630 -0.0109 +vn 0.9726 0.2310 -0.0270 +vn 0.9713 0.2356 -0.0317 +vn 0.9982 0.0577 -0.0130 +vn 0.9985 0.0528 -0.0135 +vn 0.9704 0.2390 -0.0339 +vn 0.9711 0.2369 -0.0280 +vn 0.9988 0.0482 -0.0116 +vn 0.9990 0.0440 -0.0081 +vn 0.9727 0.2315 -0.0163 +vn 0.4109 0.9067 -0.0948 +vn 0.3104 0.9443 -0.1095 +vn 0.3181 0.9454 -0.0711 +vn 0.4178 0.9067 -0.0576 +vn 0.2160 0.9687 -0.1221 +vn 0.2232 0.9713 -0.0827 +vn 0.2252 0.9742 -0.0174 +vn 0.3206 0.9471 -0.0115 +vn 0.4201 0.9074 -0.0065 +vn 0.4025 0.9148 -0.0343 +vn 0.2896 0.9564 -0.0386 +vn 0.3035 0.9459 -0.1147 +vn 0.4053 0.9083 -0.1039 +vn 0.1248 0.9911 -0.0474 +vn 0.2043 0.9711 -0.1237 +vn 0.8256 0.5619 -0.0507 +vn 0.7555 0.6506 -0.0769 +vn 0.9592 0.2162 -0.1825 +vn 0.9974 0.0702 -0.0150 +vn 0.6152 0.7849 -0.0739 +vn 0.7421 0.5424 -0.3938 +vn 0.7529 0.1609 -0.6382 +vn 0.9720 -0.0502 -0.2297 +vn 0.9962 -0.0874 -0.0031 +vn 0.1311 0.9872 -0.0911 +vn -0.1845 0.9762 -0.1137 +vn -0.6071 0.7614 -0.2276 +vn -0.1533 0.8871 -0.4353 +vn -0.3760 0.9240 -0.0699 +vn -0.7575 0.6507 -0.0523 +vn -0.6070 0.7614 -0.2275 +vn -0.7577 0.6506 -0.0523 +vn -0.7603 0.6474 -0.0520 +vn -0.7085 0.6508 -0.2727 +vn -0.1534 0.8871 -0.4353 +vn -0.4079 0.6315 -0.6594 +vn 0.4183 0.9075 0.0379 +vn 0.3162 0.9477 0.0439 +vn 0.3134 0.9496 0.0089 +vn 0.4150 0.9098 0.0058 +vn 0.2188 0.9745 0.0487 +vn 0.2106 0.9775 0.0087 +vn 0.3000 0.9498 -0.0888 +vn 0.4098 0.9081 -0.0865 +vn 0.4244 0.9033 0.0633 +vn 0.3252 0.9431 0.0691 +vn 0.3208 0.9451 0.0630 +vn 0.4218 0.9049 0.0561 +vn 0.2294 0.9704 0.0751 +vn 0.2241 0.9721 0.0693 +vn 0.4246 0.9042 0.0470 +vn 0.3290 0.9429 0.0521 +vn 0.3283 0.9422 0.0674 +vn 0.4251 0.9030 0.0626 +vn 0.2354 0.9702 0.0575 +vn 0.2339 0.9695 0.0730 +vn 0.3178 0.9472 0.0425 +vn 0.4166 0.9082 0.0386 +vn 0.2232 0.9738 0.0432 +vn 0.2190 0.9720 0.0847 +vn 0.3126 0.9463 0.0819 +vn 0.4105 0.9087 0.0757 +vn 0.8017 0.5977 -0.0040 +vn 0.8023 0.5967 0.0163 +vn 0.5819 0.8133 -0.0032 +vn 0.5788 0.8151 0.0249 +vn 0.5729 0.8176 0.0567 +vn 0.8006 0.5977 0.0429 +vn 0.7942 0.6070 0.0282 +vn 0.7914 0.6097 0.0441 +vn 0.5781 0.8148 0.0427 +vn 0.5791 0.8131 0.0593 +vn 0.5787 0.8135 0.0566 +vn 0.7862 0.6166 0.0421 +vn 0.7804 0.6243 0.0343 +vn 0.5767 0.8156 0.0466 +vn 0.5735 0.8187 0.0281 +vn 0.7764 0.6299 0.0204 +vn 0.7791 0.6270 -0.0017 +vn 0.5737 0.8190 -0.0016 +vn 0.6153 0.7849 -0.0739 +vn 0.7985 0.6013 -0.0295 +vn 0.8361 0.5469 -0.0428 +vn 0.8592 0.5097 -0.0450 +vn 0.8449 0.5328 -0.0487 +vn 0.7630 0.6455 -0.0331 +vn 0.8449 0.5327 -0.0487 +vn 0.7630 0.6455 -0.0332 +vn 0.6217 0.7823 -0.0398 +vn 0.8131 0.5791 -0.0596 +vn 0.7964 0.6008 -0.0693 +vn 0.5755 0.8129 -0.0892 +vn 0.5755 0.8146 -0.0727 +vn 0.7954 0.6036 -0.0555 +vn 0.7991 0.6005 -0.0293 +vn 0.5800 0.8137 -0.0384 +vn 0.0705 0.9966 0.0435 +vn 0.0682 0.9938 0.0873 +vn 0.0721 0.9972 -0.0213 +vn -0.0778 0.9967 -0.0222 +vn -0.0773 0.9960 0.0440 +vn -0.0803 0.9927 0.0900 +vn 0.0713 0.9947 0.0744 +vn 0.0660 0.9964 0.0526 +vn 0.0757 0.9939 0.0808 +vn -0.0741 0.9938 0.0830 +vn -0.0768 0.9941 0.0766 +vn -0.0793 0.9954 0.0545 +vn -0.1045 0.9920 -0.0704 +vn -0.1715 0.9825 -0.0730 +vn 0.0005 0.9992 -0.0400 +vn -0.1014 0.9945 -0.0251 +vn -0.1207 0.9910 -0.0575 +vn -0.1285 0.9890 -0.0734 +vn 0.0526 0.9896 -0.1338 +vn 0.0678 0.9890 -0.1315 +vn 0.0021 0.9948 -0.1017 +vn -0.0966 0.9884 -0.1171 +vn -0.0810 0.9868 -0.1404 +vn -0.0760 0.9879 -0.1349 +vn 0.0800 0.9937 0.0784 +vn 0.0820 0.9947 0.0624 +vn -0.0726 0.9954 0.0629 +vn -0.0716 0.9942 0.0805 +vn 0.0513 0.9986 0.0124 +vn -0.0859 0.9961 0.0176 +vn -0.1854 0.9822 -0.0316 +vn -0.1029 0.9918 -0.0758 +vn -0.1178 0.9891 -0.0888 +vn 0.0715 0.9933 -0.0908 +vn -0.0765 0.9927 -0.0933 +vn -0.9532 -0.3022 -0.0049 +vn -0.9591 -0.2773 0.0564 +vn -0.9382 -0.2370 -0.2523 +vn -0.4657 -0.6766 -0.5703 +vn -0.4870 -0.8731 -0.0204 +vn -0.5054 -0.8478 0.1604 +vn 0.9794 0.0764 0.1867 +vn -0.0010 -0.0107 0.9999 +vn 0.0392 -0.4535 0.8904 +vn 0.9657 -0.1623 0.2027 +vn -0.9791 -0.0826 0.1859 +vn -0.9225 -0.3252 0.2081 +vn 0.0393 -0.4536 0.8904 +vn -0.5949 -0.8028 0.0398 +vn 0.0886 -0.9422 0.3231 +vn 0.0888 -0.9422 0.3232 +vn 0.7388 -0.6728 0.0377 +vn -0.1328 0.9870 -0.0907 +vn -0.1320 0.9840 -0.1193 +vn -0.1339 0.9883 -0.0736 +vn -0.2637 0.9619 -0.0728 +vn -0.2625 0.9608 -0.0896 +vn -0.2612 0.9581 -0.1180 +vn -0.7708 -0.5252 -0.3605 +vn -0.9358 -0.1847 -0.3003 +vn -0.5530 -0.7424 -0.3782 +vn -0.7708 -0.5253 -0.3604 +vn -0.2849 -0.3117 -0.9065 +vn -0.3542 -0.1977 -0.9140 +vn -0.4798 -0.0748 -0.8742 +vn -0.1803 0.4227 0.8882 +vn -0.1312 0.9078 0.3984 +vn -0.5700 0.7426 0.3517 +vn -0.6655 0.2859 0.6894 +vn -0.1666 0.9813 0.0960 +vn -0.2836 0.9559 0.0757 +vn -0.7614 0.6324 0.1425 +vn -0.6656 0.2858 0.6894 +vn -0.5700 0.7426 0.3516 +vn -0.9771 0.0580 0.2049 +vn 0.4679 0.1473 -0.8714 +vn 0.3930 0.3493 -0.8506 +vn 0.7488 0.6060 -0.2683 +vn 0.9267 0.2530 -0.2779 +vn 0.3929 0.3493 -0.8506 +vn 0.2428 0.4355 -0.8668 +vn 0.5401 0.7982 -0.2668 +vn 0.9800 0.0696 -0.1862 +vn 0.9967 0.0760 -0.0301 +vn 0.9984 -0.0426 -0.0378 +vn 0.9580 -0.1689 -0.2317 +vn 0.9971 0.0764 -0.0051 +vn 0.9983 -0.0552 -0.0159 +vn 0.7146 -0.6964 -0.0660 +vn 0.7214 -0.6880 -0.0790 +vn 0.7315 -0.6675 -0.1393 +vn -0.9573 -0.2861 -0.0408 +vn -0.9602 -0.2773 -0.0325 +vn -0.9553 -0.2935 -0.0346 +vn -0.4945 -0.8634 -0.0999 +vn -0.4997 -0.8589 -0.1127 +vn -0.5063 -0.8583 -0.0842 +vn -0.1255 -0.0824 -0.9887 +vn 0.3227 -0.2758 -0.9054 +vn -0.4902 -0.1494 -0.8587 +vn -0.6847 -0.0630 -0.7261 +vn 0.9009 -0.1082 -0.4204 +vn -0.1526 -0.0972 -0.9835 +vn -0.1526 -0.0973 -0.9835 +vn -0.9808 -0.0843 -0.1757 +vn -0.9813 -0.0863 -0.1721 +vn -0.9811 -0.0886 -0.1720 +vn 0.0081 0.4570 0.8894 +vn 0.0446 0.4485 0.8927 +vn 0.2567 0.8909 0.3747 +vn 0.1720 0.9118 0.3729 +vn 0.1018 0.4331 0.8956 +vn 0.3512 0.8575 0.3760 +vn -0.1312 0.9812 -0.1414 +vn -0.1320 0.9820 -0.1349 +vn -0.2601 0.9554 -0.1397 +vn -0.2607 0.9562 -0.1331 +vn -0.9331 -0.0861 0.3492 +vn -0.9412 -0.0260 0.3367 +vn -0.9394 -0.2102 0.2707 +vn -0.4638 -0.6531 0.5986 +vn -0.4332 -0.2634 0.8619 +vn -0.4484 -0.0990 0.8883 +vn 0.4471 -0.1069 0.8881 +vn 0.4262 -0.2825 0.8594 +vn 0.9299 -0.1284 0.3446 +vn 0.9413 -0.0482 0.3340 +vn 0.4343 -0.6777 0.5934 +vn 0.9294 -0.2589 0.2631 +vn -0.9964 -0.0850 -0.0005 +vn -0.9964 -0.0850 0.0004 +vn -0.9751 -0.2216 -0.0023 +vn -0.9752 -0.2215 0.0027 +vn -0.9964 -0.0850 0.0011 +vn -0.9752 -0.2212 -0.0065 +vn -0.5623 -0.8259 -0.0418 +vn -0.5616 -0.8273 -0.0142 +vn -0.5616 -0.8272 0.0175 +vn -0.9489 -0.0283 0.3142 +vn -0.9377 -0.1691 0.3035 +vn -0.4662 -0.0392 0.8838 +vn -0.4465 -0.0797 0.8912 +vn 0.4614 -0.8826 0.0898 +vn 0.9500 -0.3099 0.0393 +vn 0.4922 -0.8612 -0.1271 +vn 0.9606 -0.2753 -0.0376 +vn -0.5075 -0.8614 -0.0216 +vn -0.5040 -0.8068 0.3082 +vn -0.4337 -0.8531 0.2900 +vn -0.5645 -0.7607 0.3204 +vn -0.3030 -0.3245 0.8960 +vn -0.2893 -0.3507 0.8907 +vn -0.2729 -0.3734 0.8866 +vn -0.1337 0.9866 -0.0931 +vn -0.1330 0.9909 -0.0223 +vn -0.2617 0.9608 -0.0919 +vn -0.2642 0.9642 -0.0221 +vn -0.9649 -0.2586 0.0462 +vn -0.9742 -0.2230 -0.0357 +vn -0.5437 -0.8298 -0.1256 +vn -0.5100 -0.8549 0.0952 +vn 0.1517 0.4078 0.9004 +vn 0.4359 0.8174 0.3766 +vn 0.2014 0.3904 0.8983 +vn 0.5124 0.7748 0.3702 +vn 0.4964 0.8656 0.0659 +vn 0.9971 0.0764 -0.0022 +vn 0.9983 -0.0567 -0.0125 +vn 0.9971 0.0764 -0.0015 +vn 0.9983 -0.0574 -0.0089 +vn 0.7119 -0.7010 -0.0423 +vn 0.7129 -0.6987 -0.0593 +vn -0.9632 -0.2682 -0.0160 +vn -0.9654 -0.2608 0.0003 +vn -0.5132 -0.8577 -0.0318 +vn -0.5180 -0.8551 0.0209 +vn -0.9546 -0.0390 -0.2953 +vn -0.9474 -0.0281 -0.3188 +vn -0.5077 -0.0245 -0.8612 +vn -0.4847 -0.0711 -0.8718 +vn -0.9568 -0.2888 0.0349 +vn -0.9547 -0.2975 0.0078 +vn -0.4987 -0.8616 0.0948 +vn -0.4927 -0.8701 0.0145 +vn -0.9682 -0.2500 0.0037 +vn -0.9715 -0.2368 -0.0113 +vn -0.5261 -0.8497 0.0352 +vn -0.5369 -0.8434 -0.0180 +vn -0.1287 0.9907 0.0442 +vn -0.2727 0.9613 0.0394 +vn -0.9996 -0.0274 0.0008 +vn -0.9991 -0.0274 0.0323 +vn -0.8253 0.5625 0.0488 +vn -0.8110 0.5849 -0.0133 +vn -0.8253 0.5626 0.0487 +vn -0.8113 0.5845 -0.0132 +vn -0.3466 -0.8973 0.2735 +vn -0.2365 -0.9201 0.3122 +vn -0.2492 -0.4035 0.8804 +vn -0.1993 -0.4036 0.8930 +vn 0.5071 0.8619 -0.0039 +vn 0.5036 0.8634 0.0322 +vn 0.5073 0.8607 0.0442 +vn 0.5089 0.8587 0.0609 +vn 0.5098 0.8582 0.0598 +vn 0.5085 0.8595 0.0508 +vn 0.5057 0.8621 0.0324 +vn 0.5031 0.8642 0.0017 +vn 0.5068 0.8578 -0.0860 +vn 0.1698 0.8214 -0.5445 +vn 0.3309 0.7591 -0.5606 +vn 0.1698 0.8214 -0.5446 +vn 0.0164 0.5354 -0.8444 +vn 0.3309 0.7592 -0.5605 +vn 0.2017 0.4858 -0.8505 +vn 0.1736 0.8919 0.4175 +vn -0.1537 0.9418 0.2991 +vn 0.3476 0.8292 0.4378 +vn 0.1736 0.8919 0.4176 +vn 0.3476 0.8291 0.4379 +vn 0.2382 0.6040 0.7606 +vn 0.0344 0.6568 0.7533 +vn -0.4031 0.7251 0.5584 +vn 0.5046 0.8628 -0.0314 +vn 0.4963 0.8629 -0.0952 +vn 0.4995 0.8624 -0.0819 +vn 0.5052 0.8617 -0.0462 +vn -0.5119 -0.8587 -0.0266 +vn -0.5154 -0.8570 0.0042 +vn -0.5168 -0.8536 -0.0659 +vn -0.5151 -0.8529 -0.0850 +vn -0.5175 -0.8536 -0.0597 +vn -0.5164 -0.8548 -0.0505 +vn -0.5138 -0.8573 -0.0324 +vn -0.5108 -0.8597 -0.0059 +vn -0.5093 -0.8603 0.0219 +vn -0.5086 -0.8597 0.0477 +vn -0.5077 -0.8587 0.0694 +vn -0.5052 -0.8584 0.0886 +vn -0.5033 -0.8580 0.1029 +vn -0.5036 -0.8577 0.1037 +vn -0.5076 -0.8576 0.0825 +vn -0.5134 -0.8569 0.0458 +vn -0.9966 -0.0819 0.0021 +vn -0.9963 -0.0814 0.0288 +vn -0.9960 -0.0845 0.0287 +vn -0.9964 -0.0852 0.0021 +vn -0.9801 -0.0781 0.1825 +vn -0.9807 -0.0820 0.1774 +vn -0.9802 -0.0933 0.1748 +vn -0.9947 -0.0986 0.0282 +vn -0.9950 -0.0997 0.0025 +vn -0.9966 -0.0821 -0.0029 +vn -0.9966 -0.0821 -0.0032 +vn -0.9964 -0.0852 -0.0028 +vn -0.9964 -0.0851 -0.0026 +vn -0.9966 -0.0821 -0.0030 +vn -0.9950 -0.0997 -0.0006 +vn -0.9950 -0.0994 -0.0008 +vn -0.9951 -0.0991 -0.0009 +vn -0.9966 -0.0820 -0.0023 +vn -0.9964 -0.0851 -0.0021 +vn -0.9964 -0.0851 -0.0017 +vn -0.9951 -0.0992 -0.0009 +vn -0.9951 -0.0989 -0.0007 +vn -0.9815 0.0699 -0.1781 +vn -0.9994 -0.0264 -0.0216 +vn -0.8226 0.5676 0.0348 +vn -0.7652 0.6430 -0.0312 +vn -0.9996 -0.0290 0.0040 +vn -0.8150 0.5769 0.0536 +vn -0.8227 0.5675 0.0348 +vn -0.8147 0.5774 0.0537 +vn -0.2621 0.9615 0.0822 +vn -0.2675 0.9604 0.0783 +vn -0.7651 0.6432 -0.0311 +vn -0.2756 0.9587 0.0699 +vn -0.9966 -0.0819 0.0003 +vn -0.9964 -0.0849 0.0004 +vn -0.9966 -0.0820 -0.0004 +vn -0.9951 -0.0987 -0.0002 +vn -0.9951 -0.0987 0.0001 +vn -0.9951 -0.0989 0.0004 +vn -0.9966 -0.0820 0.0019 +vn -0.9964 -0.0850 0.0016 +vn -0.9964 -0.0850 -0.0008 +vn -0.9951 -0.0990 0.0006 +vn -0.9951 -0.0992 -0.0020 +vn -0.9963 -0.0823 -0.0252 +vn -0.9960 -0.0851 -0.0256 +vn -0.9948 -0.0977 -0.0272 +vn -0.1347 0.9893 -0.0559 +vn -0.1351 0.9906 -0.0228 +vn -0.2651 0.9640 -0.0225 +vn -0.2647 0.9628 -0.0552 +vn -0.9964 -0.0850 -0.0017 +vn -0.9964 -0.0850 -0.0012 +vn -0.9753 -0.2208 0.0065 +vn -0.9754 -0.2202 0.0084 +vn -0.5632 -0.8252 0.0428 +vn -0.5644 -0.8236 0.0563 +vn -0.1351 0.9907 0.0187 +vn -0.1345 0.9894 0.0549 +vn -0.2641 0.9630 0.0542 +vn -0.2650 0.9641 0.0185 +vn 0.1582 -0.7558 0.6354 +vn 0.3373 -0.2783 0.8993 +vn 0.1582 -0.7557 0.6355 +vn -0.0737 -0.2810 0.9569 +vn -0.0737 -0.2809 0.9569 +vn -0.1270 -0.1286 0.9835 +vn -0.9797 -0.0892 -0.1794 +vn -0.0018 -0.0435 -0.9991 +vn 0.0327 -0.4094 -0.9118 +vn -0.9147 -0.3308 -0.2322 +vn -0.0017 -0.0434 -0.9991 +vn 0.0326 -0.4094 -0.9118 +vn 0.0845 -0.8971 -0.4337 +vn 0.0846 -0.8970 -0.4338 +vn -0.5889 -0.7960 -0.1398 +vn -0.1335 0.9881 0.0769 +vn -0.1324 0.9877 0.0833 +vn -0.2629 0.9618 0.0760 +vn 0.9971 0.0764 -0.0005 +vn 0.9983 -0.0577 -0.0030 +vn 0.9971 0.0764 0.0007 +vn 0.9983 -0.0576 0.0038 +vn 0.7115 -0.7025 0.0178 +vn 0.7115 -0.7026 -0.0143 +vn -0.3543 -0.8562 -0.3761 +vn -0.4320 -0.8193 -0.3770 +vn -0.2475 -0.8722 -0.4219 +vn -0.2031 -0.3248 -0.9237 +vn -0.2466 -0.3326 -0.9102 +vn -0.2538 -0.3213 -0.9123 +vn -0.1310 0.9881 0.0808 +vn -0.1657 0.9845 0.0577 +vn -0.9753 -0.2207 0.0105 +vn -0.9751 -0.2211 0.0141 +vn -0.5633 -0.8234 0.0692 +vn -0.5620 -0.8221 0.0911 +vn 0.7224 -0.6912 0.0189 +vn 0.7292 -0.6842 -0.0113 +vn 0.1110 -0.9932 -0.0352 +vn 0.1110 -0.9936 0.0230 +vn 0.0887 -0.9422 0.3231 +vn -0.5950 -0.8027 0.0398 +vn -0.5831 -0.8123 -0.0109 +vn -0.5749 -0.8180 0.0186 +vn 0.7314 -0.6676 -0.1393 +vn 0.1106 -0.9898 -0.0898 +vn 0.7147 -0.6963 -0.0661 +vn 0.1107 -0.9903 -0.0842 +vn -0.5662 -0.8217 -0.0651 +vn -0.5746 -0.8147 -0.0783 +vn 0.7130 -0.6987 -0.0593 +vn 0.1108 -0.9909 -0.0769 +vn 0.7120 -0.7009 -0.0423 +vn 0.1109 -0.9923 -0.0548 +vn -0.5639 -0.8238 -0.0585 +vn 0.7116 -0.7025 -0.0143 +vn 0.1111 -0.9936 -0.0186 +vn 0.7116 -0.7024 0.0178 +vn 0.1111 -0.9935 0.0230 +vn -0.5615 -0.8274 -0.0142 +vn 0.7148 -0.6917 0.1033 +vn 0.7187 -0.6917 0.0709 +vn 0.1107 -0.9895 0.0925 +vn 0.1101 -0.9848 0.1344 +vn -0.5711 -0.8179 0.0701 +vn -0.5674 -0.8171 0.1023 +vn 0.7108 -0.6973 0.0924 +vn 0.7120 -0.6937 0.1089 +vn 0.1100 -0.9839 0.1412 +vn 0.1103 -0.9867 0.1195 +vn -0.5642 -0.8186 0.1077 +vn -0.5620 -0.8221 0.0912 +vn 0.7136 -0.6982 0.0572 +vn 0.7122 -0.6984 0.0705 +vn 0.1107 -0.9897 0.0911 +vn 0.1108 -0.9911 0.0740 +vn -0.5631 -0.8235 0.0692 +vn -0.5645 -0.8235 0.0563 +vn 0.7127 -0.7001 0.0434 +vn 0.1109 -0.9922 0.0562 +vn -0.9753 -0.2206 -0.0090 +vn -0.9964 -0.0850 -0.0007 +vn -0.9756 -0.2190 -0.0119 +vn -0.5638 -0.8238 -0.0585 +vn 0.9971 0.0765 0.0035 +vn 0.9967 0.0770 0.0275 +vn 0.9989 -0.0419 0.0209 +vn 0.9986 -0.0522 0.0061 +vn 0.7292 -0.6842 -0.0114 +vn 0.7223 -0.6913 0.0189 +vn 0.9971 0.0765 0.0036 +vn 0.9971 0.0765 0.0025 +vn 0.9985 -0.0535 0.0143 +vn 0.9983 -0.0548 0.0212 +vn 0.7186 -0.6918 0.0709 +vn 0.7148 -0.6916 0.1033 +vn -0.9960 -0.0853 -0.0255 +vn -0.9779 -0.2064 -0.0337 +vn -0.5745 -0.8147 -0.0783 +vn 0.9971 0.0765 0.0039 +vn 0.9982 -0.0561 0.0228 +vn 0.9982 -0.0571 0.0197 +vn 0.7121 -0.6936 0.1089 +vn 0.7109 -0.6972 0.0924 +vn -0.9960 -0.0844 0.0287 +vn -0.9784 -0.2057 0.0222 +vn -0.9964 -0.0849 0.0021 +vn -0.9763 -0.2162 0.0049 +vn -0.5750 -0.8180 0.0186 +vn -0.5833 -0.8122 -0.0110 +vn -0.9964 -0.0850 -0.0018 +vn -0.9760 -0.2175 0.0105 +vn -0.9964 -0.0850 -0.0026 +vn -0.9756 -0.2189 0.0156 +vn -0.5712 -0.8178 0.0700 +vn 0.9971 0.0765 0.0023 +vn 0.9971 0.0765 0.0028 +vn 0.9983 -0.0567 0.0150 +vn 0.9983 -0.0562 0.0121 +vn 0.7123 -0.6983 0.0705 +vn -0.9964 -0.0851 -0.0028 +vn -0.9753 -0.2202 0.0167 +vn -0.5641 -0.8186 0.1077 +vn 0.9971 0.0765 0.0017 +vn 0.9983 -0.0568 0.0092 +vn 0.9978 0.0661 0.0022 +vn 0.9978 0.0661 0.0009 +vn 0.9978 0.0660 0.0031 +vn -0.9966 -0.0818 -0.0030 +vn -0.9966 -0.0818 -0.0029 +vn 0.9978 0.0661 0.0038 +vn 0.9978 0.0661 0.0047 +vn -0.9967 -0.0818 -0.0021 +vn -0.9963 -0.0812 0.0288 +vn -0.9798 -0.0771 0.1848 +vn 0.9978 0.0660 0.0054 +vn 0.9978 0.0659 0.0050 +vn -0.9963 -0.0821 -0.0252 +vn -0.9805 -0.0835 -0.1779 +vn 0.9978 0.0657 0.0035 +vn 0.9978 0.0657 0.0038 +vn 0.9974 0.0664 0.0283 +vn 0.9723 0.0685 0.2234 +vn -0.9967 -0.0817 0.0019 +vn -0.9967 -0.0817 0.0012 +vn -0.9967 -0.0817 -0.0025 +vn -0.9967 -0.0817 -0.0020 +vn 0.9978 0.0661 -0.0007 +vn 0.9978 0.0660 -0.0021 +vn -0.0420 -0.0405 -0.9983 +vn 0.9737 0.0610 -0.2196 +vn -0.0420 -0.0406 -0.9983 +vn 0.9978 0.0660 -0.0030 +vn 0.9978 0.0659 -0.0061 +vn -0.9967 -0.0817 0.0005 +vn 0.9973 0.0657 -0.0322 +vn -0.1439 -0.0595 0.9878 +vn -0.0380 -0.0036 0.9993 +vn -0.1438 -0.0595 0.9878 +vn -0.0380 -0.0035 0.9993 +vn 0.1379 -0.7030 -0.6977 +vn 0.1379 -0.7031 -0.6976 +vn -0.0725 -0.2135 -0.9742 +vn -0.2032 -0.3248 -0.9237 +vn -0.0253 0.4714 0.8815 +vn 0.0434 0.9283 0.3692 +vn -0.9966 -0.0821 -0.0014 +vn -0.9951 -0.0987 -0.0005 +vn -0.9996 -0.0293 0.0060 +vn -0.8155 0.5765 0.0510 +vn -0.9996 -0.0295 0.0042 +vn -0.8173 0.5750 0.0362 +vn -0.8153 0.5768 0.0510 +vn -0.8171 0.5753 0.0362 +vn -0.8181 0.5749 0.0123 +vn -0.9996 -0.0295 -0.0018 +vn -0.8184 0.5744 -0.0150 +vn -0.8183 0.5747 0.0123 +vn -0.8182 0.5747 -0.0150 +vn -0.9996 -0.0284 -0.0044 +vn -0.8166 0.5761 -0.0370 +vn -0.8153 0.5770 -0.0489 +vn -0.8167 0.5758 -0.0370 +vn -0.8152 0.5771 -0.0489 +vn -0.8156 0.5755 -0.0603 +vn -0.9995 -0.0301 -0.0092 +vn -0.8161 0.5725 -0.0790 +vn -0.8157 0.5754 -0.0603 +vn -0.8159 0.5728 -0.0790 +vn -0.8136 0.5738 -0.0938 +vn -0.9995 -0.0285 -0.0103 +vn -0.8113 0.5777 -0.0897 +vn -0.8115 0.5774 -0.0896 +vn -0.9996 -0.0278 -0.0071 +vn -0.8095 0.5838 -0.0621 +vn -0.8094 0.5840 -0.0622 +vn -0.9964 -0.0853 -0.0018 +vn -0.9950 -0.0998 -0.0004 +vn -0.1269 0.9566 -0.2623 +vn -0.5804 0.7815 -0.2290 +vn -0.1797 0.5154 -0.8379 +vn -0.6746 0.3555 -0.6470 +vn -0.6745 0.3556 -0.6469 +vn 0.2042 0.4677 -0.8600 +vn 0.4700 0.8431 -0.2613 +vn 0.1417 0.5110 -0.8479 +vn 0.3818 0.8894 -0.2514 +vn 0.3809 0.3087 0.8716 +vn 0.7401 0.5786 0.3427 +vn 0.4761 0.1111 0.8723 +vn 0.9243 0.2219 0.3105 +vn 0.7400 0.5787 0.3428 +vn -0.9544 -0.2982 -0.0164 +vn -0.4918 -0.8692 -0.0523 +vn -0.9367 -0.0849 -0.3396 +vn -0.4571 -0.2359 -0.8576 +vn 0.0656 0.5378 -0.8405 +vn 0.2817 0.9281 -0.2434 +vn 0.0205 0.5496 -0.8352 +vn 0.1931 0.9522 -0.2368 +vn 0.4941 -0.8642 -0.0944 +vn 0.9607 -0.2765 -0.0254 +vn 0.4901 -0.8716 -0.0100 +vn 0.9594 -0.2819 0.0018 +vn -0.9736 -0.2260 -0.0309 +vn -0.5439 -0.8334 -0.0977 +vn -0.4949 -0.7817 -0.3796 +vn -0.2614 -0.3214 -0.9102 +vn -0.2848 -0.3117 -0.9065 +vn 0.4829 -0.8745 0.0452 +vn 0.9576 -0.2872 0.0210 +vn 0.4781 -0.8778 0.0301 +vn 0.9568 -0.2902 0.0168 +vn -0.7844 -0.5245 0.3312 +vn -0.7844 -0.5244 0.3312 +vn -0.3434 -0.2002 0.9176 +vn -0.5645 -0.7608 0.3203 +vn -0.3434 -0.2001 0.9176 +vn -0.3030 -0.3246 0.8960 +vn 0.4758 -0.8792 -0.0245 +vn 0.9566 -0.2913 -0.0021 +vn 0.4709 -0.8786 -0.0794 +vn 0.9552 -0.2953 -0.0218 +vn 0.4642 -0.0083 0.8857 +vn 0.9490 0.0261 0.3142 +vn 0.4649 -0.8784 -0.1105 +vn 0.9533 -0.3002 -0.0340 +vn 0.4601 -0.8822 -0.1002 +vn 0.9518 -0.3051 -0.0325 +vn -0.0130 0.5644 -0.8254 +vn 0.0592 0.9714 -0.2301 +vn 0.4180 -0.6989 -0.5804 +vn 0.4073 -0.2480 -0.8790 +vn 0.9291 -0.1001 -0.3559 +vn 0.9283 -0.2612 -0.2647 +vn 0.4265 -0.0662 -0.9020 +vn 0.9423 -0.0177 -0.3344 +vn 0.9066 -0.0941 0.4115 +vn -0.4949 -0.1312 0.8590 +vn -0.6869 -0.0856 0.7217 +vn 0.4568 -0.8879 -0.0548 +vn 0.9508 -0.3092 -0.0196 +vn 0.4567 -0.8896 0.0108 +vn 0.9508 -0.3097 0.0003 +vn 0.4472 0.0260 -0.8940 +vn 0.9514 0.0549 -0.3031 +vn 0.4616 -0.8824 0.0911 +vn 0.9524 -0.3039 0.0254 +vn 0.4676 -0.8697 0.1578 +vn 0.9539 -0.2965 0.0473 +vn -0.7172 -0.0026 -0.6969 +vn -0.1748 0.0868 -0.9808 +vn -0.9816 -0.0906 -0.1683 +vn -0.6745 0.3557 -0.6469 +vn -0.1797 0.5155 -0.8378 +vn -0.7099 -0.0538 0.7022 +vn -0.1769 0.0121 0.9842 +vn -0.9796 -0.1023 0.1729 +vn -0.7099 -0.0539 0.7023 +vn -0.9938 -0.1077 -0.0273 +vn -0.9939 -0.1101 -0.0029 +vn -0.9939 -0.1102 -0.0003 +vn -0.9939 -0.1100 -0.0003 +vn -0.9939 -0.1099 -0.0001 +vn -0.9940 -0.1097 0.0001 +vn -0.9940 -0.1097 0.0002 +vn -0.9940 -0.1098 0.0001 +vn -0.9939 -0.1103 0.0002 +vn -0.9939 -0.1104 0.0004 +vn -0.9939 -0.1107 0.0008 +vn -0.9938 -0.1111 0.0010 +vn -0.9938 -0.1108 0.0006 +vn -0.9938 -0.1107 0.0027 +vn -0.9936 -0.1095 0.0276 +vn 0.0446 0.4487 0.8926 +vn -0.1126 0.0338 0.9931 +vn -0.0962 0.0354 0.9947 +vn 0.0081 0.4571 0.8894 +vn -0.1086 0.0288 0.9937 +vn -0.2728 -0.3732 0.8867 +vn 0.1417 0.5109 -0.8479 +vn 0.2041 0.4676 -0.8600 +vn -0.0419 0.0673 -0.9968 +vn -0.0733 0.0898 -0.9933 +vn -0.0415 0.0471 -0.9980 +vn -0.2613 -0.3214 -0.9102 +vn -0.2539 -0.3214 -0.9123 +vn 0.4762 0.1112 0.8723 +vn 0.3810 0.3087 0.8715 +vn -0.0450 0.0301 0.9985 +vn -0.0286 0.0157 0.9995 +vn -0.0603 0.0344 0.9976 +vn -0.4466 -0.0797 0.8912 +vn 0.4181 -0.6988 -0.5804 +vn 0.4450 -0.8952 -0.0240 +vn -0.0330 -0.9991 -0.0263 +vn -0.0374 -0.7565 -0.6529 +vn 0.4675 -0.8698 0.1578 +vn -0.0308 -0.9827 0.1824 +vn -0.4872 -0.8731 -0.0204 +vn -0.4657 -0.6766 -0.5704 +vn -0.0634 0.0388 -0.9972 +vn 0.4677 0.1473 -0.8715 +vn -0.0763 0.0318 -0.9966 +vn -0.4796 -0.0748 -0.8743 +vn -0.1082 0.1025 -0.9888 +vn -0.1104 0.1031 -0.9885 +vn -0.2466 -0.3326 -0.9103 +vn 0.4900 -0.8717 -0.0100 +vn 0.4940 -0.8643 -0.0944 +vn -0.0311 -0.9930 -0.1135 +vn -0.0295 -0.9994 -0.0177 +vn 0.4920 -0.8612 -0.1271 +vn -0.0322 -0.9884 -0.1482 +vn -0.5439 -0.8297 -0.1256 +vn -0.5441 -0.8333 -0.0977 +vn -0.5369 -0.8435 -0.0180 +vn 0.4610 -0.8828 0.0898 +vn -0.0290 -0.9932 0.1130 +vn 0.4342 -0.6778 0.5934 +vn -0.0157 -0.7326 0.6804 +vn -0.5099 -0.8550 0.0951 +vn 0.1518 0.4080 0.9003 +vn -0.0758 0.0345 0.9965 +vn -0.2893 -0.3508 0.8906 +vn 0.4781 -0.8778 0.0302 +vn 0.4830 -0.8745 0.0452 +vn -0.0287 -0.9985 0.0462 +vn -0.0288 -0.9991 0.0296 +vn -0.5262 -0.8496 0.0352 +vn -0.5179 -0.8552 0.0210 +vn -0.0042 -0.3008 0.9537 +vn 0.4469 -0.1069 0.8882 +vn -0.0035 -0.1158 0.9933 +vn -0.4484 -0.0990 0.8884 +vn -0.4637 -0.6532 0.5986 +vn 0.4706 -0.8788 -0.0794 +vn -0.0291 -0.9990 -0.0328 +vn -0.0295 -0.9951 -0.0945 +vn -0.5131 -0.8578 -0.0318 +vn -0.5063 -0.8582 -0.0842 +vn 0.4645 -0.0083 0.8856 +vn -0.0127 -0.0276 0.9995 +vn 0.4600 -0.8822 -0.1002 +vn 0.4650 -0.8784 -0.1105 +vn -0.0295 -0.9913 -0.1280 +vn -0.0295 -0.9931 -0.1139 +vn -0.4996 -0.8589 -0.1127 +vn -0.0129 0.5644 -0.8254 +vn -0.0669 0.1015 -0.9926 +vn 0.4265 -0.0662 -0.9021 +vn 0.4074 -0.2480 -0.8789 +vn -0.0402 -0.2654 -0.9633 +vn -0.0523 -0.0779 -0.9956 +vn -0.0373 -0.7565 -0.6529 +vn -0.4846 -0.0711 -0.8718 +vn -0.0253 0.4712 0.8817 +vn -0.0719 0.0253 0.9971 +vn 0.4566 -0.8880 -0.0548 +vn -0.0297 -0.9977 -0.0606 +vn -0.0302 -0.9994 0.0145 +vn -0.4917 -0.8692 -0.0523 +vn -0.4926 -0.8701 0.0146 +vn 0.4470 0.0260 -0.8941 +vn -0.0672 -0.0017 -0.9977 +vn -0.5076 -0.0245 -0.8613 +vn -0.0307 -0.9939 0.1059 +vn -0.4988 -0.8615 0.0948 +vn 0.4450 -0.8952 -0.0241 +vn 0.9456 -0.3252 -0.0128 +vn 0.7858 0.2355 0.5719 +vn 0.9782 -0.0199 0.2066 +vn 0.8646 0.4960 0.0798 +vn 0.7371 0.5740 0.3567 +vn 0.8598 0.5084 -0.0472 +vn 0.8646 0.4961 0.0798 +vn 0.8599 0.5083 -0.0472 +vn 0.5843 0.8087 -0.0677 +vn 0.5866 0.8077 -0.0594 +vn 0.7371 0.5740 0.3566 +vn 0.5727 0.8197 -0.0103 +vn -0.4078 0.6316 -0.6594 +vn -0.7088 0.6506 -0.2728 +vn -0.2288 0.9509 -0.2084 +vn -0.1022 0.8660 -0.4895 +vn -0.7604 0.6474 -0.0520 +vn -0.2080 0.9754 -0.0729 +vn 0.2126 0.9745 -0.0712 +vn 0.2087 0.9739 -0.0894 +vn 0.2226 0.9641 -0.1447 +vn 0.8613 0.4772 -0.1746 +vn 0.7132 0.5202 -0.4698 +vn 0.8612 0.4773 -0.1746 +vn 0.5711 0.8108 -0.1280 +vn 0.5875 0.8057 -0.0757 +vn 0.1655 0.7926 -0.5868 +vn 0.3307 0.7555 -0.5655 +vn -0.1022 0.8661 -0.4893 +vn 0.1655 0.7925 -0.5870 +vn 0.3031 0.9412 -0.1490 +vn 0.3307 0.7556 -0.5655 +vn 0.4068 0.9030 -0.1383 +vn -0.6075 0.7869 0.1082 +vn -0.6077 0.7868 0.1082 +vn -0.4030 0.7251 0.5584 +vn -0.7100 0.6837 0.1689 +vn 0.5141 0.7516 0.4133 +vn 0.7622 0.5769 0.2937 +vn 0.7857 0.2356 0.5719 +vn 0.4261 0.5041 0.7512 +vn 0.9646 0.2318 0.1261 +vn 0.4876 0.6917 -0.5327 +vn 0.4876 0.6917 -0.5326 +vn 0.3734 0.3976 -0.8381 +vn 0.7421 0.5425 -0.3938 +vn 0.7529 0.1608 -0.6382 +vn 0.4107 0.9090 -0.0715 +vn 0.3105 0.9479 -0.0714 +vn 0.3082 0.9489 -0.0673 +vn 0.4080 0.9103 -0.0696 +vn 0.2044 0.9774 -0.0541 +vn 0.2162 0.9763 0.0003 +vn 0.2976 0.9547 0.0044 +vn 0.4040 0.9147 -0.0056 +vn 0.3127 0.9468 -0.0754 +vn 0.4114 0.9085 -0.0733 +vn 0.5025 0.8535 -0.1379 +vn 0.5034 0.8613 -0.0687 +vn 0.5040 0.8609 -0.0701 +vn 0.5012 0.8624 -0.0716 +vn 0.5037 0.8639 -0.0031 +vn 0.5028 0.7359 0.4535 +vn 0.3487 0.8285 0.4382 +vn 0.5028 0.7359 0.4536 +vn 0.4709 0.6676 -0.5767 +vn 0.4708 0.6676 -0.5767 +vn -0.7097 0.6840 0.1689 +vn -0.2309 0.9709 0.0634 +vn -0.4030 0.7250 0.5585 +vn -0.1016 0.9291 0.3555 +vn 0.1731 0.8712 0.4594 +vn -0.1016 0.9292 0.3555 +vn 0.1731 0.8712 0.4593 +usemtl Scene_-_Root +s off +f 44120/44096/32984 44123/44097/32985 44121/44098/32986 +f 44126/44099/32987 44128/44100/32988 44129/44101/32989 +f 44134/44102/32990 44139/44103/32991 44135/44104/32992 +f 44138/44105/32993 44141/44106/32994 44139/44103/32995 +f 44140/44107/32996 44145/44108/32997 44141/44106/32998 +f 44144/44109/32999 44147/44110/33000 44145/44108/33001 +f 44146/44111/33002 44151/44112/33003 44147/44110/33000 +f 44150/44113/33004 44108/44114/33005 44151/44112/33006 +f 44798/44115/33007 44795/44116/33007 44998/44117/33007 +f 44798/44115/33007 44998/44117/33007 44999/44118/33007 +f 44795/44116/33007 44794/44119/33007 45000/44120/33007 +f 44795/44116/33007 45000/44120/33007 44998/44117/33007 +f 45003/44121/33008 44798/44115/33009 44999/44118/33009 +f 44821/44122/33010 44831/44123/33011 45017/44124/33012 +f 44821/44122/33010 45017/44124/33012 45018/44125/33013 +f 44831/44123/33014 45011/44126/33015 45017/44124/33014 +f 44794/44119/33009 44804/44127/33016 45019/44128/33009 +f 44794/44119/33009 45019/44128/33009 45000/44120/33009 +f 44804/44127/33017 45020/44129/33017 45019/44128/33017 +f 44803/44130/33008 45027/44131/33018 45028/44132/33019 +f 44803/44130/33020 45028/44132/33020 45020/44129/33020 +f 45027/44131/33021 44825/44133/33022 45029/44134/33023 +f 45027/44131/33024 45029/44134/33025 45028/44132/33024 +f 44825/44133/33026 45032/44135/33027 45029/44134/33028 +f 44822/44136/33029 44821/44122/33010 45018/44125/33030 +f 45051/44137/33031 45049/44138/33032 45176/44139/33033 +f 45051/44137/33031 45176/44139/33034 45177/44140/33034 +f 45049/44138/33032 45175/44141/33035 45176/44139/33033 +f 45057/44142/33036 45055/44143/33037 45178/44144/33038 +f 45057/44142/33039 45178/44144/33040 45179/44145/33040 +f 45055/44143/33041 45051/44137/33031 45177/44140/33042 +f 45055/44143/33037 45177/44140/33043 45178/44144/33043 +f 45063/44146/33044 45061/44147/33045 45180/44148/33046 +f 45063/44146/33047 45180/44148/33048 45181/44149/33048 +f 45061/44147/33049 45057/44142/33050 45179/44145/33051 +f 45061/44147/33052 45179/44145/33053 45180/44148/33053 +f 45069/44150/33054 45067/44151/33055 45182/44152/33056 +f 45069/44150/33057 45182/44152/33058 45183/44153/33056 +f 45067/44151/33059 45063/44146/33060 45181/44149/33061 +f 45067/44151/33062 45181/44149/33063 45182/44152/33063 +f 45075/44154/33064 45073/44155/33065 45184/44156/33066 +f 45075/44154/33067 45184/44156/33068 45185/44157/33068 +f 45073/44155/33069 45069/44150/33070 45183/44153/33071 +f 45073/44155/33069 45183/44153/33072 45184/44156/33072 +f 44729/44158/33073 45079/44159/33074 45186/44160/33075 +f 45079/44159/33076 45075/44154/33077 45185/44157/33078 +f 45079/44159/33074 45185/44157/33079 45186/44160/33080 +s 1 +f 44096/44161/33081 44097/44162/33082 44098/44163/33083 +f 44096/44161/33081 44098/44163/33083 44099/44164/33084 +f 44097/44162/33082 44100/44165/33085 44101/44166/33086 +f 44097/44162/33082 44101/44166/33086 44098/44163/33083 +f 44098/44163/33083 44101/44166/33086 44102/44167/33087 +f 44098/44163/33083 44102/44167/33087 44103/44168/33088 +f 44099/44164/33084 44098/44163/33083 44103/44168/33088 +f 44099/44164/33084 44103/44168/33088 44104/44169/33089 +f 44105/44170/33090 44106/44171/33091 44107/44172/33092 +f 44105/44170/33090 44107/44172/33092 44108/44114/33093 +f 44106/44171/33091 44109/44173/33094 44110/44174/33095 +f 44106/44171/33091 44110/44174/33095 44107/44172/33092 +f 44107/44172/33092 44110/44174/33095 44100/44165/33085 +f 44107/44172/33092 44100/44165/33085 44097/44162/33082 +f 44108/44114/33093 44107/44172/33092 44097/44162/33082 +f 44108/44114/33093 44097/44162/33082 44096/44161/33081 +f 44111/44175/33096 44112/44176/33097 44113/44177/33098 +f 44111/44175/33096 44113/44177/33098 44114/44178/33099 +f 44112/44176/33097 44115/44179/33100 44116/44180/33101 +f 44112/44176/33097 44116/44180/33101 44113/44177/33098 +f 44113/44177/33098 44116/44180/33101 44117/44181/33102 +f 44113/44177/33098 44117/44181/33102 44118/44182/33103 +f 44114/44178/33099 44113/44177/33098 44118/44182/33103 +f 44114/44178/33099 44118/44182/33103 44119/44183/33104 +f 44115/44179/33100 44120/44096/32984 44121/44098/33105 +f 44115/44179/33100 44121/44098/33105 44116/44180/33101 +f 44120/44096/32984 44122/44184/33106 44123/44097/33107 +f 44121/44098/33105 44123/44097/33107 44124/44185/33108 +f 44121/44098/33105 44124/44185/33108 44125/44186/33109 +f 44116/44180/33101 44121/44098/33105 44125/44186/33109 +f 44116/44180/33101 44125/44186/33109 44117/44181/33102 +f 44122/44184/33106 44126/44099/32987 44127/44187/33110 +f 44122/44184/33106 44127/44187/33110 44123/44097/33107 +f 44126/44099/32987 44129/44101/33111 44127/44187/33110 +f 44127/44187/33110 44129/44101/33111 44130/44188/33112 +f 44127/44187/33110 44130/44188/33112 44131/44189/33113 +f 44123/44097/33107 44127/44187/33110 44131/44189/33113 +f 44123/44097/33107 44131/44189/33113 44124/44185/33108 +f 44128/44100/33114 44132/44190/33115 44133/44191/33116 +f 44128/44100/33114 44133/44191/33116 44129/44101/33111 +f 44132/44190/33115 44134/44102/32990 44135/44104/32992 +f 44132/44190/33115 44135/44104/32992 44133/44191/33116 +f 44133/44191/33116 44135/44104/32992 44136/44192/33117 +f 44133/44191/33116 44136/44192/33117 44137/44193/33118 +f 44129/44101/33111 44133/44191/33116 44137/44193/33118 +f 44129/44101/33111 44137/44193/33118 44130/44188/33112 +f 44134/44102/32990 44138/44105/33119 44139/44103/33120 +f 44138/44105/33119 44140/44107/33121 44141/44106/32994 +f 44139/44103/33120 44141/44106/32994 44142/44194/33122 +f 44139/44103/33120 44142/44194/33122 44143/44195/33123 +f 44135/44104/32992 44139/44103/33120 44143/44195/33123 +f 44135/44104/32992 44143/44195/33123 44136/44192/33117 +f 44140/44107/33121 44144/44109/33124 44145/44108/32997 +f 44144/44109/33124 44146/44111/33002 44147/44110/33000 +f 44145/44108/33125 44147/44110/33000 44148/44196/33126 +f 44145/44108/33125 44148/44196/33126 44149/44197/33127 +f 44141/44106/32994 44145/44108/33125 44149/44197/33127 +f 44141/44106/32994 44149/44197/33127 44142/44194/33122 +f 44146/44111/33002 44150/44113/33128 44151/44112/33003 +f 44150/44113/33128 44105/44170/33090 44108/44114/33093 +f 44151/44112/33129 44108/44114/33093 44096/44161/33081 +f 44151/44112/33129 44096/44161/33081 44152/44198/33130 +f 44147/44110/33000 44151/44112/33129 44152/44198/33130 +f 44147/44110/33000 44152/44198/33130 44148/44196/33126 +f 44119/44183/33104 44118/44182/33103 44153/44199/33131 +f 44119/44183/33104 44153/44199/33131 44154/44200/33132 +f 44118/44182/33103 44117/44181/33102 44155/44201/33133 +f 44118/44182/33103 44155/44201/33133 44153/44199/33131 +f 44153/44199/33131 44155/44201/33133 44156/44202/33134 +f 44153/44199/33131 44156/44202/33134 44157/44203/33135 +f 44154/44200/33132 44153/44199/33131 44157/44203/33135 +f 44154/44200/33132 44157/44203/33135 44158/44204/33136 +f 44117/44181/33102 44125/44186/33109 44159/44205/33137 +f 44117/44181/33102 44159/44205/33137 44155/44201/33133 +f 44125/44186/33109 44124/44185/33108 44160/44206/33138 +f 44125/44186/33109 44160/44206/33138 44159/44205/33137 +f 44159/44205/33137 44160/44206/33138 44161/44207/33139 +f 44159/44205/33137 44161/44207/33139 44162/44208/33140 +f 44155/44201/33133 44159/44205/33137 44162/44208/33140 +f 44155/44201/33133 44162/44208/33140 44156/44202/33134 +f 44124/44185/33108 44131/44189/33113 44163/44209/33141 +f 44124/44185/33108 44163/44209/33141 44160/44206/33138 +f 44131/44189/33113 44130/44188/33112 44164/44210/33142 +f 44131/44189/33113 44164/44210/33142 44163/44209/33141 +f 44163/44209/33141 44164/44210/33142 44165/44211/33143 +f 44163/44209/33141 44165/44211/33143 44166/44212/33144 +f 44160/44206/33138 44163/44209/33141 44166/44212/33144 +f 44160/44206/33138 44166/44212/33144 44161/44207/33139 +f 44130/44188/33112 44137/44193/33118 44167/44213/33145 +f 44130/44188/33112 44167/44213/33145 44164/44210/33142 +f 44137/44193/33118 44136/44192/33117 44168/44214/33146 +f 44137/44193/33118 44168/44214/33146 44167/44213/33145 +f 44167/44213/33145 44168/44214/33146 44169/44215/33147 +f 44167/44213/33145 44169/44215/33147 44170/44216/33148 +f 44164/44210/33142 44167/44213/33145 44170/44216/33148 +f 44164/44210/33142 44170/44216/33148 44165/44211/33143 +f 44136/44192/33117 44143/44195/33123 44171/44217/33149 +f 44136/44192/33117 44171/44217/33149 44168/44214/33146 +f 44143/44195/33123 44142/44194/33122 44172/44218/33150 +f 44143/44195/33123 44172/44218/33150 44171/44217/33149 +f 44171/44217/33149 44172/44218/33150 44173/44219/33151 +f 44171/44217/33149 44173/44219/33151 44174/44220/33152 +f 44168/44214/33146 44171/44217/33149 44174/44220/33152 +f 44168/44214/33146 44174/44220/33152 44169/44215/33147 +f 44142/44194/33122 44149/44197/33127 44175/44221/33153 +f 44142/44194/33122 44175/44221/33153 44172/44218/33150 +f 44149/44197/33127 44148/44196/33126 44176/44222/33154 +f 44149/44197/33127 44176/44222/33154 44175/44221/33153 +f 44175/44221/33153 44176/44222/33154 44177/44223/33155 +f 44175/44221/33153 44177/44223/33155 44178/44224/33156 +f 44172/44218/33150 44175/44221/33153 44178/44224/33156 +f 44172/44218/33150 44178/44224/33156 44173/44219/33151 +f 44148/44196/33126 44152/44198/33130 44179/44225/33157 +f 44148/44196/33126 44179/44225/33157 44176/44222/33154 +f 44152/44198/33130 44096/44161/33081 44099/44164/33084 +f 44152/44198/33130 44099/44164/33084 44179/44225/33157 +f 44179/44225/33157 44099/44164/33084 44104/44169/33089 +f 44179/44225/33157 44104/44169/33089 44180/44226/33158 +f 44176/44222/33154 44179/44225/33157 44180/44226/33158 +f 44176/44222/33154 44180/44226/33158 44177/44223/33155 +f 44181/44227/33159 44182/44228/33160 44183/44229/33161 +f 44181/44227/33159 44183/44229/33161 44184/44230/33162 +f 44182/44228/33160 44185/44231/33163 44186/44232/33164 +f 44182/44228/33160 44186/44232/33164 44183/44229/33161 +f 44183/44229/33161 44186/44232/33164 44187/44233/33165 +f 44183/44229/33161 44187/44233/33165 44188/44234/33166 +f 44184/44230/33162 44183/44229/33161 44188/44234/33166 +f 44184/44230/33162 44188/44234/33166 44189/44235/33167 +f 44190/44236/33168 44191/44237/33169 44192/44238/33170 +f 44190/44236/33168 44192/44238/33170 44193/44239/33171 +f 44191/44237/33169 44181/44227/33159 44184/44230/33162 +f 44191/44237/33169 44184/44230/33162 44192/44238/33170 +f 44192/44238/33170 44184/44230/33162 44189/44235/33167 +f 44192/44238/33170 44189/44235/33167 44194/44240/33172 +f 44193/44239/33171 44192/44238/33170 44194/44240/33172 +f 44193/44239/33171 44194/44240/33172 44195/44241/33173 +f 44196/44242/33174 44197/44243/33175 44198/44244/33176 +f 44196/44242/33174 44198/44244/33176 44199/44245/33177 +f 44197/44243/33175 44190/44236/33168 44193/44239/33171 +f 44197/44243/33175 44193/44239/33171 44198/44244/33176 +f 44198/44244/33176 44193/44239/33171 44195/44241/33173 +f 44198/44244/33176 44195/44241/33173 44200/44246/33178 +f 44199/44245/33177 44198/44244/33176 44200/44246/33178 +f 44199/44245/33177 44200/44246/33178 44201/44247/33179 +f 44202/44248/33180 44203/44249/33181 44204/44250/33182 +f 44202/44248/33180 44204/44250/33182 44205/44251/33183 +f 44203/44249/33181 44196/44242/33174 44199/44245/33177 +f 44203/44249/33181 44199/44245/33177 44204/44250/33182 +f 44204/44250/33182 44199/44245/33177 44201/44247/33179 +f 44204/44250/33182 44201/44247/33179 44206/44252/33184 +f 44205/44251/33183 44204/44250/33182 44206/44252/33184 +f 44205/44251/33183 44206/44252/33184 44207/44253/33185 +f 44208/44254/33186 44209/44255/33187 44210/44256/33188 +f 44208/44254/33186 44210/44256/33188 44211/44257/33189 +f 44209/44255/33187 44202/44248/33180 44205/44251/33183 +f 44209/44255/33187 44205/44251/33183 44210/44256/33188 +f 44210/44256/33188 44205/44251/33183 44207/44253/33185 +f 44210/44256/33188 44207/44253/33185 44212/44258/33190 +f 44211/44257/33189 44210/44256/33188 44212/44258/33190 +f 44211/44257/33189 44212/44258/33190 44213/44259/33191 +f 44214/44260/33192 44215/44261/33193 44216/44262/33194 +f 44214/44260/33192 44216/44262/33194 44217/44263/33195 +f 44215/44261/33193 44208/44254/33186 44211/44257/33189 +f 44215/44261/33193 44211/44257/33189 44216/44262/33194 +f 44216/44262/33194 44211/44257/33189 44213/44259/33191 +f 44216/44262/33194 44213/44259/33191 44218/44264/33196 +f 44217/44263/33195 44216/44262/33194 44218/44264/33196 +f 44217/44263/33195 44218/44264/33196 44219/44265/33197 +f 44220/44266/33198 44221/44267/33199 44222/44268/33200 +f 44220/44266/33198 44222/44268/33200 44223/44269/33201 +f 44221/44267/33199 44214/44260/33192 44217/44263/33195 +f 44221/44267/33199 44217/44263/33195 44222/44268/33200 +f 44222/44268/33200 44217/44263/33195 44219/44265/33197 +f 44222/44268/33200 44219/44265/33197 44224/44270/33202 +f 44223/44269/33201 44222/44268/33200 44224/44270/33202 +f 44223/44269/33201 44224/44270/33202 44225/44271/33203 +f 44185/44231/33163 44226/44272/33204 44227/44273/33205 +f 44185/44231/33163 44227/44273/33205 44186/44232/33164 +f 44226/44272/33204 44228/44274/33206 44229/44275/33207 +f 44226/44272/33204 44229/44275/33207 44227/44273/33205 +f 44227/44273/33205 44229/44275/33207 44230/44276/33208 +f 44227/44273/33205 44230/44276/33208 44231/44277/33209 +f 44186/44232/33164 44227/44273/33205 44231/44277/33209 +f 44186/44232/33164 44231/44277/33209 44187/44233/33165 +f 44104/44169/33089 44103/44168/33088 44232/44278/33210 +f 44104/44169/33089 44232/44278/33210 44233/44279/33211 +f 44103/44168/33088 44102/44167/33087 44234/44280/33212 +f 44103/44168/33088 44234/44280/33212 44232/44278/33210 +f 44235/44281/33210 44236/44282/33212 44237/44283/33213 +f 44235/44281/33210 44237/44283/33213 44238/44284/33214 +f 44239/44285/33211 44235/44281/33210 44238/44284/33214 +f 44239/44285/33211 44238/44284/33214 44240/44286/33215 +f 44158/44204/33136 44157/44203/33135 44241/44287/33216 +f 44158/44204/33136 44241/44287/33216 44242/44288/33217 +f 44157/44203/33135 44156/44202/33134 44243/44289/33218 +f 44157/44203/33135 44243/44289/33218 44241/44287/33216 +f 44244/44290/33216 44245/44291/33218 44246/44292/33219 +f 44244/44290/33216 44246/44292/33219 44247/44293/33220 +f 44248/44294/33221 44244/44290/33216 44247/44293/33220 +f 44248/44294/33221 44247/44293/33220 44249/44295/33222 +f 44156/44202/33134 44162/44208/33140 44250/44296/33223 +f 44156/44202/33134 44250/44296/33223 44243/44289/33218 +f 44162/44208/33140 44161/44207/33139 44251/44297/33224 +f 44162/44208/33140 44251/44297/33224 44250/44296/33223 +f 44252/44298/33223 44253/44299/33224 44254/44300/33225 +f 44252/44298/33223 44254/44300/33225 44255/44301/33226 +f 44245/44291/33218 44252/44298/33223 44255/44301/33226 +f 44245/44291/33218 44255/44301/33226 44246/44292/33219 +f 44161/44207/33139 44166/44212/33144 44256/44302/33227 +f 44161/44207/33139 44256/44302/33227 44251/44297/33224 +f 44166/44212/33144 44165/44211/33143 44257/44303/33228 +f 44166/44212/33144 44257/44303/33228 44256/44302/33227 +f 44258/44304/33227 44259/44305/33229 44260/44306/33230 +f 44258/44304/33227 44260/44306/33230 44261/44307/33231 +f 44253/44299/33224 44258/44304/33227 44261/44307/33231 +f 44253/44299/33224 44261/44307/33231 44254/44300/33225 +f 44165/44211/33143 44170/44216/33148 44262/44308/33232 +f 44165/44211/33143 44262/44308/33232 44257/44303/33228 +f 44170/44216/33148 44169/44215/33147 44263/44309/33233 +f 44170/44216/33148 44263/44309/33233 44262/44308/33232 +f 44264/44310/33234 44265/44311/33235 44266/44312/33236 +f 44264/44310/33234 44266/44312/33236 44267/44313/33237 +f 44259/44305/33229 44264/44310/33234 44267/44313/33237 +f 44259/44305/33229 44267/44313/33237 44260/44306/33230 +f 44169/44215/33147 44174/44220/33152 44268/44314/33238 +f 44169/44215/33147 44268/44314/33238 44263/44309/33233 +f 44174/44220/33152 44173/44219/33151 44269/44315/33239 +f 44174/44220/33152 44269/44315/33239 44268/44314/33238 +f 44270/44316/33238 44271/44317/33240 44272/44318/33241 +f 44270/44316/33238 44272/44318/33241 44273/44319/33242 +f 44265/44311/33235 44270/44316/33238 44273/44319/33242 +f 44265/44311/33235 44273/44319/33242 44266/44312/33236 +f 44173/44219/33151 44178/44224/33156 44274/44320/33243 +f 44173/44219/33151 44274/44320/33243 44269/44315/33239 +f 44178/44224/33156 44177/44223/33155 44275/44321/33244 +f 44178/44224/33156 44275/44321/33244 44274/44320/33243 +f 44276/44322/33243 44277/44323/33244 44278/44324/33245 +f 44276/44322/33243 44278/44324/33245 44279/44325/33246 +f 44271/44317/33240 44276/44322/33243 44279/44325/33246 +f 44271/44317/33240 44279/44325/33246 44272/44318/33241 +f 44177/44223/33155 44180/44226/33158 44280/44326/33247 +f 44177/44223/33155 44280/44326/33247 44275/44321/33244 +f 44180/44226/33158 44104/44169/33089 44233/44279/33211 +f 44180/44226/33158 44233/44279/33211 44280/44326/33247 +f 44281/44327/33248 44239/44285/33211 44240/44286/33215 +f 44281/44327/33248 44240/44286/33215 44282/44328/33249 +f 44277/44323/33244 44281/44327/33248 44282/44328/33249 +f 44277/44323/33244 44282/44328/33249 44278/44324/33245 +f 44230/44276/33208 44283/44329/33250 44284/44330/33251 +f 44230/44276/33208 44284/44330/33251 44231/44277/33209 +f 44285/44331/33250 44286/44332/33252 44287/44333/33253 +f 44285/44331/33250 44287/44333/33253 44288/44334/33254 +f 44288/44334/33254 44287/44333/33253 44289/44335/33255 +f 44288/44334/33254 44289/44335/33255 44290/44336/33256 +f 44231/44277/33209 44284/44330/33251 44291/44337/33256 +f 44231/44277/33209 44291/44337/33256 44187/44233/33165 +f 44213/44259/33191 44292/44338/33257 44293/44339/33258 +f 44213/44259/33191 44293/44339/33258 44218/44264/33196 +f 44294/44340/33259 44295/44341/33260 44296/44342/33261 +f 44294/44340/33259 44296/44342/33261 44297/44343/33262 +f 44297/44343/33262 44296/44342/33261 44298/44344/33263 +f 44297/44343/33262 44298/44344/33263 44299/44345/33264 +f 44218/44264/33196 44293/44339/33258 44300/44346/33265 +f 44218/44264/33196 44300/44346/33265 44219/44265/33197 +f 44201/44247/33179 44301/44347/33266 44302/44348/33267 +f 44201/44247/33179 44302/44348/33267 44206/44252/33184 +f 44303/44349/33266 44304/44350/33268 44305/44351/33269 +f 44303/44349/33266 44305/44351/33269 44306/44352/33270 +f 44306/44352/33270 44305/44351/33269 44307/44353/33271 +f 44306/44352/33270 44307/44353/33271 44308/44354/33272 +f 44206/44252/33184 44302/44348/33267 44309/44355/33273 +f 44206/44252/33184 44309/44355/33273 44207/44253/33185 +f 44189/44235/33167 44310/44356/33274 44311/44357/33275 +f 44189/44235/33167 44311/44357/33275 44194/44240/33172 +f 44312/44358/33276 44313/44359/33277 44314/44360/33278 +f 44312/44358/33276 44314/44360/33278 44315/44361/33279 +f 44315/44361/33279 44314/44360/33278 44316/44362/33280 +f 44315/44361/33279 44316/44362/33280 44317/44363/33281 +f 44194/44240/33172 44311/44357/33275 44318/44364/33282 +f 44194/44240/33172 44318/44364/33282 44195/44241/33173 +f 44219/44265/33197 44300/44346/33265 44319/44365/33283 +f 44219/44265/33197 44319/44365/33283 44224/44270/33202 +f 44299/44345/33264 44298/44344/33263 44320/44366/33284 +f 44299/44345/33264 44320/44366/33284 44321/44367/33283 +f 44321/44367/33283 44320/44366/33284 44322/44368/33285 +f 44321/44367/33283 44322/44368/33285 44323/44369/33286 +f 44224/44270/33202 44319/44365/33283 44324/44370/33287 +f 44224/44270/33202 44324/44370/33287 44225/44271/33203 +f 44207/44253/33185 44309/44355/33273 44325/44371/33288 +f 44207/44253/33185 44325/44371/33288 44212/44258/33190 +f 44308/44354/33272 44307/44353/33271 44326/44372/33289 +f 44308/44354/33272 44326/44372/33289 44327/44373/33290 +f 44327/44373/33290 44326/44372/33289 44295/44341/33260 +f 44327/44373/33290 44295/44341/33260 44294/44340/33259 +f 44212/44258/33190 44325/44371/33288 44292/44338/33257 +f 44212/44258/33190 44292/44338/33257 44213/44259/33191 +f 44195/44241/33173 44318/44364/33282 44328/44374/33291 +f 44195/44241/33173 44328/44374/33291 44200/44246/33178 +f 44317/44363/33281 44316/44362/33280 44329/44375/33292 +f 44317/44363/33281 44329/44375/33292 44330/44376/33291 +f 44330/44376/33291 44329/44375/33292 44304/44350/33268 +f 44330/44376/33291 44304/44350/33268 44303/44349/33266 +f 44200/44246/33178 44328/44374/33291 44301/44347/33266 +f 44200/44246/33178 44301/44347/33266 44201/44247/33179 +f 44187/44233/33165 44291/44337/33256 44331/44377/33293 +f 44187/44233/33165 44331/44377/33293 44188/44234/33166 +f 44290/44336/33256 44289/44335/33255 44332/44378/33294 +f 44290/44336/33256 44332/44378/33294 44333/44379/33295 +f 44333/44379/33295 44332/44378/33294 44313/44359/33277 +f 44333/44379/33295 44313/44359/33277 44312/44358/33276 +f 44188/44234/33166 44331/44377/33293 44310/44356/33274 +f 44188/44234/33166 44310/44356/33274 44189/44235/33167 +f 44334/44380/33296 44335/44381/33297 44336/44382/33298 +f 44334/44380/33296 44336/44382/33298 44337/44383/33299 +f 44335/44381/33297 44338/44384/33300 44339/44385/33301 +f 44335/44381/33297 44339/44385/33301 44336/44382/33298 +f 44336/44382/33298 44339/44385/33301 44340/44386/33302 +f 44336/44382/33298 44340/44386/33302 44341/44387/33303 +f 44337/44383/33299 44336/44382/33298 44341/44387/33303 +f 44337/44383/33299 44341/44387/33303 44342/44388/33304 +f 44343/44389/33305 44344/44390/33306 44345/44391/33307 +f 44343/44389/33305 44345/44391/33307 44346/44392/33308 +f 44344/44390/33306 44334/44380/33296 44337/44383/33299 +f 44344/44390/33306 44337/44383/33299 44345/44391/33307 +f 44345/44391/33307 44337/44383/33299 44342/44388/33304 +f 44345/44391/33307 44342/44388/33304 44347/44393/33309 +f 44346/44392/33308 44345/44391/33307 44347/44393/33309 +f 44346/44392/33308 44347/44393/33309 44348/44394/33310 +f 44349/44395/33311 44350/44396/33312 44351/44397/33313 +f 44349/44395/33311 44351/44397/33313 44352/44398/33314 +f 44350/44396/33312 44353/44399/33315 44354/44400/33316 +f 44350/44396/33312 44354/44400/33316 44351/44397/33313 +f 44351/44397/33313 44354/44400/33316 44355/44401/33317 +f 44351/44397/33313 44355/44401/33317 44356/44402/33318 +f 44352/44398/33314 44351/44397/33313 44356/44402/33318 +f 44352/44398/33314 44356/44402/33318 44357/44403/33319 +f 44357/44403/33319 44356/44402/33318 44358/44404/33320 +f 44357/44403/33319 44358/44404/33320 44359/44405/33321 +f 44356/44402/33318 44355/44401/33317 44360/44406/33322 +f 44356/44402/33318 44360/44406/33322 44358/44404/33320 +f 44358/44404/33320 44360/44406/33322 44361/44407/33323 +f 44358/44404/33320 44361/44407/33323 44362/44408/33324 +f 44359/44405/33321 44358/44404/33320 44362/44408/33324 +f 44359/44405/33321 44362/44408/33324 44363/44409/33325 +f 44363/44409/33325 44362/44408/33324 44364/44410/33326 +f 44363/44409/33325 44364/44410/33326 44365/44411/33327 +f 44362/44408/33324 44361/44407/33323 44366/44412/33328 +f 44362/44408/33324 44366/44412/33328 44364/44410/33326 +f 44364/44410/33326 44366/44412/33328 44367/44413/33329 +f 44364/44410/33326 44367/44413/33329 44368/44414/33330 +f 44365/44411/33327 44364/44410/33326 44368/44414/33330 +f 44365/44411/33327 44368/44414/33330 44369/44415/33331 +f 44369/44415/33331 44368/44414/33330 44370/44416/33332 +f 44369/44415/33331 44370/44416/33332 44371/44417/33333 +f 44368/44414/33330 44367/44413/33329 44372/44418/33334 +f 44368/44414/33330 44372/44418/33334 44370/44416/33332 +f 44370/44416/33332 44372/44418/33334 44373/44419/33335 +f 44370/44416/33332 44373/44419/33335 44374/44420/33336 +f 44371/44417/33333 44370/44416/33332 44374/44420/33336 +f 44371/44417/33333 44374/44420/33336 44375/44421/33337 +f 44375/44421/33337 44374/44420/33336 44376/44422/33338 +f 44375/44421/33337 44376/44422/33338 44377/44423/33339 +f 44374/44420/33336 44373/44419/33335 44378/44424/33340 +f 44374/44420/33336 44378/44424/33340 44376/44422/33338 +f 44376/44422/33338 44378/44424/33340 44379/44425/33341 +f 44376/44422/33338 44379/44425/33341 44380/44426/33342 +f 44377/44423/33339 44376/44422/33338 44380/44426/33342 +f 44377/44423/33339 44380/44426/33342 44381/44427/33343 +f 44381/44427/33343 44380/44426/33342 44382/44428/33344 +f 44381/44427/33343 44382/44428/33344 44383/44429/33345 +f 44380/44426/33342 44379/44425/33341 44384/44430/33346 +f 44380/44426/33342 44384/44430/33346 44382/44428/33344 +f 44382/44428/33344 44384/44430/33346 44385/44431/33347 +f 44382/44428/33344 44385/44431/33347 44386/44432/33348 +f 44383/44429/33345 44382/44428/33344 44386/44432/33348 +f 44383/44429/33345 44386/44432/33348 44387/44433/33349 +f 44387/44433/33349 44386/44432/33348 44388/44434/33350 +f 44387/44433/33349 44388/44434/33350 44389/44435/33351 +f 44386/44432/33348 44385/44431/33347 44390/44436/33352 +f 44386/44432/33348 44390/44436/33352 44388/44434/33350 +f 44388/44434/33350 44390/44436/33352 44334/44380/33296 +f 44388/44434/33350 44334/44380/33296 44344/44390/33306 +f 44389/44435/33351 44388/44434/33350 44344/44390/33306 +f 44389/44435/33351 44344/44390/33306 44343/44389/33305 +f 44353/44399/33315 44391/44437/33353 44392/44438/33354 +f 44353/44399/33315 44392/44438/33354 44354/44400/33316 +f 44391/44437/33353 44393/44439/33355 44394/44440/33356 +f 44391/44437/33353 44394/44440/33356 44392/44438/33354 +f 44392/44438/33354 44394/44440/33356 44395/44441/33357 +f 44392/44438/33354 44395/44441/33357 44396/44442/33358 +f 44354/44400/33316 44392/44438/33354 44396/44442/33358 +f 44354/44400/33316 44396/44442/33358 44355/44401/33317 +f 44355/44401/33317 44396/44442/33358 44397/44443/33359 +f 44355/44401/33317 44397/44443/33359 44360/44406/33322 +f 44396/44442/33358 44395/44441/33357 44398/44444/33360 +f 44396/44442/33358 44398/44444/33360 44397/44443/33359 +f 44397/44443/33359 44398/44444/33360 44399/44445/33361 +f 44397/44443/33359 44399/44445/33361 44400/44446/33362 +f 44360/44406/33322 44397/44443/33359 44400/44446/33362 +f 44360/44406/33322 44400/44446/33362 44361/44407/33323 +f 44361/44407/33323 44400/44446/33362 44401/44447/33363 +f 44361/44407/33323 44401/44447/33363 44366/44412/33328 +f 44400/44446/33362 44399/44445/33361 44402/44448/33364 +f 44400/44446/33362 44402/44448/33364 44401/44447/33363 +f 44401/44447/33363 44402/44448/33364 44403/44449/33365 +f 44401/44447/33363 44403/44449/33365 44404/44450/33366 +f 44366/44412/33328 44401/44447/33363 44404/44450/33366 +f 44366/44412/33328 44404/44450/33366 44367/44413/33329 +f 44367/44413/33329 44404/44450/33366 44405/44451/33367 +f 44367/44413/33329 44405/44451/33367 44372/44418/33334 +f 44404/44450/33366 44403/44449/33365 44406/44452/33368 +f 44404/44450/33366 44406/44452/33368 44405/44451/33367 +f 44405/44451/33367 44406/44452/33368 44407/44453/33369 +f 44405/44451/33367 44407/44453/33369 44408/44454/33370 +f 44372/44418/33334 44405/44451/33367 44408/44454/33370 +f 44372/44418/33334 44408/44454/33370 44373/44419/33335 +f 44373/44419/33335 44408/44454/33370 44409/44455/33371 +f 44373/44419/33335 44409/44455/33371 44378/44424/33340 +f 44408/44454/33370 44407/44453/33369 44410/44456/33372 +f 44408/44454/33370 44410/44456/33372 44409/44455/33371 +f 44409/44455/33371 44410/44456/33372 44411/44457/33373 +f 44409/44455/33371 44411/44457/33373 44412/44458/33374 +f 44378/44424/33340 44409/44455/33371 44412/44458/33374 +f 44378/44424/33340 44412/44458/33374 44379/44425/33341 +f 44379/44425/33341 44412/44458/33374 44413/44459/33375 +f 44379/44425/33341 44413/44459/33375 44384/44430/33346 +f 44412/44458/33374 44411/44457/33373 44414/44460/33376 +f 44412/44458/33374 44414/44460/33376 44413/44459/33375 +f 44413/44459/33375 44414/44460/33376 44415/44461/33377 +f 44413/44459/33375 44415/44461/33377 44416/44462/33378 +f 44384/44430/33346 44413/44459/33375 44416/44462/33378 +f 44384/44430/33346 44416/44462/33378 44385/44431/33347 +f 44385/44431/33347 44416/44462/33378 44417/44463/33379 +f 44385/44431/33347 44417/44463/33379 44390/44436/33352 +f 44416/44462/33378 44415/44461/33377 44418/44464/33380 +f 44416/44462/33378 44418/44464/33380 44417/44463/33379 +f 44417/44463/33379 44418/44464/33380 44338/44384/33300 +f 44417/44463/33379 44338/44384/33300 44335/44381/33297 +f 44390/44436/33352 44417/44463/33379 44335/44381/33297 +f 44390/44436/33352 44335/44381/33297 44334/44380/33296 +f 44419/44465/33381 44420/44466/33382 44421/44467/33383 +f 44419/44465/33381 44421/44467/33383 44422/44468/33384 +f 44420/44466/33382 44423/44469/33385 44424/44470/33386 +f 44420/44466/33382 44424/44470/33386 44421/44467/33383 +f 44421/44467/33383 44424/44470/33386 44425/44471/33387 +f 44421/44467/33383 44425/44471/33387 44426/44472/33388 +f 44422/44468/33384 44421/44467/33383 44426/44472/33388 +f 44422/44468/33384 44426/44472/33388 44427/44473/33389 +f 44428/44474/33390 44429/44475/33391 44430/44476/33392 +f 44428/44474/33390 44430/44476/33392 44431/44477/33393 +f 44429/44475/33391 44432/44478/33394 44433/44479/33395 +f 44429/44475/33391 44433/44479/33395 44430/44476/33392 +f 44430/44476/33392 44433/44479/33395 44423/44469/33385 +f 44430/44476/33392 44423/44469/33385 44420/44466/33382 +f 44431/44477/33393 44430/44476/33392 44420/44466/33382 +f 44431/44477/33393 44420/44466/33382 44419/44465/33381 +f 44434/44480/33396 44435/44481/33397 44436/44482/33398 +f 44434/44480/33396 44436/44482/33398 44437/44483/33399 +f 44435/44481/33397 44438/44484/33400 44439/44485/33401 +f 44435/44481/33397 44439/44485/33401 44436/44482/33398 +f 44436/44482/33398 44439/44485/33401 44440/44486/33402 +f 44436/44482/33398 44440/44486/33402 44441/44487/33403 +f 44437/44483/33399 44436/44482/33398 44441/44487/33403 +f 44437/44483/33399 44441/44487/33403 44442/44488/33404 +f 44443/44489/33405 44444/44490/33406 44445/44491/33407 +f 44443/44489/33405 44445/44491/33407 44446/44492/33408 +f 44444/44490/33406 44447/44493/33409 44448/44494/33410 +f 44444/44490/33406 44448/44494/33410 44445/44491/33407 +f 44449/44495/33411 44450/44496/33412 44451/44497/33413 +f 44449/44495/33411 44451/44497/33413 44452/44498/33414 +f 44453/44499/33415 44449/44495/33411 44452/44498/33414 +f 44453/44499/33415 44452/44498/33414 44454/44500/33416 +f 44455/44501/33417 44456/44502/33418 44457/44503/33419 +f 44455/44501/33417 44457/44503/33419 44458/44504/33420 +f 44456/44502/33418 44459/44505/33421 44460/44506/33422 +f 44456/44502/33418 44460/44506/33422 44457/44503/33419 +f 44457/44503/33419 44460/44506/33422 44443/44489/33405 +f 44457/44503/33419 44443/44489/33405 44461/44507/33423 +f 44458/44504/33420 44457/44503/33419 44461/44507/33423 +f 44458/44504/33420 44461/44507/33423 44462/44508/33424 +f 44463/44509/33425 44464/44510/33426 44465/44511/33427 +f 44463/44509/33425 44465/44511/33427 44466/44512/33428 +f 44464/44510/33426 44467/44513/33429 44468/44514/33430 +f 44464/44510/33426 44468/44514/33430 44465/44511/33427 +f 44465/44511/33427 44468/44514/33430 44459/44505/33421 +f 44465/44511/33427 44459/44505/33421 44456/44502/33418 +f 44466/44512/33428 44465/44511/33427 44456/44502/33418 +f 44466/44512/33428 44456/44502/33418 44455/44501/33417 +f 44469/44515/33431 44470/44516/33432 44471/44517/33433 +f 44469/44515/33431 44471/44517/33433 44472/44518/33434 +f 44470/44516/33432 44473/44519/33435 44474/44520/33436 +f 44470/44516/33432 44474/44520/33436 44471/44517/33433 +f 44471/44517/33433 44474/44520/33436 44467/44513/33429 +f 44471/44517/33433 44467/44513/33429 44464/44510/33426 +f 44472/44518/33434 44471/44517/33433 44464/44510/33426 +f 44472/44518/33434 44464/44510/33426 44463/44509/33425 +f 44427/44473/33389 44426/44472/33388 44475/44521/33437 +f 44427/44473/33389 44475/44521/33437 44476/44522/33438 +f 44426/44472/33388 44425/44471/33387 44477/44523/33439 +f 44426/44472/33388 44477/44523/33439 44475/44521/33437 +f 44475/44521/33437 44477/44523/33439 44478/44524/33440 +f 44475/44521/33437 44478/44524/33440 44479/44525/33441 +f 44476/44522/33438 44475/44521/33437 44479/44525/33441 +f 44476/44522/33438 44479/44525/33441 44480/44526/33442 +f 44338/44384/33300 44481/44527/33443 44482/44528/33444 +f 44338/44384/33300 44482/44528/33444 44339/44385/33301 +f 44483/44529/33443 44484/44530/33445 44485/44531/33446 +f 44483/44529/33443 44485/44531/33446 44486/44532/33444 +f 44486/44532/33444 44485/44531/33446 44487/44533/33447 +f 44486/44532/33444 44487/44533/33447 44488/44534/33448 +f 44339/44385/33301 44482/44528/33444 44489/44535/33448 +f 44339/44385/33301 44489/44535/33448 44340/44386/33302 +f 44393/44439/33355 44490/44536/33449 44491/44537/33450 +f 44393/44439/33355 44491/44537/33450 44394/44440/33356 +f 44492/44538/33449 44493/44539/33451 44494/44540/33452 +f 44492/44538/33449 44494/44540/33452 44495/44541/33450 +f 44495/44541/33450 44494/44540/33452 44496/44542/33453 +f 44495/44541/33450 44496/44542/33453 44497/44543/33454 +f 44394/44440/33356 44491/44537/33450 44498/44544/33454 +f 44394/44440/33356 44498/44544/33454 44395/44441/33357 +f 44395/44441/33357 44498/44544/33454 44499/44545/33455 +f 44395/44441/33357 44499/44545/33455 44398/44444/33360 +f 44497/44543/33454 44496/44542/33453 44500/44546/33456 +f 44497/44543/33454 44500/44546/33456 44501/44547/33455 +f 44501/44547/33455 44500/44546/33456 44502/44548/33457 +f 44501/44547/33455 44502/44548/33457 44503/44549/33458 +f 44398/44444/33360 44499/44545/33455 44504/44550/33458 +f 44398/44444/33360 44504/44550/33458 44399/44445/33361 +f 44399/44445/33361 44504/44550/33458 44505/44551/33459 +f 44399/44445/33361 44505/44551/33459 44402/44448/33364 +f 44503/44549/33458 44502/44548/33457 44506/44552/33460 +f 44503/44549/33458 44506/44552/33460 44507/44553/33459 +f 44507/44553/33459 44506/44552/33460 44508/44554/33461 +f 44507/44553/33459 44508/44554/33461 44509/44555/33462 +f 44402/44448/33364 44505/44551/33459 44510/44556/33462 +f 44402/44448/33364 44510/44556/33462 44403/44449/33365 +f 44403/44449/33365 44510/44556/33462 44511/44557/33463 +f 44403/44449/33365 44511/44557/33463 44406/44452/33368 +f 44509/44555/33462 44508/44554/33461 44512/44558/33397 +f 44509/44555/33462 44512/44558/33397 44513/44559/33463 +f 44511/44557/33463 44435/44481/33397 44434/44480/33396 +f 44511/44557/33463 44434/44480/33396 44514/44560/33464 +f 44406/44452/33368 44511/44557/33463 44514/44560/33464 +f 44406/44452/33368 44514/44560/33464 44407/44453/33369 +f 44407/44453/33369 44514/44560/33464 44515/44561/33465 +f 44407/44453/33369 44515/44561/33465 44410/44456/33372 +f 44514/44560/33464 44434/44480/33396 44516/44562/33466 +f 44514/44560/33464 44516/44562/33466 44515/44561/33465 +f 44517/44563/33467 44518/44564/33468 44519/44565/33469 +f 44517/44563/33467 44519/44565/33469 44520/44566/33470 +f 44410/44456/33372 44515/44561/33465 44521/44567/33470 +f 44410/44456/33372 44521/44567/33470 44411/44457/33373 +f 44411/44457/33373 44521/44567/33470 44522/44568/33471 +f 44411/44457/33373 44522/44568/33471 44414/44460/33376 +f 44520/44566/33470 44519/44565/33469 44523/44569/33472 +f 44520/44566/33470 44523/44569/33472 44524/44570/33471 +f 44524/44570/33471 44523/44569/33472 44525/44571/33473 +f 44524/44570/33471 44525/44571/33473 44526/44572/33474 +f 44414/44460/33376 44522/44568/33471 44527/44573/33474 +f 44414/44460/33376 44527/44573/33474 44415/44461/33377 +f 44415/44461/33377 44527/44573/33474 44528/44574/33475 +f 44415/44461/33377 44528/44574/33475 44418/44464/33380 +f 44526/44572/33474 44525/44571/33473 44529/44575/33476 +f 44526/44572/33474 44529/44575/33476 44530/44576/33475 +f 44530/44576/33475 44529/44575/33476 44484/44530/33445 +f 44530/44576/33475 44484/44530/33445 44483/44529/33443 +f 44418/44464/33380 44528/44574/33475 44481/44527/33443 +f 44418/44464/33380 44481/44527/33443 44338/44384/33300 +f 44478/44524/33440 44477/44523/33439 44531/44577/33477 +f 44478/44524/33440 44531/44577/33477 44532/44578/33478 +f 44477/44523/33439 44425/44471/33387 44533/44579/33479 +f 44477/44523/33439 44533/44579/33479 44531/44577/33477 +f 44531/44577/33477 44533/44579/33479 44534/44580/33480 +f 44531/44577/33477 44534/44580/33480 44535/44581/33481 +f 44532/44578/33478 44531/44577/33477 44535/44581/33481 +f 44532/44578/33478 44535/44581/33481 44536/44582/33482 +f 44459/44505/33421 44468/44514/33430 44537/44583/33483 +f 44459/44505/33421 44537/44583/33483 44538/44584/33484 +f 44468/44514/33430 44467/44513/33429 44539/44585/33485 +f 44468/44514/33430 44539/44585/33485 44537/44583/33483 +f 44537/44583/33483 44539/44585/33485 44540/44586/33486 +f 44537/44583/33483 44540/44586/33486 44541/44587/33487 +f 44538/44584/33484 44537/44583/33483 44541/44587/33487 +f 44538/44584/33484 44541/44587/33487 44542/44588/33488 +f 44447/44493/33409 44444/44490/33406 44543/44589/33489 +f 44447/44493/33409 44543/44589/33489 44544/44590/33490 +f 44444/44490/33406 44443/44489/33405 44545/44591/33491 +f 44444/44490/33406 44545/44591/33491 44543/44589/33489 +f 44543/44589/33489 44545/44591/33491 44546/44592/33492 +f 44543/44589/33489 44546/44592/33492 44547/44593/33493 +f 44544/44590/33490 44543/44589/33489 44547/44593/33493 +f 44544/44590/33490 44547/44593/33493 44548/44594/33494 +f 44423/44469/33385 44433/44479/33395 44549/44595/33495 +f 44423/44469/33385 44549/44595/33495 44550/44596/33496 +f 44433/44479/33395 44432/44478/33394 44551/44597/33497 +f 44433/44479/33395 44551/44597/33497 44549/44595/33495 +f 44549/44595/33495 44551/44597/33497 44552/44598/33498 +f 44549/44595/33495 44552/44598/33498 44553/44599/33499 +f 44550/44596/33496 44549/44595/33495 44553/44599/33499 +f 44550/44596/33496 44553/44599/33499 44554/44600/33500 +f 44467/44513/33429 44474/44520/33436 44555/44601/33501 +f 44467/44513/33429 44555/44601/33501 44539/44585/33485 +f 44474/44520/33436 44473/44519/33435 44556/44602/33502 +f 44474/44520/33436 44556/44602/33502 44555/44601/33501 +f 44555/44601/33501 44556/44602/33502 44557/44603/33503 +f 44555/44601/33501 44557/44603/33503 44558/44604/33504 +f 44539/44585/33485 44555/44601/33501 44558/44604/33504 +f 44539/44585/33485 44558/44604/33504 44540/44586/33486 +f 44443/44489/33405 44460/44506/33422 44559/44605/33505 +f 44443/44489/33405 44559/44605/33505 44545/44591/33491 +f 44460/44506/33422 44459/44505/33421 44538/44584/33484 +f 44460/44506/33422 44538/44584/33484 44559/44605/33505 +f 44559/44605/33505 44538/44584/33484 44542/44588/33488 +f 44559/44605/33505 44542/44588/33488 44560/44606/33506 +f 44545/44591/33491 44559/44605/33505 44560/44606/33506 +f 44545/44591/33491 44560/44606/33506 44546/44592/33492 +f 44432/44478/33394 44561/44607/33507 44562/44608/33508 +f 44432/44478/33394 44562/44608/33508 44551/44597/33497 +f 44561/44607/33507 44447/44493/33409 44544/44590/33490 +f 44561/44607/33507 44544/44590/33490 44562/44608/33508 +f 44562/44608/33508 44544/44590/33490 44548/44594/33494 +f 44562/44608/33508 44548/44594/33494 44563/44609/33509 +f 44551/44597/33497 44562/44608/33508 44563/44609/33509 +f 44551/44597/33497 44563/44609/33509 44552/44598/33498 +f 44425/44471/33387 44424/44470/33386 44564/44610/33510 +f 44425/44471/33387 44564/44610/33510 44533/44579/33479 +f 44424/44470/33386 44423/44469/33385 44550/44596/33496 +f 44424/44470/33386 44550/44596/33496 44564/44610/33510 +f 44564/44610/33510 44550/44596/33496 44554/44600/33500 +f 44564/44610/33510 44554/44600/33500 44565/44611/33511 +f 44533/44579/33479 44564/44610/33510 44565/44611/33511 +f 44533/44579/33479 44565/44611/33511 44534/44580/33480 +f 44115/44179/33100 44112/44176/33097 44566/44612/33512 +f 44115/44179/33100 44566/44612/33512 44567/44613/33513 +f 44112/44176/33097 44111/44175/33096 44568/44614/33514 +f 44112/44176/33097 44568/44614/33514 44566/44612/33512 +f 44566/44612/33512 44568/44614/33514 44569/44615/33515 +f 44566/44612/33512 44569/44615/33515 44570/44616/33516 +f 44567/44613/33513 44566/44612/33512 44570/44616/33516 +f 44567/44613/33513 44570/44616/33516 44571/44617/33517 +f 44572/44618/33518 44573/44619/33519 44574/44620/33520 +f 44572/44618/33518 44574/44620/33520 44575/44621/33521 +f 44576/44622/33519 44577/44623/33522 44578/44624/33523 +f 44576/44622/33519 44578/44624/33523 44579/44625/33524 +f 44579/44625/33524 44578/44624/33523 44580/44626/33525 +f 44579/44625/33524 44580/44626/33525 44581/44627/33526 +f 44575/44621/33521 44574/44620/33520 44582/44628/33527 +f 44575/44621/33521 44582/44628/33527 44583/44629/33528 +f 44552/44598/33498 44563/44609/33509 44584/44630/33529 +f 44552/44598/33498 44584/44630/33529 44585/44631/33530 +f 44563/44609/33509 44548/44594/33494 44586/44632/33531 +f 44563/44609/33509 44586/44632/33531 44584/44630/33529 +f 44584/44630/33529 44586/44632/33531 44587/44633/33532 +f 44584/44630/33529 44587/44633/33532 44588/44634/33533 +f 44585/44631/33530 44584/44630/33529 44588/44634/33533 +f 44585/44631/33530 44588/44634/33533 44589/44635/33534 +f 44158/44204/33136 44242/44288/33217 44590/44636/33535 +f 44158/44204/33136 44590/44636/33535 44591/44637/33536 +f 44248/44294/33221 44249/44295/33222 44592/44638/33537 +f 44248/44294/33221 44592/44638/33537 44593/44639/33538 +f 44594/44640/33538 44595/44641/33537 44596/44642/33539 +f 44594/44640/33538 44596/44642/33539 44597/44643/33540 +f 44591/44637/33536 44590/44636/33535 44598/44644/33540 +f 44591/44637/33536 44598/44644/33540 44599/44645/33541 +f 44600/44646/33542 44601/44647/33543 44602/44648/33544 +f 44600/44646/33542 44602/44648/33544 44603/44649/33545 +f 44601/44647/33543 44536/44582/33482 44604/44650/33546 +f 44601/44647/33543 44604/44650/33546 44602/44648/33544 +f 44602/44648/33544 44604/44650/33546 44605/44651/33547 +f 44602/44648/33544 44605/44651/33547 44606/44652/33548 +f 44607/44653/33549 44608/44654/33550 44609/44655/33548 +f 44607/44653/33549 44609/44655/33548 44610/44656/33551 +f 44611/44657/33552 44612/44658/33553 44613/44659/33554 +f 44611/44657/33552 44613/44659/33554 44614/44660/33555 +f 44615/44661/33556 44616/44662/33557 44617/44663/33558 +f 44615/44661/33556 44617/44663/33558 44618/44664/33554 +f 44618/44664/33554 44617/44663/33558 44493/44539/33451 +f 44618/44664/33554 44493/44539/33451 44492/44538/33449 +f 44614/44660/33555 44613/44659/33554 44490/44536/33449 +f 44614/44660/33555 44490/44536/33449 44393/44439/33355 +f 44619/44665/33559 44620/44666/33560 44621/44667/33561 +f 44619/44665/33559 44621/44667/33561 44622/44668/33562 +f 44620/44666/33560 44623/44669/33563 44624/44670/33564 +f 44620/44666/33560 44624/44670/33564 44621/44667/33561 +f 44621/44667/33561 44624/44670/33564 44625/44671/33565 +f 44621/44667/33561 44625/44671/33565 44626/44672/33566 +f 44622/44668/33562 44621/44667/33561 44626/44672/33566 +f 44622/44668/33562 44626/44672/33566 44627/44673/33567 +f 44134/44102/32990 44132/44190/33115 44628/44674/33568 +f 44134/44102/32990 44628/44674/33568 44629/44675/33569 +f 44132/44190/33115 44128/44100/33114 44630/44676/33570 +f 44132/44190/33115 44630/44676/33570 44628/44674/33568 +f 44628/44674/33568 44630/44676/33570 44631/44677/33571 +f 44628/44674/33568 44631/44677/33571 44632/44678/33572 +f 44629/44675/33569 44628/44674/33568 44632/44678/33572 +f 44629/44675/33569 44632/44678/33572 44633/44679/33573 +f 44634/44680/33574 44635/44681/33575 44636/44682/33576 +f 44634/44680/33574 44636/44682/33576 44637/44683/33577 +f 44635/44681/33575 44638/44684/33578 44639/44685/33579 +f 44635/44681/33575 44639/44685/33579 44636/44682/33576 +f 44640/44686/33576 44641/44687/33580 44642/44688/33581 +f 44640/44686/33576 44642/44688/33581 44643/44689/33582 +f 44644/44690/33577 44640/44686/33576 44643/44689/33582 +f 44644/44690/33577 44643/44689/33582 44645/44691/33583 +f 44646/44692/33584 44647/44693/33585 44648/44694/33586 +f 44646/44692/33584 44648/44694/33586 44649/44695/33587 +f 44647/44693/33585 44650/44696/33588 44651/44697/33589 +f 44647/44693/33585 44651/44697/33589 44648/44694/33586 +f 44648/44694/33586 44651/44697/33589 44480/44526/33442 +f 44648/44694/33586 44480/44526/33442 44479/44525/33441 +f 44649/44695/33587 44648/44694/33586 44479/44525/33441 +f 44649/44695/33587 44479/44525/33441 44478/44524/33440 +f 44554/44600/33500 44553/44599/33499 44652/44698/33590 +f 44554/44600/33500 44652/44698/33590 44653/44699/33591 +f 44553/44599/33499 44552/44598/33498 44585/44631/33530 +f 44553/44599/33499 44585/44631/33530 44652/44698/33590 +f 44652/44698/33590 44585/44631/33530 44589/44635/33534 +f 44652/44698/33590 44589/44635/33534 44654/44700/33592 +f 44653/44699/33591 44652/44698/33590 44654/44700/33592 +f 44653/44699/33591 44654/44700/33592 44655/44701/33593 +f 44100/44165/33085 44110/44174/33095 44656/44702/33594 +f 44100/44165/33085 44656/44702/33594 44657/44703/33595 +f 44110/44174/33095 44109/44173/33094 44658/44704/33596 +f 44110/44174/33095 44658/44704/33596 44656/44702/33594 +f 44656/44702/33594 44658/44704/33596 44659/44705/33597 +f 44656/44702/33594 44659/44705/33597 44660/44706/33598 +f 44657/44703/33595 44656/44702/33594 44660/44706/33598 +f 44657/44703/33595 44660/44706/33598 44661/44707/33599 +f 44662/44708/33600 44663/44709/33601 44664/44710/33602 +f 44662/44708/33600 44664/44710/33602 44665/44711/33603 +f 44663/44709/33601 44666/44712/33604 44667/44713/33605 +f 44663/44709/33601 44667/44713/33605 44664/44710/33602 +f 44664/44710/33602 44667/44713/33605 44348/44394/33310 +f 44664/44710/33602 44348/44394/33310 44347/44393/33309 +f 44665/44711/33603 44664/44710/33602 44347/44393/33309 +f 44665/44711/33603 44347/44393/33309 44342/44388/33304 +f 44668/44714/33606 44669/44715/33607 44670/44716/33608 +f 44668/44714/33606 44670/44716/33608 44671/44717/33609 +f 44669/44715/33607 44672/44718/33610 44673/44719/33611 +f 44669/44715/33607 44673/44719/33611 44670/44716/33608 +f 44670/44716/33608 44673/44719/33611 44674/44720/33612 +f 44670/44716/33608 44674/44720/33612 44675/44721/33613 +f 44671/44717/33609 44670/44716/33608 44675/44721/33613 +f 44671/44717/33609 44675/44721/33613 44676/44722/33614 +f 44102/44167/33087 44101/44166/33086 44677/44723/33615 +f 44102/44167/33087 44677/44723/33615 44678/44724/33616 +f 44101/44166/33086 44100/44165/33085 44657/44703/33595 +f 44101/44166/33086 44657/44703/33595 44677/44723/33615 +f 44677/44723/33615 44657/44703/33595 44661/44707/33599 +f 44677/44723/33615 44661/44707/33599 44679/44725/33617 +f 44678/44724/33616 44677/44723/33615 44679/44725/33617 +f 44678/44724/33616 44679/44725/33617 44680/44726/33618 +f 44666/44712/33604 44681/44727/33619 44682/44728/33620 +f 44666/44712/33604 44682/44728/33620 44667/44713/33605 +f 44681/44727/33619 44683/44729/33621 44684/44730/33622 +f 44681/44727/33619 44684/44730/33622 44682/44728/33620 +f 44682/44728/33620 44684/44730/33622 44343/44389/33305 +f 44682/44728/33620 44343/44389/33305 44346/44392/33308 +f 44667/44713/33605 44682/44728/33620 44346/44392/33308 +f 44667/44713/33605 44346/44392/33308 44348/44394/33310 +f 44228/44274/33206 44685/44731/33623 44686/44732/33624 +f 44228/44274/33206 44686/44732/33624 44687/44733/33625 +f 44685/44731/33623 44237/44283/33213 44688/44734/33626 +f 44685/44731/33623 44688/44734/33626 44686/44732/33624 +f 44686/44732/33624 44688/44734/33626 44689/44735/33627 +f 44686/44732/33624 44689/44735/33627 44690/44736/33628 +f 44687/44733/33625 44686/44732/33624 44690/44736/33628 +f 44687/44733/33625 44690/44736/33628 44691/44737/33629 +f 44534/44580/33480 44565/44611/33511 44692/44738/33630 +f 44534/44580/33480 44692/44738/33630 44693/44739/33631 +f 44565/44611/33511 44554/44600/33500 44653/44699/33591 +f 44565/44611/33511 44653/44699/33591 44692/44738/33630 +f 44692/44738/33630 44653/44699/33591 44655/44701/33593 +f 44692/44738/33630 44655/44701/33593 44694/44740/33632 +f 44693/44739/33631 44692/44738/33630 44694/44740/33632 +f 44693/44739/33631 44694/44740/33632 44695/44741/33633 +f 44109/44173/33094 44106/44171/33091 44696/44742/33634 +f 44109/44173/33094 44696/44742/33634 44658/44704/33596 +f 44106/44171/33091 44105/44170/33090 44697/44743/33635 +f 44106/44171/33091 44697/44743/33635 44696/44742/33634 +f 44696/44742/33634 44697/44743/33635 44698/44744/33636 +f 44696/44742/33634 44698/44744/33636 44699/44745/33637 +f 44658/44704/33596 44696/44742/33634 44699/44745/33637 +f 44658/44704/33596 44699/44745/33637 44659/44705/33597 +f 44650/44696/33588 44700/44746/33638 44701/44747/33639 +f 44650/44696/33588 44701/44747/33639 44651/44697/33589 +f 44700/44746/33638 44702/44748/33640 44703/44749/33641 +f 44700/44746/33638 44703/44749/33641 44701/44747/33639 +f 44701/44747/33639 44703/44749/33641 44487/44533/33447 +f 44701/44747/33639 44487/44533/33447 44704/44750/33642 +f 44651/44697/33589 44701/44747/33639 44704/44750/33642 +f 44651/44697/33589 44704/44750/33642 44480/44526/33442 +f 44623/44669/33563 44705/44751/33643 44706/44752/33644 +f 44623/44669/33563 44706/44752/33644 44624/44670/33564 +f 44705/44751/33643 44707/44753/33645 44708/44754/33646 +f 44705/44751/33643 44708/44754/33646 44706/44752/33644 +f 44706/44752/33644 44708/44754/33646 44709/44755/33647 +f 44706/44752/33644 44709/44755/33647 44710/44756/33648 +f 44624/44670/33564 44706/44752/33644 44710/44756/33648 +f 44624/44670/33564 44710/44756/33648 44625/44671/33565 +f 44140/44107/33121 44138/44105/33119 44711/44757/33649 +f 44140/44107/33121 44711/44757/33649 44712/44758/33650 +f 44138/44105/33119 44134/44102/32990 44629/44675/33569 +f 44138/44105/33119 44629/44675/33569 44711/44757/33649 +f 44711/44757/33649 44629/44675/33569 44633/44679/33573 +f 44711/44757/33649 44633/44679/33573 44713/44759/33651 +f 44712/44758/33650 44711/44757/33649 44713/44759/33651 +f 44712/44758/33650 44713/44759/33651 44714/44760/33652 +f 44119/44183/33104 44154/44200/33132 44715/44761/33653 +f 44119/44183/33104 44715/44761/33653 44716/44762/33654 +f 44154/44200/33132 44158/44204/33136 44591/44637/33536 +f 44154/44200/33132 44591/44637/33536 44715/44761/33653 +f 44715/44761/33653 44591/44637/33536 44599/44645/33541 +f 44715/44761/33653 44599/44645/33541 44717/44763/33655 +f 44716/44762/33654 44715/44761/33653 44717/44763/33655 +f 44716/44762/33654 44717/44763/33655 44718/44764/33656 +f 44122/44184/33106 44120/44096/32984 44719/44765/33657 +f 44122/44184/33106 44719/44765/33657 44720/44766/33658 +f 44120/44096/32984 44115/44179/33100 44567/44613/33513 +f 44120/44096/32984 44567/44613/33513 44719/44765/33657 +f 44719/44765/33657 44567/44613/33513 44571/44617/33517 +f 44719/44765/33657 44571/44617/33517 44721/44767/33659 +f 44720/44766/33658 44719/44765/33657 44721/44767/33659 +f 44720/44766/33658 44721/44767/33659 44722/44768/33660 +f 44146/44111/33002 44144/44109/33124 44723/44769/33661 +f 44146/44111/33002 44723/44769/33661 44724/44770/33662 +f 44144/44109/33124 44140/44107/33121 44712/44758/33650 +f 44144/44109/33124 44712/44758/33650 44723/44769/33661 +f 44723/44769/33661 44712/44758/33650 44714/44760/33652 +f 44723/44769/33661 44714/44760/33652 44725/44771/33663 +f 44724/44770/33662 44723/44769/33661 44725/44771/33663 +f 44724/44770/33662 44725/44771/33663 44726/44772/33664 +f 44536/44582/33482 44535/44581/33481 44727/44773/33665 +f 44536/44582/33482 44727/44773/33665 44604/44650/33546 +f 44535/44581/33481 44534/44580/33480 44693/44739/33631 +f 44535/44581/33481 44693/44739/33631 44727/44773/33665 +f 44727/44773/33665 44693/44739/33631 44695/44741/33633 +f 44727/44773/33665 44695/44741/33633 44728/44774/33666 +f 44604/44650/33546 44727/44773/33665 44728/44774/33666 +f 44604/44650/33546 44728/44774/33666 44605/44651/33547 +f 44729/44158/33667 44730/44775/33668 44731/44776/33669 +f 44729/44158/33667 44731/44776/33669 44732/44777/33670 +f 44730/44775/33668 44610/44656/33551 44609/44655/33548 +f 44730/44775/33668 44609/44655/33548 44731/44776/33669 +f 44733/44778/33671 44606/44652/33548 44605/44651/33547 +f 44733/44778/33671 44605/44651/33547 44728/44774/33666 +f 44734/44779/33672 44733/44778/33671 44728/44774/33666 +f 44734/44779/33672 44728/44774/33666 44695/44741/33633 +f 44230/44276/33208 44229/44275/33207 44735/44780/33673 +f 44230/44276/33208 44735/44780/33673 44736/44781/33674 +f 44229/44275/33207 44228/44274/33206 44687/44733/33625 +f 44229/44275/33207 44687/44733/33625 44735/44780/33673 +f 44735/44780/33673 44687/44733/33625 44691/44737/33629 +f 44735/44780/33673 44691/44737/33629 44737/44782/33675 +f 44736/44781/33674 44735/44780/33673 44737/44782/33675 +f 44736/44781/33674 44737/44782/33675 44738/44783/33676 +f 44484/44530/33445 44739/44784/33677 44740/44785/33678 +f 44484/44530/33445 44740/44785/33678 44485/44531/33446 +f 44739/44784/33677 44427/44473/33389 44476/44522/33438 +f 44739/44784/33677 44476/44522/33438 44740/44785/33678 +f 44740/44785/33678 44476/44522/33438 44480/44526/33442 +f 44740/44785/33678 44480/44526/33442 44704/44750/33642 +f 44485/44531/33446 44740/44785/33678 44704/44750/33642 +f 44485/44531/33446 44704/44750/33642 44487/44533/33447 +f 44493/44539/33451 44741/44786/33679 44742/44787/33680 +f 44493/44539/33451 44742/44787/33680 44494/44540/33452 +f 44741/44786/33679 44469/44515/33431 44472/44518/33434 +f 44741/44786/33679 44472/44518/33434 44742/44787/33680 +f 44742/44787/33680 44472/44518/33434 44463/44509/33425 +f 44742/44787/33680 44463/44509/33425 44743/44788/33681 +f 44494/44540/33452 44742/44787/33680 44743/44788/33681 +f 44494/44540/33452 44743/44788/33681 44496/44542/33453 +f 44496/44542/33453 44743/44788/33681 44744/44789/33682 +f 44496/44542/33453 44744/44789/33682 44500/44546/33456 +f 44743/44788/33681 44463/44509/33425 44466/44512/33428 +f 44743/44788/33681 44466/44512/33428 44744/44789/33682 +f 44744/44789/33682 44466/44512/33428 44455/44501/33417 +f 44744/44789/33682 44455/44501/33417 44745/44790/33683 +f 44500/44546/33456 44744/44789/33682 44745/44790/33683 +f 44500/44546/33456 44745/44790/33683 44502/44548/33457 +f 44502/44548/33457 44745/44790/33683 44746/44791/33684 +f 44502/44548/33457 44746/44791/33684 44506/44552/33460 +f 44745/44790/33683 44455/44501/33417 44458/44504/33420 +f 44745/44790/33683 44458/44504/33420 44746/44791/33684 +f 44746/44791/33684 44458/44504/33420 44462/44508/33424 +f 44746/44791/33684 44462/44508/33424 44747/44792/33685 +f 44506/44552/33460 44746/44791/33684 44747/44792/33685 +f 44506/44552/33460 44747/44792/33685 44508/44554/33461 +f 44462/44508/33424 44461/44507/33423 44748/44793/33686 +f 44462/44508/33424 44748/44793/33686 44749/44794/33687 +f 44461/44507/33423 44443/44489/33405 44446/44492/33408 +f 44461/44507/33423 44446/44492/33408 44748/44793/33686 +f 44750/44795/33688 44751/44796/33415 44752/44797/33416 +f 44750/44795/33688 44752/44797/33416 44753/44798/33689 +f 44754/44799/33690 44750/44795/33688 44753/44798/33689 +f 44754/44799/33690 44753/44798/33689 44755/44800/33691 +f 44432/44478/33394 44429/44475/33391 44756/44801/33692 +f 44432/44478/33394 44756/44801/33692 44757/44802/33693 +f 44429/44475/33391 44428/44474/33390 44758/44803/33694 +f 44429/44475/33391 44758/44803/33694 44756/44801/33692 +f 44759/44804/33695 44760/44805/33696 44761/44806/33697 +f 44759/44804/33695 44761/44806/33697 44762/44807/33698 +f 44763/44808/33693 44759/44804/33695 44762/44807/33698 +f 44763/44808/33693 44762/44807/33698 44764/44809/33699 +f 44519/44565/33469 44765/44810/33700 44766/44811/33701 +f 44519/44565/33469 44766/44811/33701 44523/44569/33472 +f 44765/44810/33700 44428/44474/33390 44431/44477/33393 +f 44765/44810/33700 44431/44477/33393 44766/44811/33701 +f 44766/44811/33701 44431/44477/33393 44419/44465/33381 +f 44766/44811/33701 44419/44465/33381 44767/44812/33702 +f 44523/44569/33472 44766/44811/33701 44767/44812/33702 +f 44523/44569/33472 44767/44812/33702 44525/44571/33473 +f 44525/44571/33473 44767/44812/33702 44768/44813/33703 +f 44525/44571/33473 44768/44813/33703 44529/44575/33476 +f 44767/44812/33702 44419/44465/33381 44422/44468/33384 +f 44767/44812/33702 44422/44468/33384 44768/44813/33703 +f 44768/44813/33703 44422/44468/33384 44427/44473/33389 +f 44768/44813/33703 44427/44473/33389 44739/44784/33677 +f 44529/44575/33476 44768/44813/33703 44739/44784/33677 +f 44529/44575/33476 44739/44784/33677 44484/44530/33445 +f 44240/44286/33215 44238/44284/33214 44769/44814/33704 +f 44240/44286/33215 44769/44814/33704 44770/44815/33705 +f 44238/44284/33214 44237/44283/33213 44685/44731/33623 +f 44238/44284/33214 44685/44731/33623 44769/44814/33704 +f 44769/44814/33704 44685/44731/33623 44228/44274/33206 +f 44769/44814/33704 44228/44274/33206 44226/44272/33204 +f 44770/44815/33705 44769/44814/33704 44226/44272/33204 +f 44770/44815/33705 44226/44272/33204 44185/44231/33163 +f 44249/44295/33222 44247/44293/33220 44771/44816/33706 +f 44249/44295/33222 44771/44816/33706 44772/44817/33707 +f 44247/44293/33220 44246/44292/33219 44773/44818/33708 +f 44247/44293/33220 44773/44818/33708 44771/44816/33706 +f 44771/44816/33706 44773/44818/33708 44214/44260/33192 +f 44771/44816/33706 44214/44260/33192 44221/44267/33199 +f 44772/44817/33707 44771/44816/33706 44221/44267/33199 +f 44772/44817/33707 44221/44267/33199 44220/44266/33198 +f 44246/44292/33219 44255/44301/33226 44774/44819/33709 +f 44246/44292/33219 44774/44819/33709 44773/44818/33708 +f 44255/44301/33226 44254/44300/33225 44775/44820/33710 +f 44255/44301/33226 44775/44820/33710 44774/44819/33709 +f 44774/44819/33709 44775/44820/33710 44208/44254/33186 +f 44774/44819/33709 44208/44254/33186 44215/44261/33193 +f 44773/44818/33708 44774/44819/33709 44215/44261/33193 +f 44773/44818/33708 44215/44261/33193 44214/44260/33192 +f 44254/44300/33225 44261/44307/33231 44776/44821/33711 +f 44254/44300/33225 44776/44821/33711 44775/44820/33710 +f 44261/44307/33231 44260/44306/33230 44777/44822/33712 +f 44261/44307/33231 44777/44822/33712 44776/44821/33711 +f 44776/44821/33711 44777/44822/33712 44202/44248/33180 +f 44776/44821/33711 44202/44248/33180 44209/44255/33187 +f 44775/44820/33710 44776/44821/33711 44209/44255/33187 +f 44775/44820/33710 44209/44255/33187 44208/44254/33186 +f 44260/44306/33230 44267/44313/33237 44778/44823/33713 +f 44260/44306/33230 44778/44823/33713 44777/44822/33712 +f 44267/44313/33237 44266/44312/33236 44779/44824/33714 +f 44267/44313/33237 44779/44824/33714 44778/44823/33713 +f 44778/44823/33713 44779/44824/33714 44196/44242/33174 +f 44778/44823/33713 44196/44242/33174 44203/44249/33181 +f 44777/44822/33712 44778/44823/33713 44203/44249/33181 +f 44777/44822/33712 44203/44249/33181 44202/44248/33180 +f 44266/44312/33236 44273/44319/33242 44780/44825/33715 +f 44266/44312/33236 44780/44825/33715 44779/44824/33714 +f 44273/44319/33242 44272/44318/33241 44781/44826/33716 +f 44273/44319/33242 44781/44826/33716 44780/44825/33715 +f 44780/44825/33715 44781/44826/33716 44190/44236/33168 +f 44780/44825/33715 44190/44236/33168 44197/44243/33175 +f 44779/44824/33714 44780/44825/33715 44197/44243/33175 +f 44779/44824/33714 44197/44243/33175 44196/44242/33174 +f 44272/44318/33241 44279/44325/33246 44782/44827/33717 +f 44272/44318/33241 44782/44827/33717 44781/44826/33716 +f 44279/44325/33246 44278/44324/33245 44783/44828/33718 +f 44279/44325/33246 44783/44828/33718 44782/44827/33717 +f 44782/44827/33717 44783/44828/33718 44181/44227/33159 +f 44782/44827/33717 44181/44227/33159 44191/44237/33169 +f 44781/44826/33716 44782/44827/33717 44191/44237/33169 +f 44781/44826/33716 44191/44237/33169 44190/44236/33168 +f 44278/44324/33245 44282/44328/33249 44784/44829/33719 +f 44278/44324/33245 44784/44829/33719 44783/44828/33718 +f 44282/44328/33249 44240/44286/33215 44770/44815/33705 +f 44282/44328/33249 44770/44815/33705 44784/44829/33719 +f 44784/44829/33719 44770/44815/33705 44185/44231/33163 +f 44784/44829/33719 44185/44231/33163 44182/44228/33160 +f 44783/44828/33718 44784/44829/33719 44182/44228/33160 +f 44783/44828/33718 44182/44228/33160 44181/44227/33159 +f 44785/44830/33720 44786/44831/33721 44787/44832/33722 +f 44785/44830/33720 44787/44832/33722 44788/44833/33723 +f 44786/44831/33721 44789/44834/33724 44790/44835/33725 +f 44786/44831/33721 44790/44835/33725 44787/44832/33722 +f 44787/44832/33722 44790/44835/33725 44791/44836/33726 +f 44787/44832/33722 44791/44836/33726 44792/44837/33727 +f 44788/44833/33723 44787/44832/33722 44792/44837/33727 +f 44788/44833/33723 44792/44837/33727 44793/44838/33728 +f 44794/44119/33729 44795/44116/33730 44796/44839/33731 +f 44794/44119/33729 44796/44839/33731 44797/44840/33732 +f 44795/44116/33730 44798/44115/33733 44799/44841/33732 +f 44795/44116/33730 44799/44841/33732 44796/44839/33731 +f 44796/44839/33731 44799/44841/33732 44800/44842/33734 +f 44796/44839/33731 44800/44842/33734 44801/44843/33735 +f 44797/44840/33732 44796/44839/33731 44801/44843/33735 +f 44797/44840/33732 44801/44843/33735 44802/44844/33736 +f 44803/44130/33008 44804/44127/33737 44805/44845/33738 +f 44803/44130/33008 44805/44845/33738 44806/44846/33739 +f 44804/44127/33737 44794/44119/33729 44797/44840/33732 +f 44804/44127/33737 44797/44840/33732 44805/44845/33738 +f 44805/44845/33738 44797/44840/33732 44802/44844/33736 +f 44805/44845/33738 44802/44844/33736 44807/44847/33740 +f 44806/44846/33739 44805/44845/33738 44807/44847/33740 +f 44806/44846/33739 44807/44847/33740 44808/44848/33741 +f 44809/44849/33742 44810/44850/33743 44811/44851/33744 +f 44809/44849/33742 44811/44851/33744 44812/44852/33745 +f 44810/44850/33743 44813/44853/33746 44814/44854/33747 +f 44810/44850/33743 44814/44854/33747 44811/44851/33744 +f 44815/44855/33748 44816/44856/33749 44817/44857/33750 +f 44815/44855/33748 44817/44857/33750 44818/44858/33751 +f 44819/44859/33752 44815/44855/33748 44818/44858/33751 +f 44819/44859/33752 44818/44858/33751 44820/44860/33753 +f 44821/44122/33013 44822/44136/33754 44823/44861/33755 +f 44821/44122/33013 44823/44861/33755 44824/44862/33610 +f 44822/44136/33754 44825/44133/33756 44826/44863/33606 +f 44822/44136/33754 44826/44863/33606 44823/44861/33755 +f 44823/44861/33755 44826/44863/33606 44827/44864/33757 +f 44823/44861/33755 44827/44864/33757 44828/44865/33758 +f 44824/44862/33610 44823/44861/33755 44828/44865/33758 +f 44824/44862/33610 44828/44865/33758 44829/44866/33759 +f 44830/44867/33022 44831/44123/33760 44832/44868/33761 +f 44830/44867/33022 44832/44868/33761 44833/44869/33762 +f 44831/44123/33760 44821/44122/33013 44824/44862/33610 +f 44831/44123/33760 44824/44862/33610 44832/44868/33761 +f 44832/44868/33761 44824/44862/33610 44829/44866/33759 +f 44832/44868/33761 44829/44866/33759 44834/44870/33763 +f 44833/44869/33762 44832/44868/33761 44834/44870/33763 +f 44833/44869/33762 44834/44870/33763 44835/44871/33764 +f 44642/44688/33581 44836/44872/33765 44837/44873/33766 +f 44642/44688/33581 44837/44873/33766 44643/44689/33582 +f 44836/44872/33765 44830/44867/33022 44833/44869/33762 +f 44836/44872/33765 44833/44869/33762 44837/44873/33766 +f 44837/44873/33766 44833/44869/33762 44835/44871/33764 +f 44837/44873/33766 44835/44871/33764 44838/44874/33767 +f 44643/44689/33582 44837/44873/33766 44838/44874/33767 +f 44643/44689/33582 44838/44874/33767 44645/44691/33583 +f 44548/44594/33494 44547/44593/33493 44839/44875/33768 +f 44548/44594/33494 44839/44875/33768 44586/44632/33531 +f 44547/44593/33493 44546/44592/33492 44840/44876/33769 +f 44547/44593/33493 44840/44876/33769 44839/44875/33768 +f 44839/44875/33768 44840/44876/33769 44841/44877/33770 +f 44839/44875/33768 44841/44877/33770 44842/44878/33771 +f 44586/44632/33531 44839/44875/33768 44842/44878/33771 +f 44586/44632/33531 44842/44878/33771 44587/44633/33532 +f 44843/44879/33772 44844/44880/33773 44845/44881/33774 +f 44843/44879/33772 44845/44881/33774 44846/44882/33775 +f 44844/44880/33773 44668/44714/33606 44671/44717/33609 +f 44844/44880/33773 44671/44717/33609 44845/44881/33774 +f 44845/44881/33774 44671/44717/33609 44676/44722/33614 +f 44845/44881/33774 44676/44722/33614 44847/44883/33776 +f 44846/44882/33775 44845/44881/33774 44847/44883/33776 +f 44846/44882/33775 44847/44883/33776 44848/44884/33777 +f 44546/44592/33492 44560/44606/33506 44849/44885/33778 +f 44546/44592/33492 44849/44885/33778 44840/44876/33769 +f 44560/44606/33506 44542/44588/33488 44850/44886/33779 +f 44560/44606/33506 44850/44886/33779 44849/44885/33778 +f 44849/44885/33778 44850/44886/33779 44851/44887/33780 +f 44849/44885/33778 44851/44887/33780 44852/44888/33781 +f 44840/44876/33769 44849/44885/33778 44852/44888/33781 +f 44840/44876/33769 44852/44888/33781 44841/44877/33770 +f 44286/44332/33252 44285/44331/33250 44853/44889/33782 +f 44286/44332/33252 44853/44889/33782 44854/44890/33783 +f 44283/44329/33250 44230/44276/33208 44736/44781/33674 +f 44283/44329/33250 44736/44781/33674 44855/44891/33784 +f 44855/44891/33784 44736/44781/33674 44738/44783/33676 +f 44855/44891/33784 44738/44783/33676 44856/44892/33785 +f 44857/44893/33783 44858/44894/33784 44859/44895/33786 +f 44857/44893/33783 44859/44895/33786 44860/44896/33787 +f 44861/44897/33788 44862/44898/33789 44863/44899/33790 +f 44861/44897/33788 44863/44899/33790 44864/44900/33791 +f 44865/44901/33792 44619/44665/33559 44622/44668/33562 +f 44865/44901/33792 44622/44668/33562 44866/44902/33793 +f 44866/44902/33793 44622/44668/33562 44627/44673/33567 +f 44866/44902/33793 44627/44673/33567 44867/44903/33794 +f 44864/44900/33791 44863/44899/33790 44868/44904/33795 +f 44864/44900/33791 44868/44904/33795 44869/44905/33796 +f 44542/44588/33488 44541/44587/33487 44870/44906/33797 +f 44542/44588/33488 44870/44906/33797 44850/44886/33779 +f 44541/44587/33487 44540/44586/33486 44871/44907/33798 +f 44541/44587/33487 44871/44907/33798 44870/44906/33797 +f 44870/44906/33797 44871/44907/33798 44817/44857/33750 +f 44870/44906/33797 44817/44857/33750 44872/44908/33799 +f 44850/44886/33779 44870/44906/33797 44872/44908/33799 +f 44850/44886/33779 44872/44908/33799 44851/44887/33780 +f 44707/44753/33645 44873/44909/33800 44874/44910/33801 +f 44707/44753/33645 44874/44910/33801 44708/44754/33646 +f 44873/44909/33800 44875/44911/33802 44876/44912/33803 +f 44873/44909/33800 44876/44912/33803 44874/44910/33801 +f 44874/44910/33801 44876/44912/33803 44877/44913/33804 +f 44874/44910/33801 44877/44913/33804 44878/44914/33805 +f 44708/44754/33646 44874/44910/33801 44878/44914/33805 +f 44708/44754/33646 44878/44914/33805 44709/44755/33647 +f 44220/44266/33198 44223/44269/33201 44879/44915/33806 +f 44220/44266/33198 44879/44915/33806 44880/44916/33807 +f 44223/44269/33201 44225/44271/33203 44881/44917/33808 +f 44223/44269/33201 44881/44917/33808 44879/44915/33806 +f 44879/44915/33806 44881/44917/33808 44882/44918/33809 +f 44879/44915/33806 44882/44918/33809 44883/44919/33810 +f 44880/44916/33807 44879/44915/33806 44883/44919/33810 +f 44880/44916/33807 44883/44919/33810 44884/44920/33811 +f 44540/44586/33486 44558/44604/33504 44885/44921/33812 +f 44540/44586/33486 44885/44921/33812 44871/44907/33798 +f 44558/44604/33504 44557/44603/33503 44886/44922/33813 +f 44558/44604/33504 44886/44922/33813 44885/44921/33812 +f 44885/44921/33812 44886/44922/33813 44820/44860/33753 +f 44885/44921/33812 44820/44860/33753 44818/44858/33751 +f 44871/44907/33798 44885/44921/33812 44818/44858/33751 +f 44871/44907/33798 44818/44858/33751 44817/44857/33750 +f 44887/44923/33732 44888/44924/33738 44889/44925/33814 +f 44887/44923/33732 44889/44925/33814 44890/44926/33815 +f 44888/44924/33738 44843/44879/33772 44846/44882/33775 +f 44888/44924/33738 44846/44882/33775 44889/44925/33814 +f 44889/44925/33814 44846/44882/33775 44848/44884/33777 +f 44889/44925/33814 44848/44884/33777 44891/44927/33816 +f 44890/44926/33815 44889/44925/33814 44891/44927/33816 +f 44890/44926/33815 44891/44927/33816 44892/44928/33817 +f 44893/44929/33818 44894/44930/33819 44895/44931/33820 +f 44893/44929/33818 44895/44931/33820 44896/44932/33821 +f 44894/44930/33819 44897/44933/33528 44898/44934/33822 +f 44894/44930/33819 44898/44934/33822 44895/44931/33820 +f 44895/44931/33820 44898/44934/33822 44899/44935/33823 +f 44895/44931/33820 44899/44935/33823 44900/44936/33824 +f 44896/44932/33821 44895/44931/33820 44900/44936/33824 +f 44896/44932/33821 44900/44936/33824 44901/44937/33825 +f 44902/44938/33826 44903/44939/33566 44904/44940/33827 +f 44902/44938/33826 44904/44940/33827 44905/44941/33794 +f 44903/44939/33566 44906/44942/33828 44907/44943/33829 +f 44903/44939/33566 44907/44943/33829 44904/44940/33827 +f 44904/44940/33827 44907/44943/33829 44908/44944/33830 +f 44904/44940/33827 44908/44944/33830 44909/44945/33831 +f 44905/44941/33794 44904/44940/33827 44909/44945/33831 +f 44905/44941/33794 44909/44945/33831 44910/44946/33796 +f 44906/44942/33828 44911/44947/33832 44912/44948/33833 +f 44906/44942/33828 44912/44948/33833 44907/44943/33829 +f 44911/44947/33832 44913/44949/33834 44914/44950/33835 +f 44911/44947/33832 44914/44950/33835 44912/44948/33833 +f 44912/44948/33833 44914/44950/33835 44915/44951/33612 +f 44912/44948/33833 44915/44951/33612 44916/44952/33836 +f 44907/44943/33829 44912/44948/33833 44916/44952/33836 +f 44907/44943/33829 44916/44952/33836 44908/44944/33830 +f 44913/44949/33834 44917/44953/33837 44918/44954/33838 +f 44913/44949/33834 44918/44954/33838 44914/44950/33835 +f 44917/44953/33837 44919/44955/33839 44920/44956/33840 +f 44917/44953/33837 44920/44956/33840 44918/44954/33838 +f 44918/44954/33838 44920/44956/33840 44921/44957/33614 +f 44918/44954/33838 44921/44957/33614 44922/44958/33841 +f 44914/44950/33835 44918/44954/33838 44922/44958/33841 +f 44914/44950/33835 44922/44958/33841 44915/44951/33612 +f 44923/44959/33842 44924/44960/33843 44925/44961/33844 +f 44923/44959/33842 44925/44961/33844 44926/44962/33845 +f 44924/44960/33843 44893/44929/33818 44896/44932/33821 +f 44924/44960/33843 44896/44932/33821 44925/44961/33844 +f 44925/44961/33844 44896/44932/33821 44901/44937/33825 +f 44925/44961/33844 44901/44937/33825 44927/44963/33846 +f 44926/44962/33845 44925/44961/33844 44927/44963/33846 +f 44926/44962/33845 44927/44963/33846 44928/44964/33847 +f 44929/44965/33848 44930/44966/33849 44931/44967/33850 +f 44929/44965/33848 44931/44967/33850 44932/44968/33851 +f 44930/44966/33849 44923/44959/33842 44926/44962/33845 +f 44930/44966/33849 44926/44962/33845 44931/44967/33850 +f 44931/44967/33850 44926/44962/33845 44928/44964/33847 +f 44931/44967/33850 44928/44964/33847 44933/44969/33852 +f 44932/44968/33851 44931/44967/33850 44933/44969/33852 +f 44932/44968/33851 44933/44969/33852 44934/44970/33853 +f 44935/44971/33854 44936/44972/33855 44937/44973/33856 +f 44935/44971/33854 44937/44973/33856 44938/44974/33857 +f 44936/44972/33855 44929/44965/33848 44932/44968/33851 +f 44936/44972/33855 44932/44968/33851 44937/44973/33856 +f 44937/44973/33856 44932/44968/33851 44934/44970/33853 +f 44937/44973/33856 44934/44970/33853 44939/44975/33858 +f 44938/44974/33857 44937/44973/33856 44939/44975/33858 +f 44938/44974/33857 44939/44975/33858 44940/44976/33859 +f 44919/44955/33839 44941/44977/33860 44942/44978/33861 +f 44919/44955/33839 44942/44978/33861 44920/44956/33840 +f 44941/44977/33860 44935/44971/33854 44938/44974/33857 +f 44941/44977/33860 44938/44974/33857 44942/44978/33861 +f 44942/44978/33861 44938/44974/33857 44940/44976/33859 +f 44942/44978/33861 44940/44976/33859 44943/44979/33776 +f 44920/44956/33840 44942/44978/33861 44943/44979/33776 +f 44920/44956/33840 44943/44979/33776 44921/44957/33614 +f 44672/44718/33610 44944/44980/33761 44945/44981/33862 +f 44672/44718/33610 44945/44981/33862 44673/44719/33611 +f 44944/44980/33761 44946/44982/33863 44947/44983/33864 +f 44944/44980/33761 44947/44983/33864 44945/44981/33862 +f 44945/44981/33862 44947/44983/33864 44948/44984/33830 +f 44945/44981/33862 44948/44984/33830 44949/44985/33865 +f 44673/44719/33611 44945/44981/33862 44949/44985/33865 +f 44673/44719/33611 44949/44985/33865 44674/44720/33612 +f 44950/44986/33866 44951/44987/33867 44952/44988/33868 +f 44950/44986/33866 44952/44988/33868 44953/44989/33869 +f 44951/44987/33867 44572/44618/33518 44575/44621/33521 +f 44951/44987/33867 44575/44621/33521 44952/44988/33868 +f 44952/44988/33868 44575/44621/33521 44583/44629/33528 +f 44952/44988/33868 44583/44629/33528 44954/44990/33870 +f 44953/44989/33869 44952/44988/33868 44954/44990/33870 +f 44953/44989/33869 44954/44990/33870 44955/44991/33871 +f 44956/44992/33872 44957/44993/33873 44958/44994/33874 +f 44956/44992/33872 44958/44994/33874 44959/44995/33875 +f 44957/44993/33873 44950/44986/33866 44953/44989/33869 +f 44957/44993/33873 44953/44989/33869 44958/44994/33874 +f 44958/44994/33874 44953/44989/33869 44955/44991/33871 +f 44958/44994/33874 44955/44991/33871 44960/44996/33876 +f 44959/44995/33875 44958/44994/33874 44960/44996/33876 +f 44959/44995/33875 44960/44996/33876 44961/44997/33877 +f 44946/44982/33863 44962/44998/33878 44963/44999/33879 +f 44946/44982/33863 44963/44999/33879 44947/44983/33864 +f 44962/44998/33878 44861/44897/33788 44864/44900/33791 +f 44962/44998/33878 44864/44900/33791 44963/44999/33879 +f 44963/44999/33879 44864/44900/33791 44869/44905/33796 +f 44963/44999/33879 44869/44905/33796 44964/45000/33880 +f 44947/44983/33864 44963/44999/33879 44964/45000/33880 +f 44947/44983/33864 44964/45000/33880 44948/44984/33830 +f 44965/45001/33866 44966/45002/33881 44967/45003/33882 +f 44965/45001/33866 44967/45003/33882 44968/45004/33883 +f 44966/45002/33881 44956/44992/33872 44959/44995/33875 +f 44966/45002/33881 44959/44995/33875 44967/45003/33882 +f 44967/45003/33882 44959/44995/33875 44961/44997/33877 +f 44967/45003/33882 44961/44997/33877 44969/45005/33884 +f 44968/45004/33883 44967/45003/33882 44969/45005/33884 +f 44968/45004/33883 44969/45005/33884 44970/45006/33885 +f 44577/44623/33522 44971/45007/33886 44972/45008/33887 +f 44577/44623/33522 44972/45008/33887 44578/44624/33523 +f 44971/45007/33886 44973/45009/33888 44974/45010/33889 +f 44971/45007/33886 44974/45010/33889 44972/45008/33887 +f 44972/45008/33887 44974/45010/33889 44975/45011/33890 +f 44972/45008/33887 44975/45011/33890 44976/45012/33891 +f 44578/44624/33523 44972/45008/33887 44976/45012/33891 +f 44578/44624/33523 44976/45012/33891 44580/44626/33525 +f 44973/45009/33888 44977/45013/33892 44978/45014/33893 +f 44973/45009/33888 44978/45014/33893 44974/45010/33889 +f 44977/45013/33892 44979/45015/33894 44980/45016/33895 +f 44977/45013/33892 44980/45016/33895 44978/45014/33893 +f 44978/45014/33893 44980/45016/33895 44981/45017/33847 +f 44978/45014/33893 44981/45017/33847 44982/45018/33896 +f 44974/45010/33889 44978/45014/33893 44982/45018/33896 +f 44974/45010/33889 44982/45018/33896 44975/45011/33890 +f 44983/45019/33897 44984/45020/33898 44985/45021/33899 +f 44983/45019/33897 44985/45021/33899 44986/45022/33900 +f 44984/45020/33898 44965/45001/33866 44968/45004/33883 +f 44984/45020/33898 44968/45004/33883 44985/45021/33899 +f 44985/45021/33899 44968/45004/33883 44970/45006/33885 +f 44985/45021/33899 44970/45006/33885 44987/45023/33901 +f 44986/45022/33900 44985/45021/33899 44987/45023/33901 +f 44986/45022/33900 44987/45023/33901 44988/45024/33854 +f 44979/45015/33894 44989/45025/33902 44990/45026/33903 +f 44979/45015/33894 44990/45026/33903 44980/45016/33895 +f 44989/45025/33902 44887/44923/33732 44890/44926/33815 +f 44989/45025/33902 44890/44926/33815 44990/45026/33903 +f 44990/45026/33903 44890/44926/33815 44892/44928/33817 +f 44990/45026/33903 44892/44928/33817 44991/45027/33904 +f 44980/45016/33895 44990/45026/33903 44991/45027/33904 +f 44980/45016/33895 44991/45027/33904 44981/45017/33847 +f 44875/44911/33802 44992/45028/33905 44993/45029/33906 +f 44875/44911/33802 44993/45029/33906 44876/44912/33803 +f 44992/45028/33905 44983/45019/33897 44986/45022/33900 +f 44992/45028/33905 44986/45022/33900 44993/45029/33906 +f 44993/45029/33906 44986/45022/33900 44988/45024/33854 +f 44993/45029/33906 44988/45024/33854 44994/45030/33860 +f 44876/44912/33803 44993/45029/33906 44994/45030/33860 +f 44876/44912/33803 44994/45030/33860 44877/44913/33804 +f 44307/44353/33271 44305/44351/33269 44995/45031/33907 +f 44307/44353/33271 44995/45031/33907 44996/45032/33908 +f 44305/44351/33269 44304/44350/33268 44997/45033/33909 +f 44305/44351/33269 44997/45033/33909 44995/45031/33907 +f 44995/45031/33907 44997/45033/33909 44983/45019/33897 +f 44995/45031/33907 44983/45019/33897 44992/45028/33905 +f 44996/45032/33908 44995/45031/33907 44992/45028/33905 +f 44996/45032/33908 44992/45028/33905 44875/44911/33802 +f 44998/44117/33007 45000/44120/33910 44887/44923/33732 +f 44998/44117/33007 44887/44923/33732 44989/45025/33902 +f 44999/44118/33911 44998/44117/33007 44989/45025/33902 +f 44999/44118/33911 44989/45025/33902 44979/45015/33894 +f 44304/44350/33268 44329/44375/33292 45001/45034/33912 +f 44304/44350/33268 45001/45034/33912 44997/45033/33909 +f 44329/44375/33292 44316/44362/33280 45002/45035/33913 +f 44329/44375/33292 45002/45035/33913 45001/45034/33912 +f 45001/45034/33912 45002/45035/33913 44965/45001/33866 +f 45001/45034/33912 44965/45001/33866 44984/45020/33898 +f 44997/45033/33909 45001/45034/33912 44984/45020/33898 +f 44997/45033/33909 44984/45020/33898 44983/45019/33897 +f 44785/44830/33720 45003/44121/33008 45004/45036/33914 +f 44785/44830/33720 45004/45036/33914 45005/45037/33014 +f 45003/44121/33008 44999/44118/33911 45004/45036/33914 +f 45004/45036/33914 44999/44118/33911 44979/45015/33894 +f 45004/45036/33914 44979/45015/33894 44977/45013/33892 +f 45005/45037/33014 45004/45036/33914 44977/45013/33892 +f 45005/45037/33014 44977/45013/33892 44973/45009/33888 +f 44789/44834/33724 44786/44831/33721 45006/45038/33915 +f 44789/44834/33724 45006/45038/33915 45007/45039/33916 +f 44786/44831/33721 44785/44830/33720 45005/45037/33014 +f 44786/44831/33721 45005/45037/33014 45006/45038/33915 +f 45006/45038/33915 45005/45037/33014 44973/45009/33888 +f 45006/45038/33915 44973/45009/33888 44971/45007/33886 +f 45007/45039/33916 45006/45038/33915 44971/45007/33886 +f 45007/45039/33916 44971/45007/33886 44577/44623/33522 +f 44316/44362/33280 44314/44360/33278 45008/45040/33917 +f 44316/44362/33280 45008/45040/33917 45002/45035/33913 +f 44314/44360/33278 44313/44359/33277 45009/45041/33918 +f 44314/44360/33278 45009/45041/33918 45008/45040/33917 +f 45008/45040/33917 45009/45041/33918 44956/44992/33872 +f 45008/45040/33917 44956/44992/33872 44966/45002/33881 +f 45002/45035/33913 45008/45040/33917 44966/45002/33881 +f 45002/45035/33913 44966/45002/33881 44965/45001/33866 +f 44830/44867/33022 44836/44872/33765 45010/45042/33919 +f 44830/44867/33022 45010/45042/33919 45011/44126/33025 +f 44836/44872/33765 44642/44688/33581 45012/45043/33920 +f 44836/44872/33765 45012/45043/33920 45010/45042/33919 +f 45010/45042/33919 45012/45043/33920 44861/44897/33788 +f 45010/45042/33919 44861/44897/33788 44962/44998/33878 +f 45011/44126/33025 45010/45042/33919 44962/44998/33878 +f 45011/44126/33025 44962/44998/33878 44946/44982/33863 +f 44313/44359/33277 44332/44378/33294 45013/45044/33921 +f 44313/44359/33277 45013/45044/33921 45009/45041/33918 +f 44332/44378/33294 44289/44335/33255 45014/45045/33922 +f 44332/44378/33294 45014/45045/33922 45013/45044/33921 +f 45013/45044/33921 45014/45045/33922 44950/44986/33866 +f 45013/45044/33921 44950/44986/33866 44957/44993/33873 +f 45009/45041/33918 45013/45044/33921 44957/44993/33873 +f 45009/45041/33918 44957/44993/33873 44956/44992/33872 +f 44289/44335/33255 44287/44333/33253 45015/45046/33923 +f 44289/44335/33255 45015/45046/33923 45014/45045/33922 +f 44287/44333/33253 44286/44332/33252 45016/45047/33924 +f 44287/44333/33253 45016/45047/33924 45015/45046/33923 +f 45015/45046/33923 45016/45047/33924 44572/44618/33518 +f 45015/45046/33923 44572/44618/33518 44951/44987/33867 +f 45014/45045/33922 45015/45046/33923 44951/44987/33867 +f 45014/45045/33922 44951/44987/33867 44950/44986/33866 +f 44831/44123/33760 44830/44867/33022 45011/44126/33025 +f 45017/44124/33925 45011/44126/33025 44946/44982/33863 +f 45017/44124/33925 44946/44982/33863 44944/44980/33761 +f 45018/44125/33926 45017/44124/33925 44944/44980/33761 +f 45018/44125/33926 44944/44980/33761 44672/44718/33610 +f 44804/44127/33737 44803/44130/33008 45020/44129/33017 +f 45019/44128/33927 45020/44129/33928 44843/44879/33772 +f 45019/44128/33927 44843/44879/33772 44888/44924/33738 +f 45000/44120/33910 45019/44128/33927 44888/44924/33738 +f 45000/44120/33910 44888/44924/33738 44887/44923/33732 +f 44295/44341/33260 44326/44372/33289 45021/45048/33929 +f 44295/44341/33260 45021/45048/33929 45022/45049/33930 +f 44326/44372/33289 44307/44353/33271 44996/45032/33908 +f 44326/44372/33289 44996/45032/33908 45021/45048/33929 +f 45021/45048/33929 44996/45032/33908 44875/44911/33802 +f 45021/45048/33929 44875/44911/33802 44873/44909/33800 +f 45022/45049/33930 45021/45048/33929 44873/44909/33800 +f 45022/45049/33930 44873/44909/33800 44707/44753/33645 +f 44642/44688/33581 44641/44687/33580 45023/45050/33931 +f 44642/44688/33581 45023/45050/33931 45012/45043/33920 +f 45024/45051/33579 44322/44368/33285 45025/45052/33932 +f 45024/45051/33579 45025/45052/33932 45026/45053/33933 +f 45026/45053/33933 45025/45052/33932 44619/44665/33559 +f 45026/45053/33933 44619/44665/33559 44865/44901/33792 +f 45012/45043/33920 45023/45050/33931 44862/44898/33789 +f 45012/45043/33920 44862/44898/33789 44861/44897/33788 +f 45028/44132/33019 45029/44134/33023 44668/44714/33606 +f 45028/44132/33019 44668/44714/33606 44844/44880/33773 +f 45020/44129/33928 45028/44132/33019 44844/44880/33773 +f 45020/44129/33928 44844/44880/33773 44843/44879/33772 +f 44298/44344/33263 44296/44342/33261 45030/45054/33934 +f 44298/44344/33263 45030/45054/33934 45031/45055/33935 +f 44296/44342/33261 44295/44341/33260 45022/45049/33930 +f 44296/44342/33261 45022/45049/33930 45030/45054/33934 +f 45030/45054/33934 45022/45049/33930 44707/44753/33645 +f 45030/45054/33934 44707/44753/33645 44705/44751/33643 +f 45031/45055/33935 45030/45054/33934 44705/44751/33643 +f 45031/45055/33935 44705/44751/33643 44623/44669/33563 +f 44825/44133/33756 44822/44136/33754 45032/44135/33936 +f 44822/44136/33754 45018/44125/33926 45032/44135/33936 +f 45032/44135/33936 45018/44125/33926 44672/44718/33610 +f 45032/44135/33936 44672/44718/33610 44669/44715/33607 +f 45029/44134/33023 45032/44135/33936 44669/44715/33607 +f 45029/44134/33023 44669/44715/33607 44668/44714/33606 +f 44322/44368/33285 44320/44366/33284 45033/45056/33937 +f 44322/44368/33285 45033/45056/33937 45025/45052/33932 +f 44320/44366/33284 44298/44344/33263 45031/45055/33935 +f 44320/44366/33284 45031/45055/33935 45033/45056/33937 +f 45033/45056/33937 45031/45055/33935 44623/44669/33563 +f 45033/45056/33937 44623/44669/33563 44620/44666/33560 +f 45025/45052/33932 45033/45056/33937 44620/44666/33560 +f 45025/45052/33932 44620/44666/33560 44619/44665/33559 +f 44286/44332/33252 45034/45057/33938 45035/45058/33939 +f 44286/44332/33252 45035/45058/33939 45016/45047/33924 +f 45036/45059/33940 44789/44834/33724 45007/45039/33916 +f 45036/45059/33940 45007/45039/33916 45037/45060/33941 +f 45037/45060/33941 45007/45039/33916 44577/44623/33522 +f 45037/45060/33941 44577/44623/33522 44576/44622/33519 +f 45016/45047/33924 45035/45058/33939 44573/44619/33519 +f 45016/45047/33924 44573/44619/33519 44572/44618/33518 +f 44225/44271/33203 44324/44370/33287 45038/45061/33942 +f 44225/44271/33203 45038/45061/33942 44881/44917/33808 +f 44323/44369/33286 44322/44368/33285 45039/45062/33575 +f 44323/44369/33286 45039/45062/33575 45040/45063/33943 +f 45041/45064/33943 44635/44681/33575 44634/44680/33574 +f 45041/45064/33943 44634/44680/33574 45042/45065/33944 +f 45043/45066/33808 45041/45064/33943 45042/45065/33944 +f 45043/45066/33808 45042/45065/33944 45044/45067/33945 +f 44600/44646/33542 45045/45068/33946 45046/45069/33947 +f 44600/44646/33542 45046/45069/33947 44601/44647/33543 +f 45045/45068/33946 44646/44692/33584 44649/44695/33587 +f 45045/45068/33946 44649/44695/33587 45046/45069/33947 +f 45046/45069/33947 44649/44695/33587 44478/44524/33440 +f 45046/45069/33947 44478/44524/33440 44532/44578/33478 +f 44601/44647/33543 45046/45069/33947 44532/44578/33478 +f 44601/44647/33543 44532/44578/33478 44536/44582/33482 +f 44825/44133/33756 45027/44131/33948 45047/45070/33773 +f 44825/44133/33756 45047/45070/33773 44826/44863/33606 +f 45027/44131/33948 44803/44130/33008 44806/44846/33739 +f 45027/44131/33948 44806/44846/33739 45047/45070/33773 +f 45047/45070/33773 44806/44846/33739 44808/44848/33741 +f 45047/45070/33773 44808/44848/33741 45048/45071/33949 +f 44826/44863/33606 45047/45070/33773 45048/45071/33949 +f 44826/44863/33606 45048/45071/33949 44827/44864/33757 +f 44813/44853/33746 45049/44138/33950 45050/45072/33951 +f 44813/44853/33746 45050/45072/33951 44814/44854/33747 +f 45049/44138/33950 45051/44137/33952 45052/45073/33953 +f 45049/44138/33950 45052/45073/33953 45050/45072/33951 +f 45053/45074/33954 45054/45075/33955 44851/44887/33780 +f 45053/45074/33954 44851/44887/33780 44872/44908/33799 +f 44816/44856/33749 45053/45074/33954 44872/44908/33799 +f 44816/44856/33749 44872/44908/33799 44817/44857/33750 +f 45051/44137/33952 45055/44143/33041 45056/45076/33956 +f 45051/44137/33952 45056/45076/33956 45052/45073/33953 +f 45055/44143/33041 45057/44142/33957 45058/45077/33958 +f 45055/44143/33041 45058/45077/33958 45056/45076/33956 +f 45059/45078/33959 45060/45079/33960 44841/44877/33770 +f 45059/45078/33959 44841/44877/33770 44852/44888/33781 +f 45054/45075/33955 45059/45078/33959 44852/44888/33781 +f 45054/45075/33955 44852/44888/33781 44851/44887/33780 +f 45057/44142/33957 45061/44147/33961 45062/45080/33962 +f 45057/44142/33957 45062/45080/33962 45058/45077/33958 +f 45061/44147/33961 45063/44146/33044 45064/45081/33963 +f 45061/44147/33961 45064/45081/33963 45062/45080/33962 +f 45065/45082/33964 45066/45083/33965 44587/44633/33532 +f 45065/45082/33964 44587/44633/33532 44842/44878/33771 +f 45060/45079/33960 45065/45082/33964 44842/44878/33771 +f 45060/45079/33960 44842/44878/33771 44841/44877/33770 +f 45063/44146/33044 45067/44151/33055 45068/45084/33966 +f 45063/44146/33044 45068/45084/33966 45064/45081/33963 +f 45067/44151/33055 45069/44150/33967 45070/45085/33968 +f 45067/44151/33055 45070/45085/33968 45068/45084/33966 +f 45071/45086/33969 45072/45087/33970 44589/44635/33534 +f 45071/45086/33969 44589/44635/33534 44588/44634/33533 +f 45066/45083/33965 45071/45086/33969 44588/44634/33533 +f 45066/45083/33965 44588/44634/33533 44587/44633/33532 +f 45069/44150/33967 45073/44155/33065 45074/45088/33971 +f 45069/44150/33967 45074/45088/33971 45070/45085/33968 +f 45073/44155/33065 45075/44154/33972 45076/45089/33973 +f 45073/44155/33065 45076/45089/33973 45074/45088/33971 +f 45077/45090/33971 45078/45091/33974 44655/44701/33593 +f 45077/45090/33971 44655/44701/33593 44654/44700/33592 +f 45072/45087/33970 45077/45090/33971 44654/44700/33592 +f 45072/45087/33970 44654/44700/33592 44589/44635/33534 +f 45075/44154/33972 45079/44159/33975 45080/45092/33976 +f 45075/44154/33972 45080/45092/33976 45076/45089/33973 +f 45079/44159/33975 44729/44158/33667 44732/44777/33670 +f 45079/44159/33975 44732/44777/33670 45080/45092/33976 +f 45081/45093/33977 44734/44779/33672 44695/44741/33633 +f 45081/45093/33977 44695/44741/33633 44694/44740/33632 +f 45078/45091/33974 45081/45093/33977 44694/44740/33632 +f 45078/45091/33974 44694/44740/33632 44655/44701/33593 +f 44798/44115/33733 45003/44121/33008 45082/45094/33978 +f 44798/44115/33733 45082/45094/33978 44799/44841/33732 +f 45003/44121/33008 44785/44830/33720 44788/44833/33723 +f 45003/44121/33008 44788/44833/33723 45082/45094/33978 +f 45082/45094/33978 44788/44833/33723 44793/44838/33728 +f 45082/45094/33978 44793/44838/33728 45083/45095/33979 +f 44799/44841/33732 45082/45094/33978 45083/45095/33979 +f 44799/44841/33732 45083/45095/33979 44800/44842/33734 +f 44557/44603/33503 45084/45096/33980 45085/45097/33981 +f 44557/44603/33503 45085/45097/33981 44886/44922/33813 +f 45084/45096/33980 45086/45098/33982 45087/45099/33983 +f 45084/45096/33980 45087/45099/33983 45085/45097/33981 +f 45088/45100/33981 45089/45101/33984 44809/44849/33742 +f 45088/45100/33981 44809/44849/33742 44812/44852/33745 +f 44886/44922/33813 45085/45097/33981 44819/44859/33752 +f 44886/44922/33813 44819/44859/33752 44820/44860/33753 +f 44616/44662/33557 45090/45102/33985 45091/45103/33986 +f 44616/44662/33557 45091/45103/33986 44617/44663/33558 +f 45090/45102/33985 45092/45104/33987 45093/45105/33988 +f 45090/45102/33985 45093/45105/33988 45091/45103/33986 +f 45091/45103/33986 45093/45105/33988 44469/44515/33431 +f 45091/45103/33986 44469/44515/33431 44741/44786/33679 +f 44617/44663/33558 45091/45103/33986 44741/44786/33679 +f 44617/44663/33558 44741/44786/33679 44493/44539/33451 +f 44702/44748/33640 45094/45106/33989 45095/45107/33990 +f 44702/44748/33640 45095/45107/33990 44703/44749/33641 +f 45096/45108/33989 45097/45109/33991 45098/45110/33992 +f 45096/45108/33989 45098/45110/33992 45099/45111/33993 +f 45099/45111/33993 45098/45110/33992 44340/44386/33302 +f 45099/45111/33993 44340/44386/33302 44489/44535/33448 +f 44703/44749/33641 45095/45107/33990 44488/44534/33448 +f 44703/44749/33641 44488/44534/33448 44487/44533/33447 +f 44128/44100/33114 44126/44099/32987 45100/45112/33994 +f 44128/44100/33114 45100/45112/33994 44630/44676/33570 +f 44126/44099/32987 44122/44184/33106 44720/44766/33658 +f 44126/44099/32987 44720/44766/33658 45100/45112/33994 +f 45100/45112/33994 44720/44766/33658 44722/44768/33660 +f 45100/45112/33994 44722/44768/33660 45101/45113/33995 +f 44630/44676/33570 45100/45112/33994 45101/45113/33995 +f 44630/44676/33570 45101/45113/33995 44631/44677/33571 +f 44111/44175/33096 44114/44178/33099 45102/45114/33996 +f 44111/44175/33096 45102/45114/33996 44568/44614/33514 +f 44114/44178/33099 44119/44183/33104 44716/44762/33654 +f 44114/44178/33099 44716/44762/33654 45102/45114/33996 +f 45102/45114/33996 44716/44762/33654 44718/44764/33656 +f 45102/45114/33996 44718/44764/33656 45103/45115/33997 +f 44568/44614/33514 45102/45114/33996 45103/45115/33997 +f 44568/44614/33514 45103/45115/33997 44569/44615/33515 +f 45092/45104/33987 45104/45116/33998 45105/45117/33999 +f 45092/45104/33987 45105/45117/33999 45093/45105/33988 +f 45104/45116/33998 45106/45118/34000 45107/45119/34001 +f 45104/45116/33998 45107/45119/34001 45105/45117/33999 +f 45105/45117/33999 45107/45119/34001 44473/44519/33435 +f 45105/45117/33999 44473/44519/33435 44470/44516/33432 +f 45093/45105/33988 45105/45117/33999 44470/44516/33432 +f 45093/45105/33988 44470/44516/33432 44469/44515/33431 +f 44683/44729/33621 45108/45120/34002 45109/45121/34003 +f 44683/44729/33621 45109/45121/34003 44684/44730/33622 +f 45108/45120/34002 45110/45122/34004 45111/45123/34005 +f 45108/45120/34002 45111/45123/34005 45109/45121/34003 +f 45109/45121/34003 45111/45123/34005 44387/44433/33349 +f 45109/45121/34003 44387/44433/33349 44389/44435/33351 +f 44684/44730/33622 45109/45121/34003 44389/44435/33351 +f 44684/44730/33622 44389/44435/33351 44343/44389/33305 +f 44105/44170/33090 44150/44113/33128 45112/45124/34006 +f 44105/44170/33090 45112/45124/34006 44697/44743/33635 +f 44150/44113/33128 44146/44111/33002 44724/44770/33662 +f 44150/44113/33128 44724/44770/33662 45112/45124/34006 +f 45112/45124/34006 44724/44770/33662 44726/44772/33664 +f 45112/45124/34006 44726/44772/33664 45113/45125/34007 +f 44697/44743/33635 45112/45124/34006 45113/45125/34007 +f 44697/44743/33635 45113/45125/34007 44698/44744/33636 +f 44249/44295/33222 44772/44817/33707 45114/45126/34008 +f 44249/44295/33222 45114/45126/34008 44592/44638/33537 +f 44772/44817/33707 44220/44266/33198 44880/44916/33807 +f 44772/44817/33707 44880/44916/33807 45114/45126/34008 +f 45114/45126/34008 44880/44916/33807 44884/44920/33811 +f 45114/45126/34008 44884/44920/33811 45115/45127/34009 +f 44592/44638/33537 45114/45126/34008 45115/45127/34009 +f 44592/44638/33537 45115/45127/34009 45116/45128/34010 +f 45110/45122/34004 45117/45129/34011 45118/45130/34012 +f 45110/45122/34004 45118/45130/34012 45111/45123/34005 +f 45117/45129/34011 45119/45131/34013 45120/45132/34014 +f 45117/45129/34011 45120/45132/34014 45118/45130/34012 +f 45118/45130/34012 45120/45132/34014 44381/44427/33343 +f 45118/45130/34012 44381/44427/33343 44383/44429/33345 +f 45111/45123/34005 45118/45130/34012 44383/44429/33345 +f 45111/45123/34005 44383/44429/33345 44387/44433/33349 +f 44237/44283/33213 44236/44282/33212 45121/45133/34015 +f 44237/44283/33213 45121/45133/34015 44688/44734/33626 +f 44234/44280/33212 44102/44167/33087 44678/44724/33616 +f 44234/44280/33212 44678/44724/33616 45122/45134/34016 +f 45122/45134/34016 44678/44724/33616 44680/44726/33618 +f 45122/45134/34016 44680/44726/33618 45123/45135/34017 +f 45124/45136/34018 45125/45137/34016 45126/45138/34019 +f 45124/45136/34018 45126/45138/34019 45127/45139/34020 +f 45119/45131/34013 45128/45140/34021 45129/45141/34022 +f 45119/45131/34013 45129/45141/34022 45120/45132/34014 +f 45128/45140/34021 45130/45142/34023 45131/45143/34024 +f 45128/45140/34021 45131/45143/34024 45129/45141/34022 +f 45129/45141/34022 45131/45143/34024 44375/44421/33337 +f 45129/45141/34022 44375/44421/33337 44377/44423/33339 +f 45120/45132/34014 45129/45141/34022 44377/44423/33339 +f 45120/45132/34014 44377/44423/33339 44381/44427/33343 +f 45097/45109/33991 45132/45144/34025 45133/45145/34026 +f 45097/45109/33991 45133/45145/34026 45098/45110/33992 +f 45132/45144/34025 44662/44708/33600 44665/44711/33603 +f 45132/45144/34025 44665/44711/33603 45133/45145/34026 +f 45133/45145/34026 44665/44711/33603 44342/44388/33304 +f 45133/45145/34026 44342/44388/33304 44341/44387/33303 +f 45098/45110/33992 45133/45145/34026 44341/44387/33303 +f 45098/45110/33992 44341/44387/33303 44340/44386/33302 +f 45130/45142/34023 45134/45146/34027 45135/45147/34028 +f 45130/45142/34023 45135/45147/34028 45131/45143/34024 +f 45134/45146/34027 45136/45148/34029 45137/45149/34030 +f 45134/45146/34027 45137/45149/34030 45135/45147/34028 +f 45135/45147/34028 45137/45149/34030 44369/44415/33331 +f 45135/45147/34028 44369/44415/33331 44371/44417/33333 +f 45131/45143/34024 45135/45147/34028 44371/44417/33333 +f 45131/45143/34024 44371/44417/33333 44375/44421/33337 +f 45106/45118/34000 45138/45150/34031 45139/45151/34032 +f 45106/45118/34000 45139/45151/34032 45107/45119/34001 +f 45138/45150/34031 45086/45098/33982 45084/45096/33980 +f 45138/45150/34031 45084/45096/33980 45139/45151/34032 +f 45139/45151/34032 45084/45096/33980 44557/44603/33503 +f 45139/45151/34032 44557/44603/33503 44556/44602/33502 +f 45107/45119/34001 45139/45151/34032 44556/44602/33502 +f 45107/45119/34001 44556/44602/33502 44473/44519/33435 +f 45140/45152/34033 45141/45153/34034 45142/45154/34035 +f 45140/45152/34033 45142/45154/34035 45143/45155/34036 +f 45141/45153/34034 45144/45156/34037 45145/45157/34038 +f 45141/45153/34034 45145/45157/34038 45142/45154/34035 +f 45142/45154/34035 45145/45157/34038 44353/44399/33315 +f 45142/45154/34035 44353/44399/33315 44350/44396/33312 +f 45143/45155/34036 45142/45154/34035 44350/44396/33312 +f 45143/45155/34036 44350/44396/33312 44349/44395/33311 +f 45146/45158/34039 44857/44893/33783 45147/45159/34040 +f 45146/45158/34039 45147/45159/34040 45148/45160/33938 +f 44857/44893/33783 44860/44896/33787 45149/45161/34041 +f 44857/44893/33783 45149/45161/34041 45147/45159/34040 +f 45150/45162/34040 45151/45163/34041 44791/44836/33726 +f 45150/45162/34040 44791/44836/33726 44790/44835/33725 +f 45036/45059/33940 45150/45162/34040 44790/44835/33725 +f 45036/45059/33940 44790/44835/33725 44789/44834/33724 +f 45136/45148/34029 45152/45164/34042 45153/45165/34043 +f 45136/45148/34029 45153/45165/34043 45137/45149/34030 +f 45152/45164/34042 45154/45166/34044 45155/45167/34045 +f 45152/45164/34042 45155/45167/34045 45153/45165/34043 +f 45153/45165/34043 45155/45167/34045 44363/44409/33325 +f 45153/45165/34043 44363/44409/33325 44365/44411/33327 +f 45137/45149/34030 45153/45165/34043 44365/44411/33327 +f 45137/45149/34030 44365/44411/33327 44369/44415/33331 +f 45144/45156/34037 45156/45168/34046 45157/45169/34047 +f 45144/45156/34037 45157/45169/34047 45145/45157/34038 +f 45156/45168/34046 44611/44657/33552 44614/44660/33555 +f 45156/45168/34046 44614/44660/33555 45157/45169/34047 +f 45157/45169/34047 44614/44660/33555 44393/44439/33355 +f 45157/45169/34047 44393/44439/33355 44391/44437/33353 +f 45145/45157/34038 45157/45169/34047 44391/44437/33353 +f 45145/45157/34038 44391/44437/33353 44353/44399/33315 +f 45154/45166/34044 45158/45170/34048 45159/45171/34049 +f 45154/45166/34044 45159/45171/34049 45155/45167/34045 +f 45158/45170/34048 45160/45172/34050 45161/45173/34051 +f 45158/45170/34048 45161/45173/34051 45159/45171/34049 +f 45159/45171/34049 45161/45173/34051 44357/44403/33319 +f 45159/45171/34049 44357/44403/33319 44359/44405/33321 +f 45155/45167/34045 45159/45171/34049 44359/44405/33321 +f 45155/45167/34045 44359/44405/33321 44363/44409/33325 +f 44634/44680/33574 44637/44683/33577 45162/45174/34052 +f 44634/44680/33574 45162/45174/34052 45163/45175/34053 +f 44644/44690/33577 44645/44691/33583 45164/45176/34054 +f 44644/44690/33577 45164/45176/34054 45165/45177/34052 +f 45165/45177/34052 45164/45176/34054 44809/44849/33742 +f 45165/45177/34052 44809/44849/33742 45089/45101/33984 +f 45163/45175/34053 45162/45174/34052 45166/45178/34055 +f 45163/45175/34053 45166/45178/34055 45167/45179/34056 +f 45168/45180/33542 45169/45181/33549 45170/45182/34057 +f 45168/45180/33542 45170/45182/34057 45171/45183/34058 +f 44607/44653/33549 44610/44656/33551 45172/45184/34059 +f 44607/44653/33549 45172/45184/34059 45173/45185/34060 +f 45173/45185/34060 45172/45184/34059 44791/44836/33726 +f 45173/45185/34060 44791/44836/33726 45151/45163/34041 +f 45171/45183/34058 45170/45182/34057 45149/45161/34041 +f 45171/45183/34058 45149/45161/34041 44860/44896/33787 +f 44813/44853/33746 44810/44850/33743 45174/45186/34061 +f 44813/44853/33746 45174/45186/34061 45175/44141/34062 +f 44810/44850/33743 44809/44849/33742 45164/45176/34054 +f 44810/44850/33743 45164/45176/34054 45174/45186/34061 +f 45174/45186/34061 45164/45176/34054 44645/44691/33583 +f 45174/45186/34061 44645/44691/33583 44838/44874/33767 +f 45175/44141/34062 45174/45186/34061 44838/44874/33767 +f 45175/44141/34062 44838/44874/33767 44835/44871/33764 +f 45049/44138/33950 44813/44853/33746 45175/44141/34062 +f 45176/44139/34063 45175/44141/34062 44835/44871/33764 +f 45176/44139/34063 44835/44871/33764 44834/44870/33763 +f 45177/44140/34064 45176/44139/34063 44834/44870/33763 +f 45177/44140/34064 44834/44870/33763 44829/44866/33759 +f 45178/44144/34065 45177/44140/34064 44829/44866/33759 +f 45178/44144/34065 44829/44866/33759 44828/44865/33758 +f 45179/44145/34066 45178/44144/34065 44828/44865/33758 +f 45179/44145/34066 44828/44865/33758 44827/44864/33757 +f 45180/44148/34067 45179/44145/34066 44827/44864/33757 +f 45180/44148/34067 44827/44864/33757 45048/45071/33949 +f 45181/44149/34068 45180/44148/34067 45048/45071/33949 +f 45181/44149/34068 45048/45071/33949 44808/44848/33741 +f 45182/44152/34069 45181/44149/34068 44808/44848/33741 +f 45182/44152/34069 44808/44848/33741 44807/44847/33740 +f 45183/44153/34070 45182/44152/34069 44807/44847/33740 +f 45183/44153/34070 44807/44847/33740 44802/44844/33736 +f 45184/44156/34071 45183/44153/34070 44802/44844/33736 +f 45184/44156/34071 44802/44844/33736 44801/44843/33735 +f 45185/44157/34072 45184/44156/34071 44801/44843/33735 +f 45185/44157/34072 44801/44843/33735 44800/44842/33734 +f 44729/44158/33667 45186/44160/34073 45187/45187/34074 +f 45186/44160/34073 45185/44157/34072 44800/44842/33734 +f 45186/44160/34073 44800/44842/33734 45083/45095/33979 +f 45187/45187/34074 45186/44160/34073 45083/45095/33979 +f 45187/45187/34074 45083/45095/33979 44793/44838/33728 +f 44610/44656/33551 44730/44775/33668 45188/45188/34075 +f 44610/44656/33551 45188/45188/34075 45172/45184/34059 +f 44730/44775/33668 44729/44158/33667 45187/45187/34074 +f 44730/44775/33668 45187/45187/34074 45188/45188/34075 +f 45188/45188/34075 45187/45187/34074 44793/44838/33728 +f 45188/45188/34075 44793/44838/33728 44792/44837/33727 +f 45172/45184/34059 45188/45188/34075 44792/44837/33727 +f 45172/45184/34059 44792/44837/33727 44791/44836/33726 +f 45189/45189/33588 45190/45190/34076 45191/45191/34077 +f 45189/45189/33588 45191/45191/34077 45192/45192/34078 +f 45190/45190/34076 45193/45193/34079 45194/45194/34080 +f 45190/45190/34076 45194/45194/34080 45191/45191/34077 +f 45191/45191/34077 45194/45194/34080 45195/45195/33676 +f 45191/45191/34077 45195/45195/33676 45196/45196/33675 +f 45192/45192/34078 45191/45191/34077 45196/45196/33675 +f 45192/45192/34078 45196/45196/33675 45197/45197/34081 +f 45198/45198/34082 45199/45199/34083 45200/45200/34084 +f 45198/45198/34082 45200/45200/34084 45201/45201/34085 +f 45199/45199/34083 45202/45202/33557 45203/45203/34086 +f 45199/45199/34083 45203/45203/34086 45200/45200/34084 +f 45200/45200/34084 45203/45203/34086 44596/44642/33539 +f 45200/45200/34084 44596/44642/33539 45204/45204/34087 +f 45201/45201/34085 45200/45200/34084 45204/45204/34087 +f 45201/45201/34085 45204/45204/34087 45205/45205/34088 +f 45206/45206/34089 45207/45207/34090 45208/45208/34091 +f 45206/45206/34089 45208/45208/34091 45209/45209/34092 +f 45207/45207/34090 45210/45210/33640 45211/45211/34093 +f 45207/45207/34090 45211/45211/34093 45208/45208/34091 +f 45208/45208/34091 45211/45211/34093 45127/45139/34020 +f 45208/45208/34091 45127/45139/34020 45126/45138/34019 +f 45209/45209/34092 45208/45208/34091 45126/45138/34019 +f 45209/45209/34092 45126/45138/34019 45212/45212/34094 +f 45213/45213/34095 45214/45214/34096 45215/45215/34097 +f 45213/45213/34095 45215/45215/34097 45216/45216/34098 +f 45214/45214/34096 45217/45217/34099 45218/45218/34100 +f 45214/45214/34096 45218/45218/34100 45215/45215/34097 +f 45215/45215/34097 45218/45218/34100 45219/45219/33517 +f 45215/45215/34097 45219/45219/33517 45220/45220/34101 +f 45216/45216/34098 45215/45215/34097 45220/45220/34101 +f 45216/45216/34098 45220/45220/34101 45221/45221/34102 +f 45202/45202/33557 45222/45222/33556 45223/45223/34103 +f 45202/45202/33557 45223/45223/34103 45203/45203/34086 +f 45222/45222/33556 45224/45224/34104 45225/45225/34105 +f 45222/45222/33556 45225/45225/34105 45223/45223/34103 +f 45223/45223/34103 45225/45225/34105 45226/45226/34106 +f 45223/45223/34103 45226/45226/34106 44597/44643/33540 +f 45203/45203/34086 45223/45223/34103 44597/44643/33540 +f 45203/45203/34086 44597/44643/33540 44596/44642/33539 +f 45227/45227/34000 45228/45228/33998 45229/45229/34107 +f 45227/45227/34000 45229/45229/34107 45230/45230/34108 +f 45228/45228/33998 45198/45198/34082 45201/45201/34085 +f 45228/45228/33998 45201/45201/34085 45229/45229/34107 +f 45229/45229/34107 45201/45201/34085 45205/45205/34088 +f 45229/45229/34107 45205/45205/34088 45231/45231/34109 +f 45230/45230/34108 45229/45229/34107 45231/45231/34109 +f 45230/45230/34108 45231/45231/34109 45044/45067/33945 +f 45232/45232/34110 45233/45233/34111 45234/45234/34112 +f 45232/45232/34110 45234/45234/34112 45235/45235/34113 +f 45233/45233/34111 45236/45236/34114 45237/45237/34115 +f 45233/45233/34111 45237/45237/34115 45234/45234/34112 +f 45234/45234/34112 45237/45237/34115 45238/45238/34116 +f 45234/45234/34112 45238/45238/34116 45239/45239/34117 +f 45235/45235/34113 45234/45234/34112 45239/45239/34117 +f 45235/45235/34113 45239/45239/34117 45240/45240/34118 +f 45236/45236/34114 45241/45241/34119 45242/45242/34120 +f 45236/45236/34114 45242/45242/34120 45237/45237/34115 +f 45241/45241/34119 45243/45243/34121 45244/45244/34122 +f 45241/45241/34119 45244/45244/34122 45242/45242/34120 +f 45242/45242/34120 45244/45244/34122 45245/45245/33597 +f 45242/45242/34120 45245/45245/33597 45246/45246/34123 +f 45237/45237/34115 45242/45242/34120 45246/45246/34123 +f 45237/45237/34115 45246/45246/34123 45238/45238/34116 +f 45210/45210/33640 45247/45247/34124 45248/45248/34125 +f 45210/45210/33640 45248/45248/34125 45211/45211/34093 +f 45247/45247/34124 45189/45189/33588 45192/45192/34078 +f 45247/45247/34124 45192/45192/34078 45248/45248/34125 +f 45248/45248/34125 45192/45192/34078 45197/45197/34081 +f 45248/45248/34125 45197/45197/34081 45249/45249/34126 +f 45211/45211/34093 45248/45248/34125 45249/45249/34126 +f 45211/45211/34093 45249/45249/34126 45127/45139/34020 +f 45250/45250/34127 45251/45251/34128 45252/45252/34129 +f 45250/45250/34127 45252/45252/34129 45253/45253/34130 +f 45251/45251/34128 45232/45232/34110 45235/45235/34113 +f 45251/45251/34128 45235/45235/34113 45252/45252/34129 +f 45252/45252/34129 45235/45235/34113 45240/45240/34118 +f 45252/45252/34129 45240/45240/34118 45254/45254/34131 +f 45253/45253/34130 45252/45252/34129 45254/45254/34131 +f 45253/45253/34130 45254/45254/34131 45255/45255/34132 +f 45256/45256/34121 45257/45257/33601 45258/45258/34133 +f 45256/45256/34121 45258/45258/34133 45259/45259/34122 +f 45257/45257/33601 45260/45260/34134 45261/45261/34135 +f 45257/45257/33601 45261/45261/34135 45258/45258/34133 +f 45258/45258/34133 45261/45261/34135 45262/45262/34136 +f 45258/45258/34133 45262/45262/34136 45263/45263/33598 +f 45259/45259/34122 45258/45258/34133 45263/45263/33598 +f 45259/45259/34122 45263/45263/33598 45264/45264/34137 +f 45265/45265/34138 45266/45266/34021 45267/45267/34139 +f 45265/45265/34138 45267/45267/34139 45268/45268/34140 +f 45266/45266/34021 45250/45250/34127 45253/45253/34130 +f 45266/45266/34021 45253/45253/34130 45267/45267/34139 +f 45267/45267/34139 45253/45253/34130 45255/45255/34132 +f 45267/45267/34139 45255/45255/34132 45269/45269/34141 +f 45268/45268/34140 45267/45267/34139 45269/45269/34141 +f 45268/45268/34140 45269/45269/34141 45270/45270/34142 +f 45260/45260/34134 45271/45271/34143 45272/45272/34144 +f 45260/45260/34134 45272/45272/34144 45261/45261/34135 +f 45271/45271/34143 45206/45206/34089 45209/45209/34092 +f 45271/45271/34143 45209/45209/34092 45272/45272/34144 +f 45272/45272/34144 45209/45209/34092 45212/45212/34094 +f 45272/45272/34144 45212/45212/34094 45273/45273/33617 +f 45261/45261/34135 45272/45272/34144 45273/45273/33617 +f 45261/45261/34135 45273/45273/33617 45262/45262/34136 +f 45274/45274/34145 45275/45275/34146 45276/45276/34147 +f 45274/45274/34145 45276/45276/34147 45277/45277/34148 +f 45275/45275/34146 45265/45265/34138 45268/45268/34140 +f 45275/45275/34146 45268/45268/34140 45276/45276/34147 +f 45276/45276/34147 45268/45268/34140 45270/45270/34142 +f 45276/45276/34147 45270/45270/34142 45278/45278/34149 +f 45277/45277/34148 45276/45276/34147 45278/45278/34149 +f 45277/45277/34148 45278/45278/34149 45279/45279/33571 +f 45167/45179/34056 45280/45280/34150 45281/45281/34151 +f 45167/45179/34056 45281/45281/34151 45163/45175/34053 +f 45280/45280/34150 45227/45227/34000 45230/45230/34108 +f 45280/45280/34150 45230/45230/34108 45281/45281/34151 +f 45281/45281/34151 45230/45230/34108 45044/45067/33945 +f 45281/45281/34151 45044/45067/33945 45042/45065/33944 +f 45163/45175/34053 45281/45281/34151 45042/45065/33944 +f 45163/45175/34053 45042/45065/33944 44634/44680/33574 +f 45282/45282/34152 45283/45283/34153 45284/45284/34154 +f 45282/45282/34152 45284/45284/34154 45285/45285/34155 +f 45283/45283/34153 45286/45286/34095 45287/45287/34156 +f 45283/45283/34153 45287/45287/34156 45284/45284/34154 +f 45284/45284/34154 45287/45287/34156 45288/45288/33515 +f 45284/45284/34154 45288/45288/33515 45289/45289/33997 +f 45285/45285/34155 45284/45284/34154 45289/45289/33997 +f 45285/45285/34155 45289/45289/33997 45290/45290/34157 +f 45193/45193/34079 45291/45291/34158 45292/45292/34159 +f 45193/45193/34079 45292/45292/34159 45194/45194/34080 +f 45291/45291/34158 45168/45180/33542 45171/45183/34058 +f 45291/45291/34158 45171/45183/34058 45292/45292/34159 +f 45292/45292/34159 45171/45183/34058 44860/44896/33787 +f 45292/45292/34159 44860/44896/33787 44859/44895/33786 +f 45194/45194/34080 45292/45292/34159 44859/44895/33786 +f 45194/45194/34080 44859/44895/33786 45195/45195/33676 +f 45293/45293/34044 45294/45294/34160 45295/45295/34161 +f 45293/45293/34044 45295/45295/34161 45296/45296/34162 +f 45294/45294/34160 45274/45274/34145 45277/45277/34148 +f 45294/45294/34160 45277/45277/34148 45295/45295/34161 +f 45295/45295/34161 45277/45277/34148 45279/45279/33571 +f 45295/45295/34161 45279/45279/33571 45297/45297/34163 +f 45296/45296/34162 45295/45295/34161 45297/45297/34163 +f 45296/45296/34162 45297/45297/34163 45298/45298/34164 +f 45224/45224/34104 45299/45299/34165 45300/45300/34166 +f 45224/45224/34104 45300/45300/34166 45225/45225/34105 +f 45299/45299/34165 45282/45282/34152 45285/45285/34155 +f 45299/45299/34165 45285/45285/34155 45300/45300/34166 +f 45300/45300/34166 45285/45285/34155 45290/45290/34157 +f 45300/45300/34166 45290/45290/34157 45301/45301/34167 +f 45225/45225/34105 45300/45300/34166 45301/45301/34167 +f 45225/45225/34105 45301/45301/34167 45226/45226/34106 +f 45217/45217/34099 45302/45302/34048 45303/45303/34168 +f 45217/45217/34099 45303/45303/34168 45218/45218/34100 +f 45302/45302/34048 45293/45293/34044 45296/45296/34162 +f 45302/45302/34048 45296/45296/34162 45303/45303/34168 +f 45303/45303/34168 45296/45296/34162 45298/45298/34164 +f 45303/45303/34168 45298/45298/34164 45304/45304/34169 +f 45218/45218/34100 45303/45303/34168 45304/45304/34169 +f 45218/45218/34100 45304/45304/34169 45219/45219/33517 +f 45160/45172/34050 45305/45305/34170 45306/45306/34171 +f 45160/45172/34050 45306/45306/34171 45161/45173/34051 +f 45305/45305/34170 45140/45152/34033 45143/45155/34036 +f 45305/45305/34170 45143/45155/34036 45306/45306/34171 +f 45306/45306/34171 45143/45155/34036 44349/44395/33311 +f 45306/45306/34171 44349/44395/33311 44352/44398/33314 +f 45161/45173/34051 45306/45306/34171 44352/44398/33314 +f 45161/45173/34051 44352/44398/33314 44357/44403/33319 +f 45307/45307/34172 45308/45308/34173 45309/45309/34174 +f 45307/45307/34172 45309/45309/34174 45310/45310/34175 +f 45308/45308/34173 44442/44488/33404 45311/45311/34176 +f 45308/45308/34173 45311/45311/34176 45309/45309/34174 +f 45312/45312/34177 45313/45313/34178 45314/45314/34179 +f 45312/45312/34177 45314/45314/34179 45315/45315/34180 +f 45316/45316/34181 45312/45312/34177 45315/45315/34180 +f 45316/45316/34181 45315/45315/34180 45317/45317/34182 +f 45318/45318/34183 45319/45319/34184 45320/45320/34185 +f 45318/45318/34183 45320/45320/34185 45321/45321/34186 +f 45319/45319/34184 45322/45322/34187 45323/45323/34188 +f 45319/45319/34184 45323/45323/34188 45320/45320/34185 +f 45320/45320/34185 45323/45323/34188 45324/45324/34189 +f 45320/45320/34185 45324/45324/34189 45325/45325/34190 +f 45321/45321/34186 45320/45320/34185 45325/45325/34190 +f 45321/45321/34186 45325/45325/34190 45326/45326/34191 +f 44442/44488/33404 44441/44487/33403 45327/45327/34192 +f 44442/44488/33404 45327/45327/34192 45311/45311/34176 +f 44441/44487/33403 44440/44486/33402 45328/45328/34193 +f 44441/44487/33403 45328/45328/34193 45327/45327/34192 +f 45329/45329/34194 45330/45330/34193 45331/45331/34195 +f 45329/45329/34194 45331/45331/34195 45332/45332/34196 +f 45313/45313/34178 45329/45329/34194 45332/45332/34196 +f 45313/45313/34178 45332/45332/34196 45314/45314/34179 +f 44755/44800/33691 44753/44798/33689 45333/45333/34197 +f 44755/44800/33691 45333/45333/34197 45334/45334/34198 +f 44753/44798/33689 44752/44797/33416 45335/45335/34199 +f 44753/44798/33689 45335/45335/34199 45333/45333/34197 +f 45336/45336/34200 45321/45321/34186 45326/45326/34191 +f 45336/45336/34200 45326/45326/34191 45337/45337/34201 +f 45338/45338/34202 45336/45336/34200 45337/45337/34201 +f 45338/45338/34202 45337/45337/34201 45339/45339/34203 +f 44447/44493/33409 44561/44607/33507 45340/45340/34204 +f 44447/44493/33409 45340/45340/34204 44448/44494/33410 +f 44561/44607/33507 44432/44478/33394 44757/44802/33693 +f 44561/44607/33507 44757/44802/33693 45340/45340/34204 +f 45341/45341/34205 45342/45342/33693 45343/45343/34206 +f 45341/45341/34205 45343/45343/34206 45344/45344/34207 +f 44450/44496/33412 45341/45341/34205 45344/45344/34207 +f 44450/44496/33412 45344/45344/34207 44451/44497/33413 +f 44428/44474/33390 44765/44810/33700 45345/45345/34208 +f 44428/44474/33390 45345/45345/34208 44758/44803/33694 +f 44765/44810/33700 44519/44565/33469 45346/45346/34209 +f 44765/44810/33700 45346/45346/34209 45345/45345/34208 +f 45347/45347/34208 45348/45348/34209 45349/45349/34210 +f 45347/45347/34208 45349/45349/34210 45350/45350/34211 +f 44760/44805/33696 45347/45347/34208 45350/45350/34211 +f 44760/44805/33696 45350/45350/34211 44761/44806/33697 +f 45351/45351/33469 44516/44562/33466 45352/45352/34212 +f 45351/45351/33469 45352/45352/34212 45353/45353/34209 +f 44516/44562/33466 44434/44480/33396 44437/44483/33399 +f 44516/44562/33466 44437/44483/33399 45352/45352/34212 +f 45352/45352/34212 44437/44483/33399 44442/44488/33404 +f 45352/45352/34212 44442/44488/33404 45308/45308/34173 +f 45353/45353/34209 45352/45352/34212 45308/45308/34173 +f 45353/45353/34209 45308/45308/34173 45307/45307/34172 +f 44508/44554/33461 44747/44792/33685 45354/45354/34213 +f 44508/44554/33461 45354/45354/34213 45355/45355/33401 +f 44747/44792/33685 44462/44508/33424 44749/44794/33687 +f 44747/44792/33685 44749/44794/33687 45354/45354/34213 +f 45356/45356/34214 44754/44799/33690 44755/44800/33691 +f 45356/45356/34214 44755/44800/33691 45357/45357/34215 +f 45358/45358/34216 45356/45356/34214 45357/45357/34215 +f 45358/45358/34216 45357/45357/34215 45359/45359/34217 +f 45360/45360/34218 45361/45361/34219 45362/45362/34220 +f 45360/45360/34218 45362/45362/34220 45363/45363/34221 +f 45361/45361/34219 45324/45324/34189 45364/45364/34222 +f 45361/45361/34219 45364/45364/34222 45362/45362/34220 +f 45362/45362/34220 45364/45364/34222 45365/45365/34223 +f 45362/45362/34220 45365/45365/34223 45366/45366/34224 +f 45363/45363/34221 45362/45362/34220 45366/45366/34224 +f 45363/45363/34221 45366/45366/34224 45367/45367/34225 +f 45339/45339/34203 45337/45337/34201 45368/45368/34226 +f 45339/45339/34203 45368/45368/34226 45369/45369/34227 +f 45337/45337/34201 45326/45326/34191 45325/45325/34190 +f 45337/45337/34201 45325/45325/34190 45368/45368/34226 +f 45368/45368/34226 45325/45325/34190 45324/45324/34189 +f 45368/45368/34226 45324/45324/34189 45361/45361/34219 +f 45369/45369/34227 45368/45368/34226 45361/45361/34219 +f 45369/45369/34227 45361/45361/34219 45360/45360/34218 +f 45331/45331/34195 45370/45370/34228 45371/45371/34229 +f 45331/45331/34195 45371/45371/34229 45332/45332/34196 +f 45370/45370/34228 45339/45339/34203 45369/45369/34227 +f 45370/45370/34228 45369/45369/34227 45371/45371/34229 +f 45371/45371/34229 45369/45369/34227 45360/45360/34218 +f 45371/45371/34229 45360/45360/34218 45372/45372/34230 +f 45332/45332/34196 45371/45371/34229 45372/45372/34230 +f 45332/45332/34196 45372/45372/34230 45314/45314/34179 +f 45314/45314/34179 45372/45372/34230 45373/45373/34231 +f 45314/45314/34179 45373/45373/34231 45315/45315/34180 +f 45372/45372/34230 45360/45360/34218 45363/45363/34221 +f 45372/45372/34230 45363/45363/34221 45373/45373/34231 +f 45373/45373/34231 45363/45363/34221 45367/45367/34225 +f 45373/45373/34231 45367/45367/34225 45374/45374/34232 +f 45315/45315/34180 45373/45373/34231 45374/45374/34232 +f 45315/45315/34180 45374/45374/34232 45317/45317/34182 +f 44761/44806/33697 45350/45350/34211 45375/45375/34233 +f 44761/44806/33697 45375/45375/34233 45376/45376/34234 +f 45350/45350/34211 45349/45349/34210 45377/45377/34175 +f 45350/45350/34211 45377/45377/34175 45375/45375/34233 +f 45378/45378/34235 45316/45316/34181 45317/45317/34182 +f 45378/45378/34235 45317/45317/34182 45374/45374/34232 +f 45379/45379/34234 45378/45378/34235 45374/45374/34232 +f 45379/45379/34234 45374/45374/34232 45367/45367/34225 +f 45359/45359/34217 45357/45357/34215 45380/45380/34236 +f 45359/45359/34217 45380/45380/34236 45381/45381/34193 +f 45357/45357/34215 44755/44800/33691 45334/45334/34198 +f 45357/45357/34215 45334/45334/34198 45380/45380/34236 +f 45382/45382/34237 45338/45338/34202 45339/45339/34203 +f 45382/45382/34237 45339/45339/34203 45370/45370/34228 +f 45330/45330/34193 45382/45382/34237 45370/45370/34228 +f 45330/45330/34193 45370/45370/34228 45331/45331/34195 +f 45322/45322/34187 45383/45383/34238 45384/45384/34239 +f 45322/45322/34187 45384/45384/34239 45323/45323/34188 +f 45383/45383/34238 45385/45385/34240 45386/45386/34241 +f 45383/45383/34238 45386/45386/34241 45384/45384/34239 +f 45384/45384/34239 45386/45386/34241 45365/45365/34223 +f 45384/45384/34239 45365/45365/34223 45364/45364/34222 +f 45323/45323/34188 45384/45384/34239 45364/45364/34222 +f 45323/45323/34188 45364/45364/34222 45324/45324/34189 +f 44764/44809/33699 44762/44807/33698 45387/45387/34242 +f 44764/44809/33699 45387/45387/34242 45388/45388/34243 +f 44762/44807/33698 44761/44806/33697 45376/45376/34234 +f 44762/44807/33698 45376/45376/34234 45387/45387/34242 +f 45389/45389/34244 45379/45379/34234 45367/45367/34225 +f 45389/45389/34244 45367/45367/34225 45366/45366/34224 +f 45386/45386/34241 45389/45389/34244 45366/45366/34224 +f 45386/45386/34241 45366/45366/34224 45365/45365/34223 +o Sphere.022__0 +v 1.182755 -0.699228 -0.933262 +v 1.181097 -0.690879 -0.932604 +v 1.182748 -0.690712 -0.932629 +v 1.179511 -0.691368 -0.932589 +v 1.178049 -0.692159 -0.932584 +v 1.176769 -0.693222 -0.932591 +v 1.175719 -0.694517 -0.932608 +v 1.174939 -0.695993 -0.932634 +v 1.174460 -0.697594 -0.932670 +v 1.174300 -0.699257 -0.932714 +v 1.174466 -0.700921 -0.932763 +v 1.174950 -0.702519 -0.932816 +v 1.175735 -0.703992 -0.932871 +v 1.176789 -0.705282 -0.932926 +v 1.178073 -0.706340 -0.932979 +v 1.179537 -0.707124 -0.933027 +v 1.181125 -0.707606 -0.933069 +v 1.182776 -0.707766 -0.933104 +v 1.184427 -0.707599 -0.933129 +v 1.186013 -0.707110 -0.933144 +v 1.187475 -0.706319 -0.933149 +v 1.188755 -0.705256 -0.933142 +v 1.189806 -0.703961 -0.933125 +v 1.190585 -0.702485 -0.933099 +v 1.191064 -0.700884 -0.933063 +v 1.191224 -0.699221 -0.933020 +v 1.191058 -0.697557 -0.932970 +v 1.190574 -0.695959 -0.932917 +v 1.189790 -0.694486 -0.932862 +v 1.188735 -0.693196 -0.932807 +v 1.187451 -0.692138 -0.932754 +v 1.185987 -0.691354 -0.932706 +v 1.184399 -0.690872 -0.932664 +v 1.182918 -0.659199 -0.919432 +v 1.175102 -0.659992 -0.919312 +v 1.174686 -0.657661 -0.915374 +v 1.182984 -0.656819 -0.915501 +v 1.182860 -0.663139 -0.923103 +v 1.175826 -0.663853 -0.922995 +v 1.182813 -0.668488 -0.926373 +v 1.176831 -0.669095 -0.926282 +v 1.182777 -0.675041 -0.929117 +v 1.178077 -0.675518 -0.929045 +v 1.182755 -0.682545 -0.931230 +v 1.179518 -0.682873 -0.931180 +v 1.176406 -0.683832 -0.931150 +v 1.167588 -0.662306 -0.919240 +v 1.166710 -0.660118 -0.915298 +v 1.169064 -0.665936 -0.922930 +v 1.171080 -0.670867 -0.926227 +v 1.173559 -0.676909 -0.929002 +v 1.162835 -0.669308 -0.922911 +v 1.160667 -0.666053 -0.919219 +v 1.165783 -0.673734 -0.926210 +v 1.169397 -0.679163 -0.928989 +v 1.173539 -0.685384 -0.931142 +v 1.159363 -0.664095 -0.915275 +v 1.171027 -0.687469 -0.931154 +v 1.154604 -0.671089 -0.919249 +v 1.152925 -0.669441 -0.915307 +v 1.157378 -0.673839 -0.922938 +v 1.161142 -0.677588 -0.926233 +v 1.165751 -0.682190 -0.929007 +v 1.157336 -0.682280 -0.926295 +v 1.152902 -0.679357 -0.923010 +v 1.162760 -0.685877 -0.929055 +v 1.168967 -0.690009 -0.931187 +v 1.149631 -0.677218 -0.919329 +v 1.147646 -0.675949 -0.915392 +v 1.145939 -0.684208 -0.919456 +v 1.143728 -0.683368 -0.915527 +v 1.149580 -0.685647 -0.923125 +v 1.154510 -0.687629 -0.926392 +v 1.160540 -0.690080 -0.929132 +v 1.167438 -0.692904 -0.931240 +v 1.159177 -0.694638 -0.929234 +v 1.152775 -0.693431 -0.926522 +v 1.166499 -0.696044 -0.931310 +v 1.143672 -0.691788 -0.919626 +v 1.141320 -0.691416 -0.915707 +v 1.147539 -0.692469 -0.923277 +v 1.142915 -0.699668 -0.919831 +v 1.140517 -0.699781 -0.915925 +v 1.146858 -0.699561 -0.923462 +v 1.152196 -0.699462 -0.926679 +v 1.158722 -0.699377 -0.929357 +v 1.166185 -0.699308 -0.931395 +v 1.159193 -0.704113 -0.929497 +v 1.152795 -0.705491 -0.926857 +v 1.166510 -0.702570 -0.931492 +v 1.143698 -0.707545 -0.920064 +v 1.141348 -0.708143 -0.916172 +v 1.147563 -0.706650 -0.923672 +v 1.145991 -0.715115 -0.920316 +v 1.143783 -0.716179 -0.916440 +v 1.149627 -0.713462 -0.923898 +v 1.154550 -0.711285 -0.927050 +v 1.160572 -0.708666 -0.929649 +v 1.167459 -0.705706 -0.931596 +v 1.168998 -0.708594 -0.931704 +v 1.162805 -0.712859 -0.929806 +v 1.149706 -0.722089 -0.920577 +v 1.147726 -0.723582 -0.916717 +v 1.152970 -0.719738 -0.924134 +v 1.157393 -0.716622 -0.927250 +v 1.154699 -0.728198 -0.920837 +v 1.153027 -0.730067 -0.916993 +v 1.157464 -0.725236 -0.924368 +v 1.161215 -0.721298 -0.927449 +v 1.165808 -0.716532 -0.929962 +v 1.171067 -0.711125 -0.931812 +v 1.173585 -0.713199 -0.931915 +v 1.169465 -0.719544 -0.930113 +v 1.160780 -0.733206 -0.921087 +v 1.159482 -0.735384 -0.917258 +v 1.162936 -0.729744 -0.924592 +v 1.165869 -0.725131 -0.927640 +v 1.169177 -0.733088 -0.924798 +v 1.167713 -0.736923 -0.921316 +v 1.171176 -0.727976 -0.927815 +v 1.173634 -0.721779 -0.930250 +v 1.176457 -0.714739 -0.932010 +v 1.166843 -0.739330 -0.917501 +v 1.179573 -0.715684 -0.932093 +v 1.175234 -0.739204 -0.921516 +v 1.174827 -0.741752 -0.917713 +v 1.175945 -0.735142 -0.924978 +v 1.176932 -0.729722 -0.927968 +v 1.178157 -0.723151 -0.930370 +v 1.182916 -0.730303 -0.928093 +v 1.182982 -0.735825 -0.925125 +v 1.182859 -0.723608 -0.930468 +v 1.182811 -0.715998 -0.932160 +v 1.183053 -0.739964 -0.921679 +v 1.183127 -0.742558 -0.917886 +v 1.183053 -0.739964 -0.921679 +v 1.190869 -0.739170 -0.921798 +v 1.191425 -0.741716 -0.918014 +v 1.183127 -0.742558 -0.917886 +v 1.190016 -0.735111 -0.925233 +v 1.190869 -0.739170 -0.921798 +v 1.188898 -0.729696 -0.928185 +v 1.187559 -0.723131 -0.930540 +v 1.186049 -0.715670 -0.932210 +v 1.194648 -0.727925 -0.928240 +v 1.196778 -0.733028 -0.925297 +v 1.192077 -0.721739 -0.930584 +v 1.189161 -0.714711 -0.932240 +v 1.198382 -0.736856 -0.921870 +v 1.199401 -0.739259 -0.918090 +v 1.190016 -0.735111 -0.925233 +v 1.196778 -0.733028 -0.925297 +v 1.205304 -0.733109 -0.921892 +v 1.206748 -0.735281 -0.918113 +v 1.203007 -0.729657 -0.925317 +v 1.194648 -0.727925 -0.928240 +v 1.199946 -0.725056 -0.928256 +v 1.196239 -0.719486 -0.930597 +v 1.199946 -0.725056 -0.928256 +v 1.192028 -0.713159 -0.932249 +v 1.196239 -0.719486 -0.930597 +v 1.199885 -0.716458 -0.930578 +v 1.204587 -0.721203 -0.928233 +v 1.194539 -0.711074 -0.932236 +v 1.199885 -0.716458 -0.930578 +v 1.211367 -0.728074 -0.921862 +v 1.213186 -0.729936 -0.918081 +v 1.208464 -0.725125 -0.925290 +v 1.216340 -0.721944 -0.921782 +v 1.218465 -0.723428 -0.917996 +v 1.212939 -0.719608 -0.925218 +v 1.208393 -0.716511 -0.928172 +v 1.202876 -0.712772 -0.930530 +v 1.196599 -0.708534 -0.932203 +v 1.202876 -0.712772 -0.930530 +v 1.205096 -0.708569 -0.930454 +v 1.211218 -0.711161 -0.928074 +v 1.198128 -0.705639 -0.932150 +v 1.205096 -0.708569 -0.930454 +v 1.220031 -0.714954 -0.921654 +v 1.222384 -0.716008 -0.917861 +v 1.216261 -0.713317 -0.925103 +v 1.222299 -0.707374 -0.921485 +v 1.224791 -0.707961 -0.917681 +v 1.218302 -0.706496 -0.924951 +v 1.212954 -0.705359 -0.927945 +v 1.206459 -0.704010 -0.930352 +v 1.199068 -0.702499 -0.932080 +v 1.206459 -0.704010 -0.930352 +v 1.199381 -0.699235 -0.931995 +v 1.206914 -0.699272 -0.930228 +v 1.223056 -0.699494 -0.921280 +v 1.225594 -0.699596 -0.917463 +v 1.218983 -0.699404 -0.924766 +v 1.213533 -0.699329 -0.927788 +v 1.206914 -0.699272 -0.930228 +v 1.218278 -0.692315 -0.924556 +v 1.222273 -0.691617 -0.921047 +v 1.212934 -0.693300 -0.927609 +v 1.206443 -0.694535 -0.930088 +v 1.199057 -0.695973 -0.931899 +v 1.206443 -0.694535 -0.930088 +v 1.224763 -0.691234 -0.917216 +v 1.198107 -0.692837 -0.931794 +v 1.219980 -0.684047 -0.920795 +v 1.222329 -0.683197 -0.916948 +v 1.216215 -0.685502 -0.924330 +v 1.211179 -0.687506 -0.927416 +v 1.205064 -0.689983 -0.929937 +v 1.205064 -0.689983 -0.929937 +v 1.212872 -0.679226 -0.924094 +v 1.216265 -0.677073 -0.920534 +v 1.208335 -0.682169 -0.927217 +v 1.202831 -0.685790 -0.929780 +v 1.196568 -0.689949 -0.931686 +v 1.202831 -0.685790 -0.929780 +v 1.218385 -0.675795 -0.916671 +v 1.194499 -0.687418 -0.931578 +v 1.211272 -0.670965 -0.920273 +v 1.213084 -0.669310 -0.916394 +v 1.208378 -0.673728 -0.923860 +v 1.204514 -0.677494 -0.927017 +v 1.199828 -0.682116 -0.929623 +v 1.199828 -0.682116 -0.929623 +v 1.199860 -0.673660 -0.926826 +v 1.202906 -0.669220 -0.923635 +v 1.196171 -0.679104 -0.929473 +v 1.199860 -0.673660 -0.926826 +v 1.204514 -0.677494 -0.927017 +v 1.191981 -0.685344 -0.931475 +v 1.205191 -0.665956 -0.920024 +v 1.206629 -0.663992 -0.916130 +v 1.198257 -0.662240 -0.919795 +v 1.199268 -0.660047 -0.915886 +v 1.196665 -0.665876 -0.923429 +v 1.194553 -0.670816 -0.926651 +v 1.196665 -0.665876 -0.923429 +v 1.202906 -0.669220 -0.923635 +v 1.192002 -0.676869 -0.929336 +v 1.189109 -0.683804 -0.931380 +v 1.188797 -0.669069 -0.926498 +v 1.189897 -0.663822 -0.923250 +v 1.187479 -0.675497 -0.929215 +v 1.185994 -0.682859 -0.931297 +v 1.190737 -0.659958 -0.919595 +v 1.191284 -0.657625 -0.915674 +v 1.190737 -0.659958 -0.919595 +v 1.198257 -0.662240 -0.919795 +v 1.191284 -0.657625 -0.915674 +vt 0.665624 0.777137 +vt 0.665684 0.776509 +vt 0.665564 0.776509 +vt 0.665802 0.776533 +vt 0.665913 0.776580 +vt 0.666014 0.776649 +vt 0.666099 0.776736 +vt 0.666167 0.776839 +vt 0.666214 0.776953 +vt 0.666239 0.777074 +vt 0.666240 0.777198 +vt 0.666218 0.777319 +vt 0.666173 0.777433 +vt 0.666108 0.777536 +vt 0.666024 0.777623 +vt 0.665925 0.777692 +vt 0.665814 0.777739 +vt 0.665697 0.777763 +vt 0.665577 0.777763 +vt 0.665459 0.777739 +vt 0.665348 0.777692 +vt 0.665247 0.777623 +vt 0.665161 0.777536 +vt 0.665094 0.777433 +vt 0.665046 0.777319 +vt 0.665022 0.777198 +vt 0.665020 0.777074 +vt 0.665043 0.776953 +vt 0.665087 0.776839 +vt 0.665153 0.776736 +vt 0.665237 0.776649 +vt 0.665336 0.776580 +vt 0.665446 0.776533 +vt 0.665506 0.774127 +vt 0.666074 0.774127 +vt 0.666149 0.773932 +vt 0.665546 0.773932 +vt 0.665482 0.774436 +vt 0.665994 0.774436 +vt 0.665476 0.774845 +vt 0.665911 0.774845 +vt 0.665488 0.775341 +vt 0.665830 0.775341 +vt 0.665518 0.775902 +vt 0.665753 0.775902 +vt 0.665985 0.775950 +vt 0.666632 0.774242 +vt 0.666742 0.774053 +vt 0.666496 0.774538 +vt 0.666339 0.774933 +vt 0.666166 0.775409 +vt 0.666971 0.774740 +vt 0.667160 0.774465 +vt 0.666742 0.775104 +vt 0.666483 0.775544 +vt 0.666203 0.776042 +vt 0.667302 0.774291 +vt 0.666400 0.776177 +vt 0.667636 0.774790 +vt 0.667807 0.774636 +vt 0.667399 0.775032 +vt 0.667107 0.775353 +vt 0.666769 0.775739 +vt 0.667417 0.775669 +vt 0.667765 0.775405 +vt 0.667013 0.775988 +vt 0.666568 0.776348 +vt 0.668042 0.775204 +vt 0.668239 0.775075 +vt 0.668363 0.775691 +vt 0.668579 0.775592 +vt 0.668053 0.775843 +vt 0.667663 0.776042 +vt 0.667206 0.776281 +vt 0.666701 0.776550 +vt 0.667341 0.776606 +vt 0.667834 0.776455 +vt 0.666794 0.776774 +vt 0.668586 0.776231 +vt 0.668816 0.776166 +vt 0.668254 0.776329 +vt 0.668703 0.776805 +vt 0.668940 0.776775 +vt 0.668359 0.776845 +vt 0.667923 0.776895 +vt 0.667411 0.776951 +vt 0.666842 0.777011 +vt 0.667415 0.777302 +vt 0.667928 0.777342 +vt 0.666845 0.777254 +vt 0.668709 0.777390 +vt 0.668947 0.777396 +vt 0.668365 0.777372 +vt 0.668604 0.777964 +vt 0.668835 0.778005 +vt 0.668270 0.777888 +vt 0.667848 0.777781 +vt 0.667351 0.777647 +vt 0.666801 0.777491 +vt 0.666713 0.777715 +vt 0.667224 0.777973 +vt 0.668392 0.778504 +vt 0.668610 0.778579 +vt 0.668080 0.778375 +vt 0.667685 0.778195 +vt 0.668082 0.778991 +vt 0.668280 0.779095 +vt 0.667800 0.778813 +vt 0.667448 0.778567 +vt 0.667037 0.778265 +vt 0.666585 0.777917 +vt 0.666420 0.778088 +vt 0.666798 0.778514 +vt 0.667684 0.779404 +vt 0.667858 0.779534 +vt 0.667443 0.779185 +vt 0.667143 0.778884 +vt 0.667020 0.779477 +vt 0.667215 0.779729 +vt 0.666784 0.779133 +vt 0.666516 0.778709 +vt 0.666226 0.778223 +vt 0.667360 0.779879 +vt 0.666009 0.778315 +vt 0.666692 0.779953 +vt 0.666806 0.780117 +vt 0.666550 0.779679 +vt 0.666384 0.779304 +vt 0.666202 0.778844 +vt 0.665959 0.779392 +vt 0.666049 0.779782 +vt 0.665867 0.778912 +vt 0.665779 0.778363 +vt 0.666136 0.780067 +vt 0.666215 0.780238 +vt 0.945711 0.907573 +vt 0.945291 0.907460 +vt 0.945058 0.907636 +vt 0.945504 0.907756 +vt 0.665538 0.779782 +vt 0.665568 0.780067 +vt 0.665524 0.779392 +vt 0.665526 0.778912 +vt 0.665544 0.778363 +vt 0.665096 0.779304 +vt 0.665035 0.779679 +vt 0.665190 0.778844 +vt 0.665312 0.778315 +vt 0.944895 0.907237 +vt 0.944638 0.907399 +vt 0.945532 0.907174 +vt 0.945176 0.906973 +vt 0.944538 0.906912 +vt 0.944260 0.907054 +vt 0.944855 0.906681 +vt 0.945470 0.906618 +vt 0.945198 0.906370 +vt 0.664873 0.778709 +vt 0.664693 0.779133 +vt 0.665094 0.778223 +vt 0.945553 0.905990 +vt 0.945371 0.905742 +vt 0.944966 0.906053 +vt 0.664897 0.778088 +vt 0.664586 0.778514 +vt 0.944235 0.906499 +vt 0.943938 0.906615 +vt 0.944582 0.906309 +vt 0.943997 0.906012 +vt 0.943686 0.906099 +vt 0.944368 0.905871 +vt 0.944784 0.905681 +vt 0.945228 0.905449 +vt 0.664728 0.777917 +vt 0.664342 0.778265 +vt 0.945129 0.905124 +vt 0.944658 0.905267 +vt 0.664596 0.777715 +vt 0.664149 0.777973 +vt 0.943833 0.905472 +vt 0.943512 0.905525 +vt 0.944221 0.905384 +vt 0.943750 0.904897 +vt 0.943423 0.904916 +vt 0.944145 0.904868 +vt 0.944594 0.904828 +vt 0.945079 0.904779 +vt 0.664503 0.777491 +vt 0.664015 0.777647 +vt 0.664455 0.777254 +vt 0.663945 0.777302 +vt 0.943750 0.904312 +vt 0.943423 0.904294 +vt 0.944145 0.904341 +vt 0.944594 0.904379 +vt 0.945079 0.904427 +vt 0.944221 0.903824 +vt 0.943833 0.903737 +vt 0.944658 0.903940 +vt 0.945129 0.904081 +vt 0.664452 0.777011 +vt 0.663941 0.776951 +vt 0.943512 0.903684 +vt 0.664496 0.776774 +vt 0.943997 0.903196 +vt 0.943686 0.903110 +vt 0.944368 0.903336 +vt 0.944784 0.903525 +vt 0.945228 0.903756 +vt 0.664004 0.776606 +vt 0.944582 0.902898 +vt 0.944235 0.902709 +vt 0.944966 0.903152 +vt 0.945371 0.903463 +vt 0.664583 0.776550 +vt 0.664132 0.776281 +vt 0.943938 0.902592 +vt 0.664712 0.776348 +vt 0.944538 0.902294 +vt 0.944260 0.902152 +vt 0.944855 0.902525 +vt 0.945198 0.902835 +vt 0.945553 0.903213 +vt 0.664318 0.775988 +vt 0.945470 0.902586 +vt 0.945176 0.902231 +vt 0.664557 0.775739 +vt 0.664292 0.775353 +vt 0.663987 0.775669 +vt 0.664877 0.776177 +vt 0.944895 0.901968 +vt 0.944638 0.901806 +vt 0.945291 0.901743 +vt 0.945058 0.901567 +vt 0.945532 0.902029 +vt 0.664650 0.775104 +vt 0.664511 0.774740 +vt 0.664089 0.775032 +vt 0.664840 0.775544 +vt 0.665071 0.776042 +vt 0.665051 0.774933 +vt 0.664982 0.774538 +vt 0.665154 0.775409 +vt 0.665287 0.775950 +vt 0.945711 0.901628 +vt 0.945504 0.901445 +vt 0.664949 0.774242 +vt 0.664427 0.774465 +vt 0.664956 0.774053 +vn -0.0181 0.0278 -0.9994 +vn -0.0373 0.1227 -0.9917 +vn -0.0182 0.1246 -0.9920 +vn -0.0556 0.1171 -0.9916 +vn -0.0724 0.1081 -0.9915 +vn -0.0872 0.0960 -0.9916 +vn -0.0994 0.0812 -0.9917 +vn -0.1084 0.0645 -0.9920 +vn -0.1139 0.0463 -0.9924 +vn -0.1157 0.0274 -0.9929 +vn -0.1138 0.0086 -0.9935 +vn -0.1082 -0.0097 -0.9941 +vn -0.0992 -0.0264 -0.9947 +vn -0.0871 -0.0410 -0.9954 +vn -0.0723 -0.0530 -0.9960 +vn -0.0552 -0.0620 -0.9965 +vn -0.0369 -0.0675 -0.9970 +vn -0.0179 -0.0693 -0.9974 +vn 0.0012 -0.0674 -0.9977 +vn 0.0195 -0.0618 -0.9979 +vn 0.0364 -0.0528 -0.9979 +vn 0.0512 -0.0407 -0.9979 +vn 0.0633 -0.0260 -0.9977 +vn 0.0723 -0.0092 -0.9973 +vn 0.0778 0.0089 -0.9969 +vn 0.0796 0.0278 -0.9964 +vn 0.0777 0.0468 -0.9959 +vn 0.0722 0.0649 -0.9953 +vn 0.0631 0.0816 -0.9947 +vn 0.0509 0.0963 -0.9940 +vn 0.0361 0.1083 -0.9935 +vn 0.0192 0.1173 -0.9929 +vn 0.0009 0.1227 -0.9924 +vn -0.0130 0.7795 -0.6263 +vn -0.1627 0.7644 -0.6239 +vn -0.1763 0.8388 -0.5152 +vn -0.0112 0.8554 -0.5178 +vn -0.0157 0.6088 -0.7931 +vn -0.1310 0.5972 -0.7913 +vn -0.0171 0.4591 -0.8882 +vn -0.1024 0.4506 -0.8868 +vn -0.0178 0.3327 -0.9429 +vn -0.0780 0.3267 -0.9419 +vn -0.0181 0.2234 -0.9746 +vn -0.0567 0.2195 -0.9740 +vn -0.0938 0.2083 -0.9736 +vn -0.3065 0.7204 -0.6222 +vn -0.3349 0.7902 -0.5133 +vn -0.2417 0.5634 -0.7900 +vn -0.1845 0.4256 -0.8859 +vn -0.1359 0.3091 -0.9413 +vn -0.3436 0.5088 -0.7893 +vn -0.4387 0.6493 -0.6213 +vn -0.2600 0.3852 -0.8854 +vn -0.1892 0.2806 -0.9410 +vn -0.1279 0.1901 -0.9734 +vn -0.4807 0.7117 -0.5123 +vn -0.1578 0.1656 -0.9735 +vn -0.5542 0.5540 -0.6213 +vn -0.6080 0.6065 -0.5124 +vn -0.4327 0.4355 -0.7893 +vn -0.3261 0.3310 -0.8855 +vn -0.2359 0.2424 -0.9411 +vn -0.3802 0.2651 -0.8861 +vn -0.5057 0.3465 -0.7901 +vn -0.2741 0.1959 -0.9415 +vn -0.1823 0.1358 -0.9738 +vn -0.6486 0.4383 -0.6223 +vn -0.7122 0.4788 -0.5134 +vn -0.7186 0.3066 -0.6242 +vn -0.7893 0.3335 -0.5156 +vn -0.5598 0.2451 -0.7916 +vn -0.4203 0.1900 -0.8873 +vn -0.3025 0.1429 -0.9424 +vn -0.2005 0.1019 -0.9744 +vn -0.3199 0.0854 -0.9436 +vn -0.4450 0.1086 -0.8889 +vn -0.2117 0.0650 -0.9752 +vn -0.7614 0.1642 -0.6271 +vn -0.8366 0.1763 -0.5187 +vn -0.5929 0.1352 -0.7938 +vn -0.7757 0.0162 -0.6308 +vn -0.8523 0.0131 -0.5229 +vn -0.6040 0.0211 -0.7967 +vn -0.4532 0.0240 -0.8911 +vn -0.3257 0.0258 -0.9451 +vn -0.2154 0.0268 -0.9762 +vn -0.3197 -0.0339 -0.9469 +vn -0.4447 -0.0605 -0.8936 +vn -0.2116 -0.0114 -0.9773 +vn -0.7609 -0.1316 -0.6353 +vn -0.8360 -0.1500 -0.5278 +vn -0.5926 -0.0929 -0.8001 +vn -0.7176 -0.2738 -0.6404 +vn -0.7882 -0.3070 -0.5334 +vn -0.5590 -0.2025 -0.8040 +vn -0.4198 -0.1418 -0.8965 +vn -0.3021 -0.0913 -0.9489 +vn -0.2003 -0.0482 -0.9786 +vn -0.1820 -0.0821 -0.9799 +vn -0.2736 -0.1442 -0.9510 +vn -0.6472 -0.4051 -0.6458 +vn -0.7106 -0.4518 -0.5393 +vn -0.5046 -0.3037 -0.8082 +vn -0.3794 -0.2167 -0.8995 +vn -0.5523 -0.5204 -0.6512 +vn -0.6061 -0.5791 -0.5453 +vn -0.4313 -0.3924 -0.8124 +vn -0.3250 -0.2824 -0.9026 +vn -0.2351 -0.1905 -0.9531 +vn -0.1574 -0.1117 -0.9812 +vn -0.1274 -0.1361 -0.9825 +vn -0.1883 -0.2285 -0.9552 +vn -0.4365 -0.6152 -0.6565 +vn -0.4783 -0.6837 -0.5512 +vn -0.3420 -0.4653 -0.8164 +vn -0.2588 -0.3363 -0.9055 +vn -0.2399 -0.5194 -0.8201 +vn -0.3041 -0.6857 -0.6613 +vn -0.1831 -0.3763 -0.9082 +vn -0.1349 -0.2567 -0.9570 +vn -0.0932 -0.1542 -0.9836 +vn -0.3323 -0.7615 -0.5564 +vn -0.0560 -0.1652 -0.9847 +vn -0.1602 -0.7290 -0.6655 +vn -0.1736 -0.8094 -0.5610 +vn -0.1290 -0.5527 -0.8233 +vn -0.1010 -0.4009 -0.9105 +vn -0.0770 -0.2741 -0.9586 +vn -0.0156 -0.4091 -0.9124 +vn -0.0137 -0.5638 -0.8258 +vn -0.0167 -0.2798 -0.9599 +vn -0.0174 -0.1689 -0.9855 +vn -0.0105 -0.7435 -0.6687 +vn -0.0084 -0.8254 -0.5645 +vn -0.0105 -0.7435 -0.6686 +vn 0.1393 -0.7284 -0.6708 +vn 0.1567 -0.8087 -0.5670 +vn 0.1016 -0.5522 -0.8275 +vn 0.1392 -0.7284 -0.6709 +vn 0.0698 -0.4005 -0.9136 +vn 0.0435 -0.2738 -0.9608 +vn 0.0211 -0.1651 -0.9861 +vn 0.1518 -0.3756 -0.9143 +vn 0.2123 -0.5185 -0.8283 +vn 0.1014 -0.2562 -0.9613 +vn 0.0582 -0.1538 -0.9864 +vn 0.2830 -0.6844 -0.6719 +vn 0.3153 -0.7601 -0.5681 +vn 0.4152 -0.6133 -0.6719 +vn 0.4611 -0.6817 -0.5681 +vn 0.3143 -0.4639 -0.8283 +vn 0.2273 -0.3352 -0.9143 +vn 0.1547 -0.2278 -0.9613 +vn 0.0924 -0.1356 -0.9864 +vn 0.1547 -0.2277 -0.9614 +vn 0.2013 -0.1895 -0.9610 +vn 0.2934 -0.2810 -0.9137 +vn 0.1223 -0.1111 -0.9863 +vn 0.2014 -0.1895 -0.9610 +vn 0.5307 -0.5180 -0.6708 +vn 0.5885 -0.5765 -0.5669 +vn 0.4034 -0.3906 -0.8275 +vn 0.6252 -0.4023 -0.6688 +vn 0.6926 -0.4488 -0.5647 +vn 0.4764 -0.3015 -0.8259 +vn 0.3476 -0.2151 -0.9126 +vn 0.2396 -0.1430 -0.9603 +vn 0.1468 -0.0813 -0.9858 +vn 0.2396 -0.1431 -0.9603 +vn 0.2680 -0.0900 -0.9592 +vn 0.3877 -0.1400 -0.9111 +vn 0.1650 -0.0474 -0.9852 +vn 0.2680 -0.0901 -0.9592 +vn 0.6951 -0.2708 -0.6660 +vn 0.7697 -0.3036 -0.5616 +vn 0.5305 -0.2002 -0.8237 +vn 0.7380 -0.1283 -0.6624 +vn 0.8170 -0.1464 -0.5577 +vn 0.5637 -0.0904 -0.8211 +vn 0.4124 -0.0586 -0.9091 +vn 0.2854 -0.0326 -0.9579 +vn 0.1761 -0.0106 -0.9843 +vn 0.2854 -0.0326 -0.9578 +vn 0.1799 0.0276 -0.9833 +vn 0.2912 0.0271 -0.9563 +vn 0.7523 0.0196 -0.6585 +vn 0.8328 0.0168 -0.5533 +vn 0.5747 0.0237 -0.8180 +vn 0.4206 0.0259 -0.9069 +vn 0.5633 0.1378 -0.8147 +vn 0.7375 0.1674 -0.6542 +vn 0.4121 0.1105 -0.9044 +vn 0.2852 0.0867 -0.9545 +vn 0.1760 0.0659 -0.9822 +vn 0.2853 0.0867 -0.9545 +vn 0.8165 0.1799 -0.5486 +vn 0.1647 0.1027 -0.9810 +vn 0.6941 0.3097 -0.6498 +vn 0.7686 0.3369 -0.5438 +vn 0.5297 0.2474 -0.8113 +vn 0.3872 0.1917 -0.9018 +vn 0.2676 0.1441 -0.9527 +vn 0.4753 0.3486 -0.8078 +vn 0.6238 0.4410 -0.6453 +vn 0.3468 0.2667 -0.8992 +vn 0.2390 0.1970 -0.9508 +vn 0.1464 0.1365 -0.9798 +vn 0.6911 0.4818 -0.5388 +vn 0.1218 0.1662 -0.9785 +vn 0.5289 0.5563 -0.6409 +vn 0.5865 0.6091 -0.5340 +vn 0.4020 0.4373 -0.8044 +vn 0.2924 0.3324 -0.8967 +vn 0.2006 0.2433 -0.9490 +vn 0.2262 0.3863 -0.8942 +vn 0.3126 0.5102 -0.8012 +vn 0.1538 0.2814 -0.9472 +vn 0.2261 0.3863 -0.8943 +vn 0.2924 0.3323 -0.8967 +vn 0.0918 0.1905 -0.9774 +vn 0.4131 0.6511 -0.6367 +vn 0.4588 0.7137 -0.5293 +vn 0.2806 0.7217 -0.6328 +vn 0.3127 0.7916 -0.5250 +vn 0.2105 0.5644 -0.7982 +vn 0.1504 0.4263 -0.8920 +vn 0.3127 0.5103 -0.8012 +vn 0.1005 0.3096 -0.9455 +vn 0.0576 0.2086 -0.9763 +vn 0.0684 0.4509 -0.8899 +vn 0.0997 0.5977 -0.7955 +vn 0.0425 0.3269 -0.9441 +vn 0.0204 0.2197 -0.9754 +vn 0.1367 0.7650 -0.6293 +vn 0.1540 0.8395 -0.5211 +vn 0.1539 0.8395 -0.5211 +usemtl Scene_-_Root +s 1 +f 45390/45390/34245 45391/45391/34246 45392/45392/34247 +f 45390/45390/34245 45393/45393/34248 45391/45391/34246 +f 45390/45390/34245 45394/45394/34249 45393/45393/34248 +f 45390/45390/34245 45395/45395/34250 45394/45394/34249 +f 45390/45390/34245 45396/45396/34251 45395/45395/34250 +f 45390/45390/34245 45397/45397/34252 45396/45396/34251 +f 45390/45390/34245 45398/45398/34253 45397/45397/34252 +f 45390/45390/34245 45399/45399/34254 45398/45398/34253 +f 45390/45390/34245 45400/45400/34255 45399/45399/34254 +f 45390/45390/34245 45401/45401/34256 45400/45400/34255 +f 45390/45390/34245 45402/45402/34257 45401/45401/34256 +f 45390/45390/34245 45403/45403/34258 45402/45402/34257 +f 45390/45390/34245 45404/45404/34259 45403/45403/34258 +f 45390/45390/34245 45405/45405/34260 45404/45404/34259 +f 45390/45390/34245 45406/45406/34261 45405/45405/34260 +f 45390/45390/34245 45407/45407/34262 45406/45406/34261 +f 45390/45390/34245 45408/45408/34263 45407/45407/34262 +f 45390/45390/34245 45409/45409/34264 45408/45408/34263 +f 45390/45390/34245 45410/45410/34265 45409/45409/34264 +f 45390/45390/34245 45411/45411/34266 45410/45410/34265 +f 45390/45390/34245 45412/45412/34267 45411/45411/34266 +f 45390/45390/34245 45413/45413/34268 45412/45412/34267 +f 45390/45390/34245 45414/45414/34269 45413/45413/34268 +f 45390/45390/34245 45415/45415/34270 45414/45414/34269 +f 45390/45390/34245 45416/45416/34271 45415/45415/34270 +f 45390/45390/34245 45417/45417/34272 45416/45416/34271 +f 45390/45390/34245 45418/45418/34273 45417/45417/34272 +f 45390/45390/34245 45419/45419/34274 45418/45418/34273 +f 45390/45390/34245 45420/45420/34275 45419/45419/34274 +f 45390/45390/34245 45421/45421/34276 45420/45420/34275 +f 45390/45390/34245 45422/45422/34277 45421/45421/34276 +f 45390/45390/34245 45392/45392/34247 45422/45422/34277 +f 45423/45423/34278 45424/45424/34279 45425/45425/34280 +f 45423/45423/34278 45425/45425/34280 45426/45426/34281 +f 45427/45427/34282 45428/45428/34283 45424/45424/34279 +f 45427/45427/34282 45424/45424/34279 45423/45423/34278 +f 45429/45429/34284 45430/45430/34285 45428/45428/34283 +f 45429/45429/34284 45428/45428/34283 45427/45427/34282 +f 45431/45431/34286 45432/45432/34287 45430/45430/34285 +f 45431/45431/34286 45430/45430/34285 45429/45429/34284 +f 45433/45433/34288 45434/45434/34289 45432/45432/34287 +f 45433/45433/34288 45432/45432/34287 45431/45431/34286 +f 45392/45392/34247 45391/45391/34246 45434/45434/34289 +f 45392/45392/34247 45434/45434/34289 45433/45433/34288 +f 45391/45391/34246 45393/45393/34248 45435/45435/34290 +f 45391/45391/34246 45435/45435/34290 45434/45434/34289 +f 45424/45424/34279 45436/45436/34291 45437/45437/34292 +f 45424/45424/34279 45437/45437/34292 45425/45425/34280 +f 45428/45428/34283 45438/45438/34293 45436/45436/34291 +f 45428/45428/34283 45436/45436/34291 45424/45424/34279 +f 45430/45430/34285 45439/45439/34294 45438/45438/34293 +f 45430/45430/34285 45438/45438/34293 45428/45428/34283 +f 45432/45432/34287 45440/45440/34295 45439/45439/34294 +f 45432/45432/34287 45439/45439/34294 45430/45430/34285 +f 45434/45434/34289 45435/45435/34290 45440/45440/34295 +f 45434/45434/34289 45440/45440/34295 45432/45432/34287 +f 45438/45438/34293 45441/45441/34296 45442/45442/34297 +f 45438/45438/34293 45442/45442/34297 45436/45436/34291 +f 45439/45439/34294 45443/45443/34298 45441/45441/34296 +f 45439/45439/34294 45441/45441/34296 45438/45438/34293 +f 45440/45440/34295 45444/45444/34299 45443/45443/34298 +f 45440/45440/34295 45443/45443/34298 45439/45439/34294 +f 45435/45435/34290 45445/45445/34300 45444/45444/34299 +f 45435/45435/34290 45444/45444/34299 45440/45440/34295 +f 45393/45393/34248 45394/45394/34249 45445/45445/34300 +f 45393/45393/34248 45445/45445/34300 45435/45435/34290 +f 45436/45436/34291 45442/45442/34297 45446/45446/34301 +f 45436/45436/34291 45446/45446/34301 45437/45437/34292 +f 45394/45394/34249 45395/45395/34250 45447/45447/34302 +f 45394/45394/34249 45447/45447/34302 45445/45445/34300 +f 45442/45442/34297 45448/45448/34303 45449/45449/34304 +f 45442/45442/34297 45449/45449/34304 45446/45446/34301 +f 45441/45441/34296 45450/45450/34305 45448/45448/34303 +f 45441/45441/34296 45448/45448/34303 45442/45442/34297 +f 45443/45443/34298 45451/45451/34306 45450/45450/34305 +f 45443/45443/34298 45450/45450/34305 45441/45441/34296 +f 45444/45444/34299 45452/45452/34307 45451/45451/34306 +f 45444/45444/34299 45451/45451/34306 45443/45443/34298 +f 45445/45445/34300 45447/45447/34302 45452/45452/34307 +f 45445/45445/34300 45452/45452/34307 45444/45444/34299 +f 45451/45451/34306 45453/45453/34308 45454/45454/34309 +f 45451/45451/34306 45454/45454/34309 45450/45450/34305 +f 45452/45452/34307 45455/45455/34310 45453/45453/34308 +f 45452/45452/34307 45453/45453/34308 45451/45451/34306 +f 45447/45447/34302 45456/45456/34311 45455/45455/34310 +f 45447/45447/34302 45455/45455/34310 45452/45452/34307 +f 45395/45395/34250 45396/45396/34251 45456/45456/34311 +f 45395/45395/34250 45456/45456/34311 45447/45447/34302 +f 45448/45448/34303 45457/45457/34312 45458/45458/34313 +f 45448/45448/34303 45458/45458/34313 45449/45449/34304 +f 45450/45450/34305 45454/45454/34309 45457/45457/34312 +f 45450/45450/34305 45457/45457/34312 45448/45448/34303 +f 45457/45457/34312 45459/45459/34314 45460/45460/34315 +f 45457/45457/34312 45460/45460/34315 45458/45458/34313 +f 45454/45454/34309 45461/45461/34316 45459/45459/34314 +f 45454/45454/34309 45459/45459/34314 45457/45457/34312 +f 45453/45453/34308 45462/45462/34317 45461/45461/34316 +f 45453/45453/34308 45461/45461/34316 45454/45454/34309 +f 45455/45455/34310 45463/45463/34318 45462/45462/34317 +f 45455/45455/34310 45462/45462/34317 45453/45453/34308 +f 45456/45456/34311 45464/45464/34319 45463/45463/34318 +f 45456/45456/34311 45463/45463/34318 45455/45455/34310 +f 45396/45396/34251 45397/45397/34252 45464/45464/34319 +f 45396/45396/34251 45464/45464/34319 45456/45456/34311 +f 45463/45463/34318 45465/45465/34320 45466/45466/34321 +f 45463/45463/34318 45466/45466/34321 45462/45462/34317 +f 45464/45464/34319 45467/45467/34322 45465/45465/34320 +f 45464/45464/34319 45465/45465/34320 45463/45463/34318 +f 45397/45397/34252 45398/45398/34253 45467/45467/34322 +f 45397/45397/34252 45467/45467/34322 45464/45464/34319 +f 45459/45459/34314 45468/45468/34323 45469/45469/34324 +f 45459/45459/34314 45469/45469/34324 45460/45460/34315 +f 45461/45461/34316 45470/45470/34325 45468/45468/34323 +f 45461/45461/34316 45468/45468/34323 45459/45459/34314 +f 45462/45462/34317 45466/45466/34321 45470/45470/34325 +f 45462/45462/34317 45470/45470/34325 45461/45461/34316 +f 45468/45468/34323 45471/45471/34326 45472/45472/34327 +f 45468/45468/34323 45472/45472/34327 45469/45469/34324 +f 45470/45470/34325 45473/45473/34328 45471/45471/34326 +f 45470/45470/34325 45471/45471/34326 45468/45468/34323 +f 45466/45466/34321 45474/45474/34329 45473/45473/34328 +f 45466/45466/34321 45473/45473/34328 45470/45470/34325 +f 45465/45465/34320 45475/45475/34330 45474/45474/34329 +f 45465/45465/34320 45474/45474/34329 45466/45466/34321 +f 45467/45467/34322 45476/45476/34331 45475/45475/34330 +f 45467/45467/34322 45475/45475/34330 45465/45465/34320 +f 45398/45398/34253 45399/45399/34254 45476/45476/34331 +f 45398/45398/34253 45476/45476/34331 45467/45467/34322 +f 45475/45475/34330 45477/45477/34332 45478/45478/34333 +f 45475/45475/34330 45478/45478/34333 45474/45474/34329 +f 45476/45476/34331 45479/45479/34334 45477/45477/34332 +f 45476/45476/34331 45477/45477/34332 45475/45475/34330 +f 45399/45399/34254 45400/45400/34255 45479/45479/34334 +f 45399/45399/34254 45479/45479/34334 45476/45476/34331 +f 45471/45471/34326 45480/45480/34335 45481/45481/34336 +f 45471/45471/34326 45481/45481/34336 45472/45472/34327 +f 45473/45473/34328 45482/45482/34337 45480/45480/34335 +f 45473/45473/34328 45480/45480/34335 45471/45471/34326 +f 45474/45474/34329 45478/45478/34333 45482/45482/34337 +f 45474/45474/34329 45482/45482/34337 45473/45473/34328 +f 45480/45480/34335 45483/45483/34338 45484/45484/34339 +f 45480/45480/34335 45484/45484/34339 45481/45481/34336 +f 45482/45482/34337 45485/45485/34340 45483/45483/34338 +f 45482/45482/34337 45483/45483/34338 45480/45480/34335 +f 45478/45478/34333 45486/45486/34341 45485/45485/34340 +f 45478/45478/34333 45485/45485/34340 45482/45482/34337 +f 45477/45477/34332 45487/45487/34342 45486/45486/34341 +f 45477/45477/34332 45486/45486/34341 45478/45478/34333 +f 45479/45479/34334 45488/45488/34343 45487/45487/34342 +f 45479/45479/34334 45487/45487/34342 45477/45477/34332 +f 45400/45400/34255 45401/45401/34256 45488/45488/34343 +f 45400/45400/34255 45488/45488/34343 45479/45479/34334 +f 45488/45488/34343 45489/45489/34344 45490/45490/34345 +f 45488/45488/34343 45490/45490/34345 45487/45487/34342 +f 45401/45401/34256 45402/45402/34257 45489/45489/34344 +f 45401/45401/34256 45489/45489/34344 45488/45488/34343 +f 45483/45483/34338 45491/45491/34346 45492/45492/34347 +f 45483/45483/34338 45492/45492/34347 45484/45484/34339 +f 45485/45485/34340 45493/45493/34348 45491/45491/34346 +f 45485/45485/34340 45491/45491/34346 45483/45483/34338 +f 45486/45486/34341 45494/45494/34349 45493/45493/34348 +f 45486/45486/34341 45493/45493/34348 45485/45485/34340 +f 45487/45487/34342 45490/45490/34345 45494/45494/34349 +f 45487/45487/34342 45494/45494/34349 45486/45486/34341 +f 45491/45491/34346 45495/45495/34350 45496/45496/34351 +f 45491/45491/34346 45496/45496/34351 45492/45492/34347 +f 45493/45493/34348 45497/45497/34352 45495/45495/34350 +f 45493/45493/34348 45495/45495/34350 45491/45491/34346 +f 45494/45494/34349 45498/45498/34353 45497/45497/34352 +f 45494/45494/34349 45497/45497/34352 45493/45493/34348 +f 45490/45490/34345 45499/45499/34354 45498/45498/34353 +f 45490/45490/34345 45498/45498/34353 45494/45494/34349 +f 45489/45489/34344 45500/45500/34355 45499/45499/34354 +f 45489/45489/34344 45499/45499/34354 45490/45490/34345 +f 45402/45402/34257 45403/45403/34258 45500/45500/34355 +f 45402/45402/34257 45500/45500/34355 45489/45489/34344 +f 45500/45500/34355 45501/45501/34356 45502/45502/34357 +f 45500/45500/34355 45502/45502/34357 45499/45499/34354 +f 45403/45403/34258 45404/45404/34259 45501/45501/34356 +f 45403/45403/34258 45501/45501/34356 45500/45500/34355 +f 45495/45495/34350 45503/45503/34358 45504/45504/34359 +f 45495/45495/34350 45504/45504/34359 45496/45496/34351 +f 45497/45497/34352 45505/45505/34360 45503/45503/34358 +f 45497/45497/34352 45503/45503/34358 45495/45495/34350 +f 45498/45498/34353 45506/45506/34361 45505/45505/34360 +f 45498/45498/34353 45505/45505/34360 45497/45497/34352 +f 45499/45499/34354 45502/45502/34357 45506/45506/34361 +f 45499/45499/34354 45506/45506/34361 45498/45498/34353 +f 45505/45505/34360 45507/45507/34362 45508/45508/34363 +f 45505/45505/34360 45508/45508/34363 45503/45503/34358 +f 45506/45506/34361 45509/45509/34364 45507/45507/34362 +f 45506/45506/34361 45507/45507/34362 45505/45505/34360 +f 45502/45502/34357 45510/45510/34365 45509/45509/34364 +f 45502/45502/34357 45509/45509/34364 45506/45506/34361 +f 45501/45501/34356 45511/45511/34366 45510/45510/34365 +f 45501/45501/34356 45510/45510/34365 45502/45502/34357 +f 45404/45404/34259 45405/45405/34260 45511/45511/34366 +f 45404/45404/34259 45511/45511/34366 45501/45501/34356 +f 45503/45503/34358 45508/45508/34363 45512/45512/34367 +f 45503/45503/34358 45512/45512/34367 45504/45504/34359 +f 45405/45405/34260 45406/45406/34261 45513/45513/34368 +f 45405/45405/34260 45513/45513/34368 45511/45511/34366 +f 45508/45508/34363 45514/45514/34369 45515/45515/34370 +f 45508/45508/34363 45515/45515/34370 45512/45512/34367 +f 45507/45507/34362 45516/45516/34371 45514/45514/34369 +f 45507/45507/34362 45514/45514/34369 45508/45508/34363 +f 45509/45509/34364 45517/45517/34372 45516/45516/34371 +f 45509/45509/34364 45516/45516/34371 45507/45507/34362 +f 45510/45510/34365 45518/45518/34373 45517/45517/34372 +f 45510/45510/34365 45517/45517/34372 45509/45509/34364 +f 45511/45511/34366 45513/45513/34368 45518/45518/34373 +f 45511/45511/34366 45518/45518/34373 45510/45510/34365 +f 45517/45517/34372 45519/45519/34374 45520/45520/34375 +f 45517/45517/34372 45520/45520/34375 45516/45516/34371 +f 45518/45518/34373 45521/45521/34376 45519/45519/34374 +f 45518/45518/34373 45519/45519/34374 45517/45517/34372 +f 45513/45513/34368 45522/45522/34377 45521/45521/34376 +f 45513/45513/34368 45521/45521/34376 45518/45518/34373 +f 45406/45406/34261 45407/45407/34262 45522/45522/34377 +f 45406/45406/34261 45522/45522/34377 45513/45513/34368 +f 45514/45514/34369 45523/45523/34378 45524/45524/34379 +f 45514/45514/34369 45524/45524/34379 45515/45515/34370 +f 45516/45516/34371 45520/45520/34375 45523/45523/34378 +f 45516/45516/34371 45523/45523/34378 45514/45514/34369 +f 45525/45525/34380 45526/45526/34381 45527/45527/34382 +f 45525/45525/34380 45527/45527/34382 45528/45528/34379 +f 45520/45520/34375 45529/45529/34383 45530/45530/34384 +f 45520/45520/34375 45530/45530/34384 45523/45523/34378 +f 45519/45519/34374 45531/45531/34385 45529/45529/34383 +f 45519/45519/34374 45529/45529/34383 45520/45520/34375 +f 45521/45521/34376 45532/45532/34386 45531/45531/34385 +f 45521/45521/34376 45531/45531/34385 45519/45519/34374 +f 45522/45522/34377 45533/45533/34387 45532/45532/34386 +f 45522/45522/34377 45532/45532/34386 45521/45521/34376 +f 45407/45407/34262 45408/45408/34263 45533/45533/34387 +f 45407/45407/34262 45533/45533/34387 45522/45522/34377 +f 45531/45531/34385 45534/45534/34388 45535/45535/34389 +f 45531/45531/34385 45535/45535/34389 45529/45529/34383 +f 45532/45532/34386 45536/45536/34390 45534/45534/34388 +f 45532/45532/34386 45534/45534/34388 45531/45531/34385 +f 45533/45533/34387 45537/45537/34391 45536/45536/34390 +f 45533/45533/34387 45536/45536/34390 45532/45532/34386 +f 45408/45408/34263 45409/45409/34264 45537/45537/34391 +f 45408/45408/34263 45537/45537/34391 45533/45533/34387 +f 45526/45526/34381 45538/45538/34392 45539/45539/34393 +f 45526/45526/34381 45539/45539/34393 45527/45527/34382 +f 45540/45540/34383 45541/45541/34389 45538/45538/34392 +f 45540/45540/34383 45538/45538/34392 45526/45526/34381 +f 45538/45538/34392 45542/45542/34394 45543/45543/34395 +f 45538/45538/34392 45543/45543/34395 45539/45539/34393 +f 45541/45541/34389 45544/45544/34396 45542/45542/34394 +f 45541/45541/34389 45542/45542/34394 45538/45538/34392 +f 45545/45545/34388 45546/45546/34397 45544/45544/34396 +f 45545/45545/34388 45544/45544/34396 45541/45541/34389 +f 45536/45536/34390 45547/45547/34398 45548/45548/34397 +f 45536/45536/34390 45548/45548/34397 45534/45534/34388 +f 45537/45537/34391 45549/45549/34399 45547/45547/34398 +f 45537/45537/34391 45547/45547/34398 45536/45536/34390 +f 45409/45409/34264 45410/45410/34265 45549/45549/34399 +f 45409/45409/34264 45549/45549/34399 45537/45537/34391 +f 45550/45550/34400 45551/45551/34401 45552/45552/34402 +f 45550/45550/34400 45552/45552/34402 45546/45546/34397 +f 45549/45549/34399 45553/45553/34403 45554/45554/34404 +f 45549/45549/34399 45554/45554/34404 45547/45547/34398 +f 45410/45410/34265 45411/45411/34266 45553/45553/34403 +f 45410/45410/34265 45553/45553/34403 45549/45549/34399 +f 45542/45542/34394 45555/45555/34405 45556/45556/34406 +f 45542/45542/34394 45556/45556/34406 45543/45543/34395 +f 45544/45544/34396 45557/45557/34407 45555/45555/34405 +f 45544/45544/34396 45555/45555/34405 45542/45542/34394 +f 45546/45546/34397 45552/45552/34402 45557/45557/34407 +f 45546/45546/34397 45557/45557/34407 45544/45544/34396 +f 45555/45555/34405 45558/45558/34408 45559/45559/34409 +f 45555/45555/34405 45559/45559/34409 45556/45556/34406 +f 45557/45557/34407 45560/45560/34410 45558/45558/34408 +f 45557/45557/34407 45558/45558/34408 45555/45555/34405 +f 45552/45552/34402 45561/45561/34411 45560/45560/34410 +f 45552/45552/34402 45560/45560/34410 45557/45557/34407 +f 45551/45551/34401 45562/45562/34412 45561/45561/34411 +f 45551/45551/34401 45561/45561/34411 45552/45552/34402 +f 45553/45553/34403 45563/45563/34413 45564/45564/34414 +f 45553/45553/34403 45564/45564/34414 45554/45554/34404 +f 45411/45411/34266 45412/45412/34267 45563/45563/34413 +f 45411/45411/34266 45563/45563/34413 45553/45553/34403 +f 45562/45562/34412 45565/45565/34415 45566/45566/34416 +f 45562/45562/34412 45566/45566/34416 45561/45561/34411 +f 45563/45563/34413 45567/45567/34417 45568/45568/34418 +f 45563/45563/34413 45568/45568/34418 45564/45564/34414 +f 45412/45412/34267 45413/45413/34268 45567/45567/34417 +f 45412/45412/34267 45567/45567/34417 45563/45563/34413 +f 45558/45558/34408 45569/45569/34419 45570/45570/34420 +f 45558/45558/34408 45570/45570/34420 45559/45559/34409 +f 45560/45560/34410 45571/45571/34421 45569/45569/34419 +f 45560/45560/34410 45569/45569/34419 45558/45558/34408 +f 45561/45561/34411 45566/45566/34416 45571/45571/34421 +f 45561/45561/34411 45571/45571/34421 45560/45560/34410 +f 45569/45569/34419 45572/45572/34422 45573/45573/34423 +f 45569/45569/34419 45573/45573/34423 45570/45570/34420 +f 45571/45571/34421 45574/45574/34424 45572/45572/34422 +f 45571/45571/34421 45572/45572/34422 45569/45569/34419 +f 45566/45566/34416 45575/45575/34425 45574/45574/34424 +f 45566/45566/34416 45574/45574/34424 45571/45571/34421 +f 45565/45565/34415 45576/45576/34426 45575/45575/34425 +f 45565/45565/34415 45575/45575/34425 45566/45566/34416 +f 45567/45567/34417 45577/45577/34427 45578/45578/34428 +f 45567/45567/34417 45578/45578/34428 45568/45568/34418 +f 45413/45413/34268 45414/45414/34269 45577/45577/34427 +f 45413/45413/34268 45577/45577/34427 45567/45567/34417 +f 45577/45577/34427 45579/45579/34429 45580/45580/34430 +f 45577/45577/34427 45580/45580/34430 45578/45578/34428 +f 45414/45414/34269 45415/45415/34270 45579/45579/34429 +f 45414/45414/34269 45579/45579/34429 45577/45577/34427 +f 45572/45572/34422 45581/45581/34431 45582/45582/34432 +f 45572/45572/34422 45582/45582/34432 45573/45573/34423 +f 45574/45574/34424 45583/45583/34433 45581/45581/34431 +f 45574/45574/34424 45581/45581/34431 45572/45572/34422 +f 45575/45575/34425 45584/45584/34434 45583/45583/34433 +f 45575/45575/34425 45583/45583/34433 45574/45574/34424 +f 45576/45576/34426 45585/45585/34430 45584/45584/34434 +f 45576/45576/34426 45584/45584/34434 45575/45575/34425 +f 45583/45583/34433 45586/45586/34435 45587/45587/34436 +f 45583/45583/34433 45587/45587/34436 45581/45581/34431 +f 45584/45584/34434 45588/45588/34437 45586/45586/34435 +f 45584/45584/34434 45586/45586/34435 45583/45583/34433 +f 45585/45585/34430 45589/45589/34438 45588/45588/34437 +f 45585/45585/34430 45588/45588/34437 45584/45584/34434 +f 45579/45579/34429 45590/45590/34439 45591/45591/34440 +f 45579/45579/34429 45591/45591/34440 45580/45580/34430 +f 45415/45415/34270 45416/45416/34271 45590/45590/34439 +f 45415/45415/34270 45590/45590/34439 45579/45579/34429 +f 45581/45581/34431 45587/45587/34436 45592/45592/34441 +f 45581/45581/34431 45592/45592/34441 45582/45582/34432 +f 45416/45416/34271 45417/45417/34272 45593/45593/34442 +f 45416/45416/34271 45593/45593/34442 45590/45590/34439 +f 45587/45587/34436 45594/45594/34443 45595/45595/34444 +f 45587/45587/34436 45595/45595/34444 45592/45592/34441 +f 45586/45586/34435 45596/45596/34445 45594/45594/34443 +f 45586/45586/34435 45594/45594/34443 45587/45587/34436 +f 45588/45588/34437 45597/45597/34446 45596/45596/34445 +f 45588/45588/34437 45596/45596/34445 45586/45586/34435 +f 45589/45589/34438 45598/45598/34447 45597/45597/34446 +f 45589/45589/34438 45597/45597/34446 45588/45588/34437 +f 45590/45590/34439 45593/45593/34442 45599/45599/34447 +f 45590/45590/34439 45599/45599/34447 45591/45591/34440 +f 45596/45596/34445 45600/45600/34448 45601/45601/34449 +f 45596/45596/34445 45601/45601/34449 45594/45594/34443 +f 45597/45597/34446 45602/45602/34450 45600/45600/34448 +f 45597/45597/34446 45600/45600/34448 45596/45596/34445 +f 45598/45598/34447 45603/45603/34451 45602/45602/34450 +f 45598/45598/34447 45602/45602/34450 45597/45597/34446 +f 45593/45593/34442 45604/45604/34452 45605/45605/34451 +f 45593/45593/34442 45605/45605/34451 45599/45599/34447 +f 45417/45417/34272 45418/45418/34273 45604/45604/34452 +f 45417/45417/34272 45604/45604/34452 45593/45593/34442 +f 45594/45594/34443 45601/45601/34449 45606/45606/34453 +f 45594/45594/34443 45606/45606/34453 45595/45595/34444 +f 45418/45418/34273 45419/45419/34274 45607/45607/34454 +f 45418/45418/34273 45607/45607/34454 45604/45604/34452 +f 45601/45601/34449 45608/45608/34455 45609/45609/34456 +f 45601/45601/34449 45609/45609/34456 45606/45606/34453 +f 45600/45600/34448 45610/45610/34457 45608/45608/34455 +f 45600/45600/34448 45608/45608/34455 45601/45601/34449 +f 45602/45602/34450 45611/45611/34458 45610/45610/34457 +f 45602/45602/34450 45610/45610/34457 45600/45600/34448 +f 45603/45603/34451 45612/45612/34459 45611/45611/34458 +f 45603/45603/34451 45611/45611/34458 45602/45602/34450 +f 45604/45604/34452 45607/45607/34454 45613/45613/34459 +f 45604/45604/34452 45613/45613/34459 45605/45605/34451 +f 45611/45611/34458 45614/45614/34460 45615/45615/34461 +f 45611/45611/34458 45615/45615/34461 45610/45610/34457 +f 45613/45613/34459 45616/45616/34462 45617/45617/34463 +f 45613/45613/34459 45617/45617/34463 45618/45618/34464 +f 45607/45607/34454 45619/45619/34465 45616/45616/34462 +f 45607/45607/34454 45616/45616/34462 45613/45613/34459 +f 45419/45419/34274 45420/45420/34275 45619/45619/34465 +f 45419/45419/34274 45619/45619/34465 45607/45607/34454 +f 45608/45608/34455 45620/45620/34466 45621/45621/34467 +f 45608/45608/34455 45621/45621/34467 45609/45609/34456 +f 45610/45610/34457 45615/45615/34461 45620/45620/34466 +f 45610/45610/34457 45620/45620/34466 45608/45608/34455 +f 45620/45620/34466 45622/45622/34468 45623/45623/34469 +f 45620/45620/34466 45623/45623/34469 45621/45621/34467 +f 45615/45615/34461 45624/45624/34470 45622/45622/34468 +f 45615/45615/34461 45622/45622/34468 45620/45620/34466 +f 45617/45617/34463 45625/45625/34471 45626/45626/34470 +f 45617/45617/34463 45626/45626/34470 45627/45627/34472 +f 45616/45616/34462 45628/45628/34473 45625/45625/34471 +f 45616/45616/34462 45625/45625/34471 45617/45617/34463 +f 45619/45619/34465 45629/45629/34474 45628/45628/34473 +f 45619/45619/34465 45628/45628/34473 45616/45616/34462 +f 45420/45420/34275 45421/45421/34276 45629/45629/34474 +f 45420/45420/34275 45629/45629/34474 45619/45619/34465 +f 45625/45625/34471 45630/45630/34475 45631/45631/34476 +f 45625/45625/34471 45631/45631/34476 45626/45626/34470 +f 45628/45628/34473 45632/45632/34477 45630/45630/34475 +f 45628/45628/34473 45630/45630/34475 45625/45625/34471 +f 45629/45629/34474 45633/45633/34478 45632/45632/34477 +f 45629/45629/34474 45632/45632/34477 45628/45628/34473 +f 45421/45421/34276 45422/45422/34277 45633/45633/34478 +f 45421/45421/34276 45633/45633/34478 45629/45629/34474 +f 45622/45622/34468 45634/45634/34479 45635/45635/34480 +f 45622/45622/34468 45635/45635/34480 45623/45623/34469 +f 45626/45626/34470 45631/45631/34476 45636/45636/34479 +f 45626/45626/34470 45636/45636/34479 45637/45637/34468 +f 45636/45636/34479 45423/45423/34278 45426/45426/34281 +f 45636/45636/34479 45426/45426/34281 45638/45638/34481 +f 45631/45631/34476 45427/45427/34282 45423/45423/34278 +f 45631/45631/34476 45423/45423/34278 45636/45636/34479 +f 45630/45630/34475 45429/45429/34284 45427/45427/34282 +f 45630/45630/34475 45427/45427/34282 45631/45631/34476 +f 45632/45632/34477 45431/45431/34286 45429/45429/34284 +f 45632/45632/34477 45429/45429/34284 45630/45630/34475 +f 45633/45633/34478 45433/45433/34288 45431/45431/34286 +f 45633/45633/34478 45431/45431/34286 45632/45632/34477 +f 45422/45422/34277 45392/45392/34247 45433/45433/34288 +f 45422/45422/34277 45433/45433/34288 45633/45633/34478 +o Sphere.023__0 +v 1.319006 -0.707175 -0.933262 +v 1.317348 -0.698826 -0.932604 +v 1.318999 -0.698658 -0.932629 +v 1.315762 -0.699315 -0.932589 +v 1.314300 -0.700106 -0.932584 +v 1.313020 -0.701169 -0.932591 +v 1.311970 -0.702464 -0.932608 +v 1.311190 -0.703939 -0.932634 +v 1.310711 -0.705540 -0.932670 +v 1.310551 -0.707204 -0.932714 +v 1.310717 -0.708867 -0.932763 +v 1.311201 -0.710466 -0.932816 +v 1.311986 -0.711938 -0.932871 +v 1.313040 -0.713228 -0.932926 +v 1.314324 -0.714286 -0.932979 +v 1.315788 -0.715071 -0.933027 +v 1.317376 -0.715553 -0.933069 +v 1.319027 -0.715713 -0.933104 +v 1.320678 -0.715545 -0.933129 +v 1.322264 -0.715057 -0.933144 +v 1.323726 -0.714266 -0.933149 +v 1.325006 -0.713202 -0.933142 +v 1.326056 -0.711908 -0.933125 +v 1.326836 -0.710432 -0.933099 +v 1.327315 -0.708831 -0.933063 +v 1.327475 -0.707167 -0.933020 +v 1.327309 -0.705504 -0.932970 +v 1.326825 -0.703906 -0.932917 +v 1.326041 -0.702433 -0.932862 +v 1.324986 -0.701143 -0.932807 +v 1.323702 -0.700085 -0.932754 +v 1.322238 -0.699300 -0.932706 +v 1.320650 -0.698819 -0.932664 +v 1.319169 -0.667146 -0.919432 +v 1.311353 -0.667939 -0.919312 +v 1.310937 -0.665607 -0.915374 +v 1.319235 -0.664766 -0.915501 +v 1.319111 -0.671086 -0.923103 +v 1.312077 -0.671800 -0.922995 +v 1.319064 -0.676435 -0.926373 +v 1.313082 -0.677042 -0.926282 +v 1.319028 -0.682987 -0.929117 +v 1.314328 -0.683465 -0.929045 +v 1.319006 -0.690492 -0.931230 +v 1.315768 -0.690820 -0.931180 +v 1.312657 -0.691778 -0.931150 +v 1.303839 -0.670253 -0.919240 +v 1.302961 -0.668065 -0.915298 +v 1.305315 -0.673882 -0.922930 +v 1.307331 -0.678813 -0.926227 +v 1.309810 -0.684856 -0.929002 +v 1.299086 -0.677254 -0.922911 +v 1.296918 -0.674000 -0.919219 +v 1.302034 -0.681681 -0.926210 +v 1.305648 -0.687109 -0.928989 +v 1.309790 -0.693330 -0.931142 +v 1.295614 -0.672042 -0.915275 +v 1.307278 -0.695416 -0.931154 +v 1.290855 -0.679035 -0.919249 +v 1.289176 -0.677387 -0.915307 +v 1.293629 -0.681786 -0.922938 +v 1.297393 -0.685535 -0.926233 +v 1.302001 -0.690137 -0.929007 +v 1.293586 -0.690227 -0.926295 +v 1.289153 -0.687303 -0.923010 +v 1.299011 -0.693824 -0.929055 +v 1.305218 -0.697955 -0.931187 +v 1.285882 -0.685165 -0.919329 +v 1.283897 -0.683895 -0.915392 +v 1.282190 -0.692155 -0.919456 +v 1.279979 -0.691315 -0.915527 +v 1.285831 -0.693594 -0.923125 +v 1.290761 -0.695576 -0.926392 +v 1.296791 -0.698027 -0.929132 +v 1.303689 -0.700850 -0.931240 +v 1.295428 -0.702585 -0.929234 +v 1.289026 -0.701378 -0.926522 +v 1.302750 -0.703990 -0.931310 +v 1.279923 -0.699735 -0.919626 +v 1.277571 -0.699363 -0.915707 +v 1.283790 -0.700416 -0.923277 +v 1.279166 -0.707615 -0.919831 +v 1.276768 -0.707728 -0.915925 +v 1.283109 -0.707507 -0.923462 +v 1.288447 -0.707409 -0.926679 +v 1.294973 -0.707324 -0.929357 +v 1.302436 -0.707254 -0.931395 +v 1.295444 -0.712060 -0.929497 +v 1.289046 -0.713437 -0.926857 +v 1.302761 -0.710517 -0.931492 +v 1.279949 -0.715492 -0.920064 +v 1.277599 -0.716089 -0.916172 +v 1.283814 -0.714596 -0.923672 +v 1.282242 -0.723062 -0.920316 +v 1.280034 -0.724126 -0.916440 +v 1.285878 -0.721409 -0.923898 +v 1.290801 -0.719232 -0.927050 +v 1.296823 -0.716612 -0.929649 +v 1.303710 -0.713653 -0.931596 +v 1.305249 -0.716541 -0.931704 +v 1.299056 -0.720806 -0.929806 +v 1.285957 -0.730035 -0.920577 +v 1.283977 -0.731529 -0.916717 +v 1.289221 -0.727685 -0.924134 +v 1.293644 -0.724569 -0.927250 +v 1.290950 -0.736144 -0.920837 +v 1.289278 -0.738014 -0.916993 +v 1.293715 -0.733183 -0.924368 +v 1.297466 -0.729244 -0.927449 +v 1.302059 -0.724479 -0.929962 +v 1.307317 -0.719071 -0.931812 +v 1.309836 -0.721146 -0.931915 +v 1.305716 -0.727491 -0.930113 +v 1.297031 -0.741153 -0.921087 +v 1.295733 -0.743331 -0.917258 +v 1.299187 -0.737691 -0.924592 +v 1.302120 -0.733078 -0.927640 +v 1.305428 -0.741035 -0.924798 +v 1.303964 -0.744870 -0.921316 +v 1.307427 -0.735922 -0.927815 +v 1.309885 -0.729726 -0.930250 +v 1.312708 -0.722686 -0.932010 +v 1.303094 -0.747277 -0.917501 +v 1.315824 -0.723631 -0.932093 +v 1.311485 -0.747151 -0.921516 +v 1.311078 -0.749699 -0.917713 +v 1.312196 -0.743089 -0.924978 +v 1.313183 -0.737669 -0.927968 +v 1.314408 -0.731098 -0.930370 +v 1.319167 -0.738249 -0.928093 +v 1.319233 -0.743772 -0.925125 +v 1.319110 -0.731555 -0.930468 +v 1.319062 -0.723945 -0.932160 +v 1.319304 -0.747910 -0.921679 +v 1.319378 -0.750504 -0.917886 +v 1.319304 -0.747910 -0.921679 +v 1.327120 -0.747117 -0.921798 +v 1.327676 -0.749663 -0.918014 +v 1.319378 -0.750504 -0.917886 +v 1.326267 -0.743058 -0.925233 +v 1.327120 -0.747117 -0.921798 +v 1.325149 -0.737642 -0.928185 +v 1.323810 -0.731078 -0.930540 +v 1.322300 -0.723616 -0.932210 +v 1.330899 -0.735871 -0.928240 +v 1.333029 -0.740975 -0.925297 +v 1.328328 -0.729686 -0.930584 +v 1.325412 -0.722658 -0.932240 +v 1.334633 -0.744803 -0.921870 +v 1.335652 -0.747206 -0.918090 +v 1.326267 -0.743058 -0.925233 +v 1.333029 -0.740975 -0.925297 +v 1.341555 -0.741056 -0.921892 +v 1.342999 -0.743228 -0.918113 +v 1.339258 -0.737603 -0.925317 +v 1.330899 -0.735871 -0.928240 +v 1.336197 -0.733003 -0.928256 +v 1.332490 -0.727433 -0.930597 +v 1.336197 -0.733003 -0.928256 +v 1.328279 -0.721106 -0.932249 +v 1.332490 -0.727433 -0.930597 +v 1.336136 -0.724405 -0.930578 +v 1.340838 -0.729150 -0.928233 +v 1.330790 -0.719020 -0.932236 +v 1.336136 -0.724405 -0.930578 +v 1.347618 -0.736021 -0.921862 +v 1.349437 -0.737883 -0.918081 +v 1.344715 -0.733072 -0.925290 +v 1.352591 -0.729890 -0.921782 +v 1.354716 -0.731375 -0.917996 +v 1.349190 -0.727555 -0.925218 +v 1.344644 -0.724458 -0.928172 +v 1.339127 -0.720719 -0.930530 +v 1.332850 -0.716481 -0.932203 +v 1.339127 -0.720719 -0.930530 +v 1.341347 -0.716516 -0.930454 +v 1.347469 -0.719108 -0.928074 +v 1.334379 -0.713586 -0.932150 +v 1.341347 -0.716516 -0.930454 +v 1.356282 -0.722901 -0.921654 +v 1.358635 -0.723955 -0.917861 +v 1.352512 -0.721264 -0.925103 +v 1.358550 -0.715320 -0.921485 +v 1.361042 -0.715908 -0.917681 +v 1.354553 -0.714442 -0.924951 +v 1.349205 -0.713306 -0.927945 +v 1.342710 -0.711957 -0.930352 +v 1.335319 -0.710446 -0.932080 +v 1.342710 -0.711957 -0.930352 +v 1.335632 -0.707182 -0.931995 +v 1.343165 -0.707219 -0.930228 +v 1.359307 -0.707441 -0.921280 +v 1.361845 -0.707543 -0.917463 +v 1.355234 -0.707350 -0.924766 +v 1.349784 -0.707275 -0.927788 +v 1.343165 -0.707219 -0.930228 +v 1.354529 -0.700262 -0.924556 +v 1.358524 -0.699564 -0.921047 +v 1.349185 -0.701247 -0.927609 +v 1.342694 -0.702482 -0.930088 +v 1.335308 -0.703919 -0.931899 +v 1.342694 -0.702482 -0.930088 +v 1.361014 -0.699181 -0.917216 +v 1.334358 -0.700784 -0.931794 +v 1.356230 -0.691994 -0.920795 +v 1.358580 -0.691144 -0.916948 +v 1.352466 -0.693449 -0.924330 +v 1.347430 -0.695453 -0.927416 +v 1.341315 -0.697930 -0.929937 +v 1.341315 -0.697930 -0.929937 +v 1.349123 -0.687173 -0.924094 +v 1.352516 -0.685020 -0.920534 +v 1.344586 -0.690115 -0.927217 +v 1.339082 -0.693736 -0.929780 +v 1.332819 -0.697895 -0.931686 +v 1.339082 -0.693736 -0.929780 +v 1.354636 -0.683741 -0.916671 +v 1.330750 -0.695365 -0.931578 +v 1.347523 -0.678912 -0.920273 +v 1.349335 -0.677256 -0.916394 +v 1.344629 -0.681675 -0.923860 +v 1.340765 -0.685440 -0.927017 +v 1.336079 -0.690063 -0.929623 +v 1.336079 -0.690063 -0.929623 +v 1.336111 -0.681607 -0.926826 +v 1.339157 -0.677167 -0.923635 +v 1.332422 -0.687051 -0.929473 +v 1.336111 -0.681607 -0.926826 +v 1.340765 -0.685440 -0.927017 +v 1.328232 -0.693290 -0.931475 +v 1.341442 -0.673903 -0.920024 +v 1.342880 -0.671939 -0.916130 +v 1.334508 -0.670186 -0.919795 +v 1.335519 -0.667994 -0.915886 +v 1.332916 -0.673822 -0.923429 +v 1.330804 -0.678762 -0.926651 +v 1.332916 -0.673822 -0.923429 +v 1.339157 -0.677167 -0.923635 +v 1.328253 -0.684816 -0.929336 +v 1.325360 -0.691751 -0.931380 +v 1.325047 -0.677016 -0.926498 +v 1.326148 -0.671769 -0.923250 +v 1.323730 -0.683444 -0.929215 +v 1.322245 -0.690805 -0.931297 +v 1.326988 -0.667905 -0.919595 +v 1.327535 -0.665571 -0.915674 +v 1.326988 -0.667905 -0.919595 +v 1.334508 -0.670186 -0.919795 +v 1.327535 -0.665571 -0.915674 +vt 0.655413 0.777137 +vt 0.655473 0.776509 +vt 0.655353 0.776509 +vt 0.655591 0.776533 +vt 0.655702 0.776580 +vt 0.655803 0.776649 +vt 0.655888 0.776736 +vt 0.655956 0.776839 +vt 0.656003 0.776953 +vt 0.656028 0.777074 +vt 0.656029 0.777198 +vt 0.656007 0.777319 +vt 0.655962 0.777433 +vt 0.655897 0.777536 +vt 0.655813 0.777623 +vt 0.655714 0.777692 +vt 0.655603 0.777739 +vt 0.655486 0.777763 +vt 0.655366 0.777763 +vt 0.655248 0.777739 +vt 0.655137 0.777692 +vt 0.655036 0.777623 +vt 0.654950 0.777536 +vt 0.654883 0.777433 +vt 0.654836 0.777319 +vt 0.654811 0.777198 +vt 0.654810 0.777074 +vt 0.654832 0.776953 +vt 0.654877 0.776839 +vt 0.654942 0.776736 +vt 0.655026 0.776649 +vt 0.655125 0.776580 +vt 0.655235 0.776533 +vt 0.655295 0.774127 +vt 0.655863 0.774127 +vt 0.655939 0.773932 +vt 0.655335 0.773932 +vt 0.655271 0.774436 +vt 0.655783 0.774436 +vt 0.655265 0.774845 +vt 0.655700 0.774845 +vt 0.655278 0.775341 +vt 0.655619 0.775341 +vt 0.655307 0.775902 +vt 0.655542 0.775902 +vt 0.655774 0.775950 +vt 0.656422 0.774242 +vt 0.656531 0.774053 +vt 0.656285 0.774538 +vt 0.656128 0.774933 +vt 0.655955 0.775409 +vt 0.656760 0.774740 +vt 0.656949 0.774465 +vt 0.656532 0.775104 +vt 0.656272 0.775544 +vt 0.655992 0.776042 +vt 0.657091 0.774291 +vt 0.656189 0.776177 +vt 0.657425 0.774790 +vt 0.657597 0.774636 +vt 0.657188 0.775032 +vt 0.656896 0.775353 +vt 0.656558 0.775739 +vt 0.657207 0.775669 +vt 0.657554 0.775405 +vt 0.656803 0.775988 +vt 0.656358 0.776348 +vt 0.657831 0.775204 +vt 0.658028 0.775075 +vt 0.658152 0.775691 +vt 0.658368 0.775592 +vt 0.657843 0.775843 +vt 0.657452 0.776042 +vt 0.656996 0.776281 +vt 0.656491 0.776550 +vt 0.657130 0.776606 +vt 0.657623 0.776455 +vt 0.656583 0.776774 +vt 0.658375 0.776231 +vt 0.658605 0.776166 +vt 0.658043 0.776329 +vt 0.658492 0.776805 +vt 0.658729 0.776775 +vt 0.658149 0.776845 +vt 0.657712 0.776895 +vt 0.657200 0.776951 +vt 0.656631 0.777011 +vt 0.657204 0.777302 +vt 0.657717 0.777342 +vt 0.656634 0.777254 +vt 0.658498 0.777390 +vt 0.658736 0.777396 +vt 0.658154 0.777372 +vt 0.658393 0.777964 +vt 0.658624 0.778005 +vt 0.658060 0.777888 +vt 0.657637 0.777781 +vt 0.657141 0.777647 +vt 0.656590 0.777491 +vt 0.656503 0.777715 +vt 0.657013 0.777973 +vt 0.658181 0.778504 +vt 0.658400 0.778579 +vt 0.657869 0.778375 +vt 0.657475 0.778195 +vt 0.657871 0.778991 +vt 0.658070 0.779095 +vt 0.657589 0.778813 +vt 0.657237 0.778567 +vt 0.656826 0.778265 +vt 0.656374 0.777917 +vt 0.656209 0.778088 +vt 0.656587 0.778514 +vt 0.657473 0.779404 +vt 0.657648 0.779534 +vt 0.657232 0.779185 +vt 0.656933 0.778884 +vt 0.656810 0.779477 +vt 0.657004 0.779729 +vt 0.656574 0.779133 +vt 0.656305 0.778709 +vt 0.656015 0.778223 +vt 0.657150 0.779879 +vt 0.655799 0.778315 +vt 0.656481 0.779953 +vt 0.656595 0.780117 +vt 0.656339 0.779679 +vt 0.656174 0.779304 +vt 0.655991 0.778844 +vt 0.655748 0.779392 +vt 0.655839 0.779782 +vt 0.655657 0.778912 +vt 0.655568 0.778363 +vt 0.655925 0.780067 +vt 0.656004 0.780238 +vt 0.946523 0.541543 +vt 0.946102 0.541430 +vt 0.945870 0.541606 +vt 0.946316 0.541726 +vt 0.655327 0.779782 +vt 0.655357 0.780067 +vt 0.655313 0.779392 +vt 0.655315 0.778912 +vt 0.655333 0.778363 +vt 0.654885 0.779304 +vt 0.654824 0.779679 +vt 0.654979 0.778844 +vt 0.655101 0.778315 +vt 0.945707 0.541206 +vt 0.945450 0.541369 +vt 0.946344 0.541143 +vt 0.945988 0.540943 +vt 0.945350 0.540882 +vt 0.945072 0.541024 +vt 0.945667 0.540650 +vt 0.946282 0.540588 +vt 0.946010 0.540339 +vt 0.654662 0.778709 +vt 0.654482 0.779133 +vt 0.654883 0.778223 +vt 0.946365 0.539960 +vt 0.946183 0.539711 +vt 0.945778 0.540023 +vt 0.654686 0.778088 +vt 0.654376 0.778514 +vt 0.945047 0.540468 +vt 0.944750 0.540585 +vt 0.945394 0.540278 +vt 0.944809 0.539982 +vt 0.944497 0.540069 +vt 0.945180 0.539841 +vt 0.945595 0.539650 +vt 0.946040 0.539419 +vt 0.654518 0.777917 +vt 0.654131 0.778265 +vt 0.945941 0.539094 +vt 0.945470 0.539237 +vt 0.654385 0.777715 +vt 0.653939 0.777973 +vt 0.944645 0.539441 +vt 0.944323 0.539495 +vt 0.945032 0.539354 +vt 0.944562 0.538867 +vt 0.944235 0.538885 +vt 0.944957 0.538837 +vt 0.945406 0.538797 +vt 0.945891 0.538749 +vt 0.654292 0.777491 +vt 0.653804 0.777647 +vt 0.654244 0.777254 +vt 0.653734 0.777302 +vt 0.944562 0.538281 +vt 0.944235 0.538264 +vt 0.944957 0.538310 +vt 0.945406 0.538349 +vt 0.945891 0.538396 +vt 0.945032 0.537793 +vt 0.944645 0.537707 +vt 0.945470 0.537909 +vt 0.945941 0.538051 +vt 0.654241 0.777011 +vt 0.653730 0.776951 +vt 0.944323 0.537654 +vt 0.654285 0.776774 +vt 0.944809 0.537166 +vt 0.944497 0.537079 +vt 0.945180 0.537306 +vt 0.945595 0.537495 +vt 0.946040 0.537725 +vt 0.653793 0.776606 +vt 0.945394 0.536867 +vt 0.945047 0.536678 +vt 0.945778 0.537122 +vt 0.946183 0.537432 +vt 0.654373 0.776550 +vt 0.653921 0.776281 +vt 0.944750 0.536562 +vt 0.654501 0.776348 +vt 0.945350 0.536264 +vt 0.945072 0.536122 +vt 0.945667 0.536494 +vt 0.946010 0.536805 +vt 0.946365 0.537183 +vt 0.654108 0.775988 +vt 0.946282 0.536555 +vt 0.945988 0.536201 +vt 0.654347 0.775739 +vt 0.654081 0.775353 +vt 0.653776 0.775669 +vt 0.654666 0.776177 +vt 0.945707 0.535938 +vt 0.945450 0.535775 +vt 0.946102 0.535713 +vt 0.945870 0.535537 +vt 0.946344 0.535998 +vt 0.654440 0.775104 +vt 0.654300 0.774740 +vt 0.653878 0.775032 +vt 0.654629 0.775544 +vt 0.654860 0.776042 +vt 0.654840 0.774933 +vt 0.654771 0.774538 +vt 0.654943 0.775409 +vt 0.655077 0.775950 +vt 0.946523 0.535598 +vt 0.946316 0.535414 +vt 0.654739 0.774242 +vt 0.654216 0.774465 +vt 0.654745 0.774053 +vn -0.0181 0.0278 -0.9994 +vn -0.0373 0.1227 -0.9917 +vn -0.0182 0.1246 -0.9920 +vn -0.0556 0.1171 -0.9916 +vn -0.0725 0.1081 -0.9915 +vn -0.0872 0.0960 -0.9916 +vn -0.0994 0.0812 -0.9917 +vn -0.1084 0.0645 -0.9920 +vn -0.1139 0.0463 -0.9924 +vn -0.1157 0.0274 -0.9929 +vn -0.1138 0.0086 -0.9935 +vn -0.1082 -0.0097 -0.9941 +vn -0.0992 -0.0264 -0.9947 +vn -0.0871 -0.0410 -0.9954 +vn -0.0723 -0.0530 -0.9960 +vn -0.0552 -0.0620 -0.9965 +vn -0.0369 -0.0675 -0.9970 +vn -0.0179 -0.0693 -0.9974 +vn 0.0012 -0.0674 -0.9977 +vn 0.0195 -0.0618 -0.9979 +vn 0.0364 -0.0528 -0.9979 +vn 0.0512 -0.0407 -0.9979 +vn 0.0633 -0.0260 -0.9977 +vn 0.0723 -0.0092 -0.9973 +vn 0.0778 0.0089 -0.9969 +vn 0.0796 0.0278 -0.9964 +vn 0.0777 0.0468 -0.9959 +vn 0.0721 0.0649 -0.9953 +vn 0.0631 0.0816 -0.9947 +vn 0.0509 0.0963 -0.9940 +vn 0.0361 0.1083 -0.9935 +vn 0.0192 0.1173 -0.9929 +vn 0.0009 0.1227 -0.9924 +vn -0.0130 0.7795 -0.6263 +vn -0.1627 0.7644 -0.6239 +vn -0.1763 0.8387 -0.5152 +vn -0.0112 0.8554 -0.5178 +vn -0.0157 0.6088 -0.7931 +vn -0.1310 0.5972 -0.7913 +vn -0.0171 0.4591 -0.8882 +vn -0.1024 0.4506 -0.8868 +vn -0.0178 0.3327 -0.9429 +vn -0.0780 0.3267 -0.9419 +vn -0.0181 0.2234 -0.9746 +vn -0.0567 0.2195 -0.9740 +vn -0.0938 0.2083 -0.9736 +vn -0.3065 0.7204 -0.6222 +vn -0.3349 0.7902 -0.5133 +vn -0.2417 0.5634 -0.7900 +vn -0.1845 0.4256 -0.8859 +vn -0.1359 0.3091 -0.9413 +vn -0.3436 0.5088 -0.7893 +vn -0.4387 0.6493 -0.6213 +vn -0.2600 0.3852 -0.8855 +vn -0.1892 0.2806 -0.9410 +vn -0.1279 0.1901 -0.9734 +vn -0.4807 0.7117 -0.5123 +vn -0.1578 0.1656 -0.9735 +vn -0.5542 0.5540 -0.6213 +vn -0.6080 0.6064 -0.5124 +vn -0.4327 0.4355 -0.7893 +vn -0.3261 0.3310 -0.8855 +vn -0.2359 0.2424 -0.9411 +vn -0.3802 0.2651 -0.8861 +vn -0.5057 0.3464 -0.7901 +vn -0.2741 0.1959 -0.9415 +vn -0.1823 0.1358 -0.9738 +vn -0.6486 0.4383 -0.6223 +vn -0.7122 0.4788 -0.5134 +vn -0.7186 0.3066 -0.6242 +vn -0.7893 0.3335 -0.5156 +vn -0.5598 0.2450 -0.7916 +vn -0.4203 0.1900 -0.8873 +vn -0.3025 0.1429 -0.9424 +vn -0.2005 0.1019 -0.9744 +vn -0.3199 0.0854 -0.9436 +vn -0.4450 0.1086 -0.8889 +vn -0.2117 0.0650 -0.9752 +vn -0.7614 0.1642 -0.6271 +vn -0.8366 0.1763 -0.5187 +vn -0.5929 0.1352 -0.7938 +vn -0.7757 0.0163 -0.6308 +vn -0.8523 0.0131 -0.5229 +vn -0.6040 0.0211 -0.7967 +vn -0.4532 0.0240 -0.8911 +vn -0.3257 0.0258 -0.9451 +vn -0.2154 0.0268 -0.9762 +vn -0.3197 -0.0339 -0.9469 +vn -0.4447 -0.0605 -0.8936 +vn -0.2116 -0.0114 -0.9773 +vn -0.7609 -0.1316 -0.6353 +vn -0.8360 -0.1500 -0.5278 +vn -0.5926 -0.0929 -0.8001 +vn -0.7176 -0.2739 -0.6404 +vn -0.7882 -0.3070 -0.5334 +vn -0.5590 -0.2025 -0.8040 +vn -0.4198 -0.1418 -0.8965 +vn -0.3021 -0.0913 -0.9489 +vn -0.2003 -0.0482 -0.9786 +vn -0.1820 -0.0821 -0.9799 +vn -0.2736 -0.1442 -0.9510 +vn -0.6472 -0.4051 -0.6458 +vn -0.7106 -0.4518 -0.5393 +vn -0.5046 -0.3037 -0.8082 +vn -0.3794 -0.2167 -0.8995 +vn -0.5523 -0.5204 -0.6512 +vn -0.6061 -0.5791 -0.5453 +vn -0.4313 -0.3924 -0.8124 +vn -0.3250 -0.2824 -0.9026 +vn -0.2351 -0.1905 -0.9531 +vn -0.1574 -0.1117 -0.9812 +vn -0.1274 -0.1361 -0.9825 +vn -0.1883 -0.2285 -0.9552 +vn -0.4365 -0.6152 -0.6565 +vn -0.4783 -0.6837 -0.5512 +vn -0.3420 -0.4653 -0.8164 +vn -0.2588 -0.3363 -0.9055 +vn -0.2399 -0.5194 -0.8201 +vn -0.3041 -0.6857 -0.6613 +vn -0.1831 -0.3763 -0.9082 +vn -0.1349 -0.2567 -0.9570 +vn -0.0932 -0.1541 -0.9836 +vn -0.3323 -0.7616 -0.5564 +vn -0.0560 -0.1652 -0.9847 +vn -0.1602 -0.7290 -0.6655 +vn -0.1736 -0.8094 -0.5610 +vn -0.1290 -0.5527 -0.8233 +vn -0.1010 -0.4009 -0.9105 +vn -0.0770 -0.2741 -0.9586 +vn -0.0156 -0.4091 -0.9124 +vn -0.0137 -0.5638 -0.8258 +vn -0.0167 -0.2798 -0.9599 +vn -0.0174 -0.1689 -0.9855 +vn -0.0105 -0.7435 -0.6686 +vn -0.0084 -0.8254 -0.5645 +vn 0.1393 -0.7284 -0.6708 +vn 0.1567 -0.8087 -0.5670 +vn 0.1016 -0.5522 -0.8275 +vn 0.1392 -0.7284 -0.6709 +vn 0.0698 -0.4005 -0.9136 +vn 0.0435 -0.2738 -0.9608 +vn 0.0211 -0.1651 -0.9861 +vn 0.1518 -0.3756 -0.9143 +vn 0.2123 -0.5184 -0.8283 +vn 0.1014 -0.2562 -0.9613 +vn 0.0582 -0.1538 -0.9864 +vn 0.2830 -0.6844 -0.6719 +vn 0.3153 -0.7601 -0.5681 +vn 0.2123 -0.5185 -0.8283 +vn 0.4152 -0.6133 -0.6719 +vn 0.4611 -0.6817 -0.5681 +vn 0.3143 -0.4639 -0.8283 +vn 0.2273 -0.3352 -0.9143 +vn 0.1547 -0.2278 -0.9613 +vn 0.0924 -0.1356 -0.9864 +vn 0.1547 -0.2277 -0.9614 +vn 0.2013 -0.1895 -0.9610 +vn 0.2934 -0.2810 -0.9137 +vn 0.1223 -0.1111 -0.9863 +vn 0.2014 -0.1895 -0.9610 +vn 0.5307 -0.5180 -0.6708 +vn 0.5885 -0.5765 -0.5669 +vn 0.4034 -0.3906 -0.8275 +vn 0.6252 -0.4023 -0.6688 +vn 0.6926 -0.4488 -0.5647 +vn 0.4764 -0.3015 -0.8259 +vn 0.3476 -0.2151 -0.9126 +vn 0.2396 -0.1430 -0.9603 +vn 0.1468 -0.0813 -0.9858 +vn 0.2396 -0.1431 -0.9603 +vn 0.2680 -0.0900 -0.9592 +vn 0.3877 -0.1400 -0.9111 +vn 0.1650 -0.0474 -0.9852 +vn 0.2680 -0.0901 -0.9592 +vn 0.6951 -0.2708 -0.6660 +vn 0.7697 -0.3036 -0.5616 +vn 0.5305 -0.2002 -0.8237 +vn 0.7380 -0.1283 -0.6624 +vn 0.8170 -0.1464 -0.5577 +vn 0.5637 -0.0904 -0.8211 +vn 0.4124 -0.0586 -0.9091 +vn 0.2854 -0.0326 -0.9579 +vn 0.1761 -0.0106 -0.9843 +vn 0.2854 -0.0326 -0.9578 +vn 0.1799 0.0276 -0.9833 +vn 0.2912 0.0271 -0.9563 +vn 0.7523 0.0196 -0.6585 +vn 0.8328 0.0168 -0.5533 +vn 0.5747 0.0237 -0.8180 +vn 0.4206 0.0259 -0.9069 +vn 0.5633 0.1377 -0.8147 +vn 0.7375 0.1674 -0.6542 +vn 0.4121 0.1105 -0.9044 +vn 0.2852 0.0867 -0.9545 +vn 0.1760 0.0659 -0.9822 +vn 0.2853 0.0867 -0.9545 +vn 0.8165 0.1799 -0.5486 +vn 0.1647 0.1027 -0.9810 +vn 0.6941 0.3097 -0.6498 +vn 0.7686 0.3369 -0.5438 +vn 0.5297 0.2474 -0.8113 +vn 0.3872 0.1917 -0.9018 +vn 0.2676 0.1441 -0.9527 +vn 0.4753 0.3486 -0.8078 +vn 0.6238 0.4410 -0.6453 +vn 0.3468 0.2667 -0.8992 +vn 0.2390 0.1970 -0.9508 +vn 0.1464 0.1365 -0.9798 +vn 0.6911 0.4818 -0.5388 +vn 0.1218 0.1662 -0.9785 +vn 0.5289 0.5563 -0.6409 +vn 0.5865 0.6091 -0.5340 +vn 0.4020 0.4373 -0.8044 +vn 0.2924 0.3324 -0.8967 +vn 0.2006 0.2433 -0.9490 +vn 0.2262 0.3863 -0.8942 +vn 0.3126 0.5103 -0.8012 +vn 0.1538 0.2814 -0.9472 +vn 0.2261 0.3863 -0.8943 +vn 0.2924 0.3323 -0.8967 +vn 0.0918 0.1905 -0.9774 +vn 0.4131 0.6511 -0.6367 +vn 0.4588 0.7137 -0.5293 +vn 0.2806 0.7217 -0.6328 +vn 0.3127 0.7916 -0.5250 +vn 0.2105 0.5644 -0.7982 +vn 0.1504 0.4263 -0.8920 +vn 0.3127 0.5103 -0.8012 +vn 0.1005 0.3096 -0.9455 +vn 0.0576 0.2086 -0.9763 +vn 0.0684 0.4509 -0.8899 +vn 0.0997 0.5977 -0.7955 +vn 0.0425 0.3269 -0.9441 +vn 0.0204 0.2197 -0.9754 +vn 0.1367 0.7650 -0.6293 +vn 0.1540 0.8395 -0.5211 +vn 0.1539 0.8395 -0.5211 +usemtl Scene_-_Root +s 1 +f 45639/45639/34482 45640/45640/34483 45641/45641/34484 +f 45639/45639/34482 45642/45642/34485 45640/45640/34483 +f 45639/45639/34482 45643/45643/34486 45642/45642/34485 +f 45639/45639/34482 45644/45644/34487 45643/45643/34486 +f 45639/45639/34482 45645/45645/34488 45644/45644/34487 +f 45639/45639/34482 45646/45646/34489 45645/45645/34488 +f 45639/45639/34482 45647/45647/34490 45646/45646/34489 +f 45639/45639/34482 45648/45648/34491 45647/45647/34490 +f 45639/45639/34482 45649/45649/34492 45648/45648/34491 +f 45639/45639/34482 45650/45650/34493 45649/45649/34492 +f 45639/45639/34482 45651/45651/34494 45650/45650/34493 +f 45639/45639/34482 45652/45652/34495 45651/45651/34494 +f 45639/45639/34482 45653/45653/34496 45652/45652/34495 +f 45639/45639/34482 45654/45654/34497 45653/45653/34496 +f 45639/45639/34482 45655/45655/34498 45654/45654/34497 +f 45639/45639/34482 45656/45656/34499 45655/45655/34498 +f 45639/45639/34482 45657/45657/34500 45656/45656/34499 +f 45639/45639/34482 45658/45658/34501 45657/45657/34500 +f 45639/45639/34482 45659/45659/34502 45658/45658/34501 +f 45639/45639/34482 45660/45660/34503 45659/45659/34502 +f 45639/45639/34482 45661/45661/34504 45660/45660/34503 +f 45639/45639/34482 45662/45662/34505 45661/45661/34504 +f 45639/45639/34482 45663/45663/34506 45662/45662/34505 +f 45639/45639/34482 45664/45664/34507 45663/45663/34506 +f 45639/45639/34482 45665/45665/34508 45664/45664/34507 +f 45639/45639/34482 45666/45666/34509 45665/45665/34508 +f 45639/45639/34482 45667/45667/34510 45666/45666/34509 +f 45639/45639/34482 45668/45668/34511 45667/45667/34510 +f 45639/45639/34482 45669/45669/34512 45668/45668/34511 +f 45639/45639/34482 45670/45670/34513 45669/45669/34512 +f 45639/45639/34482 45671/45671/34514 45670/45670/34513 +f 45639/45639/34482 45641/45641/34484 45671/45671/34514 +f 45672/45672/34515 45673/45673/34516 45674/45674/34517 +f 45672/45672/34515 45674/45674/34517 45675/45675/34518 +f 45676/45676/34519 45677/45677/34520 45673/45673/34516 +f 45676/45676/34519 45673/45673/34516 45672/45672/34515 +f 45678/45678/34521 45679/45679/34522 45677/45677/34520 +f 45678/45678/34521 45677/45677/34520 45676/45676/34519 +f 45680/45680/34523 45681/45681/34524 45679/45679/34522 +f 45680/45680/34523 45679/45679/34522 45678/45678/34521 +f 45682/45682/34525 45683/45683/34526 45681/45681/34524 +f 45682/45682/34525 45681/45681/34524 45680/45680/34523 +f 45641/45641/34484 45640/45640/34483 45683/45683/34526 +f 45641/45641/34484 45683/45683/34526 45682/45682/34525 +f 45640/45640/34483 45642/45642/34485 45684/45684/34527 +f 45640/45640/34483 45684/45684/34527 45683/45683/34526 +f 45673/45673/34516 45685/45685/34528 45686/45686/34529 +f 45673/45673/34516 45686/45686/34529 45674/45674/34517 +f 45677/45677/34520 45687/45687/34530 45685/45685/34528 +f 45677/45677/34520 45685/45685/34528 45673/45673/34516 +f 45679/45679/34522 45688/45688/34531 45687/45687/34530 +f 45679/45679/34522 45687/45687/34530 45677/45677/34520 +f 45681/45681/34524 45689/45689/34532 45688/45688/34531 +f 45681/45681/34524 45688/45688/34531 45679/45679/34522 +f 45683/45683/34526 45684/45684/34527 45689/45689/34532 +f 45683/45683/34526 45689/45689/34532 45681/45681/34524 +f 45687/45687/34530 45690/45690/34533 45691/45691/34534 +f 45687/45687/34530 45691/45691/34534 45685/45685/34528 +f 45688/45688/34531 45692/45692/34535 45690/45690/34533 +f 45688/45688/34531 45690/45690/34533 45687/45687/34530 +f 45689/45689/34532 45693/45693/34536 45692/45692/34535 +f 45689/45689/34532 45692/45692/34535 45688/45688/34531 +f 45684/45684/34527 45694/45694/34537 45693/45693/34536 +f 45684/45684/34527 45693/45693/34536 45689/45689/34532 +f 45642/45642/34485 45643/45643/34486 45694/45694/34537 +f 45642/45642/34485 45694/45694/34537 45684/45684/34527 +f 45685/45685/34528 45691/45691/34534 45695/45695/34538 +f 45685/45685/34528 45695/45695/34538 45686/45686/34529 +f 45643/45643/34486 45644/45644/34487 45696/45696/34539 +f 45643/45643/34486 45696/45696/34539 45694/45694/34537 +f 45691/45691/34534 45697/45697/34540 45698/45698/34541 +f 45691/45691/34534 45698/45698/34541 45695/45695/34538 +f 45690/45690/34533 45699/45699/34542 45697/45697/34540 +f 45690/45690/34533 45697/45697/34540 45691/45691/34534 +f 45692/45692/34535 45700/45700/34543 45699/45699/34542 +f 45692/45692/34535 45699/45699/34542 45690/45690/34533 +f 45693/45693/34536 45701/45701/34544 45700/45700/34543 +f 45693/45693/34536 45700/45700/34543 45692/45692/34535 +f 45694/45694/34537 45696/45696/34539 45701/45701/34544 +f 45694/45694/34537 45701/45701/34544 45693/45693/34536 +f 45700/45700/34543 45702/45702/34545 45703/45703/34546 +f 45700/45700/34543 45703/45703/34546 45699/45699/34542 +f 45701/45701/34544 45704/45704/34547 45702/45702/34545 +f 45701/45701/34544 45702/45702/34545 45700/45700/34543 +f 45696/45696/34539 45705/45705/34548 45704/45704/34547 +f 45696/45696/34539 45704/45704/34547 45701/45701/34544 +f 45644/45644/34487 45645/45645/34488 45705/45705/34548 +f 45644/45644/34487 45705/45705/34548 45696/45696/34539 +f 45697/45697/34540 45706/45706/34549 45707/45707/34550 +f 45697/45697/34540 45707/45707/34550 45698/45698/34541 +f 45699/45699/34542 45703/45703/34546 45706/45706/34549 +f 45699/45699/34542 45706/45706/34549 45697/45697/34540 +f 45706/45706/34549 45708/45708/34551 45709/45709/34552 +f 45706/45706/34549 45709/45709/34552 45707/45707/34550 +f 45703/45703/34546 45710/45710/34553 45708/45708/34551 +f 45703/45703/34546 45708/45708/34551 45706/45706/34549 +f 45702/45702/34545 45711/45711/34554 45710/45710/34553 +f 45702/45702/34545 45710/45710/34553 45703/45703/34546 +f 45704/45704/34547 45712/45712/34555 45711/45711/34554 +f 45704/45704/34547 45711/45711/34554 45702/45702/34545 +f 45705/45705/34548 45713/45713/34556 45712/45712/34555 +f 45705/45705/34548 45712/45712/34555 45704/45704/34547 +f 45645/45645/34488 45646/45646/34489 45713/45713/34556 +f 45645/45645/34488 45713/45713/34556 45705/45705/34548 +f 45712/45712/34555 45714/45714/34557 45715/45715/34558 +f 45712/45712/34555 45715/45715/34558 45711/45711/34554 +f 45713/45713/34556 45716/45716/34559 45714/45714/34557 +f 45713/45713/34556 45714/45714/34557 45712/45712/34555 +f 45646/45646/34489 45647/45647/34490 45716/45716/34559 +f 45646/45646/34489 45716/45716/34559 45713/45713/34556 +f 45708/45708/34551 45717/45717/34560 45718/45718/34561 +f 45708/45708/34551 45718/45718/34561 45709/45709/34552 +f 45710/45710/34553 45719/45719/34562 45717/45717/34560 +f 45710/45710/34553 45717/45717/34560 45708/45708/34551 +f 45711/45711/34554 45715/45715/34558 45719/45719/34562 +f 45711/45711/34554 45719/45719/34562 45710/45710/34553 +f 45717/45717/34560 45720/45720/34563 45721/45721/34564 +f 45717/45717/34560 45721/45721/34564 45718/45718/34561 +f 45719/45719/34562 45722/45722/34565 45720/45720/34563 +f 45719/45719/34562 45720/45720/34563 45717/45717/34560 +f 45715/45715/34558 45723/45723/34566 45722/45722/34565 +f 45715/45715/34558 45722/45722/34565 45719/45719/34562 +f 45714/45714/34557 45724/45724/34567 45723/45723/34566 +f 45714/45714/34557 45723/45723/34566 45715/45715/34558 +f 45716/45716/34559 45725/45725/34568 45724/45724/34567 +f 45716/45716/34559 45724/45724/34567 45714/45714/34557 +f 45647/45647/34490 45648/45648/34491 45725/45725/34568 +f 45647/45647/34490 45725/45725/34568 45716/45716/34559 +f 45724/45724/34567 45726/45726/34569 45727/45727/34570 +f 45724/45724/34567 45727/45727/34570 45723/45723/34566 +f 45725/45725/34568 45728/45728/34571 45726/45726/34569 +f 45725/45725/34568 45726/45726/34569 45724/45724/34567 +f 45648/45648/34491 45649/45649/34492 45728/45728/34571 +f 45648/45648/34491 45728/45728/34571 45725/45725/34568 +f 45720/45720/34563 45729/45729/34572 45730/45730/34573 +f 45720/45720/34563 45730/45730/34573 45721/45721/34564 +f 45722/45722/34565 45731/45731/34574 45729/45729/34572 +f 45722/45722/34565 45729/45729/34572 45720/45720/34563 +f 45723/45723/34566 45727/45727/34570 45731/45731/34574 +f 45723/45723/34566 45731/45731/34574 45722/45722/34565 +f 45729/45729/34572 45732/45732/34575 45733/45733/34576 +f 45729/45729/34572 45733/45733/34576 45730/45730/34573 +f 45731/45731/34574 45734/45734/34577 45732/45732/34575 +f 45731/45731/34574 45732/45732/34575 45729/45729/34572 +f 45727/45727/34570 45735/45735/34578 45734/45734/34577 +f 45727/45727/34570 45734/45734/34577 45731/45731/34574 +f 45726/45726/34569 45736/45736/34579 45735/45735/34578 +f 45726/45726/34569 45735/45735/34578 45727/45727/34570 +f 45728/45728/34571 45737/45737/34580 45736/45736/34579 +f 45728/45728/34571 45736/45736/34579 45726/45726/34569 +f 45649/45649/34492 45650/45650/34493 45737/45737/34580 +f 45649/45649/34492 45737/45737/34580 45728/45728/34571 +f 45737/45737/34580 45738/45738/34581 45739/45739/34582 +f 45737/45737/34580 45739/45739/34582 45736/45736/34579 +f 45650/45650/34493 45651/45651/34494 45738/45738/34581 +f 45650/45650/34493 45738/45738/34581 45737/45737/34580 +f 45732/45732/34575 45740/45740/34583 45741/45741/34584 +f 45732/45732/34575 45741/45741/34584 45733/45733/34576 +f 45734/45734/34577 45742/45742/34585 45740/45740/34583 +f 45734/45734/34577 45740/45740/34583 45732/45732/34575 +f 45735/45735/34578 45743/45743/34586 45742/45742/34585 +f 45735/45735/34578 45742/45742/34585 45734/45734/34577 +f 45736/45736/34579 45739/45739/34582 45743/45743/34586 +f 45736/45736/34579 45743/45743/34586 45735/45735/34578 +f 45740/45740/34583 45744/45744/34587 45745/45745/34588 +f 45740/45740/34583 45745/45745/34588 45741/45741/34584 +f 45742/45742/34585 45746/45746/34589 45744/45744/34587 +f 45742/45742/34585 45744/45744/34587 45740/45740/34583 +f 45743/45743/34586 45747/45747/34590 45746/45746/34589 +f 45743/45743/34586 45746/45746/34589 45742/45742/34585 +f 45739/45739/34582 45748/45748/34591 45747/45747/34590 +f 45739/45739/34582 45747/45747/34590 45743/45743/34586 +f 45738/45738/34581 45749/45749/34592 45748/45748/34591 +f 45738/45738/34581 45748/45748/34591 45739/45739/34582 +f 45651/45651/34494 45652/45652/34495 45749/45749/34592 +f 45651/45651/34494 45749/45749/34592 45738/45738/34581 +f 45749/45749/34592 45750/45750/34593 45751/45751/34594 +f 45749/45749/34592 45751/45751/34594 45748/45748/34591 +f 45652/45652/34495 45653/45653/34496 45750/45750/34593 +f 45652/45652/34495 45750/45750/34593 45749/45749/34592 +f 45744/45744/34587 45752/45752/34595 45753/45753/34596 +f 45744/45744/34587 45753/45753/34596 45745/45745/34588 +f 45746/45746/34589 45754/45754/34597 45752/45752/34595 +f 45746/45746/34589 45752/45752/34595 45744/45744/34587 +f 45747/45747/34590 45755/45755/34598 45754/45754/34597 +f 45747/45747/34590 45754/45754/34597 45746/45746/34589 +f 45748/45748/34591 45751/45751/34594 45755/45755/34598 +f 45748/45748/34591 45755/45755/34598 45747/45747/34590 +f 45754/45754/34597 45756/45756/34599 45757/45757/34600 +f 45754/45754/34597 45757/45757/34600 45752/45752/34595 +f 45755/45755/34598 45758/45758/34601 45756/45756/34599 +f 45755/45755/34598 45756/45756/34599 45754/45754/34597 +f 45751/45751/34594 45759/45759/34602 45758/45758/34601 +f 45751/45751/34594 45758/45758/34601 45755/45755/34598 +f 45750/45750/34593 45760/45760/34603 45759/45759/34602 +f 45750/45750/34593 45759/45759/34602 45751/45751/34594 +f 45653/45653/34496 45654/45654/34497 45760/45760/34603 +f 45653/45653/34496 45760/45760/34603 45750/45750/34593 +f 45752/45752/34595 45757/45757/34600 45761/45761/34604 +f 45752/45752/34595 45761/45761/34604 45753/45753/34596 +f 45654/45654/34497 45655/45655/34498 45762/45762/34605 +f 45654/45654/34497 45762/45762/34605 45760/45760/34603 +f 45757/45757/34600 45763/45763/34606 45764/45764/34607 +f 45757/45757/34600 45764/45764/34607 45761/45761/34604 +f 45756/45756/34599 45765/45765/34608 45763/45763/34606 +f 45756/45756/34599 45763/45763/34606 45757/45757/34600 +f 45758/45758/34601 45766/45766/34609 45765/45765/34608 +f 45758/45758/34601 45765/45765/34608 45756/45756/34599 +f 45759/45759/34602 45767/45767/34610 45766/45766/34609 +f 45759/45759/34602 45766/45766/34609 45758/45758/34601 +f 45760/45760/34603 45762/45762/34605 45767/45767/34610 +f 45760/45760/34603 45767/45767/34610 45759/45759/34602 +f 45766/45766/34609 45768/45768/34611 45769/45769/34612 +f 45766/45766/34609 45769/45769/34612 45765/45765/34608 +f 45767/45767/34610 45770/45770/34613 45768/45768/34611 +f 45767/45767/34610 45768/45768/34611 45766/45766/34609 +f 45762/45762/34605 45771/45771/34614 45770/45770/34613 +f 45762/45762/34605 45770/45770/34613 45767/45767/34610 +f 45655/45655/34498 45656/45656/34499 45771/45771/34614 +f 45655/45655/34498 45771/45771/34614 45762/45762/34605 +f 45763/45763/34606 45772/45772/34615 45773/45773/34616 +f 45763/45763/34606 45773/45773/34616 45764/45764/34607 +f 45765/45765/34608 45769/45769/34612 45772/45772/34615 +f 45765/45765/34608 45772/45772/34615 45763/45763/34606 +f 45774/45774/34615 45775/45775/34617 45776/45776/34618 +f 45774/45774/34615 45776/45776/34618 45777/45777/34616 +f 45769/45769/34612 45778/45778/34619 45779/45779/34620 +f 45769/45769/34612 45779/45779/34620 45772/45772/34615 +f 45768/45768/34611 45780/45780/34621 45778/45778/34619 +f 45768/45768/34611 45778/45778/34619 45769/45769/34612 +f 45770/45770/34613 45781/45781/34622 45780/45780/34621 +f 45770/45770/34613 45780/45780/34621 45768/45768/34611 +f 45771/45771/34614 45782/45782/34623 45781/45781/34622 +f 45771/45771/34614 45781/45781/34622 45770/45770/34613 +f 45656/45656/34499 45657/45657/34500 45782/45782/34623 +f 45656/45656/34499 45782/45782/34623 45771/45771/34614 +f 45780/45780/34621 45783/45783/34624 45784/45784/34625 +f 45780/45780/34621 45784/45784/34625 45778/45778/34619 +f 45781/45781/34622 45785/45785/34626 45783/45783/34624 +f 45781/45781/34622 45783/45783/34624 45780/45780/34621 +f 45782/45782/34623 45786/45786/34627 45785/45785/34626 +f 45782/45782/34623 45785/45785/34626 45781/45781/34622 +f 45657/45657/34500 45658/45658/34501 45786/45786/34627 +f 45657/45657/34500 45786/45786/34627 45782/45782/34623 +f 45775/45775/34617 45787/45787/34628 45788/45788/34629 +f 45775/45775/34617 45788/45788/34629 45776/45776/34618 +f 45789/45789/34619 45790/45790/34630 45787/45787/34628 +f 45789/45789/34619 45787/45787/34628 45775/45775/34617 +f 45787/45787/34628 45791/45791/34631 45792/45792/34632 +f 45787/45787/34628 45792/45792/34632 45788/45788/34629 +f 45790/45790/34630 45793/45793/34633 45791/45791/34631 +f 45790/45790/34630 45791/45791/34631 45787/45787/34628 +f 45794/45794/34624 45795/45795/34634 45793/45793/34633 +f 45794/45794/34624 45793/45793/34633 45790/45790/34630 +f 45785/45785/34626 45796/45796/34635 45797/45797/34634 +f 45785/45785/34626 45797/45797/34634 45783/45783/34624 +f 45786/45786/34627 45798/45798/34636 45796/45796/34635 +f 45786/45786/34627 45796/45796/34635 45785/45785/34626 +f 45658/45658/34501 45659/45659/34502 45798/45798/34636 +f 45658/45658/34501 45798/45798/34636 45786/45786/34627 +f 45799/45799/34637 45800/45800/34638 45801/45801/34639 +f 45799/45799/34637 45801/45801/34639 45795/45795/34634 +f 45798/45798/34636 45802/45802/34640 45803/45803/34641 +f 45798/45798/34636 45803/45803/34641 45796/45796/34635 +f 45659/45659/34502 45660/45660/34503 45802/45802/34640 +f 45659/45659/34502 45802/45802/34640 45798/45798/34636 +f 45791/45791/34631 45804/45804/34642 45805/45805/34643 +f 45791/45791/34631 45805/45805/34643 45792/45792/34632 +f 45793/45793/34633 45806/45806/34644 45804/45804/34642 +f 45793/45793/34633 45804/45804/34642 45791/45791/34631 +f 45795/45795/34634 45801/45801/34639 45806/45806/34644 +f 45795/45795/34634 45806/45806/34644 45793/45793/34633 +f 45804/45804/34642 45807/45807/34645 45808/45808/34646 +f 45804/45804/34642 45808/45808/34646 45805/45805/34643 +f 45806/45806/34644 45809/45809/34647 45807/45807/34645 +f 45806/45806/34644 45807/45807/34645 45804/45804/34642 +f 45801/45801/34639 45810/45810/34648 45809/45809/34647 +f 45801/45801/34639 45809/45809/34647 45806/45806/34644 +f 45800/45800/34638 45811/45811/34649 45810/45810/34648 +f 45800/45800/34638 45810/45810/34648 45801/45801/34639 +f 45802/45802/34640 45812/45812/34650 45813/45813/34651 +f 45802/45802/34640 45813/45813/34651 45803/45803/34641 +f 45660/45660/34503 45661/45661/34504 45812/45812/34650 +f 45660/45660/34503 45812/45812/34650 45802/45802/34640 +f 45811/45811/34649 45814/45814/34652 45815/45815/34653 +f 45811/45811/34649 45815/45815/34653 45810/45810/34648 +f 45812/45812/34650 45816/45816/34654 45817/45817/34655 +f 45812/45812/34650 45817/45817/34655 45813/45813/34651 +f 45661/45661/34504 45662/45662/34505 45816/45816/34654 +f 45661/45661/34504 45816/45816/34654 45812/45812/34650 +f 45807/45807/34645 45818/45818/34656 45819/45819/34657 +f 45807/45807/34645 45819/45819/34657 45808/45808/34646 +f 45809/45809/34647 45820/45820/34658 45818/45818/34656 +f 45809/45809/34647 45818/45818/34656 45807/45807/34645 +f 45810/45810/34648 45815/45815/34653 45820/45820/34658 +f 45810/45810/34648 45820/45820/34658 45809/45809/34647 +f 45818/45818/34656 45821/45821/34659 45822/45822/34660 +f 45818/45818/34656 45822/45822/34660 45819/45819/34657 +f 45820/45820/34658 45823/45823/34661 45821/45821/34659 +f 45820/45820/34658 45821/45821/34659 45818/45818/34656 +f 45815/45815/34653 45824/45824/34662 45823/45823/34661 +f 45815/45815/34653 45823/45823/34661 45820/45820/34658 +f 45814/45814/34652 45825/45825/34663 45824/45824/34662 +f 45814/45814/34652 45824/45824/34662 45815/45815/34653 +f 45816/45816/34654 45826/45826/34664 45827/45827/34665 +f 45816/45816/34654 45827/45827/34665 45817/45817/34655 +f 45662/45662/34505 45663/45663/34506 45826/45826/34664 +f 45662/45662/34505 45826/45826/34664 45816/45816/34654 +f 45826/45826/34664 45828/45828/34666 45829/45829/34667 +f 45826/45826/34664 45829/45829/34667 45827/45827/34665 +f 45663/45663/34506 45664/45664/34507 45828/45828/34666 +f 45663/45663/34506 45828/45828/34666 45826/45826/34664 +f 45821/45821/34659 45830/45830/34668 45831/45831/34669 +f 45821/45821/34659 45831/45831/34669 45822/45822/34660 +f 45823/45823/34661 45832/45832/34670 45830/45830/34668 +f 45823/45823/34661 45830/45830/34668 45821/45821/34659 +f 45824/45824/34662 45833/45833/34671 45832/45832/34670 +f 45824/45824/34662 45832/45832/34670 45823/45823/34661 +f 45825/45825/34663 45834/45834/34667 45833/45833/34671 +f 45825/45825/34663 45833/45833/34671 45824/45824/34662 +f 45832/45832/34670 45835/45835/34672 45836/45836/34673 +f 45832/45832/34670 45836/45836/34673 45830/45830/34668 +f 45833/45833/34671 45837/45837/34674 45835/45835/34672 +f 45833/45833/34671 45835/45835/34672 45832/45832/34670 +f 45834/45834/34667 45838/45838/34675 45837/45837/34674 +f 45834/45834/34667 45837/45837/34674 45833/45833/34671 +f 45828/45828/34666 45839/45839/34676 45840/45840/34677 +f 45828/45828/34666 45840/45840/34677 45829/45829/34667 +f 45664/45664/34507 45665/45665/34508 45839/45839/34676 +f 45664/45664/34507 45839/45839/34676 45828/45828/34666 +f 45830/45830/34668 45836/45836/34673 45841/45841/34678 +f 45830/45830/34668 45841/45841/34678 45831/45831/34669 +f 45665/45665/34508 45666/45666/34509 45842/45842/34679 +f 45665/45665/34508 45842/45842/34679 45839/45839/34676 +f 45836/45836/34673 45843/45843/34680 45844/45844/34681 +f 45836/45836/34673 45844/45844/34681 45841/45841/34678 +f 45835/45835/34672 45845/45845/34682 45843/45843/34680 +f 45835/45835/34672 45843/45843/34680 45836/45836/34673 +f 45837/45837/34674 45846/45846/34683 45845/45845/34682 +f 45837/45837/34674 45845/45845/34682 45835/45835/34672 +f 45838/45838/34675 45847/45847/34684 45846/45846/34683 +f 45838/45838/34675 45846/45846/34683 45837/45837/34674 +f 45839/45839/34676 45842/45842/34679 45848/45848/34684 +f 45839/45839/34676 45848/45848/34684 45840/45840/34677 +f 45845/45845/34682 45849/45849/34685 45850/45850/34686 +f 45845/45845/34682 45850/45850/34686 45843/45843/34680 +f 45846/45846/34683 45851/45851/34687 45849/45849/34685 +f 45846/45846/34683 45849/45849/34685 45845/45845/34682 +f 45847/45847/34684 45852/45852/34688 45851/45851/34687 +f 45847/45847/34684 45851/45851/34687 45846/45846/34683 +f 45842/45842/34679 45853/45853/34689 45854/45854/34688 +f 45842/45842/34679 45854/45854/34688 45848/45848/34684 +f 45666/45666/34509 45667/45667/34510 45853/45853/34689 +f 45666/45666/34509 45853/45853/34689 45842/45842/34679 +f 45843/45843/34680 45850/45850/34686 45855/45855/34690 +f 45843/45843/34680 45855/45855/34690 45844/45844/34681 +f 45667/45667/34510 45668/45668/34511 45856/45856/34691 +f 45667/45667/34510 45856/45856/34691 45853/45853/34689 +f 45850/45850/34686 45857/45857/34692 45858/45858/34693 +f 45850/45850/34686 45858/45858/34693 45855/45855/34690 +f 45849/45849/34685 45859/45859/34694 45857/45857/34692 +f 45849/45849/34685 45857/45857/34692 45850/45850/34686 +f 45851/45851/34687 45860/45860/34695 45859/45859/34694 +f 45851/45851/34687 45859/45859/34694 45849/45849/34685 +f 45852/45852/34688 45861/45861/34696 45860/45860/34695 +f 45852/45852/34688 45860/45860/34695 45851/45851/34687 +f 45853/45853/34689 45856/45856/34691 45862/45862/34696 +f 45853/45853/34689 45862/45862/34696 45854/45854/34688 +f 45860/45860/34695 45863/45863/34697 45864/45864/34698 +f 45860/45860/34695 45864/45864/34698 45859/45859/34694 +f 45862/45862/34696 45865/45865/34699 45866/45866/34700 +f 45862/45862/34696 45866/45866/34700 45867/45867/34701 +f 45856/45856/34691 45868/45868/34702 45865/45865/34699 +f 45856/45856/34691 45865/45865/34699 45862/45862/34696 +f 45668/45668/34511 45669/45669/34512 45868/45868/34702 +f 45668/45668/34511 45868/45868/34702 45856/45856/34691 +f 45857/45857/34692 45869/45869/34703 45870/45870/34704 +f 45857/45857/34692 45870/45870/34704 45858/45858/34693 +f 45859/45859/34694 45864/45864/34698 45869/45869/34703 +f 45859/45859/34694 45869/45869/34703 45857/45857/34692 +f 45869/45869/34703 45871/45871/34705 45872/45872/34706 +f 45869/45869/34703 45872/45872/34706 45870/45870/34704 +f 45864/45864/34698 45873/45873/34707 45871/45871/34705 +f 45864/45864/34698 45871/45871/34705 45869/45869/34703 +f 45866/45866/34700 45874/45874/34708 45875/45875/34707 +f 45866/45866/34700 45875/45875/34707 45876/45876/34709 +f 45865/45865/34699 45877/45877/34710 45874/45874/34708 +f 45865/45865/34699 45874/45874/34708 45866/45866/34700 +f 45868/45868/34702 45878/45878/34711 45877/45877/34710 +f 45868/45868/34702 45877/45877/34710 45865/45865/34699 +f 45669/45669/34512 45670/45670/34513 45878/45878/34711 +f 45669/45669/34512 45878/45878/34711 45868/45868/34702 +f 45874/45874/34708 45879/45879/34712 45880/45880/34713 +f 45874/45874/34708 45880/45880/34713 45875/45875/34707 +f 45877/45877/34710 45881/45881/34714 45879/45879/34712 +f 45877/45877/34710 45879/45879/34712 45874/45874/34708 +f 45878/45878/34711 45882/45882/34715 45881/45881/34714 +f 45878/45878/34711 45881/45881/34714 45877/45877/34710 +f 45670/45670/34513 45671/45671/34514 45882/45882/34715 +f 45670/45670/34513 45882/45882/34715 45878/45878/34711 +f 45871/45871/34705 45883/45883/34716 45884/45884/34717 +f 45871/45871/34705 45884/45884/34717 45872/45872/34706 +f 45875/45875/34707 45880/45880/34713 45885/45885/34716 +f 45875/45875/34707 45885/45885/34716 45886/45886/34705 +f 45885/45885/34716 45672/45672/34515 45675/45675/34518 +f 45885/45885/34716 45675/45675/34518 45887/45887/34718 +f 45880/45880/34713 45676/45676/34519 45672/45672/34515 +f 45880/45880/34713 45672/45672/34515 45885/45885/34716 +f 45879/45879/34712 45678/45678/34521 45676/45676/34519 +f 45879/45879/34712 45676/45676/34519 45880/45880/34713 +f 45881/45881/34714 45680/45680/34523 45678/45678/34521 +f 45881/45881/34714 45678/45678/34521 45879/45879/34712 +f 45882/45882/34715 45682/45682/34525 45680/45680/34523 +f 45882/45882/34715 45680/45680/34523 45881/45881/34714 +f 45671/45671/34514 45641/45641/34484 45682/45682/34525 +f 45671/45671/34514 45682/45682/34525 45882/45882/34715 +o Sphere.024__0 +v 1.182755 -0.672716 -0.177155 +v 1.181097 -0.681029 -0.178169 +v 1.182748 -0.681197 -0.178151 +v 1.179511 -0.680540 -0.178163 +v 1.178049 -0.679749 -0.178134 +v 1.176769 -0.678687 -0.178082 +v 1.175719 -0.677395 -0.178010 +v 1.174939 -0.675921 -0.177920 +v 1.174460 -0.674323 -0.177816 +v 1.174300 -0.672663 -0.177702 +v 1.174466 -0.671003 -0.177582 +v 1.174950 -0.669408 -0.177460 +v 1.175735 -0.667939 -0.177343 +v 1.176789 -0.666653 -0.177233 +v 1.178073 -0.665599 -0.177135 +v 1.179537 -0.664817 -0.177053 +v 1.181125 -0.664337 -0.176990 +v 1.182776 -0.664179 -0.176949 +v 1.184427 -0.664347 -0.176931 +v 1.186013 -0.664836 -0.176937 +v 1.187475 -0.665626 -0.176966 +v 1.188755 -0.666688 -0.177018 +v 1.189805 -0.667981 -0.177090 +v 1.190585 -0.669454 -0.177180 +v 1.191063 -0.671052 -0.177284 +v 1.191223 -0.672713 -0.177398 +v 1.191058 -0.674372 -0.177518 +v 1.190574 -0.675967 -0.177639 +v 1.189789 -0.677436 -0.177757 +v 1.188735 -0.678722 -0.177867 +v 1.187451 -0.679777 -0.177965 +v 1.185987 -0.680559 -0.178047 +v 1.184399 -0.681038 -0.178110 +v 1.182918 -0.712118 -0.192681 +v 1.175102 -0.711321 -0.192766 +v 1.174686 -0.713482 -0.196800 +v 1.182984 -0.714328 -0.196709 +v 1.182860 -0.708338 -0.188845 +v 1.175826 -0.707620 -0.188922 +v 1.182812 -0.703134 -0.185349 +v 1.176830 -0.702523 -0.185415 +v 1.182777 -0.696704 -0.182328 +v 1.178077 -0.696224 -0.182380 +v 1.182755 -0.689297 -0.179898 +v 1.179518 -0.688967 -0.179933 +v 1.176406 -0.688008 -0.179922 +v 1.167589 -0.709005 -0.192740 +v 1.166710 -0.711024 -0.196772 +v 1.169064 -0.705537 -0.188898 +v 1.171080 -0.700751 -0.185395 +v 1.173559 -0.694832 -0.182364 +v 1.162835 -0.702167 -0.188773 +v 1.160667 -0.705261 -0.192601 +v 1.165783 -0.697885 -0.185288 +v 1.169397 -0.692580 -0.182281 +v 1.173538 -0.686457 -0.179865 +v 1.159363 -0.707049 -0.196625 +v 1.171027 -0.684374 -0.179763 +v 1.154603 -0.700232 -0.192357 +v 1.152925 -0.701710 -0.196365 +v 1.157378 -0.697641 -0.188553 +v 1.161142 -0.694036 -0.185101 +v 1.165751 -0.689556 -0.182133 +v 1.157336 -0.689351 -0.184840 +v 1.152902 -0.692132 -0.188246 +v 1.162760 -0.685875 -0.181928 +v 1.168967 -0.681838 -0.179622 +v 1.149631 -0.694111 -0.192015 +v 1.147646 -0.695212 -0.196002 +v 1.145940 -0.687133 -0.191590 +v 1.143728 -0.687804 -0.195551 +v 1.149580 -0.685852 -0.187863 +v 1.154510 -0.684011 -0.184514 +v 1.160540 -0.681679 -0.181672 +v 1.167438 -0.678948 -0.179446 +v 1.159177 -0.677129 -0.181376 +v 1.152775 -0.678220 -0.184137 +v 1.166499 -0.675814 -0.179241 +v 1.143672 -0.679567 -0.191097 +v 1.141320 -0.679772 -0.195028 +v 1.147539 -0.679042 -0.187419 +v 1.142915 -0.671703 -0.190556 +v 1.140517 -0.671423 -0.194453 +v 1.146858 -0.671965 -0.186932 +v 1.152196 -0.672201 -0.183723 +v 1.158721 -0.672400 -0.181050 +v 1.166186 -0.672556 -0.179017 +v 1.159192 -0.667674 -0.180708 +v 1.152795 -0.666185 -0.183287 +v 1.166510 -0.669301 -0.178782 +v 1.143698 -0.663843 -0.189986 +v 1.141348 -0.663080 -0.193849 +v 1.147563 -0.664892 -0.186420 +v 1.145991 -0.656290 -0.189412 +v 1.143782 -0.655062 -0.193239 +v 1.149627 -0.658094 -0.185903 +v 1.154550 -0.660405 -0.182847 +v 1.160571 -0.663132 -0.180362 +v 1.167460 -0.666173 -0.178544 +v 1.168998 -0.663291 -0.178312 +v 1.162805 -0.658949 -0.180027 +v 1.149706 -0.649334 -0.188853 +v 1.147726 -0.647678 -0.192646 +v 1.152970 -0.651834 -0.185400 +v 1.157393 -0.655081 -0.182420 +v 1.154699 -0.643243 -0.188333 +v 1.153027 -0.641210 -0.192093 +v 1.157464 -0.646352 -0.184932 +v 1.161215 -0.650418 -0.182022 +v 1.165808 -0.655286 -0.179713 +v 1.171067 -0.660768 -0.178097 +v 1.173585 -0.658699 -0.177905 +v 1.169464 -0.652283 -0.179435 +v 1.160780 -0.638249 -0.187870 +v 1.159482 -0.635909 -0.191602 +v 1.162936 -0.641857 -0.184515 +v 1.165869 -0.646596 -0.181667 +v 1.169177 -0.638524 -0.184166 +v 1.167714 -0.634545 -0.187482 +v 1.171176 -0.643762 -0.181371 +v 1.173634 -0.650056 -0.179202 +v 1.176458 -0.657165 -0.177744 +v 1.166843 -0.631978 -0.191191 +v 1.179573 -0.656225 -0.177621 +v 1.175234 -0.632274 -0.187185 +v 1.174827 -0.629567 -0.190876 +v 1.175945 -0.636481 -0.183899 +v 1.176932 -0.642024 -0.181143 +v 1.178157 -0.648690 -0.179024 +v 1.182916 -0.641449 -0.180994 +v 1.182981 -0.635804 -0.183723 +v 1.182858 -0.648239 -0.178906 +v 1.182811 -0.655914 -0.177540 +v 1.183053 -0.631523 -0.186990 +v 1.183127 -0.628769 -0.190668 +v 1.183053 -0.631523 -0.186990 +v 1.190869 -0.632321 -0.186904 +v 1.191425 -0.629616 -0.190577 +v 1.183127 -0.628769 -0.190668 +v 1.190016 -0.636522 -0.183646 +v 1.190869 -0.632321 -0.186904 +v 1.188898 -0.642059 -0.180928 +v 1.187559 -0.648718 -0.178855 +v 1.186049 -0.656244 -0.177505 +v 1.194649 -0.643831 -0.180949 +v 1.196777 -0.638606 -0.183671 +v 1.192077 -0.650110 -0.178871 +v 1.189161 -0.657203 -0.177516 +v 1.198382 -0.634636 -0.186931 +v 1.199400 -0.632074 -0.190606 +v 1.190016 -0.636522 -0.183646 +v 1.196777 -0.638606 -0.183671 +v 1.205303 -0.638380 -0.187070 +v 1.206748 -0.636049 -0.190753 +v 1.203007 -0.641976 -0.183795 +v 1.194649 -0.643831 -0.180949 +v 1.199946 -0.646697 -0.181055 +v 1.196239 -0.652362 -0.178954 +v 1.199946 -0.646697 -0.181055 +v 1.192028 -0.658754 -0.177573 +v 1.196239 -0.652362 -0.178954 +v 1.199885 -0.655386 -0.179101 +v 1.204587 -0.650546 -0.181242 +v 1.194540 -0.660837 -0.177675 +v 1.199885 -0.655386 -0.179101 +v 1.211367 -0.643409 -0.187315 +v 1.213186 -0.641388 -0.191012 +v 1.208464 -0.646502 -0.184015 +v 1.216341 -0.649531 -0.187656 +v 1.218465 -0.647886 -0.191375 +v 1.212940 -0.652011 -0.184323 +v 1.208393 -0.655231 -0.181504 +v 1.202876 -0.659067 -0.179307 +v 1.196599 -0.663372 -0.177816 +v 1.202876 -0.659067 -0.179307 +v 1.205095 -0.663263 -0.179563 +v 1.211218 -0.660572 -0.181829 +v 1.198128 -0.666263 -0.177992 +v 1.205095 -0.663263 -0.179563 +v 1.220032 -0.656508 -0.188081 +v 1.222383 -0.655294 -0.191827 +v 1.216262 -0.658291 -0.184705 +v 1.222299 -0.664075 -0.188574 +v 1.224791 -0.663326 -0.192350 +v 1.218302 -0.665100 -0.185149 +v 1.212954 -0.666363 -0.182206 +v 1.206459 -0.667813 -0.179859 +v 1.199067 -0.669397 -0.178196 +v 1.206459 -0.667813 -0.179859 +v 1.199381 -0.672654 -0.178421 +v 1.206914 -0.672542 -0.180184 +v 1.223056 -0.671939 -0.189116 +v 1.225594 -0.671674 -0.192924 +v 1.218983 -0.672178 -0.185636 +v 1.213533 -0.672381 -0.182621 +v 1.206914 -0.672542 -0.180184 +v 1.218279 -0.679251 -0.186148 +v 1.222273 -0.679798 -0.189684 +v 1.212934 -0.678397 -0.183056 +v 1.206443 -0.677269 -0.180526 +v 1.199056 -0.675910 -0.178656 +v 1.206443 -0.677269 -0.180526 +v 1.224762 -0.680018 -0.193528 +v 1.198107 -0.679038 -0.178895 +v 1.219980 -0.687351 -0.190259 +v 1.222328 -0.688036 -0.194139 +v 1.216215 -0.686048 -0.186666 +v 1.211179 -0.684177 -0.183496 +v 1.205064 -0.681810 -0.180872 +v 1.205064 -0.681810 -0.180872 +v 1.212872 -0.692308 -0.187168 +v 1.216265 -0.694307 -0.190818 +v 1.208336 -0.689501 -0.183923 +v 1.202830 -0.685993 -0.181208 +v 1.196568 -0.681919 -0.179126 +v 1.202830 -0.685993 -0.181208 +v 1.218385 -0.695420 -0.194731 +v 1.194500 -0.684443 -0.179341 +v 1.211272 -0.700399 -0.191338 +v 1.213084 -0.701887 -0.195284 +v 1.208378 -0.697791 -0.187637 +v 1.204514 -0.694164 -0.184322 +v 1.199828 -0.689657 -0.181521 +v 1.199828 -0.689657 -0.181521 +v 1.199860 -0.697986 -0.184676 +v 1.202905 -0.702285 -0.188053 +v 1.196171 -0.692659 -0.181799 +v 1.199860 -0.697986 -0.184676 +v 1.204514 -0.694164 -0.184322 +v 1.191981 -0.686511 -0.179533 +v 1.205191 -0.705392 -0.191801 +v 1.206629 -0.707188 -0.195776 +v 1.198257 -0.709096 -0.192189 +v 1.199268 -0.711120 -0.196187 +v 1.196665 -0.705618 -0.188402 +v 1.194553 -0.700820 -0.184973 +v 1.196665 -0.705618 -0.188402 +v 1.202905 -0.702285 -0.188053 +v 1.192002 -0.694886 -0.182032 +v 1.189109 -0.688045 -0.179694 +v 1.188797 -0.702559 -0.185200 +v 1.189896 -0.707662 -0.188669 +v 1.187479 -0.696252 -0.182211 +v 1.185994 -0.688986 -0.179817 +v 1.190736 -0.711367 -0.192486 +v 1.191284 -0.713531 -0.196502 +v 1.190736 -0.711367 -0.192486 +v 1.198257 -0.709096 -0.192189 +v 1.191284 -0.713531 -0.196502 +vt 0.675835 0.777137 +vt 0.675894 0.776509 +vt 0.675775 0.776509 +vt 0.676012 0.776533 +vt 0.676124 0.776580 +vt 0.676224 0.776649 +vt 0.676310 0.776736 +vt 0.676378 0.776839 +vt 0.676425 0.776953 +vt 0.676450 0.777074 +vt 0.676451 0.777198 +vt 0.676429 0.777319 +vt 0.676384 0.777433 +vt 0.676318 0.777536 +vt 0.676234 0.777623 +vt 0.676135 0.777692 +vt 0.676025 0.777739 +vt 0.675908 0.777763 +vt 0.675788 0.777763 +vt 0.675670 0.777739 +vt 0.675558 0.777692 +vt 0.675458 0.777623 +vt 0.675372 0.777536 +vt 0.675304 0.777433 +vt 0.675257 0.777319 +vt 0.675233 0.777198 +vt 0.675231 0.777074 +vt 0.675253 0.776953 +vt 0.675298 0.776839 +vt 0.675364 0.776736 +vt 0.675448 0.776649 +vt 0.675547 0.776580 +vt 0.675657 0.776533 +vt 0.675716 0.774127 +vt 0.676285 0.774127 +vt 0.676360 0.773932 +vt 0.675757 0.773932 +vt 0.675693 0.774436 +vt 0.676204 0.774436 +vt 0.675687 0.774845 +vt 0.676122 0.774845 +vt 0.675699 0.775341 +vt 0.676041 0.775341 +vt 0.675729 0.775902 +vt 0.675964 0.775902 +vt 0.676195 0.775950 +vt 0.676843 0.774242 +vt 0.676953 0.774053 +vt 0.676707 0.774538 +vt 0.676549 0.774933 +vt 0.676377 0.775409 +vt 0.677182 0.774740 +vt 0.677371 0.774465 +vt 0.676953 0.775104 +vt 0.676694 0.775544 +vt 0.676414 0.776042 +vt 0.677513 0.774291 +vt 0.676611 0.776177 +vt 0.677847 0.774790 +vt 0.678018 0.774636 +vt 0.677610 0.775032 +vt 0.677317 0.775353 +vt 0.676980 0.775739 +vt 0.677628 0.775669 +vt 0.677975 0.775405 +vt 0.677224 0.775988 +vt 0.676779 0.776348 +vt 0.678253 0.775204 +vt 0.678449 0.775075 +vt 0.678573 0.775691 +vt 0.678790 0.775592 +vt 0.678264 0.775843 +vt 0.677874 0.776042 +vt 0.677417 0.776281 +vt 0.676912 0.776550 +vt 0.677551 0.776606 +vt 0.678044 0.776455 +vt 0.677005 0.776774 +vt 0.678797 0.776231 +vt 0.679027 0.776166 +vt 0.678465 0.776329 +vt 0.678913 0.776805 +vt 0.679151 0.776775 +vt 0.678570 0.776845 +vt 0.678134 0.776895 +vt 0.677622 0.776951 +vt 0.677053 0.777011 +vt 0.677625 0.777302 +vt 0.678139 0.777342 +vt 0.677055 0.777254 +vt 0.678920 0.777390 +vt 0.679157 0.777396 +vt 0.678576 0.777372 +vt 0.678815 0.777964 +vt 0.679046 0.778005 +vt 0.678481 0.777888 +vt 0.678058 0.777781 +vt 0.677562 0.777647 +vt 0.677012 0.777491 +vt 0.676924 0.777715 +vt 0.677435 0.777973 +vt 0.678603 0.778504 +vt 0.678821 0.778579 +vt 0.678291 0.778375 +vt 0.677896 0.778195 +vt 0.678292 0.778991 +vt 0.678491 0.779095 +vt 0.678011 0.778813 +vt 0.677658 0.778567 +vt 0.677248 0.778265 +vt 0.676796 0.777917 +vt 0.676631 0.778088 +vt 0.677009 0.778514 +vt 0.677895 0.779404 +vt 0.678069 0.779534 +vt 0.677653 0.779185 +vt 0.677354 0.778884 +vt 0.677231 0.779477 +vt 0.677426 0.779729 +vt 0.676995 0.779133 +vt 0.676727 0.778709 +vt 0.676437 0.778223 +vt 0.677571 0.779879 +vt 0.676220 0.778315 +vt 0.676903 0.779953 +vt 0.677016 0.780117 +vt 0.676761 0.779679 +vt 0.676595 0.779304 +vt 0.676413 0.778844 +vt 0.676170 0.779392 +vt 0.676260 0.779782 +vt 0.676078 0.778912 +vt 0.675990 0.778363 +vt 0.676347 0.780067 +vt 0.676426 0.780238 +vt 0.943377 0.907573 +vt 0.942957 0.907460 +vt 0.942725 0.907636 +vt 0.943171 0.907756 +vt 0.675749 0.779782 +vt 0.675779 0.780067 +vt 0.675735 0.779392 +vt 0.675736 0.778912 +vt 0.675754 0.778363 +vt 0.675307 0.779304 +vt 0.675246 0.779679 +vt 0.675401 0.778844 +vt 0.675523 0.778315 +vt 0.942561 0.907237 +vt 0.942304 0.907399 +vt 0.943198 0.907174 +vt 0.942842 0.906973 +vt 0.942205 0.906912 +vt 0.941926 0.907054 +vt 0.942521 0.906681 +vt 0.943137 0.906618 +vt 0.942864 0.906370 +vt 0.675083 0.778709 +vt 0.674903 0.779133 +vt 0.675305 0.778223 +vt 0.943219 0.905990 +vt 0.943037 0.905742 +vt 0.942632 0.906053 +vt 0.675107 0.778088 +vt 0.674797 0.778514 +vt 0.941902 0.906499 +vt 0.941605 0.906615 +vt 0.942249 0.906309 +vt 0.941664 0.906012 +vt 0.941352 0.906099 +vt 0.942034 0.905871 +vt 0.942450 0.905681 +vt 0.942894 0.905449 +vt 0.674939 0.777917 +vt 0.674553 0.778265 +vt 0.942795 0.905124 +vt 0.942324 0.905267 +vt 0.674806 0.777715 +vt 0.674360 0.777973 +vt 0.941500 0.905472 +vt 0.941178 0.905525 +vt 0.941887 0.905384 +vt 0.941416 0.904897 +vt 0.941089 0.904916 +vt 0.941812 0.904868 +vt 0.942260 0.904828 +vt 0.942745 0.904779 +vt 0.674714 0.777491 +vt 0.674226 0.777647 +vt 0.674666 0.777254 +vt 0.674156 0.777302 +vt 0.941416 0.904312 +vt 0.941089 0.904294 +vt 0.941812 0.904341 +vt 0.942260 0.904379 +vt 0.942745 0.904427 +vt 0.941887 0.903824 +vt 0.941500 0.903737 +vt 0.942324 0.903940 +vt 0.942795 0.904081 +vt 0.674663 0.777011 +vt 0.674152 0.776951 +vt 0.941178 0.903684 +vt 0.674706 0.776774 +vt 0.941664 0.903196 +vt 0.941352 0.903110 +vt 0.942034 0.903336 +vt 0.942450 0.903525 +vt 0.942894 0.903756 +vt 0.674215 0.776606 +vt 0.942249 0.902898 +vt 0.941902 0.902709 +vt 0.942632 0.903152 +vt 0.943037 0.903463 +vt 0.674794 0.776550 +vt 0.674342 0.776281 +vt 0.941605 0.902592 +vt 0.674923 0.776348 +vt 0.942205 0.902294 +vt 0.941926 0.902152 +vt 0.942521 0.902525 +vt 0.942864 0.902835 +vt 0.943219 0.903213 +vt 0.674529 0.775988 +vt 0.943137 0.902586 +vt 0.942842 0.902231 +vt 0.674768 0.775739 +vt 0.674502 0.775353 +vt 0.674198 0.775669 +vt 0.675087 0.776177 +vt 0.942561 0.901968 +vt 0.942304 0.901806 +vt 0.942957 0.901743 +vt 0.942725 0.901567 +vt 0.943198 0.902029 +vt 0.674861 0.775104 +vt 0.674722 0.774740 +vt 0.674300 0.775032 +vt 0.675050 0.775544 +vt 0.675282 0.776042 +vt 0.675261 0.774933 +vt 0.675192 0.774538 +vt 0.675365 0.775409 +vt 0.675498 0.775950 +vt 0.943377 0.901628 +vt 0.943171 0.901445 +vt 0.675160 0.774242 +vt 0.674638 0.774465 +vt 0.675166 0.774053 +vn -0.0181 -0.0704 0.9974 +vn -0.0373 -0.1649 0.9856 +vn -0.0182 -0.1668 0.9858 +vn -0.0556 -0.1593 0.9857 +vn -0.0725 -0.1503 0.9860 +vn -0.0873 -0.1382 0.9865 +vn -0.0993 -0.1236 0.9874 +vn -0.1084 -0.1068 0.9884 +vn -0.1139 -0.0886 0.9895 +vn -0.1157 -0.0698 0.9908 +vn -0.1138 -0.0509 0.9922 +vn -0.1082 -0.0328 0.9936 +vn -0.0992 -0.0161 0.9949 +vn -0.0870 -0.0015 0.9962 +vn -0.0722 0.0105 0.9973 +vn -0.0554 0.0194 0.9983 +vn -0.0369 0.0249 0.9990 +vn -0.0179 0.0267 0.9995 +vn 0.0011 0.0248 0.9997 +vn 0.0195 0.0192 0.9996 +vn 0.0364 0.0102 0.9993 +vn 0.0512 -0.0019 0.9987 +vn 0.0633 -0.0166 0.9979 +vn 0.0723 -0.0334 0.9968 +vn 0.0778 -0.0515 0.9956 +vn 0.0796 -0.0703 0.9943 +vn 0.0777 -0.0892 0.9930 +vn 0.0722 -0.1073 0.9916 +vn 0.0631 -0.1240 0.9903 +vn 0.0509 -0.1387 0.9890 +vn 0.0361 -0.1506 0.9879 +vn 0.0192 -0.1595 0.9870 +vn 0.0009 -0.1650 0.9863 +vn -0.0130 -0.8055 0.5925 +vn -0.1627 -0.7903 0.5907 +vn -0.1763 -0.8600 0.4789 +vn -0.0112 -0.8767 0.4808 +vn -0.0157 -0.6421 0.7665 +vn -0.1310 -0.6304 0.7651 +vn -0.0171 -0.4966 0.8678 +vn -0.1024 -0.4880 0.8668 +vn -0.0178 -0.3726 0.9278 +vn -0.0780 -0.3666 0.9271 +vn -0.0181 -0.2648 0.9641 +vn -0.0567 -0.2609 0.9637 +vn -0.0938 -0.2496 0.9638 +vn -0.3065 -0.7463 0.5909 +vn -0.3349 -0.8113 0.4791 +vn -0.2417 -0.5966 0.7652 +vn -0.1845 -0.4630 0.8669 +vn -0.1359 -0.3490 0.9272 +vn -0.3436 -0.5420 0.7669 +vn -0.4386 -0.6752 0.5931 +vn -0.2600 -0.4227 0.8682 +vn -0.1892 -0.3205 0.9282 +vn -0.1279 -0.2314 0.9644 +vn -0.4807 -0.7329 0.4815 +vn -0.1578 -0.2069 0.9655 +vn -0.5541 -0.5799 0.5972 +vn -0.6080 -0.6277 0.4860 +vn -0.4327 -0.4688 0.7700 +vn -0.3261 -0.3685 0.8706 +vn -0.2359 -0.2823 0.9299 +vn -0.3802 -0.3026 0.8740 +vn -0.5057 -0.3799 0.7746 +vn -0.2741 -0.2359 0.9323 +vn -0.1823 -0.1772 0.9671 +vn -0.6486 -0.4644 0.6030 +vn -0.7122 -0.5002 0.4926 +vn -0.7185 -0.3330 0.6106 +vn -0.7893 -0.3552 0.5009 +vn -0.5598 -0.2786 0.7804 +vn -0.4204 -0.2277 0.8783 +vn -0.3025 -0.1830 0.9354 +vn -0.2005 -0.1433 0.9691 +vn -0.3199 -0.1256 0.9391 +vn -0.4450 -0.1464 0.8835 +vn -0.2117 -0.1066 0.9715 +vn -0.7614 -0.1908 0.6195 +vn -0.8365 -0.1983 0.5108 +vn -0.5930 -0.1690 0.7873 +vn -0.7757 -0.0432 0.6296 +vn -0.8523 -0.0354 0.5219 +vn -0.6040 -0.0551 0.7951 +vn -0.4532 -0.0620 0.8892 +vn -0.3257 -0.0660 0.9432 +vn -0.2154 -0.0684 0.9741 +vn -0.3197 -0.0065 0.9475 +vn -0.4447 0.0223 0.8954 +vn -0.2116 -0.0303 0.9769 +vn -0.7609 0.1044 0.6404 +vn -0.8360 0.1273 0.5337 +vn -0.5926 0.0587 0.8034 +vn -0.7176 0.2463 0.6515 +vn -0.7882 0.2839 0.5460 +vn -0.5590 0.1681 0.8119 +vn -0.4198 0.1034 0.9017 +vn -0.3021 0.0507 0.9519 +vn -0.2003 0.0064 0.9797 +vn -0.1820 0.0402 0.9825 +vn -0.2736 0.1035 0.9563 +vn -0.6472 0.3772 0.6624 +vn -0.7106 0.4284 0.5581 +vn -0.5046 0.2689 0.8204 +vn -0.3794 0.1781 0.9079 +vn -0.5523 0.4921 0.6728 +vn -0.6060 0.5553 0.5695 +vn -0.4313 0.3574 0.8284 +vn -0.3251 0.2436 0.9138 +vn -0.2352 0.1497 0.9604 +vn -0.1574 0.0697 0.9851 +vn -0.1274 0.0940 0.9874 +vn -0.1884 0.1876 0.9640 +vn -0.4366 0.5866 0.6821 +vn -0.4784 0.6596 0.5798 +vn -0.3420 0.4300 0.8355 +vn -0.2588 0.2973 0.9190 +vn -0.2399 0.4840 0.8416 +vn -0.3041 0.6569 0.6899 +vn -0.1831 0.3372 0.9235 +vn -0.1350 0.2157 0.9671 +vn -0.0932 0.1120 0.9893 +vn -0.3323 0.7371 0.5884 +vn -0.0561 0.1231 0.9908 +vn -0.1602 0.7000 0.6959 +vn -0.1736 0.7848 0.5950 +vn -0.1290 0.5171 0.8461 +vn -0.1010 0.3617 0.9268 +vn -0.0770 0.2329 0.9694 +vn -0.0156 0.3698 0.9290 +vn -0.0137 0.5281 0.8491 +vn -0.0168 0.2386 0.9710 +vn -0.0174 0.1267 0.9918 +vn -0.0105 0.7143 0.6997 +vn -0.0084 0.8006 0.5992 +vn -0.0105 0.7143 0.6998 +vn 0.1392 0.6991 0.7013 +vn 0.1567 0.7838 0.6010 +vn -0.0084 0.8005 0.5992 +vn 0.1016 0.5164 0.8503 +vn 0.1392 0.6992 0.7013 +vn 0.0698 0.3612 0.9299 +vn 0.0435 0.2326 0.9716 +vn 0.0211 0.1228 0.9922 +vn 0.1518 0.3362 0.9295 +vn 0.2123 0.4826 0.8497 +vn 0.1014 0.2150 0.9713 +vn 0.0582 0.1116 0.9920 +vn 0.2830 0.6551 0.7005 +vn 0.3153 0.7352 0.6000 +vn 0.2123 0.4827 0.8497 +vn 0.4152 0.5841 0.6975 +vn 0.4611 0.6568 0.5967 +vn 0.3143 0.4281 0.8473 +vn 0.2273 0.2959 0.9278 +vn 0.1547 0.1865 0.9702 +vn 0.2274 0.2959 0.9278 +vn 0.0924 0.0934 0.9913 +vn 0.2013 0.1483 0.9682 +vn 0.2934 0.2418 0.9249 +vn 0.1223 0.0689 0.9901 +vn 0.2013 0.1484 0.9682 +vn 0.5307 0.4890 0.6923 +vn 0.5884 0.5518 0.5910 +vn 0.4034 0.3549 0.8434 +vn 0.6252 0.3735 0.6853 +vn 0.6926 0.4243 0.5833 +vn 0.4764 0.2660 0.8380 +vn 0.3476 0.1760 0.9210 +vn 0.2396 0.1019 0.9655 +vn 0.1468 0.0392 0.9884 +vn 0.2680 0.0490 0.9622 +vn 0.3877 0.1010 0.9162 +vn 0.1650 0.0053 0.9863 +vn 0.2680 0.0491 0.9622 +vn 0.6952 0.2421 0.6768 +vn 0.7698 0.2794 0.5739 +vn 0.5305 0.1648 0.8315 +vn 0.7381 0.0999 0.6673 +vn 0.8170 0.1225 0.5634 +vn 0.5637 0.0552 0.8242 +vn 0.4124 0.0198 0.9108 +vn 0.2854 -0.0083 0.9584 +vn 0.1761 -0.0314 0.9839 +vn 0.1799 -0.0696 0.9812 +vn 0.2912 -0.0679 0.9542 +vn 0.7523 -0.0477 0.6571 +vn 0.8328 -0.0404 0.5521 +vn 0.5747 -0.0586 0.8162 +vn 0.4206 -0.0646 0.9049 +vn 0.2912 -0.0679 0.9543 +vn 0.5633 -0.1724 0.8081 +vn 0.7376 -0.1952 0.6465 +vn 0.4121 -0.1490 0.8989 +vn 0.2852 -0.1274 0.9500 +vn 0.1760 -0.1077 0.9785 +vn 0.8165 -0.2032 0.5404 +vn 0.1647 -0.1444 0.9757 +vn 0.6942 -0.3371 0.6360 +vn 0.7687 -0.3598 0.5288 +vn 0.5297 -0.2818 0.8000 +vn 0.3872 -0.2301 0.8928 +vn 0.2676 -0.1846 0.9457 +vn 0.2676 -0.1847 0.9457 +vn 0.4753 -0.3827 0.7922 +vn 0.6238 -0.4681 0.6259 +vn 0.3468 -0.3048 0.8871 +vn 0.2390 -0.2374 0.9416 +vn 0.1465 -0.1782 0.9730 +vn 0.2391 -0.2374 0.9415 +vn 0.6911 -0.5043 0.5177 +vn 0.1218 -0.2078 0.9706 +vn 0.5289 -0.5831 0.6166 +vn 0.5864 -0.6313 0.5075 +vn 0.4020 -0.4713 0.7850 +vn 0.2924 -0.3703 0.8817 +vn 0.2006 -0.2836 0.9377 +vn 0.2261 -0.4241 0.8769 +vn 0.3126 -0.5440 0.7787 +vn 0.1538 -0.3215 0.9343 +vn 0.2261 -0.4241 0.8770 +vn 0.0918 -0.2321 0.9684 +vn 0.4131 -0.6777 0.6084 +vn 0.4587 -0.7356 0.4984 +vn 0.2806 -0.7480 0.6014 +vn 0.3127 -0.8133 0.4908 +vn 0.2105 -0.5979 0.7734 +vn 0.1505 -0.4640 0.8730 +vn 0.2105 -0.5980 0.7734 +vn 0.1004 -0.3497 0.9315 +vn 0.0576 -0.2501 0.9665 +vn 0.0683 -0.4885 0.8699 +vn 0.0997 -0.6311 0.7693 +vn 0.0425 -0.3669 0.9293 +vn 0.0205 -0.2611 0.9651 +vn 0.1367 -0.7912 0.5961 +vn 0.1540 -0.8610 0.4848 +vn 0.2806 -0.7480 0.6015 +usemtl Scene_-_Root +s 1 +f 45888/45888/34719 45889/45889/34720 45890/45890/34721 +f 45888/45888/34719 45891/45891/34722 45889/45889/34720 +f 45888/45888/34719 45892/45892/34723 45891/45891/34722 +f 45888/45888/34719 45893/45893/34724 45892/45892/34723 +f 45888/45888/34719 45894/45894/34725 45893/45893/34724 +f 45888/45888/34719 45895/45895/34726 45894/45894/34725 +f 45888/45888/34719 45896/45896/34727 45895/45895/34726 +f 45888/45888/34719 45897/45897/34728 45896/45896/34727 +f 45888/45888/34719 45898/45898/34729 45897/45897/34728 +f 45888/45888/34719 45899/45899/34730 45898/45898/34729 +f 45888/45888/34719 45900/45900/34731 45899/45899/34730 +f 45888/45888/34719 45901/45901/34732 45900/45900/34731 +f 45888/45888/34719 45902/45902/34733 45901/45901/34732 +f 45888/45888/34719 45903/45903/34734 45902/45902/34733 +f 45888/45888/34719 45904/45904/34735 45903/45903/34734 +f 45888/45888/34719 45905/45905/34736 45904/45904/34735 +f 45888/45888/34719 45906/45906/34737 45905/45905/34736 +f 45888/45888/34719 45907/45907/34738 45906/45906/34737 +f 45888/45888/34719 45908/45908/34739 45907/45907/34738 +f 45888/45888/34719 45909/45909/34740 45908/45908/34739 +f 45888/45888/34719 45910/45910/34741 45909/45909/34740 +f 45888/45888/34719 45911/45911/34742 45910/45910/34741 +f 45888/45888/34719 45912/45912/34743 45911/45911/34742 +f 45888/45888/34719 45913/45913/34744 45912/45912/34743 +f 45888/45888/34719 45914/45914/34745 45913/45913/34744 +f 45888/45888/34719 45915/45915/34746 45914/45914/34745 +f 45888/45888/34719 45916/45916/34747 45915/45915/34746 +f 45888/45888/34719 45917/45917/34748 45916/45916/34747 +f 45888/45888/34719 45918/45918/34749 45917/45917/34748 +f 45888/45888/34719 45919/45919/34750 45918/45918/34749 +f 45888/45888/34719 45920/45920/34751 45919/45919/34750 +f 45888/45888/34719 45890/45890/34721 45920/45920/34751 +f 45921/45921/34752 45922/45922/34753 45923/45923/34754 +f 45921/45921/34752 45923/45923/34754 45924/45924/34755 +f 45925/45925/34756 45926/45926/34757 45922/45922/34753 +f 45925/45925/34756 45922/45922/34753 45921/45921/34752 +f 45927/45927/34758 45928/45928/34759 45926/45926/34757 +f 45927/45927/34758 45926/45926/34757 45925/45925/34756 +f 45929/45929/34760 45930/45930/34761 45928/45928/34759 +f 45929/45929/34760 45928/45928/34759 45927/45927/34758 +f 45931/45931/34762 45932/45932/34763 45930/45930/34761 +f 45931/45931/34762 45930/45930/34761 45929/45929/34760 +f 45890/45890/34721 45889/45889/34720 45932/45932/34763 +f 45890/45890/34721 45932/45932/34763 45931/45931/34762 +f 45889/45889/34720 45891/45891/34722 45933/45933/34764 +f 45889/45889/34720 45933/45933/34764 45932/45932/34763 +f 45922/45922/34753 45934/45934/34765 45935/45935/34766 +f 45922/45922/34753 45935/45935/34766 45923/45923/34754 +f 45926/45926/34757 45936/45936/34767 45934/45934/34765 +f 45926/45926/34757 45934/45934/34765 45922/45922/34753 +f 45928/45928/34759 45937/45937/34768 45936/45936/34767 +f 45928/45928/34759 45936/45936/34767 45926/45926/34757 +f 45930/45930/34761 45938/45938/34769 45937/45937/34768 +f 45930/45930/34761 45937/45937/34768 45928/45928/34759 +f 45932/45932/34763 45933/45933/34764 45938/45938/34769 +f 45932/45932/34763 45938/45938/34769 45930/45930/34761 +f 45936/45936/34767 45939/45939/34770 45940/45940/34771 +f 45936/45936/34767 45940/45940/34771 45934/45934/34765 +f 45937/45937/34768 45941/45941/34772 45939/45939/34770 +f 45937/45937/34768 45939/45939/34770 45936/45936/34767 +f 45938/45938/34769 45942/45942/34773 45941/45941/34772 +f 45938/45938/34769 45941/45941/34772 45937/45937/34768 +f 45933/45933/34764 45943/45943/34774 45942/45942/34773 +f 45933/45933/34764 45942/45942/34773 45938/45938/34769 +f 45891/45891/34722 45892/45892/34723 45943/45943/34774 +f 45891/45891/34722 45943/45943/34774 45933/45933/34764 +f 45934/45934/34765 45940/45940/34771 45944/45944/34775 +f 45934/45934/34765 45944/45944/34775 45935/45935/34766 +f 45892/45892/34723 45893/45893/34724 45945/45945/34776 +f 45892/45892/34723 45945/45945/34776 45943/45943/34774 +f 45940/45940/34771 45946/45946/34777 45947/45947/34778 +f 45940/45940/34771 45947/45947/34778 45944/45944/34775 +f 45939/45939/34770 45948/45948/34779 45946/45946/34777 +f 45939/45939/34770 45946/45946/34777 45940/45940/34771 +f 45941/45941/34772 45949/45949/34780 45948/45948/34779 +f 45941/45941/34772 45948/45948/34779 45939/45939/34770 +f 45942/45942/34773 45950/45950/34781 45949/45949/34780 +f 45942/45942/34773 45949/45949/34780 45941/45941/34772 +f 45943/45943/34774 45945/45945/34776 45950/45950/34781 +f 45943/45943/34774 45950/45950/34781 45942/45942/34773 +f 45949/45949/34780 45951/45951/34782 45952/45952/34783 +f 45949/45949/34780 45952/45952/34783 45948/45948/34779 +f 45950/45950/34781 45953/45953/34784 45951/45951/34782 +f 45950/45950/34781 45951/45951/34782 45949/45949/34780 +f 45945/45945/34776 45954/45954/34785 45953/45953/34784 +f 45945/45945/34776 45953/45953/34784 45950/45950/34781 +f 45893/45893/34724 45894/45894/34725 45954/45954/34785 +f 45893/45893/34724 45954/45954/34785 45945/45945/34776 +f 45946/45946/34777 45955/45955/34786 45956/45956/34787 +f 45946/45946/34777 45956/45956/34787 45947/45947/34778 +f 45948/45948/34779 45952/45952/34783 45955/45955/34786 +f 45948/45948/34779 45955/45955/34786 45946/45946/34777 +f 45955/45955/34786 45957/45957/34788 45958/45958/34789 +f 45955/45955/34786 45958/45958/34789 45956/45956/34787 +f 45952/45952/34783 45959/45959/34790 45957/45957/34788 +f 45952/45952/34783 45957/45957/34788 45955/45955/34786 +f 45951/45951/34782 45960/45960/34791 45959/45959/34790 +f 45951/45951/34782 45959/45959/34790 45952/45952/34783 +f 45953/45953/34784 45961/45961/34792 45960/45960/34791 +f 45953/45953/34784 45960/45960/34791 45951/45951/34782 +f 45954/45954/34785 45962/45962/34793 45961/45961/34792 +f 45954/45954/34785 45961/45961/34792 45953/45953/34784 +f 45894/45894/34725 45895/45895/34726 45962/45962/34793 +f 45894/45894/34725 45962/45962/34793 45954/45954/34785 +f 45961/45961/34792 45963/45963/34794 45964/45964/34795 +f 45961/45961/34792 45964/45964/34795 45960/45960/34791 +f 45962/45962/34793 45965/45965/34796 45963/45963/34794 +f 45962/45962/34793 45963/45963/34794 45961/45961/34792 +f 45895/45895/34726 45896/45896/34727 45965/45965/34796 +f 45895/45895/34726 45965/45965/34796 45962/45962/34793 +f 45957/45957/34788 45966/45966/34797 45967/45967/34798 +f 45957/45957/34788 45967/45967/34798 45958/45958/34789 +f 45959/45959/34790 45968/45968/34799 45966/45966/34797 +f 45959/45959/34790 45966/45966/34797 45957/45957/34788 +f 45960/45960/34791 45964/45964/34795 45968/45968/34799 +f 45960/45960/34791 45968/45968/34799 45959/45959/34790 +f 45966/45966/34797 45969/45969/34800 45970/45970/34801 +f 45966/45966/34797 45970/45970/34801 45967/45967/34798 +f 45968/45968/34799 45971/45971/34802 45969/45969/34800 +f 45968/45968/34799 45969/45969/34800 45966/45966/34797 +f 45964/45964/34795 45972/45972/34803 45971/45971/34802 +f 45964/45964/34795 45971/45971/34802 45968/45968/34799 +f 45963/45963/34794 45973/45973/34804 45972/45972/34803 +f 45963/45963/34794 45972/45972/34803 45964/45964/34795 +f 45965/45965/34796 45974/45974/34805 45973/45973/34804 +f 45965/45965/34796 45973/45973/34804 45963/45963/34794 +f 45896/45896/34727 45897/45897/34728 45974/45974/34805 +f 45896/45896/34727 45974/45974/34805 45965/45965/34796 +f 45973/45973/34804 45975/45975/34806 45976/45976/34807 +f 45973/45973/34804 45976/45976/34807 45972/45972/34803 +f 45974/45974/34805 45977/45977/34808 45975/45975/34806 +f 45974/45974/34805 45975/45975/34806 45973/45973/34804 +f 45897/45897/34728 45898/45898/34729 45977/45977/34808 +f 45897/45897/34728 45977/45977/34808 45974/45974/34805 +f 45969/45969/34800 45978/45978/34809 45979/45979/34810 +f 45969/45969/34800 45979/45979/34810 45970/45970/34801 +f 45971/45971/34802 45980/45980/34811 45978/45978/34809 +f 45971/45971/34802 45978/45978/34809 45969/45969/34800 +f 45972/45972/34803 45976/45976/34807 45980/45980/34811 +f 45972/45972/34803 45980/45980/34811 45971/45971/34802 +f 45978/45978/34809 45981/45981/34812 45982/45982/34813 +f 45978/45978/34809 45982/45982/34813 45979/45979/34810 +f 45980/45980/34811 45983/45983/34814 45981/45981/34812 +f 45980/45980/34811 45981/45981/34812 45978/45978/34809 +f 45976/45976/34807 45984/45984/34815 45983/45983/34814 +f 45976/45976/34807 45983/45983/34814 45980/45980/34811 +f 45975/45975/34806 45985/45985/34816 45984/45984/34815 +f 45975/45975/34806 45984/45984/34815 45976/45976/34807 +f 45977/45977/34808 45986/45986/34817 45985/45985/34816 +f 45977/45977/34808 45985/45985/34816 45975/45975/34806 +f 45898/45898/34729 45899/45899/34730 45986/45986/34817 +f 45898/45898/34729 45986/45986/34817 45977/45977/34808 +f 45986/45986/34817 45987/45987/34818 45988/45988/34819 +f 45986/45986/34817 45988/45988/34819 45985/45985/34816 +f 45899/45899/34730 45900/45900/34731 45987/45987/34818 +f 45899/45899/34730 45987/45987/34818 45986/45986/34817 +f 45981/45981/34812 45989/45989/34820 45990/45990/34821 +f 45981/45981/34812 45990/45990/34821 45982/45982/34813 +f 45983/45983/34814 45991/45991/34822 45989/45989/34820 +f 45983/45983/34814 45989/45989/34820 45981/45981/34812 +f 45984/45984/34815 45992/45992/34823 45991/45991/34822 +f 45984/45984/34815 45991/45991/34822 45983/45983/34814 +f 45985/45985/34816 45988/45988/34819 45992/45992/34823 +f 45985/45985/34816 45992/45992/34823 45984/45984/34815 +f 45989/45989/34820 45993/45993/34824 45994/45994/34825 +f 45989/45989/34820 45994/45994/34825 45990/45990/34821 +f 45991/45991/34822 45995/45995/34826 45993/45993/34824 +f 45991/45991/34822 45993/45993/34824 45989/45989/34820 +f 45992/45992/34823 45996/45996/34827 45995/45995/34826 +f 45992/45992/34823 45995/45995/34826 45991/45991/34822 +f 45988/45988/34819 45997/45997/34828 45996/45996/34827 +f 45988/45988/34819 45996/45996/34827 45992/45992/34823 +f 45987/45987/34818 45998/45998/34829 45997/45997/34828 +f 45987/45987/34818 45997/45997/34828 45988/45988/34819 +f 45900/45900/34731 45901/45901/34732 45998/45998/34829 +f 45900/45900/34731 45998/45998/34829 45987/45987/34818 +f 45998/45998/34829 45999/45999/34830 46000/46000/34831 +f 45998/45998/34829 46000/46000/34831 45997/45997/34828 +f 45901/45901/34732 45902/45902/34733 45999/45999/34830 +f 45901/45901/34732 45999/45999/34830 45998/45998/34829 +f 45993/45993/34824 46001/46001/34832 46002/46002/34833 +f 45993/45993/34824 46002/46002/34833 45994/45994/34825 +f 45995/45995/34826 46003/46003/34834 46001/46001/34832 +f 45995/45995/34826 46001/46001/34832 45993/45993/34824 +f 45996/45996/34827 46004/46004/34835 46003/46003/34834 +f 45996/45996/34827 46003/46003/34834 45995/45995/34826 +f 45997/45997/34828 46000/46000/34831 46004/46004/34835 +f 45997/45997/34828 46004/46004/34835 45996/45996/34827 +f 46003/46003/34834 46005/46005/34836 46006/46006/34837 +f 46003/46003/34834 46006/46006/34837 46001/46001/34832 +f 46004/46004/34835 46007/46007/34838 46005/46005/34836 +f 46004/46004/34835 46005/46005/34836 46003/46003/34834 +f 46000/46000/34831 46008/46008/34839 46007/46007/34838 +f 46000/46000/34831 46007/46007/34838 46004/46004/34835 +f 45999/45999/34830 46009/46009/34840 46008/46008/34839 +f 45999/45999/34830 46008/46008/34839 46000/46000/34831 +f 45902/45902/34733 45903/45903/34734 46009/46009/34840 +f 45902/45902/34733 46009/46009/34840 45999/45999/34830 +f 46001/46001/34832 46006/46006/34837 46010/46010/34841 +f 46001/46001/34832 46010/46010/34841 46002/46002/34833 +f 45903/45903/34734 45904/45904/34735 46011/46011/34842 +f 45903/45903/34734 46011/46011/34842 46009/46009/34840 +f 46006/46006/34837 46012/46012/34843 46013/46013/34844 +f 46006/46006/34837 46013/46013/34844 46010/46010/34841 +f 46005/46005/34836 46014/46014/34845 46012/46012/34843 +f 46005/46005/34836 46012/46012/34843 46006/46006/34837 +f 46007/46007/34838 46015/46015/34846 46014/46014/34845 +f 46007/46007/34838 46014/46014/34845 46005/46005/34836 +f 46008/46008/34839 46016/46016/34847 46015/46015/34846 +f 46008/46008/34839 46015/46015/34846 46007/46007/34838 +f 46009/46009/34840 46011/46011/34842 46016/46016/34847 +f 46009/46009/34840 46016/46016/34847 46008/46008/34839 +f 46015/46015/34846 46017/46017/34848 46018/46018/34849 +f 46015/46015/34846 46018/46018/34849 46014/46014/34845 +f 46016/46016/34847 46019/46019/34850 46017/46017/34848 +f 46016/46016/34847 46017/46017/34848 46015/46015/34846 +f 46011/46011/34842 46020/46020/34851 46019/46019/34850 +f 46011/46011/34842 46019/46019/34850 46016/46016/34847 +f 45904/45904/34735 45905/45905/34736 46020/46020/34851 +f 45904/45904/34735 46020/46020/34851 46011/46011/34842 +f 46012/46012/34843 46021/46021/34852 46022/46022/34853 +f 46012/46012/34843 46022/46022/34853 46013/46013/34844 +f 46014/46014/34845 46018/46018/34849 46021/46021/34852 +f 46014/46014/34845 46021/46021/34852 46012/46012/34843 +f 46023/46023/34854 46024/46024/34855 46025/46025/34856 +f 46023/46023/34854 46025/46025/34856 46026/46026/34857 +f 46018/46018/34849 46027/46027/34858 46028/46028/34859 +f 46018/46018/34849 46028/46028/34859 46021/46021/34852 +f 46017/46017/34848 46029/46029/34860 46027/46027/34858 +f 46017/46017/34848 46027/46027/34858 46018/46018/34849 +f 46019/46019/34850 46030/46030/34861 46029/46029/34860 +f 46019/46019/34850 46029/46029/34860 46017/46017/34848 +f 46020/46020/34851 46031/46031/34862 46030/46030/34861 +f 46020/46020/34851 46030/46030/34861 46019/46019/34850 +f 45905/45905/34736 45906/45906/34737 46031/46031/34862 +f 45905/45905/34736 46031/46031/34862 46020/46020/34851 +f 46029/46029/34860 46032/46032/34863 46033/46033/34864 +f 46029/46029/34860 46033/46033/34864 46027/46027/34858 +f 46030/46030/34861 46034/46034/34865 46032/46032/34863 +f 46030/46030/34861 46032/46032/34863 46029/46029/34860 +f 46031/46031/34862 46035/46035/34866 46034/46034/34865 +f 46031/46031/34862 46034/46034/34865 46030/46030/34861 +f 45906/45906/34737 45907/45907/34738 46035/46035/34866 +f 45906/45906/34737 46035/46035/34866 46031/46031/34862 +f 46024/46024/34855 46036/46036/34867 46037/46037/34868 +f 46024/46024/34855 46037/46037/34868 46025/46025/34856 +f 46038/46038/34858 46039/46039/34869 46036/46036/34867 +f 46038/46038/34858 46036/46036/34867 46024/46024/34855 +f 46036/46036/34867 46040/46040/34870 46041/46041/34871 +f 46036/46036/34867 46041/46041/34871 46037/46037/34868 +f 46039/46039/34869 46042/46042/34872 46040/46040/34870 +f 46039/46039/34869 46040/46040/34870 46036/46036/34867 +f 46043/46043/34863 46044/46044/34873 46042/46042/34872 +f 46043/46043/34863 46042/46042/34872 46039/46039/34869 +f 46034/46034/34865 46045/46045/34874 46046/46046/34875 +f 46034/46034/34865 46046/46046/34875 46032/46032/34863 +f 46035/46035/34866 46047/46047/34876 46045/46045/34874 +f 46035/46035/34866 46045/46045/34874 46034/46034/34865 +f 45907/45907/34738 45908/45908/34739 46047/46047/34876 +f 45907/45907/34738 46047/46047/34876 46035/46035/34866 +f 46048/46048/34874 46049/46049/34877 46050/46050/34878 +f 46048/46048/34874 46050/46050/34878 46044/46044/34873 +f 46047/46047/34876 46051/46051/34879 46052/46052/34880 +f 46047/46047/34876 46052/46052/34880 46045/46045/34874 +f 45908/45908/34739 45909/45909/34740 46051/46051/34879 +f 45908/45908/34739 46051/46051/34879 46047/46047/34876 +f 46040/46040/34870 46053/46053/34881 46054/46054/34882 +f 46040/46040/34870 46054/46054/34882 46041/46041/34871 +f 46042/46042/34872 46055/46055/34883 46053/46053/34881 +f 46042/46042/34872 46053/46053/34881 46040/46040/34870 +f 46044/46044/34873 46050/46050/34878 46055/46055/34883 +f 46044/46044/34873 46055/46055/34883 46042/46042/34872 +f 46053/46053/34881 46056/46056/34884 46057/46057/34885 +f 46053/46053/34881 46057/46057/34885 46054/46054/34882 +f 46055/46055/34883 46058/46058/34886 46056/46056/34884 +f 46055/46055/34883 46056/46056/34884 46053/46053/34881 +f 46050/46050/34878 46059/46059/34887 46058/46058/34886 +f 46050/46050/34878 46058/46058/34886 46055/46055/34883 +f 46049/46049/34877 46060/46060/34888 46059/46059/34887 +f 46049/46049/34877 46059/46059/34887 46050/46050/34878 +f 46051/46051/34879 46061/46061/34889 46062/46062/34888 +f 46051/46051/34879 46062/46062/34888 46052/46052/34880 +f 45909/45909/34740 45910/45910/34741 46061/46061/34889 +f 45909/45909/34740 46061/46061/34889 46051/46051/34879 +f 46060/46060/34888 46063/46063/34890 46064/46064/34891 +f 46060/46060/34888 46064/46064/34891 46059/46059/34887 +f 46061/46061/34889 46065/46065/34892 46066/46066/34893 +f 46061/46061/34889 46066/46066/34893 46062/46062/34888 +f 45910/45910/34741 45911/45911/34742 46065/46065/34892 +f 45910/45910/34741 46065/46065/34892 46061/46061/34889 +f 46056/46056/34884 46067/46067/34894 46068/46068/34895 +f 46056/46056/34884 46068/46068/34895 46057/46057/34885 +f 46058/46058/34886 46069/46069/34896 46067/46067/34894 +f 46058/46058/34886 46067/46067/34894 46056/46056/34884 +f 46059/46059/34887 46064/46064/34891 46069/46069/34896 +f 46059/46059/34887 46069/46069/34896 46058/46058/34886 +f 46067/46067/34894 46070/46070/34897 46071/46071/34898 +f 46067/46067/34894 46071/46071/34898 46068/46068/34895 +f 46069/46069/34896 46072/46072/34899 46070/46070/34897 +f 46069/46069/34896 46070/46070/34897 46067/46067/34894 +f 46064/46064/34891 46073/46073/34900 46072/46072/34899 +f 46064/46064/34891 46072/46072/34899 46069/46069/34896 +f 46063/46063/34890 46074/46074/34901 46073/46073/34900 +f 46063/46063/34890 46073/46073/34900 46064/46064/34891 +f 46065/46065/34892 46075/46075/34902 46076/46076/34901 +f 46065/46065/34892 46076/46076/34901 46066/46066/34893 +f 45911/45911/34742 45912/45912/34743 46075/46075/34902 +f 45911/45911/34742 46075/46075/34902 46065/46065/34892 +f 46075/46075/34902 46077/46077/34903 46078/46078/34904 +f 46075/46075/34902 46078/46078/34904 46076/46076/34901 +f 45912/45912/34743 45913/45913/34744 46077/46077/34903 +f 45912/45912/34743 46077/46077/34903 46075/46075/34902 +f 46070/46070/34897 46079/46079/34905 46080/46080/34906 +f 46070/46070/34897 46080/46080/34906 46071/46071/34898 +f 46072/46072/34899 46081/46081/34907 46079/46079/34905 +f 46072/46072/34899 46079/46079/34905 46070/46070/34897 +f 46073/46073/34900 46082/46082/34908 46081/46081/34907 +f 46073/46073/34900 46081/46081/34907 46072/46072/34899 +f 46074/46074/34901 46083/46083/34909 46082/46082/34908 +f 46074/46074/34901 46082/46082/34908 46073/46073/34900 +f 46081/46081/34907 46084/46084/34910 46085/46085/34911 +f 46081/46081/34907 46085/46085/34911 46079/46079/34905 +f 46082/46082/34908 46086/46086/34912 46084/46084/34910 +f 46082/46082/34908 46084/46084/34910 46081/46081/34907 +f 46083/46083/34909 46087/46087/34913 46086/46086/34912 +f 46083/46083/34909 46086/46086/34912 46082/46082/34908 +f 46077/46077/34903 46088/46088/34914 46089/46089/34913 +f 46077/46077/34903 46089/46089/34913 46078/46078/34904 +f 45913/45913/34744 45914/45914/34745 46088/46088/34914 +f 45913/45913/34744 46088/46088/34914 46077/46077/34903 +f 46079/46079/34905 46085/46085/34911 46090/46090/34915 +f 46079/46079/34905 46090/46090/34915 46080/46080/34906 +f 45914/45914/34745 45915/45915/34746 46091/46091/34916 +f 45914/45914/34745 46091/46091/34916 46088/46088/34914 +f 46085/46085/34911 46092/46092/34917 46093/46093/34918 +f 46085/46085/34911 46093/46093/34918 46090/46090/34915 +f 46084/46084/34910 46094/46094/34919 46092/46092/34917 +f 46084/46084/34910 46092/46092/34917 46085/46085/34911 +f 46086/46086/34912 46095/46095/34920 46094/46094/34919 +f 46086/46086/34912 46094/46094/34919 46084/46084/34910 +f 46087/46087/34913 46096/46096/34921 46095/46095/34920 +f 46087/46087/34913 46095/46095/34920 46086/46086/34912 +f 46088/46088/34914 46091/46091/34916 46097/46097/34922 +f 46088/46088/34914 46097/46097/34922 46089/46089/34913 +f 46094/46094/34919 46098/46098/34923 46099/46099/34924 +f 46094/46094/34919 46099/46099/34924 46092/46092/34917 +f 46095/46095/34920 46100/46100/34925 46098/46098/34923 +f 46095/46095/34920 46098/46098/34923 46094/46094/34919 +f 46096/46096/34921 46101/46101/34926 46100/46100/34925 +f 46096/46096/34921 46100/46100/34925 46095/46095/34920 +f 46091/46091/34916 46102/46102/34927 46103/46103/34928 +f 46091/46091/34916 46103/46103/34928 46097/46097/34922 +f 45915/45915/34746 45916/45916/34747 46102/46102/34927 +f 45915/45915/34746 46102/46102/34927 46091/46091/34916 +f 46092/46092/34917 46099/46099/34924 46104/46104/34929 +f 46092/46092/34917 46104/46104/34929 46093/46093/34918 +f 45916/45916/34747 45917/45917/34748 46105/46105/34930 +f 45916/45916/34747 46105/46105/34930 46102/46102/34927 +f 46099/46099/34924 46106/46106/34931 46107/46107/34932 +f 46099/46099/34924 46107/46107/34932 46104/46104/34929 +f 46098/46098/34923 46108/46108/34933 46106/46106/34931 +f 46098/46098/34923 46106/46106/34931 46099/46099/34924 +f 46100/46100/34925 46109/46109/34934 46108/46108/34933 +f 46100/46100/34925 46108/46108/34933 46098/46098/34923 +f 46101/46101/34926 46110/46110/34935 46109/46109/34934 +f 46101/46101/34926 46109/46109/34934 46100/46100/34925 +f 46102/46102/34927 46105/46105/34930 46111/46111/34935 +f 46102/46102/34927 46111/46111/34935 46103/46103/34928 +f 46109/46109/34934 46112/46112/34936 46113/46113/34937 +f 46109/46109/34934 46113/46113/34937 46108/46108/34933 +f 46111/46111/34935 46114/46114/34938 46115/46115/34939 +f 46111/46111/34935 46115/46115/34939 46116/46116/34934 +f 46105/46105/34930 46117/46117/34940 46114/46114/34938 +f 46105/46105/34930 46114/46114/34938 46111/46111/34935 +f 45917/45917/34748 45918/45918/34749 46117/46117/34940 +f 45917/45917/34748 46117/46117/34940 46105/46105/34930 +f 46106/46106/34931 46118/46118/34941 46119/46119/34942 +f 46106/46106/34931 46119/46119/34942 46107/46107/34932 +f 46108/46108/34933 46113/46113/34937 46118/46118/34941 +f 46108/46108/34933 46118/46118/34941 46106/46106/34931 +f 46118/46118/34941 46120/46120/34943 46121/46121/34944 +f 46118/46118/34941 46121/46121/34944 46119/46119/34942 +f 46113/46113/34937 46122/46122/34945 46120/46120/34943 +f 46113/46113/34937 46120/46120/34943 46118/46118/34941 +f 46115/46115/34939 46123/46123/34946 46124/46124/34947 +f 46115/46115/34939 46124/46124/34947 46125/46125/34937 +f 46114/46114/34938 46126/46126/34948 46123/46123/34946 +f 46114/46114/34938 46123/46123/34946 46115/46115/34939 +f 46117/46117/34940 46127/46127/34949 46126/46126/34948 +f 46117/46117/34940 46126/46126/34948 46114/46114/34938 +f 45918/45918/34749 45919/45919/34750 46127/46127/34949 +f 45918/45918/34749 46127/46127/34949 46117/46117/34940 +f 46123/46123/34946 46128/46128/34950 46129/46129/34951 +f 46123/46123/34946 46129/46129/34951 46124/46124/34947 +f 46126/46126/34948 46130/46130/34952 46128/46128/34950 +f 46126/46126/34948 46128/46128/34950 46123/46123/34946 +f 46127/46127/34949 46131/46131/34953 46130/46130/34952 +f 46127/46127/34949 46130/46130/34952 46126/46126/34948 +f 45919/45919/34750 45920/45920/34751 46131/46131/34953 +f 45919/45919/34750 46131/46131/34953 46127/46127/34949 +f 46120/46120/34943 46132/46132/34954 46133/46133/34955 +f 46120/46120/34943 46133/46133/34955 46121/46121/34944 +f 46124/46124/34947 46129/46129/34951 46134/46134/34954 +f 46124/46124/34947 46134/46134/34954 46135/46135/34956 +f 46134/46134/34954 45921/45921/34752 45924/45924/34755 +f 46134/46134/34954 45924/45924/34755 46136/46136/34955 +f 46129/46129/34951 45925/45925/34756 45921/45921/34752 +f 46129/46129/34951 45921/45921/34752 46134/46134/34954 +f 46128/46128/34950 45927/45927/34758 45925/45925/34756 +f 46128/46128/34950 45925/45925/34756 46129/46129/34951 +f 46130/46130/34952 45929/45929/34760 45927/45927/34758 +f 46130/46130/34952 45927/45927/34758 46128/46128/34950 +f 46131/46131/34953 45931/45931/34762 45929/45929/34760 +f 46131/46131/34953 45929/45929/34760 46130/46130/34952 +f 45920/45920/34751 45890/45890/34721 45931/45931/34762 +f 45920/45920/34751 45931/45931/34762 46131/46131/34953 +o Sphere.025__0 +v 1.319006 -0.707642 -0.176816 +v 1.317348 -0.715955 -0.177830 +v 1.318999 -0.716124 -0.177812 +v 1.315762 -0.715467 -0.177824 +v 1.314300 -0.714676 -0.177795 +v 1.313020 -0.713614 -0.177743 +v 1.311970 -0.712321 -0.177671 +v 1.311190 -0.710848 -0.177581 +v 1.310711 -0.709250 -0.177477 +v 1.310551 -0.707589 -0.177363 +v 1.310717 -0.705930 -0.177243 +v 1.311201 -0.704335 -0.177121 +v 1.311985 -0.702866 -0.177004 +v 1.313040 -0.701580 -0.176894 +v 1.314324 -0.700525 -0.176796 +v 1.315788 -0.699743 -0.176714 +v 1.317376 -0.699264 -0.176651 +v 1.319027 -0.699105 -0.176610 +v 1.320678 -0.699273 -0.176592 +v 1.322264 -0.699762 -0.176598 +v 1.323726 -0.700553 -0.176627 +v 1.325006 -0.701615 -0.176679 +v 1.326056 -0.702908 -0.176751 +v 1.326836 -0.704381 -0.176841 +v 1.327314 -0.705979 -0.176945 +v 1.327474 -0.707639 -0.177059 +v 1.327309 -0.709299 -0.177179 +v 1.326825 -0.710894 -0.177300 +v 1.326040 -0.712363 -0.177418 +v 1.324986 -0.713649 -0.177528 +v 1.323702 -0.714704 -0.177626 +v 1.322238 -0.715486 -0.177708 +v 1.320650 -0.715965 -0.177771 +v 1.319169 -0.747045 -0.192342 +v 1.311353 -0.746247 -0.192427 +v 1.310937 -0.748409 -0.196461 +v 1.319235 -0.749255 -0.196370 +v 1.319111 -0.743265 -0.188506 +v 1.312077 -0.742547 -0.188583 +v 1.319063 -0.738060 -0.185010 +v 1.313081 -0.737450 -0.185076 +v 1.319028 -0.731631 -0.181989 +v 1.314328 -0.731151 -0.182041 +v 1.319006 -0.724224 -0.179559 +v 1.315769 -0.723893 -0.179594 +v 1.312657 -0.722934 -0.179583 +v 1.303840 -0.743932 -0.192401 +v 1.302961 -0.745951 -0.196433 +v 1.305315 -0.740463 -0.188559 +v 1.307331 -0.735678 -0.185055 +v 1.309810 -0.729759 -0.182025 +v 1.299086 -0.737093 -0.188434 +v 1.296918 -0.740188 -0.192262 +v 1.302034 -0.732812 -0.184949 +v 1.305648 -0.727507 -0.181942 +v 1.309789 -0.721384 -0.179526 +v 1.295614 -0.741976 -0.196286 +v 1.307278 -0.719300 -0.179424 +v 1.290854 -0.735158 -0.192018 +v 1.289176 -0.736637 -0.196026 +v 1.293629 -0.732567 -0.188214 +v 1.297393 -0.728963 -0.184762 +v 1.302001 -0.724483 -0.181794 +v 1.293587 -0.724278 -0.184501 +v 1.289153 -0.727058 -0.187907 +v 1.299011 -0.720802 -0.181589 +v 1.305218 -0.716765 -0.179283 +v 1.285882 -0.729037 -0.191676 +v 1.283897 -0.730138 -0.195663 +v 1.282191 -0.722059 -0.191251 +v 1.279979 -0.722731 -0.195212 +v 1.285831 -0.720778 -0.187524 +v 1.290761 -0.718937 -0.184175 +v 1.296791 -0.716606 -0.181333 +v 1.303689 -0.713874 -0.179106 +v 1.295428 -0.712056 -0.181037 +v 1.289026 -0.713146 -0.183798 +v 1.302750 -0.710741 -0.178902 +v 1.279923 -0.714493 -0.190758 +v 1.277571 -0.714698 -0.194689 +v 1.283790 -0.713969 -0.187080 +v 1.279166 -0.706629 -0.190217 +v 1.276768 -0.706350 -0.194114 +v 1.283109 -0.706892 -0.186593 +v 1.288447 -0.707127 -0.183384 +v 1.294972 -0.707327 -0.180711 +v 1.302437 -0.707483 -0.178678 +v 1.295443 -0.702601 -0.180369 +v 1.289046 -0.701112 -0.182948 +v 1.302761 -0.704227 -0.178442 +v 1.279949 -0.698770 -0.189647 +v 1.277599 -0.698007 -0.193510 +v 1.283814 -0.699818 -0.186081 +v 1.282242 -0.691217 -0.189073 +v 1.280033 -0.689989 -0.192900 +v 1.285878 -0.693021 -0.185564 +v 1.290801 -0.695332 -0.182508 +v 1.296822 -0.698059 -0.180023 +v 1.303711 -0.701099 -0.178205 +v 1.305249 -0.698218 -0.177973 +v 1.299056 -0.693876 -0.179688 +v 1.285957 -0.684261 -0.188514 +v 1.283977 -0.682604 -0.192307 +v 1.289221 -0.686761 -0.185061 +v 1.293644 -0.690007 -0.182081 +v 1.290950 -0.678169 -0.187994 +v 1.289278 -0.676137 -0.191754 +v 1.293715 -0.681278 -0.184593 +v 1.297466 -0.685345 -0.181683 +v 1.302059 -0.690212 -0.179374 +v 1.307318 -0.695695 -0.177758 +v 1.309836 -0.693626 -0.177566 +v 1.305715 -0.687210 -0.179096 +v 1.297031 -0.673176 -0.187531 +v 1.295733 -0.670836 -0.191263 +v 1.299187 -0.676784 -0.184176 +v 1.302120 -0.681523 -0.181328 +v 1.305428 -0.673451 -0.183827 +v 1.303965 -0.669472 -0.187143 +v 1.307427 -0.678689 -0.181032 +v 1.309885 -0.684983 -0.178863 +v 1.312709 -0.692092 -0.177405 +v 1.303094 -0.666904 -0.190852 +v 1.315824 -0.691151 -0.177282 +v 1.311485 -0.667201 -0.186846 +v 1.311078 -0.664493 -0.190536 +v 1.312196 -0.671407 -0.183560 +v 1.313183 -0.676950 -0.180804 +v 1.314408 -0.683617 -0.178685 +v 1.319167 -0.676375 -0.180655 +v 1.319232 -0.670731 -0.183384 +v 1.319109 -0.683165 -0.178567 +v 1.319062 -0.690840 -0.177201 +v 1.319304 -0.666450 -0.186651 +v 1.319378 -0.663696 -0.190329 +v 1.319304 -0.666450 -0.186651 +v 1.327120 -0.667247 -0.186565 +v 1.327676 -0.664542 -0.190238 +v 1.319378 -0.663696 -0.190329 +v 1.326267 -0.671449 -0.183307 +v 1.327120 -0.667247 -0.186565 +v 1.325149 -0.676986 -0.180589 +v 1.323810 -0.683645 -0.178516 +v 1.322300 -0.691170 -0.177166 +v 1.330900 -0.678758 -0.180610 +v 1.333028 -0.673532 -0.183331 +v 1.328328 -0.685037 -0.178532 +v 1.325412 -0.692129 -0.177177 +v 1.334633 -0.669562 -0.186592 +v 1.335651 -0.667000 -0.190267 +v 1.326267 -0.671449 -0.183307 +v 1.333028 -0.673532 -0.183331 +v 1.341554 -0.673307 -0.186731 +v 1.342999 -0.670975 -0.190413 +v 1.339257 -0.676902 -0.183456 +v 1.330900 -0.678758 -0.180610 +v 1.336197 -0.681623 -0.180716 +v 1.332490 -0.687289 -0.178615 +v 1.336197 -0.681623 -0.180716 +v 1.328279 -0.693680 -0.177234 +v 1.332490 -0.687289 -0.178615 +v 1.336136 -0.690313 -0.178762 +v 1.340838 -0.685473 -0.180903 +v 1.330791 -0.695764 -0.177336 +v 1.336136 -0.690313 -0.178762 +v 1.347618 -0.678336 -0.186975 +v 1.349437 -0.676314 -0.190673 +v 1.344715 -0.681428 -0.183676 +v 1.352592 -0.684457 -0.187317 +v 1.354716 -0.682813 -0.191036 +v 1.349190 -0.686938 -0.183984 +v 1.344644 -0.690158 -0.181165 +v 1.339127 -0.693994 -0.178967 +v 1.332850 -0.698299 -0.177477 +v 1.339127 -0.693994 -0.178967 +v 1.341346 -0.698190 -0.179224 +v 1.347469 -0.695498 -0.181490 +v 1.334379 -0.701190 -0.177653 +v 1.341346 -0.698190 -0.179224 +v 1.356283 -0.691435 -0.187742 +v 1.358634 -0.690220 -0.191488 +v 1.352513 -0.693217 -0.184366 +v 1.358550 -0.699002 -0.188235 +v 1.361042 -0.698253 -0.192011 +v 1.354553 -0.700027 -0.184810 +v 1.349205 -0.701289 -0.181867 +v 1.342710 -0.702740 -0.179520 +v 1.335318 -0.704323 -0.177857 +v 1.342710 -0.702740 -0.179520 +v 1.335632 -0.707581 -0.178082 +v 1.343165 -0.707469 -0.179845 +v 1.359307 -0.706865 -0.188776 +v 1.361845 -0.706601 -0.192585 +v 1.355234 -0.707104 -0.185297 +v 1.349784 -0.707308 -0.182281 +v 1.343165 -0.707469 -0.179845 +v 1.354530 -0.714177 -0.185809 +v 1.358524 -0.714725 -0.189345 +v 1.349185 -0.713324 -0.182717 +v 1.342694 -0.712195 -0.180187 +v 1.335307 -0.710836 -0.178317 +v 1.342694 -0.712195 -0.180187 +v 1.361013 -0.714944 -0.193189 +v 1.334358 -0.713965 -0.178555 +v 1.356231 -0.722278 -0.189920 +v 1.358579 -0.722962 -0.193799 +v 1.352466 -0.720975 -0.186327 +v 1.347430 -0.719104 -0.183157 +v 1.341315 -0.716737 -0.180533 +v 1.341315 -0.716737 -0.180533 +v 1.349123 -0.727235 -0.186829 +v 1.352516 -0.729234 -0.190479 +v 1.344587 -0.724428 -0.183584 +v 1.339081 -0.720920 -0.180869 +v 1.332819 -0.716846 -0.178787 +v 1.339081 -0.720920 -0.180869 +v 1.354636 -0.730347 -0.194392 +v 1.330751 -0.719369 -0.179002 +v 1.347523 -0.735325 -0.190999 +v 1.349335 -0.736814 -0.194945 +v 1.344629 -0.732718 -0.187298 +v 1.340765 -0.729090 -0.183983 +v 1.336079 -0.724583 -0.181182 +v 1.336079 -0.724583 -0.181182 +v 1.336111 -0.732913 -0.184337 +v 1.339156 -0.737212 -0.187714 +v 1.332422 -0.727586 -0.181460 +v 1.336111 -0.732913 -0.184337 +v 1.340765 -0.729090 -0.183983 +v 1.328232 -0.721438 -0.179194 +v 1.341442 -0.740319 -0.191462 +v 1.342880 -0.742115 -0.195436 +v 1.334508 -0.744022 -0.191849 +v 1.335519 -0.746047 -0.195848 +v 1.332916 -0.740545 -0.188063 +v 1.330804 -0.735747 -0.184634 +v 1.332916 -0.740545 -0.188063 +v 1.339156 -0.737212 -0.187714 +v 1.328253 -0.729813 -0.181693 +v 1.325360 -0.722972 -0.179355 +v 1.325047 -0.737485 -0.184861 +v 1.326147 -0.742589 -0.188330 +v 1.323730 -0.731179 -0.181872 +v 1.322245 -0.723912 -0.179478 +v 1.326987 -0.746294 -0.192147 +v 1.327535 -0.748457 -0.196163 +v 1.326987 -0.746294 -0.192147 +v 1.334508 -0.744022 -0.191849 +v 1.327535 -0.748457 -0.196163 +vt 0.686046 0.777137 +vt 0.686105 0.776509 +vt 0.685985 0.776509 +vt 0.686223 0.776533 +vt 0.686335 0.776580 +vt 0.686435 0.776649 +vt 0.686521 0.776736 +vt 0.686589 0.776839 +vt 0.686636 0.776953 +vt 0.686660 0.777074 +vt 0.686662 0.777198 +vt 0.686640 0.777319 +vt 0.686595 0.777433 +vt 0.686529 0.777536 +vt 0.686445 0.777623 +vt 0.686346 0.777692 +vt 0.686236 0.777739 +vt 0.686118 0.777763 +vt 0.685998 0.777763 +vt 0.685880 0.777739 +vt 0.685769 0.777692 +vt 0.685669 0.777623 +vt 0.685583 0.777536 +vt 0.685515 0.777433 +vt 0.685468 0.777319 +vt 0.685443 0.777198 +vt 0.685442 0.777074 +vt 0.685464 0.776953 +vt 0.685509 0.776839 +vt 0.685574 0.776736 +vt 0.685658 0.776649 +vt 0.685757 0.776580 +vt 0.685868 0.776533 +vt 0.685927 0.774127 +vt 0.686495 0.774127 +vt 0.686571 0.773932 +vt 0.685968 0.773932 +vt 0.685904 0.774436 +vt 0.686415 0.774436 +vt 0.685898 0.774845 +vt 0.686333 0.774845 +vt 0.685910 0.775341 +vt 0.686252 0.775341 +vt 0.685939 0.775902 +vt 0.686175 0.775902 +vt 0.686406 0.775950 +vt 0.687054 0.774242 +vt 0.687164 0.774053 +vt 0.686918 0.774538 +vt 0.686760 0.774933 +vt 0.686588 0.775409 +vt 0.687392 0.774740 +vt 0.687581 0.774465 +vt 0.687164 0.775104 +vt 0.686905 0.775544 +vt 0.686625 0.776042 +vt 0.687724 0.774291 +vt 0.686822 0.776177 +vt 0.688057 0.774790 +vt 0.688229 0.774636 +vt 0.687821 0.775032 +vt 0.687528 0.775353 +vt 0.687191 0.775739 +vt 0.687839 0.775669 +vt 0.688186 0.775405 +vt 0.687435 0.775988 +vt 0.686990 0.776348 +vt 0.688464 0.775204 +vt 0.688660 0.775075 +vt 0.688784 0.775691 +vt 0.689001 0.775592 +vt 0.688475 0.775843 +vt 0.688085 0.776042 +vt 0.687628 0.776281 +vt 0.687123 0.776550 +vt 0.687762 0.776606 +vt 0.688255 0.776455 +vt 0.687215 0.776774 +vt 0.689007 0.776231 +vt 0.689237 0.776166 +vt 0.688676 0.776329 +vt 0.689124 0.776805 +vt 0.689362 0.776775 +vt 0.688781 0.776845 +vt 0.688345 0.776895 +vt 0.687832 0.776951 +vt 0.687264 0.777011 +vt 0.687836 0.777302 +vt 0.688349 0.777342 +vt 0.687266 0.777254 +vt 0.689130 0.777390 +vt 0.689368 0.777396 +vt 0.688786 0.777372 +vt 0.689026 0.777964 +vt 0.689257 0.778005 +vt 0.688692 0.777888 +vt 0.688269 0.777781 +vt 0.687773 0.777647 +vt 0.687223 0.777491 +vt 0.687135 0.777715 +vt 0.687646 0.777973 +vt 0.688814 0.778504 +vt 0.689032 0.778579 +vt 0.688501 0.778375 +vt 0.688107 0.778195 +vt 0.688503 0.778991 +vt 0.688702 0.779095 +vt 0.688222 0.778813 +vt 0.687869 0.778567 +vt 0.687459 0.778265 +vt 0.687006 0.777917 +vt 0.686842 0.778088 +vt 0.687220 0.778514 +vt 0.688106 0.779404 +vt 0.688280 0.779534 +vt 0.687864 0.779185 +vt 0.687565 0.778884 +vt 0.687442 0.779477 +vt 0.687636 0.779729 +vt 0.687206 0.779133 +vt 0.686938 0.778709 +vt 0.686647 0.778223 +vt 0.687782 0.779879 +vt 0.686431 0.778315 +vt 0.687114 0.779953 +vt 0.687227 0.780117 +vt 0.686972 0.779679 +vt 0.686806 0.779304 +vt 0.686623 0.778844 +vt 0.686380 0.779392 +vt 0.686471 0.779782 +vt 0.686289 0.778912 +vt 0.686201 0.778363 +vt 0.686558 0.780067 +vt 0.686637 0.780238 +vt 0.945218 0.152438 +vt 0.944797 0.152324 +vt 0.944565 0.152501 +vt 0.945011 0.152621 +vt 0.685960 0.779782 +vt 0.685989 0.780067 +vt 0.685945 0.779392 +vt 0.685947 0.778912 +vt 0.685965 0.778363 +vt 0.685518 0.779304 +vt 0.685457 0.779679 +vt 0.685611 0.778844 +vt 0.685734 0.778315 +vt 0.944401 0.152101 +vt 0.944145 0.152263 +vt 0.945039 0.152038 +vt 0.944682 0.151837 +vt 0.944045 0.151776 +vt 0.943767 0.151919 +vt 0.944362 0.151545 +vt 0.944977 0.151482 +vt 0.944704 0.151234 +vt 0.685294 0.778709 +vt 0.685114 0.779133 +vt 0.685515 0.778223 +vt 0.945060 0.150855 +vt 0.944878 0.150606 +vt 0.944472 0.150918 +vt 0.685318 0.778088 +vt 0.685008 0.778514 +vt 0.943742 0.151363 +vt 0.943445 0.151480 +vt 0.944089 0.151173 +vt 0.943504 0.150877 +vt 0.943192 0.150964 +vt 0.943875 0.150735 +vt 0.944290 0.150545 +vt 0.944734 0.150314 +vt 0.685150 0.777917 +vt 0.684764 0.778265 +vt 0.944636 0.149989 +vt 0.944165 0.150131 +vt 0.685017 0.777715 +vt 0.684571 0.777973 +vt 0.943340 0.150336 +vt 0.943018 0.150390 +vt 0.943727 0.150249 +vt 0.943257 0.149762 +vt 0.942930 0.149780 +vt 0.943652 0.149732 +vt 0.944101 0.149692 +vt 0.944586 0.149643 +vt 0.684925 0.777491 +vt 0.684437 0.777647 +vt 0.684876 0.777254 +vt 0.684366 0.777302 +vt 0.943257 0.149176 +vt 0.942930 0.149158 +vt 0.943652 0.149205 +vt 0.944101 0.149244 +vt 0.944586 0.149291 +vt 0.943727 0.148688 +vt 0.943340 0.148602 +vt 0.944165 0.148804 +vt 0.944636 0.148946 +vt 0.684874 0.777011 +vt 0.684363 0.776951 +vt 0.943018 0.148549 +vt 0.684917 0.776774 +vt 0.943504 0.148060 +vt 0.943192 0.147974 +vt 0.943875 0.148201 +vt 0.944290 0.148390 +vt 0.944734 0.148620 +vt 0.684426 0.776606 +vt 0.944089 0.147762 +vt 0.943742 0.147573 +vt 0.944472 0.148017 +vt 0.944878 0.148327 +vt 0.685005 0.776550 +vt 0.684553 0.776281 +vt 0.943445 0.147457 +vt 0.685134 0.776348 +vt 0.944045 0.147158 +vt 0.943767 0.147016 +vt 0.944362 0.147389 +vt 0.944704 0.147699 +vt 0.945060 0.148078 +vt 0.684740 0.775988 +vt 0.944977 0.147450 +vt 0.944682 0.147096 +vt 0.684979 0.775739 +vt 0.684713 0.775353 +vt 0.684409 0.775669 +vt 0.685298 0.776177 +vt 0.944401 0.146832 +vt 0.944145 0.146670 +vt 0.944797 0.146607 +vt 0.944565 0.146431 +vt 0.945039 0.146893 +vt 0.685072 0.775104 +vt 0.684933 0.774740 +vt 0.684511 0.775032 +vt 0.685261 0.775544 +vt 0.685493 0.776042 +vt 0.685472 0.774933 +vt 0.685403 0.774538 +vt 0.685575 0.775409 +vt 0.685709 0.775950 +vt 0.945218 0.146492 +vt 0.945011 0.146309 +vt 0.685371 0.774242 +vt 0.684848 0.774465 +vt 0.685377 0.774053 +vn -0.0181 -0.0704 0.9974 +vn -0.0373 -0.1649 0.9856 +vn -0.0182 -0.1668 0.9858 +vn -0.0556 -0.1593 0.9857 +vn -0.0725 -0.1503 0.9860 +vn -0.0873 -0.1382 0.9865 +vn -0.0993 -0.1236 0.9874 +vn -0.1084 -0.1068 0.9884 +vn -0.1139 -0.0886 0.9895 +vn -0.1157 -0.0698 0.9908 +vn -0.1138 -0.0509 0.9922 +vn -0.1082 -0.0328 0.9936 +vn -0.0992 -0.0161 0.9949 +vn -0.0870 -0.0015 0.9962 +vn -0.0723 0.0105 0.9973 +vn -0.0554 0.0194 0.9983 +vn -0.0369 0.0249 0.9990 +vn -0.0179 0.0267 0.9995 +vn 0.0011 0.0248 0.9997 +vn 0.0195 0.0192 0.9996 +vn 0.0364 0.0102 0.9993 +vn 0.0512 -0.0019 0.9987 +vn 0.0633 -0.0166 0.9979 +vn 0.0723 -0.0334 0.9968 +vn 0.0778 -0.0515 0.9956 +vn 0.0796 -0.0703 0.9943 +vn 0.0777 -0.0892 0.9930 +vn 0.0722 -0.1073 0.9916 +vn 0.0631 -0.1240 0.9903 +vn 0.0509 -0.1387 0.9890 +vn 0.0362 -0.1506 0.9879 +vn 0.0192 -0.1595 0.9870 +vn 0.0009 -0.1650 0.9863 +vn -0.0130 -0.8055 0.5925 +vn -0.1627 -0.7903 0.5907 +vn -0.1763 -0.8600 0.4789 +vn -0.0112 -0.8767 0.4808 +vn -0.0157 -0.6421 0.7665 +vn -0.1310 -0.6304 0.7651 +vn -0.0171 -0.4966 0.8678 +vn -0.1024 -0.4880 0.8668 +vn -0.0178 -0.3726 0.9278 +vn -0.0780 -0.3666 0.9271 +vn -0.0181 -0.2648 0.9641 +vn -0.0567 -0.2609 0.9637 +vn -0.0938 -0.2496 0.9638 +vn -0.3065 -0.7463 0.5909 +vn -0.3349 -0.8113 0.4792 +vn -0.2417 -0.5966 0.7653 +vn -0.1845 -0.4630 0.8669 +vn -0.1359 -0.3490 0.9272 +vn -0.3436 -0.5420 0.7669 +vn -0.4386 -0.6752 0.5931 +vn -0.2600 -0.4227 0.8682 +vn -0.1892 -0.3205 0.9282 +vn -0.1279 -0.2314 0.9644 +vn -0.4807 -0.7329 0.4815 +vn -0.1578 -0.2069 0.9655 +vn -0.5542 -0.5799 0.5972 +vn -0.6080 -0.6277 0.4860 +vn -0.4327 -0.4688 0.7700 +vn -0.3261 -0.3685 0.8706 +vn -0.2359 -0.2823 0.9299 +vn -0.3802 -0.3026 0.8740 +vn -0.5057 -0.3798 0.7746 +vn -0.2741 -0.2359 0.9323 +vn -0.1823 -0.1772 0.9671 +vn -0.6486 -0.4644 0.6030 +vn -0.7122 -0.5002 0.4926 +vn -0.7185 -0.3330 0.6106 +vn -0.7893 -0.3552 0.5009 +vn -0.5598 -0.2786 0.7804 +vn -0.4204 -0.2277 0.8783 +vn -0.3025 -0.1830 0.9354 +vn -0.2005 -0.1433 0.9691 +vn -0.3199 -0.1256 0.9391 +vn -0.4450 -0.1464 0.8835 +vn -0.2117 -0.1066 0.9715 +vn -0.7614 -0.1908 0.6195 +vn -0.8365 -0.1983 0.5108 +vn -0.5930 -0.1690 0.7873 +vn -0.7757 -0.0432 0.6296 +vn -0.8523 -0.0354 0.5219 +vn -0.6040 -0.0551 0.7951 +vn -0.4532 -0.0620 0.8892 +vn -0.3257 -0.0660 0.9431 +vn -0.2154 -0.0684 0.9741 +vn -0.3197 -0.0065 0.9475 +vn -0.4447 0.0223 0.8954 +vn -0.2116 -0.0302 0.9769 +vn -0.7609 0.1044 0.6404 +vn -0.8360 0.1273 0.5337 +vn -0.5926 0.0587 0.8034 +vn -0.7176 0.2463 0.6515 +vn -0.7882 0.2839 0.5460 +vn -0.5590 0.1681 0.8119 +vn -0.4198 0.1034 0.9017 +vn -0.3021 0.0507 0.9519 +vn -0.2003 0.0064 0.9797 +vn -0.1820 0.0402 0.9825 +vn -0.2736 0.1035 0.9563 +vn -0.6472 0.3772 0.6624 +vn -0.7106 0.4284 0.5581 +vn -0.5046 0.2689 0.8204 +vn -0.3794 0.1781 0.9079 +vn -0.5523 0.4922 0.6728 +vn -0.6060 0.5553 0.5695 +vn -0.4313 0.3574 0.8284 +vn -0.3251 0.2436 0.9138 +vn -0.2352 0.1497 0.9604 +vn -0.1574 0.0697 0.9851 +vn -0.1274 0.0940 0.9874 +vn -0.1884 0.1876 0.9640 +vn -0.4366 0.5866 0.6821 +vn -0.4783 0.6596 0.5798 +vn -0.3420 0.4300 0.8355 +vn -0.2588 0.2973 0.9190 +vn -0.2399 0.4840 0.8416 +vn -0.3041 0.6569 0.6899 +vn -0.1831 0.3372 0.9234 +vn -0.1350 0.2157 0.9671 +vn -0.0931 0.1120 0.9893 +vn -0.3323 0.7371 0.5884 +vn -0.0561 0.1231 0.9908 +vn -0.1602 0.7000 0.6959 +vn -0.1736 0.7848 0.5950 +vn -0.1290 0.5171 0.8461 +vn -0.1010 0.3617 0.9268 +vn -0.0770 0.2329 0.9694 +vn -0.0156 0.3698 0.9290 +vn -0.0137 0.5281 0.8491 +vn -0.0168 0.2386 0.9710 +vn -0.0174 0.1267 0.9918 +vn -0.0105 0.7143 0.6997 +vn -0.0084 0.8006 0.5992 +vn -0.0105 0.7143 0.6998 +vn 0.1392 0.6991 0.7013 +vn 0.1567 0.7838 0.6010 +vn 0.1016 0.5164 0.8503 +vn 0.1392 0.6992 0.7013 +vn 0.0698 0.3612 0.9299 +vn 0.0435 0.2326 0.9716 +vn 0.0211 0.1228 0.9922 +vn 0.1518 0.3362 0.9295 +vn 0.2123 0.4826 0.8497 +vn 0.1014 0.2150 0.9713 +vn 0.0582 0.1116 0.9920 +vn 0.2830 0.6552 0.7005 +vn 0.3153 0.7352 0.6000 +vn 0.1016 0.5165 0.8503 +vn 0.2123 0.4827 0.8497 +vn 0.4152 0.5841 0.6975 +vn 0.4611 0.6568 0.5967 +vn 0.3143 0.4281 0.8473 +vn 0.2273 0.2959 0.9278 +vn 0.1547 0.1865 0.9702 +vn 0.0924 0.0934 0.9913 +vn 0.2013 0.1483 0.9682 +vn 0.2934 0.2418 0.9249 +vn 0.1223 0.0689 0.9901 +vn 0.2014 0.1484 0.9682 +vn 0.5307 0.4890 0.6923 +vn 0.5884 0.5518 0.5910 +vn 0.4034 0.3549 0.8434 +vn 0.6252 0.3734 0.6853 +vn 0.6926 0.4243 0.5833 +vn 0.4764 0.2660 0.8380 +vn 0.3476 0.1760 0.9210 +vn 0.2396 0.1019 0.9655 +vn 0.1468 0.0392 0.9884 +vn 0.2680 0.0490 0.9622 +vn 0.3877 0.1010 0.9162 +vn 0.1650 0.0053 0.9863 +vn 0.2680 0.0491 0.9622 +vn 0.6952 0.2421 0.6768 +vn 0.7698 0.2794 0.5739 +vn 0.5305 0.1648 0.8315 +vn 0.7380 0.0999 0.6673 +vn 0.8170 0.1225 0.5634 +vn 0.5637 0.0552 0.8242 +vn 0.4124 0.0198 0.9108 +vn 0.2854 -0.0083 0.9584 +vn 0.1761 -0.0314 0.9839 +vn 0.1799 -0.0696 0.9812 +vn 0.2912 -0.0678 0.9542 +vn 0.7523 -0.0477 0.6571 +vn 0.8328 -0.0404 0.5521 +vn 0.5747 -0.0586 0.8162 +vn 0.4206 -0.0646 0.9049 +vn 0.2912 -0.0679 0.9543 +vn 0.5633 -0.1724 0.8081 +vn 0.7376 -0.1952 0.6465 +vn 0.4121 -0.1489 0.8989 +vn 0.2852 -0.1274 0.9500 +vn 0.1760 -0.1077 0.9785 +vn 0.8165 -0.2032 0.5404 +vn 0.1647 -0.1444 0.9757 +vn 0.6942 -0.3371 0.6360 +vn 0.7687 -0.3598 0.5288 +vn 0.5297 -0.2818 0.8000 +vn 0.3872 -0.2301 0.8928 +vn 0.2676 -0.1846 0.9457 +vn 0.2676 -0.1847 0.9457 +vn 0.4753 -0.3827 0.7922 +vn 0.6238 -0.4681 0.6259 +vn 0.3468 -0.3048 0.8871 +vn 0.2390 -0.2374 0.9416 +vn 0.1465 -0.1782 0.9730 +vn 0.2391 -0.2374 0.9415 +vn 0.6911 -0.5044 0.5177 +vn 0.1218 -0.2078 0.9706 +vn 0.5289 -0.5831 0.6166 +vn 0.5865 -0.6313 0.5075 +vn 0.4020 -0.4713 0.7850 +vn 0.2924 -0.3703 0.8817 +vn 0.2006 -0.2836 0.9377 +vn 0.2261 -0.4241 0.8769 +vn 0.3126 -0.5440 0.7787 +vn 0.1538 -0.3215 0.9343 +vn 0.2261 -0.4241 0.8770 +vn 0.0918 -0.2321 0.9684 +vn 0.4131 -0.6777 0.6084 +vn 0.4587 -0.7356 0.4984 +vn 0.2806 -0.7480 0.6014 +vn 0.3127 -0.8133 0.4908 +vn 0.2105 -0.5979 0.7734 +vn 0.1505 -0.4640 0.8730 +vn 0.2105 -0.5980 0.7734 +vn 0.1004 -0.3497 0.9315 +vn 0.0576 -0.2501 0.9665 +vn 0.0683 -0.4885 0.8699 +vn 0.0997 -0.6311 0.7693 +vn 0.0425 -0.3669 0.9293 +vn 0.0205 -0.2611 0.9651 +vn 0.1367 -0.7912 0.5961 +vn 0.1540 -0.8610 0.4848 +vn 0.2806 -0.7480 0.6015 +usemtl Scene_-_Root +s 1 +f 46137/46137/34957 46138/46138/34958 46139/46139/34959 +f 46137/46137/34957 46140/46140/34960 46138/46138/34958 +f 46137/46137/34957 46141/46141/34961 46140/46140/34960 +f 46137/46137/34957 46142/46142/34962 46141/46141/34961 +f 46137/46137/34957 46143/46143/34963 46142/46142/34962 +f 46137/46137/34957 46144/46144/34964 46143/46143/34963 +f 46137/46137/34957 46145/46145/34965 46144/46144/34964 +f 46137/46137/34957 46146/46146/34966 46145/46145/34965 +f 46137/46137/34957 46147/46147/34967 46146/46146/34966 +f 46137/46137/34957 46148/46148/34968 46147/46147/34967 +f 46137/46137/34957 46149/46149/34969 46148/46148/34968 +f 46137/46137/34957 46150/46150/34970 46149/46149/34969 +f 46137/46137/34957 46151/46151/34971 46150/46150/34970 +f 46137/46137/34957 46152/46152/34972 46151/46151/34971 +f 46137/46137/34957 46153/46153/34973 46152/46152/34972 +f 46137/46137/34957 46154/46154/34974 46153/46153/34973 +f 46137/46137/34957 46155/46155/34975 46154/46154/34974 +f 46137/46137/34957 46156/46156/34976 46155/46155/34975 +f 46137/46137/34957 46157/46157/34977 46156/46156/34976 +f 46137/46137/34957 46158/46158/34978 46157/46157/34977 +f 46137/46137/34957 46159/46159/34979 46158/46158/34978 +f 46137/46137/34957 46160/46160/34980 46159/46159/34979 +f 46137/46137/34957 46161/46161/34981 46160/46160/34980 +f 46137/46137/34957 46162/46162/34982 46161/46161/34981 +f 46137/46137/34957 46163/46163/34983 46162/46162/34982 +f 46137/46137/34957 46164/46164/34984 46163/46163/34983 +f 46137/46137/34957 46165/46165/34985 46164/46164/34984 +f 46137/46137/34957 46166/46166/34986 46165/46165/34985 +f 46137/46137/34957 46167/46167/34987 46166/46166/34986 +f 46137/46137/34957 46168/46168/34988 46167/46167/34987 +f 46137/46137/34957 46169/46169/34989 46168/46168/34988 +f 46137/46137/34957 46139/46139/34959 46169/46169/34989 +f 46170/46170/34990 46171/46171/34991 46172/46172/34992 +f 46170/46170/34990 46172/46172/34992 46173/46173/34993 +f 46174/46174/34994 46175/46175/34995 46171/46171/34991 +f 46174/46174/34994 46171/46171/34991 46170/46170/34990 +f 46176/46176/34996 46177/46177/34997 46175/46175/34995 +f 46176/46176/34996 46175/46175/34995 46174/46174/34994 +f 46178/46178/34998 46179/46179/34999 46177/46177/34997 +f 46178/46178/34998 46177/46177/34997 46176/46176/34996 +f 46180/46180/35000 46181/46181/35001 46179/46179/34999 +f 46180/46180/35000 46179/46179/34999 46178/46178/34998 +f 46139/46139/34959 46138/46138/34958 46181/46181/35001 +f 46139/46139/34959 46181/46181/35001 46180/46180/35000 +f 46138/46138/34958 46140/46140/34960 46182/46182/35002 +f 46138/46138/34958 46182/46182/35002 46181/46181/35001 +f 46171/46171/34991 46183/46183/35003 46184/46184/35004 +f 46171/46171/34991 46184/46184/35004 46172/46172/34992 +f 46175/46175/34995 46185/46185/35005 46183/46183/35003 +f 46175/46175/34995 46183/46183/35003 46171/46171/34991 +f 46177/46177/34997 46186/46186/35006 46185/46185/35005 +f 46177/46177/34997 46185/46185/35005 46175/46175/34995 +f 46179/46179/34999 46187/46187/35007 46186/46186/35006 +f 46179/46179/34999 46186/46186/35006 46177/46177/34997 +f 46181/46181/35001 46182/46182/35002 46187/46187/35007 +f 46181/46181/35001 46187/46187/35007 46179/46179/34999 +f 46185/46185/35005 46188/46188/35008 46189/46189/35009 +f 46185/46185/35005 46189/46189/35009 46183/46183/35003 +f 46186/46186/35006 46190/46190/35010 46188/46188/35008 +f 46186/46186/35006 46188/46188/35008 46185/46185/35005 +f 46187/46187/35007 46191/46191/35011 46190/46190/35010 +f 46187/46187/35007 46190/46190/35010 46186/46186/35006 +f 46182/46182/35002 46192/46192/35012 46191/46191/35011 +f 46182/46182/35002 46191/46191/35011 46187/46187/35007 +f 46140/46140/34960 46141/46141/34961 46192/46192/35012 +f 46140/46140/34960 46192/46192/35012 46182/46182/35002 +f 46183/46183/35003 46189/46189/35009 46193/46193/35013 +f 46183/46183/35003 46193/46193/35013 46184/46184/35004 +f 46141/46141/34961 46142/46142/34962 46194/46194/35014 +f 46141/46141/34961 46194/46194/35014 46192/46192/35012 +f 46189/46189/35009 46195/46195/35015 46196/46196/35016 +f 46189/46189/35009 46196/46196/35016 46193/46193/35013 +f 46188/46188/35008 46197/46197/35017 46195/46195/35015 +f 46188/46188/35008 46195/46195/35015 46189/46189/35009 +f 46190/46190/35010 46198/46198/35018 46197/46197/35017 +f 46190/46190/35010 46197/46197/35017 46188/46188/35008 +f 46191/46191/35011 46199/46199/35019 46198/46198/35018 +f 46191/46191/35011 46198/46198/35018 46190/46190/35010 +f 46192/46192/35012 46194/46194/35014 46199/46199/35019 +f 46192/46192/35012 46199/46199/35019 46191/46191/35011 +f 46198/46198/35018 46200/46200/35020 46201/46201/35021 +f 46198/46198/35018 46201/46201/35021 46197/46197/35017 +f 46199/46199/35019 46202/46202/35022 46200/46200/35020 +f 46199/46199/35019 46200/46200/35020 46198/46198/35018 +f 46194/46194/35014 46203/46203/35023 46202/46202/35022 +f 46194/46194/35014 46202/46202/35022 46199/46199/35019 +f 46142/46142/34962 46143/46143/34963 46203/46203/35023 +f 46142/46142/34962 46203/46203/35023 46194/46194/35014 +f 46195/46195/35015 46204/46204/35024 46205/46205/35025 +f 46195/46195/35015 46205/46205/35025 46196/46196/35016 +f 46197/46197/35017 46201/46201/35021 46204/46204/35024 +f 46197/46197/35017 46204/46204/35024 46195/46195/35015 +f 46204/46204/35024 46206/46206/35026 46207/46207/35027 +f 46204/46204/35024 46207/46207/35027 46205/46205/35025 +f 46201/46201/35021 46208/46208/35028 46206/46206/35026 +f 46201/46201/35021 46206/46206/35026 46204/46204/35024 +f 46200/46200/35020 46209/46209/35029 46208/46208/35028 +f 46200/46200/35020 46208/46208/35028 46201/46201/35021 +f 46202/46202/35022 46210/46210/35030 46209/46209/35029 +f 46202/46202/35022 46209/46209/35029 46200/46200/35020 +f 46203/46203/35023 46211/46211/35031 46210/46210/35030 +f 46203/46203/35023 46210/46210/35030 46202/46202/35022 +f 46143/46143/34963 46144/46144/34964 46211/46211/35031 +f 46143/46143/34963 46211/46211/35031 46203/46203/35023 +f 46210/46210/35030 46212/46212/35032 46213/46213/35033 +f 46210/46210/35030 46213/46213/35033 46209/46209/35029 +f 46211/46211/35031 46214/46214/35034 46212/46212/35032 +f 46211/46211/35031 46212/46212/35032 46210/46210/35030 +f 46144/46144/34964 46145/46145/34965 46214/46214/35034 +f 46144/46144/34964 46214/46214/35034 46211/46211/35031 +f 46206/46206/35026 46215/46215/35035 46216/46216/35036 +f 46206/46206/35026 46216/46216/35036 46207/46207/35027 +f 46208/46208/35028 46217/46217/35037 46215/46215/35035 +f 46208/46208/35028 46215/46215/35035 46206/46206/35026 +f 46209/46209/35029 46213/46213/35033 46217/46217/35037 +f 46209/46209/35029 46217/46217/35037 46208/46208/35028 +f 46215/46215/35035 46218/46218/35038 46219/46219/35039 +f 46215/46215/35035 46219/46219/35039 46216/46216/35036 +f 46217/46217/35037 46220/46220/35040 46218/46218/35038 +f 46217/46217/35037 46218/46218/35038 46215/46215/35035 +f 46213/46213/35033 46221/46221/35041 46220/46220/35040 +f 46213/46213/35033 46220/46220/35040 46217/46217/35037 +f 46212/46212/35032 46222/46222/35042 46221/46221/35041 +f 46212/46212/35032 46221/46221/35041 46213/46213/35033 +f 46214/46214/35034 46223/46223/35043 46222/46222/35042 +f 46214/46214/35034 46222/46222/35042 46212/46212/35032 +f 46145/46145/34965 46146/46146/34966 46223/46223/35043 +f 46145/46145/34965 46223/46223/35043 46214/46214/35034 +f 46222/46222/35042 46224/46224/35044 46225/46225/35045 +f 46222/46222/35042 46225/46225/35045 46221/46221/35041 +f 46223/46223/35043 46226/46226/35046 46224/46224/35044 +f 46223/46223/35043 46224/46224/35044 46222/46222/35042 +f 46146/46146/34966 46147/46147/34967 46226/46226/35046 +f 46146/46146/34966 46226/46226/35046 46223/46223/35043 +f 46218/46218/35038 46227/46227/35047 46228/46228/35048 +f 46218/46218/35038 46228/46228/35048 46219/46219/35039 +f 46220/46220/35040 46229/46229/35049 46227/46227/35047 +f 46220/46220/35040 46227/46227/35047 46218/46218/35038 +f 46221/46221/35041 46225/46225/35045 46229/46229/35049 +f 46221/46221/35041 46229/46229/35049 46220/46220/35040 +f 46227/46227/35047 46230/46230/35050 46231/46231/35051 +f 46227/46227/35047 46231/46231/35051 46228/46228/35048 +f 46229/46229/35049 46232/46232/35052 46230/46230/35050 +f 46229/46229/35049 46230/46230/35050 46227/46227/35047 +f 46225/46225/35045 46233/46233/35053 46232/46232/35052 +f 46225/46225/35045 46232/46232/35052 46229/46229/35049 +f 46224/46224/35044 46234/46234/35054 46233/46233/35053 +f 46224/46224/35044 46233/46233/35053 46225/46225/35045 +f 46226/46226/35046 46235/46235/35055 46234/46234/35054 +f 46226/46226/35046 46234/46234/35054 46224/46224/35044 +f 46147/46147/34967 46148/46148/34968 46235/46235/35055 +f 46147/46147/34967 46235/46235/35055 46226/46226/35046 +f 46235/46235/35055 46236/46236/35056 46237/46237/35057 +f 46235/46235/35055 46237/46237/35057 46234/46234/35054 +f 46148/46148/34968 46149/46149/34969 46236/46236/35056 +f 46148/46148/34968 46236/46236/35056 46235/46235/35055 +f 46230/46230/35050 46238/46238/35058 46239/46239/35059 +f 46230/46230/35050 46239/46239/35059 46231/46231/35051 +f 46232/46232/35052 46240/46240/35060 46238/46238/35058 +f 46232/46232/35052 46238/46238/35058 46230/46230/35050 +f 46233/46233/35053 46241/46241/35061 46240/46240/35060 +f 46233/46233/35053 46240/46240/35060 46232/46232/35052 +f 46234/46234/35054 46237/46237/35057 46241/46241/35061 +f 46234/46234/35054 46241/46241/35061 46233/46233/35053 +f 46238/46238/35058 46242/46242/35062 46243/46243/35063 +f 46238/46238/35058 46243/46243/35063 46239/46239/35059 +f 46240/46240/35060 46244/46244/35064 46242/46242/35062 +f 46240/46240/35060 46242/46242/35062 46238/46238/35058 +f 46241/46241/35061 46245/46245/35065 46244/46244/35064 +f 46241/46241/35061 46244/46244/35064 46240/46240/35060 +f 46237/46237/35057 46246/46246/35066 46245/46245/35065 +f 46237/46237/35057 46245/46245/35065 46241/46241/35061 +f 46236/46236/35056 46247/46247/35067 46246/46246/35066 +f 46236/46236/35056 46246/46246/35066 46237/46237/35057 +f 46149/46149/34969 46150/46150/34970 46247/46247/35067 +f 46149/46149/34969 46247/46247/35067 46236/46236/35056 +f 46247/46247/35067 46248/46248/35068 46249/46249/35069 +f 46247/46247/35067 46249/46249/35069 46246/46246/35066 +f 46150/46150/34970 46151/46151/34971 46248/46248/35068 +f 46150/46150/34970 46248/46248/35068 46247/46247/35067 +f 46242/46242/35062 46250/46250/35070 46251/46251/35071 +f 46242/46242/35062 46251/46251/35071 46243/46243/35063 +f 46244/46244/35064 46252/46252/35072 46250/46250/35070 +f 46244/46244/35064 46250/46250/35070 46242/46242/35062 +f 46245/46245/35065 46253/46253/35073 46252/46252/35072 +f 46245/46245/35065 46252/46252/35072 46244/46244/35064 +f 46246/46246/35066 46249/46249/35069 46253/46253/35073 +f 46246/46246/35066 46253/46253/35073 46245/46245/35065 +f 46252/46252/35072 46254/46254/35074 46255/46255/35075 +f 46252/46252/35072 46255/46255/35075 46250/46250/35070 +f 46253/46253/35073 46256/46256/35076 46254/46254/35074 +f 46253/46253/35073 46254/46254/35074 46252/46252/35072 +f 46249/46249/35069 46257/46257/35077 46256/46256/35076 +f 46249/46249/35069 46256/46256/35076 46253/46253/35073 +f 46248/46248/35068 46258/46258/35078 46257/46257/35077 +f 46248/46248/35068 46257/46257/35077 46249/46249/35069 +f 46151/46151/34971 46152/46152/34972 46258/46258/35078 +f 46151/46151/34971 46258/46258/35078 46248/46248/35068 +f 46250/46250/35070 46255/46255/35075 46259/46259/35079 +f 46250/46250/35070 46259/46259/35079 46251/46251/35071 +f 46152/46152/34972 46153/46153/34973 46260/46260/35080 +f 46152/46152/34972 46260/46260/35080 46258/46258/35078 +f 46255/46255/35075 46261/46261/35081 46262/46262/35082 +f 46255/46255/35075 46262/46262/35082 46259/46259/35079 +f 46254/46254/35074 46263/46263/35083 46261/46261/35081 +f 46254/46254/35074 46261/46261/35081 46255/46255/35075 +f 46256/46256/35076 46264/46264/35084 46263/46263/35083 +f 46256/46256/35076 46263/46263/35083 46254/46254/35074 +f 46257/46257/35077 46265/46265/35085 46264/46264/35084 +f 46257/46257/35077 46264/46264/35084 46256/46256/35076 +f 46258/46258/35078 46260/46260/35080 46265/46265/35085 +f 46258/46258/35078 46265/46265/35085 46257/46257/35077 +f 46264/46264/35084 46266/46266/35086 46267/46267/35087 +f 46264/46264/35084 46267/46267/35087 46263/46263/35083 +f 46265/46265/35085 46268/46268/35088 46266/46266/35086 +f 46265/46265/35085 46266/46266/35086 46264/46264/35084 +f 46260/46260/35080 46269/46269/35089 46268/46268/35088 +f 46260/46260/35080 46268/46268/35088 46265/46265/35085 +f 46153/46153/34973 46154/46154/34974 46269/46269/35089 +f 46153/46153/34973 46269/46269/35089 46260/46260/35080 +f 46261/46261/35081 46270/46270/35090 46271/46271/35091 +f 46261/46261/35081 46271/46271/35091 46262/46262/35082 +f 46263/46263/35083 46267/46267/35087 46270/46270/35090 +f 46263/46263/35083 46270/46270/35090 46261/46261/35081 +f 46272/46272/35092 46273/46273/35093 46274/46274/35094 +f 46272/46272/35092 46274/46274/35094 46275/46275/35091 +f 46267/46267/35087 46276/46276/35095 46277/46277/35096 +f 46267/46267/35087 46277/46277/35096 46270/46270/35090 +f 46266/46266/35086 46278/46278/35097 46276/46276/35095 +f 46266/46266/35086 46276/46276/35095 46267/46267/35087 +f 46268/46268/35088 46279/46279/35098 46278/46278/35097 +f 46268/46268/35088 46278/46278/35097 46266/46266/35086 +f 46269/46269/35089 46280/46280/35099 46279/46279/35098 +f 46269/46269/35089 46279/46279/35098 46268/46268/35088 +f 46154/46154/34974 46155/46155/34975 46280/46280/35099 +f 46154/46154/34974 46280/46280/35099 46269/46269/35089 +f 46278/46278/35097 46281/46281/35100 46282/46282/35101 +f 46278/46278/35097 46282/46282/35101 46276/46276/35095 +f 46279/46279/35098 46283/46283/35102 46281/46281/35100 +f 46279/46279/35098 46281/46281/35100 46278/46278/35097 +f 46280/46280/35099 46284/46284/35103 46283/46283/35102 +f 46280/46280/35099 46283/46283/35102 46279/46279/35098 +f 46155/46155/34975 46156/46156/34976 46284/46284/35103 +f 46155/46155/34975 46284/46284/35103 46280/46280/35099 +f 46273/46273/35093 46285/46285/35104 46286/46286/35105 +f 46273/46273/35093 46286/46286/35105 46274/46274/35094 +f 46287/46287/35106 46288/46288/35107 46285/46285/35104 +f 46287/46287/35106 46285/46285/35104 46273/46273/35093 +f 46285/46285/35104 46289/46289/35108 46290/46290/35109 +f 46285/46285/35104 46290/46290/35109 46286/46286/35105 +f 46288/46288/35107 46291/46291/35110 46289/46289/35108 +f 46288/46288/35107 46289/46289/35108 46285/46285/35104 +f 46292/46292/35100 46293/46293/35111 46291/46291/35110 +f 46292/46292/35100 46291/46291/35110 46288/46288/35107 +f 46283/46283/35102 46294/46294/35112 46295/46295/35111 +f 46283/46283/35102 46295/46295/35111 46281/46281/35100 +f 46284/46284/35103 46296/46296/35113 46294/46294/35112 +f 46284/46284/35103 46294/46294/35112 46283/46283/35102 +f 46156/46156/34976 46157/46157/34977 46296/46296/35113 +f 46156/46156/34976 46296/46296/35113 46284/46284/35103 +f 46297/46297/35112 46298/46298/35114 46299/46299/35115 +f 46297/46297/35112 46299/46299/35115 46293/46293/35111 +f 46296/46296/35113 46300/46300/35116 46301/46301/35117 +f 46296/46296/35113 46301/46301/35117 46294/46294/35112 +f 46157/46157/34977 46158/46158/34978 46300/46300/35116 +f 46157/46157/34977 46300/46300/35116 46296/46296/35113 +f 46289/46289/35108 46302/46302/35118 46303/46303/35119 +f 46289/46289/35108 46303/46303/35119 46290/46290/35109 +f 46291/46291/35110 46304/46304/35120 46302/46302/35118 +f 46291/46291/35110 46302/46302/35118 46289/46289/35108 +f 46293/46293/35111 46299/46299/35115 46304/46304/35120 +f 46293/46293/35111 46304/46304/35120 46291/46291/35110 +f 46302/46302/35118 46305/46305/35121 46306/46306/35122 +f 46302/46302/35118 46306/46306/35122 46303/46303/35119 +f 46304/46304/35120 46307/46307/35123 46305/46305/35121 +f 46304/46304/35120 46305/46305/35121 46302/46302/35118 +f 46299/46299/35115 46308/46308/35124 46307/46307/35123 +f 46299/46299/35115 46307/46307/35123 46304/46304/35120 +f 46298/46298/35114 46309/46309/35125 46308/46308/35124 +f 46298/46298/35114 46308/46308/35124 46299/46299/35115 +f 46300/46300/35116 46310/46310/35126 46311/46311/35125 +f 46300/46300/35116 46311/46311/35125 46301/46301/35117 +f 46158/46158/34978 46159/46159/34979 46310/46310/35126 +f 46158/46158/34978 46310/46310/35126 46300/46300/35116 +f 46309/46309/35125 46312/46312/35127 46313/46313/35128 +f 46309/46309/35125 46313/46313/35128 46308/46308/35124 +f 46310/46310/35126 46314/46314/35129 46315/46315/35130 +f 46310/46310/35126 46315/46315/35130 46311/46311/35125 +f 46159/46159/34979 46160/46160/34980 46314/46314/35129 +f 46159/46159/34979 46314/46314/35129 46310/46310/35126 +f 46305/46305/35121 46316/46316/35131 46317/46317/35132 +f 46305/46305/35121 46317/46317/35132 46306/46306/35122 +f 46307/46307/35123 46318/46318/35133 46316/46316/35131 +f 46307/46307/35123 46316/46316/35131 46305/46305/35121 +f 46308/46308/35124 46313/46313/35128 46318/46318/35133 +f 46308/46308/35124 46318/46318/35133 46307/46307/35123 +f 46316/46316/35131 46319/46319/35134 46320/46320/35135 +f 46316/46316/35131 46320/46320/35135 46317/46317/35132 +f 46318/46318/35133 46321/46321/35136 46319/46319/35134 +f 46318/46318/35133 46319/46319/35134 46316/46316/35131 +f 46313/46313/35128 46322/46322/35137 46321/46321/35136 +f 46313/46313/35128 46321/46321/35136 46318/46318/35133 +f 46312/46312/35127 46323/46323/35138 46322/46322/35137 +f 46312/46312/35127 46322/46322/35137 46313/46313/35128 +f 46314/46314/35129 46324/46324/35139 46325/46325/35138 +f 46314/46314/35129 46325/46325/35138 46315/46315/35130 +f 46160/46160/34980 46161/46161/34981 46324/46324/35139 +f 46160/46160/34980 46324/46324/35139 46314/46314/35129 +f 46324/46324/35139 46326/46326/35140 46327/46327/35141 +f 46324/46324/35139 46327/46327/35141 46325/46325/35138 +f 46161/46161/34981 46162/46162/34982 46326/46326/35140 +f 46161/46161/34981 46326/46326/35140 46324/46324/35139 +f 46319/46319/35134 46328/46328/35142 46329/46329/35143 +f 46319/46319/35134 46329/46329/35143 46320/46320/35135 +f 46321/46321/35136 46330/46330/35144 46328/46328/35142 +f 46321/46321/35136 46328/46328/35142 46319/46319/35134 +f 46322/46322/35137 46331/46331/35145 46330/46330/35144 +f 46322/46322/35137 46330/46330/35144 46321/46321/35136 +f 46323/46323/35138 46332/46332/35146 46331/46331/35145 +f 46323/46323/35138 46331/46331/35145 46322/46322/35137 +f 46330/46330/35144 46333/46333/35147 46334/46334/35148 +f 46330/46330/35144 46334/46334/35148 46328/46328/35142 +f 46331/46331/35145 46335/46335/35149 46333/46333/35147 +f 46331/46331/35145 46333/46333/35147 46330/46330/35144 +f 46332/46332/35146 46336/46336/35150 46335/46335/35149 +f 46332/46332/35146 46335/46335/35149 46331/46331/35145 +f 46326/46326/35140 46337/46337/35151 46338/46338/35150 +f 46326/46326/35140 46338/46338/35150 46327/46327/35141 +f 46162/46162/34982 46163/46163/34983 46337/46337/35151 +f 46162/46162/34982 46337/46337/35151 46326/46326/35140 +f 46328/46328/35142 46334/46334/35148 46339/46339/35152 +f 46328/46328/35142 46339/46339/35152 46329/46329/35143 +f 46163/46163/34983 46164/46164/34984 46340/46340/35153 +f 46163/46163/34983 46340/46340/35153 46337/46337/35151 +f 46334/46334/35148 46341/46341/35154 46342/46342/35155 +f 46334/46334/35148 46342/46342/35155 46339/46339/35152 +f 46333/46333/35147 46343/46343/35156 46341/46341/35154 +f 46333/46333/35147 46341/46341/35154 46334/46334/35148 +f 46335/46335/35149 46344/46344/35157 46343/46343/35156 +f 46335/46335/35149 46343/46343/35156 46333/46333/35147 +f 46336/46336/35150 46345/46345/35158 46344/46344/35157 +f 46336/46336/35150 46344/46344/35157 46335/46335/35149 +f 46337/46337/35151 46340/46340/35153 46346/46346/35159 +f 46337/46337/35151 46346/46346/35159 46338/46338/35150 +f 46343/46343/35156 46347/46347/35160 46348/46348/35161 +f 46343/46343/35156 46348/46348/35161 46341/46341/35154 +f 46344/46344/35157 46349/46349/35162 46347/46347/35160 +f 46344/46344/35157 46347/46347/35160 46343/46343/35156 +f 46345/46345/35158 46350/46350/35163 46349/46349/35162 +f 46345/46345/35158 46349/46349/35162 46344/46344/35157 +f 46340/46340/35153 46351/46351/35164 46352/46352/35165 +f 46340/46340/35153 46352/46352/35165 46346/46346/35159 +f 46164/46164/34984 46165/46165/34985 46351/46351/35164 +f 46164/46164/34984 46351/46351/35164 46340/46340/35153 +f 46341/46341/35154 46348/46348/35161 46353/46353/35166 +f 46341/46341/35154 46353/46353/35166 46342/46342/35155 +f 46165/46165/34985 46166/46166/34986 46354/46354/35167 +f 46165/46165/34985 46354/46354/35167 46351/46351/35164 +f 46348/46348/35161 46355/46355/35168 46356/46356/35169 +f 46348/46348/35161 46356/46356/35169 46353/46353/35166 +f 46347/46347/35160 46357/46357/35170 46355/46355/35168 +f 46347/46347/35160 46355/46355/35168 46348/46348/35161 +f 46349/46349/35162 46358/46358/35171 46357/46357/35170 +f 46349/46349/35162 46357/46357/35170 46347/46347/35160 +f 46350/46350/35163 46359/46359/35172 46358/46358/35171 +f 46350/46350/35163 46358/46358/35171 46349/46349/35162 +f 46351/46351/35164 46354/46354/35167 46360/46360/35172 +f 46351/46351/35164 46360/46360/35172 46352/46352/35165 +f 46358/46358/35171 46361/46361/35173 46362/46362/35174 +f 46358/46358/35171 46362/46362/35174 46357/46357/35170 +f 46360/46360/35172 46363/46363/35175 46364/46364/35176 +f 46360/46360/35172 46364/46364/35176 46365/46365/35171 +f 46354/46354/35167 46366/46366/35177 46363/46363/35175 +f 46354/46354/35167 46363/46363/35175 46360/46360/35172 +f 46166/46166/34986 46167/46167/34987 46366/46366/35177 +f 46166/46166/34986 46366/46366/35177 46354/46354/35167 +f 46355/46355/35168 46367/46367/35178 46368/46368/35179 +f 46355/46355/35168 46368/46368/35179 46356/46356/35169 +f 46357/46357/35170 46362/46362/35174 46367/46367/35178 +f 46357/46357/35170 46367/46367/35178 46355/46355/35168 +f 46367/46367/35178 46369/46369/35180 46370/46370/35181 +f 46367/46367/35178 46370/46370/35181 46368/46368/35179 +f 46362/46362/35174 46371/46371/35182 46369/46369/35180 +f 46362/46362/35174 46369/46369/35180 46367/46367/35178 +f 46364/46364/35176 46372/46372/35183 46373/46373/35184 +f 46364/46364/35176 46373/46373/35184 46374/46374/35174 +f 46363/46363/35175 46375/46375/35185 46372/46372/35183 +f 46363/46363/35175 46372/46372/35183 46364/46364/35176 +f 46366/46366/35177 46376/46376/35186 46375/46375/35185 +f 46366/46366/35177 46375/46375/35185 46363/46363/35175 +f 46167/46167/34987 46168/46168/34988 46376/46376/35186 +f 46167/46167/34987 46376/46376/35186 46366/46366/35177 +f 46372/46372/35183 46377/46377/35187 46378/46378/35188 +f 46372/46372/35183 46378/46378/35188 46373/46373/35184 +f 46375/46375/35185 46379/46379/35189 46377/46377/35187 +f 46375/46375/35185 46377/46377/35187 46372/46372/35183 +f 46376/46376/35186 46380/46380/35190 46379/46379/35189 +f 46376/46376/35186 46379/46379/35189 46375/46375/35185 +f 46168/46168/34988 46169/46169/34989 46380/46380/35190 +f 46168/46168/34988 46380/46380/35190 46376/46376/35186 +f 46369/46369/35180 46381/46381/35191 46382/46382/35192 +f 46369/46369/35180 46382/46382/35192 46370/46370/35181 +f 46373/46373/35184 46378/46378/35188 46383/46383/35191 +f 46373/46373/35184 46383/46383/35191 46384/46384/35193 +f 46383/46383/35191 46170/46170/34990 46173/46173/34993 +f 46383/46383/35191 46173/46173/34993 46385/46385/35192 +f 46378/46378/35188 46174/46174/34994 46170/46170/34990 +f 46378/46378/35188 46170/46170/34990 46383/46383/35191 +f 46377/46377/35187 46176/46176/34996 46174/46174/34994 +f 46377/46377/35187 46174/46174/34994 46378/46378/35188 +f 46379/46379/35189 46178/46178/34998 46176/46176/34996 +f 46379/46379/35189 46176/46176/34996 46377/46377/35187 +f 46380/46380/35190 46180/46180/35000 46178/46178/34998 +f 46380/46380/35190 46178/46178/34998 46379/46379/35189 +f 46169/46169/34989 46139/46139/34959 46180/46180/35000 +f 46169/46169/34989 46180/46180/35000 46380/46380/35190 +o Sphere.026__0 +v 1.589673 -0.628095 -0.435599 +v 1.589104 -0.636450 -0.433941 +v 1.589131 -0.636617 -0.435592 +v 1.589084 -0.635962 -0.432354 +v 1.589071 -0.635171 -0.430893 +v 1.589066 -0.634107 -0.429613 +v 1.589069 -0.632812 -0.428563 +v 1.589080 -0.631337 -0.427783 +v 1.589099 -0.629735 -0.427304 +v 1.589124 -0.628071 -0.427144 +v 1.589156 -0.626408 -0.427310 +v 1.589192 -0.624809 -0.427794 +v 1.589231 -0.623335 -0.428578 +v 1.589272 -0.622045 -0.429633 +v 1.589314 -0.620987 -0.430917 +v 1.589354 -0.620202 -0.432381 +v 1.589391 -0.619719 -0.433969 +v 1.589423 -0.619559 -0.435620 +v 1.589450 -0.619726 -0.437271 +v 1.589471 -0.620214 -0.438857 +v 1.589484 -0.621006 -0.440319 +v 1.589489 -0.622069 -0.441599 +v 1.589486 -0.623363 -0.442649 +v 1.589475 -0.624840 -0.443429 +v 1.589456 -0.626441 -0.443907 +v 1.589431 -0.628105 -0.444067 +v 1.589399 -0.629768 -0.443902 +v 1.589363 -0.631368 -0.443418 +v 1.589324 -0.632840 -0.442634 +v 1.589283 -0.634131 -0.441579 +v 1.589241 -0.635189 -0.440295 +v 1.589201 -0.635975 -0.438831 +v 1.589164 -0.636456 -0.437243 +v 1.576272 -0.668270 -0.435762 +v 1.576144 -0.667478 -0.427946 +v 1.572231 -0.669851 -0.427530 +v 1.572367 -0.670691 -0.435827 +v 1.579901 -0.664290 -0.435704 +v 1.579786 -0.663578 -0.428669 +v 1.583114 -0.658906 -0.435657 +v 1.583016 -0.658300 -0.429674 +v 1.585788 -0.652325 -0.435621 +v 1.585711 -0.651849 -0.430921 +v 1.587820 -0.644799 -0.435599 +v 1.587766 -0.644471 -0.432362 +v 1.587726 -0.643513 -0.429250 +v 1.576047 -0.665164 -0.420433 +v 1.572129 -0.667395 -0.419554 +v 1.579698 -0.661496 -0.421908 +v 1.582942 -0.656530 -0.423924 +v 1.585652 -0.650458 -0.426403 +v 1.579643 -0.658124 -0.415679 +v 1.575985 -0.661418 -0.413511 +v 1.582895 -0.653662 -0.418626 +v 1.585615 -0.648205 -0.422241 +v 1.587701 -0.641961 -0.426383 +v 1.572063 -0.663418 -0.412206 +v 1.587691 -0.639875 -0.423871 +v 1.575962 -0.656383 -0.407447 +v 1.572038 -0.658072 -0.405769 +v 1.579622 -0.653592 -0.410222 +v 1.582876 -0.649808 -0.413985 +v 1.585601 -0.645177 -0.418594 +v 1.582887 -0.645116 -0.410179 +v 1.579635 -0.648075 -0.405746 +v 1.585610 -0.641490 -0.415604 +v 1.587697 -0.637336 -0.421811 +v 1.575976 -0.650252 -0.402474 +v 1.572053 -0.651564 -0.400490 +v 1.576029 -0.643262 -0.398783 +v 1.572109 -0.644143 -0.396571 +v 1.579682 -0.641783 -0.402424 +v 1.582927 -0.639766 -0.407354 +v 1.585641 -0.637286 -0.413384 +v 1.587719 -0.634440 -0.420282 +v 1.585694 -0.632727 -0.412021 +v 1.582995 -0.633963 -0.405619 +v 1.587755 -0.631300 -0.419343 +v 1.576117 -0.635680 -0.396515 +v 1.572203 -0.636094 -0.394164 +v 1.579761 -0.634960 -0.400383 +v 1.576238 -0.627798 -0.395759 +v 1.572331 -0.627728 -0.393361 +v 1.579870 -0.627867 -0.399702 +v 1.583088 -0.627931 -0.405040 +v 1.585767 -0.627988 -0.411566 +v 1.587805 -0.628035 -0.419029 +v 1.585856 -0.623250 -0.412036 +v 1.583202 -0.621901 -0.405639 +v 1.587867 -0.624772 -0.419354 +v 1.576386 -0.619920 -0.396542 +v 1.572489 -0.619364 -0.394192 +v 1.580004 -0.620776 -0.400407 +v 1.576557 -0.612347 -0.398835 +v 1.572670 -0.611325 -0.396626 +v 1.580158 -0.613961 -0.402471 +v 1.583332 -0.616105 -0.407394 +v 1.585959 -0.618696 -0.413415 +v 1.587938 -0.621635 -0.420304 +v 1.588015 -0.618745 -0.421842 +v 1.586071 -0.614501 -0.415649 +v 1.576744 -0.605371 -0.402550 +v 1.572869 -0.603919 -0.400570 +v 1.580326 -0.607683 -0.405814 +v 1.583475 -0.610766 -0.410237 +v 1.576939 -0.599260 -0.407543 +v 1.573076 -0.597431 -0.405871 +v 1.580501 -0.602183 -0.410308 +v 1.583624 -0.606089 -0.414059 +v 1.586189 -0.610826 -0.418652 +v 1.588096 -0.616214 -0.423911 +v 1.588177 -0.614139 -0.426429 +v 1.586306 -0.607813 -0.422308 +v 1.577135 -0.594249 -0.413624 +v 1.573283 -0.592112 -0.412326 +v 1.580678 -0.597673 -0.415780 +v 1.583774 -0.602253 -0.418712 +v 1.580848 -0.594326 -0.422020 +v 1.577324 -0.590530 -0.420557 +v 1.583919 -0.599407 -0.424020 +v 1.586420 -0.605577 -0.426478 +v 1.588255 -0.612598 -0.429301 +v 1.573484 -0.588164 -0.419687 +v 1.588328 -0.611652 -0.432416 +v 1.577499 -0.588247 -0.428078 +v 1.573671 -0.585739 -0.427671 +v 1.581006 -0.592271 -0.428789 +v 1.584053 -0.597659 -0.429776 +v 1.586526 -0.604204 -0.431000 +v 1.584172 -0.597077 -0.435760 +v 1.581145 -0.591587 -0.435826 +v 1.586619 -0.603746 -0.435702 +v 1.588392 -0.611337 -0.435655 +v 1.577654 -0.587486 -0.435897 +v 1.573835 -0.584932 -0.435971 +v 1.577654 -0.587486 -0.435897 +v 1.577782 -0.588278 -0.443713 +v 1.573971 -0.585773 -0.444268 +v 1.573835 -0.584932 -0.435971 +v 1.581260 -0.592299 -0.442860 +v 1.577782 -0.588278 -0.443713 +v 1.584270 -0.597683 -0.441742 +v 1.586696 -0.604222 -0.440403 +v 1.588445 -0.611665 -0.438893 +v 1.584344 -0.599454 -0.447492 +v 1.581347 -0.594381 -0.449621 +v 1.586754 -0.605613 -0.444920 +v 1.588485 -0.612623 -0.442004 +v 1.577879 -0.590591 -0.451226 +v 1.574074 -0.588228 -0.452245 +v 1.581260 -0.592299 -0.442860 +v 1.581347 -0.594381 -0.449621 +v 1.577941 -0.594337 -0.458148 +v 1.574139 -0.592205 -0.459592 +v 1.581403 -0.597753 -0.455851 +v 1.584344 -0.599454 -0.447492 +v 1.584391 -0.602321 -0.452790 +v 1.586791 -0.607866 -0.449083 +v 1.584391 -0.602321 -0.452790 +v 1.588511 -0.614175 -0.444871 +v 1.586791 -0.607866 -0.449083 +v 1.586806 -0.610894 -0.452729 +v 1.584409 -0.606175 -0.457431 +v 1.588521 -0.616261 -0.447383 +v 1.586806 -0.610894 -0.452729 +v 1.577965 -0.599373 -0.464211 +v 1.574164 -0.597551 -0.466029 +v 1.581424 -0.602284 -0.461308 +v 1.577950 -0.605503 -0.469184 +v 1.574149 -0.604059 -0.471308 +v 1.581411 -0.607802 -0.465783 +v 1.584398 -0.610867 -0.461237 +v 1.586797 -0.614581 -0.455720 +v 1.588515 -0.618800 -0.449443 +v 1.586797 -0.614581 -0.455720 +v 1.586765 -0.618784 -0.457939 +v 1.584358 -0.616217 -0.464062 +v 1.588493 -0.621696 -0.450972 +v 1.586765 -0.618784 -0.457939 +v 1.577898 -0.612494 -0.472875 +v 1.574093 -0.611480 -0.475227 +v 1.581364 -0.614094 -0.469105 +v 1.577809 -0.620076 -0.475143 +v 1.573999 -0.619529 -0.477635 +v 1.581285 -0.620917 -0.471146 +v 1.584291 -0.622020 -0.465797 +v 1.586712 -0.623344 -0.459303 +v 1.588456 -0.624836 -0.451911 +v 1.586712 -0.623344 -0.459303 +v 1.588406 -0.628101 -0.452225 +v 1.586639 -0.628083 -0.459758 +v 1.577688 -0.627957 -0.475900 +v 1.573871 -0.627896 -0.478438 +v 1.581176 -0.628010 -0.471827 +v 1.584198 -0.628053 -0.466377 +v 1.586639 -0.628083 -0.459758 +v 1.581042 -0.635101 -0.471122 +v 1.577540 -0.635836 -0.475116 +v 1.584084 -0.634083 -0.465777 +v 1.586550 -0.632821 -0.459287 +v 1.588345 -0.631364 -0.451900 +v 1.586550 -0.632821 -0.459287 +v 1.573713 -0.636260 -0.477607 +v 1.588274 -0.634501 -0.450951 +v 1.577369 -0.643409 -0.472823 +v 1.573532 -0.644299 -0.475172 +v 1.580888 -0.641916 -0.469059 +v 1.583953 -0.639878 -0.464022 +v 1.586447 -0.637375 -0.457908 +v 1.586447 -0.637375 -0.457908 +v 1.580720 -0.648194 -0.465716 +v 1.577182 -0.650384 -0.469109 +v 1.583811 -0.645217 -0.461179 +v 1.586335 -0.641570 -0.455674 +v 1.588197 -0.637391 -0.449412 +v 1.586335 -0.641570 -0.455674 +v 1.573334 -0.651705 -0.471229 +v 1.588116 -0.639922 -0.447344 +v 1.576987 -0.656495 -0.464115 +v 1.573127 -0.658192 -0.465928 +v 1.580545 -0.653694 -0.461221 +v 1.583661 -0.649894 -0.457357 +v 1.586218 -0.645244 -0.452672 +v 1.586218 -0.645244 -0.452672 +v 1.583511 -0.653730 -0.452704 +v 1.580368 -0.658203 -0.455750 +v 1.586100 -0.648258 -0.449015 +v 1.583511 -0.653730 -0.452704 +v 1.583661 -0.649894 -0.457357 +v 1.588035 -0.641997 -0.444825 +v 1.576791 -0.661506 -0.458035 +v 1.572919 -0.663512 -0.459472 +v 1.576602 -0.665225 -0.451101 +v 1.572718 -0.667460 -0.452112 +v 1.580198 -0.661551 -0.449509 +v 1.583367 -0.656576 -0.447397 +v 1.580198 -0.661551 -0.449509 +v 1.580368 -0.658203 -0.455750 +v 1.585986 -0.650494 -0.444845 +v 1.587956 -0.643538 -0.441953 +v 1.583232 -0.658324 -0.441640 +v 1.580040 -0.663606 -0.442740 +v 1.585881 -0.651868 -0.440323 +v 1.587884 -0.644484 -0.438838 +v 1.576427 -0.667509 -0.443580 +v 1.572532 -0.669884 -0.444128 +v 1.576427 -0.667509 -0.443580 +v 1.576602 -0.665225 -0.451101 +v 1.572532 -0.669884 -0.444128 +vt 0.680940 0.777137 +vt 0.681000 0.776509 +vt 0.680880 0.776509 +vt 0.681118 0.776533 +vt 0.681229 0.776580 +vt 0.681330 0.776649 +vt 0.681415 0.776736 +vt 0.681483 0.776839 +vt 0.681530 0.776953 +vt 0.681555 0.777074 +vt 0.681556 0.777198 +vt 0.681534 0.777319 +vt 0.681489 0.777433 +vt 0.681424 0.777536 +vt 0.681340 0.777623 +vt 0.681241 0.777692 +vt 0.681130 0.777739 +vt 0.681013 0.777763 +vt 0.680893 0.777763 +vt 0.680775 0.777739 +vt 0.680664 0.777692 +vt 0.680563 0.777623 +vt 0.680477 0.777536 +vt 0.680410 0.777433 +vt 0.680363 0.777319 +vt 0.680338 0.777198 +vt 0.680337 0.777074 +vt 0.680359 0.776953 +vt 0.680403 0.776839 +vt 0.680469 0.776736 +vt 0.680553 0.776649 +vt 0.680652 0.776580 +vt 0.680762 0.776533 +vt 0.680822 0.774127 +vt 0.681390 0.774127 +vt 0.681465 0.773932 +vt 0.680862 0.773932 +vt 0.680798 0.774436 +vt 0.681310 0.774436 +vt 0.680792 0.774845 +vt 0.681227 0.774845 +vt 0.680804 0.775341 +vt 0.681146 0.775341 +vt 0.680834 0.775902 +vt 0.681069 0.775902 +vt 0.681301 0.775950 +vt 0.681949 0.774242 +vt 0.682058 0.774053 +vt 0.681812 0.774538 +vt 0.681655 0.774933 +vt 0.681482 0.775409 +vt 0.682287 0.774740 +vt 0.682476 0.774465 +vt 0.682059 0.775104 +vt 0.681799 0.775544 +vt 0.681519 0.776042 +vt 0.682618 0.774291 +vt 0.681716 0.776177 +vt 0.682952 0.774790 +vt 0.683123 0.774636 +vt 0.682715 0.775032 +vt 0.682423 0.775353 +vt 0.682085 0.775739 +vt 0.682734 0.775669 +vt 0.683081 0.775405 +vt 0.682330 0.775988 +vt 0.681885 0.776348 +vt 0.683358 0.775204 +vt 0.683555 0.775075 +vt 0.683679 0.775691 +vt 0.683895 0.775592 +vt 0.683370 0.775843 +vt 0.682979 0.776042 +vt 0.682523 0.776281 +vt 0.682017 0.776550 +vt 0.682657 0.776606 +vt 0.683150 0.776455 +vt 0.682110 0.776774 +vt 0.683902 0.776231 +vt 0.684132 0.776166 +vt 0.683570 0.776329 +vt 0.684019 0.776805 +vt 0.684256 0.776775 +vt 0.683676 0.776845 +vt 0.683239 0.776895 +vt 0.682727 0.776951 +vt 0.682158 0.777011 +vt 0.682731 0.777302 +vt 0.683244 0.777342 +vt 0.682161 0.777254 +vt 0.684025 0.777390 +vt 0.684263 0.777396 +vt 0.683681 0.777372 +vt 0.683920 0.777964 +vt 0.684151 0.778005 +vt 0.683587 0.777888 +vt 0.683164 0.777781 +vt 0.682668 0.777647 +vt 0.682117 0.777491 +vt 0.682030 0.777715 +vt 0.682540 0.777973 +vt 0.683708 0.778504 +vt 0.683926 0.778579 +vt 0.683396 0.778375 +vt 0.683002 0.778195 +vt 0.683398 0.778991 +vt 0.683597 0.779095 +vt 0.683116 0.778813 +vt 0.682764 0.778567 +vt 0.682353 0.778265 +vt 0.681901 0.777917 +vt 0.681736 0.778088 +vt 0.682114 0.778514 +vt 0.683000 0.779404 +vt 0.683175 0.779534 +vt 0.682759 0.779185 +vt 0.682460 0.778884 +vt 0.682337 0.779477 +vt 0.682531 0.779729 +vt 0.682101 0.779133 +vt 0.681832 0.778709 +vt 0.681542 0.778223 +vt 0.682677 0.779879 +vt 0.681325 0.778315 +vt 0.682008 0.779953 +vt 0.682122 0.780117 +vt 0.681866 0.779679 +vt 0.681701 0.779304 +vt 0.681518 0.778844 +vt 0.681275 0.779392 +vt 0.681366 0.779782 +vt 0.681184 0.778912 +vt 0.681095 0.778363 +vt 0.681452 0.780067 +vt 0.681531 0.780238 +vt 0.948856 0.541543 +vt 0.948436 0.541430 +vt 0.948204 0.541606 +vt 0.948650 0.541726 +vt 0.680854 0.779782 +vt 0.680884 0.780067 +vt 0.680840 0.779392 +vt 0.680842 0.778912 +vt 0.680860 0.778363 +vt 0.680412 0.779304 +vt 0.680351 0.779679 +vt 0.680506 0.778844 +vt 0.680628 0.778315 +vt 0.948040 0.541206 +vt 0.947784 0.541369 +vt 0.948677 0.541143 +vt 0.948321 0.540943 +vt 0.947684 0.540882 +vt 0.947406 0.541024 +vt 0.948001 0.540650 +vt 0.948616 0.540588 +vt 0.948343 0.540339 +vt 0.680189 0.778709 +vt 0.680009 0.779133 +vt 0.680410 0.778223 +vt 0.948699 0.539960 +vt 0.948516 0.539711 +vt 0.948111 0.540023 +vt 0.680213 0.778088 +vt 0.679903 0.778514 +vt 0.947381 0.540468 +vt 0.947084 0.540585 +vt 0.947728 0.540278 +vt 0.947143 0.539982 +vt 0.946831 0.540069 +vt 0.947514 0.539841 +vt 0.947929 0.539650 +vt 0.948373 0.539419 +vt 0.680045 0.777917 +vt 0.679658 0.778265 +vt 0.948275 0.539094 +vt 0.947804 0.539237 +vt 0.679912 0.777715 +vt 0.679465 0.777973 +vt 0.946979 0.539441 +vt 0.946657 0.539495 +vt 0.947366 0.539354 +vt 0.946895 0.538867 +vt 0.946568 0.538885 +vt 0.947291 0.538837 +vt 0.947740 0.538797 +vt 0.948224 0.538749 +vt 0.679819 0.777491 +vt 0.679331 0.777647 +vt 0.679771 0.777254 +vt 0.679261 0.777302 +vt 0.946895 0.538281 +vt 0.946568 0.538264 +vt 0.947291 0.538310 +vt 0.947740 0.538349 +vt 0.948224 0.538396 +vt 0.947366 0.537793 +vt 0.946979 0.537707 +vt 0.947804 0.537909 +vt 0.948275 0.538051 +vt 0.679768 0.777011 +vt 0.679257 0.776951 +vt 0.946657 0.537654 +vt 0.679812 0.776774 +vt 0.947143 0.537166 +vt 0.946831 0.537079 +vt 0.947514 0.537306 +vt 0.947929 0.537495 +vt 0.948373 0.537725 +vt 0.679320 0.776606 +vt 0.947728 0.536867 +vt 0.947381 0.536678 +vt 0.948111 0.537122 +vt 0.948516 0.537432 +vt 0.679900 0.776550 +vt 0.679448 0.776281 +vt 0.947084 0.536562 +vt 0.680028 0.776348 +vt 0.947684 0.536264 +vt 0.947406 0.536122 +vt 0.948001 0.536494 +vt 0.948343 0.536805 +vt 0.948699 0.537183 +vt 0.679635 0.775988 +vt 0.948616 0.536555 +vt 0.948321 0.536201 +vt 0.679874 0.775739 +vt 0.679608 0.775353 +vt 0.679303 0.775669 +vt 0.680193 0.776177 +vt 0.948040 0.535938 +vt 0.947784 0.535775 +vt 0.948436 0.535713 +vt 0.948204 0.535537 +vt 0.948677 0.535998 +vt 0.679967 0.775104 +vt 0.679827 0.774740 +vt 0.679405 0.775032 +vt 0.680156 0.775544 +vt 0.680387 0.776042 +vt 0.680367 0.774933 +vt 0.680298 0.774538 +vt 0.680470 0.775409 +vt 0.680604 0.775950 +vt 0.948856 0.535598 +vt 0.948650 0.535414 +vt 0.680266 0.774242 +vt 0.679743 0.774465 +vt 0.680272 0.774053 +vn 0.9997 -0.0171 0.0181 +vn 0.9930 -0.1121 0.0373 +vn 0.9933 -0.1140 0.0182 +vn 0.9928 -0.1065 0.0556 +vn 0.9926 -0.0975 0.0725 +vn 0.9925 -0.0854 0.0873 +vn 0.9925 -0.0707 0.0994 +vn 0.9927 -0.0539 0.1084 +vn 0.9929 -0.0356 0.1139 +vn 0.9931 -0.0168 0.1157 +vn 0.9935 0.0021 0.1138 +vn 0.9939 0.0203 0.1082 +vn 0.9944 0.0369 0.0992 +vn 0.9949 0.0517 0.0870 +vn 0.9954 0.0637 0.0722 +vn 0.9958 0.0726 0.0553 +vn 0.9963 0.0781 0.0370 +vn 0.9966 0.0800 0.0179 +vn 0.9969 0.0781 -0.0012 +vn 0.9972 0.0725 -0.0195 +vn 0.9973 0.0635 -0.0364 +vn 0.9974 0.0514 -0.0511 +vn 0.9973 0.0366 -0.0633 +vn 0.9972 0.0199 -0.0723 +vn 0.9970 0.0018 -0.0778 +vn 0.9967 -0.0172 -0.0796 +vn 0.9963 -0.0360 -0.0777 +vn 0.9959 -0.0543 -0.0721 +vn 0.9955 -0.0710 -0.0631 +vn 0.9950 -0.0856 -0.0510 +vn 0.9946 -0.0977 -0.0361 +vn 0.9941 -0.1066 -0.0192 +vn 0.9937 -0.1121 -0.0008 +vn 0.6346 -0.7727 0.0130 +vn 0.6320 -0.7577 0.1627 +vn 0.5241 -0.8332 0.1764 +vn 0.5269 -0.8498 0.0112 +vn 0.7996 -0.6003 0.0157 +vn 0.7976 -0.5887 0.1310 +vn 0.8931 -0.4496 0.0171 +vn 0.8916 -0.4410 0.1024 +vn 0.9464 -0.3226 0.0178 +vn 0.9453 -0.3166 0.0780 +vn 0.9769 -0.2129 0.0181 +vn 0.9763 -0.2091 0.0567 +vn 0.9757 -0.1978 0.0938 +vn 0.6299 -0.7137 0.3065 +vn 0.5217 -0.7846 0.3349 +vn 0.7960 -0.5550 0.2417 +vn 0.8904 -0.4161 0.1845 +vn 0.9445 -0.2990 0.1359 +vn 0.7947 -0.5004 0.3436 +vn 0.6282 -0.6426 0.4386 +vn 0.8895 -0.3757 0.2600 +vn 0.9439 -0.2705 0.1892 +vn 0.9754 -0.1796 0.1279 +vn 0.5200 -0.7061 0.4807 +vn 0.9752 -0.1551 0.1578 +vn 0.6272 -0.5473 0.5541 +vn 0.5189 -0.6009 0.6080 +vn 0.7940 -0.4271 0.4327 +vn 0.8890 -0.3215 0.3261 +vn 0.9436 -0.2323 0.2359 +vn 0.8889 -0.2556 0.3802 +vn 0.7937 -0.3380 0.5057 +vn 0.9436 -0.1858 0.2741 +vn 0.9752 -0.1253 0.1823 +vn 0.6269 -0.4316 0.6486 +vn 0.5185 -0.4732 0.7122 +vn 0.6275 -0.2999 0.7185 +vn 0.5191 -0.3280 0.7893 +vn 0.7942 -0.2366 0.5598 +vn 0.8892 -0.1805 0.4204 +vn 0.9439 -0.1328 0.3025 +vn 0.9754 -0.0914 0.2005 +vn 0.9444 -0.0753 0.3199 +vn 0.8900 -0.0991 0.4450 +vn 0.9758 -0.0546 0.2117 +vn 0.6288 -0.1574 0.7614 +vn 0.5207 -0.1708 0.8365 +vn 0.7952 -0.1267 0.5930 +vn 0.6310 -0.0095 0.7757 +vn 0.5230 -0.0075 0.8523 +vn 0.7969 -0.0126 0.6040 +vn 0.8913 -0.0145 0.4532 +vn 0.9453 -0.0156 0.3257 +vn 0.9764 -0.0164 0.2154 +vn 0.9465 0.0441 0.3197 +vn 0.8929 0.0701 0.4447 +vn 0.9771 0.0219 0.2116 +vn 0.6339 0.1384 0.7609 +vn 0.5262 0.1556 0.8360 +vn 0.7991 0.1014 0.5926 +vn 0.6374 0.2807 0.7176 +vn 0.5301 0.3127 0.7882 +vn 0.8018 0.2111 0.5590 +vn 0.8949 0.1513 0.4198 +vn 0.9479 0.1014 0.3021 +vn 0.9780 0.0587 0.2003 +vn 0.9789 0.0925 0.1819 +vn 0.9494 0.1543 0.2735 +vn 0.6414 0.4120 0.6472 +vn 0.5345 0.4576 0.7106 +vn 0.8049 0.3123 0.5046 +vn 0.8971 0.2263 0.3794 +vn 0.6456 0.5273 0.5523 +vn 0.5392 0.5848 0.6060 +vn 0.8081 0.4011 0.4314 +vn 0.8995 0.2920 0.3250 +vn 0.9510 0.2007 0.2351 +vn 0.9800 0.1222 0.1573 +vn 0.9810 0.1465 0.1274 +vn 0.9527 0.2387 0.1883 +vn 0.6499 0.6222 0.4365 +vn 0.5438 0.6895 0.4783 +vn 0.8114 0.4740 0.3420 +vn 0.9019 0.3459 0.2587 +vn 0.8145 0.5282 0.2399 +vn 0.6540 0.6927 0.3041 +vn 0.9041 0.3860 0.1831 +vn 0.9542 0.2670 0.1350 +vn 0.9819 0.1646 0.0931 +vn 0.5484 0.7674 0.3323 +vn 0.9828 0.1757 0.0560 +vn 0.6576 0.7361 0.1602 +vn 0.5524 0.8153 0.1736 +vn 0.8173 0.5616 0.1290 +vn 0.9062 0.4106 0.1010 +vn 0.9556 0.2843 0.0770 +vn 0.9079 0.4188 0.0156 +vn 0.8197 0.5727 0.0137 +vn 0.9569 0.2901 0.0168 +vn 0.9836 0.1794 0.0175 +vn 0.6606 0.7506 0.0105 +vn 0.5557 0.8313 0.0084 +vn 0.6607 0.7506 0.0105 +vn 0.6630 0.7355 -0.1392 +vn 0.5583 0.8147 -0.1567 +vn 0.8215 0.5611 -0.1016 +vn 0.6630 0.7356 -0.1392 +vn 0.9093 0.4103 -0.0698 +vn 0.9578 0.2841 -0.0435 +vn 0.9842 0.1756 -0.0211 +vn 0.9102 0.3853 -0.1518 +vn 0.8227 0.5273 -0.2124 +vn 0.9585 0.2665 -0.1014 +vn 0.9847 0.1643 -0.0582 +vn 0.6646 0.6916 -0.2830 +vn 0.5600 0.7661 -0.3153 +vn 0.8227 0.5273 -0.2123 +vn 0.6653 0.6205 -0.4152 +vn 0.5608 0.6877 -0.4610 +vn 0.8233 0.4727 -0.3143 +vn 0.9102 0.3854 -0.1518 +vn 0.9107 0.3450 -0.2273 +vn 0.9589 0.2380 -0.1547 +vn 0.9849 0.1461 -0.0924 +vn 0.9589 0.1998 -0.2013 +vn 0.9107 0.2908 -0.2934 +vn 0.9850 0.1217 -0.1223 +vn 0.6652 0.5252 -0.5307 +vn 0.5608 0.5825 -0.5884 +vn 0.8232 0.3994 -0.4034 +vn 0.6644 0.4095 -0.6252 +vn 0.5599 0.4548 -0.6926 +vn 0.8226 0.3104 -0.4764 +vn 0.9103 0.2248 -0.3476 +vn 0.9587 0.1533 -0.2396 +vn 0.9849 0.0919 -0.1468 +vn 0.9582 0.1003 -0.2680 +vn 0.9095 0.1498 -0.3878 +vn 0.9846 0.0579 -0.1650 +vn 0.6630 0.2779 -0.6951 +vn 0.5583 0.3096 -0.7697 +vn 0.8215 0.2090 -0.5305 +vn 0.6610 0.1354 -0.7380 +vn 0.5562 0.1524 -0.8170 +vn 0.8200 0.0992 -0.5637 +vn 0.9084 0.0684 -0.4124 +vn 0.9575 0.0428 -0.2854 +vn 0.9841 0.0211 -0.1761 +vn 0.9574 0.0429 -0.2854 +vn 0.9835 -0.0172 -0.1799 +vn 0.9565 -0.0169 -0.2912 +vn 0.6587 -0.0125 -0.7523 +vn 0.5535 -0.0109 -0.8328 +vn 0.8182 -0.0150 -0.5747 +vn 0.9071 -0.0162 -0.4206 +vn 0.8161 -0.1290 -0.5633 +vn 0.6560 -0.1604 -0.7375 +vn 0.9055 -0.1008 -0.4121 +vn 0.9554 -0.0765 -0.2852 +vn 0.9828 -0.0554 -0.1760 +vn 0.5506 -0.1740 -0.8164 +vn 0.9820 -0.0921 -0.1647 +vn 0.6531 -0.3027 -0.6942 +vn 0.5473 -0.3311 -0.7686 +vn 0.8139 -0.2387 -0.5297 +vn 0.9038 -0.1821 -0.3872 +vn 0.9542 -0.1339 -0.2675 +vn 0.9542 -0.1339 -0.2676 +vn 0.8115 -0.3399 -0.4753 +vn 0.6500 -0.4341 -0.6238 +vn 0.9020 -0.2570 -0.3468 +vn 0.9529 -0.1868 -0.2390 +vn 0.9812 -0.1260 -0.1464 +vn 0.5440 -0.4760 -0.6910 +vn 0.9803 -0.1557 -0.1218 +vn 0.6468 -0.5494 -0.5289 +vn 0.5405 -0.6033 -0.5864 +vn 0.8091 -0.4287 -0.4020 +vn 0.9002 -0.3227 -0.2924 +vn 0.9515 -0.2332 -0.2006 +vn 0.8983 -0.3767 -0.2261 +vn 0.8066 -0.5017 -0.3126 +vn 0.9501 -0.2712 -0.1538 +vn 0.9794 -0.1800 -0.0918 +vn 0.6436 -0.6443 -0.4131 +vn 0.5369 -0.7080 -0.4587 +vn 0.6405 -0.7148 -0.2806 +vn 0.5335 -0.7859 -0.3127 +vn 0.8041 -0.5559 -0.2106 +vn 0.8965 -0.4167 -0.1505 +vn 0.8042 -0.5558 -0.2105 +vn 0.8066 -0.5016 -0.3127 +vn 0.9488 -0.2994 -0.1005 +vn 0.9785 -0.1981 -0.0576 +vn 0.8947 -0.4414 -0.0684 +vn 0.8018 -0.5892 -0.0997 +vn 0.9475 -0.3168 -0.0425 +vn 0.9777 -0.2092 -0.0205 +vn 0.6375 -0.7583 -0.1368 +vn 0.5301 -0.8338 -0.1540 +vn 0.6374 -0.7583 -0.1367 +vn 0.6404 -0.7149 -0.2807 +vn 0.5301 -0.8339 -0.1540 +usemtl Scene_-_Root +s 1 +f 46386/46386/35194 46387/46387/35195 46388/46388/35196 +f 46386/46386/35194 46389/46389/35197 46387/46387/35195 +f 46386/46386/35194 46390/46390/35198 46389/46389/35197 +f 46386/46386/35194 46391/46391/35199 46390/46390/35198 +f 46386/46386/35194 46392/46392/35200 46391/46391/35199 +f 46386/46386/35194 46393/46393/35201 46392/46392/35200 +f 46386/46386/35194 46394/46394/35202 46393/46393/35201 +f 46386/46386/35194 46395/46395/35203 46394/46394/35202 +f 46386/46386/35194 46396/46396/35204 46395/46395/35203 +f 46386/46386/35194 46397/46397/35205 46396/46396/35204 +f 46386/46386/35194 46398/46398/35206 46397/46397/35205 +f 46386/46386/35194 46399/46399/35207 46398/46398/35206 +f 46386/46386/35194 46400/46400/35208 46399/46399/35207 +f 46386/46386/35194 46401/46401/35209 46400/46400/35208 +f 46386/46386/35194 46402/46402/35210 46401/46401/35209 +f 46386/46386/35194 46403/46403/35211 46402/46402/35210 +f 46386/46386/35194 46404/46404/35212 46403/46403/35211 +f 46386/46386/35194 46405/46405/35213 46404/46404/35212 +f 46386/46386/35194 46406/46406/35214 46405/46405/35213 +f 46386/46386/35194 46407/46407/35215 46406/46406/35214 +f 46386/46386/35194 46408/46408/35216 46407/46407/35215 +f 46386/46386/35194 46409/46409/35217 46408/46408/35216 +f 46386/46386/35194 46410/46410/35218 46409/46409/35217 +f 46386/46386/35194 46411/46411/35219 46410/46410/35218 +f 46386/46386/35194 46412/46412/35220 46411/46411/35219 +f 46386/46386/35194 46413/46413/35221 46412/46412/35220 +f 46386/46386/35194 46414/46414/35222 46413/46413/35221 +f 46386/46386/35194 46415/46415/35223 46414/46414/35222 +f 46386/46386/35194 46416/46416/35224 46415/46415/35223 +f 46386/46386/35194 46417/46417/35225 46416/46416/35224 +f 46386/46386/35194 46418/46418/35226 46417/46417/35225 +f 46386/46386/35194 46388/46388/35196 46418/46418/35226 +f 46419/46419/35227 46420/46420/35228 46421/46421/35229 +f 46419/46419/35227 46421/46421/35229 46422/46422/35230 +f 46423/46423/35231 46424/46424/35232 46420/46420/35228 +f 46423/46423/35231 46420/46420/35228 46419/46419/35227 +f 46425/46425/35233 46426/46426/35234 46424/46424/35232 +f 46425/46425/35233 46424/46424/35232 46423/46423/35231 +f 46427/46427/35235 46428/46428/35236 46426/46426/35234 +f 46427/46427/35235 46426/46426/35234 46425/46425/35233 +f 46429/46429/35237 46430/46430/35238 46428/46428/35236 +f 46429/46429/35237 46428/46428/35236 46427/46427/35235 +f 46388/46388/35196 46387/46387/35195 46430/46430/35238 +f 46388/46388/35196 46430/46430/35238 46429/46429/35237 +f 46387/46387/35195 46389/46389/35197 46431/46431/35239 +f 46387/46387/35195 46431/46431/35239 46430/46430/35238 +f 46420/46420/35228 46432/46432/35240 46433/46433/35241 +f 46420/46420/35228 46433/46433/35241 46421/46421/35229 +f 46424/46424/35232 46434/46434/35242 46432/46432/35240 +f 46424/46424/35232 46432/46432/35240 46420/46420/35228 +f 46426/46426/35234 46435/46435/35243 46434/46434/35242 +f 46426/46426/35234 46434/46434/35242 46424/46424/35232 +f 46428/46428/35236 46436/46436/35244 46435/46435/35243 +f 46428/46428/35236 46435/46435/35243 46426/46426/35234 +f 46430/46430/35238 46431/46431/35239 46436/46436/35244 +f 46430/46430/35238 46436/46436/35244 46428/46428/35236 +f 46434/46434/35242 46437/46437/35245 46438/46438/35246 +f 46434/46434/35242 46438/46438/35246 46432/46432/35240 +f 46435/46435/35243 46439/46439/35247 46437/46437/35245 +f 46435/46435/35243 46437/46437/35245 46434/46434/35242 +f 46436/46436/35244 46440/46440/35248 46439/46439/35247 +f 46436/46436/35244 46439/46439/35247 46435/46435/35243 +f 46431/46431/35239 46441/46441/35249 46440/46440/35248 +f 46431/46431/35239 46440/46440/35248 46436/46436/35244 +f 46389/46389/35197 46390/46390/35198 46441/46441/35249 +f 46389/46389/35197 46441/46441/35249 46431/46431/35239 +f 46432/46432/35240 46438/46438/35246 46442/46442/35250 +f 46432/46432/35240 46442/46442/35250 46433/46433/35241 +f 46390/46390/35198 46391/46391/35199 46443/46443/35251 +f 46390/46390/35198 46443/46443/35251 46441/46441/35249 +f 46438/46438/35246 46444/46444/35252 46445/46445/35253 +f 46438/46438/35246 46445/46445/35253 46442/46442/35250 +f 46437/46437/35245 46446/46446/35254 46444/46444/35252 +f 46437/46437/35245 46444/46444/35252 46438/46438/35246 +f 46439/46439/35247 46447/46447/35255 46446/46446/35254 +f 46439/46439/35247 46446/46446/35254 46437/46437/35245 +f 46440/46440/35248 46448/46448/35256 46447/46447/35255 +f 46440/46440/35248 46447/46447/35255 46439/46439/35247 +f 46441/46441/35249 46443/46443/35251 46448/46448/35256 +f 46441/46441/35249 46448/46448/35256 46440/46440/35248 +f 46447/46447/35255 46449/46449/35257 46450/46450/35258 +f 46447/46447/35255 46450/46450/35258 46446/46446/35254 +f 46448/46448/35256 46451/46451/35259 46449/46449/35257 +f 46448/46448/35256 46449/46449/35257 46447/46447/35255 +f 46443/46443/35251 46452/46452/35260 46451/46451/35259 +f 46443/46443/35251 46451/46451/35259 46448/46448/35256 +f 46391/46391/35199 46392/46392/35200 46452/46452/35260 +f 46391/46391/35199 46452/46452/35260 46443/46443/35251 +f 46444/46444/35252 46453/46453/35261 46454/46454/35262 +f 46444/46444/35252 46454/46454/35262 46445/46445/35253 +f 46446/46446/35254 46450/46450/35258 46453/46453/35261 +f 46446/46446/35254 46453/46453/35261 46444/46444/35252 +f 46453/46453/35261 46455/46455/35263 46456/46456/35264 +f 46453/46453/35261 46456/46456/35264 46454/46454/35262 +f 46450/46450/35258 46457/46457/35265 46455/46455/35263 +f 46450/46450/35258 46455/46455/35263 46453/46453/35261 +f 46449/46449/35257 46458/46458/35266 46457/46457/35265 +f 46449/46449/35257 46457/46457/35265 46450/46450/35258 +f 46451/46451/35259 46459/46459/35267 46458/46458/35266 +f 46451/46451/35259 46458/46458/35266 46449/46449/35257 +f 46452/46452/35260 46460/46460/35268 46459/46459/35267 +f 46452/46452/35260 46459/46459/35267 46451/46451/35259 +f 46392/46392/35200 46393/46393/35201 46460/46460/35268 +f 46392/46392/35200 46460/46460/35268 46452/46452/35260 +f 46459/46459/35267 46461/46461/35269 46462/46462/35270 +f 46459/46459/35267 46462/46462/35270 46458/46458/35266 +f 46460/46460/35268 46463/46463/35271 46461/46461/35269 +f 46460/46460/35268 46461/46461/35269 46459/46459/35267 +f 46393/46393/35201 46394/46394/35202 46463/46463/35271 +f 46393/46393/35201 46463/46463/35271 46460/46460/35268 +f 46455/46455/35263 46464/46464/35272 46465/46465/35273 +f 46455/46455/35263 46465/46465/35273 46456/46456/35264 +f 46457/46457/35265 46466/46466/35274 46464/46464/35272 +f 46457/46457/35265 46464/46464/35272 46455/46455/35263 +f 46458/46458/35266 46462/46462/35270 46466/46466/35274 +f 46458/46458/35266 46466/46466/35274 46457/46457/35265 +f 46464/46464/35272 46467/46467/35275 46468/46468/35276 +f 46464/46464/35272 46468/46468/35276 46465/46465/35273 +f 46466/46466/35274 46469/46469/35277 46467/46467/35275 +f 46466/46466/35274 46467/46467/35275 46464/46464/35272 +f 46462/46462/35270 46470/46470/35278 46469/46469/35277 +f 46462/46462/35270 46469/46469/35277 46466/46466/35274 +f 46461/46461/35269 46471/46471/35279 46470/46470/35278 +f 46461/46461/35269 46470/46470/35278 46462/46462/35270 +f 46463/46463/35271 46472/46472/35280 46471/46471/35279 +f 46463/46463/35271 46471/46471/35279 46461/46461/35269 +f 46394/46394/35202 46395/46395/35203 46472/46472/35280 +f 46394/46394/35202 46472/46472/35280 46463/46463/35271 +f 46471/46471/35279 46473/46473/35281 46474/46474/35282 +f 46471/46471/35279 46474/46474/35282 46470/46470/35278 +f 46472/46472/35280 46475/46475/35283 46473/46473/35281 +f 46472/46472/35280 46473/46473/35281 46471/46471/35279 +f 46395/46395/35203 46396/46396/35204 46475/46475/35283 +f 46395/46395/35203 46475/46475/35283 46472/46472/35280 +f 46467/46467/35275 46476/46476/35284 46477/46477/35285 +f 46467/46467/35275 46477/46477/35285 46468/46468/35276 +f 46469/46469/35277 46478/46478/35286 46476/46476/35284 +f 46469/46469/35277 46476/46476/35284 46467/46467/35275 +f 46470/46470/35278 46474/46474/35282 46478/46478/35286 +f 46470/46470/35278 46478/46478/35286 46469/46469/35277 +f 46476/46476/35284 46479/46479/35287 46480/46480/35288 +f 46476/46476/35284 46480/46480/35288 46477/46477/35285 +f 46478/46478/35286 46481/46481/35289 46479/46479/35287 +f 46478/46478/35286 46479/46479/35287 46476/46476/35284 +f 46474/46474/35282 46482/46482/35290 46481/46481/35289 +f 46474/46474/35282 46481/46481/35289 46478/46478/35286 +f 46473/46473/35281 46483/46483/35291 46482/46482/35290 +f 46473/46473/35281 46482/46482/35290 46474/46474/35282 +f 46475/46475/35283 46484/46484/35292 46483/46483/35291 +f 46475/46475/35283 46483/46483/35291 46473/46473/35281 +f 46396/46396/35204 46397/46397/35205 46484/46484/35292 +f 46396/46396/35204 46484/46484/35292 46475/46475/35283 +f 46484/46484/35292 46485/46485/35293 46486/46486/35294 +f 46484/46484/35292 46486/46486/35294 46483/46483/35291 +f 46397/46397/35205 46398/46398/35206 46485/46485/35293 +f 46397/46397/35205 46485/46485/35293 46484/46484/35292 +f 46479/46479/35287 46487/46487/35295 46488/46488/35296 +f 46479/46479/35287 46488/46488/35296 46480/46480/35288 +f 46481/46481/35289 46489/46489/35297 46487/46487/35295 +f 46481/46481/35289 46487/46487/35295 46479/46479/35287 +f 46482/46482/35290 46490/46490/35298 46489/46489/35297 +f 46482/46482/35290 46489/46489/35297 46481/46481/35289 +f 46483/46483/35291 46486/46486/35294 46490/46490/35298 +f 46483/46483/35291 46490/46490/35298 46482/46482/35290 +f 46487/46487/35295 46491/46491/35299 46492/46492/35300 +f 46487/46487/35295 46492/46492/35300 46488/46488/35296 +f 46489/46489/35297 46493/46493/35301 46491/46491/35299 +f 46489/46489/35297 46491/46491/35299 46487/46487/35295 +f 46490/46490/35298 46494/46494/35302 46493/46493/35301 +f 46490/46490/35298 46493/46493/35301 46489/46489/35297 +f 46486/46486/35294 46495/46495/35303 46494/46494/35302 +f 46486/46486/35294 46494/46494/35302 46490/46490/35298 +f 46485/46485/35293 46496/46496/35304 46495/46495/35303 +f 46485/46485/35293 46495/46495/35303 46486/46486/35294 +f 46398/46398/35206 46399/46399/35207 46496/46496/35304 +f 46398/46398/35206 46496/46496/35304 46485/46485/35293 +f 46496/46496/35304 46497/46497/35305 46498/46498/35306 +f 46496/46496/35304 46498/46498/35306 46495/46495/35303 +f 46399/46399/35207 46400/46400/35208 46497/46497/35305 +f 46399/46399/35207 46497/46497/35305 46496/46496/35304 +f 46491/46491/35299 46499/46499/35307 46500/46500/35308 +f 46491/46491/35299 46500/46500/35308 46492/46492/35300 +f 46493/46493/35301 46501/46501/35309 46499/46499/35307 +f 46493/46493/35301 46499/46499/35307 46491/46491/35299 +f 46494/46494/35302 46502/46502/35310 46501/46501/35309 +f 46494/46494/35302 46501/46501/35309 46493/46493/35301 +f 46495/46495/35303 46498/46498/35306 46502/46502/35310 +f 46495/46495/35303 46502/46502/35310 46494/46494/35302 +f 46501/46501/35309 46503/46503/35311 46504/46504/35312 +f 46501/46501/35309 46504/46504/35312 46499/46499/35307 +f 46502/46502/35310 46505/46505/35313 46503/46503/35311 +f 46502/46502/35310 46503/46503/35311 46501/46501/35309 +f 46498/46498/35306 46506/46506/35314 46505/46505/35313 +f 46498/46498/35306 46505/46505/35313 46502/46502/35310 +f 46497/46497/35305 46507/46507/35315 46506/46506/35314 +f 46497/46497/35305 46506/46506/35314 46498/46498/35306 +f 46400/46400/35208 46401/46401/35209 46507/46507/35315 +f 46400/46400/35208 46507/46507/35315 46497/46497/35305 +f 46499/46499/35307 46504/46504/35312 46508/46508/35316 +f 46499/46499/35307 46508/46508/35316 46500/46500/35308 +f 46401/46401/35209 46402/46402/35210 46509/46509/35317 +f 46401/46401/35209 46509/46509/35317 46507/46507/35315 +f 46504/46504/35312 46510/46510/35318 46511/46511/35319 +f 46504/46504/35312 46511/46511/35319 46508/46508/35316 +f 46503/46503/35311 46512/46512/35320 46510/46510/35318 +f 46503/46503/35311 46510/46510/35318 46504/46504/35312 +f 46505/46505/35313 46513/46513/35321 46512/46512/35320 +f 46505/46505/35313 46512/46512/35320 46503/46503/35311 +f 46506/46506/35314 46514/46514/35322 46513/46513/35321 +f 46506/46506/35314 46513/46513/35321 46505/46505/35313 +f 46507/46507/35315 46509/46509/35317 46514/46514/35322 +f 46507/46507/35315 46514/46514/35322 46506/46506/35314 +f 46513/46513/35321 46515/46515/35323 46516/46516/35324 +f 46513/46513/35321 46516/46516/35324 46512/46512/35320 +f 46514/46514/35322 46517/46517/35325 46515/46515/35323 +f 46514/46514/35322 46515/46515/35323 46513/46513/35321 +f 46509/46509/35317 46518/46518/35326 46517/46517/35325 +f 46509/46509/35317 46517/46517/35325 46514/46514/35322 +f 46402/46402/35210 46403/46403/35211 46518/46518/35326 +f 46402/46402/35210 46518/46518/35326 46509/46509/35317 +f 46510/46510/35318 46519/46519/35327 46520/46520/35328 +f 46510/46510/35318 46520/46520/35328 46511/46511/35319 +f 46512/46512/35320 46516/46516/35324 46519/46519/35327 +f 46512/46512/35320 46519/46519/35327 46510/46510/35318 +f 46521/46521/35329 46522/46522/35330 46523/46523/35331 +f 46521/46521/35329 46523/46523/35331 46524/46524/35328 +f 46516/46516/35324 46525/46525/35332 46526/46526/35333 +f 46516/46516/35324 46526/46526/35333 46519/46519/35327 +f 46515/46515/35323 46527/46527/35334 46525/46525/35332 +f 46515/46515/35323 46525/46525/35332 46516/46516/35324 +f 46517/46517/35325 46528/46528/35335 46527/46527/35334 +f 46517/46517/35325 46527/46527/35334 46515/46515/35323 +f 46518/46518/35326 46529/46529/35336 46528/46528/35335 +f 46518/46518/35326 46528/46528/35335 46517/46517/35325 +f 46403/46403/35211 46404/46404/35212 46529/46529/35336 +f 46403/46403/35211 46529/46529/35336 46518/46518/35326 +f 46527/46527/35334 46530/46530/35337 46531/46531/35338 +f 46527/46527/35334 46531/46531/35338 46525/46525/35332 +f 46528/46528/35335 46532/46532/35339 46530/46530/35337 +f 46528/46528/35335 46530/46530/35337 46527/46527/35334 +f 46529/46529/35336 46533/46533/35340 46532/46532/35339 +f 46529/46529/35336 46532/46532/35339 46528/46528/35335 +f 46404/46404/35212 46405/46405/35213 46533/46533/35340 +f 46404/46404/35212 46533/46533/35340 46529/46529/35336 +f 46522/46522/35330 46534/46534/35341 46535/46535/35342 +f 46522/46522/35330 46535/46535/35342 46523/46523/35331 +f 46536/46536/35332 46537/46537/35343 46534/46534/35341 +f 46536/46536/35332 46534/46534/35341 46522/46522/35330 +f 46534/46534/35341 46538/46538/35344 46539/46539/35345 +f 46534/46534/35341 46539/46539/35345 46535/46535/35342 +f 46537/46537/35343 46540/46540/35346 46538/46538/35344 +f 46537/46537/35343 46538/46538/35344 46534/46534/35341 +f 46541/46541/35347 46542/46542/35348 46540/46540/35346 +f 46541/46541/35347 46540/46540/35346 46537/46537/35343 +f 46532/46532/35339 46543/46543/35349 46544/46544/35348 +f 46532/46532/35339 46544/46544/35348 46530/46530/35337 +f 46533/46533/35340 46545/46545/35350 46543/46543/35349 +f 46533/46533/35340 46543/46543/35349 46532/46532/35339 +f 46405/46405/35213 46406/46406/35214 46545/46545/35350 +f 46405/46405/35213 46545/46545/35350 46533/46533/35340 +f 46546/46546/35349 46547/46547/35351 46548/46548/35352 +f 46546/46546/35349 46548/46548/35352 46542/46542/35348 +f 46545/46545/35350 46549/46549/35353 46550/46550/35351 +f 46545/46545/35350 46550/46550/35351 46543/46543/35349 +f 46406/46406/35214 46407/46407/35215 46549/46549/35353 +f 46406/46406/35214 46549/46549/35353 46545/46545/35350 +f 46538/46538/35344 46551/46551/35354 46552/46552/35355 +f 46538/46538/35344 46552/46552/35355 46539/46539/35345 +f 46540/46540/35346 46553/46553/35356 46551/46551/35354 +f 46540/46540/35346 46551/46551/35354 46538/46538/35344 +f 46542/46542/35348 46548/46548/35352 46553/46553/35356 +f 46542/46542/35348 46553/46553/35356 46540/46540/35346 +f 46551/46551/35354 46554/46554/35357 46555/46555/35358 +f 46551/46551/35354 46555/46555/35358 46552/46552/35355 +f 46553/46553/35356 46556/46556/35359 46554/46554/35357 +f 46553/46553/35356 46554/46554/35357 46551/46551/35354 +f 46548/46548/35352 46557/46557/35360 46556/46556/35359 +f 46548/46548/35352 46556/46556/35359 46553/46553/35356 +f 46547/46547/35351 46558/46558/35361 46557/46557/35360 +f 46547/46547/35351 46557/46557/35360 46548/46548/35352 +f 46549/46549/35353 46559/46559/35362 46560/46560/35361 +f 46549/46549/35353 46560/46560/35361 46550/46550/35351 +f 46407/46407/35215 46408/46408/35216 46559/46559/35362 +f 46407/46407/35215 46559/46559/35362 46549/46549/35353 +f 46558/46558/35361 46561/46561/35363 46562/46562/35364 +f 46558/46558/35361 46562/46562/35364 46557/46557/35360 +f 46559/46559/35362 46563/46563/35365 46564/46564/35363 +f 46559/46559/35362 46564/46564/35363 46560/46560/35361 +f 46408/46408/35216 46409/46409/35217 46563/46563/35365 +f 46408/46408/35216 46563/46563/35365 46559/46559/35362 +f 46554/46554/35357 46565/46565/35366 46566/46566/35367 +f 46554/46554/35357 46566/46566/35367 46555/46555/35358 +f 46556/46556/35359 46567/46567/35368 46565/46565/35366 +f 46556/46556/35359 46565/46565/35366 46554/46554/35357 +f 46557/46557/35360 46562/46562/35364 46567/46567/35368 +f 46557/46557/35360 46567/46567/35368 46556/46556/35359 +f 46565/46565/35366 46568/46568/35369 46569/46569/35370 +f 46565/46565/35366 46569/46569/35370 46566/46566/35367 +f 46567/46567/35368 46570/46570/35371 46568/46568/35369 +f 46567/46567/35368 46568/46568/35369 46565/46565/35366 +f 46562/46562/35364 46571/46571/35372 46570/46570/35371 +f 46562/46562/35364 46570/46570/35371 46567/46567/35368 +f 46561/46561/35363 46572/46572/35373 46571/46571/35372 +f 46561/46561/35363 46571/46571/35372 46562/46562/35364 +f 46563/46563/35365 46573/46573/35374 46574/46574/35375 +f 46563/46563/35365 46574/46574/35375 46564/46564/35363 +f 46409/46409/35217 46410/46410/35218 46573/46573/35374 +f 46409/46409/35217 46573/46573/35374 46563/46563/35365 +f 46573/46573/35374 46575/46575/35376 46576/46576/35377 +f 46573/46573/35374 46576/46576/35377 46574/46574/35375 +f 46410/46410/35218 46411/46411/35219 46575/46575/35376 +f 46410/46410/35218 46575/46575/35376 46573/46573/35374 +f 46568/46568/35369 46577/46577/35378 46578/46578/35379 +f 46568/46568/35369 46578/46578/35379 46569/46569/35370 +f 46570/46570/35371 46579/46579/35380 46577/46577/35378 +f 46570/46570/35371 46577/46577/35378 46568/46568/35369 +f 46571/46571/35372 46580/46580/35381 46579/46579/35380 +f 46571/46571/35372 46579/46579/35380 46570/46570/35371 +f 46572/46572/35373 46581/46581/35377 46580/46580/35381 +f 46572/46572/35373 46580/46580/35381 46571/46571/35372 +f 46579/46579/35380 46582/46582/35382 46583/46583/35383 +f 46579/46579/35380 46583/46583/35383 46577/46577/35378 +f 46580/46580/35381 46584/46584/35384 46582/46582/35382 +f 46580/46580/35381 46582/46582/35382 46579/46579/35380 +f 46581/46581/35377 46585/46585/35385 46584/46584/35384 +f 46581/46581/35377 46584/46584/35384 46580/46580/35381 +f 46575/46575/35376 46586/46586/35386 46587/46587/35385 +f 46575/46575/35376 46587/46587/35385 46576/46576/35377 +f 46411/46411/35219 46412/46412/35220 46586/46586/35386 +f 46411/46411/35219 46586/46586/35386 46575/46575/35376 +f 46577/46577/35378 46583/46583/35383 46588/46588/35387 +f 46577/46577/35378 46588/46588/35387 46578/46578/35379 +f 46412/46412/35220 46413/46413/35221 46589/46589/35388 +f 46412/46412/35220 46589/46589/35388 46586/46586/35386 +f 46583/46583/35383 46590/46590/35389 46591/46591/35390 +f 46583/46583/35383 46591/46591/35390 46588/46588/35387 +f 46582/46582/35382 46592/46592/35391 46590/46590/35389 +f 46582/46582/35382 46590/46590/35389 46583/46583/35383 +f 46584/46584/35384 46593/46593/35392 46592/46592/35391 +f 46584/46584/35384 46592/46592/35391 46582/46582/35382 +f 46585/46585/35385 46594/46594/35393 46593/46593/35392 +f 46585/46585/35385 46593/46593/35392 46584/46584/35384 +f 46586/46586/35386 46589/46589/35388 46595/46595/35394 +f 46586/46586/35386 46595/46595/35394 46587/46587/35385 +f 46592/46592/35391 46596/46596/35395 46597/46597/35396 +f 46592/46592/35391 46597/46597/35396 46590/46590/35389 +f 46593/46593/35392 46598/46598/35397 46596/46596/35395 +f 46593/46593/35392 46596/46596/35395 46592/46592/35391 +f 46594/46594/35393 46599/46599/35398 46598/46598/35397 +f 46594/46594/35393 46598/46598/35397 46593/46593/35392 +f 46589/46589/35388 46600/46600/35399 46601/46601/35398 +f 46589/46589/35388 46601/46601/35398 46595/46595/35394 +f 46413/46413/35221 46414/46414/35222 46600/46600/35399 +f 46413/46413/35221 46600/46600/35399 46589/46589/35388 +f 46590/46590/35389 46597/46597/35396 46602/46602/35400 +f 46590/46590/35389 46602/46602/35400 46591/46591/35390 +f 46414/46414/35222 46415/46415/35223 46603/46603/35401 +f 46414/46414/35222 46603/46603/35401 46600/46600/35399 +f 46597/46597/35396 46604/46604/35402 46605/46605/35403 +f 46597/46597/35396 46605/46605/35403 46602/46602/35400 +f 46596/46596/35395 46606/46606/35404 46604/46604/35402 +f 46596/46596/35395 46604/46604/35402 46597/46597/35396 +f 46598/46598/35397 46607/46607/35405 46606/46606/35404 +f 46598/46598/35397 46606/46606/35404 46596/46596/35395 +f 46599/46599/35398 46608/46608/35406 46607/46607/35405 +f 46599/46599/35398 46607/46607/35405 46598/46598/35397 +f 46600/46600/35399 46603/46603/35401 46609/46609/35406 +f 46600/46600/35399 46609/46609/35406 46601/46601/35398 +f 46607/46607/35405 46610/46610/35407 46611/46611/35408 +f 46607/46607/35405 46611/46611/35408 46606/46606/35404 +f 46609/46609/35406 46612/46612/35409 46613/46613/35407 +f 46609/46609/35406 46613/46613/35407 46614/46614/35405 +f 46603/46603/35401 46615/46615/35410 46612/46612/35409 +f 46603/46603/35401 46612/46612/35409 46609/46609/35406 +f 46415/46415/35223 46416/46416/35224 46615/46615/35410 +f 46415/46415/35223 46615/46615/35410 46603/46603/35401 +f 46604/46604/35402 46616/46616/35411 46617/46617/35412 +f 46604/46604/35402 46617/46617/35412 46605/46605/35403 +f 46606/46606/35404 46611/46611/35408 46616/46616/35411 +f 46606/46606/35404 46616/46616/35411 46604/46604/35402 +f 46616/46616/35411 46618/46618/35413 46619/46619/35414 +f 46616/46616/35411 46619/46619/35414 46617/46617/35412 +f 46611/46611/35408 46620/46620/35415 46618/46618/35413 +f 46611/46611/35408 46618/46618/35413 46616/46616/35411 +f 46613/46613/35407 46621/46621/35416 46622/46622/35417 +f 46613/46613/35407 46622/46622/35417 46623/46623/35418 +f 46612/46612/35409 46624/46624/35419 46621/46621/35416 +f 46612/46612/35409 46621/46621/35416 46613/46613/35407 +f 46615/46615/35410 46625/46625/35420 46624/46624/35419 +f 46615/46615/35410 46624/46624/35419 46612/46612/35409 +f 46416/46416/35224 46417/46417/35225 46625/46625/35420 +f 46416/46416/35224 46625/46625/35420 46615/46615/35410 +f 46621/46621/35416 46626/46626/35421 46627/46627/35422 +f 46621/46621/35416 46627/46627/35422 46622/46622/35417 +f 46624/46624/35419 46628/46628/35423 46626/46626/35421 +f 46624/46624/35419 46626/46626/35421 46621/46621/35416 +f 46625/46625/35420 46629/46629/35424 46628/46628/35423 +f 46625/46625/35420 46628/46628/35423 46624/46624/35419 +f 46417/46417/35225 46418/46418/35226 46629/46629/35424 +f 46417/46417/35225 46629/46629/35424 46625/46625/35420 +f 46618/46618/35413 46630/46630/35425 46631/46631/35426 +f 46618/46618/35413 46631/46631/35426 46619/46619/35414 +f 46622/46622/35417 46627/46627/35422 46632/46632/35427 +f 46622/46622/35417 46632/46632/35427 46633/46633/35428 +f 46632/46632/35427 46419/46419/35227 46422/46422/35230 +f 46632/46632/35427 46422/46422/35230 46634/46634/35429 +f 46627/46627/35422 46423/46423/35231 46419/46419/35227 +f 46627/46627/35422 46419/46419/35227 46632/46632/35427 +f 46626/46626/35421 46425/46425/35233 46423/46423/35231 +f 46626/46626/35421 46423/46423/35231 46627/46627/35422 +f 46628/46628/35423 46427/46427/35235 46425/46425/35233 +f 46628/46628/35423 46425/46425/35233 46626/46626/35421 +f 46629/46629/35424 46429/46429/35237 46427/46427/35235 +f 46629/46629/35424 46427/46427/35235 46628/46628/35423 +f 46418/46418/35226 46388/46388/35196 46429/46429/35237 +f 46418/46418/35226 46429/46429/35237 46629/46629/35424 +o Sphere.027__0 +v 1.589673 -0.618526 -0.683333 +v 1.589390 -0.626895 -0.681676 +v 1.589423 -0.627062 -0.683326 +v 1.589353 -0.626408 -0.680089 +v 1.589313 -0.625618 -0.678628 +v 1.589272 -0.624556 -0.677347 +v 1.589230 -0.623262 -0.676297 +v 1.589191 -0.621786 -0.675518 +v 1.589155 -0.620185 -0.675039 +v 1.589123 -0.618521 -0.674879 +v 1.589098 -0.616857 -0.675044 +v 1.589080 -0.615258 -0.675529 +v 1.589069 -0.613784 -0.676313 +v 1.589066 -0.612493 -0.677368 +v 1.589071 -0.611434 -0.678651 +v 1.589084 -0.610648 -0.680116 +v 1.589105 -0.610165 -0.681704 +v 1.589132 -0.610003 -0.683355 +v 1.589164 -0.610169 -0.685005 +v 1.589202 -0.610657 -0.686592 +v 1.589242 -0.611447 -0.688053 +v 1.589283 -0.612509 -0.689334 +v 1.589324 -0.613803 -0.690384 +v 1.589364 -0.615279 -0.691163 +v 1.589400 -0.616880 -0.691642 +v 1.589431 -0.618544 -0.691802 +v 1.589456 -0.620208 -0.691637 +v 1.589475 -0.621807 -0.691152 +v 1.589486 -0.623281 -0.690368 +v 1.589489 -0.624572 -0.689314 +v 1.589483 -0.625631 -0.688030 +v 1.589470 -0.626417 -0.686565 +v 1.589450 -0.626900 -0.684977 +v 1.577652 -0.659135 -0.683496 +v 1.577497 -0.658348 -0.675680 +v 1.573667 -0.660853 -0.675264 +v 1.573832 -0.661689 -0.683562 +v 1.581142 -0.655034 -0.683438 +v 1.581003 -0.654326 -0.676404 +v 1.584170 -0.649544 -0.683391 +v 1.584051 -0.648941 -0.677409 +v 1.586617 -0.642874 -0.683356 +v 1.586524 -0.642401 -0.678656 +v 1.588391 -0.635283 -0.683334 +v 1.588327 -0.634957 -0.680096 +v 1.588254 -0.634001 -0.676984 +v 1.577321 -0.656039 -0.668167 +v 1.573481 -0.658402 -0.667289 +v 1.580845 -0.652248 -0.669643 +v 1.583916 -0.647174 -0.671658 +v 1.586418 -0.641013 -0.674137 +v 1.580674 -0.648880 -0.663413 +v 1.577132 -0.652297 -0.661246 +v 1.583771 -0.644310 -0.666361 +v 1.586304 -0.638762 -0.669975 +v 1.588176 -0.632451 -0.674117 +v 1.573279 -0.654430 -0.659941 +v 1.588094 -0.630367 -0.671605 +v 1.576936 -0.647266 -0.655182 +v 1.573071 -0.649088 -0.653504 +v 1.580498 -0.644352 -0.657956 +v 1.583622 -0.640459 -0.661720 +v 1.586187 -0.635737 -0.666329 +v 1.583472 -0.635769 -0.657914 +v 1.580323 -0.638837 -0.653481 +v 1.586069 -0.632052 -0.663339 +v 1.588014 -0.627829 -0.669546 +v 1.576741 -0.641138 -0.650209 +v 1.572865 -0.642583 -0.648224 +v 1.576555 -0.634150 -0.646518 +v 1.572667 -0.635164 -0.644306 +v 1.580155 -0.632548 -0.650159 +v 1.583330 -0.630421 -0.655089 +v 1.585957 -0.627850 -0.661119 +v 1.587936 -0.624934 -0.668017 +v 1.585855 -0.623291 -0.659755 +v 1.583199 -0.624619 -0.653353 +v 1.587866 -0.621794 -0.667077 +v 1.576384 -0.626570 -0.644250 +v 1.572486 -0.627117 -0.641899 +v 1.580001 -0.625726 -0.648118 +v 1.576236 -0.618688 -0.643493 +v 1.572328 -0.618751 -0.641095 +v 1.579868 -0.618633 -0.647437 +v 1.583086 -0.618587 -0.652774 +v 1.585766 -0.618552 -0.659300 +v 1.587804 -0.618530 -0.666764 +v 1.585693 -0.613814 -0.659771 +v 1.582994 -0.612557 -0.653373 +v 1.587754 -0.615266 -0.667088 +v 1.576115 -0.610809 -0.644276 +v 1.572200 -0.610386 -0.641927 +v 1.579759 -0.611542 -0.648142 +v 1.576027 -0.603235 -0.646569 +v 1.572107 -0.602346 -0.644361 +v 1.579680 -0.604726 -0.650205 +v 1.582926 -0.606760 -0.655128 +v 1.585640 -0.609259 -0.661150 +v 1.587718 -0.612129 -0.668038 +v 1.587697 -0.609239 -0.669577 +v 1.585609 -0.605063 -0.663384 +v 1.575975 -0.596257 -0.650284 +v 1.572052 -0.594938 -0.648304 +v 1.579633 -0.598445 -0.653548 +v 1.582886 -0.601419 -0.657972 +v 1.575962 -0.590143 -0.655278 +v 1.572037 -0.588447 -0.653605 +v 1.579621 -0.592943 -0.658043 +v 1.582876 -0.596739 -0.661793 +v 1.585601 -0.601386 -0.666386 +v 1.587691 -0.606706 -0.671645 +v 1.587701 -0.604629 -0.674164 +v 1.585616 -0.598371 -0.670043 +v 1.575986 -0.585128 -0.661358 +v 1.572063 -0.583123 -0.660060 +v 1.579643 -0.588429 -0.663515 +v 1.582895 -0.592901 -0.666447 +v 1.579699 -0.585079 -0.669755 +v 1.576048 -0.581405 -0.668292 +v 1.582942 -0.590051 -0.671754 +v 1.585653 -0.596132 -0.674213 +v 1.587727 -0.603086 -0.677036 +v 1.572129 -0.579171 -0.667421 +v 1.587767 -0.602139 -0.680151 +v 1.576146 -0.579117 -0.675813 +v 1.572232 -0.576742 -0.675405 +v 1.579787 -0.583019 -0.676524 +v 1.583017 -0.588300 -0.677510 +v 1.585711 -0.594756 -0.678735 +v 1.583115 -0.587714 -0.683494 +v 1.579902 -0.582331 -0.683560 +v 1.585789 -0.594296 -0.683437 +v 1.587820 -0.601822 -0.683390 +v 1.576274 -0.578351 -0.683631 +v 1.572369 -0.575929 -0.683705 +v 1.576274 -0.578351 -0.683631 +v 1.576429 -0.579138 -0.691448 +v 1.572534 -0.576764 -0.692003 +v 1.572369 -0.575929 -0.683705 +v 1.580042 -0.583038 -0.690594 +v 1.576429 -0.579138 -0.691448 +v 1.583234 -0.588316 -0.689476 +v 1.585882 -0.594769 -0.688137 +v 1.587885 -0.602148 -0.686627 +v 1.583368 -0.590083 -0.695227 +v 1.580200 -0.585116 -0.697356 +v 1.585988 -0.596157 -0.692655 +v 1.587957 -0.603104 -0.689739 +v 1.576605 -0.581447 -0.698960 +v 1.572721 -0.579215 -0.699979 +v 1.580042 -0.583038 -0.690594 +v 1.580200 -0.585116 -0.697356 +v 1.576795 -0.585189 -0.705882 +v 1.572922 -0.583188 -0.707327 +v 1.580371 -0.588484 -0.703585 +v 1.583368 -0.590083 -0.695227 +v 1.583513 -0.592947 -0.700524 +v 1.586102 -0.598407 -0.696817 +v 1.583513 -0.592947 -0.700524 +v 1.588036 -0.604654 -0.692606 +v 1.586102 -0.598407 -0.696817 +v 1.586220 -0.601433 -0.700464 +v 1.583663 -0.596798 -0.705165 +v 1.588117 -0.606738 -0.695118 +v 1.586220 -0.601433 -0.700464 +v 1.576991 -0.590220 -0.711946 +v 1.573130 -0.588529 -0.713764 +v 1.580547 -0.593013 -0.709042 +v 1.577185 -0.596348 -0.716919 +v 1.573336 -0.595034 -0.719043 +v 1.580723 -0.598527 -0.713518 +v 1.583812 -0.601488 -0.708971 +v 1.586337 -0.605118 -0.703454 +v 1.588198 -0.609276 -0.697178 +v 1.586337 -0.605118 -0.703454 +v 1.586449 -0.609320 -0.705674 +v 1.583955 -0.606837 -0.711796 +v 1.588275 -0.612171 -0.698707 +v 1.586449 -0.609320 -0.705674 +v 1.577372 -0.603336 -0.720610 +v 1.573534 -0.602453 -0.722962 +v 1.580890 -0.604816 -0.716840 +v 1.577542 -0.610917 -0.722878 +v 1.573715 -0.610500 -0.725369 +v 1.581044 -0.611639 -0.718881 +v 1.584086 -0.612639 -0.713532 +v 1.586551 -0.613879 -0.707037 +v 1.588346 -0.615311 -0.699646 +v 1.586551 -0.613879 -0.707037 +v 1.588407 -0.618575 -0.699959 +v 1.586641 -0.618618 -0.707492 +v 1.577691 -0.618798 -0.723634 +v 1.573873 -0.618867 -0.726172 +v 1.581177 -0.618731 -0.719562 +v 1.584199 -0.618671 -0.714111 +v 1.586641 -0.618618 -0.707492 +v 1.581286 -0.625822 -0.718857 +v 1.577811 -0.626677 -0.722851 +v 1.584291 -0.624701 -0.713512 +v 1.586713 -0.623356 -0.707021 +v 1.588457 -0.621839 -0.699635 +v 1.586713 -0.623356 -0.707021 +v 1.574001 -0.627231 -0.725341 +v 1.588493 -0.624976 -0.698685 +v 1.577899 -0.634251 -0.720558 +v 1.574094 -0.635272 -0.722907 +v 1.581365 -0.632639 -0.716793 +v 1.584359 -0.630498 -0.711757 +v 1.586766 -0.627910 -0.705643 +v 1.586766 -0.627910 -0.705643 +v 1.581411 -0.638919 -0.713451 +v 1.577951 -0.641229 -0.716843 +v 1.584399 -0.635839 -0.708914 +v 1.586797 -0.632107 -0.703409 +v 1.588515 -0.627867 -0.697147 +v 1.586797 -0.632107 -0.703409 +v 1.574149 -0.642680 -0.718963 +v 1.588521 -0.630399 -0.695078 +v 1.577965 -0.647343 -0.711850 +v 1.574164 -0.649170 -0.713662 +v 1.581424 -0.644422 -0.708956 +v 1.584409 -0.640518 -0.705092 +v 1.586805 -0.635783 -0.700406 +v 1.586805 -0.635783 -0.700406 +v 1.584390 -0.644356 -0.700438 +v 1.581402 -0.648935 -0.703484 +v 1.586791 -0.638799 -0.696750 +v 1.584390 -0.644356 -0.700438 +v 1.584409 -0.640518 -0.705092 +v 1.588510 -0.632476 -0.692560 +v 1.577940 -0.652358 -0.705769 +v 1.574138 -0.654494 -0.707207 +v 1.577878 -0.656081 -0.698835 +v 1.574072 -0.658447 -0.699846 +v 1.581346 -0.652286 -0.697244 +v 1.584343 -0.647206 -0.695131 +v 1.581346 -0.652286 -0.697244 +v 1.581402 -0.648935 -0.703484 +v 1.586753 -0.641038 -0.692580 +v 1.588485 -0.634018 -0.689688 +v 1.584268 -0.648957 -0.689375 +v 1.581258 -0.654345 -0.690475 +v 1.586695 -0.642414 -0.688058 +v 1.588444 -0.634966 -0.686572 +v 1.577781 -0.658370 -0.691315 +v 1.573968 -0.660876 -0.691862 +v 1.577781 -0.658370 -0.691315 +v 1.577878 -0.656081 -0.698835 +v 1.573968 -0.660876 -0.691862 +vt 0.670730 0.777137 +vt 0.670789 0.776509 +vt 0.670669 0.776509 +vt 0.670907 0.776533 +vt 0.671018 0.776580 +vt 0.671119 0.776649 +vt 0.671205 0.776736 +vt 0.671272 0.776839 +vt 0.671320 0.776953 +vt 0.671344 0.777074 +vt 0.671346 0.777198 +vt 0.671323 0.777319 +vt 0.671279 0.777433 +vt 0.671213 0.777536 +vt 0.671129 0.777623 +vt 0.671030 0.777692 +vt 0.670920 0.777739 +vt 0.670802 0.777763 +vt 0.670682 0.777763 +vt 0.670564 0.777739 +vt 0.670453 0.777692 +vt 0.670352 0.777623 +vt 0.670267 0.777536 +vt 0.670199 0.777433 +vt 0.670152 0.777319 +vt 0.670127 0.777198 +vt 0.670126 0.777074 +vt 0.670148 0.776953 +vt 0.670193 0.776839 +vt 0.670258 0.776736 +vt 0.670342 0.776649 +vt 0.670441 0.776580 +vt 0.670552 0.776533 +vt 0.670611 0.774127 +vt 0.671179 0.774127 +vt 0.671255 0.773932 +vt 0.670651 0.773932 +vt 0.670587 0.774436 +vt 0.671099 0.774436 +vt 0.670582 0.774845 +vt 0.671017 0.774845 +vt 0.670594 0.775341 +vt 0.670935 0.775341 +vt 0.670623 0.775902 +vt 0.670859 0.775902 +vt 0.671090 0.775950 +vt 0.671738 0.774242 +vt 0.671848 0.774053 +vt 0.671602 0.774538 +vt 0.671444 0.774933 +vt 0.671271 0.775409 +vt 0.672076 0.774740 +vt 0.672265 0.774465 +vt 0.671848 0.775104 +vt 0.671588 0.775544 +vt 0.671308 0.776042 +vt 0.672408 0.774291 +vt 0.671506 0.776177 +vt 0.672741 0.774790 +vt 0.672913 0.774636 +vt 0.672505 0.775032 +vt 0.672212 0.775353 +vt 0.671875 0.775739 +vt 0.672523 0.775669 +vt 0.672870 0.775405 +vt 0.672119 0.775988 +vt 0.671674 0.776348 +vt 0.673147 0.775204 +vt 0.673344 0.775075 +vt 0.673468 0.775691 +vt 0.673684 0.775592 +vt 0.673159 0.775843 +vt 0.672768 0.776042 +vt 0.672312 0.776281 +vt 0.671807 0.776550 +vt 0.672446 0.776606 +vt 0.672939 0.776455 +vt 0.671899 0.776774 +vt 0.673691 0.776231 +vt 0.673921 0.776166 +vt 0.673360 0.776329 +vt 0.673808 0.776805 +vt 0.674045 0.776775 +vt 0.673465 0.776845 +vt 0.673029 0.776895 +vt 0.672516 0.776951 +vt 0.671948 0.777011 +vt 0.672520 0.777302 +vt 0.673033 0.777342 +vt 0.671950 0.777254 +vt 0.673814 0.777390 +vt 0.674052 0.777396 +vt 0.673470 0.777372 +vt 0.673709 0.777964 +vt 0.673941 0.778005 +vt 0.673376 0.777888 +vt 0.672953 0.777781 +vt 0.672457 0.777647 +vt 0.671907 0.777491 +vt 0.671819 0.777715 +vt 0.672329 0.777973 +vt 0.673497 0.778504 +vt 0.673716 0.778579 +vt 0.673185 0.778375 +vt 0.672791 0.778195 +vt 0.673187 0.778991 +vt 0.673386 0.779095 +vt 0.672906 0.778813 +vt 0.672553 0.778567 +vt 0.672143 0.778265 +vt 0.671690 0.777917 +vt 0.671526 0.778088 +vt 0.671904 0.778514 +vt 0.672789 0.779404 +vt 0.672964 0.779534 +vt 0.672548 0.779185 +vt 0.672249 0.778884 +vt 0.672126 0.779477 +vt 0.672320 0.779729 +vt 0.671890 0.779133 +vt 0.671622 0.778709 +vt 0.671331 0.778223 +vt 0.672466 0.779879 +vt 0.671115 0.778315 +vt 0.671798 0.779953 +vt 0.671911 0.780117 +vt 0.671655 0.779679 +vt 0.671490 0.779304 +vt 0.671307 0.778844 +vt 0.671064 0.779392 +vt 0.671155 0.779782 +vt 0.670973 0.778912 +vt 0.670884 0.778363 +vt 0.671241 0.780067 +vt 0.671321 0.780238 +vt 0.944189 0.541543 +vt 0.943769 0.541430 +vt 0.943537 0.541606 +vt 0.943983 0.541726 +vt 0.670643 0.779782 +vt 0.670673 0.780067 +vt 0.670629 0.779392 +vt 0.670631 0.778912 +vt 0.670649 0.778363 +vt 0.670202 0.779304 +vt 0.670141 0.779679 +vt 0.670295 0.778844 +vt 0.670418 0.778315 +vt 0.943373 0.541206 +vt 0.943116 0.541369 +vt 0.944010 0.541143 +vt 0.943654 0.540943 +vt 0.943017 0.540882 +vt 0.942738 0.541024 +vt 0.943333 0.540650 +vt 0.943948 0.540588 +vt 0.943676 0.540339 +vt 0.669978 0.778709 +vt 0.669798 0.779133 +vt 0.670199 0.778223 +vt 0.944031 0.539960 +vt 0.943849 0.539711 +vt 0.943444 0.540023 +vt 0.670002 0.778088 +vt 0.669692 0.778514 +vt 0.942714 0.540468 +vt 0.942416 0.540585 +vt 0.943060 0.540278 +vt 0.942475 0.539982 +vt 0.942164 0.540069 +vt 0.942846 0.539841 +vt 0.943262 0.539650 +vt 0.943706 0.539419 +vt 0.669834 0.777917 +vt 0.669448 0.778265 +vt 0.943607 0.539094 +vt 0.943136 0.539237 +vt 0.669701 0.777715 +vt 0.669255 0.777973 +vt 0.942312 0.539441 +vt 0.941990 0.539495 +vt 0.942699 0.539354 +vt 0.942228 0.538867 +vt 0.941901 0.538885 +vt 0.942623 0.538837 +vt 0.943072 0.538797 +vt 0.943557 0.538749 +vt 0.669608 0.777491 +vt 0.669120 0.777647 +vt 0.669560 0.777254 +vt 0.669050 0.777302 +vt 0.942228 0.538281 +vt 0.941901 0.538264 +vt 0.942623 0.538310 +vt 0.943072 0.538349 +vt 0.943557 0.538396 +vt 0.942699 0.537793 +vt 0.942312 0.537707 +vt 0.943136 0.537909 +vt 0.943607 0.538051 +vt 0.669558 0.777011 +vt 0.669047 0.776951 +vt 0.941990 0.537654 +vt 0.669601 0.776774 +vt 0.942475 0.537166 +vt 0.942164 0.537079 +vt 0.942846 0.537306 +vt 0.943262 0.537495 +vt 0.943706 0.537725 +vt 0.669110 0.776606 +vt 0.943060 0.536867 +vt 0.942714 0.536678 +vt 0.943444 0.537122 +vt 0.943849 0.537432 +vt 0.669689 0.776550 +vt 0.669237 0.776281 +vt 0.942416 0.536562 +vt 0.669817 0.776348 +vt 0.943017 0.536264 +vt 0.942738 0.536122 +vt 0.943333 0.536494 +vt 0.943676 0.536805 +vt 0.944031 0.537183 +vt 0.669424 0.775988 +vt 0.943948 0.536555 +vt 0.943654 0.536201 +vt 0.669663 0.775739 +vt 0.669397 0.775353 +vt 0.669093 0.775669 +vt 0.669982 0.776177 +vt 0.943373 0.535938 +vt 0.943116 0.535775 +vt 0.943769 0.535713 +vt 0.943537 0.535537 +vt 0.944010 0.535998 +vt 0.669756 0.775104 +vt 0.669617 0.774740 +vt 0.669194 0.775032 +vt 0.669945 0.775544 +vt 0.670176 0.776042 +vt 0.670156 0.774933 +vt 0.670087 0.774538 +vt 0.670259 0.775409 +vt 0.670393 0.775950 +vt 0.944189 0.535598 +vt 0.943983 0.535414 +vt 0.670055 0.774242 +vt 0.669532 0.774465 +vt 0.670061 0.774053 +vn 0.9997 0.0171 0.0181 +vn 0.9963 -0.0780 0.0373 +vn 0.9966 -0.0800 0.0182 +vn 0.9958 -0.0725 0.0556 +vn 0.9953 -0.0635 0.0725 +vn 0.9949 -0.0515 0.0872 +vn 0.9944 -0.0367 0.0994 +vn 0.9939 -0.0200 0.1083 +vn 0.9935 -0.0017 0.1139 +vn 0.9931 0.0171 0.1157 +vn 0.9929 0.0360 0.1138 +vn 0.9926 0.0543 0.1082 +vn 0.9925 0.0709 0.0992 +vn 0.9925 0.0856 0.0870 +vn 0.9926 0.0977 0.0722 +vn 0.9928 0.1066 0.0554 +vn 0.9930 0.1121 0.0369 +vn 0.9933 0.1139 0.0179 +vn 0.9937 0.1121 -0.0012 +vn 0.9941 0.1065 -0.0195 +vn 0.9946 0.0975 -0.0364 +vn 0.9950 0.0854 -0.0512 +vn 0.9955 0.0707 -0.0633 +vn 0.9959 0.0539 -0.0723 +vn 0.9963 0.0357 -0.0778 +vn 0.9967 0.0168 -0.0796 +vn 0.9970 -0.0020 -0.0777 +vn 0.9972 -0.0202 -0.0721 +vn 0.9973 -0.0369 -0.0631 +vn 0.9974 -0.0516 -0.0509 +vn 0.9973 -0.0637 -0.0361 +vn 0.9972 -0.0726 -0.0192 +vn 0.9969 -0.0781 -0.0009 +vn 0.6606 -0.7506 0.0130 +vn 0.6575 -0.7357 0.1627 +vn 0.5522 -0.8149 0.1764 +vn 0.5556 -0.8314 0.0112 +vn 0.8197 -0.5726 0.0157 +vn 0.8173 -0.5611 0.1310 +vn 0.9079 -0.4188 0.0171 +vn 0.9062 -0.4103 0.1024 +vn 0.9568 -0.2901 0.0178 +vn 0.9556 -0.2841 0.0780 +vn 0.9836 -0.1795 0.0181 +vn 0.9828 -0.1756 0.0567 +vn 0.9819 -0.1644 0.0938 +vn 0.6539 -0.6918 0.3065 +vn 0.5481 -0.7664 0.3349 +vn 0.8145 -0.5274 0.2417 +vn 0.9041 -0.3855 0.1845 +vn 0.9542 -0.2666 0.1359 +vn 0.8114 -0.4729 0.3436 +vn 0.6498 -0.6207 0.4387 +vn 0.9018 -0.3451 0.2600 +vn 0.9526 -0.2381 0.1892 +vn 0.9810 -0.1462 0.1279 +vn 0.5437 -0.6880 0.4807 +vn 0.9799 -0.1217 0.1578 +vn 0.6455 -0.5255 0.5541 +vn 0.5390 -0.5829 0.6080 +vn 0.8081 -0.3997 0.4327 +vn 0.8995 -0.2910 0.3261 +vn 0.9510 -0.2000 0.2359 +vn 0.8971 -0.2251 0.3802 +vn 0.8049 -0.3106 0.5057 +vn 0.9494 -0.1535 0.2741 +vn 0.9789 -0.0920 0.1823 +vn 0.6413 -0.4099 0.6486 +vn 0.5343 -0.4552 0.7122 +vn 0.6374 -0.2783 0.7186 +vn 0.5300 -0.3100 0.7893 +vn 0.8018 -0.2093 0.5598 +vn 0.8949 -0.1500 0.4204 +vn 0.9478 -0.1005 0.3025 +vn 0.9780 -0.0580 0.2005 +vn 0.9465 -0.0431 0.3199 +vn 0.8929 -0.0686 0.4450 +vn 0.9771 -0.0212 0.2117 +vn 0.6338 -0.1359 0.7614 +vn 0.5261 -0.1529 0.8366 +vn 0.7991 -0.0995 0.5929 +vn 0.6310 0.0121 0.7757 +vn 0.5229 0.0103 0.8523 +vn 0.7968 0.0146 0.6040 +vn 0.8912 0.0159 0.4532 +vn 0.9453 0.0167 0.3257 +vn 0.9764 0.0170 0.2154 +vn 0.9444 0.0764 0.3197 +vn 0.8900 0.1005 0.4447 +vn 0.9758 0.0553 0.2116 +vn 0.6288 0.1600 0.7609 +vn 0.5206 0.1735 0.8360 +vn 0.7952 0.1287 0.5926 +vn 0.6275 0.3023 0.7176 +vn 0.5190 0.3306 0.7882 +vn 0.7942 0.2384 0.5590 +vn 0.8892 0.1818 0.4198 +vn 0.9438 0.1338 0.3021 +vn 0.9754 0.0920 0.2003 +vn 0.9752 0.1259 0.1820 +vn 0.9436 0.1866 0.2736 +vn 0.6270 0.4337 0.6472 +vn 0.5185 0.4756 0.7106 +vn 0.7938 0.3396 0.5046 +vn 0.8889 0.2568 0.3794 +vn 0.6272 0.5491 0.5523 +vn 0.5188 0.6030 0.6060 +vn 0.7940 0.4284 0.4313 +vn 0.8890 0.3226 0.3251 +vn 0.9436 0.2331 0.2352 +vn 0.9752 0.1556 0.1573 +vn 0.9754 0.1800 0.1273 +vn 0.9439 0.2711 0.1883 +vn 0.6282 0.6440 0.4365 +vn 0.5199 0.7077 0.4783 +vn 0.7948 0.5014 0.3420 +vn 0.8895 0.3766 0.2588 +vn 0.7960 0.5557 0.2399 +vn 0.6299 0.7147 0.3041 +vn 0.8904 0.4167 0.1831 +vn 0.9445 0.2994 0.1349 +vn 0.9757 0.1981 0.0932 +vn 0.5217 0.7857 0.3323 +vn 0.9763 0.2092 0.0560 +vn 0.6321 0.7582 0.1602 +vn 0.5241 0.8338 0.1736 +vn 0.7977 0.5891 0.1290 +vn 0.8916 0.4414 0.1010 +vn 0.9454 0.3168 0.0770 +vn 0.8931 0.4496 0.0156 +vn 0.7997 0.6003 0.0137 +vn 0.9464 0.3226 0.0167 +vn 0.9769 0.2129 0.0175 +vn 0.6346 0.7727 0.0104 +vn 0.5270 0.8498 0.0084 +vn 0.6347 0.7727 0.0105 +vn 0.6375 0.7578 -0.1392 +vn 0.5301 0.8333 -0.1567 +vn 0.8019 0.5888 -0.1016 +vn 0.8947 0.4411 -0.0698 +vn 0.9475 0.3167 -0.0435 +vn 0.9777 0.2091 -0.0211 +vn 0.8965 0.4162 -0.1518 +vn 0.8042 0.5551 -0.2123 +vn 0.9488 0.2991 -0.1014 +vn 0.9785 0.1979 -0.0582 +vn 0.6406 0.7138 -0.2830 +vn 0.5335 0.7848 -0.3153 +vn 0.6437 0.6429 -0.4152 +vn 0.5370 0.7064 -0.4611 +vn 0.8067 0.5005 -0.3142 +vn 0.8984 0.3759 -0.2273 +vn 0.9502 0.2706 -0.1547 +vn 0.8983 0.3759 -0.2273 +vn 0.9794 0.1796 -0.0924 +vn 0.9515 0.2324 -0.2014 +vn 0.9002 0.3217 -0.2934 +vn 0.9803 0.1552 -0.1223 +vn 0.9516 0.2324 -0.2013 +vn 0.6469 0.5476 -0.5307 +vn 0.5405 0.6013 -0.5885 +vn 0.8091 0.4273 -0.4034 +vn 0.6500 0.4319 -0.6252 +vn 0.5440 0.4737 -0.6926 +vn 0.8116 0.3383 -0.4764 +vn 0.9021 0.2558 -0.3476 +vn 0.9529 0.1860 -0.2396 +vn 0.9812 0.1255 -0.1468 +vn 0.9542 0.1330 -0.2680 +vn 0.9039 0.1807 -0.3877 +vn 0.9820 0.0915 -0.1650 +vn 0.6531 0.3003 -0.6951 +vn 0.5474 0.3284 -0.7697 +vn 0.8139 0.2369 -0.5305 +vn 0.6560 0.1579 -0.7380 +vn 0.5505 0.1713 -0.8170 +vn 0.8162 0.1271 -0.5636 +vn 0.9056 0.0994 -0.4124 +vn 0.9554 0.0756 -0.2854 +vn 0.9828 0.0547 -0.1761 +vn 0.9554 0.0755 -0.2854 +vn 0.9836 0.0165 -0.1799 +vn 0.9565 0.0158 -0.2912 +vn 0.6587 0.0100 -0.7523 +vn 0.5535 0.0080 -0.8328 +vn 0.8182 0.0130 -0.5747 +vn 0.9071 0.0148 -0.4206 +vn 0.8201 -0.1011 -0.5633 +vn 0.6611 -0.1379 -0.7376 +vn 0.9085 -0.0698 -0.4121 +vn 0.9575 -0.0439 -0.2852 +vn 0.9841 -0.0218 -0.1760 +vn 0.5561 -0.1551 -0.8165 +vn 0.9846 -0.0585 -0.1647 +vn 0.6630 -0.2803 -0.6942 +vn 0.5583 -0.3122 -0.7687 +vn 0.8216 -0.2108 -0.5297 +vn 0.9095 -0.1511 -0.3872 +vn 0.9582 -0.1013 -0.2676 +vn 0.8226 -0.3120 -0.4753 +vn 0.6644 -0.4116 -0.6238 +vn 0.9103 -0.2261 -0.3468 +vn 0.9587 -0.1542 -0.2390 +vn 0.9849 -0.0924 -0.1464 +vn 0.5598 -0.4572 -0.6911 +vn 0.9850 -0.1221 -0.1218 +vn 0.6652 -0.5270 -0.5289 +vn 0.5606 -0.5845 -0.5865 +vn 0.8233 -0.4008 -0.4020 +vn 0.9107 -0.2918 -0.2924 +vn 0.9589 -0.2005 -0.2006 +vn 0.9107 -0.3458 -0.2261 +vn 0.8233 -0.4738 -0.3126 +vn 0.9588 -0.2386 -0.1539 +vn 0.9849 -0.1465 -0.0918 +vn 0.6653 -0.6219 -0.4131 +vn 0.5607 -0.6893 -0.4588 +vn 0.6645 -0.6926 -0.2807 +vn 0.5599 -0.7673 -0.3127 +vn 0.8227 -0.5280 -0.2105 +vn 0.9102 -0.3859 -0.1505 +vn 0.9585 -0.2669 -0.1004 +vn 0.9847 -0.1646 -0.0576 +vn 0.9093 -0.4106 -0.0683 +vn 0.8215 -0.5614 -0.0997 +vn 0.9578 -0.2843 -0.0425 +vn 0.9842 -0.1757 -0.0205 +vn 0.6629 -0.7361 -0.1367 +vn 0.5581 -0.8153 -0.1540 +vn 0.6630 -0.7360 -0.1367 +vn 0.6646 -0.6925 -0.2806 +vn 0.5582 -0.8153 -0.1540 +usemtl Scene_-_Root +s 1 +f 46635/46635/35430 46636/46636/35431 46637/46637/35432 +f 46635/46635/35430 46638/46638/35433 46636/46636/35431 +f 46635/46635/35430 46639/46639/35434 46638/46638/35433 +f 46635/46635/35430 46640/46640/35435 46639/46639/35434 +f 46635/46635/35430 46641/46641/35436 46640/46640/35435 +f 46635/46635/35430 46642/46642/35437 46641/46641/35436 +f 46635/46635/35430 46643/46643/35438 46642/46642/35437 +f 46635/46635/35430 46644/46644/35439 46643/46643/35438 +f 46635/46635/35430 46645/46645/35440 46644/46644/35439 +f 46635/46635/35430 46646/46646/35441 46645/46645/35440 +f 46635/46635/35430 46647/46647/35442 46646/46646/35441 +f 46635/46635/35430 46648/46648/35443 46647/46647/35442 +f 46635/46635/35430 46649/46649/35444 46648/46648/35443 +f 46635/46635/35430 46650/46650/35445 46649/46649/35444 +f 46635/46635/35430 46651/46651/35446 46650/46650/35445 +f 46635/46635/35430 46652/46652/35447 46651/46651/35446 +f 46635/46635/35430 46653/46653/35448 46652/46652/35447 +f 46635/46635/35430 46654/46654/35449 46653/46653/35448 +f 46635/46635/35430 46655/46655/35450 46654/46654/35449 +f 46635/46635/35430 46656/46656/35451 46655/46655/35450 +f 46635/46635/35430 46657/46657/35452 46656/46656/35451 +f 46635/46635/35430 46658/46658/35453 46657/46657/35452 +f 46635/46635/35430 46659/46659/35454 46658/46658/35453 +f 46635/46635/35430 46660/46660/35455 46659/46659/35454 +f 46635/46635/35430 46661/46661/35456 46660/46660/35455 +f 46635/46635/35430 46662/46662/35457 46661/46661/35456 +f 46635/46635/35430 46663/46663/35458 46662/46662/35457 +f 46635/46635/35430 46664/46664/35459 46663/46663/35458 +f 46635/46635/35430 46665/46665/35460 46664/46664/35459 +f 46635/46635/35430 46666/46666/35461 46665/46665/35460 +f 46635/46635/35430 46667/46667/35462 46666/46666/35461 +f 46635/46635/35430 46637/46637/35432 46667/46667/35462 +f 46668/46668/35463 46669/46669/35464 46670/46670/35465 +f 46668/46668/35463 46670/46670/35465 46671/46671/35466 +f 46672/46672/35467 46673/46673/35468 46669/46669/35464 +f 46672/46672/35467 46669/46669/35464 46668/46668/35463 +f 46674/46674/35469 46675/46675/35470 46673/46673/35468 +f 46674/46674/35469 46673/46673/35468 46672/46672/35467 +f 46676/46676/35471 46677/46677/35472 46675/46675/35470 +f 46676/46676/35471 46675/46675/35470 46674/46674/35469 +f 46678/46678/35473 46679/46679/35474 46677/46677/35472 +f 46678/46678/35473 46677/46677/35472 46676/46676/35471 +f 46637/46637/35432 46636/46636/35431 46679/46679/35474 +f 46637/46637/35432 46679/46679/35474 46678/46678/35473 +f 46636/46636/35431 46638/46638/35433 46680/46680/35475 +f 46636/46636/35431 46680/46680/35475 46679/46679/35474 +f 46669/46669/35464 46681/46681/35476 46682/46682/35477 +f 46669/46669/35464 46682/46682/35477 46670/46670/35465 +f 46673/46673/35468 46683/46683/35478 46681/46681/35476 +f 46673/46673/35468 46681/46681/35476 46669/46669/35464 +f 46675/46675/35470 46684/46684/35479 46683/46683/35478 +f 46675/46675/35470 46683/46683/35478 46673/46673/35468 +f 46677/46677/35472 46685/46685/35480 46684/46684/35479 +f 46677/46677/35472 46684/46684/35479 46675/46675/35470 +f 46679/46679/35474 46680/46680/35475 46685/46685/35480 +f 46679/46679/35474 46685/46685/35480 46677/46677/35472 +f 46683/46683/35478 46686/46686/35481 46687/46687/35482 +f 46683/46683/35478 46687/46687/35482 46681/46681/35476 +f 46684/46684/35479 46688/46688/35483 46686/46686/35481 +f 46684/46684/35479 46686/46686/35481 46683/46683/35478 +f 46685/46685/35480 46689/46689/35484 46688/46688/35483 +f 46685/46685/35480 46688/46688/35483 46684/46684/35479 +f 46680/46680/35475 46690/46690/35485 46689/46689/35484 +f 46680/46680/35475 46689/46689/35484 46685/46685/35480 +f 46638/46638/35433 46639/46639/35434 46690/46690/35485 +f 46638/46638/35433 46690/46690/35485 46680/46680/35475 +f 46681/46681/35476 46687/46687/35482 46691/46691/35486 +f 46681/46681/35476 46691/46691/35486 46682/46682/35477 +f 46639/46639/35434 46640/46640/35435 46692/46692/35487 +f 46639/46639/35434 46692/46692/35487 46690/46690/35485 +f 46687/46687/35482 46693/46693/35488 46694/46694/35489 +f 46687/46687/35482 46694/46694/35489 46691/46691/35486 +f 46686/46686/35481 46695/46695/35490 46693/46693/35488 +f 46686/46686/35481 46693/46693/35488 46687/46687/35482 +f 46688/46688/35483 46696/46696/35491 46695/46695/35490 +f 46688/46688/35483 46695/46695/35490 46686/46686/35481 +f 46689/46689/35484 46697/46697/35492 46696/46696/35491 +f 46689/46689/35484 46696/46696/35491 46688/46688/35483 +f 46690/46690/35485 46692/46692/35487 46697/46697/35492 +f 46690/46690/35485 46697/46697/35492 46689/46689/35484 +f 46696/46696/35491 46698/46698/35493 46699/46699/35494 +f 46696/46696/35491 46699/46699/35494 46695/46695/35490 +f 46697/46697/35492 46700/46700/35495 46698/46698/35493 +f 46697/46697/35492 46698/46698/35493 46696/46696/35491 +f 46692/46692/35487 46701/46701/35496 46700/46700/35495 +f 46692/46692/35487 46700/46700/35495 46697/46697/35492 +f 46640/46640/35435 46641/46641/35436 46701/46701/35496 +f 46640/46640/35435 46701/46701/35496 46692/46692/35487 +f 46693/46693/35488 46702/46702/35497 46703/46703/35498 +f 46693/46693/35488 46703/46703/35498 46694/46694/35489 +f 46695/46695/35490 46699/46699/35494 46702/46702/35497 +f 46695/46695/35490 46702/46702/35497 46693/46693/35488 +f 46702/46702/35497 46704/46704/35499 46705/46705/35500 +f 46702/46702/35497 46705/46705/35500 46703/46703/35498 +f 46699/46699/35494 46706/46706/35501 46704/46704/35499 +f 46699/46699/35494 46704/46704/35499 46702/46702/35497 +f 46698/46698/35493 46707/46707/35502 46706/46706/35501 +f 46698/46698/35493 46706/46706/35501 46699/46699/35494 +f 46700/46700/35495 46708/46708/35503 46707/46707/35502 +f 46700/46700/35495 46707/46707/35502 46698/46698/35493 +f 46701/46701/35496 46709/46709/35504 46708/46708/35503 +f 46701/46701/35496 46708/46708/35503 46700/46700/35495 +f 46641/46641/35436 46642/46642/35437 46709/46709/35504 +f 46641/46641/35436 46709/46709/35504 46701/46701/35496 +f 46708/46708/35503 46710/46710/35505 46711/46711/35506 +f 46708/46708/35503 46711/46711/35506 46707/46707/35502 +f 46709/46709/35504 46712/46712/35507 46710/46710/35505 +f 46709/46709/35504 46710/46710/35505 46708/46708/35503 +f 46642/46642/35437 46643/46643/35438 46712/46712/35507 +f 46642/46642/35437 46712/46712/35507 46709/46709/35504 +f 46704/46704/35499 46713/46713/35508 46714/46714/35509 +f 46704/46704/35499 46714/46714/35509 46705/46705/35500 +f 46706/46706/35501 46715/46715/35510 46713/46713/35508 +f 46706/46706/35501 46713/46713/35508 46704/46704/35499 +f 46707/46707/35502 46711/46711/35506 46715/46715/35510 +f 46707/46707/35502 46715/46715/35510 46706/46706/35501 +f 46713/46713/35508 46716/46716/35511 46717/46717/35512 +f 46713/46713/35508 46717/46717/35512 46714/46714/35509 +f 46715/46715/35510 46718/46718/35513 46716/46716/35511 +f 46715/46715/35510 46716/46716/35511 46713/46713/35508 +f 46711/46711/35506 46719/46719/35514 46718/46718/35513 +f 46711/46711/35506 46718/46718/35513 46715/46715/35510 +f 46710/46710/35505 46720/46720/35515 46719/46719/35514 +f 46710/46710/35505 46719/46719/35514 46711/46711/35506 +f 46712/46712/35507 46721/46721/35516 46720/46720/35515 +f 46712/46712/35507 46720/46720/35515 46710/46710/35505 +f 46643/46643/35438 46644/46644/35439 46721/46721/35516 +f 46643/46643/35438 46721/46721/35516 46712/46712/35507 +f 46720/46720/35515 46722/46722/35517 46723/46723/35518 +f 46720/46720/35515 46723/46723/35518 46719/46719/35514 +f 46721/46721/35516 46724/46724/35519 46722/46722/35517 +f 46721/46721/35516 46722/46722/35517 46720/46720/35515 +f 46644/46644/35439 46645/46645/35440 46724/46724/35519 +f 46644/46644/35439 46724/46724/35519 46721/46721/35516 +f 46716/46716/35511 46725/46725/35520 46726/46726/35521 +f 46716/46716/35511 46726/46726/35521 46717/46717/35512 +f 46718/46718/35513 46727/46727/35522 46725/46725/35520 +f 46718/46718/35513 46725/46725/35520 46716/46716/35511 +f 46719/46719/35514 46723/46723/35518 46727/46727/35522 +f 46719/46719/35514 46727/46727/35522 46718/46718/35513 +f 46725/46725/35520 46728/46728/35523 46729/46729/35524 +f 46725/46725/35520 46729/46729/35524 46726/46726/35521 +f 46727/46727/35522 46730/46730/35525 46728/46728/35523 +f 46727/46727/35522 46728/46728/35523 46725/46725/35520 +f 46723/46723/35518 46731/46731/35526 46730/46730/35525 +f 46723/46723/35518 46730/46730/35525 46727/46727/35522 +f 46722/46722/35517 46732/46732/35527 46731/46731/35526 +f 46722/46722/35517 46731/46731/35526 46723/46723/35518 +f 46724/46724/35519 46733/46733/35528 46732/46732/35527 +f 46724/46724/35519 46732/46732/35527 46722/46722/35517 +f 46645/46645/35440 46646/46646/35441 46733/46733/35528 +f 46645/46645/35440 46733/46733/35528 46724/46724/35519 +f 46733/46733/35528 46734/46734/35529 46735/46735/35530 +f 46733/46733/35528 46735/46735/35530 46732/46732/35527 +f 46646/46646/35441 46647/46647/35442 46734/46734/35529 +f 46646/46646/35441 46734/46734/35529 46733/46733/35528 +f 46728/46728/35523 46736/46736/35531 46737/46737/35532 +f 46728/46728/35523 46737/46737/35532 46729/46729/35524 +f 46730/46730/35525 46738/46738/35533 46736/46736/35531 +f 46730/46730/35525 46736/46736/35531 46728/46728/35523 +f 46731/46731/35526 46739/46739/35534 46738/46738/35533 +f 46731/46731/35526 46738/46738/35533 46730/46730/35525 +f 46732/46732/35527 46735/46735/35530 46739/46739/35534 +f 46732/46732/35527 46739/46739/35534 46731/46731/35526 +f 46736/46736/35531 46740/46740/35535 46741/46741/35536 +f 46736/46736/35531 46741/46741/35536 46737/46737/35532 +f 46738/46738/35533 46742/46742/35537 46740/46740/35535 +f 46738/46738/35533 46740/46740/35535 46736/46736/35531 +f 46739/46739/35534 46743/46743/35538 46742/46742/35537 +f 46739/46739/35534 46742/46742/35537 46738/46738/35533 +f 46735/46735/35530 46744/46744/35539 46743/46743/35538 +f 46735/46735/35530 46743/46743/35538 46739/46739/35534 +f 46734/46734/35529 46745/46745/35540 46744/46744/35539 +f 46734/46734/35529 46744/46744/35539 46735/46735/35530 +f 46647/46647/35442 46648/46648/35443 46745/46745/35540 +f 46647/46647/35442 46745/46745/35540 46734/46734/35529 +f 46745/46745/35540 46746/46746/35541 46747/46747/35542 +f 46745/46745/35540 46747/46747/35542 46744/46744/35539 +f 46648/46648/35443 46649/46649/35444 46746/46746/35541 +f 46648/46648/35443 46746/46746/35541 46745/46745/35540 +f 46740/46740/35535 46748/46748/35543 46749/46749/35544 +f 46740/46740/35535 46749/46749/35544 46741/46741/35536 +f 46742/46742/35537 46750/46750/35545 46748/46748/35543 +f 46742/46742/35537 46748/46748/35543 46740/46740/35535 +f 46743/46743/35538 46751/46751/35546 46750/46750/35545 +f 46743/46743/35538 46750/46750/35545 46742/46742/35537 +f 46744/46744/35539 46747/46747/35542 46751/46751/35546 +f 46744/46744/35539 46751/46751/35546 46743/46743/35538 +f 46750/46750/35545 46752/46752/35547 46753/46753/35548 +f 46750/46750/35545 46753/46753/35548 46748/46748/35543 +f 46751/46751/35546 46754/46754/35549 46752/46752/35547 +f 46751/46751/35546 46752/46752/35547 46750/46750/35545 +f 46747/46747/35542 46755/46755/35550 46754/46754/35549 +f 46747/46747/35542 46754/46754/35549 46751/46751/35546 +f 46746/46746/35541 46756/46756/35551 46755/46755/35550 +f 46746/46746/35541 46755/46755/35550 46747/46747/35542 +f 46649/46649/35444 46650/46650/35445 46756/46756/35551 +f 46649/46649/35444 46756/46756/35551 46746/46746/35541 +f 46748/46748/35543 46753/46753/35548 46757/46757/35552 +f 46748/46748/35543 46757/46757/35552 46749/46749/35544 +f 46650/46650/35445 46651/46651/35446 46758/46758/35553 +f 46650/46650/35445 46758/46758/35553 46756/46756/35551 +f 46753/46753/35548 46759/46759/35554 46760/46760/35555 +f 46753/46753/35548 46760/46760/35555 46757/46757/35552 +f 46752/46752/35547 46761/46761/35556 46759/46759/35554 +f 46752/46752/35547 46759/46759/35554 46753/46753/35548 +f 46754/46754/35549 46762/46762/35557 46761/46761/35556 +f 46754/46754/35549 46761/46761/35556 46752/46752/35547 +f 46755/46755/35550 46763/46763/35558 46762/46762/35557 +f 46755/46755/35550 46762/46762/35557 46754/46754/35549 +f 46756/46756/35551 46758/46758/35553 46763/46763/35558 +f 46756/46756/35551 46763/46763/35558 46755/46755/35550 +f 46762/46762/35557 46764/46764/35559 46765/46765/35560 +f 46762/46762/35557 46765/46765/35560 46761/46761/35556 +f 46763/46763/35558 46766/46766/35561 46764/46764/35559 +f 46763/46763/35558 46764/46764/35559 46762/46762/35557 +f 46758/46758/35553 46767/46767/35562 46766/46766/35561 +f 46758/46758/35553 46766/46766/35561 46763/46763/35558 +f 46651/46651/35446 46652/46652/35447 46767/46767/35562 +f 46651/46651/35446 46767/46767/35562 46758/46758/35553 +f 46759/46759/35554 46768/46768/35563 46769/46769/35564 +f 46759/46759/35554 46769/46769/35564 46760/46760/35555 +f 46761/46761/35556 46765/46765/35560 46768/46768/35563 +f 46761/46761/35556 46768/46768/35563 46759/46759/35554 +f 46770/46770/35565 46771/46771/35566 46772/46772/35567 +f 46770/46770/35565 46772/46772/35567 46773/46773/35564 +f 46765/46765/35560 46774/46774/35568 46775/46775/35566 +f 46765/46765/35560 46775/46775/35566 46768/46768/35563 +f 46764/46764/35559 46776/46776/35569 46774/46774/35568 +f 46764/46764/35559 46774/46774/35568 46765/46765/35560 +f 46766/46766/35561 46777/46777/35570 46776/46776/35569 +f 46766/46766/35561 46776/46776/35569 46764/46764/35559 +f 46767/46767/35562 46778/46778/35571 46777/46777/35570 +f 46767/46767/35562 46777/46777/35570 46766/46766/35561 +f 46652/46652/35447 46653/46653/35448 46778/46778/35571 +f 46652/46652/35447 46778/46778/35571 46767/46767/35562 +f 46776/46776/35569 46779/46779/35572 46780/46780/35573 +f 46776/46776/35569 46780/46780/35573 46774/46774/35568 +f 46777/46777/35570 46781/46781/35574 46779/46779/35572 +f 46777/46777/35570 46779/46779/35572 46776/46776/35569 +f 46778/46778/35571 46782/46782/35575 46781/46781/35574 +f 46778/46778/35571 46781/46781/35574 46777/46777/35570 +f 46653/46653/35448 46654/46654/35449 46782/46782/35575 +f 46653/46653/35448 46782/46782/35575 46778/46778/35571 +f 46771/46771/35566 46783/46783/35576 46784/46784/35577 +f 46771/46771/35566 46784/46784/35577 46772/46772/35567 +f 46785/46785/35568 46786/46786/35573 46783/46783/35576 +f 46785/46785/35568 46783/46783/35576 46771/46771/35566 +f 46783/46783/35576 46787/46787/35578 46788/46788/35579 +f 46783/46783/35576 46788/46788/35579 46784/46784/35577 +f 46786/46786/35573 46789/46789/35580 46787/46787/35578 +f 46786/46786/35573 46787/46787/35578 46783/46783/35576 +f 46790/46790/35572 46791/46791/35581 46789/46789/35580 +f 46790/46790/35572 46789/46789/35580 46786/46786/35573 +f 46781/46781/35574 46792/46792/35582 46793/46793/35583 +f 46781/46781/35574 46793/46793/35583 46779/46779/35572 +f 46782/46782/35575 46794/46794/35584 46792/46792/35582 +f 46782/46782/35575 46792/46792/35582 46781/46781/35574 +f 46654/46654/35449 46655/46655/35450 46794/46794/35584 +f 46654/46654/35449 46794/46794/35584 46782/46782/35575 +f 46795/46795/35582 46796/46796/35585 46797/46797/35586 +f 46795/46795/35582 46797/46797/35586 46791/46791/35581 +f 46794/46794/35584 46798/46798/35587 46799/46799/35588 +f 46794/46794/35584 46799/46799/35588 46792/46792/35582 +f 46655/46655/35450 46656/46656/35451 46798/46798/35587 +f 46655/46655/35450 46798/46798/35587 46794/46794/35584 +f 46787/46787/35578 46800/46800/35589 46801/46801/35590 +f 46787/46787/35578 46801/46801/35590 46788/46788/35579 +f 46789/46789/35580 46802/46802/35591 46800/46800/35589 +f 46789/46789/35580 46800/46800/35589 46787/46787/35578 +f 46791/46791/35581 46797/46797/35586 46802/46802/35591 +f 46791/46791/35581 46802/46802/35591 46789/46789/35580 +f 46800/46800/35589 46803/46803/35592 46804/46804/35593 +f 46800/46800/35589 46804/46804/35593 46801/46801/35590 +f 46802/46802/35591 46805/46805/35594 46803/46803/35592 +f 46802/46802/35591 46803/46803/35592 46800/46800/35589 +f 46797/46797/35586 46806/46806/35595 46805/46805/35594 +f 46797/46797/35586 46805/46805/35594 46802/46802/35591 +f 46796/46796/35585 46807/46807/35596 46806/46806/35595 +f 46796/46796/35585 46806/46806/35595 46797/46797/35586 +f 46798/46798/35587 46808/46808/35597 46809/46809/35596 +f 46798/46798/35587 46809/46809/35596 46799/46799/35588 +f 46656/46656/35451 46657/46657/35452 46808/46808/35597 +f 46656/46656/35451 46808/46808/35597 46798/46798/35587 +f 46807/46807/35596 46810/46810/35598 46811/46811/35599 +f 46807/46807/35596 46811/46811/35599 46806/46806/35595 +f 46808/46808/35597 46812/46812/35600 46813/46813/35598 +f 46808/46808/35597 46813/46813/35598 46809/46809/35596 +f 46657/46657/35452 46658/46658/35453 46812/46812/35600 +f 46657/46657/35452 46812/46812/35600 46808/46808/35597 +f 46803/46803/35592 46814/46814/35601 46815/46815/35602 +f 46803/46803/35592 46815/46815/35602 46804/46804/35593 +f 46805/46805/35594 46816/46816/35603 46814/46814/35601 +f 46805/46805/35594 46814/46814/35601 46803/46803/35592 +f 46806/46806/35595 46811/46811/35599 46816/46816/35603 +f 46806/46806/35595 46816/46816/35603 46805/46805/35594 +f 46814/46814/35601 46817/46817/35604 46818/46818/35605 +f 46814/46814/35601 46818/46818/35605 46815/46815/35602 +f 46816/46816/35603 46819/46819/35606 46817/46817/35604 +f 46816/46816/35603 46817/46817/35604 46814/46814/35601 +f 46811/46811/35599 46820/46820/35607 46819/46819/35606 +f 46811/46811/35599 46819/46819/35606 46816/46816/35603 +f 46810/46810/35598 46821/46821/35608 46820/46820/35607 +f 46810/46810/35598 46820/46820/35607 46811/46811/35599 +f 46812/46812/35600 46822/46822/35609 46823/46823/35610 +f 46812/46812/35600 46823/46823/35610 46813/46813/35598 +f 46658/46658/35453 46659/46659/35454 46822/46822/35609 +f 46658/46658/35453 46822/46822/35609 46812/46812/35600 +f 46822/46822/35609 46824/46824/35611 46825/46825/35612 +f 46822/46822/35609 46825/46825/35612 46823/46823/35610 +f 46659/46659/35454 46660/46660/35455 46824/46824/35611 +f 46659/46659/35454 46824/46824/35611 46822/46822/35609 +f 46817/46817/35604 46826/46826/35613 46827/46827/35614 +f 46817/46817/35604 46827/46827/35614 46818/46818/35605 +f 46819/46819/35606 46828/46828/35615 46826/46826/35613 +f 46819/46819/35606 46826/46826/35613 46817/46817/35604 +f 46820/46820/35607 46829/46829/35616 46828/46828/35615 +f 46820/46820/35607 46828/46828/35615 46819/46819/35606 +f 46821/46821/35608 46830/46830/35612 46829/46829/35616 +f 46821/46821/35608 46829/46829/35616 46820/46820/35607 +f 46828/46828/35615 46831/46831/35617 46832/46832/35618 +f 46828/46828/35615 46832/46832/35618 46826/46826/35613 +f 46829/46829/35616 46833/46833/35619 46831/46831/35617 +f 46829/46829/35616 46831/46831/35617 46828/46828/35615 +f 46830/46830/35612 46834/46834/35620 46833/46833/35619 +f 46830/46830/35612 46833/46833/35619 46829/46829/35616 +f 46824/46824/35611 46835/46835/35621 46836/46836/35620 +f 46824/46824/35611 46836/46836/35620 46825/46825/35612 +f 46660/46660/35455 46661/46661/35456 46835/46835/35621 +f 46660/46660/35455 46835/46835/35621 46824/46824/35611 +f 46826/46826/35613 46832/46832/35618 46837/46837/35622 +f 46826/46826/35613 46837/46837/35622 46827/46827/35614 +f 46661/46661/35456 46662/46662/35457 46838/46838/35623 +f 46661/46661/35456 46838/46838/35623 46835/46835/35621 +f 46832/46832/35618 46839/46839/35624 46840/46840/35625 +f 46832/46832/35618 46840/46840/35625 46837/46837/35622 +f 46831/46831/35617 46841/46841/35626 46839/46839/35624 +f 46831/46831/35617 46839/46839/35624 46832/46832/35618 +f 46833/46833/35619 46842/46842/35627 46841/46841/35626 +f 46833/46833/35619 46841/46841/35626 46831/46831/35617 +f 46834/46834/35620 46843/46843/35628 46842/46842/35627 +f 46834/46834/35620 46842/46842/35627 46833/46833/35619 +f 46835/46835/35621 46838/46838/35623 46844/46844/35628 +f 46835/46835/35621 46844/46844/35628 46836/46836/35620 +f 46841/46841/35626 46845/46845/35629 46846/46846/35630 +f 46841/46841/35626 46846/46846/35630 46839/46839/35624 +f 46842/46842/35627 46847/46847/35631 46845/46845/35629 +f 46842/46842/35627 46845/46845/35629 46841/46841/35626 +f 46843/46843/35628 46848/46848/35632 46847/46847/35631 +f 46843/46843/35628 46847/46847/35631 46842/46842/35627 +f 46838/46838/35623 46849/46849/35633 46850/46850/35632 +f 46838/46838/35623 46850/46850/35632 46844/46844/35628 +f 46662/46662/35457 46663/46663/35458 46849/46849/35633 +f 46662/46662/35457 46849/46849/35633 46838/46838/35623 +f 46839/46839/35624 46846/46846/35630 46851/46851/35634 +f 46839/46839/35624 46851/46851/35634 46840/46840/35625 +f 46663/46663/35458 46664/46664/35459 46852/46852/35635 +f 46663/46663/35458 46852/46852/35635 46849/46849/35633 +f 46846/46846/35630 46853/46853/35636 46854/46854/35637 +f 46846/46846/35630 46854/46854/35637 46851/46851/35634 +f 46845/46845/35629 46855/46855/35638 46853/46853/35636 +f 46845/46845/35629 46853/46853/35636 46846/46846/35630 +f 46847/46847/35631 46856/46856/35639 46855/46855/35638 +f 46847/46847/35631 46855/46855/35638 46845/46845/35629 +f 46848/46848/35632 46857/46857/35640 46856/46856/35639 +f 46848/46848/35632 46856/46856/35639 46847/46847/35631 +f 46849/46849/35633 46852/46852/35635 46858/46858/35640 +f 46849/46849/35633 46858/46858/35640 46850/46850/35632 +f 46856/46856/35639 46859/46859/35641 46860/46860/35642 +f 46856/46856/35639 46860/46860/35642 46855/46855/35638 +f 46858/46858/35640 46861/46861/35643 46862/46862/35641 +f 46858/46858/35640 46862/46862/35641 46863/46863/35639 +f 46852/46852/35635 46864/46864/35644 46861/46861/35643 +f 46852/46852/35635 46861/46861/35643 46858/46858/35640 +f 46664/46664/35459 46665/46665/35460 46864/46864/35644 +f 46664/46664/35459 46864/46864/35644 46852/46852/35635 +f 46853/46853/35636 46865/46865/35645 46866/46866/35646 +f 46853/46853/35636 46866/46866/35646 46854/46854/35637 +f 46855/46855/35638 46860/46860/35642 46865/46865/35645 +f 46855/46855/35638 46865/46865/35645 46853/46853/35636 +f 46865/46865/35645 46867/46867/35647 46868/46868/35648 +f 46865/46865/35645 46868/46868/35648 46866/46866/35646 +f 46860/46860/35642 46869/46869/35649 46867/46867/35647 +f 46860/46860/35642 46867/46867/35647 46865/46865/35645 +f 46862/46862/35641 46870/46870/35650 46871/46871/35649 +f 46862/46862/35641 46871/46871/35649 46872/46872/35642 +f 46861/46861/35643 46873/46873/35651 46870/46870/35650 +f 46861/46861/35643 46870/46870/35650 46862/46862/35641 +f 46864/46864/35644 46874/46874/35652 46873/46873/35651 +f 46864/46864/35644 46873/46873/35651 46861/46861/35643 +f 46665/46665/35460 46666/46666/35461 46874/46874/35652 +f 46665/46665/35460 46874/46874/35652 46864/46864/35644 +f 46870/46870/35650 46875/46875/35653 46876/46876/35654 +f 46870/46870/35650 46876/46876/35654 46871/46871/35649 +f 46873/46873/35651 46877/46877/35655 46875/46875/35653 +f 46873/46873/35651 46875/46875/35653 46870/46870/35650 +f 46874/46874/35652 46878/46878/35656 46877/46877/35655 +f 46874/46874/35652 46877/46877/35655 46873/46873/35651 +f 46666/46666/35461 46667/46667/35462 46878/46878/35656 +f 46666/46666/35461 46878/46878/35656 46874/46874/35652 +f 46867/46867/35647 46879/46879/35657 46880/46880/35658 +f 46867/46867/35647 46880/46880/35658 46868/46868/35648 +f 46871/46871/35649 46876/46876/35654 46881/46881/35659 +f 46871/46871/35649 46881/46881/35659 46882/46882/35660 +f 46881/46881/35659 46668/46668/35463 46671/46671/35466 +f 46881/46881/35659 46671/46671/35466 46883/46883/35661 +f 46876/46876/35654 46672/46672/35467 46668/46668/35463 +f 46876/46876/35654 46668/46668/35463 46881/46881/35659 +f 46875/46875/35653 46674/46674/35469 46672/46672/35467 +f 46875/46875/35653 46672/46672/35467 46876/46876/35654 +f 46877/46877/35655 46676/46676/35471 46674/46674/35469 +f 46877/46877/35655 46674/46674/35469 46875/46875/35653 +f 46878/46878/35656 46678/46678/35473 46676/46676/35471 +f 46878/46878/35656 46676/46676/35471 46877/46877/35655 +f 46667/46667/35462 46637/46637/35432 46678/46678/35473 +f 46667/46667/35462 46678/46678/35473 46878/46878/35656 +o Cube.055__0 +v 0.934049 1.380560 -2.537126 +v 0.930868 1.388221 -2.543956 +v 0.928987 1.344884 -2.575418 +v 0.932187 1.339004 -2.567295 +v 0.934049 1.392343 -2.553356 +v 0.932187 1.350787 -2.583525 +v 0.938115 1.307261 -2.615125 +v 0.935382 1.299510 -2.608360 +v 0.938115 1.295478 -2.598895 +v 1.080964 1.292682 -2.625709 +v 1.107507 1.298969 -2.621145 +v 1.111881 1.293679 -2.629633 +v 1.082422 1.286620 -2.634757 +v 1.118691 1.317176 -2.607926 +v 1.125980 1.314428 -2.614569 +v 1.133270 1.307261 -2.615125 +v 1.116255 1.283970 -2.632034 +v 1.083880 1.276140 -2.637718 +v 1.133270 1.295478 -2.598895 +v 1.136003 1.299510 -2.608360 +v 1.142392 1.344884 -2.575418 +v 1.139192 1.339004 -2.567295 +v 1.133270 1.307261 -2.615125 +v 1.139192 1.350787 -2.583525 +v 1.137285 1.392343 -2.553356 +v 1.140465 1.388221 -2.543956 +v 1.137285 1.380560 -2.537126 +v 0.953257 1.401174 -2.522161 +v 0.950918 1.409720 -2.528348 +v 0.938264 1.407032 -2.530299 +v 0.941192 1.398597 -2.524031 +v 0.953257 1.412956 -2.538390 +v 0.941192 1.410380 -2.540261 +v 0.938264 1.407032 -2.530299 +v 0.941192 1.410380 -2.540261 +v 0.941192 1.398597 -2.524031 +v 1.120327 1.382905 -2.560208 +v 1.122129 1.350847 -2.583482 +v 1.118930 1.344966 -2.575359 +v 1.117147 1.375243 -2.553378 +v 1.118691 1.317176 -2.607926 +v 1.115957 1.313144 -2.598462 +v 1.118691 1.305393 -2.591697 +v 1.122129 1.339064 -2.567252 +v 1.120327 1.371122 -2.543978 +v 1.105445 1.398799 -2.548669 +v 1.114453 1.396812 -2.550111 +v 1.111530 1.388377 -2.543843 +v 1.103114 1.390253 -2.542481 +v 1.114453 1.396812 -2.550111 +v 1.111530 1.388377 -2.543843 +v 1.114453 1.385029 -2.533881 +v 1.114453 1.385029 -2.533881 +v 1.105445 1.387016 -2.532439 +v 0.952694 1.305393 -2.591697 +v 0.949251 1.339064 -2.567252 +v 0.940718 1.336824 -2.564230 +v 0.945405 1.298226 -2.592252 +v 0.951016 1.371122 -2.543978 +v 0.942533 1.373631 -2.537509 +v 0.934049 1.380560 -2.537126 +v 0.932187 1.339004 -2.567295 +v 0.938115 1.295478 -2.598895 +v 0.951016 1.382905 -2.560208 +v 0.949251 1.350847 -2.583482 +v 0.940718 1.353026 -2.586547 +v 0.942533 1.389833 -2.559825 +v 0.952694 1.317176 -2.607926 +v 0.945405 1.314428 -2.614569 +v 0.938115 1.307261 -2.615125 +v 0.932187 1.350787 -2.583525 +v 0.934049 1.392343 -2.553356 +v 1.083880 1.264357 -2.621488 +v 1.084426 1.267147 -2.631855 +v 1.117895 1.275267 -2.625960 +v 1.116255 1.272187 -2.615804 +v 1.083880 1.276140 -2.637718 +v 1.116255 1.283970 -2.632034 +v 1.117895 1.275267 -2.625960 +v 1.116255 1.283970 -2.632034 +v 1.116255 1.272187 -2.615804 +v 0.963878 1.298969 -2.621145 +v 0.959504 1.293679 -2.629633 +v 0.990422 1.292682 -2.625709 +v 0.988963 1.286620 -2.634757 +v 0.987505 1.276140 -2.637718 +v 0.955131 1.283970 -2.632034 +v 1.120327 1.371122 -2.543978 +v 1.122129 1.339064 -2.567252 +v 1.130661 1.336824 -2.564230 +v 1.128806 1.373631 -2.537509 +v 1.118691 1.305393 -2.591697 +v 1.125980 1.298226 -2.592252 +v 1.133270 1.295478 -2.598895 +v 1.139192 1.339004 -2.567295 +v 1.137285 1.380560 -2.537126 +v 1.122129 1.350847 -2.583482 +v 1.130661 1.353026 -2.586547 +v 1.120327 1.382905 -2.560208 +v 1.128806 1.389833 -2.559825 +v 1.137285 1.392343 -2.553356 +v 1.139192 1.350787 -2.583525 +v 1.105445 1.387016 -2.532439 +v 1.114453 1.385029 -2.533881 +v 1.122247 1.389604 -2.525913 +v 1.111660 1.391886 -2.524256 +v 1.130041 1.398597 -2.524031 +v 1.117875 1.401174 -2.522161 +v 0.965729 1.398799 -2.548669 +v 0.956806 1.396812 -2.550111 +v 0.948999 1.405806 -2.548229 +v 0.959493 1.408087 -2.546573 +v 0.941192 1.410380 -2.540261 +v 0.953257 1.412956 -2.538390 +v 1.107507 1.298969 -2.621145 +v 1.105867 1.295889 -2.610988 +v 1.107507 1.298969 -2.621145 +v 1.080964 1.292682 -2.625709 +v 1.080417 1.289892 -2.615343 +v 1.105867 1.295889 -2.610988 +v 1.080964 1.280899 -2.609479 +v 1.107507 1.287186 -2.604915 +v 1.107507 1.287186 -2.604915 +v 0.952694 1.317176 -2.607926 +v 0.949251 1.350847 -2.583482 +v 0.952451 1.344966 -2.575359 +v 0.955428 1.313144 -2.598462 +v 0.951016 1.382905 -2.560208 +v 0.954198 1.375243 -2.553378 +v 0.951016 1.371122 -2.543978 +v 0.949251 1.339064 -2.567252 +v 0.952694 1.305393 -2.591697 +v 0.990422 1.292682 -2.625709 +v 0.963878 1.298969 -2.621145 +v 0.965518 1.295889 -2.610988 +v 0.990968 1.289892 -2.615343 +v 0.963878 1.298969 -2.621145 +v 0.965518 1.295889 -2.610988 +v 0.963878 1.287186 -2.604915 +v 0.963878 1.287186 -2.604915 +v 0.990422 1.280899 -2.609479 +v 0.990422 1.280899 -2.609479 +v 0.963878 1.287186 -2.604915 +v 0.959504 1.277477 -2.607316 +v 0.988963 1.270419 -2.612440 +v 0.955131 1.272187 -2.615804 +v 0.987505 1.264357 -2.621488 +v 1.107507 1.287186 -2.604915 +v 1.111881 1.277477 -2.607316 +v 1.080964 1.280899 -2.609479 +v 1.082422 1.270419 -2.612440 +v 1.083880 1.264357 -2.621488 +v 1.116255 1.272187 -2.615804 +v 1.035692 1.288347 -2.616464 +v 1.035692 1.291070 -2.626880 +v 1.035692 1.279287 -2.610650 +v 1.035692 1.284829 -2.636058 +v 1.035692 1.291070 -2.626880 +v 1.035692 1.274170 -2.639148 +v 1.035692 1.268627 -2.613741 +v 1.035692 1.279287 -2.610650 +v 1.035692 1.262387 -2.622919 +v 1.035692 1.265110 -2.633334 +v 1.035692 1.274170 -2.639148 +v 1.035692 1.262387 -2.622919 +v 0.987505 1.264357 -2.621488 +v 0.986959 1.267147 -2.631855 +v 0.987505 1.276140 -2.637718 +v 0.953490 1.275267 -2.625960 +v 0.955131 1.272187 -2.615804 +v 0.955131 1.283970 -2.632034 +v 0.953490 1.275267 -2.625960 +v 0.955131 1.283970 -2.632034 +v 0.955131 1.272187 -2.615804 +v 1.114453 1.396812 -2.550111 +v 1.122247 1.405806 -2.548229 +v 1.105445 1.398799 -2.548669 +v 1.111660 1.408087 -2.546573 +v 1.117875 1.412956 -2.538390 +v 1.130041 1.410380 -2.540261 +v 1.086054 1.398752 -2.548966 +v 1.094746 1.398793 -2.548706 +v 1.093397 1.390224 -2.542502 +v 1.085612 1.390017 -2.542653 +v 1.094746 1.386979 -2.532433 +v 1.086054 1.386719 -2.532392 +v 0.965729 1.398799 -2.548669 +v 0.976391 1.398793 -2.548706 +v 0.977750 1.390224 -2.542502 +v 0.968068 1.390253 -2.542481 +v 0.985078 1.398752 -2.548966 +v 0.985530 1.390017 -2.542653 +v 0.985078 1.386719 -2.532391 +v 0.976391 1.386979 -2.532433 +v 0.965729 1.387016 -2.532439 +v 1.132964 1.407032 -2.530299 +v 1.130041 1.398597 -2.524031 +v 1.130041 1.410380 -2.540261 +v 1.132964 1.407032 -2.530299 +v 1.130041 1.410380 -2.540261 +v 1.117875 1.412956 -2.538390 +v 1.120206 1.409720 -2.528348 +v 1.130041 1.398597 -2.524031 +v 1.117875 1.401174 -2.522161 +v 0.956806 1.396812 -2.550111 +v 0.959733 1.388377 -2.543843 +v 0.956806 1.396812 -2.550111 +v 0.959733 1.388377 -2.543843 +v 0.956806 1.385029 -2.533881 +v 0.956806 1.385029 -2.533881 +v 0.956806 1.385029 -2.533881 +v 0.948999 1.389604 -2.525913 +v 0.965729 1.387016 -2.532439 +v 0.959493 1.391886 -2.524256 +v 0.953257 1.401174 -2.522161 +v 0.941192 1.398597 -2.524031 +v 1.094746 1.398793 -2.548706 +v 1.098342 1.408109 -2.546602 +v 1.086054 1.398752 -2.548966 +v 1.087233 1.408259 -2.546810 +v 1.088412 1.413254 -2.538438 +v 1.101939 1.412994 -2.538396 +v 1.086054 1.386719 -2.532392 +v 1.094746 1.386979 -2.532433 +v 1.098342 1.391865 -2.524227 +v 1.087233 1.391713 -2.524019 +v 1.101939 1.401179 -2.522123 +v 1.088412 1.401220 -2.521863 +v 0.976391 1.386979 -2.532433 +v 0.972770 1.391865 -2.524227 +v 0.985078 1.386719 -2.532391 +v 0.983874 1.391714 -2.524019 +v 0.982669 1.401221 -2.521863 +v 0.969148 1.401180 -2.522123 +v 0.985078 1.398752 -2.548966 +v 0.976391 1.398793 -2.548706 +v 0.972770 1.408109 -2.546602 +v 0.983874 1.408259 -2.546809 +v 0.969148 1.412994 -2.538396 +v 0.982669 1.413254 -2.538438 +v 0.982669 1.401221 -2.521863 +v 0.982217 1.409956 -2.528177 +v 0.967791 1.409749 -2.528327 +v 0.969148 1.401180 -2.522123 +v 0.982669 1.413254 -2.538438 +v 0.969148 1.412994 -2.538396 +v 0.988573 1.408711 -2.547431 +v 0.988735 1.398629 -2.549746 +v 0.988411 1.414034 -2.538561 +v 0.988573 1.408711 -2.547431 +v 0.988411 1.414034 -2.538561 +v 0.989232 1.415930 -2.538861 +v 0.989244 1.409807 -2.548939 +v 0.988735 1.398629 -2.549746 +v 0.989257 1.398329 -2.551640 +v 1.082346 1.389395 -2.543104 +v 1.082397 1.398628 -2.549746 +v 1.082397 1.385938 -2.532268 +v 1.082346 1.389395 -2.543104 +v 1.082397 1.385938 -2.532268 +v 1.081875 1.384044 -2.531968 +v 1.081880 1.387885 -2.544200 +v 1.082397 1.398628 -2.549746 +v 1.081875 1.398326 -2.551641 +v 0.988795 1.389396 -2.543103 +v 0.988735 1.385939 -2.532267 +v 0.988735 1.398629 -2.549746 +v 0.988795 1.389396 -2.543103 +v 0.989261 1.387887 -2.544199 +v 0.988735 1.385939 -2.532267 +v 0.989257 1.384045 -2.531965 +v 0.988573 1.391263 -2.523398 +v 0.988411 1.401345 -2.521083 +v 0.988735 1.385939 -2.532267 +v 0.988573 1.391263 -2.523398 +v 0.989244 1.390168 -2.521888 +v 0.988411 1.401345 -2.521083 +v 0.989232 1.401647 -2.519188 +v 1.103288 1.409749 -2.528327 +v 1.101939 1.401179 -2.522123 +v 1.101939 1.412994 -2.538396 +v 1.088412 1.413254 -2.538438 +v 1.088855 1.409956 -2.528177 +v 1.088412 1.401220 -2.521863 +v 0.989244 1.411720 -2.551573 +v 0.989257 1.397805 -2.554946 +v 0.989232 1.419236 -2.539385 +v 0.989232 1.422767 -2.539944 +v 0.989244 1.413763 -2.554383 +v 0.989257 1.397247 -2.558475 +v 1.081880 1.385249 -2.546114 +v 1.081875 1.397800 -2.554948 +v 1.081875 1.380736 -2.531444 +v 1.081875 1.377206 -2.530885 +v 1.081880 1.382437 -2.548156 +v 1.081875 1.397238 -2.558478 +v 0.989261 1.385254 -2.546110 +v 0.989257 1.380740 -2.531440 +v 0.989261 1.382444 -2.548151 +v 0.989257 1.377212 -2.530878 +v 0.989244 1.388257 -2.519253 +v 0.989232 1.402173 -2.515881 +v 0.989244 1.386217 -2.516441 +v 0.989232 1.402735 -2.512351 +v 1.082721 1.410578 -2.527725 +v 1.082670 1.401344 -2.521083 +v 1.082670 1.414034 -2.538562 +v 1.082721 1.410578 -2.527725 +v 1.082670 1.414034 -2.538562 +v 1.081850 1.415927 -2.538863 +v 1.081845 1.412086 -2.526630 +v 1.082670 1.401344 -2.521083 +v 1.081850 1.401644 -2.519189 +v 0.988350 1.410578 -2.527725 +v 0.988411 1.414034 -2.538561 +v 0.988411 1.401345 -2.521083 +v 0.988350 1.410578 -2.527725 +v 0.989227 1.412088 -2.526629 +v 1.082534 1.391262 -2.523398 +v 1.082397 1.385938 -2.532268 +v 1.082670 1.401344 -2.521083 +v 1.082534 1.391262 -2.523398 +v 1.081862 1.390166 -2.521890 +v 1.082534 1.408710 -2.547431 +v 1.082670 1.414034 -2.538562 +v 1.082397 1.398628 -2.549746 +v 1.082534 1.408710 -2.547431 +v 1.081862 1.409805 -2.548941 +v 1.082136 1.380337 -2.549582 +v 1.082134 1.396842 -2.560967 +v 1.082104 1.374252 -2.530435 +v 1.084034 1.368931 -2.529828 +v 1.083951 1.378714 -2.550465 +v 1.082134 1.396842 -2.560967 +v 1.082136 1.380337 -2.549582 +v 1.083951 1.378714 -2.550465 +v 1.083944 1.396623 -2.562341 +v 0.989005 1.380346 -2.549576 +v 0.989028 1.374258 -2.530426 +v 0.988998 1.396852 -2.560963 +v 0.989005 1.380346 -2.549576 +v 0.988998 1.396852 -2.560963 +v 0.987187 1.396635 -2.562338 +v 0.987190 1.378724 -2.550458 +v 0.987190 1.378724 -2.550458 +v 0.987101 1.368937 -2.529816 +v 0.989070 1.384685 -2.514329 +v 0.989003 1.403222 -2.509403 +v 0.987930 1.383362 -2.512506 +v 0.987073 1.404292 -2.504156 +v 1.081850 1.422761 -2.539951 +v 1.081862 1.413756 -2.554388 +v 1.082121 1.415195 -2.556372 +v 1.082109 1.425250 -2.540347 +v 1.082121 1.415195 -2.556372 +v 1.082134 1.396842 -2.560967 +v 1.083944 1.396623 -2.562341 +v 1.083932 1.415989 -2.557467 +v 1.082109 1.425250 -2.540347 +v 1.083920 1.426624 -2.540566 +v 1.081845 1.414719 -2.524719 +v 1.081850 1.402167 -2.515883 +v 1.081850 1.419233 -2.539390 +v 1.081845 1.417529 -2.522679 +v 1.081850 1.402726 -2.512354 +v 0.989227 1.414723 -2.524716 +v 0.989227 1.417536 -2.522674 +v 1.081862 1.388252 -2.519257 +v 1.081862 1.386210 -2.516446 +v 1.081862 1.411716 -2.551576 +v 1.084006 1.404279 -2.504158 +v 1.086071 1.411181 -2.501925 +v 1.087402 1.407769 -2.493715 +v 1.086860 1.400102 -2.498781 +v 1.086071 1.411181 -2.501925 +v 1.072801 1.412005 -2.501672 +v 1.073222 1.408846 -2.493020 +v 1.087402 1.407769 -2.493715 +v 1.087402 1.407769 -2.493715 +v 1.073222 1.408846 -2.493020 +v 1.073943 1.411610 -2.489450 +v 1.089591 1.410381 -2.490341 +v 1.086860 1.400102 -2.498781 +v 1.090562 1.401787 -2.496582 +v 0.987187 1.396635 -2.562338 +v 0.987175 1.415999 -2.557460 +v 0.985483 1.416300 -2.557874 +v 0.985495 1.396553 -2.562858 +v 0.987163 1.426631 -2.540555 +v 0.985470 1.427152 -2.540638 +v 0.985483 1.416300 -2.557874 +v 0.985470 1.427152 -2.540638 +v 0.998460 1.427225 -2.540651 +v 0.998472 1.416342 -2.557934 +v 0.985495 1.396553 -2.562858 +v 0.998484 1.396539 -2.562932 +v 1.085688 1.377934 -2.551327 +v 1.085636 1.396540 -2.562862 +v 1.086107 1.364671 -2.535702 +v 1.085688 1.377934 -2.551327 +v 1.085688 1.377934 -2.551327 +v 1.086107 1.364671 -2.535702 +v 1.072839 1.364177 -2.536402 +v 1.072675 1.377813 -2.551512 +v 1.085636 1.396540 -2.562862 +v 1.072647 1.396530 -2.562936 +v 0.988986 1.415203 -2.556366 +v 0.988973 1.425256 -2.540338 +v 0.988986 1.415203 -2.556366 +v 0.988973 1.425256 -2.540338 +v 0.988998 1.396852 -2.560963 +v 1.082102 1.419534 -2.521125 +v 1.082078 1.403211 -2.509407 +v 1.082102 1.419534 -2.521125 +v 1.082109 1.425250 -2.540347 +v 1.083920 1.426624 -2.540566 +v 1.083916 1.420875 -2.519856 +v 1.083916 1.420875 -2.519856 +v 0.988971 1.419543 -2.521119 +v 0.987156 1.420885 -2.519850 +v 0.988973 1.425256 -2.540338 +v 0.988971 1.419543 -2.521119 +v 0.987156 1.420885 -2.519850 +v 0.987163 1.426631 -2.540555 +v 1.082036 1.384676 -2.514335 +v 1.083177 1.383353 -2.512513 +v 1.085821 1.382342 -2.511119 +v 1.086886 1.365114 -2.524192 +v 1.085821 1.382342 -2.511119 +v 1.090020 1.382145 -2.510847 +v 1.086886 1.365114 -2.524192 +v 1.090589 1.362503 -2.525112 +v 1.096639 1.382017 -2.510668 +v 1.096208 1.358572 -2.527209 +v 1.096179 1.404998 -2.493494 +v 1.107123 1.408196 -2.484585 +v 1.109262 1.381427 -2.509856 +v 1.107158 1.349093 -2.527504 +v 0.998484 1.396539 -2.562932 +v 0.998467 1.377821 -2.551506 +v 0.985453 1.377944 -2.551319 +v 0.985495 1.396553 -2.562858 +v 0.998305 1.364181 -2.536392 +v 0.985036 1.364676 -2.535687 +v 0.985453 1.377944 -2.551319 +v 0.985036 1.364676 -2.535687 +v 0.985495 1.396553 -2.562858 +v 0.985453 1.377944 -2.551319 +v 0.985286 1.382350 -2.511113 +v 0.984221 1.400115 -2.498782 +v 0.984247 1.365119 -2.524179 +v 0.985286 1.382350 -2.511113 +v 0.984247 1.365119 -2.524179 +v 0.980545 1.362505 -2.525100 +v 0.981087 1.382152 -2.510842 +v 0.984221 1.400115 -2.498782 +v 0.980518 1.401799 -2.496583 +v 1.107123 1.408196 -2.484585 +v 1.110366 1.406093 -2.461887 +v 1.130202 1.403819 -2.463143 +v 1.129483 1.402938 -2.484980 +v 1.110734 1.393066 -2.441715 +v 1.130436 1.391399 -2.442925 +v 1.149055 1.379703 -2.451419 +v 1.148267 1.392233 -2.470984 +v 1.144453 1.394915 -2.486274 +v 0.963984 1.349087 -2.527498 +v 0.975352 1.340124 -2.531454 +v 0.973980 1.327256 -2.518893 +v 0.960741 1.328073 -2.518529 +v 0.995374 1.339112 -2.531885 +v 0.995024 1.327063 -2.518959 +v 0.994974 1.312828 -2.499971 +v 0.973788 1.312826 -2.499970 +v 0.960372 1.312824 -2.499970 +v 0.940905 1.329971 -2.516757 +v 0.941624 1.351080 -2.522629 +v 0.940671 1.314492 -2.498760 +v 0.922052 1.326190 -2.490269 +v 0.922839 1.341012 -2.508171 +v 0.926654 1.354779 -2.515412 +v 0.981516 1.353909 -2.531339 +v 0.978471 1.348732 -2.533899 +v 0.974927 1.358572 -2.527199 +v 0.997164 1.352682 -2.532232 +v 0.996199 1.347384 -2.534803 +v 0.978471 1.348732 -2.533899 +v 0.996199 1.347384 -2.534803 +v 0.975352 1.340124 -2.531454 +v 0.963984 1.349087 -2.527498 +v 0.974467 1.382021 -2.510665 +v 0.974898 1.405008 -2.493498 +v 0.961845 1.381427 -2.509856 +v 0.963948 1.408202 -2.484592 +v 1.095755 1.414726 -2.477294 +v 1.097127 1.406692 -2.461223 +v 1.075733 1.415447 -2.476466 +v 1.076083 1.406813 -2.461061 +v 1.076133 1.393066 -2.441719 +v 1.097319 1.393065 -2.441717 +v 0.997123 1.411621 -2.489453 +v 0.981477 1.410395 -2.490345 +v 0.978429 1.414426 -2.486220 +v 0.996156 1.415700 -2.485217 +v 0.975308 1.414734 -2.477301 +v 0.996156 1.415700 -2.485217 +v 0.978429 1.414426 -2.486220 +v 0.975308 1.414734 -2.477301 +v 0.995329 1.415454 -2.476470 +v 0.973932 1.406699 -2.461232 +v 0.994976 1.406818 -2.461066 +v 0.963948 1.408202 -2.484592 +v 0.960693 1.406097 -2.461899 +v 0.960321 1.393069 -2.441728 +v 0.973738 1.393071 -2.441726 +v 0.994925 1.393070 -2.441724 +v 1.075778 1.339115 -2.531892 +v 1.095799 1.340128 -2.531465 +v 1.097174 1.327261 -2.518903 +v 1.076131 1.327067 -2.518965 +v 1.107158 1.349093 -2.527504 +v 1.110414 1.328083 -2.518536 +v 1.110785 1.312835 -2.499977 +v 1.097368 1.312833 -2.499978 +v 1.076182 1.312832 -2.499977 +v 0.998268 1.412016 -2.501672 +v 0.984999 1.411196 -2.501924 +v 0.983668 1.407784 -2.493718 +v 0.997846 1.408858 -2.493023 +v 0.984999 1.411196 -2.501924 +v 0.983668 1.407784 -2.493718 +v 0.983668 1.407784 -2.493718 +v 0.997846 1.408858 -2.493023 +v 1.073983 1.352682 -2.532243 +v 1.089629 1.353909 -2.531353 +v 1.092677 1.348734 -2.533912 +v 1.074950 1.347386 -2.534812 +v 1.095799 1.340128 -2.531465 +v 1.074950 1.347386 -2.534812 +v 1.092677 1.348734 -2.533912 +v 1.087439 1.357924 -2.529916 +v 1.073260 1.356931 -2.530721 +v 1.087439 1.357924 -2.529916 +v 1.087439 1.357924 -2.529916 +v 1.073260 1.356931 -2.530721 +v 1.092636 1.414415 -2.486214 +v 1.074907 1.415692 -2.485213 +v 1.092636 1.414415 -2.486214 +v 1.074907 1.415692 -2.485213 +v 1.095755 1.414726 -2.477294 +v 0.983705 1.357926 -2.529900 +v 0.997885 1.356932 -2.530709 +v 0.983705 1.357926 -2.529900 +v 0.983705 1.357926 -2.529900 +v 0.997885 1.356932 -2.530709 +v 1.072622 1.427219 -2.540659 +v 1.072640 1.422152 -2.519323 +v 1.085653 1.421935 -2.519382 +v 1.085612 1.427144 -2.540649 +v 1.085653 1.421935 -2.519382 +v 1.085612 1.427144 -2.540649 +v 1.085653 1.421935 -2.519382 +v 1.072647 1.396530 -2.562936 +v 1.072635 1.416334 -2.557940 +v 1.085624 1.416289 -2.557882 +v 1.085636 1.396540 -2.562862 +v 1.072622 1.427219 -2.540659 +v 1.085612 1.427144 -2.540649 +v 1.085624 1.416289 -2.557882 +v 1.085612 1.427144 -2.540649 +v 1.085636 1.396540 -2.562862 +v 1.035532 1.415696 -2.485214 +v 1.035533 1.411615 -2.489452 +v 1.035531 1.415451 -2.476468 +v 1.035532 1.415696 -2.485214 +v 1.035530 1.406816 -2.461064 +v 1.035529 1.393068 -2.441721 +v 1.035577 1.327065 -2.518962 +v 1.035576 1.339113 -2.531888 +v 1.035578 1.312830 -2.499974 +v 1.035534 1.408852 -2.493021 +v 1.035535 1.412010 -2.501672 +v 1.035534 1.408852 -2.493021 +v 1.035575 1.347385 -2.534808 +v 1.035573 1.352682 -2.532237 +v 1.035575 1.347385 -2.534808 +v 1.035573 1.356932 -2.530715 +v 1.035572 1.364179 -2.536397 +v 1.035573 1.356932 -2.530715 +v 1.035571 1.377817 -2.551509 +v 1.035566 1.396534 -2.562934 +v 1.035553 1.416338 -2.557937 +v 1.035541 1.427222 -2.540655 +v 1.035566 1.396534 -2.562934 +v 1.035536 1.422156 -2.519320 +v 1.035541 1.427222 -2.540655 +v 0.998460 1.427225 -2.540651 +v 0.998431 1.422159 -2.519317 +v 0.985418 1.421946 -2.519374 +v 0.985470 1.427152 -2.540638 +v 0.985418 1.421946 -2.519374 +v 0.985418 1.421946 -2.519374 +v 0.985470 1.427152 -2.540638 +v 1.144480 1.354800 -2.515404 +v 1.147496 1.376457 -2.503030 +v 1.154919 1.366794 -2.489789 +v 1.148303 1.341036 -2.508162 +v 1.144453 1.394915 -2.486274 +v 1.148267 1.392233 -2.470984 +v 1.149055 1.379703 -2.451419 +v 1.155985 1.352961 -2.470839 +v 1.149093 1.326216 -2.490261 +v 0.926626 1.394902 -2.486291 +v 0.923611 1.376440 -2.503043 +v 0.916188 1.366772 -2.489805 +v 0.922804 1.392218 -2.471005 +v 0.926654 1.354779 -2.515412 +v 0.922839 1.341012 -2.508171 +v 0.922052 1.326190 -2.490269 +v 0.915121 1.352937 -2.470856 +v 0.922014 1.379687 -2.451441 +v 1.129911 1.380447 -2.508503 +v 1.129516 1.351094 -2.522627 +v 1.129483 1.402938 -2.484980 +v 1.144453 1.394915 -2.486274 +v 1.147496 1.376457 -2.503030 +v 1.144480 1.354800 -2.515404 +v 0.940856 1.403814 -2.463161 +v 0.940619 1.391393 -2.442944 +v 0.941591 1.402932 -2.484994 +v 0.926626 1.394902 -2.486291 +v 0.922804 1.392218 -2.471005 +v 0.922014 1.379687 -2.451441 +v 1.130251 1.329988 -2.516758 +v 1.130488 1.314511 -2.498760 +v 1.129516 1.351094 -2.522627 +v 1.144480 1.354800 -2.515404 +v 1.148303 1.341036 -2.508162 +v 1.149093 1.326216 -2.490261 +v 0.941196 1.380437 -2.508510 +v 0.941591 1.402932 -2.484994 +v 0.941624 1.351080 -2.522629 +v 0.926654 1.354779 -2.515412 +v 0.923611 1.376440 -2.503043 +v 0.926626 1.394902 -2.486291 +vt 0.311864 0.248835 +vt 0.311542 0.248026 +vt 0.311303 0.248022 +vt 0.311688 0.249007 +vt 0.311716 0.247049 +vt 0.749651 0.604895 +vt 0.750543 0.604577 +vt 0.750539 0.604337 +vt 0.749473 0.604723 +vt 0.751447 0.604863 +vt 0.751619 0.604685 +vt 0.313645 0.248861 +vt 0.312747 0.249390 +vt 0.313816 0.249039 +vt 0.312750 0.249150 +vt 0.313668 0.247253 +vt 0.313991 0.248062 +vt 0.314229 0.248066 +vt 0.313844 0.247081 +vt 0.751477 0.606471 +vt 0.750589 0.607029 +vt 0.751656 0.606642 +vt 0.750585 0.606788 +vt 0.749681 0.606503 +vt 0.749509 0.606681 +vt 0.311887 0.247227 +vt 0.312782 0.246938 +vt 0.312786 0.246698 +vt 0.751799 0.605661 +vt 0.752040 0.605656 +vt 0.749329 0.605705 +vt 0.749089 0.605709 +vt 0.997609 0.802514 +vt 0.999358 0.802518 +vt 0.999358 0.799515 +vt 0.997254 0.689344 +vt 0.999003 0.689348 +vt 0.999003 0.686346 +vt 0.070805 0.068290 +vt 0.071509 0.068444 +vt 0.071442 0.064485 +vt 0.070739 0.064493 +vt 0.072274 0.068273 +vt 0.072209 0.064476 +vt 0.072220 0.060497 +vt 0.071456 0.060337 +vt 0.070751 0.060514 +vt 0.968355 0.901004 +vt 0.968930 0.899041 +vt 0.968245 0.898720 +vt 0.967599 0.900898 +vt 0.970594 0.898214 +vt 0.970141 0.897677 +vt 0.969688 0.897136 +vt 0.967559 0.898394 +vt 0.966843 0.900788 +vt 0.213859 0.109907 +vt 0.214591 0.110084 +vt 0.214586 0.105948 +vt 0.213855 0.105939 +vt 0.215341 0.109913 +vt 0.215337 0.105945 +vt 0.215357 0.102146 +vt 0.214607 0.101985 +vt 0.213875 0.102139 +vt 0.943615 0.428874 +vt 0.942900 0.429047 +vt 0.942876 0.429982 +vt 0.943593 0.429766 +vt 0.942138 0.428874 +vt 0.942116 0.429766 +vt 0.071605 0.070160 +vt 0.072367 0.069917 +vt 0.070897 0.069934 +vt 0.496621 0.053028 +vt 0.496580 0.055957 +vt 0.497347 0.055962 +vt 0.497387 0.053195 +vt 0.496591 0.059033 +vt 0.497355 0.058869 +vt 0.498060 0.059046 +vt 0.498050 0.055970 +vt 0.498091 0.053040 +vt 0.285100 0.248666 +vt 0.285082 0.247999 +vt 0.284321 0.248216 +vt 0.284338 0.248838 +vt 0.496691 0.051755 +vt 0.497454 0.051993 +vt 0.498160 0.051768 +vt 0.283605 0.247999 +vt 0.283623 0.248666 +vt 0.593434 0.007558 +vt 0.596508 0.007339 +vt 0.596493 0.006782 +vt 0.592969 0.007086 +vt 0.599436 0.007495 +vt 0.599854 0.006946 +vt 0.600297 0.006278 +vt 0.596503 0.006106 +vt 0.592529 0.006496 +vt 0.976602 0.910612 +vt 0.973671 0.910743 +vt 0.973669 0.911376 +vt 0.977033 0.911242 +vt 0.970594 0.910488 +vt 0.970141 0.911030 +vt 0.969688 0.911566 +vt 0.973666 0.912005 +vt 0.977464 0.911867 +vt 0.528877 0.102145 +vt 0.529588 0.102105 +vt 0.529660 0.099630 +vt 0.528946 0.099751 +vt 0.530354 0.102145 +vt 0.530423 0.099751 +vt 0.214639 0.112273 +vt 0.215386 0.112017 +vt 0.213904 0.112010 +vt 0.968930 0.909661 +vt 0.968244 0.909987 +vt 0.968355 0.907699 +vt 0.967599 0.907809 +vt 0.966843 0.907914 +vt 0.967559 0.910308 +vt 0.599436 0.019725 +vt 0.596509 0.019827 +vt 0.596493 0.020502 +vt 0.599854 0.020401 +vt 0.593434 0.019548 +vt 0.592969 0.020130 +vt 0.592529 0.020592 +vt 0.596503 0.021059 +vt 0.600298 0.020959 +vt 0.973672 0.897960 +vt 0.973669 0.897331 +vt 0.976602 0.898093 +vt 0.977033 0.897468 +vt 0.977464 0.896839 +vt 0.973666 0.896698 +vt 0.600887 0.018665 +vt 0.600706 0.019313 +vt 0.601312 0.019942 +vt 0.601521 0.019179 +vt 0.601944 0.020452 +vt 0.602180 0.019575 +vt 0.978054 0.909525 +vt 0.977873 0.910184 +vt 0.978493 0.910764 +vt 0.978702 0.909988 +vt 0.979113 0.911339 +vt 0.979348 0.910447 +vt 0.496691 0.060694 +vt 0.497444 0.060443 +vt 0.528958 0.077154 +vt 0.528904 0.079117 +vt 0.529669 0.079158 +vt 0.529721 0.077276 +vt 0.530381 0.079117 +vt 0.530435 0.077154 +vt 0.498160 0.060706 +vt 0.213865 0.061534 +vt 0.213862 0.064615 +vt 0.214613 0.064610 +vt 0.214615 0.061698 +vt 0.213875 0.067541 +vt 0.214625 0.067374 +vt 0.215357 0.067539 +vt 0.215344 0.064613 +vt 0.215347 0.061531 +vt 0.528904 0.085813 +vt 0.528958 0.087775 +vt 0.529721 0.087654 +vt 0.529669 0.085772 +vt 0.213896 0.059854 +vt 0.214643 0.060107 +vt 0.215378 0.059851 +vt 0.530435 0.087775 +vt 0.530381 0.085813 +vt 0.591198 0.010261 +vt 0.591772 0.008349 +vt 0.591074 0.008086 +vt 0.590430 0.010208 +vt 0.590402 0.007704 +vt 0.589687 0.010035 +vt 0.591772 0.018724 +vt 0.591074 0.019093 +vt 0.591198 0.016801 +vt 0.590430 0.016958 +vt 0.589687 0.016997 +vt 0.590402 0.019343 +vt 0.529656 0.082465 +vt 0.528890 0.082465 +vt 0.530367 0.082465 +vt 0.967436 0.904354 +vt 0.968208 0.904351 +vt 0.966663 0.904351 +vt 0.590266 0.013581 +vt 0.591051 0.013529 +vt 0.589507 0.013514 +vt 0.529570 0.105709 +vt 0.530336 0.105708 +vt 0.528860 0.105708 +vt 0.528877 0.109272 +vt 0.529588 0.109312 +vt 0.530354 0.109272 +vt 0.071612 0.058113 +vt 0.070897 0.058377 +vt 0.072367 0.058360 +vt 0.529660 0.111787 +vt 0.530423 0.111666 +vt 0.528946 0.111666 +vt 0.977873 0.898527 +vt 0.978493 0.897953 +vt 0.978055 0.899193 +vt 0.978702 0.898736 +vt 0.979349 0.898274 +vt 0.979113 0.897375 +vt 0.285114 0.250099 +vt 0.285101 0.249457 +vt 0.284338 0.249556 +vt 0.284336 0.250132 +vt 0.283621 0.249457 +vt 0.283606 0.250099 +vt 0.285234 0.248668 +vt 0.285232 0.249456 +vt 0.285996 0.249557 +vt 0.285996 0.248841 +vt 0.285220 0.250099 +vt 0.285998 0.250132 +vt 0.286728 0.250099 +vt 0.286713 0.249456 +vt 0.286710 0.248668 +vt 0.214636 0.100256 +vt 0.213904 0.100481 +vt 0.215386 0.100488 +vt 0.711550 0.778226 +vt 0.712310 0.778010 +vt 0.712288 0.777111 +vt 0.711527 0.777283 +vt 0.710833 0.778010 +vt 0.710811 0.777111 +vt 0.213896 0.068803 +vt 0.214645 0.068565 +vt 0.285251 0.248008 +vt 0.286012 0.248225 +vt 0.286728 0.248008 +vt 0.215378 0.068801 +vt 0.600706 0.007926 +vt 0.601312 0.007427 +vt 0.600887 0.008572 +vt 0.601520 0.008188 +vt 0.602180 0.007684 +vt 0.601944 0.006810 +vt 0.978053 0.899984 +vt 0.978702 0.899721 +vt 0.978039 0.900627 +vt 0.978702 0.900543 +vt 0.979364 0.900453 +vt 0.979351 0.899453 +vt 0.600871 0.017267 +vt 0.600885 0.017892 +vt 0.601520 0.018218 +vt 0.601520 0.017419 +vt 0.602182 0.018424 +vt 0.602195 0.017450 +vt 0.600885 0.009343 +vt 0.601520 0.009147 +vt 0.600870 0.009973 +vt 0.601520 0.009953 +vt 0.602195 0.009812 +vt 0.602181 0.008832 +vt 0.978039 0.908094 +vt 0.978052 0.908736 +vt 0.978702 0.909006 +vt 0.978702 0.908185 +vt 0.979351 0.909272 +vt 0.979364 0.908272 +vt 0.943632 0.426699 +vt 0.942902 0.426732 +vt 0.942900 0.427799 +vt 0.943617 0.427698 +vt 0.942124 0.426699 +vt 0.942136 0.427698 +vt 0.978702 0.907839 +vt 0.977998 0.907824 +vt 0.979406 0.907848 +vt 0.311685 0.248028 +vt 0.311994 0.247328 +vt 0.311970 0.248736 +vt 0.284330 0.250374 +vt 0.285151 0.250370 +vt 0.283561 0.250370 +vt 0.750547 0.604715 +vt 0.751350 0.604964 +vt 0.749755 0.604993 +vt 0.286003 0.250374 +vt 0.286773 0.250369 +vt 0.285183 0.250369 +vt 0.312757 0.249012 +vt 0.313553 0.248760 +vt 0.601517 0.010305 +vt 0.602234 0.010236 +vt 0.600827 0.010246 +vt 0.313861 0.248060 +vt 0.313576 0.247352 +vt 0.711526 0.776032 +vt 0.710809 0.775932 +vt 0.712290 0.775932 +vt 0.712302 0.774932 +vt 0.711524 0.774965 +vt 0.710794 0.774932 +vt 0.311534 0.246859 +vt 0.311049 0.248018 +vt 0.311500 0.249191 +vt 0.751802 0.604494 +vt 0.750534 0.604080 +vt 0.749282 0.604540 +vt 0.312743 0.249647 +vt 0.313999 0.249228 +vt 0.314484 0.248069 +vt 0.314032 0.246896 +vt 0.711519 0.774511 +vt 0.710749 0.774507 +vt 0.712339 0.774507 +vt 0.750585 0.606649 +vt 0.749782 0.606400 +vt 0.751378 0.606371 +vt 0.942907 0.426279 +vt 0.942087 0.426274 +vt 0.943677 0.426274 +vt 0.312789 0.247076 +vt 0.601517 0.017092 +vt 0.600827 0.017011 +vt 0.602234 0.017045 +vt 0.751663 0.605662 +vt 0.978702 0.900891 +vt 0.979406 0.900878 +vt 0.977998 0.900898 +vt 0.749469 0.605702 +vt 0.750537 0.603892 +vt 0.749149 0.604410 +vt 0.751955 0.604334 +vt 0.752223 0.604034 +vt 0.750558 0.603753 +vt 0.215136 0.700742 +vt 0.215133 0.702087 +vt 0.215267 0.702092 +vt 0.215270 0.700663 +vt 0.312749 0.249834 +vt 0.314153 0.249388 +vt 0.311371 0.249321 +vt 0.215133 0.702126 +vt 0.215136 0.703472 +vt 0.215270 0.703551 +vt 0.215267 0.702121 +vt 0.312783 0.249970 +vt 0.314433 0.249683 +vt 0.314677 0.248072 +vt 0.314190 0.246741 +vt 0.314853 0.248074 +vt 0.314479 0.246453 +vt 0.749326 0.606871 +vt 0.748832 0.605714 +vt 0.748652 0.605716 +vt 0.749198 0.607005 +vt 0.215068 0.561458 +vt 0.215180 0.562777 +vt 0.215295 0.562845 +vt 0.215178 0.561452 +vt 0.215180 0.560184 +vt 0.215295 0.560107 +vt 0.750594 0.607285 +vt 0.751846 0.606826 +vt 0.312789 0.246441 +vt 0.752296 0.605651 +vt 0.752284 0.607264 +vt 0.752133 0.607773 +vt 0.752779 0.607912 +vt 0.752795 0.607234 +vt 0.869392 0.433292 +vt 0.869377 0.434273 +vt 0.870047 0.434242 +vt 0.870043 0.433194 +vt 0.646923 0.013038 +vt 0.646828 0.011989 +vt 0.646508 0.012043 +vt 0.646620 0.013201 +vt 0.647602 0.012998 +vt 0.647406 0.013272 +vt 0.215265 0.559994 +vt 0.215147 0.558600 +vt 0.215017 0.558600 +vt 0.215136 0.560021 +vt 0.215265 0.557255 +vt 0.215137 0.557228 +vt 0.701242 0.773498 +vt 0.699844 0.773502 +vt 0.699840 0.774462 +vt 0.701242 0.774458 +vt 0.702641 0.773504 +vt 0.702645 0.774464 +vt 0.215395 0.702067 +vt 0.215395 0.700633 +vt 0.752053 0.603524 +vt 0.750544 0.603667 +vt 0.864076 0.440735 +vt 0.865592 0.440766 +vt 0.865577 0.439785 +vt 0.864072 0.439773 +vt 0.862525 0.440732 +vt 0.862521 0.439771 +vt 0.310872 0.248015 +vt 0.311408 0.246725 +vt 0.215299 0.558604 +vt 0.215411 0.557330 +vt 0.215411 0.559923 +vt 0.750604 0.607472 +vt 0.752005 0.606980 +vt 0.215133 0.699150 +vt 0.215136 0.700495 +vt 0.215270 0.700574 +vt 0.215267 0.699146 +vt 0.750630 0.607605 +vt 0.312800 0.246253 +vt 0.312838 0.246117 +vt 0.215136 0.697767 +vt 0.215133 0.699112 +vt 0.215267 0.699116 +vt 0.215270 0.697688 +vt 0.752490 0.605648 +vt 0.752659 0.605643 +vt 0.752795 0.605637 +vt 0.752734 0.604038 +vt 0.649201 0.012922 +vt 0.649201 0.013232 +vt 0.650801 0.013000 +vt 0.650997 0.013274 +vt 0.649201 0.013722 +vt 0.651323 0.013690 +vt 0.647079 0.013688 +vt 0.646501 0.014501 +vt 0.649201 0.014656 +vt 0.651904 0.014503 +vt 0.862520 0.434287 +vt 0.864071 0.434286 +vt 0.864075 0.433323 +vt 0.862524 0.433326 +vt 0.865577 0.434273 +vt 0.865591 0.433292 +vt 0.312782 0.250053 +vt 0.314282 0.250190 +vt 0.215395 0.703580 +vt 0.215395 0.702146 +vt 0.315006 0.248076 +vt 0.315006 0.246476 +vt 0.314961 0.249673 +vt 0.649201 0.005488 +vt 0.650800 0.005410 +vt 0.650997 0.005137 +vt 0.649201 0.005177 +vt 0.647602 0.005409 +vt 0.647405 0.005135 +vt 0.996058 0.794221 +vt 0.997583 0.793981 +vt 0.997588 0.792514 +vt 0.996230 0.792568 +vt 0.999358 0.793954 +vt 0.999343 0.792497 +vt 0.999242 0.791120 +vt 0.997524 0.791179 +vt 0.996449 0.791461 +vt 0.995701 0.681052 +vt 0.995921 0.681892 +vt 0.997248 0.681791 +vt 0.997228 0.680812 +vt 0.995947 0.683373 +vt 0.997254 0.683347 +vt 0.999003 0.683343 +vt 0.999003 0.681776 +vt 0.999003 0.680784 +vt 0.997233 0.679345 +vt 0.995873 0.679398 +vt 0.998989 0.679327 +vt 0.998885 0.677951 +vt 0.997167 0.678009 +vt 0.996091 0.678291 +vt 0.651782 0.005209 +vt 0.652203 0.004985 +vt 0.651323 0.004722 +vt 0.651894 0.006366 +vt 0.652323 0.006296 +vt 0.995364 0.682123 +vt 0.995380 0.683434 +vt 0.652613 0.004759 +vt 0.651904 0.003917 +vt 0.649201 0.004688 +vt 0.647079 0.004720 +vt 0.649202 0.003755 +vt 0.646502 0.003914 +vt 0.996277 0.795062 +vt 0.997603 0.794960 +vt 0.996303 0.796542 +vt 0.997609 0.796516 +vt 0.999358 0.796512 +vt 0.999358 0.794946 +vt 0.646508 0.006363 +vt 0.646620 0.005206 +vt 0.646199 0.004981 +vt 0.646079 0.006292 +vt 0.645794 0.004755 +vt 0.995737 0.802427 +vt 0.995721 0.803738 +vt 0.996277 0.803968 +vt 0.996303 0.802488 +vt 0.997603 0.804070 +vt 0.996058 0.804808 +vt 0.997583 0.805049 +vt 0.999358 0.805076 +vt 0.999358 0.804084 +vt 0.995947 0.689318 +vt 0.995921 0.690799 +vt 0.997248 0.690901 +vt 0.995701 0.691639 +vt 0.997228 0.691880 +vt 0.999003 0.691907 +vt 0.999003 0.690915 +vt 0.869377 0.439785 +vt 0.869392 0.440766 +vt 0.870043 0.440865 +vt 0.870047 0.439816 +vt 0.314343 0.245940 +vt 0.314992 0.245797 +vt 0.646922 0.005367 +vt 0.646828 0.006416 +vt 0.651895 0.012047 +vt 0.651783 0.013203 +vt 0.652204 0.013429 +vt 0.652323 0.012119 +vt 0.652613 0.013665 +vt 0.995380 0.689257 +vt 0.995364 0.690568 +vt 0.866243 0.440865 +vt 0.866247 0.439816 +vt 0.752693 0.603359 +vt 0.651480 0.013041 +vt 0.651574 0.011992 +vt 0.646200 0.013426 +vt 0.646080 0.012115 +vt 0.995721 0.795292 +vt 0.995737 0.796603 +vt 0.645794 0.013662 +vt 0.314927 0.250352 +vt 0.866247 0.434242 +vt 0.866243 0.433194 +vt 0.651479 0.005370 +vt 0.651574 0.006419 +vt 0.866321 0.434287 +vt 0.867871 0.434286 +vt 0.867875 0.433323 +vt 0.866325 0.433326 +vt 0.750619 0.607686 +vt 0.215395 0.700604 +vt 0.215395 0.699171 +vt 0.702645 0.779948 +vt 0.701242 0.779942 +vt 0.701242 0.780902 +vt 0.702641 0.780908 +vt 0.699840 0.779946 +vt 0.699844 0.780906 +vt 0.215292 0.561449 +vt 0.215412 0.560077 +vt 0.215412 0.562871 +vt 0.646079 0.009204 +vt 0.646508 0.009203 +vt 0.996303 0.799515 +vt 0.995737 0.799515 +vt 0.997609 0.799515 +vt 0.997254 0.686346 +vt 0.995947 0.686346 +vt 0.870047 0.437029 +vt 0.869377 0.437029 +vt 0.646828 0.009202 +vt 0.652323 0.009207 +vt 0.651895 0.009206 +vt 0.995380 0.686346 +vt 0.866247 0.437029 +vt 0.865577 0.437029 +vt 0.651574 0.009205 +vt 0.864071 0.437029 +vt 0.862521 0.437029 +vt 0.701242 0.777200 +vt 0.699840 0.777204 +vt 0.702645 0.777206 +vt 0.867871 0.437029 +vt 0.866322 0.437029 +vt 0.866322 0.439771 +vt 0.867872 0.439773 +vt 0.215395 0.699091 +vt 0.215395 0.697659 +vt 0.312839 0.246033 +vt 0.867876 0.440735 +vt 0.866326 0.440732 +vt 0.296141 0.246108 +vt 0.295965 0.247938 +vt 0.297200 0.247914 +vt 0.297179 0.245585 +vt 0.296173 0.249773 +vt 0.297219 0.250263 +vt 0.298937 0.250348 +vt 0.298937 0.247895 +vt 0.298894 0.245461 +vt 0.299217 0.245986 +vt 0.298997 0.247812 +vt 0.300272 0.247850 +vt 0.300292 0.245513 +vt 0.299112 0.249651 +vt 0.300157 0.250189 +vt 0.301861 0.250348 +vt 0.302001 0.247905 +vt 0.302001 0.245462 +vt 0.649201 0.016184 +vt 0.651572 0.016159 +vt 0.646833 0.016156 +vt 0.647370 0.017265 +vt 0.649203 0.017489 +vt 0.651037 0.017267 +vt 0.997589 0.806516 +vt 0.999343 0.806533 +vt 0.996231 0.806462 +vt 0.996450 0.807568 +vt 0.997525 0.807851 +vt 0.999242 0.807909 +vt 0.997233 0.693346 +vt 0.998989 0.693364 +vt 0.995873 0.693292 +vt 0.996092 0.694399 +vt 0.997168 0.694681 +vt 0.998886 0.694740 +vt 0.649203 0.002230 +vt 0.646835 0.002262 +vt 0.651574 0.002265 +vt 0.651039 0.001160 +vt 0.649205 0.000934 +vt 0.647372 0.001158 +vn -0.9948 -0.0168 -0.1005 +vn -0.9919 0.0762 -0.1015 +vn -1.0000 -0.0009 -0.0007 +vn -1.0000 -0.0007 -0.0003 +vn -1.0000 -0.0009 0.0001 +vn -0.9919 0.0762 -0.1016 +vn -1.0000 -0.0002 -0.0005 +vn -1.0000 -0.0008 -0.0006 +vn 0.9948 -0.0156 -0.1006 +vn 0.9945 -0.0843 -0.0618 +vn 1.0000 0.0001 -0.0002 +vn 0.9948 -0.0155 -0.1004 +vn 1.0000 0.0000 0.0001 +vn 1.0000 0.0003 -0.0001 +vn 0.9945 -0.0845 -0.0613 +vn 0.9948 -0.1003 0.0163 +vn 1.0000 0.0001 0.0005 +vn -0.9948 -0.1008 0.0151 +vn -1.0000 -0.0001 0.0000 +vn -1.0000 -0.0000 -0.0003 +vn -0.9945 -0.0848 -0.0616 +vn -0.9948 -0.0163 -0.1006 +vn -1.0000 -0.0004 0.0001 +vn -1.0000 -0.0002 0.0003 +vn -0.9897 0.0276 0.1406 +vn -0.9919 -0.0730 0.1039 +vn -1.0000 -0.0007 -0.0005 +vn -1.0000 -0.0007 -0.0004 +vn -1.0000 -0.0006 0.0000 +vn -1.0000 -0.0008 -0.0005 +vn 0.9896 0.0289 0.1407 +vn 0.9852 0.1389 0.1008 +vn 0.9896 0.1427 -0.0161 +vn 1.0000 0.0001 0.0004 +vn -0.9897 0.1422 -0.0173 +vn -0.9852 0.1388 0.1003 +vn -1.0000 -0.0000 -0.0001 +vn -1.0000 -0.0001 0.0001 +vn -1.0000 -0.0003 -0.0006 +vn -0.9852 0.1386 0.1007 +vn -0.9897 0.0275 0.1406 +vn -1.0000 -0.0007 -0.0001 +vn 0.9919 -0.0714 0.1050 +vn 1.0000 0.0010 0.0007 +vn 1.0000 0.0005 0.0000 +vn 1.0000 0.0008 0.0006 +vn 0.9919 0.0778 -0.1004 +vn 1.0000 0.0007 0.0005 +vn 0.9896 0.1428 -0.0161 +vn 1.0000 0.0005 0.0006 +vn 1.0000 0.0002 0.0010 +vn 0.9919 0.0777 -0.1005 +vn 1.0000 0.0006 0.0001 +vn 1.0000 0.0008 0.0005 +vn -0.0085 0.8487 0.5287 +vn -0.0023 0.8162 0.5777 +vn 0.0000 0.8151 0.5794 +vn 0.0085 -0.7622 -0.6473 +vn 0.0023 -0.7989 -0.6015 +vn 0.0000 -0.8001 -0.5998 +vn -0.7277 -0.2945 0.6195 +vn -0.9830 0.1483 0.1083 +vn -0.9993 -0.0304 -0.0222 +vn -0.7542 -0.4080 0.5145 +vn -0.7277 0.4978 -0.4719 +vn -0.7542 0.3628 -0.5473 +vn -0.7219 0.1868 -0.6663 +vn -0.9422 -0.2711 -0.1968 +vn -0.7219 -0.5758 0.3839 +vn -0.1120 0.9744 -0.1950 +vn -0.4172 0.8443 -0.3362 +vn 0.0705 0.5394 -0.8391 +vn 0.0056 0.5666 -0.8240 +vn -0.6943 0.5616 -0.4501 +vn 0.0547 0.5866 -0.8080 +vn 0.7219 0.1868 -0.6663 +vn 0.4618 -0.0804 -0.8833 +vn 0.1216 -0.1601 -0.9796 +vn 0.7219 -0.5757 0.3839 +vn 0.9422 -0.2710 -0.1968 +vn 0.9993 -0.0299 -0.0220 +vn 0.7542 -0.4077 0.5147 +vn 0.7542 0.3631 -0.5471 +vn 0.7274 0.4993 -0.4708 +vn 0.9825 0.1508 0.1093 +vn 0.7274 -0.2931 0.6205 +vn -0.0938 0.1903 0.9772 +vn -0.1428 0.8011 0.5813 +vn -0.6880 0.5873 0.4264 +vn -0.5071 0.0333 0.8613 +vn -0.0938 0.9881 -0.1217 +vn -0.5070 0.8292 -0.2351 +vn -0.6879 0.5873 0.4264 +vn -0.5070 0.8293 -0.2350 +vn -0.5070 0.0334 0.8613 +vn -0.6934 0.3126 -0.6492 +vn -0.7394 0.4070 -0.5364 +vn -0.9999 0.0134 0.0097 +vn -0.9847 -0.1409 -0.1023 +vn -0.6943 0.5615 -0.4501 +vn -0.9693 0.1991 0.1445 +vn -0.6943 -0.2541 0.6733 +vn -0.7394 -0.3839 0.5531 +vn -0.6934 -0.5205 0.4983 +vn -0.0891 -0.1482 -0.9849 +vn -0.4086 0.1203 -0.9047 +vn -0.6848 -0.5897 -0.4282 +vn -0.1163 -0.8038 -0.5834 +vn -0.4085 0.1203 -0.9048 +vn -0.6848 -0.5897 -0.4281 +vn -0.4086 -0.8230 0.3946 +vn -0.4085 -0.8230 0.3946 +vn -0.0891 -0.9824 0.1641 +vn 0.6943 -0.2540 0.6733 +vn 0.7394 -0.3836 0.5533 +vn -0.0176 -0.5897 0.8074 +vn -0.0548 -0.5866 0.8080 +vn 0.6941 -0.5189 0.4990 +vn -0.0416 -0.5936 0.8037 +vn -0.7542 -0.4080 0.5144 +vn -0.7218 -0.5758 0.3840 +vn 0.6941 0.3137 -0.6479 +vn 0.7394 0.4072 -0.5361 +vn -0.0176 0.5850 -0.8108 +vn -0.0416 0.5803 -0.8133 +vn 0.6943 0.5616 -0.4500 +vn -0.0547 0.5866 -0.8080 +vn 0.1216 -0.9810 0.1511 +vn 0.1694 -0.7975 -0.5791 +vn 0.6009 -0.6468 -0.4696 +vn 0.4618 -0.8648 0.1971 +vn 0.1216 -0.1600 -0.9796 +vn 0.4172 0.8443 -0.3362 +vn -0.0705 0.5395 -0.8390 +vn 0.1120 0.9744 -0.1950 +vn -0.0055 0.5665 -0.8240 +vn -0.1216 -0.1601 -0.9796 +vn -0.4618 -0.0804 -0.8833 +vn -0.7394 -0.3840 0.5531 +vn 0.0178 -0.5897 0.8074 +vn 0.0420 -0.5935 0.8037 +vn -0.6943 -0.2540 0.6733 +vn 0.0547 -0.5866 0.8080 +vn 0.7543 -0.4077 0.5146 +vn -0.7394 0.4070 -0.5363 +vn 0.0178 0.5850 -0.8108 +vn 0.0420 0.5804 -0.8133 +vn 0.7274 0.4992 -0.4708 +vn 0.7543 0.3630 -0.5470 +vn 0.0681 -0.5280 0.8465 +vn -0.0094 -0.5555 0.8315 +vn 0.5054 0.0348 0.8622 +vn 0.0931 0.1905 0.9773 +vn 0.0898 -0.1477 -0.9849 +vn 0.4098 0.1220 -0.9040 +vn -0.0684 0.6413 -0.7642 +vn 0.0094 0.6187 -0.7856 +vn -0.5071 0.8293 -0.2350 +vn -0.4172 0.8443 -0.3363 +vn -0.6653 0.6042 0.4386 +vn -0.1635 0.7983 0.5796 +vn -0.1120 0.1164 0.9869 +vn -0.4173 -0.0583 0.9069 +vn -0.4172 -0.0582 0.9069 +vn 0.6943 0.5616 -0.4501 +vn 0.7394 0.4073 -0.5361 +vn 0.9999 0.0137 0.0101 +vn 0.9692 0.1992 0.1446 +vn 0.6941 0.3138 -0.6479 +vn 0.9852 -0.1390 -0.1008 +vn 0.6942 -0.5189 0.4989 +vn 0.6943 -0.2540 0.6734 +vn 0.4173 0.8443 -0.3362 +vn 0.6653 0.6042 0.4386 +vn 0.1635 0.7984 0.5796 +vn 0.4172 -0.0582 0.9069 +vn 0.1120 0.1164 0.9869 +vn -0.0705 -0.6307 0.7728 +vn -0.0056 -0.6080 0.7939 +vn -0.4618 -0.8648 0.1971 +vn -0.1216 -0.9810 0.1512 +vn -0.4173 -0.0582 0.9069 +vn 0.0705 -0.6307 0.7728 +vn -0.1120 0.1163 0.9869 +vn 0.0055 -0.6081 0.7939 +vn 0.1216 -0.9810 0.1512 +vn 0.0000 0.8092 0.5875 +vn -0.0000 0.9844 -0.1757 +vn 0.0000 0.1378 0.9905 +vn -0.0000 0.5792 -0.8152 +vn 0.0000 -0.1553 -0.9879 +vn 0.0000 -0.5957 0.8032 +vn -0.0000 -0.9874 0.1583 +vn -0.0000 -0.8092 -0.5875 +vn 0.0000 -0.1552 -0.9879 +vn -0.1694 -0.7976 -0.5790 +vn -0.6009 -0.6469 -0.4696 +vn 0.0676 0.6417 -0.7640 +vn -0.0093 0.6186 -0.7857 +vn 0.0931 0.9882 -0.1215 +vn 0.5054 0.8306 -0.2339 +vn 0.1215 -0.2048 -0.9712 +vn 0.0171 -0.2036 -0.9789 +vn 0.0184 -0.8090 -0.5875 +vn 0.1270 -0.8027 -0.5827 +vn 0.0171 -0.9938 0.1096 +vn 0.1215 -0.9869 0.1061 +vn 0.0898 -0.1476 -0.9850 +vn -0.0171 -0.2036 -0.9789 +vn -0.0182 -0.8091 -0.5874 +vn 0.1170 -0.8037 -0.5835 +vn -0.1215 -0.2049 -0.9712 +vn -0.1269 -0.8027 -0.5827 +vn -0.1214 -0.9869 0.1059 +vn -0.0171 -0.9938 0.1095 +vn 0.0898 -0.9823 0.1646 +vn 0.6859 0.5889 0.4275 +vn 0.5053 0.8306 -0.2339 +vn 0.5054 0.8306 -0.2340 +vn 0.1417 0.8009 0.5817 +vn 0.4099 0.1219 -0.9040 +vn 0.6876 -0.5876 -0.4266 +vn 0.4099 0.1220 -0.9039 +vn 0.6875 -0.5876 -0.4266 +vn 0.4099 -0.8218 0.3959 +vn 0.4099 -0.8217 0.3960 +vn 0.4098 -0.8217 0.3960 +vn -0.0682 -0.5279 0.8465 +vn 0.0898 -0.9822 0.1647 +vn 0.0093 -0.5552 0.8317 +vn -0.5071 0.0334 0.8613 +vn 0.0129 0.5846 -0.8112 +vn 0.1215 -0.2047 -0.9712 +vn 0.0964 0.5786 -0.8099 +vn 0.0801 0.9899 -0.1170 +vn 0.0105 0.9934 -0.1142 +vn 0.0132 -0.5903 0.8070 +vn 0.0964 -0.5909 0.8010 +vn 0.0105 0.1990 0.9799 +vn 0.0801 0.1954 0.9775 +vn -0.0171 -0.9938 0.1096 +vn -0.0130 -0.5902 0.8071 +vn -0.1215 -0.9869 0.1059 +vn -0.0964 -0.5911 0.8008 +vn -0.0801 0.1952 0.9775 +vn -0.0105 0.1990 0.9799 +vn -0.1214 -0.2050 -0.9712 +vn -0.0131 0.5847 -0.8111 +vn -0.0964 0.5784 -0.8100 +vn -0.0106 0.9934 -0.1142 +vn -0.0800 0.9899 -0.1171 +vn -0.0800 0.1953 0.9775 +vn -0.0716 0.8072 0.5860 +vn -0.0094 0.8092 0.5874 +vn -0.0801 0.9899 -0.1171 +vn -0.0105 0.9934 -0.1142 +vn -0.7136 0.4101 -0.5680 +vn -0.7578 -0.1300 -0.6394 +vn -0.6833 0.7253 -0.0836 +vn -0.7134 0.4102 -0.5682 +vn -0.6833 0.7254 -0.0836 +vn -0.9897 0.1423 -0.0173 +vn -0.9919 0.0764 -0.1017 +vn 0.7471 -0.5379 -0.3905 +vn 0.7579 -0.1288 -0.6396 +vn 0.7579 -0.6480 0.0756 +vn 0.7577 -0.6482 0.0756 +vn 0.9948 -0.1005 0.0164 +vn 0.7578 -0.1288 -0.6397 +vn 0.9948 -0.0156 -0.1005 +vn -0.7469 -0.5380 -0.3906 +vn -0.7578 -0.6483 0.0744 +vn -0.7578 -0.1301 -0.6394 +vn -0.7470 -0.5380 -0.3906 +vn -0.9945 -0.0848 -0.0615 +vn -0.7579 -0.6482 0.0743 +vn -0.9948 -0.1007 0.0151 +vn -0.7135 -0.4131 0.5659 +vn -0.6833 0.1451 0.7156 +vn -0.7578 -0.6483 0.0743 +vn -0.7134 -0.4131 0.5661 +vn -0.9919 -0.0731 0.1041 +vn 0.0094 0.8092 0.5875 +vn 0.0105 0.1991 0.9799 +vn 0.0716 0.8072 0.5860 +vn 0.0801 0.1953 0.9775 +vn -1.0000 -0.0002 -0.0006 +vn -1.0000 -0.0001 -0.0006 +vn -0.9979 -0.0640 0.0080 +vn -0.9979 -0.0386 0.0521 +vn -1.0000 -0.0005 0.0001 +vn -0.9979 0.0113 0.0633 +vn 0.9945 -0.0847 -0.0614 +vn 1.0000 0.0001 0.0006 +vn 1.0000 -0.0001 0.0000 +vn 0.9987 0.0499 -0.0031 +vn 0.9983 0.0464 0.0366 +vn 1.0000 0.0004 0.0002 +vn 0.9979 0.0123 0.0635 +vn -1.0000 -0.0002 -0.0000 +vn -1.0000 0.0000 -0.0000 +vn -0.9983 0.0461 0.0365 +vn -0.9988 0.0497 -0.0040 +vn -1.0000 -0.0001 -0.0005 +vn -0.9990 0.0257 -0.0365 +vn -1.0000 -0.0006 0.0001 +vn -0.9988 -0.0124 -0.0483 +vn 0.6414 0.6208 0.4507 +vn 0.6832 0.1463 0.7154 +vn 0.6832 0.7255 -0.0824 +vn 0.6413 0.6209 0.4508 +vn 0.6831 0.7256 -0.0825 +vn 0.9851 0.1389 0.1009 +vn 0.6831 0.1463 0.7155 +vn -0.6415 0.6208 0.4507 +vn -0.6833 0.1452 0.7156 +vn -0.9852 0.1387 0.1007 +vn 0.7136 -0.4116 0.5670 +vn 0.7135 -0.4116 0.5670 +vn 0.9919 -0.0715 0.1050 +vn 0.7136 0.4116 -0.5669 +vn 0.6833 0.7255 -0.0824 +vn 0.7579 -0.1287 -0.6395 +vn 0.7135 0.4116 -0.5670 +vn 0.9012 0.3171 0.2955 +vn 0.8391 0.0906 0.5365 +vn 0.9565 0.2911 -0.0180 +vn 0.9229 0.3788 -0.0688 +vn 0.7525 0.4644 0.4669 +vn 0.8391 0.0906 0.5364 +vn 0.9012 0.3170 0.2955 +vn 0.7525 0.4645 0.4669 +vn 0.4979 0.1331 0.8570 +vn -0.9013 0.3169 0.2954 +vn -0.9566 0.2908 -0.0187 +vn -0.8391 0.0900 0.5364 +vn -0.9012 0.3170 0.2955 +vn -0.4978 0.1328 0.8571 +vn -0.7526 0.4643 0.4669 +vn -0.9232 0.3780 -0.0696 +vn -0.9637 0.1564 -0.2165 +vn -0.9565 -0.0731 -0.2823 +vn -0.8798 0.2787 -0.3850 +vn -0.9229 -0.0519 -0.3814 +vn 0.9979 -0.0638 0.0089 +vn 0.9979 -0.0375 0.0528 +vn 0.8297 -0.3275 0.4520 +vn 0.8391 -0.5380 0.0806 +vn 0.8296 -0.3276 0.4521 +vn 0.8391 0.0906 0.5363 +vn 0.4980 0.1332 0.8569 +vn 0.4382 -0.5279 0.7276 +vn 0.4978 -0.8560 0.1392 +vn 1.0000 -0.0000 -0.0000 +vn 1.0000 -0.0000 0.0005 +vn 0.9983 -0.0490 -0.0326 +vn 1.0000 0.0006 -0.0002 +vn 0.9988 -0.0115 -0.0484 +vn -0.9852 0.1386 0.1006 +vn -0.9983 -0.0491 -0.0327 +vn 1.0000 0.0007 -0.0000 +vn 0.9990 0.0268 -0.0358 +vn 0.9232 -0.0509 -0.3810 +vn 0.8132 0.5727 0.1032 +vn 0.4039 0.7377 -0.5410 +vn 0.6204 0.3818 -0.6851 +vn 0.0289 0.9030 0.4288 +vn 0.0297 0.9864 -0.1617 +vn 0.4038 0.7377 -0.5411 +vn 0.4040 0.7376 -0.5410 +vn 0.0297 0.9864 -0.1618 +vn 0.0107 0.7526 -0.6584 +vn 0.0964 0.6774 -0.7293 +vn 0.1777 0.5807 -0.7945 +vn -0.4382 -0.5283 0.7272 +vn -0.9356 0.2070 -0.2860 +vn -0.9315 -0.0633 -0.3581 +vn -0.4979 -0.8560 0.1388 +vn -0.9316 0.3598 -0.0511 +vn -0.9356 0.2069 -0.2860 +vn -0.9315 0.3600 -0.0513 +vn -0.0044 0.9866 -0.1628 +vn -0.0028 0.5875 -0.8092 +vn -0.9316 -0.0634 -0.3580 +vn -0.0046 -0.1507 -0.9886 +vn 0.8683 -0.3080 -0.3888 +vn 0.9316 -0.0627 -0.3580 +vn 0.8134 -0.2752 -0.5125 +vn 0.8683 -0.3081 -0.3888 +vn 0.8684 -0.3079 -0.3886 +vn 0.0287 -0.6873 -0.7258 +vn 0.0127 -0.6416 -0.7669 +vn 0.9315 -0.0628 -0.3582 +vn 0.0044 -0.1508 -0.9886 +vn -0.8297 -0.3283 0.4515 +vn -0.8391 -0.5380 0.0800 +vn -0.8296 -0.3283 0.4515 +vn -0.8392 -0.5379 0.0799 +vn -0.8390 0.0900 0.5366 +vn 0.9013 -0.3791 -0.2098 +vn 0.9566 -0.0723 -0.2822 +vn 0.8391 -0.5379 0.0806 +vn 0.7526 -0.5878 -0.2969 +vn -0.9012 -0.3791 -0.2099 +vn -0.7524 -0.5879 -0.2970 +vn -0.8392 -0.5379 0.0801 +vn -0.9012 -0.3792 -0.2099 +vn -0.7524 -0.5879 -0.2971 +vn -0.4980 -0.8560 0.1388 +vn 0.9637 0.1574 -0.2158 +vn 0.8799 0.2797 -0.3842 +vn 0.5486 0.4916 -0.6763 +vn 0.6204 0.5338 -0.5746 +vn 0.5485 0.4916 -0.6763 +vn 0.1062 0.5844 -0.8045 +vn 0.1780 0.5759 -0.7979 +vn 0.1503 0.5810 -0.7999 +vn 0.2117 0.4743 -0.8545 +vn 0.2117 0.6661 -0.7152 +vn 0.2737 0.8949 -0.3525 +vn 0.1747 0.5787 -0.7966 +vn 0.2734 0.0602 -0.9600 +vn -0.0045 -0.1507 -0.9886 +vn -0.0129 -0.6418 -0.7668 +vn -0.8683 -0.3081 -0.3886 +vn -0.9315 -0.0634 -0.3581 +vn -0.0289 -0.6873 -0.7258 +vn -0.8132 -0.2755 -0.5126 +vn -0.8683 -0.3082 -0.3887 +vn -0.9316 -0.0633 -0.3579 +vn -0.5485 0.4908 -0.6769 +vn -0.6204 0.3810 -0.6855 +vn -0.6203 0.5331 -0.5753 +vn -0.5486 0.4908 -0.6769 +vn -0.6203 0.5332 -0.5753 +vn -0.1777 0.5755 -0.7982 +vn -0.1062 0.5840 -0.8048 +vn -0.6204 0.3810 -0.6856 +vn -0.1781 0.5803 -0.7947 +vn 0.2736 0.8949 -0.3525 +vn 0.1681 0.9279 0.3328 +vn 0.3649 0.8934 0.2622 +vn 0.3018 0.8838 -0.3575 +vn 0.0750 0.8364 0.5430 +vn 0.3750 0.7888 0.4869 +vn 0.8427 0.4680 0.2661 +vn 0.8076 0.5823 0.0930 +vn 0.6449 0.6853 -0.3382 +vn -0.2730 0.0599 -0.9602 +vn -0.2201 -0.3775 -0.8995 +vn -0.1043 -0.7056 -0.7009 +vn -0.1678 -0.6002 -0.7820 +vn -0.0215 -0.5351 -0.8445 +vn -0.0086 -0.7621 -0.6474 +vn -0.0024 -0.7989 -0.6014 +vn -0.0186 -0.7906 -0.6121 +vn -0.0750 -0.7720 -0.6312 +vn -0.3645 -0.5228 -0.7706 +vn -0.3012 0.0680 -0.9511 +vn -0.3745 -0.7044 -0.6030 +vn -0.8420 -0.3969 -0.3653 +vn -0.8072 -0.2669 -0.5264 +vn -0.6445 0.1105 -0.7566 +vn -0.0963 0.4837 -0.8699 +vn -0.1876 0.1505 -0.9706 +vn -0.2115 0.4739 -0.8548 +vn -0.0106 0.3931 -0.9194 +vn -0.0178 0.0596 -0.9981 +vn -0.1876 0.1505 -0.9707 +vn -0.0177 0.0596 -0.9981 +vn -0.1502 0.5807 -0.8001 +vn -0.2120 0.6658 -0.7154 +vn -0.1748 0.5783 -0.7969 +vn -0.2740 0.8947 -0.3527 +vn 0.2207 0.9718 0.0837 +vn 0.1044 0.8827 0.4583 +vn 0.0216 0.9676 0.2515 +vn 0.0086 0.8488 0.5287 +vn 0.0025 0.8162 0.5778 +vn 0.0186 0.8238 0.5665 +vn -0.0104 0.7527 -0.6583 +vn -0.0965 0.6773 -0.7293 +vn -0.1880 0.8769 -0.4423 +vn -0.0176 0.9313 -0.3638 +vn -0.2208 0.9717 0.0838 +vn -0.0176 0.9313 -0.3639 +vn -0.1880 0.8769 -0.4424 +vn -0.0214 0.9676 0.2516 +vn -0.1047 0.8826 0.4583 +vn -0.1685 0.9278 0.3327 +vn -0.0755 0.8363 0.5430 +vn -0.0187 0.8238 0.5666 +vn 0.0214 -0.5352 -0.8444 +vn 0.2203 -0.3775 -0.8994 +vn 0.1044 -0.7056 -0.7009 +vn 0.1682 -0.6001 -0.7820 +vn 0.0754 -0.7720 -0.6311 +vn 0.0187 -0.7906 -0.6120 +vn 0.0023 -0.7989 -0.6014 +vn -0.0287 0.9030 0.4288 +vn -0.8134 0.5725 0.1029 +vn -0.4040 0.7373 -0.5414 +vn -0.0294 0.9864 -0.1617 +vn -0.4041 0.7373 -0.5414 +vn 0.0104 0.3928 -0.9195 +vn 0.0964 0.4838 -0.8699 +vn 0.1877 0.1505 -0.9706 +vn 0.0176 0.0593 -0.9981 +vn 0.0176 0.0594 -0.9981 +vn 0.1877 0.1504 -0.9706 +vn 0.4040 0.2864 -0.8688 +vn 0.0294 -0.1518 -0.9880 +vn 0.4041 0.2864 -0.8687 +vn 0.0294 -0.1517 -0.9880 +vn 0.1878 0.8769 -0.4424 +vn 0.0178 0.9312 -0.3640 +vn 0.1879 0.8769 -0.4424 +vn 0.2207 0.9717 0.0838 +vn -0.4039 0.2860 -0.8690 +vn -0.0297 -0.1516 -0.9880 +vn -0.4038 0.2861 -0.8690 +vn -0.0297 -0.1517 -0.9880 +vn 0.0046 0.9866 -0.1629 +vn 0.0129 0.9278 0.3728 +vn 0.8683 0.4649 0.1726 +vn 0.9316 0.3601 -0.0506 +vn 0.8684 0.4649 0.1726 +vn 0.9316 0.3599 -0.0506 +vn 0.8684 0.4648 0.1726 +vn 0.0028 0.5874 -0.8093 +vn 0.9356 0.2078 -0.2854 +vn 0.9315 -0.0627 -0.3582 +vn 0.9316 0.3600 -0.0506 +vn 0.9316 0.3600 -0.0507 +vn 0.9315 -0.0627 -0.3584 +vn 0.0001 0.9326 -0.3609 +vn 0.0001 0.7566 -0.6538 +vn 0.0001 0.9639 0.2662 +vn 0.0000 0.8449 0.5349 +vn 0.0000 0.8151 0.5793 +vn -0.0000 -0.7669 -0.6417 +vn -0.0001 -0.5480 -0.8365 +vn 0.0001 0.9881 -0.1537 +vn 0.0001 0.9065 0.4222 +vn 0.0001 0.9881 -0.1538 +vn -0.0001 0.0562 -0.9984 +vn -0.0001 0.3875 -0.9219 +vn -0.0001 -0.1598 -0.9871 +vn -0.0001 -0.6822 -0.7312 +vn -0.0001 -0.6383 -0.7698 +vn -0.0000 -0.1499 -0.9887 +vn -0.0000 0.5875 -0.8092 +vn 0.0000 0.9865 -0.1637 +vn -0.0001 -0.1499 -0.9887 +vn 0.0001 0.9296 0.3685 +vn 0.0001 0.9865 -0.1637 +vn -0.0044 0.9867 -0.1628 +vn -0.0127 0.9279 0.3726 +vn -0.8685 0.4648 0.1724 +vn -0.9316 0.3599 -0.0513 +vn -0.8684 0.4649 0.1724 +vn -0.9315 0.3600 -0.0512 +vn 0.6448 0.1112 -0.7562 +vn 0.6922 0.4245 -0.5837 +vn 0.9769 0.1261 -0.1726 +vn 0.8077 -0.2663 -0.5261 +vn 0.6449 0.6853 -0.3383 +vn 0.8427 0.4680 0.2662 +vn 0.9990 0.0268 -0.0370 +vn 0.8426 -0.3962 -0.3648 +vn -0.6452 0.6848 -0.3388 +vn -0.6922 0.4238 -0.5842 +vn -0.9769 0.1252 -0.1732 +vn -0.8081 0.5817 0.0926 +vn -0.9990 0.0263 -0.0374 +vn -0.8432 0.4673 0.2657 +vn 0.2279 0.5723 -0.7878 +vn 0.3015 0.0683 -0.9510 +vn -0.3654 0.8932 0.2620 +vn -0.3755 0.7886 0.4869 +vn -0.3021 0.8836 -0.3578 +vn -0.6452 0.6848 -0.3387 +vn 0.3650 -0.5226 -0.7705 +vn 0.3751 -0.7042 -0.6029 +vn 0.8077 -0.2663 -0.5260 +vn -0.2278 0.5719 -0.7880 +vn -0.3021 0.8835 -0.3579 +usemtl Scene_-_Root +s off +f 47138/46884/35662 47136/46885/35663 47168/46886/35664 +f 47138/46884/35662 47168/46886/35665 47169/46887/35666 +f 47136/46885/35667 47170/46888/35668 47168/46886/35669 +f 47147/46889/35670 47145/46890/35671 47174/46891/35672 +f 47147/46889/35673 47174/46891/35674 47175/46892/35675 +f 47145/46890/35676 47144/46893/35677 47176/46894/35678 +f 47154/46895/35679 47180/46896/35680 47181/46897/35681 +f 47152/46898/35682 47138/46884/35683 47169/46887/35684 +f 47152/46898/35682 47169/46887/35685 47180/46896/35685 +f 47161/46899/35686 47159/46900/35687 47184/46901/35688 +f 47161/46899/35686 47184/46901/35689 47185/46902/35690 +f 47159/46900/35687 47181/46897/35668 47184/46901/35691 +f 47196/46903/35692 47244/46904/35674 47245/46905/35675 +f 47194/46906/35693 47193/46907/35694 47246/46908/35695 +f 47135/46909/35696 47201/46910/35697 47249/46911/35698 +f 47135/46909/35696 47249/46911/35699 47170/46888/35700 +f 47201/46910/35701 47161/46899/35702 47185/46902/35703 +f 47144/46893/35677 47206/46912/35704 47251/46913/35705 +f 47206/46912/35704 47245/46905/35706 47251/46913/35707 +f 47193/46907/35694 47211/46914/35708 47253/46915/35709 +f 47193/46907/35710 47253/46915/35711 47246/46908/35712 +f 47211/46914/35713 47175/46892/35714 47253/46915/35715 +f 47394/46916/35716 47399/46917/35717 47460/46918/35718 +f 47403/46919/35719 47408/46920/35720 47463/46921/35721 +s 1 +f 46884/46922/35722 46885/46923/35723 46886/46924/35724 +f 46884/46922/35722 46886/46924/35724 46887/46925/35725 +f 46885/46923/35723 46888/46926/35726 46889/46927/35727 +f 46885/46923/35723 46889/46927/35727 46886/46924/35724 +f 46886/46924/35724 46889/46927/35727 46890/46928/35728 +f 46886/46924/35724 46890/46928/35728 46891/46929/35729 +f 46887/46925/35725 46886/46924/35724 46891/46929/35729 +f 46887/46925/35725 46891/46929/35729 46892/46930/35730 +f 46893/46931/35731 46894/46932/35732 46895/46933/35733 +f 46893/46931/35731 46895/46933/35733 46896/46934/35734 +f 46894/46932/35732 46897/46935/35735 46898/46936/35736 +f 46894/46932/35732 46898/46936/35736 46895/46933/35733 +f 46895/46933/35733 46898/46936/35736 46899/46937/35737 +f 46895/46933/35733 46899/46937/35737 46900/46938/35738 +f 46896/46934/35734 46895/46933/35733 46900/46938/35738 +f 46896/46934/35734 46900/46938/35738 46901/46939/35739 +f 46902/46940/35740 46903/46941/35741 46904/46942/35742 +f 46902/46940/35740 46904/46942/35742 46905/46943/35743 +f 46903/46941/35741 46906/46944/35737 46907/46945/35744 +f 46903/46941/35741 46907/46945/35744 46904/46942/35742 +f 46904/46942/35742 46907/46945/35744 46908/46946/35745 +f 46904/46942/35742 46908/46946/35745 46909/46947/35746 +f 46905/46943/35743 46904/46942/35742 46909/46947/35746 +f 46905/46943/35743 46909/46947/35746 46910/46948/35747 +f 46911/46949/35748 46912/46950/35749 46913/46951/35750 +f 46911/46949/35748 46913/46951/35750 46914/46952/35751 +f 46912/46950/35749 46915/46953/35752 46916/46954/35753 +f 46912/46950/35749 46916/46954/35753 46913/46951/35750 +f 46917/46955/35754 46918/46956/35755 46888/46926/35726 +f 46917/46955/35754 46888/46926/35726 46885/46923/35723 +f 46919/46957/35756 46917/46955/35754 46885/46923/35723 +f 46919/46957/35756 46885/46923/35723 46884/46922/35722 +f 46920/46958/35757 46921/46959/35758 46922/46960/35759 +f 46920/46958/35757 46922/46960/35759 46923/46961/35760 +f 46921/46959/35758 46924/46962/35761 46925/46963/35762 +f 46921/46959/35758 46925/46963/35762 46922/46960/35759 +f 46922/46960/35759 46925/46963/35762 46926/46964/35763 +f 46922/46960/35759 46926/46964/35763 46927/46965/35764 +f 46923/46961/35760 46922/46960/35759 46927/46965/35764 +f 46923/46961/35760 46927/46965/35764 46928/46966/35765 +f 46929/46967/35766 46930/46968/35767 46931/46969/35768 +f 46929/46967/35766 46931/46969/35768 46932/46970/35769 +f 46933/46971/35770 46920/46958/35757 46923/46961/35760 +f 46933/46971/35770 46923/46961/35760 46934/46972/35771 +f 46934/46972/35771 46923/46961/35760 46928/46966/35765 +f 46934/46972/35771 46928/46966/35765 46935/46973/35772 +f 46932/46970/35769 46931/46969/35768 46936/46974/35773 +f 46932/46970/35769 46936/46974/35773 46937/46975/35774 +f 46938/46976/35775 46939/46977/35776 46940/46978/35777 +f 46938/46976/35775 46940/46978/35777 46941/46979/35778 +f 46939/46977/35776 46942/46980/35779 46943/46981/35780 +f 46939/46977/35776 46943/46981/35780 46940/46978/35777 +f 46940/46978/35777 46943/46981/35780 46944/46982/35722 +f 46940/46978/35777 46944/46982/35722 46945/46983/35781 +f 46941/46979/35778 46940/46978/35777 46945/46983/35781 +f 46941/46979/35778 46945/46983/35781 46946/46984/35782 +f 46947/46985/35783 46948/46986/35784 46949/46987/35785 +f 46947/46985/35783 46949/46987/35785 46950/46988/35786 +f 46948/46986/35784 46951/46989/35787 46952/46990/35788 +f 46948/46986/35784 46952/46990/35788 46949/46987/35785 +f 46949/46987/35785 46952/46990/35788 46953/46991/35728 +f 46949/46987/35785 46953/46991/35728 46954/46992/35727 +f 46950/46988/35786 46949/46987/35785 46954/46992/35727 +f 46950/46988/35786 46954/46992/35727 46955/46993/35726 +f 46956/46994/35789 46957/46995/35790 46958/46996/35791 +f 46956/46994/35789 46958/46996/35791 46959/46997/35792 +f 46957/46995/35790 46960/46998/35793 46961/46999/35738 +f 46957/46995/35790 46961/46999/35738 46958/46996/35791 +f 46962/47000/35791 46963/47001/35738 46906/46944/35737 +f 46962/47000/35791 46906/46944/35737 46903/46941/35741 +f 46964/47002/35792 46962/47000/35791 46903/46941/35741 +f 46964/47002/35792 46903/46941/35741 46902/46940/35740 +f 46951/46989/35787 46965/47003/35794 46966/47004/35795 +f 46951/46989/35787 46966/47004/35795 46952/46990/35788 +f 46965/47003/35794 46967/47005/35796 46968/47006/35797 +f 46965/47003/35794 46968/47006/35797 46966/47004/35795 +f 46966/47004/35795 46968/47006/35797 46969/47007/35798 +f 46966/47004/35795 46969/47007/35798 46970/47008/35799 +f 46952/46990/35788 46966/47004/35795 46970/47008/35799 +f 46952/46990/35788 46970/47008/35799 46953/46991/35728 +f 46971/47009/35765 46972/47010/35800 46973/47011/35801 +f 46971/47009/35765 46973/47011/35801 46974/47012/35802 +f 46972/47010/35800 46975/47013/35803 46976/47014/35804 +f 46972/47010/35800 46976/47014/35804 46973/47011/35801 +f 46973/47011/35801 46976/47014/35804 46977/47015/35740 +f 46973/47011/35801 46977/47015/35740 46978/47016/35805 +f 46974/47012/35802 46973/47011/35801 46978/47016/35805 +f 46974/47012/35802 46978/47016/35805 46979/47017/35747 +f 46897/46935/35735 46980/47018/35806 46981/47019/35807 +f 46897/46935/35735 46981/47019/35807 46898/46936/35736 +f 46980/47018/35806 46982/47020/35757 46983/47021/35808 +f 46980/47018/35806 46983/47021/35808 46981/47019/35807 +f 46981/47019/35807 46983/47021/35808 46984/47022/35809 +f 46981/47019/35807 46984/47022/35809 46985/47023/35810 +f 46898/46936/35736 46981/47019/35807 46985/47023/35810 +f 46898/46936/35736 46985/47023/35810 46899/46937/35737 +f 46986/47024/35774 46987/47025/35773 46988/47026/35811 +f 46986/47024/35774 46988/47026/35811 46989/47027/35812 +f 46987/47025/35773 46971/47009/35765 46974/47012/35802 +f 46987/47025/35773 46974/47012/35802 46988/47026/35811 +f 46988/47026/35811 46974/47012/35802 46979/47017/35747 +f 46988/47026/35811 46979/47017/35747 46990/47028/35813 +f 46989/47027/35812 46988/47026/35811 46990/47028/35813 +f 46989/47027/35812 46990/47028/35813 46991/47029/35814 +f 46992/47030/35815 46993/47031/35816 46994/47032/35817 +f 46992/47030/35815 46994/47032/35817 46995/47033/35818 +f 46993/47031/35816 46947/46985/35783 46950/46988/35786 +f 46993/47031/35816 46950/46988/35786 46994/47032/35817 +f 46994/47032/35817 46950/46988/35786 46955/46993/35726 +f 46994/47032/35817 46955/46993/35726 46996/47034/35819 +f 46995/47033/35818 46994/47032/35817 46996/47034/35819 +f 46995/47033/35818 46996/47034/35819 46997/47035/35752 +f 46924/46962/35761 46998/47036/35820 46999/47037/35821 +f 46924/46962/35761 46999/47037/35821 46925/46963/35762 +f 47000/47038/35732 47001/47039/35731 47002/47040/35822 +f 47000/47038/35732 47002/47040/35822 47003/47041/35821 +f 47003/47041/35821 47002/47040/35822 47004/47042/35823 +f 47003/47041/35821 47004/47042/35823 47005/47043/35824 +f 46925/46963/35762 46999/47037/35821 47006/47044/35825 +f 46925/46963/35762 47006/47044/35825 46926/46964/35763 +f 47007/47045/35826 47008/47046/35827 47009/47047/35828 +f 47007/47045/35826 47009/47047/35828 47010/47048/35829 +f 47008/47046/35827 47011/47049/35830 47012/47050/35831 +f 47008/47046/35827 47012/47050/35831 47009/47047/35828 +f 47009/47047/35828 47012/47050/35831 47013/47051/35832 +f 47009/47047/35828 47013/47051/35832 47014/47052/35776 +f 47010/47048/35829 47009/47047/35828 47014/47052/35776 +f 47010/47048/35829 47014/47052/35776 47015/47053/35833 +f 47016/47054/35796 47017/47055/35834 47018/47056/35835 +f 47016/47054/35796 47018/47056/35835 47019/47057/35836 +f 47020/47058/35794 47007/47045/35826 47010/47048/35829 +f 47020/47058/35794 47010/47048/35829 47021/47059/35835 +f 47021/47059/35835 47010/47048/35829 47015/47053/35833 +f 47021/47059/35835 47015/47053/35833 47022/47060/35837 +f 47019/47057/35836 47018/47056/35835 47023/47061/35837 +f 47019/47057/35836 47023/47061/35837 47024/47062/35838 +f 47025/47063/35838 47026/47064/35837 47027/47065/35839 +f 47025/47063/35838 47027/47065/35839 47028/47066/35840 +f 47026/47064/35837 46938/46976/35775 46941/46979/35778 +f 47026/47064/35837 46941/46979/35778 47027/47065/35839 +f 47027/47065/35839 46941/46979/35778 46946/46984/35782 +f 47027/47065/35839 46946/46984/35782 47029/47067/35841 +f 47028/47066/35840 47027/47065/35839 47029/47067/35841 +f 47028/47066/35840 47029/47067/35841 47030/47068/35842 +f 46975/47013/35803 47031/47069/35843 47032/47070/35844 +f 46975/47013/35803 47032/47070/35844 46976/47014/35804 +f 47031/47069/35843 47033/47071/35845 47034/47072/35846 +f 47031/47069/35843 47034/47072/35846 47032/47070/35844 +f 47032/47070/35844 47034/47072/35846 47035/47073/35847 +f 47032/47070/35844 47035/47073/35847 47036/47074/35792 +f 46976/47014/35804 47032/47070/35844 47036/47074/35792 +f 46976/47014/35804 47036/47074/35792 46977/47015/35740 +f 47016/47054/35796 47019/47057/35836 47037/47075/35848 +f 47016/47054/35796 47037/47075/35848 47038/47076/35849 +f 47019/47057/35836 47024/47062/35838 47039/47077/35850 +f 47019/47057/35836 47039/47077/35850 47037/47075/35848 +f 47037/47075/35848 47039/47077/35850 47004/47042/35823 +f 47037/47075/35848 47004/47042/35823 47002/47040/35822 +f 47038/47076/35849 47037/47075/35848 47002/47040/35822 +f 47038/47076/35849 47002/47040/35822 47001/47039/35731 +f 46893/46931/35731 46896/46934/35734 47040/47078/35851 +f 46893/46931/35731 47040/47078/35851 47041/47079/35849 +f 46896/46934/35734 46901/46939/35739 47042/47080/35852 +f 46896/46934/35734 47042/47080/35852 47040/47078/35851 +f 47040/47078/35851 47042/47080/35852 46969/47007/35798 +f 47040/47078/35851 46969/47007/35798 46968/47006/35797 +f 47041/47079/35849 47040/47078/35851 46968/47006/35797 +f 47041/47079/35849 46968/47006/35797 46967/47005/35796 +f 47025/47063/35838 47028/47066/35840 47043/47081/35853 +f 47025/47063/35838 47043/47081/35853 47044/47082/35850 +f 47028/47066/35840 47030/47068/35842 47045/47083/35854 +f 47028/47066/35840 47045/47083/35854 47043/47081/35853 +f 47043/47081/35853 47045/47083/35854 47035/47073/35847 +f 47043/47081/35853 47035/47073/35847 47034/47072/35846 +f 47044/47082/35850 47043/47081/35853 47034/47072/35846 +f 47044/47082/35850 47034/47072/35846 47033/47071/35845 +f 46960/46998/35793 46957/46995/35790 47046/47084/35855 +f 46960/46998/35793 47046/47084/35855 47047/47085/35856 +f 46957/46995/35790 46956/46994/35789 47048/47086/35854 +f 46957/46995/35790 47048/47086/35854 47046/47084/35855 +f 47046/47084/35855 47048/47086/35854 47049/47087/35842 +f 47046/47084/35855 47049/47087/35842 47050/47088/35857 +f 47047/47085/35856 47046/47084/35855 47050/47088/35857 +f 47047/47085/35856 47050/47088/35857 47051/47089/35798 +f 46892/46930/35730 46891/46929/35729 47052/47090/35858 +f 46892/46930/35730 47052/47090/35858 47053/47091/35841 +f 46891/46929/35729 46890/46928/35728 47054/47092/35799 +f 46891/46929/35729 47054/47092/35799 47052/47090/35858 +f 47055/47093/35858 47056/47094/35799 47051/47089/35798 +f 47055/47093/35858 47051/47089/35798 47050/47088/35857 +f 47057/47095/35841 47055/47093/35858 47050/47088/35857 +f 47057/47095/35841 47050/47088/35857 47049/47087/35842 +f 46982/47020/35757 47058/47096/35770 47059/47097/35859 +f 46982/47020/35757 47059/47097/35859 46983/47021/35808 +f 47058/47096/35770 47060/47098/35766 47061/47099/35860 +f 47058/47096/35770 47061/47099/35860 47059/47097/35859 +f 47059/47097/35859 47061/47099/35860 47062/47100/35861 +f 47059/47097/35859 47062/47100/35861 47063/47101/35862 +f 46983/47021/35808 47059/47097/35859 47063/47101/35862 +f 46983/47021/35808 47063/47101/35862 46984/47022/35809 +f 47064/47102/35863 47065/47103/35864 47066/47104/35865 +f 47064/47102/35863 47066/47104/35865 47067/47105/35866 +f 47065/47103/35864 46929/46967/35766 46932/46970/35769 +f 47065/47103/35864 46932/46970/35769 47066/47104/35865 +f 47066/47104/35865 46932/46970/35769 46937/46975/35774 +f 47066/47104/35865 46937/46975/35774 47068/47106/35867 +f 47067/47105/35866 47066/47104/35865 47068/47106/35867 +f 47067/47105/35866 47068/47106/35867 47069/47107/35868 +f 47070/47108/35869 47071/47109/35870 47072/47110/35871 +f 47070/47108/35869 47072/47110/35871 47073/47111/35872 +f 47071/47109/35870 47074/47112/35873 47075/47113/35874 +f 47071/47109/35870 47075/47113/35874 47072/47110/35871 +f 47072/47110/35871 47075/47113/35874 47076/47114/35875 +f 47072/47110/35871 47076/47114/35875 47077/47115/35876 +f 47073/47111/35872 47072/47110/35871 47077/47115/35876 +f 47073/47111/35872 47077/47115/35876 47078/47116/35877 +f 46910/46948/35747 46909/46947/35746 47079/47117/35878 +f 46910/46948/35747 47079/47117/35878 47080/47118/35813 +f 46909/46947/35746 46908/46946/35745 47081/47119/35879 +f 46909/46947/35746 47081/47119/35879 47079/47117/35878 +f 47082/47120/35878 47083/47121/35880 47084/47122/35861 +f 47082/47120/35878 47084/47122/35861 47085/47123/35881 +f 47086/47124/35813 47082/47120/35878 47085/47123/35881 +f 47086/47124/35813 47085/47123/35881 47087/47125/35814 +f 47011/47049/35830 47088/47126/35882 47089/47127/35883 +f 47011/47049/35830 47089/47127/35883 47012/47050/35831 +f 47090/47128/35884 47070/47108/35869 47073/47111/35872 +f 47090/47128/35884 47073/47111/35872 47091/47129/35885 +f 47091/47129/35885 47073/47111/35872 47078/47116/35877 +f 47091/47129/35885 47078/47116/35877 47092/47130/35886 +f 47012/47050/35831 47089/47127/35883 47093/47131/35887 +f 47012/47050/35831 47093/47131/35887 47013/47051/35832 +f 46942/46980/35779 47094/47132/35888 47095/47133/35889 +f 46942/46980/35779 47095/47133/35889 46943/46981/35780 +f 47094/47132/35888 47096/47134/35890 47097/47135/35891 +f 47094/47132/35888 47097/47135/35891 47095/47133/35889 +f 47095/47133/35889 47097/47135/35891 47098/47136/35748 +f 47095/47133/35889 47098/47136/35748 47099/47137/35892 +f 46943/46981/35780 47095/47133/35889 47099/47137/35892 +f 46943/46981/35780 47099/47137/35892 46944/46982/35722 +f 47060/47098/35766 47100/47138/35864 47101/47139/35893 +f 47060/47098/35766 47101/47139/35893 47061/47099/35860 +f 47100/47138/35864 47102/47140/35894 47103/47141/35895 +f 47100/47138/35864 47103/47141/35895 47101/47139/35893 +f 47101/47139/35893 47103/47141/35895 47104/47142/35896 +f 47101/47139/35893 47104/47142/35896 47105/47143/35897 +f 47061/47099/35860 47101/47139/35893 47105/47143/35897 +f 47061/47099/35860 47105/47143/35897 47062/47100/35861 +f 47106/47144/35868 47107/47145/35867 47108/47146/35898 +f 47106/47144/35868 47108/47146/35898 47109/47147/35899 +f 47107/47145/35867 46986/47024/35774 46989/47027/35812 +f 47107/47145/35867 46989/47027/35812 47108/47146/35898 +f 47108/47146/35898 46989/47027/35812 46991/47029/35814 +f 47108/47146/35898 46991/47029/35814 47110/47148/35900 +f 47109/47147/35899 47108/47146/35898 47110/47148/35900 +f 47109/47147/35899 47110/47148/35900 47111/47149/35901 +f 47096/47134/35890 47112/47150/35902 47113/47151/35903 +f 47096/47134/35890 47113/47151/35903 47097/47135/35891 +f 47112/47150/35902 47114/47152/35904 47115/47153/35905 +f 47112/47150/35902 47115/47153/35905 47113/47151/35903 +f 47113/47151/35903 47115/47153/35905 47116/47154/35906 +f 47113/47151/35903 47116/47154/35906 47117/47155/35907 +f 47097/47135/35891 47113/47151/35903 47117/47155/35907 +f 47097/47135/35891 47117/47155/35907 47098/47136/35748 +f 47118/47156/35908 47119/47157/35870 47120/47158/35909 +f 47118/47156/35908 47120/47158/35909 47121/47159/35910 +f 47119/47157/35870 46992/47030/35815 46995/47033/35818 +f 47119/47157/35870 46995/47033/35818 47120/47158/35909 +f 47120/47158/35909 46995/47033/35818 46997/47035/35752 +f 47120/47158/35909 46997/47035/35752 47122/47160/35911 +f 47121/47159/35910 47120/47158/35909 47122/47160/35911 +f 47121/47159/35910 47122/47160/35911 47123/47161/35912 +f 47124/47162/35913 47125/47163/35914 47126/47164/35915 +f 47124/47162/35913 47126/47164/35915 47127/47165/35907 +f 47125/47163/35914 47128/47166/35916 47129/47167/35917 +f 47125/47163/35914 47129/47167/35917 47126/47164/35915 +f 47126/47164/35915 47129/47167/35917 46915/46953/35752 +f 47126/47164/35915 46915/46953/35752 46912/46950/35749 +f 47127/47165/35907 47126/47164/35915 46912/46950/35749 +f 47127/47165/35907 46912/46950/35749 46911/46949/35748 +f 47118/47156/35908 47121/47159/35910 47130/47168/35918 +f 47118/47156/35908 47130/47168/35918 47131/47169/35919 +f 47121/47159/35910 47123/47161/35912 47132/47170/35920 +f 47121/47159/35910 47132/47170/35920 47130/47168/35918 +f 47133/47171/35921 47134/47172/35922 47135/46909/35923 +f 47133/47171/35921 47135/46909/35923 47136/46885/35924 +f 47137/47173/35919 47133/47171/35921 47136/46885/35924 +f 47137/47173/35919 47136/46885/35924 47138/46884/35662 +f 47064/47102/35863 47067/47105/35866 47139/47174/35925 +f 47064/47102/35863 47139/47174/35925 47140/47175/35926 +f 47067/47105/35866 47069/47107/35868 47141/47176/35927 +f 47067/47105/35866 47141/47176/35927 47139/47174/35925 +f 47142/47177/35925 47143/47178/35928 47144/46893/35929 +f 47142/47177/35925 47144/46893/35929 47145/46890/35676 +f 47146/47179/35930 47142/47177/35925 47145/46890/35676 +f 47146/47179/35930 47145/46890/35676 47147/46889/35931 +f 47076/47114/35875 47075/47113/35874 47148/47180/35932 +f 47076/47114/35875 47148/47180/35932 47149/47181/35933 +f 47075/47113/35874 47074/47112/35873 47150/47182/35934 +f 47075/47113/35874 47150/47182/35934 47148/47180/35932 +f 47151/47183/35935 47137/47173/35919 47138/46884/35662 +f 47151/47183/35935 47138/46884/35662 47152/46898/35936 +f 47153/47184/35937 47151/47183/35935 47152/46898/35936 +f 47153/47184/35937 47152/46898/35936 47154/46895/35938 +f 47116/47154/35906 47115/47153/35905 47155/47185/35939 +f 47116/47154/35906 47155/47185/35939 47156/47186/35940 +f 47115/47153/35905 47114/47152/35904 47157/47187/35941 +f 47115/47153/35905 47157/47187/35941 47155/47185/35939 +f 47158/47188/35942 47153/47184/35937 47154/46895/35938 +f 47158/47188/35942 47154/46895/35938 47159/46900/35943 +f 47160/47189/35940 47158/47188/35942 47159/46900/35943 +f 47160/47189/35940 47159/46900/35943 47161/46899/35686 +f 47087/47125/35814 47085/47123/35881 47162/47190/35944 +f 47087/47125/35814 47162/47190/35944 47163/47191/35945 +f 47085/47123/35881 47084/47122/35861 47164/47192/35897 +f 47085/47123/35881 47164/47192/35897 47162/47190/35944 +f 47162/47190/35944 47164/47192/35897 47165/47193/35896 +f 47162/47190/35944 47165/47193/35896 47166/47194/35946 +f 47163/47191/35945 47162/47190/35944 47166/47194/35946 +f 47163/47191/35945 47166/47194/35946 47167/47195/35947 +f 47136/46885/35924 47135/46909/35923 47170/46888/35948 +f 47168/46886/35688 47170/46888/35949 47171/47196/35950 +f 47168/46886/35688 47171/47196/35950 47172/47197/35951 +f 47169/46887/35952 47168/46886/35688 47172/47197/35951 +f 47169/46887/35952 47172/47197/35951 47173/47198/35953 +f 47145/46890/35954 47176/46894/35955 47174/46891/35956 +f 47174/46891/35956 47176/46894/35955 47177/47199/35957 +f 47174/46891/35956 47177/47199/35957 47178/47200/35958 +f 47175/46892/35959 47174/46891/35956 47178/47200/35958 +f 47175/46892/35959 47178/47200/35958 47179/47201/35960 +f 47154/46895/35938 47152/46898/35936 47180/46896/35961 +f 47180/46896/35962 47169/46887/35952 47173/47198/35953 +f 47180/46896/35962 47173/47198/35953 47182/47202/35963 +f 47181/46897/35949 47180/46896/35962 47182/47202/35963 +f 47181/46897/35949 47182/47202/35963 47183/47203/35964 +f 47159/46900/35943 47154/46895/35938 47181/46897/35965 +f 47184/46901/35688 47181/46897/35949 47183/47203/35964 +f 47184/46901/35688 47183/47203/35964 47186/47204/35966 +f 47185/46902/35967 47184/46901/35688 47186/47204/35966 +f 47185/46902/35967 47186/47204/35966 47187/47205/35968 +f 47167/47195/35947 47166/47194/35946 47188/47206/35969 +f 47167/47195/35947 47188/47206/35969 47189/47207/35970 +f 47166/47194/35946 47165/47193/35896 47190/47208/35971 +f 47166/47194/35946 47190/47208/35971 47188/47206/35969 +f 47191/47209/35972 47192/47210/35973 47193/46907/35710 +f 47191/47209/35972 47193/46907/35710 47194/46906/35974 +f 47195/47211/35975 47191/47209/35972 47194/46906/35974 +f 47195/47211/35975 47194/46906/35974 47196/46903/35692 +f 47128/47166/35916 47125/47163/35914 47197/47212/35976 +f 47128/47166/35916 47197/47212/35976 47198/47213/35920 +f 47125/47163/35914 47124/47162/35913 47199/47214/35977 +f 47125/47163/35914 47199/47214/35977 47197/47212/35976 +f 47200/47215/35976 47160/47189/35940 47161/46899/35686 +f 47200/47215/35976 47161/46899/35686 47201/46910/35978 +f 47134/47172/35922 47200/47215/35976 47201/46910/35978 +f 47134/47172/35922 47201/46910/35978 47135/46909/35923 +f 47106/47144/35868 47109/47147/35899 47202/47216/35979 +f 47106/47144/35868 47202/47216/35979 47203/47217/35927 +f 47109/47147/35899 47111/47149/35901 47204/47218/35970 +f 47109/47147/35899 47204/47218/35970 47202/47216/35979 +f 47205/47219/35980 47195/47211/35975 47196/46903/35692 +f 47205/47219/35980 47196/46903/35692 47206/46912/35981 +f 47143/47178/35928 47205/47219/35980 47206/46912/35981 +f 47143/47178/35928 47206/46912/35981 47144/46893/35929 +f 47104/47142/35896 47103/47141/35895 47207/47220/35982 +f 47104/47142/35896 47207/47220/35982 47208/47221/35983 +f 47103/47141/35895 47102/47140/35894 47209/47222/35984 +f 47103/47141/35895 47209/47222/35984 47207/47220/35982 +f 47210/47223/35985 47146/47179/35930 47147/46889/35931 +f 47210/47223/35985 47147/46889/35931 47211/46914/35713 +f 47192/47210/35973 47210/47223/35985 47211/46914/35713 +f 47192/47210/35973 47211/46914/35713 47193/46907/35710 +f 47179/47201/35960 47178/47200/35958 47212/47224/35986 +f 47179/47201/35960 47212/47224/35986 47213/47225/35987 +f 47178/47200/35958 47177/47199/35957 47214/47226/35988 +f 47178/47200/35958 47214/47226/35988 47212/47224/35986 +f 47212/47224/35986 47214/47226/35988 47215/47227/35989 +f 47212/47224/35986 47215/47227/35989 47216/47228/35990 +f 47217/47229/35991 47218/47230/35992 47219/47231/35993 +f 47217/47229/35991 47219/47231/35993 47220/47232/35994 +f 47183/47203/35964 47182/47202/35963 47221/47233/35995 +f 47183/47203/35964 47221/47233/35995 47222/47234/35996 +f 47182/47202/35963 47173/47198/35953 47223/47235/35997 +f 47182/47202/35963 47223/47235/35997 47221/47233/35995 +f 47224/47236/35998 47225/47237/35997 47226/47238/35999 +f 47224/47236/35998 47226/47238/35999 47227/47239/36000 +f 47222/47234/35996 47221/47233/35995 47228/47240/36000 +f 47222/47234/35996 47228/47240/36000 47229/47241/36001 +f 47187/47205/35968 47186/47204/35966 47230/47242/36002 +f 47187/47205/35968 47230/47242/36002 47231/47243/36003 +f 47186/47204/35966 47183/47203/35964 47222/47234/35996 +f 47186/47204/35966 47222/47234/35996 47230/47242/36002 +f 47230/47242/36002 47222/47234/35996 47229/47241/36001 +f 47230/47242/36002 47229/47241/36001 47232/47244/36004 +f 47231/47243/36003 47230/47242/36002 47232/47244/36004 +f 47231/47243/36003 47232/47244/36004 47233/47245/36005 +f 47234/47246/36006 47235/47247/36007 47236/47248/36008 +f 47234/47246/36006 47236/47248/36008 47237/47249/36009 +f 47235/47247/36007 47179/47201/35960 47213/47225/35987 +f 47235/47247/36007 47213/47225/35987 47236/47248/36008 +f 47238/47250/36010 47239/47251/36011 47240/47252/36012 +f 47238/47250/36010 47240/47252/36012 47241/47253/36013 +f 47242/47254/36009 47238/47250/36010 47241/47253/36013 +f 47242/47254/36009 47241/47253/36013 47243/47255/36014 +f 47196/46903/35692 47194/46906/35974 47244/46904/36015 +f 47194/46906/35974 47246/46908/36016 47244/46904/36015 +f 47244/46904/36015 47246/46908/36016 47234/47246/36006 +f 47244/46904/36015 47234/47246/36006 47247/47256/36017 +f 47245/46905/36018 47244/46904/36015 47247/47256/36017 +f 47245/46905/36018 47247/47256/36017 47248/47257/36019 +f 47201/46910/36020 47185/46902/35967 47249/46911/35962 +f 47249/46911/35962 47185/46902/35967 47187/47205/35968 +f 47249/46911/35962 47187/47205/35968 47250/47258/36021 +f 47170/46888/35949 47249/46911/35962 47250/47258/36021 +f 47170/46888/35949 47250/47258/36021 47171/47196/35950 +f 47144/46893/35677 47251/46913/35709 47176/46894/35955 +f 47206/46912/35981 47196/46903/35692 47245/46905/36022 +f 47251/46913/35709 47245/46905/36018 47248/47257/36019 +f 47251/46913/35709 47248/47257/36019 47252/47259/36023 +f 47176/46894/35955 47251/46913/35709 47252/47259/36023 +f 47176/46894/35955 47252/47259/36023 47177/47199/35957 +f 47211/46914/35713 47147/46889/35931 47175/46892/36022 +f 47253/46915/35709 47175/46892/35959 47179/47201/35960 +f 47253/46915/35709 47179/47201/35960 47235/47247/36007 +f 47246/46908/36016 47253/46915/35709 47235/47247/36007 +f 47246/46908/36016 47235/47247/36007 47234/47246/36006 +f 47254/47260/36024 47255/47261/36025 47256/47262/36026 +f 47254/47260/36024 47256/47262/36026 47257/47263/36027 +f 47258/47264/36025 47259/47265/36028 47260/47266/36029 +f 47258/47264/36025 47260/47266/36029 47261/47267/36030 +f 47262/47268/36031 47263/47269/36032 47264/47270/36033 +f 47262/47268/36031 47264/47270/36033 47265/47271/36034 +f 47266/47272/36027 47262/47268/36031 47265/47271/36034 +f 47266/47272/36027 47265/47271/36034 47267/47273/36035 +f 47268/47274/35999 47269/47275/36036 47270/47276/36037 +f 47268/47274/35999 47270/47276/36037 47271/47277/36038 +f 47269/47275/36036 47272/47278/36039 47273/47279/36040 +f 47269/47275/36036 47273/47279/36040 47270/47276/36037 +f 47274/47280/36041 47275/47281/36042 47276/47282/36043 +f 47274/47280/36041 47276/47282/36043 47277/47283/36044 +f 47278/47284/36045 47274/47280/36041 47277/47283/36044 +f 47278/47284/36045 47277/47283/36044 47279/47285/36046 +f 47220/47232/35994 47219/47231/35993 47280/47286/36047 +f 47220/47232/35994 47280/47286/36047 47281/47287/36048 +f 47216/47228/35990 47215/47227/35989 47282/47288/36049 +f 47216/47228/35990 47282/47288/36049 47283/47289/36050 +f 47284/47290/36051 47285/47291/36049 47286/47292/36052 +f 47284/47290/36051 47286/47292/36052 47287/47293/36053 +f 47288/47294/36054 47284/47290/36051 47287/47293/36053 +f 47288/47294/36054 47287/47293/36053 47289/47295/36055 +f 47173/47198/35953 47172/47197/35951 47290/47296/36056 +f 47173/47198/35953 47290/47296/36056 47223/47235/35997 +f 47172/47197/35951 47171/47196/35950 47291/47297/36057 +f 47172/47197/35951 47291/47297/36057 47290/47296/36056 +f 47292/47298/36058 47293/47299/36059 47272/47278/36039 +f 47292/47298/36058 47272/47278/36039 47269/47275/36036 +f 47294/47300/36060 47292/47298/36058 47269/47275/36036 +f 47294/47300/36060 47269/47275/36036 47268/47274/35999 +f 47248/47257/36019 47247/47256/36017 47295/47301/36061 +f 47248/47257/36019 47295/47301/36061 47296/47302/36062 +f 47247/47256/36017 47234/47246/36006 47237/47249/36009 +f 47247/47256/36017 47237/47249/36009 47295/47301/36061 +f 47297/47303/36061 47298/47304/36063 47299/47305/36014 +f 47297/47303/36061 47299/47305/36014 47300/47306/36064 +f 47296/47302/36062 47295/47301/36061 47301/47307/36064 +f 47296/47302/36062 47301/47307/36064 47254/47260/36024 +f 47171/47196/35950 47250/47258/36021 47302/47308/36065 +f 47171/47196/35950 47302/47308/36065 47291/47297/36057 +f 47250/47258/36021 47187/47205/35968 47231/47243/36003 +f 47250/47258/36021 47231/47243/36003 47302/47308/36065 +f 47302/47308/36065 47231/47243/36003 47233/47245/36005 +f 47302/47308/36065 47233/47245/36005 47303/47309/36066 +f 47304/47310/36067 47305/47311/36068 47306/47312/36069 +f 47304/47310/36067 47306/47312/36069 47307/47313/36070 +f 47177/47199/35957 47252/47259/36023 47308/47314/36071 +f 47177/47199/35957 47308/47314/36071 47214/47226/35988 +f 47252/47259/36023 47248/47257/36019 47296/47302/36062 +f 47252/47259/36023 47296/47302/36062 47308/47314/36071 +f 47308/47314/36071 47296/47302/36062 47254/47260/36024 +f 47308/47314/36071 47254/47260/36024 47309/47315/36072 +f 47214/47226/35988 47308/47314/36071 47309/47315/36072 +f 47214/47226/35988 47309/47315/36072 47215/47227/35989 +f 47215/47227/35989 47309/47315/36072 47310/47316/36073 +f 47215/47227/35989 47310/47316/36073 47311/47317/36074 +f 47309/47315/36072 47254/47260/36024 47257/47263/36027 +f 47309/47315/36072 47257/47263/36027 47310/47316/36073 +f 47312/47318/36075 47266/47272/36027 47267/47273/36035 +f 47312/47318/36075 47267/47273/36035 47313/47319/36076 +f 47314/47320/36074 47312/47318/36075 47313/47319/36076 +f 47314/47320/36074 47313/47319/36076 47315/47321/36077 +f 47315/47321/36077 47313/47319/36076 47316/47322/36078 +f 47315/47321/36077 47316/47322/36078 47317/47323/36079 +f 47313/47319/36076 47267/47273/36035 47318/47324/36080 +f 47313/47319/36076 47318/47324/36080 47316/47322/36078 +f 47316/47322/36078 47318/47324/36080 47319/47325/36081 +f 47316/47322/36078 47319/47325/36081 47320/47326/36082 +f 47317/47323/36079 47316/47322/36078 47320/47326/36082 +f 47317/47323/36079 47320/47326/36082 47321/47327/36083 +f 47322/47328/36084 47323/47329/36085 47324/47330/36086 +f 47322/47328/36084 47324/47330/36086 47325/47331/36087 +f 47323/47329/36085 47326/47332/36088 47327/47333/36089 +f 47323/47329/36085 47327/47333/36089 47324/47330/36086 +f 47328/47334/36090 47329/47335/36089 47229/47241/36001 +f 47328/47334/36090 47229/47241/36001 47228/47240/36000 +f 47330/47336/36091 47331/47337/36090 47227/47239/36000 +f 47330/47336/36091 47227/47239/36000 47226/47238/35999 +f 47233/47245/36005 47232/47244/36004 47332/47338/36092 +f 47233/47245/36005 47332/47338/36092 47333/47339/36093 +f 47232/47244/36004 47229/47241/36001 47334/47340/36094 +f 47232/47244/36004 47334/47340/36094 47332/47338/36092 +f 47335/47341/36095 47336/47342/36096 47337/47343/36097 +f 47335/47341/36095 47337/47343/36097 47338/47344/36098 +f 47339/47345/36099 47335/47341/36095 47338/47344/36098 +f 47339/47345/36099 47338/47344/36098 47340/47346/36100 +f 47341/47347/36101 47342/47348/36102 47343/47349/36103 +f 47341/47347/36101 47343/47349/36103 47344/47350/36104 +f 47342/47348/36102 47345/47351/36105 47346/47352/36106 +f 47342/47348/36102 47346/47352/36106 47343/47349/36103 +f 47343/47349/36103 47346/47352/36106 47347/47353/36107 +f 47343/47349/36103 47347/47353/36107 47348/47354/36108 +f 47344/47350/36104 47343/47349/36103 47348/47354/36108 +f 47344/47350/36104 47348/47354/36108 47349/47355/36109 +f 47350/47356/36110 47351/47357/36111 47352/47358/36112 +f 47350/47356/36110 47352/47358/36112 47353/47359/36113 +f 47351/47357/36111 47354/47360/36114 47355/47361/36115 +f 47351/47357/36111 47355/47361/36115 47352/47358/36112 +f 47352/47358/36112 47355/47361/36115 47356/47362/36116 +f 47352/47358/36112 47356/47362/36116 47357/47363/36117 +f 47353/47359/36113 47352/47358/36112 47357/47363/36117 +f 47353/47359/36113 47357/47363/36117 47358/47364/36118 +f 47350/47356/36110 47353/47359/36113 47359/47365/36119 +f 47350/47356/36110 47359/47365/36119 47360/47366/36120 +f 47353/47359/36113 47358/47364/36118 47361/47367/36121 +f 47353/47359/36113 47361/47367/36121 47359/47365/36119 +f 47359/47365/36119 47361/47367/36121 47362/47368/36122 +f 47359/47365/36119 47362/47368/36122 47363/47369/36123 +f 47360/47366/36120 47359/47365/36119 47363/47369/36123 +f 47360/47366/36120 47363/47369/36123 47364/47370/36124 +f 47337/47343/36097 47365/47371/36125 47366/47372/36126 +f 47337/47343/36097 47366/47372/36126 47367/47373/36127 +f 47365/47371/36125 47368/47374/36128 47369/47375/36129 +f 47365/47371/36125 47369/47375/36129 47366/47372/36126 +f 47370/47376/36130 47371/47377/36131 47354/47360/36114 +f 47370/47376/36130 47354/47360/36114 47351/47357/36111 +f 47367/47373/36127 47366/47372/36126 47372/47378/36111 +f 47367/47373/36127 47372/47378/36111 47373/47379/36110 +f 47340/47346/36100 47338/47344/36098 47374/47380/36132 +f 47340/47346/36100 47374/47380/36132 47375/47381/36133 +f 47338/47344/36098 47337/47343/36097 47367/47373/36127 +f 47338/47344/36098 47367/47373/36127 47374/47380/36132 +f 47374/47380/36132 47367/47373/36127 47373/47379/36110 +f 47374/47380/36132 47373/47379/36110 47376/47382/36134 +f 47375/47381/36133 47374/47380/36132 47376/47382/36134 +f 47375/47381/36133 47376/47382/36134 47377/47383/36135 +f 47341/47347/36101 47378/47384/36136 47379/47385/36137 +f 47341/47347/36101 47379/47385/36137 47342/47348/36102 +f 47378/47384/36136 47380/47386/36138 47381/47387/36139 +f 47378/47384/36136 47381/47387/36139 47379/47385/36137 +f 47379/47385/36137 47381/47387/36139 47382/47388/36140 +f 47379/47385/36137 47382/47388/36140 47383/47389/36141 +f 47342/47348/36102 47379/47385/36137 47383/47389/36141 +f 47342/47348/36102 47383/47389/36141 47345/47351/36105 +f 47384/47390/36142 47385/47391/36143 47386/47392/36144 +f 47384/47390/36142 47386/47392/36144 47387/47393/36145 +f 47385/47391/36143 47340/47346/36100 47375/47381/36133 +f 47385/47391/36143 47375/47381/36133 47386/47392/36144 +f 47386/47392/36144 47375/47381/36133 47377/47383/36135 +f 47386/47392/36144 47377/47383/36135 47388/47394/36146 +f 47389/47395/36147 47390/47396/36148 47391/47397/36146 +f 47389/47395/36147 47391/47397/36146 47392/47398/36149 +f 47392/47398/36149 47391/47397/36146 47393/47399/36150 +f 47392/47398/36149 47393/47399/36150 47394/46916/35716 +f 47391/47397/36146 47395/47400/36135 47396/47401/36151 +f 47391/47397/36146 47396/47401/36151 47393/47399/36150 +f 47393/47399/36150 47396/47401/36151 47397/47402/36152 +f 47393/47399/36150 47397/47402/36152 47398/47403/36153 +f 47394/46916/35716 47393/47399/36150 47398/47403/36153 +f 47394/46916/35716 47398/47403/36153 47399/46917/35717 +f 47400/47404/36154 47401/47405/36155 47402/47406/36156 +f 47400/47404/36154 47402/47406/36156 47403/46919/35719 +f 47401/47405/36155 47404/47407/36083 47405/47408/36157 +f 47401/47405/36155 47405/47408/36157 47402/47406/36156 +f 47402/47406/36156 47405/47408/36157 47406/47409/36158 +f 47402/47406/36156 47406/47409/36158 47407/47410/36159 +f 47403/46919/35719 47402/47406/36156 47407/47410/36159 +f 47403/46919/35719 47407/47410/36159 47408/46920/36160 +f 47409/47411/36161 47410/47412/36162 47411/47413/36163 +f 47409/47411/36161 47411/47413/36163 47412/47414/36164 +f 47413/47415/36162 47233/47245/36005 47333/47339/36093 +f 47413/47415/36162 47333/47339/36093 47414/47416/36163 +f 47415/47417/36165 47339/47345/36099 47340/47346/36100 +f 47415/47417/36165 47340/47346/36100 47385/47391/36143 +f 47416/47418/36164 47415/47417/36165 47385/47391/36143 +f 47416/47418/36164 47385/47391/36143 47384/47390/36142 +f 47417/47419/36166 47418/47420/36167 47419/47421/36168 +f 47417/47419/36166 47419/47421/36168 47420/47422/36169 +f 47418/47420/36167 47315/47321/36077 47317/47323/36079 +f 47418/47420/36167 47317/47323/36079 47419/47421/36168 +f 47419/47421/36168 47317/47323/36079 47321/47327/36083 +f 47419/47421/36168 47321/47327/36083 47421/47423/36155 +f 47422/47424/36170 47423/47425/36171 47401/47405/36155 +f 47422/47424/36170 47401/47405/36155 47400/47404/36154 +f 47286/47292/36052 47285/47291/36049 47424/47426/36172 +f 47286/47292/36052 47424/47426/36172 47425/47427/36173 +f 47282/47288/36049 47215/47227/35989 47311/47317/36074 +f 47282/47288/36049 47311/47317/36074 47426/47428/36172 +f 47427/47429/36174 47314/47320/36074 47315/47321/36077 +f 47427/47429/36174 47315/47321/36077 47418/47420/36167 +f 47428/47430/36175 47427/47429/36174 47418/47420/36167 +f 47428/47430/36175 47418/47420/36167 47417/47419/36166 +f 47267/47273/36035 47265/47271/36034 47429/47431/36176 +f 47267/47273/36035 47429/47431/36176 47318/47324/36080 +f 47265/47271/36034 47264/47270/36033 47430/47432/36177 +f 47265/47271/36034 47430/47432/36177 47429/47431/36176 +f 47431/47433/36178 47432/47434/36177 47380/47386/36138 +f 47431/47433/36178 47380/47386/36138 47378/47384/36136 +f 47318/47324/36080 47429/47431/36176 47433/47435/36179 +f 47318/47324/36080 47433/47435/36179 47319/47325/36081 +f 47229/47241/36001 47329/47335/36089 47434/47436/36180 +f 47229/47241/36001 47434/47436/36180 47334/47340/36094 +f 47327/47333/36089 47326/47332/36088 47435/47437/36181 +f 47327/47333/36089 47435/47437/36181 47436/47438/36182 +f 47437/47439/36180 47438/47440/36183 47368/47374/36128 +f 47437/47439/36180 47368/47374/36128 47365/47371/36125 +f 47336/47342/36096 47437/47439/36180 47365/47371/36125 +f 47336/47342/36096 47365/47371/36125 47337/47343/36097 +f 47439/47441/36184 47440/47442/36185 47441/47443/36186 +f 47439/47441/36184 47441/47443/36186 47442/47444/36187 +f 47440/47442/36185 47259/47265/36028 47258/47264/36025 +f 47440/47442/36185 47258/47264/36025 47441/47443/36186 +f 47443/47445/36188 47255/47261/36025 47254/47260/36024 +f 47443/47445/36188 47254/47260/36024 47301/47307/36064 +f 47444/47446/36189 47445/47447/36190 47300/47306/36064 +f 47444/47446/36189 47300/47306/36064 47299/47305/36014 +f 47446/47448/36055 47447/47449/36191 47448/47450/36192 +f 47446/47448/36055 47448/47450/36192 47449/47451/36193 +f 47447/47449/36191 47450/47452/36184 47451/47453/36194 +f 47447/47449/36191 47451/47453/36194 47448/47450/36192 +f 47452/47454/36192 47453/47455/36195 47243/47255/36014 +f 47452/47454/36192 47243/47255/36014 47241/47253/36013 +f 47454/47456/36196 47452/47454/36192 47241/47253/36013 +f 47454/47456/36196 47241/47253/36013 47240/47252/36012 +f 47384/47390/36142 47387/47393/36145 47455/47457/36197 +f 47384/47390/36142 47455/47457/36197 47456/47458/36198 +f 47389/47395/36147 47392/47398/36149 47457/47459/36199 +f 47389/47395/36147 47457/47459/36199 47458/47460/36197 +f 47458/47460/36197 47457/47459/36199 47380/47386/36138 +f 47458/47460/36197 47380/47386/36138 47432/47434/36177 +f 47456/47458/36198 47455/47457/36197 47430/47432/36177 +f 47456/47458/36198 47430/47432/36177 47264/47270/36033 +f 47392/47398/36149 47394/46916/35716 47459/47461/36200 +f 47392/47398/36149 47459/47461/36200 47457/47459/36199 +f 47394/46916/35716 47460/46918/36201 47459/47461/36200 +f 47459/47461/36200 47460/46918/36201 47382/47388/36140 +f 47459/47461/36200 47382/47388/36140 47381/47387/36139 +f 47457/47459/36199 47459/47461/36200 47381/47387/36139 +f 47457/47459/36199 47381/47387/36139 47380/47386/36138 +f 47400/47404/36154 47403/46919/35719 47461/47462/36202 +f 47400/47404/36154 47461/47462/36202 47462/47463/36203 +f 47403/46919/35719 47463/46921/35721 47461/47462/36202 +f 47461/47462/36202 47463/46921/35721 47356/47362/36116 +f 47461/47462/36202 47356/47362/36116 47355/47361/36115 +f 47462/47463/36203 47461/47462/36202 47355/47361/36115 +f 47462/47463/36203 47355/47361/36115 47354/47360/36114 +f 47409/47411/36161 47412/47414/36164 47464/47464/36204 +f 47409/47411/36161 47464/47464/36204 47465/47465/36205 +f 47416/47418/36164 47384/47390/36142 47456/47458/36198 +f 47416/47418/36164 47456/47458/36198 47466/47466/36206 +f 47466/47466/36206 47456/47458/36198 47264/47270/36033 +f 47466/47466/36206 47264/47270/36033 47263/47269/36032 +f 47465/47465/36205 47464/47464/36204 47260/47266/36029 +f 47465/47465/36205 47260/47266/36029 47259/47265/36028 +f 47417/47419/36166 47420/47422/36169 47467/47467/36207 +f 47417/47419/36166 47467/47467/36207 47468/47468/36208 +f 47422/47424/36170 47400/47404/36154 47462/47463/36203 +f 47422/47424/36170 47462/47463/36203 47469/47469/36207 +f 47469/47469/36207 47462/47463/36203 47354/47360/36114 +f 47469/47469/36207 47354/47360/36114 47371/47377/36131 +f 47468/47468/36208 47467/47467/36207 47369/47375/36129 +f 47468/47468/36208 47369/47375/36129 47368/47374/36128 +f 47286/47292/36052 47425/47427/36173 47470/47470/36209 +f 47286/47292/36052 47470/47470/36209 47471/47471/36210 +f 47428/47430/36175 47417/47419/36166 47468/47468/36208 +f 47428/47430/36175 47468/47468/36208 47472/47472/36209 +f 47472/47472/36209 47468/47468/36208 47368/47374/36128 +f 47472/47472/36209 47368/47374/36128 47438/47440/36183 +f 47471/47471/36210 47470/47470/36209 47435/47437/36181 +f 47471/47471/36210 47435/47437/36181 47326/47332/36088 +f 47326/47332/36088 47323/47329/36085 47473/47473/36211 +f 47326/47332/36088 47473/47473/36211 47471/47471/36210 +f 47323/47329/36085 47322/47328/36084 47474/47474/36212 +f 47323/47329/36085 47474/47474/36212 47473/47473/36211 +f 47473/47473/36211 47474/47474/36212 47289/47295/36055 +f 47473/47473/36211 47289/47295/36055 47287/47293/36053 +f 47471/47471/36210 47473/47473/36211 47287/47293/36053 +f 47471/47471/36210 47287/47293/36053 47286/47292/36052 +f 47450/47452/36184 47447/47449/36191 47475/47475/36213 +f 47450/47452/36184 47475/47475/36213 47476/47476/36214 +f 47447/47449/36191 47446/47448/36055 47477/47477/36215 +f 47447/47449/36191 47477/47477/36215 47475/47475/36213 +f 47475/47475/36213 47477/47477/36215 47279/47285/36046 +f 47475/47475/36213 47279/47285/36046 47277/47283/36044 +f 47476/47476/36214 47475/47475/36213 47277/47283/36044 +f 47476/47476/36214 47277/47283/36044 47276/47282/36043 +f 47259/47265/36028 47440/47442/36185 47478/47478/36216 +f 47259/47265/36028 47478/47478/36216 47465/47465/36205 +f 47440/47442/36185 47439/47441/36184 47479/47479/36217 +f 47440/47442/36185 47479/47479/36217 47478/47478/36216 +f 47478/47478/36216 47479/47479/36217 47480/47480/36218 +f 47478/47478/36216 47480/47480/36218 47481/47481/36219 +f 47465/47465/36205 47478/47478/36216 47481/47481/36219 +f 47465/47465/36205 47481/47481/36219 47409/47411/36161 +f 47307/47313/36070 47306/47312/36069 47482/47482/36220 +f 47307/47313/36070 47482/47482/36220 47483/47483/36221 +f 47303/47309/36066 47233/47245/36005 47413/47415/36162 +f 47303/47309/36066 47413/47415/36162 47484/47484/36220 +f 47485/47485/36222 47410/47412/36162 47409/47411/36161 +f 47485/47485/36222 47409/47411/36161 47481/47481/36219 +f 47486/47486/36223 47485/47485/36222 47481/47481/36219 +f 47486/47486/36223 47481/47481/36219 47480/47480/36218 +f 47487/47487/36224 47488/47488/36225 47489/47489/36226 +f 47487/47487/36224 47489/47489/36226 47490/47490/36227 +f 47488/47488/36225 47491/47491/36228 47492/47492/36108 +f 47488/47488/36225 47492/47492/36108 47489/47489/36226 +f 47489/47489/36226 47492/47492/36108 47493/47493/36229 +f 47489/47489/36226 47493/47493/36229 47494/47494/36230 +f 47490/47490/36227 47489/47489/36226 47494/47494/36230 +f 47490/47490/36227 47494/47494/36230 47495/47495/36231 +f 47496/47496/36232 47497/47497/36233 47498/47498/36234 +f 47496/47496/36232 47498/47498/36234 47499/47499/36235 +f 47497/47497/36233 47500/47500/36124 47501/47501/36123 +f 47497/47497/36233 47501/47501/36123 47498/47498/36234 +f 47498/47498/36234 47501/47501/36123 47502/47502/36122 +f 47498/47498/36234 47502/47502/36122 47503/47503/36236 +f 47499/47499/36235 47498/47498/36234 47503/47503/36236 +f 47499/47499/36235 47503/47503/36236 47504/47504/36237 +f 47321/47327/36083 47320/47326/36082 47505/47505/36238 +f 47321/47327/36083 47505/47505/36238 47506/47506/36239 +f 47320/47326/36082 47319/47325/36081 47507/47507/36104 +f 47320/47326/36082 47507/47507/36104 47505/47505/36238 +f 47505/47505/36238 47507/47507/36104 47508/47508/36109 +f 47505/47505/36238 47508/47508/36109 47509/47509/36225 +f 47506/47506/36239 47505/47505/36238 47509/47509/36225 +f 47506/47506/36239 47509/47509/36225 47510/47510/36224 +f 47397/47402/36152 47396/47401/36151 47511/47511/36240 +f 47397/47402/36152 47511/47511/36240 47512/47512/36241 +f 47396/47401/36151 47395/47400/36135 47513/47513/36242 +f 47396/47401/36151 47513/47513/36242 47511/47511/36240 +f 47511/47511/36240 47513/47513/36242 47514/47514/36243 +f 47511/47511/36240 47514/47514/36243 47515/47515/36235 +f 47512/47512/36241 47511/47511/36240 47515/47515/36235 +f 47512/47512/36241 47515/47515/36235 47516/47516/36237 +f 47406/47409/36158 47405/47408/36157 47517/47517/36244 +f 47406/47409/36158 47517/47517/36244 47518/47518/36245 +f 47405/47408/36157 47404/47407/36083 47519/47519/36239 +f 47405/47408/36157 47519/47519/36239 47517/47517/36244 +f 47517/47517/36244 47519/47519/36239 47520/47520/36224 +f 47517/47517/36244 47520/47520/36224 47521/47521/36246 +f 47518/47518/36245 47517/47517/36244 47521/47521/36246 +f 47518/47518/36245 47521/47521/36246 47522/47522/36231 +f 47377/47383/36135 47376/47382/36134 47523/47523/36247 +f 47377/47383/36135 47523/47523/36247 47524/47524/36248 +f 47376/47382/36134 47373/47379/36110 47525/47525/36120 +f 47376/47382/36134 47525/47525/36120 47523/47523/36247 +f 47523/47523/36247 47525/47525/36120 47526/47526/36124 +f 47523/47523/36247 47526/47526/36124 47527/47527/36233 +f 47524/47524/36248 47523/47523/36247 47527/47527/36233 +f 47524/47524/36248 47527/47527/36233 47528/47528/36232 diff --git a/Demo/RenderDemo/data/backpack/diffuse.jpg b/Demo/RenderDemo/data/backpack/diffuse.jpg new file mode 100644 index 0000000..e971a33 Binary files /dev/null and b/Demo/RenderDemo/data/backpack/diffuse.jpg differ diff --git a/Demo/RenderDemo/data/backpack/normal.jpg b/Demo/RenderDemo/data/backpack/normal.jpg new file mode 100644 index 0000000..c40fae8 Binary files /dev/null and b/Demo/RenderDemo/data/backpack/normal.jpg differ diff --git a/Demo/RenderDemo/data/backpack/roughness.jpg b/Demo/RenderDemo/data/backpack/roughness.jpg new file mode 100644 index 0000000..9f50e67 Binary files /dev/null and b/Demo/RenderDemo/data/backpack/roughness.jpg differ diff --git a/Demo/RenderDemo/data/backpack/source_attribution.txt b/Demo/RenderDemo/data/backpack/source_attribution.txt new file mode 100644 index 0000000..a704b4a --- /dev/null +++ b/Demo/RenderDemo/data/backpack/source_attribution.txt @@ -0,0 +1,3 @@ +Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36 + +Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup. \ No newline at end of file diff --git a/Demo/RenderDemo/data/backpack/specular.jpg b/Demo/RenderDemo/data/backpack/specular.jpg new file mode 100644 index 0000000..d0ca86f Binary files /dev/null and b/Demo/RenderDemo/data/backpack/specular.jpg differ diff --git a/Demo/RenderDemo/data/fonts/OpenSans-Regular.ttf b/Demo/RenderDemo/data/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..29e9e60 Binary files /dev/null and b/Demo/RenderDemo/data/fonts/OpenSans-Regular.ttf differ diff --git a/Demo/RenderDemo/data/models/duck.obj b/Demo/RenderDemo/data/models/duck.obj new file mode 100644 index 0000000..d9dd966 --- /dev/null +++ b/Demo/RenderDemo/data/models/duck.obj @@ -0,0 +1,10713 @@ +# Blender v2.71 (sub 0) OBJ File: '' +# www.blender.org +mtllib duck.mtl +o Duck +v -0.239364 0.115353 0.306125 +v -0.187264 0.101080 0.266814 +v -0.156992 0.114278 0.342321 +v -0.114590 0.100413 0.298243 +v -0.245326 0.101147 0.222069 +v -0.305196 0.116272 0.251326 +v -0.351528 0.116836 0.177191 +v -0.285504 0.101785 0.157995 +v -0.311142 0.101703 0.063849 +v -0.379272 0.117800 0.069973 +v 0.477677 0.141162 0.336212 +v 0.615472 0.142726 0.252082 +v 0.518411 0.177055 0.365602 +v 0.657206 0.183720 0.270862 +v 0.560117 0.114345 0.226963 +v 0.436854 0.114300 0.300164 +v -0.286467 0.144120 0.339793 +v -0.194590 0.143090 0.379267 +v -0.360670 0.145054 0.276816 +v -0.329292 0.185574 0.367248 +v -0.409218 0.186322 0.296382 +v -0.232343 0.181488 0.410429 +v -0.409463 0.146426 0.192219 +v -0.441714 0.146552 0.072783 +v -0.461733 0.186604 0.205246 +v -0.502675 0.183890 0.073635 +v 0.686182 0.142022 0.140757 +v 0.624487 0.113989 0.129806 +v 0.733418 0.183468 0.149194 +v 0.557803 0.224988 0.385465 +v 0.688732 0.234107 0.284208 +v 0.602326 0.281944 0.395949 +v 0.712984 0.290359 0.293335 +v -0.369819 0.237436 0.385844 +v -0.270171 0.234671 0.430366 +v -0.452302 0.236628 0.309246 +v -0.410731 0.293325 0.394763 +v -0.489500 0.289358 0.314102 +v -0.329737 0.296914 0.434770 +v 0.769844 0.234678 0.155749 +v 0.794615 0.291894 0.160672 +v 0.728865 0.351223 0.298369 +v 0.632406 0.345574 0.398307 +v 0.652513 0.413955 0.398840 +v 0.738118 0.417425 0.298584 +v 0.809318 0.353877 0.164090 +v 0.818608 0.421140 0.167292 +v 0.646263 0.554849 0.382648 +v 0.660817 0.485555 0.392449 +v 0.726597 0.550030 0.292468 +v 0.739987 0.485347 0.296857 +v 0.815894 0.488387 0.169628 +v 0.801688 0.551853 0.169480 +v 0.555179 0.677340 0.357358 +v 0.611927 0.620057 0.372950 +v 0.665829 0.664165 0.279218 +v 0.701700 0.610152 0.286395 +v 0.777874 0.610196 0.167611 +v 0.748647 0.663268 0.166010 +v 0.434971 0.756992 0.318699 +v 0.485084 0.721529 0.339029 +v 0.569340 0.750037 0.257495 +v 0.617637 0.710370 0.268557 +v 0.716321 0.711772 0.166670 +v 0.671835 0.754493 0.166366 +v -0.121248 0.739991 0.289191 +v 0.019364 0.728387 0.338763 +v -0.074004 0.761581 0.263759 +v 0.036476 0.759142 0.305480 +v -0.033796 0.780576 0.231953 +v 0.053181 0.784269 0.269639 +v 0.148335 0.763145 0.320471 +v 0.147016 0.788465 0.288886 +v 0.147601 0.738701 0.351574 +v -0.147042 0.766096 0.197209 +v -0.192017 0.778115 0.073361 +v -0.209470 0.750059 0.213995 +v -0.247824 0.782304 0.076512 +v -0.132799 0.782816 0.067808 +v -0.093096 0.780917 0.176635 +v 0.023331 0.812658 0.107014 +v 0.006560 0.810723 0.039938 +v 0.049422 0.814267 0.158195 +v -0.553055 0.814823 0.201865 +v -0.495150 0.838778 0.207678 +v -0.547257 0.899761 0.088449 +v -0.485489 0.922656 0.090651 +v -0.424217 0.915301 0.090221 +v -0.441025 0.828784 0.210800 +v -0.483998 0.772606 0.269595 +v -0.441714 0.778938 0.261268 +v -0.536566 0.747375 0.269735 +v -0.638341 0.698359 0.177050 +v -0.603339 0.763635 0.190618 +v -0.647587 0.738997 0.071530 +v -0.601596 0.844057 0.082814 +v -0.582579 0.706396 0.264175 +v -0.615691 0.656958 0.252253 +v -0.581459 0.604109 0.315845 +v -0.545522 0.648765 0.329243 +v -0.501918 0.687831 0.330970 +v -0.429296 0.612502 0.394496 +v -0.463972 0.555620 0.403341 +v -0.489596 0.492561 0.398218 +v -0.535557 0.461592 0.349928 +v -0.608158 0.559957 0.285728 +v -0.583698 0.439468 0.280360 +v -0.630690 0.527290 0.240553 +v -0.649663 0.572673 0.217398 +v -0.636495 0.607883 0.233658 +v -0.506442 0.234975 0.212438 +v -0.557570 0.230430 0.077306 +v -0.544261 0.285392 0.216382 +v -0.601092 0.282359 0.079278 +v -0.046697 0.357333 0.522177 +v -0.051828 0.393551 0.528687 +v -0.103735 0.363160 0.518336 +v -0.124228 0.392454 0.519419 +v -0.059546 0.433855 0.531660 +v -0.142645 0.434767 0.518892 +v -0.451383 0.351824 0.390803 +v -0.521766 0.341006 0.309987 +v -0.393582 0.371753 0.428245 +v -0.577470 0.335446 0.215100 +v -0.632047 0.333562 0.077735 +v -0.624832 0.427738 0.196053 +v -0.662519 0.423750 0.075912 +v -0.063446 0.475345 0.530926 +v -0.062067 0.514293 0.524750 +v -0.149689 0.480973 0.515712 +v -0.145047 0.522745 0.510455 +v -0.241626 0.668013 0.396298 +v -0.210960 0.645792 0.417131 +v -0.132184 0.681588 0.385488 +v -0.106093 0.655757 0.412676 +v -0.292013 0.796561 0.080857 +v -0.275531 0.736877 0.228942 +v -0.208410 0.719312 0.315875 +v -0.317993 0.708398 0.334366 +v -0.340814 0.736573 0.231685 +v -0.331153 0.823349 0.086247 +v 0.341225 0.805718 0.266473 +v 0.390864 0.776536 0.294959 +v 0.482452 0.810789 0.223270 +v 0.522860 0.782905 0.242985 +v 0.286752 0.750467 0.347400 +v 0.266207 0.769559 0.319144 +v 0.245284 0.794248 0.290977 +v 0.625867 0.788584 0.161198 +v 0.582456 0.816454 0.149372 +v 0.087642 0.815601 0.202429 +v 0.155527 0.813807 0.244230 +v -0.400580 0.733058 0.290169 +v -0.393930 0.779086 0.222647 +v -0.371064 0.881752 0.089146 +v -0.655928 0.516658 0.172594 +v -0.680046 0.515783 0.071537 +v -0.662542 0.577677 0.160138 +v -0.679758 0.585114 0.069980 +v -0.448336 0.713336 0.321213 +v -0.380814 0.666122 0.376368 +v -0.655690 0.635509 0.165565 +v -0.669147 0.656180 0.070774 +v 0.551672 0.837325 0.132216 +v 0.461403 0.832928 0.200590 +v 0.533737 0.855572 0.123674 +v 0.448651 0.851990 0.187578 +v 0.253055 0.831594 0.237810 +v 0.175457 0.832299 0.216568 +v 0.243957 0.812413 0.264145 +v 0.190500 0.850093 0.204734 +v 0.260550 0.849410 0.223278 +v 0.351961 0.830430 0.235111 +v 0.352584 0.849759 0.220089 +v 0.121192 0.832358 0.180750 +v 0.086500 0.831534 0.137124 +v 0.102211 0.849641 0.131445 +v 0.138638 0.850248 0.172846 +v 0.392717 0.100042 0.259897 +v 0.497414 0.099968 0.197068 +v 0.146156 0.100124 0.317958 +v 0.259631 0.100257 0.300393 +v 0.151798 0.114100 0.364164 +v 0.282119 0.114278 0.345791 +v -0.006794 0.100168 0.318299 +v -0.026968 0.113425 0.364653 +v 0.551790 0.100309 0.114214 +v 0.305288 0.140969 0.382233 +v 0.161259 0.139798 0.402177 +v 0.172973 0.173674 0.432976 +v 0.330793 0.177336 0.413765 +v -0.052198 0.140791 0.402548 +v -0.083205 0.178723 0.433717 +v 0.189195 0.362041 0.525892 +v 0.184628 0.399920 0.532994 +v 0.112191 0.356243 0.525988 +v 0.106044 0.396524 0.534314 +v 0.182523 0.443116 0.537955 +v 0.101522 0.438267 0.539252 +v 0.259535 0.399994 0.527745 +v 0.270248 0.445585 0.528835 +v 0.245685 0.369247 0.524691 +v 0.176910 0.489863 0.538221 +v 0.097355 0.480914 0.538815 +v 0.093544 0.521796 0.535056 +v 0.169236 0.536009 0.532898 +v 0.254374 0.550852 0.520724 +v 0.268721 0.498693 0.526952 +v 0.161429 0.576002 0.523171 +v 0.091260 0.558675 0.527181 +v 0.092313 0.592580 0.512115 +v 0.159783 0.608706 0.508542 +v 0.212751 0.616417 0.503945 +v 0.232428 0.592083 0.511997 +v 0.322615 0.714100 0.379727 +v 0.152006 0.709348 0.384909 +v 0.438649 0.677941 0.398677 +v 0.514408 0.626760 0.414618 +v 0.559835 0.561625 0.427808 +v 0.576406 0.489151 0.438433 +v 0.564187 0.417648 0.444371 +v 0.529177 0.350586 0.445773 +v 0.469566 0.290085 0.442399 +v 0.362170 0.231483 0.439056 +v 0.180410 0.213370 0.454158 +v -0.130679 0.235531 0.456457 +v -0.242634 0.297596 0.464694 +v -0.317681 0.366178 0.457769 +v -0.371346 0.446474 0.444312 +v -0.378300 0.515724 0.436927 +v -0.358668 0.578953 0.427333 +v -0.314745 0.632943 0.412950 +v -0.057351 0.546841 0.518166 +v -0.129337 0.554359 0.506592 +v -0.055476 0.574675 0.506459 +v -0.110645 0.573325 0.503033 +v 0.013848 0.692606 0.385873 +v -0.279498 0.364747 0.466355 +v -0.320076 0.433195 0.457562 +v -0.238534 0.366519 0.487626 +v -0.272981 0.428866 0.480687 +v -0.259576 0.365644 0.472776 +v -0.298093 0.429681 0.465354 +v -0.164436 0.322248 0.493054 +v -0.186612 0.311764 0.478255 +v -0.206037 0.306107 0.470640 +v -0.333289 0.501288 0.448568 +v -0.321367 0.564888 0.438329 +v -0.287520 0.492710 0.472864 +v -0.278897 0.550430 0.465161 +v -0.312662 0.496491 0.456583 +v -0.302660 0.558423 0.447033 +v 0.299349 0.259004 0.465236 +v 0.164046 0.239305 0.470581 +v 0.136265 0.280639 0.499986 +v 0.149477 0.257121 0.483904 +v 0.239612 0.295453 0.499126 +v 0.267542 0.275116 0.481161 +v 0.323868 0.327171 0.498711 +v 0.362897 0.312217 0.480605 +v 0.401118 0.302660 0.465139 +v -0.098419 0.261273 0.471530 +v -0.071594 0.293978 0.497079 +v -0.084280 0.274619 0.482347 +v 0.468217 0.358170 0.465762 +v 0.381551 0.375127 0.497814 +v 0.426645 0.365214 0.480598 +v 0.413922 0.434352 0.494685 +v 0.465110 0.427776 0.477899 +v 0.507757 0.422756 0.463478 +v 0.520569 0.493051 0.457651 +v 0.422701 0.499123 0.488776 +v 0.477344 0.496380 0.471827 +v 0.404699 0.563449 0.480345 +v 0.456636 0.564673 0.462574 +v 0.501277 0.563990 0.447582 +v 0.264851 0.692584 0.412994 +v 0.371171 0.669377 0.423456 +v 0.205055 0.662430 0.459037 +v 0.289733 0.650389 0.463945 +v 0.232102 0.678126 0.435534 +v 0.328524 0.661703 0.442955 +v 0.110523 0.656624 0.456909 +v 0.123579 0.672602 0.432175 +v 0.137088 0.687742 0.411082 +v 0.450638 0.625551 0.435645 +v 0.358278 0.616884 0.471419 +v 0.405551 0.622549 0.452372 +v -0.282701 0.615994 0.426785 +v -0.185848 0.623861 0.455990 +v -0.201774 0.638423 0.425992 +v -0.246964 0.595316 0.458889 +v -0.267479 0.607542 0.436698 +v -0.089566 0.632617 0.455834 +v -0.098115 0.645785 0.425347 +v 0.013225 0.641537 0.456605 +v 0.015627 0.654519 0.430262 +v -0.223883 0.433299 0.498488 +v -0.191490 0.381518 0.504005 +v -0.133437 0.344469 0.507719 +v -0.228339 0.538174 0.486047 +v -0.236628 0.488825 0.492194 +v 0.211045 0.327401 0.514785 +v 0.123031 0.316369 0.514681 +v 0.282000 0.349703 0.514911 +v -0.057025 0.324450 0.511085 +v 0.324268 0.389651 0.514600 +v 0.349314 0.441559 0.512583 +v 0.352465 0.500413 0.507771 +v 0.337281 0.558993 0.500475 +v 0.248495 0.633700 0.486114 +v 0.179201 0.637837 0.484371 +v 0.099616 0.628873 0.484038 +v 0.300180 0.605970 0.492453 +v -0.204236 0.576424 0.481257 +v -0.150193 0.597488 0.480109 +v -0.071135 0.605511 0.482081 +v 0.015220 0.615001 0.483586 +v 0.017674 0.580161 0.510099 +v 0.017029 0.548295 0.524802 +v 0.016376 0.513863 0.533032 +v 0.017577 0.475190 0.537873 +v 0.021136 0.434389 0.538266 +v 0.026133 0.394033 0.533009 +v 0.030300 0.354574 0.524675 +v 0.031101 0.316361 0.513265 +v 0.030753 0.282293 0.499356 +v 0.030945 0.258960 0.484757 +v 0.031234 0.240639 0.472805 +v 0.030293 0.214474 0.458963 +v 0.040821 0.173859 0.439419 +v 0.044817 0.139220 0.409628 +v 0.046308 0.113477 0.370599 +v 0.049555 0.099983 0.323904 +v 0.706407 0.143913 0.029283 +v 0.758256 0.183928 0.029395 +v 0.642756 0.116576 0.026599 +v 0.799353 0.234130 0.029395 +v 0.828128 0.291368 0.029395 +v 0.845803 0.353544 0.029395 +v 0.858726 0.421384 0.029395 +v 0.859631 0.488595 0.032575 +v 0.849147 0.552091 0.032575 +v 0.828254 0.610226 0.032583 +v 0.799360 0.662007 0.032575 +v 0.767546 0.713433 0.032553 +v 0.729207 0.756569 0.031167 +v 0.690133 0.791475 0.030099 +v 0.649644 0.821214 0.028920 +v 0.615583 0.842063 0.025176 +v 0.591501 0.858263 0.021172 +v 0.570756 0.101525 0.022855 +v 0.066400 0.830734 0.086410 +v 0.056606 0.830193 0.029728 +v 0.079197 0.847475 0.081836 +v 0.067334 0.845266 0.028379 +v 0.103479 0.874003 0.139949 +v 0.076706 0.867590 0.086381 +v 0.061663 0.863527 0.033376 +v 0.043305 0.887008 0.045773 +v 0.059928 0.895698 0.101098 +v 0.092291 0.915427 0.171037 +v 0.195238 0.870994 0.206484 +v 0.143983 0.872706 0.178748 +v 0.145318 0.904728 0.205795 +v 0.195676 0.897173 0.224879 +v 0.262100 0.869437 0.221654 +v 0.258400 0.893162 0.235593 +v 0.350226 0.893874 0.233732 +v 0.350308 0.869496 0.219178 +v 0.450571 0.894178 0.198240 +v 0.444291 0.871742 0.186599 +v 0.528472 0.875160 0.123304 +v 0.541484 0.901992 0.131393 +v 0.585778 0.875953 0.022336 +v 0.591034 0.900324 0.033769 +v 0.015805 0.668139 0.412357 +v -0.318022 0.100858 -0.019710 +v -0.388006 0.116880 -0.019443 +v -0.452458 0.145410 -0.019814 +v -0.515643 0.182037 -0.021067 +v 0.707816 0.142259 -0.105137 +v 0.759308 0.182734 -0.106190 +v 0.643713 0.115264 -0.101319 +v 0.799368 0.233648 -0.106420 +v 0.826956 0.291294 -0.107480 +v 0.843683 0.353670 -0.110661 +v 0.856139 0.421370 -0.115317 +v 0.858037 0.489262 -0.120255 +v 0.847924 0.553455 -0.124133 +v 0.827112 0.612146 -0.126921 +v 0.796343 0.663979 -0.129219 +v 0.716684 0.756332 -0.127061 +v 0.760168 0.714278 -0.133949 +v -0.197310 0.779019 -0.019443 +v -0.202604 0.779924 -0.112248 +v -0.250219 0.786923 -0.018220 +v -0.252621 0.791542 -0.112952 +v -0.138211 0.783245 -0.018998 +v -0.143624 0.783676 -0.105812 +v 0.005996 0.810967 -0.011139 +v 0.005433 0.811205 -0.062216 +v -0.554464 0.924777 -0.033871 +v -0.489670 0.943801 -0.034331 +v -0.493845 0.929811 -0.153182 +v -0.431913 0.920224 -0.149719 +v -0.427435 0.927505 -0.032448 +v -0.663149 0.754782 -0.021186 +v -0.616254 0.866775 -0.029586 +v -0.568395 0.229229 -0.020429 +v -0.610434 0.280454 -0.113123 +v -0.613273 0.281670 -0.020007 +v -0.643531 0.342467 -0.111677 +v -0.646830 0.341592 -0.019280 +v -0.291664 0.803716 -0.016796 +v -0.291309 0.810871 -0.114450 +v -0.328632 0.835116 -0.019525 +v -0.326111 0.846875 -0.125304 +v 0.675801 0.791089 -0.122650 +v 0.634852 0.820057 -0.115406 +v -0.371383 0.889529 -0.029771 +v -0.373177 0.893021 -0.145323 +v -0.677244 0.426760 -0.018895 +v -0.692985 0.520358 -0.019836 +v -0.690782 0.590674 -0.019858 +v -0.680128 0.665870 -0.019636 +v 0.599983 0.840135 -0.107406 +v 0.577629 0.856098 -0.103506 +v 0.056880 0.830274 -0.007276 +v 0.057155 0.830356 -0.044281 +v 0.065095 0.844391 -0.009671 +v 0.063553 0.843783 -0.037215 +v 0.570919 0.100917 -0.095929 +v 0.057251 0.862104 -0.003317 +v 0.054597 0.861214 -0.032603 +v 0.037381 0.885303 0.011089 +v 0.032473 0.885844 -0.027243 +v 0.569280 0.897848 -0.105352 +v 0.564936 0.874619 -0.100800 +v -0.243405 0.114359 -0.383603 +v -0.161893 0.114130 -0.418242 +v -0.191772 0.099701 -0.345627 +v -0.120514 0.099939 -0.374698 +v -0.311060 0.114775 -0.329686 +v -0.251190 0.099294 -0.301860 +v -0.354745 0.116324 -0.256774 +v -0.290093 0.100524 -0.239684 +v -0.378441 0.117199 -0.179362 +v -0.309667 0.101577 -0.169998 +v 0.654167 0.183720 -0.346672 +v 0.610000 0.143030 -0.326913 +v 0.511145 0.178270 -0.437764 +v 0.469722 0.142133 -0.407944 +v 0.555386 0.114663 -0.302365 +v 0.429826 0.115093 -0.374209 +v -0.195197 0.143549 -0.453897 +v -0.289966 0.143787 -0.416404 +v -0.364880 0.144595 -0.353605 +v -0.412258 0.186322 -0.372200 +v -0.331887 0.185722 -0.442309 +v -0.227101 0.183816 -0.481723 +v -0.414341 0.144313 -0.271351 +v -0.441233 0.144447 -0.186976 +v -0.499064 0.181281 -0.194546 +v -0.466619 0.183928 -0.282843 +v 0.620944 0.114196 -0.205393 +v 0.682653 0.142141 -0.216559 +v 0.730378 0.183468 -0.225011 +v 0.709277 0.290352 -0.368544 +v 0.685692 0.234107 -0.360025 +v 0.593140 0.284606 -0.465397 +v 0.548395 0.227093 -0.457182 +v -0.268814 0.236917 -0.501401 +v -0.371724 0.237510 -0.458917 +v -0.455350 0.236628 -0.385063 +v -0.493615 0.288780 -0.390246 +v -0.413718 0.293444 -0.467703 +v -0.331991 0.298730 -0.507109 +v 0.766804 0.234678 -0.231566 +v 0.791575 0.291894 -0.236481 +v 0.725633 0.351268 -0.373883 +v 0.625170 0.348109 -0.466606 +v 0.734812 0.417559 -0.373453 +v 0.646226 0.415905 -0.465931 +v 0.806278 0.353877 -0.239899 +v 0.815568 0.421140 -0.243110 +v 0.639264 0.552231 -0.455736 +v 0.729066 0.550971 -0.370309 +v 0.652083 0.485511 -0.461149 +v 0.738400 0.485629 -0.373000 +v 0.816740 0.488988 -0.246283 +v 0.806871 0.553477 -0.248070 +v 0.558026 0.667664 -0.441694 +v 0.673080 0.664328 -0.361160 +v 0.607961 0.614452 -0.450316 +v 0.707794 0.611190 -0.367907 +v 0.786126 0.612650 -0.248040 +v 0.755475 0.665218 -0.246246 +v 0.439561 0.746649 -0.398150 +v 0.578297 0.752380 -0.341393 +v 0.491935 0.709503 -0.423484 +v 0.629885 0.710490 -0.351951 +v 0.714756 0.712009 -0.244489 +v 0.668647 0.754648 -0.244251 +v -0.122174 0.738819 -0.364385 +v -0.068569 0.761307 -0.332993 +v 0.022026 0.728765 -0.412252 +v 0.040999 0.758378 -0.374454 +v -0.020421 0.784120 -0.294750 +v 0.061870 0.785203 -0.334350 +v 0.153978 0.787998 -0.355147 +v 0.153904 0.761240 -0.389186 +v 0.155401 0.731894 -0.425115 +v -0.247876 0.765792 -0.197267 +v -0.186590 0.771776 -0.189697 +v -0.206749 0.749933 -0.288188 +v -0.145648 0.766133 -0.270075 +v -0.125340 0.782897 -0.176678 +v -0.083190 0.783549 -0.242702 +v 0.019646 0.812562 -0.183514 +v 0.007279 0.811872 -0.124148 +v 0.043446 0.811227 -0.241642 +v -0.558430 0.813140 -0.285504 +v -0.558163 0.872424 -0.220756 +v -0.498916 0.836109 -0.289872 +v -0.496254 0.893466 -0.224648 +v -0.437036 0.883494 -0.223158 +v -0.444451 0.826048 -0.289686 +v -0.444888 0.778752 -0.336648 +v -0.486808 0.772324 -0.345316 +v -0.541303 0.747924 -0.346324 +v -0.643131 0.696573 -0.258984 +v -0.655053 0.725896 -0.185049 +v -0.611227 0.761114 -0.272671 +v -0.617107 0.818990 -0.209783 +v -0.587835 0.707123 -0.341097 +v -0.619613 0.657536 -0.329553 +v -0.584469 0.603879 -0.391736 +v -0.550601 0.650337 -0.405186 +v -0.505077 0.687809 -0.406817 +v -0.434634 0.604480 -0.474894 +v -0.467190 0.553544 -0.480974 +v -0.492087 0.491998 -0.473723 +v -0.541830 0.459931 -0.422824 +v -0.589689 0.437199 -0.355858 +v -0.613029 0.558348 -0.362984 +v -0.638549 0.525711 -0.320063 +v -0.651954 0.570723 -0.295143 +v -0.639335 0.607290 -0.311655 +v -0.512017 0.231727 -0.290783 +v -0.549570 0.228131 -0.199766 +v -0.592654 0.279119 -0.202361 +v -0.551520 0.282115 -0.295499 +v -0.039639 0.360409 -0.595080 +v -0.093266 0.366667 -0.590505 +v -0.043791 0.395768 -0.598409 +v -0.112032 0.394137 -0.590290 +v -0.130864 0.433447 -0.588481 +v -0.052221 0.434715 -0.598809 +v -0.458464 0.354359 -0.463143 +v -0.530760 0.342815 -0.385249 +v -0.397533 0.373377 -0.501979 +v -0.586945 0.336906 -0.294149 +v -0.631283 0.334630 -0.201464 +v -0.663446 0.421948 -0.194391 +v -0.631328 0.425522 -0.278513 +v -0.142200 0.519030 -0.580496 +v -0.060065 0.513551 -0.590490 +v -0.142141 0.477244 -0.584915 +v -0.058419 0.475145 -0.595984 +v -0.111349 0.654890 -0.486957 +v -0.217418 0.640098 -0.492903 +v -0.139368 0.678282 -0.459206 +v -0.250582 0.659138 -0.472878 +v -0.300695 0.773155 -0.205683 +v -0.273062 0.738878 -0.303291 +v -0.215757 0.712928 -0.393886 +v -0.331287 0.693852 -0.414713 +v -0.342579 0.739026 -0.308400 +v -0.344892 0.800254 -0.215618 +v 0.342382 0.805703 -0.342498 +v 0.486990 0.811865 -0.308689 +v 0.392161 0.776454 -0.370836 +v 0.527939 0.784766 -0.328685 +v 0.297051 0.737336 -0.420511 +v 0.271279 0.767275 -0.388845 +v 0.252180 0.793136 -0.358083 +v 0.623879 0.789177 -0.242442 +v 0.579394 0.817173 -0.232211 +v 0.095242 0.810708 -0.287966 +v 0.165759 0.811153 -0.318950 +v -0.403947 0.733170 -0.365831 +v -0.396428 0.780687 -0.298339 +v -0.386256 0.846334 -0.221512 +v -0.661326 0.513373 -0.258257 +v -0.680395 0.512550 -0.183870 +v -0.680180 0.582133 -0.178183 +v -0.666864 0.575891 -0.246884 +v -0.451368 0.712869 -0.396934 +v -0.391943 0.648054 -0.457138 +v -0.658464 0.634174 -0.250094 +v -0.670838 0.651042 -0.179110 +v 0.544673 0.836613 -0.215529 +v 0.460958 0.832499 -0.286417 +v 0.441941 0.851190 -0.267866 +v 0.521903 0.853592 -0.204029 +v 0.179216 0.832039 -0.290153 +v 0.252513 0.810708 -0.333601 +v 0.258474 0.831357 -0.308770 +v 0.190219 0.850345 -0.274843 +v 0.261633 0.850641 -0.293275 +v 0.347653 0.850426 -0.294209 +v 0.350315 0.830667 -0.312656 +v 0.121451 0.832039 -0.255855 +v 0.083757 0.831824 -0.211125 +v 0.099409 0.849232 -0.200693 +v 0.137244 0.849789 -0.242465 +v 0.493922 0.100272 -0.273241 +v 0.387965 0.100502 -0.336129 +v 0.141870 0.099360 -0.395629 +v 0.147802 0.113848 -0.440174 +v 0.254849 0.099383 -0.379992 +v 0.277425 0.114278 -0.421534 +v -0.032588 0.113870 -0.439714 +v -0.009262 0.099627 -0.395747 +v 0.550359 0.100176 -0.190023 +v 0.156372 0.139546 -0.478631 +v 0.300780 0.141043 -0.457664 +v 0.169221 0.174452 -0.508066 +v 0.327953 0.177996 -0.488099 +v -0.059761 0.142111 -0.475917 +v -0.090641 0.181577 -0.505723 +v 0.188513 0.362745 -0.605645 +v 0.113896 0.357436 -0.602776 +v 0.184480 0.400625 -0.612347 +v 0.108610 0.397903 -0.608997 +v 0.104495 0.439097 -0.610858 +v 0.183879 0.443219 -0.613282 +v 0.265918 0.446467 -0.610071 +v 0.255709 0.401514 -0.609249 +v 0.242460 0.370634 -0.605519 +v 0.179876 0.487616 -0.610605 +v 0.099846 0.480417 -0.607803 +v 0.094560 0.519980 -0.600277 +v 0.171720 0.530256 -0.601664 +v 0.254626 0.544929 -0.595273 +v 0.267053 0.497018 -0.606231 +v 0.162348 0.567727 -0.588674 +v 0.090245 0.556280 -0.588755 +v 0.090067 0.589948 -0.572808 +v 0.159709 0.599690 -0.573289 +v 0.213366 0.605555 -0.572059 +v 0.232776 0.582326 -0.582090 +v 0.155861 0.700443 -0.460785 +v 0.329162 0.700487 -0.455996 +v 0.441377 0.664765 -0.474420 +v 0.512480 0.616595 -0.487462 +v 0.555401 0.555242 -0.497715 +v 0.570734 0.488091 -0.505693 +v 0.560065 0.419561 -0.512803 +v 0.525663 0.353329 -0.516029 +v 0.465132 0.292250 -0.515050 +v 0.175056 0.214015 -0.531414 +v 0.357529 0.232580 -0.514249 +v -0.135854 0.239342 -0.526112 +v -0.248654 0.303579 -0.528774 +v -0.323879 0.370560 -0.526379 +v -0.375950 0.446801 -0.517631 +v -0.363175 0.565451 -0.506094 +v -0.380947 0.508613 -0.514190 +v -0.322767 0.620154 -0.492051 +v -0.130315 0.552283 -0.575699 +v -0.057574 0.547064 -0.582557 +v -0.056580 0.575512 -0.570761 +v -0.111972 0.572725 -0.569708 +v 0.013818 0.689774 -0.459569 +v -0.322894 0.431438 -0.531362 +v -0.278334 0.368602 -0.538620 +v -0.216936 0.374949 -0.562842 +v -0.248684 0.370434 -0.548511 +v -0.262193 0.426871 -0.556006 +v -0.295994 0.427331 -0.540504 +v -0.150875 0.333422 -0.567928 +v -0.177196 0.321054 -0.553997 +v -0.203917 0.312343 -0.542831 +v -0.328298 0.553737 -0.514331 +v -0.337448 0.492984 -0.523954 +v -0.285177 0.485533 -0.547769 +v -0.315250 0.488313 -0.531740 +v -0.285919 0.544558 -0.538865 +v -0.310452 0.549518 -0.521567 +v 0.295034 0.260458 -0.540829 +v 0.158893 0.239164 -0.547310 +v 0.133618 0.277844 -0.577174 +v 0.237499 0.294563 -0.576722 +v 0.144814 0.256447 -0.559766 +v 0.264258 0.275071 -0.556637 +v 0.318122 0.331212 -0.576826 +v 0.356595 0.316265 -0.556473 +v 0.396795 0.305618 -0.538806 +v -0.100503 0.265855 -0.545085 +v -0.068028 0.301029 -0.572111 +v -0.083361 0.281588 -0.557549 +v 0.462530 0.362100 -0.537901 +v 0.370326 0.381125 -0.577227 +v 0.416947 0.370493 -0.556696 +v 0.398055 0.439520 -0.575439 +v 0.450786 0.432372 -0.554835 +v 0.500128 0.425536 -0.535439 +v 0.511390 0.492547 -0.529597 +v 0.406137 0.501599 -0.570286 +v 0.461069 0.497648 -0.549594 +v 0.389151 0.561492 -0.560878 +v 0.442682 0.561306 -0.540718 +v 0.493210 0.558341 -0.520848 +v 0.371431 0.657944 -0.498316 +v 0.267320 0.680261 -0.487847 +v 0.204387 0.657863 -0.531414 +v 0.232554 0.670170 -0.508845 +v 0.285307 0.643375 -0.538731 +v 0.326130 0.653459 -0.518098 +v 0.108825 0.652576 -0.528604 +v 0.122638 0.666664 -0.503239 +v 0.136339 0.678667 -0.486371 +v 0.446241 0.616202 -0.510127 +v 0.348580 0.611842 -0.549200 +v 0.396610 0.615616 -0.529449 +v -0.292399 0.607943 -0.502557 +v -0.188250 0.619909 -0.528915 +v -0.254638 0.591765 -0.531910 +v -0.204769 0.631994 -0.503046 +v -0.276280 0.601306 -0.511217 +v -0.091835 0.631068 -0.528225 +v -0.101563 0.644547 -0.500444 +v 0.010964 0.639090 -0.528700 +v 0.014789 0.650285 -0.502728 +v -0.203457 0.430689 -0.573067 +v -0.168788 0.385536 -0.577812 +v -0.121122 0.350371 -0.581689 +v -0.222438 0.531256 -0.560203 +v -0.222779 0.481633 -0.566920 +v 0.209614 0.327638 -0.593975 +v 0.122904 0.317184 -0.591973 +v 0.277581 0.352002 -0.594961 +v -0.051561 0.328988 -0.585686 +v 0.317892 0.392914 -0.596303 +v 0.338971 0.444969 -0.595273 +v 0.342463 0.501711 -0.589927 +v 0.327486 0.555991 -0.579969 +v 0.245692 0.625262 -0.558246 +v 0.177651 0.631379 -0.554049 +v 0.096903 0.623164 -0.552589 +v 0.293959 0.599275 -0.567944 +v -0.199928 0.570804 -0.554805 +v -0.149222 0.593774 -0.552218 +v -0.072388 0.603598 -0.552040 +v 0.012461 0.612169 -0.552299 +v 0.015449 0.581214 -0.571999 +v 0.016428 0.549177 -0.586553 +v 0.018074 0.514352 -0.596459 +v 0.021514 0.476250 -0.602798 +v 0.026356 0.436332 -0.605215 +v 0.031420 0.396169 -0.604303 +v 0.034549 0.356754 -0.599047 +v 0.033214 0.318267 -0.589081 +v 0.028180 0.259316 -0.560077 +v 0.030196 0.283271 -0.575284 +v 0.025518 0.216054 -0.533934 +v 0.027290 0.241781 -0.548289 +v 0.036239 0.175846 -0.512515 +v 0.042793 0.140176 -0.483510 +v 0.045662 0.114122 -0.445415 +v 0.045989 0.099768 -0.400908 +v -0.387872 0.117814 -0.103899 +v -0.317926 0.101666 -0.099777 +v -0.452866 0.145017 -0.108326 +v -0.513804 0.182081 -0.111306 +v -0.554174 0.911379 -0.151558 +v -0.655402 0.747902 -0.111558 +v -0.608729 0.856046 -0.142238 +v -0.564851 0.228762 -0.112211 +v -0.672833 0.424839 -0.109141 +v -0.690093 0.516317 -0.106220 +v -0.688802 0.586841 -0.104374 +v -0.676547 0.661837 -0.104878 +v 0.051772 0.830067 -0.104967 +v 0.063101 0.846215 -0.095907 +v 0.060373 0.830742 -0.161330 +v 0.074630 0.848157 -0.151358 +v 0.055308 0.866678 -0.092444 +v 0.023931 0.903705 -0.098568 +v 0.099194 0.869399 -0.199543 +v 0.071205 0.868962 -0.150149 +v 0.052550 0.898204 -0.162020 +v 0.086752 0.895668 -0.209938 +v 0.191716 0.869829 -0.271848 +v 0.138867 0.869385 -0.240596 +v 0.129607 0.894230 -0.249078 +v 0.183501 0.894171 -0.279721 +v 0.259809 0.870964 -0.289590 +v 0.250482 0.895646 -0.299540 +v 0.327991 0.897151 -0.304233 +v 0.340372 0.871164 -0.290287 +v 0.413633 0.901718 -0.287054 +v 0.428321 0.872394 -0.265835 +v 0.509529 0.873143 -0.206038 +v 0.508728 0.906708 -0.236459 +v -0.112981 1.226920 0.096968 +v -0.104921 1.277670 0.104464 +v -0.116043 1.227810 0.086848 +v -0.111023 1.279440 0.084156 +v -0.109770 1.223660 0.106888 +v -0.098597 1.271220 0.124230 +v -0.106656 1.218200 0.115860 +v -0.092465 1.260370 0.142114 +v -0.103765 1.210780 0.123445 +v -0.086808 1.245610 0.157276 +v -0.101237 1.201750 0.129302 +v -0.081863 1.227640 0.168946 +v -0.099183 1.191560 0.133142 +v -0.077896 1.207330 0.176635 +v -0.097722 1.180670 0.134803 +v -0.074931 1.185630 0.179719 +v -0.096877 1.169600 0.134188 +v -0.073344 1.163630 0.178451 +v -0.096706 1.158870 0.131341 +v -0.073085 1.142330 0.172735 +v -0.097233 1.148990 0.126358 +v -0.074182 1.122730 0.162733 +v -0.098582 1.140210 0.118907 +v -0.076999 1.105340 0.147860 +v -0.101429 1.132540 0.107089 +v -0.082775 1.090330 0.124727 +v -0.107227 1.129140 0.087189 +v -0.093578 1.080800 0.085424 +v -0.104380 1.130060 0.096753 +v -0.088499 1.083950 0.104182 +v -0.090493 1.327370 0.109810 +v -0.099561 1.329980 0.079626 +v -0.081114 1.317810 0.139103 +v -0.072032 1.301730 0.165602 +v -0.063661 1.279880 0.188075 +v -0.056402 1.253280 0.205468 +v -0.050582 1.223180 0.216961 +v -0.046482 1.190990 0.222025 +v -0.044228 1.158240 0.220238 +v -0.043976 1.126500 0.211845 +v -0.045629 1.097460 0.196875 +v -0.049707 1.072110 0.173891 +v -0.058308 1.049900 0.140223 +v -0.067205 1.038920 0.109765 +v -0.070141 1.375370 0.112983 +v -0.082048 1.378790 0.073369 +v -0.057855 1.362840 0.151374 +v -0.045956 1.341760 0.186110 +v -0.034983 1.313130 0.215559 +v -0.025463 1.278270 0.238351 +v -0.017841 1.238830 0.253417 +v -0.012465 1.196640 0.260060 +v -0.009589 1.153670 0.257954 +v -0.009322 1.112020 0.247018 +v -0.011568 1.074110 0.226977 +v -0.017196 1.040940 0.196809 +v -0.028562 1.011430 0.153198 +v -0.040121 0.996658 0.113213 +v -0.058745 1.425160 0.065480 +v -0.044176 1.420980 0.113954 +v -0.029162 1.405660 0.160879 +v -0.014608 1.379890 0.203341 +v -0.001196 1.344890 0.239337 +v 0.010437 1.302290 0.267200 +v 0.019757 1.254070 0.285617 +v 0.026326 1.202490 0.293728 +v 0.029840 1.149980 0.291163 +v 0.030130 1.098970 0.278025 +v 0.027223 1.052480 0.253810 +v 0.020039 1.013150 0.214907 +v 0.006908 0.979167 0.163207 +v -0.008061 0.958341 0.113643 +v -0.029985 1.468400 0.056071 +v -0.012970 1.463530 0.112694 +v 0.004558 1.445640 0.167478 +v 0.021544 1.415560 0.217035 +v 0.037203 1.374700 0.259059 +v 0.050786 1.324970 0.291585 +v 0.061663 1.268690 0.313079 +v 0.069336 1.208480 0.322555 +v 0.073429 1.147180 0.319552 +v 0.073770 1.087640 0.304219 +v 0.070256 1.033350 0.275927 +v 0.061596 0.988146 0.229217 +v 0.046730 0.948688 0.169057 +v 0.027386 0.925778 0.109750 +v 0.003809 1.507890 0.045284 +v 0.023019 1.502390 0.109231 +v 0.042808 1.482200 0.171066 +v 0.061981 1.448250 0.227007 +v 0.079650 1.402130 0.274444 +v 0.094982 1.346000 0.311152 +v 0.107268 1.282460 0.335419 +v 0.115920 1.214500 0.346110 +v 0.120547 1.145310 0.342722 +v 0.120932 1.078100 0.325417 +v 0.116995 1.016280 0.294492 +v 0.107461 0.964739 0.241724 +v 0.042141 1.543050 0.033265 +v 0.063271 1.537000 0.103604 +v 0.085032 1.514810 0.171593 +v 0.106111 1.477490 0.233102 +v 0.125537 1.426770 0.285254 +v 0.142397 1.365050 0.325617 +v 0.155905 1.295190 0.352301 +v 0.165418 1.220480 0.364053 +v 0.170504 1.144390 0.360331 +v 0.170919 1.070500 0.341306 +v 0.166589 1.002580 0.307400 +v 0.157233 0.947279 0.257910 +v 0.084454 1.573380 0.020208 +v 0.107201 1.566870 0.095908 +v 0.130608 1.542990 0.169057 +v 0.153288 1.502830 0.235229 +v 0.174189 1.448270 0.291348 +v 0.192332 1.381860 0.334774 +v 0.206856 1.306700 0.363481 +v 0.217103 1.226310 0.376123 +v 0.222575 1.144450 0.372119 +v 0.223019 1.064950 0.351648 +v 0.218259 0.992209 0.314888 +v 0.208250 0.933985 0.265962 +v 0.130133 1.598420 0.006284 +v 0.154163 1.591540 0.086247 +v 0.178875 1.566330 0.163489 +v 0.202830 1.523920 0.233369 +v 0.224903 1.466310 0.292623 +v 0.244054 1.396180 0.338481 +v 0.259394 1.316820 0.368790 +v 0.270211 1.231930 0.382151 +v 0.275987 1.145490 0.377917 +v 0.276461 1.061530 0.356297 +v 0.271561 0.984202 0.318069 +v 0.262026 0.923353 0.267949 +v 0.178512 1.617810 -0.008292 +v 0.203468 1.610670 0.074755 +v 0.229136 1.584490 0.154970 +v 0.254011 1.540450 0.227534 +v 0.276929 1.480630 0.289072 +v 0.296814 1.407800 0.336686 +v 0.312747 1.325390 0.368168 +v 0.323972 1.237240 0.382032 +v 0.330378 1.147320 0.377776 +v 0.331394 1.060040 0.355511 +v 0.325863 0.979694 0.315919 +v 0.319650 0.913737 0.262299 +v 0.254700 1.634940 -0.030935 +v 0.280317 1.627610 0.054322 +v 0.306652 1.600740 0.136627 +v 0.332180 1.555560 0.211096 +v 0.355698 1.494160 0.274236 +v 0.376109 1.419430 0.323103 +v 0.392458 1.334870 0.355408 +v 0.403779 1.244400 0.368931 +v 0.410778 1.151820 0.363645 +v 0.413685 1.062510 0.343441 +v 0.405714 0.980124 0.300964 +v 0.394830 0.908428 0.245869 +v 0.332647 1.639700 -0.053801 +v 0.358181 1.632410 0.031167 +v 0.384420 1.605640 0.113176 +v 0.409852 1.560620 0.187370 +v 0.455605 1.501640 0.241539 +v 0.469596 1.435120 0.285313 +v 0.487731 1.361430 0.309839 +v 0.481273 1.251120 0.341698 +v 0.495294 1.162890 0.342469 +v 0.499179 1.071130 0.324260 +v 0.486893 0.988206 0.278254 +v 0.472243 0.916280 0.221780 +v 0.384532 1.634550 -0.068822 +v 0.409503 1.627420 0.014292 +v 0.435171 1.601230 0.094507 +v 0.477967 1.551730 0.173906 +v 0.531913 1.293920 0.304605 +v 0.574434 1.201870 0.303530 +v 0.577555 1.088810 0.291971 +v 0.565010 1.003490 0.248901 +v 0.544406 0.934897 0.186510 +v 0.435401 1.623220 -0.083413 +v 0.459453 1.616360 -0.003354 +v 0.504154 1.581240 0.099519 +v 0.484521 1.605890 -0.097345 +v 0.507305 1.599390 -0.021512 +v 0.543182 1.576140 0.062314 +v 0.639101 1.100600 0.247226 +v 0.638033 1.195650 0.253861 +v 0.629010 1.022190 0.209027 +v 0.607679 0.960876 0.147059 +v 0.531171 1.582800 -0.110416 +v 0.552347 1.576750 -0.039921 +v 0.581900 1.558720 0.028075 +v 0.672969 1.195730 0.210355 +v 0.677537 1.112500 0.200049 +v 0.673733 1.039200 0.171459 +v 0.650430 0.981407 0.115222 +v 0.574671 1.554290 -0.122450 +v 0.593940 1.548790 -0.058316 +v 0.621915 1.529820 0.001035 +v 0.708076 1.122690 0.156490 +v 0.696977 1.198480 0.165973 +v 0.704413 1.060390 0.128968 +v 0.685447 1.007250 0.081991 +v 0.614382 1.520770 -0.133260 +v 0.631457 1.515900 -0.076422 +v 0.657800 1.494270 -0.020437 +v 0.728213 1.199410 0.109157 +v 0.729933 1.135600 0.101899 +v 0.726093 1.091230 0.072301 +v 0.716506 1.049860 0.006840 +v 0.663361 0.952358 0.001532 +v 0.714208 1.026920 -0.059369 +v 0.643527 0.948043 -0.125052 +v 0.600369 0.914033 -0.110824 +v 0.623057 0.925874 0.029313 +v 0.661158 1.463140 -0.145560 +v 0.676306 1.456560 -0.088737 +v 0.689370 1.446410 -0.047313 +v 0.679679 1.431890 -0.150231 +v 0.698430 1.418360 -0.093082 +v 0.699913 1.401690 -0.155436 +v 0.718760 1.387490 -0.096907 +v -0.113759 1.176340 0.087782 +v 0.617689 1.387380 0.169517 +v 0.634504 1.401090 0.152998 +v 0.607657 1.404450 0.166648 +v 0.623546 1.414470 0.151878 +v 0.596128 1.397500 0.175893 +v 0.605626 1.375760 0.180038 +v 0.601192 1.420660 0.159826 +v 0.591790 1.418150 0.165439 +v 0.614471 1.425870 0.149150 +v 0.641066 1.356200 0.164201 +v 0.655909 1.372420 0.149847 +v 0.629418 1.371000 0.168738 +v 0.645685 1.386720 0.152167 +v 0.617458 1.355830 0.178214 +v 0.630381 1.339840 0.171452 +v 0.659460 1.333900 0.147222 +v 0.667994 1.346350 0.141328 +v 0.651157 1.343610 0.156497 +v 0.663464 1.358610 0.145969 +v 0.643364 1.328660 0.161250 +v 0.654233 1.320970 0.149091 +v 0.673889 1.336510 0.131986 +v 0.669492 1.337140 0.138169 +v 0.672903 1.329390 0.128657 +v 0.666044 1.328320 0.138036 +v 0.663694 1.317910 0.136738 +v 0.672154 1.320190 0.124453 +v 0.679657 1.328940 0.113154 +v 0.685151 1.343060 0.103248 +v 0.679094 1.337280 0.120538 +v 0.682793 1.350090 0.114955 +v 0.677907 1.342830 0.127419 +v 0.677410 1.352820 0.128723 +v 0.668854 1.381870 0.129695 +v 0.674912 1.366730 0.129257 +v 0.677633 1.383550 0.107993 +v 0.682460 1.366220 0.110736 +v 0.686738 1.360940 0.095144 +v 0.682882 1.380590 0.089658 +v 0.648184 1.411260 0.131519 +v 0.659438 1.396930 0.130347 +v 0.656517 1.416850 0.109157 +v 0.668721 1.400780 0.107355 +v 0.673615 1.400390 0.087849 +v 0.660150 1.418920 0.090614 +v 0.625229 1.433430 0.132497 +v 0.636091 1.423650 0.132305 +v 0.628610 1.439670 0.117343 +v 0.642593 1.430150 0.112634 +v 0.644194 1.433740 0.096968 +v 0.627831 1.443630 0.105976 +v 0.610674 1.439460 0.138533 +v 0.617844 1.440050 0.131407 +v 0.606115 1.441970 0.136175 +v 0.616205 1.444010 0.124393 +v 0.613218 1.447720 0.117684 +v 0.601096 1.444640 0.133409 +v 0.600361 1.433450 0.149402 +v 0.608028 1.433410 0.146881 +v 0.593318 1.434570 0.150788 +v 0.599546 1.375790 0.212023 +v 0.615272 1.345310 0.206551 +v 0.604639 1.374640 0.200420 +v 0.618763 1.348310 0.195882 +v 0.635846 1.334490 0.177798 +v 0.622167 1.351300 0.185205 +v 0.634845 1.328570 0.187674 +v 0.605959 1.487290 0.145628 +v 0.595052 1.473310 0.173142 +v 0.607479 1.470300 0.141165 +v 0.597648 1.457920 0.165098 +v 0.596002 1.423930 0.173936 +v 0.600235 1.442530 0.157061 +v 0.591931 1.435850 0.184382 +v 0.587861 1.447770 0.194836 +v 0.588328 1.412040 0.208056 +v 0.594081 1.405660 0.196623 +v 0.609733 1.373500 0.188824 +v 0.599835 1.399270 0.185190 +v 0.653699 1.307060 0.186303 +v 0.651653 1.315030 0.176961 +v 0.633644 1.322440 0.197795 +v 0.661373 1.315230 0.154970 +v 0.649258 1.322800 0.167923 +v 0.665740 1.306540 0.161776 +v 0.670122 1.297640 0.168798 +v 0.683045 1.293870 0.147556 +v 0.677426 1.303220 0.143856 +v 0.671776 1.312360 0.140179 +v 0.680977 1.314720 0.124801 +v 0.687983 1.305810 0.125261 +v 0.689044 1.323350 0.109928 +v 0.698230 1.317360 0.106896 +v 0.695345 1.338850 0.096486 +v 0.706207 1.336360 0.089984 +v 0.707571 1.310990 0.103129 +v 0.695049 1.297050 0.125735 +v 0.714393 1.360840 0.066659 +v 0.706489 1.359760 0.077083 +v 0.715801 1.333930 0.082043 +v 0.697696 1.359520 0.085068 +v 0.694233 1.382730 0.077617 +v 0.700306 1.385290 0.068787 +v 0.691838 1.417040 0.056301 +v 0.687916 1.411090 0.066273 +v 0.706155 1.388550 0.058347 +v 0.683794 1.405730 0.075586 +v 0.668358 1.426310 0.079953 +v 0.670790 1.435100 0.071374 +v 0.652209 1.467150 0.076386 +v 0.651046 1.454640 0.082837 +v 0.673192 1.443950 0.062766 +v 0.649874 1.442120 0.089287 +v 0.633399 1.452410 0.101906 +v 0.634081 1.468120 0.098429 +v 0.619527 1.490980 0.118158 +v 0.619742 1.473540 0.117839 +v 0.634756 1.483830 0.094952 +v 0.619957 1.456110 0.117513 +v 0.608999 1.453300 0.136701 +v 0.641940 1.320520 0.163667 +v 0.653848 1.313230 0.150306 +v 0.628195 1.331840 0.174640 +v 0.592072 1.394850 0.180623 +v 0.601659 1.370600 0.184575 +v 0.588061 1.417700 0.168434 +v 0.614122 1.348870 0.181943 +v 0.664087 1.310470 0.136130 +v 0.673103 1.313110 0.121873 +v 0.590411 1.435720 0.151678 +v 0.598997 1.446270 0.132097 +v 0.686945 1.336970 0.096301 +v 0.680821 1.321890 0.108290 +v 0.611490 1.449740 0.114258 +v 0.626779 1.445730 0.100134 +v 0.685944 1.377830 0.079419 +v 0.689548 1.356240 0.086166 +v 0.643898 1.435340 0.088650 +v 0.661373 1.419720 0.080323 +v 0.675801 1.399480 0.077291 +v 0.717477 1.300250 0.095671 +v 0.725233 1.329830 0.067081 +v 0.703049 1.281940 0.127300 +v 0.721177 1.363200 0.047730 +v 0.708876 1.397010 0.038848 +v 0.623546 1.311570 0.227541 +v 0.592932 1.342010 0.238217 +v 0.573232 1.381680 0.244749 +v 0.650801 1.493590 0.059719 +v 0.626852 1.515750 0.081636 +v 0.673926 1.462790 0.044134 +v 0.560087 1.473270 0.216990 +v 0.569459 1.504090 0.185398 +v 0.585355 1.521520 0.147897 +v 0.561303 1.429470 0.237928 +v 0.674163 1.282030 0.185732 +v 0.652135 1.292830 0.209902 +v 0.689562 1.277830 0.157988 +v 0.692988 1.429880 0.036957 +v 0.605470 1.526100 0.111863 +v 0.726026 1.275660 0.084757 +v 0.729533 1.316260 0.043348 +v 0.713592 1.253400 0.126099 +v 0.723965 1.360970 0.017050 +v 0.708958 1.402880 0.008005 +v 0.565247 1.326140 0.276949 +v 0.604142 1.284850 0.253476 +v 0.533566 1.373680 0.280990 +v 0.636929 1.516850 0.030878 +v 0.601785 1.544540 0.056561 +v 0.668521 1.481520 0.015463 +v 0.520220 1.530090 0.189305 +v 0.504599 1.493210 0.234570 +v 0.544777 1.551900 0.140957 +v 0.511249 1.442260 0.268356 +v 0.639865 1.265080 0.225154 +v 0.668083 1.256100 0.196379 +v 0.692202 1.252380 0.165350 +v 0.690541 1.443170 0.006929 +v 0.572187 1.556610 0.095612 +v 0.739550 1.298720 0.009562 +v 0.738222 1.240510 0.068876 +v 0.729303 1.354320 -0.032537 +v 0.711249 1.402380 -0.038720 +v 0.759205 1.175270 -0.094261 +v 0.761644 1.165720 -0.088314 +v 0.749633 1.165530 -0.097389 +v 0.759716 1.160370 -0.099236 +v 0.750849 1.163660 -0.090413 +v 0.746763 1.172260 -0.133023 +v 0.754185 1.158820 -0.138516 +v 0.740417 1.171570 -0.161597 +v 0.748654 1.158130 -0.163999 +v 0.757054 1.158950 -0.117089 +v 0.747512 1.169600 -0.112522 +v 0.760488 1.194380 -0.126624 +v 0.757440 1.187320 -0.108711 +v 0.778207 1.215290 -0.173927 +v 0.787980 1.215280 -0.136567 +v 0.750456 1.191620 -0.164370 +v 0.781707 1.271100 -0.044585 +v 0.766107 1.274950 -0.038134 +v 0.769644 1.222050 0.029432 +v 0.756269 1.218570 0.036572 +v 0.749870 1.208080 0.062003 +v 0.752258 1.283800 -0.027554 +v 0.725032 1.082230 -0.020948 +v 0.730430 1.068750 -0.103143 +v 0.758359 1.081570 -0.044555 +v 0.758715 1.073380 -0.109986 +v 0.752065 1.065250 -0.162769 +v 0.723201 1.059690 -0.152641 +v 0.756543 1.314570 -0.074183 +v 0.742945 1.317870 -0.068385 +v 0.741744 1.347690 -0.119588 +v 0.730089 1.347230 -0.116266 +v 0.759894 1.341760 -0.124407 +v 0.776673 1.309200 -0.079721 +v 0.817666 1.276210 -0.059139 +v 0.799509 1.273830 -0.051265 +v 0.815976 1.228730 0.008286 +v 0.795957 1.227830 0.019964 +v 0.764239 1.173640 0.074970 +v 0.794986 1.176560 0.067296 +v 0.766345 1.202050 0.060772 +v 0.796098 1.203600 0.048864 +v 0.821877 1.171110 0.046662 +v 0.823917 1.199360 0.032813 +v 0.795468 1.143050 0.059066 +v 0.766804 1.140450 0.071975 +v 0.783479 1.084710 -0.058005 +v 0.790322 1.100080 0.016598 +v 0.764373 1.098760 0.033851 +v 0.814612 1.109020 -0.002969 +v 0.807256 1.087850 -0.071291 +v 0.780128 1.076350 -0.120211 +v 0.801169 1.081170 -0.136233 +v 0.773477 1.069010 -0.169108 +v 0.798634 1.073080 -0.176552 +v 0.778467 1.335640 -0.129456 +v 0.795268 1.307580 -0.084778 +v 0.801251 1.328420 -0.135803 +v 0.813351 1.306110 -0.090620 +v 0.835075 1.176850 0.024687 +v 0.834830 1.161490 0.026288 +v 0.830011 1.140260 0.035037 +v 0.903783 1.106340 -0.091577 +v 0.917610 1.086720 -0.141260 +v 0.911709 1.122570 -0.101186 +v 0.924261 1.110420 -0.148022 +v 0.892610 1.078960 -0.127825 +v 0.888584 1.091040 -0.092718 +v 0.921266 1.098890 -0.180081 +v 0.913177 1.072670 -0.176789 +v 0.913867 1.094570 -0.211013 +v 0.904702 1.070670 -0.207351 +v 0.883001 1.061640 -0.200804 +v 0.889763 1.066660 -0.167455 +v 0.943976 1.383990 -0.171755 +v 0.943523 1.358040 -0.113701 +v 0.960984 1.367890 -0.174832 +v 0.961799 1.340370 -0.114887 +v 0.938845 1.316450 -0.074546 +v 0.954037 1.294020 -0.075814 +v 0.791990 1.163970 -0.077482 +v 0.789833 1.186590 -0.093363 +v 0.819698 1.177060 -0.065760 +v 0.823405 1.195790 -0.092659 +v 0.823865 1.157920 -0.033997 +v 0.816235 1.160260 -0.053727 +v 0.782737 1.157730 -0.097916 +v 0.808413 1.153690 -0.096537 +v 0.798693 1.144930 -0.148934 +v 0.774160 1.150640 -0.143959 +v 0.803171 1.148150 -0.124815 +v 0.778096 1.152650 -0.120804 +v 0.768324 1.149440 -0.169597 +v 0.792991 1.142950 -0.176596 +v 0.831835 1.233750 -0.005660 +v 0.835372 1.280100 -0.067851 +v 0.848272 1.292100 -0.074805 +v 0.852625 1.245870 -0.018108 +v 0.835372 1.168960 -0.030972 +v 0.841318 1.185710 -0.063610 +v 0.857451 1.178060 -0.035258 +v 0.862686 1.193130 -0.066583 +v 0.847701 1.204770 -0.093734 +v 0.868232 1.214140 -0.095276 +v 0.833881 1.170340 -0.003228 +v 0.857155 1.178140 -0.010983 +v 0.828751 1.156580 -0.005445 +v 0.828336 1.160650 -0.002435 +v 0.840376 1.183100 0.012490 +v 0.859097 1.188860 0.003252 +v 0.850712 1.232250 -0.118706 +v 0.824806 1.220500 -0.115955 +v 0.871182 1.244050 -0.120018 +v 0.846456 1.240170 -0.151551 +v 0.864413 1.249100 -0.156051 +v 0.824754 1.230100 -0.145108 +v 0.888191 1.282750 -0.045667 +v 0.901959 1.307080 -0.064655 +v 0.871990 1.317760 -0.091606 +v 0.880999 1.332290 -0.102009 +v 0.887516 1.344160 -0.111099 +v 0.911968 1.334190 -0.090101 +v 0.922897 1.238180 -0.072025 +v 0.918070 1.243320 -0.090338 +v 0.942515 1.269910 -0.096262 +v 0.934241 1.268200 -0.108934 +v 0.915661 1.253000 -0.110513 +v 0.927753 1.268380 -0.118772 +v 0.899564 1.236240 -0.102795 +v 0.899394 1.222500 -0.079002 +v 0.901003 1.213410 -0.057886 +v 0.904806 1.214590 -0.040559 +v 0.929703 1.240470 -0.055906 +v 0.908128 1.225360 -0.029371 +v 0.934426 1.253580 -0.045556 +v 0.950537 1.278610 -0.084207 +v 0.866067 1.335980 -0.115288 +v 0.875542 1.347820 -0.123095 +v 0.859460 1.340220 -0.153694 +v 0.868728 1.351080 -0.158513 +v 0.885707 1.358520 -0.129256 +v 0.880213 1.363270 -0.164059 +v 0.913940 1.278080 -0.132948 +v 0.898207 1.264650 -0.126372 +v 0.929117 1.288170 -0.139117 +v 0.909752 1.284780 -0.168885 +v 0.928436 1.300180 -0.175358 +v 0.892928 1.269740 -0.163569 +v 0.915424 1.365450 -0.122591 +v 0.913103 1.385820 -0.169330 +v 0.940891 1.294640 -0.138324 +v 0.943716 1.312540 -0.179443 +v 0.950404 1.303440 -0.132941 +v 0.953962 1.327640 -0.178798 +v 0.829299 1.090110 -0.083621 +v 0.836906 1.110700 -0.020748 +v 0.857392 1.107230 -0.036363 +v 0.848317 1.088560 -0.096381 +v 0.836929 1.139090 0.000968 +v 0.856702 1.133760 -0.020926 +v 0.839642 1.149270 -0.007343 +v 0.860135 1.147460 -0.027673 +v 0.836402 1.155860 -0.062298 +v 0.832265 1.151220 -0.103417 +v 0.851809 1.141350 -0.135766 +v 0.827372 1.146180 -0.130324 +v 0.855323 1.146830 -0.107629 +v 0.822292 1.081450 -0.140185 +v 0.841511 1.079940 -0.146242 +v 0.818660 1.069770 -0.182320 +v 0.835950 1.070640 -0.187273 +v 0.822626 1.141080 -0.153812 +v 0.818267 1.137090 -0.183173 +v 0.846693 1.138300 -0.160203 +v 0.841132 1.134610 -0.189875 +v 0.865792 1.081620 -0.110609 +v 0.875631 1.100720 -0.063758 +v 0.881600 1.123140 -0.052066 +v 0.886597 1.139500 -0.056433 +v 0.885351 1.139060 -0.143610 +v 0.882163 1.140840 -0.112463 +v 0.853967 1.064880 -0.192404 +v 0.859475 1.074390 -0.153597 +v 0.882578 1.134560 -0.171125 +v 0.875994 1.131720 -0.200641 +v 0.831168 1.306140 -0.098160 +v 0.844929 1.314250 -0.102884 +v 0.820565 1.323880 -0.141586 +v 0.839442 1.324850 -0.146398 +v 0.878886 1.258170 -0.159581 +v 0.885233 1.253320 -0.122287 +v 0.884714 1.224120 -0.097908 +v 0.907371 1.250970 -0.025367 +v 0.885596 1.227180 -0.009901 +v 0.884424 1.201480 -0.010650 +v 0.859995 1.213230 0.005602 +v 0.872109 1.262270 -0.030335 +v 0.861099 1.304340 -0.082605 +v 0.878345 1.188720 -0.044251 +v 0.881236 1.205680 -0.071432 +v 0.924098 1.280850 -0.044659 +v 0.837426 1.206250 0.017754 +v 0.743672 1.172950 0.078803 +v 0.801607 1.123040 0.041465 +v 0.716609 1.361110 -0.159358 +v 0.728517 1.364630 -0.164526 +v 0.743568 1.358830 -0.167173 +v 0.766211 1.351680 -0.173616 +v 0.789611 1.343050 -0.180244 +v 0.810749 1.335600 -0.186235 +v 0.829529 1.331260 -0.191618 +v 0.851416 1.331140 -0.149897 +v 0.841259 1.334780 -0.195125 +v 0.849244 1.342480 -0.197638 +v 0.857941 1.352220 -0.200404 +v 0.869900 1.366830 -0.204237 +v 0.904947 1.394330 -0.215114 +v 0.937133 1.394470 -0.224507 +v 0.960880 1.347210 -0.176366 +v 0.955972 1.360050 -0.229201 +v 0.954994 1.380230 -0.229393 +v 0.949967 1.339680 -0.226969 +v 0.937963 1.322090 -0.223054 +v 0.920955 1.305360 -0.217701 +v 0.901255 1.286040 -0.211495 +v 0.883638 1.268320 -0.205942 +v 0.870197 1.256940 -0.201745 +v 0.856599 1.249600 -0.197608 +v 0.837714 1.241690 -0.191907 +v 0.814537 1.230620 -0.184885 +v 0.916357 1.115800 -0.179377 +v 0.918960 1.124860 -0.149156 +v 0.909181 1.111960 -0.210087 +v 0.842971 1.155190 -0.025011 +v 0.829974 1.152770 0.017673 +v 0.862805 1.151880 -0.045000 +v 0.857510 1.151290 -0.073130 +v 0.885833 1.144510 -0.069719 +v 0.876284 1.146160 -0.084474 +v 0.880828 1.189760 -0.022616 +v 0.909233 1.131980 -0.108133 +v 0.958359 1.319120 -0.124400 +v 0.785266 1.204520 -0.113783 +v 0.857325 1.324790 -0.107807 +v 0.713295 1.377320 -0.158765 +v 0.729748 1.362880 -0.106843 +v 0.741581 1.331030 -0.052763 +v 0.752109 1.288250 -0.014001 +v 0.750730 1.221230 0.062114 +v 0.742901 1.186160 0.088383 +v 0.740083 1.141330 0.079930 +v 0.734597 1.103470 0.049183 +v 0.739950 1.142900 0.069995 +v 0.731142 1.108500 0.035630 +v 0.713963 1.041770 -0.151099 +v 0.727842 1.053820 -0.072581 +v 0.694560 1.007270 -0.144700 +v 0.728198 1.069300 -0.009679 +v 0.824554 1.132900 0.021817 +v 0.795720 1.115210 0.032642 +v -0.116777 1.276720 0.063856 +v -0.118920 1.226450 0.076727 +v -0.121989 1.269340 0.044090 +v -0.121529 1.222740 0.066800 +v -0.126304 1.257650 0.026199 +v -0.123643 1.216850 0.057806 +v -0.129514 1.242190 0.011030 +v -0.125340 1.209090 0.050184 +v -0.131465 1.223690 -0.000715 +v -0.126260 1.199780 0.044290 +v -0.132072 1.203010 -0.008485 +v -0.126460 1.189380 0.040405 +v -0.131242 1.181130 -0.011881 +v -0.125956 1.178400 0.038714 +v -0.128996 1.159100 -0.010739 +v -0.124777 1.167340 0.039285 +v -0.122953 1.156740 0.042080 +v -0.125437 1.137980 -0.005119 +v -0.120595 1.147070 0.047003 +v -0.120803 1.118760 0.004683 +v -0.115131 1.102010 0.019067 +v -0.117659 1.138620 0.054336 +v -0.107279 1.086840 0.043556 +v -0.113552 1.131330 0.066333 +v -0.101652 1.082620 0.062158 +v -0.110734 1.129650 0.075763 +v -0.108109 1.325960 0.049450 +v -0.115843 1.315020 0.020157 +v -0.122226 1.297690 -0.006350 +v -0.126979 1.274790 -0.028830 +v -0.129870 1.247380 -0.046231 +v -0.130768 1.216740 -0.057745 +v -0.129633 1.184310 -0.062824 +v -0.126504 1.151600 -0.061237 +v -0.121492 1.120180 -0.053008 +v -0.114627 1.091680 -0.038394 +v -0.106360 1.066940 -0.017434 +v -0.094504 1.044010 0.019541 +v -0.086200 1.037050 0.047389 +v -0.093274 1.373520 0.033762 +v -0.103401 1.359190 -0.004629 +v -0.111772 1.336480 -0.039373 +v -0.118000 1.306460 -0.068830 +v -0.121796 1.270540 -0.091636 +v -0.122968 1.230390 -0.106717 +v -0.121477 1.187890 -0.113375 +v -0.117385 1.145020 -0.111299 +v -0.110883 1.103790 -0.100578 +v -0.101881 1.066490 -0.081286 +v -0.091138 1.034150 -0.053949 +v -0.075605 1.004920 -0.006275 +v -0.064513 0.994990 0.029506 +v -0.072476 1.418710 0.017013 +v -0.084858 1.401190 -0.029919 +v -0.095090 1.373440 -0.072381 +v -0.102704 1.336740 -0.108392 +v -0.107339 1.292830 -0.136270 +v -0.108777 1.243750 -0.154702 +v -0.106953 1.191790 -0.162843 +v -0.101948 1.139400 -0.160300 +v -0.093800 1.089160 -0.146924 +v -0.082404 1.044100 -0.122576 +v -0.068117 1.005500 -0.086587 +v -0.050686 0.972087 -0.034694 +v -0.037318 0.956969 0.009858 +v -0.046030 1.460870 -0.000544 +v -0.060480 1.440420 -0.055328 +v -0.072432 1.408020 -0.104893 +v -0.081314 1.365190 -0.146932 +v -0.086727 1.313930 -0.179473 +v -0.088402 1.256640 -0.200997 +v -0.086274 1.195990 -0.210494 +v -0.080432 1.134820 -0.207529 +v -0.070860 1.076250 -0.191759 +v -0.057796 1.023530 -0.163577 +v -0.041270 0.978226 -0.122769 +v -0.018849 0.939531 -0.063855 +v -0.004814 0.918178 -0.005030 +v -0.014311 1.499390 -0.018657 +v -0.030623 1.476310 -0.080492 +v -0.044110 1.439740 -0.136441 +v -0.054141 1.391390 -0.183892 +v -0.060250 1.333530 -0.220622 +v -0.062141 1.268860 -0.244919 +v -0.059739 1.200400 -0.255640 +v -0.053140 1.131360 -0.252289 +v -0.042538 1.065090 -0.234776 +v -0.028147 1.005140 -0.203577 +v -0.008573 0.953878 -0.159247 +v 0.004424 0.915093 0.028201 +v 0.022211 1.533710 -0.037059 +v 0.004276 1.508320 -0.105049 +v -0.010553 1.468120 -0.166565 +v -0.021585 1.414960 -0.218739 +v -0.028295 1.351340 -0.259124 +v -0.030378 1.280240 -0.285838 +v -0.027731 1.204970 -0.297627 +v -0.020488 1.129060 -0.293942 +v -0.008973 1.056060 -0.274954 +v 0.006582 0.989955 -0.241115 +v 0.026697 0.937269 -0.197623 +v 0.063004 1.563320 -0.055484 +v 0.043705 1.536020 -0.128633 +v 0.027750 1.492750 -0.194821 +v 0.015887 1.435560 -0.250954 +v 0.008665 1.367110 -0.294409 +v 0.006426 1.290610 -0.323147 +v 0.009266 1.209630 -0.335833 +v 0.017066 1.127960 -0.331866 +v 0.029455 1.049410 -0.311440 +v 0.046434 0.979398 -0.274910 +v 0.066934 0.928958 -0.234650 +v 0.107483 1.587800 -0.073664 +v 0.087101 1.558960 -0.150906 +v 0.070256 1.513280 -0.220800 +v 0.057718 1.452890 -0.280077 +v 0.050096 1.380610 -0.325957 +v 0.047731 1.299830 -0.356311 +v 0.050734 1.214310 -0.369701 +v 0.058971 1.128070 -0.365512 +v 0.072050 1.045130 -0.343944 +v 0.090549 0.972925 -0.305560 +v 0.112406 0.925807 -0.269734 +v 0.154979 1.606780 -0.091332 +v 0.133818 1.576840 -0.171547 +v 0.116321 1.529400 -0.244125 +v 0.103309 1.466690 -0.305671 +v 0.095390 1.391630 -0.353323 +v 0.092936 1.307750 -0.384834 +v 0.096057 1.218950 -0.398743 +v 0.104606 1.129390 -0.394398 +v 0.118189 1.043260 -0.372000 +v 0.140588 0.969514 -0.333467 +v 0.166434 0.924725 -0.299718 +v 0.230545 1.623620 -0.116177 +v 0.208829 1.592890 -0.198483 +v 0.190871 1.544210 -0.272967 +v 0.177525 1.479860 -0.336129 +v 0.169392 1.402840 -0.385019 +v 0.166871 1.316750 -0.417360 +v 0.170074 1.225630 -0.431632 +v 0.178853 1.133730 -0.427169 +v 0.192791 1.045350 -0.404185 +v 0.212106 0.970107 -0.362628 +v 0.234200 0.927149 -0.324103 +v 0.308573 1.628430 -0.138754 +v 0.286938 1.597810 -0.220763 +v 0.269055 1.549310 -0.294973 +v 0.279242 1.487490 -0.362635 +v 0.268335 1.418960 -0.404148 +v 0.271308 1.344030 -0.431558 +v 0.248332 1.231900 -0.453060 +v 0.257073 1.140330 -0.448611 +v 0.270960 1.052270 -0.425709 +v 0.289770 0.977766 -0.383173 +v 0.310100 0.931798 -0.337501 +v 0.360984 1.623520 -0.151936 +v 0.339816 1.593580 -0.232144 +v 0.333826 1.540150 -0.319877 +v 0.312043 1.277970 -0.451888 +v 0.341114 1.180810 -0.467154 +v 0.352740 1.069580 -0.447195 +v 0.368836 0.993018 -0.394702 +v 0.389366 0.942630 -0.337738 +v 0.412721 1.612610 -0.163458 +v 0.395527 1.572520 -0.272589 +v 0.463034 1.595830 -0.173163 +v 0.448502 1.568540 -0.262038 +v 0.429789 1.085910 -0.452964 +v 0.425748 1.175210 -0.466924 +v 0.445010 1.009510 -0.406187 +v 0.472910 0.948665 -0.334268 +v 0.511197 1.573450 -0.180904 +v 0.499772 1.552130 -0.253275 +v 0.487168 1.099610 -0.440908 +v 0.482059 1.177080 -0.457612 +v 0.503568 1.025090 -0.400270 +v 0.534827 0.967468 -0.329174 +v 0.556498 1.545780 -0.186568 +v 0.548409 1.523920 -0.250769 +v 0.536228 1.113510 -0.412941 +v 0.527864 1.182090 -0.432581 +v 0.552413 1.046560 -0.380407 +v 0.587364 0.994700 -0.318202 +v 0.598286 1.513230 -0.190083 +v 0.590656 1.488880 -0.250487 +v 0.586371 1.126470 -0.372162 +v 0.583546 1.187430 -0.382809 +v 0.600213 1.083580 -0.343455 +v 0.636573 1.031640 -0.296181 +v 0.619223 0.966682 -0.233508 +v 0.667364 1.012150 -0.232055 +v 0.568080 0.933547 -0.233279 +v 0.643461 1.453930 -0.201264 +v 0.632939 1.441710 -0.242324 +v 0.664762 1.416040 -0.208641 +v 0.684454 1.382920 -0.215291 +v 0.456050 1.374390 -0.384211 +v 0.448917 1.391710 -0.377145 +v 0.478930 1.388610 -0.379940 +v 0.470130 1.402150 -0.373683 +v 0.434311 1.384510 -0.378428 +v 0.440339 1.362490 -0.386168 +v 0.446923 1.408280 -0.368618 +v 0.436017 1.405640 -0.368188 +v 0.463798 1.413770 -0.366995 +v 0.478930 1.343160 -0.391277 +v 0.466541 1.357910 -0.389245 +v 0.499030 1.359830 -0.387555 +v 0.488984 1.374140 -0.384633 +v 0.451446 1.342460 -0.390580 +v 0.466052 1.326560 -0.391566 +v 0.503776 1.321340 -0.386198 +v 0.491683 1.330760 -0.389875 +v 0.514089 1.333980 -0.385931 +v 0.507646 1.346090 -0.387822 +v 0.482504 1.315670 -0.389341 +v 0.498356 1.308460 -0.384441 +v 0.514356 1.316090 -0.381690 +v 0.517129 1.324880 -0.383810 +v 0.525225 1.317500 -0.377278 +v 0.524194 1.324470 -0.380845 +v 0.513088 1.305730 -0.378872 +v 0.526931 1.308510 -0.373023 +v 0.540743 1.338690 -0.371666 +v 0.549106 1.332140 -0.362776 +v 0.534767 1.325690 -0.373890 +v 0.539312 1.317670 -0.367632 +v 0.529993 1.330950 -0.379288 +v 0.528762 1.340880 -0.380496 +v 0.542530 1.354980 -0.368633 +v 0.526196 1.354790 -0.380192 +v 0.539713 1.372480 -0.364482 +v 0.520658 1.369970 -0.377961 +v 0.554037 1.370250 -0.351736 +v 0.554586 1.350330 -0.357586 +v 0.532321 1.389830 -0.359892 +v 0.512183 1.385110 -0.374098 +v 0.520865 1.405960 -0.355540 +v 0.501892 1.399520 -0.369649 +v 0.533870 1.408780 -0.341972 +v 0.546942 1.390210 -0.346087 +v 0.507090 1.419260 -0.351558 +v 0.491112 1.412010 -0.364341 +v 0.492647 1.428750 -0.348407 +v 0.481733 1.421900 -0.359091 +v 0.498059 1.433210 -0.338591 +v 0.516817 1.423510 -0.339384 +v 0.478345 1.432940 -0.347866 +v 0.476009 1.428670 -0.354487 +v 0.463531 1.430520 -0.352278 +v 0.466141 1.427850 -0.356607 +v 0.460758 1.433370 -0.347362 +v 0.479390 1.436980 -0.340771 +v 0.451675 1.421520 -0.359951 +v 0.459490 1.421480 -0.361946 +v 0.444980 1.422670 -0.357379 +v 0.417955 1.361190 -0.410087 +v 0.428521 1.360480 -0.402939 +v 0.434222 1.330630 -0.413875 +v 0.442964 1.334080 -0.406498 +v 0.467260 1.320910 -0.399847 +v 0.460899 1.314510 -0.407647 +v 0.451713 1.337540 -0.399113 +v 0.457748 1.475390 -0.362109 +v 0.461640 1.458590 -0.358431 +v 0.433933 1.460370 -0.378806 +v 0.440636 1.445310 -0.372763 +v 0.434927 1.410990 -0.377857 +v 0.425725 1.422500 -0.384974 +v 0.447331 1.430250 -0.366728 +v 0.416524 1.434010 -0.392100 +v 0.410259 1.397750 -0.401938 +v 0.421344 1.391790 -0.395132 +v 0.439086 1.359780 -0.395785 +v 0.432421 1.385830 -0.388326 +v 0.477811 1.293120 -0.415937 +v 0.454530 1.308090 -0.415454 +v 0.480895 1.301390 -0.407032 +v 0.501181 1.302450 -0.393182 +v 0.501107 1.293390 -0.401160 +v 0.483979 1.309670 -0.398120 +v 0.501010 1.284330 -0.409145 +v 0.523542 1.281200 -0.397631 +v 0.520814 1.290650 -0.391855 +v 0.518085 1.300090 -0.386079 +v 0.534219 1.302910 -0.377879 +v 0.539920 1.293840 -0.381720 +v 0.548980 1.312140 -0.369842 +v 0.561362 1.328070 -0.362509 +v 0.558478 1.306200 -0.371918 +v 0.572832 1.326390 -0.362405 +v 0.568747 1.300030 -0.373653 +v 0.545637 1.284860 -0.385583 +v 0.592710 1.351220 -0.348148 +v 0.585718 1.323820 -0.360552 +v 0.580113 1.350020 -0.352811 +v 0.569414 1.349260 -0.355317 +v 0.570422 1.372900 -0.348170 +v 0.579772 1.375690 -0.343714 +v 0.579468 1.407520 -0.330391 +v 0.590129 1.379570 -0.337931 +v 0.570771 1.401720 -0.335929 +v 0.562052 1.395950 -0.341460 +v 0.546430 1.416530 -0.337723 +v 0.552984 1.425650 -0.332185 +v 0.534219 1.457680 -0.327803 +v 0.559539 1.434770 -0.326654 +v 0.529926 1.444920 -0.332066 +v 0.525633 1.432140 -0.336329 +v 0.504828 1.442080 -0.338546 +v 0.507075 1.457920 -0.336656 +v 0.483905 1.480090 -0.346435 +v 0.509314 1.473760 -0.334765 +v 0.484484 1.462680 -0.345523 +v 0.485055 1.445280 -0.344611 +v 0.465533 1.441790 -0.354761 +v 0.497303 1.300610 -0.384737 +v 0.479983 1.307600 -0.390142 +v 0.462433 1.318540 -0.392708 +v 0.434601 1.357180 -0.387740 +v 0.428387 1.381700 -0.380111 +v 0.431271 1.405110 -0.368678 +v 0.446634 1.335350 -0.391929 +v 0.529147 1.301380 -0.370872 +v 0.513763 1.298450 -0.378198 +v 0.442029 1.423820 -0.356615 +v 0.459668 1.435090 -0.345197 +v 0.554430 1.326360 -0.357653 +v 0.542990 1.310780 -0.363859 +v 0.479753 1.439170 -0.337041 +v 0.500284 1.435570 -0.333201 +v 0.562208 1.367840 -0.344582 +v 0.561837 1.345990 -0.351328 +v 0.521021 1.425470 -0.332281 +v 0.540432 1.410010 -0.334001 +v 0.554482 1.389730 -0.338331 +v 0.600643 1.318070 -0.352485 +v 0.582159 1.289070 -0.373334 +v 0.550842 1.269610 -0.390439 +v 0.603282 1.388730 -0.324200 +v 0.608235 1.353050 -0.335811 +v 0.429500 1.296200 -0.436504 +v 0.398159 1.326270 -0.428845 +v 0.378104 1.365990 -0.423736 +v 0.509410 1.506320 -0.320693 +v 0.541663 1.484830 -0.314153 +v 0.570126 1.454490 -0.312322 +v 0.380876 1.458890 -0.396926 +v 0.405373 1.490920 -0.376693 +v 0.438723 1.509750 -0.354420 +v 0.371201 1.414210 -0.413319 +v 0.495108 1.268020 -0.426850 +v 0.463145 1.278040 -0.436823 +v 0.523171 1.264770 -0.409857 +v 0.591168 1.421330 -0.315495 +v 0.474993 1.515620 -0.335084 +v 0.619319 1.302800 -0.335996 +v 0.594660 1.261010 -0.368574 +v 0.559843 1.242140 -0.398068 +v 0.627690 1.349180 -0.311499 +v 0.619357 1.395120 -0.298517 +v 0.400547 1.271590 -0.448752 +v 0.353370 1.309170 -0.447544 +v 0.325262 1.356930 -0.432641 +v 0.545184 1.509490 -0.283414 +v 0.501396 1.536480 -0.287343 +v 0.580699 1.474570 -0.286001 +v 0.361436 1.517340 -0.354628 +v 0.324395 1.478740 -0.382750 +v 0.407865 1.540900 -0.328062 +v 0.312473 1.426300 -0.412578 +v 0.485485 1.238910 -0.442502 +v 0.444825 1.247500 -0.450680 +v 0.522230 1.237670 -0.420800 +v 0.603461 1.437350 -0.290309 +v 0.455294 1.547230 -0.304826 +v 0.648265 1.281370 -0.310498 +v 0.614092 1.213440 -0.360211 +v 0.646093 1.395630 -0.258976 +v 0.660209 1.342400 -0.272240 +v 0.726559 1.163660 -0.236348 +v 0.722444 1.164420 -0.223254 +v 0.720220 1.162410 -0.229037 +v 0.728888 1.158840 -0.226383 +v 0.733892 1.171410 -0.190068 +v 0.740565 1.157380 -0.188756 +v 0.727523 1.168610 -0.209560 +v 0.735880 1.158370 -0.210027 +v 0.743546 1.193710 -0.203332 +v 0.734137 1.185810 -0.218902 +v 0.766708 1.214560 -0.211288 +v 0.647835 1.205210 -0.337531 +v 0.697533 1.258950 -0.281175 +v 0.662834 1.209580 -0.339154 +v 0.713889 1.257950 -0.283703 +v 0.679487 1.268330 -0.285074 +v 0.626749 1.196160 -0.357438 +v 0.729185 1.071010 -0.211147 +v 0.701714 1.066450 -0.201493 +v 0.693603 1.076370 -0.266398 +v 0.654323 1.075280 -0.269171 +v 0.706786 1.302520 -0.249797 +v 0.691965 1.304840 -0.248144 +v 0.705081 1.343190 -0.202732 +v 0.716743 1.343560 -0.207640 +v 0.734782 1.338840 -0.211310 +v 0.726997 1.298970 -0.254795 +v 0.689993 1.215980 -0.345597 +v 0.731742 1.262940 -0.288100 +v 0.712569 1.219890 -0.347844 +v 0.750515 1.267570 -0.292103 +v 0.631531 1.163580 -0.373542 +v 0.642148 1.192060 -0.364696 +v 0.663234 1.165590 -0.384240 +v 0.673688 1.193590 -0.370517 +v 0.705985 1.189580 -0.371681 +v 0.697229 1.160440 -0.380771 +v 0.667935 1.132860 -0.375877 +v 0.635342 1.131200 -0.369642 +v 0.721970 1.079770 -0.268719 +v 0.687427 1.091820 -0.335877 +v 0.655901 1.090290 -0.335959 +v 0.749121 1.083190 -0.270453 +v 0.718315 1.101290 -0.332852 +v 0.752695 1.074150 -0.214172 +v 0.778994 1.079390 -0.212215 +v 0.753384 1.332980 -0.216337 +v 0.776228 1.324640 -0.222276 +v 0.745162 1.299230 -0.260103 +v 0.763201 1.298800 -0.264826 +v 0.719998 1.167420 -0.369872 +v 0.719026 1.152250 -0.370598 +v 0.710463 1.130660 -0.374483 +v 0.888094 1.105780 -0.269527 +v 0.879791 1.083690 -0.270824 +v 0.852891 1.116530 -0.301957 +v 0.841169 1.101310 -0.306072 +v 0.851586 1.075670 -0.268363 +v 0.829166 1.086270 -0.296277 +v 0.903568 1.097870 -0.241197 +v 0.895331 1.071240 -0.237920 +v 0.870649 1.065130 -0.232930 +v 0.914667 1.381630 -0.272159 +v 0.930867 1.365470 -0.278016 +v 0.883401 1.353200 -0.319677 +v 0.899668 1.335380 -0.327744 +v 0.872695 1.287490 -0.354465 +v 0.858919 1.310030 -0.348340 +v 0.775760 1.189130 -0.266205 +v 0.742589 1.182730 -0.248974 +v 0.753807 1.172610 -0.286335 +v 0.741388 1.159500 -0.260645 +v 0.726589 1.172780 -0.230980 +v 0.747186 1.152010 -0.292771 +v 0.741796 1.150130 -0.314161 +v 0.745081 1.155550 -0.239173 +v 0.762215 1.149810 -0.253972 +v 0.773173 1.146690 -0.226413 +v 0.752124 1.151610 -0.217041 +v 0.782730 1.144140 -0.202702 +v 0.759612 1.149480 -0.194391 +v 0.733188 1.226300 -0.345204 +v 0.769377 1.273370 -0.295447 +v 0.756780 1.238170 -0.346450 +v 0.783012 1.286860 -0.298368 +v 0.749877 1.161900 -0.323036 +v 0.770845 1.170970 -0.331740 +v 0.771416 1.181140 -0.300044 +v 0.792280 1.186100 -0.308741 +v 0.812906 1.208220 -0.288656 +v 0.797455 1.195900 -0.277520 +v 0.757618 1.170150 -0.351966 +v 0.733922 1.162310 -0.345642 +v 0.730971 1.148720 -0.340422 +v 0.728947 1.152680 -0.342906 +v 0.730867 1.174450 -0.362917 +v 0.751464 1.180210 -0.365460 +v 0.788617 1.221500 -0.251110 +v 0.809955 1.231210 -0.261556 +v 0.827305 1.240790 -0.270743 +v 0.840844 1.247210 -0.236771 +v 0.823397 1.238330 -0.230520 +v 0.801888 1.228340 -0.223988 +v 0.824725 1.327770 -0.294795 +v 0.822626 1.300710 -0.336418 +v 0.811720 1.312930 -0.298079 +v 0.801110 1.275760 -0.343959 +v 0.844402 1.328770 -0.321553 +v 0.834949 1.339940 -0.291154 +v 0.845114 1.231930 -0.338509 +v 0.874282 1.264440 -0.330020 +v 0.850815 1.237930 -0.320715 +v 0.874141 1.263380 -0.314821 +v 0.873956 1.264050 -0.303062 +v 0.859520 1.248490 -0.302847 +v 0.842007 1.231620 -0.299962 +v 0.829247 1.216870 -0.319314 +v 0.819364 1.206850 -0.337567 +v 0.813232 1.207240 -0.354257 +v 0.809881 1.217470 -0.365927 +v 0.842148 1.233440 -0.355836 +v 0.840399 1.246030 -0.367655 +v 0.874445 1.272500 -0.344856 +v 0.819223 1.332220 -0.275740 +v 0.834260 1.338200 -0.240033 +v 0.831264 1.344270 -0.274776 +v 0.844528 1.349140 -0.241434 +v 0.857036 1.361410 -0.243458 +v 0.843016 1.355090 -0.275510 +v 0.853181 1.261040 -0.280604 +v 0.869811 1.274540 -0.284118 +v 0.885803 1.284690 -0.287521 +v 0.904562 1.298270 -0.257152 +v 0.885515 1.282830 -0.251888 +v 0.868669 1.267800 -0.246669 +v 0.864391 1.361350 -0.297404 +v 0.887308 1.383750 -0.257679 +v 0.927583 1.325520 -0.269171 +v 0.919487 1.310590 -0.262461 +v 0.900231 1.299410 -0.304819 +v 0.895220 1.290980 -0.294795 +v 0.774300 1.085700 -0.272025 +v 0.746652 1.103460 -0.329938 +v 0.797217 1.084460 -0.271440 +v 0.772358 1.100400 -0.327655 +v 0.768458 1.137370 -0.337746 +v 0.763149 1.126250 -0.341430 +v 0.741210 1.141130 -0.344307 +v 0.734634 1.130870 -0.349460 +v 0.768228 1.148880 -0.295521 +v 0.785236 1.147520 -0.260741 +v 0.796802 1.143580 -0.233746 +v 0.809021 1.146380 -0.267177 +v 0.820676 1.140190 -0.240982 +v 0.798915 1.079560 -0.220252 +v 0.818400 1.078090 -0.225419 +v 0.806122 1.140730 -0.210487 +v 0.828432 1.134770 -0.217471 +v 0.819683 1.077920 -0.268548 +v 0.802549 1.094850 -0.314116 +v 0.801006 1.116670 -0.328137 +v 0.806945 1.131980 -0.327484 +v 0.833651 1.136980 -0.276845 +v 0.851483 1.133120 -0.252630 +v 0.837573 1.072620 -0.228645 +v 0.864999 1.131950 -0.228837 +v 0.813655 1.322770 -0.234746 +v 0.795016 1.310240 -0.273879 +v 0.795527 1.320540 -0.227740 +v 0.781729 1.300270 -0.268719 +v 0.854827 1.256240 -0.241983 +v 0.840191 1.249700 -0.276585 +v 0.827149 1.219010 -0.295647 +v 0.806767 1.242890 -0.369998 +v 0.780395 1.218740 -0.370279 +v 0.780128 1.193110 -0.367914 +v 0.750649 1.204450 -0.368974 +v 0.779572 1.254840 -0.347339 +v 0.797863 1.299260 -0.299221 +v 0.793229 1.181870 -0.335803 +v 0.809955 1.199530 -0.315310 +v 0.830864 1.273360 -0.364037 +v 0.725418 1.197120 -0.366595 +v 0.611201 1.162880 -0.364563 +v 0.683445 1.113310 -0.363747 +v 0.825547 1.329060 -0.238513 +v 0.931861 1.344880 -0.275777 +v 0.898690 1.114570 -0.239848 +v 0.884224 1.119800 -0.266420 +v 0.719612 1.143910 -0.360381 +v 0.752791 1.144710 -0.331310 +v 0.792235 1.148610 -0.297308 +v 0.780365 1.142570 -0.324652 +v 0.813907 1.138760 -0.315584 +v 0.814167 1.144450 -0.297768 +v 0.783679 1.181960 -0.355399 +v 0.854308 1.125410 -0.295180 +v 0.902145 1.314600 -0.316971 +v 0.752428 1.208610 -0.232937 +v 0.807976 1.320830 -0.276852 +v 0.699438 1.358910 -0.211621 +v 0.682393 1.316700 -0.262038 +v 0.674378 1.271360 -0.295202 +v 0.628091 1.206870 -0.359907 +v 0.605767 1.176530 -0.373935 +v 0.626030 1.100790 -0.318602 +v 0.620921 1.095560 -0.331525 +v 0.612017 1.134640 -0.352759 +v 0.607761 1.132470 -0.361998 +v 0.684684 1.048050 -0.225375 +v 0.652417 1.059350 -0.281842 +v 0.713073 1.123940 -0.360092 +v 0.683164 1.106170 -0.352945 +v 0.015383 0.662289 -0.487276 +v -0.109333 1.129310 0.080279 +v -0.097982 1.081280 0.072242 +v -0.080350 1.034650 0.063404 +v -0.056677 0.991208 0.052742 +v -0.028213 0.951602 0.040472 +v 0.013106 0.915316 0.059222 +v -0.074249 1.033830 0.082177 +v -0.049099 0.990215 0.077476 +v -0.019034 0.951527 0.070885 +v 0.591887 0.918044 0.089524 +v -0.115390 0.101510 0.199241 +v -0.054986 0.101436 0.218177 +v -0.159268 0.101577 0.163800 +v -0.193300 0.101651 0.116357 +v -0.225381 0.101681 0.044015 +v 0.402660 0.101244 0.136679 +v 0.327190 0.101303 0.185309 +v 0.227994 0.101333 0.217028 +v 0.142263 0.101377 0.230462 +v 0.027016 0.101370 0.231159 +v 0.444157 0.101281 0.075697 +v 0.068209 0.101370 0.236438 +v 0.465807 0.101555 0.008041 +v -0.251531 0.101622 -0.022068 +v 0.465392 0.101481 -0.083562 +v -0.125993 0.101510 -0.282717 +v -0.065737 0.101422 -0.300845 +v -0.184966 0.101644 -0.256115 +v -0.216988 0.101659 -0.205282 +v -0.216462 0.101607 -0.142928 +v 0.406619 0.101362 -0.219510 +v 0.329614 0.101496 -0.271618 +v 0.229625 0.101599 -0.318320 +v 0.138408 0.101637 -0.336470 +v 0.021166 0.101488 -0.324430 +v 0.447679 0.101347 -0.155147 +v 0.060432 0.101488 -0.325260 +v -0.227316 0.101651 -0.087988 +v 0.125907 0.101733 -0.038053 +vt 0.877975 0.397658 +vt 0.873951 0.397664 +vt 0.900103 0.397679 +vt 0.870831 0.397671 +vt 0.867889 0.397674 +vt 0.931273 0.397662 +vt 0.929288 0.397637 +vt 0.865490 0.397668 +vt 0.867711 0.397671 +vt 0.868707 0.397667 +vt 0.866606 0.398924 +vt 0.871384 0.397619 +vt 0.874160 0.398826 +vt 0.878048 0.397558 +vt 0.866060 0.397625 +vt 0.860570 0.399008 +vt 0.856321 0.399060 +vt 0.862375 0.397683 +vt 0.860024 0.397676 +vt 0.853776 0.399148 +vt 0.932361 0.401286 +vt 0.944998 0.401429 +vt 0.936097 0.404570 +vt 0.948825 0.405179 +vt 0.939922 0.398832 +vt 0.928618 0.398828 +vt 0.862287 0.401557 +vt 0.870712 0.401462 +vt 0.855482 0.401642 +vt 0.858360 0.405349 +vt 0.851030 0.405417 +vt 0.867250 0.404976 +vt 0.851008 0.401767 +vt 0.848050 0.401779 +vt 0.846214 0.405443 +vt 0.842460 0.405195 +vt 0.951482 0.401365 +vt 0.945825 0.398800 +vt 0.955814 0.405156 +vt 0.939709 0.408955 +vt 0.951716 0.409790 +vt 0.943792 0.414167 +vt 0.953940 0.414936 +vt 0.854643 0.410095 +vt 0.863781 0.409841 +vt 0.847079 0.410021 +vt 0.850892 0.415208 +vt 0.843668 0.414845 +vt 0.858319 0.415536 +vt 0.959154 0.409842 +vt 0.961426 0.415077 +vt 0.955396 0.420505 +vt 0.946551 0.419988 +vt 0.948394 0.426244 +vt 0.956245 0.426562 +vt 0.962774 0.420748 +vt 0.963626 0.426902 +vt 0.947821 0.439136 +vt 0.949156 0.432796 +vt 0.955188 0.438695 +vt 0.956416 0.432776 +vt 0.963377 0.433055 +vt 0.962074 0.438861 +vt 0.939469 0.450342 +vt 0.944673 0.445101 +vt 0.949616 0.449137 +vt 0.952905 0.444195 +vt 0.959891 0.444199 +vt 0.957210 0.449055 +vt 0.928445 0.457630 +vt 0.933041 0.454385 +vt 0.940767 0.456994 +vt 0.945196 0.453364 +vt 0.954246 0.453493 +vt 0.950166 0.457401 +vt 0.877438 0.456074 +vt 0.890333 0.455013 +vt 0.881771 0.458050 +vt 0.891902 0.457826 +vt 0.885457 0.459788 +vt 0.893433 0.460126 +vt 0.902160 0.458193 +vt 0.902038 0.460510 +vt 0.902093 0.455956 +vt 0.875073 0.458463 +vt 0.870949 0.459563 +vt 0.869348 0.456995 +vt 0.865831 0.459946 +vt 0.876379 0.459992 +vt 0.880020 0.459819 +vt 0.890696 0.462723 +vt 0.889158 0.462546 +vt 0.893089 0.462870 +vt 0.245158 0.423975 +vt 0.250110 0.468112 +vt 0.148569 0.498875 +vt 0.150442 0.543685 +vt 0.595914 0.442419 +vt 0.701364 0.364720 +vt 0.595493 0.387203 +vt 0.704143 0.312403 +vt 0.757075 0.288915 +vt 0.749567 0.262372 +vt 0.302841 0.416173 +vt 0.302959 0.373132 +vt 0.224027 0.289653 +vt 0.235580 0.359702 +vt 0.134156 0.320572 +vt 0.143764 0.429085 +vt 0.298228 0.319321 +vt 0.288073 0.263566 +vt 0.342229 0.232442 +vt 0.353643 0.285267 +vt 0.355112 0.336459 +vt 0.409212 0.301844 +vt 0.416748 0.239090 +vt 0.412385 0.174765 +vt 0.371257 0.129527 +vt 0.316583 0.183819 +vt 0.312010 0.090946 +vt 0.278107 0.146712 +vt 0.258385 0.177707 +vt 0.272238 0.213152 +vt 0.842115 0.409869 +vt 0.837426 0.409453 +vt 0.838646 0.414482 +vt 0.833434 0.414204 +vt 0.345064 0.636086 +vt 0.339502 0.673242 +vt 0.283208 0.642063 +vt 0.260986 0.672117 +vt 0.331126 0.714598 +vt 0.241009 0.715530 +vt 0.847163 0.420560 +vt 0.840709 0.419570 +vt 0.839445 0.430603 +vt 0.835030 0.428579 +vt 0.843659 0.433436 +vt 0.852464 0.422383 +vt 0.835601 0.419062 +vt 0.830596 0.418889 +vt 0.831257 0.427506 +vt 0.827802 0.427141 +vt 0.326898 0.757163 +vt 0.328393 0.797118 +vt 0.233372 0.762934 +vt 0.238410 0.805793 +vt 0.866399 0.449489 +vt 0.869211 0.447456 +vt 0.876435 0.450731 +vt 0.878828 0.448367 +vt 0.861778 0.461251 +vt 0.863290 0.455790 +vt 0.869445 0.454182 +vt 0.798670 0.019963 +vt 0.720188 0.090411 +vt 0.815355 0.094326 +vt 0.722678 0.141004 +vt 0.586596 0.164171 +vt 0.591566 0.221736 +vt 0.919848 0.462088 +vt 0.924400 0.459418 +vt 0.932799 0.462552 +vt 0.936505 0.460001 +vt 0.914853 0.457033 +vt 0.912969 0.458780 +vt 0.911051 0.461039 +vt 0.945951 0.460521 +vt 0.941970 0.463070 +vt 0.896594 0.462992 +vt 0.902819 0.462828 +vt 0.775513 0.183818 +vt 0.714664 0.225413 +vt 0.594393 0.311859 +vt 0.240207 0.064107 +vt 0.220228 0.127313 +vt 0.137886 0.045291 +vt 0.134162 0.116701 +vt 0.209620 0.176711 +vt 0.132836 0.176022 +vt 0.803506 0.201004 +vt 0.853165 0.100422 +vt 0.393776 0.367451 +vt 0.346805 0.380154 +vt 0.214240 0.228892 +vt 0.133514 0.241035 +vt 0.939147 0.464980 +vt 0.930869 0.464578 +vt 0.937502 0.466649 +vt 0.929700 0.466322 +vt 0.911763 0.464455 +vt 0.904647 0.464520 +vt 0.910929 0.462701 +vt 0.906026 0.466148 +vt 0.912450 0.466086 +vt 0.920833 0.464349 +vt 0.920890 0.466118 +vt 0.899670 0.464526 +vt 0.896490 0.464450 +vt 0.897930 0.466107 +vt 0.901270 0.466162 +vt 0.924570 0.397524 +vt 0.934172 0.397517 +vt 0.901960 0.397532 +vt 0.912366 0.397543 +vt 0.902477 0.398810 +vt 0.914428 0.398827 +vt 0.887934 0.397535 +vt 0.886084 0.398748 +vt 0.939158 0.397548 +vt 0.916553 0.401268 +vt 0.903345 0.401161 +vt 0.904419 0.404260 +vt 0.918892 0.404595 +vt 0.883770 0.401252 +vt 0.880927 0.404722 +vt 0.600870 0.640918 +vt 0.595916 0.679782 +vt 0.517366 0.634965 +vt 0.510699 0.676291 +vt 0.593633 0.724091 +vt 0.505796 0.719121 +vt 0.905488 0.424961 +vt 0.912357 0.424967 +vt 0.905294 0.428912 +vt 0.913340 0.429138 +vt 0.911087 0.422154 +vt 0.905906 0.421495 +vt 0.587548 0.772055 +vt 0.501279 0.762876 +vt 0.497144 0.804816 +vt 0.579229 0.819401 +vt 0.904076 0.437412 +vt 0.904780 0.433190 +vt 0.911884 0.438770 +vt 0.913199 0.433998 +vt 0.570764 0.860428 +vt 0.494669 0.842655 +vt 0.495808 0.877438 +vt 0.568980 0.893979 +vt 0.903210 0.444063 +vt 0.903361 0.441071 +vt 0.908067 0.444769 +vt 0.909872 0.442542 +vt 0.918142 0.453706 +vt 0.902496 0.453271 +vt 0.928783 0.450398 +vt 0.935730 0.445715 +vt 0.939896 0.439756 +vt 0.941415 0.433124 +vt 0.940295 0.426582 +vt 0.937084 0.420446 +vt 0.931618 0.414911 +vt 0.921769 0.409549 +vt 0.905101 0.407893 +vt 0.876573 0.409920 +vt 0.866307 0.415598 +vt 0.859425 0.421874 +vt 0.854503 0.429219 +vt 0.853866 0.435555 +vt 0.855666 0.441340 +vt 0.846009 0.439206 +vt 0.849189 0.444410 +vt 0.859693 0.446280 +vt 0.853635 0.449316 +vt 0.859396 0.453185 +vt 0.333511 0.830512 +vt 0.255441 0.838224 +vt 0.335539 0.859065 +vt 0.275714 0.857682 +vt 0.889827 0.451740 +vt 0.862926 0.421743 +vt 0.859205 0.428005 +vt 0.137030 0.645509 +vt 0.099669 0.709478 +vt 0.114209 0.644610 +vt 0.072436 0.710311 +vt 0.217381 0.600094 +vt 0.193334 0.589335 +vt 0.869662 0.416377 +vt 0.857993 0.434235 +vt 0.859086 0.440054 +vt 0.083907 0.774978 +vt 0.093256 0.834193 +vt 0.056643 0.778851 +vt 0.067488 0.842396 +vt 0.916008 0.412068 +vt 0.903601 0.410265 +vt 0.543475 0.557405 +vt 0.557800 0.533271 +vt 0.655545 0.572596 +vt 0.685834 0.551732 +vt 0.910530 0.415402 +vt 0.913091 0.413541 +vt 0.918257 0.418305 +vt 0.921836 0.416936 +vt 0.925340 0.416062 +vt 0.879532 0.412275 +vt 0.318062 0.571086 +vt 0.304302 0.551225 +vt 0.931494 0.421140 +vt 0.923547 0.422692 +vt 0.927682 0.421785 +vt 0.926515 0.428111 +vt 0.931209 0.427509 +vt 0.935120 0.427050 +vt 0.936295 0.433481 +vt 0.927320 0.434037 +vt 0.932331 0.433786 +vt 0.925669 0.439922 +vt 0.930432 0.440034 +vt 0.934525 0.439972 +vt 0.912845 0.451737 +vt 0.922595 0.449614 +vt 0.907361 0.448978 +vt 0.915126 0.447877 +vt 0.909842 0.450414 +vt 0.918684 0.448912 +vt 0.515560 0.943140 +vt 0.618068 0.949096 +vt 0.529717 0.959537 +vt 0.647404 0.965201 +vt 0.901128 0.451294 +vt 0.929882 0.445604 +vt 0.921412 0.444811 +vt 0.925747 0.445329 +vt 0.862632 0.444730 +vt 0.194162 0.909528 +vt 0.176891 0.924466 +vt 0.127886 0.880246 +vt 0.105635 0.892789 +vt 0.298575 0.918513 +vt 0.289302 0.932026 +vt 0.410040 0.927663 +vt 0.412647 0.940987 +vt 0.152917 0.714025 +vt 0.188039 0.660899 +vt 0.251002 0.622891 +vt 0.148083 0.821618 +vt 0.139091 0.770988 +vt 0.624566 0.605374 +vt 0.529124 0.594060 +vt 0.907910 0.418325 +vt 0.914417 0.420366 +vt 0.333860 0.602351 +vt 0.918293 0.424021 +vt 0.920590 0.428770 +vt 0.920879 0.434155 +vt 0.919487 0.439514 +vt 0.911345 0.446349 +vt 0.904990 0.446728 +vt 0.503730 0.914675 +vt 0.590033 0.923870 +vt 0.916084 0.443813 +vt 0.174218 0.860862 +vt 0.232830 0.882474 +vt 0.318561 0.890705 +vt 0.412205 0.900441 +vt 0.414872 0.864697 +vt 0.414169 0.832004 +vt 0.413463 0.796679 +vt 0.414763 0.757000 +vt 0.418623 0.715141 +vt 0.424042 0.673740 +vt 0.428561 0.633258 +vt 0.429426 0.594048 +vt 0.429051 0.559095 +vt 0.429259 0.535162 +vt 0.891421 0.410387 +vt 0.891335 0.407994 +vt 0.892300 0.404278 +vt 0.892667 0.401108 +vt 0.892803 0.398753 +vt 0.893101 0.397518 +vt 0.953337 0.401538 +vt 0.958091 0.405199 +vt 0.947500 0.399036 +vt 0.961860 0.409791 +vt 0.964499 0.415028 +vt 0.966120 0.420717 +vt 0.967305 0.426924 +vt 0.967388 0.433074 +vt 0.966427 0.438883 +vt 0.964510 0.444202 +vt 0.961861 0.448940 +vt 0.958944 0.453645 +vt 0.955428 0.457592 +vt 0.951844 0.460785 +vt 0.948132 0.463506 +vt 0.945008 0.465414 +vt 0.942800 0.466896 +vt 0.940897 0.397660 +vt 0.894646 0.464377 +vt 0.893748 0.464327 +vt 0.895819 0.465909 +vt 0.894732 0.465707 +vt 0.898046 0.468336 +vt 0.895591 0.467749 +vt 0.894211 0.467377 +vt 0.892528 0.469525 +vt 0.894053 0.470321 +vt 0.897020 0.472125 +vt 0.906461 0.468060 +vt 0.901761 0.468217 +vt 0.901883 0.471147 +vt 0.906501 0.470456 +vt 0.912592 0.467918 +vt 0.912253 0.470089 +vt 0.920674 0.470154 +vt 0.920682 0.467923 +vt 0.929876 0.470181 +vt 0.929300 0.468129 +vt 0.937020 0.468441 +vt 0.938213 0.470896 +vt 0.942275 0.468514 +vt 0.942757 0.470744 +vt 0.890006 0.449500 +vt 0.859393 0.397599 +vt 0.852976 0.399065 +vt 0.847065 0.401675 +vt 0.841270 0.405026 +vt 0.953466 0.401386 +vt 0.958188 0.405089 +vt 0.947588 0.398916 +vt 0.961862 0.409747 +vt 0.964391 0.415022 +vt 0.965926 0.420729 +vt 0.967068 0.426923 +vt 0.967242 0.433135 +vt 0.966314 0.439008 +vt 0.964406 0.444378 +vt 0.961584 0.449120 +vt 0.954279 0.457569 +vt 0.958267 0.453722 +vt 0.870463 0.459645 +vt 0.869977 0.459728 +vt 0.865611 0.460368 +vt 0.865391 0.460791 +vt 0.875883 0.460032 +vt 0.875386 0.460071 +vt 0.889107 0.462568 +vt 0.044392 0.517280 +vt 0.043999 0.560029 +vt 0.579657 0.457140 +vt 0.472222 0.467543 +vt 0.576570 0.399149 +vt 0.470583 0.402538 +vt 0.055194 0.327681 +vt 0.048040 0.442488 +vt 0.836433 0.409343 +vt 0.832578 0.414030 +vt 0.832317 0.414141 +vt 0.829542 0.419704 +vt 0.829240 0.419624 +vt 0.456894 0.171519 +vt 0.545104 0.178866 +vt 0.459246 0.232082 +vt 0.554780 0.242428 +vt 0.861810 0.461905 +vt 0.861843 0.462560 +vt 0.950530 0.460750 +vt 0.946775 0.463400 +vt 0.468306 0.320445 +vt 0.572701 0.325840 +vt 0.057144 0.041836 +vt 0.056343 0.115320 +vt 0.056323 0.176259 +vt 0.056512 0.244825 +vt 0.943577 0.465237 +vt 0.941527 0.466697 +vt 0.893773 0.464335 +vt 0.894526 0.465626 +vt 0.894385 0.465571 +vt 0.940912 0.397604 +vt 0.893807 0.467247 +vt 0.893563 0.467166 +vt 0.891985 0.469369 +vt 0.891535 0.469419 +vt 0.940762 0.470517 +vt 0.940364 0.468392 +vt 0.866236 0.398834 +vt 0.873711 0.398813 +vt 0.870971 0.397493 +vt 0.877506 0.397514 +vt 0.860032 0.398872 +vt 0.865522 0.397455 +vt 0.856026 0.399014 +vt 0.861954 0.397568 +vt 0.853853 0.399094 +vt 0.860159 0.397664 +vt 0.948546 0.405179 +vt 0.944496 0.401457 +vt 0.935431 0.404681 +vt 0.931632 0.401375 +vt 0.939488 0.398861 +vt 0.927974 0.398901 +vt 0.861966 0.401526 +vt 0.855096 0.401600 +vt 0.850751 0.405417 +vt 0.858121 0.405363 +vt 0.867731 0.405188 +vt 0.850561 0.401575 +vt 0.848094 0.401586 +vt 0.842791 0.404957 +vt 0.845766 0.405198 +vt 0.945500 0.398818 +vt 0.951158 0.401375 +vt 0.955535 0.405156 +vt 0.953600 0.414936 +vt 0.951437 0.409790 +vt 0.942950 0.414410 +vt 0.938847 0.409148 +vt 0.863906 0.410047 +vt 0.854469 0.410101 +vt 0.846800 0.410021 +vt 0.843291 0.414792 +vt 0.850618 0.415218 +vt 0.858112 0.415702 +vt 0.958875 0.409842 +vt 0.961147 0.415077 +vt 0.955100 0.420509 +vt 0.945887 0.420220 +vt 0.955942 0.426574 +vt 0.947818 0.426423 +vt 0.962495 0.420748 +vt 0.963347 0.426902 +vt 0.947179 0.438896 +vt 0.955415 0.438781 +vt 0.948355 0.432791 +vt 0.956270 0.432802 +vt 0.963455 0.433109 +vt 0.962550 0.439010 +vt 0.939730 0.449457 +vt 0.950281 0.449152 +vt 0.944309 0.444589 +vt 0.953464 0.444290 +vt 0.960647 0.444424 +vt 0.957836 0.449233 +vt 0.928866 0.456683 +vt 0.941589 0.457208 +vt 0.933669 0.453285 +vt 0.946319 0.453375 +vt 0.954103 0.453514 +vt 0.949874 0.457416 +vt 0.877353 0.455968 +vt 0.882269 0.458025 +vt 0.890577 0.455047 +vt 0.892317 0.457757 +vt 0.886684 0.460112 +vt 0.894230 0.460211 +vt 0.902677 0.460467 +vt 0.902670 0.458019 +vt 0.902808 0.455334 +vt 0.865825 0.458435 +vt 0.871446 0.458982 +vt 0.869597 0.456984 +vt 0.875200 0.458466 +vt 0.877063 0.460000 +vt 0.880928 0.460060 +vt 0.890358 0.462714 +vt 0.889224 0.462652 +vt 0.892541 0.462593 +vt 0.253473 0.420340 +vt 0.198325 0.471074 +vt 0.257191 0.464291 +vt 0.201641 0.514357 +vt 0.644363 0.422582 +vt 0.643061 0.366324 +vt 0.703499 0.366966 +vt 0.703370 0.314326 +vt 0.745969 0.267070 +vt 0.753820 0.293297 +vt 0.305266 0.371658 +vt 0.304409 0.414784 +vt 0.230885 0.286168 +vt 0.167912 0.306331 +vt 0.242536 0.354324 +vt 0.188981 0.401339 +vt 0.300813 0.317790 +vt 0.290984 0.262458 +vt 0.343946 0.231017 +vt 0.355397 0.284532 +vt 0.356783 0.335152 +vt 0.414764 0.292810 +vt 0.419941 0.236001 +vt 0.413771 0.173263 +vt 0.370421 0.125545 +vt 0.313385 0.086563 +vt 0.319456 0.180460 +vt 0.282902 0.142155 +vt 0.261679 0.175104 +vt 0.275739 0.211488 +vt 0.841603 0.409572 +vt 0.838159 0.409243 +vt 0.834209 0.413908 +vt 0.837981 0.414182 +vt 0.352720 0.639241 +vt 0.294558 0.645659 +vt 0.348213 0.675519 +vt 0.274212 0.673847 +vt 0.253789 0.714174 +vt 0.339072 0.715472 +vt 0.846514 0.420792 +vt 0.839885 0.419736 +vt 0.834481 0.428371 +vt 0.838869 0.430451 +vt 0.843430 0.433385 +vt 0.852102 0.422532 +vt 0.834732 0.419195 +vt 0.830666 0.418987 +vt 0.827717 0.426976 +vt 0.830662 0.427303 +vt 0.241492 0.801977 +vt 0.330569 0.796358 +vt 0.241562 0.759109 +vt 0.332348 0.756954 +vt 0.878346 0.448288 +vt 0.868619 0.446935 +vt 0.875777 0.450429 +vt 0.865577 0.448677 +vt 0.860982 0.459109 +vt 0.863516 0.455972 +vt 0.868771 0.453598 +vt 0.797949 0.022112 +vt 0.816816 0.093012 +vt 0.715991 0.092651 +vt 0.720595 0.147032 +vt 0.636546 0.210325 +vt 0.627672 0.148444 +vt 0.919955 0.462087 +vt 0.933215 0.462650 +vt 0.924520 0.459410 +vt 0.936971 0.460171 +vt 0.915797 0.455832 +vt 0.913434 0.458571 +vt 0.911682 0.460937 +vt 0.945768 0.460575 +vt 0.941689 0.463136 +vt 0.897291 0.462545 +vt 0.903757 0.462585 +vt 0.772502 0.189202 +vt 0.711355 0.231084 +vt 0.641706 0.289174 +vt 0.247515 0.059560 +vt 0.175872 0.043369 +vt 0.230266 0.122298 +vt 0.166908 0.113803 +vt 0.162066 0.173298 +vt 0.220575 0.173418 +vt 0.800674 0.205793 +vt 0.855305 0.094200 +vt 0.399643 0.347472 +vt 0.348371 0.378515 +vt 0.223314 0.226619 +vt 0.162858 0.235961 +vt 0.938505 0.464915 +vt 0.930828 0.464538 +vt 0.929084 0.466249 +vt 0.936418 0.466469 +vt 0.904992 0.464496 +vt 0.911714 0.462545 +vt 0.912260 0.464434 +vt 0.906001 0.466171 +vt 0.912549 0.466198 +vt 0.920438 0.466178 +vt 0.920682 0.464371 +vt 0.896238 0.464476 +vt 0.897673 0.466070 +vt 0.901142 0.466120 +vt 0.933851 0.397545 +vt 0.924135 0.397565 +vt 0.901567 0.397461 +vt 0.902111 0.398787 +vt 0.911927 0.397463 +vt 0.913998 0.398826 +vt 0.885568 0.398789 +vt 0.887707 0.397486 +vt 0.939027 0.397536 +vt 0.902897 0.401138 +vt 0.916139 0.401275 +vt 0.904075 0.404332 +vt 0.918631 0.404656 +vt 0.883077 0.401373 +vt 0.880245 0.404983 +vt 0.600135 0.641640 +vt 0.519216 0.636196 +vt 0.595756 0.680499 +vt 0.513483 0.677706 +vt 0.509018 0.719971 +vt 0.595108 0.724198 +vt 0.912942 0.429219 +vt 0.912006 0.425106 +vt 0.905419 0.428922 +vt 0.910791 0.422281 +vt 0.905844 0.421559 +vt 0.590769 0.769750 +vt 0.503982 0.762367 +vt 0.498249 0.802950 +vt 0.581926 0.813498 +vt 0.904305 0.436885 +vt 0.911907 0.438227 +vt 0.905052 0.432984 +vt 0.913047 0.433844 +vt 0.571758 0.851938 +vt 0.493564 0.840197 +vt 0.493370 0.874734 +vt 0.568900 0.884732 +vt 0.903203 0.443238 +vt 0.908124 0.443775 +vt 0.903445 0.440313 +vt 0.909903 0.441649 +vt 0.902850 0.452456 +vt 0.918742 0.452460 +vt 0.929033 0.449192 +vt 0.935553 0.444785 +vt 0.939489 0.439171 +vt 0.940895 0.433027 +vt 0.939916 0.426757 +vt 0.936762 0.420698 +vt 0.931211 0.415109 +vt 0.904610 0.407951 +vt 0.921344 0.409650 +vt 0.876099 0.410269 +vt 0.865754 0.416146 +vt 0.858856 0.422274 +vt 0.854080 0.429250 +vt 0.848700 0.443676 +vt 0.855252 0.440105 +vt 0.845714 0.439016 +vt 0.853622 0.434905 +vt 0.852614 0.447663 +vt 0.858958 0.445110 +vt 0.858176 0.451853 +vt 0.254385 0.836095 +vt 0.333265 0.830744 +vt 0.334347 0.859927 +vt 0.274272 0.857068 +vt 0.889824 0.451480 +vt 0.858947 0.427844 +vt 0.863033 0.422095 +vt 0.160452 0.654158 +vt 0.126019 0.649524 +vt 0.111374 0.707428 +vt 0.074711 0.707898 +vt 0.232092 0.611555 +vt 0.203545 0.598866 +vt 0.869857 0.416948 +vt 0.858451 0.439034 +vt 0.857612 0.433475 +vt 0.086444 0.767612 +vt 0.053832 0.770468 +vt 0.085639 0.828171 +vt 0.059040 0.833261 +vt 0.915613 0.412200 +vt 0.903128 0.410252 +vt 0.540600 0.554531 +vt 0.653253 0.571690 +vt 0.552741 0.532581 +vt 0.682275 0.551691 +vt 0.910336 0.415321 +vt 0.917730 0.418674 +vt 0.912790 0.413538 +vt 0.921258 0.417307 +vt 0.924944 0.416332 +vt 0.879341 0.412694 +vt 0.321928 0.578317 +vt 0.305300 0.558373 +vt 0.930972 0.421500 +vt 0.922517 0.423241 +vt 0.926792 0.422268 +vt 0.925060 0.428584 +vt 0.929895 0.427930 +vt 0.934420 0.427304 +vt 0.935453 0.433435 +vt 0.925801 0.434263 +vt 0.930838 0.433902 +vt 0.924243 0.439743 +vt 0.929152 0.439726 +vt 0.933786 0.439455 +vt 0.922618 0.448568 +vt 0.913071 0.450609 +vt 0.907300 0.448560 +vt 0.909883 0.449686 +vt 0.914720 0.447235 +vt 0.918464 0.448158 +vt 0.513713 0.938992 +vt 0.528694 0.953445 +vt 0.617347 0.944413 +vt 0.647892 0.957038 +vt 0.901060 0.450464 +vt 0.929479 0.444749 +vt 0.920523 0.444350 +vt 0.924927 0.444695 +vt 0.861743 0.443993 +vt 0.191556 0.905473 +vt 0.119561 0.876603 +vt 0.173642 0.917872 +vt 0.096090 0.886393 +vt 0.296111 0.916924 +vt 0.285563 0.930752 +vt 0.407594 0.925155 +vt 0.411737 0.936637 +vt 0.175067 0.711347 +vt 0.212659 0.665019 +vt 0.264355 0.628942 +vt 0.154483 0.814520 +vt 0.154113 0.763611 +vt 0.623018 0.605621 +vt 0.528987 0.594894 +vt 0.907779 0.418347 +vt 0.914012 0.420577 +vt 0.339791 0.607004 +vt 0.917709 0.424320 +vt 0.919641 0.429082 +vt 0.919962 0.434273 +vt 0.918588 0.439240 +vt 0.911088 0.445577 +vt 0.904848 0.446138 +vt 0.588358 0.917245 +vt 0.500784 0.908814 +vt 0.915514 0.443200 +vt 0.178893 0.855096 +vt 0.233880 0.878659 +vt 0.317203 0.888741 +vt 0.409219 0.897533 +vt 0.412456 0.865776 +vt 0.413517 0.832907 +vt 0.415303 0.797177 +vt 0.419030 0.758087 +vt 0.424284 0.717135 +vt 0.429773 0.675932 +vt 0.433166 0.635493 +vt 0.431719 0.596003 +vt 0.426262 0.535529 +vt 0.428450 0.560105 +vt 0.890897 0.408138 +vt 0.891059 0.410492 +vt 0.891880 0.404459 +vt 0.892481 0.401195 +vt 0.892744 0.398811 +vt 0.892774 0.397499 +vt 0.852987 0.399150 +vt 0.859402 0.397672 +vt 0.847027 0.401638 +vt 0.841440 0.405030 +vt 0.139391 0.505963 +vt 0.140772 0.546375 +vt 0.105327 0.324975 +vt 0.131454 0.436403 +vt 0.836758 0.409301 +vt 0.826856 0.427241 +vt 0.103269 0.042003 +vt 0.100779 0.113050 +vt 0.099208 0.173793 +vt 0.099637 0.242841 +vt 0.893304 0.464316 +vt 0.894343 0.465793 +vt 0.894093 0.464377 +vt 0.895401 0.465971 +vt 0.893628 0.467665 +vt 0.890751 0.471053 +vt 0.897653 0.467915 +vt 0.895086 0.467874 +vt 0.893376 0.470550 +vt 0.896513 0.470318 +vt 0.906138 0.467954 +vt 0.901291 0.467913 +vt 0.900442 0.470186 +vt 0.905385 0.470181 +vt 0.912382 0.468058 +vt 0.911527 0.470316 +vt 0.918635 0.470453 +vt 0.919770 0.468076 +vt 0.926488 0.470872 +vt 0.927835 0.468189 +vt 0.935282 0.468257 +vt 0.935209 0.471328 +vt 0.878197 0.500625 +vt 0.878935 0.505269 +vt 0.877915 0.500707 +vt 0.878376 0.505430 +vt 0.878490 0.500327 +vt 0.879515 0.504678 +vt 0.878776 0.499827 +vt 0.880077 0.503685 +vt 0.879041 0.499148 +vt 0.880596 0.502336 +vt 0.879273 0.498323 +vt 0.881050 0.500691 +vt 0.879461 0.497390 +vt 0.881414 0.498833 +vt 0.879595 0.496393 +vt 0.881685 0.496848 +vt 0.879673 0.495381 +vt 0.881831 0.494834 +vt 0.879688 0.494400 +vt 0.881855 0.492886 +vt 0.879641 0.493495 +vt 0.881754 0.491093 +vt 0.879517 0.492692 +vt 0.881496 0.489502 +vt 0.879256 0.491990 +vt 0.880966 0.488128 +vt 0.878724 0.491679 +vt 0.879976 0.487255 +vt 0.878985 0.491764 +vt 0.880441 0.487544 +vt 0.880259 0.509816 +vt 0.879427 0.510054 +vt 0.881118 0.508941 +vt 0.881951 0.507469 +vt 0.882719 0.505470 +vt 0.883385 0.503037 +vt 0.883918 0.500283 +vt 0.884295 0.497337 +vt 0.884501 0.494341 +vt 0.884524 0.491438 +vt 0.884373 0.488781 +vt 0.883999 0.486461 +vt 0.883210 0.484429 +vt 0.882394 0.483424 +vt 0.882124 0.514208 +vt 0.881033 0.514520 +vt 0.883251 0.513061 +vt 0.884343 0.511133 +vt 0.885349 0.508513 +vt 0.886222 0.505324 +vt 0.886921 0.501715 +vt 0.887414 0.497854 +vt 0.887677 0.493924 +vt 0.887702 0.490113 +vt 0.887496 0.486645 +vt 0.886980 0.483610 +vt 0.885938 0.480910 +vt 0.884878 0.479558 +vt 0.883170 0.518762 +vt 0.884506 0.518380 +vt 0.885883 0.516979 +vt 0.887217 0.514621 +vt 0.888447 0.511419 +vt 0.889514 0.507521 +vt 0.890369 0.503109 +vt 0.890971 0.498390 +vt 0.891293 0.493586 +vt 0.891320 0.488919 +vt 0.891054 0.484665 +vt 0.890395 0.481066 +vt 0.889190 0.477958 +vt 0.887817 0.476052 +vt 0.885807 0.522719 +vt 0.887367 0.522273 +vt 0.888975 0.520637 +vt 0.890533 0.517885 +vt 0.891968 0.514147 +vt 0.893214 0.509596 +vt 0.894212 0.504446 +vt 0.894915 0.498938 +vt 0.895291 0.493329 +vt 0.895322 0.487882 +vt 0.895000 0.482915 +vt 0.894205 0.478779 +vt 0.892842 0.475169 +vt 0.891068 0.473073 +vt 0.888906 0.526332 +vt 0.890668 0.525829 +vt 0.892483 0.523982 +vt 0.894241 0.520876 +vt 0.895861 0.516656 +vt 0.897267 0.511520 +vt 0.898394 0.505707 +vt 0.899187 0.499489 +vt 0.899612 0.493158 +vt 0.899646 0.487009 +vt 0.899286 0.481354 +vt 0.898411 0.476638 +vt 0.892421 0.529549 +vt 0.894359 0.528996 +vt 0.896354 0.526965 +vt 0.898288 0.523550 +vt 0.900069 0.518911 +vt 0.901615 0.513263 +vt 0.902854 0.506872 +vt 0.903726 0.500036 +vt 0.904193 0.493075 +vt 0.904231 0.486314 +vt 0.903834 0.480100 +vt 0.902975 0.475040 +vt 0.896302 0.532323 +vt 0.898388 0.531728 +vt 0.900534 0.529543 +vt 0.902614 0.525869 +vt 0.904531 0.520877 +vt 0.906194 0.514801 +vt 0.907527 0.507925 +vt 0.908466 0.500570 +vt 0.908967 0.493081 +vt 0.909009 0.485806 +vt 0.908572 0.479151 +vt 0.907654 0.473824 +vt 0.900491 0.534614 +vt 0.902694 0.533986 +vt 0.904960 0.531679 +vt 0.907157 0.527799 +vt 0.909181 0.522528 +vt 0.910937 0.516111 +vt 0.912345 0.508850 +vt 0.913336 0.501084 +vt 0.913866 0.493175 +vt 0.913909 0.485494 +vt 0.913460 0.478418 +vt 0.912585 0.472851 +vt 0.904927 0.536388 +vt 0.907215 0.535736 +vt 0.909569 0.533340 +vt 0.911850 0.529311 +vt 0.913952 0.523838 +vt 0.915776 0.517175 +vt 0.917237 0.509635 +vt 0.918266 0.501570 +vt 0.918854 0.493342 +vt 0.918947 0.485357 +vt 0.918440 0.478006 +vt 0.917870 0.471971 +vt 0.911914 0.537955 +vt 0.914263 0.537286 +vt 0.916678 0.534827 +vt 0.919019 0.530693 +vt 0.921175 0.525076 +vt 0.923047 0.518239 +vt 0.924546 0.510502 +vt 0.925585 0.502224 +vt 0.926227 0.493754 +vt 0.926493 0.485583 +vt 0.925762 0.478045 +vt 0.924764 0.471485 +vt 0.919062 0.538392 +vt 0.921403 0.537724 +vt 0.923810 0.535275 +vt 0.926142 0.531156 +vt 0.930338 0.525761 +vt 0.931620 0.519674 +vt 0.933283 0.512932 +vt 0.932692 0.502839 +vt 0.933977 0.494768 +vt 0.934333 0.486371 +vt 0.933206 0.478784 +vt 0.931863 0.472204 +vt 0.923820 0.537920 +vt 0.926110 0.537268 +vt 0.928464 0.534872 +vt 0.932388 0.530343 +vt 0.937335 0.506755 +vt 0.941235 0.498334 +vt 0.941521 0.487989 +vt 0.940371 0.480184 +vt 0.938481 0.473907 +vt 0.928485 0.536884 +vt 0.930691 0.536256 +vt 0.934789 0.533043 +vt 0.932989 0.535298 +vt 0.935078 0.534703 +vt 0.938368 0.532576 +vt 0.947164 0.489068 +vt 0.947066 0.497764 +vt 0.946239 0.481893 +vt 0.944283 0.476284 +vt 0.937267 0.533185 +vt 0.939209 0.532632 +vt 0.941919 0.530982 +vt 0.950271 0.497772 +vt 0.950689 0.490156 +vt 0.950340 0.483450 +vt 0.948203 0.478162 +vt 0.941256 0.530577 +vt 0.943023 0.530074 +vt 0.945589 0.528338 +vt 0.953490 0.491089 +vt 0.952472 0.498024 +vt 0.953154 0.485389 +vt 0.951415 0.480527 +vt 0.944898 0.527510 +vt 0.946464 0.527065 +vt 0.948879 0.525086 +vt 0.955336 0.498108 +vt 0.955494 0.492270 +vt 0.955142 0.488211 +vt 0.954263 0.484425 +vt 0.949389 0.475505 +vt 0.954052 0.482326 +vt 0.947570 0.475109 +vt 0.943613 0.471998 +vt 0.945693 0.473082 +vt 0.949187 0.522238 +vt 0.950577 0.521636 +vt 0.951775 0.520708 +vt 0.950886 0.519379 +vt 0.952605 0.518141 +vt 0.952742 0.516616 +vt 0.954470 0.515316 +vt 0.878125 0.495997 +vt 0.699705 0.808301 +vt 0.767751 0.813767 +vt 0.710393 0.859091 +vt 0.770203 0.857847 +vt 0.670460 0.860010 +vt 0.652167 0.800156 +vt 0.732575 0.902022 +vt 0.706983 0.910753 +vt 0.776574 0.894725 +vt 0.709069 0.706824 +vt 0.772884 0.721001 +vt 0.699610 0.756109 +vt 0.769128 0.766819 +vt 0.650715 0.739559 +vt 0.665169 0.685443 +vt 0.747389 0.629544 +vt 0.781976 0.645207 +vt 0.726035 0.663915 +vt 0.777571 0.679447 +vt 0.692510 0.641696 +vt 0.725600 0.608173 +vt 0.800844 0.613722 +vt 0.782354 0.622030 +vt 0.800842 0.598447 +vt 0.770640 0.606739 +vt 0.761516 0.586356 +vt 0.801211 0.578120 +vt 0.843418 0.585771 +vt 0.884582 0.608278 +vt 0.833474 0.606525 +vt 0.861681 0.629270 +vt 0.821482 0.621769 +vt 0.826927 0.645008 +vt 0.841154 0.721344 +vt 0.835351 0.679466 +vt 0.901508 0.709495 +vt 0.885190 0.664947 +vt 0.920582 0.644640 +vt 0.946246 0.692573 +vt 0.840491 0.814502 +vt 0.842749 0.767471 +vt 0.905321 0.811872 +vt 0.908491 0.759591 +vt 0.957769 0.748636 +vt 0.953229 0.808266 +vt 0.832824 0.894364 +vt 0.836470 0.858222 +vt 0.876480 0.901039 +vt 0.893987 0.860506 +vt 0.934495 0.863509 +vt 0.904941 0.908789 +vt 0.808557 0.928096 +vt 0.833115 0.918674 +vt 0.811165 0.939260 +vt 0.850764 0.928355 +vt 0.866017 0.939324 +vt 0.815782 0.955298 +vt 0.767445 0.930389 +vt 0.781351 0.919619 +vt 0.756778 0.947206 +vt 0.943537 0.514246 +vt 0.944979 0.511457 +vt 0.944004 0.514141 +vt 0.945299 0.511731 +vt 0.946866 0.510467 +vt 0.945612 0.512005 +vt 0.946775 0.509925 +vt 0.944125 0.524447 +vt 0.943125 0.523168 +vt 0.944265 0.522893 +vt 0.943363 0.521760 +vt 0.943213 0.518650 +vt 0.943600 0.520352 +vt 0.942839 0.519741 +vt 0.942465 0.520831 +vt 0.942508 0.517563 +vt 0.943036 0.516979 +vt 0.944472 0.514036 +vt 0.943564 0.516394 +vt 0.948503 0.507957 +vt 0.948316 0.508687 +vt 0.946664 0.509365 +vt 0.949207 0.508705 +vt 0.948096 0.509397 +vt 0.949608 0.507910 +vt 0.950009 0.507096 +vt 0.951195 0.506751 +vt 0.950679 0.507606 +vt 0.950161 0.508443 +vt 0.951005 0.508659 +vt 0.951647 0.507843 +vt 0.951744 0.509448 +vt 0.952587 0.508900 +vt 0.952323 0.510866 +vt 0.953318 0.510638 +vt 0.953444 0.508317 +vt 0.952296 0.507042 +vt 0.954069 0.512878 +vt 0.953344 0.512779 +vt 0.954198 0.510416 +vt 0.952538 0.512757 +vt 0.952220 0.514880 +vt 0.952777 0.515115 +vt 0.952001 0.518020 +vt 0.951641 0.517475 +vt 0.953314 0.515413 +vt 0.951263 0.516984 +vt 0.949848 0.518868 +vt 0.950071 0.519673 +vt 0.948367 0.522605 +vt 0.948260 0.521460 +vt 0.950291 0.520481 +vt 0.948152 0.520315 +vt 0.946642 0.521256 +vt 0.946704 0.522693 +vt 0.945370 0.524785 +vt 0.945389 0.523190 +vt 0.946766 0.524131 +vt 0.945409 0.521595 +vt 0.944404 0.521338 +vt 0.678283 0.626368 +vt 0.715348 0.591757 +vt 0.648199 0.671421 +vt 0.648584 0.866073 +vt 0.628808 0.796368 +vt 0.694447 0.921544 +vt 0.627873 0.728326 +vt 0.756739 0.569509 +vt 0.801790 0.560389 +vt 0.753465 0.960832 +vt 0.819304 0.969461 +vt 0.896919 0.591012 +vt 0.849419 0.567507 +vt 0.878442 0.952645 +vt 0.925282 0.919811 +vt 0.970524 0.680324 +vt 0.939853 0.628765 +vt 0.962143 0.870229 +vt 0.978626 0.806509 +vt 0.983346 0.741752 +vt 0.947425 0.509189 +vt 0.948517 0.508521 +vt 0.946164 0.510225 +vt 0.942852 0.515989 +vt 0.943731 0.513771 +vt 0.942484 0.518080 +vt 0.944874 0.511783 +vt 0.949456 0.508269 +vt 0.950283 0.508511 +vt 0.942699 0.519730 +vt 0.943487 0.520694 +vt 0.950990 0.509314 +vt 0.951552 0.510694 +vt 0.944633 0.521012 +vt 0.946034 0.520645 +vt 0.951791 0.512457 +vt 0.951461 0.514432 +vt 0.947604 0.519694 +vt 0.949207 0.518265 +vt 0.950530 0.516413 +vt 0.954352 0.507334 +vt 0.955064 0.510040 +vt 0.953029 0.505660 +vt 0.954691 0.513093 +vt 0.953563 0.516187 +vt 0.945738 0.508370 +vt 0.942931 0.511155 +vt 0.941124 0.514785 +vt 0.948237 0.525023 +vt 0.946042 0.527051 +vt 0.950358 0.522206 +vt 0.939919 0.523165 +vt 0.940778 0.525984 +vt 0.942236 0.527579 +vt 0.940031 0.519157 +vt 0.950380 0.505668 +vt 0.948360 0.506655 +vt 0.951792 0.505283 +vt 0.952106 0.519194 +vt 0.944080 0.527997 +vt 0.955136 0.505085 +vt 0.955458 0.508799 +vt 0.953996 0.503048 +vt 0.954947 0.512890 +vt 0.953571 0.516724 +vt 0.940392 0.509704 +vt 0.943959 0.505926 +vt 0.937487 0.514053 +vt 0.946965 0.527152 +vt 0.943743 0.529685 +vt 0.949863 0.523920 +vt 0.936263 0.528363 +vt 0.934831 0.524989 +vt 0.938515 0.530358 +vt 0.935440 0.520327 +vt 0.947235 0.504116 +vt 0.949823 0.503295 +vt 0.952034 0.502955 +vt 0.951882 0.520410 +vt 0.941028 0.530790 +vt 0.956376 0.507194 +vt 0.956255 0.501869 +vt 0.955436 0.512282 +vt 0.953780 0.516679 +vt 0.874321 0.260529 +vt 0.874570 0.258357 +vt 0.870642 0.262514 +vt 0.875205 0.262091 +vt 0.870232 0.260129 +vt 0.874180 0.274349 +vt 0.878088 0.275377 +vt 0.875282 0.284248 +vt 0.879128 0.284194 +vt 0.876451 0.268146 +vt 0.871760 0.267630 +vt 0.879196 0.270887 +vt 0.875496 0.265391 +vt 0.893101 0.284420 +vt 0.892287 0.271326 +vt 0.879947 0.284131 +vt 0.877309 0.242158 +vt 0.869772 0.241647 +vt 0.862255 0.219399 +vt 0.855575 0.218438 +vt 0.849440 0.210845 +vt 0.862432 0.239621 +vt 0.849901 0.240235 +vt 0.863194 0.266321 +vt 0.867315 0.244511 +vt 0.876212 0.265675 +vt 0.880423 0.283451 +vt 0.866718 0.283089 +vt 0.870498 0.254293 +vt 0.863904 0.253791 +vt 0.870234 0.270504 +vt 0.864805 0.270607 +vt 0.878645 0.270230 +vt 0.879852 0.254050 +vt 0.894641 0.243235 +vt 0.885819 0.242521 +vt 0.884908 0.221559 +vt 0.874780 0.219802 +vt 0.853855 0.205189 +vt 0.868038 0.204565 +vt 0.856654 0.209577 +vt 0.870975 0.210424 +vt 0.882303 0.208527 +vt 0.885027 0.212810 +vt 0.869343 0.207181 +vt 0.855354 0.205901 +vt 0.879862 0.246326 +vt 0.872817 0.221463 +vt 0.859409 0.218500 +vt 0.885826 0.225344 +vt 0.891813 0.248223 +vt 0.886742 0.266822 +vt 0.897889 0.269881 +vt 0.890434 0.283337 +vt 0.902191 0.283202 +vt 0.887267 0.269985 +vt 0.888486 0.253806 +vt 0.897865 0.269734 +vt 0.897003 0.253871 +vt 0.890889 0.214313 +vt 0.890567 0.213820 +vt 0.887336 0.211472 +vt 0.935827 0.245027 +vt 0.948386 0.259727 +vt 0.940502 0.247339 +vt 0.952135 0.261243 +vt 0.935892 0.257903 +vt 0.929477 0.246937 +vt 0.955141 0.271935 +vt 0.951237 0.271687 +vt 0.956107 0.282705 +vt 0.951697 0.282445 +vt 0.941535 0.282520 +vt 0.939971 0.271031 +vt 0.963745 0.266939 +vt 0.955791 0.248173 +vt 0.971434 0.266214 +vt 0.963770 0.246708 +vt 0.948554 0.235961 +vt 0.955224 0.234835 +vt 0.886107 0.251776 +vt 0.887306 0.257140 +vt 0.896396 0.245174 +vt 0.901578 0.253513 +vt 0.893935 0.234459 +vt 0.893306 0.241625 +vt 0.884880 0.259333 +vt 0.895682 0.256287 +vt 0.898524 0.274248 +vt 0.887363 0.275119 +vt 0.897217 0.265981 +vt 0.885952 0.267220 +vt 0.888292 0.284017 +vt 0.899782 0.283788 +vt 0.893557 0.224473 +vt 0.903384 0.244263 +vt 0.909834 0.245212 +vt 0.904117 0.226402 +vt 0.898452 0.232315 +vt 0.905360 0.242289 +vt 0.908475 0.231470 +vt 0.914901 0.241090 +vt 0.912117 0.251402 +vt 0.921110 0.249824 +vt 0.894105 0.223477 +vt 0.905103 0.223634 +vt 0.892209 0.224715 +vt 0.891627 0.223783 +vt 0.894785 0.217728 +vt 0.904032 0.218825 +vt 0.916745 0.259188 +vt 0.905292 0.260920 +vt 0.925679 0.257542 +vt 0.919312 0.270264 +vt 0.927598 0.269904 +vt 0.909165 0.270372 +vt 0.923018 0.231732 +vt 0.931448 0.236491 +vt 0.922229 0.248254 +vt 0.927474 0.250713 +vt 0.931475 0.252998 +vt 0.939132 0.243721 +vt 0.941395 0.236759 +vt 0.941774 0.243180 +vt 0.953028 0.242625 +vt 0.951181 0.247570 +vt 0.943442 0.249961 +vt 0.949719 0.251412 +vt 0.935522 0.249090 +vt 0.932269 0.241398 +vt 0.930136 0.234395 +vt 0.929446 0.228394 +vt 0.942151 0.230847 +vt 0.929372 0.224433 +vt 0.942787 0.227016 +vt 0.954848 0.237908 +vt 0.922857 0.256527 +vt 0.927955 0.258098 +vt 0.925166 0.269641 +vt 0.929776 0.270263 +vt 0.933130 0.259066 +vt 0.935431 0.270899 +vt 0.945703 0.257403 +vt 0.938091 0.256867 +vt 0.953024 0.257866 +vt 0.948714 0.269472 +vt 0.957575 0.269677 +vt 0.940805 0.269454 +vt 0.944953 0.253898 +vt 0.950208 0.269278 +vt 0.957956 0.256418 +vt 0.964661 0.269455 +vt 0.961307 0.253711 +vt 0.968960 0.268209 +vt 0.902892 0.249987 +vt 0.897745 0.228849 +vt 0.908596 0.231834 +vt 0.912735 0.252197 +vt 0.894850 0.221810 +vt 0.906240 0.226903 +vt 0.897122 0.224227 +vt 0.908607 0.228742 +vt 0.903082 0.242361 +vt 0.906809 0.256103 +vt 0.919494 0.264606 +vt 0.908311 0.265315 +vt 0.917237 0.255133 +vt 0.907454 0.269025 +vt 0.916487 0.269043 +vt 0.911531 0.283044 +vt 0.919593 0.282900 +vt 0.909419 0.273405 +vt 0.911476 0.283360 +vt 0.920571 0.273041 +vt 0.922157 0.283218 +vt 0.922114 0.255039 +vt 0.920062 0.238863 +vt 0.921052 0.234472 +vt 0.923775 0.235380 +vt 0.934895 0.263753 +vt 0.929369 0.253983 +vt 0.927988 0.282737 +vt 0.937386 0.272947 +vt 0.938515 0.283177 +vt 0.905634 0.254510 +vt 0.912156 0.254648 +vt 0.906903 0.269654 +vt 0.915624 0.269303 +vt 0.934262 0.269581 +vt 0.931993 0.256855 +vt 0.928513 0.249010 +vt 0.928512 0.223212 +vt 0.917128 0.220406 +vt 0.916725 0.220767 +vt 0.904100 0.217973 +vt 0.914088 0.228391 +vt 0.916363 0.246441 +vt 0.918617 0.232270 +vt 0.923487 0.240784 +vt 0.938248 0.227770 +vt 0.892821 0.216321 +vt 0.844542 0.206031 +vt 0.874322 0.212263 +vt 0.864795 0.285932 +vt 0.870581 0.286403 +vt 0.877377 0.285736 +vt 0.887924 0.285532 +vt 0.898823 0.285311 +vt 0.908672 0.285115 +vt 0.917425 0.284957 +vt 0.921216 0.269224 +vt 0.922914 0.284906 +vt 0.926665 0.284912 +vt 0.930758 0.284928 +vt 0.936388 0.284960 +vt 0.952837 0.284936 +vt 0.967867 0.284724 +vt 0.971593 0.266723 +vt 0.976556 0.284338 +vt 0.976161 0.284497 +vt 0.973686 0.284223 +vt 0.968029 0.284169 +vt 0.960033 0.284154 +vt 0.950775 0.284138 +vt 0.942494 0.284121 +vt 0.936182 0.284123 +vt 0.929809 0.284158 +vt 0.920968 0.284223 +vt 0.910111 0.284292 +vt 0.952943 0.272204 +vt 0.950019 0.262148 +vt 0.953976 0.282879 +vt 0.900909 0.229617 +vt 0.889642 0.217102 +vt 0.912068 0.234085 +vt 0.913562 0.243735 +vt 0.925227 0.239763 +vt 0.923110 0.245509 +vt 0.916786 0.225007 +vt 0.940372 0.249840 +vt 0.963568 0.250138 +vt 0.888081 0.264217 +vt 0.918118 0.254988 +vt 0.953969 0.514386 +vt 0.955477 0.513065 +vt 0.954272 0.512902 +vt 0.955509 0.511632 +vt 0.956562 0.510151 +vt 0.957528 0.506237 +vt 0.957401 0.500104 +vt 0.957541 0.505830 +vt 0.957323 0.498901 +vt 0.956684 0.496896 +vt 0.956425 0.492794 +vt 0.955922 0.489330 +vt 0.956413 0.492938 +vt 0.955605 0.489791 +vt 0.954030 0.483685 +vt 0.955302 0.484788 +vt 0.952251 0.480529 +vt 0.844126 0.209259 +vt 0.844951 0.221286 +vt 0.955335 0.486204 +vt 0.955539 0.486154 +vt 0.954877 0.485325 +vt 0.956687 0.508947 +vt 0.956754 0.495687 +vt 0.955045 0.487387 +vt 0.886769 0.216308 +vt 0.872985 0.215718 +vt 0.877848 0.505182 +vt 0.877652 0.500582 +vt 0.877370 0.504506 +vt 0.877412 0.500243 +vt 0.876974 0.503437 +vt 0.877218 0.499703 +vt 0.876680 0.502023 +vt 0.877063 0.498994 +vt 0.876501 0.500330 +vt 0.876979 0.498142 +vt 0.876446 0.498438 +vt 0.876960 0.497191 +vt 0.876522 0.496436 +vt 0.877006 0.496186 +vt 0.876728 0.494420 +vt 0.877115 0.495174 +vt 0.877281 0.494204 +vt 0.877054 0.492488 +vt 0.877498 0.493320 +vt 0.877479 0.490730 +vt 0.877999 0.489197 +vt 0.877767 0.492546 +vt 0.878719 0.487808 +vt 0.878144 0.491879 +vt 0.879235 0.487423 +vt 0.878402 0.491725 +vt 0.878643 0.509686 +vt 0.877934 0.508686 +vt 0.877348 0.507101 +vt 0.876912 0.505005 +vt 0.876647 0.502497 +vt 0.876565 0.499694 +vt 0.876669 0.496727 +vt 0.876956 0.493734 +vt 0.877416 0.490859 +vt 0.878045 0.488251 +vt 0.878803 0.485988 +vt 0.879891 0.483890 +vt 0.880652 0.483253 +vt 0.880004 0.514038 +vt 0.879075 0.512727 +vt 0.878307 0.510649 +vt 0.877736 0.507903 +vt 0.877388 0.504616 +vt 0.877280 0.500942 +vt 0.877417 0.497054 +vt 0.877793 0.493132 +vt 0.878389 0.489360 +vt 0.879214 0.485947 +vt 0.880199 0.482989 +vt 0.881623 0.480314 +vt 0.882641 0.479405 +vt 0.881911 0.518172 +vt 0.880775 0.516569 +vt 0.879836 0.514030 +vt 0.879138 0.510673 +vt 0.878713 0.506655 +vt 0.878582 0.502165 +vt 0.878749 0.497412 +vt 0.879208 0.492618 +vt 0.879955 0.488021 +vt 0.881001 0.483899 +vt 0.882310 0.480367 +vt 0.883909 0.477310 +vt 0.885135 0.475926 +vt 0.884336 0.522030 +vt 0.883011 0.520159 +vt 0.881915 0.517195 +vt 0.881100 0.513276 +vt 0.880604 0.508586 +vt 0.880450 0.503344 +vt 0.880646 0.497795 +vt 0.881181 0.492199 +vt 0.882059 0.486840 +vt 0.883257 0.482017 +vt 0.884772 0.477872 +vt 0.886828 0.474331 +vt 0.888116 0.472377 +vt 0.887245 0.525554 +vt 0.885749 0.523442 +vt 0.884512 0.520096 +vt 0.883592 0.515673 +vt 0.883032 0.510379 +vt 0.882858 0.504462 +vt 0.883079 0.498199 +vt 0.883683 0.491882 +vt 0.884656 0.485819 +vt 0.885976 0.480334 +vt 0.887771 0.475644 +vt 0.888962 0.472096 +vt 0.890594 0.528694 +vt 0.888949 0.526372 +vt 0.887589 0.522693 +vt 0.886578 0.517830 +vt 0.885962 0.512009 +vt 0.885771 0.505504 +vt 0.886014 0.498617 +vt 0.886678 0.491672 +vt 0.887734 0.484992 +vt 0.889161 0.478945 +vt 0.891005 0.474124 +vt 0.894335 0.531403 +vt 0.892565 0.528905 +vt 0.891102 0.524947 +vt 0.890014 0.519714 +vt 0.889351 0.513452 +vt 0.889146 0.506453 +vt 0.889407 0.499043 +vt 0.890122 0.491571 +vt 0.891258 0.484384 +vt 0.892815 0.477978 +vt 0.894695 0.473363 +vt 0.898413 0.533643 +vt 0.896544 0.531004 +vt 0.894999 0.526825 +vt 0.893850 0.521300 +vt 0.893151 0.514687 +vt 0.892934 0.507295 +vt 0.893209 0.499472 +vt 0.893965 0.491581 +vt 0.895164 0.483992 +vt 0.896860 0.477387 +vt 0.898865 0.473076 +vt 0.902769 0.535380 +vt 0.900829 0.532640 +vt 0.899224 0.528300 +vt 0.898031 0.522562 +vt 0.897305 0.515695 +vt 0.897079 0.508020 +vt 0.897366 0.499895 +vt 0.898150 0.491701 +vt 0.899396 0.483821 +vt 0.901449 0.477074 +vt 0.903819 0.472976 +vt 0.909699 0.536920 +vt 0.907707 0.534109 +vt 0.906061 0.529655 +vt 0.904836 0.523767 +vt 0.904091 0.516721 +vt 0.903860 0.508844 +vt 0.904153 0.500507 +vt 0.904958 0.492099 +vt 0.906237 0.484012 +vt 0.908008 0.477129 +vt 0.910034 0.473198 +vt 0.916854 0.537360 +vt 0.914870 0.534559 +vt 0.913230 0.530122 +vt 0.914164 0.524465 +vt 0.913164 0.518196 +vt 0.913437 0.511340 +vt 0.911330 0.501080 +vt 0.912131 0.492703 +vt 0.913405 0.484646 +vt 0.915130 0.477830 +vt 0.916994 0.473623 +vt 0.921660 0.536911 +vt 0.919719 0.534172 +vt 0.919170 0.529284 +vt 0.917172 0.505296 +vt 0.919838 0.496406 +vt 0.920904 0.486229 +vt 0.922380 0.479225 +vt 0.924263 0.474614 +vt 0.926405 0.535913 +vt 0.924828 0.532245 +vt 0.931019 0.534378 +vt 0.929686 0.531880 +vt 0.927970 0.487724 +vt 0.927599 0.495894 +vt 0.929366 0.480734 +vt 0.931925 0.475167 +vt 0.935435 0.532330 +vt 0.934387 0.530379 +vt 0.933232 0.488977 +vt 0.932764 0.496065 +vt 0.934736 0.482159 +vt 0.937602 0.476887 +vt 0.939590 0.529799 +vt 0.938848 0.527798 +vt 0.937731 0.490249 +vt 0.936964 0.496523 +vt 0.939215 0.484123 +vt 0.942421 0.479379 +vt 0.943421 0.526821 +vt 0.942722 0.524593 +vt 0.942329 0.491435 +vt 0.942070 0.497013 +vt 0.943599 0.487511 +vt 0.946933 0.482758 +vt 0.945342 0.476815 +vt 0.949756 0.480976 +vt 0.940652 0.473783 +vt 0.947564 0.521395 +vt 0.946600 0.520277 +vt 0.949518 0.517928 +vt 0.951324 0.514898 +vt 0.699423 0.809253 +vt 0.710111 0.860044 +vt 0.767468 0.814720 +vt 0.769921 0.858800 +vt 0.669688 0.860514 +vt 0.651885 0.801109 +vt 0.732293 0.902975 +vt 0.706453 0.911484 +vt 0.776292 0.895678 +vt 0.708787 0.707777 +vt 0.699329 0.757062 +vt 0.772602 0.721954 +vt 0.768846 0.767772 +vt 0.650433 0.740512 +vt 0.664887 0.686395 +vt 0.747107 0.630497 +vt 0.725753 0.664868 +vt 0.781693 0.646160 +vt 0.777288 0.680400 +vt 0.692228 0.642648 +vt 0.725318 0.609127 +vt 0.770358 0.607692 +vt 0.782072 0.622983 +vt 0.800560 0.599400 +vt 0.800562 0.614675 +vt 0.761234 0.587309 +vt 0.800928 0.579073 +vt 0.861399 0.630223 +vt 0.884300 0.609231 +vt 0.833192 0.607478 +vt 0.843136 0.586725 +vt 0.821200 0.622722 +vt 0.826645 0.645961 +vt 0.884907 0.665900 +vt 0.835069 0.680418 +vt 0.901226 0.710448 +vt 0.840872 0.722297 +vt 0.945964 0.693526 +vt 0.920299 0.645594 +vt 0.908209 0.760544 +vt 0.842467 0.768423 +vt 0.905039 0.812825 +vt 0.840209 0.815454 +vt 0.952947 0.809219 +vt 0.957487 0.749588 +vt 0.893705 0.861459 +vt 0.836187 0.859175 +vt 0.876198 0.901993 +vt 0.832541 0.895317 +vt 0.904659 0.909742 +vt 0.934213 0.864462 +vt 0.850482 0.929308 +vt 0.832833 0.919627 +vt 0.810883 0.940213 +vt 0.808275 0.929049 +vt 0.815494 0.955807 +vt 0.865735 0.940277 +vt 0.767163 0.931342 +vt 0.781069 0.920572 +vt 0.757688 0.947696 +vt 0.926885 0.512910 +vt 0.927854 0.512845 +vt 0.928377 0.510114 +vt 0.929178 0.510430 +vt 0.931406 0.509225 +vt 0.930823 0.508639 +vt 0.929980 0.510746 +vt 0.930534 0.523359 +vt 0.930891 0.521821 +vt 0.928350 0.521984 +vt 0.928964 0.520607 +vt 0.928441 0.517467 +vt 0.927597 0.518520 +vt 0.929579 0.519229 +vt 0.926753 0.519573 +vt 0.926179 0.516255 +vt 0.927195 0.515710 +vt 0.928823 0.512781 +vt 0.928211 0.515165 +vt 0.932374 0.506682 +vt 0.930239 0.508053 +vt 0.932657 0.507439 +vt 0.934517 0.507536 +vt 0.934510 0.506707 +vt 0.932940 0.508196 +vt 0.934502 0.505878 +vt 0.936567 0.505592 +vt 0.936317 0.506456 +vt 0.936067 0.507320 +vt 0.937546 0.507578 +vt 0.938070 0.506748 +vt 0.938901 0.508422 +vt 0.940036 0.509880 +vt 0.939772 0.507879 +vt 0.941088 0.509726 +vt 0.940713 0.507314 +vt 0.938594 0.505926 +vt 0.942911 0.511998 +vt 0.942269 0.509491 +vt 0.941755 0.511888 +vt 0.940774 0.511818 +vt 0.940867 0.513981 +vt 0.941724 0.514237 +vt 0.941696 0.517149 +vt 0.942674 0.514592 +vt 0.940898 0.516619 +vt 0.940099 0.516090 +vt 0.938667 0.517973 +vt 0.939267 0.518807 +vt 0.937547 0.521739 +vt 0.939868 0.519641 +vt 0.937153 0.520570 +vt 0.936759 0.519402 +vt 0.934851 0.520311 +vt 0.935057 0.521760 +vt 0.932933 0.523788 +vt 0.935263 0.523209 +vt 0.932985 0.522196 +vt 0.933038 0.520604 +vt 0.931248 0.520284 +vt 0.715065 0.592710 +vt 0.678001 0.627321 +vt 0.647916 0.672373 +vt 0.628526 0.797321 +vt 0.648988 0.865355 +vt 0.693916 0.922274 +vt 0.627590 0.729278 +vt 0.801508 0.561342 +vt 0.756457 0.570463 +vt 0.753635 0.961316 +vt 0.820182 0.969676 +vt 0.896636 0.591965 +vt 0.849136 0.568460 +vt 0.878160 0.953598 +vt 0.925000 0.920764 +vt 0.970242 0.681277 +vt 0.939570 0.629718 +vt 0.961861 0.871181 +vt 0.978343 0.807461 +vt 0.983064 0.742705 +vt 0.932573 0.508007 +vt 0.934161 0.507367 +vt 0.930964 0.509008 +vt 0.927841 0.514787 +vt 0.928411 0.512543 +vt 0.928106 0.516928 +vt 0.929515 0.510546 +vt 0.935671 0.507169 +vt 0.937081 0.507438 +vt 0.929093 0.518640 +vt 0.930710 0.519671 +vt 0.938351 0.508298 +vt 0.939400 0.509723 +vt 0.932552 0.520045 +vt 0.934434 0.519715 +vt 0.940079 0.511519 +vt 0.940113 0.513519 +vt 0.936336 0.518792 +vt 0.938116 0.517377 +vt 0.939405 0.515521 +vt 0.943638 0.508965 +vt 0.941943 0.506311 +vt 0.939071 0.504531 +vt 0.943880 0.515430 +vt 0.944335 0.512165 +vt 0.927944 0.506963 +vt 0.925069 0.509715 +vt 0.923231 0.513349 +vt 0.935271 0.526189 +vt 0.938229 0.524222 +vt 0.940839 0.521447 +vt 0.923484 0.521848 +vt 0.925731 0.524779 +vt 0.928789 0.526502 +vt 0.922597 0.517761 +vt 0.933960 0.504385 +vt 0.931029 0.505302 +vt 0.936534 0.504088 +vt 0.942769 0.518413 +vt 0.932116 0.527039 +vt 0.945351 0.507568 +vt 0.943089 0.503744 +vt 0.939896 0.502018 +vt 0.946118 0.511811 +vt 0.945354 0.516015 +vt 0.925289 0.504712 +vt 0.920962 0.508150 +vt 0.918385 0.512520 +vt 0.938552 0.526478 +vt 0.934537 0.528948 +vt 0.941809 0.523283 +vt 0.921702 0.527196 +vt 0.918305 0.523665 +vt 0.925959 0.529352 +vt 0.917212 0.518867 +vt 0.933078 0.501722 +vt 0.929349 0.502508 +vt 0.936447 0.501609 +vt 0.943896 0.519878 +vt 0.930309 0.529931 +vt 0.948005 0.505607 +vt 0.944871 0.499392 +vt 0.947806 0.516062 +vt 0.949100 0.511191 +vt 0.879346 0.309871 +vt 0.875833 0.306046 +vt 0.875654 0.308144 +vt 0.879007 0.306407 +vt 0.876295 0.294136 +vt 0.878977 0.293033 +vt 0.876175 0.301094 +vt 0.879812 0.300399 +vt 0.882198 0.297454 +vt 0.880254 0.303450 +vt 0.893175 0.297687 +vt 0.859181 0.350621 +vt 0.872916 0.327332 +vt 0.865817 0.349629 +vt 0.880252 0.326495 +vt 0.865713 0.330422 +vt 0.852822 0.359205 +vt 0.877097 0.301439 +vt 0.864055 0.301093 +vt 0.869257 0.322943 +vt 0.852819 0.327816 +vt 0.872679 0.316230 +vt 0.866118 0.317194 +vt 0.865658 0.301152 +vt 0.871305 0.301562 +vt 0.879516 0.300927 +vt 0.881998 0.315802 +vt 0.878301 0.348969 +vt 0.888479 0.326114 +vt 0.888262 0.347411 +vt 0.897047 0.325511 +vt 0.857019 0.363938 +vt 0.860381 0.359999 +vt 0.872015 0.364197 +vt 0.874655 0.358691 +vt 0.888629 0.355800 +vt 0.886097 0.359632 +vt 0.872907 0.361011 +vt 0.858128 0.362290 +vt 0.881706 0.320824 +vt 0.875903 0.346079 +vt 0.862423 0.349295 +vt 0.893556 0.318638 +vt 0.888714 0.341972 +vt 0.887564 0.300041 +vt 0.898554 0.296744 +vt 0.888147 0.300674 +vt 0.898715 0.300283 +vt 0.890480 0.315686 +vt 0.898830 0.315390 +vt 0.894383 0.353795 +vt 0.894065 0.354129 +vt 0.890921 0.356254 +vt 0.952900 0.304272 +vt 0.949521 0.305533 +vt 0.942171 0.318343 +vt 0.937705 0.320863 +vt 0.937122 0.307590 +vt 0.931259 0.318903 +vt 0.955735 0.293528 +vt 0.951772 0.293299 +vt 0.940544 0.294181 +vt 0.964624 0.302435 +vt 0.972337 0.302695 +vt 0.957594 0.320997 +vt 0.965634 0.321964 +vt 0.957663 0.333351 +vt 0.950951 0.332759 +vt 0.904388 0.314564 +vt 0.887892 0.312338 +vt 0.897685 0.323309 +vt 0.888936 0.316243 +vt 0.878641 0.308129 +vt 0.895710 0.326063 +vt 0.896265 0.333541 +vt 0.887647 0.308911 +vt 0.896958 0.311973 +vt 0.897963 0.301935 +vt 0.887703 0.301029 +vt 0.898883 0.293285 +vt 0.887878 0.292930 +vt 0.896731 0.344468 +vt 0.905567 0.324686 +vt 0.906991 0.342485 +vt 0.911791 0.324251 +vt 0.900908 0.335596 +vt 0.911043 0.336295 +vt 0.907054 0.325968 +vt 0.917143 0.326675 +vt 0.923285 0.318080 +vt 0.915184 0.316034 +vt 0.908088 0.344187 +vt 0.897103 0.344536 +vt 0.895142 0.343144 +vt 0.894607 0.344154 +vt 0.898106 0.350443 +vt 0.907260 0.349181 +vt 0.907871 0.308374 +vt 0.918398 0.309598 +vt 0.927049 0.310818 +vt 0.928305 0.298442 +vt 0.920004 0.298182 +vt 0.909927 0.298243 +vt 0.929162 0.318872 +vt 0.933826 0.332572 +vt 0.924036 0.321254 +vt 0.925629 0.337191 +vt 0.941158 0.325550 +vt 0.933051 0.316658 +vt 0.943727 0.330971 +vt 0.955075 0.325269 +vt 0.943791 0.324629 +vt 0.952983 0.320359 +vt 0.951332 0.316568 +vt 0.945126 0.317960 +vt 0.937248 0.318798 +vt 0.934373 0.326359 +vt 0.932584 0.333273 +vt 0.932192 0.339300 +vt 0.932318 0.343421 +vt 0.944776 0.336887 +vt 0.945607 0.340893 +vt 0.957129 0.330060 +vt 0.924262 0.313255 +vt 0.925922 0.300164 +vt 0.929283 0.311724 +vt 0.930502 0.299579 +vt 0.936126 0.298969 +vt 0.934410 0.310774 +vt 0.939442 0.311396 +vt 0.947027 0.310849 +vt 0.954323 0.310334 +vt 0.958291 0.298597 +vt 0.949440 0.298819 +vt 0.941532 0.298832 +vt 0.946483 0.315703 +vt 0.950981 0.300512 +vt 0.969751 0.300159 +vt 0.965388 0.298807 +vt 0.962811 0.314479 +vt 0.959326 0.311738 +vt 0.904541 0.316598 +vt 0.900452 0.338160 +vt 0.914268 0.314088 +vt 0.911146 0.334819 +vt 0.910827 0.338483 +vt 0.909045 0.340214 +vt 0.900043 0.343367 +vt 0.897918 0.345703 +vt 0.905082 0.324826 +vt 0.907714 0.311836 +vt 0.909052 0.301920 +vt 0.918749 0.311513 +vt 0.920236 0.301846 +vt 0.908155 0.297332 +vt 0.917180 0.297035 +vt 0.909931 0.293440 +vt 0.920410 0.293444 +vt 0.923496 0.310879 +vt 0.922253 0.327378 +vt 0.923469 0.332076 +vt 0.925923 0.331262 +vt 0.930583 0.312153 +vt 0.934974 0.302503 +vt 0.925817 0.296140 +vt 0.937580 0.293425 +vt 0.916398 0.300537 +vt 0.913653 0.315103 +vt 0.907706 0.300101 +vt 0.907277 0.314776 +vt 0.934984 0.298714 +vt 0.933344 0.311407 +vt 0.930312 0.318902 +vt 0.931529 0.345055 +vt 0.920283 0.347817 +vt 0.919853 0.347075 +vt 0.907379 0.350402 +vt 0.916863 0.340467 +vt 0.918259 0.323025 +vt 0.921166 0.335346 +vt 0.925584 0.327014 +vt 0.941044 0.340685 +vt 0.896265 0.352186 +vt 0.847118 0.363087 +vt 0.877923 0.355511 +vt 0.921992 0.300554 +vt 0.972463 0.301867 +vt 0.953466 0.293583 +vt 0.950828 0.303658 +vt 0.892951 0.350759 +vt 0.903260 0.337983 +vt 0.915596 0.322974 +vt 0.914170 0.333036 +vt 0.927312 0.326701 +vt 0.925040 0.320904 +vt 0.919699 0.342662 +vt 0.941871 0.316003 +vt 0.965254 0.318221 +vt 0.889956 0.306147 +vt 0.919598 0.314755 +vt 0.953215 0.511264 +vt 0.952698 0.512701 +vt 0.951135 0.508840 +vt 0.950868 0.504414 +vt 0.946032 0.497811 +vt 0.950400 0.504692 +vt 0.946155 0.498790 +vt 0.944108 0.496015 +vt 0.945966 0.489086 +vt 0.945497 0.488606 +vt 0.944681 0.492183 +vt 0.944291 0.491984 +vt 0.951345 0.484260 +vt 0.845891 0.359181 +vt 0.847322 0.346695 +vt 0.948386 0.485293 +vt 0.952907 0.485943 +vt 0.952013 0.507755 +vt 0.944606 0.494766 +vt 0.948560 0.486751 +vt 0.890112 0.351330 +vt 0.876360 0.352039 +vt 0.889967 0.448966 +vt 0.878531 0.491695 +vt 0.879572 0.487300 +vt 0.881189 0.483034 +vt 0.883359 0.479059 +vt 0.885970 0.475436 +vt 0.826451 0.427416 +vt 0.889758 0.472115 +vt 0.881748 0.482959 +vt 0.884054 0.478968 +vt 0.886811 0.475429 +vt 0.942835 0.472365 +vt 0.883515 0.397651 +vt 0.925482 0.397634 +vt 0.918562 0.397639 +vt 0.909465 0.397642 +vt 0.901603 0.397646 +vt 0.891034 0.397645 +vt 0.894812 0.397645 +vt 0.931235 0.397655 +vt 0.877003 0.397658 +vt 0.882529 0.397650 +vt 0.871595 0.397671 +vt 0.925845 0.397644 +vt 0.918784 0.397657 +vt 0.909614 0.397666 +vt 0.901249 0.397670 +vt 0.890498 0.397656 +vt 0.929610 0.397643 +vt 0.894099 0.397656 +vt 0.484696 0.402538 +vt 0.483058 0.467543 +vt 0.026409 0.041836 +vt 0.027211 0.115320 +vt 0.027231 0.176259 +vt 0.027041 0.244825 +vt 0.028360 0.327681 +vt 0.035514 0.442488 +vt 0.039161 0.517280 +vt 0.039555 0.560029 +vt 0.486973 0.320445 +vt 0.496033 0.232082 +vt 0.498386 0.171519 +vt 0.166927 0.932027 +vt 0.089131 0.901460 +vt 0.412839 0.954955 +vt 0.280654 0.942250 +vt 0.172265 0.583534 +vt 0.092604 0.643694 +vt 0.048602 0.713913 +vt 0.034269 0.783775 +vt 0.288973 0.537530 +vt 0.047197 0.849027 +vt 0.429574 0.516361 +vt 0.573602 0.514995 +vt 0.720327 0.535205 +vt 0.544365 0.975068 +vt 0.682918 0.980037 +vt 0.412382 0.948959 +vt 0.274953 0.941360 +vt 0.159929 0.926191 +vt 0.078614 0.893197 +vt 0.045546 0.712112 +vt 0.029763 0.775258 +vt 0.174568 0.589926 +vt 0.093871 0.647648 +vt 0.286715 0.542233 +vt 0.039682 0.837587 +vt 0.425296 0.517534 +vt 0.568016 0.514851 +vt 0.715649 0.536695 +vt 0.543555 0.965760 +vt 0.685594 0.967391 +vn -0.000400 -1.000000 -0.001400 +vn -0.000400 -1.000000 -0.001300 +vn 0.000000 -1.000000 -0.000400 +vn 0.000000 -1.000000 -0.004000 +vn 0.000300 -1.000000 0.000800 +vn 0.000300 -1.000000 -0.000300 +vn 0.000100 -1.000000 0.000800 +vn -0.194000 -0.929900 0.312500 +vn -0.063200 -0.992600 0.103800 +vn -0.117200 -0.915600 0.384400 +vn -0.037300 -0.991600 0.123400 +vn -0.093800 -0.992300 0.080500 +vn -0.262900 -0.938400 0.224000 +vn -0.316900 -0.939800 0.127800 +vn -0.110000 -0.992900 0.045800 +vn -0.117300 -0.992800 0.023100 +vn -0.327600 -0.942800 0.061600 +vn 0.217700 -0.817900 0.532600 +vn 0.413800 -0.813000 0.409500 +vn 0.297900 -0.665300 0.684600 +vn 0.570800 -0.636800 0.518400 +vn 0.236100 -0.936600 0.258800 +vn 0.144100 -0.924300 0.353500 +vn -0.311300 -0.816300 0.486500 +vn -0.175900 -0.787800 0.590300 +vn -0.425800 -0.834200 0.350300 +vn -0.408700 -0.662100 0.628100 +vn -0.550800 -0.704300 0.447800 +vn -0.232100 -0.610200 0.757400 +vn -0.492600 -0.847100 0.199400 +vn -0.472800 -0.875100 0.103600 +vn -0.617600 -0.737400 0.273200 +vn -0.581400 -0.799000 0.153500 +vn 0.516400 -0.833100 0.198000 +vn 0.295200 -0.948700 0.113400 +vn 0.693800 -0.665400 0.275600 +vn 0.376500 -0.521100 0.765900 +vn 0.670200 -0.479900 0.566100 +vn 0.480900 -0.384100 0.788200 +vn 0.741900 -0.328600 0.584400 +vn -0.464600 -0.525700 0.712600 +vn -0.285100 -0.453800 0.844300 +vn -0.636100 -0.581100 0.507500 +vn -0.519000 -0.399900 0.755400 +vn -0.698300 -0.469400 0.540300 +vn -0.360900 -0.326600 0.873500 +vn 0.806600 -0.490500 0.329700 +vn 0.875900 -0.318600 0.362300 +vn 0.788200 -0.187900 0.586000 +vn 0.565100 -0.233300 0.791300 +vn 0.615700 -0.088600 0.782900 +vn 0.811400 -0.064800 0.580800 +vn 0.904900 -0.188800 0.381500 +vn 0.913900 -0.068200 0.400100 +vn 0.597100 0.313900 0.738200 +vn 0.637800 0.111300 0.762100 +vn 0.774500 0.284800 0.564800 +vn 0.811500 0.097900 0.576000 +vn 0.904500 0.107900 0.412500 +vn 0.867800 0.275900 0.413200 +vn 0.365300 0.669300 0.647000 +vn 0.501500 0.501700 0.704800 +vn 0.592600 0.584500 0.554200 +vn 0.707600 0.437800 0.554600 +vn 0.819300 0.405300 0.405400 +vn 0.776600 0.481700 0.405900 +vn 0.171300 0.773700 0.609900 +vn 0.260700 0.722500 0.640300 +vn 0.389000 0.714000 0.582000 +vn 0.469100 0.677900 0.566000 +vn 0.690600 0.589400 0.419100 +vn 0.568900 0.702100 0.428200 +vn -0.135100 0.896900 0.421000 +vn -0.122000 0.793800 0.595700 +vn -0.175400 0.902400 0.393400 +vn -0.162400 0.810800 0.562400 +vn -0.183000 0.941100 0.284200 +vn -0.172300 0.888600 0.425000 +vn -0.084700 0.782300 0.617200 +vn -0.125400 0.829300 0.544500 +vn -0.082000 0.762900 0.641200 +vn -0.184500 0.958500 0.217500 +vn -0.010300 0.996000 0.088500 +vn -0.135200 0.956500 0.258400 +vn 0.191300 0.969100 0.155900 +vn -0.142300 0.988200 0.056100 +vn -0.197900 0.966500 0.163500 +vn -0.279400 0.955500 0.094700 +vn -0.269800 0.962600 0.023700 +vn -0.291500 0.938500 0.185000 +vn -0.517800 0.626600 0.582400 +vn -0.135800 0.745000 0.653100 +vn -0.507500 0.783900 0.357600 +vn -0.087800 0.925700 0.367800 +vn 0.322000 0.886200 0.333000 +vn 0.295100 0.710500 0.638800 +vn -0.129600 0.658000 0.741700 +vn 0.228500 0.698500 0.678100 +vn -0.436800 0.561800 0.702500 +vn -0.895700 0.306500 0.322000 +vn -0.768600 0.460800 0.443700 +vn -0.927900 0.310500 0.206000 +vn -0.794500 0.531400 0.293700 +vn -0.652700 0.434900 0.620300 +vn -0.808000 0.277900 0.519500 +vn -0.695700 0.150200 0.702400 +vn -0.526400 0.350000 0.774800 +vn -0.308100 0.511000 0.802500 +vn -0.274300 0.413500 0.868200 +vn -0.397600 0.206000 0.894100 +vn -0.538700 -0.030900 0.841900 +vn -0.714200 -0.185400 0.674900 +vn -0.801400 -0.043100 0.596500 +vn -0.803200 -0.268300 0.531900 +vn -0.868500 -0.183200 0.460500 +vn -0.927000 0.000800 0.375000 +vn -0.878200 0.162900 0.449700 +vn -0.701800 -0.627800 0.336400 +vn -0.697700 -0.690200 0.191700 +vn -0.751000 -0.536800 0.384400 +vn -0.794500 -0.568000 0.214900 +vn -0.066600 -0.244600 0.967300 +vn -0.086600 -0.137600 0.986700 +vn -0.142700 -0.224200 0.964000 +vn -0.174000 -0.119300 0.977500 +vn -0.113300 -0.040200 0.992700 +vn -0.199300 -0.015400 0.979800 +vn -0.588200 -0.287500 0.755900 +vn -0.741500 -0.370400 0.559300 +vn -0.417300 -0.180700 0.890600 +vn -0.806300 -0.427000 0.409200 +vn -0.884800 -0.412700 0.216200 +vn -0.879300 -0.292300 0.375900 +vn -0.944600 -0.254600 0.207000 +vn -0.127100 0.082000 0.988500 +vn -0.126100 0.182700 0.975000 +vn -0.208900 0.092600 0.973500 +vn -0.203200 0.183900 0.961700 +vn -0.081000 0.721300 0.687900 +vn -0.091600 0.665400 0.740800 +vn -0.056100 0.782700 0.619900 +vn -0.055000 0.734600 0.676300 +vn 0.426200 0.872900 0.237300 +vn -0.037800 0.954900 0.294400 +vn -0.066900 0.910400 0.408200 +vn -0.033400 0.867900 0.495600 +vn 0.244900 0.888200 0.388700 +vn 0.688200 0.662200 0.296500 +vn 0.088600 0.778600 0.621100 +vn 0.111500 0.819900 0.561500 +vn 0.249500 0.790100 0.559900 +vn 0.305000 0.771200 0.558700 +vn 0.026200 0.764900 0.643500 +vn 0.010700 0.794300 0.607400 +vn -0.003600 0.792000 0.610600 +vn 0.465800 0.779400 0.418900 +vn 0.388600 0.829500 0.401100 +vn -0.261000 0.915600 0.305600 +vn -0.181200 0.874000 0.450900 +vn 0.205600 0.799600 0.564200 +vn 0.507000 0.673000 0.538400 +vn 0.656100 0.690400 0.304600 +vn -0.944200 -0.157800 0.289000 +vn -0.979900 -0.089700 0.178200 +vn -0.976700 0.025300 0.213200 +vn -0.984700 0.075000 0.157200 +vn -0.042500 0.656100 0.753400 +vn -0.150200 0.627000 0.764300 +vn -0.951700 0.173200 0.253500 +vn -0.968100 0.195400 0.156600 +vn 0.428900 0.797300 0.424700 +vn 0.284700 0.743600 0.604900 +vn 0.639000 0.501100 0.583500 +vn 0.403900 0.436200 0.804100 +vn -0.068800 0.742500 0.666300 +vn -0.241300 0.792800 0.559600 +vn -0.035900 0.829600 0.557200 +vn -0.349800 0.373400 0.859200 +vn -0.087300 0.390100 0.916600 +vn 0.120500 0.696600 0.707200 +vn 0.174400 0.361900 0.915700 +vn -0.375500 0.825800 0.420800 +vn -0.486800 0.829200 0.274600 +vn -0.808000 0.299300 0.507500 +vn -0.596400 0.351300 0.721800 +vn 0.048300 -0.991000 0.124600 +vn 0.079300 -0.992500 0.092800 +vn 0.016200 -0.989700 0.141700 +vn 0.028600 -0.990200 0.136600 +vn 0.045400 -0.904500 0.424000 +vn 0.088500 -0.906300 0.413100 +vn -0.018300 -0.991300 0.129900 +vn -0.054600 -0.908600 0.414000 +vn 0.094800 -0.994800 0.036000 +vn 0.129500 -0.772400 0.621800 +vn 0.064800 -0.760700 0.645900 +vn 0.075900 -0.586800 0.806100 +vn 0.154100 -0.601900 0.783600 +vn -0.084100 -0.756100 0.649000 +vn -0.098600 -0.563400 0.820200 +vn 0.034800 -0.230300 0.972500 +vn 0.040100 -0.143500 0.988800 +vn 0.004000 -0.237100 0.971500 +vn 0.005700 -0.159600 0.987200 +vn 0.060000 -0.046200 0.997100 +vn 0.002200 -0.055900 0.998400 +vn 0.134300 -0.109000 0.984900 +vn 0.154500 -0.007600 0.987900 +vn 0.098300 -0.211200 0.972400 +vn 0.063700 0.064500 0.995900 +vn -0.009900 0.051900 0.998600 +vn -0.025900 0.150900 0.988200 +vn 0.053700 0.182800 0.981700 +vn 0.159500 0.224000 0.961400 +vn 0.165000 0.103100 0.980900 +vn 0.017800 0.323700 0.946000 +vn -0.051900 0.307800 0.950000 +vn -0.088400 0.512700 0.854000 +vn -0.041600 0.538400 0.841600 +vn 0.071200 0.534700 0.842000 +vn 0.140500 0.353300 0.924900 +vn 0.085200 0.734600 0.673100 +vn -0.064200 0.768100 0.637100 +vn 0.194600 0.675400 0.711300 +vn 0.304800 0.507500 0.805900 +vn 0.383100 0.312400 0.869200 +vn 0.408900 0.116200 0.905100 +vn 0.383300 -0.077100 0.920400 +vn 0.322100 -0.235800 0.916800 +vn 0.247300 -0.381100 0.890800 +vn 0.182700 -0.473700 0.861500 +vn 0.080600 -0.488800 0.868600 +vn -0.128500 -0.413700 0.901300 +vn -0.194300 -0.263500 0.944900 +vn -0.294500 -0.126100 0.947300 +vn -0.313200 0.002400 0.949700 +vn -0.265300 0.137800 0.954300 +vn -0.214500 0.320900 0.922500 +vn -0.160100 0.534500 0.829800 +vn -0.101000 0.295600 0.949900 +vn -0.189000 0.298000 0.935600 +vn -0.076100 0.497500 0.864100 +vn -0.131000 0.460400 0.878000 +vn -0.082200 0.765200 0.638500 +vn -0.253100 -0.114400 0.960600 +vn -0.283100 0.017200 0.958900 +vn -0.411600 -0.323700 0.851900 +vn -0.443400 -0.080900 0.892700 +vn -0.402500 -0.269300 0.874900 +vn -0.424300 -0.058900 0.903600 +vn -0.243300 -0.437500 0.865700 +vn -0.268500 -0.460400 0.846100 +vn -0.179000 -0.286100 0.941300 +vn -0.266800 0.132700 0.954600 +vn -0.236600 0.293600 0.926100 +vn -0.450100 0.092800 0.888100 +vn -0.424300 0.301800 0.853700 +vn -0.427000 0.112700 0.897200 +vn -0.393600 0.327200 0.859100 +vn 0.154500 -0.498900 0.852800 +vn 0.062000 -0.533300 0.843600 +vn 0.027100 -0.469500 0.882500 +vn 0.045800 -0.562200 0.825700 +vn 0.117700 -0.466200 0.876800 +vn 0.149800 -0.532400 0.833100 +vn 0.217000 -0.375600 0.901000 +vn 0.245200 -0.419400 0.874100 +vn 0.236600 -0.390400 0.889700 +vn -0.132100 -0.455600 0.880300 +vn -0.121400 -0.464600 0.877100 +vn -0.145700 -0.535400 0.831900 +vn 0.280900 -0.234200 0.930700 +vn 0.274700 -0.206100 0.939200 +vn 0.292700 -0.238600 0.926000 +vn 0.290200 -0.033400 0.956400 +vn 0.308500 -0.057400 0.949500 +vn 0.311500 -0.062500 0.948200 +vn 0.323000 0.118700 0.938900 +vn 0.286400 0.126200 0.949700 +vn 0.310300 0.123600 0.942500 +vn 0.282500 0.298400 0.911600 +vn 0.302500 0.315300 0.899500 +vn 0.308400 0.311200 0.898900 +vn 0.036500 0.813100 0.581000 +vn 0.173700 0.700800 0.691900 +vn -0.008100 0.789600 0.613600 +vn 0.143700 0.690900 0.708400 +vn 0.014600 0.828900 0.559100 +vn 0.166200 0.722600 0.671000 +vn -0.107100 0.800100 0.590200 +vn -0.101500 0.847300 0.521300 +vn -0.077900 0.810600 0.580400 +vn 0.261100 0.510500 0.819300 +vn 0.244100 0.498700 0.831700 +vn 0.264100 0.523800 0.809800 +vn -0.185400 0.488100 0.852800 +vn -0.169100 0.730800 0.661200 +vn -0.147900 0.766500 0.625000 +vn -0.339200 0.538000 0.771600 +vn -0.299200 0.567000 0.767400 +vn -0.080200 0.800300 0.594200 +vn -0.074900 0.840800 0.536100 +vn -0.105800 0.809100 0.578000 +vn -0.114600 0.847700 0.518000 +vn -0.294300 -0.016100 0.955600 +vn -0.244200 -0.161300 0.956200 +vn -0.181600 -0.295600 0.937900 +vn -0.287200 0.232400 0.929200 +vn -0.304300 0.102300 0.947100 +vn 0.067000 -0.332800 0.940600 +vn 0.009800 -0.327400 0.944800 +vn 0.161600 -0.278300 0.946800 +vn -0.087100 -0.342000 0.935600 +vn 0.215600 -0.144600 0.965700 +vn 0.240500 -0.006700 0.970600 +vn 0.245200 0.124700 0.961400 +vn 0.237700 0.264200 0.934700 +vn 0.115300 0.619300 0.776600 +vn -0.036400 0.699700 0.713500 +vn -0.102300 0.673500 0.732000 +vn 0.203500 0.437700 0.875800 +vn -0.235000 0.391900 0.889500 +vn -0.127800 0.553300 0.823100 +vn -0.074900 0.636800 0.767400 +vn -0.102300 0.654000 0.749500 +vn -0.093000 0.507800 0.856400 +vn -0.077200 0.319900 0.944300 +vn -0.064600 0.174600 0.982500 +vn -0.050700 0.063100 0.996700 +vn -0.040700 -0.060800 0.997300 +vn -0.028300 -0.168300 0.985300 +vn -0.024700 -0.248300 0.968400 +vn -0.031700 -0.334000 0.942000 +vn -0.041900 -0.458500 0.887700 +vn -0.047100 -0.541200 0.839500 +vn -0.040800 -0.507300 0.860800 +vn -0.029400 -0.451200 0.891900 +vn -0.010100 -0.553000 0.833100 +vn -0.004500 -0.747200 0.664500 +vn -0.002400 -0.906000 0.423200 +vn -0.002000 -0.990100 0.140500 +vn 0.513900 -0.856200 0.052700 +vn 0.702400 -0.707100 0.081100 +vn 0.305800 -0.951800 0.022200 +vn 0.838000 -0.535900 0.102400 +vn 0.927500 -0.354800 0.117100 +vn 0.966400 -0.224300 0.125500 +vn 0.986400 -0.101600 0.128600 +vn 0.986900 0.073000 0.143500 +vn 0.956400 0.249300 0.151900 +vn 0.899300 0.408300 0.156200 +vn 0.851800 0.501200 0.152200 +vn 0.791500 0.596500 0.132800 +vn 0.702300 0.702700 0.113300 +vn 0.621700 0.774600 0.116100 +vn 0.546000 0.828800 0.122400 +vn 0.516500 0.847100 0.125000 +vn 0.760000 0.633200 0.146200 +vn 0.106800 -0.994300 0.004000 +vn -0.557000 0.817300 0.147000 +vn -0.594900 0.802200 0.050400 +vn -0.923000 0.240600 0.300300 +vn -0.982400 0.131300 0.132700 +vn -0.734200 -0.383500 0.560200 +vn -0.831200 -0.418400 0.366100 +vn -0.839600 -0.509300 0.188700 +vn -0.665500 -0.712300 0.222800 +vn -0.637000 -0.667300 0.385800 +vn -0.554400 -0.632100 0.541400 +vn -0.340600 -0.292300 0.893600 +vn -0.562400 -0.330100 0.758100 +vn -0.443200 -0.613400 0.653600 +vn -0.268400 -0.623100 0.734600 +vn -0.087200 -0.231500 0.968900 +vn -0.094800 -0.633400 0.768000 +vn 0.117000 -0.681100 0.722800 +vn 0.177600 -0.234200 0.955800 +vn 0.370100 -0.688100 0.624100 +vn 0.456000 -0.200400 0.867100 +vn 0.738800 -0.159700 0.654700 +vn 0.587800 -0.657900 0.470800 +vn 0.989100 0.017900 0.146100 +vn 0.769800 -0.613000 0.178000 +vn -0.103300 0.762500 0.638700 +vn -0.110000 -0.993900 0.005200 +vn -0.319300 -0.947500 0.016800 +vn -0.455500 -0.889500 0.035600 +vn -0.590000 -0.806500 0.038700 +vn 0.514000 -0.856000 -0.054500 +vn 0.709500 -0.699500 -0.085000 +vn 0.299400 -0.953800 -0.023600 +vn 0.844800 -0.523500 -0.110800 +vn 0.929300 -0.345000 -0.131500 +vn 0.963600 -0.225700 -0.143500 +vn 0.982100 -0.108600 -0.153700 +vn 0.985700 0.054500 -0.159500 +vn 0.959500 0.234000 -0.156600 +vn 0.899700 0.410000 -0.149400 +vn 0.834800 0.530500 -0.147200 +vn 0.658300 0.735900 -0.158400 +vn 0.742800 0.649300 -0.163500 +vn 0.032900 0.999300 0.014500 +vn 0.056900 0.995200 -0.079200 +vn 0.270300 0.962200 0.032600 +vn 0.341100 0.934200 -0.104400 +vn -0.131200 0.991200 0.012800 +vn -0.130900 0.991000 -0.028900 +vn -0.273000 0.962000 0.005800 +vn -0.272600 0.962000 0.009800 +vn -0.498400 0.866100 0.038800 +vn -0.022200 0.999200 0.033300 +vn -0.062700 0.956300 -0.285600 +vn 0.298700 0.915800 -0.268500 +vn 0.388100 0.921000 0.032600 +vn -0.954800 0.292600 0.051600 +vn -0.818900 0.572100 0.045100 +vn -0.715100 -0.698100 0.034500 +vn -0.815200 -0.574600 -0.072500 +vn -0.820800 -0.570000 0.037500 +vn -0.913600 -0.402100 -0.060100 +vn -0.912300 -0.407800 0.037000 +vn 0.510200 0.857900 0.060800 +vn 0.584500 0.803400 -0.113700 +vn 0.723100 0.686500 0.076200 +vn 0.725100 0.666400 -0.173500 +vn 0.593300 0.788800 -0.160400 +vn 0.511800 0.845100 -0.154500 +vn 0.666000 0.744500 0.046700 +vn 0.600000 0.756900 -0.258900 +vn -0.966100 -0.253200 0.050100 +vn -0.996300 -0.067800 0.051500 +vn -0.994700 0.090500 0.047700 +vn -0.982800 0.178700 0.046400 +vn 0.502200 0.848700 -0.165800 +vn 0.661400 0.715500 -0.224700 +vn -0.644200 0.764700 0.013000 +vn -0.679800 0.733200 0.017100 +vn -0.997100 0.040400 0.063500 +vn -0.999900 0.006000 0.007800 +vn 0.102200 -0.994800 -0.003500 +vn -0.828100 -0.553000 0.092300 +vn -0.826100 -0.563400 0.011000 +vn -0.680000 -0.724600 0.111600 +vn -0.707300 -0.706800 -0.010000 +vn 0.732000 -0.630400 -0.258400 +vn 0.933200 0.182600 -0.309500 +vn -0.190900 -0.921500 -0.338200 +vn -0.115100 -0.904500 -0.410600 +vn -0.054400 -0.992500 -0.109100 +vn -0.031800 -0.991100 -0.129100 +vn -0.278600 -0.931300 -0.234400 +vn -0.089100 -0.992800 -0.079900 +vn -0.310300 -0.941900 -0.128500 +vn -0.115200 -0.992700 -0.034600 +vn -0.310700 -0.948500 -0.060900 +vn -0.114400 -0.993300 -0.017600 +vn 0.554400 -0.640900 -0.531000 +vn 0.397200 -0.818000 -0.416100 +vn 0.299400 -0.659100 -0.689800 +vn 0.222000 -0.813300 -0.537800 +vn 0.236200 -0.932600 -0.272800 +vn 0.154300 -0.917100 -0.367400 +vn -0.181500 -0.749300 -0.636800 +vn -0.305900 -0.793000 -0.526700 +vn -0.433500 -0.822400 -0.368300 +vn -0.545500 -0.692800 -0.471600 +vn -0.395100 -0.638000 -0.660900 +vn -0.217700 -0.573900 -0.789400 +vn -0.473900 -0.852700 -0.219900 +vn -0.463500 -0.879100 -0.111600 +vn -0.594400 -0.785200 -0.173600 +vn -0.599200 -0.739700 -0.306100 +vn 0.293000 -0.947500 -0.127800 +vn 0.506100 -0.835100 -0.215600 +vn 0.687500 -0.665100 -0.291700 +vn 0.724100 -0.323500 -0.609200 +vn 0.658300 -0.468600 -0.589100 +vn 0.474200 -0.367500 -0.800000 +vn 0.378000 -0.497900 -0.780500 +vn -0.249800 -0.427700 -0.868700 +vn -0.449600 -0.515200 -0.729700 +vn -0.615600 -0.581500 -0.531800 +vn -0.670100 -0.479200 -0.566800 +vn -0.502500 -0.403900 -0.764500 +vn -0.313900 -0.317900 -0.894600 +vn 0.802600 -0.487200 -0.344100 +vn 0.871700 -0.317300 -0.373400 +vn 0.769200 -0.185600 -0.611500 +vn 0.552100 -0.226900 -0.802300 +vn 0.790400 -0.071900 -0.608300 +vn 0.600900 -0.078100 -0.795500 +vn 0.898600 -0.191700 -0.394600 +vn 0.905400 -0.090500 -0.414700 +vn 0.561800 0.252000 -0.787900 +vn 0.759100 0.213600 -0.614900 +vn 0.607400 0.082300 -0.790100 +vn 0.786600 0.047000 -0.615600 +vn 0.906200 0.045400 -0.420200 +vn 0.882800 0.215000 -0.417700 +vn 0.334500 0.601200 -0.725700 +vn 0.591200 0.558700 -0.581700 +vn 0.471200 0.428000 -0.771200 +vn 0.692600 0.391400 -0.605900 +vn 0.829000 0.388000 -0.402600 +vn 0.745900 0.540300 -0.389400 +vn 0.137000 0.724600 -0.675300 +vn 0.382900 0.711900 -0.588600 +vn 0.208800 0.692900 -0.690100 +vn 0.486400 0.659500 -0.573000 +vn 0.654600 0.651500 -0.383500 +vn 0.588000 0.714200 -0.379700 +vn -0.133200 0.906900 -0.399600 +vn -0.156600 0.913400 -0.375600 +vn -0.095900 0.805000 -0.585400 +vn -0.137700 0.837200 -0.529200 +vn -0.184100 0.938300 -0.292700 +vn -0.167700 0.886100 -0.432100 +vn -0.119100 0.823900 -0.554000 +vn -0.082900 0.780200 -0.620000 +vn -0.052900 0.759500 -0.648400 +vn 0.082900 0.962800 -0.257000 +vn -0.115500 0.983700 -0.137500 +vn -0.132700 0.956400 -0.260200 +vn -0.179400 0.957300 -0.226600 +vn -0.183100 0.979000 -0.089600 +vn -0.191900 0.964400 -0.181500 +vn -0.283400 0.952800 -0.109000 +vn -0.278600 0.960000 -0.025900 +vn -0.269300 0.936900 -0.223000 +vn -0.476800 0.589400 -0.652100 +vn -0.493000 0.720200 -0.488100 +vn -0.094500 0.700400 -0.707400 +vn -0.071500 0.828100 -0.556000 +vn 0.318200 0.768900 -0.554500 +vn 0.300300 0.682100 -0.666800 +vn 0.221300 0.695100 -0.684000 +vn -0.104800 0.649000 -0.753500 +vn -0.412500 0.552500 -0.724200 +vn -0.895600 0.271200 -0.352700 +vn -0.944600 0.272400 -0.182800 +vn -0.761000 0.410900 -0.501900 +vn -0.807700 0.489900 -0.328000 +vn -0.645700 0.423600 -0.635300 +vn -0.807800 0.257200 -0.530400 +vn -0.692600 0.141300 -0.707300 +vn -0.527400 0.348300 -0.774900 +vn -0.299200 0.521800 -0.798900 +vn -0.248100 0.401700 -0.881500 +vn -0.402600 0.184400 -0.896600 +vn -0.537600 -0.043700 -0.842000 +vn -0.704400 -0.178000 -0.687200 +vn -0.788500 -0.261700 -0.556600 +vn -0.786700 -0.015000 -0.617200 +vn -0.866400 -0.131600 -0.481700 +vn -0.922200 0.053800 -0.382900 +vn -0.881000 0.144800 -0.450300 +vn -0.678900 -0.634800 -0.368900 +vn -0.700600 -0.679500 -0.217700 +vn -0.767800 -0.589200 -0.251800 +vn -0.735500 -0.538500 -0.411200 +vn -0.084900 -0.182700 -0.979500 +vn -0.146300 -0.170900 -0.974300 +vn -0.093500 -0.064900 -0.993500 +vn -0.165900 -0.076900 -0.983100 +vn -0.171100 -0.000800 -0.985200 +vn -0.104700 0.011700 -0.994400 +vn -0.576300 -0.290100 -0.764000 +vn -0.724600 -0.367700 -0.582800 +vn -0.395200 -0.187700 -0.899200 +vn -0.793800 -0.415800 -0.443700 +vn -0.865800 -0.433100 -0.250300 +vn -0.943000 -0.253600 -0.215300 +vn -0.862800 -0.282800 -0.419000 +vn -0.169900 0.156300 -0.973000 +vn -0.090900 0.178400 -0.979700 +vn -0.170600 0.072000 -0.982700 +vn -0.106400 0.095200 -0.989700 +vn -0.061500 0.748500 -0.660200 +vn -0.107700 0.669800 -0.734600 +vn -0.073800 0.781800 -0.619100 +vn -0.103500 0.719700 -0.686500 +vn 0.355000 0.846700 -0.396300 +vn -0.027100 0.948500 -0.315700 +vn -0.094800 0.894000 -0.437900 +vn -0.015700 0.825800 -0.563700 +vn 0.259500 0.863000 -0.433400 +vn 0.596900 0.644800 -0.477300 +vn 0.047600 0.761800 -0.646000 +vn 0.223600 0.806000 -0.548000 +vn 0.090000 0.754200 -0.650400 +vn 0.286000 0.762600 -0.580200 +vn 0.030100 0.723600 -0.689500 +vn 0.002400 0.746500 -0.665400 +vn -0.036300 0.789500 -0.612600 +vn 0.495400 0.782200 -0.377800 +vn 0.390500 0.851100 -0.350700 +vn -0.228700 0.902000 -0.366100 +vn -0.157100 0.847900 -0.506300 +vn 0.231800 0.783700 -0.576300 +vn 0.484200 0.673800 -0.558100 +vn 0.594000 0.607200 -0.527700 +vn -0.940500 -0.129800 -0.313900 +vn -0.981300 -0.083400 -0.173300 +vn -0.984600 0.074600 -0.158200 +vn -0.964100 0.057100 -0.259100 +vn -0.035200 0.660200 -0.750200 +vn -0.115500 0.592500 -0.797200 +vn -0.944600 0.161400 -0.285700 +vn -0.973000 0.167500 -0.158800 +vn 0.380400 0.856000 -0.349900 +vn 0.226900 0.811200 -0.539000 +vn 0.345700 0.611300 -0.711800 +vn 0.578300 0.657500 -0.483000 +vn -0.230100 0.778600 -0.583800 +vn -0.065200 0.797400 -0.599800 +vn -0.089100 0.715800 -0.692500 +vn -0.334700 0.464500 -0.819800 +vn -0.113500 0.421000 -0.899900 +vn 0.119600 0.483500 -0.867100 +vn 0.077400 0.727300 -0.681900 +vn -0.356100 0.827800 -0.433400 +vn -0.446300 0.846500 -0.290100 +vn -0.748300 0.428700 -0.506200 +vn -0.555900 0.481700 -0.677400 +vn 0.078800 -0.991800 -0.100500 +vn 0.055900 -0.989700 -0.131700 +vn 0.012900 -0.989700 -0.142400 +vn 0.039500 -0.899500 -0.435100 +vn 0.034600 -0.988500 -0.147300 +vn 0.100700 -0.899000 -0.426200 +vn -0.055500 -0.896200 -0.440100 +vn -0.016100 -0.989700 -0.141900 +vn 0.096700 -0.994400 -0.042500 +vn 0.057800 -0.749400 -0.659500 +vn 0.140300 -0.765600 -0.627900 +vn 0.070600 -0.589000 -0.805000 +vn 0.167600 -0.602800 -0.780100 +vn -0.087300 -0.733100 -0.674500 +vn -0.114900 -0.537300 -0.835500 +vn 0.010900 -0.235500 -0.971800 +vn -0.033800 -0.212500 -0.976600 +vn 0.000100 -0.093400 -0.995600 +vn -0.044600 -0.099900 -0.994000 +vn -0.050900 0.009100 -0.998700 +vn 0.002700 0.016800 -0.999800 +vn 0.124200 0.012900 -0.992200 +vn 0.118700 -0.105900 -0.987200 +vn 0.097400 -0.229400 -0.968400 +vn -0.002700 0.135400 -0.990800 +vn -0.057600 0.122900 -0.990700 +vn -0.057700 0.236700 -0.969800 +vn -0.012500 0.262500 -0.964800 +vn 0.084400 0.301900 -0.949600 +vn 0.117300 0.157900 -0.980400 +vn -0.030900 0.372000 -0.927700 +vn -0.059900 0.358000 -0.931800 +vn -0.069300 0.479000 -0.875100 +vn -0.054100 0.486200 -0.872100 +vn 0.017200 0.486500 -0.873500 +vn 0.053900 0.398100 -0.915800 +vn -0.034100 0.764000 -0.644300 +vn 0.074100 0.734000 -0.675000 +vn 0.177600 0.641100 -0.746500 +vn 0.291000 0.460500 -0.838600 +vn 0.383800 0.283200 -0.878900 +vn 0.429700 0.107800 -0.896500 +vn 0.413100 -0.065900 -0.908300 +vn 0.347500 -0.229100 -0.909200 +vn 0.268700 -0.369700 -0.889400 +vn 0.077600 -0.503500 -0.860500 +vn 0.197000 -0.468600 -0.861100 +vn -0.157900 -0.415100 -0.895900 +vn -0.218600 -0.296000 -0.929800 +vn -0.279000 -0.156500 -0.947400 +vn -0.305000 -0.025200 -0.952000 +vn -0.191800 0.298600 -0.934900 +vn -0.252300 0.110200 -0.961300 +vn -0.166600 0.519300 -0.838100 +vn -0.147400 0.295400 -0.943900 +vn -0.063300 0.307300 -0.949500 +vn -0.049700 0.461900 -0.885500 +vn -0.088700 0.448900 -0.889200 +vn -0.063700 0.746500 -0.662300 +vn -0.287600 -0.024500 -0.957400 +vn -0.280800 -0.193000 -0.940100 +vn -0.307600 -0.250600 -0.917900 +vn -0.329000 -0.258900 -0.908100 +vn -0.352900 -0.096700 -0.930600 +vn -0.372600 -0.083600 -0.924200 +vn -0.246700 -0.374800 -0.893700 +vn -0.258200 -0.402900 -0.878000 +vn -0.237700 -0.351700 -0.905400 +vn -0.216100 0.267900 -0.938900 +vn -0.245700 0.110000 -0.963000 +vn -0.383900 0.060500 -0.921400 +vn -0.387900 0.085900 -0.917700 +vn -0.407000 0.274100 -0.871300 +vn -0.390000 0.301500 -0.870000 +vn 0.170800 -0.493700 -0.852700 +vn 0.057800 -0.529200 -0.846500 +vn 0.017200 -0.500200 -0.865700 +vn 0.138900 -0.505400 -0.851600 +vn 0.043800 -0.590100 -0.806100 +vn 0.174100 -0.555400 -0.813100 +vn 0.255700 -0.405000 -0.877800 +vn 0.273500 -0.427300 -0.861700 +vn 0.255700 -0.381300 -0.888400 +vn -0.161100 -0.461300 -0.872400 +vn -0.153400 -0.442900 -0.883300 +vn -0.171300 -0.497800 -0.850200 +vn 0.306600 -0.232900 -0.922900 +vn 0.320800 -0.229800 -0.918800 +vn 0.331200 -0.252300 -0.909200 +vn 0.337000 -0.047700 -0.940300 +vn 0.355000 -0.071100 -0.932100 +vn 0.347400 -0.065400 -0.935400 +vn 0.371300 0.118800 -0.920900 +vn 0.328600 0.134100 -0.934900 +vn 0.366900 0.124900 -0.921800 +vn 0.299500 0.336800 -0.892600 +vn 0.347100 0.341100 -0.873600 +vn 0.347500 0.315900 -0.882800 +vn 0.183700 0.718900 -0.670400 +vn 0.052200 0.829400 -0.556200 +vn -0.007100 0.791100 -0.611700 +vn 0.031000 0.869200 -0.493500 +vn 0.122200 0.699200 -0.704400 +vn 0.171100 0.763300 -0.623000 +vn -0.097600 0.794100 -0.599900 +vn -0.091200 0.867500 -0.489000 +vn -0.059800 0.809400 -0.584200 +vn 0.283300 0.522800 -0.803900 +vn 0.234400 0.535400 -0.811400 +vn 0.286500 0.562300 -0.775700 +vn -0.182000 0.470000 -0.863600 +vn -0.165900 0.715100 -0.679000 +vn -0.320200 0.531500 -0.784100 +vn -0.159900 0.763100 -0.626100 +vn -0.302100 0.553900 -0.775800 +vn -0.071600 0.775300 -0.627500 +vn -0.068600 0.831900 -0.550600 +vn -0.089000 0.805100 -0.586300 +vn -0.094200 0.859700 -0.501900 +vn -0.246100 -0.034200 -0.968600 +vn -0.231500 -0.152300 -0.960800 +vn -0.203700 -0.273500 -0.940000 +vn -0.249700 0.201800 -0.947000 +vn -0.255800 0.074500 -0.963800 +vn 0.065200 -0.351600 -0.933900 +vn -0.015300 -0.315400 -0.948800 +vn 0.182700 -0.311300 -0.932600 +vn -0.110900 -0.316800 -0.942000 +vn 0.245100 -0.170400 -0.954400 +vn 0.265700 -0.008300 -0.964000 +vn 0.251300 0.151500 -0.956000 +vn 0.208100 0.317600 -0.925100 +vn 0.067200 0.577300 -0.813700 +vn -0.041400 0.611500 -0.790100 +vn -0.080400 0.593900 -0.800500 +vn 0.143800 0.465000 -0.873500 +vn -0.206700 0.366300 -0.907300 +vn -0.119100 0.526000 -0.842100 +vn -0.058900 0.586900 -0.807500 +vn -0.071100 0.594300 -0.801100 +vn -0.060500 0.473000 -0.879000 +vn -0.058200 0.338600 -0.939100 +vn -0.067400 0.211100 -0.975100 +vn -0.075100 0.105700 -0.991500 +vn -0.075100 0.010900 -0.997100 +vn -0.066700 -0.083700 -0.994200 +vn -0.054900 -0.195500 -0.979200 +vn -0.055800 -0.309700 -0.949200 +vn -0.075700 -0.546700 -0.833900 +vn -0.072500 -0.451600 -0.889300 +vn -0.049100 -0.476000 -0.878000 +vn -0.063000 -0.518200 -0.852900 +vn -0.024200 -0.559500 -0.828500 +vn -0.013500 -0.733100 -0.679900 +vn -0.004800 -0.896000 -0.444000 +vn -0.003800 -0.988500 -0.151300 +vn -0.312000 -0.949900 -0.019800 +vn -0.114800 -0.993300 -0.009500 +vn -0.454900 -0.890000 -0.032200 +vn -0.601200 -0.797100 -0.056000 +vn -0.505200 0.826000 -0.250100 +vn -0.949700 0.299900 -0.089800 +vn -0.812400 0.560400 -0.161000 +vn -0.712500 -0.697800 -0.072500 +vn -0.963900 -0.256600 -0.070600 +vn -0.993900 -0.079800 -0.075900 +vn -0.993500 0.088700 -0.071700 +vn -0.979100 0.191100 -0.069000 +vn -0.588800 0.807600 -0.033800 +vn -0.985200 0.146900 -0.088500 +vn -0.520100 0.840100 -0.154200 +vn -0.897000 0.320100 -0.304800 +vn -0.846300 -0.511600 -0.148200 +vn -0.708600 -0.684200 -0.172200 +vn -0.764600 -0.278900 -0.581000 +vn -0.852700 -0.395700 -0.340900 +vn -0.676300 -0.662100 -0.322700 +vn -0.595100 -0.614900 -0.517400 +vn -0.378500 -0.123600 -0.917300 +vn -0.613000 -0.171900 -0.771100 +vn -0.500600 -0.560100 -0.660000 +vn -0.335100 -0.531000 -0.778300 +vn -0.131800 -0.138000 -0.981600 +vn -0.140600 -0.548900 -0.823900 +vn 0.066100 -0.578300 -0.813100 +vn 0.122500 -0.117700 -0.985400 +vn 0.249800 -0.634900 -0.731100 +vn 0.410400 -0.068300 -0.909300 +vn 0.775700 -0.036300 -0.630000 +vn 0.484800 -0.711500 -0.508600 +vn -0.951600 0.037200 0.305100 +vn -0.930500 0.171500 0.323500 +vn -0.959100 0.039800 0.280300 +vn -0.946000 0.176100 0.272000 +vn -0.943800 0.028900 0.329100 +vn -0.914300 0.155300 0.374000 +vn -0.936200 0.015100 0.350900 +vn -0.898500 0.128000 0.419800 +vn -0.929100 -0.003700 0.369700 +vn -0.883900 0.090100 0.458900 +vn -0.923100 -0.026100 0.383700 +vn -0.871400 0.044300 0.488500 +vn -0.917900 -0.051000 0.393500 +vn -0.861800 -0.010600 0.507100 +vn -0.914100 -0.076800 0.398100 +vn -0.855400 -0.067100 0.513600 +vn -0.912000 -0.105400 0.396400 +vn -0.852000 -0.118700 0.509800 +vn -0.911700 -0.131900 0.389000 +vn -0.852200 -0.171800 0.494200 +vn -0.913200 -0.157800 0.375700 +vn -0.854100 -0.226600 0.468100 +vn -0.916600 -0.180900 0.356500 +vn -0.858600 -0.274300 0.433000 +vn -0.923000 -0.197900 0.329800 +vn -0.873300 -0.306800 0.378400 +vn -0.935000 -0.203900 0.290000 +vn -0.897900 -0.329600 0.291900 +vn -0.930600 -0.202900 0.304700 +vn -0.891400 -0.320300 0.320600 +vn -0.894600 0.293300 0.337100 +vn -0.917600 0.299800 0.260800 +vn -0.870400 0.269500 0.411900 +vn -0.846800 0.229600 0.479700 +vn -0.825000 0.175600 0.537100 +vn -0.806300 0.109800 0.581200 +vn -0.791600 0.035800 0.610000 +vn -0.782600 -0.045500 0.620900 +vn -0.779000 -0.127800 0.613800 +vn -0.779100 -0.209500 0.590700 +vn -0.783100 -0.296700 0.546600 +vn -0.791100 -0.365000 0.490700 +vn -0.808000 -0.407100 0.425900 +vn -0.833700 -0.432400 0.343300 +vn -0.845600 0.407200 0.345000 +vn -0.875500 0.415800 0.245900 +vn -0.814200 0.376200 0.442200 +vn -0.783300 0.324200 0.530300 +vn -0.754800 0.254000 0.604800 +vn -0.730000 0.168900 0.662200 +vn -0.710300 0.073000 0.700100 +vn -0.696500 -0.029300 0.716900 +vn -0.690200 -0.135800 0.710700 +vn -0.692300 -0.245300 0.678500 +vn -0.697200 -0.362800 0.618300 +vn -0.698500 -0.456500 0.551100 +vn -0.718600 -0.514900 0.467400 +vn -0.759900 -0.545100 0.354000 +vn -0.820600 0.524300 0.227300 +vn -0.784300 0.513700 0.347700 +vn -0.746100 0.476000 0.465600 +vn -0.708500 0.412800 0.572300 +vn -0.673800 0.327600 0.662300 +vn -0.643800 0.224300 0.731600 +vn -0.619800 0.107900 0.777300 +vn -0.603100 -0.015900 0.797500 +vn -0.594800 -0.142200 0.791200 +vn -0.595800 -0.273300 0.755200 +vn -0.604600 -0.425200 0.673400 +vn -0.603600 -0.544100 0.582800 +vn -0.613300 -0.612500 0.498600 +vn -0.657200 -0.657300 0.368900 +vn -0.754000 0.623800 0.205500 +vn -0.712000 0.611500 0.345100 +vn -0.667600 0.567600 0.481700 +vn -0.624100 0.494200 0.605200 +vn -0.584000 0.395100 0.709100 +vn -0.549100 0.275400 0.789000 +vn -0.521400 0.140800 0.841600 +vn -0.502100 -0.002500 0.864800 +vn -0.492100 -0.148200 0.857800 +vn -0.492000 -0.299600 0.817400 +vn -0.510200 -0.471800 0.719100 +vn -0.521000 -0.605900 0.601100 +vn -0.544500 -0.669200 0.505600 +vn -0.589500 -0.709600 0.385800 +vn -0.677300 0.713100 0.181000 +vn -0.630100 0.699300 0.337500 +vn -0.580400 0.649900 0.490600 +vn -0.531800 0.567300 0.628800 +vn -0.486800 0.456100 0.745000 +vn -0.447900 0.321800 0.834100 +vn -0.417000 0.171000 0.892700 +vn -0.395500 0.010700 0.918400 +vn -0.384400 -0.152300 0.910500 +vn -0.386000 -0.315400 0.866900 +vn -0.412900 -0.495500 0.764200 +vn -0.467400 -0.628100 0.622200 +vn -0.591800 0.791100 0.154200 +vn -0.540300 0.776100 0.325300 +vn -0.486000 0.722000 0.492400 +vn -0.433000 0.631500 0.643200 +vn -0.384100 0.509700 0.769800 +vn -0.341900 0.363000 0.866800 +vn -0.308300 0.198300 0.930400 +vn -0.285000 0.023500 0.958200 +vn -0.272900 -0.154100 0.949600 +vn -0.272800 -0.330000 0.903700 +vn -0.287300 -0.511700 0.809700 +vn -0.354100 -0.637500 0.684200 +vn -0.499000 0.857400 0.125600 +vn -0.443900 0.841200 0.308600 +vn -0.385900 0.783200 0.487500 +vn -0.329400 0.686200 0.648500 +vn -0.277500 0.555700 0.783700 +vn -0.232600 0.398600 0.887100 +vn -0.197100 0.222600 0.954800 +vn -0.172300 0.035800 0.984400 +vn -0.159400 -0.153800 0.975100 +vn -0.158400 -0.343200 0.925800 +vn -0.175100 -0.525400 0.832600 +vn -0.212500 -0.655200 0.725000 +vn -0.400200 0.911400 0.095500 +vn -0.342200 0.894400 0.287900 +vn -0.281500 0.833200 0.475900 +vn -0.222400 0.731000 0.645100 +vn -0.168200 0.593600 0.787000 +vn -0.121600 0.428400 0.895300 +vn -0.084600 0.243600 0.966200 +vn -0.058800 0.047500 0.997100 +vn -0.046600 -0.151100 0.987400 +vn -0.049300 -0.347200 0.936500 +vn -0.069000 -0.536100 0.841300 +vn -0.098700 -0.673600 0.732400 +vn -0.279000 0.958500 0.059000 +vn -0.218800 0.940700 0.259000 +vn -0.155900 0.877000 0.454400 +vn -0.094900 0.770600 0.630200 +vn -0.039100 0.627600 0.777500 +vn 0.008800 0.455900 0.890000 +vn 0.047900 0.262900 0.963600 +vn 0.077200 0.061300 0.995100 +vn 0.093200 -0.145100 0.985000 +vn 0.083300 -0.346500 0.934300 +vn 0.072400 -0.543000 0.836600 +vn 0.037800 -0.712200 0.700900 +vn -0.135500 0.990600 0.016400 +vn -0.074200 0.972500 0.220600 +vn -0.010200 0.907400 0.420100 +vn 0.051500 0.798500 0.599700 +vn 0.112700 0.651300 0.750400 +vn 0.175300 0.473100 0.863400 +vn 0.226100 0.282400 0.932200 +vn 0.241400 0.070200 0.967900 +vn 0.219300 -0.115600 0.968800 +vn 0.199000 -0.347300 0.916300 +vn 0.214300 -0.544800 0.810700 +vn 0.188800 -0.746400 0.638100 +vn 0.010700 0.999600 -0.026500 +vn 0.071900 0.981500 0.177100 +vn 0.135400 0.916600 0.376200 +vn 0.169600 0.814400 0.554900 +vn 0.201300 0.665800 0.718400 +vn 0.277700 0.458100 0.844400 +vn 0.391200 0.308400 0.867100 +vn 0.373900 0.137400 0.917200 +vn 0.344300 -0.051100 0.937400 +vn 0.332500 -0.338900 0.880100 +vn 0.335900 -0.566700 0.752400 +vn 0.366500 -0.726800 0.580900 +vn 0.139300 0.988200 -0.063800 +vn 0.199100 0.970500 0.135500 +vn 0.226100 0.920000 0.320000 +vn 0.208400 0.827400 0.521400 +vn 0.496200 0.214600 0.841200 +vn 0.541400 0.084200 0.836500 +vn 0.520200 -0.264500 0.812000 +vn 0.477800 -0.572300 0.666400 +vn 0.487000 -0.711400 0.506700 +vn 0.247900 0.964100 -0.094900 +vn 0.291700 0.952500 0.087700 +vn 0.272500 0.912400 0.305500 +vn 0.354100 0.926800 -0.125100 +vn 0.394200 0.918800 0.019700 +vn 0.392200 0.908600 0.143500 +vn 0.692900 -0.219500 0.686800 +vn 0.697800 0.092800 0.710200 +vn 0.617600 -0.535300 0.576200 +vn 0.586700 -0.688800 0.425700 +vn 0.456400 0.876300 -0.153800 +vn 0.491900 0.870100 -0.029300 +vn 0.518100 0.854600 0.034400 +vn 0.821700 0.089200 0.562800 +vn 0.802000 -0.150600 0.578000 +vn 0.739600 -0.458400 0.492800 +vn 0.674400 -0.665000 0.320700 +vn 0.553500 0.813000 -0.180600 +vn 0.587100 0.806500 -0.069000 +vn 0.638200 0.769500 -0.021500 +vn 0.877700 -0.096800 0.469300 +vn 0.861600 0.075600 0.501800 +vn 0.878400 -0.369000 0.303700 +vn 0.809900 -0.551800 0.198900 +vn 0.666200 0.715200 -0.211200 +vn 0.703100 0.702000 -0.112600 +vn 0.768800 0.637400 -0.050900 +vn 0.876000 0.089300 0.474000 +vn 0.920700 -0.156500 0.357500 +vn 0.922700 -0.341500 0.179000 +vn 0.887800 -0.442800 0.125600 +vn 0.720600 -0.689000 0.077900 +vn 0.857400 -0.514500 0.013200 +vn 0.654400 -0.737200 -0.167800 +vn 0.510800 -0.845900 -0.153100 +vn 0.632600 -0.763100 0.132300 +vn 0.779200 0.578600 -0.240900 +vn 0.815200 0.562200 -0.139000 +vn 0.857400 0.510800 -0.061300 +vn 0.805200 0.539600 -0.245900 +vn 0.845400 0.522300 -0.111500 +vn 0.808900 0.532200 -0.249900 +vn 0.878900 0.473600 -0.056900 +vn -0.955000 -0.086900 0.283500 +vn 0.456600 0.344500 0.820200 +vn 0.545400 0.440300 0.713200 +vn 0.408200 0.442300 0.798500 +vn 0.496900 0.511100 0.701300 +vn 0.479300 0.428100 0.766100 +vn 0.487200 0.294900 0.822000 +vn 0.339500 0.553500 0.760500 +vn 0.418100 0.533700 0.735000 +vn 0.449900 0.570000 0.687500 +vn 0.569500 0.085300 0.817500 +vn 0.655400 0.258600 0.709600 +vn 0.504500 0.229700 0.832200 +vn 0.597700 0.365800 0.713300 +vn 0.521300 0.159900 0.838200 +vn 0.593700 0.073900 0.801300 +vn 0.693700 -0.166600 0.700700 +vn 0.744300 -0.043000 0.666400 +vn 0.639600 -0.049000 0.767100 +vn 0.711900 0.101400 0.694800 +vn 0.678900 -0.002400 0.734200 +vn 0.753000 -0.059600 0.655300 +vn 0.820100 -0.241300 0.518800 +vn 0.756600 -0.193800 0.624400 +vn 0.836900 -0.292000 0.462900 +vn 0.754300 -0.262200 0.601900 +vn 0.803200 -0.114100 0.584700 +vn 0.861800 -0.160600 0.481000 +vn 0.911800 -0.175000 0.371400 +vn 0.960700 -0.062900 0.270400 +vn 0.917600 -0.221000 0.330400 +vn 0.957200 -0.011200 0.289100 +vn 0.889100 -0.123300 0.440700 +vn 0.872200 0.060500 0.485400 +vn 0.779900 0.376900 0.499600 +vn 0.841600 0.225800 0.490600 +vn 0.881300 0.378800 0.282500 +vn 0.937300 0.202200 0.283700 +vn 0.965300 0.142600 0.218800 +vn 0.918800 0.347900 0.186500 +vn 0.662400 0.540200 0.519000 +vn 0.719400 0.470900 0.510500 +vn 0.735500 0.603100 0.308600 +vn 0.811500 0.506000 0.292300 +vn 0.849500 0.501900 0.162800 +vn 0.756100 0.631800 0.170800 +vn 0.555100 0.659400 0.506900 +vn 0.601300 0.604300 0.522700 +vn 0.545500 0.770700 0.329300 +vn 0.648800 0.689500 0.321700 +vn 0.648200 0.741000 0.175500 +vn 0.521800 0.822000 0.228100 +vn 0.330100 0.769700 0.546400 +vn 0.487600 0.767600 0.415900 +vn 0.206200 0.848000 0.488200 +vn 0.396400 0.845600 0.357400 +vn 0.371000 0.870100 0.324500 +vn 0.262700 0.828200 0.495000 +vn 0.252100 0.693800 0.674600 +vn 0.327100 0.640900 0.694400 +vn 0.357100 0.670900 0.649800 +vn 0.822600 0.323800 0.467400 +vn 0.782100 0.422000 0.458500 +vn 0.864100 0.372300 0.338700 +vn 0.813600 0.438100 0.382100 +vn 0.591800 0.772100 -0.231400 +vn 0.729800 0.604300 -0.319700 +vn 0.754100 0.521600 0.399000 +vn 0.857600 0.225500 0.462300 +vn 0.855500 0.210600 0.473100 +vn 0.911300 -0.024300 0.411100 +vn 0.940900 -0.012000 0.338300 +vn 0.977800 -0.140400 -0.155200 +vn 0.925200 -0.376200 0.049700 +vn 0.955700 0.087800 0.280700 +vn 0.862000 0.186600 0.471300 +vn 0.853600 0.251000 0.456400 +vn 0.914600 0.275500 0.295900 +vn 0.856100 0.395900 -0.332100 +vn 0.944500 0.141000 -0.296600 +vn 0.706400 0.596800 0.380400 +vn 0.717900 0.599500 0.353700 +vn 0.734300 0.536500 0.415900 +vn 0.432000 0.901800 0.009400 +vn 0.513200 0.850100 -0.118200 +vn 0.717400 0.612100 0.332700 +vn 0.733000 0.586700 0.344200 +vn 0.725800 0.558200 0.402000 +vn 0.692300 0.588300 0.417800 +vn 0.324500 0.923100 0.206100 +vn 0.247500 0.850700 0.463600 +vn 0.635000 0.541500 0.550900 +vn 0.196200 0.680500 0.705900 +vn 0.562500 0.463900 0.684400 +vn 0.238200 0.505100 0.829500 +vn 0.599500 0.381800 0.703400 +vn 0.684700 0.356000 0.635900 +vn 0.691700 0.476200 0.542900 +vn 0.810900 0.351200 0.468000 +vn 0.680100 0.360900 0.638100 +vn 0.764100 0.315300 0.562800 +vn 0.342600 0.382500 0.858100 +vn 0.454800 0.319400 0.831300 +vn 0.728800 0.384400 0.566700 +vn 0.791500 0.430600 0.433500 +vn 0.730100 0.408600 0.547600 +vn 0.812400 0.405500 0.418900 +vn 0.504700 0.266900 0.821000 +vn 0.517000 0.154200 0.841900 +vn 0.708100 0.378200 0.596200 +vn 0.779000 0.301800 0.549600 +vn 0.714300 0.261000 0.649300 +vn 0.767800 0.393000 0.506000 +vn 0.544200 0.000700 0.838900 +vn 0.627400 -0.200000 0.752600 +vn 0.775200 0.105200 0.622900 +vn 0.851000 0.223600 0.475100 +vn 0.851600 0.005000 0.524000 +vn 0.818400 0.245500 0.519500 +vn 0.735100 -0.398100 0.548700 +vn 0.848400 -0.449700 0.279000 +vn 0.641300 0.766100 0.041400 +vn 0.573600 0.802400 0.164700 +vn 0.699100 0.710600 -0.079700 +vn 0.959700 0.232300 -0.158400 +vn 0.893600 0.422900 -0.150400 +vn 0.997200 0.072500 0.020000 +vn 0.809400 0.573600 -0.126000 +vn 0.487400 0.808800 0.329000 +vn 0.428600 0.738600 0.520300 +vn 0.970500 -0.105700 0.216400 +vn 0.886700 -0.079700 0.455300 +vn 0.498400 0.404800 0.766600 +vn 0.435600 0.560900 0.704000 +vn 0.787600 -0.036400 0.615100 +vn 0.688300 0.109700 0.717000 +vn 0.563400 0.346200 0.750100 +vn 0.532900 0.358600 0.766400 +vn 0.636800 0.232100 0.735200 +vn 0.604000 0.264000 0.752000 +vn 0.597000 0.331600 0.730400 +vn 0.864600 0.203500 0.459500 +vn 0.945500 0.154600 0.286600 +vn 0.810100 0.357800 0.464400 +vn 0.934700 0.297400 0.194800 +vn 0.894500 0.406800 0.185300 +vn 0.670400 0.380700 0.636900 +vn 0.716800 0.325200 0.616700 +vn 0.706300 0.286400 0.647400 +vn 0.803400 0.507100 0.311900 +vn 0.753500 0.583700 0.302500 +vn 0.839400 0.452300 0.301300 +vn 0.588100 0.451700 0.670900 +vn 0.570900 0.559700 0.600600 +vn 0.622300 0.614400 0.485100 +vn 0.665800 0.307000 0.680000 +vn 0.795600 0.334300 0.505200 +vn 0.713300 0.347100 0.608800 +vn 0.821000 0.387800 0.419000 +vn 0.865500 0.443200 0.233200 +vn 0.688500 0.622200 0.372500 +vn 0.926100 0.185600 0.328400 +vn 0.973400 0.146300 0.176000 +vn 0.883700 0.185100 0.429900 +vn 0.956700 0.280700 0.077000 +vn 0.918900 0.389300 0.063700 +vn 0.603300 0.229900 0.763600 +vn 0.636200 0.243900 0.731900 +vn 0.505100 0.301000 0.808900 +vn 0.706300 0.704500 0.069600 +vn 0.589300 0.800300 0.110900 +vn 0.826000 0.560900 0.056000 +vn 0.308400 0.738900 0.599100 +vn 0.310300 0.622000 0.718900 +vn 0.365900 0.824300 0.431900 +vn 0.385500 0.421700 0.820600 +vn 0.696100 0.192400 0.691600 +vn 0.772600 0.122400 0.622900 +vn 0.841000 0.130300 0.525100 +vn 0.881100 0.469000 0.061200 +vn 0.475900 0.843300 0.249600 +vn 0.925900 0.295500 0.235200 +vn 0.879100 0.275400 0.389000 +vn 0.936500 0.341000 0.082100 +vn 0.911900 0.410300 0.004800 +vn 0.500100 -0.539800 -0.677100 +vn 0.319700 0.240000 -0.916600 +vn 0.956400 0.181000 -0.229300 +vn 0.283500 0.936500 -0.206500 +vn 0.709400 0.135300 -0.691700 +vn 0.988600 0.020500 -0.149300 +vn 0.612400 0.778600 -0.136800 +vn 0.971100 0.034700 -0.236100 +vn 0.607800 0.771500 -0.187600 +vn 0.538000 0.838900 -0.081700 +vn 0.981700 0.124200 -0.144400 +vn 0.679800 -0.712600 -0.173100 +vn 0.651300 -0.651800 -0.388400 +vn 0.488100 -0.863800 -0.124900 +vn 0.434000 -0.873100 -0.222100 +vn 0.755600 -0.633100 -0.167900 +vn 0.250400 0.746500 0.616500 +vn 0.541500 0.639900 0.545200 +vn 0.101800 0.803300 0.586700 +vn 0.490900 0.702500 0.515200 +vn 0.829700 0.310700 0.463600 +vn 0.896200 0.373100 0.240000 +vn 0.821200 -0.561800 0.099900 +vn 0.633500 -0.772000 0.050600 +vn 0.159400 -0.972900 0.167200 +vn 0.195500 -0.972400 0.127100 +vn 0.169500 -0.985100 -0.028400 +vn 0.570200 -0.810400 -0.134500 +vn 0.396200 0.757700 0.518600 +vn 0.798400 0.556800 0.229100 +vn 0.231300 0.898400 0.373200 +vn 0.712500 0.693000 0.110000 +vn 0.371700 0.862600 0.343200 +vn 0.296600 0.764200 0.572600 +vn 0.167300 0.759100 0.629000 +vn 0.160400 0.759600 0.630300 +vn 0.321600 0.722000 0.612500 +vn 0.194500 0.775700 0.600400 +vn 0.172600 0.138200 0.975200 +vn 0.444000 0.180300 0.877700 +vn 0.237000 0.637400 0.733200 +vn 0.360200 0.627200 0.690600 +vn 0.692500 0.093400 0.715300 +vn 0.580600 0.425500 0.694200 +vn 0.465600 -0.354900 0.810700 +vn 0.122100 -0.409600 0.904000 +vn 0.232500 -0.958000 0.167800 +vn 0.403700 -0.848700 0.341600 +vn 0.079100 -0.846100 0.527100 +vn 0.514500 -0.780300 0.355400 +vn 0.225400 -0.956500 0.184900 +vn 0.234500 -0.966300 0.105600 +vn 0.166700 -0.976700 0.135200 +vn 0.177300 -0.983700 -0.028700 +vn 0.007100 -0.999700 0.021400 +vn 0.363700 0.873500 0.323600 +vn 0.239500 0.798500 0.552200 +vn 0.317600 0.905500 0.281200 +vn 0.220000 0.822200 0.524900 +vn 0.935400 -0.038200 0.351400 +vn 0.986600 -0.095900 0.132100 +vn 0.828900 -0.419800 0.369800 +vn 0.781200 -0.416100 0.465300 +vn 0.776500 -0.575200 0.257000 +vn 0.927600 0.125600 0.351700 +vn 0.996200 0.063500 0.058400 +vn 0.264400 -0.911800 0.314200 +vn 0.413600 -0.822300 0.390700 +vn 0.987200 -0.029400 -0.156400 +vn 0.703500 -0.709800 0.033300 +vn 0.958500 -0.068100 -0.276700 +vn 0.676600 -0.713900 -0.180500 +vn 0.119200 -0.992800 -0.011200 +vn 0.125600 -0.965600 0.227500 +vn 0.408300 0.877600 0.251000 +vn 0.352400 0.757400 0.549600 +vn 0.913800 0.397400 0.084400 +vn 0.903900 0.294300 0.310400 +vn 0.366000 0.562900 0.741100 +vn 0.905900 0.059700 0.419100 +vn 0.518500 0.336500 -0.786000 +vn 0.290600 -0.654800 -0.697600 +vn 0.470800 -0.701200 -0.535400 +vn 0.255300 -0.758000 -0.600200 +vn 0.289700 -0.941400 -0.172900 +vn 0.758800 0.451400 -0.469500 +vn 0.153100 0.939900 -0.305200 +vn 0.141800 0.967100 -0.211100 +vn 0.155600 0.978000 -0.138900 +vn 0.271000 0.955000 -0.120800 +vn 0.103400 0.978700 -0.177000 +vn 0.199100 0.967100 -0.158000 +vn 0.292600 0.950500 -0.104400 +vn 0.203600 0.976500 -0.070900 +vn 0.186000 0.723300 0.665000 +vn -0.083500 0.759600 0.645000 +vn -0.298500 0.717200 0.629700 +vn -0.020700 0.686800 0.726500 +vn 0.540200 -0.819700 -0.190300 +vn 0.303000 -0.849600 -0.431700 +vn 0.361600 -0.914100 -0.183700 +vn 0.317400 -0.833900 -0.451600 +vn 0.264500 -0.753300 -0.602100 +vn 0.324500 -0.723600 -0.609100 +vn 0.713000 -0.681700 0.164100 +vn 0.462000 -0.848500 0.257900 +vn 0.811700 0.583400 0.026200 +vn 0.978500 -0.202000 -0.040800 +vn 0.764900 -0.405900 0.500200 +vn 0.544000 -0.450900 0.707700 +vn 0.352800 -0.784700 -0.509700 +vn 0.288400 -0.800700 -0.525100 +vn 0.400400 -0.763600 -0.506500 +vn 0.397000 -0.900100 -0.179300 +vn 0.452100 -0.878500 -0.154300 +vn 0.353500 -0.914300 -0.197500 +vn -0.137600 0.650000 0.747300 +vn -0.140400 0.677100 0.722300 +vn -0.347100 0.690100 0.635000 +vn -0.346900 0.687800 0.637600 +vn -0.334500 0.700100 0.630800 +vn -0.127600 0.705300 0.697300 +vn 0.678500 -0.680200 -0.277300 +vn 0.599500 -0.703300 -0.382000 +vn 0.769100 -0.583700 -0.260300 +vn 0.657200 -0.647100 -0.386500 +vn 0.446500 -0.679600 -0.582000 +vn 0.478900 -0.674400 -0.562000 +vn 0.415900 -0.693400 -0.588400 +vn 0.544000 -0.738800 -0.397700 +vn 0.635000 -0.732000 -0.246600 +vn 0.754000 -0.649000 0.101200 +vn 0.804200 -0.593200 0.035700 +vn 0.750700 -0.347700 0.561700 +vn 0.822400 -0.175500 0.541100 +vn 0.916200 -0.399100 -0.035200 +vn -0.555400 0.716300 0.422400 +vn -0.554900 0.726200 0.405700 +vn -0.693300 0.692300 0.200000 +vn -0.682600 0.703500 0.197500 +vn -0.431100 0.829100 0.356000 +vn -0.574700 0.784100 0.234200 +vn 0.413400 -0.777500 -0.473900 +vn 0.451900 -0.738900 -0.499900 +vn 0.437800 -0.785900 -0.436700 +vn 0.598700 -0.778700 -0.187400 +vn 0.575000 -0.784000 -0.233900 +vn 0.614600 -0.773300 -0.155400 +vn -0.136600 0.849800 0.509000 +vn -0.214300 0.929600 0.299700 +vn 0.631200 -0.691300 -0.351500 +vn 0.711900 -0.660900 -0.237500 +vn 0.841300 -0.490700 -0.226600 +vn 0.885500 -0.428800 -0.178800 +vn 0.125600 -0.971100 0.203000 +vn 0.408700 -0.747800 0.523100 +vn 0.408000 -0.729100 0.549400 +vn -0.017900 -0.966400 0.256500 +vn 0.828700 -0.214300 0.517000 +vn 0.703800 -0.139500 0.696600 +vn 0.716400 0.543300 0.437700 +vn 0.666200 0.531800 0.522800 +vn 0.158300 0.983700 -0.085600 +vn 0.103500 0.980800 -0.165200 +vn 0.100700 0.981600 -0.162200 +vn 0.100200 0.973600 -0.205200 +vn 0.168100 0.970300 -0.173900 +vn 0.011000 -0.980300 0.196900 +vn -0.100700 -0.971000 0.216700 +vn -0.049800 -0.998000 0.037700 +vn -0.125900 -0.990200 0.060800 +vn 0.114200 0.978100 -0.173500 +vn 0.159600 0.984400 -0.074200 +vn 0.063300 0.988000 -0.140600 +vn 0.072400 0.994100 -0.080000 +vn -0.046500 -0.961500 0.270500 +vn 0.412600 -0.773700 0.480700 +vn 0.751700 -0.251000 0.609900 +vn 0.792000 0.380000 0.477800 +vn 0.213900 0.970400 -0.112100 +vn 0.235800 0.966800 -0.098600 +vn -0.199500 -0.976500 0.081600 +vn -0.148400 -0.959900 0.237900 +vn 0.243000 0.953200 -0.180100 +vn 0.271200 0.955100 -0.118700 +vn -0.042700 0.841800 0.538100 +vn -0.351000 0.796700 0.492000 +vn 0.134300 0.956800 0.257600 +vn -0.205800 0.952800 0.222800 +vn 0.552400 -0.820200 -0.148300 +vn 0.435800 -0.741200 -0.510500 +vn 0.373900 -0.709100 -0.597800 +vn 0.373400 0.258800 0.890800 +vn 0.413100 0.240500 0.878300 +vn 0.683400 -0.370600 0.628900 +vn 0.376400 0.273000 0.885300 +vn -0.087000 0.645500 0.758800 +vn -0.322400 0.708100 0.628200 +vn 0.513100 -0.829200 -0.221300 +vn 0.471100 -0.763500 -0.441700 +vn 0.348400 0.438000 0.828700 +vn 0.513600 0.361300 0.778300 +vn 0.774600 -0.062400 0.629300 +vn 0.470300 -0.685700 0.555500 +vn 0.599000 0.781400 -0.174700 +vn 0.034900 0.997100 -0.067800 +vn 0.301000 0.947100 -0.110800 +vn 0.291700 0.949600 -0.114500 +vn 0.302300 0.944900 -0.125300 +vn 0.198700 0.975600 -0.092900 +vn -0.064500 0.997900 -0.004600 +vn -0.556600 0.805500 0.203400 +vn -0.492800 0.861300 0.123600 +vn -0.681500 0.708700 0.182300 +vn -0.711800 0.675700 0.191900 +vn -0.649300 0.740700 0.172200 +vn -0.278600 0.958600 0.058800 +vn 0.314300 0.942500 -0.113800 +vn 0.983700 -0.153800 -0.093300 +vn 0.955300 -0.104900 -0.276300 +vn 0.837900 0.482000 -0.255900 +vn 0.874100 -0.419100 -0.245300 +vn 0.740700 -0.640900 -0.201100 +vn 0.652000 -0.738200 -0.173000 +vn 0.653700 -0.736600 -0.173600 +vn 0.633500 -0.755400 -0.167300 +vn 0.532200 -0.835700 -0.135800 +vn 0.415400 -0.904100 -0.100100 +vn 0.391900 -0.915300 -0.093100 +vn 0.384100 -0.918800 -0.090900 +vn 0.756600 0.605400 -0.247000 +vn 0.734600 0.672400 -0.091000 +vn 0.770100 0.592800 -0.235500 +vn 0.309400 0.934800 0.174500 +vn 0.986200 -0.165300 -0.011200 +vn 0.365400 0.922300 0.126000 +vn 0.190800 0.977100 -0.094000 +vn 0.524200 0.847100 0.087200 +vn 0.252000 0.962100 -0.104100 +vn 0.633100 -0.749400 0.193600 +vn 0.695300 0.711200 0.103900 +vn 0.963500 -0.255800 -0.078700 +vn 0.355400 -0.786500 -0.505000 +vn -0.480000 0.749200 0.456400 +vn 0.888200 0.371000 -0.270900 +vn 0.944400 0.306800 -0.118200 +vn 0.951700 0.304500 0.038800 +vn 0.963200 0.233500 0.132800 +vn 0.951800 0.146600 0.269500 +vn 0.911000 -0.004900 0.412300 +vn 0.964700 -0.178800 0.193300 +vn 0.981800 -0.189500 -0.011700 +vn 0.735500 -0.394900 0.550500 +vn 0.764500 -0.566800 0.307100 +vn 0.850400 -0.473200 -0.229900 +vn 0.960400 -0.278300 0.008500 +vn 0.786700 -0.591000 -0.178200 +vn 0.984500 -0.174800 0.015700 +vn 0.770300 -0.585900 0.251700 +vn 0.504700 -0.751100 0.425500 +vn -0.960600 0.169300 0.220500 +vn -0.966200 0.036600 0.255300 +vn -0.973800 0.150800 0.169800 +vn -0.972900 0.026700 0.229700 +vn -0.984800 0.121600 0.124000 +vn -0.977400 0.015400 0.210600 +vn -0.992900 0.083700 0.085000 +vn -0.981100 -0.002300 0.193400 +vn -0.997800 0.037700 0.054500 +vn -0.983900 -0.030700 0.175800 +vn -0.999300 -0.014500 0.035100 +vn -0.984300 -0.057100 0.167200 +vn -0.997100 -0.070900 0.027900 +vn -0.982900 -0.083100 0.164300 +vn -0.991100 -0.128500 0.032800 +vn -0.979900 -0.110000 0.166300 +vn -0.975600 -0.135000 0.173200 +vn -0.982500 -0.179900 0.048900 +vn -0.970000 -0.157000 0.185200 +vn -0.971000 -0.227100 0.074500 +vn -0.957200 -0.268100 0.108800 +vn -0.963200 -0.175600 0.203400 +vn -0.938400 -0.301700 0.168000 +vn -0.953800 -0.190500 0.232400 +vn -0.914600 -0.319600 0.247400 +vn -0.944200 -0.196800 0.264100 +vn -0.939100 0.289700 0.184600 +vn -0.958700 0.262300 0.109600 +vn -0.974800 0.219300 0.041400 +vn -0.986500 0.162700 -0.016200 +vn -0.993600 0.095100 -0.060900 +vn -0.995700 0.020100 -0.090600 +vn -0.992800 -0.059600 -0.103500 +vn -0.985200 -0.140900 -0.097900 +vn -0.972500 -0.220700 -0.073900 +vn -0.954800 -0.294900 -0.036000 +vn -0.932200 -0.361300 0.019100 +vn -0.902400 -0.418600 0.102200 +vn -0.871800 -0.446600 0.201400 +vn -0.903600 0.402500 0.146600 +vn -0.928900 0.367000 0.049100 +vn -0.949600 0.310800 -0.039400 +vn -0.964700 0.237200 -0.114300 +vn -0.973600 0.149400 -0.172300 +vn -0.976200 0.051600 -0.210700 +vn -0.972300 -0.051400 -0.227900 +vn -0.962400 -0.155300 -0.222800 +vn -0.944100 -0.264600 -0.196600 +vn -0.919400 -0.362400 -0.152800 +vn -0.882100 -0.464100 -0.080800 +vn -0.843700 -0.535900 0.029100 +vn -0.817000 -0.559400 0.139800 +vn -0.854600 0.508100 0.106800 +vn -0.885300 0.464900 -0.011400 +vn -0.910200 0.396600 -0.118700 +vn -0.928300 0.307100 -0.209400 +vn -0.938900 0.200600 -0.279500 +vn -0.941800 0.082100 -0.325900 +vn -0.937000 -0.042700 -0.346500 +vn -0.924400 -0.170800 -0.340900 +vn -0.901600 -0.305600 -0.306000 +vn -0.867900 -0.432800 -0.243700 +vn -0.820900 -0.549700 -0.154500 +vn -0.783700 -0.618200 -0.059800 +vn -0.768600 -0.635900 0.069300 +vn -0.793500 0.605000 0.065800 +vn -0.829000 0.554700 -0.071100 +vn -0.857800 0.475400 -0.195300 +vn -0.878600 0.371500 -0.300100 +vn -0.890700 0.248000 -0.381000 +vn -0.893900 0.110900 -0.434400 +vn -0.888200 -0.033500 -0.458100 +vn -0.873600 -0.182800 -0.451000 +vn -0.850800 -0.331400 -0.407800 +vn -0.818400 -0.474600 -0.324000 +vn -0.772000 -0.599500 -0.211200 +vn -0.727100 -0.676000 -0.119500 +vn -0.700600 -0.713100 0.024400 +vn -0.721500 0.691900 0.024400 +vn -0.761300 0.635400 -0.129100 +vn -0.793500 0.546300 -0.268000 +vn -0.816700 0.429600 -0.385200 +vn -0.830200 0.291100 -0.475400 +vn -0.833700 0.137500 -0.534800 +vn -0.827400 -0.024000 -0.561100 +vn -0.811700 -0.189000 -0.552500 +vn -0.788500 -0.350500 -0.505300 +vn -0.756400 -0.507600 -0.412400 +vn -0.711100 -0.642800 -0.284900 +vn -0.668800 -0.727600 0.152600 +vn -0.640200 0.768000 -0.016800 +vn -0.683700 0.706000 -0.184500 +vn -0.718800 0.608600 -0.336000 +vn -0.744200 0.480800 -0.463600 +vn -0.758900 0.329500 -0.561700 +vn -0.762700 0.161900 -0.626100 +vn -0.755800 -0.014300 -0.654600 +vn -0.739000 -0.192000 -0.645700 +vn -0.712400 -0.368400 -0.597200 +vn -0.670800 -0.538100 -0.510300 +vn -0.632500 -0.664000 -0.398800 +vn -0.550700 0.832700 -0.057500 +vn -0.597300 0.766200 -0.236700 +vn -0.635100 0.661600 -0.398600 +vn -0.662300 0.524700 -0.534700 +vn -0.678200 0.362800 -0.639100 +vn -0.682300 0.183700 -0.707600 +vn -0.675000 -0.004500 -0.737800 +vn -0.656800 -0.193700 -0.728800 +vn -0.625100 -0.386700 -0.678000 +vn -0.571100 -0.566900 -0.593600 +vn -0.532600 -0.667300 -0.520600 +vn -0.454700 0.885300 -0.097000 +vn -0.503700 0.815400 -0.285300 +vn -0.543600 0.705200 -0.455100 +vn -0.572500 0.561100 -0.597800 +vn -0.589300 0.390900 -0.707000 +vn -0.593900 0.202700 -0.778600 +vn -0.586300 0.005100 -0.810000 +vn -0.567200 -0.193400 -0.800500 +vn -0.534800 -0.398800 -0.744900 +vn -0.476200 -0.586000 -0.655600 +vn -0.441700 -0.662900 -0.604500 +vn -0.335600 0.931400 -0.141100 +vn -0.386800 0.858500 -0.336600 +vn -0.428600 0.743800 -0.512900 +vn -0.458900 0.593900 -0.660800 +vn -0.476900 0.416900 -0.773800 +vn -0.481900 0.221400 -0.847700 +vn -0.474300 0.016300 -0.880200 +vn -0.454600 -0.189800 -0.870200 +vn -0.419700 -0.404700 -0.812400 +vn -0.359600 -0.599600 -0.714900 +vn -0.311200 -0.664200 -0.679700 +vn -0.193400 0.963000 -0.187900 +vn -0.245900 0.888500 -0.387500 +vn -0.289000 0.771200 -0.567100 +vn -0.316700 0.616800 -0.720600 +vn -0.322700 0.433300 -0.841500 +vn -0.319200 0.245900 -0.915200 +vn -0.337700 0.028400 -0.940800 +vn -0.317600 -0.181700 -0.930600 +vn -0.281400 -0.402900 -0.870900 +vn -0.218000 -0.611800 -0.760300 +vn -0.157400 -0.680700 -0.715400 +vn -0.046900 0.972000 -0.230200 +vn -0.099600 0.897700 -0.429200 +vn -0.165600 0.787600 -0.593600 +vn -0.225000 0.631600 -0.741900 +vn -0.226200 0.419000 -0.879400 +vn -0.150600 0.284700 -0.946700 +vn -0.192100 0.074900 -0.978500 +vn -0.206200 -0.169900 -0.963600 +vn -0.165800 -0.412100 -0.895900 +vn -0.068200 -0.613800 -0.786500 +vn 0.004500 -0.698000 -0.716000 +vn 0.082700 0.961200 -0.263000 +vn 0.006900 0.902400 -0.430800 +vn -0.115000 0.801400 -0.586900 +vn -0.056700 0.183000 -0.981500 +vn -0.055300 -0.014400 -0.998400 +vn -0.065800 -0.383800 -0.921000 +vn 0.015600 -0.644500 -0.764500 +vn 0.100400 -0.731300 -0.674600 +vn 0.186700 0.944000 -0.271800 +vn 0.053900 0.894800 -0.443200 +vn 0.310200 0.912000 -0.268200 +vn 0.242000 0.896600 -0.370900 +vn 0.126300 -0.322400 -0.938100 +vn 0.083700 0.001700 -0.996500 +vn 0.140900 -0.611700 -0.778400 +vn 0.222100 -0.776500 -0.589700 +vn 0.419400 0.864300 -0.277400 +vn 0.407500 0.845700 -0.344500 +vn 0.374600 -0.277500 -0.884700 +vn 0.320200 0.002700 -0.947300 +vn 0.364500 -0.508900 -0.779800 +vn 0.381500 -0.732700 -0.563600 +vn 0.522000 0.801200 -0.292400 +vn 0.539800 0.761700 -0.358200 +vn 0.584800 -0.202000 -0.785600 +vn 0.561000 0.015100 -0.827700 +vn 0.580900 -0.358300 -0.730800 +vn 0.567200 -0.569600 -0.594800 +vn 0.644400 0.697400 -0.313500 +vn 0.666500 0.632100 -0.395200 +vn 0.575300 -0.216700 -0.788700 +vn 0.559000 0.001600 -0.829200 +vn 0.636300 -0.292900 -0.713600 +vn 0.712100 -0.371900 -0.595400 +vn 0.586200 -0.727100 -0.357200 +vn 0.762400 -0.514000 -0.392900 +vn 0.449300 -0.822400 -0.348900 +vn 0.753700 0.560500 -0.342900 +vn 0.754800 0.493100 -0.432500 +vn 0.768900 0.504200 -0.393100 +vn 0.762900 0.452300 -0.462000 +vn -0.059700 0.305400 -0.950300 +vn -0.090800 0.402100 -0.911100 +vn 0.070700 0.402100 -0.912800 +vn 0.035300 0.474200 -0.879700 +vn -0.014000 0.389500 -0.920900 +vn -0.031700 0.264400 -0.963900 +vn -0.129600 0.515800 -0.846800 +vn -0.050000 0.496100 -0.866800 +vn 0.002400 0.534100 -0.845400 +vn 0.046300 0.064900 -0.996800 +vn -0.022000 0.200200 -0.979500 +vn 0.169900 0.223900 -0.959700 +vn 0.116200 0.327800 -0.937600 +vn -0.005600 0.146200 -0.989200 +vn 0.073900 0.044200 -0.996300 +vn 0.219500 -0.194800 -0.956000 +vn 0.136600 -0.071200 -0.988000 +vn 0.279300 -0.066700 -0.957900 +vn 0.230600 0.072100 -0.970400 +vn 0.184000 -0.047100 -0.981800 +vn 0.285800 -0.114400 -0.951400 +vn 0.327500 -0.292200 -0.898500 +vn 0.318700 -0.213600 -0.923400 +vn 0.470100 -0.314100 -0.824800 +vn 0.424700 -0.262400 -0.866500 +vn 0.367700 -0.156900 -0.916600 +vn 0.478200 -0.197100 -0.855800 +vn 0.652200 -0.034800 -0.757200 +vn 0.665500 -0.085200 -0.741500 +vn 0.603000 -0.241300 -0.760400 +vn 0.575900 -0.197200 -0.793400 +vn 0.518800 -0.147300 -0.842100 +vn 0.475800 0.031600 -0.879000 +vn 0.635000 0.177900 -0.751700 +vn 0.443200 0.194500 -0.875000 +vn 0.586100 0.355200 -0.728200 +vn 0.384000 0.345000 -0.856400 +vn 0.670600 0.327900 -0.665400 +vn 0.694500 0.120700 -0.709300 +vn 0.520500 0.482700 -0.704300 +vn 0.326200 0.439200 -0.837000 +vn 0.446600 0.579900 -0.681300 +vn 0.272600 0.509100 -0.816400 +vn 0.537400 0.614200 -0.577800 +vn 0.622100 0.483700 -0.615600 +vn 0.365100 0.666800 -0.649600 +vn 0.218200 0.573700 -0.789400 +vn 0.273100 0.748600 -0.604100 +vn 0.187300 0.629800 -0.753800 +vn 0.307000 0.804600 -0.508300 +vn 0.442800 0.724500 -0.528100 +vn 0.131600 0.824300 -0.550600 +vn 0.178300 0.742700 -0.645400 +vn -0.099400 0.823500 -0.558500 +vn -0.025400 0.740700 -0.671300 +vn -0.054400 0.802300 -0.594500 +vn 0.127500 0.850200 -0.510700 +vn -0.158500 0.660800 -0.733600 +vn -0.105300 0.606000 -0.788400 +vn -0.056400 0.637600 -0.768300 +vn 0.439100 0.311200 -0.842800 +vn 0.542600 0.359100 -0.759300 +vn 0.414600 0.415600 -0.809500 +vn 0.481600 0.426700 -0.765500 +vn 0.611600 0.773700 -0.165300 +vn 0.419100 0.503200 -0.755700 +vn 0.781400 0.607900 -0.141100 +vn 0.471600 0.194400 -0.860100 +vn 0.547400 -0.053600 -0.835100 +vn 0.464200 0.179000 -0.867500 +vn 0.611400 -0.038500 -0.790300 +vn 0.909600 -0.145700 -0.389000 +vn 0.653600 0.063700 -0.754100 +vn 0.758000 -0.389700 -0.522900 +vn 0.471000 0.155100 -0.868400 +vn 0.471700 0.223200 -0.853000 +vn 0.608800 0.253300 -0.751700 +vn 0.897200 0.399200 -0.188900 +vn 0.954500 0.141700 -0.262400 +vn 0.398600 0.596300 -0.696700 +vn 0.401700 0.531100 -0.746000 +vn 0.414700 0.581700 -0.699700 +vn 0.351600 0.895400 -0.273100 +vn 0.426600 0.591600 -0.684000 +vn 0.486600 0.847200 -0.213000 +vn 0.439700 0.578800 -0.686800 +vn 0.400700 0.535100 -0.743700 +vn 0.358700 0.561900 -0.745400 +vn 0.159800 0.907700 -0.387900 +vn -0.049900 0.832800 -0.551300 +vn 0.240000 0.510900 -0.825400 +vn -0.224600 0.653100 -0.723200 +vn -0.249700 0.466400 -0.848600 +vn 0.097900 0.435400 -0.894900 +vn 0.136800 0.342200 -0.929600 +vn 0.205700 0.358200 -0.910700 +vn 0.283800 0.437000 -0.853500 +vn 0.457100 0.301100 -0.836800 +vn 0.375900 0.291300 -0.879700 +vn 0.254900 0.313100 -0.914900 +vn -0.163800 0.338000 -0.926800 +vn -0.048500 0.283900 -0.957600 +vn 0.330800 0.351500 -0.875800 +vn 0.412600 0.391600 -0.822400 +vn 0.457200 0.358700 -0.813800 +vn 0.310700 0.368400 -0.876200 +vn -0.019400 0.227800 -0.973500 +vn -0.018300 0.111500 -0.993600 +vn 0.268300 0.343000 -0.900200 +vn 0.355200 0.267800 -0.895600 +vn 0.360700 0.360500 -0.860100 +vn 0.249500 0.223600 -0.942200 +vn 0.007700 -0.042500 -0.999100 +vn 0.126600 -0.240200 -0.962400 +vn 0.317200 0.068700 -0.945800 +vn 0.459200 0.192100 -0.867300 +vn 0.407600 0.212500 -0.888100 +vn 0.436200 -0.028400 -0.899400 +vn 0.329600 -0.430900 -0.840000 +vn 0.571000 -0.471800 -0.671800 +vn 0.387800 0.780000 -0.491100 +vn 0.511400 0.748600 -0.421900 +vn 0.627500 0.699400 -0.342100 +vn 0.828700 0.418400 -0.371700 +vn 0.890300 0.226900 -0.394800 +vn 0.828700 0.059400 -0.556600 +vn 0.747100 0.574100 -0.335000 +vn 0.078500 0.710700 -0.699100 +vn 0.229500 0.783900 -0.576900 +vn 0.703500 -0.127800 -0.699100 +vn 0.503900 -0.111100 -0.856500 +vn 0.000400 0.368700 -0.929500 +vn -0.020600 0.530000 -0.847700 +vn 0.333500 -0.073200 -0.939900 +vn 0.193300 0.069900 -0.978600 +vn 0.052800 0.305100 -0.950800 +vn 0.020200 0.319800 -0.947200 +vn 0.138600 0.192100 -0.971500 +vn 0.101300 0.223700 -0.969400 +vn 0.104200 0.293300 -0.950300 +vn 0.638400 0.172900 -0.750000 +vn 0.472200 0.198300 -0.858900 +vn 0.417700 0.364700 -0.832100 +vn 0.655900 0.362700 -0.662000 +vn 0.686800 0.258200 -0.679500 +vn 0.226800 0.426100 -0.875800 +vn 0.273000 0.335400 -0.901600 +vn 0.244600 0.271500 -0.930800 +vn 0.465100 0.560500 -0.685100 +vn 0.500900 0.484500 -0.717200 +vn 0.530700 0.433000 -0.728600 +vn 0.129400 0.414900 -0.900600 +vn 0.151300 0.526100 -0.836800 +vn 0.256100 0.585000 -0.769500 +vn 0.192400 0.271500 -0.943000 +vn 0.449900 0.438300 -0.778100 +vn 0.304300 0.450100 -0.839500 +vn 0.473200 0.428000 -0.770000 +vn 0.595900 0.418700 -0.685300 +vn 0.372300 0.596800 -0.710700 +vn 0.718400 0.155600 -0.677900 +vn 0.616800 0.153300 -0.772000 +vn 0.544700 0.226900 -0.807300 +vn 0.766700 0.250700 -0.591000 +vn 0.754700 0.356200 -0.550900 +vn 0.098100 0.246300 -0.964200 +vn 0.080400 0.236400 -0.968300 +vn -0.020400 0.287300 -0.957600 +vn 0.548200 0.692700 -0.468500 +vn 0.427000 0.787200 -0.444800 +vn 0.655200 0.554300 -0.513300 +vn -0.071400 0.708500 -0.702100 +vn -0.132800 0.586400 -0.799000 +vn 0.065700 0.800200 -0.596100 +vn -0.121500 0.383200 -0.915600 +vn 0.372800 0.253700 -0.892600 +vn 0.157500 0.246100 -0.956300 +vn 0.491000 0.264200 -0.830100 +vn 0.708400 0.451900 -0.542200 +vn 0.256300 0.825600 -0.502600 +vn 0.649400 0.282400 -0.706000 +vn 0.438600 0.259900 -0.860300 +vn 0.766400 0.383300 -0.515400 +vn 0.737400 0.318800 -0.595400 +vn 0.815300 0.310300 0.488900 +vn 0.946400 0.149100 -0.286400 +vn 0.976700 0.102500 0.188400 +vn 0.434700 0.900200 -0.023200 +vn 0.971800 -0.037700 -0.232600 +vn 0.666000 0.728500 -0.160100 +vn 0.948000 0.075800 -0.309200 +vn 0.581600 0.792800 -0.182100 +vn 0.747100 -0.639500 -0.181100 +vn 0.833700 -0.551200 -0.031900 +vn 0.478700 -0.872700 -0.096000 +vn 0.148600 0.728600 -0.668600 +vn 0.140800 0.622800 -0.769600 +vn -0.269400 0.833000 -0.483100 +vn -0.224000 0.732100 -0.643300 +vn 0.678200 0.300100 -0.670800 +vn 0.481200 0.213800 -0.850100 +vn 0.108000 -0.979800 -0.168000 +vn 0.546300 -0.762900 -0.345700 +vn 0.070700 -0.979400 -0.188800 +vn 0.679900 -0.531700 -0.505000 +vn 0.011800 0.682500 -0.730700 +vn 0.528200 0.518400 -0.672500 +vn 0.504500 0.661100 -0.555300 +vn -0.054400 0.836900 -0.544600 +vn 0.097000 0.818600 -0.566100 +vn -0.133500 0.694600 -0.706900 +vn -0.219100 0.786800 -0.577000 +vn -0.316300 0.736600 -0.597900 +vn -0.156900 0.720500 -0.675400 +vn -0.307100 0.743700 -0.593700 +vn -0.361700 0.112900 -0.925400 +vn -0.202900 0.660400 -0.723000 +vn -0.097000 0.122500 -0.987700 +vn -0.068800 0.632300 -0.771600 +vn 0.099200 0.401100 -0.910600 +vn 0.195400 0.050100 -0.979400 +vn -0.069800 -0.405200 -0.911600 +vn -0.372100 -0.476300 -0.796600 +vn 0.118000 -0.967200 -0.225000 +vn 0.161200 -0.868700 -0.468400 +vn -0.219800 -0.862800 -0.455200 +vn 0.102800 -0.966400 -0.235600 +vn 0.252600 -0.801400 -0.542200 +vn 0.153100 -0.972900 -0.173300 +vn 0.079800 -0.983700 -0.161300 +vn 0.119600 0.827500 -0.548500 +vn 0.100200 0.871200 -0.480600 +vn -0.162800 0.749700 -0.641400 +vn -0.172300 0.790700 -0.587500 +vn 0.598900 -0.066500 -0.798000 +vn 0.758500 -0.112400 -0.641900 +vn 0.502200 -0.442300 -0.743000 +vn 0.797800 0.047700 -0.601100 +vn 0.523800 -0.592400 -0.612100 +vn 0.602500 0.120700 -0.788900 +vn 0.419900 -0.433100 -0.797500 +vn 0.065600 -0.927700 -0.367400 +vn 0.149000 -0.843600 -0.515900 +vn 0.913800 -0.024700 -0.405200 +vn 0.583200 -0.720600 -0.374800 +vn -0.004100 -0.976100 -0.217100 +vn 0.198200 0.860700 -0.468800 +vn 0.719900 0.381800 -0.579600 +vn -0.007800 0.728500 -0.685000 +vn 0.591400 0.269300 -0.760100 +vn 0.537700 0.030000 -0.842600 +vn -0.097000 0.525700 -0.845100 +vn 0.470000 -0.749700 0.465800 +vn 0.710000 -0.530400 0.463200 +vn 0.726000 -0.657700 0.200600 +vn 0.867000 0.432500 0.247400 +vn 0.867900 -0.436000 0.237900 +vn 0.809100 0.576600 -0.113000 +vn 0.397500 -0.917400 -0.019200 +vn 0.344400 0.934000 0.094400 +vn 0.249500 0.968300 0.008000 +vn 0.200600 0.978700 0.042900 +vn 0.291100 0.956600 0.013600 +vn 0.186800 0.982400 -0.001000 +vn 0.290600 0.955100 -0.057600 +vn -0.246300 0.709400 -0.660400 +vn -0.517100 0.721500 -0.460500 +vn -0.421000 0.661400 -0.620700 +vn -0.645000 0.675500 -0.357100 +vn 0.588800 -0.803900 -0.083500 +vn 0.407100 -0.913400 0.006700 +vn 0.430400 -0.877400 0.211600 +vn 0.495000 -0.846500 0.195800 +vn 0.684600 -0.651200 0.327400 +vn 0.576400 -0.713300 0.398700 +vn 0.260000 -0.863800 -0.431500 +vn 0.521900 -0.696600 -0.492300 +vn 0.695100 0.559000 -0.452100 +vn 0.849700 -0.213600 -0.482100 +vn 0.378500 -0.430900 -0.819100 +vn 0.081100 -0.488500 -0.868800 +vn 0.504700 -0.771800 0.386800 +vn 0.569400 -0.758600 0.316500 +vn 0.602900 -0.752700 0.264400 +vn 0.473800 -0.877300 -0.076400 +vn 0.431200 -0.901500 -0.037200 +vn 0.392200 -0.919600 -0.020400 +vn -0.643900 0.663900 -0.380100 +vn -0.515300 0.647100 -0.561900 +vn -0.642800 0.666400 -0.377800 +vn -0.526000 0.618900 -0.583300 +vn -0.491400 0.676000 -0.549100 +vn -0.630100 0.676300 -0.381500 +vn 0.729800 -0.676000 -0.101900 +vn 0.795700 -0.581500 -0.169200 +vn 0.719700 -0.693600 0.029800 +vn 0.770000 -0.638100 -0.000300 +vn 0.714500 -0.655500 0.244600 +vn 0.698000 -0.659500 0.279000 +vn 0.681900 -0.668000 0.297800 +vn 0.685800 -0.724700 0.067200 +vn 0.677900 -0.727500 -0.105200 +vn 0.589300 -0.662200 -0.462900 +vn 0.335200 -0.381100 -0.861600 +vn 0.666200 -0.604200 -0.437100 +vn 0.404600 -0.209100 -0.890300 +vn 0.796300 -0.408700 -0.445800 +vn -0.704400 0.704300 -0.087900 +vn -0.700700 0.691700 0.174600 +vn -0.695000 0.715100 -0.074700 +vn -0.690500 0.702900 0.170400 +vn -0.620400 0.780400 0.078000 +vn -0.565100 0.818400 -0.103600 +vn 0.659100 -0.722200 0.209800 +vn 0.613000 -0.761500 0.210500 +vn 0.613900 -0.771700 0.166200 +vn 0.620300 -0.780400 -0.078200 +vn 0.615300 -0.777400 -0.130400 +vn 0.611400 -0.773600 -0.166300 +vn -0.399500 0.828700 -0.391900 +vn -0.353500 0.918500 -0.177300 +vn 0.848100 -0.431700 -0.307100 +vn 0.736100 -0.659000 -0.154200 +vn 0.837200 -0.491200 -0.240400 +vn 0.729900 -0.683400 -0.013600 +vn 0.008800 -0.980400 -0.196600 +vn 0.072600 -0.774800 -0.627900 +vn -0.140900 -0.976200 -0.164600 +vn 0.057600 -0.757300 -0.650400 +vn 0.285000 0.533300 -0.796400 +vn 0.234300 -0.146900 -0.961000 +vn 0.404500 0.549900 -0.730700 +vn 0.425200 -0.244200 -0.871500 +vn 0.082000 0.992700 -0.088600 +vn 0.087200 0.994800 0.053300 +vn 0.150000 0.985400 0.080900 +vn 0.216600 0.974800 0.053800 +vn 0.245500 0.964700 0.095400 +vn -0.084100 -0.988000 -0.129500 +vn -0.188800 -0.978200 -0.086300 +vn 0.208100 0.977200 0.042200 +vn 0.187800 0.981300 0.041100 +vn -0.172700 -0.971700 -0.161300 +vn 0.099200 -0.798900 -0.593200 +vn 0.311300 -0.274700 -0.909700 +vn 0.387300 0.356600 -0.850200 +vn 0.364600 0.928000 -0.076300 +vn 0.263500 0.962700 -0.061500 +vn -0.241000 -0.967300 -0.078600 +vn 0.244700 0.966800 -0.073500 +vn -0.335900 0.935500 -0.109400 +vn -0.616200 0.753200 -0.230100 +vn -0.093300 0.939000 -0.330900 +vn -0.432700 0.797000 -0.421400 +vn 0.555900 -0.819900 -0.136800 +vn 0.649500 -0.724700 0.230200 +vn 0.671200 -0.671300 0.314200 +vn -0.167500 0.215300 -0.962100 +vn -0.127100 0.197300 -0.972000 +vn 0.242700 -0.405900 -0.881100 +vn -0.164300 0.228300 -0.959600 +vn -0.489600 0.613100 -0.620000 +vn -0.618600 0.684300 -0.386000 +vn 0.564600 -0.822200 -0.072300 +vn 0.660400 -0.741600 0.117400 +vn -0.157300 0.397400 -0.904000 +vn -0.002000 0.320500 -0.947200 +vn 0.309200 -0.106000 -0.945100 +vn 0.095300 -0.716800 -0.690700 +vn -0.588900 0.802700 0.093400 +vn 0.881400 -0.162100 -0.443700 +vn 0.738900 0.625800 -0.249700 +vn 0.637100 0.674600 -0.372900 +vn 0.840200 -0.178100 -0.512200 +vn 0.216200 0.924400 -0.314300 +vn 0.097000 0.987000 -0.127800 +vn 0.177400 0.904300 -0.388300 +vn 0.392800 0.793100 -0.465400 +vn 0.358000 0.915500 -0.183600 +vn 0.439300 -0.764200 -0.472200 +vn 0.544800 0.694900 -0.469300 +vn 0.857800 -0.264400 -0.440700 +vn 0.618100 -0.748900 0.238700 +vn -0.659700 0.734600 -0.158300 +vn 0.852000 0.297700 -0.430500 +vn 0.779800 0.276500 -0.561600 +vn 0.779300 0.156700 -0.606700 +vn 0.608400 0.116400 -0.785000 +vn 0.513800 -0.052200 -0.856300 +vn 0.448100 -0.548400 -0.706000 +vn 0.793100 -0.135500 -0.593800 +vn 0.386000 -0.449800 -0.805300 +vn 0.703000 -0.218600 -0.676700 +vn 0.856900 -0.212900 -0.469300 +vn 0.866600 -0.015800 -0.498800 +vn 0.522900 -0.605400 -0.600000 +vn 0.201600 -0.779800 -0.592600 +vn -0.077400 0.751400 -0.655200 +vn -0.939100 -0.200900 0.278800 +vn -0.900400 -0.328500 0.285100 +vn -0.856400 -0.451700 0.249900 +vn -0.802500 -0.561400 0.202200 +vn -0.740500 -0.650500 0.168600 +vn -0.641600 -0.723300 0.255300 +vn -0.850200 -0.448000 0.276400 +vn -0.783900 -0.564200 0.259100 +vn -0.705100 -0.660500 0.257900 +vn 0.571600 -0.765500 0.295400 +vn 0.000300 -1.000000 -0.006700 +vn 0.000300 -1.000000 -0.007200 +vn 0.002300 -1.000000 -0.003900 +vn -0.000700 -1.000000 -0.002500 +vn -0.000400 -1.000000 0.000700 +vn -0.005000 -1.000000 -0.005400 +vn -0.003700 -1.000000 -0.006500 +vn -0.001700 -1.000000 -0.007100 +vn -0.001200 -0.999900 -0.007900 +vn 0.000300 -0.999900 -0.007900 +vn -0.005600 -1.000000 -0.005300 +vn 0.000400 -0.999900 -0.008700 +vn -0.002400 -1.000000 -0.001900 +vn 0.005400 -1.000000 -0.000000 +vn -0.003600 -1.000000 0.002600 +vn 0.003000 -0.999900 0.010800 +vn 0.001600 -0.999900 0.010500 +vn 0.010600 -0.999900 0.011400 +vn 0.005300 -0.999900 0.007100 +vn 0.000300 -1.000000 -0.000200 +vn -0.005100 -1.000000 0.004100 +vn -0.003100 -0.999900 0.008100 +vn -0.005800 -0.999800 0.017600 +vn 0.000200 -0.999800 0.021500 +vn 0.002500 -0.999900 0.012800 +vn -0.005600 -1.000000 0.003300 +vn 0.000300 -0.999900 0.012900 +vn -0.000200 -1.000000 0.000200 +vn -0.000600 -1.000000 -0.001300 +vn -0.000300 -1.000000 0.000600 +usemtl blinn3-material +s off +f 2080/1/1 2082/2/1 2108/3/1 +f 2082/2/2 2083/4/2 2108/3/2 +f 2083/4/3 2084/5/3 2108/3/3 +f 2092/6/4 2090/7/4 2108/3/4 +f 2084/5/5 2093/8/5 2108/3/5 +f 2093/8/6 2107/9/6 2108/3/6 +f 2107/9/7 2099/10/7 2108/3/7 +s 1 +f 1/11/8 2/12/9 3/13/10 +f 3/13/10 2/12/9 4/14/11 +f 2/12/9 1/11/8 5/15/12 +f 5/15/12 1/11/8 6/16/13 +f 7/17/14 8/18/15 6/16/13 +f 6/16/13 8/18/15 5/15/12 +f 8/18/15 7/17/14 9/19/16 +f 9/19/16 7/17/14 10/20/17 +f 11/21/18 12/22/19 13/23/20 +f 13/23/20 12/22/19 14/24/21 +f 12/22/19 11/21/18 15/25/22 +f 15/25/22 11/21/18 16/26/23 +f 17/27/24 1/11/8 18/28/25 +f 18/28/25 1/11/8 3/13/10 +f 1/11/8 17/27/24 6/16/13 +f 6/16/13 17/27/24 19/29/26 +f 17/27/24 20/30/27 19/29/26 +f 19/29/26 20/30/27 21/31/28 +f 20/30/27 17/27/24 22/32/29 +f 22/32/29 17/27/24 18/28/25 +f 23/33/30 7/17/14 19/29/26 +f 19/29/26 7/17/14 6/16/13 +f 7/17/14 23/33/30 10/20/17 +f 10/20/17 23/33/30 24/34/31 +f 23/33/30 25/35/32 24/34/31 +f 24/34/31 25/35/32 26/36/33 +f 25/35/32 23/33/30 21/31/28 +f 21/31/28 23/33/30 19/29/26 +f 27/37/34 12/22/19 28/38/35 +f 28/38/35 12/22/19 15/25/22 +f 12/22/19 27/37/34 14/24/21 +f 14/24/21 27/37/34 29/39/36 +f 30/40/37 31/41/38 32/42/39 +f 32/42/39 31/41/38 33/43/40 +f 31/41/38 30/40/37 14/24/21 +f 14/24/21 30/40/37 13/23/20 +f 34/44/41 20/30/27 35/45/42 +f 35/45/42 20/30/27 22/32/29 +f 20/30/27 34/44/41 21/31/28 +f 21/31/28 34/44/41 36/46/43 +f 34/44/41 37/47/44 36/46/43 +f 36/46/43 37/47/44 38/48/45 +f 37/47/44 34/44/41 39/49/46 +f 39/49/46 34/44/41 35/45/42 +f 40/50/47 31/41/38 29/39/36 +f 29/39/36 31/41/38 14/24/21 +f 31/41/38 40/50/47 33/43/40 +f 33/43/40 40/50/47 41/51/48 +f 42/52/49 43/53/50 33/43/40 +f 33/43/40 43/53/50 32/42/39 +f 43/53/50 42/52/49 44/54/51 +f 44/54/51 42/52/49 45/55/52 +f 46/56/53 42/52/49 41/51/48 +f 41/51/48 42/52/49 33/43/40 +f 42/52/49 46/56/53 45/55/52 +f 45/55/52 46/56/53 47/57/54 +f 48/58/55 49/59/56 50/60/57 +f 50/60/57 49/59/56 51/61/58 +f 51/61/58 49/59/56 45/55/52 +f 45/55/52 49/59/56 44/54/51 +f 52/62/59 51/61/58 47/57/54 +f 47/57/54 51/61/58 45/55/52 +f 52/62/59 53/63/60 51/61/58 +f 51/61/58 53/63/60 50/60/57 +f 54/64/61 55/65/62 56/66/63 +f 56/66/63 55/65/62 57/67/64 +f 55/65/62 48/58/55 57/67/64 +f 57/67/64 48/58/55 50/60/57 +f 53/63/60 58/68/65 50/60/57 +f 50/60/57 58/68/65 57/67/64 +f 58/68/65 59/69/66 57/67/64 +f 57/67/64 59/69/66 56/66/63 +f 60/70/67 61/71/68 62/72/69 +f 62/72/69 61/71/68 63/73/70 +f 61/71/68 54/64/61 63/73/70 +f 63/73/70 54/64/61 56/66/63 +f 59/69/66 64/74/71 56/66/63 +f 56/66/63 64/74/71 63/73/70 +f 64/74/71 65/75/72 63/73/70 +f 63/73/70 65/75/72 62/72/69 +f 66/76/73 67/77/74 68/78/75 +f 68/78/75 67/77/74 69/79/76 +f 68/78/75 69/79/76 70/80/77 +f 70/80/77 69/79/76 71/81/78 +f 69/79/76 72/82/79 71/81/78 +f 71/81/78 72/82/79 73/83/80 +f 72/82/79 69/79/76 74/84/81 +f 74/84/81 69/79/76 67/77/74 +f 75/85/82 76/86/83 77/87/84 +f 77/87/84 76/86/83 78/88/85 +f 76/86/83 75/85/82 79/89/86 +f 79/89/86 75/85/82 80/90/87 +f 75/85/82 68/78/75 80/90/87 +f 80/90/87 68/78/75 70/80/77 +f 68/78/75 75/85/82 66/76/73 +f 66/76/73 75/85/82 77/87/84 +f 80/90/87 81/91/88 79/89/86 +f 79/89/86 81/91/88 82/92/89 +f 80/90/87 70/80/77 81/91/88 +f 81/91/88 70/80/77 83/93/90 +f 84/94/91 85/95/92 86/96/93 +f 86/96/93 85/95/92 87/97/94 +f 87/98/94 85/99/92 88/100/95 +f 88/100/95 85/99/92 89/101/96 +f 85/99/92 90/102/97 89/101/96 +f 89/101/96 90/102/97 91/103/98 +f 85/95/92 84/94/91 90/104/97 +f 90/104/97 84/94/91 92/105/99 +f 93/106/100 94/107/101 95/108/102 +f 95/108/102 94/107/101 96/109/103 +f 94/107/101 84/94/91 96/109/103 +f 96/109/103 84/94/91 86/96/93 +f 84/94/91 94/107/101 92/105/99 +f 92/105/99 94/107/101 97/110/104 +f 94/107/101 93/106/100 97/110/104 +f 97/110/104 93/106/100 98/111/105 +f 99/112/106 100/113/107 98/111/105 +f 98/111/105 100/113/107 97/110/104 +f 100/113/107 101/114/108 97/110/104 +f 97/110/104 101/114/108 92/105/99 +f 101/114/108 100/113/107 102/115/109 +f 102/115/109 100/113/107 103/116/110 +f 100/113/107 99/112/106 103/116/110 +f 103/116/110 99/112/106 104/117/111 +f 105/118/112 106/119/113 107/120/114 +f 107/120/114 106/119/113 108/121/115 +f 108/121/115 106/119/113 109/122/116 +f 109/122/116 106/119/113 110/123/117 +f 106/119/113 99/112/106 110/123/117 +f 110/123/117 99/112/106 98/111/105 +f 106/119/113 105/118/112 99/112/106 +f 99/112/106 105/118/112 104/117/111 +f 111/124/118 25/35/32 36/46/43 +f 36/46/43 25/35/32 21/31/28 +f 25/35/32 111/124/118 26/36/33 +f 26/36/33 111/124/118 112/125/119 +f 111/124/118 113/126/120 112/125/119 +f 112/125/119 113/126/120 114/127/121 +f 113/126/120 111/124/118 38/48/45 +f 38/48/45 111/124/118 36/46/43 +f 115/128/122 116/129/123 117/130/124 +f 117/130/124 116/129/123 118/131/125 +f 116/129/123 119/132/126 118/131/125 +f 118/131/125 119/132/126 120/133/127 +f 37/47/44 121/134/128 38/48/45 +f 38/48/45 121/134/128 122/135/129 +f 121/134/128 105/136/112 122/135/129 +f 122/135/129 105/136/112 107/137/114 +f 105/136/112 121/134/128 104/138/111 +f 104/138/111 121/134/128 123/139/130 +f 121/134/128 37/47/44 123/139/130 +f 123/139/130 37/47/44 39/49/46 +f 113/126/120 124/140/131 114/127/121 +f 114/127/121 124/140/131 125/141/132 +f 124/140/131 126/142/133 125/141/132 +f 125/141/132 126/142/133 127/143/134 +f 126/142/133 124/140/131 107/137/114 +f 107/137/114 124/140/131 122/135/129 +f 124/140/131 113/126/120 122/135/129 +f 122/135/129 113/126/120 38/48/45 +f 128/144/135 129/145/136 130/146/137 +f 130/146/137 129/145/136 131/147/138 +f 119/132/126 128/144/135 120/133/127 +f 120/133/127 128/144/135 130/146/137 +f 132/148/139 133/149/140 134/150/141 +f 134/150/141 133/149/140 135/151/142 +f 136/152/143 137/153/144 78/88/85 +f 78/88/85 137/153/144 77/87/84 +f 137/153/144 138/154/145 77/87/84 +f 77/87/84 138/154/145 66/76/73 +f 138/155/145 137/156/144 139/157/146 +f 139/157/146 137/156/144 140/158/147 +f 137/156/144 136/159/143 140/158/147 +f 140/158/147 136/159/143 141/160/148 +f 142/161/149 143/162/150 144/163/151 +f 144/163/151 143/162/150 145/164/152 +f 143/162/150 60/70/67 145/164/152 +f 145/164/152 60/70/67 62/72/69 +f 146/165/153 147/166/154 74/84/81 +f 74/84/81 147/166/154 72/82/79 +f 147/166/154 148/167/155 72/82/79 +f 72/82/79 148/167/155 73/83/80 +f 148/167/155 147/166/154 142/161/149 +f 142/161/149 147/166/154 143/162/150 +f 147/166/154 146/165/153 143/162/150 +f 143/162/150 146/165/153 60/70/67 +f 65/75/72 149/168/156 62/72/69 +f 62/72/69 149/168/156 145/164/152 +f 149/168/156 150/169/157 145/164/152 +f 145/164/152 150/169/157 144/163/151 +f 151/170/158 83/93/90 71/81/78 +f 71/81/78 83/93/90 70/80/77 +f 71/81/78 73/83/80 151/170/158 +f 151/170/158 73/83/80 152/171/159 +f 153/172/160 154/173/161 91/103/98 +f 91/103/98 154/173/161 89/101/96 +f 154/173/161 155/174/162 89/101/96 +f 89/101/96 155/174/162 88/100/95 +f 155/174/162 154/173/161 141/160/148 +f 141/160/148 154/173/161 140/158/147 +f 154/173/161 153/172/160 140/158/147 +f 140/158/147 153/172/160 139/157/146 +f 126/175/133 156/176/163 127/177/134 +f 127/177/134 156/176/163 157/178/164 +f 156/176/163 158/179/165 157/178/164 +f 157/178/164 158/179/165 159/180/166 +f 158/179/165 156/176/163 109/122/116 +f 109/122/116 156/176/163 108/121/115 +f 156/176/163 126/175/133 108/121/115 +f 108/121/115 126/175/133 107/120/114 +f 160/181/167 161/182/168 153/172/160 +f 153/172/160 161/182/168 139/157/146 +f 161/183/168 160/184/167 102/115/109 +f 102/115/109 160/184/167 101/114/108 +f 160/184/167 90/104/97 101/114/108 +f 101/114/108 90/104/97 92/105/99 +f 90/102/97 160/181/167 91/103/98 +f 91/103/98 160/181/167 153/172/160 +f 110/123/117 162/185/169 109/122/116 +f 109/122/116 162/185/169 158/179/165 +f 158/179/165 162/185/169 159/180/166 +f 159/180/166 162/185/169 163/186/170 +f 162/185/169 93/106/100 163/186/170 +f 163/186/170 93/106/100 95/108/102 +f 93/106/100 162/185/169 98/111/105 +f 98/111/105 162/185/169 110/123/117 +f 150/169/157 164/187/171 144/163/151 +f 144/163/151 164/187/171 165/188/172 +f 164/187/171 166/189/173 165/188/172 +f 165/188/172 166/189/173 167/190/174 +f 168/191/175 169/192/176 170/193/177 +f 170/193/177 169/192/176 152/171/159 +f 169/192/176 168/191/175 171/194/178 +f 171/194/178 168/191/175 172/195/179 +f 168/191/175 173/196/180 172/195/179 +f 172/195/179 173/196/180 174/197/181 +f 173/196/180 168/191/175 142/161/149 +f 142/161/149 168/191/175 170/193/177 +f 174/197/181 173/196/180 167/190/174 +f 167/190/174 173/196/180 165/188/172 +f 165/188/172 173/196/180 144/163/151 +f 144/163/151 173/196/180 142/161/149 +f 169/192/176 175/198/182 152/171/159 +f 152/171/159 175/198/182 151/170/158 +f 175/198/182 176/199/183 151/170/158 +f 151/170/158 176/199/183 83/93/90 +f 176/199/183 175/198/182 177/200/184 +f 177/200/184 175/198/182 178/201/185 +f 175/198/182 169/192/176 178/201/185 +f 178/201/185 169/192/176 171/194/178 +f 179/202/186 180/203/187 16/26/23 +f 16/26/23 180/203/187 15/25/22 +f 181/204/188 182/205/189 183/206/190 +f 183/206/190 182/205/189 184/207/191 +f 182/205/189 179/202/186 184/207/191 +f 184/207/191 179/202/186 16/26/23 +f 185/208/192 186/209/193 4/14/11 +f 4/14/11 186/209/193 3/13/10 +f 180/203/187 187/210/194 15/25/22 +f 15/25/22 187/210/194 28/38/35 +f 188/211/195 189/212/196 184/207/191 +f 184/207/191 189/212/196 183/206/190 +f 189/212/196 188/211/195 190/213/197 +f 190/213/197 188/211/195 191/214/198 +f 188/211/195 11/21/18 191/214/198 +f 191/214/198 11/21/18 13/23/20 +f 11/21/18 188/211/195 16/26/23 +f 16/26/23 188/211/195 184/207/191 +f 186/209/193 192/215/199 3/13/10 +f 3/13/10 192/215/199 18/28/25 +f 192/215/199 193/216/200 18/28/25 +f 18/28/25 193/216/200 22/32/29 +f 194/217/201 195/218/202 196/219/203 +f 196/219/203 195/218/202 197/220/204 +f 195/218/202 198/221/205 197/220/204 +f 197/220/204 198/221/205 199/222/206 +f 195/223/202 200/224/207 198/225/205 +f 198/225/205 200/224/207 201/226/208 +f 200/224/207 195/223/202 202/227/209 +f 202/227/209 195/223/202 194/228/201 +f 198/221/205 203/229/210 199/222/206 +f 199/222/206 203/229/210 204/230/211 +f 204/230/211 203/229/210 205/231/212 +f 205/231/212 203/229/210 206/232/213 +f 206/233/213 203/234/210 207/235/214 +f 207/235/214 203/234/210 208/236/215 +f 203/234/210 198/225/205 208/236/215 +f 208/236/215 198/225/205 201/226/208 +f 209/237/216 210/238/217 206/232/213 +f 206/232/213 210/238/217 205/231/212 +f 210/238/217 209/237/216 211/239/218 +f 211/239/218 209/237/216 212/240/219 +f 212/241/219 209/242/216 213/243/220 +f 213/243/220 209/242/216 214/244/221 +f 209/242/216 206/233/213 214/244/221 +f 214/244/221 206/233/213 207/235/214 +f 215/245/222 146/165/153 216/246/223 +f 216/246/223 146/165/153 74/84/81 +f 146/165/153 215/245/222 60/70/67 +f 60/70/67 215/245/222 61/71/68 +f 215/245/222 217/247/224 61/71/68 +f 61/71/68 217/247/224 54/64/61 +f 148/167/155 170/193/177 73/83/80 +f 73/83/80 170/193/177 152/171/159 +f 170/193/177 148/167/155 142/161/149 +f 217/247/224 218/248/225 54/64/61 +f 54/64/61 218/248/225 55/65/62 +f 218/248/225 219/249/226 55/65/62 +f 55/65/62 219/249/226 48/58/55 +f 219/249/226 220/250/227 48/58/55 +f 48/58/55 220/250/227 49/59/56 +f 49/59/56 220/250/227 44/54/51 +f 44/54/51 220/250/227 221/251/228 +f 222/252/229 43/53/50 221/251/228 +f 221/251/228 43/53/50 44/54/51 +f 43/53/50 222/252/229 32/42/39 +f 32/42/39 222/252/229 223/253/230 +f 224/254/231 225/255/232 191/214/198 +f 191/214/198 225/255/232 190/213/197 +f 224/254/231 30/40/37 223/253/230 +f 223/253/230 30/40/37 32/42/39 +f 30/40/37 224/254/231 13/23/20 +f 13/23/20 224/254/231 191/214/198 +f 193/216/200 226/256/233 22/32/29 +f 22/32/29 226/256/233 35/45/42 +f 226/256/233 227/257/234 35/45/42 +f 35/45/42 227/257/234 39/49/46 +f 227/257/234 228/258/235 39/49/46 +f 39/49/46 228/258/235 123/139/130 +f 228/258/235 229/259/236 123/139/130 +f 123/139/130 229/259/236 104/138/111 +f 230/260/237 231/261/238 103/262/110 +f 103/262/110 231/261/238 102/263/109 +f 229/259/236 230/260/237 104/138/111 +f 104/138/111 230/260/237 103/262/110 +f 232/264/239 161/265/168 231/261/238 +f 231/261/238 161/265/168 102/263/109 +f 161/265/168 232/264/239 139/266/146 +f 139/266/146 232/264/239 132/148/139 +f 233/267/240 234/268/241 129/145/136 +f 129/145/136 234/268/241 131/147/138 +f 235/269/242 236/270/243 233/267/240 +f 233/267/240 236/270/243 234/268/241 +f 134/150/141 138/154/145 132/148/139 +f 132/148/139 138/154/145 139/266/146 +f 237/271/244 67/77/74 134/150/141 +f 67/77/74 66/76/73 134/150/141 +f 134/150/141 66/76/73 138/154/145 +f 238/272/245 239/273/246 228/258/235 +f 228/258/235 239/273/246 229/259/236 +f 240/274/247 241/275/248 242/276/249 +f 242/276/249 241/275/248 243/277/250 +f 244/278/251 240/274/247 245/279/252 +f 245/279/252 240/274/247 242/276/249 +f 246/280/253 238/272/245 227/257/234 +f 227/257/234 238/272/245 228/258/235 +f 247/281/254 248/282/255 230/260/237 +f 230/260/237 248/282/255 231/261/238 +f 249/283/256 250/284/257 251/285/258 +f 251/285/258 250/284/257 252/286/259 +f 241/275/248 249/283/256 243/277/250 +f 243/277/250 249/283/256 251/285/258 +f 239/273/246 247/281/254 229/259/236 +f 229/259/236 247/281/254 230/260/237 +f 224/254/231 253/287/260 225/255/232 +f 225/255/232 253/287/260 254/288/261 +f 255/289/262 256/290/263 257/291/264 +f 257/291/264 256/290/263 258/292/265 +f 257/293/264 258/294/265 259/295/266 +f 259/295/266 258/294/265 260/296/267 +f 253/287/260 224/254/231 261/297/268 +f 261/297/268 224/254/231 223/253/230 +f 262/298/269 246/280/253 226/256/233 +f 226/256/233 246/280/253 227/257/234 +f 263/299/270 244/278/251 264/300/271 +f 264/300/271 244/278/251 245/279/252 +f 222/252/229 265/301/272 223/253/230 +f 223/253/230 265/301/272 261/297/268 +f 259/295/266 260/296/267 266/302/273 +f 266/302/273 260/296/267 267/303/274 +f 266/302/273 267/303/274 268/304/275 +f 268/304/275 267/303/274 269/305/276 +f 265/301/272 222/252/229 270/306/277 +f 270/306/277 222/252/229 221/251/228 +f 220/250/227 271/307/278 221/251/228 +f 221/251/228 271/307/278 270/306/277 +f 268/304/275 269/305/276 272/308/279 +f 272/308/279 269/305/276 273/309/280 +f 274/310/281 272/308/279 275/311/282 +f 275/311/282 272/308/279 273/309/280 +f 276/312/283 271/307/278 219/249/226 +f 219/249/226 271/307/278 220/250/227 +f 277/313/284 278/314/285 215/245/222 +f 215/245/222 278/314/285 217/247/224 +f 279/315/286 280/316/287 281/317/288 +f 281/317/288 280/316/287 282/318/289 +f 283/319/290 279/320/286 284/321/291 +f 284/321/291 279/320/286 281/322/288 +f 285/323/292 277/313/284 216/246/223 +f 216/246/223 277/313/284 215/245/222 +f 286/324/293 276/312/283 218/248/225 +f 218/248/225 276/312/283 219/249/226 +f 287/325/294 274/310/281 288/326/295 +f 288/326/295 274/310/281 275/311/282 +f 280/316/287 287/325/294 282/318/289 +f 282/318/289 287/325/294 288/326/295 +f 278/314/285 286/324/293 217/247/224 +f 217/247/224 286/324/293 218/248/225 +f 232/264/239 289/327/296 132/148/139 +f 132/148/139 289/327/296 133/149/140 +f 290/328/297 291/329/298 292/330/299 +f 292/330/299 291/329/298 293/331/300 +f 292/330/299 293/331/300 250/284/257 +f 250/284/257 293/331/300 252/286/259 +f 289/327/296 232/264/239 248/282/255 +f 248/282/255 232/264/239 231/261/238 +f 294/332/301 295/333/302 290/328/297 +f 290/328/297 295/333/302 291/329/298 +f 296/334/303 297/335/304 294/332/301 +f 294/332/301 297/335/304 295/333/302 +f 298/336/305 299/337/306 120/133/127 +f 120/133/127 299/337/306 118/131/125 +f 117/130/124 118/131/125 300/338/307 +f 300/338/307 118/131/125 299/337/306 +f 301/339/308 302/340/309 131/147/138 +f 131/147/138 302/340/309 130/146/137 +f 120/133/127 130/146/137 298/336/305 +f 298/336/305 130/146/137 302/340/309 +f 303/341/310 194/217/201 304/342/311 +f 304/342/311 194/217/201 196/219/203 +f 194/228/201 303/343/310 202/227/209 +f 202/227/209 303/343/310 305/344/312 +f 300/338/307 306/345/313 117/130/124 +f 117/130/124 306/345/313 115/128/122 +f 202/227/209 305/344/312 200/224/207 +f 200/224/207 305/344/312 307/346/314 +f 200/224/207 307/346/314 201/226/208 +f 201/226/208 307/346/314 308/347/315 +f 201/226/208 308/347/315 208/236/215 +f 208/236/215 308/347/315 309/348/316 +f 207/235/214 208/236/215 310/349/317 +f 310/349/317 208/236/215 309/348/316 +f 311/350/318 312/351/319 213/243/220 +f 213/243/220 312/351/319 212/241/219 +f 211/239/218 212/240/219 313/352/320 +f 313/352/320 212/240/219 312/353/319 +f 310/349/317 314/354/321 207/235/214 +f 207/235/214 314/354/321 214/244/221 +f 213/243/220 214/244/221 311/350/318 +f 311/350/318 214/244/221 314/354/321 +f 315/355/322 234/268/241 316/356/323 +f 316/356/323 234/268/241 236/270/243 +f 301/339/308 131/147/138 315/355/322 +f 315/355/322 131/147/138 234/268/241 +f 316/356/323 236/270/243 317/357/324 +f 317/357/324 236/270/243 235/269/242 +f 317/357/324 235/269/242 318/358/325 +f 318/358/325 235/269/242 319/359/326 +f 319/359/326 211/239/218 318/358/325 +f 318/358/325 211/239/218 313/352/320 +f 233/267/240 320/360/327 235/269/242 +f 235/269/242 320/360/327 319/359/326 +f 210/238/217 320/360/327 205/231/212 +f 205/231/212 320/360/327 321/361/328 +f 322/362/329 321/361/328 128/144/135 +f 128/144/135 321/361/328 129/145/136 +f 322/362/329 323/363/330 204/230/211 +f 204/230/211 323/363/330 199/222/206 +f 324/364/331 323/363/330 116/129/123 +f 116/129/123 323/363/330 119/132/126 +f 324/364/331 325/365/332 197/220/204 +f 197/220/204 325/365/332 196/219/203 +f 325/365/332 115/128/122 326/366/333 +f 326/366/333 115/128/122 306/345/313 +f 325/365/332 326/366/333 196/219/203 +f 196/219/203 326/366/333 304/342/311 +f 327/367/334 263/299/270 328/368/335 +f 328/368/335 263/299/270 264/300/271 +f 329/369/336 330/370/337 254/288/261 +f 254/288/261 330/370/337 225/255/232 +f 330/370/337 331/371/338 225/255/232 +f 225/255/232 331/371/338 190/213/197 +f 332/372/339 331/371/338 192/215/199 +f 192/215/199 331/371/338 193/216/200 +f 189/212/196 332/372/339 183/206/190 +f 183/206/190 332/372/339 333/373/340 +f 334/374/341 333/373/340 185/208/192 +f 185/208/192 333/373/340 186/209/193 +f 249/283/256 241/275/248 302/340/309 +f 302/340/309 241/275/248 298/336/305 +f 250/284/257 249/283/256 301/339/308 +f 301/339/308 249/283/256 302/340/309 +f 244/278/251 263/299/270 300/338/307 +f 300/338/307 263/299/270 306/345/313 +f 241/275/248 240/274/247 298/336/305 +f 298/336/305 240/274/247 299/337/306 +f 240/274/247 244/278/251 299/337/306 +f 299/337/306 244/278/251 300/338/307 +f 315/355/322 292/330/299 301/339/308 +f 301/339/308 292/330/299 250/284/257 +f 292/330/299 315/355/322 290/328/297 +f 290/328/297 315/355/322 316/356/323 +f 263/299/270 327/367/334 306/345/313 +f 306/345/313 327/367/334 326/366/333 +f 256/290/263 255/289/262 328/368/335 +f 328/368/335 255/289/262 327/367/334 +f 307/346/314 266/302/273 308/347/315 +f 308/347/315 266/302/273 268/304/275 +f 266/302/273 307/346/314 259/295/266 +f 259/295/266 307/346/314 305/344/312 +f 257/291/264 303/341/310 255/289/262 +f 255/289/262 303/341/310 304/342/311 +f 303/343/310 257/293/264 305/344/312 +f 305/344/312 257/293/264 259/295/266 +f 272/308/279 309/348/316 268/304/275 +f 268/304/275 309/348/316 308/347/315 +f 272/308/279 274/310/281 309/348/316 +f 309/348/316 274/310/281 310/349/317 +f 274/310/281 287/325/294 310/349/317 +f 310/349/317 287/325/294 314/354/321 +f 287/325/294 280/316/287 314/354/321 +f 314/354/321 280/316/287 311/350/318 +f 296/334/303 283/319/290 297/335/304 +f 297/335/304 283/319/290 284/321/291 +f 283/319/290 296/334/303 313/352/320 +f 313/352/320 296/334/303 318/358/325 +f 280/316/287 279/315/286 311/350/318 +f 311/350/318 279/315/286 312/351/319 +f 279/320/286 283/319/290 312/353/319 +f 312/353/319 283/319/290 313/352/320 +f 317/357/324 294/332/301 316/356/323 +f 316/356/323 294/332/301 290/328/297 +f 27/37/34 335/375/342 29/39/36 +f 29/39/36 335/375/342 336/376/343 +f 335/375/342 27/37/34 337/377/344 +f 337/377/344 27/37/34 28/38/35 +f 40/50/47 338/378/345 41/51/48 +f 41/51/48 338/378/345 339/379/346 +f 338/378/345 40/50/47 336/376/343 +f 336/376/343 40/50/47 29/39/36 +f 46/56/53 340/380/347 47/57/54 +f 47/57/54 340/380/347 341/381/348 +f 340/380/347 46/56/53 339/379/346 +f 339/379/346 46/56/53 41/51/48 +f 342/382/349 343/383/350 52/62/59 +f 52/62/59 343/383/350 53/63/60 +f 341/381/348 342/382/349 47/57/54 +f 47/57/54 342/382/349 52/62/59 +f 344/384/351 345/385/352 58/68/65 +f 58/68/65 345/385/352 59/69/66 +f 343/383/350 344/384/351 53/63/60 +f 53/63/60 344/384/351 58/68/65 +f 346/386/353 347/387/354 64/74/71 +f 64/74/71 347/387/354 65/75/72 +f 345/385/352 346/386/353 59/69/66 +f 59/69/66 346/386/353 64/74/71 +f 348/388/355 349/389/356 149/168/156 +f 149/168/156 349/389/356 150/169/157 +f 149/168/156 65/75/72 348/388/355 +f 348/388/355 65/75/72 347/387/354 +f 350/390/357 351/391/358 164/187/171 +f 164/187/171 351/391/358 166/189/173 +f 164/187/171 150/169/157 350/390/357 +f 350/390/357 150/169/157 349/389/356 +f 187/210/194 352/392/359 28/38/35 +f 28/38/35 352/392/359 337/377/344 +f 353/393/360 81/91/88 176/199/183 +f 176/199/183 81/91/88 83/93/90 +f 81/91/88 353/393/360 82/92/89 +f 82/92/89 353/393/360 354/394/361 +f 353/393/360 355/395/362 354/394/361 +f 354/394/361 355/395/362 356/396/363 +f 353/393/360 176/199/183 355/395/362 +f 355/395/362 176/199/183 177/200/184 +f 357/397/364 358/398/365 177/200/184 +f 177/200/184 358/398/365 355/395/362 +f 358/398/365 359/399/366 355/395/362 +f 355/395/362 359/399/366 356/396/363 +f 359/399/366 358/398/365 360/400/367 +f 360/400/367 358/398/365 361/401/368 +f 358/398/365 357/397/364 361/401/368 +f 361/401/368 357/397/364 362/402/369 +f 363/403/370 364/404/371 171/194/178 +f 171/194/178 364/404/371 178/201/185 +f 364/404/371 357/397/364 178/201/185 +f 178/201/185 357/397/364 177/200/184 +f 357/397/364 364/404/371 362/402/369 +f 362/402/369 364/404/371 365/405/372 +f 364/404/371 363/403/370 365/405/372 +f 365/405/372 363/403/370 366/406/373 +f 367/407/374 363/403/370 172/195/179 +f 172/195/179 363/403/370 171/194/178 +f 363/403/370 367/407/374 366/406/373 +f 366/406/373 367/407/374 368/408/375 +f 368/408/375 367/407/374 369/409/376 +f 369/409/376 367/407/374 370/410/377 +f 367/407/374 172/195/179 370/410/377 +f 370/410/377 172/195/179 174/197/181 +f 369/409/376 370/410/377 371/411/378 +f 371/411/378 370/410/377 372/412/379 +f 370/410/377 174/197/181 372/412/379 +f 372/412/379 174/197/181 167/190/174 +f 166/189/173 373/413/380 167/190/174 +f 167/190/174 373/413/380 372/412/379 +f 372/412/379 373/413/380 371/411/378 +f 371/411/378 373/413/380 374/414/381 +f 351/391/358 375/415/382 166/189/173 +f 166/189/173 375/415/382 373/413/380 +f 375/415/382 376/416/383 373/413/380 +f 373/413/380 376/416/383 374/414/381 +f 134/150/141 135/151/142 237/271/244 +f 237/271/244 135/151/142 377/417/384 +f 237/271/244 216/246/223 67/77/74 +f 67/77/74 216/246/223 74/84/81 +f 377/417/384 285/323/292 237/271/244 +f 237/271/244 285/323/292 216/246/223 +f 333/373/340 334/374/341 183/206/190 +f 183/206/190 334/374/341 181/204/188 +f 333/373/340 332/372/339 186/209/193 +f 186/209/193 332/372/339 192/215/199 +f 190/213/197 331/371/338 189/212/196 +f 189/212/196 331/371/338 332/372/339 +f 331/371/338 330/370/337 193/216/200 +f 193/216/200 330/370/337 226/256/233 +f 226/256/233 330/370/337 262/298/269 +f 262/298/269 330/370/337 329/369/336 +f 326/366/333 327/367/334 304/342/311 +f 304/342/311 327/367/334 255/289/262 +f 325/365/332 324/364/331 115/128/122 +f 115/128/122 324/364/331 116/129/123 +f 323/363/330 324/364/331 199/222/206 +f 199/222/206 324/364/331 197/220/204 +f 323/363/330 322/362/329 119/132/126 +f 119/132/126 322/362/329 128/144/135 +f 205/231/212 321/361/328 204/230/211 +f 204/230/211 321/361/328 322/362/329 +f 129/145/136 321/361/328 233/267/240 +f 233/267/240 321/361/328 320/360/327 +f 211/239/218 319/359/326 210/238/217 +f 210/238/217 319/359/326 320/360/327 +f 318/358/325 296/334/303 317/357/324 +f 317/357/324 296/334/303 294/332/301 +f 9/19/16 10/20/17 378/418/385 +f 378/418/385 10/20/17 379/419/386 +f 10/20/17 24/34/31 379/419/386 +f 379/419/386 24/34/31 380/420/387 +f 24/34/31 26/36/33 380/420/387 +f 380/420/387 26/36/33 381/421/388 +f 335/375/342 382/422/389 336/376/343 +f 336/376/343 382/422/389 383/423/390 +f 337/377/344 384/424/391 335/375/342 +f 335/375/342 384/424/391 382/422/389 +f 338/378/345 385/425/392 339/379/346 +f 339/379/346 385/425/392 386/426/393 +f 338/378/345 336/376/343 385/425/392 +f 385/425/392 336/376/343 383/423/390 +f 340/380/347 387/427/394 341/381/348 +f 341/381/348 387/427/394 388/428/395 +f 339/379/346 386/426/393 340/380/347 +f 340/380/347 386/426/393 387/427/394 +f 342/382/349 389/429/396 343/383/350 +f 343/383/350 389/429/396 390/430/397 +f 341/381/348 388/428/395 342/382/349 +f 342/382/349 388/428/395 389/429/396 +f 344/384/351 391/431/398 345/385/352 +f 345/385/352 391/431/398 392/432/399 +f 343/383/350 390/430/397 344/384/351 +f 344/384/351 390/430/397 391/431/398 +f 347/387/354 346/386/353 393/433/400 +f 393/433/400 346/386/353 394/434/401 +f 345/385/352 392/432/399 346/386/353 +f 346/386/353 392/432/399 394/434/401 +f 395/435/402 396/436/403 397/437/404 +f 397/437/404 396/436/403 398/438/405 +f 399/439/406 400/440/407 395/435/402 +f 395/435/402 400/440/407 396/436/403 +f 401/441/408 402/441/409 399/439/406 +f 399/439/406 402/441/409 400/440/407 +f 86/96/93 87/97/94 403/442/410 +f 403/442/410 87/97/94 404/443/411 +f 405/444/412 404/445/411 406/446/413 +f 406/446/413 404/445/411 407/447/414 +f 95/108/102 96/109/103 408/448/415 +f 408/448/415 96/109/103 409/449/416 +f 96/109/103 86/96/93 409/449/416 +f 409/449/416 86/96/93 403/442/410 +f 26/36/33 112/125/119 381/421/388 +f 381/421/388 112/125/119 410/450/417 +f 411/451/418 412/452/419 413/453/420 +f 413/453/420 412/452/419 414/454/421 +f 415/455/422 416/456/423 417/457/424 +f 417/457/424 416/456/423 418/458/425 +f 397/437/404 398/438/405 415/459/422 +f 415/459/422 398/438/405 416/460/423 +f 348/388/355 419/461/426 349/389/356 +f 349/389/356 419/461/426 420/462/427 +f 347/387/354 393/433/400 348/388/355 +f 348/388/355 393/433/400 419/461/426 +f 421/463/428 422/464/429 407/447/414 +f 407/447/414 422/464/429 406/446/413 +f 417/457/424 418/458/425 421/463/428 +f 421/463/428 418/458/425 422/464/429 +f 127/177/134 157/178/164 423/465/430 +f 423/465/430 157/178/164 424/466/431 +f 157/178/164 159/180/166 424/466/431 +f 424/466/431 159/180/166 425/467/432 +f 159/180/166 163/186/170 425/467/432 +f 425/467/432 163/186/170 426/468/433 +f 163/186/170 95/108/102 426/468/433 +f 426/468/433 95/108/102 408/448/415 +f 350/390/357 427/469/434 351/391/358 +f 351/391/358 427/469/434 428/470/435 +f 349/389/356 420/462/427 350/390/357 +f 350/390/357 420/462/427 427/469/434 +f 429/471/436 430/471/437 401/441/408 +f 401/441/408 430/471/437 402/441/409 +f 431/472/438 432/473/439 429/471/436 +f 429/471/436 432/473/439 430/471/437 +f 352/392/359 433/474/440 337/377/344 +f 337/377/344 433/474/440 384/424/391 +f 434/475/441 435/476/442 431/472/438 +f 431/472/438 435/476/442 432/473/439 +f 436/477/443 437/478/444 434/475/441 +f 434/475/441 437/478/444 435/476/442 +f 376/416/383 375/415/382 438/479/445 +f 438/479/445 375/415/382 439/480/446 +f 375/415/382 351/391/358 439/480/446 +f 439/480/446 351/391/358 428/470/435 +f 440/481/447 441/482/448 442/483/449 +f 442/483/449 441/482/448 443/484/450 +f 444/485/451 440/481/447 445/486/452 +f 445/486/452 440/481/447 442/483/449 +f 446/487/453 444/485/451 447/488/454 +f 447/488/454 444/485/451 445/486/452 +f 448/489/455 446/487/453 449/490/456 +f 449/490/456 446/487/453 447/488/454 +f 450/491/457 451/492/458 452/493/459 +f 452/493/459 451/492/458 453/494/460 +f 451/492/458 454/495/461 453/494/460 +f 453/494/460 454/495/461 455/496/462 +f 441/482/448 440/481/447 456/28/463 +f 456/28/463 440/481/447 457/497/464 +f 440/481/447 444/485/451 457/497/464 +f 457/497/464 444/485/451 458/498/465 +f 459/499/466 460/500/467 458/498/465 +f 458/498/465 460/500/467 457/497/464 +f 460/500/467 461/501/468 457/497/464 +f 457/497/464 461/501/468 456/28/463 +f 444/485/451 446/487/453 458/498/465 +f 458/498/465 446/487/453 462/502/469 +f 446/487/453 448/489/455 462/502/469 +f 462/502/469 448/489/455 463/503/470 +f 464/504/471 465/505/472 463/503/470 +f 463/503/470 465/505/472 462/502/469 +f 465/505/472 459/499/466 462/502/469 +f 462/502/469 459/499/466 458/498/465 +f 454/495/461 451/492/458 466/506/473 +f 466/506/473 451/492/458 467/507/474 +f 451/492/458 450/491/457 467/507/474 +f 467/507/474 450/491/457 468/508/475 +f 469/509/476 470/510/477 471/511/478 +f 471/511/478 470/510/477 472/512/479 +f 470/510/477 450/491/457 472/512/479 +f 472/512/479 450/491/457 452/493/459 +f 461/501/468 460/500/467 473/513/480 +f 473/513/480 460/500/467 474/514/481 +f 460/500/467 459/499/466 474/514/481 +f 474/514/481 459/499/466 475/515/482 +f 476/516/483 477/517/484 475/515/482 +f 475/515/482 477/517/484 474/514/481 +f 477/517/484 478/518/485 474/514/481 +f 474/514/481 478/518/485 473/513/480 +f 450/491/457 470/510/477 468/508/475 +f 468/508/475 470/510/477 479/519/486 +f 470/510/477 469/509/476 479/519/486 +f 479/519/486 469/509/476 480/520/487 +f 481/521/488 469/509/476 482/522/489 +f 482/522/489 469/509/476 471/511/478 +f 483/523/490 481/521/488 484/524/491 +f 484/524/491 481/521/488 482/522/489 +f 469/509/476 481/521/488 480/520/487 +f 480/520/487 481/521/488 485/525/492 +f 481/521/488 483/523/490 485/525/492 +f 485/525/492 483/523/490 486/526/493 +f 487/527/494 488/528/495 489/529/496 +f 489/529/496 488/528/495 490/530/497 +f 490/530/497 483/523/490 489/529/496 +f 489/529/496 483/523/490 484/524/491 +f 483/523/490 490/530/497 486/526/493 +f 486/526/493 490/530/497 491/531/498 +f 488/528/495 492/532/499 490/530/497 +f 490/530/497 492/532/499 491/531/498 +f 493/533/500 494/534/501 495/535/502 +f 495/535/502 494/534/501 496/536/503 +f 488/528/495 487/527/494 496/536/503 +f 496/536/503 487/527/494 495/535/502 +f 492/532/499 488/528/495 497/537/504 +f 497/537/504 488/528/495 496/536/503 +f 494/534/501 498/538/505 496/536/503 +f 496/536/503 498/538/505 497/537/504 +f 499/539/506 500/540/507 501/541/508 +f 501/541/508 500/540/507 502/542/509 +f 494/534/501 493/533/500 502/542/509 +f 502/542/509 493/533/500 501/541/508 +f 498/538/505 494/534/501 503/543/510 +f 503/543/510 494/534/501 502/542/509 +f 500/540/507 504/544/511 502/542/509 +f 502/542/509 504/544/511 503/543/510 +f 505/545/512 506/546/513 507/547/514 +f 507/547/514 506/546/513 508/548/515 +f 506/546/513 509/549/516 508/548/515 +f 508/548/515 509/549/516 510/550/517 +f 511/551/518 512/552/519 510/550/517 +f 510/550/517 512/552/519 508/548/515 +f 512/552/519 513/553/520 508/548/515 +f 508/548/515 513/553/520 507/547/514 +f 514/554/521 515/555/522 516/556/523 +f 516/556/523 515/555/522 517/557/524 +f 515/555/522 518/558/525 517/557/524 +f 517/557/524 518/558/525 519/559/526 +f 509/549/516 506/546/513 519/559/526 +f 519/559/526 506/546/513 517/557/524 +f 506/546/513 505/545/512 517/557/524 +f 517/557/524 505/545/512 516/556/523 +f 519/559/526 518/558/525 520/560/527 +f 520/560/527 518/558/525 521/561/528 +f 519/559/526 520/560/527 509/549/516 +f 509/549/516 520/560/527 522/562/529 +f 523/563/530 524/564/531 525/565/532 +f 525/565/532 524/564/531 526/566/533 +f 526/567/533 527/568/534 525/569/532 +f 525/569/532 527/568/534 528/570/535 +f 529/571/536 530/572/537 528/570/535 +f 528/570/535 530/572/537 525/569/532 +f 531/573/538 523/563/530 530/574/537 +f 530/574/537 523/563/530 525/565/532 +f 532/575/539 533/576/540 534/577/541 +f 534/577/541 533/576/540 535/578/542 +f 524/564/531 523/563/530 535/578/542 +f 535/578/542 523/563/530 534/577/541 +f 523/563/530 531/573/538 534/577/541 +f 534/577/541 531/573/538 536/579/543 +f 537/580/544 532/575/539 536/579/543 +f 536/579/543 532/575/539 534/577/541 +f 538/581/545 537/580/544 539/582/546 +f 539/582/546 537/580/544 536/579/543 +f 531/573/538 540/583/547 536/579/543 +f 536/579/543 540/583/547 539/582/546 +f 540/583/547 541/584/548 539/582/546 +f 539/582/546 541/584/548 542/585/549 +f 543/586/550 538/581/545 542/585/549 +f 542/585/549 538/581/545 539/582/546 +f 544/587/551 545/588/552 546/589/553 +f 546/589/553 545/588/552 547/590/554 +f 547/590/554 548/591/555 546/589/553 +f 546/589/553 548/591/555 549/592/556 +f 537/580/544 538/581/545 549/592/556 +f 549/592/556 538/581/545 546/589/553 +f 543/586/550 544/587/551 538/581/545 +f 538/581/545 544/587/551 546/589/553 +f 459/499/466 465/505/472 475/515/482 +f 475/515/482 465/505/472 550/593/557 +f 465/505/472 464/504/471 550/593/557 +f 550/593/557 464/504/471 551/594/558 +f 552/595/559 553/596/560 551/594/558 +f 551/594/558 553/596/560 550/593/557 +f 553/596/560 476/516/483 550/593/557 +f 550/593/557 476/516/483 475/515/482 +f 554/597/561 555/598/562 556/599/563 +f 556/599/563 555/598/562 557/600/564 +f 558/601/565 559/602/566 557/600/564 +f 557/600/564 559/602/566 556/599/563 +f 477/517/484 476/516/483 560/603/567 +f 560/603/567 476/516/483 561/604/568 +f 545/605/552 544/606/551 561/604/568 +f 561/604/568 544/606/551 560/603/567 +f 544/606/551 543/607/550 560/603/567 +f 560/603/567 543/607/550 562/608/569 +f 478/518/485 477/517/484 562/608/569 +f 562/608/569 477/517/484 560/603/567 +f 553/596/560 552/595/559 563/609/570 +f 563/609/570 552/595/559 564/610/571 +f 565/611/572 566/612/573 564/610/571 +f 564/610/571 566/612/573 563/609/570 +f 566/612/573 545/605/552 563/609/570 +f 563/609/570 545/605/552 561/604/568 +f 476/516/483 553/596/560 561/604/568 +f 561/604/568 553/596/560 563/609/570 +f 567/613/574 568/614/575 569/615/576 +f 569/615/576 568/614/575 570/616/577 +f 559/602/566 558/601/565 570/616/577 +f 570/616/577 558/601/565 569/615/576 +f 571/617/578 572/618/579 573/619/580 +f 573/619/580 572/618/579 574/620/581 +f 575/621/582 514/554/521 576/622/583 +f 576/622/583 514/554/521 516/556/523 +f 505/545/512 577/623/584 516/556/523 +f 516/556/523 577/623/584 576/622/583 +f 577/624/584 578/625/585 576/626/583 +f 576/626/583 578/625/585 579/627/586 +f 580/628/587 575/629/582 579/627/586 +f 579/627/586 575/629/582 576/626/583 +f 581/630/588 582/631/589 583/632/590 +f 583/632/590 582/631/589 584/633/591 +f 500/540/507 499/539/506 584/633/591 +f 584/633/591 499/539/506 583/632/590 +f 585/634/592 513/553/520 586/635/593 +f 586/635/593 513/553/520 512/552/519 +f 511/551/518 587/636/594 512/552/519 +f 512/552/519 587/636/594 586/635/593 +f 587/636/594 581/630/588 586/635/593 +f 586/635/593 581/630/588 583/632/590 +f 499/539/506 585/634/592 583/632/590 +f 583/632/590 585/634/592 586/635/593 +f 504/544/511 500/540/507 588/637/595 +f 588/637/595 500/540/507 584/633/591 +f 582/631/589 589/638/596 584/633/591 +f 584/633/591 589/638/596 588/637/595 +f 590/639/597 510/550/517 522/562/529 +f 522/562/529 510/550/517 509/549/516 +f 591/640/598 511/551/518 590/639/597 +f 590/639/597 511/551/518 510/550/517 +f 592/641/599 529/571/536 593/642/600 +f 593/642/600 529/571/536 528/570/535 +f 527/568/534 594/643/601 528/570/535 +f 528/570/535 594/643/601 593/642/600 +f 594/643/601 580/628/587 593/642/600 +f 593/642/600 580/628/587 579/627/586 +f 578/625/585 592/641/599 579/627/586 +f 579/627/586 592/641/599 593/642/600 +f 566/644/573 565/645/572 595/646/602 +f 595/646/602 565/645/572 596/647/603 +f 597/648/604 598/649/605 596/647/603 +f 596/647/603 598/649/605 595/646/602 +f 598/649/605 548/591/555 595/646/602 +f 595/646/602 548/591/555 547/590/554 +f 545/588/552 566/644/573 547/590/554 +f 547/590/554 566/644/573 595/646/602 +f 592/641/599 578/625/585 599/650/606 +f 599/650/606 578/625/585 600/651/607 +f 541/584/548 540/583/547 600/652/607 +f 600/652/607 540/583/547 599/653/606 +f 531/573/538 530/574/537 540/583/547 +f 540/583/547 530/574/537 599/653/606 +f 530/572/537 529/571/536 599/650/606 +f 599/650/606 529/571/536 592/641/599 +f 548/591/555 598/649/605 549/592/556 +f 549/592/556 598/649/605 601/654/608 +f 598/649/605 597/648/604 601/654/608 +f 601/654/608 597/648/604 602/655/609 +f 533/576/540 532/575/539 602/655/609 +f 602/655/609 532/575/539 601/654/608 +f 532/575/539 537/580/544 601/654/608 +f 601/654/608 537/580/544 549/592/556 +f 589/638/596 582/631/589 603/656/610 +f 603/656/610 582/631/589 604/657/611 +f 605/658/612 606/659/613 604/657/611 +f 604/657/611 606/659/613 603/656/610 +f 591/640/598 607/660/614 608/661/615 +f 608/661/615 607/660/614 609/662/616 +f 607/660/614 610/663/617 609/662/616 +f 609/662/616 610/663/617 611/664/618 +f 611/664/618 612/665/619 609/662/616 +f 609/662/616 612/665/619 613/666/620 +f 613/666/620 581/630/588 609/662/616 +f 609/662/616 581/630/588 608/661/615 +f 612/665/619 605/658/612 613/666/620 +f 613/666/620 605/658/612 604/657/611 +f 582/631/589 581/630/588 604/657/611 +f 604/657/611 581/630/588 613/666/620 +f 607/660/614 591/640/598 614/198/621 +f 614/198/621 591/640/598 590/639/597 +f 522/562/529 615/667/622 590/639/597 +f 590/639/597 615/667/622 614/198/621 +f 615/667/622 616/668/623 614/198/621 +f 614/198/621 616/668/623 617/669/624 +f 610/663/617 607/660/614 617/669/624 +f 617/669/624 607/660/614 614/198/621 +f 454/495/461 618/670/625 455/496/462 +f 455/496/462 618/670/625 619/671/626 +f 620/672/627 621/673/628 622/674/629 +f 622/674/629 621/673/628 623/675/630 +f 455/496/462 619/671/626 623/675/630 +f 623/675/630 619/671/626 622/674/629 +f 441/482/448 624/676/631 443/484/450 +f 443/484/450 624/676/631 625/677/632 +f 618/670/625 454/495/461 626/678/633 +f 626/678/633 454/495/461 466/506/473 +f 621/673/628 627/679/634 623/675/630 +f 623/675/630 627/679/634 628/680/635 +f 627/679/634 629/681/636 628/680/635 +f 628/680/635 629/681/636 630/682/637 +f 452/493/459 453/494/460 630/682/637 +f 630/682/637 453/494/460 628/680/635 +f 453/494/460 455/496/462 628/680/635 +f 628/680/635 455/496/462 623/675/630 +f 624/676/631 441/482/448 631/683/638 +f 631/683/638 441/482/448 456/28/463 +f 461/501/468 632/684/639 456/28/463 +f 456/28/463 632/684/639 631/683/638 +f 633/685/640 634/686/641 635/687/642 +f 635/687/642 634/686/641 636/688/643 +f 637/689/644 638/690/645 636/688/643 +f 636/688/643 638/690/645 635/687/642 +f 639/691/646 640/692/647 638/693/645 +f 638/693/645 640/692/647 635/223/642 +f 640/692/647 641/694/648 635/223/642 +f 635/223/642 641/694/648 633/695/640 +f 638/690/645 637/689/644 642/696/649 +f 642/696/649 637/689/644 643/697/650 +f 644/698/651 645/699/652 643/697/650 +f 643/697/650 645/699/652 642/696/649 +f 645/700/652 646/701/653 642/702/649 +f 642/702/649 646/701/653 647/703/654 +f 647/703/654 639/691/646 642/702/649 +f 642/702/649 639/691/646 638/693/645 +f 645/699/652 644/698/651 648/704/655 +f 648/704/655 644/698/651 649/705/656 +f 649/705/656 650/706/657 648/704/655 +f 648/704/655 650/706/657 651/707/658 +f 651/708/658 652/709/659 648/710/655 +f 648/710/655 652/709/659 653/711/660 +f 646/701/653 645/700/652 653/711/660 +f 653/711/660 645/700/652 648/710/655 +f 513/553/520 585/634/592 654/712/661 +f 654/712/661 585/634/592 655/713/662 +f 585/634/592 499/539/506 655/713/662 +f 655/713/662 499/539/506 501/541/508 +f 493/533/500 656/714/663 501/541/508 +f 501/541/508 656/714/663 655/713/662 +f 511/551/518 591/640/598 587/636/594 +f 587/636/594 591/640/598 608/661/615 +f 608/661/615 581/630/588 587/636/594 +f 656/714/663 493/533/500 657/715/664 +f 657/715/664 493/533/500 495/535/502 +f 487/527/494 658/716/665 495/535/502 +f 495/535/502 658/716/665 657/715/664 +f 658/716/665 487/527/494 659/717/666 +f 659/717/666 487/527/494 489/529/496 +f 489/529/496 484/524/491 659/717/666 +f 659/717/666 484/524/491 660/718/667 +f 484/524/491 482/522/489 660/718/667 +f 660/718/667 482/522/489 661/719/668 +f 482/522/489 471/511/478 661/719/668 +f 661/719/668 471/511/478 662/720/669 +f 629/681/636 663/721/670 630/682/637 +f 630/682/637 663/721/670 664/722/671 +f 471/511/478 472/512/479 662/720/669 +f 662/720/669 472/512/479 664/722/671 +f 472/512/479 452/493/459 664/722/671 +f 664/722/671 452/493/459 630/682/637 +f 632/684/639 461/501/468 665/723/672 +f 665/723/672 461/501/468 473/513/480 +f 478/518/485 666/724/673 473/513/480 +f 473/513/480 666/724/673 665/723/672 +f 666/724/673 478/518/485 667/725/674 +f 667/725/674 478/518/485 562/608/569 +f 543/607/550 668/726/675 562/608/569 +f 562/608/569 668/726/675 667/725/674 +f 541/727/548 669/728/676 542/729/549 +f 542/729/549 669/728/676 670/730/677 +f 668/726/675 543/607/550 670/730/677 +f 670/730/677 543/607/550 542/729/549 +f 541/727/548 600/731/607 669/728/676 +f 669/728/676 600/731/607 671/732/678 +f 600/731/607 578/733/585 671/732/678 +f 671/732/678 578/733/585 574/620/581 +f 567/613/574 672/734/679 568/614/575 +f 568/614/575 672/734/679 673/735/680 +f 674/736/681 673/735/680 675/737/682 +f 675/737/682 673/735/680 672/734/679 +f 578/733/585 577/623/584 574/620/581 +f 574/620/581 577/623/584 573/619/580 +f 676/738/683 573/619/580 507/547/514 +f 573/619/580 577/623/584 507/547/514 +f 577/623/584 505/545/512 507/547/514 +f 668/726/675 677/739/684 667/725/674 +f 667/725/674 677/739/684 678/740/685 +f 679/741/686 680/742/687 681/743/688 +f 681/743/688 680/742/687 682/744/689 +f 683/745/690 684/746/691 679/741/686 +f 679/741/686 684/746/691 680/742/687 +f 685/747/692 666/724/673 678/740/685 +f 678/740/685 666/724/673 667/725/674 +f 669/728/676 686/748/693 670/730/677 +f 670/730/677 686/748/693 687/749/694 +f 688/750/695 689/751/696 690/752/697 +f 690/752/697 689/751/696 691/753/698 +f 681/743/688 682/744/689 688/750/695 +f 688/750/695 682/744/689 689/751/696 +f 677/739/684 668/726/675 687/749/694 +f 687/749/694 668/726/675 670/730/677 +f 664/722/671 663/721/670 692/754/699 +f 692/754/699 663/721/670 693/755/700 +f 694/756/701 695/757/702 696/758/703 +f 696/758/703 695/757/702 697/759/704 +f 695/760/702 698/761/705 697/762/704 +f 697/762/704 698/761/705 699/763/706 +f 662/720/669 664/722/671 700/764/707 +f 700/764/707 664/722/671 692/754/699 +f 666/724/673 685/747/692 665/723/672 +f 665/723/672 685/747/692 701/765/708 +f 702/766/709 703/767/710 683/745/690 +f 683/745/690 703/767/710 684/746/691 +f 661/719/668 662/720/669 704/768/711 +f 704/768/711 662/720/669 700/764/707 +f 698/761/705 705/769/712 699/763/706 +f 699/763/706 705/769/712 706/770/713 +f 705/769/712 707/771/714 706/770/713 +f 706/770/713 707/771/714 708/772/715 +f 660/718/667 661/719/668 709/773/716 +f 709/773/716 661/719/668 704/768/711 +f 659/717/666 660/718/667 710/774/717 +f 710/774/717 660/718/667 709/773/716 +f 707/771/714 711/775/718 708/772/715 +f 708/772/715 711/775/718 712/776/719 +f 713/777/720 714/778/721 711/775/718 +f 711/775/718 714/778/721 712/776/719 +f 715/779/722 658/716/665 710/774/717 +f 710/774/717 658/716/665 659/717/666 +f 656/714/663 716/780/723 655/713/662 +f 655/713/662 716/780/723 717/781/724 +f 718/782/725 719/783/726 720/784/727 +f 720/784/727 719/783/726 721/785/728 +f 722/786/729 723/787/730 718/788/725 +f 718/788/725 723/787/730 719/789/726 +f 724/790/731 654/712/661 717/781/724 +f 717/781/724 654/712/661 655/713/662 +f 658/716/665 715/779/722 657/715/664 +f 657/715/664 715/779/722 725/791/732 +f 726/792/733 727/793/734 713/777/720 +f 713/777/720 727/793/734 714/778/721 +f 720/784/727 721/785/728 726/792/733 +f 726/792/733 721/785/728 727/793/734 +f 716/780/723 656/714/663 725/791/732 +f 725/791/732 656/714/663 657/715/664 +f 671/732/678 574/620/581 728/794/735 +f 728/794/735 574/620/581 572/618/579 +f 729/795/736 730/796/737 731/797/738 +f 731/797/738 730/796/737 732/798/739 +f 730/796/737 690/752/697 732/798/739 +f 732/798/739 690/752/697 691/753/698 +f 669/728/676 671/732/678 686/748/693 +f 686/748/693 671/732/678 728/794/735 +f 733/799/740 729/795/736 734/800/741 +f 734/800/741 729/795/736 731/797/738 +f 735/801/742 733/799/740 736/802/743 +f 736/802/743 733/799/740 734/800/741 +f 737/803/744 558/601/565 738/804/745 +f 738/804/745 558/601/565 557/600/564 +f 738/804/745 557/600/564 739/805/746 +f 739/805/746 557/600/564 555/598/562 +f 740/806/747 567/613/574 741/807/748 +f 741/807/748 567/613/574 569/615/576 +f 741/807/748 569/615/576 737/803/744 +f 737/803/744 569/615/576 558/601/565 +f 742/808/749 743/809/750 633/685/640 +f 633/685/640 743/809/750 634/686/641 +f 633/695/640 641/694/648 742/810/749 +f 742/810/749 641/694/648 744/811/751 +f 739/805/746 555/598/562 745/812/752 +f 745/812/752 555/598/562 554/597/561 +f 746/813/753 744/811/751 640/692/647 +f 640/692/647 744/811/751 641/694/648 +f 640/692/647 639/691/646 746/813/753 +f 746/813/753 639/691/646 747/814/754 +f 748/815/755 747/814/754 647/703/654 +f 647/703/654 747/814/754 639/691/646 +f 748/815/755 647/703/654 749/816/756 +f 749/816/756 647/703/654 646/701/653 +f 750/817/757 652/709/659 751/818/758 +f 751/818/758 652/709/659 651/708/658 +f 751/819/758 651/707/658 752/820/759 +f 752/820/759 651/707/658 650/706/657 +f 749/816/756 646/701/653 753/821/760 +f 753/821/760 646/701/653 653/711/660 +f 753/821/760 653/711/660 750/817/757 +f 750/817/757 653/711/660 652/709/659 +f 754/822/761 755/823/762 672/734/679 +f 672/734/679 755/823/762 675/737/682 +f 672/734/679 567/613/574 754/822/761 +f 754/822/761 567/613/574 740/806/747 +f 755/823/762 756/824/763 675/737/682 +f 675/737/682 756/824/763 674/736/681 +f 756/824/763 757/825/764 674/736/681 +f 674/736/681 757/825/764 758/826/765 +f 752/820/759 650/706/657 757/825/764 +f 757/825/764 650/706/657 758/826/765 +f 673/735/680 674/736/681 759/827/766 +f 759/827/766 674/736/681 758/826/765 +f 644/698/651 760/828/767 649/705/656 +f 649/705/656 760/828/767 759/827/766 +f 568/614/575 760/828/767 570/616/577 +f 570/616/577 760/828/767 761/829/768 +f 637/689/644 762/830/769 643/697/650 +f 643/697/650 762/830/769 761/829/768 +f 559/602/566 762/830/769 556/599/563 +f 556/599/563 762/830/769 763/831/770 +f 634/686/641 764/832/771 636/688/643 +f 636/688/643 764/832/771 763/831/770 +f 745/812/752 554/597/561 765/833/772 +f 765/833/772 554/597/561 764/832/771 +f 743/809/750 765/833/772 634/686/641 +f 634/686/641 765/833/772 764/832/771 +f 703/767/710 702/766/709 766/834/773 +f 766/834/773 702/766/709 767/835/774 +f 663/721/670 768/836/775 693/755/700 +f 693/755/700 768/836/775 769/837/776 +f 629/681/636 770/838/777 663/721/670 +f 663/721/670 770/838/777 768/836/775 +f 632/684/639 770/838/777 631/683/638 +f 631/683/638 770/838/777 771/839/778 +f 627/679/634 621/673/628 771/839/778 +f 771/839/778 621/673/628 772/840/779 +f 624/676/631 772/840/779 625/677/632 +f 625/677/632 772/840/779 773/841/780 +f 737/803/744 681/743/688 741/807/748 +f 741/807/748 681/743/688 688/750/695 +f 690/752/697 740/806/747 688/750/695 +f 688/750/695 740/806/747 741/807/748 +f 683/745/690 739/805/746 702/766/709 +f 702/766/709 739/805/746 745/812/752 +f 681/743/688 737/803/744 679/741/686 +f 679/741/686 737/803/744 738/804/745 +f 739/805/746 683/745/690 738/804/745 +f 738/804/745 683/745/690 679/741/686 +f 754/822/761 740/806/747 730/796/737 +f 730/796/737 740/806/747 690/752/697 +f 755/823/762 754/822/761 729/795/736 +f 729/795/736 754/822/761 730/796/737 +f 702/766/709 745/812/752 767/835/774 +f 767/835/774 745/812/752 765/833/772 +f 767/835/774 694/756/701 766/834/773 +f 766/834/773 694/756/701 696/758/703 +f 746/813/753 747/814/754 705/769/712 +f 705/769/712 747/814/754 707/771/714 +f 744/811/751 746/813/753 698/761/705 +f 698/761/705 746/813/753 705/769/712 +f 743/809/750 742/808/749 694/756/701 +f 694/756/701 742/808/749 695/757/702 +f 742/810/749 744/811/751 695/760/702 +f 695/760/702 744/811/751 698/761/705 +f 747/814/754 748/815/755 707/771/714 +f 707/771/714 748/815/755 711/775/718 +f 749/816/756 713/777/720 748/815/755 +f 748/815/755 713/777/720 711/775/718 +f 713/777/720 749/816/756 726/792/733 +f 726/792/733 749/816/756 753/821/760 +f 750/817/757 720/784/727 753/821/760 +f 753/821/760 720/784/727 726/792/733 +f 735/801/742 736/802/743 722/786/729 +f 722/786/729 736/802/743 723/787/730 +f 722/786/729 752/820/759 735/801/742 +f 735/801/742 752/820/759 757/825/764 +f 720/784/727 750/817/757 718/782/725 +f 718/782/725 750/817/757 751/818/758 +f 752/820/759 722/786/729 751/819/758 +f 751/819/758 722/786/729 718/788/725 +f 756/824/763 755/823/762 733/799/740 +f 733/799/740 755/823/762 729/795/736 +f 774/842/781 448/489/455 775/843/782 +f 775/843/782 448/489/455 449/490/456 +f 448/489/455 774/842/781 463/503/470 +f 463/503/470 774/842/781 776/844/783 +f 777/845/784 464/504/471 776/844/783 +f 776/844/783 464/504/471 463/503/470 +f 467/507/474 468/508/475 382/422/389 +f 382/422/389 468/508/475 383/423/390 +f 466/506/473 467/507/474 384/424/391 +f 384/424/391 467/507/474 382/422/389 +f 479/519/486 480/520/487 385/425/392 +f 385/425/392 480/520/487 386/426/393 +f 468/508/475 479/519/486 383/423/390 +f 383/423/390 479/519/486 385/425/392 +f 486/526/493 388/428/395 485/525/492 +f 485/525/492 388/428/395 387/427/394 +f 480/520/487 485/525/492 386/426/393 +f 386/426/393 485/525/492 387/427/394 +f 492/532/499 390/430/397 491/531/498 +f 491/531/498 390/430/397 389/429/396 +f 388/428/395 486/526/493 389/429/396 +f 389/429/396 486/526/493 491/531/498 +f 498/538/505 392/432/399 497/537/504 +f 497/537/504 392/432/399 391/431/398 +f 390/430/397 492/532/499 391/431/398 +f 391/431/398 492/532/499 497/537/504 +f 504/544/511 393/433/400 503/543/510 +f 503/543/510 393/433/400 394/434/401 +f 392/432/399 498/538/505 394/434/401 +f 394/434/401 498/538/505 503/543/510 +f 515/555/522 514/554/521 396/436/403 +f 396/436/403 514/554/521 398/438/405 +f 518/558/525 515/555/522 400/440/407 +f 400/440/407 515/555/522 396/436/403 +f 518/558/525 400/440/407 521/561/528 +f 521/561/528 400/440/407 402/441/409 +f 524/564/531 778/846/785 526/566/533 +f 526/566/533 778/846/785 405/847/412 +f 406/446/413 527/568/534 405/444/412 +f 405/444/412 527/568/534 526/567/533 +f 533/576/540 779/848/786 535/578/542 +f 535/578/542 779/848/786 780/849/787 +f 778/846/785 524/564/531 780/849/787 +f 780/849/787 524/564/531 535/578/542 +f 464/504/471 777/845/784 551/594/558 +f 551/594/558 777/845/784 781/850/788 +f 411/451/418 552/595/559 781/850/788 +f 781/850/788 552/595/559 551/594/558 +f 552/595/559 411/451/418 564/610/571 +f 564/610/571 411/451/418 413/453/420 +f 782/851/789 565/611/572 413/453/420 +f 413/453/420 565/611/572 564/610/571 +f 580/628/587 418/458/425 575/629/582 +f 575/629/582 418/458/425 416/456/423 +f 398/438/405 514/554/521 416/460/423 +f 416/460/423 514/554/521 575/621/582 +f 589/638/596 420/462/427 588/637/595 +f 588/637/595 420/462/427 419/461/426 +f 588/637/595 419/461/426 504/544/511 +f 504/544/511 419/461/426 393/433/400 +f 594/643/601 527/568/534 422/464/429 +f 422/464/429 527/568/534 406/446/413 +f 580/628/587 594/643/601 418/458/425 +f 418/458/425 594/643/601 422/464/429 +f 565/645/572 782/852/789 596/647/603 +f 596/647/603 782/852/789 783/853/790 +f 784/854/791 597/648/604 783/853/790 +f 783/853/790 597/648/604 596/647/603 +f 597/648/604 784/854/791 602/655/609 +f 602/655/609 784/854/791 785/855/792 +f 779/848/786 533/576/540 785/855/792 +f 785/855/792 533/576/540 602/655/609 +f 606/659/613 428/470/435 603/656/610 +f 603/656/610 428/470/435 427/469/434 +f 603/656/610 427/469/434 589/638/596 +f 589/638/596 427/469/434 420/462/427 +f 521/561/528 402/441/409 786/856/793 +f 786/856/793 402/441/409 430/471/437 +f 432/473/439 787/857/794 430/471/437 +f 430/471/437 787/857/794 786/856/793 +f 626/678/633 466/506/473 433/474/440 +f 433/474/440 466/506/473 384/424/391 +f 522/562/529 520/560/527 615/667/622 +f 615/667/622 520/560/527 788/858/795 +f 520/560/527 521/561/528 788/858/795 +f 788/858/795 521/561/528 786/856/793 +f 787/857/794 789/859/796 786/856/793 +f 786/856/793 789/859/796 788/858/795 +f 789/859/796 616/668/623 788/858/795 +f 788/858/795 616/668/623 615/667/622 +f 787/857/794 432/473/439 790/860/797 +f 790/860/797 432/473/439 435/476/442 +f 791/861/798 790/860/797 437/478/444 +f 437/478/444 790/860/797 435/476/442 +f 616/668/623 789/859/796 792/862/799 +f 792/862/799 789/859/796 793/863/800 +f 789/859/796 787/857/794 793/863/800 +f 793/863/800 787/857/794 790/860/797 +f 791/861/798 794/864/801 790/860/797 +f 790/860/797 794/864/801 793/863/800 +f 795/865/802 792/862/799 794/864/801 +f 794/864/801 792/862/799 793/863/800 +f 796/866/803 610/663/617 797/867/804 +f 797/867/804 610/663/617 617/669/624 +f 617/669/624 616/668/623 797/867/804 +f 797/867/804 616/668/623 792/862/799 +f 795/865/802 798/868/805 792/862/799 +f 792/862/799 798/868/805 797/867/804 +f 798/868/805 799/869/806 797/867/804 +f 797/867/804 799/869/806 796/866/803 +f 611/664/618 610/663/617 800/870/807 +f 800/870/807 610/663/617 796/866/803 +f 799/869/806 801/871/808 796/866/803 +f 796/866/803 801/871/808 800/870/807 +f 801/871/808 802/872/809 800/870/807 +f 800/870/807 802/872/809 803/873/810 +f 612/665/619 611/664/618 803/873/810 +f 803/873/810 611/664/618 800/870/807 +f 802/872/809 804/874/811 803/873/810 +f 803/873/810 804/874/811 805/875/812 +f 605/658/612 612/665/619 805/875/812 +f 805/875/812 612/665/619 803/873/810 +f 606/659/613 605/658/612 806/876/813 +f 806/876/813 605/658/612 805/875/812 +f 804/874/811 807/877/814 805/875/812 +f 805/875/812 807/877/814 806/876/813 +f 428/470/435 606/659/613 439/480/446 +f 439/480/446 606/659/613 806/876/813 +f 807/877/814 438/479/445 806/876/813 +f 806/876/813 438/479/445 439/480/446 +f 808/878/815 809/879/816 810/880/817 +f 810/880/817 809/879/816 811/881/818 +f 812/882/819 813/883/820 808/878/815 +f 808/878/815 813/883/820 809/879/816 +f 814/884/821 815/885/822 812/882/819 +f 812/882/819 815/885/822 813/883/820 +f 816/886/823 817/887/824 814/884/821 +f 814/884/821 817/887/824 815/885/822 +f 818/888/825 819/889/826 816/886/823 +f 816/886/823 819/889/826 817/887/824 +f 820/890/827 821/891/828 818/888/825 +f 818/888/825 821/891/828 819/889/826 +f 822/892/829 823/893/830 820/890/827 +f 820/890/827 823/893/830 821/891/828 +f 824/894/831 825/895/832 822/892/829 +f 822/892/829 825/895/832 823/893/830 +f 824/894/831 826/896/833 825/895/832 +f 825/895/832 826/896/833 827/897/834 +f 826/896/833 828/898/835 827/897/834 +f 827/897/834 828/898/835 829/899/836 +f 830/900/837 831/901/838 828/898/835 +f 828/898/835 831/901/838 829/899/836 +f 832/902/839 833/903/840 830/900/837 +f 830/900/837 833/903/840 831/901/838 +f 834/904/841 835/905/842 836/906/843 +f 836/906/843 835/905/842 837/907/844 +f 809/879/816 838/908/845 811/881/818 +f 811/881/818 838/908/845 839/909/846 +f 813/883/820 840/910/847 809/879/816 +f 809/879/816 840/910/847 838/908/845 +f 815/885/822 841/911/848 813/883/820 +f 813/883/820 841/911/848 840/910/847 +f 817/887/824 842/912/849 815/885/822 +f 815/885/822 842/912/849 841/911/848 +f 819/889/826 843/913/850 817/887/824 +f 817/887/824 843/913/850 842/912/849 +f 821/891/828 844/914/851 819/889/826 +f 819/889/826 844/914/851 843/913/850 +f 823/893/830 845/915/852 821/891/828 +f 821/891/828 845/915/852 844/914/851 +f 825/895/832 846/916/853 823/893/830 +f 823/893/830 846/916/853 845/915/852 +f 825/895/832 827/897/834 846/916/853 +f 846/916/853 827/897/834 847/917/854 +f 827/897/834 829/899/836 847/917/854 +f 847/917/854 829/899/836 848/918/855 +f 831/901/838 849/919/856 829/899/836 +f 829/899/836 849/919/856 848/918/855 +f 850/920/857 833/903/840 851/921/858 +f 851/921/858 833/903/840 837/907/844 +f 838/908/845 852/922/859 839/909/846 +f 839/909/846 852/922/859 853/923/860 +f 840/910/847 854/924/861 838/908/845 +f 838/908/845 854/924/861 852/922/859 +f 841/911/848 855/925/862 840/910/847 +f 840/910/847 855/925/862 854/924/861 +f 842/912/849 856/926/863 841/911/848 +f 841/911/848 856/926/863 855/925/862 +f 843/913/850 857/927/864 842/912/849 +f 842/912/849 857/927/864 856/926/863 +f 844/914/851 858/928/865 843/913/850 +f 843/913/850 858/928/865 857/927/864 +f 845/915/852 859/929/866 844/914/851 +f 844/914/851 859/929/866 858/928/865 +f 846/916/853 860/930/867 845/915/852 +f 845/915/852 860/930/867 859/929/866 +f 846/916/853 847/917/854 860/930/867 +f 860/930/867 847/917/854 861/931/868 +f 848/918/855 862/932/869 847/917/854 +f 847/917/854 862/932/869 861/931/868 +f 849/919/856 863/933/870 848/918/855 +f 848/918/855 863/933/870 862/932/869 +f 864/934/871 850/920/857 865/935/872 +f 865/935/872 850/920/857 851/921/858 +f 853/923/860 852/922/859 866/936/873 +f 866/936/873 852/922/859 867/937/874 +f 854/924/861 868/938/875 852/922/859 +f 852/922/859 868/938/875 867/937/874 +f 855/925/862 869/939/876 854/924/861 +f 854/924/861 869/939/876 868/938/875 +f 856/926/863 870/940/877 855/925/862 +f 855/925/862 870/940/877 869/939/876 +f 857/927/864 871/941/878 856/926/863 +f 856/926/863 871/941/878 870/940/877 +f 858/928/865 872/942/879 857/927/864 +f 857/927/864 872/942/879 871/941/878 +f 859/929/866 873/943/880 858/928/865 +f 858/928/865 873/943/880 872/942/879 +f 860/930/867 874/944/881 859/929/866 +f 859/929/866 874/944/881 873/943/880 +f 860/930/867 861/931/868 874/944/881 +f 874/944/881 861/931/868 875/945/882 +f 862/932/869 876/946/883 861/931/868 +f 861/931/868 876/946/883 875/945/882 +f 863/933/870 877/947/884 862/932/869 +f 862/932/869 877/947/884 876/946/883 +f 878/948/885 864/934/871 879/949/886 +f 879/949/886 864/934/871 865/935/872 +f 866/936/873 867/937/874 880/950/887 +f 880/950/887 867/937/874 881/951/888 +f 868/938/875 882/952/889 867/937/874 +f 867/937/874 882/952/889 881/951/888 +f 869/939/876 883/953/890 868/938/875 +f 868/938/875 883/953/890 882/952/889 +f 870/940/877 884/954/891 869/939/876 +f 869/939/876 884/954/891 883/953/890 +f 871/941/878 885/955/892 870/940/877 +f 870/940/877 885/955/892 884/954/891 +f 872/942/879 886/956/893 871/941/878 +f 871/941/878 886/956/893 885/955/892 +f 873/943/880 887/957/894 872/942/879 +f 872/942/879 887/957/894 886/956/893 +f 874/944/881 888/958/895 873/943/880 +f 873/943/880 888/958/895 887/957/894 +f 874/944/881 875/945/882 888/958/895 +f 888/958/895 875/945/882 889/959/896 +f 876/946/883 890/960/897 875/945/882 +f 875/945/882 890/960/897 889/959/896 +f 877/947/884 891/961/898 876/946/883 +f 876/946/883 891/961/898 890/960/897 +f 892/962/899 878/948/885 893/963/900 +f 893/963/900 878/948/885 879/949/886 +f 880/950/887 881/951/888 894/964/901 +f 894/964/901 881/951/888 895/965/902 +f 882/952/889 896/966/903 881/951/888 +f 881/951/888 896/966/903 895/965/902 +f 883/953/890 897/967/904 882/952/889 +f 882/952/889 897/967/904 896/966/903 +f 884/954/891 898/968/905 883/953/890 +f 883/953/890 898/968/905 897/967/904 +f 885/955/892 899/969/906 884/954/891 +f 884/954/891 899/969/906 898/968/905 +f 886/956/893 900/970/907 885/955/892 +f 885/955/892 900/970/907 899/969/906 +f 887/957/894 901/971/908 886/956/893 +f 886/956/893 901/971/908 900/970/907 +f 888/958/895 902/972/909 887/957/894 +f 887/957/894 902/972/909 901/971/908 +f 888/958/895 889/959/896 902/972/909 +f 902/972/909 889/959/896 903/973/910 +f 889/959/896 890/960/897 903/973/910 +f 903/973/910 890/960/897 904/974/911 +f 891/961/898 905/975/912 890/960/897 +f 890/960/897 905/975/912 904/974/911 +f 362/402/369 892/962/899 361/401/368 +f 361/401/368 892/962/899 893/963/900 +f 894/964/901 895/965/902 906/976/913 +f 906/976/913 895/965/902 907/977/914 +f 896/966/903 908/978/915 895/965/902 +f 895/965/902 908/978/915 907/977/914 +f 897/967/904 909/979/916 896/966/903 +f 896/966/903 909/979/916 908/978/915 +f 898/968/905 910/980/917 897/967/904 +f 897/967/904 910/980/917 909/979/916 +f 899/969/906 911/981/918 898/968/905 +f 898/968/905 911/981/918 910/980/917 +f 900/970/907 912/982/919 899/969/906 +f 899/969/906 912/982/919 911/981/918 +f 901/971/908 913/983/920 900/970/907 +f 900/970/907 913/983/920 912/982/919 +f 902/972/909 914/984/921 901/971/908 +f 901/971/908 914/984/921 913/983/920 +f 902/972/909 903/973/910 914/984/921 +f 914/984/921 903/973/910 915/985/922 +f 903/973/910 904/974/911 915/985/922 +f 915/985/922 904/974/911 916/986/923 +f 905/975/912 917/987/924 904/974/911 +f 904/974/911 917/987/924 916/986/923 +f 906/976/913 907/977/914 918/988/925 +f 918/988/925 907/977/914 919/989/926 +f 908/978/915 920/990/927 907/977/914 +f 907/977/914 920/990/927 919/989/926 +f 909/979/916 921/991/928 908/978/915 +f 908/978/915 921/991/928 920/990/927 +f 910/980/917 922/992/929 909/979/916 +f 909/979/916 922/992/929 921/991/928 +f 911/981/918 923/993/930 910/980/917 +f 910/980/917 923/993/930 922/992/929 +f 912/982/919 924/994/931 911/981/918 +f 911/981/918 924/994/931 923/993/930 +f 913/983/920 925/995/932 912/982/919 +f 912/982/919 925/995/932 924/994/931 +f 914/984/921 926/996/933 913/983/920 +f 913/983/920 926/996/933 925/995/932 +f 914/984/921 915/985/922 926/996/933 +f 926/996/933 915/985/922 927/997/934 +f 915/985/922 916/986/923 927/997/934 +f 927/997/934 916/986/923 928/998/935 +f 917/987/924 929/999/936 916/986/923 +f 916/986/923 929/999/936 928/998/935 +f 918/988/925 919/989/926 930/1000/937 +f 930/1000/937 919/989/926 931/1001/938 +f 920/990/927 932/1002/939 919/989/926 +f 919/989/926 932/1002/939 931/1001/938 +f 921/991/928 933/1003/940 920/990/927 +f 920/990/927 933/1003/940 932/1002/939 +f 922/992/929 934/1004/941 921/991/928 +f 921/991/928 934/1004/941 933/1003/940 +f 923/993/930 935/1005/942 922/992/929 +f 922/992/929 935/1005/942 934/1004/941 +f 924/994/931 936/1006/943 923/993/930 +f 923/993/930 936/1006/943 935/1005/942 +f 925/995/932 937/1007/944 924/994/931 +f 924/994/931 937/1007/944 936/1006/943 +f 926/996/933 938/1008/945 925/995/932 +f 925/995/932 938/1008/945 937/1007/944 +f 926/996/933 927/997/934 938/1008/945 +f 938/1008/945 927/997/934 939/1009/946 +f 927/997/934 928/998/935 939/1009/946 +f 939/1009/946 928/998/935 940/1010/947 +f 929/999/936 941/1011/948 928/998/935 +f 928/998/935 941/1011/948 940/1010/947 +f 930/1000/937 931/1001/938 942/1012/949 +f 942/1012/949 931/1001/938 943/1013/950 +f 932/1002/939 944/1014/951 931/1001/938 +f 931/1001/938 944/1014/951 943/1013/950 +f 933/1003/940 945/1015/952 932/1002/939 +f 932/1002/939 945/1015/952 944/1014/951 +f 934/1004/941 946/1016/953 933/1003/940 +f 933/1003/940 946/1016/953 945/1015/952 +f 935/1005/942 947/1017/954 934/1004/941 +f 934/1004/941 947/1017/954 946/1016/953 +f 936/1006/943 948/1018/955 935/1005/942 +f 935/1005/942 948/1018/955 947/1017/954 +f 937/1007/944 949/1019/956 936/1006/943 +f 936/1006/943 949/1019/956 948/1018/955 +f 937/1007/944 938/1008/945 949/1019/956 +f 949/1019/956 938/1008/945 950/1020/957 +f 938/1008/945 939/1009/946 950/1020/957 +f 950/1020/957 939/1009/946 951/1021/958 +f 939/1009/946 940/1010/947 951/1021/958 +f 951/1021/958 940/1010/947 952/1022/959 +f 940/1010/947 941/1011/948 952/1022/959 +f 952/1022/959 941/1011/948 953/1023/960 +f 942/1012/949 943/1013/950 954/1024/961 +f 954/1024/961 943/1013/950 955/1025/962 +f 944/1014/951 956/1026/963 943/1013/950 +f 943/1013/950 956/1026/963 955/1025/962 +f 945/1015/952 957/1027/964 944/1014/951 +f 944/1014/951 957/1027/964 956/1026/963 +f 946/1016/953 958/1028/965 945/1015/952 +f 945/1015/952 958/1028/965 957/1027/964 +f 947/1017/954 959/1029/966 946/1016/953 +f 946/1016/953 959/1029/966 958/1028/965 +f 948/1018/955 960/1030/967 947/1017/954 +f 947/1017/954 960/1030/967 959/1029/966 +f 949/1019/956 961/1031/968 948/1018/955 +f 948/1018/955 961/1031/968 960/1030/967 +f 949/1019/956 950/1020/957 961/1031/968 +f 961/1031/968 950/1020/957 962/1032/969 +f 950/1020/957 951/1021/958 962/1032/969 +f 962/1032/969 951/1021/958 963/1033/970 +f 952/1022/959 964/1034/971 951/1021/958 +f 951/1021/958 964/1034/971 963/1033/970 +f 952/1022/959 953/1023/960 964/1034/971 +f 964/1034/971 953/1023/960 965/1035/972 +f 954/1024/961 955/1025/962 966/1036/973 +f 966/1036/973 955/1025/962 967/1037/974 +f 955/1025/962 956/1026/963 967/1037/974 +f 967/1037/974 956/1026/963 968/1038/975 +f 956/1026/963 957/1027/964 968/1038/975 +f 968/1038/975 957/1027/964 969/1039/976 +f 957/1027/964 958/1028/965 969/1039/976 +f 969/1039/976 958/1028/965 970/1040/977 +f 959/1029/966 971/1041/978 958/1028/965 +f 958/1028/965 971/1041/978 970/1040/977 +f 960/1030/967 972/1042/979 959/1029/966 +f 959/1029/966 972/1042/979 971/1041/978 +f 961/1031/968 973/1043/980 960/1030/967 +f 960/1030/967 973/1043/980 972/1042/979 +f 961/1031/968 962/1032/969 973/1043/980 +f 973/1043/980 962/1032/969 974/1044/981 +f 963/1033/970 975/1045/982 962/1032/969 +f 962/1032/969 975/1045/982 974/1044/981 +f 964/1034/971 976/1046/983 963/1033/970 +f 963/1033/970 976/1046/983 975/1045/982 +f 965/1035/972 977/1047/984 964/1034/971 +f 964/1034/971 977/1047/984 976/1046/983 +f 966/1036/973 967/1037/974 978/1048/985 +f 978/1048/985 967/1037/974 979/1049/986 +f 967/1037/974 968/1038/975 979/1049/986 +f 979/1049/986 968/1038/975 980/1050/987 +f 968/1038/975 969/1039/976 980/1050/987 +f 980/1050/987 969/1039/976 981/1051/988 +f 972/1042/979 973/1043/980 982/1052/989 +f 974/1044/981 983/1053/990 973/1043/980 +f 973/1043/980 983/1053/990 982/1052/989 +f 975/1045/982 984/1054/991 974/1044/981 +f 974/1044/981 984/1054/991 983/1053/990 +f 976/1046/983 985/1055/992 975/1045/982 +f 975/1045/982 985/1055/992 984/1054/991 +f 977/1047/984 986/1056/993 976/1046/983 +f 976/1046/983 986/1056/993 985/1055/992 +f 978/1048/985 979/1049/986 987/1057/994 +f 987/1057/994 979/1049/986 988/1058/995 +f 979/1049/986 980/1050/987 988/1058/995 +f 988/1058/995 980/1050/987 989/1059/996 +f 987/1057/994 988/1058/995 990/1060/997 +f 990/1060/997 988/1058/995 991/1061/998 +f 989/1059/996 992/1062/999 988/1058/995 +f 988/1058/995 992/1062/999 991/1061/998 +f 993/1063/1000 994/1064/1001 984/1054/991 +f 984/1054/991 994/1064/1001 983/1053/990 +f 985/1055/992 995/1065/1002 984/1054/991 +f 984/1054/991 995/1065/1002 993/1063/1000 +f 986/1056/993 996/1066/1003 985/1055/992 +f 985/1055/992 996/1066/1003 995/1065/1002 +f 990/1060/997 991/1061/998 997/1067/1004 +f 997/1067/1004 991/1061/998 998/1068/1005 +f 992/1062/999 999/1069/1006 991/1061/998 +f 991/1061/998 999/1069/1006 998/1068/1005 +f 1000/1070/1007 994/1064/1001 1001/1071/1008 +f 1001/1071/1008 994/1064/1001 993/1063/1000 +f 993/1063/1000 995/1065/1002 1001/1071/1008 +f 1001/1071/1008 995/1065/1002 1002/1072/1009 +f 996/1066/1003 1003/1073/1010 995/1065/1002 +f 995/1065/1002 1003/1073/1010 1002/1072/1009 +f 997/1067/1004 998/1068/1005 1004/1074/1011 +f 1004/1074/1011 998/1068/1005 1005/1075/1012 +f 998/1068/1005 999/1069/1006 1005/1075/1012 +f 1005/1075/1012 999/1069/1006 1006/1076/1013 +f 1007/1077/1014 1008/1078/1015 1001/1071/1008 +f 1001/1071/1008 1008/1078/1015 1000/1070/1007 +f 1001/1071/1008 1002/1072/1009 1007/1077/1014 +f 1007/1077/1014 1002/1072/1009 1009/1079/1016 +f 1003/1073/1010 1010/1080/1017 1002/1072/1009 +f 1002/1072/1009 1010/1080/1017 1009/1079/1016 +f 1004/1074/1011 1005/1075/1012 1011/1081/1018 +f 1011/1081/1018 1005/1075/1012 1012/1082/1019 +f 1005/1075/1012 1006/1076/1013 1012/1082/1019 +f 1012/1082/1019 1006/1076/1013 1013/1083/1020 +f 1008/1078/1015 1007/1077/1014 1014/1084/1021 +f 1014/1084/1021 1007/1077/1014 1015/1085/1022 +f 1007/1077/1014 1009/1079/1016 1015/1085/1022 +f 1015/1085/1022 1009/1079/1016 1016/1086/1023 +f 1009/1079/1016 1010/1080/1017 1016/1086/1023 +f 1016/1086/1023 1010/1080/1017 1017/1087/1024 +f 1010/1080/1017 1018/1088/1025 1017/1087/1024 +f 1017/1087/1024 1018/1088/1025 1019/1089/1026 +f 1020/1090/1027 1018/1088/1025 1021/1091/1028 +f 1021/1091/1028 1018/1088/1025 1022/1092/1029 +f 1011/1081/1018 1012/1082/1019 1023/1093/1030 +f 1023/1093/1030 1012/1082/1019 1024/1094/1031 +f 1012/1082/1019 1013/1083/1020 1024/1094/1031 +f 1024/1094/1031 1013/1083/1020 1025/1095/1032 +f 1026/1096/1033 1027/1097/1034 1028/1098/1035 +f 1028/1098/1035 1027/1097/1034 1029/1099/1036 +f 808/878/815 810/880/817 1030/1100/1037 +f 812/882/819 808/878/815 1030/1100/1037 +f 814/884/821 812/882/819 1030/1100/1037 +f 816/886/823 814/884/821 1030/1100/1037 +f 818/888/825 816/886/823 1030/1100/1037 +f 820/890/827 818/888/825 1030/1100/1037 +f 822/892/829 820/890/827 1030/1100/1037 +f 824/894/831 822/892/829 1030/1100/1037 +f 826/896/833 824/894/831 1030/1100/1037 +f 828/898/835 826/896/833 1030/1100/1037 +f 830/900/837 828/898/835 1030/1100/1037 +f 830/900/837 1030/1100/1037 832/902/839 +f 834/904/841 836/906/843 1030/1100/1037 +f 1031/1101/1038 1032/1102/1039 1033/1103/1040 +f 1033/1103/1040 1032/1102/1039 1034/1104/1041 +f 1033/1103/1040 1035/1105/1042 1031/1101/1038 +f 1031/1101/1038 1035/1105/1042 1036/1106/1043 +f 1037/1107/1044 1038/1108/1045 1033/1103/1040 +f 1033/1103/1040 1038/1108/1045 1035/1105/1042 +f 1033/1103/1040 1034/1104/1041 1037/1107/1044 +f 1037/1107/1044 1034/1104/1041 1039/1109/1046 +f 1040/1110/1047 1041/1111/1048 1042/1112/1049 +f 1042/1112/1049 1041/1111/1048 1043/1113/1050 +f 1042/1112/1049 1044/1114/1051 1040/1110/1047 +f 1040/1110/1047 1044/1114/1051 1045/1115/1052 +f 1031/1101/1038 1036/1106/1043 1042/1112/1049 +f 1042/1112/1049 1036/1106/1043 1044/1114/1051 +f 1042/1112/1049 1043/1113/1050 1031/1101/1038 +f 1031/1101/1038 1043/1113/1050 1032/1102/1039 +f 1046/1116/1053 1047/1117/1054 1048/1118/1055 +f 1048/1118/1055 1047/1117/1054 1049/1119/1056 +f 1048/1118/1055 1050/1120/1057 1046/1116/1053 +f 1046/1116/1053 1050/1120/1057 1051/1121/1058 +f 1040/1110/1047 1045/1115/1052 1048/1118/1055 +f 1048/1118/1055 1045/1115/1052 1050/1120/1057 +f 1048/1118/1055 1049/1119/1056 1040/1110/1047 +f 1040/1110/1047 1049/1119/1056 1041/1111/1048 +f 1052/1122/1059 1053/1123/1060 1054/1124/1061 +f 1054/1124/1061 1053/1123/1060 1055/1125/1062 +f 1055/1125/1062 1056/1126/1063 1054/1124/1061 +f 1054/1124/1061 1056/1126/1063 1057/1127/1064 +f 1046/1116/1053 1051/1121/1058 1055/1125/1062 +f 1055/1125/1062 1051/1121/1058 1056/1126/1063 +f 1055/1125/1062 1053/1123/1060 1046/1116/1053 +f 1046/1116/1053 1053/1123/1060 1047/1117/1054 +f 1058/1128/1065 1059/1129/1066 1060/1130/1067 +f 1060/1130/1067 1059/1129/1066 1061/1131/1068 +f 1057/1127/1064 1058/1128/1065 1054/1124/1061 +f 1054/1124/1061 1058/1128/1065 1060/1130/1067 +f 1060/1130/1067 1061/1131/1068 1062/1132/1069 +f 1062/1132/1069 1061/1131/1068 1063/1133/1070 +f 1064/1134/1071 1065/1135/1072 1066/1136/1073 +f 1066/1136/1073 1065/1135/1072 1067/1137/1074 +f 1068/1138/1075 1069/1139/1076 1067/1137/1074 +f 1067/1137/1074 1069/1139/1076 1066/1136/1073 +f 1059/1129/1066 1068/1138/1075 1061/1131/1068 +f 1061/1131/1068 1068/1138/1075 1067/1137/1074 +f 1065/1135/1072 1063/1133/1070 1067/1137/1074 +f 1067/1137/1074 1063/1133/1070 1061/1131/1068 +f 1070/1140/1077 1071/1141/1078 1072/1142/1079 +f 1072/1142/1079 1071/1141/1078 1073/1143/1080 +f 1074/1144/1081 1075/1145/1082 1073/1143/1080 +f 1073/1143/1080 1075/1145/1082 1072/1142/1079 +f 1069/1139/1076 1074/1144/1081 1066/1136/1073 +f 1066/1136/1073 1074/1144/1081 1073/1143/1080 +f 1071/1141/1078 1064/1134/1071 1073/1143/1080 +f 1073/1143/1080 1064/1134/1071 1066/1136/1073 +f 1076/1146/1083 1077/1147/1084 1078/1148/1085 +f 1078/1148/1085 1077/1147/1084 1079/1149/1086 +f 1080/1150/1087 1081/1151/1088 1079/1149/1086 +f 1079/1149/1086 1081/1151/1088 1078/1148/1085 +f 1075/1145/1082 1080/1150/1087 1072/1142/1079 +f 1072/1142/1079 1080/1150/1087 1079/1149/1086 +f 1077/1147/1084 1070/1140/1077 1079/1149/1086 +f 1079/1149/1086 1070/1140/1077 1072/1142/1079 +f 1082/1152/1089 1083/1153/1090 1084/1154/1091 +f 1084/1154/1091 1083/1153/1090 1085/1155/1092 +f 1086/1156/1093 1087/1157/1094 1085/1155/1092 +f 1085/1155/1092 1087/1157/1094 1084/1154/1091 +f 1081/1151/1088 1086/1156/1093 1078/1148/1085 +f 1078/1148/1085 1086/1156/1093 1085/1155/1092 +f 1083/1153/1090 1076/1146/1083 1085/1155/1092 +f 1085/1155/1092 1076/1146/1083 1078/1148/1085 +f 1037/1107/1044 1039/1109/1046 1088/1158/1095 +f 1088/1158/1095 1039/1109/1046 1089/1159/1096 +f 1088/1158/1095 1090/1160/1097 1037/1107/1044 +f 1037/1107/1044 1090/1160/1097 1038/1108/1045 +f 1084/1154/1091 1087/1157/1094 1088/1158/1095 +f 1088/1158/1095 1087/1157/1094 1090/1160/1097 +f 1088/1158/1095 1089/1159/1096 1084/1154/1091 +f 1084/1154/1091 1089/1159/1096 1082/1152/1089 +f 1077/1147/1084 1076/1146/1083 1034/1104/1041 +f 1034/1104/1041 1076/1146/1083 1039/1109/1046 +f 1091/1161/1098 1092/1162/1099 1093/1163/1100 +f 1093/1163/1100 1092/1162/1099 1094/1164/1101 +f 1095/1165/1102 1096/1166/1103 1097/1167/1104 +f 1097/1167/1104 1096/1166/1103 1094/1164/1101 +f 1098/1168/1105 1099/1169/1106 1100/1170/1107 +f 1100/1170/1107 1099/1169/1106 1101/1171/1108 +f 1102/1172/1109 1103/1173/1110 1104/1174/1111 +f 1104/1174/1111 1103/1173/1110 1101/1171/1108 +f 1105/1175/1112 1106/1176/1113 1104/1174/1111 +f 1104/1174/1111 1106/1176/1113 1107/1177/1114 +f 1108/1178/1115 1109/1179/1116 1093/1163/1100 +f 1093/1163/1100 1109/1179/1116 1107/1177/1114 +f 1110/1180/1117 1111/1181/1118 1112/1182/1119 +f 1112/1182/1119 1111/1181/1118 1097/1167/1104 +f 1113/1183/1120 1114/1184/1121 1115/1185/1122 +f 1115/1185/1122 1114/1184/1121 1111/1181/1118 +f 1116/1186/1123 1117/1187/1124 1115/1185/1122 +f 1115/1185/1122 1117/1187/1124 1118/1188/1125 +f 1119/1189/1126 1118/1188/1125 1120/1190/1127 +f 1120/1190/1127 1118/1188/1125 1121/1191/1128 +f 1122/1192/1129 1123/1193/1130 1124/1194/1131 +f 1124/1194/1131 1123/1193/1130 1125/1195/1132 +f 1126/1196/1133 1123/1193/1130 1127/1197/1134 +f 1127/1197/1134 1123/1193/1130 1121/1191/1128 +f 1128/1198/1135 1129/1199/1136 1130/1200/1137 +f 1130/1200/1137 1129/1199/1136 1125/1195/1132 +f 1131/1201/1138 1129/1199/1136 1132/1202/1139 +f 1132/1202/1139 1129/1199/1136 1133/1203/1140 +f 1134/1204/1141 1135/1205/1142 1136/1206/1143 +f 1136/1206/1143 1135/1205/1142 1133/1203/1140 +f 1137/1207/1144 1135/1205/1142 1138/1208/1145 +f 1138/1208/1145 1135/1205/1142 1139/1209/1146 +f 1140/1210/1147 1141/1211/1148 1142/1212/1149 +f 1142/1212/1149 1141/1211/1148 1139/1209/1146 +f 1143/1213/1150 1141/1211/1148 1144/1214/1151 +f 1144/1214/1151 1141/1211/1148 1145/1215/1152 +f 1146/1216/1153 1147/1217/1154 1148/1218/1155 +f 1148/1218/1155 1147/1217/1154 1145/1215/1152 +f 1149/1219/1156 1147/1217/1154 1150/1220/1157 +f 1150/1220/1157 1147/1217/1154 1100/1170/1107 +f 1050/1120/1057 1151/1221/1158 1051/1121/1058 +f 1051/1121/1058 1151/1221/1158 1152/1222/1159 +f 1151/1221/1158 1050/1120/1057 1153/1223/1160 +f 1153/1223/1160 1050/1120/1057 1045/1115/1052 +f 1035/1105/1042 1154/1224/1161 1036/1106/1043 +f 1036/1106/1043 1154/1224/1161 1155/1225/1162 +f 1154/1224/1161 1035/1105/1042 1156/1226/1163 +f 1156/1226/1163 1035/1105/1042 1038/1108/1045 +f 1044/1114/1051 1157/1227/1164 1045/1115/1052 +f 1045/1115/1052 1157/1227/1164 1153/1223/1160 +f 1157/1227/1164 1044/1114/1051 1155/1225/1162 +f 1155/1225/1162 1044/1114/1051 1036/1106/1043 +f 1056/1126/1063 1158/1228/1165 1057/1127/1064 +f 1057/1127/1064 1158/1228/1165 1159/1229/1166 +f 1158/1228/1165 1056/1126/1063 1152/1222/1159 +f 1152/1222/1159 1056/1126/1063 1051/1121/1058 +f 1090/1160/1097 1160/1230/1167 1038/1108/1045 +f 1038/1108/1045 1160/1230/1167 1156/1226/1163 +f 1160/1230/1167 1090/1160/1097 1161/1231/1168 +f 1161/1231/1168 1090/1160/1097 1087/1157/1094 +f 1059/1129/1066 1058/1128/1065 1162/1232/1169 +f 1162/1232/1169 1058/1128/1065 1163/1233/1170 +f 1058/1128/1065 1057/1127/1064 1163/1233/1170 +f 1163/1233/1170 1057/1127/1064 1159/1229/1166 +f 1087/1157/1094 1086/1156/1093 1161/1231/1168 +f 1161/1231/1168 1086/1156/1093 1164/1234/1171 +f 1086/1156/1093 1081/1151/1088 1164/1234/1171 +f 1164/1234/1171 1081/1151/1088 1165/1235/1172 +f 1069/1139/1076 1068/1138/1075 1166/1236/1173 +f 1166/1236/1173 1068/1138/1075 1167/1237/1174 +f 1068/1138/1075 1059/1129/1066 1167/1237/1174 +f 1167/1237/1174 1059/1129/1066 1162/1232/1169 +f 1081/1151/1088 1080/1150/1087 1165/1235/1172 +f 1165/1235/1172 1080/1150/1087 1168/1238/1175 +f 1080/1150/1087 1075/1145/1082 1168/1238/1175 +f 1168/1238/1175 1075/1145/1082 1169/1239/1176 +f 1075/1145/1082 1074/1144/1081 1169/1239/1176 +f 1169/1239/1176 1074/1144/1081 1170/1240/1177 +f 1074/1144/1081 1069/1139/1076 1170/1240/1177 +f 1170/1240/1177 1069/1139/1076 1166/1236/1173 +f 1151/1241/1158 1114/1184/1121 1152/1242/1159 +f 1152/1242/1159 1114/1184/1121 1113/1183/1120 +f 1114/1184/1121 1151/1241/1158 1095/1165/1102 +f 1095/1165/1102 1151/1241/1158 1153/1243/1160 +f 1154/1244/1161 1109/1179/1116 1155/1245/1162 +f 1155/1245/1162 1109/1179/1116 1108/1178/1115 +f 1102/1172/1109 1109/1179/1116 1156/1246/1163 +f 1156/1246/1163 1109/1179/1116 1154/1244/1161 +f 1095/1165/1102 1153/1243/1160 1096/1166/1103 +f 1096/1166/1103 1153/1243/1160 1157/1247/1164 +f 1155/1245/1162 1108/1178/1115 1157/1247/1164 +f 1157/1247/1164 1108/1178/1115 1096/1166/1103 +f 1158/1248/1165 1119/1189/1126 1159/1249/1166 +f 1159/1249/1166 1119/1189/1126 1120/1190/1127 +f 1152/1242/1159 1113/1183/1120 1158/1248/1165 +f 1158/1248/1165 1113/1183/1120 1119/1189/1126 +f 1156/1246/1163 1160/1250/1167 1102/1172/1109 +f 1102/1172/1109 1160/1250/1167 1103/1173/1110 +f 1150/1220/1157 1103/1173/1110 1161/1251/1168 +f 1161/1251/1168 1103/1173/1110 1160/1250/1167 +f 1163/1252/1170 1122/1192/1129 1162/1253/1169 +f 1162/1253/1169 1122/1192/1129 1124/1194/1131 +f 1159/1249/1166 1120/1190/1127 1163/1252/1170 +f 1163/1252/1170 1120/1190/1127 1122/1192/1129 +f 1161/1251/1168 1164/1254/1171 1150/1220/1157 +f 1150/1220/1157 1164/1254/1171 1149/1219/1156 +f 1144/1214/1151 1149/1219/1156 1165/1255/1172 +f 1165/1255/1172 1149/1219/1156 1164/1254/1171 +f 1167/1256/1174 1131/1201/1138 1166/1257/1173 +f 1166/1257/1173 1131/1201/1138 1132/1202/1139 +f 1162/1253/1169 1124/1194/1131 1167/1256/1174 +f 1167/1256/1174 1124/1194/1131 1131/1201/1138 +f 1165/1255/1172 1168/1258/1175 1144/1214/1151 +f 1144/1214/1151 1168/1258/1175 1143/1213/1150 +f 1138/1208/1145 1143/1213/1150 1169/1259/1176 +f 1169/1259/1176 1143/1213/1150 1168/1258/1175 +f 1138/1208/1145 1169/1259/1176 1137/1207/1144 +f 1137/1207/1144 1169/1259/1176 1170/1260/1177 +f 1166/1257/1173 1132/1202/1139 1170/1260/1177 +f 1170/1260/1177 1132/1202/1139 1137/1207/1144 +f 1126/1196/1133 1171/1261/1178 1130/1200/1137 +f 1130/1200/1137 1171/1261/1178 1172/1262/1179 +f 1126/1196/1133 1127/1197/1134 1171/1261/1178 +f 1171/1261/1178 1127/1197/1134 1173/1263/1180 +f 1128/1198/1135 1174/1264/1181 1136/1206/1143 +f 1136/1206/1143 1174/1264/1181 1175/1265/1182 +f 1174/1264/1181 1128/1198/1135 1172/1262/1179 +f 1172/1262/1179 1128/1198/1135 1130/1200/1137 +f 1112/1182/1119 1092/1162/1099 1176/1266/1183 +f 1176/1266/1183 1092/1162/1099 1177/1267/1184 +f 1092/1162/1099 1091/1161/1098 1177/1267/1184 +f 1177/1267/1184 1091/1161/1098 1178/1268/1185 +f 1140/1210/1147 1179/1269/1186 1148/1218/1155 +f 1148/1218/1155 1179/1269/1186 1180/1270/1187 +f 1179/1269/1186 1140/1210/1147 1181/1271/1188 +f 1181/1271/1188 1140/1210/1147 1142/1212/1149 +f 1105/1175/1112 1099/1169/1106 1182/1272/1189 +f 1182/1272/1189 1099/1169/1106 1183/1273/1190 +f 1183/1273/1190 1099/1169/1106 1184/1274/1191 +f 1184/1274/1191 1099/1169/1106 1098/1168/1105 +f 1091/1161/1098 1106/1176/1113 1178/1268/1185 +f 1178/1268/1185 1106/1176/1113 1185/1275/1192 +f 1106/1176/1113 1105/1175/1112 1185/1275/1192 +f 1185/1275/1192 1105/1175/1112 1182/1272/1189 +f 1116/1186/1123 1110/1180/1117 1186/1276/1193 +f 1186/1276/1193 1110/1180/1117 1187/1277/1194 +f 1110/1180/1117 1112/1182/1119 1187/1277/1194 +f 1187/1277/1194 1112/1182/1119 1176/1266/1183 +f 1127/1197/1134 1117/1187/1124 1173/1263/1180 +f 1173/1263/1180 1117/1187/1124 1188/1278/1195 +f 1117/1187/1124 1116/1186/1123 1188/1278/1195 +f 1188/1278/1195 1116/1186/1123 1186/1276/1193 +f 1134/1204/1141 1189/1279/1196 1142/1212/1149 +f 1142/1212/1149 1189/1279/1196 1181/1271/1188 +f 1189/1279/1196 1134/1204/1141 1175/1265/1182 +f 1175/1265/1182 1134/1204/1141 1136/1206/1143 +f 1146/1216/1153 1190/1280/1197 1098/1168/1105 +f 1098/1168/1105 1190/1280/1197 1184/1274/1191 +f 1190/1280/1197 1146/1216/1153 1180/1270/1187 +f 1180/1270/1187 1146/1216/1153 1148/1218/1155 +f 1191/1281/1198 1192/1282/1199 1171/1261/1178 +f 1171/1261/1178 1192/1282/1199 1172/1262/1179 +f 1193/1283/1200 1191/1281/1198 1173/1263/1180 +f 1173/1263/1180 1191/1281/1198 1171/1261/1178 +f 1174/1264/1181 1194/1284/1201 1175/1265/1182 +f 1175/1265/1182 1194/1284/1201 1195/1285/1202 +f 1194/1284/1201 1174/1264/1181 1192/1282/1199 +f 1192/1282/1199 1174/1264/1181 1172/1262/1179 +f 1196/1286/1203 1197/1287/1204 1177/1267/1184 +f 1177/1267/1184 1197/1287/1204 1176/1266/1183 +f 1198/1288/1205 1196/1286/1203 1178/1268/1185 +f 1178/1268/1185 1196/1286/1203 1177/1267/1184 +f 1179/1269/1186 1199/1289/1206 1180/1270/1187 +f 1180/1270/1187 1199/1289/1206 1200/1290/1207 +f 1199/1289/1206 1179/1269/1186 1201/1291/1208 +f 1201/1291/1208 1179/1269/1186 1181/1271/1188 +f 1183/1273/1190 1202/1292/1209 1182/1272/1189 +f 1182/1272/1189 1202/1292/1209 1203/1293/1210 +f 1202/1292/1209 1183/1273/1190 1204/1294/1211 +f 1204/1294/1211 1183/1273/1190 1184/1274/1191 +f 1205/1295/1212 1198/1288/1205 1185/1275/1192 +f 1185/1275/1192 1198/1288/1205 1178/1268/1185 +f 1203/1293/1210 1205/1295/1212 1182/1272/1189 +f 1182/1272/1189 1205/1295/1212 1185/1275/1192 +f 1206/1296/1213 1207/1297/1214 1187/1277/1194 +f 1187/1277/1194 1207/1297/1214 1186/1276/1193 +f 1197/1287/1204 1206/1296/1213 1176/1266/1183 +f 1176/1266/1183 1206/1296/1213 1187/1277/1194 +f 1208/1298/1215 1193/1283/1200 1188/1278/1195 +f 1188/1278/1195 1193/1283/1200 1173/1263/1180 +f 1207/1297/1214 1208/1298/1215 1186/1276/1193 +f 1186/1276/1193 1208/1298/1215 1188/1278/1195 +f 1189/1279/1196 1209/1299/1216 1181/1271/1188 +f 1181/1271/1188 1209/1299/1216 1201/1291/1208 +f 1209/1299/1216 1189/1279/1196 1195/1285/1202 +f 1195/1285/1202 1189/1279/1196 1175/1265/1182 +f 1190/1280/1197 1210/1300/1217 1184/1274/1191 +f 1184/1274/1191 1210/1300/1217 1204/1294/1211 +f 1210/1300/1217 1190/1280/1197 1200/1290/1207 +f 1200/1290/1207 1190/1280/1197 1180/1270/1187 +f 1083/1153/1090 1082/1152/1089 1076/1146/1083 +f 1076/1146/1083 1082/1152/1089 1039/1109/1046 +f 1082/1152/1089 1089/1159/1096 1039/1109/1046 +f 1032/1102/1039 1043/1113/1050 1070/1140/1077 +f 1070/1140/1077 1043/1113/1050 1071/1141/1078 +f 1034/1104/1041 1032/1102/1039 1077/1147/1084 +f 1077/1147/1084 1032/1102/1039 1070/1140/1077 +f 1043/1113/1050 1041/1111/1048 1071/1141/1078 +f 1071/1141/1078 1041/1111/1048 1064/1134/1071 +f 1053/1123/1060 1052/1122/1059 1047/1117/1054 +f 1063/1133/1070 1047/1117/1054 1062/1132/1069 +f 1047/1117/1054 1052/1122/1059 1062/1132/1069 +f 1049/1119/1056 1065/1135/1072 1041/1111/1048 +f 1041/1111/1048 1065/1135/1072 1064/1134/1071 +f 1062/1132/1069 1052/1122/1059 1060/1130/1067 +f 1060/1130/1067 1052/1122/1059 1054/1124/1061 +f 1047/1117/1054 1063/1133/1070 1049/1119/1056 +f 1049/1119/1056 1063/1133/1070 1065/1135/1072 +f 1192/1282/1199 1191/1281/1198 1211/1301/1218 +f 1211/1301/1218 1191/1281/1198 1212/1302/1219 +f 1191/1281/1198 1193/1283/1200 1212/1302/1219 +f 1212/1302/1219 1193/1283/1200 1014/1084/1021 +f 1194/1284/1201 1213/1303/1220 1195/1285/1202 +f 1195/1285/1202 1213/1303/1220 1214/1304/1221 +f 1196/1286/1203 982/1052/989 1197/1287/1204 +f 1197/1287/1204 982/1052/989 983/1053/990 +f 1196/1286/1203 1198/1288/1205 982/1052/989 +f 982/1052/989 1198/1288/1205 972/1042/979 +f 1199/1289/1206 1006/1076/1013 1200/1290/1207 +f 1200/1290/1207 1006/1076/1013 999/1069/1006 +f 1201/1291/1208 1013/1083/1020 1199/1289/1206 +f 1199/1289/1206 1013/1083/1020 1006/1076/1013 +f 1203/1293/1210 1202/1292/1209 970/1040/977 +f 970/1040/977 1202/1292/1209 981/1051/988 +f 1202/1292/1209 1204/1294/1211 981/1051/988 +f 981/1051/988 1204/1294/1211 989/1059/996 +f 1205/1295/1212 971/1041/978 1198/1288/1205 +f 1198/1288/1205 971/1041/978 972/1042/979 +f 1205/1295/1212 1203/1293/1210 971/1041/978 +f 971/1041/978 1203/1293/1210 970/1040/977 +f 1207/1297/1214 1206/1296/1213 1000/1070/1007 +f 1000/1070/1007 1206/1296/1213 994/1064/1001 +f 1206/1296/1213 1197/1287/1204 994/1064/1001 +f 994/1064/1001 1197/1287/1204 983/1053/990 +f 1208/1298/1215 1207/1297/1214 1008/1078/1015 +f 1008/1078/1015 1207/1297/1214 1000/1070/1007 +f 1201/1291/1208 1209/1299/1216 1013/1083/1020 +f 1013/1083/1020 1209/1299/1216 1025/1095/1032 +f 1195/1285/1202 1214/1304/1221 1209/1299/1216 +f 1209/1299/1216 1214/1304/1221 1025/1095/1032 +f 1204/1294/1211 1210/1300/1217 989/1059/996 +f 989/1059/996 1210/1300/1217 992/1062/999 +f 1210/1300/1217 1200/1290/1207 992/1062/999 +f 992/1062/999 1200/1290/1207 999/1069/1006 +f 1192/1282/1199 1211/1301/1218 1194/1284/1201 +f 1194/1284/1201 1211/1301/1218 1213/1303/1220 +f 989/1059/996 980/1050/987 981/1051/988 +f 981/1051/988 969/1039/976 970/1040/977 +f 1208/1298/1215 1008/1078/1015 1193/1283/1200 +f 1193/1283/1200 1008/1078/1015 1014/1084/1021 +f 1215/1305/1222 1216/1306/1223 1217/1307/1224 +f 1216/1306/1223 1218/1308/1225 1219/1309/1226 +f 1219/1309/1226 1218/1308/1225 1217/1307/1224 +f 1220/1310/1227 1221/1311/1228 1222/1312/1229 +f 1222/1312/1229 1221/1311/1228 1223/1313/1230 +f 1221/1311/1228 1220/1310/1227 1224/1314/1231 +f 1224/1314/1231 1220/1310/1227 1225/1315/1232 +f 1226/1316/1233 1227/1317/1234 1220/1310/1227 +f 1220/1310/1227 1227/1317/1234 1225/1315/1232 +f 1228/1318/1235 1229/1319/1236 1230/1320/1237 +f 1230/1320/1237 1229/1319/1236 1226/1316/1233 +f 1226/1316/1233 1220/1310/1227 1230/1320/1237 +f 1230/1320/1237 1220/1310/1227 1222/1312/1229 +f 1231/1321/1238 1232/1322/1239 1233/1323/1240 +f 1233/1323/1240 1232/1322/1239 1234/1324/1241 +f 1235/1325/1242 1234/1324/1241 1236/1326/1243 +f 1236/1326/1243 1234/1324/1241 1232/1322/1239 +f 1237/1327/1244 1238/1328/1245 1239/1329/1246 +f 1239/1329/1246 1238/1328/1245 1240/1330/1247 +f 1241/1331/1248 1240/1330/1247 1242/1332/1249 +f 1242/1332/1249 1240/1330/1247 1238/1328/1245 +f 1232/1322/1239 1243/1333/1250 1236/1326/1243 +f 1236/1326/1243 1243/1333/1250 1244/1334/1251 +f 1243/1333/1250 1245/1335/1252 1244/1334/1251 +f 1244/1334/1251 1245/1335/1252 1246/1336/1253 +f 1245/1335/1252 1243/1333/1250 1247/1337/1254 +f 1247/1337/1254 1243/1333/1250 1248/1338/1255 +f 1243/1333/1250 1232/1322/1239 1248/1338/1255 +f 1248/1338/1255 1232/1322/1239 1231/1321/1238 +f 1249/1339/1256 1250/1340/1257 1251/1341/1258 +f 1251/1341/1258 1250/1340/1257 1252/1342/1259 +f 1233/1323/1240 1252/1342/1259 1231/1321/1238 +f 1231/1321/1238 1252/1342/1259 1250/1340/1257 +f 1253/1343/1260 1254/1344/1261 1255/1345/1262 +f 1255/1345/1262 1254/1344/1261 1256/1346/1263 +f 1254/1344/1261 1257/1347/1264 1256/1346/1263 +f 1256/1346/1263 1257/1347/1264 1258/1348/1265 +f 1257/1347/1264 1254/1344/1261 1259/1349/1266 +f 1259/1349/1266 1254/1344/1261 1260/1350/1267 +f 1260/1350/1267 1254/1344/1261 1253/1343/1260 +f 1261/1351/1268 1262/1352/1269 1239/1329/1246 +f 1239/1329/1246 1262/1352/1269 1263/1353/1270 +f 1262/1352/1269 1261/1351/1268 1264/1354/1271 +f 1264/1354/1271 1261/1351/1268 1265/1355/1272 +f 1261/1351/1268 1266/1356/1273 1265/1355/1272 +f 1265/1355/1272 1266/1356/1273 1267/1357/1274 +f 1266/1356/1273 1268/1358/1275 1267/1357/1274 +f 1267/1357/1274 1268/1358/1275 1269/1359/1276 +f 1268/1358/1275 1266/1356/1273 1241/1331/1248 +f 1241/1331/1248 1266/1356/1273 1240/1330/1247 +f 1266/1356/1273 1261/1351/1268 1240/1330/1247 +f 1240/1330/1247 1261/1351/1268 1239/1329/1246 +f 1270/1360/1277 1271/1361/1278 1272/1362/1279 +f 1272/1362/1279 1271/1361/1278 1273/1363/1280 +f 1273/1363/1280 1271/1361/1278 1249/1339/1256 +f 1249/1339/1256 1271/1361/1278 1250/1340/1257 +f 1271/1361/1278 1248/1338/1255 1250/1340/1257 +f 1250/1340/1257 1248/1338/1255 1231/1321/1238 +f 1271/1361/1278 1270/1360/1277 1248/1338/1255 +f 1248/1338/1255 1270/1360/1277 1247/1337/1254 +f 1258/1348/1265 1257/1347/1264 1274/1364/1281 +f 1274/1364/1281 1257/1347/1264 1275/1365/1282 +f 1275/1365/1282 1257/1347/1264 1276/1366/1283 +f 1277/1367/1284 1278/1368/1285 1279/1369/1286 +f 1279/1369/1286 1278/1368/1285 1280/1370/1287 +f 1278/1368/1285 1277/1367/1284 1281/1371/1288 +f 1281/1371/1288 1277/1367/1284 1282/1372/1289 +f 1283/1373/1290 1284/1374/1291 1285/1375/1292 +f 1285/1375/1292 1284/1374/1291 1286/1376/1293 +f 1286/1376/1293 1284/1374/1291 1287/1377/1294 +f 1287/1377/1294 1284/1374/1291 1288/1378/1295 +f 1284/1374/1291 1278/1368/1285 1288/1378/1295 +f 1288/1378/1295 1278/1368/1285 1281/1371/1288 +f 1284/1374/1291 1283/1373/1290 1278/1368/1285 +f 1278/1368/1285 1283/1373/1290 1280/1370/1287 +f 1289/1379/1296 1290/1380/1297 1291/1381/1298 +f 1291/1381/1298 1290/1380/1297 1292/1382/1299 +f 1290/1380/1297 1293/1383/1300 1292/1382/1299 +f 1292/1382/1299 1293/1383/1300 1294/1384/1301 +f 1295/1385/1302 1296/1386/1303 1297/1387/1304 +f 1297/1387/1304 1296/1386/1303 1298/1388/1305 +f 1295/1385/1302 1216/1306/1223 1296/1386/1303 +f 1296/1386/1303 1216/1306/1223 1215/1305/1222 +f 1299/1389/1306 1300/1390/1307 1297/1387/1304 +f 1297/1387/1304 1300/1390/1307 1295/1385/1302 +f 1295/1385/1302 1301/1391/1308 1216/1306/1223 +f 1216/1306/1223 1301/1391/1308 1218/1308/1225 +f 1301/1391/1308 1295/1385/1302 1302/1392/1309 +f 1302/1392/1309 1295/1385/1302 1300/1390/1307 +f 1303/1393/1310 1304/1394/1311 1305/1395/1312 +f 1305/1395/1312 1304/1394/1311 1306/1396/1313 +f 1304/1394/1311 1221/1311/1228 1306/1396/1313 +f 1306/1396/1313 1221/1311/1228 1224/1314/1231 +f 1221/1311/1228 1304/1394/1311 1223/1313/1230 +f 1223/1313/1230 1304/1394/1311 1307/1397/1314 +f 1304/1394/1311 1303/1393/1310 1307/1397/1314 +f 1307/1397/1314 1303/1393/1310 1308/1398/1315 +f 1251/1341/1258 1309/1399/1316 1249/1339/1256 +f 1249/1339/1256 1309/1399/1316 1310/1400/1317 +f 1311/1401/1318 1310/1400/1317 1312/1402/1319 +f 1312/1402/1319 1310/1400/1317 1309/1399/1316 +f 1313/1403/1320 1314/1404/1321 1315/1405/1322 +f 1315/1405/1322 1314/1404/1321 1316/1406/1323 +f 1314/1404/1321 1317/1407/1324 1316/1406/1323 +f 1316/1406/1323 1317/1407/1324 1318/1408/1325 +f 1317/1407/1324 1314/1404/1321 1298/1388/1305 +f 1298/1388/1305 1314/1404/1321 1297/1387/1304 +f 1319/1409/1326 1313/1403/1320 1320/1410/1327 +f 1320/1410/1327 1313/1403/1320 1315/1405/1322 +f 1300/1390/1307 1299/1389/1306 1321/1411/1328 +f 1322/1412/1329 1321/1411/1328 1299/1389/1306 +f 1322/1412/1329 1319/1409/1326 1274/1364/1281 +f 1274/1364/1281 1319/1409/1326 1323/1413/1330 +f 1319/1409/1326 1320/1410/1327 1323/1413/1330 +f 1323/1413/1330 1320/1410/1327 1324/1414/1331 +f 1325/1415/1332 1317/1407/1324 1326/1416/1333 +f 1326/1416/1333 1317/1407/1324 1298/1388/1305 +f 1317/1407/1324 1325/1415/1332 1318/1408/1325 +f 1318/1408/1325 1325/1415/1332 1327/1417/1334 +f 1325/1415/1332 1328/1418/1335 1327/1417/1334 +f 1327/1417/1334 1328/1418/1335 1329/1419/1336 +f 1328/1418/1335 1325/1415/1332 1330/1420/1337 +f 1330/1420/1337 1325/1415/1332 1326/1416/1333 +f 1331/1421/1338 1332/1422/1339 1333/1423/1340 +f 1333/1423/1340 1332/1422/1339 1334/1424/1341 +f 1335/1425/1342 1334/1424/1341 1336/1426/1343 +f 1336/1426/1343 1334/1424/1341 1332/1422/1339 +f 1337/1427/1344 1338/1428/1345 1339/1429/1346 +f 1339/1429/1346 1338/1428/1345 1340/1430/1347 +f 1338/1428/1345 1341/1431/1348 1340/1430/1347 +f 1340/1430/1347 1341/1431/1348 1342/1432/1349 +f 1341/1431/1348 1338/1428/1345 1343/1433/1350 +f 1343/1433/1350 1338/1428/1345 1344/1434/1351 +f 1338/1428/1345 1337/1427/1344 1344/1434/1351 +f 1344/1434/1351 1337/1427/1344 1345/1435/1352 +f 1346/1436/1353 1347/1437/1354 1348/1438/1355 +f 1348/1438/1355 1347/1437/1354 1349/1439/1356 +f 1347/1437/1354 1350/1440/1357 1349/1439/1356 +f 1349/1439/1356 1350/1440/1357 1294/1384/1301 +f 1347/1437/1354 1337/1427/1344 1350/1440/1357 +f 1350/1440/1357 1337/1427/1344 1339/1429/1346 +f 1337/1427/1344 1347/1437/1354 1345/1435/1352 +f 1345/1435/1352 1347/1437/1354 1346/1436/1353 +f 1351/1441/1358 1352/1442/1359 1353/1443/1360 +f 1353/1443/1360 1352/1442/1359 1354/1444/1361 +f 1352/1442/1359 1355/1445/1362 1354/1444/1361 +f 1354/1444/1361 1355/1445/1362 1356/1446/1363 +f 1355/1445/1362 1352/1442/1359 1335/1425/1342 +f 1335/1425/1342 1352/1442/1359 1334/1424/1341 +f 1352/1442/1359 1351/1441/1358 1334/1424/1341 +f 1334/1424/1341 1351/1441/1358 1333/1423/1340 +f 1357/1447/1364 1341/1431/1348 1358/1448/1365 +f 1358/1448/1365 1341/1431/1348 1343/1433/1350 +f 1341/1431/1348 1357/1447/1364 1342/1432/1349 +f 1342/1432/1349 1357/1447/1364 1359/1449/1366 +f 1357/1447/1364 1360/1450/1367 1359/1449/1366 +f 1359/1449/1366 1360/1450/1367 1361/1451/1368 +f 1360/1450/1367 1357/1447/1364 1362/1452/1369 +f 1362/1452/1369 1357/1447/1364 1358/1448/1365 +f 1336/1426/1343 1363/1453/1370 1335/1425/1342 +f 1335/1425/1342 1363/1453/1370 1355/1445/1362 +f 1364/1454/1371 1356/1446/1363 1363/1453/1370 +f 1363/1453/1370 1356/1446/1363 1355/1445/1362 +f 1365/1455/1372 1366/1456/1373 1367/1457/1374 +f 1367/1457/1374 1366/1456/1373 1368/1458/1375 +f 1366/1456/1373 1365/1455/1372 1361/1451/1368 +f 1361/1451/1368 1365/1455/1372 1359/1449/1366 +f 1359/1449/1366 1365/1455/1372 1342/1432/1349 +f 1342/1432/1349 1365/1455/1372 1340/1430/1347 +f 1365/1455/1372 1367/1457/1374 1340/1430/1347 +f 1340/1430/1347 1367/1457/1374 1339/1429/1346 +f 1369/1459/1376 1370/1460/1377 1265/1355/1272 +f 1265/1355/1272 1370/1460/1377 1264/1354/1271 +f 1370/1460/1377 1369/1459/1376 1371/1461/1378 +f 1371/1461/1378 1369/1459/1376 1372/1462/1379 +f 1373/1463/1380 1374/1464/1381 1375/1465/1382 +f 1375/1465/1382 1374/1464/1381 1376/1466/1383 +f 1300/1390/1307 1377/1467/1384 1302/1392/1309 +f 1302/1392/1309 1377/1467/1384 1378/1468/1385 +f 1379/1469/1386 1380/1470/1387 1381/1471/1388 +f 1381/1471/1388 1380/1470/1387 1378/1468/1385 +f 1369/1459/1376 1382/1472/1389 1372/1462/1379 +f 1372/1462/1379 1382/1472/1389 1383/1473/1390 +f 1382/1472/1389 1384/1474/1391 1383/1473/1390 +f 1383/1473/1390 1384/1474/1391 1385/1475/1392 +f 1384/1474/1391 1382/1472/1389 1269/1359/1276 +f 1269/1359/1276 1382/1472/1389 1267/1357/1274 +f 1382/1472/1389 1369/1459/1376 1267/1357/1274 +f 1267/1357/1274 1369/1459/1376 1265/1355/1272 +f 1386/1476/1393 1303/1393/1310 1380/1470/1387 +f 1380/1470/1387 1303/1393/1310 1305/1395/1312 +f 1303/1393/1310 1386/1476/1393 1308/1398/1315 +f 1308/1398/1315 1386/1476/1393 1387/1477/1394 +f 1386/1476/1393 1388/1478/1395 1387/1477/1394 +f 1387/1477/1394 1388/1478/1395 1389/1479/1396 +f 1388/1478/1395 1386/1476/1393 1379/1469/1386 +f 1379/1469/1386 1386/1476/1393 1380/1470/1387 +f 1390/1480/1397 1391/1481/1398 1372/1462/1379 +f 1372/1462/1379 1391/1481/1398 1371/1461/1378 +f 1374/1464/1381 1392/1482/1399 1376/1466/1383 +f 1376/1466/1383 1392/1482/1399 1393/1483/1400 +f 1394/1484/1401 1379/1469/1386 1395/1485/1402 +f 1395/1485/1402 1379/1469/1386 1381/1471/1388 +f 1396/1486/1403 1397/1443/1404 1385/1475/1392 +f 1385/1475/1392 1397/1443/1404 1383/1473/1390 +f 1397/1443/1404 1390/1480/1397 1383/1473/1390 +f 1383/1473/1390 1390/1480/1397 1372/1462/1379 +f 1388/1478/1395 1398/1487/1405 1389/1479/1396 +f 1389/1479/1396 1398/1487/1405 1399/1488/1406 +f 1398/1487/1405 1388/1478/1395 1394/1484/1401 +f 1394/1484/1401 1388/1478/1395 1379/1469/1386 +f 1392/1482/1399 1277/1367/1284 1393/1483/1400 +f 1393/1483/1400 1277/1367/1284 1279/1369/1286 +f 1287/1377/1294 1288/1378/1295 1396/1486/1403 +f 1396/1486/1403 1288/1378/1295 1397/1443/1404 +f 1288/1378/1295 1281/1371/1288 1397/1443/1404 +f 1397/1443/1404 1281/1371/1288 1390/1480/1397 +f 1400/1489/1407 1401/1490/1408 1402/1491/1409 +f 1402/1491/1409 1401/1490/1408 1403/1492/1410 +f 1401/1490/1408 1400/1489/1407 1311/1401/1318 +f 1311/1401/1318 1400/1489/1407 1310/1400/1317 +f 1400/1489/1407 1273/1363/1280 1310/1400/1317 +f 1310/1400/1317 1273/1363/1280 1249/1339/1256 +f 1273/1363/1280 1400/1489/1407 1272/1362/1279 +f 1272/1362/1279 1400/1489/1407 1402/1491/1409 +f 1404/1493/1411 1405/1494/1412 1329/1419/1336 +f 1329/1419/1336 1405/1494/1412 1327/1417/1334 +f 1405/1494/1412 1406/1495/1413 1327/1417/1334 +f 1327/1417/1334 1406/1495/1413 1318/1408/1325 +f 1406/1495/1413 1405/1494/1412 1343/1433/1350 +f 1343/1433/1350 1405/1494/1412 1358/1448/1365 +f 1405/1494/1412 1404/1493/1411 1358/1448/1365 +f 1358/1448/1365 1404/1493/1411 1362/1452/1369 +f 1407/1496/1414 1408/1497/1415 1348/1438/1355 +f 1348/1438/1355 1408/1497/1415 1409/1498/1416 +f 1408/1497/1415 1410/1499/1417 1409/1498/1416 +f 1409/1498/1416 1410/1499/1417 1324/1414/1331 +f 1312/1402/1319 1411/1500/1418 1311/1401/1318 +f 1311/1401/1318 1411/1500/1418 1412/1501/1419 +f 1333/1423/1340 1412/1501/1419 1331/1421/1338 +f 1331/1421/1338 1412/1501/1419 1411/1500/1418 +f 1413/1502/1420 1414/1503/1421 1345/1435/1352 +f 1345/1435/1352 1414/1503/1421 1344/1434/1351 +f 1414/1503/1421 1406/1495/1413 1344/1434/1351 +f 1344/1434/1351 1406/1495/1413 1343/1433/1350 +f 1406/1495/1413 1414/1503/1421 1318/1408/1325 +f 1318/1408/1325 1414/1503/1421 1316/1406/1323 +f 1414/1503/1421 1413/1502/1420 1316/1406/1323 +f 1316/1406/1323 1413/1502/1420 1315/1405/1322 +f 1364/1454/1371 1363/1453/1370 1289/1379/1296 +f 1289/1379/1296 1363/1453/1370 1290/1380/1297 +f 1363/1453/1370 1336/1426/1343 1290/1380/1297 +f 1290/1380/1297 1336/1426/1343 1293/1383/1300 +f 1336/1426/1343 1332/1422/1339 1293/1383/1300 +f 1293/1383/1300 1332/1422/1339 1415/1504/1422 +f 1332/1422/1339 1331/1421/1338 1415/1504/1422 +f 1415/1504/1422 1331/1421/1338 1407/1496/1414 +f 1312/1402/1319 1309/1399/1316 1410/1499/1417 +f 1410/1499/1417 1309/1399/1316 1416/1505/1423 +f 1309/1399/1316 1251/1341/1258 1416/1505/1423 +f 1416/1505/1423 1251/1341/1258 1258/1348/1265 +f 1251/1341/1258 1252/1342/1259 1258/1348/1265 +f 1258/1348/1265 1252/1342/1259 1256/1346/1263 +f 1252/1342/1259 1233/1323/1240 1256/1346/1263 +f 1256/1346/1263 1233/1323/1240 1255/1345/1262 +f 1417/1506/1424 1253/1343/1260 1235/1325/1242 +f 1235/1325/1242 1253/1343/1260 1255/1345/1262 +f 1418/1507/1425 1259/1349/1266 1260/1350/1267 +f 1373/1463/1380 1370/1460/1377 1374/1464/1381 +f 1374/1464/1381 1370/1460/1377 1371/1461/1378 +f 1391/1481/1398 1392/1482/1399 1371/1461/1378 +f 1371/1461/1378 1392/1482/1399 1374/1464/1381 +f 1282/1372/1289 1277/1367/1284 1391/1481/1398 +f 1391/1481/1398 1277/1367/1284 1392/1482/1399 +f 1246/1336/1253 1245/1335/1252 1419/1508/1426 +f 1419/1508/1426 1245/1335/1252 1420/1509/1427 +f 1420/1509/1427 1245/1335/1252 1421/1510/1428 +f 1421/1510/1428 1245/1335/1252 1247/1337/1254 +f 1270/1360/1277 1422/1511/1429 1247/1337/1254 +f 1247/1337/1254 1422/1511/1429 1421/1510/1428 +f 1422/1511/1429 1270/1360/1277 1423/1512/1430 +f 1423/1512/1430 1270/1360/1277 1272/1362/1279 +f 1402/1491/1409 1424/1513/1431 1272/1362/1279 +f 1272/1362/1279 1424/1513/1431 1423/1512/1430 +f 1402/1491/1409 1403/1492/1410 1424/1513/1431 +f 1424/1513/1431 1403/1492/1410 1425/1514/1432 +f 1403/1492/1410 1426/1515/1433 1425/1514/1432 +f 1425/1514/1432 1426/1515/1433 1427/1516/1434 +f 1426/1515/1433 1353/1443/1360 1427/1516/1434 +f 1427/1516/1434 1353/1443/1360 1428/1517/1435 +f 1353/1443/1360 1354/1444/1361 1428/1517/1435 +f 1428/1517/1435 1354/1444/1361 1429/1518/1436 +f 1354/1444/1361 1356/1446/1363 1429/1518/1436 +f 1429/1518/1436 1356/1446/1363 1430/1519/1437 +f 1356/1446/1363 1364/1454/1371 1430/1519/1437 +f 1430/1519/1437 1364/1454/1371 1431/1520/1438 +f 1364/1454/1371 1289/1379/1296 1431/1520/1438 +f 1431/1520/1438 1289/1379/1296 1432/1521/1439 +f 1433/1522/1440 1434/1523/1441 1291/1381/1298 +f 1291/1381/1298 1434/1523/1441 1435/1524/1442 +f 1434/1523/1441 1433/1522/1440 1436/1525/1443 +f 1436/1525/1443 1433/1522/1440 1368/1458/1375 +f 1437/1526/1444 1366/1456/1373 1438/1527/1445 +f 1438/1527/1445 1366/1456/1373 1361/1451/1368 +f 1366/1456/1373 1437/1526/1444 1368/1458/1375 +f 1368/1458/1375 1437/1526/1444 1436/1525/1443 +f 1360/1450/1367 1439/1528/1446 1361/1451/1368 +f 1361/1451/1368 1439/1528/1446 1438/1527/1445 +f 1439/1528/1446 1360/1450/1367 1440/1529/1447 +f 1440/1529/1447 1360/1450/1367 1362/1452/1369 +f 1441/1530/1448 1404/1493/1411 1442/1531/1449 +f 1442/1531/1449 1404/1493/1411 1329/1419/1336 +f 1404/1493/1411 1441/1530/1448 1362/1452/1369 +f 1362/1452/1369 1441/1530/1448 1440/1529/1447 +f 1328/1418/1335 1443/1532/1450 1329/1419/1336 +f 1329/1419/1336 1443/1532/1450 1442/1531/1449 +f 1443/1532/1450 1328/1418/1335 1444/1533/1451 +f 1444/1533/1451 1328/1418/1335 1330/1420/1337 +f 1229/1319/1236 1228/1318/1235 1330/1420/1337 +f 1330/1420/1337 1228/1318/1235 1444/1533/1451 +f 1283/1373/1290 1445/1534/1452 1280/1370/1287 +f 1280/1370/1287 1445/1534/1452 1446/1535/1453 +f 1445/1534/1452 1398/1487/1405 1446/1535/1453 +f 1446/1535/1453 1398/1487/1405 1394/1484/1401 +f 1398/1487/1405 1445/1534/1452 1399/1488/1406 +f 1399/1488/1406 1445/1534/1452 1447/1536/1454 +f 1445/1534/1452 1283/1373/1290 1447/1536/1454 +f 1447/1536/1454 1283/1373/1290 1285/1375/1292 +f 1432/1521/1439 1289/1379/1296 1435/1524/1442 +f 1435/1524/1442 1289/1379/1296 1291/1381/1298 +f 1448/1537/1455 1321/1411/1328 1375/1465/1382 +f 1375/1465/1382 1321/1411/1328 1449/1538/1456 +f 1321/1411/1328 1448/1537/1455 1300/1390/1307 +f 1300/1390/1307 1448/1537/1455 1377/1467/1384 +f 1448/1537/1455 1450/1539/1457 1377/1467/1384 +f 1377/1467/1384 1450/1539/1457 1451/1540/1458 +f 1450/1539/1457 1448/1537/1455 1376/1466/1383 +f 1376/1466/1383 1448/1537/1455 1375/1465/1382 +f 1410/1499/1417 1416/1505/1423 1324/1414/1331 +f 1324/1414/1331 1416/1505/1423 1323/1413/1330 +f 1323/1413/1330 1416/1505/1423 1274/1364/1281 +f 1274/1364/1281 1416/1505/1423 1258/1348/1265 +f 1452/1541/1459 1450/1539/1457 1393/1483/1400 +f 1393/1483/1400 1450/1539/1457 1376/1466/1383 +f 1450/1539/1457 1452/1541/1459 1451/1540/1458 +f 1451/1540/1458 1452/1541/1459 1453/1542/1460 +f 1413/1502/1420 1454/1543/1461 1315/1405/1322 +f 1315/1405/1322 1454/1543/1461 1320/1410/1327 +f 1320/1410/1327 1454/1543/1461 1324/1414/1331 +f 1324/1414/1331 1454/1543/1461 1409/1498/1416 +f 1454/1543/1461 1346/1436/1353 1409/1498/1416 +f 1409/1498/1416 1346/1436/1353 1348/1438/1355 +f 1454/1543/1461 1413/1502/1420 1346/1436/1353 +f 1346/1436/1353 1413/1502/1420 1345/1435/1352 +f 1455/1544/1462 1452/1541/1459 1279/1369/1286 +f 1279/1369/1286 1452/1541/1459 1393/1483/1400 +f 1452/1541/1459 1455/1544/1462 1453/1542/1460 +f 1453/1542/1460 1455/1544/1462 1395/1485/1402 +f 1293/1383/1300 1415/1504/1422 1294/1384/1301 +f 1294/1384/1301 1415/1504/1422 1349/1439/1356 +f 1415/1504/1422 1407/1496/1414 1349/1439/1356 +f 1349/1439/1356 1407/1496/1414 1348/1438/1355 +f 1446/1535/1453 1455/1544/1462 1280/1370/1287 +f 1280/1370/1287 1455/1544/1462 1279/1369/1286 +f 1433/1522/1440 1456/1545/1463 1368/1458/1375 +f 1368/1458/1375 1456/1545/1463 1367/1457/1374 +f 1456/1545/1463 1350/1440/1357 1367/1457/1374 +f 1367/1457/1374 1350/1440/1357 1339/1429/1346 +f 1350/1440/1357 1456/1545/1463 1294/1384/1301 +f 1294/1384/1301 1456/1545/1463 1292/1382/1299 +f 1456/1545/1463 1433/1522/1440 1292/1382/1299 +f 1292/1382/1299 1433/1522/1440 1291/1381/1298 +f 1281/1371/1288 1282/1372/1289 1390/1480/1397 +f 1390/1480/1397 1282/1372/1289 1391/1481/1398 +f 1233/1323/1240 1234/1324/1241 1255/1345/1262 +f 1255/1345/1262 1234/1324/1241 1235/1325/1242 +f 1274/1364/1281 1275/1365/1282 1322/1412/1329 +f 1275/1365/1282 1449/1538/1456 1322/1412/1329 +f 1321/1411/1328 1322/1412/1329 1449/1538/1456 +f 1457/1546/1464 1229/1319/1236 1326/1416/1333 +f 1326/1416/1333 1229/1319/1236 1330/1420/1337 +f 1229/1319/1236 1457/1546/1464 1226/1316/1233 +f 1226/1316/1233 1457/1546/1464 1227/1317/1234 +f 1296/1386/1303 1457/1546/1464 1298/1388/1305 +f 1298/1388/1305 1457/1546/1464 1326/1416/1333 +f 1401/1490/1408 1458/1547/1465 1403/1492/1410 +f 1403/1492/1410 1458/1547/1465 1426/1515/1433 +f 1458/1547/1465 1351/1441/1358 1426/1515/1433 +f 1426/1515/1433 1351/1441/1358 1353/1443/1360 +f 1351/1441/1358 1458/1547/1465 1333/1423/1340 +f 1333/1423/1340 1458/1547/1465 1412/1501/1419 +f 1458/1547/1465 1401/1490/1408 1412/1501/1419 +f 1412/1501/1419 1401/1490/1408 1311/1401/1318 +f 1331/1421/1338 1411/1500/1418 1407/1496/1414 +f 1407/1496/1414 1411/1500/1418 1408/1497/1415 +f 1411/1500/1418 1312/1402/1319 1408/1497/1415 +f 1408/1497/1415 1312/1402/1319 1410/1499/1417 +f 1299/1389/1306 1313/1403/1320 1322/1412/1329 +f 1322/1412/1329 1313/1403/1320 1319/1409/1326 +f 1314/1404/1321 1313/1403/1320 1297/1387/1304 +f 1297/1387/1304 1313/1403/1320 1299/1389/1306 +f 1451/1540/1458 1453/1542/1460 1381/1471/1388 +f 1381/1471/1388 1453/1542/1460 1395/1485/1402 +f 1377/1467/1384 1451/1540/1458 1378/1468/1385 +f 1378/1468/1385 1451/1540/1458 1381/1471/1388 +f 1395/1485/1402 1455/1544/1462 1394/1484/1401 +f 1394/1484/1401 1455/1544/1462 1446/1535/1453 +f 1380/1470/1387 1305/1395/1312 1378/1468/1385 +f 1378/1468/1385 1305/1395/1312 1302/1392/1309 +f 1306/1396/1313 1301/1391/1308 1305/1395/1312 +f 1305/1395/1312 1301/1391/1308 1302/1392/1309 +f 1301/1391/1308 1306/1396/1313 1218/1308/1225 +f 1218/1308/1225 1306/1396/1313 1224/1314/1231 +f 1224/1314/1231 1225/1315/1232 1218/1308/1225 +f 1218/1308/1225 1225/1315/1232 1217/1307/1224 +f 1227/1317/1234 1215/1305/1222 1225/1315/1232 +f 1225/1315/1232 1215/1305/1222 1217/1307/1224 +f 1457/1546/1464 1296/1386/1303 1227/1317/1234 +f 1227/1317/1234 1296/1386/1303 1215/1305/1222 +f 1459/1548/1466 1460/1549/1467 1419/1550/1426 +f 1419/1550/1426 1460/1549/1467 1246/1551/1253 +f 1461/1552/1468 1460/1549/1467 1213/1303/1220 +f 1213/1303/1220 1460/1549/1467 1029/1099/1036 +f 1213/1303/1220 1029/1099/1036 1214/1304/1221 +f 1214/1304/1221 1029/1099/1036 1027/1097/1034 +f 1024/1094/1031 1025/1095/1032 1027/1097/1034 +f 1027/1097/1034 1025/1095/1032 1214/1304/1221 +f 1023/1093/1030 1024/1094/1031 1026/1096/1033 +f 1026/1096/1033 1024/1094/1031 1027/1097/1034 +f 1462/1553/1469 1463/1554/1470 1236/1555/1243 +f 1236/1555/1243 1463/1554/1470 1235/1556/1242 +f 1464/1557/1471 1463/1554/1470 1014/1084/1021 +f 1014/1084/1021 1463/1554/1470 1212/1302/1219 +f 1465/1558/1472 1466/1559/1473 1467/1560/1474 +f 1467/1560/1474 1466/1559/1473 1468/1561/1475 +f 1469/1562/1476 1470/1563/1477 1471/1564/1478 +f 1471/1564/1478 1470/1563/1477 1019/1089/1026 +f 1462/1553/1469 1461/1552/1468 1211/1301/1218 +f 1211/1301/1218 1461/1552/1468 1213/1303/1220 +f 1465/1558/1472 1464/1557/1471 1015/1085/1022 +f 1015/1085/1022 1464/1557/1471 1014/1084/1021 +f 1417/1506/1424 1467/1565/1474 1253/1343/1260 +f 1253/1343/1260 1467/1565/1474 1260/1350/1267 +f 1239/1329/1246 1263/1353/1270 1237/1327/1244 +f 1237/1327/1244 1263/1353/1270 1468/1566/1475 +f 1472/1567/1479 1466/1559/1473 1017/1087/1024 +f 1017/1087/1024 1466/1559/1473 1016/1086/1023 +f 1263/1353/1270 1260/1350/1267 1468/1566/1475 +f 1468/1566/1475 1260/1350/1267 1467/1565/1474 +f 1460/1549/1467 1459/1548/1466 1029/1099/1036 +f 1029/1099/1036 1459/1548/1466 1028/1098/1035 +f 1470/1563/1477 1469/1562/1476 1238/1568/1245 +f 1238/1568/1245 1469/1562/1476 1242/1569/1249 +f 1246/1551/1253 1460/1549/1467 1244/1570/1251 +f 1244/1570/1251 1460/1549/1467 1461/1552/1468 +f 1244/1570/1251 1461/1552/1468 1236/1555/1243 +f 1236/1555/1243 1461/1552/1468 1462/1553/1469 +f 1212/1302/1219 1463/1554/1470 1211/1301/1218 +f 1211/1301/1218 1463/1554/1470 1462/1553/1469 +f 1463/1554/1470 1464/1557/1471 1235/1556/1242 +f 1235/1556/1242 1464/1557/1471 1417/1571/1424 +f 1464/1557/1471 1465/1558/1472 1417/1571/1424 +f 1417/1571/1424 1465/1558/1472 1467/1560/1474 +f 1466/1559/1473 1465/1558/1472 1016/1086/1023 +f 1016/1086/1023 1465/1558/1472 1015/1085/1022 +f 1466/1559/1473 1472/1567/1479 1468/1561/1475 +f 1468/1561/1475 1472/1567/1479 1237/1572/1244 +f 1472/1567/1479 1470/1563/1477 1237/1572/1244 +f 1237/1572/1244 1470/1563/1477 1238/1568/1245 +f 1473/1573/1480 1373/1463/1380 1449/1538/1456 +f 1449/1538/1456 1373/1463/1380 1375/1465/1382 +f 1370/1460/1377 1373/1463/1380 1264/1354/1271 +f 1264/1354/1271 1373/1463/1380 1473/1573/1480 +f 1262/1352/1269 1264/1354/1271 1474/1574/1481 +f 1474/1574/1481 1264/1354/1271 1473/1573/1480 +f 1473/1573/1480 1449/1538/1456 1276/1366/1283 +f 1276/1366/1283 1449/1538/1456 1275/1365/1282 +f 1474/1574/1481 1473/1573/1480 1418/1507/1425 +f 1418/1507/1425 1473/1573/1480 1276/1366/1283 +f 1474/1574/1481 1418/1507/1425 1263/1353/1270 +f 1263/1353/1270 1418/1507/1425 1260/1350/1267 +f 1263/1353/1270 1262/1352/1269 1474/1574/1481 +f 1418/1507/1425 1276/1366/1283 1259/1349/1266 +f 1259/1349/1266 1276/1366/1283 1257/1347/1264 +f 1017/1087/1024 1019/1089/1026 1472/1567/1479 +f 1472/1567/1479 1019/1089/1026 1470/1563/1477 +f 833/903/840 850/920/857 831/901/838 +f 831/901/838 850/920/857 849/919/856 +f 850/920/857 864/934/871 849/919/856 +f 849/919/856 864/934/871 863/933/870 +f 864/934/871 878/948/885 863/933/870 +f 863/933/870 878/948/885 877/947/884 +f 878/948/885 892/962/899 877/947/884 +f 877/947/884 892/962/899 891/961/898 +f 891/961/898 892/962/899 905/975/912 +f 905/975/912 892/962/899 362/402/369 +f 362/402/369 365/405/372 905/975/912 +f 905/975/912 365/405/372 917/987/924 +f 1003/1073/1010 1022/1092/1029 1010/1080/1017 +f 1010/1080/1017 1022/1092/1029 1018/1088/1025 +f 811/881/818 1475/1575/1482 810/880/817 +f 810/880/817 1475/1575/1482 1476/1576/1483 +f 1475/1575/1482 1477/1577/1484 1476/1576/1483 +f 1476/1576/1483 1477/1577/1484 1478/1578/1485 +f 1477/1577/1484 1479/1579/1486 1478/1578/1485 +f 1478/1578/1485 1479/1579/1486 1480/1580/1487 +f 1479/1579/1486 1481/1581/1488 1480/1580/1487 +f 1480/1580/1487 1481/1581/1488 1482/1582/1489 +f 1481/1581/1488 1483/1583/1490 1482/1582/1489 +f 1482/1582/1489 1483/1583/1490 1484/1584/1491 +f 1483/1583/1490 1485/1585/1492 1484/1584/1491 +f 1484/1584/1491 1485/1585/1492 1486/1586/1493 +f 1485/1585/1492 1487/1587/1494 1486/1586/1493 +f 1486/1586/1493 1487/1587/1494 1488/1588/1495 +f 1487/1587/1494 1489/1589/1496 1488/1588/1495 +f 1488/1588/1495 1489/1589/1496 1490/1590/1497 +f 1490/1590/1497 1489/1589/1496 1491/1591/1498 +f 1491/1591/1498 1489/1589/1496 1492/1592/1499 +f 1491/1591/1498 1492/1592/1499 1493/1593/1500 +f 1493/1593/1500 1492/1592/1499 1494/1594/1501 +f 1494/1594/1501 1495/1595/1502 1493/1593/1500 +f 1493/1593/1500 1495/1595/1502 1496/1596/1503 +f 1495/1595/1502 1497/1597/1504 1496/1596/1503 +f 1496/1596/1503 1497/1597/1504 1498/1598/1505 +f 1497/1597/1504 1499/1599/1506 1498/1598/1505 +f 1498/1598/1505 1499/1599/1506 1500/1600/1507 +f 839/909/846 1501/1601/1508 811/881/818 +f 811/881/818 1501/1601/1508 1475/1575/1482 +f 1501/1601/1508 1502/1602/1509 1475/1575/1482 +f 1475/1575/1482 1502/1602/1509 1477/1577/1484 +f 1502/1602/1509 1503/1603/1510 1477/1577/1484 +f 1477/1577/1484 1503/1603/1510 1479/1579/1486 +f 1503/1603/1510 1504/1604/1511 1479/1579/1486 +f 1479/1579/1486 1504/1604/1511 1481/1581/1488 +f 1504/1604/1511 1505/1605/1512 1481/1581/1488 +f 1481/1581/1488 1505/1605/1512 1483/1583/1490 +f 1505/1605/1512 1506/1606/1513 1483/1583/1490 +f 1483/1583/1490 1506/1606/1513 1485/1585/1492 +f 1506/1606/1513 1507/1607/1514 1485/1585/1492 +f 1485/1585/1492 1507/1607/1514 1487/1587/1494 +f 1507/1607/1514 1508/1608/1515 1487/1587/1494 +f 1487/1587/1494 1508/1608/1515 1489/1589/1496 +f 1489/1589/1496 1508/1608/1515 1492/1592/1499 +f 1492/1592/1499 1508/1608/1515 1509/1609/1516 +f 1492/1592/1499 1509/1609/1516 1494/1594/1501 +f 1494/1594/1501 1509/1609/1516 1510/1610/1517 +f 1510/1610/1517 1511/1611/1518 1494/1594/1501 +f 1494/1594/1501 1511/1611/1518 1495/1595/1502 +f 1512/1612/1519 1513/1613/1520 1497/1597/1504 +f 1497/1597/1504 1513/1613/1520 1499/1599/1506 +f 853/923/860 1514/1614/1521 839/909/846 +f 839/909/846 1514/1614/1521 1501/1601/1508 +f 1514/1614/1521 1515/1615/1522 1501/1601/1508 +f 1501/1601/1508 1515/1615/1522 1502/1602/1509 +f 1515/1615/1522 1516/1616/1523 1502/1602/1509 +f 1502/1602/1509 1516/1616/1523 1503/1603/1510 +f 1516/1616/1523 1517/1617/1524 1503/1603/1510 +f 1503/1603/1510 1517/1617/1524 1504/1604/1511 +f 1517/1617/1524 1518/1618/1525 1504/1604/1511 +f 1504/1604/1511 1518/1618/1525 1505/1605/1512 +f 1518/1618/1525 1519/1619/1526 1505/1605/1512 +f 1505/1605/1512 1519/1619/1526 1506/1606/1513 +f 1519/1619/1526 1520/1620/1527 1506/1606/1513 +f 1506/1606/1513 1520/1620/1527 1507/1607/1514 +f 1520/1620/1527 1521/1621/1528 1507/1607/1514 +f 1507/1607/1514 1521/1621/1528 1508/1608/1515 +f 1508/1608/1515 1521/1621/1528 1509/1609/1516 +f 1509/1609/1516 1521/1621/1528 1522/1622/1529 +f 1509/1609/1516 1522/1622/1529 1510/1610/1517 +f 1510/1610/1517 1522/1622/1529 1523/1623/1530 +f 1510/1610/1517 1523/1623/1530 1511/1611/1518 +f 1511/1611/1518 1523/1623/1530 1524/1624/1531 +f 1525/1625/1532 1526/1626/1533 1512/1612/1519 +f 1512/1612/1519 1526/1626/1533 1513/1613/1520 +f 853/923/860 866/936/873 1514/1614/1521 +f 1514/1614/1521 866/936/873 1527/1627/1534 +f 1527/1627/1534 1528/1628/1535 1514/1614/1521 +f 1514/1614/1521 1528/1628/1535 1515/1615/1522 +f 1528/1628/1535 1529/1629/1536 1515/1615/1522 +f 1515/1615/1522 1529/1629/1536 1516/1616/1523 +f 1529/1629/1536 1530/1630/1537 1516/1616/1523 +f 1516/1616/1523 1530/1630/1537 1517/1617/1524 +f 1530/1630/1537 1531/1631/1538 1517/1617/1524 +f 1517/1617/1524 1531/1631/1538 1518/1618/1525 +f 1531/1631/1538 1532/1632/1539 1518/1618/1525 +f 1518/1618/1525 1532/1632/1539 1519/1619/1526 +f 1532/1632/1539 1533/1633/1540 1519/1619/1526 +f 1519/1619/1526 1533/1633/1540 1520/1620/1527 +f 1533/1633/1540 1534/1634/1541 1520/1620/1527 +f 1520/1620/1527 1534/1634/1541 1521/1621/1528 +f 1521/1621/1528 1534/1634/1541 1522/1622/1529 +f 1522/1622/1529 1534/1634/1541 1535/1635/1542 +f 1535/1635/1542 1536/1636/1543 1522/1622/1529 +f 1522/1622/1529 1536/1636/1543 1523/1623/1530 +f 1523/1623/1530 1536/1636/1543 1524/1624/1531 +f 1524/1624/1531 1536/1636/1543 1537/1637/1544 +f 1538/1638/1545 1539/1639/1546 1525/1625/1532 +f 1525/1625/1532 1539/1639/1546 1526/1626/1533 +f 866/936/873 880/950/887 1527/1627/1534 +f 1527/1627/1534 880/950/887 1540/1640/1547 +f 1540/1640/1547 1541/1641/1548 1527/1627/1534 +f 1527/1627/1534 1541/1641/1548 1528/1628/1535 +f 1541/1641/1548 1542/1642/1549 1528/1628/1535 +f 1528/1628/1535 1542/1642/1549 1529/1629/1536 +f 1542/1642/1549 1543/1643/1550 1529/1629/1536 +f 1529/1629/1536 1543/1643/1550 1530/1630/1537 +f 1543/1643/1550 1544/1644/1551 1530/1630/1537 +f 1530/1630/1537 1544/1644/1551 1531/1631/1538 +f 1544/1644/1551 1545/1645/1552 1531/1631/1538 +f 1531/1631/1538 1545/1645/1552 1532/1632/1539 +f 1545/1645/1552 1546/1646/1553 1532/1632/1539 +f 1532/1632/1539 1546/1646/1553 1533/1633/1540 +f 1546/1646/1553 1547/1647/1554 1533/1633/1540 +f 1533/1633/1540 1547/1647/1554 1534/1634/1541 +f 1534/1634/1541 1547/1647/1554 1535/1635/1542 +f 1535/1635/1542 1547/1647/1554 1548/1648/1555 +f 1548/1648/1555 1549/1649/1556 1535/1635/1542 +f 1535/1635/1542 1549/1649/1556 1536/1636/1543 +f 1549/1649/1556 1550/1650/1557 1536/1636/1543 +f 1536/1636/1543 1550/1650/1557 1537/1637/1544 +f 1551/1651/1558 1552/1652/1559 1538/1638/1545 +f 1538/1638/1545 1552/1652/1559 1539/1639/1546 +f 880/950/887 894/964/901 1540/1640/1547 +f 1540/1640/1547 894/964/901 1553/1653/1560 +f 1553/1653/1560 1554/1654/1561 1540/1640/1547 +f 1540/1640/1547 1554/1654/1561 1541/1641/1548 +f 1554/1654/1561 1555/1655/1562 1541/1641/1548 +f 1541/1641/1548 1555/1655/1562 1542/1642/1549 +f 1555/1655/1562 1556/1656/1563 1542/1642/1549 +f 1542/1642/1549 1556/1656/1563 1543/1643/1550 +f 1556/1656/1563 1557/1657/1564 1543/1643/1550 +f 1543/1643/1550 1557/1657/1564 1544/1644/1551 +f 1557/1657/1564 1558/1658/1565 1544/1644/1551 +f 1544/1644/1551 1558/1658/1565 1545/1645/1552 +f 1558/1658/1565 1559/1659/1566 1545/1645/1552 +f 1545/1645/1552 1559/1659/1566 1546/1646/1553 +f 1559/1659/1566 1560/1660/1567 1546/1646/1553 +f 1546/1646/1553 1560/1660/1567 1547/1647/1554 +f 1547/1647/1554 1560/1660/1567 1548/1648/1555 +f 1548/1648/1555 1560/1660/1567 1561/1661/1568 +f 1561/1661/1568 1562/1662/1569 1548/1648/1555 +f 1548/1648/1555 1562/1662/1569 1549/1649/1556 +f 1562/1662/1569 1563/1663/1570 1549/1649/1556 +f 1549/1649/1556 1563/1663/1570 1550/1650/1557 +f 1564/1664/1571 1552/1652/1559 436/477/443 +f 436/477/443 1552/1652/1559 437/478/444 +f 894/964/901 906/976/913 1553/1653/1560 +f 1553/1653/1560 906/976/913 1565/1665/1572 +f 1565/1665/1572 1566/1666/1573 1553/1653/1560 +f 1553/1653/1560 1566/1666/1573 1554/1654/1561 +f 1566/1666/1573 1567/1667/1574 1554/1654/1561 +f 1554/1654/1561 1567/1667/1574 1555/1655/1562 +f 1567/1667/1574 1568/1668/1575 1555/1655/1562 +f 1555/1655/1562 1568/1668/1575 1556/1656/1563 +f 1568/1668/1575 1569/1669/1576 1556/1656/1563 +f 1556/1656/1563 1569/1669/1576 1557/1657/1564 +f 1569/1669/1576 1570/1670/1577 1557/1657/1564 +f 1557/1657/1564 1570/1670/1577 1558/1658/1565 +f 1570/1670/1577 1571/1671/1578 1558/1658/1565 +f 1558/1658/1565 1571/1671/1578 1559/1659/1566 +f 1571/1671/1578 1572/1672/1579 1559/1659/1566 +f 1559/1659/1566 1572/1672/1579 1560/1660/1567 +f 1560/1660/1567 1572/1672/1579 1561/1661/1568 +f 1561/1661/1568 1572/1672/1579 1573/1673/1580 +f 1561/1661/1568 1573/1673/1580 1562/1662/1569 +f 1562/1662/1569 1573/1673/1580 1574/1674/1581 +f 1574/1674/1581 1575/1675/1582 1562/1662/1569 +f 1562/1662/1569 1575/1675/1582 1563/1663/1570 +f 906/976/913 918/988/925 1565/1665/1572 +f 1565/1665/1572 918/988/925 1576/1676/1583 +f 1576/1676/1583 1577/1677/1584 1565/1665/1572 +f 1565/1665/1572 1577/1677/1584 1566/1666/1573 +f 1577/1677/1584 1578/1678/1585 1566/1666/1573 +f 1566/1666/1573 1578/1678/1585 1567/1667/1574 +f 1578/1678/1585 1579/1679/1586 1567/1667/1574 +f 1567/1667/1574 1579/1679/1586 1568/1668/1575 +f 1579/1679/1586 1580/1680/1587 1568/1668/1575 +f 1568/1668/1575 1580/1680/1587 1569/1669/1576 +f 1580/1680/1587 1581/1681/1588 1569/1669/1576 +f 1569/1669/1576 1581/1681/1588 1570/1670/1577 +f 1581/1681/1588 1582/1682/1589 1570/1670/1577 +f 1570/1670/1577 1582/1682/1589 1571/1671/1578 +f 1582/1682/1589 1583/1683/1590 1571/1671/1578 +f 1571/1671/1578 1583/1683/1590 1572/1672/1579 +f 1572/1672/1579 1583/1683/1590 1573/1673/1580 +f 1573/1673/1580 1583/1683/1590 1584/1684/1591 +f 1584/1684/1591 1585/1685/1592 1573/1673/1580 +f 1573/1673/1580 1585/1685/1592 1574/1674/1581 +f 1585/1685/1592 1586/1686/1593 1574/1674/1581 +f 1574/1674/1581 1586/1686/1593 1575/1675/1582 +f 918/988/925 930/1000/937 1576/1676/1583 +f 1576/1676/1583 930/1000/937 1587/1687/1594 +f 1587/1687/1594 1588/1688/1595 1576/1676/1583 +f 1576/1676/1583 1588/1688/1595 1577/1677/1584 +f 1588/1688/1595 1589/1689/1596 1577/1677/1584 +f 1577/1677/1584 1589/1689/1596 1578/1678/1585 +f 1589/1689/1596 1590/1690/1597 1578/1678/1585 +f 1578/1678/1585 1590/1690/1597 1579/1679/1586 +f 1590/1690/1597 1591/1691/1598 1579/1679/1586 +f 1579/1679/1586 1591/1691/1598 1580/1680/1587 +f 1591/1691/1598 1592/1692/1599 1580/1680/1587 +f 1580/1680/1587 1592/1692/1599 1581/1681/1588 +f 1592/1692/1599 1593/1693/1600 1581/1681/1588 +f 1581/1681/1588 1593/1693/1600 1582/1682/1589 +f 1593/1693/1600 1594/1694/1601 1582/1682/1589 +f 1582/1682/1589 1594/1694/1601 1583/1683/1590 +f 1583/1683/1590 1594/1694/1601 1584/1684/1591 +f 1584/1684/1591 1594/1694/1601 1595/1695/1602 +f 1595/1695/1602 1596/1696/1603 1584/1684/1591 +f 1584/1684/1591 1596/1696/1603 1585/1685/1592 +f 1596/1696/1603 1597/1697/1604 1585/1685/1592 +f 1585/1685/1592 1597/1697/1604 1586/1686/1593 +f 930/1000/937 942/1012/949 1587/1687/1594 +f 1587/1687/1594 942/1012/949 1598/1698/1605 +f 1598/1698/1605 1599/1699/1606 1587/1687/1594 +f 1587/1687/1594 1599/1699/1606 1588/1688/1595 +f 1599/1699/1606 1600/1700/1607 1588/1688/1595 +f 1588/1688/1595 1600/1700/1607 1589/1689/1596 +f 1600/1700/1607 1601/1701/1608 1589/1689/1596 +f 1589/1689/1596 1601/1701/1608 1590/1690/1597 +f 1601/1701/1608 1602/1702/1609 1590/1690/1597 +f 1590/1690/1597 1602/1702/1609 1591/1691/1598 +f 1602/1702/1609 1603/1703/1610 1591/1691/1598 +f 1591/1691/1598 1603/1703/1610 1592/1692/1599 +f 1603/1703/1610 1604/1704/1611 1592/1692/1599 +f 1592/1692/1599 1604/1704/1611 1593/1693/1600 +f 1604/1704/1611 1605/1705/1612 1593/1693/1600 +f 1593/1693/1600 1605/1705/1612 1594/1694/1601 +f 1594/1694/1601 1605/1705/1612 1595/1695/1602 +f 1595/1695/1602 1605/1705/1612 1606/1706/1613 +f 1595/1695/1602 1606/1706/1613 1596/1696/1603 +f 1596/1696/1603 1606/1706/1613 1607/1707/1614 +f 1596/1696/1603 1607/1707/1614 1597/1697/1604 +f 1597/1697/1604 1607/1707/1614 1608/1708/1615 +f 942/1012/949 954/1024/961 1598/1698/1605 +f 1598/1698/1605 954/1024/961 1609/1709/1616 +f 1609/1709/1616 1610/1710/1617 1598/1698/1605 +f 1598/1698/1605 1610/1710/1617 1599/1699/1606 +f 1610/1710/1617 1611/1711/1618 1599/1699/1606 +f 1599/1699/1606 1611/1711/1618 1600/1700/1607 +f 1611/1711/1618 1612/1712/1619 1600/1700/1607 +f 1600/1700/1607 1612/1712/1619 1601/1701/1608 +f 1612/1712/1619 1613/1713/1620 1601/1701/1608 +f 1601/1701/1608 1613/1713/1620 1602/1702/1609 +f 1613/1713/1620 1614/1714/1621 1602/1702/1609 +f 1602/1702/1609 1614/1714/1621 1603/1703/1610 +f 1614/1714/1621 1615/1715/1622 1603/1703/1610 +f 1603/1703/1610 1615/1715/1622 1604/1704/1611 +f 1604/1704/1611 1615/1715/1622 1605/1705/1612 +f 1605/1705/1612 1615/1715/1622 1616/1716/1623 +f 1605/1705/1612 1616/1716/1623 1606/1706/1613 +f 1606/1706/1613 1616/1716/1623 1617/1717/1624 +f 1606/1706/1613 1617/1717/1624 1607/1707/1614 +f 1607/1707/1614 1617/1717/1624 1618/1718/1625 +f 1607/1707/1614 1618/1718/1625 1608/1708/1615 +f 1608/1708/1615 1618/1718/1625 1619/1719/1626 +f 954/1024/961 966/1036/973 1609/1709/1616 +f 1609/1709/1616 966/1036/973 1620/1720/1627 +f 1609/1709/1616 1620/1720/1627 1610/1710/1617 +f 1610/1710/1617 1620/1720/1627 1621/1721/1628 +f 1610/1710/1617 1621/1721/1628 1611/1711/1618 +f 1611/1711/1618 1621/1721/1628 1622/1722/1629 +f 1611/1711/1618 1622/1722/1629 1612/1712/1619 +f 1612/1712/1619 1622/1722/1629 1623/1723/1630 +f 1623/1723/1630 1624/1724/1631 1612/1712/1619 +f 1612/1712/1619 1624/1724/1631 1613/1713/1620 +f 1624/1724/1631 1625/1725/1632 1613/1713/1620 +f 1613/1713/1620 1625/1725/1632 1614/1714/1621 +f 1625/1725/1632 1626/1726/1633 1614/1714/1621 +f 1614/1714/1621 1626/1726/1633 1615/1715/1622 +f 1615/1715/1622 1626/1726/1633 1616/1716/1623 +f 1616/1716/1623 1626/1726/1633 1627/1727/1634 +f 1616/1716/1623 1627/1727/1634 1617/1717/1624 +f 1617/1717/1624 1627/1727/1634 1628/1728/1635 +f 1617/1717/1624 1628/1728/1635 1618/1718/1625 +f 1618/1718/1625 1628/1728/1635 1629/1729/1636 +f 1618/1718/1625 1629/1729/1636 1619/1719/1626 +f 1619/1719/1626 1629/1729/1636 1630/1730/1637 +f 966/1036/973 978/1048/985 1620/1720/1627 +f 1620/1720/1627 978/1048/985 1631/1731/1638 +f 1620/1720/1627 1631/1731/1638 1621/1721/1628 +f 1621/1721/1628 1631/1731/1638 1632/1732/1639 +f 1621/1721/1628 1632/1732/1639 1622/1722/1629 +f 1622/1722/1629 1632/1732/1639 1633/1733/1640 +f 1625/1725/1632 1634/1734/1641 1626/1726/1633 +f 1634/1734/1641 1635/1735/1642 1626/1726/1633 +f 1626/1726/1633 1635/1735/1642 1627/1727/1634 +f 1635/1735/1642 1636/1736/1643 1627/1727/1634 +f 1627/1727/1634 1636/1736/1643 1628/1728/1635 +f 1636/1736/1643 1637/1737/1644 1628/1728/1635 +f 1628/1728/1635 1637/1737/1644 1629/1729/1636 +f 1629/1729/1636 1637/1737/1644 1630/1730/1637 +f 1630/1730/1637 1637/1737/1644 1638/1738/1645 +f 978/1048/985 987/1057/994 1631/1731/1638 +f 1631/1731/1638 987/1057/994 1639/1739/1646 +f 1631/1731/1638 1639/1739/1646 1632/1732/1639 +f 1632/1732/1639 1639/1739/1646 1640/1740/1647 +f 987/1057/994 990/1060/997 1639/1739/1646 +f 1639/1739/1646 990/1060/997 1641/1741/1648 +f 1641/1741/1648 1642/1742/1649 1639/1739/1646 +f 1639/1739/1646 1642/1742/1649 1640/1740/1647 +f 1643/1743/1650 1636/1736/1643 1644/1744/1651 +f 1644/1744/1651 1636/1736/1643 1635/1735/1642 +f 1643/1743/1650 1645/1745/1652 1636/1736/1643 +f 1636/1736/1643 1645/1745/1652 1637/1737/1644 +f 1637/1737/1644 1645/1745/1652 1638/1738/1645 +f 1638/1738/1645 1645/1745/1652 1646/1746/1653 +f 990/1060/997 997/1067/1004 1641/1741/1648 +f 1641/1741/1648 997/1067/1004 1647/1747/1654 +f 1647/1747/1654 1648/1748/1655 1641/1741/1648 +f 1641/1741/1648 1648/1748/1655 1642/1742/1649 +f 1643/1743/1650 1644/1744/1651 1649/1749/1656 +f 1649/1749/1656 1644/1744/1651 1650/1750/1657 +f 1643/1743/1650 1649/1749/1656 1645/1745/1652 +f 1645/1745/1652 1649/1749/1656 1651/1751/1658 +f 1645/1745/1652 1651/1751/1658 1646/1746/1653 +f 1646/1746/1653 1651/1751/1658 1652/1752/1659 +f 997/1067/1004 1004/1074/1011 1647/1747/1654 +f 1647/1747/1654 1004/1074/1011 1653/1753/1660 +f 1647/1747/1654 1653/1753/1660 1648/1748/1655 +f 1648/1748/1655 1653/1753/1660 1654/1754/1661 +f 1655/1755/1662 1649/1749/1656 1656/1756/1663 +f 1656/1756/1663 1649/1749/1656 1650/1750/1657 +f 1649/1749/1656 1655/1755/1662 1651/1751/1658 +f 1651/1751/1658 1655/1755/1662 1657/1757/1664 +f 1651/1751/1658 1657/1757/1664 1652/1752/1659 +f 1652/1752/1659 1657/1757/1664 1658/1758/1665 +f 1004/1074/1011 1011/1081/1018 1653/1753/1660 +f 1653/1753/1660 1011/1081/1018 1659/1759/1666 +f 1653/1753/1660 1659/1759/1666 1654/1754/1661 +f 1654/1754/1661 1659/1759/1666 1660/1760/1667 +f 1661/1761/1668 1655/1755/1662 1662/1762/1669 +f 1662/1762/1669 1655/1755/1662 1656/1756/1663 +f 1655/1755/1662 1661/1761/1668 1657/1757/1664 +f 1657/1757/1664 1661/1761/1668 1663/1763/1670 +f 1657/1757/1664 1663/1763/1670 1658/1758/1665 +f 1658/1758/1665 1663/1763/1670 1664/1764/1671 +f 1658/1758/1665 1664/1764/1671 1665/1765/1672 +f 1665/1765/1672 1664/1764/1671 1666/1766/1673 +f 1665/1765/1672 1020/1090/1027 1667/1767/1674 +f 1667/1767/1674 1020/1090/1027 1021/1091/1028 +f 1011/1081/1018 1023/1093/1030 1659/1759/1666 +f 1659/1759/1666 1023/1093/1030 1668/1768/1675 +f 1659/1759/1666 1668/1768/1675 1660/1760/1667 +f 1660/1760/1667 1668/1768/1675 1669/1769/1676 +f 1026/1096/1033 1028/1098/1035 1670/1770/1677 +f 1670/1770/1677 1028/1098/1035 1671/1771/1678 +f 1476/1576/1483 1030/1100/1037 810/880/817 +f 1478/1578/1485 1030/1100/1037 1476/1576/1483 +f 1480/1580/1487 1030/1100/1037 1478/1578/1485 +f 1482/1582/1489 1030/1100/1037 1480/1580/1487 +f 1484/1584/1491 1030/1100/1037 1482/1582/1489 +f 1486/1586/1493 1030/1100/1037 1484/1584/1491 +f 1488/1588/1495 1030/1100/1037 1486/1586/1493 +f 1490/1590/1497 1030/1100/1037 1488/1588/1495 +f 1491/1591/1498 1030/1100/1037 1490/1590/1497 +f 1493/1593/1500 1030/1100/1037 1491/1591/1498 +f 1496/1596/1503 1030/1100/1037 1493/1593/1500 +f 1496/1596/1503 1498/1598/1505 1030/1100/1037 +f 1500/1600/1507 1030/1100/1037 1498/1598/1505 +f 1672/1772/1679 1673/1773/1680 1674/1774/1681 +f 1674/1774/1681 1673/1773/1680 1675/1775/1682 +f 1673/1773/1680 1672/1772/1679 1676/1776/1683 +f 1676/1776/1683 1672/1772/1679 1677/1777/1684 +f 1678/1778/1685 1673/1773/1680 1679/1779/1686 +f 1679/1779/1686 1673/1773/1680 1676/1776/1683 +f 1673/1773/1680 1678/1778/1685 1675/1775/1682 +f 1675/1775/1682 1678/1778/1685 1680/1780/1687 +f 1681/1781/1688 1682/1782/1689 1683/1783/1690 +f 1683/1783/1690 1682/1782/1689 1684/1784/1691 +f 1682/1782/1689 1681/1781/1688 1685/1785/1692 +f 1685/1785/1692 1681/1781/1688 1686/1786/1693 +f 1672/1772/1679 1682/1782/1689 1677/1777/1684 +f 1677/1777/1684 1682/1782/1689 1685/1785/1692 +f 1682/1782/1689 1672/1772/1679 1684/1784/1691 +f 1684/1784/1691 1672/1772/1679 1674/1774/1681 +f 1687/1787/1694 1688/1788/1695 1689/1789/1696 +f 1689/1789/1696 1688/1788/1695 1690/1790/1697 +f 1688/1788/1695 1687/1787/1694 1691/1791/1698 +f 1691/1791/1698 1687/1787/1694 1692/1792/1699 +f 1681/1781/1688 1688/1788/1695 1686/1786/1693 +f 1686/1786/1693 1688/1788/1695 1691/1791/1698 +f 1688/1788/1695 1681/1781/1688 1690/1790/1697 +f 1690/1790/1697 1681/1781/1688 1683/1783/1690 +f 1693/1793/1700 1694/1794/1701 1695/1795/1702 +f 1695/1795/1702 1694/1794/1701 1696/1796/1703 +f 1693/1793/1700 1695/1795/1702 1697/1797/1704 +f 1697/1797/1704 1695/1795/1702 1698/1798/1705 +f 1687/1787/1694 1693/1793/1700 1692/1792/1699 +f 1692/1792/1699 1693/1793/1700 1697/1797/1704 +f 1693/1793/1700 1687/1787/1694 1694/1794/1701 +f 1694/1794/1701 1687/1787/1694 1689/1789/1696 +f 1699/1799/1706 1700/1800/1707 1701/1801/1708 +f 1701/1801/1708 1700/1800/1707 1702/1802/1709 +f 1701/1801/1708 1702/1802/1709 1695/1795/1702 +f 1695/1795/1702 1702/1802/1709 1698/1798/1705 +f 1701/1801/1708 1703/1803/1710 1699/1799/1706 +f 1699/1799/1706 1703/1803/1710 1704/1804/1711 +f 1705/1805/1712 1706/1806/1713 1707/1807/1714 +f 1707/1807/1714 1706/1806/1713 1708/1808/1715 +f 1707/1807/1714 1709/1809/1716 1705/1805/1712 +f 1705/1805/1712 1709/1809/1716 1710/1810/1717 +f 1705/1805/1712 1710/1810/1717 1699/1799/1706 +f 1699/1799/1706 1710/1810/1717 1700/1800/1707 +f 1699/1799/1706 1704/1804/1711 1705/1805/1712 +f 1705/1805/1712 1704/1804/1711 1706/1806/1713 +f 1711/1811/1718 1712/1812/1719 1713/1813/1720 +f 1713/1813/1720 1712/1812/1719 1714/1814/1721 +f 1713/1813/1720 1715/1815/1722 1711/1811/1718 +f 1711/1811/1718 1715/1815/1722 1716/1816/1723 +f 1711/1811/1718 1716/1816/1723 1707/1807/1714 +f 1707/1807/1714 1716/1816/1723 1709/1809/1716 +f 1707/1807/1714 1708/1808/1715 1711/1811/1718 +f 1711/1811/1718 1708/1808/1715 1712/1812/1719 +f 1717/1817/1724 1718/1818/1725 1719/1819/1726 +f 1719/1819/1726 1718/1818/1725 1720/1820/1727 +f 1719/1819/1726 1721/1821/1728 1717/1817/1724 +f 1717/1817/1724 1721/1821/1728 1722/1822/1729 +f 1717/1817/1724 1722/1822/1729 1713/1813/1720 +f 1713/1813/1720 1722/1822/1729 1715/1815/1722 +f 1713/1813/1720 1714/1814/1721 1717/1817/1724 +f 1717/1817/1724 1714/1814/1721 1718/1818/1725 +f 1723/1823/1730 1724/1824/1731 1725/1825/1732 +f 1725/1825/1732 1724/1824/1731 1726/1826/1733 +f 1725/1825/1732 1727/1827/1734 1723/1823/1730 +f 1723/1823/1730 1727/1827/1734 1728/1828/1735 +f 1723/1823/1730 1728/1828/1735 1719/1819/1726 +f 1719/1819/1726 1728/1828/1735 1721/1821/1728 +f 1719/1819/1726 1720/1820/1727 1723/1823/1730 +f 1723/1823/1730 1720/1820/1727 1724/1824/1731 +f 1678/1778/1685 1729/1829/1736 1680/1780/1687 +f 1680/1780/1687 1729/1829/1736 1730/1830/1737 +f 1729/1829/1736 1678/1778/1685 1731/1831/1738 +f 1731/1831/1738 1678/1778/1685 1679/1779/1686 +f 1725/1825/1732 1729/1829/1736 1727/1827/1734 +f 1727/1827/1734 1729/1829/1736 1731/1831/1738 +f 1729/1829/1736 1725/1825/1732 1730/1830/1737 +f 1730/1830/1737 1725/1825/1732 1726/1826/1733 +f 1680/1780/1687 1720/1820/1727 1675/1775/1682 +f 1675/1775/1682 1720/1820/1727 1718/1818/1725 +f 1732/1832/1739 1733/1833/1740 1734/1834/1741 +f 1734/1834/1741 1733/1833/1740 1735/1835/1742 +f 1736/1836/1743 1737/1837/1744 1738/1838/1745 +f 1738/1838/1745 1737/1837/1744 1735/1835/1742 +f 1739/1839/1746 1740/1840/1747 1741/1841/1748 +f 1741/1841/1748 1740/1840/1747 1742/1842/1749 +f 1743/1843/1750 1744/1844/1751 1745/1845/1752 +f 1745/1845/1752 1744/1844/1751 1742/1842/1749 +f 1746/1846/1753 1744/1844/1751 1747/1847/1754 +f 1747/1847/1754 1744/1844/1751 1748/1848/1755 +f 1749/1849/1756 1733/1833/1740 1750/1850/1757 +f 1750/1850/1757 1733/1833/1740 1748/1848/1755 +f 1751/1851/1758 1752/1852/1759 1753/1853/1760 +f 1753/1853/1760 1752/1852/1759 1737/1837/1744 +f 1754/1854/1761 1755/1855/1762 1756/1856/1763 +f 1756/1856/1763 1755/1855/1762 1753/1853/1760 +f 1757/1857/1764 1755/1855/1762 1758/1858/1765 +f 1758/1858/1765 1755/1855/1762 1759/1859/1766 +f 1760/1860/1767 1761/1861/1768 1759/1859/1766 +f 1759/1859/1766 1761/1861/1768 1762/1862/1769 +f 1763/1863/1770 1764/1864/1771 1765/1865/1772 +f 1765/1865/1772 1764/1864/1771 1766/1866/1773 +f 1767/1867/1774 1768/1868/1775 1765/1865/1772 +f 1765/1865/1772 1768/1868/1775 1762/1862/1769 +f 1769/1869/1776 1770/1870/1777 1771/1871/1778 +f 1771/1871/1778 1770/1870/1777 1766/1866/1773 +f 1772/1872/1779 1773/1873/1780 1771/1871/1778 +f 1771/1871/1778 1773/1873/1780 1774/1874/1781 +f 1775/1875/1782 1776/1876/1783 1777/1877/1784 +f 1777/1877/1784 1776/1876/1783 1774/1874/1781 +f 1778/1878/1785 1779/1879/1786 1777/1877/1784 +f 1777/1877/1784 1779/1879/1786 1780/1880/1787 +f 1781/1881/1788 1782/1882/1789 1783/1883/1790 +f 1783/1883/1790 1782/1882/1789 1780/1880/1787 +f 1784/1884/1791 1785/1885/1792 1783/1883/1790 +f 1783/1883/1790 1785/1885/1792 1786/1886/1793 +f 1787/1887/1794 1788/1888/1795 1789/1889/1796 +f 1789/1889/1796 1788/1888/1795 1786/1886/1793 +f 1790/1890/1797 1791/1891/1798 1789/1889/1796 +f 1789/1889/1796 1791/1891/1798 1740/1840/1747 +f 1792/1892/1799 1793/1893/1800 1692/1792/1699 +f 1692/1792/1699 1793/1893/1800 1691/1791/1698 +f 1793/1893/1800 1794/1894/1801 1691/1791/1698 +f 1691/1791/1698 1794/1894/1801 1686/1786/1693 +f 1795/1895/1802 1796/1896/1803 1677/1777/1684 +f 1677/1777/1684 1796/1896/1803 1676/1776/1683 +f 1796/1896/1803 1797/1897/1804 1676/1776/1683 +f 1676/1776/1683 1797/1897/1804 1679/1779/1686 +f 1794/1894/1801 1798/1898/1805 1686/1786/1693 +f 1686/1786/1693 1798/1898/1805 1685/1785/1692 +f 1798/1898/1805 1795/1895/1802 1685/1785/1692 +f 1685/1785/1692 1795/1895/1802 1677/1777/1684 +f 1799/1899/1806 1800/1900/1807 1698/1798/1705 +f 1698/1798/1705 1800/1900/1807 1697/1797/1704 +f 1800/1900/1807 1792/1892/1799 1697/1797/1704 +f 1697/1797/1704 1792/1892/1799 1692/1792/1699 +f 1797/1897/1804 1801/1901/1808 1679/1779/1686 +f 1679/1779/1686 1801/1901/1808 1731/1831/1738 +f 1801/1901/1808 1802/1902/1809 1731/1831/1738 +f 1731/1831/1738 1802/1902/1809 1727/1827/1734 +f 1700/1800/1707 1803/1903/1810 1702/1802/1709 +f 1702/1802/1709 1803/1903/1810 1804/1904/1811 +f 1799/1899/1806 1698/1798/1705 1804/1904/1811 +f 1804/1904/1811 1698/1798/1705 1702/1802/1709 +f 1727/1827/1734 1802/1902/1809 1728/1828/1735 +f 1728/1828/1735 1802/1902/1809 1805/1905/1812 +f 1806/1906/1813 1721/1821/1728 1805/1905/1812 +f 1805/1905/1812 1721/1821/1728 1728/1828/1735 +f 1709/1809/1716 1807/1907/1814 1710/1810/1717 +f 1710/1810/1717 1807/1907/1814 1808/1908/1815 +f 1803/1903/1810 1700/1800/1707 1808/1908/1815 +f 1808/1908/1815 1700/1800/1707 1710/1810/1717 +f 1721/1821/1728 1806/1906/1813 1722/1822/1729 +f 1722/1822/1729 1806/1906/1813 1809/1909/1816 +f 1810/1910/1817 1715/1815/1722 1809/1909/1816 +f 1809/1909/1816 1715/1815/1722 1722/1822/1729 +f 1715/1815/1722 1810/1910/1817 1716/1816/1723 +f 1716/1816/1723 1810/1910/1817 1811/1911/1818 +f 1807/1907/1814 1709/1809/1716 1811/1911/1818 +f 1811/1911/1818 1709/1809/1716 1716/1816/1723 +f 1793/1912/1800 1792/1913/1799 1756/1856/1763 +f 1756/1856/1763 1792/1913/1799 1754/1854/1761 +f 1756/1856/1763 1736/1836/1743 1793/1912/1800 +f 1793/1912/1800 1736/1836/1743 1794/1914/1801 +f 1796/1915/1803 1795/1916/1802 1750/1850/1757 +f 1750/1850/1757 1795/1916/1802 1749/1849/1756 +f 1796/1915/1803 1750/1850/1757 1797/1917/1804 +f 1797/1917/1804 1750/1850/1757 1743/1843/1750 +f 1798/1918/1805 1794/1914/1801 1738/1838/1745 +f 1738/1838/1745 1794/1914/1801 1736/1836/1743 +f 1738/1838/1745 1749/1849/1756 1798/1918/1805 +f 1798/1918/1805 1749/1849/1756 1795/1916/1802 +f 1800/1919/1807 1799/1920/1806 1760/1860/1767 +f 1760/1860/1767 1799/1920/1806 1761/1861/1768 +f 1760/1860/1767 1754/1854/1761 1800/1919/1807 +f 1800/1919/1807 1754/1854/1761 1792/1913/1799 +f 1797/1917/1804 1743/1843/1750 1801/1921/1808 +f 1801/1921/1808 1743/1843/1750 1745/1845/1752 +f 1801/1921/1808 1745/1845/1752 1802/1922/1809 +f 1802/1922/1809 1745/1845/1752 1791/1891/1798 +f 1804/1923/1811 1803/1924/1810 1763/1863/1770 +f 1763/1863/1770 1803/1924/1810 1764/1864/1771 +f 1763/1863/1770 1761/1861/1768 1804/1923/1811 +f 1804/1923/1811 1761/1861/1768 1799/1920/1806 +f 1802/1922/1809 1791/1891/1798 1805/1925/1812 +f 1805/1925/1812 1791/1891/1798 1790/1890/1797 +f 1805/1925/1812 1790/1890/1797 1806/1926/1813 +f 1806/1926/1813 1790/1890/1797 1785/1885/1792 +f 1808/1927/1815 1807/1928/1814 1772/1872/1779 +f 1772/1872/1779 1807/1928/1814 1773/1873/1780 +f 1772/1872/1779 1764/1864/1771 1808/1927/1815 +f 1808/1927/1815 1764/1864/1771 1803/1924/1810 +f 1806/1926/1813 1785/1885/1792 1809/1929/1816 +f 1809/1929/1816 1785/1885/1792 1784/1884/1791 +f 1809/1929/1816 1784/1884/1791 1810/1930/1817 +f 1810/1930/1817 1784/1884/1791 1779/1879/1786 +f 1811/1931/1818 1810/1930/1817 1778/1878/1785 +f 1778/1878/1785 1810/1930/1817 1779/1879/1786 +f 1778/1878/1785 1773/1873/1780 1811/1931/1818 +f 1811/1931/1818 1773/1873/1780 1807/1928/1814 +f 1812/1932/1819 1813/1933/1820 1770/1870/1777 +f 1770/1870/1777 1813/1933/1820 1767/1867/1774 +f 1814/1934/1821 1768/1868/1775 1813/1933/1820 +f 1813/1933/1820 1768/1868/1775 1767/1867/1774 +f 1815/1935/1822 1816/1936/1823 1776/1876/1783 +f 1776/1876/1783 1816/1936/1823 1769/1869/1776 +f 1816/1936/1823 1812/1932/1819 1769/1869/1776 +f 1769/1869/1776 1812/1932/1819 1770/1870/1777 +f 1752/1852/1759 1817/1937/1824 1734/1834/1741 +f 1734/1834/1741 1817/1937/1824 1818/1938/1825 +f 1819/1939/1826 1732/1832/1739 1818/1938/1825 +f 1818/1938/1825 1732/1832/1739 1734/1834/1741 +f 1820/1940/1827 1821/1941/1828 1788/1888/1795 +f 1788/1888/1795 1821/1941/1828 1781/1881/1788 +f 1821/1941/1828 1822/1942/1829 1781/1881/1788 +f 1781/1881/1788 1822/1942/1829 1782/1882/1789 +f 1746/1846/1753 1823/1943/1830 1741/1841/1748 +f 1741/1841/1748 1823/1943/1830 1824/1944/1831 +f 1824/1944/1831 1825/1945/1832 1741/1841/1748 +f 1741/1841/1748 1825/1945/1832 1739/1839/1746 +f 1732/1832/1739 1819/1939/1826 1747/1847/1754 +f 1747/1847/1754 1819/1939/1826 1826/1946/1833 +f 1823/1943/1830 1746/1846/1753 1826/1946/1833 +f 1826/1946/1833 1746/1846/1753 1747/1847/1754 +f 1757/1857/1764 1827/1947/1834 1751/1851/1758 +f 1751/1851/1758 1827/1947/1834 1828/1948/1835 +f 1817/1937/1824 1752/1852/1759 1828/1948/1835 +f 1828/1948/1835 1752/1852/1759 1751/1851/1758 +f 1768/1868/1775 1814/1934/1821 1758/1858/1765 +f 1758/1858/1765 1814/1934/1821 1829/1949/1836 +f 1827/1947/1834 1757/1857/1764 1829/1949/1836 +f 1829/1949/1836 1757/1857/1764 1758/1858/1765 +f 1822/1942/1829 1830/1950/1837 1782/1882/1789 +f 1782/1882/1789 1830/1950/1837 1775/1875/1782 +f 1830/1950/1837 1815/1935/1822 1775/1875/1782 +f 1775/1875/1782 1815/1935/1822 1776/1876/1783 +f 1825/1945/1832 1831/1951/1838 1739/1839/1746 +f 1739/1839/1746 1831/1951/1838 1787/1887/1794 +f 1831/1951/1838 1820/1940/1827 1787/1887/1794 +f 1787/1887/1794 1820/1940/1827 1788/1888/1795 +f 1812/1932/1819 1832/1952/1839 1813/1933/1820 +f 1813/1933/1820 1832/1952/1839 1833/1953/1840 +f 1834/1954/1841 1814/1934/1821 1833/1953/1840 +f 1833/1953/1840 1814/1934/1821 1813/1933/1820 +f 1816/1936/1823 1815/1935/1822 1835/1955/1842 +f 1835/1955/1842 1815/1935/1822 1836/1956/1843 +f 1812/1932/1819 1816/1936/1823 1832/1952/1839 +f 1832/1952/1839 1816/1936/1823 1835/1955/1842 +f 1817/1937/1824 1837/1957/1844 1818/1938/1825 +f 1818/1938/1825 1837/1957/1844 1838/1958/1845 +f 1839/1959/1846 1819/1939/1826 1838/1958/1845 +f 1838/1958/1845 1819/1939/1826 1818/1938/1825 +f 1821/1941/1828 1820/1940/1827 1840/1960/1847 +f 1840/1960/1847 1820/1940/1827 1841/1961/1848 +f 1822/1942/1829 1821/1941/1828 1842/1962/1849 +f 1842/1962/1849 1821/1941/1828 1840/1960/1847 +f 1824/1944/1831 1823/1943/1830 1843/1963/1850 +f 1843/1963/1850 1823/1943/1830 1844/1964/1851 +f 1825/1945/1832 1824/1944/1831 1845/1965/1852 +f 1845/1965/1852 1824/1944/1831 1843/1963/1850 +f 1819/1939/1826 1839/1959/1846 1826/1946/1833 +f 1826/1946/1833 1839/1959/1846 1846/1966/1853 +f 1844/1964/1851 1823/1943/1830 1846/1966/1853 +f 1846/1966/1853 1823/1943/1830 1826/1946/1833 +f 1827/1947/1834 1847/1967/1854 1828/1948/1835 +f 1828/1948/1835 1847/1967/1854 1848/1968/1855 +f 1837/1957/1844 1817/1937/1824 1848/1968/1855 +f 1848/1968/1855 1817/1937/1824 1828/1948/1835 +f 1814/1934/1821 1834/1954/1841 1829/1949/1836 +f 1829/1949/1836 1834/1954/1841 1849/1969/1856 +f 1847/1967/1854 1827/1947/1834 1849/1969/1856 +f 1849/1969/1856 1827/1947/1834 1829/1949/1836 +f 1830/1950/1837 1822/1942/1829 1850/1970/1857 +f 1850/1970/1857 1822/1942/1829 1842/1962/1849 +f 1815/1935/1822 1830/1950/1837 1836/1956/1843 +f 1836/1956/1843 1830/1950/1837 1850/1970/1857 +f 1831/1951/1838 1825/1945/1832 1851/1971/1858 +f 1851/1971/1858 1825/1945/1832 1845/1965/1852 +f 1820/1940/1827 1831/1951/1838 1841/1961/1848 +f 1841/1961/1848 1831/1951/1838 1851/1971/1858 +f 1724/1824/1731 1720/1820/1727 1726/1826/1733 +f 1720/1820/1727 1680/1780/1687 1726/1826/1733 +f 1680/1780/1687 1730/1830/1737 1726/1826/1733 +f 1674/1774/1681 1714/1814/1721 1684/1784/1691 +f 1684/1784/1691 1714/1814/1721 1712/1812/1719 +f 1675/1775/1682 1718/1818/1725 1674/1774/1681 +f 1674/1774/1681 1718/1818/1725 1714/1814/1721 +f 1684/1784/1691 1712/1812/1719 1683/1783/1690 +f 1683/1783/1690 1712/1812/1719 1708/1808/1715 +f 1694/1794/1701 1689/1789/1696 1696/1796/1703 +f 1704/1804/1711 1703/1803/1710 1689/1789/1696 +f 1689/1789/1696 1703/1803/1710 1696/1796/1703 +f 1708/1808/1715 1706/1806/1713 1683/1783/1690 +f 1683/1783/1690 1706/1806/1713 1690/1790/1697 +f 1695/1795/1702 1696/1796/1703 1701/1801/1708 +f 1701/1801/1708 1696/1796/1703 1703/1803/1710 +f 1689/1789/1696 1690/1790/1697 1704/1804/1711 +f 1704/1804/1711 1690/1790/1697 1706/1806/1713 +f 1832/1952/1839 1852/1972/1859 1833/1953/1840 +f 1833/1953/1840 1852/1972/1859 1853/1973/1860 +f 1833/1953/1840 1853/1973/1860 1834/1954/1841 +f 1834/1954/1841 1853/1973/1860 1662/1762/1669 +f 1854/1974/1861 1855/1975/1862 1836/1956/1843 +f 1836/1956/1843 1855/1975/1862 1835/1955/1842 +f 1635/1735/1642 1634/1734/1641 1837/1957/1844 +f 1837/1957/1844 1634/1734/1641 1838/1958/1845 +f 1838/1958/1845 1634/1734/1641 1839/1959/1846 +f 1839/1959/1846 1634/1734/1641 1625/1725/1632 +f 1648/1748/1655 1654/1754/1661 1841/1961/1848 +f 1841/1961/1848 1654/1754/1661 1840/1960/1847 +f 1654/1754/1661 1660/1760/1667 1840/1960/1847 +f 1840/1960/1847 1660/1760/1667 1842/1962/1849 +f 1844/1964/1851 1623/1723/1630 1843/1963/1850 +f 1843/1963/1850 1623/1723/1630 1633/1733/1640 +f 1843/1963/1850 1633/1733/1640 1845/1965/1852 +f 1845/1965/1852 1633/1733/1640 1640/1740/1647 +f 1625/1725/1632 1624/1724/1631 1839/1959/1846 +f 1839/1959/1846 1624/1724/1631 1846/1966/1853 +f 1846/1966/1853 1624/1724/1631 1844/1964/1851 +f 1844/1964/1851 1624/1724/1631 1623/1723/1630 +f 1847/1967/1854 1650/1750/1657 1848/1968/1855 +f 1848/1968/1855 1650/1750/1657 1644/1744/1651 +f 1848/1968/1855 1644/1744/1651 1837/1957/1844 +f 1837/1957/1844 1644/1744/1651 1635/1735/1642 +f 1849/1969/1856 1656/1756/1663 1847/1967/1854 +f 1847/1967/1854 1656/1756/1663 1650/1750/1657 +f 1842/1962/1849 1660/1760/1667 1850/1970/1857 +f 1850/1970/1857 1660/1760/1667 1669/1769/1676 +f 1669/1769/1676 1854/1974/1861 1850/1970/1857 +f 1850/1970/1857 1854/1974/1861 1836/1956/1843 +f 1845/1965/1852 1640/1740/1647 1851/1971/1858 +f 1851/1971/1858 1640/1740/1647 1642/1742/1649 +f 1851/1971/1858 1642/1742/1649 1841/1961/1848 +f 1841/1961/1848 1642/1742/1649 1648/1748/1655 +f 1855/1975/1862 1852/1972/1859 1835/1955/1842 +f 1835/1955/1842 1852/1972/1859 1832/1952/1839 +f 1640/1740/1647 1633/1733/1640 1632/1732/1639 +f 1633/1733/1640 1623/1723/1630 1622/1722/1629 +f 1849/1969/1856 1834/1954/1841 1656/1756/1663 +f 1656/1756/1663 1834/1954/1841 1662/1762/1669 +f 1856/1976/1863 1857/1977/1864 1858/1978/1865 +f 1857/1977/1864 1859/1979/1866 1858/1978/1865 +f 1858/1978/1865 1859/1979/1866 1856/1976/1863 +f 1860/1980/1867 1222/1312/1229 1861/1981/1868 +f 1861/1981/1868 1222/1312/1229 1223/1313/1230 +f 1862/1982/1869 1860/1980/1867 1863/1983/1870 +f 1863/1983/1870 1860/1980/1867 1861/1981/1868 +f 1860/1980/1867 1862/1982/1869 1864/1984/1871 +f 1864/1984/1871 1862/1982/1869 1865/1985/1872 +f 1230/1320/1237 1864/1984/1871 1228/1318/1235 +f 1228/1318/1235 1864/1984/1871 1866/1986/1873 +f 1222/1312/1229 1860/1980/1867 1230/1320/1237 +f 1230/1320/1237 1860/1980/1867 1864/1984/1871 +f 1867/1987/1874 1868/1988/1875 1869/1989/1876 +f 1869/1989/1876 1868/1988/1875 1870/1990/1877 +f 1868/1988/1875 1867/1987/1874 1871/1991/1878 +f 1871/1991/1878 1867/1987/1874 1872/1992/1879 +f 1873/1993/1880 1874/1994/1881 1875/1995/1882 +f 1875/1995/1882 1874/1994/1881 1876/1996/1883 +f 1241/1331/1248 1242/1332/1249 1873/1993/1880 +f 1873/1993/1880 1242/1332/1249 1874/1994/1881 +f 1868/1988/1875 1871/1991/1878 1877/1997/1884 +f 1877/1997/1884 1871/1991/1878 1878/1998/1885 +f 1879/1999/1886 1880/2000/1887 1878/1998/1885 +f 1878/1998/1885 1880/2000/1887 1877/1997/1884 +f 1880/2000/1887 1881/2001/1888 1877/1997/1884 +f 1877/1997/1884 1881/2001/1888 1882/2002/1889 +f 1870/1990/1877 1868/1988/1875 1882/2002/1889 +f 1882/2002/1889 1868/1988/1875 1877/1997/1884 +f 1883/2003/1890 1884/2004/1891 1885/2005/1892 +f 1885/2005/1892 1884/2004/1891 1886/2006/1893 +f 1869/1989/1876 1870/1990/1877 1883/2003/1890 +f 1883/2003/1890 1870/1990/1877 1884/2004/1891 +f 1887/2007/1894 1888/2008/1895 1889/2009/1896 +f 1889/2009/1896 1888/2008/1895 1890/2010/1897 +f 1891/2011/1898 1892/2012/1899 1890/2010/1897 +f 1890/2010/1897 1892/2012/1899 1889/2009/1896 +f 1892/2012/1899 1893/2013/1900 1889/2009/1896 +f 1893/2013/1900 1894/2014/1901 1889/2009/1896 +f 1889/2009/1896 1894/2014/1901 1887/2007/1894 +f 1895/2015/1902 1875/1995/1882 1896/2016/1903 +f 1896/2016/1903 1875/1995/1882 1897/2017/1904 +f 1898/2018/1905 1895/2015/1902 1899/2019/1906 +f 1899/2019/1906 1895/2015/1902 1896/2016/1903 +f 1895/2015/1902 1898/2018/1905 1900/2020/1907 +f 1900/2020/1907 1898/2018/1905 1901/2021/1908 +f 1269/1359/1276 1268/1358/1275 1901/2021/1908 +f 1901/2021/1908 1268/1358/1275 1900/2020/1907 +f 1268/1358/1275 1241/1331/1248 1900/2020/1907 +f 1900/2020/1907 1241/1331/1248 1873/1993/1880 +f 1875/1995/1882 1895/2015/1902 1873/1993/1880 +f 1873/1993/1880 1895/2015/1902 1900/2020/1907 +f 1902/2022/1909 1903/2023/1910 1904/2024/1911 +f 1904/2024/1911 1903/2023/1910 1905/2025/1912 +f 1905/2025/1912 1886/2006/1893 1904/2024/1911 +f 1904/2024/1911 1886/2006/1893 1884/2004/1891 +f 1870/1990/1877 1882/2002/1889 1884/2004/1891 +f 1884/2004/1891 1882/2002/1889 1904/2024/1911 +f 1881/2001/1888 1902/2022/1909 1882/2002/1889 +f 1882/2002/1889 1902/2022/1909 1904/2024/1911 +f 1891/2011/1898 1906/2026/1913 1892/2012/1899 +f 1892/2012/1899 1906/2026/1913 1907/2027/1914 +f 1907/2027/1914 1908/2028/1915 1892/2012/1899 +f 1909/2029/1916 1910/2030/1917 1911/2031/1918 +f 1911/2031/1918 1910/2030/1917 1912/2032/1919 +f 1910/2030/1917 1913/2033/1920 1912/2032/1919 +f 1912/2032/1919 1913/2033/1920 1914/2034/1921 +f 1915/2035/1922 1285/1375/1292 1916/2036/1923 +f 1916/2036/1923 1285/1375/1292 1286/1376/1293 +f 1286/1376/1293 1287/1377/1294 1916/2036/1923 +f 1916/2036/1923 1287/1377/1294 1917/2037/1924 +f 1913/2033/1920 1910/2030/1917 1917/2037/1924 +f 1917/2037/1924 1910/2030/1917 1916/2036/1923 +f 1909/2029/1916 1915/2035/1922 1910/2030/1917 +f 1910/2030/1917 1915/2035/1922 1916/2036/1923 +f 1918/2038/1925 1919/2039/1926 1920/2040/1927 +f 1920/2040/1927 1919/2039/1926 1921/2041/1928 +f 1922/2042/1929 1923/2043/1930 1921/2041/1928 +f 1921/2041/1928 1923/2043/1930 1920/2040/1927 +f 1924/2044/1931 1925/2045/1932 1926/2046/1933 +f 1926/2046/1933 1925/2045/1932 1927/2047/1934 +f 1928/2048/1935 1856/1976/1863 1925/2045/1932 +f 1925/2045/1932 1856/1976/1863 1927/2047/1934 +f 1927/2047/1934 1929/2049/1936 1926/2046/1933 +f 1926/2046/1933 1929/2049/1936 1930/2050/1937 +f 1859/1979/1866 1931/2051/1938 1856/1976/1863 +f 1856/1976/1863 1931/2051/1938 1927/2047/1934 +f 1931/2051/1938 1932/2052/1939 1927/2047/1934 +f 1927/2047/1934 1932/2052/1939 1929/2049/1936 +f 1933/2053/1940 1934/2054/1941 1935/2055/1942 +f 1935/2055/1942 1934/2054/1941 1936/2056/1943 +f 1934/2054/1941 1863/1983/1870 1936/2056/1943 +f 1936/2056/1943 1863/1983/1870 1861/1981/1868 +f 1861/1981/1868 1223/1313/1230 1936/2056/1943 +f 1936/2056/1943 1223/1313/1230 1307/1397/1314 +f 1308/1398/1315 1935/2055/1942 1307/1397/1314 +f 1307/1397/1314 1935/2055/1942 1936/2056/1943 +f 1885/2005/1892 1886/2006/1893 1937/2057/1944 +f 1937/2057/1944 1886/2006/1893 1938/2058/1945 +f 1937/2057/1944 1938/2058/1945 1939/2059/1946 +f 1939/2059/1946 1938/2058/1945 1940/2060/1947 +f 1941/2061/1948 1942/2062/1949 1943/2063/1950 +f 1943/2063/1950 1942/2062/1949 1944/2064/1951 +f 1945/2065/1952 1946/2066/1953 1944/2064/1951 +f 1944/2064/1951 1946/2066/1953 1943/2063/1950 +f 1946/2066/1953 1924/2044/1931 1943/2063/1950 +f 1943/2063/1950 1924/2044/1931 1926/2046/1933 +f 1942/2062/1949 1941/2061/1948 1947/2067/1954 +f 1947/2067/1954 1941/2061/1948 1948/2068/1955 +f 1929/2049/1936 1949/2069/1956 1930/2050/1937 +f 1950/2070/1957 1930/2050/1937 1949/2069/1956 +f 1950/2070/1957 1906/2026/1913 1948/2068/1955 +f 1948/2068/1955 1906/2026/1913 1951/2071/1958 +f 1952/2072/1959 1947/2067/1954 1951/2071/1958 +f 1951/2071/1958 1947/2067/1954 1948/2068/1955 +f 1924/2044/1931 1946/2066/1953 1953/2073/1960 +f 1953/2073/1960 1946/2066/1953 1954/2074/1961 +f 1946/2066/1953 1945/2065/1952 1954/2074/1961 +f 1954/2074/1961 1945/2065/1952 1955/2075/1962 +f 1956/2076/1963 1957/2077/1964 1955/2075/1962 +f 1955/2075/1962 1957/2077/1964 1954/2074/1961 +f 1957/2077/1964 1958/2078/1965 1954/2074/1961 +f 1954/2074/1961 1958/2078/1965 1953/2073/1960 +f 1959/2079/1966 1960/2080/1967 1961/2081/1968 +f 1961/2081/1968 1960/2080/1967 1962/2082/1969 +f 1960/2080/1967 1959/2079/1966 1963/2083/1970 +f 1963/2083/1970 1959/2079/1966 1964/2084/1971 +f 1965/2085/1972 1966/2086/1973 1967/2087/1974 +f 1967/2087/1974 1966/2086/1973 1968/2088/1975 +f 1969/2089/1976 1970/2090/1977 1968/2088/1975 +f 1968/2088/1975 1970/2090/1977 1967/2087/1974 +f 1970/2090/1977 1971/2091/1978 1967/2087/1974 +f 1967/2087/1974 1971/2091/1978 1972/2092/1979 +f 1973/2093/1980 1965/2085/1972 1972/2092/1979 +f 1972/2092/1979 1965/2085/1972 1967/2087/1974 +f 1974/2094/1981 1975/2095/1982 1976/2096/1983 +f 1976/2096/1983 1975/2095/1982 1977/2097/1984 +f 1922/2042/1929 1978/2098/1985 1977/2097/1984 +f 1977/2097/1984 1978/2098/1985 1976/2096/1983 +f 1966/2086/1973 1965/2085/1972 1978/2098/1985 +f 1978/2098/1985 1965/2085/1972 1976/2096/1983 +f 1965/2085/1972 1973/2093/1980 1976/2096/1983 +f 1976/2096/1983 1973/2093/1980 1974/2094/1981 +f 1979/2099/1986 1980/2100/1987 1981/2101/1988 +f 1981/2101/1988 1980/2100/1987 1982/2102/1989 +f 1983/2103/1990 1984/2104/1991 1982/2102/1989 +f 1982/2102/1989 1984/2104/1991 1981/2101/1988 +f 1984/2104/1991 1964/2084/1971 1981/2101/1988 +f 1981/2101/1988 1964/2084/1971 1959/2079/1966 +f 1961/2081/1968 1979/2099/1986 1959/2079/1966 +f 1959/2079/1966 1979/2099/1986 1981/2101/1988 +f 1971/2091/1978 1970/2090/1977 1985/2105/1992 +f 1985/2105/1992 1970/2090/1977 1986/2106/1993 +f 1970/2090/1977 1969/2089/1976 1986/2106/1993 +f 1986/2106/1993 1969/2089/1976 1987/2107/1994 +f 1988/2108/1995 1989/2109/1996 1987/2107/1994 +f 1987/2107/1994 1989/2109/1996 1986/2106/1993 +f 1989/2109/1996 1990/2110/1997 1986/2106/1993 +f 1986/2106/1993 1990/2110/1997 1985/2105/1992 +f 1963/2083/1970 1964/2084/1971 1991/2111/1998 +f 1991/2111/1998 1964/2084/1971 1984/2104/1991 +f 1992/2112/1999 1991/2111/1998 1983/2103/1990 +f 1983/2103/1990 1991/2111/1998 1984/2104/1991 +f 1993/2113/2000 1994/2114/2001 1995/2115/2002 +f 1995/2115/2002 1994/2114/2001 1996/2116/2003 +f 1994/2114/2001 1988/2108/1995 1996/2116/2003 +f 1996/2116/2003 1988/2108/1995 1987/2107/1994 +f 1987/2107/1994 1969/2089/1976 1996/2116/2003 +f 1996/2116/2003 1969/2089/1976 1968/2088/1975 +f 1966/2086/1973 1995/2115/2002 1968/2088/1975 +f 1968/2088/1975 1995/2115/2002 1996/2116/2003 +f 1997/2117/2004 1898/2018/1905 1998/2118/2005 +f 1998/2118/2005 1898/2018/1905 1899/2019/1906 +f 1999/2119/2006 1997/2117/2004 2000/2120/2007 +f 2000/2120/2007 1997/2117/2004 1998/2118/2005 +f 2001/2121/2008 2002/2122/2009 2003/2123/2010 +f 2003/2123/2010 2002/2122/2009 2004/2124/2011 +f 1929/2049/1936 1932/2052/1939 2005/2125/2012 +f 2005/2125/2012 1932/2052/1939 2006/2126/2013 +f 2006/2126/2013 2007/2127/2014 2008/2128/2015 +f 2008/2128/2015 2007/2127/2014 2009/2129/2016 +f 1997/2117/2004 1999/2119/2006 2010/2130/2017 +f 2010/2130/2017 1999/2119/2006 2011/2131/2018 +f 1385/1475/1392 1384/1474/1391 2011/2131/2018 +f 2011/2131/2018 1384/1474/1391 2010/2130/2017 +f 1384/1474/1391 1269/1359/1276 2010/2130/2017 +f 2010/2130/2017 1269/1359/1276 1901/2021/1908 +f 1898/2018/1905 1997/2117/2004 1901/2021/1908 +f 1901/2021/1908 1997/2117/2004 2010/2130/2017 +f 1933/2053/1940 1935/2055/1942 2007/2127/2014 +f 2007/2127/2014 1935/2055/1942 2012/2132/2019 +f 1935/2055/1942 1308/1398/1315 2012/2132/2019 +f 2012/2132/2019 1308/1398/1315 1387/1477/1394 +f 1389/1479/1396 2013/2133/2020 1387/1477/1394 +f 1387/1477/1394 2013/2133/2020 2012/2132/2019 +f 2013/2133/2020 2009/2129/2016 2012/2132/2019 +f 2012/2132/2019 2009/2129/2016 2007/2127/2014 +f 2014/2134/2021 1999/2119/2006 2015/2135/2022 +f 2015/2135/2022 1999/2119/2006 2000/2120/2007 +f 2002/2122/2009 2001/2121/2008 2016/2136/2023 +f 2016/2136/2023 2001/2121/2008 2017/2137/2024 +f 2008/2128/2015 2009/2129/2016 2018/2138/2025 +f 2018/2138/2025 2009/2129/2016 2019/2139/2026 +f 1396/1486/1403 1385/1475/1392 2020/2140/2027 +f 2020/2140/2027 1385/1475/1392 2011/2131/2018 +f 1999/2119/2006 2014/2134/2021 2011/2131/2018 +f 2011/2131/2018 2014/2134/2021 2020/2140/2027 +f 2013/2133/2020 1389/1479/1396 2021/2141/2028 +f 2021/2141/2028 1389/1479/1396 1399/1488/1406 +f 2009/2129/2016 2013/2133/2020 2019/2139/2026 +f 2019/2139/2026 2013/2133/2020 2021/2141/2028 +f 2016/2136/2023 2017/2137/2024 1912/2032/1919 +f 1912/2032/1919 2017/2137/2024 1911/2031/1918 +f 1287/1377/1294 1396/1486/1403 1917/2037/1924 +f 1917/2037/1924 1396/1486/1403 2020/2140/2027 +f 2014/2134/2021 1913/2033/1920 2020/2140/2027 +f 2020/2140/2027 1913/2033/1920 1917/2037/1924 +f 2022/2142/2029 2023/2143/2030 2024/2144/2031 +f 2024/2144/2031 2023/2143/2030 2025/2145/2032 +f 2023/2143/2030 1940/2060/1947 2025/2145/2032 +f 2025/2145/2032 1940/2060/1947 1938/2058/1945 +f 1886/2006/1893 1905/2025/1912 1938/2058/1945 +f 1938/2058/1945 1905/2025/1912 2025/2145/2032 +f 1905/2025/1912 1903/2023/1910 2025/2145/2032 +f 2025/2145/2032 1903/2023/1910 2024/2144/2031 +f 2026/2146/2033 1956/2076/1963 2027/2147/2034 +f 2027/2147/2034 1956/2076/1963 1955/2075/1962 +f 1945/2065/1952 2028/2148/2035 1955/2075/1962 +f 1955/2075/1962 2028/2148/2035 2027/2147/2034 +f 2028/2148/2035 1971/2091/1978 2027/2147/2034 +f 2027/2147/2034 1971/2091/1978 1985/2105/1992 +f 1990/2110/1997 2026/2146/2033 1985/2105/1992 +f 1985/2105/1992 2026/2146/2033 2027/2147/2034 +f 2029/2149/2036 1975/2095/1982 2030/2150/2037 +f 2030/2150/2037 1975/2095/1982 2031/2151/2038 +f 1952/2072/1959 2032/2152/2039 2031/2151/2038 +f 2031/2151/2038 2032/2152/2039 2030/2150/2037 +f 1939/2059/1946 1940/2060/1947 2033/2153/2040 +f 2033/2153/2040 1940/2060/1947 2034/2154/2041 +f 1961/2081/1968 1962/2082/1969 2034/2154/2041 +f 2034/2154/2041 1962/2082/1969 2033/2153/2040 +f 2035/2155/2042 1973/2093/1980 2036/2156/2043 +f 2036/2156/2043 1973/2093/1980 1972/2092/1979 +f 1971/2091/1978 2028/2148/2035 1972/2092/1979 +f 1972/2092/1979 2028/2148/2035 2036/2156/2043 +f 2028/2148/2035 1945/2065/1952 2036/2156/2043 +f 2036/2156/2043 1945/2065/1952 1944/2064/1951 +f 1942/2062/1949 2035/2155/2042 1944/2064/1951 +f 1944/2064/1951 2035/2155/2042 2036/2156/2043 +f 1992/2112/1999 1918/2038/1925 1991/2111/1998 +f 1991/2111/1998 1918/2038/1925 1920/2040/1927 +f 1923/2043/1930 1963/2083/1970 1920/2040/1927 +f 1920/2040/1927 1963/2083/1970 1991/2111/1998 +f 1963/2083/1970 1923/2043/1930 1960/2080/1967 +f 1960/2080/1967 1923/2043/1930 2037/2157/2044 +f 2029/2149/2036 1962/2082/1969 2037/2157/2044 +f 2037/2157/2044 1962/2082/1969 1960/2080/1967 +f 1939/2059/1946 2032/2152/2039 1937/2057/1944 +f 1937/2057/1944 2032/2152/2039 2038/2158/2045 +f 1891/2011/1898 1885/2005/1892 2038/2158/2045 +f 2038/2158/2045 1885/2005/1892 1937/2057/1944 +f 1885/2005/1892 1891/2011/1898 1883/2003/1890 +f 1883/2003/1890 1891/2011/1898 1890/2010/1897 +f 1888/2008/1895 1869/1989/1876 1890/2010/1897 +f 1890/2010/1897 1869/1989/1876 1883/2003/1890 +f 1888/2008/1895 1887/2007/1894 1872/1992/1879 +f 1872/1992/1879 1887/2007/1894 2039/2159/2046 +f 2040/2160/2047 1894/2014/1901 1893/2013/1900 +f 2004/2124/2011 2002/2122/2009 1998/2118/2005 +f 1998/2118/2005 2002/2122/2009 2000/2120/2007 +f 2002/2122/2009 2016/2136/2023 2000/2120/2007 +f 2000/2120/2007 2016/2136/2023 2015/2135/2022 +f 2016/2136/2023 1912/2032/1919 2015/2135/2022 +f 2015/2135/2022 1912/2032/1919 1914/2034/1921 +f 1419/1508/1426 1420/1509/1427 1879/1999/1886 +f 1879/1999/1886 1420/1509/1427 1880/2000/1887 +f 1420/1509/1427 1421/1510/1428 1880/2000/1887 +f 1880/2000/1887 1421/1510/1428 1881/2001/1888 +f 1421/1510/1428 1422/1511/1429 1881/2001/1888 +f 1881/2001/1888 1422/1511/1429 1902/2022/1909 +f 1422/1511/1429 1423/1512/1430 1902/2022/1909 +f 1902/2022/1909 1423/1512/1430 1903/2023/1910 +f 1423/1512/1430 1424/1513/1431 1903/2023/1910 +f 1903/2023/1910 1424/1513/1431 2024/2144/2031 +f 1425/1514/1432 2022/2142/2029 1424/1513/1431 +f 1424/1513/1431 2022/2142/2029 2024/2144/2031 +f 2022/2142/2029 1425/1514/1432 2041/2161/2048 +f 2041/2161/2048 1425/1514/1432 1427/1516/1434 +f 1428/1517/1435 1980/2100/1987 1427/1516/1434 +f 1427/1516/1434 1980/2100/1987 2041/2161/2048 +f 1980/2100/1987 1428/1517/1435 1982/2102/1989 +f 1982/2102/1989 1428/1517/1435 1429/1518/1436 +f 1430/1519/1437 1983/2103/1990 1429/1518/1436 +f 1429/1518/1436 1983/2103/1990 1982/2102/1989 +f 1431/1520/1438 1992/2112/1999 1430/1519/1437 +f 1430/1519/1437 1992/2112/1999 1983/2103/1990 +f 1432/1521/1439 1918/2038/1925 1431/1520/1438 +f 1431/1520/1438 1918/2038/1925 1992/2112/1999 +f 1435/1524/1442 1434/1523/1441 1919/2039/1926 +f 1919/2039/1926 1434/1523/1441 2042/2162/2049 +f 1434/1523/1441 1436/1525/1443 2042/2162/2049 +f 2042/2162/2049 1436/1525/1443 1993/2113/2000 +f 1437/1526/1444 1438/1527/1445 1994/2114/2001 +f 1994/2114/2001 1438/1527/1445 1988/2108/1995 +f 1436/1525/1443 1437/1526/1444 1993/2113/2000 +f 1993/2113/2000 1437/1526/1444 1994/2114/2001 +f 1438/1527/1445 1439/1528/1446 1988/2108/1995 +f 1988/2108/1995 1439/1528/1446 1989/2109/1996 +f 1439/1528/1446 1440/1529/1447 1989/2109/1996 +f 1989/2109/1996 1440/1529/1447 1990/2110/1997 +f 1441/1530/1448 1442/1531/1449 2026/2146/2033 +f 2026/2146/2033 1442/1531/1449 1956/2076/1963 +f 1440/1529/1447 1441/1530/1448 1990/2110/1997 +f 1990/2110/1997 1441/1530/1448 2026/2146/2033 +f 1442/1531/1449 1443/1532/1450 1956/2076/1963 +f 1956/2076/1963 1443/1532/1450 1957/2077/1964 +f 1443/1532/1450 1444/1533/1451 1957/2077/1964 +f 1957/2077/1964 1444/1533/1451 1958/2078/1965 +f 1444/1533/1451 1228/1318/1235 1958/2078/1965 +f 1958/2078/1965 1228/1318/1235 1866/1986/1873 +f 1915/2035/1922 1909/2029/1916 2043/2163/2050 +f 2043/2163/2050 1909/2029/1916 2044/2164/2051 +f 2019/2139/2026 2021/2141/2028 2044/2164/2051 +f 2044/2164/2051 2021/2141/2028 2043/2163/2050 +f 2021/2141/2028 1399/1488/1406 2043/2163/2050 +f 2043/2163/2050 1399/1488/1406 1447/1536/1454 +f 1285/1375/1292 1915/2035/1922 1447/1536/1454 +f 1447/1536/1454 1915/2035/1922 2043/2163/2050 +f 1432/1521/1439 1435/1524/1442 1918/2038/1925 +f 1918/2038/1925 1435/1524/1442 1919/2039/1926 +f 2045/2165/2052 1949/2069/1956 2003/2123/2010 +f 2003/2123/2010 1949/2069/1956 2046/2166/2053 +f 1949/2069/1956 1929/2049/1936 2046/2166/2053 +f 2046/2166/2053 1929/2049/1936 2005/2125/2012 +f 2047/2167/2054 2048/2168/2055 2005/2125/2012 +f 2005/2125/2012 2048/2168/2055 2046/2166/2053 +f 2048/2168/2055 2001/2121/2008 2046/2166/2053 +f 2046/2166/2053 2001/2121/2008 2003/2123/2010 +f 2032/2152/2039 1952/2072/1959 2038/2158/2045 +f 2038/2158/2045 1952/2072/1959 1951/2071/1958 +f 1891/2011/1898 2038/2158/2045 1906/2026/1913 +f 1906/2026/1913 2038/2158/2045 1951/2071/1958 +f 2001/2121/2008 2048/2168/2055 2017/2137/2024 +f 2017/2137/2024 2048/2168/2055 2049/2169/2056 +f 2048/2168/2055 2047/2167/2054 2049/2169/2056 +f 2049/2169/2056 2047/2167/2054 2050/2170/2057 +f 2035/2155/2042 1942/2062/1949 2051/2171/2058 +f 2051/2171/2058 1942/2062/1949 1947/2067/1954 +f 1947/2067/1954 1952/2072/1959 2051/2171/2058 +f 2051/2171/2058 1952/2072/1959 2031/2151/2038 +f 1975/2095/1982 1974/2094/1981 2031/2151/2038 +f 2031/2151/2038 1974/2094/1981 2051/2171/2058 +f 1973/2093/1980 2035/2155/2042 1974/2094/1981 +f 1974/2094/1981 2035/2155/2042 2051/2171/2058 +f 2017/2137/2024 2049/2169/2056 1911/2031/1918 +f 1911/2031/1918 2049/2169/2056 2052/2172/2059 +f 2050/2170/2057 2018/2138/2025 2049/2169/2056 +f 2049/2169/2056 2018/2138/2025 2052/2172/2059 +f 1923/2043/1930 1922/2042/1929 2037/2157/2044 +f 2037/2157/2044 1922/2042/1929 1977/2097/1984 +f 1975/2095/1982 2029/2149/2036 1977/2097/1984 +f 1977/2097/1984 2029/2149/2036 2037/2157/2044 +f 2044/2164/2051 1909/2029/1916 2052/2172/2059 +f 2052/2172/2059 1909/2029/1916 1911/2031/1918 +f 2042/2162/2049 1993/2113/2000 2053/2173/2060 +f 2053/2173/2060 1993/2113/2000 1995/2115/2002 +f 1966/2086/1973 1978/2098/1985 1995/2115/2002 +f 1995/2115/2002 1978/2098/1985 2053/2173/2060 +f 1978/2098/1985 1922/2042/1929 2053/2173/2060 +f 2053/2173/2060 1922/2042/1929 1921/2041/1928 +f 1919/2039/1926 2042/2162/2049 1921/2041/1928 +f 1921/2041/1928 2042/2162/2049 2053/2173/2060 +f 1913/2033/1920 2014/2134/2021 1914/2034/1921 +f 1914/2034/1921 2014/2134/2021 2015/2135/2022 +f 1869/1989/1876 1888/2008/1895 1867/1987/1874 +f 1867/1987/1874 1888/2008/1895 1872/1992/1879 +f 1906/2026/1913 1950/2070/1957 1907/2027/1914 +f 1907/2027/1914 1950/2070/1957 2045/2165/2052 +f 1949/2069/1956 2045/2165/2052 1950/2070/1957 +f 1958/2078/1965 1866/1986/1873 1953/2073/1960 +f 1953/2073/1960 1866/1986/1873 2054/2174/2061 +f 1866/1986/1873 1864/1984/1871 2054/2174/2061 +f 1864/1984/1871 1865/1985/1872 2054/2174/2061 +f 1925/2045/1932 1924/2044/1931 2054/2174/2061 +f 2054/2174/2061 1924/2044/1931 1953/2073/1960 +f 2023/2143/2030 2022/2142/2029 2055/2175/2062 +f 2055/2175/2062 2022/2142/2029 2041/2161/2048 +f 1980/2100/1987 1979/2099/1986 2041/2161/2048 +f 2041/2161/2048 1979/2099/1986 2055/2175/2062 +f 1979/2099/1986 1961/2081/1968 2055/2175/2062 +f 2055/2175/2062 1961/2081/1968 2034/2154/2041 +f 1940/2060/1947 2023/2143/2030 2034/2154/2041 +f 2034/2154/2041 2023/2143/2030 2055/2175/2062 +f 1962/2082/1969 2029/2149/2036 2033/2153/2040 +f 2033/2153/2040 2029/2149/2036 2030/2150/2037 +f 2032/2152/2039 1939/2059/1946 2030/2150/2037 +f 2030/2150/2037 1939/2059/1946 2033/2153/2040 +f 1930/2050/1937 1950/2070/1957 1941/2061/1948 +f 1941/2061/1948 1950/2070/1957 1948/2068/1955 +f 1930/2050/1937 1941/2061/1948 1926/2046/1933 +f 1926/2046/1933 1941/2061/1948 1943/2063/1950 +f 2047/2167/2054 2008/2128/2015 2050/2170/2057 +f 2050/2170/2057 2008/2128/2015 2018/2138/2025 +f 2008/2128/2015 2047/2167/2054 2006/2126/2013 +f 2006/2126/2013 2047/2167/2054 2005/2125/2012 +f 2018/2138/2025 2019/2139/2026 2052/2172/2059 +f 2052/2172/2059 2019/2139/2026 2044/2164/2051 +f 1932/2052/1939 1933/2053/1940 2006/2126/2013 +f 2006/2126/2013 1933/2053/1940 2007/2127/2014 +f 1934/2054/1941 1933/2053/1940 1931/2051/1938 +f 1931/2051/1938 1933/2053/1940 1932/2052/1939 +f 1931/2051/1938 1859/1979/1866 1934/2054/1941 +f 1934/2054/1941 1859/1979/1866 1863/1983/1870 +f 1857/1977/1864 1862/1982/1869 1859/1979/1866 +f 1859/1979/1866 1862/1982/1869 1863/1983/1870 +f 1865/1985/1872 1862/1982/1869 1928/2048/1935 +f 1928/2048/1935 1862/1982/1869 1857/1977/1864 +f 2054/2174/2061 1865/1985/1872 1925/2045/1932 +f 1925/2045/1932 1865/1985/1872 1928/2048/1935 +f 1879/2176/1886 2056/2177/2063 1419/1550/1426 +f 1419/1550/1426 2056/2177/2063 1459/1548/1466 +f 1671/1771/1678 2056/2177/2063 1855/1975/1862 +f 1855/1975/1862 2056/2177/2063 2057/2178/2064 +f 1855/1975/1862 1854/1974/1861 1671/1771/1678 +f 1671/1771/1678 1854/1974/1861 1670/1770/1677 +f 1854/1974/1861 1669/1769/1676 1670/1770/1677 +f 1670/1770/1677 1669/1769/1676 1668/1768/1675 +f 1023/1093/1030 1026/1096/1033 1668/1768/1675 +f 1668/1768/1675 1026/1096/1033 1670/1770/1677 +f 1871/2179/1878 1872/2180/1879 2058/2181/2065 +f 2058/2181/2065 1872/2180/1879 2059/2182/2066 +f 1662/1762/1669 1853/1973/1860 2060/2183/2067 +f 2060/2183/2067 1853/1973/1860 2059/2182/2066 +f 2061/2184/2068 2062/2185/2069 2063/2186/2070 +f 2063/2186/2070 2062/2185/2069 2064/2187/2071 +f 1666/1766/1673 2065/2188/2072 1471/1564/1478 +f 1471/1564/1478 2065/2188/2072 1469/1562/1476 +f 1855/1975/1862 2057/2178/2064 1852/1972/1859 +f 1852/1972/1859 2057/2178/2064 2058/2181/2065 +f 1662/1762/1669 2060/2183/2067 1661/1761/1668 +f 1661/1761/1668 2060/2183/2067 2064/2187/2071 +f 1887/2007/1894 1894/2014/1901 2039/2159/2046 +f 2039/2159/2046 1894/2014/1901 2063/2189/2070 +f 1875/1995/1882 1876/1996/1883 1897/2017/1904 +f 1897/2017/1904 1876/1996/1883 2061/2190/2068 +f 1663/1763/1670 2062/2185/2069 1664/1764/1671 +f 1664/1764/1671 2062/2185/2069 2066/2191/2073 +f 2063/2189/2070 1894/2014/1901 2061/2190/2068 +f 2061/2190/2068 1894/2014/1901 1897/2017/1904 +f 1028/1098/1035 1459/1548/1466 1671/1771/1678 +f 1671/1771/1678 1459/1548/1466 2056/2177/2063 +f 1242/1569/1249 1469/1562/1476 1874/2192/1881 +f 1874/2192/1881 1469/1562/1476 2065/2188/2072 +f 1879/2176/1886 1878/2193/1885 2056/2177/2063 +f 2056/2177/2063 1878/2193/1885 2057/2178/2064 +f 1878/2193/1885 1871/2179/1878 2057/2178/2064 +f 2057/2178/2064 1871/2179/1878 2058/2181/2065 +f 1853/1973/1860 1852/1972/1859 2059/2182/2066 +f 2059/2182/2066 1852/1972/1859 2058/2181/2065 +f 2039/2194/2046 2060/2183/2067 1872/2180/1879 +f 1872/2180/1879 2060/2183/2067 2059/2182/2066 +f 2063/2186/2070 2064/2187/2071 2039/2194/2046 +f 2039/2194/2046 2064/2187/2071 2060/2183/2067 +f 1661/1761/1668 2064/2187/2071 1663/1763/1670 +f 1663/1763/1670 2064/2187/2071 2062/2185/2069 +f 1876/2195/1883 2066/2191/2073 2061/2184/2068 +f 2061/2184/2068 2066/2191/2073 2062/2185/2069 +f 1874/2192/1881 2065/2188/2072 1876/2195/1883 +f 1876/2195/1883 2065/2188/2072 2066/2191/2073 +f 2067/2196/2074 2045/2165/2052 2004/2124/2011 +f 2004/2124/2011 2045/2165/2052 2003/2123/2010 +f 2067/2196/2074 2004/2124/2011 1899/2019/1906 +f 1899/2019/1906 2004/2124/2011 1998/2118/2005 +f 2067/2196/2074 1899/2019/1906 2068/2197/2075 +f 2068/2197/2075 1899/2019/1906 1896/2016/1903 +f 1907/2027/1914 2045/2165/2052 1908/2028/1915 +f 1908/2028/1915 2045/2165/2052 2067/2196/2074 +f 1908/2028/1915 2067/2196/2074 2040/2160/2047 +f 2040/2160/2047 2067/2196/2074 2068/2197/2075 +f 1894/2014/1901 2040/2160/2047 1897/2017/1904 +f 1897/2017/1904 2040/2160/2047 2068/2197/2075 +f 1897/2017/1904 2068/2197/2075 1896/2016/1903 +f 1892/2012/1899 1908/2028/1915 1893/2013/1900 +f 1893/2013/1900 1908/2028/1915 2040/2160/2047 +f 1664/1764/1671 2066/2191/2073 1666/1766/1673 +f 1666/1766/1673 2066/2191/2073 2065/2188/2072 +f 1511/1611/1518 1512/1612/1519 1495/1595/1502 +f 1495/1595/1502 1512/1612/1519 1497/1597/1504 +f 1524/1624/1531 1525/1625/1532 1511/1611/1518 +f 1511/1611/1518 1525/1625/1532 1512/1612/1519 +f 1537/1637/1544 1538/1638/1545 1524/1624/1531 +f 1524/1624/1531 1538/1638/1545 1525/1625/1532 +f 1550/1650/1557 1551/1651/1558 1537/1637/1544 +f 1537/1637/1544 1551/1651/1558 1538/1638/1545 +f 1550/1650/1557 1563/1663/1570 1551/1651/1558 +f 1551/1651/1558 1563/1663/1570 791/861/798 +f 1575/1675/1582 794/864/801 1563/1663/1570 +f 1563/1663/1570 794/864/801 791/861/798 +f 1646/1746/1653 1667/1767/1674 807/877/814 +f 1652/1752/1659 1658/1758/1665 1667/1767/1674 +f 1667/1767/1674 1658/1758/1665 1665/1765/1672 +f 1106/1176/1113 1091/1161/1098 1107/1177/1114 +f 1107/1177/1114 1091/1161/1098 1093/1163/1100 +f 1092/1162/1099 1112/1182/1119 1094/1164/1101 +f 1094/1164/1101 1112/1182/1119 1097/1167/1104 +f 1096/1166/1103 1108/1178/1115 1094/1164/1101 +f 1094/1164/1101 1108/1178/1115 1093/1163/1100 +f 1109/1179/1116 1102/1172/1109 1107/1177/1114 +f 1107/1177/1114 1102/1172/1109 1104/1174/1111 +f 1114/1184/1121 1095/1165/1102 1111/1181/1118 +f 1111/1181/1118 1095/1165/1102 1097/1167/1104 +f 1099/1169/1106 1105/1175/1112 1101/1171/1108 +f 1101/1171/1108 1105/1175/1112 1104/1174/1111 +f 1110/1180/1117 1116/1186/1123 1111/1181/1118 +f 1111/1181/1118 1116/1186/1123 1115/1185/1122 +f 1103/1173/1110 1150/1220/1157 1101/1171/1108 +f 1101/1171/1108 1150/1220/1157 1100/1170/1107 +f 1119/1189/1126 1113/1183/1120 1118/1188/1125 +f 1118/1188/1125 1113/1183/1120 1115/1185/1122 +f 1098/1168/1105 1100/1170/1107 1146/1216/1153 +f 1146/1216/1153 1100/1170/1107 1147/1217/1154 +f 1127/1197/1134 1121/1191/1128 1117/1187/1124 +f 1117/1187/1124 1121/1191/1128 1118/1188/1125 +f 1144/1214/1151 1145/1215/1152 1149/1219/1156 +f 1149/1219/1156 1145/1215/1152 1147/1217/1154 +f 1120/1190/1127 1121/1191/1128 1122/1192/1129 +f 1122/1192/1129 1121/1191/1128 1123/1193/1130 +f 1148/1218/1155 1145/1215/1152 1140/1210/1147 +f 1140/1210/1147 1145/1215/1152 1141/1211/1148 +f 1130/1200/1137 1125/1195/1132 1126/1196/1133 +f 1126/1196/1133 1125/1195/1132 1123/1193/1130 +f 1138/1208/1145 1139/1209/1146 1143/1213/1150 +f 1143/1213/1150 1139/1209/1146 1141/1211/1148 +f 1124/1194/1131 1125/1195/1132 1131/1201/1138 +f 1131/1201/1138 1125/1195/1132 1129/1199/1136 +f 1142/1212/1149 1139/1209/1146 1134/1204/1141 +f 1134/1204/1141 1139/1209/1146 1135/1205/1142 +f 1136/1206/1143 1133/1203/1140 1128/1198/1135 +f 1128/1198/1135 1133/1203/1140 1129/1199/1136 +f 1132/1202/1139 1133/1203/1140 1137/1207/1144 +f 1137/1207/1144 1133/1203/1140 1135/1205/1142 +f 1734/1834/1741 1735/1835/1742 1752/1852/1759 +f 1752/1852/1759 1735/1835/1742 1737/1837/1744 +f 1747/1847/1754 1748/1848/1755 1732/1832/1739 +f 1732/1832/1739 1748/1848/1755 1733/1833/1740 +f 1738/1838/1745 1735/1835/1742 1749/1849/1756 +f 1749/1849/1756 1735/1835/1742 1733/1833/1740 +f 1756/1856/1763 1753/1853/1760 1736/1836/1743 +f 1736/1836/1743 1753/1853/1760 1737/1837/1744 +f 1750/1850/1757 1748/1848/1755 1743/1843/1750 +f 1743/1843/1750 1748/1848/1755 1744/1844/1751 +f 1751/1851/1758 1753/1853/1760 1757/1857/1764 +f 1757/1857/1764 1753/1853/1760 1755/1855/1762 +f 1741/1841/1748 1742/1842/1749 1746/1846/1753 +f 1746/1846/1753 1742/1842/1749 1744/1844/1751 +f 1760/1860/1767 1759/1859/1766 1754/1854/1761 +f 1754/1854/1761 1759/1859/1766 1755/1855/1762 +f 1745/1845/1752 1742/1842/1749 1791/1891/1798 +f 1791/1891/1798 1742/1842/1749 1740/1840/1747 +f 1768/1868/1775 1758/1858/1765 1762/1862/1769 +f 1762/1862/1769 1758/1858/1765 1759/1859/1766 +f 1739/1839/1746 1787/1887/1794 1740/1840/1747 +f 1740/1840/1747 1787/1887/1794 1789/1889/1796 +f 1761/1861/1768 1763/1863/1770 1762/1862/1769 +f 1762/1862/1769 1763/1863/1770 1765/1865/1772 +f 1785/1885/1792 1790/1890/1797 1786/1886/1793 +f 1786/1886/1793 1790/1890/1797 1789/1889/1796 +f 1770/1870/1777 1767/1867/1774 1766/1866/1773 +f 1766/1866/1773 1767/1867/1774 1765/1865/1772 +f 1788/1888/1795 1781/1881/1788 1786/1886/1793 +f 1786/1886/1793 1781/1881/1788 1783/1883/1790 +f 1764/1864/1771 1772/1872/1779 1766/1866/1773 +f 1766/1866/1773 1772/1872/1779 1771/1871/1778 +f 1779/1879/1786 1784/1884/1791 1780/1880/1787 +f 1780/1880/1787 1784/1884/1791 1783/1883/1790 +f 1776/1876/1783 1769/1869/1776 1774/1874/1781 +f 1774/1874/1781 1769/1869/1776 1771/1871/1778 +f 1782/1882/1789 1775/1875/1782 1780/1880/1787 +f 1780/1880/1787 1775/1875/1782 1777/1877/1784 +f 1773/1873/1780 1778/1878/1785 1774/1874/1781 +f 1774/1874/1781 1778/1878/1785 1777/1877/1784 +f 573/619/580 676/738/683 571/617/578 +f 571/617/578 676/738/683 2069/2198/2076 +f 513/553/520 654/712/661 507/547/514 +f 507/547/514 654/712/661 676/738/683 +f 2069/2198/2076 676/738/683 724/790/731 +f 724/790/731 676/738/683 654/712/661 +f 621/673/628 620/672/627 772/840/779 +f 772/840/779 620/672/627 773/841/780 +f 631/683/638 771/839/778 624/676/631 +f 624/676/631 771/839/778 772/840/779 +f 629/681/636 627/679/634 770/838/777 +f 770/838/777 627/679/634 771/839/778 +f 665/723/672 768/836/775 632/684/639 +f 632/684/639 768/836/775 770/838/777 +f 665/723/672 701/765/708 768/836/775 +f 768/836/775 701/765/708 769/837/776 +f 694/756/701 767/835/774 743/809/750 +f 743/809/750 767/835/774 765/833/772 +f 556/599/563 763/831/770 554/597/561 +f 554/597/561 763/831/770 764/832/771 +f 636/688/643 763/831/770 637/689/644 +f 637/689/644 763/831/770 762/830/769 +f 570/616/577 761/829/768 559/602/566 +f 559/602/566 761/829/768 762/830/769 +f 643/697/650 761/829/768 644/698/651 +f 644/698/651 761/829/768 760/828/767 +f 568/614/575 673/735/680 760/828/767 +f 760/828/767 673/735/680 759/827/766 +f 650/706/657 649/705/656 758/826/765 +f 758/826/765 649/705/656 759/827/766 +f 733/799/740 735/801/742 756/824/763 +f 756/824/763 735/801/742 757/825/764 +f 1619/1719/1626 1630/1730/1637 801/871/808 +f 801/871/808 1630/1730/1637 802/872/809 +f 1608/1708/1615 1619/1719/1626 799/869/806 +f 799/869/806 1619/1719/1626 801/871/808 +f 1597/1697/1604 1608/1708/1615 798/868/805 +f 798/868/805 1608/1708/1615 799/869/806 +f 1586/1686/1593 1597/1697/1604 795/865/802 +f 795/865/802 1597/1697/1604 798/868/805 +f 804/874/811 802/872/809 1638/1738/1645 +f 1638/1738/1645 802/872/809 1630/1730/1637 +f 807/877/814 804/874/811 1646/1746/1653 +f 1646/1746/1653 804/874/811 1638/1738/1645 +f 807/877/814 1667/1767/1674 438/479/445 +f 438/479/445 1667/1767/1674 1021/1091/1028 +f 438/479/445 1021/1091/1028 376/416/383 +f 376/416/383 1021/1091/1028 1022/1092/1029 +f 794/864/801 1575/1675/1582 795/865/802 +f 795/865/802 1575/1675/1582 1586/1686/1593 +f 2070/2199/2077 1500/1600/1507 2071/2200/2078 +f 2071/2200/2078 1500/1600/1507 1499/1599/1506 +f 791/861/798 437/478/444 1551/1651/1558 +f 1551/1651/1558 437/478/444 1552/1652/1559 +f 2072/2201/2079 2071/2200/2078 1513/1613/1520 +f 1513/1613/1520 2071/2200/2078 1499/1599/1506 +f 2073/2202/2080 2072/2201/2079 1526/1626/1533 +f 1526/1626/1533 2072/2201/2079 1513/1613/1520 +f 2073/2202/2080 1526/1626/1533 2074/2203/2081 +f 2074/2203/2081 1526/1626/1533 1539/1639/1546 +f 1564/1664/1571 2074/2203/2081 1552/1652/1559 +f 1552/1652/1559 2074/2203/2081 1539/1639/1546 +f 413/453/420 414/454/421 782/851/789 +f 782/851/789 414/454/421 423/2204/430 +f 112/125/119 114/127/121 410/450/417 +f 410/450/417 114/127/121 412/452/419 +f 977/1047/984 371/411/378 986/1056/993 +f 986/1056/993 371/411/378 374/414/381 +f 977/1047/984 965/1035/972 371/411/378 +f 371/411/378 965/1035/972 369/409/376 +f 833/903/840 832/902/839 837/907/844 +f 837/907/844 832/902/839 836/906/843 +f 360/400/367 361/401/368 2075/2205/2082 +f 2075/2205/2082 361/401/368 893/963/900 +f 2076/2206/2083 851/921/858 835/905/842 +f 835/905/842 851/921/858 837/907/844 +f 2077/2207/2084 865/935/872 2076/2206/2083 +f 2076/2206/2083 865/935/872 851/921/858 +f 2078/2208/2085 879/949/886 2077/2207/2084 +f 2077/2207/2084 879/949/886 865/935/872 +f 2075/2205/2082 893/963/900 2078/2208/2085 +f 2078/2208/2085 893/963/900 879/949/886 +f 929/999/936 917/987/924 366/406/373 +f 366/406/373 917/987/924 365/405/372 +f 366/406/373 368/408/375 929/999/936 +f 929/999/936 368/408/375 941/1011/948 +f 941/1011/948 368/408/375 953/1023/960 +f 953/1023/960 368/408/375 369/409/376 +f 965/1035/972 953/1023/960 369/409/376 +f 376/416/383 1022/1092/1029 2079/2209/2086 +f 2079/2209/2086 374/414/381 376/416/383 +f 1666/1766/1673 1471/1564/1478 1665/1765/1672 +f 1665/1765/1672 1471/1564/1478 1020/1090/1027 +f 1018/1088/1025 1020/1090/1027 1019/1089/1026 +f 1019/1089/1026 1020/1090/1027 1471/1564/1478 +f 2/12/9 2080/1/2087 4/14/11 +f 4/14/11 2080/1/2087 2081/2210/2088 +f 5/15/12 2082/2/2089 2/12/9 +f 2/12/9 2082/2/2089 2080/1/2087 +f 8/18/15 2083/4/2090 5/15/12 +f 5/15/12 2083/4/2090 2082/2/2089 +f 9/19/16 2084/5/2091 8/18/15 +f 8/18/15 2084/5/2091 2083/4/2090 +f 180/203/187 179/202/186 2085/2211/2092 +f 2085/2211/2092 179/202/186 2086/2212/2093 +f 182/205/189 181/204/188 2087/2213/2094 +f 2087/2213/2094 181/204/188 2088/2214/2095 +f 179/202/186 182/205/189 2086/2212/2093 +f 2086/2212/2093 182/205/189 2087/2213/2094 +f 4/14/11 2081/2210/2088 185/208/192 +f 185/208/192 2081/2210/2088 2089/2215/2096 +f 187/210/194 180/203/187 2090/7/2097 +f 2090/7/2097 180/203/187 2085/2211/2092 +f 185/208/192 2089/2215/2096 334/374/341 +f 334/374/341 2089/2215/2096 2091/2216/2098 +f 352/392/359 187/210/194 2092/6/2099 +f 2092/6/2099 187/210/194 2090/7/2097 +f 334/374/341 2091/2216/2098 181/204/188 +f 181/204/188 2091/2216/2098 2088/2214/2095 +f 2084/5/2091 9/19/16 2093/8/2100 +f 2093/8/2100 9/19/16 378/418/385 +f 352/392/359 2092/6/2099 433/474/440 +f 433/474/440 2092/6/2099 2094/2217/2101 +f 442/483/449 443/484/450 2095/2218/2102 +f 2095/2218/2102 443/484/450 2096/2219/2103 +f 445/486/452 442/483/449 2097/2220/2104 +f 2097/2220/2104 442/483/449 2095/2218/2102 +f 447/488/454 445/486/452 2098/10/2105 +f 2098/10/2105 445/486/452 2097/2220/2104 +f 447/488/454 2098/10/2105 449/490/456 +f 449/490/456 2098/10/2105 2099/10/2106 +f 618/670/625 2100/2221/2107 619/671/626 +f 619/671/626 2100/2221/2107 2101/2222/2108 +f 622/674/629 2102/2223/2109 620/672/627 +f 620/672/627 2102/2223/2109 2103/2224/2110 +f 619/671/626 2101/2222/2108 622/674/629 +f 622/674/629 2101/2222/2108 2102/2223/2109 +f 443/484/450 625/677/632 2096/2219/2103 +f 2096/2219/2103 625/677/632 2104/2225/2111 +f 626/678/633 2105/2226/2112 618/670/625 +f 618/670/625 2105/2226/2112 2100/2221/2107 +f 625/677/632 773/841/780 2104/2225/2111 +f 2104/2225/2111 773/841/780 2106/2227/2113 +f 449/490/456 2099/10/2106 775/843/782 +f 775/843/782 2099/10/2106 2107/9/2114 +f 433/474/440 2094/2217/2101 626/678/633 +f 626/678/633 2094/2217/2101 2105/2226/2112 +f 773/841/780 620/672/627 2106/2227/2113 +f 2106/2227/2113 620/672/627 2103/2224/2110 +f 2081/2210/2088 2080/1/2087 2108/3/2115 +f 2085/2211/2092 2086/2212/2093 2108/3/2115 +f 2087/2213/2094 2088/2214/2095 2108/3/2115 +f 2086/2212/2093 2087/2213/2094 2108/3/2115 +f 2089/2215/2096 2081/2210/2088 2108/3/2115 +f 2090/7/2097 2085/2211/2092 2108/3/2115 +f 2091/2216/2098 2089/2215/2096 2108/3/2115 +f 2088/2214/2095 2091/2216/2098 2108/3/2115 +f 2094/2217/2101 2092/6/2099 2108/3/2116 +f 2095/2218/2102 2096/2219/2103 2108/3/2116 +f 2097/2220/2104 2095/2218/2102 2108/3/2116 +f 2098/10/2105 2097/2220/2104 2108/3/2116 +f 2099/10/2106 2098/10/2105 2108/3/2116 +f 2101/2222/2108 2100/2221/2107 2108/3/2116 +f 2103/2224/2110 2102/2223/2109 2108/3/2116 +f 2102/2223/2109 2101/2222/2108 2108/3/2116 +f 2096/2219/2103 2104/2225/2111 2108/3/2116 +f 2100/2221/2107 2105/2226/2112 2108/3/2116 +f 2104/2225/2111 2106/2227/2113 2108/3/2116 +f 2105/2226/2112 2094/2217/2101 2108/3/2116 +f 2106/2227/2113 2103/2224/2110 2108/3/2116 +f 1022/1092/1029 1003/1073/1010 2079/2209/2086 +f 2079/2209/2086 1003/1073/1010 996/1066/1003 +f 986/1056/993 374/414/381 996/1066/1003 +f 996/1066/1003 374/414/381 2079/2209/2086 +f 1646/1746/1653 1652/1752/1659 1667/1767/1674 +f 2107/9/2114 2093/8/2100 775/843/782 +f 775/843/782 2093/8/2100 378/418/385 +f 88/100/95 407/2228/414 87/98/94 +f 87/98/94 407/2228/414 404/2229/411 +f 776/844/783 774/842/781 380/420/387 +f 380/420/387 774/842/781 379/419/386 +f 774/842/781 775/843/782 379/419/386 +f 379/419/386 775/843/782 378/418/385 +f 777/845/784 776/844/783 381/421/388 +f 381/421/388 776/844/783 380/420/387 +f 777/845/784 381/421/388 781/850/788 +f 781/850/788 381/421/388 410/450/417 +f 781/850/788 410/450/417 411/451/418 +f 411/451/418 410/450/417 412/452/419 +f 114/127/121 125/141/132 412/452/419 +f 412/452/419 125/141/132 414/454/421 +f 125/141/132 127/143/134 414/454/421 +f 414/454/421 127/143/134 423/2204/430 +f 782/852/789 423/2230/430 783/853/790 +f 783/853/790 423/2230/430 424/2231/431 +f 783/853/790 424/2231/431 784/854/791 +f 784/854/791 424/2231/431 425/2232/432 +f 784/854/791 425/2232/432 785/855/792 +f 785/855/792 425/2232/432 426/2233/433 +f 785/855/792 426/2233/433 779/848/786 +f 779/848/786 426/2233/433 408/2234/415 +f 780/849/787 779/848/786 409/2235/416 +f 409/2235/416 779/848/786 408/2234/415 +f 778/846/785 780/849/787 403/2236/410 +f 403/2236/410 780/849/787 409/2235/416 +f 778/846/785 403/2236/410 405/847/412 +f 405/847/412 403/2236/410 404/2237/411 +f 407/2228/414 88/100/95 421/2238/428 +f 421/2238/428 88/100/95 155/174/162 +f 141/160/148 417/2239/424 155/174/162 +f 155/174/162 417/2239/424 421/2238/428 +f 136/159/143 415/2240/422 141/160/148 +f 141/160/148 415/2240/422 417/2239/424 +f 136/152/143 78/88/85 415/459/422 +f 415/459/422 78/88/85 397/437/404 +f 76/86/83 395/435/402 78/88/85 +f 78/88/85 395/435/402 397/437/404 +f 79/89/86 399/439/406 76/86/83 +f 76/86/83 399/439/406 395/435/402 +f 79/89/86 82/92/89 399/439/406 +f 399/439/406 82/92/89 401/441/408 +f 82/92/89 354/394/361 401/441/408 +f 401/441/408 354/394/361 429/471/436 +f 354/394/361 356/396/363 429/471/436 +f 429/471/436 356/396/363 431/472/438 +f 359/399/366 434/475/441 356/396/363 +f 356/396/363 434/475/441 431/472/438 +f 360/400/367 436/477/443 359/399/366 +f 359/399/366 436/477/443 434/475/441 +f 2075/2205/2082 1564/1664/1571 360/400/367 +f 360/400/367 1564/1664/1571 436/477/443 +f 2078/2208/2085 2074/2203/2081 2075/2205/2082 +f 2075/2205/2082 2074/2203/2081 1564/1664/1571 +f 2078/2208/2085 2077/2207/2084 2074/2203/2081 +f 2074/2203/2081 2077/2207/2084 2073/2202/2080 +f 2077/2207/2084 2076/2206/2083 2073/2202/2080 +f 2073/2202/2080 2076/2206/2083 2072/2201/2079 +f 2076/2206/2083 835/905/842 2072/2201/2079 +f 2072/2201/2079 835/905/842 2071/2200/2078 +f 835/905/842 834/904/841 2071/2200/2078 +f 2071/2200/2078 834/904/841 2070/2199/2077 +f 1030/1100/1037 2070/2199/2077 834/904/841 +f 1500/1600/1507 2070/2199/2077 1030/1100/1037 +f 1030/1100/1037 836/906/843 832/902/839 +f 291/329/298 133/2241/140 293/331/300 +f 293/331/300 133/2241/140 289/2242/296 +f 297/335/304 377/2243/384 295/333/302 +f 295/333/302 377/2243/384 135/2244/142 +f 295/333/302 135/2244/142 291/329/298 +f 291/329/298 135/2244/142 133/2241/140 +f 245/279/252 242/276/249 246/2245/253 +f 246/2245/253 242/276/249 238/2246/245 +f 243/277/250 251/285/258 239/2247/246 +f 239/2247/246 251/285/258 247/2248/254 +f 242/276/249 243/277/250 238/2246/245 +f 238/2246/245 243/277/250 239/2247/246 +f 264/300/271 245/279/252 262/2249/269 +f 262/2249/269 245/279/252 246/2245/253 +f 293/331/300 289/2242/296 252/286/259 +f 252/286/259 289/2242/296 248/2250/255 +f 251/285/258 252/286/259 247/2248/254 +f 247/2248/254 252/286/259 248/2250/255 +f 258/294/265 253/287/260 260/296/267 +f 260/296/267 253/287/260 261/297/268 +f 328/368/335 329/2251/336 256/290/263 +f 256/290/263 329/2251/336 254/2252/261 +f 256/290/263 254/2252/261 258/292/265 +f 258/292/265 254/2252/261 253/2253/260 +f 260/296/267 261/297/268 267/303/274 +f 267/303/274 261/297/268 265/301/272 +f 328/368/335 264/300/271 329/2251/336 +f 329/2251/336 264/300/271 262/2249/269 +f 267/303/274 265/301/272 269/305/276 +f 269/305/276 265/301/272 270/306/277 +f 269/305/276 270/306/277 273/309/280 +f 273/309/280 270/306/277 271/307/278 +f 275/311/282 273/309/280 276/312/283 +f 276/312/283 273/309/280 271/307/278 +f 288/326/295 275/311/282 286/324/293 +f 286/324/293 275/311/282 276/312/283 +f 284/321/291 281/322/288 285/2254/292 +f 285/2254/292 281/322/288 277/2255/284 +f 282/318/289 288/326/295 278/314/285 +f 278/314/285 288/326/295 286/324/293 +f 281/317/288 282/318/289 277/313/284 +f 277/313/284 282/318/289 278/314/285 +f 297/335/304 284/321/291 377/2243/384 +f 377/2243/384 284/321/291 285/2254/292 +f 736/802/743 734/800/741 2069/2256/2076 +f 2069/2256/2076 734/800/741 571/2257/578 +f 731/797/738 732/798/739 572/2258/579 +f 572/2258/579 732/798/739 728/2259/735 +f 734/800/741 731/797/738 571/2257/578 +f 571/2257/578 731/797/738 572/2258/579 +f 682/744/689 677/2260/684 689/751/696 +f 689/751/696 677/2260/684 687/2261/694 +f 684/746/691 685/2262/692 680/742/687 +f 680/742/687 685/2262/692 678/2263/685 +f 680/742/687 678/2263/685 682/744/689 +f 682/744/689 678/2263/685 677/2260/684 +f 703/767/710 701/2264/708 684/746/691 +f 684/746/691 701/2264/708 685/2262/692 +f 732/798/739 691/753/698 728/2259/735 +f 728/2259/735 691/753/698 686/2265/693 +f 689/751/696 687/2261/694 691/753/698 +f 691/753/698 687/2261/694 686/2265/693 +f 766/834/773 696/758/703 769/2266/776 +f 769/2266/776 696/758/703 693/2267/700 +f 697/762/704 699/763/706 692/754/699 +f 692/754/699 699/763/706 700/764/707 +f 696/758/703 697/759/704 693/2267/700 +f 693/2267/700 697/759/704 692/2268/699 +f 699/763/706 706/770/713 700/764/707 +f 700/764/707 706/770/713 704/768/711 +f 766/834/773 769/2266/776 703/767/710 +f 703/767/710 769/2266/776 701/2264/708 +f 706/770/713 708/772/715 704/768/711 +f 704/768/711 708/772/715 709/773/716 +f 708/772/715 712/776/719 709/773/716 +f 709/773/716 712/776/719 710/774/717 +f 714/778/721 715/779/722 712/776/719 +f 712/776/719 715/779/722 710/774/717 +f 727/793/734 725/791/732 714/778/721 +f 714/778/721 725/791/732 715/779/722 +f 721/785/728 716/780/723 727/793/734 +f 727/793/734 716/780/723 725/791/732 +f 723/787/730 724/2269/731 719/789/726 +f 719/789/726 724/2269/731 717/2270/724 +f 719/783/726 717/781/724 721/785/728 +f 721/785/728 717/781/724 716/780/723 +f 736/802/743 2069/2256/2076 723/787/730 +f 723/787/730 2069/2256/2076 724/2269/731 +f 1928/2048/1935 1857/1977/1864 1856/1976/1863 +f 1217/1307/1224 1216/1306/1223 1219/1309/1226 diff --git a/Demo/RenderDemo/data/sounds/bgm/01 - The Signal.mp3 b/Demo/RenderDemo/data/sounds/bgm/01 - The Signal.mp3 new file mode 100644 index 0000000..87d9824 Binary files /dev/null and b/Demo/RenderDemo/data/sounds/bgm/01 - The Signal.mp3 differ diff --git a/Demo/RenderDemo/data/sounds/bgm/Asketa & Natan Chaim - More [NCS Release].mp3 b/Demo/RenderDemo/data/sounds/bgm/Asketa & Natan Chaim - More [NCS Release].mp3 new file mode 100644 index 0000000..ffcc90f Binary files /dev/null and b/Demo/RenderDemo/data/sounds/bgm/Asketa & Natan Chaim - More [NCS Release].mp3 differ diff --git a/Demo/RenderDemo/data/sounds/bgm/lofi-chill-medium-version-159456.mp3 b/Demo/RenderDemo/data/sounds/bgm/lofi-chill-medium-version-159456.mp3 new file mode 100644 index 0000000..f74f413 Binary files /dev/null and b/Demo/RenderDemo/data/sounds/bgm/lofi-chill-medium-version-159456.mp3 differ diff --git a/Demo/RenderDemo/data/texture/awesomeface.png b/Demo/RenderDemo/data/texture/awesomeface.png new file mode 100644 index 0000000..9840caf Binary files /dev/null and b/Demo/RenderDemo/data/texture/awesomeface.png differ diff --git a/Demo/RenderDemo/data/texture/blending_transparent_window.png b/Demo/RenderDemo/data/texture/blending_transparent_window.png new file mode 100644 index 0000000..1188863 Binary files /dev/null and b/Demo/RenderDemo/data/texture/blending_transparent_window.png differ diff --git a/Demo/RenderDemo/data/texture/concrete.jpg b/Demo/RenderDemo/data/texture/concrete.jpg new file mode 100644 index 0000000..93bf21a Binary files /dev/null and b/Demo/RenderDemo/data/texture/concrete.jpg differ diff --git a/Demo/RenderDemo/data/texture/container.jpg b/Demo/RenderDemo/data/texture/container.jpg new file mode 100644 index 0000000..d07bee4 Binary files /dev/null and b/Demo/RenderDemo/data/texture/container.jpg differ diff --git a/Demo/RenderDemo/data/texture/container2.png b/Demo/RenderDemo/data/texture/container2.png new file mode 100644 index 0000000..596e8da Binary files /dev/null and b/Demo/RenderDemo/data/texture/container2.png differ diff --git a/Demo/RenderDemo/data/texture/container2_specular.png b/Demo/RenderDemo/data/texture/container2_specular.png new file mode 100644 index 0000000..681bf6e Binary files /dev/null and b/Demo/RenderDemo/data/texture/container2_specular.png differ diff --git a/Demo/RenderDemo/data/texture/duck_diffuse.png b/Demo/RenderDemo/data/texture/duck_diffuse.png new file mode 100644 index 0000000..5f55c1a Binary files /dev/null and b/Demo/RenderDemo/data/texture/duck_diffuse.png differ diff --git a/Demo/RenderDemo/data/texture/grass.png b/Demo/RenderDemo/data/texture/grass.png new file mode 100644 index 0000000..0eafd97 Binary files /dev/null and b/Demo/RenderDemo/data/texture/grass.png differ diff --git a/Demo/RenderDemo/data/texture/marble.jpg b/Demo/RenderDemo/data/texture/marble.jpg new file mode 100644 index 0000000..7ca023d Binary files /dev/null and b/Demo/RenderDemo/data/texture/marble.jpg differ diff --git a/Demo/RenderDemo/data/texture/matrix.jpg b/Demo/RenderDemo/data/texture/matrix.jpg new file mode 100644 index 0000000..2361c1c Binary files /dev/null and b/Demo/RenderDemo/data/texture/matrix.jpg differ diff --git a/Demo/RenderDemo/data/texture/metal.jpg b/Demo/RenderDemo/data/texture/metal.jpg new file mode 100644 index 0000000..11a786d Binary files /dev/null and b/Demo/RenderDemo/data/texture/metal.jpg differ diff --git a/Demo/RenderDemo/data/texture/wall.jpg b/Demo/RenderDemo/data/texture/wall.jpg new file mode 100644 index 0000000..4963198 Binary files /dev/null and b/Demo/RenderDemo/data/texture/wall.jpg differ diff --git a/Demo/RenderDemo/data/texture/wood.jpg b/Demo/RenderDemo/data/texture/wood.jpg new file mode 100644 index 0000000..4f32173 Binary files /dev/null and b/Demo/RenderDemo/data/texture/wood.jpg differ diff --git a/Demo/RenderDemo/source/Main.cpp b/Demo/RenderDemo/source/Main.cpp new file mode 100644 index 0000000..ccf2769 --- /dev/null +++ b/Demo/RenderDemo/source/Main.cpp @@ -0,0 +1,185 @@ +#include + +// Getting started +#include "app/ColorTriangle.h" +#include "app/CubePerspective.h" +#include "app/HelloCamera.h" +#include "app/HelloPerspective.h" +#include "app/HelloTriangle.h" +#include "app/LookAroundCamera.h" +#include "app/RotatingCubes.h" +#include "app/SimpleMoveCamera.h" +#include "app/TexturedQuad.h" +#include "app/TexturedTriangle.h" +#include "app/TransformedQuad.h" + +// Lighting +#include "app/BasicLighting.h" +#include "app/LightCube.h" +#include "app/SimpleMaterial.h" +#include "app/LightingMaps.h" +#include "app/DirectionalLightCaster.h" +#include "app/PointLightCaster.h" +#include "app/SpotLightCaster.h" +#include "app/MultipleLights.h" + +// Model loading +#include "app/ModelLoad.h" + +// Advanced OpenGL + +// Advanced lighting + +// PBR + +// In practice +#include "app/RenderText.h" + +// Other +#include "app/ImguiDemo.h" + +enum class AppKind +{ + // Getting started + HelloTriangle, + ColorTriangle, + TexturedTriangle, + TexturedQuad, + TransformedQuad, + HelloPerspective, + CubePerspective, + RotatingCubes, + HelloCamera, + SimpleMoveCamera, + LookAroundCamera, + LightCube, + + // Lighting + BasicLighting, + SimpleMaterial, + LightingMaps, + // Lighting - light casters + DirectionalLightCaster, + PointLightCaster, + SpotLightCaster, + MultipleLights, + + // Model loading + ModelLoad, + + // In practice + RenderText, + + // Other + ImguiDemo +}; + +std::unique_ptr createApp(AppKind kind) +{ + switch (kind) + { + case AppKind::HelloTriangle: + return std::make_unique(); + case AppKind::ColorTriangle: + return std::make_unique(); + case AppKind::TexturedTriangle: + return std::make_unique(); + case AppKind::TexturedQuad: + return std::make_unique(); + case AppKind::TransformedQuad: + return std::make_unique(); + case AppKind::HelloPerspective: + return std::make_unique(); + case AppKind::CubePerspective: + return std::make_unique(); + case AppKind::RotatingCubes: + return std::make_unique(); + case AppKind::HelloCamera: + return std::make_unique(); + case AppKind::SimpleMoveCamera: + return std::make_unique(); + case AppKind::LookAroundCamera: + return std::make_unique(); + case AppKind::LightCube: + return std::make_unique(); + case AppKind::BasicLighting: + return std::make_unique(); + case AppKind::SimpleMaterial: + return std::make_unique(); + case AppKind::LightingMaps: + return std::make_unique(); + case AppKind::DirectionalLightCaster: + return std::make_unique(); + case AppKind::PointLightCaster: + return std::make_unique(); + case AppKind::SpotLightCaster: + return std::make_unique(); + case AppKind::MultipleLights: + return std::make_unique(); + case AppKind::RenderText: + return std::make_unique(); + case AppKind::ModelLoad: + return std::make_unique(); + case AppKind::ImguiDemo: + return std::make_unique(); + } + throw std::runtime_error("Unsupported app kind"); +} + +int main(int argc, char** argv) +{ +#ifndef NDEBUG + fmtlog::setLogLevel(fmtlog::DBG); +#endif + fmtlog::startPollingThread(); + + try + { + std::vector kinds; + + // Getting started + /* + kinds.push_back(AppKind::HelloTriangle); + kinds.push_back(AppKind::ColorTriangle); + kinds.push_back(AppKind::TexturedTriangle); + kinds.push_back(AppKind::TexturedQuad); + kinds.push_back(AppKind::TransformedQuad); + kinds.push_back(AppKind::HelloPerspective); + kinds.push_back(AppKind::CubePerspective); + kinds.push_back(AppKind::RotatingCubes); + kinds.push_back(AppKind::HelloCamera); + kinds.push_back(AppKind::SimpleMoveCamera); + kinds.push_back(AppKind::LookAroundCamera); + */ + + // Lighting + /* + kinds.push_back(AppKind::LightCube); + kinds.push_back(AppKind::BasicLighting); + kinds.push_back(AppKind::SimpleMaterial); + kinds.push_back(AppKind::LightingMaps); + kinds.push_back(AppKind::DirectionalLightCaster); + kinds.push_back(AppKind::PointLightCaster); + kinds.push_back(AppKind::SpotLightCaster); + kinds.push_back(AppKind::MultipleLights); + */ + + // Model loading + kinds.push_back(AppKind::ModelLoad); + + // In practice + kinds.push_back(AppKind::RenderText); + // Other + kinds.push_back(AppKind::ImguiDemo); + + for (auto kind : kinds) + { + createApp(kind)->run(); + } + } + catch (const std::exception& e) + { + loge("{}", e.what()); + } + return 0; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/RenderApplication.cpp b/Demo/RenderDemo/source/RenderApplication.cpp new file mode 100644 index 0000000..5e77007 --- /dev/null +++ b/Demo/RenderDemo/source/RenderApplication.cpp @@ -0,0 +1,161 @@ +#include "RenderApplication.h" + +#include + +#include + +#include "gfx/PhongColorMaterial.h" + +RenderApplication::RenderApplication() +{ + // Window + m_window = std::make_shared(800, 600, "Render Test"); + m_window->setVSync(true); + m_window->setKeyCallback( + [](Window& w, int key, int scancode, int action, int mods) + { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + { + w.close(); + } + if (key == GLFW_KEY_F1 && action == GLFW_PRESS) + { + w.setCursorCapture(!w.getCursorCapture()); + } + }); + + // Sound + m_soundSystem = std::make_shared("data/sounds/bgm"); + m_soundSystem->getManager()->registerSound("bg", "lofi-chill-medium-version-159456.mp3"); + + m_backgroundSoundEmitter = m_soundSystem->createEmitter(); + m_backgroundSoundEmitter->setLooping(true); + + // Camera + m_camera.setPosition(glm::vec3(0.f, 0.f, 10.f)); + m_camera.setUp(glm::vec3(0.f, 1.f, 0.f)); + + // Shader library + setupPhongColorMaterials(); +} + +RenderApplication::~RenderApplication() +{ + clearTextureCache(); + m_backgroundSoundEmitter = nullptr; + m_soundSystem = nullptr; + m_window = nullptr; +} + +int RenderApplication::run() +{ + // Setup resources + if (!setup()) + return 1; + + std::chrono::high_resolution_clock hpc; + auto start = hpc.now(); + + // Start background sound + if (m_soundSystem->getManager()->hasSound("bg")) + { + auto bgsound = m_soundSystem->getManager()->getSound("bg"); + m_backgroundSoundEmitter->play(bgsound); + } + + while (m_window->isOpen()) + { + // Receive user input + m_window->pollEvents(); + + // Draw scene + render(); + + // Update sounds + m_soundSystem->update(m_dtime); + + // Process user input + processInput(); + + // Swap screen buffers + m_window->swapBuffers(); + + // Time delta + auto end = hpc.now(); + auto diff = std::chrono::duration_cast(end - start); + m_dtime = ((float)diff.count()) / 1000.f; + m_time += m_dtime; + + start = end; + } + return 0; +} + +float RenderApplication::getTimeDelta() const { return m_dtime; } +float RenderApplication::getTimeTotal() const { return m_time; } + +const Window& RenderApplication::getWindow() const { return *m_window; } +const Camera& RenderApplication::getCamera() const { return m_camera; } + +void RenderApplication::setCameraMovementSpeed(float speed) { m_cameraSpeed = speed; } +void RenderApplication::setCameraSensitivitySpeed(float sens) { m_cameraSensitivty = sens; } + +void RenderApplication::processInput() +{ + auto dTime = getTimeDelta(); + // Camera view direction + // Cursor offset + auto offset = getWindow().getCursorMovement(); + const auto sensitivity = 5.0f; + offset *= sensitivity * dTime; + // Prevent losing precision by constraining yaw values + m_cameraYaw = glm::mod(m_cameraYaw + offset.x, 360.f); + m_cameraPitch += offset.y; + + // Camera constraints + if (m_cameraPitch > 89.0f) + m_cameraPitch = 89.0f; + else if (m_cameraPitch < -89.0f) + m_cameraPitch = -89.0f; + + // Calculates front vector + m_camera.setDirection(m_cameraYaw, m_cameraPitch); + + // Forwards, backward + if (getWindow().getKey(GLFW_KEY_W) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() + m_camera.getDirection() * m_cameraSpeed * dTime); + + if (getWindow().getKey(GLFW_KEY_S) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() - m_camera.getDirection() * m_cameraSpeed * dTime); + + // Left, right + if (getWindow().getKey(GLFW_KEY_A) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() - m_camera.getRight() * m_cameraSpeed * dTime); + + if (getWindow().getKey(GLFW_KEY_D) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() + m_camera.getRight() * m_cameraSpeed * dTime); + + // Up / down + if (getWindow().getKey(GLFW_KEY_E) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() + m_camera.getUp() * m_cameraSpeed * dTime); + + if (getWindow().getKey(GLFW_KEY_Q) == GLFW_PRESS) + m_camera.setPosition(m_camera.getPosition() - m_camera.getUp() * m_cameraSpeed * dTime); +} + +void RenderApplication::setupPhongColorMaterials() +{ + // Based on http://devernay.free.fr/cours/opengl/materials.html + float shininessFactor = 128.f; + // + PhongColorMaterial::addMaterial( + "emerald", PhongColorMaterial(glm::vec3(0.0215f, 0.1745f, 0.0215f), glm::vec3(0.07568f, 0.61424f, 0.07568f), + glm::vec3(0.633f, 0.727811f, 0.633f), 0.6f * shininessFactor)); + + PhongColorMaterial::addMaterial( + "gold", PhongColorMaterial(glm::vec3(0.24725f, 0.1995f, 0.0745f), glm::vec3(0.75164f, 0.60648f, 0.22648f), + glm::vec3(0.628281f, 0.555802f, 0.366065), 0.4f * shininessFactor)); + + PhongColorMaterial::addMaterial( + "blackplastic", PhongColorMaterial(glm::vec3(0.f), glm::vec3(0.01f), glm::vec3(0.5f), 0.25f * shininessFactor)); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/RenderApplication.h b/Demo/RenderDemo/source/RenderApplication.h new file mode 100644 index 0000000..659fef8 --- /dev/null +++ b/Demo/RenderDemo/source/RenderApplication.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include + +#include "gfx/Window.h" +#include "gfx/Camera.h" + +/** + * Provides basic rendering context and window creation. + */ +class RenderApplication +{ + public: + RenderApplication(); + virtual ~RenderApplication(); + + int run(); + + protected: + // Delta time in seconds + float getTimeDelta() const; + float getTimeTotal() const; + + const Window& getWindow() const; + const Camera& getCamera() const; + + void setCameraMovementSpeed(float speed); + void setCameraSensitivitySpeed(float sens); + private: + void processInput(); + void setupPhongColorMaterials(); + + std::shared_ptr m_soundSystem; + std::shared_ptr m_window; + std::shared_ptr m_backgroundSoundEmitter; + float m_dtime = 0.f; + float m_time = 0.f; + + // Default camera + Camera m_camera; + float m_cameraSpeed = 1.f; + float m_cameraSensitivty = 2.f; + float m_cameraYaw = -90.f; + float m_cameraPitch = 0.f; + + virtual bool setup() = 0; + virtual void render() = 0; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/BasicLighting.cpp b/Demo/RenderDemo/source/app/BasicLighting.cpp new file mode 100644 index 0000000..16453a7 --- /dev/null +++ b/Demo/RenderDemo/source/app/BasicLighting.cpp @@ -0,0 +1,151 @@ +#include "app/BasicLighting.h" + +#include +#include +#include + +#include "gfx/BasicMeshes.h" + +bool BasicLighting::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; + +out vec3 normal; +out vec3 fragPos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +out vec4 fragColor; + +in vec3 normal; +in vec3 fragPos; + +uniform float ambientStrength; +uniform vec3 objectColor; +uniform vec3 lightColor; +uniform vec3 lightPos; +uniform vec3 viewPos; + +void main(){ + // ambient + vec3 ambient = lightColor * ambientStrength; + + // diffuse + vec3 norm = normalize(normal); + vec3 lightDir = normalize(lightPos - fragPos); + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = diff * lightColor; + + // specular + float specularStrength = 0.5f; + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), 32); + vec3 specular = specularStrength * spec * lightColor; + + // final + vec3 result = (ambient + diffuse + specular) * objectColor; + fragColor = vec4(result, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +void main(){ + fragColor = vec4(1.f); +} + )##"; + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + glCreateBuffers(1, &m_vertexBuffer); + glNamedBufferData(m_vertexBuffer, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glCreateVertexArrays(1, &m_vertexArray); + glBindVertexArray(m_vertexArray); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(5 * sizeof(float))); + + // uv data is ignored + glBindVertexArray(0); + + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void BasicLighting::render() +{ + // Update light movement + m_lightPos.y = std::sin(getTimeTotal() * 0.3f) * 2.f; + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + + glm::vec3 cubePos(0.f); + + // Draw cube model + m_modelShader->setActive(); + m_modelShader->set("ambientStrength", 0.1f); + m_modelShader->set("objectColor", glm::vec3(1.f, 0.5f, 0.31f)); + m_modelShader->set("lightColor", glm::vec3(1.f, 1.f, 1.f)); + m_modelShader->set("lightPos", m_lightPos); + m_modelShader->set("viewPos", getCamera().getPosition()); + + m_modelShader->set("model", glm::translate(cubePos)); + m_modelShader->set("view", getCamera().getView()); + m_modelShader->set("projection", projection); + + glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Draw light model + m_lightShader->setActive(); + m_lightShader->set("model", glm::scale(glm::translate(m_lightPos), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + + // glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); +} + +BasicLighting::~BasicLighting() +{ + glDeleteBuffers(1, &m_vertexBuffer); + glDeleteVertexArrays(1, &m_vertexArray); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/BasicLighting.h b/Demo/RenderDemo/source/app/BasicLighting.h new file mode 100644 index 0000000..0792b13 --- /dev/null +++ b/Demo/RenderDemo/source/app/BasicLighting.h @@ -0,0 +1,22 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Camera.h" +#include "gfx/Shader.h" + +class BasicLighting : public RenderApplication +{ + private: + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + GLuint m_vertexArray = 0; + GLuint m_vertexBuffer = 0; + glm::vec3 m_lightPos= glm::vec3(1.2f, 1.f, 2.f); + + bool setup() override; + + void render() override; + + public: + ~BasicLighting(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ColorTriangle.cpp b/Demo/RenderDemo/source/app/ColorTriangle.cpp new file mode 100644 index 0000000..10d6986 --- /dev/null +++ b/Demo/RenderDemo/source/app/ColorTriangle.cpp @@ -0,0 +1,105 @@ +#include "app/ColorTriangle.h" + +#include + +bool ColorTriangle::setup() +{ + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec2 vertexPosition_normalizedScreenSpace; +layout(location = 1) in vec3 vertexColor; + +out vec3 fragmentColor; + +uniform float xoffset; +uniform float yoffset; + +void main(){ +gl_Position = vec4(vertexPosition_normalizedScreenSpace, 0.f, 1.f); +gl_Position.x += xoffset; +gl_Position.y += yoffset; +fragmentColor = vertexColor; +} + )##"; + + const char* fragmentCode = R"##( +#version 460 core + +in vec3 fragmentColor; +out vec4 color; + +uniform float brightness; + +void main(){ +color = vec4(fragmentColor * brightness, 1.f); +} + )##"; + + // Vertices + // vec2 position + vec3 rgb + const GLfloat vertexData[] = { + -0.5f, -0.5f, 1.f, 0.f, 0.f, + 0.5f, -0.5f, 0.f, 1.f, 0.f, + 0.f, 0.5f, 0.f, 0.f, 1.f + }; + + const GLuint indices[] = { + 0, 1, 2 + }; + + // Create vertex buffer + glCreateBuffers(1, &m_vertexBuffer); + glNamedBufferData(m_vertexBuffer, sizeof(vertexData), vertexData, GL_STATIC_DRAW); + + // Index buffer + glCreateBuffers(1, &m_indexBuffer); + glNamedBufferData(m_indexBuffer, sizeof(indices), indices, GL_STATIC_DRAW); + + // Vertex array object + glGenVertexArrays(1, &m_vertexArray); + glBindVertexArray(m_vertexArray); + + // Setup vertex buffer + glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); + // Vec2, xy positions in normalized device coordinates + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, nullptr); + // Vec3, RGB vertex colors + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(sizeof(GLfloat) * 2)); + // Setup index buffer + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); + + glBindVertexArray(0); + + m_shader = std::make_unique(vertexCode, fragmentCode); + return true; +} + +void ColorTriangle::render() +{ + static float accTime = 0; + accTime += getTimeDelta(); + + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw + m_shader->setActive(); + m_shader->set("brightness", std::abs(std::sin(accTime * 5.f)) / 2.f + 0.5f); + m_shader->set("xoffset", std::sin(accTime) / 2.f); + m_shader->set("yoffset", std::cos(accTime) / 2.f); + + glBindVertexArray(m_vertexArray); + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); +} + +ColorTriangle::~ColorTriangle() +{ + glDeleteVertexArrays(1, &m_vertexArray); + glDeleteBuffers(1, &m_vertexBuffer); + glDeleteBuffers(1, &m_indexBuffer); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ColorTriangle.h b/Demo/RenderDemo/source/app/ColorTriangle.h new file mode 100644 index 0000000..90d4f87 --- /dev/null +++ b/Demo/RenderDemo/source/app/ColorTriangle.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "RenderApplication.h" +#include "gfx/Shader.h" + +/** + * Display 2 colored triangles + */ +class ColorTriangle : public RenderApplication +{ + private: + std::unique_ptr m_shader; + GLuint m_vertexArray = 0; + GLuint m_vertexBuffer = 0; + GLuint m_indexBuffer = 0; + + bool setup() override; + + void render() override; + + public: + ~ColorTriangle(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/CubePerspective.cpp b/Demo/RenderDemo/source/app/CubePerspective.cpp new file mode 100644 index 0000000..44f52d5 --- /dev/null +++ b/Demo/RenderDemo/source/app/CubePerspective.cpp @@ -0,0 +1,136 @@ +#include "app/CubePerspective.h" +#include "gfx/BasicMeshes.h" + +#include + +bool CubePerspective::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec3 vp_ms; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ +texCoord = uv; +// Matrix multiplication is read left to right +gl_Position = projection * view * model * vec4(vp_ms, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; +uniform sampler2D blendTex; +uniform float mixRatio; + +void main() +{ +color = mix( + texture(baseTex, texCoord), + texture(blendTex, texCoord), + clamp(mixRatio, 0.2, 0.8)); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Texture + texContainer.id = textureIdFromFile("wall.jpg", "data/texture/"); + // texAwesome.id = textureIdFromFile("awesomeface.png", "data/texture/"); + texAwesome.id = textureIdFromFile("container.jpg", "data/texture/"); + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // vertices x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + + // texcoords u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(sizeof(GLfloat) * 3)); + + // normals x/y/z ignored + glBindVertexArray(0); + + // Set render state + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glEnable(GL_DEPTH_TEST); + + return true; +} + +void CubePerspective::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Model matrix + glm::mat4 model{1.f}; + // Rotation + model = glm::rotate(model, glm::radians(timeAcc * 100.f), {1.f, 0.3f, 0.7f}); + + // View matrix + glm::mat4 view{1.f}; + view = glm::translate(view, {0.f, 0.f, -3.f}); + + // Projection + auto aspectRatio = (float)getWindow().getWidth() / (float)getWindow().getHeight(); + glm::mat4 projection = glm::perspective(glm::radians(45.f), aspectRatio, 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Use shader + shader->setActive(); + + // Transformation data for shader + shader->set("model", model); + shader->set("view", view); + shader->set("projection", projection); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + // Blend texture + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texAwesome.id); + shader->set("blendTex", 1); + + // Mix ratio + shader->set("mixRatio", (std::sin(timeAcc * 3) + 1.f) / 2.f); + + glBindVertexArray(vao); + auto vertexCount = sizeof(cubeVertices) / sizeof(GLfloat) / 8; + glDrawArrays(GL_TRIANGLES, 0, static_cast(vertexCount)); + glBindVertexArray(0); +} + +CubePerspective::~CubePerspective() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/CubePerspective.h b/Demo/RenderDemo/source/app/CubePerspective.h new file mode 100644 index 0000000..e6e2f0e --- /dev/null +++ b/Demo/RenderDemo/source/app/CubePerspective.h @@ -0,0 +1,25 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +/** + * Display cube with perspective camera + */ +class CubePerspective : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Texture texAwesome; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~CubePerspective(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/DirectionalLightCaster.cpp b/Demo/RenderDemo/source/app/DirectionalLightCaster.cpp new file mode 100644 index 0000000..3b11749 --- /dev/null +++ b/Demo/RenderDemo/source/app/DirectionalLightCaster.cpp @@ -0,0 +1,241 @@ +#include "app/DirectionalLightCaster.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool DirectionalLightCaster::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoords; + +out vec3 normal; +out vec3 fragPos; +out vec2 texCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +struct Light +{ + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +out vec4 fragColor; + +in vec2 texCoords; +in vec3 normal; +in vec3 fragPos; + +uniform Material material; +uniform Light light; +uniform vec3 viewPos; + +void main() { + // Textures + vec3 diffuseTex = vec3(texture(material.diffuse, texCoords)); + vec3 specularTex = vec3(texture(material.specular, texCoords)); + + // ambient + vec3 ambient = light.ambient * diffuseTex; + + // diffuse + vec3 norm = normalize(normal); + // Direction vector from fragment to light source + vec3 lightDir = normalize(-light.direction); + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = diff * diffuseTex * light.diffuse; + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + vec3 specular = spec * specularTex * light.specular; + + // final + vec3 result = ambient + diffuse + specular; + fragColor = vec4(result, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + // Shaders + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Mesh + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), + std::vector{3, 2, 3}); + + glBindVertexArray(m_vao.getId()); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + auto attr = m_vertexBuffer->getAttributes(); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // Location 2, uv data + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, attr.at(1).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(1).offset); + + glBindVertexArray(0); + + // Textures + m_diffuse = textureFromFile("container2.png", "data/texture/", "diffuse"); + m_specular = textureFromFile("container2_specular.png", "data/texture/", "specular"); + + // Light + m_directionalLight.direction = glm::vec3(-0.2f, -1.f, -0.3f); + m_directionalLight.ambient = m_lightColor * 0.05f; + m_directionalLight.diffuse = m_lightColor * 0.5f; + m_directionalLight.specular = m_lightColor; + + // Models + m_cubePositions.push_back(glm::vec3{0.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 0.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 2.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, -2.f}); + + // Initial state setup + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void DirectionalLightCaster::render() +{ + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Update light movement and color + m_lightPos.y = std::sin(getTimeTotal() * 0.3f) * 2.f; + m_lightColor.x = std::abs(std::sin(getTimeTotal() * 2.f)); + m_lightColor.y = std::abs(std::sin(getTimeTotal() * 0.7f)); + m_lightColor.z = std::abs(std::sin(getTimeTotal() * 1.3f)); + + // Draw cube model + m_modelShader->setActive(); + + // Material + m_modelShader->setTexture("material.diffuse", *m_diffuse, 0); + m_modelShader->setTexture("material.specular", *m_specular, 1); + m_modelShader->set("material.shininess", 64.f); + + // Light + m_directionalLight.set(*m_modelShader, "light"); + + // Camera + m_modelShader->set("viewPos", getCamera().getPosition()); + m_modelShader->set("view", getCamera().getView()); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + m_modelShader->set("projection", projection); + + // Draw models + glBindVertexArray(m_vao.getId()); + for (int i = 0; i < m_cubePositions.size(); ++i) + { + glm::mat4 model{1.f}; + model = glm::translate(model, m_cubePositions.at(i)); + // Angle in degree + float angle = 15.f * i; + model = glm::rotate(model, glm::radians(angle), glm::vec3(1.f, 0.3f, 0.5f)); + m_modelShader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + // Draw light model + /* + m_lightShader->setActive(); + + m_lightShader->set("color", m_lightColor); + m_lightShader->set("model", glm::scale(glm::translate(m_lightPos), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + + // glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + */ + + glBindVertexArray(0); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/DirectionalLightCaster.h b/Demo/RenderDemo/source/app/DirectionalLightCaster.h new file mode 100644 index 0000000..1d764e9 --- /dev/null +++ b/Demo/RenderDemo/source/app/DirectionalLightCaster.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/VertexBuffer.h" +#include "gfx/DirectionalLight.h" +#include "gfx/VertexArrayObject.h" + +class DirectionalLightCaster : public RenderApplication +{ + public: + ~DirectionalLightCaster() = default; + + private: + bool setup() override; + void render() override; + + std::vector m_cubePositions; + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + std::unique_ptr m_vertexBuffer; + std::shared_ptr m_diffuse; + std::shared_ptr m_specular; + VertexArrayObject m_vao; + + DirectionalLight m_directionalLight; + + glm::vec3 m_lightPos = glm::vec3(1.2f, 1.f, 2.f); + glm::vec3 m_lightColor = glm::vec3(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloCamera.cpp b/Demo/RenderDemo/source/app/HelloCamera.cpp new file mode 100644 index 0000000..3e53c0e --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloCamera.cpp @@ -0,0 +1,135 @@ +#include "app/HelloCamera.h" +#include "gfx/BasicMeshes.h" + +#include + +bool HelloCamera::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec3 vp_ms; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + texCoord = uv; + // Matrix multiplication is read left to right + gl_Position = projection * view * model * vec4(vp_ms, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; + +void main() +{ + color = texture(baseTex, texCoord); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Camera + camera.setPosition({0.f, 0.f, 5.f}); + camera.setDirection({0.f, 0.f, -1.f}); + camera.setUp({0.f, 1.f, 0.f}); + + // Texture + texContainer.id = textureIdFromFile("container.jpg", "data/texture/"); + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(sizeof(GLfloat) * 3)); + + glBindVertexArray(0); + + // Set render state + + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glEnable(GL_DEPTH_TEST); + + return true; +} + +void HelloCamera::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Camera movement, circle around 0/0/0 on x/z plane + const float radius = 10.f; + float camX = std::sin(timeAcc) * radius; + float camZ = std::cos(timeAcc) * radius; + camera.setPosition({camX, 0.f, camZ}); + camera.setLookAt(glm::vec3(3.f, 0.f, 0.f)); + + // Projection + auto aspectRatio = (float)getWindow().getWidth() / (float)getWindow().getHeight(); + glm::mat4 projection = glm::perspective(glm::radians(45.f), aspectRatio, 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArray(vao); + // Use shader + shader->setActive(); + shader->set("view", camera.getView()); + shader->set("projection", projection); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + glm::vec3 positions[] = {{0.f, 0.f, 0.f}, {2.f, 0.f, 0.f}, {0.f, -2.f, 0.f}, + {0.f, 2.f, -2.f}, {0.f, 0.f, 2.f}, {3.f, -3.f, 2.f}}; + + auto vertexCount = sizeof(cubeVertices) / sizeof(GLfloat) / 8; + + // Draw cubes + for (const auto position : positions) + { + // Model matrix + glm::mat4 model{1.f}; + model = glm::translate(model, position); + model = glm::rotate(model, glm::radians(timeAcc * (50.f)), {1.f, 0.3f, 0.7f}); + + // Transformation data for shader + shader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, static_cast(vertexCount)); + } + glBindVertexArray(0); +} + +HelloCamera::~HelloCamera() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloCamera.h b/Demo/RenderDemo/source/app/HelloCamera.h new file mode 100644 index 0000000..e8addf1 --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloCamera.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Camera.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class HelloCamera : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Camera camera; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~HelloCamera(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloPerspective.cpp b/Demo/RenderDemo/source/app/HelloPerspective.cpp new file mode 100644 index 0000000..8f53183 --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloPerspective.cpp @@ -0,0 +1,131 @@ +#include "app/HelloPerspective.h" + +#include + +bool HelloPerspective::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec2 vp_ndc; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ +texCoord = uv; + // Matrix multiplication is read left to right + gl_Position = projection * view * model * vec4(vp_ndc, 0.f, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; +uniform sampler2D blendTex; + +void main() +{ + color = mix(texture(baseTex, texCoord), texture(blendTex, texCoord), 0.5f); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Texture + texBase.id = textureIdFromFile("container.jpg", "data/texture/"); + texBlend.id = textureIdFromFile("awesomeface.png", "data/texture/"); + + // Vertex data, x/y, v/v + const GLfloat vertexData[] = {// First triangle, upper right, upper left, lower left + 0.5f, 0.5f, 1.f, 1.f, -0.5f, 0.5f, 0.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, + // Second triangle, upper right, lower left, lower right + 0.5f, 0.5f, 1.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, 0.5f, -0.5f, 1.f, 0.f}; + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(vertexData), vertexData, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2)); + + glBindVertexArray(0); + + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + + return true; +} + +void HelloPerspective::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Model matrix + glm::mat4 model{1.f}; + // Rotation on x axis + model = glm::rotate(model, glm::radians(-55.f), {1.f, 0.f, 0.f}); + + // View matrix + glm::mat4 view{1.f}; + view = glm::translate(view, {0.f, 0.f, -3.f}); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use shader + shader->setActive(); + + // Transformation data for shader + shader->set("model", model); + shader->set("view", view); + shader->set("projection", projection); + + // Textures + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texBase.id); + // Set texture location manually + shader->set("baseTex", 0); + + + // Activate the binding location + glActiveTexture(GL_TEXTURE1); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texBlend.id); + // Set texture location manually + shader->set("blendTex", 1); + + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); +} + +HelloPerspective::~HelloPerspective() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloPerspective.h b/Demo/RenderDemo/source/app/HelloPerspective.h new file mode 100644 index 0000000..e684430 --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloPerspective.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class HelloPerspective : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texBase; + Texture texBlend; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~HelloPerspective(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloTriangle.cpp b/Demo/RenderDemo/source/app/HelloTriangle.cpp new file mode 100644 index 0000000..8eca31b --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloTriangle.cpp @@ -0,0 +1,72 @@ +#include "app/HelloTriangle.h" + +#include + +bool HelloTriangle::setup() +{ + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec2 vpos_ndc; + +void main(){ + gl_Position = vec4(vpos_ndc, 0.f, 1.f); +} + )##"; + + const char* fragmentCode = R"##( +#version 460 core + +uniform vec3 base_color; +out vec3 color; + +void main(){ + color = base_color; +} + )##"; + + // Vertices + const std::vector vertices{{-0.5f, -0.5f}, {0.5f, -0.5f}, {0.f, 0.5f}}; + + // Create vertex buffer + std::vector components{2}; + m_vertexBuffer = std::make_unique((const float*)vertices.data(), vertices.size() * 2, components); + //glCreateBuffers(1, &vertexBuffer); + //glNamedBufferData(vertexBuffer, vertices.size() * sizeof(float) * 2, (float*)vertices.data(), GL_STATIC_DRAW); + + // Vertex array object + glGenVertexArrays(1, &vertexArray); + glBindVertexArray(vertexArray); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Vec2, xy positions in normalized device coordinates + glEnableVertexAttribArray(0); + auto attribute = m_vertexBuffer->getAttributes().at(0); + glVertexAttribPointer(0, attribute.componentCount, m_vertexBuffer->getType(), GL_FALSE, m_vertexBuffer->getStride(), (void*)attribute.offset); + glBindVertexArray(0); + + m_shader = std::make_unique(vertexCode, fragmentCode); + + // Global state + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + + return true; +} + +void HelloTriangle::render() +{ + // Clear color buffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Draw + glBindVertexArray(vertexArray); + + m_shader->setActive(); + m_shader->set("base_color", {1.f, 0.f, 0.f}); + + glDrawArrays(GL_TRIANGLES, 0, m_vertexBuffer->getEntryCount()); + glBindVertexArray(0); +} + +HelloTriangle::~HelloTriangle() { glDeleteVertexArrays(1, &vertexArray); } \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/HelloTriangle.h b/Demo/RenderDemo/source/app/HelloTriangle.h new file mode 100644 index 0000000..1d49a9e --- /dev/null +++ b/Demo/RenderDemo/source/app/HelloTriangle.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/VertexBuffer.h" + +// Displays 2 triangles +class HelloTriangle : public RenderApplication +{ + private: + std::unique_ptr m_shader; + std::unique_ptr m_vertexBuffer; + GLuint vertexBuffer = 0; + GLuint vertexArray = 0; + + bool setup() override; + + void render() override; + + public: + ~HelloTriangle(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ImguiDemo.cpp b/Demo/RenderDemo/source/app/ImguiDemo.cpp new file mode 100644 index 0000000..3ccc2dd --- /dev/null +++ b/Demo/RenderDemo/source/app/ImguiDemo.cpp @@ -0,0 +1,70 @@ +#include "app/ImguiDemo.h" + +// Imgui +#include + +#include "imgui/imgui_impl_glfw.h" +#include "imgui/imgui_impl_opengl3.h" + +bool ImguiDemo::setup() +{ + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + // io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + // ImGui::StyleColorsClassic(); + + // Setup Platform/Renderer bindings + ImGui_ImplGlfw_InitForOpenGL(getWindow().getGLFWWindow(), true); + ImGui_ImplOpenGL3_Init("#version 460"); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use + // ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application + // (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling + // ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double + // backslash \\ ! + // io.Fonts->AddFontDefault(); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + // io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + // ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, + // io.Fonts->GetGlyphRangesJapanese()); IM_ASSERT(font != NULL); + return true; +} + +void ImguiDemo::render() +{ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + ImGui::ShowDemoWindow(); + + ImGui::Render(); + + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); +} + +ImguiDemo::~ImguiDemo() +{ + // Imgui cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ImguiDemo.h b/Demo/RenderDemo/source/app/ImguiDemo.h new file mode 100644 index 0000000..e036269 --- /dev/null +++ b/Demo/RenderDemo/source/app/ImguiDemo.h @@ -0,0 +1,15 @@ +#pragma once + +#include "RenderApplication.h" + +// Displays 2 triangles +class ImguiDemo : public RenderApplication +{ + private: + bool setup() override; + + void render() override; + + public: + ~ImguiDemo(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LightCube.cpp b/Demo/RenderDemo/source/app/LightCube.cpp new file mode 100644 index 0000000..6cf20fe --- /dev/null +++ b/Demo/RenderDemo/source/app/LightCube.cpp @@ -0,0 +1,114 @@ +#include "app/LightCube.h" + +#include "gfx/BasicMeshes.h" +#include +#include + +bool LightCube::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 objectColor; +uniform vec3 lightColor; + +void main(){ + fragColor = vec4(objectColor * lightColor, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +void main(){ + fragColor = vec4(1.f); +} + )##"; + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Camera setup + m_camera.setPosition(glm::vec3(2.f, 0.f, 5.f)); + m_camera.setUp(glm::vec3(0.f, 1.f, 0.f)); + m_camera.setLookAt(glm::vec3(0.f)); + + glCreateBuffers(1, &m_vertexBuffer); + glNamedBufferData(m_vertexBuffer, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glCreateVertexArrays(1, &m_vertexArray); + glBindVertexArray(m_vertexArray); + glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); + + // Buffer has x/y/z/u/v/x/y/u + // Location 0, vertex data x/y/z + // uv and normal data is ignored + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + + // Rest gets ignored + glBindVertexArray(0); + + glClearColor(0.f, 0.f, 0.f, 1.f); + + return true; +} + +void LightCube::render() +{ + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.1f, 100.f); + + glm::vec3 cubePos(0.f); + glm::vec3 lightPos(1.2f, 1.f, 1.f); + + // Draw cube model + m_modelShader->setActive(); + m_modelShader->set("objectColor", glm::vec3(1.f, 0.5f, 0.31f)); + m_modelShader->set("lightColor", glm::vec3(1.f, 1.f, 1.f)); + + m_modelShader->set("model", glm::translate(cubePos)); + m_modelShader->set("view", m_camera.getView()); + m_modelShader->set("projection", projection); + + glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Draw light model + m_lightShader->setActive(); + m_lightShader->set("model", glm::scale(glm::translate(lightPos), glm::vec3(0.2f))); + m_lightShader->set("view", m_camera.getView()); + m_lightShader->set("projection", projection); + + // glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); +} + +LightCube::~LightCube() +{ + glDeleteBuffers(1, &m_vertexBuffer); + glDeleteVertexArrays(1, &m_vertexArray); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LightCube.h b/Demo/RenderDemo/source/app/LightCube.h new file mode 100644 index 0000000..7569042 --- /dev/null +++ b/Demo/RenderDemo/source/app/LightCube.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Camera.h" + +// Draws a cube light +class LightCube : public RenderApplication +{ + private: + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + GLuint m_vertexArray = 0; + GLuint m_vertexBuffer = 0; + Camera m_camera; + + bool setup() override; + + void render() override; + + public: + ~LightCube(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LightingMaps.cpp b/Demo/RenderDemo/source/app/LightingMaps.cpp new file mode 100644 index 0000000..7dd9a91 --- /dev/null +++ b/Demo/RenderDemo/source/app/LightingMaps.cpp @@ -0,0 +1,214 @@ +#include "app/LightingMaps.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool LightingMaps::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoords; + +out vec3 normal; +out vec3 fragPos; +out vec2 texCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + sampler2D emissive; + float shininess; + float glow; +}; + +struct Light +{ + vec3 position; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +out vec4 fragColor; + +in vec2 texCoords; +in vec3 normal; +in vec3 fragPos; + +uniform Material material; +uniform Light light; +uniform vec3 viewPos; + +void main() { + // Textures + vec3 diffuseTex = vec3(texture(material.diffuse, texCoords)); + vec3 specularTex = vec3(texture(material.specular, texCoords)); + vec3 emissiveTex = vec3(texture(material.emissive, texCoords)); + + // ambient + vec3 ambient = light.ambient * diffuseTex; + + // diffuse + vec3 norm = normalize(normal); + vec3 lightDir = normalize(light.position - fragPos); + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = diff * diffuseTex * light.diffuse; + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + vec3 specular = spec * specularTex * light.specular; + + // Emission + vec3 emission = emissiveTex * material.glow; + + // final + vec3 result = ambient + diffuse + specular + emission; + fragColor = vec4(result, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + // Shaders + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Mesh + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), + std::vector{3, 2, 3}); + + glCreateVertexArrays(1, &m_vertexArray); + glBindVertexArray(m_vertexArray); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + auto attr = m_vertexBuffer->getAttributes(); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // Location 2, uv data + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, attr.at(1).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(1).offset); + + glBindVertexArray(0); + + // Textures + m_diffuse = textureFromFile("container2.png", "data/texture/", "diffuse"); + m_specular = textureFromFile("container2_specular.png", "data/texture/", "specular"); + m_emission = textureFromFile("matrix.jpg", "data/texture/", "emission"); + + // Initial state setup + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void LightingMaps::render() +{ + // Update light movement and color + m_lightPos.y = std::sin(getTimeTotal() * 0.3f) * 2.f; + m_lightColor.x = std::abs(std::sin(getTimeTotal() * 2.f)); + m_lightColor.y = std::abs(std::sin(getTimeTotal() * 0.7f)); + m_lightColor.z = std::abs(std::sin(getTimeTotal() * 1.3f)); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + + glm::vec3 cubePos(0.f); + + // Draw cube model + m_modelShader->setActive(); + + // Material + m_modelShader->setTexture("material.diffuse", *m_diffuse, 0); + m_modelShader->setTexture("material.specular", *m_specular, 1); + m_modelShader->setTexture("material.emissive", *m_emission, 2); + m_modelShader->set("material.shininess", 64.f); + m_modelShader->set("material.glow", (1.f + std::sin(getTimeTotal())) / 2.f); + + // Light + m_modelShader->set("light.ambient", m_lightColor * 0.05f); + m_modelShader->set("light.diffuse", m_lightColor * 0.5f); + m_modelShader->set("light.specular", m_lightColor); + m_modelShader->set("light.position", m_lightPos); + + m_modelShader->set("viewPos", getCamera().getPosition()); + + m_modelShader->set("model", glm::translate(cubePos)); + m_modelShader->set("view", getCamera().getView()); + m_modelShader->set("projection", projection); + + glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Draw light model + m_lightShader->setActive(); + + m_lightShader->set("color", m_lightColor); + m_lightShader->set("model", glm::scale(glm::translate(m_lightPos), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + + // glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); +} + +LightingMaps::~LightingMaps() { + glDeleteVertexArrays(1, &m_vertexArray); + m_diffuse = nullptr; + m_emission = nullptr; + m_specular = nullptr; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LightingMaps.h b/Demo/RenderDemo/source/app/LightingMaps.h new file mode 100644 index 0000000..c280582 --- /dev/null +++ b/Demo/RenderDemo/source/app/LightingMaps.h @@ -0,0 +1,26 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/VertexBuffer.h" + +class LightingMaps : public RenderApplication +{ + public: + ~LightingMaps(); + + private: + bool setup() override; + void render() override; + + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + std::unique_ptr m_vertexBuffer; + std::shared_ptr m_diffuse; + std::shared_ptr m_specular; + std::shared_ptr m_emission; + + GLuint m_vertexArray = 0; + glm::vec3 m_lightPos = glm::vec3(1.2f, 1.f, 2.f); + glm::vec3 m_lightColor = glm::vec3(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LookAroundCamera.cpp b/Demo/RenderDemo/source/app/LookAroundCamera.cpp new file mode 100644 index 0000000..a938e45 --- /dev/null +++ b/Demo/RenderDemo/source/app/LookAroundCamera.cpp @@ -0,0 +1,171 @@ +#include "app/LookAroundCamera.h" +#include "gfx/BasicMeshes.h" + +#include + +bool LookAroundCamera::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec3 vp_ms; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + texCoord = uv; + // Matrix multiplication is read left to right + gl_Position = projection * view * model * vec4(vp_ms, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; + +void main() +{ + color = texture(baseTex, texCoord); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Camera + glm::vec3 position{0.f, 0.f, 5.f}; + camera.setPosition({0.f, 0.f, 5.f}); + camera.setDirection({0.f, 0.f, -1.f}); + camera.setUp({0.f, 1.f, 0.f}); + + // Texture + texContainer.id = textureIdFromFile("container.jpg", "data/texture/"); + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(sizeof(GLfloat) * 3)); + + glBindVertexArray(0); + + // Set render state + + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glEnable(GL_DEPTH_TEST); + + return true; +} + +void LookAroundCamera::render() +{ + // Camera view direction + // Cursor offset + auto offset = getWindow().getCursorMovement(); + const auto sensitivity = 2.0f; + offset *= sensitivity * getTimeDelta(); + // Prevent losing precision by constraining yaw values + yaw = glm::mod(yaw + offset.x, 360.f); + pitch += offset.y; + + // Camera constraints + if (pitch > 89.0f) + pitch = 89.0f; + else if (pitch < -89.0f) + pitch = -89.0f; + + // Calculates front vector + camera.setDirection(yaw, pitch); + + // Process input for camera movement + auto direction = camera.getDirection(); + float cameraSpeed = 2.f * getTimeDelta(); + glm::vec3 position = camera.getPosition(); + glm::vec3 right = camera.getRight(); + + // Forwards, backward + if (getWindow().getKey(GLFW_KEY_W) == GLFW_PRESS) + position += direction * cameraSpeed; + if (getWindow().getKey(GLFW_KEY_S) == GLFW_PRESS) + position -= direction * cameraSpeed; + // Left, right + if (getWindow().getKey(GLFW_KEY_A) == GLFW_PRESS) + position -= right * cameraSpeed; + if (getWindow().getKey(GLFW_KEY_D) == GLFW_PRESS) + position += right * cameraSpeed; + + camera.setPosition(position); + + // Zoom effect + // Scrolling y direction changes fov + fov -= getWindow().getScrollOffset().y; + // Constraints + if (fov > 60.f) + fov = 60.f; + else if (fov < 1.f) + fov = 1.f; + + // Projection + auto aspectRatio = (float)getWindow().getWidth() / (float)getWindow().getHeight(); + glm::mat4 projection = glm::perspective(glm::radians(fov), aspectRatio, 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArray(vao); + // Use shader + shader->setActive(); + shader->set("view", camera.getView()); + shader->set("projection", projection); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + glm::vec3 positions[] = {{0.f, 0.f, 0.f}, {2.f, 0.f, 0.f}, {0.f, -2.f, 0.f}, + {0.f, 2.f, -2.f}, {0.f, 0.f, 2.f}, {3.f, -3.f, 2.f}}; + + auto vertexCount = sizeof(cubeVertices) / sizeof(GLfloat) / 8; + + // Draw cubes + for (const auto position : positions) + { + // Model matrix + glm::mat4 model{1.f}; + model = glm::translate(model, position); + + // Transformation data for shader + shader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, static_cast(vertexCount)); + } + glBindVertexArray(0); +} + +LookAroundCamera::~LookAroundCamera() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/LookAroundCamera.h b/Demo/RenderDemo/source/app/LookAroundCamera.h new file mode 100644 index 0000000..557cb2c --- /dev/null +++ b/Demo/RenderDemo/source/app/LookAroundCamera.h @@ -0,0 +1,35 @@ +#pragma once + +#include "gfx/Camera.h" +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +/** + * Mouse controlled camera that can look around + */ +class LookAroundCamera : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Camera camera; + // Camera view direction + // Left / right rotation + float yaw = -90.f; + // Up / down rotation + float pitch = 0.f; + + // Field of view + float fov = 45.f; + + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~LookAroundCamera(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ModelLoad.cpp b/Demo/RenderDemo/source/app/ModelLoad.cpp new file mode 100644 index 0000000..6196b5f --- /dev/null +++ b/Demo/RenderDemo/source/app/ModelLoad.cpp @@ -0,0 +1,74 @@ +#include "app/ModelLoad.h" + +#include +#include + +#include "gfx/BasicMeshes.h" + +bool ModelLoad::setup() +{ + const char* vertexCode = R"##( +#version 460 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; + +out vec2 TexCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + TexCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + const char* fragmentCode = R"##( +#version 460 core +out vec4 FragColor; + +in vec2 TexCoords; + +uniform sampler2D texture_diffuse; +//uniform sampler2D texture_specular; + +void main() +{ + FragColor = texture(texture_diffuse, TexCoords); +} + )##"; + + models.push_back(Model{"data/backpack/backpack.obj"}); + shader = std::make_unique(vertexCode, fragmentCode); + + glClearColor(0.9f, 0.9f, 0.9f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void ModelLoad::render() +{ + // Clear color buffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + shader->setActive(); + + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); + model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f)); + shader->set("model", model); + + glm::mat4 view = getCamera().getView(); + shader->set("view", view); + + glm::mat4 projection = getWindow().getProjection(45.f, 0.1f, 100.f); + shader->set("projection", projection); + + for (const auto& m : models) + { + m.draw(*shader); + } +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/ModelLoad.h b/Demo/RenderDemo/source/app/ModelLoad.h new file mode 100644 index 0000000..6558eef --- /dev/null +++ b/Demo/RenderDemo/source/app/ModelLoad.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +#include "RenderApplication.h" +#include "gfx/Model.h" +#include "gfx/Shader.h" + +// Displays 2 triangles +class ModelLoad : public RenderApplication +{ + private: + std::vector models; + std::unique_ptr shader; + std::unique_ptr m_mesh; + + bool setup() override; + + void render() override; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/MultipleLights.cpp b/Demo/RenderDemo/source/app/MultipleLights.cpp new file mode 100644 index 0000000..30e632d --- /dev/null +++ b/Demo/RenderDemo/source/app/MultipleLights.cpp @@ -0,0 +1,367 @@ +#include "app/MultipleLights.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool MultipleLights::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoords; + +out vec3 normal; +out vec3 fragPos; +out vec2 texCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +// Spot light +struct SpotLight +{ + vec3 position; + vec3 direction; + float innerCutOff; + float outerCutOff; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; + +struct DirectionalLight +{ + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct PointLight +{ + vec3 position; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; + +out vec3 fragColor; + +in vec2 texCoords; +in vec3 normal; +in vec3 fragPos; + +uniform Material material; + +uniform DirectionalLight dirLight; +#define NR_POINT_LIGHTS 4 +uniform PointLight pointLights[NR_POINT_LIGHTS]; +uniform SpotLight spotLight; + +uniform vec3 viewPos; + +vec3 calculateDirectionalLight(DirectionalLight light, vec3 norm, vec3 viewDir) +{ + vec3 lightDir = normalize(-light.direction); + + // Diffuse + float diff = max(dot(norm, lightDir), 0.f); + + // Specular + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + + // Combine + vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, texCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, texCoords)); + + return ambient + diffuse + specular; +} + +vec3 calculatePointLight(PointLight light, vec3 norm, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + + // Diffuse + float diff = max(dot(norm, lightDir), 0.f); + + // Specular + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); + + // Combine + vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoords)) * attenuation; + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, texCoords)) * attenuation; + vec3 specular = light.specular * spec * vec3(texture(material.specular, texCoords)) * attenuation; + + return ambient + diffuse + specular; +} + +vec3 calculateSpotLight(SpotLight light, vec3 norm, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + float theta = dot(lightDir, normalize(-light.direction)); + + if (theta > light.outerCutOff) + { + // Inside outer light cone, do normal light calculation + float epsilon = light.innerCutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.f, 1.f); + + // diffuse + float diff = max(dot(normal, lightDir), 0.f); + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); + + // combine + vec3 ambient = light.ambient * vec3(texture(material.diffuse, texCoords)) * attenuation * intensity; + vec3 diffuse = diff * vec3(texture(material.diffuse, texCoords)) * light.diffuse * attenuation * intensity; + vec3 specular = spec * vec3(texture(material.specular, texCoords)) * light.specular * attenuation * intensity; + + return ambient + diffuse + specular; + } + return vec3(0.f); +} + +void main() +{ + vec3 norm = normalize(normal); + vec3 viewDir =normalize(viewPos - fragPos); + + // Directional light + vec3 result = calculateDirectionalLight(dirLight, norm, viewDir); + // Point lights + for (int i = 0; i < NR_POINT_LIGHTS; ++i) + { + result += calculatePointLight(pointLights[i], norm, fragPos, viewDir); + } + + // Spot Light + result += calculateSpotLight(spotLight, norm, fragPos, viewDir); + + fragColor = result; +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + // Shaders + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Mesh + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), + std::vector{3, 2, 3}); + + glBindVertexArray(m_vao.getId()); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + auto attr = m_vertexBuffer->getAttributes(); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // Location 2, uv data + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, attr.at(1).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(1).offset); + + glBindVertexArray(0); + + // Textures + m_diffuse = textureFromFile("container2.png", "data/texture/", "diffuse"); + m_specular = textureFromFile("container2_specular.png", "data/texture/", "specular"); + + // Light + m_dirLight.ambient = glm::vec3(0.1); + m_dirLight.diffuse = glm::vec3(0.3); + m_dirLight.specular = glm::vec3(0.9); + m_dirLight.direction = glm::vec3(0.3f, -1.f, -0.1f); + + glm::vec3 positions[4] = { + glm::vec3(0.7f, 0.2f, 2.f), + glm::vec3(2.3f, -3.3f, -4.f), + glm::vec3(-4.f, 2.f, -12.f), + glm::vec3(0.f, 0.f, -3.f), + }; + + for (int i = 0; i < 4; ++i) + { + m_pointLights[i].ambient = glm::vec3(0.01); + m_pointLights[i].diffuse = glm::vec3(0.2); + m_pointLights[i].specular = glm::vec3(0.7); + m_pointLights[i].position = positions[i]; + } + + m_spotLight.ambient = glm::vec3(0.01f); + m_spotLight.diffuse = glm::vec3(0.4f); + m_spotLight.specular = glm::vec3(1.f); + m_spotLight.position = getCamera().getPosition(); + m_spotLight.direction = getCamera().getDirection(); + + // Models + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 0.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 2.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, -2.f}); + + // Initial state setup + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void MultipleLights::render() +{ + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Draw cube model + m_modelShader->setActive(); + + // Material + m_modelShader->setTexture("material.diffuse", *m_diffuse, 0); + m_modelShader->setTexture("material.specular", *m_specular, 1); + m_modelShader->set("material.shininess", 64.f); + + // Lights + // Update + m_spotLight.position = getCamera().getPosition(); + m_spotLight.direction = getCamera().getDirection(); + + m_dirLight.set(*m_modelShader, "dirLight"); + for (int i = 0; i < 4; ++i) + { + m_pointLights[i].set(*m_modelShader, "pointLights[" + std::to_string(i) + "]"); + } + m_spotLight.set(*m_modelShader, "spotLight"); + + // Camera + m_modelShader->set("viewPos", getCamera().getPosition()); + m_modelShader->set("view", getCamera().getView()); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + m_modelShader->set("projection", projection); + + // Cube vao + glBindVertexArray(m_vao.getId()); + + // Draw models + for (int i = 0; i < m_cubePositions.size(); ++i) + { + glm::mat4 model{1.f}; + model = glm::translate(model, m_cubePositions.at(i)); + // Angle in degree + float angle = 15.f * i; + model = glm::rotate(model, glm::radians(angle), glm::vec3(1.f, 0.3f, 0.5f)); + m_modelShader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + // Draw lights as small white cubes + m_lightShader->setActive(); + for (int i = 0; i < 4; ++i) + { + m_lightShader->set("color", glm::vec3(1.f)); + m_lightShader->set("model", glm::scale(glm::translate(m_pointLights[i].position), glm::vec3(0.25f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + glBindVertexArray(0); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/MultipleLights.h b/Demo/RenderDemo/source/app/MultipleLights.h new file mode 100644 index 0000000..e6302df --- /dev/null +++ b/Demo/RenderDemo/source/app/MultipleLights.h @@ -0,0 +1,38 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/DirectionalLight.h" +#include "gfx/PointLight.h" +#include "gfx/SpotLight.h" +#include "gfx/Shader.h" +#include "gfx/VertexArrayObject.h" +#include "gfx/VertexBuffer.h" + +class MultipleLights : public RenderApplication +{ + public: + ~MultipleLights() = default; + + private: + bool setup() override; + void render() override; + + // Scene data + // Lights + DirectionalLight m_dirLight; + SpotLight m_spotLight; + PointLight m_pointLights[4]; + // Model positions + std::vector m_cubePositions; + + // Graphics resources + // Shader + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + // Mesh data + std::unique_ptr m_vertexBuffer; + VertexArrayObject m_vao; + // textures + std::shared_ptr m_diffuse; + std::shared_ptr m_specular; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/PointLightCaster.cpp b/Demo/RenderDemo/source/app/PointLightCaster.cpp new file mode 100644 index 0000000..174f3c5 --- /dev/null +++ b/Demo/RenderDemo/source/app/PointLightCaster.cpp @@ -0,0 +1,240 @@ +#include "app/PointLightCaster.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool PointLightCaster::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoords; + +out vec3 normal; +out vec3 fragPos; +out vec2 texCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +// Point light +struct Light +{ + vec3 position; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; + +out vec4 fragColor; + +in vec2 texCoords; +in vec3 normal; +in vec3 fragPos; + +uniform Material material; +uniform Light light; +uniform vec3 viewPos; + +void main() { + // Textures + vec3 diffuseTex = vec3(texture(material.diffuse, texCoords)); + vec3 specularTex = vec3(texture(material.specular, texCoords)); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); + + // ambient + vec3 ambient = light.ambient * diffuseTex * attenuation; + + // diffuse + vec3 norm = normalize(normal); + vec3 lightDir = normalize(light.position - fragPos); // Direction vector from fragment to light source + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = diff * diffuseTex * light.diffuse * attenuation; + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + vec3 specular = spec * specularTex * light.specular * attenuation; + + // final + vec3 result = ambient + diffuse + specular; + fragColor = vec4(result, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + // Shaders + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Mesh + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), + std::vector{3, 2, 3}); + + glBindVertexArray(m_vao.getId()); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + auto attr = m_vertexBuffer->getAttributes(); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // Location 2, uv data + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, attr.at(1).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(1).offset); + + glBindVertexArray(0); + + // Textures + m_diffuse = textureFromFile("container2.png", "data/texture/", "diffuse"); + m_specular = textureFromFile("container2_specular.png", "data/texture/", "specular"); + + // Light + m_pointLight.position = glm::vec3(0.f); + m_pointLight.ambient = m_lightColor * 0.05f; + m_pointLight.diffuse = m_lightColor * 0.5f; + m_pointLight.specular = m_lightColor; + + // Models + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 0.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 2.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, -2.f}); + + // Initial state setup + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void PointLightCaster::render() +{ + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Draw cube model + m_modelShader->setActive(); + + // Material + m_modelShader->setTexture("material.diffuse", *m_diffuse, 0); + m_modelShader->setTexture("material.specular", *m_specular, 1); + m_modelShader->set("material.shininess", 64.f); + + // Light + m_pointLight.set(*m_modelShader, "light"); + + // Camera + m_modelShader->set("viewPos", getCamera().getPosition()); + m_modelShader->set("view", getCamera().getView()); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + m_modelShader->set("projection", projection); + + // Cube vao + glBindVertexArray(m_vao.getId()); + + // Draw models + for (int i = 0; i < m_cubePositions.size(); ++i) + { + glm::mat4 model{1.f}; + model = glm::translate(model, m_cubePositions.at(i)); + // Angle in degree + float angle = 15.f * i; + model = glm::rotate(model, glm::radians(angle), glm::vec3(1.f, 0.3f, 0.5f)); + m_modelShader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + // Draw light + m_lightShader->setActive(); + + m_lightShader->set("color", m_lightColor); + m_lightShader->set("model", glm::scale(glm::translate(m_pointLight.position), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/PointLightCaster.h b/Demo/RenderDemo/source/app/PointLightCaster.h new file mode 100644 index 0000000..571a20a --- /dev/null +++ b/Demo/RenderDemo/source/app/PointLightCaster.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/PointLight.h" +#include "gfx/Shader.h" +#include "gfx/VertexArrayObject.h" +#include "gfx/VertexBuffer.h" + +class PointLightCaster : public RenderApplication +{ + public: + ~PointLightCaster() = default; + + private: + bool setup() override; + void render() override; + + std::vector m_cubePositions; + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + std::unique_ptr m_vertexBuffer; + std::shared_ptr m_diffuse; + std::shared_ptr m_specular; + VertexArrayObject m_vao; + + PointLight m_pointLight; + + glm::vec3 m_lightPos = glm::vec3(1.2f, 1.f, 2.f); + glm::vec3 m_lightColor = glm::vec3(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/RenderText.cpp b/Demo/RenderDemo/source/app/RenderText.cpp new file mode 100644 index 0000000..d772263 --- /dev/null +++ b/Demo/RenderDemo/source/app/RenderText.cpp @@ -0,0 +1,112 @@ +#include "app/RenderText.h" +#include + +RenderText::~RenderText() +{ + // +} + +bool RenderText::setup() +{ + static const char* vertexCode = R"##( +#version 460 core +layout (location = 0) in vec4 vertex; +out vec2 TexCoords; + +uniform mat4 projection; + +void main() +{ + gl_Position = projection * vec4(vertex.xy, 0.0, 1.0); + TexCoords = vertex.zw; +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 TexCoords; +out vec4 color; + +uniform sampler2D text; +uniform vec3 textColor; + +void main() +{ + vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r); + color = vec4(textColor, 1.0) * sampled; +} +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + font = std::make_unique("data/fonts/OpenSans-Regular.ttf"); + + glm::mat4 projection = glm::ortho(0.0f, 800.0f, 0.0f, 600.0f); + shader->setActive(); + shader->set("projection", projection); + + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + return true; +} + +void RenderText::renderText(std::string text, float x, float y, float scale, glm::vec3 color) +{ + // activate corresponding render state + shader->setActive(); + shader->set("textColor", color); + glActiveTexture(GL_TEXTURE0); + glBindVertexArray(VAO); + + // iterate through all characters + for (char c : text) + { + auto character = font->characters.at(c); + + float xpos = x + character.bearing.x * scale; + float ypos = y - (character.size.y - character.bearing.y) * scale; + + float w = character.size.x * scale; + float h = character.size.y * scale; + // update VBO for each character + float vertices[6][4] = { + {xpos, ypos + h, 0.0f, 0.0f}, {xpos, ypos, 0.0f, 1.0f}, {xpos + w, ypos, 1.0f, 1.0f}, + + {xpos, ypos + h, 0.0f, 0.0f}, {xpos + w, ypos, 1.0f, 1.0f}, {xpos + w, ypos + h, 1.0f, 0.0f}}; + // render glyph texture over quad + glBindTexture(GL_TEXTURE_2D, character.textureId); + // update content of VBO memory + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + glBindBuffer(GL_ARRAY_BUFFER, 0); + // render quad + glDrawArrays(GL_TRIANGLES, 0, 6); + // now advance cursors for next glyph (note that advance is number of 1/64 pixels) + x += (character.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64) + } + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void RenderText::render() +{ + // + + renderText("This is sample text", 0.0f, 0.0f, 1.0f, glm::vec3(1.f, 0.f, 0.f)); + renderText("This is sample text", 25.0f, 25.0f, 1.0f, glm::vec3(0.5, 0.8f, 0.2f)); + renderText("(C) LearnOpenGL.com", 540.0f, 570.0f, 0.5f, glm::vec3(0.3, 0.7f, 0.9f)); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/RenderText.h b/Demo/RenderDemo/source/app/RenderText.h new file mode 100644 index 0000000..b0cf7cc --- /dev/null +++ b/Demo/RenderDemo/source/app/RenderText.h @@ -0,0 +1,21 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Font.h" + +class RenderText : public RenderApplication +{ + private: + std::unique_ptr shader; + std::unique_ptr font; + GLuint VAO = 0; + GLuint VBO = 0; + + bool setup() override; + + void render() override; + void renderText(std::string text, float x, float y, float scale, glm::vec3 color); + public: + ~RenderText(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/RotatingCubes.cpp b/Demo/RenderDemo/source/app/RotatingCubes.cpp new file mode 100644 index 0000000..218ab64 --- /dev/null +++ b/Demo/RenderDemo/source/app/RotatingCubes.cpp @@ -0,0 +1,147 @@ +#include "app/RotatingCubes.h" +#include "gfx/BasicMeshes.h" + +#include + +bool RotatingCubes::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec3 vp_ms; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ +texCoord = uv; +// Matrix multiplication is read left to right +gl_Position = projection * view * model * vec4(vp_ms, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; +uniform sampler2D blendTex; +uniform float mixRatio; + +void main() +{ +color = mix( + texture(baseTex, texCoord), + texture(blendTex, texCoord), + clamp(mixRatio, 0.2, 0.8)); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Texture + texContainer.id = textureIdFromFile("wall.jpg", "data/texture/"); + // texAwesome.id = textureIdFromFile("awesomeface.png", "data/texture/"); + texAwesome.id = textureIdFromFile("container.jpg", "data/texture/"); + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(sizeof(GLfloat) * 3)); + // Ignore normals + glBindVertexArray(0); + + // Set render state + + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glEnable(GL_DEPTH_TEST); + + return true; +} + +void RotatingCubes::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + glm::vec3 cubePositions[] = {glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(2.0f, 5.0f, -15.0f), + glm::vec3(-1.5f, -2.2f, -2.5f), glm::vec3(-3.8f, -2.0f, -12.3f), + glm::vec3(2.4f, -0.4f, -3.5f), glm::vec3(-1.7f, 3.0f, -7.5f), + glm::vec3(1.3f, -2.0f, -2.5f), glm::vec3(1.5f, 2.0f, -2.5f), + glm::vec3(1.5f, 0.2f, -1.5f), glm::vec3(-1.3f, 1.0f, -1.5f)}; + + // View matrix + glm::mat4 view{1.f}; + view = glm::translate(view, {0.f, 0.f, -5.f}); + + // Projection + auto aspectRatio = (float)getWindow().getWidth() / (float)getWindow().getHeight(); + glm::mat4 projection = glm::perspective(glm::radians(45.f), aspectRatio, 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArray(vao); + // Use shader + shader->setActive(); + shader->set("view", view); + shader->set("projection", projection); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + // Blend texture + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texAwesome.id); + shader->set("blendTex", 1); + + // Same cube with different positions + float i = 0.f; + for (const auto& position : cubePositions) + { + // Model matrix, different rotation and translation for each cube + glm::mat4 model{1.f}; + model = glm::translate(model, position); + model = glm::rotate(model, glm::radians(timeAcc * (5.f + i)), {1.f, 0.3f, 0.7f}); + + // Transformation data for shader + shader->set("model", model); + + // Mix ratio + shader->set("mixRatio", (std::sin(timeAcc * (1.f + i)) + 1.f) / 2.f); + + auto vertexCount = sizeof(cubeVertices) / sizeof(GLfloat) / 8; + glDrawArrays(GL_TRIANGLES, 0, static_cast(vertexCount)); + i += 1.f; + } + glBindVertexArray(0); +} + +RotatingCubes::~RotatingCubes() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/RotatingCubes.h b/Demo/RenderDemo/source/app/RotatingCubes.h new file mode 100644 index 0000000..42063f9 --- /dev/null +++ b/Demo/RenderDemo/source/app/RotatingCubes.h @@ -0,0 +1,22 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class RotatingCubes : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Texture texAwesome; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~RotatingCubes(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SimpleMaterial.cpp b/Demo/RenderDemo/source/app/SimpleMaterial.cpp new file mode 100644 index 0000000..2e15b80 --- /dev/null +++ b/Demo/RenderDemo/source/app/SimpleMaterial.cpp @@ -0,0 +1,186 @@ +#include "app/SimpleMaterial.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool SimpleMaterial::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; + +out vec3 normal; +out vec3 fragPos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + vec3 ambient; + vec3 diffuse; + vec3 specular; + float shininess; +}; + +struct Light +{ + vec3 position; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +out vec4 fragColor; + +in vec3 normal; +in vec3 fragPos; + +uniform Material material; +uniform Light light; +uniform vec3 viewPos; + +void main(){ + // ambient + vec3 ambient = light.ambient * material.ambient; + + // diffuse + vec3 norm = normalize(normal); + vec3 lightDir = normalize(light.position - fragPos); + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = (diff * material.diffuse) * light.diffuse; + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + vec3 specular = (spec * material.specular) * light.specular; + + // final + vec3 result = ambient + diffuse + specular; + fragColor = vec4(result, 1.f); +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), std::vector{3, 2, 3}); + + glCreateVertexArrays(1, &m_vertexArray); + glBindVertexArray(m_vertexArray); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + glEnableVertexAttribArray(0); + auto attr = m_vertexBuffer->getAttributes(); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + //glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(5 * sizeof(float))); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // uv data is ignored + glBindVertexArray(0); + + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void SimpleMaterial::render() +{ + // Update light movement and color + m_lightPos.y = std::sin(getTimeTotal() * 0.3f) * 2.f; + m_lightColor.x = std::abs(std::sin(getTimeTotal() * 2.f)); + m_lightColor.y = std::abs(std::sin(getTimeTotal() * 0.7f)); + m_lightColor.z = std::abs(std::sin(getTimeTotal() * 1.3f)); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + + glm::vec3 cubePos(0.f); + + // Draw cube model + m_modelShader->setActive(); + // Material + auto mat = PhongColorMaterial::getMaterial("gold"); + mat.set(*m_modelShader); + //m_modelShader->set("material.ambient", glm::vec3(1.f, 0.5f, 0.31f)); + //m_modelShader->set("material.diffuse", glm::vec3(1.f, 0.5f, 0.31f)); + //m_modelShader->set("material.specular", glm::vec3(0.5f, 0.5f, 0.5f)); + //m_modelShader->set("material.shininess", 64.f); + + // Light + m_modelShader->set("light.ambient", glm::vec3(1.f)); // m_lightColor * 0.2f); + m_modelShader->set("light.diffuse", glm::vec3(1.f)); // m_lightColor * 0.5f); + m_modelShader->set("light.specular", glm::vec3(1.f)); // m_lightColor); + m_modelShader->set("light.position", m_lightPos); + + m_modelShader->set("viewPos", getCamera().getPosition()); + + m_modelShader->set("model", glm::translate(cubePos)); + m_modelShader->set("view", getCamera().getView()); + m_modelShader->set("projection", projection); + + glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + // Draw light model + m_lightShader->setActive(); + + m_lightShader->set("color", m_lightColor); + m_lightShader->set("model", glm::scale(glm::translate(m_lightPos), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + + // glBindVertexArray(m_vertexArray); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); +} + +SimpleMaterial::~SimpleMaterial() +{ + glDeleteVertexArrays(1, &m_vertexArray); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SimpleMaterial.h b/Demo/RenderDemo/source/app/SimpleMaterial.h new file mode 100644 index 0000000..3f97281 --- /dev/null +++ b/Demo/RenderDemo/source/app/SimpleMaterial.h @@ -0,0 +1,22 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/VertexBuffer.h" + +class SimpleMaterial : public RenderApplication +{ + public: + ~SimpleMaterial(); + + private: + bool setup() override; + void render() override; + + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + std::unique_ptr m_vertexBuffer; + GLuint m_vertexArray = 0; + glm::vec3 m_lightPos = glm::vec3(1.2f, 1.f, 2.f); + glm::vec3 m_lightColor = glm::vec3(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SimpleMoveCamera.cpp b/Demo/RenderDemo/source/app/SimpleMoveCamera.cpp new file mode 100644 index 0000000..82fa6f6 --- /dev/null +++ b/Demo/RenderDemo/source/app/SimpleMoveCamera.cpp @@ -0,0 +1,149 @@ +#include "app/SimpleMoveCamera.h" +#include "gfx/BasicMeshes.h" + +#include + +bool SimpleMoveCamera::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec3 vp_ms; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + texCoord = uv; + // Matrix multiplication is read left to right + gl_Position = projection * view * model * vec4(vp_ms, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +in vec2 texCoord; + +out vec4 color; + +uniform sampler2D baseTex; + +void main() +{ + color = texture(baseTex, texCoord); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Camera + camera.setPosition({0.f, 0.f, 5.f}); + // Look into negative z + camera.setDirection({0.f, 0.f, -1.f}); + camera.setUp({0.f, 1.f, 0.f}); + + // Texture + texContainer.id = textureIdFromFile("container.jpg", "data/texture/"); + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y/z + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(GLfloat) * 8, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 8, (void*)(sizeof(GLfloat) * 3)); + + glBindVertexArray(0); + + // Set render state + + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glEnable(GL_DEPTH_TEST); + + return true; +} + +void SimpleMoveCamera::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Camera parameters + float cameraSpeed = 2.f * getTimeDelta(); + + glm::vec3 position = camera.getPosition(); + auto direction = camera.getDirection(); + auto right = camera.getRight(); + + // Process input for camera movement + // Forwards, backward + if (getWindow().getKey(GLFW_KEY_W) == GLFW_PRESS) + position += direction * cameraSpeed; + if (getWindow().getKey(GLFW_KEY_S) == GLFW_PRESS) + position -= direction * cameraSpeed; + // Left, right + if (getWindow().getKey(GLFW_KEY_A) == GLFW_PRESS) + position -= right * cameraSpeed; + if (getWindow().getKey(GLFW_KEY_D) == GLFW_PRESS) + position += right * cameraSpeed; + + camera.setPosition(position); + + // Projection + auto aspectRatio = (float)getWindow().getWidth() / (float)getWindow().getHeight(); + glm::mat4 projection = glm::perspective(glm::radians(45.f), aspectRatio, 0.1f, 100.f); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindVertexArray(vao); + // Use shader + shader->setActive(); + shader->set("view", camera.getView()); + shader->set("projection", projection); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + glm::vec3 positions[] = {{0.f, 0.f, 0.f}, {2.f, 0.f, 0.f}, {0.f, -2.f, 0.f}, + {0.f, 2.f, -2.f}, {0.f, 0.f, 2.f}, {3.f, -3.f, 2.f}}; + + auto vertexCount = sizeof(cubeVertices) / sizeof(GLfloat) / 8; + + // Draw cubes + for (const auto position : positions) + { + // Model matrix + glm::mat4 model{1.f}; + model = glm::translate(model, position); + + // Transformation data for shader + shader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, static_cast(vertexCount)); + } + glBindVertexArray(0); +} + +SimpleMoveCamera::~SimpleMoveCamera() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SimpleMoveCamera.h b/Demo/RenderDemo/source/app/SimpleMoveCamera.h new file mode 100644 index 0000000..dad71be --- /dev/null +++ b/Demo/RenderDemo/source/app/SimpleMoveCamera.h @@ -0,0 +1,23 @@ +#pragma once + +#include "gfx/Camera.h" +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class SimpleMoveCamera : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Camera camera; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~SimpleMoveCamera(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SpotLightCaster.cpp b/Demo/RenderDemo/source/app/SpotLightCaster.cpp new file mode 100644 index 0000000..c394412 --- /dev/null +++ b/Demo/RenderDemo/source/app/SpotLightCaster.cpp @@ -0,0 +1,260 @@ +#include "app/SpotLightCaster.h" + +// +#include +#include + +// +#include "gfx/BasicMeshes.h" +#include "gfx/PhongColorMaterial.h" + +bool SpotLightCaster::setup() +{ + // For model and light source + const char* vertexCode = R"##( +#version 460 core + +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; +layout(location = 2) in vec2 aTexCoords; + +out vec3 normal; +out vec3 fragPos; +out vec2 texCoords; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(){ + fragPos = vec3(model * vec4(aPos, 1.0)); + normal = mat3(transpose(inverse(model))) * aNormal; + texCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0); +} + )##"; + + // For model + const char* fragmentCode = R"##( +#version 460 core + +struct Material +{ + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +// Spot light +struct Light +{ + vec3 position; + vec3 direction; + float innerCutOff; + float outerCutOff; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; + +out vec4 fragColor; + +in vec2 texCoords; +in vec3 normal; +in vec3 fragPos; + +uniform Material material; +uniform Light light; +uniform vec3 viewPos; + +void main() +{ + // Textures + vec3 diffuseTex = vec3(texture(material.diffuse, texCoords)); + vec3 specularTex = vec3(texture(material.specular, texCoords)); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); + + // ambient + vec3 ambient = light.ambient * diffuseTex * attenuation; + + vec3 lightDir = normalize(light.position - fragPos); // Direction vector from fragment to light source + float theta = dot(lightDir, normalize(-light.direction)); // Angle between fragment to light and light direction + if (theta > light.outerCutOff) + { + // Inside outer light cone, do normal light calculation + float epsilon = light.innerCutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.f, 1.f); + + // diffuse + vec3 norm = normalize(normal); + float diff = max(dot(normal, lightDir), 0.f); + vec3 diffuse = diff * diffuseTex * light.diffuse * attenuation * intensity; + + // specular + vec3 viewDir = normalize(viewPos - fragPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.f), material.shininess); + vec3 specular = spec * specularTex * light.specular * attenuation * intensity; + + // final + vec3 result = ambient + diffuse + specular; + fragColor = vec4(result, 1.f); + } + else + { + // Outside light cone, only affected by ambient light + fragColor = vec4(ambient, 1.f); + } +} + )##"; + + // For light source, always white + const char* fragmentCodeLightSource = R"##( +#version 460 core + +out vec4 fragColor; + +uniform vec3 color; + +void main(){ + fragColor = vec4(color, 1.f); +} + )##"; + + // Shaders + m_modelShader = std::make_unique(vertexCode, fragmentCode); + m_lightShader = std::make_unique(vertexCode, fragmentCodeLightSource); + + // Mesh + m_vertexBuffer = std::make_unique(cubeVertices, sizeof(cubeVertices) / sizeof(float), + std::vector{3, 2, 3}); + + glBindVertexArray(m_vao.getId()); + m_vertexBuffer->bind(GL_ARRAY_BUFFER); + + // Buffer has x/y/z/u/v/x/y/z + // Location 0, vertex data x/y/z + auto attr = m_vertexBuffer->getAttributes(); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, attr.at(0).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(0).offset); + + // Location 1, normal data + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, attr.at(2).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(2).offset); + + // Location 2, uv data + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, attr.at(1).componentCount, GL_FLOAT, false, m_vertexBuffer->getStride(), + (void*)attr.at(1).offset); + + glBindVertexArray(0); + + // Textures + m_diffuse = textureFromFile("container2.png", "data/texture/", "diffuse"); + m_specular = textureFromFile("container2_specular.png", "data/texture/", "specular"); + + // Light + m_spotLight.position = glm::vec3(0.f, 0.f, 8.f); + m_spotLight.direction = glm::vec3(0.f, 0.f, -1.f); + m_spotLight.innerCutOff = 12.5f; + m_spotLight.outerCutOff= 17.f; + m_spotLight.ambient = m_lightColor * 0.1f; + m_spotLight.diffuse = m_lightColor * 0.8f; + m_spotLight.specular = m_lightColor; + + // Models + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 0.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 0.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, 2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, 2.f}); + + m_cubePositions.push_back(glm::vec3{0.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 0.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{0.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{2.f, -2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, 2.f, -2.f}); + m_cubePositions.push_back(glm::vec3{-2.f, -2.f, -2.f}); + + // Initial state setup + glClearColor(0.f, 0.f, 0.f, 1.f); + glEnable(GL_DEPTH_TEST); + return true; +} + +void SpotLightCaster::render() +{ + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Draw cube model + m_modelShader->setActive(); + + // Material + m_modelShader->setTexture("material.diffuse", *m_diffuse, 0); + m_modelShader->setTexture("material.specular", *m_specular, 1); + m_modelShader->set("material.shininess", 64.f); + + // Light + m_spotLight.set(*m_modelShader, "light"); + + // Camera + m_modelShader->set("viewPos", getCamera().getPosition()); + m_modelShader->set("view", getCamera().getView()); + + // Projection + glm::mat4 projection = glm::perspective(glm::radians(45.f), getWindow().getAspectRation(), 0.001f, 100.f); + m_modelShader->set("projection", projection); + + // Cube vao + glBindVertexArray(m_vao.getId()); + + // Draw models + for (int i = 0; i < m_cubePositions.size(); ++i) + { + glm::mat4 model{1.f}; + model = glm::translate(model, m_cubePositions.at(i)); + // Angle in degree + float angle = 15.f * i; + model = glm::rotate(model, glm::radians(angle), glm::vec3(1.f, 0.3f, 0.5f)); + m_modelShader->set("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + // Draw light + m_lightShader->setActive(); + + m_lightShader->set("color", m_lightColor); + m_lightShader->set("model", glm::scale(glm::translate(m_spotLight.position), glm::vec3(0.3f))); + m_lightShader->set("view", getCamera().getView()); + m_lightShader->set("projection", projection); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glBindVertexArray(0); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/SpotLightCaster.h b/Demo/RenderDemo/source/app/SpotLightCaster.h new file mode 100644 index 0000000..0ba5beb --- /dev/null +++ b/Demo/RenderDemo/source/app/SpotLightCaster.h @@ -0,0 +1,30 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/SpotLight.h" +#include "gfx/Shader.h" +#include "gfx/VertexArrayObject.h" +#include "gfx/VertexBuffer.h" + +class SpotLightCaster : public RenderApplication +{ + public: + ~SpotLightCaster() = default; + + private: + bool setup() override; + void render() override; + + std::vector m_cubePositions; + std::unique_ptr m_modelShader; + std::unique_ptr m_lightShader; + std::unique_ptr m_vertexBuffer; + std::shared_ptr m_diffuse; + std::shared_ptr m_specular; + VertexArrayObject m_vao; + + SpotLight m_spotLight; + + glm::vec3 m_lightPos = glm::vec3(1.2f, 1.f, 2.f); + glm::vec3 m_lightColor = glm::vec3(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TexturedQuad.cpp b/Demo/RenderDemo/source/app/TexturedQuad.cpp new file mode 100644 index 0000000..59d7a72 --- /dev/null +++ b/Demo/RenderDemo/source/app/TexturedQuad.cpp @@ -0,0 +1,110 @@ +#include "app/TexturedQuad.h" + +bool TexturedQuad::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec2 vp_ndc; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +void main() +{ +texCoord = uv; +gl_Position = vec4(vp_ndc, 0.f, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +uniform sampler2D baseTex; +uniform sampler2D blendTex; +uniform float mixRatio; + +in vec2 texCoord; + +out vec4 color; + +void main() +{ +vec4 base = texture(baseTex, texCoord); +vec4 blend = texture(blendTex, texCoord); +color = mix(base, blend, mixRatio); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Texture + texContainer.id = textureIdFromFile("container.jpg", "data/texture/"); + texAwesome.id = textureIdFromFile("awesomeface.png", "data/texture/"); + + // Vertex data, x/y, v/v + const GLfloat vertexData[] = {// First triangle, upper right, upper left, lower left + 0.5f, 0.5f, 1.f, 1.f, -0.5f, 0.5f, 0.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, + // Second triangle, upper right, lower left, lower right + 0.5f, 0.5f, 1.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, 0.5f, -0.5f, 1.f, 0.f}; + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(vertexData), vertexData, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2)); + + glBindVertexArray(0); + + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + + return true; +} + +void TexturedQuad::render() +{ + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use shader + shader->setActive(); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + // Face texture + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texAwesome.id); + shader->set("blendTex", 1); + + // Mix ratio + shader->set("mixRatio", (std::sin(timeAcc * 3.f) + 1.f) / 2.f); + + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); +} + +TexturedQuad::~TexturedQuad() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TexturedQuad.h b/Demo/RenderDemo/source/app/TexturedQuad.h new file mode 100644 index 0000000..181297e --- /dev/null +++ b/Demo/RenderDemo/source/app/TexturedQuad.h @@ -0,0 +1,22 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class TexturedQuad : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Texture texAwesome; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~TexturedQuad(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TexturedTriangle.cpp b/Demo/RenderDemo/source/app/TexturedTriangle.cpp new file mode 100644 index 0000000..a46d5ca --- /dev/null +++ b/Demo/RenderDemo/source/app/TexturedTriangle.cpp @@ -0,0 +1,98 @@ +#include "app/TexturedTriangle.h" + +bool TexturedTriangle::setup() +{ + const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec2 vp_ndc; +layout (location = 1) in vec2 uv; + +out vec2 texCoords; + +void main(){ +gl_Position = vec4(vp_ndc, 0.f, 1.f); +texCoords = uv; +} + )##"; + + const char* fragmentCode = R"##( +#version 460 core + +out vec4 color; + +in vec2 texCoords; + +uniform sampler2D tex; + +void main(){ +color = texture(tex, texCoords); +} + )##"; + + // Shader + m_shader = std::make_unique(vertexCode, fragmentCode); + + texture = textureIdFromFile("wall.jpg", "data/texture/"); + + // Vertices, x, y, u, v + const float vertexData[] = {// Top middle + 0.0f, 0.8f, 0.5f, 1.0f, + // Lower left + -0.8f, -0.8f, 0.f, 0.f, + // Lower right + 0.8f, -0.8f, 1.f, 0.f}; + + // Create vertex buffer + glCreateBuffers(1, &vertexBuffer); + glNamedBufferData(vertexBuffer, sizeof(vertexData), vertexData, GL_STATIC_DRAW); + + // Vertex array object + glGenVertexArrays(1, &vertexArray); + + // Setup VAO state + glBindVertexArray(vertexArray); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + + // Vertex x/y + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr); + + // Texcoord u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void*)(sizeof(float) * 2)); + + glBindVertexArray(0); + + return true; +} + +void TexturedTriangle::render() +{ + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw + // Active shader + m_shader->setActive(); + + // VAO state with vertex buffer object state and data + // Also binds vertex data to the attrobute locations + glBindVertexArray(vertexArray); + + // Model textures, defaults to texture location 0 + // So this call is actually unnecessary + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glBindVertexArray(0); +} + +TexturedTriangle::~TexturedTriangle() +{ + glDeleteVertexArrays(1, &vertexArray); + glDeleteBuffers(1, &vertexBuffer); + glDeleteTextures(1, &texture); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TexturedTriangle.h b/Demo/RenderDemo/source/app/TexturedTriangle.h new file mode 100644 index 0000000..6c4d37f --- /dev/null +++ b/Demo/RenderDemo/source/app/TexturedTriangle.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +// Triangle with texture applied +class TexturedTriangle : public RenderApplication +{ + private: + std::unique_ptr m_shader; + GLuint vertexArray = 0; + GLuint vertexBuffer = 0; + GLuint texture = 0; + + bool setup() override; + + void render() override; + + public: + ~TexturedTriangle(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TransformedQuad.cpp b/Demo/RenderDemo/source/app/TransformedQuad.cpp new file mode 100644 index 0000000..c9d82ce --- /dev/null +++ b/Demo/RenderDemo/source/app/TransformedQuad.cpp @@ -0,0 +1,128 @@ +#include "app/TransformedQuad.h" + +#include + +bool TransformedQuad::setup() +{ + static const char* vertexCode = R"##( +#version 460 core + +layout (location = 0) in vec2 vp_ndc; +layout (location = 1) in vec2 uv; + +out vec2 texCoord; + +uniform mat4 transform; + +void main() +{ +texCoord = uv; +gl_Position = transform * vec4(vp_ndc, 0.f, 1.f); +} +)##"; + + static const char* fragmentCode = R"##( +#version 460 core + +uniform sampler2D baseTex; +uniform sampler2D blendTex; +uniform float mixRatio; + +in vec2 texCoord; + +out vec4 color; + +void main() +{ +vec4 base = texture(baseTex, texCoord); +vec4 blend = texture(blendTex, texCoord); +color = mix(base, blend, mixRatio); +} + +)##"; + + // Shader + shader = std::make_unique(vertexCode, fragmentCode); + + // Texture + texContainer.id = textureIdFromFile("container.jpg", "data/texture/"); + texAwesome.id = textureIdFromFile("awesomeface.png", "data/texture/"); + + // Vertex data, x/y, v/v + const GLfloat vertexData[] = {// First triangle, upper right, upper left, lower left + 0.5f, 0.5f, 1.f, 1.f, -0.5f, 0.5f, 0.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, + // Second triangle, upper right, lower left, lower right + 0.5f, 0.5f, 1.f, 1.f, -0.5f, -0.5f, 0.f, 0.f, 0.5f, -0.5f, 1.f, 0.f}; + + glCreateBuffers(1, &vbo); + glNamedBufferData(vbo, sizeof(vertexData), vertexData, GL_STATIC_DRAW); + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + // x/y + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, nullptr); + // u/v + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(GLfloat) * 4, (void*)(sizeof(GLfloat) * 2)); + + glBindVertexArray(0); + + // Clear color buffer + glClearColor(0.2f, 0.3f, 0.3f, 1.f); + + return true; +} + +void TransformedQuad::render() +{ + // Timer + static float timeAcc = 0; + timeAcc += getTimeDelta(); + + // Clear framebuffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use shader + shader->setActive(); + + // Tranformation order: scale, rotate, translate + // With matrix denotation: T * R * S, applied in reverse order + glm::mat4 transform = glm::mat4{1.f}; + // Translate on x axis + transform = glm::translate(transform, {std::sin(timeAcc * 1.5f), 0.f, 0.f}); + // Rotate on Z axis, 10 degrees each second + transform = glm::rotate(transform, glm::radians(timeAcc * 10.f), {0.f, 0.f, 1.f}); + // Scale on each axis + transform = glm::scale(transform, glm::vec3{(std::sin(timeAcc) + 1.f) / 2.f}); + + // Set transformation + shader->set("transform", transform); + + // Texture + // Activate the binding location + glActiveTexture(GL_TEXTURE0); + // Bind the actual texture to active location + glBindTexture(GL_TEXTURE_2D, texContainer.id); + // Set texture location manually + shader->set("baseTex", 0); + + // Face texture + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texAwesome.id); + shader->set("blendTex", 1); + + // Mix ratio + shader->set("mixRatio", (std::sin(timeAcc * 3.f) + 1.f) / 2.f); + + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); +} + +TransformedQuad::~TransformedQuad() +{ + glDeleteVertexArrays(1, &vao); + glDeleteBuffers(1, &vbo); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/app/TransformedQuad.h b/Demo/RenderDemo/source/app/TransformedQuad.h new file mode 100644 index 0000000..452f9b7 --- /dev/null +++ b/Demo/RenderDemo/source/app/TransformedQuad.h @@ -0,0 +1,22 @@ +#pragma once + +#include "RenderApplication.h" +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +class TransformedQuad : public RenderApplication +{ + private: + std::unique_ptr shader; + Texture texContainer; + Texture texAwesome; + GLuint vao = 0; + GLuint vbo = 0; + + bool setup() override; + + void render() override; + + public: + ~TransformedQuad(); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/BasicMeshes.cpp b/Demo/RenderDemo/source/gfx/BasicMeshes.cpp new file mode 100644 index 0000000..1443cd5 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/BasicMeshes.cpp @@ -0,0 +1,49 @@ +#include "gfx/BasicMeshes.h" + +// Cube vertices, 36 entries +// clang-format off +const float cubeVertices[288] = { + // x, y, z, u, v, x, y, z + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f +}; +// clang-format on \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/BasicMeshes.h b/Demo/RenderDemo/source/gfx/BasicMeshes.h new file mode 100644 index 0000000..e1ba798 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/BasicMeshes.h @@ -0,0 +1,8 @@ +#pragma once + +// Layout +// vertex | texture | normal +// 3, 2, 3 +// 8 entries +// x/y/z u/v x/y/z +extern const float cubeVertices[288]; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Camera.cpp b/Demo/RenderDemo/source/gfx/Camera.cpp new file mode 100644 index 0000000..9cb32fe --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Camera.cpp @@ -0,0 +1,53 @@ +#include "gfx/Camera.h" + +#include + +void Camera::setPosition(const glm::vec3& position) +{ + this->position = position; + viewDirty = true; +} + +void Camera::setDirection(const glm::vec3& direction) +{ + this->direction = direction; + viewDirty = true; +} + +void Camera::setDirection(const float yaw, const float pitch) +{ + glm::vec3 direction; + direction.x = std::cos(glm::radians(yaw)) * std::cos(glm::radians(pitch)); + direction.y = std::sin(glm::radians(pitch)); + direction.z = std::sin(glm::radians(yaw)) * std::cos(glm::radians(pitch)); + setDirection(direction); +} + +void Camera::setLookAt(const glm::vec3& point) +{ + setDirection(point - getPosition()); +} + +void Camera::setUp(const glm::vec3& up) +{ + this->up = up; + viewDirty = true; +} + +const glm::vec3& Camera::getPosition() const { return position; } + +const glm::vec3& Camera::getDirection() const { return direction; } + +const glm::vec3& Camera::getUp() const { return up; } + +const glm::vec3 Camera::getRight() const { return glm::normalize(glm::cross(direction, up)); } + +const glm::mat4& Camera::getView() const +{ + if (viewDirty) + { + viewDirty = false; + view = glm::lookAt(position, position + direction, up); + } + return view; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Camera.h b/Demo/RenderDemo/source/gfx/Camera.h new file mode 100644 index 0000000..d6a4c65 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Camera.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +class Camera +{ + public: + // Camera position in world space + void setPosition(const glm::vec3& position); + // Camera direction vector + void setDirection(const glm::vec3& direction); + // Camera direction from yaw and pitch + void setDirection(const float yaw, const float pitch); + // Camera direction from look at point + void setLookAt(const glm::vec3& point); + // Up vector + void setUp(const glm::vec3& up); + + const glm::vec3& getPosition() const; + const glm::vec3& getDirection() const; + const glm::vec3& getUp() const; + + // Utility + // Normalized right vector + const glm::vec3 getRight() const; + + // View matrix + const glm::mat4& getView() const; + + private: + // Position in world space + glm::vec3 position = glm::vec3{0.f, 0.f, 0.f}; + // Camera direction in world space + glm::vec3 direction = glm::vec3{0.f, 0.f, -1.f}; + // Camera up vector + glm::vec3 up = glm::vec3{0.f, 1.f, 0.f}; + + // View matrix, recalculated on access + mutable bool viewDirty = true; + mutable glm::mat4 view = glm::mat4(1.f); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/DirectionalLight.cpp b/Demo/RenderDemo/source/gfx/DirectionalLight.cpp new file mode 100644 index 0000000..2f9e6a1 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/DirectionalLight.cpp @@ -0,0 +1,10 @@ +#include "gfx/DirectionalLight.h" + +void DirectionalLight::set(Shader& shader, const std::string& prefix) const +{ + shader.setActive(); + shader.set(prefix + ".direction", direction); + shader.set(prefix + ".ambient", ambient); + shader.set(prefix + ".diffuse", diffuse); + shader.set(prefix + ".specular", specular); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/DirectionalLight.h b/Demo/RenderDemo/source/gfx/DirectionalLight.h new file mode 100644 index 0000000..3db3f2b --- /dev/null +++ b/Demo/RenderDemo/source/gfx/DirectionalLight.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "gfx/Shader.h" + +class DirectionalLight +{ + public: + // Ligth direction, default towards Z + glm::vec3 direction = glm::vec3(0.f, 0.f, 1.f); + // Colors + glm::vec3 ambient = glm::vec3(1.f); + glm::vec3 diffuse = glm::vec3(1.f); + glm::vec3 specular = glm::vec3(1.f); + + void set(Shader& shader, const std::string& prefix) const; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Font.cpp b/Demo/RenderDemo/source/gfx/Font.cpp new file mode 100644 index 0000000..eda2807 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Font.cpp @@ -0,0 +1,71 @@ +#include "gfx/Font.h" + +#include + +Font::Font(const std::string& font) +{ + FT_Library ft; + if (FT_Init_FreeType(&ft)) + { + loge("Could not init FreeType Library"); + return; + } + + FT_Face face; + if (FT_New_Face(ft, font.c_str(), 0, &face)) + { + loge("Failed to load font"); + return; + } + + FT_Set_Pixel_Sizes(face, 0, 48); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // disable byte-alignment restriction + + for (unsigned char c = 0; c < 128; c++) + { + // load character glyph + if (FT_Load_Char(face, c, FT_LOAD_RENDER)) + { + loge("Failed to load Glyph"); + continue; + } + + // generate texture + GLuint texture = 0; + glCreateTextures(GL_TEXTURE_2D, 1, &texture); + + // set texture options + glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (face->glyph->bitmap.buffer != nullptr) + { + // create storage + glTextureStorage2D(texture, 1, GL_R8, face->glyph->bitmap.width, face->glyph->bitmap.rows); + // Write data + glTextureSubImage2D(texture, 0, 0, 0, face->glyph->bitmap.width, face->glyph->bitmap.rows, GL_RED, + GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer); + } + else + { + // Glyph has no data -> not present in our font + // Create dummy texture with single blank pixel + uint8_t p = 0; + glTextureStorage2D(texture, 1, GL_R8, 1, 1); + glTextureSubImage2D(texture, 0, 0, 0, 1, 1, GL_RED, GL_UNSIGNED_BYTE, &p); + } + + // now store character for later use + Character character = {texture, glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows), + glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top), + (unsigned int)face->glyph->advance.x}; + + characters.insert(std::pair(c, character)); + } + + FT_Done_Face(face); + FT_Done_FreeType(ft); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Font.h b/Demo/RenderDemo/source/gfx/Font.h new file mode 100644 index 0000000..eb728cd --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Font.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include FT_FREETYPE_H + +#include "gfx/Shader.h" + +class Font +{ + public: + struct Character + { + GLuint textureId = 0; // ID handle of the glyph texture + glm::ivec2 size; // Size of glyph + glm::ivec2 bearing; // Offset from baseline to left/top of glyph + unsigned int advance = 0; // Offset to advance to next glyph + }; + + Font(const std::string& font); + + std::unordered_map characters; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Mesh.cpp b/Demo/RenderDemo/source/gfx/Mesh.cpp new file mode 100644 index 0000000..4ade9e6 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Mesh.cpp @@ -0,0 +1,102 @@ +#include "Mesh.h" + +#include + +#include +#include + +// |x y z u v| x y z u v |x y z u v +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 +// xyz - attribute 1, 3 * 4 bytes = 12 byte, offset 0 +// uv - attribute 2, 2 * 4 byte = 8 byte, offset 3 * 4 = 12 +// xyzuv - attribute block, 5 * 4 = 20 byte = stride +// position of attribute element at index i = offset + stride * i +// Example: attribute uv, index 2 position in buffer = 12 + 20 * 2 = 48 bytes from start + +Mesh::Mesh(const std::vector& vertices, const std::vector& indices, + const std::vector>& diffuseTexs, + const std::vector>& specularTexs, + const std::vector>& normalTexs) + : m_vertices(vertices), + m_indices(indices), + m_diffuseTextures(diffuseTexs), + m_specularTextures(specularTexs), + m_normalTextures(normalTexs) +{ + if (m_diffuseTextures.empty()) + throw std::runtime_error("Missing diffuse textures"); + + if (m_specularTextures.empty()) + throw std::runtime_error("Missing specular textures"); + + if (m_normalTextures.empty()) + logi("No normal texture was provided for the mesh"); + + if (m_diffuseTextures.size() > 1) + logw("Multiple diffuse textures are provided but only the first will be used"); + + if (m_specularTextures.size() > 1) + logw("Multiple specular textures are provided but only the first will be used"); + + if (m_normalTextures.size() > 1) + logw("Multiple normal textures are provided but only the first will be used"); + + logi("Creating mesh with {} vertices and {} indices", m_vertices.size(), m_indices.size()); + + // VAO Stores buffer states + glGenVertexArrays(1, &m_vao); + // Per-vertex data buffer + glGenBuffers(1, &m_vbo); + // Index buffer + glGenBuffers(1, &m_ebo); + + glBindVertexArray(m_vao); + + // Write data + // Vertices + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(decltype(m_vertices)::value_type), m_vertices.data(), + GL_STATIC_DRAW); + + // Indices + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(decltype(m_indices)::value_type), m_indices.data(), + GL_STATIC_DRAW); + + // Set attributes + // Vertex buffer has attributes for vertices, normals and texcoords + // Layout is v0, v1, v2, n0, n1, n2, t0, t1 + // All values are float + // Vertices at index 0 + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr); + + // Normals at index 1, requires offset + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal)); + + // Texture coordinates at index 2, requires offset + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoords)); + + // Disable vao + glBindVertexArray(0); +} + +Mesh::~Mesh() +{ + glDeleteVertexArrays(1, &m_vao); + glDeleteBuffers(1, &m_vbo); + glDeleteBuffers(1, &m_ebo); +} + +void Mesh::draw(Shader& shader) const +{ + shader.setTexture("texture_diffuse", *m_diffuseTextures.at(0), 0); + + // Draw mesh + glBindVertexArray(m_vao); + glDrawElements(GL_TRIANGLES, static_cast(m_indices.size()), GL_UNSIGNED_INT, nullptr); + glBindVertexArray(0); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Mesh.h b/Demo/RenderDemo/source/gfx/Mesh.h new file mode 100644 index 0000000..4238d23 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Mesh.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include +#include + +#include "gfx/Shader.h" +#include "gfx/Texture.h" + +// Represents per-vertex data in model space +struct Vertex +{ + glm::vec3 position = glm::vec3(0.f); + glm::vec3 normal = glm::vec3(0.f); + glm::vec2 texCoords = glm::vec3(0.f); +}; + +class Mesh +{ + public: + std::vector m_vertices; + std::vector m_indices; + // Textures + std::vector> m_diffuseTextures; + std::vector> m_specularTextures; + std::vector> m_normalTextures; + + Mesh(const std::vector& vertices, const std::vector& indices, + const std::vector>& diffuseTextures, + const std::vector>& specularTextures, + const std::vector>& normalTextures); + ~Mesh(); + + void draw(Shader& shader) const; + + private: + // Vertex array object + GLuint m_vao = 0; + // Vertex buffer, interleaved vertex data + GLuint m_vbo = 0; + // Element buffer, index buffer for vbo + GLuint m_ebo = 0; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Model.cpp b/Demo/RenderDemo/source/gfx/Model.cpp new file mode 100644 index 0000000..ebf21ef --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Model.cpp @@ -0,0 +1,132 @@ +#include "gfx/Model.h" + +#include +#include + +#include "gfx/Texture.h" + +Model::Model(const std::string& path) { loadModel(path); } + +void Model::draw(Shader& shader) const +{ + // Draw each mesh + // TODO Camera for culling? + for (const auto& mesh : meshes) + { + mesh->draw(shader); + } +} + +void Model::loadModel(const std::string& path) +{ + Assimp::Importer importer; + auto scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); + // Check error + if (scene == nullptr || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || scene->mRootNode == nullptr) + { + throw std::runtime_error{importer.GetErrorString()}; + } + + // Directory of the loaded file + directory = path.substr(0, path.find_last_of('/')); + + processNode(scene->mRootNode, scene); +} + +void Model::processNode(aiNode* node, const aiScene* scene) +{ + // Process all meshes + for (unsigned int i = 0; i < node->mNumMeshes; ++i) + { + // Meshes are stored in the scene, each node has a list + // of mesh indices + // TODO Range check + auto mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(processMesh(mesh, scene)); + } + + // Process all children of the mesh + // TODO Probably bad idea for meshes with large amount of children + // Change this to be non-recursive + for (unsigned int i = 0; i < node->mNumChildren; ++i) + { + processNode(node->mChildren[i], scene); + } +} + +std::shared_ptr Model::processMesh(aiMesh* mesh, const aiScene* scene) +{ + std::vector vertices; + vertices.reserve(mesh->mNumVertices); + + std::vector indices; + + if (mesh->mNormals == nullptr) + throw std::runtime_error{"Mesh is missing normal data"}; + + // Per vertex data + for (unsigned int i = 0; i < mesh->mNumVertices; ++i) + { + Vertex vertex; + vertex.position = {mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z}; + vertex.normal = {mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z}; + + // Texture coordinates + // Up to 8 different texture coordinates allowed per vertex + // Only use the first + if (mesh->mTextureCoords[0] != nullptr) + { + vertex.texCoords = {mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y}; + } + else + { + vertex.texCoords = {0.f, 0.f}; + } + + vertices.push_back(vertex); + } + + // Indices, stored per face + for (unsigned int i = 0; i < mesh->mNumFaces; ++i) + { + auto face = mesh->mFaces[i]; + for (unsigned int j = 0; j < face.mNumIndices; ++j) + { + indices.push_back(face.mIndices[j]); + } + } + + // Material + std::vector> diffuseTextures; + std::vector> specularTextures; + std::vector> normalTextures; + if (mesh->mMaterialIndex >= 0) + { + auto material = scene->mMaterials[mesh->mMaterialIndex]; + diffuseTextures = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse"); + specularTextures = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"); + normalTextures = loadMaterialTextures(material, aiTextureType_NORMALS, "texture_normal"); + } + + return std::make_shared(vertices, indices, diffuseTextures, specularTextures, normalTextures); +} + +std::vector> Model::loadMaterialTextures(aiMaterial* material, aiTextureType type, + const std::string& typeName) +{ + std::vector> textures; + logi("Loading {} material textures.", material->GetTextureCount(type)); + for (unsigned int i = 0; i < material->GetTextureCount(type); ++i) + { + // Path to the texture + aiString fileName; + material->GetTexture(type, i, &fileName); + + // Load texture + auto texture = textureFromFile(fileName.C_Str(), directory, typeName); + + textures.push_back(texture); + } + + return textures; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Model.h b/Demo/RenderDemo/source/gfx/Model.h new file mode 100644 index 0000000..565f4c1 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Model.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include "Mesh.h" +#include "gfx/Shader.h" + +/** + * Basically a collection of meshes + */ +class Model +{ + public: + Model(const std::string& path); + + void draw(Shader& shader) const; + + private: + // Model data + std::vector> meshes; + std::string directory; + + void loadModel(const std::string& path); + + void processNode(aiNode* node, const aiScene* scene); + // Builds Mesh from aiMesh + std::shared_ptr processMesh(aiMesh* mesh, const aiScene* scene); + std::vector> loadMaterialTextures(aiMaterial* material, aiTextureType type, + const std::string& typeName); +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/PhongColorMaterial.cpp b/Demo/RenderDemo/source/gfx/PhongColorMaterial.cpp new file mode 100644 index 0000000..443a1e7 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/PhongColorMaterial.cpp @@ -0,0 +1,34 @@ +#include "gfx/PhongColorMaterial.h" + +#include + +std::unordered_map PhongColorMaterial::s_materials; + +PhongColorMaterial::PhongColorMaterial(const glm::vec3& ambient, const glm::vec3& diffuse, const glm::vec3& specular, + float shininess) + : ambient(ambient), diffuse(diffuse), specular(specular), shininess(shininess) +{ +} + +void PhongColorMaterial::set(Shader& shader) +{ + shader.setActive(); + shader.set("material.ambient", ambient); + shader.set("material.diffuse", diffuse); + shader.set("material.specular", specular); + shader.set("material.shininess", shininess); +} + +void PhongColorMaterial::addMaterial(const std::string& name, const PhongColorMaterial& mat) +{ + s_materials[name] = mat; +} + +const PhongColorMaterial& PhongColorMaterial::getMaterial(const std::string& name) +{ + auto it = s_materials.find(name); + if (it != s_materials.end()) + return it->second; + + throw std::runtime_error("Failed to find material " + name); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/PhongColorMaterial.h b/Demo/RenderDemo/source/gfx/PhongColorMaterial.h new file mode 100644 index 0000000..28225ba --- /dev/null +++ b/Demo/RenderDemo/source/gfx/PhongColorMaterial.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "gfx/Shader.h" + +class PhongColorMaterial +{ + public: + glm::vec3 ambient = glm::vec3(0.f); + glm::vec3 diffuse = glm::vec3(0.f); + glm::vec3 specular = glm::vec3(0.f); + float shininess = 0.f; + + PhongColorMaterial() = default; + PhongColorMaterial(const glm::vec3& ambient, const glm::vec3& diffuse, const glm::vec3& specular, float shininess); + + void set(Shader& shader); + + // Static material library + static void addMaterial(const std::string& name, const PhongColorMaterial& mat); + static const PhongColorMaterial& getMaterial(const std::string& name); + + private: + static std::unordered_map s_materials; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/PointLight.cpp b/Demo/RenderDemo/source/gfx/PointLight.cpp new file mode 100644 index 0000000..b50fb51 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/PointLight.cpp @@ -0,0 +1,14 @@ +#include "gfx/PointLight.h" + +void PointLight::set(Shader& shader, const std::string& prefix) const +{ + shader.setActive(); + shader.set(prefix + ".position", position); + shader.set(prefix + ".ambient", ambient); + shader.set(prefix + ".diffuse", diffuse); + shader.set(prefix + ".specular", specular); + // Attenuation factors + shader.set(prefix + ".constant", constant); + shader.set(prefix + ".linear", linear); + shader.set(prefix + ".quadratic", quadratic); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/PointLight.h b/Demo/RenderDemo/source/gfx/PointLight.h new file mode 100644 index 0000000..1cd0da0 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/PointLight.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include "gfx/Shader.h" + +class PointLight +{ + public: + glm::vec3 position = glm::vec3(0.f); + // Per color light strength + glm::vec3 ambient = glm::vec3(0.f); + glm::vec3 diffuse = glm::vec3(0.f); + glm::vec3 specular = glm::vec3(0.f); + + // Attenuation factors with sane defaults + float constant = 1.f; + float linear = 0.09f; + float quadratic = 0.032f; + + void set(Shader& shader, const std::string& prefix) const; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Shader.cpp b/Demo/RenderDemo/source/gfx/Shader.cpp new file mode 100644 index 0000000..441ccc5 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Shader.cpp @@ -0,0 +1,221 @@ +#include "gfx/Shader.h" + +#include + +#include +#include + +GLuint Shader::activeShaderId = 0; + +Shader::Shader(const std::string& vertexShaderCode, const std::string& fragmentShaderCode) +{ + id = createShaderProgram(vertexShaderCode, fragmentShaderCode); +} + +Shader::~Shader() +{ + if (id == 0) + return; + if (isActive()) + { + glUseProgram(0); + activeShaderId = 0; + } + glDeleteProgram(id); +} + +void Shader::setActive() const +{ + if (id == 0) + throw std::runtime_error("Shader id is null"); + if (isActive()) + return; + + glUseProgram(id); + activeShaderId = id; +} + +void Shader::set(const std::string& name, const int value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform1i(loc, value); +} + +void Shader::set(const std::string& name, const unsigned int value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform1ui(loc, value); +} + +void Shader::set(const std::string& name, const float value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform1f(loc, value); +} + +void Shader::set(const std::string& name, const glm::vec2& value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform2f(loc, value.x, value.y); +} + +void Shader::set(const std::string& name, const glm::vec3& value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform3f(loc, value.x, value.y, value.z); +} + +void Shader::set(const std::string& name, const glm::vec4& value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniform4f(loc, value.x, value.y, value.z, value.w); +} + +void Shader::set(const std::string& name, const glm::mat4& value, bool required) +{ + ensureActive(); + auto loc = getUniformLocation(name, required); + if (loc < 0) + return; + glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(value)); +} + +void Shader::setTexture(const std::string& name, const Texture& texture, int unit, bool required) +{ + ensureActive(); + glBindTextureUnit(unit, texture.id); + set(name, unit, required); +} + +bool Shader::isActive() const { return activeShaderId == id; } + +void Shader::ensureActive() const +{ + if (!isActive()) + throw std::runtime_error("Shader is not active"); +} + +int Shader::getUniformLocation(const std::string& name, bool required) const +{ + auto iter = uniformLocations.find(name); + if (iter != uniformLocations.end()) + { + return iter->second; + } + int index = glGetUniformLocation(id, name.c_str()); + + // Error if not found? + if (index < 0 && required) + throw std::runtime_error{"Uniform does not exist: " + name}; + + uniformLocations[name] = index; + return index; +} + +static std::string shaderTypeToString(GLenum shaderType) +{ + switch (shaderType) + { + case GL_VERTEX_SHADER: + return "Vertex"; + case GL_FRAGMENT_SHADER: + return "Fragment"; + case GL_GEOMETRY_SHADER: + return "Geometry"; + case GL_TESS_CONTROL_SHADER: + return "Tess Control"; + case GL_TESS_EVALUATION_SHADER: + return "Tess Eval"; + default: + throw std::runtime_error("Unrecognized shader type"); + } +} + +GLuint createShaderObject(const std::string& code, GLenum shaderType) +{ + GLuint shaderObject = glCreateShader(shaderType); + + // Compile shader + logi("Compiling shader type"); + const char* temp = code.c_str(); + glShaderSource(shaderObject, 1, &temp, NULL); + glCompileShader(shaderObject); + + // Check shader + GLint result = GL_FALSE; + glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &result); + + int infoLogLength = 0; + glGetShaderiv(shaderObject, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + std::vector infoLog(infoLogLength + 1); + glGetShaderInfoLog(shaderObject, infoLogLength, NULL, infoLog.data()); + logi("Error while compiling {} shader: {}", shaderTypeToString(shaderType), infoLog.data()); + } + if (result == GL_FALSE) + { + glDeleteShader(shaderObject); + throw std::runtime_error{"Failed to compile shader object"}; + } + + return shaderObject; +} + +GLuint createShaderProgram(const std::string& vertexShaderCode, const std::string& fragmentShaderCode) +{ + GLuint vertexShader = createShaderObject(vertexShaderCode, GL_VERTEX_SHADER); + GLuint fragmentShader = createShaderObject(fragmentShaderCode, GL_FRAGMENT_SHADER); + + // Link the program + logi("Linking shader program"); + GLuint shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + + // Check the program + GLint result = GL_FALSE; + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &result); + + int infoLogLength = 0; + glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength); + if (infoLogLength > 0) + { + std::vector infoLog(infoLogLength + 1); + glGetProgramInfoLog(shaderProgram, infoLogLength, NULL, &infoLog[0]); + logi("Error while linking shader: {}", infoLog.data()); + } + + glDetachShader(shaderProgram, vertexShader); + glDetachShader(shaderProgram, fragmentShader); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + if (result == GL_FALSE) + { + glDeleteProgram(shaderProgram); + throw std::runtime_error{"Failed to link shader program"}; + } + + return shaderProgram; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Shader.h b/Demo/RenderDemo/source/gfx/Shader.h new file mode 100644 index 0000000..3d3faa4 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Shader.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include +#include +#include + +#include "gfx/Texture.h" + +class Shader +{ + public: + Shader(const std::string& vertexShaderCode, const std::string& fragmentShaderCode); + ~Shader(); + + void setActive() const; + + void set(const std::string& name, const int value, bool required = true); + void set(const std::string& name, const unsigned int value, bool required = true); + void set(const std::string& name, const float value, bool required = true); + void set(const std::string& name, const glm::vec2& value, bool required = true); + void set(const std::string& name, const glm::vec3& value, bool required = true); + void set(const std::string& name, const glm::vec4& value, bool required = true); + void set(const std::string& name, const glm::mat4& value, bool required = true); + void setTexture(const std::string& name, const Texture& texture, int unit, bool required = true); + + private: + bool isActive() const; + void ensureActive() const; + int getUniformLocation(const std::string& name, bool required) const; + + // Shader id + GLuint id = 0; + // Cached uniform names with location ids + mutable std::unordered_map uniformLocations; + static GLuint activeShaderId; +}; + +GLuint createShaderObject(const std::string& code, GLenum shaderType); +GLuint createShaderProgram(const std::string& vertexShaderCode, const std::string& fragmentShaderCode); \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/SpotLight.cpp b/Demo/RenderDemo/source/gfx/SpotLight.cpp new file mode 100644 index 0000000..f09358f --- /dev/null +++ b/Demo/RenderDemo/source/gfx/SpotLight.cpp @@ -0,0 +1,18 @@ +#include "gfx/SpotLight.h" + +void SpotLight::set(Shader& shader, const std::string& prefix) const +{ + shader.setActive(); + shader.set(prefix + ".position", position); + shader.set(prefix + ".direction", direction); + shader.set(prefix + ".innerCutOff", std::cos(glm::radians(innerCutOff))); + shader.set(prefix + ".outerCutOff", std::cos(glm::radians(outerCutOff))); + + shader.set(prefix + ".ambient", ambient); + shader.set(prefix + ".diffuse", diffuse); + shader.set(prefix + ".specular", specular); + + shader.set(prefix + ".constant", constant); + shader.set(prefix + ".linear", linear); + shader.set(prefix + ".quadratic", quadratic); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/SpotLight.h b/Demo/RenderDemo/source/gfx/SpotLight.h new file mode 100644 index 0000000..5174525 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/SpotLight.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "gfx/Shader.h" + +class SpotLight +{ + public: + glm::vec3 position = glm::vec3(0.f); + glm::vec3 direction = glm::vec3(0.f, 0.f, 1.f); + + // Attenuation factors with sane defaults + float constant = 1.f; + float linear = 0.09f; + float quadratic = 0.032f; + + // Light + glm::vec3 ambient = glm::vec3(0.1f); + glm::vec3 diffuse = glm::vec3(0.5f); + glm::vec3 specular = glm::vec3(1.f); + + // Cutoff angles in degrees + float innerCutOff = 12.5f; + float outerCutOff = 15.f; + + void set(Shader& shader, const std::string& prefix) const; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Texture.cpp b/Demo/RenderDemo/source/gfx/Texture.cpp new file mode 100644 index 0000000..2ac94d9 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Texture.cpp @@ -0,0 +1,85 @@ +#include "gfx/Texture.h" + +#include +#include +#include + +#define STB_IMAGE_IMPLEMENTATION +#include + +#include + +static std::unordered_map>& getTexturesCache() +{ + static std::unordered_map> cache; + return cache; +} + +void clearTextureCache() { getTexturesCache().clear(); } + +std::shared_ptr textureFromFile(const std::string& fileName, const std::string& directory, + const std::string& typeName) +{ + auto filePath = directory + "/" + fileName; + auto key = filePath + "." + typeName; + // In cache + if (getTexturesCache().find(key) != getTexturesCache().end()) + { + return getTexturesCache().at(key); + } + + GLuint id = textureIdFromFile(fileName, directory); + auto tex = std::make_shared(); + tex->id = id; + tex->fileName = fileName; + tex->type = typeName; + + getTexturesCache()[key] = tex; + return tex; +} + +GLuint textureIdFromFile(const std::string& fileName, const std::string& directory) +{ + // Load with stb_image + auto filePath = directory + "/" + fileName; + logi("Load texture {}", filePath); + + int x = 0; + int y = 0; + int channels = 0; + // Load as RGB + stbi_set_flip_vertically_on_load(true); + const uint8_t* image = stbi_load(filePath.c_str(), &x, &y, &channels, 3); + if (image == nullptr) + { + loge(stbi_failure_reason()); + throw std::runtime_error("Failed to load the texture " + fileName); + } + + GLuint id = 0; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, image); + + glGenerateMipmap(GL_TEXTURE_2D); + + // Wrapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // Filtering + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Unbind + glBindTexture(GL_TEXTURE_2D, 0); + return id; +} + +Texture::~Texture() +{ + if (id == 0) + return; + + glDeleteTextures(1, &id); + id = 0; +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Texture.h b/Demo/RenderDemo/source/gfx/Texture.h new file mode 100644 index 0000000..f957a9c --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Texture.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include +#include + +class Texture +{ + public: + ~Texture(); + + enum class Type + { + Diffuse, + Specular, + Normal, + Height + }; + + GLuint id = 0; + // Either "diffuse_texture" or "specular_texture" + // TODO Use enum + std::string type; + std::string fileName; +}; + +// Texture loading +GLuint textureIdFromFile(const std::string& fileName, const std::string& directory); +// caches +void clearTextureCache(); +std::shared_ptr textureFromFile(const std::string& fileName, const std::string& directory, + const std::string& typeName); diff --git a/Demo/RenderDemo/source/gfx/VertexArrayObject.cpp b/Demo/RenderDemo/source/gfx/VertexArrayObject.cpp new file mode 100644 index 0000000..7fb7817 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/VertexArrayObject.cpp @@ -0,0 +1,7 @@ +#include "gfx/VertexArrayObject.h" + +VertexArrayObject::VertexArrayObject() { glCreateVertexArrays(1, &m_id); } + +VertexArrayObject::~VertexArrayObject() { glDeleteVertexArrays(1, &m_id); } + +GLuint VertexArrayObject::getId() const { return m_id; } \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/VertexArrayObject.h b/Demo/RenderDemo/source/gfx/VertexArrayObject.h new file mode 100644 index 0000000..be707ae --- /dev/null +++ b/Demo/RenderDemo/source/gfx/VertexArrayObject.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +class VertexArrayObject +{ + public: + VertexArrayObject(); + ~VertexArrayObject(); + + GLuint getId() const; + + private: + GLuint m_id = 0; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/VertexBuffer.cpp b/Demo/RenderDemo/source/gfx/VertexBuffer.cpp new file mode 100644 index 0000000..44cf8ed --- /dev/null +++ b/Demo/RenderDemo/source/gfx/VertexBuffer.cpp @@ -0,0 +1,50 @@ +#include "gfx/VertexBuffer.h" + +#include + +VertexBuffer::VertexBuffer(const float* data, std::size_t size, const std::vector& componentsPerAttribute) +{ + // Buffer can have multiple interleaved attributes with varying component counts + // One entry has 1-n attributes + for (auto components : componentsPerAttribute) + { + if (components > 4) + throw std::runtime_error("Invalid number of components"); + AttributeDescriptor desc; + desc.componentCount = components; + desc.offset = m_entrySize * sizeof(float); + m_entrySize += components; + m_attributes.push_back(desc); + } + + if (size % m_entrySize != 0) + throw std::runtime_error("Invalid number of components for size"); + + m_entries = size / m_entrySize; + + // To bytes per entry + m_entrySize *= sizeof(float); + glCreateBuffers(1, &m_id); + glNamedBufferData(m_id, size * sizeof(float), data, GL_STATIC_DRAW); +} + +VertexBuffer::~VertexBuffer() +{ + // + glDeleteBuffers(1, &m_id); +} + +void VertexBuffer::bind(GLenum target) +{ + // + glBindBuffer(target, m_id); +} + +const std::vector& VertexBuffer::getAttributes() const { return m_attributes; } + +unsigned int VertexBuffer::getEntryCount() const { return m_entries; } + +unsigned int VertexBuffer::getStride() const { return m_entrySize; } + +GLenum VertexBuffer::getType() const +{ return GL_FLOAT; } \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/VertexBuffer.h b/Demo/RenderDemo/source/gfx/VertexBuffer.h new file mode 100644 index 0000000..aa4c2f5 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/VertexBuffer.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include +#include + +class VertexBuffer +{ + public: + struct AttributeDescriptor + { + unsigned int componentCount = 0; + // Initial offset + unsigned long long offset = 0; + }; + // From raw data + // size is number of array elements, NOT bytes + VertexBuffer(const float* data, std::size_t size, const std::vector& componentCountPerAttribute); + ~VertexBuffer(); + + void bind(GLenum target); + + const std::vector& getAttributes() const; + // Total number of entries / indices + unsigned int getEntryCount() const; + // Stride between entries in byte + unsigned int getStride() const; + GLenum getType() const; + + private: + std::vector m_attributes; + + // One data entry consists of one or multiple components + // Total number of values in the buffer is m_enries * m_components + // Total buffer size in bytes is m_entries * m_components * sizeof(componentType) + // Total number of data entries in the buffer + GLuint m_id = 0; + // Number of entries / indices + unsigned int m_entries = 0; + // Total size of an entry in bytes + unsigned int m_entrySize = 0; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Window.cpp b/Demo/RenderDemo/source/gfx/Window.cpp new file mode 100644 index 0000000..cb31871 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Window.cpp @@ -0,0 +1,295 @@ +#include "gfx/Window.h" + +#include + +#include +#include +#include + +static void APIENTRY glDebugOutput(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar* message, const void* userParam) +{ + // ignore non-significant error/warning codes + if (id == 131169 || id == 131185 || id == 131218 || id == 131204) + return; + + std::stringstream ss; + ss << "Debug message (" << id << "): " << message << std::endl; + + switch (source) + { + case GL_DEBUG_SOURCE_API: + ss << "Source: API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + ss << "Source: Window System"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: + ss << "Source: Shader Compiler"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY: + ss << "Source: Third Party"; + break; + case GL_DEBUG_SOURCE_APPLICATION: + ss << "Source: Application"; + break; + case GL_DEBUG_SOURCE_OTHER: + ss << "Source: Other"; + break; + } + ss << std::endl; + + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + ss << "Type: Error"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + ss << "Type: Deprecated Behaviour"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + ss << "Type: Undefined Behaviour"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + ss << "Type: Portability"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + ss << "Type: Performance"; + break; + case GL_DEBUG_TYPE_MARKER: + ss << "Type: Marker"; + break; + case GL_DEBUG_TYPE_PUSH_GROUP: + ss << "Type: Push Group"; + break; + case GL_DEBUG_TYPE_POP_GROUP: + ss << "Type: Pop Group"; + break; + case GL_DEBUG_TYPE_OTHER: + ss << "Type: Other"; + break; + } + ss << std::endl; + + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + ss << "Severity: high"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + ss << "Severity: medium"; + break; + case GL_DEBUG_SEVERITY_LOW: + ss << "Severity: low"; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + ss << "Severity: notification"; + + break; + } + loge("{}", ss.str()); + throw std::runtime_error(ss.str()); +} + +Window* Window::s_window = nullptr; + +Window::Window(unsigned int width, unsigned int height, const char* title) : m_width(width), m_height(height) +{ + if (s_window != nullptr) + { + throw std::runtime_error{"Only single window allowed"}; + } + s_window = this; + + // Init glfw + if (glfwInit() != GLFW_TRUE) + { + throw std::runtime_error{"Failed to init glfw"}; + } + + // Setup error callback + glfwSetErrorCallback([](int code, const char* error) { throw std::runtime_error{error}; }); + + // Setup for Opengl context + glfwWindowHint(GLFW_SAMPLES, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + // Create window + m_window = glfwCreateWindow(width, height, title, nullptr, nullptr); + if (m_window == nullptr) + { + glfwTerminate(); + throw std::runtime_error{"Failed to create window"}; + } + + // Key callback + glfwSetKeyCallback(m_window, + [](GLFWwindow* w, int key, int code, int action, int mods) + { + if (Window::s_window == nullptr) + return; + Window::s_window->onKeyPress(key, code, action, mods); + }); + + // Mouse move callback + glfwSetCursorPosCallback(m_window, + [](GLFWwindow* w, double x, double y) + { + if (Window::s_window == nullptr) + return; + Window::s_window->onCursorMove(x, y); + }); + + // Scrolling callback + glfwSetScrollCallback(m_window, + [](GLFWwindow* w, double xOffset, double yOffset) + { + if (Window::s_window == nullptr) + return; + Window::s_window->onScroll(xOffset, yOffset); + }); + + // Set active context + glfwMakeContextCurrent(m_window); + + glfwSetFramebufferSizeCallback(m_window, + [](GLFWwindow* window, int width, int height) + { + if (Window::s_window == nullptr) + return; + glViewport(0, 0, width, height); + Window::s_window->onResize(width, height); + }); + + // Load opengl functions + if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) + { + throw std::runtime_error{"Failed to init GL context"}; + } + + // Debug context + int flags; + glGetIntegerv(GL_CONTEXT_FLAGS, &flags); + if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) + { + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(glDebugOutput, nullptr); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); + } + + // Initial viewport is the entire window + glViewport(0, 0, width, height); +} + +Window::~Window() +{ + if (m_window != nullptr) + { + glfwDestroyWindow(m_window); + } + glfwTerminate(); + s_window = nullptr; +} + +void Window::swapBuffers() { glfwSwapBuffers(m_window); } + +void Window::setVSync(bool sync) +{ + if (sync) + { + glfwSwapInterval(1); + } + else + { + glfwSwapInterval(0); + } +} + +void Window::pollEvents() +{ + // Reset offsets + m_cursorMovement = glm::vec2{0.f}; + m_scrollOffset = glm::vec2{0.f}; + + // Poll for events, triggers callbacks + glfwPollEvents(); +} + +void Window::close() { glfwSetWindowShouldClose(m_window, GLFW_TRUE); } + +void Window::setKeyCallback(const KeyCallback& callback) { m_keyCallback = callback; } + +bool Window::isOpen() const { return glfwWindowShouldClose(m_window) == GLFW_FALSE; } + +int Window::getKey(int code) const { return glfwGetKey(m_window, code); } + +float Window::getAspectRation() const { return (float)getWidth() / (float)getHeight(); } + +glm::mat4 Window::getProjection(float fieldOfView, float zNear, float zFar) const +{ + return glm::perspective(glm::radians(fieldOfView), getAspectRation(), zNear, zFar); +} + +const glm::vec2& Window::getCursorMovement() const { return m_cursorMovement; } + +const glm::vec2& Window::getScrollOffset() const { return m_scrollOffset; } + +void Window::setCursorCapture(bool capture) +{ + if (m_cursorCaptured == capture) + return; + + m_cursorCaptured = capture; + if (capture) + { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + else + { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } +} + +bool Window::getCursorCapture() const { return m_cursorCaptured; } + +GLFWwindow* Window::getGLFWWindow() const { return m_window; } + +unsigned int Window::getWidth() const { return m_width; } +unsigned int Window::getHeight() const { return m_height; } + +void Window::onResize(unsigned int width, unsigned int height) +{ + m_width = width; + m_height = height; +} + +void Window::onCursorMove(double x, double y) +{ + auto position = glm::vec2{x, y}; + // Prevent huge movement delta on initial call + if (m_firstCursorMove) + { + m_firstCursorMove = false; + } + else + { + m_cursorMovement = position - m_cursorPosition; + // Inverted due to different axis directions + m_cursorMovement.y = -m_cursorMovement.y; + } + m_cursorPosition = position; +} + +void Window::onScroll(double xOffset, double yOffset) { m_scrollOffset = glm::vec2{xOffset, yOffset}; } + +void Window::onKeyPress(int key, int code, int action, int mods) +{ + // Default mappings + if (m_keyCallback != nullptr) + m_keyCallback(*this, key, code, action, mods); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/gfx/Window.h b/Demo/RenderDemo/source/gfx/Window.h new file mode 100644 index 0000000..1cd5809 --- /dev/null +++ b/Demo/RenderDemo/source/gfx/Window.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#define GLFW_INCLUDE_NONE +#include + +#include + +class Window +{ + public: + Window(unsigned int width, unsigned int height, const char* title); + ~Window(); + + using KeyCallback = void (*)(Window&, int, int, int, int); + using MousePositionCallback = void (*)(Window&, double, double); + + void swapBuffers(); + + void setVSync(bool sync); + + void pollEvents(); + + void close(); + + void setKeyCallback(const KeyCallback& callback); + + bool isOpen() const; + + // Get key state + int getKey(int code) const; + + float getAspectRation() const; + glm::mat4 getProjection(float fieldOfView, float zNear, float zFar) const; + + // Movement delta since last frame + const glm::vec2& getCursorMovement() const; + const glm::vec2& getScrollOffset() const; + + // Capture mouse cursor in window area + void setCursorCapture(bool capture); + bool getCursorCapture() const; + + GLFWwindow* getGLFWWindow() const; + + unsigned int getWidth() const; + unsigned int getHeight() const; + + private: + void onResize(unsigned int width, unsigned int height); + void onCursorMove(double x, double y); + void onScroll(double xOffset, double yOffset); + void onKeyPress(int key , int code, int action, int mods); + + unsigned int m_width = 0; + unsigned int m_height = 0; + + // Scrolling offset + glm::vec2 m_scrollOffset = glm::vec2{0.f}; + + // Mouse capture, default off, toggle with f1 + bool m_cursorCaptured = false; + + glm::vec2 m_cursorPosition = glm::vec2(0.f); + // First mouse position / movement + // To prevent huge move vector on first call + bool m_firstCursorMove = true; + // Mouse movement delta + glm::vec2 m_cursorMovement = glm::vec2{0.f}; + + KeyCallback m_keyCallback = nullptr; + GLFWwindow* m_window = nullptr; + + static Window* s_window; +}; \ No newline at end of file diff --git a/Demo/RenderDemo/source/imgui/imgui_imp_opengl3.cpp b/Demo/RenderDemo/source/imgui/imgui_imp_opengl3.cpp new file mode 100644 index 0000000..a0e88a7 --- /dev/null +++ b/Demo/RenderDemo/source/imgui/imgui_imp_opengl3.cpp @@ -0,0 +1,759 @@ +// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 2.x 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about +// ImTextureID! [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX. +// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix. +// 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable +// ImGuiBackendFlags_RendererHasVtxOffset. 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader. +// 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader. +// 2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use +// glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders. 2019-09-22: OpenGL: Detect default GL loader using +// __has_include compiler facility. 2019-09-16: OpenGL: Tweak initialization code to allow application calling +// ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call. 2019-05-29: OpenGL: Desktop GL only: Added +// support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. 2019-04-30: OpenGL: +// Added support for special ImDrawCallback_ResetRenderState callback to reset render state. 2019-03-29: OpenGL: Not +// calling glBindBuffer more than necessary in the render loop. 2019-03-15: OpenGL: Added a dummy GL call + comments in +// ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. 2019-03-03: OpenGL: Fix support for +// ES 2.0 (WebGL 1.0). 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN +// even if defined by the headers/loader. 2019-02-11: OpenGL: Projecting clipping rectangles correctly using +// draw_data->FramebufferScale to allow multi-viewports for retina display. 2019-02-01: OpenGL: Using GLSL 410 shaders +// for any version over 410 (e.g. 430, 450). 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed +// in the About Window. 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN. +// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader +// can be used. 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 +// ES". 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. 2018-07-10: OpenGL: +// Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to +// compile/link. 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 +// examples. 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and +// clipping rectangle. 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since +// this is part of the VAO state. 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't +// fail if the function is a NULL pointer. 2018-03-06: OpenGL: Added const char* glsl_version parameter to +// ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150". 2018-02-23: OpenGL: Create the +// VAO in the render function so the setup can more easily be used with multiple shared GL context. 2018-02-16: Misc: +// Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can +// call it yourself. 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. 2017-09-01: OpenGL: Save and +// restore current bound sampler. Save and restore current polygon mode. 2017-05-01: OpenGL: Fixed save and restore of +// current blend func state. 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. 2016-09-05: +// OpenGL: Fixed save and restore of current scissor rectangle. 2016-07-29: OpenGL: Explicitly setting +// GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) + +//---------------------------------------- +// OpenGL GLSL GLSL +// version version string +//---------------------------------------- +// 2.0 110 "#version 110" +// 2.1 120 "#version 120" +// 3.0 130 "#version 130" +// 3.1 140 "#version 140" +// 3.2 150 "#version 150" +// 3.3 330 "#version 330 core" +// 4.0 400 "#version 400 core" +// 4.1 410 "#version 410 core" +// 4.2 420 "#version 410 core" +// 4.3 430 "#version 430 core" +// ES 2.0 100 "#version 100" = WebGL 1.0 +// ES 3.0 300 "#version 300 es" = WebGL 2.0 +//---------------------------------------- + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include + +#include "imgui.h" +#include "imgui_impl_opengl3.h" +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// GL includes +#if defined(IMGUI_IMPL_OPENGL_ES2) +#include +#elif defined(IMGUI_IMPL_OPENGL_ES3) +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) +#include // Use GL ES 3 +#else +#include // Use GL ES 3 +#endif +#else +// About Desktop OpenGL function loaders: +// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. +// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). +// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) +#include // Needs to be initialized with gl3wInit() in user's code +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) +#include // Needs to be initialized with glewInit() in user's code. +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) +#include // Needs to be initialized with gladLoadGL() in user's code. +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#ifndef GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#endif +#include // Needs to be initialized with glbinding::Binding::initialize() in user's code. +#include +using namespace gl; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#ifndef GLFW_INCLUDE_NONE +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#endif +#include +#include // Needs to be initialized with glbinding::initialize() in user's code. +using namespace gl; +#else +#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM +#endif +#endif + +// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have. +#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) || !defined(GL_VERSION_3_2) +#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET 0 +#else +#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET 1 +#endif + +// OpenGL Data +static GLuint g_GlVersion = + 0; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) +static char g_GlslVersionString[32] = ""; // Specified by user or detected based on compile time GL settings. +static GLuint g_FontTexture = 0; +static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location +static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, + g_AttribLocationVtxColor = 0; // Vertex attributes location +static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; + +// Functions +bool ImGui_ImplOpenGL3_Init(const char* glsl_version) +{ + // Query for GL version (e.g. 320 for GL 3.2) +#if !defined(IMGUI_IMPL_OPENGL_ES2) + GLint major, minor; + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + g_GlVersion = major * 100 + minor * 10; +#else + g_GlVersion = 200; // GLES 2 +#endif + + // Setup back-end capabilities flags + ImGuiIO& io = ImGui::GetIO(); + io.BackendRendererName = "imgui_impl_opengl3"; +#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET + if (g_GlVersion >= 320) + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, + // allowing for large meshes. +#endif + + // Store GLSL version string so we can refer to it later in case we recreate shaders. + // Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. +#if defined(IMGUI_IMPL_OPENGL_ES2) + if (glsl_version == NULL) + glsl_version = "#version 100"; +#elif defined(IMGUI_IMPL_OPENGL_ES3) + if (glsl_version == NULL) + glsl_version = "#version 300 es"; +#elif defined(__APPLE__) + if (glsl_version == NULL) + glsl_version = "#version 150"; +#else + if (glsl_version == NULL) + glsl_version = "#version 130"; +#endif + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString)); + strcpy(g_GlslVersionString, glsl_version); + strcat(g_GlslVersionString, "\n"); + + // Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected. + // The code actually never uses the 'gl_loader' variable! It is only here so you can read it! + // If auto-detection fails or doesn't select the same GL loader file as used by your application, + // you are likely to get a crash below. + // You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler + // command-line. + const char* gl_loader = "Unknown"; + IM_UNUSED(gl_loader); +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) + gl_loader = "GL3W"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) + gl_loader = "GLEW"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) + gl_loader = "GLAD"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + gl_loader = "glbinding2"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) + gl_loader = "glbinding3"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + gl_loader = "custom"; +#else + gl_loader = "none"; +#endif + + // Make a dummy GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this + // code. Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. + GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + + return true; +} + +void ImGui_ImplOpenGL3_Shutdown() { ImGui_ImplOpenGL3_DestroyDeviceObjects(); } + +void ImGui_ImplOpenGL3_NewFrame() +{ + if (!g_ShaderHandle) + ImGui_ImplOpenGL3_CreateDeviceObjects(); +} + +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, + GLuint vertex_array_object) +{ + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); +#ifdef GL_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif + + // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + bool clip_origin_lower_left = true; +#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) + GLenum current_clip_origin = 0; + glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); + if (current_clip_origin == GL_UPPER_LEFT) + clip_origin_lower_left = false; +#endif + + // Setup viewport, orthographic projection matrix + // Our visible imgui space lies from draw_data->DisplayPos (top left) to + // draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + float L = draw_data->DisplayPos.x; + float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; + float T = draw_data->DisplayPos.y; + float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + if (!clip_origin_lower_left) + { + float tmp = T; + T = B; + B = tmp; + } // Swap top and bottom if origin is upper left + const float ortho_projection[4][4] = { + {2.0f / (R - L), 0.0f, 0.0f, 0.0f}, + {0.0f, 2.0f / (T - B), 0.0f, 0.0f}, + {0.0f, 0.0f, -1.0f, 0.0f}, + {(R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f}, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); +#ifdef GL_SAMPLER_BINDING + glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. +#endif + + (void)vertex_array_object; +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(vertex_array_object); +#endif + + // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glEnableVertexAttribArray(g_AttribLocationVtxPos); + glEnableVertexAttribArray(g_AttribLocationVtxUV); + glEnableVertexAttribArray(g_AttribLocationVtxColor); + glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), + (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); +} + +// OpenGL3 Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from +// your main loop) Note that this implementation is little overcomplicated because we are saving/setting up/restoring +// every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. +void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer + // coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + // Backup GL state + GLenum last_active_texture; + glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); + glActiveTexture(GL_TEXTURE0); + GLint last_program; + glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); +#ifdef GL_SAMPLER_BINDING + GLint last_sampler; + glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); +#endif + GLint last_array_buffer; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + GLint last_vertex_array_object; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); +#endif +#ifdef GL_POLYGON_MODE + GLint last_polygon_mode[2]; + glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +#endif + GLint last_viewport[4]; + glGetIntegerv(GL_VIEWPORT, last_viewport); + GLint last_scissor_box[4]; + glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); + GLenum last_blend_src_rgb; + glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; + glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; + glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + + // Setup desired GL state + // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared + // among GL contexts) The renderer would actually work without any VAO bound, but then our VertexAttrib calls would + // overwrite the default one currently bound. + GLuint vertex_array_object = 0; +#ifndef IMGUI_IMPL_OPENGL_ES2 + glGenVertexArrays(1, &vertex_array_object); +#endif + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + + // Upload vertex/index buffers + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), + (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), + (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != NULL) + { + // User callback, registered via ImDrawList::AddCallback() + // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer + // to reset render state.) + if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + else + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec4 clip_rect; + clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; + clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; + clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; + clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; + + if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) + { + // Apply scissor/clipping rectangle + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), + (int)(clip_rect.w - clip_rect.y)); + + // Bind texture, Draw + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); +#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET + if (g_GlVersion >= 320) + glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, + (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), + (GLint)pcmd->VtxOffset); + else +#endif + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, + sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, + (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))); + } + } + } + } + + // Destroy the temporary VAO +#ifndef IMGUI_IMPL_OPENGL_ES2 + glDeleteVertexArrays(1, &vertex_array_object); +#endif + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); +#ifdef GL_SAMPLER_BINDING + glBindSampler(0, last_sampler); +#endif + glActiveTexture(last_active_texture); +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(last_vertex_array_object); +#endif + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); + if (last_enable_blend) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + if (last_enable_cull_face) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + if (last_enable_depth_test) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); +#ifdef GL_POLYGON_MODE + glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +#endif + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); + glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); +} + +bool ImGui_ImplOpenGL3_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32( + &pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) + // because it is more likely to be compatible with user's existing shaders. If your + // ImTextureId represent a higher-level concept than just a GL texture id, consider + // calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#ifdef GL_UNPACK_ROW_LENGTH + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +#endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL3_DestroyFontsTexture() +{ + if (g_FontTexture) + { + ImGuiIO& io = ImGui::GetIO(); + glDeleteTextures(1, &g_FontTexture); + io.Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL +// version table at the top of this file. +static bool CheckShader(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetShaderiv(handle, GL_COMPILE_STATUS, &status); + glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetShaderInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +// If you get an error please report on GitHub. You may try different GL context version or GLSL version. +static bool CheckProgram(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetProgramiv(handle, GL_LINK_STATUS, &status); + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + if ((GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, + g_GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize((int)(log_length + 1)); + glGetProgramInfoLog(handle, log_length, NULL, (GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + } + return (GLboolean)status == GL_TRUE; +} + +bool ImGui_ImplOpenGL3_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + GLint last_vertex_array; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +#endif + + // Parse GLSL version string + int glsl_version = 130; + sscanf(g_GlslVersionString, "#version %d", &glsl_version); + + const GLchar* vertex_shader_glsl_120 = + "uniform mat4 ProjMtx;\n" + "attribute vec2 Position;\n" + "attribute vec2 UV;\n" + "attribute vec4 Color;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* vertex_shader_glsl_130 = + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* vertex_shader_glsl_300_es = + "precision mediump float;\n" + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* vertex_shader_glsl_410_core = + "layout (location = 0) in vec2 Position;\n" + "layout (location = 1) in vec2 UV;\n" + "layout (location = 2) in vec4 Color;\n" + "uniform mat4 ProjMtx;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_120 = + "#ifdef GL_ES\n" + " precision mediump float;\n" + "#endif\n" + "uniform sampler2D Texture;\n" + "varying vec2 Frag_UV;\n" + "varying vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_130 = + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_300_es = + "precision mediump float;\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + const GLchar* fragment_shader_glsl_410_core = + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "uniform sampler2D Texture;\n" + "layout (location = 0) out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n" + "}\n"; + + // Select shaders matching our GLSL versions + const GLchar* vertex_shader = NULL; + const GLchar* fragment_shader = NULL; + if (glsl_version < 130) + { + vertex_shader = vertex_shader_glsl_120; + fragment_shader = fragment_shader_glsl_120; + } + else if (glsl_version >= 410) + { + vertex_shader = vertex_shader_glsl_410_core; + fragment_shader = fragment_shader_glsl_410_core; + } + else if (glsl_version == 300) + { + vertex_shader = vertex_shader_glsl_300_es; + fragment_shader = fragment_shader_glsl_300_es; + } + else + { + vertex_shader = vertex_shader_glsl_130; + fragment_shader = fragment_shader_glsl_130; + } + + // Create shaders + const GLchar* vertex_shader_with_version[2] = {g_GlslVersionString, vertex_shader}; + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glCompileShader(g_VertHandle); + CheckShader(g_VertHandle, "vertex shader"); + + const GLchar* fragment_shader_with_version[2] = {g_GlslVersionString, fragment_shader}; + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); + glCompileShader(g_FragHandle); + CheckShader(g_FragHandle, "fragment shader"); + + g_ShaderHandle = glCreateProgram(); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + CheckProgram(g_ShaderHandle, "shader program"); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + // Create buffers + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + ImGui_ImplOpenGL3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +#ifndef IMGUI_IMPL_OPENGL_ES2 + glBindVertexArray(last_vertex_array); +#endif + + return true; +} + +void ImGui_ImplOpenGL3_DestroyDeviceObjects() +{ + if (g_VboHandle) + { + glDeleteBuffers(1, &g_VboHandle); + g_VboHandle = 0; + } + if (g_ElementsHandle) + { + glDeleteBuffers(1, &g_ElementsHandle); + g_ElementsHandle = 0; + } + if (g_ShaderHandle && g_VertHandle) + { + glDetachShader(g_ShaderHandle, g_VertHandle); + } + if (g_ShaderHandle && g_FragHandle) + { + glDetachShader(g_ShaderHandle, g_FragHandle); + } + if (g_VertHandle) + { + glDeleteShader(g_VertHandle); + g_VertHandle = 0; + } + if (g_FragHandle) + { + glDeleteShader(g_FragHandle); + g_FragHandle = 0; + } + if (g_ShaderHandle) + { + glDeleteProgram(g_ShaderHandle); + g_ShaderHandle = 0; + } + + ImGui_ImplOpenGL3_DestroyFontsTexture(); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/imgui/imgui_impl_glfw.cpp b/Demo/RenderDemo/source/imgui/imgui_impl_glfw.cpp new file mode 100644 index 0000000..c1f1749 --- /dev/null +++ b/Demo/RenderDemo/source/imgui/imgui_impl_glfw.cpp @@ -0,0 +1,393 @@ +// dear imgui: Platform Binding for GLFW +// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..) +// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context +// creation, etc.) (Requires: GLFW 3.1+) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= +// ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+). [X] Platform: Keyboard arrays +// indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE). + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and +// it generates errors. 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, +// not allowed cursor). 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown. 2019-07-21: +// Inputs: Added mapping for ImGuiKey_KeyPadEnter. 2019-05-11: Inputs: Don't filter value from character callback +// before calling AddInputCharacter(). 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is +// minimized. 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. +// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and +// chain call them. 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. +// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. +// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples. +// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor +// ImGuiConfigFlags_NoMouseCursorChange flag. 2018-02-20: Inputs: Added support for mouse cursors +// (ImGui::GetMouseCursor() value, passed to glfwSetCursor()). 2018-02-06: Misc: Removed call to ImGui::Shutdown() +// which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. 2018-02-06: +// Inputs: Added mapping for ImGuiKey_Space. 2018-01-25: Inputs: Added gamepad support if +// ImGuiConfigFlags_NavEnableGamepad is set. 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the +// mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). 2018-01-20: Inputs: Added Horizontal Mouse +// Wheel support. 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. 2017-08-25: Inputs: MousePos set to +// -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). 2016-10-15: Misc: Added a void* user_data +// parameter to Clipboard function handlers. + +#include "imgui_impl_glfw.h" + +#include "imgui.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#include // for glfwGetWin32Window +#endif +#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING +#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED +#define GLFW_HAS_WINDOW_ALPHA \ + (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity +#define GLFW_HAS_PER_MONITOR_DPI \ + (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale +#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface +#ifdef GLFW_RESIZE_NESW_CURSOR // let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and + // 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released? +#define GLFW_HAS_NEW_CURSORS \ + (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= \ + 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR +#else +#define GLFW_HAS_NEW_CURSORS (0) +#endif + +// Data +enum GlfwClientApi +{ + GlfwClientApi_Unknown, + GlfwClientApi_OpenGL, + GlfwClientApi_Vulkan +}; +static GLFWwindow* g_Window = NULL; // Main window +static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; +static double g_Time = 0.0; +static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; +static bool g_InstalledCallbacks = false; + +// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. +static GLFWmousebuttonfun g_PrevUserCallbackMousebutton = NULL; +static GLFWscrollfun g_PrevUserCallbackScroll = NULL; +static GLFWkeyfun g_PrevUserCallbackKey = NULL; +static GLFWcharfun g_PrevUserCallbackChar = NULL; + +static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) +{ + return glfwGetClipboardString((GLFWwindow*)user_data); +} + +static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) +{ + glfwSetClipboardString((GLFWwindow*)user_data, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) +{ + if (g_PrevUserCallbackMousebutton != NULL) + g_PrevUserCallbackMousebutton(window, button, action, mods); + + if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(g_MouseJustPressed)) + g_MouseJustPressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) +{ + if (g_PrevUserCallbackScroll != NULL) + g_PrevUserCallbackScroll(window, xoffset, yoffset); + + ImGuiIO& io = ImGui::GetIO(); + io.MouseWheelH += (float)xoffset; + io.MouseWheel += (float)yoffset; +} + +void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (g_PrevUserCallbackKey != NULL) + g_PrevUserCallbackKey(window, key, scancode, action, mods); + + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; +#ifdef _WIN32 + io.KeySuper = false; +#else + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +#endif +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) +{ + if (g_PrevUserCallbackChar != NULL) + g_PrevUserCallbackChar(window, c); + + ImGuiIO& io = ImGui::GetIO(); + io.AddInputCharacter(c); +} + +static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) +{ + g_Window = window; + g_Time = 0.0; + + // Setup back-end capabilities flags + ImGuiIO& io = ImGui::GetIO(); + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= + ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + io.BackendPlatformName = "imgui_impl_glfw"; + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; + io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_KeyPadEnter] = GLFW_KEY_KP_ENTER; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; + io.ClipboardUserData = g_Window; +#if defined(_WIN32) + io.ImeWindowHandle = (void*)glfwGetWin32Window(g_Window); +#endif + + // Create mouse cursors + // (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist, + // GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting. + // Missing cursors will return NULL and our _UpdateMouseCursor() function will use the Arrow cursor instead.) + GLFWerrorfun prev_error_callback = glfwSetErrorCallback(NULL); + g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR); +#if GLFW_HAS_NEW_CURSORS + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_RESIZE_ALL_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_RESIZE_NESW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR); +#else + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); +#endif + glfwSetErrorCallback(prev_error_callback); + + // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. + g_PrevUserCallbackMousebutton = NULL; + g_PrevUserCallbackScroll = NULL; + g_PrevUserCallbackKey = NULL; + g_PrevUserCallbackChar = NULL; + if (install_callbacks) + { + g_InstalledCallbacks = true; + g_PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + g_PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + g_PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + g_PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + g_ClientApi = client_api; + return true; +} + +bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks) +{ + return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL); +} + +bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks) +{ + return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan); +} + +void ImGui_ImplGlfw_Shutdown() +{ + if (g_InstalledCallbacks) + { + glfwSetMouseButtonCallback(g_Window, g_PrevUserCallbackMousebutton); + glfwSetScrollCallback(g_Window, g_PrevUserCallbackScroll); + glfwSetKeyCallback(g_Window, g_PrevUserCallbackKey); + glfwSetCharCallback(g_Window, g_PrevUserCallbackChar); + g_InstalledCallbacks = false; + } + + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) + { + glfwDestroyCursor(g_MouseCursors[cursor_n]); + g_MouseCursors[cursor_n] = NULL; + } + g_ClientApi = GlfwClientApi_Unknown; +} + +static void ImGui_ImplGlfw_UpdateMousePosAndButtons() +{ + // Update buttons + ImGuiIO& io = ImGui::GetIO(); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + { + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events + // that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0; + g_MouseJustPressed[i] = false; + } + + // Update mouse position + const ImVec2 mouse_pos_backup = io.MousePos; + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); +#ifdef __EMSCRIPTEN__ + const bool focused = true; // Emscripten +#else + const bool focused = glfwGetWindowAttrib(g_Window, GLFW_FOCUSED) != 0; +#endif + if (focused) + { + if (io.WantSetMousePos) + { + glfwSetCursorPos(g_Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); + } + else + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); + } + } +} + +static void ImGui_ImplGlfw_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || + glfwGetInputMode(g_Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) + return; + + ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + } + else + { + // Show OS mouse cursor + // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here. + glfwSetCursor(g_Window, g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] + : g_MouseCursors[ImGuiMouseCursor_Arrow]); + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } +} + +static void ImGui_ImplGlfw_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + memset(io.NavInputs, 0, sizeof(io.NavInputs)); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + +// Update gamepad inputs +#define MAP_BUTTON(NAV_NO, BUTTON_NO) \ + { \ + if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) \ + io.NavInputs[NAV_NO] = 1.0f; \ + } +#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) \ + { \ + float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; \ + v = (v - V0) / (V1 - V0); \ + if (v > 1.0f) \ + v = 1.0f; \ + if (io.NavInputs[NAV_NO] < v) \ + io.NavInputs[NAV_NO] = v; \ + } + int axes_count = 0, buttons_count = 0; + const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axes_count); + const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &buttons_count); + MAP_BUTTON(ImGuiNavInput_Activate, 0); // Cross / A + MAP_BUTTON(ImGuiNavInput_Cancel, 1); // Circle / B + MAP_BUTTON(ImGuiNavInput_Menu, 2); // Square / X + MAP_BUTTON(ImGuiNavInput_Input, 3); // Triangle / Y + MAP_BUTTON(ImGuiNavInput_DpadLeft, 13); // D-Pad Left + MAP_BUTTON(ImGuiNavInput_DpadRight, 11); // D-Pad Right + MAP_BUTTON(ImGuiNavInput_DpadUp, 10); // D-Pad Up + MAP_BUTTON(ImGuiNavInput_DpadDown, 12); // D-Pad Down + MAP_BUTTON(ImGuiNavInput_FocusPrev, 4); // L1 / LB + MAP_BUTTON(ImGuiNavInput_FocusNext, 5); // R1 / RB + MAP_BUTTON(ImGuiNavInput_TweakSlow, 4); // L1 / LB + MAP_BUTTON(ImGuiNavInput_TweakFast, 5); // R1 / RB + MAP_ANALOG(ImGuiNavInput_LStickLeft, 0, -0.3f, -0.9f); + MAP_ANALOG(ImGuiNavInput_LStickRight, 0, +0.3f, +0.9f); + MAP_ANALOG(ImGuiNavInput_LStickUp, 1, +0.3f, +0.9f); + MAP_ANALOG(ImGuiNavInput_LStickDown, 1, -0.3f, -0.9f); +#undef MAP_BUTTON +#undef MAP_ANALOG + if (axes_count > 0 && buttons_count > 0) + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; + else + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; +} + +void ImGui_ImplGlfw_NewFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.Fonts->IsBuilt() && + "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer " + "_NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + if (w > 0 && h > 0) + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); + g_Time = current_time; + + ImGui_ImplGlfw_UpdateMousePosAndButtons(); + ImGui_ImplGlfw_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplGlfw_UpdateGamepads(); +} \ No newline at end of file diff --git a/Demo/RenderDemo/source/imgui/imgui_impl_glfw.h b/Demo/RenderDemo/source/imgui/imgui_impl_glfw.h new file mode 100644 index 0000000..2973124 --- /dev/null +++ b/Demo/RenderDemo/source/imgui/imgui_impl_glfw.h @@ -0,0 +1,39 @@ +// dear imgui: Platform Binding for GLFW +// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..) +// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context +// creation, etc.) + +// Implemented features: +// [X] Platform: Clipboard support. +// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. +// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= +// ImGuiConfigFlags_NoMouseCursorChange'. FIXME: 3 cursors types are missing from GLFW. [X] Platform: Keyboard arrays +// indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE). + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// About GLSL version: +// The 'glsl_version' initialization parameter defaults to "#version 150" if NULL. +// Only override if your GL version doesn't handle this GLSL version. Keep NULL if unsure! + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API + +struct GLFWwindow; + +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks); +IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); + +// GLFW callbacks +// - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's +// previously installed callbacks, if any. +// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those +// function yourself from your own GLFW callbacks. +IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); \ No newline at end of file diff --git a/Demo/RenderDemo/source/imgui/imgui_impl_opengl3.h b/Demo/RenderDemo/source/imgui/imgui_impl_opengl3.h new file mode 100644 index 0000000..0fe4019 --- /dev/null +++ b/Demo/RenderDemo/source/imgui/imgui_impl_opengl3.h @@ -0,0 +1,82 @@ +// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline +// - Desktop GL: 2.x 3.x 4.x +// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) + +// Implemented features: +// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about +// ImTextureID! [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +// About Desktop OpenGL function loaders: +// Modern Desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. +// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). +// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. + +// About GLSL version: +// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. +// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version +// 300 es" Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of +// imgui_impl_opengl3.cpp. + +#pragma once +#include // IMGUI_IMPL_API + +// Backend API +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); + +// (Optional) Called by Init/NewFrame/Shutdown +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); +IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); +IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); + +// Specific OpenGL ES versions +//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten +//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android + +// Attempt to auto-detect the default Desktop GL loader based on available header files. +// If auto-detection fails or doesn't select the same GL loader file as used by your application, +// you are likely to get a crash in ImGui_ImplOpenGL3_Init(). +// You can explicitly select a loader by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or +// compiler command-line. +#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) && \ + !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) && \ + !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) && \ + !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + +// Try to detect GLES on matching platforms +#if defined(__APPLE__) +#include "TargetConditionals.h" +#endif +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) +#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" +#elif defined(__EMSCRIPTEN__) +#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" + +// Otherwise try to detect supported Desktop OpenGL loaders.. +#elif defined(__has_include) +#if __has_include() +#define IMGUI_IMPL_OPENGL_LOADER_GLEW +#elif __has_include() +#define IMGUI_IMPL_OPENGL_LOADER_GLAD +#elif __has_include() +#define IMGUI_IMPL_OPENGL_LOADER_GL3W +#elif __has_include() +#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +#elif __has_include() +#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +#else +#error "Cannot detect OpenGL loader!" +#endif +#else +#define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W embedded in our repository +#endif + +#endif \ No newline at end of file diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt new file mode 100644 index 0000000..034ac75 --- /dev/null +++ b/Engine/CMakeLists.txt @@ -0,0 +1,4 @@ +project (Engine) + +add_subdirectory (Lib) +add_subdirectory (Test) \ No newline at end of file diff --git a/Engine/Lib/CMakeLists.txt b/Engine/Lib/CMakeLists.txt new file mode 100644 index 0000000..c71461b --- /dev/null +++ b/Engine/Lib/CMakeLists.txt @@ -0,0 +1,44 @@ +project(EngineLib) + +file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp +) +# Source group to preserve folder structure in ide +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) + +add_library(${PROJECT_NAME} ${SOURCE_FILES}) + +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 17 +) + +target_link_libraries(${PROJECT_NAME} + PUBLIC glm::glm + PUBLIC nlohmann_json::nlohmann_json + PUBLIC fmtlog::fmtlog + PUBLIC SQLite::SQLite3 + + PUBLIC OpenAL::OpenAL + # TODO Should be private? + PUBLIC vorbis::vorbis + PUBLIC minimp3::minimp3 + + PUBLIC OpenGL::GL + PUBLIC glfw + PUBLIC glad::glad + PUBLIC imgui::imgui + PUBLIC stb::stb + PUBLIC assimp::assimp + PUBLIC tinyobjloader::tinyobjloader + PUBLIC Freetype::Freetype +) + +target_include_directories(${PROJECT_NAME} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include +) \ No newline at end of file diff --git a/Engine/Lib/include/kern/app/GameApplication.h b/Engine/Lib/include/kern/app/GameApplication.h new file mode 100644 index 0000000..a86b2e9 --- /dev/null +++ b/Engine/Lib/include/kern/app/GameApplication.h @@ -0,0 +1,23 @@ +#pragma once + +#include "kern/resource/IResourceManager.h" +#include "kern/game/GameSystem.h" +#include "kern/audio/SoundSystem.h" + +class GameApplication +{ + public: + GameApplication(); + virtual ~GameApplication(); + + bool init(); + void run(); + + protected: + // Resource manager + std::unique_ptr m_resourceManager; + // Manages game states and state transitions + std::unique_ptr m_gameSystem; + // Creates and manages sounds and sound emitters + std::unique_ptr m_soundSystem; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/Sound.h b/Engine/Lib/include/kern/audio/Sound.h new file mode 100644 index 0000000..6a03654 --- /dev/null +++ b/Engine/Lib/include/kern/audio/Sound.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +// Represents playable audio data +class Sound +{ + public: + // pcmSampleData - is either 8 or 16 bit sound data + // sizeInBytes - total size of the sample data in bytes + // channels - number of channels, 1 = mono, >=2 = stereo + // bitsPerSample - size of a single pcm sample in bits, either 8 or 16 + // frequency - the sampling frequency + Sound(const void* pcmSampleData, std::size_t sizeInBytes, unsigned short channels, unsigned short bitsPerSample, + unsigned int frequency); + ~Sound(); + + ALuint getBuffer() const; + ALenum getOALFormat() const; + + float getLength() const; + + private: + ALuint buffer = 0; + ALenum format = 0; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/SoundEmitter.h b/Engine/Lib/include/kern/audio/SoundEmitter.h new file mode 100644 index 0000000..d7dfe89 --- /dev/null +++ b/Engine/Lib/include/kern/audio/SoundEmitter.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include +#include + +#include "kern/audio/Sound.h" +#include "kern/audio/SoundPriority.h" + +// Represents a sound source in 3d space +class SoundEmitter +{ + public: + SoundEmitter(); + SoundEmitter(const std::shared_ptr& sound); + ~SoundEmitter(); + + void play(); + void play(const std::shared_ptr& sound); + void stop(); + + void setSound(const std::shared_ptr& sound); + + void setPosition(const glm::vec3& position); + const glm::vec3& getPosition() const; + + void setVelocity(const glm::vec3& velocity); + const glm::vec3& getVelocity() const; + + SoundPriority getPriority() const; + void setPriority(SoundPriority prio); + + float getVolume() const; + void setVolume(float volume); + + bool getLooping() const; + void setLooping(bool loop); + + float getRadius() const; + void setRadius(float radius); + + private: + ALuint source = 0; + glm::vec3 position = glm::vec3(0.f); + glm::vec3 velocity = glm::vec3(0.f); + std::shared_ptr sound; + SoundPriority priority = SoundPriority::Low; + float volume = 0.f; + bool looping = false; + float radius = 0.f; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/SoundListener.h b/Engine/Lib/include/kern/audio/SoundListener.h new file mode 100644 index 0000000..9493626 --- /dev/null +++ b/Engine/Lib/include/kern/audio/SoundListener.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +// Represens a sound listener +// Only one listener is active +class SoundListener +{ + public: + void setPosition(const glm::vec3& position); + void setVelocity(const glm::vec3& velocity); + + const glm::vec3& getPosition() const; + const glm::vec3& getVelocity() const; + + private: + glm::vec3 position = glm::vec3(0.f); + glm::vec3 velocity = glm::vec3(0.f); +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/SoundManager.h b/Engine/Lib/include/kern/audio/SoundManager.h new file mode 100644 index 0000000..6f88cd8 --- /dev/null +++ b/Engine/Lib/include/kern/audio/SoundManager.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include + +#include "kern/audio/Sound.h" + +class SoundManager +{ + public: + SoundManager(const std::string& soundDirectory); + // Registers a sound name to filename mapping + void registerSound(const std::string& name, const std::string& fileName); + // Retrieves sound by previously registered name + std::shared_ptr getSound(const std::string& name); + bool hasSound(const std::string& name) const; + + private: + std::shared_ptr loadFromFile(const std::string& fileName); + std::shared_ptr loadFromWav(const std::string& fileName); + std::shared_ptr loadFromMp3(const std::string& fileName); + + std::string directory; + std::unordered_map namesToFiles; + // File name to sound + std::unordered_map> filesToSounds; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/SoundPriority.h b/Engine/Lib/include/kern/audio/SoundPriority.h new file mode 100644 index 0000000..714b84b --- /dev/null +++ b/Engine/Lib/include/kern/audio/SoundPriority.h @@ -0,0 +1,9 @@ +#pragma once + +enum class SoundPriority +{ + Low, + Medium, + High, + Always +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/audio/SoundSystem.h b/Engine/Lib/include/kern/audio/SoundSystem.h new file mode 100644 index 0000000..a7c2d7e --- /dev/null +++ b/Engine/Lib/include/kern/audio/SoundSystem.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include +#include + +#include + +#include "kern/audio/SoundManager.h" +#include "kern/audio/SoundEmitter.h" +#include "kern/audio/SoundListener.h" + +class SoundSystem +{ + public: + SoundSystem(const std::string& directory); + ~SoundSystem(); + + SoundListener& getListener(); + std::shared_ptr& getManager(); + std::shared_ptr createEmitter(); + std::shared_ptr createEmitter(const std::shared_ptr sound); + + // Global background sound emitter + std::shared_ptr& getGlobalSoundEmitter(); + + // Delta time in seconds + void update(float dtime); + private: + // Global background sound emitter + std::shared_ptr bgmEmitter; + std::unordered_set> emitters; + + // The current listener + SoundListener listener; + ALCdevice* device = nullptr; + ALCcontext* context = nullptr; + + // Sound manager + std::shared_ptr manager; +}; \ No newline at end of file diff --git a/Foundation/Lib/include/foundation/io/CIniFile.h b/Engine/Lib/include/kern/foundation/IniFile.h similarity index 99% rename from Foundation/Lib/include/foundation/io/CIniFile.h rename to Engine/Lib/include/kern/foundation/IniFile.h index a39735f..d43ae42 100644 --- a/Foundation/Lib/include/foundation/io/CIniFile.h +++ b/Engine/Lib/include/kern/foundation/IniFile.h @@ -12,7 +12,7 @@ * [group] <-- This is a group * key=value <-- This is a key/value pair */ -class CIniFile +class IniFile { public: /** diff --git a/Engine/Lib/include/kern/foundation/JsonDeserialize.h b/Engine/Lib/include/kern/foundation/JsonDeserialize.h new file mode 100644 index 0000000..a83da3a --- /dev/null +++ b/Engine/Lib/include/kern/foundation/JsonDeserialize.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include + +namespace glm +{ +void from_json(const nlohmann::json &j, glm::vec2 &val); +void from_json(const nlohmann::json &j, glm::vec3 &val); +void from_json(const nlohmann::json &j, glm::vec4 &val); +void from_json(const nlohmann::json &j, glm::quat &val); +} \ No newline at end of file diff --git a/Engine/Lib/include/kern/foundation/JsonUtil.h b/Engine/Lib/include/kern/foundation/JsonUtil.h new file mode 100644 index 0000000..e01ee44 --- /dev/null +++ b/Engine/Lib/include/kern/foundation/JsonUtil.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#include +#include + +bool load(const std::string &file, nlohmann::json &root); + +bool load(const nlohmann::json &node, const std::string &name, int &i); +bool load(const nlohmann::json &node, const std::string &name, unsigned int &i); +bool load(const nlohmann::json &node, const std::string &name, float &f); +bool load(const nlohmann::json &node, const std::string &name, bool &b); +bool load(const nlohmann::json &node, const std::string &name, glm::vec3 &vec); +bool load(const nlohmann::json &node, const std::string &name, std::string &str); \ No newline at end of file diff --git a/Engine/Lib/include/kern/foundation/StringUtil.h b/Engine/Lib/include/kern/foundation/StringUtil.h new file mode 100644 index 0000000..ccb40df --- /dev/null +++ b/Engine/Lib/include/kern/foundation/StringUtil.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +// Extension of the file without the dot +// Empty if theres no extension +// Basically returns everything after the last dot +std::string getFileExtension(const std::string &file); diff --git a/Foundation/Lib/include/foundation/util/Time.h b/Engine/Lib/include/kern/foundation/Time.h similarity index 100% rename from Foundation/Lib/include/foundation/util/Time.h rename to Engine/Lib/include/kern/foundation/Time.h diff --git a/Foundation/Lib/include/foundation/math/TransformUtils.h b/Engine/Lib/include/kern/foundation/TransformUtils.h similarity index 100% rename from Foundation/Lib/include/foundation/math/TransformUtils.h rename to Engine/Lib/include/kern/foundation/TransformUtils.h diff --git a/Foundation/Lib/include/foundation/math/CTransformer.h b/Engine/Lib/include/kern/foundation/Transformer.h similarity index 99% rename from Foundation/Lib/include/foundation/math/CTransformer.h rename to Engine/Lib/include/kern/foundation/Transformer.h index 13417c9..35adcd0 100644 --- a/Foundation/Lib/include/foundation/math/CTransformer.h +++ b/Engine/Lib/include/kern/foundation/Transformer.h @@ -6,7 +6,7 @@ /** * \brief Transformer class calculates and stores all necessary transformations. */ -class CTransformer +class Transformer { public: void setPosition(const glm::vec3 &position); diff --git a/Application/Lib/include/application/game/AGameState.h b/Engine/Lib/include/kern/game/AGameState.h similarity index 69% rename from Application/Lib/include/application/game/AGameState.h rename to Engine/Lib/include/kern/game/AGameState.h index f0473b3..245ef90 100644 --- a/Application/Lib/include/application/game/AGameState.h +++ b/Engine/Lib/include/kern/game/AGameState.h @@ -1,7 +1,7 @@ #pragma once -#include "application/game/CGameWorld.h" -#include "application/game/IGameState.h" +#include "kern/game/GameWorld.h" +#include "kern/game/IGameState.h" /** * \brief Abstract game state base class. @@ -13,11 +13,11 @@ class AGameState : public IGameState public: virtual ~AGameState(); - CGameWorld &getGameWorld(); - const CGameWorld &getGameWorld() const; + GameWorld &getGameWorld(); + const GameWorld &getGameWorld() const; - virtual bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager); + virtual bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem); virtual void onEnter(); virtual bool update(float dtime); virtual void onExit(); @@ -29,5 +29,5 @@ class AGameState : public IGameState private: bool m_stateTransitionTriggered = false; std::string m_nextStateId = "exit"; - CGameWorld m_gameWorld; + GameWorld m_gameWorld; }; \ No newline at end of file diff --git a/Application/Lib/include/application/game/CGameObject.h b/Engine/Lib/include/kern/game/GameObject.h similarity index 81% rename from Application/Lib/include/application/game/CGameObject.h rename to Engine/Lib/include/kern/game/GameObject.h index f2e9b4b..bd2804b 100644 --- a/Application/Lib/include/application/game/CGameObject.h +++ b/Engine/Lib/include/kern/game/GameObject.h @@ -5,28 +5,28 @@ #include -#include "graphics/graphics/proxy/CSceneObjectProxy.h" +#include "kern/graphics/proxy/SceneObjectProxy.h" -#include "application/game/Message.h" +#include "kern/game/Message.h" -class IController; -class CCollidable; +class IGameObjectController; +class Collidable; /** * \brief Game object storing relevant data. */ -class CGameObject +class GameObject { public: /** * \brief Default constructor. */ - CGameObject(); + GameObject(); /** * \brief Resource cleanup. */ - ~CGameObject(); + ~GameObject(); /** * \brief Sets rotation. @@ -46,12 +46,12 @@ class CGameObject /** * \brief Adds controller to object. */ - void addController(const std::shared_ptr &controller); + void addController(const std::shared_ptr &controller); /** * \brief Set scene object. */ - void setSceneObject(CSceneObjectProxy *proxy); + void setSceneObject(SceneObjectProxy *proxy); /** * \brief Returns rotation. @@ -99,12 +99,12 @@ class CGameObject /** * \brief Sets the collision entity for the object. */ - void setCollidable(CCollidable *entity); + void setCollidable(Collidable *entity); /** * \brief Returns collidable entity. */ - CCollidable *getCollidable() const; + Collidable *getCollidable() const; /** * \brief returns true if a collidable has been set for the game object and @@ -123,15 +123,15 @@ class CGameObject void setDead(); protected: - std::unique_ptr m_sceneObject; /**< Scene object. */ + std::unique_ptr m_sceneObject; /**< Scene object. */ glm::vec3 m_forward = glm::vec3(0.f, 0.f, 1.f); /**< Forward direction per default +z. */ glm::vec3 m_rotation = glm::vec3(0.f); /**< Rotation. */ glm::vec3 m_position = glm::vec3(0.f); /**< Position. */ glm::vec3 m_scale = glm::vec3(1.f); /**< Scale. */ bool m_transformationChanged = false; /**< Transformation dirty flag. */ bool m_deleteRequested = false; /**< Deletion of this object is requested. */ - std::list> + std::list> m_controllers; /**< Controllers attached to the object. */ - CCollidable *m_collidable = nullptr; /**< Collidable object. */ + Collidable *m_collidable = nullptr; /**< Collidable object. */ bool m_dead = false; /**< Death flag. */ }; diff --git a/Application/Lib/include/application/game/CGameSystem.h b/Engine/Lib/include/kern/game/GameSystem.h similarity index 83% rename from Application/Lib/include/application/game/CGameSystem.h rename to Engine/Lib/include/kern/game/GameSystem.h index 93c3f49..e403ba1 100644 --- a/Application/Lib/include/application/game/CGameSystem.h +++ b/Engine/Lib/include/kern/game/GameSystem.h @@ -5,28 +5,29 @@ #include #include -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/input/IInputProvider.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/input/IInputProvider.h" +#include "kern/audio/SoundSystem.h" -#include "application/game/IGameState.h" +#include "kern/game/IGameState.h" /** * \brief Manages game objects * * High level system for managing and updating the game objects and logic */ -class CGameSystem +class GameSystem { public: /** * \brief Default constructor. */ - CGameSystem(); + GameSystem(); /** * \brief Cleans up all game objects. */ - ~CGameSystem(); + ~GameSystem(); /** * \brief Updates the game objects @@ -37,7 +38,7 @@ class CGameSystem * \brief Initialize game system with startup config file. */ bool init(const std::string &initialState, IGraphicsSystem *graphicsSystem, - IInputProvider *inputProvider, IResourceManager *resourceManager); + IInputProvider *inputProvider, IResourceManager *resourceManager, SoundSystem* soundSystem); /** * \brief Add game state by name and initializes the state. diff --git a/Application/Lib/include/application/game/CGameWorld.h b/Engine/Lib/include/kern/game/GameWorld.h similarity index 67% rename from Application/Lib/include/application/game/CGameWorld.h rename to Engine/Lib/include/kern/game/GameWorld.h index 08e4e46..a3e54e9 100644 --- a/Application/Lib/include/application/game/CGameWorld.h +++ b/Engine/Lib/include/kern/game/GameWorld.h @@ -3,12 +3,12 @@ #include #include -#include "application/game/CGameObject.h" +#include "kern/game/GameObject.h" /** * \brief Stores game objects and manages object lifetime. */ -class CGameWorld +class GameWorld { public: /** @@ -21,8 +21,8 @@ class CGameWorld * * The object must be created on the heap and is owned by the game world. */ - void addObject(CGameObject *object); + void addObject(GameObject *object); private: - std::list> m_objects; /**< Game objects. */ + std::list> m_objects; /**< Game objects. */ }; diff --git a/Application/Lib/include/application/game/IController.h b/Engine/Lib/include/kern/game/IGameObjectController.h similarity index 78% rename from Application/Lib/include/application/game/IController.h rename to Engine/Lib/include/kern/game/IGameObjectController.h index bcb860f..ce3094e 100644 --- a/Application/Lib/include/application/game/IController.h +++ b/Engine/Lib/include/kern/game/IGameObjectController.h @@ -1,26 +1,26 @@ #pragma once -#include "application/game/Message.h" +#include "kern/game/Message.h" -class CGameObject; /**< Game object forward declare. */ +class GameObject; /**< Game object forward declare. */ /** * \brief Controller class interface. * Controllers are attached to game objects and implement specific * game logic. */ -class IController +class IGameObjectController { public: /** * \brief Virtual destructor. */ - virtual ~IController(); + virtual ~IGameObjectController(); /** * \brief Called on attaching to game object. */ - virtual void attach(CGameObject *object) = 0; + virtual void attach(GameObject *object) = 0; /** * \brief Called on detaching from game object. diff --git a/Application/Lib/include/application/game/IGameState.h b/Engine/Lib/include/kern/game/IGameState.h similarity index 88% rename from Application/Lib/include/application/game/IGameState.h rename to Engine/Lib/include/kern/game/IGameState.h index ab1feba..ee89490 100644 --- a/Application/Lib/include/application/game/IGameState.h +++ b/Engine/Lib/include/kern/game/IGameState.h @@ -5,6 +5,7 @@ class IGraphicsSystem; class IInputProvider; class IResourceManager; +class SoundSystem; /** * \brief Game state interface class. @@ -23,8 +24,8 @@ class IGameState /** * \brief Explicit initialization. */ - virtual bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) = 0; + virtual bool init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) = 0; /** * \brief Called on entering state. diff --git a/Engine/Lib/include/kern/game/LoadGame.h b/Engine/Lib/include/kern/game/LoadGame.h new file mode 100644 index 0000000..ac07d1c --- /dev/null +++ b/Engine/Lib/include/kern/game/LoadGame.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include + +class IResourceManager; +class GameSystem; + +/** + * \brief Loads entire game. + */ +bool load(const std::string &file, IResourceManager &manager, GameSystem &system); +bool loadGameStates(const nlohmann::json &node, IResourceManager &manager, GameSystem &system); +bool loadGameState(const nlohmann::json &node, IResourceManager &manager, GameSystem &system); +bool loadGameState(const std::string &file, const std::string &name, IResourceManager &manager, + GameSystem &system); \ No newline at end of file diff --git a/Application/Lib/include/application/game/Message.h b/Engine/Lib/include/kern/game/Message.h similarity index 100% rename from Application/Lib/include/application/game/Message.h rename to Engine/Lib/include/kern/game/Message.h diff --git a/Graphics/Lib/include/graphics/graphics/ICamera.h b/Engine/Lib/include/kern/graphics/ICamera.h similarity index 100% rename from Graphics/Lib/include/graphics/graphics/ICamera.h rename to Engine/Lib/include/kern/graphics/ICamera.h diff --git a/Engine/Lib/include/kern/graphics/IGraphicsResourceManager.h b/Engine/Lib/include/kern/graphics/IGraphicsResourceManager.h new file mode 100644 index 0000000..95bb210 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/IGraphicsResourceManager.h @@ -0,0 +1,56 @@ +#pragma once + +#include "kern/resource/ResourceId.h" + +class Mesh; +class Material; +class Model; +class Texture; +class ShaderProgram; + +/** + * \brief Graphics resource manager interface. + * Provides access to GPU resources. + */ +class IGraphicsResourceManager +{ + public: + /** + * \brief Cleans up resource callbacks. + */ + virtual ~IGraphicsResourceManager(); + + /** + * \brief Maps id to internal mesh object. + */ + virtual Mesh *getMesh(ResourceId) const = 0; + + /** + * \brief Maps id to internal material object. + */ + virtual Material *getMaterial(ResourceId) const = 0; + + /** + * \brief Maps id to internal model object. + */ + virtual Model *getModel(ResourceId) const = 0; + + /** + * \brief Maps id to internal texture object. + */ + virtual Texture *getTexture(ResourceId) const = 0; + + /** + * \brief Maps id to internal shader program object. + */ + virtual ShaderProgram *getShaderProgram(ResourceId) const = 0; + + /** + * \brief Returns respective default texture. + */ + virtual Texture *getDefaultDiffuseTexture() const = 0; + virtual Texture *getDefaultNormalTexture() const = 0; + virtual Texture *getDefaultSpecularTexture() const = 0; + virtual Texture *getDefaultGlowTexture() const = 0; + virtual Texture *getDefaultAlphaTexture() const = 0; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/IGraphicsSystem.h b/Engine/Lib/include/kern/graphics/IGraphicsSystem.h similarity index 95% rename from Graphics/Lib/include/graphics/graphics/IGraphicsSystem.h rename to Engine/Lib/include/kern/graphics/IGraphicsSystem.h index 8043581..7ff3aa5 100644 --- a/Graphics/Lib/include/graphics/graphics/IGraphicsSystem.h +++ b/Engine/Lib/include/kern/graphics/IGraphicsSystem.h @@ -3,7 +3,7 @@ #include class IScene; -class IWindow; +class Window; class IResourceManager; class ICamera; @@ -62,5 +62,5 @@ class IGraphicsSystem /** * \brief Draws active scene. */ - virtual void draw(IWindow &window) = 0; + virtual void draw(Window &window) = 0; }; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/IRenderer.h b/Engine/Lib/include/kern/graphics/IRenderer.h similarity index 91% rename from Graphics/Lib/include/graphics/graphics/IRenderer.h rename to Engine/Lib/include/kern/graphics/IRenderer.h index 4183667..7cf52f3 100644 --- a/Graphics/Lib/include/graphics/graphics/IRenderer.h +++ b/Engine/Lib/include/kern/graphics/IRenderer.h @@ -1,7 +1,7 @@ #pragma once class IScene; -class IWindow; +class Window; class ICamera; class IGraphicsResourceManager; @@ -19,6 +19,6 @@ class IRenderer /** * \brief Draw scene viewed from camera into window. */ - virtual void draw(const IScene &scene, const ICamera &camera, const IWindow &window, + virtual void draw(const IScene &scene, const ICamera &camera, const Window &window, const IGraphicsResourceManager &manager) = 0; }; diff --git a/Graphics/Lib/include/graphics/graphics/IScene.h b/Engine/Lib/include/kern/graphics/IScene.h similarity index 97% rename from Graphics/Lib/include/graphics/graphics/IScene.h rename to Engine/Lib/include/kern/graphics/IScene.h index 8003fbe..477ea7f 100644 --- a/Graphics/Lib/include/graphics/graphics/IScene.h +++ b/Engine/Lib/include/kern/graphics/IScene.h @@ -5,8 +5,8 @@ #include #include -#include "graphics/graphics/SceneConfig.h" -#include "graphics/resource/ResourceConfig.h" +#include "kern/graphics/SceneConfig.h" +#include "kern/resource/ResourceId.h" class ICamera; class ISceneQuery; diff --git a/Graphics/Lib/include/graphics/graphics/ISceneQuery.h b/Engine/Lib/include/kern/graphics/ISceneQuery.h similarity index 96% rename from Graphics/Lib/include/graphics/graphics/ISceneQuery.h rename to Engine/Lib/include/kern/graphics/ISceneQuery.h index 4e2b0cb..9570bfb 100644 --- a/Graphics/Lib/include/graphics/graphics/ISceneQuery.h +++ b/Engine/Lib/include/kern/graphics/ISceneQuery.h @@ -1,6 +1,6 @@ #pragma once -#include "graphics/graphics/SceneConfig.h" +#include "kern/graphics/SceneConfig.h" /** * \brief Scene query interface class. diff --git a/Graphics/Lib/include/graphics/graphics/SceneConfig.h b/Engine/Lib/include/kern/graphics/SceneConfig.h similarity index 58% rename from Graphics/Lib/include/graphics/graphics/SceneConfig.h rename to Engine/Lib/include/kern/graphics/SceneConfig.h index 85c34ba..f83aa52 100644 --- a/Graphics/Lib/include/graphics/graphics/SceneConfig.h +++ b/Engine/Lib/include/kern/graphics/SceneConfig.h @@ -3,4 +3,4 @@ #include typedef int32_t SceneObjectId; -static const SceneObjectId invalidObject = -1; +static const SceneObjectId InvalidObject = -1; diff --git a/Graphics/Lib/include/graphics/graphics/window/CGlfwWindow.h b/Engine/Lib/include/kern/graphics/Window.h similarity index 65% rename from Graphics/Lib/include/graphics/graphics/window/CGlfwWindow.h rename to Engine/Lib/include/kern/graphics/Window.h index a914550..754cc2d 100644 --- a/Graphics/Lib/include/graphics/graphics/window/CGlfwWindow.h +++ b/Engine/Lib/include/kern/graphics/Window.h @@ -2,14 +2,14 @@ #include #include +#include #include -#include "graphics/graphics/IWindow.h" -#include "graphics/input/IInputProvider.h" +#include "kern/graphics/input/IInputProvider.h" struct GLFWwindow; -class IGlfwWindowListener +class IWindowListener { public: virtual void handleResizeEvent(int width, int height) = 0; @@ -18,11 +18,11 @@ class IGlfwWindowListener /** * \brief GLFW based implementation of the window interface. */ -class CGlfwWindow : public IWindow +class Window { public: - CGlfwWindow(); - ~CGlfwWindow(); + Window(); + ~Window(); bool init(unsigned int width, unsigned int height, const std::string &name); @@ -32,6 +32,11 @@ class CGlfwWindow : public IWindow unsigned int getWidth() const; unsigned int getHeight() const; + /** + * \brief Sets window active for rendering. + * Must set the context as current. + * TODO Should this be const or provide renderer with non const reference? + */ void setActive() const; bool isOpen() const; @@ -41,6 +46,9 @@ class CGlfwWindow : public IWindow */ void swapBuffer(); + // Event processing + void processEvents(); + /** * \brief Toggles mouse capture state. */ @@ -48,20 +56,19 @@ class CGlfwWindow : public IWindow GLFWwindow *getGlfwHandle() const; - void addListener(IGlfwWindowListener *l); - void removeListener(IGlfwWindowListener *l); + void addListener(IWindowListener *l); + void removeListener(IWindowListener *l); private: static void resizeCallback(GLFWwindow *window, int width, int height); void handleResize(int width, int height); - static std::unordered_map - s_windows; /**< GLFW window to window object mapping. */ + static std::unordered_map s_windows; /**< GLFW window to window object mapping. */ GLFWwindow *m_window = nullptr; /**< Window resource. */ unsigned int m_width = 0; /**< Current window width. */ unsigned int m_height = 0; /**< Current window height. */ bool m_mouseCaptured = false; /**< Current mouse capture state. */ - std::set m_listeners; + std::set m_listeners; }; diff --git a/Graphics/Lib/include/graphics/animation/Animation.h b/Engine/Lib/include/kern/graphics/animation/AnimationObjectType.h similarity index 100% rename from Graphics/Lib/include/graphics/animation/Animation.h rename to Engine/Lib/include/kern/graphics/animation/AnimationObjectType.h diff --git a/Graphics/Lib/include/graphics/animation/CAnimationWorld.h b/Engine/Lib/include/kern/graphics/animation/AnimationWorld.h similarity index 96% rename from Graphics/Lib/include/graphics/animation/CAnimationWorld.h rename to Engine/Lib/include/kern/graphics/animation/AnimationWorld.h index 8c5626c..03730c2 100644 --- a/Graphics/Lib/include/graphics/animation/CAnimationWorld.h +++ b/Engine/Lib/include/kern/graphics/animation/AnimationWorld.h @@ -8,7 +8,7 @@ class IAnimationController; /** * \brief The animation world stores a collection of animation controller. */ -class CAnimationWorld +class AnimationWorld { public: /** diff --git a/Graphics/Lib/include/graphics/animation/IAnimationController.h b/Engine/Lib/include/kern/graphics/animation/IAnimationController.h similarity index 100% rename from Graphics/Lib/include/graphics/animation/IAnimationController.h rename to Engine/Lib/include/kern/graphics/animation/IAnimationController.h diff --git a/Graphics/Lib/include/graphics/animation/CMovementController.h b/Engine/Lib/include/kern/graphics/animation/MovementController.h similarity index 50% rename from Graphics/Lib/include/graphics/animation/CMovementController.h rename to Engine/Lib/include/kern/graphics/animation/MovementController.h index 39278f0..038bfca 100644 --- a/Graphics/Lib/include/graphics/animation/CMovementController.h +++ b/Engine/Lib/include/kern/graphics/animation/MovementController.h @@ -2,16 +2,17 @@ #include -#include "graphics/animation/Animation.h" -#include "graphics/animation/IAnimationController.h" -#include "graphics/graphics/SceneConfig.h" +#include "kern/graphics/animation/AnimationObjectType.h" +#include "kern/graphics/animation/IAnimationController.h" +#include "kern/graphics/SceneConfig.h" class IScene; -class CMovementController : public IAnimationController +// Moves the controlled object in a direction +class MovementController : public IAnimationController { public: - CMovementController(SceneObjectId id, AnimationObjectType type, IScene &scene, + MovementController(SceneObjectId id, AnimationObjectType type, IScene &scene, const glm::vec3 &direction); void update(float timeStep); diff --git a/Engine/Lib/include/kern/graphics/animation/RotationController.h b/Engine/Lib/include/kern/graphics/animation/RotationController.h new file mode 100644 index 0000000..9b318a8 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/animation/RotationController.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "kern/graphics/animation/AnimationObjectType.h" +#include "kern/graphics/animation/IAnimationController.h" +#include "kern/graphics/SceneConfig.h" + +class IScene; + +// Rotates the controlled object +class RotationController : public IAnimationController +{ + public: + RotationController(SceneObjectId id, AnimationObjectType type, IScene &scene, + const glm::vec3 &rotation); + + void update(float timeStep); + + private: + SceneObjectId m_objectId = -1; + AnimationObjectType m_type; + IScene &m_scene; + glm::vec3 m_rotation; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/animation/CSineTranslationController.h b/Engine/Lib/include/kern/graphics/animation/SineTranslationController.h similarity index 51% rename from Graphics/Lib/include/graphics/animation/CSineTranslationController.h rename to Engine/Lib/include/kern/graphics/animation/SineTranslationController.h index b36a643..a5275cd 100644 --- a/Graphics/Lib/include/graphics/animation/CSineTranslationController.h +++ b/Engine/Lib/include/kern/graphics/animation/SineTranslationController.h @@ -2,16 +2,17 @@ #include -#include "graphics/animation/Animation.h" -#include "graphics/animation/IAnimationController.h" -#include "graphics/graphics/SceneConfig.h" +#include "kern/graphics/animation/AnimationObjectType.h" +#include "kern/graphics/animation/IAnimationController.h" +#include "kern/graphics/SceneConfig.h" class IScene; -class CSineTranslationController : public IAnimationController +// Performs a sine translation on the object +class SineTranslationController : public IAnimationController { public: - CSineTranslationController(SceneObjectId id, AnimationObjectType type, IScene &scene, + SineTranslationController(SceneObjectId id, AnimationObjectType type, IScene &scene, const glm::vec3 &translation, float timeScale); void update(float timeStep); diff --git a/Graphics/Lib/include/graphics/graphics/camera/CCamera.h b/Engine/Lib/include/kern/graphics/camera/Camera.h similarity index 85% rename from Graphics/Lib/include/graphics/graphics/camera/CCamera.h rename to Engine/Lib/include/kern/graphics/camera/Camera.h index 69f8b29..fe1ad8a 100644 --- a/Graphics/Lib/include/graphics/graphics/camera/CCamera.h +++ b/Engine/Lib/include/kern/graphics/camera/Camera.h @@ -2,9 +2,9 @@ #include -#include "graphics/graphics/ICamera.h" +#include "kern/graphics/ICamera.h" -class CCamera : public ICamera +class Camera : public ICamera { public: void setView(const glm::mat4 &view); diff --git a/Graphics/Lib/include/graphics/graphics/camera/CFirstPersonCamera.h b/Engine/Lib/include/kern/graphics/camera/FirstPersonCamera.h similarity index 80% rename from Graphics/Lib/include/graphics/graphics/camera/CFirstPersonCamera.h rename to Engine/Lib/include/kern/graphics/camera/FirstPersonCamera.h index a0fbc53..ad966df 100644 --- a/Graphics/Lib/include/graphics/graphics/camera/CFirstPersonCamera.h +++ b/Engine/Lib/include/kern/graphics/camera/FirstPersonCamera.h @@ -2,15 +2,14 @@ #include -#include +#include "kern/foundation/TransformUtils.h" +#include "kern/graphics/camera/IControllableCamera.h" -#include "graphics/graphics/camera/IControllableCamera.h" - -class CFirstPersonCamera : public IControllableCamera +class FirstPersonCamera : public IControllableCamera { public: - CFirstPersonCamera(const glm::vec3 &position, const glm::vec3 &target, const glm::vec3 &up, - float fieldOfView, float aspectRatio, float zNear, float zFar); + FirstPersonCamera(const glm::vec3 &position, const glm::vec3 &target, const glm::vec3 &up, float fieldOfView, + float aspectRatio, float zNear, float zFar); const glm::mat4 &getView() const override; const glm::mat4 &getProjection() const override; diff --git a/Graphics/Lib/include/graphics/graphics/camera/IControllableCamera.h b/Engine/Lib/include/kern/graphics/camera/IControllableCamera.h similarity index 96% rename from Graphics/Lib/include/graphics/graphics/camera/IControllableCamera.h rename to Engine/Lib/include/kern/graphics/camera/IControllableCamera.h index e9dd14a..9baf1af 100644 --- a/Graphics/Lib/include/graphics/graphics/camera/IControllableCamera.h +++ b/Engine/Lib/include/kern/graphics/camera/IControllableCamera.h @@ -2,7 +2,7 @@ #include -#include "graphics/graphics/ICamera.h" +#include "kern/graphics/ICamera.h" class IControllableCamera : public ICamera { diff --git a/Graphics/Lib/include/graphics/graphics/camera/CStaticCamera.h b/Engine/Lib/include/kern/graphics/camera/StaticCamera.h similarity index 65% rename from Graphics/Lib/include/graphics/graphics/camera/CStaticCamera.h rename to Engine/Lib/include/kern/graphics/camera/StaticCamera.h index 1ed5447..7ed97df 100644 --- a/Graphics/Lib/include/graphics/graphics/camera/CStaticCamera.h +++ b/Engine/Lib/include/kern/graphics/camera/StaticCamera.h @@ -2,15 +2,15 @@ #include -#include "graphics/graphics/ICamera.h" +#include "kern/graphics/ICamera.h" /** * \brief Simple static camera for shadow map pass. */ -class CStaticCamera : public ICamera +class StaticCamera : public ICamera { public: - CStaticCamera(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &position); + StaticCamera(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &position); const glm::mat4 &getView() const; const glm::mat4 &getProjection() const; diff --git a/Graphics/Lib/include/graphics/collision/CAABBox.h b/Engine/Lib/include/kern/graphics/collision/AABBox.h similarity index 88% rename from Graphics/Lib/include/graphics/collision/CAABBox.h rename to Engine/Lib/include/kern/graphics/collision/AABBox.h index 8e2fc35..05c6e0f 100644 --- a/Graphics/Lib/include/graphics/collision/CAABBox.h +++ b/Engine/Lib/include/kern/graphics/collision/AABBox.h @@ -8,7 +8,7 @@ /** * \brief Axis aligned bounding box */ -class CAABBox +class AABBox { public: /** @@ -41,7 +41,7 @@ class CAABBox /** * \brief Creates axis aligned bounding box from vertices. */ - static CAABBox create(const std::vector &vertices); + static AABBox create(const std::vector &vertices); private: glm::vec3 m_middlePoint = glm::vec3(0.f); /**< Middle of the box. */ @@ -51,4 +51,4 @@ class CAABBox /** * \brief Collision check. */ -bool collides(const CAABBox &b1, const CAABBox &b2); \ No newline at end of file +bool collides(const AABBox &b1, const AABBox &b2); \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/collision/CBoundingSphere.h b/Engine/Lib/include/kern/graphics/collision/BoundingSphere.h similarity index 55% rename from Graphics/Lib/include/graphics/collision/CBoundingSphere.h rename to Engine/Lib/include/kern/graphics/collision/BoundingSphere.h index cca75c4..5129319 100644 --- a/Graphics/Lib/include/graphics/collision/CBoundingSphere.h +++ b/Engine/Lib/include/kern/graphics/collision/BoundingSphere.h @@ -4,11 +4,11 @@ #include -class CBoundingSphere +class BoundingSphere { public: - CBoundingSphere(); - CBoundingSphere(const glm::vec3 &position, float radius); + BoundingSphere(); + BoundingSphere(const glm::vec3 &position, float radius); void setPosition(const glm::vec3 &position); void setRadius(float radius); @@ -16,11 +16,11 @@ class CBoundingSphere const glm::vec3 &getPosition() const; float getRadius() const; - static CBoundingSphere create(const std::vector &vertices); + static BoundingSphere create(const std::vector &vertices); private: glm::vec3 m_position = glm::vec3(0.f); float m_radius = 0.f; }; -bool collides(const CBoundingSphere &sphere1, const CBoundingSphere &sphere2); \ No newline at end of file +bool collides(const BoundingSphere &sphere1, const BoundingSphere &sphere2); \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/collision/CCollidable.h b/Engine/Lib/include/kern/graphics/collision/Collidable.h similarity index 88% rename from Graphics/Lib/include/graphics/collision/CCollidable.h rename to Engine/Lib/include/kern/graphics/collision/Collidable.h index b2230d4..c95da59 100644 --- a/Graphics/Lib/include/graphics/collision/CCollidable.h +++ b/Engine/Lib/include/kern/graphics/collision/Collidable.h @@ -2,7 +2,7 @@ #include -#include "graphics/collision/CAABBox.h" +#include "kern/graphics/collision/AABBox.h" /** * \brief Represents a collision entity in the collision system. @@ -10,14 +10,14 @@ * A collidable entity deals a certain amount of damage to the other entity. * This is used for modeling projectile with ship collision. */ -class CCollidable +class Collidable { public: /** * \brief The entity is created with its group id and the untransformed * bounding volume */ - CCollidable(unsigned int groupId, const CAABBox &box); + Collidable(unsigned int groupId, const AABBox &box); /** * \brief Returns the group id @@ -49,7 +49,7 @@ class CCollidable /** * \brief Returns the bounding box. */ - const CAABBox &getAABBox() const; + const AABBox &getAABBox() const; /** * \brief Sets the translation matrix for the entity @@ -85,9 +85,9 @@ class CCollidable bool deleteRequested() const; protected: - CAABBox m_boxTransformed; /**< Transformed collision volume, recalculated on + AABBox m_boxTransformed; /**< Transformed collision volume, recalculated on setTranslation call. */ - CAABBox m_box; /**< The untransformed collision volume. */ + AABBox m_box; /**< The untransformed collision volume. */ unsigned int m_groupId = 0; /**< Collision group id. */ float m_damageReceived = 0.f; /**< Accumulated damage that was received since the last call to diff --git a/Graphics/Lib/include/graphics/collision/CCollisionSystem.h b/Engine/Lib/include/kern/graphics/collision/CollisionSystem.h similarity index 72% rename from Graphics/Lib/include/graphics/collision/CCollisionSystem.h rename to Engine/Lib/include/kern/graphics/collision/CollisionSystem.h index dd377d5..d8f9d48 100644 --- a/Graphics/Lib/include/graphics/collision/CCollisionSystem.h +++ b/Engine/Lib/include/kern/graphics/collision/CollisionSystem.h @@ -2,17 +2,17 @@ #include -#include "graphics/collision/CAABBox.h" +#include "kern/graphics/collision/AABBox.h" -class CCollidable; +class Collidable; -class CCollisionSystem +class CollisionSystem { public: /** * \brief Cleanup of resources. */ - ~CCollisionSystem(); + ~CollisionSystem(); /** * \brief Creates a new collidable and adds it to the specified group. @@ -21,12 +21,12 @@ class CCollisionSystem * Collidables in the same group are not tested for collision. * \param The untransformed bounding box for the entity */ - CCollidable *add(const CAABBox &box, unsigned int group); + Collidable *add(const AABBox &box, unsigned int group); /** * \brief Remove collidable entity */ - void remove(CCollidable *entity); + void remove(Collidable *entity); /** * \brief Tests the entities for collision @@ -43,8 +43,8 @@ class CCollisionSystem * \brief Tests the entity for collision with all other entities not in the * group */ - void testCollision(CCollidable *entity, unsigned int groupId); + void testCollision(Collidable *entity, unsigned int groupId); - std::vector> + std::vector> m_entities; /**< Stores entities by group id (vector index) in lists. */ }; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/collision/CFrustum.h b/Engine/Lib/include/kern/graphics/collision/Frustum.h similarity index 85% rename from Graphics/Lib/include/graphics/collision/CFrustum.h rename to Engine/Lib/include/kern/graphics/collision/Frustum.h index 5b30826..40523b7 100644 --- a/Graphics/Lib/include/graphics/collision/CFrustum.h +++ b/Engine/Lib/include/kern/graphics/collision/Frustum.h @@ -2,19 +2,19 @@ #include -#include "graphics/collision/CBoundingSphere.h" -#include "graphics/collision/CPlane.h" +#include "kern/graphics/collision/BoundingSphere.h" +#include "kern/graphics/collision/Plane.h" /** * \brief Represents a frustum for view frustum culling. * * Based on http://www.lighthouse3d.com/tutorials/view-frustum-culling. */ -class CFrustum +class Frustum { public: - CFrustum(); - ~CFrustum(); + Frustum() = default; + ~Frustum() = default; /** * \brief Calculates frustum planes from camera parameters. @@ -53,7 +53,7 @@ class CFrustum * \brief Returns true if the sphere either is completely inside or intersects * the frustum and false otherwise. */ - bool isInsideOrIntersects(const CBoundingSphere &sphere) const; + bool isInsideOrIntersects(const BoundingSphere &sphere) const; private: enum PlanePosition @@ -68,5 +68,5 @@ class CFrustum NumPlanes }; - CPlane m_planes[NumPlanes]; /**< Frustum planes. */ + Plane m_planes[NumPlanes]; /**< Frustum planes. */ }; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/collision/CPlane.h b/Engine/Lib/include/kern/graphics/collision/Plane.h similarity index 87% rename from Graphics/Lib/include/graphics/collision/CPlane.h rename to Engine/Lib/include/kern/graphics/collision/Plane.h index 68ecdd5..d4cd208 100644 --- a/Graphics/Lib/include/graphics/collision/CPlane.h +++ b/Engine/Lib/include/kern/graphics/collision/Plane.h @@ -5,12 +5,12 @@ /** * \brief Represents a 3d plane. */ -class CPlane +class Plane { public: - CPlane(); - CPlane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3); - ~CPlane(); + Plane(); + Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3); + ~Plane(); // Ordering of points defines normal vector // Clockwise/Counterclockwise ordering rule is used to calculate normal vector diff --git a/Graphics/Lib/include/graphics/input/provider/CGlfwInputProvider.h b/Engine/Lib/include/kern/graphics/input/GlfwInputProvider.h similarity index 79% rename from Graphics/Lib/include/graphics/input/provider/CGlfwInputProvider.h rename to Engine/Lib/include/kern/graphics/input/GlfwInputProvider.h index e76f123..072bdfb 100644 --- a/Graphics/Lib/include/graphics/input/provider/CGlfwInputProvider.h +++ b/Engine/Lib/include/kern/graphics/input/GlfwInputProvider.h @@ -3,7 +3,7 @@ #include #include -#include "graphics/input/IInputProvider.h" +#include "kern/graphics/input/IInputProvider.h" struct GLFWwindow; @@ -11,11 +11,11 @@ struct GLFWwindow; * \brief Provides user input. * Uses the glfw api. */ -class CGlfwInputProvider : public IInputProvider +class GlfwInputProvider : public IInputProvider { public: - CGlfwInputProvider(GLFWwindow *window); - ~CGlfwInputProvider(); + GlfwInputProvider(GLFWwindow *window); + ~GlfwInputProvider(); virtual void addInputListener(IInputListener *listener) override; virtual void removeInputListener(IInputListener *listener) override; @@ -33,5 +33,5 @@ class CGlfwInputProvider : public IInputProvider GLFWwindow *m_window; - static std::unordered_map s_instances; + static std::unordered_map s_instances; }; diff --git a/Graphics/Lib/include/graphics/input/IInputListener.h b/Engine/Lib/include/kern/graphics/input/IInputListener.h similarity index 100% rename from Graphics/Lib/include/graphics/input/IInputListener.h rename to Engine/Lib/include/kern/graphics/input/IInputListener.h diff --git a/Graphics/Lib/include/graphics/input/IInputProvider.h b/Engine/Lib/include/kern/graphics/input/IInputProvider.h similarity index 91% rename from Graphics/Lib/include/graphics/input/IInputProvider.h rename to Engine/Lib/include/kern/graphics/input/IInputProvider.h index bc8786d..70ab006 100644 --- a/Graphics/Lib/include/graphics/input/IInputProvider.h +++ b/Engine/Lib/include/kern/graphics/input/IInputProvider.h @@ -1,6 +1,6 @@ #pragma once -#include "graphics/input/EKeyCode.h" +#include "kern/graphics/input/KeyCode.h" class IInputListener; diff --git a/Graphics/Lib/include/graphics/input/EKeyCode.h b/Engine/Lib/include/kern/graphics/input/KeyCode.h similarity index 96% rename from Graphics/Lib/include/graphics/input/EKeyCode.h rename to Engine/Lib/include/kern/graphics/input/KeyCode.h index 8d28bce..7556409 100644 --- a/Graphics/Lib/include/graphics/input/EKeyCode.h +++ b/Engine/Lib/include/kern/graphics/input/KeyCode.h @@ -1,6 +1,6 @@ #pragma once -enum class EKeyCode +enum class KeyCode { KeyA, KeyB, diff --git a/Engine/Lib/include/kern/graphics/io/SceneLoader.h b/Engine/Lib/include/kern/graphics/io/SceneLoader.h new file mode 100644 index 0000000..1ae7c33 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/io/SceneLoader.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "kern/graphics/SceneConfig.h" +#include "kern/graphics/animation/AnimationObjectType.h" + +class IScene; +class IResourceManager; +class AnimationWorld; + +/** + * \brief Scene loader utility class. + * Populates scene with static geometry from file. + * Used for testing only, ids are not stored. + */ + +class SceneLoader +{ + public: + /** + * \brief Create scene loader with resource manager. + */ + SceneLoader(IResourceManager &resourceManager); + bool load(const std::string &file, IScene &scene, AnimationWorld &animationWorld); + + protected: + bool loadSceneObjects(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + bool loadSceneObject(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + + bool loadPointLights(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + bool loadPointLight(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + + bool loadDirectionalLights(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + bool loadDirectionalLight(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld); + + bool loadAmbientLight(const nlohmann::json &node, IScene &scene); + + bool loadAnimationControllers(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld, + SceneObjectId id, AnimationObjectType type); + + bool loadAnimationController(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld, + SceneObjectId id, AnimationObjectType type); + + private: + IResourceManager &m_resourceManager; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/proxy/CSceneObjectProxy.h b/Engine/Lib/include/kern/graphics/proxy/SceneObjectProxy.h similarity index 74% rename from Graphics/Lib/include/graphics/graphics/proxy/CSceneObjectProxy.h rename to Engine/Lib/include/kern/graphics/proxy/SceneObjectProxy.h index 3b1a759..12331bc 100644 --- a/Graphics/Lib/include/graphics/graphics/proxy/CSceneObjectProxy.h +++ b/Engine/Lib/include/kern/graphics/proxy/SceneObjectProxy.h @@ -2,13 +2,13 @@ #include -#include "graphics/graphics/IScene.h" +#include "kern/graphics/IScene.h" -class CSceneObjectProxy +class SceneObjectProxy { public: - CSceneObjectProxy(); - CSceneObjectProxy(IScene *scene, SceneObjectId id); + SceneObjectProxy(); + SceneObjectProxy(IScene *scene, SceneObjectId id); bool init(IScene *scene, SceneObjectId id); @@ -32,8 +32,8 @@ class CSceneObjectProxy void getUpdate() const; void sendUpdate(); - mutable ResourceId m_mesh = invalidResource; - mutable ResourceId m_material = invalidResource; + mutable ResourceId m_mesh = InvalidResource; + mutable ResourceId m_material = InvalidResource; mutable glm::vec3 m_position; mutable glm::quat m_rotation; mutable glm::vec3 m_scale; @@ -41,5 +41,5 @@ class CSceneObjectProxy bool m_init = false; IScene *m_scene = nullptr; - SceneObjectId m_objectId = invalidObject; + SceneObjectId m_objectId = InvalidObject; }; \ No newline at end of file diff --git a/Engine/Lib/include/kern/graphics/renderer/DeferredRenderer.h b/Engine/Lib/include/kern/graphics/renderer/DeferredRenderer.h new file mode 100644 index 0000000..27f54d1 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/renderer/DeferredRenderer.h @@ -0,0 +1,393 @@ +#pragma once + +#include +#include + +#include "kern/foundation/Transformer.h" + +#include "kern/graphics/IRenderer.h" +#include "kern/graphics/renderer/FrameBuffer.h" +#include "kern/graphics/renderer/RenderRequest.h" +#include "kern/graphics/renderer/pass/ScreenQuadPass.h" + +#include "kern/resource/ResourceId.h" + +class ShaderProgram; +class IResourceManager; +class ISceneQuery; + +/** + * \brief Deferred renderer implementation. + */ +class DeferredRenderer : public IRenderer +{ + public: + DeferredRenderer(); + ~DeferredRenderer(); + + bool init(IResourceManager &manager); + + void draw(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager); + + static DeferredRenderer *create(IResourceManager &manager); + + protected: + /** + * \brief Writes geometry data into g-buffer. + */ + void geometryPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query); + + /** + * \brief Performs shadow map calculation. + */ + void shadowMapPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager); + + /** + * \brief Performs shadow cube calculation. + */ + void shadowCubePass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager); + + /** + * \brief Writes light data into l-buffer. + */ + void lightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query); + + /** + * \brief Writes point light data to l-buffer. + */ + void pointLightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query); + + /** + * \brief Writes directional light data to l-buffer. + */ + void directionalLightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query); + + /** + * \brief Performs scene illumination and tone mapping. + */ + void illuminationPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query); + + /** + * \brief Performs post processing of lit scene. + */ + void postProcessPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void fogPass(const ICamera &camera, const Window &, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief FXAA Pass. + */ + void fxaaPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Vertical gauss blur pass. + */ + void gaussBlurVerticalPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Horizontal gauss blur pass. + */ + void gaussBlurHorizontalPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void depthOfFieldPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture, + const std::shared_ptr &blurTexture); + + /** + * \brief Draws scene texture to main FBO. + */ + void displayPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void passthroughPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void godRayPass1(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void godRayPass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture, + const std::shared_ptr &godrayTexture); + + /** + * \brief Depth visualization pass. + * + * For debugging. + */ + void visualizeDepthPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager); + + /** + * \brief Vignette blur pass. + */ + void vignetteBlurPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Bloom pass 1, writes blooom texture. + */ + void bloomPass1(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Bloom pass 2, blends bloom texture on scene texture. + */ + void bloomPass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture, + const std::shared_ptr &bloomTexture); + + /** + * \brief Lens flare pass, blends lens flare texture on scene texture. + */ + void lensFlarePass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void lensFlarePass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + void lensFlarePass3(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture, + const std::shared_ptr &lensTexture); + + /** + * \brief Cel pass, blends Cel texture on scene texture. + */ + void celPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Tone map pass for HDR to LDR conversion. + * + * This pass should be done at the end of the post porcessing pipeline. + */ + void toneMapPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture); + + /** + * \brief Initializes resources for geometry pass. + */ + bool initGeometryPass(IResourceManager &manager); + + /** + * \brief Initializes resources for point light pass. + */ + bool initPointLightPass(IResourceManager &manager); + + /** + * \brief Initializes resources for directional light pass. + */ + bool initDirectionalLightPass(IResourceManager &manager); + + /** + * \brief Initializes resources for illumination pass. + */ + bool initIlluminationPass(IResourceManager &manager); + + /** + * \brief Initializes resources for shadow map pass + */ + bool initShadowMapPass(IResourceManager &manager); + + /** + * \brief Initializes resources for shadow map pass + */ + bool initShadowCubePass(IResourceManager &manager); + + /** + * \brief Initializes post processing pass. + */ + bool initPostProcessPass(IResourceManager &manager); + + /** + * \brief Initializes post process pass for depth of field. + * + * Called by initPostProcesPass. + */ + bool initDepthOfFieldPass(IResourceManager &manager); + + /** + * \brief Initializes vertical gauss blur pass. + */ + bool initGaussBlurVerticalPass(IResourceManager &manager); + + /** + * \brief Initializes horizontal gauss blur pass. + */ + bool initGaussBlurHorizontalPass(IResourceManager &manager); + + /** + * \brief Initializes FXAA pass for post processing. + */ + bool initFxaaPass(IResourceManager &manager); + + /** + * \brief Initializes fog pass for post processing. + */ + bool initFogPass(IResourceManager &manager); + + bool initGodRayPass1(IResourceManager &manager); + bool initGodRayPass2(IResourceManager &manager); + + /** + * \brief Display pass draws final image to screen. + */ + bool initDisplayPass(IResourceManager &manager); + + bool initVisualizeDepthPass(IResourceManager &manager); + + /** + * \brief Initializes distortion pass. + */ + bool initVignetteBlurPass(IResourceManager &manager); + + /** + * \brief Bloom technique. + */ + bool initBloomPass1(IResourceManager &manager); + bool initBloomPass2(IResourceManager &manager); + + /** + * \brief Lens flare technique. + */ + bool initLensFlarePass(IResourceManager &manager); + + /** + * \brief Lens flare technique. + */ + bool initLensFlarePass2(IResourceManager &manager); + + /** + * \brief Lens flare technique. + */ + bool initLensFlarePass3(IResourceManager &manager); + + /** + * \brief Lens flare technique. + */ + bool initCelPass(IResourceManager &manager); + + /** + * \brief Tone mapping pass. + */ + bool initToneMapPass(IResourceManager &manager); + + void draw(Mesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, + const glm::mat4 &scale, Material *material, const IGraphicsResourceManager &manager, + ShaderProgram *shader); + + private: + Transformer m_transformer; /**< Stores current transformation matrices. */ + + // Geometry pass + // TODO Put into geometry pass class + FrameBuffer m_geometryBuffer; /**< GBuffer. */ + std::shared_ptr m_depthTexture = nullptr; /**< Depth texture attachment. */ + std::shared_ptr m_diffuseGlowTexture = + nullptr; /**< Diffuse texture with glow as alpha. */ + std::shared_ptr + m_normalSpecularTexture; /**< Normal texture with specularity as alpha. */ + ResourceId m_geometryPassShaderId = InvalidResource; + + // Shadow map pass + ResourceId m_shadowMapPassShaderId = InvalidResource; + FrameBuffer m_shadowMapBuffer; + std::shared_ptr m_shadowDepthTexture = nullptr; + + // Shadow cube pass + ResourceId m_shadowCubePassShaderId = InvalidResource; + FrameBuffer m_shadowCubeBuffer; + std::shared_ptr m_shadowCubeDepthTexture = nullptr; + std::shared_ptr m_shadowCubeTexture = nullptr; + + // Light pass common resources + // TODO Put into light pass class + FrameBuffer m_lightPassFrameBuffer; /**< Stores lit scene and depth. */ + std::shared_ptr m_lightPassTexture = nullptr; + + // Point light pass + ResourceId m_pointLightPassShaderId = InvalidResource; + ResourceId m_pointLightSphereId = InvalidResource; + + // Directional light pass + ResourceId m_directionalLightPassShaderId = InvalidResource; + ResourceId m_directionalLightScreenQuadId = InvalidResource; + + // Illumination pass + ResourceId m_illuminationPassShaderId = InvalidResource; + ResourceId m_illuminationPassScreenQuadId = InvalidResource; + FrameBuffer m_illumationPassFrameBuffer; + std::shared_ptr m_illuminationPassTexture = nullptr; + + // Post processing pass + ResourceId m_postProcessScreenQuadId = InvalidResource; + FrameBuffer m_postProcessPassFrameBuffer0; + FrameBuffer m_postProcessPassFrameBuffer1; + FrameBuffer m_postProcessPassFrameBuffer2; + + std::shared_ptr m_postProcessPassTexture0 = nullptr; + std::shared_ptr m_postProcessPassTexture1 = nullptr; + std::shared_ptr m_postProcessPassTexture2 = nullptr; + std::shared_ptr m_postProcessPassOutputTexture = nullptr; + + // Gauss blur pass + ResourceId m_gaussBlurVerticalShaderId = InvalidResource; + ResourceId m_gaussBlurHorizontalShaderId = InvalidResource; + + // FXAA pass + ResourceId m_fxaaPassShaderId = InvalidResource; + + // Fog pass + ResourceId m_fogPassShaderId = InvalidResource; + + // Depth-of-field pass + ResourceId m_depthOfFieldPassShaderId = InvalidResource; + + // Godray pass + ResourceId m_godRayPass1ShaderId = InvalidResource; + ResourceId m_godRayPass2ShaderId = InvalidResource; + + // Display pass for final screen draw + ResourceId m_displayPassShaderId = InvalidResource; + + // Depth visualization pass + ResourceId m_visualizeDepthPassShaderId = InvalidResource; + + // Vignette blur pass + ResourceId m_vignetteBlurPassShaderId = InvalidResource; + + // Bloom pass + ResourceId m_bloomPass1ShaderId = InvalidResource; + ResourceId m_bloomPass2ShaderId = InvalidResource; + + // Lens flare Pass + ResourceId m_lensFlarePassShaderId = InvalidResource; + ResourceId m_lensFlarePass2ShaderId = InvalidResource; + ResourceId m_lensFlarePass3ShaderId = InvalidResource; + + // Cel Pass + ResourceId m_celPassShaderId = InvalidResource; + + // Tonemap pass + ResourceId m_toneMapPassShaderId = InvalidResource; + + // Fullscreen draw pass + ScreenQuadPass m_screenQuadPass; + + // Render requests with custom shaders. + std::list m_customShaderMeshes; +}; diff --git a/Graphics/Lib/include/graphics/graphics/renderer/Draw.h b/Engine/Lib/include/kern/graphics/renderer/Draw.h similarity index 84% rename from Graphics/Lib/include/graphics/graphics/renderer/Draw.h rename to Engine/Lib/include/kern/graphics/renderer/Draw.h index b513389..1320f8f 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/Draw.h +++ b/Engine/Lib/include/kern/graphics/renderer/Draw.h @@ -1,6 +1,6 @@ #pragma once -class CMesh; +class Mesh; /** * \brief Performs GL draw call based on mesh data. @@ -9,4 +9,4 @@ class CMesh; *draw call. * Shader must be set by caller. */ -void draw(CMesh &mesh); \ No newline at end of file +void draw(Mesh &mesh); \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/renderer/CForwardRenderer.h b/Engine/Lib/include/kern/graphics/renderer/ForwardRenderer.h similarity index 65% rename from Graphics/Lib/include/graphics/graphics/renderer/CForwardRenderer.h rename to Engine/Lib/include/kern/graphics/renderer/ForwardRenderer.h index e723860..d5d891d 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/CForwardRenderer.h +++ b/Engine/Lib/include/kern/graphics/renderer/ForwardRenderer.h @@ -2,29 +2,29 @@ #include -#include "graphics/resource/ResourceConfig.h" +#include "kern/resource/ResourceId.h" -#include "graphics/graphics/IRenderer.h" -#include "graphics/graphics/renderer/SRenderRequest.h" +#include "kern/graphics/IRenderer.h" +#include "kern/graphics/renderer/RenderRequest.h" -class CShaderProgram; +class ShaderProgram; class IResourceManager; /** * \brief Forward renderer. */ -class CForwardRenderer : public IRenderer +class ForwardRenderer : public IRenderer { public: /** * \brief Default constructor. */ - CForwardRenderer(); + ForwardRenderer(); /** * \brief Internal resource cleanup. */ - ~CForwardRenderer(); + ~ForwardRenderer(); /** * \brief Draws whole scene. @@ -32,7 +32,7 @@ class CForwardRenderer : public IRenderer * This function implements the highlevel drawing logic for the scene, * selects rendering targets and manages render passes. */ - void draw(const IScene &scene, const ICamera &camera, const IWindow &window, + void draw(const IScene &scene, const ICamera &camera, const Window &window, const IGraphicsResourceManager &manager); /** @@ -43,7 +43,7 @@ class CForwardRenderer : public IRenderer /** * \brief Creates and initializes forward renderer. */ - static CForwardRenderer *create(IResourceManager &manager); + static ForwardRenderer *create(IResourceManager &manager); protected: /** @@ -52,8 +52,8 @@ class CForwardRenderer : public IRenderer * mesh data * and performs actual draw call. */ - void draw(CMesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, - const glm::mat4 &scale, CMaterial *material, const IGraphicsResourceManager &manager); + void draw(Mesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, + const glm::mat4 &scale, Material *material, const IGraphicsResourceManager &manager); private: bool initShaders(IResourceManager &manager); @@ -61,7 +61,7 @@ class CForwardRenderer : public IRenderer glm::mat4 m_currentView = glm::mat4(1.f); /**< Stores the current view matrix. */ glm::mat4 m_currentProjection = glm::mat4(1.f); /**< Stores the current projection matrix. */ - std::list m_customShaderMeshes; /**< Render requests with custom shaders. */ + std::list m_customShaderMeshes; /**< Render requests with custom shaders. */ ResourceId m_forwardShaderId; /**< Forward shader resource id. */ - CShaderProgram *m_forwardShader = nullptr; /**< Currently active shader object. */ + ShaderProgram *m_forwardShader = nullptr; /**< Currently active shader object. */ }; diff --git a/Graphics/Lib/include/graphics/graphics/renderer/CFrameBuffer.h b/Engine/Lib/include/kern/graphics/renderer/FrameBuffer.h similarity index 57% rename from Graphics/Lib/include/graphics/graphics/renderer/CFrameBuffer.h rename to Engine/Lib/include/kern/graphics/renderer/FrameBuffer.h index 59e1f36..2fda6e5 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/CFrameBuffer.h +++ b/Engine/Lib/include/kern/graphics/renderer/FrameBuffer.h @@ -5,20 +5,20 @@ #include #include -#include "graphics/graphics/renderer/ETextureSemantic.h" -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/TextureSemantic.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" -class CTexture; -class CRenderBuffer; +class Texture; +class RenderBuffer; /** * \brief Represents a frame buffer (rendering target). */ -class CFrameBuffer +class FrameBuffer { public: - CFrameBuffer(); - ~CFrameBuffer(); + FrameBuffer(); + ~FrameBuffer(); GLuint getId() const { return m_fboId; }; @@ -33,28 +33,28 @@ class CFrameBuffer void resize(unsigned int width, unsigned int height); - void attach(const std::shared_ptr &texture, GLenum attachment); - void attach(const std::shared_ptr &texture, GLenum attachment, - ETextureSemantic semantic); - void attach(const std::shared_ptr &renderBuffer, GLenum attachment); + void attach(const std::shared_ptr &texture, GLenum attachment); + void attach(const std::shared_ptr &texture, GLenum attachment, + TextureSemantic semantic); + void attach(const std::shared_ptr &renderBuffer, GLenum attachment); /** * \brief returns attached texture based on semantic. * * Not const because the returned texture can be modified. */ - std::shared_ptr getTexture(ETextureSemantic semantic); + std::shared_ptr getTexture(TextureSemantic semantic); static void setDefaultActive(); private: std::vector m_drawBuffers; /**< Stores draw buffer attachments. */ - std::unordered_map> + std::unordered_map> m_textures; /**< Stores attached textures by attachment type. */ - std::unordered_map> + std::unordered_map> m_renderBuffers; /**< Stores attached render buffers. */ - std::map> + std::map> m_texturesBySemantic; /**< Stores textures by their semantic. */ GLuint m_fboId; /**< Frame buffer id. */ diff --git a/Graphics/Lib/include/graphics/graphics/renderer/core/CIndexBuffer.h b/Engine/Lib/include/kern/graphics/renderer/IndexBuffer.h similarity index 65% rename from Graphics/Lib/include/graphics/graphics/renderer/core/CIndexBuffer.h rename to Engine/Lib/include/kern/graphics/renderer/IndexBuffer.h index 3027264..04fb295 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/core/CIndexBuffer.h +++ b/Engine/Lib/include/kern/graphics/renderer/IndexBuffer.h @@ -2,21 +2,21 @@ #include -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /** * \brief Represents an index buffer. */ -class CIndexBuffer +class IndexBuffer { public: - CIndexBuffer(const std::vector &indices, GLenum usage = GL_STATIC_DRAW); + IndexBuffer(const std::vector &indices, GLenum usage = GL_STATIC_DRAW); - CIndexBuffer(const CIndexBuffer &rhs) = delete; + IndexBuffer(const IndexBuffer &rhs) = delete; - ~CIndexBuffer(); + ~IndexBuffer(); - CIndexBuffer &operator=(const CIndexBuffer &rhs) = delete; + IndexBuffer &operator=(const IndexBuffer &rhs) = delete; /** * \brief Sets the VBO as active object. diff --git a/Graphics/Lib/include/graphics/graphics/renderer/CNullRenderer.h b/Engine/Lib/include/kern/graphics/renderer/NullRenderer.h similarity index 56% rename from Graphics/Lib/include/graphics/graphics/renderer/CNullRenderer.h rename to Engine/Lib/include/kern/graphics/renderer/NullRenderer.h index b30ddb5..8cbc8a8 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/CNullRenderer.h +++ b/Engine/Lib/include/kern/graphics/renderer/NullRenderer.h @@ -1,20 +1,17 @@ #pragma once -#include "graphics/graphics/IRenderer.h" +#include "kern/graphics/IRenderer.h" -class CNullRenderer : public IRenderer +class NullRenderer : public IRenderer { public: + ~NullRenderer() = default; + /** * \brief Performs no actual drawing operations. * * Clears screen to black. */ - void draw(const IScene &scene, const ICamera &camera, const IWindow &window, + void draw(const IScene &scene, const ICamera &camera, const Window &window, const IGraphicsResourceManager &manager); - - /** - * \brief Creates and initializes null renderer. - */ - static CNullRenderer *create(); }; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/renderer/CRenderBuffer.h b/Engine/Lib/include/kern/graphics/renderer/RenderBuffer.h similarity index 84% rename from Graphics/Lib/include/graphics/graphics/renderer/CRenderBuffer.h rename to Engine/Lib/include/kern/graphics/renderer/RenderBuffer.h index 1314f4e..f38127d 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/CRenderBuffer.h +++ b/Engine/Lib/include/kern/graphics/renderer/RenderBuffer.h @@ -1,23 +1,23 @@ #pragma once -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /** * \brief Write-only render buffer target as frame buffer attachement. */ -class CRenderBuffer +class RenderBuffer { public: /** * \brief Creates render buffer resource. */ - CRenderBuffer(); - CRenderBuffer(unsigned int width, unsigned int height, GLenum format); + RenderBuffer(); + RenderBuffer(unsigned int width, unsigned int height, GLenum format); /** * \brief Deletes render buffer resource. */ - ~CRenderBuffer(); + ~RenderBuffer(); /** * \brief Initializes with dimensions and format. diff --git a/Engine/Lib/include/kern/graphics/renderer/RenderRequest.h b/Engine/Lib/include/kern/graphics/renderer/RenderRequest.h new file mode 100644 index 0000000..20746c1 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/renderer/RenderRequest.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +class Mesh; +class Material; + +struct RenderRequest +{ + RenderRequest(); + RenderRequest(Mesh *mesh, Material *material, const glm::mat4 &translation, + const glm::mat4 &rotation, const glm::mat4 &scale); + + Mesh *m_mesh; + Material *m_material; + glm::mat4 m_translation; + glm::mat4 m_rotation; + glm::mat4 m_scale; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/renderer/core/RendererCoreConfig.h b/Engine/Lib/include/kern/graphics/renderer/RendererCoreConfig.h similarity index 98% rename from Graphics/Lib/include/graphics/graphics/renderer/core/RendererCoreConfig.h rename to Engine/Lib/include/kern/graphics/renderer/RendererCoreConfig.h index 99d2187..efeb7c2 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/core/RendererCoreConfig.h +++ b/Engine/Lib/include/kern/graphics/renderer/RendererCoreConfig.h @@ -2,13 +2,7 @@ #include -#ifndef __APPLE__ -#include -#else -#define GLFW_INCLUDE_GLCOREARB -#define flextInit -#include -#endif +#include /** * Defines the default application-to-shader interface. diff --git a/Graphics/Lib/include/graphics/graphics/renderer/CSampler.h b/Engine/Lib/include/kern/graphics/renderer/Sampler.h similarity index 70% rename from Graphics/Lib/include/graphics/graphics/renderer/CSampler.h rename to Engine/Lib/include/kern/graphics/renderer/Sampler.h index f382991..0d7ace5 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/CSampler.h +++ b/Engine/Lib/include/kern/graphics/renderer/Sampler.h @@ -1,15 +1,15 @@ #pragma once -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /** * \brief Opengl sampler wrapper. */ -class CSampler +class Sampler { public: - CSampler(); - ~CSampler(); + Sampler(); + ~Sampler(); /** * \brief Bind to texture unit. diff --git a/Graphics/Lib/include/graphics/graphics/renderer/ETextureSemantic.h b/Engine/Lib/include/kern/graphics/renderer/TextureSemantic.h similarity index 91% rename from Graphics/Lib/include/graphics/graphics/renderer/ETextureSemantic.h rename to Engine/Lib/include/kern/graphics/renderer/TextureSemantic.h index f14c5e4..4548e92 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/ETextureSemantic.h +++ b/Engine/Lib/include/kern/graphics/renderer/TextureSemantic.h @@ -1,6 +1,6 @@ #pragma once -enum class ETextureSemantic +enum class TextureSemantic { DiffuseRGB, /**< Stores diffuse rgb data. */ SceneRGBLDR, /**< Stores currently lit scene RGB data in LDR format. */ diff --git a/Graphics/Lib/include/graphics/graphics/renderer/core/CVertexArrayObject.h b/Engine/Lib/include/kern/graphics/renderer/VertexArrayObject.h similarity index 79% rename from Graphics/Lib/include/graphics/graphics/renderer/core/CVertexArrayObject.h rename to Engine/Lib/include/kern/graphics/renderer/VertexArrayObject.h index ea1a30d..b5b437a 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/core/CVertexArrayObject.h +++ b/Engine/Lib/include/kern/graphics/renderer/VertexArrayObject.h @@ -1,23 +1,23 @@ #pragma once -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /** * \brief Represents an OpenGl vertex array object. * A VAO stores and restores binding state of VBOs. */ -class CVertexArrayObject +class VertexArrayObject { public: /** * \brief Resource allocation. */ - CVertexArrayObject(); + VertexArrayObject(); /** * \brief Cleanup of resources. */ - ~CVertexArrayObject(); + ~VertexArrayObject(); /** * \brief Set as active vertex array object. diff --git a/Graphics/Lib/include/graphics/graphics/renderer/core/CVertexBuffer.h b/Engine/Lib/include/kern/graphics/renderer/VertexBuffer.h similarity index 75% rename from Graphics/Lib/include/graphics/graphics/renderer/core/CVertexBuffer.h rename to Engine/Lib/include/kern/graphics/renderer/VertexBuffer.h index f1dce2e..ea35b87 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/core/CVertexBuffer.h +++ b/Engine/Lib/include/kern/graphics/renderer/VertexBuffer.h @@ -2,13 +2,13 @@ #include -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /* * \brief Manages an OpenGL VBO in VRAM. * Stores float triples (x, y, z) and uses static draw modifier. */ -class CVertexBuffer +class VertexBuffer { public: /** @@ -16,15 +16,15 @@ class CVertexBuffer * \param data Float buffer data. * \param usage Buffer usage. */ - CVertexBuffer(const std::vector &data, GLenum usage = GL_STATIC_DRAW); - CVertexBuffer(const CVertexBuffer &rhs) = delete; + VertexBuffer(const std::vector &data, GLenum usage = GL_STATIC_DRAW); + VertexBuffer(const VertexBuffer &rhs) = delete; /** * \brief Frees all GPU resources. */ - ~CVertexBuffer(); + ~VertexBuffer(); - CVertexBuffer &operator=(const CVertexBuffer &rhs) = delete; + VertexBuffer &operator=(const VertexBuffer &rhs) = delete; /** * \brief Sets the VBO as active object. @@ -50,7 +50,7 @@ class CVertexBuffer unsigned int getSize() const; // TODO we might want to have a CMutableVertexBuffer or something similar - CVertexBuffer(GLenum usage = GL_STATIC_DRAW); + VertexBuffer(GLenum usage = GL_STATIC_DRAW); void setData(const std::vector &data); diff --git a/Graphics/Lib/include/graphics/graphics/renderer/pass/IRenderPass.h b/Engine/Lib/include/kern/graphics/renderer/pass/IRenderPass.h similarity index 100% rename from Graphics/Lib/include/graphics/graphics/renderer/pass/IRenderPass.h rename to Engine/Lib/include/kern/graphics/renderer/pass/IRenderPass.h diff --git a/Graphics/Lib/include/graphics/graphics/renderer/pass/CPostProcessPass.h b/Engine/Lib/include/kern/graphics/renderer/pass/PostProcessPass.h similarity index 76% rename from Graphics/Lib/include/graphics/graphics/renderer/pass/CPostProcessPass.h rename to Engine/Lib/include/kern/graphics/renderer/pass/PostProcessPass.h index 49cc3ea..2b0302e 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/pass/CPostProcessPass.h +++ b/Engine/Lib/include/kern/graphics/renderer/pass/PostProcessPass.h @@ -2,7 +2,7 @@ #include -#include "graphics/graphics/renderer/pass/IRenderPass.h" +#include "kern/graphics/renderer/pass/IRenderPass.h" class CPostProcessPass { diff --git a/Engine/Lib/include/kern/graphics/renderer/pass/ScreenQuadPass.h b/Engine/Lib/include/kern/graphics/renderer/pass/ScreenQuadPass.h new file mode 100644 index 0000000..27a09aa --- /dev/null +++ b/Engine/Lib/include/kern/graphics/renderer/pass/ScreenQuadPass.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/renderer/FrameBuffer.h" +#include "kern/graphics/resource/Mesh.h" +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/Texture.h" + +#include "kern/resource/IResourceManager.h" + +/** + * \brief Draws textured screen space quad. + */ +class ScreenQuadPass +{ + public: + ScreenQuadPass(); + + bool init(IResourceManager &manager); + + /** + * \brief Draws screen space quad with specified texture to specified frame + * buffer. + */ + void draw(Texture *diffuseGlowTexture, Texture *lightTexture, Texture *depthTexture, + const glm::mat4 &inverseViewProj, FrameBuffer *fbo, + const IGraphicsResourceManager *manager); + + private: + std::unique_ptr m_quad = nullptr; + ShaderProgram *m_shader = nullptr; + ResourceId m_shaderId = -1; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/renderer/pass/CScreenSpacePass.h b/Engine/Lib/include/kern/graphics/renderer/pass/ScreenSpacePass.h similarity index 60% rename from Graphics/Lib/include/graphics/graphics/renderer/pass/CScreenSpacePass.h rename to Engine/Lib/include/kern/graphics/renderer/pass/ScreenSpacePass.h index 48200e5..281108b 100644 --- a/Graphics/Lib/include/graphics/graphics/renderer/pass/CScreenSpacePass.h +++ b/Engine/Lib/include/kern/graphics/renderer/pass/ScreenSpacePass.h @@ -2,24 +2,24 @@ #include -#include "graphics/graphics/resource/CMesh.h" +#include "kern/graphics/resource/Mesh.h" class IResourceManager; -class CTexture; -class CFrameBuffer; +class Texture; +class FrameBuffer; class IGraphicsResourceManager; /** * \brief Represents a draw pass to implement screen space effects. * Performs a screen space effect with a texture input and frame buffer output. */ -class CScreenSpacePass +class ScreenSpacePass { public: /** * \brief Performs mesh initialization. */ - CScreenSpacePass(); + ScreenSpacePass(); /** * \brief Initialize resources. @@ -30,11 +30,11 @@ class CScreenSpacePass * \brief Draws screen space quad with shader to render target and supplies * textures as shader inputs. */ - void draw(const IGraphicsResourceManager *manager, CFrameBuffer *fbo, - CTexture *texture0 = nullptr, CTexture *texture1 = nullptr, - CTexture *texture2 = nullptr, CTexture *texture3 = nullptr); + void draw(const IGraphicsResourceManager *manager, FrameBuffer *fbo, + Texture *texture0 = nullptr, Texture *texture1 = nullptr, + Texture *texture2 = nullptr, Texture *texture3 = nullptr); private: - std::unique_ptr m_quad = nullptr; /**< Dummy mesh for fullscreen quad. */ + std::unique_ptr m_quad = nullptr; /**< Dummy mesh for fullscreen quad. */ ResourceId m_shaderId = -1; /**< Shader program resource id. */ }; diff --git a/Graphics/Lib/include/graphics/graphics/resource/CGraphicsResourceManager.h b/Engine/Lib/include/kern/graphics/resource/GraphicsResourceManager.h similarity index 68% rename from Graphics/Lib/include/graphics/graphics/resource/CGraphicsResourceManager.h rename to Engine/Lib/include/kern/graphics/resource/GraphicsResourceManager.h index b9f3fc5..156f002 100644 --- a/Graphics/Lib/include/graphics/graphics/resource/CGraphicsResourceManager.h +++ b/Engine/Lib/include/kern/graphics/resource/GraphicsResourceManager.h @@ -5,28 +5,29 @@ #include #include -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/resource/IResourceListener.h" - -#include "graphics/graphics/resource/CMaterial.h" -#include "graphics/graphics/resource/CMesh.h" -#include "graphics/graphics/resource/CModel.h" -#include "graphics/graphics/resource/CShaderProgram.h" -#include "graphics/graphics/resource/CTexture.h" -#include "graphics/graphics/resource/TShaderObject.h" - -class CGraphicsResourceManager : public IGraphicsResourceManager, public IResourceListener +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/resource/Material.h" +#include "kern/graphics/resource/Mesh.h" +#include "kern/graphics/resource/Model.h" +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/TShaderObject.h" +#include "kern/graphics/resource/Texture.h" +#include "kern/resource/IResourceListener.h" +#include "kern/resource/ResourceEvent.h" +#include "kern/resource/ResourceType.h" + +class GraphicsResourceManager : public IGraphicsResourceManager, public IResourceListener { public: /** * \brief Sets resource callbacks. */ - CGraphicsResourceManager(); + GraphicsResourceManager(); /** * \brief Cleans up resource callbacks. */ - ~CGraphicsResourceManager(); + ~GraphicsResourceManager(); /** * \brief On attach callback. @@ -49,42 +50,41 @@ class CGraphicsResourceManager : public IGraphicsResourceManager, public IResour * The function resolves the resource type and forwards the call to specialized * functions. */ - void notify(EResourceType type, ResourceId, EListenerEvent event, - IResourceManager *resourceManager); + void notify(ResourceType type, ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Maps id to internal mesh object. */ - CMesh *getMesh(ResourceId) const; + Mesh *getMesh(ResourceId) const; /** * \brief Maps id to internal material object. */ - CMaterial *getMaterial(ResourceId) const; + Material *getMaterial(ResourceId) const; /** * \brief Maps id to internal model object. */ - CModel *getModel(ResourceId) const; + Model *getModel(ResourceId) const; /** * \brief Maps id to internal texture object. */ - CTexture *getTexture(ResourceId) const; + Texture *getTexture(ResourceId) const; /** * \brief Maps id to internal shader program object. */ - CShaderProgram *getShaderProgram(ResourceId) const; + ShaderProgram *getShaderProgram(ResourceId) const; /** * \brief Returns respective default texture. */ - CTexture *getDefaultDiffuseTexture() const; - CTexture *getDefaultNormalTexture() const; - CTexture *getDefaultSpecularTexture() const; - CTexture *getDefaultGlowTexture() const; - CTexture *getDefaultAlphaTexture() const; + Texture *getDefaultDiffuseTexture() const; + Texture *getDefaultNormalTexture() const; + Texture *getDefaultSpecularTexture() const; + Texture *getDefaultGlowTexture() const; + Texture *getDefaultAlphaTexture() const; protected: /** @@ -146,27 +146,27 @@ class CGraphicsResourceManager : public IGraphicsResourceManager, public IResour /** * \brief Handles resource events for image resources. */ - void handleImageEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleImageEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Handles resource events for mesh resources. */ - void handleMeshEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleMeshEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Handles resource events for material resources. */ - void handleMaterialEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleMaterialEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Handles resource events for model resource. */ - void handleModelEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleModelEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Handles resource events for shader resources. */ - void handleShaderEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleShaderEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); /** * \brief Handles resource events for string resources. @@ -174,21 +174,20 @@ class CGraphicsResourceManager : public IGraphicsResourceManager, public IResour * TODO Consider hot reloading of shader source code and on-the-fly * recompiling of shader objects/programs */ - void handleStringEvent(ResourceId, EListenerEvent event, IResourceManager *resourceManager); + void handleStringEvent(ResourceId, ResourceEvent event, IResourceManager *resourceManager); - std::unordered_map> + std::unordered_map> m_meshes; /**< Maps mesh id from resource manager to GPU side mesh. */ - std::unordered_map> m_textures; /**< Maps image id + std::unordered_map> m_textures; /**< Maps image id from resource manager to GPU side texture. */ - std::unordered_map> - m_materials; /**< Maps material id from resource manager to cached - material. */ + std::unordered_map> m_materials; /**< Maps material id from resource manager + to cached material. */ - std::unordered_map> + std::unordered_map> m_models; /**< Maps model id from resource manager to cached model. */ std::unordered_map>> @@ -213,14 +212,14 @@ class CGraphicsResourceManager : public IGraphicsResourceManager, public IResour m_fragmentShader; /**< Maps string resource ids to compiled fragment shader objects. */ - std::unordered_map> + std::unordered_map> m_shaderPrograms; /**< Maps resource ids to linked shader programs. */ - std::unique_ptr m_defaultDiffuseTexture = nullptr; /**< Default diffuse texture. */ - std::unique_ptr m_defaultNormalTexture = nullptr; /**< Default normal texture. */ - std::unique_ptr m_defaultSpecularTexture = nullptr; /**< Default specular texture. */ - std::unique_ptr m_defaultGlowTexture = nullptr; /**< Default glow texture. */ - std::unique_ptr m_defaultAlphaTexture = nullptr; /**< Default alpha texture. */ + std::unique_ptr m_defaultDiffuseTexture = nullptr; /**< Default diffuse texture. */ + std::unique_ptr m_defaultNormalTexture = nullptr; /**< Default normal texture. */ + std::unique_ptr m_defaultSpecularTexture = nullptr; /**< Default specular texture. */ + std::unique_ptr m_defaultGlowTexture = nullptr; /**< Default glow texture. */ + std::unique_ptr m_defaultAlphaTexture = nullptr; /**< Default alpha texture. */ std::list m_registeredManagers; /**< Resource managers, this listener is diff --git a/Engine/Lib/include/kern/graphics/resource/Material.h b/Engine/Lib/include/kern/graphics/resource/Material.h new file mode 100644 index 0000000..73bbae6 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/resource/Material.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/Texture.h" + +/** + * \brief Material class. + * + * Stores visual properties of a surface. + */ +class Material +{ + public: + Material(const Texture *diffuse, const Texture *normal, const Texture *specular, + const Texture *glow, const Texture *alpha); + + bool init(const Texture *diffuse, const Texture *normal, const Texture *specular, + const Texture *glow, const Texture *alpha); + + bool hasDiffuse() const; + bool hasNormal() const; + bool hasSpecular() const; + bool hasGlow() const; + bool hasAlpha() const; + + const Texture *getDiffuse() const; + const Texture *getNormal() const; + const Texture *getSpecular() const; + const Texture *getGlow() const; + const Texture *getAlpha() const; + + private: + const Texture *m_diffuseTexture; /**< Base color. */ + const Texture *m_normalTexture; /**< Normal map. */ + const Texture *m_specularTexture; /**< Specular highlights. */ + const Texture *m_glowTexture; /**< Glow map. */ + const Texture *m_alphaTexture; /**< Alpha map. */ +}; diff --git a/Engine/Lib/include/kern/graphics/resource/Mesh.h b/Engine/Lib/include/kern/graphics/resource/Mesh.h new file mode 100644 index 0000000..2a71ebd --- /dev/null +++ b/Engine/Lib/include/kern/graphics/resource/Mesh.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +#include "kern/graphics/collision/BoundingSphere.h" +#include "kern/graphics/renderer/IndexBuffer.h" +#include "kern/graphics/renderer/VertexArrayObject.h" +#include "kern/graphics/renderer/VertexBuffer.h" +#include "kern/resource/PrimitiveType.h" +#include "kern/resource/ResourceId.h" + +/** + * \brief Contains mesh data (vertices, faces, normals and uv data). + * + * Represents mesh data in the VRAM. It holds a buffer object for vertices, + * one for texture coordinates and one for nomal data. the data can be used for + * direct rendering or used in conjunction with an VAO. + */ +class Mesh +{ + public: + Mesh(const std::vector &vertices, const std::vector &indices, + const std::vector &normals, const std::vector &uvs, PrimitiveType type); + + Mesh(const Mesh &) = delete; + Mesh &operator=(const Mesh &) = delete; + + /** + * \brief Deletes graphic resources and frees memory. + */ + ~Mesh(); + + /** + * \brief Initializes mesh with data. + */ + bool init(const std::vector &vertices, const std::vector &indices, + const std::vector &normals, const std::vector &uvs, PrimitiveType type); + + /** + * \brief Returns whether or not an index buffer has been set. + */ + bool hasIndexBuffer() const; + + /** + * \brief Read access to vertex buffer + */ + const std::unique_ptr &getVertexBuffer() const; + + /** + * \brief Read access to index buffer. + */ + const std::unique_ptr &getIndexBuffer() const; + + /** + * \brief Read access to normal buffer + */ + const std::unique_ptr &getNormalBuffer() const; + + /** + * \brief Read access to texture uv buffer + */ + const std::unique_ptr &getUVBuffer() const; + + /** + * \brief Returns primitive type of the mesh. + */ + const PrimitiveType getPrimitiveType() const; + + /** + * \brief Returns vertex array object. + */ + const std::unique_ptr &getVertexArray() const; + + /** + * \brief Returns bounding sphere for view frustum culling. + */ + const BoundingSphere &getBoundingSphere() const; + + /** + * \brief Maps primitive type to GL type. + * Example: Maps PrimitiveType::Triangle to GL_TRIANGLES. + */ + static GLenum toGLPrimitive(PrimitiveType type); + + /** + * \brief Returns primitive size for the type. + * Example: Returns value 3 for PrimitiveType::Triangle. + */ + static unsigned int getPrimitiveSize(PrimitiveType type); + + private: + std::unique_ptr m_vertices; /**< Mesh vertices. */ + std::unique_ptr m_indices; /**< Mesh indices. */ + std::unique_ptr m_normals; /**< Per vertex normals. */ + std::unique_ptr m_uvs; /**< Texture coordinates. */ + std::unique_ptr m_vao; /**< Vertex array object. */ + PrimitiveType m_type; /**< Mesh primitive type. */ + + // For frustum culling + // TODO Should be stored separately? + BoundingSphere m_boundingSphere; /**< Bounding sphere calculated from vertices. */ +}; diff --git a/Engine/Lib/include/kern/graphics/resource/Model.h b/Engine/Lib/include/kern/graphics/resource/Model.h new file mode 100644 index 0000000..92ae552 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/resource/Model.h @@ -0,0 +1,28 @@ +#pragma once + +#include "kern/graphics/resource/Material.h" +#include "kern/graphics/resource/Mesh.h" + +/** + * \brief Model resource stores mesh and material. + */ +class Model +{ + public: + Model(const Mesh *mesh, const Material *material); + + /** + * \brief Initialize form mesh and material. + */ + bool init(const Mesh *mesh, const Material *material); + + bool hasMesh() const; + bool hasMaterial() const; + + const Mesh *getMesh() const; + const Material *getMaterial() const; + + private: + const Mesh *m_mesh = nullptr; /**< Mesh resource. */ + const Material *m_material = nullptr; /**< Material resource. */ +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/resource/CShaderProgram.h b/Engine/Lib/include/kern/graphics/resource/ShaderProgram.h similarity index 91% rename from Graphics/Lib/include/graphics/graphics/resource/CShaderProgram.h rename to Engine/Lib/include/kern/graphics/resource/ShaderProgram.h index 36725f3..b6f4106 100644 --- a/Graphics/Lib/include/graphics/graphics/resource/CShaderProgram.h +++ b/Engine/Lib/include/kern/graphics/resource/ShaderProgram.h @@ -4,15 +4,15 @@ #include -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/resource/TShaderObject.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/graphics/resource/TShaderObject.h" -class CTexture; +class Texture; /** * \brief Represents a linked shader program. */ -class CShaderProgram +class ShaderProgram { public: /** @@ -21,7 +21,7 @@ class CShaderProgram * must be valid or program creation will fail and the program object will * be in invalid state after creation. */ - CShaderProgram(TShaderObject *vertex, + ShaderProgram(TShaderObject *vertex, TShaderObject *tessControl, TShaderObject *tessEval, TShaderObject *geometry, @@ -30,7 +30,7 @@ class CShaderProgram /** * \brief Deletes GPU shader resource. */ - ~CShaderProgram(); + ~ShaderProgram(); /** * \brief Initializes the program with new shader objects. @@ -98,7 +98,7 @@ class CShaderProgram bool setUniform(GLint location, const glm::mat4 &m); bool setUniform(const std::string &uniformName, const glm::mat4 &m); - bool setUniform(CTexture &texture, const std::string &textureName, GLint textureUnit); + bool setUniform(Texture &texture, const std::string &textureName, GLint textureUnit); private: static GLuint s_activeShaderProgram; /**< Stores currently active shader id to prevent diff --git a/Graphics/Lib/include/graphics/graphics/resource/TShaderObject.h b/Engine/Lib/include/kern/graphics/resource/TShaderObject.h similarity index 90% rename from Graphics/Lib/include/graphics/graphics/resource/TShaderObject.h rename to Engine/Lib/include/kern/graphics/resource/TShaderObject.h index 3ae1f7b..93d576d 100644 --- a/Graphics/Lib/include/graphics/graphics/resource/TShaderObject.h +++ b/Engine/Lib/include/kern/graphics/resource/TShaderObject.h @@ -1,12 +1,11 @@ #pragma once +#include + #include #include -#include - -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/renderer/debug/RendererDebug.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" /** * \brief Represents a compiled shader object. @@ -113,13 +112,6 @@ bool TShaderObject::init(const std::string &source) // Set validity flag m_valid = true; - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } - return true; } diff --git a/Graphics/Lib/include/graphics/graphics/resource/CTexture.h b/Engine/Lib/include/kern/graphics/resource/Texture.h similarity index 75% rename from Graphics/Lib/include/graphics/graphics/resource/CTexture.h rename to Engine/Lib/include/kern/graphics/resource/Texture.h index 0cdaad1..527ba23 100644 --- a/Graphics/Lib/include/graphics/graphics/resource/CTexture.h +++ b/Engine/Lib/include/kern/graphics/resource/Texture.h @@ -2,42 +2,43 @@ #include -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/resource/ResourceConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/resource/ResourceId.h" +#include "kern/resource/ColorFormat.h" /** * \brief Texture class. */ -class CTexture +class Texture { public: - CTexture(); + Texture(); /** * \brief Create from image data. */ - CTexture(const std::vector &imageData, unsigned int width, unsigned int height, - EColorFormat format, bool createMipmaps = true); + Texture(const std::vector &imageData, unsigned int width, unsigned int height, + ColorFormat format, bool createMipmaps = true); /** * \brief Creates empty texture. */ - CTexture(unsigned int width, unsigned int height, EColorFormat format, + Texture(unsigned int width, unsigned int height, ColorFormat format, bool createMipmaps = true); // TODO remove this and introduce ability to create cubetextures (necessary // for point light // shadows) - CTexture(GLint id, bool hasMipmaps, unsigned int width, unsigned int height, GLint format, + Texture(GLuint id, bool hasMipmaps, unsigned int width, unsigned int height, GLint format, GLenum externalFormat); - ~CTexture(); + ~Texture(); /** * \brief Initializes texture data. */ bool init(const std::vector &imageData, unsigned int width, unsigned int height, - EColorFormat format, bool createMipmaps = true); + ColorFormat format, bool createMipmaps = true); bool init(unsigned int width, unsigned int height, GLint format); diff --git a/Graphics/Lib/include/graphics/sampler/Interpolation.h b/Engine/Lib/include/kern/graphics/sampler/Interpolation.h similarity index 100% rename from Graphics/Lib/include/graphics/sampler/Interpolation.h rename to Engine/Lib/include/kern/graphics/sampler/Interpolation.h diff --git a/Graphics/Lib/include/graphics/sampler/TSampler.h b/Engine/Lib/include/kern/graphics/sampler/TSampler.h similarity index 100% rename from Graphics/Lib/include/graphics/sampler/TSampler.h rename to Engine/Lib/include/kern/graphics/sampler/TSampler.h diff --git a/Graphics/Lib/include/graphics/graphics/scene/CScene.h b/Engine/Lib/include/kern/graphics/scene/Scene.h similarity index 84% rename from Graphics/Lib/include/graphics/graphics/scene/CScene.h rename to Engine/Lib/include/kern/graphics/scene/Scene.h index 7424aed..32ece18 100644 --- a/Graphics/Lib/include/graphics/graphics/scene/CScene.h +++ b/Engine/Lib/include/kern/graphics/scene/Scene.h @@ -5,22 +5,22 @@ #include -#include "graphics/graphics/IScene.h" +#include "kern/graphics/IScene.h" -struct SSceneObject; -struct SScenePointLight; -struct SSceneDirectionalLight; +struct SceneObject; +struct ScenePointLight; +struct SceneDirectionalLight; class IGraphicsResourceManager; /** * \brief Simple scene implementation. */ -class CScene : public IScene +class Scene : public IScene { public: - CScene(const IGraphicsResourceManager *resourceManager); - ~CScene(); + Scene(const IGraphicsResourceManager *resourceManager); + ~Scene(); SceneObjectId createObject(ResourceId model, const glm::vec3 &position, const glm::quat &rotation, const glm::vec3 &scale) override; @@ -71,9 +71,9 @@ class CScene : public IScene glm::vec3 m_ambientColor = glm::vec3(1.f); /**< Global ambient light color. */ float m_ambientIntensity = 0.f; /**< Global ambient light intensity. */ - std::vector m_objects; /**< Drawable scene objects. */ - std::vector m_pointLights; /**< Point lights. */ - std::vector m_directionalLights; /**< Directional lights. */ + std::vector m_objects; /**< Drawable scene objects. */ + std::vector m_pointLights; /**< Point lights. */ + std::vector m_directionalLights; /**< Directional lights. */ const IGraphicsResourceManager *m_resourceManager = nullptr; }; diff --git a/Graphics/Lib/include/graphics/graphics/scene/SSceneDirectionalLight.h b/Engine/Lib/include/kern/graphics/scene/SceneDirectionalLight.h similarity index 75% rename from Graphics/Lib/include/graphics/graphics/scene/SSceneDirectionalLight.h rename to Engine/Lib/include/kern/graphics/scene/SceneDirectionalLight.h index 7d14830..c637f08 100644 --- a/Graphics/Lib/include/graphics/graphics/scene/SSceneDirectionalLight.h +++ b/Engine/Lib/include/kern/graphics/scene/SceneDirectionalLight.h @@ -5,10 +5,10 @@ /** * \brief Directional light object data. */ -struct SSceneDirectionalLight +struct SceneDirectionalLight { - SSceneDirectionalLight(); - SSceneDirectionalLight(const glm::vec3 &direction, const glm::vec3 &color, float intensity, + SceneDirectionalLight(); + SceneDirectionalLight(const glm::vec3 &direction, const glm::vec3 &color, float intensity, bool castsShadow); glm::vec3 m_direction = glm::vec3(0.f, -1.f, 0.f); /**< Default direction is down 0/-1/0. */ diff --git a/Engine/Lib/include/kern/graphics/scene/SceneObject.h b/Engine/Lib/include/kern/graphics/scene/SceneObject.h new file mode 100644 index 0000000..3ccafd0 --- /dev/null +++ b/Engine/Lib/include/kern/graphics/scene/SceneObject.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +#include "kern/graphics/collision/BoundingSphere.h" +#include "kern/resource/ResourceId.h" + +/** + * \brief Scene object data struct. + */ +struct SceneObject +{ + SceneObject(); + SceneObject(ResourceId mesh, ResourceId material, const glm::vec3 &position, + const glm::quat &rotation, const glm::vec3 &scale, bool visible, + const BoundingSphere &sphere); + + SceneObject(ResourceId model, const glm::vec3 &position, const glm::quat &rotation, + const glm::vec3 &scale, bool visible, const BoundingSphere &sphere); + + void updateBoundingSphere(); + + ResourceId m_mesh = InvalidResource; + ResourceId m_material = InvalidResource; + ResourceId m_model = InvalidResource; + glm::vec3 m_position = glm::vec3(0.f); + glm::quat m_rotation = glm::quat(0.f, 0.f, 0.f, 0.f); + glm::vec3 m_scale = glm::vec3(1.f); + bool m_visible = true; + BoundingSphere boundingSphere; /**< Translated and scaled bounding sphere. */ +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/graphics/scene/SScenePointLight.h b/Engine/Lib/include/kern/graphics/scene/ScenePointLight.h similarity index 79% rename from Graphics/Lib/include/graphics/graphics/scene/SScenePointLight.h rename to Engine/Lib/include/kern/graphics/scene/ScenePointLight.h index 1dc5721..0bf2f4c 100644 --- a/Graphics/Lib/include/graphics/graphics/scene/SScenePointLight.h +++ b/Engine/Lib/include/kern/graphics/scene/ScenePointLight.h @@ -6,10 +6,10 @@ * \brief Point light object data. * TODO Add constructors */ -struct SScenePointLight +struct ScenePointLight { - SScenePointLight(); - SScenePointLight(const glm::vec3 &position, float radius, const glm::vec3 &color, + ScenePointLight(); + ScenePointLight(const glm::vec3 &position, float radius, const glm::vec3 &color, float intensity, bool castsShadow); glm::vec3 m_position = glm::vec3(0.f); /**< Default position is origin at 0/0/0. */ diff --git a/Graphics/Lib/include/graphics/graphics/scene/CSceneQuery.h b/Engine/Lib/include/kern/graphics/scene/SceneQuery.h similarity index 84% rename from Graphics/Lib/include/graphics/graphics/scene/CSceneQuery.h rename to Engine/Lib/include/kern/graphics/scene/SceneQuery.h index 15fd062..082e306 100644 --- a/Graphics/Lib/include/graphics/graphics/scene/CSceneQuery.h +++ b/Engine/Lib/include/kern/graphics/scene/SceneQuery.h @@ -2,18 +2,18 @@ #include -#include "graphics/graphics/ISceneQuery.h" +#include "kern/graphics/ISceneQuery.h" /** * \brief Scene query implementation. */ -class CSceneQuery : public ISceneQuery +class SceneQuery : public ISceneQuery { public: /** * \brief Sets initial storage. */ - CSceneQuery(unsigned int objectStorage = 200, unsigned int lightStorage = 100); + SceneQuery(unsigned int objectStorage = 200, unsigned int lightStorage = 100); void addObject(SceneObjectId id); diff --git a/Graphics/Lib/include/graphics/graphics/system/CGraphicsSystem.h b/Engine/Lib/include/kern/graphics/system/GraphicsSystem.h similarity index 66% rename from Graphics/Lib/include/graphics/graphics/system/CGraphicsSystem.h rename to Engine/Lib/include/kern/graphics/system/GraphicsSystem.h index 2bda4d2..a1f0194 100644 --- a/Graphics/Lib/include/graphics/graphics/system/CGraphicsSystem.h +++ b/Engine/Lib/include/kern/graphics/system/GraphicsSystem.h @@ -3,20 +3,16 @@ #include #include -#include +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/IGraphicsSystem.h" +#include "kern/graphics/IRenderer.h" +#include "kern/graphics/IScene.h" -#include "graphics/graphics/CDebugInfoDisplay.h" -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/graphics/IGraphicsSystem.h" -#include "graphics/graphics/IRenderer.h" -#include "graphics/graphics/IScene.h" -#include "graphics/graphics/system/SGraphicsSettings.h" - -class CGraphicsSystem : public IGraphicsSystem +class GraphicsSystem : public IGraphicsSystem { public: - CGraphicsSystem(); - ~CGraphicsSystem(); + GraphicsSystem(); + ~GraphicsSystem(); bool init(IResourceManager &manager); void setActiveRenderer(const std::string &renderer); @@ -32,16 +28,13 @@ class CGraphicsSystem : public IGraphicsSystem void toggleWireframeMode(); void toggleViewFrustumCulling(); - void draw(IWindow &window); + void draw(Window &window); private: bool m_wireframeMode = false; /**< Wireframe mode flag. */ bool m_drawDebugOverlay = false; bool m_transparentDebugOverlay = true; - CDebugInfo m_debugInfo; /**< Debug info data. */ - std::unique_ptr m_debugInfoDisplay = - nullptr; /**< Debug info overlay renderer. */ // Debug info double m_lastCallTime = 0.f; diff --git a/Engine/Lib/include/kern/resource/ColorFormat.h b/Engine/Lib/include/kern/resource/ColorFormat.h new file mode 100644 index 0000000..d81ec50 --- /dev/null +++ b/Engine/Lib/include/kern/resource/ColorFormat.h @@ -0,0 +1,12 @@ +#pragma once + +/** + * \brief Color format for texture data. + */ +enum class ColorFormat +{ + GreyScale8 = 1, + RGB24 = 3, + RGBA32 = 4, + Invalid +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/resource/IResourceListener.h b/Engine/Lib/include/kern/resource/IResourceListener.h similarity index 72% rename from Graphics/Lib/include/graphics/resource/IResourceListener.h rename to Engine/Lib/include/kern/resource/IResourceListener.h index f0203e7..79c0043 100644 --- a/Graphics/Lib/include/graphics/resource/IResourceListener.h +++ b/Engine/Lib/include/kern/resource/IResourceListener.h @@ -1,6 +1,8 @@ #pragma once -#include "graphics/resource/ResourceConfig.h" +#include "kern/resource/ResourceId.h" +#include "kern/resource/ResourceType.h" +#include "kern/resource/ResourceEvent.h" class IResourceManager; @@ -14,7 +16,7 @@ class IResourceListener /** * \brief Virtual destructor for interface class. */ - virtual ~IResourceListener(); + virtual ~IResourceListener() = default; /** * \brief Called on attaching listener. @@ -29,6 +31,6 @@ class IResourceListener /** * \brief Called on resource event. */ - virtual void notify(EResourceType type, ResourceId id, EListenerEvent event, + virtual void notify(ResourceType type, ResourceId id, ResourceEvent event, IResourceManager *resourceManager) = 0; }; diff --git a/Engine/Lib/include/kern/resource/IResourceLoader.h b/Engine/Lib/include/kern/resource/IResourceLoader.h new file mode 100644 index 0000000..afd96cf --- /dev/null +++ b/Engine/Lib/include/kern/resource/IResourceLoader.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +#include "kern/resource/IResourceManager.h" + +class IResourceLoader +{ + public: + virtual ~IResourceLoader() = default; + + // Loads resource from file and adds it to the resource manager + virtual bool loadFromFile(const std::string& file, IResourceManager& manager) = 0; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/resource/IResourceManager.h b/Engine/Lib/include/kern/resource/IResourceManager.h similarity index 86% rename from Graphics/Lib/include/graphics/resource/IResourceManager.h rename to Engine/Lib/include/kern/resource/IResourceManager.h index 216c5a6..fa755d0 100644 --- a/Graphics/Lib/include/graphics/resource/IResourceManager.h +++ b/Engine/Lib/include/kern/resource/IResourceManager.h @@ -2,8 +2,11 @@ #include #include +#include -#include "graphics/resource/ResourceConfig.h" +#include "kern/resource/ResourceId.h" +#include "kern/resource/PrimitiveType.h" +#include "kern/resource/ColorFormat.h" class IResourceListener; /**< Listener class. */ @@ -18,7 +21,12 @@ class IResourceManager /** * \brief Virtual destructor for interface class. */ - virtual ~IResourceManager(); + virtual ~IResourceManager() = default; + + /** + * Load resource(s) from file + */ + virtual bool loadFromFile(const std::string& file) = 0; /** * \brief Creates mesh and returns id. @@ -26,7 +34,7 @@ class IResourceManager virtual ResourceId createMesh(const std::vector &vertices, const std::vector &indices, const std::vector &normals, const std::vector &uvs, - EPrimitiveType type) = 0; + PrimitiveType type) = 0; /** * \brief Loads mesh from file. @@ -38,7 +46,7 @@ class IResourceManager */ virtual bool getMesh(ResourceId id, std::vector &vertices, std::vector &indices, std::vector &normals, - std::vector &uvs, EPrimitiveType &type) const = 0; + std::vector &uvs, PrimitiveType &type) const = 0; /** * \brief Creates texture object from image data and returns id. @@ -48,18 +56,18 @@ class IResourceManager * \parm format Image format of the provided data. */ virtual ResourceId createImage(const std::vector &imageData, unsigned int width, - unsigned int height, EColorFormat format) = 0; + unsigned int height, ColorFormat format) = 0; /** * \brief Loads image from file. */ - virtual ResourceId loadImage(const std::string &file, EColorFormat format) = 0; + virtual ResourceId loadImage(const std::string &file, ColorFormat format) = 0; /** * \brief Retrieves image data. */ virtual bool getImage(ResourceId id, std::vector &data, unsigned int &width, - unsigned int &height, EColorFormat &format) const = 0; + unsigned int &height, ColorFormat &format) const = 0; /** * \brief Creates material. diff --git a/Engine/Lib/include/kern/resource/Image.h b/Engine/Lib/include/kern/resource/Image.h new file mode 100644 index 0000000..e2dc29f --- /dev/null +++ b/Engine/Lib/include/kern/resource/Image.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "kern/resource/ResourceId.h" +#include "kern/resource/ColorFormat.h" + +/** + * \brief Image data. + */ +struct Image +{ + Image() = default; + Image(std::vector data, unsigned int width, unsigned int height, + ColorFormat format); + + std::vector m_data; + unsigned int m_width = 0; + unsigned int m_height = 0; + ColorFormat m_format = ColorFormat::Invalid; +}; diff --git a/Engine/Lib/include/kern/resource/ImageLoader.h b/Engine/Lib/include/kern/resource/ImageLoader.h new file mode 100644 index 0000000..6e6cc64 --- /dev/null +++ b/Engine/Lib/include/kern/resource/ImageLoader.h @@ -0,0 +1,11 @@ +#pragma once + +#include "kern/resource/IResourceLoader.h" + +class ImageLoader : public IResourceLoader +{ + public: + ~ImageLoader() = default; + + bool loadFromFile(const std::string& file, IResourceManager& manager) override; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/LoadImage.h b/Engine/Lib/include/kern/resource/LoadImage.h new file mode 100644 index 0000000..591c05c --- /dev/null +++ b/Engine/Lib/include/kern/resource/LoadImage.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +#include "kern/resource/ResourceId.h" +#include "kern/resource/ColorFormat.h" +#include "kern/resource/Image.h" + +bool load(const std::string &file, Image &image); +bool load(const std::string &file, ColorFormat format, Image &image); diff --git a/Graphics/Lib/include/graphics/resource/core/LoadMaterial.h b/Engine/Lib/include/kern/resource/LoadMaterial.h similarity index 71% rename from Graphics/Lib/include/graphics/resource/core/LoadMaterial.h rename to Engine/Lib/include/kern/resource/LoadMaterial.h index db62c58..a379537 100644 --- a/Graphics/Lib/include/graphics/resource/core/LoadMaterial.h +++ b/Engine/Lib/include/kern/resource/LoadMaterial.h @@ -2,11 +2,11 @@ #include -#include "graphics/resource/core/SMaterial.h" +#include "kern/resource/SMaterial.h" -class CResourceManager; +class ResourceManager; -bool load(const std::string &file, CResourceManager &manager, SMaterial &material); +bool load(const std::string &file, ResourceManager &manager, SMaterial &material); bool loadMaterialFromIni(const std::string &file, std::string &base, std::string &normal, std::string &specular, std::string &glow, std::string &alpha); diff --git a/Graphics/Lib/include/graphics/resource/core/LoadMesh.h b/Engine/Lib/include/kern/resource/LoadMesh.h similarity index 77% rename from Graphics/Lib/include/graphics/resource/core/LoadMesh.h rename to Engine/Lib/include/kern/resource/LoadMesh.h index 4c3b978..86d630e 100644 --- a/Graphics/Lib/include/graphics/resource/core/LoadMesh.h +++ b/Engine/Lib/include/kern/resource/LoadMesh.h @@ -2,7 +2,7 @@ #include -#include "graphics/resource/core/SMesh.h" +#include "kern/resource/SMesh.h" bool load(const std::string &file, SMesh &mesh); bool loadMeshFromObj(const std::string &file, SMesh &mesh); \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/LoadModel.h b/Engine/Lib/include/kern/resource/LoadModel.h new file mode 100644 index 0000000..e05a9f2 --- /dev/null +++ b/Engine/Lib/include/kern/resource/LoadModel.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#include "kern/resource/ResourceManager.h" +#include "kern/resource/SModel.h" + +bool load(const std::string &file, ResourceManager &manager, SModel &model); +bool loadModelFromJson(const std::string &file, std::string &meshFile, std::string &materialFile); \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/resource/core/LoadShader.h b/Engine/Lib/include/kern/resource/LoadShader.h similarity index 69% rename from Graphics/Lib/include/graphics/resource/core/LoadShader.h rename to Engine/Lib/include/kern/resource/LoadShader.h index 120b637..4fa6f24 100644 --- a/Graphics/Lib/include/graphics/resource/core/LoadShader.h +++ b/Engine/Lib/include/kern/resource/LoadShader.h @@ -2,11 +2,12 @@ #include -#include "graphics/resource/core/SShader.h" +#include "kern/resource/SShader.h" +#include "kern/resource/ResourceManager.h" -class CResourceManager; +class ResourceManager; -bool load(const std::string &file, CResourceManager &manager, SShader &shader); +bool load(const std::string &file, ResourceManager &manager, SShader &shader); bool loadShaderFromIni(const std::string &file, std::string &vertex, std::string &tessControl, std::string &tessEval, std::string &geometry, std::string &fragment); diff --git a/Engine/Lib/include/kern/resource/PrimitiveType.h b/Engine/Lib/include/kern/resource/PrimitiveType.h new file mode 100644 index 0000000..1646f15 --- /dev/null +++ b/Engine/Lib/include/kern/resource/PrimitiveType.h @@ -0,0 +1,13 @@ +#pragma once + +/** + * \brief Primitive type for vertex data. + * NOTE GL_QUAD is deprecated. + */ +enum class PrimitiveType +{ + Point = 1, + Line = 2, + Triangle = 3, + Invalid +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/ResourceEvent.h b/Engine/Lib/include/kern/resource/ResourceEvent.h new file mode 100644 index 0000000..ce9bbbc --- /dev/null +++ b/Engine/Lib/include/kern/resource/ResourceEvent.h @@ -0,0 +1,11 @@ +#pragma once + +/** + * \brief Possible listener events. + */ +enum class ResourceEvent +{ + Create, /**< Specified resource was created. */ + Change, /**< Specified resource was changed. */ + Delete /**< Specified resource was deleted. */ +}; diff --git a/Engine/Lib/include/kern/resource/ResourceId.h b/Engine/Lib/include/kern/resource/ResourceId.h new file mode 100644 index 0000000..a1d7759 --- /dev/null +++ b/Engine/Lib/include/kern/resource/ResourceId.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +typedef int64_t ResourceId; +static const ResourceId InvalidResource = -1; \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/ResourceManager.h b/Engine/Lib/include/kern/resource/ResourceManager.h new file mode 100644 index 0000000..56246dc --- /dev/null +++ b/Engine/Lib/include/kern/resource/ResourceManager.h @@ -0,0 +1,111 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "kern/resource/IResourceLoader.h" +#include "kern/resource/IResourceManager.h" +#include "kern/resource/Image.h" +#include "kern/resource/ResourceEvent.h" +#include "kern/resource/ResourceType.h" +#include "kern/resource/SMaterial.h" +#include "kern/resource/SMesh.h" +#include "kern/resource/SModel.h" +#include "kern/resource/SShader.h" + +/** + * \brief Resource manager implementation. + */ +class ResourceManager : public IResourceManager +{ + public: + ResourceManager() = default; + ~ResourceManager(); + + bool loadFromFile(const std::string &file) override; + + ResourceId createMesh(const std::vector &vertices, const std::vector &indices, + const std::vector &normals, const std::vector &uvs, + PrimitiveType type) override; + + ResourceId loadMesh(const std::string &file) override; + + bool getMesh(ResourceId id, std::vector &vertices, std::vector &indices, + std::vector &normals, std::vector &uvs, PrimitiveType &type) const override; + + ResourceId createImage(const std::vector &imageData, unsigned int width, unsigned int height, + ColorFormat format) override; + + ResourceId loadImage(const std::string &file, ColorFormat format) override; + + bool getImage(ResourceId id, std::vector &data, unsigned int &width, unsigned int &height, + ColorFormat &format) const override; + + ResourceId createMaterial(ResourceId base, ResourceId normal, ResourceId specular, ResourceId glow, + ResourceId alpha) override; + + ResourceId loadMaterial(const std::string &file) override; + + bool getMaterial(ResourceId id, ResourceId &base, ResourceId &normal, ResourceId &specular, ResourceId &glow, + ResourceId &alpha) const override; + + ResourceId createModel(ResourceId mesh, ResourceId material) override; + + ResourceId loadModel(const std::string &file) override; + + bool getModel(ResourceId id, ResourceId &mesh, ResourceId &material) override; + + ResourceId createString(const std::string &text) override; + + ResourceId loadString(const std::string &file) override; + + bool getString(ResourceId id, std::string &text) const override; + + ResourceId createShader(ResourceId vertex, ResourceId tessCtrl, ResourceId tessEval, ResourceId geometry, + ResourceId fragment) override; + + ResourceId loadShader(const std::string &file) override; + + bool getShader(ResourceId id, ResourceId &vertex, ResourceId &tessCtrl, ResourceId &tessEval, ResourceId &geometry, + ResourceId &fragment) const override; + + void addResourceListener(IResourceListener *listener); + void removeResourceListener(IResourceListener *listener); + + // Adds a factory function for crearing a resource loader object for a specific file extension + void addResourceLoaderCreator(const std::string &extension, const std::function()>& creator); + + protected: + void notifyResourceListeners(ResourceType type, ResourceId id, ResourceEvent event); + + private: + ResourceId m_nextMeshId = 0; /**< Next free mesh id. */ + ResourceId m_nextImageId = 0; /**< Next free image id. */ + ResourceId m_nextMaterialId = 0; /**< Next free material id. */ + ResourceId m_nextModelId = 0; /**< Next free model id. */ + ResourceId m_nextStringId = 0; /**< Next free string id. */ + ResourceId m_nextShaderId = 0; /**< Next free shader id. */ + + // TODO Change to vector? + std::unordered_map m_meshes; /**< Loaded meshes. */ + std::unordered_map m_images; /**< Loaded images. */ + std::unordered_map m_materials; /**< Loaded materials. */ + std::unordered_map m_models; /**< Loaded models. */ + std::unordered_map m_strings; /**< Loaded strings. */ + std::unordered_map m_shaders; /**< Loaded shaders. */ + + std::unordered_map m_meshFiles; /**< Maps mesh file to mesh resource id. */ + std::unordered_map m_imageFiles; /**< Maps image file to image resource id. */ + std::unordered_map m_materialFiles; /**< Maps material file to material resource id. */ + std::unordered_map m_modelFiles; /**< Maps model file to model resource id. */ + std::unordered_map m_textFiles; /**< Maps text file to string resource id. */ + std::unordered_map m_shaderFiles; /**< Maps shader program file to shader resource id. */ + + std::list m_resourceListeners; /**< Registered listeners. */ + // Resource loader creation functions + std::unordered_map(void)>> m_resourceLoaderCreators; +}; diff --git a/Engine/Lib/include/kern/resource/ResourceType.h b/Engine/Lib/include/kern/resource/ResourceType.h new file mode 100644 index 0000000..071d8a4 --- /dev/null +++ b/Engine/Lib/include/kern/resource/ResourceType.h @@ -0,0 +1,14 @@ +#pragma once + +/** + * \brief Resource types. + */ +enum class ResourceType +{ + Mesh, + Image, + String, + Shader, + Material, + Model +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/SMaterial.h b/Engine/Lib/include/kern/resource/SMaterial.h new file mode 100644 index 0000000..3b1f76c --- /dev/null +++ b/Engine/Lib/include/kern/resource/SMaterial.h @@ -0,0 +1,18 @@ +#pragma once + +#include "kern/resource/ResourceId.h" + +/** + * \brief Material data. + */ +struct SMaterial +{ + SMaterial() = default; + SMaterial(ResourceId base, ResourceId normal, ResourceId specular, ResourceId glow, ResourceId alpha); + + ResourceId m_base = InvalidResource; + ResourceId m_normal = InvalidResource; + ResourceId m_specular = InvalidResource; + ResourceId m_glow = InvalidResource; + ResourceId m_alpha = InvalidResource; +}; \ No newline at end of file diff --git a/Graphics/Lib/include/graphics/resource/core/SMesh.h b/Engine/Lib/include/kern/resource/SMesh.h similarity index 61% rename from Graphics/Lib/include/graphics/resource/core/SMesh.h rename to Engine/Lib/include/kern/resource/SMesh.h index 769718e..5ce720c 100644 --- a/Graphics/Lib/include/graphics/resource/core/SMesh.h +++ b/Engine/Lib/include/kern/resource/SMesh.h @@ -2,7 +2,8 @@ #include -#include "graphics/resource/ResourceConfig.h" +#include "kern/resource/ResourceId.h" +#include "kern/resource/PrimitiveType.h" /** * \brief Mesh data. @@ -11,10 +12,11 @@ struct SMesh { SMesh(); SMesh(std::vector vertices, std::vector indices, - std::vector normals, std::vector uvs, EPrimitiveType type); + std::vector normals, std::vector uvs, PrimitiveType type); + std::vector m_vertices; std::vector m_indices; std::vector m_normals; std::vector m_uvs; - EPrimitiveType m_type; + PrimitiveType m_type; }; diff --git a/Engine/Lib/include/kern/resource/SModel.h b/Engine/Lib/include/kern/resource/SModel.h new file mode 100644 index 0000000..34d8abf --- /dev/null +++ b/Engine/Lib/include/kern/resource/SModel.h @@ -0,0 +1,15 @@ +#pragma once + +#include "kern/resource/ResourceId.h" + +/** + * \brief Stores model data. + */ +struct SModel +{ + SModel() = default; + SModel(ResourceId mesh, ResourceId material); + + ResourceId m_mesh = InvalidResource; + ResourceId m_material = InvalidResource; +}; \ No newline at end of file diff --git a/Engine/Lib/include/kern/resource/SShader.h b/Engine/Lib/include/kern/resource/SShader.h new file mode 100644 index 0000000..6194c02 --- /dev/null +++ b/Engine/Lib/include/kern/resource/SShader.h @@ -0,0 +1,16 @@ +#pragma once + +#include "kern/resource/ResourceId.h" + +struct SShader +{ + SShader() = default; + SShader(ResourceId vertex, ResourceId tessCtrl, ResourceId tessEval, ResourceId geometry, + ResourceId fragment); + + ResourceId m_vertex = InvalidResource; + ResourceId m_tessCtrl = InvalidResource; + ResourceId m_tessEval = InvalidResource; + ResourceId m_geometry = InvalidResource; + ResourceId m_fragment = InvalidResource; +}; diff --git a/Engine/Lib/source/app/GameApplication.cpp b/Engine/Lib/source/app/GameApplication.cpp new file mode 100644 index 0000000..fee50b7 --- /dev/null +++ b/Engine/Lib/source/app/GameApplication.cpp @@ -0,0 +1,16 @@ +#include "kern/app/GameApplication.h" + +GameApplication::GameApplication() +{ + // + m_gameSystem = std::make_unique(); +} + +GameApplication::~GameApplication() +{ + m_gameSystem = nullptr; + // +} + +bool GameApplication::init() { return true; } +void GameApplication::run() {} \ No newline at end of file diff --git a/Engine/Lib/source/audio/Sound.cpp b/Engine/Lib/source/audio/Sound.cpp new file mode 100644 index 0000000..29b924c --- /dev/null +++ b/Engine/Lib/source/audio/Sound.cpp @@ -0,0 +1,39 @@ +#include "kern/audio/Sound.h" + +#include +#include +#include + +ALenum toALFormat(unsigned short channels, unsigned short bitsPerSample) +{ + bool stereo = channels > 1; + + if (bitsPerSample == 8 && stereo) + return AL_FORMAT_STEREO8; + if (bitsPerSample == 8) + return AL_FORMAT_MONO8; + + if (bitsPerSample == 16 && stereo) + return AL_FORMAT_STEREO16; + if (bitsPerSample == 16) + return AL_FORMAT_MONO16; + + throw std::runtime_error("Invalid format"); +} + +Sound::Sound(const void* pcmSampleData, std::size_t sizeInBytes, unsigned short channels, unsigned short bitsPerSample, + unsigned int frequency) +{ + logd("Creating sound with {} bytes, {} channels, {} bits per sample and frequency of {} hz", sizeInBytes, channels, bitsPerSample, frequency); + alGenBuffers(1, &buffer); + format = toALFormat(channels, bitsPerSample); + alBufferData(buffer, format, pcmSampleData, sizeInBytes, frequency); +} + +Sound::~Sound() { alDeleteBuffers(1, &buffer); } + +ALuint Sound::getBuffer() const { return buffer; } + +ALenum Sound::getOALFormat() const { return format; } + +float Sound::getLength() const { return 0.f; } \ No newline at end of file diff --git a/Engine/Lib/source/audio/SoundEmitter.cpp b/Engine/Lib/source/audio/SoundEmitter.cpp new file mode 100644 index 0000000..8d05950 --- /dev/null +++ b/Engine/Lib/source/audio/SoundEmitter.cpp @@ -0,0 +1,68 @@ +#include "kern/audio/SoundEmitter.h" + +SoundEmitter::SoundEmitter() : SoundEmitter(nullptr) {} + +SoundEmitter::SoundEmitter(const std::shared_ptr& sound) : sound(sound) { alGenSources(1, &source); } + +SoundEmitter::~SoundEmitter() { alDeleteSources(1, &source); } + +void SoundEmitter::play() +{ + stop(); + alSourcei(source, AL_BUFFER, sound->getBuffer()); + alSourcePlay(source); +} + +void SoundEmitter::play(const std::shared_ptr& sound) +{ + setSound(sound); + play(); +} + +void SoundEmitter::stop() { alSourceStop(source); } + +void SoundEmitter::setSound(const std::shared_ptr& sound) +{ + stop(); + this->sound = sound; +} + +void SoundEmitter::setPosition(const glm::vec3& pos) +{ + position = pos; + alSource3f(source, AL_POSITION, position.x, position.y, position.z); +} + +const glm::vec3& SoundEmitter::getPosition() const { return position; } + +void SoundEmitter::setVelocity(const glm::vec3& vel) +{ + velocity = vel; + alSource3f(source, AL_VELOCITY, velocity.x, velocity.y, velocity.z); +} + +const glm::vec3& SoundEmitter::getVelocity() const { return velocity; } + +SoundPriority SoundEmitter::getPriority() const { return priority; } + +void SoundEmitter::setPriority(SoundPriority prio) { priority = prio; } + +float SoundEmitter::getVolume() const { return volume; } + +void SoundEmitter::setVolume(float vol) +{ + alSourcef(source, AL_GAIN, vol); + volume = vol; +} + +bool SoundEmitter::getLooping() const { return looping; } + +void SoundEmitter::setLooping(bool loop) +{ + looping = loop; + alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); +} + +float SoundEmitter::getRadius() const { return radius; } + +void SoundEmitter::setRadius(float radi) { radius = radi; } \ No newline at end of file diff --git a/Engine/Lib/source/audio/SoundListener.cpp b/Engine/Lib/source/audio/SoundListener.cpp new file mode 100644 index 0000000..3adb1fd --- /dev/null +++ b/Engine/Lib/source/audio/SoundListener.cpp @@ -0,0 +1,18 @@ +#include "kern/audio/SoundListener.h" + +#include "AL/al.h" + +void SoundListener::setPosition(const glm::vec3& pos) +{ + position = pos; + alListener3f(AL_POSITION, position.x, position.y, position.z); +} + +void SoundListener::setVelocity(const glm::vec3& velo) +{ + velocity = velo; + alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); +} + +const glm::vec3& SoundListener::getPosition() const { return position; } +const glm::vec3& SoundListener::getVelocity() const { return velocity; } \ No newline at end of file diff --git a/Engine/Lib/source/audio/SoundManager.cpp b/Engine/Lib/source/audio/SoundManager.cpp new file mode 100644 index 0000000..b69695b --- /dev/null +++ b/Engine/Lib/source/audio/SoundManager.cpp @@ -0,0 +1,259 @@ +#include "kern/audio/SoundManager.h" + +#include +#include + +#include + +#define MINIMP3_IMPLEMENTATION +#include + +struct WavHeader +{ + int16_t format = 0; + int16_t channels = 0; + // Samples per second + uint32_t srate = 0; + // Average bytes per second + uint32_t bps = 0; + // Block alignment + int16_t balign = 0; + // Bits per sample? + int16_t amp = 0; +}; + +SoundManager::SoundManager(const std::string& soundDirectory) : directory(soundDirectory) {} + +void SoundManager::registerSound(const std::string& name, const std::string& fileName) +{ + if (namesToFiles.find(name) != namesToFiles.end()) + throw std::runtime_error("Name already exists in mappings"); + + namesToFiles[name] = fileName; +} + +std::shared_ptr SoundManager::getSound(const std::string& name) +{ + auto fileIter = namesToFiles.find(name); + if (fileIter == namesToFiles.end()) + throw std::runtime_error("Name is not registered"); + + auto fileName = fileIter->second; + auto soundIter = filesToSounds.find(fileName); + if (soundIter != filesToSounds.end()) + { + return soundIter->second; + } + + auto sound = loadFromFile(fileName); + if (sound == nullptr) + throw std::runtime_error("Failed to load sound"); + + filesToSounds[fileName] = sound; + return sound; +} + +bool SoundManager::hasSound(const std::string& name) const +{ + auto fileIter = namesToFiles.find(name); + return fileIter != namesToFiles.end(); +} + +std::shared_ptr SoundManager::loadFromFile(const std::string& fileName) +{ + auto extension = fileName.substr(fileName.length() - 4); + auto fullPath = directory + "/" + fileName; + logi("Loading sound file {} from path {}", fileName, directory); + if (extension == ".wav") + { + return loadFromWav(fullPath); + } + else if (extension == ".ogg") + { + // TODO + return nullptr; + } + else if (extension == ".mp3") + { + return loadFromMp3(fullPath); + } + return nullptr; +} + +static std::int32_t convert_to_int(char* buffer, std::size_t len) +{ + std::int32_t a = 0; + std::memcpy(&a, buffer, len); + return a; +} + +bool loadWavFile(std::ifstream& file, std::uint8_t& channels, std::int32_t& sampleRate, std::uint8_t& bitsPerSample, + ALsizei& size) +{ + char buffer[4]; + if (!file.is_open()) + return false; + + // the RIFF + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read RIFF"); + } + if (std::strncmp(buffer, "RIFF", 4) != 0) + { + throw std::runtime_error("ERROR: file is not a valid WAVE file (header doesn't begin with RIFF)"); + } + + // the size of the file + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read size of file"); + } + + // the WAVE + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read WAVE"); + } + if (std::strncmp(buffer, "WAVE", 4) != 0) + { + throw std::runtime_error("ERROR: file is not a valid WAVE file (header doesn't contain WAVE)"); + } + + // "fmt/0" + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read fmt/0"); + } + + // this is always 16, the size of the fmt data chunk + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read the 16"); + } + + // PCM should be 1? + if (!file.read(buffer, 2)) + { + throw std::runtime_error("ERROR: could not read PCM"); + } + + // the number of channels + if (!file.read(buffer, 2)) + { + throw std::runtime_error("ERROR: could not read number of channels"); + } + channels = convert_to_int(buffer, 2); + + // sample rate + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read sample rate"); + } + sampleRate = convert_to_int(buffer, 4); + + // (sampleRate * bitsPerSample * channels) / 8 + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read (sampleRate * bitsPerSample * channels) / 8"); + } + + // ?? dafaq + if (!file.read(buffer, 2)) + { + throw std::runtime_error("ERROR: could not read dafaq"); + } + + // bitsPerSample + if (!file.read(buffer, 2)) + { + throw std::runtime_error("ERROR: could not read bits per sample"); + } + bitsPerSample = convert_to_int(buffer, 2); + + // data chunk header "data" + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read data chunk header"); + } + + if (std::strncmp(buffer, "LIST", 4) == 0) + { + // LIST chunk + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read data chunk header"); + } + size = convert_to_int(buffer, 4); + char buf[1000]; + // skip + if (!file.read(buf, size)) + { + throw std::runtime_error("ERROR: could not read data chunk header"); + } + + // data chunk header "data" + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read data chunk header"); + } + } + + if (std::strncmp(buffer, "data", 4) != 0) + { + throw std::runtime_error("ERROR: file is not a valid WAVE file (doesn't have 'data' tag)"); + } + + // size of data + if (!file.read(buffer, 4)) + { + throw std::runtime_error("ERROR: could not read data size"); + } + size = convert_to_int(buffer, 4); + + /* cannot be at the end of file */ + if (file.eof()) + { + throw std::runtime_error("ERROR: reached EOF on the file"); + } + if (file.fail()) + { + throw std::runtime_error("ERROR: fail state set on the file"); + } + + return true; +} + +std::shared_ptr SoundManager::loadFromWav(const std::string& fileName) +{ + std::ifstream ifs(fileName, std::ios::binary); + if (!ifs.is_open()) + throw std::runtime_error("Failed to open file"); + + std::uint8_t channels = 0; + std::int32_t sampleRate = 0; + std::uint8_t bitsPerSample = 0; + ALsizei size = 0; + loadWavFile(ifs, channels, sampleRate, bitsPerSample, size); + + std::vector data(size); + data.resize(size); + ifs.read(data.data(), size); + + return std::make_shared(data.data(), size, channels, bitsPerSample, sampleRate); +} + +std::shared_ptr SoundManager::loadFromMp3(const std::string& fileName) +{ + mp3dec_t mp3; + mp3dec_file_info_t info; + if (mp3dec_load(&mp3, fileName.c_str(), &info, nullptr, nullptr) != 0) + { + throw std::runtime_error("Failed to load mp3"); + } + + auto sound = std::make_shared(info.buffer, info.samples * sizeof(mp3d_sample_t), info.channels, + static_cast(sizeof(mp3d_sample_t) * 8), info.hz); + free(info.buffer); + return sound; +} \ No newline at end of file diff --git a/Engine/Lib/source/audio/SoundSystem.cpp b/Engine/Lib/source/audio/SoundSystem.cpp new file mode 100644 index 0000000..62de6ce --- /dev/null +++ b/Engine/Lib/source/audio/SoundSystem.cpp @@ -0,0 +1,56 @@ +#include "kern/audio/SoundSystem.h" + +#include + +SoundSystem::SoundSystem(const std::string& directory) : manager(std::make_shared(directory)) +{ + // Default device + device = alcOpenDevice(nullptr); + if (device == nullptr) + { + throw std::runtime_error("Device is null"); + } + + context = alcCreateContext(device, nullptr); + if (context == nullptr) + { + throw std::runtime_error("Context is null"); + } + + alcMakeContextCurrent(context); + + // bgm emitter + bgmEmitter = createEmitter(); +} + +SoundSystem::~SoundSystem() +{ + // Cleanup in order + bgmEmitter = nullptr; + emitters.clear(); + manager = nullptr; + alcMakeContextCurrent(nullptr); + + alcDestroyContext(context); + context = nullptr; + + alcCloseDevice(device); + device = nullptr; +} + +SoundListener& SoundSystem::getListener() { return listener; } + +std::shared_ptr& SoundSystem::getManager() { return manager; } + +void SoundSystem::update(float dtime) { return; } + +std::shared_ptr SoundSystem::createEmitter() { return createEmitter(nullptr); } + +std::shared_ptr SoundSystem::createEmitter(const std::shared_ptr sound) +{ + auto emitter = std::make_shared(sound); + emitters.insert(emitter); + return emitter; +} + +std::shared_ptr& SoundSystem::getGlobalSoundEmitter() { return bgmEmitter; } \ No newline at end of file diff --git a/Foundation/Lib/source/io/CIniFile.cpp b/Engine/Lib/source/foundation/IniFile.cpp similarity index 75% rename from Foundation/Lib/source/io/CIniFile.cpp rename to Engine/Lib/source/foundation/IniFile.cpp index 1d8ccd6..c1c03d7 100644 --- a/Foundation/Lib/source/io/CIniFile.cpp +++ b/Engine/Lib/source/foundation/IniFile.cpp @@ -1,9 +1,9 @@ -#include "foundation/io/CIniFile.h" +#include "kern/foundation/IniFile.h" #include #include -bool CIniFile::load(const std::string &file) +bool IniFile::load(const std::string &file) { d_entries.clear(); @@ -54,7 +54,7 @@ bool CIniFile::load(const std::string &file) return true; } -bool CIniFile::save(const std::string &file) +bool IniFile::save(const std::string &file) { // Ini file std::ofstream ofs(file); @@ -77,27 +77,27 @@ bool CIniFile::save(const std::string &file) return true; } -void CIniFile::setValue(const std::string &group, const std::string &key, const std::string &value) +void IniFile::setValue(const std::string &group, const std::string &key, const std::string &value) { d_entries[group][key] = value; return; } -void CIniFile::setValue(const std::string &group, const std::string &key, int value) +void IniFile::setValue(const std::string &group, const std::string &key, int value) { std::stringstream ss; ss << value; setValue(group, key, ss.str()); } -void CIniFile::setValue(const std::string &group, const std::string &key, float value) +void IniFile::setValue(const std::string &group, const std::string &key, float value) { std::stringstream ss; ss << value; setValue(group, key, ss.str()); } -const std::string &CIniFile::getValue(const std::string &group, const std::string &key, +const std::string &IniFile::getValue(const std::string &group, const std::string &key, const std::string &defaultValue) const { if (hasKey(group, key)) @@ -107,7 +107,7 @@ const std::string &CIniFile::getValue(const std::string &group, const std::strin return defaultValue; } -int CIniFile::getValue(const std::string &group, const std::string &key, int defaultValue) const +int IniFile::getValue(const std::string &group, const std::string &key, int defaultValue) const { if (hasKey(group, key)) { @@ -123,7 +123,7 @@ int CIniFile::getValue(const std::string &group, const std::string &key, int def return defaultValue; } -float CIniFile::getValue(const std::string &group, const std::string &key, float defaultValue) const +float IniFile::getValue(const std::string &group, const std::string &key, float defaultValue) const { if (hasKey(group, key)) { @@ -139,9 +139,9 @@ float CIniFile::getValue(const std::string &group, const std::string &key, float return defaultValue; } -bool CIniFile::hasGroup(const std::string &group) const { return d_entries.count(group) == 1; } +bool IniFile::hasGroup(const std::string &group) const { return d_entries.count(group) == 1; } -bool CIniFile::hasKey(const std::string &group, const std::string &key) const +bool IniFile::hasKey(const std::string &group, const std::string &key) const { return hasGroup(group) && d_entries.at(group).count(key) == 1; } diff --git a/Engine/Lib/source/foundation/JsonDeserialize.cpp b/Engine/Lib/source/foundation/JsonDeserialize.cpp new file mode 100644 index 0000000..08325c4 --- /dev/null +++ b/Engine/Lib/source/foundation/JsonDeserialize.cpp @@ -0,0 +1,33 @@ +#include "kern/foundation/JsonDeserialize.h" + +namespace glm +{ +void from_json(const nlohmann::json &j, glm::vec2 &val) +{ + val.x = j[0]; + val.y = j[1]; +} + +void from_json(const nlohmann::json &j, glm::vec3 &val) +{ + val.x = j[0]; + val.y = j[1]; + val.z = j[2]; +} + +void from_json(const nlohmann::json &j, glm::vec4 &val) +{ + val.x = j[0]; + val.y = j[1]; + val.z = j[2]; + val.w = j[3]; +} + +void from_json(const nlohmann::json &j, glm::quat &val) +{ + val.x = j[0]; + val.y = j[1]; + val.z = j[2]; + val.w = j[3]; +} +} \ No newline at end of file diff --git a/Engine/Lib/source/foundation/JsonUtil.cpp b/Engine/Lib/source/foundation/JsonUtil.cpp new file mode 100644 index 0000000..f7511c1 --- /dev/null +++ b/Engine/Lib/source/foundation/JsonUtil.cpp @@ -0,0 +1,146 @@ +#include "kern/foundation/JsonUtil.h" + +#include + +#include + +#include "kern/foundation/JsonDeserialize.h" + +template +bool deserialize(const nlohmann::json &node, const std::string &key, T &value) +{ + auto iter = node.find(key); + if (iter == node.end()) + { + logw("Failed to read json value, key does not exist: {}", key.c_str()); + return false; + } + + try + { + value = node.at(key).get(); + } + catch (const std::exception &e) + { + loge("Failed to read json value: {}", e.what()); + return false; + } + return true; +} + +bool load(const std::string &file, nlohmann::json &value) +{ + std::ifstream ifs(file); + if (!ifs.is_open()) + { + loge("failed to open json file {}.", file.c_str()); + return false; + } + + try + { + value = nlohmann::json::parse(ifs); + } + catch (const nlohmann::json::parse_error &e) + { + loge("Failed to parse json file {}: {}", file.c_str(), e.what()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, int &i) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, i)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, unsigned int &u) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, u)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, float &f) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, f)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, bool &b) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, b)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, glm::vec3 &vec) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, vec)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} + +bool load(const nlohmann::json &node, const std::string &name, std::string &str) +{ + if (node.find(name) == node.end()) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + + if (!deserialize(node, name, str)) + { + loge("Failed to load '{}' parameter.", name.c_str()); + return false; + } + return true; +} \ No newline at end of file diff --git a/Foundation/Lib/source/util/StringUtil.cpp b/Engine/Lib/source/foundation/StringUtil.cpp similarity index 60% rename from Foundation/Lib/source/util/StringUtil.cpp rename to Engine/Lib/source/foundation/StringUtil.cpp index d22e93f..ee7e138 100644 --- a/Foundation/Lib/source/util/StringUtil.cpp +++ b/Engine/Lib/source/foundation/StringUtil.cpp @@ -1,5 +1,4 @@ -#include "foundation/util/StringUtil.h" -#include "foundation/hash/CRC32Util.h" +#include "kern/foundation/StringUtil.h" #include #include @@ -31,17 +30,4 @@ std::string getFileExtension(const std::string &file) // Retrieve file extension std::string extension = file.substr(pos + 1); return extension; -} - -uint32_t crc32Hash(const std::string &text) { return crc32Calculate(text); } - -std::string hexdigest(const std::uint8_t *data, std::uint32_t size) -{ - std::stringstream ss; - ss << std::hex; - for (std::uint32_t i = 0; i < size; ++i) - { - ss << data[i]; - } - return ss.str(); -} +} \ No newline at end of file diff --git a/Foundation/Lib/source/util/Time.cpp b/Engine/Lib/source/foundation/Time.cpp similarity index 88% rename from Foundation/Lib/source/util/Time.cpp rename to Engine/Lib/source/foundation/Time.cpp index 65ba1cf..2ec5cf4 100644 --- a/Foundation/Lib/source/util/Time.cpp +++ b/Engine/Lib/source/foundation/Time.cpp @@ -1,6 +1,6 @@ #include -#include "foundation/util/Time.h" +#include "kern/foundation/Time.h" double getTime() { diff --git a/Foundation/Lib/source/math/TransformUtils.cpp b/Engine/Lib/source/foundation/TransformUtils.cpp similarity index 97% rename from Foundation/Lib/source/math/TransformUtils.cpp rename to Engine/Lib/source/foundation/TransformUtils.cpp index 7601ee8..ab1c967 100644 --- a/Foundation/Lib/source/math/TransformUtils.cpp +++ b/Engine/Lib/source/foundation/TransformUtils.cpp @@ -2,7 +2,7 @@ #include -#include "foundation/math/TransformUtils.h" +#include "kern/foundation/TransformUtils.h" glm::vec3 TransformUtils::rotate(const glm::vec3 &axis, float amount, const glm::vec3 &vector) { diff --git a/Foundation/Lib/source/math/CTransformer.cpp b/Engine/Lib/source/foundation/Transformer.cpp similarity index 75% rename from Foundation/Lib/source/math/CTransformer.cpp rename to Engine/Lib/source/foundation/Transformer.cpp index 4fbf664..69680b6 100644 --- a/Foundation/Lib/source/math/CTransformer.cpp +++ b/Engine/Lib/source/foundation/Transformer.cpp @@ -1,8 +1,8 @@ -#include "foundation/math/CTransformer.h" +#include "kern/foundation/Transformer.h" -#include +#include -void CTransformer::setPosition(const glm::vec3 &position) +void Transformer::setPosition(const glm::vec3 &position) { m_positionVector = position; @@ -16,7 +16,7 @@ void CTransformer::setPosition(const glm::vec3 &position) m_modelViewProjection.m_inverseDirty = true; } -void CTransformer::setRotation(const glm::quat &rotation) +void Transformer::setRotation(const glm::quat &rotation) { m_rotationQuat = rotation; @@ -30,7 +30,7 @@ void CTransformer::setRotation(const glm::quat &rotation) m_modelViewProjection.m_inverseDirty = true; } -void CTransformer::setScale(const glm::vec3 &scale) +void Transformer::setScale(const glm::vec3 &scale) { m_scaleVector = scale; @@ -44,7 +44,7 @@ void CTransformer::setScale(const glm::vec3 &scale) m_modelViewProjection.m_inverseDirty = true; } -void CTransformer::setViewMatrix(const glm::mat4 &view) +void Transformer::setViewMatrix(const glm::mat4 &view) { m_view.m_matrix = view; @@ -58,7 +58,7 @@ void CTransformer::setViewMatrix(const glm::mat4 &view) m_modelViewProjection.m_inverseDirty = true; } -void CTransformer::setProjectionMatrix(const glm::mat4 &projection) +void Transformer::setProjectionMatrix(const glm::mat4 &projection) { m_projection.m_matrix = projection; @@ -72,13 +72,13 @@ void CTransformer::setProjectionMatrix(const glm::mat4 &projection) m_modelViewProjection.m_inverseDirty = true; } -const glm::vec3 &CTransformer::getPosition() const { return m_positionVector; } +const glm::vec3 &Transformer::getPosition() const { return m_positionVector; } -const glm::quat &CTransformer::getRotation() const { return m_rotationQuat; } +const glm::quat &Transformer::getRotation() const { return m_rotationQuat; } -const glm::vec3 &CTransformer::getScale() const { return m_scaleVector; } +const glm::vec3 &Transformer::getScale() const { return m_scaleVector; } -const glm::mat4 &CTransformer::getTranslationMatrix() const +const glm::mat4 &Transformer::getTranslationMatrix() const { if (m_translation.m_matrixDirty) { @@ -88,17 +88,17 @@ const glm::mat4 &CTransformer::getTranslationMatrix() const return m_translation.m_matrix; } -const glm::mat4 &CTransformer::getInverseTranslationMatrix() const +const glm::mat4 &Transformer::getInverseTranslationMatrix() const { if (m_translation.m_inverseDirty) { - m_translation.m_inverse = glm::translate(-m_positionVector); + m_translation.m_inverse = glm::translate(glm::mat4(1.f) , - m_positionVector); m_translation.m_inverseDirty = false; } return m_translation.m_inverse; } -const glm::mat4 &CTransformer::getRotationMatrix() const +const glm::mat4 &Transformer::getRotationMatrix() const { if (m_rotation.m_matrixDirty) { @@ -114,7 +114,7 @@ const glm::mat4 &CTransformer::getRotationMatrix() const return m_rotation.m_matrix; } -const glm::mat4 &CTransformer::getInverseRotationMatrix() const +const glm::mat4 &Transformer::getInverseRotationMatrix() const { if (m_rotation.m_inverseDirty) { @@ -130,28 +130,28 @@ const glm::mat4 &CTransformer::getInverseRotationMatrix() const return m_rotation.m_inverse; } -const glm::mat4 &CTransformer::getScaleMatrix() const +const glm::mat4 &Transformer::getScaleMatrix() const { if (m_scale.m_matrixDirty) { - m_scale.m_matrix = glm::scale(m_scaleVector); + m_scale.m_matrix = glm::scale(glm::mat4(1.f), m_scaleVector); m_scale.m_matrixDirty = false; } return m_scale.m_matrix; } -const glm::mat4 &CTransformer::getInverseScaleMatrix() const +const glm::mat4 &Transformer::getInverseScaleMatrix() const { if (m_scale.m_inverseDirty) { // TODO Prevent div by zero? - m_scale.m_inverse = glm::scale(1.f / m_scaleVector); + m_scale.m_inverse = glm::scale(glm::mat4(1.f) , 1.f / m_scaleVector); m_scale.m_inverseDirty = false; } return m_scale.m_inverse; } -const glm::mat4 &CTransformer::getModelMatrix() const +const glm::mat4 &Transformer::getModelMatrix() const { if (m_model.m_matrixDirty) { @@ -161,7 +161,7 @@ const glm::mat4 &CTransformer::getModelMatrix() const return m_model.m_matrix; } -const glm::mat4 &CTransformer::getInverseModelMatrix() const +const glm::mat4 &Transformer::getInverseModelMatrix() const { if (m_model.m_inverseDirty) { @@ -173,14 +173,14 @@ const glm::mat4 &CTransformer::getInverseModelMatrix() const return m_model.m_inverse; } -const glm::mat4 &CTransformer::getViewMatrix() const +const glm::mat4 &Transformer::getViewMatrix() const { // View matrix is set directly // TODO Set actual camera parameters and calculate view matrix on the fly return m_view.m_matrix; } -const glm::mat4 &CTransformer::getInverseViewMatrix() const +const glm::mat4 &Transformer::getInverseViewMatrix() const { if (m_view.m_inverseDirty) { @@ -191,7 +191,7 @@ const glm::mat4 &CTransformer::getInverseViewMatrix() const return m_view.m_inverse; } -const glm::mat4 &CTransformer::getProjectionMatrix() const +const glm::mat4 &Transformer::getProjectionMatrix() const { // View projection matrix is set directly // TODO Set actual camera parameters and calculate projection matrix on the @@ -199,7 +199,7 @@ const glm::mat4 &CTransformer::getProjectionMatrix() const return m_projection.m_matrix; } -const glm::mat4 &CTransformer::getInverseProjectionMatrix() const +const glm::mat4 &Transformer::getInverseProjectionMatrix() const { if (m_projection.m_inverseDirty) { @@ -210,7 +210,7 @@ const glm::mat4 &CTransformer::getInverseProjectionMatrix() const return m_projection.m_inverse; } -const glm::mat4 &CTransformer::getViewProjectionMatrix() const +const glm::mat4 &Transformer::getViewProjectionMatrix() const { if (m_viewProjection.m_matrixDirty) { @@ -220,7 +220,7 @@ const glm::mat4 &CTransformer::getViewProjectionMatrix() const return m_viewProjection.m_matrix; } -const glm::mat4 &CTransformer::getInverseViewProjectionMatrix() const +const glm::mat4 &Transformer::getInverseViewProjectionMatrix() const { if (m_viewProjection.m_inverseDirty) { @@ -230,7 +230,7 @@ const glm::mat4 &CTransformer::getInverseViewProjectionMatrix() const return m_viewProjection.m_inverse; } -const glm::mat4 &CTransformer::getModelViewProjectionMatrix() const +const glm::mat4 &Transformer::getModelViewProjectionMatrix() const { if (m_modelViewProjection.m_matrixDirty) { @@ -240,7 +240,7 @@ const glm::mat4 &CTransformer::getModelViewProjectionMatrix() const return m_modelViewProjection.m_matrix; } -const glm::mat4 &CTransformer::getInverseModelViewProjectionMatrix() const +const glm::mat4 &Transformer::getInverseModelViewProjectionMatrix() const { if (m_modelViewProjection.m_inverseDirty) { diff --git a/Application/Lib/source/game/AGameState.cpp b/Engine/Lib/source/game/AGameState.cpp similarity index 71% rename from Application/Lib/source/game/AGameState.cpp rename to Engine/Lib/source/game/AGameState.cpp index a6f5e5d..75611a5 100644 --- a/Application/Lib/source/game/AGameState.cpp +++ b/Engine/Lib/source/game/AGameState.cpp @@ -1,4 +1,4 @@ -#include "application/game/AGameState.h" +#include "kern/game/AGameState.h" const std::string errStr("Error"); @@ -7,12 +7,12 @@ AGameState::~AGameState() // Empty } -CGameWorld &AGameState::getGameWorld() { return m_gameWorld; } +GameWorld &AGameState::getGameWorld() { return m_gameWorld; } -const CGameWorld &AGameState::getGameWorld() const { return m_gameWorld; } +const GameWorld &AGameState::getGameWorld() const { return m_gameWorld; } -bool AGameState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, - IResourceManager *resourceManager) +bool AGameState::init(IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, IResourceManager *resourceManager, + SoundSystem *soundSystem) { return true; } diff --git a/Application/Lib/source/game/CGameObject.cpp b/Engine/Lib/source/game/GameObject.cpp similarity index 58% rename from Application/Lib/source/game/CGameObject.cpp rename to Engine/Lib/source/game/GameObject.cpp index dc2257b..b405588 100644 --- a/Application/Lib/source/game/CGameObject.cpp +++ b/Engine/Lib/source/game/GameObject.cpp @@ -1,21 +1,21 @@ -#include "application/game/CGameObject.h" +#include "kern/game/GameObject.h" -#include +#include "kern/graphics/collision/Collidable.h" -#include -#include +#include -#include "application/game/IController.h" +#include "kern/foundation/TransformUtils.h" +#include "kern/game/IGameObjectController.h" // Constructor initializes drawable and matrices -CGameObject::CGameObject() : m_collidable(nullptr) // Collidable +GameObject::GameObject() : m_collidable(nullptr) // Collidable { return; } -CGameObject::~CGameObject() { return; } +GameObject::~GameObject() { return; } -void CGameObject::setRotation(const glm::vec3 &rotation) +void GameObject::setRotation(const glm::vec3 &rotation) { m_rotation = rotation; // Update forward vector @@ -23,40 +23,40 @@ void CGameObject::setRotation(const glm::vec3 &rotation) m_transformationChanged = true; } -void CGameObject::setPosition(const glm::vec3 &position) +void GameObject::setPosition(const glm::vec3 &position) { m_position = position; m_transformationChanged = true; } -void CGameObject::setScale(const glm::vec3 &scale) +void GameObject::setScale(const glm::vec3 &scale) { m_scale = scale; m_transformationChanged = true; } -const glm::vec3 &CGameObject::getRotation() const { return m_rotation; } +const glm::vec3 &GameObject::getRotation() const { return m_rotation; } -void CGameObject::addController(const std::shared_ptr &controller) +void GameObject::addController(const std::shared_ptr &controller) { assert(controller != nullptr); controller->attach(this); m_controllers.push_back(controller); } -void CGameObject::setSceneObject(CSceneObjectProxy *proxy) +void GameObject::setSceneObject(SceneObjectProxy *proxy) { assert(proxy != nullptr); m_sceneObject.reset(proxy); } -const glm::vec3 &CGameObject::getPosition() const { return m_position; } +const glm::vec3 &GameObject::getPosition() const { return m_position; } -const glm::vec3 &CGameObject::getScale() const { return m_scale; } +const glm::vec3 &GameObject::getScale() const { return m_scale; } -const glm::vec3 &CGameObject::getForward() const { return m_forward; } +const glm::vec3 &GameObject::getForward() const { return m_forward; } -void CGameObject::update(float dtime) +void GameObject::update(float dtime) { // Update object controllers for (auto &controller : m_controllers) @@ -84,7 +84,7 @@ void CGameObject::update(float dtime) } } -void CGameObject::markDeleted() +void GameObject::markDeleted() { m_deleteRequested = true; if (m_sceneObject != nullptr) @@ -97,9 +97,9 @@ void CGameObject::markDeleted() } } -bool CGameObject::isDeleteRequested() const { return m_deleteRequested; } +bool GameObject::isDeleteRequested() const { return m_deleteRequested; } -void CGameObject::sendMessage(Message message) +void GameObject::sendMessage(Message message) { for (auto &controller : m_controllers) { @@ -107,7 +107,7 @@ void CGameObject::sendMessage(Message message) } } -void CGameObject::setCollidable(CCollidable *entity) +void GameObject::setCollidable(Collidable *entity) { assert(entity != nullptr); if (m_collidable != entity) @@ -119,14 +119,14 @@ void CGameObject::setCollidable(CCollidable *entity) } } -CCollidable *CGameObject::getCollidable() const +Collidable *GameObject::getCollidable() const { assert(m_collidable != nullptr); return m_collidable; } -bool CGameObject::hasCollidable() const { return m_collidable != nullptr; } +bool GameObject::hasCollidable() const { return m_collidable != nullptr; } -bool CGameObject::isDead() const { return m_dead; } +bool GameObject::isDead() const { return m_dead; } -void CGameObject::setDead() { m_dead = true; } \ No newline at end of file +void GameObject::setDead() { m_dead = true; } \ No newline at end of file diff --git a/Application/Lib/source/game/CGameSystem.cpp b/Engine/Lib/source/game/GameSystem.cpp similarity index 55% rename from Application/Lib/source/game/CGameSystem.cpp rename to Engine/Lib/source/game/GameSystem.cpp index c9839e1..7bc53f9 100644 --- a/Application/Lib/source/game/CGameSystem.cpp +++ b/Engine/Lib/source/game/GameSystem.cpp @@ -1,20 +1,20 @@ -#include "application/game/CGameSystem.h" +#include "kern/game/GameSystem.h" #include -#include +#include -CGameSystem::~CGameSystem() { LOG_DEBUG("Game system destroyed."); } +GameSystem::~GameSystem() { logd("Game system destroyed."); } -CGameSystem::CGameSystem() : m_activeState(nullptr) { LOG_DEBUG("Game system created."); } +GameSystem::GameSystem() : m_activeState(nullptr) { logd("Game system created."); } // Updates game objects -bool CGameSystem::update(float dtime) +bool GameSystem::update(float dtime) { // Exit if state not set if (m_activeState == nullptr) { - LOG_ERROR("No active state is set."); + loge("No active state is set."); return false; } @@ -37,18 +37,18 @@ bool CGameSystem::update(float dtime) return true; } -bool CGameSystem::init(const std::string &initialState, IGraphicsSystem *graphicsSystem, - IInputProvider *inputProvider, IResourceManager *resourceManager) +bool GameSystem::init(const std::string &initialState, IGraphicsSystem *graphicsSystem, IInputProvider *inputProvider, + IResourceManager *resourceManager, SoundSystem *soundSystem) { - LOG_DEBUG("Initializing game system."); - LOG_DEBUG("Game system initial state set to %s.", initialState.c_str()); + logd("Initializing game system."); + logd("Game system initial state set to {}.", initialState.c_str()); // Initialize game states for (auto &entry : m_gameStates) { - if (!entry.second->init(graphicsSystem, inputProvider, resourceManager)) + if (!entry.second->init(graphicsSystem, inputProvider, resourceManager, soundSystem)) { - LOG_ERROR("Failed to initialize game state %s.", entry.first.c_str()); + loge("Failed to initialize game state {}.", entry.first.c_str()); return false; } } @@ -62,28 +62,28 @@ bool CGameSystem::init(const std::string &initialState, IGraphicsSystem *graphic return true; } -bool CGameSystem::addState(const std::string &name, IGameState *state) +bool GameSystem::addState(const std::string &name, IGameState *state) { // Check for duplicates if (m_gameStates.count(name) != 0) { // State with name already exists - LOG_WARNING("Overwriting game state %s.", name.c_str()); + logw("Overwriting game state {}.", name.c_str()); } // Add state m_gameStates[name] = std::unique_ptr(state); - LOG_DEBUG("Added game state %s to game system.", name.c_str()); + logd("Added game state {} to game system.", name.c_str()); return true; } -void CGameSystem::removeState(const std::string &name) +void GameSystem::removeState(const std::string &name) { if (m_gameStates.count(name) == 0) { - LOG_WARNING("Could not remove state %s, the state does not exist.", name.c_str()); + logw("Could not remove state {}, the state does not exist.", name.c_str()); return; } m_gameStates.erase(name); - LOG_DEBUG("Removed game state %s from game system.", name.c_str()); + logd("Removed game state {} from game system.", name.c_str()); } diff --git a/Application/Lib/source/game/CGameWorld.cpp b/Engine/Lib/source/game/GameWorld.cpp similarity index 67% rename from Application/Lib/source/game/CGameWorld.cpp rename to Engine/Lib/source/game/GameWorld.cpp index a63eaf5..9ba2134 100644 --- a/Application/Lib/source/game/CGameWorld.cpp +++ b/Engine/Lib/source/game/GameWorld.cpp @@ -1,8 +1,8 @@ -#include "application/game/CGameWorld.h" +#include "kern/game/GameWorld.h" #include -void CGameWorld::update(float dtime) +void GameWorld::update(float dtime) { for (auto iter = m_objects.begin(); iter != m_objects.end();) { @@ -20,8 +20,8 @@ void CGameWorld::update(float dtime) } } -void CGameWorld::addObject(CGameObject *object) +void GameWorld::addObject(GameObject *object) { assert(object != nullptr); - m_objects.push_back(std::unique_ptr(object)); + m_objects.push_back(std::unique_ptr(object)); } diff --git a/Engine/Lib/source/game/IGGameObjectController.cpp b/Engine/Lib/source/game/IGGameObjectController.cpp new file mode 100644 index 0000000..89e98c5 --- /dev/null +++ b/Engine/Lib/source/game/IGGameObjectController.cpp @@ -0,0 +1,3 @@ +#include "kern/game/IGameObjectController.h" + +IGameObjectController::~IGameObjectController() { return; } \ No newline at end of file diff --git a/Engine/Lib/source/game/IGameState.cpp b/Engine/Lib/source/game/IGameState.cpp new file mode 100644 index 0000000..2d1cd57 --- /dev/null +++ b/Engine/Lib/source/game/IGameState.cpp @@ -0,0 +1,3 @@ +#include "kern/game/IGameState.h" + +IGameState::~IGameState() { return; } \ No newline at end of file diff --git a/Application/Lib/source/io/LoadGame.cpp b/Engine/Lib/source/game/LoadGame.cpp similarity index 53% rename from Application/Lib/source/io/LoadGame.cpp rename to Engine/Lib/source/game/LoadGame.cpp index b4a491c..37f9fd2 100644 --- a/Application/Lib/source/io/LoadGame.cpp +++ b/Engine/Lib/source/game/LoadGame.cpp @@ -1,27 +1,23 @@ -#include "application/io/LoadGame.h" +#include "kern/game/LoadGame.h" -#include +#include -#include #include +#include +#include -#include -#include -#include - -#include "graphics/resource/IResourceManager.h" - -#include "application/game/CGameSystem.h" -#include "application/game/IGameState.h" -//#include "graphics/game/state/CTitleState.h" -//#include "graphics/game/state/CGamePlayState.h" +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" +#include "kern/game/GameSystem.h" +#include "kern/game/IGameState.h" +#include "kern/resource/IResourceManager.h" -bool load(const std::string &file, IResourceManager &manager, CGameSystem &system) +bool load(const std::string &file, IResourceManager &manager, GameSystem &system) { - Json::Value root; + nlohmann::json root; if (!load(file, root)) { - LOG_ERROR("Failed to load game from file %s.", file.c_str()); + loge("Failed to load game from file {}.", file.c_str()); return false; } @@ -29,17 +25,17 @@ bool load(const std::string &file, IResourceManager &manager, CGameSystem &syste std::string name; if (!load(root, "name", name)) { - LOG_ERROR("Failed to load game name identfier from file %s.", file.c_str()); + loge("Failed to load game name identfier from file {}.", file.c_str()); return false; } // TODO Name identifier unused. Use for window title. - LOG_INFO("Loading game %s.", name.c_str()); + logi("Loading game {}.", name.c_str()); // Load game states which contain high level game logic and application // control if (!loadGameStates(root["game_states"], manager, system)) { - LOG_ERROR("Failed to load game states from file %s.", file.c_str()); + loge("Failed to load game states from file {}.", file.c_str()); return false; } @@ -47,35 +43,35 @@ bool load(const std::string &file, IResourceManager &manager, CGameSystem &syste std::string initialState; if (!load(root, "start_state", initialState)) { - LOG_ERROR("Failed to load initial game state from file %s.", file.c_str()); + loge("Failed to load initial game state from file {}.", file.c_str()); return false; } // Load successful - LOG_INFO("Loaded game file %s.", file.c_str()); + logi("Loaded game file {}.", file.c_str()); return true; } -bool loadGameStates(const Json::Value &node, IResourceManager &manager, CGameSystem &system) +bool loadGameStates(const nlohmann::json &node, IResourceManager &manager, GameSystem &system) { // Node empty? - if (node.empty()) + if (node.is_null()) { - LOG_INFO("Missing or empty 'game_states' node. No game states were loaded."); + logi("Missing or empty 'game_states' node. No game states were loaded."); return false; } // Node is array type? - if (!node.isArray()) + if (!node.is_array()) { - LOG_ERROR("The node 'game_states' must be array type."); + loge("The node 'game_states' must be array type."); return false; } // Load game states - for (unsigned int i = 0; i < node.size(); ++i) + for (auto it : node) { - if (!loadGameState(node[i], manager, system)) + if (!loadGameState(it, manager, system)) { return false; } @@ -83,7 +79,7 @@ bool loadGameStates(const Json::Value &node, IResourceManager &manager, CGameSys return true; } -bool loadGameState(const Json::Value &node, IResourceManager &manager, CGameSystem &system) +bool loadGameState(const nlohmann::json &node, IResourceManager &manager, GameSystem &system) { // Load name of state for identification std::string name; @@ -107,14 +103,13 @@ bool loadGameState(const Json::Value &node, IResourceManager &manager, CGameSyst return true; } -bool loadGameState(const std::string &file, const std::string &name, IResourceManager &manager, - CGameSystem &system) +bool loadGameState(const std::string &file, const std::string &name, IResourceManager &manager, GameSystem &system) { // Load json file - Json::Value root; + nlohmann::json root; if (!load(file, root)) { - LOG_ERROR("Failed to load game state from file %s.", file.c_str()); + loge("Failed to load game state from file {}.", file.c_str()); return false; } @@ -124,7 +119,7 @@ bool loadGameState(const std::string &file, const std::string &name, IResourceMa std::string type; if (!load(root, "type", type)) { - LOG_ERROR("Failed to load state type."); + loge("Failed to load state type."); return false; } @@ -132,11 +127,11 @@ bool loadGameState(const std::string &file, const std::string &name, IResourceMa IGameState *state = nullptr; if (type == "title") { - // state = new CTitleState; + // state = new TitleState; } else if (type == "game") { - // state = new CGamePlayState; + // state = new GamePlayState; } // TODO Remove diff --git a/Engine/Lib/source/graphics/ICamera.cpp b/Engine/Lib/source/graphics/ICamera.cpp new file mode 100644 index 0000000..5e2967b --- /dev/null +++ b/Engine/Lib/source/graphics/ICamera.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/ICamera.h" + +ICamera::~ICamera() { return; } diff --git a/Graphics/Lib/source/graphics/IGraphicsResourceManager.cpp b/Engine/Lib/source/graphics/IGraphicsResourceManager.cpp similarity index 54% rename from Graphics/Lib/source/graphics/IGraphicsResourceManager.cpp rename to Engine/Lib/source/graphics/IGraphicsResourceManager.cpp index 015b57f..28dcf93 100644 --- a/Graphics/Lib/source/graphics/IGraphicsResourceManager.cpp +++ b/Engine/Lib/source/graphics/IGraphicsResourceManager.cpp @@ -1,3 +1,3 @@ -#include "graphics/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/IGraphicsResourceManager.h" IGraphicsResourceManager::~IGraphicsResourceManager() { return; } \ No newline at end of file diff --git a/Engine/Lib/source/graphics/IGraphicsSystem.cpp b/Engine/Lib/source/graphics/IGraphicsSystem.cpp new file mode 100644 index 0000000..94e71f6 --- /dev/null +++ b/Engine/Lib/source/graphics/IGraphicsSystem.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/IGraphicsSystem.h" + +IGraphicsSystem::~IGraphicsSystem() {} \ No newline at end of file diff --git a/Engine/Lib/source/graphics/IRenderer.cpp b/Engine/Lib/source/graphics/IRenderer.cpp new file mode 100644 index 0000000..926bbe8 --- /dev/null +++ b/Engine/Lib/source/graphics/IRenderer.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/IRenderer.h" + +IRenderer::~IRenderer() {} \ No newline at end of file diff --git a/Engine/Lib/source/graphics/IScene.cpp b/Engine/Lib/source/graphics/IScene.cpp new file mode 100644 index 0000000..78df46d --- /dev/null +++ b/Engine/Lib/source/graphics/IScene.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/IScene.h" + +IScene::~IScene() { return; } diff --git a/Engine/Lib/source/graphics/ISceneQuery.cpp b/Engine/Lib/source/graphics/ISceneQuery.cpp new file mode 100644 index 0000000..71427ae --- /dev/null +++ b/Engine/Lib/source/graphics/ISceneQuery.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/ISceneQuery.h" + +ISceneQuery::~ISceneQuery() { return; } diff --git a/Engine/Lib/source/graphics/Window.cpp b/Engine/Lib/source/graphics/Window.cpp new file mode 100644 index 0000000..f246eb5 --- /dev/null +++ b/Engine/Lib/source/graphics/Window.cpp @@ -0,0 +1,242 @@ +#include "kern/graphics/Window.h" + +#include +#include + +#include + +#define GLFW_INCLUDE_NONE +#include + +#include "kern/graphics/renderer/RendererCoreConfig.h" + +static void APIENTRY glDebugOutput(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar *message, const void *userParam) +{ + // ignore non-significant error/warning codes + if (id == 131169 || id == 131185 || id == 131218 || id == 131204) + return; + + std::cout << "---------------" << std::endl; + std::cout << "Debug message (" << id << "): " << message << std::endl; + + switch (source) + { + case GL_DEBUG_SOURCE_API: + std::cout << "Source: API"; + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + std::cout << "Source: Window System"; + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: + std::cout << "Source: Shader Compiler"; + break; + case GL_DEBUG_SOURCE_THIRD_PARTY: + std::cout << "Source: Third Party"; + break; + case GL_DEBUG_SOURCE_APPLICATION: + std::cout << "Source: Application"; + break; + case GL_DEBUG_SOURCE_OTHER: + std::cout << "Source: Other"; + break; + } + std::cout << std::endl; + + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + std::cout << "Type: Error"; + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + std::cout << "Type: Deprecated Behaviour"; + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + std::cout << "Type: Undefined Behaviour"; + break; + case GL_DEBUG_TYPE_PORTABILITY: + std::cout << "Type: Portability"; + break; + case GL_DEBUG_TYPE_PERFORMANCE: + std::cout << "Type: Performance"; + break; + case GL_DEBUG_TYPE_MARKER: + std::cout << "Type: Marker"; + break; + case GL_DEBUG_TYPE_PUSH_GROUP: + std::cout << "Type: Push Group"; + break; + case GL_DEBUG_TYPE_POP_GROUP: + std::cout << "Type: Pop Group"; + break; + case GL_DEBUG_TYPE_OTHER: + std::cout << "Type: Other"; + break; + } + std::cout << std::endl; + + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + std::cout << "Severity: high"; + break; + case GL_DEBUG_SEVERITY_MEDIUM: + std::cout << "Severity: medium"; + break; + case GL_DEBUG_SEVERITY_LOW: + std::cout << "Severity: low"; + break; + case GL_DEBUG_SEVERITY_NOTIFICATION: + std::cout << "Severity: notification"; + break; + } + std::cout << std::endl; + std::cout << std::endl; +} + +std::unordered_map Window::s_windows; /**< Window mapping. */ + +Window::Window() : m_window(nullptr), m_width(0), m_height(0), m_mouseCaptured(false) +{ + return; +} + +Window::~Window() +{ + // Remove mapping + s_windows.erase(m_window); +} + +bool Window::init(unsigned int width, unsigned int height, const std::string &name) +{ + if (glfwInit() != GLFW_TRUE) + { + loge("Failed to initialize GLFW."); + return false; + } + + // Setup error callback + glfwSetErrorCallback([](int code, const char* error) { + throw std::runtime_error{ error }; + }); + + glfwWindowHint(GLFW_SAMPLES, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + +#ifndef NDEBUG + // Enable debugging + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); +#endif + + // Create window from parameters + logi("Creating GLFW window for OpenGL version {}.{}.", 4, + 6); + m_window = glfwCreateWindow(width, height, name.c_str(), nullptr, nullptr); + if (m_window == nullptr) + { + loge("Failed to create GLFW window."); + glfwTerminate(); + return false; + } + + int framebufferWidth = 0; + int framebufferHeight = 0; + + glfwGetFramebufferSize(m_window, &framebufferWidth, &framebufferHeight); + + m_width = framebufferWidth; + m_height = framebufferHeight; + + glfwMakeContextCurrent(m_window); + glfwSetInputMode(m_window, GLFW_STICKY_KEYS, GL_FALSE); + // Vsync ON + glfwSwapInterval(1); + +// Load OpenGL extensions +#ifndef __APPLE__ + if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0) + { + glfwTerminate(); + loge("Failed to initialize GL context using GLAD."); + return false; + } +#endif + + // Add mapping + s_windows[m_window] = this; + + // Set window resize callback + glfwSetFramebufferSizeCallback(m_window, &Window::resizeCallback); + +#ifndef NDEBUG + // Setup debug vallback + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(glDebugOutput, nullptr); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); +#endif + + return true; +} + +void Window::setWidth(unsigned int width) { m_width = width; } + +void Window::setHeight(unsigned int height) { m_height = height; } + +unsigned int Window::getWidth() const { return m_width; } + +unsigned int Window::getHeight() const { return m_height; } + +void Window::setActive() const { glfwMakeContextCurrent(m_window); } + +bool Window::isOpen() const { return !glfwWindowShouldClose(m_window); } + +void Window::swapBuffer() { glfwSwapBuffers(m_window); } + +void Window::processEvents() { glfwPollEvents(); } + +void Window::toggleMouseCapture() +{ + // Set capture mode + if (m_mouseCaptured) + { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + else + { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + // Toggle + m_mouseCaptured = !m_mouseCaptured; +} + +GLFWwindow *Window::getGlfwHandle() const { return m_window; } + +void Window::addListener(IWindowListener *l) { m_listeners.insert(l); } + +void Window::removeListener(IWindowListener *l) { m_listeners.erase(l); } + +void Window::resizeCallback(GLFWwindow *window, int width, int height) +{ + assert(width > 0); + assert(height > 0); + if (s_windows.count(window) != 0) + { + Window *win = s_windows.at(window); + win->handleResize(width, height); + } +} + +void Window::handleResize(int width, int height) +{ + setWidth(width); + setHeight(height); + + for (auto &l : m_listeners) + { + l->handleResizeEvent(width, height); + } +} diff --git a/Graphics/Lib/source/animation/CAnimationWorld.cpp b/Engine/Lib/source/graphics/animation/AnimationWorld.cpp similarity index 62% rename from Graphics/Lib/source/animation/CAnimationWorld.cpp rename to Engine/Lib/source/graphics/animation/AnimationWorld.cpp index 2c3d85a..00d580c 100644 --- a/Graphics/Lib/source/animation/CAnimationWorld.cpp +++ b/Engine/Lib/source/graphics/animation/AnimationWorld.cpp @@ -1,10 +1,10 @@ -#include "graphics/animation/CAnimationWorld.h" +#include "kern/graphics/animation/AnimationWorld.h" #include -#include "graphics/animation/IAnimationController.h" +#include "kern/graphics/animation/IAnimationController.h" -void CAnimationWorld::addAnimationController( +void AnimationWorld::addAnimationController( const std::shared_ptr &controller) { assert(controller != nullptr); @@ -14,7 +14,7 @@ void CAnimationWorld::addAnimationController( } } -void CAnimationWorld::update(float timeDiff) +void AnimationWorld::update(float timeDiff) { for (auto &controller : m_animationController) { diff --git a/Engine/Lib/source/graphics/animation/IAnimationController.cpp b/Engine/Lib/source/graphics/animation/IAnimationController.cpp new file mode 100644 index 0000000..6604a86 --- /dev/null +++ b/Engine/Lib/source/graphics/animation/IAnimationController.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/animation/IAnimationController.h" + +IAnimationController::~IAnimationController() {} \ No newline at end of file diff --git a/Graphics/Lib/source/animation/CMovementController.cpp b/Engine/Lib/source/graphics/animation/MovementController.cpp similarity index 86% rename from Graphics/Lib/source/animation/CMovementController.cpp rename to Engine/Lib/source/graphics/animation/MovementController.cpp index fc1e6b1..a18eea4 100644 --- a/Graphics/Lib/source/animation/CMovementController.cpp +++ b/Engine/Lib/source/graphics/animation/MovementController.cpp @@ -1,15 +1,15 @@ -#include "graphics/animation/CMovementController.h" +#include "kern/graphics/animation/MovementController.h" -#include "graphics/graphics/IScene.h" +#include "kern/graphics/IScene.h" -CMovementController::CMovementController(SceneObjectId id, AnimationObjectType type, IScene &scene, +MovementController::MovementController(SceneObjectId id, AnimationObjectType type, IScene &scene, const glm::vec3 &direction) : m_objectId(id), m_type(type), m_scene(scene), m_direction(direction) { m_endTime = glm::length(m_direction) * 2; } -void CMovementController::update(float timeStep) +void MovementController::update(float timeStep) { m_currentTimePoint += timeStep; if (m_currentTimePoint > m_endTime) diff --git a/Graphics/Lib/source/animation/CRotationController.cpp b/Engine/Lib/source/graphics/animation/RotationController.cpp similarity index 78% rename from Graphics/Lib/source/animation/CRotationController.cpp rename to Engine/Lib/source/graphics/animation/RotationController.cpp index 1bb2ff2..d8a7e63 100644 --- a/Graphics/Lib/source/animation/CRotationController.cpp +++ b/Engine/Lib/source/graphics/animation/RotationController.cpp @@ -1,14 +1,14 @@ -#include "graphics/animation/CRotationController.h" +#include "kern/graphics/animation/RotationController.h" -#include "graphics/graphics/IScene.h" +#include "kern/graphics/IScene.h" -CRotationController::CRotationController(SceneObjectId id, AnimationObjectType type, IScene &scene, +RotationController::RotationController(SceneObjectId id, AnimationObjectType type, IScene &scene, const glm::vec3 &rotation) : m_objectId(id), m_type(type), m_scene(scene), m_rotation(rotation) { } -void CRotationController::update(float timeStep) +void RotationController::update(float timeStep) { if (m_type == AnimationObjectType::Model) { diff --git a/Graphics/Lib/source/animation/CSineTranslationController.cpp b/Engine/Lib/source/graphics/animation/SineTranslationController.cpp similarity index 85% rename from Graphics/Lib/source/animation/CSineTranslationController.cpp rename to Engine/Lib/source/graphics/animation/SineTranslationController.cpp index baa6ec1..373f7bb 100644 --- a/Graphics/Lib/source/animation/CSineTranslationController.cpp +++ b/Engine/Lib/source/graphics/animation/SineTranslationController.cpp @@ -1,10 +1,10 @@ -#include "graphics/animation/CSineTranslationController.h" +#include "kern/graphics/animation/SineTranslationController.h" #include -#include "graphics/graphics/IScene.h" +#include "kern/graphics/IScene.h" -CSineTranslationController::CSineTranslationController(SceneObjectId id, AnimationObjectType type, +SineTranslationController::SineTranslationController(SceneObjectId id, AnimationObjectType type, IScene &scene, const glm::vec3 &translation, float timeScale) : m_objectId(id), @@ -15,7 +15,7 @@ CSineTranslationController::CSineTranslationController(SceneObjectId id, Animati { } -void CSineTranslationController::update(float timeStep) +void SineTranslationController::update(float timeStep) { // Calc sine movement m_time += timeStep; diff --git a/Engine/Lib/source/graphics/camera/Camera.cpp b/Engine/Lib/source/graphics/camera/Camera.cpp new file mode 100644 index 0000000..34bf20b --- /dev/null +++ b/Engine/Lib/source/graphics/camera/Camera.cpp @@ -0,0 +1,13 @@ +#include "kern/graphics/camera/Camera.h" + +void Camera::setView(const glm::mat4 &view) { m_view = view; } + +const glm::mat4 &Camera::getView() const { return m_view; } + +void Camera::setProjection(const glm::mat4 &proj) { m_projection = proj; } + +const glm::mat4 &Camera::getProjection() const { return m_projection; } + +void Camera::setPosition(const glm::vec3 &position) { m_position = position; } + +const glm::vec3 &Camera::getPosition() const { return m_position; } \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/camera/CFirstPersonCamera.cpp b/Engine/Lib/source/graphics/camera/FirstPersonCamera.cpp similarity index 59% rename from Graphics/Lib/source/graphics/camera/CFirstPersonCamera.cpp rename to Engine/Lib/source/graphics/camera/FirstPersonCamera.cpp index b43ff43..2d123e9 100644 --- a/Graphics/Lib/source/graphics/camera/CFirstPersonCamera.cpp +++ b/Engine/Lib/source/graphics/camera/FirstPersonCamera.cpp @@ -1,10 +1,10 @@ -#include "graphics/graphics/camera/CFirstPersonCamera.h" +#include "kern/graphics/camera/FirstPersonCamera.h" #include #include -CFirstPersonCamera::CFirstPersonCamera(const glm::vec3 &position, const glm::vec3 &target, +FirstPersonCamera::FirstPersonCamera(const glm::vec3 &position, const glm::vec3 &target, const glm::vec3 &up, float fieldOfView, float aspectRatio, float zNear, float zFar) { @@ -12,44 +12,44 @@ CFirstPersonCamera::CFirstPersonCamera(const glm::vec3 &position, const glm::vec setProjection(fieldOfView, aspectRatio, zNear, zFar); } -const glm::vec3 &CFirstPersonCamera::getPosition() const { return m_position; } +const glm::vec3 &FirstPersonCamera::getPosition() const { return m_position; } -void CFirstPersonCamera::setPosition(const glm::vec3 &position) +void FirstPersonCamera::setPosition(const glm::vec3 &position) { m_position = position; updateView(); } -void CFirstPersonCamera::move(const glm::vec3 &direction) +void FirstPersonCamera::move(const glm::vec3 &direction) { m_position += direction; updateView(); } -void CFirstPersonCamera::moveForward(float amount) +void FirstPersonCamera::moveForward(float amount) { m_position += glm::vec3(m_forward.x * amount, 0.0f, m_forward.y * amount); updateView(); } -void CFirstPersonCamera::moveRight(float amount) +void FirstPersonCamera::moveRight(float amount) { m_position += glm::vec3(m_forward.y * amount, 0.0f, -m_forward.x * amount); updateView(); } -void CFirstPersonCamera::moveUp(float amount) +void FirstPersonCamera::moveUp(float amount) { m_position += glm::vec3(0.0f, 1.0f, 0.0f) * amount; updateView(); } -void CFirstPersonCamera::rotate(const glm::vec3 &axis, float amount) +void FirstPersonCamera::rotate(const glm::vec3 &axis, float amount) { // TODO no support for arbitrary rotation ? } -void CFirstPersonCamera::pitch(float amount) +void FirstPersonCamera::pitch(float amount) { m_pitch += amount; m_pitch = fmin(m_pitch, glm::pi() / 4); @@ -58,12 +58,12 @@ void CFirstPersonCamera::pitch(float amount) updateView(); } -void CFirstPersonCamera::roll(float amount) +void FirstPersonCamera::roll(float amount) { // TODO no support for rolling ? } -void CFirstPersonCamera::yaw(float amount) +void FirstPersonCamera::yaw(float amount) { glm::vec3 forward = TransformUtils::rotate(glm::vec3(0.0f, 1.0f, 0.0f), amount, glm::vec3(m_forward.x, 0.0f, m_forward.y)); @@ -74,7 +74,7 @@ void CFirstPersonCamera::yaw(float amount) updateView(); } -void CFirstPersonCamera::lookAt(const glm::vec3 &target, const glm::vec3 & /* up */) +void FirstPersonCamera::lookAt(const glm::vec3 &target, const glm::vec3 & /* up */) { glm::vec3 forward = glm::normalize(target - m_position); m_pitch = -std::asin(forward.y / std::sqrt(2.f)); @@ -86,23 +86,23 @@ void CFirstPersonCamera::lookAt(const glm::vec3 &target, const glm::vec3 & /* up updateView(); } -const glm::mat4 &CFirstPersonCamera::getView() const { return m_view; } +const glm::mat4 &FirstPersonCamera::getView() const { return m_view; } -const glm::mat4 &CFirstPersonCamera::getProjection() const { return m_proj; } +const glm::mat4 &FirstPersonCamera::getProjection() const { return m_proj; } -void CFirstPersonCamera::lookAt(const glm::vec3 &eye, const glm::vec3 &target, const glm::vec3 &up) +void FirstPersonCamera::lookAt(const glm::vec3 &eye, const glm::vec3 &target, const glm::vec3 &up) { m_position = eye; lookAt(target, up); } -float CFirstPersonCamera::getFieldOfView() const { return m_fieldOfView; } +float FirstPersonCamera::getFieldOfView() const { return m_fieldOfView; } -float CFirstPersonCamera::getZNear() const { return m_zNear; } +float FirstPersonCamera::getZNear() const { return m_zNear; } -float CFirstPersonCamera::getZFar() const { return m_zFar; } +float FirstPersonCamera::getZFar() const { return m_zFar; } -void CFirstPersonCamera::setProjection(float fieldOfView, float aspectRatio, float zNear, +void FirstPersonCamera::setProjection(float fieldOfView, float aspectRatio, float zNear, float zFar) { m_fieldOfView = fieldOfView; @@ -112,7 +112,7 @@ void CFirstPersonCamera::setProjection(float fieldOfView, float aspectRatio, flo m_proj = glm::perspective(fieldOfView, aspectRatio, zNear, zFar); } -void CFirstPersonCamera::updateView() +void FirstPersonCamera::updateView() { glm::vec3 forward = glm::vec3(m_forward.x, 0.0f, m_forward.y); glm::vec3 axis = glm::vec3(m_forward.y, 0.0f, -m_forward.x); diff --git a/Engine/Lib/source/graphics/camera/IControllableCamera.cpp b/Engine/Lib/source/graphics/camera/IControllableCamera.cpp new file mode 100644 index 0000000..2b1bf46 --- /dev/null +++ b/Engine/Lib/source/graphics/camera/IControllableCamera.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/camera/IControllableCamera.h" + +IControllableCamera::~IControllableCamera() {} \ No newline at end of file diff --git a/Engine/Lib/source/graphics/camera/StaticCamera.cpp b/Engine/Lib/source/graphics/camera/StaticCamera.cpp new file mode 100644 index 0000000..7e4d01d --- /dev/null +++ b/Engine/Lib/source/graphics/camera/StaticCamera.cpp @@ -0,0 +1,14 @@ +#include "kern/graphics/camera/StaticCamera.h" + +StaticCamera::StaticCamera(const glm::mat4 &view, const glm::mat4 &projection, + const glm::vec3 &position) + : m_view(view), m_projection(projection), m_position(position) +{ + return; +} + +const glm::mat4 &StaticCamera::getView() const { return m_view; } + +const glm::mat4 &StaticCamera::getProjection() const { return m_projection; } + +const glm::vec3 &StaticCamera::getPosition() const { return m_position; } diff --git a/Graphics/Lib/source/collision/CAABBox.cpp b/Engine/Lib/source/graphics/collision/AABBox.cpp similarity index 77% rename from Graphics/Lib/source/collision/CAABBox.cpp rename to Engine/Lib/source/graphics/collision/AABBox.cpp index 16a2198..e99190e 100644 --- a/Graphics/Lib/source/collision/CAABBox.cpp +++ b/Engine/Lib/source/graphics/collision/AABBox.cpp @@ -1,25 +1,25 @@ -#include "graphics/collision/CAABBox.h" +#include "kern/graphics/collision/AABBox.h" #include #include #include // Returns mid point -const glm::vec3 &CAABBox::getMid() const { return m_middlePoint; } +const glm::vec3 &AABBox::getMid() const { return m_middlePoint; } // Returns halfwidth vector -const glm::vec3 &CAABBox::getHalfWidths() const { return m_halfWidth; } +const glm::vec3 &AABBox::getHalfWidths() const { return m_halfWidth; } // Sets middle -void CAABBox::setMid(const glm::vec3 &mid) { m_middlePoint = mid; } +void AABBox::setMid(const glm::vec3 &mid) { m_middlePoint = mid; } // Sets half width -void CAABBox::setHalfWidths(const glm::vec3 &halfWidth) { m_halfWidth = halfWidth; } +void AABBox::setHalfWidths(const glm::vec3 &halfWidth) { m_halfWidth = halfWidth; } // Returns as string -std::string CAABBox::toString() const +std::string AABBox::toString() const { - std::stringstream ss("CAABBox:"); + std::stringstream ss("AABBox:"); ss << " mid.x =" << m_middlePoint.x; ss << " mid.y =" << m_middlePoint.y; ss << " mid.z =" << m_middlePoint.z; @@ -29,7 +29,7 @@ std::string CAABBox::toString() const return ss.str(); } -CAABBox CAABBox::create(const std::vector &vertices) +AABBox AABBox::create(const std::vector &vertices) { assert(vertices.size() >= 3); assert(vertices.size() % 3 == 0); @@ -72,14 +72,14 @@ CAABBox CAABBox::create(const std::vector &vertices) } glm::vec3 mid((xmin + xmax) / 2.f, (ymin + ymax) / 2.f, (zmin + zmax) / 2.f); - CAABBox box; + AABBox box; box.setMid(mid); box.setHalfWidths( glm::vec3(xmax - box.getMid().x, ymax - box.getMid().y, zmax - box.getMid().z)); return box; } -bool collides(const CAABBox &box1, const CAABBox &box2) +bool collides(const AABBox &box1, const AABBox &box2) { glm::vec3 diff = box1.getMid() - box2.getMid(); glm::vec3 widths = box1.getHalfWidths() + box2.getHalfWidths(); diff --git a/Graphics/Lib/source/collision/CBoundingSphere.cpp b/Engine/Lib/source/graphics/collision/BoundingSphere.cpp similarity index 59% rename from Graphics/Lib/source/collision/CBoundingSphere.cpp rename to Engine/Lib/source/graphics/collision/BoundingSphere.cpp index c067b66..f0d1e8e 100644 --- a/Graphics/Lib/source/collision/CBoundingSphere.cpp +++ b/Engine/Lib/source/graphics/collision/BoundingSphere.cpp @@ -1,27 +1,27 @@ -#include "graphics/collision/CBoundingSphere.h" +#include "kern/graphics/collision/BoundingSphere.h" #include -CBoundingSphere::CBoundingSphere() +BoundingSphere::BoundingSphere() { // Empty } -CBoundingSphere::CBoundingSphere(const glm::vec3 &position, float radius) +BoundingSphere::BoundingSphere(const glm::vec3 &position, float radius) : m_position(position), m_radius(radius) { // Empty } -void CBoundingSphere::setPosition(const glm::vec3 &position) { m_position = position; } +void BoundingSphere::setPosition(const glm::vec3 &position) { m_position = position; } -void CBoundingSphere::setRadius(float radius) { m_radius = radius; } +void BoundingSphere::setRadius(float radius) { m_radius = radius; } -const glm::vec3 &CBoundingSphere::getPosition() const { return m_position; } +const glm::vec3 &BoundingSphere::getPosition() const { return m_position; } -float CBoundingSphere::getRadius() const { return m_radius; } +float BoundingSphere::getRadius() const { return m_radius; } -CBoundingSphere CBoundingSphere::create(const std::vector &vertices) +BoundingSphere BoundingSphere::create(const std::vector &vertices) { // Simple algorithm: Assume 0/0/0 is mid point of the mesh. // Radius is distance from mid point to furthest vertex @@ -39,7 +39,7 @@ CBoundingSphere CBoundingSphere::create(const std::vector &vertices) } } - CBoundingSphere sphere; + BoundingSphere sphere; // Default position is mid sphere.setPosition(glm::vec3(0.f)); // Set to calculated radius @@ -47,7 +47,7 @@ CBoundingSphere CBoundingSphere::create(const std::vector &vertices) return sphere; } -bool collides(const CBoundingSphere &sphere1, const CBoundingSphere &sphere2) +bool collides(const BoundingSphere &sphere1, const BoundingSphere &sphere2) { float distance = glm::distance(sphere1.getPosition(), sphere2.getPosition()); return distance < (sphere1.getRadius() + sphere2.getRadius()); diff --git a/Engine/Lib/source/graphics/collision/Collidable.cpp b/Engine/Lib/source/graphics/collision/Collidable.cpp new file mode 100644 index 0000000..67d9acc --- /dev/null +++ b/Engine/Lib/source/graphics/collision/Collidable.cpp @@ -0,0 +1,49 @@ +#include "kern/graphics/collision/Collidable.h" + +Collidable::Collidable(unsigned int group, const AABBox &box) + : m_boxTransformed(box), m_box(box), m_groupId(group) +{ +} + +float Collidable::getDamage() const { return m_damageDealt; } + +// Returns accumuated damage and resets damage counter +float Collidable::getDamageReceived() +{ + float temp = m_damageReceived; + m_damageReceived = 0.f; + return temp; +} + +// Returns group id +unsigned int Collidable::getGroupId() const { return m_groupId; } + +// Add damage to the internal counter +void Collidable::receiveDamage(float damage) { m_damageReceived += damage; } + +// Sets the damage dealt by this entity +void Collidable::setDamage(float damage) { m_damageDealt = damage; } + +const AABBox &Collidable::getAABBox() const { return m_boxTransformed; } + +void Collidable::setScale(const glm::vec3 &scale) +{ + m_boxTransformed.setHalfWidths(scale); + return; +} + +void Collidable::setTranslation(const glm::vec3 &translate) +{ + m_boxTransformed.setMid(translate); + return; +} + +// Sets collidable state +void Collidable::setCollidable(bool state) { m_collidable = state; } + +// Returns collidable state +bool Collidable::isCollidable() const { return m_collidable; } + +bool Collidable::deleteRequested() const { return m_deleteMe; } + +void Collidable::markDeleted() { m_deleteMe = true; } diff --git a/Graphics/Lib/source/collision/CCollisionSystem.cpp b/Engine/Lib/source/graphics/collision/CollisionSystem.cpp similarity index 71% rename from Graphics/Lib/source/collision/CCollisionSystem.cpp rename to Engine/Lib/source/graphics/collision/CollisionSystem.cpp index 25a9dbf..5957e53 100644 --- a/Graphics/Lib/source/collision/CCollisionSystem.cpp +++ b/Engine/Lib/source/graphics/collision/CollisionSystem.cpp @@ -1,23 +1,23 @@ -#include "graphics/collision/CCollisionSystem.h" +#include "kern/graphics/collision/CollisionSystem.h" #include -#include +#include -#include "graphics/collision/CCollidable.h" +#include "kern/graphics/collision/Collidable.h" -unsigned int CCollisionSystem::getNewGroupId() +unsigned int CollisionSystem::getNewGroupId() { // Add new collision group - m_entities.push_back(std::list()); + m_entities.push_back(std::list()); // Return the group id - return m_entities.size() - 1; + return (unsigned int)m_entities.size() - 1; } // Cleanup -CCollisionSystem::~CCollisionSystem() +CollisionSystem::~CollisionSystem() { - for (unsigned int i = 0; i < m_entities.size(); ++i) + for (size_t i = 0; i < m_entities.size(); ++i) { for (auto iter = m_entities[i].begin(); iter != m_entities[i].end(); ++iter) { @@ -26,28 +26,28 @@ CCollisionSystem::~CCollisionSystem() } } -CCollidable *CCollisionSystem::add(const CAABBox &box, unsigned int groupId) +Collidable *CollisionSystem::add(const AABBox &box, unsigned int groupId) { if (groupId >= m_entities.size()) { - LOG_ERROR("Group id %i does not exist", groupId); - throw std::runtime_error("CCollisionSystem.add: Invalid goup id"); + loge("Group id {} does not exist", groupId); + throw std::runtime_error("CollisionSystem.add: Invalid goup id"); } // Create new entity and add to the collision group - CCollidable *entity = new CCollidable(groupId, box); + Collidable *entity = new Collidable(groupId, box); m_entities[groupId].push_back(entity); return entity; } // Removes collidable entity -void CCollisionSystem::remove(CCollidable *entity) +void CollisionSystem::remove(Collidable *entity) { m_entities[entity->getGroupId()].remove(entity); delete entity; } // Test all entities for collision -void CCollisionSystem::update() +void CollisionSystem::update() { for (unsigned int i = 0; i < m_entities.size(); ++i) { @@ -57,7 +57,7 @@ void CCollisionSystem::update() // Delete if requested if ((*iter)->deleteRequested()) { - CCollidable *temp = (*iter); + Collidable *temp = (*iter); iter = m_entities[i].erase(iter); delete temp; } @@ -74,7 +74,7 @@ void CCollisionSystem::update() } // Tests collidable entity against all entities not in the group -void CCollisionSystem::testCollision(CCollidable *entity, unsigned int group) +void CollisionSystem::testCollision(Collidable *entity, unsigned int group) { // Everything gets tested twice, make this faster for (unsigned int i = 0; i < m_entities.size(); ++i) @@ -87,7 +87,7 @@ void CCollisionSystem::testCollision(CCollidable *entity, unsigned int group) // Delete if requested if ((*iter)->deleteRequested()) { - CCollidable *temp = (*iter); + Collidable *temp = (*iter); iter = m_entities[i].erase(iter); delete temp; } diff --git a/Graphics/Lib/source/collision/CFrustum.cpp b/Engine/Lib/source/graphics/collision/Frustum.cpp similarity index 89% rename from Graphics/Lib/source/collision/CFrustum.cpp rename to Engine/Lib/source/graphics/collision/Frustum.cpp index 62082ce..ddb45ed 100644 --- a/Graphics/Lib/source/collision/CFrustum.cpp +++ b/Engine/Lib/source/graphics/collision/Frustum.cpp @@ -1,18 +1,14 @@ -#include "graphics/collision/CFrustum.h" +#include "kern/graphics/collision/Frustum.h" #include #include -#include +#include "kern/foundation/Transformer.h" const float gradToRad = glm::pi() / 180.0f; -CFrustum::CFrustum() {} - -CFrustum::~CFrustum() {} - -void CFrustum::setFromCameraParameters(float angle, float ratio, float nearD, float farD, +void Frustum::setFromCameraParameters(float angle, float ratio, float nearD, float farD, glm::vec3 &pos, glm::vec3 &look, glm::vec3 &u) { // Compute width and height of the near and far plane sections @@ -63,9 +59,9 @@ void CFrustum::setFromCameraParameters(float angle, float ratio, float nearD, fl m_planes[Far].set3Points(ftr, ftl, fbl); } -void CFrustum::setFromViewProjectionClipSpaceApproach(const glm::mat4 &view, const glm::mat4 &proj) +void Frustum::setFromViewProjectionClipSpaceApproach(const glm::mat4 &view, const glm::mat4 &proj) { - CTransformer transformer; + Transformer transformer; transformer.setViewMatrix(view); transformer.setProjectionMatrix(proj); glm::mat4 matrix = transformer.getViewProjectionMatrix(); @@ -84,7 +80,7 @@ void CFrustum::setFromViewProjectionClipSpaceApproach(const glm::mat4 &view, con m_planes[Far].setCoefficients(glm::normalize(rowW - rowZ)); } -void CFrustum::setFromInverseViewProjection(const glm::mat4 &invViewProj) +void Frustum::setFromInverseViewProjection(const glm::mat4 &invViewProj) { // Setup frustum from invViewProj matrix (transform from projection space // into world space). @@ -133,16 +129,16 @@ void CFrustum::setFromInverseViewProjection(const glm::mat4 &invViewProj) glm::vec3(points[bottomRightNear])); } -void CFrustum::setFromViewProjection(const glm::mat4 &view, const glm::mat4 &proj) +void Frustum::setFromViewProjection(const glm::mat4 &view, const glm::mat4 &proj) { // Handles transformation calculations - CTransformer transformer; + Transformer transformer; transformer.setViewMatrix(view); transformer.setProjectionMatrix(proj); setFromInverseViewProjection(transformer.getInverseViewProjectionMatrix()); } -bool CFrustum::isInside(glm::vec3 &p) const +bool Frustum::isInside(glm::vec3 &p) const { for (int i = 0; i < 6; i++) { @@ -154,7 +150,7 @@ bool CFrustum::isInside(glm::vec3 &p) const return true; } -bool CFrustum::isInsideOrIntersects(const CBoundingSphere &sphere) const +bool Frustum::isInsideOrIntersects(const BoundingSphere &sphere) const { auto position = sphere.getPosition(); auto radius = sphere.getRadius(); diff --git a/Graphics/Lib/source/collision/CPlane.cpp b/Engine/Lib/source/graphics/collision/Plane.cpp similarity index 55% rename from Graphics/Lib/source/collision/CPlane.cpp rename to Engine/Lib/source/graphics/collision/Plane.cpp index c7c5123..9aad469 100644 --- a/Graphics/Lib/source/collision/CPlane.cpp +++ b/Engine/Lib/source/graphics/collision/Plane.cpp @@ -1,29 +1,29 @@ -#include "graphics/collision/CPlane.h" +#include "kern/graphics/collision/Plane.h" -CPlane::CPlane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) +Plane::Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { set3Points(v1, v2, v3); } -CPlane::CPlane() {} +Plane::Plane() {} -CPlane::~CPlane() {} +Plane::~Plane() {} -void CPlane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) +void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { m_normal = glm::normalize(glm::cross(v1 - v2, v3 - v2)); m_d = -(glm::dot(m_normal, v2)); } -void CPlane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) +void Plane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) { m_normal = glm::normalize(normal); m_d = -(glm::dot(m_normal, point)); } -void CPlane::setCoefficients(const glm::vec4 &v) { setCoefficients(v.x, v.y, v.z, v.w); } +void Plane::setCoefficients(const glm::vec4 &v) { setCoefficients(v.x, v.y, v.z, v.w); } -void CPlane::setCoefficients(float a, float b, float c, float d) +void Plane::setCoefficients(float a, float b, float c, float d) { // Based on // http://www.lighthouse3d.com/tutorials/view-frustum-culling/clip-space-approach-implementation-details/ @@ -38,4 +38,4 @@ void CPlane::setCoefficients(float a, float b, float c, float d) m_d = d / length; } -float CPlane::distance(const glm::vec3 &p) const { return m_d + glm::dot(m_normal, p); } \ No newline at end of file +float Plane::distance(const glm::vec3 &p) const { return m_d + glm::dot(m_normal, p); } \ No newline at end of file diff --git a/Graphics/Lib/source/input/provider/CGlfwInputProvider.cpp b/Engine/Lib/source/graphics/input/GlfwInputProvider.cpp similarity index 63% rename from Graphics/Lib/source/input/provider/CGlfwInputProvider.cpp rename to Engine/Lib/source/graphics/input/GlfwInputProvider.cpp index 677f449..5b9fdb9 100644 --- a/Graphics/Lib/source/input/provider/CGlfwInputProvider.cpp +++ b/Engine/Lib/source/graphics/input/GlfwInputProvider.cpp @@ -1,17 +1,15 @@ -#include "graphics/input/provider/CGlfwInputProvider.h" +#include "kern/graphics/input/GlfwInputProvider.h" #include - +#define GLFW_INCLUDE_NONE #include +#include -#include - -#include "graphics/input/IInputListener.h" +#include "kern/graphics/input/IInputListener.h" -std::unordered_map CGlfwInputProvider::s_instances; +std::unordered_map GlfwInputProvider::s_instances; -void CGlfwInputProvider::glfwKeyCallback(GLFWwindow *window, int key, int scancode, int action, - int mods) +void GlfwInputProvider::glfwKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { auto it = s_instances.find(window); if (it != s_instances.end()) @@ -30,7 +28,7 @@ void CGlfwInputProvider::glfwKeyCallback(GLFWwindow *window, int key, int scanco eventType = EKeyEventType::KEY_RELEASED; break; default: - LOG_WARNING("Ignored unknown action '%ui' for glfwKeyCallback.", action); + logw("Ignored unknown action '{}' for glfwKeyCallback.", action); return; } @@ -41,7 +39,7 @@ void CGlfwInputProvider::glfwKeyCallback(GLFWwindow *window, int key, int scanco } } -void CGlfwInputProvider::glfwCursorPositionCallback(GLFWwindow *window, double xpos, double ypos) +void GlfwInputProvider::glfwCursorPositionCallback(GLFWwindow *window, double xpos, double ypos) { auto it = s_instances.find(window); if (it != s_instances.end()) @@ -65,8 +63,7 @@ void CGlfwInputProvider::glfwCursorPositionCallback(GLFWwindow *window, double x // } //} -void CGlfwInputProvider::glfwMouseButtonCallback(GLFWwindow *window, int button, int action, - int mods) +void GlfwInputProvider::glfwMouseButtonCallback(GLFWwindow *window, int button, int action, int mods) { auto it = s_instances.find(window); if (it != s_instances.end()) @@ -82,7 +79,7 @@ void CGlfwInputProvider::glfwMouseButtonCallback(GLFWwindow *window, int button, eventType = EMouseButtonEventType::MOUSE_BUTTON_RELEASED; break; default: - LOG_WARNING("Ignored unknown action '%ui' for glfwMouseButtonCallback.", action); + logw("Ignored unknown action '{}' for glfwMouseButtonCallback.", action); return; } @@ -106,39 +103,33 @@ void CGlfwInputProvider::glfwMouseButtonCallback(GLFWwindow *window, int button, //} // === -// class CGlfwInputProvider +// class GlfwInputProvider // === -CGlfwInputProvider::CGlfwInputProvider(GLFWwindow *window) : m_window(window) +GlfwInputProvider::GlfwInputProvider(GLFWwindow *window) : m_window(window) { assert(m_window != nullptr); assert(s_instances.find(m_window) == s_instances.end()); // Set callbacks - glfwSetKeyCallback(m_window, CGlfwInputProvider::glfwKeyCallback); - glfwSetCursorPosCallback(m_window, CGlfwInputProvider::glfwCursorPositionCallback); - glfwSetMouseButtonCallback(m_window, CGlfwInputProvider::glfwMouseButtonCallback); + glfwSetKeyCallback(m_window, GlfwInputProvider::glfwKeyCallback); + glfwSetCursorPosCallback(m_window, GlfwInputProvider::glfwCursorPositionCallback); + glfwSetMouseButtonCallback(m_window, GlfwInputProvider::glfwMouseButtonCallback); // Create mapping for callbacks s_instances[m_window] = this; } -CGlfwInputProvider::~CGlfwInputProvider() +GlfwInputProvider::~GlfwInputProvider() { // Remove mapping s_instances.erase(m_window); } -void CGlfwInputProvider::addInputListener(IInputListener *listener) -{ - m_listeners.push_back(listener); -} +void GlfwInputProvider::addInputListener(IInputListener *listener) { m_listeners.push_back(listener); } -void CGlfwInputProvider::removeInputListener(IInputListener *listener) -{ - m_listeners.remove(listener); -} +void GlfwInputProvider::removeInputListener(IInputListener *listener) { m_listeners.remove(listener); } -bool CGlfwInputProvider::isKeyPressed(int keyCode) +bool GlfwInputProvider::isKeyPressed(int keyCode) { if (m_window != nullptr) { diff --git a/Engine/Lib/source/graphics/input/IInputListener.cpp b/Engine/Lib/source/graphics/input/IInputListener.cpp new file mode 100644 index 0000000..900e381 --- /dev/null +++ b/Engine/Lib/source/graphics/input/IInputListener.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/input/IInputListener.h" + +IInputListener::~IInputListener() { return; } diff --git a/Engine/Lib/source/graphics/input/IInputProvider.cpp b/Engine/Lib/source/graphics/input/IInputProvider.cpp new file mode 100644 index 0000000..b449ad1 --- /dev/null +++ b/Engine/Lib/source/graphics/input/IInputProvider.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/input/IInputProvider.h" + +IInputProvider::~IInputProvider() { return; } diff --git a/Engine/Lib/source/graphics/io/SceneLoader.cpp b/Engine/Lib/source/graphics/io/SceneLoader.cpp new file mode 100644 index 0000000..a781d5c --- /dev/null +++ b/Engine/Lib/source/graphics/io/SceneLoader.cpp @@ -0,0 +1,393 @@ +#include "kern/graphics/io/SceneLoader.h" + +#include + +#include +#include +#include + +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/animation/AnimationWorld.h" +#include "kern/graphics/animation/MovementController.h" +#include "kern/graphics/animation/RotationController.h" +#include "kern/graphics/animation/SineTranslationController.h" +#include "kern/resource/IResourceManager.h" + +SceneLoader::SceneLoader(IResourceManager &resourceManager) : m_resourceManager(resourceManager) { return; } + +bool SceneLoader::load(const std::string &file, IScene &scene, AnimationWorld &animationWorld) +{ + nlohmann::json root; + + if (!::load(file, root)) + { + loge("Failed to load scene."); + return false; + } + + // Load scene objects + if (!loadSceneObjects(root["scene_objects"], scene, animationWorld)) + { + loge("Error while loading scene objects from scene file {}.", file.c_str()); + return false; + } + + // Load point lights + if (!loadPointLights(root["point_lights"], scene, animationWorld)) + { + loge("Error while loading point lights from scene file {}.", file.c_str()); + return false; + } + + // Load directional lights + if (!loadDirectionalLights(root["directional_lights"], scene, animationWorld)) + { + loge("Error while loading ambient light from scene file &s.", file.c_str()); + return false; + } + + // Load ambient light + if (!loadAmbientLight(root["ambient_light"], scene)) + { + loge("Error while loading ambient light from scene file &s.", file.c_str()); + return false; + } + + return true; +} + +bool SceneLoader::loadSceneObjects(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + // Node empty? + if (node.empty()) + { + logi("Missing or empty 'scene_objects' node. No scene objects are loaded."); + return true; + } + + // Node is array type + if (!node.is_array()) + { + loge("The node 'scene_objects' must be array type."); + return false; + } + + // Load scene objects + for (unsigned int i = 0; i < node.size(); ++i) + { + if (!loadSceneObject(node[i], scene, animationWorld)) + { + return false; + } + } + return true; +} + +bool SceneLoader::loadSceneObject(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + std::string mesh; + std::string material; + glm::vec3 position; + glm::vec3 rotation; + glm::vec3 scale; + + if (!::load(node, "mesh", mesh)) + { + return false; + } + + if (!::load(node, "material", material)) + { + return false; + } + + if (!::load(node, "position", position)) + { + return false; + } + + if (!::load(node, "rotation", rotation)) + { + return false; + } + + if (!::load(node, "scale", scale)) + { + return false; + } + + // Load mesh file + ResourceId meshId = m_resourceManager.loadMesh(mesh); + if (meshId == -1) + { + loge("Failed to load mesh file {}.", mesh.c_str()); + return false; + } + + // Load material file + ResourceId materialId = m_resourceManager.loadMaterial(material); + if (materialId == -1) + { + loge("Failed to load material file {}.", material.c_str()); + return false; + } + + // Create object in scene + SceneObjectId objectId = scene.createObject(meshId, materialId, position, glm::quat(rotation), scale); + + // Load optional animation controllers + if (node.find("animations") != node.end()) + { + if (!loadAnimationControllers(node.at("animations"), scene, animationWorld, objectId, + AnimationObjectType::Model)) + { + loge("Failed to scene object load animation controller."); + return false; + } + } + + return true; +} + +bool SceneLoader::loadPointLights(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + // Node empty? + if (node.empty()) + { + logi("Missing or empty 'point_lights' node. No point lights are loaded."); + return true; + } + + // Node is array type + if (!node.is_array()) + { + loge("The node 'point_lights' must be array type."); + return false; + } + + // Load scene point lights + for (unsigned int i = 0; i < node.size(); ++i) + { + if (!loadPointLight(node[i], scene, animationWorld)) + { + return false; + } + } + return true; +} + +bool SceneLoader::loadPointLight(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + glm::vec3 position; + glm::vec3 color; + float radius; + float intensity; + bool castsShadow; + + if (!::load(node, "position", position)) + { + return false; + } + + if (!::load(node, "color", color)) + { + return false; + } + + if (!::load(node, "radius", radius)) + { + return false; + } + + if (!::load(node, "intensity", intensity)) + { + return false; + } + + if (!::load(node, "casts_shadow", castsShadow)) + { + return false; + } + + // Create object in scene + SceneObjectId objectId = scene.createPointLight(position, radius, color, intensity, castsShadow); + + // Load optional animation controllers + if (node.find("animations") != node.end()) + { + if (!loadAnimationControllers(node["animations"], scene, animationWorld, objectId, + AnimationObjectType::PointLight)) + { + loge("Failed to load point light animation controller."); + return false; + } + } + return true; +} + +bool SceneLoader::loadDirectionalLights(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + // Node empty? + if (node.empty()) + { + logi( + "Missing or empty 'directional_lights' node. No directional " + "lights are loaded."); + return true; + } + + // Node is array type + if (!node.is_array()) + { + loge("The node 'directional_lights' must be array type."); + return false; + } + + // Load scene directional lights + for (unsigned int i = 0; i < node.size(); ++i) + { + if (!loadDirectionalLight(node[i], scene, animationWorld)) + { + return false; + } + } + return true; +} + +bool SceneLoader::loadDirectionalLight(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld) +{ + glm::vec3 direction; + glm::vec3 color; + float intensity; + bool castsShadow; + + if (!::load(node, "direction", direction)) + { + return false; + } + + if (!::load(node, "color", color)) + { + return false; + } + + if (!::load(node, "intensity", intensity)) + { + return false; + } + + if (!::load(node, "casts_shadow", castsShadow)) + { + return false; + } + + // Create object in scene + scene.createDirectionalLight(direction, color, intensity, castsShadow); + return true; +} + +bool SceneLoader::loadAmbientLight(const nlohmann::json &node, IScene &scene) +{ + if (node.empty()) + { + logi("Missing or empty 'ambient_light' node. No ambient light is loaded."); + return true; + } + + glm::vec3 color; + float intensity; + + if (!::load(node, "color", color)) + { + return false; + } + + if (!::load(node, "intensity", intensity)) + { + return false; + } + + scene.setAmbientLight(color, intensity); + return true; +} + +bool SceneLoader::loadAnimationControllers(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld, + SceneObjectId id, AnimationObjectType type) +{ + if (node.empty()) + { + // logi("Missing or empty 'animations' node. No animation controllers + // where loaded."); + return true; + } + + // Node is array type + if (!node.is_array()) + { + loge("The node 'animations' must be array type."); + return false; + } + + // Load animation controllers for object + for (unsigned int i = 0; i < node.size(); ++i) + { + if (!loadAnimationController(node[i], scene, animationWorld, id, type)) + { + return false; + } + } + return true; +} + +bool SceneLoader::loadAnimationController(const nlohmann::json &node, IScene &scene, AnimationWorld &animationWorld, + SceneObjectId id, AnimationObjectType type) +{ + std::string controllerType; + if (!::load(node, "type", controllerType)) + { + return false; + } + // + if (controllerType == "rotation") + { + glm::vec3 rotation; + if (!::load(node, "rotation", rotation)) + { + return false; + } + animationWorld.addAnimationController(std::make_shared(id, type, scene, rotation)); + } + else if (controllerType == "movement") + { + glm::vec3 direction; + if (!::load(node, "direction", direction)) + { + return false; + } + animationWorld.addAnimationController(std::make_shared(id, type, scene, direction)); + } + else if (controllerType == "sine_translation") + { + glm::vec3 translation; + float timeScale; + if (!::load(node, "translation", translation)) + { + return false; + } + if (!::load(node, "timescale", timeScale)) + { + return false; + } + animationWorld.addAnimationController( + std::make_shared(id, type, scene, translation, timeScale)); + } + else + { + // Unknown controller type + return false; + } + + return true; +} \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/proxy/CSceneObjectProxy.cpp b/Engine/Lib/source/graphics/proxy/SceneObjectProxy.cpp similarity index 53% rename from Graphics/Lib/source/graphics/proxy/CSceneObjectProxy.cpp rename to Engine/Lib/source/graphics/proxy/SceneObjectProxy.cpp index 315b449..edcc1c9 100644 --- a/Graphics/Lib/source/graphics/proxy/CSceneObjectProxy.cpp +++ b/Engine/Lib/source/graphics/proxy/SceneObjectProxy.cpp @@ -1,17 +1,17 @@ -#include "graphics/graphics/proxy/CSceneObjectProxy.h" +#include "kern/graphics/proxy/SceneObjectProxy.h" const glm::vec3 nullVec(0.f); -CSceneObjectProxy::CSceneObjectProxy() +SceneObjectProxy::SceneObjectProxy() { // Empty } -CSceneObjectProxy::CSceneObjectProxy(IScene *scene, SceneObjectId id) { init(scene, id); } +SceneObjectProxy::SceneObjectProxy(IScene *scene, SceneObjectId id) { init(scene, id); } -bool CSceneObjectProxy::init(IScene *scene, SceneObjectId id) +bool SceneObjectProxy::init(IScene *scene, SceneObjectId id) { - if (scene != nullptr && id != invalidObject) + if (scene != nullptr && id != InvalidObject) { m_scene = scene; m_objectId = id; @@ -21,60 +21,60 @@ bool CSceneObjectProxy::init(IScene *scene, SceneObjectId id) return false; } -const glm::vec3 &CSceneObjectProxy::getPosition() const +const glm::vec3 &SceneObjectProxy::getPosition() const { getUpdate(); return m_position; } -const glm::quat &CSceneObjectProxy::getRotation() const +const glm::quat &SceneObjectProxy::getRotation() const { getUpdate(); return m_rotation; } -const glm::vec3 &CSceneObjectProxy::getScale() const +const glm::vec3 &SceneObjectProxy::getScale() const { getUpdate(); return m_scale; } -void CSceneObjectProxy::setPosition(const glm::vec3 &position) +void SceneObjectProxy::setPosition(const glm::vec3 &position) { getUpdate(); m_position = position; sendUpdate(); } -void CSceneObjectProxy::setRotation(const glm::vec3 &rotation) +void SceneObjectProxy::setRotation(const glm::vec3 &rotation) { getUpdate(); m_rotation = glm::quat(rotation); sendUpdate(); } -void CSceneObjectProxy::setRotation(const glm::quat &rotation) +void SceneObjectProxy::setRotation(const glm::quat &rotation) { getUpdate(); m_rotation = rotation; sendUpdate(); } -void CSceneObjectProxy::setScale(const glm::vec3 &scale) +void SceneObjectProxy::setScale(const glm::vec3 &scale) { getUpdate(); m_scale = scale; sendUpdate(); } -void CSceneObjectProxy::setVisibility(bool visible) +void SceneObjectProxy::setVisibility(bool visible) { getUpdate(); m_visible = visible; sendUpdate(); } -void CSceneObjectProxy::getUpdate() const +void SceneObjectProxy::getUpdate() const { if (!m_init) { @@ -83,7 +83,7 @@ void CSceneObjectProxy::getUpdate() const m_scene->getObject(m_objectId, m_mesh, m_material, m_position, m_rotation, m_scale, m_visible); } -void CSceneObjectProxy::sendUpdate() +void SceneObjectProxy::sendUpdate() { if (!m_init) { diff --git a/Graphics/Lib/source/graphics/renderer/CDeferredRenderer.cpp b/Engine/Lib/source/graphics/renderer/DeferredRenderer.cpp similarity index 65% rename from Graphics/Lib/source/graphics/renderer/CDeferredRenderer.cpp rename to Engine/Lib/source/graphics/renderer/DeferredRenderer.cpp index ae14187..e4bdab3 100644 --- a/Graphics/Lib/source/graphics/renderer/CDeferredRenderer.cpp +++ b/Engine/Lib/source/graphics/renderer/DeferredRenderer.cpp @@ -1,52 +1,38 @@ -#include "graphics/graphics/renderer/CDeferredRenderer.h" +#include "kern/graphics/renderer/DeferredRenderer.h" -#include -#include +#include +#include #include +#include -#include - -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IScene.h" -#include "graphics/graphics/IWindow.h" -#include "graphics/graphics/scene/CSceneQuery.h" - -#include "graphics/graphics/camera/CStaticCamera.h" -#include "graphics/resource/IResourceManager.h" - -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/graphics/renderer/CRenderBuffer.h" -#include "graphics/graphics/resource/CMaterial.h" -#include "graphics/graphics/resource/CMesh.h" -#include "graphics/graphics/resource/CShaderProgram.h" -#include "graphics/graphics/resource/CTexture.h" - -#include "graphics/graphics/renderer/Draw.h" -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" - -#include "graphics/graphics/renderer/debug/RendererDebug.h" - -CDeferredRenderer::CDeferredRenderer() { return; } - -CDeferredRenderer::~CDeferredRenderer() { return; } - -bool CDeferredRenderer::init(IResourceManager &manager) +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/Window.h" +#include "kern/graphics/camera/StaticCamera.h" +#include "kern/graphics/renderer/Draw.h" +#include "kern/graphics/renderer/RenderBuffer.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/graphics/resource/Material.h" +#include "kern/graphics/resource/Mesh.h" +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/Texture.h" +#include "kern/graphics/scene/SceneQuery.h" +#include "kern/resource/IResourceManager.h" + +DeferredRenderer::DeferredRenderer() { return; } + +DeferredRenderer::~DeferredRenderer() { return; } + +bool DeferredRenderer::init(IResourceManager &manager) { - LOG_INFO("Initializing deferred renderer."); - - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } + logi("Initializing deferred renderer."); // Init geometry pass resources if (!initGeometryPass(manager)) { - LOG_ERROR("Failed to intialize geometry pass."); + loge("Failed to intialize geometry pass."); return false; } @@ -54,34 +40,34 @@ bool CDeferredRenderer::init(IResourceManager &manager) // TODO Should be done in directional light pass if (!initShadowMapPass(manager)) { - LOG_ERROR("Failed to intialize shadow map pass."); + loge("Failed to intialize shadow map pass."); return false; } if (!initShadowCubePass(manager)) { - LOG_ERROR("Failed to intialize shadow map pass."); + loge("Failed to intialize shadow map pass."); return false; } // Init light pass resources if (!initPointLightPass(manager)) { - LOG_ERROR("Failed to initialize point light pass."); + loge("Failed to initialize point light pass."); return false; } // Init directional light pass if (!initDirectionalLightPass(manager)) { - LOG_ERROR("Failed to initialize directional light pass."); + loge("Failed to initialize directional light pass."); return false; } // Init illumination pass if (!initIlluminationPass(manager)) { - LOG_ERROR("Failed to initialize illumination pass."); + loge("Failed to initialize illumination pass."); return false; } @@ -89,40 +75,40 @@ bool CDeferredRenderer::init(IResourceManager &manager) // TODO Dedicated post processor? if (!initPostProcessPass(manager)) { - LOG_ERROR("Failed to initialize post processing pass."); + loge("Failed to initialize post processing pass."); return false; } // Display pass if (!initDisplayPass(manager)) { - LOG_ERROR("Failed to initialize display pass."); + loge("Failed to initialize display pass."); return false; } if (!m_screenQuadPass.init(manager)) { - LOG_ERROR("Failed to initialize screen quad pass."); + loge("Failed to initialize screen quad pass."); return false; } if (!initVisualizeDepthPass(manager)) { - LOG_ERROR("Failed to initialize depth visualization pass."); + loge("Failed to initialize depth visualization pass."); return false; } return true; } -void CDeferredRenderer::draw(const IScene &scene, const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager) +void DeferredRenderer::draw(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) { // Draw init window.setActive(); // Query visible scene objects and lights - CSceneQuery query; + SceneQuery query; scene.getVisibleObjects(camera, query); // Geometry pass fills gbuffer @@ -137,7 +123,7 @@ void CDeferredRenderer::draw(const IScene &scene, const ICamera &camera, const I // Post processing pass postProcessPass(camera, window, manager, m_illuminationPassTexture); - CFrameBuffer::setDefaultActive(); + FrameBuffer::setDefaultActive(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // Select rendering mode if (camera.getFeatureInfo().renderMode == RenderMode::Color) @@ -161,32 +147,22 @@ void CDeferredRenderer::draw(const IScene &scene, const ICamera &camera, const I // Final display pass displayPass(window, manager, m_postProcessPassOutputTexture); } - -#ifndef NDEBUG - // Post draw error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } -#endif } -CDeferredRenderer *CDeferredRenderer::create(IResourceManager &manager) +DeferredRenderer *DeferredRenderer::create(IResourceManager &manager) { - CDeferredRenderer *renderer = new CDeferredRenderer; + DeferredRenderer *renderer = new DeferredRenderer; if (!renderer->init(manager)) { delete renderer; renderer = nullptr; - LOG_ERROR("Failed to create deferred renderer, initialization failed."); + loge("Failed to create deferred renderer, initialization failed."); } return renderer; } -void CDeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, - const IWindow &window, const IGraphicsResourceManager &manager, - ISceneQuery &query) +void DeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query) { // Set framebuffer m_geometryBuffer.setActive(GL_FRAMEBUFFER); @@ -203,10 +179,10 @@ void CDeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, glClear(GL_DEPTH_BUFFER_BIT); // Geometry pass, uses gbuffer fbo - CShaderProgram *geometryPassShader = manager.getShaderProgram(m_geometryPassShaderId); + ShaderProgram *geometryPassShader = manager.getShaderProgram(m_geometryPassShaderId); if (geometryPassShader == nullptr) { - LOG_ERROR("Failed to retrieve geometry pass shader."); + loge("Failed to retrieve geometry pass shader."); return; } @@ -231,8 +207,7 @@ void CDeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, // Send view/projection to default shader geometryPassShader->setUniform(viewMatrixUniformName, m_transformer.getViewMatrix()); - geometryPassShader->setUniform(projectionMatrixUniformName, - m_transformer.getProjectionMatrix()); + geometryPassShader->setUniform(projectionMatrixUniformName, m_transformer.getProjectionMatrix()); // Traverse visible objects while (query.hasNextObject()) @@ -252,13 +227,13 @@ void CDeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, if (!scene.getObject(id, meshId, materialId, position, rotation, scale, visible)) { // Invalid id - LOG_ERROR("Invalid scene object id %l.", id); + loge("Invalid scene object id {}.", id); } else { // Resolve ids - CMesh *mesh = manager.getMesh(meshId); - CMaterial *material = manager.getMaterial(materialId); + Mesh *mesh = manager.getMesh(meshId); + Material *material = manager.getMaterial(materialId); // Set transformations m_transformer.setPosition(position); @@ -271,24 +246,14 @@ void CDeferredRenderer::geometryPass(const IScene &scene, const ICamera &camera, } } -#ifndef NDEBUG - // Post draw error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } -#endif - // Disable geometry buffer m_geometryBuffer.setInactive(GL_FRAMEBUFFER); } -void CDeferredRenderer::shadowMapPass(const IScene &scene, const ICamera &camera, - const IWindow &window, - const IGraphicsResourceManager &manager) +void DeferredRenderer::shadowMapPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) { - CShaderProgram *shadowMapPassShader = manager.getShaderProgram(m_shadowMapPassShaderId); + ShaderProgram *shadowMapPassShader = manager.getShaderProgram(m_shadowMapPassShaderId); // Set framebuffer m_shadowMapBuffer.setActive(GL_FRAMEBUFFER); @@ -313,14 +278,14 @@ void CDeferredRenderer::shadowMapPass(const IScene &scene, const ICamera &camera m_shadowMapBuffer.resize(4096, 4096); // Stores active transformations - CTransformer transformer; + Transformer transformer; // Set view and projection matrices transformer.setViewMatrix(camera.getView()); transformer.setProjectionMatrix(camera.getProjection()); // Query visible scene objects - CSceneQuery query; + SceneQuery query; scene.getVisibleObjects(camera, query); // Send view/projection to default shader @@ -345,13 +310,13 @@ void CDeferredRenderer::shadowMapPass(const IScene &scene, const ICamera &camera if (!scene.getObject(id, meshId, materialId, position, rotation, scale, visible)) { // Invalid id - LOG_ERROR("Invalid scene object id %l.", id); + loge("Invalid scene object id {}.", id); } else { // Resolve ids - CMesh *mesh = manager.getMesh(meshId); - CMaterial *material = manager.getMaterial(materialId); + Mesh *mesh = manager.getMesh(meshId); + Material *material = manager.getMaterial(materialId); // Set transformations transformer.setPosition(position); @@ -364,15 +329,6 @@ void CDeferredRenderer::shadowMapPass(const IScene &scene, const ICamera &camera } } -#ifndef NDEBUG - // Post draw error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } -#endif - // Disable geometry buffer m_shadowMapBuffer.setInactive(GL_FRAMEBUFFER); @@ -394,11 +350,10 @@ CameraDirection g_cameraDirections[6] = { {GL_TEXTURE_CUBE_MAP_POSITIVE_Z, glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)}, {GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)}}; -void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camera, - const IWindow &window, - const IGraphicsResourceManager &manager) +void DeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) { - CShaderProgram *shadowCubePassShader = manager.getShaderProgram(m_shadowCubePassShaderId); + ShaderProgram *shadowCubePassShader = manager.getShaderProgram(m_shadowCubePassShaderId); shadowCubePassShader->setActive(); // Depth @@ -425,8 +380,8 @@ void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camer for (unsigned int i = 0; i < 6; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, m_shadowCubeBuffer.getId()); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - g_cameraDirections[i].cubemapFace, m_shadowCubeTexture->getId(), 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, g_cameraDirections[i].cubemapFace, + m_shadowCubeTexture->getId(), 0); glDrawBuffer(GL_COLOR_ATTACHMENT0); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); @@ -434,15 +389,14 @@ void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camer glViewport(0, 0, 1024, 1024); // Send view/projection to default shader - glm::mat4 view = - glm::lookAt(camera.getPosition(), camera.getPosition() + g_cameraDirections[i].target, - g_cameraDirections[i].up); + glm::mat4 view = glm::lookAt(camera.getPosition(), camera.getPosition() + g_cameraDirections[i].target, + g_cameraDirections[i].up); shadowCubePassShader->setUniform(projectionMatrixUniformName, camera.getProjection()); shadowCubePassShader->setUniform(viewMatrixUniformName, view); // Query visible scene objects - CSceneQuery query; + SceneQuery query; scene.getVisibleObjects(camera, query); // Traverse visible objects @@ -463,15 +417,15 @@ void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camer if (!scene.getObject(id, meshId, materialId, position, rotation, scale, visible)) { // Invalid id - LOG_ERROR("Invalid scene object id %l.", id); + loge("Invalid scene object id {}.", id); } else { // Resolve ids - CMesh *mesh = manager.getMesh(meshId); - CMaterial *material = manager.getMaterial(materialId); + Mesh *mesh = manager.getMesh(meshId); + Material *material = manager.getMaterial(materialId); - CTransformer transformer; + Transformer transformer; // Set transformations transformer.setPosition(position); @@ -485,15 +439,6 @@ void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camer } } -#ifndef NDEBUG - // Post draw error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } -#endif - // Disable buffer m_shadowCubeBuffer.setInactive(GL_FRAMEBUFFER); @@ -501,8 +446,8 @@ void CDeferredRenderer::shadowCubePass(const IScene &scene, const ICamera &camer glCullFace(GL_BACK); } -void CDeferredRenderer::lightPass(const IScene &scene, const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager, ISceneQuery &query) +void DeferredRenderer::lightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query) { // Prepare light pass frame buffer glViewport(0, 0, window.getWidth(), window.getHeight()); @@ -537,22 +482,21 @@ void CDeferredRenderer::lightPass(const IScene &scene, const ICamera &camera, co m_lightPassFrameBuffer.setInactive(GL_FRAMEBUFFER); } -void CDeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camera, - const IWindow &window, - const IGraphicsResourceManager &manager, ISceneQuery &query) +void DeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query) { // Point light pass - CShaderProgram *pointLightPassShader = manager.getShaderProgram(m_pointLightPassShaderId); + ShaderProgram *pointLightPassShader = manager.getShaderProgram(m_pointLightPassShaderId); if (pointLightPassShader == nullptr) { - LOG_ERROR("Shader program for point light pass could not be retrieved."); + loge("Shader program for point light pass could not be retrieved."); return; } - CMesh *pointLightMesh = manager.getMesh(m_pointLightSphereId); + Mesh *pointLightMesh = manager.getMesh(m_pointLightSphereId); if (pointLightMesh == nullptr) { - LOG_ERROR("Mesh object for point light pass could not be retrieved."); + loge("Mesh object for point light pass could not be retrieved."); return; } @@ -570,7 +514,7 @@ void CDeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camer if (!scene.getPointLight(pointLightId, position, radius, color, intensity, castsShadow)) { - LOG_ERROR("Failed to retrieve point light data from point light id %i.", pointLightId); + loge("Failed to retrieve point light data from point light id {}.", pointLightId); } else { @@ -580,7 +524,7 @@ void CDeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camer // too small and // 89.55 too big. glm::mat4 shadowProj = glm::perspective(89.54f, 1.0f, 0.01f, radius * 1.5f); - CStaticCamera shadowCamera(glm::mat4(), shadowProj, position); + StaticCamera shadowCamera(glm::mat4(), shadowProj, position); shadowCubePass(scene, shadowCamera, window, manager); // Prepare light pass frame buffer @@ -603,14 +547,12 @@ void CDeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camer // Set texture with world space normal and specular power m_normalSpecularTexture->setActive(lightPassNormalSpecularTextureUnit); - pointLightPassShader->setUniform(normalSpecularTextureUniformName, - lightPassNormalSpecularTextureUnit); + pointLightPassShader->setUniform(normalSpecularTextureUniformName, lightPassNormalSpecularTextureUnit); // Set shadow texture for shadow mapping glActiveTexture(GL_TEXTURE0 + lightPassShadowMapTextureUnit); glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowCubeTexture->getId()); - pointLightPassShader->setUniform(shadowCubeTextureUniformName, - lightPassShadowMapTextureUnit); + pointLightPassShader->setUniform(shadowCubeTextureUniformName, lightPassShadowMapTextureUnit); // Set screen size pointLightPassShader->setUniform(screenWidthUniformName, (float)window.getWidth()); @@ -646,25 +588,22 @@ void CDeferredRenderer::pointLightPass(const IScene &scene, const ICamera &camer return; } -void CDeferredRenderer::directionalLightPass(const IScene &scene, const ICamera &camera, - const IWindow &window, - const IGraphicsResourceManager &manager, - ISceneQuery &query) +void DeferredRenderer::directionalLightPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query) { // Restrieve shader - CShaderProgram *directionalLightPassShader = - manager.getShaderProgram(m_directionalLightPassShaderId); + ShaderProgram *directionalLightPassShader = manager.getShaderProgram(m_directionalLightPassShaderId); if (directionalLightPassShader == nullptr) { - LOG_ERROR("Shader program for directional light pass could not be retrieved."); + loge("Shader program for directional light pass could not be retrieved."); return; } // Retrieve fullscreen quad mesh - CMesh *quadMesh = manager.getMesh(m_directionalLightScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_directionalLightScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for directional light pass could not be retrieved."); + loge("Mesh object for directional light pass could not be retrieved."); return; } @@ -679,19 +618,16 @@ void CDeferredRenderer::directionalLightPass(const IScene &scene, const ICamera float intensity; bool castsShadow; - if (!scene.getDirectionalLight(directionalLightId, direction, color, intensity, - castsShadow)) + if (!scene.getDirectionalLight(directionalLightId, direction, color, intensity, castsShadow)) { - LOG_ERROR("Failed to retrieve directional light data from point light id %i.", - directionalLightId); + loge("Failed to retrieve directional light data from point light id {}.", directionalLightId); } else { // Create shadow camera - glm::mat4 shadowView = - glm::lookAt(glm::vec3(0), glm::normalize(direction), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::mat4 shadowView = glm::lookAt(glm::vec3(0), glm::normalize(direction), glm::vec3(0.0f, 1.0f, 0.0f)); glm::mat4 shadowProj = glm::ortho(-150.0f, 150.0f, -150.0f, 150.0f, -250.0f, 150.0f); - CStaticCamera shadowCamera(shadowView, shadowProj, camera.getPosition()); + StaticCamera shadowCamera(shadowView, shadowProj, camera.getPosition()); // Render shadow map shadowMapPass(scene, shadowCamera, window, manager); @@ -715,8 +651,7 @@ void CDeferredRenderer::directionalLightPass(const IScene &scene, const ICamera // Set textures for point light pass // Set depth texture m_depthTexture->setActive(lightPassDepthTextureUnit); - directionalLightPassShader->setUniform(depthTextureUniformName, - lightPassDepthTextureUnit); + directionalLightPassShader->setUniform(depthTextureUniformName, lightPassDepthTextureUnit); // Set texture with world space normal and specular power m_normalSpecularTexture->setActive(lightPassNormalSpecularTextureUnit); @@ -725,26 +660,21 @@ void CDeferredRenderer::directionalLightPass(const IScene &scene, const ICamera // Set shadow texture for shadow mapping m_shadowDepthTexture->setActive(lightPassShadowMapTextureUnit); - directionalLightPassShader->setUniform(shadowMapTextureUniformName, - lightPassShadowMapTextureUnit); + directionalLightPassShader->setUniform(shadowMapTextureUniformName, lightPassShadowMapTextureUnit); // Set screen size - directionalLightPassShader->setUniform(screenWidthUniformName, - (float)window.getWidth()); - directionalLightPassShader->setUniform(screenHeightUniformName, - (float)window.getHeight()); + directionalLightPassShader->setUniform(screenWidthUniformName, (float)window.getWidth()); + directionalLightPassShader->setUniform(screenHeightUniformName, (float)window.getHeight()); // Inverse view-projection directionalLightPassShader->setUniform(inverseViewProjectionMatrixUniformName, m_transformer.getInverseViewProjectionMatrix()); // Shadow ViewProjectionBias - glm::mat4 shadowViewProjBiasMatrix = - glm::mat4(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f) * - shadowProj * shadowView; - directionalLightPassShader->setUniform(shadowViewProjectionBiasMatrixUniformName, - shadowViewProjBiasMatrix); + glm::mat4 shadowViewProjBiasMatrix = glm::mat4(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f) * + shadowProj * shadowView; + directionalLightPassShader->setUniform(shadowViewProjectionBiasMatrixUniformName, shadowViewProjBiasMatrix); // Set directional light parameters directionalLightPassShader->setUniform(lightDirectionUniformName, direction); @@ -760,10 +690,8 @@ void CDeferredRenderer::directionalLightPass(const IScene &scene, const ICamera return; } -void CDeferredRenderer::illuminationPass(const IScene &scene, const ICamera &camera, - const IWindow &window, - const IGraphicsResourceManager &manager, - ISceneQuery &query) +void DeferredRenderer::illuminationPass(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, ISceneQuery &query) { // Reset viewport glViewport(0, 0, window.getWidth(), window.getHeight()); @@ -771,18 +699,18 @@ void CDeferredRenderer::illuminationPass(const IScene &scene, const ICamera &cam // TODO Clear illumination pass buffer? // Get illumination shader - CShaderProgram *illuminationShader = manager.getShaderProgram(m_illuminationPassShaderId); + ShaderProgram *illuminationShader = manager.getShaderProgram(m_illuminationPassShaderId); if (illuminationShader == nullptr) { - LOG_ERROR("Shader program for illumination pass could not be retrieved."); + loge("Shader program for illumination pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_illuminationPassScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_illuminationPassScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for illumination pass could not be retrieved."); + loge("Mesh object for illumination pass could not be retrieved."); return; } @@ -793,8 +721,7 @@ void CDeferredRenderer::illuminationPass(const IScene &scene, const ICamera &cam // G-buffer diffuse glow texture m_diffuseGlowTexture->setActive(illuminationPassDiffuseGlowTextureUnit); - illuminationShader->setUniform(diffuseGlowTextureUniformName, - illuminationPassDiffuseGlowTextureUnit); + illuminationShader->setUniform(diffuseGlowTextureUniformName, illuminationPassDiffuseGlowTextureUnit); // G-buffer depth texture m_depthTexture->setActive(illuminationPassDepthTextureUnit); @@ -810,9 +737,8 @@ void CDeferredRenderer::illuminationPass(const IScene &scene, const ICamera &cam m_illumationPassFrameBuffer.setInactive(GL_FRAMEBUFFER); } -void CDeferredRenderer::postProcessPass(const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::postProcessPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, const std::shared_ptr &texture) { // Reset viewport glViewport(0, 0, window.getWidth(), window.getHeight()); @@ -865,8 +791,7 @@ void CDeferredRenderer::postProcessPass(const ICamera &camera, const IWindow &wi // TODO DOF parameter m_postProcessPassFrameBuffer0.setActive(GL_FRAMEBUFFER); - depthOfFieldPass(camera, window, manager, m_postProcessPassTexture1, - m_postProcessPassTexture2); + depthOfFieldPass(camera, window, manager, m_postProcessPassTexture1, m_postProcessPassTexture2); } else { @@ -876,8 +801,7 @@ void CDeferredRenderer::postProcessPass(const ICamera &camera, const IWindow &wi // Processed scene in texture0 // Godray technique, consists of 2 passes - if ((camera.getFeatureInfo().godRayActive || - camera.getFeatureInfo().renderMode == RenderMode::GodRay)) + if ((camera.getFeatureInfo().godRayActive || camera.getFeatureInfo().renderMode == RenderMode::GodRay)) { // God ray pass 1 m_postProcessPassFrameBuffer1.setActive(GL_FRAMEBUFFER); @@ -957,22 +881,22 @@ void CDeferredRenderer::postProcessPass(const ICamera &camera, const IWindow &wi return; } -void CDeferredRenderer::fxaaPass(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::fxaaPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get fxaa shader - CShaderProgram *fxaaShader = manager.getShaderProgram(m_fxaaPassShaderId); + ShaderProgram *fxaaShader = manager.getShaderProgram(m_fxaaPassShaderId); if (fxaaShader == nullptr) { - LOG_ERROR("Shader program for fxaa pass could not be retrieved."); + loge("Shader program for fxaa pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for fxaa pass could not be retrieved."); + loge("Mesh object for fxaa pass could not be retrieved."); return; } @@ -987,23 +911,22 @@ void CDeferredRenderer::fxaaPass(const IWindow &window, const IGraphicsResourceM ::draw(*quadMesh); } -void CDeferredRenderer::fogPass(const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::fogPass(const ICamera &camera, const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get fog shader - CShaderProgram *fogShader = manager.getShaderProgram(m_fogPassShaderId); + ShaderProgram *fogShader = manager.getShaderProgram(m_fogPassShaderId); if (fogShader == nullptr) { - LOG_ERROR("Shader program for fog pass could not be retrieved."); + loge("Shader program for fog pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for fog pass could not be retrieved."); + loge("Mesh object for fog pass could not be retrieved."); return; } @@ -1041,23 +964,22 @@ void CDeferredRenderer::fogPass(const ICamera &camera, const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::gaussBlurVerticalPass(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::gaussBlurVerticalPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get gauss shader - CShaderProgram *shader = manager.getShaderProgram(m_gaussBlurVerticalShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_gaussBlurVerticalShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for vertical gauss blur pass could not be retrieved."); + loge("Shader program for vertical gauss blur pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for vertical gauss blur pass could not be retrieved."); + loge("Mesh object for vertical gauss blur pass could not be retrieved."); return; } @@ -1076,25 +998,24 @@ void CDeferredRenderer::gaussBlurVerticalPass(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::gaussBlurHorizontalPass(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::gaussBlurHorizontalPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get gauss shader - CShaderProgram *shader = manager.getShaderProgram(m_gaussBlurHorizontalShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_gaussBlurHorizontalShaderId); if (shader == nullptr) { - LOG_ERROR( + loge( "Shader program for horizontal gauss blur pass could not be " "retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for horizontal gauss blur pass could not be retrieved."); + loge("Mesh object for horizontal gauss blur pass could not be retrieved."); return; } @@ -1113,24 +1034,24 @@ void CDeferredRenderer::gaussBlurHorizontalPass(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::depthOfFieldPass(const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture, - const std::shared_ptr &blurTexture) +void DeferredRenderer::depthOfFieldPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture, + const std::shared_ptr &blurTexture) { // Get shader - CShaderProgram *shader = manager.getShaderProgram(m_depthOfFieldPassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_depthOfFieldPassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for depth-of-field pass could not be retrieved."); + loge("Shader program for depth-of-field pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for depth-of-field pass could not be retrieved."); + loge("Mesh object for depth-of-field pass could not be retrieved."); return; } @@ -1156,8 +1077,7 @@ void CDeferredRenderer::depthOfFieldPass(const ICamera &camera, const IWindow &w shader->setUniform(cameraPositionUniformName, camera.getPosition()); // Transformation - shader->setUniform(inverseViewProjectionMatrixUniformName, - m_transformer.getInverseViewProjectionMatrix()); + shader->setUniform(inverseViewProjectionMatrixUniformName, m_transformer.getInverseViewProjectionMatrix()); // Screen size shader->setUniform(screenWidthUniformName, (float)window.getWidth()); @@ -1167,34 +1087,33 @@ void CDeferredRenderer::depthOfFieldPass(const ICamera &camera, const IWindow &w ::draw(*quadMesh); } -void CDeferredRenderer::displayPass(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::displayPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Set main FBO active - CFrameBuffer::setDefaultActive(); + FrameBuffer::setDefaultActive(); passthroughPass(window, manager, texture); } -void CDeferredRenderer::passthroughPass(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::passthroughPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Reset viewport glViewport(0, 0, window.getWidth(), window.getHeight()); // Get display shader - CShaderProgram *displayShader = manager.getShaderProgram(m_displayPassShaderId); + ShaderProgram *displayShader = manager.getShaderProgram(m_displayPassShaderId); if (displayShader == nullptr) { - LOG_ERROR("Shader program for display pass could not be retrieved."); + loge("Shader program for display pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_illuminationPassScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_illuminationPassScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for illumination pass could not be retrieved."); + loge("Mesh object for illumination pass could not be retrieved."); return; } @@ -1209,22 +1128,22 @@ void CDeferredRenderer::passthroughPass(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::godRayPass1(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::godRayPass1(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get shader - CShaderProgram *shader = manager.getShaderProgram(m_godRayPass1ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_godRayPass1ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for god ray 1 pass could not be retrieved."); + loge("Shader program for god ray 1 pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for god ray 1 pass could not be retrieved."); + loge("Mesh object for god ray 1 pass could not be retrieved."); return; } @@ -1237,8 +1156,7 @@ void CDeferredRenderer::godRayPass1(const IWindow &window, const IGraphicsResour shader->setUniform(depthTextureUniformName, godRayPass1DepthTextureUnit); // Inverse projection - shader->setUniform(inverseProjectionMatrixUniformName, - m_transformer.getInverseProjectionMatrix()); + shader->setUniform(inverseProjectionMatrixUniformName, m_transformer.getInverseProjectionMatrix()); // Light position shader->setUniform(lightPositionScreenUniformName, glm::vec2(0.5, 0.5)); @@ -1251,23 +1169,23 @@ void CDeferredRenderer::godRayPass1(const IWindow &window, const IGraphicsResour ::draw(*quadMesh); } -void CDeferredRenderer::godRayPass2(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture, - const std::shared_ptr &godrayTexture) +void DeferredRenderer::godRayPass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture, + const std::shared_ptr &godrayTexture) { // Get gauss shader - CShaderProgram *shader = manager.getShaderProgram(m_godRayPass2ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_godRayPass2ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for god ray 2 pass could not be retrieved."); + loge("Shader program for god ray 2 pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for god ray 2 pass could not be retrieved."); + loge("Mesh object for god ray 2 pass could not be retrieved."); return; } @@ -1287,22 +1205,22 @@ void CDeferredRenderer::godRayPass2(const IWindow &window, const IGraphicsResour ::draw(*quadMesh); } -void CDeferredRenderer::visualizeDepthPass(const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager) +void DeferredRenderer::visualizeDepthPass(const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) { // Get shader - CShaderProgram *shader = manager.getShaderProgram(m_visualizeDepthPassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_visualizeDepthPassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for depth visualization pass could not be retrieved."); + loge("Shader program for depth visualization pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for depth visualization pass could not be retrieved."); + loge("Mesh object for depth visualization pass could not be retrieved."); return; } @@ -1323,23 +1241,22 @@ void CDeferredRenderer::visualizeDepthPass(const ICamera &camera, const IWindow ::draw(*quadMesh); } -void CDeferredRenderer::vignetteBlurPass(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::vignetteBlurPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get distortion shader - CShaderProgram *shader = manager.getShaderProgram(m_vignetteBlurPassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_vignetteBlurPassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for vignette blur pass could not be retrieved."); + loge("Shader program for vignette blur pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for vignette blur pass could not be retrieved."); + loge("Mesh object for vignette blur pass could not be retrieved."); return; } @@ -1354,22 +1271,22 @@ void CDeferredRenderer::vignetteBlurPass(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::bloomPass1(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::bloomPass1(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get bloom pass 1 shader - CShaderProgram *shader = manager.getShaderProgram(m_bloomPass1ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_bloomPass1ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for bloom 1 pass could not be retrieved."); + loge("Shader program for bloom 1 pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for bloom 1 pass could not be retrieved."); + loge("Mesh object for bloom 1 pass could not be retrieved."); return; } @@ -1384,24 +1301,24 @@ void CDeferredRenderer::bloomPass1(const IWindow &window, const IGraphicsResourc ::draw(*quadMesh); } -void CDeferredRenderer::bloomPass2(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture, - const std::shared_ptr &bloomTexture) +void DeferredRenderer::bloomPass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture, + const std::shared_ptr &bloomTexture) { // TODO Actually same as godray pass 2, create additive blend pass // Get bloom pass 2 shader - CShaderProgram *shader = manager.getShaderProgram(m_bloomPass2ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_bloomPass2ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for bloom pass 2 could not be retrieved."); + loge("Shader program for bloom pass 2 could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for bloom pass 2 could not be retrieved."); + loge("Mesh object for bloom pass 2 could not be retrieved."); return; } @@ -1421,22 +1338,21 @@ void CDeferredRenderer::bloomPass2(const IWindow &window, const IGraphicsResourc ::draw(*quadMesh); } -void CDeferredRenderer::lensFlarePass(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture) +void DeferredRenderer::lensFlarePass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture) { - CShaderProgram *shader = manager.getShaderProgram(m_lensFlarePassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_lensFlarePassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for lens flare could not be retrieved."); + loge("Shader program for lens flare could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for lens flare could not be retrieved."); + loge("Mesh object for lens flare could not be retrieved."); return; } @@ -1452,22 +1368,21 @@ void CDeferredRenderer::lensFlarePass(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::lensFlarePass2(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture) +void DeferredRenderer::lensFlarePass2(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture) { - CShaderProgram *shader = manager.getShaderProgram(m_lensFlarePass2ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_lensFlarePass2ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for lens flare could not be retrieved."); + loge("Shader program for lens flare could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for lens flare could not be retrieved."); + loge("Mesh object for lens flare could not be retrieved."); return; } @@ -1483,23 +1398,22 @@ void CDeferredRenderer::lensFlarePass2(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::lensFlarePass3(const IWindow &window, - const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture, - const std::shared_ptr &lensTexture) +void DeferredRenderer::lensFlarePass3(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture, + const std::shared_ptr &lensTexture) { - CShaderProgram *shader = manager.getShaderProgram(m_lensFlarePass3ShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_lensFlarePass3ShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for lens flare could not be retrieved."); + loge("Shader program for lens flare could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for lens flare could not be retrieved."); + loge("Mesh object for lens flare could not be retrieved."); return; } @@ -1519,21 +1433,21 @@ void CDeferredRenderer::lensFlarePass3(const IWindow &window, ::draw(*quadMesh); } -void CDeferredRenderer::celPass(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &sceneTexture) +void DeferredRenderer::celPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &sceneTexture) { - CShaderProgram *shader = manager.getShaderProgram(m_celPassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_celPassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for cel Pass could not be retrieved."); + loge("Shader program for cel Pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for cel Pass could not be retrieved."); + loge("Mesh object for cel Pass could not be retrieved."); return; } @@ -1549,22 +1463,22 @@ void CDeferredRenderer::celPass(const IWindow &window, const IGraphicsResourceMa ::draw(*quadMesh); } -void CDeferredRenderer::toneMapPass(const IWindow &window, const IGraphicsResourceManager &manager, - const std::shared_ptr &texture) +void DeferredRenderer::toneMapPass(const Window &window, const IGraphicsResourceManager &manager, + const std::shared_ptr &texture) { // Get tone map shader - CShaderProgram *shader = manager.getShaderProgram(m_toneMapPassShaderId); + ShaderProgram *shader = manager.getShaderProgram(m_toneMapPassShaderId); if (shader == nullptr) { - LOG_ERROR("Shader program for tone map pass could not be retrieved."); + loge("Shader program for tone map pass could not be retrieved."); return; } // Get screen space quad - CMesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); + Mesh *quadMesh = manager.getMesh(m_postProcessScreenQuadId); if (quadMesh == nullptr) { - LOG_ERROR("Mesh object for tone map pass could not be retrieved."); + loge("Mesh object for tone map pass could not be retrieved."); return; } @@ -1579,9 +1493,8 @@ void CDeferredRenderer::toneMapPass(const IWindow &window, const IGraphicsResour ::draw(*quadMesh); } -void CDeferredRenderer::draw(CMesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, - const glm::mat4 &scale, CMaterial *material, - const IGraphicsResourceManager &manager, CShaderProgram *shader) +void DeferredRenderer::draw(Mesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, const glm::mat4 &scale, + Material *material, const IGraphicsResourceManager &manager, ShaderProgram *shader) { // TODO Only called from geometry pass, rename? shader->setActive(); @@ -1652,17 +1565,10 @@ void CDeferredRenderer::draw(CMesh *mesh, const glm::mat4 &translation, const gl // TODO Consider custom shader bindings for meshes ::draw(*mesh); -#ifndef NDEBUG - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } -#endif // TODO Cleanup? } -bool CDeferredRenderer::initGeometryPass(IResourceManager &manager) +bool DeferredRenderer::initGeometryPass(IResourceManager &manager) { // Init geometry pass shader // TODO Read file name from config? @@ -1671,74 +1577,51 @@ bool CDeferredRenderer::initGeometryPass(IResourceManager &manager) m_geometryPassShaderId = manager.loadShader(geometryPassShaderFile); // Check if ok - if (m_geometryPassShaderId == invalidResource) + if (m_geometryPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", geometryPassShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", geometryPassShaderFile.c_str()); return false; } // Init gbuffer // Diffuse texture, stores base color and glow mask. - m_diffuseGlowTexture = std::make_shared(); - m_diffuseGlowTexture->init(800, 600, GL_RGBA); + m_diffuseGlowTexture = std::make_shared(); + m_diffuseGlowTexture->init(800, 600, GL_RGBA8); // Normal texture, store x and y, z normals and specularity. - m_normalSpecularTexture = std::make_shared(); + m_normalSpecularTexture = std::make_shared(); m_normalSpecularTexture->init(800, 600, GL_RGBA16F); // Depth texture - m_depthTexture = std::make_shared(); + m_depthTexture = std::make_shared(); m_depthTexture->init(800, 600, GL_DEPTH_COMPONENT24); - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - // Total 96 bit per pixel m_geometryBuffer.attach(m_depthTexture, GL_DEPTH_ATTACHMENT); m_geometryBuffer.attach(m_diffuseGlowTexture, GL_COLOR_ATTACHMENT0); m_geometryBuffer.attach(m_normalSpecularTexture, GL_COLOR_ATTACHMENT1); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - - LOG_INFO("GBuffer state: %s.", m_geometryBuffer.getState().c_str()); + logi("GBuffer state: {}.", m_geometryBuffer.getState()); // Reset framebuffer m_geometryBuffer.setInactive(GL_FRAMEBUFFER); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } return true; } -bool CDeferredRenderer::initShadowCubePass(IResourceManager &manager) +bool DeferredRenderer::initShadowCubePass(IResourceManager &manager) { std::string shaderFile("data/shader/shadow_cube_pass.ini"); m_shadowCubePassShaderId = manager.loadShader(shaderFile); - if (m_shadowCubePassShaderId == invalidResource) + if (m_shadowCubePassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } m_shadowCubeBuffer.resize(1024, 1024); // Depth texture - m_shadowCubeDepthTexture = std::make_shared(); + m_shadowCubeDepthTexture = std::make_shared(); m_shadowCubeDepthTexture->init(1024, 1024, GL_DEPTH_COMPONENT24); // TODO Cleanup and move into cube texture class @@ -1763,63 +1646,38 @@ bool CDeferredRenderer::initShadowCubePass(IResourceManager &manager) for (int i = 0; i < 6; i++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, 1024, 1024, 0, GL_RED, - GL_FLOAT, NULL); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, 1024, 1024, 0, GL_RED, GL_FLOAT, NULL); } - m_shadowCubeTexture = std::make_shared(textureId, false, 1024, 1024, - GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT); - - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } + m_shadowCubeTexture = + std::make_shared(textureId, false, 1024, 1024, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT); glBindFramebuffer(GL_FRAMEBUFFER, m_shadowCubeBuffer.getId()); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - m_shadowCubeDepthTexture->getId(), 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowCubeDepthTexture->getId(), 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); m_shadowCubeBuffer.setInactive(GL_FRAMEBUFFER); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - - LOG_INFO("Shadow cube buffer state: %s.", m_shadowCubeBuffer.getState().c_str()); + logi("Shadow cube buffer state: {}.", m_shadowCubeBuffer.getState().c_str()); // Reset framebuffer m_shadowCubeBuffer.setInactive(GL_FRAMEBUFFER); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } return true; } -bool CDeferredRenderer::initShadowMapPass(IResourceManager &manager) +bool DeferredRenderer::initShadowMapPass(IResourceManager &manager) { std::string shaderFile("data/shader/shadow_map_pass.ini"); m_shadowMapPassShaderId = manager.loadShader(shaderFile); - if (m_shadowMapPassShaderId == invalidResource) + if (m_shadowMapPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } // Depth texture - m_shadowDepthTexture = std::make_shared(); + m_shadowDepthTexture = std::make_shared(); m_shadowDepthTexture->init(4096, 4096, GL_DEPTH_COMPONENT24); // Set to PCF parameters @@ -1832,86 +1690,62 @@ bool CDeferredRenderer::initShadowMapPass(IResourceManager &manager) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glBindTexture(GL_TEXTURE_2D, 0); - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - // Total 96 bit per pixel m_shadowMapBuffer.attach(m_shadowDepthTexture, GL_DEPTH_ATTACHMENT); m_shadowMapBuffer.setActive(GL_FRAMEBUFFER); glDrawBuffer(GL_NONE); m_shadowMapBuffer.setInactive(GL_FRAMEBUFFER); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - - LOG_INFO("Shadow map buffer state: %s.", m_shadowMapBuffer.getState().c_str()); + logi("Shadow map buffer state: {}.", m_shadowMapBuffer.getState().c_str()); // Reset framebuffer m_shadowMapBuffer.setInactive(GL_FRAMEBUFFER); - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } return true; } -bool CDeferredRenderer::initPointLightPass(IResourceManager &manager) +bool DeferredRenderer::initPointLightPass(IResourceManager &manager) { // Point light shader std::string pointLightPassShaderFile("data/shader/deferred/point_light_pass.ini"); m_pointLightPassShaderId = manager.loadShader(pointLightPassShaderFile); // Check if ok - if (m_pointLightPassShaderId == invalidResource) + if (m_pointLightPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", - pointLightPassShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", pointLightPassShaderFile.c_str()); return false; } // Load sphere mesh for point light representation std::string sphereMesh = "data/mesh/sphere.obj"; m_pointLightSphereId = manager.loadMesh(sphereMesh); - if (m_pointLightSphereId == invalidResource) + if (m_pointLightSphereId == InvalidResource) { - LOG_ERROR("Failed to load point light volume mesh %s.", sphereMesh.c_str()); + loge("Failed to load point light volume mesh {}.", sphereMesh.c_str()); return false; } // Attach texture for light data - m_lightPassTexture = std::make_shared(); + m_lightPassTexture = std::make_shared(); if (!m_lightPassTexture->init(800, 600, GL_RGBA16F)) { - LOG_ERROR("Failed to create color texture for light pass frame buffer."); + loge("Failed to create color texture for light pass frame buffer."); return false; } m_lightPassFrameBuffer.attach(m_lightPassTexture, GL_COLOR_ATTACHMENT0); // Attach depth buffer // Depth gets discarded, depth values from geometry pass are used - std::shared_ptr depthBuffer = std::make_shared(); + std::shared_ptr depthBuffer = std::make_shared(); if (!depthBuffer->init(800, 600, GL_DEPTH_COMPONENT)) { - LOG_ERROR("Failed to create depth buffer for light pass frame buffer."); + loge("Failed to create depth buffer for light pass frame buffer."); return false; } m_lightPassFrameBuffer.attach(depthBuffer, GL_DEPTH_ATTACHMENT); return true; } -bool CDeferredRenderer::initDirectionalLightPass(IResourceManager &manager) +bool DeferredRenderer::initDirectionalLightPass(IResourceManager &manager) { // Uses same frame buffer as point light pass // Directional light shader @@ -1919,49 +1753,33 @@ bool CDeferredRenderer::initDirectionalLightPass(IResourceManager &manager) m_directionalLightPassShaderId = manager.loadShader(directionalLightPassShaderFile); // Check if ok - if (m_directionalLightPassShaderId == invalidResource) + if (m_directionalLightPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", - directionalLightPassShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", directionalLightPassShaderFile.c_str()); return false; } // Load quad mesh for directional light representation std::string quadMesh = "data/mesh/screen_quad.obj"; m_directionalLightScreenQuadId = manager.loadMesh(quadMesh); - if (m_directionalLightScreenQuadId == invalidResource) + if (m_directionalLightScreenQuadId == InvalidResource) { - LOG_ERROR("Failed to load screen quad mesh %s.", quadMesh.c_str()); + loge("Failed to load screen quad mesh {}.", quadMesh.c_str()); return false; } return true; } -bool CDeferredRenderer::initIlluminationPass(IResourceManager &manager) +bool DeferredRenderer::initIlluminationPass(IResourceManager &manager) { - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } // Load illumination shader std::string illuminationPassShaderFile = "data/shader/deferred/illumination_pass.ini"; m_illuminationPassShaderId = manager.loadShader(illuminationPassShaderFile); // Check if ok - if (m_illuminationPassShaderId == invalidResource) - { - LOG_ERROR("Failed to initialize the shader from file %s.", - illuminationPassShaderFile.c_str()); - return false; - } - - // Error check - if (hasGLError(error)) + if (m_illuminationPassShaderId == InvalidResource) { - LOG_ERROR("GL Error: %s", error.c_str()); + loge("Failed to initialize the shader from file {}.", illuminationPassShaderFile.c_str()); return false; } @@ -1969,155 +1787,141 @@ bool CDeferredRenderer::initIlluminationPass(IResourceManager &manager) std::string quadMesh = "data/mesh/screen_quad.obj"; m_illuminationPassScreenQuadId = manager.loadMesh(quadMesh); // Check if ok - if (m_illuminationPassScreenQuadId == invalidResource) + if (m_illuminationPassScreenQuadId == InvalidResource) { - LOG_ERROR("Failed to load screen quad mesh %s.", quadMesh.c_str()); - return false; - } - - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); + loge("Failed to load screen quad mesh {}.", quadMesh.c_str()); return false; } // FBO - m_illuminationPassTexture = std::make_shared(); + m_illuminationPassTexture = std::make_shared(); if (!m_illuminationPassTexture->init(800, 600, GL_RGB16F)) { - LOG_ERROR("Failed to initialize illumination pass texture."); + loge("Failed to initialize illumination pass texture."); return false; } m_illumationPassFrameBuffer.attach(m_illuminationPassTexture, GL_COLOR_ATTACHMENT0); // TODO Check FBO - // Error check - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - return true; } -bool CDeferredRenderer::initPostProcessPass(IResourceManager &manager) +bool DeferredRenderer::initPostProcessPass(IResourceManager &manager) { // Gauss blur pass if (!initGaussBlurHorizontalPass(manager)) { - LOG_ERROR("Failed to initialize gauss blur horizontal pass."); + loge("Failed to initialize gauss blur horizontal pass."); return false; } if (!initGaussBlurVerticalPass(manager)) { - LOG_ERROR("Failed to initialize gauss blur vertical pass."); + loge("Failed to initialize gauss blur vertical pass."); return false; } // FXAA if (!initFxaaPass(manager)) { - LOG_ERROR("Failed to initialize fxaa pass."); + loge("Failed to initialize fxaa pass."); return false; } // Fog if (!initFogPass(manager)) { - LOG_ERROR("Failed to initialize fog pass."); + loge("Failed to initialize fog pass."); return false; } // Godray if (!initGodRayPass1(manager)) { - LOG_ERROR("Failed to initialize god ray 1 pass."); + loge("Failed to initialize god ray 1 pass."); return false; } // Should actually compose by additive blending if (!initGodRayPass2(manager)) { - LOG_ERROR("Failed to initialize god ray 2 pass."); + loge("Failed to initialize god ray 2 pass."); return false; } // DOF pass if (!initDepthOfFieldPass(manager)) { - LOG_ERROR("Failed to initialize depth of field pass."); + loge("Failed to initialize depth of field pass."); return false; } // Vignette blur pass if (!initVignetteBlurPass(manager)) { - LOG_ERROR("Failed to initialize depth visualization pass."); + loge("Failed to initialize depth visualization pass."); return false; } // Bloom pass 1 if (!initBloomPass1(manager)) { - LOG_ERROR("Failed to initialize bloom pass 1."); + loge("Failed to initialize bloom pass 1."); return false; } // Bloom pass 2 if (!initBloomPass2(manager)) { - LOG_ERROR("Failed to initialize bloom pass 2."); + loge("Failed to initialize bloom pass 2."); return false; } if (!initLensFlarePass(manager)) { - LOG_ERROR("Failed to initialize lens flare pass."); + loge("Failed to initialize lens flare pass."); return false; } if (!initLensFlarePass2(manager)) { - LOG_ERROR("Failed to initialize lens flare pass."); + loge("Failed to initialize lens flare pass."); return false; } if (!initLensFlarePass3(manager)) { - LOG_ERROR("Failed to initialize lens flare pass."); + loge("Failed to initialize lens flare pass."); return false; } if (!initCelPass(manager)) { - LOG_ERROR("Failed to initialize cel pass."); + loge("Failed to initialize cel pass."); return false; } // Tone map pass (non-adaptive) if (!initToneMapPass(manager)) { - LOG_ERROR("Failed to initialize non-adaptive tonemap pass."); + loge("Failed to initialize non-adaptive tonemap pass."); } // Screen quad mesh std::string quadMesh = "data/mesh/screen_quad.obj"; m_postProcessScreenQuadId = manager.loadMesh(quadMesh); - if (m_directionalLightScreenQuadId == invalidResource) + if (m_directionalLightScreenQuadId == InvalidResource) { - LOG_ERROR("Failed to load screen quad mesh %s.", quadMesh.c_str()); + loge("Failed to load screen quad mesh {}.", quadMesh.c_str()); return false; } // Init post processing FBOs // Texture 0 - m_postProcessPassTexture0 = std::make_shared(); + m_postProcessPassTexture0 = std::make_shared(); if (!m_postProcessPassTexture0->init(800, 600, GL_RGB16F)) { - LOG_ERROR("Failed to initialize post process pass texture 0."); + loge("Failed to initialize post process pass texture 0."); return false; } m_postProcessPassTexture0->setParameter(GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); @@ -2125,10 +1929,10 @@ bool CDeferredRenderer::initPostProcessPass(IResourceManager &manager) m_postProcessPassTexture0->setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // Texture 1 - m_postProcessPassTexture1 = std::make_shared(); + m_postProcessPassTexture1 = std::make_shared(); if (!m_postProcessPassTexture1->init(800, 600, GL_RGB16F)) { - LOG_ERROR("Failed to initialize post process pass texture 1."); + loge("Failed to initialize post process pass texture 1."); return false; } m_postProcessPassTexture1->setParameter(GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); @@ -2136,10 +1940,10 @@ bool CDeferredRenderer::initPostProcessPass(IResourceManager &manager) m_postProcessPassTexture1->setParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); // Texture 2 - m_postProcessPassTexture2 = std::make_shared(); + m_postProcessPassTexture2 = std::make_shared(); if (!m_postProcessPassTexture2->init(800, 600, GL_RGB16F)) { - LOG_ERROR("Failed to initialize post process pass texture 2."); + loge("Failed to initialize post process pass texture 2."); return false; } m_postProcessPassTexture2->setParameter(GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); @@ -2153,241 +1957,239 @@ bool CDeferredRenderer::initPostProcessPass(IResourceManager &manager) return true; } -bool CDeferredRenderer::initDepthOfFieldPass(IResourceManager &manager) +bool DeferredRenderer::initDepthOfFieldPass(IResourceManager &manager) { // Depth of field shader std::string depthOfFieldShaderFile = "data/shader/post/depth_of_field_pass.ini"; m_depthOfFieldPassShaderId = manager.loadShader(depthOfFieldShaderFile); // Check if ok - if (m_depthOfFieldPassShaderId == invalidResource) + if (m_depthOfFieldPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", depthOfFieldShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", depthOfFieldShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initGaussBlurVerticalPass(IResourceManager &manager) +bool DeferredRenderer::initGaussBlurVerticalPass(IResourceManager &manager) { // Depth of field shader std::string gaussBlurVerticalShaderFile = "data/shader/post/gauss_blur_vertical_pass.ini"; m_gaussBlurVerticalShaderId = manager.loadShader(gaussBlurVerticalShaderFile); // Check if ok - if (m_gaussBlurVerticalShaderId == invalidResource) + if (m_gaussBlurVerticalShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", - gaussBlurVerticalShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", gaussBlurVerticalShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initGaussBlurHorizontalPass(IResourceManager &manager) +bool DeferredRenderer::initGaussBlurHorizontalPass(IResourceManager &manager) { // Depth of field shader std::string gaussBlurHorizontalShaderFile = "data/shader/post/gauss_blur_horizontal_pass.ini"; m_gaussBlurHorizontalShaderId = manager.loadShader(gaussBlurHorizontalShaderFile); // Check if ok - if (m_gaussBlurHorizontalShaderId == invalidResource) + if (m_gaussBlurHorizontalShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", - gaussBlurHorizontalShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", gaussBlurHorizontalShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initFxaaPass(IResourceManager &manager) +bool DeferredRenderer::initFxaaPass(IResourceManager &manager) { // Fxaa shader std::string fxaaShaderFile = "data/shader/post/fxaa_pass.ini"; m_fxaaPassShaderId = manager.loadShader(fxaaShaderFile); // Check if ok - if (m_fxaaPassShaderId == invalidResource) + if (m_fxaaPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", fxaaShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", fxaaShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initFogPass(IResourceManager &manager) +bool DeferredRenderer::initFogPass(IResourceManager &manager) { // Fog shader std::string fogShaderFile = "data/shader/post/fog_pass.ini"; m_fogPassShaderId = manager.loadShader(fogShaderFile); // Check if ok - if (m_fogPassShaderId == invalidResource) + if (m_fogPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", fogShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", fogShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initGodRayPass1(IResourceManager &manager) +bool DeferredRenderer::initGodRayPass1(IResourceManager &manager) { // Get shader std::string shader = "data/shader/post/god_ray_1_pass.ini"; m_godRayPass1ShaderId = manager.loadShader(shader); // Check if ok - if (m_godRayPass1ShaderId == invalidResource) + if (m_godRayPass1ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shader.c_str()); + loge("Failed to initialize the shader from file {}.", shader.c_str()); return false; } return true; } -bool CDeferredRenderer::initGodRayPass2(IResourceManager &manager) +bool DeferredRenderer::initGodRayPass2(IResourceManager &manager) { // Get shader std::string shader = "data/shader/post/god_ray_2_pass.ini"; m_godRayPass2ShaderId = manager.loadShader(shader); // Check if ok - if (m_godRayPass2ShaderId == invalidResource) + if (m_godRayPass2ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shader.c_str()); + loge("Failed to initialize the shader from file {}.", shader.c_str()); return false; } return true; } -bool CDeferredRenderer::initDisplayPass(IResourceManager &manager) +bool DeferredRenderer::initDisplayPass(IResourceManager &manager) { // Display shader std::string displayPassShaderFile = "data/shader/display_pass.ini"; m_displayPassShaderId = manager.loadShader(displayPassShaderFile); // Check if ok - if (m_displayPassShaderId == invalidResource) + if (m_displayPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", displayPassShaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", displayPassShaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initVisualizeDepthPass(IResourceManager &manager) +bool DeferredRenderer::initVisualizeDepthPass(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/debug/visualize_depth_buffer_pass.ini"; m_visualizeDepthPassShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_visualizeDepthPassShaderId == invalidResource) + if (m_visualizeDepthPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initVignetteBlurPass(IResourceManager &manager) +bool DeferredRenderer::initVignetteBlurPass(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/vignette_blur_pass.ini"; m_vignetteBlurPassShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_vignetteBlurPassShaderId == invalidResource) + if (m_vignetteBlurPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initBloomPass1(IResourceManager &manager) +bool DeferredRenderer::initBloomPass1(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/bloom_1_pass.ini"; m_bloomPass1ShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_bloomPass1ShaderId == invalidResource) + if (m_bloomPass1ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initBloomPass2(IResourceManager &manager) +bool DeferredRenderer::initBloomPass2(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/bloom_2_pass.ini"; m_bloomPass2ShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_bloomPass2ShaderId == invalidResource) + if (m_bloomPass2ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initLensFlarePass(IResourceManager &manager) +bool DeferredRenderer::initLensFlarePass(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/lens_flare_pass.ini"; m_lensFlarePassShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_lensFlarePassShaderId == invalidResource) + if (m_lensFlarePassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initLensFlarePass2(IResourceManager &manager) +bool DeferredRenderer::initLensFlarePass2(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/lens_flare_pass2.ini"; m_lensFlarePass2ShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_lensFlarePass2ShaderId == invalidResource) + if (m_lensFlarePass2ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initLensFlarePass3(IResourceManager &manager) +bool DeferredRenderer::initLensFlarePass3(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/lens_flare_pass3.ini"; m_lensFlarePass3ShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_lensFlarePass3ShaderId == invalidResource) + if (m_lensFlarePass3ShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initCelPass(IResourceManager &manager) +bool DeferredRenderer::initCelPass(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/cel_pass.ini"; m_celPassShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_celPassShaderId == invalidResource) + if (m_celPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; } -bool CDeferredRenderer::initToneMapPass(IResourceManager &manager) +bool DeferredRenderer::initToneMapPass(IResourceManager &manager) { // Get shader std::string shaderFile = "data/shader/post/tonemap_pass.ini"; m_toneMapPassShaderId = manager.loadShader(shaderFile); // Check if ok - if (m_toneMapPassShaderId == invalidResource) + if (m_toneMapPassShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the shader from file %s.", shaderFile.c_str()); + loge("Failed to initialize the shader from file {}.", shaderFile.c_str()); return false; } return true; diff --git a/Graphics/Lib/source/graphics/renderer/Draw.cpp b/Engine/Lib/source/graphics/renderer/Draw.cpp similarity index 61% rename from Graphics/Lib/source/graphics/renderer/Draw.cpp rename to Engine/Lib/source/graphics/renderer/Draw.cpp index 41a3897..b33d13f 100644 --- a/Graphics/Lib/source/graphics/renderer/Draw.cpp +++ b/Engine/Lib/source/graphics/renderer/Draw.cpp @@ -1,16 +1,22 @@ -#include "graphics/graphics/renderer/Draw.h" +#include "kern/graphics/renderer/Draw.h" #include -#include "graphics/graphics/resource/CMesh.h" +#include -void draw(CMesh &mesh) +#include "kern/graphics/resource/Mesh.h" + +void draw(Mesh &mesh) { + if (mesh.getPrimitiveType() == PrimitiveType::Invalid) + { + return; + } mesh.getVertexArray()->setActive(); // Set primitive draw mode - GLenum mode = CMesh::toGLPrimitive(mesh.getPrimitiveType()); - unsigned int primitiveSize = CMesh::getPrimitiveSize(mesh.getPrimitiveType()); + GLenum mode = Mesh::toGLPrimitive(mesh.getPrimitiveType()); + unsigned int primitiveSize = Mesh::getPrimitiveSize(mesh.getPrimitiveType()); // Decide on draw method based on the stored data if (mesh.hasIndexBuffer()) diff --git a/Graphics/Lib/source/graphics/renderer/CForwardRenderer.cpp b/Engine/Lib/source/graphics/renderer/ForwardRenderer.cpp similarity index 66% rename from Graphics/Lib/source/graphics/renderer/CForwardRenderer.cpp rename to Engine/Lib/source/graphics/renderer/ForwardRenderer.cpp index 70edfa0..69876b9 100644 --- a/Graphics/Lib/source/graphics/renderer/CForwardRenderer.cpp +++ b/Engine/Lib/source/graphics/renderer/ForwardRenderer.cpp @@ -1,41 +1,36 @@ -#include "graphics/graphics/renderer/CForwardRenderer.h" +#include "kern/graphics/renderer/ForwardRenderer.h" -#include -#include +#include +#include #include +#include -#include -#include - -#include "graphics/resource/IResourceManager.h" - -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/graphics/IScene.h" -#include "graphics/graphics/IWindow.h" -#include "graphics/graphics/scene/CSceneQuery.h" - -#include "graphics/graphics/resource/CMaterial.h" -#include "graphics/graphics/resource/CMesh.h" -#include "graphics/graphics/resource/CShaderProgram.h" -#include "graphics/graphics/resource/CTexture.h" - -#include "graphics/graphics/renderer/Draw.h" -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/renderer/debug/RendererDebug.h" +#include "kern/foundation/Transformer.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/Window.h" +#include "kern/graphics/renderer/Draw.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/graphics/resource/Material.h" +#include "kern/graphics/resource/Mesh.h" +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/Texture.h" +#include "kern/graphics/scene/SceneQuery.h" +#include "kern/resource/IResourceManager.h" // Shader sources #include "graphics/renderer/shader/ShaderForwardRenderer.h" -CForwardRenderer::CForwardRenderer() { return; } +ForwardRenderer::ForwardRenderer() { return; } -CForwardRenderer::~CForwardRenderer() +ForwardRenderer::~ForwardRenderer() { // TODO Cleanup } -bool CForwardRenderer::init(IResourceManager &manager) +bool ForwardRenderer::init(IResourceManager &manager) { // Set clear color glClearColor(0.6f, 0.6f, 0.6f, 1.0f); @@ -51,20 +46,12 @@ bool CForwardRenderer::init(IResourceManager &manager) // Winding order, standard is counter-clockwise glFrontFace(GL_CCW); - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - // Load and init default shaders return initShaders(manager); } -void CForwardRenderer::draw(const IScene &scene, const ICamera &camera, const IWindow &window, - const IGraphicsResourceManager &manager) +void ForwardRenderer::draw(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) { // Draw init window.setActive(); @@ -86,7 +73,7 @@ void CForwardRenderer::draw(const IScene &scene, const ICamera &camera, const IW m_currentProjection = camera.getProjection(); // Query visible scene objects - CSceneQuery query; + SceneQuery query; scene.getVisibleObjects(camera, query); // Send view/projection to default shader @@ -111,16 +98,16 @@ void CForwardRenderer::draw(const IScene &scene, const ICamera &camera, const IW if (!scene.getObject(id, meshId, materialId, position, rotation, scale, visible)) { // Invalid id - LOG_ERROR("Invalid scene object id %l.", id); + loge("Invalid scene object id {}.", id); } else { // Resolve ids - CMesh *mesh = manager.getMesh(meshId); - CMaterial *material = manager.getMaterial(materialId); + Mesh *mesh = manager.getMesh(meshId); + Material *material = manager.getMaterial(materialId); // Create matrices - CTransformer transformer; + Transformer transformer; transformer.setPosition(position); transformer.setRotation(rotation); transformer.setScale(scale); @@ -130,30 +117,22 @@ void CForwardRenderer::draw(const IScene &scene, const ICamera &camera, const IW transformer.getScaleMatrix(), material, manager); } } - - // Post draw error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } } -CForwardRenderer *CForwardRenderer::create(IResourceManager &manager) +ForwardRenderer *ForwardRenderer::create(IResourceManager &manager) { - CForwardRenderer *renderer = new CForwardRenderer; + ForwardRenderer *renderer = new ForwardRenderer; if (!renderer->init(manager)) { delete renderer; renderer = nullptr; - LOG_ERROR("Failed to create forward renderer, initialization failed."); + loge("Failed to create forward renderer, initialization failed."); } return renderer; } -void CForwardRenderer::draw(CMesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, - const glm::mat4 &scale, CMaterial *material, - const IGraphicsResourceManager &manager) +void ForwardRenderer::draw(Mesh *mesh, const glm::mat4 &translation, const glm::mat4 &rotation, const glm::mat4 &scale, + Material *material, const IGraphicsResourceManager &manager) { // Transformation matrices m_forwardShader->setUniform(translationMatrixUniformName, translation); @@ -226,19 +205,19 @@ void CForwardRenderer::draw(CMesh *mesh, const glm::mat4 &translation, const glm ::draw(*mesh); } -bool CForwardRenderer::initShaders(IResourceManager &manager) +bool ForwardRenderer::initShaders(IResourceManager &manager) { std::string defaultShaderFile("data/shader/forward_test_0.ini"); auto vertexShaderId = manager.createString(getForwardRendererVertexShader()); auto fragmentShaderId = manager.createString(getForwardRendererFragmentShader()); - m_forwardShaderId = manager.createShader(vertexShaderId, invalidResource, invalidResource, - invalidResource, fragmentShaderId); + m_forwardShaderId = + manager.createShader(vertexShaderId, InvalidResource, InvalidResource, InvalidResource, fragmentShaderId); // Check if ok - if (m_forwardShaderId == invalidResource) + if (m_forwardShaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the farward shader."); + loge("Failed to initialize the farward shader."); return false; } return true; diff --git a/Graphics/Lib/source/graphics/renderer/CFrameBuffer.cpp b/Engine/Lib/source/graphics/renderer/FrameBuffer.cpp similarity index 76% rename from Graphics/Lib/source/graphics/renderer/CFrameBuffer.cpp rename to Engine/Lib/source/graphics/renderer/FrameBuffer.cpp index 39137a0..1f349f1 100644 --- a/Graphics/Lib/source/graphics/renderer/CFrameBuffer.cpp +++ b/Engine/Lib/source/graphics/renderer/FrameBuffer.cpp @@ -1,13 +1,13 @@ -#include "graphics/graphics/renderer/CFrameBuffer.h" +#include "kern/graphics/renderer/FrameBuffer.h" #include -#include "graphics/graphics/renderer/CRenderBuffer.h" -#include "graphics/graphics/resource/CTexture.h" +#include "kern/graphics/renderer/RenderBuffer.h" +#include "kern/graphics/resource/Texture.h" -CFrameBuffer::CFrameBuffer() : m_fboId(0), m_valid(false) { init(); } +FrameBuffer::FrameBuffer() : m_fboId(0), m_valid(false) { init(); } -CFrameBuffer::~CFrameBuffer() +FrameBuffer::~FrameBuffer() { if (m_valid) { @@ -15,7 +15,7 @@ CFrameBuffer::~CFrameBuffer() } } -bool CFrameBuffer::init() +bool FrameBuffer::init() { GLuint bufferId; glGenFramebuffers(1, &bufferId); @@ -26,9 +26,9 @@ bool CFrameBuffer::init() return m_valid; } -bool CFrameBuffer::isValid() const { return m_valid; } +bool FrameBuffer::isValid() const { return m_valid; } -std::string CFrameBuffer::getState() +std::string FrameBuffer::getState() { assert(m_valid); glBindFramebuffer(GL_FRAMEBUFFER, m_fboId); @@ -72,7 +72,7 @@ std::string CFrameBuffer::getState() return "Invalid state encountered"; } -void CFrameBuffer::setActive(GLenum target) +void FrameBuffer::setActive(GLenum target) { assert(m_valid); glBindFramebuffer(target, m_fboId); @@ -83,14 +83,15 @@ void CFrameBuffer::setActive(GLenum target) } } -void CFrameBuffer::setInactive(GLenum target) { glBindFramebuffer(target, 0); } +void FrameBuffer::setInactive(GLenum target) { glBindFramebuffer(target, 0); } -void CFrameBuffer::resize(unsigned int width, unsigned int height) +void FrameBuffer::resize(unsigned int width, unsigned int height) { for (auto &entry : m_textures) { entry.second->resize(width, height); } + for (auto &entry : m_renderBuffers) { // Need renderbuffer connot be resized @@ -102,8 +103,8 @@ void CFrameBuffer::resize(unsigned int width, unsigned int height) } } -void CFrameBuffer::attach(const std::shared_ptr &texture, GLenum attachment, - ETextureSemantic semantic) +void FrameBuffer::attach(const std::shared_ptr &texture, GLenum attachment, + TextureSemantic semantic) { // Bind assert(m_valid); @@ -117,27 +118,27 @@ void CFrameBuffer::attach(const std::shared_ptr &texture, GLenum attac m_drawBuffers.push_back(attachment); } m_textures[attachment] = texture; - if (semantic != ETextureSemantic::Unknown) + if (semantic != TextureSemantic::Unknown) { m_texturesBySemantic[semantic] = texture; } setInactive(GL_FRAMEBUFFER); } -void CFrameBuffer::attach(const std::shared_ptr &texture, GLenum attachment) +void FrameBuffer::attach(const std::shared_ptr &texture, GLenum attachment) { - ETextureSemantic semantic = ETextureSemantic::Unknown; + TextureSemantic semantic = TextureSemantic::Unknown; // On depth attachment automatically set semantic if (attachment == GL_DEPTH_ATTACHMENT) { - semantic = ETextureSemantic::Depth; + semantic = TextureSemantic::Depth; } attach(texture, attachment, semantic); } -void CFrameBuffer::setDefaultActive() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void FrameBuffer::setDefaultActive() { glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void CFrameBuffer::attach(const std::shared_ptr &renderBuffer, GLenum attachment) +void FrameBuffer::attach(const std::shared_ptr &renderBuffer, GLenum attachment) { // Bind assert(m_valid); @@ -154,7 +155,7 @@ void CFrameBuffer::attach(const std::shared_ptr &renderBuffer, GL setInactive(GL_FRAMEBUFFER); } -std::shared_ptr CFrameBuffer::getTexture(ETextureSemantic semantic) +std::shared_ptr FrameBuffer::getTexture(TextureSemantic semantic) { // TODO Slow, fix this if (m_texturesBySemantic.count(semantic) == 0) diff --git a/Engine/Lib/source/graphics/renderer/IndexBuffer.cpp b/Engine/Lib/source/graphics/renderer/IndexBuffer.cpp new file mode 100644 index 0000000..f23a96f --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/IndexBuffer.cpp @@ -0,0 +1,41 @@ +#include "kern/graphics/renderer/IndexBuffer.h" + +#include + +#include + +IndexBuffer::IndexBuffer(const std::vector &indices, GLenum usage) + : m_bufferId(0), m_size(0), m_valid(false) +{ + if (indices.empty()) + { + loge("Index buffer data is empty."); + return; + } + glGenBuffers(1, &m_bufferId); + // Unchecked bind + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufferId); + // Set data + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), usage); + m_size = (unsigned int)indices.size(); + // TODO Check error + // Unbind + setInactive(); + m_valid = true; +} + +IndexBuffer::~IndexBuffer() { glDeleteBuffers(1, &m_bufferId); } + +void IndexBuffer::setActive() const +{ + assert(isValid()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufferId); +} + +void IndexBuffer::setInactive() const { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + +bool IndexBuffer::isValid() const { return m_valid; } + +GLuint IndexBuffer::getId() const { return m_bufferId; } + +unsigned int IndexBuffer::getSize() const { return m_size; } \ No newline at end of file diff --git a/Engine/Lib/source/graphics/renderer/NullRenderer.cpp b/Engine/Lib/source/graphics/renderer/NullRenderer.cpp new file mode 100644 index 0000000..f2e2ebe --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/NullRenderer.cpp @@ -0,0 +1,21 @@ +#include "kern/graphics/renderer/NullRenderer.h" + +#include + +#include + +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/IScene.h" +#include "kern/graphics/Window.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" + +void NullRenderer::draw(const IScene &scene, const ICamera &camera, const Window &window, + const IGraphicsResourceManager &manager) +{ + window.setActive(); + // Set clear color + glClearColor(0.f, 0.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + return; +} \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/renderer/CRenderBuffer.cpp b/Engine/Lib/source/graphics/renderer/RenderBuffer.cpp similarity index 51% rename from Graphics/Lib/source/graphics/renderer/CRenderBuffer.cpp rename to Engine/Lib/source/graphics/renderer/RenderBuffer.cpp index 5eb4eac..f8571cb 100644 --- a/Graphics/Lib/source/graphics/renderer/CRenderBuffer.cpp +++ b/Engine/Lib/source/graphics/renderer/RenderBuffer.cpp @@ -1,8 +1,8 @@ -#include "graphics/graphics/renderer/CRenderBuffer.h" +#include "kern/graphics/renderer/RenderBuffer.h" -CRenderBuffer::CRenderBuffer() {} +RenderBuffer::RenderBuffer() {} -CRenderBuffer::~CRenderBuffer() +RenderBuffer::~RenderBuffer() { if (m_init) { @@ -10,7 +10,7 @@ CRenderBuffer::~CRenderBuffer() } } -bool CRenderBuffer::init(unsigned int width, unsigned int height, GLenum format) +bool RenderBuffer::init(unsigned int width, unsigned int height, GLenum format) { if (m_init) { @@ -25,7 +25,7 @@ bool CRenderBuffer::init(unsigned int width, unsigned int height, GLenum format) return true; } -bool CRenderBuffer::resize(unsigned int width, unsigned int height) +bool RenderBuffer::resize(unsigned int width, unsigned int height) { if (m_width != width || m_height != height) { @@ -35,8 +35,8 @@ bool CRenderBuffer::resize(unsigned int width, unsigned int height) return false; } -GLuint CRenderBuffer::getId() const { return m_bufferId; } +GLuint RenderBuffer::getId() const { return m_bufferId; } -GLenum CRenderBuffer::getFormat() const { return m_format; } +GLenum RenderBuffer::getFormat() const { return m_format; } -void CRenderBuffer::setActive() const { glBindRenderbuffer(GL_RENDERBUFFER, m_bufferId); } +void RenderBuffer::setActive() const { glBindRenderbuffer(GL_RENDERBUFFER, m_bufferId); } diff --git a/Graphics/Lib/source/graphics/renderer/SRenderRequest.cpp b/Engine/Lib/source/graphics/renderer/RenderRequest.cpp similarity index 63% rename from Graphics/Lib/source/graphics/renderer/SRenderRequest.cpp rename to Engine/Lib/source/graphics/renderer/RenderRequest.cpp index 9a1c9fd..51bc508 100644 --- a/Graphics/Lib/source/graphics/renderer/SRenderRequest.cpp +++ b/Engine/Lib/source/graphics/renderer/RenderRequest.cpp @@ -1,11 +1,11 @@ -#include "graphics/graphics/renderer/SRenderRequest.h" +#include "kern/graphics/renderer/RenderRequest.h" -SRenderRequest::SRenderRequest() +RenderRequest::RenderRequest() : m_mesh(nullptr), m_material(nullptr), m_translation(1.f), m_rotation(1.f), m_scale(1.f) { } -SRenderRequest::SRenderRequest(CMesh *mesh, CMaterial *material, const glm::mat4 &translation, +RenderRequest::RenderRequest(Mesh *mesh, Material *material, const glm::mat4 &translation, const glm::mat4 &rotation, const glm::mat4 &scale) : m_mesh(mesh), m_material(material), diff --git a/Engine/Lib/source/graphics/renderer/Sampler.cpp b/Engine/Lib/source/graphics/renderer/Sampler.cpp new file mode 100644 index 0000000..637eff4 --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/Sampler.cpp @@ -0,0 +1,17 @@ +#include "kern/graphics/renderer/Sampler.h" + +Sampler::Sampler() { glGenSamplers(1, &m_samplerId); } + +Sampler::~Sampler() { glDeleteSamplers(1, &m_samplerId); } + +void Sampler::bind(GLuint unit) { glBindSampler(unit, m_samplerId); } + +void Sampler::setMinFilter(GLint filter) +{ + glSamplerParameteri(m_samplerId, GL_TEXTURE_MIN_FILTER, filter); +} + +void Sampler::setMagFilter(GLint filter) +{ + glSamplerParameteri(m_samplerId, GL_TEXTURE_MAG_FILTER, filter); +} \ No newline at end of file diff --git a/Engine/Lib/source/graphics/renderer/VertexArrayObject.cpp b/Engine/Lib/source/graphics/renderer/VertexArrayObject.cpp new file mode 100644 index 0000000..579f893 --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/VertexArrayObject.cpp @@ -0,0 +1,19 @@ +#include "kern/graphics/renderer/VertexArrayObject.h" + +VertexArrayObject::VertexArrayObject() { glGenVertexArrays(1, &m_vaoId); } + +VertexArrayObject::~VertexArrayObject() { glDeleteVertexArrays(1, &m_vaoId); } + +void VertexArrayObject::setActive() const +{ + glBindVertexArray(m_vaoId); + return; +} + +void VertexArrayObject::setInactive() const +{ + glBindVertexArray(0); + return; +} + +GLuint VertexArrayObject::getId() const { return m_vaoId; } diff --git a/Engine/Lib/source/graphics/renderer/VertexBuffer.cpp b/Engine/Lib/source/graphics/renderer/VertexBuffer.cpp new file mode 100644 index 0000000..b6aafdc --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/VertexBuffer.cpp @@ -0,0 +1,54 @@ +#include "kern/graphics/renderer/VertexBuffer.h" + +#include + +#include + +VertexBuffer::VertexBuffer(const std::vector &data, GLenum usage) + : m_bufferId(0), m_valid(false), m_size((unsigned int)data.size()), m_usage(usage) +{ + if (data.empty()) + { + loge("Vertex buffer data is empty."); + return; + } + // Create GL buffer resource + glGenBuffers(1, &m_bufferId); + // Unchecked bind + glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); + // Set data + glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), data.data(), usage); + setInactive(); + m_valid = true; +} + +VertexBuffer::~VertexBuffer() { glDeleteBuffers(1, &m_bufferId); } + +void VertexBuffer::setActive() const +{ + assert(isValid()); + glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); +} + +void VertexBuffer::setInactive() const { glBindBuffer(GL_ARRAY_BUFFER, 0); } + +bool VertexBuffer::isValid() const { return m_valid; } + +GLuint VertexBuffer::getId() const { return m_bufferId; } + +unsigned int VertexBuffer::getSize() const { return m_size; } + +VertexBuffer::VertexBuffer(GLenum usage) : m_bufferId(0), m_valid(false), m_size(0), m_usage(usage) +{ + glGenBuffers(1, &m_bufferId); +} + +void VertexBuffer::setData(const std::vector &data) +{ + // Unchecked bind + glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); + // Set data + glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), data.data(), m_usage); + setInactive(); + m_valid = true; +} \ No newline at end of file diff --git a/Engine/Lib/source/graphics/renderer/pass/IRenderPass.cpp b/Engine/Lib/source/graphics/renderer/pass/IRenderPass.cpp new file mode 100644 index 0000000..15e0f2b --- /dev/null +++ b/Engine/Lib/source/graphics/renderer/pass/IRenderPass.cpp @@ -0,0 +1,3 @@ +#include "kern/graphics/renderer/pass/IRenderPass.h" + +IRenderPass::~IRenderPass() {} \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/renderer/pass/CScreenQuadPass.cpp b/Engine/Lib/source/graphics/renderer/pass/ScreenQuadPass.cpp similarity index 63% rename from Graphics/Lib/source/graphics/renderer/pass/CScreenQuadPass.cpp rename to Engine/Lib/source/graphics/renderer/pass/ScreenQuadPass.cpp index 8d8091e..2420a73 100644 --- a/Graphics/Lib/source/graphics/renderer/pass/CScreenQuadPass.cpp +++ b/Engine/Lib/source/graphics/renderer/pass/ScreenQuadPass.cpp @@ -1,31 +1,30 @@ -#include "graphics/graphics/renderer/pass/CScreenQuadPass.h" +#include "kern/graphics/renderer/pass/ScreenQuadPass.h" -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" -CScreenQuadPass::CScreenQuadPass() +ScreenQuadPass::ScreenQuadPass() { std::vector vertices = {0.f, 0.f, 0.f}; std::vector indices = {1}; std::vector normals = {0.f, 1.f, 0.f}; std::vector uvs = {0.f, 0.f, 0.f}; - m_quad.reset(new CMesh(vertices, indices, normals, uvs, EPrimitiveType::Point)); + m_quad.reset(new Mesh(vertices, indices, normals, uvs, PrimitiveType::Point)); } -bool CScreenQuadPass::init(IResourceManager &manager) +bool ScreenQuadPass::init(IResourceManager &manager) { std::string screenQuadShaderFile = "data/shader/compose_screenquad.ini"; m_shaderId = manager.loadShader(screenQuadShaderFile); - if (m_shaderId == invalidResource) + if (m_shaderId == InvalidResource) { - LOG_ERROR("Failed to load screenquad shader %s.", screenQuadShaderFile.c_str()); + loge("Failed to load screenquad shader {}.", screenQuadShaderFile.c_str()); return false; } return true; } -void CScreenQuadPass::draw(CTexture *diffuseGlow, CTexture *lightTexture, CTexture *depthTexture, - const glm::mat4 &inverseViewProj, CFrameBuffer *fbo, - const IGraphicsResourceManager *manager) +void ScreenQuadPass::draw(Texture *diffuseGlow, Texture *lightTexture, Texture *depthTexture, + const glm::mat4 &inverseViewProj, FrameBuffer *fbo, const IGraphicsResourceManager *manager) { m_shader = manager->getShaderProgram(m_shaderId); if (fbo == nullptr) diff --git a/Graphics/Lib/source/graphics/renderer/pass/CScreenSpacePass.cpp b/Engine/Lib/source/graphics/renderer/pass/ScreenSpacePass.cpp similarity index 55% rename from Graphics/Lib/source/graphics/renderer/pass/CScreenSpacePass.cpp rename to Engine/Lib/source/graphics/renderer/pass/ScreenSpacePass.cpp index e8581fb..59e97cd 100644 --- a/Graphics/Lib/source/graphics/renderer/pass/CScreenSpacePass.cpp +++ b/Engine/Lib/source/graphics/renderer/pass/ScreenSpacePass.cpp @@ -1,55 +1,54 @@ -#include "graphics/graphics/renderer/pass/CScreenSpacePass.h" +#include "kern/graphics/renderer/pass/ScreenSpacePass.h" // Debugging -#include +#include // Resource management -#include "graphics/resource/IResourceManager.h" +#include "kern/resource/IResourceManager.h" // Graphics API -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/graphics/renderer/CFrameBuffer.h" -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/resource/CShaderProgram.h" -#include "graphics/graphics/resource/CTexture.h" +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/renderer/FrameBuffer.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/graphics/resource/ShaderProgram.h" +#include "kern/graphics/resource/Texture.h" -CScreenSpacePass::CScreenSpacePass() +ScreenSpacePass::ScreenSpacePass() { std::vector vertices = {0.f, 0.f, 0.f}; std::vector indices = {1}; std::vector normals = {0.f, 1.f, 0.f}; std::vector uvs = {0.f, 0.f, 0.f}; - m_quad.reset(new CMesh(vertices, indices, normals, uvs, EPrimitiveType::Point)); + m_quad.reset(new Mesh(vertices, indices, normals, uvs, PrimitiveType::Point)); } -bool CScreenSpacePass::init(const std::string &shaderFile, IResourceManager *manager) +bool ScreenSpacePass::init(const std::string &shaderFile, IResourceManager *manager) { - LOG_INFO("Initializing screen space pass with shader %s.", shaderFile.c_str()); + logi("Initializing screen space pass with shader {}.", shaderFile.c_str()); m_shaderId = manager->loadShader(shaderFile); - if (m_shaderId == invalidResource) + if (m_shaderId == InvalidResource) { - LOG_ERROR("Failed to initialize the screen space pass from shader %s.", shaderFile.c_str()); + loge("Failed to initialize the screen space pass from shader {}.", shaderFile.c_str()); return false; } return true; } -void CScreenSpacePass::draw(const IGraphicsResourceManager *manager, CFrameBuffer *fbo, - CTexture *texture0, CTexture *texture1, CTexture *texture2, - CTexture *texture3) +void ScreenSpacePass::draw(const IGraphicsResourceManager *manager, FrameBuffer *fbo, Texture *texture0, + Texture *texture1, Texture *texture2, Texture *texture3) { - if (m_shaderId == invalidResource) + if (m_shaderId == InvalidResource) { - LOG_ERROR("The screen space pass shader id is not valid."); + loge("The screen space pass shader id is not valid."); return; } // Fetch shader based on id. // TODO Cache shader and only fetch on change (make listener)? - CShaderProgram *shader = manager->getShaderProgram(m_shaderId); + ShaderProgram *shader = manager->getShaderProgram(m_shaderId); if (shader == nullptr) { - LOG_ERROR("Failed to load screen space pass shader with id %."); + loge("Failed to load screen space pass shader with id {}.", m_shaderId); return; } diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.cpp b/Engine/Lib/source/graphics/renderer/shader/ShaderCommon.cpp similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.cpp rename to Engine/Lib/source/graphics/renderer/shader/ShaderCommon.cpp diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderCommon.h b/Engine/Lib/source/graphics/renderer/shader/ShaderCommon.h similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderCommon.h rename to Engine/Lib/source/graphics/renderer/shader/ShaderCommon.h diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.h b/Engine/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.cpp similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.h rename to Engine/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.cpp diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderPostProcess.cpp b/Engine/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.h similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderPostProcess.cpp rename to Engine/Lib/source/graphics/renderer/shader/ShaderDeferredRenderer.h diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.cpp b/Engine/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.cpp similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.cpp rename to Engine/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.cpp diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.h b/Engine/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.h similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.h rename to Engine/Lib/source/graphics/renderer/shader/ShaderForwardRenderer.h diff --git a/Graphics/Lib/source/graphics/renderer/shader/ShaderPostProcess.h b/Engine/Lib/source/graphics/renderer/shader/ShaderPostProcess.cpp similarity index 100% rename from Graphics/Lib/source/graphics/renderer/shader/ShaderPostProcess.h rename to Engine/Lib/source/graphics/renderer/shader/ShaderPostProcess.cpp diff --git a/Engine/Lib/source/graphics/renderer/shader/ShaderPostProcess.h b/Engine/Lib/source/graphics/renderer/shader/ShaderPostProcess.h new file mode 100644 index 0000000..e69de29 diff --git a/Graphics/Lib/source/graphics/resource/CGraphicsResourceManager.cpp b/Engine/Lib/source/graphics/resource/GraphicsResourceManager.cpp similarity index 60% rename from Graphics/Lib/source/graphics/resource/CGraphicsResourceManager.cpp rename to Engine/Lib/source/graphics/resource/GraphicsResourceManager.cpp index a4f3552..c8b9eb2 100644 --- a/Graphics/Lib/source/graphics/resource/CGraphicsResourceManager.cpp +++ b/Engine/Lib/source/graphics/resource/GraphicsResourceManager.cpp @@ -1,20 +1,20 @@ -#include "graphics/graphics/resource/CGraphicsResourceManager.h" +#include "kern/graphics/resource/GraphicsResourceManager.h" + +#include #include #include -#include - -#include "graphics/resource/IResourceManager.h" +#include "kern/resource/IResourceManager.h" -CGraphicsResourceManager::CGraphicsResourceManager() +GraphicsResourceManager::GraphicsResourceManager() { // Create default textures initDefaultTextures(); return; } -CGraphicsResourceManager::~CGraphicsResourceManager() +GraphicsResourceManager::~GraphicsResourceManager() { // Remove resource listener while (!m_registeredManagers.empty()) @@ -24,7 +24,7 @@ CGraphicsResourceManager::~CGraphicsResourceManager() } } -void CGraphicsResourceManager::onAttach(IResourceManager *resourceManager) +void GraphicsResourceManager::onAttach(IResourceManager *resourceManager) { // Add to known resource managers if (std::find(m_registeredManagers.begin(), m_registeredManagers.end(), resourceManager) == @@ -35,63 +35,63 @@ void CGraphicsResourceManager::onAttach(IResourceManager *resourceManager) return; } -void CGraphicsResourceManager::onDetach(IResourceManager *resourceManager) +void GraphicsResourceManager::onDetach(IResourceManager *resourceManager) { m_registeredManagers.remove(resourceManager); return; } -void CGraphicsResourceManager::notify(EResourceType type, ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::notify(ResourceType type, ResourceId id, ResourceEvent event, + IResourceManager *resourceManager) { // Resolve resource type switch (type) { - case EResourceType::Image: + case ResourceType::Image: handleImageEvent(id, event, resourceManager); break; - case EResourceType::Material: + case ResourceType::Material: handleMaterialEvent(id, event, resourceManager); break; - case EResourceType::Mesh: + case ResourceType::Mesh: handleMeshEvent(id, event, resourceManager); break; - case EResourceType::Shader: + case ResourceType::Shader: handleShaderEvent(id, event, resourceManager); break; - case EResourceType::String: + case ResourceType::String: handleStringEvent(id, event, resourceManager); break; default: - LOG_ERROR("Unknown resource type encountered."); + loge("Unknown resource type encountered."); break; } } -void CGraphicsResourceManager::initDefaultTextures() +void GraphicsResourceManager::initDefaultTextures() { // Default diffuse texture is deep pink to signal errors/missing textures - m_defaultDiffuseTexture.reset(new CTexture({238, 18, 137}, 1, 1, EColorFormat::RGB24, 0)); + m_defaultDiffuseTexture.reset(new Texture({238, 18, 137}, 1, 1, ColorFormat::RGB24, 0)); // Default normal texture with straight/non-perturbed normals // Discussion here: // http://www.gameartisans.org/forums/threads/1985-Normal-Map-RGB-127-127-255-or-128-128-255 - m_defaultNormalTexture.reset(new CTexture({128, 128, 255}, 1, 1, EColorFormat::RGB24, 0)); + m_defaultNormalTexture.reset(new Texture({128, 128, 255}, 1, 1, ColorFormat::RGB24, 0)); // Default specular texture is black (no specular highlights) - m_defaultSpecularTexture.reset(new CTexture({0}, 1, 1, EColorFormat::GreyScale8)); + m_defaultSpecularTexture.reset(new Texture({0}, 1, 1, ColorFormat::GreyScale8)); // Default glow texture is black (no glow) - m_defaultGlowTexture.reset(new CTexture({0}, 1, 1, EColorFormat::GreyScale8)); + m_defaultGlowTexture.reset(new Texture({0}, 1, 1, ColorFormat::GreyScale8)); // Default alpha texture is white (completely opaque) - m_defaultAlphaTexture.reset(new CTexture({255}, 1, 1, EColorFormat::GreyScale8)); + m_defaultAlphaTexture.reset(new Texture({255}, 1, 1, ColorFormat::GreyScale8)); } -CMesh *CGraphicsResourceManager::getMesh(ResourceId id) const +Mesh *GraphicsResourceManager::getMesh(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -104,10 +104,10 @@ CMesh *CGraphicsResourceManager::getMesh(ResourceId id) const return iter->second.get(); } -CMaterial *CGraphicsResourceManager::getMaterial(ResourceId id) const +Material *GraphicsResourceManager::getMaterial(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -120,10 +120,10 @@ CMaterial *CGraphicsResourceManager::getMaterial(ResourceId id) const return iter->second.get(); } -CModel *CGraphicsResourceManager::getModel(ResourceId id) const +Model *GraphicsResourceManager::getModel(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -136,10 +136,10 @@ CModel *CGraphicsResourceManager::getModel(ResourceId id) const return iter->second.get(); } -CTexture *CGraphicsResourceManager::getTexture(ResourceId id) const +Texture *GraphicsResourceManager::getTexture(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -152,10 +152,10 @@ CTexture *CGraphicsResourceManager::getTexture(ResourceId id) const return iter->second.get(); } -CShaderProgram *CGraphicsResourceManager::getShaderProgram(ResourceId id) const +ShaderProgram *GraphicsResourceManager::getShaderProgram(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -166,42 +166,26 @@ CShaderProgram *CGraphicsResourceManager::getShaderProgram(ResourceId id) const // TODO Allow shader loading if not found? if (iter == m_shaderPrograms.end()) { - LOG_ERROR("The requested shader program id %i has not been loaded.", id); + loge("The requested shader program id {} has not been loaded.", id); return nullptr; } return iter->second.get(); } -CTexture *CGraphicsResourceManager::getDefaultDiffuseTexture() const -{ - return m_defaultDiffuseTexture.get(); -} +Texture *GraphicsResourceManager::getDefaultDiffuseTexture() const { return m_defaultDiffuseTexture.get(); } -CTexture *CGraphicsResourceManager::getDefaultNormalTexture() const -{ - return m_defaultNormalTexture.get(); -} +Texture *GraphicsResourceManager::getDefaultNormalTexture() const { return m_defaultNormalTexture.get(); } -CTexture *CGraphicsResourceManager::getDefaultSpecularTexture() const -{ - return m_defaultSpecularTexture.get(); -} +Texture *GraphicsResourceManager::getDefaultSpecularTexture() const { return m_defaultSpecularTexture.get(); } -CTexture *CGraphicsResourceManager::getDefaultGlowTexture() const -{ - return m_defaultGlowTexture.get(); -} +Texture *GraphicsResourceManager::getDefaultGlowTexture() const { return m_defaultGlowTexture.get(); } -CTexture *CGraphicsResourceManager::getDefaultAlphaTexture() const -{ - return m_defaultAlphaTexture.get(); -} +Texture *GraphicsResourceManager::getDefaultAlphaTexture() const { return m_defaultAlphaTexture.get(); } -TShaderObject *CGraphicsResourceManager::getVertexShaderObject( - ResourceId id) const +TShaderObject *GraphicsResourceManager::getVertexShaderObject(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -214,11 +198,10 @@ TShaderObject *CGraphicsResourceManager::getVertexShaderObject return iter->second.get(); } -TShaderObject *CGraphicsResourceManager::getTessControlShaderObject( - ResourceId id) const +TShaderObject *GraphicsResourceManager::getTessControlShaderObject(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -231,11 +214,10 @@ TShaderObject *CGraphicsResourceManager::getTessControlS return iter->second.get(); } -TShaderObject *CGraphicsResourceManager::getTessEvalShaderObject( - ResourceId id) const +TShaderObject *GraphicsResourceManager::getTessEvalShaderObject(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -248,11 +230,10 @@ TShaderObject *CGraphicsResourceManager::getTessEvalS return iter->second.get(); } -TShaderObject *CGraphicsResourceManager::getGeometryShaderObject( - ResourceId id) const +TShaderObject *GraphicsResourceManager::getGeometryShaderObject(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -265,11 +246,10 @@ TShaderObject *CGraphicsResourceManager::getGeometryShaderOb return iter->second.get(); } -TShaderObject *CGraphicsResourceManager::getFragmentShaderObject( - ResourceId id) const +TShaderObject *GraphicsResourceManager::getFragmentShaderObject(ResourceId id) const { // Invalid id - if (id == invalidResource) + if (id == InvalidResource) { return nullptr; } @@ -282,10 +262,10 @@ TShaderObject *CGraphicsResourceManager::getFragmentShaderOb return iter->second.get(); } -bool CGraphicsResourceManager::loadVertexShader(ResourceId id, IResourceManager *resourceManager) +bool GraphicsResourceManager::loadVertexShader(ResourceId id, IResourceManager *resourceManager) { // Unused id - if (id == invalidResource) + if (id == InvalidResource) { return true; } @@ -301,12 +281,11 @@ bool CGraphicsResourceManager::loadVertexShader(ResourceId id, IResourceManager { return false; } - std::unique_ptr> shader( - new TShaderObject(text)); + std::unique_ptr> shader(new TShaderObject(text)); // Check compile error if (!shader->isValid()) { - LOG_ERROR("%s", shader->getErrorString().c_str()); + loge("{}", shader->getErrorString().c_str()); return false; } // Move to map @@ -314,11 +293,10 @@ bool CGraphicsResourceManager::loadVertexShader(ResourceId id, IResourceManager return true; } -bool CGraphicsResourceManager::loadTessControlShader(ResourceId id, - IResourceManager *resourceManager) +bool GraphicsResourceManager::loadTessControlShader(ResourceId id, IResourceManager *resourceManager) { // Unused id - if (id == invalidResource) + if (id == InvalidResource) { return true; } @@ -334,12 +312,11 @@ bool CGraphicsResourceManager::loadTessControlShader(ResourceId id, { return false; } - std::unique_ptr> shader( - new TShaderObject(text)); + std::unique_ptr> shader(new TShaderObject(text)); // Check compile error if (!shader->isValid()) { - LOG_ERROR("%s", shader->getErrorString().c_str()); + loge("{}", shader->getErrorString().c_str()); return false; } // Move to map @@ -347,10 +324,10 @@ bool CGraphicsResourceManager::loadTessControlShader(ResourceId id, return true; } -bool CGraphicsResourceManager::loadTessEvalShader(ResourceId id, IResourceManager *resourceManager) +bool GraphicsResourceManager::loadTessEvalShader(ResourceId id, IResourceManager *resourceManager) { // Unused id - if (id == invalidResource) + if (id == InvalidResource) { return true; } @@ -371,7 +348,7 @@ bool CGraphicsResourceManager::loadTessEvalShader(ResourceId id, IResourceManage // Check compile error if (!shader->isValid()) { - LOG_ERROR("%s", shader->getErrorString().c_str()); + loge("{}", shader->getErrorString().c_str()); return false; } // Move to map @@ -379,10 +356,10 @@ bool CGraphicsResourceManager::loadTessEvalShader(ResourceId id, IResourceManage return true; } -bool CGraphicsResourceManager::loadGeometryShader(ResourceId id, IResourceManager *resourceManager) +bool GraphicsResourceManager::loadGeometryShader(ResourceId id, IResourceManager *resourceManager) { // Unused id - if (id == invalidResource) + if (id == InvalidResource) { return true; } @@ -398,12 +375,11 @@ bool CGraphicsResourceManager::loadGeometryShader(ResourceId id, IResourceManage { return false; } - std::unique_ptr> shader( - new TShaderObject(text)); + std::unique_ptr> shader(new TShaderObject(text)); // Check compile error if (!shader->isValid()) { - LOG_ERROR("%s", shader->getErrorString().c_str()); + loge("{}", shader->getErrorString().c_str()); return false; } // Move to map @@ -411,10 +387,10 @@ bool CGraphicsResourceManager::loadGeometryShader(ResourceId id, IResourceManage return true; } -bool CGraphicsResourceManager::loadFragmentShader(ResourceId id, IResourceManager *resourceManager) +bool GraphicsResourceManager::loadFragmentShader(ResourceId id, IResourceManager *resourceManager) { // Unused id - if (id == invalidResource) + if (id == InvalidResource) { return true; } @@ -430,12 +406,11 @@ bool CGraphicsResourceManager::loadFragmentShader(ResourceId id, IResourceManage { return false; } - std::unique_ptr> shader( - new TShaderObject(text)); + std::unique_ptr> shader(new TShaderObject(text)); // Check compile error if (!shader->isValid()) { - LOG_ERROR("%s", shader->getErrorString().c_str()); + loge("{}", shader->getErrorString().c_str()); return false; } // Move to map @@ -443,17 +418,16 @@ bool CGraphicsResourceManager::loadFragmentShader(ResourceId id, IResourceManage return true; } -void CGraphicsResourceManager::handleImageEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleImageEvent(ResourceId id, ResourceEvent event, IResourceManager *resourceManager) { std::vector data; unsigned int width; unsigned int height; - EColorFormat format; + ColorFormat format; switch (event) { - case EListenerEvent::Create: + case ResourceEvent::Create: assert(m_textures.count(id) == 0 && "Texture id already exists"); if (!resourceManager->getImage(id, data, width, height, format)) @@ -461,11 +435,10 @@ void CGraphicsResourceManager::handleImageEvent(ResourceId id, EListenerEvent ev assert(false && "Failed to access image resource"); } // Create new texture - m_textures[id] = - std::move(std::unique_ptr(new CTexture(data, width, height, format))); + m_textures[id] = std::move(std::unique_ptr(new Texture(data, width, height, format))); break; - case EListenerEvent::Change: + case ResourceEvent::Change: assert(m_textures.count(id) == 1 && "Texture id does not exist"); if (!resourceManager->getImage(id, data, width, height, format)) @@ -476,7 +449,7 @@ void CGraphicsResourceManager::handleImageEvent(ResourceId id, EListenerEvent ev m_textures.at(id)->init(data, width, height, format); break; - case EListenerEvent::Delete: + case ResourceEvent::Delete: // Keep texture? break; @@ -485,18 +458,17 @@ void CGraphicsResourceManager::handleImageEvent(ResourceId id, EListenerEvent ev } } -void CGraphicsResourceManager::handleMeshEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleMeshEvent(ResourceId id, ResourceEvent event, IResourceManager *resourceManager) { std::vector vertices; std::vector indices; std::vector normals; std::vector uvs; - EPrimitiveType type; + PrimitiveType type; switch (event) { - case EListenerEvent::Create: + case ResourceEvent::Create: assert(m_meshes.count(id) == 0 && "Mesh id already exists"); if (!resourceManager->getMesh(id, vertices, indices, normals, uvs, type)) @@ -504,11 +476,10 @@ void CGraphicsResourceManager::handleMeshEvent(ResourceId id, EListenerEvent eve assert(false && "Failed to access mesh resource"); } // Create new texture - m_meshes[id] = - std::move(std::unique_ptr(new CMesh(vertices, indices, normals, uvs, type))); + m_meshes[id] = std::move(std::unique_ptr(new Mesh(vertices, indices, normals, uvs, type))); break; - case EListenerEvent::Change: + case ResourceEvent::Change: assert(m_meshes.count(id) == 1 && "Mesh id does not exist"); if (!resourceManager->getMesh(id, vertices, indices, normals, uvs, type)) @@ -519,7 +490,7 @@ void CGraphicsResourceManager::handleMeshEvent(ResourceId id, EListenerEvent eve m_meshes.at(id)->init(vertices, indices, normals, uvs, type); break; - case EListenerEvent::Delete: + case ResourceEvent::Delete: // Keep mesh? break; @@ -528,8 +499,8 @@ void CGraphicsResourceManager::handleMeshEvent(ResourceId id, EListenerEvent eve } } -void CGraphicsResourceManager::handleMaterialEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleMaterialEvent(ResourceId id, ResourceEvent event, + IResourceManager *resourceManager) { ResourceId diffuse; ResourceId normal; @@ -539,7 +510,7 @@ void CGraphicsResourceManager::handleMaterialEvent(ResourceId id, EListenerEvent switch (event) { - case EListenerEvent::Create: + case ResourceEvent::Create: assert(m_materials.count(id) == 0 && "Material id already exists"); if (!resourceManager->getMaterial(id, diffuse, normal, specular, glow, alpha)) @@ -549,12 +520,11 @@ void CGraphicsResourceManager::handleMaterialEvent(ResourceId id, EListenerEvent } // Create new material - m_materials[id] = std::move(std::unique_ptr( - new CMaterial(getTexture(diffuse), getTexture(normal), getTexture(specular), - getTexture(glow), getTexture(alpha)))); + m_materials[id] = std::move(std::unique_ptr(new Material( + getTexture(diffuse), getTexture(normal), getTexture(specular), getTexture(glow), getTexture(alpha)))); break; - case EListenerEvent::Change: + case ResourceEvent::Change: assert(m_materials.count(id) == 1 && "Material id does not exist"); if (!resourceManager->getMaterial(id, diffuse, normal, specular, glow, alpha)) @@ -564,11 +534,11 @@ void CGraphicsResourceManager::handleMaterialEvent(ResourceId id, EListenerEvent } // Reinitialize material on change - m_materials.at(id)->init(getTexture(diffuse), getTexture(normal), getTexture(specular), - getTexture(glow), getTexture(alpha)); + m_materials.at(id)->init(getTexture(diffuse), getTexture(normal), getTexture(specular), getTexture(glow), + getTexture(alpha)); break; - case EListenerEvent::Delete: + case ResourceEvent::Delete: // Keep material? break; @@ -577,15 +547,14 @@ void CGraphicsResourceManager::handleMaterialEvent(ResourceId id, EListenerEvent } } -void CGraphicsResourceManager::handleModelEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleModelEvent(ResourceId id, ResourceEvent event, IResourceManager *resourceManager) { ResourceId mesh; ResourceId material; switch (event) { - case EListenerEvent::Create: + case ResourceEvent::Create: assert(m_models.count(id) == 0 && "Model id already exists"); if (!resourceManager->getModel(id, mesh, material)) @@ -595,11 +564,10 @@ void CGraphicsResourceManager::handleModelEvent(ResourceId id, EListenerEvent ev } // Create new model - m_models[id] = - std::move(std::unique_ptr(new CModel(getMesh(mesh), getMaterial(material)))); + m_models[id] = std::move(std::unique_ptr(new Model(getMesh(mesh), getMaterial(material)))); break; - case EListenerEvent::Change: + case ResourceEvent::Change: assert(m_models.count(id) == 1 && "Model id does not exist"); if (!resourceManager->getModel(id, mesh, material)) @@ -612,7 +580,7 @@ void CGraphicsResourceManager::handleModelEvent(ResourceId id, EListenerEvent ev m_models.at(id)->init(getMesh(mesh), getMaterial(material)); break; - case EListenerEvent::Delete: + case ResourceEvent::Delete: // Keep model? break; @@ -621,8 +589,7 @@ void CGraphicsResourceManager::handleModelEvent(ResourceId id, EListenerEvent ev } } -void CGraphicsResourceManager::handleShaderEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleShaderEvent(ResourceId id, ResourceEvent event, IResourceManager *resourceManager) { ResourceId vertex; ResourceId tessControl; @@ -632,7 +599,7 @@ void CGraphicsResourceManager::handleShaderEvent(ResourceId id, EListenerEvent e switch (event) { - case EListenerEvent::Create: + case ResourceEvent::Create: // TODO Replace assert with log statement and global error handler assert(m_shaderPrograms.count(id) == 0 && "Shader id already exists"); @@ -644,10 +611,8 @@ void CGraphicsResourceManager::handleShaderEvent(ResourceId id, EListenerEvent e } // Load shader objects from source - if (!loadVertexShader(vertex, resourceManager) || - !loadTessControlShader(tessControl, resourceManager) || - !loadTessEvalShader(tessEval, resourceManager) || - !loadGeometryShader(geometry, resourceManager) || + if (!loadVertexShader(vertex, resourceManager) || !loadTessControlShader(tessControl, resourceManager) || + !loadTessEvalShader(tessEval, resourceManager) || !loadGeometryShader(geometry, resourceManager) || !loadFragmentShader(fragment, resourceManager)) { // TODO Log error @@ -655,17 +620,16 @@ void CGraphicsResourceManager::handleShaderEvent(ResourceId id, EListenerEvent e } // Add create shader program - m_shaderPrograms[id] = std::move(std::unique_ptr(new CShaderProgram( - getVertexShaderObject(vertex), getTessControlShaderObject(tessControl), - getTessEvalShaderObject(tessEval), getGeometryShaderObject(geometry), - getFragmentShaderObject(fragment)))); + m_shaderPrograms[id] = std::move(std::unique_ptr(new ShaderProgram( + getVertexShaderObject(vertex), getTessControlShaderObject(tessControl), getTessEvalShaderObject(tessEval), + getGeometryShaderObject(geometry), getFragmentShaderObject(fragment)))); break; - case EListenerEvent::Change: + case ResourceEvent::Change: // TODO Implement - case EListenerEvent::Delete: + case ResourceEvent::Delete: // TODO Keep shader? break; @@ -675,8 +639,7 @@ void CGraphicsResourceManager::handleShaderEvent(ResourceId id, EListenerEvent e } } -void CGraphicsResourceManager::handleStringEvent(ResourceId id, EListenerEvent event, - IResourceManager *resourceManager) +void GraphicsResourceManager::handleStringEvent(ResourceId id, ResourceEvent event, IResourceManager *resourceManager) { // Does not need processing, shader events handle source loading } diff --git a/Engine/Lib/source/graphics/resource/Material.cpp b/Engine/Lib/source/graphics/resource/Material.cpp new file mode 100644 index 0000000..9f9e1bf --- /dev/null +++ b/Engine/Lib/source/graphics/resource/Material.cpp @@ -0,0 +1,73 @@ +#include "kern/graphics/resource/Material.h" + +#include + +Material::Material(const Texture *diffuse, const Texture *normal, const Texture *specular, + const Texture *glow, const Texture *alpha) + : m_diffuseTexture(nullptr), + m_normalTexture(nullptr), + m_specularTexture(nullptr), + m_glowTexture(nullptr), + m_alphaTexture(nullptr) +{ + init(diffuse, normal, specular, glow, alpha); +} + +bool Material::init(const Texture *diffuse, const Texture *normal, const Texture *specular, + const Texture *glow, const Texture *alpha) +{ + // Textures must either be nullptr (unused) or valid + if (diffuse != nullptr && !diffuse->isValid()) + { + loge("Diffuse texture is not valid."); + return false; + } + if (normal != nullptr && !normal->isValid()) + { + loge("Normal texture is not valid."); + return false; + } + if (specular != nullptr && !specular->isValid()) + { + loge("Specular texture is not valid."); + return false; + } + if (glow != nullptr && !glow->isValid()) + { + loge("Glow texture is not valid."); + return false; + } + if (alpha != nullptr && !alpha->isValid()) + { + loge("Alpha texture is not valid."); + return false; + } + + // All checks ok, set values + m_diffuseTexture = diffuse; + m_normalTexture = normal; + m_specularTexture = specular; + m_glowTexture = glow; + m_alphaTexture = alpha; + return true; +} + +bool Material::hasDiffuse() const { return m_diffuseTexture != nullptr; } + +bool Material::hasNormal() const { return m_normalTexture != nullptr; } + +bool Material::hasSpecular() const { return m_specularTexture != nullptr; } + +bool Material::hasGlow() const { return m_glowTexture != nullptr; } + +bool Material::hasAlpha() const { return m_alphaTexture != nullptr; } + +const Texture *Material::getDiffuse() const { return m_diffuseTexture; } + +const Texture *Material::getNormal() const { return m_normalTexture; } + +const Texture *Material::getSpecular() const { return m_specularTexture; } + +const Texture *Material::getGlow() const { return m_glowTexture; } + +const Texture *Material::getAlpha() const { return m_alphaTexture; } \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/resource/CMesh.cpp b/Engine/Lib/source/graphics/resource/Mesh.cpp similarity index 53% rename from Graphics/Lib/source/graphics/resource/CMesh.cpp rename to Engine/Lib/source/graphics/resource/Mesh.cpp index 4c58ed7..fd859c4 100644 --- a/Graphics/Lib/source/graphics/resource/CMesh.cpp +++ b/Engine/Lib/source/graphics/resource/Mesh.cpp @@ -1,57 +1,56 @@ -#include "graphics/graphics/resource/CMesh.h" +#include "kern/graphics/resource/Mesh.h" #include -#include +#include -#include "graphics/graphics/renderer/core/RendererCoreConfig.h" -#include "graphics/graphics/renderer/debug/RendererDebug.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" -CMesh::CMesh(const std::vector &vertices, const std::vector &indices, - const std::vector &normals, const std::vector &uvs, EPrimitiveType type) +Mesh::Mesh(const std::vector &vertices, const std::vector &indices, + const std::vector &normals, const std::vector &uvs, PrimitiveType type) : m_vertices(nullptr), m_indices(nullptr), m_normals(nullptr), m_uvs(nullptr), m_vao(nullptr), - m_type(EPrimitiveType::Invalid) + m_type(PrimitiveType::Invalid) { init(vertices, indices, normals, uvs, type); } -CMesh::~CMesh() { return; } +Mesh::~Mesh() { return; } -bool CMesh::init(const std::vector &vertices, const std::vector &indices, +bool Mesh::init(const std::vector &vertices, const std::vector &indices, const std::vector &normals, const std::vector &uvs, - EPrimitiveType type) + PrimitiveType type) { - if (vertices.empty() || type == EPrimitiveType::Invalid) + if (vertices.empty() || type == PrimitiveType::Invalid) { return false; } // Set vertex data - m_vertices.reset(new CVertexBuffer(vertices)); + m_vertices.reset(new VertexBuffer(vertices)); if (!indices.empty()) { // Set indices - m_indices.reset(new CIndexBuffer(indices)); + m_indices.reset(new IndexBuffer(indices)); } if (!normals.empty()) { // Set normals - m_normals.reset(new CVertexBuffer(normals)); + m_normals.reset(new VertexBuffer(normals)); } if (!uvs.empty()) { // Set uvs - m_uvs.reset(new CVertexBuffer(uvs)); + m_uvs.reset(new VertexBuffer(uvs)); } // Create new vertex array object to store buffer state - m_vao.reset(new CVertexArrayObject); + m_vao.reset(new VertexArrayObject); // Set primitive type m_type = type; @@ -99,70 +98,65 @@ bool CMesh::init(const std::vector &vertices, const std::vectorsetInactive(); - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } - // Build bounding sphere - m_boundingSphere = CBoundingSphere::create(vertices); + m_boundingSphere = BoundingSphere::create(vertices); return true; } -bool CMesh::hasIndexBuffer() const { return m_indices != nullptr; } +bool Mesh::hasIndexBuffer() const { return m_indices != nullptr; } -const std::unique_ptr &CMesh::getVertexBuffer() const { return m_vertices; } +const std::unique_ptr &Mesh::getVertexBuffer() const { return m_vertices; } -const std::unique_ptr &CMesh::getIndexBuffer() const { return m_indices; } +const std::unique_ptr &Mesh::getIndexBuffer() const { return m_indices; } -const std::unique_ptr &CMesh::getNormalBuffer() const { return m_normals; } +const std::unique_ptr &Mesh::getNormalBuffer() const { return m_normals; } -const std::unique_ptr &CMesh::getUVBuffer() const { return m_uvs; } +const std::unique_ptr &Mesh::getUVBuffer() const { return m_uvs; } -const EPrimitiveType CMesh::getPrimitiveType() const { return m_type; } +const PrimitiveType Mesh::getPrimitiveType() const { return m_type; } -const std::unique_ptr &CMesh::getVertexArray() const { return m_vao; } +const std::unique_ptr &Mesh::getVertexArray() const { + return m_vao; +} -const CBoundingSphere &CMesh::getBoundingSphere() const { return m_boundingSphere; } +const BoundingSphere &Mesh::getBoundingSphere() const { return m_boundingSphere; } -GLenum CMesh::toGLPrimitive(EPrimitiveType type) +GLenum Mesh::toGLPrimitive(PrimitiveType type) { switch (type) { - case EPrimitiveType::Point: + case PrimitiveType::Point: return GL_POINTS; break; - case EPrimitiveType::Line: + case PrimitiveType::Line: return GL_LINE; break; - case EPrimitiveType::Triangle: + case PrimitiveType::Triangle: return GL_TRIANGLES; break; default: - LOG_ERROR("Invalid or unknown primitive type, default triangle type used."); + loge("Invalid or unknown primitive type, default triangle type used."); // Default return GL_TRIANGLES; } } -unsigned int CMesh::getPrimitiveSize(EPrimitiveType type) +unsigned int Mesh::getPrimitiveSize(PrimitiveType type) { switch (type) { - case EPrimitiveType::Point: + case PrimitiveType::Point: return 1; break; - case EPrimitiveType::Line: + case PrimitiveType::Line: return 2; break; - case EPrimitiveType::Triangle: + case PrimitiveType::Triangle: return 3; break; default: - LOG_ERROR("Invalid or unknown primitive type"); + loge("Invalid or unknown primitive type"); return 0; } } diff --git a/Engine/Lib/source/graphics/resource/Model.cpp b/Engine/Lib/source/graphics/resource/Model.cpp new file mode 100644 index 0000000..ab587b3 --- /dev/null +++ b/Engine/Lib/source/graphics/resource/Model.cpp @@ -0,0 +1,25 @@ +#include "kern/graphics/resource/Model.h" + +Model::Model(const Mesh *mesh, const Material *material) : m_mesh(mesh), m_material(material) +{ + return; +} + +bool Model::init(const Mesh *mesh, const Material *material) +{ + if (mesh == nullptr || material == nullptr) + { + return false; + } + m_mesh = mesh; + m_material = material; + return true; +} + +bool Model::hasMesh() const { return m_mesh != nullptr; } + +bool Model::hasMaterial() const { return m_material != nullptr; } + +const Mesh *Model::getMesh() const { return m_mesh; } + +const Material *Model::getMaterial() const { return m_material; } \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/resource/CShaderProgram.cpp b/Engine/Lib/source/graphics/resource/ShaderProgram.cpp similarity index 61% rename from Graphics/Lib/source/graphics/resource/CShaderProgram.cpp rename to Engine/Lib/source/graphics/resource/ShaderProgram.cpp index 7508b6d..166e08a 100644 --- a/Graphics/Lib/source/graphics/resource/CShaderProgram.cpp +++ b/Engine/Lib/source/graphics/resource/ShaderProgram.cpp @@ -1,27 +1,24 @@ -#include "graphics/graphics/resource/CShaderProgram.h" +#include "kern/graphics/resource/ShaderProgram.h" -#include +#include +#include #include -#include - -#include "graphics/graphics/renderer/debug/RendererDebug.h" -#include "graphics/graphics/resource/CTexture.h" +#include "kern/graphics/resource/Texture.h" -GLuint CShaderProgram::s_activeShaderProgram = 0; +GLuint ShaderProgram::s_activeShaderProgram = 0; -CShaderProgram::CShaderProgram(TShaderObject *vertex, - TShaderObject *tessControl, - TShaderObject *tessEval, - TShaderObject *geometry, - TShaderObject *fragment) +ShaderProgram::ShaderProgram(TShaderObject *vertex, + TShaderObject *tessControl, + TShaderObject *tessEval, + TShaderObject *geometry, TShaderObject *fragment) : m_programId(0), m_valid(false) { init(vertex, tessControl, tessEval, geometry, fragment); } -CShaderProgram::~CShaderProgram() +ShaderProgram::~ShaderProgram() { if (m_valid) { @@ -29,11 +26,9 @@ CShaderProgram::~CShaderProgram() } } -bool CShaderProgram::init(TShaderObject *vertex, - TShaderObject *tessControl, - TShaderObject *tessEval, - TShaderObject *geometry, - TShaderObject *fragment) +bool ShaderProgram::init(TShaderObject *vertex, TShaderObject *tessControl, + TShaderObject *tessEval, + TShaderObject *geometry, TShaderObject *fragment) { // Needs vertex shader if (vertex == nullptr || !vertex->isValid()) @@ -117,17 +112,10 @@ bool CShaderProgram::init(TShaderObject *vertex, // Clear uniform location cache m_uniformLocations.clear(); - // Error check - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - } - return true; } -void CShaderProgram::setActive() +void ShaderProgram::setActive() { assert(isValid()); if (s_activeShaderProgram != m_programId) @@ -137,7 +125,7 @@ void CShaderProgram::setActive() } } -void CShaderProgram::setInactive() +void ShaderProgram::setInactive() { assert(isValid()); if (s_activeShaderProgram == m_programId) @@ -147,11 +135,11 @@ void CShaderProgram::setInactive() } } -const std::string &CShaderProgram::getErrorString() const { return m_infoLog; } +const std::string &ShaderProgram::getErrorString() const { return m_infoLog; } -bool CShaderProgram::isValid() const { return m_valid; } +bool ShaderProgram::isValid() const { return m_valid; } -GLint CShaderProgram::getUniformLocation(const std::string &uniformName) const +GLint ShaderProgram::getUniformLocation(const std::string &uniformName) const { // Search for cached location auto iter = m_uniformLocations.find(uniformName); @@ -163,8 +151,7 @@ GLint CShaderProgram::getUniformLocation(const std::string &uniformName) const // Invalid location, uniform name does not exist in shader if (location == -1) { - LOG_ERROR("Failed to retrieve uniform name %s from shader program.", - uniformName.c_str()); + loge("Failed to retrieve uniform name {} from shader program.", uniformName.c_str()); } m_uniformLocations[uniformName] = location; return location; @@ -173,12 +160,12 @@ GLint CShaderProgram::getUniformLocation(const std::string &uniformName) const return iter->second; } -GLint CShaderProgram::getAttributeLocation(const std::string &attributeName) const +GLint ShaderProgram::getAttributeLocation(const std::string &attributeName) const { return glGetAttribLocation(m_programId, attributeName.data()); } -bool CShaderProgram::setUniform(GLint location, int i) +bool ShaderProgram::setUniform(GLint location, int i) { if (location == -1) { @@ -189,12 +176,9 @@ bool CShaderProgram::setUniform(GLint location, int i) return true; } -bool CShaderProgram::setUniform(const std::string &name, int i) -{ - return setUniform(getUniformLocation(name), i); -} +bool ShaderProgram::setUniform(const std::string &name, int i) { return setUniform(getUniformLocation(name), i); } -bool CShaderProgram::setUniform(GLint location, float f) +bool ShaderProgram::setUniform(GLint location, float f) { if (location == -1) { @@ -205,12 +189,9 @@ bool CShaderProgram::setUniform(GLint location, float f) return true; } -bool CShaderProgram::setUniform(const std::string &name, float f) -{ - return setUniform(getUniformLocation(name), f); -} +bool ShaderProgram::setUniform(const std::string &name, float f) { return setUniform(getUniformLocation(name), f); } -bool CShaderProgram::setUniform(GLint location, const glm::vec2 &v) +bool ShaderProgram::setUniform(GLint location, const glm::vec2 &v) { if (location == -1) { @@ -221,12 +202,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::vec2 &v) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::vec2 &v) +bool ShaderProgram::setUniform(const std::string &name, const glm::vec2 &v) { return setUniform(getUniformLocation(name), v); } -bool CShaderProgram::setUniform(GLint location, const glm::vec3 &v) +bool ShaderProgram::setUniform(GLint location, const glm::vec3 &v) { if (location == -1) { @@ -237,12 +218,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::vec3 &v) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::vec3 &v) +bool ShaderProgram::setUniform(const std::string &name, const glm::vec3 &v) { return setUniform(getUniformLocation(name), v); } -bool CShaderProgram::setUniform(GLint location, const glm::vec4 &v) +bool ShaderProgram::setUniform(GLint location, const glm::vec4 &v) { if (location == -1) { @@ -253,12 +234,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::vec4 &v) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::vec4 &v) +bool ShaderProgram::setUniform(const std::string &name, const glm::vec4 &v) { return setUniform(getUniformLocation(name), v); } -bool CShaderProgram::setUniform(GLint location, const glm::mat2 &m) +bool ShaderProgram::setUniform(GLint location, const glm::mat2 &m) { if (location == -1) { @@ -269,12 +250,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::mat2 &m) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::mat2 &m) +bool ShaderProgram::setUniform(const std::string &name, const glm::mat2 &m) { return setUniform(getUniformLocation(name), m); } -bool CShaderProgram::setUniform(GLint location, const glm::mat3 &m) +bool ShaderProgram::setUniform(GLint location, const glm::mat3 &m) { if (location == -1) { @@ -285,12 +266,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::mat3 &m) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::mat3 &m) +bool ShaderProgram::setUniform(const std::string &name, const glm::mat3 &m) { return setUniform(getUniformLocation(name), m); } -bool CShaderProgram::setUniform(GLint location, const glm::mat4 &m) +bool ShaderProgram::setUniform(GLint location, const glm::mat4 &m) { if (location == -1) { @@ -301,13 +282,12 @@ bool CShaderProgram::setUniform(GLint location, const glm::mat4 &m) return true; } -bool CShaderProgram::setUniform(const std::string &name, const glm::mat4 &m) +bool ShaderProgram::setUniform(const std::string &name, const glm::mat4 &m) { return setUniform(getUniformLocation(name), m); } -bool CShaderProgram::setUniform(CTexture &texture, const std::string &textureName, - GLint textureUnit) +bool ShaderProgram::setUniform(Texture &texture, const std::string &textureName, GLint textureUnit) { texture.setActive(textureUnit); return setUniform(textureName, textureUnit); diff --git a/Graphics/Lib/source/graphics/resource/CTexture.cpp b/Engine/Lib/source/graphics/resource/Texture.cpp similarity index 55% rename from Graphics/Lib/source/graphics/resource/CTexture.cpp rename to Engine/Lib/source/graphics/resource/Texture.cpp index c77e578..1998ce8 100644 --- a/Graphics/Lib/source/graphics/resource/CTexture.cpp +++ b/Engine/Lib/source/graphics/resource/Texture.cpp @@ -1,40 +1,38 @@ -#include "graphics/graphics/resource/CTexture.h" +#include "kern/graphics/resource/Texture.h" #include #include -#include +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include +#include -#include - -#include "graphics/graphics/renderer/debug/RendererDebug.h" - -CTexture::CTexture() +Texture::Texture() { // empty } -CTexture::CTexture(const std::vector &image, unsigned int width, unsigned int height, - EColorFormat format, bool createMipmaps) +Texture::Texture(const std::vector &image, unsigned int width, unsigned int height, ColorFormat format, + bool createMipmaps) { // Init texture with data if (!init(image, width, height, format, createMipmaps)) { - LOG_ERROR("Failed to initialize texture."); + loge("Failed to initialize texture."); } } -CTexture::CTexture(unsigned int width, unsigned int height, EColorFormat format, bool createMipmaps) +Texture::Texture(unsigned int width, unsigned int height, ColorFormat format, bool createMipmaps) { // Init texture with data if (!init({}, width, height, format, createMipmaps)) { - LOG_ERROR("Failed to initialize texture."); + loge("Failed to initialize texture."); } } -CTexture::CTexture(GLint id, bool hasMipmaps, unsigned int width, unsigned int height, GLint format, - GLenum externalFormat) +Texture::Texture(GLuint id, bool hasMipmaps, unsigned int width, unsigned int height, GLint format, + GLenum externalFormat) { m_valid = true; m_hasMipmaps = hasMipmaps; @@ -45,7 +43,7 @@ CTexture::CTexture(GLint id, bool hasMipmaps, unsigned int width, unsigned int h m_externalFormat = externalFormat; } -CTexture::~CTexture() +Texture::~Texture() { if (m_valid) { @@ -53,20 +51,20 @@ CTexture::~CTexture() } } -bool CTexture::init(const std::vector &image, unsigned int width, - unsigned int height, EColorFormat format, bool createMipmaps) +bool Texture::init(const std::vector &image, unsigned int width, unsigned int height, ColorFormat format, + bool createMipmaps) { // Set format GLint internalFormat; switch (format) { - case EColorFormat::GreyScale8: + case ColorFormat::GreyScale8: internalFormat = GL_R8; break; - case EColorFormat::RGB24: + case ColorFormat::RGB24: internalFormat = GL_RGB8; break; - case EColorFormat::RGBA32: + case ColorFormat::RGBA32: internalFormat = GL_RGBA8; break; default: @@ -76,47 +74,49 @@ bool CTexture::init(const std::vector &image, unsigned int width, return init(image, width, height, internalFormat, createMipmaps); } -bool CTexture::init(unsigned int width, unsigned int height, GLint format) +bool Texture::init(unsigned int width, unsigned int height, GLint format) { return init({}, width, height, format, false); } -void CTexture::resize(unsigned int width, unsigned int height) +void Texture::resize(unsigned int width, unsigned int height) { + // TODO Remove resizing functionality if (m_width == width && m_height == height) { return; } - LOG_DEBUG("Texture resize from %u, %u to %u, %u.", m_width, m_height, width, height); + logd("Texture resize from {}, {} to {}, {}.", m_width, m_height, width, height); glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexImage2D(GL_TEXTURE_2D, 0, m_format, width, height, 0, m_externalFormat, GL_UNSIGNED_BYTE, - nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, m_format, width, height, 0, m_externalFormat, GL_UNSIGNED_BYTE, nullptr); m_width = width; m_height = height; } -GLuint CTexture::getId() const { return m_textureId; } +GLuint Texture::getId() const { return m_textureId; } -bool CTexture::isValid() const { return m_valid; } +bool Texture::isValid() const { return m_valid; } -void CTexture::setActive(GLint textureUnit) const +void Texture::setActive(GLint textureUnit) const { assert(isValid()); - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, m_textureId); + glBindTextureUnit(textureUnit, m_textureId); } -void CTexture::saveAsPng(const std::string &file) +void Texture::saveAsPng(const std::string &file) { std::vector image; image.resize(m_width * m_height * 3); - glBindTexture(GL_TEXTURE_2D, m_textureId); - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image.data()); - lodepng::encode(file, image, m_width, m_height, LCT_RGB); + glGetTextureImage(m_textureId, 0, GL_RGB, GL_UNSIGNED_BYTE, image.size(), image.data()); + + if (stbi_write_png(file.c_str(), m_width, m_height, 3, image.data(), m_width * 3) != 1) + { + loge("Failed to save png"); + } } -bool CTexture::init(const std::vector &image, unsigned int width, - unsigned int height, GLint format, bool createMipmaps) +bool Texture::init(const std::vector &image, unsigned int width, unsigned int height, GLint format, + bool createMipmaps) { // Sanity checks if (width == 0 || height == 0) @@ -176,70 +176,67 @@ bool CTexture::init(const std::vector &image, unsigned int width, } // Create id - GLuint textureId; - glGenTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); + GLuint textureId = 0; + glCreateTextures(GL_TEXTURE_2D, 1, &textureId); // TODO Filter should be based on arguments and mip map level // Set filters if (width == 1 && height == 1) { // Special case 1x1 texture - // Needs nearest filtering otherwise texture is black? - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + // NOTE Needs nearest filtering otherwise texture is black? + glTextureParameteri(textureId, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTextureParameteri(textureId, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { if (m_hasMipmaps) { // Bilinear filtering - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTextureParameteri(textureId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTextureParameteri(textureId, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } else { // Default value is linear filtering - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTextureParameteri(textureId, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTextureParameteri(textureId, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } // Set wrap mode - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + glTextureParameteri(textureId, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT); + glTextureParameteri(textureId, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); + + int levels = 1; + if (createMipmaps) + { + levels = (int)std::floor(std::log2(std::min(width, height))) + 1; + } - // Load data + // Use glTexImage for mutable storage for resizing later + // TODO Disallow resizing of textures / create completely new texture on resize + // NOTE Actually disallowing and forcing a new texture to be created would be better? + // TODO For FBO resize, the FBO would need to be recreated completely + glBindTexture(GL_TEXTURE_2D, textureId); + // Load data if (image.empty()) { - // No image data, only allocate texture space - // TODO As of OpenGL 4.3, glTexStorage should be used for this. glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, m_externalFormat, type, nullptr); } else { // Load image data - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, m_externalFormat, type, - image.data()); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, m_externalFormat, type, image.data()); } // Mipmaps - // Do not generate for 1x1 images - if (width != 1 && height != 1 && createMipmaps) + if (levels > 1) { - glGenerateMipmap(GL_TEXTURE_2D); + glGenerateTextureMipmap(textureId); } - - // Unbind glBindTexture(GL_TEXTURE_2D, 0); - std::string error; - if (hasGLError(error)) - { - LOG_ERROR("GL Error: %s", error.c_str()); - return false; - } - // Clean up previously created id if (m_textureId != 0) { @@ -254,8 +251,7 @@ bool CTexture::init(const std::vector &image, unsigned int width, return true; } -void CTexture::setParameter(GLenum parameterName, GLint value) +void Texture::setParameter(GLenum parameterName, GLint value) { - glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexParameteri(GL_TEXTURE_2D, parameterName, value); + glTextureParameteri(m_textureId, parameterName, value); } diff --git a/Graphics/Lib/source/sampler/Interpolation.cpp b/Engine/Lib/source/graphics/sampler/Interpolation.cpp similarity index 93% rename from Graphics/Lib/source/sampler/Interpolation.cpp rename to Engine/Lib/source/graphics/sampler/Interpolation.cpp index 7457e1b..fdd02f0 100644 --- a/Graphics/Lib/source/sampler/Interpolation.cpp +++ b/Engine/Lib/source/graphics/sampler/Interpolation.cpp @@ -1,4 +1,4 @@ -#include "graphics/sampler/Interpolation.h" +#include "kern/graphics/sampler/Interpolation.h" #include diff --git a/Graphics/Lib/source/graphics/scene/CScene.cpp b/Engine/Lib/source/graphics/scene/Scene.cpp similarity index 51% rename from Graphics/Lib/source/graphics/scene/CScene.cpp rename to Engine/Lib/source/graphics/scene/Scene.cpp index eed0075..f25a997 100644 --- a/Graphics/Lib/source/graphics/scene/CScene.cpp +++ b/Engine/Lib/source/graphics/scene/Scene.cpp @@ -1,48 +1,44 @@ -#include "graphics/graphics/scene/CScene.h" +#include "kern/graphics/scene/Scene.h" -#include +#include -#include "graphics/collision/CFrustum.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/IGraphicsResourceManager.h" +#include "kern/graphics/collision/Frustum.h" +#include "kern/graphics/resource/Mesh.h" +#include "kern/graphics/scene/SceneDirectionalLight.h" +#include "kern/graphics/scene/SceneObject.h" +#include "kern/graphics/scene/ScenePointLight.h" +#include "kern/graphics/scene/SceneQuery.h" -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/IGraphicsResourceManager.h" -#include "graphics/graphics/resource/CMesh.h" -#include "graphics/graphics/scene/CSceneQuery.h" -#include "graphics/graphics/scene/SSceneDirectionalLight.h" -#include "graphics/graphics/scene/SSceneObject.h" -#include "graphics/graphics/scene/SScenePointLight.h" +bool Scene::getViewFrustumCulling() { return s_useViewFrustumCulling; } -bool CScene::getViewFrustumCulling() { return s_useViewFrustumCulling; } +void Scene::setViewFrustumCulling(bool enable) { s_useViewFrustumCulling = enable; } -void CScene::setViewFrustumCulling(bool enable) { s_useViewFrustumCulling = enable; } +bool Scene::s_useViewFrustumCulling = true; -bool CScene::s_useViewFrustumCulling = true; +Scene::Scene(const IGraphicsResourceManager *manager) : m_resourceManager(manager) {} -CScene::CScene(const IGraphicsResourceManager *manager) : m_resourceManager(manager) {} +Scene::~Scene() {} -CScene::~CScene() {} - -SceneObjectId CScene::createObject(ResourceId model, const glm::vec3 &position, - const glm::quat &rotation, const glm::vec3 &scale) +SceneObjectId Scene::createObject(ResourceId model, const glm::vec3 &position, const glm::quat &rotation, + const glm::vec3 &scale) { - // const CMesh* meshPtr = m_resourceManager->getMesh(meshId); - m_objects.push_back(SSceneObject(model, position, rotation, scale, true, CBoundingSphere())); - return m_objects.size() - 1; + // const Mesh* meshPtr = m_resourceManager->getMesh(meshId); + m_objects.push_back(SceneObject(model, position, rotation, scale, true, BoundingSphere())); + return (SceneObjectId)m_objects.size() - 1; } -SceneObjectId CScene::createObject(ResourceId meshId, ResourceId material, - const glm::vec3 &position, const glm::quat &rotation, - const glm::vec3 &scale) +SceneObjectId Scene::createObject(ResourceId meshId, ResourceId material, const glm::vec3 &position, + const glm::quat &rotation, const glm::vec3 &scale) { - const CMesh *meshPtr = m_resourceManager->getMesh(meshId); - m_objects.push_back(SSceneObject(meshId, material, position, rotation, scale, true, - meshPtr->getBoundingSphere())); - return m_objects.size() - 1; + const Mesh *meshPtr = m_resourceManager->getMesh(meshId); + m_objects.push_back(SceneObject(meshId, material, position, rotation, scale, true, meshPtr->getBoundingSphere())); + return (SceneObjectId)m_objects.size() - 1; } -bool CScene::getObject(SceneObjectId id, ResourceId &mesh, ResourceId &material, - glm::vec3 &position, glm::quat &rotation, glm::vec3 &scale, - bool &visible) const +bool Scene::getObject(SceneObjectId id, ResourceId &mesh, ResourceId &material, glm::vec3 &position, + glm::quat &rotation, glm::vec3 &scale, bool &visible) const { // TODO Needs to be changed for better data structures if (id < 0 || ((unsigned int)id) >= m_objects.size()) @@ -60,29 +56,27 @@ bool CScene::getObject(SceneObjectId id, ResourceId &mesh, ResourceId &material, return true; } -void CScene::setObject(SceneObjectId id, ResourceId meshId, ResourceId material, - const glm::vec3 &position, const glm::quat &rotation, const glm::vec3 &scale, - bool visible) +void Scene::setObject(SceneObjectId id, ResourceId meshId, ResourceId material, const glm::vec3 &position, + const glm::quat &rotation, const glm::vec3 &scale, bool visible) { // TODO Needs to be changed for better data structures assert(id >= 0 && ((unsigned int)id) < m_objects.size() && "Invalid scene object id"); unsigned int index = (unsigned int)id; // Write data - const CMesh *meshPtr = m_resourceManager->getMesh(meshId); - m_objects[index] = SSceneObject(meshId, material, position, rotation, scale, visible, - meshPtr->getBoundingSphere()); + const Mesh *meshPtr = m_resourceManager->getMesh(meshId); + m_objects[index] = SceneObject(meshId, material, position, rotation, scale, visible, meshPtr->getBoundingSphere()); return; } -SceneObjectId CScene::createPointLight(const glm::vec3 &position, float radius, - const glm::vec3 &color, float intensity, bool castsShadow) +SceneObjectId Scene::createPointLight(const glm::vec3 &position, float radius, const glm::vec3 &color, float intensity, + bool castsShadow) { - m_pointLights.push_back(SScenePointLight(position, radius, color, intensity, castsShadow)); - return m_pointLights.size() - 1; + m_pointLights.push_back(ScenePointLight(position, radius, color, intensity, castsShadow)); + return (SceneObjectId)m_pointLights.size() - 1; } -bool CScene::getPointLight(SceneObjectId id, glm::vec3 &position, float &radius, glm::vec3 &color, - float &intensity, bool &castsShadow) const +bool Scene::getPointLight(SceneObjectId id, glm::vec3 &position, float &radius, glm::vec3 &color, float &intensity, + bool &castsShadow) const { // TODO Needs to be changed for better data structures if (id < 0 || ((unsigned int)id) >= m_pointLights.size()) @@ -99,8 +93,8 @@ bool CScene::getPointLight(SceneObjectId id, glm::vec3 &position, float &radius, return true; } -void CScene::setPointLight(SceneObjectId id, const glm::vec3 &position, float radius, - const glm::vec3 &color, float intensity, bool castsShadow) +void Scene::setPointLight(SceneObjectId id, const glm::vec3 &position, float radius, const glm::vec3 &color, + float intensity, bool castsShadow) { // TODO Needs to be changed for better data structures assert(id >= 0 && ((unsigned int)id) < m_pointLights.size() && "Invalid scene object id"); @@ -114,15 +108,15 @@ void CScene::setPointLight(SceneObjectId id, const glm::vec3 &position, float ra return; } -SceneObjectId CScene::createDirectionalLight(const glm::vec3 &direction, const glm::vec3 &color, - float intensity, bool castsShadow) +SceneObjectId Scene::createDirectionalLight(const glm::vec3 &direction, const glm::vec3 &color, float intensity, + bool castsShadow) { - m_directionalLights.push_back(SSceneDirectionalLight(direction, color, intensity, castsShadow)); - return m_directionalLights.size() - 1; + m_directionalLights.push_back(SceneDirectionalLight(direction, color, intensity, castsShadow)); + return (SceneObjectId)m_directionalLights.size() - 1; } -bool CScene::getDirectionalLight(SceneObjectId id, glm::vec3 &direction, glm::vec3 &color, - float &intensity, bool &castsShadow) const +bool Scene::getDirectionalLight(SceneObjectId id, glm::vec3 &direction, glm::vec3 &color, float &intensity, + bool &castsShadow) const { // TODO Needs to be changed for better data structures if (id < 0 || ((unsigned int)id) >= m_directionalLights.size()) @@ -138,8 +132,8 @@ bool CScene::getDirectionalLight(SceneObjectId id, glm::vec3 &direction, glm::ve return true; } -void CScene::setDirectionalLight(SceneObjectId id, const glm::vec3 &direction, - const glm::vec3 &color, float intensity, bool castsShadow) +void Scene::setDirectionalLight(SceneObjectId id, const glm::vec3 &direction, const glm::vec3 &color, float intensity, + bool castsShadow) { // TODO Needs to be changed for better data structures assert(id >= 0 && ((unsigned int)id) < m_directionalLights.size() && "Invalid scene object id"); @@ -152,23 +146,23 @@ void CScene::setDirectionalLight(SceneObjectId id, const glm::vec3 &direction, return; } -void CScene::setAmbientLight(const glm::vec3 &color, float intensity) +void Scene::setAmbientLight(const glm::vec3 &color, float intensity) { m_ambientColor = color; m_ambientIntensity = intensity; } -bool CScene::getAmbientLight(glm::vec3 &color, float &intensity) const +bool Scene::getAmbientLight(glm::vec3 &color, float &intensity) const { color = m_ambientColor; intensity = m_ambientIntensity; return true; } -void CScene::getVisibleObjects(const ICamera &camera, ISceneQuery &query) const +void Scene::getVisibleObjects(const ICamera &camera, ISceneQuery &query) const { // Create frustum from camera matrices - CFrustum viewFrustum; + Frustum viewFrustum; viewFrustum.setFromViewProjectionClipSpaceApproach(camera.getView(), camera.getProjection()); // Hackyyy @@ -203,8 +197,7 @@ void CScene::getVisibleObjects(const ICamera &camera, ISceneQuery &query) const { // Check light volume against view frustum for point light culling const auto &pointLight = m_pointLights.at(i); - if (viewFrustum.isInsideOrIntersects( - CBoundingSphere(pointLight.m_position, pointLight.m_radius))) + if (viewFrustum.isInsideOrIntersects(BoundingSphere(pointLight.m_position, pointLight.m_radius))) { // Counter variable is light id query.addPointLight(i); diff --git a/Engine/Lib/source/graphics/scene/SceneDirectionalLight.cpp b/Engine/Lib/source/graphics/scene/SceneDirectionalLight.cpp new file mode 100644 index 0000000..efd83a0 --- /dev/null +++ b/Engine/Lib/source/graphics/scene/SceneDirectionalLight.cpp @@ -0,0 +1,9 @@ +#include "kern/graphics/scene/SceneDirectionalLight.h" + +SceneDirectionalLight::SceneDirectionalLight() {} + +SceneDirectionalLight::SceneDirectionalLight(const glm::vec3 &direction, const glm::vec3 &color, + float intensity, bool castsShadow) + : m_direction(direction), m_color(color), m_intensity(intensity), m_castsShadow(castsShadow) +{ +} \ No newline at end of file diff --git a/Graphics/Lib/source/graphics/scene/SSceneObject.cpp b/Engine/Lib/source/graphics/scene/SceneObject.cpp similarity index 67% rename from Graphics/Lib/source/graphics/scene/SSceneObject.cpp rename to Engine/Lib/source/graphics/scene/SceneObject.cpp index 83a275d..e19b531 100644 --- a/Graphics/Lib/source/graphics/scene/SSceneObject.cpp +++ b/Engine/Lib/source/graphics/scene/SceneObject.cpp @@ -1,12 +1,12 @@ -#include "graphics/graphics/scene/SSceneObject.h" +#include "kern/graphics/scene/SceneObject.h" #include -SSceneObject::SSceneObject() { return; } +SceneObject::SceneObject() { return; } -SSceneObject::SSceneObject(ResourceId mesh, ResourceId material, const glm::vec3 &position, +SceneObject::SceneObject(ResourceId mesh, ResourceId material, const glm::vec3 &position, const glm::quat &rotation, const glm::vec3 &scale, bool visible, - const CBoundingSphere &sphere) + const BoundingSphere &sphere) : m_mesh(mesh), m_material(material), m_position(position), @@ -19,8 +19,8 @@ SSceneObject::SSceneObject(ResourceId mesh, ResourceId material, const glm::vec3 return; } -SSceneObject::SSceneObject(ResourceId model, const glm::vec3 &position, const glm::quat &rotation, - const glm::vec3 &scale, bool visible, const CBoundingSphere &sphere) +SceneObject::SceneObject(ResourceId model, const glm::vec3 &position, const glm::quat &rotation, + const glm::vec3 &scale, bool visible, const BoundingSphere &sphere) : m_model(model), m_position(position), m_rotation(rotation), @@ -32,7 +32,7 @@ SSceneObject::SSceneObject(ResourceId model, const glm::vec3 &position, const gl return; } -void SSceneObject::updateBoundingSphere() +void SceneObject::updateBoundingSphere() { // Translate boundingSphere.setPosition(m_position); diff --git a/Graphics/Lib/source/graphics/scene/SScenePointLight.cpp b/Engine/Lib/source/graphics/scene/ScenePointLight.cpp similarity index 52% rename from Graphics/Lib/source/graphics/scene/SScenePointLight.cpp rename to Engine/Lib/source/graphics/scene/ScenePointLight.cpp index fcf993a..ae54466 100644 --- a/Graphics/Lib/source/graphics/scene/SScenePointLight.cpp +++ b/Engine/Lib/source/graphics/scene/ScenePointLight.cpp @@ -1,8 +1,8 @@ -#include "graphics/graphics/scene/SScenePointLight.h" +#include "kern/graphics/scene/ScenePointLight.h" -SScenePointLight::SScenePointLight() {} +ScenePointLight::ScenePointLight() {} -SScenePointLight::SScenePointLight(const glm::vec3 &position, float radius, const glm::vec3 &color, +ScenePointLight::ScenePointLight(const glm::vec3 &position, float radius, const glm::vec3 &color, float intensity, bool castsShadow) : m_position(position), m_radius(radius), diff --git a/Graphics/Lib/source/graphics/scene/CSceneQuery.cpp b/Engine/Lib/source/graphics/scene/SceneQuery.cpp similarity index 57% rename from Graphics/Lib/source/graphics/scene/CSceneQuery.cpp rename to Engine/Lib/source/graphics/scene/SceneQuery.cpp index 1763d54..53d5854 100644 --- a/Graphics/Lib/source/graphics/scene/CSceneQuery.cpp +++ b/Engine/Lib/source/graphics/scene/SceneQuery.cpp @@ -1,17 +1,17 @@ -#include "graphics/graphics/scene/CSceneQuery.h" +#include "kern/graphics/scene/SceneQuery.h" -#include "graphics/graphics/ICamera.h" -#include "graphics/graphics/scene/CScene.h" +#include "kern/graphics/ICamera.h" +#include "kern/graphics/scene/Scene.h" -CSceneQuery::CSceneQuery(unsigned int objectStorage, unsigned int lightStorage) +SceneQuery::SceneQuery(unsigned int objectStorage, unsigned int lightStorage) { m_visibleObjects.reserve(objectStorage); m_visiblePointLights.reserve(lightStorage); } -bool CSceneQuery::hasNextObject() const { return m_nextObjectIndex < m_visibleObjects.size(); } +bool SceneQuery::hasNextObject() const { return m_nextObjectIndex < m_visibleObjects.size(); } -SceneObjectId CSceneQuery::getNextObject() +SceneObjectId SceneQuery::getNextObject() { if (!hasNextObject()) { @@ -26,12 +26,12 @@ SceneObjectId CSceneQuery::getNextObject() return id; } -bool CSceneQuery::hasNextPointLight() const +bool SceneQuery::hasNextPointLight() const { return m_nextPointLightIndex < m_visiblePointLights.size(); } -SceneObjectId CSceneQuery::getNextPointLight() +SceneObjectId SceneQuery::getNextPointLight() { if (!hasNextPointLight()) { @@ -46,17 +46,17 @@ SceneObjectId CSceneQuery::getNextPointLight() return id; } -bool CSceneQuery::hasNextDirectionalLight() const +bool SceneQuery::hasNextDirectionalLight() const { return m_nextDirectionalLightIndex < m_visibleDirectionalLights.size(); } -SceneObjectId CSceneQuery::getNextDirectionalLight() +SceneObjectId SceneQuery::getNextDirectionalLight() { if (!hasNextDirectionalLight()) { // Invalid object id - return invalidObject; + return InvalidObject; } // Get id SceneObjectId id = m_visibleDirectionalLights.at(m_nextDirectionalLightIndex); @@ -65,11 +65,11 @@ SceneObjectId CSceneQuery::getNextDirectionalLight() return id; } -void CSceneQuery::addObject(SceneObjectId id) { m_visibleObjects.push_back(id); } +void SceneQuery::addObject(SceneObjectId id) { m_visibleObjects.push_back(id); } -void CSceneQuery::addPointLight(SceneObjectId id) { m_visiblePointLights.push_back(id); } +void SceneQuery::addPointLight(SceneObjectId id) { m_visiblePointLights.push_back(id); } -void CSceneQuery::addDirectionalLight(SceneObjectId id) +void SceneQuery::addDirectionalLight(SceneObjectId id) { m_visibleDirectionalLights.push_back(id); } diff --git a/Engine/Lib/source/graphics/system/GraphicsSystem.cpp b/Engine/Lib/source/graphics/system/GraphicsSystem.cpp new file mode 100644 index 0000000..f93fa6a --- /dev/null +++ b/Engine/Lib/source/graphics/system/GraphicsSystem.cpp @@ -0,0 +1,165 @@ +#include "kern/graphics/system/GraphicsSystem.h" + +#include + +#include "kern/foundation/Time.h" +#include "kern/graphics/camera/Camera.h" +#include "kern/graphics/renderer/DeferredRenderer.h" +#include "kern/graphics/renderer/ForwardRenderer.h" +#include "kern/graphics/renderer/RendererCoreConfig.h" +#include "kern/graphics/resource/GraphicsResourceManager.h" +#include "kern/resource/IResourceManager.h" +#include "kern/graphics/scene/Scene.h" + +GraphicsSystem::GraphicsSystem() {} + +GraphicsSystem::~GraphicsSystem() {} + +bool GraphicsSystem::init(IResourceManager &manager) +{ + // Create graphics resource manager and register as listener to resource + // manager + GraphicsResourceManager *grm = new GraphicsResourceManager; + manager.addResourceListener(grm); + m_resourceManager.reset(grm); + + // Create renderers + // Deferred renderer + m_deferredRenderer.reset(DeferredRenderer::create(manager)); + if (m_deferredRenderer == nullptr) + { + loge("Failed to initialize deferred renderer."); + return false; + } + + // Forward renderer + m_forwardRenderer.reset(ForwardRenderer::create(manager)); + if (m_forwardRenderer == nullptr) + { + loge("Failed to initialize forward renderer."); + return false; + } + + // Set default active renderer + m_activeRenderer = m_deferredRenderer.get(); + + // Init ok + return true; +} + +void GraphicsSystem::setActiveRenderer(const std::string &renderer) +{ + // Deferred renderer does not support wireframe mode, force forward renderer + if (renderer == "deferred" && !m_wireframeMode) + { + m_activeRenderer = m_deferredRenderer.get(); + } + else if (renderer == "forward") + { + m_activeRenderer = m_forwardRenderer.get(); + } + else + { + // Use default + logw("Invalid or unknown renderer type {}. Setting renderer to default.", renderer.c_str()); + m_activeRenderer = m_deferredRenderer.get(); + } +} + +IScene *GraphicsSystem::createScene() +{ + // TODO Refactor + IScene *scene = new Scene(m_resourceManager.get()); + m_scenes.push_back(std::unique_ptr(scene)); + return scene; +} + +void GraphicsSystem::setActiveScene(IScene *scene) { m_activeScene = scene; } + +ICamera *GraphicsSystem::createCamera() +{ + ICamera *camera = new Camera; + m_cameras.push_back(std::unique_ptr(camera)); + return camera; +} + +void GraphicsSystem::setActiveCamera(const ICamera *camera) { m_activeCamera = camera; } + +void GraphicsSystem::toggleDebugOverlay() { m_drawDebugOverlay = !m_drawDebugOverlay; } + +void GraphicsSystem::toggleDebugOverlayTransparency() { m_transparentDebugOverlay = !m_transparentDebugOverlay; } + +void GraphicsSystem::toggleWireframeMode() +{ + m_wireframeMode = !m_wireframeMode; + if (m_wireframeMode) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + // Only supported for forward renderer + // TODO Implement rendering parameters for IRenderer interface + // Force usage of forward renderer + setActiveRenderer("forward"); + } + else + { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + // Reset renderer + setActiveRenderer("deferred"); + } +} + +void GraphicsSystem::toggleViewFrustumCulling() +{ + Scene::setViewFrustumCulling(!Scene::getViewFrustumCulling()); + if (Scene::getViewFrustumCulling()) + { + logi("View frustum culling enabled."); + } + else + { + logi("View frustum culling disabled."); + } +} + +void GraphicsSystem::draw(Window &window) +{ + // Current calling time + double callTime = getTime(); + double timeDiff = 0.0; + + // Check for first call to draw + // TODO Actually necessary? + if (m_lastCallTime == 0.0) + { + m_lastCallTime = callTime; + } + else + { + // Time difference between calls + timeDiff = callTime - m_lastCallTime; + // Set last call time to current call time + m_lastCallTime = callTime; + } + + // Update time accumulator + m_timeAccum += timeDiff; + // Check if time accumulator passed 1 sec + if (m_timeAccum >= 1.0) + { + // Set last frame count for fps calculation + m_lastFrameCount = m_currentFrameCount; + // Reset current frame count + m_currentFrameCount = 0; + // Reset time accumulator + m_timeAccum = 0.0; + } + + // Update frame count + ++m_currentFrameCount; + + // Scene draw + if (m_activeScene != nullptr && m_activeCamera != nullptr) + { + m_activeRenderer->draw(*m_activeScene, *m_activeCamera, window, *m_resourceManager); + } +} \ No newline at end of file diff --git a/Engine/Lib/source/resource/ImageLoader.cpp b/Engine/Lib/source/resource/ImageLoader.cpp new file mode 100644 index 0000000..3941bde --- /dev/null +++ b/Engine/Lib/source/resource/ImageLoader.cpp @@ -0,0 +1,12 @@ +#include "kern/resource/ImageLoader.h" + +#include "kern/resource/LoadImage.h" + +bool ImageLoader::loadFromFile(const std::string& file, IResourceManager& manager) { + Image img; + if (!load(file, img)) + return false; + + manager.createImage(img.m_data, img.m_width, img.m_height, img.m_format); + return true; +} \ No newline at end of file diff --git a/Engine/Lib/source/resource/LoadImage.cpp b/Engine/Lib/source/resource/LoadImage.cpp new file mode 100644 index 0000000..c67b79a --- /dev/null +++ b/Engine/Lib/source/resource/LoadImage.cpp @@ -0,0 +1,81 @@ +#include "kern/resource/LoadImage.h" + +#include +#include + +#include + +static ColorFormat channelsToFormat(int channels) +{ + switch (channels) + { + case 1: + return ColorFormat::GreyScale8; + case 3: + return ColorFormat::RGB24; + case 4: + return ColorFormat::RGBA32; + default: + return ColorFormat::Invalid; + } +} + +static bool loadInternal(const std::string& file, int stbiDesiredChannels, Image& image) +{ + stbi_set_flip_vertically_on_load(true); + + // Decode image data + int channels = 0; + int width = 0; + int height = 0; + uint8_t* data = stbi_load(file.c_str(), &width, &height, &channels, stbiDesiredChannels); + + // Set channels to actual channels when converting + if (stbiDesiredChannels != STBI_default) + { + channels = stbiDesiredChannels; + } + + if (data == nullptr) + { + loge("An error occured while decoding the image file {}", file); + return false; + } + + image.m_format = channelsToFormat(channels); + image.m_width = width; + image.m_height = height; + image.m_data.assign(data, data + channels * width * height); + stbi_image_free(data); + + return true; +} + +bool load(const std::string& file, Image& image) +{ + return loadInternal(file, STBI_default, image); +} + +bool load(const std::string &file, ColorFormat format, Image &image) +{ + // Map color type + int desiredChannels = 0; + switch (format) + { + case ColorFormat::GreyScale8: + desiredChannels = STBI_grey; + break; + case ColorFormat::RGB24: + desiredChannels = STBI_rgb; + break; + case ColorFormat::RGBA32: + desiredChannels = STBI_rgb_alpha; + break; + default: + loge("Unknown color format encountered while loading image file {}.", file); + return false; + break; + } + + return loadInternal(file, desiredChannels, image); +} \ No newline at end of file diff --git a/Engine/Lib/source/resource/LoadMaterial.cpp b/Engine/Lib/source/resource/LoadMaterial.cpp new file mode 100644 index 0000000..4492623 --- /dev/null +++ b/Engine/Lib/source/resource/LoadMaterial.cpp @@ -0,0 +1,151 @@ +#include "kern/resource/LoadMaterial.h" + +#include + +#include "kern/foundation/IniFile.h" +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" +#include "kern/resource/ResourceManager.h" + +bool load(const std::string &file, ResourceManager &manager, SMaterial &material) +{ + std::string base; + std::string normal; + std::string specular; + std::string glow; + std::string alpha; + + if (file.find(".ini") != std::string::npos) + { + if (!loadMaterialFromIni(file, base, normal, specular, glow, alpha)) + { + return false; + } + } + else if (file.find(".json") != std::string::npos) + { + if (!loadMaterialFromJson(file, base, normal, specular, glow, alpha)) + { + return false; + } + } + else + { + return false; + } + + ResourceId baseId = InvalidResource; + if (!base.empty()) + { + // Diffuse texture is RGB format, ignore alpha + baseId = manager.loadImage(base, ColorFormat::RGB24); + if (baseId == InvalidResource) + { + loge("Failed to load base."); + return false; + } + } + + ResourceId normalId = InvalidResource; + if (!normal.empty()) + { + // Normal texture is RGB format + normalId = manager.loadImage(normal, ColorFormat::RGB24); + if (normalId == InvalidResource) + { + loge("Failed to load normal texture."); + return false; + } + } + + ResourceId specularId = InvalidResource; + if (!specular.empty()) + { + // Specular texture is grey-scale format + specularId = manager.loadImage(specular, ColorFormat::GreyScale8); + if (specularId == InvalidResource) + { + loge("Failed to load specular texture."); + return false; + } + } + + ResourceId glowId = InvalidResource; + if (!glow.empty()) + { + // Glow texture is grey-scale format + glowId = manager.loadImage(glow, ColorFormat::GreyScale8); + if (glowId == InvalidResource) + { + loge("Failed to load glow texture."); + return false; + } + } + + ResourceId alphaId = InvalidResource; + if (!alpha.empty()) + { + // Alpha texture is grey-scale format + alphaId = manager.loadImage(alpha, ColorFormat::GreyScale8); + if (alphaId == InvalidResource) + { + loge("Failed to load alpha texture."); + return false; + } + } + + // Set ids + material.m_base = baseId; + material.m_normal = normalId; + material.m_specular = specularId; + material.m_glow = glowId; + material.m_alpha = alphaId; + return true; +} + +bool loadMaterialFromIni(const std::string &file, std::string &base, std::string &normal, std::string &specular, + std::string &glow, std::string &alpha) +{ + logd("Loading material from ini file {}.", file.c_str()); + IniFile ini; + if (!ini.load(file)) + { + loge("Failed to load material file {} as ini file.", file.c_str()); + return false; + } + + // Load from ini + base = ini.getValue("base", "file", ""); + if (base.empty()) + { + base = ini.getValue("diffuse", "file", ""); + if (!base.empty()) + { + logw("The material file {} uses deprecated 'diffuse' instead of 'base'", file); + } + } + normal = ini.getValue("normal", "file", ""); + specular = ini.getValue("specular", "file", ""); + glow = ini.getValue("glow", "file", ""); + alpha = ini.getValue("alpha", "file", ""); + return true; +} + +bool loadMaterialFromJson(const std::string &file, std::string &base, std::string &normal, std::string &specular, + std::string &glow, std::string &alpha) +{ + nlohmann::json root; + if (!load(file, root)) + { + loge("Failed to load material file {} as json file.", file.c_str()); + return false; + } + + // Load from json + load(root, "base", base); + load(root, "normal", normal); + load(root, "specular", specular); + load(root, "glow", glow); + load(root, "alpha", alpha); + return true; +} \ No newline at end of file diff --git a/Engine/Lib/source/resource/LoadMesh.cpp b/Engine/Lib/source/resource/LoadMesh.cpp new file mode 100644 index 0000000..059a935 --- /dev/null +++ b/Engine/Lib/source/resource/LoadMesh.cpp @@ -0,0 +1,112 @@ +#include "kern/resource/LoadMesh.h" + +#include +#include +#include + +#include + +#include "kern/foundation/StringUtil.h" + +#define TINYOBJLOADER_IMPLEMENTATION +#include + +bool load(const std::string &file, SMesh &mesh) +{ + logi("Loading mesh from file {}", file.c_str()); + std::string extension = getFileExtension(file); + if (extension == "obj") + { + return loadMeshFromObj(file, mesh); + } + else + { + loge("Invalid or unknown mesh file format."); + return false; + } +} + +bool loadMeshFromObj(const std::string &file, SMesh &mesh) +{ + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + + std::string warn; + std::string err; + + if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, file.c_str())) + { + loge("Failed to load mesh from file {}: {}", file, err); + return false; + } + if (!err.empty()) + { + loge("Error while loading mesh from file {}: {}", file, err); + return false; + } + if (!warn.empty()) + { + logw("Warning while loading mesh from file {}: {}", file, warn); + } + + if (shapes.size() != 1) + { + loge("Loading of multiple meshes not supported: {}", file); + return false; + } + + auto shape = shapes.at(0); + + mesh.m_type = PrimitiveType::Triangle; + /* + mesh.m_vertices = attrib.vertices; + + // Reorder normals and uvs to match vertex indices + // TODO Doesnt work + mesh.m_normals.resize(mesh.m_vertices.size(), -1.f); + mesh.m_uvs.resize(mesh.m_vertices.size() / 3 * 2); + for (auto index : shape.mesh.indices) + { + mesh.m_indices.push_back(index.vertex_index); + // + if (index.normal_index >= 0) + { + mesh.m_normals[index.vertex_index * 3] = attrib.normals.at(index.normal_index * 3); + mesh.m_normals[index.vertex_index * 3 + 1] = attrib.normals.at(index.normal_index * 3 + 1); + mesh.m_normals[index.vertex_index * 3 + 2] = attrib.normals.at(index.normal_index * 3 + 2); + } + + if (index.texcoord_index >= 0) + { + mesh.m_uvs[index.vertex_index * 2] = attrib.texcoords.at(index.texcoord_index * 2); + mesh.m_uvs[index.vertex_index * 2 + 1] = attrib.texcoords.at(index.texcoord_index * 2 + 1); + } + } + */ + // Flatten and remove index buffer to non indexed mesh + for (auto index : shape.mesh.indices) + { + // Vertex x/y/z + mesh.m_vertices.push_back(attrib.vertices.at(index.vertex_index * 3)); + mesh.m_vertices.push_back(attrib.vertices.at(index.vertex_index * 3 + 1)); + mesh.m_vertices.push_back(attrib.vertices.at(index.vertex_index * 3 + 2)); + // Normal x/y/z + mesh.m_normals.push_back(attrib.normals.at(index.normal_index * 3)); + mesh.m_normals.push_back(attrib.normals.at(index.normal_index * 3 + 1)); + mesh.m_normals.push_back(attrib.normals.at(index.normal_index * 3 + 2)); + // UVs + if (index.texcoord_index >= 0) + { + mesh.m_uvs.push_back(attrib.texcoords.at(index.texcoord_index * 2)); + mesh.m_uvs.push_back(attrib.texcoords.at(index.texcoord_index * 2 + 1)); + } + else + { + mesh.m_uvs.push_back(0.f); + mesh.m_uvs.push_back(0.f); + } + } + + return true; +} diff --git a/Graphics/Lib/source/resource/core/LoadModel.cpp b/Engine/Lib/source/resource/LoadModel.cpp similarity index 54% rename from Graphics/Lib/source/resource/core/LoadModel.cpp rename to Engine/Lib/source/resource/LoadModel.cpp index b49f27d..4ace394 100644 --- a/Graphics/Lib/source/resource/core/LoadModel.cpp +++ b/Engine/Lib/source/resource/LoadModel.cpp @@ -1,11 +1,12 @@ -#include "graphics/resource/core/LoadModel.h" +#include "kern/resource/LoadModel.h" -#include -#include -#include -#include +#include -bool load(const std::string &file, CResourceManager &manager, SModel &model) +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" +#include "kern/foundation/StringUtil.h" + +bool load(const std::string &file, ResourceManager &manager, SModel &model) { std::string extension = getFileExtension(file); std::string mesh; @@ -19,23 +20,23 @@ bool load(const std::string &file, CResourceManager &manager, SModel &model) } else { - LOG_ERROR("Invalid or unknown model file format."); + loge("Invalid or unknown model file format."); return false; } // Load mesh ResourceId meshId = manager.loadMesh(mesh); - if (meshId == invalidResource) + if (meshId == InvalidResource) { - LOG_ERROR("Failed to load mesh."); + loge("Failed to load mesh."); return false; } // Load material ResourceId materialId = manager.loadMaterial(material); - if (meshId == invalidResource) + if (meshId == InvalidResource) { - LOG_ERROR("Failed to load material."); + loge("Failed to load material."); return false; } @@ -47,20 +48,20 @@ bool load(const std::string &file, CResourceManager &manager, SModel &model) bool loadModelFromJson(const std::string &file, std::string &meshFile, std::string &materialFile) { - Json::Value root; + nlohmann::json root; if (!load(file, root)) { return false; } - if (!deserialize(root["mesh"], meshFile)) + if (!load(root, "mesh", meshFile)) { - LOG_ERROR("Failed to load mesh node."); + loge("Failed to load mesh node."); return false; } - if (!deserialize(root["material"], materialFile)) + if (!load(root, "material", materialFile)) { - LOG_ERROR("Failed to load material node."); + loge("Failed to load material node."); return false; } return true; diff --git a/Graphics/Lib/source/resource/core/LoadShader.cpp b/Engine/Lib/source/resource/LoadShader.cpp similarity index 53% rename from Graphics/Lib/source/resource/core/LoadShader.cpp rename to Engine/Lib/source/resource/LoadShader.cpp index 9540ac9..36476b6 100644 --- a/Graphics/Lib/source/resource/core/LoadShader.cpp +++ b/Engine/Lib/source/resource/LoadShader.cpp @@ -1,13 +1,12 @@ -#include "graphics/resource/core/LoadShader.h" +#include "kern/resource/LoadShader.h" -#include -#include -#include -#include +#include -#include "graphics/resource/core/CResourceManager.h" +#include "kern/foundation/IniFile.h" +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" -bool load(const std::string &file, CResourceManager &manager, SShader &shader) +bool load(const std::string &file, ResourceManager &manager, SShader &shader) { std::string vertex; std::string tessControl; @@ -31,15 +30,15 @@ bool load(const std::string &file, CResourceManager &manager, SShader &shader) } else { - LOG_ERROR("Unknown or invalid shader file format."); + loge("Unknown or invalid shader file format."); return false; } // Requires vertex and fragment shader files if (vertex.empty()) { - LOG_ERROR( - "The shader program file %s is missing a vertex shader source " + loge( + "The shader program file {} is missing a vertex shader source " "file specifier.", file.c_str()); return false; @@ -47,74 +46,74 @@ bool load(const std::string &file, CResourceManager &manager, SShader &shader) if (fragment.empty()) { - LOG_ERROR( - "The shader program file %s is missing a vertex shader source " + loge( + "The shader program file {} is missing a vertex shader source " "file specifier.", file.c_str()); return false; } - ResourceId vertexId = manager.loadString(vertex, true); - if (vertexId == invalidResource) + ResourceId vertexId = manager.loadString(vertex); + if (vertexId == InvalidResource) { - LOG_ERROR( - "The vertex shader source file %s, specified in the shader " - "program file %s could not " + loge( + "The vertex shader source file {}, specified in the shader " + "program file {} could not " "be loaded.", vertex.c_str(), file.c_str()); return false; } - ResourceId fragmentId = manager.loadString(fragment, true); - if (fragmentId == invalidResource) + ResourceId fragmentId = manager.loadString(fragment); + if (fragmentId == InvalidResource) { - LOG_ERROR( - "The fragment shader source file %s, specified in the shader " - "program file %s could not " + loge( + "The fragment shader source file {}, specified in the shader " + "program file {} could not " "be loaded.", fragment.c_str(), file.c_str()); return false; } - ResourceId tessCtrlId = invalidResource; + ResourceId tessCtrlId = InvalidResource; if (!tessControl.empty()) { - tessCtrlId = manager.loadString(tessControl, true); - if (tessCtrlId == invalidResource) + tessCtrlId = manager.loadString(tessControl); + if (tessCtrlId == InvalidResource) { - LOG_ERROR( - "The tessellation control shader source file %s, specified in " + loge( + "The tessellation control shader source file {}, specified in " "the shader program " - "file %s could not be loaded.", + "file {} could not be loaded.", tessControl.c_str(), file.c_str()); return false; } } - ResourceId tessEvalId = invalidResource; + ResourceId tessEvalId = InvalidResource; if (!tessEval.empty()) { - tessEvalId = manager.loadString(tessEval, true); - if (tessEvalId == invalidResource) + tessEvalId = manager.loadString(tessEval); + if (tessEvalId == InvalidResource) { - LOG_ERROR( - "The tessellation evaluation shader source file %s, specified " + loge( + "The tessellation evaluation shader source file {}, specified " "in the shader " - "program file %s could not be loaded.", + "program file {} could not be loaded.", tessEval.c_str(), file.c_str()); return false; } } - ResourceId geometryId = invalidResource; + ResourceId geometryId = InvalidResource; if (!geometry.empty()) { - geometryId = manager.loadString(geometry, true); - if (geometryId == invalidResource) + geometryId = manager.loadString(geometry); + if (geometryId == InvalidResource) { - LOG_ERROR( - "The geometry shader source file %s, specified in the shader " - "program file %s could " + loge( + "The geometry shader source file {}, specified in the shader " + "program file {} could " "not be loaded.", geometry.c_str(), file.c_str()); return false; @@ -129,14 +128,14 @@ bool load(const std::string &file, CResourceManager &manager, SShader &shader) return true; } -bool loadShaderFromIni(const std::string &file, std::string &vertex, std::string &tessControl, - std::string &tessEval, std::string &geometry, std::string &fragment) +bool loadShaderFromIni(const std::string &file, std::string &vertex, std::string &tessControl, std::string &tessEval, + std::string &geometry, std::string &fragment) { // Load shader ini - CIniFile ini; + IniFile ini; if (!ini.load(file)) { - LOG_ERROR("Failed to load shader program file %s", file.c_str()); + loge("Failed to load shader program file {}", file.c_str()); return false; } @@ -149,9 +148,9 @@ bool loadShaderFromIni(const std::string &file, std::string &vertex, std::string return true; } -bool loadShaderFromJson(const std::string &file, std::string &vertex, std::string &tessControl, - std::string &tessEval, std::string &geometry, std::string &fragment) +bool loadShaderFromJson(const std::string &file, std::string &vertex, std::string &tessControl, std::string &tessEval, + std::string &geometry, std::string &fragment) { - LOG_DEBUG("Not implemented"); + logd("Not implemented"); return false; } \ No newline at end of file diff --git a/Engine/Lib/source/resource/ResourceManager.cpp b/Engine/Lib/source/resource/ResourceManager.cpp new file mode 100644 index 0000000..a55802e --- /dev/null +++ b/Engine/Lib/source/resource/ResourceManager.cpp @@ -0,0 +1,437 @@ +#include "kern/resource/ResourceManager.h" + +#include + +#include +#include +#include +#include + +#include "kern/foundation/IniFile.h" +#include "kern/foundation/JsonDeserialize.h" +#include "kern/foundation/JsonUtil.h" +#include "kern/resource/IResourceListener.h" +#include "kern/resource/LoadImage.h" +#include "kern/resource/LoadMaterial.h" +#include "kern/resource/LoadMesh.h" +#include "kern/resource/LoadModel.h" +#include "kern/resource/LoadShader.h" +#include "kern/foundation/StringUtil.h" + +ResourceManager::~ResourceManager() +{ + for (auto listener : m_resourceListeners) + { + listener->onDetach(this); + } +} + +bool ResourceManager::loadFromFile(const std::string &file) +{ + auto ext = getFileExtension(file); + auto iter = m_resourceLoaderCreators.find(ext); + if (iter == m_resourceLoaderCreators.end()) + { + logw("No resource loader registered for extension {}. Failed to load file {}", ext, file); + return false; + } + + auto loader = iter->second(); + return loader->loadFromFile(file, *this); +} + +ResourceId ResourceManager::createMesh(const std::vector &vertices, const std::vector &indices, + const std::vector &normals, const std::vector &uvs, + PrimitiveType type) +{ + // Create mesh id + ResourceId id = m_nextMeshId; + ++m_nextMeshId; + + // Add mesh + m_meshes[id] = SMesh(vertices, indices, normals, uvs, type); + + // Notify listener with create event + notifyResourceListeners(ResourceType::Mesh, id, ResourceEvent::Create); + return id; +} + +ResourceId ResourceManager::loadMesh(const std::string &file) +{ + auto entry = m_meshFiles.find(file); + if (entry != m_meshFiles.end()) + { + return entry->second; + } + + // Load mesh + SMesh mesh; + if (!load(file, mesh)) + { + loge("Failed to load mesh from file {}.", file.c_str()); + throw std::runtime_error("Failed to load mesh"); + } + + // Create mesh resource + ResourceId meshId = createMesh(mesh.m_vertices, mesh.m_indices, mesh.m_normals, mesh.m_uvs, mesh.m_type); + if (meshId == InvalidResource) + { + loge("Failed to create mesh resource id from file {}.", file.c_str()); + throw std::runtime_error("Failed to create mesh"); + } + m_meshFiles[file] = meshId; + return meshId; +} + +bool ResourceManager::getMesh(ResourceId id, std::vector &vertices, std::vector &indices, + std::vector &normals, std::vector &uvs, PrimitiveType &type) const +{ + // Retrieve from map + auto iter = m_meshes.find(id); + if (iter == m_meshes.end()) + { + return false; + } + // Copy data + vertices = iter->second.m_vertices; + indices = iter->second.m_indices; + normals = iter->second.m_normals; + uvs = iter->second.m_uvs; + type = iter->second.m_type; + return true; +} + +ResourceId ResourceManager::createImage(const std::vector &imageData, unsigned int width, + unsigned int height, ColorFormat format) +{ + // Create image + ResourceId id = m_nextImageId; + ++m_nextImageId; + + // TODO Sanity check if image already exists? + // Add mesh + m_images[id] = Image(imageData, width, height, format); + + // Notify listener with create event + notifyResourceListeners(ResourceType::Image, id, ResourceEvent::Create); + return id; +} + +ResourceId ResourceManager::loadImage(const std::string &file, ColorFormat format) +{ + auto entry = m_imageFiles.find(file); + if (entry != m_imageFiles.end()) + { + return entry->second; + } + + // Load image + Image image; + if (!load(file, format, image)) + { + loge("Failed to load image from file {}.", file.c_str()); + throw std::runtime_error("Failed to load image"); + } + + // Create managed resource + ResourceId imageId = createImage(image.m_data, image.m_width, image.m_height, image.m_format); + if (imageId == InvalidResource) + { + loge("Failed to create image resource id from file {}.", file.c_str()); + throw std::runtime_error("Failed to create image"); + } + m_imageFiles[file] = imageId; + return imageId; +} + +bool ResourceManager::getImage(ResourceId id, std::vector &data, unsigned int &width, + unsigned int &height, ColorFormat &format) const +{ + // Retrieve from map + auto iter = m_images.find(id); + if (iter == m_images.end()) + { + return false; + } + // Copy data + data = iter->second.m_data; + width = iter->second.m_width; + height = iter->second.m_height; + format = iter->second.m_format; + return true; +} + +ResourceId ResourceManager::createMaterial(ResourceId base, ResourceId normal, ResourceId specular, ResourceId glow, + ResourceId alpha) +{ + // Create material + ResourceId id = m_nextMaterialId; + ++m_nextMaterialId; + + // Add material + m_materials[id] = SMaterial(base, normal, specular, glow, alpha); + + // Notify listener with create event + notifyResourceListeners(ResourceType::Material, id, ResourceEvent::Create); + return id; +} + +ResourceId ResourceManager::loadMaterial(const std::string &file) +{ + auto entry = m_materialFiles.find(file); + if (entry != m_materialFiles.end()) + { + return entry->second; + } + + logd("Loading material from file {}.", file.c_str()); + SMaterial material; + if (!load(file, *this, material)) + { + loge("Failed to load material from file {}.", file.c_str()); + throw std::runtime_error("Failed to load material"); + } + + ResourceId materialId = + createMaterial(material.m_base, material.m_normal, material.m_specular, material.m_glow, material.m_alpha); + if (materialId == InvalidResource) + { + loge("Failed to create material resource id for material file {}.", file.c_str()); + throw std::runtime_error("Failed to create material"); + } + m_materialFiles[file] = materialId; + return materialId; +} + +bool ResourceManager::getMaterial(ResourceId id, ResourceId &base, ResourceId &normal, ResourceId &specular, + ResourceId &glow, ResourceId &alpha) const +{ + // Retrieve from map + auto iter = m_materials.find(id); + if (iter == m_materials.end()) + { + return false; + } + // Copy data + base = iter->second.m_base; + normal = iter->second.m_normal; + specular = iter->second.m_specular; + glow = iter->second.m_glow; + alpha = iter->second.m_alpha; + return true; +} + +ResourceId ResourceManager::createModel(ResourceId mesh, ResourceId material) +{ + // Create model + ResourceId id = m_nextModelId; + ++m_nextModelId; + + // Add material + m_models[id] = SModel(mesh, material); + + // Notify listener with create event + notifyResourceListeners(ResourceType::Model, id, ResourceEvent::Create); + return id; +} + +ResourceId ResourceManager::loadModel(const std::string &file) +{ + auto entry = m_modelFiles.find(file); + if (entry != m_modelFiles.end()) + { + return entry->second; + } + + logd("Loading model from file {}.", file.c_str()); + SModel model; + if (!load(file, *this, model)) + { + loge("Failed to load model from file {}.", file.c_str()); + throw std::runtime_error("Failed to load model"); + } + + ResourceId modelId = createModel(model.m_mesh, model.m_material); + if (modelId == InvalidResource) + { + loge("Failed to create model resource id for model file {}.", file.c_str()); + throw std::runtime_error("Failed to create model"); + } + m_modelFiles[file] = modelId; + return modelId; +} + +bool ResourceManager::getModel(ResourceId id, ResourceId &mesh, ResourceId &material) +{ + // Retrieve from map + auto iter = m_models.find(id); + if (iter == m_models.end()) + { + return false; + } + // Copy data + mesh = iter->second.m_mesh; + material = iter->second.m_material; + return true; +} + +ResourceId ResourceManager::createString(const std::string &text) +{ + // Create string + ResourceId id = m_nextStringId; + ++m_nextStringId; + + // Add string + m_strings[id] = text; + + // Notify listener with create event + notifyResourceListeners(ResourceType::String, id, ResourceEvent::Create); + return id; +} + +bool ResourceManager::getString(ResourceId id, std::string &text) const +{ + // Retrieve from map + auto iter = m_strings.find(id); + if (iter == m_strings.end()) + { + return false; + } + // Copy data + text = iter->second; + return true; +} + +ResourceId ResourceManager::createShader(ResourceId vertex, ResourceId tessCtrl, ResourceId tessEval, + ResourceId geometry, ResourceId fragment) +{ + // Needs at least valid vertex and fragment shader + if (vertex == InvalidResource || fragment == InvalidResource) + { + loge("Failed to create shader, resource id for vertex or fragment shader is invalid."); + throw std::runtime_error("Failed to create shader: one or more ids invalid"); + } + + // Create shader + ResourceId id = m_nextShaderId; + ++m_nextShaderId; + + // Add shader + m_shaders[id] = SShader(vertex, tessCtrl, tessEval, geometry, fragment); + + // Notify listener with create event + notifyResourceListeners(ResourceType::Shader, id, ResourceEvent::Create); + return id; +} + +bool ResourceManager::getShader(ResourceId id, ResourceId &vertex, ResourceId &tessCtrl, ResourceId &tessEval, + ResourceId &geometry, ResourceId &fragment) const +{ + // Retrieve from map + auto iter = m_shaders.find(id); + if (iter == m_shaders.end()) + { + return false; + } + // Copy data + vertex = iter->second.m_vertex; + tessCtrl = iter->second.m_tessCtrl; + tessEval = iter->second.m_tessEval; + geometry = iter->second.m_geometry; + fragment = iter->second.m_fragment; + return true; +} + +ResourceId ResourceManager::loadShader(const std::string &file) +{ + // Check if shader exists + auto entry = m_shaderFiles.find(file); + if (entry != m_shaderFiles.end()) + { + return entry->second; + } + + logd("Loading shader from file {}.", file.c_str()); + SShader shader; + if (!load(file, *this, shader)) + { + loge("Failed to load shader from file {}.", file.c_str()); + throw std::runtime_error("Failed to load shader file"); + } + + ResourceId shaderId = InvalidResource; + shaderId = + createShader(shader.m_vertex, shader.m_tessCtrl, shader.m_tessEval, shader.m_geometry, shader.m_fragment); + if (shaderId == InvalidResource) + { + loge("Failed to create reasource id for shader file {}.", file.c_str()); + throw std::runtime_error("Failed to create shader"); + } + + m_shaderFiles[file] = shaderId; + return shaderId; +} + +void ResourceManager::addResourceListener(IResourceListener *listener) +{ + m_resourceListeners.push_back(listener); + listener->onAttach(this); +} + +void ResourceManager::removeResourceListener(IResourceListener *listener) +{ + m_resourceListeners.remove(listener); + listener->onDetach(this); +} + +void ResourceManager::addResourceLoaderCreator(const std::string &extension, + const std::function()> &creator) +{ + if (m_resourceLoaderCreators.find(extension) != m_resourceLoaderCreators.end()) + { + throw std::runtime_error("Creation function for " + extension + " already exists"); + } + m_resourceLoaderCreators[extension] = creator; +} + +void ResourceManager::notifyResourceListeners(ResourceType type, ResourceId id, ResourceEvent event) +{ + for (const auto &listener : m_resourceListeners) + { + listener->notify(type, id, event, this); + } +} + +ResourceId ResourceManager::loadString(const std::string &file) +{ + auto iter = m_textFiles.find(file); + if (iter != m_textFiles.end()) + { + return iter->second; + } + + logd("Loading text from file {}.", file.c_str()); + std::ifstream ifs(file); + if (!ifs.is_open()) + { + loge("Failed to open the text file {}.", file.c_str()); + throw std::runtime_error("Failed to load text file"); + } + + // Load file + std::string text((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + ifs.close(); + + ResourceId stringId = -1; + + // Create new string entry + stringId = createString(text); + if (stringId == -1) + { + loge("Failed to create string id for text file {}.", file.c_str()); + throw std::runtime_error("Failed to create text from file"); + } + + m_textFiles[file] = stringId; + return stringId; +} \ No newline at end of file diff --git a/Engine/Lib/source/resource/SImage.cpp b/Engine/Lib/source/resource/SImage.cpp new file mode 100644 index 0000000..9cde713 --- /dev/null +++ b/Engine/Lib/source/resource/SImage.cpp @@ -0,0 +1,8 @@ +#include "kern/resource/Image.h" + +Image::Image(std::vector data, unsigned int width, unsigned int height, + ColorFormat format) + : m_data(data), m_width(width), m_height(height), m_format(format) +{ + return; +} diff --git a/Graphics/Lib/source/resource/core/SMaterial.cpp b/Engine/Lib/source/resource/SMaterial.cpp similarity index 74% rename from Graphics/Lib/source/resource/core/SMaterial.cpp rename to Engine/Lib/source/resource/SMaterial.cpp index 879b62b..e5202f5 100644 --- a/Graphics/Lib/source/resource/core/SMaterial.cpp +++ b/Engine/Lib/source/resource/SMaterial.cpp @@ -1,6 +1,4 @@ -#include "graphics/resource/core/SMaterial.h" - -SMaterial::SMaterial() { return; } +#include "kern/resource/SMaterial.h" SMaterial::SMaterial(ResourceId base, ResourceId normal, ResourceId specular, ResourceId glow, ResourceId alpha) diff --git a/Graphics/Lib/source/resource/core/SMesh.cpp b/Engine/Lib/source/resource/SMesh.cpp similarity index 66% rename from Graphics/Lib/source/resource/core/SMesh.cpp rename to Engine/Lib/source/resource/SMesh.cpp index 9599295..7b4b5f4 100644 --- a/Graphics/Lib/source/resource/core/SMesh.cpp +++ b/Engine/Lib/source/resource/SMesh.cpp @@ -1,10 +1,10 @@ -#include "graphics/resource/core/SMesh.h" +#include "kern/resource/SMesh.h" SMesh::SMesh(std::vector vertices, std::vector indices, - std::vector normals, std::vector uvs, EPrimitiveType type) + std::vector normals, std::vector uvs, PrimitiveType type) : m_vertices(vertices), m_indices(indices), m_normals(normals), m_uvs(uvs), m_type(type) { return; } -SMesh::SMesh() : m_type(EPrimitiveType::Invalid) { return; } +SMesh::SMesh() : m_type(PrimitiveType::Invalid) { return; } diff --git a/Graphics/Lib/source/resource/core/SModel.cpp b/Engine/Lib/source/resource/SModel.cpp similarity index 62% rename from Graphics/Lib/source/resource/core/SModel.cpp rename to Engine/Lib/source/resource/SModel.cpp index 56b4ba8..612f521 100644 --- a/Graphics/Lib/source/resource/core/SModel.cpp +++ b/Engine/Lib/source/resource/SModel.cpp @@ -1,6 +1,4 @@ -#include "graphics/resource/core/SModel.h" - -SModel::SModel() {} +#include "kern/resource/SModel.h" SModel::SModel(ResourceId mesh, ResourceId material) : m_mesh(mesh), m_material(material) { diff --git a/Graphics/Lib/source/resource/core/SShader.cpp b/Engine/Lib/source/resource/SShader.cpp similarity index 64% rename from Graphics/Lib/source/resource/core/SShader.cpp rename to Engine/Lib/source/resource/SShader.cpp index 01f65ad..d377963 100644 --- a/Graphics/Lib/source/resource/core/SShader.cpp +++ b/Engine/Lib/source/resource/SShader.cpp @@ -1,9 +1,4 @@ -#include "graphics/resource/core/SShader.h" - -SShader::SShader() : m_vertex(-1), m_tessCtrl(-1), m_tessEval(-1), m_geometry(-1), m_fragment(-1) -{ - return; -} +#include "kern/resource/SShader.h" SShader::SShader(ResourceId vertex, ResourceId tessCtrl, ResourceId tessEval, ResourceId geometry, ResourceId fragment) diff --git a/Engine/Test/CMakeLists.txt b/Engine/Test/CMakeLists.txt new file mode 100644 index 0000000..2c257fe --- /dev/null +++ b/Engine/Test/CMakeLists.txt @@ -0,0 +1,24 @@ +project(EngineTest) + +file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp +) +# Source group to preserve folder structure in ide +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES}) + +add_executable (${PROJECT_NAME} ${SOURCE_FILES}) +add_test (${PROJECT_NAME} ${PROJECT_NAME}) + +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_STANDARD 17 +) + +target_link_libraries (${PROJECT_NAME} + PRIVATE EngineLib + PRIVATE Catch2::Catch2WithMain +) + +target_include_directories(${PROJECT_NAME} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source/ +) \ No newline at end of file diff --git a/Engine/Test/source/Main.cpp b/Engine/Test/source/Main.cpp new file mode 100644 index 0000000..f4f49eb --- /dev/null +++ b/Engine/Test/source/Main.cpp @@ -0,0 +1,6 @@ +#include + +TEST_CASE("Test", "[test]") +{ + REQUIRE(true); +} \ No newline at end of file diff --git a/Foundation/CMakeLists.txt b/Foundation/CMakeLists.txt deleted file mode 100644 index aa2f563..0000000 --- a/Foundation/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required (VERSION 3.0.0) -project (Foundation) - -set (CXX_STANDARD_REQUIRED ON) - -add_subdirectory (Lib) -add_subdirectory (Test) - diff --git a/Foundation/Lib/CMakeLists.txt b/Foundation/Lib/CMakeLists.txt deleted file mode 100644 index 44548ca..0000000 --- a/Foundation/Lib/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -# JsonCPP -set(JSONCPP_WITH_TESTS OFF CACHE BOOL "") -set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "") -set(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF CACHE BOOL "") -set(JSONCPP_WITH_WARNING_AS_ERROR OFF CACHE BOOL "") -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/jsoncpp) - -# Crypto++ library -set(BUILD_SHARED OFF CACHE BOOL "") -set(BUILD_TESTING OFF CACHE BOOL "") -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/cryptopp) - -# TinyXML2 -set(BUILD_SHARED_LIBS OFF CACHE BOOL "") -set(BUILD_STATIC_LIBS ON CACHE BOOL "") -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/tinyxml2) - -# Boost libraries -set(Boost_USE_STATIC_LIBS ON CACHE BOOL "") -find_package(Boost 1.55 REQUIRED system program_options regex filesystem date_time log) - - -# Third party code -# SQLite3 -file(GLOB SQLITE3_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/external/sqlite-amalgamation-3081101/sqlite3.c) -set(THIRD_PARTY_SOURCES ${THIRD_PARTY_SOURCES} ${SQLITE3_SOURCES}) - - -# Foundation library source files -file(GLOB_RECURSE SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cxx - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/source/*.hxx - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hxx -) - -# Foundation library -add_library (${PROJECT_NAME} ${SOURCE_FILES} ${THIRD_PARTY_SOURCES}) - - -# Properties -set_target_properties (${PROJECT_NAME} PROPERTIES - CXX_STANDARD 11 -) - - -# Link dependencies -target_link_libraries(${PROJECT_NAME} - LINK_PUBLIC cryptopp-static - LINK_PUBLIC ${Boost_LIBRARIES} - LINK_PUBLIC jsoncpp_lib_static - LINK_PUBLIC tinyxml2_static -) - - -# Additional libraries for SQLite3 (g++/clang only) -if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - target_link_libraries(${PROJECT_NAME} LINK_PUBLIC dl pthread) -endif () - - -# Includes -target_include_directories(${PROJECT_NAME} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include - - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/external/cryptopp - PUBLIC ${Boost_INCLUDE_DIR} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/external/glm - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/external/jsoncpp/include - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/external/tinyxml2 - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/external/sqlite-amalgamation-3150100 -) - - -# Additional definitions -target_compile_definitions(${PROJECT_NAME} - PUBLIC -DGLM_ENABLE_EXPERIMENTAL -) \ No newline at end of file diff --git a/Foundation/Lib/external/cryptopp b/Foundation/Lib/external/cryptopp deleted file mode 160000 index 3fc97d2..0000000 --- a/Foundation/Lib/external/cryptopp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3fc97d2bfff25d571049466a6803e8edcad2ceb4 diff --git a/Foundation/Lib/external/glm b/Foundation/Lib/external/glm deleted file mode 160000 index 1a95482..0000000 --- a/Foundation/Lib/external/glm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1a95482b50084032b83d4ac2483abf55e2ad404e diff --git a/Foundation/Lib/external/jsoncpp b/Foundation/Lib/external/jsoncpp deleted file mode 160000 index a691cb1..0000000 --- a/Foundation/Lib/external/jsoncpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a691cb19deedb9e1e5ed6c0dad12735019ef5e47 diff --git a/Foundation/Lib/external/sqlite-amalgamation-3150100/shell.c b/Foundation/Lib/external/sqlite-amalgamation-3150100/shell.c deleted file mode 100644 index 732ef62..0000000 --- a/Foundation/Lib/external/sqlite-amalgamation-3150100/shell.c +++ /dev/null @@ -1,5811 +0,0 @@ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code to implement the "sqlite" command line -** utility for accessing SQLite databases. -*/ -#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) -/* This needs to come before any includes for MSVC compiler */ -#define _CRT_SECURE_NO_WARNINGS -#endif - -/* -** If requested, include the SQLite compiler options file for MSVC. -*/ -#if defined(INCLUDE_MSVC_H) -#include "msvc.h" -#endif - -/* -** No support for loadable extensions in VxWorks. -*/ -#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION -# define SQLITE_OMIT_LOAD_EXTENSION 1 -#endif - -/* -** Enable large-file support for fopen() and friends on unix. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - -#include -#include -#include -#include -#include "sqlite3.h" -#if SQLITE_USER_AUTHENTICATION -# include "sqlite3userauth.h" -#endif -#include -#include - -#if !defined(_WIN32) && !defined(WIN32) -# include -# if !defined(__RTP__) && !defined(_WRS_KERNEL) -# include -# endif -# include -# include -#endif - -#if HAVE_READLINE -# include -# include -#endif - -#if HAVE_EDITLINE -# include -#endif - -#if HAVE_EDITLINE || HAVE_READLINE - -# define shell_add_history(X) add_history(X) -# define shell_read_history(X) read_history(X) -# define shell_write_history(X) write_history(X) -# define shell_stifle_history(X) stifle_history(X) -# define shell_readline(X) readline(X) - -#elif HAVE_LINENOISE - -# include "linenoise.h" -# define shell_add_history(X) linenoiseHistoryAdd(X) -# define shell_read_history(X) linenoiseHistoryLoad(X) -# define shell_write_history(X) linenoiseHistorySave(X) -# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) -# define shell_readline(X) linenoise(X) - -#else - -# define shell_read_history(X) -# define shell_write_history(X) -# define shell_stifle_history(X) - -# define SHELL_USE_LOCAL_GETLINE 1 -#endif - - -#if defined(_WIN32) || defined(WIN32) -# include -# include -# define isatty(h) _isatty(h) -# ifndef access -# define access(f,m) _access((f),(m)) -# endif -# undef popen -# define popen _popen -# undef pclose -# define pclose _pclose -#else - /* Make sure isatty() has a prototype. */ - extern int isatty(int); - -# if !defined(__RTP__) && !defined(_WRS_KERNEL) - /* popen and pclose are not C89 functions and so are - ** sometimes omitted from the header */ - extern FILE *popen(const char*,const char*); - extern int pclose(FILE*); -# else -# define SQLITE_OMIT_POPEN 1 -# endif -#endif - -#if defined(_WIN32_WCE) -/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() - * thus we always assume that we have a console. That can be - * overridden with the -batch command line option. - */ -#define isatty(x) 1 -#endif - -/* ctype macros that work with signed characters */ -#define IsSpace(X) isspace((unsigned char)X) -#define IsDigit(X) isdigit((unsigned char)X) -#define ToLower(X) (char)tolower((unsigned char)X) - -#if defined(_WIN32) || defined(WIN32) -#include - -/* string conversion routines only needed on Win32 */ -extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); -extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int); -extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int); -extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); -#endif - -/* On Windows, we normally run with output mode of TEXT so that \n characters -** are automatically translated into \r\n. However, this behavior needs -** to be disabled in some cases (ex: when generating CSV output and when -** rendering quoted strings that contain \n characters). The following -** routines take care of that. -*/ -#if defined(_WIN32) || defined(WIN32) -static void setBinaryMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_BINARY); -} -static void setTextMode(FILE *file, int isOutput){ - if( isOutput ) fflush(file); - _setmode(_fileno(file), _O_TEXT); -} -#else -# define setBinaryMode(X,Y) -# define setTextMode(X,Y) -#endif - - -/* True if the timer is enabled */ -static int enableTimer = 0; - -/* Return the current wall-clock time */ -static sqlite3_int64 timeOfDay(void){ - static sqlite3_vfs *clockVfs = 0; - sqlite3_int64 t; - if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); - if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ - clockVfs->xCurrentTimeInt64(clockVfs, &t); - }else{ - double r; - clockVfs->xCurrentTime(clockVfs, &r); - t = (sqlite3_int64)(r*86400000.0); - } - return t; -} - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) -#include -#include - -/* VxWorks does not support getrusage() as far as we can determine */ -#if defined(_WRS_KERNEL) || defined(__RTP__) -struct rusage { - struct timeval ru_utime; /* user CPU time used */ - struct timeval ru_stime; /* system CPU time used */ -}; -#define getrusage(A,B) memset(B,0,sizeof(*B)) -#endif - -/* Saved resource information for the beginning of an operation */ -static struct rusage sBegin; /* CPU time at start */ -static sqlite3_int64 iBegin; /* Wall-clock time at start */ - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer ){ - getrusage(RUSAGE_SELF, &sBegin); - iBegin = timeOfDay(); - } -} - -/* Return the difference of two time_structs in seconds */ -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + - (double)(pEnd->tv_sec - pStart->tv_sec); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer ){ - sqlite3_int64 iEnd = timeOfDay(); - struct rusage sEnd; - getrusage(RUSAGE_SELF, &sEnd); - printf("Run Time: real %.3f user %f sys %f\n", - (iEnd - iBegin)*0.001, - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER 1 - -#elif (defined(_WIN32) || defined(WIN32)) - -/* Saved resource information for the beginning of an operation */ -static HANDLE hProcess; -static FILETIME ftKernelBegin; -static FILETIME ftUserBegin; -static sqlite3_int64 ftWallBegin; -typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, - LPFILETIME, LPFILETIME); -static GETPROCTIMES getProcessTimesAddr = NULL; - -/* -** Check to see if we have timer support. Return 1 if necessary -** support found (or found previously). -*/ -static int hasTimer(void){ - if( getProcessTimesAddr ){ - return 1; - } else { - /* GetProcessTimes() isn't supported in WIN95 and some other Windows - ** versions. See if the version we are running on has it, and if it - ** does, save off a pointer to it and the current process handle. - */ - hProcess = GetCurrentProcess(); - if( hProcess ){ - HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); - if( NULL != hinstLib ){ - getProcessTimesAddr = - (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); - if( NULL != getProcessTimesAddr ){ - return 1; - } - FreeLibrary(hinstLib); - } - } - } - return 0; -} - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer && getProcessTimesAddr ){ - FILETIME ftCreation, ftExit; - getProcessTimesAddr(hProcess,&ftCreation,&ftExit, - &ftKernelBegin,&ftUserBegin); - ftWallBegin = timeOfDay(); - } -} - -/* Return the difference of two FILETIME structs in seconds */ -static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ - sqlite_int64 i64Start = *((sqlite_int64 *) pStart); - sqlite_int64 i64End = *((sqlite_int64 *) pEnd); - return (double) ((i64End - i64Start) / 10000000.0); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer && getProcessTimesAddr){ - FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; - sqlite3_int64 ftWallEnd = timeOfDay(); - getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - printf("Run Time: real %.3f user %f sys %f\n", - (ftWallEnd - ftWallBegin)*0.001, - timeDiff(&ftUserBegin, &ftUserEnd), - timeDiff(&ftKernelBegin, &ftKernelEnd)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER hasTimer() - -#else -#define BEGIN_TIMER -#define END_TIMER -#define HAS_TIMER 0 -#endif - -/* -** Used to prevent warnings about unused parameters -*/ -#define UNUSED_PARAMETER(x) (void)(x) - -/* -** If the following flag is set, then command execution stops -** at an error if we are not interactive. -*/ -static int bail_on_error = 0; - -/* -** Threat stdin as an interactive input if the following variable -** is true. Otherwise, assume stdin is connected to a file or pipe. -*/ -static int stdin_is_interactive = 1; - -/* -** On Windows systems we have to know if standard output is a console -** in order to translate UTF-8 into MBCS. The following variable is -** true if translation is required. -*/ -static int stdout_is_console = 1; - -/* -** The following is the open SQLite database. We make a pointer -** to this database a static variable so that it can be accessed -** by the SIGINT handler to interrupt database processing. -*/ -static sqlite3 *globalDb = 0; - -/* -** True if an interrupt (Control-C) has been received. -*/ -static volatile int seenInterrupt = 0; - -/* -** This is the name of our program. It is set in main(), used -** in a number of other places, mostly for error messages. -*/ -static char *Argv0; - -/* -** Prompt strings. Initialized in main. Settable with -** .prompt main continue -*/ -static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/ -static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ - -/* -** Render output like fprintf(). Except, if the output is going to the -** console and if this is running on a Windows machine, translate the -** output from UTF-8 into MBCS. -*/ -#if defined(_WIN32) || defined(WIN32) -void utf8_printf(FILE *out, const char *zFormat, ...){ - va_list ap; - va_start(ap, zFormat); - if( stdout_is_console && (out==stdout || out==stderr) ){ - char *z1 = sqlite3_vmprintf(zFormat, ap); - char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); - sqlite3_free(z1); - fputs(z2, out); - sqlite3_free(z2); - }else{ - vfprintf(out, zFormat, ap); - } - va_end(ap); -} -#elif !defined(utf8_printf) -# define utf8_printf fprintf -#endif - -/* -** Render output like fprintf(). This should not be used on anything that -** includes string formatting (e.g. "%s"). -*/ -#if !defined(raw_printf) -# define raw_printf fprintf -#endif - -/* -** Write I/O traces to the following stream. -*/ -#ifdef SQLITE_ENABLE_IOTRACE -static FILE *iotrace = 0; -#endif - -/* -** This routine works like printf in that its first argument is a -** format string and subsequent arguments are values to be substituted -** in place of % fields. The result of formatting this string -** is written to iotrace. -*/ -#ifdef SQLITE_ENABLE_IOTRACE -static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ - va_list ap; - char *z; - if( iotrace==0 ) return; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - utf8_printf(iotrace, "%s", z); - sqlite3_free(z); -} -#endif - - -/* -** Determines if a string is a number of not. -*/ -static int isNumber(const char *z, int *realnum){ - if( *z=='-' || *z=='+' ) z++; - if( !IsDigit(*z) ){ - return 0; - } - z++; - if( realnum ) *realnum = 0; - while( IsDigit(*z) ){ z++; } - if( *z=='.' ){ - z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z++; - if( *z=='+' || *z=='-' ) z++; - if( !IsDigit(*z) ) return 0; - while( IsDigit(*z) ){ z++; } - if( realnum ) *realnum = 1; - } - return *z==0; -} - -/* -** A global char* and an SQL function to access its current value -** from within an SQL statement. This program used to use the -** sqlite_exec_printf() API to substitue a string into an SQL statement. -** The correct way to do this with sqlite3 is to use the bind API, but -** since the shell is built around the callback paradigm it would be a lot -** of work. Instead just use this hack, which is quite harmless. -*/ -static const char *zShellStatic = 0; -static void shellstaticFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - assert( 0==argc ); - assert( zShellStatic ); - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); -} - - -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -*/ -static int strlen30(const char *z){ - const char *z2 = z; - while( *z2 ){ z2++; } - return 0x3fffffff & (int)(z2 - z); -} - -/* -** This routine reads a line of text from FILE in, stores -** the text in memory obtained from malloc() and returns a pointer -** to the text. NULL is returned at end of file, or if malloc() -** fails. -** -** If zLine is not NULL then it is a malloced buffer returned from -** a previous call to this routine that may be reused. -*/ -static char *local_getline(char *zLine, FILE *in){ - int nLine = zLine==0 ? 0 : 100; - int n = 0; - - while( 1 ){ - if( n+100>nLine ){ - nLine = nLine*2 + 100; - zLine = realloc(zLine, nLine); - if( zLine==0 ) return 0; - } - if( fgets(&zLine[n], nLine - n, in)==0 ){ - if( n==0 ){ - free(zLine); - return 0; - } - zLine[n] = 0; - break; - } - while( zLine[n] ) n++; - if( n>0 && zLine[n-1]=='\n' ){ - n--; - if( n>0 && zLine[n-1]=='\r' ) n--; - zLine[n] = 0; - break; - } - } -#if defined(_WIN32) || defined(WIN32) - /* For interactive input on Windows systems, translate the - ** multi-byte characterset characters into UTF-8. */ - if( stdin_is_interactive && in==stdin ){ - char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); - if( zTrans ){ - int nTrans = strlen30(zTrans)+1; - if( nTrans>nLine ){ - zLine = realloc(zLine, nTrans); - if( zLine==0 ){ - sqlite3_free(zTrans); - return 0; - } - } - memcpy(zLine, zTrans, nTrans); - sqlite3_free(zTrans); - } - } -#endif /* defined(_WIN32) || defined(WIN32) */ - return zLine; -} - -/* -** Retrieve a single line of input text. -** -** If in==0 then read from standard input and prompt before each line. -** If isContinuation is true, then a continuation prompt is appropriate. -** If isContinuation is zero, then the main prompt should be used. -** -** If zPrior is not NULL then it is a buffer from a prior call to this -** routine that can be reused. -** -** The result is stored in space obtained from malloc() and must either -** be freed by the caller or else passed back into this routine via the -** zPrior argument for reuse. -*/ -static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ - char *zPrompt; - char *zResult; - if( in!=0 ){ - zResult = local_getline(zPrior, in); - }else{ - zPrompt = isContinuation ? continuePrompt : mainPrompt; -#if SHELL_USE_LOCAL_GETLINE - printf("%s", zPrompt); - fflush(stdout); - zResult = local_getline(zPrior, stdin); -#else - free(zPrior); - zResult = shell_readline(zPrompt); - if( zResult && *zResult ) shell_add_history(zResult); -#endif - } - return zResult; -} - -#if defined(SQLITE_ENABLE_SESSION) -/* -** State information for a single open session -*/ -typedef struct OpenSession OpenSession; -struct OpenSession { - char *zName; /* Symbolic name for this session */ - int nFilter; /* Number of xFilter rejection GLOB patterns */ - char **azFilter; /* Array of xFilter rejection GLOB patterns */ - sqlite3_session *p; /* The open session */ -}; -#endif - -/* -** Shell output mode information from before ".explain on", -** saved so that it can be restored by ".explain off" -*/ -typedef struct SavedModeInfo SavedModeInfo; -struct SavedModeInfo { - int valid; /* Is there legit data in here? */ - int mode; /* Mode prior to ".explain on" */ - int showHeader; /* The ".header" setting prior to ".explain on" */ - int colWidth[100]; /* Column widths prior to ".explain on" */ -}; - -/* -** State information about the database connection is contained in an -** instance of the following structure. -*/ -typedef struct ShellState ShellState; -struct ShellState { - sqlite3 *db; /* The database */ - int echoOn; /* True to echo input commands */ - int autoExplain; /* Automatically turn on .explain mode */ - int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ - int statsOn; /* True to display memory stats before each finalize */ - int scanstatsOn; /* True to display scan stats before each finalize */ - int countChanges; /* True to display change counts */ - int backslashOn; /* Resolve C-style \x escapes in SQL input text */ - int outCount; /* Revert to stdout when reaching zero */ - int cnt; /* Number of records displayed so far */ - FILE *out; /* Write results here */ - FILE *traceOut; /* Output for sqlite3_trace() */ - int nErr; /* Number of errors seen */ - int mode; /* An output mode setting */ - int cMode; /* temporary output mode for the current query */ - int normalMode; /* Output mode before ".explain on" */ - int writableSchema; /* True if PRAGMA writable_schema=ON */ - int showHeader; /* True to show column names in List or Column mode */ - int nCheck; /* Number of ".check" commands run */ - unsigned shellFlgs; /* Various flags */ - char *zDestTable; /* Name of destination table when MODE_Insert */ - char zTestcase[30]; /* Name of current test case */ - char colSeparator[20]; /* Column separator character for several modes */ - char rowSeparator[20]; /* Row separator character for MODE_Ascii */ - int colWidth[100]; /* Requested width of each column when in column mode*/ - int actualWidth[100]; /* Actual width of each column */ - char nullValue[20]; /* The text to print when a NULL comes back from - ** the database */ - char outfile[FILENAME_MAX]; /* Filename for *out */ - const char *zDbFilename; /* name of the database file */ - char *zFreeOnClose; /* Filename to free when closing */ - const char *zVfs; /* Name of VFS to use */ - sqlite3_stmt *pStmt; /* Current statement if any. */ - FILE *pLog; /* Write log output here */ - int *aiIndent; /* Array of indents used in MODE_Explain */ - int nIndent; /* Size of array aiIndent[] */ - int iIndent; /* Index of current op in aiIndent[] */ -#if defined(SQLITE_ENABLE_SESSION) - int nSession; /* Number of active sessions */ - OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ -#endif -}; - -/* -** These are the allowed shellFlgs values -*/ -#define SHFLG_Scratch 0x00001 /* The --scratch option is used */ -#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */ -#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */ - -/* -** These are the allowed modes. -*/ -#define MODE_Line 0 /* One column per line. Blank line between records */ -#define MODE_Column 1 /* One record per line in neat columns */ -#define MODE_List 2 /* One record per line with a separator */ -#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ -#define MODE_Html 4 /* Generate an XHTML table */ -#define MODE_Insert 5 /* Generate SQL "insert" statements */ -#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */ -#define MODE_Csv 7 /* Quote strings, numbers are plain */ -#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */ -#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */ -#define MODE_Pretty 10 /* Pretty-print schemas */ - -static const char *modeDescr[] = { - "line", - "column", - "list", - "semi", - "html", - "insert", - "tcl", - "csv", - "explain", - "ascii", - "prettyprint", -}; - -/* -** These are the column/row/line separators used by the various -** import/export modes. -*/ -#define SEP_Column "|" -#define SEP_Row "\n" -#define SEP_Tab "\t" -#define SEP_Space " " -#define SEP_Comma "," -#define SEP_CrLf "\r\n" -#define SEP_Unit "\x1F" -#define SEP_Record "\x1E" - -/* -** Number of elements in an array -*/ -#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) - -/* -** A callback for the sqlite3_log() interface. -*/ -static void shellLog(void *pArg, int iErrCode, const char *zMsg){ - ShellState *p = (ShellState*)pArg; - if( p->pLog==0 ) return; - utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg); - fflush(p->pLog); -} - -/* -** Output the given string as a hex-encoded blob (eg. X'1234' ) -*/ -static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ - int i; - char *zBlob = (char *)pBlob; - raw_printf(out,"X'"); - for(i=0; i0 ){ - utf8_printf(out,"%.*s",i,z); - } - if( z[i]=='<' ){ - raw_printf(out,"<"); - }else if( z[i]=='&' ){ - raw_printf(out,"&"); - }else if( z[i]=='>' ){ - raw_printf(out,">"); - }else if( z[i]=='\"' ){ - raw_printf(out,"""); - }else if( z[i]=='\'' ){ - raw_printf(out,"'"); - }else{ - break; - } - z += i + 1; - } -} - -/* -** If a field contains any character identified by a 1 in the following -** array, then the string must be quoted for CSV. -*/ -static const char needCsvQuote[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 0, 0, 0, 0, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -/* -** Output a single term of CSV. Actually, p->colSeparator is used for -** the separator, which may or may not be a comma. p->nullValue is -** the null value. Strings are quoted if necessary. The separator -** is only issued if bSep is true. -*/ -static void output_csv(ShellState *p, const char *z, int bSep){ - FILE *out = p->out; - if( z==0 ){ - utf8_printf(out,"%s",p->nullValue); - }else{ - int i; - int nSep = strlen30(p->colSeparator); - for(i=0; z[i]; i++){ - if( needCsvQuote[((unsigned char*)z)[i]] - || (z[i]==p->colSeparator[0] && - (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){ - i = 0; - break; - } - } - if( i==0 ){ - putc('"', out); - for(i=0; z[i]; i++){ - if( z[i]=='"' ) putc('"', out); - putc(z[i], out); - } - putc('"', out); - }else{ - utf8_printf(out, "%s", z); - } - } - if( bSep ){ - utf8_printf(p->out, "%s", p->colSeparator); - } -} - -#ifdef SIGINT -/* -** This routine runs when the user presses Ctrl-C -*/ -static void interrupt_handler(int NotUsed){ - UNUSED_PARAMETER(NotUsed); - seenInterrupt++; - if( seenInterrupt>2 ) exit(1); - if( globalDb ) sqlite3_interrupt(globalDb); -} -#endif - -#ifndef SQLITE_OMIT_AUTHORIZATION -/* -** When the ".auth ON" is set, the following authorizer callback is -** invoked. It always returns SQLITE_OK. -*/ -static int shellAuth( - void *pClientData, - int op, - const char *zA1, - const char *zA2, - const char *zA3, - const char *zA4 -){ - ShellState *p = (ShellState*)pClientData; - static const char *azAction[] = { 0, - "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", - "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", - "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", - "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", - "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", - "DROP_TRIGGER", "DROP_VIEW", "INSERT", - "PRAGMA", "READ", "SELECT", - "TRANSACTION", "UPDATE", "ATTACH", - "DETACH", "ALTER_TABLE", "REINDEX", - "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", - "FUNCTION", "SAVEPOINT", "RECURSIVE" - }; - int i; - const char *az[4]; - az[0] = zA1; - az[1] = zA2; - az[2] = zA3; - az[3] = zA4; - utf8_printf(p->out, "authorizer: %s", azAction[op]); - for(i=0; i<4; i++){ - raw_printf(p->out, " "); - if( az[i] ){ - output_c_string(p->out, az[i]); - }else{ - raw_printf(p->out, "NULL"); - } - } - raw_printf(p->out, "\n"); - return SQLITE_OK; -} -#endif - - -/* -** This is the callback routine that the shell -** invokes for each row of a query result. -*/ -static int shell_callback( - void *pArg, - int nArg, /* Number of result columns */ - char **azArg, /* Text of each result column */ - char **azCol, /* Column names */ - int *aiType /* Column types */ -){ - int i; - ShellState *p = (ShellState*)pArg; - - switch( p->cMode ){ - case MODE_Line: { - int w = 5; - if( azArg==0 ) break; - for(i=0; iw ) w = len; - } - if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator); - for(i=0; iout,"%*s = %s%s", w, azCol[i], - azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); - } - break; - } - case MODE_Explain: - case MODE_Column: { - static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13}; - const int *colWidth; - int showHdr; - char *rowSep; - if( p->cMode==MODE_Column ){ - colWidth = p->colWidth; - showHdr = p->showHeader; - rowSep = p->rowSeparator; - }else{ - colWidth = aExplainWidths; - showHdr = 1; - rowSep = SEP_Row; - } - if( p->cnt++==0 ){ - for(i=0; icolWidth) ){ - w = colWidth[i]; - }else{ - w = 0; - } - if( w==0 ){ - w = strlen30(azCol[i] ? azCol[i] : ""); - if( w<10 ) w = 10; - n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue); - if( wactualWidth) ){ - p->actualWidth[i] = w; - } - if( showHdr ){ - if( w<0 ){ - utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i], - i==nArg-1 ? rowSep : " "); - }else{ - utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i], - i==nArg-1 ? rowSep : " "); - } - } - } - if( showHdr ){ - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - if( w<0 ) w = -w; - }else{ - w = 10; - } - utf8_printf(p->out,"%-*.*s%s",w,w, - "----------------------------------------------------------" - "----------------------------------------------------------", - i==nArg-1 ? rowSep : " "); - } - } - } - if( azArg==0 ) break; - for(i=0; iactualWidth) ){ - w = p->actualWidth[i]; - }else{ - w = 10; - } - if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){ - w = strlen30(azArg[i]); - } - if( i==1 && p->aiIndent && p->pStmt ){ - if( p->iIndentnIndent ){ - utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); - } - p->iIndent++; - } - if( w<0 ){ - utf8_printf(p->out,"%*.*s%s",-w,-w, - azArg[i] ? azArg[i] : p->nullValue, - i==nArg-1 ? rowSep : " "); - }else{ - utf8_printf(p->out,"%-*.*s%s",w,w, - azArg[i] ? azArg[i] : p->nullValue, - i==nArg-1 ? rowSep : " "); - } - } - break; - } - case MODE_Semi: { /* .schema and .fullschema output */ - utf8_printf(p->out, "%s;\n", azArg[0]); - break; - } - case MODE_Pretty: { /* .schema and .fullschema with --indent */ - char *z; - int j; - int nParen = 0; - char cEnd = 0; - char c; - int nLine = 0; - assert( nArg==1 ); - if( azArg[0]==0 ) break; - if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 - || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 - ){ - utf8_printf(p->out, "%s;\n", azArg[0]); - break; - } - z = sqlite3_mprintf("%s", azArg[0]); - j = 0; - for(i=0; IsSpace(z[i]); i++){} - for(; (c = z[i])!=0; i++){ - if( IsSpace(c) ){ - if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; - }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ - j--; - } - z[j++] = c; - } - while( j>0 && IsSpace(z[j-1]) ){ j--; } - z[j] = 0; - if( strlen30(z)>=79 ){ - for(i=j=0; (c = z[i])!=0; i++){ - if( c==cEnd ){ - cEnd = 0; - }else if( c=='"' || c=='\'' || c=='`' ){ - cEnd = c; - }else if( c=='[' ){ - cEnd = ']'; - }else if( c=='(' ){ - nParen++; - }else if( c==')' ){ - nParen--; - if( nLine>0 && nParen==0 && j>0 ){ - utf8_printf(p->out, "%.*s\n", j, z); - j = 0; - } - } - z[j++] = c; - if( nParen==1 && (c=='(' || c==',' || c=='\n') ){ - if( c=='\n' ) j--; - utf8_printf(p->out, "%.*s\n ", j, z); - j = 0; - nLine++; - while( IsSpace(z[i+1]) ){ i++; } - } - } - z[j] = 0; - } - utf8_printf(p->out, "%s;\n", z); - sqlite3_free(z); - break; - } - case MODE_List: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,"%s%s",azCol[i], - i==nArg-1 ? p->rowSeparator : p->colSeparator); - } - } - if( azArg==0 ) break; - for(i=0; inullValue; - utf8_printf(p->out, "%s", z); - if( iout, "%s", p->colSeparator); - }else{ - utf8_printf(p->out, "%s", p->rowSeparator); - } - } - break; - } - case MODE_Html: { - if( p->cnt++==0 && p->showHeader ){ - raw_printf(p->out,""); - for(i=0; iout,""); - output_html_string(p->out, azCol[i]); - raw_printf(p->out,"\n"); - } - raw_printf(p->out,"\n"); - } - if( azArg==0 ) break; - raw_printf(p->out,""); - for(i=0; iout,""); - output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); - raw_printf(p->out,"\n"); - } - raw_printf(p->out,"\n"); - break; - } - case MODE_Tcl: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout,azCol[i] ? azCol[i] : ""); - if(iout, "%s", p->colSeparator); - } - utf8_printf(p->out, "%s", p->rowSeparator); - } - if( azArg==0 ) break; - for(i=0; iout, azArg[i] ? azArg[i] : p->nullValue); - if(iout, "%s", p->colSeparator); - } - utf8_printf(p->out, "%s", p->rowSeparator); - break; - } - case MODE_Csv: { - setBinaryMode(p->out, 1); - if( p->cnt++==0 && p->showHeader ){ - for(i=0; iout, "%s", p->rowSeparator); - } - if( nArg>0 ){ - for(i=0; iout, "%s", p->rowSeparator); - } - setTextMode(p->out, 1); - break; - } - case MODE_Insert: { - p->cnt++; - if( azArg==0 ) break; - utf8_printf(p->out,"INSERT INTO %s",p->zDestTable); - if( p->showHeader ){ - raw_printf(p->out,"("); - for(i=0; i0 ? ",": ""; - utf8_printf(p->out, "%s%s", zSep, azCol[i]); - } - raw_printf(p->out,")"); - } - raw_printf(p->out," VALUES("); - for(i=0; i0 ? ",": ""; - if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ - utf8_printf(p->out,"%sNULL",zSep); - }else if( aiType && aiType[i]==SQLITE_TEXT ){ - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); - output_quoted_string(p->out, azArg[i]); - }else if( aiType && (aiType[i]==SQLITE_INTEGER - || aiType[i]==SQLITE_FLOAT) ){ - utf8_printf(p->out,"%s%s",zSep, azArg[i]); - }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ - const void *pBlob = sqlite3_column_blob(p->pStmt, i); - int nBlob = sqlite3_column_bytes(p->pStmt, i); - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); - output_hex_blob(p->out, pBlob, nBlob); - }else if( isNumber(azArg[i], 0) ){ - utf8_printf(p->out,"%s%s",zSep, azArg[i]); - }else{ - if( zSep[0] ) utf8_printf(p->out,"%s",zSep); - output_quoted_string(p->out, azArg[i]); - } - } - raw_printf(p->out,");\n"); - break; - } - case MODE_Ascii: { - if( p->cnt++==0 && p->showHeader ){ - for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); - utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : ""); - } - utf8_printf(p->out, "%s", p->rowSeparator); - } - if( azArg==0 ) break; - for(i=0; i0 ) utf8_printf(p->out, "%s", p->colSeparator); - utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); - } - utf8_printf(p->out, "%s", p->rowSeparator); - break; - } - } - return 0; -} - -/* -** This is the callback routine that the SQLite library -** invokes for each row of a query result. -*/ -static int callback(void *pArg, int nArg, char **azArg, char **azCol){ - /* since we don't have type info, call the shell_callback with a NULL value */ - return shell_callback(pArg, nArg, azArg, azCol, NULL); -} - -/* -** Set the destination table field of the ShellState structure to -** the name of the table given. Escape any quote characters in the -** table name. -*/ -static void set_table_name(ShellState *p, const char *zName){ - int i, n; - int needQuote; - char *z; - - if( p->zDestTable ){ - free(p->zDestTable); - p->zDestTable = 0; - } - if( zName==0 ) return; - needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; - for(i=n=0; zName[i]; i++, n++){ - if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ - needQuote = 1; - if( zName[i]=='\'' ) n++; - } - } - if( needQuote ) n += 2; - z = p->zDestTable = malloc( n+1 ); - if( z==0 ){ - raw_printf(stderr,"Error: out of memory\n"); - exit(1); - } - n = 0; - if( needQuote ) z[n++] = '\''; - for(i=0; zName[i]; i++){ - z[n++] = zName[i]; - if( zName[i]=='\'' ) z[n++] = '\''; - } - if( needQuote ) z[n++] = '\''; - z[n] = 0; -} - -/* zIn is either a pointer to a NULL-terminated string in memory obtained -** from malloc(), or a NULL pointer. The string pointed to by zAppend is -** added to zIn, and the result returned in memory obtained from malloc(). -** zIn, if it was not NULL, is freed. -** -** If the third argument, quote, is not '\0', then it is used as a -** quote character for zAppend. -*/ -static char *appendText(char *zIn, char const *zAppend, char quote){ - int len; - int i; - int nAppend = strlen30(zAppend); - int nIn = (zIn?strlen30(zIn):0); - - len = nAppend+nIn+1; - if( quote ){ - len += 2; - for(i=0; idb, zSelect, -1, &pSelect, 0); - if( rc!=SQLITE_OK || !pSelect ){ - utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, - sqlite3_errmsg(p->db)); - if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; - return rc; - } - rc = sqlite3_step(pSelect); - nResult = sqlite3_column_count(pSelect); - while( rc==SQLITE_ROW ){ - if( zFirstRow ){ - utf8_printf(p->out, "%s", zFirstRow); - zFirstRow = 0; - } - z = (const char*)sqlite3_column_text(pSelect, 0); - utf8_printf(p->out, "%s", z); - for(i=1; iout, ",%s", sqlite3_column_text(pSelect, i)); - } - if( z==0 ) z = ""; - while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; - if( z[0] ){ - raw_printf(p->out, "\n;\n"); - }else{ - raw_printf(p->out, ";\n"); - } - rc = sqlite3_step(pSelect); - } - rc = sqlite3_finalize(pSelect); - if( rc!=SQLITE_OK ){ - utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, - sqlite3_errmsg(p->db)); - if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; - } - return rc; -} - -/* -** Allocate space and save off current error string. -*/ -static char *save_err_msg( - sqlite3 *db /* Database to query */ -){ - int nErrMsg = 1+strlen30(sqlite3_errmsg(db)); - char *zErrMsg = sqlite3_malloc64(nErrMsg); - if( zErrMsg ){ - memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg); - } - return zErrMsg; -} - -#ifdef __linux__ -/* -** Attempt to display I/O stats on Linux using /proc/PID/io -*/ -static void displayLinuxIoStats(FILE *out){ - FILE *in; - char z[200]; - sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); - in = fopen(z, "rb"); - if( in==0 ) return; - while( fgets(z, sizeof(z), in)!=0 ){ - static const struct { - const char *zPattern; - const char *zDesc; - } aTrans[] = { - { "rchar: ", "Bytes received by read():" }, - { "wchar: ", "Bytes sent to write():" }, - { "syscr: ", "Read() system calls:" }, - { "syscw: ", "Write() system calls:" }, - { "read_bytes: ", "Bytes read from storage:" }, - { "write_bytes: ", "Bytes written to storage:" }, - { "cancelled_write_bytes: ", "Cancelled write bytes:" }, - }; - int i; - for(i=0; iout ){ - - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Memory Used: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n", - iCur, iHiwtr); - if( pArg->shellFlgs & SHFLG_Pagecache ){ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Pcache Pages Used: %d (max %d) pages\n", - iCur, iHiwtr); - } - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); - if( pArg->shellFlgs & SHFLG_Scratch ){ - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Scratch Allocations Used: %d (max %d)\n", - iCur, iHiwtr); - } - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Allocation: %d bytes\n", - iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n", - iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n", - iHiwtr); -#ifdef YYTRACKMAXSTACKDEPTH - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n", - iCur, iHiwtr); -#endif - } - - if( pArg && pArg->out && db ){ - if( pArg->shellFlgs & SHFLG_Lookaside ){ - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, - "Lookaside Slots Used: %d (max %d)\n", - iCur, iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Successful lookaside attempts: %d\n", - iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Lookaside failures due to size: %d\n", - iHiwtr); - sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, - &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n", - iHiwtr); - } - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n", - iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache hits: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache misses: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); - raw_printf(pArg->out, "Page cache writes: %d\n", iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n", - iCur); - iHiwtr = iCur = -1; - sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); - raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n", - iCur); - } - - if( pArg && pArg->out && db && pArg->pStmt ){ - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, - bReset); - raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); - raw_printf(pArg->out, "Sort Operations: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); - raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); - raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); - } - -#ifdef __linux__ - displayLinuxIoStats(pArg->out); -#endif - - /* Do not remove this machine readable comment: extra-stats-output-here */ - - return 0; -} - -/* -** Display scan stats. -*/ -static void display_scanstats( - sqlite3 *db, /* Database to query */ - ShellState *pArg /* Pointer to ShellState */ -){ -#ifndef SQLITE_ENABLE_STMT_SCANSTATUS - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(pArg); -#else - int i, k, n, mx; - raw_printf(pArg->out, "-------- scanstats --------\n"); - mx = 0; - for(k=0; k<=mx; k++){ - double rEstLoop = 1.0; - for(i=n=0; 1; i++){ - sqlite3_stmt *p = pArg->pStmt; - sqlite3_int64 nLoop, nVisit; - double rEst; - int iSid; - const char *zExplain; - if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){ - break; - } - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid); - if( iSid>mx ) mx = iSid; - if( iSid!=k ) continue; - if( n==0 ){ - rEstLoop = (double)nLoop; - if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k); - } - n++; - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst); - sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); - utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain); - rEstLoop *= rEst; - raw_printf(pArg->out, - " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n", - nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst - ); - } - } - raw_printf(pArg->out, "---------------------------\n"); -#endif -} - -/* -** Parameter azArray points to a zero-terminated array of strings. zStr -** points to a single nul-terminated string. Return non-zero if zStr -** is equal, according to strcmp(), to any of the strings in the array. -** Otherwise, return zero. -*/ -static int str_in_array(const char *zStr, const char **azArray){ - int i; - for(i=0; azArray[i]; i++){ - if( 0==strcmp(zStr, azArray[i]) ) return 1; - } - return 0; -} - -/* -** If compiled statement pSql appears to be an EXPLAIN statement, allocate -** and populate the ShellState.aiIndent[] array with the number of -** spaces each opcode should be indented before it is output. -** -** The indenting rules are: -** -** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent -** all opcodes that occur between the p2 jump destination and the opcode -** itself by 2 spaces. -** -** * For each "Goto", if the jump destination is earlier in the program -** and ends on one of: -** Yield SeekGt SeekLt RowSetRead Rewind -** or if the P1 parameter is one instead of zero, -** then indent all opcodes between the earlier instruction -** and "Goto" by 2 spaces. -*/ -static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ - const char *zSql; /* The text of the SQL statement */ - const char *z; /* Used to check if this is an EXPLAIN */ - int *abYield = 0; /* True if op is an OP_Yield */ - int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ - int iOp; /* Index of operation in p->aiIndent[] */ - - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", - "NextIfOpen", "PrevIfOpen", 0 }; - const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", - "Rewind", 0 }; - const char *azGoto[] = { "Goto", 0 }; - - /* Try to figure out if this is really an EXPLAIN statement. If this - ** cannot be verified, return early. */ - if( sqlite3_column_count(pSql)!=8 ){ - p->cMode = p->mode; - return; - } - zSql = sqlite3_sql(pSql); - if( zSql==0 ) return; - for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); - if( sqlite3_strnicmp(z, "explain", 7) ){ - p->cMode = p->mode; - return; - } - - for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ - int i; - int iAddr = sqlite3_column_int(pSql, 0); - const char *zOp = (const char*)sqlite3_column_text(pSql, 1); - - /* Set p2 to the P2 field of the current opcode. Then, assuming that - ** p2 is an instruction address, set variable p2op to the index of that - ** instruction in the aiIndent[] array. p2 and p2op may be different if - ** the current instruction is part of a sub-program generated by an - ** SQL trigger or foreign key. */ - int p2 = sqlite3_column_int(pSql, 3); - int p2op = (p2 + (iOp-iAddr)); - - /* Grow the p->aiIndent array as required */ - if( iOp>=nAlloc ){ - if( iOp==0 ){ - /* Do further verfication that this is explain output. Abort if - ** it is not */ - static const char *explainCols[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" }; - int jj; - for(jj=0; jjcMode = p->mode; - sqlite3_reset(pSql); - return; - } - } - } - nAlloc += 100; - p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); - abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); - } - abYield[iOp] = str_in_array(zOp, azYield); - p->aiIndent[iOp] = 0; - p->nIndent = iOp+1; - - if( str_in_array(zOp, azNext) ){ - for(i=p2op; iaiIndent[i] += 2; - } - if( str_in_array(zOp, azGoto) && p2opnIndent - && (abYield[p2op] || sqlite3_column_int(pSql, 2)) - ){ - for(i=p2op; iaiIndent[i] += 2; - } - } - - p->iIndent = 0; - sqlite3_free(abYield); - sqlite3_reset(pSql); -} - -/* -** Free the array allocated by explain_data_prepare(). -*/ -static void explain_data_delete(ShellState *p){ - sqlite3_free(p->aiIndent); - p->aiIndent = 0; - p->nIndent = 0; - p->iIndent = 0; -} - -/* -** Disable and restore .wheretrace and .selecttrace settings. -*/ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern int sqlite3SelectTrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif -static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3SelectTrace; - sqlite3SelectTrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif -} -static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3SelectTrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif -} - -/* -** Run a prepared statement -*/ -static void exec_prepared_stmt( - ShellState *pArg, /* Pointer to ShellState */ - sqlite3_stmt *pStmt, /* Statment to run */ - int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */ -){ - int rc; - - /* perform the first step. this will tell us if we - ** have a result set or not and how wide it is. - */ - rc = sqlite3_step(pStmt); - /* if we have a result set... */ - if( SQLITE_ROW == rc ){ - /* if we have a callback... */ - if( xCallback ){ - /* allocate space for col name ptr, value ptr, and type */ - int nCol = sqlite3_column_count(pStmt); - void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); - if( !pData ){ - rc = SQLITE_NOMEM; - }else{ - char **azCols = (char **)pData; /* Names of result columns */ - char **azVals = &azCols[nCol]; /* Results */ - int *aiTypes = (int *)&azVals[nCol]; /* Result types */ - int i, x; - assert(sizeof(int) <= sizeof(char *)); - /* save off ptrs to column names */ - for(i=0; icMode==MODE_Insert ){ - azVals[i] = ""; - }else{ - azVals[i] = (char*)sqlite3_column_text(pStmt, i); - } - if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ - rc = SQLITE_NOMEM; - break; /* from for */ - } - } /* end for */ - - /* if data and types extracted successfully... */ - if( SQLITE_ROW == rc ){ - /* call the supplied callback with the result row data */ - if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){ - rc = SQLITE_ABORT; - }else{ - rc = sqlite3_step(pStmt); - } - } - } while( SQLITE_ROW == rc ); - sqlite3_free(pData); - } - }else{ - do{ - rc = sqlite3_step(pStmt); - } while( rc == SQLITE_ROW ); - } - } -} - -/* -** Execute a statement or set of statements. Print -** any result rows/columns depending on the current mode -** set via the supplied callback. -** -** This is very similar to SQLite's built-in sqlite3_exec() -** function except it takes a slightly different callback -** and callback data argument. -*/ -static int shell_exec( - sqlite3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */ - /* (not the same as sqlite3_exec) */ - ShellState *pArg, /* Pointer to ShellState */ - char **pzErrMsg /* Error msg written here */ -){ - sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ - int rc = SQLITE_OK; /* Return Code */ - int rc2; - const char *zLeftover; /* Tail of unprocessed SQL */ - - if( pzErrMsg ){ - *pzErrMsg = NULL; - } - - while( zSql[0] && (SQLITE_OK == rc) ){ - static const char *zStmtSql; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); - if( SQLITE_OK != rc ){ - if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - }else{ - if( !pStmt ){ - /* this happens for a comment or white-space */ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - continue; - } - zStmtSql = sqlite3_sql(pStmt); - while( IsSpace(zStmtSql[0]) ) zStmtSql++; - - /* save off the prepared statment handle and reset row count */ - if( pArg ){ - pArg->pStmt = pStmt; - pArg->cnt = 0; - } - - /* echo the sql statement if echo on */ - if( pArg && pArg->echoOn ){ - utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); - } - - /* Show the EXPLAIN QUERY PLAN if .eqp is on */ - if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){ - sqlite3_stmt *pExplain; - char *zEQP; - disable_debug_trace_modes(); - zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc==SQLITE_OK ){ - while( sqlite3_step(pExplain)==SQLITE_ROW ){ - raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1)); - raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2)); - utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3)); - } - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); - if( pArg->autoEQP>=2 ){ - /* Also do an EXPLAIN for ".eqp full" mode */ - zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); - if( rc==SQLITE_OK ){ - pArg->cMode = MODE_Explain; - explain_data_prepare(pArg, pExplain); - exec_prepared_stmt(pArg, pExplain, xCallback); - explain_data_delete(pArg); - } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); - } - restore_debug_trace_modes(); - } - - if( pArg ){ - pArg->cMode = pArg->mode; - if( pArg->autoExplain - && sqlite3_column_count(pStmt)==8 - && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0 - ){ - pArg->cMode = MODE_Explain; - } - - /* If the shell is currently in ".explain" mode, gather the extra - ** data required to add indents to the output.*/ - if( pArg->cMode==MODE_Explain ){ - explain_data_prepare(pArg, pStmt); - } - } - - exec_prepared_stmt(pArg, pStmt, xCallback); - explain_data_delete(pArg); - - /* print usage stats if stats on */ - if( pArg && pArg->statsOn ){ - display_stats(db, pArg, 0); - } - - /* print loop-counters if required */ - if( pArg && pArg->scanstatsOn ){ - display_scanstats(db, pArg); - } - - /* Finalize the statement just executed. If this fails, save a - ** copy of the error message. Otherwise, set zSql to point to the - ** next statement to execute. */ - rc2 = sqlite3_finalize(pStmt); - if( rc!=SQLITE_NOMEM ) rc = rc2; - if( rc==SQLITE_OK ){ - zSql = zLeftover; - while( IsSpace(zSql[0]) ) zSql++; - }else if( pzErrMsg ){ - *pzErrMsg = save_err_msg(db); - } - - /* clear saved stmt handle */ - if( pArg ){ - pArg->pStmt = NULL; - } - } - } /* end while */ - - return rc; -} - - -/* -** This is a different callback routine used for dumping the database. -** Each row received by this callback consists of a table name, -** the table type ("index" or "table") and SQL to create the table. -** This routine should print text sufficient to recreate the table. -*/ -static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ - int rc; - const char *zTable; - const char *zType; - const char *zSql; - const char *zPrepStmt = 0; - ShellState *p = (ShellState *)pArg; - - UNUSED_PARAMETER(azCol); - if( nArg!=3 ) return 1; - zTable = azArg[0]; - zType = azArg[1]; - zSql = azArg[2]; - - if( strcmp(zTable, "sqlite_sequence")==0 ){ - zPrepStmt = "DELETE FROM sqlite_sequence;\n"; - }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){ - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - }else if( strncmp(zTable, "sqlite_", 7)==0 ){ - return 0; - }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ - char *zIns; - if( !p->writableSchema ){ - raw_printf(p->out, "PRAGMA writable_schema=ON;\n"); - p->writableSchema = 1; - } - zIns = sqlite3_mprintf( - "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" - "VALUES('table','%q','%q',0,'%q');", - zTable, zTable, zSql); - utf8_printf(p->out, "%s\n", zIns); - sqlite3_free(zIns); - return 0; - }else{ - utf8_printf(p->out, "%s;\n", zSql); - } - - if( strcmp(zType, "table")==0 ){ - sqlite3_stmt *pTableInfo = 0; - char *zSelect = 0; - char *zTableInfo = 0; - char *zTmp = 0; - int nRow = 0; - - zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); - zTableInfo = appendText(zTableInfo, zTable, '"'); - zTableInfo = appendText(zTableInfo, ");", 0); - - rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0); - free(zTableInfo); - if( rc!=SQLITE_OK || !pTableInfo ){ - return 1; - } - - zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); - /* Always quote the table name, even if it appears to be pure ascii, - ** in case it is a keyword. Ex: INSERT INTO "table" ... */ - zTmp = appendText(zTmp, zTable, '"'); - if( zTmp ){ - zSelect = appendText(zSelect, zTmp, '\''); - free(zTmp); - } - zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); - rc = sqlite3_step(pTableInfo); - while( rc==SQLITE_ROW ){ - const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); - zSelect = appendText(zSelect, "quote(", 0); - zSelect = appendText(zSelect, zText, '"'); - rc = sqlite3_step(pTableInfo); - if( rc==SQLITE_ROW ){ - zSelect = appendText(zSelect, "), ", 0); - }else{ - zSelect = appendText(zSelect, ") ", 0); - } - nRow++; - } - rc = sqlite3_finalize(pTableInfo); - if( rc!=SQLITE_OK || nRow==0 ){ - free(zSelect); - return 1; - } - zSelect = appendText(zSelect, "|| ')' FROM ", 0); - zSelect = appendText(zSelect, zTable, '"'); - - rc = run_table_dump_query(p, zSelect, zPrepStmt); - if( rc==SQLITE_CORRUPT ){ - zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); - run_table_dump_query(p, zSelect, 0); - } - free(zSelect); - } - return 0; -} - -/* -** Run zQuery. Use dump_callback() as the callback routine so that -** the contents of the query are output as SQL statements. -** -** If we get a SQLITE_CORRUPT error, rerun the query after appending -** "ORDER BY rowid DESC" to the end. -*/ -static int run_schema_dump_query( - ShellState *p, - const char *zQuery -){ - int rc; - char *zErr = 0; - rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); - if( rc==SQLITE_CORRUPT ){ - char *zQ2; - int len = strlen30(zQuery); - raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n"); - if( zErr ){ - utf8_printf(p->out, "/****** %s ******/\n", zErr); - sqlite3_free(zErr); - zErr = 0; - } - zQ2 = malloc( len+100 ); - if( zQ2==0 ) return rc; - sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); - rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); - if( rc ){ - utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr); - }else{ - rc = SQLITE_CORRUPT; - } - sqlite3_free(zErr); - free(zQ2); - } - return rc; -} - -/* -** Text of a help message -*/ -static char zHelp[] = -#ifndef SQLITE_OMIT_AUTHORIZATION - ".auth ON|OFF Show authorizer callbacks\n" -#endif - ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" - ".bail on|off Stop after hitting an error. Default OFF\n" - ".binary on|off Turn binary output on or off. Default OFF\n" - ".changes on|off Show number of rows changed by SQL\n" - ".check GLOB Fail if output since .testcase does not match\n" - ".clone NEWDB Clone data into NEWDB from the existing database\n" - ".databases List names and files of attached databases\n" - ".dbinfo ?DB? Show status information about the database\n" - ".dump ?TABLE? ... Dump the database in an SQL text format\n" - " If TABLE specified, only dump tables matching\n" - " LIKE pattern TABLE.\n" - ".echo on|off Turn command echo on or off\n" - ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n" - ".exit Exit this program\n" - ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n" - ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n" - ".headers on|off Turn display of headers on or off\n" - ".help Show this message\n" - ".import FILE TABLE Import data from FILE into TABLE\n" - ".indexes ?TABLE? Show names of all indexes\n" - " If TABLE specified, only show indexes for tables\n" - " matching LIKE pattern TABLE.\n" -#ifdef SQLITE_ENABLE_IOTRACE - ".iotrace FILE Enable I/O diagnostic logging to FILE\n" -#endif - ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n" -#ifndef SQLITE_OMIT_LOAD_EXTENSION - ".load FILE ?ENTRY? Load an extension library\n" -#endif - ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n" - ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" - " ascii Columns/rows delimited by 0x1F and 0x1E\n" - " csv Comma-separated values\n" - " column Left-aligned columns. (See .width)\n" - " html HTML code\n" - " insert SQL insert statements for TABLE\n" - " line One value per line\n" - " list Values delimited by .separator strings\n" - " tabs Tab-separated values\n" - " tcl TCL list elements\n" - ".nullvalue STRING Use STRING in place of NULL values\n" - ".once FILENAME Output for the next SQL command only to FILENAME\n" - ".open ?--new? ?FILE? Close existing database and reopen FILE\n" - " The --new starts with an empty file\n" - ".output ?FILENAME? Send output to FILENAME or stdout\n" - ".print STRING... Print literal STRING\n" - ".prompt MAIN CONTINUE Replace the standard prompts\n" - ".quit Exit this program\n" - ".read FILENAME Execute SQL in FILENAME\n" - ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" - ".save FILE Write in-memory database into FILE\n" - ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n" - ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n" - " Add --indent for pretty-printing\n" - ".separator COL ?ROW? Change the column separator and optionally the row\n" - " separator for both the output mode and .import\n" -#if defined(SQLITE_ENABLE_SESSION) - ".session CMD ... Create or control sessions\n" -#endif - ".shell CMD ARGS... Run CMD ARGS... in a system shell\n" - ".show Show the current values for various settings\n" - ".stats ?on|off? Show stats or turn stats on or off\n" - ".system CMD ARGS... Run CMD ARGS... in a system shell\n" - ".tables ?TABLE? List names of tables\n" - " If TABLE specified, only list tables matching\n" - " LIKE pattern TABLE.\n" - ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n" - ".timeout MS Try opening locked tables for MS milliseconds\n" - ".timer on|off Turn SQL timer on or off\n" - ".trace FILE|off Output each SQL statement as it is run\n" - ".vfsinfo ?AUX? Information about the top-level VFS\n" - ".vfslist List all available VFSes\n" - ".vfsname ?AUX? Print the name of the VFS stack\n" - ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" - " Negative values right-justify\n" -; - -#if defined(SQLITE_ENABLE_SESSION) -/* -** Print help information for the ".sessions" command -*/ -void session_help(ShellState *p){ - raw_printf(p->out, - ".session ?NAME? SUBCOMMAND ?ARGS...?\n" - "If ?NAME? is omitted, the first defined session is used.\n" - "Subcommands:\n" - " attach TABLE Attach TABLE\n" - " changeset FILE Write a changeset into FILE\n" - " close Close one session\n" - " enable ?BOOLEAN? Set or query the enable bit\n" - " filter GLOB... Reject tables matching GLOBs\n" - " indirect ?BOOLEAN? Mark or query the indirect status\n" - " isempty Query whether the session is empty\n" - " list List currently open session names\n" - " open DB NAME Open a new session on DB\n" - " patchset FILE Write a patchset into FILE\n" - ); -} -#endif - - -/* Forward reference */ -static int process_input(ShellState *p, FILE *in); - - -/* -** Read the content of a file into memory obtained from sqlite3_malloc64(). -** The caller is responsible for freeing the memory. -** -** NULL is returned if any error is encountered. -*/ -static char *readFile(const char *zName){ - FILE *in = fopen(zName, "rb"); - long nIn; - size_t nRead; - char *pBuf; - if( in==0 ) return 0; - fseek(in, 0, SEEK_END); - nIn = ftell(in); - rewind(in); - pBuf = sqlite3_malloc64( nIn+1 ); - if( pBuf==0 ) return 0; - nRead = fread(pBuf, nIn, 1, in); - fclose(in); - if( nRead!=1 ){ - sqlite3_free(pBuf); - return 0; - } - pBuf[nIn] = 0; - return pBuf; -} - -/* -** Implementation of the "readfile(X)" SQL function. The entire content -** of the file named X is read and returned as a BLOB. NULL is returned -** if the file does not exist or is unreadable. -*/ -static void readfileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *zName; - void *pBuf; - - UNUSED_PARAMETER(argc); - zName = (const char*)sqlite3_value_text(argv[0]); - if( zName==0 ) return; - pBuf = readFile(zName); - if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free); -} - -/* -** Implementation of the "writefile(X,Y)" SQL function. The argument Y -** is written into file X. The number of bytes written is returned. Or -** NULL is returned if something goes wrong, such as being unable to open -** file X for writing. -*/ -static void writefileFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - FILE *out; - const char *z; - sqlite3_int64 rc; - const char *zFile; - - UNUSED_PARAMETER(argc); - zFile = (const char*)sqlite3_value_text(argv[0]); - if( zFile==0 ) return; - out = fopen(zFile, "wb"); - if( out==0 ) return; - z = (const char*)sqlite3_value_blob(argv[1]); - if( z==0 ){ - rc = 0; - }else{ - rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out); - } - fclose(out); - sqlite3_result_int64(context, rc); -} - -#if defined(SQLITE_ENABLE_SESSION) -/* -** Close a single OpenSession object and release all of its associated -** resources. -*/ -static void session_close(OpenSession *pSession){ - int i; - sqlite3session_delete(pSession->p); - sqlite3_free(pSession->zName); - for(i=0; inFilter; i++){ - sqlite3_free(pSession->azFilter[i]); - } - sqlite3_free(pSession->azFilter); - memset(pSession, 0, sizeof(OpenSession)); -} -#endif - -/* -** Close all OpenSession objects and release all associated resources. -*/ -#if defined(SQLITE_ENABLE_SESSION) -static void session_close_all(ShellState *p){ - int i; - for(i=0; inSession; i++){ - session_close(&p->aSession[i]); - } - p->nSession = 0; -} -#else -# define session_close_all(X) -#endif - -/* -** Implementation of the xFilter function for an open session. Omit -** any tables named by ".session filter" but let all other table through. -*/ -#if defined(SQLITE_ENABLE_SESSION) -static int session_filter(void *pCtx, const char *zTab){ - OpenSession *pSession = (OpenSession*)pCtx; - int i; - for(i=0; inFilter; i++){ - if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; - } - return 1; -} -#endif - -/* -** Make sure the database is open. If it is not, then open it. If -** the database fails to open, print an error message and exit. -*/ -static void open_db(ShellState *p, int keepAlive){ - if( p->db==0 ){ - sqlite3_initialize(); - sqlite3_open(p->zDbFilename, &p->db); - globalDb = p->db; - if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){ - sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0, - shellstaticFunc, 0, 0); - } - if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ - utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", - p->zDbFilename, sqlite3_errmsg(p->db)); - if( keepAlive ) return; - exit(1); - } -#ifndef SQLITE_OMIT_LOAD_EXTENSION - sqlite3_enable_load_extension(p->db, 1); -#endif - sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0, - readfileFunc, 0, 0); - sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0, - writefileFunc, 0, 0); - } -} - -/* -** Do C-language style dequoting. -** -** \a -> alarm -** \b -> backspace -** \t -> tab -** \n -> newline -** \v -> vertical tab -** \f -> form feed -** \r -> carriage return -** \s -> space -** \" -> " -** \' -> ' -** \\ -> backslash -** \NNN -> ascii character NNN in octal -*/ -static void resolve_backslashes(char *z){ - int i, j; - char c; - while( *z && *z!='\\' ) z++; - for(i=j=0; (c = z[i])!=0; i++, j++){ - if( c=='\\' && z[i+1]!=0 ){ - c = z[++i]; - if( c=='a' ){ - c = '\a'; - }else if( c=='b' ){ - c = '\b'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='v' ){ - c = '\v'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='"' ){ - c = '"'; - }else if( c=='\'' ){ - c = '\''; - }else if( c=='\\' ){ - c = '\\'; - }else if( c>='0' && c<='7' ){ - c -= '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - if( z[i+1]>='0' && z[i+1]<='7' ){ - i++; - c = (c<<3) + z[i] - '0'; - } - } - } - } - z[j] = c; - } - if( j='0' && c<='9' ) return c - '0'; - if( c>='a' && c<='f' ) return c - 'a' + 10; - if( c>='A' && c<='F' ) return c - 'A' + 10; - return -1; -} - -/* -** Interpret zArg as an integer value, possibly with suffixes. -*/ -static sqlite3_int64 integerValue(const char *zArg){ - sqlite3_int64 v = 0; - static const struct { char *zSuffix; int iMult; } aMult[] = { - { "KiB", 1024 }, - { "MiB", 1024*1024 }, - { "GiB", 1024*1024*1024 }, - { "KB", 1000 }, - { "MB", 1000000 }, - { "GB", 1000000000 }, - { "K", 1000 }, - { "M", 1000000 }, - { "G", 1000000000 }, - }; - int i; - int isNeg = 0; - if( zArg[0]=='-' ){ - isNeg = 1; - zArg++; - }else if( zArg[0]=='+' ){ - zArg++; - } - if( zArg[0]=='0' && zArg[1]=='x' ){ - int x; - zArg += 2; - while( (x = hexDigitValue(zArg[0]))>=0 ){ - v = (v<<4) + x; - zArg++; - } - }else{ - while( IsDigit(zArg[0]) ){ - v = v*10 + zArg[0] - '0'; - zArg++; - } - } - for(i=0; i=0; i++){} - }else{ - for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} - } - if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); - if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ - return 1; - } - if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ - return 0; - } - utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", - zArg); - return 0; -} - -/* -** Close an output file, assuming it is not stderr or stdout -*/ -static void output_file_close(FILE *f){ - if( f && f!=stdout && f!=stderr ) fclose(f); -} - -/* -** Try to open an output file. The names "stdout" and "stderr" are -** recognized and do the right thing. NULL is returned if the output -** filename is "off". -*/ -static FILE *output_file_open(const char *zFile){ - FILE *f; - if( strcmp(zFile,"stdout")==0 ){ - f = stdout; - }else if( strcmp(zFile, "stderr")==0 ){ - f = stderr; - }else if( strcmp(zFile, "off")==0 ){ - f = 0; - }else{ - f = fopen(zFile, "wb"); - if( f==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - } - } - return f; -} - -/* -** A routine for handling output from sqlite3_trace(). -*/ -static int sql_trace_callback( - unsigned mType, - void *pArg, - void *pP, - void *pX -){ - FILE *f = (FILE*)pArg; - UNUSED_PARAMETER(mType); - UNUSED_PARAMETER(pP); - if( f ){ - const char *z = (const char*)pX; - int i = (int)strlen(z); - while( i>0 && z[i-1]==';' ){ i--; } - utf8_printf(f, "%.*s;\n", i, z); - } - return 0; -} - -/* -** A no-op routine that runs with the ".breakpoint" doc-command. This is -** a useful spot to set a debugger breakpoint. -*/ -static void test_breakpoint(void){ - static int nCall = 0; - nCall++; -} - -/* -** An object used to read a CSV and other files for import. -*/ -typedef struct ImportCtx ImportCtx; -struct ImportCtx { - const char *zFile; /* Name of the input file */ - FILE *in; /* Read the CSV text from this input stream */ - char *z; /* Accumulated text for a field */ - int n; /* Number of bytes in z */ - int nAlloc; /* Space allocated for z[] */ - int nLine; /* Current line number */ - int cTerm; /* Character that terminated the most recent field */ - int cColSep; /* The column separator character. (Usually ",") */ - int cRowSep; /* The row separator character. (Usually "\n") */ -}; - -/* Append a single byte to z[] */ -static void import_append_char(ImportCtx *p, int c){ - if( p->n+1>=p->nAlloc ){ - p->nAlloc += p->nAlloc + 100; - p->z = sqlite3_realloc64(p->z, p->nAlloc); - if( p->z==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } - } - p->z[p->n++] = (char)c; -} - -/* Read a single field of CSV text. Compatible with rfc4180 and extended -** with the option of having a separator other than ",". -** -** + Input comes from p->in. -** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc64(). -** + Use p->cSep as the column separator. The default is ",". -** + Use p->rSep as the row separator. The default is "\n". -** + Keep track of the line number in p->nLine. -** + Store the character that terminates the field in p->cTerm. Store -** EOF on end-of-file. -** + Report syntax errors on stderr -*/ -static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ - int c; - int cSep = p->cColSep; - int rSep = p->cRowSep; - p->n = 0; - c = fgetc(p->in); - if( c==EOF || seenInterrupt ){ - p->cTerm = EOF; - return 0; - } - if( c=='"' ){ - int pc, ppc; - int startLine = p->nLine; - int cQuote = c; - pc = ppc = 0; - while( 1 ){ - c = fgetc(p->in); - if( c==rSep ) p->nLine++; - if( c==cQuote ){ - if( pc==cQuote ){ - pc = 0; - continue; - } - } - if( (c==cSep && pc==cQuote) - || (c==rSep && pc==cQuote) - || (c==rSep && pc=='\r' && ppc==cQuote) - || (c==EOF && pc==cQuote) - ){ - do{ p->n--; }while( p->z[p->n]!=cQuote ); - p->cTerm = c; - break; - } - if( pc==cQuote && c!='\r' ){ - utf8_printf(stderr, "%s:%d: unescaped %c character\n", - p->zFile, p->nLine, cQuote); - } - if( c==EOF ){ - utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n", - p->zFile, startLine, cQuote); - p->cTerm = c; - break; - } - import_append_char(p, c); - ppc = pc; - pc = c; - } - }else{ - while( c!=EOF && c!=cSep && c!=rSep ){ - import_append_char(p, c); - c = fgetc(p->in); - } - if( c==rSep ){ - p->nLine++; - if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; - } - p->cTerm = c; - } - if( p->z ) p->z[p->n] = 0; - return p->z; -} - -/* Read a single field of ASCII delimited text. -** -** + Input comes from p->in. -** + Store results in p->z of length p->n. Space to hold p->z comes -** from sqlite3_malloc64(). -** + Use p->cSep as the column separator. The default is "\x1F". -** + Use p->rSep as the row separator. The default is "\x1E". -** + Keep track of the row number in p->nLine. -** + Store the character that terminates the field in p->cTerm. Store -** EOF on end-of-file. -** + Report syntax errors on stderr -*/ -static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ - int c; - int cSep = p->cColSep; - int rSep = p->cRowSep; - p->n = 0; - c = fgetc(p->in); - if( c==EOF || seenInterrupt ){ - p->cTerm = EOF; - return 0; - } - while( c!=EOF && c!=cSep && c!=rSep ){ - import_append_char(p, c); - c = fgetc(p->in); - } - if( c==rSep ){ - p->nLine++; - } - p->cTerm = c; - if( p->z ) p->z[p->n] = 0; - return p->z; -} - -/* -** Try to transfer data for table zTable. If an error is seen while -** moving forward, try to go backwards. The backwards movement won't -** work for WITHOUT ROWID tables. -*/ -static void tryToCloneData( - ShellState *p, - sqlite3 *newDb, - const char *zTable -){ - sqlite3_stmt *pQuery = 0; - sqlite3_stmt *pInsert = 0; - char *zQuery = 0; - char *zInsert = 0; - int rc; - int i, j, n; - int nTable = (int)strlen(zTable); - int k = 0; - int cnt = 0; - const int spinRate = 10000; - - zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error %d: %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_data_xfer; - } - n = sqlite3_column_count(pQuery); - zInsert = sqlite3_malloc64(200 + nTable + n*3); - if( zInsert==0 ){ - raw_printf(stderr, "out of memory\n"); - goto end_data_xfer; - } - sqlite3_snprintf(200+nTable,zInsert, - "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); - i = (int)strlen(zInsert); - for(j=1; jdb, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable); - break; - } - } /* End for(k=0...) */ - -end_data_xfer: - sqlite3_finalize(pQuery); - sqlite3_finalize(pInsert); - sqlite3_free(zQuery); - sqlite3_free(zInsert); -} - - -/* -** Try to transfer all rows of the schema that match zWhere. For -** each row, invoke xForEach() on the object defined by that row. -** If an error is encountered while moving forward through the -** sqlite_master table, try again moving backwards. -*/ -static void tryToCloneSchema( - ShellState *p, - sqlite3 *newDb, - const char *zWhere, - void (*xForEach)(ShellState*,sqlite3*,const char*) -){ - sqlite3_stmt *pQuery = 0; - char *zQuery = 0; - int rc; - const unsigned char *zName; - const unsigned char *zSql; - char *zErrMsg = 0; - - zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" - " WHERE %s", zWhere); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error: (%d) %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_schema_xfer; - } - while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ - zName = sqlite3_column_text(pQuery, 0); - zSql = sqlite3_column_text(pQuery, 1); - printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); - sqlite3_free(zErrMsg); - zErrMsg = 0; - } - if( xForEach ){ - xForEach(p, newDb, (const char*)zName); - } - printf("done\n"); - } - if( rc!=SQLITE_DONE ){ - sqlite3_finalize(pQuery); - sqlite3_free(zQuery); - zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master" - " WHERE %s ORDER BY rowid DESC", zWhere); - rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); - if( rc ){ - utf8_printf(stderr, "Error: (%d) %s on [%s]\n", - sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), - zQuery); - goto end_schema_xfer; - } - while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ - zName = sqlite3_column_text(pQuery, 0); - zSql = sqlite3_column_text(pQuery, 1); - printf("%s... ", zName); fflush(stdout); - sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql); - sqlite3_free(zErrMsg); - zErrMsg = 0; - } - if( xForEach ){ - xForEach(p, newDb, (const char*)zName); - } - printf("done\n"); - } - } -end_schema_xfer: - sqlite3_finalize(pQuery); - sqlite3_free(zQuery); -} - -/* -** Open a new database file named "zNewDb". Try to recover as much information -** as possible out of the main database (which might be corrupt) and write it -** into zNewDb. -*/ -static void tryToClone(ShellState *p, const char *zNewDb){ - int rc; - sqlite3 *newDb = 0; - if( access(zNewDb,0)==0 ){ - utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb); - return; - } - rc = sqlite3_open(zNewDb, &newDb); - if( rc ){ - utf8_printf(stderr, "Cannot create output database: %s\n", - sqlite3_errmsg(newDb)); - }else{ - sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); - sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); - tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); - tryToCloneSchema(p, newDb, "type!='table'", 0); - sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - } - sqlite3_close(newDb); -} - -/* -** Change the output file back to stdout -*/ -static void output_reset(ShellState *p){ - if( p->outfile[0]=='|' ){ -#ifndef SQLITE_OMIT_POPEN - pclose(p->out); -#endif - }else{ - output_file_close(p->out); - } - p->outfile[0] = 0; - p->out = stdout; -} - -/* -** Run an SQL command and return the single integer result. -*/ -static int db_int(ShellState *p, const char *zSql){ - sqlite3_stmt *pStmt; - int res = 0; - sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ - res = sqlite3_column_int(pStmt,0); - } - sqlite3_finalize(pStmt); - return res; -} - -/* -** Convert a 2-byte or 4-byte big-endian integer into a native integer -*/ -static unsigned int get2byteInt(unsigned char *a){ - return (a[0]<<8) + a[1]; -} -static unsigned int get4byteInt(unsigned char *a){ - return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3]; -} - -/* -** Implementation of the ".info" command. -** -** Return 1 on error, 2 to exit, and 0 otherwise. -*/ -static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ - static const struct { const char *zName; int ofst; } aField[] = { - { "file change counter:", 24 }, - { "database page count:", 28 }, - { "freelist page count:", 36 }, - { "schema cookie:", 40 }, - { "schema format:", 44 }, - { "default cache size:", 48 }, - { "autovacuum top root:", 52 }, - { "incremental vacuum:", 64 }, - { "text encoding:", 56 }, - { "user version:", 60 }, - { "application id:", 68 }, - { "software version:", 96 }, - }; - static const struct { const char *zName; const char *zSql; } aQuery[] = { - { "number of tables:", - "SELECT count(*) FROM %s WHERE type='table'" }, - { "number of indexes:", - "SELECT count(*) FROM %s WHERE type='index'" }, - { "number of triggers:", - "SELECT count(*) FROM %s WHERE type='trigger'" }, - { "number of views:", - "SELECT count(*) FROM %s WHERE type='view'" }, - { "schema size:", - "SELECT total(length(sql)) FROM %s" }, - }; - sqlite3_file *pFile = 0; - int i; - char *zSchemaTab; - char *zDb = nArg>=2 ? azArg[1] : "main"; - unsigned char aHdr[100]; - open_db(p, 0); - if( p->db==0 ) return 1; - sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile); - if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){ - return 1; - } - i = pFile->pMethods->xRead(pFile, aHdr, 100, 0); - if( i!=SQLITE_OK ){ - raw_printf(stderr, "unable to read database header\n"); - return 1; - } - i = get2byteInt(aHdr+16); - if( i==1 ) i = 65536; - utf8_printf(p->out, "%-20s %d\n", "database page size:", i); - utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]); - utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]); - utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); - for(i=0; iout, "%-20s %u", aField[i].zName, val); - switch( ofst ){ - case 56: { - if( val==1 ) raw_printf(p->out, " (utf8)"); - if( val==2 ) raw_printf(p->out, " (utf16le)"); - if( val==3 ) raw_printf(p->out, " (utf16be)"); - } - } - raw_printf(p->out, "\n"); - } - if( zDb==0 ){ - zSchemaTab = sqlite3_mprintf("main.sqlite_master"); - }else if( strcmp(zDb,"temp")==0 ){ - zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master"); - }else{ - zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb); - } - for(i=0; iout, "%-20s %d\n", aQuery[i].zName, val); - } - sqlite3_free(zSchemaTab); - return 0; -} - -/* -** Print the current sqlite3_errmsg() value to stderr and return 1. -*/ -static int shellDatabaseError(sqlite3 *db){ - const char *zErr = sqlite3_errmsg(db); - utf8_printf(stderr, "Error: %s\n", zErr); - return 1; -} - -/* -** Print an out-of-memory message to stderr and return 1. -*/ -static int shellNomemError(void){ - raw_printf(stderr, "Error: out of memory\n"); - return 1; -} - -/* -** Compare the pattern in zGlob[] against the text in z[]. Return TRUE -** if they match and FALSE (0) if they do not match. -** -** Globbing rules: -** -** '*' Matches any sequence of zero or more characters. -** -** '?' Matches exactly one character. -** -** [...] Matches one character from the enclosed list of -** characters. -** -** [^...] Matches one character not in the enclosed list. -** -** '#' Matches any sequence of one or more digits with an -** optional + or - sign in front -** -** ' ' Any span of whitespace matches any other span of -** whitespace. -** -** Extra whitespace at the end of z[] is ignored. -*/ -static int testcase_glob(const char *zGlob, const char *z){ - int c, c2; - int invert; - int seen; - - while( (c = (*(zGlob++)))!=0 ){ - if( IsSpace(c) ){ - if( !IsSpace(*z) ) return 0; - while( IsSpace(*zGlob) ) zGlob++; - while( IsSpace(*z) ) z++; - }else if( c=='*' ){ - while( (c=(*(zGlob++))) == '*' || c=='?' ){ - if( c=='?' && (*(z++))==0 ) return 0; - } - if( c==0 ){ - return 1; - }else if( c=='[' ){ - while( *z && testcase_glob(zGlob-1,z)==0 ){ - z++; - } - return (*z)!=0; - } - while( (c2 = (*(z++)))!=0 ){ - while( c2!=c ){ - c2 = *(z++); - if( c2==0 ) return 0; - } - if( testcase_glob(zGlob,z) ) return 1; - } - return 0; - }else if( c=='?' ){ - if( (*(z++))==0 ) return 0; - }else if( c=='[' ){ - int prior_c = 0; - seen = 0; - invert = 0; - c = *(z++); - if( c==0 ) return 0; - c2 = *(zGlob++); - if( c2=='^' ){ - invert = 1; - c2 = *(zGlob++); - } - if( c2==']' ){ - if( c==']' ) seen = 1; - c2 = *(zGlob++); - } - while( c2 && c2!=']' ){ - if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ - c2 = *(zGlob++); - if( c>=prior_c && c<=c2 ) seen = 1; - prior_c = 0; - }else{ - if( c==c2 ){ - seen = 1; - } - prior_c = c2; - } - c2 = *(zGlob++); - } - if( c2==0 || (seen ^ invert)==0 ) return 0; - }else if( c=='#' ){ - if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; - if( !IsDigit(z[0]) ) return 0; - z++; - while( IsDigit(z[0]) ){ z++; } - }else{ - if( c!=(*(z++)) ) return 0; - } - } - while( IsSpace(*z) ){ z++; } - return *z==0; -} - - -/* -** Compare the string as a command-line option with either one or two -** initial "-" characters. -*/ -static int optionMatch(const char *zStr, const char *zOpt){ - if( zStr[0]!='-' ) return 0; - zStr++; - if( zStr[0]=='-' ) zStr++; - return strcmp(zStr, zOpt)==0; -} - -/* -** Delete a file. -*/ -int shellDeleteFile(const char *zFilename){ - int rc; -#ifdef _WIN32 - wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); - rc = _wunlink(z); - sqlite3_free(z); -#else - rc = unlink(zFilename); -#endif - return rc; -} - -/* -** If an input line begins with "." then invoke this routine to -** process that line. -** -** Return 1 on error, 2 to exit, and 0 otherwise. -*/ -static int do_meta_command(char *zLine, ShellState *p){ - int h = 1; - int nArg = 0; - int n, c; - int rc = 0; - char *azArg[50]; - - /* Parse the input line into tokens. - */ - while( zLine[h] && nArgdb, shellAuth, p); - }else{ - sqlite3_set_authorizer(p->db, 0, 0); - } - }else -#endif - - if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0) - || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0) - ){ - const char *zDestFile = 0; - const char *zDb = 0; - sqlite3 *pDest; - sqlite3_backup *pBackup; - int j; - for(j=1; jdb, zDb); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - sqlite3_close(pDest); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else{ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); - rc = 1; - } - sqlite3_close(pDest); - }else - - if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){ - if( nArg==2 ){ - bail_on_error = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .bail on|off\n"); - rc = 1; - } - }else - - if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){ - if( nArg==2 ){ - if( booleanValue(azArg[1]) ){ - setBinaryMode(p->out, 1); - }else{ - setTextMode(p->out, 1); - } - }else{ - raw_printf(stderr, "Usage: .binary on|off\n"); - rc = 1; - } - }else - - /* The undocumented ".breakpoint" command causes a call to the no-op - ** routine named test_breakpoint(). - */ - if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){ - test_breakpoint(); - }else - - if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){ - if( nArg==2 ){ - p->countChanges = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .changes on|off\n"); - rc = 1; - } - }else - - /* Cancel output redirection, if it is currently set (by .testcase) - ** Then read the content of the testcase-out.txt file and compare against - ** azArg[1]. If there are differences, report an error and exit. - */ - if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){ - char *zRes = 0; - output_reset(p); - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .check GLOB-PATTERN\n"); - rc = 2; - }else if( (zRes = readFile("testcase-out.txt"))==0 ){ - raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n"); - rc = 2; - }else if( testcase_glob(azArg[1],zRes)==0 ){ - utf8_printf(stderr, - "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", - p->zTestcase, azArg[1], zRes); - rc = 2; - }else{ - utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase); - p->nCheck++; - } - sqlite3_free(zRes); - }else - - if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){ - if( nArg==2 ){ - tryToClone(p, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .clone FILENAME\n"); - rc = 1; - } - }else - - if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ - ShellState data; - char *zErrMsg = 0; - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 1; - data.cMode = data.mode = MODE_Column; - data.colWidth[0] = 3; - data.colWidth[1] = 15; - data.colWidth[2] = 58; - data.cnt = 0; - sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else - - if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){ - rc = shell_dbinfo_command(p, nArg, azArg); - }else - - if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ - open_db(p, 0); - /* When playing back a "dump", the content might appear in an order - ** which causes immediate foreign key constraints to be violated. - ** So disable foreign-key constraint enforcement to prevent problems. */ - if( nArg!=1 && nArg!=2 ){ - raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n"); - raw_printf(p->out, "BEGIN TRANSACTION;\n"); - p->writableSchema = 0; - sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); - p->nErr = 0; - if( nArg==1 ){ - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); - run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); - }else{ - int i; - for(i=1; iwritableSchema ){ - raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); - p->writableSchema = 0; - } - sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); - sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); - }else - - if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){ - if( nArg==2 ){ - p->echoOn = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .echo on|off\n"); - rc = 1; - } - }else - - if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){ - if( nArg==2 ){ - if( strcmp(azArg[1],"full")==0 ){ - p->autoEQP = 2; - }else{ - p->autoEQP = booleanValue(azArg[1]); - } - }else{ - raw_printf(stderr, "Usage: .eqp on|off|full\n"); - rc = 1; - } - }else - - if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ - if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); - rc = 2; - }else - - if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ - int val = 1; - if( nArg>=2 ){ - if( strcmp(azArg[1],"auto")==0 ){ - val = 99; - }else{ - val = booleanValue(azArg[1]); - } - } - if( val==1 && p->mode!=MODE_Explain ){ - p->normalMode = p->mode; - p->mode = MODE_Explain; - p->autoExplain = 0; - }else if( val==0 ){ - if( p->mode==MODE_Explain ) p->mode = p->normalMode; - p->autoExplain = 0; - }else if( val==99 ){ - if( p->mode==MODE_Explain ) p->mode = p->normalMode; - p->autoExplain = 1; - } - }else - - if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){ - ShellState data; - char *zErrMsg = 0; - int doStats = 0; - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; - if( nArg==2 && optionMatch(azArg[1], "indent") ){ - data.cMode = data.mode = MODE_Pretty; - nArg = 1; - } - if( nArg!=1 ){ - raw_printf(stderr, "Usage: .fullschema ?--indent?\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - rc = sqlite3_exec(p->db, - "SELECT sql FROM" - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " - "ORDER BY rowid", - callback, &data, &zErrMsg - ); - if( rc==SQLITE_OK ){ - sqlite3_stmt *pStmt; - rc = sqlite3_prepare_v2(p->db, - "SELECT rowid FROM sqlite_master" - " WHERE name GLOB 'sqlite_stat[134]'", - -1, &pStmt, 0); - doStats = sqlite3_step(pStmt)==SQLITE_ROW; - sqlite3_finalize(pStmt); - } - if( doStats==0 ){ - raw_printf(p->out, "/* No STAT tables available */\n"); - }else{ - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'", - callback, &data, &zErrMsg); - data.cMode = data.mode = MODE_Insert; - data.zDestTable = "sqlite_stat1"; - shell_exec(p->db, "SELECT * FROM sqlite_stat1", - shell_callback, &data,&zErrMsg); - data.zDestTable = "sqlite_stat3"; - shell_exec(p->db, "SELECT * FROM sqlite_stat3", - shell_callback, &data,&zErrMsg); - data.zDestTable = "sqlite_stat4"; - shell_exec(p->db, "SELECT * FROM sqlite_stat4", - shell_callback, &data, &zErrMsg); - raw_printf(p->out, "ANALYZE sqlite_master;\n"); - } - }else - - if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){ - if( nArg==2 ){ - p->showHeader = booleanValue(azArg[1]); - }else{ - raw_printf(stderr, "Usage: .headers on|off\n"); - rc = 1; - } - }else - - if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ - utf8_printf(p->out, "%s", zHelp); - }else - - if( c=='i' && strncmp(azArg[0], "import", n)==0 ){ - char *zTable; /* Insert data into this table */ - char *zFile; /* Name of file to extra content from */ - sqlite3_stmt *pStmt = NULL; /* A statement */ - int nCol; /* Number of columns in the table */ - int nByte; /* Number of bytes in an SQL string */ - int i, j; /* Loop counters */ - int needCommit; /* True to COMMIT or ROLLBACK at end */ - int nSep; /* Number of bytes in p->colSeparator[] */ - char *zSql; /* An SQL statement */ - ImportCtx sCtx; /* Reader context */ - char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ - int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */ - - if( nArg!=3 ){ - raw_printf(stderr, "Usage: .import FILE TABLE\n"); - goto meta_command_exit; - } - zFile = azArg[1]; - zTable = azArg[2]; - seenInterrupt = 0; - memset(&sCtx, 0, sizeof(sCtx)); - open_db(p, 0); - nSep = strlen30(p->colSeparator); - if( nSep==0 ){ - raw_printf(stderr, - "Error: non-null column separator required for import\n"); - return 1; - } - if( nSep>1 ){ - raw_printf(stderr, "Error: multi-character column separators not allowed" - " for import\n"); - return 1; - } - nSep = strlen30(p->rowSeparator); - if( nSep==0 ){ - raw_printf(stderr, "Error: non-null row separator required for import\n"); - return 1; - } - if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){ - /* When importing CSV (only), if the row separator is set to the - ** default output row separator, change it to the default input - ** row separator. This avoids having to maintain different input - ** and output row separators. */ - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); - nSep = strlen30(p->rowSeparator); - } - if( nSep>1 ){ - raw_printf(stderr, "Error: multi-character row separators not allowed" - " for import\n"); - return 1; - } - sCtx.zFile = zFile; - sCtx.nLine = 1; - if( sCtx.zFile[0]=='|' ){ -#ifdef SQLITE_OMIT_POPEN - raw_printf(stderr, "Error: pipes are not supported in this OS\n"); - return 1; -#else - sCtx.in = popen(sCtx.zFile+1, "r"); - sCtx.zFile = ""; - xCloser = pclose; -#endif - }else{ - sCtx.in = fopen(sCtx.zFile, "rb"); - xCloser = fclose; - } - if( p->mode==MODE_Ascii ){ - xRead = ascii_read_one_field; - }else{ - xRead = csv_read_one_field; - } - if( sCtx.in==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); - return 1; - } - sCtx.cColSep = p->colSeparator[0]; - sCtx.cRowSep = p->rowSeparator[0]; - zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); - return 1; - } - nByte = strlen30(zSql); - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ - if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){ - char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); - char cSep = '('; - while( xRead(&sCtx) ){ - zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z); - cSep = ','; - if( sCtx.cTerm!=sCtx.cColSep ) break; - } - if( cSep=='(' ){ - sqlite3_free(zCreate); - sqlite3_free(sCtx.z); - xCloser(sCtx.in); - utf8_printf(stderr,"%s: empty file\n", sCtx.zFile); - return 1; - } - zCreate = sqlite3_mprintf("%z\n)", zCreate); - rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); - sqlite3_free(zCreate); - if( rc ){ - utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable, - sqlite3_errmsg(p->db)); - sqlite3_free(sCtx.z); - xCloser(sCtx.in); - return 1; - } - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - } - sqlite3_free(zSql); - if( rc ){ - if (pStmt) sqlite3_finalize(pStmt); - utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db)); - xCloser(sCtx.in); - return 1; - } - nCol = sqlite3_column_count(pStmt); - sqlite3_finalize(pStmt); - pStmt = 0; - if( nCol==0 ) return 0; /* no columns, no error */ - zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 ); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - xCloser(sCtx.in); - return 1; - } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); - j = strlen30(zSql); - for(i=1; idb, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - if( rc ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - if (pStmt) sqlite3_finalize(pStmt); - xCloser(sCtx.in); - return 1; - } - needCommit = sqlite3_get_autocommit(p->db); - if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); - do{ - int startLine = sCtx.nLine; - for(i=0; imode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; - sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); - if( i=nCol ){ - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, - startLine, sqlite3_errmsg(p->db)); - } - } - }while( sCtx.cTerm!=EOF ); - - xCloser(sCtx.in); - sqlite3_free(sCtx.z); - sqlite3_finalize(pStmt); - if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); - }else - - if( c=='i' && (strncmp(azArg[0], "indices", n)==0 - || strncmp(azArg[0], "indexes", n)==0) ){ - ShellState data; - char *zErrMsg = 0; - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_List; - if( nArg==1 ){ - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND name NOT LIKE 'sqlite_%' " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - }else if( nArg==2 ){ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, - "SELECT name FROM sqlite_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type='index' AND tbl_name LIKE shellstatic() " - "ORDER BY 1", - callback, &data, &zErrMsg - ); - zShellStatic = 0; - }else{ - raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - raw_printf(stderr, - "Error: querying sqlite_master and sqlite_temp_master\n"); - rc = 1; - } - }else - -#ifdef SQLITE_ENABLE_IOTRACE - if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ - SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); - if( iotrace && iotrace!=stdout ) fclose(iotrace); - iotrace = 0; - if( nArg<2 ){ - sqlite3IoTrace = 0; - }else if( strcmp(azArg[1], "-")==0 ){ - sqlite3IoTrace = iotracePrintf; - iotrace = stdout; - }else{ - iotrace = fopen(azArg[1], "w"); - if( iotrace==0 ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); - sqlite3IoTrace = 0; - rc = 1; - }else{ - sqlite3IoTrace = iotracePrintf; - } - } - }else -#endif - if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){ - static const struct { - const char *zLimitName; /* Name of a limit */ - int limitCode; /* Integer code for that limit */ - } aLimit[] = { - { "length", SQLITE_LIMIT_LENGTH }, - { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, - { "column", SQLITE_LIMIT_COLUMN }, - { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, - { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, - { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, - { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, - { "attached", SQLITE_LIMIT_ATTACHED }, - { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, - { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, - { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, - { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, - }; - int i, n2; - open_db(p, 0); - if( nArg==1 ){ - for(i=0; idb, aLimit[i].limitCode, -1)); - } - }else if( nArg>3 ){ - raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n"); - rc = 1; - goto meta_command_exit; - }else{ - int iLimit = -1; - n2 = strlen30(azArg[1]); - for(i=0; idb, aLimit[iLimit].limitCode, - (int)integerValue(azArg[2])); - } - printf("%20s %d\n", aLimit[iLimit].zLimitName, - sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); - } - }else - -#ifndef SQLITE_OMIT_LOAD_EXTENSION - if( c=='l' && strncmp(azArg[0], "load", n)==0 ){ - const char *zFile, *zProc; - char *zErrMsg = 0; - if( nArg<2 ){ - raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n"); - rc = 1; - goto meta_command_exit; - } - zFile = azArg[1]; - zProc = nArg>=3 ? azArg[2] : 0; - open_db(p, 0); - rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - } - }else -#endif - - if( c=='l' && strncmp(azArg[0], "log", n)==0 ){ - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .log FILENAME\n"); - rc = 1; - }else{ - const char *zFile = azArg[1]; - output_file_close(p->pLog); - p->pLog = output_file_open(zFile); - } - }else - - if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){ - const char *zMode = nArg>=2 ? azArg[1] : ""; - int n2 = (int)strlen(zMode); - int c2 = zMode[0]; - if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){ - p->mode = MODE_Line; - }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){ - p->mode = MODE_Column; - }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){ - p->mode = MODE_List; - }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){ - p->mode = MODE_Html; - }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){ - p->mode = MODE_Tcl; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); - }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){ - p->mode = MODE_Csv; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); - }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){ - p->mode = MODE_List; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); - }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){ - p->mode = MODE_Insert; - set_table_name(p, nArg>=3 ? azArg[2] : "table"); - }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){ - p->mode = MODE_Ascii; - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); - }else { - raw_printf(stderr, "Error: mode should be one of: " - "ascii column csv html insert line list tabs tcl\n"); - rc = 1; - } - p->cMode = p->mode; - }else - - if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){ - if( nArg==2 ){ - sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, - "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); - }else{ - raw_printf(stderr, "Usage: .nullvalue STRING\n"); - rc = 1; - } - }else - - if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ - /* Close the existing database */ - session_close_all(p); - sqlite3_close(p->db); - p->db = 0; - sqlite3_free(p->zFreeOnClose); - p->zFreeOnClose = 0; - /* Check for command-line arguments */ - for(iName=1; iNameiName ? sqlite3_mprintf("%s", azArg[iName]) : 0; - if( zNewFilename ){ - if( newFlag ) shellDeleteFile(zNewFilename); - p->zDbFilename = zNewFilename; - open_db(p, 1); - if( p->db==0 ){ - utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); - sqlite3_free(zNewFilename); - }else{ - p->zFreeOnClose = zNewFilename; - } - } - if( p->db==0 ){ - /* As a fall-back open a TEMP database */ - p->zDbFilename = 0; - open_db(p, 0); - } - }else - - if( c=='o' - && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0) - ){ - const char *zFile = nArg>=2 ? azArg[1] : "stdout"; - if( nArg>2 ){ - utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]); - rc = 1; - goto meta_command_exit; - } - if( n>1 && strncmp(azArg[0], "once", n)==0 ){ - if( nArg<2 ){ - raw_printf(stderr, "Usage: .once FILE\n"); - rc = 1; - goto meta_command_exit; - } - p->outCount = 2; - }else{ - p->outCount = 0; - } - output_reset(p); - if( zFile[0]=='|' ){ -#ifdef SQLITE_OMIT_POPEN - raw_printf(stderr, "Error: pipes are not supported in this OS\n"); - rc = 1; - p->out = stdout; -#else - p->out = popen(zFile + 1, "w"); - if( p->out==0 ){ - utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); - p->out = stdout; - rc = 1; - }else{ - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); - } -#endif - }else{ - p->out = output_file_open(zFile); - if( p->out==0 ){ - if( strcmp(zFile,"off")!=0 ){ - utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile); - } - p->out = stdout; - rc = 1; - } else { - sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); - } - } - }else - - if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){ - int i; - for(i=1; i1 ) raw_printf(p->out, " "); - utf8_printf(p->out, "%s", azArg[i]); - } - raw_printf(p->out, "\n"); - }else - - if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){ - if( nArg >= 2) { - strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); - } - if( nArg >= 3) { - strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); - } - }else - - if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ - rc = 2; - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ - FILE *alt; - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .read FILE\n"); - rc = 1; - goto meta_command_exit; - } - alt = fopen(azArg[1], "rb"); - if( alt==0 ){ - utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); - rc = 1; - }else{ - rc = process_input(p, alt); - fclose(alt); - } - }else - - if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ - const char *zSrcFile; - const char *zDb; - sqlite3 *pSrc; - sqlite3_backup *pBackup; - int nTimeout = 0; - - if( nArg==2 ){ - zSrcFile = azArg[1]; - zDb = "main"; - }else if( nArg==3 ){ - zSrcFile = azArg[2]; - zDb = azArg[1]; - }else{ - raw_printf(stderr, "Usage: .restore ?DB? FILE\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_open(zSrcFile, &pSrc); - if( rc!=SQLITE_OK ){ - utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile); - sqlite3_close(pSrc); - return 1; - } - open_db(p, 0); - pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); - if( pBackup==0 ){ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - sqlite3_close(pSrc); - return 1; - } - while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK - || rc==SQLITE_BUSY ){ - if( rc==SQLITE_BUSY ){ - if( nTimeout++ >= 3 ) break; - sqlite3_sleep(100); - } - } - sqlite3_backup_finish(pBackup); - if( rc==SQLITE_DONE ){ - rc = 0; - }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - raw_printf(stderr, "Error: source database is busy\n"); - rc = 1; - }else{ - utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); - rc = 1; - } - sqlite3_close(pSrc); - }else - - - if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){ - if( nArg==2 ){ - p->scanstatsOn = booleanValue(azArg[1]); -#ifndef SQLITE_ENABLE_STMT_SCANSTATUS - raw_printf(stderr, "Warning: .scanstats not available in this build.\n"); -#endif - }else{ - raw_printf(stderr, "Usage: .scanstats on|off\n"); - rc = 1; - } - }else - - if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ - ShellState data; - char *zErrMsg = 0; - open_db(p, 0); - memcpy(&data, p, sizeof(data)); - data.showHeader = 0; - data.cMode = data.mode = MODE_Semi; - if( nArg>=2 && optionMatch(azArg[1], "indent") ){ - data.cMode = data.mode = MODE_Pretty; - nArg--; - if( nArg==2 ) azArg[1] = azArg[2]; - } - if( nArg==2 && azArg[1][0]!='-' ){ - int i; - for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]); - if( strcmp(azArg[1],"sqlite_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TABLE sqlite_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ - char *new_argv[2], *new_colv[2]; - new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" - " type text,\n" - " name text,\n" - " tbl_name text,\n" - " rootpage integer,\n" - " sql text\n" - ")"; - new_argv[1] = 0; - new_colv[0] = "sql"; - new_colv[1] = 0; - callback(&data, 1, new_argv, new_colv); - rc = SQLITE_OK; - }else{ - zShellStatic = azArg[1]; - rc = sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE lower(tbl_name) LIKE shellstatic()" - " AND type!='meta' AND sql NOTNULL " - "ORDER BY rowid", - callback, &data, &zErrMsg); - zShellStatic = 0; - } - }else if( nArg==1 ){ - rc = sqlite3_exec(p->db, - "SELECT sql FROM " - " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" - " FROM sqlite_master UNION ALL" - " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " - "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' " - "ORDER BY rowid", - callback, &data, &zErrMsg - ); - }else{ - raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; - } - if( zErrMsg ){ - utf8_printf(stderr,"Error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - rc = 1; - }else if( rc != SQLITE_OK ){ - raw_printf(stderr,"Error: querying schema information\n"); - rc = 1; - }else{ - rc = 0; - } - }else - -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3SelectTrace = integerValue(azArg[1]); - }else -#endif - -#if defined(SQLITE_ENABLE_SESSION) - if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ - OpenSession *pSession = &p->aSession[0]; - char **azCmd = &azArg[1]; - int iSes = 0; - int nCmd = nArg - 1; - int i; - if( nArg<=1 ) goto session_syntax_error; - open_db(p, 0); - if( nArg>=3 ){ - for(iSes=0; iSesnSession; iSes++){ - if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break; - } - if( iSesnSession ){ - pSession = &p->aSession[iSes]; - azCmd++; - nCmd--; - }else{ - pSession = &p->aSession[0]; - iSes = 0; - } - } - - /* .session attach TABLE - ** Invoke the sqlite3session_attach() interface to attach a particular - ** table so that it is never filtered. - */ - if( strcmp(azCmd[0],"attach")==0 ){ - if( nCmd!=2 ) goto session_syntax_error; - if( pSession->p==0 ){ - session_not_open: - raw_printf(stderr, "ERROR: No sessions are open\n"); - }else{ - rc = sqlite3session_attach(pSession->p, azCmd[1]); - if( rc ){ - raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc); - rc = 0; - } - } - }else - - /* .session changeset FILE - ** .session patchset FILE - ** Write a changeset or patchset into a file. The file is overwritten. - */ - if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){ - FILE *out = 0; - if( nCmd!=2 ) goto session_syntax_error; - if( pSession->p==0 ) goto session_not_open; - out = fopen(azCmd[1], "wb"); - if( out==0 ){ - utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); - }else{ - int szChng; - void *pChng; - if( azCmd[0][0]=='c' ){ - rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); - }else{ - rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); - } - if( rc ){ - printf("Error: error code %d\n", rc); - rc = 0; - } - if( pChng - && fwrite(pChng, szChng, 1, out)!=1 ){ - raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n", - szChng); - } - sqlite3_free(pChng); - fclose(out); - } - }else - - /* .session close - ** Close the identified session - */ - if( strcmp(azCmd[0], "close")==0 ){ - if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ - session_close(pSession); - p->aSession[iSes] = p->aSession[--p->nSession]; - } - }else - - /* .session enable ?BOOLEAN? - ** Query or set the enable flag - */ - if( strcmp(azCmd[0], "enable")==0 ){ - int ii; - if( nCmd>2 ) goto session_syntax_error; - ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ - ii = sqlite3session_enable(pSession->p, ii); - utf8_printf(p->out, "session %s enable flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session filter GLOB .... - ** Set a list of GLOB patterns of table names to be excluded. - */ - if( strcmp(azCmd[0], "filter")==0 ){ - int ii, nByte; - if( nCmd<2 ) goto session_syntax_error; - if( p->nSession ){ - for(ii=0; iinFilter; ii++){ - sqlite3_free(pSession->azFilter[ii]); - } - sqlite3_free(pSession->azFilter); - nByte = sizeof(pSession->azFilter[0])*(nCmd-1); - pSession->azFilter = sqlite3_malloc( nByte ); - if( pSession->azFilter==0 ){ - raw_printf(stderr, "Error: out or memory\n"); - exit(1); - } - for(ii=1; iiazFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); - } - pSession->nFilter = ii-1; - } - }else - - /* .session indirect ?BOOLEAN? - ** Query or set the indirect flag - */ - if( strcmp(azCmd[0], "indirect")==0 ){ - int ii; - if( nCmd>2 ) goto session_syntax_error; - ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); - if( p->nSession ){ - ii = sqlite3session_indirect(pSession->p, ii); - utf8_printf(p->out, "session %s indirect flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session isempty - ** Determine if the session is empty - */ - if( strcmp(azCmd[0], "isempty")==0 ){ - int ii; - if( nCmd!=1 ) goto session_syntax_error; - if( p->nSession ){ - ii = sqlite3session_isempty(pSession->p); - utf8_printf(p->out, "session %s isempty flag = %d\n", - pSession->zName, ii); - } - }else - - /* .session list - ** List all currently open sessions - */ - if( strcmp(azCmd[0],"list")==0 ){ - for(i=0; inSession; i++){ - utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName); - } - }else - - /* .session open DB NAME - ** Open a new session called NAME on the attached database DB. - ** DB is normally "main". - */ - if( strcmp(azCmd[0],"open")==0 ){ - char *zName; - if( nCmd!=3 ) goto session_syntax_error; - zName = azCmd[2]; - if( zName[0]==0 ) goto session_syntax_error; - for(i=0; inSession; i++){ - if( strcmp(p->aSession[i].zName,zName)==0 ){ - utf8_printf(stderr, "Session \"%s\" already exists\n", zName); - goto meta_command_exit; - } - } - if( p->nSession>=ArraySize(p->aSession) ){ - raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession)); - goto meta_command_exit; - } - pSession = &p->aSession[p->nSession]; - rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); - if( rc ){ - raw_printf(stderr, "Cannot open session: error code=%d\n", rc); - rc = 0; - goto meta_command_exit; - } - pSession->nFilter = 0; - sqlite3session_table_filter(pSession->p, session_filter, pSession); - p->nSession++; - pSession->zName = sqlite3_mprintf("%s", zName); - }else - /* If no command name matches, show a syntax error */ - session_syntax_error: - session_help(p); - }else -#endif - -#ifdef SQLITE_DEBUG - /* Undocumented commands for internal testing. Subject to change - ** without notice. */ - if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){ - if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){ - int i, v; - for(i=1; iout, "%s: %d 0x%x\n", azArg[i], v, v); - } - } - if( strncmp(azArg[0]+9, "integer", n-9)==0 ){ - int i; sqlite3_int64 v; - for(i=1; iout, "%s", zBuf); - } - } - }else -#endif - - if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){ - if( nArg<2 || nArg>3 ){ - raw_printf(stderr, "Usage: .separator COL ?ROW?\n"); - rc = 1; - } - if( nArg>=2 ){ - sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, - "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); - } - if( nArg>=3 ){ - sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, - "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); - } - }else - - if( c=='s' - && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0) - ){ - char *zCmd; - int i, x; - if( nArg<2 ){ - raw_printf(stderr, "Usage: .system COMMAND\n"); - rc = 1; - goto meta_command_exit; - } - zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); - for(i=2; iout, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]); - utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); - utf8_printf(p->out, "%12.12s: %s\n","explain", - p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); - utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]); - utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); - utf8_printf(p->out, "%12.12s: ", "nullvalue"); - output_c_string(p->out, p->nullValue); - raw_printf(p->out, "\n"); - utf8_printf(p->out,"%12.12s: %s\n","output", - strlen30(p->outfile) ? p->outfile : "stdout"); - utf8_printf(p->out,"%12.12s: ", "colseparator"); - output_c_string(p->out, p->colSeparator); - raw_printf(p->out, "\n"); - utf8_printf(p->out,"%12.12s: ", "rowseparator"); - output_c_string(p->out, p->rowSeparator); - raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); - utf8_printf(p->out, "%12.12s: ", "width"); - for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { - raw_printf(p->out, "%d ", p->colWidth[i]); - } - raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n", "filename", - p->zDbFilename ? p->zDbFilename : ""); - }else - - if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ - if( nArg==2 ){ - p->statsOn = booleanValue(azArg[1]); - }else if( nArg==1 ){ - display_stats(p->db, p, 0); - }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); - rc = 1; - } - }else - - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ - sqlite3_stmt *pStmt; - char **azResult; - int nRow, nAlloc; - char *zSql = 0; - int ii; - open_db(p, 0); - rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); - if( rc ) return shellDatabaseError(p->db); - - /* Create an SQL statement to query for the list of tables in the - ** main and all attached databases where the table name matches the - ** LIKE pattern bound to variable "?1". */ - zSql = sqlite3_mprintf( - "SELECT name FROM sqlite_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1"); - while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){ - const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); - if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue; - if( strcmp(zDbName,"temp")==0 ){ - zSql = sqlite3_mprintf( - "%z UNION ALL " - "SELECT 'temp.' || name FROM sqlite_temp_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1", zSql); - }else{ - zSql = sqlite3_mprintf( - "%z UNION ALL " - "SELECT '%q.' || name FROM \"%w\".sqlite_master" - " WHERE type IN ('table','view')" - " AND name NOT LIKE 'sqlite_%%'" - " AND name LIKE ?1", zSql, zDbName, zDbName); - } - } - rc = sqlite3_finalize(pStmt); - if( zSql && rc==SQLITE_OK ){ - zSql = sqlite3_mprintf("%z ORDER BY 1", zSql); - if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - } - sqlite3_free(zSql); - if( !zSql ) return shellNomemError(); - if( rc ) return shellDatabaseError(p->db); - - /* Run the SQL statement prepared by the above block. Store the results - ** as an array of nul-terminated strings in azResult[]. */ - nRow = nAlloc = 0; - azResult = 0; - if( nArg>1 ){ - sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); - }else{ - sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); - } - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - if( nRow>=nAlloc ){ - char **azNew; - int n2 = nAlloc*2 + 10; - azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); - if( azNew==0 ){ - rc = shellNomemError(); - break; - } - nAlloc = n2; - azResult = azNew; - } - azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); - if( 0==azResult[nRow] ){ - rc = shellNomemError(); - break; - } - nRow++; - } - if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ - rc = shellDatabaseError(p->db); - } - - /* Pretty-print the contents of array azResult[] to the output */ - if( rc==0 && nRow>0 ){ - int len, maxlen = 0; - int i, j; - int nPrintCol, nPrintRow; - for(i=0; imaxlen ) maxlen = len; - } - nPrintCol = 80/(maxlen+2); - if( nPrintCol<1 ) nPrintCol = 1; - nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; - for(i=0; iout, "%s%-*s", zSp, maxlen, - azResult[j] ? azResult[j]:""); - } - raw_printf(p->out, "\n"); - } - } - - for(ii=0; iiout = output_file_open("testcase-out.txt"); - if( p->out==0 ){ - utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n"); - } - if( nArg>=2 ){ - sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); - }else{ - sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); - } - }else - - if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ - static const struct { - const char *zCtrlName; /* Name of a test-control option */ - int ctrlCode; /* Integer code for that option */ - } aCtrl[] = { - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE }, - { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET }, - { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST }, - { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, - { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, - { "assert", SQLITE_TESTCTRL_ASSERT }, - { "always", SQLITE_TESTCTRL_ALWAYS }, - { "reserve", SQLITE_TESTCTRL_RESERVE }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, - { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, - { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, - { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, - { "imposter", SQLITE_TESTCTRL_IMPOSTER }, - }; - int testctrl = -1; - int rc2 = 0; - int i, n2; - open_db(p, 0); - - /* convert testctrl text option to value. allow any unique prefix - ** of the option name, or a numerical value. */ - n2 = strlen30(azArg[1]); - for(i=0; iSQLITE_TESTCTRL_LAST) ){ - utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]); - }else{ - switch(testctrl){ - - /* sqlite3_test_control(int, db, int) */ - case SQLITE_TESTCTRL_OPTIMIZATIONS: - case SQLITE_TESTCTRL_RESERVE: - if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); - rc2 = sqlite3_test_control(testctrl, p->db, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int) */ - case SQLITE_TESTCTRL_PRNG_SAVE: - case SQLITE_TESTCTRL_PRNG_RESTORE: - case SQLITE_TESTCTRL_PRNG_RESET: - case SQLITE_TESTCTRL_BYTEORDER: - if( nArg==2 ){ - rc2 = sqlite3_test_control(testctrl); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes no options\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int, uint) */ - case SQLITE_TESTCTRL_PENDING_BYTE: - if( nArg==3 ){ - unsigned int opt = (unsigned int)integerValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single unsigned" - " int option\n", azArg[1]); - } - break; - - /* sqlite3_test_control(int, int) */ - case SQLITE_TESTCTRL_ASSERT: - case SQLITE_TESTCTRL_ALWAYS: - case SQLITE_TESTCTRL_NEVER_CORRUPT: - if( nArg==3 ){ - int opt = booleanValue(azArg[2]); - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr,"Error: testctrl %s takes a single int option\n", - azArg[1]); - } - break; - - /* sqlite3_test_control(int, char *) */ -#ifdef SQLITE_N_KEYWORD - case SQLITE_TESTCTRL_ISKEYWORD: - if( nArg==3 ){ - const char *opt = azArg[2]; - rc2 = sqlite3_test_control(testctrl, opt); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - } else { - utf8_printf(stderr, - "Error: testctrl %s takes a single char * option\n", - azArg[1]); - } - break; -#endif - - case SQLITE_TESTCTRL_IMPOSTER: - if( nArg==5 ){ - rc2 = sqlite3_test_control(testctrl, p->db, - azArg[2], - integerValue(azArg[3]), - integerValue(azArg[4])); - raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2); - }else{ - raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n"); - } - break; - - case SQLITE_TESTCTRL_BITVEC_TEST: - case SQLITE_TESTCTRL_FAULT_INSTALL: - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: - default: - utf8_printf(stderr, - "Error: CLI support for testctrl %s not implemented\n", - azArg[1]); - break; - } - } - }else - - if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){ - open_db(p, 0); - sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); - }else - - if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){ - if( nArg==2 ){ - enableTimer = booleanValue(azArg[1]); - if( enableTimer && !HAS_TIMER ){ - raw_printf(stderr, "Error: timer not available on this system.\n"); - enableTimer = 0; - } - }else{ - raw_printf(stderr, "Usage: .timer on|off\n"); - rc = 1; - } - }else - - if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){ - open_db(p, 0); - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .trace FILE|off\n"); - rc = 1; - goto meta_command_exit; - } - output_file_close(p->traceOut); - p->traceOut = output_file_open(azArg[1]); -#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) - if( p->traceOut==0 ){ - sqlite3_trace_v2(p->db, 0, 0, 0); - }else{ - sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut); - } -#endif - }else - -#if SQLITE_USER_AUTHENTICATION - if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ - if( nArg<2 ){ - raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - if( strcmp(azArg[1],"login")==0 ){ - if( nArg!=4 ){ - raw_printf(stderr, "Usage: .user login USER PASSWORD\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], - (int)strlen(azArg[3])); - if( rc ){ - utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); - rc = 1; - } - }else if( strcmp(azArg[1],"add")==0 ){ - if( nArg!=5 ){ - raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_add(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Add failed: %d\n", rc); - rc = 1; - } - }else if( strcmp(azArg[1],"edit")==0 ){ - if( nArg!=5 ){ - raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_change(p->db, azArg[2], - azArg[3], (int)strlen(azArg[3]), - booleanValue(azArg[4])); - if( rc ){ - raw_printf(stderr, "User-Edit failed: %d\n", rc); - rc = 1; - } - }else if( strcmp(azArg[1],"delete")==0 ){ - if( nArg!=3 ){ - raw_printf(stderr, "Usage: .user delete USER\n"); - rc = 1; - goto meta_command_exit; - } - rc = sqlite3_user_delete(p->db, azArg[2]); - if( rc ){ - raw_printf(stderr, "User-Delete failed: %d\n", rc); - rc = 1; - } - }else{ - raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n"); - rc = 1; - goto meta_command_exit; - } - }else -#endif /* SQLITE_USER_AUTHENTICATION */ - - if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ - utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, - sqlite3_libversion(), sqlite3_sourceid()); - }else - - if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){ - const char *zDbName = nArg==2 ? azArg[1] : "main"; - sqlite3_vfs *pVfs; - if( p->db ){ - sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); - if( pVfs ){ - utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); - raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); - raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); - raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); - } - } - }else - - if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){ - sqlite3_vfs *pVfs; - sqlite3_vfs *pCurrent = 0; - if( p->db ){ - sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); - } - for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ - utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, - pVfs==pCurrent ? " <--- CURRENT" : ""); - raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); - raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); - raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); - if( pVfs->pNext ){ - raw_printf(p->out, "-----------------------------------\n"); - } - } - }else - - if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){ - const char *zDbName = nArg==2 ? azArg[1] : "main"; - char *zVfsName = 0; - if( p->db ){ - sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); - if( zVfsName ){ - utf8_printf(p->out, "%s\n", zVfsName); - sqlite3_free(zVfsName); - } - } - }else - -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; - }else -#endif - - if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ - int j; - assert( nArg<=ArraySize(azArg) ); - for(j=1; jcolWidth); j++){ - p->colWidth[j-1] = (int)integerValue(azArg[j]); - } - }else - - { - utf8_printf(stderr, "Error: unknown command or invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[0]); - rc = 1; - } - -meta_command_exit: - if( p->outCount ){ - p->outCount--; - if( p->outCount==0 ) output_reset(p); - } - return rc; -} - -/* -** Return TRUE if a semicolon occurs anywhere in the first N characters -** of string z[]. -*/ -static int line_contains_semicolon(const char *z, int N){ - int i; - for(i=0; iout); - zLine = one_input_line(in, zLine, nSql>0); - if( zLine==0 ){ - /* End of input */ - if( in==0 && stdin_is_interactive ) printf("\n"); - break; - } - if( seenInterrupt ){ - if( in!=0 ) break; - seenInterrupt = 0; - } - lineno++; - if( nSql==0 && _all_whitespace(zLine) ){ - if( p->echoOn ) printf("%s\n", zLine); - continue; - } - if( zLine && zLine[0]=='.' && nSql==0 ){ - if( p->echoOn ) printf("%s\n", zLine); - rc = do_meta_command(zLine, p); - if( rc==2 ){ /* exit requested */ - break; - }else if( rc ){ - errCnt++; - } - continue; - } - if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){ - memcpy(zLine,";",2); - } - nLine = strlen30(zLine); - if( nSql+nLine+2>=nAlloc ){ - nAlloc = nSql+nLine+100; - zSql = realloc(zSql, nAlloc); - if( zSql==0 ){ - raw_printf(stderr, "Error: out of memory\n"); - exit(1); - } - } - nSqlPrior = nSql; - if( nSql==0 ){ - int i; - for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} - assert( nAlloc>0 && zSql!=0 ); - memcpy(zSql, zLine+i, nLine+1-i); - startline = lineno; - nSql = nLine-i; - }else{ - zSql[nSql++] = '\n'; - memcpy(zSql+nSql, zLine, nLine+1); - nSql += nLine; - } - if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) - && sqlite3_complete(zSql) ){ - p->cnt = 0; - open_db(p, 0); - if( p->backslashOn ) resolve_backslashes(zSql); - BEGIN_TIMER; - rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); - END_TIMER; - if( rc || zErrMsg ){ - char zPrefix[100]; - if( in!=0 || !stdin_is_interactive ){ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, - "Error: near line %d:", startline); - }else{ - sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); - } - if( zErrMsg!=0 ){ - utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg); - sqlite3_free(zErrMsg); - zErrMsg = 0; - }else{ - utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db)); - } - errCnt++; - }else if( p->countChanges ){ - raw_printf(p->out, "changes: %3d total_changes: %d\n", - sqlite3_changes(p->db), sqlite3_total_changes(p->db)); - } - nSql = 0; - if( p->outCount ){ - output_reset(p); - p->outCount = 0; - } - }else if( nSql && _all_whitespace(zSql) ){ - if( p->echoOn ) printf("%s\n", zSql); - nSql = 0; - } - } - if( nSql ){ - if( !_all_whitespace(zSql) ){ - utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql); - errCnt++; - } - } - free(zSql); - free(zLine); - return errCnt>0; -} - -/* -** Return a pathname which is the user's home directory. A -** 0 return indicates an error of some kind. -*/ -static char *find_home_dir(int clearFlag){ - static char *home_dir = NULL; - if( clearFlag ){ - free(home_dir); - home_dir = 0; - return 0; - } - if( home_dir ) return home_dir; - -#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ - && !defined(__RTP__) && !defined(_WRS_KERNEL) - { - struct passwd *pwent; - uid_t uid = getuid(); - if( (pwent=getpwuid(uid)) != NULL) { - home_dir = pwent->pw_dir; - } - } -#endif - -#if defined(_WIN32_WCE) - /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() - */ - home_dir = "/"; -#else - -#if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - home_dir = getenv("USERPROFILE"); - } -#endif - - if (!home_dir) { - home_dir = getenv("HOME"); - } - -#if defined(_WIN32) || defined(WIN32) - if (!home_dir) { - char *zDrive, *zPath; - int n; - zDrive = getenv("HOMEDRIVE"); - zPath = getenv("HOMEPATH"); - if( zDrive && zPath ){ - n = strlen30(zDrive) + strlen30(zPath) + 1; - home_dir = malloc( n ); - if( home_dir==0 ) return 0; - sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); - return home_dir; - } - home_dir = "c:\\"; - } -#endif - -#endif /* !_WIN32_WCE */ - - if( home_dir ){ - int n = strlen30(home_dir) + 1; - char *z = malloc( n ); - if( z ) memcpy(z, home_dir, n); - home_dir = z; - } - - return home_dir; -} - -/* -** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from ~/.sqliterc -** -** Returns the number of errors. -*/ -static void process_sqliterc( - ShellState *p, /* Configuration data */ - const char *sqliterc_override /* Name of config file. NULL to use default */ -){ - char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf = 0; - FILE *in = NULL; - - if (sqliterc == NULL) { - home_dir = find_home_dir(0); - if( home_dir==0 ){ - raw_printf(stderr, "-- warning: cannot find home directory;" - " cannot read ~/.sqliterc\n"); - return; - } - sqlite3_initialize(); - zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); - sqliterc = zBuf; - } - in = fopen(sqliterc,"rb"); - if( in ){ - if( stdin_is_interactive ){ - utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); - } - process_input(p,in); - fclose(in); - } - sqlite3_free(zBuf); -} - -/* -** Show available command line options -*/ -static const char zOptions[] = - " -ascii set output mode to 'ascii'\n" - " -bail stop after hitting an error\n" - " -batch force batch I/O\n" - " -column set output mode to 'column'\n" - " -cmd COMMAND run \"COMMAND\" before reading stdin\n" - " -csv set output mode to 'csv'\n" - " -echo print commands before execution\n" - " -init FILENAME read/process named file\n" - " -[no]header turn headers on or off\n" -#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) - " -heap SIZE Size of heap for memsys3 or memsys5\n" -#endif - " -help show this message\n" - " -html set output mode to HTML\n" - " -interactive force interactive I/O\n" - " -line set output mode to 'line'\n" - " -list set output mode to 'list'\n" - " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" - " -mmap N default mmap size set to N\n" -#ifdef SQLITE_ENABLE_MULTIPLEX - " -multiplex enable the multiplexor VFS\n" -#endif - " -newline SEP set output row separator. Default: '\\n'\n" - " -nullvalue TEXT set text string for NULL values. Default ''\n" - " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" - " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" - " -separator SEP set output column separator. Default: '|'\n" - " -stats print memory stats before each finalize\n" - " -version show SQLite version\n" - " -vfs NAME use NAME as the default VFS\n" -#ifdef SQLITE_ENABLE_VFSTRACE - " -vfstrace enable tracing of all VFS calls\n" -#endif -; -static void usage(int showDetail){ - utf8_printf(stderr, - "Usage: %s [OPTIONS] FILENAME [SQL]\n" - "FILENAME is the name of an SQLite database. A new database is created\n" - "if the file does not previously exist.\n", Argv0); - if( showDetail ){ - utf8_printf(stderr, "OPTIONS include:\n%s", zOptions); - }else{ - raw_printf(stderr, "Use the -help option for additional information\n"); - } - exit(1); -} - -/* -** Initialize the state information in data -*/ -static void main_init(ShellState *data) { - memset(data, 0, sizeof(*data)); - data->normalMode = data->cMode = data->mode = MODE_List; - data->autoExplain = 1; - memcpy(data->colSeparator,SEP_Column, 2); - memcpy(data->rowSeparator,SEP_Row, 2); - data->showHeader = 0; - data->shellFlgs = SHFLG_Lookaside; - sqlite3_config(SQLITE_CONFIG_URI, 1); - sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); - sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); - sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); -} - -/* -** Output text to the console in a font that attracts extra attention. -*/ -#ifdef _WIN32 -static void printBold(const char *zText){ - HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; - GetConsoleScreenBufferInfo(out, &defaultScreenInfo); - SetConsoleTextAttribute(out, - FOREGROUND_RED|FOREGROUND_INTENSITY - ); - printf("%s", zText); - SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); -} -#else -static void printBold(const char *zText){ - printf("\033[1m%s\033[0m", zText); -} -#endif - -/* -** Get the argument to an --option. Throw an error and die if no argument -** is available. -*/ -static char *cmdline_option_value(int argc, char **argv, int i){ - if( i==argc ){ - utf8_printf(stderr, "%s: Error: missing argument to %s\n", - argv[0], argv[argc-1]); - exit(1); - } - return argv[i]; -} - -#ifndef SQLITE_SHELL_IS_UTF8 -# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) -# define SQLITE_SHELL_IS_UTF8 (0) -# else -# define SQLITE_SHELL_IS_UTF8 (1) -# endif -#endif - -#if SQLITE_SHELL_IS_UTF8 -int SQLITE_CDECL main(int argc, char **argv){ -#else -int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ - char **argv; -#endif - char *zErrMsg = 0; - ShellState data; - const char *zInitFile = 0; - int i; - int rc = 0; - int warnInmemoryDb = 0; - int readStdin = 1; - int nCmd = 0; - char **azCmd = 0; - - setBinaryMode(stdin, 0); - setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ - stdin_is_interactive = isatty(0); - stdout_is_console = isatty(1); - -#if USE_SYSTEM_SQLITE+0!=1 - if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ - utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", - sqlite3_sourceid(), SQLITE_SOURCE_ID); - exit(1); - } -#endif - main_init(&data); -#if !SQLITE_SHELL_IS_UTF8 - sqlite3_initialize(); - argv = sqlite3_malloc64(sizeof(argv[0])*argc); - if( argv==0 ){ - raw_printf(stderr, "out of memory\n"); - exit(1); - } - for(i=0; i=1 && argv && argv[0] ); - Argv0 = argv[0]; - - /* Make sure we have a valid signal handler early, before anything - ** else is done. - */ -#ifdef SIGINT - signal(SIGINT, interrupt_handler); -#endif - -#ifdef SQLITE_SHELL_DBNAME_PROC - { - /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name - ** of a C-function that will provide the name of the database file. Use - ** this compile-time option to embed this shell program in larger - ** applications. */ - extern void SQLITE_SHELL_DBNAME_PROC(const char**); - SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); - warnInmemoryDb = 0; - } -#endif - - /* Do an initial pass through the command-line argument to locate - ** the name of the database file, the name of the initialization file, - ** the size of the alternative malloc heap, - ** and the first command to execute. - */ - for(i=1; i0x7fff0000 ) szHeap = 0x7fff0000; - sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); -#else - (void)cmdline_option_value(argc, argv, ++i); -#endif - }else if( strcmp(z,"-scratch")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz>400000 ) sz = 400000; - if( sz<2500 ) sz = 2500; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n>10 ) n = 10; - if( n<1 ) n = 1; - sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); - data.shellFlgs |= SHFLG_Scratch; - }else if( strcmp(z,"-pagecache")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz>70000 ) sz = 70000; - if( sz<0 ) sz = 0; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - sqlite3_config(SQLITE_CONFIG_PAGECACHE, - (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); - data.shellFlgs |= SHFLG_Pagecache; - }else if( strcmp(z,"-lookaside")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz<0 ) sz = 0; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n<0 ) n = 0; - sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); - if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; -#ifdef SQLITE_ENABLE_VFSTRACE - }else if( strcmp(z,"-vfstrace")==0 ){ - extern int vfstrace_register( - const char *zTraceName, - const char *zOldVfsName, - int (*xOut)(const char*,void*), - void *pOutArg, - int makeDefault - ); - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); -#endif -#ifdef SQLITE_ENABLE_MULTIPLEX - }else if( strcmp(z,"-multiplex")==0 ){ - extern int sqlite3_multiple_initialize(const char*,int); - sqlite3_multiplex_initialize(0, 1); -#endif - }else if( strcmp(z,"-mmap")==0 ){ - sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); - sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); - }else if( strcmp(z,"-vfs")==0 ){ - sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i)); - if( pVfs ){ - sqlite3_vfs_register(pVfs, 1); - }else{ - utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]); - exit(1); - } - } - } - if( data.zDbFilename==0 ){ -#ifndef SQLITE_OMIT_MEMORYDB - data.zDbFilename = ":memory:"; - warnInmemoryDb = argc==1; -#else - utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0); - return 1; -#endif - } - data.out = stdout; - - /* Go ahead and open the database file if it already exists. If the - ** file does not exist, delay opening it. This prevents empty database - ** files from being created if a user mistypes the database name argument - ** to the sqlite command-line tool. - */ - if( access(data.zDbFilename, 0)==0 ){ - open_db(&data, 0); - } - - /* Process the initialization file if there is one. If no -init option - ** is given on the command line, look for a file named ~/.sqliterc and - ** try to process it. - */ - process_sqliterc(&data,zInitFile); - - /* Make a second pass through the command-line argument and set - ** options. This second pass is delayed until after the initialization - ** file is processed so that the command-line arguments will override - ** settings in the initialization file. - */ - for(i=1; i=1400 -# define _CRT_RAND_S -#endif - -/* -** Include the header file used to customize the compiler options for MSVC. -** This should be done first so that it can successfully prevent spurious -** compiler warnings due to subsequent content in this file and other files -** that are included by this file. -*/ -/************** Include msvc.h in the middle of sqliteInt.h ******************/ -/************** Begin file msvc.h ********************************************/ -/* -** 2015 January 12 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to MSVC. -*/ -#ifndef SQLITE_MSVC_H -#define SQLITE_MSVC_H - -#if defined(_MSC_VER) -#pragma warning(disable : 4054) -#pragma warning(disable : 4055) -#pragma warning(disable : 4100) -#pragma warning(disable : 4127) -#pragma warning(disable : 4130) -#pragma warning(disable : 4152) -#pragma warning(disable : 4189) -#pragma warning(disable : 4206) -#pragma warning(disable : 4210) -#pragma warning(disable : 4232) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) -#pragma warning(disable : 4306) -#pragma warning(disable : 4702) -#pragma warning(disable : 4706) -#endif /* defined(_MSC_VER) */ - -#endif /* SQLITE_MSVC_H */ - -/************** End of msvc.h ************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* -** Special setup for VxWorks -*/ -/************** Include vxworks.h in the middle of sqliteInt.h ***************/ -/************** Begin file vxworks.h *****************************************/ -/* -** 2015-03-02 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to Wind River's VxWorks -*/ -#if defined(__RTP__) || defined(_WRS_KERNEL) -/* This is VxWorks. Set up things specially for that OS -*/ -#include -#include /* amalgamator: dontcache */ -#define OS_VXWORKS 1 -#define SQLITE_OS_OTHER 0 -#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 -#define SQLITE_OMIT_LOAD_EXTENSION 1 -#define SQLITE_ENABLE_LOCKING_STYLE 0 -#define HAVE_UTIME 1 -#else -/* This is not VxWorks. */ -#define OS_VXWORKS 0 -#define HAVE_FCHOWN 1 -#define HAVE_READLINK 1 -#define HAVE_LSTAT 1 -#endif /* defined(_WRS_KERNEL) */ - -/************** End of vxworks.h *********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* -** These #defines should enable >2GB file support on POSIX if the -** underlying operating system supports it. If the OS lacks -** large file support, or if the OS is windows, these should be no-ops. -** -** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any -** system #includes. Hence, this block of code must be the very first -** code in all source files. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: Red Hat 7.2) but you want your code to work -** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in Red Hat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -** -** The previous paragraph was written in 2005. (This paragraph is written -** on 2008-11-28.) These days, all Linux kernels support large files, so -** you should probably leave LFS enabled. But some embedded platforms might -** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. -** -** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - -/* What version of GCC is being used. 0 means GCC is not being used */ -#ifdef __GNUC__ -# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) -#else -# define GCC_VERSION 0 -#endif - -/* Needed for various definitions... */ -#if defined(__GNUC__) && !defined(_GNU_SOURCE) -# define _GNU_SOURCE -#endif - -#if defined(__OpenBSD__) && !defined(_BSD_SOURCE) -# define _BSD_SOURCE -#endif - -/* -** For MinGW, check to see if we can include the header file containing its -** version information, among other things. Normally, this internal MinGW -** header file would [only] be included automatically by other MinGW header -** files; however, the contained version information is now required by this -** header file to work around binary compatibility issues (see below) and -** this is the only known way to reliably obtain it. This entire #if block -** would be completely unnecessary if there was any other way of detecting -** MinGW via their preprocessor (e.g. if they customized their GCC to define -** some MinGW-specific macros). When compiling for MinGW, either the -** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be -** defined; otherwise, detection of conditions specific to MinGW will be -** disabled. -*/ -#if defined(_HAVE_MINGW_H) -# include "mingw.h" -#elif defined(_HAVE__MINGW_H) -# include "_mingw.h" -#endif - -/* -** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T -** define is required to maintain binary compatibility with the MSVC runtime -** library in use (e.g. for Windows XP). -*/ -#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \ - defined(_WIN32) && !defined(_WIN64) && \ - defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \ - defined(__MSVCRT__) -# define _USE_32BIT_TIME_T -#endif - -/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear -** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for -** MinGW. -*/ -/************** Include sqlite3.h in the middle of sqliteInt.h ***************/ -/************** Begin file sqlite3.h *****************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the interface that the SQLite library -** presents to client programs. If a C-function, structure, datatype, -** or constant definition does not appear in this file, then it is -** not a published API of SQLite, is subject to change without -** notice, and should not be referenced by programs that use SQLite. -** -** Some of the definitions that are in this file are marked as -** "experimental". Experimental interfaces are normally new -** features recently added to SQLite. We do not anticipate changes -** to experimental interfaces but reserve the right to make minor changes -** if experience from use "in the wild" suggest such changes are prudent. -** -** The official C-language API documentation for SQLite is derived -** from comments in this file. This file is the authoritative source -** on how SQLite interfaces are supposed to operate. -** -** The name of this file under configuration management is "sqlite.h.in". -** The makefile makes some minor changes to this file (such as inserting -** the version number) and changes its name to "sqlite3.h" as -** part of the build process. -*/ -#ifndef SQLITE3_H -#define SQLITE3_H -#include /* Needed for the definition of va_list */ - -/* -** Make sure we can call this stuff from C++. -*/ -#if 0 -extern "C" { -#endif - - -/* -** Provide the ability to override linkage features of the interface. -*/ -#ifndef SQLITE_EXTERN -# define SQLITE_EXTERN extern -#endif -#ifndef SQLITE_API -# define SQLITE_API -#endif -#ifndef SQLITE_CDECL -# define SQLITE_CDECL -#endif -#ifndef SQLITE_APICALL -# define SQLITE_APICALL -#endif -#ifndef SQLITE_STDCALL -# define SQLITE_STDCALL SQLITE_APICALL -#endif -#ifndef SQLITE_CALLBACK -# define SQLITE_CALLBACK -#endif -#ifndef SQLITE_SYSAPI -# define SQLITE_SYSAPI -#endif - -/* -** These no-op macros are used in front of interfaces to mark those -** interfaces as either deprecated or experimental. New applications -** should not use deprecated interfaces - they are supported for backwards -** compatibility only. Application writers should be aware that -** experimental interfaces are subject to change in point releases. -** -** These macros used to resolve to various kinds of compiler magic that -** would generate warning messages when they were used. But that -** compiler magic ended up generating such a flurry of bug reports -** that we have taken it all out and gone back to using simple -** noop macros. -*/ -#define SQLITE_DEPRECATED -#define SQLITE_EXPERIMENTAL - -/* -** Ensure these symbols were not defined by some previous header file. -*/ -#ifdef SQLITE_VERSION -# undef SQLITE_VERSION -#endif -#ifdef SQLITE_VERSION_NUMBER -# undef SQLITE_VERSION_NUMBER -#endif - -/* -** CAPI3REF: Compile-Time Library Version Numbers -** -** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header -** evaluates to a string literal that is the SQLite version in the -** format "X.Y.Z" where X is the major version number (always 3 for -** SQLite3) and Y is the minor version number and Z is the release number.)^ -** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer -** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same -** numbers used in [SQLITE_VERSION].)^ -** The SQLITE_VERSION_NUMBER for any given release of SQLite will also -** be larger than the release from which it is derived. Either Y will -** be held constant and Z will be incremented or else Y will be incremented -** and Z will be reset to zero. -** -** Since [version 3.6.18] ([dateof:3.6.18]), -** SQLite source code has been stored in the -** Fossil configuration management -** system. ^The SQLITE_SOURCE_ID macro evaluates to -** a string which identifies a particular check-in of SQLite -** within its configuration management system. ^The SQLITE_SOURCE_ID -** string contains the date and time of the check-in (UTC) and an SHA1 -** hash of the entire source tree. -** -** See also: [sqlite3_libversion()], -** [sqlite3_libversion_number()], [sqlite3_sourceid()], -** [sqlite_version()] and [sqlite_source_id()]. -*/ -#define SQLITE_VERSION "3.15.1" -#define SQLITE_VERSION_NUMBER 3015001 -#define SQLITE_SOURCE_ID "2016-11-04 12:08:49 1136863c76576110e710dd5d69ab6bf347c65e36" - -/* -** CAPI3REF: Run-Time Library Version Numbers -** KEYWORDS: sqlite3_version, sqlite3_sourceid -** -** These interfaces provide the same information as the [SQLITE_VERSION], -** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros -** but are associated with the library instead of the header file. ^(Cautious -** programmers might include assert() statements in their application to -** verify that values returned by these interfaces match the macros in -** the header, and thus ensure that the application is -** compiled with matching library and header files. -** -**
-** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
-** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
-** 
)^ -** -** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] -** macro. ^The sqlite3_libversion() function returns a pointer to the -** to the sqlite3_version[] string constant. The sqlite3_libversion() -** function is provided for use in DLLs since DLL users usually do not have -** direct access to string constants within the DLL. ^The -** sqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns -** a pointer to a string constant whose value is the same as the -** [SQLITE_SOURCE_ID] C preprocessor macro. -** -** See also: [sqlite_version()] and [sqlite_source_id()]. -*/ -SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; -SQLITE_API const char *sqlite3_libversion(void); -SQLITE_API const char *sqlite3_sourceid(void); -SQLITE_API int sqlite3_libversion_number(void); - -/* -** CAPI3REF: Run-Time Library Compilation Options Diagnostics -** -** ^The sqlite3_compileoption_used() function returns 0 or 1 -** indicating whether the specified option was defined at -** compile time. ^The SQLITE_ prefix may be omitted from the -** option name passed to sqlite3_compileoption_used(). -** -** ^The sqlite3_compileoption_get() function allows iterating -** over the list of options that were defined at compile time by -** returning the N-th compile time option string. ^If N is out of range, -** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ -** prefix is omitted from any strings returned by -** sqlite3_compileoption_get(). -** -** ^Support for the diagnostic functions sqlite3_compileoption_used() -** and sqlite3_compileoption_get() may be omitted by specifying the -** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. -** -** See also: SQL functions [sqlite_compileoption_used()] and -** [sqlite_compileoption_get()] and the [compile_options pragma]. -*/ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_API int sqlite3_compileoption_used(const char *zOptName); -SQLITE_API const char *sqlite3_compileoption_get(int N); -#endif - -/* -** CAPI3REF: Test To See If The Library Is Threadsafe -** -** ^The sqlite3_threadsafe() function returns zero if and only if -** SQLite was compiled with mutexing code omitted due to the -** [SQLITE_THREADSAFE] compile-time option being set to 0. -** -** SQLite can be compiled with or without mutexes. When -** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes -** are enabled and SQLite is threadsafe. When the -** [SQLITE_THREADSAFE] macro is 0, -** the mutexes are omitted. Without the mutexes, it is not safe -** to use SQLite concurrently from more than one thread. -** -** Enabling mutexes incurs a measurable performance penalty. -** So if speed is of utmost importance, it makes sense to disable -** the mutexes. But for maximum safety, mutexes should be enabled. -** ^The default behavior is for mutexes to be enabled. -** -** This interface can be used by an application to make sure that the -** version of SQLite that it is linking against was compiled with -** the desired setting of the [SQLITE_THREADSAFE] macro. -** -** This interface only reports on the compile-time mutex setting -** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with -** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but -** can be fully or partially disabled using a call to [sqlite3_config()] -** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], -** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the -** sqlite3_threadsafe() function shows only the compile-time setting of -** thread safety, not any run-time changes to that setting made by -** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() -** is unchanged by calls to sqlite3_config().)^ -** -** See the [threading mode] documentation for additional information. -*/ -SQLITE_API int sqlite3_threadsafe(void); - -/* -** CAPI3REF: Database Connection Handle -** KEYWORDS: {database connection} {database connections} -** -** Each open SQLite database is represented by a pointer to an instance of -** the opaque structure named "sqlite3". It is useful to think of an sqlite3 -** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and -** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] -** and [sqlite3_close_v2()] are its destructors. There are many other -** interfaces (such as -** [sqlite3_prepare_v2()], [sqlite3_create_function()], and -** [sqlite3_busy_timeout()] to name but three) that are methods on an -** sqlite3 object. -*/ -typedef struct sqlite3 sqlite3; - -/* -** CAPI3REF: 64-Bit Integer Types -** KEYWORDS: sqlite_int64 sqlite_uint64 -** -** Because there is no cross-platform way to specify 64-bit integer types -** SQLite includes typedefs for 64-bit signed and unsigned integers. -** -** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. -** The sqlite_int64 and sqlite_uint64 types are supported for backwards -** compatibility only. -** -** ^The sqlite3_int64 and sqlite_int64 types can store integer values -** between -9223372036854775808 and +9223372036854775807 inclusive. ^The -** sqlite3_uint64 and sqlite_uint64 types can store integer values -** between 0 and +18446744073709551615 inclusive. -*/ -#ifdef SQLITE_INT64_TYPE - typedef SQLITE_INT64_TYPE sqlite_int64; - typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; -#elif defined(_MSC_VER) || defined(__BORLANDC__) - typedef __int64 sqlite_int64; - typedef unsigned __int64 sqlite_uint64; -#else - typedef long long int sqlite_int64; - typedef unsigned long long int sqlite_uint64; -#endif -typedef sqlite_int64 sqlite3_int64; -typedef sqlite_uint64 sqlite3_uint64; - -/* -** If compiling for a processor that lacks floating point support, -** substitute integer for floating-point. -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# define double sqlite3_int64 -#endif - -/* -** CAPI3REF: Closing A Database Connection -** DESTRUCTOR: sqlite3 -** -** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors -** for the [sqlite3] object. -** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if -** the [sqlite3] object is successfully destroyed and all associated -** resources are deallocated. -** -** ^If the database connection is associated with unfinalized prepared -** statements or unfinished sqlite3_backup objects then sqlite3_close() -** will leave the database connection open and return [SQLITE_BUSY]. -** ^If sqlite3_close_v2() is called with unfinalized prepared statements -** and/or unfinished sqlite3_backups, then the database connection becomes -** an unusable "zombie" which will automatically be deallocated when the -** last prepared statement is finalized or the last sqlite3_backup is -** finished. The sqlite3_close_v2() interface is intended for use with -** host languages that are garbage collected, and where the order in which -** destructors are called is arbitrary. -** -** Applications should [sqlite3_finalize | finalize] all [prepared statements], -** [sqlite3_blob_close | close] all [BLOB handles], and -** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated -** with the [sqlite3] object prior to attempting to close the object. ^If -** sqlite3_close_v2() is called on a [database connection] that still has -** outstanding [prepared statements], [BLOB handles], and/or -** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation -** of resources is deferred until all [prepared statements], [BLOB handles], -** and [sqlite3_backup] objects are also destroyed. -** -** ^If an [sqlite3] object is destroyed while a transaction is open, -** the transaction is automatically rolled back. -** -** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] -** must be either a NULL -** pointer or an [sqlite3] object pointer obtained -** from [sqlite3_open()], [sqlite3_open16()], or -** [sqlite3_open_v2()], and not previously closed. -** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer -** argument is a harmless no-op. -*/ -SQLITE_API int sqlite3_close(sqlite3*); -SQLITE_API int sqlite3_close_v2(sqlite3*); - -/* -** The type for a callback function. -** This is legacy and deprecated. It is included for historical -** compatibility and is not documented. -*/ -typedef int (*sqlite3_callback)(void*,int,char**, char**); - -/* -** CAPI3REF: One-Step Query Execution Interface -** METHOD: sqlite3 -** -** The sqlite3_exec() interface is a convenience wrapper around -** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], -** that allows an application to run multiple statements of SQL -** without having to use a lot of C code. -** -** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, -** semicolon-separate SQL statements passed into its 2nd argument, -** in the context of the [database connection] passed in as its 1st -** argument. ^If the callback function of the 3rd argument to -** sqlite3_exec() is not NULL, then it is invoked for each result row -** coming out of the evaluated SQL statements. ^The 4th argument to -** sqlite3_exec() is relayed through to the 1st argument of each -** callback invocation. ^If the callback pointer to sqlite3_exec() -** is NULL, then no callback is ever invoked and result rows are -** ignored. -** -** ^If an error occurs while evaluating the SQL statements passed into -** sqlite3_exec(), then execution of the current statement stops and -** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() -** is not NULL then any error message is written into memory obtained -** from [sqlite3_malloc()] and passed back through the 5th parameter. -** To avoid memory leaks, the application should invoke [sqlite3_free()] -** on error message strings returned through the 5th parameter of -** sqlite3_exec() after the error message string is no longer needed. -** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors -** occur, then sqlite3_exec() sets the pointer in its 5th parameter to -** NULL before returning. -** -** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() -** routine returns SQLITE_ABORT without invoking the callback again and -** without running any subsequent SQL statements. -** -** ^The 2nd argument to the sqlite3_exec() callback function is the -** number of columns in the result. ^The 3rd argument to the sqlite3_exec() -** callback is an array of pointers to strings obtained as if from -** [sqlite3_column_text()], one for each column. ^If an element of a -** result row is NULL then the corresponding string pointer for the -** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the -** sqlite3_exec() callback is an array of pointers to strings where each -** entry represents the name of corresponding result column as obtained -** from [sqlite3_column_name()]. -** -** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer -** to an empty string, or a pointer that contains only whitespace and/or -** SQL comments, then no SQL statements are evaluated and the database -** is not changed. -** -** Restrictions: -** -**
    -**
  • The application must ensure that the 1st parameter to sqlite3_exec() -** is a valid and open [database connection]. -**
  • The application must not close the [database connection] specified by -** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. -**
  • The application must not modify the SQL statement text passed into -** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. -**
-*/ -SQLITE_API int sqlite3_exec( - sqlite3*, /* An open database */ - const char *sql, /* SQL to be evaluated */ - int (*callback)(void*,int,char**,char**), /* Callback function */ - void *, /* 1st argument to callback */ - char **errmsg /* Error msg written here */ -); - -/* -** CAPI3REF: Result Codes -** KEYWORDS: {result code definitions} -** -** Many SQLite functions return an integer result code from the set shown -** here in order to indicate success or failure. -** -** New error codes may be added in future versions of SQLite. -** -** See also: [extended result code definitions] -*/ -#define SQLITE_OK 0 /* Successful result */ -/* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* SQL error or missing database */ -#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ -#define SQLITE_PERM 3 /* Access permission denied */ -#define SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define SQLITE_BUSY 5 /* The database file is locked */ -#define SQLITE_LOCKED 6 /* A table in the database is locked */ -#define SQLITE_NOMEM 7 /* A malloc() failed */ -#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ -#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ -#define SQLITE_FULL 13 /* Insertion failed because database is full */ -#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Database is empty */ -#define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ -#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -#define SQLITE_MISMATCH 20 /* Data type mismatch */ -#define SQLITE_MISUSE 21 /* Library used incorrectly */ -#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Auxiliary database format error */ -#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ -#define SQLITE_NOTADB 26 /* File opened that is not a database file */ -#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ -#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ -#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ -/* end-of-error-codes */ - -/* -** CAPI3REF: Extended Result Codes -** KEYWORDS: {extended result code definitions} -** -** In its default configuration, SQLite API routines return one of 30 integer -** [result codes]. However, experience has shown that many of -** these result codes are too coarse-grained. They do not provide as -** much information about problems as programmers might like. In an effort to -** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8] -** and later) include -** support for additional result codes that provide more detailed information -** about errors. These [extended result codes] are enabled or disabled -** on a per database connection basis using the -** [sqlite3_extended_result_codes()] API. Or, the extended code for -** the most recent error can be obtained using -** [sqlite3_extended_errcode()]. -*/ -#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) -#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) -#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) -#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) -#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) -#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) -#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) -#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) -#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) -#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) -#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) -#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) -#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) -#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) -#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) -#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) -#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) -#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) -#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) -#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) -#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) -#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) -#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) -#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) -#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) -#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) -#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) -#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) -#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) -#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) -#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) -#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) -#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) -#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) -#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) -#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) -#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) -#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) -#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) -#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) -#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) -#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) -#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) -#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) -#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) -#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) -#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) -#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) -#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) -#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) -#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) -#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) -#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) -#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) -#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) -#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) - -/* -** CAPI3REF: Flags For File Open Operations -** -** These bit values are intended for use in the -** 3rd parameter to the [sqlite3_open_v2()] interface and -** in the 4th parameter to the [sqlite3_vfs.xOpen] method. -*/ -#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ -#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ -#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ -#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ -#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ -#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ -#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ -#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ -#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ -#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ -#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ - -/* Reserved: 0x00F00000 */ - -/* -** CAPI3REF: Device Characteristics -** -** The xDeviceCharacteristics method of the [sqlite3_io_methods] -** object returns an integer which is a vector of these -** bit values expressing I/O characteristics of the mass storage -** device that holds the file that the [sqlite3_io_methods] -** refers to. -** -** The SQLITE_IOCAP_ATOMIC property means that all writes of -** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values -** mean that writes of blocks that are nnn bytes in size and -** are aligned to an address which is an integer multiple of -** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means -** that when data is appended to a file, the data is appended -** first then the size of the file is extended, never the other -** way around. The SQLITE_IOCAP_SEQUENTIAL property means that -** information is written to disk in the same order as calls -** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that -** after reboot following a crash or power loss, the only bytes in a -** file that were written at the application level might have changed -** and that adjacent bytes, even bytes within the same sector are -** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN -** flag indicate that a file cannot be deleted when open. The -** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on -** read-only media and cannot be changed even by processes with -** elevated privileges. -*/ -#define SQLITE_IOCAP_ATOMIC 0x00000001 -#define SQLITE_IOCAP_ATOMIC512 0x00000002 -#define SQLITE_IOCAP_ATOMIC1K 0x00000004 -#define SQLITE_IOCAP_ATOMIC2K 0x00000008 -#define SQLITE_IOCAP_ATOMIC4K 0x00000010 -#define SQLITE_IOCAP_ATOMIC8K 0x00000020 -#define SQLITE_IOCAP_ATOMIC16K 0x00000040 -#define SQLITE_IOCAP_ATOMIC32K 0x00000080 -#define SQLITE_IOCAP_ATOMIC64K 0x00000100 -#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 -#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 -#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 -#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 -#define SQLITE_IOCAP_IMMUTABLE 0x00002000 - -/* -** CAPI3REF: File Locking Levels -** -** SQLite uses one of these integer values as the second -** argument to calls it makes to the xLock() and xUnlock() methods -** of an [sqlite3_io_methods] object. -*/ -#define SQLITE_LOCK_NONE 0 -#define SQLITE_LOCK_SHARED 1 -#define SQLITE_LOCK_RESERVED 2 -#define SQLITE_LOCK_PENDING 3 -#define SQLITE_LOCK_EXCLUSIVE 4 - -/* -** CAPI3REF: Synchronization Type Flags -** -** When SQLite invokes the xSync() method of an -** [sqlite3_io_methods] object it uses a combination of -** these integer values as the second argument. -** -** When the SQLITE_SYNC_DATAONLY flag is used, it means that the -** sync operation only needs to flush data to mass storage. Inode -** information need not be flushed. If the lower four bits of the flag -** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. -** If the lower four bits equal SQLITE_SYNC_FULL, that means -** to use Mac OS X style fullsync instead of fsync(). -** -** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags -** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL -** settings. The [synchronous pragma] determines when calls to the -** xSync VFS method occur and applies uniformly across all platforms. -** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how -** energetic or rigorous or forceful the sync operations are and -** only make a difference on Mac OSX for the default SQLite code. -** (Third-party VFS implementations might also make the distinction -** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the -** operating systems natively supported by SQLite, only Mac OSX -** cares about the difference.) -*/ -#define SQLITE_SYNC_NORMAL 0x00002 -#define SQLITE_SYNC_FULL 0x00003 -#define SQLITE_SYNC_DATAONLY 0x00010 - -/* -** CAPI3REF: OS Interface Open File Handle -** -** An [sqlite3_file] object represents an open file in the -** [sqlite3_vfs | OS interface layer]. Individual OS interface -** implementations will -** want to subclass this object by appending additional fields -** for their own use. The pMethods entry is a pointer to an -** [sqlite3_io_methods] object that defines methods for performing -** I/O operations on the open file. -*/ -typedef struct sqlite3_file sqlite3_file; -struct sqlite3_file { - const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ -}; - -/* -** CAPI3REF: OS Interface File Virtual Methods Object -** -** Every file opened by the [sqlite3_vfs.xOpen] method populates an -** [sqlite3_file] object (or, more commonly, a subclass of the -** [sqlite3_file] object) with a pointer to an instance of this object. -** This object defines the methods used to perform various operations -** against the open file represented by the [sqlite3_file] object. -** -** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element -** to a non-NULL pointer, then the sqlite3_io_methods.xClose method -** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The -** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] -** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element -** to NULL. -** -** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or -** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). -** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] -** flag may be ORed in to indicate that only the data of the file -** and not its inode needs to be synced. -** -** The integer values to xLock() and xUnlock() are one of -**
    -**
  • [SQLITE_LOCK_NONE], -**
  • [SQLITE_LOCK_SHARED], -**
  • [SQLITE_LOCK_RESERVED], -**
  • [SQLITE_LOCK_PENDING], or -**
  • [SQLITE_LOCK_EXCLUSIVE]. -**
-** xLock() increases the lock. xUnlock() decreases the lock. -** The xCheckReservedLock() method checks whether any database connection, -** either in this process or in some other process, is holding a RESERVED, -** PENDING, or EXCLUSIVE lock on the file. It returns true -** if such a lock exists and false otherwise. -** -** The xFileControl() method is a generic interface that allows custom -** VFS implementations to directly control an open file using the -** [sqlite3_file_control()] interface. The second "op" argument is an -** integer opcode. The third argument is a generic pointer intended to -** point to a structure that may contain arguments or space in which to -** write return values. Potential uses for xFileControl() might be -** functions to enable blocking locks with timeouts, to change the -** locking strategy (for example to use dot-file locks), to inquire -** about the status of a lock, or to break stale locks. The SQLite -** core reserves all opcodes less than 100 for its own use. -** A [file control opcodes | list of opcodes] less than 100 is available. -** Applications that define a custom xFileControl method should use opcodes -** greater than 100 to avoid conflicts. VFS implementations should -** return [SQLITE_NOTFOUND] for file control opcodes that they do not -** recognize. -** -** The xSectorSize() method returns the sector size of the -** device that underlies the file. The sector size is the -** minimum write that can be performed without disturbing -** other bytes in the file. The xDeviceCharacteristics() -** method returns a bit vector describing behaviors of the -** underlying device: -** -**
    -**
  • [SQLITE_IOCAP_ATOMIC] -**
  • [SQLITE_IOCAP_ATOMIC512] -**
  • [SQLITE_IOCAP_ATOMIC1K] -**
  • [SQLITE_IOCAP_ATOMIC2K] -**
  • [SQLITE_IOCAP_ATOMIC4K] -**
  • [SQLITE_IOCAP_ATOMIC8K] -**
  • [SQLITE_IOCAP_ATOMIC16K] -**
  • [SQLITE_IOCAP_ATOMIC32K] -**
  • [SQLITE_IOCAP_ATOMIC64K] -**
  • [SQLITE_IOCAP_SAFE_APPEND] -**
  • [SQLITE_IOCAP_SEQUENTIAL] -**
-** -** The SQLITE_IOCAP_ATOMIC property means that all writes of -** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values -** mean that writes of blocks that are nnn bytes in size and -** are aligned to an address which is an integer multiple of -** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means -** that when data is appended to a file, the data is appended -** first then the size of the file is extended, never the other -** way around. The SQLITE_IOCAP_SEQUENTIAL property means that -** information is written to disk in the same order as calls -** to xWrite(). -** -** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill -** in the unread portions of the buffer with zeros. A VFS that -** fails to zero-fill short reads might seem to work. However, -** failure to zero-fill short reads will eventually lead to -** database corruption. -*/ -typedef struct sqlite3_io_methods sqlite3_io_methods; -struct sqlite3_io_methods { - int iVersion; - int (*xClose)(sqlite3_file*); - int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); - int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); - int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); - int (*xSync)(sqlite3_file*, int flags); - int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); - int (*xLock)(sqlite3_file*, int); - int (*xUnlock)(sqlite3_file*, int); - int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); - int (*xFileControl)(sqlite3_file*, int op, void *pArg); - int (*xSectorSize)(sqlite3_file*); - int (*xDeviceCharacteristics)(sqlite3_file*); - /* Methods above are valid for version 1 */ - int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); - int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); - void (*xShmBarrier)(sqlite3_file*); - int (*xShmUnmap)(sqlite3_file*, int deleteFlag); - /* Methods above are valid for version 2 */ - int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); - int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); - /* Methods above are valid for version 3 */ - /* Additional methods may be added in future releases */ -}; - -/* -** CAPI3REF: Standard File Control Opcodes -** KEYWORDS: {file control opcodes} {file control opcode} -** -** These integer constants are opcodes for the xFileControl method -** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] -** interface. -** -**
    -**
  • [[SQLITE_FCNTL_LOCKSTATE]] -** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This -** opcode causes the xFileControl method to write the current state of -** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], -** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) -** into an integer that the pArg argument points to. This capability -** is used during testing and is only available when the SQLITE_TEST -** compile-time option is used. -** -**
  • [[SQLITE_FCNTL_SIZE_HINT]] -** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS -** layer a hint of how large the database file will grow to be during the -** current transaction. This hint is not guaranteed to be accurate but it -** is often close. The underlying VFS might choose to preallocate database -** file space based on this hint in order to help writes to the database -** file run faster. -** -**
  • [[SQLITE_FCNTL_CHUNK_SIZE]] -** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS -** extends and truncates the database file in chunks of a size specified -** by the user. The fourth argument to [sqlite3_file_control()] should -** point to an integer (type int) containing the new chunk-size to use -** for the nominated database. Allocating database file space in large -** chunks (say 1MB at a time), may reduce file-system fragmentation and -** improve performance on some systems. -** -**
  • [[SQLITE_FCNTL_FILE_POINTER]] -** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer -** to the [sqlite3_file] object associated with a particular database -** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER]. -** -**
  • [[SQLITE_FCNTL_JOURNAL_POINTER]] -** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer -** to the [sqlite3_file] object associated with the journal file (either -** the [rollback journal] or the [write-ahead log]) for a particular database -** connection. See also [SQLITE_FCNTL_FILE_POINTER]. -** -**
  • [[SQLITE_FCNTL_SYNC_OMITTED]] -** No longer in use. -** -**
  • [[SQLITE_FCNTL_SYNC]] -** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and -** sent to the VFS immediately before the xSync method is invoked on a -** database file descriptor. Or, if the xSync method is not invoked -** because the user has configured SQLite with -** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place -** of the xSync method. In most cases, the pointer argument passed with -** this file-control is NULL. However, if the database file is being synced -** as part of a multi-database commit, the argument points to a nul-terminated -** string containing the transactions master-journal file name. VFSes that -** do not need this signal should silently ignore this opcode. Applications -** should not call [sqlite3_file_control()] with this opcode as doing so may -** disrupt the operation of the specialized VFSes that do require it. -** -**
  • [[SQLITE_FCNTL_COMMIT_PHASETWO]] -** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite -** and sent to the VFS after a transaction has been committed immediately -** but before the database is unlocked. VFSes that do not need this signal -** should silently ignore this opcode. Applications should not call -** [sqlite3_file_control()] with this opcode as doing so may disrupt the -** operation of the specialized VFSes that do require it. -** -**
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] -** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic -** retry counts and intervals for certain disk I/O operations for the -** windows [VFS] in order to provide robustness in the presence of -** anti-virus programs. By default, the windows VFS will retry file read, -** file write, and file delete operations up to 10 times, with a delay -** of 25 milliseconds before the first retry and with the delay increasing -** by an additional 25 milliseconds with each subsequent retry. This -** opcode allows these two values (10 retries and 25 milliseconds of delay) -** to be adjusted. The values are changed for all database connections -** within the same process. The argument is a pointer to an array of two -** integers where the first integer i the new retry count and the second -** integer is the delay. If either integer is negative, then the setting -** is not changed but instead the prior value of that setting is written -** into the array entry, allowing the current retry settings to be -** interrogated. The zDbName parameter is ignored. -** -**
  • [[SQLITE_FCNTL_PERSIST_WAL]] -** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the -** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary -** write ahead log and shared memory files used for transaction control -** are automatically deleted when the latest connection to the database -** closes. Setting persistent WAL mode causes those files to persist after -** close. Persisting the files is useful when other processes that do not -** have write permission on the directory containing the database file want -** to read the database file, as the WAL and shared memory files must exist -** in order for the database to be readable. The fourth parameter to -** [sqlite3_file_control()] for this opcode should be a pointer to an integer. -** That integer is 0 to disable persistent WAL mode or 1 to enable persistent -** WAL mode. If the integer is -1, then it is overwritten with the current -** WAL persistence setting. -** -**
  • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] -** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the -** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting -** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the -** xDeviceCharacteristics methods. The fourth parameter to -** [sqlite3_file_control()] for this opcode should be a pointer to an integer. -** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage -** mode. If the integer is -1, then it is overwritten with the current -** zero-damage mode setting. -** -**
  • [[SQLITE_FCNTL_OVERWRITE]] -** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening -** a write transaction to indicate that, unless it is rolled back for some -** reason, the entire database file will be overwritten by the current -** transaction. This is used by VACUUM operations. -** -**
  • [[SQLITE_FCNTL_VFSNAME]] -** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of -** all [VFSes] in the VFS stack. The names are of all VFS shims and the -** final bottom-level VFS are written into memory obtained from -** [sqlite3_malloc()] and the result is stored in the char* variable -** that the fourth parameter of [sqlite3_file_control()] points to. -** The caller is responsible for freeing the memory when done. As with -** all file-control actions, there is no guarantee that this will actually -** do anything. Callers should initialize the char* variable to a NULL -** pointer in case this file-control is not implemented. This file-control -** is intended for diagnostic use only. -** -**
  • [[SQLITE_FCNTL_VFS_POINTER]] -** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level -** [VFSes] currently in use. ^(The argument X in -** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be -** of type "[sqlite3_vfs] **". This opcodes will set *X -** to a pointer to the top-level VFS.)^ -** ^When there are multiple VFS shims in the stack, this opcode finds the -** upper-most shim only. -** -**
  • [[SQLITE_FCNTL_PRAGMA]] -** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] -** file control is sent to the open [sqlite3_file] object corresponding -** to the database file to which the pragma statement refers. ^The argument -** to the [SQLITE_FCNTL_PRAGMA] file control is an array of -** pointers to strings (char**) in which the second element of the array -** is the name of the pragma and the third element is the argument to the -** pragma or NULL if the pragma has no argument. ^The handler for an -** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element -** of the char** argument point to a string obtained from [sqlite3_mprintf()] -** or the equivalent and that string will become the result of the pragma or -** the error message if the pragma fails. ^If the -** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal -** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] -** file control returns [SQLITE_OK], then the parser assumes that the -** VFS has handled the PRAGMA itself and the parser generates a no-op -** prepared statement if result string is NULL, or that returns a copy -** of the result string if the string is non-NULL. -** ^If the [SQLITE_FCNTL_PRAGMA] file control returns -** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means -** that the VFS encountered an error while handling the [PRAGMA] and the -** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] -** file control occurs at the beginning of pragma statement analysis and so -** it is able to override built-in [PRAGMA] statements. -** -**
  • [[SQLITE_FCNTL_BUSYHANDLER]] -** ^The [SQLITE_FCNTL_BUSYHANDLER] -** file-control may be invoked by SQLite on the database file handle -** shortly after it is opened in order to provide a custom VFS with access -** to the connections busy-handler callback. The argument is of type (void **) -** - an array of two (void *) values. The first (void *) actually points -** to a function of type (int (*)(void *)). In order to invoke the connections -** busy-handler, this function should be invoked with the second (void *) in -** the array as the only argument. If it returns non-zero, then the operation -** should be retried. If it returns zero, the custom VFS should abandon the -** current operation. -** -**
  • [[SQLITE_FCNTL_TEMPFILENAME]] -** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control -** to have SQLite generate a -** temporary filename using the same algorithm that is followed to generate -** temporary filenames for TEMP tables and other internal uses. The -** argument should be a char** which will be filled with the filename -** written into memory obtained from [sqlite3_malloc()]. The caller should -** invoke [sqlite3_free()] on the result to avoid a memory leak. -** -**
  • [[SQLITE_FCNTL_MMAP_SIZE]] -** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the -** maximum number of bytes that will be used for memory-mapped I/O. -** The argument is a pointer to a value of type sqlite3_int64 that -** is an advisory maximum number of bytes in the file to memory map. The -** pointer is overwritten with the old value. The limit is not changed if -** the value originally pointed to is negative, and so the current limit -** can be queried by passing in a pointer to a negative number. This -** file-control is used internally to implement [PRAGMA mmap_size]. -** -**
  • [[SQLITE_FCNTL_TRACE]] -** The [SQLITE_FCNTL_TRACE] file control provides advisory information -** to the VFS about what the higher layers of the SQLite stack are doing. -** This file control is used by some VFS activity tracing [shims]. -** The argument is a zero-terminated string. Higher layers in the -** SQLite stack may generate instances of this file control if -** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. -** -**
  • [[SQLITE_FCNTL_HAS_MOVED]] -** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a -** pointer to an integer and it writes a boolean into that integer depending -** on whether or not the file has been renamed, moved, or deleted since it -** was first opened. -** -**
  • [[SQLITE_FCNTL_WIN32_GET_HANDLE]] -** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the -** underlying native file handle associated with a file handle. This file -** control interprets its argument as a pointer to a native file handle and -** writes the resulting value there. -** -**
  • [[SQLITE_FCNTL_WIN32_SET_HANDLE]] -** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This -** opcode causes the xFileControl method to swap the file handle with the one -** pointed to by the pArg argument. This capability is used during testing -** and only needs to be supported when SQLITE_TEST is defined. -** -**
  • [[SQLITE_FCNTL_WAL_BLOCK]] -** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might -** be advantageous to block on the next WAL lock if the lock is not immediately -** available. The WAL subsystem issues this signal during rare -** circumstances in order to fix a problem with priority inversion. -** Applications should not use this file-control. -** -**
  • [[SQLITE_FCNTL_ZIPVFS]] -** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other -** VFS should return SQLITE_NOTFOUND for this opcode. -** -**
  • [[SQLITE_FCNTL_RBU]] -** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by -** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for -** this opcode. -**
-*/ -#define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 -#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 -#define SQLITE_FCNTL_LAST_ERRNO 4 -#define SQLITE_FCNTL_SIZE_HINT 5 -#define SQLITE_FCNTL_CHUNK_SIZE 6 -#define SQLITE_FCNTL_FILE_POINTER 7 -#define SQLITE_FCNTL_SYNC_OMITTED 8 -#define SQLITE_FCNTL_WIN32_AV_RETRY 9 -#define SQLITE_FCNTL_PERSIST_WAL 10 -#define SQLITE_FCNTL_OVERWRITE 11 -#define SQLITE_FCNTL_VFSNAME 12 -#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 -#define SQLITE_FCNTL_PRAGMA 14 -#define SQLITE_FCNTL_BUSYHANDLER 15 -#define SQLITE_FCNTL_TEMPFILENAME 16 -#define SQLITE_FCNTL_MMAP_SIZE 18 -#define SQLITE_FCNTL_TRACE 19 -#define SQLITE_FCNTL_HAS_MOVED 20 -#define SQLITE_FCNTL_SYNC 21 -#define SQLITE_FCNTL_COMMIT_PHASETWO 22 -#define SQLITE_FCNTL_WIN32_SET_HANDLE 23 -#define SQLITE_FCNTL_WAL_BLOCK 24 -#define SQLITE_FCNTL_ZIPVFS 25 -#define SQLITE_FCNTL_RBU 26 -#define SQLITE_FCNTL_VFS_POINTER 27 -#define SQLITE_FCNTL_JOURNAL_POINTER 28 -#define SQLITE_FCNTL_WIN32_GET_HANDLE 29 - -/* deprecated names */ -#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE -#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE -#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO - - -/* -** CAPI3REF: Mutex Handle -** -** The mutex module within SQLite defines [sqlite3_mutex] to be an -** abstract type for a mutex object. The SQLite core never looks -** at the internal representation of an [sqlite3_mutex]. It only -** deals with pointers to the [sqlite3_mutex] object. -** -** Mutexes are created using [sqlite3_mutex_alloc()]. -*/ -typedef struct sqlite3_mutex sqlite3_mutex; - -/* -** CAPI3REF: Loadable Extension Thunk -** -** A pointer to the opaque sqlite3_api_routines structure is passed as -** the third parameter to entry points of [loadable extensions]. This -** structure must be typedefed in order to work around compiler warnings -** on some platforms. -*/ -typedef struct sqlite3_api_routines sqlite3_api_routines; - -/* -** CAPI3REF: OS Interface Object -** -** An instance of the sqlite3_vfs object defines the interface between -** the SQLite core and the underlying operating system. The "vfs" -** in the name of the object stands for "virtual file system". See -** the [VFS | VFS documentation] for further information. -** -** The value of the iVersion field is initially 1 but may be larger in -** future versions of SQLite. Additional fields may be appended to this -** object when the iVersion value is increased. Note that the structure -** of the sqlite3_vfs object changes in the transaction between -** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not -** modified. -** -** The szOsFile field is the size of the subclassed [sqlite3_file] -** structure used by this VFS. mxPathname is the maximum length of -** a pathname in this VFS. -** -** Registered sqlite3_vfs objects are kept on a linked list formed by -** the pNext pointer. The [sqlite3_vfs_register()] -** and [sqlite3_vfs_unregister()] interfaces manage this list -** in a thread-safe way. The [sqlite3_vfs_find()] interface -** searches the list. Neither the application code nor the VFS -** implementation should use the pNext pointer. -** -** The pNext field is the only field in the sqlite3_vfs -** structure that SQLite will ever modify. SQLite will only access -** or modify this field while holding a particular static mutex. -** The application should never modify anything within the sqlite3_vfs -** object once the object has been registered. -** -** The zName field holds the name of the VFS module. The name must -** be unique across all VFS modules. -** -** [[sqlite3_vfs.xOpen]] -** ^SQLite guarantees that the zFilename parameter to xOpen -** is either a NULL pointer or string obtained -** from xFullPathname() with an optional suffix added. -** ^If a suffix is added to the zFilename parameter, it will -** consist of a single "-" character followed by no more than -** 11 alphanumeric and/or "-" characters. -** ^SQLite further guarantees that -** the string will be valid and unchanged until xClose() is -** called. Because of the previous sentence, -** the [sqlite3_file] can safely store a pointer to the -** filename if it needs to remember the filename for some reason. -** If the zFilename parameter to xOpen is a NULL pointer then xOpen -** must invent its own temporary name for the file. ^Whenever the -** xFilename parameter is NULL it will also be the case that the -** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. -** -** The flags argument to xOpen() includes all bits set in -** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] -** or [sqlite3_open16()] is used, then flags includes at least -** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. -** If xOpen() opens a file read-only then it sets *pOutFlags to -** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. -** -** ^(SQLite will also add one of the following flags to the xOpen() -** call, depending on the object being opened: -** -**
    -**
  • [SQLITE_OPEN_MAIN_DB] -**
  • [SQLITE_OPEN_MAIN_JOURNAL] -**
  • [SQLITE_OPEN_TEMP_DB] -**
  • [SQLITE_OPEN_TEMP_JOURNAL] -**
  • [SQLITE_OPEN_TRANSIENT_DB] -**
  • [SQLITE_OPEN_SUBJOURNAL] -**
  • [SQLITE_OPEN_MASTER_JOURNAL] -**
  • [SQLITE_OPEN_WAL] -**
)^ -** -** The file I/O implementation can use the object type flags to -** change the way it deals with files. For example, an application -** that does not care about crash recovery or rollback might make -** the open of a journal file a no-op. Writes to this journal would -** also be no-ops, and any attempt to read the journal would return -** SQLITE_IOERR. Or the implementation might recognize that a database -** file will be doing page-aligned sector reads and writes in a random -** order and set up its I/O subsystem accordingly. -** -** SQLite might also add one of the following flags to the xOpen method: -** -**
    -**
  • [SQLITE_OPEN_DELETEONCLOSE] -**
  • [SQLITE_OPEN_EXCLUSIVE] -**
-** -** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be -** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] -** will be set for TEMP databases and their journals, transient -** databases, and subjournals. -** -** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction -** with the [SQLITE_OPEN_CREATE] flag, which are both directly -** analogous to the O_EXCL and O_CREAT flags of the POSIX open() -** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the -** SQLITE_OPEN_CREATE, is used to indicate that file should always -** be created, and that it is an error if it already exists. -** It is not used to indicate the file should be opened -** for exclusive access. -** -** ^At least szOsFile bytes of memory are allocated by SQLite -** to hold the [sqlite3_file] structure passed as the third -** argument to xOpen. The xOpen method does not have to -** allocate the structure; it should just fill it in. Note that -** the xOpen method must set the sqlite3_file.pMethods to either -** a valid [sqlite3_io_methods] object or to NULL. xOpen must do -** this even if the open fails. SQLite expects that the sqlite3_file.pMethods -** element will be valid after xOpen returns regardless of the success -** or failure of the xOpen call. -** -** [[sqlite3_vfs.xAccess]] -** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] -** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to -** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] -** to test whether a file is at least readable. The file can be a -** directory. -** -** ^SQLite will always allocate at least mxPathname+1 bytes for the -** output buffer xFullPathname. The exact size of the output buffer -** is also passed as a parameter to both methods. If the output buffer -** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is -** handled as a fatal error by SQLite, vfs implementations should endeavor -** to prevent this by setting mxPathname to a sufficiently large value. -** -** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() -** interfaces are not strictly a part of the filesystem, but they are -** included in the VFS structure for completeness. -** The xRandomness() function attempts to return nBytes bytes -** of good-quality randomness into zOut. The return value is -** the actual number of bytes of randomness obtained. -** The xSleep() method causes the calling thread to sleep for at -** least the number of microseconds given. ^The xCurrentTime() -** method returns a Julian Day Number for the current date and time as -** a floating point value. -** ^The xCurrentTimeInt64() method returns, as an integer, the Julian -** Day Number multiplied by 86400000 (the number of milliseconds in -** a 24-hour day). -** ^SQLite will use the xCurrentTimeInt64() method to get the current -** date and time if that method is available (if iVersion is 2 or -** greater and the function pointer is not NULL) and will fall back -** to xCurrentTime() if xCurrentTimeInt64() is unavailable. -** -** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces -** are not used by the SQLite core. These optional interfaces are provided -** by some VFSes to facilitate testing of the VFS code. By overriding -** system calls with functions under its control, a test program can -** simulate faults and error conditions that would otherwise be difficult -** or impossible to induce. The set of system calls that can be overridden -** varies from one VFS to another, and from one version of the same VFS to the -** next. Applications that use these interfaces must be prepared for any -** or all of these interfaces to be NULL or for their behavior to change -** from one release to the next. Applications must not attempt to access -** any of these methods if the iVersion of the VFS is less than 3. -*/ -typedef struct sqlite3_vfs sqlite3_vfs; -typedef void (*sqlite3_syscall_ptr)(void); -struct sqlite3_vfs { - int iVersion; /* Structure version number (currently 3) */ - int szOsFile; /* Size of subclassed sqlite3_file */ - int mxPathname; /* Maximum file pathname length */ - sqlite3_vfs *pNext; /* Next registered VFS */ - const char *zName; /* Name of this virtual file system */ - void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, - int flags, int *pOutFlags); - int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); - int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); - int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); - void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); - void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); - void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); - void (*xDlClose)(sqlite3_vfs*, void*); - int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); - int (*xSleep)(sqlite3_vfs*, int microseconds); - int (*xCurrentTime)(sqlite3_vfs*, double*); - int (*xGetLastError)(sqlite3_vfs*, int, char *); - /* - ** The methods above are in version 1 of the sqlite_vfs object - ** definition. Those that follow are added in version 2 or later - */ - int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); - /* - ** The methods above are in versions 1 and 2 of the sqlite_vfs object. - ** Those below are for version 3 and greater. - */ - int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); - sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); - const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); - /* - ** The methods above are in versions 1 through 3 of the sqlite_vfs object. - ** New fields may be appended in future versions. The iVersion - ** value will increment whenever this happens. - */ -}; - -/* -** CAPI3REF: Flags for the xAccess VFS method -** -** These integer constants can be used as the third parameter to -** the xAccess method of an [sqlite3_vfs] object. They determine -** what kind of permissions the xAccess method is looking for. -** With SQLITE_ACCESS_EXISTS, the xAccess method -** simply checks whether the file exists. -** With SQLITE_ACCESS_READWRITE, the xAccess method -** checks whether the named directory is both readable and writable -** (in other words, if files can be added, removed, and renamed within -** the directory). -** The SQLITE_ACCESS_READWRITE constant is currently used only by the -** [temp_store_directory pragma], though this could change in a future -** release of SQLite. -** With SQLITE_ACCESS_READ, the xAccess method -** checks whether the file is readable. The SQLITE_ACCESS_READ constant is -** currently unused, though it might be used in a future release of -** SQLite. -*/ -#define SQLITE_ACCESS_EXISTS 0 -#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ -#define SQLITE_ACCESS_READ 2 /* Unused */ - -/* -** CAPI3REF: Flags for the xShmLock VFS method -** -** These integer constants define the various locking operations -** allowed by the xShmLock method of [sqlite3_io_methods]. The -** following are the only legal combinations of flags to the -** xShmLock method: -** -**
    -**
  • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED -**
  • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE -**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED -**
  • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE -**
-** -** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as -** was given on the corresponding lock. -** -** The xShmLock method can transition between unlocked and SHARED or -** between unlocked and EXCLUSIVE. It cannot transition between SHARED -** and EXCLUSIVE. -*/ -#define SQLITE_SHM_UNLOCK 1 -#define SQLITE_SHM_LOCK 2 -#define SQLITE_SHM_SHARED 4 -#define SQLITE_SHM_EXCLUSIVE 8 - -/* -** CAPI3REF: Maximum xShmLock index -** -** The xShmLock method on [sqlite3_io_methods] may use values -** between 0 and this upper bound as its "offset" argument. -** The SQLite core will never attempt to acquire or release a -** lock outside of this range -*/ -#define SQLITE_SHM_NLOCK 8 - - -/* -** CAPI3REF: Initialize The SQLite Library -** -** ^The sqlite3_initialize() routine initializes the -** SQLite library. ^The sqlite3_shutdown() routine -** deallocates any resources that were allocated by sqlite3_initialize(). -** These routines are designed to aid in process initialization and -** shutdown on embedded systems. Workstation applications using -** SQLite normally do not need to invoke either of these routines. -** -** A call to sqlite3_initialize() is an "effective" call if it is -** the first time sqlite3_initialize() is invoked during the lifetime of -** the process, or if it is the first time sqlite3_initialize() is invoked -** following a call to sqlite3_shutdown(). ^(Only an effective call -** of sqlite3_initialize() does any initialization. All other calls -** are harmless no-ops.)^ -** -** A call to sqlite3_shutdown() is an "effective" call if it is the first -** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only -** an effective call to sqlite3_shutdown() does any deinitialization. -** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ -** -** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() -** is not. The sqlite3_shutdown() interface must only be called from a -** single thread. All open [database connections] must be closed and all -** other SQLite resources must be deallocated prior to invoking -** sqlite3_shutdown(). -** -** Among other things, ^sqlite3_initialize() will invoke -** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() -** will invoke sqlite3_os_end(). -** -** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. -** ^If for some reason, sqlite3_initialize() is unable to initialize -** the library (perhaps it is unable to allocate a needed resource such -** as a mutex) it returns an [error code] other than [SQLITE_OK]. -** -** ^The sqlite3_initialize() routine is called internally by many other -** SQLite interfaces so that an application usually does not need to -** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] -** calls sqlite3_initialize() so the SQLite library will be automatically -** initialized when [sqlite3_open()] is called if it has not be initialized -** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] -** compile-time option, then the automatic calls to sqlite3_initialize() -** are omitted and the application must call sqlite3_initialize() directly -** prior to using any other SQLite interface. For maximum portability, -** it is recommended that applications always invoke sqlite3_initialize() -** directly prior to using any other SQLite interface. Future releases -** of SQLite may require this. In other words, the behavior exhibited -** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the -** default behavior in some future release of SQLite. -** -** The sqlite3_os_init() routine does operating-system specific -** initialization of the SQLite library. The sqlite3_os_end() -** routine undoes the effect of sqlite3_os_init(). Typical tasks -** performed by these routines include allocation or deallocation -** of static resources, initialization of global variables, -** setting up a default [sqlite3_vfs] module, or setting up -** a default configuration using [sqlite3_config()]. -** -** The application should never invoke either sqlite3_os_init() -** or sqlite3_os_end() directly. The application should only invoke -** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() -** interface is called automatically by sqlite3_initialize() and -** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate -** implementations for sqlite3_os_init() and sqlite3_os_end() -** are built into SQLite when it is compiled for Unix, Windows, or OS/2. -** When [custom builds | built for other platforms] -** (using the [SQLITE_OS_OTHER=1] compile-time -** option) the application must supply a suitable implementation for -** sqlite3_os_init() and sqlite3_os_end(). An application-supplied -** implementation of sqlite3_os_init() or sqlite3_os_end() -** must return [SQLITE_OK] on success and some other [error code] upon -** failure. -*/ -SQLITE_API int sqlite3_initialize(void); -SQLITE_API int sqlite3_shutdown(void); -SQLITE_API int sqlite3_os_init(void); -SQLITE_API int sqlite3_os_end(void); - -/* -** CAPI3REF: Configuring The SQLite Library -** -** The sqlite3_config() interface is used to make global configuration -** changes to SQLite in order to tune SQLite to the specific needs of -** the application. The default configuration is recommended for most -** applications and so this routine is usually not necessary. It is -** provided to support rare applications with unusual needs. -** -** The sqlite3_config() interface is not threadsafe. The application -** must ensure that no other SQLite interfaces are invoked by other -** threads while sqlite3_config() is running. -** -** The sqlite3_config() interface -** may only be invoked prior to library initialization using -** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** ^If sqlite3_config() is called after [sqlite3_initialize()] and before -** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. -** Note, however, that ^sqlite3_config() can be called as part of the -** implementation of an application-defined [sqlite3_os_init()]. -** -** The first argument to sqlite3_config() is an integer -** [configuration option] that determines -** what property of SQLite is to be configured. Subsequent arguments -** vary depending on the [configuration option] -** in the first argument. -** -** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. -** ^If the option is unknown or SQLite is unable to set the option -** then this routine returns a non-zero [error code]. -*/ -SQLITE_API int sqlite3_config(int, ...); - -/* -** CAPI3REF: Configure database connections -** METHOD: sqlite3 -** -** The sqlite3_db_config() interface is used to make configuration -** changes to a [database connection]. The interface is similar to -** [sqlite3_config()] except that the changes apply to a single -** [database connection] (specified in the first argument). -** -** The second argument to sqlite3_db_config(D,V,...) is the -** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code -** that indicates what aspect of the [database connection] is being configured. -** Subsequent arguments vary depending on the configuration verb. -** -** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if -** the call is considered successful. -*/ -SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); - -/* -** CAPI3REF: Memory Allocation Routines -** -** An instance of this object defines the interface between SQLite -** and low-level memory allocation routines. -** -** This object is used in only one place in the SQLite interface. -** A pointer to an instance of this object is the argument to -** [sqlite3_config()] when the configuration option is -** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. -** By creating an instance of this object -** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) -** during configuration, an application can specify an alternative -** memory allocation subsystem for SQLite to use for all of its -** dynamic memory needs. -** -** Note that SQLite comes with several [built-in memory allocators] -** that are perfectly adequate for the overwhelming majority of applications -** and that this object is only useful to a tiny minority of applications -** with specialized memory allocation requirements. This object is -** also used during testing of SQLite in order to specify an alternative -** memory allocator that simulates memory out-of-memory conditions in -** order to verify that SQLite recovers gracefully from such -** conditions. -** -** The xMalloc, xRealloc, and xFree methods must work like the -** malloc(), realloc() and free() functions from the standard C library. -** ^SQLite guarantees that the second argument to -** xRealloc is always a value returned by a prior call to xRoundup. -** -** xSize should return the allocated size of a memory allocation -** previously obtained from xMalloc or xRealloc. The allocated size -** is always at least as big as the requested size but may be larger. -** -** The xRoundup method returns what would be the allocated size of -** a memory allocation given a particular requested size. Most memory -** allocators round up memory allocations at least to the next multiple -** of 8. Some allocators round up to a larger multiple or to a power of 2. -** Every memory allocation request coming in through [sqlite3_malloc()] -** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, -** that causes the corresponding memory allocation to fail. -** -** The xInit method initializes the memory allocator. For example, -** it might allocate any require mutexes or initialize internal data -** structures. The xShutdown method is invoked (indirectly) by -** [sqlite3_shutdown()] and should deallocate any resources acquired -** by xInit. The pAppData pointer is used as the only parameter to -** xInit and xShutdown. -** -** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes -** the xInit method, so the xInit method need not be threadsafe. The -** xShutdown method is only called from [sqlite3_shutdown()] so it does -** not need to be threadsafe either. For all other methods, SQLite -** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the -** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which -** it is by default) and so the methods are automatically serialized. -** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other -** methods must be threadsafe or else make their own arrangements for -** serialization. -** -** SQLite will never invoke xInit() more than once without an intervening -** call to xShutdown(). -*/ -typedef struct sqlite3_mem_methods sqlite3_mem_methods; -struct sqlite3_mem_methods { - void *(*xMalloc)(int); /* Memory allocation function */ - void (*xFree)(void*); /* Free a prior allocation */ - void *(*xRealloc)(void*,int); /* Resize an allocation */ - int (*xSize)(void*); /* Return the size of an allocation */ - int (*xRoundup)(int); /* Round up request size to allocation size */ - int (*xInit)(void*); /* Initialize the memory allocator */ - void (*xShutdown)(void*); /* Deinitialize the memory allocator */ - void *pAppData; /* Argument to xInit() and xShutdown() */ -}; - -/* -** CAPI3REF: Configuration Options -** KEYWORDS: {configuration option} -** -** These constants are the available integer configuration options that -** can be passed as the first argument to the [sqlite3_config()] interface. -** -** New configuration options may be added in future releases of SQLite. -** Existing configuration options might be discontinued. Applications -** should check the return code from [sqlite3_config()] to make sure that -** the call worked. The [sqlite3_config()] interface will return a -** non-zero [error code] if a discontinued or unsupported configuration option -** is invoked. -** -**
-** [[SQLITE_CONFIG_SINGLETHREAD]]
SQLITE_CONFIG_SINGLETHREAD
-**
There are no arguments to this option. ^This option sets the -** [threading mode] to Single-thread. In other words, it disables -** all mutexing and puts SQLite into a mode where it can only be used -** by a single thread. ^If SQLite is compiled with -** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then -** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [sqlite3_config()] will return -** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD -** configuration option.
-** -** [[SQLITE_CONFIG_MULTITHREAD]]
SQLITE_CONFIG_MULTITHREAD
-**
There are no arguments to this option. ^This option sets the -** [threading mode] to Multi-thread. In other words, it disables -** mutexing on [database connection] and [prepared statement] objects. -** The application is responsible for serializing access to -** [database connections] and [prepared statements]. But other mutexes -** are enabled so that SQLite will be safe to use in a multi-threaded -** environment as long as no two threads attempt to use the same -** [database connection] at the same time. ^If SQLite is compiled with -** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then -** it is not possible to set the Multi-thread [threading mode] and -** [sqlite3_config()] will return [SQLITE_ERROR] if called with the -** SQLITE_CONFIG_MULTITHREAD configuration option.
-** -** [[SQLITE_CONFIG_SERIALIZED]]
SQLITE_CONFIG_SERIALIZED
-**
There are no arguments to this option. ^This option sets the -** [threading mode] to Serialized. In other words, this option enables -** all mutexes including the recursive -** mutexes on [database connection] and [prepared statement] objects. -** In this mode (which is the default when SQLite is compiled with -** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access -** to [database connections] and [prepared statements] so that the -** application is free to use the same [database connection] or the -** same [prepared statement] in different threads at the same time. -** ^If SQLite is compiled with -** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then -** it is not possible to set the Serialized [threading mode] and -** [sqlite3_config()] will return [SQLITE_ERROR] if called with the -** SQLITE_CONFIG_SERIALIZED configuration option.
-** -** [[SQLITE_CONFIG_MALLOC]]
SQLITE_CONFIG_MALLOC
-**
^(The SQLITE_CONFIG_MALLOC option takes a single argument which is -** a pointer to an instance of the [sqlite3_mem_methods] structure. -** The argument specifies -** alternative low-level memory allocation routines to be used in place of -** the memory allocation routines built into SQLite.)^ ^SQLite makes -** its own private copy of the content of the [sqlite3_mem_methods] structure -** before the [sqlite3_config()] call returns.
-** -** [[SQLITE_CONFIG_GETMALLOC]]
SQLITE_CONFIG_GETMALLOC
-**
^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which -** is a pointer to an instance of the [sqlite3_mem_methods] structure. -** The [sqlite3_mem_methods] -** structure is filled with the currently defined memory allocation routines.)^ -** This option can be used to overload the default memory allocation -** routines with a wrapper that simulations memory allocation failure or -** tracks memory usage, for example.
-** -** [[SQLITE_CONFIG_MEMSTATUS]]
SQLITE_CONFIG_MEMSTATUS
-**
^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, -** interpreted as a boolean, which enables or disables the collection of -** memory allocation statistics. ^(When memory allocation statistics are -** disabled, the following SQLite interfaces become non-operational: -**
    -**
  • [sqlite3_memory_used()] -**
  • [sqlite3_memory_highwater()] -**
  • [sqlite3_soft_heap_limit64()] -**
  • [sqlite3_status64()] -**
)^ -** ^Memory allocation statistics are enabled by default unless SQLite is -** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory -** allocation statistics are disabled by default. -**
-** -** [[SQLITE_CONFIG_SCRATCH]]
SQLITE_CONFIG_SCRATCH
-**
^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer -** that SQLite can use for scratch memory. ^(There are three arguments -** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte -** aligned memory buffer from which the scratch allocations will be -** drawn, the size of each scratch allocation (sz), -** and the maximum number of scratch allocations (N).)^ -** The first argument must be a pointer to an 8-byte aligned buffer -** of at least sz*N bytes of memory. -** ^SQLite will not use more than one scratch buffers per thread. -** ^SQLite will never request a scratch buffer that is more than 6 -** times the database page size. -** ^If SQLite needs needs additional -** scratch memory beyond what is provided by this configuration option, then -** [sqlite3_malloc()] will be used to obtain the memory needed.

-** ^When the application provides any amount of scratch memory using -** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large -** [sqlite3_malloc|heap allocations]. -** This can help [Robson proof|prevent memory allocation failures] due to heap -** fragmentation in low-memory embedded systems. -**

-** -** [[SQLITE_CONFIG_PAGECACHE]]
SQLITE_CONFIG_PAGECACHE
-**
^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool -** that SQLite can use for the database page cache with the default page -** cache implementation. -** This configuration option is a no-op if an application-define page -** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]. -** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to -** 8-byte aligned memory (pMem), the size of each page cache line (sz), -** and the number of cache lines (N). -** The sz argument should be the size of the largest database page -** (a power of two between 512 and 65536) plus some extra bytes for each -** page header. ^The number of extra bytes needed by the page header -** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ]. -** ^It is harmless, apart from the wasted memory, -** for the sz parameter to be larger than necessary. The pMem -** argument must be either a NULL pointer or a pointer to an 8-byte -** aligned block of memory of at least sz*N bytes, otherwise -** subsequent behavior is undefined. -** ^When pMem is not NULL, SQLite will strive to use the memory provided -** to satisfy page cache needs, falling back to [sqlite3_malloc()] if -** a page cache line is larger than sz bytes or if all of the pMem buffer -** is exhausted. -** ^If pMem is NULL and N is non-zero, then each database connection -** does an initial bulk allocation for page cache memory -** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or -** of -1024*N bytes if N is negative, . ^If additional -** page cache memory is needed beyond what is provided by the initial -** allocation, then SQLite goes to [sqlite3_malloc()] separately for each -** additional cache line.
-** -** [[SQLITE_CONFIG_HEAP]]
SQLITE_CONFIG_HEAP
-**
^The SQLITE_CONFIG_HEAP option specifies a static memory buffer -** that SQLite will use for all of its dynamic memory allocation needs -** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and -** [SQLITE_CONFIG_PAGECACHE]. -** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled -** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns -** [SQLITE_ERROR] if invoked otherwise. -** ^There are three arguments to SQLITE_CONFIG_HEAP: -** An 8-byte aligned pointer to the memory, -** the number of bytes in the memory buffer, and the minimum allocation size. -** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts -** to using its default memory allocator (the system malloc() implementation), -** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the -** memory pointer is not NULL then the alternative memory -** allocator is engaged to handle all of SQLites memory allocation needs. -** The first pointer (the memory pointer) must be aligned to an 8-byte -** boundary or subsequent behavior of SQLite will be undefined. -** The minimum allocation size is capped at 2**12. Reasonable values -** for the minimum allocation size are 2**5 through 2**8.
-** -** [[SQLITE_CONFIG_MUTEX]]
SQLITE_CONFIG_MUTEX
-**
^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a -** pointer to an instance of the [sqlite3_mutex_methods] structure. -** The argument specifies alternative low-level mutex routines to be used -** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of -** the content of the [sqlite3_mutex_methods] structure before the call to -** [sqlite3_config()] returns. ^If SQLite is compiled with -** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then -** the entire mutexing subsystem is omitted from the build and hence calls to -** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will -** return [SQLITE_ERROR].
-** -** [[SQLITE_CONFIG_GETMUTEX]]
SQLITE_CONFIG_GETMUTEX
-**
^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which -** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The -** [sqlite3_mutex_methods] -** structure is filled with the currently defined mutex routines.)^ -** This option can be used to overload the default mutex allocation -** routines with a wrapper used to track mutex usage for performance -** profiling or testing, for example. ^If SQLite is compiled with -** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then -** the entire mutexing subsystem is omitted from the build and hence calls to -** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will -** return [SQLITE_ERROR].
-** -** [[SQLITE_CONFIG_LOOKASIDE]]
SQLITE_CONFIG_LOOKASIDE
-**
^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine -** the default size of lookaside memory on each [database connection]. -** The first argument is the -** size of each lookaside buffer slot and the second is the number of -** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE -** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] -** option to [sqlite3_db_config()] can be used to change the lookaside -** configuration on individual connections.)^
-** -** [[SQLITE_CONFIG_PCACHE2]]
SQLITE_CONFIG_PCACHE2
-**
^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is -** a pointer to an [sqlite3_pcache_methods2] object. This object specifies -** the interface to a custom page cache implementation.)^ -** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.
-** -** [[SQLITE_CONFIG_GETPCACHE2]]
SQLITE_CONFIG_GETPCACHE2
-**
^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which -** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of -** the current page cache implementation into that object.)^
-** -** [[SQLITE_CONFIG_LOG]]
SQLITE_CONFIG_LOG
-**
The SQLITE_CONFIG_LOG option is used to configure the SQLite -** global [error log]. -** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a -** function with a call signature of void(*)(void*,int,const char*), -** and a pointer to void. ^If the function pointer is not NULL, it is -** invoked by [sqlite3_log()] to process each logging event. ^If the -** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. -** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is -** passed through as the first parameter to the application-defined logger -** function whenever that function is invoked. ^The second parameter to -** the logger function is a copy of the first parameter to the corresponding -** [sqlite3_log()] call and is intended to be a [result code] or an -** [extended result code]. ^The third parameter passed to the logger is -** log message after formatting via [sqlite3_snprintf()]. -** The SQLite logging interface is not reentrant; the logger function -** supplied by the application must not invoke any SQLite interface. -** In a multi-threaded application, the application-defined logger -** function must be threadsafe.
-** -** [[SQLITE_CONFIG_URI]]
SQLITE_CONFIG_URI -**
^(The SQLITE_CONFIG_URI option takes a single argument of type int. -** If non-zero, then URI handling is globally enabled. If the parameter is zero, -** then URI handling is globally disabled.)^ ^If URI handling is globally -** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], -** [sqlite3_open16()] or -** specified as part of [ATTACH] commands are interpreted as URIs, regardless -** of whether or not the [SQLITE_OPEN_URI] flag is set when the database -** connection is opened. ^If it is globally disabled, filenames are -** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the -** database connection is opened. ^(By default, URI handling is globally -** disabled. The default value may be changed by compiling with the -** [SQLITE_USE_URI] symbol defined.)^ -** -** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]]
SQLITE_CONFIG_COVERING_INDEX_SCAN -**
^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer -** argument which is interpreted as a boolean in order to enable or disable -** the use of covering indices for full table scans in the query optimizer. -** ^The default setting is determined -** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" -** if that compile-time option is omitted. -** The ability to disable the use of covering indices for full table scans -** is because some incorrectly coded legacy applications might malfunction -** when the optimization is enabled. Providing the ability to -** disable the optimization allows the older, buggy application code to work -** without change even with newer versions of SQLite. -** -** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] -**
SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE -**
These options are obsolete and should not be used by new code. -** They are retained for backwards compatibility but are now no-ops. -**
-** -** [[SQLITE_CONFIG_SQLLOG]] -**
SQLITE_CONFIG_SQLLOG -**
This option is only available if sqlite is compiled with the -** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should -** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). -** The second should be of type (void*). The callback is invoked by the library -** in three separate circumstances, identified by the value passed as the -** fourth parameter. If the fourth parameter is 0, then the database connection -** passed as the second argument has just been opened. The third argument -** points to a buffer containing the name of the main database file. If the -** fourth parameter is 1, then the SQL statement that the third parameter -** points to has just been executed. Or, if the fourth parameter is 2, then -** the connection being passed as the second parameter is being closed. The -** third parameter is passed NULL In this case. An example of using this -** configuration option can be seen in the "test_sqllog.c" source file in -** the canonical SQLite source tree.
-** -** [[SQLITE_CONFIG_MMAP_SIZE]] -**
SQLITE_CONFIG_MMAP_SIZE -**
^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values -** that are the default mmap size limit (the default setting for -** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. -** ^The default setting can be overridden by each database connection using -** either the [PRAGMA mmap_size] command, or by using the -** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size -** will be silently truncated if necessary so that it does not exceed the -** compile-time maximum mmap size set by the -** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ -** ^If either argument to this option is negative, then that argument is -** changed to its compile-time default. -** -** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] -**
SQLITE_CONFIG_WIN32_HEAPSIZE -**
^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is -** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro -** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value -** that specifies the maximum size of the created heap. -** -** [[SQLITE_CONFIG_PCACHE_HDRSZ]] -**
SQLITE_CONFIG_PCACHE_HDRSZ -**
^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which -** is a pointer to an integer and writes into that integer the number of extra -** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. -** The amount of extra space required can change depending on the compiler, -** target platform, and SQLite version. -** -** [[SQLITE_CONFIG_PMASZ]] -**
SQLITE_CONFIG_PMASZ -**
^The SQLITE_CONFIG_PMASZ option takes a single parameter which -** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded -** sorter to that integer. The default minimum PMA Size is set by the -** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched -** to help with sort operations when multithreaded sorting -** is enabled (using the [PRAGMA threads] command) and the amount of content -** to be sorted exceeds the page size times the minimum of the -** [PRAGMA cache_size] setting and this value. -** -** [[SQLITE_CONFIG_STMTJRNL_SPILL]] -**
SQLITE_CONFIG_STMTJRNL_SPILL -**
^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which -** becomes the [statement journal] spill-to-disk threshold. -** [Statement journals] are held in memory until their size (in bytes) -** exceeds this threshold, at which point they are written to disk. -** Or if the threshold is -1, statement journals are always held -** exclusively in memory. -** Since many statement journals never become large, setting the spill -** threshold to a value such as 64KiB can greatly reduce the amount of -** I/O required to support statement rollback. -** The default value for this setting is controlled by the -** [SQLITE_STMTJRNL_SPILL] compile-time option. -**
-*/ -#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ -#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ -#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ -#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ -#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* no-op */ -#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ -#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ -#define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ -#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ -#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ -#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ -#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ - -/* -** CAPI3REF: Database Connection Configuration Options -** -** These constants are the available integer configuration options that -** can be passed as the second argument to the [sqlite3_db_config()] interface. -** -** New configuration options may be added in future releases of SQLite. -** Existing configuration options might be discontinued. Applications -** should check the return code from [sqlite3_db_config()] to make sure that -** the call worked. ^The [sqlite3_db_config()] interface will return a -** non-zero [error code] if a discontinued or unsupported configuration option -** is invoked. -** -**
-**
SQLITE_DBCONFIG_LOOKASIDE
-**
^This option takes three additional arguments that determine the -** [lookaside memory allocator] configuration for the [database connection]. -** ^The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to a memory buffer to use for lookaside memory. -** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb -** may be NULL in which case SQLite will allocate the -** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the -** size of each lookaside buffer slot. ^The third argument is the number of -** slots. The size of the buffer in the first argument must be greater than -** or equal to the product of the second and third arguments. The buffer -** must be aligned to an 8-byte boundary. ^If the second argument to -** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally -** rounded down to the next smaller multiple of 8. ^(The lookaside memory -** configuration for a database connection can only be changed when that -** connection is not currently using lookaside memory, or in other words -** when the "current value" returned by -** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. -** Any attempt to change the lookaside memory configuration when lookaside -** memory is in use leaves the configuration unchanged and returns -** [SQLITE_BUSY].)^
-** -**
SQLITE_DBCONFIG_ENABLE_FKEY
-**
^This option is used to enable or disable the enforcement of -** [foreign key constraints]. There should be two additional arguments. -** The first argument is an integer which is 0 to disable FK enforcement, -** positive to enable FK enforcement or negative to leave FK enforcement -** unchanged. The second parameter is a pointer to an integer into which -** is written 0 or 1 to indicate whether FK enforcement is off or on -** following this call. The second parameter may be a NULL pointer, in -** which case the FK enforcement setting is not reported back.
-** -**
SQLITE_DBCONFIG_ENABLE_TRIGGER
-**
^This option is used to enable or disable [CREATE TRIGGER | triggers]. -** There should be two additional arguments. -** The first argument is an integer which is 0 to disable triggers, -** positive to enable triggers or negative to leave the setting unchanged. -** The second parameter is a pointer to an integer into which -** is written 0 or 1 to indicate whether triggers are disabled or enabled -** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back.
-** -**
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
-**
^This option is used to enable or disable the two-argument -** version of the [fts3_tokenizer()] function which is part of the -** [FTS3] full-text search engine extension. -** There should be two additional arguments. -** The first argument is an integer which is 0 to disable fts3_tokenizer() or -** positive to enable fts3_tokenizer() or negative to leave the setting -** unchanged. -** The second parameter is a pointer to an integer into which -** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled -** following this call. The second parameter may be a NULL pointer, in -** which case the new setting is not reported back.
-** -**
SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
-**
^This option is used to enable or disable the [sqlite3_load_extension()] -** interface independently of the [load_extension()] SQL function. -** The [sqlite3_enable_load_extension()] API enables or disables both the -** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. -** There should be two additional arguments. -** When the first argument to this interface is 1, then only the C-API is -** enabled and the SQL function remains disabled. If the first argument to -** this interface is 0, then both the C-API and the SQL function are disabled. -** If the first argument is -1, then no changes are made to state of either the -** C-API or the SQL function. -** The second parameter is a pointer to an integer into which -** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface -** is disabled or enabled following this call. The second parameter may -** be a NULL pointer, in which case the new setting is not reported back. -**
-** -**
SQLITE_DBCONFIG_MAINDBNAME
-**
^This option is used to change the name of the "main" database -** schema. ^The sole argument is a pointer to a constant UTF8 string -** which will become the new schema name in place of "main". ^SQLite -** does not make a copy of the new main schema name string, so the application -** must ensure that the argument passed into this DBCONFIG option is unchanged -** until after the database connection closes. -**
-** -**
-*/ -#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ -#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ -#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ -#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ -#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ -#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ - - -/* -** CAPI3REF: Enable Or Disable Extended Result Codes -** METHOD: sqlite3 -** -** ^The sqlite3_extended_result_codes() routine enables or disables the -** [extended result codes] feature of SQLite. ^The extended result -** codes are disabled by default for historical compatibility. -*/ -SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); - -/* -** CAPI3REF: Last Insert Rowid -** METHOD: sqlite3 -** -** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) -** has a unique 64-bit signed -** integer key called the [ROWID | "rowid"]. ^The rowid is always available -** as an undeclared column named ROWID, OID, or _ROWID_ as long as those -** names are not also used by explicitly declared columns. ^If -** the table has a column of type [INTEGER PRIMARY KEY] then that column -** is another alias for the rowid. -** -** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the -** most recent successful [INSERT] into a rowid table or [virtual table] -** on database connection D. -** ^Inserts into [WITHOUT ROWID] tables are not recorded. -** ^If no successful [INSERT]s into rowid tables -** have ever occurred on the database connection D, -** then sqlite3_last_insert_rowid(D) returns zero. -** -** ^(If an [INSERT] occurs within a trigger or within a [virtual table] -** method, then this routine will return the [rowid] of the inserted -** row as long as the trigger or virtual table method is running. -** But once the trigger or virtual table method ends, the value returned -** by this routine reverts to what it was before the trigger or virtual -** table method began.)^ -** -** ^An [INSERT] that fails due to a constraint violation is not a -** successful [INSERT] and does not change the value returned by this -** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, -** and INSERT OR ABORT make no changes to the return value of this -** routine when their insertion fails. ^(When INSERT OR REPLACE -** encounters a constraint violation, it does not fail. The -** INSERT continues to completion after deleting rows that caused -** the constraint problem so INSERT OR REPLACE will always change -** the return value of this interface.)^ -** -** ^For the purposes of this routine, an [INSERT] is considered to -** be successful even if it is subsequently rolled back. -** -** This function is accessible to SQL statements via the -** [last_insert_rowid() SQL function]. -** -** If a separate thread performs a new [INSERT] on the same -** database connection while the [sqlite3_last_insert_rowid()] -** function is running and thus changes the last insert [rowid], -** then the value returned by [sqlite3_last_insert_rowid()] is -** unpredictable and might not equal either the old or the new -** last insert [rowid]. -*/ -SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); - -/* -** CAPI3REF: Count The Number Of Rows Modified -** METHOD: sqlite3 -** -** ^This function returns the number of rows modified, inserted or -** deleted by the most recently completed INSERT, UPDATE or DELETE -** statement on the database connection specified by the only parameter. -** ^Executing any other type of SQL statement does not modify the value -** returned by this function. -** -** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are -** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], -** [foreign key actions] or [REPLACE] constraint resolution are not counted. -** -** Changes to a view that are intercepted by -** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value -** returned by sqlite3_changes() immediately after an INSERT, UPDATE or -** DELETE statement run on a view is always zero. Only changes made to real -** tables are counted. -** -** Things are more complicated if the sqlite3_changes() function is -** executed while a trigger program is running. This may happen if the -** program uses the [changes() SQL function], or if some other callback -** function invokes sqlite3_changes() directly. Essentially: -** -**
    -**
  • ^(Before entering a trigger program the value returned by -** sqlite3_changes() function is saved. After the trigger program -** has finished, the original value is restored.)^ -** -**
  • ^(Within a trigger program each INSERT, UPDATE and DELETE -** statement sets the value returned by sqlite3_changes() -** upon completion as normal. Of course, this value will not include -** any changes performed by sub-triggers, as the sqlite3_changes() -** value will be saved and restored after each sub-trigger has run.)^ -**
-** -** ^This means that if the changes() SQL function (or similar) is used -** by the first INSERT, UPDATE or DELETE statement within a trigger, it -** returns the value as set when the calling statement began executing. -** ^If it is used by the second or subsequent such statement within a trigger -** program, the value returned reflects the number of rows modified by the -** previous INSERT, UPDATE or DELETE statement within the same trigger. -** -** See also the [sqlite3_total_changes()] interface, the -** [count_changes pragma], and the [changes() SQL function]. -** -** If a separate thread makes changes on the same database connection -** while [sqlite3_changes()] is running then the value returned -** is unpredictable and not meaningful. -*/ -SQLITE_API int sqlite3_changes(sqlite3*); - -/* -** CAPI3REF: Total Number Of Rows Modified -** METHOD: sqlite3 -** -** ^This function returns the total number of rows inserted, modified or -** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed -** since the database connection was opened, including those executed as -** part of trigger programs. ^Executing any other type of SQL statement -** does not affect the value returned by sqlite3_total_changes(). -** -** ^Changes made as part of [foreign key actions] are included in the -** count, but those made as part of REPLACE constraint resolution are -** not. ^Changes to a view that are intercepted by INSTEAD OF triggers -** are not counted. -** -** See also the [sqlite3_changes()] interface, the -** [count_changes pragma], and the [total_changes() SQL function]. -** -** If a separate thread makes changes on the same database connection -** while [sqlite3_total_changes()] is running then the value -** returned is unpredictable and not meaningful. -*/ -SQLITE_API int sqlite3_total_changes(sqlite3*); - -/* -** CAPI3REF: Interrupt A Long-Running Query -** METHOD: sqlite3 -** -** ^This function causes any pending database operation to abort and -** return at its earliest opportunity. This routine is typically -** called in response to a user action such as pressing "Cancel" -** or Ctrl-C where the user wants a long query operation to halt -** immediately. -** -** ^It is safe to call this routine from a thread different from the -** thread that is currently running the database operation. But it -** is not safe to call this routine with a [database connection] that -** is closed or might close before sqlite3_interrupt() returns. -** -** ^If an SQL operation is very nearly finished at the time when -** sqlite3_interrupt() is called, then it might not have an opportunity -** to be interrupted and might continue to completion. -** -** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. -** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE -** that is inside an explicit transaction, then the entire transaction -** will be rolled back automatically. -** -** ^The sqlite3_interrupt(D) call is in effect until all currently running -** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the sqlite3_interrupt() call and before the -** running statements reaches zero are interrupted as if they had been -** running prior to the sqlite3_interrupt() call. ^New SQL statements -** that are started after the running statement count reaches zero are -** not effected by the sqlite3_interrupt(). -** ^A call to sqlite3_interrupt(D) that occurs when there are no running -** SQL statements is a no-op and has no effect on SQL statements -** that are started after the sqlite3_interrupt() call returns. -** -** If the database connection closes while [sqlite3_interrupt()] -** is running then bad things will likely happen. -*/ -SQLITE_API void sqlite3_interrupt(sqlite3*); - -/* -** CAPI3REF: Determine If An SQL Statement Is Complete -** -** These routines are useful during command-line input to determine if the -** currently entered text seems to form a complete SQL statement or -** if additional input is needed before sending the text into -** SQLite for parsing. ^These routines return 1 if the input string -** appears to be a complete SQL statement. ^A statement is judged to be -** complete if it ends with a semicolon token and is not a prefix of a -** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within -** string literals or quoted identifier names or comments are not -** independent tokens (they are part of the token in which they are -** embedded) and thus do not count as a statement terminator. ^Whitespace -** and comments that follow the final semicolon are ignored. -** -** ^These routines return 0 if the statement is incomplete. ^If a -** memory allocation fails, then SQLITE_NOMEM is returned. -** -** ^These routines do not parse the SQL statements thus -** will not detect syntactically incorrect SQL. -** -** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior -** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked -** automatically by sqlite3_complete16(). If that initialization fails, -** then the return value from sqlite3_complete16() will be non-zero -** regardless of whether or not the input SQL is complete.)^ -** -** The input to [sqlite3_complete()] must be a zero-terminated -** UTF-8 string. -** -** The input to [sqlite3_complete16()] must be a zero-terminated -** UTF-16 string in native byte order. -*/ -SQLITE_API int sqlite3_complete(const char *sql); -SQLITE_API int sqlite3_complete16(const void *sql); - -/* -** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors -** KEYWORDS: {busy-handler callback} {busy handler} -** METHOD: sqlite3 -** -** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X -** that might be invoked with argument P whenever -** an attempt is made to access a database table associated with -** [database connection] D when another thread -** or process has the table locked. -** The sqlite3_busy_handler() interface is used to implement -** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. -** -** ^If the busy callback is NULL, then [SQLITE_BUSY] -** is returned immediately upon encountering the lock. ^If the busy callback -** is not NULL, then the callback might be invoked with two arguments. -** -** ^The first argument to the busy handler is a copy of the void* pointer which -** is the third argument to sqlite3_busy_handler(). ^The second argument to -** the busy handler callback is the number of times that the busy handler has -** been invoked previously for the same locking event. ^If the -** busy callback returns 0, then no additional attempts are made to -** access the database and [SQLITE_BUSY] is returned -** to the application. -** ^If the callback returns non-zero, then another attempt -** is made to access the database and the cycle repeats. -** -** The presence of a busy handler does not guarantee that it will be invoked -** when there is lock contention. ^If SQLite determines that invoking the busy -** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] -** to the application instead of invoking the -** busy handler. -** Consider a scenario where one process is holding a read lock that -** it is trying to promote to a reserved lock and -** a second process is holding a reserved lock that it is trying -** to promote to an exclusive lock. The first process cannot proceed -** because it is blocked by the second and the second process cannot -** proceed because it is blocked by the first. If both processes -** invoke the busy handlers, neither will make any progress. Therefore, -** SQLite returns [SQLITE_BUSY] for the first process, hoping that this -** will induce the first process to release its read lock and allow -** the second process to proceed. -** -** ^The default busy callback is NULL. -** -** ^(There can only be a single busy handler defined for each -** [database connection]. Setting a new busy handler clears any -** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] -** or evaluating [PRAGMA busy_timeout=N] will change the -** busy handler and thus clear any previously set busy handler. -** -** The busy callback should not take any actions which modify the -** database connection that invoked the busy handler. In other words, -** the busy handler is not reentrant. Any such actions -** result in undefined behavior. -** -** A busy handler must not close the database connection -** or [prepared statement] that invoked the busy handler. -*/ -SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); - -/* -** CAPI3REF: Set A Busy Timeout -** METHOD: sqlite3 -** -** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps -** for a specified amount of time when a table is locked. ^The handler -** will sleep multiple times until at least "ms" milliseconds of sleeping -** have accumulated. ^After at least "ms" milliseconds of sleeping, -** the handler returns 0 which causes [sqlite3_step()] to return -** [SQLITE_BUSY]. -** -** ^Calling this routine with an argument less than or equal to zero -** turns off all busy handlers. -** -** ^(There can only be a single busy handler for a particular -** [database connection] at any given moment. If another busy handler -** was defined (using [sqlite3_busy_handler()]) prior to calling -** this routine, that other busy handler is cleared.)^ -** -** See also: [PRAGMA busy_timeout] -*/ -SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); - -/* -** CAPI3REF: Convenience Routines For Running Queries -** METHOD: sqlite3 -** -** This is a legacy interface that is preserved for backwards compatibility. -** Use of this interface is not recommended. -** -** Definition: A result table is memory data structure created by the -** [sqlite3_get_table()] interface. A result table records the -** complete query results from one or more queries. -** -** The table conceptually has a number of rows and columns. But -** these numbers are not part of the result table itself. These -** numbers are obtained separately. Let N be the number of rows -** and M be the number of columns. -** -** A result table is an array of pointers to zero-terminated UTF-8 strings. -** There are (N+1)*M elements in the array. The first M pointers point -** to zero-terminated strings that contain the names of the columns. -** The remaining entries all point to query results. NULL values result -** in NULL pointers. All other values are in their UTF-8 zero-terminated -** string representation as returned by [sqlite3_column_text()]. -** -** A result table might consist of one or more memory allocations. -** It is not safe to pass a result table directly to [sqlite3_free()]. -** A result table should be deallocated using [sqlite3_free_table()]. -** -** ^(As an example of the result table format, suppose a query result -** is as follows: -** -**
-**        Name        | Age
-**        -----------------------
-**        Alice       | 43
-**        Bob         | 28
-**        Cindy       | 21
-** 
-** -** There are two column (M==2) and three rows (N==3). Thus the -** result table has 8 entries. Suppose the result table is stored -** in an array names azResult. Then azResult holds this content: -** -**
-**        azResult[0] = "Name";
-**        azResult[1] = "Age";
-**        azResult[2] = "Alice";
-**        azResult[3] = "43";
-**        azResult[4] = "Bob";
-**        azResult[5] = "28";
-**        azResult[6] = "Cindy";
-**        azResult[7] = "21";
-** 
)^ -** -** ^The sqlite3_get_table() function evaluates one or more -** semicolon-separated SQL statements in the zero-terminated UTF-8 -** string of its 2nd parameter and returns a result table to the -** pointer given in its 3rd parameter. -** -** After the application has finished with the result from sqlite3_get_table(), -** it must pass the result table pointer to sqlite3_free_table() in order to -** release the memory that was malloced. Because of the way the -** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling -** function must not try to call [sqlite3_free()] directly. Only -** [sqlite3_free_table()] is able to release the memory properly and safely. -** -** The sqlite3_get_table() interface is implemented as a wrapper around -** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access -** to any internal data structures of SQLite. It uses only the public -** interface defined here. As a consequence, errors that occur in the -** wrapper layer outside of the internal [sqlite3_exec()] call are not -** reflected in subsequent calls to [sqlite3_errcode()] or -** [sqlite3_errmsg()]. -*/ -SQLITE_API int sqlite3_get_table( - sqlite3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - char ***pazResult, /* Results of the query */ - int *pnRow, /* Number of result rows written here */ - int *pnColumn, /* Number of result columns written here */ - char **pzErrmsg /* Error msg written here */ -); -SQLITE_API void sqlite3_free_table(char **result); - -/* -** CAPI3REF: Formatted String Printing Functions -** -** These routines are work-alikes of the "printf()" family of functions -** from the standard C library. -** These routines understand most of the common K&R formatting options, -** plus some additional non-standard formats, detailed below. -** Note that some of the more obscure formatting options from recent -** C-library standards are omitted from this implementation. -** -** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their -** results into memory obtained from [sqlite3_malloc()]. -** The strings returned by these two routines should be -** released by [sqlite3_free()]. ^Both routines return a -** NULL pointer if [sqlite3_malloc()] is unable to allocate enough -** memory to hold the resulting string. -** -** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from -** the standard C library. The result is written into the -** buffer supplied as the second parameter whose size is given by -** the first parameter. Note that the order of the -** first two parameters is reversed from snprintf().)^ This is an -** historical accident that cannot be fixed without breaking -** backwards compatibility. ^(Note also that sqlite3_snprintf() -** returns a pointer to its buffer instead of the number of -** characters actually written into the buffer.)^ We admit that -** the number of characters written would be a more useful return -** value but we cannot change the implementation of sqlite3_snprintf() -** now without breaking compatibility. -** -** ^As long as the buffer size is greater than zero, sqlite3_snprintf() -** guarantees that the buffer is always zero-terminated. ^The first -** parameter "n" is the total size of the buffer, including space for -** the zero terminator. So the longest string that can be completely -** written will be n-1 characters. -** -** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). -** -** These routines all implement some additional formatting -** options that are useful for constructing SQL statements. -** All of the usual printf() formatting options apply. In addition, there -** is are "%q", "%Q", "%w" and "%z" options. -** -** ^(The %q option works like %s in that it substitutes a nul-terminated -** string from the argument list. But %q also doubles every '\'' character. -** %q is designed for use inside a string literal.)^ By doubling each '\'' -** character it escapes that character and allows it to be inserted into -** the string. -** -** For example, assume the string variable zText contains text as follows: -** -**
-**  char *zText = "It's a happy day!";
-** 
-** -** One can use this text in an SQL statement as follows: -** -**
-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-**  sqlite3_exec(db, zSQL, 0, 0, 0);
-**  sqlite3_free(zSQL);
-** 
-** -** Because the %q format string is used, the '\'' character in zText -** is escaped and the SQL generated is as follows: -** -**
-**  INSERT INTO table1 VALUES('It''s a happy day!')
-** 
-** -** This is correct. Had we used %s instead of %q, the generated SQL -** would have looked like this: -** -**
-**  INSERT INTO table1 VALUES('It's a happy day!');
-** 
-** -** This second example is an SQL syntax error. As a general rule you should -** always use %q instead of %s when inserting text into a string literal. -** -** ^(The %Q option works like %q except it also adds single quotes around -** the outside of the total string. Additionally, if the parameter in the -** argument list is a NULL pointer, %Q substitutes the text "NULL" (without -** single quotes).)^ So, for example, one could say: -** -**
-**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-**  sqlite3_exec(db, zSQL, 0, 0, 0);
-**  sqlite3_free(zSQL);
-** 
-** -** The code above will render a correct SQL statement in the zSQL -** variable even if the zText variable is a NULL pointer. -** -** ^(The "%w" formatting option is like "%q" except that it expects to -** be contained within double-quotes instead of single quotes, and it -** escapes the double-quote character instead of the single-quote -** character.)^ The "%w" formatting option is intended for safely inserting -** table and column names into a constructed SQL statement. -** -** ^(The "%z" formatting option works like "%s" but with the -** addition that after the string has been read and copied into -** the result, [sqlite3_free()] is called on the input string.)^ -*/ -SQLITE_API char *sqlite3_mprintf(const char*,...); -SQLITE_API char *sqlite3_vmprintf(const char*, va_list); -SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); -SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); - -/* -** CAPI3REF: Memory Allocation Subsystem -** -** The SQLite core uses these three routines for all of its own -** internal memory allocation needs. "Core" in the previous sentence -** does not include operating-system specific VFS implementation. The -** Windows VFS uses native malloc() and free() for some operations. -** -** ^The sqlite3_malloc() routine returns a pointer to a block -** of memory at least N bytes in length, where N is the parameter. -** ^If sqlite3_malloc() is unable to obtain sufficient free -** memory, it returns a NULL pointer. ^If the parameter N to -** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns -** a NULL pointer. -** -** ^The sqlite3_malloc64(N) routine works just like -** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead -** of a signed 32-bit integer. -** -** ^Calling sqlite3_free() with a pointer previously returned -** by sqlite3_malloc() or sqlite3_realloc() releases that memory so -** that it might be reused. ^The sqlite3_free() routine is -** a no-op if is called with a NULL pointer. Passing a NULL pointer -** to sqlite3_free() is harmless. After being freed, memory -** should neither be read nor written. Even reading previously freed -** memory might result in a segmentation fault or other severe error. -** Memory corruption, a segmentation fault, or other severe error -** might result if sqlite3_free() is called with a non-NULL pointer that -** was not obtained from sqlite3_malloc() or sqlite3_realloc(). -** -** ^The sqlite3_realloc(X,N) interface attempts to resize a -** prior memory allocation X to be at least N bytes. -** ^If the X parameter to sqlite3_realloc(X,N) -** is a NULL pointer then its behavior is identical to calling -** sqlite3_malloc(N). -** ^If the N parameter to sqlite3_realloc(X,N) is zero or -** negative then the behavior is exactly the same as calling -** sqlite3_free(X). -** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation -** of at least N bytes in size or NULL if insufficient memory is available. -** ^If M is the size of the prior allocation, then min(N,M) bytes -** of the prior allocation are copied into the beginning of buffer returned -** by sqlite3_realloc(X,N) and the prior allocation is freed. -** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the -** prior allocation is not freed. -** -** ^The sqlite3_realloc64(X,N) interfaces works the same as -** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead -** of a 32-bit signed integer. -** -** ^If X is a memory allocation previously obtained from sqlite3_malloc(), -** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then -** sqlite3_msize(X) returns the size of that memory allocation in bytes. -** ^The value returned by sqlite3_msize(X) might be larger than the number -** of bytes requested when X was allocated. ^If X is a NULL pointer then -** sqlite3_msize(X) returns zero. If X points to something that is not -** the beginning of memory allocation, or if it points to a formerly -** valid memory allocation that has now been freed, then the behavior -** of sqlite3_msize(X) is undefined and possibly harmful. -** -** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), -** sqlite3_malloc64(), and sqlite3_realloc64() -** is always aligned to at least an 8 byte boundary, or to a -** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time -** option is used. -** -** In SQLite version 3.5.0 and 3.5.1, it was possible to define -** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in -** implementation of these routines to be omitted. That capability -** is no longer provided. Only built-in memory allocators can be used. -** -** Prior to SQLite version 3.7.10, the Windows OS interface layer called -** the system malloc() and free() directly when converting -** filenames between the UTF-8 encoding used by SQLite -** and whatever filename encoding is used by the particular Windows -** installation. Memory allocation errors were detected, but -** they were reported back as [SQLITE_CANTOPEN] or -** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. -** -** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] -** must be either NULL or else pointers obtained from a prior -** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have -** not yet been released. -** -** The application must not read or write any part of -** a block of memory after it has been released using -** [sqlite3_free()] or [sqlite3_realloc()]. -*/ -SQLITE_API void *sqlite3_malloc(int); -SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); -SQLITE_API void *sqlite3_realloc(void*, int); -SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); -SQLITE_API void sqlite3_free(void*); -SQLITE_API sqlite3_uint64 sqlite3_msize(void*); - -/* -** CAPI3REF: Memory Allocator Statistics -** -** SQLite provides these two interfaces for reporting on the status -** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] -** routines, which form the built-in memory allocation subsystem. -** -** ^The [sqlite3_memory_used()] routine returns the number of bytes -** of memory currently outstanding (malloced but not freed). -** ^The [sqlite3_memory_highwater()] routine returns the maximum -** value of [sqlite3_memory_used()] since the high-water mark -** was last reset. ^The values returned by [sqlite3_memory_used()] and -** [sqlite3_memory_highwater()] include any overhead -** added by SQLite in its implementation of [sqlite3_malloc()], -** but not overhead added by the any underlying system library -** routines that [sqlite3_malloc()] may call. -** -** ^The memory high-water mark is reset to the current value of -** [sqlite3_memory_used()] if and only if the parameter to -** [sqlite3_memory_highwater()] is true. ^The value returned -** by [sqlite3_memory_highwater(1)] is the high-water mark -** prior to the reset. -*/ -SQLITE_API sqlite3_int64 sqlite3_memory_used(void); -SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); - -/* -** CAPI3REF: Pseudo-Random Number Generator -** -** SQLite contains a high-quality pseudo-random number generator (PRNG) used to -** select random [ROWID | ROWIDs] when inserting new records into a table that -** already uses the largest possible [ROWID]. The PRNG is also used for -** the build-in random() and randomblob() SQL functions. This interface allows -** applications to access the same PRNG for other purposes. -** -** ^A call to this routine stores N bytes of randomness into buffer P. -** ^The P parameter can be a NULL pointer. -** -** ^If this routine has not been previously called or if the previous -** call had N less than one or a NULL pointer for P, then the PRNG is -** seeded using randomness obtained from the xRandomness method of -** the default [sqlite3_vfs] object. -** ^If the previous call to this routine had an N of 1 or more and a -** non-NULL P then the pseudo-randomness is generated -** internally and without recourse to the [sqlite3_vfs] xRandomness -** method. -*/ -SQLITE_API void sqlite3_randomness(int N, void *P); - -/* -** CAPI3REF: Compile-Time Authorization Callbacks -** METHOD: sqlite3 -** -** ^This routine registers an authorizer callback with a particular -** [database connection], supplied in the first argument. -** ^The authorizer callback is invoked as SQL statements are being compiled -** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], -** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various -** points during the compilation process, as logic is being created -** to perform various actions, the authorizer callback is invoked to -** see if those actions are allowed. ^The authorizer callback should -** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the -** specific action but allow the SQL statement to continue to be -** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be -** rejected with an error. ^If the authorizer callback returns -** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] -** then the [sqlite3_prepare_v2()] or equivalent call that triggered -** the authorizer will fail with an error message. -** -** When the callback returns [SQLITE_OK], that means the operation -** requested is ok. ^When the callback returns [SQLITE_DENY], the -** [sqlite3_prepare_v2()] or equivalent call that triggered the -** authorizer will fail with an error message explaining that -** access is denied. -** -** ^The first parameter to the authorizer callback is a copy of the third -** parameter to the sqlite3_set_authorizer() interface. ^The second parameter -** to the callback is an integer [SQLITE_COPY | action code] that specifies -** the particular action to be authorized. ^The third through sixth parameters -** to the callback are zero-terminated strings that contain additional -** details about the action to be authorized. -** -** ^If the action code is [SQLITE_READ] -** and the callback returns [SQLITE_IGNORE] then the -** [prepared statement] statement is constructed to substitute -** a NULL value in place of the table column that would have -** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] -** return can be used to deny an untrusted user access to individual -** columns of a table. -** ^If the action code is [SQLITE_DELETE] and the callback returns -** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the -** [truncate optimization] is disabled and all rows are deleted individually. -** -** An authorizer is used when [sqlite3_prepare | preparing] -** SQL statements from an untrusted source, to ensure that the SQL statements -** do not try to access data they are not allowed to see, or that they do not -** try to execute malicious statements that damage the database. For -** example, an application may allow a user to enter arbitrary -** SQL queries for evaluation by a database. But the application does -** not want the user to be able to make arbitrary changes to the -** database. An authorizer could then be put in place while the -** user-entered SQL is being [sqlite3_prepare | prepared] that -** disallows everything except [SELECT] statements. -** -** Applications that need to process SQL from untrusted sources -** might also consider lowering resource limits using [sqlite3_limit()] -** and limiting database size using the [max_page_count] [PRAGMA] -** in addition to using an authorizer. -** -** ^(Only a single authorizer can be in place on a database connection -** at a time. Each call to sqlite3_set_authorizer overrides the -** previous call.)^ ^Disable the authorizer by installing a NULL callback. -** The authorizer is disabled by default. -** -** The authorizer callback must not do anything that will modify -** the database connection that invoked the authorizer callback. -** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their -** database connections for the meaning of "modify" in this paragraph. -** -** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [sqlite3_step()] due to a -** schema change. Hence, the application should ensure that the -** correct authorizer callback remains in place during the [sqlite3_step()]. -** -** ^Note that the authorizer callback is invoked only during -** [sqlite3_prepare()] or its variants. Authorization is not -** performed during statement evaluation in [sqlite3_step()], unless -** as stated in the previous paragraph, sqlite3_step() invokes -** sqlite3_prepare_v2() to reprepare a statement after a schema change. -*/ -SQLITE_API int sqlite3_set_authorizer( - sqlite3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData -); - -/* -** CAPI3REF: Authorizer Return Codes -** -** The [sqlite3_set_authorizer | authorizer callback function] must -** return either [SQLITE_OK] or one of these two constants in order -** to signal SQLite whether or not the action is permitted. See the -** [sqlite3_set_authorizer | authorizer documentation] for additional -** information. -** -** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] -** returned from the [sqlite3_vtab_on_conflict()] interface. -*/ -#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ -#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ - -/* -** CAPI3REF: Authorizer Action Codes -** -** The [sqlite3_set_authorizer()] interface registers a callback function -** that is invoked to authorize certain SQL statement actions. The -** second parameter to the callback is an integer code that specifies -** what action is being authorized. These are the integer action codes that -** the authorizer callback may be passed. -** -** These action code values signify what kind of operation is to be -** authorized. The 3rd and 4th parameters to the authorization -** callback function will be parameters or NULL depending on which of these -** codes is used as the second parameter. ^(The 5th parameter to the -** authorizer callback is the name of the database ("main", "temp", -** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback -** is the name of the inner-most trigger or view that is responsible for -** the access attempt or NULL if this access attempt is directly from -** top-level SQL code. -*/ -/******************************************* 3rd ************ 4th ***********/ -#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ -#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ -#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ -#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ -#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ -#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ -#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ -#define SQLITE_DELETE 9 /* Table Name NULL */ -#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ -#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ -#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ -#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ -#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ -#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ -#define SQLITE_DROP_VIEW 17 /* View Name NULL */ -#define SQLITE_INSERT 18 /* Table Name NULL */ -#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ -#define SQLITE_READ 20 /* Table Name Column Name */ -#define SQLITE_SELECT 21 /* NULL NULL */ -#define SQLITE_TRANSACTION 22 /* Operation NULL */ -#define SQLITE_UPDATE 23 /* Table Name Column Name */ -#define SQLITE_ATTACH 24 /* Filename NULL */ -#define SQLITE_DETACH 25 /* Database Name NULL */ -#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ -#define SQLITE_REINDEX 27 /* Index Name NULL */ -#define SQLITE_ANALYZE 28 /* Table Name NULL */ -#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ -#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ -#define SQLITE_FUNCTION 31 /* NULL Function Name */ -#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ -#define SQLITE_COPY 0 /* No longer used */ -#define SQLITE_RECURSIVE 33 /* NULL NULL */ - -/* -** CAPI3REF: Tracing And Profiling Functions -** METHOD: sqlite3 -** -** These routines are deprecated. Use the [sqlite3_trace_v2()] interface -** instead of the routines described here. -** -** These routines register callback functions that can be used for -** tracing and profiling the execution of SQL statements. -** -** ^The callback function registered by sqlite3_trace() is invoked at -** various times when an SQL statement is being run by [sqlite3_step()]. -** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the -** SQL statement text as the statement first begins executing. -** ^(Additional sqlite3_trace() callbacks might occur -** as each triggered subprogram is entered. The callbacks for triggers -** contain a UTF-8 SQL comment that identifies the trigger.)^ -** -** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit -** the length of [bound parameter] expansion in the output of sqlite3_trace(). -** -** ^The callback function registered by sqlite3_profile() is invoked -** as each SQL statement finishes. ^The profile callback contains -** the original statement text and an estimate of wall-clock time -** of how long that statement took to run. ^The profile callback -** time is in units of nanoseconds, however the current implementation -** is only capable of millisecond resolution so the six least significant -** digits in the time are meaningless. Future versions of SQLite -** might provide greater resolution on the profiler callback. The -** sqlite3_profile() function is considered experimental and is -** subject to change in future versions of SQLite. -*/ -SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, - void(*xTrace)(void*,const char*), void*); -SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, - void(*xProfile)(void*,const char*,sqlite3_uint64), void*); - -/* -** CAPI3REF: SQL Trace Event Codes -** KEYWORDS: SQLITE_TRACE -** -** These constants identify classes of events that can be monitored -** using the [sqlite3_trace_v2()] tracing logic. The third argument -** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of -** the following constants. ^The first argument to the trace callback -** is one of the following constants. -** -** New tracing constants may be added in future releases. -** -** ^A trace callback has four arguments: xCallback(T,C,P,X). -** ^The T argument is one of the integer type codes above. -** ^The C argument is a copy of the context pointer passed in as the -** fourth argument to [sqlite3_trace_v2()]. -** The P and X arguments are pointers whose meanings depend on T. -** -**
-** [[SQLITE_TRACE_STMT]]
SQLITE_TRACE_STMT
-**
^An SQLITE_TRACE_STMT callback is invoked when a prepared statement -** first begins running and possibly at other times during the -** execution of the prepared statement, such as at the start of each -** trigger subprogram. ^The P argument is a pointer to the -** [prepared statement]. ^The X argument is a pointer to a string which -** is the unexpanded SQL text of the prepared statement or an SQL comment -** that indicates the invocation of a trigger. ^The callback can compute -** the same text that would have been returned by the legacy [sqlite3_trace()] -** interface by using the X argument when X begins with "--" and invoking -** [sqlite3_expanded_sql(P)] otherwise. -** -** [[SQLITE_TRACE_PROFILE]]
SQLITE_TRACE_PROFILE
-**
^An SQLITE_TRACE_PROFILE callback provides approximately the same -** information as is provided by the [sqlite3_profile()] callback. -** ^The P argument is a pointer to the [prepared statement] and the -** X argument points to a 64-bit integer which is the estimated of -** the number of nanosecond that the prepared statement took to run. -** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. -** -** [[SQLITE_TRACE_ROW]]
SQLITE_TRACE_ROW
-**
^An SQLITE_TRACE_ROW callback is invoked whenever a prepared -** statement generates a single row of result. -** ^The P argument is a pointer to the [prepared statement] and the -** X argument is unused. -** -** [[SQLITE_TRACE_CLOSE]]
SQLITE_TRACE_CLOSE
-**
^An SQLITE_TRACE_CLOSE callback is invoked when a database -** connection closes. -** ^The P argument is a pointer to the [database connection] object -** and the X argument is unused. -**
-*/ -#define SQLITE_TRACE_STMT 0x01 -#define SQLITE_TRACE_PROFILE 0x02 -#define SQLITE_TRACE_ROW 0x04 -#define SQLITE_TRACE_CLOSE 0x08 - -/* -** CAPI3REF: SQL Trace Hook -** METHOD: sqlite3 -** -** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback -** function X against [database connection] D, using property mask M -** and context pointer P. ^If the X callback is -** NULL or if the M mask is zero, then tracing is disabled. The -** M argument should be the bitwise OR-ed combination of -** zero or more [SQLITE_TRACE] constants. -** -** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides -** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). -** -** ^The X callback is invoked whenever any of the events identified by -** mask M occur. ^The integer return value from the callback is currently -** ignored, though this may change in future releases. Callback -** implementations should return zero to ensure future compatibility. -** -** ^A trace callback is invoked with four arguments: callback(T,C,P,X). -** ^The T argument is one of the [SQLITE_TRACE] -** constants to indicate why the callback was invoked. -** ^The C argument is a copy of the context pointer. -** The P and X arguments are pointers whose meanings depend on T. -** -** The sqlite3_trace_v2() interface is intended to replace the legacy -** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which -** are deprecated. -*/ -SQLITE_API int sqlite3_trace_v2( - sqlite3*, - unsigned uMask, - int(*xCallback)(unsigned,void*,void*,void*), - void *pCtx -); - -/* -** CAPI3REF: Query Progress Callbacks -** METHOD: sqlite3 -** -** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback -** function X to be invoked periodically during long running calls to -** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for -** database connection D. An example use for this -** interface is to keep a GUI updated during a large query. -** -** ^The parameter P is passed through as the only parameter to the -** callback function X. ^The parameter N is the approximate number of -** [virtual machine instructions] that are evaluated between successive -** invocations of the callback X. ^If N is less than one then the progress -** handler is disabled. -** -** ^Only a single progress handler may be defined at one time per -** [database connection]; setting a new progress handler cancels the -** old one. ^Setting parameter X to NULL disables the progress handler. -** ^The progress handler is also disabled by setting N to a value less -** than 1. -** -** ^If the progress callback returns non-zero, the operation is -** interrupted. This feature can be used to implement a -** "Cancel" button on a GUI progress dialog box. -** -** The progress handler callback must not do anything that will modify -** the database connection that invoked the progress handler. -** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their -** database connections for the meaning of "modify" in this paragraph. -** -*/ -SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); - -/* -** CAPI3REF: Opening A New Database Connection -** CONSTRUCTOR: sqlite3 -** -** ^These routines open an SQLite database file as specified by the -** filename argument. ^The filename argument is interpreted as UTF-8 for -** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte -** order for sqlite3_open16(). ^(A [database connection] handle is usually -** returned in *ppDb, even if an error occurs. The only exception is that -** if SQLite is unable to allocate memory to hold the [sqlite3] object, -** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] -** object.)^ ^(If the database is opened (and/or created) successfully, then -** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The -** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain -** an English language description of the error following a failure of any -** of the sqlite3_open() routines. -** -** ^The default encoding will be UTF-8 for databases created using -** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases -** created using sqlite3_open16() will be UTF-16 in the native byte order. -** -** Whether or not an error occurs when it is opened, resources -** associated with the [database connection] handle should be released by -** passing it to [sqlite3_close()] when it is no longer required. -** -** The sqlite3_open_v2() interface works like sqlite3_open() -** except that it accepts two additional parameters for additional control -** over the new database connection. ^(The flags parameter to -** sqlite3_open_v2() can take one of -** the following three values, optionally combined with the -** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], -** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^ -** -**
-** ^(
[SQLITE_OPEN_READONLY]
-**
The database is opened in read-only mode. If the database does not -** already exist, an error is returned.
)^ -** -** ^(
[SQLITE_OPEN_READWRITE]
-**
The database is opened for reading and writing if possible, or reading -** only if the file is write protected by the operating system. In either -** case the database must already exist, otherwise an error is returned.
)^ -** -** ^(
[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
-**
The database is opened for reading and writing, and is created if -** it does not already exist. This is the behavior that is always used for -** sqlite3_open() and sqlite3_open16().
)^ -**
-** -** If the 3rd parameter to sqlite3_open_v2() is not one of the -** combinations shown above optionally combined with other -** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] -** then the behavior is undefined. -** -** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection -** opens in the multi-thread [threading mode] as long as the single-thread -** mode has not been set at compile-time or start-time. ^If the -** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens -** in the serialized [threading mode] unless single-thread was -** previously selected at compile-time or start-time. -** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be -** eligible to use [shared cache mode], regardless of whether or not shared -** cache is enabled using [sqlite3_enable_shared_cache()]. ^The -** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not -** participate in [shared cache mode] even if it is enabled. -** -** ^The fourth parameter to sqlite3_open_v2() is the name of the -** [sqlite3_vfs] object that defines the operating system interface that -** the new database connection should use. ^If the fourth parameter is -** a NULL pointer then the default [sqlite3_vfs] object is used. -** -** ^If the filename is ":memory:", then a private, temporary in-memory database -** is created for the connection. ^This in-memory database will vanish when -** the database connection is closed. Future versions of SQLite might -** make use of additional special filenames that begin with the ":" character. -** It is recommended that when a database filename actually does begin with -** a ":" character you should prefix the filename with a pathname such as -** "./" to avoid ambiguity. -** -** ^If the filename is an empty string, then a private, temporary -** on-disk database will be created. ^This private database will be -** automatically deleted as soon as the database connection is closed. -** -** [[URI filenames in sqlite3_open()]]

URI Filenames

-** -** ^If [URI filename] interpretation is enabled, and the filename argument -** begins with "file:", then the filename is interpreted as a URI. ^URI -** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is -** set in the fourth argument to sqlite3_open_v2(), or if it has -** been enabled globally using the [SQLITE_CONFIG_URI] option with the -** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. -** As of SQLite version 3.7.7, URI filename interpretation is turned off -** by default, but future releases of SQLite might enable URI filename -** interpretation by default. See "[URI filenames]" for additional -** information. -** -** URI filenames are parsed according to RFC 3986. ^If the URI contains an -** authority, then it must be either an empty string or the string -** "localhost". ^If the authority is not an empty string or "localhost", an -** error is returned to the caller. ^The fragment component of a URI, if -** present, is ignored. -** -** ^SQLite uses the path component of the URI as the name of the disk file -** which contains the database. ^If the path begins with a '/' character, -** then it is interpreted as an absolute path. ^If the path does not begin -** with a '/' (meaning that the authority section is omitted from the URI) -** then the path is interpreted as a relative path. -** ^(On windows, the first component of an absolute path -** is a drive specification (e.g. "C:").)^ -** -** [[core URI query parameters]] -** The query component of a URI may contain parameters that are interpreted -** either by SQLite itself, or by a [VFS | custom VFS implementation]. -** SQLite and its built-in [VFSes] interpret the -** following query parameters: -** -**
    -**
  • vfs: ^The "vfs" parameter may be used to specify the name of -** a VFS object that provides the operating system interface that should -** be used to access the database file on disk. ^If this option is set to -** an empty string the default VFS object is used. ^Specifying an unknown -** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is -** present, then the VFS specified by the option takes precedence over -** the value passed as the fourth parameter to sqlite3_open_v2(). -** -**
  • mode: ^(The mode parameter may be set to either "ro", "rw", -** "rwc", or "memory". Attempting to set it to any other value is -** an error)^. -** ^If "ro" is specified, then the database is opened for read-only -** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the -** third argument to sqlite3_open_v2(). ^If the mode option is set to -** "rw", then the database is opened for read-write (but not create) -** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had -** been set. ^Value "rwc" is equivalent to setting both -** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is -** set to "memory" then a pure [in-memory database] that never reads -** or writes from disk is used. ^It is an error to specify a value for -** the mode parameter that is less restrictive than that specified by -** the flags passed in the third parameter to sqlite3_open_v2(). -** -**
  • cache: ^The cache parameter may be set to either "shared" or -** "private". ^Setting it to "shared" is equivalent to setting the -** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to -** sqlite3_open_v2(). ^Setting the cache parameter to "private" is -** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. -** ^If sqlite3_open_v2() is used and the "cache" parameter is present in -** a URI filename, its value overrides any behavior requested by setting -** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. -** -**
  • psow: ^The psow parameter indicates whether or not the -** [powersafe overwrite] property does or does not apply to the -** storage media on which the database file resides. -** -**
  • nolock: ^The nolock parameter is a boolean query parameter -** which if set disables file locking in rollback journal modes. This -** is useful for accessing a database on a filesystem that does not -** support locking. Caution: Database corruption might result if two -** or more processes write to the same database and any one of those -** processes uses nolock=1. -** -**
  • immutable: ^The immutable parameter is a boolean query -** parameter that indicates that the database file is stored on -** read-only media. ^When immutable is set, SQLite assumes that the -** database file cannot be changed, even by a process with higher -** privilege, and so the database is opened read-only and all locking -** and change detection is disabled. Caution: Setting the immutable -** property on a database file that does in fact change can result -** in incorrect query results and/or [SQLITE_CORRUPT] errors. -** See also: [SQLITE_IOCAP_IMMUTABLE]. -** -**
-** -** ^Specifying an unknown parameter in the query component of a URI is not an -** error. Future versions of SQLite might understand additional query -** parameters. See "[query parameters with special meaning to SQLite]" for -** additional information. -** -** [[URI filename examples]]

URI filename examples

-** -**
-**
URI filenames Results -**
file:data.db -** Open the file "data.db" in the current directory. -**
file:/home/fred/data.db
-** file:///home/fred/data.db
-** file://localhost/home/fred/data.db
-** Open the database file "/home/fred/data.db". -**
file://darkstar/home/fred/data.db -** An error. "darkstar" is not a recognized authority. -**
-** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db -** Windows only: Open the file "data.db" on fred's desktop on drive -** C:. Note that the %20 escaping in this example is not strictly -** necessary - space characters can be used literally -** in URI filenames. -**
file:data.db?mode=ro&cache=private -** Open file "data.db" in the current directory for read-only access. -** Regardless of whether or not shared-cache mode is enabled by -** default, use a private cache. -**
file:/home/fred/data.db?vfs=unix-dotfile -** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" -** that uses dot-files in place of posix advisory locking. -**
file:data.db?mode=readonly -** An error. "readonly" is not a valid option for the "mode" parameter. -**
-** -** ^URI hexadecimal escape sequences (%HH) are supported within the path and -** query components of a URI. A hexadecimal escape sequence consists of a -** percent sign - "%" - followed by exactly two hexadecimal digits -** specifying an octet value. ^Before the path or query components of a -** URI filename are interpreted, they are encoded using UTF-8 and all -** hexadecimal escape sequences replaced by a single byte containing the -** corresponding octet. If this process generates an invalid UTF-8 encoding, -** the results are undefined. -** -** Note to Windows users: The encoding used for the filename argument -** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever -** codepage is currently defined. Filenames containing international -** characters must be converted to UTF-8 prior to passing them into -** sqlite3_open() or sqlite3_open_v2(). -** -** Note to Windows Runtime users: The temporary directory must be set -** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various -** features that require the use of temporary files may fail. -** -** See also: [sqlite3_temp_directory] -*/ -SQLITE_API int sqlite3_open( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -SQLITE_API int sqlite3_open16( - const void *filename, /* Database filename (UTF-16) */ - sqlite3 **ppDb /* OUT: SQLite db handle */ -); -SQLITE_API int sqlite3_open_v2( - const char *filename, /* Database filename (UTF-8) */ - sqlite3 **ppDb, /* OUT: SQLite db handle */ - int flags, /* Flags */ - const char *zVfs /* Name of VFS module to use */ -); - -/* -** CAPI3REF: Obtain Values For URI Parameters -** -** These are utility routines, useful to VFS implementations, that check -** to see if a database file was a URI that contained a specific query -** parameter, and if so obtains the value of that query parameter. -** -** If F is the database filename pointer passed into the xOpen() method of -** a VFS implementation when the flags parameter to xOpen() has one or -** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and -** P is the name of the query parameter, then -** sqlite3_uri_parameter(F,P) returns the value of the P -** parameter if it exists or a NULL pointer if P does not appear as a -** query parameter on F. If P is a query parameter of F -** has no explicit value, then sqlite3_uri_parameter(F,P) returns -** a pointer to an empty string. -** -** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean -** parameter and returns true (1) or false (0) according to the value -** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the -** value of query parameter P is one of "yes", "true", or "on" in any -** case or if the value begins with a non-zero number. The -** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of -** query parameter P is one of "no", "false", or "off" in any case or -** if the value begins with a numeric zero. If P is not a query -** parameter on F or if the value of P is does not match any of the -** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). -** -** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a -** 64-bit signed integer and returns that integer, or D if P does not -** exist. If the value of P is something other than an integer, then -** zero is returned. -** -** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and -** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and -** is not a database file pathname pointer that SQLite passed into the xOpen -** VFS method, then the behavior of this routine is undefined and probably -** undesirable. -*/ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); -SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); -SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); - - -/* -** CAPI3REF: Error Codes And Messages -** METHOD: sqlite3 -** -** ^If the most recent sqlite3_* API call associated with -** [database connection] D failed, then the sqlite3_errcode(D) interface -** returns the numeric [result code] or [extended result code] for that -** API call. -** If the most recent API call was successful, -** then the return value from sqlite3_errcode() is undefined. -** ^The sqlite3_extended_errcode() -** interface is the same except that it always returns the -** [extended result code] even when extended result codes are -** disabled. -** -** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. -** ^(Memory to hold the error message string is managed internally. -** The application does not need to worry about freeing the result. -** However, the error string might be overwritten or deallocated by -** subsequent calls to other SQLite interface functions.)^ -** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. -** ^(Memory to hold the error message string is managed internally -** and must not be freed by the application)^. -** -** When the serialized [threading mode] is in use, it might be the -** case that a second error occurs on a separate thread in between -** the time of the first error and the call to these interfaces. -** When that happens, the second error will be reported since these -** interfaces always report the most recent result. To avoid -** this, each thread can obtain exclusive use of the [database connection] D -** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning -** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after -** all calls to the interfaces listed here are completed. -** -** If an interface fails with SQLITE_MISUSE, that means the interface -** was invoked incorrectly by the application. In that case, the -** error code and message may or may not be set. -*/ -SQLITE_API int sqlite3_errcode(sqlite3 *db); -SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); -SQLITE_API const char *sqlite3_errmsg(sqlite3*); -SQLITE_API const void *sqlite3_errmsg16(sqlite3*); -SQLITE_API const char *sqlite3_errstr(int); - -/* -** CAPI3REF: Prepared Statement Object -** KEYWORDS: {prepared statement} {prepared statements} -** -** An instance of this object represents a single SQL statement that -** has been compiled into binary form and is ready to be evaluated. -** -** Think of each SQL statement as a separate computer program. The -** original SQL text is source code. A prepared statement object -** is the compiled object code. All SQL must be converted into a -** prepared statement before it can be run. -** -** The life-cycle of a prepared statement object usually goes like this: -** -**
    -**
  1. Create the prepared statement object using [sqlite3_prepare_v2()]. -**
  2. Bind values to [parameters] using the sqlite3_bind_*() -** interfaces. -**
  3. Run the SQL by calling [sqlite3_step()] one or more times. -**
  4. Reset the prepared statement using [sqlite3_reset()] then go back -** to step 2. Do this zero or more times. -**
  5. Destroy the object using [sqlite3_finalize()]. -**
-*/ -typedef struct sqlite3_stmt sqlite3_stmt; - -/* -** CAPI3REF: Run-time Limits -** METHOD: sqlite3 -** -** ^(This interface allows the size of various constructs to be limited -** on a connection by connection basis. The first parameter is the -** [database connection] whose limit is to be set or queried. The -** second parameter is one of the [limit categories] that define a -** class of constructs to be size limited. The third parameter is the -** new limit for that construct.)^ -** -** ^If the new limit is a negative number, the limit is unchanged. -** ^(For each limit category SQLITE_LIMIT_NAME there is a -** [limits | hard upper bound] -** set at compile-time by a C preprocessor macro called -** [limits | SQLITE_MAX_NAME]. -** (The "_LIMIT_" in the name is changed to "_MAX_".))^ -** ^Attempts to increase a limit above its hard upper bound are -** silently truncated to the hard upper bound. -** -** ^Regardless of whether or not the limit was changed, the -** [sqlite3_limit()] interface returns the prior value of the limit. -** ^Hence, to find the current value of a limit without changing it, -** simply invoke this interface with the third parameter set to -1. -** -** Run-time limits are intended for use in applications that manage -** both their own internal database and also databases that are controlled -** by untrusted external sources. An example application might be a -** web browser that has its own databases for storing history and -** separate databases controlled by JavaScript applications downloaded -** off the Internet. The internal databases can be given the -** large, default limits. Databases managed by external sources can -** be given much smaller limits designed to prevent a denial of service -** attack. Developers might also want to use the [sqlite3_set_authorizer()] -** interface to further control untrusted SQL. The size of the database -** created by an untrusted script can be contained using the -** [max_page_count] [PRAGMA]. -** -** New run-time limit categories may be added in future releases. -*/ -SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); - -/* -** CAPI3REF: Run-Time Limit Categories -** KEYWORDS: {limit category} {*limit categories} -** -** These constants define various performance limits -** that can be lowered at run-time using [sqlite3_limit()]. -** The synopsis of the meanings of the various limits is shown below. -** Additional information is available at [limits | Limits in SQLite]. -** -**
-** [[SQLITE_LIMIT_LENGTH]] ^(
SQLITE_LIMIT_LENGTH
-**
The maximum size of any string or BLOB or table row, in bytes.
)^ -** -** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
SQLITE_LIMIT_SQL_LENGTH
-**
The maximum length of an SQL statement, in bytes.
)^ -** -** [[SQLITE_LIMIT_COLUMN]] ^(
SQLITE_LIMIT_COLUMN
-**
The maximum number of columns in a table definition or in the -** result set of a [SELECT] or the maximum number of columns in an index -** or in an ORDER BY or GROUP BY clause.
)^ -** -** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
SQLITE_LIMIT_EXPR_DEPTH
-**
The maximum depth of the parse tree on any expression.
)^ -** -** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
SQLITE_LIMIT_COMPOUND_SELECT
-**
The maximum number of terms in a compound SELECT statement.
)^ -** -** [[SQLITE_LIMIT_VDBE_OP]] ^(
SQLITE_LIMIT_VDBE_OP
-**
The maximum number of instructions in a virtual machine program -** used to implement an SQL statement. This limit is not currently -** enforced, though that might be added in some future release of -** SQLite.
)^ -** -** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
SQLITE_LIMIT_FUNCTION_ARG
-**
The maximum number of arguments on a function.
)^ -** -** [[SQLITE_LIMIT_ATTACHED]] ^(
SQLITE_LIMIT_ATTACHED
-**
The maximum number of [ATTACH | attached databases].)^
-** -** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] -** ^(
SQLITE_LIMIT_LIKE_PATTERN_LENGTH
-**
The maximum length of the pattern argument to the [LIKE] or -** [GLOB] operators.
)^ -** -** [[SQLITE_LIMIT_VARIABLE_NUMBER]] -** ^(
SQLITE_LIMIT_VARIABLE_NUMBER
-**
The maximum index number of any [parameter] in an SQL statement.)^ -** -** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
SQLITE_LIMIT_TRIGGER_DEPTH
-**
The maximum depth of recursion for triggers.
)^ -** -** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
SQLITE_LIMIT_WORKER_THREADS
-**
The maximum number of auxiliary worker threads that a single -** [prepared statement] may start.
)^ -**
-*/ -#define SQLITE_LIMIT_LENGTH 0 -#define SQLITE_LIMIT_SQL_LENGTH 1 -#define SQLITE_LIMIT_COLUMN 2 -#define SQLITE_LIMIT_EXPR_DEPTH 3 -#define SQLITE_LIMIT_COMPOUND_SELECT 4 -#define SQLITE_LIMIT_VDBE_OP 5 -#define SQLITE_LIMIT_FUNCTION_ARG 6 -#define SQLITE_LIMIT_ATTACHED 7 -#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 -#define SQLITE_LIMIT_VARIABLE_NUMBER 9 -#define SQLITE_LIMIT_TRIGGER_DEPTH 10 -#define SQLITE_LIMIT_WORKER_THREADS 11 - -/* -** CAPI3REF: Compiling An SQL Statement -** KEYWORDS: {SQL statement compiler} -** METHOD: sqlite3 -** CONSTRUCTOR: sqlite3_stmt -** -** To execute an SQL query, it must first be compiled into a byte-code -** program using one of these routines. -** -** The first argument, "db", is a [database connection] obtained from a -** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or -** [sqlite3_open16()]. The database connection must not have been closed. -** -** The second argument, "zSql", is the statement to be compiled, encoded -** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2() -** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2() -** use UTF-16. -** -** ^If the nByte argument is negative, then zSql is read up to the -** first zero terminator. ^If nByte is positive, then it is the -** number of bytes read from zSql. ^If nByte is zero, then no prepared -** statement is generated. -** If the caller knows that the supplied string is nul-terminated, then -** there is a small performance advantage to passing an nByte parameter that -** is the number of bytes in the input string including -** the nul-terminator. -** -** ^If pzTail is not NULL then *pzTail is made to point to the first byte -** past the end of the first SQL statement in zSql. These routines only -** compile the first statement in zSql, so *pzTail is left pointing to -** what remains uncompiled. -** -** ^*ppStmt is left pointing to a compiled [prepared statement] that can be -** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set -** to NULL. ^If the input text contains no SQL (if the input is an empty -** string or a comment) then *ppStmt is set to NULL. -** The calling procedure is responsible for deleting the compiled -** SQL statement using [sqlite3_finalize()] after it has finished with it. -** ppStmt may not be NULL. -** -** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; -** otherwise an [error code] is returned. -** -** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are -** recommended for all new programs. The two older interfaces are retained -** for backwards compatibility, but their use is discouraged. -** ^In the "v2" interfaces, the prepared statement -** that is returned (the [sqlite3_stmt] object) contains a copy of the -** original SQL text. This causes the [sqlite3_step()] interface to -** behave differently in three ways: -** -**
    -**
  1. -** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it -** always used to do, [sqlite3_step()] will automatically recompile the SQL -** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] -** retries will occur before sqlite3_step() gives up and returns an error. -**
  2. -** -**
  3. -** ^When an error occurs, [sqlite3_step()] will return one of the detailed -** [error codes] or [extended error codes]. ^The legacy behavior was that -** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code -** and the application would have to make a second call to [sqlite3_reset()] -** in order to find the underlying cause of the problem. With the "v2" prepare -** interfaces, the underlying reason for the error is returned immediately. -**
  4. -** -**
  5. -** ^If the specific value bound to [parameter | host parameter] in the -** WHERE clause might influence the choice of query plan for a statement, -** then the statement will be automatically recompiled, as if there had been -** a schema change, on the first [sqlite3_step()] call following any change -** to the [sqlite3_bind_text | bindings] of that [parameter]. -** ^The specific value of WHERE-clause [parameter] might influence the -** choice of query plan if the parameter is the left-hand side of a [LIKE] -** or [GLOB] operator or if the parameter is compared to an indexed column -** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. -**
  6. -**
-*/ -SQLITE_API int sqlite3_prepare( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -SQLITE_API int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ -); -SQLITE_API int sqlite3_prepare16( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); -SQLITE_API int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ -); - -/* -** CAPI3REF: Retrieving Statement SQL -** METHOD: sqlite3_stmt -** -** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 -** SQL text used to create [prepared statement] P if P was -** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. -** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 -** string containing the SQL text of prepared statement P with -** [bound parameters] expanded. -** -** ^(For example, if a prepared statement is created using the SQL -** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 -** and parameter :xyz is unbound, then sqlite3_sql() will return -** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() -** will return "SELECT 2345,NULL".)^ -** -** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory -** is available to hold the result, or if the result would exceed the -** the maximum string length determined by the [SQLITE_LIMIT_LENGTH]. -** -** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of -** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time -** option causes sqlite3_expanded_sql() to always return NULL. -** -** ^The string returned by sqlite3_sql(P) is managed by SQLite and is -** automatically freed when the prepared statement is finalized. -** ^The string returned by sqlite3_expanded_sql(P), on the other hand, -** is obtained from [sqlite3_malloc()] and must be free by the application -** by passing it to [sqlite3_free()]. -*/ -SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); -SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Determine If An SQL Statement Writes The Database -** METHOD: sqlite3_stmt -** -** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if -** and only if the [prepared statement] X makes no direct changes to -** the content of the database file. -** -** Note that [application-defined SQL functions] or -** [virtual tables] might change the database indirectly as a side effect. -** ^(For example, if an application defines a function "eval()" that -** calls [sqlite3_exec()], then the following SQL statement would -** change the database file through side-effects: -** -**
-**    SELECT eval('DELETE FROM t1') FROM t2;
-** 
-** -** But because the [SELECT] statement does not change the database file -** directly, sqlite3_stmt_readonly() would still return true.)^ -** -** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], -** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, -** since the statements themselves do not actually modify the database but -** rather they control the timing of when other statements modify the -** database. ^The [ATTACH] and [DETACH] statements also cause -** sqlite3_stmt_readonly() to return true since, while those statements -** change the configuration of a database connection, they do not make -** changes to the content of the database files on disk. -*/ -SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Determine If A Prepared Statement Has Been Reset -** METHOD: sqlite3_stmt -** -** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the -** [prepared statement] S has been stepped at least once using -** [sqlite3_step(S)] but has neither run to completion (returned -** [SQLITE_DONE] from [sqlite3_step(S)]) nor -** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) -** interface returns false if S is a NULL pointer. If S is not a -** NULL pointer and is not a pointer to a valid [prepared statement] -** object, then the behavior is undefined and probably undesirable. -** -** This interface can be used in combination [sqlite3_next_stmt()] -** to locate all prepared statements associated with a database -** connection that are in need of being reset. This can be used, -** for example, in diagnostic routines to search for prepared -** statements that are holding a transaction open. -*/ -SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); - -/* -** CAPI3REF: Dynamically Typed Value Object -** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} -** -** SQLite uses the sqlite3_value object to represent all values -** that can be stored in a database table. SQLite uses dynamic typing -** for the values it stores. ^Values stored in sqlite3_value objects -** can be integers, floating point values, strings, BLOBs, or NULL. -** -** An sqlite3_value object may be either "protected" or "unprotected". -** Some interfaces require a protected sqlite3_value. Other interfaces -** will accept either a protected or an unprotected sqlite3_value. -** Every interface that accepts sqlite3_value arguments specifies -** whether or not it requires a protected sqlite3_value. The -** [sqlite3_value_dup()] interface can be used to construct a new -** protected sqlite3_value from an unprotected sqlite3_value. -** -** The terms "protected" and "unprotected" refer to whether or not -** a mutex is held. An internal mutex is held for a protected -** sqlite3_value object but no mutex is held for an unprotected -** sqlite3_value object. If SQLite is compiled to be single-threaded -** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) -** or if SQLite is run in one of reduced mutex modes -** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] -** then there is no distinction between protected and unprotected -** sqlite3_value objects and they can be used interchangeably. However, -** for maximum code portability it is recommended that applications -** still make the distinction between protected and unprotected -** sqlite3_value objects even when not strictly required. -** -** ^The sqlite3_value objects that are passed as parameters into the -** implementation of [application-defined SQL functions] are protected. -** ^The sqlite3_value object returned by -** [sqlite3_column_value()] is unprotected. -** Unprotected sqlite3_value objects may only be used with -** [sqlite3_result_value()] and [sqlite3_bind_value()]. -** The [sqlite3_value_blob | sqlite3_value_type()] family of -** interfaces require protected sqlite3_value objects. -*/ -typedef struct Mem sqlite3_value; - -/* -** CAPI3REF: SQL Function Context Object -** -** The context in which an SQL function executes is stored in an -** sqlite3_context object. ^A pointer to an sqlite3_context object -** is always first parameter to [application-defined SQL functions]. -** The application-defined SQL function implementation will pass this -** pointer through into calls to [sqlite3_result_int | sqlite3_result()], -** [sqlite3_aggregate_context()], [sqlite3_user_data()], -** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], -** and/or [sqlite3_set_auxdata()]. -*/ -typedef struct sqlite3_context sqlite3_context; - -/* -** CAPI3REF: Binding Values To Prepared Statements -** KEYWORDS: {host parameter} {host parameters} {host parameter name} -** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} -** METHOD: sqlite3_stmt -** -** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] that matches one of following -** templates: -** -**
    -**
  • ? -**
  • ?NNN -**
  • :VVV -**
  • @VVV -**
  • $VVV -**
-** -** In the templates above, NNN represents an integer literal, -** and VVV represents an alphanumeric identifier.)^ ^The values of these -** parameters (also called "host parameter names" or "SQL parameters") -** can be set using the sqlite3_bind_*() routines defined here. -** -** ^The first argument to the sqlite3_bind_*() routines is always -** a pointer to the [sqlite3_stmt] object returned from -** [sqlite3_prepare_v2()] or its variants. -** -** ^The second argument is the index of the SQL parameter to be set. -** ^The leftmost SQL parameter has an index of 1. ^When the same named -** SQL parameter is used more than once, second and subsequent -** occurrences have the same index as the first occurrence. -** ^The index for named parameters can be looked up using the -** [sqlite3_bind_parameter_index()] API if desired. ^The index -** for "?NNN" parameters is the value of NNN. -** ^The NNN value must be between 1 and the [sqlite3_limit()] -** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). -** -** ^The third argument is the value to bind to the parameter. -** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() -** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter -** is ignored and the end result is the same as sqlite3_bind_null(). -** -** ^(In those routines that have a fourth argument, its value is the -** number of bytes in the parameter. To be clear: the value is the -** number of bytes in the value, not the number of characters.)^ -** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() -** is negative, then the length of the string is -** the number of bytes up to the first zero terminator. -** If the fourth parameter to sqlite3_bind_blob() is negative, then -** the behavior is undefined. -** If a non-negative fourth parameter is provided to sqlite3_bind_text() -** or sqlite3_bind_text16() or sqlite3_bind_text64() then -** that parameter must be the byte offset -** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occur at byte offsets less than -** the value of the fourth parameter then the resulting string value will -** contain embedded NULs. The result of expressions involving strings -** with embedded NULs is undefined. -** -** ^The fifth argument to the BLOB and string binding interfaces -** is a destructor used to dispose of the BLOB or -** string after SQLite has finished with it. ^The destructor is called -** to dispose of the BLOB or string even if the call to bind API fails. -** ^If the fifth argument is -** the special value [SQLITE_STATIC], then SQLite assumes that the -** information is in static, unmanaged space and does not need to be freed. -** ^If the fifth argument has the value [SQLITE_TRANSIENT], then -** SQLite makes its own private copy of the data immediately, before -** the sqlite3_bind_*() routine returns. -** -** ^The sixth argument to sqlite3_bind_text64() must be one of -** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] -** to specify the encoding of the text in the third parameter. If -** the sixth argument to sqlite3_bind_text64() is not one of the -** allowed values shown above, or if the text encoding is different -** from the encoding specified by the sixth parameter, then the behavior -** is undefined. -** -** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that -** is filled with zeroes. ^A zeroblob uses a fixed amount of memory -** (just an integer to hold its size) while it is being processed. -** Zeroblobs are intended to serve as placeholders for BLOBs whose -** content is later written using -** [sqlite3_blob_open | incremental BLOB I/O] routines. -** ^A negative value for the zeroblob results in a zero-length BLOB. -** -** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer -** for the [prepared statement] or with a prepared statement for which -** [sqlite3_step()] has been called more recently than [sqlite3_reset()], -** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() -** routine is passed a [prepared statement] that has been finalized, the -** result is undefined and probably harmful. -** -** ^Bindings are not cleared by the [sqlite3_reset()] routine. -** ^Unbound parameters are interpreted as NULL. -** -** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an -** [error code] if anything goes wrong. -** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB -** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or -** [SQLITE_MAX_LENGTH]. -** ^[SQLITE_RANGE] is returned if the parameter -** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. -** -** See also: [sqlite3_bind_parameter_count()], -** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. -*/ -SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); -SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, - void(*)(void*)); -SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); -SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); -SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); -SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); -SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); -SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, - void(*)(void*), unsigned char encoding); -SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); -SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); - -/* -** CAPI3REF: Number Of SQL Parameters -** METHOD: sqlite3_stmt -** -** ^This routine can be used to find the number of [SQL parameters] -** in a [prepared statement]. SQL parameters are tokens of the -** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as -** placeholders for values that are [sqlite3_bind_blob | bound] -** to the parameters at a later time. -** -** ^(This routine actually returns the index of the largest (rightmost) -** parameter. For all forms except ?NNN, this will correspond to the -** number of unique parameters. If parameters of the ?NNN form are used, -** there may be gaps in the list.)^ -** -** See also: [sqlite3_bind_blob|sqlite3_bind()], -** [sqlite3_bind_parameter_name()], and -** [sqlite3_bind_parameter_index()]. -*/ -SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); - -/* -** CAPI3REF: Name Of A Host Parameter -** METHOD: sqlite3_stmt -** -** ^The sqlite3_bind_parameter_name(P,N) interface returns -** the name of the N-th [SQL parameter] in the [prepared statement] P. -** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" -** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" -** respectively. -** In other words, the initial ":" or "$" or "@" or "?" -** is included as part of the name.)^ -** ^Parameters of the form "?" without a following integer have no name -** and are referred to as "nameless" or "anonymous parameters". -** -** ^The first host parameter has an index of 1, not 0. -** -** ^If the value N is out of range or if the N-th parameter is -** nameless, then NULL is returned. ^The returned string is -** always in UTF-8 encoding even if the named parameter was -** originally specified as UTF-16 in [sqlite3_prepare16()] or -** [sqlite3_prepare16_v2()]. -** -** See also: [sqlite3_bind_blob|sqlite3_bind()], -** [sqlite3_bind_parameter_count()], and -** [sqlite3_bind_parameter_index()]. -*/ -SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); - -/* -** CAPI3REF: Index Of A Parameter With A Given Name -** METHOD: sqlite3_stmt -** -** ^Return the index of an SQL parameter given its name. ^The -** index value returned is suitable for use as the second -** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero -** is returned if no matching parameter is found. ^The parameter -** name must be given in UTF-8 even if the original statement -** was prepared from UTF-16 text using [sqlite3_prepare16_v2()]. -** -** See also: [sqlite3_bind_blob|sqlite3_bind()], -** [sqlite3_bind_parameter_count()], and -** [sqlite3_bind_parameter_name()]. -*/ -SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); - -/* -** CAPI3REF: Reset All Bindings On A Prepared Statement -** METHOD: sqlite3_stmt -** -** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset -** the [sqlite3_bind_blob | bindings] on a [prepared statement]. -** ^Use this routine to reset all host parameters to NULL. -*/ -SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); - -/* -** CAPI3REF: Number Of Columns In A Result Set -** METHOD: sqlite3_stmt -** -** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^This routine returns 0 if pStmt is an SQL -** statement that does not return data (for example an [UPDATE]). -** -** See also: [sqlite3_data_count()] -*/ -SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Column Names In A Result Set -** METHOD: sqlite3_stmt -** -** ^These routines return the name assigned to a particular column -** in the result set of a [SELECT] statement. ^The sqlite3_column_name() -** interface returns a pointer to a zero-terminated UTF-8 string -** and sqlite3_column_name16() returns a pointer to a zero-terminated -** UTF-16 string. ^The first parameter is the [prepared statement] -** that implements the [SELECT] statement. ^The second parameter is the -** column number. ^The leftmost column is number 0. -** -** ^The returned string pointer is valid until either the [prepared statement] -** is destroyed by [sqlite3_finalize()] or until the statement is automatically -** reprepared by the first call to [sqlite3_step()] for a particular run -** or until the next call to -** sqlite3_column_name() or sqlite3_column_name16() on the same column. -** -** ^If sqlite3_malloc() fails during the processing of either routine -** (for example during a conversion from UTF-8 to UTF-16) then a -** NULL pointer is returned. -** -** ^The name of a result column is the value of the "AS" clause for -** that column, if there is an AS clause. If there is no AS clause -** then the name of the column is unspecified and may change from -** one release of SQLite to the next. -*/ -SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); -SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); - -/* -** CAPI3REF: Source Of Data In A Query Result -** METHOD: sqlite3_stmt -** -** ^These routines provide a means to determine the database, table, and -** table column that is the origin of a particular result column in -** [SELECT] statement. -** ^The name of the database or table or column can be returned as -** either a UTF-8 or UTF-16 string. ^The _database_ routines return -** the database name, the _table_ routines return the table name, and -** the origin_ routines return the column name. -** ^The returned string is valid until the [prepared statement] is destroyed -** using [sqlite3_finalize()] or until the statement is automatically -** reprepared by the first call to [sqlite3_step()] for a particular run -** or until the same information is requested -** again in a different encoding. -** -** ^The names returned are the original un-aliased names of the -** database, table, and column. -** -** ^The first argument to these interfaces is a [prepared statement]. -** ^These functions return information about the Nth result column returned by -** the statement, where N is the second function argument. -** ^The left-most column is column 0 for these routines. -** -** ^If the Nth column returned by the statement is an expression or -** subquery and is not a column value, then all of these functions return -** NULL. ^These routine might also return NULL if a memory allocation error -** occurs. ^Otherwise, they return the name of the attached database, table, -** or column that query result column was extracted from. -** -** ^As with all other SQLite APIs, those whose names end with "16" return -** UTF-16 encoded strings and the other functions return UTF-8. -** -** ^These APIs are only available if the library was compiled with the -** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. -** -** If two or more threads call one or more of these routines against the same -** prepared statement and column at the same time then the results are -** undefined. -** -** If two or more threads call one or more -** [sqlite3_column_database_name | column metadata interfaces] -** for the same [prepared statement] and result column -** at the same time then the results are undefined. -*/ -SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); -SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); - -/* -** CAPI3REF: Declared Datatype Of A Query Result -** METHOD: sqlite3_stmt -** -** ^(The first parameter is a [prepared statement]. -** If this statement is a [SELECT] statement and the Nth column of the -** returned result set of that [SELECT] is a table column (not an -** expression or subquery) then the declared type of the table -** column is returned.)^ ^If the Nth column of the result set is an -** expression or subquery, then a NULL pointer is returned. -** ^The returned string is always UTF-8 encoded. -** -** ^(For example, given the database schema: -** -** CREATE TABLE t1(c1 VARIANT); -** -** and the following statement to be compiled: -** -** SELECT c1 + 1, c1 FROM t1; -** -** this routine would return the string "VARIANT" for the second result -** column (i==1), and a NULL pointer for the first result column (i==0).)^ -** -** ^SQLite uses dynamic run-time typing. ^So just because a column -** is declared to contain a particular type does not mean that the -** data stored in that column is of the declared type. SQLite is -** strongly typed, but the typing is dynamic not static. ^Type -** is associated with individual values, not with the containers -** used to hold those values. -*/ -SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); -SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); - -/* -** CAPI3REF: Evaluate An SQL Statement -** METHOD: sqlite3_stmt -** -** After a [prepared statement] has been prepared using either -** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy -** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function -** must be called one or more times to evaluate the statement. -** -** The details of the behavior of the sqlite3_step() interface depend -** on whether the statement was prepared using the newer "v2" interface -** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy -** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the -** new "v2" interface is recommended for new applications but the legacy -** interface will continue to be supported. -** -** ^In the legacy interface, the return value will be either [SQLITE_BUSY], -** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. -** ^With the "v2" interface, any of the other [result codes] or -** [extended result codes] might be returned as well. -** -** ^[SQLITE_BUSY] means that the database engine was unable to acquire the -** database locks it needs to do its job. ^If the statement is a [COMMIT] -** or occurs outside of an explicit transaction, then you can retry the -** statement. If the statement is not a [COMMIT] and occurs within an -** explicit transaction then you should rollback the transaction before -** continuing. -** -** ^[SQLITE_DONE] means that the statement has finished executing -** successfully. sqlite3_step() should not be called again on this virtual -** machine without first calling [sqlite3_reset()] to reset the virtual -** machine back to its initial state. -** -** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] -** is returned each time a new row of data is ready for processing by the -** caller. The values may be accessed using the [column access functions]. -** sqlite3_step() is called again to retrieve the next row of data. -** -** ^[SQLITE_ERROR] means that a run-time error (such as a constraint -** violation) has occurred. sqlite3_step() should not be called again on -** the VM. More information may be found by calling [sqlite3_errmsg()]. -** ^With the legacy interface, a more specific error code (for example, -** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) -** can be obtained by calling [sqlite3_reset()] on the -** [prepared statement]. ^In the "v2" interface, -** the more specific error code is returned directly by sqlite3_step(). -** -** [SQLITE_MISUSE] means that the this routine was called inappropriately. -** Perhaps it was called on a [prepared statement] that has -** already been [sqlite3_finalize | finalized] or on one that had -** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could -** be the case that the same database connection is being used by two or -** more threads at the same moment in time. -** -** For all versions of SQLite up to and including 3.6.23.1, a call to -** [sqlite3_reset()] was required after sqlite3_step() returned anything -** other than [SQLITE_ROW] before any subsequent invocation of -** sqlite3_step(). Failure to reset the prepared statement using -** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], -** sqlite3_step() began -** calling [sqlite3_reset()] automatically in this circumstance rather -** than returning [SQLITE_MISUSE]. This is not considered a compatibility -** break because any application that ever receives an SQLITE_MISUSE error -** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option -** can be used to restore the legacy behavior. -** -** Goofy Interface Alert: In the legacy interface, the sqlite3_step() -** API always returns a generic error code, [SQLITE_ERROR], following any -** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call -** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the -** specific [error codes] that better describes the error. -** We admit that this is a goofy design. The problem has been fixed -** with the "v2" interface. If you prepare all of your SQL statements -** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead -** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, -** then the more specific [error codes] are returned directly -** by sqlite3_step(). The use of the "v2" interface is recommended. -*/ -SQLITE_API int sqlite3_step(sqlite3_stmt*); - -/* -** CAPI3REF: Number of columns in a result set -** METHOD: sqlite3_stmt -** -** ^The sqlite3_data_count(P) interface returns the number of columns in the -** current row of the result set of [prepared statement] P. -** ^If prepared statement P does not have results ready to return -** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of -** interfaces) then sqlite3_data_count(P) returns 0. -** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. -** ^The sqlite3_data_count(P) routine returns 0 if the previous call to -** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) -** will return non-zero if previous call to [sqlite3_step](P) returned -** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] -** where it always returns zero since each step of that multi-step -** pragma returns 0 columns of data. -** -** See also: [sqlite3_column_count()] -*/ -SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Fundamental Datatypes -** KEYWORDS: SQLITE_TEXT -** -** ^(Every value in SQLite has one of five fundamental datatypes: -** -**
    -**
  • 64-bit signed integer -**
  • 64-bit IEEE floating point number -**
  • string -**
  • BLOB -**
  • NULL -**
)^ -** -** These constants are codes for each of those types. -** -** Note that the SQLITE_TEXT constant was also used in SQLite version 2 -** for a completely different meaning. Software that links against both -** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not -** SQLITE_TEXT. -*/ -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 -#ifdef SQLITE_TEXT -# undef SQLITE_TEXT -#else -# define SQLITE_TEXT 3 -#endif -#define SQLITE3_TEXT 3 - -/* -** CAPI3REF: Result Values From A Query -** KEYWORDS: {column access functions} -** METHOD: sqlite3_stmt -** -** ^These routines return information about a single column of the current -** result row of a query. ^In every case the first argument is a pointer -** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] -** that was returned from [sqlite3_prepare_v2()] or one of its variants) -** and the second argument is the index of the column for which information -** should be returned. ^The leftmost column of the result set has the index 0. -** ^The number of columns in the result can be determined using -** [sqlite3_column_count()]. -** -** If the SQL statement does not currently point to a valid row, or if the -** column index is out of range, the result is undefined. -** These routines may only be called when the most recent call to -** [sqlite3_step()] has returned [SQLITE_ROW] and neither -** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. -** If any of these routines are called after [sqlite3_reset()] or -** [sqlite3_finalize()] or after [sqlite3_step()] has returned -** something other than [SQLITE_ROW], the results are undefined. -** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] -** are called from a different thread while any of these routines -** are pending, then the results are undefined. -** -** ^The sqlite3_column_type() routine returns the -** [SQLITE_INTEGER | datatype code] for the initial data type -** of the result column. ^The returned value is one of [SQLITE_INTEGER], -** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value -** returned by sqlite3_column_type() is only meaningful if no type -** conversions have occurred as described below. After a type conversion, -** the value returned by sqlite3_column_type() is undefined. Future -** versions of SQLite may change the behavior of sqlite3_column_type() -** following a type conversion. -** -** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() -** routine returns the number of bytes in that BLOB or string. -** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts -** the string to UTF-8 and then returns the number of bytes. -** ^If the result is a numeric value then sqlite3_column_bytes() uses -** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns -** the number of bytes in that string. -** ^If the result is NULL, then sqlite3_column_bytes() returns zero. -** -** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() -** routine returns the number of bytes in that BLOB or string. -** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts -** the string to UTF-16 and then returns the number of bytes. -** ^If the result is a numeric value then sqlite3_column_bytes16() uses -** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns -** the number of bytes in that string. -** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. -** -** ^The values returned by [sqlite3_column_bytes()] and -** [sqlite3_column_bytes16()] do not include the zero terminators at the end -** of the string. ^For clarity: the values returned by -** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of -** bytes in the string, not the number of characters. -** -** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), -** even empty strings, are always zero-terminated. ^The return -** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. -** -** Warning: ^The object returned by [sqlite3_column_value()] is an -** [unprotected sqlite3_value] object. In a multithreaded environment, -** an unprotected sqlite3_value object may only be used safely with -** [sqlite3_bind_value()] and [sqlite3_result_value()]. -** If the [unprotected sqlite3_value] object returned by -** [sqlite3_column_value()] is used in any other way, including calls -** to routines like [sqlite3_value_int()], [sqlite3_value_text()], -** or [sqlite3_value_bytes()], the behavior is not threadsafe. -** -** These routines attempt to convert the value where appropriate. ^For -** example, if the internal representation is FLOAT and a text result -** is requested, [sqlite3_snprintf()] is used internally to perform the -** conversion automatically. ^(The following table details the conversions -** that are applied: -** -**
-** -**
Internal
Type
Requested
Type
Conversion -** -**
NULL INTEGER Result is 0 -**
NULL FLOAT Result is 0.0 -**
NULL TEXT Result is a NULL pointer -**
NULL BLOB Result is a NULL pointer -**
INTEGER FLOAT Convert from integer to float -**
INTEGER TEXT ASCII rendering of the integer -**
INTEGER BLOB Same as INTEGER->TEXT -**
FLOAT INTEGER [CAST] to INTEGER -**
FLOAT TEXT ASCII rendering of the float -**
FLOAT BLOB [CAST] to BLOB -**
TEXT INTEGER [CAST] to INTEGER -**
TEXT FLOAT [CAST] to REAL -**
TEXT BLOB No change -**
BLOB INTEGER [CAST] to INTEGER -**
BLOB FLOAT [CAST] to REAL -**
BLOB TEXT Add a zero terminator if needed -**
-**
)^ -** -** Note that when type conversions occur, pointers returned by prior -** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or -** sqlite3_column_text16() may be invalidated. -** Type conversions and pointer invalidations might occur -** in the following cases: -** -**
    -**
  • The initial content is a BLOB and sqlite3_column_text() or -** sqlite3_column_text16() is called. A zero-terminator might -** need to be added to the string.
  • -**
  • The initial content is UTF-8 text and sqlite3_column_bytes16() or -** sqlite3_column_text16() is called. The content must be converted -** to UTF-16.
  • -**
  • The initial content is UTF-16 text and sqlite3_column_bytes() or -** sqlite3_column_text() is called. The content must be converted -** to UTF-8.
  • -**
-** -** ^Conversions between UTF-16be and UTF-16le are always done in place and do -** not invalidate a prior pointer, though of course the content of the buffer -** that the prior pointer references will have been modified. Other kinds -** of conversion are done in place when it is possible, but sometimes they -** are not possible and in those cases prior pointers are invalidated. -** -** The safest policy is to invoke these routines -** in one of the following ways: -** -**
    -**
  • sqlite3_column_text() followed by sqlite3_column_bytes()
  • -**
  • sqlite3_column_blob() followed by sqlite3_column_bytes()
  • -**
  • sqlite3_column_text16() followed by sqlite3_column_bytes16()
  • -**
-** -** In other words, you should call sqlite3_column_text(), -** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result -** into the desired format, then invoke sqlite3_column_bytes() or -** sqlite3_column_bytes16() to find the size of the result. Do not mix calls -** to sqlite3_column_text() or sqlite3_column_blob() with calls to -** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() -** with calls to sqlite3_column_bytes(). -** -** ^The pointers returned are valid until a type conversion occurs as -** described above, or until [sqlite3_step()] or [sqlite3_reset()] or -** [sqlite3_finalize()] is called. ^The memory space used to hold strings -** and BLOBs is freed automatically. Do not pass the pointers returned -** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into -** [sqlite3_free()]. -** -** ^(If a memory allocation error occurs during the evaluation of any -** of these routines, a default value is returned. The default value -** is either the integer 0, the floating point number 0.0, or a NULL -** pointer. Subsequent calls to [sqlite3_errcode()] will return -** [SQLITE_NOMEM].)^ -*/ -SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); -SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); -SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); - -/* -** CAPI3REF: Destroy A Prepared Statement Object -** DESTRUCTOR: sqlite3_stmt -** -** ^The sqlite3_finalize() function is called to delete a [prepared statement]. -** ^If the most recent evaluation of the statement encountered no errors -** or if the statement is never been evaluated, then sqlite3_finalize() returns -** SQLITE_OK. ^If the most recent evaluation of statement S failed, then -** sqlite3_finalize(S) returns the appropriate [error code] or -** [extended error code]. -** -** ^The sqlite3_finalize(S) routine can be called at any point during -** the life cycle of [prepared statement] S: -** before statement S is ever evaluated, after -** one or more calls to [sqlite3_reset()], or after any call -** to [sqlite3_step()] regardless of whether or not the statement has -** completed execution. -** -** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. -** -** The application must finalize every [prepared statement] in order to avoid -** resource leaks. It is a grievous error for the application to try to use -** a prepared statement after it has been finalized. Any use of a prepared -** statement after it has been finalized can result in undefined and -** undesirable behavior such as segfaults and heap corruption. -*/ -SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Reset A Prepared Statement Object -** METHOD: sqlite3_stmt -** -** The sqlite3_reset() function is called to reset a [prepared statement] -** object back to its initial state, ready to be re-executed. -** ^Any SQL statement variables that had values bound to them using -** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. -** Use [sqlite3_clear_bindings()] to reset the bindings. -** -** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S -** back to the beginning of its program. -** -** ^If the most recent call to [sqlite3_step(S)] for the -** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], -** or if [sqlite3_step(S)] has never before been called on S, -** then [sqlite3_reset(S)] returns [SQLITE_OK]. -** -** ^If the most recent call to [sqlite3_step(S)] for the -** [prepared statement] S indicated an error, then -** [sqlite3_reset(S)] returns an appropriate [error code]. -** -** ^The [sqlite3_reset(S)] interface does not change the values -** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. -*/ -SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Create Or Redefine SQL Functions -** KEYWORDS: {function creation routines} -** KEYWORDS: {application-defined SQL function} -** KEYWORDS: {application-defined SQL functions} -** METHOD: sqlite3 -** -** ^These functions (collectively known as "function creation routines") -** are used to add SQL functions or aggregates or to redefine the behavior -** of existing SQL functions or aggregates. The only differences between -** these routines are the text encoding expected for -** the second parameter (the name of the function being created) -** and the presence or absence of a destructor callback for -** the application data pointer. -** -** ^The first parameter is the [database connection] to which the SQL -** function is to be added. ^If an application uses more than one database -** connection then application-defined SQL functions must be added -** to each database connection separately. -** -** ^The second parameter is the name of the SQL function to be created or -** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 -** representation, exclusive of the zero-terminator. ^Note that the name -** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. -** ^Any attempt to create a function with a longer name -** will result in [SQLITE_MISUSE] being returned. -** -** ^The third parameter (nArg) -** is the number of arguments that the SQL function or -** aggregate takes. ^If this parameter is -1, then the SQL function or -** aggregate may take any number of arguments between 0 and the limit -** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third -** parameter is less than -1 or greater than 127 then the behavior is -** undefined. -** -** ^The fourth parameter, eTextRep, specifies what -** [SQLITE_UTF8 | text encoding] this SQL function prefers for -** its parameters. The application should set this parameter to -** [SQLITE_UTF16LE] if the function implementation invokes -** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the -** implementation invokes [sqlite3_value_text16be()] on an input, or -** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] -** otherwise. ^The same SQL function may be registered multiple times using -** different preferred text encodings, with different implementations for -** each encoding. -** ^When multiple implementations of the same function are available, SQLite -** will pick the one that involves the least amount of data conversion. -** -** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] -** to signal that the function will always return the same result given -** the same inputs within a single SQL statement. Most SQL functions are -** deterministic. The built-in [random()] SQL function is an example of a -** function that is not deterministic. The SQLite query planner is able to -** perform additional optimizations on deterministic functions, so use -** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. -** -** ^(The fifth parameter is an arbitrary pointer. The implementation of the -** function can gain access to this pointer using [sqlite3_user_data()].)^ -** -** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are -** pointers to C-language functions that implement the SQL function or -** aggregate. ^A scalar SQL function requires an implementation of the xFunc -** callback only; NULL pointers must be passed as the xStep and xFinal -** parameters. ^An aggregate SQL function requires an implementation of xStep -** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing -** SQL function or aggregate, pass NULL pointers for all three function -** callbacks. -** -** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, -** then it is destructor for the application data pointer. -** The destructor is invoked when the function is deleted, either by being -** overloaded or when the database connection closes.)^ -** ^The destructor is also invoked if the call to -** sqlite3_create_function_v2() fails. -** ^When the destructor callback of the tenth parameter is invoked, it -** is passed a single argument which is a copy of the application data -** pointer which was the fifth parameter to sqlite3_create_function_v2(). -** -** ^It is permitted to register multiple implementations of the same -** functions with the same name but with either differing numbers of -** arguments or differing preferred text encodings. ^SQLite will use -** the implementation that most closely matches the way in which the -** SQL function is used. ^A function implementation with a non-negative -** nArg parameter is a better match than a function implementation with -** a negative nArg. ^A function where the preferred text encoding -** matches the database encoding is a better -** match than a function where the encoding is different. -** ^A function where the encoding difference is between UTF16le and UTF16be -** is a closer match than a function where the encoding difference is -** between UTF8 and UTF16. -** -** ^Built-in functions may be overloaded by new application-defined functions. -** -** ^An application-defined function is permitted to call other -** SQLite interfaces. However, such calls must not -** close the database connection nor finalize or reset the prepared -** statement in which the function is running. -*/ -SQLITE_API int sqlite3_create_function( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); -SQLITE_API int sqlite3_create_function16( - sqlite3 *db, - const void *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -); -SQLITE_API int sqlite3_create_function_v2( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*), - void(*xDestroy)(void*) -); - -/* -** CAPI3REF: Text Encodings -** -** These constant define integer codes that represent the various -** text encodings supported by SQLite. -*/ -#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ -#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ -#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ -#define SQLITE_UTF16 4 /* Use native byte order */ -#define SQLITE_ANY 5 /* Deprecated */ -#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ - -/* -** CAPI3REF: Function Flags -** -** These constants may be ORed together with the -** [SQLITE_UTF8 | preferred text encoding] as the fourth argument -** to [sqlite3_create_function()], [sqlite3_create_function16()], or -** [sqlite3_create_function_v2()]. -*/ -#define SQLITE_DETERMINISTIC 0x800 - -/* -** CAPI3REF: Deprecated Functions -** DEPRECATED -** -** These functions are [deprecated]. In order to maintain -** backwards compatibility with older code, these functions continue -** to be supported. However, new applications should avoid -** the use of these functions. To encourage programmers to avoid -** these functions, we will not explain what they do. -*/ -#ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); -SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), - void*,sqlite3_int64); -#endif - -/* -** CAPI3REF: Obtaining SQL Values -** METHOD: sqlite3_value -** -** The C-language implementation of SQL functions and aggregates uses -** this set of interface routines to access the parameter values on -** the function or aggregate. -** -** The xFunc (for scalar functions) or xStep (for aggregates) parameters -** to [sqlite3_create_function()] and [sqlite3_create_function16()] -** define callbacks that implement the SQL functions and aggregates. -** The 3rd parameter to these callbacks is an array of pointers to -** [protected sqlite3_value] objects. There is one [sqlite3_value] object for -** each parameter to the SQL function. These routines are used to -** extract values from the [sqlite3_value] objects. -** -** These routines work only with [protected sqlite3_value] objects. -** Any attempt to use these routines on an [unprotected sqlite3_value] -** object results in undefined behavior. -** -** ^These routines work just like the corresponding [column access functions] -** except that these routines take a single [protected sqlite3_value] object -** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. -** -** ^The sqlite3_value_text16() interface extracts a UTF-16 string -** in the native byte-order of the host machine. ^The -** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces -** extract UTF-16 strings as big-endian and little-endian respectively. -** -** ^(The sqlite3_value_numeric_type() interface attempts to apply -** numeric affinity to the value. This means that an attempt is -** made to convert the value to an integer or floating point. If -** such a conversion is possible without loss of information (in other -** words, if the value is a string that looks like a number) -** then the conversion is performed. Otherwise no conversion occurs. -** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ -** -** Please pay particular attention to the fact that the pointer returned -** from [sqlite3_value_blob()], [sqlite3_value_text()], or -** [sqlite3_value_text16()] can be invalidated by a subsequent call to -** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], -** or [sqlite3_value_text16()]. -** -** These routines must be called from the same thread as -** the SQL function that supplied the [sqlite3_value*] parameters. -*/ -SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes(sqlite3_value*); -SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); -SQLITE_API double sqlite3_value_double(sqlite3_value*); -SQLITE_API int sqlite3_value_int(sqlite3_value*); -SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); -SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); -SQLITE_API int sqlite3_value_type(sqlite3_value*); -SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); - -/* -** CAPI3REF: Finding The Subtype Of SQL Values -** METHOD: sqlite3_value -** -** The sqlite3_value_subtype(V) function returns the subtype for -** an [application-defined SQL function] argument V. The subtype -** information can be used to pass a limited amount of context from -** one SQL function to another. Use the [sqlite3_result_subtype()] -** routine to set the subtype for the return value of an SQL function. -** -** SQLite makes no use of subtype itself. It merely passes the subtype -** from the result of one [application-defined SQL function] into the -** input of another. -*/ -SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); - -/* -** CAPI3REF: Copy And Free SQL Values -** METHOD: sqlite3_value -** -** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] -** object D and returns a pointer to that copy. ^The [sqlite3_value] returned -** is a [protected sqlite3_value] object even if the input is not. -** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -** memory allocation fails. -** -** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object -** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer -** then sqlite3_value_free(V) is a harmless no-op. -*/ -SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*); -SQLITE_API void sqlite3_value_free(sqlite3_value*); - -/* -** CAPI3REF: Obtain Aggregate Function Context -** METHOD: sqlite3_context -** -** Implementations of aggregate SQL functions use this -** routine to allocate memory for storing their state. -** -** ^The first time the sqlite3_aggregate_context(C,N) routine is called -** for a particular aggregate function, SQLite -** allocates N of memory, zeroes out that memory, and returns a pointer -** to the new memory. ^On second and subsequent calls to -** sqlite3_aggregate_context() for the same aggregate function instance, -** the same buffer is returned. Sqlite3_aggregate_context() is normally -** called once for each invocation of the xStep callback and then one -** last time when the xFinal callback is invoked. ^(When no rows match -** an aggregate query, the xStep() callback of the aggregate function -** implementation is never called and xFinal() is called exactly once. -** In those cases, sqlite3_aggregate_context() might be called for the -** first time from within xFinal().)^ -** -** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer -** when first called if N is less than or equal to zero or if a memory -** allocate error occurs. -** -** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is -** determined by the N parameter on first successful call. Changing the -** value of N in subsequent call to sqlite3_aggregate_context() within -** the same aggregate function instance will not resize the memory -** allocation.)^ Within the xFinal callback, it is customary to set -** N=0 in calls to sqlite3_aggregate_context(C,N) so that no -** pointless memory allocations occur. -** -** ^SQLite automatically frees the memory allocated by -** sqlite3_aggregate_context() when the aggregate query concludes. -** -** The first parameter must be a copy of the -** [sqlite3_context | SQL function context] that is the first parameter -** to the xStep or xFinal callback routine that implements the aggregate -** function. -** -** This routine must be called from the same thread in which -** the aggregate SQL function is running. -*/ -SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); - -/* -** CAPI3REF: User Data For Functions -** METHOD: sqlite3_context -** -** ^The sqlite3_user_data() interface returns a copy of -** the pointer that was the pUserData parameter (the 5th parameter) -** of the [sqlite3_create_function()] -** and [sqlite3_create_function16()] routines that originally -** registered the application defined function. -** -** This routine must be called from the same thread in which -** the application-defined function is running. -*/ -SQLITE_API void *sqlite3_user_data(sqlite3_context*); - -/* -** CAPI3REF: Database Connection For Functions -** METHOD: sqlite3_context -** -** ^The sqlite3_context_db_handle() interface returns a copy of -** the pointer to the [database connection] (the 1st parameter) -** of the [sqlite3_create_function()] -** and [sqlite3_create_function16()] routines that originally -** registered the application defined function. -*/ -SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); - -/* -** CAPI3REF: Function Auxiliary Data -** METHOD: sqlite3_context -** -** These functions may be used by (non-aggregate) SQL functions to -** associate metadata with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. An example -** of where this might be useful is in a regular-expression matching -** function. The compiled version of the regular expression can be stored as -** metadata associated with the pattern string. -** Then as long as the pattern string remains the same, -** the compiled regular expression can be reused on multiple -** invocations of the same function. -** -** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata -** associated by the sqlite3_set_auxdata() function with the Nth argument -** value to the application-defined function. ^If there is no metadata -** associated with the function argument, this sqlite3_get_auxdata() interface -** returns a NULL pointer. -** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th -** argument of the application-defined function. ^Subsequent -** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or -** NULL if the metadata has been discarded. -** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, -** SQLite will invoke the destructor function X with parameter P exactly -** once, when the metadata is discarded. -** SQLite is free to discard the metadata at any time, including:
    -**
  • ^(when the corresponding function parameter changes)^, or -**
  • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the -** SQL statement)^, or -**
  • ^(when sqlite3_set_auxdata() is invoked again on the same -** parameter)^, or -**
  • ^(during the original sqlite3_set_auxdata() call when a memory -** allocation error occurs.)^
-** -** Note the last bullet in particular. The destructor X in -** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the -** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() -** should be called near the end of the function implementation and the -** function implementation should not make any use of P after -** sqlite3_set_auxdata() has been called. -** -** ^(In practice, metadata is preserved between function calls for -** function parameters that are compile-time constants, including literal -** values and [parameters] and expressions composed from the same.)^ -** -** These routines must be called from the same thread in which -** the SQL function is running. -*/ -SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); -SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); - - -/* -** CAPI3REF: Constants Defining Special Destructor Behavior -** -** These are special values for the destructor that is passed in as the -** final argument to routines like [sqlite3_result_blob()]. ^If the destructor -** argument is SQLITE_STATIC, it means that the content pointer is constant -** and will never change. It does not need to be destroyed. ^The -** SQLITE_TRANSIENT value means that the content will likely change in -** the near future and that SQLite should make its own private copy of -** the content before returning. -** -** The typedef is necessary to work around problems in certain -** C++ compilers. -*/ -typedef void (*sqlite3_destructor_type)(void*); -#define SQLITE_STATIC ((sqlite3_destructor_type)0) -#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) - -/* -** CAPI3REF: Setting The Result Of An SQL Function -** METHOD: sqlite3_context -** -** These routines are used by the xFunc or xFinal callbacks that -** implement SQL functions and aggregates. See -** [sqlite3_create_function()] and [sqlite3_create_function16()] -** for additional information. -** -** These functions work very much like the [parameter binding] family of -** functions used to bind values to host parameters in prepared statements. -** Refer to the [SQL parameter] documentation for additional information. -** -** ^The sqlite3_result_blob() interface sets the result from -** an application-defined function to be the BLOB whose content is pointed -** to by the second parameter and which is N bytes long where N is the -** third parameter. -** -** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) -** interfaces set the result of the application-defined function to be -** a BLOB containing all zero bytes and N bytes in size. -** -** ^The sqlite3_result_double() interface sets the result from -** an application-defined function to be a floating point value specified -** by its 2nd argument. -** -** ^The sqlite3_result_error() and sqlite3_result_error16() functions -** cause the implemented SQL function to throw an exception. -** ^SQLite uses the string pointed to by the -** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() -** as the text of an error message. ^SQLite interprets the error -** message string from sqlite3_result_error() as UTF-8. ^SQLite -** interprets the string from sqlite3_result_error16() as UTF-16 in native -** byte order. ^If the third parameter to sqlite3_result_error() -** or sqlite3_result_error16() is negative then SQLite takes as the error -** message all text up through the first zero character. -** ^If the third parameter to sqlite3_result_error() or -** sqlite3_result_error16() is non-negative then SQLite takes that many -** bytes (not characters) from the 2nd parameter as the error message. -** ^The sqlite3_result_error() and sqlite3_result_error16() -** routines make a private copy of the error message text before -** they return. Hence, the calling function can deallocate or -** modify the text after they return without harm. -** ^The sqlite3_result_error_code() function changes the error code -** returned by SQLite as a result of an error in a function. ^By default, -** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() -** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. -** -** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an -** error indicating that a string or BLOB is too long to represent. -** -** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an -** error indicating that a memory allocation failed. -** -** ^The sqlite3_result_int() interface sets the return value -** of the application-defined function to be the 32-bit signed integer -** value given in the 2nd argument. -** ^The sqlite3_result_int64() interface sets the return value -** of the application-defined function to be the 64-bit signed integer -** value given in the 2nd argument. -** -** ^The sqlite3_result_null() interface sets the return value -** of the application-defined function to be NULL. -** -** ^The sqlite3_result_text(), sqlite3_result_text16(), -** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces -** set the return value of the application-defined function to be -** a text string which is represented as UTF-8, UTF-16 native byte order, -** UTF-16 little endian, or UTF-16 big endian, respectively. -** ^The sqlite3_result_text64() interface sets the return value of an -** application-defined function to be a text string in an encoding -** specified by the fifth (and last) parameter, which must be one -** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. -** ^SQLite takes the text result from the application from -** the 2nd parameter of the sqlite3_result_text* interfaces. -** ^If the 3rd parameter to the sqlite3_result_text* interfaces -** is negative, then SQLite takes result text from the 2nd parameter -** through the first zero character. -** ^If the 3rd parameter to the sqlite3_result_text* interfaces -** is non-negative, then as many bytes (not characters) of the text -** pointed to by the 2nd parameter are taken as the application-defined -** function result. If the 3rd parameter is non-negative, then it -** must be the byte offset into the string where the NUL terminator would -** appear if the string where NUL terminated. If any NUL characters occur -** in the string at a byte offset that is less than the value of the 3rd -** parameter, then the resulting string will contain embedded NULs and the -** result of expressions operating on strings with embedded NULs is undefined. -** ^If the 4th parameter to the sqlite3_result_text* interfaces -** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that -** function as the destructor on the text or BLOB result when it has -** finished using that result. -** ^If the 4th parameter to the sqlite3_result_text* interfaces or to -** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite -** assumes that the text or BLOB result is in constant space and does not -** copy the content of the parameter nor call a destructor on the content -** when it has finished using that result. -** ^If the 4th parameter to the sqlite3_result_text* interfaces -** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT -** then SQLite makes a copy of the result into space obtained from -** from [sqlite3_malloc()] before it returns. -** -** ^The sqlite3_result_value() interface sets the result of -** the application-defined function to be a copy of the -** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The -** sqlite3_result_value() interface makes a copy of the [sqlite3_value] -** so that the [sqlite3_value] specified in the parameter may change or -** be deallocated after sqlite3_result_value() returns without harm. -** ^A [protected sqlite3_value] object may always be used where an -** [unprotected sqlite3_value] object is required, so either -** kind of [sqlite3_value] object can be used with this interface. -** -** If these routines are called from within the different thread -** than the one containing the application-defined function that received -** the [sqlite3_context] pointer, the results are undefined. -*/ -SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, - sqlite3_uint64,void(*)(void*)); -SQLITE_API void sqlite3_result_double(sqlite3_context*, double); -SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); -SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); -SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); -SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); -SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int(sqlite3_context*, int); -SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); -SQLITE_API void sqlite3_result_null(sqlite3_context*); -SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, - void(*)(void*), unsigned char encoding); -SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); -SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); - - -/* -** CAPI3REF: Setting The Subtype Of An SQL Function -** METHOD: sqlite3_context -** -** The sqlite3_result_subtype(C,T) function causes the subtype of -** the result from the [application-defined SQL function] with -** [sqlite3_context] C to be the value T. Only the lower 8 bits -** of the subtype T are preserved in current versions of SQLite; -** higher order bits are discarded. -** The number of subtype bytes preserved by SQLite might increase -** in future releases of SQLite. -*/ -SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); - -/* -** CAPI3REF: Define New Collating Sequences -** METHOD: sqlite3 -** -** ^These functions add, remove, or modify a [collation] associated -** with the [database connection] specified as the first argument. -** -** ^The name of the collation is a UTF-8 string -** for sqlite3_create_collation() and sqlite3_create_collation_v2() -** and a UTF-16 string in native byte order for sqlite3_create_collation16(). -** ^Collation names that compare equal according to [sqlite3_strnicmp()] are -** considered to be the same name. -** -** ^(The third argument (eTextRep) must be one of the constants: -**
    -**
  • [SQLITE_UTF8], -**
  • [SQLITE_UTF16LE], -**
  • [SQLITE_UTF16BE], -**
  • [SQLITE_UTF16], or -**
  • [SQLITE_UTF16_ALIGNED]. -**
)^ -** ^The eTextRep argument determines the encoding of strings passed -** to the collating function callback, xCallback. -** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep -** force strings to be UTF16 with native byte order. -** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin -** on an even byte address. -** -** ^The fourth argument, pArg, is an application data pointer that is passed -** through as the first argument to the collating function callback. -** -** ^The fifth argument, xCallback, is a pointer to the collating function. -** ^Multiple collating functions can be registered using the same name but -** with different eTextRep parameters and SQLite will use whichever -** function requires the least amount of data transformation. -** ^If the xCallback argument is NULL then the collating function is -** deleted. ^When all collating functions having the same name are deleted, -** that collation is no longer usable. -** -** ^The collating function callback is invoked with a copy of the pArg -** application data pointer and with two strings in the encoding specified -** by the eTextRep argument. The collating function must return an -** integer that is negative, zero, or positive -** if the first string is less than, equal to, or greater than the second, -** respectively. A collating function must always return the same answer -** given the same inputs. If two or more collating functions are registered -** to the same collation name (using different eTextRep values) then all -** must give an equivalent answer when invoked with equivalent strings. -** The collating function must obey the following properties for all -** strings A, B, and C: -** -**
    -**
  1. If A==B then B==A. -**
  2. If A==B and B==C then A==C. -**
  3. If A<B THEN B>A. -**
  4. If A<B and B<C then A<C. -**
-** -** If a collating function fails any of the above constraints and that -** collating function is registered and used, then the behavior of SQLite -** is undefined. -** -** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() -** with the addition that the xDestroy callback is invoked on pArg when -** the collating function is deleted. -** ^Collating functions are deleted when they are overridden by later -** calls to the collation creation functions or when the -** [database connection] is closed using [sqlite3_close()]. -** -** ^The xDestroy callback is not called if the -** sqlite3_create_collation_v2() function fails. Applications that invoke -** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should -** check the return code and dispose of the application data pointer -** themselves rather than expecting SQLite to deal with it for them. -** This is different from every other SQLite interface. The inconsistency -** is unfortunate but cannot be changed without breaking backwards -** compatibility. -** -** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. -*/ -SQLITE_API int sqlite3_create_collation( - sqlite3*, - const char *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) -); -SQLITE_API int sqlite3_create_collation_v2( - sqlite3*, - const char *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDestroy)(void*) -); -SQLITE_API int sqlite3_create_collation16( - sqlite3*, - const void *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) -); - -/* -** CAPI3REF: Collation Needed Callbacks -** METHOD: sqlite3 -** -** ^To avoid having to register all collation sequences before a database -** can be used, a single callback function may be registered with the -** [database connection] to be invoked whenever an undefined collation -** sequence is required. -** -** ^If the function is registered using the sqlite3_collation_needed() API, -** then it is passed the names of undefined collation sequences as strings -** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, -** the names are passed as UTF-16 in machine native byte order. -** ^A call to either function replaces the existing collation-needed callback. -** -** ^(When the callback is invoked, the first argument passed is a copy -** of the second argument to sqlite3_collation_needed() or -** sqlite3_collation_needed16(). The second argument is the database -** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], -** or [SQLITE_UTF16LE], indicating the most desirable form of the collation -** sequence function required. The fourth parameter is the name of the -** required collation sequence.)^ -** -** The callback function should register the desired collation using -** [sqlite3_create_collation()], [sqlite3_create_collation16()], or -** [sqlite3_create_collation_v2()]. -*/ -SQLITE_API int sqlite3_collation_needed( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const char*) -); -SQLITE_API int sqlite3_collation_needed16( - sqlite3*, - void*, - void(*)(void*,sqlite3*,int eTextRep,const void*) -); - -#ifdef SQLITE_HAS_CODEC -/* -** Specify the key for an encrypted database. This routine should be -** called right after sqlite3_open(). -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -SQLITE_API int sqlite3_key( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The key */ -); -SQLITE_API int sqlite3_key_v2( - sqlite3 *db, /* Database to be rekeyed */ - const char *zDbName, /* Name of the database */ - const void *pKey, int nKey /* The key */ -); - -/* -** Change the key on an open database. If the current database is not -** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the -** database is decrypted. -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -SQLITE_API int sqlite3_rekey( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The new key */ -); -SQLITE_API int sqlite3_rekey_v2( - sqlite3 *db, /* Database to be rekeyed */ - const char *zDbName, /* Name of the database */ - const void *pKey, int nKey /* The new key */ -); - -/* -** Specify the activation key for a SEE database. Unless -** activated, none of the SEE routines will work. -*/ -SQLITE_API void sqlite3_activate_see( - const char *zPassPhrase /* Activation phrase */ -); -#endif - -#ifdef SQLITE_ENABLE_CEROD -/* -** Specify the activation key for a CEROD database. Unless -** activated, none of the CEROD routines will work. -*/ -SQLITE_API void sqlite3_activate_cerod( - const char *zPassPhrase /* Activation phrase */ -); -#endif - -/* -** CAPI3REF: Suspend Execution For A Short Time -** -** The sqlite3_sleep() function causes the current thread to suspend execution -** for at least a number of milliseconds specified in its parameter. -** -** If the operating system does not support sleep requests with -** millisecond time resolution, then the time will be rounded up to -** the nearest second. The number of milliseconds of sleep actually -** requested from the operating system is returned. -** -** ^SQLite implements this interface by calling the xSleep() -** method of the default [sqlite3_vfs] object. If the xSleep() method -** of the default VFS is not implemented correctly, or not implemented at -** all, then the behavior of sqlite3_sleep() may deviate from the description -** in the previous paragraphs. -*/ -SQLITE_API int sqlite3_sleep(int); - -/* -** CAPI3REF: Name Of The Folder Holding Temporary Files -** -** ^(If this global variable is made to point to a string which is -** the name of a folder (a.k.a. directory), then all temporary files -** created by SQLite when using a built-in [sqlite3_vfs | VFS] -** will be placed in that directory.)^ ^If this variable -** is a NULL pointer, then SQLite performs a search for an appropriate -** temporary file directory. -** -** Applications are strongly discouraged from using this global variable. -** It is required to set a temporary folder on Windows Runtime (WinRT). -** But for all other platforms, it is highly recommended that applications -** neither read nor write this variable. This global variable is a relic -** that exists for backwards compatibility of legacy applications and should -** be avoided in new projects. -** -** It is not safe to read or modify this variable in more than one -** thread at a time. It is not safe to read or modify this variable -** if a [database connection] is being used at the same time in a separate -** thread. -** It is intended that this variable be set once -** as part of process initialization and before any SQLite interface -** routines have been called and that this variable remain unchanged -** thereafter. -** -** ^The [temp_store_directory pragma] may modify this variable and cause -** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, -** the [temp_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from -** [sqlite3_malloc] and the pragma may attempt to free that memory -** using [sqlite3_free]. -** Hence, if this variable is modified directly, either it should be -** made NULL or made to point to memory obtained from [sqlite3_malloc] -** or else the use of the [temp_store_directory pragma] should be avoided. -** Except when requested by the [temp_store_directory pragma], SQLite -** does not free the memory that sqlite3_temp_directory points to. If -** the application wants that memory to be freed, it must do -** so itself, taking care to only do so after all [database connection] -** objects have been destroyed. -** -** Note to Windows Runtime users: The temporary directory must be set -** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various -** features that require the use of temporary files may fail. Here is an -** example of how to do this using C++ with the Windows Runtime: -** -**
-** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
-**       TemporaryFolder->Path->Data();
-** char zPathBuf[MAX_PATH + 1];
-** memset(zPathBuf, 0, sizeof(zPathBuf));
-** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
-**       NULL, NULL);
-** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
-** 
-*/ -SQLITE_API char *sqlite3_temp_directory; - -/* -** CAPI3REF: Name Of The Folder Holding Database Files -** -** ^(If this global variable is made to point to a string which is -** the name of a folder (a.k.a. directory), then all database files -** specified with a relative pathname and created or accessed by -** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed -** to be relative to that directory.)^ ^If this variable is a NULL -** pointer, then SQLite assumes that all database files specified -** with a relative pathname are relative to the current directory -** for the process. Only the windows VFS makes use of this global -** variable; it is ignored by the unix VFS. -** -** Changing the value of this variable while a database connection is -** open can result in a corrupt database. -** -** It is not safe to read or modify this variable in more than one -** thread at a time. It is not safe to read or modify this variable -** if a [database connection] is being used at the same time in a separate -** thread. -** It is intended that this variable be set once -** as part of process initialization and before any SQLite interface -** routines have been called and that this variable remain unchanged -** thereafter. -** -** ^The [data_store_directory pragma] may modify this variable and cause -** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, -** the [data_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from -** [sqlite3_malloc] and the pragma may attempt to free that memory -** using [sqlite3_free]. -** Hence, if this variable is modified directly, either it should be -** made NULL or made to point to memory obtained from [sqlite3_malloc] -** or else the use of the [data_store_directory pragma] should be avoided. -*/ -SQLITE_API char *sqlite3_data_directory; - -/* -** CAPI3REF: Test For Auto-Commit Mode -** KEYWORDS: {autocommit mode} -** METHOD: sqlite3 -** -** ^The sqlite3_get_autocommit() interface returns non-zero or -** zero if the given database connection is or is not in autocommit mode, -** respectively. ^Autocommit mode is on by default. -** ^Autocommit mode is disabled by a [BEGIN] statement. -** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. -** -** If certain kinds of errors occur on a statement within a multi-statement -** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], -** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the -** transaction might be rolled back automatically. The only way to -** find out whether SQLite automatically rolled back the transaction after -** an error is to use this function. -** -** If another thread changes the autocommit status of the database -** connection while this routine is running, then the return value -** is undefined. -*/ -SQLITE_API int sqlite3_get_autocommit(sqlite3*); - -/* -** CAPI3REF: Find The Database Handle Of A Prepared Statement -** METHOD: sqlite3_stmt -** -** ^The sqlite3_db_handle interface returns the [database connection] handle -** to which a [prepared statement] belongs. ^The [database connection] -** returned by sqlite3_db_handle is the same [database connection] -** that was the first argument -** to the [sqlite3_prepare_v2()] call (or its variants) that was used to -** create the statement in the first place. -*/ -SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); - -/* -** CAPI3REF: Return The Filename For A Database Connection -** METHOD: sqlite3 -** -** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename -** associated with database N of connection D. ^The main database file -** has the name "main". If there is no attached database N on the database -** connection D, or if database N is a temporary or in-memory database, then -** a NULL pointer is returned. -** -** ^The filename returned by this function is the output of the -** xFullPathname method of the [VFS]. ^In other words, the filename -** will be an absolute pathname, even if the filename used -** to open the database originally was a URI or relative pathname. -*/ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); - -/* -** CAPI3REF: Determine if a database is read-only -** METHOD: sqlite3 -** -** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N -** of connection D is read-only, 0 if it is read/write, or -1 if N is not -** the name of a database on connection D. -*/ -SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); - -/* -** CAPI3REF: Find the next prepared statement -** METHOD: sqlite3 -** -** ^This interface returns a pointer to the next [prepared statement] after -** pStmt associated with the [database connection] pDb. ^If pStmt is NULL -** then this interface returns a pointer to the first prepared statement -** associated with the database connection pDb. ^If no prepared statement -** satisfies the conditions of this routine, it returns NULL. -** -** The [database connection] pointer D in a call to -** [sqlite3_next_stmt(D,S)] must refer to an open database -** connection and in particular must not be a NULL pointer. -*/ -SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); - -/* -** CAPI3REF: Commit And Rollback Notification Callbacks -** METHOD: sqlite3 -** -** ^The sqlite3_commit_hook() interface registers a callback -** function to be invoked whenever a transaction is [COMMIT | committed]. -** ^Any callback set by a previous call to sqlite3_commit_hook() -** for the same database connection is overridden. -** ^The sqlite3_rollback_hook() interface registers a callback -** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. -** ^Any callback set by a previous call to sqlite3_rollback_hook() -** for the same database connection is overridden. -** ^The pArg argument is passed through to the callback. -** ^If the callback on a commit hook function returns non-zero, -** then the commit is converted into a rollback. -** -** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions -** return the P argument from the previous call of the same function -** on the same [database connection] D, or NULL for -** the first call for each function on D. -** -** The commit and rollback hook callbacks are not reentrant. -** The callback implementation must not do anything that will modify -** the database connection that invoked the callback. Any actions -** to modify the database connection must be deferred until after the -** completion of the [sqlite3_step()] call that triggered the commit -** or rollback hook in the first place. -** Note that running any other SQL statements, including SELECT statements, -** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify -** the database connections for the meaning of "modify" in this paragraph. -** -** ^Registering a NULL function disables the callback. -** -** ^When the commit hook callback routine returns zero, the [COMMIT] -** operation is allowed to continue normally. ^If the commit hook -** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. -** ^The rollback hook is invoked on a rollback that results from a commit -** hook returning non-zero, just as it would be with any other rollback. -** -** ^For the purposes of this API, a transaction is said to have been -** rolled back if an explicit "ROLLBACK" statement is executed, or -** an error or constraint causes an implicit rollback to occur. -** ^The rollback callback is not invoked if a transaction is -** automatically rolled back because the database connection is closed. -** -** See also the [sqlite3_update_hook()] interface. -*/ -SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); - -/* -** CAPI3REF: Data Change Notification Callbacks -** METHOD: sqlite3 -** -** ^The sqlite3_update_hook() interface registers a callback function -** with the [database connection] identified by the first argument -** to be invoked whenever a row is updated, inserted or deleted in -** a [rowid table]. -** ^Any callback set by a previous call to this function -** for the same database connection is overridden. -** -** ^The second argument is a pointer to the function to invoke when a -** row is updated, inserted or deleted in a rowid table. -** ^The first argument to the callback is a copy of the third argument -** to sqlite3_update_hook(). -** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], -** or [SQLITE_UPDATE], depending on the operation that caused the callback -** to be invoked. -** ^The third and fourth arguments to the callback contain pointers to the -** database and table name containing the affected row. -** ^The final callback parameter is the [rowid] of the row. -** ^In the case of an update, this is the [rowid] after the update takes place. -** -** ^(The update hook is not invoked when internal system tables are -** modified (i.e. sqlite_master and sqlite_sequence).)^ -** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. -** -** ^In the current implementation, the update hook -** is not invoked when duplication rows are deleted because of an -** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook -** invoked when rows are deleted using the [truncate optimization]. -** The exceptions defined in this paragraph might change in a future -** release of SQLite. -** -** The update hook implementation must not do anything that will modify -** the database connection that invoked the update hook. Any actions -** to modify the database connection must be deferred until after the -** completion of the [sqlite3_step()] call that triggered the update hook. -** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their -** database connections for the meaning of "modify" in this paragraph. -** -** ^The sqlite3_update_hook(D,C,P) function -** returns the P argument from the previous call -** on the same [database connection] D, or NULL for -** the first call on D. -** -** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()], -** and [sqlite3_preupdate_hook()] interfaces. -*/ -SQLITE_API void *sqlite3_update_hook( - sqlite3*, - void(*)(void *,int ,char const *,char const *,sqlite3_int64), - void* -); - -/* -** CAPI3REF: Enable Or Disable Shared Pager Cache -** -** ^(This routine enables or disables the sharing of the database cache -** and schema data structures between [database connection | connections] -** to the same database. Sharing is enabled if the argument is true -** and disabled if the argument is false.)^ -** -** ^Cache sharing is enabled and disabled for an entire process. -** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). -** In prior versions of SQLite, -** sharing was enabled or disabled for each thread separately. -** -** ^(The cache sharing mode set by this interface effects all subsequent -** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. -** Existing database connections continue use the sharing mode -** that was in effect at the time they were opened.)^ -** -** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled -** successfully. An [error code] is returned otherwise.)^ -** -** ^Shared cache is disabled by default. But this might change in -** future releases of SQLite. Applications that care about shared -** cache setting should set it explicitly. -** -** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 -** and will always return SQLITE_MISUSE. On those systems, -** shared cache mode should be enabled per-database connection via -** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. -** -** This interface is threadsafe on processors where writing a -** 32-bit integer is atomic. -** -** See Also: [SQLite Shared-Cache Mode] -*/ -SQLITE_API int sqlite3_enable_shared_cache(int); - -/* -** CAPI3REF: Attempt To Free Heap Memory -** -** ^The sqlite3_release_memory() interface attempts to free N bytes -** of heap memory by deallocating non-essential memory allocations -** held by the database library. Memory used to cache database -** pages to improve performance is an example of non-essential memory. -** ^sqlite3_release_memory() returns the number of bytes actually freed, -** which might be more or less than the amount requested. -** ^The sqlite3_release_memory() routine is a no-op returning zero -** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. -** -** See also: [sqlite3_db_release_memory()] -*/ -SQLITE_API int sqlite3_release_memory(int); - -/* -** CAPI3REF: Free Memory Used By A Database Connection -** METHOD: sqlite3 -** -** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap -** memory as possible from database connection D. Unlike the -** [sqlite3_release_memory()] interface, this interface is in effect even -** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is -** omitted. -** -** See also: [sqlite3_release_memory()] -*/ -SQLITE_API int sqlite3_db_release_memory(sqlite3*); - -/* -** CAPI3REF: Impose A Limit On Heap Size -** -** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the -** soft limit on the amount of heap memory that may be allocated by SQLite. -** ^SQLite strives to keep heap memory utilization below the soft heap -** limit by reducing the number of pages held in the page cache -** as heap memory usages approaches the limit. -** ^The soft heap limit is "soft" because even though SQLite strives to stay -** below the limit, it will exceed the limit rather than generate -** an [SQLITE_NOMEM] error. In other words, the soft heap limit -** is advisory only. -** -** ^The return value from sqlite3_soft_heap_limit64() is the size of -** the soft heap limit prior to the call, or negative in the case of an -** error. ^If the argument N is negative -** then no change is made to the soft heap limit. Hence, the current -** size of the soft heap limit can be determined by invoking -** sqlite3_soft_heap_limit64() with a negative argument. -** -** ^If the argument N is zero then the soft heap limit is disabled. -** -** ^(The soft heap limit is not enforced in the current implementation -** if one or more of following conditions are true: -** -**
    -**
  • The soft heap limit is set to zero. -**
  • Memory accounting is disabled using a combination of the -** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and -** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. -**
  • An alternative page cache implementation is specified using -** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). -**
  • The page cache allocates from its own memory pool supplied -** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than -** from the heap. -**
)^ -** -** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]), -** the soft heap limit is enforced -** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT] -** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT], -** the soft heap limit is enforced on every memory allocation. Without -** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced -** when memory is allocated by the page cache. Testing suggests that because -** the page cache is the predominate memory user in SQLite, most -** applications will achieve adequate soft heap limit enforcement without -** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT]. -** -** The circumstances under which SQLite will enforce the soft heap limit may -** changes in future releases of SQLite. -*/ -SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); - -/* -** CAPI3REF: Deprecated Soft Heap Limit Interface -** DEPRECATED -** -** This is a deprecated version of the [sqlite3_soft_heap_limit64()] -** interface. This routine is provided for historical compatibility -** only. All new applications should use the -** [sqlite3_soft_heap_limit64()] interface rather than this one. -*/ -SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); - - -/* -** CAPI3REF: Extract Metadata About A Column Of A Table -** METHOD: sqlite3 -** -** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns -** information about column C of table T in database D -** on [database connection] X.)^ ^The sqlite3_table_column_metadata() -** interface returns SQLITE_OK and fills in the non-NULL pointers in -** the final five arguments with appropriate values if the specified -** column exists. ^The sqlite3_table_column_metadata() interface returns -** SQLITE_ERROR and if the specified column does not exist. -** ^If the column-name parameter to sqlite3_table_column_metadata() is a -** NULL pointer, then this routine simply checks for the existence of the -** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it -** does not. -** -** ^The column is identified by the second, third and fourth parameters to -** this function. ^(The second parameter is either the name of the database -** (i.e. "main", "temp", or an attached database) containing the specified -** table or NULL.)^ ^If it is NULL, then all attached databases are searched -** for the table using the same algorithm used by the database engine to -** resolve unqualified table references. -** -** ^The third and fourth parameters to this function are the table and column -** name of the desired column, respectively. -** -** ^Metadata is returned by writing to the memory locations passed as the 5th -** and subsequent parameters to this function. ^Any of these arguments may be -** NULL, in which case the corresponding element of metadata is omitted. -** -** ^(
-** -**
Parameter Output
Type
Description -** -**
5th const char* Data type -**
6th const char* Name of default collation sequence -**
7th int True if column has a NOT NULL constraint -**
8th int True if column is part of the PRIMARY KEY -**
9th int True if column is [AUTOINCREMENT] -**
-**
)^ -** -** ^The memory pointed to by the character pointers returned for the -** declaration type and collation sequence is valid until the next -** call to any SQLite API function. -** -** ^If the specified table is actually a view, an [error code] is returned. -** -** ^If the specified column is "rowid", "oid" or "_rowid_" and the table -** is not a [WITHOUT ROWID] table and an -** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output -** parameters are set for the explicitly declared column. ^(If there is no -** [INTEGER PRIMARY KEY] column, then the outputs -** for the [rowid] are set as follows: -** -**
-**     data type: "INTEGER"
-**     collation sequence: "BINARY"
-**     not null: 0
-**     primary key: 1
-**     auto increment: 0
-** 
)^ -** -** ^This function causes all database schemas to be read from disk and -** parsed, if that has not already been done, and returns an error if -** any errors are encountered while loading the schema. -*/ -SQLITE_API int sqlite3_table_column_metadata( - sqlite3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if column is auto-increment */ -); - -/* -** CAPI3REF: Load An Extension -** METHOD: sqlite3 -** -** ^This interface loads an SQLite extension library from the named file. -** -** ^The sqlite3_load_extension() interface attempts to load an -** [SQLite extension] library contained in the file zFile. If -** the file cannot be loaded directly, attempts are made to load -** with various operating-system specific extensions added. -** So for example, if "samplelib" cannot be loaded, then names like -** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might -** be tried also. -** -** ^The entry point is zProc. -** ^(zProc may be 0, in which case SQLite will try to come up with an -** entry point name on its own. It first tries "sqlite3_extension_init". -** If that does not work, it constructs a name "sqlite3_X_init" where the -** X is consists of the lower-case equivalent of all ASCII alphabetic -** characters in the filename from the last "/" to the first following -** "." and omitting any initial "lib".)^ -** ^The sqlite3_load_extension() interface returns -** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. -** ^If an error occurs and pzErrMsg is not 0, then the -** [sqlite3_load_extension()] interface shall attempt to -** fill *pzErrMsg with error message text stored in memory -** obtained from [sqlite3_malloc()]. The calling function -** should free this memory by calling [sqlite3_free()]. -** -** ^Extension loading must be enabled using -** [sqlite3_enable_load_extension()] or -** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) -** prior to calling this API, -** otherwise an error will be returned. -** -** Security warning: It is recommended that the -** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this -** interface. The use of the [sqlite3_enable_load_extension()] interface -** should be avoided. This will keep the SQL function [load_extension()] -** disabled and prevent SQL injections from giving attackers -** access to extension loading capabilities. -** -** See also the [load_extension() SQL function]. -*/ -SQLITE_API int sqlite3_load_extension( - sqlite3 *db, /* Load the extension into this database connection */ - const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Derived from zFile if 0 */ - char **pzErrMsg /* Put error message here if not 0 */ -); - -/* -** CAPI3REF: Enable Or Disable Extension Loading -** METHOD: sqlite3 -** -** ^So as not to open security holes in older applications that are -** unprepared to deal with [extension loading], and as a means of disabling -** [extension loading] while evaluating user-entered SQL, the following API -** is provided to turn the [sqlite3_load_extension()] mechanism on and off. -** -** ^Extension loading is off by default. -** ^Call the sqlite3_enable_load_extension() routine with onoff==1 -** to turn extension loading on and call it with onoff==0 to turn -** it back off again. -** -** ^This interface enables or disables both the C-API -** [sqlite3_load_extension()] and the SQL function [load_extension()]. -** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) -** to enable or disable only the C-API.)^ -** -** Security warning: It is recommended that extension loading -** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method -** rather than this interface, so the [load_extension()] SQL function -** remains disabled. This will prevent SQL injections from giving attackers -** access to extension loading capabilities. -*/ -SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); - -/* -** CAPI3REF: Automatically Load Statically Linked Extensions -** -** ^This interface causes the xEntryPoint() function to be invoked for -** each new [database connection] that is created. The idea here is that -** xEntryPoint() is the entry point for a statically linked [SQLite extension] -** that is to be automatically loaded into all new database connections. -** -** ^(Even though the function prototype shows that xEntryPoint() takes -** no arguments and returns void, SQLite invokes xEntryPoint() with three -** arguments and expects an integer result as if the signature of the -** entry point where as follows: -** -**
-**    int xEntryPoint(
-**      sqlite3 *db,
-**      const char **pzErrMsg,
-**      const struct sqlite3_api_routines *pThunk
-**    );
-** 
)^ -** -** If the xEntryPoint routine encounters an error, it should make *pzErrMsg -** point to an appropriate error message (obtained from [sqlite3_mprintf()]) -** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg -** is NULL before calling the xEntryPoint(). ^SQLite will invoke -** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any -** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], -** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. -** -** ^Calling sqlite3_auto_extension(X) with an entry point X that is already -** on the list of automatic extensions is a harmless no-op. ^No entry point -** will be called more than once for each database connection that is opened. -** -** See also: [sqlite3_reset_auto_extension()] -** and [sqlite3_cancel_auto_extension()] -*/ -SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); - -/* -** CAPI3REF: Cancel Automatic Extension Loading -** -** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the -** initialization routine X that was registered using a prior call to -** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] -** routine returns 1 if initialization routine X was successfully -** unregistered and it returns 0 if X was not on the list of initialization -** routines. -*/ -SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); - -/* -** CAPI3REF: Reset Automatic Extension Loading -** -** ^This interface disables all automatic extensions previously -** registered using [sqlite3_auto_extension()]. -*/ -SQLITE_API void sqlite3_reset_auto_extension(void); - -/* -** The interface to the virtual-table mechanism is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stabilizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -*/ - -/* -** Structures used by the virtual table interface -*/ -typedef struct sqlite3_vtab sqlite3_vtab; -typedef struct sqlite3_index_info sqlite3_index_info; -typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; -typedef struct sqlite3_module sqlite3_module; - -/* -** CAPI3REF: Virtual Table Object -** KEYWORDS: sqlite3_module {virtual table module} -** -** This structure, sometimes called a "virtual table module", -** defines the implementation of a [virtual tables]. -** This structure consists mostly of methods for the module. -** -** ^A virtual table module is created by filling in a persistent -** instance of this structure and passing a pointer to that instance -** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. -** ^The registration remains valid until it is replaced by a different -** module or until the [database connection] closes. The content -** of this structure must not change while it is registered with -** any database connection. -*/ -struct sqlite3_module { - int iVersion; - int (*xCreate)(sqlite3*, void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVTab, char**); - int (*xConnect)(sqlite3*, void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVTab, char**); - int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); - int (*xDisconnect)(sqlite3_vtab *pVTab); - int (*xDestroy)(sqlite3_vtab *pVTab); - int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); - int (*xClose)(sqlite3_vtab_cursor*); - int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, - int argc, sqlite3_value **argv); - int (*xNext)(sqlite3_vtab_cursor*); - int (*xEof)(sqlite3_vtab_cursor*); - int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); - int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); - int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); - int (*xBegin)(sqlite3_vtab *pVTab); - int (*xSync)(sqlite3_vtab *pVTab); - int (*xCommit)(sqlite3_vtab *pVTab); - int (*xRollback)(sqlite3_vtab *pVTab); - int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), - void **ppArg); - int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); - /* The methods above are in version 1 of the sqlite_module object. Those - ** below are for version 2 and greater. */ - int (*xSavepoint)(sqlite3_vtab *pVTab, int); - int (*xRelease)(sqlite3_vtab *pVTab, int); - int (*xRollbackTo)(sqlite3_vtab *pVTab, int); -}; - -/* -** CAPI3REF: Virtual Table Indexing Information -** KEYWORDS: sqlite3_index_info -** -** The sqlite3_index_info structure and its substructures is used as part -** of the [virtual table] interface to -** pass information into and receive the reply from the [xBestIndex] -** method of a [virtual table module]. The fields under **Inputs** are the -** inputs to xBestIndex and are read-only. xBestIndex inserts its -** results into the **Outputs** fields. -** -** ^(The aConstraint[] array records WHERE clause constraints of the form: -** -**
column OP expr
-** -** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is -** stored in aConstraint[].op using one of the -** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ -** ^(The index of the column is stored in -** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the -** expr on the right-hand side can be evaluated (and thus the constraint -** is usable) and false if it cannot.)^ -** -** ^The optimizer automatically inverts terms of the form "expr OP column" -** and makes other simplifications to the WHERE clause in an attempt to -** get as many WHERE clause terms into the form shown above as possible. -** ^The aConstraint[] array only reports WHERE clause terms that are -** relevant to the particular virtual table being queried. -** -** ^Information about the ORDER BY clause is stored in aOrderBy[]. -** ^Each term of aOrderBy records a column of the ORDER BY clause. -** -** The colUsed field indicates which columns of the virtual table may be -** required by the current scan. Virtual table columns are numbered from -** zero in the order in which they appear within the CREATE TABLE statement -** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62), -** the corresponding bit is set within the colUsed mask if the column may be -** required by SQLite. If the table has at least 64 columns and any column -** to the right of the first 63 is required, then bit 63 of colUsed is also -** set. In other words, column iCol may be required if the expression -** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to -** non-zero. -** -** The [xBestIndex] method must fill aConstraintUsage[] with information -** about what parameters to pass to xFilter. ^If argvIndex>0 then -** the right-hand side of the corresponding aConstraint[] is evaluated -** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit -** is true, then the constraint is assumed to be fully handled by the -** virtual table and is not checked again by SQLite.)^ -** -** ^The idxNum and idxPtr values are recorded and passed into the -** [xFilter] method. -** ^[sqlite3_free()] is used to free idxPtr if and only if -** needToFreeIdxPtr is true. -** -** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in -** the correct order to satisfy the ORDER BY clause so that no separate -** sorting step is required. -** -** ^The estimatedCost value is an estimate of the cost of a particular -** strategy. A cost of N indicates that the cost of the strategy is similar -** to a linear scan of an SQLite table with N rows. A cost of log(N) -** indicates that the expense of the operation is similar to that of a -** binary search on a unique indexed field of an SQLite table with N rows. -** -** ^The estimatedRows value is an estimate of the number of rows that -** will be returned by the strategy. -** -** The xBestIndex method may optionally populate the idxFlags field with a -** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - -** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. -** -** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then -** SQLite also assumes that if a call to the xUpdate() method is made as -** part of the same statement to delete or update a virtual table row and the -** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback -** any database changes. In other words, if the xUpdate() returns -** SQLITE_CONSTRAINT, the database contents must be exactly as they were -** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not -** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by -** the xUpdate method are automatically rolled back by SQLite. -** -** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info -** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). -** If a virtual table extension is -** used with an SQLite version earlier than 3.8.2, the results of attempting -** to read or write the estimatedRows field are undefined (but are likely -** to included crashing the application). The estimatedRows field should -** therefore only be used if [sqlite3_libversion_number()] returns a -** value greater than or equal to 3008002. Similarly, the idxFlags field -** was added for [version 3.9.0] ([dateof:3.9.0]). -** It may therefore only be used if -** sqlite3_libversion_number() returns a value greater than or equal to -** 3009000. -*/ -struct sqlite3_index_info { - /* Inputs */ - int nConstraint; /* Number of entries in aConstraint */ - struct sqlite3_index_constraint { - int iColumn; /* Column constrained. -1 for ROWID */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should ignore */ - } *aConstraint; /* Table of WHERE clause constraints */ - int nOrderBy; /* Number of terms in the ORDER BY clause */ - struct sqlite3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlite3_index_constraint_usage { - int argvIndex; /* if >0, constraint is part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this constraint */ - } *aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from sqlite3_malloc */ - int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ - /* Fields below are only available in SQLite 3.8.2 and later */ - sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ - /* Fields below are only available in SQLite 3.9.0 and later */ - int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ - /* Fields below are only available in SQLite 3.10.0 and later */ - sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ -}; - -/* -** CAPI3REF: Virtual Table Scan Flags -*/ -#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ - -/* -** CAPI3REF: Virtual Table Constraint Operator Codes -** -** These macros defined the allowed values for the -** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of -** a query that uses a [virtual table]. -*/ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 - -/* -** CAPI3REF: Register A Virtual Table Implementation -** METHOD: sqlite3 -** -** ^These routines are used to register a new [virtual table module] name. -** ^Module names must be registered before -** creating a new [virtual table] using the module and before using a -** preexisting [virtual table] for the module. -** -** ^The module name is registered on the [database connection] specified -** by the first parameter. ^The name of the module is given by the -** second parameter. ^The third parameter is a pointer to -** the implementation of the [virtual table module]. ^The fourth -** parameter is an arbitrary client data pointer that is passed through -** into the [xCreate] and [xConnect] methods of the virtual table module -** when a new virtual table is be being created or reinitialized. -** -** ^The sqlite3_create_module_v2() interface has a fifth parameter which -** is a pointer to a destructor for the pClientData. ^SQLite will -** invoke the destructor function (if it is not NULL) when SQLite -** no longer needs the pClientData pointer. ^The destructor will also -** be invoked if the call to sqlite3_create_module_v2() fails. -** ^The sqlite3_create_module() -** interface is equivalent to sqlite3_create_module_v2() with a NULL -** destructor. -*/ -SQLITE_API int sqlite3_create_module( - sqlite3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlite3_module *p, /* Methods for the module */ - void *pClientData /* Client data for xCreate/xConnect */ -); -SQLITE_API int sqlite3_create_module_v2( - sqlite3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlite3_module *p, /* Methods for the module */ - void *pClientData, /* Client data for xCreate/xConnect */ - void(*xDestroy)(void*) /* Module destructor function */ -); - -/* -** CAPI3REF: Virtual Table Instance Object -** KEYWORDS: sqlite3_vtab -** -** Every [virtual table module] implementation uses a subclass -** of this object to describe a particular instance -** of the [virtual table]. Each subclass will -** be tailored to the specific needs of the module implementation. -** The purpose of this superclass is to define certain fields that are -** common to all module implementations. -** -** ^Virtual tables methods can set an error message by assigning a -** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should -** take care that any prior string is freed by a call to [sqlite3_free()] -** prior to assigning a new string to zErrMsg. ^After the error message -** is delivered up to the client application, the string will be automatically -** freed by sqlite3_free() and the zErrMsg field will be zeroed. -*/ -struct sqlite3_vtab { - const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Number of open cursors */ - char *zErrMsg; /* Error message from sqlite3_mprintf() */ - /* Virtual table implementations will typically add additional fields */ -}; - -/* -** CAPI3REF: Virtual Table Cursor Object -** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} -** -** Every [virtual table module] implementation uses a subclass of the -** following structure to describe cursors that point into the -** [virtual table] and are used -** to loop through the virtual table. Cursors are created using the -** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed -** by the [sqlite3_module.xClose | xClose] method. Cursors are used -** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods -** of the module. Each module implementation will define -** the content of a cursor structure to suit its own needs. -** -** This superclass exists in order to define fields of the cursor that -** are common to all implementations. -*/ -struct sqlite3_vtab_cursor { - sqlite3_vtab *pVtab; /* Virtual table of this cursor */ - /* Virtual table implementations will typically add additional fields */ -}; - -/* -** CAPI3REF: Declare The Schema Of A Virtual Table -** -** ^The [xCreate] and [xConnect] methods of a -** [virtual table module] call this interface -** to declare the format (the names and datatypes of the columns) of -** the virtual tables they implement. -*/ -SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); - -/* -** CAPI3REF: Overload A Function For A Virtual Table -** METHOD: sqlite3 -** -** ^(Virtual tables can provide alternative implementations of functions -** using the [xFindFunction] method of the [virtual table module]. -** But global versions of those functions -** must exist in order to be overloaded.)^ -** -** ^(This API makes sure a global version of a function with a particular -** name and number of parameters exists. If no such function exists -** before this API is called, a new function is created.)^ ^The implementation -** of the new function always causes an exception to be thrown. So -** the new function is not good for anything by itself. Its only -** purpose is to be a placeholder function that can be overloaded -** by a [virtual table]. -*/ -SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); - -/* -** The interface to the virtual-table mechanism defined above (back up -** to a comment remarkably similar to this one) is currently considered -** to be experimental. The interface might change in incompatible ways. -** If this is a problem for you, do not use the interface at this time. -** -** When the virtual-table mechanism stabilizes, we will declare the -** interface fixed, support it indefinitely, and remove this comment. -*/ - -/* -** CAPI3REF: A Handle To An Open BLOB -** KEYWORDS: {BLOB handle} {BLOB handles} -** -** An instance of this object represents an open BLOB on which -** [sqlite3_blob_open | incremental BLOB I/O] can be performed. -** ^Objects of this type are created by [sqlite3_blob_open()] -** and destroyed by [sqlite3_blob_close()]. -** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces -** can be used to read or write small subsections of the BLOB. -** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. -*/ -typedef struct sqlite3_blob sqlite3_blob; - -/* -** CAPI3REF: Open A BLOB For Incremental I/O -** METHOD: sqlite3 -** CONSTRUCTOR: sqlite3_blob -** -** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located -** in row iRow, column zColumn, table zTable in database zDb; -** in other words, the same BLOB that would be selected by: -** -**
-**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
-** 
)^ -** -** ^(Parameter zDb is not the filename that contains the database, but -** rather the symbolic name of the database. For attached databases, this is -** the name that appears after the AS keyword in the [ATTACH] statement. -** For the main database file, the database name is "main". For TEMP -** tables, the database name is "temp".)^ -** -** ^If the flags parameter is non-zero, then the BLOB is opened for read -** and write access. ^If the flags parameter is zero, the BLOB is opened for -** read-only access. -** -** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored -** in *ppBlob. Otherwise an [error code] is returned and, unless the error -** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided -** the API is not misused, it is always safe to call [sqlite3_blob_close()] -** on *ppBlob after this function it returns. -** -** This function fails with SQLITE_ERROR if any of the following are true: -**
    -**
  • ^(Database zDb does not exist)^, -**
  • ^(Table zTable does not exist within database zDb)^, -**
  • ^(Table zTable is a WITHOUT ROWID table)^, -**
  • ^(Column zColumn does not exist)^, -**
  • ^(Row iRow is not present in the table)^, -**
  • ^(The specified column of row iRow contains a value that is not -** a TEXT or BLOB value)^, -**
  • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE -** constraint and the blob is being opened for read/write access)^, -**
  • ^([foreign key constraints | Foreign key constraints] are enabled, -** column zColumn is part of a [child key] definition and the blob is -** being opened for read/write access)^. -**
-** -** ^Unless it returns SQLITE_MISUSE, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. -** -** -** ^(If the row that a BLOB handle points to is modified by an -** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects -** then the BLOB handle is marked as "expired". -** This is true if any column of the row is changed, even a column -** other than the one the BLOB handle is open on.)^ -** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for -** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. -** ^(Changes written into a BLOB prior to the BLOB expiring are not -** rolled back by the expiration of the BLOB. Such changes will eventually -** commit if the transaction continues to completion.)^ -** -** ^Use the [sqlite3_blob_bytes()] interface to determine the size of -** the opened blob. ^The size of a blob may not be changed by this -** interface. Use the [UPDATE] SQL command to change the size of a -** blob. -** -** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces -** and the built-in [zeroblob] SQL function may be used to create a -** zero-filled blob to read or write using the incremental-blob interface. -** -** To avoid a resource leak, every open [BLOB handle] should eventually -** be released by a call to [sqlite3_blob_close()]. -*/ -SQLITE_API int sqlite3_blob_open( - sqlite3*, - const char *zDb, - const char *zTable, - const char *zColumn, - sqlite3_int64 iRow, - int flags, - sqlite3_blob **ppBlob -); - -/* -** CAPI3REF: Move a BLOB Handle to a New Row -** METHOD: sqlite3_blob -** -** ^This function is used to move an existing blob handle so that it points -** to a different row of the same database table. ^The new row is identified -** by the rowid value passed as the second argument. Only the row can be -** changed. ^The database, table and column on which the blob handle is open -** remain the same. Moving an existing blob handle to a new row can be -** faster than closing the existing handle and opening a new one. -** -** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - -** it must exist and there must be either a blob or text value stored in -** the nominated column.)^ ^If the new row is not present in the table, or if -** it does not contain a blob or text value, or if another error occurs, an -** SQLite error code is returned and the blob handle is considered aborted. -** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or -** [sqlite3_blob_reopen()] on an aborted blob handle immediately return -** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle -** always returns zero. -** -** ^This function sets the database handle error code and message. -*/ -SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); - -/* -** CAPI3REF: Close A BLOB Handle -** DESTRUCTOR: sqlite3_blob -** -** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed -** unconditionally. Even if this routine returns an error code, the -** handle is still closed.)^ -** -** ^If the blob handle being closed was opened for read-write access, and if -** the database is in auto-commit mode and there are no other open read-write -** blob handles or active write statements, the current transaction is -** committed. ^If an error occurs while committing the transaction, an error -** code is returned and the transaction rolled back. -** -** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behaviour. ^Calling this routine -** with a null pointer (such as would be returned by a failed call to -** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function -** is passed a valid open blob handle, the values returned by the -** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. -*/ -SQLITE_API int sqlite3_blob_close(sqlite3_blob *); - -/* -** CAPI3REF: Return The Size Of An Open BLOB -** METHOD: sqlite3_blob -** -** ^Returns the size in bytes of the BLOB accessible via the -** successfully opened [BLOB handle] in its only argument. ^The -** incremental blob I/O routines can only read or overwriting existing -** blob content; they cannot change the size of a blob. -** -** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [sqlite3_blob_open()] and which has not -** been closed by [sqlite3_blob_close()]. Passing any other pointer in -** to this routine results in undefined and probably undesirable behavior. -*/ -SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); - -/* -** CAPI3REF: Read Data From A BLOB Incrementally -** METHOD: sqlite3_blob -** -** ^(This function is used to read data from an open [BLOB handle] into a -** caller-supplied buffer. N bytes of data are copied into buffer Z -** from the open BLOB, starting at offset iOffset.)^ -** -** ^If offset iOffset is less than N bytes from the end of the BLOB, -** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is -** less than zero, [SQLITE_ERROR] is returned and no data is read. -** ^The size of the blob (and hence the maximum value of N+iOffset) -** can be determined using the [sqlite3_blob_bytes()] interface. -** -** ^An attempt to read from an expired [BLOB handle] fails with an -** error code of [SQLITE_ABORT]. -** -** ^(On success, sqlite3_blob_read() returns SQLITE_OK. -** Otherwise, an [error code] or an [extended error code] is returned.)^ -** -** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [sqlite3_blob_open()] and which has not -** been closed by [sqlite3_blob_close()]. Passing any other pointer in -** to this routine results in undefined and probably undesirable behavior. -** -** See also: [sqlite3_blob_write()]. -*/ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); - -/* -** CAPI3REF: Write Data Into A BLOB Incrementally -** METHOD: sqlite3_blob -** -** ^(This function is used to write data into an open [BLOB handle] from a -** caller-supplied buffer. N bytes of data are copied from the buffer Z -** into the open BLOB, starting at offset iOffset.)^ -** -** ^(On success, sqlite3_blob_write() returns SQLITE_OK. -** Otherwise, an [error code] or an [extended error code] is returned.)^ -** ^Unless SQLITE_MISUSE is returned, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. -** -** ^If the [BLOB handle] passed as the first argument was not opened for -** writing (the flags parameter to [sqlite3_blob_open()] was zero), -** this function returns [SQLITE_READONLY]. -** -** This function may only modify the contents of the BLOB; it is -** not possible to increase the size of a BLOB using this API. -** ^If offset iOffset is less than N bytes from the end of the BLOB, -** [SQLITE_ERROR] is returned and no data is written. The size of the -** BLOB (and hence the maximum value of N+iOffset) can be determined -** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less -** than zero [SQLITE_ERROR] is returned and no data is written. -** -** ^An attempt to write to an expired [BLOB handle] fails with an -** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred -** before the [BLOB handle] expired are not rolled back by the -** expiration of the handle, though of course those changes might -** have been overwritten by the statement that expired the BLOB handle -** or by other independent statements. -** -** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [sqlite3_blob_open()] and which has not -** been closed by [sqlite3_blob_close()]. Passing any other pointer in -** to this routine results in undefined and probably undesirable behavior. -** -** See also: [sqlite3_blob_read()]. -*/ -SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); - -/* -** CAPI3REF: Virtual File System Objects -** -** A virtual filesystem (VFS) is an [sqlite3_vfs] object -** that SQLite uses to interact -** with the underlying operating system. Most SQLite builds come with a -** single default VFS that is appropriate for the host computer. -** New VFSes can be registered and existing VFSes can be unregistered. -** The following interfaces are provided. -** -** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. -** ^Names are case sensitive. -** ^Names are zero-terminated UTF-8 strings. -** ^If there is no match, a NULL pointer is returned. -** ^If zVfsName is NULL then the default VFS is returned. -** -** ^New VFSes are registered with sqlite3_vfs_register(). -** ^Each new VFS becomes the default VFS if the makeDflt flag is set. -** ^The same VFS can be registered multiple times without injury. -** ^To make an existing VFS into the default VFS, register it again -** with the makeDflt flag set. If two different VFSes with the -** same name are registered, the behavior is undefined. If a -** VFS is registered with a name that is NULL or an empty string, -** then the behavior is undefined. -** -** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. -** ^(If the default VFS is unregistered, another VFS is chosen as -** the default. The choice for the new VFS is arbitrary.)^ -*/ -SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); -SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); -SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); - -/* -** CAPI3REF: Mutexes -** -** The SQLite core uses these routines for thread -** synchronization. Though they are intended for internal -** use by SQLite, code that links against SQLite is -** permitted to use any of these routines. -** -** The SQLite source code contains multiple implementations -** of these mutex routines. An appropriate implementation -** is selected automatically at compile-time. The following -** implementations are available in the SQLite core: -** -**
    -**
  • SQLITE_MUTEX_PTHREADS -**
  • SQLITE_MUTEX_W32 -**
  • SQLITE_MUTEX_NOOP -**
-** -** The SQLITE_MUTEX_NOOP implementation is a set of routines -** that does no real locking and is appropriate for use in -** a single-threaded application. The SQLITE_MUTEX_PTHREADS and -** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix -** and Windows. -** -** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor -** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex -** implementation is included with the library. In this case the -** application must supply a custom mutex implementation using the -** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function -** before calling sqlite3_initialize() or any other public sqlite3_ -** function that calls sqlite3_initialize(). -** -** ^The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() -** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to sqlite3_mutex_alloc() must one of these -** integer constants: -** -**
    -**
  • SQLITE_MUTEX_FAST -**
  • SQLITE_MUTEX_RECURSIVE -**
  • SQLITE_MUTEX_STATIC_MASTER -**
  • SQLITE_MUTEX_STATIC_MEM -**
  • SQLITE_MUTEX_STATIC_OPEN -**
  • SQLITE_MUTEX_STATIC_PRNG -**
  • SQLITE_MUTEX_STATIC_LRU -**
  • SQLITE_MUTEX_STATIC_PMEM -**
  • SQLITE_MUTEX_STATIC_APP1 -**
  • SQLITE_MUTEX_STATIC_APP2 -**
  • SQLITE_MUTEX_STATIC_APP3 -**
  • SQLITE_MUTEX_STATIC_VFS1 -**
  • SQLITE_MUTEX_STATIC_VFS2 -**
  • SQLITE_MUTEX_STATIC_VFS3 -**
-** -** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) -** cause sqlite3_mutex_alloc() to create -** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other -** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return -** a pointer to a static preexisting mutex. ^Nine static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. ^For the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -** -** ^The sqlite3_mutex_free() routine deallocates a previously -** allocated dynamic mutex. Attempting to deallocate a static -** mutex results in undefined behavior. -** -** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. ^If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] -** upon successful entry. ^(Mutexes created using -** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. -** In such cases, the -** mutex must be exited an equal number of times before another thread -** can enter.)^ If the same thread tries to enter any mutex other -** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. -** -** ^(Some systems (for example, Windows 95) do not support the operation -** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ -** -** ^The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered by the -** calling thread or is not currently allocated. -** -** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or -** sqlite3_mutex_leave() is a NULL pointer, then all three routines -** behave as no-ops. -** -** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. -*/ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); -SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); -SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); - -/* -** CAPI3REF: Mutex Methods Object -** -** An instance of this structure defines the low-level routines -** used to allocate and use mutexes. -** -** Usually, the default mutex implementations provided by SQLite are -** sufficient, however the application has the option of substituting a custom -** implementation for specialized deployments or systems for which SQLite -** does not provide a suitable implementation. In this case, the application -** creates and populates an instance of this structure to pass -** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. -** Additionally, an instance of this structure can be used as an -** output variable when querying the system for the current mutex -** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. -** -** ^The xMutexInit method defined by this structure is invoked as -** part of system initialization by the sqlite3_initialize() function. -** ^The xMutexInit routine is called by SQLite exactly once for each -** effective call to [sqlite3_initialize()]. -** -** ^The xMutexEnd method defined by this structure is invoked as -** part of system shutdown by the sqlite3_shutdown() function. The -** implementation of this method is expected to release all outstanding -** resources obtained by the mutex methods implementation, especially -** those obtained by the xMutexInit method. ^The xMutexEnd() -** interface is invoked exactly once for each call to [sqlite3_shutdown()]. -** -** ^(The remaining seven methods defined by this structure (xMutexAlloc, -** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and -** xMutexNotheld) implement the following interfaces (respectively): -** -**
    -**
  • [sqlite3_mutex_alloc()]
  • -**
  • [sqlite3_mutex_free()]
  • -**
  • [sqlite3_mutex_enter()]
  • -**
  • [sqlite3_mutex_try()]
  • -**
  • [sqlite3_mutex_leave()]
  • -**
  • [sqlite3_mutex_held()]
  • -**
  • [sqlite3_mutex_notheld()]
  • -**
)^ -** -** The only difference is that the public sqlite3_XXX functions enumerated -** above silently ignore any invocations that pass a NULL pointer instead -** of a valid mutex handle. The implementations of the methods defined -** by this structure are not required to handle this case, the results -** of passing a NULL pointer instead of a valid mutex handle are undefined -** (i.e. it is acceptable to provide an implementation that segfaults if -** it is passed a NULL pointer). -** -** The xMutexInit() method must be threadsafe. It must be harmless to -** invoke xMutexInit() multiple times within the same process and without -** intervening calls to xMutexEnd(). Second and subsequent calls to -** xMutexInit() must be no-ops. -** -** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] -** and its associates). Similarly, xMutexAlloc() must not use SQLite memory -** allocation for a static mutex. ^However xMutexAlloc() may use SQLite -** memory allocation for a fast or recursive mutex. -** -** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is -** called, but only if the prior call to xMutexInit returned SQLITE_OK. -** If xMutexInit fails in any way, it is expected to clean up after itself -** prior to returning. -*/ -typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; -struct sqlite3_mutex_methods { - int (*xMutexInit)(void); - int (*xMutexEnd)(void); - sqlite3_mutex *(*xMutexAlloc)(int); - void (*xMutexFree)(sqlite3_mutex *); - void (*xMutexEnter)(sqlite3_mutex *); - int (*xMutexTry)(sqlite3_mutex *); - void (*xMutexLeave)(sqlite3_mutex *); - int (*xMutexHeld)(sqlite3_mutex *); - int (*xMutexNotheld)(sqlite3_mutex *); -}; - -/* -** CAPI3REF: Mutex Verification Routines -** -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines -** are intended for use inside assert() statements. The SQLite core -** never uses these routines except inside an assert() and applications -** are advised to follow the lead of the core. The SQLite core only -** provides implementations for these routines when it is compiled -** with the SQLITE_DEBUG flag. External mutex implementations -** are only required to provide these routines if SQLITE_DEBUG is -** defined and if NDEBUG is not defined. -** -** These routines should return true if the mutex in their argument -** is held or not held, respectively, by the calling thread. -** -** The implementation is not required to provide versions of these -** routines that actually work. If the implementation does not provide working -** versions of these routines, it should at least provide stubs that always -** return true so that one does not get spurious assertion failures. -** -** If the argument to sqlite3_mutex_held() is a NULL pointer then -** the routine should return 1. This seems counter-intuitive since -** clearly the mutex cannot be held if it does not exist. But -** the reason the mutex does not exist is because the build is not -** using mutexes. And we do not want the assert() containing the -** call to sqlite3_mutex_held() to fail, so a non-zero return is -** the appropriate thing to do. The sqlite3_mutex_notheld() -** interface should also return 1 when given a NULL pointer. -*/ -#ifndef NDEBUG -SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); -SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); -#endif - -/* -** CAPI3REF: Mutex Types -** -** The [sqlite3_mutex_alloc()] interface takes a single argument -** which is one of these integer constants. -** -** The set of static mutexes may change from one SQLite release to the -** next. Applications that override the built-in mutex logic must be -** prepared to accommodate additional static mutexes. -*/ -#define SQLITE_MUTEX_FAST 0 -#define SQLITE_MUTEX_RECURSIVE 1 -#define SQLITE_MUTEX_STATIC_MASTER 2 -#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ -#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ -#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ -#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */ -#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ -#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ -#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ -#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ -#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ -#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ -#define SQLITE_MUTEX_STATIC_VFS1 11 /* For use by built-in VFS */ -#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */ -#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */ - -/* -** CAPI3REF: Retrieve the mutex for a database connection -** METHOD: sqlite3 -** -** ^This interface returns a pointer the [sqlite3_mutex] object that -** serializes access to the [database connection] given in the argument -** when the [threading mode] is Serialized. -** ^If the [threading mode] is Single-thread or Multi-thread then this -** routine returns a NULL pointer. -*/ -SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); - -/* -** CAPI3REF: Low-Level Control Of Database Files -** METHOD: sqlite3 -** -** ^The [sqlite3_file_control()] interface makes a direct call to the -** xFileControl method for the [sqlite3_io_methods] object associated -** with a particular database identified by the second argument. ^The -** name of the database is "main" for the main database or "temp" for the -** TEMP database, or the name that appears after the AS keyword for -** databases that are added using the [ATTACH] SQL command. -** ^A NULL pointer can be used in place of "main" to refer to the -** main database file. -** ^The third and fourth parameters to this routine -** are passed directly through to the second and third parameters of -** the xFileControl method. ^The return value of the xFileControl -** method becomes the return value of this routine. -** -** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes -** a pointer to the underlying [sqlite3_file] object to be written into -** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER -** case is a short-circuit path which does not actually invoke the -** underlying sqlite3_io_methods.xFileControl method. -** -** ^If the second parameter (zDbName) does not match the name of any -** open database file, then SQLITE_ERROR is returned. ^This error -** code is not remembered and will not be recalled by [sqlite3_errcode()] -** or [sqlite3_errmsg()]. The underlying xFileControl method might -** also return SQLITE_ERROR. There is no way to distinguish between -** an incorrect zDbName and an SQLITE_ERROR return from the underlying -** xFileControl method. -** -** See also: [SQLITE_FCNTL_LOCKSTATE] -*/ -SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); - -/* -** CAPI3REF: Testing Interface -** -** ^The sqlite3_test_control() interface is used to read out internal -** state of SQLite and to inject faults into SQLite for testing -** purposes. ^The first parameter is an operation code that determines -** the number, meaning, and operation of all subsequent parameters. -** -** This interface is not for use by applications. It exists solely -** for verifying the correct operation of the SQLite library. Depending -** on how the SQLite library is compiled, this interface might not exist. -** -** The details of the operation codes, their meanings, the parameters -** they take, and what they do are all subject to change without notice. -** Unlike most of the SQLite API, this function is not guaranteed to -** operate consistently from one release to the next. -*/ -SQLITE_API int sqlite3_test_control(int op, ...); - -/* -** CAPI3REF: Testing Interface Operation Codes -** -** These constants are the valid operation code parameters used -** as the first argument to [sqlite3_test_control()]. -** -** These parameters and their meanings are subject to change -** without notice. These values are for testing purposes only. -** Applications should not use any of these parameters or the -** [sqlite3_test_control()] interface. -*/ -#define SQLITE_TESTCTRL_FIRST 5 -#define SQLITE_TESTCTRL_PRNG_SAVE 5 -#define SQLITE_TESTCTRL_PRNG_RESTORE 6 -#define SQLITE_TESTCTRL_PRNG_RESET 7 -#define SQLITE_TESTCTRL_BITVEC_TEST 8 -#define SQLITE_TESTCTRL_FAULT_INSTALL 9 -#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 -#define SQLITE_TESTCTRL_PENDING_BYTE 11 -#define SQLITE_TESTCTRL_ASSERT 12 -#define SQLITE_TESTCTRL_ALWAYS 13 -#define SQLITE_TESTCTRL_RESERVE 14 -#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 -#define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 -#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 -#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ -#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 -#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 -#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 -#define SQLITE_TESTCTRL_BYTEORDER 22 -#define SQLITE_TESTCTRL_ISINIT 23 -#define SQLITE_TESTCTRL_SORTER_MMAP 24 -#define SQLITE_TESTCTRL_IMPOSTER 25 -#define SQLITE_TESTCTRL_LAST 25 - -/* -** CAPI3REF: SQLite Runtime Status -** -** ^These interfaces are used to retrieve runtime status information -** about the performance of SQLite, and optionally to reset various -** highwater marks. ^The first argument is an integer code for -** the specific parameter to measure. ^(Recognized integer codes -** are of the form [status parameters | SQLITE_STATUS_...].)^ -** ^The current value of the parameter is returned into *pCurrent. -** ^The highest recorded value is returned in *pHighwater. ^If the -** resetFlag is true, then the highest record value is reset after -** *pHighwater is written. ^(Some parameters do not record the highest -** value. For those parameters -** nothing is written into *pHighwater and the resetFlag is ignored.)^ -** ^(Other parameters record only the highwater mark and not the current -** value. For these latter parameters nothing is written into *pCurrent.)^ -** -** ^The sqlite3_status() and sqlite3_status64() routines return -** SQLITE_OK on success and a non-zero [error code] on failure. -** -** If either the current value or the highwater mark is too large to -** be represented by a 32-bit integer, then the values returned by -** sqlite3_status() are undefined. -** -** See also: [sqlite3_db_status()] -*/ -SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); -SQLITE_API int sqlite3_status64( - int op, - sqlite3_int64 *pCurrent, - sqlite3_int64 *pHighwater, - int resetFlag -); - - -/* -** CAPI3REF: Status Parameters -** KEYWORDS: {status parameters} -** -** These integer constants designate various run-time status parameters -** that can be returned by [sqlite3_status()]. -** -**
-** [[SQLITE_STATUS_MEMORY_USED]] ^(
SQLITE_STATUS_MEMORY_USED
-**
This parameter is the current amount of memory checked out -** using [sqlite3_malloc()], either directly or indirectly. The -** figure includes calls made to [sqlite3_malloc()] by the application -** and internal memory usage by the SQLite library. Scratch memory -** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache -** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in -** this parameter. The amount returned is the sum of the allocation -** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ -** -** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
SQLITE_STATUS_MALLOC_SIZE
-**
This parameter records the largest memory allocation request -** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their -** internal equivalents). Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. -** The value written into the *pCurrent parameter is undefined.
)^ -** -** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
SQLITE_STATUS_MALLOC_COUNT
-**
This parameter records the number of separate memory allocations -** currently checked out.
)^ -** -** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
SQLITE_STATUS_PAGECACHE_USED
-**
This parameter returns the number of pages used out of the -** [pagecache memory allocator] that was configured using -** [SQLITE_CONFIG_PAGECACHE]. The -** value returned is in pages, not in bytes.
)^ -** -** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] -** ^(
SQLITE_STATUS_PAGECACHE_OVERFLOW
-**
This parameter returns the number of bytes of page cache -** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] -** buffer and where forced to overflow to [sqlite3_malloc()]. The -** returned value includes allocations that overflowed because they -** where too large (they were larger than the "sz" parameter to -** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because -** no space was left in the page cache.
)^ -** -** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
SQLITE_STATUS_PAGECACHE_SIZE
-**
This parameter records the largest memory allocation request -** handed to [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. -** The value written into the *pCurrent parameter is undefined.
)^ -** -** [[SQLITE_STATUS_SCRATCH_USED]] ^(
SQLITE_STATUS_SCRATCH_USED
-**
This parameter returns the number of allocations used out of the -** [scratch memory allocator] configured using -** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not -** in bytes. Since a single thread may only have one scratch allocation -** outstanding at time, this parameter also reports the number of threads -** using scratch memory at the same time.
)^ -** -** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
-**
This parameter returns the number of bytes of scratch memory -** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] -** buffer and where forced to overflow to [sqlite3_malloc()]. The values -** returned include overflows because the requested allocation was too -** larger (that is, because the requested allocation was larger than the -** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer -** slots were available. -**
)^ -** -** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
SQLITE_STATUS_SCRATCH_SIZE
-**
This parameter records the largest memory allocation request -** handed to [scratch memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. -** The value written into the *pCurrent parameter is undefined.
)^ -** -** [[SQLITE_STATUS_PARSER_STACK]] ^(
SQLITE_STATUS_PARSER_STACK
-**
The *pHighwater parameter records the deepest parser stack. -** The *pCurrent value is undefined. The *pHighwater value is only -** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
)^ -**
-** -** New status parameters may be added from time to time. -*/ -#define SQLITE_STATUS_MEMORY_USED 0 -#define SQLITE_STATUS_PAGECACHE_USED 1 -#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 -#define SQLITE_STATUS_SCRATCH_USED 3 -#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 -#define SQLITE_STATUS_MALLOC_SIZE 5 -#define SQLITE_STATUS_PARSER_STACK 6 -#define SQLITE_STATUS_PAGECACHE_SIZE 7 -#define SQLITE_STATUS_SCRATCH_SIZE 8 -#define SQLITE_STATUS_MALLOC_COUNT 9 - -/* -** CAPI3REF: Database Connection Status -** METHOD: sqlite3 -** -** ^This interface is used to retrieve runtime status information -** about a single [database connection]. ^The first argument is the -** database connection object to be interrogated. ^The second argument -** is an integer constant, taken from the set of -** [SQLITE_DBSTATUS options], that -** determines the parameter to interrogate. The set of -** [SQLITE_DBSTATUS options] is likely -** to grow in future releases of SQLite. -** -** ^The current value of the requested parameter is written into *pCur -** and the highest instantaneous value is written into *pHiwtr. ^If -** the resetFlg is true, then the highest instantaneous value is -** reset back down to the current value. -** -** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a -** non-zero [error code] on failure. -** -** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. -*/ -SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); - -/* -** CAPI3REF: Status Parameters for database connections -** KEYWORDS: {SQLITE_DBSTATUS options} -** -** These constants are the available integer "verbs" that can be passed as -** the second argument to the [sqlite3_db_status()] interface. -** -** New verbs may be added in future releases of SQLite. Existing verbs -** might be discontinued. Applications should check the return code from -** [sqlite3_db_status()] to make sure that the call worked. -** The [sqlite3_db_status()] interface will return a non-zero error code -** if a discontinued or unsupported verb is invoked. -** -**
-** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
SQLITE_DBSTATUS_LOOKASIDE_USED
-**
This parameter returns the number of lookaside memory slots currently -** checked out.
)^ -** -** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
SQLITE_DBSTATUS_LOOKASIDE_HIT
-**
This parameter returns the number malloc attempts that were -** satisfied using lookaside memory. Only the high-water value is meaningful; -** the current value is always zero.)^ -** -** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] -** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
-**
This parameter returns the number malloc attempts that might have -** been satisfied using lookaside memory but failed due to the amount of -** memory requested being larger than the lookaside slot size. -** Only the high-water value is meaningful; -** the current value is always zero.)^ -** -** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] -** ^(
SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
-**
This parameter returns the number malloc attempts that might have -** been satisfied using lookaside memory but failed due to all lookaside -** memory already being in use. -** Only the high-water value is meaningful; -** the current value is always zero.)^ -** -** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
SQLITE_DBSTATUS_CACHE_USED
-**
This parameter returns the approximate number of bytes of heap -** memory used by all pager caches associated with the database connection.)^ -** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. -** -** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] -** ^(
SQLITE_DBSTATUS_CACHE_USED_SHARED
-**
This parameter is similar to DBSTATUS_CACHE_USED, except that if a -** pager cache is shared between two or more connections the bytes of heap -** memory used by that pager cache is divided evenly between the attached -** connections.)^ In other words, if none of the pager caches associated -** with the database connection are shared, this request returns the same -** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are -** shared, the value returned by this call will be smaller than that returned -** by DBSTATUS_CACHE_USED. ^The highwater mark associated with -** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. -** -** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
SQLITE_DBSTATUS_SCHEMA_USED
-**
This parameter returns the approximate number of bytes of heap -** memory used to store the schema for all databases associated -** with the connection - main, temp, and any [ATTACH]-ed databases.)^ -** ^The full amount of memory used by the schemas is reported, even if the -** schema memory is shared with other database connections due to -** [shared cache mode] being enabled. -** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. -** -** [[SQLITE_DBSTATUS_STMT_USED]] ^(
SQLITE_DBSTATUS_STMT_USED
-**
This parameter returns the approximate number of bytes of heap -** and lookaside memory used by all prepared statements associated with -** the database connection.)^ -** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. -**
-** -** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
-**
This parameter returns the number of pager cache hits that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT -** is always 0. -**
-** -** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
-**
This parameter returns the number of pager cache misses that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS -** is always 0. -**
-** -** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(
SQLITE_DBSTATUS_CACHE_WRITE
-**
This parameter returns the number of dirty cache entries that have -** been written to disk. Specifically, the number of pages written to the -** wal file in wal mode databases, or the number of pages written to the -** database file in rollback mode databases. Any pages written as part of -** transaction rollback or database recovery operations are not included. -** If an IO or other error occurs while writing a page to disk, the effect -** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The -** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. -**
-** -** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
SQLITE_DBSTATUS_DEFERRED_FKS
-**
This parameter returns zero for the current value if and only if -** all foreign key constraints (deferred or immediate) have been -** resolved.)^ ^The highwater mark is always 0. -**
-**
-*/ -#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 -#define SQLITE_DBSTATUS_CACHE_USED 1 -#define SQLITE_DBSTATUS_SCHEMA_USED 2 -#define SQLITE_DBSTATUS_STMT_USED 3 -#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 -#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 -#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 -#define SQLITE_DBSTATUS_CACHE_HIT 7 -#define SQLITE_DBSTATUS_CACHE_MISS 8 -#define SQLITE_DBSTATUS_CACHE_WRITE 9 -#define SQLITE_DBSTATUS_DEFERRED_FKS 10 -#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 -#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */ - - -/* -** CAPI3REF: Prepared Statement Status -** METHOD: sqlite3_stmt -** -** ^(Each prepared statement maintains various -** [SQLITE_STMTSTATUS counters] that measure the number -** of times it has performed specific operations.)^ These counters can -** be used to monitor the performance characteristics of the prepared -** statements. For example, if the number of table steps greatly exceeds -** the number of table searches or result rows, that would tend to indicate -** that the prepared statement is using a full table scan rather than -** an index. -** -** ^(This interface is used to retrieve and reset counter values from -** a [prepared statement]. The first argument is the prepared statement -** object to be interrogated. The second argument -** is an integer code for a specific [SQLITE_STMTSTATUS counter] -** to be interrogated.)^ -** ^The current value of the requested counter is returned. -** ^If the resetFlg is true, then the counter is reset to zero after this -** interface call returns. -** -** See also: [sqlite3_status()] and [sqlite3_db_status()]. -*/ -SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - -/* -** CAPI3REF: Status Parameters for prepared statements -** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} -** -** These preprocessor macros define integer codes that name counter -** values associated with the [sqlite3_stmt_status()] interface. -** The meanings of the various counters are as follows: -** -**
-** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
SQLITE_STMTSTATUS_FULLSCAN_STEP
-**
^This is the number of times that SQLite has stepped forward in -** a table as part of a full table scan. Large numbers for this counter -** may indicate opportunities for performance improvement through -** careful use of indices.
-** -** [[SQLITE_STMTSTATUS_SORT]]
SQLITE_STMTSTATUS_SORT
-**
^This is the number of sort operations that have occurred. -** A non-zero value in this counter may indicate an opportunity to -** improvement performance through careful use of indices.
-** -** [[SQLITE_STMTSTATUS_AUTOINDEX]]
SQLITE_STMTSTATUS_AUTOINDEX
-**
^This is the number of rows inserted into transient indices that -** were created automatically in order to help joins run faster. -** A non-zero value in this counter may indicate an opportunity to -** improvement performance by adding permanent indices that do not -** need to be reinitialized each time the statement is run.
-** -** [[SQLITE_STMTSTATUS_VM_STEP]]
SQLITE_STMTSTATUS_VM_STEP
-**
^This is the number of virtual machine operations executed -** by the prepared statement if that number is less than or equal -** to 2147483647. The number of virtual machine operations can be -** used as a proxy for the total work done by the prepared statement. -** If the number of virtual machine operations exceeds 2147483647 -** then the value returned by this statement status code is undefined. -**
-**
-*/ -#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 -#define SQLITE_STMTSTATUS_SORT 2 -#define SQLITE_STMTSTATUS_AUTOINDEX 3 -#define SQLITE_STMTSTATUS_VM_STEP 4 - -/* -** CAPI3REF: Custom Page Cache Object -** -** The sqlite3_pcache type is opaque. It is implemented by -** the pluggable module. The SQLite core has no knowledge of -** its size or internal structure and never deals with the -** sqlite3_pcache object except by holding and passing pointers -** to the object. -** -** See [sqlite3_pcache_methods2] for additional information. -*/ -typedef struct sqlite3_pcache sqlite3_pcache; - -/* -** CAPI3REF: Custom Page Cache Object -** -** The sqlite3_pcache_page object represents a single page in the -** page cache. The page cache will allocate instances of this -** object. Various methods of the page cache use pointers to instances -** of this object as parameters or as their return value. -** -** See [sqlite3_pcache_methods2] for additional information. -*/ -typedef struct sqlite3_pcache_page sqlite3_pcache_page; -struct sqlite3_pcache_page { - void *pBuf; /* The content of the page */ - void *pExtra; /* Extra information associated with the page */ -}; - -/* -** CAPI3REF: Application Defined Page Cache. -** KEYWORDS: {page cache} -** -** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can -** register an alternative page cache implementation by passing in an -** instance of the sqlite3_pcache_methods2 structure.)^ -** In many applications, most of the heap memory allocated by -** SQLite is used for the page cache. -** By implementing a -** custom page cache using this API, an application can better control -** the amount of memory consumed by SQLite, the way in which -** that memory is allocated and released, and the policies used to -** determine exactly which parts of a database file are cached and for -** how long. -** -** The alternative page cache mechanism is an -** extreme measure that is only needed by the most demanding applications. -** The built-in page cache is recommended for most uses. -** -** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an -** internal buffer by SQLite within the call to [sqlite3_config]. Hence -** the application may discard the parameter after the call to -** [sqlite3_config()] returns.)^ -** -** [[the xInit() page cache method]] -** ^(The xInit() method is called once for each effective -** call to [sqlite3_initialize()])^ -** (usually only once during the lifetime of the process). ^(The xInit() -** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ -** The intent of the xInit() method is to set up global data structures -** required by the custom page cache implementation. -** ^(If the xInit() method is NULL, then the -** built-in default page cache is used instead of the application defined -** page cache.)^ -** -** [[the xShutdown() page cache method]] -** ^The xShutdown() method is called by [sqlite3_shutdown()]. -** It can be used to clean up -** any outstanding resources before process shutdown, if required. -** ^The xShutdown() method may be NULL. -** -** ^SQLite automatically serializes calls to the xInit method, -** so the xInit method need not be threadsafe. ^The -** xShutdown method is only called from [sqlite3_shutdown()] so it does -** not need to be threadsafe either. All other methods must be threadsafe -** in multithreaded applications. -** -** ^SQLite will never invoke xInit() more than once without an intervening -** call to xShutdown(). -** -** [[the xCreate() page cache methods]] -** ^SQLite invokes the xCreate() method to construct a new cache instance. -** SQLite will typically create one cache instance for each open database file, -** though this is not guaranteed. ^The -** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. ^szPage will always a power of two. ^The -** second parameter szExtra is a number of bytes of extra storage -** associated with each page cache entry. ^The szExtra parameter will -** a number less than 250. SQLite will use the -** extra szExtra bytes on each page to store metadata about the underlying -** database page on disk. The value passed into szExtra depends -** on the SQLite version, the target platform, and how SQLite was compiled. -** ^The third argument to xCreate(), bPurgeable, is true if the cache being -** created will be used to cache database pages of a file stored on disk, or -** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based with the value of bPurgeable; -** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will -** never invoke xUnpin() except to deliberately delete a page. -** ^In other words, calls to xUnpin() on a cache with bPurgeable set to -** false will always have the "discard" flag set to true. -** ^Hence, a cache created with bPurgeable false will -** never contain any unpinned pages. -** -** [[the xCachesize() page cache method]] -** ^(The xCachesize() method may be called at any time by SQLite to set the -** suggested maximum cache-size (number of pages stored by) the cache -** instance passed as the first argument. This is the value configured using -** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable -** parameter, the implementation is not required to do anything with this -** value; it is advisory only. -** -** [[the xPagecount() page cache methods]] -** The xPagecount() method must return the number of pages currently -** stored in the cache, both pinned and unpinned. -** -** [[the xFetch() page cache methods]] -** The xFetch() method locates a page in the cache and returns a pointer to -** an sqlite3_pcache_page object associated with that page, or a NULL pointer. -** The pBuf element of the returned sqlite3_pcache_page object will be a -** pointer to a buffer of szPage bytes used to store the content of a -** single database page. The pExtra element of sqlite3_pcache_page will be -** a pointer to the szExtra bytes of extra storage that SQLite has requested -** for each entry in the page cache. -** -** The page to be fetched is determined by the key. ^The minimum key value -** is 1. After it has been retrieved using xFetch, the page is considered -** to be "pinned". -** -** If the requested page is already in the page cache, then the page cache -** implementation must return a pointer to the page buffer with its content -** intact. If the requested page is not already in the cache, then the -** cache implementation should use the value of the createFlag -** parameter to help it determined what action to take: -** -** -**
createFlag Behavior when page is not already in cache -**
0 Do not allocate a new page. Return NULL. -**
1 Allocate a new page if it easy and convenient to do so. -** Otherwise return NULL. -**
2 Make every effort to allocate a new page. Only return -** NULL if allocating a new page is effectively impossible. -**
-** -** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite -** will only use a createFlag of 2 after a prior call with a createFlag of 1 -** failed.)^ In between the to xFetch() calls, SQLite may -** attempt to unpin one or more cache pages by spilling the content of -** pinned pages to disk and synching the operating system disk cache. -** -** [[the xUnpin() page cache method]] -** ^xUnpin() is called by SQLite with a pointer to a currently pinned page -** as its second argument. If the third parameter, discard, is non-zero, -** then the page must be evicted from the cache. -** ^If the discard parameter is -** zero, then the page may be discarded or retained at the discretion of -** page cache implementation. ^The page cache implementation -** may choose to evict unpinned pages at any time. -** -** The cache must not perform any reference counting. A single -** call to xUnpin() unpins the page regardless of the number of prior calls -** to xFetch(). -** -** [[the xRekey() page cache methods]] -** The xRekey() method is used to change the key value associated with the -** page passed as the second argument. If the cache -** previously contains an entry associated with newKey, it must be -** discarded. ^Any prior cache entry associated with newKey is guaranteed not -** to be pinned. -** -** When SQLite calls the xTruncate() method, the cache must discard all -** existing cache entries with page numbers (keys) greater than or equal -** to the value of the iLimit parameter passed to xTruncate(). If any -** of these pages are pinned, they are implicitly unpinned, meaning that -** they can be safely discarded. -** -** [[the xDestroy() page cache method]] -** ^The xDestroy() method is used to delete a cache allocated by xCreate(). -** All resources associated with the specified cache should be freed. ^After -** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] -** handle invalid, and will not use it with any other sqlite3_pcache_methods2 -** functions. -** -** [[the xShrink() page cache method]] -** ^SQLite invokes the xShrink() method when it wants the page cache to -** free up as much of heap memory as possible. The page cache implementation -** is not obligated to free any memory, but well-behaved implementations should -** do their best. -*/ -typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; -struct sqlite3_pcache_methods2 { - int iVersion; - void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); - void (*xCachesize)(sqlite3_pcache*, int nCachesize); - int (*xPagecount)(sqlite3_pcache*); - sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); - void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, - unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlite3_pcache*); - void (*xShrink)(sqlite3_pcache*); -}; - -/* -** This is the obsolete pcache_methods object that has now been replaced -** by sqlite3_pcache_methods2. This object is not used by SQLite. It is -** retained in the header file for backwards compatibility only. -*/ -typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; -struct sqlite3_pcache_methods { - void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); - void (*xCachesize)(sqlite3_pcache*, int nCachesize); - int (*xPagecount)(sqlite3_pcache*); - void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlite3_pcache*, void*, int discard); - void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlite3_pcache*); -}; - - -/* -** CAPI3REF: Online Backup Object -** -** The sqlite3_backup object records state information about an ongoing -** online backup operation. ^The sqlite3_backup object is created by -** a call to [sqlite3_backup_init()] and is destroyed by a call to -** [sqlite3_backup_finish()]. -** -** See Also: [Using the SQLite Online Backup API] -*/ -typedef struct sqlite3_backup sqlite3_backup; - -/* -** CAPI3REF: Online Backup API. -** -** The backup API copies the content of one database into another. -** It is useful either for creating backups of databases or -** for copying in-memory databases to or from persistent files. -** -** See Also: [Using the SQLite Online Backup API] -** -** ^SQLite holds a write transaction open on the destination database file -** for the duration of the backup operation. -** ^The source database is read-locked only while it is being read; -** it is not locked continuously for the entire backup operation. -** ^Thus, the backup may be performed on a live source database without -** preventing other database connections from -** reading or writing to the source database while the backup is underway. -** -** ^(To perform a backup operation: -**
    -**
  1. sqlite3_backup_init() is called once to initialize the -** backup, -**
  2. sqlite3_backup_step() is called one or more times to transfer -** the data between the two databases, and finally -**
  3. sqlite3_backup_finish() is called to release all resources -** associated with the backup operation. -**
)^ -** There should be exactly one call to sqlite3_backup_finish() for each -** successful call to sqlite3_backup_init(). -** -** [[sqlite3_backup_init()]] sqlite3_backup_init() -** -** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the -** [database connection] associated with the destination database -** and the database name, respectively. -** ^The database name is "main" for the main database, "temp" for the -** temporary database, or the name specified after the AS keyword in -** an [ATTACH] statement for an attached database. -** ^The S and M arguments passed to -** sqlite3_backup_init(D,N,S,M) identify the [database connection] -** and database name of the source database, respectively. -** ^The source and destination [database connections] (parameters S and D) -** must be different or else sqlite3_backup_init(D,N,S,M) will fail with -** an error. -** -** ^A call to sqlite3_backup_init() will fail, returning NULL, if -** there is already a read or read-write transaction open on the -** destination database. -** -** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is -** returned and an error code and error message are stored in the -** destination [database connection] D. -** ^The error code and message for the failed call to sqlite3_backup_init() -** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or -** [sqlite3_errmsg16()] functions. -** ^A successful call to sqlite3_backup_init() returns a pointer to an -** [sqlite3_backup] object. -** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and -** sqlite3_backup_finish() functions to perform the specified backup -** operation. -** -** [[sqlite3_backup_step()]] sqlite3_backup_step() -** -** ^Function sqlite3_backup_step(B,N) will copy up to N pages between -** the source and destination databases specified by [sqlite3_backup] object B. -** ^If N is negative, all remaining source pages are copied. -** ^If sqlite3_backup_step(B,N) successfully copies N pages and there -** are still more pages to be copied, then the function returns [SQLITE_OK]. -** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages -** from source to destination, then it returns [SQLITE_DONE]. -** ^If an error occurs while running sqlite3_backup_step(B,N), -** then an [error code] is returned. ^As well as [SQLITE_OK] and -** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], -** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an -** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. -** -** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if -**
    -**
  1. the destination database was opened read-only, or -**
  2. the destination database is using write-ahead-log journaling -** and the destination and source page sizes differ, or -**
  3. the destination database is an in-memory database and the -** destination and source page sizes differ. -**
)^ -** -** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then -** the [sqlite3_busy_handler | busy-handler function] -** is invoked (if one is specified). ^If the -** busy-handler returns non-zero before the lock is available, then -** [SQLITE_BUSY] is returned to the caller. ^In this case the call to -** sqlite3_backup_step() can be retried later. ^If the source -** [database connection] -** is being used to write to the source database when sqlite3_backup_step() -** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this -** case the call to sqlite3_backup_step() can be retried later on. ^(If -** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or -** [SQLITE_READONLY] is returned, then -** there is no point in retrying the call to sqlite3_backup_step(). These -** errors are considered fatal.)^ The application must accept -** that the backup operation has failed and pass the backup operation handle -** to the sqlite3_backup_finish() to release associated resources. -** -** ^The first call to sqlite3_backup_step() obtains an exclusive lock -** on the destination file. ^The exclusive lock is not released until either -** sqlite3_backup_finish() is called or the backup operation is complete -** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to -** sqlite3_backup_step() obtains a [shared lock] on the source database that -** lasts for the duration of the sqlite3_backup_step() call. -** ^Because the source database is not locked between calls to -** sqlite3_backup_step(), the source database may be modified mid-way -** through the backup process. ^If the source database is modified by an -** external process or via a database connection other than the one being -** used by the backup operation, then the backup will be automatically -** restarted by the next call to sqlite3_backup_step(). ^If the source -** database is modified by the using the same database connection as is used -** by the backup operation, then the backup database is automatically -** updated at the same time. -** -** [[sqlite3_backup_finish()]] sqlite3_backup_finish() -** -** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the -** application wishes to abandon the backup operation, the application -** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). -** ^The sqlite3_backup_finish() interfaces releases all -** resources associated with the [sqlite3_backup] object. -** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any -** active write-transaction on the destination database is rolled back. -** The [sqlite3_backup] object is invalid -** and may not be used following a call to sqlite3_backup_finish(). -** -** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no -** sqlite3_backup_step() errors occurred, regardless or whether or not -** sqlite3_backup_step() completed. -** ^If an out-of-memory condition or IO error occurred during any prior -** sqlite3_backup_step() call on the same [sqlite3_backup] object, then -** sqlite3_backup_finish() returns the corresponding [error code]. -** -** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() -** is not a permanent error and does not affect the return value of -** sqlite3_backup_finish(). -** -** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] -** sqlite3_backup_remaining() and sqlite3_backup_pagecount() -** -** ^The sqlite3_backup_remaining() routine returns the number of pages still -** to be backed up at the conclusion of the most recent sqlite3_backup_step(). -** ^The sqlite3_backup_pagecount() routine returns the total number of pages -** in the source database at the conclusion of the most recent -** sqlite3_backup_step(). -** ^(The values returned by these functions are only updated by -** sqlite3_backup_step(). If the source database is modified in a way that -** changes the size of the source database or the number of pages remaining, -** those changes are not reflected in the output of sqlite3_backup_pagecount() -** and sqlite3_backup_remaining() until after the next -** sqlite3_backup_step().)^ -** -** Concurrent Usage of Database Handles -** -** ^The source [database connection] may be used by the application for other -** purposes while a backup operation is underway or being initialized. -** ^If SQLite is compiled and configured to support threadsafe database -** connections, then the source database connection may be used concurrently -** from within other threads. -** -** However, the application must guarantee that the destination -** [database connection] is not passed to any other API (by any thread) after -** sqlite3_backup_init() is called and before the corresponding call to -** sqlite3_backup_finish(). SQLite does not currently check to see -** if the application incorrectly accesses the destination [database connection] -** and so no error code is reported, but the operations may malfunction -** nevertheless. Use of the destination database connection while a -** backup is in progress might also also cause a mutex deadlock. -** -** If running in [shared cache mode], the application must -** guarantee that the shared cache used by the destination database -** is not accessed while the backup is running. In practice this means -** that the application must guarantee that the disk file being -** backed up to is not accessed by any connection within the process, -** not just the specific connection that was passed to sqlite3_backup_init(). -** -** The [sqlite3_backup] object itself is partially threadsafe. Multiple -** threads may safely make multiple concurrent calls to sqlite3_backup_step(). -** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() -** APIs are not strictly speaking threadsafe. If they are invoked at the -** same time as another thread is invoking sqlite3_backup_step() it is -** possible that they return invalid values. -*/ -SQLITE_API sqlite3_backup *sqlite3_backup_init( - sqlite3 *pDest, /* Destination database handle */ - const char *zDestName, /* Destination database name */ - sqlite3 *pSource, /* Source database handle */ - const char *zSourceName /* Source database name */ -); -SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); -SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); -SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); - -/* -** CAPI3REF: Unlock Notification -** METHOD: sqlite3 -** -** ^When running in shared-cache mode, a database operation may fail with -** an [SQLITE_LOCKED] error if the required locks on the shared-cache or -** individual tables within the shared-cache cannot be obtained. See -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. -** ^This API may be used to register a callback that SQLite will invoke -** when the connection currently holding the required lock relinquishes it. -** ^This API is only available if the library was compiled with the -** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. -** -** See Also: [Using the SQLite Unlock Notification Feature]. -** -** ^Shared-cache locks are released when a database connection concludes -** its current transaction, either by committing it or rolling it back. -** -** ^When a connection (known as the blocked connection) fails to obtain a -** shared-cache lock and SQLITE_LOCKED is returned to the caller, the -** identity of the database connection (the blocking connection) that -** has locked the required resource is stored internally. ^After an -** application receives an SQLITE_LOCKED error, it may call the -** sqlite3_unlock_notify() method with the blocked connection handle as -** the first argument to register for a callback that will be invoked -** when the blocking connections current transaction is concluded. ^The -** callback is invoked from within the [sqlite3_step] or [sqlite3_close] -** call that concludes the blocking connections transaction. -** -** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, -** there is a chance that the blocking connection will have already -** concluded its transaction by the time sqlite3_unlock_notify() is invoked. -** If this happens, then the specified callback is invoked immediately, -** from within the call to sqlite3_unlock_notify().)^ -** -** ^If the blocked connection is attempting to obtain a write-lock on a -** shared-cache table, and more than one other connection currently holds -** a read-lock on the same table, then SQLite arbitrarily selects one of -** the other connections to use as the blocking connection. -** -** ^(There may be at most one unlock-notify callback registered by a -** blocked connection. If sqlite3_unlock_notify() is called when the -** blocked connection already has a registered unlock-notify callback, -** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is -** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connections -** unlock-notify callback may also be canceled by closing the blocked -** connection using [sqlite3_close()]. -** -** The unlock-notify callback is not reentrant. If an application invokes -** any sqlite3_xxx API functions from within an unlock-notify callback, a -** crash or deadlock may be the result. -** -** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always -** returns SQLITE_OK. -** -** Callback Invocation Details -** -** When an unlock-notify callback is registered, the application provides a -** single void* pointer that is passed to the callback when it is invoked. -** However, the signature of the callback function allows SQLite to pass -** it an array of void* context pointers. The first argument passed to -** an unlock-notify callback is a pointer to an array of void* pointers, -** and the second is the number of entries in the array. -** -** When a blocking connections transaction is concluded, there may be -** more than one blocked connection that has registered for an unlock-notify -** callback. ^If two or more such blocked connections have specified the -** same callback function, then instead of invoking the callback function -** multiple times, it is invoked once with the set of void* context pointers -** specified by the blocked connections bundled together into an array. -** This gives the application an opportunity to prioritize any actions -** related to the set of unblocked database connections. -** -** Deadlock Detection -** -** Assuming that after registering for an unlock-notify callback a -** database waits for the callback to be issued before taking any further -** action (a reasonable assumption), then using this API may cause the -** application to deadlock. For example, if connection X is waiting for -** connection Y's transaction to be concluded, and similarly connection -** Y is waiting on connection X's transaction, then neither connection -** will proceed and the system may remain deadlocked indefinitely. -** -** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock -** detection. ^If a given call to sqlite3_unlock_notify() would put the -** system in a deadlocked state, then SQLITE_LOCKED is returned and no -** unlock-notify callback is registered. The system is said to be in -** a deadlocked state if connection A has registered for an unlock-notify -** callback on the conclusion of connection B's transaction, and connection -** B has itself registered for an unlock-notify callback when connection -** A's transaction is concluded. ^Indirect deadlock is also detected, so -** the system is also considered to be deadlocked if connection B has -** registered for an unlock-notify callback on the conclusion of connection -** C's transaction, where connection C is waiting on connection A. ^Any -** number of levels of indirection are allowed. -** -** The "DROP TABLE" Exception -** -** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost -** always appropriate to call sqlite3_unlock_notify(). There is however, -** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, -** SQLite checks if there are any currently executing SELECT statements -** that belong to the same connection. If there are, SQLITE_LOCKED is -** returned. In this case there is no "blocking connection", so invoking -** sqlite3_unlock_notify() results in the unlock-notify callback being -** invoked immediately. If the application then re-attempts the "DROP TABLE" -** or "DROP INDEX" query, an infinite loop might be the result. -** -** One way around this problem is to check the extended error code returned -** by an sqlite3_step() call. ^(If there is a blocking connection, then the -** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in -** the special "DROP TABLE/INDEX" case, the extended error code is just -** SQLITE_LOCKED.)^ -*/ -SQLITE_API int sqlite3_unlock_notify( - sqlite3 *pBlocked, /* Waiting connection */ - void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ - void *pNotifyArg /* Argument to pass to xNotify */ -); - - -/* -** CAPI3REF: String Comparison -** -** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications -** and extensions to compare the contents of two buffers containing UTF-8 -** strings in a case-independent fashion, using the same definition of "case -** independence" that SQLite uses internally when comparing identifiers. -*/ -SQLITE_API int sqlite3_stricmp(const char *, const char *); -SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); - -/* -** CAPI3REF: String Globbing -* -** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if -** string X matches the [GLOB] pattern P. -** ^The definition of [GLOB] pattern matching used in -** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the -** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function -** is case sensitive. -** -** Note that this routine returns zero on a match and non-zero if the strings -** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. -** -** See also: [sqlite3_strlike()]. -*/ -SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); - -/* -** CAPI3REF: String LIKE Matching -* -** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if -** string X matches the [LIKE] pattern P with escape character E. -** ^The definition of [LIKE] pattern matching used in -** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" -** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without -** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. -** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case -** insensitive - equivalent upper and lower case ASCII characters match -** one another. -** -** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though -** only ASCII characters are case folded. -** -** Note that this routine returns zero on a match and non-zero if the strings -** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. -** -** See also: [sqlite3_strglob()]. -*/ -SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); - -/* -** CAPI3REF: Error Logging Interface -** -** ^The [sqlite3_log()] interface writes a message into the [error log] -** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. -** ^If logging is enabled, the zFormat string and subsequent arguments are -** used with [sqlite3_snprintf()] to generate the final output string. -** -** The sqlite3_log() interface is intended for use by extensions such as -** virtual tables, collating functions, and SQL functions. While there is -** nothing to prevent an application from calling sqlite3_log(), doing so -** is considered bad form. -** -** The zFormat string must not be NULL. -** -** To avoid deadlocks and other threading problems, the sqlite3_log() routine -** will not use dynamically allocated memory. The log message is stored in -** a fixed-length buffer on the stack. If the log message is longer than -** a few hundred characters, it will be truncated to the length of the -** buffer. -*/ -SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); - -/* -** CAPI3REF: Write-Ahead Log Commit Hook -** METHOD: sqlite3 -** -** ^The [sqlite3_wal_hook()] function is used to register a callback that -** is invoked each time data is committed to a database in wal mode. -** -** ^(The callback is invoked by SQLite after the commit has taken place and -** the associated write-lock on the database released)^, so the implementation -** may read, write or [checkpoint] the database as required. -** -** ^The first parameter passed to the callback function when it is invoked -** is a copy of the third parameter passed to sqlite3_wal_hook() when -** registering the callback. ^The second is a copy of the database handle. -** ^The third parameter is the name of the database that was written to - -** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter -** is the number of pages currently in the write-ahead log file, -** including those that were just committed. -** -** The callback function should normally return [SQLITE_OK]. ^If an error -** code is returned, that error will propagate back up through the -** SQLite code base to cause the statement that provoked the callback -** to report an error, though the commit will have still occurred. If the -** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value -** that does not correspond to any valid SQLite error code, the results -** are undefined. -** -** A single database handle may have at most a single write-ahead log callback -** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any -** previously registered write-ahead log callback. ^Note that the -** [sqlite3_wal_autocheckpoint()] interface and the -** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will -** overwrite any prior [sqlite3_wal_hook()] settings. -*/ -SQLITE_API void *sqlite3_wal_hook( - sqlite3*, - int(*)(void *,sqlite3*,const char*,int), - void* -); - -/* -** CAPI3REF: Configure an auto-checkpoint -** METHOD: sqlite3 -** -** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around -** [sqlite3_wal_hook()] that causes any database on [database connection] D -** to automatically [checkpoint] -** after committing a transaction if there are N or -** more frames in the [write-ahead log] file. ^Passing zero or -** a negative value as the nFrame parameter disables automatic -** checkpoints entirely. -** -** ^The callback registered by this function replaces any existing callback -** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback -** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism -** configured by this function. -** -** ^The [wal_autocheckpoint pragma] can be used to invoke this interface -** from SQL. -** -** ^Checkpoints initiated by this mechanism are -** [sqlite3_wal_checkpoint_v2|PASSIVE]. -** -** ^Every new [database connection] defaults to having the auto-checkpoint -** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] -** pages. The use of this interface -** is only necessary if the default setting is found to be suboptimal -** for a particular application. -*/ -SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); - -/* -** CAPI3REF: Checkpoint a database -** METHOD: sqlite3 -** -** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to -** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ -** -** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the -** [write-ahead log] for database X on [database connection] D to be -** transferred into the database file and for the write-ahead log to -** be reset. See the [checkpointing] documentation for addition -** information. -** -** This interface used to be the only way to cause a checkpoint to -** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] -** interface was added. This interface is retained for backwards -** compatibility and as a convenience for applications that need to manually -** start a callback but which do not need the full power (and corresponding -** complication) of [sqlite3_wal_checkpoint_v2()]. -*/ -SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); - -/* -** CAPI3REF: Checkpoint a database -** METHOD: sqlite3 -** -** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint -** operation on database X of [database connection] D in mode M. Status -** information is written back into integers pointed to by L and C.)^ -** ^(The M parameter must be a valid [checkpoint mode]:)^ -** -**
-**
SQLITE_CHECKPOINT_PASSIVE
-** ^Checkpoint as many frames as possible without waiting for any database -** readers or writers to finish, then sync the database file if all frames -** in the log were checkpointed. ^The [busy-handler callback] -** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. -** ^On the other hand, passive mode might leave the checkpoint unfinished -** if there are concurrent readers or writers. -** -**
SQLITE_CHECKPOINT_FULL
-** ^This mode blocks (it invokes the -** [sqlite3_busy_handler|busy-handler callback]) until there is no -** database writer and all readers are reading from the most recent database -** snapshot. ^It then checkpoints all frames in the log file and syncs the -** database file. ^This mode blocks new database writers while it is pending, -** but new database readers are allowed to continue unimpeded. -** -**
SQLITE_CHECKPOINT_RESTART
-** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition -** that after checkpointing the log file it blocks (calls the -** [busy-handler callback]) -** until all readers are reading from the database file only. ^This ensures -** that the next writer will restart the log file from the beginning. -** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new -** database writer attempts while it is pending, but does not impede readers. -** -**
SQLITE_CHECKPOINT_TRUNCATE
-** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the -** addition that it also truncates the log file to zero bytes just prior -** to a successful return. -**
-** -** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in -** the log file or to -1 if the checkpoint could not run because -** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not -** NULL,then *pnCkpt is set to the total number of checkpointed frames in the -** log file (including any that were already checkpointed before the function -** was called) or to -1 if the checkpoint could not run due to an error or -** because the database is not in WAL mode. ^Note that upon successful -** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been -** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. -** -** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If -** any other process is running a checkpoint operation at the same time, the -** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a -** busy-handler configured, it will not be invoked in this case. -** -** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the -** exclusive "writer" lock on the database file. ^If the writer lock cannot be -** obtained immediately, and a busy-handler is configured, it is invoked and -** the writer lock retried until either the busy-handler returns 0 or the lock -** is successfully obtained. ^The busy-handler is also invoked while waiting for -** database readers as described above. ^If the busy-handler returns 0 before -** the writer lock is obtained or while waiting for database readers, the -** checkpoint operation proceeds from that point in the same way as -** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible -** without blocking any further. ^SQLITE_BUSY is returned in this case. -** -** ^If parameter zDb is NULL or points to a zero length string, then the -** specified operation is attempted on all WAL databases [attached] to -** [database connection] db. In this case the -** values written to output parameters *pnLog and *pnCkpt are undefined. ^If -** an SQLITE_BUSY error is encountered when processing one or more of the -** attached WAL databases, the operation is still attempted on any remaining -** attached databases and SQLITE_BUSY is returned at the end. ^If any other -** error occurs while processing an attached database, processing is abandoned -** and the error code is returned to the caller immediately. ^If no error -** (SQLITE_BUSY or otherwise) is encountered while processing the attached -** databases, SQLITE_OK is returned. -** -** ^If database zDb is the name of an attached database that is not in WAL -** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If -** zDb is not NULL (or a zero length string) and is not the name of any -** attached database, SQLITE_ERROR is returned to the caller. -** -** ^Unless it returns SQLITE_MISUSE, -** the sqlite3_wal_checkpoint_v2() interface -** sets the error information that is queried by -** [sqlite3_errcode()] and [sqlite3_errmsg()]. -** -** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface -** from SQL. -*/ -SQLITE_API int sqlite3_wal_checkpoint_v2( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of attached database (or NULL) */ - int eMode, /* SQLITE_CHECKPOINT_* value */ - int *pnLog, /* OUT: Size of WAL log in frames */ - int *pnCkpt /* OUT: Total number of frames checkpointed */ -); - -/* -** CAPI3REF: Checkpoint Mode Values -** KEYWORDS: {checkpoint mode} -** -** These constants define all valid values for the "checkpoint mode" passed -** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. -** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the -** meaning of each of these checkpoint modes. -*/ -#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ -#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ -#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ -#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ - -/* -** CAPI3REF: Virtual Table Interface Configuration -** -** This function may be called by either the [xConnect] or [xCreate] method -** of a [virtual table] implementation to configure -** various facets of the virtual table interface. -** -** If this interface is invoked outside the context of an xConnect or -** xCreate virtual table method then the behavior is undefined. -** -** At present, there is only one option that may be configured using -** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options -** may be added in the future. -*/ -SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); - -/* -** CAPI3REF: Virtual Table Configuration Options -** -** These macros define the various options to the -** [sqlite3_vtab_config()] interface that [virtual table] implementations -** can use to customize and optimize their behavior. -** -**
-**
SQLITE_VTAB_CONSTRAINT_SUPPORT -**
Calls of the form -** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, -** where X is an integer. If X is zero, then the [virtual table] whose -** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not -** support constraints. In this configuration (which is the default) if -** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire -** statement is rolled back as if [ON CONFLICT | OR ABORT] had been -** specified as part of the users SQL statement, regardless of the actual -** ON CONFLICT mode specified. -** -** If X is non-zero, then the virtual table implementation guarantees -** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before -** any modifications to internal or persistent data structures have been made. -** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite -** is able to roll back a statement or database transaction, and abandon -** or continue processing the current SQL statement as appropriate. -** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns -** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode -** had been ABORT. -** -** Virtual table implementations that are required to handle OR REPLACE -** must do so within the [xUpdate] method. If a call to the -** [sqlite3_vtab_on_conflict()] function indicates that the current ON -** CONFLICT policy is REPLACE, the virtual table implementation should -** silently replace the appropriate rows within the xUpdate callback and -** return SQLITE_OK. Or, if this is not possible, it may return -** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT -** constraint handling. -**
-*/ -#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 - -/* -** CAPI3REF: Determine The Virtual Table Conflict Policy -** -** This function may only be called from within a call to the [xUpdate] method -** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The -** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], -** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode -** of the SQL statement that triggered the call to the [xUpdate] method of the -** [virtual table]. -*/ -SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); - -/* -** CAPI3REF: Conflict resolution modes -** KEYWORDS: {conflict resolution mode} -** -** These constants are returned by [sqlite3_vtab_on_conflict()] to -** inform a [virtual table] implementation what the [ON CONFLICT] mode -** is for the SQL statement being evaluated. -** -** Note that the [SQLITE_IGNORE] constant is also used as a potential -** return value from the [sqlite3_set_authorizer()] callback and that -** [SQLITE_ABORT] is also a [result code]. -*/ -#define SQLITE_ROLLBACK 1 -/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ -#define SQLITE_FAIL 3 -/* #define SQLITE_ABORT 4 // Also an error code */ -#define SQLITE_REPLACE 5 - -/* -** CAPI3REF: Prepared Statement Scan Status Opcodes -** KEYWORDS: {scanstatus options} -** -** The following constants can be used for the T parameter to the -** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a -** different metric for sqlite3_stmt_scanstatus() to return. -** -** When the value returned to V is a string, space to hold that string is -** managed by the prepared statement S and will be automatically freed when -** S is finalized. -** -**
-** [[SQLITE_SCANSTAT_NLOOP]]
SQLITE_SCANSTAT_NLOOP
-**
^The [sqlite3_int64] variable pointed to by the T parameter will be -** set to the total number of times that the X-th loop has run.
-** -** [[SQLITE_SCANSTAT_NVISIT]]
SQLITE_SCANSTAT_NVISIT
-**
^The [sqlite3_int64] variable pointed to by the T parameter will be set -** to the total number of rows examined by all iterations of the X-th loop.
-** -** [[SQLITE_SCANSTAT_EST]]
SQLITE_SCANSTAT_EST
-**
^The "double" variable pointed to by the T parameter will be set to the -** query planner's estimate for the average number of rows output from each -** iteration of the X-th loop. If the query planner's estimates was accurate, -** then this value will approximate the quotient NVISIT/NLOOP and the -** product of this value for all prior loops with the same SELECTID will -** be the NLOOP value for the current loop. -** -** [[SQLITE_SCANSTAT_NAME]]
SQLITE_SCANSTAT_NAME
-**
^The "const char *" variable pointed to by the T parameter will be set -** to a zero-terminated UTF-8 string containing the name of the index or table -** used for the X-th loop. -** -** [[SQLITE_SCANSTAT_EXPLAIN]]
SQLITE_SCANSTAT_EXPLAIN
-**
^The "const char *" variable pointed to by the T parameter will be set -** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] -** description for the X-th loop. -** -** [[SQLITE_SCANSTAT_SELECTID]]
SQLITE_SCANSTAT_SELECT
-**
^The "int" variable pointed to by the T parameter will be set to the -** "select-id" for the X-th loop. The select-id identifies which query or -** subquery the loop is part of. The main query has a select-id of zero. -** The select-id is the same value as is output in the first column -** of an [EXPLAIN QUERY PLAN] query. -**
-*/ -#define SQLITE_SCANSTAT_NLOOP 0 -#define SQLITE_SCANSTAT_NVISIT 1 -#define SQLITE_SCANSTAT_EST 2 -#define SQLITE_SCANSTAT_NAME 3 -#define SQLITE_SCANSTAT_EXPLAIN 4 -#define SQLITE_SCANSTAT_SELECTID 5 - -/* -** CAPI3REF: Prepared Statement Scan Status -** METHOD: sqlite3_stmt -** -** This interface returns information about the predicted and measured -** performance for pStmt. Advanced applications can use this -** interface to compare the predicted and the measured performance and -** issue warnings and/or rerun [ANALYZE] if discrepancies are found. -** -** Since this interface is expected to be rarely used, it is only -** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] -** compile-time option. -** -** The "iScanStatusOp" parameter determines which status information to return. -** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. -** ^The requested measurement is written into a variable pointed to by -** the "pOut" parameter. -** Parameter "idx" identifies the specific loop to retrieve statistics for. -** Loops are numbered starting from zero. ^If idx is out of range - less than -** zero or greater than or equal to the total number of loops used to implement -** the statement - a non-zero value is returned and the variable that pOut -** points to is unchanged. -** -** ^Statistics might not be available for all loops in all statements. ^In cases -** where there exist loops with no available statistics, this function behaves -** as if the loop did not exist - it returns non-zero and leave the variable -** that pOut points to unchanged. -** -** See also: [sqlite3_stmt_scanstatus_reset()] -*/ -SQLITE_API int sqlite3_stmt_scanstatus( - sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ - void *pOut /* Result written here */ -); - -/* -** CAPI3REF: Zero Scan-Status Counters -** METHOD: sqlite3_stmt -** -** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. -** -** This API is only available if the library is built with pre-processor -** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. -*/ -SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); - -/* -** CAPI3REF: Flush caches to disk mid-transaction -** -** ^If a write-transaction is open on [database connection] D when the -** [sqlite3_db_cacheflush(D)] interface invoked, any dirty -** pages in the pager-cache that are not currently in use are written out -** to disk. A dirty page may be in use if a database cursor created by an -** active SQL statement is reading from it, or if it is page 1 of a database -** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] -** interface flushes caches for all schemas - "main", "temp", and -** any [attached] databases. -** -** ^If this function needs to obtain extra database locks before dirty pages -** can be flushed to disk, it does so. ^If those locks cannot be obtained -** immediately and there is a busy-handler callback configured, it is invoked -** in the usual manner. ^If the required lock still cannot be obtained, then -** the database is skipped and an attempt made to flush any dirty pages -** belonging to the next (if any) database. ^If any databases are skipped -** because locks cannot be obtained, but no other error occurs, this -** function returns SQLITE_BUSY. -** -** ^If any other error occurs while flushing dirty pages to disk (for -** example an IO error or out-of-memory condition), then processing is -** abandoned and an SQLite [error code] is returned to the caller immediately. -** -** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK. -** -** ^This function does not set the database handle error code or message -** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. -*/ -SQLITE_API int sqlite3_db_cacheflush(sqlite3*); - -/* -** CAPI3REF: The pre-update hook. -** -** ^These interfaces are only available if SQLite is compiled using the -** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. -** -** ^The [sqlite3_preupdate_hook()] interface registers a callback function -** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation -** on a [rowid table]. -** ^At most one preupdate hook may be registered at a time on a single -** [database connection]; each call to [sqlite3_preupdate_hook()] overrides -** the previous setting. -** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()] -** with a NULL pointer as the second parameter. -** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as -** the first parameter to callbacks. -** -** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate -** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID] -** tables. -** -** ^The second parameter to the preupdate callback is a pointer to -** the [database connection] that registered the preupdate hook. -** ^The third parameter to the preupdate callback is one of the constants -** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the -** kind of update operation that is about to occur. -** ^(The fourth parameter to the preupdate callback is the name of the -** database within the database connection that is being modified. This -** will be "main" for the main database or "temp" for TEMP tables or -** the name given after the AS keyword in the [ATTACH] statement for attached -** databases.)^ -** ^The fifth parameter to the preupdate callback is the name of the -** table that is being modified. -** ^The sixth parameter to the preupdate callback is the initial [rowid] of the -** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is -** undefined for SQLITE_INSERT changes. -** ^The seventh parameter to the preupdate callback is the final [rowid] of -** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is -** undefined for SQLITE_DELETE changes. -** -** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], -** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces -** provide additional information about a preupdate event. These routines -** may only be called from within a preupdate callback. Invoking any of -** these routines from outside of a preupdate callback or with a -** [database connection] pointer that is different from the one supplied -** to the preupdate callback results in undefined and probably undesirable -** behavior. -** -** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns -** in the row that is being inserted, updated, or deleted. -** -** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to -** a [protected sqlite3_value] that contains the value of the Nth column of -** the table row before it is updated. The N parameter must be between 0 -** and one less than the number of columns or the behavior will be -** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE -** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the -** behavior is undefined. The [sqlite3_value] that P points to -** will be destroyed when the preupdate callback returns. -** -** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to -** a [protected sqlite3_value] that contains the value of the Nth column of -** the table row after it is updated. The N parameter must be between 0 -** and one less than the number of columns or the behavior will be -** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE -** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the -** behavior is undefined. The [sqlite3_value] that P points to -** will be destroyed when the preupdate callback returns. -** -** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate -** callback was invoked as a result of a direct insert, update, or delete -** operation; or 1 for inserts, updates, or deletes invoked by top-level -** triggers; or 2 for changes resulting from triggers called by top-level -** triggers; and so forth. -** -** See also: [sqlite3_update_hook()] -*/ -SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_preupdate_hook( - sqlite3 *db, - void(*xPreUpdate)( - void *pCtx, /* Copy of third arg to preupdate_hook() */ - sqlite3 *db, /* Database handle */ - int op, /* SQLITE_UPDATE, DELETE or INSERT */ - char const *zDb, /* Database name */ - char const *zName, /* Table name */ - sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ - sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ - ), - void* -); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_count(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_depth(sqlite3 *); -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); - -/* -** CAPI3REF: Low-level system error code -** -** ^Attempt to return the underlying operating system error code or error -** number that caused the most recent I/O error or failure to open a file. -** The return value is OS-dependent. For example, on unix systems, after -** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be -** called to get back the underlying "errno" that caused the problem, such -** as ENOSPC, EAUTH, EISDIR, and so forth. -*/ -SQLITE_API int sqlite3_system_errno(sqlite3*); - -/* -** CAPI3REF: Database Snapshot -** KEYWORDS: {snapshot} -** EXPERIMENTAL -** -** An instance of the snapshot object records the state of a [WAL mode] -** database for some specific point in history. -** -** In [WAL mode], multiple [database connections] that are open on the -** same database file can each be reading a different historical version -** of the database file. When a [database connection] begins a read -** transaction, that connection sees an unchanging copy of the database -** as it existed for the point in time when the transaction first started. -** Subsequent changes to the database from other connections are not seen -** by the reader until a new read transaction is started. -** -** The sqlite3_snapshot object records state information about an historical -** version of the database file so that it is possible to later open a new read -** transaction that sees that historical version of the database rather than -** the most recent version. -** -** The constructor for this object is [sqlite3_snapshot_get()]. The -** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer -** to an historical snapshot (if possible). The destructor for -** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. -*/ -typedef struct sqlite3_snapshot sqlite3_snapshot; - -/* -** CAPI3REF: Record A Database Snapshot -** EXPERIMENTAL -** -** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a -** new [sqlite3_snapshot] object that records the current state of -** schema S in database connection D. ^On success, the -** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly -** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. -** ^If schema S of [database connection] D is not a [WAL mode] database -** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)] -** leaves the *P value unchanged and returns an appropriate [error code]. -** -** The [sqlite3_snapshot] object returned from a successful call to -** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] -** to avoid a memory leak. -** -** The [sqlite3_snapshot_get()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -*/ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( - sqlite3 *db, - const char *zSchema, - sqlite3_snapshot **ppSnapshot -); - -/* -** CAPI3REF: Start a read transaction on an historical snapshot -** EXPERIMENTAL -** -** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a -** read transaction for schema S of -** [database connection] D such that the read transaction -** refers to historical [snapshot] P, rather than the most -** recent change to the database. -** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success -** or an appropriate [error code] if it fails. -** -** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be -** the first operation following the [BEGIN] that takes the schema S -** out of [autocommit mode]. -** ^In other words, schema S must not currently be in -** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the -** database connection D must be out of [autocommit mode]. -** ^A [snapshot] will fail to open if it has been overwritten by a -** [checkpoint]. -** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the -** database connection D does not know that the database file for -** schema S is in [WAL mode]. A database connection might not know -** that the database file is in [WAL mode] if there has been no prior -** I/O on that database connection, or if the database entered [WAL mode] -** after the most recent I/O on the database connection.)^ -** (Hint: Run "[PRAGMA application_id]" against a newly opened -** database connection in order to make it ready to use snapshots.) -** -** The [sqlite3_snapshot_open()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -*/ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( - sqlite3 *db, - const char *zSchema, - sqlite3_snapshot *pSnapshot -); - -/* -** CAPI3REF: Destroy a snapshot -** EXPERIMENTAL -** -** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. -** The application must eventually free every [sqlite3_snapshot] object -** using this routine to avoid a memory leak. -** -** The [sqlite3_snapshot_free()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. -*/ -SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); - -/* -** CAPI3REF: Compare the ages of two snapshot handles. -** EXPERIMENTAL -** -** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages -** of two valid snapshot handles. -** -** If the two snapshot handles are not associated with the same database -** file, the result of the comparison is undefined. -** -** Additionally, the result of the comparison is only valid if both of the -** snapshot handles were obtained by calling sqlite3_snapshot_get() since the -** last time the wal file was deleted. The wal file is deleted when the -** database is changed back to rollback mode or when the number of database -** clients drops to zero. If either snapshot handle was obtained before the -** wal file was last deleted, the value returned by this function -** is undefined. -** -** Otherwise, this API returns a negative value if P1 refers to an older -** snapshot than P2, zero if the two handles refer to the same database -** snapshot, and a positive value if P1 is a newer snapshot than P2. -*/ -SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( - sqlite3_snapshot *p1, - sqlite3_snapshot *p2 -); - -/* -** Undo the hack that converts floating point types to integer for -** builds on processors without floating point support. -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# undef double -#endif - -#if 0 -} /* End of the 'extern "C"' block */ -#endif -#endif /* SQLITE3_H */ - -/******** Begin file sqlite3rtree.h *********/ -/* -** 2010 August 30 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -*/ - -#ifndef _SQLITE3RTREE_H_ -#define _SQLITE3RTREE_H_ - - -#if 0 -extern "C" { -#endif - -typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; -typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; - -/* The double-precision datatype used by RTree depends on the -** SQLITE_RTREE_INT_ONLY compile-time option. -*/ -#ifdef SQLITE_RTREE_INT_ONLY - typedef sqlite3_int64 sqlite3_rtree_dbl; -#else - typedef double sqlite3_rtree_dbl; -#endif - -/* -** Register a geometry callback named zGeom that can be used as part of an -** R-Tree geometry query as follows: -** -** SELECT ... FROM WHERE MATCH $zGeom(... params ...) -*/ -SQLITE_API int sqlite3_rtree_geometry_callback( - sqlite3 *db, - const char *zGeom, - int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), - void *pContext -); - - -/* -** A pointer to a structure of the following type is passed as the first -** argument to callbacks registered using rtree_geometry_callback(). -*/ -struct sqlite3_rtree_geometry { - void *pContext; /* Copy of pContext passed to s_r_g_c() */ - int nParam; /* Size of array aParam[] */ - sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ - void *pUser; /* Callback implementation user data */ - void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ -}; - -/* -** Register a 2nd-generation geometry callback named zScore that can be -** used as part of an R-Tree geometry query as follows: -** -** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) -*/ -SQLITE_API int sqlite3_rtree_query_callback( - sqlite3 *db, - const char *zQueryFunc, - int (*xQueryFunc)(sqlite3_rtree_query_info*), - void *pContext, - void (*xDestructor)(void*) -); - - -/* -** A pointer to a structure of the following type is passed as the -** argument to scored geometry callback registered using -** sqlite3_rtree_query_callback(). -** -** Note that the first 5 fields of this structure are identical to -** sqlite3_rtree_geometry. This structure is a subclass of -** sqlite3_rtree_geometry. -*/ -struct sqlite3_rtree_query_info { - void *pContext; /* pContext from when function registered */ - int nParam; /* Number of function parameters */ - sqlite3_rtree_dbl *aParam; /* value of function parameters */ - void *pUser; /* callback can use this, if desired */ - void (*xDelUser)(void*); /* function to free pUser */ - sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ - unsigned int *anQueue; /* Number of pending entries in the queue */ - int nCoord; /* Number of coordinates */ - int iLevel; /* Level of current node or entry */ - int mxLevel; /* The largest iLevel value in the tree */ - sqlite3_int64 iRowid; /* Rowid for current entry */ - sqlite3_rtree_dbl rParentScore; /* Score of parent node */ - int eParentWithin; /* Visibility of parent node */ - int eWithin; /* OUT: Visiblity */ - sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ - /* The following fields are only available in 3.8.11 and later */ - sqlite3_value **apSqlParam; /* Original SQL values of parameters */ -}; - -/* -** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. -*/ -#define NOT_WITHIN 0 /* Object completely outside of query region */ -#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ -#define FULLY_WITHIN 2 /* Object fully contained within query region */ - - -#if 0 -} /* end of the 'extern "C"' block */ -#endif - -#endif /* ifndef _SQLITE3RTREE_H_ */ - -/******** End of sqlite3rtree.h *********/ -/******** Begin file sqlite3session.h *********/ - -#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) -#define __SQLITESESSION_H_ 1 - -/* -** Make sure we can call this stuff from C++. -*/ -#if 0 -extern "C" { -#endif - - -/* -** CAPI3REF: Session Object Handle -*/ -typedef struct sqlite3_session sqlite3_session; - -/* -** CAPI3REF: Changeset Iterator Handle -*/ -typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; - -/* -** CAPI3REF: Create A New Session Object -** -** Create a new session object attached to database handle db. If successful, -** a pointer to the new object is written to *ppSession and SQLITE_OK is -** returned. If an error occurs, *ppSession is set to NULL and an SQLite -** error code (e.g. SQLITE_NOMEM) is returned. -** -** It is possible to create multiple session objects attached to a single -** database handle. -** -** Session objects created using this function should be deleted using the -** [sqlite3session_delete()] function before the database handle that they -** are attached to is itself closed. If the database handle is closed before -** the session object is deleted, then the results of calling any session -** module function, including [sqlite3session_delete()] on the session object -** are undefined. -** -** Because the session module uses the [sqlite3_preupdate_hook()] API, it -** is not possible for an application to register a pre-update hook on a -** database handle that has one or more session objects attached. Nor is -** it possible to create a session object attached to a database handle for -** which a pre-update hook is already defined. The results of attempting -** either of these things are undefined. -** -** The session object will be used to create changesets for tables in -** database zDb, where zDb is either "main", or "temp", or the name of an -** attached database. It is not an error if database zDb is not attached -** to the database when the session object is created. -*/ -int sqlite3session_create( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of db (e.g. "main") */ - sqlite3_session **ppSession /* OUT: New session object */ -); - -/* -** CAPI3REF: Delete A Session Object -** -** Delete a session object previously allocated using -** [sqlite3session_create()]. Once a session object has been deleted, the -** results of attempting to use pSession with any other session module -** function are undefined. -** -** Session objects must be deleted before the database handle to which they -** are attached is closed. Refer to the documentation for -** [sqlite3session_create()] for details. -*/ -void sqlite3session_delete(sqlite3_session *pSession); - - -/* -** CAPI3REF: Enable Or Disable A Session Object -** -** Enable or disable the recording of changes by a session object. When -** enabled, a session object records changes made to the database. When -** disabled - it does not. A newly created session object is enabled. -** Refer to the documentation for [sqlite3session_changeset()] for further -** details regarding how enabling and disabling a session object affects -** the eventual changesets. -** -** Passing zero to this function disables the session. Passing a value -** greater than zero enables it. Passing a value less than zero is a -** no-op, and may be used to query the current state of the session. -** -** The return value indicates the final state of the session object: 0 if -** the session is disabled, or 1 if it is enabled. -*/ -int sqlite3session_enable(sqlite3_session *pSession, int bEnable); - -/* -** CAPI3REF: Set Or Clear the Indirect Change Flag -** -** Each change recorded by a session object is marked as either direct or -** indirect. A change is marked as indirect if either: -** -**
    -**
  • The session object "indirect" flag is set when the change is -** made, or -**
  • The change is made by an SQL trigger or foreign key action -** instead of directly as a result of a users SQL statement. -**
-** -** If a single row is affected by more than one operation within a session, -** then the change is considered indirect if all operations meet the criteria -** for an indirect change above, or direct otherwise. -** -** This function is used to set, clear or query the session object indirect -** flag. If the second argument passed to this function is zero, then the -** indirect flag is cleared. If it is greater than zero, the indirect flag -** is set. Passing a value less than zero does not modify the current value -** of the indirect flag, and may be used to query the current state of the -** indirect flag for the specified session object. -** -** The return value indicates the final state of the indirect flag: 0 if -** it is clear, or 1 if it is set. -*/ -int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); - -/* -** CAPI3REF: Attach A Table To A Session Object -** -** If argument zTab is not NULL, then it is the name of a table to attach -** to the session object passed as the first argument. All subsequent changes -** made to the table while the session object is enabled will be recorded. See -** documentation for [sqlite3session_changeset()] for further details. -** -** Or, if argument zTab is NULL, then changes are recorded for all tables -** in the database. If additional tables are added to the database (by -** executing "CREATE TABLE" statements) after this call is made, changes for -** the new tables are also recorded. -** -** Changes can only be recorded for tables that have a PRIMARY KEY explicitly -** defined as part of their CREATE TABLE statement. It does not matter if the -** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY -** KEY may consist of a single column, or may be a composite key. -** -** It is not an error if the named table does not exist in the database. Nor -** is it an error if the named table does not have a PRIMARY KEY. However, -** no changes will be recorded in either of these scenarios. -** -** Changes are not recorded for individual rows that have NULL values stored -** in one or more of their PRIMARY KEY columns. -** -** SQLITE_OK is returned if the call completes without error. Or, if an error -** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. -*/ -int sqlite3session_attach( - sqlite3_session *pSession, /* Session object */ - const char *zTab /* Table name */ -); - -/* -** CAPI3REF: Set a table filter on a Session Object. -** -** The second argument (xFilter) is the "filter callback". For changes to rows -** in tables that are not attached to the Session object, the filter is called -** to determine whether changes to the table's rows should be tracked or not. -** If xFilter returns 0, changes is not tracked. Note that once a table is -** attached, xFilter will not be called again. -*/ -void sqlite3session_table_filter( - sqlite3_session *pSession, /* Session object */ - int(*xFilter)( - void *pCtx, /* Copy of third arg to _filter_table() */ - const char *zTab /* Table name */ - ), - void *pCtx /* First argument passed to xFilter */ -); - -/* -** CAPI3REF: Generate A Changeset From A Session Object -** -** Obtain a changeset containing changes to the tables attached to the -** session object passed as the first argument. If successful, -** set *ppChangeset to point to a buffer containing the changeset -** and *pnChangeset to the size of the changeset in bytes before returning -** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to -** zero and return an SQLite error code. -** -** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes, -** each representing a change to a single row of an attached table. An INSERT -** change contains the values of each field of a new database row. A DELETE -** contains the original values of each field of a deleted database row. An -** UPDATE change contains the original values of each field of an updated -** database row along with the updated values for each updated non-primary-key -** column. It is not possible for an UPDATE change to represent a change that -** modifies the values of primary key columns. If such a change is made, it -** is represented in a changeset as a DELETE followed by an INSERT. -** -** Changes are not recorded for rows that have NULL values stored in one or -** more of their PRIMARY KEY columns. If such a row is inserted or deleted, -** no corresponding change is present in the changesets returned by this -** function. If an existing row with one or more NULL values stored in -** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL, -** only an INSERT is appears in the changeset. Similarly, if an existing row -** with non-NULL PRIMARY KEY values is updated so that one or more of its -** PRIMARY KEY columns are set to NULL, the resulting changeset contains a -** DELETE change only. -** -** The contents of a changeset may be traversed using an iterator created -** using the [sqlite3changeset_start()] API. A changeset may be applied to -** a database with a compatible schema using the [sqlite3changeset_apply()] -** API. -** -** Within a changeset generated by this function, all changes related to a -** single table are grouped together. In other words, when iterating through -** a changeset or when applying a changeset to a database, all changes related -** to a single table are processed before moving on to the next table. Tables -** are sorted in the same order in which they were attached (or auto-attached) -** to the sqlite3_session object. The order in which the changes related to -** a single table are stored is undefined. -** -** Following a successful call to this function, it is the responsibility of -** the caller to eventually free the buffer that *ppChangeset points to using -** [sqlite3_free()]. -** -**

Changeset Generation

-** -** Once a table has been attached to a session object, the session object -** records the primary key values of all new rows inserted into the table. -** It also records the original primary key and other column values of any -** deleted or updated rows. For each unique primary key value, data is only -** recorded once - the first time a row with said primary key is inserted, -** updated or deleted in the lifetime of the session. -** -** There is one exception to the previous paragraph: when a row is inserted, -** updated or deleted, if one or more of its primary key columns contain a -** NULL value, no record of the change is made. -** -** The session object therefore accumulates two types of records - those -** that consist of primary key values only (created when the user inserts -** a new record) and those that consist of the primary key values and the -** original values of other table columns (created when the users deletes -** or updates a record). -** -** When this function is called, the requested changeset is created using -** both the accumulated records and the current contents of the database -** file. Specifically: -** -**
    -**
  • For each record generated by an insert, the database is queried -** for a row with a matching primary key. If one is found, an INSERT -** change is added to the changeset. If no such row is found, no change -** is added to the changeset. -** -**
  • For each record generated by an update or delete, the database is -** queried for a row with a matching primary key. If such a row is -** found and one or more of the non-primary key fields have been -** modified from their original values, an UPDATE change is added to -** the changeset. Or, if no such row is found in the table, a DELETE -** change is added to the changeset. If there is a row with a matching -** primary key in the database, but all fields contain their original -** values, no change is added to the changeset. -**
-** -** This means, amongst other things, that if a row is inserted and then later -** deleted while a session object is active, neither the insert nor the delete -** will be present in the changeset. Or if a row is deleted and then later a -** row with the same primary key values inserted while a session object is -** active, the resulting changeset will contain an UPDATE change instead of -** a DELETE and an INSERT. -** -** When a session object is disabled (see the [sqlite3session_enable()] API), -** it does not accumulate records when rows are inserted, updated or deleted. -** This may appear to have some counter-intuitive effects if a single row -** is written to more than once during a session. For example, if a row -** is inserted while a session object is enabled, then later deleted while -** the same session object is disabled, no INSERT record will appear in the -** changeset, even though the delete took place while the session was disabled. -** Or, if one field of a row is updated while a session is disabled, and -** another field of the same row is updated while the session is enabled, the -** resulting changeset will contain an UPDATE change that updates both fields. -*/ -int sqlite3session_changeset( - sqlite3_session *pSession, /* Session object */ - int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ - void **ppChangeset /* OUT: Buffer containing changeset */ -); - -/* -** CAPI3REF: Load The Difference Between Tables Into A Session -** -** If it is not already attached to the session object passed as the first -** argument, this function attaches table zTbl in the same manner as the -** [sqlite3session_attach()] function. If zTbl does not exist, or if it -** does not have a primary key, this function is a no-op (but does not return -** an error). -** -** Argument zFromDb must be the name of a database ("main", "temp" etc.) -** attached to the same database handle as the session object that contains -** a table compatible with the table attached to the session by this function. -** A table is considered compatible if it: -** -**
    -**
  • Has the same name, -**
  • Has the same set of columns declared in the same order, and -**
  • Has the same PRIMARY KEY definition. -**
-** -** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables -** are compatible but do not have any PRIMARY KEY columns, it is not an error -** but no changes are added to the session object. As with other session -** APIs, tables without PRIMARY KEYs are simply ignored. -** -** This function adds a set of changes to the session object that could be -** used to update the table in database zFrom (call this the "from-table") -** so that its content is the same as the table attached to the session -** object (call this the "to-table"). Specifically: -** -**
    -**
  • For each row (primary key) that exists in the to-table but not in -** the from-table, an INSERT record is added to the session object. -** -**
  • For each row (primary key) that exists in the to-table but not in -** the from-table, a DELETE record is added to the session object. -** -**
  • For each row (primary key) that exists in both tables, but features -** different in each, an UPDATE record is added to the session. -**
-** -** To clarify, if this function is called and then a changeset constructed -** using [sqlite3session_changeset()], then after applying that changeset to -** database zFrom the contents of the two compatible tables would be -** identical. -** -** It an error if database zFrom does not exist or does not contain the -** required compatible table. -** -** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite -** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg -** may be set to point to a buffer containing an English language error -** message. It is the responsibility of the caller to free this buffer using -** sqlite3_free(). -*/ -int sqlite3session_diff( - sqlite3_session *pSession, - const char *zFromDb, - const char *zTbl, - char **pzErrMsg -); - - -/* -** CAPI3REF: Generate A Patchset From A Session Object -** -** The differences between a patchset and a changeset are that: -** -**
    -**
  • DELETE records consist of the primary key fields only. The -** original values of other fields are omitted. -**
  • The original values of any modified fields are omitted from -** UPDATE records. -**
-** -** A patchset blob may be used with up to date versions of all -** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), -** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly, -** attempting to use a patchset blob with old versions of the -** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. -** -** Because the non-primary key "old.*" fields are omitted, no -** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset -** is passed to the sqlite3changeset_apply() API. Other conflict types work -** in the same way as for changesets. -** -** Changes within a patchset are ordered in the same way as for changesets -** generated by the sqlite3session_changeset() function (i.e. all changes for -** a single table are grouped together, tables appear in the order in which -** they were attached to the session object). -*/ -int sqlite3session_patchset( - sqlite3_session *pSession, /* Session object */ - int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ - void **ppPatchset /* OUT: Buffer containing changeset */ -); - -/* -** CAPI3REF: Test if a changeset has recorded any changes. -** -** Return non-zero if no changes to attached tables have been recorded by -** the session object passed as the first argument. Otherwise, if one or -** more changes have been recorded, return zero. -** -** Even if this function returns zero, it is possible that calling -** [sqlite3session_changeset()] on the session handle may still return a -** changeset that contains no changes. This can happen when a row in -** an attached table is modified and then later on the original values -** are restored. However, if this function returns non-zero, then it is -** guaranteed that a call to sqlite3session_changeset() will return a -** changeset containing zero changes. -*/ -int sqlite3session_isempty(sqlite3_session *pSession); - -/* -** CAPI3REF: Create An Iterator To Traverse A Changeset -** -** Create an iterator used to iterate through the contents of a changeset. -** If successful, *pp is set to point to the iterator handle and SQLITE_OK -** is returned. Otherwise, if an error occurs, *pp is set to zero and an -** SQLite error code is returned. -** -** The following functions can be used to advance and query a changeset -** iterator created by this function: -** -**
    -**
  • [sqlite3changeset_next()] -**
  • [sqlite3changeset_op()] -**
  • [sqlite3changeset_new()] -**
  • [sqlite3changeset_old()] -**
-** -** It is the responsibility of the caller to eventually destroy the iterator -** by passing it to [sqlite3changeset_finalize()]. The buffer containing the -** changeset (pChangeset) must remain valid until after the iterator is -** destroyed. -** -** Assuming the changeset blob was created by one of the -** [sqlite3session_changeset()], [sqlite3changeset_concat()] or -** [sqlite3changeset_invert()] functions, all changes within the changeset -** that apply to a single table are grouped together. This means that when -** an application iterates through a changeset using an iterator created by -** this function, all changes that relate to a single table are visited -** consecutively. There is no chance that the iterator will visit a change -** the applies to table X, then one for table Y, and then later on visit -** another change for table X. -*/ -int sqlite3changeset_start( - sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ - int nChangeset, /* Size of changeset blob in bytes */ - void *pChangeset /* Pointer to blob containing changeset */ -); - - -/* -** CAPI3REF: Advance A Changeset Iterator -** -** This function may only be used with iterators created by function -** [sqlite3changeset_start()]. If it is called on an iterator passed to -** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE -** is returned and the call has no effect. -** -** Immediately after an iterator is created by sqlite3changeset_start(), it -** does not point to any change in the changeset. Assuming the changeset -** is not empty, the first call to this function advances the iterator to -** point to the first change in the changeset. Each subsequent call advances -** the iterator to point to the next change in the changeset (if any). If -** no error occurs and the iterator points to a valid change after a call -** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. -** Otherwise, if all changes in the changeset have already been visited, -** SQLITE_DONE is returned. -** -** If an error occurs, an SQLite error code is returned. Possible error -** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or -** SQLITE_NOMEM. -*/ -int sqlite3changeset_next(sqlite3_changeset_iter *pIter); - -/* -** CAPI3REF: Obtain The Current Operation From A Changeset Iterator -** -** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -** created by [sqlite3changeset_start()]. In the latter case, the most recent -** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this -** is not the case, this function returns [SQLITE_MISUSE]. -** -** If argument pzTab is not NULL, then *pzTab is set to point to a -** nul-terminated utf-8 encoded string containing the name of the table -** affected by the current change. The buffer remains valid until either -** sqlite3changeset_next() is called on the iterator or until the -** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. If -** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change -** is an indirect change, or false (0) otherwise. See the documentation for -** [sqlite3session_indirect()] for a description of direct and indirect -** changes. Finally, if pOp is not NULL, then *pOp is set to one of -** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the -** type of change that the iterator currently points to. -** -** If no error occurs, SQLITE_OK is returned. If an error does occur, an -** SQLite error code is returned. The values of the output variables may not -** be trusted in this case. -*/ -int sqlite3changeset_op( - sqlite3_changeset_iter *pIter, /* Iterator object */ - const char **pzTab, /* OUT: Pointer to table name */ - int *pnCol, /* OUT: Number of columns in table */ - int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ - int *pbIndirect /* OUT: True for an 'indirect' change */ -); - -/* -** CAPI3REF: Obtain The Primary Key Definition Of A Table -** -** For each modified table, a changeset includes the following: -** -**
    -**
  • The number of columns in the table, and -**
  • Which of those columns make up the tables PRIMARY KEY. -**
-** -** This function is used to find which columns comprise the PRIMARY KEY of -** the table modified by the change that iterator pIter currently points to. -** If successful, *pabPK is set to point to an array of nCol entries, where -** nCol is the number of columns in the table. Elements of *pabPK are set to -** 0x01 if the corresponding column is part of the tables primary key, or -** 0x00 if it is not. -** -** If argument pnCol is not NULL, then *pnCol is set to the number of columns -** in the table. -** -** If this function is called when the iterator does not point to a valid -** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise, -** SQLITE_OK is returned and the output variables populated as described -** above. -*/ -int sqlite3changeset_pk( - sqlite3_changeset_iter *pIter, /* Iterator object */ - unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ - int *pnCol /* OUT: Number of entries in output array */ -); - -/* -** CAPI3REF: Obtain old.* Values From A Changeset Iterator -** -** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -** created by [sqlite3changeset_start()]. In the latter case, the most recent -** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. -** Furthermore, it may only be called if the type of change that the iterator -** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise, -** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. -** -** Argument iVal must be greater than or equal to 0, and less than the number -** of columns in the table affected by the current change. Otherwise, -** [SQLITE_RANGE] is returned and *ppValue is set to NULL. -** -** If successful, this function sets *ppValue to point to a protected -** sqlite3_value object containing the iVal'th value from the vector of -** original row values stored as part of the UPDATE or DELETE change and -** returns SQLITE_OK. The name of the function comes from the fact that this -** is similar to the "old.*" columns available to update or delete triggers. -** -** If some other error occurs (e.g. an OOM condition), an SQLite error code -** is returned and *ppValue is set to NULL. -*/ -int sqlite3changeset_old( - sqlite3_changeset_iter *pIter, /* Changeset iterator */ - int iVal, /* Column number */ - sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ -); - -/* -** CAPI3REF: Obtain new.* Values From A Changeset Iterator -** -** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator -** created by [sqlite3changeset_start()]. In the latter case, the most recent -** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. -** Furthermore, it may only be called if the type of change that the iterator -** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise, -** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. -** -** Argument iVal must be greater than or equal to 0, and less than the number -** of columns in the table affected by the current change. Otherwise, -** [SQLITE_RANGE] is returned and *ppValue is set to NULL. -** -** If successful, this function sets *ppValue to point to a protected -** sqlite3_value object containing the iVal'th value from the vector of -** new row values stored as part of the UPDATE or INSERT change and -** returns SQLITE_OK. If the change is an UPDATE and does not include -** a new value for the requested column, *ppValue is set to NULL and -** SQLITE_OK returned. The name of the function comes from the fact that -** this is similar to the "new.*" columns available to update or delete -** triggers. -** -** If some other error occurs (e.g. an OOM condition), an SQLite error code -** is returned and *ppValue is set to NULL. -*/ -int sqlite3changeset_new( - sqlite3_changeset_iter *pIter, /* Changeset iterator */ - int iVal, /* Column number */ - sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ -); - -/* -** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator -** -** This function should only be used with iterator objects passed to a -** conflict-handler callback by [sqlite3changeset_apply()] with either -** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function -** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue -** is set to NULL. -** -** Argument iVal must be greater than or equal to 0, and less than the number -** of columns in the table affected by the current change. Otherwise, -** [SQLITE_RANGE] is returned and *ppValue is set to NULL. -** -** If successful, this function sets *ppValue to point to a protected -** sqlite3_value object containing the iVal'th value from the -** "conflicting row" associated with the current conflict-handler callback -** and returns SQLITE_OK. -** -** If some other error occurs (e.g. an OOM condition), an SQLite error code -** is returned and *ppValue is set to NULL. -*/ -int sqlite3changeset_conflict( - sqlite3_changeset_iter *pIter, /* Changeset iterator */ - int iVal, /* Column number */ - sqlite3_value **ppValue /* OUT: Value from conflicting row */ -); - -/* -** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations -** -** This function may only be called with an iterator passed to an -** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case -** it sets the output variable to the total number of known foreign key -** violations in the destination database and returns SQLITE_OK. -** -** In all other cases this function returns SQLITE_MISUSE. -*/ -int sqlite3changeset_fk_conflicts( - sqlite3_changeset_iter *pIter, /* Changeset iterator */ - int *pnOut /* OUT: Number of FK violations */ -); - - -/* -** CAPI3REF: Finalize A Changeset Iterator -** -** This function is used to finalize an iterator allocated with -** [sqlite3changeset_start()]. -** -** This function should only be called on iterators created using the -** [sqlite3changeset_start()] function. If an application calls this -** function with an iterator passed to a conflict-handler by -** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the -** call has no effect. -** -** If an error was encountered within a call to an sqlite3changeset_xxx() -** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an -** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding -** to that error is returned by this function. Otherwise, SQLITE_OK is -** returned. This is to allow the following pattern (pseudo-code): -** -** sqlite3changeset_start(); -** while( SQLITE_ROW==sqlite3changeset_next() ){ -** // Do something with change. -** } -** rc = sqlite3changeset_finalize(); -** if( rc!=SQLITE_OK ){ -** // An error has occurred -** } -*/ -int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); - -/* -** CAPI3REF: Invert A Changeset -** -** This function is used to "invert" a changeset object. Applying an inverted -** changeset to a database reverses the effects of applying the uninverted -** changeset. Specifically: -** -**
    -**
  • Each DELETE change is changed to an INSERT, and -**
  • Each INSERT change is changed to a DELETE, and -**
  • For each UPDATE change, the old.* and new.* values are exchanged. -**
-** -** This function does not change the order in which changes appear within -** the changeset. It merely reverses the sense of each individual change. -** -** If successful, a pointer to a buffer containing the inverted changeset -** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and -** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are -** zeroed and an SQLite error code returned. -** -** It is the responsibility of the caller to eventually call sqlite3_free() -** on the *ppOut pointer to free the buffer allocation following a successful -** call to this function. -** -** WARNING/TODO: This function currently assumes that the input is a valid -** changeset. If it is not, the results are undefined. -*/ -int sqlite3changeset_invert( - int nIn, const void *pIn, /* Input changeset */ - int *pnOut, void **ppOut /* OUT: Inverse of input */ -); - -/* -** CAPI3REF: Concatenate Two Changeset Objects -** -** This function is used to concatenate two changesets, A and B, into a -** single changeset. The result is a changeset equivalent to applying -** changeset A followed by changeset B. -** -** This function combines the two input changesets using an -** sqlite3_changegroup object. Calling it produces similar results as the -** following code fragment: -** -** sqlite3_changegroup *pGrp; -** rc = sqlite3_changegroup_new(&pGrp); -** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA); -** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB); -** if( rc==SQLITE_OK ){ -** rc = sqlite3changegroup_output(pGrp, pnOut, ppOut); -** }else{ -** *ppOut = 0; -** *pnOut = 0; -** } -** -** Refer to the sqlite3_changegroup documentation below for details. -*/ -int sqlite3changeset_concat( - int nA, /* Number of bytes in buffer pA */ - void *pA, /* Pointer to buffer containing changeset A */ - int nB, /* Number of bytes in buffer pB */ - void *pB, /* Pointer to buffer containing changeset B */ - int *pnOut, /* OUT: Number of bytes in output changeset */ - void **ppOut /* OUT: Buffer containing output changeset */ -); - - -/* -** CAPI3REF: Changegroup Handle -*/ -typedef struct sqlite3_changegroup sqlite3_changegroup; - -/* -** CAPI3REF: Create A New Changegroup Object -** -** An sqlite3_changegroup object is used to combine two or more changesets -** (or patchsets) into a single changeset (or patchset). A single changegroup -** object may combine changesets or patchsets, but not both. The output is -** always in the same format as the input. -** -** If successful, this function returns SQLITE_OK and populates (*pp) with -** a pointer to a new sqlite3_changegroup object before returning. The caller -** should eventually free the returned object using a call to -** sqlite3changegroup_delete(). If an error occurs, an SQLite error code -** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL. -** -** The usual usage pattern for an sqlite3_changegroup object is as follows: -** -**
    -**
  • It is created using a call to sqlite3changegroup_new(). -** -**
  • Zero or more changesets (or patchsets) are added to the object -** by calling sqlite3changegroup_add(). -** -**
  • The result of combining all input changesets together is obtained -** by the application via a call to sqlite3changegroup_output(). -** -**
  • The object is deleted using a call to sqlite3changegroup_delete(). -**
-** -** Any number of calls to add() and output() may be made between the calls to -** new() and delete(), and in any order. -** -** As well as the regular sqlite3changegroup_add() and -** sqlite3changegroup_output() functions, also available are the streaming -** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). -*/ -int sqlite3changegroup_new(sqlite3_changegroup **pp); - -/* -** CAPI3REF: Add A Changeset To A Changegroup -** -** Add all changes within the changeset (or patchset) in buffer pData (size -** nData bytes) to the changegroup. -** -** If the buffer contains a patchset, then all prior calls to this function -** on the same changegroup object must also have specified patchsets. Or, if -** the buffer contains a changeset, so must have the earlier calls to this -** function. Otherwise, SQLITE_ERROR is returned and no changes are added -** to the changegroup. -** -** Rows within the changeset and changegroup are identified by the values in -** their PRIMARY KEY columns. A change in the changeset is considered to -** apply to the same row as a change already present in the changegroup if -** the two rows have the same primary key. -** -** Changes to rows that do not already appear in the changegroup are -** simply copied into it. Or, if both the new changeset and the changegroup -** contain changes that apply to a single row, the final contents of the -** changegroup depends on the type of each change, as follows: -** -** -** -** -**
Existing Change New Change Output Change -**
INSERT INSERT -** The new change is ignored. This case does not occur if the new -** changeset was recorded immediately after the changesets already -** added to the changegroup. -**
INSERT UPDATE -** The INSERT change remains in the changegroup. The values in the -** INSERT change are modified as if the row was inserted by the -** existing change and then updated according to the new change. -**
INSERT DELETE -** The existing INSERT is removed from the changegroup. The DELETE is -** not added. -**
UPDATE INSERT -** The new change is ignored. This case does not occur if the new -** changeset was recorded immediately after the changesets already -** added to the changegroup. -**
UPDATE UPDATE -** The existing UPDATE remains within the changegroup. It is amended -** so that the accompanying values are as if the row was updated once -** by the existing change and then again by the new change. -**
UPDATE DELETE -** The existing UPDATE is replaced by the new DELETE within the -** changegroup. -**
DELETE INSERT -** If one or more of the column values in the row inserted by the -** new change differ from those in the row deleted by the existing -** change, the existing DELETE is replaced by an UPDATE within the -** changegroup. Otherwise, if the inserted row is exactly the same -** as the deleted row, the existing DELETE is simply discarded. -**
DELETE UPDATE -** The new change is ignored. This case does not occur if the new -** changeset was recorded immediately after the changesets already -** added to the changegroup. -**
DELETE DELETE -** The new change is ignored. This case does not occur if the new -** changeset was recorded immediately after the changesets already -** added to the changegroup. -**
-** -** If the new changeset contains changes to a table that is already present -** in the changegroup, then the number of columns and the position of the -** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. If the input changeset -** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is -** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the -** final contents of the changegroup is undefined. -** -** If no error occurs, SQLITE_OK is returned. -*/ -int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); - -/* -** CAPI3REF: Obtain A Composite Changeset From A Changegroup -** -** Obtain a buffer containing a changeset (or patchset) representing the -** current contents of the changegroup. If the inputs to the changegroup -** were themselves changesets, the output is a changeset. Or, if the -** inputs were patchsets, the output is also a patchset. -** -** As with the output of the sqlite3session_changeset() and -** sqlite3session_patchset() functions, all changes related to a single -** table are grouped together in the output of this function. Tables appear -** in the same order as for the very first changeset added to the changegroup. -** If the second or subsequent changesets added to the changegroup contain -** changes for tables that do not appear in the first changeset, they are -** appended onto the end of the output changeset, again in the order in -** which they are first encountered. -** -** If an error occurs, an SQLite error code is returned and the output -** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK -** is returned and the output variables are set to the size of and a -** pointer to the output buffer, respectively. In this case it is the -** responsibility of the caller to eventually free the buffer using a -** call to sqlite3_free(). -*/ -int sqlite3changegroup_output( - sqlite3_changegroup*, - int *pnData, /* OUT: Size of output buffer in bytes */ - void **ppData /* OUT: Pointer to output buffer */ -); - -/* -** CAPI3REF: Delete A Changegroup Object -*/ -void sqlite3changegroup_delete(sqlite3_changegroup*); - -/* -** CAPI3REF: Apply A Changeset To A Database -** -** Apply a changeset to a database. This function attempts to update the -** "main" database attached to handle db with the changes found in the -** changeset passed via the second and third arguments. -** -** The fourth argument (xFilter) passed to this function is the "filter -** callback". If it is not NULL, then for each table affected by at least one -** change in the changeset, the filter callback is invoked with -** the table name as the second argument, and a copy of the context pointer -** passed as the sixth argument to this function as the first. If the "filter -** callback" returns zero, then no attempt is made to apply any changes to -** the table. Otherwise, if the return value is non-zero or the xFilter -** argument to this function is NULL, all changes related to the table are -** attempted. -** -** For each table that is not excluded by the filter callback, this function -** tests that the target database contains a compatible table. A table is -** considered compatible if all of the following are true: -** -**
    -**
  • The table has the same name as the name recorded in the -** changeset, and -**
  • The table has the same number of columns as recorded in the -** changeset, and -**
  • The table has primary key columns in the same position as -** recorded in the changeset. -**
-** -** If there is no compatible table, it is not an error, but none of the -** changes associated with the table are applied. A warning message is issued -** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most -** one such warning is issued for each table in the changeset. -** -** For each change for which there is a compatible table, an attempt is made -** to modify the table contents according to the UPDATE, INSERT or DELETE -** change. If a change cannot be applied cleanly, the conflict handler -** function passed as the fifth argument to sqlite3changeset_apply() may be -** invoked. A description of exactly when the conflict handler is invoked for -** each type of change is below. -** -** Unlike the xFilter argument, xConflict may not be passed NULL. The results -** of passing anything other than a valid function pointer as the xConflict -** argument are undefined. -** -** Each time the conflict handler function is invoked, it must return one -** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or -** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned -** if the second argument passed to the conflict handler is either -** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler -** returns an illegal value, any changes already made are rolled back and -** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different -** actions are taken by sqlite3changeset_apply() depending on the value -** returned by each invocation of the conflict-handler function. Refer to -** the documentation for the three -** [SQLITE_CHANGESET_OMIT|available return values] for details. -** -**
-**
DELETE Changes
-** For each DELETE change, this function checks if the target database -** contains a row with the same primary key value (or values) as the -** original row values stored in the changeset. If it does, and the values -** stored in all non-primary key columns also match the values stored in -** the changeset the row is deleted from the target database. -** -** If a row with matching primary key values is found, but one or more of -** the non-primary key fields contains a value different from the original -** row value stored in the changeset, the conflict-handler function is -** invoked with [SQLITE_CHANGESET_DATA] as the second argument. -** -** If no row with matching primary key values is found in the database, -** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] -** passed as the second argument. -** -** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT -** (which can only happen if a foreign key constraint is violated), the -** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT] -** passed as the second argument. This includes the case where the DELETE -** operation is attempted because an earlier call to the conflict handler -** function returned [SQLITE_CHANGESET_REPLACE]. -** -**
INSERT Changes
-** For each INSERT change, an attempt is made to insert the new row into -** the database. -** -** If the attempt to insert the row fails because the database already -** contains a row with the same primary key values, the conflict handler -** function is invoked with the second argument set to -** [SQLITE_CHANGESET_CONFLICT]. -** -** If the attempt to insert the row fails because of some other constraint -** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is -** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT]. -** This includes the case where the INSERT operation is re-attempted because -** an earlier call to the conflict handler function returned -** [SQLITE_CHANGESET_REPLACE]. -** -**
UPDATE Changes
-** For each UPDATE change, this function checks if the target database -** contains a row with the same primary key value (or values) as the -** original row values stored in the changeset. If it does, and the values -** stored in all non-primary key columns also match the values stored in -** the changeset the row is updated within the target database. -** -** If a row with matching primary key values is found, but one or more of -** the non-primary key fields contains a value different from an original -** row value stored in the changeset, the conflict-handler function is -** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since -** UPDATE changes only contain values for non-primary key fields that are -** to be modified, only those fields need to match the original values to -** avoid the SQLITE_CHANGESET_DATA conflict-handler callback. -** -** If no row with matching primary key values is found in the database, -** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] -** passed as the second argument. -** -** If the UPDATE operation is attempted, but SQLite returns -** SQLITE_CONSTRAINT, the conflict-handler function is invoked with -** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument. -** This includes the case where the UPDATE operation is attempted after -** an earlier call to the conflict handler function returned -** [SQLITE_CHANGESET_REPLACE]. -**
-** -** It is safe to execute SQL statements, including those that write to the -** table that the callback related to, from within the xConflict callback. -** This can be used to further customize the applications conflict -** resolution strategy. -** -** All changes made by this function are enclosed in a savepoint transaction. -** If any other error (aside from a constraint failure when attempting to -** write to the target database) occurs, then the savepoint transaction is -** rolled back, restoring the target database to its original state, and an -** SQLite error code returned. -*/ -int sqlite3changeset_apply( - sqlite3 *db, /* Apply change to "main" db of this handle */ - int nChangeset, /* Size of changeset in bytes */ - void *pChangeset, /* Changeset blob */ - int(*xFilter)( - void *pCtx, /* Copy of sixth arg to _apply() */ - const char *zTab /* Table name */ - ), - int(*xConflict)( - void *pCtx, /* Copy of sixth arg to _apply() */ - int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - sqlite3_changeset_iter *p /* Handle describing change and conflict */ - ), - void *pCtx /* First argument passed to xConflict */ -); - -/* -** CAPI3REF: Constants Passed To The Conflict Handler -** -** Values that may be passed as the second argument to a conflict-handler. -** -**
-**
SQLITE_CHANGESET_DATA
-** The conflict handler is invoked with CHANGESET_DATA as the second argument -** when processing a DELETE or UPDATE change if a row with the required -** PRIMARY KEY fields is present in the database, but one or more other -** (non primary-key) fields modified by the update do not contain the -** expected "before" values. -** -** The conflicting row, in this case, is the database row with the matching -** primary key. -** -**
SQLITE_CHANGESET_NOTFOUND
-** The conflict handler is invoked with CHANGESET_NOTFOUND as the second -** argument when processing a DELETE or UPDATE change if a row with the -** required PRIMARY KEY fields is not present in the database. -** -** There is no conflicting row in this case. The results of invoking the -** sqlite3changeset_conflict() API are undefined. -** -**
SQLITE_CHANGESET_CONFLICT
-** CHANGESET_CONFLICT is passed as the second argument to the conflict -** handler while processing an INSERT change if the operation would result -** in duplicate primary key values. -** -** The conflicting row in this case is the database row with the matching -** primary key. -** -**
SQLITE_CHANGESET_FOREIGN_KEY
-** If foreign key handling is enabled, and applying a changeset leaves the -** database in a state containing foreign key violations, the conflict -** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument -** exactly once before the changeset is committed. If the conflict handler -** returns CHANGESET_OMIT, the changes, including those that caused the -** foreign key constraint violation, are committed. Or, if it returns -** CHANGESET_ABORT, the changeset is rolled back. -** -** No current or conflicting row information is provided. The only function -** it is possible to call on the supplied sqlite3_changeset_iter handle -** is sqlite3changeset_fk_conflicts(). -** -**
SQLITE_CHANGESET_CONSTRAINT
-** If any other constraint violation occurs while applying a change (i.e. -** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is -** invoked with CHANGESET_CONSTRAINT as the second argument. -** -** There is no conflicting row in this case. The results of invoking the -** sqlite3changeset_conflict() API are undefined. -** -**
-*/ -#define SQLITE_CHANGESET_DATA 1 -#define SQLITE_CHANGESET_NOTFOUND 2 -#define SQLITE_CHANGESET_CONFLICT 3 -#define SQLITE_CHANGESET_CONSTRAINT 4 -#define SQLITE_CHANGESET_FOREIGN_KEY 5 - -/* -** CAPI3REF: Constants Returned By The Conflict Handler -** -** A conflict handler callback must return one of the following three values. -** -**
-**
SQLITE_CHANGESET_OMIT
-** If a conflict handler returns this value no special action is taken. The -** change that caused the conflict is not applied. The session module -** continues to the next change in the changeset. -** -**
SQLITE_CHANGESET_REPLACE
-** This value may only be returned if the second argument to the conflict -** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this -** is not the case, any changes applied so far are rolled back and the -** call to sqlite3changeset_apply() returns SQLITE_MISUSE. -** -** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict -** handler, then the conflicting row is either updated or deleted, depending -** on the type of change. -** -** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict -** handler, then the conflicting row is removed from the database and a -** second attempt to apply the change is made. If this second attempt fails, -** the original row is restored to the database before continuing. -** -**
SQLITE_CHANGESET_ABORT
-** If this value is returned, any changes applied so far are rolled back -** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. -**
-*/ -#define SQLITE_CHANGESET_OMIT 0 -#define SQLITE_CHANGESET_REPLACE 1 -#define SQLITE_CHANGESET_ABORT 2 - -/* -** CAPI3REF: Streaming Versions of API functions. -** -** The six streaming API xxx_strm() functions serve similar purposes to the -** corresponding non-streaming API functions: -** -** -** -**
Streaming functionNon-streaming equivalent
sqlite3changeset_apply_str[sqlite3changeset_apply] -**
sqlite3changeset_concat_str[sqlite3changeset_concat] -**
sqlite3changeset_invert_str[sqlite3changeset_invert] -**
sqlite3changeset_start_str[sqlite3changeset_start] -**
sqlite3session_changeset_str[sqlite3session_changeset] -**
sqlite3session_patchset_str[sqlite3session_patchset] -**
-** -** Non-streaming functions that accept changesets (or patchsets) as input -** require that the entire changeset be stored in a single buffer in memory. -** Similarly, those that return a changeset or patchset do so by returning -** a pointer to a single large buffer allocated using sqlite3_malloc(). -** Normally this is convenient. However, if an application running in a -** low-memory environment is required to handle very large changesets, the -** large contiguous memory allocations required can become onerous. -** -** In order to avoid this problem, instead of a single large buffer, input -** is passed to a streaming API functions by way of a callback function that -** the sessions module invokes to incrementally request input data as it is -** required. In all cases, a pair of API function parameters such as -** -**
-**        int nChangeset,
-**        void *pChangeset,
-**  
-** -** Is replaced by: -** -**
-**        int (*xInput)(void *pIn, void *pData, int *pnData),
-**        void *pIn,
-**  
-** -** Each time the xInput callback is invoked by the sessions module, the first -** argument passed is a copy of the supplied pIn context pointer. The second -** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no -** error occurs the xInput method should copy up to (*pnData) bytes of data -** into the buffer and set (*pnData) to the actual number of bytes copied -** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) -** should be set to zero to indicate this. Or, if an error occurs, an SQLite -** error code should be returned. In all cases, if an xInput callback returns -** an error, all processing is abandoned and the streaming API function -** returns a copy of the error code to the caller. -** -** In the case of sqlite3changeset_start_strm(), the xInput callback may be -** invoked by the sessions module at any point during the lifetime of the -** iterator. If such an xInput callback returns an error, the iterator enters -** an error state, whereby all subsequent calls to iterator functions -** immediately fail with the same error code as returned by xInput. -** -** Similarly, streaming API functions that return changesets (or patchsets) -** return them in chunks by way of a callback function instead of via a -** pointer to a single large buffer. In this case, a pair of parameters such -** as: -** -**
-**        int *pnChangeset,
-**        void **ppChangeset,
-**  
-** -** Is replaced by: -** -**
-**        int (*xOutput)(void *pOut, const void *pData, int nData),
-**        void *pOut
-**  
-** -** The xOutput callback is invoked zero or more times to return data to -** the application. The first parameter passed to each call is a copy of the -** pOut pointer supplied by the application. The second parameter, pData, -** points to a buffer nData bytes in size containing the chunk of output -** data being returned. If the xOutput callback successfully processes the -** supplied data, it should return SQLITE_OK to indicate success. Otherwise, -** it should return some other SQLite error code. In this case processing -** is immediately abandoned and the streaming API function returns a copy -** of the xOutput error code to the application. -** -** The sessions module never invokes an xOutput callback with the third -** parameter set to a value less than or equal to zero. Other than this, -** no guarantees are made as to the size of the chunks of data returned. -*/ -int sqlite3changeset_apply_strm( - sqlite3 *db, /* Apply change to "main" db of this handle */ - int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ - void *pIn, /* First arg for xInput */ - int(*xFilter)( - void *pCtx, /* Copy of sixth arg to _apply() */ - const char *zTab /* Table name */ - ), - int(*xConflict)( - void *pCtx, /* Copy of sixth arg to _apply() */ - int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - sqlite3_changeset_iter *p /* Handle describing change and conflict */ - ), - void *pCtx /* First argument passed to xConflict */ -); -int sqlite3changeset_concat_strm( - int (*xInputA)(void *pIn, void *pData, int *pnData), - void *pInA, - int (*xInputB)(void *pIn, void *pData, int *pnData), - void *pInB, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); -int sqlite3changeset_invert_strm( - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); -int sqlite3changeset_start_strm( - sqlite3_changeset_iter **pp, - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn -); -int sqlite3session_changeset_strm( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); -int sqlite3session_patchset_strm( - sqlite3_session *pSession, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); -int sqlite3changegroup_add_strm(sqlite3_changegroup*, - int (*xInput)(void *pIn, void *pData, int *pnData), - void *pIn -); -int sqlite3changegroup_output_strm(sqlite3_changegroup*, - int (*xOutput)(void *pOut, const void *pData, int nData), - void *pOut -); - - -/* -** Make sure we can call this stuff from C++. -*/ -#if 0 -} -#endif - -#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */ - -/******** End of sqlite3session.h *********/ -/******** Begin file fts5.h *********/ -/* -** 2014 May 31 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** Interfaces to extend FTS5. Using the interfaces defined in this file, -** FTS5 may be extended with: -** -** * custom tokenizers, and -** * custom auxiliary functions. -*/ - - -#ifndef _FTS5_H -#define _FTS5_H - - -#if 0 -extern "C" { -#endif - -/************************************************************************* -** CUSTOM AUXILIARY FUNCTIONS -** -** Virtual table implementations may overload SQL functions by implementing -** the sqlite3_module.xFindFunction() method. -*/ - -typedef struct Fts5ExtensionApi Fts5ExtensionApi; -typedef struct Fts5Context Fts5Context; -typedef struct Fts5PhraseIter Fts5PhraseIter; - -typedef void (*fts5_extension_function)( - const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ - Fts5Context *pFts, /* First arg to pass to pApi functions */ - sqlite3_context *pCtx, /* Context for returning result/error */ - int nVal, /* Number of values in apVal[] array */ - sqlite3_value **apVal /* Array of trailing arguments */ -); - -struct Fts5PhraseIter { - const unsigned char *a; - const unsigned char *b; -}; - -/* -** EXTENSION API FUNCTIONS -** -** xUserData(pFts): -** Return a copy of the context pointer the extension function was -** registered with. -** -** xColumnTotalSize(pFts, iCol, pnToken): -** If parameter iCol is less than zero, set output variable *pnToken -** to the total number of tokens in the FTS5 table. Or, if iCol is -** non-negative but less than the number of columns in the table, return -** the total number of tokens in column iCol, considering all rows in -** the FTS5 table. -** -** If parameter iCol is greater than or equal to the number of columns -** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. -** an OOM condition or IO error), an appropriate SQLite error code is -** returned. -** -** xColumnCount(pFts): -** Return the number of columns in the table. -** -** xColumnSize(pFts, iCol, pnToken): -** If parameter iCol is less than zero, set output variable *pnToken -** to the total number of tokens in the current row. Or, if iCol is -** non-negative but less than the number of columns in the table, set -** *pnToken to the number of tokens in column iCol of the current row. -** -** If parameter iCol is greater than or equal to the number of columns -** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. -** an OOM condition or IO error), an appropriate SQLite error code is -** returned. -** -** This function may be quite inefficient if used with an FTS5 table -** created with the "columnsize=0" option. -** -** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer -** containing the text in utf-8 encoding, (*pn) is set to the size in bytes -** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, -** if an error occurs, an SQLite error code is returned and the final values -** of (*pz) and (*pn) are undefined. -** -** xPhraseCount: -** Returns the number of phrases in the current query expression. -** -** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. -** -** xInstCount: -** Set *pnInst to the total number of occurrences of all phrases within -** the query within the current row. Return SQLITE_OK if successful, or -** an error code (i.e. SQLITE_NOMEM) if an error occurs. -** -** This API can be quite slow if used with an FTS5 table created with the -** "detail=none" or "detail=column" option. If the FTS5 table is created -** with either "detail=none" or "detail=column" and "content=" option -** (i.e. if it is a contentless table), then this API always returns 0. -** -** xInst: -** Query for the details of phrase match iIdx within the current row. -** Phrase matches are numbered starting from zero, so the iIdx argument -** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). -** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol -** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. The exception is if the table was created -** with the offsets=0 option specified. In this case *piOff is always -** set to -1. -** -** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) -** if an error occurs. -** -** This API can be quite slow if used with an FTS5 table created with the -** "detail=none" or "detail=column" option. -** -** xRowid: -** Returns the rowid of the current row. -** -** xTokenize: -** Tokenize text using the tokenizer belonging to the FTS5 table. -** -** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback): -** This API function is used to query the FTS table for phrase iPhrase -** of the current query. Specifically, a query equivalent to: -** -** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid -** -** with $p set to a phrase equivalent to the phrase iPhrase of the -** current query is executed. Any column filter that applies to -** phrase iPhrase of the current query is included in $p. For each -** row visited, the callback function passed as the fourth argument -** is invoked. The context and API objects passed to the callback -** function may be used to access the properties of each matched row. -** Invoking Api.xUserData() returns a copy of the pointer passed as -** the third argument to pUserData. -** -** If the callback function returns any value other than SQLITE_OK, the -** query is abandoned and the xQueryPhrase function returns immediately. -** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. -** Otherwise, the error code is propagated upwards. -** -** If the query runs to completion without incident, SQLITE_OK is returned. -** Or, if some error occurs before the query completes or is aborted by -** the callback, an SQLite error code is returned. -** -** -** xSetAuxdata(pFts5, pAux, xDelete) -** -** Save the pointer passed as the second argument as the extension functions -** "auxiliary data". The pointer may then be retrieved by the current or any -** future invocation of the same fts5 extension function made as part of -** of the same MATCH query using the xGetAuxdata() API. -** -** Each extension function is allocated a single auxiliary data slot for -** each FTS query (MATCH expression). If the extension function is invoked -** more than once for a single FTS query, then all invocations share a -** single auxiliary data context. -** -** If there is already an auxiliary data pointer when this function is -** invoked, then it is replaced by the new pointer. If an xDelete callback -** was specified along with the original pointer, it is invoked at this -** point. -** -** The xDelete callback, if one is specified, is also invoked on the -** auxiliary data pointer after the FTS5 query has finished. -** -** If an error (e.g. an OOM condition) occurs within this function, an -** the auxiliary data is set to NULL and an error code returned. If the -** xDelete parameter was not NULL, it is invoked on the auxiliary data -** pointer before returning. -** -** -** xGetAuxdata(pFts5, bClear) -** -** Returns the current auxiliary data pointer for the fts5 extension -** function. See the xSetAuxdata() method for details. -** -** If the bClear argument is non-zero, then the auxiliary data is cleared -** (set to NULL) before this function returns. In this case the xDelete, -** if any, is not invoked. -** -** -** xRowCount(pFts5, pnRow) -** -** This function is used to retrieve the total number of rows in the table. -** In other words, the same value that would be returned by: -** -** SELECT count(*) FROM ftstable; -** -** xPhraseFirst() -** This function is used, along with type Fts5PhraseIter and the xPhraseNext -** method, to iterate through all instances of a single query phrase within -** the current row. This is the same information as is accessible via the -** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient -** to use, this API may be faster under some circumstances. To iterate -** through instances of phrase iPhrase, use the following code: -** -** Fts5PhraseIter iter; -** int iCol, iOff; -** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff); -** iCol>=0; -** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff) -** ){ -** // An instance of phrase iPhrase at offset iOff of column iCol -** } -** -** The Fts5PhraseIter structure is defined above. Applications should not -** modify this structure directly - it should only be used as shown above -** with the xPhraseFirst() and xPhraseNext() API methods (and by -** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below). -** -** This API can be quite slow if used with an FTS5 table created with the -** "detail=none" or "detail=column" option. If the FTS5 table is created -** with either "detail=none" or "detail=column" and "content=" option -** (i.e. if it is a contentless table), then this API always iterates -** through an empty set (all calls to xPhraseFirst() set iCol to -1). -** -** xPhraseNext() -** See xPhraseFirst above. -** -** xPhraseFirstColumn() -** This function and xPhraseNextColumn() are similar to the xPhraseFirst() -** and xPhraseNext() APIs described above. The difference is that instead -** of iterating through all instances of a phrase in the current row, these -** APIs are used to iterate through the set of columns in the current row -** that contain one or more instances of a specified phrase. For example: -** -** Fts5PhraseIter iter; -** int iCol; -** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol); -** iCol>=0; -** pApi->xPhraseNextColumn(pFts, &iter, &iCol) -** ){ -** // Column iCol contains at least one instance of phrase iPhrase -** } -** -** This API can be quite slow if used with an FTS5 table created with the -** "detail=none" option. If the FTS5 table is created with either -** "detail=none" "content=" option (i.e. if it is a contentless table), -** then this API always iterates through an empty set (all calls to -** xPhraseFirstColumn() set iCol to -1). -** -** The information accessed using this API and its companion -** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext -** (or xInst/xInstCount). The chief advantage of this API is that it is -** significantly more efficient than those alternatives when used with -** "detail=column" tables. -** -** xPhraseNextColumn() -** See xPhraseFirstColumn above. -*/ -struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ - - void *(*xUserData)(Fts5Context*); - - int (*xColumnCount)(Fts5Context*); - int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); - int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); - - int (*xTokenize)(Fts5Context*, - const char *pText, int nText, /* Text to tokenize */ - void *pCtx, /* Context passed to xToken() */ - int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ - ); - - int (*xPhraseCount)(Fts5Context*); - int (*xPhraseSize)(Fts5Context*, int iPhrase); - - int (*xInstCount)(Fts5Context*, int *pnInst); - int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); - - sqlite3_int64 (*xRowid)(Fts5Context*); - int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); - int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); - - int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData, - int(*)(const Fts5ExtensionApi*,Fts5Context*,void*) - ); - int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*)); - void *(*xGetAuxdata)(Fts5Context*, int bClear); - - int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*); - void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff); - - int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); - void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); -}; - -/* -** CUSTOM AUXILIARY FUNCTIONS -*************************************************************************/ - -/************************************************************************* -** CUSTOM TOKENIZERS -** -** Applications may also register custom tokenizer types. A tokenizer -** is registered by providing fts5 with a populated instance of the -** following structure. All structure methods must be defined, setting -** any member of the fts5_tokenizer struct to NULL leads to undefined -** behaviour. The structure methods are expected to function as follows: -** -** xCreate: -** This function is used to allocate and initialize a tokenizer instance. -** A tokenizer instance is required to actually tokenize text. -** -** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object -** was registered with FTS5 (the third argument to xCreateTokenizer()). -** The second and third arguments are an array of nul-terminated strings -** containing the tokenizer arguments, if any, specified following the -** tokenizer name as part of the CREATE VIRTUAL TABLE statement used -** to create the FTS5 table. -** -** The final argument is an output variable. If successful, (*ppOut) -** should be set to point to the new tokenizer handle and SQLITE_OK -** returned. If an error occurs, some value other than SQLITE_OK should -** be returned. In this case, fts5 assumes that the final value of *ppOut -** is undefined. -** -** xDelete: -** This function is invoked to delete a tokenizer handle previously -** allocated using xCreate(). Fts5 guarantees that this function will -** be invoked exactly once for each successful call to xCreate(). -** -** xTokenize: -** This function is expected to tokenize the nText byte string indicated -** by argument pText. pText may or may not be nul-terminated. The first -** argument passed to this function is a pointer to an Fts5Tokenizer object -** returned by an earlier call to xCreate(). -** -** The second argument indicates the reason that FTS5 is requesting -** tokenization of the supplied text. This is always one of the following -** four values: -** -**
  • FTS5_TOKENIZE_DOCUMENT - A document is being inserted into -** or removed from the FTS table. The tokenizer is being invoked to -** determine the set of tokens to add to (or delete from) the -** FTS index. -** -**
  • FTS5_TOKENIZE_QUERY - A MATCH query is being executed -** against the FTS index. The tokenizer is being called to tokenize -** a bareword or quoted string specified as part of the query. -** -**
  • (FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX) - Same as -** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is -** followed by a "*" character, indicating that the last token -** returned by the tokenizer will be treated as a token prefix. -** -**
  • FTS5_TOKENIZE_AUX - The tokenizer is being invoked to -** satisfy an fts5_api.xTokenize() request made by an auxiliary -** function. Or an fts5_api.xColumnSize() request made by the same -** on a columnsize=0 database. -**
-** -** For each token in the input string, the supplied callback xToken() must -** be invoked. The first argument to it should be a copy of the pointer -** passed as the second argument to xTokenize(). The third and fourth -** arguments are a pointer to a buffer containing the token text, and the -** size of the token in bytes. The 4th and 5th arguments are the byte offsets -** of the first byte of and first byte immediately following the text from -** which the token is derived within the input. -** -** The second argument passed to the xToken() callback ("tflags") should -** normally be set to 0. The exception is if the tokenizer supports -** synonyms. In this case see the discussion below for details. -** -** FTS5 assumes the xToken() callback is invoked for each token in the -** order that they occur within the input text. -** -** If an xToken() callback returns any value other than SQLITE_OK, then -** the tokenization should be abandoned and the xTokenize() method should -** immediately return a copy of the xToken() return value. Or, if the -** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, -** if an error occurs with the xTokenize() implementation itself, it -** may abandon the tokenization and return any error code other than -** SQLITE_OK or SQLITE_DONE. -** -** SYNONYM SUPPORT -** -** Custom tokenizers may also support synonyms. Consider a case in which a -** user wishes to query for a phrase such as "first place". Using the -** built-in tokenizers, the FTS5 query 'first + place' will match instances -** of "first place" within the document set, but not alternative forms -** such as "1st place". In some applications, it would be better to match -** all instances of "first place" or "1st place" regardless of which form -** the user specified in the MATCH query text. -** -** There are several ways to approach this in FTS5: -** -**
  1. By mapping all synonyms to a single token. In this case, the -** In the above example, this means that the tokenizer returns the -** same token for inputs "first" and "1st". Say that token is in -** fact "first", so that when the user inserts the document "I won -** 1st place" entries are added to the index for tokens "i", "won", -** "first" and "place". If the user then queries for '1st + place', -** the tokenizer substitutes "first" for "1st" and the query works -** as expected. -** -**
  2. By adding multiple synonyms for a single term to the FTS index. -** In this case, when tokenizing query text, the tokenizer may -** provide multiple synonyms for a single term within the document. -** FTS5 then queries the index for each synonym individually. For -** example, faced with the query: -** -** -** ... MATCH 'first place' -** -** the tokenizer offers both "1st" and "first" as synonyms for the -** first token in the MATCH query and FTS5 effectively runs a query -** similar to: -** -** -** ... MATCH '(first OR 1st) place' -** -** except that, for the purposes of auxiliary functions, the query -** still appears to contain just two phrases - "(first OR 1st)" -** being treated as a single phrase. -** -**
  3. By adding multiple synonyms for a single term to the FTS index. -** Using this method, when tokenizing document text, the tokenizer -** provides multiple synonyms for each token. So that when a -** document such as "I won first place" is tokenized, entries are -** added to the FTS index for "i", "won", "first", "1st" and -** "place". -** -** This way, even if the tokenizer does not provide synonyms -** when tokenizing query text (it should not - to do would be -** inefficient), it doesn't matter if the user queries for -** 'first + place' or '1st + place', as there are entires in the -** FTS index corresponding to both forms of the first token. -**
-** -** Whether it is parsing document or query text, any call to xToken that -** specifies a tflags argument with the FTS5_TOKEN_COLOCATED bit -** is considered to supply a synonym for the previous token. For example, -** when parsing the document "I won first place", a tokenizer that supports -** synonyms would call xToken() 5 times, as follows: -** -** -** xToken(pCtx, 0, "i", 1, 0, 1); -** xToken(pCtx, 0, "won", 3, 2, 5); -** xToken(pCtx, 0, "first", 5, 6, 11); -** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11); -** xToken(pCtx, 0, "place", 5, 12, 17); -** -** -** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time -** xToken() is called. Multiple synonyms may be specified for a single token -** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. -** There is no limit to the number of synonyms that may be provided for a -** single token. -** -** In many cases, method (1) above is the best approach. It does not add -** extra data to the FTS index or require FTS5 to query for multiple terms, -** so it is efficient in terms of disk space and query speed. However, it -** does not support prefix queries very well. If, as suggested above, the -** token "first" is subsituted for "1st" by the tokenizer, then the query: -** -** -** ... MATCH '1s*' -** -** will not match documents that contain the token "1st" (as the tokenizer -** will probably not map "1s" to any prefix of "first"). -** -** For full prefix support, method (3) may be preferred. In this case, -** because the index contains entries for both "first" and "1st", prefix -** queries such as 'fi*' or '1s*' will match correctly. However, because -** extra entries are added to the FTS index, this method uses more space -** within the database. -** -** Method (2) offers a midpoint between (1) and (3). Using this method, -** a query such as '1s*' will match documents that contain the literal -** token "1st", but not "first" (assuming the tokenizer is not able to -** provide synonyms for prefixes). However, a non-prefix query like '1st' -** will match against "1st" and "first". This method does not require -** extra disk space, as no extra entries are added to the FTS index. -** On the other hand, it may require more CPU cycles to run MATCH queries, -** as separate queries of the FTS index are required for each synonym. -** -** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (2)) or query -** text (method (3)), not both. Doing so will not cause any errors, but is -** inefficient. -*/ -typedef struct Fts5Tokenizer Fts5Tokenizer; -typedef struct fts5_tokenizer fts5_tokenizer; -struct fts5_tokenizer { - int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); - void (*xDelete)(Fts5Tokenizer*); - int (*xTokenize)(Fts5Tokenizer*, - void *pCtx, - int flags, /* Mask of FTS5_TOKENIZE_* flags */ - const char *pText, int nText, - int (*xToken)( - void *pCtx, /* Copy of 2nd argument to xTokenize() */ - int tflags, /* Mask of FTS5_TOKEN_* flags */ - const char *pToken, /* Pointer to buffer containing token */ - int nToken, /* Size of token in bytes */ - int iStart, /* Byte offset of token within input text */ - int iEnd /* Byte offset of end of token within input text */ - ) - ); -}; - -/* Flags that may be passed as the third argument to xTokenize() */ -#define FTS5_TOKENIZE_QUERY 0x0001 -#define FTS5_TOKENIZE_PREFIX 0x0002 -#define FTS5_TOKENIZE_DOCUMENT 0x0004 -#define FTS5_TOKENIZE_AUX 0x0008 - -/* Flags that may be passed by the tokenizer implementation back to FTS5 -** as the third argument to the supplied xToken callback. */ -#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ - -/* -** END OF CUSTOM TOKENIZERS -*************************************************************************/ - -/************************************************************************* -** FTS5 EXTENSION REGISTRATION API -*/ -typedef struct fts5_api fts5_api; -struct fts5_api { - int iVersion; /* Currently always set to 2 */ - - /* Create a new tokenizer */ - int (*xCreateTokenizer)( - fts5_api *pApi, - const char *zName, - void *pContext, - fts5_tokenizer *pTokenizer, - void (*xDestroy)(void*) - ); - - /* Find an existing tokenizer */ - int (*xFindTokenizer)( - fts5_api *pApi, - const char *zName, - void **ppContext, - fts5_tokenizer *pTokenizer - ); - - /* Create a new auxiliary function */ - int (*xCreateFunction)( - fts5_api *pApi, - const char *zName, - void *pContext, - fts5_extension_function xFunction, - void (*xDestroy)(void*) - ); -}; - -/* -** END OF REGISTRATION API -*************************************************************************/ - -#if 0 -} /* end of the 'extern "C"' block */ -#endif - -#endif /* _FTS5_H */ - -/******** End of fts5.h *********/ - -/************** End of sqlite3.h *********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* -** Include the configuration header output by 'configure' if we're using the -** autoconf-based build -*/ -#ifdef _HAVE_SQLITE_CONFIG_H -#include "config.h" -#endif - -/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ -/************** Begin file sqliteLimit.h *************************************/ -/* -** 2007 May 7 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file defines various limits of what SQLite can process. -*/ - -/* -** The maximum length of a TEXT or BLOB in bytes. This also -** limits the size of a row in a table or index. -** -** The hard limit is the ability of a 32-bit signed integer -** to count the size: 2^31-1 or 2147483647. -*/ -#ifndef SQLITE_MAX_LENGTH -# define SQLITE_MAX_LENGTH 1000000000 -#endif - -/* -** This is the maximum number of -** -** * Columns in a table -** * Columns in an index -** * Columns in a view -** * Terms in the SET clause of an UPDATE statement -** * Terms in the result set of a SELECT statement -** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. -** * Terms in the VALUES clause of an INSERT statement -** -** The hard upper limit here is 32676. Most database people will -** tell you that in a well-normalized database, you usually should -** not have more than a dozen or so columns in any table. And if -** that is the case, there is no point in having more than a few -** dozen values in any of the other situations described above. -*/ -#ifndef SQLITE_MAX_COLUMN -# define SQLITE_MAX_COLUMN 2000 -#endif - -/* -** The maximum length of a single SQL statement in bytes. -** -** It used to be the case that setting this value to zero would -** turn the limit off. That is no longer true. It is not possible -** to turn this limit off. -*/ -#ifndef SQLITE_MAX_SQL_LENGTH -# define SQLITE_MAX_SQL_LENGTH 1000000000 -#endif - -/* -** The maximum depth of an expression tree. This is limited to -** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might -** want to place more severe limits on the complexity of an -** expression. -** -** A value of 0 used to mean that the limit was not enforced. -** But that is no longer true. The limit is now strictly enforced -** at all times. -*/ -#ifndef SQLITE_MAX_EXPR_DEPTH -# define SQLITE_MAX_EXPR_DEPTH 1000 -#endif - -/* -** The maximum number of terms in a compound SELECT statement. -** The code generator for compound SELECT statements does one -** level of recursion for each term. A stack overflow can result -** if the number of terms is too large. In practice, most SQL -** never has more than 3 or 4 terms. Use a value of 0 to disable -** any limit on the number of terms in a compount SELECT. -*/ -#ifndef SQLITE_MAX_COMPOUND_SELECT -# define SQLITE_MAX_COMPOUND_SELECT 500 -#endif - -/* -** The maximum number of opcodes in a VDBE program. -** Not currently enforced. -*/ -#ifndef SQLITE_MAX_VDBE_OP -# define SQLITE_MAX_VDBE_OP 25000 -#endif - -/* -** The maximum number of arguments to an SQL function. -*/ -#ifndef SQLITE_MAX_FUNCTION_ARG -# define SQLITE_MAX_FUNCTION_ARG 127 -#endif - -/* -** The suggested maximum number of in-memory pages to use for -** the main database table and for temporary tables. -** -** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, -** which means the cache size is limited to 2048000 bytes of memory. -** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be -** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. -*/ -#ifndef SQLITE_DEFAULT_CACHE_SIZE -# define SQLITE_DEFAULT_CACHE_SIZE -2000 -#endif - -/* -** The default number of frames to accumulate in the log file before -** checkpointing the database in WAL mode. -*/ -#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT -# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 -#endif - -/* -** The maximum number of attached databases. This must be between 0 -** and 125. The upper bound of 125 is because the attached databases are -** counted using a signed 8-bit integer which has a maximum value of 127 -** and we have to allow 2 extra counts for the "main" and "temp" databases. -*/ -#ifndef SQLITE_MAX_ATTACHED -# define SQLITE_MAX_ATTACHED 10 -#endif - - -/* -** The maximum value of a ?nnn wildcard that the parser will accept. -*/ -#ifndef SQLITE_MAX_VARIABLE_NUMBER -# define SQLITE_MAX_VARIABLE_NUMBER 999 -#endif - -/* Maximum page size. The upper bound on this value is 65536. This a limit -** imposed by the use of 16-bit offsets within each page. -** -** Earlier versions of SQLite allowed the user to change this value at -** compile time. This is no longer permitted, on the grounds that it creates -** a library that is technically incompatible with an SQLite library -** compiled with a different limit. If a process operating on a database -** with a page-size of 65536 bytes crashes, then an instance of SQLite -** compiled with the default page-size limit will not be able to rollback -** the aborted transaction. This could lead to database corruption. -*/ -#ifdef SQLITE_MAX_PAGE_SIZE -# undef SQLITE_MAX_PAGE_SIZE -#endif -#define SQLITE_MAX_PAGE_SIZE 65536 - - -/* -** The default size of a database page. -*/ -#ifndef SQLITE_DEFAULT_PAGE_SIZE -# define SQLITE_DEFAULT_PAGE_SIZE 4096 -#endif -#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE -# undef SQLITE_DEFAULT_PAGE_SIZE -# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE -#endif - -/* -** Ordinarily, if no value is explicitly provided, SQLite creates databases -** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain -** device characteristics (sector-size and atomic write() support), -** SQLite may choose a larger value. This constant is the maximum value -** SQLite will choose on its own. -*/ -#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE -# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 -#endif -#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE -# undef SQLITE_MAX_DEFAULT_PAGE_SIZE -# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE -#endif - - -/* -** Maximum number of pages in one database file. -** -** This is really just the default value for the max_page_count pragma. -** This value can be lowered (or raised) at run-time using that the -** max_page_count macro. -*/ -#ifndef SQLITE_MAX_PAGE_COUNT -# define SQLITE_MAX_PAGE_COUNT 1073741823 -#endif - -/* -** Maximum length (in bytes) of the pattern in a LIKE or GLOB -** operator. -*/ -#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH -# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 -#endif - -/* -** Maximum depth of recursion for triggers. -** -** A value of 1 means that a trigger program will not be able to itself -** fire any triggers. A value of 0 means that no trigger programs at all -** may be executed. -*/ -#ifndef SQLITE_MAX_TRIGGER_DEPTH -# define SQLITE_MAX_TRIGGER_DEPTH 1000 -#endif - -/************** End of sqliteLimit.h *****************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* Disable nuisance warnings on Borland compilers */ -#if defined(__BORLANDC__) -#pragma warn -rch /* unreachable code */ -#pragma warn -ccc /* Condition is always true or false */ -#pragma warn -aus /* Assigned value is never used */ -#pragma warn -csu /* Comparing signed and unsigned */ -#pragma warn -spa /* Suspicious pointer arithmetic */ -#endif - -/* -** Include standard header files as necessary -*/ -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif - -/* -** The following macros are used to cast pointers to integers and -** integers to pointers. The way you do this varies from one compiler -** to the next, so we have developed the following set of #if statements -** to generate appropriate macros for a wide range of compilers. -** -** The correct "ANSI" way to do this is to use the intptr_t type. -** Unfortunately, that typedef is not available on all compilers, or -** if it is available, it requires an #include of specific headers -** that vary from one machine to the next. -** -** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on -** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). -** So we have to define the macros in different ways depending on the -** compiler. -*/ -#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ -# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) -# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) -#elif !defined(__GNUC__) /* Works for compilers other than LLVM */ -# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) -# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) -#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ -# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) -# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) -#else /* Generates a warning - but it always works */ -# define SQLITE_INT_TO_PTR(X) ((void*)(X)) -# define SQLITE_PTR_TO_INT(X) ((int)(X)) -#endif - -/* -** A macro to hint to the compiler that a function should not be -** inlined. -*/ -#if defined(__GNUC__) -# define SQLITE_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) && _MSC_VER>=1310 -# define SQLITE_NOINLINE __declspec(noinline) -#else -# define SQLITE_NOINLINE -#endif - -/* -** Make sure that the compiler intrinsics we desire are enabled when -** compiling with an appropriate version of MSVC unless prevented by -** the SQLITE_DISABLE_INTRINSIC define. -*/ -#if !defined(SQLITE_DISABLE_INTRINSIC) -# if defined(_MSC_VER) && _MSC_VER>=1400 -# if !defined(_WIN32_WCE) -# include -# pragma intrinsic(_byteswap_ushort) -# pragma intrinsic(_byteswap_ulong) -# pragma intrinsic(_ReadWriteBarrier) -# else -# include -# endif -# endif -#endif - -/* -** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. -** 0 means mutexes are permanently disable and the library is never -** threadsafe. 1 means the library is serialized which is the highest -** level of threadsafety. 2 means the library is multithreaded - multiple -** threads can use SQLite as long as no two threads try to use the same -** database connection at the same time. -** -** Older versions of SQLite used an optional THREADSAFE macro. -** We support that for legacy. -*/ -#if !defined(SQLITE_THREADSAFE) -# if defined(THREADSAFE) -# define SQLITE_THREADSAFE THREADSAFE -# else -# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ -# endif -#endif - -/* -** Powersafe overwrite is on by default. But can be turned off using -** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. -*/ -#ifndef SQLITE_POWERSAFE_OVERWRITE -# define SQLITE_POWERSAFE_OVERWRITE 1 -#endif - -/* -** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by -** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in -** which case memory allocation statistics are disabled by default. -*/ -#if !defined(SQLITE_DEFAULT_MEMSTATUS) -# define SQLITE_DEFAULT_MEMSTATUS 1 -#endif - -/* -** Exactly one of the following macros must be defined in order to -** specify which memory allocation subsystem to use. -** -** SQLITE_SYSTEM_MALLOC // Use normal system malloc() -** SQLITE_WIN32_MALLOC // Use Win32 native heap API -** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails -** SQLITE_MEMDEBUG // Debugging version of system malloc() -** -** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the -** assert() macro is enabled, each call into the Win32 native heap subsystem -** will cause HeapValidate to be called. If heap validation should fail, an -** assertion will be triggered. -** -** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as -** the default. -*/ -#if defined(SQLITE_SYSTEM_MALLOC) \ - + defined(SQLITE_WIN32_MALLOC) \ - + defined(SQLITE_ZERO_MALLOC) \ - + defined(SQLITE_MEMDEBUG)>1 -# error "Two or more of the following compile-time configuration options\ - are defined but at most one is allowed:\ - SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\ - SQLITE_ZERO_MALLOC" -#endif -#if defined(SQLITE_SYSTEM_MALLOC) \ - + defined(SQLITE_WIN32_MALLOC) \ - + defined(SQLITE_ZERO_MALLOC) \ - + defined(SQLITE_MEMDEBUG)==0 -# define SQLITE_SYSTEM_MALLOC 1 -#endif - -/* -** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the -** sizes of memory allocations below this value where possible. -*/ -#if !defined(SQLITE_MALLOC_SOFT_LIMIT) -# define SQLITE_MALLOC_SOFT_LIMIT 1024 -#endif - -/* -** We need to define _XOPEN_SOURCE as follows in order to enable -** recursive mutexes on most Unix systems and fchmod() on OpenBSD. -** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit -** it. -*/ -#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) -# define _XOPEN_SOURCE 600 -#endif - -/* -** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that -** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, -** make it true by defining or undefining NDEBUG. -** -** Setting NDEBUG makes the code smaller and faster by disabling the -** assert() statements in the code. So we want the default action -** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG -** is set. Thus NDEBUG becomes an opt-in rather than an opt-out -** feature. -*/ -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif -#if defined(NDEBUG) && defined(SQLITE_DEBUG) -# undef NDEBUG -#endif - -/* -** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on. -*/ -#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG) -# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 -#endif - -/* -** The testcase() macro is used to aid in coverage testing. When -** doing coverage testing, the condition inside the argument to -** testcase() must be evaluated both true and false in order to -** get full branch coverage. The testcase() macro is inserted -** to help ensure adequate test coverage in places where simple -** condition/decision coverage is inadequate. For example, testcase() -** can be used to make sure boundary values are tested. For -** bitmask tests, testcase() can be used to make sure each bit -** is significant and used at least once. On switch statements -** where multiple cases go to the same block of code, testcase() -** can insure that all cases are evaluated. -** -*/ -#ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void sqlite3Coverage(int); -# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } -#else -# define testcase(X) -#endif - -/* -** The TESTONLY macro is used to enclose variable declarations or -** other bits of code that are needed to support the arguments -** within testcase() and assert() macros. -*/ -#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) -# define TESTONLY(X) X -#else -# define TESTONLY(X) -#endif - -/* -** Sometimes we need a small amount of code such as a variable initialization -** to setup for a later assert() statement. We do not want this code to -** appear when assert() is disabled. The following macro is therefore -** used to contain that setup code. The "VVA" acronym stands for -** "Verification, Validation, and Accreditation". In other words, the -** code within VVA_ONLY() will only run during verification processes. -*/ -#ifndef NDEBUG -# define VVA_ONLY(X) X -#else -# define VVA_ONLY(X) -#endif - -/* -** The ALWAYS and NEVER macros surround boolean expressions which -** are intended to always be true or false, respectively. Such -** expressions could be omitted from the code completely. But they -** are included in a few cases in order to enhance the resilience -** of SQLite to unexpected behavior - to make the code "self-healing" -** or "ductile" rather than being "brittle" and crashing at the first -** hint of unplanned behavior. -** -** In other words, ALWAYS and NEVER are added for defensive code. -** -** When doing coverage testing ALWAYS and NEVER are hard-coded to -** be true and false so that the unreachable code they specify will -** not be counted as untested code. -*/ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) -# define ALWAYS(X) (1) -# define NEVER(X) (0) -#elif !defined(NDEBUG) -# define ALWAYS(X) ((X)?1:(assert(0),0)) -# define NEVER(X) ((X)?(assert(0),1):0) -#else -# define ALWAYS(X) (X) -# define NEVER(X) (X) -#endif - -/* -** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is -** defined. We need to defend against those failures when testing with -** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches -** during a normal build. The following macro can be used to disable tests -** that are always false except when SQLITE_TEST_REALLOC_STRESS is set. -*/ -#if defined(SQLITE_TEST_REALLOC_STRESS) -# define ONLY_IF_REALLOC_STRESS(X) (X) -#elif !defined(NDEBUG) -# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0) -#else -# define ONLY_IF_REALLOC_STRESS(X) (0) -#endif - -/* -** Declarations used for tracing the operating system interfaces. -*/ -#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ - (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) - extern int sqlite3OSTrace; -# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X -# define SQLITE_HAVE_OS_TRACE -#else -# define OSTRACE(X) -# undef SQLITE_HAVE_OS_TRACE -#endif - -/* -** Is the sqlite3ErrName() function needed in the build? Currently, -** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when -** OSTRACE is enabled), and by several "test*.c" files (which are -** compiled using SQLITE_TEST). -*/ -#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \ - (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) -# define SQLITE_NEED_ERR_NAME -#else -# undef SQLITE_NEED_ERR_NAME -#endif - -/* -** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN -*/ -#ifdef SQLITE_OMIT_EXPLAIN -# undef SQLITE_ENABLE_EXPLAIN_COMMENTS -#endif - -/* -** Return true (non-zero) if the input is an integer that is too large -** to fit in 32-bits. This macro is used inside of various testcase() -** macros to verify that we have tested SQLite for large-file support. -*/ -#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) - -/* -** The macro unlikely() is a hint that surrounds a boolean -** expression that is usually false. Macro likely() surrounds -** a boolean expression that is usually true. These hints could, -** in theory, be used by the compiler to generate better code, but -** currently they are just comments for human readers. -*/ -#define likely(X) (X) -#define unlikely(X) (X) - -/************** Include hash.h in the middle of sqliteInt.h ******************/ -/************** Begin file hash.h ********************************************/ -/* -** 2001 September 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This is the header file for the generic hash-table implementation -** used in SQLite. -*/ -#ifndef SQLITE_HASH_H -#define SQLITE_HASH_H - -/* Forward declarations of structures. */ -typedef struct Hash Hash; -typedef struct HashElem HashElem; - -/* A complete hash table is an instance of the following structure. -** The internals of this structure are intended to be opaque -- client -** code should not attempt to access or modify the fields of this structure -** directly. Change this structure only by using the routines below. -** However, some of the "procedures" and "functions" for modifying and -** accessing this structure are really macros, so we can't really make -** this structure opaque. -** -** All elements of the hash table are on a single doubly-linked list. -** Hash.first points to the head of this list. -** -** There are Hash.htsize buckets. Each bucket points to a spot in -** the global doubly-linked list. The contents of the bucket are the -** element pointed to plus the next _ht.count-1 elements in the list. -** -** Hash.htsize and Hash.ht may be zero. In that case lookup is done -** by a linear search of the global list. For small tables, the -** Hash.ht table is never allocated because if there are few elements -** in the table, it is faster to do a linear search than to manage -** the hash table. -*/ -struct Hash { - unsigned int htsize; /* Number of buckets in the hash table */ - unsigned int count; /* Number of entries in this table */ - HashElem *first; /* The first element of the array */ - struct _ht { /* the hash table */ - int count; /* Number of entries with this hash */ - HashElem *chain; /* Pointer to first entry with this hash */ - } *ht; -}; - -/* Each element in the hash table is an instance of the following -** structure. All elements are stored on a single doubly-linked list. -** -** Again, this structure is intended to be opaque, but it can't really -** be opaque because it is used by macros. -*/ -struct HashElem { - HashElem *next, *prev; /* Next and previous elements in the table */ - void *data; /* Data associated with this element */ - const char *pKey; /* Key associated with this element */ -}; - -/* -** Access routines. To delete, insert a NULL pointer. -*/ -SQLITE_PRIVATE void sqlite3HashInit(Hash*); -SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); -SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey); -SQLITE_PRIVATE void sqlite3HashClear(Hash*); - -/* -** Macros for looping over all elements of a hash table. The idiom is -** like this: -** -** Hash h; -** HashElem *p; -** ... -** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ -** SomeStructure *pData = sqliteHashData(p); -** // do something with pData -** } -*/ -#define sqliteHashFirst(H) ((H)->first) -#define sqliteHashNext(E) ((E)->next) -#define sqliteHashData(E) ((E)->data) -/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ -/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ - -/* -** Number of entries in a hash table -*/ -/* #define sqliteHashCount(H) ((H)->count) // NOT USED */ - -#endif /* SQLITE_HASH_H */ - -/************** End of hash.h ************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include parse.h in the middle of sqliteInt.h *****************/ -/************** Begin file parse.h *******************************************/ -#define TK_SEMI 1 -#define TK_EXPLAIN 2 -#define TK_QUERY 3 -#define TK_PLAN 4 -#define TK_BEGIN 5 -#define TK_TRANSACTION 6 -#define TK_DEFERRED 7 -#define TK_IMMEDIATE 8 -#define TK_EXCLUSIVE 9 -#define TK_COMMIT 10 -#define TK_END 11 -#define TK_ROLLBACK 12 -#define TK_SAVEPOINT 13 -#define TK_RELEASE 14 -#define TK_TO 15 -#define TK_TABLE 16 -#define TK_CREATE 17 -#define TK_IF 18 -#define TK_NOT 19 -#define TK_EXISTS 20 -#define TK_TEMP 21 -#define TK_LP 22 -#define TK_RP 23 -#define TK_AS 24 -#define TK_WITHOUT 25 -#define TK_COMMA 26 -#define TK_OR 27 -#define TK_AND 28 -#define TK_IS 29 -#define TK_MATCH 30 -#define TK_LIKE_KW 31 -#define TK_BETWEEN 32 -#define TK_IN 33 -#define TK_ISNULL 34 -#define TK_NOTNULL 35 -#define TK_NE 36 -#define TK_EQ 37 -#define TK_GT 38 -#define TK_LE 39 -#define TK_LT 40 -#define TK_GE 41 -#define TK_ESCAPE 42 -#define TK_BITAND 43 -#define TK_BITOR 44 -#define TK_LSHIFT 45 -#define TK_RSHIFT 46 -#define TK_PLUS 47 -#define TK_MINUS 48 -#define TK_STAR 49 -#define TK_SLASH 50 -#define TK_REM 51 -#define TK_CONCAT 52 -#define TK_COLLATE 53 -#define TK_BITNOT 54 -#define TK_ID 55 -#define TK_INDEXED 56 -#define TK_ABORT 57 -#define TK_ACTION 58 -#define TK_AFTER 59 -#define TK_ANALYZE 60 -#define TK_ASC 61 -#define TK_ATTACH 62 -#define TK_BEFORE 63 -#define TK_BY 64 -#define TK_CASCADE 65 -#define TK_CAST 66 -#define TK_COLUMNKW 67 -#define TK_CONFLICT 68 -#define TK_DATABASE 69 -#define TK_DESC 70 -#define TK_DETACH 71 -#define TK_EACH 72 -#define TK_FAIL 73 -#define TK_FOR 74 -#define TK_IGNORE 75 -#define TK_INITIALLY 76 -#define TK_INSTEAD 77 -#define TK_NO 78 -#define TK_KEY 79 -#define TK_OF 80 -#define TK_OFFSET 81 -#define TK_PRAGMA 82 -#define TK_RAISE 83 -#define TK_RECURSIVE 84 -#define TK_REPLACE 85 -#define TK_RESTRICT 86 -#define TK_ROW 87 -#define TK_TRIGGER 88 -#define TK_VACUUM 89 -#define TK_VIEW 90 -#define TK_VIRTUAL 91 -#define TK_WITH 92 -#define TK_REINDEX 93 -#define TK_RENAME 94 -#define TK_CTIME_KW 95 -#define TK_ANY 96 -#define TK_STRING 97 -#define TK_JOIN_KW 98 -#define TK_CONSTRAINT 99 -#define TK_DEFAULT 100 -#define TK_NULL 101 -#define TK_PRIMARY 102 -#define TK_UNIQUE 103 -#define TK_CHECK 104 -#define TK_REFERENCES 105 -#define TK_AUTOINCR 106 -#define TK_ON 107 -#define TK_INSERT 108 -#define TK_DELETE 109 -#define TK_UPDATE 110 -#define TK_SET 111 -#define TK_DEFERRABLE 112 -#define TK_FOREIGN 113 -#define TK_DROP 114 -#define TK_UNION 115 -#define TK_ALL 116 -#define TK_EXCEPT 117 -#define TK_INTERSECT 118 -#define TK_SELECT 119 -#define TK_VALUES 120 -#define TK_DISTINCT 121 -#define TK_DOT 122 -#define TK_FROM 123 -#define TK_JOIN 124 -#define TK_USING 125 -#define TK_ORDER 126 -#define TK_GROUP 127 -#define TK_HAVING 128 -#define TK_LIMIT 129 -#define TK_WHERE 130 -#define TK_INTO 131 -#define TK_FLOAT 132 -#define TK_BLOB 133 -#define TK_INTEGER 134 -#define TK_VARIABLE 135 -#define TK_CASE 136 -#define TK_WHEN 137 -#define TK_THEN 138 -#define TK_ELSE 139 -#define TK_INDEX 140 -#define TK_ALTER 141 -#define TK_ADD 142 -#define TK_TO_TEXT 143 -#define TK_TO_BLOB 144 -#define TK_TO_NUMERIC 145 -#define TK_TO_INT 146 -#define TK_TO_REAL 147 -#define TK_ISNOT 148 -#define TK_END_OF_FILE 149 -#define TK_UNCLOSED_STRING 150 -#define TK_FUNCTION 151 -#define TK_COLUMN 152 -#define TK_AGG_FUNCTION 153 -#define TK_AGG_COLUMN 154 -#define TK_UMINUS 155 -#define TK_UPLUS 156 -#define TK_REGISTER 157 -#define TK_VECTOR 158 -#define TK_SELECT_COLUMN 159 -#define TK_ASTERISK 160 -#define TK_SPAN 161 -#define TK_SPACE 162 -#define TK_ILLEGAL 163 - -/* The token codes above must all fit in 8 bits */ -#define TKFLG_MASK 0xff - -/* Flags that can be added to a token code when it is not -** being stored in a u8: */ -#define TKFLG_DONTFOLD 0x100 /* Omit constant folding optimizations */ - -/************** End of parse.h ***********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -#include -#include -#include -#include -#include - -/* -** If compiling for a processor that lacks floating point support, -** substitute integer for floating-point -*/ -#ifdef SQLITE_OMIT_FLOATING_POINT -# define double sqlite_int64 -# define float sqlite_int64 -# define LONGDOUBLE_TYPE sqlite_int64 -# ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) -# endif -# define SQLITE_OMIT_DATETIME_FUNCS 1 -# define SQLITE_OMIT_TRACE 1 -# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -# undef SQLITE_HAVE_ISNAN -#endif -#ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (1e99) -#endif - -/* -** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 -** afterward. Having this macro allows us to cause the C compiler -** to omit code used by TEMP tables without messy #ifndef statements. -*/ -#ifdef SQLITE_OMIT_TEMPDB -#define OMIT_TEMPDB 1 -#else -#define OMIT_TEMPDB 0 -#endif - -/* -** The "file format" number is an integer that is incremented whenever -** the VDBE-level file format changes. The following macros define the -** the default file format for new databases and the maximum file format -** that the library can read. -*/ -#define SQLITE_MAX_FILE_FORMAT 4 -#ifndef SQLITE_DEFAULT_FILE_FORMAT -# define SQLITE_DEFAULT_FILE_FORMAT 4 -#endif - -/* -** Determine whether triggers are recursive by default. This can be -** changed at run-time using a pragma. -*/ -#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS -# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 -#endif - -/* -** Provide a default value for SQLITE_TEMP_STORE in case it is not specified -** on the command-line -*/ -#ifndef SQLITE_TEMP_STORE -# define SQLITE_TEMP_STORE 1 -# define SQLITE_TEMP_STORE_xc 1 /* Exclude from ctime.c */ -#endif - -/* -** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if -** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it -** to zero. -*/ -#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0 -# undef SQLITE_MAX_WORKER_THREADS -# define SQLITE_MAX_WORKER_THREADS 0 -#endif -#ifndef SQLITE_MAX_WORKER_THREADS -# define SQLITE_MAX_WORKER_THREADS 8 -#endif -#ifndef SQLITE_DEFAULT_WORKER_THREADS -# define SQLITE_DEFAULT_WORKER_THREADS 0 -#endif -#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS -# undef SQLITE_MAX_WORKER_THREADS -# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS -#endif - -/* -** The default initial allocation for the pagecache when using separate -** pagecaches for each database connection. A positive number is the -** number of pages. A negative number N translations means that a buffer -** of -1024*N bytes is allocated and used for as many pages as it will hold. -*/ -#ifndef SQLITE_DEFAULT_PCACHE_INITSZ -# define SQLITE_DEFAULT_PCACHE_INITSZ 100 -#endif - -/* -** GCC does not define the offsetof() macro so we'll have to do it -** ourselves. -*/ -#ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) -#endif - -/* -** Macros to compute minimum and maximum of two numbers. -*/ -#ifndef MIN -# define MIN(A,B) ((A)<(B)?(A):(B)) -#endif -#ifndef MAX -# define MAX(A,B) ((A)>(B)?(A):(B)) -#endif - -/* -** Swap two objects of type TYPE. -*/ -#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} - -/* -** Check to see if this machine uses EBCDIC. (Yes, believe it or -** not, there are still machines out there that use EBCDIC.) -*/ -#if 'A' == '\301' -# define SQLITE_EBCDIC 1 -#else -# define SQLITE_ASCII 1 -#endif - -/* -** Integers of known sizes. These typedefs might change for architectures -** where the sizes very. Preprocessor macros are available so that the -** types can be conveniently redefined at compile-type. Like this: -** -** cc '-DUINTPTR_TYPE=long long int' ... -*/ -#ifndef UINT32_TYPE -# ifdef HAVE_UINT32_T -# define UINT32_TYPE uint32_t -# else -# define UINT32_TYPE unsigned int -# endif -#endif -#ifndef UINT16_TYPE -# ifdef HAVE_UINT16_T -# define UINT16_TYPE uint16_t -# else -# define UINT16_TYPE unsigned short int -# endif -#endif -#ifndef INT16_TYPE -# ifdef HAVE_INT16_T -# define INT16_TYPE int16_t -# else -# define INT16_TYPE short int -# endif -#endif -#ifndef UINT8_TYPE -# ifdef HAVE_UINT8_T -# define UINT8_TYPE uint8_t -# else -# define UINT8_TYPE unsigned char -# endif -#endif -#ifndef INT8_TYPE -# ifdef HAVE_INT8_T -# define INT8_TYPE int8_t -# else -# define INT8_TYPE signed char -# endif -#endif -#ifndef LONGDOUBLE_TYPE -# define LONGDOUBLE_TYPE long double -#endif -typedef sqlite_int64 i64; /* 8-byte signed integer */ -typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ -typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ -typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ -typedef INT16_TYPE i16; /* 2-byte signed integer */ -typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ -typedef INT8_TYPE i8; /* 1-byte signed integer */ - -/* -** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value -** that can be stored in a u32 without loss of data. The value -** is 0x00000000ffffffff. But because of quirks of some compilers, we -** have to specify the value in the less intuitive manner shown: -*/ -#define SQLITE_MAX_U32 ((((u64)1)<<32)-1) - -/* -** The datatype used to store estimates of the number of rows in a -** table or index. This is an unsigned integer type. For 99.9% of -** the world, a 32-bit integer is sufficient. But a 64-bit integer -** can be used at compile-time if desired. -*/ -#ifdef SQLITE_64BIT_STATS - typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ -#else - typedef u32 tRowcnt; /* 32-bit is the default */ -#endif - -/* -** Estimated quantities used for query planning are stored as 16-bit -** logarithms. For quantity X, the value stored is 10*log2(X). This -** gives a possible range of values of approximately 1.0e986 to 1e-986. -** But the allowed values are "grainy". Not every value is representable. -** For example, quantities 16 and 17 are both represented by a LogEst -** of 40. However, since LogEst quantities are suppose to be estimates, -** not exact values, this imprecision is not a problem. -** -** "LogEst" is short for "Logarithmic Estimate". -** -** Examples: -** 1 -> 0 20 -> 43 10000 -> 132 -** 2 -> 10 25 -> 46 25000 -> 146 -** 3 -> 16 100 -> 66 1000000 -> 199 -** 4 -> 20 1000 -> 99 1048576 -> 200 -** 10 -> 33 1024 -> 100 4294967296 -> 320 -** -** The LogEst can be negative to indicate fractional values. -** Examples: -** -** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 -*/ -typedef INT16_TYPE LogEst; - -/* -** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer -*/ -#ifndef SQLITE_PTRSIZE -# if defined(__SIZEOF_POINTER__) -# define SQLITE_PTRSIZE __SIZEOF_POINTER__ -# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(_M_ARM) || defined(__arm__) || defined(__x86) -# define SQLITE_PTRSIZE 4 -# else -# define SQLITE_PTRSIZE 8 -# endif -#endif - -/* The uptr type is an unsigned integer large enough to hold a pointer -*/ -#if defined(HAVE_STDINT_H) - typedef uintptr_t uptr; -#elif SQLITE_PTRSIZE==4 - typedef u32 uptr; -#else - typedef u64 uptr; -#endif - -/* -** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to -** something between S (inclusive) and E (exclusive). -** -** In other words, S is a buffer and E is a pointer to the first byte after -** the end of buffer S. This macro returns true if P points to something -** contained within the buffer S. -*/ -#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) - - -/* -** Macros to determine whether the machine is big or little endian, -** and whether or not that determination is run-time or compile-time. -** -** For best performance, an attempt is made to guess at the byte-order -** using C-preprocessor macros. If that is unsuccessful, or if -** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined -** at run-time. -*/ -#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER) -# define SQLITE_BYTEORDER 1234 -# define SQLITE_BIGENDIAN 0 -# define SQLITE_LITTLEENDIAN 1 -# define SQLITE_UTF16NATIVE SQLITE_UTF16LE -#endif -#if (defined(sparc) || defined(__ppc__)) \ - && !defined(SQLITE_RUNTIME_BYTEORDER) -# define SQLITE_BYTEORDER 4321 -# define SQLITE_BIGENDIAN 1 -# define SQLITE_LITTLEENDIAN 0 -# define SQLITE_UTF16NATIVE SQLITE_UTF16BE -#endif -#if !defined(SQLITE_BYTEORDER) -# ifdef SQLITE_AMALGAMATION - const int sqlite3one = 1; -# else - extern const int sqlite3one; -# endif -# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ -# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) -# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) -# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) -#endif - -/* -** Constants for the largest and smallest possible 64-bit signed integers. -** These macros are designed to work correctly on both 32-bit and 64-bit -** compilers. -*/ -#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) -#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) - -/* -** Round up a number to the next larger multiple of 8. This is used -** to force 8-byte alignment on 64-bit architectures. -*/ -#define ROUND8(x) (((x)+7)&~7) - -/* -** Round down to the nearest multiple of 8 -*/ -#define ROUNDDOWN8(x) ((x)&~7) - -/* -** Assert that the pointer X is aligned to an 8-byte boundary. This -** macro is used only within assert() to verify that the code gets -** all alignment restrictions correct. -** -** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the -** underlying malloc() implementation might return us 4-byte aligned -** pointers. In that case, only verify 4-byte alignment. -*/ -#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC -# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) -#else -# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) -#endif - -/* -** Disable MMAP on platforms where it is known to not work -*/ -#if defined(__OpenBSD__) || defined(__QNXNTO__) -# undef SQLITE_MAX_MMAP_SIZE -# define SQLITE_MAX_MMAP_SIZE 0 -#endif - -/* -** Default maximum size of memory used by memory-mapped I/O in the VFS -*/ -#ifdef __APPLE__ -# include -#endif -#ifndef SQLITE_MAX_MMAP_SIZE -# if defined(__linux__) \ - || defined(_WIN32) \ - || (defined(__APPLE__) && defined(__MACH__)) \ - || defined(__sun) \ - || defined(__FreeBSD__) \ - || defined(__DragonFly__) -# define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */ -# else -# define SQLITE_MAX_MMAP_SIZE 0 -# endif -# define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */ -#endif - -/* -** The default MMAP_SIZE is zero on all platforms. Or, even if a larger -** default MMAP_SIZE is specified at compile-time, make sure that it does -** not exceed the maximum mmap size. -*/ -#ifndef SQLITE_DEFAULT_MMAP_SIZE -# define SQLITE_DEFAULT_MMAP_SIZE 0 -# define SQLITE_DEFAULT_MMAP_SIZE_xc 1 /* Exclude from ctime.c */ -#endif -#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE -# undef SQLITE_DEFAULT_MMAP_SIZE -# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE -#endif - -/* -** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. -** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also -** define SQLITE_ENABLE_STAT3_OR_STAT4 -*/ -#ifdef SQLITE_ENABLE_STAT4 -# undef SQLITE_ENABLE_STAT3 -# define SQLITE_ENABLE_STAT3_OR_STAT4 1 -#elif SQLITE_ENABLE_STAT3 -# define SQLITE_ENABLE_STAT3_OR_STAT4 1 -#elif SQLITE_ENABLE_STAT3_OR_STAT4 -# undef SQLITE_ENABLE_STAT3_OR_STAT4 -#endif - -/* -** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not -** the Select query generator tracing logic is turned on. -*/ -#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) -# define SELECTTRACE_ENABLED 1 -#else -# define SELECTTRACE_ENABLED 0 -#endif - -/* -** An instance of the following structure is used to store the busy-handler -** callback for a given sqlite handle. -** -** The sqlite.busyHandler member of the sqlite struct contains the busy -** callback for the database handle. Each pager opened via the sqlite -** handle is passed a pointer to sqlite.busyHandler. The busy-handler -** callback is currently invoked only from within pager.c. -*/ -typedef struct BusyHandler BusyHandler; -struct BusyHandler { - int (*xFunc)(void *,int); /* The busy callback */ - void *pArg; /* First arg to busy callback */ - int nBusy; /* Incremented with each busy call */ -}; - -/* -** Name of the master database table. The master database table -** is a special table that holds the names and attributes of all -** user tables and indices. -*/ -#define MASTER_NAME "sqlite_master" -#define TEMP_MASTER_NAME "sqlite_temp_master" - -/* -** The root-page of the master database table. -*/ -#define MASTER_ROOT 1 - -/* -** The name of the schema table. -*/ -#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME) - -/* -** A convenience macro that returns the number of elements in -** an array. -*/ -#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0]))) - -/* -** Determine if the argument is a power of two -*/ -#define IsPowerOfTwo(X) (((X)&((X)-1))==0) - -/* -** The following value as a destructor means to use sqlite3DbFree(). -** The sqlite3DbFree() routine requires two parameters instead of the -** one parameter that destructors normally want. So we have to introduce -** this magic value that the code knows to handle differently. Any -** pointer will work here as long as it is distinct from SQLITE_STATIC -** and SQLITE_TRANSIENT. -*/ -#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize) - -/* -** When SQLITE_OMIT_WSD is defined, it means that the target platform does -** not support Writable Static Data (WSD) such as global and static variables. -** All variables must either be on the stack or dynamically allocated from -** the heap. When WSD is unsupported, the variable declarations scattered -** throughout the SQLite code must become constants instead. The SQLITE_WSD -** macro is used for this purpose. And instead of referencing the variable -** directly, we use its constant as a key to lookup the run-time allocated -** buffer that holds real variable. The constant is also the initializer -** for the run-time allocated buffer. -** -** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL -** macros become no-ops and have zero performance impact. -*/ -#ifdef SQLITE_OMIT_WSD - #define SQLITE_WSD const - #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) - #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) -SQLITE_API int sqlite3_wsd_init(int N, int J); -SQLITE_API void *sqlite3_wsd_find(void *K, int L); -#else - #define SQLITE_WSD - #define GLOBAL(t,v) v - #define sqlite3GlobalConfig sqlite3Config -#endif - -/* -** The following macros are used to suppress compiler warnings and to -** make it clear to human readers when a function parameter is deliberately -** left unused within the body of a function. This usually happens when -** a function is called via a function pointer. For example the -** implementation of an SQL aggregate step callback may not use the -** parameter indicating the number of arguments passed to the aggregate, -** if it knows that this is enforced elsewhere. -** -** When a function parameter is not used at all within the body of a function, -** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. -** However, these macros may also be used to suppress warnings related to -** parameters that may or may not be used depending on compilation options. -** For example those parameters only used in assert() statements. In these -** cases the parameters are named as per the usual conventions. -*/ -#define UNUSED_PARAMETER(x) (void)(x) -#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) - -/* -** Forward references to structures -*/ -typedef struct AggInfo AggInfo; -typedef struct AuthContext AuthContext; -typedef struct AutoincInfo AutoincInfo; -typedef struct Bitvec Bitvec; -typedef struct CollSeq CollSeq; -typedef struct Column Column; -typedef struct Db Db; -typedef struct Schema Schema; -typedef struct Expr Expr; -typedef struct ExprList ExprList; -typedef struct ExprSpan ExprSpan; -typedef struct FKey FKey; -typedef struct FuncDestructor FuncDestructor; -typedef struct FuncDef FuncDef; -typedef struct FuncDefHash FuncDefHash; -typedef struct IdList IdList; -typedef struct Index Index; -typedef struct IndexSample IndexSample; -typedef struct KeyClass KeyClass; -typedef struct KeyInfo KeyInfo; -typedef struct Lookaside Lookaside; -typedef struct LookasideSlot LookasideSlot; -typedef struct Module Module; -typedef struct NameContext NameContext; -typedef struct Parse Parse; -typedef struct PreUpdate PreUpdate; -typedef struct PrintfArguments PrintfArguments; -typedef struct RowSet RowSet; -typedef struct Savepoint Savepoint; -typedef struct Select Select; -typedef struct SQLiteThread SQLiteThread; -typedef struct SelectDest SelectDest; -typedef struct SrcList SrcList; -typedef struct StrAccum StrAccum; -typedef struct Table Table; -typedef struct TableLock TableLock; -typedef struct Token Token; -typedef struct TreeView TreeView; -typedef struct Trigger Trigger; -typedef struct TriggerPrg TriggerPrg; -typedef struct TriggerStep TriggerStep; -typedef struct UnpackedRecord UnpackedRecord; -typedef struct VTable VTable; -typedef struct VtabCtx VtabCtx; -typedef struct Walker Walker; -typedef struct WhereInfo WhereInfo; -typedef struct With With; - -/* -** Defer sourcing vdbe.h and btree.h until after the "u8" and -** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque -** pointer types (i.e. FuncDef) defined above. -*/ -/************** Include btree.h in the middle of sqliteInt.h *****************/ -/************** Begin file btree.h *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the interface that the sqlite B-Tree file -** subsystem. See comments in the source code for a detailed description -** of what each interface routine does. -*/ -#ifndef SQLITE_BTREE_H -#define SQLITE_BTREE_H - -/* TODO: This definition is just included so other modules compile. It -** needs to be revisited. -*/ -#define SQLITE_N_BTREE_META 16 - -/* -** If defined as non-zero, auto-vacuum is enabled by default. Otherwise -** it must be turned on for each database using "PRAGMA auto_vacuum = 1". -*/ -#ifndef SQLITE_DEFAULT_AUTOVACUUM - #define SQLITE_DEFAULT_AUTOVACUUM 0 -#endif - -#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ -#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ -#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ - -/* -** Forward declarations of structure -*/ -typedef struct Btree Btree; -typedef struct BtCursor BtCursor; -typedef struct BtShared BtShared; -typedef struct BtreePayload BtreePayload; - - -SQLITE_PRIVATE int sqlite3BtreeOpen( - sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ - const char *zFilename, /* Name of database file to open */ - sqlite3 *db, /* Associated database connection */ - Btree **ppBtree, /* Return open Btree* here */ - int flags, /* Flags */ - int vfsFlags /* Flags passed through to VFS open */ -); - -/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the -** following values. -** -** NOTE: These values must match the corresponding PAGER_ values in -** pager.h. -*/ -#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ -#define BTREE_MEMORY 2 /* This is an in-memory DB */ -#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ -#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ - -SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); -SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int); -#if SQLITE_MAX_MMAP_SIZE>0 -SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); -#endif -SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); -SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); -SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); -SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); -SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); -SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); -SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); -SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); -SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); -SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); -SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); -SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); -SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); -SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags); -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); -SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); -SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); -SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); -#ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); -#endif -SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); - -SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); -SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); -SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); - -SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); - -/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR -** of the flags shown below. -** -** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. -** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data -** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With -** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored -** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL -** indices.) -*/ -#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ -#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ - -SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); -SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); -SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int); - -SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); -SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); - -SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); - -/* -** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta -** should be one of the following values. The integer values are assigned -** to constants so that the offset of the corresponding field in an -** SQLite database header may be found using the following formula: -** -** offset = 36 + (idx * 4) -** -** For example, the free-page-count field is located at byte offset 36 of -** the database file header. The incr-vacuum-flag field is located at -** byte offset 64 (== 36+4*7). -** -** The BTREE_DATA_VERSION value is not really a value stored in the header. -** It is a read-only number computed by the pager. But we merge it with -** the header value access routines since its access pattern is the same. -** Call it a "virtual meta value". -*/ -#define BTREE_FREE_PAGE_COUNT 0 -#define BTREE_SCHEMA_VERSION 1 -#define BTREE_FILE_FORMAT 2 -#define BTREE_DEFAULT_CACHE_SIZE 3 -#define BTREE_LARGEST_ROOT_PAGE 4 -#define BTREE_TEXT_ENCODING 5 -#define BTREE_USER_VERSION 6 -#define BTREE_INCR_VACUUM 7 -#define BTREE_APPLICATION_ID 8 -#define BTREE_DATA_VERSION 15 /* A virtual meta-value */ - -/* -** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() -** interface. -** -** BTREE_HINT_RANGE (arguments: Expr*, Mem*) -** -** The first argument is an Expr* (which is guaranteed to be constant for -** the lifetime of the cursor) that defines constraints on which rows -** might be fetched with this cursor. The Expr* tree may contain -** TK_REGISTER nodes that refer to values stored in the array of registers -** passed as the second parameter. In other words, if Expr.op==TK_REGISTER -** then the value of the node is the value in Mem[pExpr.iTable]. Any -** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th -** column of the b-tree of the cursor. The Expr tree will not contain -** any function calls nor subqueries nor references to b-trees other than -** the cursor being hinted. -** -** The design of the _RANGE hint is aid b-tree implementations that try -** to prefetch content from remote machines - to provide those -** implementations with limits on what needs to be prefetched and thereby -** reduce network bandwidth. -** -** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by -** standard SQLite. The other hints are provided for extentions that use -** the SQLite parser and code generator but substitute their own storage -** engine. -*/ -#define BTREE_HINT_RANGE 0 /* Range constraints on queries */ - -/* -** Values that may be OR'd together to form the argument to the -** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): -** -** The BTREE_BULKLOAD flag is set on index cursors when the index is going -** to be filled with content that is already in sorted order. -** -** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or -** OP_SeekLE opcodes for a range search, but where the range of entries -** selected will all have the same key. In other words, the cursor will -** be used only for equality key searches. -** -*/ -#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ -#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ - -/* -** Flags passed as the third argument to sqlite3BtreeCursor(). -** -** For read-only cursors the wrFlag argument is always zero. For read-write -** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just -** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will -** only be used by SQLite for the following: -** -** * to seek to and then delete specific entries, and/or -** -** * to read values that will be used to create keys that other -** BTREE_FORDELETE cursors will seek to and delete. -** -** The BTREE_FORDELETE flag is an optimization hint. It is not used by -** by this, the native b-tree engine of SQLite, but it is available to -** alternative storage engines that might be substituted in place of this -** b-tree system. For alternative storage engines in which a delete of -** the main table row automatically deletes corresponding index rows, -** the FORDELETE flag hint allows those alternative storage engines to -** skip a lot of work. Namely: FORDELETE cursors may treat all SEEK -** and DELETE operations as no-ops, and any READ operation against a -** FORDELETE cursor may return a null row: 0x01 0x00. -*/ -#define BTREE_WRCSR 0x00000004 /* read-write cursor */ -#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ - -SQLITE_PRIVATE int sqlite3BtreeCursor( - Btree*, /* BTree containing table to open */ - int iTable, /* Index of root page */ - int wrFlag, /* 1 for writing. 0 for read-only */ - struct KeyInfo*, /* First argument to compare function */ - BtCursor *pCursor /* Space to write cursor structure */ -); -SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); -SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); -SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); -#ifdef SQLITE_ENABLE_CURSOR_HINTS -SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); -#endif - -SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( - BtCursor*, - UnpackedRecord *pUnKey, - i64 intKey, - int bias, - int *pRes -); -SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); -SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); - -/* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */ -#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ -#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ - -/* An instance of the BtreePayload object describes the content of a single -** entry in either an index or table btree. -** -** Index btrees (used for indexes and also WITHOUT ROWID tables) contain -** an arbitrary key and no data. These btrees have pKey,nKey set to their -** key and pData,nData,nZero set to zero. -** -** Table btrees (used for rowid tables) contain an integer rowid used as -** the key and passed in the nKey field. The pKey field is zero. -** pData,nData hold the content of the new entry. nZero extra zero bytes -** are appended to the end of the content when constructing the entry. -** -** This object is used to pass information into sqlite3BtreeInsert(). The -** same information used to be passed as five separate parameters. But placing -** the information into this object helps to keep the interface more -** organized and understandable, and it also helps the resulting code to -** run a little faster by using fewer registers for parameter passing. -*/ -struct BtreePayload { - const void *pKey; /* Key content for indexes. NULL for tables */ - sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ - const void *pData; /* Data for tables. NULL for indexes */ - int nData; /* Size of pData. 0 if none. */ - int nZero; /* Extra zero data appended after pData,nData */ -}; - -SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, - int bias, int seekResult); -SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); -SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); -SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); -SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes); -SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); -SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); -SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); - -SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); -SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); - -#ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); -SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); -#endif -SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); -SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); -SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); -SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); -SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); - -#ifndef NDEBUG -SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); -#endif - -#ifndef SQLITE_OMIT_BTREECOUNT -SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *); -#endif - -#ifdef SQLITE_TEST -SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); -SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); -#endif - -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); -#endif - -/* -** If we are not using shared cache, then there is no need to -** use mutexes to access the BtShared structures. So make the -** Enter and Leave procedures no-ops. -*/ -#ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); -SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); -SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); -SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree*); -#else -# define sqlite3BtreeEnter(X) -# define sqlite3BtreeEnterAll(X) -# define sqlite3BtreeSharable(X) 0 -# define sqlite3BtreeEnterCursor(X) -# define sqlite3BtreeConnectionCount(X) 1 -#endif - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE -SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); -SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); -SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); -#ifndef NDEBUG - /* These routines are used inside assert() statements only. */ -SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); -SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); -SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); -#endif -#else - -# define sqlite3BtreeLeave(X) -# define sqlite3BtreeLeaveCursor(X) -# define sqlite3BtreeLeaveAll(X) - -# define sqlite3BtreeHoldsMutex(X) 1 -# define sqlite3BtreeHoldsAllMutexes(X) 1 -# define sqlite3SchemaMutexHeld(X,Y,Z) 1 -#endif - - -#endif /* SQLITE_BTREE_H */ - -/************** End of btree.h ***********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include vdbe.h in the middle of sqliteInt.h ******************/ -/************** Begin file vdbe.h ********************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Header file for the Virtual DataBase Engine (VDBE) -** -** This header defines the interface to the virtual database engine -** or VDBE. The VDBE implements an abstract machine that runs a -** simple program to access and modify the underlying database. -*/ -#ifndef SQLITE_VDBE_H -#define SQLITE_VDBE_H -/* #include */ - -/* -** A single VDBE is an opaque structure named "Vdbe". Only routines -** in the source file sqliteVdbe.c are allowed to see the insides -** of this structure. -*/ -typedef struct Vdbe Vdbe; - -/* -** The names of the following types declared in vdbeInt.h are required -** for the VdbeOp definition. -*/ -typedef struct Mem Mem; -typedef struct SubProgram SubProgram; - -/* -** A single instruction of the virtual machine has an opcode -** and as many as three operands. The instruction is recorded -** as an instance of the following structure: -*/ -struct VdbeOp { - u8 opcode; /* What operation to perform */ - signed char p4type; /* One of the P4_xxx constants for p4 */ - u8 notUsed1; - u8 p5; /* Fifth parameter is an unsigned character */ - int p1; /* First operand */ - int p2; /* Second parameter (often the jump destination) */ - int p3; /* The third parameter */ - union p4union { /* fourth parameter */ - int i; /* Integer value if p4type==P4_INT32 */ - void *p; /* Generic pointer */ - char *z; /* Pointer to data for string (char array) types */ - i64 *pI64; /* Used when p4type is P4_INT64 */ - double *pReal; /* Used when p4type is P4_REAL */ - FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ - sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ - CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ - Mem *pMem; /* Used when p4type is P4_MEM */ - VTable *pVtab; /* Used when p4type is P4_VTAB */ - KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ - int *ai; /* Used when p4type is P4_INTARRAY */ - SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ - Table *pTab; /* Used when p4type is P4_TABLE */ -#ifdef SQLITE_ENABLE_CURSOR_HINTS - Expr *pExpr; /* Used when p4type is P4_EXPR */ -#endif - int (*xAdvance)(BtCursor *, int *); - } p4; -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - char *zComment; /* Comment to improve readability */ -#endif -#ifdef VDBE_PROFILE - u32 cnt; /* Number of times this instruction was executed */ - u64 cycles; /* Total time spent executing this instruction */ -#endif -#ifdef SQLITE_VDBE_COVERAGE - int iSrcLine; /* Source-code line that generated this opcode */ -#endif -}; -typedef struct VdbeOp VdbeOp; - - -/* -** A sub-routine used to implement a trigger program. -*/ -struct SubProgram { - VdbeOp *aOp; /* Array of opcodes for sub-program */ - int nOp; /* Elements in aOp[] */ - int nMem; /* Number of memory cells required */ - int nCsr; /* Number of cursors required */ - void *token; /* id that may be used to recursive triggers */ - SubProgram *pNext; /* Next sub-program already visited */ -}; - -/* -** A smaller version of VdbeOp used for the VdbeAddOpList() function because -** it takes up less space. -*/ -struct VdbeOpList { - u8 opcode; /* What operation to perform */ - signed char p1; /* First operand */ - signed char p2; /* Second parameter (often the jump destination) */ - signed char p3; /* Third parameter */ -}; -typedef struct VdbeOpList VdbeOpList; - -/* -** Allowed values of VdbeOp.p4type -*/ -#define P4_NOTUSED 0 /* The P4 parameter is not used */ -#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ -#define P4_STATIC (-2) /* Pointer to a static string */ -#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ -#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-7) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ -#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ -#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ -#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ -#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ -#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ -#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ -#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ -#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ -#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */ -#define P4_TABLE (-20) /* P4 is a pointer to a Table structure */ -#define P4_FUNCCTX (-21) /* P4 is a pointer to an sqlite3_context object */ - -/* Error message codes for OP_Halt */ -#define P5_ConstraintNotNull 1 -#define P5_ConstraintUnique 2 -#define P5_ConstraintCheck 3 -#define P5_ConstraintFK 4 - -/* -** The Vdbe.aColName array contains 5n Mem structures, where n is the -** number of columns of data returned by the statement. -*/ -#define COLNAME_NAME 0 -#define COLNAME_DECLTYPE 1 -#define COLNAME_DATABASE 2 -#define COLNAME_TABLE 3 -#define COLNAME_COLUMN 4 -#ifdef SQLITE_ENABLE_COLUMN_METADATA -# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ -#else -# ifdef SQLITE_OMIT_DECLTYPE -# define COLNAME_N 1 /* Store only the name */ -# else -# define COLNAME_N 2 /* Store the name and decltype */ -# endif -#endif - -/* -** The following macro converts a relative address in the p2 field -** of a VdbeOp structure into a negative number so that -** sqlite3VdbeAddOpList() knows that the address is relative. Calling -** the macro again restores the address. -*/ -#define ADDR(X) (-1-(X)) - -/* -** The makefile scans the vdbe.c source file and creates the "opcodes.h" -** header file that defines a number for each opcode used by the VDBE. -*/ -/************** Include opcodes.h in the middle of vdbe.h ********************/ -/************** Begin file opcodes.h *****************************************/ -/* Automatically generated. Do not edit */ -/* See the tool/mkopcodeh.tcl script for details */ -#define OP_Savepoint 0 -#define OP_AutoCommit 1 -#define OP_Transaction 2 -#define OP_SorterNext 3 -#define OP_PrevIfOpen 4 -#define OP_NextIfOpen 5 -#define OP_Prev 6 -#define OP_Next 7 -#define OP_Checkpoint 8 -#define OP_JournalMode 9 -#define OP_Vacuum 10 -#define OP_VFilter 11 /* synopsis: iplan=r[P3] zplan='P4' */ -#define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */ -#define OP_Goto 13 -#define OP_Gosub 14 -#define OP_InitCoroutine 15 -#define OP_Yield 16 -#define OP_MustBeInt 17 -#define OP_Jump 18 -#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ -#define OP_Once 20 -#define OP_If 21 -#define OP_IfNot 22 -#define OP_SeekLT 23 /* synopsis: key=r[P3@P4] */ -#define OP_SeekLE 24 /* synopsis: key=r[P3@P4] */ -#define OP_SeekGE 25 /* synopsis: key=r[P3@P4] */ -#define OP_SeekGT 26 /* synopsis: key=r[P3@P4] */ -#define OP_Or 27 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ -#define OP_And 28 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_NoConflict 29 /* synopsis: key=r[P3@P4] */ -#define OP_NotFound 30 /* synopsis: key=r[P3@P4] */ -#define OP_Found 31 /* synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 32 /* synopsis: intkey=r[P3] */ -#define OP_NotExists 33 /* synopsis: intkey=r[P3] */ -#define OP_IsNull 34 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -#define OP_NotNull 35 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -#define OP_Ne 36 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -#define OP_Eq 37 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -#define OP_Gt 38 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */ -#define OP_Le 39 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 40 /* same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseNotEq 42 /* same as TK_ESCAPE */ -#define OP_BitAnd 43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 47 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 48 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 49 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_Last 53 -#define OP_BitNot 54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ -#define OP_SorterSort 55 -#define OP_Sort 56 -#define OP_Rewind 57 -#define OP_IdxLE 58 /* synopsis: key=r[P3@P4] */ -#define OP_IdxGT 59 /* synopsis: key=r[P3@P4] */ -#define OP_IdxLT 60 /* synopsis: key=r[P3@P4] */ -#define OP_IdxGE 61 /* synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 62 /* synopsis: r[P3]=rowset(P1) */ -#define OP_RowSetTest 63 /* synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 64 -#define OP_FkIfZero 65 /* synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IfPos 66 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 67 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */ -#define OP_DecrJumpZero 68 /* synopsis: if (--r[P1])==0 goto P2 */ -#define OP_IncrVacuum 69 -#define OP_VNext 70 -#define OP_Init 71 /* synopsis: Start at P2 */ -#define OP_Return 72 -#define OP_EndCoroutine 73 -#define OP_HaltIfNull 74 /* synopsis: if r[P3]=null halt */ -#define OP_Halt 75 -#define OP_Integer 76 /* synopsis: r[P2]=P1 */ -#define OP_Int64 77 /* synopsis: r[P2]=P4 */ -#define OP_String 78 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 79 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 80 /* synopsis: r[P1]=NULL */ -#define OP_Blob 81 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 82 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 83 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 84 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 85 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 86 /* synopsis: r[P2]=r[P1] */ -#define OP_ResultRow 87 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 88 -#define OP_Function0 89 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_Function 90 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_AddImm 91 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 92 -#define OP_Cast 93 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 94 -#define OP_Compare 95 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_Column 96 /* synopsis: r[P3]=PX */ -#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 100 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 101 -#define OP_SetCookie 102 -#define OP_ReopenIdx 103 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 104 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 105 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenAutoindex 106 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 107 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 108 -#define OP_SequenceTest 109 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 110 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 111 -#define OP_ColumnsUsed 112 -#define OP_Sequence 113 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 114 /* synopsis: r[P2]=rowid */ -#define OP_Insert 115 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_InsertInt 116 /* synopsis: intkey=P3 data=r[P2] */ -#define OP_Delete 117 -#define OP_ResetCount 118 -#define OP_SorterCompare 119 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 120 /* synopsis: r[P2]=data */ -#define OP_RowKey 121 /* synopsis: r[P2]=key */ -#define OP_RowData 122 /* synopsis: r[P2]=data */ -#define OP_Rowid 123 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 124 -#define OP_SorterInsert 125 -#define OP_IdxInsert 126 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */ -#define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */ -#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */ -#define OP_Destroy 130 -#define OP_Clear 131 -#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_ResetSorter 133 -#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */ -#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */ -#define OP_ParseSchema 136 -#define OP_LoadAnalysis 137 -#define OP_DropTable 138 -#define OP_DropIndex 139 -#define OP_DropTrigger 140 -#define OP_IntegrityCk 141 -#define OP_RowSetAdd 142 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 143 -#define OP_FkCounter 144 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 145 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 146 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggStep0 147 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggFinal 149 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 150 -#define OP_TableLock 151 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 152 -#define OP_VCreate 153 -#define OP_VDestroy 154 -#define OP_VOpen 155 -#define OP_VColumn 156 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 157 -#define OP_Pagecount 158 -#define OP_MaxPgcnt 159 -#define OP_CursorHint 160 -#define OP_Noop 161 -#define OP_Explain 162 - -/* Properties such as "out2" or "jump" that are specified in -** comments following the "case" for each opcode in the vdbe.c -** are encoded into bitvectors as follows: -*/ -#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ -#define OPFLG_IN1 0x02 /* in1: P1 is an input */ -#define OPFLG_IN2 0x04 /* in2: P2 is an input */ -#define OPFLG_IN3 0x08 /* in3: P3 is an input */ -#define OPFLG_OUT2 0x10 /* out2: P2 is an output */ -#define OPFLG_OUT3 0x20 /* out3: P3 is an output */ -#define OPFLG_INITIALIZER {\ -/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ -/* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\ -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x09,\ -/* 24 */ 0x09, 0x09, 0x09, 0x26, 0x26, 0x09, 0x09, 0x09,\ -/* 32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\ -/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23, 0x0b,\ -/* 64 */ 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,\ -/* 72 */ 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10,\ -/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00,\ -/* 88 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ -/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 112 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\ -/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\ -/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\ -/* 144 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ -/* 160 */ 0x00, 0x00, 0x00,} - -/* The sqlite3P2Values() routine is able to run faster if it knows -** the value of the largest JUMP opcode. The smaller the maximum -** JUMP opcode the better, so the mkopcodeh.tcl script that -** generated this include file strives to group all JUMP opcodes -** together near the beginning of the list. -*/ -#define SQLITE_MX_JUMP_OPCODE 71 /* Maximum JUMP opcode */ - -/************** End of opcodes.h *********************************************/ -/************** Continuing where we left off in vdbe.h ***********************/ - -/* -** Prototypes for the VDBE interface. See comments on the implementation -** for a description of what each of these routines does. -*/ -SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*); -SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); -SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); -SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); -SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); -SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); -#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) -SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); -#else -# define sqlite3VdbeVerifyNoMallocRequired(A,B) -#endif -SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno); -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); -SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); -SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); -SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); -SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); -SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5); -SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); -SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); -SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); -SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); -SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); -SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); -SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); -SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); -SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); -SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); -#endif -SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); -SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); -SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); -SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); -SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); -SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); -SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); -SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); -#ifndef SQLITE_OMIT_TRACE -SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); -#endif -SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); - -SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); -SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); -SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); - -typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); -SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); - -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); -#endif - -/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on -** each VDBE opcode. -** -** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op -** comments in VDBE programs that show key decision points in the code -** generator. -*/ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS -SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); -# define VdbeComment(X) sqlite3VdbeComment X -SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); -# define VdbeNoopComment(X) sqlite3VdbeNoopComment X -# ifdef SQLITE_ENABLE_MODULE_COMMENTS -# define VdbeModuleComment(X) sqlite3VdbeNoopComment X -# else -# define VdbeModuleComment(X) -# endif -#else -# define VdbeComment(X) -# define VdbeNoopComment(X) -# define VdbeModuleComment(X) -#endif - -/* -** The VdbeCoverage macros are used to set a coverage testing point -** for VDBE branch instructions. The coverage testing points are line -** numbers in the sqlite3.c source file. VDBE branch coverage testing -** only works with an amalagmation build. That's ok since a VDBE branch -** coverage build designed for testing the test suite only. No application -** should ever ship with VDBE branch coverage measuring turned on. -** -** VdbeCoverage(v) // Mark the previously coded instruction -** // as a branch -** -** VdbeCoverageIf(v, conditional) // Mark previous if conditional true -** -** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken -** -** VdbeCoverageNeverTaken(v) // Previous branch is never taken -** -** Every VDBE branch operation must be tagged with one of the macros above. -** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and -** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() -** routine in vdbe.c, alerting the developer to the missed tag. -*/ -#ifdef SQLITE_VDBE_COVERAGE -SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); -# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) -# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) -# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); -# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); -# define VDBE_OFFSET_LINENO(x) (__LINE__+x) -#else -# define VdbeCoverage(v) -# define VdbeCoverageIf(v,x) -# define VdbeCoverageAlwaysTaken(v) -# define VdbeCoverageNeverTaken(v) -# define VDBE_OFFSET_LINENO(x) 0 -#endif - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); -#else -# define sqlite3VdbeScanStatus(a,b,c,d,e) -#endif - -#endif /* SQLITE_VDBE_H */ - -/************** End of vdbe.h ************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include pager.h in the middle of sqliteInt.h *****************/ -/************** Begin file pager.h *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the interface that the sqlite page cache -** subsystem. The page cache subsystem reads and writes a file a page -** at a time and provides a journal for rollback. -*/ - -#ifndef SQLITE_PAGER_H -#define SQLITE_PAGER_H - -/* -** Default maximum size for persistent journal files. A negative -** value means no limit. This value may be overridden using the -** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". -*/ -#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT - #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 -#endif - -/* -** The type used to represent a page number. The first page in a file -** is called page 1. 0 is used to represent "not a page". -*/ -typedef u32 Pgno; - -/* -** Each open file is managed by a separate instance of the "Pager" structure. -*/ -typedef struct Pager Pager; - -/* -** Handle type for pages. -*/ -typedef struct PgHdr DbPage; - -/* -** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is -** reserved for working around a windows/posix incompatibility). It is -** used in the journal to signify that the remainder of the journal file -** is devoted to storing a master journal name - there are no more pages to -** roll back. See comments for function writeMasterJournal() in pager.c -** for details. -*/ -#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) - -/* -** Allowed values for the flags parameter to sqlite3PagerOpen(). -** -** NOTE: These values must match the corresponding BTREE_ values in btree.h. -*/ -#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ -#define PAGER_MEMORY 0x0002 /* In-memory database */ - -/* -** Valid values for the second argument to sqlite3PagerLockingMode(). -*/ -#define PAGER_LOCKINGMODE_QUERY -1 -#define PAGER_LOCKINGMODE_NORMAL 0 -#define PAGER_LOCKINGMODE_EXCLUSIVE 1 - -/* -** Numeric constants that encode the journalmode. -** -** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY) -** are exposed in the API via the "PRAGMA journal_mode" command and -** therefore cannot be changed without a compatibility break. -*/ -#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ -#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ -#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ -#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ -#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ -#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ -#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ - -/* -** Flags that make up the mask passed to sqlite3PagerGet(). -*/ -#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ -#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ - -/* -** Flags for sqlite3PagerSetFlags() -** -** Value constraints (enforced via assert()): -** PAGER_FULLFSYNC == SQLITE_FullFSync -** PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync -** PAGER_CACHE_SPILL == SQLITE_CacheSpill -*/ -#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ -#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ -#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ -#define PAGER_SYNCHRONOUS_EXTRA 0x04 /* PRAGMA synchronous=EXTRA */ -#define PAGER_SYNCHRONOUS_MASK 0x07 /* Mask for four values above */ -#define PAGER_FULLFSYNC 0x08 /* PRAGMA fullfsync=ON */ -#define PAGER_CKPT_FULLFSYNC 0x10 /* PRAGMA checkpoint_fullfsync=ON */ -#define PAGER_CACHESPILL 0x20 /* PRAGMA cache_spill=ON */ -#define PAGER_FLAGS_MASK 0x38 /* All above except SYNCHRONOUS */ - -/* -** The remainder of this file contains the declarations of the functions -** that make up the Pager sub-system API. See source code comments for -** a detailed description of each routine. -*/ - -/* Open and close a Pager connection. */ -SQLITE_PRIVATE int sqlite3PagerOpen( - sqlite3_vfs*, - Pager **ppPager, - const char*, - int, - int, - int, - void(*)(DbPage*) -); -SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager); -SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); - -/* Functions used to configure a Pager object. */ -SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); -#ifdef SQLITE_HAS_CODEC -SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*); -#endif -SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); -SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); -SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int); -SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); -SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); -SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned); -SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); -SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); -SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); -SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); -SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); -SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); -SQLITE_PRIVATE int sqlite3PagerFlush(Pager*); - -/* Functions used to obtain and release page references. */ -SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); -SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); -SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); -SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); -SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); - -/* Operations on page references. */ -SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); -SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); -SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); -SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); -SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); -SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); - -/* Functions used to manage pager transactions and savepoints. */ -SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); -SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); -SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); -SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); -SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster); -SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); -SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); -SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); -SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); -SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); - -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*); -SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); -SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); -SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); -SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager); -SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager); -# ifdef SQLITE_ENABLE_SNAPSHOT -SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); -SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); -# endif -#else -# define sqlite3PagerUseWal(x) 0 -#endif - -#ifdef SQLITE_ENABLE_ZIPVFS -SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); -#endif - -/* Functions used to query pager state and configuration. */ -SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); -SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); -#endif -SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); -SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int); -SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*); -SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); -SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); -SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); -SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); -SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); -SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); -SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); - -/* Functions used to truncate the database file. */ -SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); - -SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16); - -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) -SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); -#endif - -/* Functions to support testing and debugging. */ -#if !defined(NDEBUG) || defined(SQLITE_TEST) -SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); -SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); -#endif -#ifdef SQLITE_TEST -SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); -SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); - void disable_simulated_io_errors(void); - void enable_simulated_io_errors(void); -#else -# define disable_simulated_io_errors() -# define enable_simulated_io_errors() -#endif - -#endif /* SQLITE_PAGER_H */ - -/************** End of pager.h ***********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include pcache.h in the middle of sqliteInt.h ****************/ -/************** Begin file pcache.h ******************************************/ -/* -** 2008 August 05 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the interface that the sqlite page cache -** subsystem. -*/ - -#ifndef _PCACHE_H_ - -typedef struct PgHdr PgHdr; -typedef struct PCache PCache; - -/* -** Every page in the cache is controlled by an instance of the following -** structure. -*/ -struct PgHdr { - sqlite3_pcache_page *pPage; /* Pcache object page handle */ - void *pData; /* Page data */ - void *pExtra; /* Extra content */ - PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ - Pager *pPager; /* The pager this page is part of */ - Pgno pgno; /* Page number for this page */ -#ifdef SQLITE_CHECK_PAGES - u32 pageHash; /* Hash of page content */ -#endif - u16 flags; /* PGHDR flags defined below */ - - /********************************************************************** - ** Elements above are public. All that follows is private to pcache.c - ** and should not be accessed by other modules. - */ - i16 nRef; /* Number of users of this page */ - PCache *pCache; /* Cache that owns this page */ - - PgHdr *pDirtyNext; /* Next element in list of dirty pages */ - PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ -}; - -/* Bit values for PgHdr.flags */ -#define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */ -#define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */ -#define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ -#define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before - ** writing this page to the database */ -#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */ -#define PGHDR_MMAP 0x020 /* This is an mmap page object */ - -#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ - -/* Initialize and shutdown the page cache subsystem */ -SQLITE_PRIVATE int sqlite3PcacheInitialize(void); -SQLITE_PRIVATE void sqlite3PcacheShutdown(void); - -/* Page cache buffer management: -** These routines implement SQLITE_CONFIG_PAGECACHE. -*/ -SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); - -/* Create a new pager cache. -** Under memory stress, invoke xStress to try to make pages clean. -** Only clean and unpinned pages can be reclaimed. -*/ -SQLITE_PRIVATE int sqlite3PcacheOpen( - int szPage, /* Size of every page */ - int szExtra, /* Extra space associated with each page */ - int bPurgeable, /* True if pages are on backing store */ - int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ - void *pStress, /* Argument to xStress */ - PCache *pToInit /* Preallocated space for the PCache */ -); - -/* Modify the page-size after the cache has been created. */ -SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); - -/* Return the size in bytes of a PCache object. Used to preallocate -** storage space. -*/ -SQLITE_PRIVATE int sqlite3PcacheSize(void); - -/* One release per successful fetch. Page is pinned until released. -** Reference counted. -*/ -SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); -SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); -SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); -SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); - -SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ -SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ -SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ -SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ -SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*); - -/* Change a page number. Used by incr-vacuum. */ -SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno); - -/* Remove all pages with pgno>x. Reset the cache if x==0 */ -SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x); - -/* Get a list of all dirty pages in the cache, sorted by page number */ -SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*); - -/* Reset and close the cache object */ -SQLITE_PRIVATE void sqlite3PcacheClose(PCache*); - -/* Clear flags from pages of the page cache */ -SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); - -/* Discard the contents of the cache */ -SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); - -/* Return the total number of outstanding page references */ -SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); - -/* Increment the reference count of an existing page */ -SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); - -SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); - -/* Return the total number of pages stored in the cache */ -SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); - -#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) -/* Iterate through all dirty pages currently stored in the cache. This -** interface is only available if SQLITE_CHECK_PAGES is defined when the -** library is built. -*/ -SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); -#endif - -#if defined(SQLITE_DEBUG) -/* Check invariants on a PgHdr object */ -SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*); -#endif - -/* Set and get the suggested cache-size for the specified pager-cache. -** -** If no global maximum is configured, then the system attempts to limit -** the total number of pages cached by purgeable pager-caches to the sum -** of the suggested cache-sizes. -*/ -SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int); -#ifdef SQLITE_TEST -SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *); -#endif - -/* Set or get the suggested spill-size for the specified pager-cache. -** -** The spill-size is the minimum number of pages in cache before the cache -** will attempt to spill dirty pages by calling xStress. -*/ -SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int); - -/* Free up as much memory as possible from the page cache */ -SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*); - -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT -/* Try to return memory used by the pcache module to the main memory heap */ -SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int); -#endif - -#ifdef SQLITE_TEST -SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*); -#endif - -SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); - -/* Return the header size */ -SQLITE_PRIVATE int sqlite3HeaderSizePcache(void); -SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void); - -/* Number of dirty pages as a percentage of the configured cache size */ -SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*); - -#endif /* _PCACHE_H_ */ - -/************** End of pcache.h **********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include os.h in the middle of sqliteInt.h ********************/ -/************** Begin file os.h **********************************************/ -/* -** 2001 September 16 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This header file (together with is companion C source-code file -** "os.c") attempt to abstract the underlying operating system so that -** the SQLite library will work on both POSIX and windows systems. -** -** This header file is #include-ed by sqliteInt.h and thus ends up -** being included by every source file. -*/ -#ifndef _SQLITE_OS_H_ -#define _SQLITE_OS_H_ - -/* -** Attempt to automatically detect the operating system and setup the -** necessary pre-processor macros for it. -*/ -/************** Include os_setup.h in the middle of os.h *********************/ -/************** Begin file os_setup.h ****************************************/ -/* -** 2013 November 25 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains pre-processor directives related to operating system -** detection and/or setup. -*/ -#ifndef SQLITE_OS_SETUP_H -#define SQLITE_OS_SETUP_H - -/* -** Figure out if we are dealing with Unix, Windows, or some other operating -** system. -** -** After the following block of preprocess macros, all of SQLITE_OS_UNIX, -** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of -** the three will be 1. The other two will be 0. -*/ -#if defined(SQLITE_OS_OTHER) -# if SQLITE_OS_OTHER==1 -# undef SQLITE_OS_UNIX -# define SQLITE_OS_UNIX 0 -# undef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -# else -# undef SQLITE_OS_OTHER -# endif -#endif -#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) -# define SQLITE_OS_OTHER 0 -# ifndef SQLITE_OS_WIN -# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ - defined(__MINGW32__) || defined(__BORLANDC__) -# define SQLITE_OS_WIN 1 -# define SQLITE_OS_UNIX 0 -# else -# define SQLITE_OS_WIN 0 -# define SQLITE_OS_UNIX 1 -# endif -# else -# define SQLITE_OS_UNIX 0 -# endif -#else -# ifndef SQLITE_OS_WIN -# define SQLITE_OS_WIN 0 -# endif -#endif - -#endif /* SQLITE_OS_SETUP_H */ - -/************** End of os_setup.h ********************************************/ -/************** Continuing where we left off in os.h *************************/ - -/* If the SET_FULLSYNC macro is not defined above, then make it -** a no-op -*/ -#ifndef SET_FULLSYNC -# define SET_FULLSYNC(x,y) -#endif - -/* -** The default size of a disk sector -*/ -#ifndef SQLITE_DEFAULT_SECTOR_SIZE -# define SQLITE_DEFAULT_SECTOR_SIZE 4096 -#endif - -/* -** Temporary files are named starting with this prefix followed by 16 random -** alphanumeric characters, and no file extension. They are stored in the -** OS's standard temporary file directory, and are deleted prior to exit. -** If sqlite is being embedded in another program, you may wish to change the -** prefix to reflect your program's name, so that if your program exits -** prematurely, old temporary files can be easily identified. This can be done -** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. -** -** 2006-10-31: The default prefix used to be "sqlite_". But then -** Mcafee started using SQLite in their anti-virus product and it -** started putting files with the "sqlite" name in the c:/temp folder. -** This annoyed many windows users. Those users would then do a -** Google search for "sqlite", find the telephone numbers of the -** developers and call to wake them up at night and complain. -** For this reason, the default name prefix is changed to be "sqlite" -** spelled backwards. So the temp files are still identified, but -** anybody smart enough to figure out the code is also likely smart -** enough to know that calling the developer will not help get rid -** of the file. -*/ -#ifndef SQLITE_TEMP_FILE_PREFIX -# define SQLITE_TEMP_FILE_PREFIX "etilqs_" -#endif - -/* -** The following values may be passed as the second argument to -** sqlite3OsLock(). The various locks exhibit the following semantics: -** -** SHARED: Any number of processes may hold a SHARED lock simultaneously. -** RESERVED: A single process may hold a RESERVED lock on a file at -** any time. Other processes may hold and obtain new SHARED locks. -** PENDING: A single process may hold a PENDING lock on a file at -** any one time. Existing SHARED locks may persist, but no new -** SHARED locks may be obtained by other processes. -** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. -** -** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a -** process that requests an EXCLUSIVE lock may actually obtain a PENDING -** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to -** sqlite3OsLock(). -*/ -#define NO_LOCK 0 -#define SHARED_LOCK 1 -#define RESERVED_LOCK 2 -#define PENDING_LOCK 3 -#define EXCLUSIVE_LOCK 4 - -/* -** File Locking Notes: (Mostly about windows but also some info for Unix) -** -** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because -** those functions are not available. So we use only LockFile() and -** UnlockFile(). -** -** LockFile() prevents not just writing but also reading by other processes. -** A SHARED_LOCK is obtained by locking a single randomly-chosen -** byte out of a specific range of bytes. The lock byte is obtained at -** random so two separate readers can probably access the file at the -** same time, unless they are unlucky and choose the same lock byte. -** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. -** There can only be one writer. A RESERVED_LOCK is obtained by locking -** a single byte of the file that is designated as the reserved lock byte. -** A PENDING_LOCK is obtained by locking a designated byte different from -** the RESERVED_LOCK byte. -** -** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, -** which means we can use reader/writer locks. When reader/writer locks -** are used, the lock is placed on the same range of bytes that is used -** for probabilistic locking in Win95/98/ME. Hence, the locking scheme -** will support two or more Win95 readers or two or more WinNT readers. -** But a single Win95 reader will lock out all WinNT readers and a single -** WinNT reader will lock out all other Win95 readers. -** -** The following #defines specify the range of bytes used for locking. -** SHARED_SIZE is the number of bytes available in the pool from which -** a random byte is selected for a shared lock. The pool of bytes for -** shared locks begins at SHARED_FIRST. -** -** The same locking strategy and -** byte ranges are used for Unix. This leaves open the possibility of having -** clients on win95, winNT, and unix all talking to the same shared file -** and all locking correctly. To do so would require that samba (or whatever -** tool is being used for file sharing) implements locks correctly between -** windows and unix. I'm guessing that isn't likely to happen, but by -** using the same locking range we are at least open to the possibility. -** -** Locking in windows is manditory. For this reason, we cannot store -** actual data in the bytes used for locking. The pager never allocates -** the pages involved in locking therefore. SHARED_SIZE is selected so -** that all locks will fit on a single page even at the minimum page size. -** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE -** is set high so that we don't have to allocate an unused page except -** for very large databases. But one should test the page skipping logic -** by setting PENDING_BYTE low and running the entire regression suite. -** -** Changing the value of PENDING_BYTE results in a subtly incompatible -** file format. Depending on how it is changed, you might not notice -** the incompatibility right away, even running a full regression test. -** The default location of PENDING_BYTE is the first byte past the -** 1GB boundary. -** -*/ -#ifdef SQLITE_OMIT_WSD -# define PENDING_BYTE (0x40000000) -#else -# define PENDING_BYTE sqlite3PendingByte -#endif -#define RESERVED_BYTE (PENDING_BYTE+1) -#define SHARED_FIRST (PENDING_BYTE+2) -#define SHARED_SIZE 510 - -/* -** Wrapper around OS specific sqlite3_os_init() function. -*/ -SQLITE_PRIVATE int sqlite3OsInit(void); - -/* -** Functions for accessing sqlite3_file methods -*/ -SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); -SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); -SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); -SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); -SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); -SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); -SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); -#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 -SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); -SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); -SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); -SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); -SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); -SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); - - -/* -** Functions for accessing sqlite3_vfs methods -*/ -SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); -SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); -SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); -SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); -#ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); -SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); -SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); -SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); -SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); -SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); - -/* -** Convenience functions for opening and closing files using -** sqlite3_malloc() to obtain space for the file-handle structure. -*/ -SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); -SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); - -#endif /* _SQLITE_OS_H_ */ - -/************** End of os.h **************************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ -/************** Include mutex.h in the middle of sqliteInt.h *****************/ -/************** Begin file mutex.h *******************************************/ -/* -** 2007 August 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the common header for all mutex implementations. -** The sqliteInt.h header #includes this file so that it is available -** to all source files. We break it out in an effort to keep the code -** better organized. -** -** NOTE: source files should *not* #include this header file directly. -** Source files should #include the sqliteInt.h file and let that file -** include this one indirectly. -*/ - - -/* -** Figure out what version of the code to use. The choices are -** -** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The -** mutexes implementation cannot be overridden -** at start-time. -** -** SQLITE_MUTEX_NOOP For single-threaded applications. No -** mutual exclusion is provided. But this -** implementation can be overridden at -** start-time. -** -** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. -** -** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. -*/ -#if !SQLITE_THREADSAFE -# define SQLITE_MUTEX_OMIT -#endif -#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) -# if SQLITE_OS_UNIX -# define SQLITE_MUTEX_PTHREADS -# elif SQLITE_OS_WIN -# define SQLITE_MUTEX_W32 -# else -# define SQLITE_MUTEX_NOOP -# endif -#endif - -#ifdef SQLITE_MUTEX_OMIT -/* -** If this is a no-op implementation, implement everything as macros. -*/ -#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) -#define sqlite3_mutex_free(X) -#define sqlite3_mutex_enter(X) -#define sqlite3_mutex_try(X) SQLITE_OK -#define sqlite3_mutex_leave(X) -#define sqlite3_mutex_held(X) ((void)(X),1) -#define sqlite3_mutex_notheld(X) ((void)(X),1) -#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) -#define sqlite3MutexInit() SQLITE_OK -#define sqlite3MutexEnd() -#define MUTEX_LOGIC(X) -#else -#define MUTEX_LOGIC(X) X -#endif /* defined(SQLITE_MUTEX_OMIT) */ - -/************** End of mutex.h ***********************************************/ -/************** Continuing where we left off in sqliteInt.h ******************/ - -/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default -** synchronous setting to EXTRA. It is no longer supported. -*/ -#ifdef SQLITE_EXTRA_DURABLE -# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE -# define SQLITE_DEFAULT_SYNCHRONOUS 3 -#endif - -/* -** Default synchronous levels. -** -** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ -** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. -** -** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS -** OFF 1 0 -** NORMAL 2 1 -** FULL 3 2 -** EXTRA 4 3 -** -** The "PRAGMA synchronous" statement also uses the zero-based numbers. -** In other words, the zero-based numbers are used for all external interfaces -** and the one-based values are used internally. -*/ -#ifndef SQLITE_DEFAULT_SYNCHRONOUS -# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1) -#endif -#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS -# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS -#endif - -/* -** Each database file to be accessed by the system is an instance -** of the following structure. There are normally two of these structures -** in the sqlite.aDb[] array. aDb[0] is the main database file and -** aDb[1] is the database file used to hold temporary tables. Additional -** databases may be attached. -*/ -struct Db { - char *zDbSName; /* Name of this database. (schema name, not filename) */ - Btree *pBt; /* The B*Tree structure for this database file */ - u8 safety_level; /* How aggressive at syncing data to disk */ - u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ - Schema *pSchema; /* Pointer to database schema (possibly shared) */ -}; - -/* -** An instance of the following structure stores a database schema. -** -** Most Schema objects are associated with a Btree. The exception is -** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. -** In shared cache mode, a single Schema object can be shared by multiple -** Btrees that refer to the same underlying BtShared object. -** -** Schema objects are automatically deallocated when the last Btree that -** references them is destroyed. The TEMP Schema is manually freed by -** sqlite3_close(). -* -** A thread must be holding a mutex on the corresponding Btree in order -** to access Schema content. This implies that the thread must also be -** holding a mutex on the sqlite3 connection pointer that owns the Btree. -** For a TEMP Schema, only the connection mutex is required. -*/ -struct Schema { - int schema_cookie; /* Database schema version number for this file */ - int iGeneration; /* Generation counter. Incremented with each change */ - Hash tblHash; /* All tables indexed by name */ - Hash idxHash; /* All (named) indices indexed by name */ - Hash trigHash; /* All triggers indexed by name */ - Hash fkeyHash; /* All foreign keys by referenced table name */ - Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ - u8 file_format; /* Schema format version for this file */ - u8 enc; /* Text encoding used by this database */ - u16 schemaFlags; /* Flags associated with this schema */ - int cache_size; /* Number of pages to use in the cache */ -}; - -/* -** These macros can be used to test, set, or clear bits in the -** Db.pSchema->flags field. -*/ -#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) -#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0) -#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P) -#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P) - -/* -** Allowed values for the DB.pSchema->flags field. -** -** The DB_SchemaLoaded flag is set after the database schema has been -** read into internal hash tables. -** -** DB_UnresetViews means that one or more views have column names that -** have been filled out. If the schema changes, these column names might -** changes and so the view will need to be reset. -*/ -#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ -#define DB_UnresetViews 0x0002 /* Some views have defined column names */ -#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ - -/* -** The number of different kinds of things that can be limited -** using the sqlite3_limit() interface. -*/ -#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) - -/* -** Lookaside malloc is a set of fixed-size buffers that can be used -** to satisfy small transient memory allocation requests for objects -** associated with a particular database connection. The use of -** lookaside malloc provides a significant performance enhancement -** (approx 10%) by avoiding numerous malloc/free requests while parsing -** SQL statements. -** -** The Lookaside structure holds configuration information about the -** lookaside malloc subsystem. Each available memory allocation in -** the lookaside subsystem is stored on a linked list of LookasideSlot -** objects. -** -** Lookaside allocations are only allowed for objects that are associated -** with a particular database connection. Hence, schema information cannot -** be stored in lookaside because in shared cache mode the schema information -** is shared by multiple database connections. Therefore, while parsing -** schema information, the Lookaside.bEnabled flag is cleared so that -** lookaside allocations are not used to construct the schema objects. -*/ -struct Lookaside { - u32 bDisable; /* Only operate the lookaside when zero */ - u16 sz; /* Size of each buffer in bytes */ - u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ - int nOut; /* Number of buffers currently checked out */ - int mxOut; /* Highwater mark for nOut */ - int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ - LookasideSlot *pFree; /* List of available buffers */ - void *pStart; /* First byte of available memory space */ - void *pEnd; /* First byte past end of available space */ -}; -struct LookasideSlot { - LookasideSlot *pNext; /* Next buffer in the list of free buffers */ -}; - -/* -** A hash table for built-in function definitions. (Application-defined -** functions use a regular table table from hash.h.) -** -** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. -** Collisions are on the FuncDef.u.pHash chain. -*/ -#define SQLITE_FUNC_HASH_SZ 23 -struct FuncDefHash { - FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */ -}; - -#ifdef SQLITE_USER_AUTHENTICATION -/* -** Information held in the "sqlite3" database connection object and used -** to manage user authentication. -*/ -typedef struct sqlite3_userauth sqlite3_userauth; -struct sqlite3_userauth { - u8 authLevel; /* Current authentication level */ - int nAuthPW; /* Size of the zAuthPW in bytes */ - char *zAuthPW; /* Password used to authenticate */ - char *zAuthUser; /* User name used to authenticate */ -}; - -/* Allowed values for sqlite3_userauth.authLevel */ -#define UAUTH_Unknown 0 /* Authentication not yet checked */ -#define UAUTH_Fail 1 /* User authentication failed */ -#define UAUTH_User 2 /* Authenticated as a normal user */ -#define UAUTH_Admin 3 /* Authenticated as an administrator */ - -/* Functions used only by user authorization logic */ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); -SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); -SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); -SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - -#endif /* SQLITE_USER_AUTHENTICATION */ - -/* -** typedef for the authorization callback function. -*/ -#ifdef SQLITE_USER_AUTHENTICATION - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*, const char*); -#else - typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, - const char*); -#endif - -#ifndef SQLITE_OMIT_DEPRECATED -/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing -** in the style of sqlite3_trace() -*/ -#define SQLITE_TRACE_LEGACY 0x80 -#else -#define SQLITE_TRACE_LEGACY 0 -#endif /* SQLITE_OMIT_DEPRECATED */ - - -/* -** Each database connection is an instance of the following structure. -*/ -struct sqlite3 { - sqlite3_vfs *pVfs; /* OS Interface */ - struct Vdbe *pVdbe; /* List of active virtual machines */ - CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ - sqlite3_mutex *mutex; /* Connection mutex */ - Db *aDb; /* All backends */ - int nDb; /* Number of backends currently in use */ - int flags; /* Miscellaneous flags. See below */ - i64 lastRowid; /* ROWID of most recent insert (see above) */ - i64 szMmap; /* Default mmap_size setting */ - unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ - int errCode; /* Most recent error code (SQLITE_*) */ - int errMask; /* & result codes with this before returning */ - int iSysErrno; /* Errno value from last system error */ - u16 dbOptFlags; /* Flags to enable/disable optimizations */ - u8 enc; /* Text encoding */ - u8 autoCommit; /* The auto-commit flag. */ - u8 temp_store; /* 1: file 2: memory 0: default */ - u8 mallocFailed; /* True if we have seen a malloc failure */ - u8 bBenignMalloc; /* Do not require OOMs if true */ - u8 dfltLockMode; /* Default locking-mode for attached dbs */ - signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ - u8 suppressErr; /* Do not issue error messages if true */ - u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ - u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ - u8 mTrace; /* zero or more SQLITE_TRACE flags */ - int nextPagesize; /* Pagesize after VACUUM if >0 */ - u32 magic; /* Magic number for detect library misuse */ - int nChange; /* Value returned by sqlite3_changes() */ - int nTotalChange; /* Value returned by sqlite3_total_changes() */ - int aLimit[SQLITE_N_LIMIT]; /* Limits */ - int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ - struct sqlite3InitInfo { /* Information used during initialization */ - int newTnum; /* Rootpage of table being initialized */ - u8 iDb; /* Which db file is being initialized */ - u8 busy; /* TRUE if currently initializing */ - u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ - u8 imposterTable; /* Building an imposter table */ - } init; - int nVdbeActive; /* Number of VDBEs currently running */ - int nVdbeRead; /* Number of active VDBEs that read or write */ - int nVdbeWrite; /* Number of active VDBEs that read and write */ - int nVdbeExec; /* Number of nested calls to VdbeExec() */ - int nVDestroy; /* Number of active OP_VDestroy operations */ - int nExtension; /* Number of loaded extensions */ - void **aExtension; /* Array of shared library handles */ - int (*xTrace)(u32,void*,void*,void*); /* Trace function */ - void *pTraceArg; /* Argument to the trace function */ - void (*xProfile)(void*,const char*,u64); /* Profiling function */ - void *pProfileArg; /* Argument to profile function */ - void *pCommitArg; /* Argument to xCommitCallback() */ - int (*xCommitCallback)(void*); /* Invoked at every commit. */ - void *pRollbackArg; /* Argument to xRollbackCallback() */ - void (*xRollbackCallback)(void*); /* Invoked at every commit. */ - void *pUpdateArg; - void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ - void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */ - void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 - ); - PreUpdate *pPreUpdate; /* Context for active pre-update callback */ -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ -#ifndef SQLITE_OMIT_WAL - int (*xWalCallback)(void *, sqlite3 *, const char *, int); - void *pWalArg; -#endif - void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); - void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); - void *pCollNeededArg; - sqlite3_value *pErr; /* Most recent error message */ - union { - volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ - double notUsed1; /* Spacer */ - } u1; - Lookaside lookaside; /* Lookaside malloc configuration */ -#ifndef SQLITE_OMIT_AUTHORIZATION - sqlite3_xauth xAuth; /* Access authorization function */ - void *pAuthArg; /* 1st argument to the access auth function */ -#endif -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - int (*xProgress)(void *); /* The progress callback */ - void *pProgressArg; /* Argument to the progress callback */ - unsigned nProgressOps; /* Number of opcodes for progress callback */ -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - int nVTrans; /* Allocated size of aVTrans */ - Hash aModule; /* populated by sqlite3_create_module() */ - VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ - VTable **aVTrans; /* Virtual tables with open transactions */ - VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ -#endif - Hash aFunc; /* Hash table of connection functions */ - Hash aCollSeq; /* All collating sequences */ - BusyHandler busyHandler; /* Busy callback */ - Db aDbStatic[2]; /* Static space for the 2 default backends */ - Savepoint *pSavepoint; /* List of active savepoints */ - int busyTimeout; /* Busy handler timeout, in msec */ - int nSavepoint; /* Number of non-transaction savepoints */ - int nStatement; /* Number of nested statement-transactions */ - i64 nDeferredCons; /* Net deferred constraints this transaction. */ - i64 nDeferredImmCons; /* Net deferred immediate constraints */ - int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ -#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY - /* The following variables are all protected by the STATIC_MASTER - ** mutex, not by sqlite3.mutex. They are used by code in notify.c. - ** - ** When X.pUnlockConnection==Y, that means that X is waiting for Y to - ** unlock so that it can proceed. - ** - ** When X.pBlockingConnection==Y, that means that something that X tried - ** tried to do recently failed with an SQLITE_LOCKED error due to locks - ** held by Y. - */ - sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ - sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ - void *pUnlockArg; /* Argument to xUnlockNotify */ - void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ - sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ -#endif -#ifdef SQLITE_USER_AUTHENTICATION - sqlite3_userauth auth; /* User authentication information */ -#endif -}; - -/* -** A macro to discover the encoding of a database. -*/ -#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) -#define ENC(db) ((db)->enc) - -/* -** Possible values for the sqlite3.flags. -** -** Value constraints (enforced via assert()): -** SQLITE_FullFSync == PAGER_FULLFSYNC -** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC -** SQLITE_CacheSpill == PAGER_CACHE_SPILL -*/ -#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ -#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ -#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ -#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */ -#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ -#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ -#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ -#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ - /* DELETE, or UPDATE and return */ - /* the count using a callback. */ -#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ - /* result set is empty */ -#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ -#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ -#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */ -#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ -#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */ -#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ -#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */ -#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */ -#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */ -#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */ -#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ -#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ -#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ -#define SQLITE_LoadExtFunc 0x00800000 /* Enable load_extension() SQL func */ -#define SQLITE_EnableTrigger 0x01000000 /* True to enable triggers */ -#define SQLITE_DeferFKs 0x02000000 /* Defer all FK constraints */ -#define SQLITE_QueryOnly 0x04000000 /* Disable database changes */ -#define SQLITE_VdbeEQP 0x08000000 /* Debug EXPLAIN QUERY PLAN */ -#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */ -#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */ -#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */ - - -/* -** Bits of the sqlite3.dbOptFlags field that are used by the -** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to -** selectively disable various optimizations. -*/ -#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_ColumnCache 0x0002 /* Column cache */ -#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */ -#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */ -#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */ -#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */ -#define SQLITE_Transitive 0x0200 /* Transitive constraints */ -#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ -#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ -#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */ -#define SQLITE_AllOpts 0xffff /* All optimizations */ - -/* -** Macros for testing whether or not optimizations are enabled or disabled. -*/ -#ifndef SQLITE_OMIT_BUILTIN_TEST -#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) -#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) -#else -#define OptimizationDisabled(db, mask) 0 -#define OptimizationEnabled(db, mask) 1 -#endif - -/* -** Return true if it OK to factor constant expressions into the initialization -** code. The argument is a Parse object for the code generator. -*/ -#define ConstFactorOk(P) ((P)->okConstFactor) - -/* -** Possible values for the sqlite.magic field. -** The numbers are obtained at random and have no special meaning, other -** than being distinct from one another. -*/ -#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ -#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ -#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ -#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ -#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ -#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ - -/* -** Each SQL function is defined by an instance of the following -** structure. For global built-in functions (ex: substr(), max(), count()) -** a pointer to this structure is held in the sqlite3BuiltinFunctions object. -** For per-connection application-defined functions, a pointer to this -** structure is held in the db->aHash hash table. -** -** The u.pHash field is used by the global built-ins. The u.pDestructor -** field is used by per-connection app-def functions. -*/ -struct FuncDef { - i8 nArg; /* Number of arguments. -1 means unlimited */ - u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ - void *pUserData; /* User data parameter */ - FuncDef *pNext; /* Next function with same name */ - void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ - void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ - const char *zName; /* SQL name of the function. */ - union { - FuncDef *pHash; /* Next with a different name but the same hash */ - FuncDestructor *pDestructor; /* Reference counted destructor function */ - } u; -}; - -/* -** This structure encapsulates a user-function destructor callback (as -** configured using create_function_v2()) and a reference counter. When -** create_function_v2() is called to create a function with a destructor, -** a single object of this type is allocated. FuncDestructor.nRef is set to -** the number of FuncDef objects created (either 1 or 3, depending on whether -** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor -** member of each of the new FuncDef objects is set to point to the allocated -** FuncDestructor. -** -** Thereafter, when one of the FuncDef objects is deleted, the reference -** count on this object is decremented. When it reaches 0, the destructor -** is invoked and the FuncDestructor structure freed. -*/ -struct FuncDestructor { - int nRef; - void (*xDestroy)(void *); - void *pUserData; -}; - -/* -** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF -** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And -** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There -** are assert() statements in the code to verify this. -** -** Value constraints (enforced via assert()): -** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg -** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG -** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG -** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API -** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API -*/ -#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ -#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ -#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ -#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ -#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ -#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ -#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ -#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ -#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */ -#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ -#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */ -#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ -#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a - ** single query - might change over time */ - -/* -** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are -** used to create the initializers for the FuncDef structures. -** -** FUNCTION(zName, nArg, iArg, bNC, xFunc) -** Used to create a scalar function definition of a function zName -** implemented by C function xFunc that accepts nArg arguments. The -** value passed as iArg is cast to a (void*) and made available -** as the user-data (sqlite3_user_data()) for the function. If -** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. -** -** VFUNCTION(zName, nArg, iArg, bNC, xFunc) -** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. -** -** DFUNCTION(zName, nArg, iArg, bNC, xFunc) -** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and -** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions -** and functions like sqlite_version() that can change, but not during -** a single query. -** -** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) -** Used to create an aggregate function definition implemented by -** the C functions xStep and xFinal. The first four parameters -** are interpreted in the same way as the first 4 parameters to -** FUNCTION(). -** -** LIKEFUNC(zName, nArg, pArg, flags) -** Used to create a scalar function definition of a function zName -** that accepts nArg arguments and is implemented by a call to C -** function likeFunc. Argument pArg is cast to a (void *) and made -** available as the function user-data (sqlite3_user_data()). The -** FuncDef.flags variable is set to the value passed as the flags -** parameter. -*/ -#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } -#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - pArg, 0, xFunc, 0, #zName, } -#define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ - (void *)arg, 0, likeFunc, 0, #zName, {0} } -#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ - {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} -#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ - {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} - -/* -** All current savepoints are stored in a linked list starting at -** sqlite3.pSavepoint. The first element in the list is the most recently -** opened savepoint. Savepoints are added to the list by the vdbe -** OP_Savepoint instruction. -*/ -struct Savepoint { - char *zName; /* Savepoint name (nul-terminated) */ - i64 nDeferredCons; /* Number of deferred fk violations */ - i64 nDeferredImmCons; /* Number of deferred imm fk. */ - Savepoint *pNext; /* Parent savepoint (if any) */ -}; - -/* -** The following are used as the second parameter to sqlite3Savepoint(), -** and as the P1 argument to the OP_Savepoint instruction. -*/ -#define SAVEPOINT_BEGIN 0 -#define SAVEPOINT_RELEASE 1 -#define SAVEPOINT_ROLLBACK 2 - - -/* -** Each SQLite module (virtual table definition) is defined by an -** instance of the following structure, stored in the sqlite3.aModule -** hash table. -*/ -struct Module { - const sqlite3_module *pModule; /* Callback pointers */ - const char *zName; /* Name passed to create_module() */ - void *pAux; /* pAux passed to create_module() */ - void (*xDestroy)(void *); /* Module destructor function */ - Table *pEpoTab; /* Eponymous table for this module */ -}; - -/* -** information about each column of an SQL table is held in an instance -** of this structure. -*/ -struct Column { - char *zName; /* Name of this column, \000, then the type */ - Expr *pDflt; /* Default value of this column */ - char *zColl; /* Collating sequence. If NULL, use the default */ - u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ - char affinity; /* One of the SQLITE_AFF_... values */ - u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ - u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */ -}; - -/* Allowed values for Column.colFlags: -*/ -#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ -#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ -#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ - -/* -** A "Collating Sequence" is defined by an instance of the following -** structure. Conceptually, a collating sequence consists of a name and -** a comparison routine that defines the order of that sequence. -** -** If CollSeq.xCmp is NULL, it means that the -** collating sequence is undefined. Indices built on an undefined -** collating sequence may not be read or written. -*/ -struct CollSeq { - char *zName; /* Name of the collating sequence, UTF-8 encoded */ - u8 enc; /* Text encoding handled by xCmp() */ - void *pUser; /* First argument to xCmp() */ - int (*xCmp)(void*,int, const void*, int, const void*); - void (*xDel)(void*); /* Destructor for pUser */ -}; - -/* -** A sort order can be either ASC or DESC. -*/ -#define SQLITE_SO_ASC 0 /* Sort in ascending order */ -#define SQLITE_SO_DESC 1 /* Sort in ascending order */ -#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */ - -/* -** Column affinity types. -** -** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and -** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve -** the speed a little by numbering the values consecutively. -** -** But rather than start with 0 or 1, we begin with 'A'. That way, -** when multiple affinity types are concatenated into a string and -** used as the P4 operand, they will be more readable. -** -** Note also that the numeric types are grouped together so that testing -** for a numeric type is a single comparison. And the BLOB type is first. -*/ -#define SQLITE_AFF_BLOB 'A' -#define SQLITE_AFF_TEXT 'B' -#define SQLITE_AFF_NUMERIC 'C' -#define SQLITE_AFF_INTEGER 'D' -#define SQLITE_AFF_REAL 'E' - -#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) - -/* -** The SQLITE_AFF_MASK values masks off the significant bits of an -** affinity value. -*/ -#define SQLITE_AFF_MASK 0x47 - -/* -** Additional bit values that can be ORed with an affinity without -** changing the affinity. -** -** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL. -** It causes an assert() to fire if either operand to a comparison -** operator is NULL. It is added to certain comparison operators to -** prove that the operands are always NOT NULL. -*/ -#define SQLITE_KEEPNULL 0x08 /* Used by vector == or <> */ -#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ -#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */ -#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ -#define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */ - -/* -** An object of this type is created for each virtual table present in -** the database schema. -** -** If the database schema is shared, then there is one instance of this -** structure for each database connection (sqlite3*) that uses the shared -** schema. This is because each database connection requires its own unique -** instance of the sqlite3_vtab* handle used to access the virtual table -** implementation. sqlite3_vtab* handles can not be shared between -** database connections, even when the rest of the in-memory database -** schema is shared, as the implementation often stores the database -** connection handle passed to it via the xConnect() or xCreate() method -** during initialization internally. This database connection handle may -** then be used by the virtual table implementation to access real tables -** within the database. So that they appear as part of the callers -** transaction, these accesses need to be made via the same database -** connection as that used to execute SQL operations on the virtual table. -** -** All VTable objects that correspond to a single table in a shared -** database schema are initially stored in a linked-list pointed to by -** the Table.pVTable member variable of the corresponding Table object. -** When an sqlite3_prepare() operation is required to access the virtual -** table, it searches the list for the VTable that corresponds to the -** database connection doing the preparing so as to use the correct -** sqlite3_vtab* handle in the compiled query. -** -** When an in-memory Table object is deleted (for example when the -** schema is being reloaded for some reason), the VTable objects are not -** deleted and the sqlite3_vtab* handles are not xDisconnect()ed -** immediately. Instead, they are moved from the Table.pVTable list to -** another linked list headed by the sqlite3.pDisconnect member of the -** corresponding sqlite3 structure. They are then deleted/xDisconnected -** next time a statement is prepared using said sqlite3*. This is done -** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. -** Refer to comments above function sqlite3VtabUnlockList() for an -** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect -** list without holding the corresponding sqlite3.mutex mutex. -** -** The memory for objects of this type is always allocated by -** sqlite3DbMalloc(), using the connection handle stored in VTable.db as -** the first argument. -*/ -struct VTable { - sqlite3 *db; /* Database connection associated with this table */ - Module *pMod; /* Pointer to module implementation */ - sqlite3_vtab *pVtab; /* Pointer to vtab instance */ - int nRef; /* Number of pointers to this structure */ - u8 bConstraint; /* True if constraints are supported */ - int iSavepoint; /* Depth of the SAVEPOINT stack */ - VTable *pNext; /* Next in linked list (see above) */ -}; - -/* -** The schema for each SQL table and view is represented in memory -** by an instance of the following structure. -*/ -struct Table { - char *zName; /* Name of the table or view */ - Column *aCol; /* Information about each column */ - Index *pIndex; /* List of SQL indexes on this table. */ - Select *pSelect; /* NULL for tables. Points to definition if a view. */ - FKey *pFKey; /* Linked list of all foreign keys in this table */ - char *zColAff; /* String defining the affinity of each column */ - ExprList *pCheck; /* All CHECK constraints */ - /* ... also used as column name list in a VIEW */ - int tnum; /* Root BTree page for this table */ - i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ - i16 nCol; /* Number of columns in this table */ - u16 nRef; /* Number of pointers to this Table */ - LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ - LogEst szTabRow; /* Estimated size of each table row in bytes */ -#ifdef SQLITE_ENABLE_COSTMULT - LogEst costMult; /* Cost multiplier for using this table */ -#endif - u8 tabFlags; /* Mask of TF_* values */ - u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ -#ifndef SQLITE_OMIT_ALTERTABLE - int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - int nModuleArg; /* Number of arguments to the module */ - char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */ - VTable *pVTable; /* List of VTable objects. */ -#endif - Trigger *pTrigger; /* List of triggers stored in pSchema */ - Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ -}; - -/* -** Allowed values for Table.tabFlags. -** -** TF_OOOHidden applies to tables or view that have hidden columns that are -** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING -** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, -** the TF_OOOHidden attribute would apply in this case. Such tables require -** special handling during INSERT processing. -*/ -#define TF_Readonly 0x01 /* Read-only system table */ -#define TF_Ephemeral 0x02 /* An ephemeral table */ -#define TF_HasPrimaryKey 0x04 /* Table has a primary key */ -#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ -#define TF_Virtual 0x10 /* Is a virtual table */ -#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ -#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ - - -/* -** Test to see whether or not a table is a virtual table. This is -** done as a macro so that it will be optimized out when virtual -** table support is omitted from the build. -*/ -#ifndef SQLITE_OMIT_VIRTUALTABLE -# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0) -#else -# define IsVirtual(X) 0 -#endif - -/* -** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn() -** only works for non-virtual tables (ordinary tables and views) and is -** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined. The -** IsHiddenColumn() macro is general purpose. -*/ -#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS) -# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) -# define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) -#elif !defined(SQLITE_OMIT_VIRTUALTABLE) -# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) -# define IsOrdinaryHiddenColumn(X) 0 -#else -# define IsHiddenColumn(X) 0 -# define IsOrdinaryHiddenColumn(X) 0 -#endif - - -/* Does the table have a rowid */ -#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) -#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) - -/* -** Each foreign key constraint is an instance of the following structure. -** -** A foreign key is associated with two tables. The "from" table is -** the table that contains the REFERENCES clause that creates the foreign -** key. The "to" table is the table that is named in the REFERENCES clause. -** Consider this example: -** -** CREATE TABLE ex1( -** a INTEGER PRIMARY KEY, -** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) -** ); -** -** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". -** Equivalent names: -** -** from-table == child-table -** to-table == parent-table -** -** Each REFERENCES clause generates an instance of the following structure -** which is attached to the from-table. The to-table need not exist when -** the from-table is created. The existence of the to-table is not checked. -** -** The list of all parents for child Table X is held at X.pFKey. -** -** A list of all children for a table named Z (which might not even exist) -** is held in Schema.fkeyHash with a hash key of Z. -*/ -struct FKey { - Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ - FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of pFrom */ - char *zTo; /* Name of table that the key points to (aka: Parent) */ - FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */ - FKey *pPrevTo; /* Previous with the same zTo */ - int nCol; /* Number of columns in this key */ - /* EV: R-30323-21917 */ - u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ - u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ - Trigger *apTrigger[2];/* Triggers for aAction[] actions */ - struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ - int iFrom; /* Index of column in pFrom */ - char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ - } aCol[1]; /* One entry for each of nCol columns */ -}; - -/* -** SQLite supports many different ways to resolve a constraint -** error. ROLLBACK processing means that a constraint violation -** causes the operation in process to fail and for the current transaction -** to be rolled back. ABORT processing means the operation in process -** fails and any prior changes from that one operation are backed out, -** but the transaction is not rolled back. FAIL processing means that -** the operation in progress stops and returns an error code. But prior -** changes due to the same operation are not backed out and no rollback -** occurs. IGNORE means that the particular row that caused the constraint -** error is not inserted or updated. Processing continues and no error -** is returned. REPLACE means that preexisting database rows that caused -** a UNIQUE constraint violation are removed so that the new insert or -** update can proceed. Processing continues and no error is reported. -** -** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. -** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the -** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign -** key is set to NULL. CASCADE means that a DELETE or UPDATE of the -** referenced table row is propagated into the row that holds the -** foreign key. -** -** The following symbolic values are used to record which type -** of action to take. -*/ -#define OE_None 0 /* There is no constraint to check */ -#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ -#define OE_Abort 2 /* Back out changes but do no rollback transaction */ -#define OE_Fail 3 /* Stop the operation but leave all prior changes */ -#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ -#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ - -#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ -#define OE_SetNull 7 /* Set the foreign key value to NULL */ -#define OE_SetDflt 8 /* Set the foreign key value to its default */ -#define OE_Cascade 9 /* Cascade the changes */ - -#define OE_Default 10 /* Do whatever the default action is */ - - -/* -** An instance of the following structure is passed as the first -** argument to sqlite3VdbeKeyCompare and is used to control the -** comparison of the two index keys. -** -** Note that aSortOrder[] and aColl[] have nField+1 slots. There -** are nField slots for the columns of an index then one extra slot -** for the rowid at the end. -*/ -struct KeyInfo { - u32 nRef; /* Number of references to this KeyInfo object */ - u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ - u16 nField; /* Number of key columns in the index */ - u16 nXField; /* Number of columns beyond the key columns */ - sqlite3 *db; /* The database connection */ - u8 *aSortOrder; /* Sort order for each column. */ - CollSeq *aColl[1]; /* Collating sequence for each term of the key */ -}; - -/* -** This object holds a record which has been parsed out into individual -** fields, for the purposes of doing a comparison. -** -** A record is an object that contains one or more fields of data. -** Records are used to store the content of a table row and to store -** the key of an index. A blob encoding of a record is created by -** the OP_MakeRecord opcode of the VDBE and is disassembled by the -** OP_Column opcode. -** -** An instance of this object serves as a "key" for doing a search on -** an index b+tree. The goal of the search is to find the entry that -** is closed to the key described by this object. This object might hold -** just a prefix of the key. The number of fields is given by -** pKeyInfo->nField. -** -** The r1 and r2 fields are the values to return if this key is less than -** or greater than a key in the btree, respectively. These are normally -** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree -** is in DESC order. -** -** The key comparison functions actually return default_rc when they find -** an equals comparison. default_rc can be -1, 0, or +1. If there are -** multiple entries in the b-tree with the same key (when only looking -** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to -** cause the search to find the last match, or +1 to cause the search to -** find the first match. -** -** The key comparison functions will set eqSeen to true if they ever -** get and equal results when comparing this structure to a b-tree record. -** When default_rc!=0, the search might end up on the record immediately -** before the first match or immediately after the last match. The -** eqSeen field will indicate whether or not an exact match exists in the -** b-tree. -*/ -struct UnpackedRecord { - KeyInfo *pKeyInfo; /* Collation and sort-order information */ - Mem *aMem; /* Values */ - u16 nField; /* Number of entries in apMem[] */ - i8 default_rc; /* Comparison result if keys are equal */ - u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ - i8 r1; /* Value to return if (lhs > rhs) */ - i8 r2; /* Value to return if (rhs < lhs) */ - u8 eqSeen; /* True if an equality comparison has been seen */ -}; - - -/* -** Each SQL index is represented in memory by an -** instance of the following structure. -** -** The columns of the table that are to be indexed are described -** by the aiColumn[] field of this structure. For example, suppose -** we have the following table and index: -** -** CREATE TABLE Ex1(c1 int, c2 int, c3 text); -** CREATE INDEX Ex2 ON Ex1(c3,c1); -** -** In the Table structure describing Ex1, nCol==3 because there are -** three columns in the table. In the Index structure describing -** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. -** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the -** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. -** The second column to be indexed (c1) has an index of 0 in -** Ex1.aCol[], hence Ex2.aiColumn[1]==0. -** -** The Index.onError field determines whether or not the indexed columns -** must be unique and what to do if they are not. When Index.onError=OE_None, -** it means this is not a unique index. Otherwise it is a unique index -** and the value of Index.onError indicate the which conflict resolution -** algorithm to employ whenever an attempt is made to insert a non-unique -** element. -** -** While parsing a CREATE TABLE or CREATE INDEX statement in order to -** generate VDBE code (as opposed to parsing one read from an sqlite_master -** table as part of parsing an existing database schema), transient instances -** of this structure may be created. In this case the Index.tnum variable is -** used to store the address of a VDBE instruction, not a database page -** number (it cannot - the database page is not allocated until the VDBE -** program is executed). See convertToWithoutRowidTable() for details. -*/ -struct Index { - char *zName; /* Name of this index */ - i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ - LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */ - Table *pTable; /* The SQL table being indexed */ - char *zColAff; /* String defining the affinity of each column */ - Index *pNext; /* The next index associated with the same table */ - Schema *pSchema; /* Schema containing this index */ - u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ - const char **azColl; /* Array of collation sequence names for index */ - Expr *pPartIdxWhere; /* WHERE clause for partial indices */ - ExprList *aColExpr; /* Column expressions */ - int tnum; /* DB Page containing root of this index */ - LogEst szIdxRow; /* Estimated average row size in bytes */ - u16 nKeyCol; /* Number of columns forming the key */ - u16 nColumn; /* Number of columns stored in the index */ - u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ - unsigned bUnordered:1; /* Use this index for == or IN queries only */ - unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ - unsigned isResized:1; /* True if resizeIndexObject() has been called */ - unsigned isCovering:1; /* True if this is a covering index */ - unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int nSample; /* Number of elements in aSample[] */ - int nSampleCol; /* Size of IndexSample.anEq[] and so on */ - tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ - IndexSample *aSample; /* Samples of the left-most key */ - tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ - tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ -#endif -}; - -/* -** Allowed values for Index.idxType -*/ -#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ -#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ -#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ - -/* Return true if index X is a PRIMARY KEY index */ -#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) - -/* Return true if index X is a UNIQUE index */ -#define IsUniqueIndex(X) ((X)->onError!=OE_None) - -/* The Index.aiColumn[] values are normally positive integer. But -** there are some negative values that have special meaning: -*/ -#define XN_ROWID (-1) /* Indexed column is the rowid */ -#define XN_EXPR (-2) /* Indexed column is an expression */ - -/* -** Each sample stored in the sqlite_stat3 table is represented in memory -** using a structure of this type. See documentation at the top of the -** analyze.c source file for additional information. -*/ -struct IndexSample { - void *p; /* Pointer to sampled record */ - int n; /* Size of record in bytes */ - tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ - tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ - tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ -}; - -/* -** Each token coming out of the lexer is an instance of -** this structure. Tokens are also used as part of an expression. -** -** Note if Token.z==0 then Token.dyn and Token.n are undefined and -** may contain random values. Do not make any assumptions about Token.dyn -** and Token.n when Token.z==0. -*/ -struct Token { - const char *z; /* Text of the token. Not NULL-terminated! */ - unsigned int n; /* Number of characters in this token */ -}; - -/* -** An instance of this structure contains information needed to generate -** code for a SELECT that contains aggregate functions. -** -** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a -** pointer to this structure. The Expr.iColumn field is the index in -** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate -** code for that node. -** -** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the -** original Select structure that describes the SELECT statement. These -** fields do not need to be freed when deallocating the AggInfo structure. -*/ -struct AggInfo { - u8 directMode; /* Direct rendering mode means take data directly - ** from source tables rather than from accumulators */ - u8 useSortingIdx; /* In direct mode, reference the sorting index rather - ** than the source table */ - int sortingIdx; /* Cursor number of the sorting index */ - int sortingIdxPTab; /* Cursor number of pseudo-table */ - int nSortingColumn; /* Number of columns in the sorting index */ - int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ - ExprList *pGroupBy; /* The group by clause */ - struct AggInfo_col { /* For each column used in source tables */ - Table *pTab; /* Source table */ - int iTable; /* Cursor number of the source table */ - int iColumn; /* Column number within the source table */ - int iSorterColumn; /* Column number in the sorting index */ - int iMem; /* Memory location that acts as accumulator */ - Expr *pExpr; /* The original expression */ - } *aCol; - int nColumn; /* Number of used entries in aCol[] */ - int nAccumulator; /* Number of columns that show through to the output. - ** Additional columns are used only as parameters to - ** aggregate functions */ - struct AggInfo_func { /* For each aggregate function */ - Expr *pExpr; /* Expression encoding the function */ - FuncDef *pFunc; /* The aggregate function implementation */ - int iMem; /* Memory location that acts as accumulator */ - int iDistinct; /* Ephemeral table used to enforce DISTINCT */ - } *aFunc; - int nFunc; /* Number of entries in aFunc[] */ -}; - -/* -** The datatype ynVar is a signed integer, either 16-bit or 32-bit. -** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater -** than 32767 we have to make it 32-bit. 16-bit is preferred because -** it uses less memory in the Expr object, which is a big memory user -** in systems with lots of prepared statements. And few applications -** need more than about 10 or 20 variables. But some extreme users want -** to have prepared statements with over 32767 variables, and for them -** the option is available (at compile-time). -*/ -#if SQLITE_MAX_VARIABLE_NUMBER<=32767 -typedef i16 ynVar; -#else -typedef int ynVar; -#endif - -/* -** Each node of an expression in the parse tree is an instance -** of this structure. -** -** Expr.op is the opcode. The integer parser token codes are reused -** as opcodes here. For example, the parser defines TK_GE to be an integer -** code representing the ">=" operator. This same integer code is reused -** to represent the greater-than-or-equal-to operator in the expression -** tree. -** -** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, -** or TK_STRING), then Expr.token contains the text of the SQL literal. If -** the expression is a variable (TK_VARIABLE), then Expr.token contains the -** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), -** then Expr.token contains the name of the function. -** -** Expr.pRight and Expr.pLeft are the left and right subexpressions of a -** binary operator. Either or both may be NULL. -** -** Expr.x.pList is a list of arguments if the expression is an SQL function, -** a CASE expression or an IN expression of the form " IN (, ...)". -** Expr.x.pSelect is used if the expression is a sub-select or an expression of -** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the -** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is -** valid. -** -** An expression of the form ID or ID.ID refers to a column in a table. -** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is -** the integer cursor number of a VDBE cursor pointing to that table and -** Expr.iColumn is the column number for the specific column. If the -** expression is used as a result in an aggregate SELECT, then the -** value is also stored in the Expr.iAgg column in the aggregate so that -** it can be accessed after all aggregates are computed. -** -** If the expression is an unbound variable marker (a question mark -** character '?' in the original SQL) then the Expr.iTable holds the index -** number for that variable. -** -** If the expression is a subquery then Expr.iColumn holds an integer -** register number containing the result of the subquery. If the -** subquery gives a constant result, then iTable is -1. If the subquery -** gives a different answer at different times during statement processing -** then iTable is the address of a subroutine that computes the subquery. -** -** If the Expr is of type OP_Column, and the table it is selecting from -** is a disk table or the "old.*" pseudo-table, then pTab points to the -** corresponding table definition. -** -** ALLOCATION NOTES: -** -** Expr objects can use a lot of memory space in database schema. To -** help reduce memory requirements, sometimes an Expr object will be -** truncated. And to reduce the number of memory allocations, sometimes -** two or more Expr objects will be stored in a single memory allocation, -** together with Expr.zToken strings. -** -** If the EP_Reduced and EP_TokenOnly flags are set when -** an Expr object is truncated. When EP_Reduced is set, then all -** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees -** are contained within the same memory allocation. Note, however, that -** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately -** allocated, regardless of whether or not EP_Reduced is set. -*/ -struct Expr { - u8 op; /* Operation performed by this node */ - char affinity; /* The affinity of the column or 0 if not a column */ - u32 flags; /* Various flags. EP_* See below */ - union { - char *zToken; /* Token value. Zero terminated and dequoted */ - int iValue; /* Non-negative integer value if EP_IntValue */ - } u; - - /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no - ** space is allocated for the fields below this point. An attempt to - ** access them will result in a segfault or malfunction. - *********************************************************************/ - - Expr *pLeft; /* Left subnode */ - Expr *pRight; /* Right subnode */ - union { - ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */ - Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */ - } x; - - /* If the EP_Reduced flag is set in the Expr.flags mask, then no - ** space is allocated for the fields below this point. An attempt to - ** access them will result in a segfault or malfunction. - *********************************************************************/ - -#if SQLITE_MAX_EXPR_DEPTH>0 - int nHeight; /* Height of the tree headed by this node */ -#endif - int iTable; /* TK_COLUMN: cursor number of table holding column - ** TK_REGISTER: register number - ** TK_TRIGGER: 1 -> new, 0 -> old - ** EP_Unlikely: 134217728 times likelihood - ** TK_SELECT: 1st register of result vector */ - ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. - ** TK_VARIABLE: variable number (always >= 1). - ** TK_SELECT_COLUMN: column of the result vector */ - i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ - i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ - u8 op2; /* TK_REGISTER: original value of Expr.op - ** TK_COLUMN: the value of p5 for OP_Column - ** TK_AGG_FUNCTION: nesting depth */ - AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ - Table *pTab; /* Table for TK_COLUMN expressions. */ -}; - -/* -** The following are the meanings of bits in the Expr.flags field. -*/ -#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ -#define EP_Agg 0x000002 /* Contains one or more aggregate functions */ -#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */ -#define EP_Error 0x000008 /* Expression contains one or more errors */ -#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ -#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ -#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ -#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ -#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ -#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ -#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ -#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ -#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ -#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ -#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ -#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ -#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ -#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ -#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ -#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ -#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ -#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ -#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ - -/* -** Combinations of two or more EP_* flags -*/ -#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */ - -/* -** These macros can be used to test, set, or clear bits in the -** Expr.flags field. -*/ -#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) -#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) -#define ExprSetProperty(E,P) (E)->flags|=(P) -#define ExprClearProperty(E,P) (E)->flags&=~(P) - -/* The ExprSetVVAProperty() macro is used for Verification, Validation, -** and Accreditation only. It works like ExprSetProperty() during VVA -** processes but is a no-op for delivery. -*/ -#ifdef SQLITE_DEBUG -# define ExprSetVVAProperty(E,P) (E)->flags|=(P) -#else -# define ExprSetVVAProperty(E,P) -#endif - -/* -** Macros to determine the number of bytes required by a normal Expr -** struct, an Expr struct with the EP_Reduced flag set in Expr.flags -** and an Expr struct with the EP_TokenOnly flag set. -*/ -#define EXPR_FULLSIZE sizeof(Expr) /* Full size */ -#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */ -#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ - -/* -** Flags passed to the sqlite3ExprDup() function. See the header comment -** above sqlite3ExprDup() for details. -*/ -#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ - -/* -** A list of expressions. Each expression may optionally have a -** name. An expr/name combination can be used in several ways, such -** as the list of "expr AS ID" fields following a "SELECT" or in the -** list of "ID = expr" items in an UPDATE. A list of expressions can -** also be used as the argument to a function, in which case the a.zName -** field is not used. -** -** By default the Expr.zSpan field holds a human-readable description of -** the expression that is used in the generation of error messages and -** column labels. In this case, Expr.zSpan is typically the text of a -** column expression as it exists in a SELECT statement. However, if -** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name -** of the result column in the form: DATABASE.TABLE.COLUMN. This later -** form is used for name resolution with nested FROM clauses. -*/ -struct ExprList { - int nExpr; /* Number of expressions on the list */ - struct ExprList_item { /* For each expression in the list */ - Expr *pExpr; /* The list of expressions */ - char *zName; /* Token associated with this expression */ - char *zSpan; /* Original text of the expression */ - u8 sortOrder; /* 1 for DESC or 0 for ASC */ - unsigned done :1; /* A flag to indicate when processing is finished */ - unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ - unsigned reusable :1; /* Constant expression is reusable */ - union { - struct { - u16 iOrderByCol; /* For ORDER BY, column number in result set */ - u16 iAlias; /* Index into Parse.aAlias[] for zName */ - } x; - int iConstExprReg; /* Register in which Expr value is cached */ - } u; - } *a; /* Alloc a power of two greater or equal to nExpr */ -}; - -/* -** An instance of this structure is used by the parser to record both -** the parse tree for an expression and the span of input text for an -** expression. -*/ -struct ExprSpan { - Expr *pExpr; /* The expression parse tree */ - const char *zStart; /* First character of input text */ - const char *zEnd; /* One character past the end of input text */ -}; - -/* -** An instance of this structure can hold a simple list of identifiers, -** such as the list "a,b,c" in the following statements: -** -** INSERT INTO t(a,b,c) VALUES ...; -** CREATE INDEX idx ON t(a,b,c); -** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...; -** -** The IdList.a.idx field is used when the IdList represents the list of -** column names after a table name in an INSERT statement. In the statement -** -** INSERT INTO t(a,b,c) ... -** -** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. -*/ -struct IdList { - struct IdList_item { - char *zName; /* Name of the identifier */ - int idx; /* Index in some Table.aCol[] of a column named zName */ - } *a; - int nId; /* Number of identifiers on the list */ -}; - -/* -** The bitmask datatype defined below is used for various optimizations. -** -** Changing this from a 64-bit to a 32-bit type limits the number of -** tables in a join to 32 instead of 64. But it also reduces the size -** of the library by 738 bytes on ix86. -*/ -#ifdef SQLITE_BITMASK_TYPE - typedef SQLITE_BITMASK_TYPE Bitmask; -#else - typedef u64 Bitmask; -#endif - -/* -** The number of bits in a Bitmask. "BMS" means "BitMask Size". -*/ -#define BMS ((int)(sizeof(Bitmask)*8)) - -/* -** A bit in a Bitmask -*/ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) - -/* -** The following structure describes the FROM clause of a SELECT statement. -** Each table or subquery in the FROM clause is a separate element of -** the SrcList.a[] array. -** -** With the addition of multiple database support, the following structure -** can also be used to describe a particular table such as the table that -** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL, -** such a table must be a simple name: ID. But in SQLite, the table can -** now be identified by a database name, a dot, then the table name: ID.ID. -** -** The jointype starts out showing the join type between the current table -** and the next table on the list. The parser builds the list this way. -** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each -** jointype expresses the join between the table and the previous table. -** -** In the colUsed field, the high-order bit (bit 63) is set if the table -** contains more than 63 columns and the 64-th or later column is used. -*/ -struct SrcList { - int nSrc; /* Number of tables or subqueries in the FROM clause */ - u32 nAlloc; /* Number of entries allocated in a[] below */ - struct SrcList_item { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ - char *zName; /* Name of the table */ - char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ - struct { - u8 jointype; /* Type of join between this table and the previous */ - unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ - unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ - unsigned isTabFunc :1; /* True if table-valued-function syntax */ - unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ - } fg; -#ifndef SQLITE_OMIT_EXPLAIN - u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */ -#endif - int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ - Bitmask colUsed; /* Bit N (1<" clause */ - ExprList *pFuncArg; /* Arguments to table-valued-function */ - } u1; - Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - } a[1]; /* One entry for each identifier on the list */ -}; - -/* -** Permitted values of the SrcList.a.jointype field -*/ -#define JT_INNER 0x0001 /* Any kind of inner or cross join */ -#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */ -#define JT_NATURAL 0x0004 /* True for a "natural" join */ -#define JT_LEFT 0x0008 /* Left outer join */ -#define JT_RIGHT 0x0010 /* Right outer join */ -#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */ -#define JT_ERROR 0x0040 /* unknown or unsupported join type */ - - -/* -** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() -** and the WhereInfo.wctrlFlags member. -** -** Value constraints (enforced via assert()): -** WHERE_USE_LIMIT == SF_FixedLimit -*/ -#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */ -#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */ -#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ -#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ -#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */ -#define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */ -#define WHERE_OR_SUBCLAUSE 0x0020 /* Processing a sub-WHERE as part of - ** the OR optimization */ -#define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ -#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ -#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ -#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ -#define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ -#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ - /* 0x1000 not currently used */ - /* 0x2000 not currently used */ -#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ - /* 0x8000 not currently used */ - -/* Allowed return values from sqlite3WhereIsDistinct() -*/ -#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ -#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ -#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ -#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */ - -/* -** A NameContext defines a context in which to resolve table and column -** names. The context consists of a list of tables (the pSrcList) field and -** a list of named expression (pEList). The named expression list may -** be NULL. The pSrc corresponds to the FROM clause of a SELECT or -** to the table being operated on by INSERT, UPDATE, or DELETE. The -** pEList corresponds to the result set of a SELECT and is NULL for -** other statements. -** -** NameContexts can be nested. When resolving names, the inner-most -** context is searched first. If no match is found, the next outer -** context is checked. If there is still no match, the next context -** is checked. This process continues until either a match is found -** or all contexts are check. When a match is found, the nRef member of -** the context containing the match is incremented. -** -** Each subquery gets a new NameContext. The pNext field points to the -** NameContext in the parent query. Thus the process of scanning the -** NameContext list corresponds to searching through successively outer -** subqueries looking for a match. -*/ -struct NameContext { - Parse *pParse; /* The parser */ - SrcList *pSrcList; /* One or more tables used to resolve names */ - ExprList *pEList; /* Optional list of result-set columns */ - AggInfo *pAggInfo; /* Information about aggregates at this level */ - NameContext *pNext; /* Next outer name context. NULL for outermost */ - int nRef; /* Number of names resolved by this context */ - int nErr; /* Number of errors encountered while resolving names */ - u16 ncFlags; /* Zero or more NC_* flags defined below */ -}; - -/* -** Allowed values for the NameContext, ncFlags field. -** -** Value constraints (all checked via assert()): -** NC_HasAgg == SF_HasAgg -** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX -** -*/ -#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */ -#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */ -#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ -#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ -#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */ -#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */ -#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */ -#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ - -/* -** An instance of the following structure contains all information -** needed to generate code for a single SELECT statement. -** -** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0. -** If there is a LIMIT clause, the parser sets nLimit to the value of the -** limit and nOffset to the value of the offset (or 0 if there is not -** offset). But later on, nLimit and nOffset become the memory locations -** in the VDBE that record the limit and offset counters. -** -** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. -** These addresses must be stored so that we can go back and fill in -** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor -** the number of columns in P2 can be computed at the same time -** as the OP_OpenEphm instruction is coded because not -** enough information about the compound query is known at that point. -** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences -** for the result set. The KeyInfo for addrOpenEphm[2] contains collating -** sequences for the ORDER BY clause. -*/ -struct Select { - ExprList *pEList; /* The fields of the result */ - u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ - LogEst nSelectRow; /* Estimated number of result rows */ - u32 selFlags; /* Various SF_* values */ - int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ -#if SELECTTRACE_ENABLED - char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ -#endif - int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ - SrcList *pSrc; /* The FROM clause */ - Expr *pWhere; /* The WHERE clause */ - ExprList *pGroupBy; /* The GROUP BY clause */ - Expr *pHaving; /* The HAVING clause */ - ExprList *pOrderBy; /* The ORDER BY clause */ - Select *pPrior; /* Prior select in a compound select statement */ - Select *pNext; /* Next select to the left in a compound */ - Expr *pLimit; /* LIMIT expression. NULL means not used. */ - Expr *pOffset; /* OFFSET expression. NULL means not used. */ - With *pWith; /* WITH clause attached to this select. Or NULL. */ -}; - -/* -** Allowed values for Select.selFlags. The "SF" prefix stands for -** "Select Flag". -** -** Value constraints (all checked via assert()) -** SF_HasAgg == NC_HasAgg -** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX -** SF_FixedLimit == WHERE_USE_LIMIT -*/ -#define SF_Distinct 0x00001 /* Output should be DISTINCT */ -#define SF_All 0x00002 /* Includes the ALL keyword */ -#define SF_Resolved 0x00004 /* Identifiers have been resolved */ -#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */ -#define SF_HasAgg 0x00010 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */ -#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */ -#define SF_Compound 0x00100 /* Part of a compound query */ -#define SF_Values 0x00200 /* Synthesized from VALUES clause */ -#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */ -#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */ -#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */ -#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */ -#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */ -#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */ -#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */ -#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ - - -/* -** The results of a SELECT can be distributed in several ways, as defined -** by one of the following macros. The "SRT" prefix means "SELECT Result -** Type". -** -** SRT_Union Store results as a key in a temporary index -** identified by pDest->iSDParm. -** -** SRT_Except Remove results from the temporary index pDest->iSDParm. -** -** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result -** set is not empty. -** -** SRT_Discard Throw the results away. This is used by SELECT -** statements within triggers whose only purpose is -** the side-effects of functions. -** -** All of the above are free to ignore their ORDER BY clause. Those that -** follow must honor the ORDER BY clause. -** -** SRT_Output Generate a row of output (using the OP_ResultRow -** opcode) for each row in the result set. -** -** SRT_Mem Only valid if the result is a single column. -** Store the first column of the first result row -** in register pDest->iSDParm then abandon the rest -** of the query. This destination implies "LIMIT 1". -** -** SRT_Set The result must be a single column. Store each -** row of result as the key in table pDest->iSDParm. -** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". -** -** SRT_EphemTab Create an temporary table pDest->iSDParm and store -** the result there. The cursor is left open after -** returning. This is like SRT_Table except that -** this destination uses OP_OpenEphemeral to create -** the table first. -** -** SRT_Coroutine Generate a co-routine that returns a new row of -** results each time it is invoked. The entry point -** of the co-routine is stored in register pDest->iSDParm -** and the result row is stored in pDest->nDest registers -** starting with pDest->iSdst. -** -** SRT_Table Store results in temporary table pDest->iSDParm. -** SRT_Fifo This is like SRT_EphemTab except that the table -** is assumed to already be open. SRT_Fifo has -** the additional property of being able to ignore -** the ORDER BY clause. -** -** SRT_DistFifo Store results in a temporary table pDest->iSDParm. -** But also use temporary table pDest->iSDParm+1 as -** a record of all prior results and ignore any duplicate -** rows. Name means: "Distinct Fifo". -** -** SRT_Queue Store results in priority queue pDest->iSDParm (really -** an index). Append a sequence number so that all entries -** are distinct. -** -** SRT_DistQueue Store results in priority queue pDest->iSDParm only if -** the same record has never been stored before. The -** index at pDest->iSDParm+1 hold all prior stores. -*/ -#define SRT_Union 1 /* Store result as keys in an index */ -#define SRT_Except 2 /* Remove result from a UNION index */ -#define SRT_Exists 3 /* Store 1 if the result is not empty */ -#define SRT_Discard 4 /* Do not save the results anywhere */ -#define SRT_Fifo 5 /* Store result as data with an automatic rowid */ -#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */ -#define SRT_Queue 7 /* Store result in an queue */ -#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */ - -/* The ORDER BY clause is ignored for all of the above */ -#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue) - -#define SRT_Output 9 /* Output each row of result */ -#define SRT_Mem 10 /* Store result in a memory cell */ -#define SRT_Set 11 /* Store results as keys in an index */ -#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */ -#define SRT_Coroutine 13 /* Generate a single row of result */ -#define SRT_Table 14 /* Store result as data with an automatic rowid */ - -/* -** An instance of this object describes where to put of the results of -** a SELECT statement. -*/ -struct SelectDest { - u8 eDest; /* How to dispose of the results. On of SRT_* above. */ - char *zAffSdst; /* Affinity used when eDest==SRT_Set */ - int iSDParm; /* A parameter used by the eDest disposal method */ - int iSdst; /* Base register where results are written */ - int nSdst; /* Number of registers allocated */ - ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ -}; - -/* -** During code generation of statements that do inserts into AUTOINCREMENT -** tables, the following information is attached to the Table.u.autoInc.p -** pointer of each autoincrement table to record some side information that -** the code generator needs. We have to keep per-table autoincrement -** information in case inserts are done within triggers. Triggers do not -** normally coordinate their activities, but we do need to coordinate the -** loading and saving of autoincrement information. -*/ -struct AutoincInfo { - AutoincInfo *pNext; /* Next info block in a list of them all */ - Table *pTab; /* Table this info block refers to */ - int iDb; /* Index in sqlite3.aDb[] of database holding pTab */ - int regCtr; /* Memory register holding the rowid counter */ -}; - -/* -** Size of the column cache -*/ -#ifndef SQLITE_N_COLCACHE -# define SQLITE_N_COLCACHE 10 -#endif - -/* -** At least one instance of the following structure is created for each -** trigger that may be fired while parsing an INSERT, UPDATE or DELETE -** statement. All such objects are stored in the linked list headed at -** Parse.pTriggerPrg and deleted once statement compilation has been -** completed. -** -** A Vdbe sub-program that implements the body and WHEN clause of trigger -** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of -** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable. -** The Parse.pTriggerPrg list never contains two entries with the same -** values for both pTrigger and orconf. -** -** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns -** accessed (or set to 0 for triggers fired as a result of INSERT -** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to -** a mask of new.* columns used by the program. -*/ -struct TriggerPrg { - Trigger *pTrigger; /* Trigger this program was coded from */ - TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ - SubProgram *pProgram; /* Program implementing pTrigger/orconf */ - int orconf; /* Default ON CONFLICT policy */ - u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ -}; - -/* -** The yDbMask datatype for the bitmask of all attached databases. -*/ -#if SQLITE_MAX_ATTACHED>30 - typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; -# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) -# define DbMaskZero(M) memset((M),0,sizeof(M)) -# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) -# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) -# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) -#else - typedef unsigned int yDbMask; -# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) -# define DbMaskZero(M) (M)=0 -# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) -# define DbMaskAllZero(M) (M)==0 -# define DbMaskNonZero(M) (M)!=0 -#endif - -/* -** An SQL parser context. A copy of this structure is passed through -** the parser and down into all the parser action routine in order to -** carry around information that is global to the entire parse. -** -** The structure is divided into two parts. When the parser and code -** generate call themselves recursively, the first part of the structure -** is constant but the second part is reset at the beginning and end of -** each recursion. -** -** The nTableLock and aTableLock variables are only used if the shared-cache -** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are -** used to store the set of table-locks required by the statement being -** compiled. Function sqlite3TableLock() is used to add entries to the -** list. -*/ -struct Parse { - sqlite3 *db; /* The main database structure */ - char *zErrMsg; /* An error message */ - Vdbe *pVdbe; /* An engine for executing database bytecode */ - int rc; /* Return code from execution */ - u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ - u8 checkSchema; /* Causes schema cookie check after an error */ - u8 nested; /* Number of nested calls to the parser/code generator */ - u8 nTempReg; /* Number of temporary registers in aTempReg[] */ - u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ - u8 mayAbort; /* True if statement may throw an ABORT exception */ - u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ - u8 okConstFactor; /* OK to factor out constants */ - u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 nColCache; /* Number of entries in aColCache[] */ - int nRangeReg; /* Size of the temporary register block */ - int iRangeReg; /* First register in temporary register block */ - int nErr; /* Number of errors seen */ - int nTab; /* Number of previously allocated VDBE cursors */ - int nMem; /* Number of memory cells used so far */ - int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ - int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ - int ckBase; /* Base register of data during check constraints */ - int iSelfTab; /* Table of an index whose exprs are being coded */ - int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ - int iCacheCnt; /* Counter used to generate aColCache[].lru values */ - int nLabel; /* Number of labels used */ - int *aLabel; /* Space to hold the labels */ - ExprList *pConstExpr;/* Constant expressions */ - Token constraintName;/* Name of the constraint currently being parsed */ - yDbMask writeMask; /* Start a write transaction on these databases */ - yDbMask cookieMask; /* Bitmask of schema verified databases */ - int regRowid; /* Register holding rowid of CREATE TABLE entry */ - int regRoot; /* Register holding root page number for new objects */ - int nMaxArg; /* Max args passed to user function by sub-program */ -#if SELECTTRACE_ENABLED - int nSelect; /* Number of SELECT statements seen */ - int nSelectIndent; /* How far to indent SELECTTRACE() output */ -#endif -#ifndef SQLITE_OMIT_SHARED_CACHE - int nTableLock; /* Number of locks in aTableLock */ - TableLock *aTableLock; /* Required table locks for shared-cache mode */ -#endif - AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ - Parse *pToplevel; /* Parse structure for main program (or NULL) */ - Table *pTriggerTab; /* Table triggers are being coded for */ - int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ - u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ - u32 oldmask; /* Mask of old.* columns referenced */ - u32 newmask; /* Mask of new.* columns referenced */ - u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ - u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ - u8 disableTriggers; /* True to disable triggers */ - - /************************************************************************** - ** Fields above must be initialized to zero. The fields that follow, - ** down to the beginning of the recursive section, do not need to be - ** initialized as they will be set before being used. The boundary is - ** determined by offsetof(Parse,aColCache). - **************************************************************************/ - - struct yColCache { - int iTable; /* Table cursor number */ - i16 iColumn; /* Table column number */ - u8 tempReg; /* iReg is a temp register that needs to be freed */ - int iLevel; /* Nesting level */ - int iReg; /* Reg with value of this column. 0 means none. */ - int lru; /* Least recently used entry has the smallest value */ - } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ - int aTempReg[8]; /* Holding area for temporary registers */ - Token sNameToken; /* Token with unqualified schema object name */ - Token sLastToken; /* The last token parsed */ - - /************************************************************************ - ** Above is constant between recursions. Below is reset before and after - ** each recursion. The boundary between these two regions is determined - ** using offsetof(Parse,nVar) so the nVar field must be the first field - ** in the recursive region. - ************************************************************************/ - - ynVar nVar; /* Number of '?' variables seen in the SQL so far */ - int nzVar; /* Number of available slots in azVar[] */ - u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ - u8 explain; /* True if the EXPLAIN flag is found on the query */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ - int nVtabLock; /* Number of virtual tables to lock */ -#endif - int nHeight; /* Expression tree height of current sub-select */ -#ifndef SQLITE_OMIT_EXPLAIN - int iSelectId; /* ID of current select for EXPLAIN output */ - int iNextSelectId; /* Next available select ID for EXPLAIN output */ -#endif - char **azVar; /* Pointers to names of parameters */ - Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ - const char *zTail; /* All SQL text past the last semicolon parsed */ - Table *pNewTable; /* A table being constructed by CREATE TABLE */ - Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ - const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - Token sArg; /* Complete text of a module argument */ - Table **apVtabLock; /* Pointer to virtual tables needing locking */ -#endif - Table *pZombieTab; /* List of Table objects to delete after code gen */ - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ - With *pWith; /* Current WITH clause, or NULL */ - With *pWithToFree; /* Free this WITH object at the end of the parse */ -}; - -/* -** Sizes and pointers of various parts of the Parse object. -*/ -#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ -#define PARSE_RECURSE_SZ offsetof(Parse,nVar) /* Recursive part */ -#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ -#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ - -/* -** Return true if currently inside an sqlite3_declare_vtab() call. -*/ -#ifdef SQLITE_OMIT_VIRTUALTABLE - #define IN_DECLARE_VTAB 0 -#else - #define IN_DECLARE_VTAB (pParse->declareVtab) -#endif - -/* -** An instance of the following structure can be declared on a stack and used -** to save the Parse.zAuthContext value so that it can be restored later. -*/ -struct AuthContext { - const char *zAuthContext; /* Put saved Parse.zAuthContext here */ - Parse *pParse; /* The Parse structure */ -}; - -/* -** Bitfield flags for P5 value in various opcodes. -** -** Value constraints (enforced via assert()): -** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH -** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF -** OPFLAG_BULKCSR == BTREE_BULKLOAD -** OPFLAG_SEEKEQ == BTREE_SEEK_EQ -** OPFLAG_FORDELETE == BTREE_FORDELETE -** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION -** OPFLAG_AUXDELETE == BTREE_AUXDELETE -*/ -#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ - /* Also used in P2 (not P5) of OP_Delete */ -#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ -#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ -#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ -#define OPFLAG_APPEND 0x08 /* This is likely to be an append */ -#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ -#endif -#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ -#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ -#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ -#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ -#define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ -#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ -#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ -#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */ -#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ - -/* - * Each trigger present in the database schema is stored as an instance of - * struct Trigger. - * - * Pointers to instances of struct Trigger are stored in two ways. - * 1. In the "trigHash" hash table (part of the sqlite3* that represents the - * database). This allows Trigger structures to be retrieved by name. - * 2. All triggers associated with a single table form a linked list, using the - * pNext member of struct Trigger. A pointer to the first element of the - * linked list is stored as the "pTrigger" member of the associated - * struct Table. - * - * The "step_list" member points to the first element of a linked list - * containing the SQL statements specified as the trigger program. - */ -struct Trigger { - char *zName; /* The name of the trigger */ - char *table; /* The table or view to which the trigger applies */ - u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ - u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ - Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ - IdList *pColumns; /* If this is an UPDATE OF trigger, - the is stored here */ - Schema *pSchema; /* Schema containing the trigger */ - Schema *pTabSchema; /* Schema containing the table */ - TriggerStep *step_list; /* Link list of trigger program steps */ - Trigger *pNext; /* Next trigger associated with the table */ -}; - -/* -** A trigger is either a BEFORE or an AFTER trigger. The following constants -** determine which. -** -** If there are multiple triggers, you might of some BEFORE and some AFTER. -** In that cases, the constants below can be ORed together. -*/ -#define TRIGGER_BEFORE 1 -#define TRIGGER_AFTER 2 - -/* - * An instance of struct TriggerStep is used to store a single SQL statement - * that is a part of a trigger-program. - * - * Instances of struct TriggerStep are stored in a singly linked list (linked - * using the "pNext" member) referenced by the "step_list" member of the - * associated struct Trigger instance. The first element of the linked list is - * the first step of the trigger-program. - * - * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or - * "SELECT" statement. The meanings of the other members is determined by the - * value of "op" as follows: - * - * (op == TK_INSERT) - * orconf -> stores the ON CONFLICT algorithm - * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then - * this stores a pointer to the SELECT statement. Otherwise NULL. - * zTarget -> Dequoted name of the table to insert into. - * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then - * this stores values to be inserted. Otherwise NULL. - * pIdList -> If this is an INSERT INTO ... () VALUES ... - * statement, then this stores the column-names to be - * inserted into. - * - * (op == TK_DELETE) - * zTarget -> Dequoted name of the table to delete from. - * pWhere -> The WHERE clause of the DELETE statement if one is specified. - * Otherwise NULL. - * - * (op == TK_UPDATE) - * zTarget -> Dequoted name of the table to update. - * pWhere -> The WHERE clause of the UPDATE statement if one is specified. - * Otherwise NULL. - * pExprList -> A list of the columns to update and the expressions to update - * them to. See sqlite3Update() documentation of "pChanges" - * argument. - * - */ -struct TriggerStep { - u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ - u8 orconf; /* OE_Rollback etc. */ - Trigger *pTrig; /* The trigger that this step is a part of */ - Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ - char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ - Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE. */ - IdList *pIdList; /* Column names for INSERT */ - TriggerStep *pNext; /* Next in the link-list */ - TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ -}; - -/* -** The following structure contains information used by the sqliteFix... -** routines as they walk the parse tree to make database references -** explicit. -*/ -typedef struct DbFixer DbFixer; -struct DbFixer { - Parse *pParse; /* The parsing context. Error messages written here */ - Schema *pSchema; /* Fix items to this schema */ - int bVarOnly; /* Check for variable references only */ - const char *zDb; /* Make sure all objects are contained in this database */ - const char *zType; /* Type of the container - used for error messages */ - const Token *pName; /* Name of the container - used for error messages */ -}; - -/* -** An objected used to accumulate the text of a string where we -** do not necessarily know how big the string will be in the end. -*/ -struct StrAccum { - sqlite3 *db; /* Optional database for lookaside. Can be NULL */ - char *zBase; /* A base allocation. Not from malloc. */ - char *zText; /* The string collected so far */ - u32 nChar; /* Length of the string so far */ - u32 nAlloc; /* Amount of space allocated in zText */ - u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ - u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ - u8 printfFlags; /* SQLITE_PRINTF flags below */ -}; -#define STRACCUM_NOMEM 1 -#define STRACCUM_TOOBIG 2 -#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ -#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ -#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ - -#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) - - -/* -** A pointer to this structure is used to communicate information -** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. -*/ -typedef struct { - sqlite3 *db; /* The database being initialized */ - char **pzErrMsg; /* Error message stored here */ - int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ - int rc; /* Result code stored here */ -} InitData; - -/* -** Structure containing global configuration data for the SQLite library. -** -** This structure also contains some state information. -*/ -struct Sqlite3Config { - int bMemstat; /* True to enable memory status */ - int bCoreMutex; /* True to enable core mutexing */ - int bFullMutex; /* True to enable full mutexing */ - int bOpenUri; /* True to interpret filenames as URIs */ - int bUseCis; /* Use covering indices for full-scans */ - int mxStrlen; /* Maximum string length */ - int neverCorrupt; /* Database is always well-formed */ - int szLookaside; /* Default lookaside buffer size */ - int nLookaside; /* Default lookaside buffer count */ - int nStmtSpill; /* Stmt-journal spill-to-disk threshold */ - sqlite3_mem_methods m; /* Low-level memory allocation interface */ - sqlite3_mutex_methods mutex; /* Low-level mutex interface */ - sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ - void *pHeap; /* Heap storage space */ - int nHeap; /* Size of pHeap[] */ - int mnReq, mxReq; /* Min and max heap requests sizes */ - sqlite3_int64 szMmap; /* mmap() space per open file */ - sqlite3_int64 mxMmap; /* Maximum value for szMmap */ - void *pScratch; /* Scratch memory */ - int szScratch; /* Size of each scratch buffer */ - int nScratch; /* Number of scratch buffers */ - void *pPage; /* Page cache memory */ - int szPage; /* Size of each page in pPage[] */ - int nPage; /* Number of pages in pPage[] */ - int mxParserStack; /* maximum depth of the parser stack */ - int sharedCacheEnabled; /* true if shared-cache mode enabled */ - u32 szPma; /* Maximum Sorter PMA size */ - /* The above might be initialized to non-zero. The following need to always - ** initially be zero, however. */ - int isInit; /* True after initialization has finished */ - int inProgress; /* True while initialization in progress */ - int isMutexInit; /* True after mutexes are initialized */ - int isMallocInit; /* True after malloc is initialized */ - int isPCacheInit; /* True after malloc is initialized */ - int nRefInitMutex; /* Number of users of pInitMutex */ - sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ - void (*xLog)(void*,int,const char*); /* Function for logging */ - void *pLogArg; /* First argument to xLog() */ -#ifdef SQLITE_ENABLE_SQLLOG - void(*xSqllog)(void*,sqlite3*,const char*, int); - void *pSqllogArg; -#endif -#ifdef SQLITE_VDBE_COVERAGE - /* The following callback (if not NULL) is invoked on every VDBE branch - ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. - */ - void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ - void *pVdbeBranchArg; /* 1st argument */ -#endif -#ifndef SQLITE_OMIT_BUILTIN_TEST - int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ -#endif - int bLocaltimeFault; /* True to fail localtime() calls */ - int iOnceResetThreshold; /* When to reset OP_Once counters */ -}; - -/* -** This macro is used inside of assert() statements to indicate that -** the assert is only valid on a well-formed database. Instead of: -** -** assert( X ); -** -** One writes: -** -** assert( X || CORRUPT_DB ); -** -** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate -** that the database is definitely corrupt, only that it might be corrupt. -** For most test cases, CORRUPT_DB is set to false using a special -** sqlite3_test_control(). This enables assert() statements to prove -** things that are always true for well-formed databases. -*/ -#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) - -/* -** Context pointer passed down through the tree-walk. -*/ -struct Walker { - Parse *pParse; /* Parser context. */ - int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ - int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ - void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ - int walkerDepth; /* Number of subqueries */ - u8 eCode; /* A small processing code */ - union { /* Extra data for callback */ - NameContext *pNC; /* Naming context */ - int n; /* A counter */ - int iCur; /* A cursor number */ - SrcList *pSrcList; /* FROM clause */ - struct SrcCount *pSrcCount; /* Counting column references */ - struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ - int *aiCol; /* array of column indexes */ - struct IdxCover *pIdxCover; /* Check for index coverage */ - } u; -}; - -/* Forward declarations */ -SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); -SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); -SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); -SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); -SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); -SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); - -/* -** Return code from the parse-tree walking primitives and their -** callbacks. -*/ -#define WRC_Continue 0 /* Continue down into children */ -#define WRC_Prune 1 /* Omit children but continue walking siblings */ -#define WRC_Abort 2 /* Abandon the tree walk */ - -/* -** An instance of this structure represents a set of one or more CTEs -** (common table expressions) created by a single WITH clause. -*/ -struct With { - int nCte; /* Number of CTEs in the WITH clause */ - With *pOuter; /* Containing WITH clause, or NULL */ - struct Cte { /* For each CTE in the WITH clause.... */ - char *zName; /* Name of this CTE */ - ExprList *pCols; /* List of explicit column names, or NULL */ - Select *pSelect; /* The definition of this CTE */ - const char *zCteErr; /* Error message for circular references */ - } a[1]; -}; - -#ifdef SQLITE_DEBUG -/* -** An instance of the TreeView object is used for printing the content of -** data structures on sqlite3DebugPrintf() using a tree-like view. -*/ -struct TreeView { - int iLevel; /* Which level of the tree we are on */ - u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */ -}; -#endif /* SQLITE_DEBUG */ - -/* -** Assuming zIn points to the first byte of a UTF-8 character, -** advance zIn to point to the first byte of the next UTF-8 character. -*/ -#define SQLITE_SKIP_UTF8(zIn) { \ - if( (*(zIn++))>=0xc0 ){ \ - while( (*zIn & 0xc0)==0x80 ){ zIn++; } \ - } \ -} - -/* -** The SQLITE_*_BKPT macros are substitutes for the error codes with -** the same name but without the _BKPT suffix. These macros invoke -** routines that report the line-number on which the error originated -** using sqlite3_log(). The routines also provide a convenient place -** to set a debugger breakpoint. -*/ -SQLITE_PRIVATE int sqlite3CorruptError(int); -SQLITE_PRIVATE int sqlite3MisuseError(int); -SQLITE_PRIVATE int sqlite3CantopenError(int); -#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__) -#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__) -#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__) -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3NomemError(int); -SQLITE_PRIVATE int sqlite3IoerrnomemError(int); -# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__) -# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__) -#else -# define SQLITE_NOMEM_BKPT SQLITE_NOMEM -# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM -#endif - -/* -** FTS3 and FTS4 both require virtual table support -*/ -#if defined(SQLITE_OMIT_VIRTUALTABLE) -# undef SQLITE_ENABLE_FTS3 -# undef SQLITE_ENABLE_FTS4 -#endif - -/* -** FTS4 is really an extension for FTS3. It is enabled using the -** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call -** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. -*/ -#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) -# define SQLITE_ENABLE_FTS3 1 -#endif - -/* -** The ctype.h header is needed for non-ASCII systems. It is also -** needed by FTS3 when FTS3 is included in the amalgamation. -*/ -#if !defined(SQLITE_ASCII) || \ - (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) -# include -#endif - -/* -** The following macros mimic the standard library functions toupper(), -** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The -** sqlite versions only work for ASCII characters, regardless of locale. -*/ -#ifdef SQLITE_ASCII -# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20)) -# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01) -# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06) -# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02) -# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) -# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) -# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) -# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) -#else -# define sqlite3Toupper(x) toupper((unsigned char)(x)) -# define sqlite3Isspace(x) isspace((unsigned char)(x)) -# define sqlite3Isalnum(x) isalnum((unsigned char)(x)) -# define sqlite3Isalpha(x) isalpha((unsigned char)(x)) -# define sqlite3Isdigit(x) isdigit((unsigned char)(x)) -# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) -# define sqlite3Tolower(x) tolower((unsigned char)(x)) -# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') -#endif -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_PRIVATE int sqlite3IsIdChar(u8); -#endif - -/* -** Internal function prototypes -*/ -SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*); -SQLITE_PRIVATE int sqlite3Strlen30(const char*); -SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*); -#define sqlite3StrNICmp sqlite3_strnicmp - -SQLITE_PRIVATE int sqlite3MallocInit(void); -SQLITE_PRIVATE void sqlite3MallocEnd(void); -SQLITE_PRIVATE void *sqlite3Malloc(u64); -SQLITE_PRIVATE void *sqlite3MallocZero(u64); -SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); -SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); -SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64); -SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); -SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); -SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); -SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); -SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); -SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); -SQLITE_PRIVATE int sqlite3MallocSize(void*); -SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); -SQLITE_PRIVATE void *sqlite3ScratchMalloc(int); -SQLITE_PRIVATE void sqlite3ScratchFree(void*); -SQLITE_PRIVATE void *sqlite3PageMalloc(int); -SQLITE_PRIVATE void sqlite3PageFree(void*); -SQLITE_PRIVATE void sqlite3MemSetDefault(void); -#ifndef SQLITE_OMIT_BUILTIN_TEST -SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); -#endif -SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); - -/* -** On systems with ample stack space and that support alloca(), make -** use of alloca() to obtain space for large automatic objects. By default, -** obtain space from malloc(). -** -** The alloca() routine never returns NULL. This will cause code paths -** that deal with sqlite3StackAlloc() failures to be unreachable. -*/ -#ifdef SQLITE_USE_ALLOCA -# define sqlite3StackAllocRaw(D,N) alloca(N) -# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) -# define sqlite3StackFree(D,P) -#else -# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) -# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) -# define sqlite3StackFree(D,P) sqlite3DbFree(D,P) -#endif - -/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they -** are, disable MEMSYS3 -*/ -#ifdef SQLITE_ENABLE_MEMSYS5 -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); -#undef SQLITE_ENABLE_MEMSYS3 -#endif -#ifdef SQLITE_ENABLE_MEMSYS3 -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); -#endif - - -#ifndef SQLITE_MUTEX_OMIT -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void); -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void); -SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int); -SQLITE_PRIVATE int sqlite3MutexInit(void); -SQLITE_PRIVATE int sqlite3MutexEnd(void); -#endif -#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP) -SQLITE_PRIVATE void sqlite3MemoryBarrier(void); -#else -# define sqlite3MemoryBarrier() -#endif - -SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); -SQLITE_PRIVATE void sqlite3StatusUp(int, int); -SQLITE_PRIVATE void sqlite3StatusDown(int, int); -SQLITE_PRIVATE void sqlite3StatusHighwater(int, int); - -/* Access to mutexes used by sqlite3_status() */ -SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); -SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); - -#ifndef SQLITE_OMIT_FLOATING_POINT -SQLITE_PRIVATE int sqlite3IsNaN(double); -#else -# define sqlite3IsNaN(X) 0 -#endif - -/* -** An instance of the following structure holds information about SQL -** functions arguments that are the parameters to the printf() function. -*/ -struct PrintfArguments { - int nArg; /* Total number of arguments */ - int nUsed; /* Number of arguments used so far */ - sqlite3_value **apArg; /* The argument values */ -}; - -SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, const char*, va_list); -SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...); -SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); -SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) -SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); -#endif -#if defined(SQLITE_TEST) -SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); -#endif - -#if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); -SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); -SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); -SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); -SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); -#endif - - -SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); -SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); -SQLITE_PRIVATE void sqlite3Dequote(char*); -SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); -SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); -SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); -SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); -SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); -SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); -SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); -SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); -SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); -#endif -SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); -SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); -SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); -SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); -SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); -SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); -SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); -SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); -SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); -SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); -SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); -SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int); -SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); -SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); -SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); -SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); -SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); -SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); -SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); -SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); -SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); -SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); -SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); -SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); -SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); -SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*); -SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*); -SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); -SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); -SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16); -SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); -#if SQLITE_ENABLE_HIDDEN_COLUMNS -SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*); -#else -# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ -#endif -SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*); -SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); -SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); -SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); -SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*); -SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); -SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); -SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, - sqlite3_vfs**,char**,char **); -SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); - -#ifdef SQLITE_OMIT_BUILTIN_TEST -# define sqlite3FaultSim(X) SQLITE_OK -#else -SQLITE_PRIVATE int sqlite3FaultSim(int); -#endif - -SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); -SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); -SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec*, u32); -SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); -SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); -SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*); -SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); -#ifndef SQLITE_OMIT_BUILTIN_TEST -SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); -#endif - -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); -SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); -SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); - -SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); - -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); -#else -# define sqlite3ViewGetColumnNames(A,B) 0 -#endif - -#if SQLITE_MAX_ATTACHED>30 -SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); -#endif -SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); -SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); -SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); -#ifndef SQLITE_OMIT_AUTOINCREMENT -SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); -SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); -#else -# define sqlite3AutoincrementBegin(X) -# define sqlite3AutoincrementEnd(X) -#endif -SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int); -SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); -SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); -SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); -SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); -SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); -SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, - Token*, Select*, Expr*, IdList*); -SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); -SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); -SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); -SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); -SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); -SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); -SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); -SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Expr*, int, int, u8); -SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); -SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); -SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, - Expr*,ExprList*,u32,Expr*,Expr*); -SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); -SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); -SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); -SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); -#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) -SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*); -#endif -SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); -SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); -SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); -SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); -#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ -#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ -#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ -SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); -SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); -SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); -SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); -SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); -SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); -SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); -SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int); -SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); -#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ -#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ -#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */ -SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); -SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); -SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); -SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); -#define LOCATE_VIEW 0x01 -#define LOCATE_NOERR 0x02 -SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); -SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); -SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); -SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*); -SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int); -SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); -SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int); -SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); -SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int); -SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); -SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); -SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); -SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); -SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); -#ifndef SQLITE_OMIT_BUILTIN_TEST -SQLITE_PRIVATE void sqlite3PrngSaveState(void); -SQLITE_PRIVATE void sqlite3PrngRestoreState(void); -#endif -SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int); -SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); -SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); -SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); -SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*); -SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*); -SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); -SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); -SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); -SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); -SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); -SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); -SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); -#ifdef SQLITE_ENABLE_CURSOR_HINTS -SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); -#endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); -SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); -SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); -SQLITE_PRIVATE int sqlite3IsRowid(const char*); -SQLITE_PRIVATE void sqlite3GenerateRowDelete( - Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); -SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); -SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); -SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); -SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, - u8,u8,int,int*,int*); -SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); -SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); -SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); -SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); -SQLITE_PRIVATE void sqlite3MayAbort(Parse*); -SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); -SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); -SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*); -SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); -SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); -SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); -SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); -#if SELECTTRACE_ENABLED -SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*); -#else -# define sqlite3SelectSetName(A,B) -#endif -SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); -SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); -SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); -SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); -SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); -SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); -SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); -SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); - -#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int); -#endif - -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, - Expr*,int, int); -SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); -SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int); -SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*); -SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); -SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *); -SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, - int, int, int); -SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); - void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); -SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, - Select*,u8); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); -SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); -SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); -# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) -# define sqlite3IsToplevel(p) ((p)->pToplevel==0) -#else -# define sqlite3TriggersExist(B,C,D,E,F) 0 -# define sqlite3DeleteTrigger(A,B) -# define sqlite3DropTriggerPtr(A,B) -# define sqlite3UnlinkAndDeleteTrigger(A,B,C) -# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) -# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F) -# define sqlite3TriggerList(X, Y) 0 -# define sqlite3ParseToplevel(p) p -# define sqlite3IsToplevel(p) 1 -# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 -#endif - -SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); -SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); -SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); -#ifndef SQLITE_OMIT_AUTHORIZATION -SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); -SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); -SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); -SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); -SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int); -#else -# define sqlite3AuthRead(a,b,c,d) -# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK -# define sqlite3AuthContextPush(a,b,c) -# define sqlite3AuthContextPop(a) ((void)(a)) -#endif -SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); -SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); -SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); -SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); -SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); -SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); -SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); -SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); -SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); -SQLITE_PRIVATE int sqlite3Atoi(const char*); -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); -SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); -SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); -SQLITE_PRIVATE LogEst sqlite3LogEst(u64); -SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); -#ifndef SQLITE_OMIT_VIRTUALTABLE -SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); -#endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) -SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); -#endif - -/* -** Routines to read and write variable-length integers. These used to -** be defined locally, but now we use the varint routines in the util.c -** file. -*/ -SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); -SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); -SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); -SQLITE_PRIVATE int sqlite3VarintLen(u64 v); - -/* -** The common case is for a varint to be a single byte. They following -** macros handle the common case without a procedure call, but then call -** the procedure for larger varints. -*/ -#define getVarint32(A,B) \ - (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) -#define putVarint32(A,B) \ - (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ - sqlite3PutVarint((A),(B))) -#define getVarint sqlite3GetVarint -#define putVarint sqlite3PutVarint - - -SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); -SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); -SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); -SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); -SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int); -SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); -SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); -SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); -SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); -SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); -SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); -SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); -SQLITE_PRIVATE u8 sqlite3HexToInt(int h); -SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); - -#if defined(SQLITE_NEED_ERR_NAME) -SQLITE_PRIVATE const char *sqlite3ErrName(int); -#endif - -SQLITE_PRIVATE const char *sqlite3ErrStr(int); -SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); -SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); -SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); -SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); -SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); -SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); -SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); -SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); -SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); -SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); -SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); -SQLITE_PRIVATE int sqlite3AbsInt32(int); -#ifdef SQLITE_ENABLE_8_3_NAMES -SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); -#else -# define sqlite3FileSuffix3(X,Y) -#endif -SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); - -SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); -SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); -SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, - void(*)(void*)); -SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*); -SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); -SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); -SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); -SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); -SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); -#ifndef SQLITE_AMALGAMATION -SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; -SQLITE_PRIVATE const char sqlite3StrBINARY[]; -SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; -SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; -SQLITE_PRIVATE const Token sqlite3IntTokens[]; -SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; -SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; -#ifndef SQLITE_OMIT_WSD -SQLITE_PRIVATE int sqlite3PendingByte; -#endif -#endif -SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); -SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); -SQLITE_PRIVATE void sqlite3AlterFunctions(void); -SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); -SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); -SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); -SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); -SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int); -SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); -SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); -SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); -SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); -SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*); -SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); -SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); -SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); -SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); -SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); -SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); -SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); -SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*); -SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); -SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); -SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); -SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); -SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); -SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); -SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); -SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); -SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); -SQLITE_PRIVATE void sqlite3SchemaClear(void *); -SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); -SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); -SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); -#endif -SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, - void (*)(sqlite3_context*,int,sqlite3_value **), - void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), - FuncDestructor *pDestructor -); -SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); -SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); -SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); -SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); - -SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); -SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); -SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); -SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char); -SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); -SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*); -SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); -SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); - -SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); -SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); - -#ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*); -#else -# define sqlite3ExprCheckIN(x,y) SQLITE_OK -#endif - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); -SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( - Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); -SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); -SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); -SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); -SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); -#endif - -/* -** The interface to the LEMON-generated parser -*/ -SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64)); -SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); -SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*); -#ifdef YYTRACKMAXSTACKDEPTH -SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); -#endif - -SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*); -#ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*); -#else -# define sqlite3CloseExtensions(X) -#endif - -#ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, int, u8, const char *); -#else - #define sqlite3TableLock(v,w,x,y,z) -#endif - -#ifdef SQLITE_TEST -SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); -#endif - -#ifdef SQLITE_OMIT_VIRTUALTABLE -# define sqlite3VtabClear(Y) -# define sqlite3VtabSync(X,Y) SQLITE_OK -# define sqlite3VtabRollback(X) -# define sqlite3VtabCommit(X) -# define sqlite3VtabInSync(db) 0 -# define sqlite3VtabLock(X) -# define sqlite3VtabUnlock(X) -# define sqlite3VtabUnlockList(X) -# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK -# define sqlite3GetVTable(X,Y) ((VTable*)0) -#else -SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); -SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); -SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*); -SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); -SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); -SQLITE_PRIVATE void sqlite3VtabLock(VTable *); -SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); -SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); -SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); -SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); -SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); -# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) -#endif -SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); -SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); -SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); -SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); -SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); -SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); -SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); -SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); -SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); -SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); -SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); -SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); -SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); -SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); -SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); -SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); -SQLITE_PRIVATE void sqlite3ParserReset(Parse*); -SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); -SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); -SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); -SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); -SQLITE_PRIVATE const char *sqlite3JournalModename(int); -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); -SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); -#endif -#ifndef SQLITE_OMIT_CTE -SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); -SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); -SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8); -#else -#define sqlite3WithPush(x,y,z) -#define sqlite3WithDelete(x,y) -#endif - -/* Declarations for functions in fkey.c. All of these are replaced by -** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign -** key functionality is available. If OMIT_TRIGGER is defined but -** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In -** this case foreign keys are parsed, but no other functionality is -** provided (enforcement of FK constraints requires the triggers sub-system). -*/ -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); -SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); -SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); -SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); -SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); -SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); -#else - #define sqlite3FkActions(a,b,c,d,e,f) - #define sqlite3FkCheck(a,b,c,d,e,f) - #define sqlite3FkDropTable(a,b,c) - #define sqlite3FkOldmask(a,b) 0 - #define sqlite3FkRequired(a,b,c,d) 0 -#endif -#ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); -SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); -#else - #define sqlite3FkDelete(a,b) - #define sqlite3FkLocateIndex(a,b,c,d,e) -#endif - - -/* -** Available fault injectors. Should be numbered beginning with 0. -*/ -#define SQLITE_FAULTINJECTOR_MALLOC 0 -#define SQLITE_FAULTINJECTOR_COUNT 1 - -/* -** The interface to the code in fault.c used for identifying "benign" -** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST -** is not defined. -*/ -#ifndef SQLITE_OMIT_BUILTIN_TEST -SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void); -SQLITE_PRIVATE void sqlite3EndBenignMalloc(void); -#else - #define sqlite3BeginBenignMalloc() - #define sqlite3EndBenignMalloc() -#endif - -/* -** Allowed return values from sqlite3FindInIndex() -*/ -#define IN_INDEX_ROWID 1 /* Search the rowid of the table */ -#define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ -#define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */ -#define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ -#define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ -/* -** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). -*/ -#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ -#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ -#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ -SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*); - -SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); -SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); -#ifdef SQLITE_ENABLE_ATOMIC_WRITE -SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); -#endif - -SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p); -SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); - -SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); -#if SQLITE_MAX_EXPR_DEPTH>0 -SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *); -SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); -#else - #define sqlite3SelectExprHeight(x) 0 - #define sqlite3ExprCheckHeight(x,y) -#endif - -SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); -SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); - -#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY -SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *); -SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db); -SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); -#else - #define sqlite3ConnectionBlocked(x,y) - #define sqlite3ConnectionUnlocked(x) - #define sqlite3ConnectionClosed(x) -#endif - -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); -#endif - -/* -** If the SQLITE_ENABLE IOTRACE exists then the global variable -** sqlite3IoTrace is a pointer to a printf-like routine used to -** print I/O tracing messages. -*/ -#ifdef SQLITE_ENABLE_IOTRACE -# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } -SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); -SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); -#else -# define IOTRACE(A) -# define sqlite3VdbeIOTraceSql(X) -#endif - -/* -** These routines are available for the mem2.c debugging memory allocator -** only. They are used to verify that different "types" of memory -** allocations are properly tracked by the system. -** -** sqlite3MemdebugSetType() sets the "type" of an allocation to one of -** the MEMTYPE_* macros defined below. The type must be a bitmask with -** a single bit set. -** -** sqlite3MemdebugHasType() returns true if any of the bits in its second -** argument match the type set by the previous sqlite3MemdebugSetType(). -** sqlite3MemdebugHasType() is intended for use inside assert() statements. -** -** sqlite3MemdebugNoType() returns true if none of the bits in its second -** argument match the type set by the previous sqlite3MemdebugSetType(). -** -** Perhaps the most important point is the difference between MEMTYPE_HEAP -** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means -** it might have been allocated by lookaside, except the allocation was -** too large or lookaside was already full. It is important to verify -** that allocations that might have been satisfied by lookaside are not -** passed back to non-lookaside free() routines. Asserts such as the -** example above are placed on the non-lookaside free() routines to verify -** this constraint. -** -** All of this is no-op for a production build. It only comes into -** play when the SQLITE_MEMDEBUG compile-time option is used. -*/ -#ifdef SQLITE_MEMDEBUG -SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); -SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8); -SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8); -#else -# define sqlite3MemdebugSetType(X,Y) /* no-op */ -# define sqlite3MemdebugHasType(X,Y) 1 -# define sqlite3MemdebugNoType(X,Y) 1 -#endif -#define MEMTYPE_HEAP 0x01 /* General heap allocations */ -#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ -#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ -#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ - -/* -** Threading interface -*/ -#if SQLITE_MAX_WORKER_THREADS>0 -SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); -SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); -#endif - -#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) -SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); -#endif - -SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr); -SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr); -SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int); -SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); - -#endif /* SQLITEINT_H */ - -/************** End of sqliteInt.h *******************************************/ -/************** Begin file global.c ******************************************/ -/* -** 2008 June 13 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains definitions of global variables and constants. -*/ -/* #include "sqliteInt.h" */ - -/* An array to map all upper-case characters into their corresponding -** lower-case character. -** -** SQLite only considers US-ASCII (or EBCDIC) characters. We do not -** handle case conversions for the UTF character set since the tables -** involved are nearly as big or bigger than SQLite itself. -*/ -SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { -#ifdef SQLITE_ASCII - 0, 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, 97, 98, 99,100,101,102,103, - 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121, - 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107, - 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, - 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161, - 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179, - 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197, - 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, - 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233, - 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251, - 252,253,254,255 -#endif -#ifdef SQLITE_EBCDIC - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */ - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */ - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */ - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */ - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */ - 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */ - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */ - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */ - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */ - 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */ - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */ - 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */ - 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */ - 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */ - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */ -#endif -}; - -/* -** The following 256 byte lookup table is used to support SQLites built-in -** equivalents to the following standard library functions: -** -** isspace() 0x01 -** isalpha() 0x02 -** isdigit() 0x04 -** isalnum() 0x06 -** isxdigit() 0x08 -** toupper() 0x20 -** SQLite identifier character 0x40 -** Quote character 0x80 -** -** Bit 0x20 is set if the mapped character requires translation to upper -** case. i.e. if the character is a lower-case ASCII character. -** If x is a lower-case ASCII character, then its upper-case equivalent -** is (x - 0x20). Therefore toupper() can be implemented as: -** -** (x & ~(map[x]&0x20)) -** -** The equivalent of tolower() is implemented using the sqlite3UpperToLower[] -** array. tolower() is used more often than toupper() by SQLite. -** -** Bit 0x40 is set if the character is non-alphanumeric and can be used in an -** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any -** non-ASCII UTF character. Hence the test for whether or not a character is -** part of an identifier is 0x46. -*/ -#ifdef SQLITE_ASCII -SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ - 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ - 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ - 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ - - 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ - 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ - 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ - 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ - - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */ - - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ -}; -#endif - -/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards -** compatibility for legacy applications, the URI filename capability is -** disabled by default. -** -** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled -** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options. -** -** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally -** disabled. The default value may be changed by compiling with the -** SQLITE_USE_URI symbol defined. -*/ -#ifndef SQLITE_USE_URI -# define SQLITE_USE_URI 0 -#endif - -/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the -** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if -** that compile-time option is omitted. -*/ -#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN -# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1 -#endif - -/* The minimum PMA size is set to this value multiplied by the database -** page size in bytes. -*/ -#ifndef SQLITE_SORTER_PMASZ -# define SQLITE_SORTER_PMASZ 250 -#endif - -/* Statement journals spill to disk when their size exceeds the following -** threshold (in bytes). 0 means that statement journals are created and -** written to disk immediately (the default behavior for SQLite versions -** before 3.12.0). -1 means always keep the entire statement journal in -** memory. (The statement journal is also always held entirely in memory -** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this -** setting.) -*/ -#ifndef SQLITE_STMTJRNL_SPILL -# define SQLITE_STMTJRNL_SPILL (64*1024) -#endif - -/* -** The following singleton contains the global configuration for -** the SQLite library. -*/ -SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { - SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ - 1, /* bCoreMutex */ - SQLITE_THREADSAFE==1, /* bFullMutex */ - SQLITE_USE_URI, /* bOpenUri */ - SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ - 0x7ffffffe, /* mxStrlen */ - 0, /* neverCorrupt */ - 128, /* szLookaside */ - 500, /* nLookaside */ - SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ - {0,0,0,0,0,0,0,0}, /* m */ - {0,0,0,0,0,0,0,0,0}, /* mutex */ - {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ - (void*)0, /* pHeap */ - 0, /* nHeap */ - 0, 0, /* mnHeap, mxHeap */ - SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ - SQLITE_MAX_MMAP_SIZE, /* mxMmap */ - (void*)0, /* pScratch */ - 0, /* szScratch */ - 0, /* nScratch */ - (void*)0, /* pPage */ - 0, /* szPage */ - SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */ - 0, /* mxParserStack */ - 0, /* sharedCacheEnabled */ - SQLITE_SORTER_PMASZ, /* szPma */ - /* All the rest should always be initialized to zero */ - 0, /* isInit */ - 0, /* inProgress */ - 0, /* isMutexInit */ - 0, /* isMallocInit */ - 0, /* isPCacheInit */ - 0, /* nRefInitMutex */ - 0, /* pInitMutex */ - 0, /* xLog */ - 0, /* pLogArg */ -#ifdef SQLITE_ENABLE_SQLLOG - 0, /* xSqllog */ - 0, /* pSqllogArg */ -#endif -#ifdef SQLITE_VDBE_COVERAGE - 0, /* xVdbeBranch */ - 0, /* pVbeBranchArg */ -#endif -#ifndef SQLITE_OMIT_BUILTIN_TEST - 0, /* xTestCallback */ -#endif - 0, /* bLocaltimeFault */ - 0x7ffffffe /* iOnceResetThreshold */ -}; - -/* -** Hash table for global functions - functions common to all -** database connections. After initialization, this table is -** read-only. -*/ -SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; - -/* -** Constant tokens for values 0 and 1. -*/ -SQLITE_PRIVATE const Token sqlite3IntTokens[] = { - { "0", 1 }, - { "1", 1 } -}; - - -/* -** The value of the "pending" byte must be 0x40000000 (1 byte past the -** 1-gibabyte boundary) in a compatible database. SQLite never uses -** the database page that contains the pending byte. It never attempts -** to read or write that page. The pending byte page is set aside -** for use by the VFS layers as space for managing file locks. -** -** During testing, it is often desirable to move the pending byte to -** a different position in the file. This allows code that has to -** deal with the pending byte to run on files that are much smaller -** than 1 GiB. The sqlite3_test_control() interface can be used to -** move the pending byte. -** -** IMPORTANT: Changing the pending byte to any value other than -** 0x40000000 results in an incompatible database file format! -** Changing the pending byte during operation will result in undefined -** and incorrect behavior. -*/ -#ifndef SQLITE_OMIT_WSD -SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; -#endif - -/* #include "opcodes.h" */ -/* -** Properties of opcodes. The OPFLG_INITIALIZER macro is -** created by mkopcodeh.awk during compilation. Data is obtained -** from the comments following the "case OP_xxxx:" statements in -** the vdbe.c file. -*/ -SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; - -/* -** Name of the default collating sequence -*/ -SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY"; - -/************** End of global.c **********************************************/ -/************** Begin file ctime.c *******************************************/ -/* -** 2010 February 23 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file implements routines used to report what compile-time options -** SQLite was built with. -*/ - -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - -/* #include "sqliteInt.h" */ - -/* -** An array of names of all compile-time options. This array should -** be sorted A-Z. -** -** This array looks large, but in a typical installation actually uses -** only a handful of compile-time options, so most times this array is usually -** rather short and uses little memory space. -*/ -static const char * const azCompileOpt[] = { - -/* These macros are provided to "stringify" the value of the define -** for those options in which the value is meaningful. */ -#define CTIMEOPT_VAL_(opt) #opt -#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) - -#if SQLITE_32BIT_ROWID - "32BIT_ROWID", -#endif -#if SQLITE_4_BYTE_ALIGNED_MALLOC - "4_BYTE_ALIGNED_MALLOC", -#endif -#if SQLITE_CASE_SENSITIVE_LIKE - "CASE_SENSITIVE_LIKE", -#endif -#if SQLITE_CHECK_PAGES - "CHECK_PAGES", -#endif -#if defined(__clang__) && defined(__clang_major__) - "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "." - CTIMEOPT_VAL(__clang_minor__) "." - CTIMEOPT_VAL(__clang_patchlevel__), -#elif defined(_MSC_VER) - "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), -#elif defined(__GNUC__) && defined(__VERSION__) - "COMPILER=gcc-" __VERSION__, -#endif -#if SQLITE_COVERAGE_TEST - "COVERAGE_TEST", -#endif -#if SQLITE_DEBUG - "DEBUG", -#endif -#if SQLITE_DEFAULT_LOCKING_MODE - "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), -#endif -#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc) - "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), -#endif -#if SQLITE_DISABLE_DIRSYNC - "DISABLE_DIRSYNC", -#endif -#if SQLITE_DISABLE_LFS - "DISABLE_LFS", -#endif -#if SQLITE_ENABLE_8_3_NAMES - "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), -#endif -#if SQLITE_ENABLE_API_ARMOR - "ENABLE_API_ARMOR", -#endif -#if SQLITE_ENABLE_ATOMIC_WRITE - "ENABLE_ATOMIC_WRITE", -#endif -#if SQLITE_ENABLE_CEROD - "ENABLE_CEROD", -#endif -#if SQLITE_ENABLE_COLUMN_METADATA - "ENABLE_COLUMN_METADATA", -#endif -#if SQLITE_ENABLE_DBSTAT_VTAB - "ENABLE_DBSTAT_VTAB", -#endif -#if SQLITE_ENABLE_EXPENSIVE_ASSERT - "ENABLE_EXPENSIVE_ASSERT", -#endif -#if SQLITE_ENABLE_FTS1 - "ENABLE_FTS1", -#endif -#if SQLITE_ENABLE_FTS2 - "ENABLE_FTS2", -#endif -#if SQLITE_ENABLE_FTS3 - "ENABLE_FTS3", -#endif -#if SQLITE_ENABLE_FTS3_PARENTHESIS - "ENABLE_FTS3_PARENTHESIS", -#endif -#if SQLITE_ENABLE_FTS4 - "ENABLE_FTS4", -#endif -#if SQLITE_ENABLE_FTS5 - "ENABLE_FTS5", -#endif -#if SQLITE_ENABLE_ICU - "ENABLE_ICU", -#endif -#if SQLITE_ENABLE_IOTRACE - "ENABLE_IOTRACE", -#endif -#if SQLITE_ENABLE_JSON1 - "ENABLE_JSON1", -#endif -#if SQLITE_ENABLE_LOAD_EXTENSION - "ENABLE_LOAD_EXTENSION", -#endif -#if SQLITE_ENABLE_LOCKING_STYLE - "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), -#endif -#if SQLITE_ENABLE_MEMORY_MANAGEMENT - "ENABLE_MEMORY_MANAGEMENT", -#endif -#if SQLITE_ENABLE_MEMSYS3 - "ENABLE_MEMSYS3", -#endif -#if SQLITE_ENABLE_MEMSYS5 - "ENABLE_MEMSYS5", -#endif -#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK - "ENABLE_OVERSIZE_CELL_CHECK", -#endif -#if SQLITE_ENABLE_RTREE - "ENABLE_RTREE", -#endif -#if defined(SQLITE_ENABLE_STAT4) - "ENABLE_STAT4", -#elif defined(SQLITE_ENABLE_STAT3) - "ENABLE_STAT3", -#endif -#if SQLITE_ENABLE_UNLOCK_NOTIFY - "ENABLE_UNLOCK_NOTIFY", -#endif -#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT - "ENABLE_UPDATE_DELETE_LIMIT", -#endif -#if SQLITE_HAS_CODEC - "HAS_CODEC", -#endif -#if HAVE_ISNAN || SQLITE_HAVE_ISNAN - "HAVE_ISNAN", -#endif -#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX - "HOMEGROWN_RECURSIVE_MUTEX", -#endif -#if SQLITE_IGNORE_AFP_LOCK_ERRORS - "IGNORE_AFP_LOCK_ERRORS", -#endif -#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS - "IGNORE_FLOCK_LOCK_ERRORS", -#endif -#ifdef SQLITE_INT64_TYPE - "INT64_TYPE", -#endif -#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS - "LIKE_DOESNT_MATCH_BLOBS", -#endif -#if SQLITE_LOCK_TRACE - "LOCK_TRACE", -#endif -#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc) - "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), -#endif -#ifdef SQLITE_MAX_SCHEMA_RETRY - "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), -#endif -#if SQLITE_MEMDEBUG - "MEMDEBUG", -#endif -#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT - "MIXED_ENDIAN_64BIT_FLOAT", -#endif -#if SQLITE_NO_SYNC - "NO_SYNC", -#endif -#if SQLITE_OMIT_ALTERTABLE - "OMIT_ALTERTABLE", -#endif -#if SQLITE_OMIT_ANALYZE - "OMIT_ANALYZE", -#endif -#if SQLITE_OMIT_ATTACH - "OMIT_ATTACH", -#endif -#if SQLITE_OMIT_AUTHORIZATION - "OMIT_AUTHORIZATION", -#endif -#if SQLITE_OMIT_AUTOINCREMENT - "OMIT_AUTOINCREMENT", -#endif -#if SQLITE_OMIT_AUTOINIT - "OMIT_AUTOINIT", -#endif -#if SQLITE_OMIT_AUTOMATIC_INDEX - "OMIT_AUTOMATIC_INDEX", -#endif -#if SQLITE_OMIT_AUTORESET - "OMIT_AUTORESET", -#endif -#if SQLITE_OMIT_AUTOVACUUM - "OMIT_AUTOVACUUM", -#endif -#if SQLITE_OMIT_BETWEEN_OPTIMIZATION - "OMIT_BETWEEN_OPTIMIZATION", -#endif -#if SQLITE_OMIT_BLOB_LITERAL - "OMIT_BLOB_LITERAL", -#endif -#if SQLITE_OMIT_BTREECOUNT - "OMIT_BTREECOUNT", -#endif -#if SQLITE_OMIT_BUILTIN_TEST - "OMIT_BUILTIN_TEST", -#endif -#if SQLITE_OMIT_CAST - "OMIT_CAST", -#endif -#if SQLITE_OMIT_CHECK - "OMIT_CHECK", -#endif -#if SQLITE_OMIT_COMPLETE - "OMIT_COMPLETE", -#endif -#if SQLITE_OMIT_COMPOUND_SELECT - "OMIT_COMPOUND_SELECT", -#endif -#if SQLITE_OMIT_CTE - "OMIT_CTE", -#endif -#if SQLITE_OMIT_DATETIME_FUNCS - "OMIT_DATETIME_FUNCS", -#endif -#if SQLITE_OMIT_DECLTYPE - "OMIT_DECLTYPE", -#endif -#if SQLITE_OMIT_DEPRECATED - "OMIT_DEPRECATED", -#endif -#if SQLITE_OMIT_DISKIO - "OMIT_DISKIO", -#endif -#if SQLITE_OMIT_EXPLAIN - "OMIT_EXPLAIN", -#endif -#if SQLITE_OMIT_FLAG_PRAGMAS - "OMIT_FLAG_PRAGMAS", -#endif -#if SQLITE_OMIT_FLOATING_POINT - "OMIT_FLOATING_POINT", -#endif -#if SQLITE_OMIT_FOREIGN_KEY - "OMIT_FOREIGN_KEY", -#endif -#if SQLITE_OMIT_GET_TABLE - "OMIT_GET_TABLE", -#endif -#if SQLITE_OMIT_INCRBLOB - "OMIT_INCRBLOB", -#endif -#if SQLITE_OMIT_INTEGRITY_CHECK - "OMIT_INTEGRITY_CHECK", -#endif -#if SQLITE_OMIT_LIKE_OPTIMIZATION - "OMIT_LIKE_OPTIMIZATION", -#endif -#if SQLITE_OMIT_LOAD_EXTENSION - "OMIT_LOAD_EXTENSION", -#endif -#if SQLITE_OMIT_LOCALTIME - "OMIT_LOCALTIME", -#endif -#if SQLITE_OMIT_LOOKASIDE - "OMIT_LOOKASIDE", -#endif -#if SQLITE_OMIT_MEMORYDB - "OMIT_MEMORYDB", -#endif -#if SQLITE_OMIT_OR_OPTIMIZATION - "OMIT_OR_OPTIMIZATION", -#endif -#if SQLITE_OMIT_PAGER_PRAGMAS - "OMIT_PAGER_PRAGMAS", -#endif -#if SQLITE_OMIT_PRAGMA - "OMIT_PRAGMA", -#endif -#if SQLITE_OMIT_PROGRESS_CALLBACK - "OMIT_PROGRESS_CALLBACK", -#endif -#if SQLITE_OMIT_QUICKBALANCE - "OMIT_QUICKBALANCE", -#endif -#if SQLITE_OMIT_REINDEX - "OMIT_REINDEX", -#endif -#if SQLITE_OMIT_SCHEMA_PRAGMAS - "OMIT_SCHEMA_PRAGMAS", -#endif -#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - "OMIT_SCHEMA_VERSION_PRAGMAS", -#endif -#if SQLITE_OMIT_SHARED_CACHE - "OMIT_SHARED_CACHE", -#endif -#if SQLITE_OMIT_SUBQUERY - "OMIT_SUBQUERY", -#endif -#if SQLITE_OMIT_TCL_VARIABLE - "OMIT_TCL_VARIABLE", -#endif -#if SQLITE_OMIT_TEMPDB - "OMIT_TEMPDB", -#endif -#if SQLITE_OMIT_TRACE - "OMIT_TRACE", -#endif -#if SQLITE_OMIT_TRIGGER - "OMIT_TRIGGER", -#endif -#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION - "OMIT_TRUNCATE_OPTIMIZATION", -#endif -#if SQLITE_OMIT_UTF16 - "OMIT_UTF16", -#endif -#if SQLITE_OMIT_VACUUM - "OMIT_VACUUM", -#endif -#if SQLITE_OMIT_VIEW - "OMIT_VIEW", -#endif -#if SQLITE_OMIT_VIRTUALTABLE - "OMIT_VIRTUALTABLE", -#endif -#if SQLITE_OMIT_WAL - "OMIT_WAL", -#endif -#if SQLITE_OMIT_WSD - "OMIT_WSD", -#endif -#if SQLITE_OMIT_XFER_OPT - "OMIT_XFER_OPT", -#endif -#if SQLITE_PERFORMANCE_TRACE - "PERFORMANCE_TRACE", -#endif -#if SQLITE_PROXY_DEBUG - "PROXY_DEBUG", -#endif -#if SQLITE_RTREE_INT_ONLY - "RTREE_INT_ONLY", -#endif -#if SQLITE_SECURE_DELETE - "SECURE_DELETE", -#endif -#if SQLITE_SMALL_STACK - "SMALL_STACK", -#endif -#if SQLITE_SOUNDEX - "SOUNDEX", -#endif -#if SQLITE_SYSTEM_MALLOC - "SYSTEM_MALLOC", -#endif -#if SQLITE_TCL - "TCL", -#endif -#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) - "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), -#endif -#if SQLITE_TEST - "TEST", -#endif -#if defined(SQLITE_THREADSAFE) - "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), -#endif -#if SQLITE_USE_ALLOCA - "USE_ALLOCA", -#endif -#if SQLITE_USER_AUTHENTICATION - "USER_AUTHENTICATION", -#endif -#if SQLITE_WIN32_MALLOC - "WIN32_MALLOC", -#endif -#if SQLITE_ZERO_MALLOC - "ZERO_MALLOC" -#endif -}; - -/* -** Given the name of a compile-time option, return true if that option -** was used and false if not. -** -** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix -** is not required for a match. -*/ -SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ - int i, n; - -#if SQLITE_ENABLE_API_ARMOR - if( zOptName==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; - n = sqlite3Strlen30(zOptName); - - /* Since ArraySize(azCompileOpt) is normally in single digits, a - ** linear search is adequate. No need for a binary search. */ - for(i=0; i=0 && NaDb[] (or -1) */ - u8 nullRow; /* True if pointing to a row with no data */ - u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ - u8 isTable; /* True for rowid tables. False for indexes */ -#ifdef SQLITE_DEBUG - u8 seekOp; /* Most recent seek operation on this cursor */ - u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ -#endif - Bool isEphemeral:1; /* True for an ephemeral table */ - Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ - Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ - Pgno pgnoRoot; /* Root page of the open btree cursor */ - i16 nField; /* Number of fields in the header */ - u16 nHdrParsed; /* Number of header fields parsed so far */ - union { - BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ - sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ - int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ - VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ - } uc; - Btree *pBt; /* Separate file holding temporary table */ - KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int seekResult; /* Result of previous sqlite3BtreeMoveto() */ - i64 seqCount; /* Sequence counter */ - i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ - int *aAltMap; /* Mapping from table to index column numbers */ -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK - u64 maskUsed; /* Mask of columns used by this cursor */ -#endif - - /* Cached information about the header for the data record that the - ** cursor is currently pointing to. Only valid if cacheStatus matches - ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of - ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that - ** the cache is out of date. - ** - ** aRow might point to (ephemeral) data for the current row, or it might - ** be NULL. - */ - u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - u32 payloadSize; /* Total number of bytes in the record */ - u32 szRow; /* Byte available in aRow */ - u32 iHdrOffset; /* Offset to next unparsed byte of the header */ - const u8 *aRow; /* Data for the current row, if all on one page */ - u32 *aOffset; /* Pointer to aType[nField] */ - u32 aType[1]; /* Type values for all entries in the record */ - /* 2*nField extra array elements allocated for aType[], beyond the one - ** static element declared in the structure. nField total array slots for - ** aType[] and nField+1 array slots for aOffset[] */ -}; - - -/* -** A value for VdbeCursor.cacheStatus that means the cache is always invalid. -*/ -#define CACHE_STALE 0 - -/* -** When a sub-program is executed (OP_Program), a structure of this type -** is allocated to store the current value of the program counter, as -** well as the current memory cell array and various other frame specific -** values stored in the Vdbe struct. When the sub-program is finished, -** these values are copied back to the Vdbe from the VdbeFrame structure, -** restoring the state of the VM to as it was before the sub-program -** began executing. -** -** The memory for a VdbeFrame object is allocated and managed by a memory -** cell in the parent (calling) frame. When the memory cell is deleted or -** overwritten, the VdbeFrame object is not freed immediately. Instead, it -** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame -** list is deleted when the VM is reset in VdbeHalt(). The reason for doing -** this instead of deleting the VdbeFrame immediately is to avoid recursive -** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the -** child frame are released. -** -** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is -** set to NULL if the currently executing frame is the main program. -*/ -typedef struct VdbeFrame VdbeFrame; -struct VdbeFrame { - Vdbe *v; /* VM this frame belongs to */ - VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ - Op *aOp; /* Program instructions for parent frame */ - i64 *anExec; /* Event counters from parent frame */ - Mem *aMem; /* Array of memory cells for parent frame */ - VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ - void *token; /* Copy of SubProgram.token */ - i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ - AuxData *pAuxData; /* Linked list of auxdata allocations */ - int nCursor; /* Number of entries in apCsr */ - int pc; /* Program Counter in parent (calling) frame */ - int nOp; /* Size of aOp array */ - int nMem; /* Number of entries in aMem */ - int nChildMem; /* Number of memory cells for child frame */ - int nChildCsr; /* Number of cursors for child frame */ - int nChange; /* Statement changes (Vdbe.nChange) */ - int nDbChange; /* Value of db->nChange */ -}; - -#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) - -/* -** Internally, the vdbe manipulates nearly all SQL values as Mem -** structures. Each Mem struct may cache multiple representations (string, -** integer etc.) of the same value. -*/ -struct Mem { - union MemValue { - double r; /* Real value used when MEM_Real is set in flags */ - i64 i; /* Integer value used when MEM_Int is set in flags */ - int nZero; /* Used when bit MEM_Zero is set in flags */ - FuncDef *pDef; /* Used only when flags==MEM_Agg */ - RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ - VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ - } u; - u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ - u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ - u8 eSubtype; /* Subtype for this value */ - int n; /* Number of characters in string value, excluding '\0' */ - char *z; /* String or BLOB value */ - /* ShallowCopy only needs to copy the information above */ - char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ - int szMalloc; /* Size of the zMalloc allocation */ - u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ - sqlite3 *db; /* The associated database connection */ - void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ -#ifdef SQLITE_DEBUG - Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ - void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ -#endif -}; - -/* -** Size of struct Mem not including the Mem.zMalloc member or anything that -** follows. -*/ -#define MEMCELLSIZE offsetof(Mem,zMalloc) - -/* One or more of the following flags are set to indicate the validOK -** representations of the value stored in the Mem struct. -** -** If the MEM_Null flag is set, then the value is an SQL NULL value. -** No other flags may be set in this case. -** -** If the MEM_Str flag is set then Mem.z points at a string representation. -** Usually this is encoded in the same unicode encoding as the main -** database (see below for exceptions). If the MEM_Term flag is also -** set, then the string is nul terminated. The MEM_Int and MEM_Real -** flags may coexist with the MEM_Str flag. -*/ -#define MEM_Null 0x0001 /* Value is NULL */ -#define MEM_Str 0x0002 /* Value is a string */ -#define MEM_Int 0x0004 /* Value is an integer */ -#define MEM_Real 0x0008 /* Value is a real number */ -#define MEM_Blob 0x0010 /* Value is a BLOB */ -#define MEM_AffMask 0x001f /* Mask of affinity bits */ -#define MEM_RowSet 0x0020 /* Value is a RowSet object */ -#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ -#define MEM_Undefined 0x0080 /* Value is undefined */ -#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ -#define MEM_TypeMask 0x81ff /* Mask of type bits */ - - -/* Whenever Mem contains a valid string or blob representation, one of -** the following flags must be set to determine the memory management -** policy for Mem.z. The MEM_Term flag tells us whether or not the -** string is \000 or \u0000 terminated -*/ -#define MEM_Term 0x0200 /* String rep is nul terminated */ -#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */ -#define MEM_Static 0x0800 /* Mem.z points to a static string */ -#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ -#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ -#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ -#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ -#ifdef SQLITE_OMIT_INCRBLOB - #undef MEM_Zero - #define MEM_Zero 0x0000 -#endif - -/* Return TRUE if Mem X contains dynamically allocated content - anything -** that needs to be deallocated to avoid a leak. -*/ -#define VdbeMemDynamic(X) \ - (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) - -/* -** Clear any existing type flags from a Mem and replace them with f -*/ -#define MemSetTypeFlag(p, f) \ - ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) - -/* -** Return true if a memory cell is not marked as invalid. This macro -** is for use inside assert() statements only. -*/ -#ifdef SQLITE_DEBUG -#define memIsValid(M) ((M)->flags & MEM_Undefined)==0 -#endif - -/* -** Each auxiliary data pointer stored by a user defined function -** implementation calling sqlite3_set_auxdata() is stored in an instance -** of this structure. All such structures associated with a single VM -** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed -** when the VM is halted (if not before). -*/ -struct AuxData { - int iOp; /* Instruction number of OP_Function opcode */ - int iArg; /* Index of function argument. */ - void *pAux; /* Aux data pointer */ - void (*xDelete)(void *); /* Destructor for the aux data */ - AuxData *pNext; /* Next element in list */ -}; - -/* -** The "context" argument for an installable function. A pointer to an -** instance of this structure is the first argument to the routines used -** implement the SQL functions. -** -** There is a typedef for this structure in sqlite.h. So all routines, -** even the public interface to SQLite, can use a pointer to this structure. -** But this file is the only place where the internal details of this -** structure are known. -** -** This structure is defined inside of vdbeInt.h because it uses substructures -** (Mem) which are only defined there. -*/ -struct sqlite3_context { - Mem *pOut; /* The return value is stored here */ - FuncDef *pFunc; /* Pointer to function information */ - Mem *pMem; /* Memory cell used to store aggregate context */ - Vdbe *pVdbe; /* The VM that owns this context */ - int iOp; /* Instruction number of OP_Function */ - int isError; /* Error code returned by the function. */ - u8 skipFlag; /* Skip accumulator loading if true */ - u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ - u8 argc; /* Number of arguments */ - sqlite3_value *argv[1]; /* Argument set */ -}; - -/* A bitfield type for use inside of structures. Always follow with :N where -** N is the number of bits. -*/ -typedef unsigned bft; /* Bit Field Type */ - -typedef struct ScanStatus ScanStatus; -struct ScanStatus { - int addrExplain; /* OP_Explain for loop */ - int addrLoop; /* Address of "loops" counter */ - int addrVisit; /* Address of "rows visited" counter */ - int iSelectID; /* The "Select-ID" for this loop */ - LogEst nEst; /* Estimated output rows per loop */ - char *zName; /* Name of table or index */ -}; - -/* -** An instance of the virtual machine. This structure contains the complete -** state of the virtual machine. -** -** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() -** is really a pointer to an instance of this structure. -*/ -struct Vdbe { - sqlite3 *db; /* The database connection that owns this statement */ - Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ - Parse *pParse; /* Parsing context used to create this Vdbe */ - ynVar nVar; /* Number of entries in aVar[] */ - ynVar nzVar; /* Number of entries in azVar[] */ - u32 magic; /* Magic number for sanity checking */ - int nMem; /* Number of memory locations currently allocated */ - int nCursor; /* Number of slots in apCsr[] */ - u32 cacheCtr; /* VdbeCursor row cache generation counter */ - int pc; /* The program counter */ - int rc; /* Value to return */ - int nChange; /* Number of db changes made since last reset */ - int iStatement; /* Statement number (or 0 if has not opened stmt) */ - i64 iCurrentTime; /* Value of julianday('now') for this statement */ - i64 nFkConstraint; /* Number of imm. FK constraints this VM */ - i64 nStmtDefCons; /* Number of def. constraints when stmt started */ - i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ - - /* When allocating a new Vdbe object, all of the fields below should be - ** initialized to zero or NULL */ - - Op *aOp; /* Space to hold the virtual machine's program */ - Mem *aMem; /* The memory locations */ - Mem **apArg; /* Arguments to currently executing user function */ - Mem *aColName; /* Column names to return */ - Mem *pResultSet; /* Pointer to an array of results */ - char *zErrMsg; /* Error message written here */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - Mem *aVar; /* Values for the OP_Variable opcode. */ - char **azVar; /* Name of variables */ -#ifndef SQLITE_OMIT_TRACE - i64 startTime; /* Time when query started - used for profiling */ -#endif - int nOp; /* Number of instructions in the program */ -#ifdef SQLITE_DEBUG - int rcApp; /* errcode set by sqlite3_result_error_code() */ -#endif - u16 nResColumn; /* Number of columns in one row of the result set */ - u8 errorAction; /* Recovery action to do in case of an error */ - u8 minWriteFileFormat; /* Minimum file format for writable database files */ - bft expired:1; /* True if the VM needs to be recompiled */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ - bft explain:2; /* True if EXPLAIN present on SQL command */ - bft changeCntOn:1; /* True to update the change-counter */ - bft runOnlyOnce:1; /* Automatically expire on reset */ - bft usesStmtJournal:1; /* True if uses a statement journal */ - bft readOnly:1; /* True for statements that do not write */ - bft bIsReader:1; /* True for statements that read */ - bft isPrepareV2:1; /* True if prepared with prepare_v2() */ - yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ - yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */ - char *zSql; /* Text of the SQL statement that generated this */ - void *pFree; /* Free this when deleting the vdbe */ - VdbeFrame *pFrame; /* Parent frame */ - VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ - int nFrame; /* Number of frames in pFrame list */ - u32 expmask; /* Binding to these vars invalidates VM */ - SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ - AuxData *pAuxData; /* Linked list of auxdata allocations */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - i64 *anExec; /* Number of times each op has been executed */ - int nScan; /* Entries in aScan[] */ - ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ -#endif -}; - -/* -** The following are allowed values for Vdbe.magic -*/ -#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */ -#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */ -#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */ -#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */ -#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */ - -/* -** Structure used to store the context required by the -** sqlite3_preupdate_*() API functions. -*/ -struct PreUpdate { - Vdbe *v; - VdbeCursor *pCsr; /* Cursor to read old values from */ - int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ - u8 *aRecord; /* old.* database record */ - KeyInfo keyinfo; - UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ - UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ - int iNewReg; /* Register for new.* values */ - i64 iKey1; /* First key value passed to hook */ - i64 iKey2; /* Second key value passed to hook */ - Mem *aNew; /* Array of new.* values */ - Table *pTab; /* Schema object being upated */ -}; - -/* -** Function prototypes -*/ -SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); -SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); -void sqliteVdbePopStack(Vdbe*,int); -SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); -SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); -#endif -SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); -SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); -SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*); -SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); -SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); - -int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); -SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); -SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); -SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); -SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); -SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); -#ifdef SQLITE_OMIT_FLOATING_POINT -# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 -#else -SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); -#endif -SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); -SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); -SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); -SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); -SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); -SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); -SQLITE_PRIVATE const char *sqlite3OpcodeName(int); -SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); -SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); -SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); -SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); -SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); -#endif -SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); - -SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); -SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); -SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); -SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); - -#if !defined(SQLITE_OMIT_SHARED_CACHE) -SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); -#else -# define sqlite3VdbeEnter(X) -#endif - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 -SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); -#else -# define sqlite3VdbeLeave(X) -#endif - -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); -SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); -#endif - -#ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); -#else -# define sqlite3VdbeCheckFk(p,i) 0 -#endif - -SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf); -#endif -SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); - -#ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); - #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) -#else - #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK - #define ExpandBlob(P) SQLITE_OK -#endif - -#endif /* !defined(SQLITE_VDBEINT_H) */ - -/************** End of vdbeInt.h *********************************************/ -/************** Continuing where we left off in status.c *********************/ - -/* -** Variables in which to record status information. -*/ -#if SQLITE_PTRSIZE>4 -typedef sqlite3_int64 sqlite3StatValueType; -#else -typedef u32 sqlite3StatValueType; -#endif -typedef struct sqlite3StatType sqlite3StatType; -static SQLITE_WSD struct sqlite3StatType { - sqlite3StatValueType nowValue[10]; /* Current value */ - sqlite3StatValueType mxValue[10]; /* Maximum value */ -} sqlite3Stat = { {0,}, {0,} }; - -/* -** Elements of sqlite3Stat[] are protected by either the memory allocator -** mutex, or by the pcache1 mutex. The following array determines which. -*/ -static const char statMutex[] = { - 0, /* SQLITE_STATUS_MEMORY_USED */ - 1, /* SQLITE_STATUS_PAGECACHE_USED */ - 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */ - 0, /* SQLITE_STATUS_SCRATCH_USED */ - 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */ - 0, /* SQLITE_STATUS_MALLOC_SIZE */ - 0, /* SQLITE_STATUS_PARSER_STACK */ - 1, /* SQLITE_STATUS_PAGECACHE_SIZE */ - 0, /* SQLITE_STATUS_SCRATCH_SIZE */ - 0, /* SQLITE_STATUS_MALLOC_COUNT */ -}; - - -/* The "wsdStat" macro will resolve to the status information -** state vector. If writable static data is unsupported on the target, -** we have to locate the state vector at run-time. In the more common -** case where writable static data is supported, wsdStat can refer directly -** to the "sqlite3Stat" state vector declared above. -*/ -#ifdef SQLITE_OMIT_WSD -# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) -# define wsdStat x[0] -#else -# define wsdStatInit -# define wsdStat sqlite3Stat -#endif - -/* -** Return the current value of a status parameter. The caller must -** be holding the appropriate mutex. -*/ -SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){ - wsdStatInit; - assert( op>=0 && op=0 && op=0 && op=0 && opwsdStat.mxValue[op] ){ - wsdStat.mxValue[op] = wsdStat.nowValue[op]; - } -} -SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){ - wsdStatInit; - assert( N>=0 ); - assert( op>=0 && op=0 && op=0 ); - newValue = (sqlite3StatValueType)X; - assert( op>=0 && op=0 && opwsdStat.mxValue[op] ){ - wsdStat.mxValue[op] = newValue; - } -} - -/* -** Query status information. -*/ -SQLITE_API int sqlite3_status64( - int op, - sqlite3_int64 *pCurrent, - sqlite3_int64 *pHighwater, - int resetFlag -){ - sqlite3_mutex *pMutex; - wsdStatInit; - if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ - return SQLITE_MISUSE_BKPT; - } -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; -#endif - pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); - sqlite3_mutex_enter(pMutex); - *pCurrent = wsdStat.nowValue[op]; - *pHighwater = wsdStat.mxValue[op]; - if( resetFlag ){ - wsdStat.mxValue[op] = wsdStat.nowValue[op]; - } - sqlite3_mutex_leave(pMutex); - (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ - return SQLITE_OK; -} -SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ - sqlite3_int64 iCur = 0, iHwtr = 0; - int rc; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; -#endif - rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); - if( rc==0 ){ - *pCurrent = (int)iCur; - *pHighwater = (int)iHwtr; - } - return rc; -} - -/* -** Query status information for a single database connection -*/ -SQLITE_API int sqlite3_db_status( - sqlite3 *db, /* The database connection whose status is desired */ - int op, /* Status verb */ - int *pCurrent, /* Write current value here */ - int *pHighwater, /* Write high-water mark here */ - int resetFlag /* Reset high-water mark if true */ -){ - int rc = SQLITE_OK; /* Return code */ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - switch( op ){ - case SQLITE_DBSTATUS_LOOKASIDE_USED: { - *pCurrent = db->lookaside.nOut; - *pHighwater = db->lookaside.mxOut; - if( resetFlag ){ - db->lookaside.mxOut = db->lookaside.nOut; - } - break; - } - - case SQLITE_DBSTATUS_LOOKASIDE_HIT: - case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: - case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { - testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); - testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); - testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); - assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); - assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); - *pCurrent = 0; - *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; - if( resetFlag ){ - db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; - } - break; - } - - /* - ** Return an approximation for the amount of memory currently used - ** by all pagers associated with the given database connection. The - ** highwater mark is meaningless and is returned as zero. - */ - case SQLITE_DBSTATUS_CACHE_USED_SHARED: - case SQLITE_DBSTATUS_CACHE_USED: { - int totalUsed = 0; - int i; - sqlite3BtreeEnterAll(db); - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - Pager *pPager = sqlite3BtreePager(pBt); - int nByte = sqlite3PagerMemUsed(pPager); - if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){ - nByte = nByte / sqlite3BtreeConnectionCount(pBt); - } - totalUsed += nByte; - } - } - sqlite3BtreeLeaveAll(db); - *pCurrent = totalUsed; - *pHighwater = 0; - break; - } - - /* - ** *pCurrent gets an accurate estimate of the amount of memory used - ** to store the schema for all databases (main, temp, and any ATTACHed - ** databases. *pHighwater is set to zero. - */ - case SQLITE_DBSTATUS_SCHEMA_USED: { - int i; /* Used to iterate through schemas */ - int nByte = 0; /* Used to accumulate return value */ - - sqlite3BtreeEnterAll(db); - db->pnBytesFreed = &nByte; - for(i=0; inDb; i++){ - Schema *pSchema = db->aDb[i].pSchema; - if( ALWAYS(pSchema!=0) ){ - HashElem *p; - - nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( - pSchema->tblHash.count - + pSchema->trigHash.count - + pSchema->idxHash.count - + pSchema->fkeyHash.count - ); - nByte += sqlite3_msize(pSchema->tblHash.ht); - nByte += sqlite3_msize(pSchema->trigHash.ht); - nByte += sqlite3_msize(pSchema->idxHash.ht); - nByte += sqlite3_msize(pSchema->fkeyHash.ht); - - for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ - sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); - } - for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ - sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); - } - } - } - db->pnBytesFreed = 0; - sqlite3BtreeLeaveAll(db); - - *pHighwater = 0; - *pCurrent = nByte; - break; - } - - /* - ** *pCurrent gets an accurate estimate of the amount of memory used - ** to store all prepared statements. - ** *pHighwater is set to zero. - */ - case SQLITE_DBSTATUS_STMT_USED: { - struct Vdbe *pVdbe; /* Used to iterate through VMs */ - int nByte = 0; /* Used to accumulate return value */ - - db->pnBytesFreed = &nByte; - for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ - sqlite3VdbeClearObject(db, pVdbe); - sqlite3DbFree(db, pVdbe); - } - db->pnBytesFreed = 0; - - *pHighwater = 0; /* IMP: R-64479-57858 */ - *pCurrent = nByte; - - break; - } - - /* - ** Set *pCurrent to the total cache hits or misses encountered by all - ** pagers the database handle is connected to. *pHighwater is always set - ** to zero. - */ - case SQLITE_DBSTATUS_CACHE_HIT: - case SQLITE_DBSTATUS_CACHE_MISS: - case SQLITE_DBSTATUS_CACHE_WRITE:{ - int i; - int nRet = 0; - assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); - assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); - - for(i=0; inDb; i++){ - if( db->aDb[i].pBt ){ - Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); - sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); - } - } - *pHighwater = 0; /* IMP: R-42420-56072 */ - /* IMP: R-54100-20147 */ - /* IMP: R-29431-39229 */ - *pCurrent = nRet; - break; - } - - /* Set *pCurrent to non-zero if there are unresolved deferred foreign - ** key constraints. Set *pCurrent to zero if all foreign key constraints - ** have been satisfied. The *pHighwater is always set to zero. - */ - case SQLITE_DBSTATUS_DEFERRED_FKS: { - *pHighwater = 0; /* IMP: R-11967-56545 */ - *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; - break; - } - - default: { - rc = SQLITE_ERROR; - } - } - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/************** End of status.c **********************************************/ -/************** Begin file date.c ********************************************/ -/* -** 2003 October 31 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement date and time -** functions for SQLite. -** -** There is only one exported symbol in this file - the function -** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. -** All other code has file scope. -** -** SQLite processes all times and dates as julian day numbers. The -** dates and times are stored as the number of days since noon -** in Greenwich on November 24, 4714 B.C. according to the Gregorian -** calendar system. -** -** 1970-01-01 00:00:00 is JD 2440587.5 -** 2000-01-01 00:00:00 is JD 2451544.5 -** -** This implementation requires years to be expressed as a 4-digit number -** which means that only dates between 0000-01-01 and 9999-12-31 can -** be represented, even though julian day numbers allow a much wider -** range of dates. -** -** The Gregorian calendar system is used for all dates and times, -** even those that predate the Gregorian calendar. Historians usually -** use the julian calendar for dates prior to 1582-10-15 and for some -** dates afterwards, depending on locale. Beware of this difference. -** -** The conversion algorithms are implemented based on descriptions -** in the following text: -** -** Jean Meeus -** Astronomical Algorithms, 2nd Edition, 1998 -** ISBM 0-943396-61-1 -** Willmann-Bell, Inc -** Richmond, Virginia (USA) -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include */ -#include - -#ifndef SQLITE_OMIT_DATETIME_FUNCS - -/* -** The MSVC CRT on Windows CE may not have a localtime() function. -** So declare a substitute. The substitute function itself is -** defined in "os_win.c". -*/ -#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) -struct tm *__cdecl localtime(const time_t *); -#endif - -/* -** A structure for holding a single date and time. -*/ -typedef struct DateTime DateTime; -struct DateTime { - sqlite3_int64 iJD; /* The julian day number times 86400000 */ - int Y, M, D; /* Year, month, and day */ - int h, m; /* Hour and minutes */ - int tz; /* Timezone offset in minutes */ - double s; /* Seconds */ - char validYMD; /* True (1) if Y,M,D are valid */ - char validHMS; /* True (1) if h,m,s are valid */ - char validJD; /* True (1) if iJD is valid */ - char validTZ; /* True (1) if tz is valid */ - char tzSet; /* Timezone was set explicitly */ -}; - - -/* -** Convert zDate into one or more integers according to the conversion -** specifier zFormat. -** -** zFormat[] contains 4 characters for each integer converted, except for -** the last integer which is specified by three characters. The meaning -** of a four-character format specifiers ABCD is: -** -** A: number of digits to convert. Always "2" or "4". -** B: minimum value. Always "0" or "1". -** C: maximum value, decoded as: -** a: 12 -** b: 14 -** c: 24 -** d: 31 -** e: 59 -** f: 9999 -** D: the separator character, or \000 to indicate this is the -** last number to convert. -** -** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would -** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-". -** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates -** the 2-digit day which is the last integer in the set. -** -** The function returns the number of successful conversions. -*/ -static int getDigits(const char *zDate, const char *zFormat, ...){ - /* The aMx[] array translates the 3rd character of each format - ** spec into a max size: a b c d e f */ - static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; - va_list ap; - int cnt = 0; - char nextC; - va_start(ap, zFormat); - do{ - char N = zFormat[0] - '0'; - char min = zFormat[1] - '0'; - int val = 0; - u16 max; - - assert( zFormat[2]>='a' && zFormat[2]<='f' ); - max = aMx[zFormat[2] - 'a']; - nextC = zFormat[3]; - val = 0; - while( N-- ){ - if( !sqlite3Isdigit(*zDate) ){ - goto end_getDigits; - } - val = val*10 + *zDate - '0'; - zDate++; - } - if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){ - goto end_getDigits; - } - *va_arg(ap,int*) = val; - zDate++; - cnt++; - zFormat += 4; - }while( nextC ); -end_getDigits: - va_end(ap); - return cnt; -} - -/* -** Parse a timezone extension on the end of a date-time. -** The extension is of the form: -** -** (+/-)HH:MM -** -** Or the "zulu" notation: -** -** Z -** -** If the parse is successful, write the number of minutes -** of change in p->tz and return 0. If a parser error occurs, -** return non-zero. -** -** A missing specifier is not considered an error. -*/ -static int parseTimezone(const char *zDate, DateTime *p){ - int sgn = 0; - int nHr, nMn; - int c; - while( sqlite3Isspace(*zDate) ){ zDate++; } - p->tz = 0; - c = *zDate; - if( c=='-' ){ - sgn = -1; - }else if( c=='+' ){ - sgn = +1; - }else if( c=='Z' || c=='z' ){ - zDate++; - goto zulu_time; - }else{ - return c!=0; - } - zDate++; - if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){ - return 1; - } - zDate += 5; - p->tz = sgn*(nMn + nHr*60); -zulu_time: - while( sqlite3Isspace(*zDate) ){ zDate++; } - p->tzSet = 1; - return *zDate!=0; -} - -/* -** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. -** The HH, MM, and SS must each be exactly 2 digits. The -** fractional seconds FFFF can be one or more digits. -** -** Return 1 if there is a parsing error and 0 on success. -*/ -static int parseHhMmSs(const char *zDate, DateTime *p){ - int h, m, s; - double ms = 0.0; - if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){ - return 1; - } - zDate += 5; - if( *zDate==':' ){ - zDate++; - if( getDigits(zDate, "20e", &s)!=1 ){ - return 1; - } - zDate += 2; - if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){ - double rScale = 1.0; - zDate++; - while( sqlite3Isdigit(*zDate) ){ - ms = ms*10.0 + *zDate - '0'; - rScale *= 10.0; - zDate++; - } - ms /= rScale; - } - }else{ - s = 0; - } - p->validJD = 0; - p->validHMS = 1; - p->h = h; - p->m = m; - p->s = s + ms; - if( parseTimezone(zDate, p) ) return 1; - p->validTZ = (p->tz!=0)?1:0; - return 0; -} - -/* -** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume -** that the YYYY-MM-DD is according to the Gregorian calendar. -** -** Reference: Meeus page 61 -*/ -static void computeJD(DateTime *p){ - int Y, M, D, A, B, X1, X2; - - if( p->validJD ) return; - if( p->validYMD ){ - Y = p->Y; - M = p->M; - D = p->D; - }else{ - Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ - M = 1; - D = 1; - } - if( M<=2 ){ - Y--; - M += 12; - } - A = Y/100; - B = 2 - A + (A/4); - X1 = 36525*(Y+4716)/100; - X2 = 306001*(M+1)/10000; - p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); - p->validJD = 1; - if( p->validHMS ){ - p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); - if( p->validTZ ){ - p->iJD -= p->tz*60000; - p->validYMD = 0; - p->validHMS = 0; - p->validTZ = 0; - } - } -} - -/* -** Parse dates of the form -** -** YYYY-MM-DD HH:MM:SS.FFF -** YYYY-MM-DD HH:MM:SS -** YYYY-MM-DD HH:MM -** YYYY-MM-DD -** -** Write the result into the DateTime structure and return 0 -** on success and 1 if the input string is not a well-formed -** date. -*/ -static int parseYyyyMmDd(const char *zDate, DateTime *p){ - int Y, M, D, neg; - - if( zDate[0]=='-' ){ - zDate++; - neg = 1; - }else{ - neg = 0; - } - if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){ - return 1; - } - zDate += 10; - while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } - if( parseHhMmSs(zDate, p)==0 ){ - /* We got the time */ - }else if( *zDate==0 ){ - p->validHMS = 0; - }else{ - return 1; - } - p->validJD = 0; - p->validYMD = 1; - p->Y = neg ? -Y : Y; - p->M = M; - p->D = D; - if( p->validTZ ){ - computeJD(p); - } - return 0; -} - -/* -** Set the time to the current time reported by the VFS. -** -** Return the number of errors. -*/ -static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ - p->iJD = sqlite3StmtCurrentTime(context); - if( p->iJD>0 ){ - p->validJD = 1; - return 0; - }else{ - return 1; - } -} - -/* -** Attempt to parse the given string into a julian day number. Return -** the number of errors. -** -** The following are acceptable forms for the input string: -** -** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM -** DDDD.DD -** now -** -** In the first form, the +/-HH:MM is always optional. The fractional -** seconds extension (the ".FFF") is optional. The seconds portion -** (":SS.FFF") is option. The year and date can be omitted as long -** as there is a time string. The time string can be omitted as long -** as there is a year and date. -*/ -static int parseDateOrTime( - sqlite3_context *context, - const char *zDate, - DateTime *p -){ - double r; - if( parseYyyyMmDd(zDate,p)==0 ){ - return 0; - }else if( parseHhMmSs(zDate, p)==0 ){ - return 0; - }else if( sqlite3StrICmp(zDate,"now")==0){ - return setDateTimeToCurrent(context, p); - }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ - p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); - p->validJD = 1; - return 0; - } - return 1; -} - -/* -** Compute the Year, Month, and Day from the julian day number. -*/ -static void computeYMD(DateTime *p){ - int Z, A, B, C, D, E, X1; - if( p->validYMD ) return; - if( !p->validJD ){ - p->Y = 2000; - p->M = 1; - p->D = 1; - }else{ - Z = (int)((p->iJD + 43200000)/86400000); - A = (int)((Z - 1867216.25)/36524.25); - A = Z + 1 + A - (A/4); - B = A + 1524; - C = (int)((B - 122.1)/365.25); - D = (36525*(C&32767))/100; - E = (int)((B-D)/30.6001); - X1 = (int)(30.6001*E); - p->D = B - D - X1; - p->M = E<14 ? E-1 : E-13; - p->Y = p->M>2 ? C - 4716 : C - 4715; - } - p->validYMD = 1; -} - -/* -** Compute the Hour, Minute, and Seconds from the julian day number. -*/ -static void computeHMS(DateTime *p){ - int s; - if( p->validHMS ) return; - computeJD(p); - s = (int)((p->iJD + 43200000) % 86400000); - p->s = s/1000.0; - s = (int)p->s; - p->s -= s; - p->h = s/3600; - s -= p->h*3600; - p->m = s/60; - p->s += s - p->m*60; - p->validHMS = 1; -} - -/* -** Compute both YMD and HMS -*/ -static void computeYMD_HMS(DateTime *p){ - computeYMD(p); - computeHMS(p); -} - -/* -** Clear the YMD and HMS and the TZ -*/ -static void clearYMD_HMS_TZ(DateTime *p){ - p->validYMD = 0; - p->validHMS = 0; - p->validTZ = 0; -} - -#ifndef SQLITE_OMIT_LOCALTIME -/* -** On recent Windows platforms, the localtime_s() function is available -** as part of the "Secure CRT". It is essentially equivalent to -** localtime_r() available under most POSIX platforms, except that the -** order of the parameters is reversed. -** -** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. -** -** If the user has not indicated to use localtime_r() or localtime_s() -** already, check for an MSVC build environment that provides -** localtime_s(). -*/ -#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \ - && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) -#undef HAVE_LOCALTIME_S -#define HAVE_LOCALTIME_S 1 -#endif - -/* -** The following routine implements the rough equivalent of localtime_r() -** using whatever operating-system specific localtime facility that -** is available. This routine returns 0 on success and -** non-zero on any kind of error. -** -** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this -** routine will always fail. -** -** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C -** library function localtime_r() is used to assist in the calculation of -** local time. -*/ -static int osLocaltime(time_t *t, struct tm *pTm){ - int rc; -#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S - struct tm *pX; -#if SQLITE_THREADSAFE>0 - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - sqlite3_mutex_enter(mutex); - pX = localtime(t); -#ifndef SQLITE_OMIT_BUILTIN_TEST - if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; -#endif - if( pX ) *pTm = *pX; - sqlite3_mutex_leave(mutex); - rc = pX==0; -#else -#ifndef SQLITE_OMIT_BUILTIN_TEST - if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; -#endif -#if HAVE_LOCALTIME_R - rc = localtime_r(t, pTm)==0; -#else - rc = localtime_s(pTm, t); -#endif /* HAVE_LOCALTIME_R */ -#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ - return rc; -} -#endif /* SQLITE_OMIT_LOCALTIME */ - - -#ifndef SQLITE_OMIT_LOCALTIME -/* -** Compute the difference (in milliseconds) between localtime and UTC -** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, -** return this value and set *pRc to SQLITE_OK. -** -** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value -** is undefined in this case. -*/ -static sqlite3_int64 localtimeOffset( - DateTime *p, /* Date at which to calculate offset */ - sqlite3_context *pCtx, /* Write error here if one occurs */ - int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ -){ - DateTime x, y; - time_t t; - struct tm sLocal; - - /* Initialize the contents of sLocal to avoid a compiler warning. */ - memset(&sLocal, 0, sizeof(sLocal)); - - x = *p; - computeYMD_HMS(&x); - if( x.Y<1971 || x.Y>=2038 ){ - /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only - ** works for years between 1970 and 2037. For dates outside this range, - ** SQLite attempts to map the year into an equivalent year within this - ** range, do the calculation, then map the year back. - */ - x.Y = 2000; - x.M = 1; - x.D = 1; - x.h = 0; - x.m = 0; - x.s = 0.0; - } else { - int s = (int)(x.s + 0.5); - x.s = s; - } - x.tz = 0; - x.validJD = 0; - computeJD(&x); - t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); - if( osLocaltime(&t, &sLocal) ){ - sqlite3_result_error(pCtx, "local time unavailable", -1); - *pRc = SQLITE_ERROR; - return 0; - } - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - y.validYMD = 1; - y.validHMS = 1; - y.validJD = 0; - y.validTZ = 0; - computeJD(&y); - *pRc = SQLITE_OK; - return y.iJD - x.iJD; -} -#endif /* SQLITE_OMIT_LOCALTIME */ - -/* -** Process a modifier to a date-time stamp. The modifiers are -** as follows: -** -** NNN days -** NNN hours -** NNN minutes -** NNN.NNNN seconds -** NNN months -** NNN years -** start of month -** start of year -** start of week -** start of day -** weekday N -** unixepoch -** localtime -** utc -** -** Return 0 on success and 1 if there is any kind of error. If the error -** is in a system call (i.e. localtime()), then an error message is written -** to context pCtx. If the error is an unrecognized modifier, no error is -** written to pCtx. -*/ -static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ - int rc = 1; - int n; - double r; - char *z, zBuf[30]; - z = zBuf; - for(n=0; niJD += localtimeOffset(p, pCtx, &rc); - clearYMD_HMS_TZ(p); - } - break; - } -#endif - case 'u': { - /* - ** unixepoch - ** - ** Treat the current value of p->iJD as the number of - ** seconds since 1970. Convert to a real julian day number. - */ - if( strcmp(z, "unixepoch")==0 && p->validJD ){ - p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; - clearYMD_HMS_TZ(p); - rc = 0; - } -#ifndef SQLITE_OMIT_LOCALTIME - else if( strcmp(z, "utc")==0 ){ - if( p->tzSet==0 ){ - sqlite3_int64 c1; - computeJD(p); - c1 = localtimeOffset(p, pCtx, &rc); - if( rc==SQLITE_OK ){ - p->iJD -= c1; - clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p, pCtx, &rc); - } - p->tzSet = 1; - }else{ - rc = SQLITE_OK; - } - } -#endif - break; - } - case 'w': { - /* - ** weekday N - ** - ** Move the date to the same time on the next occurrence of - ** weekday N where 0==Sunday, 1==Monday, and so forth. If the - ** date is already on the appropriate weekday, this is a no-op. - */ - if( strncmp(z, "weekday ", 8)==0 - && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) - && (n=(int)r)==r && n>=0 && r<7 ){ - sqlite3_int64 Z; - computeYMD_HMS(p); - p->validTZ = 0; - p->validJD = 0; - computeJD(p); - Z = ((p->iJD + 129600000)/86400000) % 7; - if( Z>n ) Z -= 7; - p->iJD += (n - Z)*86400000; - clearYMD_HMS_TZ(p); - rc = 0; - } - break; - } - case 's': { - /* - ** start of TTTTT - ** - ** Move the date backwards to the beginning of the current day, - ** or month or year. - */ - if( strncmp(z, "start of ", 9)!=0 ) break; - z += 9; - computeYMD(p); - p->validHMS = 1; - p->h = p->m = 0; - p->s = 0.0; - p->validTZ = 0; - p->validJD = 0; - if( strcmp(z,"month")==0 ){ - p->D = 1; - rc = 0; - }else if( strcmp(z,"year")==0 ){ - computeYMD(p); - p->M = 1; - p->D = 1; - rc = 0; - }else if( strcmp(z,"day")==0 ){ - rc = 0; - } - break; - } - case '+': - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - double rRounder; - for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} - if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ - rc = 1; - break; - } - if( z[n]==':' ){ - /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the - ** specified number of hours, minutes, seconds, and fractional seconds - ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be - ** omitted. - */ - const char *z2 = z; - DateTime tx; - sqlite3_int64 day; - if( !sqlite3Isdigit(*z2) ) z2++; - memset(&tx, 0, sizeof(tx)); - if( parseHhMmSs(z2, &tx) ) break; - computeJD(&tx); - tx.iJD -= 43200000; - day = tx.iJD/86400000; - tx.iJD -= day*86400000; - if( z[0]=='-' ) tx.iJD = -tx.iJD; - computeJD(p); - clearYMD_HMS_TZ(p); - p->iJD += tx.iJD; - rc = 0; - break; - } - z += n; - while( sqlite3Isspace(*z) ) z++; - n = sqlite3Strlen30(z); - if( n>10 || n<3 ) break; - if( z[n-1]=='s' ){ z[n-1] = 0; n--; } - computeJD(p); - rc = 0; - rRounder = r<0 ? -0.5 : +0.5; - if( n==3 && strcmp(z,"day")==0 ){ - p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); - }else if( n==4 && strcmp(z,"hour")==0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); - }else if( n==6 && strcmp(z,"minute")==0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); - }else if( n==6 && strcmp(z,"second")==0 ){ - p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); - }else if( n==5 && strcmp(z,"month")==0 ){ - int x, y; - computeYMD_HMS(p); - p->M += (int)r; - x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; - p->Y += x; - p->M -= x*12; - p->validJD = 0; - computeJD(p); - y = (int)r; - if( y!=r ){ - p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); - } - }else if( n==4 && strcmp(z,"year")==0 ){ - int y = (int)r; - computeYMD_HMS(p); - p->Y += y; - p->validJD = 0; - computeJD(p); - if( y!=r ){ - p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); - } - }else{ - rc = 1; - } - clearYMD_HMS_TZ(p); - break; - } - default: { - break; - } - } - return rc; -} - -/* -** Process time function arguments. argv[0] is a date-time stamp. -** argv[1] and following are modifiers. Parse them all and write -** the resulting time into the DateTime structure p. Return 0 -** on success and 1 if there are any errors. -** -** If there are zero parameters (if even argv[0] is undefined) -** then assume a default value of "now" for argv[0]. -*/ -static int isDate( - sqlite3_context *context, - int argc, - sqlite3_value **argv, - DateTime *p -){ - int i; - const unsigned char *z; - int eType; - memset(p, 0, sizeof(*p)); - if( argc==0 ){ - return setDateTimeToCurrent(context, p); - } - if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT - || eType==SQLITE_INTEGER ){ - p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); - p->validJD = 1; - }else{ - z = sqlite3_value_text(argv[0]); - if( !z || parseDateOrTime(context, (char*)z, p) ){ - return 1; - } - } - for(i=1; iaLimit[SQLITE_LIMIT_LENGTH]+1 ); - testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); - if( n(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(context); - return; - }else{ - z = sqlite3DbMallocRawNN(db, (int)n); - if( z==0 ){ - sqlite3_result_error_nomem(context); - return; - } - } - computeJD(&x); - computeYMD_HMS(&x); - for(i=j=0; zFmt[i]; i++){ - if( zFmt[i]!='%' ){ - z[j++] = zFmt[i]; - }else{ - i++; - switch( zFmt[i] ){ - case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; - case 'f': { - double s = x.s; - if( s>59.999 ) s = 59.999; - sqlite3_snprintf(7, &z[j],"%06.3f", s); - j += sqlite3Strlen30(&z[j]); - break; - } - case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; - case 'W': /* Fall thru */ - case 'j': { - int nDay; /* Number of days since 1st day of year */ - DateTime y = x; - y.validJD = 0; - y.M = 1; - y.D = 1; - computeJD(&y); - nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( zFmt[i]=='W' ){ - int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ - wd = (int)(((x.iJD+43200000)/86400000)%7); - sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); - j += 2; - }else{ - sqlite3_snprintf(4, &z[j],"%03d",nDay+1); - j += 3; - } - break; - } - case 'J': { - sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); - j+=sqlite3Strlen30(&z[j]); - break; - } - case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; - case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; - case 's': { - sqlite3_snprintf(30,&z[j],"%lld", - (i64)(x.iJD/1000 - 21086676*(i64)10000)); - j += sqlite3Strlen30(&z[j]); - break; - } - case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; - case 'w': { - z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; - break; - } - case 'Y': { - sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); - break; - } - default: z[j++] = '%'; break; - } - } - } - z[j] = 0; - sqlite3_result_text(context, z, -1, - z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); -} - -/* -** current_time() -** -** This function returns the same value as time('now'). -*/ -static void ctimeFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **NotUsed2 -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - timeFunc(context, 0, 0); -} - -/* -** current_date() -** -** This function returns the same value as date('now'). -*/ -static void cdateFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **NotUsed2 -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - dateFunc(context, 0, 0); -} - -/* -** current_timestamp() -** -** This function returns the same value as datetime('now'). -*/ -static void ctimestampFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **NotUsed2 -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - datetimeFunc(context, 0, 0); -} -#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ - -#ifdef SQLITE_OMIT_DATETIME_FUNCS -/* -** If the library is compiled to omit the full-scale date and time -** handling (to get a smaller binary), the following minimal version -** of the functions current_time(), current_date() and current_timestamp() -** are included instead. This is to support column declarations that -** include "DEFAULT CURRENT_TIME" etc. -** -** This function uses the C-library functions time(), gmtime() -** and strftime(). The format string to pass to strftime() is supplied -** as the user-data for the function. -*/ -static void currentTimeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - time_t t; - char *zFormat = (char *)sqlite3_user_data(context); - sqlite3_int64 iT; - struct tm *pTm; - struct tm sNow; - char zBuf[20]; - - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - - iT = sqlite3StmtCurrentTime(context); - if( iT<=0 ) return; - t = iT/1000 - 10000*(sqlite3_int64)21086676; -#if HAVE_GMTIME_R - pTm = gmtime_r(&t, &sNow); -#else - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); - pTm = gmtime(&t); - if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); -#endif - if( pTm ){ - strftime(zBuf, 20, zFormat, &sNow); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); - } -} -#endif - -/* -** This function registered all of the above C functions as SQL -** functions. This should be the only routine in this file with -** external linkage. -*/ -SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ - static FuncDef aDateTimeFuncs[] = { -#ifndef SQLITE_OMIT_DATETIME_FUNCS - DFUNCTION(julianday, -1, 0, 0, juliandayFunc ), - DFUNCTION(date, -1, 0, 0, dateFunc ), - DFUNCTION(time, -1, 0, 0, timeFunc ), - DFUNCTION(datetime, -1, 0, 0, datetimeFunc ), - DFUNCTION(strftime, -1, 0, 0, strftimeFunc ), - DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), - DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), - DFUNCTION(current_date, 0, 0, 0, cdateFunc ), -#else - STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), - STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), - STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), -#endif - }; - sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); -} - -/************** End of date.c ************************************************/ -/************** Begin file os.c **********************************************/ -/* -** 2005 November 29 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains OS interface code that is common to all -** architectures. -*/ -/* #include "sqliteInt.h" */ - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ -SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ -SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ -SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ -SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ -SQLITE_API int sqlite3_diskfull_pending = 0; -SQLITE_API int sqlite3_diskfull = 0; -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, also keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API int sqlite3_open_file_count = 0; -#endif /* defined(SQLITE_TEST) */ - -/* -** The default SQLite sqlite3_vfs implementations do not allocate -** memory (actually, os_unix.c allocates a small amount of memory -** from within OsOpen()), but some third-party implementations may. -** So we test the effects of a malloc() failing and the sqlite3OsXXX() -** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. -** -** The following functions are instrumented for malloc() failure -** testing: -** -** sqlite3OsRead() -** sqlite3OsWrite() -** sqlite3OsSync() -** sqlite3OsFileSize() -** sqlite3OsLock() -** sqlite3OsCheckReservedLock() -** sqlite3OsFileControl() -** sqlite3OsShmMap() -** sqlite3OsOpen() -** sqlite3OsDelete() -** sqlite3OsAccess() -** sqlite3OsFullPathname() -** -*/ -#if defined(SQLITE_TEST) -SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; - #define DO_OS_MALLOC_TEST(x) \ - if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \ - void *pTstAlloc = sqlite3Malloc(10); \ - if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \ - sqlite3_free(pTstAlloc); \ - } -#else - #define DO_OS_MALLOC_TEST(x) -#endif - -/* -** The following routines are convenience wrappers around methods -** of the sqlite3_file object. This is mostly just syntactic sugar. All -** of this would be completely automatic if SQLite were coded using -** C++ instead of plain old C. -*/ -SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){ - if( pId->pMethods ){ - pId->pMethods->xClose(pId); - pId->pMethods = 0; - } -} -SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xRead(id, pBuf, amt, offset); -} -SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xWrite(id, pBuf, amt, offset); -} -SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ - return id->pMethods->xTruncate(id, size); -} -SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xSync(id, flags); -} -SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xFileSize(id, pSize); -} -SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xLock(id, lockType); -} -SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ - return id->pMethods->xUnlock(id, lockType); -} -SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xCheckReservedLock(id, pResOut); -} - -/* -** Use sqlite3OsFileControl() when we are doing something that might fail -** and we need to know about the failures. Use sqlite3OsFileControlHint() -** when simply tossing information over the wall to the VFS and we do not -** really care if the VFS receives and understands the information since it -** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() -** routine has no return value since the return value would be meaningless. -*/ -SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ -#ifdef SQLITE_TEST - if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ - /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite - ** is using a regular VFS, it is called after the corresponding - ** transaction has been committed. Injecting a fault at this point - ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM - ** but the transaction is committed anyway. - ** - ** The core must call OsFileControl() though, not OsFileControlHint(), - ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably - ** means the commit really has failed and an error should be returned - ** to the user. */ - DO_OS_MALLOC_TEST(id); - } -#endif - return id->pMethods->xFileControl(id, op, pArg); -} -SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ - (void)id->pMethods->xFileControl(id, op, pArg); -} - -SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ - int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; - return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); -} -SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ - return id->pMethods->xDeviceCharacteristics(id); -} -SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ - return id->pMethods->xShmLock(id, offset, n, flags); -} -SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ - id->pMethods->xShmBarrier(id); -} -SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ - return id->pMethods->xShmUnmap(id, deleteFlag); -} -SQLITE_PRIVATE int sqlite3OsShmMap( - sqlite3_file *id, /* Database file handle */ - int iPage, - int pgsz, - int bExtend, /* True to extend file if necessary */ - void volatile **pp /* OUT: Pointer to mapping */ -){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); -} - -#if SQLITE_MAX_MMAP_SIZE>0 -/* The real implementation of xFetch and xUnfetch */ -SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ - DO_OS_MALLOC_TEST(id); - return id->pMethods->xFetch(id, iOff, iAmt, pp); -} -SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ - return id->pMethods->xUnfetch(id, iOff, p); -} -#else -/* No-op stubs to use when memory-mapped I/O is disabled */ -SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ - *pp = 0; - return SQLITE_OK; -} -SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ - return SQLITE_OK; -} -#endif - -/* -** The next group of routines are convenience wrappers around the -** VFS methods. -*/ -SQLITE_PRIVATE int sqlite3OsOpen( - sqlite3_vfs *pVfs, - const char *zPath, - sqlite3_file *pFile, - int flags, - int *pFlagsOut -){ - int rc; - DO_OS_MALLOC_TEST(0); - /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed - ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, - ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before - ** reaching the VFS. */ - rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); - assert( rc==SQLITE_OK || pFile->pMethods==0 ); - return rc; -} -SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ - DO_OS_MALLOC_TEST(0); - assert( dirSync==0 || dirSync==1 ); - return pVfs->xDelete(pVfs, zPath, dirSync); -} -SQLITE_PRIVATE int sqlite3OsAccess( - sqlite3_vfs *pVfs, - const char *zPath, - int flags, - int *pResOut -){ - DO_OS_MALLOC_TEST(0); - return pVfs->xAccess(pVfs, zPath, flags, pResOut); -} -SQLITE_PRIVATE int sqlite3OsFullPathname( - sqlite3_vfs *pVfs, - const char *zPath, - int nPathOut, - char *zPathOut -){ - DO_OS_MALLOC_TEST(0); - zPathOut[0] = 0; - return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); -} -#ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ - return pVfs->xDlOpen(pVfs, zPath); -} -SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ - pVfs->xDlError(pVfs, nByte, zBufOut); -} -SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ - return pVfs->xDlSym(pVfs, pHdle, zSym); -} -SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ - pVfs->xDlClose(pVfs, pHandle); -} -#endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ - return pVfs->xRandomness(pVfs, nByte, zBufOut); -} -SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ - return pVfs->xSleep(pVfs, nMicro); -} -SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ - return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; -} -SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ - int rc; - /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() - ** method to get the current date and time if that method is available - ** (if iVersion is 2 or greater and the function pointer is not NULL) and - ** will fall back to xCurrentTime() if xCurrentTimeInt64() is - ** unavailable. - */ - if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ - rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); - }else{ - double r; - rc = pVfs->xCurrentTime(pVfs, &r); - *pTimeOut = (sqlite3_int64)(r*86400000.0); - } - return rc; -} - -SQLITE_PRIVATE int sqlite3OsOpenMalloc( - sqlite3_vfs *pVfs, - const char *zFile, - sqlite3_file **ppFile, - int flags, - int *pOutFlags -){ - int rc; - sqlite3_file *pFile; - pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); - if( pFile ){ - rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); - if( rc!=SQLITE_OK ){ - sqlite3_free(pFile); - }else{ - *ppFile = pFile; - } - }else{ - rc = SQLITE_NOMEM_BKPT; - } - return rc; -} -SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){ - assert( pFile ); - sqlite3OsClose(pFile); - sqlite3_free(pFile); -} - -/* -** This function is a wrapper around the OS specific implementation of -** sqlite3_os_init(). The purpose of the wrapper is to provide the -** ability to simulate a malloc failure, so that the handling of an -** error in sqlite3_os_init() by the upper layers can be tested. -*/ -SQLITE_PRIVATE int sqlite3OsInit(void){ - void *p = sqlite3_malloc(10); - if( p==0 ) return SQLITE_NOMEM_BKPT; - sqlite3_free(p); - return sqlite3_os_init(); -} - -/* -** The list of all registered VFS implementations. -*/ -static sqlite3_vfs * SQLITE_WSD vfsList = 0; -#define vfsList GLOBAL(sqlite3_vfs *, vfsList) - -/* -** Locate a VFS by name. If no name is given, simply return the -** first VFS on the list. -*/ -SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ - sqlite3_vfs *pVfs = 0; -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex; -#endif -#ifndef SQLITE_OMIT_AUTOINIT - int rc = sqlite3_initialize(); - if( rc ) return 0; -#endif -#if SQLITE_THREADSAFE - mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - sqlite3_mutex_enter(mutex); - for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ - if( zVfs==0 ) break; - if( strcmp(zVfs, pVfs->zName)==0 ) break; - } - sqlite3_mutex_leave(mutex); - return pVfs; -} - -/* -** Unlink a VFS from the linked list -*/ -static void vfsUnlink(sqlite3_vfs *pVfs){ - assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); - if( pVfs==0 ){ - /* No-op */ - }else if( vfsList==pVfs ){ - vfsList = pVfs->pNext; - }else if( vfsList ){ - sqlite3_vfs *p = vfsList; - while( p->pNext && p->pNext!=pVfs ){ - p = p->pNext; - } - if( p->pNext==pVfs ){ - p->pNext = pVfs->pNext; - } - } -} - -/* -** Register a VFS with the system. It is harmless to register the same -** VFS multiple times. The new VFS becomes the default if makeDflt is -** true. -*/ -SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ - MUTEX_LOGIC(sqlite3_mutex *mutex;) -#ifndef SQLITE_OMIT_AUTOINIT - int rc = sqlite3_initialize(); - if( rc ) return rc; -#endif -#ifdef SQLITE_ENABLE_API_ARMOR - if( pVfs==0 ) return SQLITE_MISUSE_BKPT; -#endif - - MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - sqlite3_mutex_enter(mutex); - vfsUnlink(pVfs); - if( makeDflt || vfsList==0 ){ - pVfs->pNext = vfsList; - vfsList = pVfs; - }else{ - pVfs->pNext = vfsList->pNext; - vfsList->pNext = pVfs; - } - assert(vfsList); - sqlite3_mutex_leave(mutex); - return SQLITE_OK; -} - -/* -** Unregister a VFS so that it is no longer accessible. -*/ -SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - sqlite3_mutex_enter(mutex); - vfsUnlink(pVfs); - sqlite3_mutex_leave(mutex); - return SQLITE_OK; -} - -/************** End of os.c **************************************************/ -/************** Begin file fault.c *******************************************/ -/* -** 2008 Jan 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code to support the concept of "benign" -** malloc failures (when the xMalloc() or xRealloc() method of the -** sqlite3_mem_methods structure fails to allocate a block of memory -** and returns 0). -** -** Most malloc failures are non-benign. After they occur, SQLite -** abandons the current operation and returns an error code (usually -** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily -** fatal. For example, if a malloc fails while resizing a hash table, this -** is completely recoverable simply by not carrying out the resize. The -** hash table will continue to function normally. So a malloc failure -** during a hash table resize is a benign fault. -*/ - -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_OMIT_BUILTIN_TEST - -/* -** Global variables. -*/ -typedef struct BenignMallocHooks BenignMallocHooks; -static SQLITE_WSD struct BenignMallocHooks { - void (*xBenignBegin)(void); - void (*xBenignEnd)(void); -} sqlite3Hooks = { 0, 0 }; - -/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks -** structure. If writable static data is unsupported on the target, -** we have to locate the state vector at run-time. In the more common -** case where writable static data is supported, wsdHooks can refer directly -** to the "sqlite3Hooks" state vector declared above. -*/ -#ifdef SQLITE_OMIT_WSD -# define wsdHooksInit \ - BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) -# define wsdHooks x[0] -#else -# define wsdHooksInit -# define wsdHooks sqlite3Hooks -#endif - - -/* -** Register hooks to call when sqlite3BeginBenignMalloc() and -** sqlite3EndBenignMalloc() are called, respectively. -*/ -SQLITE_PRIVATE void sqlite3BenignMallocHooks( - void (*xBenignBegin)(void), - void (*xBenignEnd)(void) -){ - wsdHooksInit; - wsdHooks.xBenignBegin = xBenignBegin; - wsdHooks.xBenignEnd = xBenignEnd; -} - -/* -** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that -** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() -** indicates that subsequent malloc failures are non-benign. -*/ -SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){ - wsdHooksInit; - if( wsdHooks.xBenignBegin ){ - wsdHooks.xBenignBegin(); - } -} -SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){ - wsdHooksInit; - if( wsdHooks.xBenignEnd ){ - wsdHooks.xBenignEnd(); - } -} - -#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */ - -/************** End of fault.c ***********************************************/ -/************** Begin file mem0.c ********************************************/ -/* -** 2008 October 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains a no-op memory allocation drivers for use when -** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented -** here always fail. SQLite will not operate with these drivers. These -** are merely placeholders. Real drivers must be substituted using -** sqlite3_config() before SQLite will operate. -*/ -/* #include "sqliteInt.h" */ - -/* -** This version of the memory allocator is the default. It is -** used when no other memory allocator is specified using compile-time -** macros. -*/ -#ifdef SQLITE_ZERO_MALLOC - -/* -** No-op versions of all memory allocation routines -*/ -static void *sqlite3MemMalloc(int nByte){ return 0; } -static void sqlite3MemFree(void *pPrior){ return; } -static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } -static int sqlite3MemSize(void *pPrior){ return 0; } -static int sqlite3MemRoundup(int n){ return n; } -static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } -static void sqlite3MemShutdown(void *NotUsed){ return; } - -/* -** This routine is the only routine in this file with external linkage. -** -** Populate the low-level memory allocation function pointers in -** sqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void sqlite3MemSetDefault(void){ - static const sqlite3_mem_methods defaultMethods = { - sqlite3MemMalloc, - sqlite3MemFree, - sqlite3MemRealloc, - sqlite3MemSize, - sqlite3MemRoundup, - sqlite3MemInit, - sqlite3MemShutdown, - 0 - }; - sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); -} - -#endif /* SQLITE_ZERO_MALLOC */ - -/************** End of mem0.c ************************************************/ -/************** Begin file mem1.c ********************************************/ -/* -** 2007 August 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains low-level memory allocation drivers for when -** SQLite will use the standard C-library malloc/realloc/free interface -** to obtain the memory it needs. -** -** This file contains implementations of the low-level memory allocation -** routines specified in the sqlite3_mem_methods object. The content of -** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The -** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the -** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The -** default configuration is to use memory allocation routines in this -** file. -** -** C-preprocessor macro summary: -** -** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if -** the malloc_usable_size() interface exists -** on the target platform. Or, this symbol -** can be set manually, if desired. -** If an equivalent interface exists by -** a different name, using a separate -D -** option to rename it. -** -** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone -** memory allocator. Set this symbol to enable -** building on older macs. -** -** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of -** _msize() on windows systems. This might -** be necessary when compiling for Delphi, -** for example. -*/ -/* #include "sqliteInt.h" */ - -/* -** This version of the memory allocator is the default. It is -** used when no other memory allocator is specified using compile-time -** macros. -*/ -#ifdef SQLITE_SYSTEM_MALLOC -#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) - -/* -** Use the zone allocator available on apple products unless the -** SQLITE_WITHOUT_ZONEMALLOC symbol is defined. -*/ -#include -#include -#include -static malloc_zone_t* _sqliteZone_; -#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) -#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); -#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) -#define SQLITE_MALLOCSIZE(x) \ - (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) - -#else /* if not __APPLE__ */ - -/* -** Use standard C library malloc and free on non-Apple systems. -** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined. -*/ -#define SQLITE_MALLOC(x) malloc(x) -#define SQLITE_FREE(x) free(x) -#define SQLITE_REALLOC(x,y) realloc((x),(y)) - -/* -** The malloc.h header file is needed for malloc_usable_size() function -** on some systems (e.g. Linux). -*/ -#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE -# define SQLITE_USE_MALLOC_H 1 -# define SQLITE_USE_MALLOC_USABLE_SIZE 1 -/* -** The MSVCRT has malloc_usable_size(), but it is called _msize(). The -** use of _msize() is automatic, but can be disabled by compiling with -** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires -** the malloc.h header file. -*/ -#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) -# define SQLITE_USE_MALLOC_H -# define SQLITE_USE_MSIZE -#endif - -/* -** Include the malloc.h header file, if necessary. Also set define macro -** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize() -** for MSVC and malloc_usable_size() for most other systems (e.g. Linux). -** The memory size function can always be overridden manually by defining -** the macro SQLITE_MALLOCSIZE to the desired function name. -*/ -#if defined(SQLITE_USE_MALLOC_H) -# include -# if defined(SQLITE_USE_MALLOC_USABLE_SIZE) -# if !defined(SQLITE_MALLOCSIZE) -# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) -# endif -# elif defined(SQLITE_USE_MSIZE) -# if !defined(SQLITE_MALLOCSIZE) -# define SQLITE_MALLOCSIZE _msize -# endif -# endif -#endif /* defined(SQLITE_USE_MALLOC_H) */ - -#endif /* __APPLE__ or not __APPLE__ */ - -/* -** Like malloc(), but remember the size of the allocation -** so that we can find it later using sqlite3MemSize(). -** -** For this low-level routine, we are guaranteed that nByte>0 because -** cases of nByte<=0 will be intercepted and dealt with by higher level -** routines. -*/ -static void *sqlite3MemMalloc(int nByte){ -#ifdef SQLITE_MALLOCSIZE - void *p = SQLITE_MALLOC( nByte ); - if( p==0 ){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); - } - return p; -#else - sqlite3_int64 *p; - assert( nByte>0 ); - nByte = ROUND8(nByte); - p = SQLITE_MALLOC( nByte+8 ); - if( p ){ - p[0] = nByte; - p++; - }else{ - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); - } - return (void *)p; -#endif -} - -/* -** Like free() but works for allocations obtained from sqlite3MemMalloc() -** or sqlite3MemRealloc(). -** -** For this low-level routine, we already know that pPrior!=0 since -** cases where pPrior==0 will have been intecepted and dealt with -** by higher-level routines. -*/ -static void sqlite3MemFree(void *pPrior){ -#ifdef SQLITE_MALLOCSIZE - SQLITE_FREE(pPrior); -#else - sqlite3_int64 *p = (sqlite3_int64*)pPrior; - assert( pPrior!=0 ); - p--; - SQLITE_FREE(p); -#endif -} - -/* -** Report the allocated size of a prior return from xMalloc() -** or xRealloc(). -*/ -static int sqlite3MemSize(void *pPrior){ -#ifdef SQLITE_MALLOCSIZE - assert( pPrior!=0 ); - return (int)SQLITE_MALLOCSIZE(pPrior); -#else - sqlite3_int64 *p; - assert( pPrior!=0 ); - p = (sqlite3_int64*)pPrior; - p--; - return (int)p[0]; -#endif -} - -/* -** Like realloc(). Resize an allocation previously obtained from -** sqlite3MemMalloc(). -** -** For this low-level interface, we know that pPrior!=0. Cases where -** pPrior==0 while have been intercepted by higher-level routine and -** redirected to xMalloc. Similarly, we know that nByte>0 because -** cases where nByte<=0 will have been intercepted by higher-level -** routines and redirected to xFree. -*/ -static void *sqlite3MemRealloc(void *pPrior, int nByte){ -#ifdef SQLITE_MALLOCSIZE - void *p = SQLITE_REALLOC(pPrior, nByte); - if( p==0 ){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_NOMEM, - "failed memory resize %u to %u bytes", - SQLITE_MALLOCSIZE(pPrior), nByte); - } - return p; -#else - sqlite3_int64 *p = (sqlite3_int64*)pPrior; - assert( pPrior!=0 && nByte>0 ); - assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ - p--; - p = SQLITE_REALLOC(p, nByte+8 ); - if( p ){ - p[0] = nByte; - p++; - }else{ - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_NOMEM, - "failed memory resize %u to %u bytes", - sqlite3MemSize(pPrior), nByte); - } - return (void*)p; -#endif -} - -/* -** Round up a request size to the next valid allocation size. -*/ -static int sqlite3MemRoundup(int n){ - return ROUND8(n); -} - -/* -** Initialize this module. -*/ -static int sqlite3MemInit(void *NotUsed){ -#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) - int cpuCount; - size_t len; - if( _sqliteZone_ ){ - return SQLITE_OK; - } - len = sizeof(cpuCount); - /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ - sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); - if( cpuCount>1 ){ - /* defer MT decisions to system malloc */ - _sqliteZone_ = malloc_default_zone(); - }else{ - /* only 1 core, use our own zone to contention over global locks, - ** e.g. we have our own dedicated locks */ - bool success; - malloc_zone_t* newzone = malloc_create_zone(4096, 0); - malloc_set_zone_name(newzone, "Sqlite_Heap"); - do{ - success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, - (void * volatile *)&_sqliteZone_); - }while(!_sqliteZone_); - if( !success ){ - /* somebody registered a zone first */ - malloc_destroy_zone(newzone); - } - } -#endif - UNUSED_PARAMETER(NotUsed); - return SQLITE_OK; -} - -/* -** Deinitialize this module. -*/ -static void sqlite3MemShutdown(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return; -} - -/* -** This routine is the only routine in this file with external linkage. -** -** Populate the low-level memory allocation function pointers in -** sqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void sqlite3MemSetDefault(void){ - static const sqlite3_mem_methods defaultMethods = { - sqlite3MemMalloc, - sqlite3MemFree, - sqlite3MemRealloc, - sqlite3MemSize, - sqlite3MemRoundup, - sqlite3MemInit, - sqlite3MemShutdown, - 0 - }; - sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); -} - -#endif /* SQLITE_SYSTEM_MALLOC */ - -/************** End of mem1.c ************************************************/ -/************** Begin file mem2.c ********************************************/ -/* -** 2007 August 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains low-level memory allocation drivers for when -** SQLite will use the standard C-library malloc/realloc/free interface -** to obtain the memory it needs while adding lots of additional debugging -** information to each allocation in order to help detect and fix memory -** leaks and memory usage errors. -** -** This file contains implementations of the low-level memory allocation -** routines specified in the sqlite3_mem_methods object. -*/ -/* #include "sqliteInt.h" */ - -/* -** This version of the memory allocator is used only if the -** SQLITE_MEMDEBUG macro is defined -*/ -#ifdef SQLITE_MEMDEBUG - -/* -** The backtrace functionality is only available with GLIBC -*/ -#ifdef __GLIBC__ - extern int backtrace(void**,int); - extern void backtrace_symbols_fd(void*const*,int,int); -#else -# define backtrace(A,B) 1 -# define backtrace_symbols_fd(A,B,C) -#endif -/* #include */ - -/* -** Each memory allocation looks like this: -** -** ------------------------------------------------------------------------ -** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard | -** ------------------------------------------------------------------------ -** -** The application code sees only a pointer to the allocation. We have -** to back up from the allocation pointer to find the MemBlockHdr. The -** MemBlockHdr tells us the size of the allocation and the number of -** backtrace pointers. There is also a guard word at the end of the -** MemBlockHdr. -*/ -struct MemBlockHdr { - i64 iSize; /* Size of this allocation */ - struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ - char nBacktrace; /* Number of backtraces on this alloc */ - char nBacktraceSlots; /* Available backtrace slots */ - u8 nTitle; /* Bytes of title; includes '\0' */ - u8 eType; /* Allocation type code */ - int iForeGuard; /* Guard word for sanity */ -}; - -/* -** Guard words -*/ -#define FOREGUARD 0x80F5E153 -#define REARGUARD 0xE4676B53 - -/* -** Number of malloc size increments to track. -*/ -#define NCSIZE 1000 - -/* -** All of the static variables used by this module are collected -** into a single structure named "mem". This is to keep the -** static variables organized and to reduce namespace pollution -** when this module is combined with other in the amalgamation. -*/ -static struct { - - /* - ** Mutex to control access to the memory allocation subsystem. - */ - sqlite3_mutex *mutex; - - /* - ** Head and tail of a linked list of all outstanding allocations - */ - struct MemBlockHdr *pFirst; - struct MemBlockHdr *pLast; - - /* - ** The number of levels of backtrace to save in new allocations. - */ - int nBacktrace; - void (*xBacktrace)(int, int, void **); - - /* - ** Title text to insert in front of each block - */ - int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ - char zTitle[100]; /* The title text */ - - /* - ** sqlite3MallocDisallow() increments the following counter. - ** sqlite3MallocAllow() decrements it. - */ - int disallow; /* Do not allow memory allocation */ - - /* - ** Gather statistics on the sizes of memory allocations. - ** nAlloc[i] is the number of allocation attempts of i*8 - ** bytes. i==NCSIZE is the number of allocation attempts for - ** sizes more than NCSIZE*8 bytes. - */ - int nAlloc[NCSIZE]; /* Total number of allocations */ - int nCurrent[NCSIZE]; /* Current number of allocations */ - int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */ - -} mem; - - -/* -** Adjust memory usage statistics -*/ -static void adjustStats(int iSize, int increment){ - int i = ROUND8(iSize)/8; - if( i>NCSIZE-1 ){ - i = NCSIZE - 1; - } - if( increment>0 ){ - mem.nAlloc[i]++; - mem.nCurrent[i]++; - if( mem.nCurrent[i]>mem.mxCurrent[i] ){ - mem.mxCurrent[i] = mem.nCurrent[i]; - } - }else{ - mem.nCurrent[i]--; - assert( mem.nCurrent[i]>=0 ); - } -} - -/* -** Given an allocation, find the MemBlockHdr for that allocation. -** -** This routine checks the guards at either end of the allocation and -** if they are incorrect it asserts. -*/ -static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ - struct MemBlockHdr *p; - int *pInt; - u8 *pU8; - int nReserve; - - p = (struct MemBlockHdr*)pAllocation; - p--; - assert( p->iForeGuard==(int)FOREGUARD ); - nReserve = ROUND8(p->iSize); - pInt = (int*)pAllocation; - pU8 = (u8*)pAllocation; - assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); - /* This checks any of the "extra" bytes allocated due - ** to rounding up to an 8 byte boundary to ensure - ** they haven't been overwritten. - */ - while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); - return p; -} - -/* -** Return the number of bytes currently allocated at address p. -*/ -static int sqlite3MemSize(void *p){ - struct MemBlockHdr *pHdr; - if( !p ){ - return 0; - } - pHdr = sqlite3MemsysGetHeader(p); - return (int)pHdr->iSize; -} - -/* -** Initialize the memory allocation subsystem. -*/ -static int sqlite3MemInit(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - assert( (sizeof(struct MemBlockHdr)&7) == 0 ); - if( !sqlite3GlobalConfig.bMemstat ){ - /* If memory status is enabled, then the malloc.c wrapper will already - ** hold the STATIC_MEM mutex when the routines here are invoked. */ - mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - } - return SQLITE_OK; -} - -/* -** Deinitialize the memory allocation subsystem. -*/ -static void sqlite3MemShutdown(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - mem.mutex = 0; -} - -/* -** Round up a request size to the next valid allocation size. -*/ -static int sqlite3MemRoundup(int n){ - return ROUND8(n); -} - -/* -** Fill a buffer with pseudo-random bytes. This is used to preset -** the content of a new memory allocation to unpredictable values and -** to clear the content of a freed allocation to unpredictable values. -*/ -static void randomFill(char *pBuf, int nByte){ - unsigned int x, y, r; - x = SQLITE_PTR_TO_INT(pBuf); - y = nByte | 1; - while( nByte >= 4 ){ - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(int*)pBuf = r; - pBuf += 4; - nByte -= 4; - } - while( nByte-- > 0 ){ - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(pBuf++) = r & 0xff; - } -} - -/* -** Allocate nByte bytes of memory. -*/ -static void *sqlite3MemMalloc(int nByte){ - struct MemBlockHdr *pHdr; - void **pBt; - char *z; - int *pInt; - void *p = 0; - int totalSize; - int nReserve; - sqlite3_mutex_enter(mem.mutex); - assert( mem.disallow==0 ); - nReserve = ROUND8(nByte); - totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + - mem.nBacktrace*sizeof(void*) + mem.nTitle; - p = malloc(totalSize); - if( p ){ - z = p; - pBt = (void**)&z[mem.nTitle]; - pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; - pHdr->pNext = 0; - pHdr->pPrev = mem.pLast; - if( mem.pLast ){ - mem.pLast->pNext = pHdr; - }else{ - mem.pFirst = pHdr; - } - mem.pLast = pHdr; - pHdr->iForeGuard = FOREGUARD; - pHdr->eType = MEMTYPE_HEAP; - pHdr->nBacktraceSlots = mem.nBacktrace; - pHdr->nTitle = mem.nTitle; - if( mem.nBacktrace ){ - void *aAddr[40]; - pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; - memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); - assert(pBt[0]); - if( mem.xBacktrace ){ - mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); - } - }else{ - pHdr->nBacktrace = 0; - } - if( mem.nTitle ){ - memcpy(z, mem.zTitle, mem.nTitle); - } - pHdr->iSize = nByte; - adjustStats(nByte, +1); - pInt = (int*)&pHdr[1]; - pInt[nReserve/sizeof(int)] = REARGUARD; - randomFill((char*)pInt, nByte); - memset(((char*)pInt)+nByte, 0x65, nReserve-nByte); - p = (void*)pInt; - } - sqlite3_mutex_leave(mem.mutex); - return p; -} - -/* -** Free memory. -*/ -static void sqlite3MemFree(void *pPrior){ - struct MemBlockHdr *pHdr; - void **pBt; - char *z; - assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 - || mem.mutex!=0 ); - pHdr = sqlite3MemsysGetHeader(pPrior); - pBt = (void**)pHdr; - pBt -= pHdr->nBacktraceSlots; - sqlite3_mutex_enter(mem.mutex); - if( pHdr->pPrev ){ - assert( pHdr->pPrev->pNext==pHdr ); - pHdr->pPrev->pNext = pHdr->pNext; - }else{ - assert( mem.pFirst==pHdr ); - mem.pFirst = pHdr->pNext; - } - if( pHdr->pNext ){ - assert( pHdr->pNext->pPrev==pHdr ); - pHdr->pNext->pPrev = pHdr->pPrev; - }else{ - assert( mem.pLast==pHdr ); - mem.pLast = pHdr->pPrev; - } - z = (char*)pBt; - z -= pHdr->nTitle; - adjustStats((int)pHdr->iSize, -1); - randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + - (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); - free(z); - sqlite3_mutex_leave(mem.mutex); -} - -/* -** Change the size of an existing memory allocation. -** -** For this debugging implementation, we *always* make a copy of the -** allocation into a new place in memory. In this way, if the -** higher level code is using pointer to the old allocation, it is -** much more likely to break and we are much more liking to find -** the error. -*/ -static void *sqlite3MemRealloc(void *pPrior, int nByte){ - struct MemBlockHdr *pOldHdr; - void *pNew; - assert( mem.disallow==0 ); - assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ - pOldHdr = sqlite3MemsysGetHeader(pPrior); - pNew = sqlite3MemMalloc(nByte); - if( pNew ){ - memcpy(pNew, pPrior, (int)(nByteiSize ? nByte : pOldHdr->iSize)); - if( nByte>pOldHdr->iSize ){ - randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); - } - sqlite3MemFree(pPrior); - } - return pNew; -} - -/* -** Populate the low-level memory allocation function pointers in -** sqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void sqlite3MemSetDefault(void){ - static const sqlite3_mem_methods defaultMethods = { - sqlite3MemMalloc, - sqlite3MemFree, - sqlite3MemRealloc, - sqlite3MemSize, - sqlite3MemRoundup, - sqlite3MemInit, - sqlite3MemShutdown, - 0 - }; - sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); -} - -/* -** Set the "type" of an allocation. -*/ -SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ - if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ - struct MemBlockHdr *pHdr; - pHdr = sqlite3MemsysGetHeader(p); - assert( pHdr->iForeGuard==FOREGUARD ); - pHdr->eType = eType; - } -} - -/* -** Return TRUE if the mask of type in eType matches the type of the -** allocation p. Also return true if p==NULL. -** -** This routine is designed for use within an assert() statement, to -** verify the type of an allocation. For example: -** -** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); -*/ -SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ - int rc = 1; - if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ - struct MemBlockHdr *pHdr; - pHdr = sqlite3MemsysGetHeader(p); - assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ - if( (pHdr->eType&eType)==0 ){ - rc = 0; - } - } - return rc; -} - -/* -** Return TRUE if the mask of type in eType matches no bits of the type of the -** allocation p. Also return true if p==NULL. -** -** This routine is designed for use within an assert() statement, to -** verify the type of an allocation. For example: -** -** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); -*/ -SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ - int rc = 1; - if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ - struct MemBlockHdr *pHdr; - pHdr = sqlite3MemsysGetHeader(p); - assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ - if( (pHdr->eType&eType)!=0 ){ - rc = 0; - } - } - return rc; -} - -/* -** Set the number of backtrace levels kept for each allocation. -** A value of zero turns off backtracing. The number is always rounded -** up to a multiple of 2. -*/ -SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){ - if( depth<0 ){ depth = 0; } - if( depth>20 ){ depth = 20; } - depth = (depth+1)&0xfe; - mem.nBacktrace = depth; -} - -SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ - mem.xBacktrace = xBacktrace; -} - -/* -** Set the title string for subsequent allocations. -*/ -SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){ - unsigned int n = sqlite3Strlen30(zTitle) + 1; - sqlite3_mutex_enter(mem.mutex); - if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; - memcpy(mem.zTitle, zTitle, n); - mem.zTitle[n] = 0; - mem.nTitle = ROUND8(n); - sqlite3_mutex_leave(mem.mutex); -} - -SQLITE_PRIVATE void sqlite3MemdebugSync(){ - struct MemBlockHdr *pHdr; - for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ - void **pBt = (void**)pHdr; - pBt -= pHdr->nBacktraceSlots; - mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); - } -} - -/* -** Open the file indicated and write a log of all unfreed memory -** allocations into that log. -*/ -SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ - FILE *out; - struct MemBlockHdr *pHdr; - void **pBt; - int i; - out = fopen(zFilename, "w"); - if( out==0 ){ - fprintf(stderr, "** Unable to output memory debug output log: %s **\n", - zFilename); - return; - } - for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ - char *z = (char*)pHdr; - z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; - fprintf(out, "**** %lld bytes at %p from %s ****\n", - pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); - if( pHdr->nBacktrace ){ - fflush(out); - pBt = (void**)pHdr; - pBt -= pHdr->nBacktraceSlots; - backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); - fprintf(out, "\n"); - } - } - fprintf(out, "COUNTS:\n"); - for(i=0; i=1 ); - size = mem3.aPool[i-1].u.hdr.size4x/4; - assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); - assert( size>=2 ); - if( size <= MX_SMALL ){ - memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]); - }else{ - hash = size % N_HASH; - memsys3UnlinkFromList(i, &mem3.aiHash[hash]); - } -} - -/* -** Link the chunk at mem3.aPool[i] so that is on the list rooted -** at *pRoot. -*/ -static void memsys3LinkIntoList(u32 i, u32 *pRoot){ - assert( sqlite3_mutex_held(mem3.mutex) ); - mem3.aPool[i].u.list.next = *pRoot; - mem3.aPool[i].u.list.prev = 0; - if( *pRoot ){ - mem3.aPool[*pRoot].u.list.prev = i; - } - *pRoot = i; -} - -/* -** Link the chunk at index i into either the appropriate -** small chunk list, or into the large chunk hash table. -*/ -static void memsys3Link(u32 i){ - u32 size, hash; - assert( sqlite3_mutex_held(mem3.mutex) ); - assert( i>=1 ); - assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 ); - size = mem3.aPool[i-1].u.hdr.size4x/4; - assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); - assert( size>=2 ); - if( size <= MX_SMALL ){ - memsys3LinkIntoList(i, &mem3.aiSmall[size-2]); - }else{ - hash = size % N_HASH; - memsys3LinkIntoList(i, &mem3.aiHash[hash]); - } -} - -/* -** If the STATIC_MEM mutex is not already held, obtain it now. The mutex -** will already be held (obtained by code in malloc.c) if -** sqlite3GlobalConfig.bMemStat is true. -*/ -static void memsys3Enter(void){ - if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ - mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - } - sqlite3_mutex_enter(mem3.mutex); -} -static void memsys3Leave(void){ - sqlite3_mutex_leave(mem3.mutex); -} - -/* -** Called when we are unable to satisfy an allocation of nBytes. -*/ -static void memsys3OutOfMemory(int nByte){ - if( !mem3.alarmBusy ){ - mem3.alarmBusy = 1; - assert( sqlite3_mutex_held(mem3.mutex) ); - sqlite3_mutex_leave(mem3.mutex); - sqlite3_release_memory(nByte); - sqlite3_mutex_enter(mem3.mutex); - mem3.alarmBusy = 0; - } -} - - -/* -** Chunk i is a free chunk that has been unlinked. Adjust its -** size parameters for check-out and return a pointer to the -** user portion of the chunk. -*/ -static void *memsys3Checkout(u32 i, u32 nBlock){ - u32 x; - assert( sqlite3_mutex_held(mem3.mutex) ); - assert( i>=1 ); - assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ); - assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); - x = mem3.aPool[i-1].u.hdr.size4x; - mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2); - mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock; - mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2; - return &mem3.aPool[i]; -} - -/* -** Carve a piece off of the end of the mem3.iMaster free chunk. -** Return a pointer to the new allocation. Or, if the master chunk -** is not large enough, return 0. -*/ -static void *memsys3FromMaster(u32 nBlock){ - assert( sqlite3_mutex_held(mem3.mutex) ); - assert( mem3.szMaster>=nBlock ); - if( nBlock>=mem3.szMaster-1 ){ - /* Use the entire master */ - void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster); - mem3.iMaster = 0; - mem3.szMaster = 0; - mem3.mnMaster = 0; - return p; - }else{ - /* Split the master block. Return the tail. */ - u32 newi, x; - newi = mem3.iMaster + mem3.szMaster - nBlock; - assert( newi > mem3.iMaster+1 ); - mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock; - mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2; - mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1; - mem3.szMaster -= nBlock; - mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster; - x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; - mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; - if( mem3.szMaster < mem3.mnMaster ){ - mem3.mnMaster = mem3.szMaster; - } - return (void*)&mem3.aPool[newi]; - } -} - -/* -** *pRoot is the head of a list of free chunks of the same size -** or same size hash. In other words, *pRoot is an entry in either -** mem3.aiSmall[] or mem3.aiHash[]. -** -** This routine examines all entries on the given list and tries -** to coalesce each entries with adjacent free chunks. -** -** If it sees a chunk that is larger than mem3.iMaster, it replaces -** the current mem3.iMaster with the new larger chunk. In order for -** this mem3.iMaster replacement to work, the master chunk must be -** linked into the hash tables. That is not the normal state of -** affairs, of course. The calling routine must link the master -** chunk before invoking this routine, then must unlink the (possibly -** changed) master chunk once this routine has finished. -*/ -static void memsys3Merge(u32 *pRoot){ - u32 iNext, prev, size, i, x; - - assert( sqlite3_mutex_held(mem3.mutex) ); - for(i=*pRoot; i>0; i=iNext){ - iNext = mem3.aPool[i].u.list.next; - size = mem3.aPool[i-1].u.hdr.size4x; - assert( (size&1)==0 ); - if( (size&2)==0 ){ - memsys3UnlinkFromList(i, pRoot); - assert( i > mem3.aPool[i-1].u.hdr.prevSize ); - prev = i - mem3.aPool[i-1].u.hdr.prevSize; - if( prev==iNext ){ - iNext = mem3.aPool[prev].u.list.next; - } - memsys3Unlink(prev); - size = i + size/4 - prev; - x = mem3.aPool[prev-1].u.hdr.size4x & 2; - mem3.aPool[prev-1].u.hdr.size4x = size*4 | x; - mem3.aPool[prev+size-1].u.hdr.prevSize = size; - memsys3Link(prev); - i = prev; - }else{ - size /= 4; - } - if( size>mem3.szMaster ){ - mem3.iMaster = i; - mem3.szMaster = size; - } - } -} - -/* -** Return a block of memory of at least nBytes in size. -** Return NULL if unable. -** -** This function assumes that the necessary mutexes, if any, are -** already held by the caller. Hence "Unsafe". -*/ -static void *memsys3MallocUnsafe(int nByte){ - u32 i; - u32 nBlock; - u32 toFree; - - assert( sqlite3_mutex_held(mem3.mutex) ); - assert( sizeof(Mem3Block)==8 ); - if( nByte<=12 ){ - nBlock = 2; - }else{ - nBlock = (nByte + 11)/8; - } - assert( nBlock>=2 ); - - /* STEP 1: - ** Look for an entry of the correct size in either the small - ** chunk table or in the large chunk hash table. This is - ** successful most of the time (about 9 times out of 10). - */ - if( nBlock <= MX_SMALL ){ - i = mem3.aiSmall[nBlock-2]; - if( i>0 ){ - memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]); - return memsys3Checkout(i, nBlock); - } - }else{ - int hash = nBlock % N_HASH; - for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){ - if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){ - memsys3UnlinkFromList(i, &mem3.aiHash[hash]); - return memsys3Checkout(i, nBlock); - } - } - } - - /* STEP 2: - ** Try to satisfy the allocation by carving a piece off of the end - ** of the master chunk. This step usually works if step 1 fails. - */ - if( mem3.szMaster>=nBlock ){ - return memsys3FromMaster(nBlock); - } - - - /* STEP 3: - ** Loop through the entire memory pool. Coalesce adjacent free - ** chunks. Recompute the master chunk as the largest free chunk. - ** Then try again to satisfy the allocation by carving a piece off - ** of the end of the master chunk. This step happens very - ** rarely (we hope!) - */ - for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){ - memsys3OutOfMemory(toFree); - if( mem3.iMaster ){ - memsys3Link(mem3.iMaster); - mem3.iMaster = 0; - mem3.szMaster = 0; - } - for(i=0; i=nBlock ){ - return memsys3FromMaster(nBlock); - } - } - } - - /* If none of the above worked, then we fail. */ - return 0; -} - -/* -** Free an outstanding memory allocation. -** -** This function assumes that the necessary mutexes, if any, are -** already held by the caller. Hence "Unsafe". -*/ -static void memsys3FreeUnsafe(void *pOld){ - Mem3Block *p = (Mem3Block*)pOld; - int i; - u32 size, x; - assert( sqlite3_mutex_held(mem3.mutex) ); - assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] ); - i = p - mem3.aPool; - assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 ); - size = mem3.aPool[i-1].u.hdr.size4x/4; - assert( i+size<=mem3.nPool+1 ); - mem3.aPool[i-1].u.hdr.size4x &= ~1; - mem3.aPool[i+size-1].u.hdr.prevSize = size; - mem3.aPool[i+size-1].u.hdr.size4x &= ~2; - memsys3Link(i); - - /* Try to expand the master using the newly freed chunk */ - if( mem3.iMaster ){ - while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){ - size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize; - mem3.iMaster -= size; - mem3.szMaster += size; - memsys3Unlink(mem3.iMaster); - x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; - mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; - mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; - } - x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2; - while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){ - memsys3Unlink(mem3.iMaster+mem3.szMaster); - mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4; - mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x; - mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster; - } - } -} - -/* -** Return the size of an outstanding allocation, in bytes. The -** size returned omits the 8-byte header overhead. This only -** works for chunks that are currently checked out. -*/ -static int memsys3Size(void *p){ - Mem3Block *pBlock; - assert( p!=0 ); - pBlock = (Mem3Block*)p; - assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); - return (pBlock[-1].u.hdr.size4x&~3)*2 - 4; -} - -/* -** Round up a request size to the next valid allocation size. -*/ -static int memsys3Roundup(int n){ - if( n<=12 ){ - return 12; - }else{ - return ((n+11)&~7) - 4; - } -} - -/* -** Allocate nBytes of memory. -*/ -static void *memsys3Malloc(int nBytes){ - sqlite3_int64 *p; - assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ - memsys3Enter(); - p = memsys3MallocUnsafe(nBytes); - memsys3Leave(); - return (void*)p; -} - -/* -** Free memory. -*/ -static void memsys3Free(void *pPrior){ - assert( pPrior ); - memsys3Enter(); - memsys3FreeUnsafe(pPrior); - memsys3Leave(); -} - -/* -** Change the size of an existing memory allocation -*/ -static void *memsys3Realloc(void *pPrior, int nBytes){ - int nOld; - void *p; - if( pPrior==0 ){ - return sqlite3_malloc(nBytes); - } - if( nBytes<=0 ){ - sqlite3_free(pPrior); - return 0; - } - nOld = memsys3Size(pPrior); - if( nBytes<=nOld && nBytes>=nOld-128 ){ - return pPrior; - } - memsys3Enter(); - p = memsys3MallocUnsafe(nBytes); - if( p ){ - if( nOld>1)!=(size&1) ){ - fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]); - assert( 0 ); - break; - } - if( size&1 ){ - fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8); - }else{ - fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8, - i==mem3.iMaster ? " **master**" : ""); - } - } - for(i=0; i0; j=mem3.aPool[j].u.list.next){ - fprintf(out, " %p(%d)", &mem3.aPool[j], - (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); - } - fprintf(out, "\n"); - } - for(i=0; i0; j=mem3.aPool[j].u.list.next){ - fprintf(out, " %p(%d)", &mem3.aPool[j], - (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); - } - fprintf(out, "\n"); - } - fprintf(out, "master=%d\n", mem3.iMaster); - fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); - fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); - sqlite3_mutex_leave(mem3.mutex); - if( out==stdout ){ - fflush(stdout); - }else{ - fclose(out); - } -#else - UNUSED_PARAMETER(zFilename); -#endif -} - -/* -** This routine is the only routine in this file with external -** linkage. -** -** Populate the low-level memory allocation function pointers in -** sqlite3GlobalConfig.m with pointers to the routines in this file. The -** arguments specify the block of memory to manage. -** -** This routine is only called by sqlite3_config(), and therefore -** is not required to be threadsafe (it is not). -*/ -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ - static const sqlite3_mem_methods mempoolMethods = { - memsys3Malloc, - memsys3Free, - memsys3Realloc, - memsys3Size, - memsys3Roundup, - memsys3Init, - memsys3Shutdown, - 0 - }; - return &mempoolMethods; -} - -#endif /* SQLITE_ENABLE_MEMSYS3 */ - -/************** End of mem3.c ************************************************/ -/************** Begin file mem5.c ********************************************/ -/* -** 2007 October 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement a memory -** allocation subsystem for use by SQLite. -** -** This version of the memory allocation subsystem omits all -** use of malloc(). The application gives SQLite a block of memory -** before calling sqlite3_initialize() from which allocations -** are made and returned by the xMalloc() and xRealloc() -** implementations. Once sqlite3_initialize() has been called, -** the amount of memory available to SQLite is fixed and cannot -** be changed. -** -** This version of the memory allocation subsystem is included -** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. -** -** This memory allocator uses the following algorithm: -** -** 1. All memory allocation sizes are rounded up to a power of 2. -** -** 2. If two adjacent free blocks are the halves of a larger block, -** then the two blocks are coalesced into the single larger block. -** -** 3. New memory is allocated from the first available free block. -** -** This algorithm is described in: J. M. Robson. "Bounds for Some Functions -** Concerning Dynamic Storage Allocation". Journal of the Association for -** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. -** -** Let n be the size of the largest allocation divided by the minimum -** allocation size (after rounding all sizes up to a power of 2.) Let M -** be the maximum amount of memory ever outstanding at one time. Let -** N be the total amount of memory available for allocation. Robson -** proved that this memory allocator will never breakdown due to -** fragmentation as long as the following constraint holds: -** -** N >= M*(1 + log2(n)/2) - n + 1 -** -** The sqlite3_status() logic tracks the maximum values of n and M so -** that an application can, at any time, verify this constraint. -*/ -/* #include "sqliteInt.h" */ - -/* -** This version of the memory allocator is used only when -** SQLITE_ENABLE_MEMSYS5 is defined. -*/ -#ifdef SQLITE_ENABLE_MEMSYS5 - -/* -** A minimum allocation is an instance of the following structure. -** Larger allocations are an array of these structures where the -** size of the array is a power of 2. -** -** The size of this object must be a power of two. That fact is -** verified in memsys5Init(). -*/ -typedef struct Mem5Link Mem5Link; -struct Mem5Link { - int next; /* Index of next free chunk */ - int prev; /* Index of previous free chunk */ -}; - -/* -** Maximum size of any allocation is ((1<=0 && i=0 && iLogsize<=LOGMAX ); - assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); - - next = MEM5LINK(i)->next; - prev = MEM5LINK(i)->prev; - if( prev<0 ){ - mem5.aiFreelist[iLogsize] = next; - }else{ - MEM5LINK(prev)->next = next; - } - if( next>=0 ){ - MEM5LINK(next)->prev = prev; - } -} - -/* -** Link the chunk at mem5.aPool[i] so that is on the iLogsize -** free list. -*/ -static void memsys5Link(int i, int iLogsize){ - int x; - assert( sqlite3_mutex_held(mem5.mutex) ); - assert( i>=0 && i=0 && iLogsize<=LOGMAX ); - assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); - - x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize]; - MEM5LINK(i)->prev = -1; - if( x>=0 ){ - assert( xprev = i; - } - mem5.aiFreelist[iLogsize] = i; -} - -/* -** Obtain or release the mutex needed to access global data structures. -*/ -static void memsys5Enter(void){ - sqlite3_mutex_enter(mem5.mutex); -} -static void memsys5Leave(void){ - sqlite3_mutex_leave(mem5.mutex); -} - -/* -** Return the size of an outstanding allocation, in bytes. -** This only works for chunks that are currently checked out. -*/ -static int memsys5Size(void *p){ - int iSize, i; - assert( p!=0 ); - i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); - assert( i>=0 && i0 ); - - /* No more than 1GiB per allocation */ - if( nByte > 0x40000000 ) return 0; - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* Keep track of the maximum allocation request. Even unfulfilled - ** requests are counted */ - if( (u32)nByte>mem5.maxRequest ){ - mem5.maxRequest = nByte; - } -#endif - - - /* Round nByte up to the next valid power of two */ - for(iFullSz=mem5.szAtom,iLogsize=0; iFullSzLOGMAX ){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); - return 0; - } - i = mem5.aiFreelist[iBin]; - memsys5Unlink(i, iBin); - while( iBin>iLogsize ){ - int newSize; - - iBin--; - newSize = 1 << iBin; - mem5.aCtrl[i+newSize] = CTRL_FREE | iBin; - memsys5Link(i+newSize, iBin); - } - mem5.aCtrl[i] = iLogsize; - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* Update allocator performance statistics. */ - mem5.nAlloc++; - mem5.totalAlloc += iFullSz; - mem5.totalExcess += iFullSz - nByte; - mem5.currentCount++; - mem5.currentOut += iFullSz; - if( mem5.maxCount=0 && iBlock0 ); - assert( mem5.currentOut>=(size*mem5.szAtom) ); - mem5.currentCount--; - mem5.currentOut -= size*mem5.szAtom; - assert( mem5.currentOut>0 || mem5.currentCount==0 ); - assert( mem5.currentCount>0 || mem5.currentOut==0 ); -#endif - - mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; - while( ALWAYS(iLogsize>iLogsize) & 1 ){ - iBuddy = iBlock - size; - assert( iBuddy>=0 ); - }else{ - iBuddy = iBlock + size; - if( iBuddy>=mem5.nBlock ) break; - } - if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; - memsys5Unlink(iBuddy, iLogsize); - iLogsize++; - if( iBuddy0 ){ - memsys5Enter(); - p = memsys5MallocUnsafe(nBytes); - memsys5Leave(); - } - return (void*)p; -} - -/* -** Free memory. -** -** The outer layer memory allocator prevents this routine from -** being called with pPrior==0. -*/ -static void memsys5Free(void *pPrior){ - assert( pPrior!=0 ); - memsys5Enter(); - memsys5FreeUnsafe(pPrior); - memsys5Leave(); -} - -/* -** Change the size of an existing memory allocation. -** -** The outer layer memory allocator prevents this routine from -** being called with pPrior==0. -** -** nBytes is always a value obtained from a prior call to -** memsys5Round(). Hence nBytes is always a non-negative power -** of two. If nBytes==0 that means that an oversize allocation -** (an allocation larger than 0x40000000) was requested and this -** routine should return 0 without freeing pPrior. -*/ -static void *memsys5Realloc(void *pPrior, int nBytes){ - int nOld; - void *p; - assert( pPrior!=0 ); - assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ - assert( nBytes>=0 ); - if( nBytes==0 ){ - return 0; - } - nOld = memsys5Size(pPrior); - if( nBytes<=nOld ){ - return pPrior; - } - p = memsys5Malloc(nBytes); - if( p ){ - memcpy(p, pPrior, nOld); - memsys5Free(pPrior); - } - return p; -} - -/* -** Round up a request size to the next valid allocation size. If -** the allocation is too large to be handled by this allocation system, -** return 0. -** -** All allocations must be a power of two and must be expressed by a -** 32-bit signed integer. Hence the largest allocation is 0x40000000 -** or 1073741824 bytes. -*/ -static int memsys5Roundup(int n){ - int iFullSz; - if( n > 0x40000000 ) return 0; - for(iFullSz=mem5.szAtom; iFullSz 0 -** memsys5Log(2) -> 1 -** memsys5Log(4) -> 2 -** memsys5Log(5) -> 3 -** memsys5Log(8) -> 3 -** memsys5Log(9) -> 4 -*/ -static int memsys5Log(int iValue){ - int iLog; - for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<mem5.szAtom ){ - mem5.szAtom = mem5.szAtom << 1; - } - - mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8))); - mem5.zPool = zByte; - mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom]; - - for(ii=0; ii<=LOGMAX; ii++){ - mem5.aiFreelist[ii] = -1; - } - - iOffset = 0; - for(ii=LOGMAX; ii>=0; ii--){ - int nAlloc = (1<mem5.nBlock); - } - - /* If a mutex is required for normal operation, allocate one */ - if( sqlite3GlobalConfig.bMemstat==0 ){ - mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - } - - return SQLITE_OK; -} - -/* -** Deinitialize this module. -*/ -static void memsys5Shutdown(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - mem5.mutex = 0; - return; -} - -#ifdef SQLITE_TEST -/* -** Open the file indicated and write a log of all unfreed memory -** allocations into that log. -*/ -SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ - FILE *out; - int i, j, n; - int nMinLog; - - if( zFilename==0 || zFilename[0]==0 ){ - out = stdout; - }else{ - out = fopen(zFilename, "w"); - if( out==0 ){ - fprintf(stderr, "** Unable to output memory debug output log: %s **\n", - zFilename); - return; - } - } - memsys5Enter(); - nMinLog = memsys5Log(mem5.szAtom); - for(i=0; i<=LOGMAX && i+nMinLog<32; i++){ - for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){} - fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n); - } - fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc); - fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc); - fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess); - fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut); - fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount); - fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut); - fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount); - fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest); - memsys5Leave(); - if( out==stdout ){ - fflush(stdout); - }else{ - fclose(out); - } -} -#endif - -/* -** This routine is the only routine in this file with external -** linkage. It returns a pointer to a static sqlite3_mem_methods -** struct populated with the memsys5 methods. -*/ -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ - static const sqlite3_mem_methods memsys5Methods = { - memsys5Malloc, - memsys5Free, - memsys5Realloc, - memsys5Size, - memsys5Roundup, - memsys5Init, - memsys5Shutdown, - 0 - }; - return &memsys5Methods; -} - -#endif /* SQLITE_ENABLE_MEMSYS5 */ - -/************** End of mem5.c ************************************************/ -/************** Begin file mutex.c *******************************************/ -/* -** 2007 August 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement mutexes. -** -** This file contains code that is common across all mutex implementations. -*/ -/* #include "sqliteInt.h" */ - -#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) -/* -** For debugging purposes, record when the mutex subsystem is initialized -** and uninitialized so that we can assert() if there is an attempt to -** allocate a mutex while the system is uninitialized. -*/ -static SQLITE_WSD int mutexIsInit = 0; -#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */ - - -#ifndef SQLITE_MUTEX_OMIT -/* -** Initialize the mutex system. -*/ -SQLITE_PRIVATE int sqlite3MutexInit(void){ - int rc = SQLITE_OK; - if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ - /* If the xMutexAlloc method has not been set, then the user did not - ** install a mutex implementation via sqlite3_config() prior to - ** sqlite3_initialize() being called. This block copies pointers to - ** the default implementation into the sqlite3GlobalConfig structure. - */ - sqlite3_mutex_methods const *pFrom; - sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; - - if( sqlite3GlobalConfig.bCoreMutex ){ - pFrom = sqlite3DefaultMutex(); - }else{ - pFrom = sqlite3NoopMutex(); - } - pTo->xMutexInit = pFrom->xMutexInit; - pTo->xMutexEnd = pFrom->xMutexEnd; - pTo->xMutexFree = pFrom->xMutexFree; - pTo->xMutexEnter = pFrom->xMutexEnter; - pTo->xMutexTry = pFrom->xMutexTry; - pTo->xMutexLeave = pFrom->xMutexLeave; - pTo->xMutexHeld = pFrom->xMutexHeld; - pTo->xMutexNotheld = pFrom->xMutexNotheld; - sqlite3MemoryBarrier(); - pTo->xMutexAlloc = pFrom->xMutexAlloc; - } - assert( sqlite3GlobalConfig.mutex.xMutexInit ); - rc = sqlite3GlobalConfig.mutex.xMutexInit(); - -#ifdef SQLITE_DEBUG - GLOBAL(int, mutexIsInit) = 1; -#endif - - return rc; -} - -/* -** Shutdown the mutex system. This call frees resources allocated by -** sqlite3MutexInit(). -*/ -SQLITE_PRIVATE int sqlite3MutexEnd(void){ - int rc = SQLITE_OK; - if( sqlite3GlobalConfig.mutex.xMutexEnd ){ - rc = sqlite3GlobalConfig.mutex.xMutexEnd(); - } - -#ifdef SQLITE_DEBUG - GLOBAL(int, mutexIsInit) = 0; -#endif - - return rc; -} - -/* -** Retrieve a pointer to a static mutex or allocate a new dynamic one. -*/ -SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ -#ifndef SQLITE_OMIT_AUTOINIT - if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; - if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0; -#endif - assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); - return sqlite3GlobalConfig.mutex.xMutexAlloc(id); -} - -SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ - if( !sqlite3GlobalConfig.bCoreMutex ){ - return 0; - } - assert( GLOBAL(int, mutexIsInit) ); - assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); - return sqlite3GlobalConfig.mutex.xMutexAlloc(id); -} - -/* -** Free a dynamic mutex. -*/ -SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ - if( p ){ - assert( sqlite3GlobalConfig.mutex.xMutexFree ); - sqlite3GlobalConfig.mutex.xMutexFree(p); - } -} - -/* -** Obtain the mutex p. If some other thread already has the mutex, block -** until it can be obtained. -*/ -SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ - if( p ){ - assert( sqlite3GlobalConfig.mutex.xMutexEnter ); - sqlite3GlobalConfig.mutex.xMutexEnter(p); - } -} - -/* -** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another -** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. -*/ -SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ - int rc = SQLITE_OK; - if( p ){ - assert( sqlite3GlobalConfig.mutex.xMutexTry ); - return sqlite3GlobalConfig.mutex.xMutexTry(p); - } - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was previously -** entered by the same thread. The behavior is undefined if the mutex -** is not currently entered. If a NULL pointer is passed as an argument -** this function is a no-op. -*/ -SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ - if( p ){ - assert( sqlite3GlobalConfig.mutex.xMutexLeave ); - sqlite3GlobalConfig.mutex.xMutexLeave(p); - } -} - -#ifndef NDEBUG -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use inside assert() statements. -*/ -SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ - assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); - return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); -} -SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ - assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); - return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); -} -#endif - -#endif /* !defined(SQLITE_MUTEX_OMIT) */ - -/************** End of mutex.c ***********************************************/ -/************** Begin file mutex_noop.c **************************************/ -/* -** 2008 October 07 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement mutexes. -** -** This implementation in this file does not provide any mutual -** exclusion and is thus suitable for use only in applications -** that use SQLite in a single thread. The routines defined -** here are place-holders. Applications can substitute working -** mutex routines at start-time using the -** -** sqlite3_config(SQLITE_CONFIG_MUTEX,...) -** -** interface. -** -** If compiled with SQLITE_DEBUG, then additional logic is inserted -** that does error checking on mutexes to make sure they are being -** called correctly. -*/ -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_MUTEX_OMIT - -#ifndef SQLITE_DEBUG -/* -** Stub routines for all mutex methods. -** -** This routines provide no mutual exclusion or error checking. -*/ -static int noopMutexInit(void){ return SQLITE_OK; } -static int noopMutexEnd(void){ return SQLITE_OK; } -static sqlite3_mutex *noopMutexAlloc(int id){ - UNUSED_PARAMETER(id); - return (sqlite3_mutex*)8; -} -static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } -static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } -static int noopMutexTry(sqlite3_mutex *p){ - UNUSED_PARAMETER(p); - return SQLITE_OK; -} -static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } - -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ - static const sqlite3_mutex_methods sMutex = { - noopMutexInit, - noopMutexEnd, - noopMutexAlloc, - noopMutexFree, - noopMutexEnter, - noopMutexTry, - noopMutexLeave, - - 0, - 0, - }; - - return &sMutex; -} -#endif /* !SQLITE_DEBUG */ - -#ifdef SQLITE_DEBUG -/* -** In this implementation, error checking is provided for testing -** and debugging purposes. The mutexes still do not provide any -** mutual exclusion. -*/ - -/* -** The mutex object -*/ -typedef struct sqlite3_debug_mutex { - int id; /* The mutex type */ - int cnt; /* Number of entries without a matching leave */ -} sqlite3_debug_mutex; - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use inside assert() statements. -*/ -static int debugMutexHeld(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - return p==0 || p->cnt>0; -} -static int debugMutexNotheld(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - return p==0 || p->cnt==0; -} - -/* -** Initialize and deinitialize the mutex subsystem. -*/ -static int debugMutexInit(void){ return SQLITE_OK; } -static int debugMutexEnd(void){ return SQLITE_OK; } - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. -*/ -static sqlite3_mutex *debugMutexAlloc(int id){ - static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1]; - sqlite3_debug_mutex *pNew = 0; - switch( id ){ - case SQLITE_MUTEX_FAST: - case SQLITE_MUTEX_RECURSIVE: { - pNew = sqlite3Malloc(sizeof(*pNew)); - if( pNew ){ - pNew->id = id; - pNew->cnt = 0; - } - break; - } - default: { -#ifdef SQLITE_ENABLE_API_ARMOR - if( id-2<0 || id-2>=ArraySize(aStatic) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - pNew = &aStatic[id-2]; - pNew->id = id; - break; - } - } - return (sqlite3_mutex*)pNew; -} - -/* -** This routine deallocates a previously allocated mutex. -*/ -static void debugMutexFree(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - assert( p->cnt==0 ); - if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ - sqlite3_free(p); - }else{ -#ifdef SQLITE_ENABLE_API_ARMOR - (void)SQLITE_MISUSE_BKPT; -#endif - } -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -static void debugMutexEnter(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); - p->cnt++; -} -static int debugMutexTry(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); - p->cnt++; - return SQLITE_OK; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -static void debugMutexLeave(sqlite3_mutex *pX){ - sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; - assert( debugMutexHeld(pX) ); - p->cnt--; - assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); -} - -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ - static const sqlite3_mutex_methods sMutex = { - debugMutexInit, - debugMutexEnd, - debugMutexAlloc, - debugMutexFree, - debugMutexEnter, - debugMutexTry, - debugMutexLeave, - - debugMutexHeld, - debugMutexNotheld - }; - - return &sMutex; -} -#endif /* SQLITE_DEBUG */ - -/* -** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation -** is used regardless of the run-time threadsafety setting. -*/ -#ifdef SQLITE_MUTEX_NOOP -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ - return sqlite3NoopMutex(); -} -#endif /* defined(SQLITE_MUTEX_NOOP) */ -#endif /* !defined(SQLITE_MUTEX_OMIT) */ - -/************** End of mutex_noop.c ******************************************/ -/************** Begin file mutex_unix.c **************************************/ -/* -** 2007 August 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement mutexes for pthreads -*/ -/* #include "sqliteInt.h" */ - -/* -** The code in this file is only used if we are compiling threadsafe -** under unix with pthreads. -** -** Note that this implementation requires a version of pthreads that -** supports recursive mutexes. -*/ -#ifdef SQLITE_MUTEX_PTHREADS - -#include - -/* -** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields -** are necessary under two condidtions: (1) Debug builds and (2) using -** home-grown mutexes. Encapsulate these conditions into a single #define. -*/ -#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) -# define SQLITE_MUTEX_NREF 1 -#else -# define SQLITE_MUTEX_NREF 0 -#endif - -/* -** Each recursive mutex is an instance of the following structure. -*/ -struct sqlite3_mutex { - pthread_mutex_t mutex; /* Mutex controlling the lock */ -#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) - int id; /* Mutex type */ -#endif -#if SQLITE_MUTEX_NREF - volatile int nRef; /* Number of entrances */ - volatile pthread_t owner; /* Thread that is within this mutex */ - int trace; /* True to trace changes */ -#endif -}; -#if SQLITE_MUTEX_NREF -#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0} -#elif defined(SQLITE_ENABLE_API_ARMOR) -#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 } -#else -#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } -#endif - -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. On some platforms, -** there might be race conditions that can cause these routines to -** deliver incorrect results. In particular, if pthread_equal() is -** not an atomic operation, then these routines might delivery -** incorrect results. On most platforms, pthread_equal() is a -** comparison of two integers and is therefore atomic. But we are -** told that HPUX is not such a platform. If so, then these routines -** will not always work correctly on HPUX. -** -** On those platforms where pthread_equal() is not atomic, SQLite -** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to -** make sure no assert() statements are evaluated and hence these -** routines are never called. -*/ -#if !defined(NDEBUG) || defined(SQLITE_DEBUG) -static int pthreadMutexHeld(sqlite3_mutex *p){ - return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); -} -static int pthreadMutexNotheld(sqlite3_mutex *p){ - return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; -} -#endif - -/* -** Try to provide a memory barrier operation, needed for initialization -** and also for the implementation of xShmBarrier in the VFS in cases -** where SQLite is compiled without mutexes. -*/ -SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ -#if defined(SQLITE_MEMORY_BARRIER) - SQLITE_MEMORY_BARRIER; -#elif defined(__GNUC__) && GCC_VERSION>=4001000 - __sync_synchronize(); -#endif -} - -/* -** Initialize and deinitialize the mutex subsystem. -*/ -static int pthreadMutexInit(void){ return SQLITE_OK; } -static int pthreadMutexEnd(void){ return SQLITE_OK; } - -/* -** The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. If it returns NULL -** that means that a mutex could not be allocated. SQLite -** will unwind its stack and return an error. The argument -** to sqlite3_mutex_alloc() is one of these integer constants: -** -**
    -**
  • SQLITE_MUTEX_FAST -**
  • SQLITE_MUTEX_RECURSIVE -**
  • SQLITE_MUTEX_STATIC_MASTER -**
  • SQLITE_MUTEX_STATIC_MEM -**
  • SQLITE_MUTEX_STATIC_OPEN -**
  • SQLITE_MUTEX_STATIC_PRNG -**
  • SQLITE_MUTEX_STATIC_LRU -**
  • SQLITE_MUTEX_STATIC_PMEM -**
  • SQLITE_MUTEX_STATIC_APP1 -**
  • SQLITE_MUTEX_STATIC_APP2 -**
  • SQLITE_MUTEX_STATIC_APP3 -**
  • SQLITE_MUTEX_STATIC_VFS1 -**
  • SQLITE_MUTEX_STATIC_VFS2 -**
  • SQLITE_MUTEX_STATIC_VFS3 -**
-** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Six static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -*/ -static sqlite3_mutex *pthreadMutexAlloc(int iType){ - static sqlite3_mutex staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER - }; - sqlite3_mutex *p; - switch( iType ){ - case SQLITE_MUTEX_RECURSIVE: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ -#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX - /* If recursive mutexes are not available, we will have to - ** build our own. See below. */ - pthread_mutex_init(&p->mutex, 0); -#else - /* Use a recursive mutex if it is available */ - pthread_mutexattr_t recursiveAttr; - pthread_mutexattr_init(&recursiveAttr); - pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&p->mutex, &recursiveAttr); - pthread_mutexattr_destroy(&recursiveAttr); -#endif - } - break; - } - case SQLITE_MUTEX_FAST: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - pthread_mutex_init(&p->mutex, 0); - } - break; - } - default: { -#ifdef SQLITE_ENABLE_API_ARMOR - if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - p = &staticMutexes[iType-2]; - break; - } - } -#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) - if( p ) p->id = iType; -#endif - return p; -} - - -/* -** This routine deallocates a previously -** allocated mutex. SQLite is careful to deallocate every -** mutex that it allocates. -*/ -static void pthreadMutexFree(sqlite3_mutex *p){ - assert( p->nRef==0 ); -#if SQLITE_ENABLE_API_ARMOR - if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) -#endif - { - pthread_mutex_destroy(&p->mutex); - sqlite3_free(p); - } -#ifdef SQLITE_ENABLE_API_ARMOR - else{ - (void)SQLITE_MISUSE_BKPT; - } -#endif -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -static void pthreadMutexEnter(sqlite3_mutex *p){ - assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); - -#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX - /* If recursive mutexes are not available, then we have to grow - ** our own. This implementation assumes that pthread_equal() - ** is atomic - that it cannot be deceived into thinking self - ** and p->owner are equal if p->owner changes between two values - ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that - ** separate processes cannot read different values from the same - ** address at the same time. If either of these two conditions - ** are not met, then the mutexes will fail and problems will result. - */ - { - pthread_t self = pthread_self(); - if( p->nRef>0 && pthread_equal(p->owner, self) ){ - p->nRef++; - }else{ - pthread_mutex_lock(&p->mutex); - assert( p->nRef==0 ); - p->owner = self; - p->nRef = 1; - } - } -#else - /* Use the built-in recursive mutexes if they are available. - */ - pthread_mutex_lock(&p->mutex); -#if SQLITE_MUTEX_NREF - assert( p->nRef>0 || p->owner==0 ); - p->owner = pthread_self(); - p->nRef++; -#endif -#endif - -#ifdef SQLITE_DEBUG - if( p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif -} -static int pthreadMutexTry(sqlite3_mutex *p){ - int rc; - assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); - -#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX - /* If recursive mutexes are not available, then we have to grow - ** our own. This implementation assumes that pthread_equal() - ** is atomic - that it cannot be deceived into thinking self - ** and p->owner are equal if p->owner changes between two values - ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that - ** separate processes cannot read different values from the same - ** address at the same time. If either of these two conditions - ** are not met, then the mutexes will fail and problems will result. - */ - { - pthread_t self = pthread_self(); - if( p->nRef>0 && pthread_equal(p->owner, self) ){ - p->nRef++; - rc = SQLITE_OK; - }else if( pthread_mutex_trylock(&p->mutex)==0 ){ - assert( p->nRef==0 ); - p->owner = self; - p->nRef = 1; - rc = SQLITE_OK; - }else{ - rc = SQLITE_BUSY; - } - } -#else - /* Use the built-in recursive mutexes if they are available. - */ - if( pthread_mutex_trylock(&p->mutex)==0 ){ -#if SQLITE_MUTEX_NREF - p->owner = pthread_self(); - p->nRef++; -#endif - rc = SQLITE_OK; - }else{ - rc = SQLITE_BUSY; - } -#endif - -#ifdef SQLITE_DEBUG - if( rc==SQLITE_OK && p->trace ){ - printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -static void pthreadMutexLeave(sqlite3_mutex *p){ - assert( pthreadMutexHeld(p) ); -#if SQLITE_MUTEX_NREF - p->nRef--; - if( p->nRef==0 ) p->owner = 0; -#endif - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); - -#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX - if( p->nRef==0 ){ - pthread_mutex_unlock(&p->mutex); - } -#else - pthread_mutex_unlock(&p->mutex); -#endif - -#ifdef SQLITE_DEBUG - if( p->trace ){ - printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); - } -#endif -} - -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ - static const sqlite3_mutex_methods sMutex = { - pthreadMutexInit, - pthreadMutexEnd, - pthreadMutexAlloc, - pthreadMutexFree, - pthreadMutexEnter, - pthreadMutexTry, - pthreadMutexLeave, -#ifdef SQLITE_DEBUG - pthreadMutexHeld, - pthreadMutexNotheld -#else - 0, - 0 -#endif - }; - - return &sMutex; -} - -#endif /* SQLITE_MUTEX_PTHREADS */ - -/************** End of mutex_unix.c ******************************************/ -/************** Begin file mutex_w32.c ***************************************/ -/* -** 2007 August 14 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C functions that implement mutexes for Win32. -*/ -/* #include "sqliteInt.h" */ - -#if SQLITE_OS_WIN -/* -** Include code that is common to all os_*.c files -*/ -/************** Include os_common.h in the middle of mutex_w32.c *************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - #error Need implementation of sqlite3Hwtime() for your platform. - - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in mutex_w32.c ******************/ - -/* -** Include the header file for the Windows VFS. -*/ -/************** Include os_win.h in the middle of mutex_w32.c ****************/ -/************** Begin file os_win.h ******************************************/ -/* -** 2013 November 25 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to Windows. -*/ -#ifndef SQLITE_OS_WIN_H -#define SQLITE_OS_WIN_H - -/* -** Include the primary Windows SDK header file. -*/ -#include "windows.h" - -#ifdef __CYGWIN__ -# include -# include /* amalgamator: dontcache */ -#endif - -/* -** Determine if we are dealing with Windows NT. -** -** We ought to be able to determine if we are compiling for Windows 9x or -** Windows NT using the _WIN32_WINNT macro as follows: -** -** #if defined(_WIN32_WINNT) -** # define SQLITE_OS_WINNT 1 -** #else -** # define SQLITE_OS_WINNT 0 -** #endif -** -** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as -** it ought to, so the above test does not work. We'll just assume that -** everything is Windows NT unless the programmer explicitly says otherwise -** by setting SQLITE_OS_WINNT to 0. -*/ -#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) -# define SQLITE_OS_WINNT 1 -#endif - -/* -** Determine if we are dealing with Windows CE - which has a much reduced -** API. -*/ -#if defined(_WIN32_WCE) -# define SQLITE_OS_WINCE 1 -#else -# define SQLITE_OS_WINCE 0 -#endif - -/* -** Determine if we are dealing with WinRT, which provides only a subset of -** the full Win32 API. -*/ -#if !defined(SQLITE_OS_WINRT) -# define SQLITE_OS_WINRT 0 -#endif - -/* -** For WinCE, some API function parameters do not appear to be declared as -** volatile. -*/ -#if SQLITE_OS_WINCE -# define SQLITE_WIN32_VOLATILE -#else -# define SQLITE_WIN32_VOLATILE volatile -#endif - -/* -** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() -** functions are not available (e.g. those not using MSVC, Cygwin, etc). -*/ -#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ - SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) -# define SQLITE_OS_WIN_THREADS 1 -#else -# define SQLITE_OS_WIN_THREADS 0 -#endif - -#endif /* SQLITE_OS_WIN_H */ - -/************** End of os_win.h **********************************************/ -/************** Continuing where we left off in mutex_w32.c ******************/ -#endif - -/* -** The code in this file is only used if we are compiling multithreaded -** on a Win32 system. -*/ -#ifdef SQLITE_MUTEX_W32 - -/* -** Each recursive mutex is an instance of the following structure. -*/ -struct sqlite3_mutex { - CRITICAL_SECTION mutex; /* Mutex controlling the lock */ - int id; /* Mutex type */ -#ifdef SQLITE_DEBUG - volatile int nRef; /* Number of enterances */ - volatile DWORD owner; /* Thread holding this mutex */ - volatile int trace; /* True to trace changes */ -#endif -}; - -/* -** These are the initializer values used when declaring a "static" mutex -** on Win32. It should be noted that all mutexes require initialization -** on the Win32 platform. -*/ -#define SQLITE_W32_MUTEX_INITIALIZER { 0 } - -#ifdef SQLITE_DEBUG -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \ - 0L, (DWORD)0, 0 } -#else -#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 } -#endif - -#ifdef SQLITE_DEBUG -/* -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are -** intended for use only inside assert() statements. -*/ -static int winMutexHeld(sqlite3_mutex *p){ - return p->nRef!=0 && p->owner==GetCurrentThreadId(); -} - -static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ - return p->nRef==0 || p->owner!=tid; -} - -static int winMutexNotheld(sqlite3_mutex *p){ - DWORD tid = GetCurrentThreadId(); - return winMutexNotheld2(p, tid); -} -#endif - -/* -** Try to provide a memory barrier operation, needed for initialization -** and also for the xShmBarrier method of the VFS in cases when SQLite is -** compiled without mutexes (SQLITE_THREADSAFE=0). -*/ -SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ -#if defined(SQLITE_MEMORY_BARRIER) - SQLITE_MEMORY_BARRIER; -#elif defined(__GNUC__) - __sync_synchronize(); -#elif !defined(SQLITE_DISABLE_INTRINSIC) && \ - defined(_MSC_VER) && _MSC_VER>=1300 - _ReadWriteBarrier(); -#elif defined(MemoryBarrier) - MemoryBarrier(); -#endif -} - -/* -** Initialize and deinitialize the mutex subsystem. -*/ -static sqlite3_mutex winMutex_staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER, - SQLITE3_MUTEX_INITIALIZER -}; - -static int winMutex_isInit = 0; -static int winMutex_isNt = -1; /* <0 means "need to query" */ - -/* As the winMutexInit() and winMutexEnd() functions are called as part -** of the sqlite3_initialize() and sqlite3_shutdown() processing, the -** "interlocked" magic used here is probably not strictly necessary. -*/ -static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; - -SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ -SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ - -static int winMutexInit(void){ - /* The first to increment to 1 does actual initialization */ - if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ - int i; - for(i=0; i -**
  • SQLITE_MUTEX_FAST -**
  • SQLITE_MUTEX_RECURSIVE -**
  • SQLITE_MUTEX_STATIC_MASTER -**
  • SQLITE_MUTEX_STATIC_MEM -**
  • SQLITE_MUTEX_STATIC_OPEN -**
  • SQLITE_MUTEX_STATIC_PRNG -**
  • SQLITE_MUTEX_STATIC_LRU -**
  • SQLITE_MUTEX_STATIC_PMEM -**
  • SQLITE_MUTEX_STATIC_APP1 -**
  • SQLITE_MUTEX_STATIC_APP2 -**
  • SQLITE_MUTEX_STATIC_APP3 -**
  • SQLITE_MUTEX_STATIC_VFS1 -**
  • SQLITE_MUTEX_STATIC_VFS2 -**
  • SQLITE_MUTEX_STATIC_VFS3 -** -** -** The first two constants cause sqlite3_mutex_alloc() to create -** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE -** is used but not necessarily so when SQLITE_MUTEX_FAST is used. -** The mutex implementation does not need to make a distinction -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. But SQLite will only request a recursive mutex in -** cases where it really needs one. If a faster non-recursive mutex -** implementation is available on the host platform, the mutex subsystem -** might return such a mutex in response to SQLITE_MUTEX_FAST. -** -** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Six static mutexes are -** used by the current version of SQLite. Future versions of SQLite -** may add additional static mutexes. Static mutexes are for internal -** use by SQLite only. Applications that use SQLite mutexes should -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or -** SQLITE_MUTEX_RECURSIVE. -** -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static -** mutex types, the same mutex is returned on every call that has -** the same type number. -*/ -static sqlite3_mutex *winMutexAlloc(int iType){ - sqlite3_mutex *p; - - switch( iType ){ - case SQLITE_MUTEX_FAST: - case SQLITE_MUTEX_RECURSIVE: { - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - p->id = iType; -#ifdef SQLITE_DEBUG -#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC - p->trace = 1; -#endif -#endif -#if SQLITE_OS_WINRT - InitializeCriticalSectionEx(&p->mutex, 0, 0); -#else - InitializeCriticalSection(&p->mutex); -#endif - } - break; - } - default: { -#ifdef SQLITE_ENABLE_API_ARMOR - if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - p = &winMutex_staticMutexes[iType-2]; - p->id = iType; -#ifdef SQLITE_DEBUG -#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC - p->trace = 1; -#endif -#endif - break; - } - } - return p; -} - - -/* -** This routine deallocates a previously -** allocated mutex. SQLite is careful to deallocate every -** mutex that it allocates. -*/ -static void winMutexFree(sqlite3_mutex *p){ - assert( p ); - assert( p->nRef==0 && p->owner==0 ); - if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ - DeleteCriticalSection(&p->mutex); - sqlite3_free(p); - }else{ -#ifdef SQLITE_ENABLE_API_ARMOR - (void)SQLITE_MISUSE_BKPT; -#endif - } -} - -/* -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt -** to enter a mutex. If another thread is already within the mutex, -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return -** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK -** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can -** be entered multiple times by the same thread. In such cases the, -** mutex must be exited an equal number of times before another thread -** can enter. If the same thread tries to enter any other kind of mutex -** more than once, the behavior is undefined. -*/ -static void winMutexEnter(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif -#ifdef SQLITE_DEBUG - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); -#else - assert( p ); -#endif - assert( winMutex_isInit==1 ); - EnterCriticalSection(&p->mutex); -#ifdef SQLITE_DEBUG - assert( p->nRef>0 || p->owner==0 ); - p->owner = tid; - p->nRef++; - if( p->trace ){ - OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); - } -#endif -} - -static int winMutexTry(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif - int rc = SQLITE_BUSY; - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); - /* - ** The sqlite3_mutex_try() routine is very rarely used, and when it - ** is used it is merely an optimization. So it is OK for it to always - ** fail. - ** - ** The TryEnterCriticalSection() interface is only available on WinNT. - ** And some windows compilers complain if you try to use it without - ** first doing some #defines that prevent SQLite from building on Win98. - ** For that reason, we will omit this optimization for now. See - ** ticket #2685. - */ -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 - assert( winMutex_isInit==1 ); - assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); - if( winMutex_isNt<0 ){ - winMutex_isNt = sqlite3_win32_is_nt(); - } - assert( winMutex_isNt==0 || winMutex_isNt==1 ); - if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ -#ifdef SQLITE_DEBUG - p->owner = tid; - p->nRef++; -#endif - rc = SQLITE_OK; - } -#else - UNUSED_PARAMETER(p); -#endif -#ifdef SQLITE_DEBUG - if( p->trace ){ - OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n", - tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); - } -#endif - return rc; -} - -/* -** The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. The behavior -** is undefined if the mutex is not currently entered or -** is not currently allocated. SQLite will never do either. -*/ -static void winMutexLeave(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif - assert( p ); -#ifdef SQLITE_DEBUG - assert( p->nRef>0 ); - assert( p->owner==tid ); - p->nRef--; - if( p->nRef==0 ) p->owner = 0; - assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); -#endif - assert( winMutex_isInit==1 ); - LeaveCriticalSection(&p->mutex); -#ifdef SQLITE_DEBUG - if( p->trace ){ - OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n", - tid, p, p->trace, p->nRef)); - } -#endif -} - -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ - static const sqlite3_mutex_methods sMutex = { - winMutexInit, - winMutexEnd, - winMutexAlloc, - winMutexFree, - winMutexEnter, - winMutexTry, - winMutexLeave, -#ifdef SQLITE_DEBUG - winMutexHeld, - winMutexNotheld -#else - 0, - 0 -#endif - }; - return &sMutex; -} - -#endif /* SQLITE_MUTEX_W32 */ - -/************** End of mutex_w32.c *******************************************/ -/************** Begin file malloc.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** Memory allocation functions used throughout sqlite. -*/ -/* #include "sqliteInt.h" */ -/* #include */ - -/* -** Attempt to release up to n bytes of non-essential memory currently -** held by SQLite. An example of non-essential memory is memory used to -** cache database pages that are not currently in use. -*/ -SQLITE_API int sqlite3_release_memory(int n){ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - return sqlite3PcacheReleaseMemory(n); -#else - /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine - ** is a no-op returning zero if SQLite is not compiled with - ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ - UNUSED_PARAMETER(n); - return 0; -#endif -} - -/* -** An instance of the following object records the location of -** each unused scratch buffer. -*/ -typedef struct ScratchFreeslot { - struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ -} ScratchFreeslot; - -/* -** State information local to the memory allocation subsystem. -*/ -static SQLITE_WSD struct Mem0Global { - sqlite3_mutex *mutex; /* Mutex to serialize access */ - sqlite3_int64 alarmThreshold; /* The soft heap limit */ - - /* - ** Pointers to the end of sqlite3GlobalConfig.pScratch memory - ** (so that a range test can be used to determine if an allocation - ** being freed came from pScratch) and a pointer to the list of - ** unused scratch allocations. - */ - void *pScratchEnd; - ScratchFreeslot *pScratchFree; - u32 nScratchFree; - - /* - ** True if heap is nearly "full" where "full" is defined by the - ** sqlite3_soft_heap_limit() setting. - */ - int nearlyFull; -} mem0 = { 0, 0, 0, 0, 0, 0 }; - -#define mem0 GLOBAL(struct Mem0Global, mem0) - -/* -** Return the memory allocator mutex. sqlite3_status() needs it. -*/ -SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ - return mem0.mutex; -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Deprecated external interface. It used to set an alarm callback -** that was invoked when memory usage grew too large. Now it is a -** no-op. -*/ -SQLITE_API int sqlite3_memory_alarm( - void(*xCallback)(void *pArg, sqlite3_int64 used,int N), - void *pArg, - sqlite3_int64 iThreshold -){ - (void)xCallback; - (void)pArg; - (void)iThreshold; - return SQLITE_OK; -} -#endif - -/* -** Set the soft heap-size limit for the library. Passing a zero or -** negative value indicates no limit. -*/ -SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ - sqlite3_int64 priorLimit; - sqlite3_int64 excess; - sqlite3_int64 nUsed; -#ifndef SQLITE_OMIT_AUTOINIT - int rc = sqlite3_initialize(); - if( rc ) return -1; -#endif - sqlite3_mutex_enter(mem0.mutex); - priorLimit = mem0.alarmThreshold; - if( n<0 ){ - sqlite3_mutex_leave(mem0.mutex); - return priorLimit; - } - mem0.alarmThreshold = n; - nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); - mem0.nearlyFull = (n>0 && n<=nUsed); - sqlite3_mutex_leave(mem0.mutex); - excess = sqlite3_memory_used() - n; - if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); - return priorLimit; -} -SQLITE_API void sqlite3_soft_heap_limit(int n){ - if( n<0 ) n = 0; - sqlite3_soft_heap_limit64(n); -} - -/* -** Initialize the memory allocation subsystem. -*/ -SQLITE_PRIVATE int sqlite3MallocInit(void){ - int rc; - if( sqlite3GlobalConfig.m.xMalloc==0 ){ - sqlite3MemSetDefault(); - } - memset(&mem0, 0, sizeof(mem0)); - mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 - && sqlite3GlobalConfig.nScratch>0 ){ - int i, n, sz; - ScratchFreeslot *pSlot; - sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); - sqlite3GlobalConfig.szScratch = sz; - pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; - n = sqlite3GlobalConfig.nScratch; - mem0.pScratchFree = pSlot; - mem0.nScratchFree = n; - for(i=0; ipNext = (ScratchFreeslot*)(sz+(char*)pSlot); - pSlot = pSlot->pNext; - } - pSlot->pNext = 0; - mem0.pScratchEnd = (void*)&pSlot[1]; - }else{ - mem0.pScratchEnd = 0; - sqlite3GlobalConfig.pScratch = 0; - sqlite3GlobalConfig.szScratch = 0; - sqlite3GlobalConfig.nScratch = 0; - } - if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 - || sqlite3GlobalConfig.nPage<=0 ){ - sqlite3GlobalConfig.pPage = 0; - sqlite3GlobalConfig.szPage = 0; - } - rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); - if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0)); - return rc; -} - -/* -** Return true if the heap is currently under memory pressure - in other -** words if the amount of heap used is close to the limit set by -** sqlite3_soft_heap_limit(). -*/ -SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){ - return mem0.nearlyFull; -} - -/* -** Deinitialize the memory allocation subsystem. -*/ -SQLITE_PRIVATE void sqlite3MallocEnd(void){ - if( sqlite3GlobalConfig.m.xShutdown ){ - sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData); - } - memset(&mem0, 0, sizeof(mem0)); -} - -/* -** Return the amount of memory currently checked out. -*/ -SQLITE_API sqlite3_int64 sqlite3_memory_used(void){ - sqlite3_int64 res, mx; - sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0); - return res; -} - -/* -** Return the maximum amount of memory that has ever been -** checked out since either the beginning of this process -** or since the most recent reset. -*/ -SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ - sqlite3_int64 res, mx; - sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag); - return mx; -} - -/* -** Trigger the alarm -*/ -static void sqlite3MallocAlarm(int nByte){ - if( mem0.alarmThreshold<=0 ) return; - sqlite3_mutex_leave(mem0.mutex); - sqlite3_release_memory(nByte); - sqlite3_mutex_enter(mem0.mutex); -} - -/* -** Do a memory allocation with statistics and alarms. Assume the -** lock is already held. -*/ -static int mallocWithAlarm(int n, void **pp){ - int nFull; - void *p; - assert( sqlite3_mutex_held(mem0.mutex) ); - nFull = sqlite3GlobalConfig.m.xRoundup(n); - sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); - if( mem0.alarmThreshold>0 ){ - sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); - if( nUsed >= mem0.alarmThreshold - nFull ){ - mem0.nearlyFull = 1; - sqlite3MallocAlarm(nFull); - }else{ - mem0.nearlyFull = 0; - } - } - p = sqlite3GlobalConfig.m.xMalloc(nFull); -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - if( p==0 && mem0.alarmThreshold>0 ){ - sqlite3MallocAlarm(nFull); - p = sqlite3GlobalConfig.m.xMalloc(nFull); - } -#endif - if( p ){ - nFull = sqlite3MallocSize(p); - sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); - sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); - } - *pp = p; - return nFull; -} - -/* -** Allocate memory. This routine is like sqlite3_malloc() except that it -** assumes the memory subsystem has already been initialized. -*/ -SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ - void *p; - if( n==0 || n>=0x7fffff00 ){ - /* A memory allocation of a number of bytes which is near the maximum - ** signed integer value might cause an integer overflow inside of the - ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving - ** 255 bytes of overhead. SQLite itself will never use anything near - ** this amount. The only way to reach the limit is with sqlite3_malloc() */ - p = 0; - }else if( sqlite3GlobalConfig.bMemstat ){ - sqlite3_mutex_enter(mem0.mutex); - mallocWithAlarm((int)n, &p); - sqlite3_mutex_leave(mem0.mutex); - }else{ - p = sqlite3GlobalConfig.m.xMalloc((int)n); - } - assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */ - return p; -} - -/* -** This version of the memory allocation is for use by the application. -** First make sure the memory subsystem is initialized, then do the -** allocation. -*/ -SQLITE_API void *sqlite3_malloc(int n){ -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return n<=0 ? 0 : sqlite3Malloc(n); -} -SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return sqlite3Malloc(n); -} - -/* -** Each thread may only have a single outstanding allocation from -** xScratchMalloc(). We verify this constraint in the single-threaded -** case by setting scratchAllocOut to 1 when an allocation -** is outstanding clearing it when the allocation is freed. -*/ -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -static int scratchAllocOut = 0; -#endif - - -/* -** Allocate memory that is to be used and released right away. -** This routine is similar to alloca() in that it is not intended -** for situations where the memory might be held long-term. This -** routine is intended to get memory to old large transient data -** structures that would not normally fit on the stack of an -** embedded processor. -*/ -SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ - void *p; - assert( n>0 ); - - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); - if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ - p = mem0.pScratchFree; - mem0.pScratchFree = mem0.pScratchFree->pNext; - mem0.nScratchFree--; - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3_mutex_leave(mem0.mutex); - p = sqlite3Malloc(n); - if( sqlite3GlobalConfig.bMemstat && p ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); - sqlite3_mutex_leave(mem0.mutex); - } - sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); - } - assert( sqlite3_mutex_notheld(mem0.mutex) ); - - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch - ** buffers per thread. - ** - ** This can only be checked in single-threaded mode. - */ - assert( scratchAllocOut==0 ); - if( p ) scratchAllocOut++; -#endif - - return p; -} -SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ - if( p ){ - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* Verify that no more than two scratch allocation per thread - ** is outstanding at one time. (This is only checked in the - ** single-threaded case since checking in the multi-threaded case - ** would be much more complicated.) */ - assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); - scratchAllocOut--; -#endif - - if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){ - /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ - ScratchFreeslot *pSlot; - pSlot = (ScratchFreeslot*)p; - sqlite3_mutex_enter(mem0.mutex); - pSlot->pNext = mem0.pScratchFree; - mem0.pScratchFree = pSlot; - mem0.nScratchFree++; - assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - /* Release memory back to the heap */ - assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - if( sqlite3GlobalConfig.bMemstat ){ - int iSize = sqlite3MallocSize(p); - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); - sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); - sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); - sqlite3GlobalConfig.m.xFree(p); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3GlobalConfig.m.xFree(p); - } - } - } -} - -/* -** TRUE if p is a lookaside memory allocation from db -*/ -#ifndef SQLITE_OMIT_LOOKASIDE -static int isLookaside(sqlite3 *db, void *p){ - return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); -} -#else -#define isLookaside(A,B) 0 -#endif - -/* -** Return the size of a memory allocation previously obtained from -** sqlite3Malloc() or sqlite3_malloc(). -*/ -SQLITE_PRIVATE int sqlite3MallocSize(void *p){ - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - return sqlite3GlobalConfig.m.xSize(p); -} -SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ - assert( p!=0 ); - if( db==0 || !isLookaside(db,p) ){ -#if SQLITE_DEBUG - if( db==0 ){ - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - }else{ - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - } -#endif - return sqlite3GlobalConfig.m.xSize(p); - }else{ - assert( sqlite3_mutex_held(db->mutex) ); - return db->lookaside.sz; - } -} -SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - return p ? sqlite3GlobalConfig.m.xSize(p) : 0; -} - -/* -** Free memory previously obtained from sqlite3Malloc(). -*/ -SQLITE_API void sqlite3_free(void *p){ - if( p==0 ) return; /* IMP: R-49053-54554 */ - assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - if( sqlite3GlobalConfig.bMemstat ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); - sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); - sqlite3GlobalConfig.m.xFree(p); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3GlobalConfig.m.xFree(p); - } -} - -/* -** Add the size of memory allocation "p" to the count in -** *db->pnBytesFreed. -*/ -static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ - *db->pnBytesFreed += sqlite3DbMallocSize(db,p); -} - -/* -** Free memory that might be associated with a particular database -** connection. -*/ -SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ - assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( p==0 ) return; - if( db ){ - if( db->pnBytesFreed ){ - measureAllocationSize(db, p); - return; - } - if( isLookaside(db, p) ){ - LookasideSlot *pBuf = (LookasideSlot*)p; -#if SQLITE_DEBUG - /* Trash all content in the buffer being freed */ - memset(p, 0xaa, db->lookaside.sz); -#endif - pBuf->pNext = db->lookaside.pFree; - db->lookaside.pFree = pBuf; - db->lookaside.nOut--; - return; - } - } - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - sqlite3_free(p); -} - -/* -** Change the size of an existing memory allocation -*/ -SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ - int nOld, nNew, nDiff; - void *pNew; - assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); - assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); - if( pOld==0 ){ - return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ - } - if( nBytes==0 ){ - sqlite3_free(pOld); /* IMP: R-26507-47431 */ - return 0; - } - if( nBytes>=0x7fffff00 ){ - /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ - return 0; - } - nOld = sqlite3MallocSize(pOld); - /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second - ** argument to xRealloc is always a value returned by a prior call to - ** xRoundup. */ - nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); - if( nOld==nNew ){ - pNew = pOld; - }else if( sqlite3GlobalConfig.bMemstat ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); - nDiff = nNew - nOld; - if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= - mem0.alarmThreshold-nDiff ){ - sqlite3MallocAlarm(nDiff); - } - pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); - if( pNew==0 && mem0.alarmThreshold>0 ){ - sqlite3MallocAlarm((int)nBytes); - pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); - } - if( pNew ){ - nNew = sqlite3MallocSize(pNew); - sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); - } - sqlite3_mutex_leave(mem0.mutex); - }else{ - pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); - } - assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */ - return pNew; -} - -/* -** The public interface to sqlite3Realloc. Make sure that the memory -** subsystem is initialized prior to invoking sqliteRealloc. -*/ -SQLITE_API void *sqlite3_realloc(void *pOld, int n){ -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - if( n<0 ) n = 0; /* IMP: R-26507-47431 */ - return sqlite3Realloc(pOld, n); -} -SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return sqlite3Realloc(pOld, n); -} - - -/* -** Allocate and zero memory. -*/ -SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){ - void *p = sqlite3Malloc(n); - if( p ){ - memset(p, 0, (size_t)n); - } - return p; -} - -/* -** Allocate and zero memory. If the allocation fails, make -** the mallocFailed flag in the connection pointer. -*/ -SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ - void *p; - testcase( db==0 ); - p = sqlite3DbMallocRaw(db, n); - if( p ) memset(p, 0, (size_t)n); - return p; -} - - -/* Finish the work of sqlite3DbMallocRawNN for the unusual and -** slower case when the allocation cannot be fulfilled using lookaside. -*/ -static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ - void *p; - assert( db!=0 ); - p = sqlite3Malloc(n); - if( !p ) sqlite3OomFault(db); - sqlite3MemdebugSetType(p, - (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); - return p; -} - -/* -** Allocate memory, either lookaside (if possible) or heap. -** If the allocation fails, set the mallocFailed flag in -** the connection pointer. -** -** If db!=0 and db->mallocFailed is true (indicating a prior malloc -** failure on the same database connection) then always return 0. -** Hence for a particular database connection, once malloc starts -** failing, it fails consistently until mallocFailed is reset. -** This is an important assumption. There are many places in the -** code that do things like this: -** -** int *a = (int*)sqlite3DbMallocRaw(db, 100); -** int *b = (int*)sqlite3DbMallocRaw(db, 200); -** if( b ) a[10] = 9; -** -** In other words, if a subsequent malloc (ex: "b") worked, it is assumed -** that all prior mallocs (ex: "a") worked too. -** -** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is -** not a NULL pointer. -*/ -SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ - void *p; - if( db ) return sqlite3DbMallocRawNN(db, n); - p = sqlite3Malloc(n); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - return p; -} -SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ -#ifndef SQLITE_OMIT_LOOKASIDE - LookasideSlot *pBuf; - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( db->pnBytesFreed==0 ); - if( db->lookaside.bDisable==0 ){ - assert( db->mallocFailed==0 ); - if( n>db->lookaside.sz ){ - db->lookaside.anStat[1]++; - }else if( (pBuf = db->lookaside.pFree)==0 ){ - db->lookaside.anStat[2]++; - }else{ - db->lookaside.pFree = pBuf->pNext; - db->lookaside.nOut++; - db->lookaside.anStat[0]++; - if( db->lookaside.nOut>db->lookaside.mxOut ){ - db->lookaside.mxOut = db->lookaside.nOut; - } - return (void*)pBuf; - } - }else if( db->mallocFailed ){ - return 0; - } -#else - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( db->pnBytesFreed==0 ); - if( db->mallocFailed ){ - return 0; - } -#endif - return dbMallocRawFinish(db, n); -} - -/* Forward declaration */ -static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); - -/* -** Resize the block of memory pointed to by p to n bytes. If the -** resize fails, set the mallocFailed flag in the connection object. -*/ -SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ - assert( db!=0 ); - if( p==0 ) return sqlite3DbMallocRawNN(db, n); - assert( sqlite3_mutex_held(db->mutex) ); - if( isLookaside(db,p) && n<=db->lookaside.sz ) return p; - return dbReallocFinish(db, p, n); -} -static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ - void *pNew = 0; - assert( db!=0 ); - assert( p!=0 ); - if( db->mallocFailed==0 ){ - if( isLookaside(db, p) ){ - pNew = sqlite3DbMallocRawNN(db, n); - if( pNew ){ - memcpy(pNew, p, db->lookaside.sz); - sqlite3DbFree(db, p); - } - }else{ - assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - pNew = sqlite3_realloc64(p, n); - if( !pNew ){ - sqlite3OomFault(db); - } - sqlite3MemdebugSetType(pNew, - (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); - } - } - return pNew; -} - -/* -** Attempt to reallocate p. If the reallocation fails, then free p -** and set the mallocFailed flag in the database connection. -*/ -SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ - void *pNew; - pNew = sqlite3DbRealloc(db, p, n); - if( !pNew ){ - sqlite3DbFree(db, p); - } - return pNew; -} - -/* -** Make a copy of a string in memory obtained from sqliteMalloc(). These -** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This -** is because when memory debugging is turned on, these two functions are -** called via macros that record the current file and line number in the -** ThreadData structure. -*/ -SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){ - char *zNew; - size_t n; - if( z==0 ){ - return 0; - } - n = sqlite3Strlen30(z) + 1; - assert( (n&0x7fffffff)==n ); - zNew = sqlite3DbMallocRaw(db, (int)n); - if( zNew ){ - memcpy(zNew, z, n); - } - return zNew; -} -SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ - char *zNew; - assert( db!=0 ); - if( z==0 ){ - return 0; - } - assert( (n&0x7fffffff)==n ); - zNew = sqlite3DbMallocRawNN(db, n+1); - if( zNew ){ - memcpy(zNew, z, (size_t)n); - zNew[n] = 0; - } - return zNew; -} - -/* -** Free any prior content in *pz and replace it with a copy of zNew. -*/ -SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ - sqlite3DbFree(db, *pz); - *pz = sqlite3DbStrDup(db, zNew); -} - -/* -** Call this routine to record the fact that an OOM (out-of-memory) error -** has happened. This routine will set db->mallocFailed, and also -** temporarily disable the lookaside memory allocator and interrupt -** any running VDBEs. -*/ -SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ - if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ - db->mallocFailed = 1; - if( db->nVdbeExec>0 ){ - db->u1.isInterrupted = 1; - } - db->lookaside.bDisable++; - } -} - -/* -** This routine reactivates the memory allocator and clears the -** db->mallocFailed flag as necessary. -** -** The memory allocator is not restarted if there are running -** VDBEs. -*/ -SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ - if( db->mallocFailed && db->nVdbeExec==0 ){ - db->mallocFailed = 0; - db->u1.isInterrupted = 0; - assert( db->lookaside.bDisable>0 ); - db->lookaside.bDisable--; - } -} - -/* -** Take actions at the end of an API call to indicate an OOM error -*/ -static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ - sqlite3OomClear(db); - sqlite3Error(db, SQLITE_NOMEM); - return SQLITE_NOMEM_BKPT; -} - -/* -** This function must be called before exiting any API function (i.e. -** returning control to the user) that has called sqlite3_malloc or -** sqlite3_realloc. -** -** The returned value is normally a copy of the second argument to this -** function. However, if a malloc() failure has occurred since the previous -** invocation SQLITE_NOMEM is returned instead. -** -** If an OOM as occurred, then the connection error-code (the value -** returned by sqlite3_errcode()) is set to SQLITE_NOMEM. -*/ -SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ - /* If the db handle must hold the connection handle mutex here. - ** Otherwise the read (and possible write) of db->mallocFailed - ** is unsafe, as is the call to sqlite3Error(). - */ - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ - return apiOomError(db); - } - return rc & db->errMask; -} - -/************** End of malloc.c **********************************************/ -/************** Begin file printf.c ******************************************/ -/* -** The "printf" code that follows dates from the 1980's. It is in -** the public domain. -** -************************************************************************** -** -** This file contains code for a set of "printf"-like routines. These -** routines format strings much like the printf() from the standard C -** library, though the implementation here has enhancements to support -** SQLite. -*/ -/* #include "sqliteInt.h" */ - -/* -** Conversion types fall into various categories as defined by the -** following enumeration. -*/ -#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */ -#define etFLOAT 1 /* Floating point. %f */ -#define etEXP 2 /* Exponentional notation. %e and %E */ -#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ -#define etSIZE 4 /* Return number of characters processed so far. %n */ -#define etSTRING 5 /* Strings. %s */ -#define etDYNSTRING 6 /* Dynamically allocated strings. %z */ -#define etPERCENT 7 /* Percent symbol. %% */ -#define etCHARX 8 /* Characters. %c */ -/* The rest are extensions, not normally found in printf() */ -#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */ -#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', - NULL pointers replaced by SQL NULL. %Q */ -#define etTOKEN 11 /* a pointer to a Token structure */ -#define etSRCLIST 12 /* a pointer to a SrcList */ -#define etPOINTER 13 /* The %p conversion */ -#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ -#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ - -#define etINVALID 16 /* Any unrecognized conversion type */ - - -/* -** An "etByte" is an 8-bit unsigned value. -*/ -typedef unsigned char etByte; - -/* -** Each builtin conversion character (ex: the 'd' in "%d") is described -** by an instance of the following structure -*/ -typedef struct et_info { /* Information about each format field */ - char fmttype; /* The format field code letter */ - etByte base; /* The base for radix conversion */ - etByte flags; /* One or more of FLAG_ constants below */ - etByte type; /* Conversion paradigm */ - etByte charset; /* Offset into aDigits[] of the digits string */ - etByte prefix; /* Offset into aPrefix[] of the prefix string */ -} et_info; - -/* -** Allowed values for et_info.flags -*/ -#define FLAG_SIGNED 1 /* True if the value to convert is signed */ -#define FLAG_INTERN 2 /* True if for internal use only */ -#define FLAG_STRING 4 /* Allow infinity precision */ - - -/* -** The following table is searched linearly, so it is good to put the -** most frequently used conversion types first. -*/ -static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; -static const char aPrefix[] = "-x0\000X0"; -static const et_info fmtinfo[] = { - { 'd', 10, 1, etRADIX, 0, 0 }, - { 's', 0, 4, etSTRING, 0, 0 }, - { 'g', 0, 1, etGENERIC, 30, 0 }, - { 'z', 0, 4, etDYNSTRING, 0, 0 }, - { 'q', 0, 4, etSQLESCAPE, 0, 0 }, - { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, - { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, - { 'c', 0, 0, etCHARX, 0, 0 }, - { 'o', 8, 0, etRADIX, 0, 2 }, - { 'u', 10, 0, etRADIX, 0, 0 }, - { 'x', 16, 0, etRADIX, 16, 1 }, - { 'X', 16, 0, etRADIX, 0, 4 }, -#ifndef SQLITE_OMIT_FLOATING_POINT - { 'f', 0, 1, etFLOAT, 0, 0 }, - { 'e', 0, 1, etEXP, 30, 0 }, - { 'E', 0, 1, etEXP, 14, 0 }, - { 'G', 0, 1, etGENERIC, 14, 0 }, -#endif - { 'i', 10, 1, etRADIX, 0, 0 }, - { 'n', 0, 0, etSIZE, 0, 0 }, - { '%', 0, 0, etPERCENT, 0, 0 }, - { 'p', 16, 0, etPOINTER, 0, 1 }, - -/* All the rest have the FLAG_INTERN bit set and are thus for internal -** use only */ - { 'T', 0, 2, etTOKEN, 0, 0 }, - { 'S', 0, 2, etSRCLIST, 0, 0 }, - { 'r', 10, 3, etORDINAL, 0, 0 }, -}; - -/* -** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point -** conversions will work. -*/ -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** "*val" is a double such that 0.1 <= *val < 10.0 -** Return the ascii code for the leading digit of *val, then -** multiply "*val" by 10.0 to renormalize. -** -** Example: -** input: *val = 3.14159 -** output: *val = 1.4159 function return = '3' -** -** The counter *cnt is incremented each time. After counter exceeds -** 16 (the number of significant digits in a 64-bit float) '0' is -** always returned. -*/ -static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ - int digit; - LONGDOUBLE_TYPE d; - if( (*cnt)<=0 ) return '0'; - (*cnt)--; - digit = (int)*val; - d = digit; - digit += '0'; - *val = (*val - d)*10.0; - return (char)digit; -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - -/* -** Set the StrAccum object to an error mode. -*/ -static void setStrAccumError(StrAccum *p, u8 eError){ - assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG ); - p->accError = eError; - p->nAlloc = 0; -} - -/* -** Extra argument values from a PrintfArguments object -*/ -static sqlite3_int64 getIntArg(PrintfArguments *p){ - if( p->nArg<=p->nUsed ) return 0; - return sqlite3_value_int64(p->apArg[p->nUsed++]); -} -static double getDoubleArg(PrintfArguments *p){ - if( p->nArg<=p->nUsed ) return 0.0; - return sqlite3_value_double(p->apArg[p->nUsed++]); -} -static char *getTextArg(PrintfArguments *p){ - if( p->nArg<=p->nUsed ) return 0; - return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); -} - - -/* -** On machines with a small stack size, you can redefine the -** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. -*/ -#ifndef SQLITE_PRINT_BUF_SIZE -# define SQLITE_PRINT_BUF_SIZE 70 -#endif -#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ - -/* -** Render a string given by "fmt" into the StrAccum object. -*/ -SQLITE_PRIVATE void sqlite3VXPrintf( - StrAccum *pAccum, /* Accumulate results here */ - const char *fmt, /* Format string */ - va_list ap /* arguments */ -){ - int c; /* Next character in the format string */ - char *bufpt; /* Pointer to the conversion buffer */ - int precision; /* Precision of the current field */ - int length; /* Length of the field */ - int idx; /* A general purpose loop counter */ - int width; /* Width of the current field */ - etByte flag_leftjustify; /* True if "-" flag is present */ - etByte flag_plussign; /* True if "+" flag is present */ - etByte flag_blanksign; /* True if " " flag is present */ - etByte flag_alternateform; /* True if "#" flag is present */ - etByte flag_altform2; /* True if "!" flag is present */ - etByte flag_zeropad; /* True if field width constant starts with zero */ - etByte flag_long; /* True if "l" flag is present */ - etByte flag_longlong; /* True if the "ll" flag is present */ - etByte done; /* Loop termination flag */ - etByte xtype = etINVALID; /* Conversion paradigm */ - u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ - u8 useIntern; /* Ok to use internal conversions (ex: %T) */ - char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ - sqlite_uint64 longvalue; /* Value for integer types */ - LONGDOUBLE_TYPE realvalue; /* Value for real types */ - const et_info *infop; /* Pointer to the appropriate info structure */ - char *zOut; /* Rendering buffer */ - int nOut; /* Size of the rendering buffer */ - char *zExtra = 0; /* Malloced memory used by some conversion */ -#ifndef SQLITE_OMIT_FLOATING_POINT - int exp, e2; /* exponent of real numbers */ - int nsd; /* Number of significant digits returned */ - double rounder; /* Used for rounding floating point values */ - etByte flag_dp; /* True if decimal point should be shown */ - etByte flag_rtz; /* True if trailing zeros should be removed */ -#endif - PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ - char buf[etBUFSIZE]; /* Conversion buffer */ - - bufpt = 0; - if( pAccum->printfFlags ){ - if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ - pArgList = va_arg(ap, PrintfArguments*); - } - useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL; - }else{ - bArgList = useIntern = 0; - } - for(; (c=(*fmt))!=0; ++fmt){ - if( c!='%' ){ - bufpt = (char *)fmt; -#if HAVE_STRCHRNUL - fmt = strchrnul(fmt, '%'); -#else - do{ fmt++; }while( *fmt && *fmt != '%' ); -#endif - sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); - if( *fmt==0 ) break; - } - if( (c=(*++fmt))==0 ){ - sqlite3StrAccumAppend(pAccum, "%", 1); - break; - } - /* Find out what flags are present */ - flag_leftjustify = flag_plussign = flag_blanksign = - flag_alternateform = flag_altform2 = flag_zeropad = 0; - done = 0; - do{ - switch( c ){ - case '-': flag_leftjustify = 1; break; - case '+': flag_plussign = 1; break; - case ' ': flag_blanksign = 1; break; - case '#': flag_alternateform = 1; break; - case '!': flag_altform2 = 1; break; - case '0': flag_zeropad = 1; break; - default: done = 1; break; - } - }while( !done && (c=(*++fmt))!=0 ); - /* Get the field width */ - if( c=='*' ){ - if( bArgList ){ - width = (int)getIntArg(pArgList); - }else{ - width = va_arg(ap,int); - } - if( width<0 ){ - flag_leftjustify = 1; - width = width >= -2147483647 ? -width : 0; - } - c = *++fmt; - }else{ - unsigned wx = 0; - while( c>='0' && c<='9' ){ - wx = wx*10 + c - '0'; - c = *++fmt; - } - testcase( wx>0x7fffffff ); - width = wx & 0x7fffffff; - } - assert( width>=0 ); -#ifdef SQLITE_PRINTF_PRECISION_LIMIT - if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ - width = SQLITE_PRINTF_PRECISION_LIMIT; - } -#endif - - /* Get the precision */ - if( c=='.' ){ - c = *++fmt; - if( c=='*' ){ - if( bArgList ){ - precision = (int)getIntArg(pArgList); - }else{ - precision = va_arg(ap,int); - } - c = *++fmt; - if( precision<0 ){ - precision = precision >= -2147483647 ? -precision : -1; - } - }else{ - unsigned px = 0; - while( c>='0' && c<='9' ){ - px = px*10 + c - '0'; - c = *++fmt; - } - testcase( px>0x7fffffff ); - precision = px & 0x7fffffff; - } - }else{ - precision = -1; - } - assert( precision>=(-1) ); -#ifdef SQLITE_PRINTF_PRECISION_LIMIT - if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ - precision = SQLITE_PRINTF_PRECISION_LIMIT; - } -#endif - - - /* Get the conversion type modifier */ - if( c=='l' ){ - flag_long = 1; - c = *++fmt; - if( c=='l' ){ - flag_longlong = 1; - c = *++fmt; - }else{ - flag_longlong = 0; - } - }else{ - flag_long = flag_longlong = 0; - } - /* Fetch the info entry for the field */ - infop = &fmtinfo[0]; - xtype = etINVALID; - for(idx=0; idxflags & FLAG_INTERN)==0 ){ - xtype = infop->type; - }else{ - return; - } - break; - } - } - - /* - ** At this point, variables are initialized as follows: - ** - ** flag_alternateform TRUE if a '#' is present. - ** flag_altform2 TRUE if a '!' is present. - ** flag_plussign TRUE if a '+' is present. - ** flag_leftjustify TRUE if a '-' is present or if the - ** field width was negative. - ** flag_zeropad TRUE if the width began with 0. - ** flag_long TRUE if the letter 'l' (ell) prefixed - ** the conversion character. - ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed - ** the conversion character. - ** flag_blanksign TRUE if a ' ' is present. - ** width The specified field width. This is - ** always non-negative. Zero is the default. - ** precision The specified precision. The default - ** is -1. - ** xtype The class of the conversion. - ** infop Pointer to the appropriate info struct. - */ - switch( xtype ){ - case etPOINTER: - flag_longlong = sizeof(char*)==sizeof(i64); - flag_long = sizeof(char*)==sizeof(long int); - /* Fall through into the next case */ - case etORDINAL: - case etRADIX: - if( infop->flags & FLAG_SIGNED ){ - i64 v; - if( bArgList ){ - v = getIntArg(pArgList); - }else if( flag_longlong ){ - v = va_arg(ap,i64); - }else if( flag_long ){ - v = va_arg(ap,long int); - }else{ - v = va_arg(ap,int); - } - if( v<0 ){ - if( v==SMALLEST_INT64 ){ - longvalue = ((u64)1)<<63; - }else{ - longvalue = -v; - } - prefix = '-'; - }else{ - longvalue = v; - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; - } - }else{ - if( bArgList ){ - longvalue = (u64)getIntArg(pArgList); - }else if( flag_longlong ){ - longvalue = va_arg(ap,u64); - }else if( flag_long ){ - longvalue = va_arg(ap,unsigned long int); - }else{ - longvalue = va_arg(ap,unsigned int); - } - prefix = 0; - } - if( longvalue==0 ) flag_alternateform = 0; - if( flag_zeropad && precision=4 || (longvalue/10)%10==1 ){ - x = 0; - } - *(--bufpt) = zOrd[x*2+1]; - *(--bufpt) = zOrd[x*2]; - } - { - const char *cset = &aDigits[infop->charset]; - u8 base = infop->base; - do{ /* Convert to ascii */ - *(--bufpt) = cset[longvalue%base]; - longvalue = longvalue/base; - }while( longvalue>0 ); - } - length = (int)(&zOut[nOut-1]-bufpt); - for(idx=precision-length; idx>0; idx--){ - *(--bufpt) = '0'; /* Zero pad */ - } - if( prefix ) *(--bufpt) = prefix; /* Add sign */ - if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ - const char *pre; - char x; - pre = &aPrefix[infop->prefix]; - for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; - } - length = (int)(&zOut[nOut-1]-bufpt); - break; - case etFLOAT: - case etEXP: - case etGENERIC: - if( bArgList ){ - realvalue = getDoubleArg(pArgList); - }else{ - realvalue = va_arg(ap,double); - } -#ifdef SQLITE_OMIT_FLOATING_POINT - length = 0; -#else - if( precision<0 ) precision = 6; /* Set default precision */ - if( realvalue<0.0 ){ - realvalue = -realvalue; - prefix = '-'; - }else{ - if( flag_plussign ) prefix = '+'; - else if( flag_blanksign ) prefix = ' '; - else prefix = 0; - } - if( xtype==etGENERIC && precision>0 ) precision--; - testcase( precision>0xfff ); - for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){} - if( xtype==etFLOAT ) realvalue += rounder; - /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ - exp = 0; - if( sqlite3IsNaN((double)realvalue) ){ - bufpt = "NaN"; - length = 3; - break; - } - if( realvalue>0.0 ){ - LONGDOUBLE_TYPE scale = 1.0; - while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} - while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; } - while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } - realvalue /= scale; - while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } - while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } - if( exp>350 ){ - bufpt = buf; - buf[0] = prefix; - memcpy(buf+(prefix!=0),"Inf",4); - length = 3+(prefix!=0); - break; - } - } - bufpt = buf; - /* - ** If the field type is etGENERIC, then convert to either etEXP - ** or etFLOAT, as appropriate. - */ - if( xtype!=etFLOAT ){ - realvalue += rounder; - if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } - } - if( xtype==etGENERIC ){ - flag_rtz = !flag_alternateform; - if( exp<-4 || exp>precision ){ - xtype = etEXP; - }else{ - precision = precision - exp; - xtype = etFLOAT; - } - }else{ - flag_rtz = flag_altform2; - } - if( xtype==etEXP ){ - e2 = 0; - }else{ - e2 = exp; - } - if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){ - bufpt = zExtra - = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); - if( bufpt==0 ){ - setStrAccumError(pAccum, STRACCUM_NOMEM); - return; - } - } - zOut = bufpt; - nsd = 16 + flag_altform2*10; - flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; - /* The sign in front of the number */ - if( prefix ){ - *(bufpt++) = prefix; - } - /* Digits prior to the decimal point */ - if( e2<0 ){ - *(bufpt++) = '0'; - }else{ - for(; e2>=0; e2--){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } - } - /* The decimal point */ - if( flag_dp ){ - *(bufpt++) = '.'; - } - /* "0" digits after the decimal point but before the first - ** significant digit of the number */ - for(e2++; e2<0; precision--, e2++){ - assert( precision>0 ); - *(bufpt++) = '0'; - } - /* Significant digits after the decimal point */ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } - /* Remove trailing zeros and the "." if no digits follow the "." */ - if( flag_rtz && flag_dp ){ - while( bufpt[-1]=='0' ) *(--bufpt) = 0; - assert( bufpt>zOut ); - if( bufpt[-1]=='.' ){ - if( flag_altform2 ){ - *(bufpt++) = '0'; - }else{ - *(--bufpt) = 0; - } - } - } - /* Add the "eNNN" suffix */ - if( xtype==etEXP ){ - *(bufpt++) = aDigits[infop->charset]; - if( exp<0 ){ - *(bufpt++) = '-'; exp = -exp; - }else{ - *(bufpt++) = '+'; - } - if( exp>=100 ){ - *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ - exp %= 100; - } - *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ - *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ - } - *bufpt = 0; - - /* The converted number is in buf[] and zero terminated. Output it. - ** Note that the number is in the usual order, not reversed as with - ** integer conversions. */ - length = (int)(bufpt-zOut); - bufpt = zOut; - - /* Special case: Add leading zeros if the flag_zeropad flag is - ** set and we are not left justified */ - if( flag_zeropad && !flag_leftjustify && length < width){ - int i; - int nPad = width - length; - for(i=width; i>=nPad; i--){ - bufpt[i] = bufpt[i-nPad]; - } - i = prefix!=0; - while( nPad-- ) bufpt[i++] = '0'; - length = width; - } -#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ - break; - case etSIZE: - if( !bArgList ){ - *(va_arg(ap,int*)) = pAccum->nChar; - } - length = width = 0; - break; - case etPERCENT: - buf[0] = '%'; - bufpt = buf; - length = 1; - break; - case etCHARX: - if( bArgList ){ - bufpt = getTextArg(pArgList); - c = bufpt ? bufpt[0] : 0; - }else{ - c = va_arg(ap,int); - } - if( precision>1 ){ - width -= precision-1; - if( width>1 && !flag_leftjustify ){ - sqlite3AppendChar(pAccum, width-1, ' '); - width = 0; - } - sqlite3AppendChar(pAccum, precision-1, c); - } - length = 1; - buf[0] = c; - bufpt = buf; - break; - case etSTRING: - case etDYNSTRING: - if( bArgList ){ - bufpt = getTextArg(pArgList); - xtype = etSTRING; - }else{ - bufpt = va_arg(ap,char*); - } - if( bufpt==0 ){ - bufpt = ""; - }else if( xtype==etDYNSTRING ){ - zExtra = bufpt; - } - if( precision>=0 ){ - for(length=0; lengthetBUFSIZE ){ - bufpt = zExtra = sqlite3Malloc( n ); - if( bufpt==0 ){ - setStrAccumError(pAccum, STRACCUM_NOMEM); - return; - } - }else{ - bufpt = buf; - } - j = 0; - if( needQuote ) bufpt[j++] = q; - k = i; - for(i=0; i=0 && precisionn ){ - sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); - } - length = width = 0; - break; - } - case etSRCLIST: { - SrcList *pSrc = va_arg(ap, SrcList*); - int k = va_arg(ap, int); - struct SrcList_item *pItem = &pSrc->a[k]; - assert( bArgList==0 ); - assert( k>=0 && knSrc ); - if( pItem->zDatabase ){ - sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); - sqlite3StrAccumAppend(pAccum, ".", 1); - } - sqlite3StrAccumAppendAll(pAccum, pItem->zName); - length = width = 0; - break; - } - default: { - assert( xtype==etINVALID ); - return; - } - }/* End switch over the format type */ - /* - ** The text of the conversion is pointed to by "bufpt" and is - ** "length" characters long. The field width is "width". Do - ** the output. - */ - width -= length; - if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); - sqlite3StrAccumAppend(pAccum, bufpt, length); - if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' '); - - if( zExtra ){ - sqlite3DbFree(pAccum->db, zExtra); - zExtra = 0; - } - }/* End for loop over the format string */ -} /* End of function */ - -/* -** Enlarge the memory allocation on a StrAccum object so that it is -** able to accept at least N more bytes of text. -** -** Return the number of bytes of text that StrAccum is able to accept -** after the attempted enlargement. The value returned might be zero. -*/ -static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ - char *zNew; - assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ - if( p->accError ){ - testcase(p->accError==STRACCUM_TOOBIG); - testcase(p->accError==STRACCUM_NOMEM); - return 0; - } - if( p->mxAlloc==0 ){ - N = p->nAlloc - p->nChar - 1; - setStrAccumError(p, STRACCUM_TOOBIG); - return N; - }else{ - char *zOld = isMalloced(p) ? p->zText : 0; - i64 szNew = p->nChar; - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); - szNew += N + 1; - if( szNew+p->nChar<=p->mxAlloc ){ - /* Force exponential buffer size growth as long as it does not overflow, - ** to avoid having to call this routine too often */ - szNew += p->nChar; - } - if( szNew > p->mxAlloc ){ - sqlite3StrAccumReset(p); - setStrAccumError(p, STRACCUM_TOOBIG); - return 0; - }else{ - p->nAlloc = (int)szNew; - } - if( p->db ){ - zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); - }else{ - zNew = sqlite3_realloc64(zOld, p->nAlloc); - } - if( zNew ){ - assert( p->zText!=0 || p->nChar==0 ); - if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); - p->zText = zNew; - p->nAlloc = sqlite3DbMallocSize(p->db, zNew); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; - }else{ - sqlite3StrAccumReset(p); - setStrAccumError(p, STRACCUM_NOMEM); - return 0; - } - } - return N; -} - -/* -** Append N copies of character c to the given string buffer. -*/ -SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){ - testcase( p->nChar + (i64)N > 0x7fffffff ); - if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ - return; - } - assert( (p->zText==p->zBase)==!isMalloced(p) ); - while( (N--)>0 ) p->zText[p->nChar++] = c; -} - -/* -** The StrAccum "p" is not large enough to accept N new bytes of z[]. -** So enlarge if first, then do the append. -** -** This is a helper routine to sqlite3StrAccumAppend() that does special-case -** work (enlarging the buffer) using tail recursion, so that the -** sqlite3StrAccumAppend() routine can use fast calling semantics. -*/ -static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ - N = sqlite3StrAccumEnlarge(p, N); - if( N>0 ){ - memcpy(&p->zText[p->nChar], z, N); - p->nChar += N; - } - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); -} - -/* -** Append N bytes of text from z to the StrAccum object. Increase the -** size of the memory allocation for StrAccum if necessary. -*/ -SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ - assert( z!=0 || N==0 ); - assert( p->zText!=0 || p->nChar==0 || p->accError ); - assert( N>=0 ); - assert( p->accError==0 || p->nAlloc==0 ); - if( p->nChar+N >= p->nAlloc ){ - enlargeAndAppend(p,z,N); - }else{ - assert( p->zText ); - p->nChar += N; - memcpy(&p->zText[p->nChar-N], z, N); - } -} - -/* -** Append the complete text of zero-terminated string z[] to the p string. -*/ -SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ - sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); -} - - -/* -** Finish off a string by making sure it is zero-terminated. -** Return a pointer to the resulting string. Return a NULL -** pointer if any kind of error was encountered. -*/ -SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ - if( p->zText ){ - assert( (p->zText==p->zBase)==!isMalloced(p) ); - p->zText[p->nChar] = 0; - if( p->mxAlloc>0 && !isMalloced(p) ){ - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); - if( p->zText ){ - memcpy(p->zText, p->zBase, p->nChar+1); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; - }else{ - setStrAccumError(p, STRACCUM_NOMEM); - } - } - } - return p->zText; -} - -/* -** Reset an StrAccum string. Reclaim all malloced memory. -*/ -SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){ - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); - if( isMalloced(p) ){ - sqlite3DbFree(p->db, p->zText); - p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; - } - p->zText = 0; -} - -/* -** Initialize a string accumulator. -** -** p: The accumulator to be initialized. -** db: Pointer to a database connection. May be NULL. Lookaside -** memory is used if not NULL. db->mallocFailed is set appropriately -** when not NULL. -** zBase: An initial buffer. May be NULL in which case the initial buffer -** is malloced. -** n: Size of zBase in bytes. If total space requirements never exceed -** n then no memory allocations ever occur. -** mx: Maximum number of bytes to accumulate. If mx==0 then no memory -** allocations will ever occur. -*/ -SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ - p->zText = p->zBase = zBase; - p->db = db; - p->nChar = 0; - p->nAlloc = n; - p->mxAlloc = mx; - p->accError = 0; - p->printfFlags = 0; -} - -/* -** Print into memory obtained from sqliteMalloc(). Use the internal -** %-conversion extensions. -*/ -SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ - char *z; - char zBase[SQLITE_PRINT_BUF_SIZE]; - StrAccum acc; - assert( db!=0 ); - sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), - db->aLimit[SQLITE_LIMIT_LENGTH]); - acc.printfFlags = SQLITE_PRINTF_INTERNAL; - sqlite3VXPrintf(&acc, zFormat, ap); - z = sqlite3StrAccumFinish(&acc); - if( acc.accError==STRACCUM_NOMEM ){ - sqlite3OomFault(db); - } - return z; -} - -/* -** Print into memory obtained from sqliteMalloc(). Use the internal -** %-conversion extensions. -*/ -SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ - va_list ap; - char *z; - va_start(ap, zFormat); - z = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - return z; -} - -/* -** Print into memory obtained from sqlite3_malloc(). Omit the internal -** %-conversion extensions. -*/ -SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ - char *z; - char zBase[SQLITE_PRINT_BUF_SIZE]; - StrAccum acc; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( zFormat==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); - sqlite3VXPrintf(&acc, zFormat, ap); - z = sqlite3StrAccumFinish(&acc); - return z; -} - -/* -** Print into memory obtained from sqlite3_malloc()(). Omit the internal -** %-conversion extensions. -*/ -SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ - va_list ap; - char *z; -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - return z; -} - -/* -** sqlite3_snprintf() works like snprintf() except that it ignores the -** current locale settings. This is important for SQLite because we -** are not able to use a "," as the decimal point in place of "." as -** specified by some locales. -** -** Oops: The first two arguments of sqlite3_snprintf() are backwards -** from the snprintf() standard. Unfortunately, it is too late to change -** this without breaking compatibility, so we just have to live with the -** mistake. -** -** sqlite3_vsnprintf() is the varargs version. -*/ -SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ - StrAccum acc; - if( n<=0 ) return zBuf; -#ifdef SQLITE_ENABLE_API_ARMOR - if( zBuf==0 || zFormat==0 ) { - (void)SQLITE_MISUSE_BKPT; - if( zBuf ) zBuf[0] = 0; - return zBuf; - } -#endif - sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); - sqlite3VXPrintf(&acc, zFormat, ap); - return sqlite3StrAccumFinish(&acc); -} -SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - char *z; - va_list ap; - va_start(ap,zFormat); - z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); - va_end(ap); - return z; -} - -/* -** This is the routine that actually formats the sqlite3_log() message. -** We house it in a separate routine from sqlite3_log() to avoid using -** stack space on small-stack systems when logging is disabled. -** -** sqlite3_log() must render into a static buffer. It cannot dynamically -** allocate memory because it might be called while the memory allocator -** mutex is held. -** -** sqlite3VXPrintf() might ask for *temporary* memory allocations for -** certain format characters (%q) or for very large precisions or widths. -** Care must be taken that any sqlite3_log() calls that occur while the -** memory mutex is held do not use these mechanisms. -*/ -static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ - StrAccum acc; /* String accumulator */ - char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ - - sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); - sqlite3VXPrintf(&acc, zFormat, ap); - sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, - sqlite3StrAccumFinish(&acc)); -} - -/* -** Format and write a message to the log if logging is enabled. -*/ -SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ - va_list ap; /* Vararg list */ - if( sqlite3GlobalConfig.xLog ){ - va_start(ap, zFormat); - renderLogMsg(iErrCode, zFormat, ap); - va_end(ap); - } -} - -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) -/* -** A version of printf() that understands %lld. Used for debugging. -** The printf() built into some versions of windows does not understand %lld -** and segfaults if you give it a long long int. -*/ -SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ - va_list ap; - StrAccum acc; - char zBuf[500]; - sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - va_start(ap,zFormat); - sqlite3VXPrintf(&acc, zFormat, ap); - va_end(ap); - sqlite3StrAccumFinish(&acc); - fprintf(stdout,"%s", zBuf); - fflush(stdout); -} -#endif - - -/* -** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument -** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. -*/ -SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ - va_list ap; - va_start(ap,zFormat); - sqlite3VXPrintf(p, zFormat, ap); - va_end(ap); -} - -/************** End of printf.c **********************************************/ -/************** Begin file treeview.c ****************************************/ -/* -** 2015-06-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains C code to implement the TreeView debugging routines. -** These routines print a parse tree to standard output for debugging and -** analysis. -** -** The interfaces in this file is only available when compiling -** with SQLITE_DEBUG. -*/ -/* #include "sqliteInt.h" */ -#ifdef SQLITE_DEBUG - -/* -** Add a new subitem to the tree. The moreToFollow flag indicates that this -** is not the last item in the tree. -*/ -static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ - if( p==0 ){ - p = sqlite3_malloc64( sizeof(*p) ); - if( p==0 ) return 0; - memset(p, 0, sizeof(*p)); - }else{ - p->iLevel++; - } - assert( moreToFollow==0 || moreToFollow==1 ); - if( p->iLevelbLine) ) p->bLine[p->iLevel] = moreToFollow; - return p; -} - -/* -** Finished with one layer of the tree -*/ -static void sqlite3TreeViewPop(TreeView *p){ - if( p==0 ) return; - p->iLevel--; - if( p->iLevel<0 ) sqlite3_free(p); -} - -/* -** Generate a single line of output for the tree, with a prefix that contains -** all the appropriate tree lines -*/ -static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ - va_list ap; - int i; - StrAccum acc; - char zBuf[500]; - sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - if( p ){ - for(i=0; iiLevel && ibLine)-1; i++){ - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "| " : " ", 4); - } - sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); - } - va_start(ap, zFormat); - sqlite3VXPrintf(&acc, zFormat, ap); - va_end(ap); - if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); - sqlite3StrAccumFinish(&acc); - fprintf(stdout,"%s", zBuf); - fflush(stdout); -} - -/* -** Shorthand for starting a new tree item that consists of a single label -*/ -static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ - p = sqlite3TreeViewPush(p, moreFollows); - sqlite3TreeViewLine(p, "%s", zLabel); -} - -/* -** Generate a human-readable description of a WITH clause. -*/ -SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ - int i; - if( pWith==0 ) return; - if( pWith->nCte==0 ) return; - if( pWith->pOuter ){ - sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); - }else{ - sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); - } - if( pWith->nCte>0 ){ - pView = sqlite3TreeViewPush(pView, 1); - for(i=0; inCte; i++){ - StrAccum x; - char zLine[1000]; - const struct Cte *pCte = &pWith->a[i]; - sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, "%s", pCte->zName); - if( pCte->pCols && pCte->pCols->nExpr>0 ){ - char cSep = '('; - int j; - for(j=0; jpCols->nExpr; j++){ - sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); - cSep = ','; - } - sqlite3XPrintf(&x, ")"); - } - sqlite3XPrintf(&x, " AS"); - sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, inCte-1); - sqlite3TreeViewSelect(pView, pCte->pSelect, 0); - sqlite3TreeViewPop(pView); - } - sqlite3TreeViewPop(pView); - } -} - - -/* -** Generate a human-readable description of a Select object. -*/ -SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ - int n = 0; - int cnt = 0; - pView = sqlite3TreeViewPush(pView, moreToFollow); - if( p->pWith ){ - sqlite3TreeViewWith(pView, p->pWith, 1); - cnt = 1; - sqlite3TreeViewPush(pView, 1); - } - do{ - sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d", - ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), - ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags, - (int)p->nSelectRow - ); - if( cnt++ ) sqlite3TreeViewPop(pView); - if( p->pPrior ){ - n = 1000; - }else{ - n = 0; - if( p->pSrc && p->pSrc->nSrc ) n++; - if( p->pWhere ) n++; - if( p->pGroupBy ) n++; - if( p->pHaving ) n++; - if( p->pOrderBy ) n++; - if( p->pLimit ) n++; - if( p->pOffset ) n++; - } - sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); - if( p->pSrc && p->pSrc->nSrc ){ - int i; - pView = sqlite3TreeViewPush(pView, (n--)>0); - sqlite3TreeViewLine(pView, "FROM"); - for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; - StrAccum x; - char zLine[100]; - sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); - if( pItem->zDatabase ){ - sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName); - }else if( pItem->zName ){ - sqlite3XPrintf(&x, " %s", pItem->zName); - } - if( pItem->pTab ){ - sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); - } - if( pItem->zAlias ){ - sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); - } - if( pItem->fg.jointype & JT_LEFT ){ - sqlite3XPrintf(&x, " LEFT-JOIN"); - } - sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1); - if( pItem->pSelect ){ - sqlite3TreeViewSelect(pView, pItem->pSelect, 0); - } - if( pItem->fg.isTabFunc ){ - sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); - } - sqlite3TreeViewPop(pView); - } - sqlite3TreeViewPop(pView); - } - if( p->pWhere ){ - sqlite3TreeViewItem(pView, "WHERE", (n--)>0); - sqlite3TreeViewExpr(pView, p->pWhere, 0); - sqlite3TreeViewPop(pView); - } - if( p->pGroupBy ){ - sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); - } - if( p->pHaving ){ - sqlite3TreeViewItem(pView, "HAVING", (n--)>0); - sqlite3TreeViewExpr(pView, p->pHaving, 0); - sqlite3TreeViewPop(pView); - } - if( p->pOrderBy ){ - sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); - } - if( p->pLimit ){ - sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); - sqlite3TreeViewExpr(pView, p->pLimit, 0); - sqlite3TreeViewPop(pView); - } - if( p->pOffset ){ - sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); - sqlite3TreeViewExpr(pView, p->pOffset, 0); - sqlite3TreeViewPop(pView); - } - if( p->pPrior ){ - const char *zOp = "UNION"; - switch( p->op ){ - case TK_ALL: zOp = "UNION ALL"; break; - case TK_INTERSECT: zOp = "INTERSECT"; break; - case TK_EXCEPT: zOp = "EXCEPT"; break; - } - sqlite3TreeViewItem(pView, zOp, 1); - } - p = p->pPrior; - }while( p!=0 ); - sqlite3TreeViewPop(pView); -} - -/* -** Generate a human-readable explanation of an expression tree. -*/ -SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ - const char *zBinOp = 0; /* Binary operator */ - const char *zUniOp = 0; /* Unary operator */ - char zFlgs[30]; - pView = sqlite3TreeViewPush(pView, moreToFollow); - if( pExpr==0 ){ - sqlite3TreeViewLine(pView, "nil"); - sqlite3TreeViewPop(pView); - return; - } - if( pExpr->flags ){ - sqlite3_snprintf(sizeof(zFlgs),zFlgs," flags=0x%x",pExpr->flags); - }else{ - zFlgs[0] = 0; - } - switch( pExpr->op ){ - case TK_AGG_COLUMN: { - sqlite3TreeViewLine(pView, "AGG{%d:%d}%s", - pExpr->iTable, pExpr->iColumn, zFlgs); - break; - } - case TK_COLUMN: { - if( pExpr->iTable<0 ){ - /* This only happens when coding check constraints */ - sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs); - }else{ - sqlite3TreeViewLine(pView, "{%d:%d}%s", - pExpr->iTable, pExpr->iColumn, zFlgs); - } - break; - } - case TK_INTEGER: { - if( pExpr->flags & EP_IntValue ){ - sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); - }else{ - sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); - } - break; - } -#ifndef SQLITE_OMIT_FLOATING_POINT - case TK_FLOAT: { - sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); - break; - } -#endif - case TK_STRING: { - sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); - break; - } - case TK_NULL: { - sqlite3TreeViewLine(pView,"NULL"); - break; - } -#ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: { - sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); - break; - } -#endif - case TK_VARIABLE: { - sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", - pExpr->u.zToken, pExpr->iColumn); - break; - } - case TK_REGISTER: { - sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); - break; - } - case TK_ID: { - sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); - break; - } -#ifndef SQLITE_OMIT_CAST - case TK_CAST: { - /* Expressions of the form: CAST(pLeft AS token) */ - sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); - break; - } -#endif /* SQLITE_OMIT_CAST */ - case TK_LT: zBinOp = "LT"; break; - case TK_LE: zBinOp = "LE"; break; - case TK_GT: zBinOp = "GT"; break; - case TK_GE: zBinOp = "GE"; break; - case TK_NE: zBinOp = "NE"; break; - case TK_EQ: zBinOp = "EQ"; break; - case TK_IS: zBinOp = "IS"; break; - case TK_ISNOT: zBinOp = "ISNOT"; break; - case TK_AND: zBinOp = "AND"; break; - case TK_OR: zBinOp = "OR"; break; - case TK_PLUS: zBinOp = "ADD"; break; - case TK_STAR: zBinOp = "MUL"; break; - case TK_MINUS: zBinOp = "SUB"; break; - case TK_REM: zBinOp = "REM"; break; - case TK_BITAND: zBinOp = "BITAND"; break; - case TK_BITOR: zBinOp = "BITOR"; break; - case TK_SLASH: zBinOp = "DIV"; break; - case TK_LSHIFT: zBinOp = "LSHIFT"; break; - case TK_RSHIFT: zBinOp = "RSHIFT"; break; - case TK_CONCAT: zBinOp = "CONCAT"; break; - case TK_DOT: zBinOp = "DOT"; break; - - case TK_UMINUS: zUniOp = "UMINUS"; break; - case TK_UPLUS: zUniOp = "UPLUS"; break; - case TK_BITNOT: zUniOp = "BITNOT"; break; - case TK_NOT: zUniOp = "NOT"; break; - case TK_ISNULL: zUniOp = "ISNULL"; break; - case TK_NOTNULL: zUniOp = "NOTNULL"; break; - - case TK_SPAN: { - sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); - break; - } - - case TK_COLLATE: { - sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); - break; - } - - case TK_AGG_FUNCTION: - case TK_FUNCTION: { - ExprList *pFarg; /* List of function arguments */ - if( ExprHasProperty(pExpr, EP_TokenOnly) ){ - pFarg = 0; - }else{ - pFarg = pExpr->x.pList; - } - if( pExpr->op==TK_AGG_FUNCTION ){ - sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", - pExpr->op2, pExpr->u.zToken); - }else{ - sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); - } - if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, 0, 0); - } - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_EXISTS: { - sqlite3TreeViewLine(pView, "EXISTS-expr"); - sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); - break; - } - case TK_SELECT: { - sqlite3TreeViewLine(pView, "SELECT-expr"); - sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); - break; - } - case TK_IN: { - sqlite3TreeViewLine(pView, "IN"); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); - }else{ - sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); - } - break; - } -#endif /* SQLITE_OMIT_SUBQUERY */ - - /* - ** x BETWEEN y AND z - ** - ** This is equivalent to - ** - ** x>=y AND x<=z - ** - ** X is stored in pExpr->pLeft. - ** Y is stored in pExpr->pList->a[0].pExpr. - ** Z is stored in pExpr->pList->a[1].pExpr. - */ - case TK_BETWEEN: { - Expr *pX = pExpr->pLeft; - Expr *pY = pExpr->x.pList->a[0].pExpr; - Expr *pZ = pExpr->x.pList->a[1].pExpr; - sqlite3TreeViewLine(pView, "BETWEEN"); - sqlite3TreeViewExpr(pView, pX, 1); - sqlite3TreeViewExpr(pView, pY, 1); - sqlite3TreeViewExpr(pView, pZ, 0); - break; - } - case TK_TRIGGER: { - /* If the opcode is TK_TRIGGER, then the expression is a reference - ** to a column in the new.* or old.* pseudo-tables available to - ** trigger programs. In this case Expr.iTable is set to 1 for the - ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn - ** is set to the column of the pseudo-table to read, or to -1 to - ** read the rowid field. - */ - sqlite3TreeViewLine(pView, "%s(%d)", - pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); - break; - } - case TK_CASE: { - sqlite3TreeViewLine(pView, "CASE"); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); - break; - } -#ifndef SQLITE_OMIT_TRIGGER - case TK_RAISE: { - const char *zType = "unk"; - switch( pExpr->affinity ){ - case OE_Rollback: zType = "rollback"; break; - case OE_Abort: zType = "abort"; break; - case OE_Fail: zType = "fail"; break; - case OE_Ignore: zType = "ignore"; break; - } - sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); - break; - } -#endif - case TK_MATCH: { - sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", - pExpr->iTable, pExpr->iColumn, zFlgs); - sqlite3TreeViewExpr(pView, pExpr->pRight, 0); - break; - } - case TK_VECTOR: { - sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR"); - break; - } - case TK_SELECT_COLUMN: { - sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); - sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); - break; - } - default: { - sqlite3TreeViewLine(pView, "op=%d", pExpr->op); - break; - } - } - if( zBinOp ){ - sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - sqlite3TreeViewExpr(pView, pExpr->pRight, 0); - }else if( zUniOp ){ - sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); - sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); - } - sqlite3TreeViewPop(pView); -} - - -/* -** Generate a human-readable explanation of an expression list. -*/ -SQLITE_PRIVATE void sqlite3TreeViewBareExprList( - TreeView *pView, - const ExprList *pList, - const char *zLabel -){ - if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; - if( pList==0 ){ - sqlite3TreeViewLine(pView, "%s (empty)", zLabel); - }else{ - int i; - sqlite3TreeViewLine(pView, "%s", zLabel); - for(i=0; inExpr; i++){ - int j = pList->a[i].u.x.iOrderByCol; - if( j ){ - sqlite3TreeViewPush(pView, 0); - sqlite3TreeViewLine(pView, "iOrderByCol=%d", j); - } - sqlite3TreeViewExpr(pView, pList->a[i].pExpr, inExpr-1); - if( j ) sqlite3TreeViewPop(pView); - } - } -} -SQLITE_PRIVATE void sqlite3TreeViewExprList( - TreeView *pView, - const ExprList *pList, - u8 moreToFollow, - const char *zLabel -){ - pView = sqlite3TreeViewPush(pView, moreToFollow); - sqlite3TreeViewBareExprList(pView, pList, zLabel); - sqlite3TreeViewPop(pView); -} - -#endif /* SQLITE_DEBUG */ - -/************** End of treeview.c ********************************************/ -/************** Begin file random.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code to implement a pseudo-random number -** generator (PRNG) for SQLite. -** -** Random numbers are used by some of the database backends in order -** to generate random integer keys for tables or random filenames. -*/ -/* #include "sqliteInt.h" */ - - -/* All threads share a single random number generator. -** This structure is the current state of the generator. -*/ -static SQLITE_WSD struct sqlite3PrngType { - unsigned char isInit; /* True if initialized */ - unsigned char i, j; /* State variables */ - unsigned char s[256]; /* State variables */ -} sqlite3Prng; - -/* -** Return N random bytes. -*/ -SQLITE_API void sqlite3_randomness(int N, void *pBuf){ - unsigned char t; - unsigned char *zBuf = pBuf; - - /* The "wsdPrng" macro will resolve to the pseudo-random number generator - ** state vector. If writable static data is unsupported on the target, - ** we have to locate the state vector at run-time. In the more common - ** case where writable static data is supported, wsdPrng can refer directly - ** to the "sqlite3Prng" state vector declared above. - */ -#ifdef SQLITE_OMIT_WSD - struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); -# define wsdPrng p[0] -#else -# define wsdPrng sqlite3Prng -#endif - -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex; -#endif - -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return; -#endif - -#if SQLITE_THREADSAFE - mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); -#endif - - sqlite3_mutex_enter(mutex); - if( N<=0 || pBuf==0 ){ - wsdPrng.isInit = 0; - sqlite3_mutex_leave(mutex); - return; - } - - /* Initialize the state of the random number generator once, - ** the first time this routine is called. The seed value does - ** not need to contain a lot of randomness since we are not - ** trying to do secure encryption or anything like that... - ** - ** Nothing in this file or anywhere else in SQLite does any kind of - ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random - ** number generator) not as an encryption device. - */ - if( !wsdPrng.isInit ){ - int i; - char k[256]; - wsdPrng.j = 0; - wsdPrng.i = 0; - sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); - for(i=0; i<256; i++){ - wsdPrng.s[i] = (u8)i; - } - for(i=0; i<256; i++){ - wsdPrng.j += wsdPrng.s[i] + k[i]; - t = wsdPrng.s[wsdPrng.j]; - wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; - wsdPrng.s[i] = t; - } - wsdPrng.isInit = 1; - } - - assert( N>0 ); - do{ - wsdPrng.i++; - t = wsdPrng.s[wsdPrng.i]; - wsdPrng.j += t; - wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; - wsdPrng.s[wsdPrng.j] = t; - t += wsdPrng.s[wsdPrng.i]; - *(zBuf++) = wsdPrng.s[t]; - }while( --N ); - sqlite3_mutex_leave(mutex); -} - -#ifndef SQLITE_OMIT_BUILTIN_TEST -/* -** For testing purposes, we sometimes want to preserve the state of -** PRNG and restore the PRNG to its saved state at a later time, or -** to reset the PRNG to its initial state. These routines accomplish -** those tasks. -** -** The sqlite3_test_control() interface calls these routines to -** control the PRNG. -*/ -static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; -SQLITE_PRIVATE void sqlite3PrngSaveState(void){ - memcpy( - &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), - &GLOBAL(struct sqlite3PrngType, sqlite3Prng), - sizeof(sqlite3Prng) - ); -} -SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ - memcpy( - &GLOBAL(struct sqlite3PrngType, sqlite3Prng), - &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), - sizeof(sqlite3Prng) - ); -} -#endif /* SQLITE_OMIT_BUILTIN_TEST */ - -/************** End of random.c **********************************************/ -/************** Begin file threads.c *****************************************/ -/* -** 2012 July 21 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file presents a simple cross-platform threading interface for -** use internally by SQLite. -** -** A "thread" can be created using sqlite3ThreadCreate(). This thread -** runs independently of its creator until it is joined using -** sqlite3ThreadJoin(), at which point it terminates. -** -** Threads do not have to be real. It could be that the work of the -** "thread" is done by the main thread at either the sqlite3ThreadCreate() -** or sqlite3ThreadJoin() call. This is, in fact, what happens in -** single threaded systems. Nothing in SQLite requires multiple threads. -** This interface exists so that applications that want to take advantage -** of multiple cores can do so, while also allowing applications to stay -** single-threaded if desired. -*/ -/* #include "sqliteInt.h" */ -#if SQLITE_OS_WIN -/* # include "os_win.h" */ -#endif - -#if SQLITE_MAX_WORKER_THREADS>0 - -/********************************* Unix Pthreads ****************************/ -#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 - -#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ -/* #include */ - -/* A running thread */ -struct SQLiteThread { - pthread_t tid; /* Thread ID */ - int done; /* Set to true when thread finishes */ - void *pOut; /* Result returned by the thread */ - void *(*xTask)(void*); /* The thread routine */ - void *pIn; /* Argument to the thread */ -}; - -/* Create a new thread */ -SQLITE_PRIVATE int sqlite3ThreadCreate( - SQLiteThread **ppThread, /* OUT: Write the thread object here */ - void *(*xTask)(void*), /* Routine to run in a separate thread */ - void *pIn /* Argument passed into xTask() */ -){ - SQLiteThread *p; - int rc; - - assert( ppThread!=0 ); - assert( xTask!=0 ); - /* This routine is never used in single-threaded mode */ - assert( sqlite3GlobalConfig.bCoreMutex!=0 ); - - *ppThread = 0; - p = sqlite3Malloc(sizeof(*p)); - if( p==0 ) return SQLITE_NOMEM_BKPT; - memset(p, 0, sizeof(*p)); - p->xTask = xTask; - p->pIn = pIn; - /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a - ** function that returns SQLITE_ERROR when passed the argument 200, that - ** forces worker threads to run sequentially and deterministically - ** for testing purposes. */ - if( sqlite3FaultSim(200) ){ - rc = 1; - }else{ - rc = pthread_create(&p->tid, 0, xTask, pIn); - } - if( rc ){ - p->done = 1; - p->pOut = xTask(pIn); - } - *ppThread = p; - return SQLITE_OK; -} - -/* Get the results of the thread */ -SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ - int rc; - - assert( ppOut!=0 ); - if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; - if( p->done ){ - *ppOut = p->pOut; - rc = SQLITE_OK; - }else{ - rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; - } - sqlite3_free(p); - return rc; -} - -#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ -/******************************** End Unix Pthreads *************************/ - - -/********************************* Win32 Threads ****************************/ -#if SQLITE_OS_WIN_THREADS - -#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ -#include - -/* A running thread */ -struct SQLiteThread { - void *tid; /* The thread handle */ - unsigned id; /* The thread identifier */ - void *(*xTask)(void*); /* The routine to run as a thread */ - void *pIn; /* Argument to xTask */ - void *pResult; /* Result of xTask */ -}; - -/* Thread procedure Win32 compatibility shim */ -static unsigned __stdcall sqlite3ThreadProc( - void *pArg /* IN: Pointer to the SQLiteThread structure */ -){ - SQLiteThread *p = (SQLiteThread *)pArg; - - assert( p!=0 ); -#if 0 - /* - ** This assert appears to trigger spuriously on certain - ** versions of Windows, possibly due to _beginthreadex() - ** and/or CreateThread() not fully setting their thread - ** ID parameter before starting the thread. - */ - assert( p->id==GetCurrentThreadId() ); -#endif - assert( p->xTask!=0 ); - p->pResult = p->xTask(p->pIn); - - _endthreadex(0); - return 0; /* NOT REACHED */ -} - -/* Create a new thread */ -SQLITE_PRIVATE int sqlite3ThreadCreate( - SQLiteThread **ppThread, /* OUT: Write the thread object here */ - void *(*xTask)(void*), /* Routine to run in a separate thread */ - void *pIn /* Argument passed into xTask() */ -){ - SQLiteThread *p; - - assert( ppThread!=0 ); - assert( xTask!=0 ); - *ppThread = 0; - p = sqlite3Malloc(sizeof(*p)); - if( p==0 ) return SQLITE_NOMEM_BKPT; - /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a - ** function that returns SQLITE_ERROR when passed the argument 200, that - ** forces worker threads to run sequentially and deterministically - ** (via the sqlite3FaultSim() term of the conditional) for testing - ** purposes. */ - if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){ - memset(p, 0, sizeof(*p)); - }else{ - p->xTask = xTask; - p->pIn = pIn; - p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); - if( p->tid==0 ){ - memset(p, 0, sizeof(*p)); - } - } - if( p->xTask==0 ){ - p->id = GetCurrentThreadId(); - p->pResult = xTask(pIn); - } - *ppThread = p; - return SQLITE_OK; -} - -SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ - -/* Get the results of the thread */ -SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ - DWORD rc; - BOOL bRc; - - assert( ppOut!=0 ); - if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; - if( p->xTask==0 ){ - /* assert( p->id==GetCurrentThreadId() ); */ - rc = WAIT_OBJECT_0; - assert( p->tid==0 ); - }else{ - assert( p->id!=0 && p->id!=GetCurrentThreadId() ); - rc = sqlite3Win32Wait((HANDLE)p->tid); - assert( rc!=WAIT_IO_COMPLETION ); - bRc = CloseHandle((HANDLE)p->tid); - assert( bRc ); - } - if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; - sqlite3_free(p); - return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; -} - -#endif /* SQLITE_OS_WIN_THREADS */ -/******************************** End Win32 Threads *************************/ - - -/********************************* Single-Threaded **************************/ -#ifndef SQLITE_THREADS_IMPLEMENTED -/* -** This implementation does not actually create a new thread. It does the -** work of the thread in the main thread, when either the thread is created -** or when it is joined -*/ - -/* A running thread */ -struct SQLiteThread { - void *(*xTask)(void*); /* The routine to run as a thread */ - void *pIn; /* Argument to xTask */ - void *pResult; /* Result of xTask */ -}; - -/* Create a new thread */ -SQLITE_PRIVATE int sqlite3ThreadCreate( - SQLiteThread **ppThread, /* OUT: Write the thread object here */ - void *(*xTask)(void*), /* Routine to run in a separate thread */ - void *pIn /* Argument passed into xTask() */ -){ - SQLiteThread *p; - - assert( ppThread!=0 ); - assert( xTask!=0 ); - *ppThread = 0; - p = sqlite3Malloc(sizeof(*p)); - if( p==0 ) return SQLITE_NOMEM_BKPT; - if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ - p->xTask = xTask; - p->pIn = pIn; - }else{ - p->xTask = 0; - p->pResult = xTask(pIn); - } - *ppThread = p; - return SQLITE_OK; -} - -/* Get the results of the thread */ -SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ - - assert( ppOut!=0 ); - if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; - if( p->xTask ){ - *ppOut = p->xTask(p->pIn); - }else{ - *ppOut = p->pResult; - } - sqlite3_free(p); - -#if defined(SQLITE_TEST) - { - void *pTstAlloc = sqlite3Malloc(10); - if (!pTstAlloc) return SQLITE_NOMEM_BKPT; - sqlite3_free(pTstAlloc); - } -#endif - - return SQLITE_OK; -} - -#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */ -/****************************** End Single-Threaded *************************/ -#endif /* SQLITE_MAX_WORKER_THREADS>0 */ - -/************** End of threads.c *********************************************/ -/************** Begin file utf.c *********************************************/ -/* -** 2004 April 13 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains routines used to translate between UTF-8, -** UTF-16, UTF-16BE, and UTF-16LE. -** -** Notes on UTF-8: -** -** Byte-0 Byte-1 Byte-2 Byte-3 Value -** 0xxxxxxx 00000000 00000000 0xxxxxxx -** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx -** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx -** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx -** -** -** Notes on UTF-16: (with wwww+1==uuuuu) -** -** Word-0 Word-1 Value -** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx -** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx -** -** -** BOM or Byte Order Mark: -** 0xff 0xfe little-endian utf-16 follows -** 0xfe 0xff big-endian utf-16 follows -** -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include "vdbeInt.h" */ - -#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0 -/* -** The following constant value is used by the SQLITE_BIGENDIAN and -** SQLITE_LITTLEENDIAN macros. -*/ -SQLITE_PRIVATE const int sqlite3one = 1; -#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */ - -/* -** This lookup table is used to help decode the first byte of -** a multi-byte UTF8 character. -*/ -static const unsigned char sqlite3Utf8Trans1[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, -}; - - -#define WRITE_UTF8(zOut, c) { \ - if( c<0x00080 ){ \ - *zOut++ = (u8)(c&0xFF); \ - } \ - else if( c<0x00800 ){ \ - *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ - else if( c<0x10000 ){ \ - *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - }else{ \ - *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ - *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ -} - -#define WRITE_UTF16LE(zOut, c) { \ - if( c<=0xFFFF ){ \ - *zOut++ = (u8)(c&0x00FF); \ - *zOut++ = (u8)((c>>8)&0x00FF); \ - }else{ \ - *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ - *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ - *zOut++ = (u8)(c&0x00FF); \ - *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ - } \ -} - -#define WRITE_UTF16BE(zOut, c) { \ - if( c<=0xFFFF ){ \ - *zOut++ = (u8)((c>>8)&0x00FF); \ - *zOut++ = (u8)(c&0x00FF); \ - }else{ \ - *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ - *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ - *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ - *zOut++ = (u8)(c&0x00FF); \ - } \ -} - -#define READ_UTF16LE(zIn, TERM, c){ \ - c = (*zIn++); \ - c += ((*zIn++)<<8); \ - if( c>=0xD800 && c<0xE000 && TERM ){ \ - int c2 = (*zIn++); \ - c2 += ((*zIn++)<<8); \ - c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - } \ -} - -#define READ_UTF16BE(zIn, TERM, c){ \ - c = ((*zIn++)<<8); \ - c += (*zIn++); \ - if( c>=0xD800 && c<0xE000 && TERM ){ \ - int c2 = ((*zIn++)<<8); \ - c2 += (*zIn++); \ - c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - } \ -} - -/* -** Translate a single UTF-8 character. Return the unicode value. -** -** During translation, assume that the byte that zTerm points -** is a 0x00. -** -** Write a pointer to the next unread byte back into *pzNext. -** -** Notes On Invalid UTF-8: -** -** * This routine never allows a 7-bit character (0x00 through 0x7f) to -** be encoded as a multi-byte character. Any multi-byte character that -** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd. -** -** * This routine never allows a UTF16 surrogate value to be encoded. -** If a multi-byte character attempts to encode a value between -** 0xd800 and 0xe000 then it is rendered as 0xfffd. -** -** * Bytes in the range of 0x80 through 0xbf which occur as the first -** byte of a character are interpreted as single-byte characters -** and rendered as themselves even though they are technically -** invalid characters. -** -** * This routine accepts over-length UTF8 encodings -** for unicode values 0x80 and greater. It does not change over-length -** encodings to 0xfffd as some systems recommend. -*/ -#define READ_UTF8(zIn, zTerm, c) \ - c = *(zIn++); \ - if( c>=0xc0 ){ \ - c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ - c = (c<<6) + (0x3f & *(zIn++)); \ - } \ - if( c<0x80 \ - || (c&0xFFFFF800)==0xD800 \ - || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ - } -SQLITE_PRIVATE u32 sqlite3Utf8Read( - const unsigned char **pz /* Pointer to string from which to read char */ -){ - unsigned int c; - - /* Same as READ_UTF8() above but without the zTerm parameter. - ** For this routine, we assume the UTF8 string is always zero-terminated. - */ - c = *((*pz)++); - if( c>=0xc0 ){ - c = sqlite3Utf8Trans1[c-0xc0]; - while( (*(*pz) & 0xc0)==0x80 ){ - c = (c<<6) + (0x3f & *((*pz)++)); - } - if( c<0x80 - || (c&0xFFFFF800)==0xD800 - || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } - } - return c; -} - - - - -/* -** If the TRANSLATE_TRACE macro is defined, the value of each Mem is -** printed on stderr on the way into and out of sqlite3VdbeMemTranslate(). -*/ -/* #define TRANSLATE_TRACE 1 */ - -#ifndef SQLITE_OMIT_UTF16 -/* -** This routine transforms the internal text encoding used by pMem to -** desiredEnc. It is an error if the string is already of the desired -** encoding, or if *pMem does not contain a string value. -*/ -SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ - int len; /* Maximum length of output string in bytes */ - unsigned char *zOut; /* Output buffer */ - unsigned char *zIn; /* Input iterator */ - unsigned char *zTerm; /* End of input */ - unsigned char *z; /* Output iterator */ - unsigned int c; - - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( pMem->flags&MEM_Str ); - assert( pMem->enc!=desiredEnc ); - assert( pMem->enc!=0 ); - assert( pMem->n>=0 ); - -#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) - { - char zBuf[100]; - sqlite3VdbeMemPrettyPrint(pMem, zBuf); - fprintf(stderr, "INPUT: %s\n", zBuf); - } -#endif - - /* If the translation is between UTF-16 little and big endian, then - ** all that is required is to swap the byte order. This case is handled - ** differently from the others. - */ - if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ - u8 temp; - int rc; - rc = sqlite3VdbeMemMakeWriteable(pMem); - if( rc!=SQLITE_OK ){ - assert( rc==SQLITE_NOMEM ); - return SQLITE_NOMEM_BKPT; - } - zIn = (u8*)pMem->z; - zTerm = &zIn[pMem->n&~1]; - while( zInenc = desiredEnc; - goto translate_out; - } - - /* Set len to the maximum number of bytes required in the output buffer. */ - if( desiredEnc==SQLITE_UTF8 ){ - /* When converting from UTF-16, the maximum growth results from - ** translating a 2-byte character to a 4-byte UTF-8 character. - ** A single byte is required for the output string - ** nul-terminator. - */ - pMem->n &= ~1; - len = pMem->n * 2 + 1; - }else{ - /* When converting from UTF-8 to UTF-16 the maximum growth is caused - ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 - ** character. Two bytes are required in the output buffer for the - ** nul-terminator. - */ - len = pMem->n * 2 + 2; - } - - /* Set zIn to point at the start of the input buffer and zTerm to point 1 - ** byte past the end. - ** - ** Variable zOut is set to point at the output buffer, space obtained - ** from sqlite3_malloc(). - */ - zIn = (u8*)pMem->z; - zTerm = &zIn[pMem->n]; - zOut = sqlite3DbMallocRaw(pMem->db, len); - if( !zOut ){ - return SQLITE_NOMEM_BKPT; - } - z = zOut; - - if( pMem->enc==SQLITE_UTF8 ){ - if( desiredEnc==SQLITE_UTF16LE ){ - /* UTF-8 -> UTF-16 Little-endian */ - while( zIn UTF-16 Big-endian */ - while( zInn = (int)(z - zOut); - *z++ = 0; - }else{ - assert( desiredEnc==SQLITE_UTF8 ); - if( pMem->enc==SQLITE_UTF16LE ){ - /* UTF-16 Little-endian -> UTF-8 */ - while( zIn UTF-8 */ - while( zInn = (int)(z - zOut); - } - *z = 0; - assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); - - c = pMem->flags; - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype)); - pMem->enc = desiredEnc; - pMem->z = (char*)zOut; - pMem->zMalloc = pMem->z; - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); - -translate_out: -#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) - { - char zBuf[100]; - sqlite3VdbeMemPrettyPrint(pMem, zBuf); - fprintf(stderr, "OUTPUT: %s\n", zBuf); - } -#endif - return SQLITE_OK; -} - -/* -** This routine checks for a byte-order mark at the beginning of the -** UTF-16 string stored in *pMem. If one is present, it is removed and -** the encoding of the Mem adjusted. This routine does not do any -** byte-swapping, it just sets Mem.enc appropriately. -** -** The allocation (static, dynamic etc.) and encoding of the Mem may be -** changed by this function. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ - int rc = SQLITE_OK; - u8 bom = 0; - - assert( pMem->n>=0 ); - if( pMem->n>1 ){ - u8 b1 = *(u8 *)pMem->z; - u8 b2 = *(((u8 *)pMem->z) + 1); - if( b1==0xFE && b2==0xFF ){ - bom = SQLITE_UTF16BE; - } - if( b1==0xFF && b2==0xFE ){ - bom = SQLITE_UTF16LE; - } - } - - if( bom ){ - rc = sqlite3VdbeMemMakeWriteable(pMem); - if( rc==SQLITE_OK ){ - pMem->n -= 2; - memmove(pMem->z, &pMem->z[2], pMem->n); - pMem->z[pMem->n] = '\0'; - pMem->z[pMem->n+1] = '\0'; - pMem->flags |= MEM_Term; - pMem->enc = bom; - } - } - return rc; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, -** return the number of unicode characters in pZ up to (but not including) -** the first 0x00 byte. If nByte is not less than zero, return the -** number of unicode characters in the first nByte of pZ (or up to -** the first 0x00, whichever comes first). -*/ -SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ - int r = 0; - const u8 *z = (const u8*)zIn; - const u8 *zTerm; - if( nByte>=0 ){ - zTerm = &z[nByte]; - }else{ - zTerm = (const u8*)(-1); - } - assert( z<=zTerm ); - while( *z!=0 && zmallocFailed ){ - sqlite3VdbeMemRelease(&m); - m.z = 0; - } - assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); - assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); - assert( m.z || db->mallocFailed ); - return m.z; -} - -/* -** zIn is a UTF-16 encoded unicode string at least nChar characters long. -** Return the number of bytes in the first nChar unicode characters -** in pZ. nChar must be non-negative. -*/ -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ - int c; - unsigned char const *z = zIn; - int n = 0; - - if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){ - while( n0 && n<=4 ); - z[0] = 0; - z = zBuf; - c = sqlite3Utf8Read((const u8**)&z); - t = i; - if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; - if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; - assert( c==t ); - assert( (z-zBuf)==n ); - } - for(i=0; i<0x00110000; i++){ - if( i>=0xD800 && i<0xE000 ) continue; - z = zBuf; - WRITE_UTF16LE(z, i); - n = (int)(z-zBuf); - assert( n>0 && n<=4 ); - z[0] = 0; - z = zBuf; - READ_UTF16LE(z, 1, c); - assert( c==i ); - assert( (z-zBuf)==n ); - } - for(i=0; i<0x00110000; i++){ - if( i>=0xD800 && i<0xE000 ) continue; - z = zBuf; - WRITE_UTF16BE(z, i); - n = (int)(z-zBuf); - assert( n>0 && n<=4 ); - z[0] = 0; - z = zBuf; - READ_UTF16BE(z, 1, c); - assert( c==i ); - assert( (z-zBuf)==n ); - } -} -#endif /* SQLITE_TEST */ -#endif /* SQLITE_OMIT_UTF16 */ - -/************** End of utf.c *************************************************/ -/************** Begin file util.c ********************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Utility functions used throughout sqlite. -** -** This file contains functions for allocating memory, comparing -** strings, and stuff like that. -** -*/ -/* #include "sqliteInt.h" */ -/* #include */ -#if HAVE_ISNAN || SQLITE_HAVE_ISNAN -# include -#endif - -/* -** Routine needed to support the testcase() macro. -*/ -#ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void sqlite3Coverage(int x){ - static unsigned dummy = 0; - dummy += (unsigned)x; -} -#endif - -/* -** Give a callback to the test harness that can be used to simulate faults -** in places where it is difficult or expensive to do so purely by means -** of inputs. -** -** The intent of the integer argument is to let the fault simulator know -** which of multiple sqlite3FaultSim() calls has been hit. -** -** Return whatever integer value the test callback returns, or return -** SQLITE_OK if no test callback is installed. -*/ -#ifndef SQLITE_OMIT_BUILTIN_TEST -SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ - int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; - return xCallback ? xCallback(iTest) : SQLITE_OK; -} -#endif - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** Return true if the floating point value is Not a Number (NaN). -** -** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. -** Otherwise, we have our own implementation that works on most systems. -*/ -SQLITE_PRIVATE int sqlite3IsNaN(double x){ - int rc; /* The value return */ -#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN - /* - ** Systems that support the isnan() library function should probably - ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have - ** found that many systems do not have a working isnan() function so - ** this implementation is provided as an alternative. - ** - ** This NaN test sometimes fails if compiled on GCC with -ffast-math. - ** On the other hand, the use of -ffast-math comes with the following - ** warning: - ** - ** This option [-ffast-math] should never be turned on by any - ** -O option since it can result in incorrect output for programs - ** which depend on an exact implementation of IEEE or ISO - ** rules/specifications for math functions. - ** - ** Under MSVC, this NaN test may fail if compiled with a floating- - ** point precision mode other than /fp:precise. From the MSDN - ** documentation: - ** - ** The compiler [with /fp:precise] will properly handle comparisons - ** involving NaN. For example, x != x evaluates to true if x is NaN - ** ... - */ -#ifdef __FAST_MATH__ -# error SQLite will not work correctly with the -ffast-math option of GCC. -#endif - volatile double y = x; - volatile double z = y; - rc = (y!=z); -#else /* if HAVE_ISNAN */ - rc = isnan(x); -#endif /* HAVE_ISNAN */ - testcase( rc ); - return rc; -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - -/* -** Compute a string length that is limited to what can be stored in -** lower 30 bits of a 32-bit signed integer. -** -** The value returned will never be negative. Nor will it ever be greater -** than the actual length of the string. For very long strings (greater -** than 1GiB) the value returned might be less than the true string length. -*/ -SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ - if( z==0 ) return 0; - return 0x3fffffff & (int)strlen(z); -} - -/* -** Return the declared type of a column. Or return zDflt if the column -** has no declared type. -** -** The column type is an extra string stored after the zero-terminator on -** the column name if and only if the COLFLAG_HASTYPE flag is set. -*/ -SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){ - if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; - return pCol->zName + strlen(pCol->zName) + 1; -} - -/* -** Helper function for sqlite3Error() - called rarely. Broken out into -** a separate routine to avoid unnecessary register saves on entry to -** sqlite3Error(). -*/ -static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ - if( db->pErr ) sqlite3ValueSetNull(db->pErr); - sqlite3SystemError(db, err_code); -} - -/* -** Set the current error code to err_code and clear any prior error message. -** Also set iSysErrno (by calling sqlite3System) if the err_code indicates -** that would be appropriate. -*/ -SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ - assert( db!=0 ); - db->errCode = err_code; - if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); -} - -/* -** Load the sqlite3.iSysErrno field if that is an appropriate thing -** to do based on the SQLite error code in rc. -*/ -SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ - if( rc==SQLITE_IOERR_NOMEM ) return; - rc &= 0xff; - if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ - db->iSysErrno = sqlite3OsGetLastError(db->pVfs); - } -} - -/* -** Set the most recent error code and error string for the sqlite -** handle "db". The error code is set to "err_code". -** -** If it is not NULL, string zFormat specifies the format of the -** error string in the style of the printf functions: The following -** format characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** zFormat and any string tokens that follow it are assumed to be -** encoded in UTF-8. -** -** To clear the most recent error for sqlite handle "db", sqlite3Error -** should be called with err_code set to SQLITE_OK and zFormat set -** to NULL. -*/ -SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ - assert( db!=0 ); - db->errCode = err_code; - sqlite3SystemError(db, err_code); - if( zFormat==0 ){ - sqlite3Error(db, err_code); - }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ - char *z; - va_list ap; - va_start(ap, zFormat); - z = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); - } -} - -/* -** Add an error message to pParse->zErrMsg and increment pParse->nErr. -** The following formatting characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** This function should be used to report any error that occurs while -** compiling an SQL statement (i.e. within sqlite3_prepare()). The -** last thing the sqlite3_prepare() function does is copy the error -** stored by this function into the database handle using sqlite3Error(). -** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used -** during statement execution (sqlite3_step() etc.). -*/ -SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ - char *zMsg; - va_list ap; - sqlite3 *db = pParse->db; - va_start(ap, zFormat); - zMsg = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - if( db->suppressErr ){ - sqlite3DbFree(db, zMsg); - }else{ - pParse->nErr++; - sqlite3DbFree(db, pParse->zErrMsg); - pParse->zErrMsg = zMsg; - pParse->rc = SQLITE_ERROR; - } -} - -/* -** Convert an SQL-style quoted string into a normal string by removing -** the quote characters. The conversion is done in-place. If the -** input does not begin with a quote character, then this routine -** is a no-op. -** -** The input string must be zero-terminated. A new zero-terminator -** is added to the dequoted string. -** -** The return value is -1 if no dequoting occurs or the length of the -** dequoted string, exclusive of the zero terminator, if dequoting does -** occur. -** -** 2002-Feb-14: This routine is extended to remove MS-Access style -** brackets from around identifiers. For example: "[a-b-c]" becomes -** "a-b-c". -*/ -SQLITE_PRIVATE void sqlite3Dequote(char *z){ - char quote; - int i, j; - if( z==0 ) return; - quote = z[0]; - if( !sqlite3Isquote(quote) ) return; - if( quote=='[' ) quote = ']'; - for(i=1, j=0;; i++){ - assert( z[i] ); - if( z[i]==quote ){ - if( z[i+1]==quote ){ - z[j++] = quote; - i++; - }else{ - break; - } - }else{ - z[j++] = z[i]; - } - } - z[j] = 0; -} - -/* -** Generate a Token object from a string -*/ -SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){ - p->z = z; - p->n = sqlite3Strlen30(z); -} - -/* Convenient short-hand */ -#define UpperToLower sqlite3UpperToLower - -/* -** Some systems have stricmp(). Others have strcasecmp(). Because -** there is no consistency, we will define our own. -** -** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and -** sqlite3_strnicmp() APIs allow applications and extensions to compare -** the contents of two buffers containing UTF-8 strings in a -** case-independent fashion, using the same definition of "case -** independence" that SQLite uses internally when comparing identifiers. -*/ -SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ - if( zLeft==0 ){ - return zRight ? -1 : 0; - }else if( zRight==0 ){ - return 1; - } - return sqlite3StrICmp(zLeft, zRight); -} -SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ - unsigned char *a, *b; - int c; - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - for(;;){ - c = (int)UpperToLower[*a] - (int)UpperToLower[*b]; - if( c || *a==0 ) break; - a++; - b++; - } - return c; -} -SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ - register unsigned char *a, *b; - if( zLeft==0 ){ - return zRight ? -1 : 0; - }else if( zRight==0 ){ - return 1; - } - a = (unsigned char *)zLeft; - b = (unsigned char *)zRight; - while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } - return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; -} - -/* -** The string z[] is an text representation of a real number. -** Convert this string to a double and write it into *pResult. -** -** The string z[] is length bytes in length (bytes, not characters) and -** uses the encoding enc. The string is not necessarily zero-terminated. -** -** Return TRUE if the result is a valid real number (or integer) and FALSE -** if the string is empty or contains extraneous text. Valid numbers -** are in one of these formats: -** -** [+-]digits[E[+-]digits] -** [+-]digits.[digits][E[+-]digits] -** [+-].digits[E[+-]digits] -** -** Leading and trailing whitespace is ignored for the purpose of determining -** validity. -** -** If some prefix of the input string is a valid number, this routine -** returns FALSE but it still converts the prefix and writes the result -** into *pResult. -*/ -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ -#ifndef SQLITE_OMIT_FLOATING_POINT - int incr; - const char *zEnd = z + length; - /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ - int eValid = 1; /* True exponent is either not used or is well-formed */ - double result; - int nDigits = 0; - int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ - - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - *pResult = 0.0; /* Default return value, in case of an error */ - - if( enc==SQLITE_UTF8 ){ - incr = 1; - }else{ - int i; - incr = 2; - assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - for(i=3-enc; i=zEnd ) return 0; - - /* get sign of significand */ - if( *z=='-' ){ - sign = -1; - z+=incr; - }else if( *z=='+' ){ - z+=incr; - } - - /* copy max significant digits to significand */ - while( z=zEnd ) goto do_atof_calc; - - /* if decimal point is present */ - if( *z=='.' ){ - z+=incr; - /* copy digits from after decimal to significand - ** (decrease exponent by d to shift decimal right) */ - while( z=zEnd ) goto do_atof_calc; - - /* if exponent is present */ - if( *z=='e' || *z=='E' ){ - z+=incr; - eValid = 0; - - /* This branch is needed to avoid a (harmless) buffer overread. The - ** special comment alerts the mutation tester that the correct answer - ** is obtained even if the branch is omitted */ - if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ - - /* get sign of exponent */ - if( *z=='-' ){ - esign = -1; - z+=incr; - }else if( *z=='+' ){ - z+=incr; - } - /* copy digits to exponent */ - while( z0 ){ /*OPTIMIZATION-IF-TRUE*/ - if( esign>0 ){ - if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ - s *= 10; - }else{ - if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ - s /= 10; - } - e--; - } - - /* adjust the sign of significand */ - s = sign<0 ? -s : s; - - if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ - result = (double)s; - }else{ - LONGDOUBLE_TYPE scale = 1.0; - /* attempt to handle extremely small/large numbers better */ - if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ - if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ - while( e%308 ) { scale *= 1.0e+1; e -= 1; } - if( esign<0 ){ - result = s / scale; - result /= 1.0e+308; - }else{ - result = s * scale; - result *= 1.0e+308; - } - }else{ assert( e>=342 ); - if( esign<0 ){ - result = 0.0*s; - }else{ - result = 1e308*1e308*s; /* Infinity */ - } - } - }else{ - /* 1.0e+22 is the largest power of 10 than can be - ** represented exactly. */ - while( e%22 ) { scale *= 1.0e+1; e -= 1; } - while( e>0 ) { scale *= 1.0e+22; e -= 22; } - if( esign<0 ){ - result = s / scale; - }else{ - result = s * scale; - } - } - } - } - - /* store the result */ - *pResult = result; - - /* return true if number and no extra non-whitespace chracters after */ - return z==zEnd && nDigits>0 && eValid && nonNum==0; -#else - return !sqlite3Atoi64(z, pResult, length, enc); -#endif /* SQLITE_OMIT_FLOATING_POINT */ -} - -/* -** Compare the 19-character string zNum against the text representation -** value 2^63: 9223372036854775808. Return negative, zero, or positive -** if zNum is less than, equal to, or greater than the string. -** Note that zNum must contain exactly 19 characters. -** -** Unlike memcmp() this routine is guaranteed to return the difference -** in the values of the last digit if the only difference is in the -** last digit. So, for example, -** -** compare2pow63("9223372036854775800", 1) -** -** will return -8. -*/ -static int compare2pow63(const char *zNum, int incr){ - int c = 0; - int i; - /* 012345678901234567 */ - const char *pow63 = "922337203685477580"; - for(i=0; c==0 && i<18; i++){ - c = (zNum[i*incr]-pow63[i])*10; - } - if( c==0 ){ - c = zNum[18*incr] - '8'; - testcase( c==(-1) ); - testcase( c==0 ); - testcase( c==(+1) ); - } - return c; -} - -/* -** Convert zNum to a 64-bit signed integer. zNum must be decimal. This -** routine does *not* accept hexadecimal notation. -** -** If the zNum value is representable as a 64-bit twos-complement -** integer, then write that value into *pNum and return 0. -** -** If zNum is exactly 9223372036854775808, return 2. This special -** case is broken out because while 9223372036854775808 cannot be a -** signed 64-bit integer, its negative -9223372036854775808 can be. -** -** If zNum is too big for a 64-bit integer and is not -** 9223372036854775808 or if zNum contains any non-numeric text, -** then return 1. -** -** length is the number of bytes in the string (bytes, not characters). -** The string is not necessarily zero-terminated. The encoding is -** given by enc. -*/ -SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ - int incr; - u64 u = 0; - int neg = 0; /* assume positive */ - int i; - int c = 0; - int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ - const char *zStart; - const char *zEnd = zNum + length; - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - if( enc==SQLITE_UTF8 ){ - incr = 1; - }else{ - incr = 2; - assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - for(i=3-enc; i='0' && c<='9'; i+=incr){ - u = u*10 + c - '0'; - } - if( u>LARGEST_INT64 ){ - *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; - }else if( neg ){ - *pNum = -(i64)u; - }else{ - *pNum = (i64)u; - } - testcase( i==18 ); - testcase( i==19 ); - testcase( i==20 ); - if( &zNum[i]19*incr /* Too many digits */ - || nonNum /* UTF16 with high-order bytes non-zero */ - ){ - /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranteeing that it is too large) */ - return 1; - }else if( i<19*incr ){ - /* Less than 19 digits, so we know that it fits in 64 bits */ - assert( u<=LARGEST_INT64 ); - return 0; - }else{ - /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */ - c = compare2pow63(zNum, incr); - if( c<0 ){ - /* zNum is less than 9223372036854775808 so it fits */ - assert( u<=LARGEST_INT64 ); - return 0; - }else if( c>0 ){ - /* zNum is greater than 9223372036854775808 so it overflows */ - return 1; - }else{ - /* zNum is exactly 9223372036854775808. Fits if negative. The - ** special case 2 overflow if positive */ - assert( u-1==LARGEST_INT64 ); - return neg ? 0 : 2; - } - } -} - -/* -** Transform a UTF-8 integer literal, in either decimal or hexadecimal, -** into a 64-bit signed integer. This routine accepts hexadecimal literals, -** whereas sqlite3Atoi64() does not. -** -** Returns: -** -** 0 Successful transformation. Fits in a 64-bit signed integer. -** 1 Integer too large for a 64-bit signed integer or is malformed -** 2 Special case of 9223372036854775808 -*/ -SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ -#ifndef SQLITE_OMIT_HEX_INTEGER - if( z[0]=='0' - && (z[1]=='x' || z[1]=='X') - ){ - u64 u = 0; - int i, k; - for(i=2; z[i]=='0'; i++){} - for(k=i; sqlite3Isxdigit(z[k]); k++){ - u = u*16 + sqlite3HexToInt(z[k]); - } - memcpy(pOut, &u, 8); - return (z[k]==0 && k-i<=16) ? 0 : 1; - }else -#endif /* SQLITE_OMIT_HEX_INTEGER */ - { - return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); - } -} - -/* -** If zNum represents an integer that will fit in 32-bits, then set -** *pValue to that integer and return true. Otherwise return false. -** -** This routine accepts both decimal and hexadecimal notation for integers. -** -** Any non-numeric characters that following zNum are ignored. -** This is different from sqlite3Atoi64() which requires the -** input number to be zero-terminated. -*/ -SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ - sqlite_int64 v = 0; - int i, c; - int neg = 0; - if( zNum[0]=='-' ){ - neg = 1; - zNum++; - }else if( zNum[0]=='+' ){ - zNum++; - } -#ifndef SQLITE_OMIT_HEX_INTEGER - else if( zNum[0]=='0' - && (zNum[1]=='x' || zNum[1]=='X') - && sqlite3Isxdigit(zNum[2]) - ){ - u32 u = 0; - zNum += 2; - while( zNum[0]=='0' ) zNum++; - for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ - u = u*16 + sqlite3HexToInt(zNum[i]); - } - if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ - memcpy(pValue, &u, 4); - return 1; - }else{ - return 0; - } - } -#endif - while( zNum[0]=='0' ) zNum++; - for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ - v = v*10 + c; - } - - /* The longest decimal representation of a 32 bit integer is 10 digits: - ** - ** 1234567890 - ** 2^31 -> 2147483648 - */ - testcase( i==10 ); - if( i>10 ){ - return 0; - } - testcase( v-neg==2147483647 ); - if( v-neg>2147483647 ){ - return 0; - } - if( neg ){ - v = -v; - } - *pValue = (int)v; - return 1; -} - -/* -** Return a 32-bit integer value extracted from a string. If the -** string is not an integer, just return 0. -*/ -SQLITE_PRIVATE int sqlite3Atoi(const char *z){ - int x = 0; - if( z ) sqlite3GetInt32(z, &x); - return x; -} - -/* -** The variable-length integer encoding is as follows: -** -** KEY: -** A = 0xxxxxxx 7 bits of data and one flag bit -** B = 1xxxxxxx 7 bits of data and one flag bit -** C = xxxxxxxx 8 bits of data -** -** 7 bits - A -** 14 bits - BA -** 21 bits - BBA -** 28 bits - BBBA -** 35 bits - BBBBA -** 42 bits - BBBBBA -** 49 bits - BBBBBBA -** 56 bits - BBBBBBBA -** 64 bits - BBBBBBBBC -*/ - -/* -** Write a 64-bit variable-length integer to memory starting at p[0]. -** The length of data write will be between 1 and 9 bytes. The number -** of bytes written is returned. -** -** A variable-length integer consists of the lower 7 bits of each byte -** for all bytes that have the 8th bit set and one byte with the 8th -** bit clear. Except, if we get to the 9th byte, it stores the full -** 8 bits and is the last byte. -*/ -static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ - int i, j, n; - u8 buf[10]; - if( v & (((u64)0xff000000)<<32) ){ - p[8] = (u8)v; - v >>= 8; - for(i=7; i>=0; i--){ - p[i] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - } - return 9; - } - n = 0; - do{ - buf[n++] = (u8)((v & 0x7f) | 0x80); - v >>= 7; - }while( v!=0 ); - buf[0] &= 0x7f; - assert( n<=9 ); - for(i=0, j=n-1; j>=0; j--, i++){ - p[i] = buf[j]; - } - return n; -} -SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ - if( v<=0x7f ){ - p[0] = v&0x7f; - return 1; - } - if( v<=0x3fff ){ - p[0] = ((v>>7)&0x7f)|0x80; - p[1] = v&0x7f; - return 2; - } - return putVarint64(p,v); -} - -/* -** Bitmasks used by sqlite3GetVarint(). These precomputed constants -** are defined here rather than simply putting the constant expressions -** inline in order to work around bugs in the RVT compiler. -** -** SLOT_2_0 A mask for (0x7f<<14) | 0x7f -** -** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 -*/ -#define SLOT_2_0 0x001fc07f -#define SLOT_4_2_0 0xf01fc07f - - -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -*/ -SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ - u32 a,b,s; - - a = *p; - /* a: p0 (unmasked) */ - if (!(a&0x80)) - { - *v = a; - return 1; - } - - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - a &= 0x7f; - a = a<<7; - a |= b; - *v = a; - return 2; - } - - /* Verify that constants are precomputed correctly */ - assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); - assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); - - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - a &= SLOT_2_0; - b &= 0x7f; - b = b<<7; - a |= b; - *v = a; - return 3; - } - - /* CSE1 from below */ - a &= SLOT_2_0; - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - b &= SLOT_2_0; - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - *v = a; - return 4; - } - - /* a: p0<<14 | p2 (masked) */ - /* b: p1<<14 | p3 (unmasked) */ - /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - b &= SLOT_2_0; - s = a; - /* s: p0<<14 | p2 (masked) */ - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* we can skip these cause they were (effectively) done above - ** while calculating s */ - /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - /* b &= (0x7f<<14)|(0x7f); */ - b = b<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 5; - } - - /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - s = s<<7; - s |= b; - /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - - p++; - b = b<<14; - b |= *p; - /* b: p1<<28 | p3<<14 | p5 (unmasked) */ - if (!(b&0x80)) - { - /* we can skip this cause it was (effectively) done above in calc'ing s */ - /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - a &= SLOT_2_0; - a = a<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 6; - } - - p++; - a = a<<14; - a |= *p; - /* a: p2<<28 | p4<<14 | p6 (unmasked) */ - if (!(a&0x80)) - { - a &= SLOT_4_2_0; - b &= SLOT_2_0; - b = b<<7; - a |= b; - s = s>>11; - *v = ((u64)s)<<32 | a; - return 7; - } - - /* CSE2 from below */ - a &= SLOT_2_0; - p++; - b = b<<14; - b |= *p; - /* b: p3<<28 | p5<<14 | p7 (unmasked) */ - if (!(b&0x80)) - { - b &= SLOT_4_2_0; - /* moved CSE2 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - s = s>>4; - *v = ((u64)s)<<32 | a; - return 8; - } - - p++; - a = a<<15; - a |= *p; - /* a: p4<<29 | p6<<15 | p8 (unmasked) */ - - /* moved CSE2 up */ - /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ - b &= SLOT_2_0; - b = b<<8; - a |= b; - - s = s<<4; - b = p[-4]; - b &= 0x7f; - b = b>>3; - s |= b; - - *v = ((u64)s)<<32 | a; - - return 9; -} - -/* -** Read a 32-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read. The value is stored in *v. -** -** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned -** integer, then set *v to 0xffffffff. -** -** A MACRO version, getVarint32, is provided which inlines the -** single-byte case. All code should use the MACRO version as -** this function assumes the single-byte case has already been handled. -*/ -SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; - - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif - - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; - return 2; - } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; - return 3; - } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - p -= 2; - n = sqlite3GetVarint(p, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 268435456 and 34359738367 */ - a &= SLOT_4_2_0; - b &= SLOT_4_2_0; - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); - *v = (u32)v64; - return n; - } -#endif -} - -/* -** Return the number of bytes that will be needed to store the given -** 64-bit integer. -*/ -SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ - int i; - for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); } - return i; -} - - -/* -** Read or write a four-byte big-endian integer value. -*/ -SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ -#if SQLITE_BYTEORDER==4321 - u32 x; - memcpy(&x,p,4); - return x; -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 - u32 x; - memcpy(&x,p,4); - return __builtin_bswap32(x); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 - u32 x; - memcpy(&x,p,4); - return _byteswap_ulong(x); -#else - testcase( p[0]&0x80 ); - return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; -#endif -} -SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ -#if SQLITE_BYTEORDER==4321 - memcpy(p,&v,4); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 - u32 x = __builtin_bswap32(v); - memcpy(p,&x,4); -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 - u32 x = _byteswap_ulong(v); - memcpy(p,&x,4); -#else - p[0] = (u8)(v>>24); - p[1] = (u8)(v>>16); - p[2] = (u8)(v>>8); - p[3] = (u8)v; -#endif -} - - - -/* -** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F -*/ -SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); -#ifdef SQLITE_ASCII - h += 9*(1&(h>>6)); -#endif -#ifdef SQLITE_EBCDIC - h += 9*(1&~(h>>4)); -#endif - return (u8)(h & 0xf); -} - -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) -/* -** Convert a BLOB literal of the form "x'hhhhhh'" into its binary -** value. Return a pointer to its binary value. Space to hold the -** binary value has been obtained from malloc and must be freed by -** the calling routine. -*/ -SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ - char *zBlob; - int i; - - zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); - n--; - if( zBlob ){ - for(i=0; imagic; - if( magic!=SQLITE_MAGIC_OPEN ){ - if( sqlite3SafetyCheckSickOrOk(db) ){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - logBadConnection("unopened"); - } - return 0; - }else{ - return 1; - } -} -SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ - u32 magic; - magic = db->magic; - if( magic!=SQLITE_MAGIC_SICK && - magic!=SQLITE_MAGIC_OPEN && - magic!=SQLITE_MAGIC_BUSY ){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - logBadConnection("invalid"); - return 0; - }else{ - return 1; - } -} - -/* -** Attempt to add, substract, or multiply the 64-bit signed value iB against -** the other 64-bit signed integer at *pA and store the result in *pA. -** Return 0 on success. Or if the operation would have resulted in an -** overflow, leave *pA unchanged and return 1. -*/ -SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ - i64 iA = *pA; - testcase( iA==0 ); testcase( iA==1 ); - testcase( iB==-1 ); testcase( iB==0 ); - if( iB>=0 ){ - testcase( iA>0 && LARGEST_INT64 - iA == iB ); - testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); - if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; - }else{ - testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); - testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); - if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; - } - *pA += iB; - return 0; -} -SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ - testcase( iB==SMALLEST_INT64+1 ); - if( iB==SMALLEST_INT64 ){ - testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); - if( (*pA)>=0 ) return 1; - *pA -= iB; - return 0; - }else{ - return sqlite3AddInt64(pA, -iB); - } -} -SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ - i64 iA = *pA; - if( iB>0 ){ - if( iA>LARGEST_INT64/iB ) return 1; - if( iA0 ){ - if( iBLARGEST_INT64/-iB ) return 1; - } - } - *pA = iA*iB; - return 0; -} - -/* -** Compute the absolute value of a 32-bit signed integer, of possible. Or -** if the integer has a value of -2147483648, return +2147483647 -*/ -SQLITE_PRIVATE int sqlite3AbsInt32(int x){ - if( x>=0 ) return x; - if( x==(int)0x80000000 ) return 0x7fffffff; - return -x; -} - -#ifdef SQLITE_ENABLE_8_3_NAMES -/* -** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database -** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and -** if filename in z[] has a suffix (a.k.a. "extension") that is longer than -** three characters, then shorten the suffix on z[] to be the last three -** characters of the original suffix. -** -** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always -** do the suffix shortening regardless of URI parameter. -** -** Examples: -** -** test.db-journal => test.nal -** test.db-wal => test.wal -** test.db-shm => test.shm -** test.db-mj7f3319fa => test.9fa -*/ -SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ -#if SQLITE_ENABLE_8_3_NAMES<2 - if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) -#endif - { - int i, sz; - sz = sqlite3Strlen30(z); - for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); - } -} -#endif - -/* -** Find (an approximate) sum of two LogEst values. This computation is -** not a simple "+" operator because LogEst is stored as a logarithmic -** value. -** -*/ -SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ - static const unsigned char x[] = { - 10, 10, /* 0,1 */ - 9, 9, /* 2,3 */ - 8, 8, /* 4,5 */ - 7, 7, 7, /* 6,7,8 */ - 6, 6, 6, /* 9,10,11 */ - 5, 5, 5, /* 12-14 */ - 4, 4, 4, 4, /* 15-18 */ - 3, 3, 3, 3, 3, 3, /* 19-24 */ - 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ - }; - if( a>=b ){ - if( a>b+49 ) return a; - if( a>b+31 ) return a+1; - return a+x[a-b]; - }else{ - if( b>a+49 ) return b; - if( b>a+31 ) return b+1; - return b+x[b-a]; - } -} - -/* -** Convert an integer into a LogEst. In other words, compute an -** approximation for 10*log2(x). -*/ -SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ - static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; - LogEst y = 40; - if( x<8 ){ - if( x<2 ) return 0; - while( x<8 ){ y -= 10; x <<= 1; } - }else{ - while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ - while( x>15 ){ y += 10; x >>= 1; } - } - return a[x&7] + y - 10; -} - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* -** Convert a double into a LogEst -** In other words, compute an approximation for 10*log2(x). -*/ -SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ - u64 a; - LogEst e; - assert( sizeof(x)==8 && sizeof(a)==8 ); - if( x<=1 ) return 0; - if( x<=2000000000 ) return sqlite3LogEst((u64)x); - memcpy(&a, &x, 8); - e = (a>>52) - 1022; - return e*10; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) -/* -** Convert a LogEst into an integer. -** -** Note that this routine is only used when one or more of various -** non-standard compile-time options is enabled. -*/ -SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ - u64 n; - n = x%10; - x /= 10; - if( n>=5 ) n -= 2; - else if( n>=1 ) n -= 1; -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) - if( x>60 ) return (u64)LARGEST_INT64; -#else - /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input - ** possible to this routine is 310, resulting in a maximum x of 31 */ - assert( x<=60 ); -#endif - return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); -} -#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ - -/************** End of util.c ************************************************/ -/************** Begin file hash.c ********************************************/ -/* -** 2001 September 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This is the implementation of generic hash-tables -** used in SQLite. -*/ -/* #include "sqliteInt.h" */ -/* #include */ - -/* Turn bulk memory into a hash table object by initializing the -** fields of the Hash structure. -** -** "pNew" is a pointer to the hash table that is to be initialized. -*/ -SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){ - assert( pNew!=0 ); - pNew->first = 0; - pNew->count = 0; - pNew->htsize = 0; - pNew->ht = 0; -} - -/* Remove all entries from a hash table. Reclaim all memory. -** Call this routine to delete a hash table or to reset a hash table -** to the empty state. -*/ -SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ - HashElem *elem; /* For looping over all elements of the table */ - - assert( pH!=0 ); - elem = pH->first; - pH->first = 0; - sqlite3_free(pH->ht); - pH->ht = 0; - pH->htsize = 0; - while( elem ){ - HashElem *next_elem = elem->next; - sqlite3_free(elem); - elem = next_elem; - } - pH->count = 0; -} - -/* -** The hashing function. -*/ -static unsigned int strHash(const char *z){ - unsigned int h = 0; - unsigned char c; - while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). - ** 0x9e3779b1 is 2654435761 which is the closest prime number to - ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ - h += sqlite3UpperToLower[c]; - h *= 0x9e3779b1; - } - return h; -} - - -/* Link pNew element into the hash table pH. If pEntry!=0 then also -** insert pNew into the pEntry hash bucket. -*/ -static void insertElement( - Hash *pH, /* The complete hash table */ - struct _ht *pEntry, /* The entry into which pNew is inserted */ - HashElem *pNew /* The element to be inserted */ -){ - HashElem *pHead; /* First element already in pEntry */ - if( pEntry ){ - pHead = pEntry->count ? pEntry->chain : 0; - pEntry->count++; - pEntry->chain = pNew; - }else{ - pHead = 0; - } - if( pHead ){ - pNew->next = pHead; - pNew->prev = pHead->prev; - if( pHead->prev ){ pHead->prev->next = pNew; } - else { pH->first = pNew; } - pHead->prev = pNew; - }else{ - pNew->next = pH->first; - if( pH->first ){ pH->first->prev = pNew; } - pNew->prev = 0; - pH->first = pNew; - } -} - - -/* Resize the hash table so that it cantains "new_size" buckets. -** -** The hash table might fail to resize if sqlite3_malloc() fails or -** if the new size is the same as the prior size. -** Return TRUE if the resize occurs and false if not. -*/ -static int rehash(Hash *pH, unsigned int new_size){ - struct _ht *new_ht; /* The new hash table */ - HashElem *elem, *next_elem; /* For looping over existing elements */ - -#if SQLITE_MALLOC_SOFT_LIMIT>0 - if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ - new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); - } - if( new_size==pH->htsize ) return 0; -#endif - - /* The inability to allocates space for a larger hash table is - ** a performance hit but it is not a fatal error. So mark the - ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of - ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() - ** only zeroes the requested number of bytes whereas this module will - ** use the actual amount of space allocated for the hash table (which - ** may be larger than the requested amount). - */ - sqlite3BeginBenignMalloc(); - new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); - sqlite3EndBenignMalloc(); - - if( new_ht==0 ) return 0; - sqlite3_free(pH->ht); - pH->ht = new_ht; - pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); - memset(new_ht, 0, new_size*sizeof(struct _ht)); - for(elem=pH->first, pH->first=0; elem; elem = next_elem){ - unsigned int h = strHash(elem->pKey) % new_size; - next_elem = elem->next; - insertElement(pH, &new_ht[h], elem); - } - return 1; -} - -/* This function (for internal use only) locates an element in an -** hash table that matches the given key. The hash for this key is -** also computed and returned in the *pH parameter. -*/ -static HashElem *findElementWithHash( - const Hash *pH, /* The pH to be searched */ - const char *pKey, /* The key we are searching for */ - unsigned int *pHash /* Write the hash value here */ -){ - HashElem *elem; /* Used to loop thru the element list */ - int count; /* Number of elements left to test */ - unsigned int h; /* The computed hash */ - - if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ - struct _ht *pEntry; - h = strHash(pKey) % pH->htsize; - pEntry = &pH->ht[h]; - elem = pEntry->chain; - count = pEntry->count; - }else{ - h = 0; - elem = pH->first; - count = pH->count; - } - *pHash = h; - while( count-- ){ - assert( elem!=0 ); - if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ - return elem; - } - elem = elem->next; - } - return 0; -} - -/* Remove a single entry from the hash table given a pointer to that -** element and a hash on the element's key. -*/ -static void removeElementGivenHash( - Hash *pH, /* The pH containing "elem" */ - HashElem* elem, /* The element to be removed from the pH */ - unsigned int h /* Hash value for the element */ -){ - struct _ht *pEntry; - if( elem->prev ){ - elem->prev->next = elem->next; - }else{ - pH->first = elem->next; - } - if( elem->next ){ - elem->next->prev = elem->prev; - } - if( pH->ht ){ - pEntry = &pH->ht[h]; - if( pEntry->chain==elem ){ - pEntry->chain = elem->next; - } - pEntry->count--; - assert( pEntry->count>=0 ); - } - sqlite3_free( elem ); - pH->count--; - if( pH->count==0 ){ - assert( pH->first==0 ); - assert( pH->count==0 ); - sqlite3HashClear(pH); - } -} - -/* Attempt to locate an element of the hash table pH with a key -** that matches pKey. Return the data for this element if it is -** found, or NULL if there is no match. -*/ -SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ - HashElem *elem; /* The element that matches key */ - unsigned int h; /* A hash on key */ - - assert( pH!=0 ); - assert( pKey!=0 ); - elem = findElementWithHash(pH, pKey, &h); - return elem ? elem->data : 0; -} - -/* Insert an element into the hash table pH. The key is pKey -** and the data is "data". -** -** If no element exists with a matching key, then a new -** element is created and NULL is returned. -** -** If another element already exists with the same key, then the -** new data replaces the old data and the old data is returned. -** The key is not copied in this instance. If a malloc fails, then -** the new data is returned and the hash table is unchanged. -** -** If the "data" parameter to this function is NULL, then the -** element corresponding to "key" is removed from the hash table. -*/ -SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ - unsigned int h; /* the hash of the key modulo hash table size */ - HashElem *elem; /* Used to loop thru the element list */ - HashElem *new_elem; /* New element added to the pH */ - - assert( pH!=0 ); - assert( pKey!=0 ); - elem = findElementWithHash(pH,pKey,&h); - if( elem ){ - void *old_data = elem->data; - if( data==0 ){ - removeElementGivenHash(pH,elem,h); - }else{ - elem->data = data; - elem->pKey = pKey; - } - return old_data; - } - if( data==0 ) return 0; - new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); - if( new_elem==0 ) return data; - new_elem->pKey = pKey; - new_elem->data = data; - pH->count++; - if( pH->count>=10 && pH->count > 2*pH->htsize ){ - if( rehash(pH, pH->count*2) ){ - assert( pH->htsize>0 ); - h = strHash(pKey) % pH->htsize; - } - } - insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); - return 0; -} - -/************** End of hash.c ************************************************/ -/************** Begin file opcodes.c *****************************************/ -/* Automatically generated. Do not edit */ -/* See the tool/mkopcodec.tcl script for details. */ -#if !defined(SQLITE_OMIT_EXPLAIN) \ - || defined(VDBE_PROFILE) \ - || defined(SQLITE_DEBUG) -#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) -# define OpHelp(X) "\0" X -#else -# define OpHelp(X) -#endif -SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ - static const char *const azName[] = { - /* 0 */ "Savepoint" OpHelp(""), - /* 1 */ "AutoCommit" OpHelp(""), - /* 2 */ "Transaction" OpHelp(""), - /* 3 */ "SorterNext" OpHelp(""), - /* 4 */ "PrevIfOpen" OpHelp(""), - /* 5 */ "NextIfOpen" OpHelp(""), - /* 6 */ "Prev" OpHelp(""), - /* 7 */ "Next" OpHelp(""), - /* 8 */ "Checkpoint" OpHelp(""), - /* 9 */ "JournalMode" OpHelp(""), - /* 10 */ "Vacuum" OpHelp(""), - /* 11 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), - /* 12 */ "VUpdate" OpHelp("data=r[P3@P2]"), - /* 13 */ "Goto" OpHelp(""), - /* 14 */ "Gosub" OpHelp(""), - /* 15 */ "InitCoroutine" OpHelp(""), - /* 16 */ "Yield" OpHelp(""), - /* 17 */ "MustBeInt" OpHelp(""), - /* 18 */ "Jump" OpHelp(""), - /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), - /* 20 */ "Once" OpHelp(""), - /* 21 */ "If" OpHelp(""), - /* 22 */ "IfNot" OpHelp(""), - /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 27 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), - /* 28 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 31 */ "Found" OpHelp("key=r[P3@P4]"), - /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 33 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 34 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 35 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 36 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 37 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 38 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 39 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 40 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 42 */ "ElseNotEq" OpHelp(""), - /* 43 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 44 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 45 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 47 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 48 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 49 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 50 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 51 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 52 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 53 */ "Last" OpHelp(""), - /* 54 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), - /* 55 */ "SorterSort" OpHelp(""), - /* 56 */ "Sort" OpHelp(""), - /* 57 */ "Rewind" OpHelp(""), - /* 58 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 59 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 60 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 61 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 62 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), - /* 63 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), - /* 64 */ "Program" OpHelp(""), - /* 65 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 66 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 67 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"), - /* 68 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), - /* 69 */ "IncrVacuum" OpHelp(""), - /* 70 */ "VNext" OpHelp(""), - /* 71 */ "Init" OpHelp("Start at P2"), - /* 72 */ "Return" OpHelp(""), - /* 73 */ "EndCoroutine" OpHelp(""), - /* 74 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), - /* 75 */ "Halt" OpHelp(""), - /* 76 */ "Integer" OpHelp("r[P2]=P1"), - /* 77 */ "Int64" OpHelp("r[P2]=P4"), - /* 78 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 79 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 80 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 81 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 82 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 83 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 84 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 85 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 86 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 87 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 88 */ "CollSeq" OpHelp(""), - /* 89 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), - /* 90 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), - /* 91 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 92 */ "RealAffinity" OpHelp(""), - /* 93 */ "Cast" OpHelp("affinity(r[P1])"), - /* 94 */ "Permutation" OpHelp(""), - /* 95 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 96 */ "Column" OpHelp("r[P3]=PX"), - /* 97 */ "String8" OpHelp("r[P2]='P4'"), - /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 100 */ "Count" OpHelp("r[P2]=count()"), - /* 101 */ "ReadCookie" OpHelp(""), - /* 102 */ "SetCookie" OpHelp(""), - /* 103 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 104 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 105 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 106 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 107 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 108 */ "SorterOpen" OpHelp(""), - /* 109 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 110 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 111 */ "Close" OpHelp(""), - /* 112 */ "ColumnsUsed" OpHelp(""), - /* 113 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 114 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 115 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 116 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), - /* 117 */ "Delete" OpHelp(""), - /* 118 */ "ResetCount" OpHelp(""), - /* 119 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 120 */ "SorterData" OpHelp("r[P2]=data"), - /* 121 */ "RowKey" OpHelp("r[P2]=key"), - /* 122 */ "RowData" OpHelp("r[P2]=data"), - /* 123 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 124 */ "NullRow" OpHelp(""), - /* 125 */ "SorterInsert" OpHelp(""), - /* 126 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"), - /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 130 */ "Destroy" OpHelp(""), - /* 131 */ "Clear" OpHelp(""), - /* 132 */ "Real" OpHelp("r[P2]=P4"), - /* 133 */ "ResetSorter" OpHelp(""), - /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), - /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), - /* 136 */ "ParseSchema" OpHelp(""), - /* 137 */ "LoadAnalysis" OpHelp(""), - /* 138 */ "DropTable" OpHelp(""), - /* 139 */ "DropIndex" OpHelp(""), - /* 140 */ "DropTrigger" OpHelp(""), - /* 141 */ "IntegrityCk" OpHelp(""), - /* 142 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 143 */ "Param" OpHelp(""), - /* 144 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 145 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 146 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 147 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 148 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 149 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 150 */ "Expire" OpHelp(""), - /* 151 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 152 */ "VBegin" OpHelp(""), - /* 153 */ "VCreate" OpHelp(""), - /* 154 */ "VDestroy" OpHelp(""), - /* 155 */ "VOpen" OpHelp(""), - /* 156 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 157 */ "VRename" OpHelp(""), - /* 158 */ "Pagecount" OpHelp(""), - /* 159 */ "MaxPgcnt" OpHelp(""), - /* 160 */ "CursorHint" OpHelp(""), - /* 161 */ "Noop" OpHelp(""), - /* 162 */ "Explain" OpHelp(""), - }; - return azName[i]; -} -#endif - -/************** End of opcodes.c *********************************************/ -/************** Begin file os_unix.c *****************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains the VFS implementation for unix-like operating systems -** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others. -** -** There are actually several different VFS implementations in this file. -** The differences are in the way that file locking is done. The default -** implementation uses Posix Advisory Locks. Alternative implementations -** use flock(), dot-files, various proprietary locking schemas, or simply -** skip locking all together. -** -** This source file is organized into divisions where the logic for various -** subfunctions is contained within the appropriate division. PLEASE -** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed -** in the correct division and should be clearly labeled. -** -** The layout of divisions is as follows: -** -** * General-purpose declarations and utility functions. -** * Unique file ID logic used by VxWorks. -** * Various locking primitive implementations (all except proxy locking): -** + for Posix Advisory Locks -** + for no-op locks -** + for dot-file locks -** + for flock() locking -** + for named semaphore locks (VxWorks only) -** + for AFP filesystem locks (MacOSX only) -** * sqlite3_file methods not associated with locking. -** * Definitions of sqlite3_io_methods objects for all locking -** methods plus "finder" functions for each locking method. -** * sqlite3_vfs method implementations. -** * Locking primitives for the proxy uber-locking-method. (MacOSX only) -** * Definitions of sqlite3_vfs objects for all locking methods -** plus implementations of sqlite3_os_init() and sqlite3_os_end(). -*/ -/* #include "sqliteInt.h" */ -#if SQLITE_OS_UNIX /* This file is used on unix only */ - -/* -** There are various methods for file locking used for concurrency -** control: -** -** 1. POSIX locking (the default), -** 2. No locking, -** 3. Dot-file locking, -** 4. flock() locking, -** 5. AFP locking (OSX only), -** 6. Named POSIX semaphores (VXWorks only), -** 7. proxy locking. (OSX only) -** -** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE -** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic -** selection of the appropriate locking style based on the filesystem -** where the database is located. -*/ -#if !defined(SQLITE_ENABLE_LOCKING_STYLE) -# if defined(__APPLE__) -# define SQLITE_ENABLE_LOCKING_STYLE 1 -# else -# define SQLITE_ENABLE_LOCKING_STYLE 0 -# endif -#endif - -/* Use pread() and pwrite() if they are available */ -#if defined(__APPLE__) -# define HAVE_PREAD 1 -# define HAVE_PWRITE 1 -#endif -#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64) -# undef USE_PREAD -# define USE_PREAD64 1 -#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE) -# undef USE_PREAD64 -# define USE_PREAD 1 -#endif - -/* -** standard include files. -*/ -#include -#include -#include -#include -/* #include */ -#include -#include -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 -# include -#endif - -#if SQLITE_ENABLE_LOCKING_STYLE -# include -# include -# include -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - -#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ - (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) -# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ - && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) -# define HAVE_GETHOSTUUID 1 -# else -# warning "gethostuuid() is disabled." -# endif -#endif - - -#if OS_VXWORKS -/* # include */ -# include -# include -#endif /* OS_VXWORKS */ - -#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE -# include -#endif - -#ifdef HAVE_UTIME -# include -#endif - -/* -** Allowed values of unixFile.fsFlags -*/ -#define SQLITE_FSFLAGS_IS_MSDOS 0x1 - -/* -** If we are to be thread-safe, include the pthreads header and define -** the SQLITE_UNIX_THREADS macro. -*/ -#if SQLITE_THREADSAFE -/* # include */ -# define SQLITE_UNIX_THREADS 1 -#endif - -/* -** Default permissions when creating a new file -*/ -#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS -# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 -#endif - -/* -** Default permissions when creating auto proxy dir -*/ -#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS -# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 -#endif - -/* -** Maximum supported path-length. -*/ -#define MAX_PATHNAME 512 - -/* -** Maximum supported symbolic links -*/ -#define SQLITE_MAX_SYMLINKS 100 - -/* Always cast the getpid() return type for compatibility with -** kernel modules in VxWorks. */ -#define osGetpid(X) (pid_t)getpid() - -/* -** Only set the lastErrno if the error code is a real error and not -** a normal expected return code of SQLITE_BUSY or SQLITE_OK -*/ -#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) - -/* Forward references */ -typedef struct unixShm unixShm; /* Connection shared memory */ -typedef struct unixShmNode unixShmNode; /* Shared memory instance */ -typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ -typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ - -/* -** Sometimes, after a file handle is closed by SQLite, the file descriptor -** cannot be closed immediately. In these cases, instances of the following -** structure are used to store the file descriptor while waiting for an -** opportunity to either close or reuse it. -*/ -struct UnixUnusedFd { - int fd; /* File descriptor to close */ - int flags; /* Flags this file descriptor was opened with */ - UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ -}; - -/* -** The unixFile structure is subclass of sqlite3_file specific to the unix -** VFS implementations. -*/ -typedef struct unixFile unixFile; -struct unixFile { - sqlite3_io_methods const *pMethod; /* Always the first entry */ - sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ - unixInodeInfo *pInode; /* Info about locks on this inode */ - int h; /* The file descriptor */ - unsigned char eFileLock; /* The type of lock held on this fd */ - unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ - int lastErrno; /* The unix errno from last I/O error */ - void *lockingContext; /* Locking style specific state */ - UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ - const char *zPath; /* Name of the file */ - unixShm *pShm; /* Shared memory segment information */ - int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ -#if SQLITE_MAX_MMAP_SIZE>0 - int nFetchOut; /* Number of outstanding xFetch refs */ - sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ - sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ - sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ - void *pMapRegion; /* Memory mapped region */ -#endif -#ifdef __QNXNTO__ - int sectorSize; /* Device sector size */ - int deviceCharacteristics; /* Precomputed device characteristics */ -#endif -#if SQLITE_ENABLE_LOCKING_STYLE - int openFlags; /* The flags specified at open() */ -#endif -#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) - unsigned fsFlags; /* cached details from statfs() */ -#endif -#if OS_VXWORKS - struct vxworksFileId *pId; /* Unique file ID */ -#endif -#ifdef SQLITE_DEBUG - /* The next group of variables are used to track whether or not the - ** transaction counter in bytes 24-27 of database files are updated - ** whenever any part of the database changes. An assertion fault will - ** occur if a file is updated without also updating the transaction - ** counter. This test is made to avoid new problems similar to the - ** one described by ticket #3584. - */ - unsigned char transCntrChng; /* True if the transaction counter changed */ - unsigned char dbUpdate; /* True if any part of database file changed */ - unsigned char inNormalWrite; /* True if in a normal write operation */ - -#endif - -#ifdef SQLITE_TEST - /* In test mode, increase the size of this structure a bit so that - ** it is larger than the struct CrashFile defined in test6.c. - */ - char aPadding[32]; -#endif -}; - -/* This variable holds the process id (pid) from when the xRandomness() -** method was called. If xOpen() is called from a different process id, -** indicating that a fork() has occurred, the PRNG will be reset. -*/ -static pid_t randomnessPid = 0; - -/* -** Allowed values for the unixFile.ctrlFlags bitmask: -*/ -#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ -#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ -#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#ifndef SQLITE_DISABLE_DIRSYNC -# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ -#else -# define UNIXFILE_DIRSYNC 0x00 -#endif -#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ -#define UNIXFILE_DELETE 0x20 /* Delete on close */ -#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ -#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ - -/* -** Include code that is common to all os_*.c files -*/ -/************** Include os_common.h in the middle of os_unix.c ***************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - #error Need implementation of sqlite3Hwtime() for your platform. - - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in os_unix.c ********************/ - -/* -** Define various macros that are missing from some systems. -*/ -#ifndef O_LARGEFILE -# define O_LARGEFILE 0 -#endif -#ifdef SQLITE_DISABLE_LFS -# undef O_LARGEFILE -# define O_LARGEFILE 0 -#endif -#ifndef O_NOFOLLOW -# define O_NOFOLLOW 0 -#endif -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -/* -** The threadid macro resolves to the thread-id or to 0. Used for -** testing and debugging only. -*/ -#if SQLITE_THREADSAFE -#define threadid pthread_self() -#else -#define threadid 0 -#endif - -/* -** HAVE_MREMAP defaults to true on Linux and false everywhere else. -*/ -#if !defined(HAVE_MREMAP) -# if defined(__linux__) && defined(_GNU_SOURCE) -# define HAVE_MREMAP 1 -# else -# define HAVE_MREMAP 0 -# endif -#endif - -/* -** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() -** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. -*/ -#ifdef __ANDROID__ -# define lseek lseek64 -#endif - -/* -** Different Unix systems declare open() in different ways. Same use -** open(const char*,int,mode_t). Others use open(const char*,int,...). -** The difference is important when using a pointer to the function. -** -** The safest way to deal with the problem is to always use this wrapper -** which always has the same well-defined interface. -*/ -static int posixOpen(const char *zFile, int flags, int mode){ - return open(zFile, flags, mode); -} - -/* Forward reference */ -static int openDirectory(const char*, int*); -static int unixGetpagesize(void); - -/* -** Many system calls are accessed through pointer-to-functions so that -** they may be overridden at runtime to facilitate fault injection during -** testing and sandboxing. The following array holds the names and pointers -** to all overrideable system calls. -*/ -static struct unix_syscall { - const char *zName; /* Name of the system call */ - sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ - sqlite3_syscall_ptr pDefault; /* Default value */ -} aSyscall[] = { - { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, -#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) - - { "close", (sqlite3_syscall_ptr)close, 0 }, -#define osClose ((int(*)(int))aSyscall[1].pCurrent) - - { "access", (sqlite3_syscall_ptr)access, 0 }, -#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) - - { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, -#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) - - { "stat", (sqlite3_syscall_ptr)stat, 0 }, -#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) - -/* -** The DJGPP compiler environment looks mostly like Unix, but it -** lacks the fcntl() system call. So redefine fcntl() to be something -** that always succeeds. This means that locking does not occur under -** DJGPP. But it is DOS - what did you expect? -*/ -#ifdef __DJGPP__ - { "fstat", 0, 0 }, -#define osFstat(a,b,c) 0 -#else - { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, -#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) -#endif - - { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, -#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) - - { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, -#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) - - { "read", (sqlite3_syscall_ptr)read, 0 }, -#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) - -#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE - { "pread", (sqlite3_syscall_ptr)pread, 0 }, -#else - { "pread", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) - -#if defined(USE_PREAD64) - { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, -#else - { "pread64", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent) - - { "write", (sqlite3_syscall_ptr)write, 0 }, -#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) - -#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE - { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, -#else - { "pwrite", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ - aSyscall[12].pCurrent) - -#if defined(USE_PREAD64) - { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, -#else - { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ - aSyscall[13].pCurrent) - - { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, -#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) - -#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE - { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, -#else - { "fallocate", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) - - { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, -#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) - - { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, -#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) - - { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, -#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) - - { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, -#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) - -#if defined(HAVE_FCHOWN) - { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, -#else - { "fchown", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) - - { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, -#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) - -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, -#else - { "mmap", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) - -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, -#else - { "munmap", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent) - -#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, -#else - { "mremap", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) - -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, -#else - { "getpagesize", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) - -#if defined(HAVE_READLINK) - { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, -#else - { "readlink", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) - -#if defined(HAVE_LSTAT) - { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, -#else - { "lstat", (sqlite3_syscall_ptr)0, 0 }, -#endif -#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) - -}; /* End of the overrideable system calls */ - - -/* -** On some systems, calls to fchown() will trigger a message in a security -** log if they come from non-root processes. So avoid calling fchown() if -** we are not running as root. -*/ -static int robustFchown(int fd, uid_t uid, gid_t gid){ -#if defined(HAVE_FCHOWN) - return osGeteuid() ? 0 : osFchown(fd,uid,gid); -#else - return 0; -#endif -} - -/* -** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "unix" VFSes. Return SQLITE_OK opon successfully updating the -** system call pointer, or SQLITE_NOTFOUND if there is no configurable -** system call named zName. -*/ -static int unixSetSystemCall( - sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ - const char *zName, /* Name of system call to override */ - sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ -){ - unsigned int i; - int rc = SQLITE_NOTFOUND; - - UNUSED_PARAMETER(pNotUsed); - if( zName==0 ){ - /* If no zName is given, restore all system calls to their default - ** settings and return NULL - */ - rc = SQLITE_OK; - for(i=0; i=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; - osClose(fd); - sqlite3_log(SQLITE_WARNING, - "attempt to open \"%s\" as file descriptor %d", z, fd); - fd = -1; - if( osOpen("/dev/null", f, m)<0 ) break; - } - if( fd>=0 ){ - if( m!=0 ){ - struct stat statbuf; - if( osFstat(fd, &statbuf)==0 - && statbuf.st_size==0 - && (statbuf.st_mode&0777)!=m - ){ - osFchmod(fd, m); - } - } -#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) - osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); -#endif - } - return fd; -} - -/* -** Helper functions to obtain and relinquish the global mutex. The -** global mutex is used to protect the unixInodeInfo and -** vxworksFileId objects used by this file, all of which may be -** shared by multiple threads. -** -** Function unixMutexHeld() is used to assert() that the global mutex -** is held when required. This function is only used as part of assert() -** statements. e.g. -** -** unixEnterMutex() -** assert( unixMutexHeld() ); -** unixEnterLeave() -*/ -static void unixEnterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -static void unixLeaveMutex(void){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -#ifdef SQLITE_DEBUG -static int unixMutexHeld(void) { - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -#endif - - -#ifdef SQLITE_HAVE_OS_TRACE -/* -** Helper function for printing out trace information from debugging -** binaries. This returns the string representation of the supplied -** integer lock-type. -*/ -static const char *azFileLock(int eFileLock){ - switch( eFileLock ){ - case NO_LOCK: return "NONE"; - case SHARED_LOCK: return "SHARED"; - case RESERVED_LOCK: return "RESERVED"; - case PENDING_LOCK: return "PENDING"; - case EXCLUSIVE_LOCK: return "EXCLUSIVE"; - } - return "ERROR"; -} -#endif - -#ifdef SQLITE_LOCK_TRACE -/* -** Print out information about all locking operations. -** -** This routine is used for troubleshooting locks on multithreaded -** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE -** command-line option on the compiler. This code is normally -** turned off. -*/ -static int lockTrace(int fd, int op, struct flock *p){ - char *zOpName, *zType; - int s; - int savedErrno; - if( op==F_GETLK ){ - zOpName = "GETLK"; - }else if( op==F_SETLK ){ - zOpName = "SETLK"; - }else{ - s = osFcntl(fd, op, p); - sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); - return s; - } - if( p->l_type==F_RDLCK ){ - zType = "RDLCK"; - }else if( p->l_type==F_WRLCK ){ - zType = "WRLCK"; - }else if( p->l_type==F_UNLCK ){ - zType = "UNLCK"; - }else{ - assert( 0 ); - } - assert( p->l_whence==SEEK_SET ); - s = osFcntl(fd, op, p); - savedErrno = errno; - sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", - threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, - (int)p->l_pid, s); - if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ - struct flock l2; - l2 = *p; - osFcntl(fd, F_GETLK, &l2); - if( l2.l_type==F_RDLCK ){ - zType = "RDLCK"; - }else if( l2.l_type==F_WRLCK ){ - zType = "WRLCK"; - }else if( l2.l_type==F_UNLCK ){ - zType = "UNLCK"; - }else{ - assert( 0 ); - } - sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", - zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); - } - errno = savedErrno; - return s; -} -#undef osFcntl -#define osFcntl lockTrace -#endif /* SQLITE_LOCK_TRACE */ - -/* -** Retry ftruncate() calls that fail due to EINTR -** -** All calls to ftruncate() within this file should be made through -** this wrapper. On the Android platform, bypassing the logic below -** could lead to a corrupt database. -*/ -static int robust_ftruncate(int h, sqlite3_int64 sz){ - int rc; -#ifdef __ANDROID__ - /* On Android, ftruncate() always uses 32-bit offsets, even if - ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to - ** truncate a file to any size larger than 2GiB. Silently ignore any - ** such attempts. */ - if( sz>(sqlite3_int64)0x7FFFFFFF ){ - rc = SQLITE_OK; - }else -#endif - do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); - return rc; -} - -/* -** This routine translates a standard POSIX errno code into something -** useful to the clients of the sqlite3 functions. Specifically, it is -** intended to translate a variety of "try again" errors into SQLITE_BUSY -** and a variety of "please close the file descriptor NOW" errors into -** SQLITE_IOERR -** -** Errors during initialization of locks, or file system support for locks, -** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. -*/ -static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { - assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || - (sqliteIOErr == SQLITE_IOERR_UNLOCK) || - (sqliteIOErr == SQLITE_IOERR_RDLOCK) || - (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); - switch (posixError) { - case EACCES: - case EAGAIN: - case ETIMEDOUT: - case EBUSY: - case EINTR: - case ENOLCK: - /* random NFS retry error, unless during file system support - * introspection, in which it actually means what it says */ - return SQLITE_BUSY; - - case EPERM: - return SQLITE_PERM; - - default: - return sqliteIOErr; - } -} - - -/****************************************************************************** -****************** Begin Unique File ID Utility Used By VxWorks *************** -** -** On most versions of unix, we can get a unique ID for a file by concatenating -** the device number and the inode number. But this does not work on VxWorks. -** On VxWorks, a unique file id must be based on the canonical filename. -** -** A pointer to an instance of the following structure can be used as a -** unique file ID in VxWorks. Each instance of this structure contains -** a copy of the canonical filename. There is also a reference count. -** The structure is reclaimed when the number of pointers to it drops to -** zero. -** -** There are never very many files open at one time and lookups are not -** a performance-critical path, so it is sufficient to put these -** structures on a linked list. -*/ -struct vxworksFileId { - struct vxworksFileId *pNext; /* Next in a list of them all */ - int nRef; /* Number of references to this one */ - int nName; /* Length of the zCanonicalName[] string */ - char *zCanonicalName; /* Canonical filename */ -}; - -#if OS_VXWORKS -/* -** All unique filenames are held on a linked list headed by this -** variable: -*/ -static struct vxworksFileId *vxworksFileList = 0; - -/* -** Simplify a filename into its canonical form -** by making the following changes: -** -** * removing any trailing and duplicate / -** * convert /./ into just / -** * convert /A/../ where A is any simple name into just / -** -** Changes are made in-place. Return the new name length. -** -** The original filename is in z[0..n-1]. Return the number of -** characters in the simplified name. -*/ -static int vxworksSimplifyName(char *z, int n){ - int i, j; - while( n>1 && z[n-1]=='/' ){ n--; } - for(i=j=0; i0 && z[j-1]!='/' ){ j--; } - if( j>0 ){ j--; } - i += 2; - continue; - } - } - z[j++] = z[i]; - } - z[j] = 0; - return j; -} - -/* -** Find a unique file ID for the given absolute pathname. Return -** a pointer to the vxworksFileId object. This pointer is the unique -** file ID. -** -** The nRef field of the vxworksFileId object is incremented before -** the object is returned. A new vxworksFileId object is created -** and added to the global list if necessary. -** -** If a memory allocation error occurs, return NULL. -*/ -static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ - struct vxworksFileId *pNew; /* search key and new file ID */ - struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ - int n; /* Length of zAbsoluteName string */ - - assert( zAbsoluteName[0]=='/' ); - n = (int)strlen(zAbsoluteName); - pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); - if( pNew==0 ) return 0; - pNew->zCanonicalName = (char*)&pNew[1]; - memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); - n = vxworksSimplifyName(pNew->zCanonicalName, n); - - /* Search for an existing entry that matching the canonical name. - ** If found, increment the reference count and return a pointer to - ** the existing file ID. - */ - unixEnterMutex(); - for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ - if( pCandidate->nName==n - && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 - ){ - sqlite3_free(pNew); - pCandidate->nRef++; - unixLeaveMutex(); - return pCandidate; - } - } - - /* No match was found. We will make a new file ID */ - pNew->nRef = 1; - pNew->nName = n; - pNew->pNext = vxworksFileList; - vxworksFileList = pNew; - unixLeaveMutex(); - return pNew; -} - -/* -** Decrement the reference count on a vxworksFileId object. Free -** the object when the reference count reaches zero. -*/ -static void vxworksReleaseFileId(struct vxworksFileId *pId){ - unixEnterMutex(); - assert( pId->nRef>0 ); - pId->nRef--; - if( pId->nRef==0 ){ - struct vxworksFileId **pp; - for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} - assert( *pp==pId ); - *pp = pId->pNext; - sqlite3_free(pId); - } - unixLeaveMutex(); -} -#endif /* OS_VXWORKS */ -/*************** End of Unique File ID Utility Used By VxWorks **************** -******************************************************************************/ - - -/****************************************************************************** -*************************** Posix Advisory Locking **************************** -** -** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996) -** section 6.5.2.2 lines 483 through 490 specify that when a process -** sets or clears a lock, that operation overrides any prior locks set -** by the same process. It does not explicitly say so, but this implies -** that it overrides locks set by the same process using a different -** file descriptor. Consider this test case: -** -** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); -** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); -** -** Suppose ./file1 and ./file2 are really the same file (because -** one is a hard or symbolic link to the other) then if you set -** an exclusive lock on fd1, then try to get an exclusive lock -** on fd2, it works. I would have expected the second lock to -** fail since there was already a lock on the file due to fd1. -** But not so. Since both locks came from the same process, the -** second overrides the first, even though they were on different -** file descriptors opened on different file names. -** -** This means that we cannot use POSIX locks to synchronize file access -** among competing threads of the same process. POSIX locks will work fine -** to synchronize access for threads in separate processes, but not -** threads within the same process. -** -** To work around the problem, SQLite has to manage file locks internally -** on its own. Whenever a new database is opened, we have to find the -** specific inode of the database file (the inode is determined by the -** st_dev and st_ino fields of the stat structure that fstat() fills in) -** and check for locks already existing on that inode. When locks are -** created or removed, we have to look at our own internal record of the -** locks to see if another thread has previously set a lock on that same -** inode. -** -** (Aside: The use of inode numbers as unique IDs does not work on VxWorks. -** For VxWorks, we have to use the alternative unique ID system based on -** canonical filename and implemented in the previous division.) -** -** The sqlite3_file structure for POSIX is no longer just an integer file -** descriptor. It is now a structure that holds the integer file -** descriptor and a pointer to a structure that describes the internal -** locks on the corresponding inode. There is one locking structure -** per inode, so if the same inode is opened twice, both unixFile structures -** point to the same locking structure. The locking structure keeps -** a reference count (so we will know when to delete it) and a "cnt" -** field that tells us its internal lock status. cnt==0 means the -** file is unlocked. cnt==-1 means the file has an exclusive lock. -** cnt>0 means there are cnt shared locks on the file. -** -** Any attempt to lock or unlock a file first checks the locking -** structure. The fcntl() system call is only invoked to set a -** POSIX lock if the internal lock structure transitions between -** a locked and an unlocked state. -** -** But wait: there are yet more problems with POSIX advisory locks. -** -** If you close a file descriptor that points to a file that has locks, -** all locks on that file that are owned by the current process are -** released. To work around this problem, each unixInodeInfo object -** maintains a count of the number of pending locks on tha inode. -** When an attempt is made to close an unixFile, if there are -** other unixFile open on the same inode that are holding locks, the call -** to close() the file descriptor is deferred until all of the locks clear. -** The unixInodeInfo structure keeps a list of file descriptors that need to -** be closed and that list is walked (and cleared) when the last lock -** clears. -** -** Yet another problem: LinuxThreads do not play well with posix locks. -** -** Many older versions of linux use the LinuxThreads library which is -** not posix compliant. Under LinuxThreads, a lock created by thread -** A cannot be modified or overridden by a different thread B. -** Only thread A can modify the lock. Locking behavior is correct -** if the appliation uses the newer Native Posix Thread Library (NPTL) -** on linux - with NPTL a lock created by thread A can override locks -** in thread B. But there is no way to know at compile-time which -** threading library is being used. So there is no way to know at -** compile-time whether or not thread A can override locks on thread B. -** One has to do a run-time check to discover the behavior of the -** current process. -** -** SQLite used to support LinuxThreads. But support for LinuxThreads -** was dropped beginning with version 3.7.0. SQLite will still work with -** LinuxThreads provided that (1) there is no more than one connection -** per database file in the same process and (2) database connections -** do not move across threads. -*/ - -/* -** An instance of the following structure serves as the key used -** to locate a particular unixInodeInfo object. -*/ -struct unixFileId { - dev_t dev; /* Device number */ -#if OS_VXWORKS - struct vxworksFileId *pId; /* Unique file ID for vxworks. */ -#else - ino_t ino; /* Inode number */ -#endif -}; - -/* -** An instance of the following structure is allocated for each open -** inode. Or, on LinuxThreads, there is one of these structures for -** each inode opened by each thread. -** -** A single inode can have multiple file descriptors, so each unixFile -** structure contains a pointer to an instance of this object and this -** object keeps a count of the number of unixFile pointing to it. -*/ -struct unixInodeInfo { - struct unixFileId fileId; /* The lookup key */ - int nShared; /* Number of SHARED locks held */ - unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ - unsigned char bProcessLock; /* An exclusive process lock is held */ - int nRef; /* Number of pointers to this structure */ - unixShmNode *pShmNode; /* Shared memory associated with this inode */ - int nLock; /* Number of outstanding file locks */ - UnixUnusedFd *pUnused; /* Unused file descriptors to close */ - unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ - unixInodeInfo *pPrev; /* .... doubly linked */ -#if SQLITE_ENABLE_LOCKING_STYLE - unsigned long long sharedByte; /* for AFP simulated shared lock */ -#endif -#if OS_VXWORKS - sem_t *pSem; /* Named POSIX semaphore */ - char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ -#endif -}; - -/* -** A lists of all unixInodeInfo objects. -*/ -static unixInodeInfo *inodeList = 0; - -/* -** -** This function - unixLogErrorAtLine(), is only ever called via the macro -** unixLogError(). -** -** It is invoked after an error occurs in an OS function and errno has been -** set. It logs a message using sqlite3_log() containing the current value of -** errno and, if possible, the human-readable equivalent from strerror() or -** strerror_r(). -** -** The first argument passed to the macro should be the error code that -** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). -** The two subsequent arguments should be the name of the OS function that -** failed (e.g. "unlink", "open") and the associated file-system path, -** if any. -*/ -#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) -static int unixLogErrorAtLine( - int errcode, /* SQLite error code */ - const char *zFunc, /* Name of OS function that failed */ - const char *zPath, /* File path associated with error */ - int iLine /* Source line number where error occurred */ -){ - char *zErr; /* Message from strerror() or equivalent */ - int iErrno = errno; /* Saved syscall error number */ - - /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use - ** the strerror() function to obtain the human-readable error message - ** equivalent to errno. Otherwise, use strerror_r(). - */ -#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) - char aErr[80]; - memset(aErr, 0, sizeof(aErr)); - zErr = aErr; - - /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, - ** assume that the system provides the GNU version of strerror_r() that - ** returns a pointer to a buffer containing the error message. That pointer - ** may point to aErr[], or it may point to some static storage somewhere. - ** Otherwise, assume that the system provides the POSIX version of - ** strerror_r(), which always writes an error message into aErr[]. - ** - ** If the code incorrectly assumes that it is the POSIX version that is - ** available, the error message will often be an empty string. Not a - ** huge problem. Incorrectly concluding that the GNU version is available - ** could lead to a segfault though. - */ -#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) - zErr = -# endif - strerror_r(iErrno, aErr, sizeof(aErr)-1); - -#elif SQLITE_THREADSAFE - /* This is a threadsafe build, but strerror_r() is not available. */ - zErr = ""; -#else - /* Non-threadsafe build, use strerror(). */ - zErr = strerror(iErrno); -#endif - - if( zPath==0 ) zPath = ""; - sqlite3_log(errcode, - "os_unix.c:%d: (%d) %s(%s) - %s", - iLine, iErrno, zFunc, zPath, zErr - ); - - return errcode; -} - -/* -** Close a file descriptor. -** -** We assume that close() almost always works, since it is only in a -** very sick application or on a very sick platform that it might fail. -** If it does fail, simply leak the file descriptor, but do log the -** error. -** -** Note that it is not safe to retry close() after EINTR since the -** file descriptor might have already been reused by another thread. -** So we don't even try to recover from an EINTR. Just log the error -** and move on. -*/ -static void robust_close(unixFile *pFile, int h, int lineno){ - if( osClose(h) ){ - unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", - pFile ? pFile->zPath : 0, lineno); - } -} - -/* -** Set the pFile->lastErrno. Do this in a subroutine as that provides -** a convenient place to set a breakpoint. -*/ -static void storeLastErrno(unixFile *pFile, int error){ - pFile->lastErrno = error; -} - -/* -** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. -*/ -static void closePendingFds(unixFile *pFile){ - unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *p; - UnixUnusedFd *pNext; - for(p=pInode->pUnused; p; p=pNext){ - pNext = p->pNext; - robust_close(pFile, p->fd, __LINE__); - sqlite3_free(p); - } - pInode->pUnused = 0; -} - -/* -** Release a unixInodeInfo structure previously allocated by findInodeInfo(). -** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. -*/ -static void releaseInodeInfo(unixFile *pFile){ - unixInodeInfo *pInode = pFile->pInode; - assert( unixMutexHeld() ); - if( ALWAYS(pInode) ){ - pInode->nRef--; - if( pInode->nRef==0 ){ - assert( pInode->pShmNode==0 ); - closePendingFds(pFile); - if( pInode->pPrev ){ - assert( pInode->pPrev->pNext==pInode ); - pInode->pPrev->pNext = pInode->pNext; - }else{ - assert( inodeList==pInode ); - inodeList = pInode->pNext; - } - if( pInode->pNext ){ - assert( pInode->pNext->pPrev==pInode ); - pInode->pNext->pPrev = pInode->pPrev; - } - sqlite3_free(pInode); - } - } -} - -/* -** Given a file descriptor, locate the unixInodeInfo object that -** describes that file descriptor. Create a new one if necessary. The -** return value might be uninitialized if an error occurs. -** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. -** -** Return an appropriate error code. -*/ -static int findInodeInfo( - unixFile *pFile, /* Unix file with file desc used in the key */ - unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ -){ - int rc; /* System call return code */ - int fd; /* The file descriptor for pFile */ - struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ - struct stat statbuf; /* Low-level file information */ - unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ - - assert( unixMutexHeld() ); - - /* Get low-level information about the file that we can used to - ** create a unique name for the file. - */ - fd = pFile->h; - rc = osFstat(fd, &statbuf); - if( rc!=0 ){ - storeLastErrno(pFile, errno); -#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS) - if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; -#endif - return SQLITE_IOERR; - } - -#ifdef __APPLE__ - /* On OS X on an msdos filesystem, the inode number is reported - ** incorrectly for zero-size files. See ticket #3260. To work - ** around this problem (we consider it a bug in OS X, not SQLite) - ** we always increase the file size to 1 by writing a single byte - ** prior to accessing the inode number. The one byte written is - ** an ASCII 'S' character which also happens to be the first byte - ** in the header of every SQLite database. In this way, if there - ** is a race condition such that another thread has already populated - ** the first page of the database, no damage is done. - */ - if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ - do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); - if( rc!=1 ){ - storeLastErrno(pFile, errno); - return SQLITE_IOERR; - } - rc = osFstat(fd, &statbuf); - if( rc!=0 ){ - storeLastErrno(pFile, errno); - return SQLITE_IOERR; - } - } -#endif - - memset(&fileId, 0, sizeof(fileId)); - fileId.dev = statbuf.st_dev; -#if OS_VXWORKS - fileId.pId = pFile->pId; -#else - fileId.ino = statbuf.st_ino; -#endif - pInode = inodeList; - while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ - pInode = pInode->pNext; - } - if( pInode==0 ){ - pInode = sqlite3_malloc64( sizeof(*pInode) ); - if( pInode==0 ){ - return SQLITE_NOMEM_BKPT; - } - memset(pInode, 0, sizeof(*pInode)); - memcpy(&pInode->fileId, &fileId, sizeof(fileId)); - pInode->nRef = 1; - pInode->pNext = inodeList; - pInode->pPrev = 0; - if( inodeList ) inodeList->pPrev = pInode; - inodeList = pInode; - }else{ - pInode->nRef++; - } - *ppInode = pInode; - return SQLITE_OK; -} - -/* -** Return TRUE if pFile has been renamed or unlinked since it was first opened. -*/ -static int fileHasMoved(unixFile *pFile){ -#if OS_VXWORKS - return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId; -#else - struct stat buf; - return pFile->pInode!=0 && - (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino); -#endif -} - - -/* -** Check a unixFile that is a database. Verify the following: -** -** (1) There is exactly one hard link on the file -** (2) The file is not a symbolic link -** (3) The file has not been renamed or unlinked -** -** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. -*/ -static void verifyDbFile(unixFile *pFile){ - struct stat buf; - int rc; - - /* These verifications occurs for the main database only */ - if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; - - rc = osFstat(pFile->h, &buf); - if( rc!=0 ){ - sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); - return; - } - if( buf.st_nlink==0 ){ - sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); - return; - } - if( buf.st_nlink>1 ){ - sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); - return; - } - if( fileHasMoved(pFile) ){ - sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); - return; - } -} - - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -*/ -static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; - unixFile *pFile = (unixFile*)id; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - - assert( pFile ); - assert( pFile->eFileLock<=SHARED_LOCK ); - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ - - /* Check if a thread in this process holds such a lock */ - if( pFile->pInode->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. - */ -#ifndef __DJGPP__ - if( !reserved && !pFile->pInode->bProcessLock ){ - struct flock lock; - lock.l_whence = SEEK_SET; - lock.l_start = RESERVED_BYTE; - lock.l_len = 1; - lock.l_type = F_WRLCK; - if( osFcntl(pFile->h, F_GETLK, &lock) ){ - rc = SQLITE_IOERR_CHECKRESERVEDLOCK; - storeLastErrno(pFile, errno); - } else if( lock.l_type!=F_UNLCK ){ - reserved = 1; - } - } -#endif - - unixLeaveMutex(); - OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); - - *pResOut = reserved; - return rc; -} - -/* -** Attempt to set a system-lock on the file pFile. The lock is -** described by pLock. -** -** If the pFile was opened read/write from unix-excl, then the only lock -** ever obtained is an exclusive lock, and it is obtained exactly once -** the first time any lock is attempted. All subsequent system locking -** operations become no-ops. Locking operations still happen internally, -** in order to coordinate access between separate database connections -** within this process, but all of that is handled in memory and the -** operating system does not participate. -** -** This function is a pass-through to fcntl(F_SETLK) if pFile is using -** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" -** and is read-only. -** -** Zero is returned if the call completes successfully, or -1 if a call -** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). -*/ -static int unixFileLock(unixFile *pFile, struct flock *pLock){ - int rc; - unixInodeInfo *pInode = pFile->pInode; - assert( unixMutexHeld() ); - assert( pInode!=0 ); - if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ - if( pInode->bProcessLock==0 ){ - struct flock lock; - assert( pInode->nLock==0 ); - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - lock.l_type = F_WRLCK; - rc = osFcntl(pFile->h, F_SETLK, &lock); - if( rc<0 ) return rc; - pInode->bProcessLock = 1; - pInode->nLock++; - }else{ - rc = 0; - } - }else{ - rc = osFcntl(pFile->h, F_SETLK, pLock); - } - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int unixLock(sqlite3_file *id, int eFileLock){ - /* The following describes the implementation of the various locks and - ** lock transitions in terms of the POSIX advisory shared and exclusive - ** lock primitives (called read-locks and write-locks below, to avoid - ** confusion with SQLite lock names). The algorithms are complicated - ** slightly in order to be compatible with Windows95 systems simultaneously - ** accessing the same database file, in case that is ever required. - ** - ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved - ** byte', each single bytes at well known offsets, and the 'shared byte - ** range', a range of 510 bytes at a well known offset. - ** - ** To obtain a SHARED lock, a read-lock is obtained on the 'pending - ** byte'. If this is successful, 'shared byte range' is read-locked - ** and the lock on the 'pending byte' released. (Legacy note: When - ** SQLite was first developed, Windows95 systems were still very common, - ** and Widnows95 lacks a shared-lock capability. So on Windows95, a - ** single randomly selected by from the 'shared byte range' is locked. - ** Windows95 is now pretty much extinct, but this work-around for the - ** lack of shared-locks on Windows95 lives on, for backwards - ** compatibility.) - ** - ** A process may only obtain a RESERVED lock after it has a SHARED lock. - ** A RESERVED lock is implemented by grabbing a write-lock on the - ** 'reserved byte'. - ** - ** A process may only obtain a PENDING lock after it has obtained a - ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock - ** on the 'pending byte'. This ensures that no new SHARED locks can be - ** obtained, but existing SHARED locks are allowed to persist. A process - ** does not have to obtain a RESERVED lock on the way to a PENDING lock. - ** This property is used by the algorithm for rolling back a journal file - ** after a crash. - ** - ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is - ** implemented by obtaining a write-lock on the entire 'shared byte - ** range'. Since all other locks require a read-lock on one of the bytes - ** within this range, this ensures that no other locks are held on the - ** database. - */ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - unixInodeInfo *pInode; - struct flock lock; - int tErrno = 0; - - assert( pFile ); - OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, - azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, - osGetpid(0))); - - /* If there is already a lock of this type or more restrictive on the - ** unixFile, do nothing. Don't use the end_lock: exit path, as - ** unixEnterMutex() hasn't been called yet. - */ - if( pFile->eFileLock>=eFileLock ){ - OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, - azFileLock(eFileLock))); - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct. - ** (1) We never move from unlocked to anything higher than shared lock. - ** (2) SQLite never explicitly requests a pendig lock. - ** (3) A shared lock is always held when a reserve lock is requested. - */ - assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); - assert( eFileLock!=PENDING_LOCK ); - assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); - - /* This mutex is needed because pFile->pInode is shared across threads - */ - unixEnterMutex(); - pInode = pFile->pInode; - - /* If some thread using this PID has a lock via a different unixFile* - ** handle that precludes the requested lock, return BUSY. - */ - if( (pFile->eFileLock!=pInode->eFileLock && - (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) - ){ - rc = SQLITE_BUSY; - goto end_lock; - } - - /* If a SHARED lock is requested, and some thread using this PID already - ** has a SHARED or RESERVED lock, then increment reference counts and - ** return SQLITE_OK. - */ - if( eFileLock==SHARED_LOCK && - (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ - assert( eFileLock==SHARED_LOCK ); - assert( pFile->eFileLock==0 ); - assert( pInode->nShared>0 ); - pFile->eFileLock = SHARED_LOCK; - pInode->nShared++; - pInode->nLock++; - goto end_lock; - } - - - /* A PENDING lock is needed before acquiring a SHARED lock and before - ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will - ** be released. - */ - lock.l_len = 1L; - lock.l_whence = SEEK_SET; - if( eFileLock==SHARED_LOCK - || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLocknShared==0 ); - assert( pInode->eFileLock==0 ); - assert( rc==SQLITE_OK ); - - /* Now get the read-lock */ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( unixFileLock(pFile, &lock) ){ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - } - - /* Drop the temporary PENDING lock */ - lock.l_start = PENDING_BYTE; - lock.l_len = 1L; - lock.l_type = F_UNLCK; - if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ - /* This could happen with a network mount */ - tErrno = errno; - rc = SQLITE_IOERR_UNLOCK; - } - - if( rc ){ - if( rc!=SQLITE_BUSY ){ - storeLastErrno(pFile, tErrno); - } - goto end_lock; - }else{ - pFile->eFileLock = SHARED_LOCK; - pInode->nLock++; - pInode->nShared = 1; - } - }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ - /* We are trying for an exclusive lock but another thread in this - ** same process is still holding a shared lock. */ - rc = SQLITE_BUSY; - }else{ - /* The request was for a RESERVED or EXCLUSIVE lock. It is - ** assumed that there is a SHARED or greater lock on the file - ** already. - */ - assert( 0!=pFile->eFileLock ); - lock.l_type = F_WRLCK; - - assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); - if( eFileLock==RESERVED_LOCK ){ - lock.l_start = RESERVED_BYTE; - lock.l_len = 1L; - }else{ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - } - - if( unixFileLock(pFile, &lock) ){ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( rc!=SQLITE_BUSY ){ - storeLastErrno(pFile, tErrno); - } - } - } - - -#ifdef SQLITE_DEBUG - /* Set up the transaction-counter change checking flags when - ** transitioning from a SHARED to a RESERVED lock. The change - ** from SHARED to RESERVED marks the beginning of a normal - ** write operation (not a hot journal rollback). - */ - if( rc==SQLITE_OK - && pFile->eFileLock<=SHARED_LOCK - && eFileLock==RESERVED_LOCK - ){ - pFile->transCntrChng = 0; - pFile->dbUpdate = 0; - pFile->inNormalWrite = 1; - } -#endif - - - if( rc==SQLITE_OK ){ - pFile->eFileLock = eFileLock; - pInode->eFileLock = eFileLock; - }else if( eFileLock==EXCLUSIVE_LOCK ){ - pFile->eFileLock = PENDING_LOCK; - pInode->eFileLock = PENDING_LOCK; - } - -end_lock: - unixLeaveMutex(); - OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); - return rc; -} - -/* -** Add the file descriptor used by file handle pFile to the corresponding -** pUnused list. -*/ -static void setPendingFd(unixFile *pFile){ - unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *p = pFile->pUnused; - p->pNext = pInode->pUnused; - pInode->pUnused = p; - pFile->h = -1; - pFile->pUnused = 0; -} - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED -** the byte range is divided into 2 parts and the first part is unlocked then -** set to a read lock, then the other part is simply unlocked. This works -** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to -** remove the write lock on a region when a read lock is set. -*/ -static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ - unixFile *pFile = (unixFile*)id; - unixInodeInfo *pInode; - struct flock lock; - int rc = SQLITE_OK; - - assert( pFile ); - OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, - pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - osGetpid(0))); - - assert( eFileLock<=SHARED_LOCK ); - if( pFile->eFileLock<=eFileLock ){ - return SQLITE_OK; - } - unixEnterMutex(); - pInode = pFile->pInode; - assert( pInode->nShared!=0 ); - if( pFile->eFileLock>SHARED_LOCK ){ - assert( pInode->eFileLock==pFile->eFileLock ); - -#ifdef SQLITE_DEBUG - /* When reducing a lock such that other processes can start - ** reading the database file again, make sure that the - ** transaction counter was updated if any part of the database - ** file changed. If the transaction counter is not updated, - ** other connections to the same file might not realize that - ** the file has changed and hence might not know to flush their - ** cache. The use of a stale cache can lead to database corruption. - */ - pFile->inNormalWrite = 0; -#endif - - /* downgrading to a shared lock on NFS involves clearing the write lock - ** before establishing the readlock - to avoid a race condition we downgrade - ** the lock in 2 blocks, so that part of the range will be covered by a - ** write lock until the rest is covered by a read lock: - ** 1: [WWWWW] - ** 2: [....W] - ** 3: [RRRRW] - ** 4: [RRRR.] - */ - if( eFileLock==SHARED_LOCK ){ -#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE - (void)handleNFSUnlock; - assert( handleNFSUnlock==0 ); -#endif -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE - if( handleNFSUnlock ){ - int tErrno; /* Error code from system call errors */ - off_t divSize = SHARED_SIZE - 1; - - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = divSize; - if( unixFileLock(pFile, &lock)==(-1) ){ - tErrno = errno; - rc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - goto end_unlock; - } - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = divSize; - if( unixFileLock(pFile, &lock)==(-1) ){ - tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } - goto end_unlock; - } - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST+divSize; - lock.l_len = SHARED_SIZE-divSize; - if( unixFileLock(pFile, &lock)==(-1) ){ - tErrno = errno; - rc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - goto end_unlock; - } - }else -#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ - { - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( unixFileLock(pFile, &lock) ){ - /* In theory, the call to unixFileLock() cannot fail because another - ** process is holding an incompatible lock. If it does, this - ** indicates that the other process is not following the locking - ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning - ** SQLITE_BUSY would confuse the upper layer (in practice it causes - ** an assert to fail). */ - rc = SQLITE_IOERR_RDLOCK; - storeLastErrno(pFile, errno); - goto end_unlock; - } - } - } - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = PENDING_BYTE; - lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); - if( unixFileLock(pFile, &lock)==0 ){ - pInode->eFileLock = SHARED_LOCK; - }else{ - rc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, errno); - goto end_unlock; - } - } - if( eFileLock==NO_LOCK ){ - /* Decrement the shared lock counter. Release the lock using an - ** OS call only when all threads in this same process have released - ** the lock. - */ - pInode->nShared--; - if( pInode->nShared==0 ){ - lock.l_type = F_UNLCK; - lock.l_whence = SEEK_SET; - lock.l_start = lock.l_len = 0L; - if( unixFileLock(pFile, &lock)==0 ){ - pInode->eFileLock = NO_LOCK; - }else{ - rc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, errno); - pInode->eFileLock = NO_LOCK; - pFile->eFileLock = NO_LOCK; - } - } - - /* Decrement the count of locks against this same file. When the - ** count reaches zero, close any other file descriptors whose close - ** was deferred because of outstanding locks. - */ - pInode->nLock--; - assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } - } - -end_unlock: - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; - return rc; -} - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int unixUnlock(sqlite3_file *id, int eFileLock){ -#if SQLITE_MAX_MMAP_SIZE>0 - assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); -#endif - return posixUnlock(id, eFileLock, 0); -} - -#if SQLITE_MAX_MMAP_SIZE>0 -static int unixMapfile(unixFile *pFd, i64 nByte); -static void unixUnmapfile(unixFile *pFd); -#endif - -/* -** This function performs the parts of the "close file" operation -** common to all locking schemes. It closes the directory and file -** handles, if they are valid, and sets all fields of the unixFile -** structure to 0. -** -** It is *not* necessary to hold the mutex when this routine is called, -** even on VxWorks. A mutex will be acquired on VxWorks by the -** vxworksReleaseFileId() routine. -*/ -static int closeUnixFile(sqlite3_file *id){ - unixFile *pFile = (unixFile*)id; -#if SQLITE_MAX_MMAP_SIZE>0 - unixUnmapfile(pFile); -#endif - if( pFile->h>=0 ){ - robust_close(pFile, pFile->h, __LINE__); - pFile->h = -1; - } -#if OS_VXWORKS - if( pFile->pId ){ - if( pFile->ctrlFlags & UNIXFILE_DELETE ){ - osUnlink(pFile->pId->zCanonicalName); - } - vxworksReleaseFileId(pFile->pId); - pFile->pId = 0; - } -#endif -#ifdef SQLITE_UNLINK_AFTER_CLOSE - if( pFile->ctrlFlags & UNIXFILE_DELETE ){ - osUnlink(pFile->zPath); - sqlite3_free(*(char**)&pFile->zPath); - pFile->zPath = 0; - } -#endif - OSTRACE(("CLOSE %-3d\n", pFile->h)); - OpenCounter(-1); - sqlite3_free(pFile->pUnused); - memset(pFile, 0, sizeof(unixFile)); - return SQLITE_OK; -} - -/* -** Close a file. -*/ -static int unixClose(sqlite3_file *id){ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile *)id; - verifyDbFile(pFile); - unixUnlock(id, NO_LOCK); - unixEnterMutex(); - - /* unixFile.pInode is always valid here. Otherwise, a different close - ** routine (e.g. nolockClose()) would be called instead. - */ - assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); - if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->pUnused list. It will be automatically closed - ** when the last lock is cleared. - */ - setPendingFd(pFile); - } - releaseInodeInfo(pFile); - rc = closeUnixFile(id); - unixLeaveMutex(); - return rc; -} - -/************** End of the posix advisory lock implementation ***************** -******************************************************************************/ - -/****************************************************************************** -****************************** No-op Locking ********************************** -** -** Of the various locking implementations available, this is by far the -** simplest: locking is ignored. No attempt is made to lock the database -** file for reading or writing. -** -** This locking mode is appropriate for use on read-only databases -** (ex: databases that are burned into CD-ROM, for example.) It can -** also be used if the application employs some external mechanism to -** prevent simultaneous access of the same database by two or more -** database connections. But there is a serious risk of database -** corruption if this locking mode is used in situations where multiple -** database connections are accessing the same database file at the same -** time and one or more of those connections are writing. -*/ - -static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ - UNUSED_PARAMETER(NotUsed); - *pResOut = 0; - return SQLITE_OK; -} -static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - return SQLITE_OK; -} -static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - return SQLITE_OK; -} - -/* -** Close the file. -*/ -static int nolockClose(sqlite3_file *id) { - return closeUnixFile(id); -} - -/******************* End of the no-op lock implementation ********************* -******************************************************************************/ - -/****************************************************************************** -************************* Begin dot-file Locking ****************************** -** -** The dotfile locking implementation uses the existence of separate lock -** files (really a directory) to control access to the database. This works -** on just about every filesystem imaginable. But there are serious downsides: -** -** (1) There is zero concurrency. A single reader blocks all other -** connections from reading or writing the database. -** -** (2) An application crash or power loss can leave stale lock files -** sitting around that need to be cleared manually. -** -** Nevertheless, a dotlock is an appropriate locking mode for use if no -** other locking strategy is available. -** -** Dotfile locking works by creating a subdirectory in the same directory as -** the database and with the same name but with a ".lock" extension added. -** The existence of a lock directory implies an EXCLUSIVE lock. All other -** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. -*/ - -/* -** The file suffix added to the data base filename in order to create the -** lock directory. -*/ -#define DOTLOCK_SUFFIX ".lock" - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -** -** In dotfile locking, either a lock exists or it does not. So in this -** variation of CheckReservedLock(), *pResOut is set to true if any lock -** is held on the file and false if the file is unlocked. -*/ -static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { - int rc = SQLITE_OK; - int reserved = 0; - unixFile *pFile = (unixFile*)id; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - - assert( pFile ); - reserved = osAccess((const char*)pFile->lockingContext, 0)==0; - OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); - *pResOut = reserved; - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -** -** With dotfile locking, we really only support state (4): EXCLUSIVE. -** But we track the other locking levels internally. -*/ -static int dotlockLock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - char *zLockFile = (char *)pFile->lockingContext; - int rc = SQLITE_OK; - - - /* If we have any lock, then the lock file already exists. All we have - ** to do is adjust our internal record of the lock level. - */ - if( pFile->eFileLock > NO_LOCK ){ - pFile->eFileLock = eFileLock; - /* Always update the timestamp on the old file */ -#ifdef HAVE_UTIME - utime(zLockFile, NULL); -#else - utimes(zLockFile, NULL); -#endif - return SQLITE_OK; - } - - /* grab an exclusive lock */ - rc = osMkdir(zLockFile, 0777); - if( rc<0 ){ - /* failed to open/create the lock directory */ - int tErrno = errno; - if( EEXIST == tErrno ){ - rc = SQLITE_BUSY; - } else { - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( rc!=SQLITE_BUSY ){ - storeLastErrno(pFile, tErrno); - } - } - return rc; - } - - /* got it, set the type and return ok */ - pFile->eFileLock = eFileLock; - return rc; -} - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** When the locking level reaches NO_LOCK, delete the lock file. -*/ -static int dotlockUnlock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - char *zLockFile = (char *)pFile->lockingContext; - int rc; - - assert( pFile ); - OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, - pFile->eFileLock, osGetpid(0))); - assert( eFileLock<=SHARED_LOCK ); - - /* no-op if possible */ - if( pFile->eFileLock==eFileLock ){ - return SQLITE_OK; - } - - /* To downgrade to shared, simply update our internal notion of the - ** lock state. No need to mess with the file on disk. - */ - if( eFileLock==SHARED_LOCK ){ - pFile->eFileLock = SHARED_LOCK; - return SQLITE_OK; - } - - /* To fully unlock the database, delete the lock file */ - assert( eFileLock==NO_LOCK ); - rc = osRmdir(zLockFile); - if( rc<0 ){ - int tErrno = errno; - if( tErrno==ENOENT ){ - rc = SQLITE_OK; - }else{ - rc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - } - return rc; - } - pFile->eFileLock = NO_LOCK; - return SQLITE_OK; -} - -/* -** Close a file. Make sure the lock has been released before closing. -*/ -static int dotlockClose(sqlite3_file *id) { - unixFile *pFile = (unixFile*)id; - assert( id!=0 ); - dotlockUnlock(id, NO_LOCK); - sqlite3_free(pFile->lockingContext); - return closeUnixFile(id); -} -/****************** End of the dot-file lock implementation ******************* -******************************************************************************/ - -/****************************************************************************** -************************** Begin flock Locking ******************************** -** -** Use the flock() system call to do file locking. -** -** flock() locking is like dot-file locking in that the various -** fine-grain locking levels supported by SQLite are collapsed into -** a single exclusive lock. In other words, SHARED, RESERVED, and -** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite -** still works when you do this, but concurrency is reduced since -** only a single process can be reading the database at a time. -** -** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off -*/ -#if SQLITE_ENABLE_LOCKING_STYLE - -/* -** Retry flock() calls that fail with EINTR -*/ -#ifdef EINTR -static int robust_flock(int fd, int op){ - int rc; - do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); - return rc; -} -#else -# define robust_flock(a,b) flock(a,b) -#endif - - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -*/ -static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; - unixFile *pFile = (unixFile*)id; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - - assert( pFile ); - - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - /* attempt to get the lock */ - int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); - if( !lrc ){ - /* got the lock, unlock it */ - lrc = robust_flock(pFile->h, LOCK_UN); - if ( lrc ) { - int tErrno = errno; - /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } else { - int tErrno = errno; - reserved = 1; - /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); - -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - *pResOut = reserved; - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** flock() only really support EXCLUSIVE locks. We track intermediate -** lock states in the sqlite3_file structure, but all locks SHARED or -** above are really EXCLUSIVE locks and exclude all other processes from -** access the file. -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int flockLock(sqlite3_file *id, int eFileLock) { - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - - assert( pFile ); - - /* if we already have a lock, it is exclusive. - ** Just adjust level and punt on outta here. */ - if (pFile->eFileLock > NO_LOCK) { - pFile->eFileLock = eFileLock; - return SQLITE_OK; - } - - /* grab an exclusive lock */ - - if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { - int tErrno = errno; - /* didn't get, must be busy */ - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } - } else { - /* got it, set the type and return ok */ - pFile->eFileLock = eFileLock; - } - OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ - rc = SQLITE_BUSY; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - return rc; -} - - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int flockUnlock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - - assert( pFile ); - OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, - pFile->eFileLock, osGetpid(0))); - assert( eFileLock<=SHARED_LOCK ); - - /* no-op if possible */ - if( pFile->eFileLock==eFileLock ){ - return SQLITE_OK; - } - - /* shared can just be set because we always have an exclusive */ - if (eFileLock==SHARED_LOCK) { - pFile->eFileLock = eFileLock; - return SQLITE_OK; - } - - /* no, really, unlock. */ - if( robust_flock(pFile->h, LOCK_UN) ){ -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - return SQLITE_OK; -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - return SQLITE_IOERR_UNLOCK; - }else{ - pFile->eFileLock = NO_LOCK; - return SQLITE_OK; - } -} - -/* -** Close a file. -*/ -static int flockClose(sqlite3_file *id) { - assert( id!=0 ); - flockUnlock(id, NO_LOCK); - return closeUnixFile(id); -} - -#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ - -/******************* End of the flock lock implementation ********************* -******************************************************************************/ - -/****************************************************************************** -************************ Begin Named Semaphore Locking ************************ -** -** Named semaphore locking is only supported on VxWorks. -** -** Semaphore locking is like dot-lock and flock in that it really only -** supports EXCLUSIVE locking. Only a single process can read or write -** the database file at a time. This reduces potential concurrency, but -** makes the lock implementation much easier. -*/ -#if OS_VXWORKS - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -*/ -static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { - int rc = SQLITE_OK; - int reserved = 0; - unixFile *pFile = (unixFile*)id; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - - assert( pFile ); - - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - sem_t *pSem = pFile->pInode->pSem; - - if( sem_trywait(pSem)==-1 ){ - int tErrno = errno; - if( EAGAIN != tErrno ){ - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); - storeLastErrno(pFile, tErrno); - } else { - /* someone else has the lock when we are in NO_LOCK */ - reserved = (pFile->eFileLock < SHARED_LOCK); - } - }else{ - /* we could have it if we want it */ - sem_post(pSem); - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); - - *pResOut = reserved; - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** Semaphore locks only really support EXCLUSIVE locks. We track intermediate -** lock states in the sqlite3_file structure, but all locks SHARED or -** above are really EXCLUSIVE locks and exclude all other processes from -** access the file. -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int semXLock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - sem_t *pSem = pFile->pInode->pSem; - int rc = SQLITE_OK; - - /* if we already have a lock, it is exclusive. - ** Just adjust level and punt on outta here. */ - if (pFile->eFileLock > NO_LOCK) { - pFile->eFileLock = eFileLock; - rc = SQLITE_OK; - goto sem_end_lock; - } - - /* lock semaphore now but bail out when already locked. */ - if( sem_trywait(pSem)==-1 ){ - rc = SQLITE_BUSY; - goto sem_end_lock; - } - - /* got it, set the type and return ok */ - pFile->eFileLock = eFileLock; - - sem_end_lock: - return rc; -} - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int semXUnlock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - sem_t *pSem = pFile->pInode->pSem; - - assert( pFile ); - assert( pSem ); - OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, - pFile->eFileLock, osGetpid(0))); - assert( eFileLock<=SHARED_LOCK ); - - /* no-op if possible */ - if( pFile->eFileLock==eFileLock ){ - return SQLITE_OK; - } - - /* shared can just be set because we always have an exclusive */ - if (eFileLock==SHARED_LOCK) { - pFile->eFileLock = eFileLock; - return SQLITE_OK; - } - - /* no, really unlock. */ - if ( sem_post(pSem)==-1 ) { - int rc, tErrno = errno; - rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } - return rc; - } - pFile->eFileLock = NO_LOCK; - return SQLITE_OK; -} - -/* - ** Close a file. - */ -static int semXClose(sqlite3_file *id) { - if( id ){ - unixFile *pFile = (unixFile*)id; - semXUnlock(id, NO_LOCK); - assert( pFile ); - unixEnterMutex(); - releaseInodeInfo(pFile); - unixLeaveMutex(); - closeUnixFile(id); - } - return SQLITE_OK; -} - -#endif /* OS_VXWORKS */ -/* -** Named semaphore locking is only available on VxWorks. -** -*************** End of the named semaphore lock implementation **************** -******************************************************************************/ - - -/****************************************************************************** -*************************** Begin AFP Locking ********************************* -** -** AFP is the Apple Filing Protocol. AFP is a network filesystem found -** on Apple Macintosh computers - both OS9 and OSX. -** -** Third-party implementations of AFP are available. But this code here -** only works on OSX. -*/ - -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -/* -** The afpLockingContext structure contains all afp lock specific state -*/ -typedef struct afpLockingContext afpLockingContext; -struct afpLockingContext { - int reserved; - const char *dbPath; /* Name of the open file */ -}; - -struct ByteRangeLockPB2 -{ - unsigned long long offset; /* offset to first byte to lock */ - unsigned long long length; /* nbr of bytes to lock */ - unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ - unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ - unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ - int fd; /* file desc to assoc this lock with */ -}; - -#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) - -/* -** This is a utility for setting or clearing a bit-range lock on an -** AFP filesystem. -** -** Return SQLITE_OK on success, SQLITE_BUSY on failure. -*/ -static int afpSetLock( - const char *path, /* Name of the file to be locked or unlocked */ - unixFile *pFile, /* Open file descriptor on path */ - unsigned long long offset, /* First byte to be locked */ - unsigned long long length, /* Number of bytes to lock */ - int setLockFlag /* True to set lock. False to clear lock */ -){ - struct ByteRangeLockPB2 pb; - int err; - - pb.unLockFlag = setLockFlag ? 0 : 1; - pb.startEndFlag = 0; - pb.offset = offset; - pb.length = length; - pb.fd = pFile->h; - - OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", - (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), - offset, length)); - err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); - if ( err==-1 ) { - int rc; - int tErrno = errno; - OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", - path, tErrno, strerror(tErrno))); -#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS - rc = SQLITE_BUSY; -#else - rc = sqliteErrorFromPosixError(tErrno, - setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); -#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ - if( IS_LOCK_ERROR(rc) ){ - storeLastErrno(pFile, tErrno); - } - return rc; - } else { - return SQLITE_OK; - } -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -*/ -static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; - unixFile *pFile = (unixFile*)id; - afpLockingContext *context; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - - assert( pFile ); - context = (afpLockingContext *) pFile->lockingContext; - if( context->reserved ){ - *pResOut = 1; - return SQLITE_OK; - } - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ - - /* Check if a thread in this process holds such a lock */ - if( pFile->pInode->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. - */ - if( !reserved ){ - /* lock the RESERVED byte */ - int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); - if( SQLITE_OK==lrc ){ - /* if we succeeded in taking the reserved lock, unlock it to restore - ** the original state */ - lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); - } else { - /* if we failed to get the lock then someone else must have it */ - reserved = 1; - } - if( IS_LOCK_ERROR(lrc) ){ - rc=lrc; - } - } - - unixLeaveMutex(); - OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); - - *pResOut = reserved; - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int afpLock(sqlite3_file *id, int eFileLock){ - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - unixInodeInfo *pInode = pFile->pInode; - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - - assert( pFile ); - OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, - azFileLock(eFileLock), azFileLock(pFile->eFileLock), - azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); - - /* If there is already a lock of this type or more restrictive on the - ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as - ** unixEnterMutex() hasn't been called yet. - */ - if( pFile->eFileLock>=eFileLock ){ - OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, - azFileLock(eFileLock))); - return SQLITE_OK; - } - - /* Make sure the locking sequence is correct - ** (1) We never move from unlocked to anything higher than shared lock. - ** (2) SQLite never explicitly requests a pendig lock. - ** (3) A shared lock is always held when a reserve lock is requested. - */ - assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); - assert( eFileLock!=PENDING_LOCK ); - assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); - - /* This mutex is needed because pFile->pInode is shared across threads - */ - unixEnterMutex(); - pInode = pFile->pInode; - - /* If some thread using this PID has a lock via a different unixFile* - ** handle that precludes the requested lock, return BUSY. - */ - if( (pFile->eFileLock!=pInode->eFileLock && - (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) - ){ - rc = SQLITE_BUSY; - goto afp_end_lock; - } - - /* If a SHARED lock is requested, and some thread using this PID already - ** has a SHARED or RESERVED lock, then increment reference counts and - ** return SQLITE_OK. - */ - if( eFileLock==SHARED_LOCK && - (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ - assert( eFileLock==SHARED_LOCK ); - assert( pFile->eFileLock==0 ); - assert( pInode->nShared>0 ); - pFile->eFileLock = SHARED_LOCK; - pInode->nShared++; - pInode->nLock++; - goto afp_end_lock; - } - - /* A PENDING lock is needed before acquiring a SHARED lock and before - ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will - ** be released. - */ - if( eFileLock==SHARED_LOCK - || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockdbPath, pFile, PENDING_BYTE, 1, 1); - if (failed) { - rc = failed; - goto afp_end_lock; - } - } - - /* If control gets to this point, then actually go ahead and make - ** operating system calls for the specified lock. - */ - if( eFileLock==SHARED_LOCK ){ - int lrc1, lrc2, lrc1Errno = 0; - long lk, mask; - - assert( pInode->nShared==0 ); - assert( pInode->eFileLock==0 ); - - mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; - /* Now get the read-lock SHARED_LOCK */ - /* note that the quality of the randomness doesn't matter that much */ - lk = random(); - pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); - lrc1 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST+pInode->sharedByte, 1, 1); - if( IS_LOCK_ERROR(lrc1) ){ - lrc1Errno = pFile->lastErrno; - } - /* Drop the temporary PENDING lock */ - lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - - if( IS_LOCK_ERROR(lrc1) ) { - storeLastErrno(pFile, lrc1Errno); - rc = lrc1; - goto afp_end_lock; - } else if( IS_LOCK_ERROR(lrc2) ){ - rc = lrc2; - goto afp_end_lock; - } else if( lrc1 != SQLITE_OK ) { - rc = lrc1; - } else { - pFile->eFileLock = SHARED_LOCK; - pInode->nLock++; - pInode->nShared = 1; - } - }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ - /* We are trying for an exclusive lock but another thread in this - ** same process is still holding a shared lock. */ - rc = SQLITE_BUSY; - }else{ - /* The request was for a RESERVED or EXCLUSIVE lock. It is - ** assumed that there is a SHARED or greater lock on the file - ** already. - */ - int failed = 0; - assert( 0!=pFile->eFileLock ); - if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { - /* Acquire a RESERVED lock */ - failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); - if( !failed ){ - context->reserved = 1; - } - } - if (!failed && eFileLock == EXCLUSIVE_LOCK) { - /* Acquire an EXCLUSIVE lock */ - - /* Remove the shared lock before trying the range. we'll need to - ** reestablish the shared lock if we can't get the afpUnlock - */ - if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + - pInode->sharedByte, 1, 0)) ){ - int failed2 = SQLITE_OK; - /* now attemmpt to get the exclusive lock range */ - failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, - SHARED_SIZE, 1); - if( failed && (failed2 = afpSetLock(context->dbPath, pFile, - SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ - /* Can't reestablish the shared lock. Sqlite can't deal, this is - ** a critical I/O error - */ - rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : - SQLITE_IOERR_LOCK; - goto afp_end_lock; - } - }else{ - rc = failed; - } - } - if( failed ){ - rc = failed; - } - } - - if( rc==SQLITE_OK ){ - pFile->eFileLock = eFileLock; - pInode->eFileLock = eFileLock; - }else if( eFileLock==EXCLUSIVE_LOCK ){ - pFile->eFileLock = PENDING_LOCK; - pInode->eFileLock = PENDING_LOCK; - } - -afp_end_lock: - unixLeaveMutex(); - OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), - rc==SQLITE_OK ? "ok" : "failed")); - return rc; -} - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int afpUnlock(sqlite3_file *id, int eFileLock) { - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - unixInodeInfo *pInode; - afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - int skipShared = 0; -#ifdef SQLITE_TEST - int h = pFile->h; -#endif - - assert( pFile ); - OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, - pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, - osGetpid(0))); - - assert( eFileLock<=SHARED_LOCK ); - if( pFile->eFileLock<=eFileLock ){ - return SQLITE_OK; - } - unixEnterMutex(); - pInode = pFile->pInode; - assert( pInode->nShared!=0 ); - if( pFile->eFileLock>SHARED_LOCK ){ - assert( pInode->eFileLock==pFile->eFileLock ); - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); - -#ifdef SQLITE_DEBUG - /* When reducing a lock such that other processes can start - ** reading the database file again, make sure that the - ** transaction counter was updated if any part of the database - ** file changed. If the transaction counter is not updated, - ** other connections to the same file might not realize that - ** the file has changed and hence might not know to flush their - ** cache. The use of a stale cache can lead to database corruption. - */ - assert( pFile->inNormalWrite==0 - || pFile->dbUpdate==0 - || pFile->transCntrChng==1 ); - pFile->inNormalWrite = 0; -#endif - - if( pFile->eFileLock==EXCLUSIVE_LOCK ){ - rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); - if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ - /* only re-establish the shared lock if necessary */ - int sharedLockByte = SHARED_FIRST+pInode->sharedByte; - rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); - } else { - skipShared = 1; - } - } - if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ - rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - } - if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ - rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); - if( !rc ){ - context->reserved = 0; - } - } - if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ - pInode->eFileLock = SHARED_LOCK; - } - } - if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ - - /* Decrement the shared lock counter. Release the lock using an - ** OS call only when all threads in this same process have released - ** the lock. - */ - unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; - pInode->nShared--; - if( pInode->nShared==0 ){ - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); - if( !skipShared ){ - rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); - } - if( !rc ){ - pInode->eFileLock = NO_LOCK; - pFile->eFileLock = NO_LOCK; - } - } - if( rc==SQLITE_OK ){ - pInode->nLock--; - assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } - } - } - - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; - return rc; -} - -/* -** Close a file & cleanup AFP specific locking context -*/ -static int afpClose(sqlite3_file *id) { - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - assert( id!=0 ); - afpUnlock(id, NO_LOCK); - unixEnterMutex(); - if( pFile->pInode && pFile->pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - setPendingFd(pFile); - } - releaseInodeInfo(pFile); - sqlite3_free(pFile->lockingContext); - rc = closeUnixFile(id); - unixLeaveMutex(); - return rc; -} - -#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ -/* -** The code above is the AFP lock implementation. The code is specific -** to MacOSX and does not work on other unix platforms. No alternative -** is available. If you don't compile for a mac, then the "unix-afp" -** VFS is not available. -** -********************* End of the AFP lock implementation ********************** -******************************************************************************/ - -/****************************************************************************** -*************************** Begin NFS Locking ********************************/ - -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -/* - ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock - ** must be either NO_LOCK or SHARED_LOCK. - ** - ** If the locking level of the file descriptor is already at or below - ** the requested locking level, this routine is a no-op. - */ -static int nfsUnlock(sqlite3_file *id, int eFileLock){ - return posixUnlock(id, eFileLock, 1); -} - -#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ -/* -** The code above is the NFS lock implementation. The code is specific -** to MacOSX and does not work on other unix platforms. No alternative -** is available. -** -********************* End of the NFS lock implementation ********************** -******************************************************************************/ - -/****************************************************************************** -**************** Non-locking sqlite3_file methods ***************************** -** -** The next division contains implementations for all methods of the -** sqlite3_file object other than the locking methods. The locking -** methods were defined in divisions above (one locking method per -** division). Those methods that are common to all locking modes -** are gather together into this division. -*/ - -/* -** Seek to the offset passed as the second argument, then read cnt -** bytes into pBuf. Return the number of bytes actually read. -** -** NB: If you define USE_PREAD or USE_PREAD64, then it might also -** be necessary to define _XOPEN_SOURCE to be 500. This varies from -** one system to another. Since SQLite does not define USE_PREAD -** in any form by default, we will not attempt to define _XOPEN_SOURCE. -** See tickets #2741 and #2681. -** -** To avoid stomping the errno value on a failed read the lastErrno value -** is set before returning. -*/ -static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ - int got; - int prior = 0; -#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) - i64 newOffset; -#endif - TIMER_START; - assert( cnt==(cnt&0x1ffff) ); - assert( id->h>2 ); - do{ -#if defined(USE_PREAD) - got = osPread(id->h, pBuf, cnt, offset); - SimulateIOError( got = -1 ); -#elif defined(USE_PREAD64) - got = osPread64(id->h, pBuf, cnt, offset); - SimulateIOError( got = -1 ); -#else - newOffset = lseek(id->h, offset, SEEK_SET); - SimulateIOError( newOffset = -1 ); - if( newOffset<0 ){ - storeLastErrno((unixFile*)id, errno); - return -1; - } - got = osRead(id->h, pBuf, cnt); -#endif - if( got==cnt ) break; - if( got<0 ){ - if( errno==EINTR ){ got = 1; continue; } - prior = 0; - storeLastErrno((unixFile*)id, errno); - break; - }else if( got>0 ){ - cnt -= got; - offset += got; - prior += got; - pBuf = (void*)(got + (char*)pBuf); - } - }while( got>0 ); - TIMER_END; - OSTRACE(("READ %-3d %5d %7lld %llu\n", - id->h, got+prior, offset-prior, TIMER_ELAPSED)); - return got+prior; -} - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -static int unixRead( - sqlite3_file *id, - void *pBuf, - int amt, - sqlite3_int64 offset -){ - unixFile *pFile = (unixFile *)id; - int got; - assert( id ); - assert( offset>=0 ); - assert( amt>0 ); - - /* If this is a database file (not a journal, master-journal or temp - ** file), the bytes in the locking range should never be read or written. */ -#if 0 - assert( pFile->pUnused==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE - ); -#endif - -#if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transfering - ** data from the memory mapping using memcpy(). */ - if( offsetmmapSize ){ - if( offset+amt <= pFile->mmapSize ){ - memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); - return SQLITE_OK; - }else{ - int nCopy = pFile->mmapSize - offset; - memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); - pBuf = &((u8 *)pBuf)[nCopy]; - amt -= nCopy; - offset += nCopy; - } - } -#endif - - got = seekAndRead(pFile, offset, pBuf, amt); - if( got==amt ){ - return SQLITE_OK; - }else if( got<0 ){ - /* lastErrno set by seekAndRead */ - return SQLITE_IOERR_READ; - }else{ - storeLastErrno(pFile, 0); /* not a system error */ - /* Unread parts of the buffer must be zero-filled */ - memset(&((char*)pBuf)[got], 0, amt-got); - return SQLITE_IOERR_SHORT_READ; - } -} - -/* -** Attempt to seek the file-descriptor passed as the first argument to -** absolute offset iOff, then attempt to write nBuf bytes of data from -** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, -** return the actual number of bytes written (which may be less than -** nBuf). -*/ -static int seekAndWriteFd( - int fd, /* File descriptor to write to */ - i64 iOff, /* File offset to begin writing at */ - const void *pBuf, /* Copy data from this buffer to the file */ - int nBuf, /* Size of buffer pBuf in bytes */ - int *piErrno /* OUT: Error number if error occurs */ -){ - int rc = 0; /* Value returned by system call */ - - assert( nBuf==(nBuf&0x1ffff) ); - assert( fd>2 ); - assert( piErrno!=0 ); - nBuf &= 0x1ffff; - TIMER_START; - -#if defined(USE_PREAD) - do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); -#elif defined(USE_PREAD64) - do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); -#else - do{ - i64 iSeek = lseek(fd, iOff, SEEK_SET); - SimulateIOError( iSeek = -1 ); - if( iSeek<0 ){ - rc = -1; - break; - } - rc = osWrite(fd, pBuf, nBuf); - }while( rc<0 && errno==EINTR ); -#endif - - TIMER_END; - OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); - - if( rc<0 ) *piErrno = errno; - return rc; -} - - -/* -** Seek to the offset in id->offset then read cnt bytes into pBuf. -** Return the number of bytes actually read. Update the offset. -** -** To avoid stomping the errno value on a failed write the lastErrno value -** is set before returning. -*/ -static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ - return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno); -} - - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -static int unixWrite( - sqlite3_file *id, - const void *pBuf, - int amt, - sqlite3_int64 offset -){ - unixFile *pFile = (unixFile*)id; - int wrote = 0; - assert( id ); - assert( amt>0 ); - - /* If this is a database file (not a journal, master-journal or temp - ** file), the bytes in the locking range should never be read or written. */ -#if 0 - assert( pFile->pUnused==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE - ); -#endif - -#ifdef SQLITE_DEBUG - /* If we are doing a normal write to a database file (as opposed to - ** doing a hot-journal rollback or a write to some file other than a - ** normal database file) then record the fact that the database - ** has changed. If the transaction counter is modified, record that - ** fact too. - */ - if( pFile->inNormalWrite ){ - pFile->dbUpdate = 1; /* The database has been modified */ - if( offset<=24 && offset+amt>=27 ){ - int rc; - char oldCntr[4]; - SimulateIOErrorBenign(1); - rc = seekAndRead(pFile, 24, oldCntr, 4); - SimulateIOErrorBenign(0); - if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ - pFile->transCntrChng = 1; /* The transaction counter has changed */ - } - } - } -#endif - -#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this write request as possible by transfering - ** data from the memory mapping using memcpy(). */ - if( offsetmmapSize ){ - if( offset+amt <= pFile->mmapSize ){ - memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); - return SQLITE_OK; - }else{ - int nCopy = pFile->mmapSize - offset; - memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); - pBuf = &((u8 *)pBuf)[nCopy]; - amt -= nCopy; - offset += nCopy; - } - } -#endif - - while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){ - amt -= wrote; - offset += wrote; - pBuf = &((char*)pBuf)[wrote]; - } - SimulateIOError(( wrote=(-1), amt=1 )); - SimulateDiskfullError(( wrote=0, amt=1 )); - - if( amt>wrote ){ - if( wrote<0 && pFile->lastErrno!=ENOSPC ){ - /* lastErrno set by seekAndWrite */ - return SQLITE_IOERR_WRITE; - }else{ - storeLastErrno(pFile, 0); /* not a system error */ - return SQLITE_FULL; - } - } - - return SQLITE_OK; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occurring at the right times. -*/ -SQLITE_API int sqlite3_sync_count = 0; -SQLITE_API int sqlite3_fullsync_count = 0; -#endif - -/* -** We do not trust systems to provide a working fdatasync(). Some do. -** Others do no. To be safe, we will stick with the (slightly slower) -** fsync(). If you know that your system does support fdatasync() correctly, -** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC -*/ -#if !defined(fdatasync) && !HAVE_FDATASYNC -# define fdatasync fsync -#endif - -/* -** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not -** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently -** only available on Mac OS X. But that could change. -*/ -#ifdef F_FULLFSYNC -# define HAVE_FULLFSYNC 1 -#else -# define HAVE_FULLFSYNC 0 -#endif - - -/* -** The fsync() system call does not work as advertised on many -** unix systems. The following procedure is an attempt to make -** it work better. -** -** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful -** for testing when we want to run through the test suite quickly. -** You are strongly advised *not* to deploy with SQLITE_NO_SYNC -** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash -** or power failure will likely corrupt the database file. -** -** SQLite sets the dataOnly flag if the size of the file is unchanged. -** The idea behind dataOnly is that it should only write the file content -** to disk, not the inode. We only set dataOnly if the file size is -** unchanged since the file size is part of the inode. However, -** Ted Ts'o tells us that fdatasync() will also write the inode if the -** file size has changed. The only real difference between fdatasync() -** and fsync(), Ted tells us, is that fdatasync() will not flush the -** inode if the mtime or owner or other inode attributes have changed. -** We only care about the file size, not the other file attributes, so -** as far as SQLite is concerned, an fdatasync() is always adequate. -** So, we always use fdatasync() if it is available, regardless of -** the value of the dataOnly flag. -*/ -static int full_fsync(int fd, int fullSync, int dataOnly){ - int rc; - - /* The following "ifdef/elif/else/" block has the same structure as - ** the one below. It is replicated here solely to avoid cluttering - ** up the real code with the UNUSED_PARAMETER() macros. - */ -#ifdef SQLITE_NO_SYNC - UNUSED_PARAMETER(fd); - UNUSED_PARAMETER(fullSync); - UNUSED_PARAMETER(dataOnly); -#elif HAVE_FULLFSYNC - UNUSED_PARAMETER(dataOnly); -#else - UNUSED_PARAMETER(fullSync); - UNUSED_PARAMETER(dataOnly); -#endif - - /* Record the number of times that we do a normal fsync() and - ** FULLSYNC. This is used during testing to verify that this procedure - ** gets called with the correct arguments. - */ -#ifdef SQLITE_TEST - if( fullSync ) sqlite3_fullsync_count++; - sqlite3_sync_count++; -#endif - - /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a - ** no-op. But go ahead and call fstat() to validate the file - ** descriptor as we need a method to provoke a failure during - ** coverate testing. - */ -#ifdef SQLITE_NO_SYNC - { - struct stat buf; - rc = osFstat(fd, &buf); - } -#elif HAVE_FULLFSYNC - if( fullSync ){ - rc = osFcntl(fd, F_FULLFSYNC, 0); - }else{ - rc = 1; - } - /* If the FULLFSYNC failed, fall back to attempting an fsync(). - ** It shouldn't be possible for fullfsync to fail on the local - ** file system (on OSX), so failure indicates that FULLFSYNC - ** isn't supported for this file system. So, attempt an fsync - ** and (for now) ignore the overhead of a superfluous fcntl call. - ** It'd be better to detect fullfsync support once and avoid - ** the fcntl call every time sync is called. - */ - if( rc ) rc = fsync(fd); - -#elif defined(__APPLE__) - /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly - ** so currently we default to the macro that redefines fdatasync to fsync - */ - rc = fsync(fd); -#else - rc = fdatasync(fd); -#if OS_VXWORKS - if( rc==-1 && errno==ENOTSUP ){ - rc = fsync(fd); - } -#endif /* OS_VXWORKS */ -#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */ - - if( OS_VXWORKS && rc!= -1 ){ - rc = 0; - } - return rc; -} - -/* -** Open a file descriptor to the directory containing file zFilename. -** If successful, *pFd is set to the opened file descriptor and -** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM -** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined -** value. -** -** The directory file descriptor is used for only one thing - to -** fsync() a directory to make sure file creation and deletion events -** are flushed to disk. Such fsyncs are not needed on newer -** journaling filesystems, but are required on older filesystems. -** -** This routine can be overridden using the xSetSysCall interface. -** The ability to override this routine was added in support of the -** chromium sandbox. Opening a directory is a security risk (we are -** told) so making it overrideable allows the chromium sandbox to -** replace this routine with a harmless no-op. To make this routine -** a no-op, replace it with a stub that returns SQLITE_OK but leaves -** *pFd set to a negative number. -** -** If SQLITE_OK is returned, the caller is responsible for closing -** the file descriptor *pFd using close(). -*/ -static int openDirectory(const char *zFilename, int *pFd){ - int ii; - int fd = -1; - char zDirname[MAX_PATHNAME+1]; - - sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); - for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--); - if( ii>0 ){ - zDirname[ii] = '\0'; - }else{ - if( zDirname[0]!='/' ) zDirname[0] = '.'; - zDirname[1] = 0; - } - fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); - if( fd>=0 ){ - OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); - } - *pFd = fd; - if( fd>=0 ) return SQLITE_OK; - return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname); -} - -/* -** Make sure all writes to a particular file are committed to disk. -** -** If dataOnly==0 then both the file itself and its metadata (file -** size, access time, etc) are synced. If dataOnly!=0 then only the -** file data is synced. -** -** Under Unix, also make sure that the directory entry for the file -** has been created by fsync-ing the directory that contains the file. -** If we do not do this and we encounter a power failure, the directory -** entry for the journal might not exist after we reboot. The next -** SQLite to access the file will not know that the journal exists (because -** the directory entry for the journal was never created) and the transaction -** will not roll back - possibly leading to database corruption. -*/ -static int unixSync(sqlite3_file *id, int flags){ - int rc; - unixFile *pFile = (unixFile*)id; - - int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); - int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; - - /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ - assert((flags&0x0F)==SQLITE_SYNC_NORMAL - || (flags&0x0F)==SQLITE_SYNC_FULL - ); - - /* Unix cannot, but some systems may return SQLITE_FULL from here. This - ** line is to test that doing so does not cause any problems. - */ - SimulateDiskfullError( return SQLITE_FULL ); - - assert( pFile ); - OSTRACE(("SYNC %-3d\n", pFile->h)); - rc = full_fsync(pFile->h, isFullsync, isDataOnly); - SimulateIOError( rc=1 ); - if( rc ){ - storeLastErrno(pFile, errno); - return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); - } - - /* Also fsync the directory containing the file if the DIRSYNC flag - ** is set. This is a one-time occurrence. Many systems (examples: AIX) - ** are unable to fsync a directory, so ignore errors on the fsync. - */ - if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ - int dirfd; - OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, - HAVE_FULLFSYNC, isFullsync)); - rc = osOpenDirectory(pFile->zPath, &dirfd); - if( rc==SQLITE_OK ){ - full_fsync(dirfd, 0, 0); - robust_close(pFile, dirfd, __LINE__); - }else{ - assert( rc==SQLITE_CANTOPEN ); - rc = SQLITE_OK; - } - pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; - } - return rc; -} - -/* -** Truncate an open file to a specified size -*/ -static int unixTruncate(sqlite3_file *id, i64 nByte){ - unixFile *pFile = (unixFile *)id; - int rc; - assert( pFile ); - SimulateIOError( return SQLITE_IOERR_TRUNCATE ); - - /* If the user has configured a chunk-size for this file, truncate the - ** file so that it consists of an integer number of chunks (i.e. the - ** actual file size after the operation may be larger than the requested - ** size). - */ - if( pFile->szChunk>0 ){ - nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; - } - - rc = robust_ftruncate(pFile->h, nByte); - if( rc ){ - storeLastErrno(pFile, errno); - return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); - }else{ -#ifdef SQLITE_DEBUG - /* If we are doing a normal write to a database file (as opposed to - ** doing a hot-journal rollback or a write to some file other than a - ** normal database file) and we truncate the file to zero length, - ** that effectively updates the change counter. This might happen - ** when restoring a database using the backup API from a zero-length - ** source. - */ - if( pFile->inNormalWrite && nByte==0 ){ - pFile->transCntrChng = 1; - } -#endif - -#if SQLITE_MAX_MMAP_SIZE>0 - /* If the file was just truncated to a size smaller than the currently - ** mapped region, reduce the effective mapping size as well. SQLite will - ** use read() and write() to access data beyond this point from now on. - */ - if( nBytemmapSize ){ - pFile->mmapSize = nByte; - } -#endif - - return SQLITE_OK; - } -} - -/* -** Determine the current size of a file in bytes -*/ -static int unixFileSize(sqlite3_file *id, i64 *pSize){ - int rc; - struct stat buf; - assert( id ); - rc = osFstat(((unixFile*)id)->h, &buf); - SimulateIOError( rc=1 ); - if( rc!=0 ){ - storeLastErrno((unixFile*)id, errno); - return SQLITE_IOERR_FSTAT; - } - *pSize = buf.st_size; - - /* When opening a zero-size database, the findInodeInfo() procedure - ** writes a single byte into that file in order to work around a bug - ** in the OS-X msdos filesystem. In order to avoid problems with upper - ** layers, we need to report this file size as zero even though it is - ** really 1. Ticket #3260. - */ - if( *pSize==1 ) *pSize = 0; - - - return SQLITE_OK; -} - -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) -/* -** Handler for proxy-locking file-control verbs. Defined below in the -** proxying locking division. -*/ -static int proxyFileControl(sqlite3_file*,int,void*); -#endif - -/* -** This function is called to handle the SQLITE_FCNTL_SIZE_HINT -** file-control operation. Enlarge the database to nBytes in size -** (rounded up to the next chunk-size). If the database is already -** nBytes or larger, this routine is a no-op. -*/ -static int fcntlSizeHint(unixFile *pFile, i64 nByte){ - if( pFile->szChunk>0 ){ - i64 nSize; /* Required file size */ - struct stat buf; /* Used to hold return values of fstat() */ - - if( osFstat(pFile->h, &buf) ){ - return SQLITE_IOERR_FSTAT; - } - - nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; - if( nSize>(i64)buf.st_size ){ - -#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE - /* The code below is handling the return value of osFallocate() - ** correctly. posix_fallocate() is defined to "returns zero on success, - ** or an error number on failure". See the manpage for details. */ - int err; - do{ - err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); - }while( err==EINTR ); - if( err ) return SQLITE_IOERR_WRITE; -#else - /* If the OS does not have posix_fallocate(), fake it. Write a - ** single byte to the last byte in each block that falls entirely - ** within the extended region. Then, if required, a single byte - ** at offset (nSize-1), to set the size of the file correctly. - ** This is a similar technique to that used by glibc on systems - ** that do not have a real fallocate() call. - */ - int nBlk = buf.st_blksize; /* File-system block size */ - int nWrite = 0; /* Number of bytes written by seekAndWrite */ - i64 iWrite; /* Next offset to write to */ - - iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1; - assert( iWrite>=buf.st_size ); - assert( ((iWrite+1)%nBlk)==0 ); - for(/*no-op*/; iWrite=nSize ) iWrite = nSize - 1; - nWrite = seekAndWrite(pFile, iWrite, "", 1); - if( nWrite!=1 ) return SQLITE_IOERR_WRITE; - } -#endif - } - } - -#if SQLITE_MAX_MMAP_SIZE>0 - if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ - int rc; - if( pFile->szChunk<=0 ){ - if( robust_ftruncate(pFile->h, nByte) ){ - storeLastErrno(pFile, errno); - return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); - } - } - - rc = unixMapfile(pFile, nByte); - return rc; - } -#endif - - return SQLITE_OK; -} - -/* -** If *pArg is initially negative then this is a query. Set *pArg to -** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. -** -** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. -*/ -static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ - if( *pArg<0 ){ - *pArg = (pFile->ctrlFlags & mask)!=0; - }else if( (*pArg)==0 ){ - pFile->ctrlFlags &= ~mask; - }else{ - pFile->ctrlFlags |= mask; - } -} - -/* Forward declaration */ -static int unixGetTempname(int nBuf, char *zBuf); - -/* -** Information and control of an open file handle. -*/ -static int unixFileControl(sqlite3_file *id, int op, void *pArg){ - unixFile *pFile = (unixFile*)id; - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = pFile->eFileLock; - return SQLITE_OK; - } - case SQLITE_FCNTL_LAST_ERRNO: { - *(int*)pArg = pFile->lastErrno; - return SQLITE_OK; - } - case SQLITE_FCNTL_CHUNK_SIZE: { - pFile->szChunk = *(int *)pArg; - return SQLITE_OK; - } - case SQLITE_FCNTL_SIZE_HINT: { - int rc; - SimulateIOErrorBenign(1); - rc = fcntlSizeHint(pFile, *(i64 *)pArg); - SimulateIOErrorBenign(0); - return rc; - } - case SQLITE_FCNTL_PERSIST_WAL: { - unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); - return SQLITE_OK; - } - case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { - unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); - return SQLITE_OK; - } - case SQLITE_FCNTL_VFSNAME: { - *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); - return SQLITE_OK; - } - case SQLITE_FCNTL_TEMPFILENAME: { - char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); - if( zTFile ){ - unixGetTempname(pFile->pVfs->mxPathname, zTFile); - *(char**)pArg = zTFile; - } - return SQLITE_OK; - } - case SQLITE_FCNTL_HAS_MOVED: { - *(int*)pArg = fileHasMoved(pFile); - return SQLITE_OK; - } -#if SQLITE_MAX_MMAP_SIZE>0 - case SQLITE_FCNTL_MMAP_SIZE: { - i64 newLimit = *(i64*)pArg; - int rc = SQLITE_OK; - if( newLimit>sqlite3GlobalConfig.mxMmap ){ - newLimit = sqlite3GlobalConfig.mxMmap; - } - *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ - pFile->mmapSizeMax = newLimit; - if( pFile->mmapSize>0 ){ - unixUnmapfile(pFile); - rc = unixMapfile(pFile, -1); - } - } - return rc; - } -#endif -#ifdef SQLITE_DEBUG - /* The pager calls this method to signal that it has done - ** a rollback and that the database is therefore unchanged and - ** it hence it is OK for the transaction change counter to be - ** unchanged. - */ - case SQLITE_FCNTL_DB_UNCHANGED: { - ((unixFile*)id)->dbUpdate = 0; - return SQLITE_OK; - } -#endif -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - case SQLITE_FCNTL_SET_LOCKPROXYFILE: - case SQLITE_FCNTL_GET_LOCKPROXYFILE: { - return proxyFileControl(id,op,pArg); - } -#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ - } - return SQLITE_NOTFOUND; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and its journal file) that the sector size will be the -** same for both. -*/ -#ifndef __QNXNTO__ -static int unixSectorSize(sqlite3_file *NotUsed){ - UNUSED_PARAMETER(NotUsed); - return SQLITE_DEFAULT_SECTOR_SIZE; -} -#endif - -/* -** The following version of unixSectorSize() is optimized for QNX. -*/ -#ifdef __QNXNTO__ -#include -#include -static int unixSectorSize(sqlite3_file *id){ - unixFile *pFile = (unixFile*)id; - if( pFile->sectorSize == 0 ){ - struct statvfs fsInfo; - - /* Set defaults for non-supported filesystems */ - pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; - pFile->deviceCharacteristics = 0; - if( fstatvfs(pFile->h, &fsInfo) == -1 ) { - return pFile->sectorSize; - } - - if( !strcmp(fsInfo.f_basetype, "tmp") ) { - pFile->sectorSize = fsInfo.f_bsize; - pFile->deviceCharacteristics = - SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ - SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until - ** the write succeeds */ - SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind - ** so it is ordered */ - 0; - }else if( strstr(fsInfo.f_basetype, "etfs") ){ - pFile->sectorSize = fsInfo.f_bsize; - pFile->deviceCharacteristics = - /* etfs cluster size writes are atomic */ - (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | - SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until - ** the write succeeds */ - SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind - ** so it is ordered */ - 0; - }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ - pFile->sectorSize = fsInfo.f_bsize; - pFile->deviceCharacteristics = - SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ - SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until - ** the write succeeds */ - SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind - ** so it is ordered */ - 0; - }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ - pFile->sectorSize = fsInfo.f_bsize; - pFile->deviceCharacteristics = - /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | - SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind - ** so it is ordered */ - 0; - }else if( strstr(fsInfo.f_basetype, "dos") ){ - pFile->sectorSize = fsInfo.f_bsize; - pFile->deviceCharacteristics = - /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | - SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind - ** so it is ordered */ - 0; - }else{ - pFile->deviceCharacteristics = - SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ - SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until - ** the write succeeds */ - 0; - } - } - /* Last chance verification. If the sector size isn't a multiple of 512 - ** then it isn't valid.*/ - if( pFile->sectorSize % 512 != 0 ){ - pFile->deviceCharacteristics = 0; - pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; - } - return pFile->sectorSize; -} -#endif /* __QNXNTO__ */ - -/* -** Return the device characteristics for the file. -** -** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. -** However, that choice is controversial since technically the underlying -** file system does not always provide powersafe overwrites. (In other -** words, after a power-loss event, parts of the file that were never -** written might end up being altered.) However, non-PSOW behavior is very, -** very rare. And asserting PSOW makes a large reduction in the amount -** of required I/O for journaling, since a lot of padding is eliminated. -** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control -** available to turn it off and URI query parameter available to turn it off. -*/ -static int unixDeviceCharacteristics(sqlite3_file *id){ - unixFile *p = (unixFile*)id; - int rc = 0; -#ifdef __QNXNTO__ - if( p->sectorSize==0 ) unixSectorSize(id); - rc = p->deviceCharacteristics; -#endif - if( p->ctrlFlags & UNIXFILE_PSOW ){ - rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; - } - return rc; -} - -#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - -/* -** Return the system page size. -** -** This function should not be called directly by other code in this file. -** Instead, it should be called via macro osGetpagesize(). -*/ -static int unixGetpagesize(void){ -#if OS_VXWORKS - return 1024; -#elif defined(_BSD_SOURCE) - return getpagesize(); -#else - return (int)sysconf(_SC_PAGESIZE); -#endif -} - -#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ - -#ifndef SQLITE_OMIT_WAL - -/* -** Object used to represent an shared memory buffer. -** -** When multiple threads all reference the same wal-index, each thread -** has its own unixShm object, but they all point to a single instance -** of this unixShmNode object. In other words, each wal-index is opened -** only once per process. -** -** Each unixShmNode object is connected to a single unixInodeInfo object. -** We could coalesce this object into unixInodeInfo, but that would mean -** every open file that does not use shared memory (in other words, most -** open files) would have to carry around this extra information. So -** the unixInodeInfo object contains a pointer to this unixShmNode object -** and the unixShmNode object is created only when needed. -** -** unixMutexHeld() must be true when creating or destroying -** this object or while reading or writing the following fields: -** -** nRef -** -** The following fields are read-only after the object is created: -** -** fid -** zFilename -** -** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and -** unixMutexHeld() is true when reading or writing any other field -** in this structure. -*/ -struct unixShmNode { - unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ - sqlite3_mutex *mutex; /* Mutex to access this object */ - char *zFilename; /* Name of the mmapped file */ - int h; /* Open file descriptor */ - int szRegion; /* Size of shared-memory regions */ - u16 nRegion; /* Size of array apRegion */ - u8 isReadonly; /* True if read-only */ - char **apRegion; /* Array of mapped shared-memory regions */ - int nRef; /* Number of unixShm objects pointing to this */ - unixShm *pFirst; /* All unixShm objects pointing to this */ -#ifdef SQLITE_DEBUG - u8 exclMask; /* Mask of exclusive locks held */ - u8 sharedMask; /* Mask of shared locks held */ - u8 nextShmId; /* Next available unixShm.id value */ -#endif -}; - -/* -** Structure used internally by this VFS to record the state of an -** open shared memory connection. -** -** The following fields are initialized when this object is created and -** are read-only thereafter: -** -** unixShm.pFile -** unixShm.id -** -** All other fields are read/write. The unixShm.pFile->mutex must be held -** while accessing any read/write fields. -*/ -struct unixShm { - unixShmNode *pShmNode; /* The underlying unixShmNode object */ - unixShm *pNext; /* Next unixShm with the same unixShmNode */ - u8 hasMutex; /* True if holding the unixShmNode mutex */ - u8 id; /* Id of this connection within its unixShmNode */ - u16 sharedMask; /* Mask of shared locks held */ - u16 exclMask; /* Mask of exclusive locks held */ -}; - -/* -** Constants used for locking -*/ -#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ -#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ - -/* -** Apply posix advisory locks for all bytes from ofst through ofst+n-1. -** -** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking -** otherwise. -*/ -static int unixShmSystemLock( - unixFile *pFile, /* Open connection to the WAL file */ - int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ - int ofst, /* First byte of the locking range */ - int n /* Number of bytes to lock */ -){ - unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ - struct flock f; /* The posix advisory locking structure */ - int rc = SQLITE_OK; /* Result code form fcntl() */ - - /* Access to the unixShmNode object is serialized by the caller */ - pShmNode = pFile->pInode->pShmNode; - assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 ); - - /* Shared locks never span more than one byte */ - assert( n==1 || lockType!=F_RDLCK ); - - /* Locks are within range */ - assert( n>=1 && n<=SQLITE_SHM_NLOCK ); - - if( pShmNode->h>=0 ){ - /* Initialize the locking parameters */ - memset(&f, 0, sizeof(f)); - f.l_type = lockType; - f.l_whence = SEEK_SET; - f.l_start = ofst; - f.l_len = n; - - rc = osFcntl(pShmNode->h, F_SETLK, &f); - rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; - } - - /* Update the global lock state and do debug tracing */ -#ifdef SQLITE_DEBUG - { u16 mask; - OSTRACE(("SHM-LOCK ")); - mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<exclMask &= ~mask; - pShmNode->sharedMask &= ~mask; - }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock %d ok", ofst)); - pShmNode->exclMask &= ~mask; - pShmNode->sharedMask |= mask; - }else{ - assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d ok", ofst)); - pShmNode->exclMask |= mask; - pShmNode->sharedMask &= ~mask; - } - }else{ - if( lockType==F_UNLCK ){ - OSTRACE(("unlock %d failed", ofst)); - }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock failed")); - }else{ - assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d failed", ofst)); - } - } - OSTRACE((" - afterwards %03x,%03x\n", - pShmNode->sharedMask, pShmNode->exclMask)); - } -#endif - - return rc; -} - -/* -** Return the minimum number of 32KB shm regions that should be mapped at -** a time, assuming that each mapping must be an integer multiple of the -** current system page-size. -** -** Usually, this is 1. The exception seems to be systems that are configured -** to use 64KB pages - in this case each mapping must cover at least two -** shm regions. -*/ -static int unixShmRegionPerMap(void){ - int shmsz = 32*1024; /* SHM region size */ - int pgsz = osGetpagesize(); /* System page size */ - assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ - if( pgszpInode->pShmNode; - assert( unixMutexHeld() ); - if( p && ALWAYS(p->nRef==0) ){ - int nShmPerMap = unixShmRegionPerMap(); - int i; - assert( p->pInode==pFd->pInode ); - sqlite3_mutex_free(p->mutex); - for(i=0; inRegion; i+=nShmPerMap){ - if( p->h>=0 ){ - osMunmap(p->apRegion[i], p->szRegion); - }else{ - sqlite3_free(p->apRegion[i]); - } - } - sqlite3_free(p->apRegion); - if( p->h>=0 ){ - robust_close(pFd, p->h, __LINE__); - p->h = -1; - } - p->pInode->pShmNode = 0; - sqlite3_free(p); - } -} - -/* -** Open a shared-memory area associated with open database file pDbFd. -** This particular implementation uses mmapped files. -** -** The file used to implement shared-memory is in the same directory -** as the open database file and has the same name as the open database -** file with the "-shm" suffix added. For example, if the database file -** is "/home/user1/config.db" then the file that is created and mmapped -** for shared memory will be called "/home/user1/config.db-shm". -** -** Another approach to is to use files in /dev/shm or /dev/tmp or an -** some other tmpfs mount. But if a file in a different directory -** from the database file is used, then differing access permissions -** or a chroot() might cause two different processes on the same -** database to end up using different files for shared memory - -** meaning that their memory would not really be shared - resulting -** in database corruption. Nevertheless, this tmpfs file usage -** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" -** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time -** option results in an incompatible build of SQLite; builds of SQLite -** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the -** same database file at the same time, database corruption will likely -** result. The SQLITE_SHM_DIRECTORY compile-time option is considered -** "unsupported" and may go away in a future SQLite release. -** -** When opening a new shared-memory file, if no other instances of that -** file are currently open, in this process or in other processes, then -** the file must be truncated to zero length or have its header cleared. -** -** If the original database file (pDbFd) is using the "unix-excl" VFS -** that means that an exclusive lock is held on the database file and -** that no other processes are able to read or write the database. In -** that case, we do not really need shared memory. No shared memory -** file is created. The shared memory will be simulated with heap memory. -*/ -static int unixOpenSharedMemory(unixFile *pDbFd){ - struct unixShm *p = 0; /* The connection to be opened */ - struct unixShmNode *pShmNode; /* The underlying mmapped file */ - int rc; /* Result code */ - unixInodeInfo *pInode; /* The inode of fd */ - char *zShmFilename; /* Name of the file used for SHM */ - int nShmFilename; /* Size of the SHM filename in bytes */ - - /* Allocate space for the new unixShm object. */ - p = sqlite3_malloc64( sizeof(*p) ); - if( p==0 ) return SQLITE_NOMEM_BKPT; - memset(p, 0, sizeof(*p)); - assert( pDbFd->pShm==0 ); - - /* Check to see if a unixShmNode object already exists. Reuse an existing - ** one if present. Create a new one if necessary. - */ - unixEnterMutex(); - pInode = pDbFd->pInode; - pShmNode = pInode->pShmNode; - if( pShmNode==0 ){ - struct stat sStat; /* fstat() info for database file */ -#ifndef SQLITE_SHM_DIRECTORY - const char *zBasePath = pDbFd->zPath; -#endif - - /* Call fstat() to figure out the permissions on the database file. If - ** a new *-shm file is created, an attempt will be made to create it - ** with the same permissions. - */ - if( osFstat(pDbFd->h, &sStat) ){ - rc = SQLITE_IOERR_FSTAT; - goto shm_open_err; - } - -#ifdef SQLITE_SHM_DIRECTORY - nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; -#else - nShmFilename = 6 + (int)strlen(zBasePath); -#endif - pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); - if( pShmNode==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shm_open_err; - } - memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); - zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1]; -#ifdef SQLITE_SHM_DIRECTORY - sqlite3_snprintf(nShmFilename, zShmFilename, - SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", - (u32)sStat.st_ino, (u32)sStat.st_dev); -#else - sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath); - sqlite3FileSuffix3(pDbFd->zPath, zShmFilename); -#endif - pShmNode->h = -1; - pDbFd->pInode->pShmNode = pShmNode; - pShmNode->pInode = pDbFd->pInode; - if( sqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shm_open_err; - } - } - - if( pInode->bProcessLock==0 ){ - int openFlags = O_RDWR | O_CREAT; - if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ - openFlags = O_RDONLY; - pShmNode->isReadonly = 1; - } - pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777)); - if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; - } - - /* If this process is running as root, make sure that the SHM file - ** is owned by the same user that owns the original database. Otherwise, - ** the original owner will not be able to connect. - */ - robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); - - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - rc = SQLITE_OK; - if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( robust_ftruncate(pShmNode->h, 0) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); - } - } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; - } - } - - /* Make the new connection a child of the unixShmNode */ - p->pShmNode = pShmNode; -#ifdef SQLITE_DEBUG - p->id = pShmNode->nextShmId++; -#endif - pShmNode->nRef++; - pDbFd->pShm = p; - unixLeaveMutex(); - - /* The reference count on pShmNode has already been incremented under - ** the cover of the unixEnterMutex() mutex and the pointer from the - ** new (struct unixShm) object to the pShmNode has been set. All that is - ** left to do is to link the new object into the linked list starting - ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex - ** mutex. - */ - sqlite3_mutex_enter(pShmNode->mutex); - p->pNext = pShmNode->pFirst; - pShmNode->pFirst = p; - sqlite3_mutex_leave(pShmNode->mutex); - return SQLITE_OK; - - /* Jump here on any error */ -shm_open_err: - unixShmPurge(pDbFd); /* This call frees pShmNode if required */ - sqlite3_free(p); - unixLeaveMutex(); - return rc; -} - -/* -** This function is called to obtain a pointer to region iRegion of the -** shared-memory associated with the database file fd. Shared-memory regions -** are numbered starting from zero. Each shared-memory region is szRegion -** bytes in size. -** -** If an error occurs, an error code is returned and *pp is set to NULL. -** -** Otherwise, if the bExtend parameter is 0 and the requested shared-memory -** region has not been allocated (by any client, including one running in a -** separate process), then *pp is set to NULL and SQLITE_OK returned. If -** bExtend is non-zero and the requested shared-memory region has not yet -** been allocated, it is allocated by this function. -** -** If the shared-memory region has already been allocated or is allocated by -** this call as described above, then it is mapped into this processes -** address space (if it is not already), *pp is set to point to the mapped -** memory and SQLITE_OK returned. -*/ -static int unixShmMap( - sqlite3_file *fd, /* Handle open on database file */ - int iRegion, /* Region to retrieve */ - int szRegion, /* Size of regions */ - int bExtend, /* True to extend file if necessary */ - void volatile **pp /* OUT: Mapped memory */ -){ - unixFile *pDbFd = (unixFile*)fd; - unixShm *p; - unixShmNode *pShmNode; - int rc = SQLITE_OK; - int nShmPerMap = unixShmRegionPerMap(); - int nReqRegion; - - /* If the shared-memory file has not yet been opened, open it now. */ - if( pDbFd->pShm==0 ){ - rc = unixOpenSharedMemory(pDbFd); - if( rc!=SQLITE_OK ) return rc; - } - - p = pDbFd->pShm; - pShmNode = p->pShmNode; - sqlite3_mutex_enter(pShmNode->mutex); - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - assert( pShmNode->pInode==pDbFd->pInode ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); - - /* Minimum number of regions required to be mapped. */ - nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; - - if( pShmNode->nRegionszRegion = szRegion; - - if( pShmNode->h>=0 ){ - /* The requested region is not mapped into this processes address space. - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ - if( osFstat(pShmNode->h, &sStat) ){ - rc = SQLITE_IOERR_SHMSIZE; - goto shmpage_out; - } - - if( sStat.st_sizeh, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ - const char *zFile = pShmNode->zFilename; - rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); - goto shmpage_out; - } - } - } - } - } - - /* Map the requested memory region into this processes address space. */ - apNew = (char **)sqlite3_realloc( - pShmNode->apRegion, nReqRegion*sizeof(char *) - ); - if( !apNew ){ - rc = SQLITE_IOERR_NOMEM_BKPT; - goto shmpage_out; - } - pShmNode->apRegion = apNew; - while( pShmNode->nRegionh>=0 ){ - pMem = osMmap(0, nMap, - pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, - MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion - ); - if( pMem==MAP_FAILED ){ - rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); - goto shmpage_out; - } - }else{ - pMem = sqlite3_malloc64(szRegion); - if( pMem==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto shmpage_out; - } - memset(pMem, 0, szRegion); - } - - for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; - } - pShmNode->nRegion += nShmPerMap; - } - } - -shmpage_out: - if( pShmNode->nRegion>iRegion ){ - *pp = pShmNode->apRegion[iRegion]; - }else{ - *pp = 0; - } - if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - sqlite3_mutex_leave(pShmNode->mutex); - return rc; -} - -/* -** Change the lock state for a shared-memory segment. -** -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little -** different here than in posix. In xShmLock(), one can go from unlocked -** to shared and back or from unlocked to exclusive and back. But one may -** not go from shared to exclusive or from exclusive to shared. -*/ -static int unixShmLock( - sqlite3_file *fd, /* Database file holding the shared memory */ - int ofst, /* First lock to acquire or release */ - int n, /* Number of locks to acquire or release */ - int flags /* What to do with the lock */ -){ - unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ - unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShm *pX; /* For looping over all siblings */ - unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ - int rc = SQLITE_OK; /* Result code */ - u16 mask; /* Mask of locks to take or release */ - - assert( pShmNode==pDbFd->pInode->pShmNode ); - assert( pShmNode->pInode==pDbFd->pInode ); - assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); - assert( n>=1 ); - assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); - assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); - - mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex); - if( flags & SQLITE_SHM_UNLOCK ){ - u16 allMask = 0; /* Mask of locks held by siblings */ - - /* See if any siblings hold this same lock */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( pX==p ) continue; - assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); - allMask |= pX->sharedMask; - } - - /* Unlock the system-level locks */ - if( (mask & allMask)==0 ){ - rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - }else if( flags & SQLITE_SHM_SHARED ){ - u16 allShared = 0; /* Union of locks held by connections other than "p" */ - - /* Find out which shared locks are already held by sibling connections. - ** If any sibling already holds an exclusive lock, go ahead and return - ** SQLITE_BUSY. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - allShared |= pX->sharedMask; - } - - /* Get shared locks at the system level, if necessary */ - if( rc==SQLITE_OK ){ - if( (allShared & mask)==0 ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - } - - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - } - - /* Get the exclusive locks at the system level. Then if successful - ** also mark the local connection as being locked. - */ - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n); - if( rc==SQLITE_OK ){ - assert( (p->sharedMask & mask)==0 ); - p->exclMask |= mask; - } - } - } - sqlite3_mutex_leave(pShmNode->mutex); - OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", - p->id, osGetpid(0), p->sharedMask, p->exclMask)); - return rc; -} - -/* -** Implement a memory barrier or memory fence on shared memory. -** -** All loads and stores begun before the barrier must complete before -** any load or store begun after the barrier. -*/ -static void unixShmBarrier( - sqlite3_file *fd /* Database file holding the shared memory */ -){ - UNUSED_PARAMETER(fd); - sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ - unixEnterMutex(); /* Also mutex, for redundancy */ - unixLeaveMutex(); -} - -/* -** Close a connection to shared-memory. Delete the underlying -** storage if deleteFlag is true. -** -** If there is no shared memory associated with the connection then this -** routine is a harmless no-op. -*/ -static int unixShmUnmap( - sqlite3_file *fd, /* The underlying database file */ - int deleteFlag /* Delete shared-memory if true */ -){ - unixShm *p; /* The connection to be closed */ - unixShmNode *pShmNode; /* The underlying shared-memory file */ - unixShm **pp; /* For looping over sibling connections */ - unixFile *pDbFd; /* The underlying database file */ - - pDbFd = (unixFile*)fd; - p = pDbFd->pShm; - if( p==0 ) return SQLITE_OK; - pShmNode = p->pShmNode; - - assert( pShmNode==pDbFd->pInode->pShmNode ); - assert( pShmNode->pInode==pDbFd->pInode ); - - /* Remove connection p from the set of connections associated - ** with pShmNode */ - sqlite3_mutex_enter(pShmNode->mutex); - for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} - *pp = p->pNext; - - /* Free the connection p */ - sqlite3_free(p); - pDbFd->pShm = 0; - sqlite3_mutex_leave(pShmNode->mutex); - - /* If pShmNode->nRef has reached 0, then close the underlying - ** shared-memory file, too */ - unixEnterMutex(); - assert( pShmNode->nRef>0 ); - pShmNode->nRef--; - if( pShmNode->nRef==0 ){ - if( deleteFlag && pShmNode->h>=0 ){ - osUnlink(pShmNode->zFilename); - } - unixShmPurge(pDbFd); - } - unixLeaveMutex(); - - return SQLITE_OK; -} - - -#else -# define unixShmMap 0 -# define unixShmLock 0 -# define unixShmBarrier 0 -# define unixShmUnmap 0 -#endif /* #ifndef SQLITE_OMIT_WAL */ - -#if SQLITE_MAX_MMAP_SIZE>0 -/* -** If it is currently memory mapped, unmap file pFd. -*/ -static void unixUnmapfile(unixFile *pFd){ - assert( pFd->nFetchOut==0 ); - if( pFd->pMapRegion ){ - osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); - pFd->pMapRegion = 0; - pFd->mmapSize = 0; - pFd->mmapSizeActual = 0; - } -} - -/* -** Attempt to set the size of the memory mapping maintained by file -** descriptor pFd to nNew bytes. Any existing mapping is discarded. -** -** If successful, this function sets the following variables: -** -** unixFile.pMapRegion -** unixFile.mmapSize -** unixFile.mmapSizeActual -** -** If unsuccessful, an error message is logged via sqlite3_log() and -** the three variables above are zeroed. In this case SQLite should -** continue accessing the database using the xRead() and xWrite() -** methods. -*/ -static void unixRemapfile( - unixFile *pFd, /* File descriptor object */ - i64 nNew /* Required mapping size */ -){ - const char *zErr = "mmap"; - int h = pFd->h; /* File descriptor open on db file */ - u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ - i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ - u8 *pNew = 0; /* Location of new mapping */ - int flags = PROT_READ; /* Flags to pass to mmap() */ - - assert( pFd->nFetchOut==0 ); - assert( nNew>pFd->mmapSize ); - assert( nNew<=pFd->mmapSizeMax ); - assert( nNew>0 ); - assert( pFd->mmapSizeActual>=pFd->mmapSize ); - assert( MAP_FAILED!=0 ); - -#ifdef SQLITE_MMAP_READWRITE - if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; -#endif - - if( pOrig ){ -#if HAVE_MREMAP - i64 nReuse = pFd->mmapSize; -#else - const int szSyspage = osGetpagesize(); - i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); -#endif - u8 *pReq = &pOrig[nReuse]; - - /* Unmap any pages of the existing mapping that cannot be reused. */ - if( nReuse!=nOrig ){ - osMunmap(pReq, nOrig-nReuse); - } - -#if HAVE_MREMAP - pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); - zErr = "mremap"; -#else - pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); - if( pNew!=MAP_FAILED ){ - if( pNew!=pReq ){ - osMunmap(pNew, nNew - nReuse); - pNew = 0; - }else{ - pNew = pOrig; - } - } -#endif - - /* The attempt to extend the existing mapping failed. Free it. */ - if( pNew==MAP_FAILED || pNew==0 ){ - osMunmap(pOrig, nReuse); - } - } - - /* If pNew is still NULL, try to create an entirely new mapping. */ - if( pNew==0 ){ - pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0); - } - - if( pNew==MAP_FAILED ){ - pNew = 0; - nNew = 0; - unixLogError(SQLITE_OK, zErr, pFd->zPath); - - /* If the mmap() above failed, assume that all subsequent mmap() calls - ** will probably fail too. Fall back to using xRead/xWrite exclusively - ** in this case. */ - pFd->mmapSizeMax = 0; - } - pFd->pMapRegion = (void *)pNew; - pFd->mmapSize = pFd->mmapSizeActual = nNew; -} - -/* -** Memory map or remap the file opened by file-descriptor pFd (if the file -** is already mapped, the existing mapping is replaced by the new). Or, if -** there already exists a mapping for this file, and there are still -** outstanding xFetch() references to it, this function is a no-op. -** -** If parameter nByte is non-negative, then it is the requested size of -** the mapping to create. Otherwise, if nByte is less than zero, then the -** requested size is the size of the file on disk. The actual size of the -** created mapping is either the requested size or the value configured -** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. -** -** SQLITE_OK is returned if no error occurs (even if the mapping is not -** recreated as a result of outstanding references) or an SQLite error -** code otherwise. -*/ -static int unixMapfile(unixFile *pFd, i64 nMap){ - assert( nMap>=0 || pFd->nFetchOut==0 ); - assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); - if( pFd->nFetchOut>0 ) return SQLITE_OK; - - if( nMap<0 ){ - struct stat statbuf; /* Low-level file information */ - if( osFstat(pFd->h, &statbuf) ){ - return SQLITE_IOERR_FSTAT; - } - nMap = statbuf.st_size; - } - if( nMap>pFd->mmapSizeMax ){ - nMap = pFd->mmapSizeMax; - } - - assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); - if( nMap!=pFd->mmapSize ){ - unixRemapfile(pFd, nMap); - } - - return SQLITE_OK; -} -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ - -/* -** If possible, return a pointer to a mapping of file fd starting at offset -** iOff. The mapping must be valid for at least nAmt bytes. -** -** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. -** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. -** Finally, if an error does occur, return an SQLite error code. The final -** value of *pp is undefined in this case. -** -** If this function does return a pointer, the caller must eventually -** release the reference by calling unixUnfetch(). -*/ -static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ -#if SQLITE_MAX_MMAP_SIZE>0 - unixFile *pFd = (unixFile *)fd; /* The underlying database file */ -#endif - *pp = 0; - -#if SQLITE_MAX_MMAP_SIZE>0 - if( pFd->mmapSizeMax>0 ){ - if( pFd->pMapRegion==0 ){ - int rc = unixMapfile(pFd, -1); - if( rc!=SQLITE_OK ) return rc; - } - if( pFd->mmapSize >= iOff+nAmt ){ - *pp = &((u8 *)pFd->pMapRegion)[iOff]; - pFd->nFetchOut++; - } - } -#endif - return SQLITE_OK; -} - -/* -** If the third argument is non-NULL, then this function releases a -** reference obtained by an earlier call to unixFetch(). The second -** argument passed to this function must be the same as the corresponding -** argument that was passed to the unixFetch() invocation. -** -** Or, if the third argument is NULL, then this function is being called -** to inform the VFS layer that, according to POSIX, any existing mapping -** may now be invalid and should be unmapped. -*/ -static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ -#if SQLITE_MAX_MMAP_SIZE>0 - unixFile *pFd = (unixFile *)fd; /* The underlying database file */ - UNUSED_PARAMETER(iOff); - - /* If p==0 (unmap the entire file) then there must be no outstanding - ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), - ** then there must be at least one outstanding. */ - assert( (p==0)==(pFd->nFetchOut==0) ); - - /* If p!=0, it must match the iOff value. */ - assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); - - if( p ){ - pFd->nFetchOut--; - }else{ - unixUnmapfile(pFd); - } - - assert( pFd->nFetchOut>=0 ); -#else - UNUSED_PARAMETER(fd); - UNUSED_PARAMETER(p); - UNUSED_PARAMETER(iOff); -#endif - return SQLITE_OK; -} - -/* -** Here ends the implementation of all sqlite3_file methods. -** -********************** End sqlite3_file Methods ******************************* -******************************************************************************/ - -/* -** This division contains definitions of sqlite3_io_methods objects that -** implement various file locking strategies. It also contains definitions -** of "finder" functions. A finder-function is used to locate the appropriate -** sqlite3_io_methods object for a particular database file. The pAppData -** field of the sqlite3_vfs VFS objects are initialized to be pointers to -** the correct finder-function for that VFS. -** -** Most finder functions return a pointer to a fixed sqlite3_io_methods -** object. The only interesting finder-function is autolockIoFinder, which -** looks at the filesystem type and tries to guess the best locking -** strategy from that. -** -** For finder-function F, two objects are created: -** -** (1) The real finder-function named "FImpt()". -** -** (2) A constant pointer to this function named just "F". -** -** -** A pointer to the F pointer is used as the pAppData value for VFS -** objects. We have to do this instead of letting pAppData point -** directly at the finder-function since C90 rules prevent a void* -** from be cast into a function pointer. -** -** -** Each instance of this macro generates two objects: -** -** * A constant sqlite3_io_methods object call METHOD that has locking -** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. -** -** * An I/O method finder function called FINDER that returns a pointer -** to the METHOD object in the previous bullet. -*/ -#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ -static const sqlite3_io_methods METHOD = { \ - VERSION, /* iVersion */ \ - CLOSE, /* xClose */ \ - unixRead, /* xRead */ \ - unixWrite, /* xWrite */ \ - unixTruncate, /* xTruncate */ \ - unixSync, /* xSync */ \ - unixFileSize, /* xFileSize */ \ - LOCK, /* xLock */ \ - UNLOCK, /* xUnlock */ \ - CKLOCK, /* xCheckReservedLock */ \ - unixFileControl, /* xFileControl */ \ - unixSectorSize, /* xSectorSize */ \ - unixDeviceCharacteristics, /* xDeviceCapabilities */ \ - SHMMAP, /* xShmMap */ \ - unixShmLock, /* xShmLock */ \ - unixShmBarrier, /* xShmBarrier */ \ - unixShmUnmap, /* xShmUnmap */ \ - unixFetch, /* xFetch */ \ - unixUnfetch, /* xUnfetch */ \ -}; \ -static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ - UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ - return &METHOD; \ -} \ -static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ - = FINDER##Impl; - -/* -** Here are all of the sqlite3_io_methods objects for each of the -** locking strategies. Functions that return pointers to these methods -** are also created. -*/ -IOMETHODS( - posixIoFinder, /* Finder function name */ - posixIoMethods, /* sqlite3_io_methods object name */ - 3, /* shared memory and mmap are enabled */ - unixClose, /* xClose method */ - unixLock, /* xLock method */ - unixUnlock, /* xUnlock method */ - unixCheckReservedLock, /* xCheckReservedLock method */ - unixShmMap /* xShmMap method */ -) -IOMETHODS( - nolockIoFinder, /* Finder function name */ - nolockIoMethods, /* sqlite3_io_methods object name */ - 3, /* shared memory is disabled */ - nolockClose, /* xClose method */ - nolockLock, /* xLock method */ - nolockUnlock, /* xUnlock method */ - nolockCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -IOMETHODS( - dotlockIoFinder, /* Finder function name */ - dotlockIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - dotlockClose, /* xClose method */ - dotlockLock, /* xLock method */ - dotlockUnlock, /* xUnlock method */ - dotlockCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) - -#if SQLITE_ENABLE_LOCKING_STYLE -IOMETHODS( - flockIoFinder, /* Finder function name */ - flockIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - flockClose, /* xClose method */ - flockLock, /* xLock method */ - flockUnlock, /* xUnlock method */ - flockCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -#endif - -#if OS_VXWORKS -IOMETHODS( - semIoFinder, /* Finder function name */ - semIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - semXClose, /* xClose method */ - semXLock, /* xLock method */ - semXUnlock, /* xUnlock method */ - semXCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -#endif - -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -IOMETHODS( - afpIoFinder, /* Finder function name */ - afpIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - afpClose, /* xClose method */ - afpLock, /* xLock method */ - afpUnlock, /* xUnlock method */ - afpCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -#endif - -/* -** The proxy locking method is a "super-method" in the sense that it -** opens secondary file descriptors for the conch and lock files and -** it uses proxy, dot-file, AFP, and flock() locking methods on those -** secondary files. For this reason, the division that implements -** proxy locking is located much further down in the file. But we need -** to go ahead and define the sqlite3_io_methods and finder function -** for proxy locking here. So we forward declare the I/O methods. -*/ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -static int proxyClose(sqlite3_file*); -static int proxyLock(sqlite3_file*, int); -static int proxyUnlock(sqlite3_file*, int); -static int proxyCheckReservedLock(sqlite3_file*, int*); -IOMETHODS( - proxyIoFinder, /* Finder function name */ - proxyIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - proxyClose, /* xClose method */ - proxyLock, /* xLock method */ - proxyUnlock, /* xUnlock method */ - proxyCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -#endif - -/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -IOMETHODS( - nfsIoFinder, /* Finder function name */ - nfsIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ - unixClose, /* xClose method */ - unixLock, /* xLock method */ - nfsUnlock, /* xUnlock method */ - unixCheckReservedLock, /* xCheckReservedLock method */ - 0 /* xShmMap method */ -) -#endif - -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy -** for the database file "filePath". It then returns the sqlite3_io_methods -** object that implements that strategy. -** -** This is for MacOSX only. -*/ -static const sqlite3_io_methods *autolockIoFinderImpl( - const char *filePath, /* name of the database file */ - unixFile *pNew /* open file object for the database file */ -){ - static const struct Mapping { - const char *zFilesystem; /* Filesystem type name */ - const sqlite3_io_methods *pMethods; /* Appropriate locking method */ - } aMap[] = { - { "hfs", &posixIoMethods }, - { "ufs", &posixIoMethods }, - { "afpfs", &afpIoMethods }, - { "smbfs", &afpIoMethods }, - { "webdav", &nolockIoMethods }, - { 0, 0 } - }; - int i; - struct statfs fsInfo; - struct flock lockInfo; - - if( !filePath ){ - /* If filePath==NULL that means we are dealing with a transient file - ** that does not need to be locked. */ - return &nolockIoMethods; - } - if( statfs(filePath, &fsInfo) != -1 ){ - if( fsInfo.f_flags & MNT_RDONLY ){ - return &nolockIoMethods; - } - for(i=0; aMap[i].zFilesystem; i++){ - if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ - return aMap[i].pMethods; - } - } - } - - /* Default case. Handles, amongst others, "nfs". - ** Test byte-range lock using fcntl(). If the call succeeds, - ** assume that the file-system supports POSIX style locks. - */ - lockInfo.l_len = 1; - lockInfo.l_start = 0; - lockInfo.l_whence = SEEK_SET; - lockInfo.l_type = F_RDLCK; - if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { - if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ - return &nfsIoMethods; - } else { - return &posixIoMethods; - } - }else{ - return &dotlockIoMethods; - } -} -static const sqlite3_io_methods - *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; - -#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ - -#if OS_VXWORKS -/* -** This "finder" function for VxWorks checks to see if posix advisory -** locking works. If it does, then that is what is used. If it does not -** work, then fallback to named semaphore locking. -*/ -static const sqlite3_io_methods *vxworksIoFinderImpl( - const char *filePath, /* name of the database file */ - unixFile *pNew /* the open file object */ -){ - struct flock lockInfo; - - if( !filePath ){ - /* If filePath==NULL that means we are dealing with a transient file - ** that does not need to be locked. */ - return &nolockIoMethods; - } - - /* Test if fcntl() is supported and use POSIX style locks. - ** Otherwise fall back to the named semaphore method. - */ - lockInfo.l_len = 1; - lockInfo.l_start = 0; - lockInfo.l_whence = SEEK_SET; - lockInfo.l_type = F_RDLCK; - if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { - return &posixIoMethods; - }else{ - return &semIoMethods; - } -} -static const sqlite3_io_methods - *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; - -#endif /* OS_VXWORKS */ - -/* -** An abstract type for a pointer to an IO method finder function: -*/ -typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); - - -/**************************************************************************** -**************************** sqlite3_vfs methods **************************** -** -** This division contains the implementation of methods on the -** sqlite3_vfs object. -*/ - -/* -** Initialize the contents of the unixFile structure pointed to by pId. -*/ -static int fillInUnixFile( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - int h, /* Open file descriptor of file being opened */ - sqlite3_file *pId, /* Write to the unixFile structure here */ - const char *zFilename, /* Name of the file being opened */ - int ctrlFlags /* Zero or more UNIXFILE_* values */ -){ - const sqlite3_io_methods *pLockingStyle; - unixFile *pNew = (unixFile *)pId; - int rc = SQLITE_OK; - - assert( pNew->pInode==NULL ); - - /* Usually the path zFilename should not be a relative pathname. The - ** exception is when opening the proxy "conch" file in builds that - ** include the special Apple locking styles. - */ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE - assert( zFilename==0 || zFilename[0]=='/' - || pVfs->pAppData==(void*)&autolockIoFinder ); -#else - assert( zFilename==0 || zFilename[0]=='/' ); -#endif - - /* No locking occurs in temporary files */ - assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); - - OSTRACE(("OPEN %-3d %s\n", h, zFilename)); - pNew->h = h; - pNew->pVfs = pVfs; - pNew->zPath = zFilename; - pNew->ctrlFlags = (u8)ctrlFlags; -#if SQLITE_MAX_MMAP_SIZE>0 - pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; -#endif - if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), - "psow", SQLITE_POWERSAFE_OVERWRITE) ){ - pNew->ctrlFlags |= UNIXFILE_PSOW; - } - if( strcmp(pVfs->zName,"unix-excl")==0 ){ - pNew->ctrlFlags |= UNIXFILE_EXCL; - } - -#if OS_VXWORKS - pNew->pId = vxworksFindFileId(zFilename); - if( pNew->pId==0 ){ - ctrlFlags |= UNIXFILE_NOLOCK; - rc = SQLITE_NOMEM_BKPT; - } -#endif - - if( ctrlFlags & UNIXFILE_NOLOCK ){ - pLockingStyle = &nolockIoMethods; - }else{ - pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); -#if SQLITE_ENABLE_LOCKING_STYLE - /* Cache zFilename in the locking context (AFP and dotlock override) for - ** proxyLock activation is possible (remote proxy is based on db name) - ** zFilename remains valid until file is closed, to support */ - pNew->lockingContext = (void*)zFilename; -#endif - } - - if( pLockingStyle == &posixIoMethods -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE - || pLockingStyle == &nfsIoMethods -#endif - ){ - unixEnterMutex(); - rc = findInodeInfo(pNew, &pNew->pInode); - if( rc!=SQLITE_OK ){ - /* If an error occurred in findInodeInfo(), close the file descriptor - ** immediately, before releasing the mutex. findInodeInfo() may fail - ** in two scenarios: - ** - ** (a) A call to fstat() failed. - ** (b) A malloc failed. - ** - ** Scenario (b) may only occur if the process is holding no other - ** file descriptors open on the same file. If there were other file - ** descriptors on this file, then no malloc would be required by - ** findInodeInfo(). If this is the case, it is quite safe to close - ** handle h - as it is guaranteed that no posix locks will be released - ** by doing so. - ** - ** If scenario (a) caused the error then things are not so safe. The - ** implicit assumption here is that if fstat() fails, things are in - ** such bad shape that dropping a lock or two doesn't matter much. - */ - robust_close(pNew, h, __LINE__); - h = -1; - } - unixLeaveMutex(); - } - -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - else if( pLockingStyle == &afpIoMethods ){ - /* AFP locking uses the file path so it needs to be included in - ** the afpLockingContext. - */ - afpLockingContext *pCtx; - pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); - if( pCtx==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - /* NB: zFilename exists and remains valid until the file is closed - ** according to requirement F11141. So we do not need to make a - ** copy of the filename. */ - pCtx->dbPath = zFilename; - pCtx->reserved = 0; - srandomdev(); - unixEnterMutex(); - rc = findInodeInfo(pNew, &pNew->pInode); - if( rc!=SQLITE_OK ){ - sqlite3_free(pNew->lockingContext); - robust_close(pNew, h, __LINE__); - h = -1; - } - unixLeaveMutex(); - } - } -#endif - - else if( pLockingStyle == &dotlockIoMethods ){ - /* Dotfile locking uses the file path so it needs to be included in - ** the dotlockLockingContext - */ - char *zLockFile; - int nFilename; - assert( zFilename!=0 ); - nFilename = (int)strlen(zFilename) + 6; - zLockFile = (char *)sqlite3_malloc64(nFilename); - if( zLockFile==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); - } - pNew->lockingContext = zLockFile; - } - -#if OS_VXWORKS - else if( pLockingStyle == &semIoMethods ){ - /* Named semaphore locking uses the file path so it needs to be - ** included in the semLockingContext - */ - unixEnterMutex(); - rc = findInodeInfo(pNew, &pNew->pInode); - if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ - char *zSemName = pNew->pInode->aSemName; - int n; - sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", - pNew->pId->zCanonicalName); - for( n=1; zSemName[n]; n++ ) - if( zSemName[n]=='/' ) zSemName[n] = '_'; - pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); - if( pNew->pInode->pSem == SEM_FAILED ){ - rc = SQLITE_NOMEM_BKPT; - pNew->pInode->aSemName[0] = '\0'; - } - } - unixLeaveMutex(); - } -#endif - - storeLastErrno(pNew, 0); -#if OS_VXWORKS - if( rc!=SQLITE_OK ){ - if( h>=0 ) robust_close(pNew, h, __LINE__); - h = -1; - osUnlink(zFilename); - pNew->ctrlFlags |= UNIXFILE_DELETE; - } -#endif - if( rc!=SQLITE_OK ){ - if( h>=0 ) robust_close(pNew, h, __LINE__); - }else{ - pNew->pMethod = pLockingStyle; - OpenCounter(+1); - verifyDbFile(pNew); - } - return rc; -} - -/* -** Return the name of a directory in which to put temporary files. -** If no suitable temporary file directory can be found, return NULL. -*/ -static const char *unixTempFileDir(void){ - static const char *azDirs[] = { - 0, - 0, - "/var/tmp", - "/usr/tmp", - "/tmp", - "." - }; - unsigned int i = 0; - struct stat buf; - const char *zDir = sqlite3_temp_directory; - - if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); - if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); - while(1){ - if( zDir!=0 - && osStat(zDir, &buf)==0 - && S_ISDIR(buf.st_mode) - && osAccess(zDir, 03)==0 - ){ - return zDir; - } - if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break; - zDir = azDirs[i++]; - } - return 0; -} - -/* -** Create a temporary file name in zBuf. zBuf must be allocated -** by the calling process and must be big enough to hold at least -** pVfs->mxPathname bytes. -*/ -static int unixGetTempname(int nBuf, char *zBuf){ - const char *zDir; - int iLimit = 0; - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. - */ - zBuf[0] = 0; - SimulateIOError( return SQLITE_IOERR ); - - zDir = unixTempFileDir(); - if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH; - do{ - u64 r; - sqlite3_randomness(sizeof(r), &r); - assert( nBuf>2 ); - zBuf[nBuf-2] = 0; - sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", - zDir, r, 0); - if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR; - }while( osAccess(zBuf,0)==0 ); - return SQLITE_OK; -} - -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) -/* -** Routine to transform a unixFile into a proxy-locking unixFile. -** Implementation in the proxy-lock division, but used by unixOpen() -** if SQLITE_PREFER_PROXY_LOCKING is defined. -*/ -static int proxyTransformUnixFile(unixFile*, const char*); -#endif - -/* -** Search for an unused file descriptor that was opened on the database -** file (not a journal or master-journal file) identified by pathname -** zPath with SQLITE_OPEN_XXX flags matching those passed as the second -** argument to this function. -** -** Such a file descriptor may exist if a database connection was closed -** but the associated file descriptor could not be closed because some -** other file descriptor open on the same file is holding a file-lock. -** Refer to comments in the unixClose() function and the lengthy comment -** describing "Posix Advisory Locking" at the start of this file for -** further details. Also, ticket #4018. -** -** If a suitable file descriptor is found, then it is returned. If no -** such file descriptor is located, -1 is returned. -*/ -static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ - UnixUnusedFd *pUnused = 0; - - /* Do not search for an unused file descriptor on vxworks. Not because - ** vxworks would not benefit from the change (it might, we're not sure), - ** but because no way to test it is currently available. It is better - ** not to risk breaking vxworks support for the sake of such an obscure - ** feature. */ -#if !OS_VXWORKS - struct stat sStat; /* Results of stat() call */ - - /* A stat() call may fail for various reasons. If this happens, it is - ** almost certain that an open() call on the same path will also fail. - ** For this reason, if an error occurs in the stat() call here, it is - ** ignored and -1 is returned. The caller will try to open a new file - ** descriptor on the same path, fail, and return an error to SQLite. - ** - ** Even if a subsequent open() call does succeed, the consequences of - ** not searching for a reusable file descriptor are not dire. */ - if( 0==osStat(zPath, &sStat) ){ - unixInodeInfo *pInode; - - unixEnterMutex(); - pInode = inodeList; - while( pInode && (pInode->fileId.dev!=sStat.st_dev - || pInode->fileId.ino!=sStat.st_ino) ){ - pInode = pInode->pNext; - } - if( pInode ){ - UnixUnusedFd **pp; - for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); - pUnused = *pp; - if( pUnused ){ - *pp = pUnused->pNext; - } - } - unixLeaveMutex(); - } -#endif /* if !OS_VXWORKS */ - return pUnused; -} - -/* -** Find the mode, uid and gid of file zFile. -*/ -static int getFileMode( - const char *zFile, /* File name */ - mode_t *pMode, /* OUT: Permissions of zFile */ - uid_t *pUid, /* OUT: uid of zFile. */ - gid_t *pGid /* OUT: gid of zFile. */ -){ - struct stat sStat; /* Output of stat() on database file */ - int rc = SQLITE_OK; - if( 0==osStat(zFile, &sStat) ){ - *pMode = sStat.st_mode & 0777; - *pUid = sStat.st_uid; - *pGid = sStat.st_gid; - }else{ - rc = SQLITE_IOERR_FSTAT; - } - return rc; -} - -/* -** This function is called by unixOpen() to determine the unix permissions -** to create new files with. If no error occurs, then SQLITE_OK is returned -** and a value suitable for passing as the third argument to open(2) is -** written to *pMode. If an IO error occurs, an SQLite error code is -** returned and the value of *pMode is not modified. -** -** In most cases, this routine sets *pMode to 0, which will become -** an indication to robust_open() to create the file using -** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. -** But if the file being opened is a WAL or regular journal file, then -** this function queries the file-system for the permissions on the -** corresponding database file and sets *pMode to this value. Whenever -** possible, WAL and journal files are created using the same permissions -** as the associated database file. -** -** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the -** original filename is unavailable. But 8_3_NAMES is only used for -** FAT filesystems and permissions do not matter there, so just use -** the default permissions. -*/ -static int findCreateFileMode( - const char *zPath, /* Path of file (possibly) being created */ - int flags, /* Flags passed as 4th argument to xOpen() */ - mode_t *pMode, /* OUT: Permissions to open file with */ - uid_t *pUid, /* OUT: uid to set on the file */ - gid_t *pGid /* OUT: gid to set on the file */ -){ - int rc = SQLITE_OK; /* Return Code */ - *pMode = 0; - *pUid = 0; - *pGid = 0; - if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ - char zDb[MAX_PATHNAME+1]; /* Database file path */ - int nDb; /* Number of valid bytes in zDb */ - - /* zPath is a path to a WAL or journal file. The following block derives - ** the path to the associated database file from zPath. This block handles - ** the following naming conventions: - ** - ** "-journal" - ** "-wal" - ** "-journalNN" - ** "-walNN" - ** - ** where NN is a decimal number. The NN naming schemes are - ** used by the test_multiplex.c module. - */ - nDb = sqlite3Strlen30(zPath) - 1; - while( zPath[nDb]!='-' ){ -#ifndef SQLITE_ENABLE_8_3_NAMES - /* In the normal case (8+3 filenames disabled) the journal filename - ** is guaranteed to contain a '-' character. */ - assert( nDb>0 ); - assert( sqlite3Isalnum(zPath[nDb]) ); -#else - /* If 8+3 names are possible, then the journal file might not contain - ** a '-' character. So check for that case and return early. */ - if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK; -#endif - nDb--; - } - memcpy(zDb, zPath, nDb); - zDb[nDb] = '\0'; - - rc = getFileMode(zDb, pMode, pUid, pGid); - }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ - *pMode = 0600; - }else if( flags & SQLITE_OPEN_URI ){ - /* If this is a main database file and the file was opened using a URI - ** filename, check for the "modeof" parameter. If present, interpret - ** its value as a filename and try to copy the mode, uid and gid from - ** that file. */ - const char *z = sqlite3_uri_parameter(zPath, "modeof"); - if( z ){ - rc = getFileMode(z, pMode, pUid, pGid); - } - } - return rc; -} - -/* -** Open the file zPath. -** -** Previously, the SQLite OS layer used three functions in place of this -** one: -** -** sqlite3OsOpenReadWrite(); -** sqlite3OsOpenReadOnly(); -** sqlite3OsOpenExclusive(); -** -** These calls correspond to the following combinations of flags: -** -** ReadWrite() -> (READWRITE | CREATE) -** ReadOnly() -> (READONLY) -** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) -** -** The old OpenExclusive() accepted a boolean argument - "delFlag". If -** true, the file was configured to be automatically deleted when the -** file handle closed. To achieve the same effect using this new -** interface, add the DELETEONCLOSE flag to those specified above for -** OpenExclusive(). -*/ -static int unixOpen( - sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ - const char *zPath, /* Pathname of file to be opened */ - sqlite3_file *pFile, /* The file descriptor to be filled in */ - int flags, /* Input flags to control the opening */ - int *pOutFlags /* Output flags returned to SQLite core */ -){ - unixFile *p = (unixFile *)pFile; - int fd = -1; /* File descriptor returned by open() */ - int openFlags = 0; /* Flags to pass to open() */ - int eType = flags&0xFFFFFF00; /* Type of file to open */ - int noLock; /* True to omit locking primitives */ - int rc = SQLITE_OK; /* Function Return Code */ - int ctrlFlags = 0; /* UNIXFILE_* flags */ - - int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); - int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); - int isCreate = (flags & SQLITE_OPEN_CREATE); - int isReadonly = (flags & SQLITE_OPEN_READONLY); - int isReadWrite = (flags & SQLITE_OPEN_READWRITE); -#if SQLITE_ENABLE_LOCKING_STYLE - int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); -#endif -#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE - struct statfs fsInfo; -#endif - - /* If creating a master or main-file journal, this function will open - ** a file-descriptor on the directory too. The first time unixSync() - ** is called the directory file descriptor will be fsync()ed and close()d. - */ - int syncDir = (isCreate && ( - eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_MAIN_JOURNAL - || eType==SQLITE_OPEN_WAL - )); - - /* If argument zPath is a NULL pointer, this function is required to open - ** a temporary file. Use this buffer to store the file name in. - */ - char zTmpname[MAX_PATHNAME+2]; - const char *zName = zPath; - - /* Check the following statements are true: - ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and - ** (b) if CREATE is set, then READWRITE must also be set, and - ** (c) if EXCLUSIVE is set, then CREATE must also be set. - ** (d) if DELETEONCLOSE is set, then CREATE must also be set. - */ - assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); - assert(isCreate==0 || isReadWrite); - assert(isExclusive==0 || isCreate); - assert(isDelete==0 || isCreate); - - /* The main DB, main journal, WAL file and master journal are never - ** automatically deleted. Nor are they ever temporary files. */ - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); - - /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL - ); - - /* Detect a pid change and reset the PRNG. There is a race condition - ** here such that two or more threads all trying to open databases at - ** the same instant might all reset the PRNG. But multiple resets - ** are harmless. - */ - if( randomnessPid!=osGetpid(0) ){ - randomnessPid = osGetpid(0); - sqlite3_randomness(0,0); - } - - memset(p, 0, sizeof(unixFile)); - - if( eType==SQLITE_OPEN_MAIN_DB ){ - UnixUnusedFd *pUnused; - pUnused = findReusableFd(zName, flags); - if( pUnused ){ - fd = pUnused->fd; - }else{ - pUnused = sqlite3_malloc64(sizeof(*pUnused)); - if( !pUnused ){ - return SQLITE_NOMEM_BKPT; - } - } - p->pUnused = pUnused; - - /* Database filenames are double-zero terminated if they are not - ** URIs with parameters. Hence, they can always be passed into - ** sqlite3_uri_parameter(). */ - assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); - - }else if( !zName ){ - /* If zName is NULL, the upper layer is requesting a temp file. */ - assert(isDelete && !syncDir); - rc = unixGetTempname(pVfs->mxPathname, zTmpname); - if( rc!=SQLITE_OK ){ - return rc; - } - zName = zTmpname; - - /* Generated temporary filenames are always double-zero terminated - ** for use by sqlite3_uri_parameter(). */ - assert( zName[strlen(zName)+1]==0 ); - } - - /* Determine the value of the flags parameter passed to POSIX function - ** open(). These must be calculated even if open() is not called, as - ** they may be stored as part of the file handle and used by the - ** 'conch file' locking functions later on. */ - if( isReadonly ) openFlags |= O_RDONLY; - if( isReadWrite ) openFlags |= O_RDWR; - if( isCreate ) openFlags |= O_CREAT; - if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); - openFlags |= (O_LARGEFILE|O_BINARY); - - if( fd<0 ){ - mode_t openMode; /* Permissions to create file with */ - uid_t uid; /* Userid for the file */ - gid_t gid; /* Groupid for the file */ - rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); - if( rc!=SQLITE_OK ){ - assert( !p->pUnused ); - assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); - return rc; - } - fd = robust_open(zName, openFlags, openMode); - OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); - assert( !isExclusive || (openFlags & O_CREAT)!=0 ); - if( fd<0 && errno!=EISDIR && isReadWrite ){ - /* Failed to open the file for read/write access. Try read-only. */ - flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); - openFlags &= ~(O_RDWR|O_CREAT); - flags |= SQLITE_OPEN_READONLY; - openFlags |= O_RDONLY; - isReadonly = 1; - fd = robust_open(zName, openFlags, openMode); - } - if( fd<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); - goto open_finished; - } - - /* If this process is running as root and if creating a new rollback - ** journal or WAL file, set the ownership of the journal or WAL to be - ** the same as the original database. - */ - if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ - robustFchown(fd, uid, gid); - } - } - assert( fd>=0 ); - if( pOutFlags ){ - *pOutFlags = flags; - } - - if( p->pUnused ){ - p->pUnused->fd = fd; - p->pUnused->flags = flags; - } - - if( isDelete ){ -#if OS_VXWORKS - zPath = zName; -#elif defined(SQLITE_UNLINK_AFTER_CLOSE) - zPath = sqlite3_mprintf("%s", zName); - if( zPath==0 ){ - robust_close(p, fd, __LINE__); - return SQLITE_NOMEM_BKPT; - } -#else - osUnlink(zName); -#endif - } -#if SQLITE_ENABLE_LOCKING_STYLE - else{ - p->openFlags = openFlags; - } -#endif - -#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE - if( fstatfs(fd, &fsInfo) == -1 ){ - storeLastErrno(p, errno); - robust_close(p, fd, __LINE__); - return SQLITE_IOERR_ACCESS; - } - if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { - ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; - } - if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { - ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; - } -#endif - - /* Set up appropriate ctrlFlags */ - if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; - if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; - noLock = eType!=SQLITE_OPEN_MAIN_DB; - if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; - if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC; - if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; - -#if SQLITE_ENABLE_LOCKING_STYLE -#if SQLITE_PREFER_PROXY_LOCKING - isAutoProxy = 1; -#endif - if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ - char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); - int useProxy = 0; - - /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means - ** never use proxy, NULL means use proxy for non-local files only. */ - if( envforce!=NULL ){ - useProxy = atoi(envforce)>0; - }else{ - useProxy = !(fsInfo.f_flags&MNT_LOCAL); - } - if( useProxy ){ - rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); - if( rc==SQLITE_OK ){ - rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); - if( rc!=SQLITE_OK ){ - /* Use unixClose to clean up the resources added in fillInUnixFile - ** and clear all the structure's references. Specifically, - ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op - */ - unixClose(pFile); - return rc; - } - } - goto open_finished; - } - } -#endif - - rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); - -open_finished: - if( rc!=SQLITE_OK ){ - sqlite3_free(p->pUnused); - } - return rc; -} - - -/* -** Delete the file at zPath. If the dirSync argument is true, fsync() -** the directory after deleting the file. -*/ -static int unixDelete( - sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ - const char *zPath, /* Name of file to be deleted */ - int dirSync /* If true, fsync() directory after deleting file */ -){ - int rc = SQLITE_OK; - UNUSED_PARAMETER(NotUsed); - SimulateIOError(return SQLITE_IOERR_DELETE); - if( osUnlink(zPath)==(-1) ){ - if( errno==ENOENT -#if OS_VXWORKS - || osAccess(zPath,0)!=0 -#endif - ){ - rc = SQLITE_IOERR_DELETE_NOENT; - }else{ - rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); - } - return rc; - } -#ifndef SQLITE_DISABLE_DIRSYNC - if( (dirSync & 1)!=0 ){ - int fd; - rc = osOpenDirectory(zPath, &fd); - if( rc==SQLITE_OK ){ - if( full_fsync(fd,0,0) ){ - rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); - } - robust_close(0, fd, __LINE__); - }else{ - assert( rc==SQLITE_CANTOPEN ); - rc = SQLITE_OK; - } - } -#endif - return rc; -} - -/* -** Test the existence of or access permissions of file zPath. The -** test performed depends on the value of flags: -** -** SQLITE_ACCESS_EXISTS: Return 1 if the file exists -** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. -** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. -** -** Otherwise return 0. -*/ -static int unixAccess( - sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ - const char *zPath, /* Path of the file to examine */ - int flags, /* What do we want to learn about the zPath file? */ - int *pResOut /* Write result boolean here */ -){ - UNUSED_PARAMETER(NotUsed); - SimulateIOError( return SQLITE_IOERR_ACCESS; ); - assert( pResOut!=0 ); - - /* The spec says there are three possible values for flags. But only - ** two of them are actually used */ - assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); - - if( flags==SQLITE_ACCESS_EXISTS ){ - struct stat buf; - *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0); - }else{ - *pResOut = osAccess(zPath, W_OK|R_OK)==0; - } - return SQLITE_OK; -} - -/* -** -*/ -static int mkFullPathname( - const char *zPath, /* Input path */ - char *zOut, /* Output buffer */ - int nOut /* Allocated size of buffer zOut */ -){ - int nPath = sqlite3Strlen30(zPath); - int iOff = 0; - if( zPath[0]!='/' ){ - if( osGetcwd(zOut, nOut-2)==0 ){ - return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); - } - iOff = sqlite3Strlen30(zOut); - zOut[iOff++] = '/'; - } - if( (iOff+nPath+1)>nOut ){ - /* SQLite assumes that xFullPathname() nul-terminates the output buffer - ** even if it returns an error. */ - zOut[iOff] = '\0'; - return SQLITE_CANTOPEN_BKPT; - } - sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); - return SQLITE_OK; -} - -/* -** Turn a relative pathname into a full pathname. The relative path -** is stored as a nul-terminated string in the buffer pointed to by -** zPath. -** -** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes -** (in this case, MAX_PATHNAME bytes). The full-path is written to -** this buffer before returning. -*/ -static int unixFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zPath, /* Possibly relative input path */ - int nOut, /* Size of output buffer in bytes */ - char *zOut /* Output buffer */ -){ -#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT) - return mkFullPathname(zPath, zOut, nOut); -#else - int rc = SQLITE_OK; - int nByte; - int nLink = 1; /* Number of symbolic links followed so far */ - const char *zIn = zPath; /* Input path for each iteration of loop */ - char *zDel = 0; - - assert( pVfs->mxPathname==MAX_PATHNAME ); - UNUSED_PARAMETER(pVfs); - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. This function could fail if, for example, the - ** current working directory has been unlinked. - */ - SimulateIOError( return SQLITE_ERROR ); - - do { - - /* Call stat() on path zIn. Set bLink to true if the path is a symbolic - ** link, or false otherwise. */ - int bLink = 0; - struct stat buf; - if( osLstat(zIn, &buf)!=0 ){ - if( errno!=ENOENT ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); - } - }else{ - bLink = S_ISLNK(buf.st_mode); - } - - if( bLink ){ - if( zDel==0 ){ - zDel = sqlite3_malloc(nOut); - if( zDel==0 ) rc = SQLITE_NOMEM_BKPT; - }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ - rc = SQLITE_CANTOPEN_BKPT; - } - - if( rc==SQLITE_OK ){ - nByte = osReadlink(zIn, zDel, nOut-1); - if( nByte<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); - }else{ - if( zDel[0]!='/' ){ - int n; - for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); - if( nByte+n+1>nOut ){ - rc = SQLITE_CANTOPEN_BKPT; - }else{ - memmove(&zDel[n], zDel, nByte+1); - memcpy(zDel, zIn, n); - nByte += n; - } - } - zDel[nByte] = '\0'; - } - } - - zIn = zDel; - } - - assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' ); - if( rc==SQLITE_OK && zIn!=zOut ){ - rc = mkFullPathname(zIn, zOut, nOut); - } - if( bLink==0 ) break; - zIn = zOut; - }while( rc==SQLITE_OK ); - - sqlite3_free(zDel); - return rc; -#endif /* HAVE_READLINK && HAVE_LSTAT */ -} - - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -#include -static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ - UNUSED_PARAMETER(NotUsed); - return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); -} - -/* -** SQLite calls this function immediately after a call to unixDlSym() or -** unixDlOpen() fails (returns a null pointer). If a more detailed error -** message is available, it is written to zBufOut. If no error message -** is available, zBufOut is left unmodified and SQLite uses a default -** error message. -*/ -static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ - const char *zErr; - UNUSED_PARAMETER(NotUsed); - unixEnterMutex(); - zErr = dlerror(); - if( zErr ){ - sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); - } - unixLeaveMutex(); -} -static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ - /* - ** GCC with -pedantic-errors says that C90 does not allow a void* to be - ** cast into a pointer to a function. And yet the library dlsym() routine - ** returns a void* which is really a pointer to a function. So how do we - ** use dlsym() with -pedantic-errors? - ** - ** Variable x below is defined to be a pointer to a function taking - ** parameters void* and const char* and returning a pointer to a function. - ** We initialize x by assigning it a pointer to the dlsym() function. - ** (That assignment requires a cast.) Then we call the function that - ** x points to. - ** - ** This work-around is unlikely to work correctly on any system where - ** you really cannot cast a function pointer into void*. But then, on the - ** other hand, dlsym() will not work on such a system either, so we have - ** not really lost anything. - */ - void (*(*x)(void*,const char*))(void); - UNUSED_PARAMETER(NotUsed); - x = (void(*(*)(void*,const char*))(void))dlsym; - return (*x)(p, zSym); -} -static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ - UNUSED_PARAMETER(NotUsed); - dlclose(pHandle); -} -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ - #define unixDlOpen 0 - #define unixDlError 0 - #define unixDlSym 0 - #define unixDlClose 0 -#endif - -/* -** Write nBuf bytes of random data to the supplied buffer zBuf. -*/ -static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ - UNUSED_PARAMETER(NotUsed); - assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); - - /* We have to initialize zBuf to prevent valgrind from reporting - ** errors. The reports issued by valgrind are incorrect - we would - ** prefer that the randomness be increased by making use of the - ** uninitialized space in zBuf - but valgrind errors tend to worry - ** some users. Rather than argue, it seems easier just to initialize - ** the whole array and silence valgrind, even if that means less randomness - ** in the random seed. - ** - ** When testing, initializing zBuf[] to zero is all we do. That means - ** that we always use the same random number sequence. This makes the - ** tests repeatable. - */ - memset(zBuf, 0, nBuf); - randomnessPid = osGetpid(0); -#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) - { - int fd, got; - fd = robust_open("/dev/urandom", O_RDONLY, 0); - if( fd<0 ){ - time_t t; - time(&t); - memcpy(zBuf, &t, sizeof(t)); - memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); - assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); - nBuf = sizeof(t) + sizeof(randomnessPid); - }else{ - do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); - robust_close(0, fd, __LINE__); - } - } -#endif - return nBuf; -} - - -/* -** Sleep for a little while. Return the amount of time slept. -** The argument is the number of microseconds we want to sleep. -** The return value is the number of microseconds of sleep actually -** requested from the underlying operating system, a number which -** might be greater than or equal to the argument, but not less -** than the argument. -*/ -static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if OS_VXWORKS - struct timespec sp; - - sp.tv_sec = microseconds / 1000000; - sp.tv_nsec = (microseconds % 1000000) * 1000; - nanosleep(&sp, NULL); - UNUSED_PARAMETER(NotUsed); - return microseconds; -#elif defined(HAVE_USLEEP) && HAVE_USLEEP - usleep(microseconds); - UNUSED_PARAMETER(NotUsed); - return microseconds; -#else - int seconds = (microseconds+999999)/1000000; - sleep(seconds); - UNUSED_PARAMETER(NotUsed); - return seconds*1000000; -#endif -} - -/* -** The following variable, if set to a non-zero value, is interpreted as -** the number of seconds since 1970 and is used to set the result of -** sqlite3OsCurrentTime() during testing. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ -#endif - -/* -** Find the current time (in Universal Coordinated Time). Write into *piNow -** the current time and date as a Julian Day number times 86_400_000. In -** other words, write into *piNow the number of milliseconds since the Julian -** epoch of noon in Greenwich on November 24, 4714 B.C according to the -** proleptic Gregorian calendar. -** -** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date -** cannot be found. -*/ -static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ - static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; - int rc = SQLITE_OK; -#if defined(NO_GETTOD) - time_t t; - time(&t); - *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; -#elif OS_VXWORKS - struct timespec sNow; - clock_gettime(CLOCK_REALTIME, &sNow); - *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; -#else - struct timeval sNow; - (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ - *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; -#endif - -#ifdef SQLITE_TEST - if( sqlite3_current_time ){ - *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; - } -#endif - UNUSED_PARAMETER(NotUsed); - return rc; -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. -*/ -static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ - sqlite3_int64 i = 0; - int rc; - UNUSED_PARAMETER(NotUsed); - rc = unixCurrentTimeInt64(0, &i); - *prNow = i/86400000.0; - return rc; -} -#else -# define unixCurrentTime 0 -#endif - -/* -** The xGetLastError() method is designed to return a better -** low-level error message when operating-system problems come up -** during SQLite operation. Only the integer return code is currently -** used. -*/ -static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ - UNUSED_PARAMETER(NotUsed); - UNUSED_PARAMETER(NotUsed2); - UNUSED_PARAMETER(NotUsed3); - return errno; -} - - -/* -************************ End of sqlite3_vfs methods *************************** -******************************************************************************/ - -/****************************************************************************** -************************** Begin Proxy Locking ******************************** -** -** Proxy locking is a "uber-locking-method" in this sense: It uses the -** other locking methods on secondary lock files. Proxy locking is a -** meta-layer over top of the primitive locking implemented above. For -** this reason, the division that implements of proxy locking is deferred -** until late in the file (here) after all of the other I/O methods have -** been defined - so that the primitive locking methods are available -** as services to help with the implementation of proxy locking. -** -**** -** -** The default locking schemes in SQLite use byte-range locks on the -** database file to coordinate safe, concurrent access by multiple readers -** and writers [http://sqlite.org/lockingv3.html]. The five file locking -** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented -** as POSIX read & write locks over fixed set of locations (via fsctl), -** on AFP and SMB only exclusive byte-range locks are available via fsctl -** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states. -** To simulate a F_RDLCK on the shared range, on AFP a randomly selected -** address in the shared range is taken for a SHARED lock, the entire -** shared range is taken for an EXCLUSIVE lock): -** -** PENDING_BYTE 0x40000000 -** RESERVED_BYTE 0x40000001 -** SHARED_RANGE 0x40000002 -> 0x40000200 -** -** This works well on the local file system, but shows a nearly 100x -** slowdown in read performance on AFP because the AFP client disables -** the read cache when byte-range locks are present. Enabling the read -** cache exposes a cache coherency problem that is present on all OS X -** supported network file systems. NFS and AFP both observe the -** close-to-open semantics for ensuring cache coherency -** [http://nfs.sourceforge.net/#faq_a8], which does not effectively -** address the requirements for concurrent database access by multiple -** readers and writers -** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html]. -** -** To address the performance and cache coherency issues, proxy file locking -** changes the way database access is controlled by limiting access to a -** single host at a time and moving file locks off of the database file -** and onto a proxy file on the local file system. -** -** -** Using proxy locks -** ----------------- -** -** C APIs -** -** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, -** | ":auto:"); -** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, -** &); -** -** -** SQL pragmas -** -** PRAGMA [database.]lock_proxy_file= | :auto: -** PRAGMA [database.]lock_proxy_file -** -** Specifying ":auto:" means that if there is a conch file with a matching -** host ID in it, the proxy path in the conch file will be used, otherwise -** a proxy path based on the user's temp dir -** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the -** actual proxy file name is generated from the name and path of the -** database file. For example: -** -** For database path "/Users/me/foo.db" -** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") -** -** Once a lock proxy is configured for a database connection, it can not -** be removed, however it may be switched to a different proxy path via -** the above APIs (assuming the conch file is not being held by another -** connection or process). -** -** -** How proxy locking works -** ----------------------- -** -** Proxy file locking relies primarily on two new supporting files: -** -** * conch file to limit access to the database file to a single host -** at a time -** -** * proxy file to act as a proxy for the advisory locks normally -** taken on the database -** -** The conch file - to use a proxy file, sqlite must first "hold the conch" -** by taking an sqlite-style shared lock on the conch file, reading the -** contents and comparing the host's unique host ID (see below) and lock -** proxy path against the values stored in the conch. The conch file is -** stored in the same directory as the database file and the file name -** is patterned after the database file name as ".-conch". -** If the conch file does not exist, or its contents do not match the -** host ID and/or proxy path, then the lock is escalated to an exclusive -** lock and the conch file contents is updated with the host ID and proxy -** path and the lock is downgraded to a shared lock again. If the conch -** is held by another process (with a shared lock), the exclusive lock -** will fail and SQLITE_BUSY is returned. -** -** The proxy file - a single-byte file used for all advisory file locks -** normally taken on the database file. This allows for safe sharing -** of the database file for multiple readers and writers on the same -** host (the conch ensures that they all use the same local lock file). -** -** Requesting the lock proxy does not immediately take the conch, it is -** only taken when the first request to lock database file is made. -** This matches the semantics of the traditional locking behavior, where -** opening a connection to a database file does not take a lock on it. -** The shared lock and an open file descriptor are maintained until -** the connection to the database is closed. -** -** The proxy file and the lock file are never deleted so they only need -** to be created the first time they are used. -** -** Configuration options -** --------------------- -** -** SQLITE_PREFER_PROXY_LOCKING -** -** Database files accessed on non-local file systems are -** automatically configured for proxy locking, lock files are -** named automatically using the same logic as -** PRAGMA lock_proxy_file=":auto:" -** -** SQLITE_PROXY_DEBUG -** -** Enables the logging of error messages during host id file -** retrieval and creation -** -** LOCKPROXYDIR -** -** Overrides the default directory used for lock proxy files that -** are named automatically via the ":auto:" setting -** -** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS -** -** Permissions to use when creating a directory for storing the -** lock proxy files, only used when LOCKPROXYDIR is not set. -** -** -** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, -** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will -** force proxy locking to be used for every database file opened, and 0 -** will force automatic proxy locking to be disabled for all database -** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or -** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). -*/ - -/* -** Proxy locking is only available on MacOSX -*/ -#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE - -/* -** The proxyLockingContext has the path and file structures for the remote -** and local proxy files in it -*/ -typedef struct proxyLockingContext proxyLockingContext; -struct proxyLockingContext { - unixFile *conchFile; /* Open conch file */ - char *conchFilePath; /* Name of the conch file */ - unixFile *lockProxy; /* Open proxy lock file */ - char *lockProxyPath; /* Name of the proxy lock file */ - char *dbPath; /* Name of the open file */ - int conchHeld; /* 1 if the conch is held, -1 if lockless */ - int nFails; /* Number of conch taking failures */ - void *oldLockingContext; /* Original lockingcontext to restore on close */ - sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ -}; - -/* -** The proxy lock file path for the database at dbPath is written into lPath, -** which must point to valid, writable memory large enough for a maxLen length -** file path. -*/ -static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ - int len; - int dbLen; - int i; - -#ifdef LOCKPROXYDIR - len = strlcpy(lPath, LOCKPROXYDIR, maxLen); -#else -# ifdef _CS_DARWIN_USER_TEMP_DIR - { - if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ - OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", - lPath, errno, osGetpid(0))); - return SQLITE_IOERR_LOCK; - } - len = strlcat(lPath, "sqliteplocks", maxLen); - } -# else - len = strlcpy(lPath, "/tmp/", maxLen); -# endif -#endif - - if( lPath[len-1]!='/' ){ - len = strlcat(lPath, "/", maxLen); - } - - /* transform the db path to a unique cache name */ - dbLen = (int)strlen(dbPath); - for( i=0; i 0) ){ - /* only mkdir if leaf dir != "." or "/" or ".." */ - if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') - || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ - buf[i]='\0'; - if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ - int err=errno; - if( err!=EEXIST ) { - OSTRACE(("CREATELOCKPATH FAILED creating %s, " - "'%s' proxy lock path=%s pid=%d\n", - buf, strerror(err), lockPath, osGetpid(0))); - return err; - } - } - } - start=i+1; - } - buf[i] = lockPath[i]; - } - OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0))); - return 0; -} - -/* -** Create a new VFS file descriptor (stored in memory obtained from -** sqlite3_malloc) and open the file named "path" in the file descriptor. -** -** The caller is responsible not only for closing the file descriptor -** but also for freeing the memory associated with the file descriptor. -*/ -static int proxyCreateUnixFile( - const char *path, /* path for the new unixFile */ - unixFile **ppFile, /* unixFile created and returned by ref */ - int islockfile /* if non zero missing dirs will be created */ -) { - int fd = -1; - unixFile *pNew; - int rc = SQLITE_OK; - int openFlags = O_RDWR | O_CREAT; - sqlite3_vfs dummyVfs; - int terrno = 0; - UnixUnusedFd *pUnused = NULL; - - /* 1. first try to open/create the file - ** 2. if that fails, and this is a lock file (not-conch), try creating - ** the parent directories and then try again. - ** 3. if that fails, try to open the file read-only - ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file - */ - pUnused = findReusableFd(path, openFlags); - if( pUnused ){ - fd = pUnused->fd; - }else{ - pUnused = sqlite3_malloc64(sizeof(*pUnused)); - if( !pUnused ){ - return SQLITE_NOMEM_BKPT; - } - } - if( fd<0 ){ - fd = robust_open(path, openFlags, 0); - terrno = errno; - if( fd<0 && errno==ENOENT && islockfile ){ - if( proxyCreateLockPath(path) == SQLITE_OK ){ - fd = robust_open(path, openFlags, 0); - } - } - } - if( fd<0 ){ - openFlags = O_RDONLY; - fd = robust_open(path, openFlags, 0); - terrno = errno; - } - if( fd<0 ){ - if( islockfile ){ - return SQLITE_BUSY; - } - switch (terrno) { - case EACCES: - return SQLITE_PERM; - case EIO: - return SQLITE_IOERR_LOCK; /* even though it is the conch */ - default: - return SQLITE_CANTOPEN_BKPT; - } - } - - pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); - if( pNew==NULL ){ - rc = SQLITE_NOMEM_BKPT; - goto end_create_proxy; - } - memset(pNew, 0, sizeof(unixFile)); - pNew->openFlags = openFlags; - memset(&dummyVfs, 0, sizeof(dummyVfs)); - dummyVfs.pAppData = (void*)&autolockIoFinder; - dummyVfs.zName = "dummy"; - pUnused->fd = fd; - pUnused->flags = openFlags; - pNew->pUnused = pUnused; - - rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); - if( rc==SQLITE_OK ){ - *ppFile = pNew; - return SQLITE_OK; - } -end_create_proxy: - robust_close(pNew, fd, __LINE__); - sqlite3_free(pNew); - sqlite3_free(pUnused); - return rc; -} - -#ifdef SQLITE_TEST -/* simulate multiple hosts by creating unique hostid file paths */ -SQLITE_API int sqlite3_hostid_num = 0; -#endif - -#define PROXY_HOSTIDLEN 16 /* conch file host id length */ - -#ifdef HAVE_GETHOSTUUID -/* Not always defined in the headers as it ought to be */ -extern int gethostuuid(uuid_t id, const struct timespec *wait); -#endif - -/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN -** bytes of writable memory. -*/ -static int proxyGetHostID(unsigned char *pHostID, int *pError){ - assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); - memset(pHostID, 0, PROXY_HOSTIDLEN); -#ifdef HAVE_GETHOSTUUID - { - struct timespec timeout = {1, 0}; /* 1 sec timeout */ - if( gethostuuid(pHostID, &timeout) ){ - int err = errno; - if( pError ){ - *pError = err; - } - return SQLITE_IOERR; - } - } -#else - UNUSED_PARAMETER(pError); -#endif -#ifdef SQLITE_TEST - /* simulate multiple hosts by creating unique hostid file paths */ - if( sqlite3_hostid_num != 0){ - pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); - } -#endif - - return SQLITE_OK; -} - -/* The conch file contains the header, host id and lock file path - */ -#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ -#define PROXY_HEADERLEN 1 /* conch file header length */ -#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) -#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) - -/* -** Takes an open conch file, copies the contents to a new path and then moves -** it back. The newly created file's file descriptor is assigned to the -** conch file structure and finally the original conch file descriptor is -** closed. Returns zero if successful. -*/ -static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - unixFile *conchFile = pCtx->conchFile; - char tPath[MAXPATHLEN]; - char buf[PROXY_MAXCONCHLEN]; - char *cPath = pCtx->conchFilePath; - size_t readLen = 0; - size_t pathLen = 0; - char errmsg[64] = ""; - int fd = -1; - int rc = -1; - UNUSED_PARAMETER(myHostID); - - /* create a new path by replace the trailing '-conch' with '-break' */ - pathLen = strlcpy(tPath, cPath, MAXPATHLEN); - if( pathLen>MAXPATHLEN || pathLen<6 || - (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ - sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); - goto end_breaklock; - } - /* read the conch content */ - readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); - if( readLenh, __LINE__); - conchFile->h = fd; - conchFile->openFlags = O_RDWR | O_CREAT; - -end_breaklock: - if( rc ){ - if( fd>=0 ){ - osUnlink(tPath); - robust_close(pFile, fd, __LINE__); - } - fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); - } - return rc; -} - -/* Take the requested lock on the conch file and break a stale lock if the -** host id matches. -*/ -static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - unixFile *conchFile = pCtx->conchFile; - int rc = SQLITE_OK; - int nTries = 0; - struct timespec conchModTime; - - memset(&conchModTime, 0, sizeof(conchModTime)); - do { - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); - nTries ++; - if( rc==SQLITE_BUSY ){ - /* If the lock failed (busy): - * 1st try: get the mod time of the conch, wait 0.5s and try again. - * 2nd try: fail if the mod time changed or host id is different, wait - * 10 sec and try again - * 3rd try: break the lock unless the mod time has changed. - */ - struct stat buf; - if( osFstat(conchFile->h, &buf) ){ - storeLastErrno(pFile, errno); - return SQLITE_IOERR_LOCK; - } - - if( nTries==1 ){ - conchModTime = buf.st_mtimespec; - usleep(500000); /* wait 0.5 sec and try the lock again*/ - continue; - } - - assert( nTries>1 ); - if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || - conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ - return SQLITE_BUSY; - } - - if( nTries==2 ){ - char tBuf[PROXY_MAXCONCHLEN]; - int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); - if( len<0 ){ - storeLastErrno(pFile, errno); - return SQLITE_IOERR_LOCK; - } - if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ - /* don't break the lock if the host id doesn't match */ - if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ - return SQLITE_BUSY; - } - }else{ - /* don't break the lock on short read or a version mismatch */ - return SQLITE_BUSY; - } - usleep(10000000); /* wait 10 sec and try the lock again */ - continue; - } - - assert( nTries==3 ); - if( 0==proxyBreakConchLock(pFile, myHostID) ){ - rc = SQLITE_OK; - if( lockType==EXCLUSIVE_LOCK ){ - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); - } - if( !rc ){ - rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); - } - } - } - } while( rc==SQLITE_BUSY && nTries<3 ); - - return rc; -} - -/* Takes the conch by taking a shared lock and read the contents conch, if -** lockPath is non-NULL, the host ID and lock file path must match. A NULL -** lockPath means that the lockPath in the conch file will be used if the -** host IDs match, or a new lock path will be generated automatically -** and written to the conch file. -*/ -static int proxyTakeConch(unixFile *pFile){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - - if( pCtx->conchHeld!=0 ){ - return SQLITE_OK; - }else{ - unixFile *conchFile = pCtx->conchFile; - uuid_t myHostID; - int pError = 0; - char readBuf[PROXY_MAXCONCHLEN]; - char lockPath[MAXPATHLEN]; - char *tempLockPath = NULL; - int rc = SQLITE_OK; - int createConch = 0; - int hostIdMatch = 0; - int readLen = 0; - int tryOldLockPath = 0; - int forceNewLockPath = 0; - - OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), - osGetpid(0))); - - rc = proxyGetHostID(myHostID, &pError); - if( (rc&0xff)==SQLITE_IOERR ){ - storeLastErrno(pFile, pError); - goto end_takeconch; - } - rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - goto end_takeconch; - } - /* read the existing conch file */ - readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); - if( readLen<0 ){ - /* I/O error: lastErrno set by seekAndRead */ - storeLastErrno(pFile, conchFile->lastErrno); - rc = SQLITE_IOERR_READ; - goto end_takeconch; - }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || - readBuf[0]!=(char)PROXY_CONCHVERSION ){ - /* a short read or version format mismatch means we need to create a new - ** conch file. - */ - createConch = 1; - } - /* if the host id matches and the lock path already exists in the conch - ** we'll try to use the path there, if we can't open that path, we'll - ** retry with a new auto-generated path - */ - do { /* in case we need to try again for an :auto: named lock file */ - - if( !createConch && !forceNewLockPath ){ - hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, - PROXY_HOSTIDLEN); - /* if the conch has data compare the contents */ - if( !pCtx->lockProxyPath ){ - /* for auto-named local lock file, just check the host ID and we'll - ** use the local lock file path that's already in there - */ - if( hostIdMatch ){ - size_t pathLen = (readLen - PROXY_PATHINDEX); - - if( pathLen>=MAXPATHLEN ){ - pathLen=MAXPATHLEN-1; - } - memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); - lockPath[pathLen] = 0; - tempLockPath = lockPath; - tryOldLockPath = 1; - /* create a copy of the lock path if the conch is taken */ - goto end_takeconch; - } - }else if( hostIdMatch - && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX], - readLen-PROXY_PATHINDEX) - ){ - /* conch host and lock path match */ - goto end_takeconch; - } - } - - /* if the conch isn't writable and doesn't match, we can't take it */ - if( (conchFile->openFlags&O_RDWR) == 0 ){ - rc = SQLITE_BUSY; - goto end_takeconch; - } - - /* either the conch didn't match or we need to create a new one */ - if( !pCtx->lockProxyPath ){ - proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); - tempLockPath = lockPath; - /* create a copy of the lock path _only_ if the conch is taken */ - } - - /* update conch with host and path (this will fail if other process - ** has a shared lock already), if the host id matches, use the big - ** stick. - */ - futimes(conchFile->h, NULL); - if( hostIdMatch && !createConch ){ - if( conchFile->pInode && conchFile->pInode->nShared>1 ){ - /* We are trying for an exclusive lock but another thread in this - ** same process is still holding a shared lock. */ - rc = SQLITE_BUSY; - } else { - rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); - } - }else{ - rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); - } - if( rc==SQLITE_OK ){ - char writeBuffer[PROXY_MAXCONCHLEN]; - int writeSize = 0; - - writeBuffer[0] = (char)PROXY_CONCHVERSION; - memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); - if( pCtx->lockProxyPath!=NULL ){ - strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, - MAXPATHLEN); - }else{ - strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); - } - writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); - robust_ftruncate(conchFile->h, writeSize); - rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); - full_fsync(conchFile->h,0,0); - /* If we created a new conch file (not just updated the contents of a - ** valid conch file), try to match the permissions of the database - */ - if( rc==SQLITE_OK && createConch ){ - struct stat buf; - int err = osFstat(pFile->h, &buf); - if( err==0 ){ - mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | - S_IROTH|S_IWOTH); - /* try to match the database file R/W permissions, ignore failure */ -#ifndef SQLITE_PROXY_DEBUG - osFchmod(conchFile->h, cmode); -#else - do{ - rc = osFchmod(conchFile->h, cmode); - }while( rc==(-1) && errno==EINTR ); - if( rc!=0 ){ - int code = errno; - fprintf(stderr, "fchmod %o FAILED with %d %s\n", - cmode, code, strerror(code)); - } else { - fprintf(stderr, "fchmod %o SUCCEDED\n",cmode); - } - }else{ - int code = errno; - fprintf(stderr, "STAT FAILED[%d] with %d %s\n", - err, code, strerror(code)); -#endif - } - } - } - conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); - - end_takeconch: - OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); - if( rc==SQLITE_OK && pFile->openFlags ){ - int fd; - if( pFile->h>=0 ){ - robust_close(pFile, pFile->h, __LINE__); - } - pFile->h = -1; - fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); - OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); - if( fd>=0 ){ - pFile->h = fd; - }else{ - rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called - during locking */ - } - } - if( rc==SQLITE_OK && !pCtx->lockProxy ){ - char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath; - rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); - if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ - /* we couldn't create the proxy lock file with the old lock file path - ** so try again via auto-naming - */ - forceNewLockPath = 1; - tryOldLockPath = 0; - continue; /* go back to the do {} while start point, try again */ - } - } - if( rc==SQLITE_OK ){ - /* Need to make a copy of path if we extracted the value - ** from the conch file or the path was allocated on the stack - */ - if( tempLockPath ){ - pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); - if( !pCtx->lockProxyPath ){ - rc = SQLITE_NOMEM_BKPT; - } - } - } - if( rc==SQLITE_OK ){ - pCtx->conchHeld = 1; - - if( pCtx->lockProxy->pMethod == &afpIoMethods ){ - afpLockingContext *afpCtx; - afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; - afpCtx->dbPath = pCtx->lockProxyPath; - } - } else { - conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); - } - OSTRACE(("TAKECONCH %d %s\n", conchFile->h, - rc==SQLITE_OK?"ok":"failed")); - return rc; - } while (1); /* in case we need to retry the :auto: lock file - - ** we should never get here except via the 'continue' call. */ - } -} - -/* -** If pFile holds a lock on a conch file, then release that lock. -*/ -static int proxyReleaseConch(unixFile *pFile){ - int rc = SQLITE_OK; /* Subroutine return code */ - proxyLockingContext *pCtx; /* The locking context for the proxy lock */ - unixFile *conchFile; /* Name of the conch file */ - - pCtx = (proxyLockingContext *)pFile->lockingContext; - conchFile = pCtx->conchFile; - OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), - osGetpid(0))); - if( pCtx->conchHeld>0 ){ - rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); - } - pCtx->conchHeld = 0; - OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, - (rc==SQLITE_OK ? "ok" : "failed"))); - return rc; -} - -/* -** Given the name of a database file, compute the name of its conch file. -** Store the conch filename in memory obtained from sqlite3_malloc64(). -** Make *pConchPath point to the new name. Return SQLITE_OK on success -** or SQLITE_NOMEM if unable to obtain memory. -** -** The caller is responsible for ensuring that the allocated memory -** space is eventually freed. -** -** *pConchPath is set to NULL if a memory allocation error occurs. -*/ -static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ - int i; /* Loop counter */ - int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ - char *conchPath; /* buffer in which to construct conch name */ - - /* Allocate space for the conch filename and initialize the name to - ** the name of the original database file. */ - *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); - if( conchPath==0 ){ - return SQLITE_NOMEM_BKPT; - } - memcpy(conchPath, dbPath, len+1); - - /* now insert a "." before the last / character */ - for( i=(len-1); i>=0; i-- ){ - if( conchPath[i]=='/' ){ - i++; - break; - } - } - conchPath[i]='.'; - while ( ilockingContext; - char *oldPath = pCtx->lockProxyPath; - int rc = SQLITE_OK; - - if( pFile->eFileLock!=NO_LOCK ){ - return SQLITE_BUSY; - } - - /* nothing to do if the path is NULL, :auto: or matches the existing path */ - if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || - (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ - return SQLITE_OK; - }else{ - unixFile *lockProxy = pCtx->lockProxy; - pCtx->lockProxy=NULL; - pCtx->conchHeld = 0; - if( lockProxy!=NULL ){ - rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); - if( rc ) return rc; - sqlite3_free(lockProxy); - } - sqlite3_free(oldPath); - pCtx->lockProxyPath = sqlite3DbStrDup(0, path); - } - - return rc; -} - -/* -** pFile is a file that has been opened by a prior xOpen call. dbPath -** is a string buffer at least MAXPATHLEN+1 characters in size. -** -** This routine find the filename associated with pFile and writes it -** int dbPath. -*/ -static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ -#if defined(__APPLE__) - if( pFile->pMethod == &afpIoMethods ){ - /* afp style keeps a reference to the db path in the filePath field - ** of the struct */ - assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); - strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, - MAXPATHLEN); - } else -#endif - if( pFile->pMethod == &dotlockIoMethods ){ - /* dot lock style uses the locking context to store the dot lock - ** file path */ - int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); - memcpy(dbPath, (char *)pFile->lockingContext, len + 1); - }else{ - /* all other styles use the locking context to store the db file path */ - assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); - strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); - } - return SQLITE_OK; -} - -/* -** Takes an already filled in unix file and alters it so all file locking -** will be performed on the local proxy lock file. The following fields -** are preserved in the locking context so that they can be restored and -** the unix structure properly cleaned up at close time: -** ->lockingContext -** ->pMethod -*/ -static int proxyTransformUnixFile(unixFile *pFile, const char *path) { - proxyLockingContext *pCtx; - char dbPath[MAXPATHLEN+1]; /* Name of the database file */ - char *lockPath=NULL; - int rc = SQLITE_OK; - - if( pFile->eFileLock!=NO_LOCK ){ - return SQLITE_BUSY; - } - proxyGetDbPathForUnixFile(pFile, dbPath); - if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ - lockPath=NULL; - }else{ - lockPath=(char *)path; - } - - OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, - (lockPath ? lockPath : ":auto:"), osGetpid(0))); - - pCtx = sqlite3_malloc64( sizeof(*pCtx) ); - if( pCtx==0 ){ - return SQLITE_NOMEM_BKPT; - } - memset(pCtx, 0, sizeof(*pCtx)); - - rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); - if( rc==SQLITE_OK ){ - rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); - if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ - /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and - ** (c) the file system is read-only, then enable no-locking access. - ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts - ** that openFlags will have only one of O_RDONLY or O_RDWR. - */ - struct statfs fsInfo; - struct stat conchInfo; - int goLockless = 0; - - if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { - int err = errno; - if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ - goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; - } - } - if( goLockless ){ - pCtx->conchHeld = -1; /* read only FS/ lockless */ - rc = SQLITE_OK; - } - } - } - if( rc==SQLITE_OK && lockPath ){ - pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); - } - - if( rc==SQLITE_OK ){ - pCtx->dbPath = sqlite3DbStrDup(0, dbPath); - if( pCtx->dbPath==NULL ){ - rc = SQLITE_NOMEM_BKPT; - } - } - if( rc==SQLITE_OK ){ - /* all memory is allocated, proxys are created and assigned, - ** switch the locking context and pMethod then return. - */ - pCtx->oldLockingContext = pFile->lockingContext; - pFile->lockingContext = pCtx; - pCtx->pOldMethod = pFile->pMethod; - pFile->pMethod = &proxyIoMethods; - }else{ - if( pCtx->conchFile ){ - pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); - sqlite3_free(pCtx->conchFile); - } - sqlite3DbFree(0, pCtx->lockProxyPath); - sqlite3_free(pCtx->conchFilePath); - sqlite3_free(pCtx); - } - OSTRACE(("TRANSPROXY %d %s\n", pFile->h, - (rc==SQLITE_OK ? "ok" : "failed"))); - return rc; -} - - -/* -** This routine handles sqlite3_file_control() calls that are specific -** to proxy locking. -*/ -static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ - switch( op ){ - case SQLITE_FCNTL_GET_LOCKPROXYFILE: { - unixFile *pFile = (unixFile*)id; - if( pFile->pMethod == &proxyIoMethods ){ - proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; - proxyTakeConch(pFile); - if( pCtx->lockProxyPath ){ - *(const char **)pArg = pCtx->lockProxyPath; - }else{ - *(const char **)pArg = ":auto: (not held)"; - } - } else { - *(const char **)pArg = NULL; - } - return SQLITE_OK; - } - case SQLITE_FCNTL_SET_LOCKPROXYFILE: { - unixFile *pFile = (unixFile*)id; - int rc = SQLITE_OK; - int isProxyStyle = (pFile->pMethod == &proxyIoMethods); - if( pArg==NULL || (const char *)pArg==0 ){ - if( isProxyStyle ){ - /* turn off proxy locking - not supported. If support is added for - ** switching proxy locking mode off then it will need to fail if - ** the journal mode is WAL mode. - */ - rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; - }else{ - /* turn off proxy locking - already off - NOOP */ - rc = SQLITE_OK; - } - }else{ - const char *proxyPath = (const char *)pArg; - if( isProxyStyle ){ - proxyLockingContext *pCtx = - (proxyLockingContext*)pFile->lockingContext; - if( !strcmp(pArg, ":auto:") - || (pCtx->lockProxyPath && - !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) - ){ - rc = SQLITE_OK; - }else{ - rc = switchLockProxyPath(pFile, proxyPath); - } - }else{ - /* turn on proxy file locking */ - rc = proxyTransformUnixFile(pFile, proxyPath); - } - } - return rc; - } - default: { - assert( 0 ); /* The call assures that only valid opcodes are sent */ - } - } - /*NOTREACHED*/ - return SQLITE_ERROR; -} - -/* -** Within this division (the proxying locking implementation) the procedures -** above this point are all utilities. The lock-related methods of the -** proxy-locking sqlite3_io_method object follow. -*/ - - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -*/ -static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { - unixFile *pFile = (unixFile*)id; - int rc = proxyTakeConch(pFile); - if( rc==SQLITE_OK ){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - if( pCtx->conchHeld>0 ){ - unixFile *proxy = pCtx->lockProxy; - return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); - }else{ /* conchHeld < 0 is lockless */ - pResOut=0; - } - } - return rc; -} - -/* -** Lock the file with the lock specified by parameter eFileLock - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. Use the sqlite3OsUnlock() -** routine to lower a locking level. -*/ -static int proxyLock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - int rc = proxyTakeConch(pFile); - if( rc==SQLITE_OK ){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - if( pCtx->conchHeld>0 ){ - unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); - pFile->eFileLock = proxy->eFileLock; - }else{ - /* conchHeld < 0 is lockless */ - } - } - return rc; -} - - -/* -** Lower the locking level on file descriptor pFile to eFileLock. eFileLock -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -*/ -static int proxyUnlock(sqlite3_file *id, int eFileLock) { - unixFile *pFile = (unixFile*)id; - int rc = proxyTakeConch(pFile); - if( rc==SQLITE_OK ){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - if( pCtx->conchHeld>0 ){ - unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); - pFile->eFileLock = proxy->eFileLock; - }else{ - /* conchHeld < 0 is lockless */ - } - } - return rc; -} - -/* -** Close a file that uses proxy locks. -*/ -static int proxyClose(sqlite3_file *id) { - if( ALWAYS(id) ){ - unixFile *pFile = (unixFile*)id; - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - unixFile *lockProxy = pCtx->lockProxy; - unixFile *conchFile = pCtx->conchFile; - int rc = SQLITE_OK; - - if( lockProxy ){ - rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); - if( rc ) return rc; - rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); - if( rc ) return rc; - sqlite3_free(lockProxy); - pCtx->lockProxy = 0; - } - if( conchFile ){ - if( pCtx->conchHeld ){ - rc = proxyReleaseConch(pFile); - if( rc ) return rc; - } - rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); - if( rc ) return rc; - sqlite3_free(conchFile); - } - sqlite3DbFree(0, pCtx->lockProxyPath); - sqlite3_free(pCtx->conchFilePath); - sqlite3DbFree(0, pCtx->dbPath); - /* restore the original locking context and pMethod then close it */ - pFile->lockingContext = pCtx->oldLockingContext; - pFile->pMethod = pCtx->pOldMethod; - sqlite3_free(pCtx); - return pFile->pMethod->xClose(id); - } - return SQLITE_OK; -} - - - -#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ -/* -** The proxy locking style is intended for use with AFP filesystems. -** And since AFP is only supported on MacOSX, the proxy locking is also -** restricted to MacOSX. -** -** -******************* End of the proxy lock implementation ********************** -******************************************************************************/ - -/* -** Initialize the operating system interface. -** -** This routine registers all VFS implementations for unix-like operating -** systems. This routine, and the sqlite3_os_end() routine that follows, -** should be the only routines in this file that are visible from other -** files. -** -** This routine is called once during SQLite initialization and by a -** single thread. The memory allocation and mutex subsystems have not -** necessarily been initialized when this routine is called, and so they -** should not be used. -*/ -SQLITE_API int sqlite3_os_init(void){ - /* - ** The following macro defines an initializer for an sqlite3_vfs object. - ** The name of the VFS is NAME. The pAppData is a pointer to a pointer - ** to the "finder" function. (pAppData is a pointer to a pointer because - ** silly C90 rules prohibit a void* from being cast to a function pointer - ** and so we have to go through the intermediate pointer to avoid problems - ** when compiling with -pedantic-errors on GCC.) - ** - ** The FINDER parameter to this macro is the name of the pointer to the - ** finder-function. The finder-function returns a pointer to the - ** sqlite_io_methods object that implements the desired locking - ** behaviors. See the division above that contains the IOMETHODS - ** macro for addition information on finder-functions. - ** - ** Most finders simply return a pointer to a fixed sqlite3_io_methods - ** object. But the "autolockIoFinder" available on MacOSX does a little - ** more than that; it looks at the filesystem type that hosts the - ** database file and tries to choose an locking method appropriate for - ** that filesystem time. - */ - #define UNIXVFS(VFSNAME, FINDER) { \ - 3, /* iVersion */ \ - sizeof(unixFile), /* szOsFile */ \ - MAX_PATHNAME, /* mxPathname */ \ - 0, /* pNext */ \ - VFSNAME, /* zName */ \ - (void*)&FINDER, /* pAppData */ \ - unixOpen, /* xOpen */ \ - unixDelete, /* xDelete */ \ - unixAccess, /* xAccess */ \ - unixFullPathname, /* xFullPathname */ \ - unixDlOpen, /* xDlOpen */ \ - unixDlError, /* xDlError */ \ - unixDlSym, /* xDlSym */ \ - unixDlClose, /* xDlClose */ \ - unixRandomness, /* xRandomness */ \ - unixSleep, /* xSleep */ \ - unixCurrentTime, /* xCurrentTime */ \ - unixGetLastError, /* xGetLastError */ \ - unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ - unixSetSystemCall, /* xSetSystemCall */ \ - unixGetSystemCall, /* xGetSystemCall */ \ - unixNextSystemCall, /* xNextSystemCall */ \ - } - - /* - ** All default VFSes for unix are contained in the following array. - ** - ** Note that the sqlite3_vfs.pNext field of the VFS object is modified - ** by the SQLite core when the VFS is registered. So the following - ** array cannot be const. - */ - static sqlite3_vfs aVfs[] = { -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - UNIXVFS("unix", autolockIoFinder ), -#elif OS_VXWORKS - UNIXVFS("unix", vxworksIoFinder ), -#else - UNIXVFS("unix", posixIoFinder ), -#endif - UNIXVFS("unix-none", nolockIoFinder ), - UNIXVFS("unix-dotfile", dotlockIoFinder ), - UNIXVFS("unix-excl", posixIoFinder ), -#if OS_VXWORKS - UNIXVFS("unix-namedsem", semIoFinder ), -#endif -#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS - UNIXVFS("unix-posix", posixIoFinder ), -#endif -#if SQLITE_ENABLE_LOCKING_STYLE - UNIXVFS("unix-flock", flockIoFinder ), -#endif -#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - UNIXVFS("unix-afp", afpIoFinder ), - UNIXVFS("unix-nfs", nfsIoFinder ), - UNIXVFS("unix-proxy", proxyIoFinder ), -#endif - }; - unsigned int i; /* Loop counter */ - - /* Double-check that the aSyscall[] array has been constructed - ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==28 ); - - /* Register all VFSes defined in the aVfs[] array */ - for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ - sqlite3_vfs_register(&aVfs[i], i==0); - } - return SQLITE_OK; -} - -/* -** Shutdown the operating system interface. -** -** Some operating systems might need to do some cleanup in this routine, -** to release dynamically allocated objects. But not on unix. -** This routine is a no-op for unix. -*/ -SQLITE_API int sqlite3_os_end(void){ - return SQLITE_OK; -} - -#endif /* SQLITE_OS_UNIX */ - -/************** End of os_unix.c *********************************************/ -/************** Begin file os_win.c ******************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code that is specific to Windows. -*/ -/* #include "sqliteInt.h" */ -#if SQLITE_OS_WIN /* This file is used for Windows only */ - -/* -** Include code that is common to all os_*.c files -*/ -/************** Include os_common.h in the middle of os_win.c ****************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - #error Need implementation of sqlite3Hwtime() for your platform. - - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in os_win.c *********************/ - -/* -** Include the header file for the Windows VFS. -*/ -/* #include "os_win.h" */ - -/* -** Compiling and using WAL mode requires several APIs that are only -** available in Windows platforms based on the NT kernel. -*/ -#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) -# error "WAL mode requires support from the Windows NT kernel, compile\ - with SQLITE_OMIT_WAL." -#endif - -#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 -# error "Memory mapped files require support from the Windows NT kernel,\ - compile with SQLITE_MAX_MMAP_SIZE=0." -#endif - -/* -** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions -** based on the sub-platform)? -*/ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) -# define SQLITE_WIN32_HAS_ANSI -#endif - -/* -** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions -** based on the sub-platform)? -*/ -#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ - !defined(SQLITE_WIN32_NO_WIDE) -# define SQLITE_WIN32_HAS_WIDE -#endif - -/* -** Make sure at least one set of Win32 APIs is available. -*/ -#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) -# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ - must be defined." -#endif - -/* -** Define the required Windows SDK version constants if they are not -** already available. -*/ -#ifndef NTDDI_WIN8 -# define NTDDI_WIN8 0x06020000 -#endif - -#ifndef NTDDI_WINBLUE -# define NTDDI_WINBLUE 0x06030000 -#endif - -#ifndef NTDDI_WINTHRESHOLD -# define NTDDI_WINTHRESHOLD 0x06040000 -#endif - -/* -** Check to see if the GetVersionEx[AW] functions are deprecated on the -** target system. GetVersionEx was first deprecated in Win8.1. -*/ -#ifndef SQLITE_WIN32_GETVERSIONEX -# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE -# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ -# else -# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ -# endif -#endif - -/* -** Check to see if the CreateFileMappingA function is supported on the -** target system. It is unavailable when using "mincore.lib" on Win10. -** When compiling for Windows 10, always assume "mincore.lib" is in use. -*/ -#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA -# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD -# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 -# else -# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 -# endif -#endif - -/* -** This constant should already be defined (in the "WinDef.h" SDK file). -*/ -#ifndef MAX_PATH -# define MAX_PATH (260) -#endif - -/* -** Maximum pathname length (in chars) for Win32. This should normally be -** MAX_PATH. -*/ -#ifndef SQLITE_WIN32_MAX_PATH_CHARS -# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) -#endif - -/* -** This constant should already be defined (in the "WinNT.h" SDK file). -*/ -#ifndef UNICODE_STRING_MAX_CHARS -# define UNICODE_STRING_MAX_CHARS (32767) -#endif - -/* -** Maximum pathname length (in chars) for WinNT. This should normally be -** UNICODE_STRING_MAX_CHARS. -*/ -#ifndef SQLITE_WINNT_MAX_PATH_CHARS -# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) -#endif - -/* -** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in -** characters, so we allocate 4 bytes per character assuming worst-case of -** 4-bytes-per-character for UTF8. -*/ -#ifndef SQLITE_WIN32_MAX_PATH_BYTES -# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) -#endif - -/* -** Maximum pathname length (in bytes) for WinNT. This should normally be -** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR). -*/ -#ifndef SQLITE_WINNT_MAX_PATH_BYTES -# define SQLITE_WINNT_MAX_PATH_BYTES \ - (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) -#endif - -/* -** Maximum error message length (in chars) for WinRT. -*/ -#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS -# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) -#endif - -/* -** Returns non-zero if the character should be treated as a directory -** separator. -*/ -#ifndef winIsDirSep -# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) -#endif - -/* -** This macro is used when a local variable is set to a value that is -** [sometimes] not used by the code (e.g. via conditional compilation). -*/ -#ifndef UNUSED_VARIABLE_VALUE -# define UNUSED_VARIABLE_VALUE(x) (void)(x) -#endif - -/* -** Returns the character that should be used as the directory separator. -*/ -#ifndef winGetDirSep -# define winGetDirSep() '\\' -#endif - -/* -** Do we need to manually define the Win32 file mapping APIs for use with WAL -** mode or memory mapped files (e.g. these APIs are available in the Windows -** CE SDK; however, they are not present in the header file)? -*/ -#if SQLITE_WIN32_FILEMAPPING_API && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) -/* -** Two of the file mapping APIs are different under WinRT. Figure out which -** set we need. -*/ -#if SQLITE_OS_WINRT -WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ - LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); - -WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T); -#else -#if defined(SQLITE_WIN32_HAS_ANSI) -WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ - DWORD, DWORD, DWORD, LPCSTR); -#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ - -#if defined(SQLITE_WIN32_HAS_WIDE) -WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ - DWORD, DWORD, DWORD, LPCWSTR); -#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ - -WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); -#endif /* SQLITE_OS_WINRT */ - -/* -** These file mapping APIs are common to both Win32 and WinRT. -*/ - -WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); -WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); -#endif /* SQLITE_WIN32_FILEMAPPING_API */ - -/* -** Some Microsoft compilers lack this definition. -*/ -#ifndef INVALID_FILE_ATTRIBUTES -# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -#endif - -#ifndef FILE_FLAG_MASK -# define FILE_FLAG_MASK (0xFF3C0000) -#endif - -#ifndef FILE_ATTRIBUTE_MASK -# define FILE_ATTRIBUTE_MASK (0x0003FFF7) -#endif - -#ifndef SQLITE_OMIT_WAL -/* Forward references to structures used for WAL */ -typedef struct winShm winShm; /* A connection to shared-memory */ -typedef struct winShmNode winShmNode; /* A region of shared-memory */ -#endif - -/* -** WinCE lacks native support for file locking so we have to fake it -** with some code of our own. -*/ -#if SQLITE_OS_WINCE -typedef struct winceLock { - int nReaders; /* Number of reader locks obtained */ - BOOL bPending; /* Indicates a pending lock has been obtained */ - BOOL bReserved; /* Indicates a reserved lock has been obtained */ - BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ -} winceLock; -#endif - -/* -** The winFile structure is a subclass of sqlite3_file* specific to the win32 -** portability layer. -*/ -typedef struct winFile winFile; -struct winFile { - const sqlite3_io_methods *pMethod; /*** Must be first ***/ - sqlite3_vfs *pVfs; /* The VFS used to open this file */ - HANDLE h; /* Handle for accessing the file */ - u8 locktype; /* Type of lock currently held on this file */ - short sharedLockByte; /* Randomly chosen byte used as a shared lock */ - u8 ctrlFlags; /* Flags. See WINFILE_* below */ - DWORD lastErrno; /* The Windows errno from the last I/O error */ -#ifndef SQLITE_OMIT_WAL - winShm *pShm; /* Instance of shared memory on this file */ -#endif - const char *zPath; /* Full pathname of this file */ - int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ -#if SQLITE_OS_WINCE - LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ - HANDLE hMutex; /* Mutex used to control access to shared lock */ - HANDLE hShared; /* Shared memory segment used for locking */ - winceLock local; /* Locks obtained by this instance of winFile */ - winceLock *shared; /* Global shared lock memory for the file */ -#endif -#if SQLITE_MAX_MMAP_SIZE>0 - int nFetchOut; /* Number of outstanding xFetch references */ - HANDLE hMap; /* Handle for accessing memory mapping */ - void *pMapRegion; /* Area memory mapped */ - sqlite3_int64 mmapSize; /* Usable size of mapped region */ - sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */ - sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ -#endif -}; - -/* -** The winVfsAppData structure is used for the pAppData member for all of the -** Win32 VFS variants. -*/ -typedef struct winVfsAppData winVfsAppData; -struct winVfsAppData { - const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ - void *pAppData; /* The extra pAppData, if any. */ - BOOL bNoLock; /* Non-zero if locking is disabled. */ -}; - -/* -** Allowed values for winFile.ctrlFlags -*/ -#define WINFILE_RDONLY 0x02 /* Connection is read only */ -#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ - -/* - * The size of the buffer used by sqlite3_win32_write_debug(). - */ -#ifndef SQLITE_WIN32_DBG_BUF_SIZE -# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) -#endif - -/* - * The value used with sqlite3_win32_set_directory() to specify that - * the data directory should be changed. - */ -#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE -# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1) -#endif - -/* - * The value used with sqlite3_win32_set_directory() to specify that - * the temporary directory should be changed. - */ -#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE -# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2) -#endif - -/* - * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the - * various Win32 API heap functions instead of our own. - */ -#ifdef SQLITE_WIN32_MALLOC - -/* - * If this is non-zero, an isolated heap will be created by the native Win32 - * allocator subsystem; otherwise, the default process heap will be used. This - * setting has no effect when compiling for WinRT. By default, this is enabled - * and an isolated heap will be created to store all allocated data. - * - ****************************************************************************** - * WARNING: It is important to note that when this setting is non-zero and the - * winMemShutdown function is called (e.g. by the sqlite3_shutdown - * function), all data that was allocated using the isolated heap will - * be freed immediately and any attempt to access any of that freed - * data will almost certainly result in an immediate access violation. - ****************************************************************************** - */ -#ifndef SQLITE_WIN32_HEAP_CREATE -# define SQLITE_WIN32_HEAP_CREATE (TRUE) -#endif - -/* - * This is cache size used in the calculation of the initial size of the - * Win32-specific heap. It cannot be negative. - */ -#ifndef SQLITE_WIN32_CACHE_SIZE -# if SQLITE_DEFAULT_CACHE_SIZE>=0 -# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) -# else -# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) -# endif -#endif - -/* - * The initial size of the Win32-specific heap. This value may be zero. - */ -#ifndef SQLITE_WIN32_HEAP_INIT_SIZE -# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ - (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) -#endif - -/* - * The maximum size of the Win32-specific heap. This value may be zero. - */ -#ifndef SQLITE_WIN32_HEAP_MAX_SIZE -# define SQLITE_WIN32_HEAP_MAX_SIZE (0) -#endif - -/* - * The extra flags to use in calls to the Win32 heap APIs. This value may be - * zero for the default behavior. - */ -#ifndef SQLITE_WIN32_HEAP_FLAGS -# define SQLITE_WIN32_HEAP_FLAGS (0) -#endif - - -/* -** The winMemData structure stores information required by the Win32-specific -** sqlite3_mem_methods implementation. -*/ -typedef struct winMemData winMemData; -struct winMemData { -#ifndef NDEBUG - u32 magic1; /* Magic number to detect structure corruption. */ -#endif - HANDLE hHeap; /* The handle to our heap. */ - BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ -#ifndef NDEBUG - u32 magic2; /* Magic number to detect structure corruption. */ -#endif -}; - -#ifndef NDEBUG -#define WINMEM_MAGIC1 0x42b2830b -#define WINMEM_MAGIC2 0xbd4d7cf4 -#endif - -static struct winMemData win_mem_data = { -#ifndef NDEBUG - WINMEM_MAGIC1, -#endif - NULL, FALSE -#ifndef NDEBUG - ,WINMEM_MAGIC2 -#endif -}; - -#ifndef NDEBUG -#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 ) -#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 ) -#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2(); -#else -#define winMemAssertMagic() -#endif - -#define winMemGetDataPtr() &win_mem_data -#define winMemGetHeap() win_mem_data.hHeap -#define winMemGetOwned() win_mem_data.bOwned - -static void *winMemMalloc(int nBytes); -static void winMemFree(void *pPrior); -static void *winMemRealloc(void *pPrior, int nBytes); -static int winMemSize(void *p); -static int winMemRoundup(int n); -static int winMemInit(void *pAppData); -static void winMemShutdown(void *pAppData); - -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); -#endif /* SQLITE_WIN32_MALLOC */ - -/* -** The following variable is (normally) set once and never changes -** thereafter. It records whether the operating system is Win9x -** or WinNT. -** -** 0: Operating system unknown. -** 1: Operating system is Win9x. -** 2: Operating system is WinNT. -** -** In order to facilitate testing on a WinNT system, the test fixture -** can manually set this value to 1 to emulate Win98 behavior. -*/ -#ifdef SQLITE_TEST -SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; -#else -static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; -#endif - -#ifndef SYSCALL -# define SYSCALL sqlite3_syscall_ptr -#endif - -/* -** This function is not available on Windows CE or WinRT. - */ - -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT -# define osAreFileApisANSI() 1 -#endif - -/* -** Many system calls are accessed through pointer-to-functions so that -** they may be overridden at runtime to facilitate fault injection during -** testing and sandboxing. The following array holds the names and pointers -** to all overrideable system calls. -*/ -static struct win_syscall { - const char *zName; /* Name of the system call */ - sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ - sqlite3_syscall_ptr pDefault; /* Default value */ -} aSyscall[] = { -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, -#else - { "AreFileApisANSI", (SYSCALL)0, 0 }, -#endif - -#ifndef osAreFileApisANSI -#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) -#endif - -#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) - { "CharLowerW", (SYSCALL)CharLowerW, 0 }, -#else - { "CharLowerW", (SYSCALL)0, 0 }, -#endif - -#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) - -#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) - { "CharUpperW", (SYSCALL)CharUpperW, 0 }, -#else - { "CharUpperW", (SYSCALL)0, 0 }, -#endif - -#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) - - { "CloseHandle", (SYSCALL)CloseHandle, 0 }, - -#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "CreateFileA", (SYSCALL)CreateFileA, 0 }, -#else - { "CreateFileA", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ - LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "CreateFileW", (SYSCALL)CreateFileW, 0 }, -#else - { "CreateFileW", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ - LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ - SQLITE_WIN32_CREATEFILEMAPPINGA - { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, -#else - { "CreateFileMappingA", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ - DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) - -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) - { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, -#else - { "CreateFileMappingW", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ - DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, -#else - { "CreateMutexW", (SYSCALL)0, 0 }, -#endif - -#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ - LPCWSTR))aSyscall[8].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, -#else - { "DeleteFileA", (SYSCALL)0, 0 }, -#endif - -#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) - { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, -#else - { "DeleteFileW", (SYSCALL)0, 0 }, -#endif - -#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) - -#if SQLITE_OS_WINCE - { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, -#else - { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, -#endif - -#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ - LPFILETIME))aSyscall[11].pCurrent) - -#if SQLITE_OS_WINCE - { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, -#else - { "FileTimeToSystemTime", (SYSCALL)0, 0 }, -#endif - -#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ - LPSYSTEMTIME))aSyscall[12].pCurrent) - - { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, - -#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, -#else - { "FormatMessageA", (SYSCALL)0, 0 }, -#endif - -#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ - DWORD,va_list*))aSyscall[14].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) - { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, -#else - { "FormatMessageW", (SYSCALL)0, 0 }, -#endif - -#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ - DWORD,va_list*))aSyscall[15].pCurrent) - -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, -#else - { "FreeLibrary", (SYSCALL)0, 0 }, -#endif - -#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) - - { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, - -#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) - -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) - { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, -#else - { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, -#endif - -#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[18].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, -#else - { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, -#endif - -#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[19].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, -#else - { "GetFileAttributesA", (SYSCALL)0, 0 }, -#endif - -#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, -#else - { "GetFileAttributesW", (SYSCALL)0, 0 }, -#endif - -#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) - { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, -#else - { "GetFileAttributesExW", (SYSCALL)0, 0 }, -#endif - -#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ - LPVOID))aSyscall[22].pCurrent) - -#if !SQLITE_OS_WINRT - { "GetFileSize", (SYSCALL)GetFileSize, 0 }, -#else - { "GetFileSize", (SYSCALL)0, 0 }, -#endif - -#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) - -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) - { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, -#else - { "GetFullPathNameA", (SYSCALL)0, 0 }, -#endif - -#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ - LPSTR*))aSyscall[24].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, -#else - { "GetFullPathNameW", (SYSCALL)0, 0 }, -#endif - -#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ - LPWSTR*))aSyscall[25].pCurrent) - - { "GetLastError", (SYSCALL)GetLastError, 0 }, - -#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) - -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) -#if SQLITE_OS_WINCE - /* The GetProcAddressA() routine is only available on Windows CE. */ - { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, -#else - /* All other Windows platforms expect GetProcAddress() to take - ** an ANSI string regardless of the _UNICODE setting */ - { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, -#endif -#else - { "GetProcAddressA", (SYSCALL)0, 0 }, -#endif - -#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ - LPCSTR))aSyscall[27].pCurrent) - -#if !SQLITE_OS_WINRT - { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, -#else - { "GetSystemInfo", (SYSCALL)0, 0 }, -#endif - -#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) - - { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, - -#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) - -#if !SQLITE_OS_WINCE - { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, -#else - { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, -#endif - -#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ - LPFILETIME))aSyscall[30].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, -#else - { "GetTempPathA", (SYSCALL)0, 0 }, -#endif - -#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, -#else - { "GetTempPathW", (SYSCALL)0, 0 }, -#endif - -#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) - -#if !SQLITE_OS_WINRT - { "GetTickCount", (SYSCALL)GetTickCount, 0 }, -#else - { "GetTickCount", (SYSCALL)0, 0 }, -#endif - -#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX - { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, -#else - { "GetVersionExA", (SYSCALL)0, 0 }, -#endif - -#define osGetVersionExA ((BOOL(WINAPI*)( \ - LPOSVERSIONINFOA))aSyscall[34].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - SQLITE_WIN32_GETVERSIONEX - { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, -#else - { "GetVersionExW", (SYSCALL)0, 0 }, -#endif - -#define osGetVersionExW ((BOOL(WINAPI*)( \ - LPOSVERSIONINFOW))aSyscall[35].pCurrent) - - { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, - -#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ - SIZE_T))aSyscall[36].pCurrent) - -#if !SQLITE_OS_WINRT - { "HeapCreate", (SYSCALL)HeapCreate, 0 }, -#else - { "HeapCreate", (SYSCALL)0, 0 }, -#endif - -#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ - SIZE_T))aSyscall[37].pCurrent) - -#if !SQLITE_OS_WINRT - { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, -#else - { "HeapDestroy", (SYSCALL)0, 0 }, -#endif - -#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) - - { "HeapFree", (SYSCALL)HeapFree, 0 }, - -#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) - - { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, - -#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ - SIZE_T))aSyscall[40].pCurrent) - - { "HeapSize", (SYSCALL)HeapSize, 0 }, - -#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[41].pCurrent) - -#if !SQLITE_OS_WINRT - { "HeapValidate", (SYSCALL)HeapValidate, 0 }, -#else - { "HeapValidate", (SYSCALL)0, 0 }, -#endif - -#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[42].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "HeapCompact", (SYSCALL)HeapCompact, 0 }, -#else - { "HeapCompact", (SYSCALL)0, 0 }, -#endif - -#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, -#else - { "LoadLibraryA", (SYSCALL)0, 0 }, -#endif - -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, -#else - { "LoadLibraryW", (SYSCALL)0, 0 }, -#endif - -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent) - -#if !SQLITE_OS_WINRT - { "LocalFree", (SYSCALL)LocalFree, 0 }, -#else - { "LocalFree", (SYSCALL)0, 0 }, -#endif - -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "LockFile", (SYSCALL)LockFile, 0 }, -#else - { "LockFile", (SYSCALL)0, 0 }, -#endif - -#ifndef osLockFile -#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[47].pCurrent) -#endif - -#if !SQLITE_OS_WINCE - { "LockFileEx", (SYSCALL)LockFileEx, 0 }, -#else - { "LockFileEx", (SYSCALL)0, 0 }, -#endif - -#ifndef osLockFileEx -#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[48].pCurrent) -#endif - -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) - { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, -#else - { "MapViewOfFile", (SYSCALL)0, 0 }, -#endif - -#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - SIZE_T))aSyscall[49].pCurrent) - - { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, - -#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ - int))aSyscall[50].pCurrent) - - { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, - -#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ - LARGE_INTEGER*))aSyscall[51].pCurrent) - - { "ReadFile", (SYSCALL)ReadFile, 0 }, - -#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[52].pCurrent) - - { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, - -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent) - -#if !SQLITE_OS_WINRT - { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, -#else - { "SetFilePointer", (SYSCALL)0, 0 }, -#endif - -#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ - DWORD))aSyscall[54].pCurrent) - -#if !SQLITE_OS_WINRT - { "Sleep", (SYSCALL)Sleep, 0 }, -#else - { "Sleep", (SYSCALL)0, 0 }, -#endif - -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) - - { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, - -#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ - LPFILETIME))aSyscall[56].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "UnlockFile", (SYSCALL)UnlockFile, 0 }, -#else - { "UnlockFile", (SYSCALL)0, 0 }, -#endif - -#ifndef osUnlockFile -#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[57].pCurrent) -#endif - -#if !SQLITE_OS_WINCE - { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, -#else - { "UnlockFileEx", (SYSCALL)0, 0 }, -#endif - -#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[58].pCurrent) - -#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, -#else - { "UnmapViewOfFile", (SYSCALL)0, 0 }, -#endif - -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) - - { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, - -#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ - LPCSTR,LPBOOL))aSyscall[60].pCurrent) - - { "WriteFile", (SYSCALL)WriteFile, 0 }, - -#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[61].pCurrent) - -#if SQLITE_OS_WINRT - { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, -#else - { "CreateEventExW", (SYSCALL)0, 0 }, -#endif - -#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ - DWORD,DWORD))aSyscall[62].pCurrent) - -#if !SQLITE_OS_WINRT - { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, -#else - { "WaitForSingleObject", (SYSCALL)0, 0 }, -#endif - -#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ - DWORD))aSyscall[63].pCurrent) - -#if !SQLITE_OS_WINCE - { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, -#else - { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, -#endif - -#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ - BOOL))aSyscall[64].pCurrent) - -#if SQLITE_OS_WINRT - { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, -#else - { "SetFilePointerEx", (SYSCALL)0, 0 }, -#endif - -#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ - PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) - -#if SQLITE_OS_WINRT - { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, -#else - { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, -#endif - -#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ - FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) - -#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, -#else - { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, -#endif - -#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ - SIZE_T))aSyscall[67].pCurrent) - -#if SQLITE_OS_WINRT - { "CreateFile2", (SYSCALL)CreateFile2, 0 }, -#else - { "CreateFile2", (SYSCALL)0, 0 }, -#endif - -#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ - LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent) - -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, -#else - { "LoadPackagedLibrary", (SYSCALL)0, 0 }, -#endif - -#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ - DWORD))aSyscall[69].pCurrent) - -#if SQLITE_OS_WINRT - { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, -#else - { "GetTickCount64", (SYSCALL)0, 0 }, -#endif - -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent) - -#if SQLITE_OS_WINRT - { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, -#else - { "GetNativeSystemInfo", (SYSCALL)0, 0 }, -#endif - -#define osGetNativeSystemInfo ((VOID(WINAPI*)( \ - LPSYSTEM_INFO))aSyscall[71].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, -#else - { "OutputDebugStringA", (SYSCALL)0, 0 }, -#endif - -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) - { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, -#else - { "OutputDebugStringW", (SYSCALL)0, 0 }, -#endif - -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) - - { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, - -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent) - -#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, -#else - { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ - LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) - -/* -** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" -** is really just a macro that uses a compiler intrinsic (e.g. x64). -** So do not try to make this is into a redefinable interface. -*/ -#if defined(InterlockedCompareExchange) - { "InterlockedCompareExchange", (SYSCALL)0, 0 }, - -#define osInterlockedCompareExchange InterlockedCompareExchange -#else - { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, - -#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ - SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) -#endif /* defined(InterlockedCompareExchange) */ - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID - { "UuidCreate", (SYSCALL)UuidCreate, 0 }, -#else - { "UuidCreate", (SYSCALL)0, 0 }, -#endif - -#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID - { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, -#else - { "UuidCreateSequential", (SYSCALL)0, 0 }, -#endif - -#define osUuidCreateSequential \ - ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) - -#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 - { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, -#else - { "FlushViewOfFile", (SYSCALL)0, 0 }, -#endif - -#define osFlushViewOfFile \ - ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) - -}; /* End of the overrideable system calls */ - -/* -** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "win32" VFSes. Return SQLITE_OK opon successfully updating the -** system call pointer, or SQLITE_NOTFOUND if there is no configurable -** system call named zName. -*/ -static int winSetSystemCall( - sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ - const char *zName, /* Name of system call to override */ - sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ -){ - unsigned int i; - int rc = SQLITE_NOTFOUND; - - UNUSED_PARAMETER(pNotUsed); - if( zName==0 ){ - /* If no zName is given, restore all system calls to their default - ** settings and return NULL - */ - rc = SQLITE_OK; - for(i=0; i0 ){ - memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); - memcpy(zDbgBuf, zBuf, nMin); - osOutputDebugStringA(zDbgBuf); - }else{ - osOutputDebugStringA(zBuf); - } -#elif defined(SQLITE_WIN32_HAS_WIDE) - memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); - if ( osMultiByteToWideChar( - osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, - nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ - return; - } - osOutputDebugStringW((LPCWSTR)zDbgBuf); -#else - if( nMin>0 ){ - memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); - memcpy(zDbgBuf, zBuf, nMin); - fprintf(stderr, "%s", zDbgBuf); - }else{ - fprintf(stderr, "%s", zBuf); - } -#endif -} - -/* -** The following routine suspends the current thread for at least ms -** milliseconds. This is equivalent to the Win32 Sleep() interface. -*/ -#if SQLITE_OS_WINRT -static HANDLE sleepObj = NULL; -#endif - -SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ -#if SQLITE_OS_WINRT - if ( sleepObj==NULL ){ - sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, - SYNCHRONIZE); - } - assert( sleepObj!=NULL ); - osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); -#else - osSleep(milliseconds); -#endif -} - -#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ - SQLITE_THREADSAFE>0 -SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ - DWORD rc; - while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, - TRUE))==WAIT_IO_COMPLETION ){} - return rc; -} -#endif - -/* -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, -** or WinCE. Return false (zero) for Win95, Win98, or WinME. -** -** Here is an interesting observation: Win95, Win98, and WinME lack -** the LockFileEx() API. But we can still statically link against that -** API as long as we don't call it when running Win95/98/ME. A call to -** this routine is used to determine if the host is Win95/98/ME or -** WinNT/2K/XP so that we will know whether or not we can safely call -** the LockFileEx() API. -*/ - -#if !SQLITE_WIN32_GETVERSIONEX -# define osIsNT() (1) -#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) -# define osIsNT() (1) -#elif !defined(SQLITE_WIN32_HAS_WIDE) -# define osIsNT() (0) -#else -# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) -#endif - -/* -** This function determines if the machine is running a version of Windows -** based on the NT kernel. -*/ -SQLITE_API int sqlite3_win32_is_nt(void){ -#if SQLITE_OS_WINRT - /* - ** NOTE: The WinRT sub-platform is always assumed to be based on the NT - ** kernel. - */ - return 1; -#elif SQLITE_WIN32_GETVERSIONEX - if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ -#if defined(SQLITE_WIN32_HAS_ANSI) - OSVERSIONINFOA sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - osGetVersionExA(&sInfo); - osInterlockedCompareExchange(&sqlite3_os_type, - (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); -#elif defined(SQLITE_WIN32_HAS_WIDE) - OSVERSIONINFOW sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - osGetVersionExW(&sInfo); - osInterlockedCompareExchange(&sqlite3_os_type, - (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); -#endif - } - return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; -#elif SQLITE_TEST - return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; -#else - /* - ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are - ** deprecated are always assumed to be based on the NT kernel. - */ - return 1; -#endif -} - -#ifdef SQLITE_WIN32_MALLOC -/* -** Allocate nBytes of memory. -*/ -static void *winMemMalloc(int nBytes){ - HANDLE hHeap; - void *p; - - winMemAssertMagic(); - hHeap = winMemGetHeap(); - assert( hHeap!=0 ); - assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); -#endif - assert( nBytes>=0 ); - p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); - if( !p ){ - sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", - nBytes, osGetLastError(), (void*)hHeap); - } - return p; -} - -/* -** Free memory. -*/ -static void winMemFree(void *pPrior){ - HANDLE hHeap; - - winMemAssertMagic(); - hHeap = winMemGetHeap(); - assert( hHeap!=0 ); - assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); -#endif - if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ - if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ - sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", - pPrior, osGetLastError(), (void*)hHeap); - } -} - -/* -** Change the size of an existing memory allocation -*/ -static void *winMemRealloc(void *pPrior, int nBytes){ - HANDLE hHeap; - void *p; - - winMemAssertMagic(); - hHeap = winMemGetHeap(); - assert( hHeap!=0 ); - assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); -#endif - assert( nBytes>=0 ); - if( !pPrior ){ - p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); - }else{ - p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); - } - if( !p ){ - sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", - pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), - (void*)hHeap); - } - return p; -} - -/* -** Return the size of an outstanding allocation, in bytes. -*/ -static int winMemSize(void *p){ - HANDLE hHeap; - SIZE_T n; - - winMemAssertMagic(); - hHeap = winMemGetHeap(); - assert( hHeap!=0 ); - assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); -#endif - if( !p ) return 0; - n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); - if( n==(SIZE_T)-1 ){ - sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", - p, osGetLastError(), (void*)hHeap); - return 0; - } - return (int)n; -} - -/* -** Round up a request size to the next valid allocation size. -*/ -static int winMemRoundup(int n){ - return n; -} - -/* -** Initialize this module. -*/ -static int winMemInit(void *pAppData){ - winMemData *pWinMemData = (winMemData *)pAppData; - - if( !pWinMemData ) return SQLITE_ERROR; - assert( pWinMemData->magic1==WINMEM_MAGIC1 ); - assert( pWinMemData->magic2==WINMEM_MAGIC2 ); - -#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE - if( !pWinMemData->hHeap ){ - DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; - DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; - if( dwMaximumSize==0 ){ - dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; - }else if( dwInitialSize>dwMaximumSize ){ - dwInitialSize = dwMaximumSize; - } - pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, - dwInitialSize, dwMaximumSize); - if( !pWinMemData->hHeap ){ - sqlite3_log(SQLITE_NOMEM, - "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", - osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, - dwMaximumSize); - return SQLITE_NOMEM_BKPT; - } - pWinMemData->bOwned = TRUE; - assert( pWinMemData->bOwned ); - } -#else - pWinMemData->hHeap = osGetProcessHeap(); - if( !pWinMemData->hHeap ){ - sqlite3_log(SQLITE_NOMEM, - "failed to GetProcessHeap (%lu)", osGetLastError()); - return SQLITE_NOMEM_BKPT; - } - pWinMemData->bOwned = FALSE; - assert( !pWinMemData->bOwned ); -#endif - assert( pWinMemData->hHeap!=0 ); - assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); -#endif - return SQLITE_OK; -} - -/* -** Deinitialize this module. -*/ -static void winMemShutdown(void *pAppData){ - winMemData *pWinMemData = (winMemData *)pAppData; - - if( !pWinMemData ) return; - assert( pWinMemData->magic1==WINMEM_MAGIC1 ); - assert( pWinMemData->magic2==WINMEM_MAGIC2 ); - - if( pWinMemData->hHeap ){ - assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) - assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); -#endif - if( pWinMemData->bOwned ){ - if( !osHeapDestroy(pWinMemData->hHeap) ){ - sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", - osGetLastError(), (void*)pWinMemData->hHeap); - } - pWinMemData->bOwned = FALSE; - } - pWinMemData->hHeap = NULL; - } -} - -/* -** Populate the low-level memory allocation function pointers in -** sqlite3GlobalConfig.m with pointers to the routines in this file. The -** arguments specify the block of memory to manage. -** -** This routine is only called by sqlite3_config(), and therefore -** is not required to be threadsafe (it is not). -*/ -SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ - static const sqlite3_mem_methods winMemMethods = { - winMemMalloc, - winMemFree, - winMemRealloc, - winMemSize, - winMemRoundup, - winMemInit, - winMemShutdown, - &win_mem_data - }; - return &winMemMethods; -} - -SQLITE_PRIVATE void sqlite3MemSetDefault(void){ - sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); -} -#endif /* SQLITE_WIN32_MALLOC */ - -/* -** Convert a UTF-8 string to Microsoft Unicode. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static LPWSTR winUtf8ToUnicode(const char *zText){ - int nChar; - LPWSTR zWideText; - - nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); - if( nChar==0 ){ - return 0; - } - zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); - if( zWideText==0 ){ - return 0; - } - nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, - nChar); - if( nChar==0 ){ - sqlite3_free(zWideText); - zWideText = 0; - } - return zWideText; -} - -/* -** Convert a Microsoft Unicode string to UTF-8. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static char *winUnicodeToUtf8(LPCWSTR zWideText){ - int nByte; - char *zText; - - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); - if( nByte == 0 ){ - return 0; - } - zText = sqlite3MallocZero( nByte ); - if( zText==0 ){ - return 0; - } - nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, - 0, 0); - if( nByte == 0 ){ - sqlite3_free(zText); - zText = 0; - } - return zText; -} - -/* -** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM -** code page. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ - int nByte; - LPWSTR zMbcsText; - int codepage = useAnsi ? CP_ACP : CP_OEMCP; - - nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, - 0)*sizeof(WCHAR); - if( nByte==0 ){ - return 0; - } - zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); - if( zMbcsText==0 ){ - return 0; - } - nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, - nByte); - if( nByte==0 ){ - sqlite3_free(zMbcsText); - zMbcsText = 0; - } - return zMbcsText; -} - -/* -** Convert a Microsoft Unicode string to a multi-byte character string, -** using the ANSI or OEM code page. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ - int nByte; - char *zText; - int codepage = useAnsi ? CP_ACP : CP_OEMCP; - - nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); - if( nByte == 0 ){ - return 0; - } - zText = sqlite3MallocZero( nByte ); - if( zText==0 ){ - return 0; - } - nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, - nByte, 0, 0); - if( nByte == 0 ){ - sqlite3_free(zText); - zText = 0; - } - return zText; -} - -/* -** Convert a multi-byte character string to UTF-8. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static char *winMbcsToUtf8(const char *zText, int useAnsi){ - char *zTextUtf8; - LPWSTR zTmpWide; - - zTmpWide = winMbcsToUnicode(zText, useAnsi); - if( zTmpWide==0 ){ - return 0; - } - zTextUtf8 = winUnicodeToUtf8(zTmpWide); - sqlite3_free(zTmpWide); - return zTextUtf8; -} - -/* -** Convert a UTF-8 string to a multi-byte character string. -** -** Space to hold the returned string is obtained from sqlite3_malloc(). -*/ -static char *winUtf8ToMbcs(const char *zText, int useAnsi){ - char *zTextMbcs; - LPWSTR zTmpWide; - - zTmpWide = winUtf8ToUnicode(zText); - if( zTmpWide==0 ){ - return 0; - } - zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); - sqlite3_free(zTmpWide); - return zTextMbcs; -} - -/* -** This is a public wrapper for the winUtf8ToUnicode() function. -*/ -SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winUtf8ToUnicode(zText); -} - -/* -** This is a public wrapper for the winUnicodeToUtf8() function. -*/ -SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zWideText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winUnicodeToUtf8(zWideText); -} - -/* -** This is a public wrapper for the winMbcsToUtf8() function. -*/ -SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winMbcsToUtf8(zText, osAreFileApisANSI()); -} - -/* -** This is a public wrapper for the winMbcsToUtf8() function. -*/ -SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winMbcsToUtf8(zText, useAnsi); -} - -/* -** This is a public wrapper for the winUtf8ToMbcs() function. -*/ -SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winUtf8ToMbcs(zText, osAreFileApisANSI()); -} - -/* -** This is a public wrapper for the winUtf8ToMbcs() function. -*/ -SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !zText ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize() ) return 0; -#endif - return winUtf8ToMbcs(zText, useAnsi); -} - -/* -** This function sets the data directory or the temporary directory based on -** the provided arguments. The type argument must be 1 in order to set the -** data directory or 2 in order to set the temporary directory. The zValue -** argument is the name of the directory to use. The return value will be -** SQLITE_OK if successful. -*/ -SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){ - char **ppDirectory = 0; -#ifndef SQLITE_OMIT_AUTOINIT - int rc = sqlite3_initialize(); - if( rc ) return rc; -#endif - if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ - ppDirectory = &sqlite3_data_directory; - }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ - ppDirectory = &sqlite3_temp_directory; - } - assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE - || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE - ); - assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); - if( ppDirectory ){ - char *zValueUtf8 = 0; - if( zValue && zValue[0] ){ - zValueUtf8 = winUnicodeToUtf8(zValue); - if ( zValueUtf8==0 ){ - return SQLITE_NOMEM_BKPT; - } - } - sqlite3_free(*ppDirectory); - *ppDirectory = zValueUtf8; - return SQLITE_OK; - } - return SQLITE_ERROR; -} - -/* -** The return value of winGetLastErrorMsg -** is zero if the error message fits in the buffer, or non-zero -** otherwise (if the message was truncated). -*/ -static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ - /* FormatMessage returns 0 on failure. Otherwise it - ** returns the number of TCHARs written to the output - ** buffer, excluding the terminating null char. - */ - DWORD dwLen = 0; - char *zOut = 0; - - if( osIsNT() ){ -#if SQLITE_OS_WINRT - WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; - dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - zTempWide, - SQLITE_WIN32_MAX_ERRMSG_CHARS, - 0); -#else - LPWSTR zTempWide = NULL; - dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPWSTR) &zTempWide, - 0, - 0); -#endif - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - sqlite3BeginBenignMalloc(); - zOut = winUnicodeToUtf8(zTempWide); - sqlite3EndBenignMalloc(); -#if !SQLITE_OS_WINRT - /* free the system buffer allocated by FormatMessage */ - osLocalFree(zTempWide); -#endif - } - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - char *zTemp = NULL; - dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPSTR) &zTemp, - 0, - 0); - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - sqlite3BeginBenignMalloc(); - zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - sqlite3EndBenignMalloc(); - /* free the system buffer allocated by FormatMessage */ - osLocalFree(zTemp); - } - } -#endif - if( 0 == dwLen ){ - sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); - }else{ - /* copy a maximum of nBuf chars to output buffer */ - sqlite3_snprintf(nBuf, zBuf, "%s", zOut); - /* free the UTF8 buffer */ - sqlite3_free(zOut); - } - return 0; -} - -/* -** -** This function - winLogErrorAtLine() - is only ever called via the macro -** winLogError(). -** -** This routine is invoked after an error occurs in an OS function. -** It logs a message using sqlite3_log() containing the current value of -** error code and, if possible, the human-readable equivalent from -** FormatMessage. -** -** The first argument passed to the macro should be the error code that -** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). -** The two subsequent arguments should be the name of the OS function that -** failed and the associated file-system path, if any. -*/ -#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) -static int winLogErrorAtLine( - int errcode, /* SQLite error code */ - DWORD lastErrno, /* Win32 last error */ - const char *zFunc, /* Name of OS function that failed */ - const char *zPath, /* File path associated with error */ - int iLine /* Source line number where error occurred */ -){ - char zMsg[500]; /* Human readable error text */ - int i; /* Loop counter */ - - zMsg[0] = 0; - winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); - assert( errcode!=SQLITE_OK ); - if( zPath==0 ) zPath = ""; - for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} - zMsg[i] = 0; - sqlite3_log(errcode, - "os_win.c:%d: (%lu) %s(%s) - %s", - iLine, lastErrno, zFunc, zPath, zMsg - ); - - return errcode; -} - -/* -** The number of times that a ReadFile(), WriteFile(), and DeleteFile() -** will be retried following a locking error - probably caused by -** antivirus software. Also the initial delay before the first retry. -** The delay increases linearly with each retry. -*/ -#ifndef SQLITE_WIN32_IOERR_RETRY -# define SQLITE_WIN32_IOERR_RETRY 10 -#endif -#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY -# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 -#endif -static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; -static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; - -/* -** The "winIoerrCanRetry1" macro is used to determine if a particular I/O -** error code obtained via GetLastError() is eligible to be retried. It -** must accept the error code DWORD as its only argument and should return -** non-zero if the error code is transient in nature and the operation -** responsible for generating the original error might succeed upon being -** retried. The argument to this macro should be a variable. -** -** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it -** is defined, it will be consulted only when the macro "winIoerrCanRetry1" -** returns zero. The "winIoerrCanRetry2" macro is completely optional and -** may be used to include additional error codes in the set that should -** result in the failing I/O operation being retried by the caller. If -** defined, the "winIoerrCanRetry2" macro must exhibit external semantics -** identical to those of the "winIoerrCanRetry1" macro. -*/ -#if !defined(winIoerrCanRetry1) -#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ - ((a)==ERROR_SHARING_VIOLATION) || \ - ((a)==ERROR_LOCK_VIOLATION) || \ - ((a)==ERROR_DEV_NOT_EXIST) || \ - ((a)==ERROR_NETNAME_DELETED) || \ - ((a)==ERROR_SEM_TIMEOUT) || \ - ((a)==ERROR_NETWORK_UNREACHABLE)) -#endif - -/* -** If a ReadFile() or WriteFile() error occurs, invoke this routine -** to see if it should be retried. Return TRUE to retry. Return FALSE -** to give up with an error. -*/ -static int winRetryIoerr(int *pnRetry, DWORD *pError){ - DWORD e = osGetLastError(); - if( *pnRetry>=winIoerrRetry ){ - if( pError ){ - *pError = e; - } - return 0; - } - if( winIoerrCanRetry1(e) ){ - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); - ++*pnRetry; - return 1; - } -#if defined(winIoerrCanRetry2) - else if( winIoerrCanRetry2(e) ){ - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); - ++*pnRetry; - return 1; - } -#endif - if( pError ){ - *pError = e; - } - return 0; -} - -/* -** Log a I/O error retry episode. -*/ -static void winLogIoerr(int nRetry, int lineno){ - if( nRetry ){ - sqlite3_log(SQLITE_NOTICE, - "delayed %dms for lock/sharing conflict at line %d", - winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno - ); - } -} - -/* -** This #if does not rely on the SQLITE_OS_WINCE define because the -** corresponding section in "date.c" cannot use it. -*/ -#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) -/* -** The MSVC CRT on Windows CE may not have a localtime() function. -** So define a substitute. -*/ -/* # include */ -struct tm *__cdecl localtime(const time_t *t) -{ - static struct tm y; - FILETIME uTm, lTm; - SYSTEMTIME pTm; - sqlite3_int64 t64; - t64 = *t; - t64 = (t64 + 11644473600)*10000000; - uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); - uTm.dwHighDateTime= (DWORD)(t64 >> 32); - osFileTimeToLocalFileTime(&uTm,&lTm); - osFileTimeToSystemTime(&lTm,&pTm); - y.tm_year = pTm.wYear - 1900; - y.tm_mon = pTm.wMonth - 1; - y.tm_wday = pTm.wDayOfWeek; - y.tm_mday = pTm.wDay; - y.tm_hour = pTm.wHour; - y.tm_min = pTm.wMinute; - y.tm_sec = pTm.wSecond; - return &y; -} -#endif - -#if SQLITE_OS_WINCE -/************************************************************************* -** This section contains code for WinCE only. -*/ -#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] - -/* -** Acquire a lock on the handle h -*/ -static void winceMutexAcquire(HANDLE h){ - DWORD dwErr; - do { - dwErr = osWaitForSingleObject(h, INFINITE); - } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); -} -/* -** Release a lock acquired by winceMutexAcquire() -*/ -#define winceMutexRelease(h) ReleaseMutex(h) - -/* -** Create the mutex and shared memory used for locking in the file -** descriptor pFile -*/ -static int winceCreateLock(const char *zFilename, winFile *pFile){ - LPWSTR zTok; - LPWSTR zName; - DWORD lastErrno; - BOOL bLogged = FALSE; - BOOL bInit = TRUE; - - zName = winUtf8ToUnicode(zFilename); - if( zName==0 ){ - /* out of memory */ - return SQLITE_IOERR_NOMEM_BKPT; - } - - /* Initialize the local lockdata */ - memset(&pFile->local, 0, sizeof(pFile->local)); - - /* Replace the backslashes from the filename and lowercase it - ** to derive a mutex name. */ - zTok = osCharLowerW(zName); - for (;*zTok;zTok++){ - if (*zTok == '\\') *zTok = '_'; - } - - /* Create/open the named mutex */ - pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); - if (!pFile->hMutex){ - pFile->lastErrno = osGetLastError(); - sqlite3_free(zName); - return winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock1", zFilename); - } - - /* Acquire the mutex before continuing */ - winceMutexAcquire(pFile->hMutex); - - /* Since the names of named mutexes, semaphores, file mappings etc are - ** case-sensitive, take advantage of that by uppercasing the mutex name - ** and using that as the shared filemapping name. - */ - osCharUpperW(zName); - pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, sizeof(winceLock), - zName); - - /* Set a flag that indicates we're the first to create the memory so it - ** must be zero-initialized */ - lastErrno = osGetLastError(); - if (lastErrno == ERROR_ALREADY_EXISTS){ - bInit = FALSE; - } - - sqlite3_free(zName); - - /* If we succeeded in making the shared memory handle, map it. */ - if( pFile->hShared ){ - pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, - FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); - /* If mapping failed, close the shared memory handle and erase it */ - if( !pFile->shared ){ - pFile->lastErrno = osGetLastError(); - winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock2", zFilename); - bLogged = TRUE; - osCloseHandle(pFile->hShared); - pFile->hShared = NULL; - } - } - - /* If shared memory could not be created, then close the mutex and fail */ - if( pFile->hShared==NULL ){ - if( !bLogged ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock3", zFilename); - bLogged = TRUE; - } - winceMutexRelease(pFile->hMutex); - osCloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - return SQLITE_IOERR; - } - - /* Initialize the shared memory if we're supposed to */ - if( bInit ){ - memset(pFile->shared, 0, sizeof(winceLock)); - } - - winceMutexRelease(pFile->hMutex); - return SQLITE_OK; -} - -/* -** Destroy the part of winFile that deals with wince locks -*/ -static void winceDestroyLock(winFile *pFile){ - if (pFile->hMutex){ - /* Acquire the mutex */ - winceMutexAcquire(pFile->hMutex); - - /* The following blocks should probably assert in debug mode, but they - are to cleanup in case any locks remained open */ - if (pFile->local.nReaders){ - pFile->shared->nReaders --; - } - if (pFile->local.bReserved){ - pFile->shared->bReserved = FALSE; - } - if (pFile->local.bPending){ - pFile->shared->bPending = FALSE; - } - if (pFile->local.bExclusive){ - pFile->shared->bExclusive = FALSE; - } - - /* De-reference and close our copy of the shared memory handle */ - osUnmapViewOfFile(pFile->shared); - osCloseHandle(pFile->hShared); - - /* Done with the mutex */ - winceMutexRelease(pFile->hMutex); - osCloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - } -} - -/* -** An implementation of the LockFile() API of Windows for CE -*/ -static BOOL winceLockFile( - LPHANDLE phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToLockLow, - DWORD nNumberOfBytesToLockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - UNUSED_PARAMETER(dwFileOffsetHigh); - UNUSED_PARAMETER(nNumberOfBytesToLockHigh); - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Wanting an exclusive lock? */ - if (dwFileOffsetLow == (DWORD)SHARED_FIRST - && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ - if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ - pFile->shared->bExclusive = TRUE; - pFile->local.bExclusive = TRUE; - bReturn = TRUE; - } - } - - /* Want a read-only lock? */ - else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && - nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bExclusive == 0){ - pFile->local.nReaders ++; - if (pFile->local.nReaders == 1){ - pFile->shared->nReaders ++; - } - bReturn = TRUE; - } - } - - /* Want a pending lock? */ - else if (dwFileOffsetLow == (DWORD)PENDING_BYTE - && nNumberOfBytesToLockLow == 1){ - /* If no pending lock has been acquired, then acquire it */ - if (pFile->shared->bPending == 0) { - pFile->shared->bPending = TRUE; - pFile->local.bPending = TRUE; - bReturn = TRUE; - } - } - - /* Want a reserved lock? */ - else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE - && nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bReserved == 0) { - pFile->shared->bReserved = TRUE; - pFile->local.bReserved = TRUE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} - -/* -** An implementation of the UnlockFile API of Windows for CE -*/ -static BOOL winceUnlockFile( - LPHANDLE phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToUnlockLow, - DWORD nNumberOfBytesToUnlockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - UNUSED_PARAMETER(dwFileOffsetHigh); - UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Releasing a reader lock or an exclusive lock */ - if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ - /* Did we have an exclusive lock? */ - if (pFile->local.bExclusive){ - assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); - pFile->local.bExclusive = FALSE; - pFile->shared->bExclusive = FALSE; - bReturn = TRUE; - } - - /* Did we just have a reader lock? */ - else if (pFile->local.nReaders){ - assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE - || nNumberOfBytesToUnlockLow == 1); - pFile->local.nReaders --; - if (pFile->local.nReaders == 0) - { - pFile->shared->nReaders --; - } - bReturn = TRUE; - } - } - - /* Releasing a pending lock */ - else if (dwFileOffsetLow == (DWORD)PENDING_BYTE - && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bPending){ - pFile->local.bPending = FALSE; - pFile->shared->bPending = FALSE; - bReturn = TRUE; - } - } - /* Releasing a reserved lock */ - else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE - && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bReserved) { - pFile->local.bReserved = FALSE; - pFile->shared->bReserved = FALSE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} -/* -** End of the special code for wince -*****************************************************************************/ -#endif /* SQLITE_OS_WINCE */ - -/* -** Lock a file region. -*/ -static BOOL winLockFile( - LPHANDLE phFile, - DWORD flags, - DWORD offsetLow, - DWORD offsetHigh, - DWORD numBytesLow, - DWORD numBytesHigh -){ -#if SQLITE_OS_WINCE - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API LockFile. - */ - return winceLockFile(phFile, offsetLow, offsetHigh, - numBytesLow, numBytesHigh); -#else - if( osIsNT() ){ - OVERLAPPED ovlp; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = offsetLow; - ovlp.OffsetHigh = offsetHigh; - return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); - }else{ - return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, - numBytesHigh); - } -#endif -} - -/* -** Unlock a file region. - */ -static BOOL winUnlockFile( - LPHANDLE phFile, - DWORD offsetLow, - DWORD offsetHigh, - DWORD numBytesLow, - DWORD numBytesHigh -){ -#if SQLITE_OS_WINCE - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API UnlockFile. - */ - return winceUnlockFile(phFile, offsetLow, offsetHigh, - numBytesLow, numBytesHigh); -#else - if( osIsNT() ){ - OVERLAPPED ovlp; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = offsetLow; - ovlp.OffsetHigh = offsetHigh; - return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); - }else{ - return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, - numBytesHigh); - } -#endif -} - -/***************************************************************************** -** The next group of routines implement the I/O methods specified -** by the sqlite3_io_methods object. -******************************************************************************/ - -/* -** Some Microsoft compilers lack this definition. -*/ -#ifndef INVALID_SET_FILE_POINTER -# define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -/* -** Move the current position of the file handle passed as the first -** argument to offset iOffset within the file. If successful, return 0. -** Otherwise, set pFile->lastErrno and return non-zero. -*/ -static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ -#if !SQLITE_OS_WINRT - LONG upperBits; /* Most sig. 32 bits of new offset */ - LONG lowerBits; /* Least sig. 32 bits of new offset */ - DWORD dwRet; /* Value returned by SetFilePointer() */ - DWORD lastErrno; /* Value returned by GetLastError() */ - - OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); - - upperBits = (LONG)((iOffset>>32) & 0x7fffffff); - lowerBits = (LONG)(iOffset & 0xffffffff); - - /* API oddity: If successful, SetFilePointer() returns a dword - ** containing the lower 32-bits of the new file-offset. Or, if it fails, - ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, - ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine - ** whether an error has actually occurred, it is also necessary to call - ** GetLastError(). - */ - dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); - - if( (dwRet==INVALID_SET_FILE_POINTER - && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, - "winSeekFile", pFile->zPath); - OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); - return 1; - } - - OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); - return 0; -#else - /* - ** Same as above, except that this implementation works for WinRT. - */ - - LARGE_INTEGER x; /* The new offset */ - BOOL bRet; /* Value returned by SetFilePointerEx() */ - - x.QuadPart = iOffset; - bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); - - if(!bRet){ - pFile->lastErrno = osGetLastError(); - winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, - "winSeekFile", pFile->zPath); - OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); - return 1; - } - - OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); - return 0; -#endif -} - -#if SQLITE_MAX_MMAP_SIZE>0 -/* Forward references to VFS helper methods used for memory mapped files */ -static int winMapfile(winFile*, sqlite3_int64); -static int winUnmapfile(winFile*); -#endif - -/* -** Close a file. -** -** It is reported that an attempt to close a handle might sometimes -** fail. This is a very unreasonable result, but Windows is notorious -** for being unreasonable so I do not doubt that it might happen. If -** the close fails, we pause for 100 milliseconds and try again. As -** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before -** giving up and returning an error. -*/ -#define MX_CLOSE_ATTEMPT 3 -static int winClose(sqlite3_file *id){ - int rc, cnt = 0; - winFile *pFile = (winFile*)id; - - assert( id!=0 ); -#ifndef SQLITE_OMIT_WAL - assert( pFile->pShm==0 ); -#endif - assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); - OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", - osGetCurrentProcessId(), pFile, pFile->h)); - -#if SQLITE_MAX_MMAP_SIZE>0 - winUnmapfile(pFile); -#endif - - do{ - rc = osCloseHandle(pFile->h); - /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); -#if SQLITE_OS_WINCE -#define WINCE_DELETION_ATTEMPTS 3 - { - winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; - if( pAppData==NULL || !pAppData->bNoLock ){ - winceDestroyLock(pFile); - } - } - if( pFile->zDeleteOnClose ){ - int cnt = 0; - while( - osDeleteFileW(pFile->zDeleteOnClose)==0 - && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff - && cnt++ < WINCE_DELETION_ATTEMPTS - ){ - sqlite3_win32_sleep(100); /* Wait a little before trying again */ - } - sqlite3_free(pFile->zDeleteOnClose); - } -#endif - if( rc ){ - pFile->h = NULL; - } - OpenCounter(-1); - OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", - osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); - return rc ? SQLITE_OK - : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), - "winClose", pFile->zPath); -} - -/* -** Read data from a file into a buffer. Return SQLITE_OK if all -** bytes were read successfully and SQLITE_IOERR if anything goes -** wrong. -*/ -static int winRead( - sqlite3_file *id, /* File to read from */ - void *pBuf, /* Write content into this buffer */ - int amt, /* Number of bytes to read */ - sqlite3_int64 offset /* Begin reading at this offset */ -){ -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) - OVERLAPPED overlapped; /* The offset for ReadFile. */ -#endif - winFile *pFile = (winFile*)id; /* file handle */ - DWORD nRead; /* Number of bytes actually read from file */ - int nRetry = 0; /* Number of retrys */ - - assert( id!=0 ); - assert( amt>0 ); - assert( offset>=0 ); - SimulateIOError(return SQLITE_IOERR_READ); - OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " - "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, - pFile->h, pBuf, amt, offset, pFile->locktype)); - -#if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transfering - ** data from the memory mapping using memcpy(). */ - if( offsetmmapSize ){ - if( offset+amt <= pFile->mmapSize ){ - memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); - OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; - }else{ - int nCopy = (int)(pFile->mmapSize - offset); - memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); - pBuf = &((u8 *)pBuf)[nCopy]; - amt -= nCopy; - offset += nCopy; - } - } -#endif - -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) - if( winSeekFile(pFile, offset) ){ - OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_FULL; - } - while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ -#else - memset(&overlapped, 0, sizeof(OVERLAPPED)); - overlapped.Offset = (LONG)(offset & 0xffffffff); - overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); - while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && - osGetLastError()!=ERROR_HANDLE_EOF ){ -#endif - DWORD lastErrno; - if( winRetryIoerr(&nRetry, &lastErrno) ) continue; - pFile->lastErrno = lastErrno; - OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, - "winRead", pFile->zPath); - } - winLogIoerr(nRetry, __LINE__); - if( nRead<(DWORD)amt ){ - /* Unread parts of the buffer must be zero-filled */ - memset(&((char*)pBuf)[nRead], 0, amt-nRead); - OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_IOERR_SHORT_READ; - } - - OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; -} - -/* -** Write data from a buffer into a file. Return SQLITE_OK on success -** or some other error code on failure. -*/ -static int winWrite( - sqlite3_file *id, /* File to write into */ - const void *pBuf, /* The bytes to be written */ - int amt, /* Number of bytes to write */ - sqlite3_int64 offset /* Offset into the file to begin writing at */ -){ - int rc = 0; /* True if error has occurred, else false */ - winFile *pFile = (winFile*)id; /* File handle */ - int nRetry = 0; /* Number of retries */ - - assert( amt>0 ); - assert( pFile ); - SimulateIOError(return SQLITE_IOERR_WRITE); - SimulateDiskfullError(return SQLITE_FULL); - - OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " - "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, - pFile->h, pBuf, amt, offset, pFile->locktype)); - -#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this write request as possible by transfering - ** data from the memory mapping using memcpy(). */ - if( offsetmmapSize ){ - if( offset+amt <= pFile->mmapSize ){ - memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); - OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; - }else{ - int nCopy = (int)(pFile->mmapSize - offset); - memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); - pBuf = &((u8 *)pBuf)[nCopy]; - amt -= nCopy; - offset += nCopy; - } - } -#endif - -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) - rc = winSeekFile(pFile, offset); - if( rc==0 ){ -#else - { -#endif -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) - OVERLAPPED overlapped; /* The offset for WriteFile. */ -#endif - u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ - int nRem = amt; /* Number of bytes yet to be written */ - DWORD nWrite; /* Bytes written by each WriteFile() call */ - DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ - -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) - memset(&overlapped, 0, sizeof(OVERLAPPED)); - overlapped.Offset = (LONG)(offset & 0xffffffff); - overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); -#endif - - while( nRem>0 ){ -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) - if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ -#else - if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ -#endif - if( winRetryIoerr(&nRetry, &lastErrno) ) continue; - break; - } - assert( nWrite==0 || nWrite<=(DWORD)nRem ); - if( nWrite==0 || nWrite>(DWORD)nRem ){ - lastErrno = osGetLastError(); - break; - } -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) - offset += nWrite; - overlapped.Offset = (LONG)(offset & 0xffffffff); - overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); -#endif - aRem += nWrite; - nRem -= nWrite; - } - if( nRem>0 ){ - pFile->lastErrno = lastErrno; - rc = 1; - } - } - - if( rc ){ - if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) - || ( pFile->lastErrno==ERROR_DISK_FULL )){ - OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return winLogError(SQLITE_FULL, pFile->lastErrno, - "winWrite1", pFile->zPath); - } - OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, - "winWrite2", pFile->zPath); - }else{ - winLogIoerr(nRetry, __LINE__); - } - OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; -} - -/* -** Truncate an open file to a specified size -*/ -static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ - winFile *pFile = (winFile*)id; /* File handle object */ - int rc = SQLITE_OK; /* Return code for this function */ - DWORD lastErrno; - - assert( pFile ); - SimulateIOError(return SQLITE_IOERR_TRUNCATE); - OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", - osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); - - /* If the user has configured a chunk-size for this file, truncate the - ** file so that it consists of an integer number of chunks (i.e. the - ** actual file size after the operation may be larger than the requested - ** size). - */ - if( pFile->szChunk>0 ){ - nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; - } - - /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ - if( winSeekFile(pFile, nByte) ){ - rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, - "winTruncate1", pFile->zPath); - }else if( 0==osSetEndOfFile(pFile->h) && - ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ - pFile->lastErrno = lastErrno; - rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, - "winTruncate2", pFile->zPath); - } - -#if SQLITE_MAX_MMAP_SIZE>0 - /* If the file was truncated to a size smaller than the currently - ** mapped region, reduce the effective mapping size as well. SQLite will - ** use read() and write() to access data beyond this point from now on. - */ - if( pFile->pMapRegion && nBytemmapSize ){ - pFile->mmapSize = nByte; - } -#endif - - OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", - osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); - return rc; -} - -#ifdef SQLITE_TEST -/* -** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. -*/ -SQLITE_API int sqlite3_sync_count = 0; -SQLITE_API int sqlite3_fullsync_count = 0; -#endif - -/* -** Make sure all writes to a particular file are committed to disk. -*/ -static int winSync(sqlite3_file *id, int flags){ -#ifndef SQLITE_NO_SYNC - /* - ** Used only when SQLITE_NO_SYNC is not defined. - */ - BOOL rc; -#endif -#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ - defined(SQLITE_HAVE_OS_TRACE) - /* - ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or - ** OSTRACE() macros. - */ - winFile *pFile = (winFile*)id; -#else - UNUSED_PARAMETER(id); -#endif - - assert( pFile ); - /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ - assert((flags&0x0F)==SQLITE_SYNC_NORMAL - || (flags&0x0F)==SQLITE_SYNC_FULL - ); - - /* Unix cannot, but some systems may return SQLITE_FULL from here. This - ** line is to test that doing so does not cause any problems. - */ - SimulateDiskfullError( return SQLITE_FULL ); - - OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", - osGetCurrentProcessId(), pFile, pFile->h, flags, - pFile->locktype)); - -#ifndef SQLITE_TEST - UNUSED_PARAMETER(flags); -#else - if( (flags&0x0F)==SQLITE_SYNC_FULL ){ - sqlite3_fullsync_count++; - } - sqlite3_sync_count++; -#endif - - /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a - ** no-op - */ -#ifdef SQLITE_NO_SYNC - OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; -#else -#if SQLITE_MAX_MMAP_SIZE>0 - if( pFile->pMapRegion ){ - if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ - OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " - "rc=SQLITE_OK\n", osGetCurrentProcessId(), - pFile, pFile->pMapRegion)); - }else{ - pFile->lastErrno = osGetLastError(); - OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " - "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), - pFile, pFile->pMapRegion)); - return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, - "winSync1", pFile->zPath); - } - } -#endif - rc = osFlushFileBuffers(pFile->h); - SimulateIOError( rc=FALSE ); - if( rc ){ - OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return SQLITE_OK; - }else{ - pFile->lastErrno = osGetLastError(); - OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", - osGetCurrentProcessId(), pFile, pFile->h)); - return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, - "winSync2", pFile->zPath); - } -#endif -} - -/* -** Determine the current size of a file in bytes -*/ -static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ - winFile *pFile = (winFile*)id; - int rc = SQLITE_OK; - - assert( id!=0 ); - assert( pSize!=0 ); - SimulateIOError(return SQLITE_IOERR_FSTAT); - OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); - -#if SQLITE_OS_WINRT - { - FILE_STANDARD_INFO info; - if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, - &info, sizeof(info)) ){ - *pSize = info.EndOfFile.QuadPart; - }else{ - pFile->lastErrno = osGetLastError(); - rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, - "winFileSize", pFile->zPath); - } - } -#else - { - DWORD upperBits; - DWORD lowerBits; - DWORD lastErrno; - - lowerBits = osGetFileSize(pFile->h, &upperBits); - *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; - if( (lowerBits == INVALID_FILE_SIZE) - && ((lastErrno = osGetLastError())!=NO_ERROR) ){ - pFile->lastErrno = lastErrno; - rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, - "winFileSize", pFile->zPath); - } - } -#endif - OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", - pFile->h, pSize, *pSize, sqlite3ErrName(rc))); - return rc; -} - -/* -** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. -*/ -#ifndef LOCKFILE_FAIL_IMMEDIATELY -# define LOCKFILE_FAIL_IMMEDIATELY 1 -#endif - -#ifndef LOCKFILE_EXCLUSIVE_LOCK -# define LOCKFILE_EXCLUSIVE_LOCK 2 -#endif - -/* -** Historically, SQLite has used both the LockFile and LockFileEx functions. -** When the LockFile function was used, it was always expected to fail -** immediately if the lock could not be obtained. Also, it always expected to -** obtain an exclusive lock. These flags are used with the LockFileEx function -** and reflect those expectations; therefore, they should not be changed. -*/ -#ifndef SQLITE_LOCKFILE_FLAGS -# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ - LOCKFILE_EXCLUSIVE_LOCK) -#endif - -/* -** Currently, SQLite never calls the LockFileEx function without wanting the -** call to fail immediately if the lock cannot be obtained. -*/ -#ifndef SQLITE_LOCKFILEEX_FLAGS -# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) -#endif - -/* -** Acquire a reader lock. -** Different API routines are called depending on whether or not this -** is Win9x or WinNT. -*/ -static int winGetReadLock(winFile *pFile){ - int res; - OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); - if( osIsNT() ){ -#if SQLITE_OS_WINCE - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API LockFileEx. - */ - res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); -#else - res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, - SHARED_SIZE, 0); -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - int lk; - sqlite3_randomness(sizeof(lk), &lk); - pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, - SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } -#endif - if( res == 0 ){ - pFile->lastErrno = osGetLastError(); - /* No need to log a failure to lock */ - } - OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); - return res; -} - -/* -** Undo a readlock -*/ -static int winUnlockReadLock(winFile *pFile){ - int res; - DWORD lastErrno; - OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); - if( osIsNT() ){ - res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } -#endif - if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, - "winUnlockReadLock", pFile->zPath); - } - OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); - return res; -} - -/* -** Lock the file with the lock specified by parameter locktype - one -** of the following: -** -** (1) SHARED_LOCK -** (2) RESERVED_LOCK -** (3) PENDING_LOCK -** (4) EXCLUSIVE_LOCK -** -** Sometimes when requesting one lock state, additional lock states -** are inserted in between. The locking might fail on one of the later -** transitions leaving the lock state different from what it started but -** still short of its goal. The following chart shows the allowed -** transitions and the inserted intermediate states: -** -** UNLOCKED -> SHARED -** SHARED -> RESERVED -** SHARED -> (PENDING) -> EXCLUSIVE -** RESERVED -> (PENDING) -> EXCLUSIVE -** PENDING -> EXCLUSIVE -** -** This routine will only increase a lock. The winUnlock() routine -** erases all locks at once and returns us immediately to locking level 0. -** It is not possible to lower the locking level one step at a time. You -** must go straight to locking level 0. -*/ -static int winLock(sqlite3_file *id, int locktype){ - int rc = SQLITE_OK; /* Return code from subroutines */ - int res = 1; /* Result of a Windows lock call */ - int newLocktype; /* Set pFile->locktype to this value before exiting */ - int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ - winFile *pFile = (winFile*)id; - DWORD lastErrno = NO_ERROR; - - assert( id!=0 ); - OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", - pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); - - /* If there is already a lock of this type or more restrictive on the - ** OsFile, do nothing. Don't use the end_lock: exit path, as - ** sqlite3OsEnterMutex() hasn't been called yet. - */ - if( pFile->locktype>=locktype ){ - OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - - /* Do not allow any kind of write-lock on a read-only database - */ - if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){ - return SQLITE_IOERR_LOCK; - } - - /* Make sure the locking sequence is correct - */ - assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - - /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or - ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of - ** the PENDING_LOCK byte is temporary. - */ - newLocktype = pFile->locktype; - if( pFile->locktype==NO_LOCK - || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) - ){ - int cnt = 3; - while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, - PENDING_BYTE, 0, 1, 0))==0 ){ - /* Try 3 times to get the pending lock. This is needed to work - ** around problems caused by indexing and/or anti-virus software on - ** Windows systems. - ** If you are using this code as a model for alternative VFSes, do not - ** copy this retry logic. It is a hack intended for Windows only. - */ - lastErrno = osGetLastError(); - OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", - pFile->h, cnt, res)); - if( lastErrno==ERROR_INVALID_HANDLE ){ - pFile->lastErrno = lastErrno; - rc = SQLITE_IOERR_LOCK; - OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", - pFile->h, cnt, sqlite3ErrName(rc))); - return rc; - } - if( cnt ) sqlite3_win32_sleep(1); - } - gotPendingLock = res; - if( !res ){ - lastErrno = osGetLastError(); - } - } - - /* Acquire a shared lock - */ - if( locktype==SHARED_LOCK && res ){ - assert( pFile->locktype==NO_LOCK ); - res = winGetReadLock(pFile); - if( res ){ - newLocktype = SHARED_LOCK; - }else{ - lastErrno = osGetLastError(); - } - } - - /* Acquire a RESERVED lock - */ - if( locktype==RESERVED_LOCK && res ){ - assert( pFile->locktype==SHARED_LOCK ); - res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); - if( res ){ - newLocktype = RESERVED_LOCK; - }else{ - lastErrno = osGetLastError(); - } - } - - /* Acquire a PENDING lock - */ - if( locktype==EXCLUSIVE_LOCK && res ){ - newLocktype = PENDING_LOCK; - gotPendingLock = 0; - } - - /* Acquire an EXCLUSIVE lock - */ - if( locktype==EXCLUSIVE_LOCK && res ){ - assert( pFile->locktype>=SHARED_LOCK ); - res = winUnlockReadLock(pFile); - res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, - SHARED_SIZE, 0); - if( res ){ - newLocktype = EXCLUSIVE_LOCK; - }else{ - lastErrno = osGetLastError(); - winGetReadLock(pFile); - } - } - - /* If we are holding a PENDING lock that ought to be released, then - ** release it now. - */ - if( gotPendingLock && locktype==SHARED_LOCK ){ - winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); - } - - /* Update the state of the lock has held in the file descriptor then - ** return the appropriate result code. - */ - if( res ){ - rc = SQLITE_OK; - }else{ - pFile->lastErrno = lastErrno; - rc = SQLITE_BUSY; - OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", - pFile->h, locktype, newLocktype)); - } - pFile->locktype = (u8)newLocktype; - OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", - pFile->h, pFile->locktype, sqlite3ErrName(rc))); - return rc; -} - -/* -** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, return -** non-zero, otherwise zero. -*/ -static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ - int res; - winFile *pFile = (winFile*)id; - - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); - - assert( id!=0 ); - if( pFile->locktype>=RESERVED_LOCK ){ - res = 1; - OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); - }else{ - res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); - if( res ){ - winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); - } - res = !res; - OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); - } - *pResOut = res; - OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", - pFile->h, pResOut, *pResOut)); - return SQLITE_OK; -} - -/* -** Lower the locking level on file descriptor id to locktype. locktype -** must be either NO_LOCK or SHARED_LOCK. -** -** If the locking level of the file descriptor is already at or below -** the requested locking level, this routine is a no-op. -** -** It is not possible for this routine to fail if the second argument -** is NO_LOCK. If the second argument is SHARED_LOCK then this routine -** might return SQLITE_IOERR; -*/ -static int winUnlock(sqlite3_file *id, int locktype){ - int type; - winFile *pFile = (winFile*)id; - int rc = SQLITE_OK; - assert( pFile!=0 ); - assert( locktype<=SHARED_LOCK ); - OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", - pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); - type = pFile->locktype; - if( type>=EXCLUSIVE_LOCK ){ - winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ - /* This should never happen. We should always be able to - ** reacquire the read lock */ - rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), - "winUnlock", pFile->zPath); - } - } - if( type>=RESERVED_LOCK ){ - winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); - } - if( locktype==NO_LOCK && type>=SHARED_LOCK ){ - winUnlockReadLock(pFile); - } - if( type>=PENDING_LOCK ){ - winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); - } - pFile->locktype = (u8)locktype; - OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", - pFile->h, pFile->locktype, sqlite3ErrName(rc))); - return rc; -} - -/****************************************************************************** -****************************** No-op Locking ********************************** -** -** Of the various locking implementations available, this is by far the -** simplest: locking is ignored. No attempt is made to lock the database -** file for reading or writing. -** -** This locking mode is appropriate for use on read-only databases -** (ex: databases that are burned into CD-ROM, for example.) It can -** also be used if the application employs some external mechanism to -** prevent simultaneous access of the same database by two or more -** database connections. But there is a serious risk of database -** corruption if this locking mode is used in situations where multiple -** database connections are accessing the same database file at the same -** time and one or more of those connections are writing. -*/ - -static int winNolockLock(sqlite3_file *id, int locktype){ - UNUSED_PARAMETER(id); - UNUSED_PARAMETER(locktype); - return SQLITE_OK; -} - -static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ - UNUSED_PARAMETER(id); - UNUSED_PARAMETER(pResOut); - return SQLITE_OK; -} - -static int winNolockUnlock(sqlite3_file *id, int locktype){ - UNUSED_PARAMETER(id); - UNUSED_PARAMETER(locktype); - return SQLITE_OK; -} - -/******************* End of the no-op lock implementation ********************* -******************************************************************************/ - -/* -** If *pArg is initially negative then this is a query. Set *pArg to -** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. -** -** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. -*/ -static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ - if( *pArg<0 ){ - *pArg = (pFile->ctrlFlags & mask)!=0; - }else if( (*pArg)==0 ){ - pFile->ctrlFlags &= ~mask; - }else{ - pFile->ctrlFlags |= mask; - } -} - -/* Forward references to VFS helper methods used for temporary files */ -static int winGetTempname(sqlite3_vfs *, char **); -static int winIsDir(const void *); -static BOOL winIsDriveLetterAndColon(const char *); - -/* -** Control and query of the open file handle. -*/ -static int winFileControl(sqlite3_file *id, int op, void *pArg){ - winFile *pFile = (winFile*)id; - OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); - switch( op ){ - case SQLITE_FCNTL_LOCKSTATE: { - *(int*)pArg = pFile->locktype; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_LAST_ERRNO: { - *(int*)pArg = (int)pFile->lastErrno; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_CHUNK_SIZE: { - pFile->szChunk = *(int *)pArg; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_SIZE_HINT: { - if( pFile->szChunk>0 ){ - sqlite3_int64 oldSz; - int rc = winFileSize(id, &oldSz); - if( rc==SQLITE_OK ){ - sqlite3_int64 newSz = *(sqlite3_int64*)pArg; - if( newSz>oldSz ){ - SimulateIOErrorBenign(1); - rc = winTruncate(id, newSz); - SimulateIOErrorBenign(0); - } - } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); - return rc; - } - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_PERSIST_WAL: { - winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { - winModeBit(pFile, WINFILE_PSOW, (int*)pArg); - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_VFSNAME: { - *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_WIN32_AV_RETRY: { - int *a = (int*)pArg; - if( a[0]>0 ){ - winIoerrRetry = a[0]; - }else{ - a[0] = winIoerrRetry; - } - if( a[1]>0 ){ - winIoerrRetryDelay = a[1]; - }else{ - a[1] = winIoerrRetryDelay; - } - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } - case SQLITE_FCNTL_WIN32_GET_HANDLE: { - LPHANDLE phFile = (LPHANDLE)pArg; - *phFile = pFile->h; - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); - return SQLITE_OK; - } -#ifdef SQLITE_TEST - case SQLITE_FCNTL_WIN32_SET_HANDLE: { - LPHANDLE phFile = (LPHANDLE)pArg; - HANDLE hOldFile = pFile->h; - pFile->h = *phFile; - *phFile = hOldFile; - OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", - hOldFile, pFile->h)); - return SQLITE_OK; - } -#endif - case SQLITE_FCNTL_TEMPFILENAME: { - char *zTFile = 0; - int rc = winGetTempname(pFile->pVfs, &zTFile); - if( rc==SQLITE_OK ){ - *(char**)pArg = zTFile; - } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); - return rc; - } -#if SQLITE_MAX_MMAP_SIZE>0 - case SQLITE_FCNTL_MMAP_SIZE: { - i64 newLimit = *(i64*)pArg; - int rc = SQLITE_OK; - if( newLimit>sqlite3GlobalConfig.mxMmap ){ - newLimit = sqlite3GlobalConfig.mxMmap; - } - *(i64*)pArg = pFile->mmapSizeMax; - if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ - pFile->mmapSizeMax = newLimit; - if( pFile->mmapSize>0 ){ - winUnmapfile(pFile); - rc = winMapfile(pFile, -1); - } - } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); - return rc; - } -#endif - } - OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); - return SQLITE_NOTFOUND; -} - -/* -** Return the sector size in bytes of the underlying block device for -** the specified file. This is almost always 512 bytes, but may be -** larger for some devices. -** -** SQLite code assumes this function cannot fail. It also assumes that -** if two files are created in the same file-system directory (i.e. -** a database and its journal file) that the sector size will be the -** same for both. -*/ -static int winSectorSize(sqlite3_file *id){ - (void)id; - return SQLITE_DEFAULT_SECTOR_SIZE; -} - -/* -** Return a vector of device characteristics. -*/ -static int winDeviceCharacteristics(sqlite3_file *id){ - winFile *p = (winFile*)id; - return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | - ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); -} - -/* -** Windows will only let you create file view mappings -** on allocation size granularity boundaries. -** During sqlite3_os_init() we do a GetSystemInfo() -** to get the granularity size. -*/ -static SYSTEM_INFO winSysInfo; - -#ifndef SQLITE_OMIT_WAL - -/* -** Helper functions to obtain and relinquish the global mutex. The -** global mutex is used to protect the winLockInfo objects used by -** this file, all of which may be shared by multiple threads. -** -** Function winShmMutexHeld() is used to assert() that the global mutex -** is held when required. This function is only used as part of assert() -** statements. e.g. -** -** winShmEnterMutex() -** assert( winShmMutexHeld() ); -** winShmLeaveMutex() -*/ -static void winShmEnterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -static void winShmLeaveMutex(void){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -#ifndef NDEBUG -static int winShmMutexHeld(void) { - return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1)); -} -#endif - -/* -** Object used to represent a single file opened and mmapped to provide -** shared memory. When multiple threads all reference the same -** log-summary, each thread has its own winFile object, but they all -** point to a single instance of this object. In other words, each -** log-summary is opened only once per process. -** -** winShmMutexHeld() must be true when creating or destroying -** this object or while reading or writing the following fields: -** -** nRef -** pNext -** -** The following fields are read-only after the object is created: -** -** fid -** zFilename -** -** Either winShmNode.mutex must be held or winShmNode.nRef==0 and -** winShmMutexHeld() is true when reading or writing any other field -** in this structure. -** -*/ -struct winShmNode { - sqlite3_mutex *mutex; /* Mutex to access this object */ - char *zFilename; /* Name of the file */ - winFile hFile; /* File handle from winOpen */ - - int szRegion; /* Size of shared-memory regions */ - int nRegion; /* Size of array apRegion */ - struct ShmRegion { - HANDLE hMap; /* File handle from CreateFileMapping */ - void *pMap; - } *aRegion; - DWORD lastErrno; /* The Windows errno from the last I/O error */ - - int nRef; /* Number of winShm objects pointing to this */ - winShm *pFirst; /* All winShm objects pointing to this */ - winShmNode *pNext; /* Next in list of all winShmNode objects */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - u8 nextShmId; /* Next available winShm.id value */ -#endif -}; - -/* -** A global array of all winShmNode objects. -** -** The winShmMutexHeld() must be true while reading or writing this list. -*/ -static winShmNode *winShmNodeList = 0; - -/* -** Structure used internally by this VFS to record the state of an -** open shared memory connection. -** -** The following fields are initialized when this object is created and -** are read-only thereafter: -** -** winShm.pShmNode -** winShm.id -** -** All other fields are read/write. The winShm.pShmNode->mutex must be held -** while accessing any read/write fields. -*/ -struct winShm { - winShmNode *pShmNode; /* The underlying winShmNode object */ - winShm *pNext; /* Next winShm with the same winShmNode */ - u8 hasMutex; /* True if holding the winShmNode mutex */ - u16 sharedMask; /* Mask of shared locks held */ - u16 exclMask; /* Mask of exclusive locks held */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - u8 id; /* Id of this connection with its winShmNode */ -#endif -}; - -/* -** Constants used for locking -*/ -#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ -#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ - -/* -** Apply advisory locks for all n bytes beginning at ofst. -*/ -#define WINSHM_UNLCK 1 -#define WINSHM_RDLCK 2 -#define WINSHM_WRLCK 3 -static int winShmSystemLock( - winShmNode *pFile, /* Apply locks to this open shared-memory segment */ - int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ - int ofst, /* Offset to first byte to be locked/unlocked */ - int nByte /* Number of bytes to lock or unlock */ -){ - int rc = 0; /* Result code form Lock/UnlockFileEx() */ - - /* Access to the winShmNode object is serialized by the caller */ - assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); - - OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", - pFile->hFile.h, lockType, ofst, nByte)); - - /* Release/Acquire the system-level lock */ - if( lockType==WINSHM_UNLCK ){ - rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); - }else{ - /* Initialize the locking parameters */ - DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; - if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; - rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); - } - - if( rc!= 0 ){ - rc = SQLITE_OK; - }else{ - pFile->lastErrno = osGetLastError(); - rc = SQLITE_BUSY; - } - - OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", - pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : - "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); - - return rc; -} - -/* Forward references to VFS methods */ -static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); -static int winDelete(sqlite3_vfs *,const char*,int); - -/* -** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. -** -** This is not a VFS shared-memory method; it is a utility function called -** by VFS shared-memory methods. -*/ -static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ - winShmNode **pp; - winShmNode *p; - assert( winShmMutexHeld() ); - OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", - osGetCurrentProcessId(), deleteFlag)); - pp = &winShmNodeList; - while( (p = *pp)!=0 ){ - if( p->nRef==0 ){ - int i; - if( p->mutex ){ sqlite3_mutex_free(p->mutex); } - for(i=0; inRegion; i++){ - BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); - OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", - osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); - UNUSED_VARIABLE_VALUE(bRc); - bRc = osCloseHandle(p->aRegion[i].hMap); - OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", - osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); - UNUSED_VARIABLE_VALUE(bRc); - } - if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ - SimulateIOErrorBenign(1); - winClose((sqlite3_file *)&p->hFile); - SimulateIOErrorBenign(0); - } - if( deleteFlag ){ - SimulateIOErrorBenign(1); - sqlite3BeginBenignMalloc(); - winDelete(pVfs, p->zFilename, 0); - sqlite3EndBenignMalloc(); - SimulateIOErrorBenign(0); - } - *pp = p->pNext; - sqlite3_free(p->aRegion); - sqlite3_free(p); - }else{ - pp = &p->pNext; - } - } -} - -/* -** Open the shared-memory area associated with database file pDbFd. -** -** When opening a new shared-memory file, if no other instances of that -** file are currently open, in this process or in other processes, then -** the file must be truncated to zero length or have its header cleared. -*/ -static int winOpenSharedMemory(winFile *pDbFd){ - struct winShm *p; /* The connection to be opened */ - struct winShmNode *pShmNode = 0; /* The underlying mmapped file */ - int rc; /* Result code */ - struct winShmNode *pNew; /* Newly allocated winShmNode */ - int nName; /* Size of zName in bytes */ - - assert( pDbFd->pShm==0 ); /* Not previously opened */ - - /* Allocate space for the new sqlite3_shm object. Also speculatively - ** allocate space for a new winShmNode and filename. - */ - p = sqlite3MallocZero( sizeof(*p) ); - if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; - nName = sqlite3Strlen30(pDbFd->zPath); - pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); - if( pNew==0 ){ - sqlite3_free(p); - return SQLITE_IOERR_NOMEM_BKPT; - } - pNew->zFilename = (char*)&pNew[1]; - sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); - sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); - - /* Look to see if there is an existing winShmNode that can be used. - ** If no matching winShmNode currently exists, create a new one. - */ - winShmEnterMutex(); - for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ - /* TBD need to come up with better match here. Perhaps - ** use FILE_ID_BOTH_DIR_INFO Structure. - */ - if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; - } - if( pShmNode ){ - sqlite3_free(pNew); - }else{ - pShmNode = pNew; - pNew = 0; - ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; - pShmNode->pNext = winShmNodeList; - winShmNodeList = pShmNode; - - if( sqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ - rc = SQLITE_IOERR_NOMEM_BKPT; - goto shm_open_err; - } - } - - rc = winOpen(pDbFd->pVfs, - pShmNode->zFilename, /* Name of the file (UTF-8) */ - (sqlite3_file*)&pShmNode->hFile, /* File handle here */ - SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, - 0); - if( SQLITE_OK!=rc ){ - goto shm_open_err; - } - - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ - rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); - if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), - "winOpenShm", pDbFd->zPath); - } - } - if( rc==SQLITE_OK ){ - winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); - rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; - } - - /* Make the new connection a child of the winShmNode */ - p->pShmNode = pShmNode; -#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - p->id = pShmNode->nextShmId++; -#endif - pShmNode->nRef++; - pDbFd->pShm = p; - winShmLeaveMutex(); - - /* The reference count on pShmNode has already been incremented under - ** the cover of the winShmEnterMutex() mutex and the pointer from the - ** new (struct winShm) object to the pShmNode has been set. All that is - ** left to do is to link the new object into the linked list starting - ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex - ** mutex. - */ - sqlite3_mutex_enter(pShmNode->mutex); - p->pNext = pShmNode->pFirst; - pShmNode->pFirst = p; - sqlite3_mutex_leave(pShmNode->mutex); - return SQLITE_OK; - - /* Jump here on any error */ -shm_open_err: - winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); - winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ - sqlite3_free(p); - sqlite3_free(pNew); - winShmLeaveMutex(); - return rc; -} - -/* -** Close a connection to shared-memory. Delete the underlying -** storage if deleteFlag is true. -*/ -static int winShmUnmap( - sqlite3_file *fd, /* Database holding shared memory */ - int deleteFlag /* Delete after closing if true */ -){ - winFile *pDbFd; /* Database holding shared-memory */ - winShm *p; /* The connection to be closed */ - winShmNode *pShmNode; /* The underlying shared-memory file */ - winShm **pp; /* For looping over sibling connections */ - - pDbFd = (winFile*)fd; - p = pDbFd->pShm; - if( p==0 ) return SQLITE_OK; - pShmNode = p->pShmNode; - - /* Remove connection p from the set of connections associated - ** with pShmNode */ - sqlite3_mutex_enter(pShmNode->mutex); - for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} - *pp = p->pNext; - - /* Free the connection p */ - sqlite3_free(p); - pDbFd->pShm = 0; - sqlite3_mutex_leave(pShmNode->mutex); - - /* If pShmNode->nRef has reached 0, then close the underlying - ** shared-memory file, too */ - winShmEnterMutex(); - assert( pShmNode->nRef>0 ); - pShmNode->nRef--; - if( pShmNode->nRef==0 ){ - winShmPurge(pDbFd->pVfs, deleteFlag); - } - winShmLeaveMutex(); - - return SQLITE_OK; -} - -/* -** Change the lock state for a shared-memory segment. -*/ -static int winShmLock( - sqlite3_file *fd, /* Database file holding the shared memory */ - int ofst, /* First lock to acquire or release */ - int n, /* Number of locks to acquire or release */ - int flags /* What to do with the lock */ -){ - winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ - winShm *p = pDbFd->pShm; /* The shared memory being locked */ - winShm *pX; /* For looping over all siblings */ - winShmNode *pShmNode = p->pShmNode; - int rc = SQLITE_OK; /* Result code */ - u16 mask; /* Mask of locks to take or release */ - - assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); - assert( n>=1 ); - assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); - assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - - mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); - if( flags & SQLITE_SHM_UNLOCK ){ - u16 allMask = 0; /* Mask of locks held by siblings */ - - /* See if any siblings hold this same lock */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( pX==p ) continue; - assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); - allMask |= pX->sharedMask; - } - - /* Unlock the system-level locks */ - if( (mask & allMask)==0 ){ - rc = winShmSystemLock(pShmNode, WINSHM_UNLCK, ofst+WIN_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - }else if( flags & SQLITE_SHM_SHARED ){ - u16 allShared = 0; /* Union of locks held by connections other than "p" */ - - /* Find out which shared locks are already held by sibling connections. - ** If any sibling already holds an exclusive lock, go ahead and return - ** SQLITE_BUSY. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - allShared |= pX->sharedMask; - } - - /* Get shared locks at the system level, if necessary */ - if( rc==SQLITE_OK ){ - if( (allShared & mask)==0 ){ - rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); - }else{ - rc = SQLITE_OK; - } - } - - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ - rc = SQLITE_BUSY; - break; - } - } - - /* Get the exclusive locks at the system level. Then if successful - ** also mark the local connection as being locked. - */ - if( rc==SQLITE_OK ){ - rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); - if( rc==SQLITE_OK ){ - assert( (p->sharedMask & mask)==0 ); - p->exclMask |= mask; - } - } - } - sqlite3_mutex_leave(pShmNode->mutex); - OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", - osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, - sqlite3ErrName(rc))); - return rc; -} - -/* -** Implement a memory barrier or memory fence on shared memory. -** -** All loads and stores begun before the barrier must complete before -** any load or store begun after the barrier. -*/ -static void winShmBarrier( - sqlite3_file *fd /* Database holding the shared memory */ -){ - UNUSED_PARAMETER(fd); - sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ - winShmEnterMutex(); /* Also mutex, for redundancy */ - winShmLeaveMutex(); -} - -/* -** This function is called to obtain a pointer to region iRegion of the -** shared-memory associated with the database file fd. Shared-memory regions -** are numbered starting from zero. Each shared-memory region is szRegion -** bytes in size. -** -** If an error occurs, an error code is returned and *pp is set to NULL. -** -** Otherwise, if the isWrite parameter is 0 and the requested shared-memory -** region has not been allocated (by any client, including one running in a -** separate process), then *pp is set to NULL and SQLITE_OK returned. If -** isWrite is non-zero and the requested shared-memory region has not yet -** been allocated, it is allocated by this function. -** -** If the shared-memory region has already been allocated or is allocated by -** this call as described above, then it is mapped into this processes -** address space (if it is not already), *pp is set to point to the mapped -** memory and SQLITE_OK returned. -*/ -static int winShmMap( - sqlite3_file *fd, /* Handle open on database file */ - int iRegion, /* Region to retrieve */ - int szRegion, /* Size of regions */ - int isWrite, /* True to extend file if necessary */ - void volatile **pp /* OUT: Mapped memory */ -){ - winFile *pDbFd = (winFile*)fd; - winShm *pShm = pDbFd->pShm; - winShmNode *pShmNode; - int rc = SQLITE_OK; - - if( !pShm ){ - rc = winOpenSharedMemory(pDbFd); - if( rc!=SQLITE_OK ) return rc; - pShm = pDbFd->pShm; - } - pShmNode = pShm->pShmNode; - - sqlite3_mutex_enter(pShmNode->mutex); - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - - if( pShmNode->nRegion<=iRegion ){ - struct ShmRegion *apNew; /* New aRegion[] array */ - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ - sqlite3_int64 sz; /* Current size of wal-index file */ - - pShmNode->szRegion = szRegion; - - /* The requested region is not mapped into this processes address space. - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ - rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); - if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), - "winShmMap1", pDbFd->zPath); - goto shmpage_out; - } - - if( szhFile, nByte); - if( rc!=SQLITE_OK ){ - rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), - "winShmMap2", pDbFd->zPath); - goto shmpage_out; - } - } - - /* Map the requested memory region into this processes address space. */ - apNew = (struct ShmRegion *)sqlite3_realloc64( - pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) - ); - if( !apNew ){ - rc = SQLITE_IOERR_NOMEM_BKPT; - goto shmpage_out; - } - pShmNode->aRegion = apNew; - - while( pShmNode->nRegion<=iRegion ){ - HANDLE hMap = NULL; /* file-mapping handle */ - void *pMap = 0; /* Mapped memory region */ - -#if SQLITE_OS_WINRT - hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, - NULL, PAGE_READWRITE, nByte, NULL - ); -#elif defined(SQLITE_WIN32_HAS_WIDE) - hMap = osCreateFileMappingW(pShmNode->hFile.h, - NULL, PAGE_READWRITE, 0, nByte, NULL - ); -#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - hMap = osCreateFileMappingA(pShmNode->hFile.h, - NULL, PAGE_READWRITE, 0, nByte, NULL - ); -#endif - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", - osGetCurrentProcessId(), pShmNode->nRegion, nByte, - hMap ? "ok" : "failed")); - if( hMap ){ - int iOffset = pShmNode->nRegion*szRegion; - int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; -#if SQLITE_OS_WINRT - pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ, - iOffset - iOffsetShift, szRegion + iOffsetShift - ); -#else - pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, - 0, iOffset - iOffsetShift, szRegion + iOffsetShift - ); -#endif - OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", - osGetCurrentProcessId(), pShmNode->nRegion, iOffset, - szRegion, pMap ? "ok" : "failed")); - } - if( !pMap ){ - pShmNode->lastErrno = osGetLastError(); - rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, - "winShmMap3", pDbFd->zPath); - if( hMap ) osCloseHandle(hMap); - goto shmpage_out; - } - - pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; - pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; - pShmNode->nRegion++; - } - } - -shmpage_out: - if( pShmNode->nRegion>iRegion ){ - int iOffset = iRegion*szRegion; - int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; - char *p = (char *)pShmNode->aRegion[iRegion].pMap; - *pp = (void *)&p[iOffsetShift]; - }else{ - *pp = 0; - } - sqlite3_mutex_leave(pShmNode->mutex); - return rc; -} - -#else -# define winShmMap 0 -# define winShmLock 0 -# define winShmBarrier 0 -# define winShmUnmap 0 -#endif /* #ifndef SQLITE_OMIT_WAL */ - -/* -** Cleans up the mapped region of the specified file, if any. -*/ -#if SQLITE_MAX_MMAP_SIZE>0 -static int winUnmapfile(winFile *pFile){ - assert( pFile!=0 ); - OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " - "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", - osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, - pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); - if( pFile->pMapRegion ){ - if( !osUnmapViewOfFile(pFile->pMapRegion) ){ - pFile->lastErrno = osGetLastError(); - OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " - "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, - pFile->pMapRegion)); - return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, - "winUnmapfile1", pFile->zPath); - } - pFile->pMapRegion = 0; - pFile->mmapSize = 0; - pFile->mmapSizeActual = 0; - } - if( pFile->hMap!=NULL ){ - if( !osCloseHandle(pFile->hMap) ){ - pFile->lastErrno = osGetLastError(); - OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", - osGetCurrentProcessId(), pFile, pFile->hMap)); - return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, - "winUnmapfile2", pFile->zPath); - } - pFile->hMap = NULL; - } - OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFile)); - return SQLITE_OK; -} - -/* -** Memory map or remap the file opened by file-descriptor pFd (if the file -** is already mapped, the existing mapping is replaced by the new). Or, if -** there already exists a mapping for this file, and there are still -** outstanding xFetch() references to it, this function is a no-op. -** -** If parameter nByte is non-negative, then it is the requested size of -** the mapping to create. Otherwise, if nByte is less than zero, then the -** requested size is the size of the file on disk. The actual size of the -** created mapping is either the requested size or the value configured -** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. -** -** SQLITE_OK is returned if no error occurs (even if the mapping is not -** recreated as a result of outstanding references) or an SQLite error -** code otherwise. -*/ -static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ - sqlite3_int64 nMap = nByte; - int rc; - - assert( nMap>=0 || pFd->nFetchOut==0 ); - OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", - osGetCurrentProcessId(), pFd, nByte)); - - if( pFd->nFetchOut>0 ) return SQLITE_OK; - - if( nMap<0 ){ - rc = winFileSize((sqlite3_file*)pFd, &nMap); - if( rc ){ - OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", - osGetCurrentProcessId(), pFd)); - return SQLITE_IOERR_FSTAT; - } - } - if( nMap>pFd->mmapSizeMax ){ - nMap = pFd->mmapSizeMax; - } - nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); - - if( nMap==0 && pFd->mmapSize>0 ){ - winUnmapfile(pFd); - } - if( nMap!=pFd->mmapSize ){ - void *pNew = 0; - DWORD protect = PAGE_READONLY; - DWORD flags = FILE_MAP_READ; - - winUnmapfile(pFd); -#ifdef SQLITE_MMAP_READWRITE - if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ - protect = PAGE_READWRITE; - flags |= FILE_MAP_WRITE; - } -#endif -#if SQLITE_OS_WINRT - pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); -#elif defined(SQLITE_WIN32_HAS_WIDE) - pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, - (DWORD)((nMap>>32) & 0xffffffff), - (DWORD)(nMap & 0xffffffff), NULL); -#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, - (DWORD)((nMap>>32) & 0xffffffff), - (DWORD)(nMap & 0xffffffff), NULL); -#endif - if( pFd->hMap==NULL ){ - pFd->lastErrno = osGetLastError(); - rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, - "winMapfile1", pFd->zPath); - /* Log the error, but continue normal operation using xRead/xWrite */ - OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); - return SQLITE_OK; - } - assert( (nMap % winSysInfo.dwPageSize)==0 ); - assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); -#if SQLITE_OS_WINRT - pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); -#else - pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); -#endif - if( pNew==NULL ){ - osCloseHandle(pFd->hMap); - pFd->hMap = NULL; - pFd->lastErrno = osGetLastError(); - rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, - "winMapfile2", pFd->zPath); - /* Log the error, but continue normal operation using xRead/xWrite */ - OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); - return SQLITE_OK; - } - pFd->pMapRegion = pNew; - pFd->mmapSize = nMap; - pFd->mmapSizeActual = nMap; - } - - OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), pFd)); - return SQLITE_OK; -} -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ - -/* -** If possible, return a pointer to a mapping of file fd starting at offset -** iOff. The mapping must be valid for at least nAmt bytes. -** -** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. -** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. -** Finally, if an error does occur, return an SQLite error code. The final -** value of *pp is undefined in this case. -** -** If this function does return a pointer, the caller must eventually -** release the reference by calling winUnfetch(). -*/ -static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ -#if SQLITE_MAX_MMAP_SIZE>0 - winFile *pFd = (winFile*)fd; /* The underlying database file */ -#endif - *pp = 0; - - OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", - osGetCurrentProcessId(), fd, iOff, nAmt, pp)); - -#if SQLITE_MAX_MMAP_SIZE>0 - if( pFd->mmapSizeMax>0 ){ - if( pFd->pMapRegion==0 ){ - int rc = winMapfile(pFd, -1); - if( rc!=SQLITE_OK ){ - OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); - return rc; - } - } - if( pFd->mmapSize >= iOff+nAmt ){ - *pp = &((u8 *)pFd->pMapRegion)[iOff]; - pFd->nFetchOut++; - } - } -#endif - - OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), fd, pp, *pp)); - return SQLITE_OK; -} - -/* -** If the third argument is non-NULL, then this function releases a -** reference obtained by an earlier call to winFetch(). The second -** argument passed to this function must be the same as the corresponding -** argument that was passed to the winFetch() invocation. -** -** Or, if the third argument is NULL, then this function is being called -** to inform the VFS layer that, according to POSIX, any existing mapping -** may now be invalid and should be unmapped. -*/ -static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ -#if SQLITE_MAX_MMAP_SIZE>0 - winFile *pFd = (winFile*)fd; /* The underlying database file */ - - /* If p==0 (unmap the entire file) then there must be no outstanding - ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), - ** then there must be at least one outstanding. */ - assert( (p==0)==(pFd->nFetchOut==0) ); - - /* If p!=0, it must match the iOff value. */ - assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); - - OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", - osGetCurrentProcessId(), pFd, iOff, p)); - - if( p ){ - pFd->nFetchOut--; - }else{ - /* FIXME: If Windows truly always prevents truncating or deleting a - ** file while a mapping is held, then the following winUnmapfile() call - ** is unnecessary can be omitted - potentially improving - ** performance. */ - winUnmapfile(pFd); - } - - assert( pFd->nFetchOut>=0 ); -#endif - - OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", - osGetCurrentProcessId(), fd)); - return SQLITE_OK; -} - -/* -** Here ends the implementation of all sqlite3_file methods. -** -********************** End sqlite3_file Methods ******************************* -******************************************************************************/ - -/* -** This vector defines all the methods that can operate on an -** sqlite3_file for win32. -*/ -static const sqlite3_io_methods winIoMethod = { - 3, /* iVersion */ - winClose, /* xClose */ - winRead, /* xRead */ - winWrite, /* xWrite */ - winTruncate, /* xTruncate */ - winSync, /* xSync */ - winFileSize, /* xFileSize */ - winLock, /* xLock */ - winUnlock, /* xUnlock */ - winCheckReservedLock, /* xCheckReservedLock */ - winFileControl, /* xFileControl */ - winSectorSize, /* xSectorSize */ - winDeviceCharacteristics, /* xDeviceCharacteristics */ - winShmMap, /* xShmMap */ - winShmLock, /* xShmLock */ - winShmBarrier, /* xShmBarrier */ - winShmUnmap, /* xShmUnmap */ - winFetch, /* xFetch */ - winUnfetch /* xUnfetch */ -}; - -/* -** This vector defines all the methods that can operate on an -** sqlite3_file for win32 without performing any locking. -*/ -static const sqlite3_io_methods winIoNolockMethod = { - 3, /* iVersion */ - winClose, /* xClose */ - winRead, /* xRead */ - winWrite, /* xWrite */ - winTruncate, /* xTruncate */ - winSync, /* xSync */ - winFileSize, /* xFileSize */ - winNolockLock, /* xLock */ - winNolockUnlock, /* xUnlock */ - winNolockCheckReservedLock, /* xCheckReservedLock */ - winFileControl, /* xFileControl */ - winSectorSize, /* xSectorSize */ - winDeviceCharacteristics, /* xDeviceCharacteristics */ - winShmMap, /* xShmMap */ - winShmLock, /* xShmLock */ - winShmBarrier, /* xShmBarrier */ - winShmUnmap, /* xShmUnmap */ - winFetch, /* xFetch */ - winUnfetch /* xUnfetch */ -}; - -static winVfsAppData winAppData = { - &winIoMethod, /* pMethod */ - 0, /* pAppData */ - 0 /* bNoLock */ -}; - -static winVfsAppData winNolockAppData = { - &winIoNolockMethod, /* pMethod */ - 0, /* pAppData */ - 1 /* bNoLock */ -}; - -/**************************************************************************** -**************************** sqlite3_vfs methods **************************** -** -** This division contains the implementation of methods on the -** sqlite3_vfs object. -*/ - -#if defined(__CYGWIN__) -/* -** Convert a filename from whatever the underlying operating system -** supports for filenames into UTF-8. Space to hold the result is -** obtained from malloc and must be freed by the calling function. -*/ -static char *winConvertToUtf8Filename(const void *zFilename){ - char *zConverted = 0; - if( osIsNT() ){ - zConverted = winUnicodeToUtf8(zFilename); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); - } -#endif - /* caller will handle out of memory */ - return zConverted; -} -#endif - -/* -** Convert a UTF-8 filename into whatever form the underlying -** operating system wants filenames in. Space to hold the result -** is obtained from malloc and must be freed by the calling -** function. -*/ -static void *winConvertFromUtf8Filename(const char *zFilename){ - void *zConverted = 0; - if( osIsNT() ){ - zConverted = winUtf8ToUnicode(zFilename); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); - } -#endif - /* caller will handle out of memory */ - return zConverted; -} - -/* -** This function returns non-zero if the specified UTF-8 string buffer -** ends with a directory separator character or one was successfully -** added to it. -*/ -static int winMakeEndInDirSep(int nBuf, char *zBuf){ - if( zBuf ){ - int nLen = sqlite3Strlen30(zBuf); - if( nLen>0 ){ - if( winIsDirSep(zBuf[nLen-1]) ){ - return 1; - }else if( nLen+1mxPathname; nBuf = nMax + 2; - zBuf = sqlite3MallocZero( nBuf ); - if( !zBuf ){ - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); - return SQLITE_IOERR_NOMEM_BKPT; - } - - /* Figure out the effective temporary directory. First, check if one - ** has been explicitly set by the application; otherwise, use the one - ** configured by the operating system. - */ - nDir = nMax - (nPre + 15); - assert( nDir>0 ); - if( sqlite3_temp_directory ){ - int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); - if( nDirLen>0 ){ - if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ - nDirLen++; - } - if( nDirLen>nDir ){ - sqlite3_free(zBuf); - OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); - return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); - } - sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); - } - } -#if defined(__CYGWIN__) - else{ - static const char *azDirs[] = { - 0, /* getenv("SQLITE_TMPDIR") */ - 0, /* getenv("TMPDIR") */ - 0, /* getenv("TMP") */ - 0, /* getenv("TEMP") */ - 0, /* getenv("USERPROFILE") */ - "/var/tmp", - "/usr/tmp", - "/tmp", - ".", - 0 /* List terminator */ - }; - unsigned int i; - const char *zDir = 0; - - if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); - if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); - if( !azDirs[2] ) azDirs[2] = getenv("TMP"); - if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); - if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); - for(i=0; i/etilqs_XXXXXXXXXXXXXXX\0\0" - ** - ** If not, return SQLITE_ERROR. The number 17 is used here in order to - ** account for the space used by the 15 character random suffix and the - ** two trailing NUL characters. The final directory separator character - ** has already added if it was not already present. - */ - nLen = sqlite3Strlen30(zBuf); - if( (nLen + nPre + 17) > nBuf ){ - sqlite3_free(zBuf); - OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); - return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); - } - - sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); - - j = sqlite3Strlen30(zBuf); - sqlite3_randomness(15, &zBuf[j]); - for(i=0; i<15; i++, j++){ - zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; - } - zBuf[j] = 0; - zBuf[j+1] = 0; - *pzBuf = zBuf; - - OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); - return SQLITE_OK; -} - -/* -** Return TRUE if the named file is really a directory. Return false if -** it is something other than a directory, or if there is any kind of memory -** allocation failure. -*/ -static int winIsDir(const void *zConverted){ - DWORD attr; - int rc = 0; - DWORD lastErrno; - - if( osIsNT() ){ - int cnt = 0; - WIN32_FILE_ATTRIBUTE_DATA sAttrData; - memset(&sAttrData, 0, sizeof(sAttrData)); - while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, - GetFileExInfoStandard, - &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} - if( !rc ){ - return 0; /* Invalid name? */ - } - attr = sAttrData.dwFileAttributes; -#if SQLITE_OS_WINCE==0 - }else{ - attr = osGetFileAttributesA((char*)zConverted); -#endif - } - return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); -} - -/* -** Open a file. -*/ -static int winOpen( - sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ - const char *zName, /* Name of the file (UTF-8) */ - sqlite3_file *id, /* Write the SQLite file handle here */ - int flags, /* Open mode flags */ - int *pOutFlags /* Status return flags */ -){ - HANDLE h; - DWORD lastErrno = 0; - DWORD dwDesiredAccess; - DWORD dwShareMode; - DWORD dwCreationDisposition; - DWORD dwFlagsAndAttributes = 0; -#if SQLITE_OS_WINCE - int isTemp = 0; -#endif - winVfsAppData *pAppData; - winFile *pFile = (winFile*)id; - void *zConverted; /* Filename in OS encoding */ - const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ - int cnt = 0; - - /* If argument zPath is a NULL pointer, this function is required to open - ** a temporary file. Use this buffer to store the file name in. - */ - char *zTmpname = 0; /* For temporary filename, if necessary. */ - - int rc = SQLITE_OK; /* Function Return Code */ -#if !defined(NDEBUG) || SQLITE_OS_WINCE - int eType = flags&0xFFFFFF00; /* Type of file to open */ -#endif - - int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); - int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); - int isCreate = (flags & SQLITE_OPEN_CREATE); - int isReadonly = (flags & SQLITE_OPEN_READONLY); - int isReadWrite = (flags & SQLITE_OPEN_READWRITE); - -#ifndef NDEBUG - int isOpenJournal = (isCreate && ( - eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_MAIN_JOURNAL - || eType==SQLITE_OPEN_WAL - )); -#endif - - OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", - zUtf8Name, id, flags, pOutFlags)); - - /* Check the following statements are true: - ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and - ** (b) if CREATE is set, then READWRITE must also be set, and - ** (c) if EXCLUSIVE is set, then CREATE must also be set. - ** (d) if DELETEONCLOSE is set, then CREATE must also be set. - */ - assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); - assert(isCreate==0 || isReadWrite); - assert(isExclusive==0 || isCreate); - assert(isDelete==0 || isCreate); - - /* The main DB, main journal, WAL file and master journal are never - ** automatically deleted. Nor are they ever temporary files. */ - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); - assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); - - /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL - || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL - ); - - assert( pFile!=0 ); - memset(pFile, 0, sizeof(winFile)); - pFile->h = INVALID_HANDLE_VALUE; - -#if SQLITE_OS_WINRT - if( !zUtf8Name && !sqlite3_temp_directory ){ - sqlite3_log(SQLITE_ERROR, - "sqlite3_temp_directory variable should be set for WinRT"); - } -#endif - - /* If the second argument to this function is NULL, generate a - ** temporary file name to use - */ - if( !zUtf8Name ){ - assert( isDelete && !isOpenJournal ); - rc = winGetTempname(pVfs, &zTmpname); - if( rc!=SQLITE_OK ){ - OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); - return rc; - } - zUtf8Name = zTmpname; - } - - /* Database filenames are double-zero terminated if they are not - ** URIs with parameters. Hence, they can always be passed into - ** sqlite3_uri_parameter(). - */ - assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || - zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); - - /* Convert the filename to the system encoding. */ - zConverted = winConvertFromUtf8Filename(zUtf8Name); - if( zConverted==0 ){ - sqlite3_free(zTmpname); - OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); - return SQLITE_IOERR_NOMEM_BKPT; - } - - if( winIsDir(zConverted) ){ - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); - return SQLITE_CANTOPEN_ISDIR; - } - - if( isReadWrite ){ - dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; - }else{ - dwDesiredAccess = GENERIC_READ; - } - - /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is - ** created. SQLite doesn't use it to indicate "exclusive access" - ** as it is usually understood. - */ - if( isExclusive ){ - /* Creates a new file, only if it does not already exist. */ - /* If the file exists, it fails. */ - dwCreationDisposition = CREATE_NEW; - }else if( isCreate ){ - /* Open existing file, or create if it doesn't exist */ - dwCreationDisposition = OPEN_ALWAYS; - }else{ - /* Opens a file, only if it exists. */ - dwCreationDisposition = OPEN_EXISTING; - } - - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - - if( isDelete ){ -#if SQLITE_OS_WINCE - dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; - isTemp = 1; -#else - dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY - | FILE_ATTRIBUTE_HIDDEN - | FILE_FLAG_DELETE_ON_CLOSE; -#endif - }else{ - dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; - } - /* Reports from the internet are that performance is always - ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ -#if SQLITE_OS_WINCE - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; -#endif - - if( osIsNT() ){ -#if SQLITE_OS_WINRT - CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; - extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); - extendedParameters.dwFileAttributes = - dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; - extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; - extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extendedParameters.lpSecurityAttributes = NULL; - extendedParameters.hTemplateFile = NULL; - while( (h = osCreateFile2((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, - dwCreationDisposition, - &extendedParameters))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } -#else - while( (h = osCreateFileW((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - while( (h = osCreateFileA((LPCSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL))==INVALID_HANDLE_VALUE && - winRetryIoerr(&cnt, &lastErrno) ){ - /* Noop */ - } - } -#endif - winLogIoerr(cnt, __LINE__); - - OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, - dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); - - if( h==INVALID_HANDLE_VALUE ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - if( isReadWrite && !isExclusive ){ - return winOpen(pVfs, zName, id, - ((flags|SQLITE_OPEN_READONLY) & - ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), - pOutFlags); - }else{ - return SQLITE_CANTOPEN_BKPT; - } - } - - if( pOutFlags ){ - if( isReadWrite ){ - *pOutFlags = SQLITE_OPEN_READWRITE; - }else{ - *pOutFlags = SQLITE_OPEN_READONLY; - } - } - - OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " - "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? - *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); - - pAppData = (winVfsAppData*)pVfs->pAppData; - -#if SQLITE_OS_WINCE - { - if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB - && ((pAppData==NULL) || !pAppData->bNoLock) - && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK - ){ - osCloseHandle(h); - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); - return rc; - } - } - if( isTemp ){ - pFile->zDeleteOnClose = zConverted; - }else -#endif - { - sqlite3_free(zConverted); - } - - sqlite3_free(zTmpname); - pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; - pFile->pVfs = pVfs; - pFile->h = h; - if( isReadonly ){ - pFile->ctrlFlags |= WINFILE_RDONLY; - } - if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ - pFile->ctrlFlags |= WINFILE_PSOW; - } - pFile->lastErrno = NO_ERROR; - pFile->zPath = zName; -#if SQLITE_MAX_MMAP_SIZE>0 - pFile->hMap = NULL; - pFile->pMapRegion = 0; - pFile->mmapSize = 0; - pFile->mmapSizeActual = 0; - pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; -#endif - - OpenCounter(+1); - return rc; -} - -/* -** Delete the named file. -** -** Note that Windows does not allow a file to be deleted if some other -** process has it open. Sometimes a virus scanner or indexing program -** will open a journal file shortly after it is created in order to do -** whatever it does. While this other process is holding the -** file open, we will be unable to delete it. To work around this -** problem, we delay 100 milliseconds and try to delete again. Up -** to MX_DELETION_ATTEMPTs deletion attempts are run before giving -** up and returning an error. -*/ -static int winDelete( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to delete */ - int syncDir /* Not used on win32 */ -){ - int cnt = 0; - int rc; - DWORD attr; - DWORD lastErrno = 0; - void *zConverted; - UNUSED_PARAMETER(pVfs); - UNUSED_PARAMETER(syncDir); - - SimulateIOError(return SQLITE_IOERR_DELETE); - OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); - - zConverted = winConvertFromUtf8Filename(zFilename); - if( zConverted==0 ){ - OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); - return SQLITE_IOERR_NOMEM_BKPT; - } - if( osIsNT() ){ - do { -#if SQLITE_OS_WINRT - WIN32_FILE_ATTRIBUTE_DATA sAttrData; - memset(&sAttrData, 0, sizeof(sAttrData)); - if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, - &sAttrData) ){ - attr = sAttrData.dwFileAttributes; - }else{ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } -#else - attr = osGetFileAttributesW(zConverted); -#endif - if ( attr==INVALID_FILE_ATTRIBUTES ){ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } - if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ - rc = SQLITE_ERROR; /* Files only. */ - break; - } - if ( osDeleteFileW(zConverted) ){ - rc = SQLITE_OK; /* Deleted OK. */ - break; - } - if ( !winRetryIoerr(&cnt, &lastErrno) ){ - rc = SQLITE_ERROR; /* No more retries. */ - break; - } - } while(1); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - do { - attr = osGetFileAttributesA(zConverted); - if ( attr==INVALID_FILE_ATTRIBUTES ){ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } - if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ - rc = SQLITE_ERROR; /* Files only. */ - break; - } - if ( osDeleteFileA(zConverted) ){ - rc = SQLITE_OK; /* Deleted OK. */ - break; - } - if ( !winRetryIoerr(&cnt, &lastErrno) ){ - rc = SQLITE_ERROR; /* No more retries. */ - break; - } - } while(1); - } -#endif - if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ - rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); - }else{ - winLogIoerr(cnt, __LINE__); - } - sqlite3_free(zConverted); - OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); - return rc; -} - -/* -** Check the existence and status of a file. -*/ -static int winAccess( - sqlite3_vfs *pVfs, /* Not used on win32 */ - const char *zFilename, /* Name of file to check */ - int flags, /* Type of test to make on this file */ - int *pResOut /* OUT: Result */ -){ - DWORD attr; - int rc = 0; - DWORD lastErrno = 0; - void *zConverted; - UNUSED_PARAMETER(pVfs); - - SimulateIOError( return SQLITE_IOERR_ACCESS; ); - OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", - zFilename, flags, pResOut)); - - zConverted = winConvertFromUtf8Filename(zFilename); - if( zConverted==0 ){ - OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); - return SQLITE_IOERR_NOMEM_BKPT; - } - if( osIsNT() ){ - int cnt = 0; - WIN32_FILE_ATTRIBUTE_DATA sAttrData; - memset(&sAttrData, 0, sizeof(sAttrData)); - while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, - GetFileExInfoStandard, - &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} - if( rc ){ - /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file - ** as if it does not exist. - */ - if( flags==SQLITE_ACCESS_EXISTS - && sAttrData.nFileSizeHigh==0 - && sAttrData.nFileSizeLow==0 ){ - attr = INVALID_FILE_ATTRIBUTES; - }else{ - attr = sAttrData.dwFileAttributes; - } - }else{ - winLogIoerr(cnt, __LINE__); - if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ - sqlite3_free(zConverted); - return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", - zFilename); - }else{ - attr = INVALID_FILE_ATTRIBUTES; - } - } - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - attr = osGetFileAttributesA((char*)zConverted); - } -#endif - sqlite3_free(zConverted); - switch( flags ){ - case SQLITE_ACCESS_READ: - case SQLITE_ACCESS_EXISTS: - rc = attr!=INVALID_FILE_ATTRIBUTES; - break; - case SQLITE_ACCESS_READWRITE: - rc = attr!=INVALID_FILE_ATTRIBUTES && - (attr & FILE_ATTRIBUTE_READONLY)==0; - break; - default: - assert(!"Invalid flags argument"); - } - *pResOut = rc; - OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", - zFilename, pResOut, *pResOut)); - return SQLITE_OK; -} - -/* -** Returns non-zero if the specified path name starts with a drive letter -** followed by a colon character. -*/ -static BOOL winIsDriveLetterAndColon( - const char *zPathname -){ - return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); -} - -/* -** Returns non-zero if the specified path name should be used verbatim. If -** non-zero is returned from this function, the calling function must simply -** use the provided path name verbatim -OR- resolve it into a full path name -** using the GetFullPathName Win32 API function (if available). -*/ -static BOOL winIsVerbatimPathname( - const char *zPathname -){ - /* - ** If the path name starts with a forward slash or a backslash, it is either - ** a legal UNC name, a volume relative path, or an absolute path name in the - ** "Unix" format on Windows. There is no easy way to differentiate between - ** the final two cases; therefore, we return the safer return value of TRUE - ** so that callers of this function will simply use it verbatim. - */ - if ( winIsDirSep(zPathname[0]) ){ - return TRUE; - } - - /* - ** If the path name starts with a letter and a colon it is either a volume - ** relative path or an absolute path. Callers of this function must not - ** attempt to treat it as a relative path name (i.e. they should simply use - ** it verbatim). - */ - if ( winIsDriveLetterAndColon(zPathname) ){ - return TRUE; - } - - /* - ** If we get to this point, the path name should almost certainly be a purely - ** relative one (i.e. not a UNC name, not absolute, and not volume relative). - */ - return FALSE; -} - -/* -** Turn a relative pathname into a full pathname. Write the full -** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname -** bytes in size. -*/ -static int winFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zRelative, /* Possibly relative input path */ - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ -){ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) - DWORD nByte; - void *zConverted; - char *zOut; -#endif - - /* If this path name begins with "/X:", where "X" is any alphabetic - ** character, discard the initial "/" from the pathname. - */ - if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ - zRelative++; - } - -#if defined(__CYGWIN__) - SimulateIOError( return SQLITE_ERROR ); - UNUSED_PARAMETER(nFull); - assert( nFull>=pVfs->mxPathname ); - if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ - /* - ** NOTE: We are dealing with a relative path name and the data - ** directory has been set. Therefore, use it as the basis - ** for converting the relative path name to an absolute - ** one by prepending the data directory and a slash. - */ - char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); - if( !zOut ){ - return SQLITE_IOERR_NOMEM_BKPT; - } - if( cygwin_conv_path( - (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | - CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ - sqlite3_free(zOut); - return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, - "winFullPathname1", zRelative); - }else{ - char *zUtf8 = winConvertToUtf8Filename(zOut); - if( !zUtf8 ){ - sqlite3_free(zOut); - return SQLITE_IOERR_NOMEM_BKPT; - } - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - sqlite3_data_directory, winGetDirSep(), zUtf8); - sqlite3_free(zUtf8); - sqlite3_free(zOut); - } - }else{ - char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); - if( !zOut ){ - return SQLITE_IOERR_NOMEM_BKPT; - } - if( cygwin_conv_path( - (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), - zRelative, zOut, pVfs->mxPathname+1)<0 ){ - sqlite3_free(zOut); - return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, - "winFullPathname2", zRelative); - }else{ - char *zUtf8 = winConvertToUtf8Filename(zOut); - if( !zUtf8 ){ - sqlite3_free(zOut); - return SQLITE_IOERR_NOMEM_BKPT; - } - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); - sqlite3_free(zUtf8); - sqlite3_free(zOut); - } - } - return SQLITE_OK; -#endif - -#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) - SimulateIOError( return SQLITE_ERROR ); - /* WinCE has no concept of a relative pathname, or so I am told. */ - /* WinRT has no way to convert a relative path to an absolute one. */ - if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ - /* - ** NOTE: We are dealing with a relative path name and the data - ** directory has been set. Therefore, use it as the basis - ** for converting the relative path name to an absolute - ** one by prepending the data directory and a backslash. - */ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - sqlite3_data_directory, winGetDirSep(), zRelative); - }else{ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); - } - return SQLITE_OK; -#endif - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. This function could fail if, for example, the - ** current working directory has been unlinked. - */ - SimulateIOError( return SQLITE_ERROR ); - if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ - /* - ** NOTE: We are dealing with a relative path name and the data - ** directory has been set. Therefore, use it as the basis - ** for converting the relative path name to an absolute - ** one by prepending the data directory and a backslash. - */ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - sqlite3_data_directory, winGetDirSep(), zRelative); - return SQLITE_OK; - } - zConverted = winConvertFromUtf8Filename(zRelative); - if( zConverted==0 ){ - return SQLITE_IOERR_NOMEM_BKPT; - } - if( osIsNT() ){ - LPWSTR zTemp; - nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname1", zRelative); - } - nByte += 3; - zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ){ - sqlite3_free(zConverted); - return SQLITE_IOERR_NOMEM_BKPT; - } - nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - sqlite3_free(zTemp); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname2", zRelative); - } - sqlite3_free(zConverted); - zOut = winUnicodeToUtf8(zTemp); - sqlite3_free(zTemp); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - char *zTemp; - nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname3", zRelative); - } - nByte += 3; - zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); - if( zTemp==0 ){ - sqlite3_free(zConverted); - return SQLITE_IOERR_NOMEM_BKPT; - } - nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - sqlite3_free(zTemp); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname4", zRelative); - } - sqlite3_free(zConverted); - zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - sqlite3_free(zTemp); - } -#endif - if( zOut ){ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); - sqlite3_free(zOut); - return SQLITE_OK; - }else{ - return SQLITE_IOERR_NOMEM_BKPT; - } -#endif -} - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Interfaces for opening a shared library, finding entry points -** within the shared library, and closing the shared library. -*/ -static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - HANDLE h; -#if defined(__CYGWIN__) - int nFull = pVfs->mxPathname+1; - char *zFull = sqlite3MallocZero( nFull ); - void *zConverted = 0; - if( zFull==0 ){ - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); - return 0; - } - if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ - sqlite3_free(zFull); - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); - return 0; - } - zConverted = winConvertFromUtf8Filename(zFull); - sqlite3_free(zFull); -#else - void *zConverted = winConvertFromUtf8Filename(zFilename); - UNUSED_PARAMETER(pVfs); -#endif - if( zConverted==0 ){ - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); - return 0; - } - if( osIsNT() ){ -#if SQLITE_OS_WINRT - h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); -#else - h = osLoadLibraryW((LPCWSTR)zConverted); -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - h = osLoadLibraryA((char*)zConverted); - } -#endif - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); - sqlite3_free(zConverted); - return (void*)h; -} -static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ - UNUSED_PARAMETER(pVfs); - winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); -} -static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ - FARPROC proc; - UNUSED_PARAMETER(pVfs); - proc = osGetProcAddressA((HANDLE)pH, zSym); - OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", - (void*)pH, zSym, (void*)proc)); - return (void(*)(void))proc; -} -static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ - UNUSED_PARAMETER(pVfs); - osFreeLibrary((HANDLE)pHandle); - OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); -} -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ - #define winDlOpen 0 - #define winDlError 0 - #define winDlSym 0 - #define winDlClose 0 -#endif - -/* State information for the randomness gatherer. */ -typedef struct EntropyGatherer EntropyGatherer; -struct EntropyGatherer { - unsigned char *a; /* Gather entropy into this buffer */ - int na; /* Size of a[] in bytes */ - int i; /* XOR next input into a[i] */ - int nXor; /* Number of XOR operations done */ -}; - -#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) -/* Mix sz bytes of entropy into p. */ -static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ - int j, k; - for(j=0, k=p->i; ja[k++] ^= x[j]; - if( k>=p->na ) k = 0; - } - p->i = k; - p->nXor += sz; -} -#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ - -/* -** Write up to nBuf bytes of randomness into zBuf. -*/ -static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ -#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) - UNUSED_PARAMETER(pVfs); - memset(zBuf, 0, nBuf); - return nBuf; -#else - EntropyGatherer e; - UNUSED_PARAMETER(pVfs); - memset(zBuf, 0, nBuf); -#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE - rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */ -#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */ - e.a = (unsigned char*)zBuf; - e.na = nBuf; - e.nXor = 0; - e.i = 0; - { - SYSTEMTIME x; - osGetSystemTime(&x); - xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); - } - { - DWORD pid = osGetCurrentProcessId(); - xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); - } -#if SQLITE_OS_WINRT - { - ULONGLONG cnt = osGetTickCount64(); - xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); - } -#else - { - DWORD cnt = osGetTickCount(); - xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); - } -#endif /* SQLITE_OS_WINRT */ - { - LARGE_INTEGER i; - osQueryPerformanceCounter(&i); - xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); - } -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID - { - UUID id; - memset(&id, 0, sizeof(UUID)); - osUuidCreate(&id); - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); - memset(&id, 0, sizeof(UUID)); - osUuidCreateSequential(&id); - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); - } -#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ - return e.nXor>nBuf ? nBuf : e.nXor; -#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ -} - - -/* -** Sleep for a little while. Return the amount of time slept. -*/ -static int winSleep(sqlite3_vfs *pVfs, int microsec){ - sqlite3_win32_sleep((microsec+999)/1000); - UNUSED_PARAMETER(pVfs); - return ((microsec+999)/1000)*1000; -} - -/* -** The following variable, if set to a non-zero value, is interpreted as -** the number of seconds since 1970 and is used to set the result of -** sqlite3OsCurrentTime() during testing. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ -#endif - -/* -** Find the current time (in Universal Coordinated Time). Write into *piNow -** the current time and date as a Julian Day number times 86_400_000. In -** other words, write into *piNow the number of milliseconds since the Julian -** epoch of noon in Greenwich on November 24, 4714 B.C according to the -** proleptic Gregorian calendar. -** -** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date -** cannot be found. -*/ -static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ - /* FILETIME structure is a 64-bit value representing the number of - 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). - */ - FILETIME ft; - static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; -#ifdef SQLITE_TEST - static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; -#endif - /* 2^32 - to avoid use of LL and warnings in gcc */ - static const sqlite3_int64 max32BitValue = - (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + - (sqlite3_int64)294967296; - -#if SQLITE_OS_WINCE - SYSTEMTIME time; - osGetSystemTime(&time); - /* if SystemTimeToFileTime() fails, it returns zero. */ - if (!osSystemTimeToFileTime(&time,&ft)){ - return SQLITE_ERROR; - } -#else - osGetSystemTimeAsFileTime( &ft ); -#endif - - *piNow = winFiletimeEpoch + - ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + - (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; - -#ifdef SQLITE_TEST - if( sqlite3_current_time ){ - *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; - } -#endif - UNUSED_PARAMETER(pVfs); - return SQLITE_OK; -} - -/* -** Find the current time (in Universal Coordinated Time). Write the -** current time and date as a Julian Day number into *prNow and -** return 0. Return 1 if the time and date cannot be found. -*/ -static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ - int rc; - sqlite3_int64 i; - rc = winCurrentTimeInt64(pVfs, &i); - if( !rc ){ - *prNow = i/86400000.0; - } - return rc; -} - -/* -** The idea is that this function works like a combination of -** GetLastError() and FormatMessage() on Windows (or errno and -** strerror_r() on Unix). After an error is returned by an OS -** function, SQLite calls this function with zBuf pointing to -** a buffer of nBuf bytes. The OS layer should populate the -** buffer with a nul-terminated UTF-8 encoded error message -** describing the last IO error to have occurred within the calling -** thread. -** -** If the error message is too large for the supplied buffer, -** it should be truncated. The return value of xGetLastError -** is zero if the error message fits in the buffer, or non-zero -** otherwise (if the message was truncated). If non-zero is returned, -** then it is not necessary to include the nul-terminator character -** in the output buffer. -** -** Not supplying an error message will have no adverse effect -** on SQLite. It is fine to have an implementation that never -** returns an error message: -** -** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ -** assert(zBuf[0]=='\0'); -** return 0; -** } -** -** However if an error message is supplied, it will be incorporated -** by sqlite into the error message available to the user using -** sqlite3_errmsg(), possibly making IO errors easier to debug. -*/ -static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ - DWORD e = osGetLastError(); - UNUSED_PARAMETER(pVfs); - if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); - return e; -} - -/* -** Initialize and deinitialize the operating system interface. -*/ -SQLITE_API int sqlite3_os_init(void){ - static sqlite3_vfs winVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ - SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32", /* zName */ - &winAppData, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ - }; -#if defined(SQLITE_WIN32_HAS_WIDE) - static sqlite3_vfs winLongPathVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ - SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32-longpath", /* zName */ - &winAppData, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ - }; -#endif - static sqlite3_vfs winNolockVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ - SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32-none", /* zName */ - &winNolockAppData, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ - }; -#if defined(SQLITE_WIN32_HAS_WIDE) - static sqlite3_vfs winLongPathNolockVfs = { - 3, /* iVersion */ - sizeof(winFile), /* szOsFile */ - SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ - 0, /* pNext */ - "win32-longpath-none", /* zName */ - &winNolockAppData, /* pAppData */ - winOpen, /* xOpen */ - winDelete, /* xDelete */ - winAccess, /* xAccess */ - winFullPathname, /* xFullPathname */ - winDlOpen, /* xDlOpen */ - winDlError, /* xDlError */ - winDlSym, /* xDlSym */ - winDlClose, /* xDlClose */ - winRandomness, /* xRandomness */ - winSleep, /* xSleep */ - winCurrentTime, /* xCurrentTime */ - winGetLastError, /* xGetLastError */ - winCurrentTimeInt64, /* xCurrentTimeInt64 */ - winSetSystemCall, /* xSetSystemCall */ - winGetSystemCall, /* xGetSystemCall */ - winNextSystemCall, /* xNextSystemCall */ - }; -#endif - - /* Double-check that the aSyscall[] array has been constructed - ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==80 ); - - /* get memory map allocation granularity */ - memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); -#if SQLITE_OS_WINRT - osGetNativeSystemInfo(&winSysInfo); -#else - osGetSystemInfo(&winSysInfo); -#endif - assert( winSysInfo.dwAllocationGranularity>0 ); - assert( winSysInfo.dwPageSize>0 ); - - sqlite3_vfs_register(&winVfs, 1); - -#if defined(SQLITE_WIN32_HAS_WIDE) - sqlite3_vfs_register(&winLongPathVfs, 0); -#endif - - sqlite3_vfs_register(&winNolockVfs, 0); - -#if defined(SQLITE_WIN32_HAS_WIDE) - sqlite3_vfs_register(&winLongPathNolockVfs, 0); -#endif - - return SQLITE_OK; -} - -SQLITE_API int sqlite3_os_end(void){ -#if SQLITE_OS_WINRT - if( sleepObj!=NULL ){ - osCloseHandle(sleepObj); - sleepObj = NULL; - } -#endif - return SQLITE_OK; -} - -#endif /* SQLITE_OS_WIN */ - -/************** End of os_win.c **********************************************/ -/************** Begin file bitvec.c ******************************************/ -/* -** 2008 February 16 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file implements an object that represents a fixed-length -** bitmap. Bits are numbered starting with 1. -** -** A bitmap is used to record which pages of a database file have been -** journalled during a transaction, or which pages have the "dont-write" -** property. Usually only a few pages are meet either condition. -** So the bitmap is usually sparse and has low cardinality. -** But sometimes (for example when during a DROP of a large table) most -** or all of the pages in a database can get journalled. In those cases, -** the bitmap becomes dense with high cardinality. The algorithm needs -** to handle both cases well. -** -** The size of the bitmap is fixed when the object is created. -** -** All bits are clear when the bitmap is created. Individual bits -** may be set or cleared one at a time. -** -** Test operations are about 100 times more common that set operations. -** Clear operations are exceedingly rare. There are usually between -** 5 and 500 set operations per Bitvec object, though the number of sets can -** sometimes grow into tens of thousands or larger. The size of the -** Bitvec object is the number of pages in the database file at the -** start of a transaction, and is thus usually less than a few thousand, -** but can be as large as 2 billion for a really big database. -*/ -/* #include "sqliteInt.h" */ - -/* Size of the Bitvec structure in bytes. */ -#define BITVEC_SZ 512 - -/* Round the union size down to the nearest pointer boundary, since that's how -** it will be aligned within the Bitvec struct. */ -#define BITVEC_USIZE \ - (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) - -/* Type of the array "element" for the bitmap representation. -** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. -** Setting this to the "natural word" size of your CPU may improve -** performance. */ -#define BITVEC_TELEM u8 -/* Size, in bits, of the bitmap element. */ -#define BITVEC_SZELEM 8 -/* Number of elements in a bitmap array. */ -#define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM)) -/* Number of bits in the bitmap array. */ -#define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM) - -/* Number of u32 values in hash table. */ -#define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) -/* Maximum number of entries in hash table before -** sub-dividing and re-hashing. */ -#define BITVEC_MXHASH (BITVEC_NINT/2) -/* Hashing function for the aHash representation. -** Empirical testing showed that the *37 multiplier -** (an arbitrary prime)in the hash function provided -** no fewer collisions than the no-op *1. */ -#define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) - -#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) - - -/* -** A bitmap is an instance of the following structure. -** -** This bitmap records the existence of zero or more bits -** with values between 1 and iSize, inclusive. -** -** There are three possible representations of the bitmap. -** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight -** bitmap. The least significant bit is bit 1. -** -** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is -** a hash table that will hold up to BITVEC_MXHASH distinct values. -** -** Otherwise, the value i is redirected into one of BITVEC_NPTR -** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap -** handles up to iDivisor separate values of i. apSub[0] holds -** values between 1 and iDivisor. apSub[1] holds values between -** iDivisor+1 and 2*iDivisor. apSub[N] holds values between -** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized -** to hold deal with values between 1 and iDivisor. -*/ -struct Bitvec { - u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ - u32 nSet; /* Number of bits that are set - only valid for aHash - ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, - ** this would be 125. */ - u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ - /* Should >=0 for apSub element. */ - /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ - /* For a BITVEC_SZ of 512, this would be 34,359,739. */ - union { - BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ - u32 aHash[BITVEC_NINT]; /* Hash table representation */ - Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ - } u; -}; - -/* -** Create a new bitmap object able to handle bits between 0 and iSize, -** inclusive. Return a pointer to the new object. Return NULL if -** malloc fails. -*/ -SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ - Bitvec *p; - assert( sizeof(*p)==BITVEC_SZ ); - p = sqlite3MallocZero( sizeof(*p) ); - if( p ){ - p->iSize = iSize; - } - return p; -} - -/* -** Check to see if the i-th bit is set. Return true or false. -** If p is NULL (if the bitmap has not been created) or if -** i is out of range, then return false. -*/ -SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){ - assert( p!=0 ); - i--; - if( i>=p->iSize ) return 0; - while( p->iDivisor ){ - u32 bin = i/p->iDivisor; - i = i%p->iDivisor; - p = p->u.apSub[bin]; - if (!p) { - return 0; - } - } - if( p->iSize<=BITVEC_NBIT ){ - return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; - } else{ - u32 h = BITVEC_HASH(i++); - while( p->u.aHash[h] ){ - if( p->u.aHash[h]==i ) return 1; - h = (h+1) % BITVEC_NINT; - } - return 0; - } -} -SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ - return p!=0 && sqlite3BitvecTestNotNull(p,i); -} - -/* -** Set the i-th bit. Return 0 on success and an error code if -** anything goes wrong. -** -** This routine might cause sub-bitmaps to be allocated. Failing -** to get the memory needed to hold the sub-bitmap is the only -** that can go wrong with an insert, assuming p and i are valid. -** -** The calling function must ensure that p is a valid Bitvec object -** and that the value for "i" is within range of the Bitvec object. -** Otherwise the behavior is undefined. -*/ -SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ - u32 h; - if( p==0 ) return SQLITE_OK; - assert( i>0 ); - assert( i<=p->iSize ); - i--; - while((p->iSize > BITVEC_NBIT) && p->iDivisor) { - u32 bin = i/p->iDivisor; - i = i%p->iDivisor; - if( p->u.apSub[bin]==0 ){ - p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); - if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT; - } - p = p->u.apSub[bin]; - } - if( p->iSize<=BITVEC_NBIT ){ - p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); - return SQLITE_OK; - } - h = BITVEC_HASH(i++); - /* if there wasn't a hash collision, and this doesn't */ - /* completely fill the hash, then just add it without */ - /* worring about sub-dividing and re-hashing. */ - if( !p->u.aHash[h] ){ - if (p->nSet<(BITVEC_NINT-1)) { - goto bitvec_set_end; - } else { - goto bitvec_set_rehash; - } - } - /* there was a collision, check to see if it's already */ - /* in hash, if not, try to find a spot for it */ - do { - if( p->u.aHash[h]==i ) return SQLITE_OK; - h++; - if( h>=BITVEC_NINT ) h = 0; - } while( p->u.aHash[h] ); - /* we didn't find it in the hash. h points to the first */ - /* available free spot. check to see if this is going to */ - /* make our hash too "full". */ -bitvec_set_rehash: - if( p->nSet>=BITVEC_MXHASH ){ - unsigned int j; - int rc; - u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); - if( aiValues==0 ){ - return SQLITE_NOMEM_BKPT; - }else{ - memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); - memset(p->u.apSub, 0, sizeof(p->u.apSub)); - p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; - rc = sqlite3BitvecSet(p, i); - for(j=0; jnSet++; - p->u.aHash[h] = i; - return SQLITE_OK; -} - -/* -** Clear the i-th bit. -** -** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage -** that BitvecClear can use to rebuilt its hash table. -*/ -SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ - if( p==0 ) return; - assert( i>0 ); - i--; - while( p->iDivisor ){ - u32 bin = i/p->iDivisor; - i = i%p->iDivisor; - p = p->u.apSub[bin]; - if (!p) { - return; - } - } - if( p->iSize<=BITVEC_NBIT ){ - p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); - }else{ - unsigned int j; - u32 *aiValues = pBuf; - memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); - memset(p->u.aHash, 0, sizeof(p->u.aHash)); - p->nSet = 0; - for(j=0; jnSet++; - while( p->u.aHash[h] ){ - h++; - if( h>=BITVEC_NINT ) h = 0; - } - p->u.aHash[h] = aiValues[j]; - } - } - } -} - -/* -** Destroy a bitmap object. Reclaim all memory used. -*/ -SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){ - if( p==0 ) return; - if( p->iDivisor ){ - unsigned int i; - for(i=0; iu.apSub[i]); - } - } - sqlite3_free(p); -} - -/* -** Return the value of the iSize parameter specified when Bitvec *p -** was created. -*/ -SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ - return p->iSize; -} - -#ifndef SQLITE_OMIT_BUILTIN_TEST -/* -** Let V[] be an array of unsigned characters sufficient to hold -** up to N bits. Let I be an integer between 0 and N. 0<=I>3] |= (1<<(I&7)) -#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) -#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 - -/* -** This routine runs an extensive test of the Bitvec code. -** -** The input is an array of integers that acts as a program -** to test the Bitvec. The integers are opcodes followed -** by 0, 1, or 3 operands, depending on the opcode. Another -** opcode follows immediately after the last operand. -** -** There are 6 opcodes numbered from 0 through 5. 0 is the -** "halt" opcode and causes the test to end. -** -** 0 Halt and return the number of errors -** 1 N S X Set N bits beginning with S and incrementing by X -** 2 N S X Clear N bits beginning with S and incrementing by X -** 3 N Set N randomly chosen bits -** 4 N Clear N randomly chosen bits -** 5 N S X Set N bits from S increment X in array only, not in bitvec -** -** The opcodes 1 through 4 perform set and clear operations are performed -** on both a Bitvec object and on a linear array of bits obtained from malloc. -** Opcode 5 works on the linear array only, not on the Bitvec. -** Opcode 5 is used to deliberately induce a fault in order to -** confirm that error detection works. -** -** At the conclusion of the test the linear array is compared -** against the Bitvec object. If there are any differences, -** an error is returned. If they are the same, zero is returned. -** -** If a memory allocation error occurs, return -1. -*/ -SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ - Bitvec *pBitvec = 0; - unsigned char *pV = 0; - int rc = -1; - int i, nx, pc, op; - void *pTmpSpace; - - /* Allocate the Bitvec to be tested and a linear array of - ** bits to act as the reference */ - pBitvec = sqlite3BitvecCreate( sz ); - pV = sqlite3MallocZero( (sz+7)/8 + 1 ); - pTmpSpace = sqlite3_malloc64(BITVEC_SZ); - if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; - - /* NULL pBitvec tests */ - sqlite3BitvecSet(0, 1); - sqlite3BitvecClear(0, 1, pTmpSpace); - - /* Run the program */ - pc = 0; - while( (op = aOp[pc])!=0 ){ - switch( op ){ - case 1: - case 2: - case 5: { - nx = 4; - i = aOp[pc+2] - 1; - aOp[pc+2] += aOp[pc+3]; - break; - } - case 3: - case 4: - default: { - nx = 2; - sqlite3_randomness(sizeof(i), &i); - break; - } - } - if( (--aOp[pc+1]) > 0 ) nx = 0; - pc += nx; - i = (i & 0x7fffffff)%sz; - if( (op & 1)!=0 ){ - SETBIT(pV, (i+1)); - if( op!=5 ){ - if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; - } - }else{ - CLEARBIT(pV, (i+1)); - sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); - } - } - - /* Test to make sure the linear array exactly matches the - ** Bitvec object. Start with the assumption that they do - ** match (rc==0). Change rc to non-zero if a discrepancy - ** is found. - */ - rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) - + sqlite3BitvecTest(pBitvec, 0) - + (sqlite3BitvecSize(pBitvec) - sz); - for(i=1; i<=sz; i++){ - if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ - rc = i; - break; - } - } - - /* Free allocated structure */ -bitvec_end: - sqlite3_free(pTmpSpace); - sqlite3_free(pV); - sqlite3BitvecDestroy(pBitvec); - return rc; -} -#endif /* SQLITE_OMIT_BUILTIN_TEST */ - -/************** End of bitvec.c **********************************************/ -/************** Begin file pcache.c ******************************************/ -/* -** 2008 August 05 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file implements that page cache. -*/ -/* #include "sqliteInt.h" */ - -/* -** A complete page cache is an instance of this structure. Every -** entry in the cache holds a single page of the database file. The -** btree layer only operates on the cached copy of the database pages. -** -** A page cache entry is "clean" if it exactly matches what is currently -** on disk. A page is "dirty" if it has been modified and needs to be -** persisted to disk. -** -** pDirty, pDirtyTail, pSynced: -** All dirty pages are linked into the doubly linked list using -** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order -** such that p was added to the list more recently than p->pDirtyNext. -** PCache.pDirty points to the first (newest) element in the list and -** pDirtyTail to the last (oldest). -** -** The PCache.pSynced variable is used to optimize searching for a dirty -** page to eject from the cache mid-transaction. It is better to eject -** a page that does not require a journal sync than one that does. -** Therefore, pSynced is maintained to that it *almost* always points -** to either the oldest page in the pDirty/pDirtyTail list that has a -** clear PGHDR_NEED_SYNC flag or to a page that is older than this one -** (so that the right page to eject can be found by following pDirtyPrev -** pointers). -*/ -struct PCache { - PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ - PgHdr *pSynced; /* Last synced page in dirty page list */ - int nRefSum; /* Sum of ref counts over all pages */ - int szCache; /* Configured cache size */ - int szSpill; /* Size before spilling occurs */ - int szPage; /* Size of every page in this cache */ - int szExtra; /* Size of extra space for each page */ - u8 bPurgeable; /* True if pages are on backing store */ - u8 eCreate; /* eCreate value for for xFetch() */ - int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ - void *pStress; /* Argument to xStress */ - sqlite3_pcache *pCache; /* Pluggable cache module */ -}; - -/********************************** Test and Debug Logic **********************/ -/* -** Debug tracing macros. Enable by by changing the "0" to "1" and -** recompiling. -** -** When sqlite3PcacheTrace is 1, single line trace messages are issued. -** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries -** is displayed for many operations, resulting in a lot of output. -*/ -#if defined(SQLITE_DEBUG) && 0 - int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ - int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ -# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} - void pcacheDump(PCache *pCache){ - int N; - int i, j; - sqlite3_pcache_page *pLower; - PgHdr *pPg; - unsigned char *a; - - if( sqlite3PcacheTrace<2 ) return; - if( pCache->pCache==0 ) return; - N = sqlite3PcachePagecount(pCache); - if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; - for(i=1; i<=N; i++){ - pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); - if( pLower==0 ) continue; - pPg = (PgHdr*)pLower->pExtra; - printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); - a = (unsigned char *)pLower->pBuf; - for(j=0; j<12; j++) printf("%02x", a[j]); - printf("\n"); - if( pPg->pPage==0 ){ - sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); - } - } - } - #else -# define pcacheTrace(X) -# define pcacheDump(X) -#endif - -/* -** Check invariants on a PgHdr entry. Return true if everything is OK. -** Return false if any invariant is violated. -** -** This routine is for use inside of assert() statements only. For -** example: -** -** assert( sqlite3PcachePageSanity(pPg) ); -*/ -#if SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ - PCache *pCache; - assert( pPg!=0 ); - assert( pPg->pgno>0 ); /* Page number is 1 or more */ - pCache = pPg->pCache; - assert( pCache!=0 ); /* Every page has an associated PCache */ - if( pPg->flags & PGHDR_CLEAN ){ - assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ - assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ - assert( pCache->pDirtyTail!=pPg ); - } - /* WRITEABLE pages must also be DIRTY */ - if( pPg->flags & PGHDR_WRITEABLE ){ - assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ - } - /* NEED_SYNC can be set independently of WRITEABLE. This can happen, - ** for example, when using the sqlite3PagerDontWrite() optimization: - ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. - ** (2) Page X moved to freelist, WRITEABLE is cleared - ** (3) Page X reused, WRITEABLE is set again - ** If NEED_SYNC had been cleared in step 2, then it would not be reset - ** in step 3, and page might be written into the database without first - ** syncing the rollback journal, which might cause corruption on a power - ** loss. - ** - ** Another example is when the database page size is smaller than the - ** disk sector size. When any page of a sector is journalled, all pages - ** in that sector are marked NEED_SYNC even if they are still CLEAN, just - ** in case they are later modified, since all pages in the same sector - ** must be journalled and synced before any of those pages can be safely - ** written. - */ - return 1; -} -#endif /* SQLITE_DEBUG */ - - -/********************************** Linked List Management ********************/ - -/* Allowed values for second argument to pcacheManageDirtyList() */ -#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ -#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ -#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ - -/* -** Manage pPage's participation on the dirty list. Bits of the addRemove -** argument determines what operation to do. The 0x01 bit means first -** remove pPage from the dirty list. The 0x02 means add pPage back to -** the dirty list. Doing both moves pPage to the front of the dirty list. -*/ -static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ - PCache *p = pPage->pCache; - - pcacheTrace(("%p.DIRTYLIST.%s %d\n", p, - addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT", - pPage->pgno)); - if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ - assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); - assert( pPage->pDirtyPrev || pPage==p->pDirty ); - - /* Update the PCache1.pSynced variable if necessary. */ - if( p->pSynced==pPage ){ - p->pSynced = pPage->pDirtyPrev; - } - - if( pPage->pDirtyNext ){ - pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; - }else{ - assert( pPage==p->pDirtyTail ); - p->pDirtyTail = pPage->pDirtyPrev; - } - if( pPage->pDirtyPrev ){ - pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; - }else{ - /* If there are now no dirty pages in the cache, set eCreate to 2. - ** This is an optimization that allows sqlite3PcacheFetch() to skip - ** searching for a dirty page to eject from the cache when it might - ** otherwise have to. */ - assert( pPage==p->pDirty ); - p->pDirty = pPage->pDirtyNext; - assert( p->bPurgeable || p->eCreate==2 ); - if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ - assert( p->bPurgeable==0 || p->eCreate==1 ); - p->eCreate = 2; - } - } - pPage->pDirtyNext = 0; - pPage->pDirtyPrev = 0; - } - if( addRemove & PCACHE_DIRTYLIST_ADD ){ - assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); - - pPage->pDirtyNext = p->pDirty; - if( pPage->pDirtyNext ){ - assert( pPage->pDirtyNext->pDirtyPrev==0 ); - pPage->pDirtyNext->pDirtyPrev = pPage; - }else{ - p->pDirtyTail = pPage; - if( p->bPurgeable ){ - assert( p->eCreate==2 ); - p->eCreate = 1; - } - } - p->pDirty = pPage; - - /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set - ** pSynced to point to it. Checking the NEED_SYNC flag is an - ** optimization, as if pSynced points to a page with the NEED_SYNC - ** flag set sqlite3PcacheFetchStress() searches through all newer - ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ - if( !p->pSynced - && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ - ){ - p->pSynced = pPage; - } - } - pcacheDump(p); -} - -/* -** Wrapper around the pluggable caches xUnpin method. If the cache is -** being used for an in-memory database, this function is a no-op. -*/ -static void pcacheUnpin(PgHdr *p){ - if( p->pCache->bPurgeable ){ - pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); - sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); - pcacheDump(p->pCache); - } -} - -/* -** Compute the number of pages of cache requested. p->szCache is the -** cache size requested by the "PRAGMA cache_size" statement. -*/ -static int numberOfCachePages(PCache *p){ - if( p->szCache>=0 ){ - /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the - ** suggested cache size is set to N. */ - return p->szCache; - }else{ - /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then - ** the number of cache pages is adjusted to use approximately abs(N*1024) - ** bytes of memory. */ - return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); - } -} - -/*************************************************** General Interfaces ****** -** -** Initialize and shutdown the page cache subsystem. Neither of these -** functions are threadsafe. -*/ -SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ - if( sqlite3GlobalConfig.pcache2.xInit==0 ){ - /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the - ** built-in default page cache is used instead of the application defined - ** page cache. */ - sqlite3PCacheSetDefault(); - } - return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); -} -SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ - if( sqlite3GlobalConfig.pcache2.xShutdown ){ - /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ - sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); - } -} - -/* -** Return the size in bytes of a PCache object. -*/ -SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } - -/* -** Create a new PCache object. Storage space to hold the object -** has already been allocated and is passed in as the p pointer. -** The caller discovers how much space needs to be allocated by -** calling sqlite3PcacheSize(). -*/ -SQLITE_PRIVATE int sqlite3PcacheOpen( - int szPage, /* Size of every page */ - int szExtra, /* Extra space associated with each page */ - int bPurgeable, /* True if pages are on backing store */ - int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ - void *pStress, /* Argument to xStress */ - PCache *p /* Preallocated space for the PCache */ -){ - memset(p, 0, sizeof(PCache)); - p->szPage = 1; - p->szExtra = szExtra; - p->bPurgeable = bPurgeable; - p->eCreate = 2; - p->xStress = xStress; - p->pStress = pStress; - p->szCache = 100; - p->szSpill = 1; - pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable)); - return sqlite3PcacheSetPageSize(p, szPage); -} - -/* -** Change the page size for PCache object. The caller must ensure that there -** are no outstanding page references when this function is called. -*/ -SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ - assert( pCache->nRefSum==0 && pCache->pDirty==0 ); - if( pCache->szPage ){ - sqlite3_pcache *pNew; - pNew = sqlite3GlobalConfig.pcache2.xCreate( - szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), - pCache->bPurgeable - ); - if( pNew==0 ) return SQLITE_NOMEM_BKPT; - sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); - if( pCache->pCache ){ - sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); - } - pCache->pCache = pNew; - pCache->szPage = szPage; - pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage)); - } - return SQLITE_OK; -} - -/* -** Try to obtain a page from the cache. -** -** This routine returns a pointer to an sqlite3_pcache_page object if -** such an object is already in cache, or if a new one is created. -** This routine returns a NULL pointer if the object was not in cache -** and could not be created. -** -** The createFlags should be 0 to check for existing pages and should -** be 3 (not 1, but 3) to try to create a new page. -** -** If the createFlag is 0, then NULL is always returned if the page -** is not already in the cache. If createFlag is 1, then a new page -** is created only if that can be done without spilling dirty pages -** and without exceeding the cache size limit. -** -** The caller needs to invoke sqlite3PcacheFetchFinish() to properly -** initialize the sqlite3_pcache_page object and convert it into a -** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() -** routines are split this way for performance reasons. When separated -** they can both (usually) operate without having to push values to -** the stack on entry and pop them back off on exit, which saves a -** lot of pushing and popping. -*/ -SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( - PCache *pCache, /* Obtain the page from this cache */ - Pgno pgno, /* Page number to obtain */ - int createFlag /* If true, create page if it does not exist already */ -){ - int eCreate; - sqlite3_pcache_page *pRes; - - assert( pCache!=0 ); - assert( pCache->pCache!=0 ); - assert( createFlag==3 || createFlag==0 ); - assert( pgno>0 ); - assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); - - /* eCreate defines what to do if the page does not exist. - ** 0 Do not allocate a new page. (createFlag==0) - ** 1 Allocate a new page if doing so is inexpensive. - ** (createFlag==1 AND bPurgeable AND pDirty) - ** 2 Allocate a new page even it doing so is difficult. - ** (createFlag==1 AND !(bPurgeable AND pDirty) - */ - eCreate = createFlag & pCache->eCreate; - assert( eCreate==0 || eCreate==1 || eCreate==2 ); - assert( createFlag==0 || pCache->eCreate==eCreate ); - assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); - pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); - pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, - createFlag?" create":"",pRes)); - return pRes; -} - -/* -** If the sqlite3PcacheFetch() routine is unable to allocate a new -** page because no clean pages are available for reuse and the cache -** size limit has been reached, then this routine can be invoked to -** try harder to allocate a page. This routine might invoke the stress -** callback to spill dirty pages to the journal. It will then try to -** allocate the new page and will only fail to allocate a new page on -** an OOM error. -** -** This routine should be invoked only after sqlite3PcacheFetch() fails. -*/ -SQLITE_PRIVATE int sqlite3PcacheFetchStress( - PCache *pCache, /* Obtain the page from this cache */ - Pgno pgno, /* Page number to obtain */ - sqlite3_pcache_page **ppPage /* Write result here */ -){ - PgHdr *pPg; - if( pCache->eCreate==2 ) return 0; - - if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){ - /* Find a dirty page to write-out and recycle. First try to find a - ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC - ** cleared), but if that is not possible settle for any other - ** unreferenced dirty page. - ** - ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC - ** flag is currently referenced, then the following may leave pSynced - ** set incorrectly (pointing to other than the LRU page with NEED_SYNC - ** cleared). This is Ok, as pSynced is just an optimization. */ - for(pPg=pCache->pSynced; - pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); - pPg=pPg->pDirtyPrev - ); - pCache->pSynced = pPg; - if( !pPg ){ - for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); - } - if( pPg ){ - int rc; -#ifdef SQLITE_LOG_CACHE_SPILL - sqlite3_log(SQLITE_FULL, - "spill page %d making room for %d - cache used: %d/%d", - pPg->pgno, pgno, - sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), - numberOfCachePages(pCache)); -#endif - pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); - rc = pCache->xStress(pCache->pStress, pPg); - pcacheDump(pCache); - if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ - return rc; - } - } - } - *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); - return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; -} - -/* -** This is a helper routine for sqlite3PcacheFetchFinish() -** -** In the uncommon case where the page being fetched has not been -** initialized, this routine is invoked to do the initialization. -** This routine is broken out into a separate function since it -** requires extra stack manipulation that can be avoided in the common -** case. -*/ -static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( - PCache *pCache, /* Obtain the page from this cache */ - Pgno pgno, /* Page number obtained */ - sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ -){ - PgHdr *pPgHdr; - assert( pPage!=0 ); - pPgHdr = (PgHdr*)pPage->pExtra; - assert( pPgHdr->pPage==0 ); - memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); - pPgHdr->pPage = pPage; - pPgHdr->pData = pPage->pBuf; - pPgHdr->pExtra = (void *)&pPgHdr[1]; - memset(pPgHdr->pExtra, 0, pCache->szExtra); - pPgHdr->pCache = pCache; - pPgHdr->pgno = pgno; - pPgHdr->flags = PGHDR_CLEAN; - return sqlite3PcacheFetchFinish(pCache,pgno,pPage); -} - -/* -** This routine converts the sqlite3_pcache_page object returned by -** sqlite3PcacheFetch() into an initialized PgHdr object. This routine -** must be called after sqlite3PcacheFetch() in order to get a usable -** result. -*/ -SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( - PCache *pCache, /* Obtain the page from this cache */ - Pgno pgno, /* Page number obtained */ - sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ -){ - PgHdr *pPgHdr; - - assert( pPage!=0 ); - pPgHdr = (PgHdr *)pPage->pExtra; - - if( !pPgHdr->pPage ){ - return pcacheFetchFinishWithInit(pCache, pgno, pPage); - } - pCache->nRefSum++; - pPgHdr->nRef++; - assert( sqlite3PcachePageSanity(pPgHdr) ); - return pPgHdr; -} - -/* -** Decrement the reference count on a page. If the page is clean and the -** reference count drops to 0, then it is made eligible for recycling. -*/ -SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ - assert( p->nRef>0 ); - p->pCache->nRefSum--; - if( (--p->nRef)==0 ){ - if( p->flags&PGHDR_CLEAN ){ - pcacheUnpin(p); - }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/ - /* Move the page to the head of the dirty list. If p->pDirtyPrev==0, - ** then page p is already at the head of the dirty list and the - ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE - ** tag above. */ - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - } - } -} - -/* -** Increase the reference count of a supplied page by 1. -*/ -SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){ - assert(p->nRef>0); - assert( sqlite3PcachePageSanity(p) ); - p->nRef++; - p->pCache->nRefSum++; -} - -/* -** Drop a page from the cache. There must be exactly one reference to the -** page. This function deletes that reference, so after it returns the -** page pointed to by p is invalid. -*/ -SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ - assert( p->nRef==1 ); - assert( sqlite3PcachePageSanity(p) ); - if( p->flags&PGHDR_DIRTY ){ - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); - } - p->pCache->nRefSum--; - sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); -} - -/* -** Make sure the page is marked as dirty. If it isn't dirty already, -** make it so. -*/ -SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ - assert( p->nRef>0 ); - assert( sqlite3PcachePageSanity(p) ); - if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ - p->flags &= ~PGHDR_DONT_WRITE; - if( p->flags & PGHDR_CLEAN ){ - p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); - pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); - assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); - } - assert( sqlite3PcachePageSanity(p) ); - } -} - -/* -** Make sure the page is marked as clean. If it isn't clean already, -** make it so. -*/ -SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ - assert( sqlite3PcachePageSanity(p) ); - if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){ - assert( (p->flags & PGHDR_CLEAN)==0 ); - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); - p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); - p->flags |= PGHDR_CLEAN; - pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); - assert( sqlite3PcachePageSanity(p) ); - if( p->nRef==0 ){ - pcacheUnpin(p); - } - } -} - -/* -** Make every page in the cache clean. -*/ -SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){ - PgHdr *p; - pcacheTrace(("%p.CLEAN-ALL\n",pCache)); - while( (p = pCache->pDirty)!=0 ){ - sqlite3PcacheMakeClean(p); - } -} - -/* -** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. -*/ -SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){ - PgHdr *p; - pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache)); - for(p=pCache->pDirty; p; p=p->pDirtyNext){ - p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); - } - pCache->pSynced = pCache->pDirtyTail; -} - -/* -** Clear the PGHDR_NEED_SYNC flag from all dirty pages. -*/ -SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ - PgHdr *p; - for(p=pCache->pDirty; p; p=p->pDirtyNext){ - p->flags &= ~PGHDR_NEED_SYNC; - } - pCache->pSynced = pCache->pDirtyTail; -} - -/* -** Change the page number of page p to newPgno. -*/ -SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ - PCache *pCache = p->pCache; - assert( p->nRef>0 ); - assert( newPgno>0 ); - assert( sqlite3PcachePageSanity(p) ); - pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); - sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); - p->pgno = newPgno; - if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ - pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); - } -} - -/* -** Drop every cache entry whose page number is greater than "pgno". The -** caller must ensure that there are no outstanding references to any pages -** other than page 1 with a page number greater than pgno. -** -** If there is a reference to page 1 and the pgno parameter passed to this -** function is 0, then the data area associated with page 1 is zeroed, but -** the page object is not dropped. -*/ -SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ - if( pCache->pCache ){ - PgHdr *p; - PgHdr *pNext; - pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno)); - for(p=pCache->pDirty; p; p=pNext){ - pNext = p->pDirtyNext; - /* This routine never gets call with a positive pgno except right - ** after sqlite3PcacheCleanAll(). So if there are dirty pages, - ** it must be that pgno==0. - */ - assert( p->pgno>0 ); - if( p->pgno>pgno ){ - assert( p->flags&PGHDR_DIRTY ); - sqlite3PcacheMakeClean(p); - } - } - if( pgno==0 && pCache->nRefSum ){ - sqlite3_pcache_page *pPage1; - pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); - if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because - ** pCache->nRefSum>0 */ - memset(pPage1->pBuf, 0, pCache->szPage); - pgno = 1; - } - } - sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); - } -} - -/* -** Close a cache. -*/ -SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ - assert( pCache->pCache!=0 ); - pcacheTrace(("%p.CLOSE\n",pCache)); - sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); -} - -/* -** Discard the contents of the cache. -*/ -SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ - sqlite3PcacheTruncate(pCache, 0); -} - -/* -** Merge two lists of pages connected by pDirty and in pgno order. -** Do not bother fixing the pDirtyPrev pointers. -*/ -static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ - PgHdr result, *pTail; - pTail = &result; - assert( pA!=0 && pB!=0 ); - for(;;){ - if( pA->pgnopgno ){ - pTail->pDirty = pA; - pTail = pA; - pA = pA->pDirty; - if( pA==0 ){ - pTail->pDirty = pB; - break; - } - }else{ - pTail->pDirty = pB; - pTail = pB; - pB = pB->pDirty; - if( pB==0 ){ - pTail->pDirty = pA; - break; - } - } - } - return result.pDirty; -} - -/* -** Sort the list of pages in accending order by pgno. Pages are -** connected by pDirty pointers. The pDirtyPrev pointers are -** corrupted by this sort. -** -** Since there cannot be more than 2^31 distinct pages in a database, -** there cannot be more than 31 buckets required by the merge sorter. -** One extra bucket is added to catch overflow in case something -** ever changes to make the previous sentence incorrect. -*/ -#define N_SORT_BUCKET 32 -static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ - PgHdr *a[N_SORT_BUCKET], *p; - int i; - memset(a, 0, sizeof(a)); - while( pIn ){ - p = pIn; - pIn = p->pDirty; - p->pDirty = 0; - for(i=0; ALWAYS(ipDirty; p; p=p->pDirtyNext){ - p->pDirty = p->pDirtyNext; - } - return pcacheSortDirtyList(pCache->pDirty); -} - -/* -** Return the total number of references to all pages held by the cache. -** -** This is not the total number of pages referenced, but the sum of the -** reference count for all pages. -*/ -SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ - return pCache->nRefSum; -} - -/* -** Return the number of references to the page supplied as an argument. -*/ -SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ - return p->nRef; -} - -/* -** Return the total number of pages in the cache. -*/ -SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ - assert( pCache->pCache!=0 ); - return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); -} - -#ifdef SQLITE_TEST -/* -** Get the suggested cache-size value. -*/ -SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){ - return numberOfCachePages(pCache); -} -#endif - -/* -** Set the suggested cache-size value. -*/ -SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ - assert( pCache->pCache!=0 ); - pCache->szCache = mxPage; - sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, - numberOfCachePages(pCache)); -} - -/* -** Set the suggested cache-spill value. Make no changes if if the -** argument is zero. Return the effective cache-spill size, which will -** be the larger of the szSpill and szCache. -*/ -SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){ - int res; - assert( p->pCache!=0 ); - if( mxPage ){ - if( mxPage<0 ){ - mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra)); - } - p->szSpill = mxPage; - } - res = numberOfCachePages(p); - if( resszSpill ) res = p->szSpill; - return res; -} - -/* -** Free up as much memory as possible from the page cache. -*/ -SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ - assert( pCache->pCache!=0 ); - sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); -} - -/* -** Return the size of the header added by this middleware layer -** in the page-cache hierarchy. -*/ -SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } - -/* -** Return the number of dirty pages currently in the cache, as a percentage -** of the configured cache size. -*/ -SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){ - PgHdr *pDirty; - int nDirty = 0; - int nCache = numberOfCachePages(pCache); - for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; - return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; -} - -#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) -/* -** For all dirty pages currently in the cache, invoke the specified -** callback. This is only used if the SQLITE_CHECK_PAGES macro is -** defined. -*/ -SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ - PgHdr *pDirty; - for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ - xIter(pDirty); - } -} -#endif - -/************** End of pcache.c **********************************************/ -/************** Begin file pcache1.c *****************************************/ -/* -** 2008 November 05 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file implements the default page cache implementation (the -** sqlite3_pcache interface). It also contains part of the implementation -** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. -** If the default page cache implementation is overridden, then neither of -** these two features are available. -** -** A Page cache line looks like this: -** -** ------------------------------------------------------------- -** | database page content | PgHdr1 | MemPage | PgHdr | -** ------------------------------------------------------------- -** -** The database page content is up front (so that buffer overreads tend to -** flow harmlessly into the PgHdr1, MemPage, and PgHdr extensions). MemPage -** is the extension added by the btree.c module containing information such -** as the database page number and how that database page is used. PgHdr -** is added by the pcache.c layer and contains information used to keep track -** of which pages are "dirty". PgHdr1 is an extension added by this -** module (pcache1.c). The PgHdr1 header is a subclass of sqlite3_pcache_page. -** PgHdr1 contains information needed to look up a page by its page number. -** The superclass sqlite3_pcache_page.pBuf points to the start of the -** database page content and sqlite3_pcache_page.pExtra points to PgHdr. -** -** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at -** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The -** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this -** size can vary according to architecture, compile-time options, and -** SQLite library version number. -** -** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained -** using a separate memory allocation from the database page content. This -** seeks to overcome the "clownshoe" problem (also called "internal -** fragmentation" in academic literature) of allocating a few bytes more -** than a power of two with the memory allocator rounding up to the next -** power of two, and leaving the rounded-up space unused. -** -** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates -** with this module. Information is passed back and forth as PgHdr1 pointers. -** -** The pcache.c and pager.c modules deal pointers to PgHdr objects. -** The btree.c module deals with pointers to MemPage objects. -** -** SOURCE OF PAGE CACHE MEMORY: -** -** Memory for a page might come from any of three sources: -** -** (1) The general-purpose memory allocator - sqlite3Malloc() -** (2) Global page-cache memory provided using sqlite3_config() with -** SQLITE_CONFIG_PAGECACHE. -** (3) PCache-local bulk allocation. -** -** The third case is a chunk of heap memory (defaulting to 100 pages worth) -** that is allocated when the page cache is created. The size of the local -** bulk allocation can be adjusted using -** -** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). -** -** If N is positive, then N pages worth of memory are allocated using a single -** sqlite3Malloc() call and that memory is used for the first N pages allocated. -** Or if N is negative, then -1024*N bytes of memory are allocated and used -** for as many pages as can be accomodated. -** -** Only one of (2) or (3) can be used. Once the memory available to (2) or -** (3) is exhausted, subsequent allocations fail over to the general-purpose -** memory allocator (1). -** -** Earlier versions of SQLite used only methods (1) and (2). But experiments -** show that method (3) with N==100 provides about a 5% performance boost for -** common workloads. -*/ -/* #include "sqliteInt.h" */ - -typedef struct PCache1 PCache1; -typedef struct PgHdr1 PgHdr1; -typedef struct PgFreeslot PgFreeslot; -typedef struct PGroup PGroup; - -/* -** Each cache entry is represented by an instance of the following -** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of -** PgHdr1.pCache->szPage bytes is allocated directly before this structure -** in memory. -*/ -struct PgHdr1 { - sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ - unsigned int iKey; /* Key value (page number) */ - u8 isPinned; /* Page in use, not on the LRU list */ - u8 isBulkLocal; /* This page from bulk local storage */ - u8 isAnchor; /* This is the PGroup.lru element */ - PgHdr1 *pNext; /* Next in hash table chain */ - PCache1 *pCache; /* Cache that currently owns this page */ - PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ - PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ -}; - -/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set -** of one or more PCaches that are able to recycle each other's unpinned -** pages when they are under memory pressure. A PGroup is an instance of -** the following object. -** -** This page cache implementation works in one of two modes: -** -** (1) Every PCache is the sole member of its own PGroup. There is -** one PGroup per PCache. -** -** (2) There is a single global PGroup that all PCaches are a member -** of. -** -** Mode 1 uses more memory (since PCache instances are not able to rob -** unused pages from other PCaches) but it also operates without a mutex, -** and is therefore often faster. Mode 2 requires a mutex in order to be -** threadsafe, but recycles pages more efficiently. -** -** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single -** PGroup which is the pcache1.grp global variable and its mutex is -** SQLITE_MUTEX_STATIC_LRU. -*/ -struct PGroup { - sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ - unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ - unsigned int nMinPage; /* Sum of nMin for purgeable caches */ - unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ - unsigned int nCurrentPage; /* Number of purgeable pages allocated */ - PgHdr1 lru; /* The beginning and end of the LRU list */ -}; - -/* Each page cache is an instance of the following object. Every -** open database file (including each in-memory database and each -** temporary or transient database) has a single page cache which -** is an instance of this object. -** -** Pointers to structures of this type are cast and returned as -** opaque sqlite3_pcache* handles. -*/ -struct PCache1 { - /* Cache configuration parameters. Page size (szPage) and the purgeable - ** flag (bPurgeable) are set when the cache is created. nMax may be - ** modified at any time by a call to the pcache1Cachesize() method. - ** The PGroup mutex must be held when accessing nMax. - */ - PGroup *pGroup; /* PGroup this cache belongs to */ - int szPage; /* Size of database content section */ - int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ - int szAlloc; /* Total size of one pcache line */ - int bPurgeable; /* True if cache is purgeable */ - unsigned int nMin; /* Minimum number of pages reserved */ - unsigned int nMax; /* Configured "cache_size" value */ - unsigned int n90pct; /* nMax*9/10 */ - unsigned int iMaxKey; /* Largest key seen since xTruncate() */ - - /* Hash table of all pages. The following variables may only be accessed - ** when the accessor is holding the PGroup mutex. - */ - unsigned int nRecyclable; /* Number of pages in the LRU list */ - unsigned int nPage; /* Total number of pages in apHash */ - unsigned int nHash; /* Number of slots in apHash[] */ - PgHdr1 **apHash; /* Hash table for fast lookup by key */ - PgHdr1 *pFree; /* List of unused pcache-local pages */ - void *pBulk; /* Bulk memory used by pcache-local */ -}; - -/* -** Free slots in the allocator used to divide up the global page cache -** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism. -*/ -struct PgFreeslot { - PgFreeslot *pNext; /* Next free slot */ -}; - -/* -** Global data used by this cache. -*/ -static SQLITE_WSD struct PCacheGlobal { - PGroup grp; /* The global PGroup for mode (2) */ - - /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The - ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all - ** fixed at sqlite3_initialize() time and do not require mutex protection. - ** The nFreeSlot and pFree values do require mutex protection. - */ - int isInit; /* True if initialized */ - int separateCache; /* Use a new PGroup for each PCache */ - int nInitPage; /* Initial bulk allocation size */ - int szSlot; /* Size of each free slot */ - int nSlot; /* The number of pcache slots */ - int nReserve; /* Try to keep nFreeSlot above this */ - void *pStart, *pEnd; /* Bounds of global page cache memory */ - /* Above requires no mutex. Use mutex below for variable that follow. */ - sqlite3_mutex *mutex; /* Mutex for accessing the following: */ - PgFreeslot *pFree; /* Free page blocks */ - int nFreeSlot; /* Number of unused pcache slots */ - /* The following value requires a mutex to change. We skip the mutex on - ** reading because (1) most platforms read a 32-bit integer atomically and - ** (2) even if an incorrect value is read, no great harm is done since this - ** is really just an optimization. */ - int bUnderPressure; /* True if low on PAGECACHE memory */ -} pcache1_g; - -/* -** All code in this file should access the global structure above via the -** alias "pcache1". This ensures that the WSD emulation is used when -** compiling for systems that do not support real WSD. -*/ -#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) - -/* -** Macros to enter and leave the PCache LRU mutex. -*/ -#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 -# define pcache1EnterMutex(X) assert((X)->mutex==0) -# define pcache1LeaveMutex(X) assert((X)->mutex==0) -# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0 -#else -# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) -# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) -# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1 -#endif - -/******************************************************************************/ -/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ - - -/* -** This function is called during initialization if a static buffer is -** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE -** verb to sqlite3_config(). Parameter pBuf points to an allocation large -** enough to contain 'n' buffers of 'sz' bytes each. -** -** This routine is called from sqlite3_initialize() and so it is guaranteed -** to be serialized already. There is no need for further mutexing. -*/ -SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ - if( pcache1.isInit ){ - PgFreeslot *p; - if( pBuf==0 ) sz = n = 0; - sz = ROUNDDOWN8(sz); - pcache1.szSlot = sz; - pcache1.nSlot = pcache1.nFreeSlot = n; - pcache1.nReserve = n>90 ? 10 : (n/10 + 1); - pcache1.pStart = pBuf; - pcache1.pFree = 0; - pcache1.bUnderPressure = 0; - while( n-- ){ - p = (PgFreeslot*)pBuf; - p->pNext = pcache1.pFree; - pcache1.pFree = p; - pBuf = (void*)&((char*)pBuf)[sz]; - } - pcache1.pEnd = pBuf; - } -} - -/* -** Try to initialize the pCache->pFree and pCache->pBulk fields. Return -** true if pCache->pFree ends up containing one or more free pages. -*/ -static int pcache1InitBulk(PCache1 *pCache){ - i64 szBulk; - char *zBulk; - if( pcache1.nInitPage==0 ) return 0; - /* Do not bother with a bulk allocation if the cache size very small */ - if( pCache->nMax<3 ) return 0; - sqlite3BeginBenignMalloc(); - if( pcache1.nInitPage>0 ){ - szBulk = pCache->szAlloc * (i64)pcache1.nInitPage; - }else{ - szBulk = -1024 * (i64)pcache1.nInitPage; - } - if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ - szBulk = pCache->szAlloc*(i64)pCache->nMax; - } - zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); - sqlite3EndBenignMalloc(); - if( zBulk ){ - int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; - int i; - for(i=0; iszPage]; - pX->page.pBuf = zBulk; - pX->page.pExtra = &pX[1]; - pX->isBulkLocal = 1; - pX->isAnchor = 0; - pX->pNext = pCache->pFree; - pCache->pFree = pX; - zBulk += pCache->szAlloc; - } - } - return pCache->pFree!=0; -} - -/* -** Malloc function used within this file to allocate space from the buffer -** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no -** such buffer exists or there is no space left in it, this function falls -** back to sqlite3Malloc(). -** -** Multiple threads can run this routine at the same time. Global variables -** in pcache1 need to be protected via mutex. -*/ -static void *pcache1Alloc(int nByte){ - void *p = 0; - assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); - if( nByte<=pcache1.szSlot ){ - sqlite3_mutex_enter(pcache1.mutex); - p = (PgHdr1 *)pcache1.pFree; - if( p ){ - pcache1.pFree = pcache1.pFree->pNext; - pcache1.nFreeSlot--; - pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); - sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); - } - sqlite3_mutex_leave(pcache1.mutex); - } - if( p==0 ){ - /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get - ** it from sqlite3Malloc instead. - */ - p = sqlite3Malloc(nByte); -#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS - if( p ){ - int sz = sqlite3MallocSize(p); - sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); - sqlite3_mutex_leave(pcache1.mutex); - } -#endif - sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); - } - return p; -} - -/* -** Free an allocated buffer obtained from pcache1Alloc(). -*/ -static void pcache1Free(void *p){ - if( p==0 ) return; - if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ - PgFreeslot *pSlot; - sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); - pSlot = (PgFreeslot*)p; - pSlot->pNext = pcache1.pFree; - pcache1.pFree = pSlot; - pcache1.nFreeSlot++; - pcache1.bUnderPressure = pcache1.nFreeSlot=pcache1.pStart && ppGroup->mutex) ); - if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ - p = pCache->pFree; - pCache->pFree = p->pNext; - p->pNext = 0; - }else{ -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - /* The group mutex must be released before pcache1Alloc() is called. This - ** is because it might call sqlite3_release_memory(), which assumes that - ** this mutex is not held. */ - assert( pcache1.separateCache==0 ); - assert( pCache->pGroup==&pcache1.grp ); - pcache1LeaveMutex(pCache->pGroup); -#endif - if( benignMalloc ){ sqlite3BeginBenignMalloc(); } -#ifdef SQLITE_PCACHE_SEPARATE_HEADER - pPg = pcache1Alloc(pCache->szPage); - p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); - if( !pPg || !p ){ - pcache1Free(pPg); - sqlite3_free(p); - pPg = 0; - } -#else - pPg = pcache1Alloc(pCache->szAlloc); - p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; -#endif - if( benignMalloc ){ sqlite3EndBenignMalloc(); } -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - pcache1EnterMutex(pCache->pGroup); -#endif - if( pPg==0 ) return 0; - p->page.pBuf = pPg; - p->page.pExtra = &p[1]; - p->isBulkLocal = 0; - p->isAnchor = 0; - } - if( pCache->bPurgeable ){ - pCache->pGroup->nCurrentPage++; - } - return p; -} - -/* -** Free a page object allocated by pcache1AllocPage(). -*/ -static void pcache1FreePage(PgHdr1 *p){ - PCache1 *pCache; - assert( p!=0 ); - pCache = p->pCache; - assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); - if( p->isBulkLocal ){ - p->pNext = pCache->pFree; - pCache->pFree = p; - }else{ - pcache1Free(p->page.pBuf); -#ifdef SQLITE_PCACHE_SEPARATE_HEADER - sqlite3_free(p); -#endif - } - if( pCache->bPurgeable ){ - pCache->pGroup->nCurrentPage--; - } -} - -/* -** Malloc function used by SQLite to obtain space from the buffer configured -** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer -** exists, this function falls back to sqlite3Malloc(). -*/ -SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ - return pcache1Alloc(sz); -} - -/* -** Free an allocated buffer obtained from sqlite3PageMalloc(). -*/ -SQLITE_PRIVATE void sqlite3PageFree(void *p){ - pcache1Free(p); -} - - -/* -** Return true if it desirable to avoid allocating a new page cache -** entry. -** -** If memory was allocated specifically to the page cache using -** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then -** it is desirable to avoid allocating a new page cache entry because -** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient -** for all page cache needs and we should not need to spill the -** allocation onto the heap. -** -** Or, the heap is used for all page cache memory but the heap is -** under memory pressure, then again it is desirable to avoid -** allocating a new page cache entry in order to avoid stressing -** the heap even further. -*/ -static int pcache1UnderMemoryPressure(PCache1 *pCache){ - if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ - return pcache1.bUnderPressure; - }else{ - return sqlite3HeapNearlyFull(); - } -} - -/******************************************************************************/ -/******** General Implementation Functions ************************************/ - -/* -** This function is used to resize the hash table used by the cache passed -** as the first argument. -** -** The PCache mutex must be held when this function is called. -*/ -static void pcache1ResizeHash(PCache1 *p){ - PgHdr1 **apNew; - unsigned int nNew; - unsigned int i; - - assert( sqlite3_mutex_held(p->pGroup->mutex) ); - - nNew = p->nHash*2; - if( nNew<256 ){ - nNew = 256; - } - - pcache1LeaveMutex(p->pGroup); - if( p->nHash ){ sqlite3BeginBenignMalloc(); } - apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); - if( p->nHash ){ sqlite3EndBenignMalloc(); } - pcache1EnterMutex(p->pGroup); - if( apNew ){ - for(i=0; inHash; i++){ - PgHdr1 *pPage; - PgHdr1 *pNext = p->apHash[i]; - while( (pPage = pNext)!=0 ){ - unsigned int h = pPage->iKey % nNew; - pNext = pPage->pNext; - pPage->pNext = apNew[h]; - apNew[h] = pPage; - } - } - sqlite3_free(p->apHash); - p->apHash = apNew; - p->nHash = nNew; - } -} - -/* -** This function is used internally to remove the page pPage from the -** PGroup LRU list, if is part of it. If pPage is not part of the PGroup -** LRU list, then this function is a no-op. -** -** The PGroup mutex must be held when this function is called. -*/ -static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ - PCache1 *pCache; - - assert( pPage!=0 ); - assert( pPage->isPinned==0 ); - pCache = pPage->pCache; - assert( pPage->pLruNext ); - assert( pPage->pLruPrev ); - assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); - pPage->pLruPrev->pLruNext = pPage->pLruNext; - pPage->pLruNext->pLruPrev = pPage->pLruPrev; - pPage->pLruNext = 0; - pPage->pLruPrev = 0; - pPage->isPinned = 1; - assert( pPage->isAnchor==0 ); - assert( pCache->pGroup->lru.isAnchor==1 ); - pCache->nRecyclable--; - return pPage; -} - - -/* -** Remove the page supplied as an argument from the hash table -** (PCache1.apHash structure) that it is currently stored in. -** Also free the page if freePage is true. -** -** The PGroup mutex must be held when this function is called. -*/ -static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ - unsigned int h; - PCache1 *pCache = pPage->pCache; - PgHdr1 **pp; - - assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); - h = pPage->iKey % pCache->nHash; - for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); - *pp = (*pp)->pNext; - - pCache->nPage--; - if( freeFlag ) pcache1FreePage(pPage); -} - -/* -** If there are currently more than nMaxPage pages allocated, try -** to recycle pages to reduce the number allocated to nMaxPage. -*/ -static void pcache1EnforceMaxPage(PCache1 *pCache){ - PGroup *pGroup = pCache->pGroup; - PgHdr1 *p; - assert( sqlite3_mutex_held(pGroup->mutex) ); - while( pGroup->nCurrentPage>pGroup->nMaxPage - && (p=pGroup->lru.pLruPrev)->isAnchor==0 - ){ - assert( p->pCache->pGroup==pGroup ); - assert( p->isPinned==0 ); - pcache1PinPage(p); - pcache1RemoveFromHash(p, 1); - } - if( pCache->nPage==0 && pCache->pBulk ){ - sqlite3_free(pCache->pBulk); - pCache->pBulk = pCache->pFree = 0; - } -} - -/* -** Discard all pages from cache pCache with a page number (key value) -** greater than or equal to iLimit. Any pinned pages that meet this -** criteria are unpinned before they are discarded. -** -** The PCache mutex must be held when this function is called. -*/ -static void pcache1TruncateUnsafe( - PCache1 *pCache, /* The cache to truncate */ - unsigned int iLimit /* Drop pages with this pgno or larger */ -){ - TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ - unsigned int h, iStop; - assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); - assert( pCache->iMaxKey >= iLimit ); - assert( pCache->nHash > 0 ); - if( pCache->iMaxKey - iLimit < pCache->nHash ){ - /* If we are just shaving the last few pages off the end of the - ** cache, then there is no point in scanning the entire hash table. - ** Only scan those hash slots that might contain pages that need to - ** be removed. */ - h = iLimit % pCache->nHash; - iStop = pCache->iMaxKey % pCache->nHash; - TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ - }else{ - /* This is the general case where many pages are being removed. - ** It is necessary to scan the entire hash table */ - h = pCache->nHash/2; - iStop = h - 1; - } - for(;;){ - PgHdr1 **pp; - PgHdr1 *pPage; - assert( hnHash ); - pp = &pCache->apHash[h]; - while( (pPage = *pp)!=0 ){ - if( pPage->iKey>=iLimit ){ - pCache->nPage--; - *pp = pPage->pNext; - if( !pPage->isPinned ) pcache1PinPage(pPage); - pcache1FreePage(pPage); - }else{ - pp = &pPage->pNext; - TESTONLY( if( nPage>=0 ) nPage++; ) - } - } - if( h==iStop ) break; - h = (h+1) % pCache->nHash; - } - assert( nPage<0 || pCache->nPage==(unsigned)nPage ); -} - -/******************************************************************************/ -/******** sqlite3_pcache Methods **********************************************/ - -/* -** Implementation of the sqlite3_pcache.xInit method. -*/ -static int pcache1Init(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - assert( pcache1.isInit==0 ); - memset(&pcache1, 0, sizeof(pcache1)); - - - /* - ** The pcache1.separateCache variable is true if each PCache has its own - ** private PGroup (mode-1). pcache1.separateCache is false if the single - ** PGroup in pcache1.grp is used for all page caches (mode-2). - ** - ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT - ** - ** * Use a unified cache in single-threaded applications that have - ** configured a start-time buffer for use as page-cache memory using - ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL - ** pBuf argument. - ** - ** * Otherwise use separate caches (mode-1) - */ -#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) - pcache1.separateCache = 0; -#elif SQLITE_THREADSAFE - pcache1.separateCache = sqlite3GlobalConfig.pPage==0 - || sqlite3GlobalConfig.bCoreMutex>0; -#else - pcache1.separateCache = sqlite3GlobalConfig.pPage==0; -#endif - -#if SQLITE_THREADSAFE - if( sqlite3GlobalConfig.bCoreMutex ){ - pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); - pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); - } -#endif - if( pcache1.separateCache - && sqlite3GlobalConfig.nPage!=0 - && sqlite3GlobalConfig.pPage==0 - ){ - pcache1.nInitPage = sqlite3GlobalConfig.nPage; - }else{ - pcache1.nInitPage = 0; - } - pcache1.grp.mxPinned = 10; - pcache1.isInit = 1; - return SQLITE_OK; -} - -/* -** Implementation of the sqlite3_pcache.xShutdown method. -** Note that the static mutex allocated in xInit does -** not need to be freed. -*/ -static void pcache1Shutdown(void *NotUsed){ - UNUSED_PARAMETER(NotUsed); - assert( pcache1.isInit!=0 ); - memset(&pcache1, 0, sizeof(pcache1)); -} - -/* forward declaration */ -static void pcache1Destroy(sqlite3_pcache *p); - -/* -** Implementation of the sqlite3_pcache.xCreate method. -** -** Allocate a new cache. -*/ -static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ - PCache1 *pCache; /* The newly created page cache */ - PGroup *pGroup; /* The group the new page cache will belong to */ - int sz; /* Bytes of memory required to allocate the new cache */ - - assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); - assert( szExtra < 300 ); - - sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache; - pCache = (PCache1 *)sqlite3MallocZero(sz); - if( pCache ){ - if( pcache1.separateCache ){ - pGroup = (PGroup*)&pCache[1]; - pGroup->mxPinned = 10; - }else{ - pGroup = &pcache1.grp; - } - if( pGroup->lru.isAnchor==0 ){ - pGroup->lru.isAnchor = 1; - pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru; - } - pCache->pGroup = pGroup; - pCache->szPage = szPage; - pCache->szExtra = szExtra; - pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1)); - pCache->bPurgeable = (bPurgeable ? 1 : 0); - pcache1EnterMutex(pGroup); - pcache1ResizeHash(pCache); - if( bPurgeable ){ - pCache->nMin = 10; - pGroup->nMinPage += pCache->nMin; - pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; - } - pcache1LeaveMutex(pGroup); - if( pCache->nHash==0 ){ - pcache1Destroy((sqlite3_pcache*)pCache); - pCache = 0; - } - } - return (sqlite3_pcache *)pCache; -} - -/* -** Implementation of the sqlite3_pcache.xCachesize method. -** -** Configure the cache_size limit for a cache. -*/ -static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ - PCache1 *pCache = (PCache1 *)p; - if( pCache->bPurgeable ){ - PGroup *pGroup = pCache->pGroup; - pcache1EnterMutex(pGroup); - pGroup->nMaxPage += (nMax - pCache->nMax); - pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; - pCache->nMax = nMax; - pCache->n90pct = pCache->nMax*9/10; - pcache1EnforceMaxPage(pCache); - pcache1LeaveMutex(pGroup); - } -} - -/* -** Implementation of the sqlite3_pcache.xShrink method. -** -** Free up as much memory as possible. -*/ -static void pcache1Shrink(sqlite3_pcache *p){ - PCache1 *pCache = (PCache1*)p; - if( pCache->bPurgeable ){ - PGroup *pGroup = pCache->pGroup; - int savedMaxPage; - pcache1EnterMutex(pGroup); - savedMaxPage = pGroup->nMaxPage; - pGroup->nMaxPage = 0; - pcache1EnforceMaxPage(pCache); - pGroup->nMaxPage = savedMaxPage; - pcache1LeaveMutex(pGroup); - } -} - -/* -** Implementation of the sqlite3_pcache.xPagecount method. -*/ -static int pcache1Pagecount(sqlite3_pcache *p){ - int n; - PCache1 *pCache = (PCache1*)p; - pcache1EnterMutex(pCache->pGroup); - n = pCache->nPage; - pcache1LeaveMutex(pCache->pGroup); - return n; -} - - -/* -** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described -** in the header of the pcache1Fetch() procedure. -** -** This steps are broken out into a separate procedure because they are -** usually not needed, and by avoiding the stack initialization required -** for these steps, the main pcache1Fetch() procedure can run faster. -*/ -static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( - PCache1 *pCache, - unsigned int iKey, - int createFlag -){ - unsigned int nPinned; - PGroup *pGroup = pCache->pGroup; - PgHdr1 *pPage = 0; - - /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ - assert( pCache->nPage >= pCache->nRecyclable ); - nPinned = pCache->nPage - pCache->nRecyclable; - assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); - assert( pCache->n90pct == pCache->nMax*9/10 ); - if( createFlag==1 && ( - nPinned>=pGroup->mxPinned - || nPinned>=pCache->n90pct - || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclablenPage>=pCache->nHash ) pcache1ResizeHash(pCache); - assert( pCache->nHash>0 && pCache->apHash ); - - /* Step 4. Try to recycle a page. */ - if( pCache->bPurgeable - && !pGroup->lru.pLruPrev->isAnchor - && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache)) - ){ - PCache1 *pOther; - pPage = pGroup->lru.pLruPrev; - assert( pPage->isPinned==0 ); - pcache1RemoveFromHash(pPage, 0); - pcache1PinPage(pPage); - pOther = pPage->pCache; - if( pOther->szAlloc != pCache->szAlloc ){ - pcache1FreePage(pPage); - pPage = 0; - }else{ - pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable); - } - } - - /* Step 5. If a usable page buffer has still not been found, - ** attempt to allocate a new one. - */ - if( !pPage ){ - pPage = pcache1AllocPage(pCache, createFlag==1); - } - - if( pPage ){ - unsigned int h = iKey % pCache->nHash; - pCache->nPage++; - pPage->iKey = iKey; - pPage->pNext = pCache->apHash[h]; - pPage->pCache = pCache; - pPage->pLruPrev = 0; - pPage->pLruNext = 0; - pPage->isPinned = 1; - *(void **)pPage->page.pExtra = 0; - pCache->apHash[h] = pPage; - if( iKey>pCache->iMaxKey ){ - pCache->iMaxKey = iKey; - } - } - return pPage; -} - -/* -** Implementation of the sqlite3_pcache.xFetch method. -** -** Fetch a page by key value. -** -** Whether or not a new page may be allocated by this function depends on -** the value of the createFlag argument. 0 means do not allocate a new -** page. 1 means allocate a new page if space is easily available. 2 -** means to try really hard to allocate a new page. -** -** For a non-purgeable cache (a cache used as the storage for an in-memory -** database) there is really no difference between createFlag 1 and 2. So -** the calling function (pcache.c) will never have a createFlag of 1 on -** a non-purgeable cache. -** -** There are three different approaches to obtaining space for a page, -** depending on the value of parameter createFlag (which may be 0, 1 or 2). -** -** 1. Regardless of the value of createFlag, the cache is searched for a -** copy of the requested page. If one is found, it is returned. -** -** 2. If createFlag==0 and the page is not already in the cache, NULL is -** returned. -** -** 3. If createFlag is 1, and the page is not already in the cache, then -** return NULL (do not allocate a new page) if any of the following -** conditions are true: -** -** (a) the number of pages pinned by the cache is greater than -** PCache1.nMax, or -** -** (b) the number of pages pinned by the cache is greater than -** the sum of nMax for all purgeable caches, less the sum of -** nMin for all other purgeable caches, or -** -** 4. If none of the first three conditions apply and the cache is marked -** as purgeable, and if one of the following is true: -** -** (a) The number of pages allocated for the cache is already -** PCache1.nMax, or -** -** (b) The number of pages allocated for all purgeable caches is -** already equal to or greater than the sum of nMax for all -** purgeable caches, -** -** (c) The system is under memory pressure and wants to avoid -** unnecessary pages cache entry allocations -** -** then attempt to recycle a page from the LRU list. If it is the right -** size, return the recycled buffer. Otherwise, free the buffer and -** proceed to step 5. -** -** 5. Otherwise, allocate and return a new page buffer. -** -** There are two versions of this routine. pcache1FetchWithMutex() is -** the general case. pcache1FetchNoMutex() is a faster implementation for -** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper -** invokes the appropriate routine. -*/ -static PgHdr1 *pcache1FetchNoMutex( - sqlite3_pcache *p, - unsigned int iKey, - int createFlag -){ - PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = 0; - - /* Step 1: Search the hash table for an existing entry. */ - pPage = pCache->apHash[iKey % pCache->nHash]; - while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } - - /* Step 2: If the page was found in the hash table, then return it. - ** If the page was not in the hash table and createFlag is 0, abort. - ** Otherwise (page not in hash and createFlag!=0) continue with - ** subsequent steps to try to create the page. */ - if( pPage ){ - if( !pPage->isPinned ){ - return pcache1PinPage(pPage); - }else{ - return pPage; - } - }else if( createFlag ){ - /* Steps 3, 4, and 5 implemented by this subroutine */ - return pcache1FetchStage2(pCache, iKey, createFlag); - }else{ - return 0; - } -} -#if PCACHE1_MIGHT_USE_GROUP_MUTEX -static PgHdr1 *pcache1FetchWithMutex( - sqlite3_pcache *p, - unsigned int iKey, - int createFlag -){ - PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage; - - pcache1EnterMutex(pCache->pGroup); - pPage = pcache1FetchNoMutex(p, iKey, createFlag); - assert( pPage==0 || pCache->iMaxKey>=iKey ); - pcache1LeaveMutex(pCache->pGroup); - return pPage; -} -#endif -static sqlite3_pcache_page *pcache1Fetch( - sqlite3_pcache *p, - unsigned int iKey, - int createFlag -){ -#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG) - PCache1 *pCache = (PCache1 *)p; -#endif - - assert( offsetof(PgHdr1,page)==0 ); - assert( pCache->bPurgeable || createFlag!=1 ); - assert( pCache->bPurgeable || pCache->nMin==0 ); - assert( pCache->bPurgeable==0 || pCache->nMin==10 ); - assert( pCache->nMin==0 || pCache->bPurgeable ); - assert( pCache->nHash>0 ); -#if PCACHE1_MIGHT_USE_GROUP_MUTEX - if( pCache->pGroup->mutex ){ - return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); - }else -#endif - { - return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); - } -} - - -/* -** Implementation of the sqlite3_pcache.xUnpin method. -** -** Mark a page as unpinned (eligible for asynchronous recycling). -*/ -static void pcache1Unpin( - sqlite3_pcache *p, - sqlite3_pcache_page *pPg, - int reuseUnlikely -){ - PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = (PgHdr1 *)pPg; - PGroup *pGroup = pCache->pGroup; - - assert( pPage->pCache==pCache ); - pcache1EnterMutex(pGroup); - - /* It is an error to call this function if the page is already - ** part of the PGroup LRU list. - */ - assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); - assert( pPage->isPinned==1 ); - - if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){ - pcache1RemoveFromHash(pPage, 1); - }else{ - /* Add the page to the PGroup LRU list. */ - PgHdr1 **ppFirst = &pGroup->lru.pLruNext; - pPage->pLruPrev = &pGroup->lru; - (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; - *ppFirst = pPage; - pCache->nRecyclable++; - pPage->isPinned = 0; - } - - pcache1LeaveMutex(pCache->pGroup); -} - -/* -** Implementation of the sqlite3_pcache.xRekey method. -*/ -static void pcache1Rekey( - sqlite3_pcache *p, - sqlite3_pcache_page *pPg, - unsigned int iOld, - unsigned int iNew -){ - PCache1 *pCache = (PCache1 *)p; - PgHdr1 *pPage = (PgHdr1 *)pPg; - PgHdr1 **pp; - unsigned int h; - assert( pPage->iKey==iOld ); - assert( pPage->pCache==pCache ); - - pcache1EnterMutex(pCache->pGroup); - - h = iOld%pCache->nHash; - pp = &pCache->apHash[h]; - while( (*pp)!=pPage ){ - pp = &(*pp)->pNext; - } - *pp = pPage->pNext; - - h = iNew%pCache->nHash; - pPage->iKey = iNew; - pPage->pNext = pCache->apHash[h]; - pCache->apHash[h] = pPage; - if( iNew>pCache->iMaxKey ){ - pCache->iMaxKey = iNew; - } - - pcache1LeaveMutex(pCache->pGroup); -} - -/* -** Implementation of the sqlite3_pcache.xTruncate method. -** -** Discard all unpinned pages in the cache with a page number equal to -** or greater than parameter iLimit. Any pinned pages with a page number -** equal to or greater than iLimit are implicitly unpinned. -*/ -static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ - PCache1 *pCache = (PCache1 *)p; - pcache1EnterMutex(pCache->pGroup); - if( iLimit<=pCache->iMaxKey ){ - pcache1TruncateUnsafe(pCache, iLimit); - pCache->iMaxKey = iLimit-1; - } - pcache1LeaveMutex(pCache->pGroup); -} - -/* -** Implementation of the sqlite3_pcache.xDestroy method. -** -** Destroy a cache allocated using pcache1Create(). -*/ -static void pcache1Destroy(sqlite3_pcache *p){ - PCache1 *pCache = (PCache1 *)p; - PGroup *pGroup = pCache->pGroup; - assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); - pcache1EnterMutex(pGroup); - if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0); - assert( pGroup->nMaxPage >= pCache->nMax ); - pGroup->nMaxPage -= pCache->nMax; - assert( pGroup->nMinPage >= pCache->nMin ); - pGroup->nMinPage -= pCache->nMin; - pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; - pcache1EnforceMaxPage(pCache); - pcache1LeaveMutex(pGroup); - sqlite3_free(pCache->pBulk); - sqlite3_free(pCache->apHash); - sqlite3_free(pCache); -} - -/* -** This function is called during initialization (sqlite3_initialize()) to -** install the default pluggable cache module, assuming the user has not -** already provided an alternative. -*/ -SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ - static const sqlite3_pcache_methods2 defaultMethods = { - 1, /* iVersion */ - 0, /* pArg */ - pcache1Init, /* xInit */ - pcache1Shutdown, /* xShutdown */ - pcache1Create, /* xCreate */ - pcache1Cachesize, /* xCachesize */ - pcache1Pagecount, /* xPagecount */ - pcache1Fetch, /* xFetch */ - pcache1Unpin, /* xUnpin */ - pcache1Rekey, /* xRekey */ - pcache1Truncate, /* xTruncate */ - pcache1Destroy, /* xDestroy */ - pcache1Shrink /* xShrink */ - }; - sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); -} - -/* -** Return the size of the header on each page of this PCACHE implementation. -*/ -SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } - -/* -** Return the global mutex used by this PCACHE implementation. The -** sqlite3_status() routine needs access to this mutex. -*/ -SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ - return pcache1.mutex; -} - -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT -/* -** This function is called to free superfluous dynamically allocated memory -** held by the pager system. Memory in use by any SQLite pager allocated -** by the current thread may be sqlite3_free()ed. -** -** nReq is the number of bytes of memory required. Once this much has -** been released, the function returns. The return value is the total number -** of bytes of memory released. -*/ -SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ - int nFree = 0; - assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); - assert( sqlite3_mutex_notheld(pcache1.mutex) ); - if( sqlite3GlobalConfig.nPage==0 ){ - PgHdr1 *p; - pcache1EnterMutex(&pcache1.grp); - while( (nReq<0 || nFreeisAnchor==0 - ){ - nFree += pcache1MemSize(p->page.pBuf); -#ifdef SQLITE_PCACHE_SEPARATE_HEADER - nFree += sqlite3MemSize(p); -#endif - assert( p->isPinned==0 ); - pcache1PinPage(p); - pcache1RemoveFromHash(p, 1); - } - pcache1LeaveMutex(&pcache1.grp); - } - return nFree; -} -#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ - -#ifdef SQLITE_TEST -/* -** This function is used by test procedures to inspect the internal state -** of the global cache. -*/ -SQLITE_PRIVATE void sqlite3PcacheStats( - int *pnCurrent, /* OUT: Total number of pages cached */ - int *pnMax, /* OUT: Global maximum cache size */ - int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ - int *pnRecyclable /* OUT: Total number of pages available for recycling */ -){ - PgHdr1 *p; - int nRecyclable = 0; - for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){ - assert( p->isPinned==0 ); - nRecyclable++; - } - *pnCurrent = pcache1.grp.nCurrentPage; - *pnMax = (int)pcache1.grp.nMaxPage; - *pnMin = (int)pcache1.grp.nMinPage; - *pnRecyclable = nRecyclable; -} -#endif - -/************** End of pcache1.c *********************************************/ -/************** Begin file rowset.c ******************************************/ -/* -** 2008 December 3 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This module implements an object we call a "RowSet". -** -** The RowSet object is a collection of rowids. Rowids -** are inserted into the RowSet in an arbitrary order. Inserts -** can be intermixed with tests to see if a given rowid has been -** previously inserted into the RowSet. -** -** After all inserts are finished, it is possible to extract the -** elements of the RowSet in sorted order. Once this extraction -** process has started, no new elements may be inserted. -** -** Hence, the primitive operations for a RowSet are: -** -** CREATE -** INSERT -** TEST -** SMALLEST -** DESTROY -** -** The CREATE and DESTROY primitives are the constructor and destructor, -** obviously. The INSERT primitive adds a new element to the RowSet. -** TEST checks to see if an element is already in the RowSet. SMALLEST -** extracts the least value from the RowSet. -** -** The INSERT primitive might allocate additional memory. Memory is -** allocated in chunks so most INSERTs do no allocation. There is an -** upper bound on the size of allocated memory. No memory is freed -** until DESTROY. -** -** The TEST primitive includes a "batch" number. The TEST primitive -** will only see elements that were inserted before the last change -** in the batch number. In other words, if an INSERT occurs between -** two TESTs where the TESTs have the same batch nubmer, then the -** value added by the INSERT will not be visible to the second TEST. -** The initial batch number is zero, so if the very first TEST contains -** a non-zero batch number, it will see all prior INSERTs. -** -** No INSERTs may occurs after a SMALLEST. An assertion will fail if -** that is attempted. -** -** The cost of an INSERT is roughly constant. (Sometimes new memory -** has to be allocated on an INSERT.) The cost of a TEST with a new -** batch number is O(NlogN) where N is the number of elements in the RowSet. -** The cost of a TEST using the same batch number is O(logN). The cost -** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST -** primitives are constant time. The cost of DESTROY is O(N). -** -** TEST and SMALLEST may not be used by the same RowSet. This used to -** be possible, but the feature was not used, so it was removed in order -** to simplify the code. -*/ -/* #include "sqliteInt.h" */ - - -/* -** Target size for allocation chunks. -*/ -#define ROWSET_ALLOCATION_SIZE 1024 - -/* -** The number of rowset entries per allocation chunk. -*/ -#define ROWSET_ENTRY_PER_CHUNK \ - ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) - -/* -** Each entry in a RowSet is an instance of the following object. -** -** This same object is reused to store a linked list of trees of RowSetEntry -** objects. In that alternative use, pRight points to the next entry -** in the list, pLeft points to the tree, and v is unused. The -** RowSet.pForest value points to the head of this forest list. -*/ -struct RowSetEntry { - i64 v; /* ROWID value for this entry */ - struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ - struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ -}; - -/* -** RowSetEntry objects are allocated in large chunks (instances of the -** following structure) to reduce memory allocation overhead. The -** chunks are kept on a linked list so that they can be deallocated -** when the RowSet is destroyed. -*/ -struct RowSetChunk { - struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */ - struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */ -}; - -/* -** A RowSet in an instance of the following structure. -** -** A typedef of this structure if found in sqliteInt.h. -*/ -struct RowSet { - struct RowSetChunk *pChunk; /* List of all chunk allocations */ - sqlite3 *db; /* The database connection */ - struct RowSetEntry *pEntry; /* List of entries using pRight */ - struct RowSetEntry *pLast; /* Last entry on the pEntry list */ - struct RowSetEntry *pFresh; /* Source of new entry objects */ - struct RowSetEntry *pForest; /* List of binary trees of entries */ - u16 nFresh; /* Number of objects on pFresh */ - u16 rsFlags; /* Various flags */ - int iBatch; /* Current insert batch */ -}; - -/* -** Allowed values for RowSet.rsFlags -*/ -#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ -#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ - -/* -** Turn bulk memory into a RowSet object. N bytes of memory -** are available at pSpace. The db pointer is used as a memory context -** for any subsequent allocations that need to occur. -** Return a pointer to the new RowSet object. -** -** It must be the case that N is sufficient to make a Rowset. If not -** an assertion fault occurs. -** -** If N is larger than the minimum, use the surplus as an initial -** allocation of entries available to be filled. -*/ -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ - RowSet *p; - assert( N >= ROUND8(sizeof(*p)) ); - p = pSpace; - p->pChunk = 0; - p->db = db; - p->pEntry = 0; - p->pLast = 0; - p->pForest = 0; - p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); - p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); - p->rsFlags = ROWSET_SORTED; - p->iBatch = 0; - return p; -} - -/* -** Deallocate all chunks from a RowSet. This frees all memory that -** the RowSet has allocated over its lifetime. This routine is -** the destructor for the RowSet. -*/ -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ - struct RowSetChunk *pChunk, *pNextChunk; - for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ - pNextChunk = pChunk->pNextChunk; - sqlite3DbFree(p->db, pChunk); - } - p->pChunk = 0; - p->nFresh = 0; - p->pEntry = 0; - p->pLast = 0; - p->pForest = 0; - p->rsFlags = ROWSET_SORTED; -} - -/* -** Allocate a new RowSetEntry object that is associated with the -** given RowSet. Return a pointer to the new and completely uninitialized -** objected. -** -** In an OOM situation, the RowSet.db->mallocFailed flag is set and this -** routine returns NULL. -*/ -static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ - assert( p!=0 ); - if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/ - /* We could allocate a fresh RowSetEntry each time one is needed, but it - ** is more efficient to pull a preallocated entry from the pool */ - struct RowSetChunk *pNew; - pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); - if( pNew==0 ){ - return 0; - } - pNew->pNextChunk = p->pChunk; - p->pChunk = pNew; - p->pFresh = pNew->aEntry; - p->nFresh = ROWSET_ENTRY_PER_CHUNK; - } - p->nFresh--; - return p->pFresh++; -} - -/* -** Insert a new value into a RowSet. -** -** The mallocFailed flag of the database connection is set if a -** memory allocation fails. -*/ -SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ - struct RowSetEntry *pEntry; /* The new entry */ - struct RowSetEntry *pLast; /* The last prior entry */ - - /* This routine is never called after sqlite3RowSetNext() */ - assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); - - pEntry = rowSetEntryAlloc(p); - if( pEntry==0 ) return; - pEntry->v = rowid; - pEntry->pRight = 0; - pLast = p->pLast; - if( pLast ){ - if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/ - /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags - ** where possible */ - p->rsFlags &= ~ROWSET_SORTED; - } - pLast->pRight = pEntry; - }else{ - p->pEntry = pEntry; - } - p->pLast = pEntry; -} - -/* -** Merge two lists of RowSetEntry objects. Remove duplicates. -** -** The input lists are connected via pRight pointers and are -** assumed to each already be in sorted order. -*/ -static struct RowSetEntry *rowSetEntryMerge( - struct RowSetEntry *pA, /* First sorted list to be merged */ - struct RowSetEntry *pB /* Second sorted list to be merged */ -){ - struct RowSetEntry head; - struct RowSetEntry *pTail; - - pTail = &head; - assert( pA!=0 && pB!=0 ); - for(;;){ - assert( pA->pRight==0 || pA->v<=pA->pRight->v ); - assert( pB->pRight==0 || pB->v<=pB->pRight->v ); - if( pA->v<=pB->v ){ - if( pA->vv ) pTail = pTail->pRight = pA; - pA = pA->pRight; - if( pA==0 ){ - pTail->pRight = pB; - break; - } - }else{ - pTail = pTail->pRight = pB; - pB = pB->pRight; - if( pB==0 ){ - pTail->pRight = pA; - break; - } - } - } - return head.pRight; -} - -/* -** Sort all elements on the list of RowSetEntry objects into order of -** increasing v. -*/ -static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ - unsigned int i; - struct RowSetEntry *pNext, *aBucket[40]; - - memset(aBucket, 0, sizeof(aBucket)); - while( pIn ){ - pNext = pIn->pRight; - pIn->pRight = 0; - for(i=0; aBucket[i]; i++){ - pIn = rowSetEntryMerge(aBucket[i], pIn); - aBucket[i] = 0; - } - aBucket[i] = pIn; - pIn = pNext; - } - pIn = aBucket[0]; - for(i=1; ipLeft ){ - struct RowSetEntry *p; - rowSetTreeToList(pIn->pLeft, ppFirst, &p); - p->pRight = pIn; - }else{ - *ppFirst = pIn; - } - if( pIn->pRight ){ - rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast); - }else{ - *ppLast = pIn; - } - assert( (*ppLast)->pRight==0 ); -} - - -/* -** Convert a sorted list of elements (connected by pRight) into a binary -** tree with depth of iDepth. A depth of 1 means the tree contains a single -** node taken from the head of *ppList. A depth of 2 means a tree with -** three nodes. And so forth. -** -** Use as many entries from the input list as required and update the -** *ppList to point to the unused elements of the list. If the input -** list contains too few elements, then construct an incomplete tree -** and leave *ppList set to NULL. -** -** Return a pointer to the root of the constructed binary tree. -*/ -static struct RowSetEntry *rowSetNDeepTree( - struct RowSetEntry **ppList, - int iDepth -){ - struct RowSetEntry *p; /* Root of the new tree */ - struct RowSetEntry *pLeft; /* Left subtree */ - if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* Prevent unnecessary deep recursion when we run out of entries */ - return 0; - } - if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ - /* This branch causes a *balanced* tree to be generated. A valid tree - ** is still generated without this branch, but the tree is wildly - ** unbalanced and inefficient. */ - pLeft = rowSetNDeepTree(ppList, iDepth-1); - p = *ppList; - if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/ - /* It is safe to always return here, but the resulting tree - ** would be unbalanced */ - return pLeft; - } - p->pLeft = pLeft; - *ppList = p->pRight; - p->pRight = rowSetNDeepTree(ppList, iDepth-1); - }else{ - p = *ppList; - *ppList = p->pRight; - p->pLeft = p->pRight = 0; - } - return p; -} - -/* -** Convert a sorted list of elements into a binary tree. Make the tree -** as deep as it needs to be in order to contain the entire list. -*/ -static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ - int iDepth; /* Depth of the tree so far */ - struct RowSetEntry *p; /* Current tree root */ - struct RowSetEntry *pLeft; /* Left subtree */ - - assert( pList!=0 ); - p = pList; - pList = p->pRight; - p->pLeft = p->pRight = 0; - for(iDepth=1; pList; iDepth++){ - pLeft = p; - p = pList; - pList = p->pRight; - p->pLeft = pLeft; - p->pRight = rowSetNDeepTree(&pList, iDepth); - } - return p; -} - -/* -** Extract the smallest element from the RowSet. -** Write the element into *pRowid. Return 1 on success. Return -** 0 if the RowSet is already empty. -** -** After this routine has been called, the sqlite3RowSetInsert() -** routine may not be called again. -** -** This routine may not be called after sqlite3RowSetTest() has -** been used. Older versions of RowSet allowed that, but as the -** capability was not used by the code generator, it was removed -** for code economy. -*/ -SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ - assert( p!=0 ); - assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ - - /* Merge the forest into a single sorted list on first call */ - if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - p->pEntry = rowSetEntrySort(p->pEntry); - } - p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT; - } - - /* Return the next entry on the list */ - if( p->pEntry ){ - *pRowid = p->pEntry->v; - p->pEntry = p->pEntry->pRight; - if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* Free memory immediately, rather than waiting on sqlite3_finalize() */ - sqlite3RowSetClear(p); - } - return 1; - }else{ - return 0; - } -} - -/* -** Check to see if element iRowid was inserted into the rowset as -** part of any insert batch prior to iBatch. Return 1 or 0. -** -** If this is the first test of a new batch and if there exist entries -** on pRowSet->pEntry, then sort those entries into the forest at -** pRowSet->pForest so that they can be tested. -*/ -SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ - struct RowSetEntry *p, *pTree; - - /* This routine is never called after sqlite3RowSetNext() */ - assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); - - /* Sort entries into the forest on the first test of a new batch. - ** To save unnecessary work, only do this when the batch number changes. - */ - if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/ - p = pRowSet->pEntry; - if( p ){ - struct RowSetEntry **ppPrevTree = &pRowSet->pForest; - if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - /* Only sort the current set of entiries if they need it */ - p = rowSetEntrySort(p); - } - for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ - ppPrevTree = &pTree->pRight; - if( pTree->pLeft==0 ){ - pTree->pLeft = rowSetListToTree(p); - break; - }else{ - struct RowSetEntry *pAux, *pTail; - rowSetTreeToList(pTree->pLeft, &pAux, &pTail); - pTree->pLeft = 0; - p = rowSetEntryMerge(pAux, p); - } - } - if( pTree==0 ){ - *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); - if( pTree ){ - pTree->v = 0; - pTree->pRight = 0; - pTree->pLeft = rowSetListToTree(p); - } - } - pRowSet->pEntry = 0; - pRowSet->pLast = 0; - pRowSet->rsFlags |= ROWSET_SORTED; - } - pRowSet->iBatch = iBatch; - } - - /* Test to see if the iRowid value appears anywhere in the forest. - ** Return 1 if it does and 0 if not. - */ - for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ - p = pTree->pLeft; - while( p ){ - if( p->vpRight; - }else if( p->v>iRowid ){ - p = p->pLeft; - }else{ - return 1; - } - } - } - return 0; -} - -/************** End of rowset.c **********************************************/ -/************** Begin file pager.c *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This is the implementation of the page cache subsystem or "pager". -** -** The pager is used to access a database disk file. It implements -** atomic commit and rollback through the use of a journal file that -** is separate from the database file. The pager also implements file -** locking to prevent two processes from writing the same database -** file simultaneously, or one process from reading the database while -** another is writing. -*/ -#ifndef SQLITE_OMIT_DISKIO -/* #include "sqliteInt.h" */ -/************** Include wal.h in the middle of pager.c ***********************/ -/************** Begin file wal.h *********************************************/ -/* -** 2010 February 1 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the interface to the write-ahead logging -** system. Refer to the comments below and the header comment attached to -** the implementation of each function in log.c for further details. -*/ - -#ifndef SQLITE_WAL_H -#define SQLITE_WAL_H - -/* #include "sqliteInt.h" */ - -/* Additional values that can be added to the sync_flags argument of -** sqlite3WalFrames(): -*/ -#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ -#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ - -#ifdef SQLITE_OMIT_WAL -# define sqlite3WalOpen(x,y,z) 0 -# define sqlite3WalLimit(x,y) -# define sqlite3WalClose(w,x,y,z) 0 -# define sqlite3WalBeginReadTransaction(y,z) 0 -# define sqlite3WalEndReadTransaction(z) -# define sqlite3WalDbsize(y) 0 -# define sqlite3WalBeginWriteTransaction(y) 0 -# define sqlite3WalEndWriteTransaction(x) 0 -# define sqlite3WalUndo(x,y,z) 0 -# define sqlite3WalSavepoint(y,z) -# define sqlite3WalSavepointUndo(y,z) 0 -# define sqlite3WalFrames(u,v,w,x,y,z) 0 -# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0 -# define sqlite3WalCallback(z) 0 -# define sqlite3WalExclusiveMode(y,z) 0 -# define sqlite3WalHeapMemory(z) 0 -# define sqlite3WalFramesize(z) 0 -# define sqlite3WalFindFrame(x,y,z) 0 -# define sqlite3WalFile(x) 0 -#else - -#define WAL_SAVEPOINT_NDATA 4 - -/* Connection to a write-ahead log (WAL) file. -** There is one object of this type for each pager. -*/ -typedef struct Wal Wal; - -/* Open and close a connection to a write-ahead log. */ -SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); -SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); - -/* Set the limiting size of a WAL file. */ -SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); - -/* Used by readers to open (lock) and close (unlock) a snapshot. A -** snapshot is like a read-transaction. It is the state of the database -** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and -** preserves the current state even if the other threads or processes -** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the -** transaction and releases the lock. -*/ -SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); -SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); - -/* Read a page from the write-ahead log, if it is present. */ -SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); -SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); - -/* If the WAL is not empty, return the size of the database. */ -SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); - -/* Obtain or release the WRITER lock. */ -SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); -SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); - -/* Undo any frames written (but not committed) to the log */ -SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); - -/* Return an integer that records the current (uncommitted) write -** position in the WAL */ -SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); - -/* Move the write position of the WAL back to iFrame. Called in -** response to a ROLLBACK TO command. */ -SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); - -/* Write a frame or frames to the log. */ -SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); - -/* Copy pages from the log to the database file */ -SQLITE_PRIVATE int sqlite3WalCheckpoint( - Wal *pWal, /* Write-ahead log connection */ - int eMode, /* One of PASSIVE, FULL and RESTART */ - int (*xBusy)(void*), /* Function to call when busy */ - void *pBusyArg, /* Context argument for xBusyHandler */ - int sync_flags, /* Flags to sync db file with (or 0) */ - int nBuf, /* Size of buffer nBuf */ - u8 *zBuf, /* Temporary buffer to use */ - int *pnLog, /* OUT: Number of frames in WAL */ - int *pnCkpt /* OUT: Number of backfilled frames in WAL */ -); - -/* Return the value to pass to a sqlite3_wal_hook callback, the -** number of frames in the WAL at the point of the last commit since -** sqlite3WalCallback() was called. If no commits have occurred since -** the last call, then return 0. -*/ -SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); - -/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) -** by the pager layer on the database file. -*/ -SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); - -/* Return true if the argument is non-NULL and the WAL module is using -** heap-memory for the wal-index. Otherwise, if the argument is NULL or the -** WAL module is using shared-memory, return false. -*/ -SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); - -#ifdef SQLITE_ENABLE_SNAPSHOT -SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); -SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); -#endif - -#ifdef SQLITE_ENABLE_ZIPVFS -/* If the WAL file is not empty, return the number of bytes of content -** stored in each frame (i.e. the db page-size when the WAL was created). -*/ -SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); -#endif - -/* Return the sqlite3_file object for the WAL file */ -SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); - -#endif /* ifndef SQLITE_OMIT_WAL */ -#endif /* SQLITE_WAL_H */ - -/************** End of wal.h *************************************************/ -/************** Continuing where we left off in pager.c **********************/ - - -/******************* NOTES ON THE DESIGN OF THE PAGER ************************ -** -** This comment block describes invariants that hold when using a rollback -** journal. These invariants do not apply for journal_mode=WAL, -** journal_mode=MEMORY, or journal_mode=OFF. -** -** Within this comment block, a page is deemed to have been synced -** automatically as soon as it is written when PRAGMA synchronous=OFF. -** Otherwise, the page is not synced until the xSync method of the VFS -** is called successfully on the file containing the page. -** -** Definition: A page of the database file is said to be "overwriteable" if -** one or more of the following are true about the page: -** -** (a) The original content of the page as it was at the beginning of -** the transaction has been written into the rollback journal and -** synced. -** -** (b) The page was a freelist leaf page at the start of the transaction. -** -** (c) The page number is greater than the largest page that existed in -** the database file at the start of the transaction. -** -** (1) A page of the database file is never overwritten unless one of the -** following are true: -** -** (a) The page and all other pages on the same sector are overwriteable. -** -** (b) The atomic page write optimization is enabled, and the entire -** transaction other than the update of the transaction sequence -** number consists of a single page change. -** -** (2) The content of a page written into the rollback journal exactly matches -** both the content in the database when the rollback journal was written -** and the content in the database at the beginning of the current -** transaction. -** -** (3) Writes to the database file are an integer multiple of the page size -** in length and are aligned on a page boundary. -** -** (4) Reads from the database file are either aligned on a page boundary and -** an integer multiple of the page size in length or are taken from the -** first 100 bytes of the database file. -** -** (5) All writes to the database file are synced prior to the rollback journal -** being deleted, truncated, or zeroed. -** -** (6) If a master journal file is used, then all writes to the database file -** are synced prior to the master journal being deleted. -** -** Definition: Two databases (or the same database at two points it time) -** are said to be "logically equivalent" if they give the same answer to -** all queries. Note in particular the content of freelist leaf -** pages can be changed arbitrarily without affecting the logical equivalence -** of the database. -** -** (7) At any time, if any subset, including the empty set and the total set, -** of the unsynced changes to a rollback journal are removed and the -** journal is rolled back, the resulting database file will be logically -** equivalent to the database file at the beginning of the transaction. -** -** (8) When a transaction is rolled back, the xTruncate method of the VFS -** is called to restore the database file to the same size it was at -** the beginning of the transaction. (In some VFSes, the xTruncate -** method is a no-op, but that does not change the fact the SQLite will -** invoke it.) -** -** (9) Whenever the database file is modified, at least one bit in the range -** of bytes from 24 through 39 inclusive will be changed prior to releasing -** the EXCLUSIVE lock, thus signaling other connections on the same -** database to flush their caches. -** -** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less -** than one billion transactions. -** -** (11) A database file is well-formed at the beginning and at the conclusion -** of every transaction. -** -** (12) An EXCLUSIVE lock is held on the database file when writing to -** the database file. -** -** (13) A SHARED lock is held on the database file while reading any -** content out of the database file. -** -******************************************************************************/ - -/* -** Macros for troubleshooting. Normally turned off -*/ -#if 0 -int sqlite3PagerTrace=1; /* True to enable tracing */ -#define sqlite3DebugPrintf printf -#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } -#else -#define PAGERTRACE(X) -#endif - -/* -** The following two macros are used within the PAGERTRACE() macros above -** to print out file-descriptors. -** -** PAGERID() takes a pointer to a Pager struct as its argument. The -** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file -** struct as its argument. -*/ -#define PAGERID(p) ((int)(p->fd)) -#define FILEHANDLEID(fd) ((int)fd) - -/* -** The Pager.eState variable stores the current 'state' of a pager. A -** pager may be in any one of the seven states shown in the following -** state diagram. -** -** OPEN <------+------+ -** | | | -** V | | -** +---------> READER-------+ | -** | | | -** | V | -** |<-------WRITER_LOCKED------> ERROR -** | | ^ -** | V | -** |<------WRITER_CACHEMOD-------->| -** | | | -** | V | -** |<-------WRITER_DBMOD---------->| -** | | | -** | V | -** +<------WRITER_FINISHED-------->+ -** -** -** List of state transitions and the C [function] that performs each: -** -** OPEN -> READER [sqlite3PagerSharedLock] -** READER -> OPEN [pager_unlock] -** -** READER -> WRITER_LOCKED [sqlite3PagerBegin] -** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] -** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] -** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] -** WRITER_*** -> READER [pager_end_transaction] -** -** WRITER_*** -> ERROR [pager_error] -** ERROR -> OPEN [pager_unlock] -** -** -** OPEN: -** -** The pager starts up in this state. Nothing is guaranteed in this -** state - the file may or may not be locked and the database size is -** unknown. The database may not be read or written. -** -** * No read or write transaction is active. -** * Any lock, or no lock at all, may be held on the database file. -** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. -** -** READER: -** -** In this state all the requirements for reading the database in -** rollback (non-WAL) mode are met. Unless the pager is (or recently -** was) in exclusive-locking mode, a user-level read transaction is -** open. The database size is known in this state. -** -** A connection running with locking_mode=normal enters this state when -** it opens a read-transaction on the database and returns to state -** OPEN after the read-transaction is completed. However a connection -** running in locking_mode=exclusive (including temp databases) remains in -** this state even after the read-transaction is closed. The only way -** a locking_mode=exclusive connection can transition from READER to OPEN -** is via the ERROR state (see below). -** -** * A read transaction may be active (but a write-transaction cannot). -** * A SHARED or greater lock is held on the database file. -** * The dbSize variable may be trusted (even if a user-level read -** transaction is not active). The dbOrigSize and dbFileSize variables -** may not be trusted at this point. -** * If the database is a WAL database, then the WAL connection is open. -** * Even if a read-transaction is not open, it is guaranteed that -** there is no hot-journal in the file-system. -** -** WRITER_LOCKED: -** -** The pager moves to this state from READER when a write-transaction -** is first opened on the database. In WRITER_LOCKED state, all locks -** required to start a write-transaction are held, but no actual -** modifications to the cache or database have taken place. -** -** In rollback mode, a RESERVED or (if the transaction was opened with -** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when -** moving to this state, but the journal file is not written to or opened -** to in this state. If the transaction is committed or rolled back while -** in WRITER_LOCKED state, all that is required is to unlock the database -** file. -** -** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. -** If the connection is running with locking_mode=exclusive, an attempt -** is made to obtain an EXCLUSIVE lock on the database file. -** -** * A write transaction is active. -** * If the connection is open in rollback-mode, a RESERVED or greater -** lock is held on the database file. -** * If the connection is open in WAL-mode, a WAL write transaction -** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully -** called). -** * The dbSize, dbOrigSize and dbFileSize variables are all valid. -** * The contents of the pager cache have not been modified. -** * The journal file may or may not be open. -** * Nothing (not even the first header) has been written to the journal. -** -** WRITER_CACHEMOD: -** -** A pager moves from WRITER_LOCKED state to this state when a page is -** first modified by the upper layer. In rollback mode the journal file -** is opened (if it is not already open) and a header written to the -** start of it. The database file on disk has not been modified. -** -** * A write transaction is active. -** * A RESERVED or greater lock is held on the database file. -** * The journal file is open and the first header has been written -** to it, but the header has not been synced to disk. -** * The contents of the page cache have been modified. -** -** WRITER_DBMOD: -** -** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state -** when it modifies the contents of the database file. WAL connections -** never enter this state (since they do not modify the database file, -** just the log file). -** -** * A write transaction is active. -** * An EXCLUSIVE or greater lock is held on the database file. -** * The journal file is open and the first header has been written -** and synced to disk. -** * The contents of the page cache have been modified (and possibly -** written to disk). -** -** WRITER_FINISHED: -** -** It is not possible for a WAL connection to enter this state. -** -** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD -** state after the entire transaction has been successfully written into the -** database file. In this state the transaction may be committed simply -** by finalizing the journal file. Once in WRITER_FINISHED state, it is -** not possible to modify the database further. At this point, the upper -** layer must either commit or rollback the transaction. -** -** * A write transaction is active. -** * An EXCLUSIVE or greater lock is held on the database file. -** * All writing and syncing of journal and database data has finished. -** If no error occurred, all that remains is to finalize the journal to -** commit the transaction. If an error did occur, the caller will need -** to rollback the transaction. -** -** ERROR: -** -** The ERROR state is entered when an IO or disk-full error (including -** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it -** difficult to be sure that the in-memory pager state (cache contents, -** db size etc.) are consistent with the contents of the file-system. -** -** Temporary pager files may enter the ERROR state, but in-memory pagers -** cannot. -** -** For example, if an IO error occurs while performing a rollback, -** the contents of the page-cache may be left in an inconsistent state. -** At this point it would be dangerous to change back to READER state -** (as usually happens after a rollback). Any subsequent readers might -** report database corruption (due to the inconsistent cache), and if -** they upgrade to writers, they may inadvertently corrupt the database -** file. To avoid this hazard, the pager switches into the ERROR state -** instead of READER following such an error. -** -** Once it has entered the ERROR state, any attempt to use the pager -** to read or write data returns an error. Eventually, once all -** outstanding transactions have been abandoned, the pager is able to -** transition back to OPEN state, discarding the contents of the -** page-cache and any other in-memory state at the same time. Everything -** is reloaded from disk (and, if necessary, hot-journal rollback peformed) -** when a read-transaction is next opened on the pager (transitioning -** the pager into READER state). At that point the system has recovered -** from the error. -** -** Specifically, the pager jumps into the ERROR state if: -** -** 1. An error occurs while attempting a rollback. This happens in -** function sqlite3PagerRollback(). -** -** 2. An error occurs while attempting to finalize a journal file -** following a commit in function sqlite3PagerCommitPhaseTwo(). -** -** 3. An error occurs while attempting to write to the journal or -** database file in function pagerStress() in order to free up -** memory. -** -** In other cases, the error is returned to the b-tree layer. The b-tree -** layer then attempts a rollback operation. If the error condition -** persists, the pager enters the ERROR state via condition (1) above. -** -** Condition (3) is necessary because it can be triggered by a read-only -** statement executed within a transaction. In this case, if the error -** code were simply returned to the user, the b-tree layer would not -** automatically attempt a rollback, as it assumes that an error in a -** read-only statement cannot leave the pager in an internally inconsistent -** state. -** -** * The Pager.errCode variable is set to something other than SQLITE_OK. -** * There are one or more outstanding references to pages (after the -** last reference is dropped the pager should move back to OPEN state). -** * The pager is not an in-memory pager. -** -** -** Notes: -** -** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the -** connection is open in WAL mode. A WAL connection is always in one -** of the first four states. -** -** * Normally, a connection open in exclusive mode is never in PAGER_OPEN -** state. There are two exceptions: immediately after exclusive-mode has -** been turned on (and before any read or write transactions are -** executed), and when the pager is leaving the "error state". -** -** * See also: assert_pager_state(). -*/ -#define PAGER_OPEN 0 -#define PAGER_READER 1 -#define PAGER_WRITER_LOCKED 2 -#define PAGER_WRITER_CACHEMOD 3 -#define PAGER_WRITER_DBMOD 4 -#define PAGER_WRITER_FINISHED 5 -#define PAGER_ERROR 6 - -/* -** The Pager.eLock variable is almost always set to one of the -** following locking-states, according to the lock currently held on -** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. -** This variable is kept up to date as locks are taken and released by -** the pagerLockDb() and pagerUnlockDb() wrappers. -** -** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY -** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not -** the operation was successful. In these circumstances pagerLockDb() and -** pagerUnlockDb() take a conservative approach - eLock is always updated -** when unlocking the file, and only updated when locking the file if the -** VFS call is successful. This way, the Pager.eLock variable may be set -** to a less exclusive (lower) value than the lock that is actually held -** at the system level, but it is never set to a more exclusive value. -** -** This is usually safe. If an xUnlock fails or appears to fail, there may -** be a few redundant xLock() calls or a lock may be held for longer than -** required, but nothing really goes wrong. -** -** The exception is when the database file is unlocked as the pager moves -** from ERROR to OPEN state. At this point there may be a hot-journal file -** in the file-system that needs to be rolled back (as part of an OPEN->SHARED -** transition, by the same pager or any other). If the call to xUnlock() -** fails at this point and the pager is left holding an EXCLUSIVE lock, this -** can confuse the call to xCheckReservedLock() call made later as part -** of hot-journal detection. -** -** xCheckReservedLock() is defined as returning true "if there is a RESERVED -** lock held by this process or any others". So xCheckReservedLock may -** return true because the caller itself is holding an EXCLUSIVE lock (but -** doesn't know it because of a previous error in xUnlock). If this happens -** a hot-journal may be mistaken for a journal being created by an active -** transaction in another process, causing SQLite to read from the database -** without rolling it back. -** -** To work around this, if a call to xUnlock() fails when unlocking the -** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It -** is only changed back to a real locking state after a successful call -** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition -** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK -** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE -** lock on the database file before attempting to roll it back. See function -** PagerSharedLock() for more detail. -** -** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in -** PAGER_OPEN state. -*/ -#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) - -/* -** A macro used for invoking the codec if there is one -*/ -#ifdef SQLITE_HAS_CODEC -# define CODEC1(P,D,N,X,E) \ - if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } -# define CODEC2(P,D,N,X,E,O) \ - if( P->xCodec==0 ){ O=(char*)D; }else \ - if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } -#else -# define CODEC1(P,D,N,X,E) /* NO-OP */ -# define CODEC2(P,D,N,X,E,O) O=(char*)D -#endif - -/* -** The maximum allowed sector size. 64KiB. If the xSectorsize() method -** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. -** This could conceivably cause corruption following a power failure on -** such a system. This is currently an undocumented limit. -*/ -#define MAX_SECTOR_SIZE 0x10000 - - -/* -** An instance of the following structure is allocated for each active -** savepoint and statement transaction in the system. All such structures -** are stored in the Pager.aSavepoint[] array, which is allocated and -** resized using sqlite3Realloc(). -** -** When a savepoint is created, the PagerSavepoint.iHdrOffset field is -** set to 0. If a journal-header is written into the main journal while -** the savepoint is active, then iHdrOffset is set to the byte offset -** immediately following the last journal record written into the main -** journal before the journal-header. This is required during savepoint -** rollback (see pagerPlaybackSavepoint()). -*/ -typedef struct PagerSavepoint PagerSavepoint; -struct PagerSavepoint { - i64 iOffset; /* Starting offset in main journal */ - i64 iHdrOffset; /* See above */ - Bitvec *pInSavepoint; /* Set of pages in this savepoint */ - Pgno nOrig; /* Original number of pages in file */ - Pgno iSubRec; /* Index of first record in sub-journal */ -#ifndef SQLITE_OMIT_WAL - u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ -#endif -}; - -/* -** Bits of the Pager.doNotSpill flag. See further description below. -*/ -#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ -#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ -#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ - -/* -** An open page cache is an instance of struct Pager. A description of -** some of the more important member variables follows: -** -** eState -** -** The current 'state' of the pager object. See the comment and state -** diagram above for a description of the pager state. -** -** eLock -** -** For a real on-disk database, the current lock held on the database file - -** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. -** -** For a temporary or in-memory database (neither of which require any -** locks), this variable is always set to EXCLUSIVE_LOCK. Since such -** databases always have Pager.exclusiveMode==1, this tricks the pager -** logic into thinking that it already has all the locks it will ever -** need (and no reason to release them). -** -** In some (obscure) circumstances, this variable may also be set to -** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for -** details. -** -** changeCountDone -** -** This boolean variable is used to make sure that the change-counter -** (the 4-byte header field at byte offset 24 of the database file) is -** not updated more often than necessary. -** -** It is set to true when the change-counter field is updated, which -** can only happen if an exclusive lock is held on the database file. -** It is cleared (set to false) whenever an exclusive lock is -** relinquished on the database file. Each time a transaction is committed, -** The changeCountDone flag is inspected. If it is true, the work of -** updating the change-counter is omitted for the current transaction. -** -** This mechanism means that when running in exclusive mode, a connection -** need only update the change-counter once, for the first transaction -** committed. -** -** setMaster -** -** When PagerCommitPhaseOne() is called to commit a transaction, it may -** (or may not) specify a master-journal name to be written into the -** journal file before it is synced to disk. -** -** Whether or not a journal file contains a master-journal pointer affects -** the way in which the journal file is finalized after the transaction is -** committed or rolled back when running in "journal_mode=PERSIST" mode. -** If a journal file does not contain a master-journal pointer, it is -** finalized by overwriting the first journal header with zeroes. If -** it does contain a master-journal pointer the journal file is finalized -** by truncating it to zero bytes, just as if the connection were -** running in "journal_mode=truncate" mode. -** -** Journal files that contain master journal pointers cannot be finalized -** simply by overwriting the first journal-header with zeroes, as the -** master journal pointer could interfere with hot-journal rollback of any -** subsequently interrupted transaction that reuses the journal file. -** -** The flag is cleared as soon as the journal file is finalized (either -** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the -** journal file from being successfully finalized, the setMaster flag -** is cleared anyway (and the pager will move to ERROR state). -** -** doNotSpill -** -** This variables control the behavior of cache-spills (calls made by -** the pcache module to the pagerStress() routine to write cached data -** to the file-system in order to free up memory). -** -** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, -** writing to the database from pagerStress() is disabled altogether. -** The SPILLFLAG_ROLLBACK case is done in a very obscure case that -** comes up during savepoint rollback that requires the pcache module -** to allocate a new page to prevent the journal file from being written -** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF -** case is a user preference. -** -** If the SPILLFLAG_NOSYNC bit is set, writing to the database from -** pagerStress() is permitted, but syncing the journal file is not. -** This flag is set by sqlite3PagerWrite() when the file-system sector-size -** is larger than the database page-size in order to prevent a journal sync -** from happening in between the journalling of two pages on the same sector. -** -** subjInMemory -** -** This is a boolean variable. If true, then any required sub-journal -** is opened as an in-memory journal file. If false, then in-memory -** sub-journals are only used for in-memory pager files. -** -** This variable is updated by the upper layer each time a new -** write-transaction is opened. -** -** dbSize, dbOrigSize, dbFileSize -** -** Variable dbSize is set to the number of pages in the database file. -** It is valid in PAGER_READER and higher states (all states except for -** OPEN and ERROR). -** -** dbSize is set based on the size of the database file, which may be -** larger than the size of the database (the value stored at offset -** 28 of the database header by the btree). If the size of the file -** is not an integer multiple of the page-size, the value stored in -** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). -** Except, any file that is greater than 0 bytes in size is considered -** to have at least one page. (i.e. a 1KB file with 2K page-size leads -** to dbSize==1). -** -** During a write-transaction, if pages with page-numbers greater than -** dbSize are modified in the cache, dbSize is updated accordingly. -** Similarly, if the database is truncated using PagerTruncateImage(), -** dbSize is updated. -** -** Variables dbOrigSize and dbFileSize are valid in states -** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize -** variable at the start of the transaction. It is used during rollback, -** and to determine whether or not pages need to be journalled before -** being modified. -** -** Throughout a write-transaction, dbFileSize contains the size of -** the file on disk in pages. It is set to a copy of dbSize when the -** write-transaction is first opened, and updated when VFS calls are made -** to write or truncate the database file on disk. -** -** The only reason the dbFileSize variable is required is to suppress -** unnecessary calls to xTruncate() after committing a transaction. If, -** when a transaction is committed, the dbFileSize variable indicates -** that the database file is larger than the database image (Pager.dbSize), -** pager_truncate() is called. The pager_truncate() call uses xFilesize() -** to measure the database file on disk, and then truncates it if required. -** dbFileSize is not used when rolling back a transaction. In this case -** pager_truncate() is called unconditionally (which means there may be -** a call to xFilesize() that is not strictly required). In either case, -** pager_truncate() may cause the file to become smaller or larger. -** -** dbHintSize -** -** The dbHintSize variable is used to limit the number of calls made to -** the VFS xFileControl(FCNTL_SIZE_HINT) method. -** -** dbHintSize is set to a copy of the dbSize variable when a -** write-transaction is opened (at the same time as dbFileSize and -** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, -** dbHintSize is increased to the number of pages that correspond to the -** size-hint passed to the method call. See pager_write_pagelist() for -** details. -** -** errCode -** -** The Pager.errCode variable is only ever used in PAGER_ERROR state. It -** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode -** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX -** sub-codes. -*/ -struct Pager { - sqlite3_vfs *pVfs; /* OS functions to use for IO */ - u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ - u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ - u8 useJournal; /* Use a rollback journal on this file */ - u8 noSync; /* Do not sync the journal if true */ - u8 fullSync; /* Do extra syncs of the journal for robustness */ - u8 extraSync; /* sync directory after journal delete */ - u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ - u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ - u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ - u8 tempFile; /* zFilename is a temporary or immutable file */ - u8 noLock; /* Do not lock (except in WAL mode) */ - u8 readOnly; /* True for a read-only database */ - u8 memDb; /* True to inhibit all file I/O */ - - /************************************************************************** - ** The following block contains those class members that change during - ** routine operation. Class members not in this block are either fixed - ** when the pager is first created or else only change when there is a - ** significant mode change (such as changing the page_size, locking_mode, - ** or the journal_mode). From another view, these class members describe - ** the "state" of the pager, while other class members describe the - ** "configuration" of the pager. - */ - u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ - u8 eLock; /* Current lock held on database file */ - u8 changeCountDone; /* Set after incrementing the change-counter */ - u8 setMaster; /* True if a m-j name has been written to jrnl */ - u8 doNotSpill; /* Do not spill the cache when non-zero */ - u8 subjInMemory; /* True to use in-memory sub-journals */ - u8 bUseFetch; /* True to use xFetch() */ - u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ - Pgno dbSize; /* Number of pages in the database */ - Pgno dbOrigSize; /* dbSize before the current transaction */ - Pgno dbFileSize; /* Number of pages in the database file */ - Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ - int errCode; /* One of several kinds of errors */ - int nRec; /* Pages journalled since last j-header written */ - u32 cksumInit; /* Quasi-random value added to every checksum */ - u32 nSubRec; /* Number of records written to sub-journal */ - Bitvec *pInJournal; /* One bit for each page in the database file */ - sqlite3_file *fd; /* File descriptor for database */ - sqlite3_file *jfd; /* File descriptor for main journal */ - sqlite3_file *sjfd; /* File descriptor for sub-journal */ - i64 journalOff; /* Current write offset in the journal file */ - i64 journalHdr; /* Byte offset to previous journal header */ - sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ - PagerSavepoint *aSavepoint; /* Array of active savepoints */ - int nSavepoint; /* Number of elements in aSavepoint[] */ - u32 iDataVersion; /* Changes whenever database content changes */ - char dbFileVers[16]; /* Changes whenever database file changes */ - - int nMmapOut; /* Number of mmap pages currently outstanding */ - sqlite3_int64 szMmap; /* Desired maximum mmap size */ - PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ - /* - ** End of the routinely-changing class members - ***************************************************************************/ - - u16 nExtra; /* Add this many bytes to each in-memory page */ - i16 nReserve; /* Number of unused bytes at end of each page */ - u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ - u32 sectorSize; /* Assumed sector size during rollback */ - int pageSize; /* Number of bytes in a page */ - Pgno mxPgno; /* Maximum allowed size of the database */ - i64 journalSizeLimit; /* Size limit for persistent journal files */ - char *zFilename; /* Name of the database file */ - char *zJournal; /* Name of the journal file */ - int (*xBusyHandler)(void*); /* Function to call when busy */ - void *pBusyHandlerArg; /* Context argument for xBusyHandler */ - int aStat[3]; /* Total cache hits, misses and writes */ -#ifdef SQLITE_TEST - int nRead; /* Database pages read */ -#endif - void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ -#ifdef SQLITE_HAS_CODEC - void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ - void (*xCodecFree)(void*); /* Destructor for the codec */ - void *pCodec; /* First argument to xCodec... methods */ -#endif - char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ - PCache *pPCache; /* Pointer to page cache object */ -#ifndef SQLITE_OMIT_WAL - Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ - char *zWal; /* File name for write-ahead log */ -#endif -}; - -/* -** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains -** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS -** or CACHE_WRITE to sqlite3_db_status(). -*/ -#define PAGER_STAT_HIT 0 -#define PAGER_STAT_MISS 1 -#define PAGER_STAT_WRITE 2 - -/* -** The following global variables hold counters used for -** testing purposes only. These variables do not exist in -** a non-testing build. These variables are not thread-safe. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ -SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ -SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ -# define PAGER_INCR(v) v++ -#else -# define PAGER_INCR(v) -#endif - - - -/* -** Journal files begin with the following magic string. The data -** was obtained from /dev/random. It is used only as a sanity check. -** -** Since version 2.8.0, the journal format contains additional sanity -** checking information. If the power fails while the journal is being -** written, semi-random garbage data might appear in the journal -** file after power is restored. If an attempt is then made -** to roll the journal back, the database could be corrupted. The additional -** sanity checking data is an attempt to discover the garbage in the -** journal and ignore it. -** -** The sanity checking information for the new journal format consists -** of a 32-bit checksum on each page of data. The checksum covers both -** the page number and the pPager->pageSize bytes of data for the page. -** This cksum is initialized to a 32-bit random value that appears in the -** journal file right after the header. The random initializer is important, -** because garbage data that appears at the end of a journal is likely -** data that was once in other files that have now been deleted. If the -** garbage data came from an obsolete journal file, the checksums might -** be correct. But by initializing the checksum to random value which -** is different for every journal, we minimize that risk. -*/ -static const unsigned char aJournalMagic[] = { - 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, -}; - -/* -** The size of the of each page record in the journal is given by -** the following macro. -*/ -#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) - -/* -** The journal header size for this pager. This is usually the same -** size as a single disk sector. See also setSectorSize(). -*/ -#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) - -/* -** The macro MEMDB is true if we are dealing with an in-memory database. -** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, -** the value of MEMDB will be a constant and the compiler will optimize -** out code that would never execute. -*/ -#ifdef SQLITE_OMIT_MEMORYDB -# define MEMDB 0 -#else -# define MEMDB pPager->memDb -#endif - -/* -** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch -** interfaces to access the database using memory-mapped I/O. -*/ -#if SQLITE_MAX_MMAP_SIZE>0 -# define USEFETCH(x) ((x)->bUseFetch) -#else -# define USEFETCH(x) 0 -#endif - -/* -** The maximum legal page number is (2^31 - 1). -*/ -#define PAGER_MAX_PGNO 2147483647 - -/* -** The argument to this macro is a file descriptor (type sqlite3_file*). -** Return 0 if it is not open, or non-zero (but not 1) if it is. -** -** This is so that expressions can be written as: -** -** if( isOpen(pPager->jfd) ){ ... -** -** instead of -** -** if( pPager->jfd->pMethods ){ ... -*/ -#define isOpen(pFd) ((pFd)->pMethods!=0) - -/* -** Return true if this pager uses a write-ahead log instead of the usual -** rollback journal. Otherwise false. -*/ -#ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager){ - return (pPager->pWal!=0); -} -# define pagerUseWal(x) sqlite3PagerUseWal(x) -#else -# define pagerUseWal(x) 0 -# define pagerRollbackWal(x) 0 -# define pagerWalFrames(v,w,x,y) 0 -# define pagerOpenWalIfPresent(z) SQLITE_OK -# define pagerBeginReadTransaction(z) SQLITE_OK -#endif - -#ifndef NDEBUG -/* -** Usage: -** -** assert( assert_pager_state(pPager) ); -** -** This function runs many asserts to try to find inconsistencies in -** the internal state of the Pager object. -*/ -static int assert_pager_state(Pager *p){ - Pager *pPager = p; - - /* State must be valid. */ - assert( p->eState==PAGER_OPEN - || p->eState==PAGER_READER - || p->eState==PAGER_WRITER_LOCKED - || p->eState==PAGER_WRITER_CACHEMOD - || p->eState==PAGER_WRITER_DBMOD - || p->eState==PAGER_WRITER_FINISHED - || p->eState==PAGER_ERROR - ); - - /* Regardless of the current state, a temp-file connection always behaves - ** as if it has an exclusive lock on the database file. It never updates - ** the change-counter field, so the changeCountDone flag is always set. - */ - assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); - assert( p->tempFile==0 || pPager->changeCountDone ); - - /* If the useJournal flag is clear, the journal-mode must be "OFF". - ** And if the journal-mode is "OFF", the journal file must not be open. - */ - assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); - assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); - - /* Check that MEMDB implies noSync. And an in-memory journal. Since - ** this means an in-memory pager performs no IO at all, it cannot encounter - ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing - ** a journal file. (although the in-memory journal implementation may - ** return SQLITE_IOERR_NOMEM while the journal file is being written). It - ** is therefore not possible for an in-memory pager to enter the ERROR - ** state. - */ - if( MEMDB ){ - assert( !isOpen(p->fd) ); - assert( p->noSync ); - assert( p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_MEMORY - ); - assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); - assert( pagerUseWal(p)==0 ); - } - - /* If changeCountDone is set, a RESERVED lock or greater must be held - ** on the file. - */ - assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); - assert( p->eLock!=PENDING_LOCK ); - - switch( p->eState ){ - case PAGER_OPEN: - assert( !MEMDB ); - assert( pPager->errCode==SQLITE_OK ); - assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); - break; - - case PAGER_READER: - assert( pPager->errCode==SQLITE_OK ); - assert( p->eLock!=UNKNOWN_LOCK ); - assert( p->eLock>=SHARED_LOCK ); - break; - - case PAGER_WRITER_LOCKED: - assert( p->eLock!=UNKNOWN_LOCK ); - assert( pPager->errCode==SQLITE_OK ); - if( !pagerUseWal(pPager) ){ - assert( p->eLock>=RESERVED_LOCK ); - } - assert( pPager->dbSize==pPager->dbOrigSize ); - assert( pPager->dbOrigSize==pPager->dbFileSize ); - assert( pPager->dbOrigSize==pPager->dbHintSize ); - assert( pPager->setMaster==0 ); - break; - - case PAGER_WRITER_CACHEMOD: - assert( p->eLock!=UNKNOWN_LOCK ); - assert( pPager->errCode==SQLITE_OK ); - if( !pagerUseWal(pPager) ){ - /* It is possible that if journal_mode=wal here that neither the - ** journal file nor the WAL file are open. This happens during - ** a rollback transaction that switches from journal_mode=off - ** to journal_mode=wal. - */ - assert( p->eLock>=RESERVED_LOCK ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL - ); - } - assert( pPager->dbOrigSize==pPager->dbFileSize ); - assert( pPager->dbOrigSize==pPager->dbHintSize ); - break; - - case PAGER_WRITER_DBMOD: - assert( p->eLock==EXCLUSIVE_LOCK ); - assert( pPager->errCode==SQLITE_OK ); - assert( !pagerUseWal(pPager) ); - assert( p->eLock>=EXCLUSIVE_LOCK ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL - ); - assert( pPager->dbOrigSize<=pPager->dbHintSize ); - break; - - case PAGER_WRITER_FINISHED: - assert( p->eLock==EXCLUSIVE_LOCK ); - assert( pPager->errCode==SQLITE_OK ); - assert( !pagerUseWal(pPager) ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL - ); - break; - - case PAGER_ERROR: - /* There must be at least one outstanding reference to the pager if - ** in ERROR state. Otherwise the pager should have already dropped - ** back to OPEN state. - */ - assert( pPager->errCode!=SQLITE_OK ); - assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); - break; - } - - return 1; -} -#endif /* ifndef NDEBUG */ - -#ifdef SQLITE_DEBUG -/* -** Return a pointer to a human readable string in a static buffer -** containing the state of the Pager object passed as an argument. This -** is intended to be used within debuggers. For example, as an alternative -** to "print *pPager" in gdb: -** -** (gdb) printf "%s", print_pager_state(pPager) -*/ -static char *print_pager_state(Pager *p){ - static char zRet[1024]; - - sqlite3_snprintf(1024, zRet, - "Filename: %s\n" - "State: %s errCode=%d\n" - "Lock: %s\n" - "Locking mode: locking_mode=%s\n" - "Journal mode: journal_mode=%s\n" - "Backing store: tempFile=%d memDb=%d useJournal=%d\n" - "Journal: journalOff=%lld journalHdr=%lld\n" - "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" - , p->zFilename - , p->eState==PAGER_OPEN ? "OPEN" : - p->eState==PAGER_READER ? "READER" : - p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : - p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : - p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : - p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : - p->eState==PAGER_ERROR ? "ERROR" : "?error?" - , (int)p->errCode - , p->eLock==NO_LOCK ? "NO_LOCK" : - p->eLock==RESERVED_LOCK ? "RESERVED" : - p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : - p->eLock==SHARED_LOCK ? "SHARED" : - p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" - , p->exclusiveMode ? "exclusive" : "normal" - , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : - p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : - p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : - p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : - p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : - p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" - , (int)p->tempFile, (int)p->memDb, (int)p->useJournal - , p->journalOff, p->journalHdr - , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize - ); - - return zRet; -} -#endif - -/* -** Return true if it is necessary to write page *pPg into the sub-journal. -** A page needs to be written into the sub-journal if there exists one -** or more open savepoints for which: -** -** * The page-number is less than or equal to PagerSavepoint.nOrig, and -** * The bit corresponding to the page-number is not set in -** PagerSavepoint.pInSavepoint. -*/ -static int subjRequiresPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - PagerSavepoint *p; - Pgno pgno = pPg->pgno; - int i; - for(i=0; inSavepoint; i++){ - p = &pPager->aSavepoint[i]; - if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ - return 1; - } - } - return 0; -} - -#ifdef SQLITE_DEBUG -/* -** Return true if the page is already in the journal file. -*/ -static int pageInJournal(Pager *pPager, PgHdr *pPg){ - return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); -} -#endif - -/* -** Read a 32-bit integer from the given file descriptor. Store the integer -** that is read in *pRes. Return SQLITE_OK if everything worked, or an -** error code is something goes wrong. -** -** All values are stored on disk as big-endian. -*/ -static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ - unsigned char ac[4]; - int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); - if( rc==SQLITE_OK ){ - *pRes = sqlite3Get4byte(ac); - } - return rc; -} - -/* -** Write a 32-bit integer into a string buffer in big-endian byte order. -*/ -#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) - - -/* -** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK -** on success or an error code is something goes wrong. -*/ -static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ - char ac[4]; - put32bits(ac, val); - return sqlite3OsWrite(fd, ac, 4, offset); -} - -/* -** Unlock the database file to level eLock, which must be either NO_LOCK -** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() -** succeeds, set the Pager.eLock variable to match the (attempted) new lock. -** -** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -** called, do not modify it. See the comment above the #define of -** UNKNOWN_LOCK for an explanation of this. -*/ -static int pagerUnlockDb(Pager *pPager, int eLock){ - int rc = SQLITE_OK; - - assert( !pPager->exclusiveMode || pPager->eLock==eLock ); - assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); - assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); - if( isOpen(pPager->fd) ){ - assert( pPager->eLock>=eLock ); - rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); - if( pPager->eLock!=UNKNOWN_LOCK ){ - pPager->eLock = (u8)eLock; - } - IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) - } - return rc; -} - -/* -** Lock the database file to level eLock, which must be either SHARED_LOCK, -** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the -** Pager.eLock variable to the new locking state. -** -** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. -** See the comment above the #define of UNKNOWN_LOCK for an explanation -** of this. -*/ -static int pagerLockDb(Pager *pPager, int eLock){ - int rc = SQLITE_OK; - - assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); - if( pPager->eLockeLock==UNKNOWN_LOCK ){ - rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); - if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ - pPager->eLock = (u8)eLock; - IOTRACE(("LOCK %p %d\n", pPager, eLock)) - } - } - return rc; -} - -/* -** This function determines whether or not the atomic-write optimization -** can be used with this pager. The optimization can be used if: -** -** (a) the value returned by OsDeviceCharacteristics() indicates that -** a database page may be written atomically, and -** (b) the value returned by OsSectorSize() is less than or equal -** to the page size. -** -** The optimization is also always enabled for temporary files. It is -** an error to call this function if pPager is opened on an in-memory -** database. -** -** If the optimization cannot be used, 0 is returned. If it can be used, -** then the value returned is the size of the journal file when it -** contains rollback data for exactly one page. -*/ -#ifdef SQLITE_ENABLE_ATOMIC_WRITE -static int jrnlBufferSize(Pager *pPager){ - assert( !MEMDB ); - if( !pPager->tempFile ){ - int dc; /* Device characteristics */ - int nSector; /* Sector size */ - int szPage; /* Page size */ - - assert( isOpen(pPager->fd) ); - dc = sqlite3OsDeviceCharacteristics(pPager->fd); - nSector = pPager->sectorSize; - szPage = pPager->pageSize; - - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ - return 0; - } - } - - return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); -} -#else -# define jrnlBufferSize(x) 0 -#endif - -/* -** If SQLITE_CHECK_PAGES is defined then we do some sanity checking -** on the cache using a hash function. This is used for testing -** and debugging only. -*/ -#ifdef SQLITE_CHECK_PAGES -/* -** Return a 32-bit hash of the page data for pPage. -*/ -static u32 pager_datahash(int nByte, unsigned char *pData){ - u32 hash = 0; - int i; - for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); -} -static void pager_set_pagehash(PgHdr *pPage){ - pPage->pageHash = pager_pagehash(pPage); -} - -/* -** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES -** is defined, and NDEBUG is not defined, an assert() statement checks -** that the page is either dirty or still matches the calculated page-hash. -*/ -#define CHECK_PAGE(x) checkPage(x) -static void checkPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - assert( pPager->eState!=PAGER_ERROR ); - assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); -} - -#else -#define pager_datahash(X,Y) 0 -#define pager_pagehash(X) 0 -#define pager_set_pagehash(X) -#define CHECK_PAGE(x) -#endif /* SQLITE_CHECK_PAGES */ - -/* -** When this is called the journal file for pager pPager must be open. -** This function attempts to read a master journal file name from the -** end of the file and, if successful, copies it into memory supplied -** by the caller. See comments above writeMasterJournal() for the format -** used to store a master journal file name at the end of a journal file. -** -** zMaster must point to a buffer of at least nMaster bytes allocated by -** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is -** enough space to write the master journal name). If the master journal -** name in the journal is longer than nMaster bytes (including a -** nul-terminator), then this is handled as if no master journal name -** were present in the journal. -** -** If a master journal file name is present at the end of the journal -** file, then it is copied into the buffer pointed to by zMaster. A -** nul-terminator byte is appended to the buffer following the master -** journal file name. -** -** If it is determined that no master journal file name is present -** zMaster[0] is set to 0 and SQLITE_OK returned. -** -** If an error occurs while reading from the journal file, an SQLite -** error code is returned. -*/ -static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ - int rc; /* Return code */ - u32 len; /* Length in bytes of master journal name */ - i64 szJ; /* Total size in bytes of journal file pJrnl */ - u32 cksum; /* MJ checksum value read from journal */ - u32 u; /* Unsigned loop counter */ - unsigned char aMagic[8]; /* A buffer to hold the magic header */ - zMaster[0] = '\0'; - - if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) - || szJ<16 - || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) - || len>=nMaster - || len==0 - || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) - || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) - || memcmp(aMagic, aJournalMagic, 8) - || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) - ){ - return rc; - } - - /* See if the checksum matches the master journal name */ - for(u=0; ujournalOff, assuming a sector -** size of pPager->sectorSize bytes. -** -** i.e for a sector size of 512: -** -** Pager.journalOff Return value -** --------------------------------------- -** 0 0 -** 512 512 -** 100 512 -** 2000 2048 -** -*/ -static i64 journalHdrOffset(Pager *pPager){ - i64 offset = 0; - i64 c = pPager->journalOff; - if( c ){ - offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); - } - assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); - assert( offset>=c ); - assert( (offset-c)jfd) ); - assert( !sqlite3JournalIsInMemory(pPager->jfd) ); - if( pPager->journalOff ){ - const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ - - IOTRACE(("JZEROHDR %p\n", pPager)) - if( doTruncate || iLimit==0 ){ - rc = sqlite3OsTruncate(pPager->jfd, 0); - }else{ - static const char zeroHdr[28] = {0}; - rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); - } - if( rc==SQLITE_OK && !pPager->noSync ){ - rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); - } - - /* At this point the transaction is committed but the write lock - ** is still held on the file. If there is a size limit configured for - ** the persistent journal and the journal file currently consumes more - ** space than that limit allows for, truncate it now. There is no need - ** to sync the file following this operation. - */ - if( rc==SQLITE_OK && iLimit>0 ){ - i64 sz; - rc = sqlite3OsFileSize(pPager->jfd, &sz); - if( rc==SQLITE_OK && sz>iLimit ){ - rc = sqlite3OsTruncate(pPager->jfd, iLimit); - } - } - } - return rc; -} - -/* -** The journal file must be open when this routine is called. A journal -** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the -** current location. -** -** The format for the journal header is as follows: -** - 8 bytes: Magic identifying journal format. -** - 4 bytes: Number of records in journal, or -1 no-sync mode is on. -** - 4 bytes: Random number used for page hash. -** - 4 bytes: Initial database page count. -** - 4 bytes: Sector size used by the process that wrote this journal. -** - 4 bytes: Database page size. -** -** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. -*/ -static int writeJournalHdr(Pager *pPager){ - int rc = SQLITE_OK; /* Return code */ - char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ - u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ - u32 nWrite; /* Bytes of header sector written */ - int ii; /* Loop counter */ - - assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ - - if( nHeader>JOURNAL_HDR_SZ(pPager) ){ - nHeader = JOURNAL_HDR_SZ(pPager); - } - - /* If there are active savepoints and any of them were created - ** since the most recent journal header was written, update the - ** PagerSavepoint.iHdrOffset fields now. - */ - for(ii=0; iinSavepoint; ii++){ - if( pPager->aSavepoint[ii].iHdrOffset==0 ){ - pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff; - } - } - - pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); - - /* - ** Write the nRec Field - the number of page records that follow this - ** journal header. Normally, zero is written to this value at this time. - ** After the records are added to the journal (and the journal synced, - ** if in full-sync mode), the zero is overwritten with the true number - ** of records (see syncJournal()). - ** - ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When - ** reading the journal this value tells SQLite to assume that the - ** rest of the journal file contains valid page records. This assumption - ** is dangerous, as if a failure occurred whilst writing to the journal - ** file it may contain some garbage data. There are two scenarios - ** where this risk can be ignored: - ** - ** * When the pager is in no-sync mode. Corruption can follow a - ** power failure in this case anyway. - ** - ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees - ** that garbage data is never appended to the journal file. - */ - assert( isOpen(pPager->fd) || pPager->noSync ); - if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) - ){ - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); - put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); - }else{ - memset(zHeader, 0, sizeof(aJournalMagic)+4); - } - - /* The random check-hash initializer */ - sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); - put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); - /* The initial database size */ - put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); - /* The assumed sector size for this process */ - put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); - - /* The page size */ - put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); - - /* Initializing the tail of the buffer is not necessary. Everything - ** works find if the following memset() is omitted. But initializing - ** the memory prevents valgrind from complaining, so we are willing to - ** take the performance hit. - */ - memset(&zHeader[sizeof(aJournalMagic)+20], 0, - nHeader-(sizeof(aJournalMagic)+20)); - - /* In theory, it is only necessary to write the 28 bytes that the - ** journal header consumes to the journal file here. Then increment the - ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next - ** record is written to the following sector (leaving a gap in the file - ** that will be implicitly filled in by the OS). - ** - ** However it has been discovered that on some systems this pattern can - ** be significantly slower than contiguously writing data to the file, - ** even if that means explicitly writing data to the block of - ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what - ** is done. - ** - ** The loop is required here in case the sector-size is larger than the - ** database page size. Since the zHeader buffer is only Pager.pageSize - ** bytes in size, more than one call to sqlite3OsWrite() may be required - ** to populate the entire journal header sector. - */ - for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) - rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); - assert( pPager->journalHdr <= pPager->journalOff ); - pPager->journalOff += nHeader; - } - - return rc; -} - -/* -** The journal file must be open when this is called. A journal header file -** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal -** file. The current location in the journal file is given by -** pPager->journalOff. See comments above function writeJournalHdr() for -** a description of the journal header format. -** -** If the header is read successfully, *pNRec is set to the number of -** page records following this header and *pDbSize is set to the size of the -** database before the transaction began, in pages. Also, pPager->cksumInit -** is set to the value read from the journal header. SQLITE_OK is returned -** in this case. -** -** If the journal header file appears to be corrupted, SQLITE_DONE is -** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes -** cannot be read from the journal file an error code is returned. -*/ -static int readJournalHdr( - Pager *pPager, /* Pager object */ - int isHot, - i64 journalSize, /* Size of the open journal file in bytes */ - u32 *pNRec, /* OUT: Value read from the nRec field */ - u32 *pDbSize /* OUT: Value of original database size field */ -){ - int rc; /* Return code */ - unsigned char aMagic[8]; /* A buffer to hold the magic header */ - i64 iHdrOff; /* Offset of journal header being read */ - - assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ - - /* Advance Pager.journalOff to the start of the next sector. If the - ** journal file is too small for there to be a header stored at this - ** point, return SQLITE_DONE. - */ - pPager->journalOff = journalHdrOffset(pPager); - if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ - return SQLITE_DONE; - } - iHdrOff = pPager->journalOff; - - /* Read in the first 8 bytes of the journal header. If they do not match - ** the magic string found at the start of each journal header, return - ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, - ** proceed. - */ - if( isHot || iHdrOff!=pPager->journalHdr ){ - rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); - if( rc ){ - return rc; - } - if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ - return SQLITE_DONE; - } - } - - /* Read the first three 32-bit fields of the journal header: The nRec - ** field, the checksum-initializer and the database size at the start - ** of the transaction. Return an error code if anything goes wrong. - */ - if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec)) - || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit)) - || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize)) - ){ - return rc; - } - - if( pPager->journalOff==0 ){ - u32 iPageSize; /* Page-size field of journal header */ - u32 iSectorSize; /* Sector-size field of journal header */ - - /* Read the page-size and sector-size journal header fields. */ - if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) - || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize)) - ){ - return rc; - } - - /* Versions of SQLite prior to 3.5.8 set the page-size field of the - ** journal header to zero. In this case, assume that the Pager.pageSize - ** variable is already set to the correct page size. - */ - if( iPageSize==0 ){ - iPageSize = pPager->pageSize; - } - - /* Check that the values read from the page-size and sector-size fields - ** are within range. To be 'in range', both values need to be a power - ** of two greater than or equal to 512 or 32, and not greater than their - ** respective compile time maximum limits. - */ - if( iPageSize<512 || iSectorSize<32 - || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE - || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 - ){ - /* If the either the page-size or sector-size in the journal-header is - ** invalid, then the process that wrote the journal-header must have - ** crashed before the header was synced. In this case stop reading - ** the journal file here. - */ - return SQLITE_DONE; - } - - /* Update the page-size to match the value read from the journal. - ** Use a testcase() macro to make sure that malloc failure within - ** PagerSetPagesize() is tested. - */ - rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); - testcase( rc!=SQLITE_OK ); - - /* Update the assumed sector-size to match the value used by - ** the process that created this journal. If this journal was - ** created by a process other than this one, then this routine - ** is being called from within pager_playback(). The local value - ** of Pager.sectorSize is restored at the end of that routine. - */ - pPager->sectorSize = iSectorSize; - } - - pPager->journalOff += JOURNAL_HDR_SZ(pPager); - return rc; -} - - -/* -** Write the supplied master journal name into the journal file for pager -** pPager at the current location. The master journal name must be the last -** thing written to a journal file. If the pager is in full-sync mode, the -** journal file descriptor is advanced to the next sector boundary before -** anything is written. The format is: -** -** + 4 bytes: PAGER_MJ_PGNO. -** + N bytes: Master journal filename in utf-8. -** + 4 bytes: N (length of master journal name in bytes, no nul-terminator). -** + 4 bytes: Master journal name checksum. -** + 8 bytes: aJournalMagic[]. -** -** The master journal page checksum is the sum of the bytes in the master -** journal name, where each byte is interpreted as a signed 8-bit integer. -** -** If zMaster is a NULL pointer (occurs for a single database transaction), -** this call is a no-op. -*/ -static int writeMasterJournal(Pager *pPager, const char *zMaster){ - int rc; /* Return code */ - int nMaster; /* Length of string zMaster */ - i64 iHdrOff; /* Offset of header in journal file */ - i64 jrnlSize; /* Size of journal file on disk */ - u32 cksum = 0; /* Checksum of string zMaster */ - - assert( pPager->setMaster==0 ); - assert( !pagerUseWal(pPager) ); - - if( !zMaster - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY - || !isOpen(pPager->jfd) - ){ - return SQLITE_OK; - } - pPager->setMaster = 1; - assert( pPager->journalHdr <= pPager->journalOff ); - - /* Calculate the length in bytes and the checksum of zMaster */ - for(nMaster=0; zMaster[nMaster]; nMaster++){ - cksum += zMaster[nMaster]; - } - - /* If in full-sync mode, advance to the next disk sector before writing - ** the master journal name. This is in case the previous page written to - ** the journal has already been synced. - */ - if( pPager->fullSync ){ - pPager->journalOff = journalHdrOffset(pPager); - } - iHdrOff = pPager->journalOff; - - /* Write the master journal data to the end of the journal file. If - ** an error occurs, return the error code to the caller. - */ - if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) - || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) - || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) - || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) - || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, - iHdrOff+4+nMaster+8))) - ){ - return rc; - } - pPager->journalOff += (nMaster+20); - - /* If the pager is in peristent-journal mode, then the physical - ** journal-file may extend past the end of the master-journal name - ** and 8 bytes of magic data just written to the file. This is - ** dangerous because the code to rollback a hot-journal file - ** will not be able to find the master-journal name to determine - ** whether or not the journal is hot. - ** - ** Easiest thing to do in this scenario is to truncate the journal - ** file to the required size. - */ - if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) - && jrnlSize>pPager->journalOff - ){ - rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); - } - return rc; -} - -/* -** Discard the entire contents of the in-memory page-cache. -*/ -static void pager_reset(Pager *pPager){ - pPager->iDataVersion++; - sqlite3BackupRestart(pPager->pBackup); - sqlite3PcacheClear(pPager->pPCache); -} - -/* -** Return the pPager->iDataVersion value -*/ -SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ - assert( pPager->eState>PAGER_OPEN ); - return pPager->iDataVersion; -} - -/* -** Free all structures in the Pager.aSavepoint[] array and set both -** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal -** if it is open and the pager is not in exclusive mode. -*/ -static void releaseAllSavepoints(Pager *pPager){ - int ii; /* Iterator for looping through Pager.aSavepoint */ - for(ii=0; iinSavepoint; ii++){ - sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); - } - if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){ - sqlite3OsClose(pPager->sjfd); - } - sqlite3_free(pPager->aSavepoint); - pPager->aSavepoint = 0; - pPager->nSavepoint = 0; - pPager->nSubRec = 0; -} - -/* -** Set the bit number pgno in the PagerSavepoint.pInSavepoint -** bitvecs of all open savepoints. Return SQLITE_OK if successful -** or SQLITE_NOMEM if a malloc failure occurs. -*/ -static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ - int ii; /* Loop counter */ - int rc = SQLITE_OK; /* Result code */ - - for(ii=0; iinSavepoint; ii++){ - PagerSavepoint *p = &pPager->aSavepoint[ii]; - if( pgno<=p->nOrig ){ - rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); - testcase( rc==SQLITE_NOMEM ); - assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); - } - } - return rc; -} - -/* -** This function is a no-op if the pager is in exclusive mode and not -** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN -** state. -** -** If the pager is not in exclusive-access mode, the database file is -** completely unlocked. If the file is unlocked and the file-system does -** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is -** closed (if it is open). -** -** If the pager is in ERROR state when this function is called, the -** contents of the pager cache are discarded before switching back to -** the OPEN state. Regardless of whether the pager is in exclusive-mode -** or not, any journal file left in the file-system will be treated -** as a hot-journal and rolled back the next time a read-transaction -** is opened (by this or by any other connection). -*/ -static void pager_unlock(Pager *pPager){ - - assert( pPager->eState==PAGER_READER - || pPager->eState==PAGER_OPEN - || pPager->eState==PAGER_ERROR - ); - - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - releaseAllSavepoints(pPager); - - if( pagerUseWal(pPager) ){ - assert( !isOpen(pPager->jfd) ); - sqlite3WalEndReadTransaction(pPager->pWal); - pPager->eState = PAGER_OPEN; - }else if( !pPager->exclusiveMode ){ - int rc; /* Error code returned by pagerUnlockDb() */ - int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; - - /* If the operating system support deletion of open files, then - ** close the journal file when dropping the database lock. Otherwise - ** another connection with journal_mode=delete might delete the file - ** out from under us. - */ - assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); - assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); - assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); - assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); - assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); - assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); - if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) - || 1!=(pPager->journalMode & 5) - ){ - sqlite3OsClose(pPager->jfd); - } - - /* If the pager is in the ERROR state and the call to unlock the database - ** file fails, set the current lock to UNKNOWN_LOCK. See the comment - ** above the #define for UNKNOWN_LOCK for an explanation of why this - ** is necessary. - */ - rc = pagerUnlockDb(pPager, NO_LOCK); - if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ - pPager->eLock = UNKNOWN_LOCK; - } - - /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here - ** without clearing the error code. This is intentional - the error - ** code is cleared and the cache reset in the block below. - */ - assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); - pPager->changeCountDone = 0; - pPager->eState = PAGER_OPEN; - } - - /* If Pager.errCode is set, the contents of the pager cache cannot be - ** trusted. Now that there are no outstanding references to the pager, - ** it can safely move back to PAGER_OPEN state. This happens in both - ** normal and exclusive-locking mode. - */ - assert( pPager->errCode==SQLITE_OK || !MEMDB ); - if( pPager->errCode ){ - if( pPager->tempFile==0 ){ - pager_reset(pPager); - pPager->changeCountDone = 0; - pPager->eState = PAGER_OPEN; - }else{ - pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); - } - if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); - pPager->errCode = SQLITE_OK; - } - - pPager->journalOff = 0; - pPager->journalHdr = 0; - pPager->setMaster = 0; -} - -/* -** This function is called whenever an IOERR or FULL error that requires -** the pager to transition into the ERROR state may ahve occurred. -** The first argument is a pointer to the pager structure, the second -** the error-code about to be returned by a pager API function. The -** value returned is a copy of the second argument to this function. -** -** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the -** IOERR sub-codes, the pager enters the ERROR state and the error code -** is stored in Pager.errCode. While the pager remains in the ERROR state, -** all major API calls on the Pager will immediately return Pager.errCode. -** -** The ERROR state indicates that the contents of the pager-cache -** cannot be trusted. This state can be cleared by completely discarding -** the contents of the pager-cache. If a transaction was active when -** the persistent error occurred, then the rollback journal may need -** to be replayed to restore the contents of the database file (as if -** it were a hot-journal). -*/ -static int pager_error(Pager *pPager, int rc){ - int rc2 = rc & 0xff; - assert( rc==SQLITE_OK || !MEMDB ); - assert( - pPager->errCode==SQLITE_FULL || - pPager->errCode==SQLITE_OK || - (pPager->errCode & 0xff)==SQLITE_IOERR - ); - if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ - pPager->errCode = rc; - pPager->eState = PAGER_ERROR; - } - return rc; -} - -static int pager_truncate(Pager *pPager, Pgno nPage); - -/* -** The write transaction open on pPager is being committed (bCommit==1) -** or rolled back (bCommit==0). -** -** Return TRUE if and only if all dirty pages should be flushed to disk. -** -** Rules: -** -** * For non-TEMP databases, always sync to disk. This is necessary -** for transactions to be durable. -** -** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing -** file has been created already (via a spill on pagerStress()) and -** when the number of dirty pages in memory exceeds 25% of the total -** cache size. -*/ -static int pagerFlushOnCommit(Pager *pPager, int bCommit){ - if( pPager->tempFile==0 ) return 1; - if( !bCommit ) return 0; - if( !isOpen(pPager->fd) ) return 0; - return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); -} - -/* -** This routine ends a transaction. A transaction is usually ended by -** either a COMMIT or a ROLLBACK operation. This routine may be called -** after rollback of a hot-journal, or if an error occurs while opening -** the journal file or writing the very first journal-header of a -** database transaction. -** -** This routine is never called in PAGER_ERROR state. If it is called -** in PAGER_NONE or PAGER_SHARED state and the lock held is less -** exclusive than a RESERVED lock, it is a no-op. -** -** Otherwise, any active savepoints are released. -** -** If the journal file is open, then it is "finalized". Once a journal -** file has been finalized it is not possible to use it to roll back a -** transaction. Nor will it be considered to be a hot-journal by this -** or any other database connection. Exactly how a journal is finalized -** depends on whether or not the pager is running in exclusive mode and -** the current journal-mode (Pager.journalMode value), as follows: -** -** journalMode==MEMORY -** Journal file descriptor is simply closed. This destroys an -** in-memory journal. -** -** journalMode==TRUNCATE -** Journal file is truncated to zero bytes in size. -** -** journalMode==PERSIST -** The first 28 bytes of the journal file are zeroed. This invalidates -** the first journal header in the file, and hence the entire journal -** file. An invalid journal file cannot be rolled back. -** -** journalMode==DELETE -** The journal file is closed and deleted using sqlite3OsDelete(). -** -** If the pager is running in exclusive mode, this method of finalizing -** the journal file is never used. Instead, if the journalMode is -** DELETE and the pager is in exclusive mode, the method described under -** journalMode==PERSIST is used instead. -** -** After the journal is finalized, the pager moves to PAGER_READER state. -** If running in non-exclusive rollback mode, the lock on the file is -** downgraded to a SHARED_LOCK. -** -** SQLITE_OK is returned if no error occurs. If an error occurs during -** any of the IO operations to finalize the journal file or unlock the -** database then the IO error code is returned to the user. If the -** operation to finalize the journal file fails, then the code still -** tries to unlock the database file if not in exclusive mode. If the -** unlock operation fails as well, then the first error code related -** to the first error encountered (the journal finalization one) is -** returned. -*/ -static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ - int rc = SQLITE_OK; /* Error code from journal finalization operation */ - int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ - - /* Do nothing if the pager does not have an open write transaction - ** or at least a RESERVED lock. This function may be called when there - ** is no write-transaction active but a RESERVED or greater lock is - ** held under two circumstances: - ** - ** 1. After a successful hot-journal rollback, it is called with - ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. - ** - ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE - ** lock switches back to locking_mode=normal and then executes a - ** read-transaction, this function is called with eState==PAGER_READER - ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. - */ - assert( assert_pager_state(pPager) ); - assert( pPager->eState!=PAGER_ERROR ); - if( pPager->eStateeLockjfd) || pPager->pInJournal==0 ); - if( isOpen(pPager->jfd) ){ - assert( !pagerUseWal(pPager) ); - - /* Finalize the journal file. */ - if( sqlite3JournalIsInMemory(pPager->jfd) ){ - /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */ - sqlite3OsClose(pPager->jfd); - }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ - if( pPager->journalOff==0 ){ - rc = SQLITE_OK; - }else{ - rc = sqlite3OsTruncate(pPager->jfd, 0); - if( rc==SQLITE_OK && pPager->fullSync ){ - /* Make sure the new file size is written into the inode right away. - ** Otherwise the journal might resurrect following a power loss and - ** cause the last transaction to roll back. See - ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 - */ - rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); - } - } - pPager->journalOff = 0; - }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST - || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL) - ){ - rc = zeroJournalHdr(pPager, hasMaster||pPager->tempFile); - pPager->journalOff = 0; - }else{ - /* This branch may be executed with Pager.journalMode==MEMORY if - ** a hot-journal was just rolled back. In this case the journal - ** file should be closed and deleted. If this connection writes to - ** the database file, it will do so using an in-memory journal. - */ - int bDelete = !pPager->tempFile; - assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); - assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY - || pPager->journalMode==PAGER_JOURNALMODE_WAL - ); - sqlite3OsClose(pPager->jfd); - if( bDelete ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); - } - } - } - -#ifdef SQLITE_CHECK_PAGES - sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); - if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ - PgHdr *p = sqlite3PagerLookup(pPager, 1); - if( p ){ - p->pageHash = 0; - sqlite3PagerUnrefNotNull(p); - } - } -#endif - - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - pPager->nRec = 0; - if( rc==SQLITE_OK ){ - if( pagerFlushOnCommit(pPager, bCommit) ){ - sqlite3PcacheCleanAll(pPager->pPCache); - }else{ - sqlite3PcacheClearWritable(pPager->pPCache); - } - sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); - } - - if( pagerUseWal(pPager) ){ - /* Drop the WAL write-lock, if any. Also, if the connection was in - ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE - ** lock held on the database file. - */ - rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); - assert( rc2==SQLITE_OK ); - }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ - /* This branch is taken when committing a transaction in rollback-journal - ** mode if the database file on disk is larger than the database image. - ** At this point the journal has been finalized and the transaction - ** successfully committed, but the EXCLUSIVE lock is still held on the - ** file. So it is safe to truncate the database file to its minimum - ** required size. */ - assert( pPager->eLock==EXCLUSIVE_LOCK ); - rc = pager_truncate(pPager, pPager->dbSize); - } - - if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - } - - if( !pPager->exclusiveMode - && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) - ){ - rc2 = pagerUnlockDb(pPager, SHARED_LOCK); - pPager->changeCountDone = 0; - } - pPager->eState = PAGER_READER; - pPager->setMaster = 0; - - return (rc==SQLITE_OK?rc2:rc); -} - -/* -** Execute a rollback if a transaction is active and unlock the -** database file. -** -** If the pager has already entered the ERROR state, do not attempt -** the rollback at this time. Instead, pager_unlock() is called. The -** call to pager_unlock() will discard all in-memory pages, unlock -** the database file and move the pager back to OPEN state. If this -** means that there is a hot-journal left in the file-system, the next -** connection to obtain a shared lock on the pager (which may be this one) -** will roll it back. -** -** If the pager has not already entered the ERROR state, but an IO or -** malloc error occurs during a rollback, then this will itself cause -** the pager to enter the ERROR state. Which will be cleared by the -** call to pager_unlock(), as described above. -*/ -static void pagerUnlockAndRollback(Pager *pPager){ - if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ - assert( assert_pager_state(pPager) ); - if( pPager->eState>=PAGER_WRITER_LOCKED ){ - sqlite3BeginBenignMalloc(); - sqlite3PagerRollback(pPager); - sqlite3EndBenignMalloc(); - }else if( !pPager->exclusiveMode ){ - assert( pPager->eState==PAGER_READER ); - pager_end_transaction(pPager, 0, 0); - } - } - pager_unlock(pPager); -} - -/* -** Parameter aData must point to a buffer of pPager->pageSize bytes -** of data. Compute and return a checksum based ont the contents of the -** page of data and the current value of pPager->cksumInit. -** -** This is not a real checksum. It is really just the sum of the -** random initial value (pPager->cksumInit) and every 200th byte -** of the page data, starting with byte offset (pPager->pageSize%200). -** Each byte is interpreted as an 8-bit unsigned integer. -** -** Changing the formula used to compute this checksum results in an -** incompatible journal file format. -** -** If journal corruption occurs due to a power failure, the most likely -** scenario is that one end or the other of the record will be changed. -** It is much less likely that the two ends of the journal record will be -** correct and the middle be corrupt. Thus, this "checksum" scheme, -** though fast and simple, catches the mostly likely kind of corruption. -*/ -static u32 pager_cksum(Pager *pPager, const u8 *aData){ - u32 cksum = pPager->cksumInit; /* Checksum value to return */ - int i = pPager->pageSize-200; /* Loop counter */ - while( i>0 ){ - cksum += aData[i]; - i -= 200; - } - return cksum; -} - -/* -** Report the current page size and number of reserved bytes back -** to the codec. -*/ -#ifdef SQLITE_HAS_CODEC -static void pagerReportSize(Pager *pPager){ - if( pPager->xCodecSizeChng ){ - pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, - (int)pPager->nReserve); - } -} -#else -# define pagerReportSize(X) /* No-op if we do not support a codec */ -#endif - -#ifdef SQLITE_HAS_CODEC -/* -** Make sure the number of reserved bits is the same in the destination -** pager as it is in the source. This comes up when a VACUUM changes the -** number of reserved bits to the "optimal" amount. -*/ -SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){ - if( pDest->nReserve!=pSrc->nReserve ){ - pDest->nReserve = pSrc->nReserve; - pagerReportSize(pDest); - } -} -#endif - -/* -** Read a single page from either the journal file (if isMainJrnl==1) or -** from the sub-journal (if isMainJrnl==0) and playback that page. -** The page begins at offset *pOffset into the file. The *pOffset -** value is increased to the start of the next page in the journal. -** -** The main rollback journal uses checksums - the statement journal does -** not. -** -** If the page number of the page record read from the (sub-)journal file -** is greater than the current value of Pager.dbSize, then playback is -** skipped and SQLITE_OK is returned. -** -** If pDone is not NULL, then it is a record of pages that have already -** been played back. If the page at *pOffset has already been played back -** (if the corresponding pDone bit is set) then skip the playback. -** Make sure the pDone bit corresponding to the *pOffset page is set -** prior to returning. -** -** If the page record is successfully read from the (sub-)journal file -** and played back, then SQLITE_OK is returned. If an IO error occurs -** while reading the record from the (sub-)journal file or while writing -** to the database file, then the IO error code is returned. If data -** is successfully read from the (sub-)journal file but appears to be -** corrupted, SQLITE_DONE is returned. Data is considered corrupted in -** two circumstances: -** -** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or -** * If the record is being rolled back from the main journal file -** and the checksum field does not match the record content. -** -** Neither of these two scenarios are possible during a savepoint rollback. -** -** If this is a savepoint rollback, then memory may have to be dynamically -** allocated by this function. If this is the case and an allocation fails, -** SQLITE_NOMEM is returned. -*/ -static int pager_playback_one_page( - Pager *pPager, /* The pager being played back */ - i64 *pOffset, /* Offset of record to playback */ - Bitvec *pDone, /* Bitvec of pages already played back */ - int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ - int isSavepnt /* True for a savepoint rollback */ -){ - int rc; - PgHdr *pPg; /* An existing page in the cache */ - Pgno pgno; /* The page number of a page in journal */ - u32 cksum; /* Checksum used for sanity checking */ - char *aData; /* Temporary storage for the page */ - sqlite3_file *jfd; /* The file descriptor for the journal file */ - int isSynced; /* True if journal page is synced */ - - assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ - assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ - assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ - assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ - - aData = pPager->pTmpSpace; - assert( aData ); /* Temp storage must have already been allocated */ - assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); - - /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction - ** or savepoint rollback done at the request of the caller) or this is - ** a hot-journal rollback. If it is a hot-journal rollback, the pager - ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback - ** only reads from the main journal, not the sub-journal. - */ - assert( pPager->eState>=PAGER_WRITER_CACHEMOD - || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) - ); - assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); - - /* Read the page number and page data from the journal or sub-journal - ** file. Return an error code to the caller if an IO error occurs. - */ - jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; - rc = read32bits(jfd, *pOffset, &pgno); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); - if( rc!=SQLITE_OK ) return rc; - *pOffset += pPager->pageSize + 4 + isMainJrnl*4; - - /* Sanity checking on the page. This is more important that I originally - ** thought. If a power failure occurs while the journal is being written, - ** it could cause invalid data to be written into the journal. We need to - ** detect this invalid data (with high probability) and ignore it. - */ - if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ - assert( !isSavepnt ); - return SQLITE_DONE; - } - if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ - return SQLITE_OK; - } - if( isMainJrnl ){ - rc = read32bits(jfd, (*pOffset)-4, &cksum); - if( rc ) return rc; - if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ - return SQLITE_DONE; - } - } - - /* If this page has already been played back before during the current - ** rollback, then don't bother to play it back again. - */ - if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ - return rc; - } - - /* When playing back page 1, restore the nReserve setting - */ - if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ - pPager->nReserve = ((u8*)aData)[20]; - pagerReportSize(pPager); - } - - /* If the pager is in CACHEMOD state, then there must be a copy of this - ** page in the pager cache. In this case just update the pager cache, - ** not the database file. The page is left marked dirty in this case. - ** - ** An exception to the above rule: If the database is in no-sync mode - ** and a page is moved during an incremental vacuum then the page may - ** not be in the pager cache. Later: if a malloc() or IO error occurs - ** during a Movepage() call, then the page may not be in the cache - ** either. So the condition described in the above paragraph is not - ** assert()able. - ** - ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the - ** pager cache if it exists and the main file. The page is then marked - ** not dirty. Since this code is only executed in PAGER_OPEN state for - ** a hot-journal rollback, it is guaranteed that the page-cache is empty - ** if the pager is in OPEN state. - ** - ** Ticket #1171: The statement journal might contain page content that is - ** different from the page content at the start of the transaction. - ** This occurs when a page is changed prior to the start of a statement - ** then changed again within the statement. When rolling back such a - ** statement we must not write to the original database unless we know - ** for certain that original page contents are synced into the main rollback - ** journal. Otherwise, a power loss might leave modified data in the - ** database file without an entry in the rollback journal that can - ** restore the database to its original form. Two conditions must be - ** met before writing to the database files. (1) the database must be - ** locked. (2) we know that the original page content is fully synced - ** in the main journal either because the page is not in cache or else - ** the page is marked as needSync==0. - ** - ** 2008-04-14: When attempting to vacuum a corrupt database file, it - ** is possible to fail a statement on a database that does not yet exist. - ** Do not attempt to write if database file has never been opened. - */ - if( pagerUseWal(pPager) ){ - pPg = 0; - }else{ - pPg = sqlite3PagerLookup(pPager, pgno); - } - assert( pPg || !MEMDB ); - assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile ); - PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", - PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), - (isMainJrnl?"main-journal":"sub-journal") - )); - if( isMainJrnl ){ - isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); - }else{ - isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); - } - if( isOpen(pPager->fd) - && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) - && isSynced - ){ - i64 ofst = (pgno-1)*(i64)pPager->pageSize; - testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); - assert( !pagerUseWal(pPager) ); - rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); - if( pgno>pPager->dbFileSize ){ - pPager->dbFileSize = pgno; - } - if( pPager->pBackup ){ - CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); - sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); - CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData); - } - }else if( !isMainJrnl && pPg==0 ){ - /* If this is a rollback of a savepoint and data was not written to - ** the database and the page is not in-memory, there is a potential - ** problem. When the page is next fetched by the b-tree layer, it - ** will be read from the database file, which may or may not be - ** current. - ** - ** There are a couple of different ways this can happen. All are quite - ** obscure. When running in synchronous mode, this can only happen - ** if the page is on the free-list at the start of the transaction, then - ** populated, then moved using sqlite3PagerMovepage(). - ** - ** The solution is to add an in-memory page to the cache containing - ** the data just read from the sub-journal. Mark the page as dirty - ** and if the pager requires a journal-sync, then mark the page as - ** requiring a journal-sync before it is written. - */ - assert( isSavepnt ); - assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); - pPager->doNotSpill |= SPILLFLAG_ROLLBACK; - rc = sqlite3PagerGet(pPager, pgno, &pPg, 1); - assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); - pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; - if( rc!=SQLITE_OK ) return rc; - sqlite3PcacheMakeDirty(pPg); - } - if( pPg ){ - /* No page should ever be explicitly rolled back that is in use, except - ** for page 1 which is held in use in order to keep the lock on the - ** database active. However such a page may be rolled back as a result - ** of an internal error resulting in an automatic call to - ** sqlite3PagerRollback(). - */ - void *pData; - pData = pPg->pData; - memcpy(pData, (u8*)aData, pPager->pageSize); - pPager->xReiniter(pPg); - /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But - ** that call was dangerous and had no detectable benefit since the cache - ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so - ** has been removed. */ - pager_set_pagehash(pPg); - - /* If this was page 1, then restore the value of Pager.dbFileVers. - ** Do this before any decoding. */ - if( pgno==1 ){ - memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); - } - - /* Decode the page just read from disk */ - CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); - sqlite3PcacheRelease(pPg); - } - return rc; -} - -/* -** Parameter zMaster is the name of a master journal file. A single journal -** file that referred to the master journal file has just been rolled back. -** This routine checks if it is possible to delete the master journal file, -** and does so if it is. -** -** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not -** available for use within this function. -** -** When a master journal file is created, it is populated with the names -** of all of its child journals, one after another, formatted as utf-8 -** encoded text. The end of each child journal file is marked with a -** nul-terminator byte (0x00). i.e. the entire contents of a master journal -** file for a transaction involving two databases might be: -** -** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" -** -** A master journal file may only be deleted once all of its child -** journals have been rolled back. -** -** This function reads the contents of the master-journal file into -** memory and loops through each of the child journal names. For -** each child journal, it checks if: -** -** * if the child journal exists, and if so -** * if the child journal contains a reference to master journal -** file zMaster -** -** If a child journal can be found that matches both of the criteria -** above, this function returns without doing anything. Otherwise, if -** no such child journal can be found, file zMaster is deleted from -** the file-system using sqlite3OsDelete(). -** -** If an IO error within this function, an error code is returned. This -** function allocates memory by calling sqlite3Malloc(). If an allocation -** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors -** occur, SQLITE_OK is returned. -** -** TODO: This function allocates a single block of memory to load -** the entire contents of the master journal file. This could be -** a couple of kilobytes or so - potentially larger than the page -** size. -*/ -static int pager_delmaster(Pager *pPager, const char *zMaster){ - sqlite3_vfs *pVfs = pPager->pVfs; - int rc; /* Return code */ - sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ - sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ - char *zMasterJournal = 0; /* Contents of master journal file */ - i64 nMasterJournal; /* Size of master journal file */ - char *zJournal; /* Pointer to one journal within MJ file */ - char *zMasterPtr; /* Space to hold MJ filename from a journal file */ - int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */ - - /* Allocate space for both the pJournal and pMaster file descriptors. - ** If successful, open the master journal file for reading. - */ - pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); - pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); - if( !pMaster ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); - rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); - } - if( rc!=SQLITE_OK ) goto delmaster_out; - - /* Load the entire master journal file into space obtained from - ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain - ** sufficient space (in zMasterPtr) to hold the names of master - ** journal files extracted from regular rollback-journals. - */ - rc = sqlite3OsFileSize(pMaster, &nMasterJournal); - if( rc!=SQLITE_OK ) goto delmaster_out; - nMasterPtr = pVfs->mxPathname+1; - zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1); - if( !zMasterJournal ){ - rc = SQLITE_NOMEM_BKPT; - goto delmaster_out; - } - zMasterPtr = &zMasterJournal[nMasterJournal+1]; - rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); - if( rc!=SQLITE_OK ) goto delmaster_out; - zMasterJournal[nMasterJournal] = 0; - - zJournal = zMasterJournal; - while( (zJournal-zMasterJournal)pageSize bytes). -** If the file on disk is currently larger than nPage pages, then use the VFS -** xTruncate() method to truncate it. -** -** Or, it might be the case that the file on disk is smaller than -** nPage pages. Some operating system implementations can get confused if -** you try to truncate a file to some size that is larger than it -** currently is, so detect this case and write a single zero byte to -** the end of the new file instead. -** -** If successful, return SQLITE_OK. If an IO error occurs while modifying -** the database file, return the error code to the caller. -*/ -static int pager_truncate(Pager *pPager, Pgno nPage){ - int rc = SQLITE_OK; - assert( pPager->eState!=PAGER_ERROR ); - assert( pPager->eState!=PAGER_READER ); - - if( isOpen(pPager->fd) - && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) - ){ - i64 currentSize, newSize; - int szPage = pPager->pageSize; - assert( pPager->eLock==EXCLUSIVE_LOCK ); - /* TODO: Is it safe to use Pager.dbFileSize here? */ - rc = sqlite3OsFileSize(pPager->fd, ¤tSize); - newSize = szPage*(i64)nPage; - if( rc==SQLITE_OK && currentSize!=newSize ){ - if( currentSize>newSize ){ - rc = sqlite3OsTruncate(pPager->fd, newSize); - }else if( (currentSize+szPage)<=newSize ){ - char *pTmp = pPager->pTmpSpace; - memset(pTmp, 0, szPage); - testcase( (newSize-szPage) == currentSize ); - testcase( (newSize-szPage) > currentSize ); - rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); - } - if( rc==SQLITE_OK ){ - pPager->dbFileSize = nPage; - } - } - } - return rc; -} - -/* -** Return a sanitized version of the sector-size of OS file pFile. The -** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE. -*/ -SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){ - int iRet = sqlite3OsSectorSize(pFile); - if( iRet<32 ){ - iRet = 512; - }else if( iRet>MAX_SECTOR_SIZE ){ - assert( MAX_SECTOR_SIZE>=512 ); - iRet = MAX_SECTOR_SIZE; - } - return iRet; -} - -/* -** Set the value of the Pager.sectorSize variable for the given -** pager based on the value returned by the xSectorSize method -** of the open database file. The sector size will be used -** to determine the size and alignment of journal header and -** master journal pointers within created journal files. -** -** For temporary files the effective sector size is always 512 bytes. -** -** Otherwise, for non-temporary files, the effective sector size is -** the value returned by the xSectorSize() method rounded up to 32 if -** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it -** is greater than MAX_SECTOR_SIZE. -** -** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set -** the effective sector size to its minimum value (512). The purpose of -** pPager->sectorSize is to define the "blast radius" of bytes that -** might change if a crash occurs while writing to a single byte in -** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero -** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector -** size. For backwards compatibility of the rollback journal file format, -** we cannot reduce the effective sector size below 512. -*/ -static void setSectorSize(Pager *pPager){ - assert( isOpen(pPager->fd) || pPager->tempFile ); - - if( pPager->tempFile - || (sqlite3OsDeviceCharacteristics(pPager->fd) & - SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 - ){ - /* Sector size doesn't matter for temporary files. Also, the file - ** may not have been opened yet, in which case the OsSectorSize() - ** call will segfault. */ - pPager->sectorSize = 512; - }else{ - pPager->sectorSize = sqlite3SectorSize(pPager->fd); - } -} - -/* -** Playback the journal and thus restore the database file to -** the state it was in before we started making changes. -** -** The journal file format is as follows: -** -** (1) 8 byte prefix. A copy of aJournalMagic[]. -** (2) 4 byte big-endian integer which is the number of valid page records -** in the journal. If this value is 0xffffffff, then compute the -** number of page records from the journal size. -** (3) 4 byte big-endian integer which is the initial value for the -** sanity checksum. -** (4) 4 byte integer which is the number of pages to truncate the -** database to during a rollback. -** (5) 4 byte big-endian integer which is the sector size. The header -** is this many bytes in size. -** (6) 4 byte big-endian integer which is the page size. -** (7) zero padding out to the next sector size. -** (8) Zero or more pages instances, each as follows: -** + 4 byte page number. -** + pPager->pageSize bytes of data. -** + 4 byte checksum -** -** When we speak of the journal header, we mean the first 7 items above. -** Each entry in the journal is an instance of the 8th item. -** -** Call the value from the second bullet "nRec". nRec is the number of -** valid page entries in the journal. In most cases, you can compute the -** value of nRec from the size of the journal file. But if a power -** failure occurred while the journal was being written, it could be the -** case that the size of the journal file had already been increased but -** the extra entries had not yet made it safely to disk. In such a case, -** the value of nRec computed from the file size would be too large. For -** that reason, we always use the nRec value in the header. -** -** If the nRec value is 0xffffffff it means that nRec should be computed -** from the file size. This value is used when the user selects the -** no-sync option for the journal. A power failure could lead to corruption -** in this case. But for things like temporary table (which will be -** deleted when the power is restored) we don't care. -** -** If the file opened as the journal file is not a well-formed -** journal file then all pages up to the first corrupted page are rolled -** back (or no pages if the journal header is corrupted). The journal file -** is then deleted and SQLITE_OK returned, just as if no corruption had -** been encountered. -** -** If an I/O or malloc() error occurs, the journal-file is not deleted -** and an error code is returned. -** -** The isHot parameter indicates that we are trying to rollback a journal -** that might be a hot journal. Or, it could be that the journal is -** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. -** If the journal really is hot, reset the pager cache prior rolling -** back any content. If the journal is merely persistent, no reset is -** needed. -*/ -static int pager_playback(Pager *pPager, int isHot){ - sqlite3_vfs *pVfs = pPager->pVfs; - i64 szJ; /* Size of the journal file in bytes */ - u32 nRec; /* Number of Records in the journal */ - u32 u; /* Unsigned loop counter */ - Pgno mxPg = 0; /* Size of the original file in pages */ - int rc; /* Result code of a subroutine */ - int res = 1; /* Value returned by sqlite3OsAccess() */ - char *zMaster = 0; /* Name of master journal file if any */ - int needPagerReset; /* True to reset page prior to first page rollback */ - int nPlayback = 0; /* Total number of pages restored from journal */ - - /* Figure out how many records are in the journal. Abort early if - ** the journal is empty. - */ - assert( isOpen(pPager->jfd) ); - rc = sqlite3OsFileSize(pPager->jfd, &szJ); - if( rc!=SQLITE_OK ){ - goto end_playback; - } - - /* Read the master journal name from the journal, if it is present. - ** If a master journal file name is specified, but the file is not - ** present on disk, then the journal is not hot and does not need to be - ** played back. - ** - ** TODO: Technically the following is an error because it assumes that - ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that - ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, - ** mxPathname is 512, which is the same as the minimum allowable value - ** for pageSize. - */ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - if( rc==SQLITE_OK && zMaster[0] ){ - rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); - } - zMaster = 0; - if( rc!=SQLITE_OK || !res ){ - goto end_playback; - } - pPager->journalOff = 0; - needPagerReset = isHot; - - /* This loop terminates either when a readJournalHdr() or - ** pager_playback_one_page() call returns SQLITE_DONE or an IO error - ** occurs. - */ - while( 1 ){ - /* Read the next journal header from the journal file. If there are - ** not enough bytes left in the journal file for a complete header, or - ** it is corrupted, then a process must have failed while writing it. - ** This indicates nothing more needs to be rolled back. - */ - rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - } - goto end_playback; - } - - /* If nRec is 0xffffffff, then this journal was created by a process - ** working in no-sync mode. This means that the rest of the journal - ** file consists of pages, there are no more journal headers. Compute - ** the value of nRec based on this assumption. - */ - if( nRec==0xffffffff ){ - assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); - nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager)); - } - - /* If nRec is 0 and this rollback is of a transaction created by this - ** process and if this is the final header in the journal, then it means - ** that this part of the journal was being filled but has not yet been - ** synced to disk. Compute the number of pages based on the remaining - ** size of the file. - ** - ** The third term of the test was added to fix ticket #2565. - ** When rolling back a hot journal, nRec==0 always means that the next - ** chunk of the journal contains zero pages to be rolled back. But - ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in - ** the journal, it means that the journal might contain additional - ** pages that need to be rolled back and that the number of pages - ** should be computed based on the journal file size. - */ - if( nRec==0 && !isHot && - pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ - nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); - } - - /* If this is the first header read from the journal, truncate the - ** database file back to its original size. - */ - if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ - rc = pager_truncate(pPager, mxPg); - if( rc!=SQLITE_OK ){ - goto end_playback; - } - pPager->dbSize = mxPg; - } - - /* Copy original pages out of the journal and back into the - ** database file and/or page cache. - */ - for(u=0; ujournalOff,0,1,0); - if( rc==SQLITE_OK ){ - nPlayback++; - }else{ - if( rc==SQLITE_DONE ){ - pPager->journalOff = szJ; - break; - }else if( rc==SQLITE_IOERR_SHORT_READ ){ - /* If the journal has been truncated, simply stop reading and - ** processing the journal. This might happen if the journal was - ** not completely written and synced prior to a crash. In that - ** case, the database should have never been written in the - ** first place so it is OK to simply abandon the rollback. */ - rc = SQLITE_OK; - goto end_playback; - }else{ - /* If we are unable to rollback, quit and return the error - ** code. This will cause the pager to enter the error state - ** so that no further harm will be done. Perhaps the next - ** process to come along will be able to rollback the database. - */ - goto end_playback; - } - } - } - } - /*NOTREACHED*/ - assert( 0 ); - -end_playback: - /* Following a rollback, the database file should be back in its original - ** state prior to the start of the transaction, so invoke the - ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the - ** assertion that the transaction counter was modified. - */ -#ifdef SQLITE_DEBUG - if( pPager->fd->pMethods ){ - sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); - } -#endif - - /* If this playback is happening automatically as a result of an IO or - ** malloc error that occurred after the change-counter was updated but - ** before the transaction was committed, then the change-counter - ** modification may just have been reverted. If this happens in exclusive - ** mode, then subsequent transactions performed by the connection will not - ** update the change-counter at all. This may lead to cache inconsistency - ** problems for other processes at some point in the future. So, just - ** in case this has happened, clear the changeCountDone flag now. - */ - pPager->changeCountDone = pPager->tempFile; - - if( rc==SQLITE_OK ){ - zMaster = pPager->pTmpSpace; - rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); - testcase( rc!=SQLITE_OK ); - } - if( rc==SQLITE_OK - && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) - ){ - rc = sqlite3PagerSync(pPager, 0); - } - if( rc==SQLITE_OK ){ - rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0); - testcase( rc!=SQLITE_OK ); - } - if( rc==SQLITE_OK && zMaster[0] && res ){ - /* If there was a master journal and this routine will return success, - ** see if it is possible to delete the master journal. - */ - rc = pager_delmaster(pPager, zMaster); - testcase( rc!=SQLITE_OK ); - } - if( isHot && nPlayback ){ - sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", - nPlayback, pPager->zJournal); - } - - /* The Pager.sectorSize variable may have been updated while rolling - ** back a journal created by a process with a different sector size - ** value. Reset it to the correct value for this process. - */ - setSectorSize(pPager); - return rc; -} - - -/* -** Read the content for page pPg out of the database file and into -** pPg->pData. A shared lock or greater must be held on the database -** file before this function is called. -** -** If page 1 is read, then the value of Pager.dbFileVers[] is set to -** the value read from the database file. -** -** If an IO error occurs, then the IO error is returned to the caller. -** Otherwise, SQLITE_OK is returned. -*/ -static int readDbPage(PgHdr *pPg, u32 iFrame){ - Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ - Pgno pgno = pPg->pgno; /* Page number to read */ - int rc = SQLITE_OK; /* Return code */ - int pgsz = pPager->pageSize; /* Number of bytes to read */ - - assert( pPager->eState>=PAGER_READER && !MEMDB ); - assert( isOpen(pPager->fd) ); - -#ifndef SQLITE_OMIT_WAL - if( iFrame ){ - /* Try to pull the page from the write-ahead log. */ - rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); - }else -#endif - { - i64 iOffset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - } - - if( pgno==1 ){ - if( rc ){ - /* If the read is unsuccessful, set the dbFileVers[] to something - ** that will never be a valid file version. dbFileVers[] is a copy - ** of bytes 24..39 of the database. Bytes 28..31 should always be - ** zero or the size of the database in page. Bytes 32..35 and 35..39 - ** should be page numbers which are never 0xffffffff. So filling - ** pPager->dbFileVers[] with all 0xff bytes should suffice. - ** - ** For an encrypted database, the situation is more complex: bytes - ** 24..39 of the database are white noise. But the probability of - ** white noise equaling 16 bytes of 0xff is vanishingly small so - ** we should still be ok. - */ - memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); - }else{ - u8 *dbFileVers = &((u8*)pPg->pData)[24]; - memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); - } - } - CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT); - - PAGER_INCR(sqlite3_pager_readdb_count); - PAGER_INCR(pPager->nRead); - IOTRACE(("PGIN %p %d\n", pPager, pgno)); - PAGERTRACE(("FETCH %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_pagehash(pPg))); - - return rc; -} - -/* -** Update the value of the change-counter at offsets 24 and 92 in -** the header and the sqlite version number at offset 96. -** -** This is an unconditional update. See also the pager_incr_changecounter() -** routine which only updates the change-counter if the update is actually -** needed, as determined by the pPager->changeCountDone state variable. -*/ -static void pager_write_changecounter(PgHdr *pPg){ - u32 change_counter; - - /* Increment the value just read and write it back to byte 24. */ - change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; - put32bits(((char*)pPg->pData)+24, change_counter); - - /* Also store the SQLite version number in bytes 96..99 and in - ** bytes 92..95 store the change counter for which the version number - ** is valid. */ - put32bits(((char*)pPg->pData)+92, change_counter); - put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); -} - -#ifndef SQLITE_OMIT_WAL -/* -** This function is invoked once for each page that has already been -** written into the log file when a WAL transaction is rolled back. -** Parameter iPg is the page number of said page. The pCtx argument -** is actually a pointer to the Pager structure. -** -** If page iPg is present in the cache, and has no outstanding references, -** it is discarded. Otherwise, if there are one or more outstanding -** references, the page content is reloaded from the database. If the -** attempt to reload content from the database is required and fails, -** return an SQLite error code. Otherwise, SQLITE_OK. -*/ -static int pagerUndoCallback(void *pCtx, Pgno iPg){ - int rc = SQLITE_OK; - Pager *pPager = (Pager *)pCtx; - PgHdr *pPg; - - assert( pagerUseWal(pPager) ); - pPg = sqlite3PagerLookup(pPager, iPg); - if( pPg ){ - if( sqlite3PcachePageRefcount(pPg)==1 ){ - sqlite3PcacheDrop(pPg); - }else{ - u32 iFrame = 0; - rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); - if( rc==SQLITE_OK ){ - rc = readDbPage(pPg, iFrame); - } - if( rc==SQLITE_OK ){ - pPager->xReiniter(pPg); - } - sqlite3PagerUnrefNotNull(pPg); - } - } - - /* Normally, if a transaction is rolled back, any backup processes are - ** updated as data is copied out of the rollback journal and into the - ** database. This is not generally possible with a WAL database, as - ** rollback involves simply truncating the log file. Therefore, if one - ** or more frames have already been written to the log (and therefore - ** also copied into the backup databases) as part of this transaction, - ** the backups must be restarted. - */ - sqlite3BackupRestart(pPager->pBackup); - - return rc; -} - -/* -** This function is called to rollback a transaction on a WAL database. -*/ -static int pagerRollbackWal(Pager *pPager){ - int rc; /* Return Code */ - PgHdr *pList; /* List of dirty pages to revert */ - - /* For all pages in the cache that are currently dirty or have already - ** been written (but not committed) to the log file, do one of the - ** following: - ** - ** + Discard the cached page (if refcount==0), or - ** + Reload page content from the database (if refcount>0). - */ - pPager->dbSize = pPager->dbOrigSize; - rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); - pList = sqlite3PcacheDirtyList(pPager->pPCache); - while( pList && rc==SQLITE_OK ){ - PgHdr *pNext = pList->pDirty; - rc = pagerUndoCallback((void *)pPager, pList->pgno); - pList = pNext; - } - - return rc; -} - -/* -** This function is a wrapper around sqlite3WalFrames(). As well as logging -** the contents of the list of pages headed by pList (connected by pDirty), -** this function notifies any active backup processes that the pages have -** changed. -** -** The list of pages passed into this routine is always sorted by page number. -** Hence, if page 1 appears anywhere on the list, it will be the first page. -*/ -static int pagerWalFrames( - Pager *pPager, /* Pager object */ - PgHdr *pList, /* List of frames to log */ - Pgno nTruncate, /* Database size after this commit */ - int isCommit /* True if this is a commit */ -){ - int rc; /* Return code */ - int nList; /* Number of pages in pList */ - PgHdr *p; /* For looping over pages */ - - assert( pPager->pWal ); - assert( pList ); -#ifdef SQLITE_DEBUG - /* Verify that the page list is in accending order */ - for(p=pList; p && p->pDirty; p=p->pDirty){ - assert( p->pgno < p->pDirty->pgno ); - } -#endif - - assert( pList->pDirty==0 || isCommit ); - if( isCommit ){ - /* If a WAL transaction is being committed, there is no point in writing - ** any pages with page numbers greater than nTruncate into the WAL file. - ** They will never be read by any client. So remove them from the pDirty - ** list here. */ - PgHdr **ppNext = &pList; - nList = 0; - for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ - if( p->pgno<=nTruncate ){ - ppNext = &p->pDirty; - nList++; - } - } - assert( pList ); - }else{ - nList = 1; - } - pPager->aStat[PAGER_STAT_WRITE] += nList; - - if( pList->pgno==1 ) pager_write_changecounter(pList); - rc = sqlite3WalFrames(pPager->pWal, - pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags - ); - if( rc==SQLITE_OK && pPager->pBackup ){ - for(p=pList; p; p=p->pDirty){ - sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); - } - } - -#ifdef SQLITE_CHECK_PAGES - pList = sqlite3PcacheDirtyList(pPager->pPCache); - for(p=pList; p; p=p->pDirty){ - pager_set_pagehash(p); - } -#endif - - return rc; -} - -/* -** Begin a read transaction on the WAL. -** -** This routine used to be called "pagerOpenSnapshot()" because it essentially -** makes a snapshot of the database at the current point in time and preserves -** that snapshot for use by the reader in spite of concurrently changes by -** other writers or checkpointers. -*/ -static int pagerBeginReadTransaction(Pager *pPager){ - int rc; /* Return code */ - int changed = 0; /* True if cache must be reset */ - - assert( pagerUseWal(pPager) ); - assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); - - /* sqlite3WalEndReadTransaction() was not called for the previous - ** transaction in locking_mode=EXCLUSIVE. So call it now. If we - ** are in locking_mode=NORMAL and EndRead() was previously called, - ** the duplicate call is harmless. - */ - sqlite3WalEndReadTransaction(pPager->pWal); - - rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); - if( rc!=SQLITE_OK || changed ){ - pager_reset(pPager); - if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); - } - - return rc; -} -#endif - -/* -** This function is called as part of the transition from PAGER_OPEN -** to PAGER_READER state to determine the size of the database file -** in pages (assuming the page size currently stored in Pager.pageSize). -** -** If no error occurs, SQLITE_OK is returned and the size of the database -** in pages is stored in *pnPage. Otherwise, an error code (perhaps -** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. -*/ -static int pagerPagecount(Pager *pPager, Pgno *pnPage){ - Pgno nPage; /* Value to return via *pnPage */ - - /* Query the WAL sub-system for the database size. The WalDbsize() - ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or - ** if the database size is not available. The database size is not - ** available from the WAL sub-system if the log file is empty or - ** contains no valid committed transactions. - */ - assert( pPager->eState==PAGER_OPEN ); - assert( pPager->eLock>=SHARED_LOCK ); - assert( isOpen(pPager->fd) ); - assert( pPager->tempFile==0 ); - nPage = sqlite3WalDbsize(pPager->pWal); - - /* If the number of pages in the database is not available from the - ** WAL sub-system, determine the page counte based on the size of - ** the database file. If the size of the database file is not an - ** integer multiple of the page-size, round up the result. - */ - if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){ - i64 n = 0; /* Size of db file in bytes */ - int rc = sqlite3OsFileSize(pPager->fd, &n); - if( rc!=SQLITE_OK ){ - return rc; - } - nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); - } - - /* If the current number of pages in the file is greater than the - ** configured maximum pager number, increase the allowed limit so - ** that the file can be read. - */ - if( nPage>pPager->mxPgno ){ - pPager->mxPgno = (Pgno)nPage; - } - - *pnPage = nPage; - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_WAL -/* -** Check if the *-wal file that corresponds to the database opened by pPager -** exists if the database is not empy, or verify that the *-wal file does -** not exist (by deleting it) if the database file is empty. -** -** If the database is not empty and the *-wal file exists, open the pager -** in WAL mode. If the database is empty or if no *-wal file exists and -** if no error occurs, make sure Pager.journalMode is not set to -** PAGER_JOURNALMODE_WAL. -** -** Return SQLITE_OK or an error code. -** -** The caller must hold a SHARED lock on the database file to call this -** function. Because an EXCLUSIVE lock on the db file is required to delete -** a WAL on a none-empty database, this ensures there is no race condition -** between the xAccess() below and an xDelete() being executed by some -** other connection. -*/ -static int pagerOpenWalIfPresent(Pager *pPager){ - int rc = SQLITE_OK; - assert( pPager->eState==PAGER_OPEN ); - assert( pPager->eLock>=SHARED_LOCK ); - - if( !pPager->tempFile ){ - int isWal; /* True if WAL file exists */ - Pgno nPage; /* Size of the database file */ - - rc = pagerPagecount(pPager, &nPage); - if( rc ) return rc; - if( nPage==0 ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); - if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK; - isWal = 0; - }else{ - rc = sqlite3OsAccess( - pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal - ); - } - if( rc==SQLITE_OK ){ - if( isWal ){ - testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); - rc = sqlite3PagerOpenWal(pPager, 0); - }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ - pPager->journalMode = PAGER_JOURNALMODE_DELETE; - } - } - } - return rc; -} -#endif - -/* -** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback -** the entire master journal file. The case pSavepoint==NULL occurs when -** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction -** savepoint. -** -** When pSavepoint is not NULL (meaning a non-transaction savepoint is -** being rolled back), then the rollback consists of up to three stages, -** performed in the order specified: -** -** * Pages are played back from the main journal starting at byte -** offset PagerSavepoint.iOffset and continuing to -** PagerSavepoint.iHdrOffset, or to the end of the main journal -** file if PagerSavepoint.iHdrOffset is zero. -** -** * If PagerSavepoint.iHdrOffset is not zero, then pages are played -** back starting from the journal header immediately following -** PagerSavepoint.iHdrOffset to the end of the main journal file. -** -** * Pages are then played back from the sub-journal file, starting -** with the PagerSavepoint.iSubRec and continuing to the end of -** the journal file. -** -** Throughout the rollback process, each time a page is rolled back, the -** corresponding bit is set in a bitvec structure (variable pDone in the -** implementation below). This is used to ensure that a page is only -** rolled back the first time it is encountered in either journal. -** -** If pSavepoint is NULL, then pages are only played back from the main -** journal file. There is no need for a bitvec in this case. -** -** In either case, before playback commences the Pager.dbSize variable -** is reset to the value that it held at the start of the savepoint -** (or transaction). No page with a page-number greater than this value -** is played back. If one is encountered it is simply skipped. -*/ -static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ - i64 szJ; /* Effective size of the main journal */ - i64 iHdrOff; /* End of first segment of main-journal records */ - int rc = SQLITE_OK; /* Return code */ - Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ - - assert( pPager->eState!=PAGER_ERROR ); - assert( pPager->eState>=PAGER_WRITER_LOCKED ); - - /* Allocate a bitvec to use to store the set of pages rolled back */ - if( pSavepoint ){ - pDone = sqlite3BitvecCreate(pSavepoint->nOrig); - if( !pDone ){ - return SQLITE_NOMEM_BKPT; - } - } - - /* Set the database size back to the value it was before the savepoint - ** being reverted was opened. - */ - pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; - pPager->changeCountDone = pPager->tempFile; - - if( !pSavepoint && pagerUseWal(pPager) ){ - return pagerRollbackWal(pPager); - } - - /* Use pPager->journalOff as the effective size of the main rollback - ** journal. The actual file might be larger than this in - ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything - ** past pPager->journalOff is off-limits to us. - */ - szJ = pPager->journalOff; - assert( pagerUseWal(pPager)==0 || szJ==0 ); - - /* Begin by rolling back records from the main journal starting at - ** PagerSavepoint.iOffset and continuing to the next journal header. - ** There might be records in the main journal that have a page number - ** greater than the current database size (pPager->dbSize) but those - ** will be skipped automatically. Pages are added to pDone as they - ** are played back. - */ - if( pSavepoint && !pagerUseWal(pPager) ){ - iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; - pPager->journalOff = pSavepoint->iOffset; - while( rc==SQLITE_OK && pPager->journalOffjournalOff, pDone, 1, 1); - } - assert( rc!=SQLITE_DONE ); - }else{ - pPager->journalOff = 0; - } - - /* Continue rolling back records out of the main journal starting at - ** the first journal header seen and continuing until the effective end - ** of the main journal file. Continue to skip out-of-range pages and - ** continue adding pages rolled back to pDone. - */ - while( rc==SQLITE_OK && pPager->journalOffjournalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff" - ** test is related to ticket #2565. See the discussion in the - ** pager_playback() function for additional information. - */ - if( nJRec==0 - && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff - ){ - nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); - } - for(ii=0; rc==SQLITE_OK && iijournalOffjournalOff, pDone, 1, 1); - } - assert( rc!=SQLITE_DONE ); - } - assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); - - /* Finally, rollback pages from the sub-journal. Page that were - ** previously rolled back out of the main journal (and are hence in pDone) - ** will be skipped. Out-of-range pages are also skipped. - */ - if( pSavepoint ){ - u32 ii; /* Loop counter */ - i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); - - if( pagerUseWal(pPager) ){ - rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); - } - for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ - assert( offset==(i64)ii*(4+pPager->pageSize) ); - rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); - } - assert( rc!=SQLITE_DONE ); - } - - sqlite3BitvecDestroy(pDone); - if( rc==SQLITE_OK ){ - pPager->journalOff = szJ; - } - - return rc; -} - -/* -** Change the maximum number of in-memory pages that are allowed -** before attempting to recycle clean and unused pages. -*/ -SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ - sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); -} - -/* -** Change the maximum number of in-memory pages that are allowed -** before attempting to spill pages to journal. -*/ -SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ - return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); -} - -/* -** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. -*/ -static void pagerFixMaplimit(Pager *pPager){ -#if SQLITE_MAX_MMAP_SIZE>0 - sqlite3_file *fd = pPager->fd; - if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ - sqlite3_int64 sz; - sz = pPager->szMmap; - pPager->bUseFetch = (sz>0); - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); - } -#endif -} - -/* -** Change the maximum size of any memory mapping made of the database file. -*/ -SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ - pPager->szMmap = szMmap; - pagerFixMaplimit(pPager); -} - -/* -** Free as much memory as possible from the pager. -*/ -SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ - sqlite3PcacheShrink(pPager->pPCache); -} - -/* -** Adjust settings of the pager to those specified in the pgFlags parameter. -** -** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness -** of the database to damage due to OS crashes or power failures by -** changing the number of syncs()s when writing the journals. -** There are four levels: -** -** OFF sqlite3OsSync() is never called. This is the default -** for temporary and transient files. -** -** NORMAL The journal is synced once before writes begin on the -** database. This is normally adequate protection, but -** it is theoretically possible, though very unlikely, -** that an inopertune power failure could leave the journal -** in a state which would cause damage to the database -** when it is rolled back. -** -** FULL The journal is synced twice before writes begin on the -** database (with some additional information - the nRec field -** of the journal header - being written in between the two -** syncs). If we assume that writing a -** single disk sector is atomic, then this mode provides -** assurance that the journal will not be corrupted to the -** point of causing damage to the database during rollback. -** -** EXTRA This is like FULL except that is also syncs the directory -** that contains the rollback journal after the rollback -** journal is unlinked. -** -** The above is for a rollback-journal mode. For WAL mode, OFF continues -** to mean that no syncs ever occur. NORMAL means that the WAL is synced -** prior to the start of checkpoint and that the database file is synced -** at the conclusion of the checkpoint if the entire content of the WAL -** was written back into the database. But no sync operations occur for -** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL -** file is synced following each commit operation, in addition to the -** syncs associated with NORMAL. There is no difference between FULL -** and EXTRA for WAL mode. -** -** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The -** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync -** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an -** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL -** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the -** synchronous=FULL versus synchronous=NORMAL setting determines when -** the xSync primitive is called and is relevant to all platforms. -** -** Numeric values associated with these states are OFF==1, NORMAL=2, -** and FULL=3. -*/ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE void sqlite3PagerSetFlags( - Pager *pPager, /* The pager to set safety level for */ - unsigned pgFlags /* Various flags */ -){ - unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; - if( pPager->tempFile ){ - pPager->noSync = 1; - pPager->fullSync = 0; - pPager->extraSync = 0; - }else{ - pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0; - pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; - pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0; - } - if( pPager->noSync ){ - pPager->syncFlags = 0; - pPager->ckptSyncFlags = 0; - }else if( pgFlags & PAGER_FULLFSYNC ){ - pPager->syncFlags = SQLITE_SYNC_FULL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; - }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ - pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; - }else{ - pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; - } - pPager->walSyncFlags = pPager->syncFlags; - if( pPager->fullSync ){ - pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; - } - if( pgFlags & PAGER_CACHESPILL ){ - pPager->doNotSpill &= ~SPILLFLAG_OFF; - }else{ - pPager->doNotSpill |= SPILLFLAG_OFF; - } -} -#endif - -/* -** The following global variable is incremented whenever the library -** attempts to open a temporary file. This information is used for -** testing and analysis only. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_opentemp_count = 0; -#endif - -/* -** Open a temporary file. -** -** Write the file descriptor into *pFile. Return SQLITE_OK on success -** or some other error code if we fail. The OS will automatically -** delete the temporary file when it is closed. -** -** The flags passed to the VFS layer xOpen() call are those specified -** by parameter vfsFlags ORed with the following: -** -** SQLITE_OPEN_READWRITE -** SQLITE_OPEN_CREATE -** SQLITE_OPEN_EXCLUSIVE -** SQLITE_OPEN_DELETEONCLOSE -*/ -static int pagerOpentemp( - Pager *pPager, /* The pager object */ - sqlite3_file *pFile, /* Write the file descriptor here */ - int vfsFlags /* Flags passed through to the VFS */ -){ - int rc; /* Return code */ - -#ifdef SQLITE_TEST - sqlite3_opentemp_count++; /* Used for testing and analysis only */ -#endif - - vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; - rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); - assert( rc!=SQLITE_OK || isOpen(pFile) ); - return rc; -} - -/* -** Set the busy handler function. -** -** The pager invokes the busy-handler if sqlite3OsLock() returns -** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, -** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE -** lock. It does *not* invoke the busy handler when upgrading from -** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE -** (which occurs during hot-journal rollback). Summary: -** -** Transition | Invokes xBusyHandler -** -------------------------------------------------------- -** NO_LOCK -> SHARED_LOCK | Yes -** SHARED_LOCK -> RESERVED_LOCK | No -** SHARED_LOCK -> EXCLUSIVE_LOCK | No -** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes -** -** If the busy-handler callback returns non-zero, the lock is -** retried. If it returns zero, then the SQLITE_BUSY error is -** returned to the caller of the pager API function. -*/ -SQLITE_PRIVATE void sqlite3PagerSetBusyhandler( - Pager *pPager, /* Pager object */ - int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ - void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ -){ - pPager->xBusyHandler = xBusyHandler; - pPager->pBusyHandlerArg = pBusyHandlerArg; - - if( isOpen(pPager->fd) ){ - void **ap = (void **)&pPager->xBusyHandler; - assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); - assert( ap[1]==pBusyHandlerArg ); - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); - } -} - -/* -** Change the page size used by the Pager object. The new page size -** is passed in *pPageSize. -** -** If the pager is in the error state when this function is called, it -** is a no-op. The value returned is the error state error code (i.e. -** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). -** -** Otherwise, if all of the following are true: -** -** * the new page size (value of *pPageSize) is valid (a power -** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and -** -** * there are no outstanding page references, and -** -** * the database is either not an in-memory database or it is -** an in-memory database that currently consists of zero pages. -** -** then the pager object page size is set to *pPageSize. -** -** If the page size is changed, then this function uses sqlite3PagerMalloc() -** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt -** fails, SQLITE_NOMEM is returned and the page size remains unchanged. -** In all other cases, SQLITE_OK is returned. -** -** If the page size is not changed, either because one of the enumerated -** conditions above is not true, the pager was in error state when this -** function was called, or because the memory allocation attempt failed, -** then *pPageSize is set to the old, retained page size before returning. -*/ -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ - int rc = SQLITE_OK; - - /* It is not possible to do a full assert_pager_state() here, as this - ** function may be called from within PagerOpen(), before the state - ** of the Pager object is internally consistent. - ** - ** At one point this function returned an error if the pager was in - ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that - ** there is at least one outstanding page reference, this function - ** is a no-op for that case anyhow. - */ - - u32 pageSize = *pPageSize; - assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); - if( (pPager->memDb==0 || pPager->dbSize==0) - && sqlite3PcacheRefCount(pPager->pPCache)==0 - && pageSize && pageSize!=(u32)pPager->pageSize - ){ - char *pNew = NULL; /* New temp space */ - i64 nByte = 0; - - if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ - rc = sqlite3OsFileSize(pPager->fd, &nByte); - } - if( rc==SQLITE_OK ){ - pNew = (char *)sqlite3PageMalloc(pageSize); - if( !pNew ) rc = SQLITE_NOMEM_BKPT; - } - - if( rc==SQLITE_OK ){ - pager_reset(pPager); - rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); - } - if( rc==SQLITE_OK ){ - sqlite3PageFree(pPager->pTmpSpace); - pPager->pTmpSpace = pNew; - pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); - pPager->pageSize = pageSize; - }else{ - sqlite3PageFree(pNew); - } - } - - *pPageSize = pPager->pageSize; - if( rc==SQLITE_OK ){ - if( nReserve<0 ) nReserve = pPager->nReserve; - assert( nReserve>=0 && nReserve<1000 ); - pPager->nReserve = (i16)nReserve; - pagerReportSize(pPager); - pagerFixMaplimit(pPager); - } - return rc; -} - -/* -** Return a pointer to the "temporary page" buffer held internally -** by the pager. This is a buffer that is big enough to hold the -** entire content of a database page. This buffer is used internally -** during rollback and will be overwritten whenever a rollback -** occurs. But other modules are free to use it too, as long as -** no rollbacks are happening. -*/ -SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ - return pPager->pTmpSpace; -} - -/* -** Attempt to set the maximum database page count if mxPage is positive. -** Make no changes if mxPage is zero or negative. And never reduce the -** maximum page count below the current size of the database. -** -** Regardless of mxPage, return the current maximum page count. -*/ -SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ - if( mxPage>0 ){ - pPager->mxPgno = mxPage; - } - assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ - assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ - return pPager->mxPgno; -} - -/* -** The following set of routines are used to disable the simulated -** I/O error mechanism. These routines are used to avoid simulated -** errors in places where we do not care about errors. -** -** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops -** and generate no code. -*/ -#ifdef SQLITE_TEST -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_hit; -static int saved_cnt; -void disable_simulated_io_errors(void){ - saved_cnt = sqlite3_io_error_pending; - sqlite3_io_error_pending = -1; -} -void enable_simulated_io_errors(void){ - sqlite3_io_error_pending = saved_cnt; -} -#else -# define disable_simulated_io_errors() -# define enable_simulated_io_errors() -#endif - -/* -** Read the first N bytes from the beginning of the file into memory -** that pDest points to. -** -** If the pager was opened on a transient file (zFilename==""), or -** opened on a file less than N bytes in size, the output buffer is -** zeroed and SQLITE_OK returned. The rationale for this is that this -** function is used to read database headers, and a new transient or -** zero sized database has a header than consists entirely of zeroes. -** -** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered, -** the error code is returned to the caller and the contents of the -** output buffer undefined. -*/ -SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ - int rc = SQLITE_OK; - memset(pDest, 0, N); - assert( isOpen(pPager->fd) || pPager->tempFile ); - - /* This routine is only called by btree immediately after creating - ** the Pager object. There has not been an opportunity to transition - ** to WAL mode yet. - */ - assert( !pagerUseWal(pPager) ); - - if( isOpen(pPager->fd) ){ - IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) - rc = sqlite3OsRead(pPager->fd, pDest, N, 0); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - } - return rc; -} - -/* -** This function may only be called when a read-transaction is open on -** the pager. It returns the total number of pages in the database. -** -** However, if the file is between 1 and bytes in size, then -** this is considered a 1 page file. -*/ -SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ - assert( pPager->eState>=PAGER_READER ); - assert( pPager->eState!=PAGER_WRITER_FINISHED ); - *pnPage = (int)pPager->dbSize; -} - - -/* -** Try to obtain a lock of type locktype on the database file. If -** a similar or greater lock is already held, this function is a no-op -** (returning SQLITE_OK immediately). -** -** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke -** the busy callback if the lock is currently not available. Repeat -** until the busy callback returns false or until the attempt to -** obtain the lock succeeds. -** -** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. If the lock is obtained successfully, set the Pager.state -** variable to locktype before returning. -*/ -static int pager_wait_on_lock(Pager *pPager, int locktype){ - int rc; /* Return code */ - - /* Check that this is either a no-op (because the requested lock is - ** already held), or one of the transitions that the busy-handler - ** may be invoked during, according to the comment above - ** sqlite3PagerSetBusyhandler(). - */ - assert( (pPager->eLock>=locktype) - || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) - || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) - ); - - do { - rc = pagerLockDb(pPager, locktype); - }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); - return rc; -} - -/* -** Function assertTruncateConstraint(pPager) checks that one of the -** following is true for all dirty pages currently in the page-cache: -** -** a) The page number is less than or equal to the size of the -** current database image, in pages, OR -** -** b) if the page content were written at this time, it would not -** be necessary to write the current content out to the sub-journal -** (as determined by function subjRequiresPage()). -** -** If the condition asserted by this function were not true, and the -** dirty page were to be discarded from the cache via the pagerStress() -** routine, pagerStress() would not write the current page content to -** the database file. If a savepoint transaction were rolled back after -** this happened, the correct behavior would be to restore the current -** content of the page. However, since this content is not present in either -** the database file or the portion of the rollback journal and -** sub-journal rolled back the content could not be restored and the -** database image would become corrupt. It is therefore fortunate that -** this circumstance cannot arise. -*/ -#if defined(SQLITE_DEBUG) -static void assertTruncateConstraintCb(PgHdr *pPg){ - assert( pPg->flags&PGHDR_DIRTY ); - assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); -} -static void assertTruncateConstraint(Pager *pPager){ - sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); -} -#else -# define assertTruncateConstraint(pPager) -#endif - -/* -** Truncate the in-memory database file image to nPage pages. This -** function does not actually modify the database file on disk. It -** just sets the internal state of the pager object so that the -** truncation will be done when the current transaction is committed. -** -** This function is only called right before committing a transaction. -** Once this function has been called, the transaction must either be -** rolled back or committed. It is not safe to call this function and -** then continue writing to the database. -*/ -SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ - assert( pPager->dbSize>=nPage ); - assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); - pPager->dbSize = nPage; - - /* At one point the code here called assertTruncateConstraint() to - ** ensure that all pages being truncated away by this operation are, - ** if one or more savepoints are open, present in the savepoint - ** journal so that they can be restored if the savepoint is rolled - ** back. This is no longer necessary as this function is now only - ** called right before committing a transaction. So although the - ** Pager object may still have open savepoints (Pager.nSavepoint!=0), - ** they cannot be rolled back. So the assertTruncateConstraint() call - ** is no longer correct. */ -} - - -/* -** This function is called before attempting a hot-journal rollback. It -** syncs the journal file to disk, then sets pPager->journalHdr to the -** size of the journal file so that the pager_playback() routine knows -** that the entire journal file has been synced. -** -** Syncing a hot-journal to disk before attempting to roll it back ensures -** that if a power-failure occurs during the rollback, the process that -** attempts rollback following system recovery sees the same journal -** content as this process. -** -** If everything goes as planned, SQLITE_OK is returned. Otherwise, -** an SQLite error code. -*/ -static int pagerSyncHotJournal(Pager *pPager){ - int rc = SQLITE_OK; - if( !pPager->noSync ){ - rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); - } - if( rc==SQLITE_OK ){ - rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); - } - return rc; -} - -/* -** Obtain a reference to a memory mapped page object for page number pgno. -** The new object will use the pointer pData, obtained from xFetch(). -** If successful, set *ppPage to point to the new page reference -** and return SQLITE_OK. Otherwise, return an SQLite error code and set -** *ppPage to zero. -** -** Page references obtained by calling this function should be released -** by calling pagerReleaseMapPage(). -*/ -static int pagerAcquireMapPage( - Pager *pPager, /* Pager object */ - Pgno pgno, /* Page number */ - void *pData, /* xFetch()'d data for this page */ - PgHdr **ppPage /* OUT: Acquired page object */ -){ - PgHdr *p; /* Memory mapped page to return */ - - if( pPager->pMmapFreelist ){ - *ppPage = p = pPager->pMmapFreelist; - pPager->pMmapFreelist = p->pDirty; - p->pDirty = 0; - memset(p->pExtra, 0, pPager->nExtra); - }else{ - *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); - if( p==0 ){ - sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); - return SQLITE_NOMEM_BKPT; - } - p->pExtra = (void *)&p[1]; - p->flags = PGHDR_MMAP; - p->nRef = 1; - p->pPager = pPager; - } - - assert( p->pExtra==(void *)&p[1] ); - assert( p->pPage==0 ); - assert( p->flags==PGHDR_MMAP ); - assert( p->pPager==pPager ); - assert( p->nRef==1 ); - - p->pgno = pgno; - p->pData = pData; - pPager->nMmapOut++; - - return SQLITE_OK; -} - -/* -** Release a reference to page pPg. pPg must have been returned by an -** earlier call to pagerAcquireMapPage(). -*/ -static void pagerReleaseMapPage(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - pPager->nMmapOut--; - pPg->pDirty = pPager->pMmapFreelist; - pPager->pMmapFreelist = pPg; - - assert( pPager->fd->pMethods->iVersion>=3 ); - sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); -} - -/* -** Free all PgHdr objects stored in the Pager.pMmapFreelist list. -*/ -static void pagerFreeMapHdrs(Pager *pPager){ - PgHdr *p; - PgHdr *pNext; - for(p=pPager->pMmapFreelist; p; p=pNext){ - pNext = p->pDirty; - sqlite3_free(p); - } -} - - -/* -** Shutdown the page cache. Free all memory and close all files. -** -** If a transaction was in progress when this routine is called, that -** transaction is rolled back. All outstanding pages are invalidated -** and their memory is freed. Any attempt to use a page associated -** with this page cache after this function returns will likely -** result in a coredump. -** -** This function always succeeds. If a transaction is active an attempt -** is made to roll it back. If an error occurs during the rollback -** a hot journal may be left in the filesystem but no error is returned -** to the caller. -*/ -SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){ - u8 *pTmp = (u8 *)pPager->pTmpSpace; - - assert( assert_pager_state(pPager) ); - disable_simulated_io_errors(); - sqlite3BeginBenignMalloc(); - pagerFreeMapHdrs(pPager); - /* pPager->errCode = 0; */ - pPager->exclusiveMode = 0; -#ifndef SQLITE_OMIT_WAL - sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp); - pPager->pWal = 0; -#endif - pager_reset(pPager); - if( MEMDB ){ - pager_unlock(pPager); - }else{ - /* If it is open, sync the journal file before calling UnlockAndRollback. - ** If this is not done, then an unsynced portion of the open journal - ** file may be played back into the database. If a power failure occurs - ** while this is happening, the database could become corrupt. - ** - ** If an error occurs while trying to sync the journal, shift the pager - ** into the ERROR state. This causes UnlockAndRollback to unlock the - ** database and close the journal file without attempting to roll it - ** back or finalize it. The next database user will have to do hot-journal - ** rollback before accessing the database file. - */ - if( isOpen(pPager->jfd) ){ - pager_error(pPager, pagerSyncHotJournal(pPager)); - } - pagerUnlockAndRollback(pPager); - } - sqlite3EndBenignMalloc(); - enable_simulated_io_errors(); - PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); - IOTRACE(("CLOSE %p\n", pPager)) - sqlite3OsClose(pPager->jfd); - sqlite3OsClose(pPager->fd); - sqlite3PageFree(pTmp); - sqlite3PcacheClose(pPager->pPCache); - -#ifdef SQLITE_HAS_CODEC - if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); -#endif - - assert( !pPager->aSavepoint && !pPager->pInJournal ); - assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); - - sqlite3_free(pPager); - return SQLITE_OK; -} - -#if !defined(NDEBUG) || defined(SQLITE_TEST) -/* -** Return the page number for page pPg. -*/ -SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){ - return pPg->pgno; -} -#endif - -/* -** Increment the reference count for page pPg. -*/ -SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ - sqlite3PcacheRef(pPg); -} - -/* -** Sync the journal. In other words, make sure all the pages that have -** been written to the journal have actually reached the surface of the -** disk and can be restored in the event of a hot-journal rollback. -** -** If the Pager.noSync flag is set, then this function is a no-op. -** Otherwise, the actions required depend on the journal-mode and the -** device characteristics of the file-system, as follows: -** -** * If the journal file is an in-memory journal file, no action need -** be taken. -** -** * Otherwise, if the device does not support the SAFE_APPEND property, -** then the nRec field of the most recently written journal header -** is updated to contain the number of journal records that have -** been written following it. If the pager is operating in full-sync -** mode, then the journal file is synced before this field is updated. -** -** * If the device does not support the SEQUENTIAL property, then -** journal file is synced. -** -** Or, in pseudo-code: -** -** if( NOT ){ -** if( NOT SAFE_APPEND ){ -** if( ) xSync(); -** -** } -** if( NOT SEQUENTIAL ) xSync(); -** } -** -** If successful, this routine clears the PGHDR_NEED_SYNC flag of every -** page currently held in memory before returning SQLITE_OK. If an IO -** error is encountered, then the IO error code is returned to the caller. -*/ -static int syncJournal(Pager *pPager, int newHdr){ - int rc; /* Return code */ - - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - ); - assert( assert_pager_state(pPager) ); - assert( !pagerUseWal(pPager) ); - - rc = sqlite3PagerExclusiveLock(pPager); - if( rc!=SQLITE_OK ) return rc; - - if( !pPager->noSync ){ - assert( !pPager->tempFile ); - if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ - const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); - assert( isOpen(pPager->jfd) ); - - if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ - /* This block deals with an obscure problem. If the last connection - ** that wrote to this database was operating in persistent-journal - ** mode, then the journal file may at this point actually be larger - ** than Pager.journalOff bytes. If the next thing in the journal - ** file happens to be a journal-header (written as part of the - ** previous connection's transaction), and a crash or power-failure - ** occurs after nRec is updated but before this connection writes - ** anything else to the journal file (or commits/rolls back its - ** transaction), then SQLite may become confused when doing the - ** hot-journal rollback following recovery. It may roll back all - ** of this connections data, then proceed to rolling back the old, - ** out-of-date data that follows it. Database corruption. - ** - ** To work around this, if the journal file does appear to contain - ** a valid header following Pager.journalOff, then write a 0x00 - ** byte to the start of it to prevent it from being recognized. - ** - ** Variable iNextHdrOffset is set to the offset at which this - ** problematic header will occur, if it exists. aMagic is used - ** as a temporary buffer to inspect the first couple of bytes of - ** the potential journal header. - */ - i64 iNextHdrOffset; - u8 aMagic[8]; - u8 zHeader[sizeof(aJournalMagic)+4]; - - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); - put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); - - iNextHdrOffset = journalHdrOffset(pPager); - rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); - if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ - static const u8 zerobyte = 0; - rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); - } - if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ - return rc; - } - - /* Write the nRec value into the journal file header. If in - ** full-synchronous mode, sync the journal first. This ensures that - ** all data has really hit the disk before nRec is updated to mark - ** it as a candidate for rollback. - ** - ** This is not required if the persistent media supports the - ** SAFE_APPEND property. Because in this case it is not possible - ** for garbage data to be appended to the file, the nRec field - ** is populated with 0xFFFFFFFF when the journal header is written - ** and never needs to be updated. - */ - if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ - PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); - IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); - if( rc!=SQLITE_OK ) return rc; - } - IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); - rc = sqlite3OsWrite( - pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr - ); - if( rc!=SQLITE_OK ) return rc; - } - if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ - PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); - IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| - (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) - ); - if( rc!=SQLITE_OK ) return rc; - } - - pPager->journalHdr = pPager->journalOff; - if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ - pPager->nRec = 0; - rc = writeJournalHdr(pPager); - if( rc!=SQLITE_OK ) return rc; - } - }else{ - pPager->journalHdr = pPager->journalOff; - } - } - - /* Unless the pager is in noSync mode, the journal file was just - ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on - ** all pages. - */ - sqlite3PcacheClearSyncFlags(pPager->pPCache); - pPager->eState = PAGER_WRITER_DBMOD; - assert( assert_pager_state(pPager) ); - return SQLITE_OK; -} - -/* -** The argument is the first in a linked list of dirty pages connected -** by the PgHdr.pDirty pointer. This function writes each one of the -** in-memory pages in the list to the database file. The argument may -** be NULL, representing an empty list. In this case this function is -** a no-op. -** -** The pager must hold at least a RESERVED lock when this function -** is called. Before writing anything to the database file, this lock -** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, -** SQLITE_BUSY is returned and no data is written to the database file. -** -** If the pager is a temp-file pager and the actual file-system file -** is not yet open, it is created and opened before any data is -** written out. -** -** Once the lock has been upgraded and, if necessary, the file opened, -** the pages are written out to the database file in list order. Writing -** a page is skipped if it meets either of the following criteria: -** -** * The page number is greater than Pager.dbSize, or -** * The PGHDR_DONT_WRITE flag is set on the page. -** -** If writing out a page causes the database file to grow, Pager.dbFileSize -** is updated accordingly. If page 1 is written out, then the value cached -** in Pager.dbFileVers[] is updated to match the new value stored in -** the database file. -** -** If everything is successful, SQLITE_OK is returned. If an IO error -** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot -** be obtained, SQLITE_BUSY is returned. -*/ -static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ - int rc = SQLITE_OK; /* Return code */ - - /* This function is only called for rollback pagers in WRITER_DBMOD state. */ - assert( !pagerUseWal(pPager) ); - assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD ); - assert( pPager->eLock==EXCLUSIVE_LOCK ); - assert( isOpen(pPager->fd) || pList->pDirty==0 ); - - /* If the file is a temp-file has not yet been opened, open it now. It - ** is not possible for rc to be other than SQLITE_OK if this branch - ** is taken, as pager_wait_on_lock() is a no-op for temp-files. - */ - if( !isOpen(pPager->fd) ){ - assert( pPager->tempFile && rc==SQLITE_OK ); - rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); - } - - /* Before the first write, give the VFS a hint of what the final - ** file size will be. - */ - assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); - if( rc==SQLITE_OK - && pPager->dbHintSizedbSize - && (pList->pDirty || pList->pgno>pPager->dbHintSize) - ){ - sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); - pPager->dbHintSize = pPager->dbSize; - } - - while( rc==SQLITE_OK && pList ){ - Pgno pgno = pList->pgno; - - /* If there are dirty pages in the page cache with page numbers greater - ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to - ** make the file smaller (presumably by auto-vacuum code). Do not write - ** any such pages to the file. - ** - ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag - ** set (set by sqlite3PagerDontWrite()). - */ - if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ - i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ - char *pData; /* Data to write */ - - assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); - if( pList->pgno==1 ) pager_write_changecounter(pList); - - /* Encode the database */ - CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData); - - /* Write out the page data. */ - rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); - - /* If page 1 was just written, update Pager.dbFileVers to match - ** the value now stored in the database file. If writing this - ** page caused the database file to grow, update dbFileSize. - */ - if( pgno==1 ){ - memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); - } - if( pgno>pPager->dbFileSize ){ - pPager->dbFileSize = pgno; - } - pPager->aStat[PAGER_STAT_WRITE]++; - - /* Update any backup objects copying the contents of this pager. */ - sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); - - PAGERTRACE(("STORE %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_pagehash(pList))); - IOTRACE(("PGOUT %p %d\n", pPager, pgno)); - PAGER_INCR(sqlite3_pager_writedb_count); - }else{ - PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); - } - pager_set_pagehash(pList); - pList = pList->pDirty; - } - - return rc; -} - -/* -** Ensure that the sub-journal file is open. If it is already open, this -** function is a no-op. -** -** SQLITE_OK is returned if everything goes according to plan. An -** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() -** fails. -*/ -static int openSubJournal(Pager *pPager){ - int rc = SQLITE_OK; - if( !isOpen(pPager->sjfd) ){ - const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE - | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE - | SQLITE_OPEN_DELETEONCLOSE; - int nStmtSpill = sqlite3Config.nStmtSpill; - if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ - nStmtSpill = -1; - } - rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill); - } - return rc; -} - -/* -** Append a record of the current state of page pPg to the sub-journal. -** -** If successful, set the bit corresponding to pPg->pgno in the bitvecs -** for all open savepoints before returning. -** -** This function returns SQLITE_OK if everything is successful, an IO -** error code if the attempt to write to the sub-journal fails, or -** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint -** bitvec. -*/ -static int subjournalPage(PgHdr *pPg){ - int rc = SQLITE_OK; - Pager *pPager = pPg->pPager; - if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - - /* Open the sub-journal, if it has not already been opened */ - assert( pPager->useJournal ); - assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); - assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); - assert( pagerUseWal(pPager) - || pageInJournal(pPager, pPg) - || pPg->pgno>pPager->dbOrigSize - ); - rc = openSubJournal(pPager); - - /* If the sub-journal was opened successfully (or was already open), - ** write the journal record into the file. */ - if( rc==SQLITE_OK ){ - void *pData = pPg->pData; - i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); - char *pData2; - - CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); - PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); - rc = write32bits(pPager->sjfd, offset, pPg->pgno); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); - } - } - } - if( rc==SQLITE_OK ){ - pPager->nSubRec++; - assert( pPager->nSavepoint>0 ); - rc = addToSavepointBitvecs(pPager, pPg->pgno); - } - return rc; -} -static int subjournalPageIfRequired(PgHdr *pPg){ - if( subjRequiresPage(pPg) ){ - return subjournalPage(pPg); - }else{ - return SQLITE_OK; - } -} - -/* -** This function is called by the pcache layer when it has reached some -** soft memory limit. The first argument is a pointer to a Pager object -** (cast as a void*). The pager is always 'purgeable' (not an in-memory -** database). The second argument is a reference to a page that is -** currently dirty but has no outstanding references. The page -** is always associated with the Pager object passed as the first -** argument. -** -** The job of this function is to make pPg clean by writing its contents -** out to the database file, if possible. This may involve syncing the -** journal file. -** -** If successful, sqlite3PcacheMakeClean() is called on the page and -** SQLITE_OK returned. If an IO error occurs while trying to make the -** page clean, the IO error code is returned. If the page cannot be -** made clean for some other reason, but no error occurs, then SQLITE_OK -** is returned by sqlite3PcacheMakeClean() is not called. -*/ -static int pagerStress(void *p, PgHdr *pPg){ - Pager *pPager = (Pager *)p; - int rc = SQLITE_OK; - - assert( pPg->pPager==pPager ); - assert( pPg->flags&PGHDR_DIRTY ); - - /* The doNotSpill NOSYNC bit is set during times when doing a sync of - ** journal (and adding a new header) is not allowed. This occurs - ** during calls to sqlite3PagerWrite() while trying to journal multiple - ** pages belonging to the same sector. - ** - ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling - ** regardless of whether or not a sync is required. This is set during - ** a rollback or by user request, respectively. - ** - ** Spilling is also prohibited when in an error state since that could - ** lead to database corruption. In the current implementation it - ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 - ** while in the error state, hence it is impossible for this routine to - ** be called in the error state. Nevertheless, we include a NEVER() - ** test for the error state as a safeguard against future changes. - */ - if( NEVER(pPager->errCode) ) return SQLITE_OK; - testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); - testcase( pPager->doNotSpill & SPILLFLAG_OFF ); - testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); - if( pPager->doNotSpill - && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 - || (pPg->flags & PGHDR_NEED_SYNC)!=0) - ){ - return SQLITE_OK; - } - - pPg->pDirty = 0; - if( pagerUseWal(pPager) ){ - /* Write a single frame for this page to the log. */ - rc = subjournalPageIfRequired(pPg); - if( rc==SQLITE_OK ){ - rc = pagerWalFrames(pPager, pPg, 0, 0); - } - }else{ - - /* Sync the journal file if required. */ - if( pPg->flags&PGHDR_NEED_SYNC - || pPager->eState==PAGER_WRITER_CACHEMOD - ){ - rc = syncJournal(pPager, 1); - } - - /* Write the contents of the page out to the database file. */ - if( rc==SQLITE_OK ){ - assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); - rc = pager_write_pagelist(pPager, pPg); - } - } - - /* Mark the page as clean. */ - if( rc==SQLITE_OK ){ - PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); - sqlite3PcacheMakeClean(pPg); - } - - return pager_error(pPager, rc); -} - -/* -** Flush all unreferenced dirty pages to disk. -*/ -SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){ - int rc = pPager->errCode; - if( !MEMDB ){ - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); - assert( assert_pager_state(pPager) ); - while( rc==SQLITE_OK && pList ){ - PgHdr *pNext = pList->pDirty; - if( pList->nRef==0 ){ - rc = pagerStress((void*)pPager, pList); - } - pList = pNext; - } - } - - return rc; -} - -/* -** Allocate and initialize a new Pager object and put a pointer to it -** in *ppPager. The pager should eventually be freed by passing it -** to sqlite3PagerClose(). -** -** The zFilename argument is the path to the database file to open. -** If zFilename is NULL then a randomly-named temporary file is created -** and used as the file to be cached. Temporary files are be deleted -** automatically when they are closed. If zFilename is ":memory:" then -** all information is held in cache. It is never written to disk. -** This can be used to implement an in-memory database. -** -** The nExtra parameter specifies the number of bytes of space allocated -** along with each page reference. This space is available to the user -** via the sqlite3PagerGetExtra() API. -** -** The flags argument is used to specify properties that affect the -** operation of the pager. It should be passed some bitwise combination -** of the PAGER_* flags. -** -** The vfsFlags parameter is a bitmask to pass to the flags parameter -** of the xOpen() method of the supplied VFS when opening files. -** -** If the pager object is allocated and the specified file opened -** successfully, SQLITE_OK is returned and *ppPager set to point to -** the new pager object. If an error occurs, *ppPager is set to NULL -** and error code returned. This function may return SQLITE_NOMEM -** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or -** various SQLITE_IO_XXX errors. -*/ -SQLITE_PRIVATE int sqlite3PagerOpen( - sqlite3_vfs *pVfs, /* The virtual file system to use */ - Pager **ppPager, /* OUT: Return the Pager structure here */ - const char *zFilename, /* Name of the database file to open */ - int nExtra, /* Extra bytes append to each in-memory page */ - int flags, /* flags controlling this file */ - int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ - void (*xReinit)(DbPage*) /* Function to reinitialize pages */ -){ - u8 *pPtr; - Pager *pPager = 0; /* Pager object to allocate and return */ - int rc = SQLITE_OK; /* Return code */ - int tempFile = 0; /* True for temp files (incl. in-memory files) */ - int memDb = 0; /* True if this is an in-memory file */ - int readOnly = 0; /* True if this is a read-only file */ - int journalFileSize; /* Bytes to allocate for each journal fd */ - char *zPathname = 0; /* Full path to database file */ - int nPathname = 0; /* Number of bytes in zPathname */ - int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ - int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ - u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ - const char *zUri = 0; /* URI args to copy */ - int nUri = 0; /* Number of bytes of URI args at *zUri */ - - /* Figure out how much space is required for each journal file-handle - ** (there are two of them, the main journal and the sub-journal). */ - journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); - - /* Set the output variable to NULL in case an error occurs. */ - *ppPager = 0; - -#ifndef SQLITE_OMIT_MEMORYDB - if( flags & PAGER_MEMORY ){ - memDb = 1; - if( zFilename && zFilename[0] ){ - zPathname = sqlite3DbStrDup(0, zFilename); - if( zPathname==0 ) return SQLITE_NOMEM_BKPT; - nPathname = sqlite3Strlen30(zPathname); - zFilename = 0; - } - } -#endif - - /* Compute and store the full pathname in an allocated buffer pointed - ** to by zPathname, length nPathname. Or, if this is a temporary file, - ** leave both nPathname and zPathname set to 0. - */ - if( zFilename && zFilename[0] ){ - const char *z; - nPathname = pVfs->mxPathname+1; - zPathname = sqlite3DbMallocRaw(0, nPathname*2); - if( zPathname==0 ){ - return SQLITE_NOMEM_BKPT; - } - zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ - rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); - nPathname = sqlite3Strlen30(zPathname); - z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; - while( *z ){ - z += sqlite3Strlen30(z)+1; - z += sqlite3Strlen30(z)+1; - } - nUri = (int)(&z[1] - zUri); - assert( nUri>=0 ); - if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ - /* This branch is taken when the journal path required by - ** the database being opened will be more than pVfs->mxPathname - ** bytes in length. This means the database cannot be opened, - ** as it will not be possible to open the journal file or even - ** check for a hot-journal before reading. - */ - rc = SQLITE_CANTOPEN_BKPT; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(0, zPathname); - return rc; - } - } - - /* Allocate memory for the Pager structure, PCache object, the - ** three file descriptors, the database file name and the journal - ** file name. The layout in memory is as follows: - ** - ** Pager object (sizeof(Pager) bytes) - ** PCache object (sqlite3PcacheSize() bytes) - ** Database file handle (pVfs->szOsFile bytes) - ** Sub-journal file handle (journalFileSize bytes) - ** Main journal file handle (journalFileSize bytes) - ** Database file name (nPathname+1 bytes) - ** Journal file name (nPathname+8+1 bytes) - */ - pPtr = (u8 *)sqlite3MallocZero( - ROUND8(sizeof(*pPager)) + /* Pager structure */ - ROUND8(pcacheSize) + /* PCache object */ - ROUND8(pVfs->szOsFile) + /* The main db file */ - journalFileSize * 2 + /* The two journal files */ - nPathname + 1 + nUri + /* zFilename */ - nPathname + 8 + 2 /* zJournal */ -#ifndef SQLITE_OMIT_WAL - + nPathname + 4 + 2 /* zWal */ -#endif - ); - assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); - if( !pPtr ){ - sqlite3DbFree(0, zPathname); - return SQLITE_NOMEM_BKPT; - } - pPager = (Pager*)(pPtr); - pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager))); - pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize)); - pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile)); - pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize); - pPager->zFilename = (char*)(pPtr += journalFileSize); - assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); - - /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */ - if( zPathname ){ - assert( nPathname>0 ); - pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri); - memcpy(pPager->zFilename, zPathname, nPathname); - if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri); - memcpy(pPager->zJournal, zPathname, nPathname); - memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2); - sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal); -#ifndef SQLITE_OMIT_WAL - pPager->zWal = &pPager->zJournal[nPathname+8+1]; - memcpy(pPager->zWal, zPathname, nPathname); - memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1); - sqlite3FileSuffix3(pPager->zFilename, pPager->zWal); -#endif - sqlite3DbFree(0, zPathname); - } - pPager->pVfs = pVfs; - pPager->vfsFlags = vfsFlags; - - /* Open the pager file. - */ - if( zFilename && zFilename[0] ){ - int fout = 0; /* VFS flags returned by xOpen() */ - rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); - assert( !memDb ); - readOnly = (fout&SQLITE_OPEN_READONLY); - - /* If the file was successfully opened for read/write access, - ** choose a default page size in case we have to create the - ** database file. The default page size is the maximum of: - ** - ** + SQLITE_DEFAULT_PAGE_SIZE, - ** + The value returned by sqlite3OsSectorSize() - ** + The largest page size that can be written atomically. - */ - if( rc==SQLITE_OK ){ - int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); - if( !readOnly ){ - setSectorSize(pPager); - assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); - if( szPageDfltsectorSize ){ - if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ - szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; - }else{ - szPageDflt = (u32)pPager->sectorSize; - } - } -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - { - int ii; - assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); - assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); - for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ - if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ - szPageDflt = ii; - } - } - } -#endif - } - pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0); - if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 - || sqlite3_uri_boolean(zFilename, "immutable", 0) ){ - vfsFlags |= SQLITE_OPEN_READONLY; - goto act_like_temp_file; - } - } - }else{ - /* If a temporary file is requested, it is not opened immediately. - ** In this case we accept the default page size and delay actually - ** opening the file until the first call to OsWrite(). - ** - ** This branch is also run for an in-memory database. An in-memory - ** database is the same as a temp-file that is never written out to - ** disk and uses an in-memory rollback journal. - ** - ** This branch also runs for files marked as immutable. - */ -act_like_temp_file: - tempFile = 1; - pPager->eState = PAGER_READER; /* Pretend we already have a lock */ - pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ - pPager->noLock = 1; /* Do no locking */ - readOnly = (vfsFlags&SQLITE_OPEN_READONLY); - } - - /* The following call to PagerSetPagesize() serves to set the value of - ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. - */ - if( rc==SQLITE_OK ){ - assert( pPager->memDb==0 ); - rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); - testcase( rc!=SQLITE_OK ); - } - - /* Initialize the PCache object. */ - if( rc==SQLITE_OK ){ - assert( nExtra<1000 ); - nExtra = ROUND8(nExtra); - rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, - !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); - } - - /* If an error occurred above, free the Pager structure and close the file. - */ - if( rc!=SQLITE_OK ){ - sqlite3OsClose(pPager->fd); - sqlite3PageFree(pPager->pTmpSpace); - sqlite3_free(pPager); - return rc; - } - - PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); - IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) - - pPager->useJournal = (u8)useJournal; - /* pPager->stmtOpen = 0; */ - /* pPager->stmtInUse = 0; */ - /* pPager->nRef = 0; */ - /* pPager->stmtSize = 0; */ - /* pPager->stmtJSize = 0; */ - /* pPager->nPage = 0; */ - pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; - /* pPager->state = PAGER_UNLOCK; */ - /* pPager->errMask = 0; */ - pPager->tempFile = (u8)tempFile; - assert( tempFile==PAGER_LOCKINGMODE_NORMAL - || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); - assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); - pPager->exclusiveMode = (u8)tempFile; - pPager->changeCountDone = pPager->tempFile; - pPager->memDb = (u8)memDb; - pPager->readOnly = (u8)readOnly; - assert( useJournal || pPager->tempFile ); - pPager->noSync = pPager->tempFile; - if( pPager->noSync ){ - assert( pPager->fullSync==0 ); - assert( pPager->extraSync==0 ); - assert( pPager->syncFlags==0 ); - assert( pPager->walSyncFlags==0 ); - assert( pPager->ckptSyncFlags==0 ); - }else{ - pPager->fullSync = 1; - pPager->extraSync = 0; - pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; - } - /* pPager->pFirst = 0; */ - /* pPager->pFirstSynced = 0; */ - /* pPager->pLast = 0; */ - pPager->nExtra = (u16)nExtra; - pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; - assert( isOpen(pPager->fd) || tempFile ); - setSectorSize(pPager); - if( !useJournal ){ - pPager->journalMode = PAGER_JOURNALMODE_OFF; - }else if( memDb ){ - pPager->journalMode = PAGER_JOURNALMODE_MEMORY; - } - /* pPager->xBusyHandler = 0; */ - /* pPager->pBusyHandlerArg = 0; */ - pPager->xReiniter = xReinit; - /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ - /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ - - *ppPager = pPager; - return SQLITE_OK; -} - - -/* Verify that the database file has not be deleted or renamed out from -** under the pager. Return SQLITE_OK if the database is still were it ought -** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error -** code from sqlite3OsAccess()) if the database has gone missing. -*/ -static int databaseIsUnmoved(Pager *pPager){ - int bHasMoved = 0; - int rc; - - if( pPager->tempFile ) return SQLITE_OK; - if( pPager->dbSize==0 ) return SQLITE_OK; - assert( pPager->zFilename && pPager->zFilename[0] ); - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); - if( rc==SQLITE_NOTFOUND ){ - /* If the HAS_MOVED file-control is unimplemented, assume that the file - ** has not been moved. That is the historical behavior of SQLite: prior to - ** version 3.8.3, it never checked */ - rc = SQLITE_OK; - }else if( rc==SQLITE_OK && bHasMoved ){ - rc = SQLITE_READONLY_DBMOVED; - } - return rc; -} - - -/* -** This function is called after transitioning from PAGER_UNLOCK to -** PAGER_SHARED state. It tests if there is a hot journal present in -** the file-system for the given pager. A hot journal is one that -** needs to be played back. According to this function, a hot-journal -** file exists if the following criteria are met: -** -** * The journal file exists in the file system, and -** * No process holds a RESERVED or greater lock on the database file, and -** * The database file itself is greater than 0 bytes in size, and -** * The first byte of the journal file exists and is not 0x00. -** -** If the current size of the database file is 0 but a journal file -** exists, that is probably an old journal left over from a prior -** database with the same name. In this case the journal file is -** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK -** is returned. -** -** This routine does not check if there is a master journal filename -** at the end of the file. If there is, and that master journal file -** does not exist, then the journal file is not really hot. In this -** case this routine will return a false-positive. The pager_playback() -** routine will discover that the journal file is not really hot and -** will not roll it back. -** -** If a hot-journal file is found to exist, *pExists is set to 1 and -** SQLITE_OK returned. If no hot-journal file is present, *pExists is -** set to 0 and SQLITE_OK returned. If an IO error occurs while trying -** to determine whether or not a hot-journal file exists, the IO error -** code is returned and the value of *pExists is undefined. -*/ -static int hasHotJournal(Pager *pPager, int *pExists){ - sqlite3_vfs * const pVfs = pPager->pVfs; - int rc = SQLITE_OK; /* Return code */ - int exists = 1; /* True if a journal file is present */ - int jrnlOpen = !!isOpen(pPager->jfd); - - assert( pPager->useJournal ); - assert( isOpen(pPager->fd) ); - assert( pPager->eState==PAGER_OPEN ); - - assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & - SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN - )); - - *pExists = 0; - if( !jrnlOpen ){ - rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); - } - if( rc==SQLITE_OK && exists ){ - int locked = 0; /* True if some process holds a RESERVED lock */ - - /* Race condition here: Another process might have been holding the - ** the RESERVED lock and have a journal open at the sqlite3OsAccess() - ** call above, but then delete the journal and drop the lock before - ** we get to the following sqlite3OsCheckReservedLock() call. If that - ** is the case, this routine might think there is a hot journal when - ** in fact there is none. This results in a false-positive which will - ** be dealt with by the playback routine. Ticket #3883. - */ - rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); - if( rc==SQLITE_OK && !locked ){ - Pgno nPage; /* Number of pages in database file */ - - assert( pPager->tempFile==0 ); - rc = pagerPagecount(pPager, &nPage); - if( rc==SQLITE_OK ){ - /* If the database is zero pages in size, that means that either (1) the - ** journal is a remnant from a prior database with the same name where - ** the database file but not the journal was deleted, or (2) the initial - ** transaction that populates a new database is being rolled back. - ** In either case, the journal file can be deleted. However, take care - ** not to delete the journal file if it is already open due to - ** journal_mode=PERSIST. - */ - if( nPage==0 && !jrnlOpen ){ - sqlite3BeginBenignMalloc(); - if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ - sqlite3OsDelete(pVfs, pPager->zJournal, 0); - if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); - } - sqlite3EndBenignMalloc(); - }else{ - /* The journal file exists and no other connection has a reserved - ** or greater lock on the database file. Now check that there is - ** at least one non-zero bytes at the start of the journal file. - ** If there is, then we consider this journal to be hot. If not, - ** it can be ignored. - */ - if( !jrnlOpen ){ - int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); - } - if( rc==SQLITE_OK ){ - u8 first = 0; - rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); - if( rc==SQLITE_IOERR_SHORT_READ ){ - rc = SQLITE_OK; - } - if( !jrnlOpen ){ - sqlite3OsClose(pPager->jfd); - } - *pExists = (first!=0); - }else if( rc==SQLITE_CANTOPEN ){ - /* If we cannot open the rollback journal file in order to see if - ** it has a zero header, that might be due to an I/O error, or - ** it might be due to the race condition described above and in - ** ticket #3883. Either way, assume that the journal is hot. - ** This might be a false positive. But if it is, then the - ** automatic journal playback and recovery mechanism will deal - ** with it under an EXCLUSIVE lock where we do not need to - ** worry so much with race conditions. - */ - *pExists = 1; - rc = SQLITE_OK; - } - } - } - } - } - - return rc; -} - -/* -** This function is called to obtain a shared lock on the database file. -** It is illegal to call sqlite3PagerGet() until after this function -** has been successfully called. If a shared-lock is already held when -** this function is called, it is a no-op. -** -** The following operations are also performed by this function. -** -** 1) If the pager is currently in PAGER_OPEN state (no lock held -** on the database file), then an attempt is made to obtain a -** SHARED lock on the database file. Immediately after obtaining -** the SHARED lock, the file-system is checked for a hot-journal, -** which is played back if present. Following any hot-journal -** rollback, the contents of the cache are validated by checking -** the 'change-counter' field of the database file header and -** discarded if they are found to be invalid. -** -** 2) If the pager is running in exclusive-mode, and there are currently -** no outstanding references to any pages, and is in the error state, -** then an attempt is made to clear the error state by discarding -** the contents of the page cache and rolling back any open journal -** file. -** -** If everything is successful, SQLITE_OK is returned. If an IO error -** occurs while locking the database, checking for a hot-journal file or -** rolling back a journal file, the IO error code is returned. -*/ -SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ - int rc = SQLITE_OK; /* Return code */ - - /* This routine is only called from b-tree and only when there are no - ** outstanding pages. This implies that the pager state should either - ** be OPEN or READER. READER is only possible if the pager is or was in - ** exclusive access mode. */ - assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); - assert( assert_pager_state(pPager) ); - assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); - assert( pPager->errCode==SQLITE_OK ); - - if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ - int bHotJournal = 1; /* True if there exists a hot journal-file */ - - assert( !MEMDB ); - assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK ); - - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); - goto failed; - } - - /* If a journal file exists, and there is no RESERVED lock on the - ** database file, then it either needs to be played back or deleted. - */ - if( pPager->eLock<=SHARED_LOCK ){ - rc = hasHotJournal(pPager, &bHotJournal); - } - if( rc!=SQLITE_OK ){ - goto failed; - } - if( bHotJournal ){ - if( pPager->readOnly ){ - rc = SQLITE_READONLY_ROLLBACK; - goto failed; - } - - /* Get an EXCLUSIVE lock on the database file. At this point it is - ** important that a RESERVED lock is not obtained on the way to the - ** EXCLUSIVE lock. If it were, another process might open the - ** database file, detect the RESERVED lock, and conclude that the - ** database is safe to read while this process is still rolling the - ** hot-journal back. - ** - ** Because the intermediate RESERVED lock is not requested, any - ** other process attempting to access the database file will get to - ** this point in the code and fail to obtain its own EXCLUSIVE lock - ** on the database file. - ** - ** Unless the pager is in locking_mode=exclusive mode, the lock is - ** downgraded to SHARED_LOCK before this function returns. - */ - rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - goto failed; - } - - /* If it is not already open and the file exists on disk, open the - ** journal for read/write access. Write access is required because - ** in exclusive-access mode the file descriptor will be kept open - ** and possibly used for a transaction later on. Also, write-access - ** is usually required to finalize the journal in journal_mode=persist - ** mode (and also for journal_mode=truncate on some systems). - ** - ** If the journal does not exist, it usually means that some - ** other connection managed to get in and roll it back before - ** this connection obtained the exclusive lock above. Or, it - ** may mean that the pager was in the error-state when this - ** function was called and the journal file does not exist. - */ - if( !isOpen(pPager->jfd) ){ - sqlite3_vfs * const pVfs = pPager->pVfs; - int bExists; /* True if journal file exists */ - rc = sqlite3OsAccess( - pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); - if( rc==SQLITE_OK && bExists ){ - int fout = 0; - int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; - assert( !pPager->tempFile ); - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); - assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); - if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ - rc = SQLITE_CANTOPEN_BKPT; - sqlite3OsClose(pPager->jfd); - } - } - } - - /* Playback and delete the journal. Drop the database write - ** lock and reacquire the read lock. Purge the cache before - ** playing back the hot-journal so that we don't end up with - ** an inconsistent cache. Sync the hot journal before playing - ** it back since the process that crashed and left the hot journal - ** probably did not sync it and we are required to always sync - ** the journal before playing it back. - */ - if( isOpen(pPager->jfd) ){ - assert( rc==SQLITE_OK ); - rc = pagerSyncHotJournal(pPager); - if( rc==SQLITE_OK ){ - rc = pager_playback(pPager, !pPager->tempFile); - pPager->eState = PAGER_OPEN; - } - }else if( !pPager->exclusiveMode ){ - pagerUnlockDb(pPager, SHARED_LOCK); - } - - if( rc!=SQLITE_OK ){ - /* This branch is taken if an error occurs while trying to open - ** or roll back a hot-journal while holding an EXCLUSIVE lock. The - ** pager_unlock() routine will be called before returning to unlock - ** the file. If the unlock attempt fails, then Pager.eLock must be - ** set to UNKNOWN_LOCK (see the comment above the #define for - ** UNKNOWN_LOCK above for an explanation). - ** - ** In order to get pager_unlock() to do this, set Pager.eState to - ** PAGER_ERROR now. This is not actually counted as a transition - ** to ERROR state in the state diagram at the top of this file, - ** since we know that the same call to pager_unlock() will very - ** shortly transition the pager object to the OPEN state. Calling - ** assert_pager_state() would fail now, as it should not be possible - ** to be in ERROR state when there are zero outstanding page - ** references. - */ - pager_error(pPager, rc); - goto failed; - } - - assert( pPager->eState==PAGER_OPEN ); - assert( (pPager->eLock==SHARED_LOCK) - || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) - ); - } - - if( !pPager->tempFile && pPager->hasHeldSharedLock ){ - /* The shared-lock has just been acquired then check to - ** see if the database has been modified. If the database has changed, - ** flush the cache. The hasHeldSharedLock flag prevents this from - ** occurring on the very first access to a file, in order to save a - ** single unnecessary sqlite3OsRead() call at the start-up. - ** - ** Database changes are detected by looking at 15 bytes beginning - ** at offset 24 into the file. The first 4 of these 16 bytes are - ** a 32-bit counter that is incremented with each change. The - ** other bytes change randomly with each file change when - ** a codec is in use. - ** - ** There is a vanishingly small chance that a change will not be - ** detected. The chance of an undetected change is so small that - ** it can be neglected. - */ - Pgno nPage = 0; - char dbFileVers[sizeof(pPager->dbFileVers)]; - - rc = pagerPagecount(pPager, &nPage); - if( rc ) goto failed; - - if( nPage>0 ){ - IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); - rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); - if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ - goto failed; - } - }else{ - memset(dbFileVers, 0, sizeof(dbFileVers)); - } - - if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ - pager_reset(pPager); - - /* Unmap the database file. It is possible that external processes - ** may have truncated the database file and then extended it back - ** to its original size while this process was not holding a lock. - ** In this case there may exist a Pager.pMap mapping that appears - ** to be the right size but is not actually valid. Avoid this - ** possibility by unmapping the db here. */ - if( USEFETCH(pPager) ){ - sqlite3OsUnfetch(pPager->fd, 0, 0); - } - } - } - - /* If there is a WAL file in the file-system, open this database in WAL - ** mode. Otherwise, the following function call is a no-op. - */ - rc = pagerOpenWalIfPresent(pPager); -#ifndef SQLITE_OMIT_WAL - assert( pPager->pWal==0 || rc==SQLITE_OK ); -#endif - } - - if( pagerUseWal(pPager) ){ - assert( rc==SQLITE_OK ); - rc = pagerBeginReadTransaction(pPager); - } - - if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ - rc = pagerPagecount(pPager, &pPager->dbSize); - } - - failed: - if( rc!=SQLITE_OK ){ - assert( !MEMDB ); - pager_unlock(pPager); - assert( pPager->eState==PAGER_OPEN ); - }else{ - pPager->eState = PAGER_READER; - pPager->hasHeldSharedLock = 1; - } - return rc; -} - -/* -** If the reference count has reached zero, rollback any active -** transaction and unlock the pager. -** -** Except, in locking_mode=EXCLUSIVE when there is nothing to in -** the rollback journal, the unlock is not performed and there is -** nothing to rollback, so this routine is a no-op. -*/ -static void pagerUnlockIfUnused(Pager *pPager){ - if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){ - pagerUnlockAndRollback(pPager); - } -} - -/* -** Acquire a reference to page number pgno in pager pPager (a page -** reference has type DbPage*). If the requested reference is -** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. -** -** If the requested page is already in the cache, it is returned. -** Otherwise, a new page object is allocated and populated with data -** read from the database file. In some cases, the pcache module may -** choose not to allocate a new page object and may reuse an existing -** object with no outstanding references. -** -** The extra data appended to a page is always initialized to zeros the -** first time a page is loaded into memory. If the page requested is -** already in the cache when this function is called, then the extra -** data is left as it was when the page object was last used. -** -** If the database image is smaller than the requested page or if a -** non-zero value is passed as the noContent parameter and the -** requested page is not already stored in the cache, then no -** actual disk read occurs. In this case the memory image of the -** page is initialized to all zeros. -** -** If noContent is true, it means that we do not care about the contents -** of the page. This occurs in two scenarios: -** -** a) When reading a free-list leaf page from the database, and -** -** b) When a savepoint is being rolled back and we need to load -** a new page into the cache to be filled with the data read -** from the savepoint journal. -** -** If noContent is true, then the data returned is zeroed instead of -** being read from the database. Additionally, the bits corresponding -** to pgno in Pager.pInJournal (bitvec of pages already written to the -** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open -** savepoints are set. This means if the page is made writable at any -** point in the future, using a call to sqlite3PagerWrite(), its contents -** will not be journaled. This saves IO. -** -** The acquisition might fail for several reasons. In all cases, -** an appropriate error code is returned and *ppPage is set to NULL. -** -** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt -** to find a page in the in-memory cache first. If the page is not already -** in memory, this routine goes to disk to read it in whereas Lookup() -** just returns 0. This routine acquires a read-lock the first time it -** has to go to disk, and could also playback an old journal if necessary. -** Since Lookup() never goes to disk, it never has to deal with locks -** or journal files. -*/ -SQLITE_PRIVATE int sqlite3PagerGet( - Pager *pPager, /* The pager open on the database file */ - Pgno pgno, /* Page number to fetch */ - DbPage **ppPage, /* Write a pointer to the page here */ - int flags /* PAGER_GET_XXX flags */ -){ - int rc = SQLITE_OK; - PgHdr *pPg = 0; - u32 iFrame = 0; /* Frame to read from WAL file */ - const int noContent = (flags & PAGER_GET_NOCONTENT); - - /* It is acceptable to use a read-only (mmap) page for any page except - ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY - ** flag was specified by the caller. And so long as the db is not a - ** temporary or in-memory database. */ - const int bMmapOk = (pgno>1 && USEFETCH(pPager) - && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) -#ifdef SQLITE_HAS_CODEC - && pPager->xCodec==0 -#endif - ); - - /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here - ** allows the compiler optimizer to reuse the results of the "pgno>1" - ** test in the previous statement, and avoid testing pgno==0 in the - ** common case where pgno is large. */ - if( pgno<=1 && pgno==0 ){ - return SQLITE_CORRUPT_BKPT; - } - assert( pPager->eState>=PAGER_READER ); - assert( assert_pager_state(pPager) ); - assert( noContent==0 || bMmapOk==0 ); - - assert( pPager->hasHeldSharedLock==1 ); - - /* If the pager is in the error state, return an error immediately. - ** Otherwise, request the page from the PCache layer. */ - if( pPager->errCode!=SQLITE_OK ){ - rc = pPager->errCode; - }else{ - if( bMmapOk && pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - } - - if( bMmapOk && iFrame==0 ){ - void *pData = 0; - - rc = sqlite3OsFetch(pPager->fd, - (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData - ); - - if( rc==SQLITE_OK && pData ){ - if( pPager->eState>PAGER_READER || pPager->tempFile ){ - pPg = sqlite3PagerLookup(pPager, pgno); - } - if( pPg==0 ){ - rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); - }else{ - sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); - } - if( pPg ){ - assert( rc==SQLITE_OK ); - *ppPage = pPg; - return SQLITE_OK; - } - } - if( rc!=SQLITE_OK ){ - goto pager_acquire_err; - } - } - - { - sqlite3_pcache_page *pBase; - pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); - if( pBase==0 ){ - rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - if( pBase==0 ){ - pPg = *ppPage = 0; - rc = SQLITE_NOMEM_BKPT; - goto pager_acquire_err; - } - } - pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); - assert( pPg!=0 ); - } - } - - if( rc!=SQLITE_OK ){ - /* Either the call to sqlite3PcacheFetch() returned an error or the - ** pager was already in the error-state when this function was called. - ** Set pPg to 0 and jump to the exception handler. */ - pPg = 0; - goto pager_acquire_err; - } - assert( pPg==(*ppPage) ); - assert( pPg->pgno==pgno ); - assert( pPg->pPager==pPager || pPg->pPager==0 ); - - if( pPg->pPager && !noContent ){ - /* In this case the pcache already contains an initialized copy of - ** the page. Return without further ado. */ - assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); - pPager->aStat[PAGER_STAT_HIT]++; - return SQLITE_OK; - - }else{ - /* The pager cache has created a new page. Its content needs to - ** be initialized. */ - - pPg->pPager = pPager; - - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page - ** number greater than this, or the unused locking-page, is requested. */ - if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ - rc = SQLITE_CORRUPT_BKPT; - goto pager_acquire_err; - } - - assert( !isOpen(pPager->fd) || !MEMDB ); - if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ - rc = SQLITE_FULL; - goto pager_acquire_err; - } - if( noContent ){ - /* Failure to set the bits in the InJournal bit-vectors is benign. - ** It merely means that we might do some extra work to journal a - ** page that does not need to be journaled. Nevertheless, be sure - ** to test the case where a malloc error occurs while trying to set - ** a bit in a bit vector. - */ - sqlite3BeginBenignMalloc(); - if( pgno<=pPager->dbOrigSize ){ - TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); - testcase( rc==SQLITE_NOMEM ); - } - TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); - testcase( rc==SQLITE_NOMEM ); - sqlite3EndBenignMalloc(); - } - memset(pPg->pData, 0, pPager->pageSize); - IOTRACE(("ZERO %p %d\n", pPager, pgno)); - }else{ - if( pagerUseWal(pPager) && bMmapOk==0 ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - } - assert( pPg->pPager==pPager ); - pPager->aStat[PAGER_STAT_MISS]++; - rc = readDbPage(pPg, iFrame); - if( rc!=SQLITE_OK ){ - goto pager_acquire_err; - } - } - pager_set_pagehash(pPg); - } - - return SQLITE_OK; - -pager_acquire_err: - assert( rc!=SQLITE_OK ); - if( pPg ){ - sqlite3PcacheDrop(pPg); - } - pagerUnlockIfUnused(pPager); - - *ppPage = 0; - return rc; -} - -/* -** Acquire a page if it is already in the in-memory cache. Do -** not read the page from disk. Return a pointer to the page, -** or 0 if the page is not in cache. -** -** See also sqlite3PagerGet(). The difference between this routine -** and sqlite3PagerGet() is that _get() will go to the disk and read -** in the page if the page is not already in cache. This routine -** returns NULL if the page is not in cache or if a disk I/O error -** has ever happened. -*/ -SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ - sqlite3_pcache_page *pPage; - assert( pPager!=0 ); - assert( pgno!=0 ); - assert( pPager->pPCache!=0 ); - pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); - assert( pPage==0 || pPager->hasHeldSharedLock ); - if( pPage==0 ) return 0; - return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); -} - -/* -** Release a page reference. -** -** If the number of references to the page drop to zero, then the -** page is added to the LRU list. When all references to all pages -** are released, a rollback occurs and the lock on the database is -** removed. -*/ -SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ - Pager *pPager; - assert( pPg!=0 ); - pPager = pPg->pPager; - if( pPg->flags & PGHDR_MMAP ){ - pagerReleaseMapPage(pPg); - }else{ - sqlite3PcacheRelease(pPg); - } - pagerUnlockIfUnused(pPager); -} -SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ - if( pPg ) sqlite3PagerUnrefNotNull(pPg); -} - -/* -** This function is called at the start of every write transaction. -** There must already be a RESERVED or EXCLUSIVE lock on the database -** file when this routine is called. -** -** Open the journal file for pager pPager and write a journal header -** to the start of it. If there are active savepoints, open the sub-journal -** as well. This function is only used when the journal file is being -** opened to write a rollback log for a transaction. It is not used -** when opening a hot journal file to roll it back. -** -** If the journal file is already open (as it may be in exclusive mode), -** then this function just writes a journal header to the start of the -** already open file. -** -** Whether or not the journal file is opened by this function, the -** Pager.pInJournal bitvec structure is allocated. -** -** Return SQLITE_OK if everything is successful. Otherwise, return -** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or -** an IO error code if opening or writing the journal file fails. -*/ -static int pager_open_journal(Pager *pPager){ - int rc = SQLITE_OK; /* Return code */ - sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ - - assert( pPager->eState==PAGER_WRITER_LOCKED ); - assert( assert_pager_state(pPager) ); - assert( pPager->pInJournal==0 ); - - /* If already in the error state, this function is a no-op. But on - ** the other hand, this routine is never called if we are already in - ** an error state. */ - if( NEVER(pPager->errCode) ) return pPager->errCode; - - if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); - if( pPager->pInJournal==0 ){ - return SQLITE_NOMEM_BKPT; - } - - /* Open the journal file if it is not already open. */ - if( !isOpen(pPager->jfd) ){ - if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ - sqlite3MemJournalOpen(pPager->jfd); - }else{ - int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; - int nSpill; - - if( pPager->tempFile ){ - flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); - nSpill = sqlite3Config.nStmtSpill; - }else{ - flags |= SQLITE_OPEN_MAIN_JOURNAL; - nSpill = jrnlBufferSize(pPager); - } - - /* Verify that the database still has the same name as it did when - ** it was originally opened. */ - rc = databaseIsUnmoved(pPager); - if( rc==SQLITE_OK ){ - rc = sqlite3JournalOpen ( - pVfs, pPager->zJournal, pPager->jfd, flags, nSpill - ); - } - } - assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); - } - - - /* Write the first journal header to the journal file and open - ** the sub-journal if necessary. - */ - if( rc==SQLITE_OK ){ - /* TODO: Check if all of these are really required. */ - pPager->nRec = 0; - pPager->journalOff = 0; - pPager->setMaster = 0; - pPager->journalHdr = 0; - rc = writeJournalHdr(pPager); - } - } - - if( rc!=SQLITE_OK ){ - sqlite3BitvecDestroy(pPager->pInJournal); - pPager->pInJournal = 0; - }else{ - assert( pPager->eState==PAGER_WRITER_LOCKED ); - pPager->eState = PAGER_WRITER_CACHEMOD; - } - - return rc; -} - -/* -** Begin a write-transaction on the specified pager object. If a -** write-transaction has already been opened, this function is a no-op. -** -** If the exFlag argument is false, then acquire at least a RESERVED -** lock on the database file. If exFlag is true, then acquire at least -** an EXCLUSIVE lock. If such a lock is already held, no locking -** functions need be called. -** -** If the subjInMemory argument is non-zero, then any sub-journal opened -** within this transaction will be opened as an in-memory file. This -** has no effect if the sub-journal is already opened (as it may be when -** running in exclusive mode) or if the transaction does not require a -** sub-journal. If the subjInMemory argument is zero, then any required -** sub-journal is implemented in-memory if pPager is an in-memory database, -** or using a temporary file otherwise. -*/ -SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ - int rc = SQLITE_OK; - - if( pPager->errCode ) return pPager->errCode; - assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; - - if( ALWAYS(pPager->eState==PAGER_READER) ){ - assert( pPager->pInJournal==0 ); - - if( pagerUseWal(pPager) ){ - /* If the pager is configured to use locking_mode=exclusive, and an - ** exclusive lock on the database is not already held, obtain it now. - */ - if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ - rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - return rc; - } - (void)sqlite3WalExclusiveMode(pPager->pWal, 1); - } - - /* Grab the write lock on the log file. If successful, upgrade to - ** PAGER_RESERVED state. Otherwise, return an error code to the caller. - ** The busy-handler is not invoked if another connection already - ** holds the write-lock. If possible, the upper layer will call it. - */ - rc = sqlite3WalBeginWriteTransaction(pPager->pWal); - }else{ - /* Obtain a RESERVED lock on the database file. If the exFlag parameter - ** is true, then immediately upgrade this to an EXCLUSIVE lock. The - ** busy-handler callback can be used when upgrading to the EXCLUSIVE - ** lock, but not when obtaining the RESERVED lock. - */ - rc = pagerLockDb(pPager, RESERVED_LOCK); - if( rc==SQLITE_OK && exFlag ){ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - } - } - - if( rc==SQLITE_OK ){ - /* Change to WRITER_LOCKED state. - ** - ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD - ** when it has an open transaction, but never to DBMOD or FINISHED. - ** This is because in those states the code to roll back savepoint - ** transactions may copy data from the sub-journal into the database - ** file as well as into the page cache. Which would be incorrect in - ** WAL mode. - */ - pPager->eState = PAGER_WRITER_LOCKED; - pPager->dbHintSize = pPager->dbSize; - pPager->dbFileSize = pPager->dbSize; - pPager->dbOrigSize = pPager->dbSize; - pPager->journalOff = 0; - } - - assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); - assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); - assert( assert_pager_state(pPager) ); - } - - PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); - return rc; -} - -/* -** Write page pPg onto the end of the rollback journal. -*/ -static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - int rc; - u32 cksum; - char *pData2; - i64 iOff = pPager->journalOff; - - /* We should never write to the journal file the page that - ** contains the database locks. The following assert verifies - ** that we do not. */ - assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); - - assert( pPager->journalHdr<=pPager->journalOff ); - CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); - cksum = pager_cksum(pPager, (u8*)pData2); - - /* Even if an IO or diskfull error occurs while journalling the - ** page in the block above, set the need-sync flag for the page. - ** Otherwise, when the transaction is rolled back, the logic in - ** playback_one_page() will think that the page needs to be restored - ** in the database file. And if an IO error occurs while doing so, - ** then corruption may follow. - */ - pPg->flags |= PGHDR_NEED_SYNC; - - rc = write32bits(pPager->jfd, iOff, pPg->pgno); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); - if( rc!=SQLITE_OK ) return rc; - rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); - if( rc!=SQLITE_OK ) return rc; - - IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, - pPager->journalOff, pPager->pageSize)); - PAGER_INCR(sqlite3_pager_writej_count); - PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", - PAGERID(pPager), pPg->pgno, - ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); - - pPager->journalOff += 8 + pPager->pageSize; - pPager->nRec++; - assert( pPager->pInJournal!=0 ); - rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); - testcase( rc==SQLITE_NOMEM ); - assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); - rc |= addToSavepointBitvecs(pPager, pPg->pgno); - assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); - return rc; -} - -/* -** Mark a single data page as writeable. The page is written into the -** main journal or sub-journal as required. If the page is written into -** one of the journals, the corresponding bit is set in the -** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs -** of any open savepoints as appropriate. -*/ -static int pager_write(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - int rc = SQLITE_OK; - - /* This routine is not called unless a write-transaction has already - ** been started. The journal file may or may not be open at this point. - ** It is never called in the ERROR state. - */ - assert( pPager->eState==PAGER_WRITER_LOCKED - || pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - ); - assert( assert_pager_state(pPager) ); - assert( pPager->errCode==0 ); - assert( pPager->readOnly==0 ); - CHECK_PAGE(pPg); - - /* The journal file needs to be opened. Higher level routines have already - ** obtained the necessary locks to begin the write-transaction, but the - ** rollback journal might not yet be open. Open it now if this is the case. - ** - ** This is done before calling sqlite3PcacheMakeDirty() on the page. - ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then - ** an error might occur and the pager would end up in WRITER_LOCKED state - ** with pages marked as dirty in the cache. - */ - if( pPager->eState==PAGER_WRITER_LOCKED ){ - rc = pager_open_journal(pPager); - if( rc!=SQLITE_OK ) return rc; - } - assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); - assert( assert_pager_state(pPager) ); - - /* Mark the page that is about to be modified as dirty. */ - sqlite3PcacheMakeDirty(pPg); - - /* If a rollback journal is in use, them make sure the page that is about - ** to change is in the rollback journal, or if the page is a new page off - ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC. - */ - assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) ); - if( pPager->pInJournal!=0 - && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 - ){ - assert( pagerUseWal(pPager)==0 ); - if( pPg->pgno<=pPager->dbOrigSize ){ - rc = pagerAddPageToRollbackJournal(pPg); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - if( pPager->eState!=PAGER_WRITER_DBMOD ){ - pPg->flags |= PGHDR_NEED_SYNC; - } - PAGERTRACE(("APPEND %d page %d needSync=%d\n", - PAGERID(pPager), pPg->pgno, - ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); - } - } - - /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list - ** and before writing the page into the rollback journal. Wait until now, - ** after the page has been successfully journalled, before setting the - ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. - */ - pPg->flags |= PGHDR_WRITEABLE; - - /* If the statement journal is open and the page is not in it, - ** then write the page into the statement journal. - */ - if( pPager->nSavepoint>0 ){ - rc = subjournalPageIfRequired(pPg); - } - - /* Update the database size and return. */ - if( pPager->dbSizepgno ){ - pPager->dbSize = pPg->pgno; - } - return rc; -} - -/* -** This is a variant of sqlite3PagerWrite() that runs when the sector size -** is larger than the page size. SQLite makes the (reasonable) assumption that -** all bytes of a sector are written together by hardware. Hence, all bytes of -** a sector need to be journalled in case of a power loss in the middle of -** a write. -** -** Usually, the sector size is less than or equal to the page size, in which -** case pages can be individually written. This routine only runs in the -** exceptional case where the page size is smaller than the sector size. -*/ -static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ - int rc = SQLITE_OK; /* Return code */ - Pgno nPageCount; /* Total number of pages in database file */ - Pgno pg1; /* First page of the sector pPg is located on. */ - int nPage = 0; /* Number of pages starting at pg1 to journal */ - int ii; /* Loop counter */ - int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ - Pager *pPager = pPg->pPager; /* The pager that owns pPg */ - Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); - - /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow - ** a journal header to be written between the pages journaled by - ** this function. - */ - assert( !MEMDB ); - assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); - pPager->doNotSpill |= SPILLFLAG_NOSYNC; - - /* This trick assumes that both the page-size and sector-size are - ** an integer power of 2. It sets variable pg1 to the identifier - ** of the first page of the sector pPg is located on. - */ - pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; - - nPageCount = pPager->dbSize; - if( pPg->pgno>nPageCount ){ - nPage = (pPg->pgno - pg1)+1; - }else if( (pg1+nPagePerSector-1)>nPageCount ){ - nPage = nPageCount+1-pg1; - }else{ - nPage = nPagePerSector; - } - assert(nPage>0); - assert(pg1<=pPg->pgno); - assert((pg1+nPage)>pPg->pgno); - - for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ - if( pg!=PAGER_MJ_PGNO(pPager) ){ - rc = sqlite3PagerGet(pPager, pg, &pPage, 0); - if( rc==SQLITE_OK ){ - rc = pager_write(pPage); - if( pPage->flags&PGHDR_NEED_SYNC ){ - needSync = 1; - } - sqlite3PagerUnrefNotNull(pPage); - } - } - }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ - if( pPage->flags&PGHDR_NEED_SYNC ){ - needSync = 1; - } - sqlite3PagerUnrefNotNull(pPage); - } - } - - /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages - ** starting at pg1, then it needs to be set for all of them. Because - ** writing to any of these nPage pages may damage the others, the - ** journal file must contain sync()ed copies of all of them - ** before any of them can be written out to the database file. - */ - if( rc==SQLITE_OK && needSync ){ - assert( !MEMDB ); - for(ii=0; iiflags |= PGHDR_NEED_SYNC; - sqlite3PagerUnrefNotNull(pPage); - } - } - } - - assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); - pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; - return rc; -} - -/* -** Mark a data page as writeable. This routine must be called before -** making changes to a page. The caller must check the return value -** of this function and be careful not to change any page data unless -** this routine returns SQLITE_OK. -** -** The difference between this function and pager_write() is that this -** function also deals with the special case where 2 or more pages -** fit on a single disk sector. In this case all co-resident pages -** must have been written to the journal file before returning. -** -** If an error occurs, SQLITE_NOMEM or an IO error code is returned -** as appropriate. Otherwise, SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - assert( (pPg->flags & PGHDR_MMAP)==0 ); - assert( pPager->eState>=PAGER_WRITER_LOCKED ); - assert( assert_pager_state(pPager) ); - if( pPager->errCode ){ - return pPager->errCode; - }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ - if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); - return SQLITE_OK; - }else if( pPager->sectorSize > (u32)pPager->pageSize ){ - assert( pPager->tempFile==0 ); - return pagerWriteLargeSector(pPg); - }else{ - return pager_write(pPg); - } -} - -/* -** Return TRUE if the page given in the argument was previously passed -** to sqlite3PagerWrite(). In other words, return TRUE if it is ok -** to change the content of the page. -*/ -#ifndef NDEBUG -SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ - return pPg->flags & PGHDR_WRITEABLE; -} -#endif - -/* -** A call to this routine tells the pager that it is not necessary to -** write the information on page pPg back to the disk, even though -** that page might be marked as dirty. This happens, for example, when -** the page has been added as a leaf of the freelist and so its -** content no longer matters. -** -** The overlying software layer calls this routine when all of the data -** on the given page is unused. The pager marks the page as clean so -** that it does not get written to disk. -** -** Tests show that this optimization can quadruple the speed of large -** DELETE operations. -** -** This optimization cannot be used with a temp-file, as the page may -** have been dirty at the start of the transaction. In that case, if -** memory pressure forces page pPg out of the cache, the data does need -** to be written out to disk so that it may be read back in if the -** current transaction is rolled back. -*/ -SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ - Pager *pPager = pPg->pPager; - if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ - PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); - IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) - pPg->flags |= PGHDR_DONT_WRITE; - pPg->flags &= ~PGHDR_WRITEABLE; - testcase( pPg->flags & PGHDR_NEED_SYNC ); - pager_set_pagehash(pPg); - } -} - -/* -** This routine is called to increment the value of the database file -** change-counter, stored as a 4-byte big-endian integer starting at -** byte offset 24 of the pager file. The secondary change counter at -** 92 is also updated, as is the SQLite version number at offset 96. -** -** But this only happens if the pPager->changeCountDone flag is false. -** To avoid excess churning of page 1, the update only happens once. -** See also the pager_write_changecounter() routine that does an -** unconditional update of the change counters. -** -** If the isDirectMode flag is zero, then this is done by calling -** sqlite3PagerWrite() on page 1, then modifying the contents of the -** page data. In this case the file will be updated when the current -** transaction is committed. -** -** The isDirectMode flag may only be non-zero if the library was compiled -** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, -** if isDirect is non-zero, then the database file is updated directly -** by writing an updated version of page 1 using a call to the -** sqlite3OsWrite() function. -*/ -static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ - int rc = SQLITE_OK; - - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - ); - assert( assert_pager_state(pPager) ); - - /* Declare and initialize constant integer 'isDirect'. If the - ** atomic-write optimization is enabled in this build, then isDirect - ** is initialized to the value passed as the isDirectMode parameter - ** to this function. Otherwise, it is always set to zero. - ** - ** The idea is that if the atomic-write optimization is not - ** enabled at compile time, the compiler can omit the tests of - ** 'isDirect' below, as well as the block enclosed in the - ** "if( isDirect )" condition. - */ -#ifndef SQLITE_ENABLE_ATOMIC_WRITE -# define DIRECT_MODE 0 - assert( isDirectMode==0 ); - UNUSED_PARAMETER(isDirectMode); -#else -# define DIRECT_MODE isDirectMode -#endif - - if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ - PgHdr *pPgHdr; /* Reference to page 1 */ - - assert( !pPager->tempFile && isOpen(pPager->fd) ); - - /* Open page 1 of the file for writing. */ - rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0); - assert( pPgHdr==0 || rc==SQLITE_OK ); - - /* If page one was fetched successfully, and this function is not - ** operating in direct-mode, make page 1 writable. When not in - ** direct mode, page 1 is always held in cache and hence the PagerGet() - ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. - */ - if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ - rc = sqlite3PagerWrite(pPgHdr); - } - - if( rc==SQLITE_OK ){ - /* Actually do the update of the change counter */ - pager_write_changecounter(pPgHdr); - - /* If running in direct mode, write the contents of page 1 to the file. */ - if( DIRECT_MODE ){ - const void *zBuf; - assert( pPager->dbFileSize>0 ); - CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); - pPager->aStat[PAGER_STAT_WRITE]++; - } - if( rc==SQLITE_OK ){ - /* Update the pager's copy of the change-counter. Otherwise, the - ** next time a read transaction is opened the cache will be - ** flushed (as the change-counter values will not match). */ - const void *pCopy = (const void *)&((const char *)zBuf)[24]; - memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers)); - pPager->changeCountDone = 1; - } - }else{ - pPager->changeCountDone = 1; - } - } - - /* Release the page reference. */ - sqlite3PagerUnref(pPgHdr); - } - return rc; -} - -/* -** Sync the database file to disk. This is a no-op for in-memory databases -** or pages with the Pager.noSync flag set. -** -** If successful, or if called on a pager for which it is a no-op, this -** function returns SQLITE_OK. Otherwise, an IO error code is returned. -*/ -SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){ - int rc = SQLITE_OK; - - if( isOpen(pPager->fd) ){ - void *pArg = (void*)zMaster; - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - } - if( rc==SQLITE_OK && !pPager->noSync ){ - assert( !MEMDB ); - rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); - } - return rc; -} - -/* -** This function may only be called while a write-transaction is active in -** rollback. If the connection is in WAL mode, this call is a no-op. -** Otherwise, if the connection does not already have an EXCLUSIVE lock on -** the database file, an attempt is made to obtain one. -** -** If the EXCLUSIVE lock is already held or the attempt to obtain it is -** successful, or the connection is in WAL mode, SQLITE_OK is returned. -** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is -** returned. -*/ -SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ - int rc = pPager->errCode; - assert( assert_pager_state(pPager) ); - if( rc==SQLITE_OK ){ - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - || pPager->eState==PAGER_WRITER_LOCKED - ); - assert( assert_pager_state(pPager) ); - if( 0==pagerUseWal(pPager) ){ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - } - } - return rc; -} - -/* -** Sync the database file for the pager pPager. zMaster points to the name -** of a master journal file that should be written into the individual -** journal file. zMaster may be NULL, which is interpreted as no master -** journal (a single database transaction). -** -** This routine ensures that: -** -** * The database file change-counter is updated, -** * the journal is synced (unless the atomic-write optimization is used), -** * all dirty pages are written to the database file, -** * the database file is truncated (if required), and -** * the database file synced. -** -** The only thing that remains to commit the transaction is to finalize -** (delete, truncate or zero the first part of) the journal file (or -** delete the master journal file if specified). -** -** Note that if zMaster==NULL, this does not overwrite a previous value -** passed to an sqlite3PagerCommitPhaseOne() call. -** -** If the final parameter - noSync - is true, then the database file itself -** is not synced. The caller must call sqlite3PagerSync() directly to -** sync the database file before calling CommitPhaseTwo() to delete the -** journal file in this case. -*/ -SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( - Pager *pPager, /* Pager object */ - const char *zMaster, /* If not NULL, the master journal name */ - int noSync /* True to omit the xSync on the db file */ -){ - int rc = SQLITE_OK; /* Return code */ - - assert( pPager->eState==PAGER_WRITER_LOCKED - || pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - || pPager->eState==PAGER_ERROR - ); - assert( assert_pager_state(pPager) ); - - /* If a prior error occurred, report that error again. */ - if( NEVER(pPager->errCode) ) return pPager->errCode; - - /* Provide the ability to easily simulate an I/O error during testing */ - if( sqlite3FaultSim(400) ) return SQLITE_IOERR; - - PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", - pPager->zFilename, zMaster, pPager->dbSize)); - - /* If no database changes have been made, return early. */ - if( pPager->eStatetempFile ); - assert( isOpen(pPager->fd) || pPager->tempFile ); - if( 0==pagerFlushOnCommit(pPager, 1) ){ - /* If this is an in-memory db, or no pages have been written to, or this - ** function has already been called, it is mostly a no-op. However, any - ** backup in progress needs to be restarted. */ - sqlite3BackupRestart(pPager->pBackup); - }else{ - if( pagerUseWal(pPager) ){ - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); - PgHdr *pPageOne = 0; - if( pList==0 ){ - /* Must have at least one page for the WAL commit flag. - ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ - rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); - pList = pPageOne; - pList->pDirty = 0; - } - assert( rc==SQLITE_OK ); - if( ALWAYS(pList) ){ - rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); - } - sqlite3PagerUnref(pPageOne); - if( rc==SQLITE_OK ){ - sqlite3PcacheCleanAll(pPager->pPCache); - } - }else{ - /* The following block updates the change-counter. Exactly how it - ** does this depends on whether or not the atomic-update optimization - ** was enabled at compile time, and if this transaction meets the - ** runtime criteria to use the operation: - ** - ** * The file-system supports the atomic-write property for - ** blocks of size page-size, and - ** * This commit is not part of a multi-file transaction, and - ** * Exactly one page has been modified and store in the journal file. - ** - ** If the optimization was not enabled at compile time, then the - ** pager_incr_changecounter() function is called to update the change - ** counter in 'indirect-mode'. If the optimization is compiled in but - ** is not applicable to this transaction, call sqlite3JournalCreate() - ** to make sure the journal file has actually been created, then call - ** pager_incr_changecounter() to update the change-counter in indirect - ** mode. - ** - ** Otherwise, if the optimization is both enabled and applicable, - ** then call pager_incr_changecounter() to update the change-counter - ** in 'direct' mode. In this case the journal file will never be - ** created for this transaction. - */ - #ifdef SQLITE_ENABLE_ATOMIC_WRITE - PgHdr *pPg; - assert( isOpen(pPager->jfd) - || pPager->journalMode==PAGER_JOURNALMODE_OFF - || pPager->journalMode==PAGER_JOURNALMODE_WAL - ); - if( !zMaster && isOpen(pPager->jfd) - && pPager->journalOff==jrnlBufferSize(pPager) - && pPager->dbSize>=pPager->dbOrigSize - && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) - ){ - /* Update the db file change counter via the direct-write method. The - ** following call will modify the in-memory representation of page 1 - ** to include the updated change counter and then write page 1 - ** directly to the database file. Because of the atomic-write - ** property of the host file-system, this is safe. - */ - rc = pager_incr_changecounter(pPager, 1); - }else{ - rc = sqlite3JournalCreate(pPager->jfd); - if( rc==SQLITE_OK ){ - rc = pager_incr_changecounter(pPager, 0); - } - } - #else - rc = pager_incr_changecounter(pPager, 0); - #endif - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* Write the master journal name into the journal file. If a master - ** journal file name has already been written to the journal file, - ** or if zMaster is NULL (no master journal), then this call is a no-op. - */ - rc = writeMasterJournal(pPager, zMaster); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - /* Sync the journal file and write all dirty pages to the database. - ** If the atomic-update optimization is being used, this sync will not - ** create the journal file or perform any real IO. - ** - ** Because the change-counter page was just modified, unless the - ** atomic-update optimization is used it is almost certain that the - ** journal requires a sync here. However, in locking_mode=exclusive - ** on a system under memory pressure it is just possible that this is - ** not the case. In this case it is likely enough that the redundant - ** xSync() call will be changed to a no-op by the OS anyhow. - */ - rc = syncJournal(pPager, 0); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - - rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); - if( rc!=SQLITE_OK ){ - assert( rc!=SQLITE_IOERR_BLOCKED ); - goto commit_phase_one_exit; - } - sqlite3PcacheCleanAll(pPager->pPCache); - - /* If the file on disk is smaller than the database image, use - ** pager_truncate to grow the file here. This can happen if the database - ** image was extended as part of the current transaction and then the - ** last page in the db image moved to the free-list. In this case the - ** last page is never written out to disk, leaving the database file - ** undersized. Fix this now if it is the case. */ - if( pPager->dbSize>pPager->dbFileSize ){ - Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager)); - assert( pPager->eState==PAGER_WRITER_DBMOD ); - rc = pager_truncate(pPager, nNew); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - } - - /* Finally, sync the database file. */ - if( !noSync ){ - rc = sqlite3PagerSync(pPager, zMaster); - } - IOTRACE(("DBSYNC %p\n", pPager)) - } - } - -commit_phase_one_exit: - if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ - pPager->eState = PAGER_WRITER_FINISHED; - } - return rc; -} - - -/* -** When this function is called, the database file has been completely -** updated to reflect the changes made by the current transaction and -** synced to disk. The journal file still exists in the file-system -** though, and if a failure occurs at this point it will eventually -** be used as a hot-journal and the current transaction rolled back. -** -** This function finalizes the journal file, either by deleting, -** truncating or partially zeroing it, so that it cannot be used -** for hot-journal rollback. Once this is done the transaction is -** irrevocably committed. -** -** If an error occurs, an IO error code is returned and the pager -** moves into the error state. Otherwise, SQLITE_OK is returned. -*/ -SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ - int rc = SQLITE_OK; /* Return code */ - - /* This routine should not be called if a prior error has occurred. - ** But if (due to a coding error elsewhere in the system) it does get - ** called, just return the same error code without doing anything. */ - if( NEVER(pPager->errCode) ) return pPager->errCode; - - assert( pPager->eState==PAGER_WRITER_LOCKED - || pPager->eState==PAGER_WRITER_FINISHED - || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) - ); - assert( assert_pager_state(pPager) ); - - /* An optimization. If the database was not actually modified during - ** this transaction, the pager is running in exclusive-mode and is - ** using persistent journals, then this function is a no-op. - ** - ** The start of the journal file currently contains a single journal - ** header with the nRec field set to 0. If such a journal is used as - ** a hot-journal during hot-journal rollback, 0 changes will be made - ** to the database file. So there is no need to zero the journal - ** header. Since the pager is in exclusive mode, there is no need - ** to drop any locks either. - */ - if( pPager->eState==PAGER_WRITER_LOCKED - && pPager->exclusiveMode - && pPager->journalMode==PAGER_JOURNALMODE_PERSIST - ){ - assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); - pPager->eState = PAGER_READER; - return SQLITE_OK; - } - - PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); - pPager->iDataVersion++; - rc = pager_end_transaction(pPager, pPager->setMaster, 1); - return pager_error(pPager, rc); -} - -/* -** If a write transaction is open, then all changes made within the -** transaction are reverted and the current write-transaction is closed. -** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR -** state if an error occurs. -** -** If the pager is already in PAGER_ERROR state when this function is called, -** it returns Pager.errCode immediately. No work is performed in this case. -** -** Otherwise, in rollback mode, this function performs two functions: -** -** 1) It rolls back the journal file, restoring all database file and -** in-memory cache pages to the state they were in when the transaction -** was opened, and -** -** 2) It finalizes the journal file, so that it is not used for hot -** rollback at any point in the future. -** -** Finalization of the journal file (task 2) is only performed if the -** rollback is successful. -** -** In WAL mode, all cache-entries containing data modified within the -** current transaction are either expelled from the cache or reverted to -** their pre-transaction state by re-reading data from the database or -** WAL files. The WAL transaction is then closed. -*/ -SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ - int rc = SQLITE_OK; /* Return code */ - PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); - - /* PagerRollback() is a no-op if called in READER or OPEN state. If - ** the pager is already in the ERROR state, the rollback is not - ** attempted here. Instead, the error code is returned to the caller. - */ - assert( assert_pager_state(pPager) ); - if( pPager->eState==PAGER_ERROR ) return pPager->errCode; - if( pPager->eState<=PAGER_READER ) return SQLITE_OK; - - if( pagerUseWal(pPager) ){ - int rc2; - rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); - rc2 = pager_end_transaction(pPager, pPager->setMaster, 0); - if( rc==SQLITE_OK ) rc = rc2; - }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ - int eState = pPager->eState; - rc = pager_end_transaction(pPager, 0, 0); - if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ - /* This can happen using journal_mode=off. Move the pager to the error - ** state to indicate that the contents of the cache may not be trusted. - ** Any active readers will get SQLITE_ABORT. - */ - pPager->errCode = SQLITE_ABORT; - pPager->eState = PAGER_ERROR; - return rc; - } - }else{ - rc = pager_playback(pPager, 0); - } - - assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); - assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT - || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR - || rc==SQLITE_CANTOPEN - ); - - /* If an error occurs during a ROLLBACK, we can no longer trust the pager - ** cache. So call pager_error() on the way out to make any error persistent. - */ - return pager_error(pPager, rc); -} - -/* -** Return TRUE if the database file is opened read-only. Return FALSE -** if the database is (in theory) writable. -*/ -SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){ - return pPager->readOnly; -} - -#ifdef SQLITE_DEBUG -/* -** Return the sum of the reference counts for all pages held by pPager. -*/ -SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ - return sqlite3PcacheRefCount(pPager->pPCache); -} -#endif - -/* -** Return the approximate number of bytes of memory currently -** used by the pager and its associated cache. -*/ -SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ - int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) - + 5*sizeof(void*); - return perPageSize*sqlite3PcachePagecount(pPager->pPCache) - + sqlite3MallocSize(pPager) - + pPager->pageSize; -} - -/* -** Return the number of references to the specified page. -*/ -SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ - return sqlite3PcachePageRefcount(pPage); -} - -#ifdef SQLITE_TEST -/* -** This routine is used for testing and analysis only. -*/ -SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ - static int a[11]; - a[0] = sqlite3PcacheRefCount(pPager->pPCache); - a[1] = sqlite3PcachePagecount(pPager->pPCache); - a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); - a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; - a[4] = pPager->eState; - a[5] = pPager->errCode; - a[6] = pPager->aStat[PAGER_STAT_HIT]; - a[7] = pPager->aStat[PAGER_STAT_MISS]; - a[8] = 0; /* Used to be pPager->nOvfl */ - a[9] = pPager->nRead; - a[10] = pPager->aStat[PAGER_STAT_WRITE]; - return a; -} -#endif - -/* -** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or -** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the -** current cache hit or miss count, according to the value of eStat. If the -** reset parameter is non-zero, the cache hit or miss count is zeroed before -** returning. -*/ -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ - - assert( eStat==SQLITE_DBSTATUS_CACHE_HIT - || eStat==SQLITE_DBSTATUS_CACHE_MISS - || eStat==SQLITE_DBSTATUS_CACHE_WRITE - ); - - assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); - assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); - assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 ); - - *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT]; - if( reset ){ - pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0; - } -} - -/* -** Return true if this is an in-memory or temp-file backed pager. -*/ -SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ - return pPager->tempFile; -} - -/* -** Check that there are at least nSavepoint savepoints open. If there are -** currently less than nSavepoints open, then open one or more savepoints -** to make up the difference. If the number of savepoints is already -** equal to nSavepoint, then this function is a no-op. -** -** If a memory allocation fails, SQLITE_NOMEM is returned. If an error -** occurs while opening the sub-journal file, then an IO error code is -** returned. Otherwise, SQLITE_OK. -*/ -static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ - int rc = SQLITE_OK; /* Return code */ - int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ - int ii; /* Iterator variable */ - PagerSavepoint *aNew; /* New Pager.aSavepoint array */ - - assert( pPager->eState>=PAGER_WRITER_LOCKED ); - assert( assert_pager_state(pPager) ); - assert( nSavepoint>nCurrent && pPager->useJournal ); - - /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM - ** if the allocation fails. Otherwise, zero the new portion in case a - ** malloc failure occurs while populating it in the for(...) loop below. - */ - aNew = (PagerSavepoint *)sqlite3Realloc( - pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint - ); - if( !aNew ){ - return SQLITE_NOMEM_BKPT; - } - memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); - pPager->aSavepoint = aNew; - - /* Populate the PagerSavepoint structures just allocated. */ - for(ii=nCurrent; iidbSize; - if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ - aNew[ii].iOffset = pPager->journalOff; - }else{ - aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); - } - aNew[ii].iSubRec = pPager->nSubRec; - aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); - if( !aNew[ii].pInSavepoint ){ - return SQLITE_NOMEM_BKPT; - } - if( pagerUseWal(pPager) ){ - sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); - } - pPager->nSavepoint = ii+1; - } - assert( pPager->nSavepoint==nSavepoint ); - assertTruncateConstraint(pPager); - return rc; -} -SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ - assert( pPager->eState>=PAGER_WRITER_LOCKED ); - assert( assert_pager_state(pPager) ); - - if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){ - return pagerOpenSavepoint(pPager, nSavepoint); - }else{ - return SQLITE_OK; - } -} - - -/* -** This function is called to rollback or release (commit) a savepoint. -** The savepoint to release or rollback need not be the most recently -** created savepoint. -** -** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. -** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with -** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes -** that have occurred since the specified savepoint was created. -** -** The savepoint to rollback or release is identified by parameter -** iSavepoint. A value of 0 means to operate on the outermost savepoint -** (the first created). A value of (Pager.nSavepoint-1) means operate -** on the most recently created savepoint. If iSavepoint is greater than -** (Pager.nSavepoint-1), then this function is a no-op. -** -** If a negative value is passed to this function, then the current -** transaction is rolled back. This is different to calling -** sqlite3PagerRollback() because this function does not terminate -** the transaction or unlock the database, it just restores the -** contents of the database to its original state. -** -** In any case, all savepoints with an index greater than iSavepoint -** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), -** then savepoint iSavepoint is also destroyed. -** -** This function may return SQLITE_NOMEM if a memory allocation fails, -** or an IO error code if an IO error occurs while rolling back a -** savepoint. If no errors occur, SQLITE_OK is returned. -*/ -SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ - int rc = pPager->errCode; - -#ifdef SQLITE_ENABLE_ZIPVFS - if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; -#endif - - assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); - assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); - - if( rc==SQLITE_OK && iSavepointnSavepoint ){ - int ii; /* Iterator variable */ - int nNew; /* Number of remaining savepoints after this op. */ - - /* Figure out how many savepoints will still be active after this - ** operation. Store this value in nNew. Then free resources associated - ** with any savepoints that are destroyed by this operation. - */ - nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); - for(ii=nNew; iinSavepoint; ii++){ - sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); - } - pPager->nSavepoint = nNew; - - /* If this is a release of the outermost savepoint, truncate - ** the sub-journal to zero bytes in size. */ - if( op==SAVEPOINT_RELEASE ){ - if( nNew==0 && isOpen(pPager->sjfd) ){ - /* Only truncate if it is an in-memory sub-journal. */ - if( sqlite3JournalIsInMemory(pPager->sjfd) ){ - rc = sqlite3OsTruncate(pPager->sjfd, 0); - assert( rc==SQLITE_OK ); - } - pPager->nSubRec = 0; - } - } - /* Else this is a rollback operation, playback the specified savepoint. - ** If this is a temp-file, it is possible that the journal file has - ** not yet been opened. In this case there have been no changes to - ** the database file, so the playback operation can be skipped. - */ - else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ - PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; - rc = pagerPlaybackSavepoint(pPager, pSavepoint); - assert(rc!=SQLITE_DONE); - } - -#ifdef SQLITE_ENABLE_ZIPVFS - /* If the cache has been modified but the savepoint cannot be rolled - ** back journal_mode=off, put the pager in the error state. This way, - ** if the VFS used by this pager includes ZipVFS, the entire transaction - ** can be rolled back at the ZipVFS level. */ - else if( - pPager->journalMode==PAGER_JOURNALMODE_OFF - && pPager->eState>=PAGER_WRITER_CACHEMOD - ){ - pPager->errCode = SQLITE_ABORT; - pPager->eState = PAGER_ERROR; - } -#endif - } - - return rc; -} - -/* -** Return the full pathname of the database file. -** -** Except, if the pager is in-memory only, then return an empty string if -** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when -** used to report the filename to the user, for compatibility with legacy -** behavior. But when the Btree needs to know the filename for matching to -** shared cache, it uses nullIfMemDb==0 so that in-memory databases can -** participate in shared-cache. -*/ -SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){ - return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename; -} - -/* -** Return the VFS structure for the pager. -*/ -SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ - return pPager->pVfs; -} - -/* -** Return the file handle for the database file associated -** with the pager. This might return NULL if the file has -** not yet been opened. -*/ -SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ - return pPager->fd; -} - -/* -** Return the file handle for the journal file (if it exists). -** This will be either the rollback journal or the WAL file. -*/ -SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ -#if SQLITE_OMIT_WAL - return pPager->jfd; -#else - return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; -#endif -} - -/* -** Return the full pathname of the journal file. -*/ -SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){ - return pPager->zJournal; -} - -#ifdef SQLITE_HAS_CODEC -/* -** Set or retrieve the codec for this pager -*/ -SQLITE_PRIVATE void sqlite3PagerSetCodec( - Pager *pPager, - void *(*xCodec)(void*,void*,Pgno,int), - void (*xCodecSizeChng)(void*,int,int), - void (*xCodecFree)(void*), - void *pCodec -){ - if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); - pPager->xCodec = pPager->memDb ? 0 : xCodec; - pPager->xCodecSizeChng = xCodecSizeChng; - pPager->xCodecFree = xCodecFree; - pPager->pCodec = pCodec; - pagerReportSize(pPager); -} -SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ - return pPager->pCodec; -} - -/* -** This function is called by the wal module when writing page content -** into the log file. -** -** This function returns a pointer to a buffer containing the encrypted -** page content. If a malloc fails, this function may return NULL. -*/ -SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){ - void *aData = 0; - CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); - return aData; -} - -/* -** Return the current pager state -*/ -SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){ - return pPager->eState; -} -#endif /* SQLITE_HAS_CODEC */ - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Move the page pPg to location pgno in the file. -** -** There must be no references to the page previously located at -** pgno (which we call pPgOld) though that page is allowed to be -** in cache. If the page previously located at pgno is not already -** in the rollback journal, it is not put there by by this routine. -** -** References to the page pPg remain valid. Updating any -** meta-data associated with pPg (i.e. data stored in the nExtra bytes -** allocated along with the page) is the responsibility of the caller. -** -** A transaction must be active when this routine is called. It used to be -** required that a statement transaction was not active, but this restriction -** has been removed (CREATE INDEX needs to move a page when a statement -** transaction is active). -** -** If the fourth argument, isCommit, is non-zero, then this page is being -** moved as part of a database reorganization just before the transaction -** is being committed. In this case, it is guaranteed that the database page -** pPg refers to will not be written to again within this transaction. -** -** This function may return SQLITE_NOMEM or an IO error code if an error -** occurs. Otherwise, it returns SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ - PgHdr *pPgOld; /* The page being overwritten. */ - Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ - int rc; /* Return code */ - Pgno origPgno; /* The original page number */ - - assert( pPg->nRef>0 ); - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - ); - assert( assert_pager_state(pPager) ); - - /* In order to be able to rollback, an in-memory database must journal - ** the page we are moving from. - */ - assert( pPager->tempFile || !MEMDB ); - if( pPager->tempFile ){ - rc = sqlite3PagerWrite(pPg); - if( rc ) return rc; - } - - /* If the page being moved is dirty and has not been saved by the latest - ** savepoint, then save the current contents of the page into the - ** sub-journal now. This is required to handle the following scenario: - ** - ** BEGIN; - ** - ** SAVEPOINT one; - ** - ** ROLLBACK TO one; - ** - ** If page X were not written to the sub-journal here, it would not - ** be possible to restore its contents when the "ROLLBACK TO one" - ** statement were is processed. - ** - ** subjournalPage() may need to allocate space to store pPg->pgno into - ** one or more savepoint bitvecs. This is the reason this function - ** may return SQLITE_NOMEM. - */ - if( (pPg->flags & PGHDR_DIRTY)!=0 - && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg)) - ){ - return rc; - } - - PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", - PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); - IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) - - /* If the journal needs to be sync()ed before page pPg->pgno can - ** be written to, store pPg->pgno in local variable needSyncPgno. - ** - ** If the isCommit flag is set, there is no need to remember that - ** the journal needs to be sync()ed before database page pPg->pgno - ** can be written to. The caller has already promised not to write to it. - */ - if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ - needSyncPgno = pPg->pgno; - assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || - pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); - assert( pPg->flags&PGHDR_DIRTY ); - } - - /* If the cache contains a page with page-number pgno, remove it - ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for - ** page pgno before the 'move' operation, it needs to be retained - ** for the page moved there. - */ - pPg->flags &= ~PGHDR_NEED_SYNC; - pPgOld = sqlite3PagerLookup(pPager, pgno); - assert( !pPgOld || pPgOld->nRef==1 ); - if( pPgOld ){ - pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); - if( pPager->tempFile ){ - /* Do not discard pages from an in-memory database since we might - ** need to rollback later. Just move the page out of the way. */ - sqlite3PcacheMove(pPgOld, pPager->dbSize+1); - }else{ - sqlite3PcacheDrop(pPgOld); - } - } - - origPgno = pPg->pgno; - sqlite3PcacheMove(pPg, pgno); - sqlite3PcacheMakeDirty(pPg); - - /* For an in-memory database, make sure the original page continues - ** to exist, in case the transaction needs to roll back. Use pPgOld - ** as the original page since it has already been allocated. - */ - if( pPager->tempFile && pPgOld ){ - sqlite3PcacheMove(pPgOld, origPgno); - sqlite3PagerUnrefNotNull(pPgOld); - } - - if( needSyncPgno ){ - /* If needSyncPgno is non-zero, then the journal file needs to be - ** sync()ed before any data is written to database file page needSyncPgno. - ** Currently, no such page exists in the page-cache and the - ** "is journaled" bitvec flag has been set. This needs to be remedied by - ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC - ** flag. - ** - ** If the attempt to load the page into the page-cache fails, (due - ** to a malloc() or IO failure), clear the bit in the pInJournal[] - ** array. Otherwise, if the page is loaded and written again in - ** this transaction, it may be written to the database file before - ** it is synced into the journal file. This way, it may end up in - ** the journal file twice, but that is not a problem. - */ - PgHdr *pPgHdr; - rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); - if( rc!=SQLITE_OK ){ - if( needSyncPgno<=pPager->dbOrigSize ){ - assert( pPager->pTmpSpace!=0 ); - sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); - } - return rc; - } - pPgHdr->flags |= PGHDR_NEED_SYNC; - sqlite3PcacheMakeDirty(pPgHdr); - sqlite3PagerUnrefNotNull(pPgHdr); - } - - return SQLITE_OK; -} -#endif - -/* -** The page handle passed as the first argument refers to a dirty page -** with a page number other than iNew. This function changes the page's -** page number to iNew and sets the value of the PgHdr.flags field to -** the value passed as the third parameter. -*/ -SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ - assert( pPg->pgno!=iNew ); - pPg->flags = flags; - sqlite3PcacheMove(pPg, iNew); -} - -/* -** Return a pointer to the data for the specified page. -*/ -SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ - assert( pPg->nRef>0 || pPg->pPager->memDb ); - return pPg->pData; -} - -/* -** Return a pointer to the Pager.nExtra bytes of "extra" space -** allocated along with the specified page. -*/ -SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ - return pPg->pExtra; -} - -/* -** Get/set the locking-mode for this pager. Parameter eMode must be one -** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or -** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then -** the locking-mode is set to the value specified. -** -** The returned value is either PAGER_LOCKINGMODE_NORMAL or -** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) -** locking-mode. -*/ -SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ - assert( eMode==PAGER_LOCKINGMODE_QUERY - || eMode==PAGER_LOCKINGMODE_NORMAL - || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); - assert( PAGER_LOCKINGMODE_QUERY<0 ); - assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); - assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); - if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ - pPager->exclusiveMode = (u8)eMode; - } - return (int)pPager->exclusiveMode; -} - -/* -** Set the journal-mode for this pager. Parameter eMode must be one of: -** -** PAGER_JOURNALMODE_DELETE -** PAGER_JOURNALMODE_TRUNCATE -** PAGER_JOURNALMODE_PERSIST -** PAGER_JOURNALMODE_OFF -** PAGER_JOURNALMODE_MEMORY -** PAGER_JOURNALMODE_WAL -** -** The journalmode is set to the value specified if the change is allowed. -** The change may be disallowed for the following reasons: -** -** * An in-memory database can only have its journal_mode set to _OFF -** or _MEMORY. -** -** * Temporary databases cannot have _WAL journalmode. -** -** The returned indicate the current (possibly updated) journal-mode. -*/ -SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ - u8 eOld = pPager->journalMode; /* Prior journalmode */ - -#ifdef SQLITE_DEBUG - /* The print_pager_state() routine is intended to be used by the debugger - ** only. We invoke it once here to suppress a compiler warning. */ - print_pager_state(pPager); -#endif - - - /* The eMode parameter is always valid */ - assert( eMode==PAGER_JOURNALMODE_DELETE - || eMode==PAGER_JOURNALMODE_TRUNCATE - || eMode==PAGER_JOURNALMODE_PERSIST - || eMode==PAGER_JOURNALMODE_OFF - || eMode==PAGER_JOURNALMODE_WAL - || eMode==PAGER_JOURNALMODE_MEMORY ); - - /* This routine is only called from the OP_JournalMode opcode, and - ** the logic there will never allow a temporary file to be changed - ** to WAL mode. - */ - assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); - - /* Do allow the journalmode of an in-memory database to be set to - ** anything other than MEMORY or OFF - */ - if( MEMDB ){ - assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); - if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ - eMode = eOld; - } - } - - if( eMode!=eOld ){ - - /* Change the journal mode. */ - assert( pPager->eState!=PAGER_ERROR ); - pPager->journalMode = (u8)eMode; - - /* When transistioning from TRUNCATE or PERSIST to any other journal - ** mode except WAL, unless the pager is in locking_mode=exclusive mode, - ** delete the journal file. - */ - assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); - assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); - assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); - assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); - assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); - assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); - - assert( isOpen(pPager->fd) || pPager->exclusiveMode ); - if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ - - /* In this case we would like to delete the journal file. If it is - ** not possible, then that is not a problem. Deleting the journal file - ** here is an optimization only. - ** - ** Before deleting the journal file, obtain a RESERVED lock on the - ** database file. This ensures that the journal file is not deleted - ** while it is in use by some other client. - */ - sqlite3OsClose(pPager->jfd); - if( pPager->eLock>=RESERVED_LOCK ){ - sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); - }else{ - int rc = SQLITE_OK; - int state = pPager->eState; - assert( state==PAGER_OPEN || state==PAGER_READER ); - if( state==PAGER_OPEN ){ - rc = sqlite3PagerSharedLock(pPager); - } - if( pPager->eState==PAGER_READER ){ - assert( rc==SQLITE_OK ); - rc = pagerLockDb(pPager, RESERVED_LOCK); - } - if( rc==SQLITE_OK ){ - sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); - } - if( rc==SQLITE_OK && state==PAGER_READER ){ - pagerUnlockDb(pPager, SHARED_LOCK); - }else if( state==PAGER_OPEN ){ - pager_unlock(pPager); - } - assert( state==pPager->eState ); - } - }else if( eMode==PAGER_JOURNALMODE_OFF ){ - sqlite3OsClose(pPager->jfd); - } - } - - /* Return the new journal mode */ - return (int)pPager->journalMode; -} - -/* -** Return the current journal mode. -*/ -SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ - return (int)pPager->journalMode; -} - -/* -** Return TRUE if the pager is in a state where it is OK to change the -** journalmode. Journalmode changes can only happen when the database -** is unmodified. -*/ -SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ - assert( assert_pager_state(pPager) ); - if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; - if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; - return 1; -} - -/* -** Get/set the size-limit used for persistent journal files. -** -** Setting the size limit to -1 means no limit is enforced. -** An attempt to set a limit smaller than -1 is a no-op. -*/ -SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ - if( iLimit>=-1 ){ - pPager->journalSizeLimit = iLimit; - sqlite3WalLimit(pPager->pWal, iLimit); - } - return pPager->journalSizeLimit; -} - -/* -** Return a pointer to the pPager->pBackup variable. The backup module -** in backup.c maintains the content of this variable. This module -** uses it opaquely as an argument to sqlite3BackupRestart() and -** sqlite3BackupUpdate() only. -*/ -SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ - return &pPager->pBackup; -} - -#ifndef SQLITE_OMIT_VACUUM -/* -** Unless this is an in-memory or temporary database, clear the pager cache. -*/ -SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){ - assert( MEMDB==0 || pPager->tempFile ); - if( pPager->tempFile==0 ) pager_reset(pPager); -} -#endif - - -#ifndef SQLITE_OMIT_WAL -/* -** This function is called when the user invokes "PRAGMA wal_checkpoint", -** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() -** or wal_blocking_checkpoint() API functions. -** -** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. -*/ -SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){ - int rc = SQLITE_OK; - if( pPager->pWal ){ - rc = sqlite3WalCheckpoint(pPager->pWal, eMode, - (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), - pPager->pBusyHandlerArg, - pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, - pnLog, pnCkpt - ); - } - return rc; -} - -SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ - return sqlite3WalCallback(pPager->pWal); -} - -/* -** Return true if the underlying VFS for the given pager supports the -** primitives necessary for write-ahead logging. -*/ -SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ - const sqlite3_io_methods *pMethods = pPager->fd->pMethods; - if( pPager->noLock ) return 0; - return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); -} - -/* -** Attempt to take an exclusive lock on the database file. If a PENDING lock -** is obtained instead, immediately release it. -*/ -static int pagerExclusiveLock(Pager *pPager){ - int rc; /* Return code */ - - assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); - rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); - if( rc!=SQLITE_OK ){ - /* If the attempt to grab the exclusive lock failed, release the - ** pending lock that may have been obtained instead. */ - pagerUnlockDb(pPager, SHARED_LOCK); - } - - return rc; -} - -/* -** Call sqlite3WalOpen() to open the WAL handle. If the pager is in -** exclusive-locking mode when this function is called, take an EXCLUSIVE -** lock on the database file and use heap-memory to store the wal-index -** in. Otherwise, use the normal shared-memory. -*/ -static int pagerOpenWal(Pager *pPager){ - int rc = SQLITE_OK; - - assert( pPager->pWal==0 && pPager->tempFile==0 ); - assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); - - /* If the pager is already in exclusive-mode, the WAL module will use - ** heap-memory for the wal-index instead of the VFS shared-memory - ** implementation. Take the exclusive lock now, before opening the WAL - ** file, to make sure this is safe. - */ - if( pPager->exclusiveMode ){ - rc = pagerExclusiveLock(pPager); - } - - /* Open the connection to the log file. If this operation fails, - ** (e.g. due to malloc() failure), return an error code. - */ - if( rc==SQLITE_OK ){ - rc = sqlite3WalOpen(pPager->pVfs, - pPager->fd, pPager->zWal, pPager->exclusiveMode, - pPager->journalSizeLimit, &pPager->pWal - ); - } - pagerFixMaplimit(pPager); - - return rc; -} - - -/* -** The caller must be holding a SHARED lock on the database file to call -** this function. -** -** If the pager passed as the first argument is open on a real database -** file (not a temp file or an in-memory database), and the WAL file -** is not already open, make an attempt to open it now. If successful, -** return SQLITE_OK. If an error occurs or the VFS used by the pager does -** not support the xShmXXX() methods, return an error code. *pbOpen is -** not modified in either case. -** -** If the pager is open on a temp-file (or in-memory database), or if -** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK -** without doing anything. -*/ -SQLITE_PRIVATE int sqlite3PagerOpenWal( - Pager *pPager, /* Pager object */ - int *pbOpen /* OUT: Set to true if call is a no-op */ -){ - int rc = SQLITE_OK; /* Return code */ - - assert( assert_pager_state(pPager) ); - assert( pPager->eState==PAGER_OPEN || pbOpen ); - assert( pPager->eState==PAGER_READER || !pbOpen ); - assert( pbOpen==0 || *pbOpen==0 ); - assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); - - if( !pPager->tempFile && !pPager->pWal ){ - if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; - - /* Close any rollback journal previously open */ - sqlite3OsClose(pPager->jfd); - - rc = pagerOpenWal(pPager); - if( rc==SQLITE_OK ){ - pPager->journalMode = PAGER_JOURNALMODE_WAL; - pPager->eState = PAGER_OPEN; - } - }else{ - *pbOpen = 1; - } - - return rc; -} - -/* -** This function is called to close the connection to the log file prior -** to switching from WAL to rollback mode. -** -** Before closing the log file, this function attempts to take an -** EXCLUSIVE lock on the database file. If this cannot be obtained, an -** error (SQLITE_BUSY) is returned and the log connection is not closed. -** If successful, the EXCLUSIVE lock is not released before returning. -*/ -SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){ - int rc = SQLITE_OK; - - assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); - - /* If the log file is not already open, but does exist in the file-system, - ** it may need to be checkpointed before the connection can switch to - ** rollback mode. Open it now so this can happen. - */ - if( !pPager->pWal ){ - int logexists = 0; - rc = pagerLockDb(pPager, SHARED_LOCK); - if( rc==SQLITE_OK ){ - rc = sqlite3OsAccess( - pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists - ); - } - if( rc==SQLITE_OK && logexists ){ - rc = pagerOpenWal(pPager); - } - } - - /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on - ** the database file, the log and log-summary files will be deleted. - */ - if( rc==SQLITE_OK && pPager->pWal ){ - rc = pagerExclusiveLock(pPager); - if( rc==SQLITE_OK ){ - rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, - pPager->pageSize, (u8*)pPager->pTmpSpace); - pPager->pWal = 0; - pagerFixMaplimit(pPager); - if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); - } - } - return rc; -} - -#ifdef SQLITE_ENABLE_SNAPSHOT -/* -** If this is a WAL database, obtain a snapshot handle for the snapshot -** currently open. Otherwise, return an error. -*/ -SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ - int rc = SQLITE_ERROR; - if( pPager->pWal ){ - rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); - } - return rc; -} - -/* -** If this is a WAL database, store a pointer to pSnapshot. Next time a -** read transaction is opened, attempt to read from the snapshot it -** identifies. If this is not a WAL database, return an error. -*/ -SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ - int rc = SQLITE_OK; - if( pPager->pWal ){ - sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); - }else{ - rc = SQLITE_ERROR; - } - return rc; -} -#endif /* SQLITE_ENABLE_SNAPSHOT */ -#endif /* !SQLITE_OMIT_WAL */ - -#ifdef SQLITE_ENABLE_ZIPVFS -/* -** A read-lock must be held on the pager when this function is called. If -** the pager is in WAL mode and the WAL file currently contains one or more -** frames, return the size in bytes of the page images stored within the -** WAL frames. Otherwise, if this is not a WAL database or the WAL file -** is empty, return 0. -*/ -SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ - assert( pPager->eState>=PAGER_READER ); - return sqlite3WalFramesize(pPager->pWal); -} -#endif - -#endif /* SQLITE_OMIT_DISKIO */ - -/************** End of pager.c ***********************************************/ -/************** Begin file wal.c *********************************************/ -/* -** 2010 February 1 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the implementation of a write-ahead log (WAL) used in -** "journal_mode=WAL" mode. -** -** WRITE-AHEAD LOG (WAL) FILE FORMAT -** -** A WAL file consists of a header followed by zero or more "frames". -** Each frame records the revised content of a single page from the -** database file. All changes to the database are recorded by writing -** frames into the WAL. Transactions commit when a frame is written that -** contains a commit marker. A single WAL can and usually does record -** multiple transactions. Periodically, the content of the WAL is -** transferred back into the database file in an operation called a -** "checkpoint". -** -** A single WAL file can be used multiple times. In other words, the -** WAL can fill up with frames and then be checkpointed and then new -** frames can overwrite the old ones. A WAL always grows from beginning -** toward the end. Checksums and counters attached to each frame are -** used to determine which frames within the WAL are valid and which -** are leftovers from prior checkpoints. -** -** The WAL header is 32 bytes in size and consists of the following eight -** big-endian 32-bit unsigned integer values: -** -** 0: Magic number. 0x377f0682 or 0x377f0683 -** 4: File format version. Currently 3007000 -** 8: Database page size. Example: 1024 -** 12: Checkpoint sequence number -** 16: Salt-1, random integer incremented with each checkpoint -** 20: Salt-2, a different random integer changing with each ckpt -** 24: Checksum-1 (first part of checksum for first 24 bytes of header). -** 28: Checksum-2 (second part of checksum for first 24 bytes of header). -** -** Immediately following the wal-header are zero or more frames. Each -** frame consists of a 24-byte frame-header followed by a bytes -** of page data. The frame-header is six big-endian 32-bit unsigned -** integer values, as follows: -** -** 0: Page number. -** 4: For commit records, the size of the database image in pages -** after the commit. For all other records, zero. -** 8: Salt-1 (copied from the header) -** 12: Salt-2 (copied from the header) -** 16: Checksum-1. -** 20: Checksum-2. -** -** A frame is considered valid if and only if the following conditions are -** true: -** -** (1) The salt-1 and salt-2 values in the frame-header match -** salt values in the wal-header -** -** (2) The checksum values in the final 8 bytes of the frame-header -** exactly match the checksum computed consecutively on the -** WAL header and the first 8 bytes and the content of all frames -** up to and including the current frame. -** -** The checksum is computed using 32-bit big-endian integers if the -** magic number in the first 4 bytes of the WAL is 0x377f0683 and it -** is computed using little-endian if the magic number is 0x377f0682. -** The checksum values are always stored in the frame header in a -** big-endian format regardless of which byte order is used to compute -** the checksum. The checksum is computed by interpreting the input as -** an even number of unsigned 32-bit integers: x[0] through x[N]. The -** algorithm used for the checksum is as follows: -** -** for i from 0 to n-1 step 2: -** s0 += x[i] + s1; -** s1 += x[i+1] + s0; -** endfor -** -** Note that s0 and s1 are both weighted checksums using fibonacci weights -** in reverse order (the largest fibonacci weight occurs on the first element -** of the sequence being summed.) The s1 value spans all 32-bit -** terms of the sequence whereas s0 omits the final term. -** -** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the -** WAL is transferred into the database, then the database is VFS.xSync-ed. -** The VFS.xSync operations serve as write barriers - all writes launched -** before the xSync must complete before any write that launches after the -** xSync begins. -** -** After each checkpoint, the salt-1 value is incremented and the salt-2 -** value is randomized. This prevents old and new frames in the WAL from -** being considered valid at the same time and being checkpointing together -** following a crash. -** -** READER ALGORITHM -** -** To read a page from the database (call it page number P), a reader -** first checks the WAL to see if it contains page P. If so, then the -** last valid instance of page P that is a followed by a commit frame -** or is a commit frame itself becomes the value read. If the WAL -** contains no copies of page P that are valid and which are a commit -** frame or are followed by a commit frame, then page P is read from -** the database file. -** -** To start a read transaction, the reader records the index of the last -** valid frame in the WAL. The reader uses this recorded "mxFrame" value -** for all subsequent read operations. New transactions can be appended -** to the WAL, but as long as the reader uses its original mxFrame value -** and ignores the newly appended content, it will see a consistent snapshot -** of the database from a single point in time. This technique allows -** multiple concurrent readers to view different versions of the database -** content simultaneously. -** -** The reader algorithm in the previous paragraphs works correctly, but -** because frames for page P can appear anywhere within the WAL, the -** reader has to scan the entire WAL looking for page P frames. If the -** WAL is large (multiple megabytes is typical) that scan can be slow, -** and read performance suffers. To overcome this problem, a separate -** data structure called the wal-index is maintained to expedite the -** search for frames of a particular page. -** -** WAL-INDEX FORMAT -** -** Conceptually, the wal-index is shared memory, though VFS implementations -** might choose to implement the wal-index using a mmapped file. Because -** the wal-index is shared memory, SQLite does not support journal_mode=WAL -** on a network filesystem. All users of the database must be able to -** share memory. -** -** The wal-index is transient. After a crash, the wal-index can (and should -** be) reconstructed from the original WAL file. In fact, the VFS is required -** to either truncate or zero the header of the wal-index when the last -** connection to it closes. Because the wal-index is transient, it can -** use an architecture-specific format; it does not have to be cross-platform. -** Hence, unlike the database and WAL file formats which store all values -** as big endian, the wal-index can store multi-byte values in the native -** byte order of the host computer. -** -** The purpose of the wal-index is to answer this question quickly: Given -** a page number P and a maximum frame index M, return the index of the -** last frame in the wal before frame M for page P in the WAL, or return -** NULL if there are no frames for page P in the WAL prior to M. -** -** The wal-index consists of a header region, followed by an one or -** more index blocks. -** -** The wal-index header contains the total number of frames within the WAL -** in the mxFrame field. -** -** Each index block except for the first contains information on -** HASHTABLE_NPAGE frames. The first index block contains information on -** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and -** HASHTABLE_NPAGE are selected so that together the wal-index header and -** first index block are the same size as all other index blocks in the -** wal-index. -** -** Each index block contains two sections, a page-mapping that contains the -** database page number associated with each wal frame, and a hash-table -** that allows readers to query an index block for a specific page number. -** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE -** for the first index block) 32-bit page numbers. The first entry in the -** first index-block contains the database page number corresponding to the -** first frame in the WAL file. The first entry in the second index block -** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in -** the log, and so on. -** -** The last index block in a wal-index usually contains less than the full -** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers, -** depending on the contents of the WAL file. This does not change the -** allocated size of the page-mapping array - the page-mapping array merely -** contains unused entries. -** -** Even without using the hash table, the last frame for page P -** can be found by scanning the page-mapping sections of each index block -** starting with the last index block and moving toward the first, and -** within each index block, starting at the end and moving toward the -** beginning. The first entry that equals P corresponds to the frame -** holding the content for that page. -** -** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. -** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the -** hash table for each page number in the mapping section, so the hash -** table is never more than half full. The expected number of collisions -** prior to finding a match is 1. Each entry of the hash table is an -** 1-based index of an entry in the mapping section of the same -** index block. Let K be the 1-based index of the largest entry in -** the mapping section. (For index blocks other than the last, K will -** always be exactly HASHTABLE_NPAGE (4096) and for the last index block -** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table -** contain a value of 0. -** -** To look for page P in the hash table, first compute a hash iKey on -** P as follows: -** -** iKey = (P * 383) % HASHTABLE_NSLOT -** -** Then start scanning entries of the hash table, starting with iKey -** (wrapping around to the beginning when the end of the hash table is -** reached) until an unused hash slot is found. Let the first unused slot -** be at index iUnused. (iUnused might be less than iKey if there was -** wrap-around.) Because the hash table is never more than half full, -** the search is guaranteed to eventually hit an unused entry. Let -** iMax be the value between iKey and iUnused, closest to iUnused, -** where aHash[iMax]==P. If there is no iMax entry (if there exists -** no hash slot such that aHash[i]==p) then page P is not in the -** current index block. Otherwise the iMax-th mapping entry of the -** current index block corresponds to the last entry that references -** page P. -** -** A hash search begins with the last index block and moves toward the -** first index block, looking for entries corresponding to page P. On -** average, only two or three slots in each index block need to be -** examined in order to either find the last entry for page P, or to -** establish that no such entry exists in the block. Each index block -** holds over 4000 entries. So two or three index blocks are sufficient -** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10 -** comparisons (on average) suffice to either locate a frame in the -** WAL or to establish that the frame does not exist in the WAL. This -** is much faster than scanning the entire 10MB WAL. -** -** Note that entries are added in order of increasing K. Hence, one -** reader might be using some value K0 and a second reader that started -** at a later time (after additional transactions were added to the WAL -** and to the wal-index) might be using a different value K1, where K1>K0. -** Both readers can use the same hash table and mapping section to get -** the correct result. There may be entries in the hash table with -** K>K0 but to the first reader, those entries will appear to be unused -** slots in the hash table and so the first reader will get an answer as -** if no values greater than K0 had ever been inserted into the hash table -** in the first place - which is what reader one wants. Meanwhile, the -** second reader using K1 will see additional values that were inserted -** later, which is exactly what reader two wants. -** -** When a rollback occurs, the value of K is decreased. Hash table entries -** that correspond to frames greater than the new K value are removed -** from the hash table at this point. -*/ -#ifndef SQLITE_OMIT_WAL - -/* #include "wal.h" */ - -/* -** Trace output macros -*/ -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3WalTrace = 0; -# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X -#else -# define WALTRACE(X) -#endif - -/* -** The maximum (and only) versions of the wal and wal-index formats -** that may be interpreted by this version of SQLite. -** -** If a client begins recovering a WAL file and finds that (a) the checksum -** values in the wal-header are correct and (b) the version field is not -** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. -** -** Similarly, if a client successfully reads a wal-index header (i.e. the -** checksum test is successful) and finds that the version field is not -** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite -** returns SQLITE_CANTOPEN. -*/ -#define WAL_MAX_VERSION 3007000 -#define WALINDEX_MAX_VERSION 3007000 - -/* -** Indices of various locking bytes. WAL_NREADER is the number -** of available reader locks and should be at least 3. The default -** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. -*/ -#define WAL_WRITE_LOCK 0 -#define WAL_ALL_BUT_WRITE 1 -#define WAL_CKPT_LOCK 1 -#define WAL_RECOVER_LOCK 2 -#define WAL_READ_LOCK(I) (3+(I)) -#define WAL_NREADER (SQLITE_SHM_NLOCK-3) - - -/* Object declarations */ -typedef struct WalIndexHdr WalIndexHdr; -typedef struct WalIterator WalIterator; -typedef struct WalCkptInfo WalCkptInfo; - - -/* -** The following object holds a copy of the wal-index header content. -** -** The actual header in the wal-index consists of two copies of this -** object followed by one instance of the WalCkptInfo object. -** For all versions of SQLite through 3.10.0 and probably beyond, -** the locking bytes (WalCkptInfo.aLock) start at offset 120 and -** the total header size is 136 bytes. -** -** The szPage value can be any power of 2 between 512 and 32768, inclusive. -** Or it can be 1 to represent a 65536-byte page. The latter case was -** added in 3.7.1 when support for 64K pages was added. -*/ -struct WalIndexHdr { - u32 iVersion; /* Wal-index version */ - u32 unused; /* Unused (padding) field */ - u32 iChange; /* Counter incremented each transaction */ - u8 isInit; /* 1 when initialized */ - u8 bigEndCksum; /* True if checksums in WAL are big-endian */ - u16 szPage; /* Database page size in bytes. 1==64K */ - u32 mxFrame; /* Index of last valid frame in the WAL */ - u32 nPage; /* Size of database in pages */ - u32 aFrameCksum[2]; /* Checksum of last frame in log */ - u32 aSalt[2]; /* Two salt values copied from WAL header */ - u32 aCksum[2]; /* Checksum over all prior fields */ -}; - -/* -** A copy of the following object occurs in the wal-index immediately -** following the second copy of the WalIndexHdr. This object stores -** information used by checkpoint. -** -** nBackfill is the number of frames in the WAL that have been written -** back into the database. (We call the act of moving content from WAL to -** database "backfilling".) The nBackfill number is never greater than -** WalIndexHdr.mxFrame. nBackfill can only be increased by threads -** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). -** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from -** mxFrame back to zero when the WAL is reset. -** -** nBackfillAttempted is the largest value of nBackfill that a checkpoint -** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however -** the nBackfillAttempted is set before any backfilling is done and the -** nBackfill is only set after all backfilling completes. So if a checkpoint -** crashes, nBackfillAttempted might be larger than nBackfill. The -** WalIndexHdr.mxFrame must never be less than nBackfillAttempted. -** -** The aLock[] field is a set of bytes used for locking. These bytes should -** never be read or written. -** -** There is one entry in aReadMark[] for each reader lock. If a reader -** holds read-lock K, then the value in aReadMark[K] is no greater than -** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) -** for any aReadMark[] means that entry is unused. aReadMark[0] is -** a special case; its value is never used and it exists as a place-holder -** to avoid having to offset aReadMark[] indexs by one. Readers holding -** WAL_READ_LOCK(0) always ignore the entire WAL and read all content -** directly from the database. -** -** The value of aReadMark[K] may only be changed by a thread that -** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of -** aReadMark[K] cannot changed while there is a reader is using that mark -** since the reader will be holding a shared lock on WAL_READ_LOCK(K). -** -** The checkpointer may only transfer frames from WAL to database where -** the frame numbers are less than or equal to every aReadMark[] that is -** in use (that is, every aReadMark[j] for which there is a corresponding -** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the -** largest value and will increase an unused aReadMark[] to mxFrame if there -** is not already an aReadMark[] equal to mxFrame. The exception to the -** previous sentence is when nBackfill equals mxFrame (meaning that everything -** in the WAL has been backfilled into the database) then new readers -** will choose aReadMark[0] which has value 0 and hence such reader will -** get all their all content directly from the database file and ignore -** the WAL. -** -** Writers normally append new frames to the end of the WAL. However, -** if nBackfill equals mxFrame (meaning that all WAL content has been -** written back into the database) and if no readers are using the WAL -** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then -** the writer will first "reset" the WAL back to the beginning and start -** writing new content beginning at frame 1. -** -** We assume that 32-bit loads are atomic and so no locks are needed in -** order to read from any aReadMark[] entries. -*/ -struct WalCkptInfo { - u32 nBackfill; /* Number of WAL frames backfilled into DB */ - u32 aReadMark[WAL_NREADER]; /* Reader marks */ - u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */ - u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */ - u32 notUsed0; /* Available for future enhancements */ -}; -#define READMARK_NOT_USED 0xffffffff - - -/* A block of WALINDEX_LOCK_RESERVED bytes beginning at -** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems -** only support mandatory file-locks, we do not read or write data -** from the region of the file on which locks are applied. -*/ -#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock)) -#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo)) - -/* Size of header before each frame in wal */ -#define WAL_FRAME_HDRSIZE 24 - -/* Size of write ahead log header, including checksum. */ -/* #define WAL_HDRSIZE 24 */ -#define WAL_HDRSIZE 32 - -/* WAL magic value. Either this value, or the same value with the least -** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit -** big-endian format in the first 4 bytes of a WAL file. -** -** If the LSB is set, then the checksums for each frame within the WAL -** file are calculated by treating all data as an array of 32-bit -** big-endian words. Otherwise, they are calculated by interpreting -** all data as 32-bit little-endian words. -*/ -#define WAL_MAGIC 0x377f0682 - -/* -** Return the offset of frame iFrame in the write-ahead log file, -** assuming a database page size of szPage bytes. The offset returned -** is to the start of the write-ahead log frame-header. -*/ -#define walFrameOffset(iFrame, szPage) ( \ - WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ -) - -/* -** An open write-ahead log file is represented by an instance of the -** following object. -*/ -struct Wal { - sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ - sqlite3_file *pDbFd; /* File handle for the database file */ - sqlite3_file *pWalFd; /* File handle for WAL file */ - u32 iCallback; /* Value to pass to log callback (or 0) */ - i64 mxWalSize; /* Truncate WAL to this size upon reset */ - int nWiData; /* Size of array apWiData */ - int szFirstBlock; /* Size of first block written to WAL file */ - volatile u32 **apWiData; /* Pointer to wal-index content in memory */ - u32 szPage; /* Database page size */ - i16 readLock; /* Which read lock is being held. -1 for none */ - u8 syncFlags; /* Flags to use to sync header writes */ - u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ - u8 writeLock; /* True if in a write transaction */ - u8 ckptLock; /* True if holding a checkpoint lock */ - u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ - u8 truncateOnCommit; /* True to truncate WAL file on commit */ - u8 syncHeader; /* Fsync the WAL header if true */ - u8 padToSectorBoundary; /* Pad transactions out to the next sector */ - WalIndexHdr hdr; /* Wal-index header for current transaction */ - u32 minFrame; /* Ignore wal frames before this one */ - u32 iReCksum; /* On commit, recalculate checksums from here */ - const char *zWalName; /* Name of WAL file */ - u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ -#ifdef SQLITE_DEBUG - u8 lockError; /* True if a locking error has occurred */ -#endif -#ifdef SQLITE_ENABLE_SNAPSHOT - WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ -#endif -}; - -/* -** Candidate values for Wal.exclusiveMode. -*/ -#define WAL_NORMAL_MODE 0 -#define WAL_EXCLUSIVE_MODE 1 -#define WAL_HEAPMEMORY_MODE 2 - -/* -** Possible values for WAL.readOnly -*/ -#define WAL_RDWR 0 /* Normal read/write connection */ -#define WAL_RDONLY 1 /* The WAL file is readonly */ -#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ - -/* -** Each page of the wal-index mapping contains a hash-table made up of -** an array of HASHTABLE_NSLOT elements of the following type. -*/ -typedef u16 ht_slot; - -/* -** This structure is used to implement an iterator that loops through -** all frames in the WAL in database page order. Where two or more frames -** correspond to the same database page, the iterator visits only the -** frame most recently written to the WAL (in other words, the frame with -** the largest index). -** -** The internals of this structure are only accessed by: -** -** walIteratorInit() - Create a new iterator, -** walIteratorNext() - Step an iterator, -** walIteratorFree() - Free an iterator. -** -** This functionality is used by the checkpoint code (see walCheckpoint()). -*/ -struct WalIterator { - int iPrior; /* Last result returned from the iterator */ - int nSegment; /* Number of entries in aSegment[] */ - struct WalSegment { - int iNext; /* Next slot in aIndex[] not yet returned */ - ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ - u32 *aPgno; /* Array of page numbers. */ - int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ - int iZero; /* Frame number associated with aPgno[0] */ - } aSegment[1]; /* One for every 32KB page in the wal-index */ -}; - -/* -** Define the parameters of the hash tables in the wal-index file. There -** is a hash-table following every HASHTABLE_NPAGE page numbers in the -** wal-index. -** -** Changing any of these constants will alter the wal-index format and -** create incompatibilities. -*/ -#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */ -#define HASHTABLE_HASH_1 383 /* Should be prime */ -#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ - -/* -** The block of page numbers associated with the first hash-table in a -** wal-index is smaller than usual. This is so that there is a complete -** hash-table on each aligned 32KB page of the wal-index. -*/ -#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) - -/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */ -#define WALINDEX_PGSZ ( \ - sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ -) - -/* -** Obtain a pointer to the iPage'th page of the wal-index. The wal-index -** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are -** numbered from zero. -** -** If this call is successful, *ppPage is set to point to the wal-index -** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, -** then an SQLite error code is returned and *ppPage is set to 0. -*/ -static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){ - int rc = SQLITE_OK; - - /* Enlarge the pWal->apWiData[] array if required */ - if( pWal->nWiData<=iPage ){ - int nByte = sizeof(u32*)*(iPage+1); - volatile u32 **apNew; - apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte); - if( !apNew ){ - *ppPage = 0; - return SQLITE_NOMEM_BKPT; - } - memset((void*)&apNew[pWal->nWiData], 0, - sizeof(u32*)*(iPage+1-pWal->nWiData)); - pWal->apWiData = apNew; - pWal->nWiData = iPage+1; - } - - /* Request a pointer to the required page from the VFS */ - if( pWal->apWiData[iPage]==0 ){ - if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ - pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); - if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; - }else{ - rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, - pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] - ); - if( rc==SQLITE_READONLY ){ - pWal->readOnly |= WAL_SHM_RDONLY; - rc = SQLITE_OK; - } - } - } - - *ppPage = pWal->apWiData[iPage]; - assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); - return rc; -} - -/* -** Return a pointer to the WalCkptInfo structure in the wal-index. -*/ -static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ - assert( pWal->nWiData>0 && pWal->apWiData[0] ); - return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); -} - -/* -** Return a pointer to the WalIndexHdr structure in the wal-index. -*/ -static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ - assert( pWal->nWiData>0 && pWal->apWiData[0] ); - return (volatile WalIndexHdr*)pWal->apWiData[0]; -} - -/* -** The argument to this macro must be of type u32. On a little-endian -** architecture, it returns the u32 value that results from interpreting -** the 4 bytes as a big-endian value. On a big-endian architecture, it -** returns the value that would be produced by interpreting the 4 bytes -** of the input value as a little-endian integer. -*/ -#define BYTESWAP32(x) ( \ - (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ - + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ -) - -/* -** Generate or extend an 8 byte checksum based on the data in -** array aByte[] and the initial values of aIn[0] and aIn[1] (or -** initial values of 0 and 0 if aIn==NULL). -** -** The checksum is written back into aOut[] before returning. -** -** nByte must be a positive multiple of 8. -*/ -static void walChecksumBytes( - int nativeCksum, /* True for native byte-order, false for non-native */ - u8 *a, /* Content to be checksummed */ - int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */ - const u32 *aIn, /* Initial checksum value input */ - u32 *aOut /* OUT: Final checksum value output */ -){ - u32 s1, s2; - u32 *aData = (u32 *)a; - u32 *aEnd = (u32 *)&a[nByte]; - - if( aIn ){ - s1 = aIn[0]; - s2 = aIn[1]; - }else{ - s1 = s2 = 0; - } - - assert( nByte>=8 ); - assert( (nByte&0x00000007)==0 ); - - if( nativeCksum ){ - do { - s1 += *aData++ + s2; - s2 += *aData++ + s1; - }while( aDataexclusiveMode!=WAL_HEAPMEMORY_MODE ){ - sqlite3OsShmBarrier(pWal->pDbFd); - } -} - -/* -** Write the header information in pWal->hdr into the wal-index. -** -** The checksum on pWal->hdr is updated before it is written. -*/ -static void walIndexWriteHdr(Wal *pWal){ - volatile WalIndexHdr *aHdr = walIndexHdr(pWal); - const int nCksum = offsetof(WalIndexHdr, aCksum); - - assert( pWal->writeLock ); - pWal->hdr.isInit = 1; - pWal->hdr.iVersion = WALINDEX_MAX_VERSION; - walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); - memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); - walShmBarrier(pWal); - memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); -} - -/* -** This function encodes a single frame header and writes it to a buffer -** supplied by the caller. A frame-header is made up of a series of -** 4-byte big-endian integers, as follows: -** -** 0: Page number. -** 4: For commit records, the size of the database image in pages -** after the commit. For all other records, zero. -** 8: Salt-1 (copied from the wal-header) -** 12: Salt-2 (copied from the wal-header) -** 16: Checksum-1. -** 20: Checksum-2. -*/ -static void walEncodeFrame( - Wal *pWal, /* The write-ahead log */ - u32 iPage, /* Database page number for frame */ - u32 nTruncate, /* New db size (or 0 for non-commit frames) */ - u8 *aData, /* Pointer to page data */ - u8 *aFrame /* OUT: Write encoded frame here */ -){ - int nativeCksum; /* True for native byte-order checksums */ - u32 *aCksum = pWal->hdr.aFrameCksum; - assert( WAL_FRAME_HDRSIZE==24 ); - sqlite3Put4byte(&aFrame[0], iPage); - sqlite3Put4byte(&aFrame[4], nTruncate); - if( pWal->iReCksum==0 ){ - memcpy(&aFrame[8], pWal->hdr.aSalt, 8); - - nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); - walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); - walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); - - sqlite3Put4byte(&aFrame[16], aCksum[0]); - sqlite3Put4byte(&aFrame[20], aCksum[1]); - }else{ - memset(&aFrame[8], 0, 16); - } -} - -/* -** Check to see if the frame with header in aFrame[] and content -** in aData[] is valid. If it is a valid frame, fill *piPage and -** *pnTruncate and return true. Return if the frame is not valid. -*/ -static int walDecodeFrame( - Wal *pWal, /* The write-ahead log */ - u32 *piPage, /* OUT: Database page number for frame */ - u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */ - u8 *aData, /* Pointer to page data (for checksum) */ - u8 *aFrame /* Frame data */ -){ - int nativeCksum; /* True for native byte-order checksums */ - u32 *aCksum = pWal->hdr.aFrameCksum; - u32 pgno; /* Page number of the frame */ - assert( WAL_FRAME_HDRSIZE==24 ); - - /* A frame is only valid if the salt values in the frame-header - ** match the salt values in the wal-header. - */ - if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ - return 0; - } - - /* A frame is only valid if the page number is creater than zero. - */ - pgno = sqlite3Get4byte(&aFrame[0]); - if( pgno==0 ){ - return 0; - } - - /* A frame is only valid if a checksum of the WAL header, - ** all prior frams, the first 16 bytes of this frame-header, - ** and the frame-data matches the checksum in the last 8 - ** bytes of this frame-header. - */ - nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); - walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); - walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); - if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) - || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) - ){ - /* Checksum failed. */ - return 0; - } - - /* If we reach this point, the frame is valid. Return the page number - ** and the new database size. - */ - *piPage = pgno; - *pnTruncate = sqlite3Get4byte(&aFrame[4]); - return 1; -} - - -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -/* -** Names of locks. This routine is used to provide debugging output and is not -** a part of an ordinary build. -*/ -static const char *walLockName(int lockIdx){ - if( lockIdx==WAL_WRITE_LOCK ){ - return "WRITE-LOCK"; - }else if( lockIdx==WAL_CKPT_LOCK ){ - return "CKPT-LOCK"; - }else if( lockIdx==WAL_RECOVER_LOCK ){ - return "RECOVER-LOCK"; - }else{ - static char zName[15]; - sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", - lockIdx-WAL_READ_LOCK(0)); - return zName; - } -} -#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ - - -/* -** Set or release locks on the WAL. Locks are either shared or exclusive. -** A lock cannot be moved directly between shared and exclusive - it must go -** through the unlocked state first. -** -** In locking_mode=EXCLUSIVE, all of these routines become no-ops. -*/ -static int walLockShared(Wal *pWal, int lockIdx){ - int rc; - if( pWal->exclusiveMode ) return SQLITE_OK; - rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, - SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); - WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, - walLockName(lockIdx), rc ? "failed" : "ok")); - VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) - return rc; -} -static void walUnlockShared(Wal *pWal, int lockIdx){ - if( pWal->exclusiveMode ) return; - (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, - SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); - WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); -} -static int walLockExclusive(Wal *pWal, int lockIdx, int n){ - int rc; - if( pWal->exclusiveMode ) return SQLITE_OK; - rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, - SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); - WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, - walLockName(lockIdx), n, rc ? "failed" : "ok")); - VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) - return rc; -} -static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ - if( pWal->exclusiveMode ) return; - (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, - SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); - WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, - walLockName(lockIdx), n)); -} - -/* -** Compute a hash on a page number. The resulting hash value must land -** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances -** the hash to the next value in the event of a collision. -*/ -static int walHash(u32 iPage){ - assert( iPage>0 ); - assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 ); - return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1); -} -static int walNextHash(int iPriorHash){ - return (iPriorHash+1)&(HASHTABLE_NSLOT-1); -} - -/* -** Return pointers to the hash table and page number array stored on -** page iHash of the wal-index. The wal-index is broken into 32KB pages -** numbered starting from 0. -** -** Set output variable *paHash to point to the start of the hash table -** in the wal-index file. Set *piZero to one less than the frame -** number of the first frame indexed by this hash table. If a -** slot in the hash table is set to N, it refers to frame number -** (*piZero+N) in the log. -** -** Finally, set *paPgno so that *paPgno[1] is the page number of the -** first frame indexed by the hash table, frame (*piZero+1). -*/ -static int walHashGet( - Wal *pWal, /* WAL handle */ - int iHash, /* Find the iHash'th table */ - volatile ht_slot **paHash, /* OUT: Pointer to hash index */ - volatile u32 **paPgno, /* OUT: Pointer to page number array */ - u32 *piZero /* OUT: Frame associated with *paPgno[0] */ -){ - int rc; /* Return code */ - volatile u32 *aPgno; - - rc = walIndexPage(pWal, iHash, &aPgno); - assert( rc==SQLITE_OK || iHash>0 ); - - if( rc==SQLITE_OK ){ - u32 iZero; - volatile ht_slot *aHash; - - aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; - if( iHash==0 ){ - aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; - iZero = 0; - }else{ - iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; - } - - *paPgno = &aPgno[-1]; - *paHash = aHash; - *piZero = iZero; - } - return rc; -} - -/* -** Return the number of the wal-index page that contains the hash-table -** and page-number array that contain entries corresponding to WAL frame -** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages -** are numbered starting from 0. -*/ -static int walFramePage(u32 iFrame){ - int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE; - assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE) - && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE) - && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)) - && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE) - && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE)) - ); - return iHash; -} - -/* -** Return the page number associated with frame iFrame in this WAL. -*/ -static u32 walFramePgno(Wal *pWal, u32 iFrame){ - int iHash = walFramePage(iFrame); - if( iHash==0 ){ - return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; - } - return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE]; -} - -/* -** Remove entries from the hash table that point to WAL slots greater -** than pWal->hdr.mxFrame. -** -** This function is called whenever pWal->hdr.mxFrame is decreased due -** to a rollback or savepoint. -** -** At most only the hash table containing pWal->hdr.mxFrame needs to be -** updated. Any later hash tables will be automatically cleared when -** pWal->hdr.mxFrame advances to the point where those hash tables are -** actually needed. -*/ -static void walCleanupHash(Wal *pWal){ - volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ - volatile u32 *aPgno = 0; /* Page number array for hash table */ - u32 iZero = 0; /* frame == (aHash[x]+iZero) */ - int iLimit = 0; /* Zero values greater than this */ - int nByte; /* Number of bytes to zero in aPgno[] */ - int i; /* Used to iterate through aHash[] */ - - assert( pWal->writeLock ); - testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); - testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE ); - testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 ); - - if( pWal->hdr.mxFrame==0 ) return; - - /* Obtain pointers to the hash-table and page-number array containing - ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed - ** that the page said hash-table and array reside on is already mapped. - */ - assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); - assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); - walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); - - /* Zero all hash-table entries that correspond to frame numbers greater - ** than pWal->hdr.mxFrame. - */ - iLimit = pWal->hdr.mxFrame - iZero; - assert( iLimit>0 ); - for(i=0; iiLimit ){ - aHash[i] = 0; - } - } - - /* Zero the entries in the aPgno array that correspond to frames with - ** frame numbers greater than pWal->hdr.mxFrame. - */ - nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); - memset((void *)&aPgno[iLimit+1], 0, nByte); - -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT - /* Verify that the every entry in the mapping region is still reachable - ** via the hash table even after the cleanup. - */ - if( iLimit ){ - int j; /* Loop counter */ - int iKey; /* Hash key */ - for(j=1; j<=iLimit; j++){ - for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){ - if( aHash[iKey]==j ) break; - } - assert( aHash[iKey]==j ); - } - } -#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ -} - - -/* -** Set an entry in the wal-index that will map database page number -** pPage into WAL frame iFrame. -*/ -static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ - int rc; /* Return code */ - u32 iZero = 0; /* One less than frame number of aPgno[1] */ - volatile u32 *aPgno = 0; /* Page number array */ - volatile ht_slot *aHash = 0; /* Hash table */ - - rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); - - /* Assuming the wal-index file was successfully mapped, populate the - ** page number array and hash table entry. - */ - if( rc==SQLITE_OK ){ - int iKey; /* Hash table key */ - int idx; /* Value to write to hash-table slot */ - int nCollide; /* Number of hash collisions */ - - idx = iFrame - iZero; - assert( idx <= HASHTABLE_NSLOT/2 + 1 ); - - /* If this is the first entry to be added to this hash-table, zero the - ** entire hash table and aPgno[] array before proceeding. - */ - if( idx==1 ){ - int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); - memset((void*)&aPgno[1], 0, nByte); - } - - /* If the entry in aPgno[] is already set, then the previous writer - ** must have exited unexpectedly in the middle of a transaction (after - ** writing one or more dirty pages to the WAL to free up memory). - ** Remove the remnants of that writers uncommitted transaction from - ** the hash-table before writing any new entries. - */ - if( aPgno[idx] ){ - walCleanupHash(pWal); - assert( !aPgno[idx] ); - } - - /* Write the aPgno[] array entry and the hash-table slot. */ - nCollide = idx; - for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ - if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; - } - aPgno[idx] = iPage; - aHash[iKey] = (ht_slot)idx; - -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT - /* Verify that the number of entries in the hash table exactly equals - ** the number of entries in the mapping region. - */ - { - int i; /* Loop counter */ - int nEntry = 0; /* Number of entries in the hash table */ - for(i=0; ickptLock==1 || pWal->ckptLock==0 ); - assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); - assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); - assert( pWal->writeLock ); - iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; - nLock = SQLITE_SHM_NLOCK - iLock; - rc = walLockExclusive(pWal, iLock, nLock); - if( rc ){ - return rc; - } - WALTRACE(("WAL%p: recovery begin...\n", pWal)); - - memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); - - rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); - if( rc!=SQLITE_OK ){ - goto recovery_error; - } - - if( nSize>WAL_HDRSIZE ){ - u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ - u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ - int szFrame; /* Number of bytes in buffer aFrame[] */ - u8 *aData; /* Pointer to data part of aFrame buffer */ - int iFrame; /* Index of last frame read */ - i64 iOffset; /* Next offset to read from log file */ - int szPage; /* Page size according to the log */ - u32 magic; /* Magic value read from WAL header */ - u32 version; /* Magic value read from WAL header */ - int isValid; /* True if this frame is valid */ - - /* Read in the WAL header. */ - rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); - if( rc!=SQLITE_OK ){ - goto recovery_error; - } - - /* If the database page size is not a power of two, or is greater than - ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid - ** data. Similarly, if the 'magic' value is invalid, ignore the whole - ** WAL file. - */ - magic = sqlite3Get4byte(&aBuf[0]); - szPage = sqlite3Get4byte(&aBuf[8]); - if( (magic&0xFFFFFFFE)!=WAL_MAGIC - || szPage&(szPage-1) - || szPage>SQLITE_MAX_PAGE_SIZE - || szPage<512 - ){ - goto finished; - } - pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); - pWal->szPage = szPage; - pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); - memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); - - /* Verify that the WAL header checksum is correct */ - walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, - aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum - ); - if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) - || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) - ){ - goto finished; - } - - /* Verify that the version number on the WAL format is one that - ** are able to understand */ - version = sqlite3Get4byte(&aBuf[4]); - if( version!=WAL_MAX_VERSION ){ - rc = SQLITE_CANTOPEN_BKPT; - goto finished; - } - - /* Malloc a buffer to read frames into. */ - szFrame = szPage + WAL_FRAME_HDRSIZE; - aFrame = (u8 *)sqlite3_malloc64(szFrame); - if( !aFrame ){ - rc = SQLITE_NOMEM_BKPT; - goto recovery_error; - } - aData = &aFrame[WAL_FRAME_HDRSIZE]; - - /* Read all frames from the log file. */ - iFrame = 0; - for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){ - u32 pgno; /* Database page number for frame */ - u32 nTruncate; /* dbsize field from frame header */ - - /* Read and decode the next log frame. */ - iFrame++; - rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); - if( rc!=SQLITE_OK ) break; - isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); - if( !isValid ) break; - rc = walIndexAppend(pWal, iFrame, pgno); - if( rc!=SQLITE_OK ) break; - - /* If nTruncate is non-zero, this is a commit record. */ - if( nTruncate ){ - pWal->hdr.mxFrame = iFrame; - pWal->hdr.nPage = nTruncate; - pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); - testcase( szPage<=32768 ); - testcase( szPage>=65536 ); - aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; - aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; - } - } - - sqlite3_free(aFrame); - } - -finished: - if( rc==SQLITE_OK ){ - volatile WalCkptInfo *pInfo; - int i; - pWal->hdr.aFrameCksum[0] = aFrameCksum[0]; - pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; - walIndexWriteHdr(pWal); - - /* Reset the checkpoint-header. This is safe because this thread is - ** currently holding locks that exclude all other readers, writers and - ** checkpointers. - */ - pInfo = walCkptInfo(pWal); - pInfo->nBackfill = 0; - pInfo->nBackfillAttempted = pWal->hdr.mxFrame; - pInfo->aReadMark[0] = 0; - for(i=1; iaReadMark[i] = READMARK_NOT_USED; - if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; - - /* If more than one frame was recovered from the log file, report an - ** event via sqlite3_log(). This is to help with identifying performance - ** problems caused by applications routinely shutting down without - ** checkpointing the log file. - */ - if( pWal->hdr.nPage ){ - sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, - "recovered %d frames from WAL file %s", - pWal->hdr.mxFrame, pWal->zWalName - ); - } - } - -recovery_error: - WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); - walUnlockExclusive(pWal, iLock, nLock); - return rc; -} - -/* -** Close an open wal-index. -*/ -static void walIndexClose(Wal *pWal, int isDelete){ - if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ - int i; - for(i=0; inWiData; i++){ - sqlite3_free((void *)pWal->apWiData[i]); - pWal->apWiData[i] = 0; - } - }else{ - sqlite3OsShmUnmap(pWal->pDbFd, isDelete); - } -} - -/* -** Open a connection to the WAL file zWalName. The database file must -** already be opened on connection pDbFd. The buffer that zWalName points -** to must remain valid for the lifetime of the returned Wal* handle. -** -** A SHARED lock should be held on the database file when this function -** is called. The purpose of this SHARED lock is to prevent any other -** client from unlinking the WAL or wal-index file. If another process -** were to do this just after this client opened one of these files, the -** system would be badly broken. -** -** If the log file is successfully opened, SQLITE_OK is returned and -** *ppWal is set to point to a new WAL handle. If an error occurs, -** an SQLite error code is returned and *ppWal is left unmodified. -*/ -SQLITE_PRIVATE int sqlite3WalOpen( - sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ - sqlite3_file *pDbFd, /* The open database file */ - const char *zWalName, /* Name of the WAL file */ - int bNoShm, /* True to run in heap-memory mode */ - i64 mxWalSize, /* Truncate WAL to this size on reset */ - Wal **ppWal /* OUT: Allocated Wal handle */ -){ - int rc; /* Return Code */ - Wal *pRet; /* Object to allocate and return */ - int flags; /* Flags passed to OsOpen() */ - - assert( zWalName && zWalName[0] ); - assert( pDbFd ); - - /* In the amalgamation, the os_unix.c and os_win.c source files come before - ** this source file. Verify that the #defines of the locking byte offsets - ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. - ** For that matter, if the lock offset ever changes from its initial design - ** value of 120, we need to know that so there is an assert() to check it. - */ - assert( 120==WALINDEX_LOCK_OFFSET ); - assert( 136==WALINDEX_HDR_SIZE ); -#ifdef WIN_SHM_BASE - assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); -#endif -#ifdef UNIX_SHM_BASE - assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); -#endif - - - /* Allocate an instance of struct Wal to return. */ - *ppWal = 0; - pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); - if( !pRet ){ - return SQLITE_NOMEM_BKPT; - } - - pRet->pVfs = pVfs; - pRet->pWalFd = (sqlite3_file *)&pRet[1]; - pRet->pDbFd = pDbFd; - pRet->readLock = -1; - pRet->mxWalSize = mxWalSize; - pRet->zWalName = zWalName; - pRet->syncHeader = 1; - pRet->padToSectorBoundary = 1; - pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); - - /* Open file handle on the write-ahead log file. */ - flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); - rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); - if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ - pRet->readOnly = WAL_RDONLY; - } - - if( rc!=SQLITE_OK ){ - walIndexClose(pRet, 0); - sqlite3OsClose(pRet->pWalFd); - sqlite3_free(pRet); - }else{ - int iDC = sqlite3OsDeviceCharacteristics(pDbFd); - if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } - if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ - pRet->padToSectorBoundary = 0; - } - *ppWal = pRet; - WALTRACE(("WAL%d: opened\n", pRet)); - } - return rc; -} - -/* -** Change the size to which the WAL file is trucated on each reset. -*/ -SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ - if( pWal ) pWal->mxWalSize = iLimit; -} - -/* -** Find the smallest page number out of all pages held in the WAL that -** has not been returned by any prior invocation of this method on the -** same WalIterator object. Write into *piFrame the frame index where -** that page was last written into the WAL. Write into *piPage the page -** number. -** -** Return 0 on success. If there are no pages in the WAL with a page -** number larger than *piPage, then return 1. -*/ -static int walIteratorNext( - WalIterator *p, /* Iterator */ - u32 *piPage, /* OUT: The page number of the next page */ - u32 *piFrame /* OUT: Wal frame index of next page */ -){ - u32 iMin; /* Result pgno must be greater than iMin */ - u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ - int i; /* For looping through segments */ - - iMin = p->iPrior; - assert( iMin<0xffffffff ); - for(i=p->nSegment-1; i>=0; i--){ - struct WalSegment *pSegment = &p->aSegment[i]; - while( pSegment->iNextnEntry ){ - u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; - if( iPg>iMin ){ - if( iPgiZero + pSegment->aIndex[pSegment->iNext]; - } - break; - } - pSegment->iNext++; - } - } - - *piPage = p->iPrior = iRet; - return (iRet==0xFFFFFFFF); -} - -/* -** This function merges two sorted lists into a single sorted list. -** -** aLeft[] and aRight[] are arrays of indices. The sort key is -** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following -** is guaranteed for all J0 && nRight>0 ); - while( iRight=nRight || aContent[aLeft[iLeft]]=nLeft || aContent[aLeft[iLeft]]>dbpage ); - assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); - } - - *paRight = aLeft; - *pnRight = iOut; - memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); -} - -/* -** Sort the elements in list aList using aContent[] as the sort key. -** Remove elements with duplicate keys, preferring to keep the -** larger aList[] values. -** -** The aList[] entries are indices into aContent[]. The values in -** aList[] are to be sorted so that for all J0 ); - assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); - - for(iList=0; iListaList && p->nList<=(1<aList==&aList[iList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); - } - aSub[iSub].aList = aMerge; - aSub[iSub].nList = nMerge; - } - - for(iSub++; iSubnList<=(1<aList==&aList[nList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); - } - } - assert( aMerge==aList ); - *pnList = nMerge; - -#ifdef SQLITE_DEBUG - { - int i; - for(i=1; i<*pnList; i++){ - assert( aContent[aList[i]] > aContent[aList[i-1]] ); - } - } -#endif -} - -/* -** Free an iterator allocated by walIteratorInit(). -*/ -static void walIteratorFree(WalIterator *p){ - sqlite3_free(p); -} - -/* -** Construct a WalInterator object that can be used to loop over all -** pages in the WAL in ascending order. The caller must hold the checkpoint -** lock. -** -** On success, make *pp point to the newly allocated WalInterator object -** return SQLITE_OK. Otherwise, return an error code. If this routine -** returns an error, the value of *pp is undefined. -** -** The calling routine should invoke walIteratorFree() to destroy the -** WalIterator object when it has finished with it. -*/ -static int walIteratorInit(Wal *pWal, WalIterator **pp){ - WalIterator *p; /* Return value */ - int nSegment; /* Number of segments to merge */ - u32 iLast; /* Last frame in log */ - int nByte; /* Number of bytes to allocate */ - int i; /* Iterator variable */ - ht_slot *aTmp; /* Temp space used by merge-sort */ - int rc = SQLITE_OK; /* Return Code */ - - /* This routine only runs while holding the checkpoint lock. And - ** it only runs if there is actually content in the log (mxFrame>0). - */ - assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); - iLast = pWal->hdr.mxFrame; - - /* Allocate space for the WalIterator object. */ - nSegment = walFramePage(iLast) + 1; - nByte = sizeof(WalIterator) - + (nSegment-1)*sizeof(struct WalSegment) - + iLast*sizeof(ht_slot); - p = (WalIterator *)sqlite3_malloc64(nByte); - if( !p ){ - return SQLITE_NOMEM_BKPT; - } - memset(p, 0, nByte); - p->nSegment = nSegment; - - /* Allocate temporary space used by the merge-sort routine. This block - ** of memory will be freed before this function returns. - */ - aTmp = (ht_slot *)sqlite3_malloc64( - sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) - ); - if( !aTmp ){ - rc = SQLITE_NOMEM_BKPT; - } - - for(i=0; rc==SQLITE_OK && iaSegment[p->nSegment])[iZero]; - iZero++; - - for(j=0; jaSegment[i].iZero = iZero; - p->aSegment[i].nEntry = nEntry; - p->aSegment[i].aIndex = aIndex; - p->aSegment[i].aPgno = (u32 *)aPgno; - } - } - sqlite3_free(aTmp); - - if( rc!=SQLITE_OK ){ - walIteratorFree(p); - } - *pp = p; - return rc; -} - -/* -** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and -** n. If the attempt fails and parameter xBusy is not NULL, then it is a -** busy-handler function. Invoke it and retry the lock until either the -** lock is successfully obtained or the busy-handler returns 0. -*/ -static int walBusyLock( - Wal *pWal, /* WAL connection */ - int (*xBusy)(void*), /* Function to call when busy */ - void *pBusyArg, /* Context argument for xBusyHandler */ - int lockIdx, /* Offset of first byte to lock */ - int n /* Number of bytes to lock */ -){ - int rc; - do { - rc = walLockExclusive(pWal, lockIdx, n); - }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); - return rc; -} - -/* -** The cache of the wal-index header must be valid to call this function. -** Return the page-size in bytes used by the database. -*/ -static int walPagesize(Wal *pWal){ - return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); -} - -/* -** The following is guaranteed when this function is called: -** -** a) the WRITER lock is held, -** b) the entire log file has been checkpointed, and -** c) any existing readers are reading exclusively from the database -** file - there are no readers that may attempt to read a frame from -** the log file. -** -** This function updates the shared-memory structures so that the next -** client to write to the database (which may be this one) does so by -** writing frames into the start of the log file. -** -** The value of parameter salt1 is used as the aSalt[1] value in the -** new wal-index header. It should be passed a pseudo-random value (i.e. -** one obtained from sqlite3_randomness()). -*/ -static void walRestartHdr(Wal *pWal, u32 salt1){ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - int i; /* Loop counter */ - u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ - pWal->nCkpt++; - pWal->hdr.mxFrame = 0; - sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); - memcpy(&pWal->hdr.aSalt[1], &salt1, 4); - walIndexWriteHdr(pWal); - pInfo->nBackfill = 0; - pInfo->nBackfillAttempted = 0; - pInfo->aReadMark[1] = 0; - for(i=2; iaReadMark[i] = READMARK_NOT_USED; - assert( pInfo->aReadMark[0]==0 ); -} - -/* -** Copy as much content as we can from the WAL back into the database file -** in response to an sqlite3_wal_checkpoint() request or the equivalent. -** -** The amount of information copies from WAL to database might be limited -** by active readers. This routine will never overwrite a database page -** that a concurrent reader might be using. -** -** All I/O barrier operations (a.k.a fsyncs) occur in this routine when -** SQLite is in WAL-mode in synchronous=NORMAL. That means that if -** checkpoints are always run by a background thread or background -** process, foreground threads will never block on a lengthy fsync call. -** -** Fsync is called on the WAL before writing content out of the WAL and -** into the database. This ensures that if the new content is persistent -** in the WAL and can be recovered following a power-loss or hard reset. -** -** Fsync is also called on the database file if (and only if) the entire -** WAL content is copied into the database file. This second fsync makes -** it safe to delete the WAL since the new content will persist in the -** database file. -** -** This routine uses and updates the nBackfill field of the wal-index header. -** This is the only routine that will increase the value of nBackfill. -** (A WAL reset or recovery will revert nBackfill to zero, but not increase -** its value.) -** -** The caller must be holding sufficient locks to ensure that no other -** checkpoint is running (in any other thread or process) at the same -** time. -*/ -static int walCheckpoint( - Wal *pWal, /* Wal connection */ - int eMode, /* One of PASSIVE, FULL or RESTART */ - int (*xBusy)(void*), /* Function to call when busy */ - void *pBusyArg, /* Context argument for xBusyHandler */ - int sync_flags, /* Flags for OsSync() (or 0) */ - u8 *zBuf /* Temporary buffer to use */ -){ - int rc = SQLITE_OK; /* Return code */ - int szPage; /* Database page-size */ - WalIterator *pIter = 0; /* Wal iterator context */ - u32 iDbpage = 0; /* Next database page to write */ - u32 iFrame = 0; /* Wal frame containing data for iDbpage */ - u32 mxSafeFrame; /* Max frame that can be backfilled */ - u32 mxPage; /* Max database page to write */ - int i; /* Loop counter */ - volatile WalCkptInfo *pInfo; /* The checkpoint status information */ - - szPage = walPagesize(pWal); - testcase( szPage<=32768 ); - testcase( szPage>=65536 ); - pInfo = walCkptInfo(pWal); - if( pInfo->nBackfillhdr.mxFrame ){ - - /* Allocate the iterator */ - rc = walIteratorInit(pWal, &pIter); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pIter ); - - /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked - ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ - assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); - - /* Compute in mxSafeFrame the index of the last frame of the WAL that is - ** safe to write into the database. Frames beyond mxSafeFrame might - ** overwrite database pages that are in use by active readers and thus - ** cannot be backfilled from the WAL. - */ - mxSafeFrame = pWal->hdr.mxFrame; - mxPage = pWal->hdr.nPage; - for(i=1; iaReadMark[i]; - if( mxSafeFrame>y ){ - assert( y<=pWal->hdr.mxFrame ); - rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); - if( rc==SQLITE_OK ){ - pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED); - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - }else if( rc==SQLITE_BUSY ){ - mxSafeFrame = y; - xBusy = 0; - }else{ - goto walcheckpoint_out; - } - } - } - - if( pInfo->nBackfillnBackfill; - - pInfo->nBackfillAttempted = mxSafeFrame; - - /* Sync the WAL to disk */ - if( sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags); - } - - /* If the database may grow as a result of this checkpoint, hint - ** about the eventual size of the db file to the VFS layer. - */ - if( rc==SQLITE_OK ){ - i64 nReq = ((i64)mxPage * szPage); - rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); - if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); - } - } - - - /* Iterate through the contents of the WAL, copying data to the db file */ - while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ - i64 iOffset; - assert( walFramePgno(pWal, iFrame)==iDbpage ); - if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ - continue; - } - iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ - rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); - if( rc!=SQLITE_OK ) break; - iOffset = (iDbpage-1)*(i64)szPage; - testcase( IS_BIG_INT(iOffset) ); - rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); - if( rc!=SQLITE_OK ) break; - } - - /* If work was actually accomplished... */ - if( rc==SQLITE_OK ){ - if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ - i64 szDb = pWal->hdr.nPage*(i64)szPage; - testcase( IS_BIG_INT(szDb) ); - rc = sqlite3OsTruncate(pWal->pDbFd, szDb); - if( rc==SQLITE_OK && sync_flags ){ - rc = sqlite3OsSync(pWal->pDbFd, sync_flags); - } - } - if( rc==SQLITE_OK ){ - pInfo->nBackfill = mxSafeFrame; - } - } - - /* Release the reader lock held while backfilling */ - walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); - } - - if( rc==SQLITE_BUSY ){ - /* Reset the return code so as not to report a checkpoint failure - ** just because there are active readers. */ - rc = SQLITE_OK; - } - } - - /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the - ** entire wal file has been copied into the database file, then block - ** until all readers have finished using the wal file. This ensures that - ** the next process to write to the database restarts the wal file. - */ - if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ - assert( pWal->writeLock ); - if( pInfo->nBackfillhdr.mxFrame ){ - rc = SQLITE_BUSY; - }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ - u32 salt1; - sqlite3_randomness(4, &salt1); - assert( pInfo->nBackfill==pWal->hdr.mxFrame ); - rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); - if( rc==SQLITE_OK ){ - if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ - /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as - ** SQLITE_CHECKPOINT_RESTART with the addition that it also - ** truncates the log file to zero bytes just prior to a - ** successful return. - ** - ** In theory, it might be safe to do this without updating the - ** wal-index header in shared memory, as all subsequent reader or - ** writer clients should see that the entire log file has been - ** checkpointed and behave accordingly. This seems unsafe though, - ** as it would leave the system in a state where the contents of - ** the wal-index header do not match the contents of the - ** file-system. To avoid this, update the wal-index header to - ** indicate that the log file contains zero valid frames. */ - walRestartHdr(pWal, salt1); - rc = sqlite3OsTruncate(pWal->pWalFd, 0); - } - walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); - } - } - } - - walcheckpoint_out: - walIteratorFree(pIter); - return rc; -} - -/* -** If the WAL file is currently larger than nMax bytes in size, truncate -** it to exactly nMax bytes. If an error occurs while doing so, ignore it. -*/ -static void walLimitSize(Wal *pWal, i64 nMax){ - i64 sz; - int rx; - sqlite3BeginBenignMalloc(); - rx = sqlite3OsFileSize(pWal->pWalFd, &sz); - if( rx==SQLITE_OK && (sz > nMax ) ){ - rx = sqlite3OsTruncate(pWal->pWalFd, nMax); - } - sqlite3EndBenignMalloc(); - if( rx ){ - sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); - } -} - -/* -** Close a connection to a log file. -*/ -SQLITE_PRIVATE int sqlite3WalClose( - Wal *pWal, /* Wal to close */ - int sync_flags, /* Flags to pass to OsSync() (or 0) */ - int nBuf, - u8 *zBuf /* Buffer of at least nBuf bytes */ -){ - int rc = SQLITE_OK; - if( pWal ){ - int isDelete = 0; /* True to unlink wal and wal-index files */ - - /* If an EXCLUSIVE lock can be obtained on the database file (using the - ** ordinary, rollback-mode locking methods, this guarantees that the - ** connection associated with this log file is the only connection to - ** the database. In this case checkpoint the database and unlink both - ** the wal and wal-index files. - ** - ** The EXCLUSIVE lock is not released before returning. - */ - rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE); - if( rc==SQLITE_OK ){ - if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ - pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; - } - rc = sqlite3WalCheckpoint( - pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 - ); - if( rc==SQLITE_OK ){ - int bPersist = -1; - sqlite3OsFileControlHint( - pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist - ); - if( bPersist!=1 ){ - /* Try to delete the WAL file if the checkpoint completed and - ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal - ** mode (!bPersist) */ - isDelete = 1; - }else if( pWal->mxWalSize>=0 ){ - /* Try to truncate the WAL file to zero bytes if the checkpoint - ** completed and fsynced (rc==SQLITE_OK) and we are in persistent - ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a - ** non-negative value (pWal->mxWalSize>=0). Note that we truncate - ** to zero bytes as truncating to the journal_size_limit might - ** leave a corrupt WAL file on disk. */ - walLimitSize(pWal, 0); - } - } - } - - walIndexClose(pWal, isDelete); - sqlite3OsClose(pWal->pWalFd); - if( isDelete ){ - sqlite3BeginBenignMalloc(); - sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); - sqlite3EndBenignMalloc(); - } - WALTRACE(("WAL%p: closed\n", pWal)); - sqlite3_free((void *)pWal->apWiData); - sqlite3_free(pWal); - } - return rc; -} - -/* -** Try to read the wal-index header. Return 0 on success and 1 if -** there is a problem. -** -** The wal-index is in shared memory. Another thread or process might -** be writing the header at the same time this procedure is trying to -** read it, which might result in inconsistency. A dirty read is detected -** by verifying that both copies of the header are the same and also by -** a checksum on the header. -** -** If and only if the read is consistent and the header is different from -** pWal->hdr, then pWal->hdr is updated to the content of the new header -** and *pChanged is set to 1. -** -** If the checksum cannot be verified return non-zero. If the header -** is read successfully and the checksum verified, return zero. -*/ -static int walIndexTryHdr(Wal *pWal, int *pChanged){ - u32 aCksum[2]; /* Checksum on the header content */ - WalIndexHdr h1, h2; /* Two copies of the header content */ - WalIndexHdr volatile *aHdr; /* Header in shared memory */ - - /* The first page of the wal-index must be mapped at this point. */ - assert( pWal->nWiData>0 && pWal->apWiData[0] ); - - /* Read the header. This might happen concurrently with a write to the - ** same area of shared memory on a different CPU in a SMP, - ** meaning it is possible that an inconsistent snapshot is read - ** from the file. If this happens, return non-zero. - ** - ** There are two copies of the header at the beginning of the wal-index. - ** When reading, read [0] first then [1]. Writes are in the reverse order. - ** Memory barriers are used to prevent the compiler or the hardware from - ** reordering the reads and writes. - */ - aHdr = walIndexHdr(pWal); - memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); - walShmBarrier(pWal); - memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); - - if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ - return 1; /* Dirty read */ - } - if( h1.isInit==0 ){ - return 1; /* Malformed header - probably all zeros */ - } - walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); - if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ - return 1; /* Checksum does not match */ - } - - if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ - *pChanged = 1; - memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); - pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); - testcase( pWal->szPage<=32768 ); - testcase( pWal->szPage>=65536 ); - } - - /* The header was successfully read. Return zero. */ - return 0; -} - -/* -** Read the wal-index header from the wal-index and into pWal->hdr. -** If the wal-header appears to be corrupt, try to reconstruct the -** wal-index from the WAL before returning. -** -** Set *pChanged to 1 if the wal-index header value in pWal->hdr is -** changed by this operation. If pWal->hdr is unchanged, set *pChanged -** to 0. -** -** If the wal-index header is successfully read, return SQLITE_OK. -** Otherwise an SQLite error code. -*/ -static int walIndexReadHdr(Wal *pWal, int *pChanged){ - int rc; /* Return code */ - int badHdr; /* True if a header read failed */ - volatile u32 *page0; /* Chunk of wal-index containing header */ - - /* Ensure that page 0 of the wal-index (the page that contains the - ** wal-index header) is mapped. Return early if an error occurs here. - */ - assert( pChanged ); - rc = walIndexPage(pWal, 0, &page0); - if( rc!=SQLITE_OK ){ - return rc; - }; - assert( page0 || pWal->writeLock==0 ); - - /* If the first page of the wal-index has been mapped, try to read the - ** wal-index header immediately, without holding any lock. This usually - ** works, but may fail if the wal-index header is corrupt or currently - ** being modified by another thread or process. - */ - badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); - - /* If the first attempt failed, it might have been due to a race - ** with a writer. So get a WRITE lock and try again. - */ - assert( badHdr==0 || pWal->writeLock==0 ); - if( badHdr ){ - if( pWal->readOnly & WAL_SHM_RDONLY ){ - if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ - walUnlockShared(pWal, WAL_WRITE_LOCK); - rc = SQLITE_READONLY_RECOVERY; - } - }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ - pWal->writeLock = 1; - if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ - badHdr = walIndexTryHdr(pWal, pChanged); - if( badHdr ){ - /* If the wal-index header is still malformed even while holding - ** a WRITE lock, it can only mean that the header is corrupted and - ** needs to be reconstructed. So run recovery to do exactly that. - */ - rc = walIndexRecover(pWal); - *pChanged = 1; - } - } - pWal->writeLock = 0; - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); - } - } - - /* If the header is read successfully, check the version number to make - ** sure the wal-index was not constructed with some future format that - ** this version of SQLite cannot understand. - */ - if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ - rc = SQLITE_CANTOPEN_BKPT; - } - - return rc; -} - -/* -** This is the value that walTryBeginRead returns when it needs to -** be retried. -*/ -#define WAL_RETRY (-1) - -/* -** Attempt to start a read transaction. This might fail due to a race or -** other transient condition. When that happens, it returns WAL_RETRY to -** indicate to the caller that it is safe to retry immediately. -** -** On success return SQLITE_OK. On a permanent failure (such an -** I/O error or an SQLITE_BUSY because another process is running -** recovery) return a positive error code. -** -** The useWal parameter is true to force the use of the WAL and disable -** the case where the WAL is bypassed because it has been completely -** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() -** to make a copy of the wal-index header into pWal->hdr. If the -** wal-index header has changed, *pChanged is set to 1 (as an indication -** to the caller that the local paget cache is obsolete and needs to be -** flushed.) When useWal==1, the wal-index header is assumed to already -** be loaded and the pChanged parameter is unused. -** -** The caller must set the cnt parameter to the number of prior calls to -** this routine during the current read attempt that returned WAL_RETRY. -** This routine will start taking more aggressive measures to clear the -** race conditions after multiple WAL_RETRY returns, and after an excessive -** number of errors will ultimately return SQLITE_PROTOCOL. The -** SQLITE_PROTOCOL return indicates that some other process has gone rogue -** and is not honoring the locking protocol. There is a vanishingly small -** chance that SQLITE_PROTOCOL could be returned because of a run of really -** bad luck when there is lots of contention for the wal-index, but that -** possibility is so small that it can be safely neglected, we believe. -** -** On success, this routine obtains a read lock on -** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is -** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) -** that means the Wal does not hold any read lock. The reader must not -** access any database page that is modified by a WAL frame up to and -** including frame number aReadMark[pWal->readLock]. The reader will -** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0 -** Or if pWal->readLock==0, then the reader will ignore the WAL -** completely and get all content directly from the database file. -** If the useWal parameter is 1 then the WAL will never be ignored and -** this routine will always set pWal->readLock>0 on success. -** When the read transaction is completed, the caller must release the -** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1. -** -** This routine uses the nBackfill and aReadMark[] fields of the header -** to select a particular WAL_READ_LOCK() that strives to let the -** checkpoint process do as much work as possible. This routine might -** update values of the aReadMark[] array in the header, but if it does -** so it takes care to hold an exclusive lock on the corresponding -** WAL_READ_LOCK() while changing values. -*/ -static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ - volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ - u32 mxReadMark; /* Largest aReadMark[] value */ - int mxI; /* Index of largest aReadMark[] value */ - int i; /* Loop counter */ - int rc = SQLITE_OK; /* Return code */ - u32 mxFrame; /* Wal frame to lock to */ - - assert( pWal->readLock<0 ); /* Not currently locked */ - - /* Take steps to avoid spinning forever if there is a protocol error. - ** - ** Circumstances that cause a RETRY should only last for the briefest - ** instances of time. No I/O or other system calls are done while the - ** locks are held, so the locks should not be held for very long. But - ** if we are unlucky, another process that is holding a lock might get - ** paged out or take a page-fault that is time-consuming to resolve, - ** during the few nanoseconds that it is holding the lock. In that case, - ** it might take longer than normal for the lock to free. - ** - ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few - ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this - ** is more of a scheduler yield than an actual delay. But on the 10th - ** an subsequent retries, the delays start becoming longer and longer, - ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. - ** The total delay time before giving up is less than 10 seconds. - */ - if( cnt>5 ){ - int nDelay = 1; /* Pause time in microseconds */ - if( cnt>100 ){ - VVA_ONLY( pWal->lockError = 1; ) - return SQLITE_PROTOCOL; - } - if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; - sqlite3OsSleep(pWal->pVfs, nDelay); - } - - if( !useWal ){ - rc = walIndexReadHdr(pWal, pChanged); - if( rc==SQLITE_BUSY ){ - /* If there is not a recovery running in another thread or process - ** then convert BUSY errors to WAL_RETRY. If recovery is known to - ** be running, convert BUSY to BUSY_RECOVERY. There is a race here - ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY - ** would be technically correct. But the race is benign since with - ** WAL_RETRY this routine will be called again and will probably be - ** right on the second iteration. - */ - if( pWal->apWiData[0]==0 ){ - /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. - ** We assume this is a transient condition, so return WAL_RETRY. The - ** xShmMap() implementation used by the default unix and win32 VFS - ** modules may return SQLITE_BUSY due to a race condition in the - ** code that determines whether or not the shared-memory region - ** must be zeroed before the requested page is returned. - */ - rc = WAL_RETRY; - }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){ - walUnlockShared(pWal, WAL_RECOVER_LOCK); - rc = WAL_RETRY; - }else if( rc==SQLITE_BUSY ){ - rc = SQLITE_BUSY_RECOVERY; - } - } - if( rc!=SQLITE_OK ){ - return rc; - } - } - - pInfo = walCkptInfo(pWal); - if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame -#ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0 - || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr))) -#endif - ){ - /* The WAL has been completely backfilled (or it is empty). - ** and can be safely ignored. - */ - rc = walLockShared(pWal, WAL_READ_LOCK(0)); - walShmBarrier(pWal); - if( rc==SQLITE_OK ){ - if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ - /* It is not safe to allow the reader to continue here if frames - ** may have been appended to the log before READ_LOCK(0) was obtained. - ** When holding READ_LOCK(0), the reader ignores the entire log file, - ** which implies that the database file contains a trustworthy - ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from - ** happening, this is usually correct. - ** - ** However, if frames have been appended to the log (or if the log - ** is wrapped and written for that matter) before the READ_LOCK(0) - ** is obtained, that is not necessarily true. A checkpointer may - ** have started to backfill the appended frames but crashed before - ** it finished. Leaving a corrupt image in the database file. - */ - walUnlockShared(pWal, WAL_READ_LOCK(0)); - return WAL_RETRY; - } - pWal->readLock = 0; - return SQLITE_OK; - }else if( rc!=SQLITE_BUSY ){ - return rc; - } - } - - /* If we get this far, it means that the reader will want to use - ** the WAL to get at content from recent commits. The job now is - ** to select one of the aReadMark[] entries that is closest to - ** but not exceeding pWal->hdr.mxFrame and lock that entry. - */ - mxReadMark = 0; - mxI = 0; - mxFrame = pWal->hdr.mxFrame; -#ifdef SQLITE_ENABLE_SNAPSHOT - if( pWal->pSnapshot && pWal->pSnapshot->mxFramepSnapshot->mxFrame; - } -#endif - for(i=1; iaReadMark[i]; - if( mxReadMark<=thisMark && thisMark<=mxFrame ){ - assert( thisMark!=READMARK_NOT_USED ); - mxReadMark = thisMark; - mxI = i; - } - } - if( (pWal->readOnly & WAL_SHM_RDONLY)==0 - && (mxReadMarkaReadMark[i] = mxFrame; - mxI = i; - walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); - break; - }else if( rc!=SQLITE_BUSY ){ - return rc; - } - } - } - if( mxI==0 ){ - assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); - return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; - } - - rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); - if( rc ){ - return rc==SQLITE_BUSY ? WAL_RETRY : rc; - } - /* Now that the read-lock has been obtained, check that neither the - ** value in the aReadMark[] array or the contents of the wal-index - ** header have changed. - ** - ** It is necessary to check that the wal-index header did not change - ** between the time it was read and when the shared-lock was obtained - ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility - ** that the log file may have been wrapped by a writer, or that frames - ** that occur later in the log than pWal->hdr.mxFrame may have been - ** copied into the database by a checkpointer. If either of these things - ** happened, then reading the database with the current value of - ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry - ** instead. - ** - ** Before checking that the live wal-index header has not changed - ** since it was read, set Wal.minFrame to the first frame in the wal - ** file that has not yet been checkpointed. This client will not need - ** to read any frames earlier than minFrame from the wal file - they - ** can be safely read directly from the database file. - ** - ** Because a ShmBarrier() call is made between taking the copy of - ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the - ** checkpointer that set nBackfill was not working with a wal-index - ** header newer than that cached in pWal->hdr. If it were, that could - ** cause a problem. The checkpointer could omit to checkpoint - ** a version of page X that lies before pWal->minFrame (call that version - ** A) on the basis that there is a newer version (version B) of the same - ** page later in the wal file. But if version B happens to like past - ** frame pWal->hdr.mxFrame - then the client would incorrectly assume - ** that it can read version A from the database file. However, since - ** we can guarantee that the checkpointer that set nBackfill could not - ** see any pages past pWal->hdr.mxFrame, this problem does not come up. - */ - pWal->minFrame = pInfo->nBackfill+1; - walShmBarrier(pWal); - if( pInfo->aReadMark[mxI]!=mxReadMark - || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) - ){ - walUnlockShared(pWal, WAL_READ_LOCK(mxI)); - return WAL_RETRY; - }else{ - assert( mxReadMark<=pWal->hdr.mxFrame ); - pWal->readLock = (i16)mxI; - } - return rc; -} - -/* -** Begin a read transaction on the database. -** -** This routine used to be called sqlite3OpenSnapshot() and with good reason: -** it takes a snapshot of the state of the WAL and wal-index for the current -** instant in time. The current thread will continue to use this snapshot. -** Other threads might append new content to the WAL and wal-index but -** that extra content is ignored by the current thread. -** -** If the database contents have changes since the previous read -** transaction, then *pChanged is set to 1 before returning. The -** Pager layer will use this to know that is cache is stale and -** needs to be flushed. -*/ -SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ - int rc; /* Return code */ - int cnt = 0; /* Number of TryBeginRead attempts */ - -#ifdef SQLITE_ENABLE_SNAPSHOT - int bChanged = 0; - WalIndexHdr *pSnapshot = pWal->pSnapshot; - if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ - bChanged = 1; - } -#endif - - do{ - rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); - }while( rc==WAL_RETRY ); - testcase( (rc&0xff)==SQLITE_BUSY ); - testcase( (rc&0xff)==SQLITE_IOERR ); - testcase( rc==SQLITE_PROTOCOL ); - testcase( rc==SQLITE_OK ); - -#ifdef SQLITE_ENABLE_SNAPSHOT - if( rc==SQLITE_OK ){ - if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ - /* At this point the client has a lock on an aReadMark[] slot holding - ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr - ** is populated with the wal-index header corresponding to the head - ** of the wal file. Verify that pSnapshot is still valid before - ** continuing. Reasons why pSnapshot might no longer be valid: - ** - ** (1) The WAL file has been reset since the snapshot was taken. - ** In this case, the salt will have changed. - ** - ** (2) A checkpoint as been attempted that wrote frames past - ** pSnapshot->mxFrame into the database file. Note that the - ** checkpoint need not have completed for this to cause problems. - */ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - - assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 ); - assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame ); - - /* It is possible that there is a checkpointer thread running - ** concurrent with this code. If this is the case, it may be that the - ** checkpointer has already determined that it will checkpoint - ** snapshot X, where X is later in the wal file than pSnapshot, but - ** has not yet set the pInfo->nBackfillAttempted variable to indicate - ** its intent. To avoid the race condition this leads to, ensure that - ** there is no checkpointer process by taking a shared CKPT lock - ** before checking pInfo->nBackfillAttempted. */ - rc = walLockShared(pWal, WAL_CKPT_LOCK); - - if( rc==SQLITE_OK ){ - /* Check that the wal file has not been wrapped. Assuming that it has - ** not, also check that no checkpointer has attempted to checkpoint any - ** frames beyond pSnapshot->mxFrame. If either of these conditions are - ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr - ** with *pSnapshot and set *pChanged as appropriate for opening the - ** snapshot. */ - if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) - && pSnapshot->mxFrame>=pInfo->nBackfillAttempted - ){ - assert( pWal->readLock>0 ); - memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); - *pChanged = bChanged; - }else{ - rc = SQLITE_BUSY_SNAPSHOT; - } - - /* Release the shared CKPT lock obtained above. */ - walUnlockShared(pWal, WAL_CKPT_LOCK); - } - - - if( rc!=SQLITE_OK ){ - sqlite3WalEndReadTransaction(pWal); - } - } - } -#endif - return rc; -} - -/* -** Finish with a read transaction. All this does is release the -** read-lock. -*/ -SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ - sqlite3WalEndWriteTransaction(pWal); - if( pWal->readLock>=0 ){ - walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); - pWal->readLock = -1; - } -} - -/* -** Search the wal file for page pgno. If found, set *piRead to the frame that -** contains the page. Otherwise, if pgno is not in the wal file, set *piRead -** to zero. -** -** Return SQLITE_OK if successful, or an error code if an error occurs. If an -** error does occur, the final value of *piRead is undefined. -*/ -SQLITE_PRIVATE int sqlite3WalFindFrame( - Wal *pWal, /* WAL handle */ - Pgno pgno, /* Database page number to read data for */ - u32 *piRead /* OUT: Frame number (or zero) */ -){ - u32 iRead = 0; /* If !=0, WAL frame to return data from */ - u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ - int iHash; /* Used to loop through N hash tables */ - int iMinHash; - - /* This routine is only be called from within a read transaction. */ - assert( pWal->readLock>=0 || pWal->lockError ); - - /* If the "last page" field of the wal-index header snapshot is 0, then - ** no data will be read from the wal under any circumstances. Return early - ** in this case as an optimization. Likewise, if pWal->readLock==0, - ** then the WAL is ignored by the reader so return early, as if the - ** WAL were empty. - */ - if( iLast==0 || pWal->readLock==0 ){ - *piRead = 0; - return SQLITE_OK; - } - - /* Search the hash table or tables for an entry matching page number - ** pgno. Each iteration of the following for() loop searches one - ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). - ** - ** This code might run concurrently to the code in walIndexAppend() - ** that adds entries to the wal-index (and possibly to this hash - ** table). This means the value just read from the hash - ** slot (aHash[iKey]) may have been added before or after the - ** current read transaction was opened. Values added after the - ** read transaction was opened may have been written incorrectly - - ** i.e. these slots may contain garbage data. However, we assume - ** that any slots written before the current read transaction was - ** opened remain unmodified. - ** - ** For the reasons above, the if(...) condition featured in the inner - ** loop of the following block is more stringent that would be required - ** if we had exclusive access to the hash-table: - ** - ** (aPgno[iFrame]==pgno): - ** This condition filters out normal hash-table collisions. - ** - ** (iFrame<=iLast): - ** This condition filters out entries that were added to the hash - ** table after the current read-transaction had started. - */ - iMinHash = walFramePage(pWal->minFrame); - for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){ - volatile ht_slot *aHash; /* Pointer to hash table */ - volatile u32 *aPgno; /* Pointer to array of page numbers */ - u32 iZero; /* Frame number corresponding to aPgno[0] */ - int iKey; /* Hash slot index */ - int nCollide; /* Number of hash collisions remaining */ - int rc; /* Error code */ - - rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); - if( rc!=SQLITE_OK ){ - return rc; - } - nCollide = HASHTABLE_NSLOT; - for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ - u32 iFrame = aHash[iKey] + iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){ - assert( iFrame>iRead || CORRUPT_DB ); - iRead = iFrame; - } - if( (nCollide--)==0 ){ - return SQLITE_CORRUPT_BKPT; - } - } - } - -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT - /* If expensive assert() statements are available, do a linear search - ** of the wal-index file content. Make sure the results agree with the - ** result obtained using the hash indexes above. */ - { - u32 iRead2 = 0; - u32 iTest; - assert( pWal->minFrame>0 ); - for(iTest=iLast; iTest>=pWal->minFrame; iTest--){ - if( walFramePgno(pWal, iTest)==pgno ){ - iRead2 = iTest; - break; - } - } - assert( iRead==iRead2 ); - } -#endif - - *piRead = iRead; - return SQLITE_OK; -} - -/* -** Read the contents of frame iRead from the wal file into buffer pOut -** (which is nOut bytes in size). Return SQLITE_OK if successful, or an -** error code otherwise. -*/ -SQLITE_PRIVATE int sqlite3WalReadFrame( - Wal *pWal, /* WAL handle */ - u32 iRead, /* Frame to read */ - int nOut, /* Size of buffer pOut in bytes */ - u8 *pOut /* Buffer to write page data to */ -){ - int sz; - i64 iOffset; - sz = pWal->hdr.szPage; - sz = (sz&0xfe00) + ((sz&0x0001)<<16); - testcase( sz<=32768 ); - testcase( sz>=65536 ); - iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); -} - -/* -** Return the size of the database in pages (or zero, if unknown). -*/ -SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ - if( pWal && ALWAYS(pWal->readLock>=0) ){ - return pWal->hdr.nPage; - } - return 0; -} - - -/* -** This function starts a write transaction on the WAL. -** -** A read transaction must have already been started by a prior call -** to sqlite3WalBeginReadTransaction(). -** -** If another thread or process has written into the database since -** the read transaction was started, then it is not possible for this -** thread to write as doing so would cause a fork. So this routine -** returns SQLITE_BUSY in that case and no write transaction is started. -** -** There can only be a single writer active at a time. -*/ -SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ - int rc; - - /* Cannot start a write transaction without first holding a read - ** transaction. */ - assert( pWal->readLock>=0 ); - assert( pWal->writeLock==0 && pWal->iReCksum==0 ); - - if( pWal->readOnly ){ - return SQLITE_READONLY; - } - - /* Only one writer allowed at a time. Get the write lock. Return - ** SQLITE_BUSY if unable. - */ - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); - if( rc ){ - return rc; - } - pWal->writeLock = 1; - - /* If another connection has written to the database file since the - ** time the read transaction on this connection was started, then - ** the write is disallowed. - */ - if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); - pWal->writeLock = 0; - rc = SQLITE_BUSY_SNAPSHOT; - } - - return rc; -} - -/* -** End a write transaction. The commit has already been done. This -** routine merely releases the lock. -*/ -SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ - if( pWal->writeLock ){ - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); - pWal->writeLock = 0; - pWal->iReCksum = 0; - pWal->truncateOnCommit = 0; - } - return SQLITE_OK; -} - -/* -** If any data has been written (but not committed) to the log file, this -** function moves the write-pointer back to the start of the transaction. -** -** Additionally, the callback function is invoked for each frame written -** to the WAL since the start of the transaction. If the callback returns -** other than SQLITE_OK, it is not invoked again and the error code is -** returned to the caller. -** -** Otherwise, if the callback function does not return an error, this -** function returns SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ - int rc = SQLITE_OK; - if( ALWAYS(pWal->writeLock) ){ - Pgno iMax = pWal->hdr.mxFrame; - Pgno iFrame; - - /* Restore the clients cache of the wal-index header to the state it - ** was in before the client began writing to the database. - */ - memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); - - for(iFrame=pWal->hdr.mxFrame+1; - ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; - iFrame++ - ){ - /* This call cannot fail. Unless the page for which the page number - ** is passed as the second argument is (a) in the cache and - ** (b) has an outstanding reference, then xUndo is either a no-op - ** (if (a) is false) or simply expels the page from the cache (if (b) - ** is false). - ** - ** If the upper layer is doing a rollback, it is guaranteed that there - ** are no outstanding references to any page other than page 1. And - ** page 1 is never written to the log until the transaction is - ** committed. As a result, the call to xUndo may not fail. - */ - assert( walFramePgno(pWal, iFrame)!=1 ); - rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); - } - if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); - } - return rc; -} - -/* -** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 -** values. This function populates the array with values required to -** "rollback" the write position of the WAL handle back to the current -** point in the event of a savepoint rollback (via WalSavepointUndo()). -*/ -SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ - assert( pWal->writeLock ); - aWalData[0] = pWal->hdr.mxFrame; - aWalData[1] = pWal->hdr.aFrameCksum[0]; - aWalData[2] = pWal->hdr.aFrameCksum[1]; - aWalData[3] = pWal->nCkpt; -} - -/* -** Move the write position of the WAL back to the point identified by -** the values in the aWalData[] array. aWalData must point to an array -** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated -** by a call to WalSavepoint(). -*/ -SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ - int rc = SQLITE_OK; - - assert( pWal->writeLock ); - assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); - - if( aWalData[3]!=pWal->nCkpt ){ - /* This savepoint was opened immediately after the write-transaction - ** was started. Right after that, the writer decided to wrap around - ** to the start of the log. Update the savepoint values to match. - */ - aWalData[0] = 0; - aWalData[3] = pWal->nCkpt; - } - - if( aWalData[0]hdr.mxFrame ){ - pWal->hdr.mxFrame = aWalData[0]; - pWal->hdr.aFrameCksum[0] = aWalData[1]; - pWal->hdr.aFrameCksum[1] = aWalData[2]; - walCleanupHash(pWal); - } - - return rc; -} - -/* -** This function is called just before writing a set of frames to the log -** file (see sqlite3WalFrames()). It checks to see if, instead of appending -** to the current log file, it is possible to overwrite the start of the -** existing log file with the new frames (i.e. "reset" the log). If so, -** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left -** unchanged. -** -** SQLITE_OK is returned if no error is encountered (regardless of whether -** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned -** if an error occurs. -*/ -static int walRestartLog(Wal *pWal){ - int rc = SQLITE_OK; - int cnt; - - if( pWal->readLock==0 ){ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - assert( pInfo->nBackfill==pWal->hdr.mxFrame ); - if( pInfo->nBackfill>0 ){ - u32 salt1; - sqlite3_randomness(4, &salt1); - rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); - if( rc==SQLITE_OK ){ - /* If all readers are using WAL_READ_LOCK(0) (in other words if no - ** readers are currently using the WAL), then the transactions - ** frames will overwrite the start of the existing log. Update the - ** wal-index header to reflect this. - ** - ** In theory it would be Ok to update the cache of the header only - ** at this point. But updating the actual wal-index header is also - ** safe and means there is no special case for sqlite3WalUndo() - ** to handle if this transaction is rolled back. */ - walRestartHdr(pWal, salt1); - walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); - }else if( rc!=SQLITE_BUSY ){ - return rc; - } - } - walUnlockShared(pWal, WAL_READ_LOCK(0)); - pWal->readLock = -1; - cnt = 0; - do{ - int notUsed; - rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); - }while( rc==WAL_RETRY ); - assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ - testcase( (rc&0xff)==SQLITE_IOERR ); - testcase( rc==SQLITE_PROTOCOL ); - testcase( rc==SQLITE_OK ); - } - return rc; -} - -/* -** Information about the current state of the WAL file and where -** the next fsync should occur - passed from sqlite3WalFrames() into -** walWriteToLog(). -*/ -typedef struct WalWriter { - Wal *pWal; /* The complete WAL information */ - sqlite3_file *pFd; /* The WAL file to which we write */ - sqlite3_int64 iSyncPoint; /* Fsync at this offset */ - int syncFlags; /* Flags for the fsync */ - int szPage; /* Size of one page */ -} WalWriter; - -/* -** Write iAmt bytes of content into the WAL file beginning at iOffset. -** Do a sync when crossing the p->iSyncPoint boundary. -** -** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, -** first write the part before iSyncPoint, then sync, then write the -** rest. -*/ -static int walWriteToLog( - WalWriter *p, /* WAL to write to */ - void *pContent, /* Content to be written */ - int iAmt, /* Number of bytes to write */ - sqlite3_int64 iOffset /* Start writing at this offset */ -){ - int rc; - if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ - int iFirstAmt = (int)(p->iSyncPoint - iOffset); - rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); - if( rc ) return rc; - iOffset += iFirstAmt; - iAmt -= iFirstAmt; - pContent = (void*)(iFirstAmt + (char*)pContent); - assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); - if( iAmt==0 || rc ) return rc; - } - rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); - return rc; -} - -/* -** Write out a single frame of the WAL -*/ -static int walWriteOneFrame( - WalWriter *p, /* Where to write the frame */ - PgHdr *pPage, /* The page of the frame to be written */ - int nTruncate, /* The commit flag. Usually 0. >0 for commit */ - sqlite3_int64 iOffset /* Byte offset at which to write */ -){ - int rc; /* Result code from subfunctions */ - void *pData; /* Data actually written */ - u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT; -#else - pData = pPage->pData; -#endif - walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); - rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); - if( rc ) return rc; - /* Write the page data */ - rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); - return rc; -} - -/* -** This function is called as part of committing a transaction within which -** one or more frames have been overwritten. It updates the checksums for -** all frames written to the wal file by the current transaction starting -** with the earliest to have been overwritten. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -static int walRewriteChecksums(Wal *pWal, u32 iLast){ - const int szPage = pWal->szPage;/* Database page size */ - int rc = SQLITE_OK; /* Return code */ - u8 *aBuf; /* Buffer to load data from wal file into */ - u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */ - u32 iRead; /* Next frame to read from wal file */ - i64 iCksumOff; - - aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE); - if( aBuf==0 ) return SQLITE_NOMEM_BKPT; - - /* Find the checksum values to use as input for the recalculating the - ** first checksum. If the first frame is frame 1 (implying that the current - ** transaction restarted the wal file), these values must be read from the - ** wal-file header. Otherwise, read them from the frame header of the - ** previous frame. */ - assert( pWal->iReCksum>0 ); - if( pWal->iReCksum==1 ){ - iCksumOff = 24; - }else{ - iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16; - } - rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff); - pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf); - pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]); - - iRead = pWal->iReCksum; - pWal->iReCksum = 0; - for(; rc==SQLITE_OK && iRead<=iLast; iRead++){ - i64 iOff = walFrameOffset(iRead, szPage); - rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff); - if( rc==SQLITE_OK ){ - u32 iPgno, nDbSize; - iPgno = sqlite3Get4byte(aBuf); - nDbSize = sqlite3Get4byte(&aBuf[4]); - - walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame); - rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff); - } - } - - sqlite3_free(aBuf); - return rc; -} - -/* -** Write a set of frames to the log. The caller must hold the write-lock -** on the log file (obtained using sqlite3WalBeginWriteTransaction()). -*/ -SQLITE_PRIVATE int sqlite3WalFrames( - Wal *pWal, /* Wal handle to write to */ - int szPage, /* Database page-size in bytes */ - PgHdr *pList, /* List of dirty pages to write */ - Pgno nTruncate, /* Database size after this commit */ - int isCommit, /* True if this is a commit */ - int sync_flags /* Flags to pass to OsSync() (or 0) */ -){ - int rc; /* Used to catch return codes */ - u32 iFrame; /* Next frame address */ - PgHdr *p; /* Iterator to run through pList with. */ - PgHdr *pLast = 0; /* Last frame in list */ - int nExtra = 0; /* Number of extra copies of last page */ - int szFrame; /* The size of a single frame */ - i64 iOffset; /* Next byte to write in WAL file */ - WalWriter w; /* The writer */ - u32 iFirst = 0; /* First frame that may be overwritten */ - WalIndexHdr *pLive; /* Pointer to shared header */ - - assert( pList ); - assert( pWal->writeLock ); - - /* If this frame set completes a transaction, then nTruncate>0. If - ** nTruncate==0 then this frame set does not complete the transaction. */ - assert( (isCommit!=0)==(nTruncate!=0) ); - -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) - { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} - WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", - pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); - } -#endif - - pLive = (WalIndexHdr*)walIndexHdr(pWal); - if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){ - iFirst = pLive->mxFrame+1; - } - - /* See if it is possible to write these frames into the start of the - ** log file, instead of appending to it at pWal->hdr.mxFrame. - */ - if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ - return rc; - } - - /* If this is the first frame written into the log, write the WAL - ** header to the start of the WAL file. See comments at the top of - ** this source file for a description of the WAL header format. - */ - iFrame = pWal->hdr.mxFrame; - if( iFrame==0 ){ - u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ - u32 aCksum[2]; /* Checksum for wal-header */ - - sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); - sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); - sqlite3Put4byte(&aWalHdr[8], szPage); - sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); - if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); - memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); - walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); - sqlite3Put4byte(&aWalHdr[24], aCksum[0]); - sqlite3Put4byte(&aWalHdr[28], aCksum[1]); - - pWal->szPage = szPage; - pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; - pWal->hdr.aFrameCksum[0] = aCksum[0]; - pWal->hdr.aFrameCksum[1] = aCksum[1]; - pWal->truncateOnCommit = 1; - - rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); - WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless - ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise - ** an out-of-order write following a WAL restart could result in - ** database corruption. See the ticket: - ** - ** http://localhost:591/sqlite/info/ff5be73dee - */ - if( pWal->syncHeader && sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); - if( rc ) return rc; - } - } - assert( (int)pWal->szPage==szPage ); - - /* Setup information needed to write frames into the WAL */ - w.pWal = pWal; - w.pFd = pWal->pWalFd; - w.iSyncPoint = 0; - w.syncFlags = sync_flags; - w.szPage = szPage; - iOffset = walFrameOffset(iFrame+1, szPage); - szFrame = szPage + WAL_FRAME_HDRSIZE; - - /* Write all frames into the log file exactly once */ - for(p=pList; p; p=p->pDirty){ - int nDbSize; /* 0 normally. Positive == commit flag */ - - /* Check if this page has already been written into the wal file by - ** the current transaction. If so, overwrite the existing frame and - ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that - ** checksums must be recomputed when the transaction is committed. */ - if( iFirst && (p->pDirty || isCommit==0) ){ - u32 iWrite = 0; - VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite); - assert( rc==SQLITE_OK || iWrite==0 ); - if( iWrite>=iFirst ){ - i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; - void *pData; - if( pWal->iReCksum==0 || iWriteiReCksum ){ - pWal->iReCksum = iWrite; - } -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; -#else - pData = p->pData; -#endif - rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); - if( rc ) return rc; - p->flags &= ~PGHDR_WAL_APPEND; - continue; - } - } - - iFrame++; - assert( iOffset==walFrameOffset(iFrame, szPage) ); - nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; - rc = walWriteOneFrame(&w, p, nDbSize, iOffset); - if( rc ) return rc; - pLast = p; - iOffset += szFrame; - p->flags |= PGHDR_WAL_APPEND; - } - - /* Recalculate checksums within the wal file if required. */ - if( isCommit && pWal->iReCksum ){ - rc = walRewriteChecksums(pWal, iFrame); - if( rc ) return rc; - } - - /* If this is the end of a transaction, then we might need to pad - ** the transaction and/or sync the WAL file. - ** - ** Padding and syncing only occur if this set of frames complete a - ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL - ** or synchronous==OFF, then no padding or syncing are needed. - ** - ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not - ** needed and only the sync is done. If padding is needed, then the - ** final frame is repeated (with its commit mark) until the next sector - ** boundary is crossed. Only the part of the WAL prior to the last - ** sector boundary is synced; the part of the last frame that extends - ** past the sector boundary is written after the sync. - */ - if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ - int bSync = 1; - if( pWal->padToSectorBoundary ){ - int sectorSize = sqlite3SectorSize(pWal->pWalFd); - w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; - bSync = (w.iSyncPoint==iOffset); - testcase( bSync ); - while( iOffsettruncateOnCommit && pWal->mxWalSize>=0 ){ - i64 sz = pWal->mxWalSize; - if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ - sz = walFrameOffset(iFrame+nExtra+1, szPage); - } - walLimitSize(pWal, sz); - pWal->truncateOnCommit = 0; - } - - /* Append data to the wal-index. It is not necessary to lock the - ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index - ** guarantees that there are no other writers, and no data that may - ** be in use by existing readers is being overwritten. - */ - iFrame = pWal->hdr.mxFrame; - for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ - if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; - iFrame++; - rc = walIndexAppend(pWal, iFrame, p->pgno); - } - while( rc==SQLITE_OK && nExtra>0 ){ - iFrame++; - nExtra--; - rc = walIndexAppend(pWal, iFrame, pLast->pgno); - } - - if( rc==SQLITE_OK ){ - /* Update the private copy of the header. */ - pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); - testcase( szPage<=32768 ); - testcase( szPage>=65536 ); - pWal->hdr.mxFrame = iFrame; - if( isCommit ){ - pWal->hdr.iChange++; - pWal->hdr.nPage = nTruncate; - } - /* If this is a commit, update the wal-index header too. */ - if( isCommit ){ - walIndexWriteHdr(pWal); - pWal->iCallback = iFrame; - } - } - - WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); - return rc; -} - -/* -** This routine is called to implement sqlite3_wal_checkpoint() and -** related interfaces. -** -** Obtain a CHECKPOINT lock and then backfill as much information as -** we can from WAL into the database. -** -** If parameter xBusy is not NULL, it is a pointer to a busy-handler -** callback. In this case this function runs a blocking checkpoint. -*/ -SQLITE_PRIVATE int sqlite3WalCheckpoint( - Wal *pWal, /* Wal connection */ - int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ - int (*xBusy)(void*), /* Function to call when busy */ - void *pBusyArg, /* Context argument for xBusyHandler */ - int sync_flags, /* Flags to sync db file with (or 0) */ - int nBuf, /* Size of temporary buffer */ - u8 *zBuf, /* Temporary buffer to use */ - int *pnLog, /* OUT: Number of frames in WAL */ - int *pnCkpt /* OUT: Number of backfilled frames in WAL */ -){ - int rc; /* Return code */ - int isChanged = 0; /* True if a new wal-index header is loaded */ - int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ - int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ - - assert( pWal->ckptLock==0 ); - assert( pWal->writeLock==0 ); - - /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked - ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ - assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); - - if( pWal->readOnly ) return SQLITE_READONLY; - WALTRACE(("WAL%p: checkpoint begins\n", pWal)); - - /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive - ** "checkpoint" lock on the database file. */ - rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); - if( rc ){ - /* EVIDENCE-OF: R-10421-19736 If any other process is running a - ** checkpoint operation at the same time, the lock cannot be obtained and - ** SQLITE_BUSY is returned. - ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, - ** it will not be invoked in this case. - */ - testcase( rc==SQLITE_BUSY ); - testcase( xBusy!=0 ); - return rc; - } - pWal->ckptLock = 1; - - /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and - ** TRUNCATE modes also obtain the exclusive "writer" lock on the database - ** file. - ** - ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained - ** immediately, and a busy-handler is configured, it is invoked and the - ** writer lock retried until either the busy-handler returns 0 or the - ** lock is successfully obtained. - */ - if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ - rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1); - if( rc==SQLITE_OK ){ - pWal->writeLock = 1; - }else if( rc==SQLITE_BUSY ){ - eMode2 = SQLITE_CHECKPOINT_PASSIVE; - xBusy2 = 0; - rc = SQLITE_OK; - } - } - - /* Read the wal-index header. */ - if( rc==SQLITE_OK ){ - rc = walIndexReadHdr(pWal, &isChanged); - if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ - sqlite3OsUnfetch(pWal->pDbFd, 0, 0); - } - } - - /* Copy data from the log to the database file. */ - if( rc==SQLITE_OK ){ - - if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); - } - - /* If no error occurred, set the output variables. */ - if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ - if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; - if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); - } - } - - if( isChanged ){ - /* If a new wal-index header was loaded before the checkpoint was - ** performed, then the pager-cache associated with pWal is now - ** out of date. So zero the cached wal-index header to ensure that - ** next time the pager opens a snapshot on this database it knows that - ** the cache needs to be reset. - */ - memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); - } - - /* Release the locks. */ - sqlite3WalEndWriteTransaction(pWal); - walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); - pWal->ckptLock = 0; - WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); - return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); -} - -/* Return the value to pass to a sqlite3_wal_hook callback, the -** number of frames in the WAL at the point of the last commit since -** sqlite3WalCallback() was called. If no commits have occurred since -** the last call, then return 0. -*/ -SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ - u32 ret = 0; - if( pWal ){ - ret = pWal->iCallback; - pWal->iCallback = 0; - } - return (int)ret; -} - -/* -** This function is called to change the WAL subsystem into or out -** of locking_mode=EXCLUSIVE. -** -** If op is zero, then attempt to change from locking_mode=EXCLUSIVE -** into locking_mode=NORMAL. This means that we must acquire a lock -** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL -** or if the acquisition of the lock fails, then return 0. If the -** transition out of exclusive-mode is successful, return 1. This -** operation must occur while the pager is still holding the exclusive -** lock on the main database file. -** -** If op is one, then change from locking_mode=NORMAL into -** locking_mode=EXCLUSIVE. This means that the pWal->readLock must -** be released. Return 1 if the transition is made and 0 if the -** WAL is already in exclusive-locking mode - meaning that this -** routine is a no-op. The pager must already hold the exclusive lock -** on the main database file before invoking this operation. -** -** If op is negative, then do a dry-run of the op==1 case but do -** not actually change anything. The pager uses this to see if it -** should acquire the database exclusive lock prior to invoking -** the op==1 case. -*/ -SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ - int rc; - assert( pWal->writeLock==0 ); - assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); - - /* pWal->readLock is usually set, but might be -1 if there was a - ** prior error while attempting to acquire are read-lock. This cannot - ** happen if the connection is actually in exclusive mode (as no xShmLock - ** locks are taken in this case). Nor should the pager attempt to - ** upgrade to exclusive-mode following such an error. - */ - assert( pWal->readLock>=0 || pWal->lockError ); - assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); - - if( op==0 ){ - if( pWal->exclusiveMode ){ - pWal->exclusiveMode = 0; - if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ - pWal->exclusiveMode = 1; - } - rc = pWal->exclusiveMode==0; - }else{ - /* Already in locking_mode=NORMAL */ - rc = 0; - } - }else if( op>0 ){ - assert( pWal->exclusiveMode==0 ); - assert( pWal->readLock>=0 ); - walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); - pWal->exclusiveMode = 1; - rc = 1; - }else{ - rc = pWal->exclusiveMode==0; - } - return rc; -} - -/* -** Return true if the argument is non-NULL and the WAL module is using -** heap-memory for the wal-index. Otherwise, if the argument is NULL or the -** WAL module is using shared-memory, return false. -*/ -SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ - return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); -} - -#ifdef SQLITE_ENABLE_SNAPSHOT -/* Create a snapshot object. The content of a snapshot is opaque to -** every other subsystem, so the WAL module can put whatever it needs -** in the object. -*/ -SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ - int rc = SQLITE_OK; - WalIndexHdr *pRet; - - assert( pWal->readLock>=0 && pWal->writeLock==0 ); - - pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); - if( pRet==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr)); - *ppSnapshot = (sqlite3_snapshot*)pRet; - } - - return rc; -} - -/* Try to open on pSnapshot when the next read-transaction starts -*/ -SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ - pWal->pSnapshot = (WalIndexHdr*)pSnapshot; -} - -/* -** Return a +ve value if snapshot p1 is newer than p2. A -ve value if -** p1 is older than p2 and zero if p1 and p2 are the same snapshot. -*/ -SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ - WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; - WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; - - /* aSalt[0] is a copy of the value stored in the wal file header. It - ** is incremented each time the wal file is restarted. */ - if( pHdr1->aSalt[0]aSalt[0] ) return -1; - if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; - if( pHdr1->mxFramemxFrame ) return -1; - if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; - return 0; -} -#endif /* SQLITE_ENABLE_SNAPSHOT */ - -#ifdef SQLITE_ENABLE_ZIPVFS -/* -** If the argument is not NULL, it points to a Wal object that holds a -** read-lock. This function returns the database page-size if it is known, -** or zero if it is not (or if pWal is NULL). -*/ -SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ - assert( pWal==0 || pWal->readLock>=0 ); - return (pWal ? pWal->szPage : 0); -} -#endif - -/* Return the sqlite3_file object for the WAL file -*/ -SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ - return pWal->pWalFd; -} - -#endif /* #ifndef SQLITE_OMIT_WAL */ - -/************** End of wal.c *************************************************/ -/************** Begin file btmutex.c *****************************************/ -/* -** 2007 August 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code used to implement mutexes on Btree objects. -** This code really belongs in btree.c. But btree.c is getting too -** big and we want to break it down some. This packaged seemed like -** a good breakout. -*/ -/************** Include btreeInt.h in the middle of btmutex.c ****************/ -/************** Begin file btreeInt.h ****************************************/ -/* -** 2004 April 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file implements an external (disk-based) database using BTrees. -** For a detailed discussion of BTrees, refer to -** -** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: -** "Sorting And Searching", pages 473-480. Addison-Wesley -** Publishing Company, Reading, Massachusetts. -** -** The basic idea is that each page of the file contains N database -** entries and N+1 pointers to subpages. -** -** ---------------------------------------------------------------- -** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | -** ---------------------------------------------------------------- -** -** All of the keys on the page that Ptr(0) points to have values less -** than Key(0). All of the keys on page Ptr(1) and its subpages have -** values greater than Key(0) and less than Key(1). All of the keys -** on Ptr(N) and its subpages have values greater than Key(N-1). And -** so forth. -** -** Finding a particular key requires reading O(log(M)) pages from the -** disk where M is the number of entries in the tree. -** -** In this implementation, a single file can hold one or more separate -** BTrees. Each BTree is identified by the index of its root page. The -** key and data for any entry are combined to form the "payload". A -** fixed amount of payload can be carried directly on the database -** page. If the payload is larger than the preset amount then surplus -** bytes are stored on overflow pages. The payload for an entry -** and the preceding pointer are combined to form a "Cell". Each -** page has a small header which contains the Ptr(N) pointer and other -** information such as the size of key and data. -** -** FORMAT DETAILS -** -** The file is divided into pages. The first page is called page 1, -** the second is page 2, and so forth. A page number of zero indicates -** "no such page". The page size can be any power of 2 between 512 and 65536. -** Each page can be either a btree page, a freelist page, an overflow -** page, or a pointer-map page. -** -** The first page is always a btree page. The first 100 bytes of the first -** page contain a special header (the "file header") that describes the file. -** The format of the file header is as follows: -** -** OFFSET SIZE DESCRIPTION -** 0 16 Header string: "SQLite format 3\000" -** 16 2 Page size in bytes. (1 means 65536) -** 18 1 File format write version -** 19 1 File format read version -** 20 1 Bytes of unused space at the end of each page -** 21 1 Max embedded payload fraction (must be 64) -** 22 1 Min embedded payload fraction (must be 32) -** 23 1 Min leaf payload fraction (must be 32) -** 24 4 File change counter -** 28 4 Reserved for future use -** 32 4 First freelist page -** 36 4 Number of freelist pages in the file -** 40 60 15 4-byte meta values passed to higher layers -** -** 40 4 Schema cookie -** 44 4 File format of schema layer -** 48 4 Size of page cache -** 52 4 Largest root-page (auto/incr_vacuum) -** 56 4 1=UTF-8 2=UTF16le 3=UTF16be -** 60 4 User version -** 64 4 Incremental vacuum mode -** 68 4 Application-ID -** 72 20 unused -** 92 4 The version-valid-for number -** 96 4 SQLITE_VERSION_NUMBER -** -** All of the integer values are big-endian (most significant byte first). -** -** The file change counter is incremented when the database is changed -** This counter allows other processes to know when the file has changed -** and thus when they need to flush their cache. -** -** The max embedded payload fraction is the amount of the total usable -** space in a page that can be consumed by a single cell for standard -** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default -** is to limit the maximum cell size so that at least 4 cells will fit -** on one page. Thus the default max embedded payload fraction is 64. -** -** If the payload for a cell is larger than the max payload, then extra -** payload is spilled to overflow pages. Once an overflow page is allocated, -** as many bytes as possible are moved into the overflow pages without letting -** the cell size drop below the min embedded payload fraction. -** -** The min leaf payload fraction is like the min embedded payload fraction -** except that it applies to leaf nodes in a LEAFDATA tree. The maximum -** payload fraction for a LEAFDATA tree is always 100% (or 255) and it -** not specified in the header. -** -** Each btree pages is divided into three sections: The header, the -** cell pointer array, and the cell content area. Page 1 also has a 100-byte -** file header that occurs before the page header. -** -** |----------------| -** | file header | 100 bytes. Page 1 only. -** |----------------| -** | page header | 8 bytes for leaves. 12 bytes for interior nodes -** |----------------| -** | cell pointer | | 2 bytes per cell. Sorted order. -** | array | | Grows downward -** | | v -** |----------------| -** | unallocated | -** | space | -** |----------------| ^ Grows upwards -** | cell content | | Arbitrary order interspersed with freeblocks. -** | area | | and free space fragments. -** |----------------| -** -** The page headers looks like this: -** -** OFFSET SIZE DESCRIPTION -** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf -** 1 2 byte offset to the first freeblock -** 3 2 number of cells on this page -** 5 2 first byte of the cell content area -** 7 1 number of fragmented free bytes -** 8 4 Right child (the Ptr(N) value). Omitted on leaves. -** -** The flags define the format of this btree page. The leaf flag means that -** this page has no children. The zerodata flag means that this page carries -** only keys and no data. The intkey flag means that the key is an integer -** which is stored in the key size entry of the cell header rather than in -** the payload area. -** -** The cell pointer array begins on the first byte after the page header. -** The cell pointer array contains zero or more 2-byte numbers which are -** offsets from the beginning of the page to the cell content in the cell -** content area. The cell pointers occur in sorted order. The system strives -** to keep free space after the last cell pointer so that new cells can -** be easily added without having to defragment the page. -** -** Cell content is stored at the very end of the page and grows toward the -** beginning of the page. -** -** Unused space within the cell content area is collected into a linked list of -** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset -** to the first freeblock is given in the header. Freeblocks occur in -** increasing order. Because a freeblock must be at least 4 bytes in size, -** any group of 3 or fewer unused bytes in the cell content area cannot -** exist on the freeblock chain. A group of 3 or fewer free bytes is called -** a fragment. The total number of bytes in all fragments is recorded. -** in the page header at offset 7. -** -** SIZE DESCRIPTION -** 2 Byte offset of the next freeblock -** 2 Bytes in this freeblock -** -** Cells are of variable length. Cells are stored in the cell content area at -** the end of the page. Pointers to the cells are in the cell pointer array -** that immediately follows the page header. Cells is not necessarily -** contiguous or in order, but cell pointers are contiguous and in order. -** -** Cell content makes use of variable length integers. A variable -** length integer is 1 to 9 bytes where the lower 7 bits of each -** byte are used. The integer consists of all bytes that have bit 8 set and -** the first byte with bit 8 clear. The most significant byte of the integer -** appears first. A variable-length integer may not be more than 9 bytes long. -** As a special case, all 8 bytes of the 9th byte are used as data. This -** allows a 64-bit integer to be encoded in 9 bytes. -** -** 0x00 becomes 0x00000000 -** 0x7f becomes 0x0000007f -** 0x81 0x00 becomes 0x00000080 -** 0x82 0x00 becomes 0x00000100 -** 0x80 0x7f becomes 0x0000007f -** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 -** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 -** -** Variable length integers are used for rowids and to hold the number of -** bytes of key and data in a btree cell. -** -** The content of a cell looks like this: -** -** SIZE DESCRIPTION -** 4 Page number of the left child. Omitted if leaf flag is set. -** var Number of bytes of data. Omitted if the zerodata flag is set. -** var Number of bytes of key. Or the key itself if intkey flag is set. -** * Payload -** 4 First page of the overflow chain. Omitted if no overflow -** -** Overflow pages form a linked list. Each page except the last is completely -** filled with data (pagesize - 4 bytes). The last page can have as little -** as 1 byte of data. -** -** SIZE DESCRIPTION -** 4 Page number of next overflow page -** * Data -** -** Freelist pages come in two subtypes: trunk pages and leaf pages. The -** file header points to the first in a linked list of trunk page. Each trunk -** page points to multiple leaf pages. The content of a leaf page is -** unspecified. A trunk page looks like this: -** -** SIZE DESCRIPTION -** 4 Page number of next trunk page -** 4 Number of leaf pointers on this page -** * zero or more pages numbers of leaves -*/ -/* #include "sqliteInt.h" */ - - -/* The following value is the maximum cell size assuming a maximum page -** size give above. -*/ -#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) - -/* The maximum number of cells on a single page of the database. This -** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself -** plus 2 bytes for the index to the cell in the page header). Such -** small cells will be rare, but they are possible. -*/ -#define MX_CELL(pBt) ((pBt->pageSize-8)/6) - -/* Forward declarations */ -typedef struct MemPage MemPage; -typedef struct BtLock BtLock; -typedef struct CellInfo CellInfo; - -/* -** This is a magic string that appears at the beginning of every -** SQLite database in order to identify the file as a real database. -** -** You can change this value at compile-time by specifying a -** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The -** header must be exactly 16 bytes including the zero-terminator so -** the string itself should be 15 characters long. If you change -** the header, then your custom library will not be able to read -** databases generated by the standard tools and the standard tools -** will not be able to read databases created by your custom library. -*/ -#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ -# define SQLITE_FILE_HEADER "SQLite format 3" -#endif - -/* -** Page type flags. An ORed combination of these flags appear as the -** first byte of on-disk image of every BTree page. -*/ -#define PTF_INTKEY 0x01 -#define PTF_ZERODATA 0x02 -#define PTF_LEAFDATA 0x04 -#define PTF_LEAF 0x08 - -/* -** As each page of the file is loaded into memory, an instance of the following -** structure is appended and initialized to zero. This structure stores -** information about the page that is decoded from the raw file page. -** -** The pParent field points back to the parent page. This allows us to -** walk up the BTree from any leaf to the root. Care must be taken to -** unref() the parent page pointer when this page is no longer referenced. -** The pageDestructor() routine handles that chore. -** -** Access to all fields of this structure is controlled by the mutex -** stored in MemPage.pBt->mutex. -*/ -struct MemPage { - u8 isInit; /* True if previously initialized. MUST BE FIRST! */ - u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ - u8 intKey; /* True if table b-trees. False for index b-trees */ - u8 intKeyLeaf; /* True if the leaf of an intKey table */ - u8 leaf; /* True if a leaf page */ - u8 hdrOffset; /* 100 for page 1. 0 otherwise */ - u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ - u8 max1bytePayload; /* min(maxLocal,127) */ - u8 bBusy; /* Prevent endless loops on corrupt database files */ - u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ - u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ - u16 cellOffset; /* Index in aData of first cell pointer */ - u16 nFree; /* Number of free bytes on the page */ - u16 nCell; /* Number of cells on this page, local and ovfl */ - u16 maskPage; /* Mask for page offset */ - u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th - ** non-overflow cell */ - u8 *apOvfl[5]; /* Pointers to the body of overflow cells */ - BtShared *pBt; /* Pointer to BtShared that this page is part of */ - u8 *aData; /* Pointer to disk image of the page data */ - u8 *aDataEnd; /* One byte past the end of usable data */ - u8 *aCellIdx; /* The cell index area */ - u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ - DbPage *pDbPage; /* Pager page handle */ - u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ - void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ - Pgno pgno; /* Page number for this page */ -}; - -/* -** The in-memory image of a disk page has the auxiliary information appended -** to the end. EXTRA_SIZE is the number of bytes of space needed to hold -** that extra information. -*/ -#define EXTRA_SIZE sizeof(MemPage) - -/* -** A linked list of the following structures is stored at BtShared.pLock. -** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor -** is opened on the table with root page BtShared.iTable. Locks are removed -** from this list when a transaction is committed or rolled back, or when -** a btree handle is closed. -*/ -struct BtLock { - Btree *pBtree; /* Btree handle holding this lock */ - Pgno iTable; /* Root page of table */ - u8 eLock; /* READ_LOCK or WRITE_LOCK */ - BtLock *pNext; /* Next in BtShared.pLock list */ -}; - -/* Candidate values for BtLock.eLock */ -#define READ_LOCK 1 -#define WRITE_LOCK 2 - -/* A Btree handle -** -** A database connection contains a pointer to an instance of -** this object for every database file that it has open. This structure -** is opaque to the database connection. The database connection cannot -** see the internals of this structure and only deals with pointers to -** this structure. -** -** For some database files, the same underlying database cache might be -** shared between multiple connections. In that case, each connection -** has it own instance of this object. But each instance of this object -** points to the same BtShared object. The database cache and the -** schema associated with the database file are all contained within -** the BtShared object. -** -** All fields in this structure are accessed under sqlite3.mutex. -** The pBt pointer itself may not be changed while there exists cursors -** in the referenced BtShared that point back to this Btree since those -** cursors have to go through this Btree to find their BtShared and -** they often do so without holding sqlite3.mutex. -*/ -struct Btree { - sqlite3 *db; /* The database connection holding this btree */ - BtShared *pBt; /* Sharable content of this btree */ - u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ - u8 sharable; /* True if we can share pBt with another db */ - u8 locked; /* True if db currently has pBt locked */ - u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ - int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ - int nBackup; /* Number of backup operations reading this btree */ - u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ - Btree *pNext; /* List of other sharable Btrees from the same db */ - Btree *pPrev; /* Back pointer of the same list */ -#ifndef SQLITE_OMIT_SHARED_CACHE - BtLock lock; /* Object used to lock page 1 */ -#endif -}; - -/* -** Btree.inTrans may take one of the following values. -** -** If the shared-data extension is enabled, there may be multiple users -** of the Btree structure. At most one of these may open a write transaction, -** but any number may have active read transactions. -*/ -#define TRANS_NONE 0 -#define TRANS_READ 1 -#define TRANS_WRITE 2 - -/* -** An instance of this object represents a single database file. -** -** A single database file can be in use at the same time by two -** or more database connections. When two or more connections are -** sharing the same database file, each connection has it own -** private Btree object for the file and each of those Btrees points -** to this one BtShared object. BtShared.nRef is the number of -** connections currently sharing this database file. -** -** Fields in this structure are accessed under the BtShared.mutex -** mutex, except for nRef and pNext which are accessed under the -** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field -** may not be modified once it is initially set as long as nRef>0. -** The pSchema field may be set once under BtShared.mutex and -** thereafter is unchanged as long as nRef>0. -** -** isPending: -** -** If a BtShared client fails to obtain a write-lock on a database -** table (because there exists one or more read-locks on the table), -** the shared-cache enters 'pending-lock' state and isPending is -** set to true. -** -** The shared-cache leaves the 'pending lock' state when either of -** the following occur: -** -** 1) The current writer (BtShared.pWriter) concludes its transaction, OR -** 2) The number of locks held by other connections drops to zero. -** -** while in the 'pending-lock' state, no connection may start a new -** transaction. -** -** This feature is included to help prevent writer-starvation. -*/ -struct BtShared { - Pager *pPager; /* The page cache */ - sqlite3 *db; /* Database connection currently using this Btree */ - BtCursor *pCursor; /* A list of all open cursors */ - MemPage *pPage1; /* First page of the database */ - u8 openFlags; /* Flags to sqlite3BtreeOpen() */ -#ifndef SQLITE_OMIT_AUTOVACUUM - u8 autoVacuum; /* True if auto-vacuum is enabled */ - u8 incrVacuum; /* True if incr-vacuum is enabled */ - u8 bDoTruncate; /* True to truncate db on commit */ -#endif - u8 inTransaction; /* Transaction state */ - u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ -#ifdef SQLITE_HAS_CODEC - u8 optimalReserve; /* Desired amount of reserved space per page */ -#endif - u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ - u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ - u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ - u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ - u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ - u32 pageSize; /* Total number of bytes on a page */ - u32 usableSize; /* Number of usable bytes on each page */ - int nTransaction; /* Number of open transactions (read + write) */ - u32 nPage; /* Number of pages in the database */ - void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ - void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ - sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ - Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ -#ifndef SQLITE_OMIT_SHARED_CACHE - int nRef; /* Number of references to this structure */ - BtShared *pNext; /* Next on a list of sharable BtShared structs */ - BtLock *pLock; /* List of locks held on this shared-btree struct */ - Btree *pWriter; /* Btree with currently open write transaction */ -#endif - u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ -}; - -/* -** Allowed values for BtShared.btsFlags -*/ -#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ -#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ -#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ -#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */ -#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */ -#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */ -#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */ - -/* -** An instance of the following structure is used to hold information -** about a cell. The parseCellPtr() function fills in this structure -** based on information extract from the raw disk page. -*/ -struct CellInfo { - i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */ - u8 *pPayload; /* Pointer to the start of payload */ - u32 nPayload; /* Bytes of payload */ - u16 nLocal; /* Amount of payload held locally, not on overflow */ - u16 nSize; /* Size of the cell content on the main b-tree page */ -}; - -/* -** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than -** this will be declared corrupt. This value is calculated based on a -** maximum database size of 2^31 pages a minimum fanout of 2 for a -** root-node and 3 for all other internal nodes. -** -** If a tree that appears to be taller than this is encountered, it is -** assumed that the database is corrupt. -*/ -#define BTCURSOR_MAX_DEPTH 20 - -/* -** A cursor is a pointer to a particular entry within a particular -** b-tree within a database file. -** -** The entry is identified by its MemPage and the index in -** MemPage.aCell[] of the entry. -** -** A single database file can be shared by two more database connections, -** but cursors cannot be shared. Each cursor is associated with a -** particular database connection identified BtCursor.pBtree.db. -** -** Fields in this structure are accessed under the BtShared.mutex -** found at self->pBt->mutex. -** -** skipNext meaning: -** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op. -** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op. -** eState==FAULT: Cursor fault with skipNext as error code. -*/ -struct BtCursor { - Btree *pBtree; /* The Btree to which this cursor belongs */ - BtShared *pBt; /* The BtShared this cursor points to */ - BtCursor *pNext; /* Forms a linked list of all cursors */ - Pgno *aOverflow; /* Cache of overflow page locations */ - CellInfo info; /* A parse of the cell we are pointing at */ - i64 nKey; /* Size of pKey, or last integer key */ - void *pKey; /* Saved key that was cursor last known position */ - Pgno pgnoRoot; /* The root page of this tree */ - int nOvflAlloc; /* Allocated size of aOverflow[] array */ - int skipNext; /* Prev() is noop if negative. Next() is noop if positive. - ** Error code if eState==CURSOR_FAULT */ - u8 curFlags; /* zero or more BTCF_* flags defined below */ - u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ - u8 eState; /* One of the CURSOR_XXX constants (see below) */ - u8 hints; /* As configured by CursorSetHints() */ - /* All fields above are zeroed when the cursor is allocated. See - ** sqlite3BtreeCursorZero(). Fields that follow must be manually - ** initialized. */ - i8 iPage; /* Index of current page in apPage */ - u8 curIntKey; /* Value of apPage[0]->intKey */ - struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */ - void *padding1; /* Make object size a multiple of 16 */ - u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ -}; - -/* -** Legal values for BtCursor.curFlags -*/ -#define BTCF_WriteFlag 0x01 /* True if a write cursor */ -#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ -#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ -#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ -#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ -#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ - -/* -** Potential values for BtCursor.eState. -** -** CURSOR_INVALID: -** Cursor does not point to a valid entry. This can happen (for example) -** because the table is empty or because BtreeCursorFirst() has not been -** called. -** -** CURSOR_VALID: -** Cursor points to a valid entry. getPayload() etc. may be called. -** -** CURSOR_SKIPNEXT: -** Cursor is valid except that the Cursor.skipNext field is non-zero -** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() -** operation should be a no-op. -** -** CURSOR_REQUIRESEEK: -** The table that this cursor was opened on still exists, but has been -** modified since the cursor was last used. The cursor position is saved -** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in -** this state, restoreCursorPosition() can be called to attempt to -** seek the cursor to the saved position. -** -** CURSOR_FAULT: -** An unrecoverable error (an I/O error or a malloc failure) has occurred -** on a different connection that shares the BtShared cache with this -** cursor. The error has left the cache in an inconsistent state. -** Do nothing else with this cursor. Any attempt to use the cursor -** should return the error code stored in BtCursor.skipNext -*/ -#define CURSOR_INVALID 0 -#define CURSOR_VALID 1 -#define CURSOR_SKIPNEXT 2 -#define CURSOR_REQUIRESEEK 3 -#define CURSOR_FAULT 4 - -/* -** The database page the PENDING_BYTE occupies. This page is never used. -*/ -# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) - -/* -** These macros define the location of the pointer-map entry for a -** database page. The first argument to each is the number of usable -** bytes on each page of the database (often 1024). The second is the -** page number to look up in the pointer map. -** -** PTRMAP_PAGENO returns the database page number of the pointer-map -** page that stores the required pointer. PTRMAP_PTROFFSET returns -** the offset of the requested map entry. -** -** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, -** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be -** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements -** this test. -*/ -#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) -#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1)) -#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) - -/* -** The pointer map is a lookup table that identifies the parent page for -** each child page in the database file. The parent page is the page that -** contains a pointer to the child. Every page in the database contains -** 0 or 1 parent pages. (In this context 'database page' refers -** to any page that is not part of the pointer map itself.) Each pointer map -** entry consists of a single byte 'type' and a 4 byte parent page number. -** The PTRMAP_XXX identifiers below are the valid types. -** -** The purpose of the pointer map is to facility moving pages from one -** position in the file to another as part of autovacuum. When a page -** is moved, the pointer in its parent must be updated to point to the -** new location. The pointer map is used to locate the parent page quickly. -** -** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not -** used in this case. -** -** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number -** is not used in this case. -** -** PTRMAP_OVERFLOW1: The database page is the first page in a list of -** overflow pages. The page number identifies the page that -** contains the cell with a pointer to this overflow page. -** -** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of -** overflow pages. The page-number identifies the previous -** page in the overflow page list. -** -** PTRMAP_BTREE: The database page is a non-root btree page. The page number -** identifies the parent page in the btree. -*/ -#define PTRMAP_ROOTPAGE 1 -#define PTRMAP_FREEPAGE 2 -#define PTRMAP_OVERFLOW1 3 -#define PTRMAP_OVERFLOW2 4 -#define PTRMAP_BTREE 5 - -/* A bunch of assert() statements to check the transaction state variables -** of handle p (type Btree*) are internally consistent. -*/ -#define btreeIntegrity(p) \ - assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ - assert( p->pBt->inTransaction>=p->inTrans ); - - -/* -** The ISAUTOVACUUM macro is used within balance_nonroot() to determine -** if the database supports auto-vacuum or not. Because it is used -** within an expression that is an argument to another macro -** (sqliteMallocRaw), it is not possible to use conditional compilation. -** So, this macro is defined instead. -*/ -#ifndef SQLITE_OMIT_AUTOVACUUM -#define ISAUTOVACUUM (pBt->autoVacuum) -#else -#define ISAUTOVACUUM 0 -#endif - - -/* -** This structure is passed around through all the sanity checking routines -** in order to keep track of some global state information. -** -** The aRef[] array is allocated so that there is 1 bit for each page in -** the database. As the integrity-check proceeds, for each page used in -** the database the corresponding bit is set. This allows integrity-check to -** detect pages that are used twice and orphaned pages (both of which -** indicate corruption). -*/ -typedef struct IntegrityCk IntegrityCk; -struct IntegrityCk { - BtShared *pBt; /* The tree being checked out */ - Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ - u8 *aPgRef; /* 1 bit per page in the db (see above) */ - Pgno nPage; /* Number of pages in the database */ - int mxErr; /* Stop accumulating errors when this reaches zero */ - int nErr; /* Number of messages written to zErrMsg so far */ - int mallocFailed; /* A memory allocation error has occurred */ - const char *zPfx; /* Error message prefix */ - int v1, v2; /* Values for up to two %d fields in zPfx */ - StrAccum errMsg; /* Accumulate the error message text here */ - u32 *heap; /* Min-heap used for analyzing cell coverage */ -}; - -/* -** Routines to read or write a two- and four-byte big-endian integer values. -*/ -#define get2byte(x) ((x)[0]<<8 | (x)[1]) -#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) -#define get4byte sqlite3Get4byte -#define put4byte sqlite3Put4byte - -/* -** get2byteAligned(), unlike get2byte(), requires that its argument point to a -** two-byte aligned address. get2bytea() is only used for accessing the -** cell addresses in a btree header. -*/ -#if SQLITE_BYTEORDER==4321 -# define get2byteAligned(x) (*(u16*)(x)) -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && GCC_VERSION>=4008000 -# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) -#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(_MSC_VER) && _MSC_VER>=1300 -# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) -#else -# define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) -#endif - -/************** End of btreeInt.h ********************************************/ -/************** Continuing where we left off in btmutex.c ********************/ -#ifndef SQLITE_OMIT_SHARED_CACHE -#if SQLITE_THREADSAFE - -/* -** Obtain the BtShared mutex associated with B-Tree handle p. Also, -** set BtShared.db to the database handle associated with p and the -** p->locked boolean to true. -*/ -static void lockBtreeMutex(Btree *p){ - assert( p->locked==0 ); - assert( sqlite3_mutex_notheld(p->pBt->mutex) ); - assert( sqlite3_mutex_held(p->db->mutex) ); - - sqlite3_mutex_enter(p->pBt->mutex); - p->pBt->db = p->db; - p->locked = 1; -} - -/* -** Release the BtShared mutex associated with B-Tree handle p and -** clear the p->locked boolean. -*/ -static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ - BtShared *pBt = p->pBt; - assert( p->locked==1 ); - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( sqlite3_mutex_held(p->db->mutex) ); - assert( p->db==pBt->db ); - - sqlite3_mutex_leave(pBt->mutex); - p->locked = 0; -} - -/* Forward reference */ -static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); - -/* -** Enter a mutex on the given BTree object. -** -** If the object is not sharable, then no mutex is ever required -** and this routine is a no-op. The underlying mutex is non-recursive. -** But we keep a reference count in Btree.wantToLock so the behavior -** of this interface is recursive. -** -** To avoid deadlocks, multiple Btrees are locked in the same order -** by all database connections. The p->pNext is a list of other -** Btrees belonging to the same database connection as the p Btree -** which need to be locked after p. If we cannot get a lock on -** p, then first unlock all of the others on p->pNext, then wait -** for the lock to become available on p, then relock all of the -** subsequent Btrees that desire a lock. -*/ -SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ - /* Some basic sanity checking on the Btree. The list of Btrees - ** connected by pNext and pPrev should be in sorted order by - ** Btree.pBt value. All elements of the list should belong to - ** the same connection. Only shared Btrees are on the list. */ - assert( p->pNext==0 || p->pNext->pBt>p->pBt ); - assert( p->pPrev==0 || p->pPrev->pBtpBt ); - assert( p->pNext==0 || p->pNext->db==p->db ); - assert( p->pPrev==0 || p->pPrev->db==p->db ); - assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); - - /* Check for locking consistency */ - assert( !p->locked || p->wantToLock>0 ); - assert( p->sharable || p->wantToLock==0 ); - - /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->db->mutex) ); - - /* Unless the database is sharable and unlocked, then BtShared.db - ** should already be set correctly. */ - assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); - - if( !p->sharable ) return; - p->wantToLock++; - if( p->locked ) return; - btreeLockCarefully(p); -} - -/* This is a helper function for sqlite3BtreeLock(). By moving -** complex, but seldom used logic, out of sqlite3BtreeLock() and -** into this routine, we avoid unnecessary stack pointer changes -** and thus help the sqlite3BtreeLock() routine to run much faster -** in the common case. -*/ -static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ - Btree *pLater; - - /* In most cases, we should be able to acquire the lock we - ** want without having to go through the ascending lock - ** procedure that follows. Just be sure not to block. - */ - if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ - p->pBt->db = p->db; - p->locked = 1; - return; - } - - /* To avoid deadlock, first release all locks with a larger - ** BtShared address. Then acquire our lock. Then reacquire - ** the other BtShared locks that we used to hold in ascending - ** order. - */ - for(pLater=p->pNext; pLater; pLater=pLater->pNext){ - assert( pLater->sharable ); - assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); - assert( !pLater->locked || pLater->wantToLock>0 ); - if( pLater->locked ){ - unlockBtreeMutex(pLater); - } - } - lockBtreeMutex(p); - for(pLater=p->pNext; pLater; pLater=pLater->pNext){ - if( pLater->wantToLock ){ - lockBtreeMutex(pLater); - } - } -} - - -/* -** Exit the recursive mutex on a Btree. -*/ -SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ - assert( sqlite3_mutex_held(p->db->mutex) ); - if( p->sharable ){ - assert( p->wantToLock>0 ); - p->wantToLock--; - if( p->wantToLock==0 ){ - unlockBtreeMutex(p); - } - } -} - -#ifndef NDEBUG -/* -** Return true if the BtShared mutex is held on the btree, or if the -** B-Tree is not marked as sharable. -** -** This routine is used only from within assert() statements. -*/ -SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ - assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); - assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); - assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); - assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); - - return (p->sharable==0 || p->locked); -} -#endif - - -/* -** Enter the mutex on every Btree associated with a database -** connection. This is needed (for example) prior to parsing -** a statement since we will be comparing table and column names -** against all schemas and we do not want those schemas being -** reset out from under us. -** -** There is a corresponding leave-all procedures. -** -** Enter the mutexes in accending order by BtShared pointer address -** to avoid the possibility of deadlock when two threads with -** two or more btrees in common both try to lock all their btrees -** at the same instant. -*/ -SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ - int i; - Btree *p; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inDb; i++){ - p = db->aDb[i].pBt; - if( p ) sqlite3BtreeEnter(p); - } -} -SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ - int i; - Btree *p; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inDb; i++){ - p = db->aDb[i].pBt; - if( p ) sqlite3BtreeLeave(p); - } -} - -#ifndef NDEBUG -/* -** Return true if the current thread holds the database connection -** mutex and all required BtShared mutexes. -** -** This routine is used inside assert() statements only. -*/ -SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ - int i; - if( !sqlite3_mutex_held(db->mutex) ){ - return 0; - } - for(i=0; inDb; i++){ - Btree *p; - p = db->aDb[i].pBt; - if( p && p->sharable && - (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ - return 0; - } - } - return 1; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Return true if the correct mutexes are held for accessing the -** db->aDb[iDb].pSchema structure. The mutexes required for schema -** access are: -** -** (1) The mutex on db -** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. -** -** If pSchema is not NULL, then iDb is computed from pSchema and -** db using sqlite3SchemaToIndex(). -*/ -SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ - Btree *p; - assert( db!=0 ); - if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); - assert( iDb>=0 && iDbnDb ); - if( !sqlite3_mutex_held(db->mutex) ) return 0; - if( iDb==1 ) return 1; - p = db->aDb[iDb].pBt; - assert( p!=0 ); - return p->sharable==0 || p->locked==1; -} -#endif /* NDEBUG */ - -#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ -/* -** The following are special cases for mutex enter routines for use -** in single threaded applications that use shared cache. Except for -** these two routines, all mutex operations are no-ops in that case and -** are null #defines in btree.h. -** -** If shared cache is disabled, then all btree mutex routines, including -** the ones below, are no-ops and are null #defines in btree.h. -*/ - -SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ - p->pBt->db = p->db; -} -SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ - int i; - for(i=0; inDb; i++){ - Btree *p = db->aDb[i].pBt; - if( p ){ - p->pBt->db = p->db; - } - } -} -#endif /* if SQLITE_THREADSAFE */ - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** Enter a mutex on a Btree given a cursor owned by that Btree. -** -** These entry points are used by incremental I/O only. Enter() is required -** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not -** the build is threadsafe. Leave() is only required by threadsafe builds. -*/ -SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){ - sqlite3BtreeEnter(pCur->pBtree); -} -# if SQLITE_THREADSAFE -SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ - sqlite3BtreeLeave(pCur->pBtree); -} -# endif -#endif /* ifndef SQLITE_OMIT_INCRBLOB */ - -#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */ - -/************** End of btmutex.c *********************************************/ -/************** Begin file btree.c *******************************************/ -/* -** 2004 April 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file implements an external (disk-based) database using BTrees. -** See the header comment on "btreeInt.h" for additional information. -** Including a description of file format and an overview of operation. -*/ -/* #include "btreeInt.h" */ - -/* -** The header string that appears at the beginning of every -** SQLite database. -*/ -static const char zMagicHeader[] = SQLITE_FILE_HEADER; - -/* -** Set this global variable to 1 to enable tracing using the TRACE -** macro. -*/ -#if 0 -int sqlite3BtreeTrace=1; /* True to enable tracing */ -# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} -#else -# define TRACE(X) -#endif - -/* -** Extract a 2-byte big-endian integer from an array of unsigned bytes. -** But if the value is zero, make it 65536. -** -** This routine is used to extract the "offset to cell content area" value -** from the header of a btree page. If the page size is 65536 and the page -** is empty, the offset should be 65536, but the 2-byte value stores zero. -** This routine makes the necessary adjustment to 65536. -*/ -#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) - -/* -** Values passed as the 5th argument to allocateBtreePage() -*/ -#define BTALLOC_ANY 0 /* Allocate any page */ -#define BTALLOC_EXACT 1 /* Allocate exact page if possible */ -#define BTALLOC_LE 2 /* Allocate any page <= the parameter */ - -/* -** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not -** defined, or 0 if it is. For example: -** -** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum); -*/ -#ifndef SQLITE_OMIT_AUTOVACUUM -#define IfNotOmitAV(expr) (expr) -#else -#define IfNotOmitAV(expr) 0 -#endif - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** A list of BtShared objects that are eligible for participation -** in shared cache. This variable has file scope during normal builds, -** but the test harness needs to access it so we make it global for -** test builds. -** -** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER. -*/ -#ifdef SQLITE_TEST -SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; -#else -static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; -#endif -#endif /* SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Enable or disable the shared pager and schema features. -** -** This routine has no effect on existing database connections. -** The shared cache setting effects only future calls to -** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). -*/ -SQLITE_API int sqlite3_enable_shared_cache(int enable){ - sqlite3GlobalConfig.sharedCacheEnabled = enable; - return SQLITE_OK; -} -#endif - - - -#ifdef SQLITE_OMIT_SHARED_CACHE - /* - ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), - ** and clearAllSharedCacheTableLocks() - ** manipulate entries in the BtShared.pLock linked list used to store - ** shared-cache table level locks. If the library is compiled with the - ** shared-cache feature disabled, then there is only ever one user - ** of each BtShared structure and so this locking is not necessary. - ** So define the lock related functions as no-ops. - */ - #define querySharedCacheTableLock(a,b,c) SQLITE_OK - #define setSharedCacheTableLock(a,b,c) SQLITE_OK - #define clearAllSharedCacheTableLocks(a) - #define downgradeAllSharedCacheTableLocks(a) - #define hasSharedCacheTableLock(a,b,c,d) 1 - #define hasReadConflicts(a, b) 0 -#endif - -#ifndef SQLITE_OMIT_SHARED_CACHE - -#ifdef SQLITE_DEBUG -/* -**** This function is only used as part of an assert() statement. *** -** -** Check to see if pBtree holds the required locks to read or write to the -** table with root page iRoot. Return 1 if it does and 0 if not. -** -** For example, when writing to a table with root-page iRoot via -** Btree connection pBtree: -** -** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); -** -** When writing to an index that resides in a sharable database, the -** caller should have first obtained a lock specifying the root page of -** the corresponding table. This makes things a bit more complicated, -** as this module treats each table as a separate structure. To determine -** the table corresponding to the index being written, this -** function has to search through the database schema. -** -** Instead of a lock on the table/index rooted at page iRoot, the caller may -** hold a write-lock on the schema table (root page 1). This is also -** acceptable. -*/ -static int hasSharedCacheTableLock( - Btree *pBtree, /* Handle that must hold lock */ - Pgno iRoot, /* Root page of b-tree */ - int isIndex, /* True if iRoot is the root of an index b-tree */ - int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ -){ - Schema *pSchema = (Schema *)pBtree->pBt->pSchema; - Pgno iTab = 0; - BtLock *pLock; - - /* If this database is not shareable, or if the client is reading - ** and has the read-uncommitted flag set, then no lock is required. - ** Return true immediately. - */ - if( (pBtree->sharable==0) - || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted)) - ){ - return 1; - } - - /* If the client is reading or writing an index and the schema is - ** not loaded, then it is too difficult to actually check to see if - ** the correct locks are held. So do not bother - just return true. - ** This case does not come up very often anyhow. - */ - if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ - return 1; - } - - /* Figure out the root-page that the lock should be held on. For table - ** b-trees, this is just the root page of the b-tree being read or - ** written. For index b-trees, it is the root page of the associated - ** table. */ - if( isIndex ){ - HashElem *p; - for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ - Index *pIdx = (Index *)sqliteHashData(p); - if( pIdx->tnum==(int)iRoot ){ - if( iTab ){ - /* Two or more indexes share the same root page. There must - ** be imposter tables. So just return true. The assert is not - ** useful in that case. */ - return 1; - } - iTab = pIdx->pTable->tnum; - } - } - }else{ - iTab = iRoot; - } - - /* Search for the required lock. Either a write-lock on root-page iTab, a - ** write-lock on the schema table, or (if the client is reading) a - ** read-lock on iTab will suffice. Return 1 if any of these are found. */ - for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ - if( pLock->pBtree==pBtree - && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) - && pLock->eLock>=eLockType - ){ - return 1; - } - } - - /* Failed to find the required lock. */ - return 0; -} -#endif /* SQLITE_DEBUG */ - -#ifdef SQLITE_DEBUG -/* -**** This function may be used as part of assert() statements only. **** -** -** Return true if it would be illegal for pBtree to write into the -** table or index rooted at iRoot because other shared connections are -** simultaneously reading that same table or index. -** -** It is illegal for pBtree to write if some other Btree object that -** shares the same BtShared object is currently reading or writing -** the iRoot table. Except, if the other Btree object has the -** read-uncommitted flag set, then it is OK for the other object to -** have a read cursor. -** -** For example, before writing to any part of the table or index -** rooted at page iRoot, one should call: -** -** assert( !hasReadConflicts(pBtree, iRoot) ); -*/ -static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ - BtCursor *p; - for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - if( p->pgnoRoot==iRoot - && p->pBtree!=pBtree - && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted) - ){ - return 1; - } - } - return 0; -} -#endif /* #ifdef SQLITE_DEBUG */ - -/* -** Query to see if Btree handle p may obtain a lock of type eLock -** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return -** SQLITE_OK if the lock may be obtained (by calling -** setSharedCacheTableLock()), or SQLITE_LOCKED if not. -*/ -static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ - BtShared *pBt = p->pBt; - BtLock *pIter; - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); - assert( p->db!=0 ); - assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 ); - - /* If requesting a write-lock, then the Btree must have an open write - ** transaction on this file. And, obviously, for this to be so there - ** must be an open write transaction on the file itself. - */ - assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); - assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); - - /* This routine is a no-op if the shared-cache is not enabled */ - if( !p->sharable ){ - return SQLITE_OK; - } - - /* If some other connection is holding an exclusive lock, the - ** requested lock may not be obtained. - */ - if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ - sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); - return SQLITE_LOCKED_SHAREDCACHE; - } - - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - /* The condition (pIter->eLock!=eLock) in the following if(...) - ** statement is a simplification of: - ** - ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) - ** - ** since we know that if eLock==WRITE_LOCK, then no other connection - ** may hold a WRITE_LOCK on any table in this file (since there can - ** only be a single writer). - */ - assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); - assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); - if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ - sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); - if( eLock==WRITE_LOCK ){ - assert( p==pBt->pWriter ); - pBt->btsFlags |= BTS_PENDING; - } - return SQLITE_LOCKED_SHAREDCACHE; - } - } - return SQLITE_OK; -} -#endif /* !SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Add a lock on the table with root-page iTable to the shared-btree used -** by Btree handle p. Parameter eLock must be either READ_LOCK or -** WRITE_LOCK. -** -** This function assumes the following: -** -** (a) The specified Btree object p is connected to a sharable -** database (one with the BtShared.sharable flag set), and -** -** (b) No other Btree objects hold a lock that conflicts -** with the requested lock (i.e. querySharedCacheTableLock() has -** already been called and returned SQLITE_OK). -** -** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM -** is returned if a malloc attempt fails. -*/ -static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ - BtShared *pBt = p->pBt; - BtLock *pLock = 0; - BtLock *pIter; - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); - assert( p->db!=0 ); - - /* A connection with the read-uncommitted flag set will never try to - ** obtain a read-lock using this function. The only read-lock obtained - ** by a connection in read-uncommitted mode is on the sqlite_master - ** table, and that lock is obtained in BtreeBeginTrans(). */ - assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK ); - - /* This function should only be called on a sharable b-tree after it - ** has been determined that no other b-tree holds a conflicting lock. */ - assert( p->sharable ); - assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); - - /* First search the list for an existing lock on this table. */ - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - if( pIter->iTable==iTable && pIter->pBtree==p ){ - pLock = pIter; - break; - } - } - - /* If the above search did not find a BtLock struct associating Btree p - ** with table iTable, allocate one and link it into the list. - */ - if( !pLock ){ - pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); - if( !pLock ){ - return SQLITE_NOMEM_BKPT; - } - pLock->iTable = iTable; - pLock->pBtree = p; - pLock->pNext = pBt->pLock; - pBt->pLock = pLock; - } - - /* Set the BtLock.eLock variable to the maximum of the current lock - ** and the requested lock. This means if a write-lock was already held - ** and a read-lock requested, we don't incorrectly downgrade the lock. - */ - assert( WRITE_LOCK>READ_LOCK ); - if( eLock>pLock->eLock ){ - pLock->eLock = eLock; - } - - return SQLITE_OK; -} -#endif /* !SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Release all the table locks (locks obtained via calls to -** the setSharedCacheTableLock() procedure) held by Btree object p. -** -** This function assumes that Btree p has an open read or write -** transaction. If it does not, then the BTS_PENDING flag -** may be incorrectly cleared. -*/ -static void clearAllSharedCacheTableLocks(Btree *p){ - BtShared *pBt = p->pBt; - BtLock **ppIter = &pBt->pLock; - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( p->sharable || 0==*ppIter ); - assert( p->inTrans>0 ); - - while( *ppIter ){ - BtLock *pLock = *ppIter; - assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); - assert( pLock->pBtree->inTrans>=pLock->eLock ); - if( pLock->pBtree==p ){ - *ppIter = pLock->pNext; - assert( pLock->iTable!=1 || pLock==&p->lock ); - if( pLock->iTable!=1 ){ - sqlite3_free(pLock); - } - }else{ - ppIter = &pLock->pNext; - } - } - - assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); - if( pBt->pWriter==p ){ - pBt->pWriter = 0; - pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); - }else if( pBt->nTransaction==2 ){ - /* This function is called when Btree p is concluding its - ** transaction. If there currently exists a writer, and p is not - ** that writer, then the number of locks held by connections other - ** than the writer must be about to drop to zero. In this case - ** set the BTS_PENDING flag to 0. - ** - ** If there is not currently a writer, then BTS_PENDING must - ** be zero already. So this next line is harmless in that case. - */ - pBt->btsFlags &= ~BTS_PENDING; - } -} - -/* -** This function changes all write-locks held by Btree p into read-locks. -*/ -static void downgradeAllSharedCacheTableLocks(Btree *p){ - BtShared *pBt = p->pBt; - if( pBt->pWriter==p ){ - BtLock *pLock; - pBt->pWriter = 0; - pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); - for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ - assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); - pLock->eLock = READ_LOCK; - } - } -} - -#endif /* SQLITE_OMIT_SHARED_CACHE */ - -static void releasePage(MemPage *pPage); /* Forward reference */ - -/* -***** This routine is used inside of assert() only **** -** -** Verify that the cursor holds the mutex on its BtShared -*/ -#ifdef SQLITE_DEBUG -static int cursorHoldsMutex(BtCursor *p){ - return sqlite3_mutex_held(p->pBt->mutex); -} - -/* Verify that the cursor and the BtShared agree about what is the current -** database connetion. This is important in shared-cache mode. If the database -** connection pointers get out-of-sync, it is possible for routines like -** btreeInitPage() to reference an stale connection pointer that references a -** a connection that has already closed. This routine is used inside assert() -** statements only and for the purpose of double-checking that the btree code -** does keep the database connection pointers up-to-date. -*/ -static int cursorOwnsBtShared(BtCursor *p){ - assert( cursorHoldsMutex(p) ); - return (p->pBtree->db==p->pBt->db); -} -#endif - -/* -** Invalidate the overflow cache of the cursor passed as the first argument. -** on the shared btree structure pBt. -*/ -#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) - -/* -** Invalidate the overflow page-list cache for all cursors opened -** on the shared btree structure pBt. -*/ -static void invalidateAllOverflowCache(BtShared *pBt){ - BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); - for(p=pBt->pCursor; p; p=p->pNext){ - invalidateOverflowCache(p); - } -} - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** This function is called before modifying the contents of a table -** to invalidate any incrblob cursors that are open on the -** row or one of the rows being modified. -** -** If argument isClearTable is true, then the entire contents of the -** table is about to be deleted. In this case invalidate all incrblob -** cursors open on any row within the table with root-page pgnoRoot. -** -** Otherwise, if argument isClearTable is false, then the row with -** rowid iRow is being replaced or deleted. In this case invalidate -** only those incrblob cursors open on that specific row. -*/ -static void invalidateIncrblobCursors( - Btree *pBtree, /* The database file to check */ - i64 iRow, /* The rowid that might be changing */ - int isClearTable /* True if all rows are being deleted */ -){ - BtCursor *p; - if( pBtree->hasIncrblobCur==0 ) return; - assert( sqlite3BtreeHoldsMutex(pBtree) ); - pBtree->hasIncrblobCur = 0; - for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - if( (p->curFlags & BTCF_Incrblob)!=0 ){ - pBtree->hasIncrblobCur = 1; - if( isClearTable || p->info.nKey==iRow ){ - p->eState = CURSOR_INVALID; - } - } - } -} - -#else - /* Stub function when INCRBLOB is omitted */ - #define invalidateIncrblobCursors(x,y,z) -#endif /* SQLITE_OMIT_INCRBLOB */ - -/* -** Set bit pgno of the BtShared.pHasContent bitvec. This is called -** when a page that previously contained data becomes a free-list leaf -** page. -** -** The BtShared.pHasContent bitvec exists to work around an obscure -** bug caused by the interaction of two useful IO optimizations surrounding -** free-list leaf pages: -** -** 1) When all data is deleted from a page and the page becomes -** a free-list leaf page, the page is not written to the database -** (as free-list leaf pages contain no meaningful data). Sometimes -** such a page is not even journalled (as it will not be modified, -** why bother journalling it?). -** -** 2) When a free-list leaf page is reused, its content is not read -** from the database or written to the journal file (why should it -** be, if it is not at all meaningful?). -** -** By themselves, these optimizations work fine and provide a handy -** performance boost to bulk delete or insert operations. However, if -** a page is moved to the free-list and then reused within the same -** transaction, a problem comes up. If the page is not journalled when -** it is moved to the free-list and it is also not journalled when it -** is extracted from the free-list and reused, then the original data -** may be lost. In the event of a rollback, it may not be possible -** to restore the database to its original configuration. -** -** The solution is the BtShared.pHasContent bitvec. Whenever a page is -** moved to become a free-list leaf page, the corresponding bit is -** set in the bitvec. Whenever a leaf page is extracted from the free-list, -** optimization 2 above is omitted if the corresponding bit is already -** set in BtShared.pHasContent. The contents of the bitvec are cleared -** at the end of every transaction. -*/ -static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ - int rc = SQLITE_OK; - if( !pBt->pHasContent ){ - assert( pgno<=pBt->nPage ); - pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); - if( !pBt->pHasContent ){ - rc = SQLITE_NOMEM_BKPT; - } - } - if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ - rc = sqlite3BitvecSet(pBt->pHasContent, pgno); - } - return rc; -} - -/* -** Query the BtShared.pHasContent vector. -** -** This function is called when a free-list leaf page is removed from the -** free-list for reuse. It returns false if it is safe to retrieve the -** page from the pager layer with the 'no-content' flag set. True otherwise. -*/ -static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ - Bitvec *p = pBt->pHasContent; - return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); -} - -/* -** Clear (destroy) the BtShared.pHasContent bitvec. This should be -** invoked at the conclusion of each write-transaction. -*/ -static void btreeClearHasContent(BtShared *pBt){ - sqlite3BitvecDestroy(pBt->pHasContent); - pBt->pHasContent = 0; -} - -/* -** Release all of the apPage[] pages for a cursor. -*/ -static void btreeReleaseAllCursorPages(BtCursor *pCur){ - int i; - for(i=0; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - pCur->apPage[i] = 0; - } - pCur->iPage = -1; -} - -/* -** The cursor passed as the only argument must point to a valid entry -** when this function is called (i.e. have eState==CURSOR_VALID). This -** function saves the current cursor key in variables pCur->nKey and -** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error -** code otherwise. -** -** If the cursor is open on an intkey table, then the integer key -** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to -** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is -** set to point to a malloced buffer pCur->nKey bytes in size containing -** the key. -*/ -static int saveCursorKey(BtCursor *pCur){ - int rc = SQLITE_OK; - assert( CURSOR_VALID==pCur->eState ); - assert( 0==pCur->pKey ); - assert( cursorHoldsMutex(pCur) ); - - if( pCur->curIntKey ){ - /* Only the rowid is required for a table btree */ - pCur->nKey = sqlite3BtreeIntegerKey(pCur); - }else{ - /* For an index btree, save the complete key content */ - void *pKey; - pCur->nKey = sqlite3BtreePayloadSize(pCur); - pKey = sqlite3Malloc( pCur->nKey ); - if( pKey ){ - rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); - if( rc==SQLITE_OK ){ - pCur->pKey = pKey; - }else{ - sqlite3_free(pKey); - } - }else{ - rc = SQLITE_NOMEM_BKPT; - } - } - assert( !pCur->curIntKey || !pCur->pKey ); - return rc; -} - -/* -** Save the current cursor position in the variables BtCursor.nKey -** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. -** -** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) -** prior to calling this routine. -*/ -static int saveCursorPosition(BtCursor *pCur){ - int rc; - - assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState ); - assert( 0==pCur->pKey ); - assert( cursorHoldsMutex(pCur) ); - - if( pCur->eState==CURSOR_SKIPNEXT ){ - pCur->eState = CURSOR_VALID; - }else{ - pCur->skipNext = 0; - } - - rc = saveCursorKey(pCur); - if( rc==SQLITE_OK ){ - btreeReleaseAllCursorPages(pCur); - pCur->eState = CURSOR_REQUIRESEEK; - } - - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast); - return rc; -} - -/* Forward reference */ -static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); - -/* -** Save the positions of all cursors (except pExcept) that are open on -** the table with root-page iRoot. "Saving the cursor position" means that -** the location in the btree is remembered in such a way that it can be -** moved back to the same spot after the btree has been modified. This -** routine is called just before cursor pExcept is used to modify the -** table, for example in BtreeDelete() or BtreeInsert(). -** -** If there are two or more cursors on the same btree, then all such -** cursors should have their BTCF_Multiple flag set. The btreeCursor() -** routine enforces that rule. This routine only needs to be called in -** the uncommon case when pExpect has the BTCF_Multiple flag set. -** -** If pExpect!=NULL and if no other cursors are found on the same root-page, -** then the BTCF_Multiple flag on pExpect is cleared, to avoid another -** pointless call to this routine. -** -** Implementation note: This routine merely checks to see if any cursors -** need to be saved. It calls out to saveCursorsOnList() in the (unusual) -** event that cursors are in need to being saved. -*/ -static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ - BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pExcept==0 || pExcept->pBt==pBt ); - for(p=pBt->pCursor; p; p=p->pNext){ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; - } - if( p ) return saveCursorsOnList(p, iRoot, pExcept); - if( pExcept ) pExcept->curFlags &= ~BTCF_Multiple; - return SQLITE_OK; -} - -/* This helper routine to saveAllCursors does the actual work of saving -** the cursors if and when a cursor is found that actually requires saving. -** The common case is that no cursors need to be saved, so this routine is -** broken out from its caller to avoid unnecessary stack pointer movement. -*/ -static int SQLITE_NOINLINE saveCursorsOnList( - BtCursor *p, /* The first cursor that needs saving */ - Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */ - BtCursor *pExcept /* Do not save this cursor */ -){ - do{ - if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ - if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ - int rc = saveCursorPosition(p); - if( SQLITE_OK!=rc ){ - return rc; - } - }else{ - testcase( p->iPage>0 ); - btreeReleaseAllCursorPages(p); - } - } - p = p->pNext; - }while( p ); - return SQLITE_OK; -} - -/* -** Clear the current cursor position. -*/ -SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - sqlite3_free(pCur->pKey); - pCur->pKey = 0; - pCur->eState = CURSOR_INVALID; -} - -/* -** In this version of BtreeMoveto, pKey is a packed index record -** such as is generated by the OP_MakeRecord opcode. Unpack the -** record and then call BtreeMovetoUnpacked() to do the work. -*/ -static int btreeMoveto( - BtCursor *pCur, /* Cursor open on the btree to be searched */ - const void *pKey, /* Packed key if the btree is an index */ - i64 nKey, /* Integer key for tables. Size of pKey for indices */ - int bias, /* Bias search to the high end */ - int *pRes /* Write search results here */ -){ - int rc; /* Status code */ - UnpackedRecord *pIdxKey; /* Unpacked index key */ - char aSpace[384]; /* Temp space for pIdxKey - to avoid a malloc */ - char *pFree = 0; - - if( pKey ){ - assert( nKey==(i64)(int)nKey ); - pIdxKey = sqlite3VdbeAllocUnpackedRecord( - pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree - ); - if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; - sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); - if( pIdxKey->nField==0 ){ - sqlite3DbFree(pCur->pKeyInfo->db, pFree); - return SQLITE_CORRUPT_BKPT; - } - }else{ - pIdxKey = 0; - } - rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); - if( pFree ){ - sqlite3DbFree(pCur->pKeyInfo->db, pFree); - } - return rc; -} - -/* -** Restore the cursor to the position it was in (or as close to as possible) -** when saveCursorPosition() was called. Note that this call deletes the -** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreCursorPosition() call after each -** saveCursorPosition(). -*/ -static int btreeRestoreCursorPosition(BtCursor *pCur){ - int rc; - int skipNext; - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState>=CURSOR_REQUIRESEEK ); - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skipNext; - } - pCur->eState = CURSOR_INVALID; - rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); - if( rc==SQLITE_OK ){ - sqlite3_free(pCur->pKey); - pCur->pKey = 0; - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); - pCur->skipNext |= skipNext; - if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ - pCur->eState = CURSOR_SKIPNEXT; - } - } - return rc; -} - -#define restoreCursorPosition(p) \ - (p->eState>=CURSOR_REQUIRESEEK ? \ - btreeRestoreCursorPosition(p) : \ - SQLITE_OK) - -/* -** Determine whether or not a cursor has moved from the position where -** it was last placed, or has been invalidated for any other reason. -** Cursors can move when the row they are pointing at is deleted out -** from under them, for example. Cursor might also move if a btree -** is rebalanced. -** -** Calling this routine with a NULL cursor pointer returns false. -** -** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor -** back to where it ought to be if this routine returns true. -*/ -SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ - return pCur->eState!=CURSOR_VALID; -} - -/* -** This routine restores a cursor back to its original position after it -** has been moved by some outside activity (such as a btree rebalance or -** a row having been deleted out from under the cursor). -** -** On success, the *pDifferentRow parameter is false if the cursor is left -** pointing at exactly the same row. *pDifferntRow is the row the cursor -** was pointing to has been deleted, forcing the cursor to point to some -** nearby row. -** -** This routine should only be called for a cursor that just returned -** TRUE from sqlite3BtreeCursorHasMoved(). -*/ -SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ - int rc; - - assert( pCur!=0 ); - assert( pCur->eState!=CURSOR_VALID ); - rc = restoreCursorPosition(pCur); - if( rc ){ - *pDifferentRow = 1; - return rc; - } - if( pCur->eState!=CURSOR_VALID ){ - *pDifferentRow = 1; - }else{ - assert( pCur->skipNext==0 ); - *pDifferentRow = 0; - } - return SQLITE_OK; -} - -#ifdef SQLITE_ENABLE_CURSOR_HINTS -/* -** Provide hints to the cursor. The particular hint given (and the type -** and number of the varargs parameters) is determined by the eHintType -** parameter. See the definitions of the BTREE_HINT_* macros for details. -*/ -SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ - /* Used only by system that substitute their own storage engine */ -} -#endif - -/* -** Provide flag hints to the cursor. -*/ -SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ - assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); - pCur->hints = x; -} - - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Given a page number of a regular database page, return the page -** number for the pointer-map page that contains the entry for the -** input page number. -** -** Return 0 (not a valid page) for pgno==1 since there is -** no pointer map associated with page 1. The integrity_check logic -** requires that ptrmapPageno(*,1)!=1. -*/ -static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ - int nPagesPerMapPage; - Pgno iPtrMap, ret; - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno<2 ) return 0; - nPagesPerMapPage = (pBt->usableSize/5)+1; - iPtrMap = (pgno-2)/nPagesPerMapPage; - ret = (iPtrMap*nPagesPerMapPage) + 2; - if( ret==PENDING_BYTE_PAGE(pBt) ){ - ret++; - } - return ret; -} - -/* -** Write an entry into the pointer map. -** -** This routine updates the pointer map entry for page number 'key' -** so that it maps to type 'eType' and parent page number 'pgno'. -** -** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is -** a no-op. If an error occurs, the appropriate error code is written -** into *pRC. -*/ -static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ - DbPage *pDbPage; /* The pointer map page */ - u8 *pPtrmap; /* The pointer map data */ - Pgno iPtrmap; /* The pointer map page number */ - int offset; /* Offset in pointer map page */ - int rc; /* Return code from subfunctions */ - - if( *pRC ) return; - - assert( sqlite3_mutex_held(pBt->mutex) ); - /* The master-journal page number must never be used as a pointer map page */ - assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); - - assert( pBt->autoVacuum ); - if( key==0 ){ - *pRC = SQLITE_CORRUPT_BKPT; - return; - } - iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); - if( rc!=SQLITE_OK ){ - *pRC = rc; - return; - } - offset = PTRMAP_PTROFFSET(iPtrmap, key); - if( offset<0 ){ - *pRC = SQLITE_CORRUPT_BKPT; - goto ptrmap_exit; - } - assert( offset <= (int)pBt->usableSize-5 ); - pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); - - if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ - TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); - *pRC= rc = sqlite3PagerWrite(pDbPage); - if( rc==SQLITE_OK ){ - pPtrmap[offset] = eType; - put4byte(&pPtrmap[offset+1], parent); - } - } - -ptrmap_exit: - sqlite3PagerUnref(pDbPage); -} - -/* -** Read an entry from the pointer map. -** -** This routine retrieves the pointer map entry for page 'key', writing -** the type and parent page number to *pEType and *pPgno respectively. -** An error code is returned if something goes wrong, otherwise SQLITE_OK. -*/ -static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ - DbPage *pDbPage; /* The pointer map page */ - int iPtrmap; /* Pointer map page index */ - u8 *pPtrmap; /* Pointer map page data */ - int offset; /* Offset of entry in pointer map */ - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - - iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); - if( rc!=0 ){ - return rc; - } - pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); - - offset = PTRMAP_PTROFFSET(iPtrmap, key); - if( offset<0 ){ - sqlite3PagerUnref(pDbPage); - return SQLITE_CORRUPT_BKPT; - } - assert( offset <= (int)pBt->usableSize-5 ); - assert( pEType!=0 ); - *pEType = pPtrmap[offset]; - if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); - - sqlite3PagerUnref(pDbPage); - if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT; - return SQLITE_OK; -} - -#else /* if defined SQLITE_OMIT_AUTOVACUUM */ - #define ptrmapPut(w,x,y,z,rc) - #define ptrmapGet(w,x,y,z) SQLITE_OK - #define ptrmapPutOvflPtr(x, y, rc) -#endif - -/* -** Given a btree page and a cell index (0 means the first cell on -** the page, 1 means the second cell, and so forth) return a pointer -** to the cell content. -** -** findCellPastPtr() does the same except it skips past the initial -** 4-byte child pointer found on interior pages, if there is one. -** -** This routine works only for pages that do not contain overflow cells. -*/ -#define findCell(P,I) \ - ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) -#define findCellPastPtr(P,I) \ - ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) - - -/* -** This is common tail processing for btreeParseCellPtr() and -** btreeParseCellPtrIndex() for the case when the cell does not fit entirely -** on a single B-tree page. Make necessary adjustments to the CellInfo -** structure. -*/ -static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( - MemPage *pPage, /* Page containing the cell */ - u8 *pCell, /* Pointer to the cell text. */ - CellInfo *pInfo /* Fill in this structure */ -){ - /* If the payload will not fit completely on the local page, we have - ** to decide how much to store locally and how much to spill onto - ** overflow pages. The strategy is to minimize the amount of unused - ** space on overflow pages while keeping the amount of local storage - ** in between minLocal and maxLocal. - ** - ** Warning: changing the way overflow payload is distributed in any - ** way will result in an incompatible file format. - */ - int minLocal; /* Minimum amount of payload held locally */ - int maxLocal; /* Maximum amount of payload held locally */ - int surplus; /* Overflow payload available for local storage */ - - minLocal = pPage->minLocal; - maxLocal = pPage->maxLocal; - surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4); - testcase( surplus==maxLocal ); - testcase( surplus==maxLocal+1 ); - if( surplus <= maxLocal ){ - pInfo->nLocal = (u16)surplus; - }else{ - pInfo->nLocal = (u16)minLocal; - } - pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; -} - -/* -** The following routines are implementations of the MemPage.xParseCell() -** method. -** -** Parse a cell content block and fill in the CellInfo structure. -** -** btreeParseCellPtr() => table btree leaf nodes -** btreeParseCellNoPayload() => table btree internal nodes -** btreeParseCellPtrIndex() => index btree nodes -** -** There is also a wrapper function btreeParseCell() that works for -** all MemPage types and that references the cell by index rather than -** by pointer. -*/ -static void btreeParseCellPtrNoPayload( - MemPage *pPage, /* Page containing the cell */ - u8 *pCell, /* Pointer to the cell text. */ - CellInfo *pInfo /* Fill in this structure */ -){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->leaf==0 ); - assert( pPage->childPtrSize==4 ); -#ifndef SQLITE_DEBUG - UNUSED_PARAMETER(pPage); -#endif - pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); - pInfo->nPayload = 0; - pInfo->nLocal = 0; - pInfo->pPayload = 0; - return; -} -static void btreeParseCellPtr( - MemPage *pPage, /* Page containing the cell */ - u8 *pCell, /* Pointer to the cell text. */ - CellInfo *pInfo /* Fill in this structure */ -){ - u8 *pIter; /* For scanning through pCell */ - u32 nPayload; /* Number of bytes of cell payload */ - u64 iKey; /* Extracted Key value */ - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->leaf==0 || pPage->leaf==1 ); - assert( pPage->intKeyLeaf ); - assert( pPage->childPtrSize==0 ); - pIter = pCell; - - /* The next block of code is equivalent to: - ** - ** pIter += getVarint32(pIter, nPayload); - ** - ** The code is inlined to avoid a function call. - */ - nPayload = *pIter; - if( nPayload>=0x80 ){ - u8 *pEnd = &pIter[8]; - nPayload &= 0x7f; - do{ - nPayload = (nPayload<<7) | (*++pIter & 0x7f); - }while( (*pIter)>=0x80 && pIternKey); - ** - ** The code is inlined to avoid a function call. - */ - iKey = *pIter; - if( iKey>=0x80 ){ - u8 *pEnd = &pIter[7]; - iKey &= 0x7f; - while(1){ - iKey = (iKey<<7) | (*++pIter & 0x7f); - if( (*pIter)<0x80 ) break; - if( pIter>=pEnd ){ - iKey = (iKey<<8) | *++pIter; - break; - } - } - } - pIter++; - - pInfo->nKey = *(i64*)&iKey; - pInfo->nPayload = nPayload; - pInfo->pPayload = pIter; - testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); - if( nPayload<=pPage->maxLocal ){ - /* This is the (easy) common case where the entire payload fits - ** on the local page. No overflow is required. - */ - pInfo->nSize = nPayload + (u16)(pIter - pCell); - if( pInfo->nSize<4 ) pInfo->nSize = 4; - pInfo->nLocal = (u16)nPayload; - }else{ - btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); - } -} -static void btreeParseCellPtrIndex( - MemPage *pPage, /* Page containing the cell */ - u8 *pCell, /* Pointer to the cell text. */ - CellInfo *pInfo /* Fill in this structure */ -){ - u8 *pIter; /* For scanning through pCell */ - u32 nPayload; /* Number of bytes of cell payload */ - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->leaf==0 || pPage->leaf==1 ); - assert( pPage->intKeyLeaf==0 ); - pIter = pCell + pPage->childPtrSize; - nPayload = *pIter; - if( nPayload>=0x80 ){ - u8 *pEnd = &pIter[8]; - nPayload &= 0x7f; - do{ - nPayload = (nPayload<<7) | (*++pIter & 0x7f); - }while( *(pIter)>=0x80 && pIternKey = nPayload; - pInfo->nPayload = nPayload; - pInfo->pPayload = pIter; - testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); - if( nPayload<=pPage->maxLocal ){ - /* This is the (easy) common case where the entire payload fits - ** on the local page. No overflow is required. - */ - pInfo->nSize = nPayload + (u16)(pIter - pCell); - if( pInfo->nSize<4 ) pInfo->nSize = 4; - pInfo->nLocal = (u16)nPayload; - }else{ - btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); - } -} -static void btreeParseCell( - MemPage *pPage, /* Page containing the cell */ - int iCell, /* The cell index. First cell is 0 */ - CellInfo *pInfo /* Fill in this structure */ -){ - pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo); -} - -/* -** The following routines are implementations of the MemPage.xCellSize -** method. -** -** Compute the total number of bytes that a Cell needs in the cell -** data area of the btree-page. The return number includes the cell -** data header and the local payload, but not any overflow page or -** the space used by the cell pointer. -** -** cellSizePtrNoPayload() => table internal nodes -** cellSizePtr() => all index nodes & table leaf nodes -*/ -static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ - u8 *pEnd; /* End mark for a varint */ - u32 nSize; /* Size value to return */ - -#ifdef SQLITE_DEBUG - /* The value returned by this function should always be the same as - ** the (CellInfo.nSize) value found by doing a full parse of the - ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of - ** this function verifies that this invariant is not violated. */ - CellInfo debuginfo; - pPage->xParseCell(pPage, pCell, &debuginfo); -#endif - - nSize = *pIter; - if( nSize>=0x80 ){ - pEnd = &pIter[8]; - nSize &= 0x7f; - do{ - nSize = (nSize<<7) | (*++pIter & 0x7f); - }while( *(pIter)>=0x80 && pIterintKey ){ - /* pIter now points at the 64-bit integer key value, a variable length - ** integer. The following block moves pIter to point at the first byte - ** past the end of the key value. */ - pEnd = &pIter[9]; - while( (*pIter++)&0x80 && pItermaxLocal ); - testcase( nSize==pPage->maxLocal+1 ); - if( nSize<=pPage->maxLocal ){ - nSize += (u32)(pIter - pCell); - if( nSize<4 ) nSize = 4; - }else{ - int minLocal = pPage->minLocal; - nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); - testcase( nSize==pPage->maxLocal ); - testcase( nSize==pPage->maxLocal+1 ); - if( nSize>pPage->maxLocal ){ - nSize = minLocal; - } - nSize += 4 + (u16)(pIter - pCell); - } - assert( nSize==debuginfo.nSize || CORRUPT_DB ); - return (u16)nSize; -} -static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ - u8 *pEnd; /* End mark for a varint */ - -#ifdef SQLITE_DEBUG - /* The value returned by this function should always be the same as - ** the (CellInfo.nSize) value found by doing a full parse of the - ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of - ** this function verifies that this invariant is not violated. */ - CellInfo debuginfo; - pPage->xParseCell(pPage, pCell, &debuginfo); -#else - UNUSED_PARAMETER(pPage); -#endif - - assert( pPage->childPtrSize==4 ); - pEnd = pIter + 9; - while( (*pIter++)&0x80 && pIterxCellSize(pPage, findCell(pPage, iCell)); -} -#endif - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** If the cell pCell, part of page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. -*/ -static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ - CellInfo info; - if( *pRC ) return; - assert( pCell!=0 ); - pPage->xParseCell(pPage, pCell, &info); - if( info.nLocalpBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); - } -} -#endif - - -/* -** Defragment the page given. All Cells are moved to the -** end of the page and all free space is collected into one -** big FreeBlk that occurs in between the header and cell -** pointer array and the cell content area. -** -** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a -** b-tree page so that there are no freeblocks or fragment bytes, all -** unused bytes are contained in the unallocated space region, and all -** cells are packed tightly at the end of the page. -*/ -static int defragmentPage(MemPage *pPage){ - int i; /* Loop counter */ - int pc; /* Address of the i-th cell */ - int hdr; /* Offset to the page header */ - int size; /* Size of a cell */ - int usableSize; /* Number of usable bytes on a page */ - int cellOffset; /* Offset to the cell pointer array */ - int cbrk; /* Offset to the cell content area */ - int nCell; /* Number of cells on the page */ - unsigned char *data; /* The page data */ - unsigned char *temp; /* Temp area for cell content */ - unsigned char *src; /* Source of content */ - int iCellFirst; /* First allowable cell index */ - int iCellLast; /* Last possible cell index */ - - - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( pPage->pBt!=0 ); - assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); - assert( pPage->nOverflow==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - temp = 0; - src = data = pPage->aData; - hdr = pPage->hdrOffset; - cellOffset = pPage->cellOffset; - nCell = pPage->nCell; - assert( nCell==get2byte(&data[hdr+3]) ); - usableSize = pPage->pBt->usableSize; - cbrk = usableSize; - iCellFirst = cellOffset + 2*nCell; - iCellLast = usableSize - 4; - for(i=0; iiCellLast ){ - return SQLITE_CORRUPT_BKPT; - } - assert( pc>=iCellFirst && pc<=iCellLast ); - size = pPage->xCellSize(pPage, &src[pc]); - cbrk -= size; - if( cbrkusableSize ){ - return SQLITE_CORRUPT_BKPT; - } - assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); - testcase( cbrk+size==usableSize ); - testcase( pc+size==usableSize ); - put2byte(pAddr, cbrk); - if( temp==0 ){ - int x; - if( cbrk==pc ) continue; - temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - x = get2byte(&data[hdr+5]); - memcpy(&temp[x], &data[x], (cbrk+size) - x); - src = temp; - } - memcpy(&data[cbrk], &src[pc], size); - } - assert( cbrk>=iCellFirst ); - put2byte(&data[hdr+5], cbrk); - data[hdr+1] = 0; - data[hdr+2] = 0; - data[hdr+7] = 0; - memset(&data[iCellFirst], 0, cbrk-iCellFirst); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - if( cbrk-iCellFirst!=pPage->nFree ){ - return SQLITE_CORRUPT_BKPT; - } - return SQLITE_OK; -} - -/* -** Search the free-list on page pPg for space to store a cell nByte bytes in -** size. If one can be found, return a pointer to the space and remove it -** from the free-list. -** -** If no suitable space can be found on the free-list, return NULL. -** -** This function may detect corruption within pPg. If corruption is -** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned. -** -** Slots on the free list that are between 1 and 3 bytes larger than nByte -** will be ignored if adding the extra space to the fragmentation count -** causes the fragmentation count to exceed 60. -*/ -static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ - const int hdr = pPg->hdrOffset; - u8 * const aData = pPg->aData; - int iAddr = hdr + 1; - int pc = get2byte(&aData[iAddr]); - int x; - int usableSize = pPg->pBt->usableSize; - - assert( pc>0 ); - do{ - int size; /* Size of the free slot */ - /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of - ** increasing offset. */ - if( pc>usableSize-4 || pc=0 ){ - testcase( x==4 ); - testcase( x==3 ); - if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ - *pRc = SQLITE_CORRUPT_BKPT; - return 0; - }else if( x<4 ){ - /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total - ** number of bytes in fragments may not exceed 60. */ - if( aData[hdr+7]>57 ) return 0; - - /* Remove the slot from the free-list. Update the number of - ** fragmented bytes within the page. */ - memcpy(&aData[iAddr], &aData[pc], 2); - aData[hdr+7] += (u8)x; - }else{ - /* The slot remains on the free-list. Reduce its size to account - ** for the portion used by the new allocation. */ - put2byte(&aData[pc+2], x); - } - return &aData[pc + x]; - } - iAddr = pc; - pc = get2byte(&aData[pc]); - }while( pc ); - - return 0; -} - -/* -** Allocate nByte bytes of space from within the B-Tree page passed -** as the first argument. Write into *pIdx the index into pPage->aData[] -** of the first byte of allocated space. Return either SQLITE_OK or -** an error code (usually SQLITE_CORRUPT). -** -** The caller guarantees that there is sufficient space to make the -** allocation. This routine might need to defragment in order to bring -** all the space together, however. This routine will avoid using -** the first two bytes past the cell pointer area since presumably this -** allocation is being made in order to insert a new cell, so we will -** also end up needing a new cell pointer. -*/ -static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ - const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ - u8 * const data = pPage->aData; /* Local cache of pPage->aData */ - int top; /* First byte of cell content area */ - int rc = SQLITE_OK; /* Integer return code */ - int gap; /* First byte of gap between cell pointers and cell content */ - - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( pPage->pBt ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( nByte>=0 ); /* Minimum cell size is 4 */ - assert( pPage->nFree>=nByte ); - assert( pPage->nOverflow==0 ); - assert( nByte < (int)(pPage->pBt->usableSize-8) ); - - assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); - gap = pPage->cellOffset + 2*pPage->nCell; - assert( gap<=65536 ); - /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size - ** and the reserved space is zero (the usual value for reserved space) - ** then the cell content offset of an empty page wants to be 65536. - ** However, that integer is too large to be stored in a 2-byte unsigned - ** integer, so a value of 0 is used in its place. */ - top = get2byte(&data[hdr+5]); - assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */ - if( gap>top ){ - if( top==0 && pPage->pBt->usableSize==65536 ){ - top = 65536; - }else{ - return SQLITE_CORRUPT_BKPT; - } - } - - /* If there is enough space between gap and top for one more cell pointer - ** array entry offset, and if the freelist is not empty, then search the - ** freelist looking for a free slot big enough to satisfy the request. - */ - testcase( gap+2==top ); - testcase( gap+1==top ); - testcase( gap==top ); - if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ - u8 *pSpace = pageFindSlot(pPage, nByte, &rc); - if( pSpace ){ - assert( pSpace>=data && (pSpace - data)<65536 ); - *pIdx = (int)(pSpace - data); - return SQLITE_OK; - }else if( rc ){ - return rc; - } - } - - /* The request could not be fulfilled using a freelist slot. Check - ** to see if defragmentation is necessary. - */ - testcase( gap+2+nByte==top ); - if( gap+2+nByte>top ){ - assert( pPage->nCell>0 || CORRUPT_DB ); - rc = defragmentPage(pPage); - if( rc ) return rc; - top = get2byteNotZero(&data[hdr+5]); - assert( gap+nByte<=top ); - } - - - /* Allocate memory from the gap in between the cell pointer array - ** and the cell content area. The btreeInitPage() call has already - ** validated the freelist. Given that the freelist is valid, there - ** is no way that the allocation can extend off the end of the page. - ** The assert() below verifies the previous sentence. - */ - top -= nByte; - put2byte(&data[hdr+5], top); - assert( top+nByte <= (int)pPage->pBt->usableSize ); - *pIdx = top; - return SQLITE_OK; -} - -/* -** Return a section of the pPage->aData to the freelist. -** The first byte of the new free block is pPage->aData[iStart] -** and the size of the block is iSize bytes. -** -** Adjacent freeblocks are coalesced. -** -** Note that even though the freeblock list was checked by btreeInitPage(), -** that routine will not detect overlap between cells or freeblocks. Nor -** does it detect cells or freeblocks that encrouch into the reserved bytes -** at the end of the page. So do additional corruption checks inside this -** routine and return SQLITE_CORRUPT if any problems are found. -*/ -static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ - u16 iPtr; /* Address of ptr to next freeblock */ - u16 iFreeBlk; /* Address of the next freeblock */ - u8 hdr; /* Page header size. 0 or 100 */ - u8 nFrag = 0; /* Reduction in fragmentation */ - u16 iOrigSize = iSize; /* Original value of iSize */ - u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ - u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ - unsigned char *data = pPage->aData; /* Page content */ - - assert( pPage->pBt!=0 ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); - assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( iSize>=4 ); /* Minimum cell size is 4 */ - assert( iStart<=iLast ); - - /* Overwrite deleted information with zeros when the secure_delete - ** option is enabled */ - if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ - memset(&data[iStart], 0, iSize); - } - - /* The list of freeblocks must be in ascending order. Find the - ** spot on the list where iStart should be inserted. - */ - hdr = pPage->hdrOffset; - iPtr = hdr + 1; - if( data[iPtr+1]==0 && data[iPtr]==0 ){ - iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ - }else{ - while( (iFreeBlk = get2byte(&data[iPtr]))iLast ) return SQLITE_CORRUPT_BKPT; - assert( iFreeBlk>iPtr || iFreeBlk==0 ); - - /* At this point: - ** iFreeBlk: First freeblock after iStart, or zero if none - ** iPtr: The address of a pointer to iFreeBlk - ** - ** Check to see if iFreeBlk should be coalesced onto the end of iStart. - */ - if( iFreeBlk && iEnd+3>=iFreeBlk ){ - nFrag = iFreeBlk - iEnd; - if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT; - iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); - if( iEnd > pPage->pBt->usableSize ) return SQLITE_CORRUPT_BKPT; - iSize = iEnd - iStart; - iFreeBlk = get2byte(&data[iFreeBlk]); - } - - /* If iPtr is another freeblock (that is, if iPtr is not the freelist - ** pointer in the page header) then check to see if iStart should be - ** coalesced onto the end of iPtr. - */ - if( iPtr>hdr+1 ){ - int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); - if( iPtrEnd+3>=iStart ){ - if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT; - nFrag += iStart - iPtrEnd; - iSize = iEnd - iPtr; - iStart = iPtr; - } - } - if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT; - data[hdr+7] -= nFrag; - } - if( iStart==get2byte(&data[hdr+5]) ){ - /* The new freeblock is at the beginning of the cell content area, - ** so just extend the cell content area rather than create another - ** freelist entry */ - if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT; - put2byte(&data[hdr+1], iFreeBlk); - put2byte(&data[hdr+5], iEnd); - }else{ - /* Insert the new freeblock into the freelist */ - put2byte(&data[iPtr], iStart); - put2byte(&data[iStart], iFreeBlk); - put2byte(&data[iStart+2], iSize); - } - pPage->nFree += iOrigSize; - return SQLITE_OK; -} - -/* -** Decode the flags byte (the first byte of the header) for a page -** and initialize fields of the MemPage structure accordingly. -** -** Only the following combinations are supported. Anything different -** indicates a corrupt database files: -** -** PTF_ZERODATA -** PTF_ZERODATA | PTF_LEAF -** PTF_LEAFDATA | PTF_INTKEY -** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF -*/ -static int decodeFlags(MemPage *pPage, int flagByte){ - BtShared *pBt; /* A copy of pPage->pBt */ - - assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); - flagByte &= ~PTF_LEAF; - pPage->childPtrSize = 4-4*pPage->leaf; - pPage->xCellSize = cellSizePtr; - pBt = pPage->pBt; - if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ - /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an - ** interior table b-tree page. */ - assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); - /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a - ** leaf table b-tree page. */ - assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); - pPage->intKey = 1; - if( pPage->leaf ){ - pPage->intKeyLeaf = 1; - pPage->xParseCell = btreeParseCellPtr; - }else{ - pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtrNoPayload; - pPage->xParseCell = btreeParseCellPtrNoPayload; - } - pPage->maxLocal = pBt->maxLeaf; - pPage->minLocal = pBt->minLeaf; - }else if( flagByte==PTF_ZERODATA ){ - /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an - ** interior index b-tree page. */ - assert( (PTF_ZERODATA)==2 ); - /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a - ** leaf index b-tree page. */ - assert( (PTF_ZERODATA|PTF_LEAF)==10 ); - pPage->intKey = 0; - pPage->intKeyLeaf = 0; - pPage->xParseCell = btreeParseCellPtrIndex; - pPage->maxLocal = pBt->maxLocal; - pPage->minLocal = pBt->minLocal; - }else{ - /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is - ** an error. */ - return SQLITE_CORRUPT_BKPT; - } - pPage->max1bytePayload = pBt->max1bytePayload; - return SQLITE_OK; -} - -/* -** Initialize the auxiliary information for a disk block. -** -** Return SQLITE_OK on success. If we see that the page does -** not contain a well-formed database page, then return -** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not -** guarantee that the page is well-formed. It only shows that -** we failed to detect any corruption. -*/ -static int btreeInitPage(MemPage *pPage){ - - assert( pPage->pBt!=0 ); - assert( pPage->pBt->db!=0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); - assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); - assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); - - if( !pPage->isInit ){ - u16 pc; /* Address of a freeblock within pPage->aData[] */ - u8 hdr; /* Offset to beginning of page header */ - u8 *data; /* Equal to pPage->aData */ - BtShared *pBt; /* The main btree structure */ - int usableSize; /* Amount of usable space on each page */ - u16 cellOffset; /* Offset from start of page to first cell pointer */ - int nFree; /* Number of unused bytes on the page */ - int top; /* First byte of the cell content area */ - int iCellFirst; /* First allowable cell or freeblock offset */ - int iCellLast; /* Last possible cell or freeblock offset */ - - pBt = pPage->pBt; - - hdr = pPage->hdrOffset; - data = pPage->aData; - /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating - ** the b-tree page type. */ - if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; - assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); - pPage->maskPage = (u16)(pBt->pageSize - 1); - pPage->nOverflow = 0; - usableSize = pBt->usableSize; - pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize; - pPage->aDataEnd = &data[usableSize]; - pPage->aCellIdx = &data[cellOffset]; - pPage->aDataOfst = &data[pPage->childPtrSize]; - /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates - ** the start of the cell content area. A zero value for this integer is - ** interpreted as 65536. */ - top = get2byteNotZero(&data[hdr+5]); - /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the - ** number of cells on the page. */ - pPage->nCell = get2byte(&data[hdr+3]); - if( pPage->nCell>MX_CELL(pBt) ){ - /* To many cells for a single page. The page must be corrupt */ - return SQLITE_CORRUPT_BKPT; - } - testcase( pPage->nCell==MX_CELL(pBt) ); - /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only - ** possible for a root page of a table that contains no rows) then the - ** offset to the cell content area will equal the page size minus the - ** bytes of reserved space. */ - assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB ); - - /* A malformed database page might cause us to read past the end - ** of page when parsing a cell. - ** - ** The following block of code checks early to see if a cell extends - ** past the end of a page boundary and causes SQLITE_CORRUPT to be - ** returned if it does. - */ - iCellFirst = cellOffset + 2*pPage->nCell; - iCellLast = usableSize - 4; - if( pBt->db->flags & SQLITE_CellSizeCk ){ - int i; /* Index into the cell pointer array */ - int sz; /* Size of a cell */ - - if( !pPage->leaf ) iCellLast--; - for(i=0; inCell; i++){ - pc = get2byteAligned(&data[cellOffset+i*2]); - testcase( pc==iCellFirst ); - testcase( pc==iCellLast ); - if( pciCellLast ){ - return SQLITE_CORRUPT_BKPT; - } - sz = pPage->xCellSize(pPage, &data[pc]); - testcase( pc+sz==usableSize ); - if( pc+sz>usableSize ){ - return SQLITE_CORRUPT_BKPT; - } - } - if( !pPage->leaf ) iCellLast++; - } - - /* Compute the total free space on the page - ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the - ** start of the first freeblock on the page, or is zero if there are no - ** freeblocks. */ - pc = get2byte(&data[hdr+1]); - nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ - while( pc>0 ){ - u16 next, size; - if( pciCellLast ){ - /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will - ** always be at least one cell before the first freeblock. - ** - ** Or, the freeblock is off the end of the page - */ - return SQLITE_CORRUPT_BKPT; - } - next = get2byte(&data[pc]); - size = get2byte(&data[pc+2]); - if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ - /* Free blocks must be in ascending order. And the last byte of - ** the free-block must lie on the database page. */ - return SQLITE_CORRUPT_BKPT; - } - nFree = nFree + size; - pc = next; - } - - /* At this point, nFree contains the sum of the offset to the start - ** of the cell-content area plus the number of free bytes within - ** the cell-content area. If this is greater than the usable-size - ** of the page, then the page must be corrupted. This check also - ** serves to verify that the offset to the start of the cell-content - ** area, according to the page header, lies within the page. - */ - if( nFree>usableSize ){ - return SQLITE_CORRUPT_BKPT; - } - pPage->nFree = (u16)(nFree - iCellFirst); - pPage->isInit = 1; - } - return SQLITE_OK; -} - -/* -** Set up a raw page so that it looks like a database page holding -** no entries. -*/ -static void zeroPage(MemPage *pPage, int flags){ - unsigned char *data = pPage->aData; - BtShared *pBt = pPage->pBt; - u8 hdr = pPage->hdrOffset; - u16 first; - - assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); - assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( sqlite3PagerGetData(pPage->pDbPage) == data ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->btsFlags & BTS_SECURE_DELETE ){ - memset(&data[hdr], 0, pBt->usableSize - hdr); - } - data[hdr] = (char)flags; - first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); - memset(&data[hdr+1], 0, 4); - data[hdr+7] = 0; - put2byte(&data[hdr+5], pBt->usableSize); - pPage->nFree = (u16)(pBt->usableSize - first); - decodeFlags(pPage, flags); - pPage->cellOffset = first; - pPage->aDataEnd = &data[pBt->usableSize]; - pPage->aCellIdx = &data[first]; - pPage->aDataOfst = &data[pPage->childPtrSize]; - pPage->nOverflow = 0; - assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); - pPage->maskPage = (u16)(pBt->pageSize - 1); - pPage->nCell = 0; - pPage->isInit = 1; -} - - -/* -** Convert a DbPage obtained from the pager into a MemPage used by -** the btree layer. -*/ -static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ - MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); - if( pgno!=pPage->pgno ){ - pPage->aData = sqlite3PagerGetData(pDbPage); - pPage->pDbPage = pDbPage; - pPage->pBt = pBt; - pPage->pgno = pgno; - pPage->hdrOffset = pgno==1 ? 100 : 0; - } - assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); - return pPage; -} - -/* -** Get a page from the pager. Initialize the MemPage.pBt and -** MemPage.aData elements if needed. See also: btreeGetUnusedPage(). -** -** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care -** about the content of the page at this time. So do not go to the disk -** to fetch the content. Just fill in the content with zeros for now. -** If in the future we call sqlite3PagerWrite() on this page, that -** means we have started to be concerned about content and the disk -** read should occur at that point. -*/ -static int btreeGetPage( - BtShared *pBt, /* The btree */ - Pgno pgno, /* Number of the page to fetch */ - MemPage **ppPage, /* Return the page in this parameter */ - int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ -){ - int rc; - DbPage *pDbPage; - - assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); - assert( sqlite3_mutex_held(pBt->mutex) ); - rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); - if( rc ) return rc; - *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); - return SQLITE_OK; -} - -/* -** Retrieve a page from the pager cache. If the requested page is not -** already in the pager cache return NULL. Initialize the MemPage.pBt and -** MemPage.aData elements if needed. -*/ -static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ - DbPage *pDbPage; - assert( sqlite3_mutex_held(pBt->mutex) ); - pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); - if( pDbPage ){ - return btreePageFromDbPage(pDbPage, pgno, pBt); - } - return 0; -} - -/* -** Return the size of the database file in pages. If there is any kind of -** error, return ((unsigned int)-1). -*/ -static Pgno btreePagecount(BtShared *pBt){ - return pBt->nPage; -} -SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ - assert( sqlite3BtreeHoldsMutex(p) ); - assert( ((p->pBt->nPage)&0x8000000)==0 ); - return btreePagecount(p->pBt); -} - -/* -** Get a page from the pager and initialize it. -** -** If pCur!=0 then the page is being fetched as part of a moveToChild() -** call. Do additional sanity checking on the page in this case. -** And if the fetch fails, this routine must decrement pCur->iPage. -** -** The page is fetched as read-write unless pCur is not NULL and is -** a read-only cursor. -** -** If an error occurs, then *ppPage is undefined. It -** may remain unchanged, or it may be set to an invalid value. -*/ -static int getAndInitPage( - BtShared *pBt, /* The database file */ - Pgno pgno, /* Number of the page to get */ - MemPage **ppPage, /* Write the page pointer here */ - BtCursor *pCur, /* Cursor to receive the page, or NULL */ - int bReadOnly /* True for a read-only page */ -){ - int rc; - DbPage *pDbPage; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] ); - assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); - assert( pCur==0 || pCur->iPage>0 ); - - if( pgno>btreePagecount(pBt) ){ - rc = SQLITE_CORRUPT_BKPT; - goto getAndInitPage_error; - } - rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); - if( rc ){ - goto getAndInitPage_error; - } - *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); - if( (*ppPage)->isInit==0 ){ - btreePageFromDbPage(pDbPage, pgno, pBt); - rc = btreeInitPage(*ppPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - goto getAndInitPage_error; - } - } - assert( (*ppPage)->pgno==pgno ); - assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); - - /* If obtaining a child page for a cursor, we must verify that the page is - ** compatible with the root page. */ - if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ - rc = SQLITE_CORRUPT_BKPT; - releasePage(*ppPage); - goto getAndInitPage_error; - } - return SQLITE_OK; - -getAndInitPage_error: - if( pCur ) pCur->iPage--; - testcase( pgno==0 ); - assert( pgno!=0 || rc==SQLITE_CORRUPT ); - return rc; -} - -/* -** Release a MemPage. This should be called once for each prior -** call to btreeGetPage. -*/ -static void releasePageNotNull(MemPage *pPage){ - assert( pPage->aData ); - assert( pPage->pBt ); - assert( pPage->pDbPage!=0 ); - assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - sqlite3PagerUnrefNotNull(pPage->pDbPage); -} -static void releasePage(MemPage *pPage){ - if( pPage ) releasePageNotNull(pPage); -} - -/* -** Get an unused page. -** -** This works just like btreeGetPage() with the addition: -** -** * If the page is already in use for some other purpose, immediately -** release it and return an SQLITE_CURRUPT error. -** * Make sure the isInit flag is clear -*/ -static int btreeGetUnusedPage( - BtShared *pBt, /* The btree */ - Pgno pgno, /* Number of the page to fetch */ - MemPage **ppPage, /* Return the page in this parameter */ - int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ -){ - int rc = btreeGetPage(pBt, pgno, ppPage, flags); - if( rc==SQLITE_OK ){ - if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ - releasePage(*ppPage); - *ppPage = 0; - return SQLITE_CORRUPT_BKPT; - } - (*ppPage)->isInit = 0; - }else{ - *ppPage = 0; - } - return rc; -} - - -/* -** During a rollback, when the pager reloads information into the cache -** so that the cache is restored to its original state at the start of -** the transaction, for each page restored this routine is called. -** -** This routine needs to reset the extra data section at the end of the -** page to agree with the restored data. -*/ -static void pageReinit(DbPage *pData){ - MemPage *pPage; - pPage = (MemPage *)sqlite3PagerGetExtra(pData); - assert( sqlite3PagerPageRefcount(pData)>0 ); - if( pPage->isInit ){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->isInit = 0; - if( sqlite3PagerPageRefcount(pData)>1 ){ - /* pPage might not be a btree page; it might be an overflow page - ** or ptrmap page or a free page. In those cases, the following - ** call to btreeInitPage() will likely return SQLITE_CORRUPT. - ** But no harm is done by this. And it is very important that - ** btreeInitPage() be called on every btree page so we make - ** the call for every page that comes in for re-initing. */ - btreeInitPage(pPage); - } - } -} - -/* -** Invoke the busy handler for a btree. -*/ -static int btreeInvokeBusyHandler(void *pArg){ - BtShared *pBt = (BtShared*)pArg; - assert( pBt->db ); - assert( sqlite3_mutex_held(pBt->db->mutex) ); - return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); -} - -/* -** Open a database file. -** -** zFilename is the name of the database file. If zFilename is NULL -** then an ephemeral database is created. The ephemeral database might -** be exclusively in memory, or it might use a disk-based memory cache. -** Either way, the ephemeral database will be automatically deleted -** when sqlite3BtreeClose() is called. -** -** If zFilename is ":memory:" then an in-memory database is created -** that is automatically destroyed when it is closed. -** -** The "flags" parameter is a bitmask that might contain bits like -** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY. -** -** If the database is already opened in the same database connection -** and we are in shared cache mode, then the open will fail with an -** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared -** objects in the same database connection since doing so will lead -** to problems with locking. -*/ -SQLITE_PRIVATE int sqlite3BtreeOpen( - sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ - const char *zFilename, /* Name of the file containing the BTree database */ - sqlite3 *db, /* Associated database handle */ - Btree **ppBtree, /* Pointer to new Btree object written here */ - int flags, /* Options */ - int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ -){ - BtShared *pBt = 0; /* Shared part of btree structure */ - Btree *p; /* Handle to return */ - sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ - int rc = SQLITE_OK; /* Result code from this function */ - u8 nReserve; /* Byte of unused space on each page */ - unsigned char zDbHeader[100]; /* Database header content */ - - /* True if opening an ephemeral, temporary database */ - const int isTempDb = zFilename==0 || zFilename[0]==0; - - /* Set the variable isMemdb to true for an in-memory database, or - ** false for a file-based database. - */ -#ifdef SQLITE_OMIT_MEMORYDB - const int isMemdb = 0; -#else - const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) - || (isTempDb && sqlite3TempInMemory(db)) - || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; -#endif - - assert( db!=0 ); - assert( pVfs!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ - - /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ - assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); - - /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ - assert( (flags & BTREE_SINGLE)==0 || isTempDb ); - - if( isMemdb ){ - flags |= BTREE_MEMORY; - } - if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ - vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; - } - p = sqlite3MallocZero(sizeof(Btree)); - if( !p ){ - return SQLITE_NOMEM_BKPT; - } - p->inTrans = TRANS_NONE; - p->db = db; -#ifndef SQLITE_OMIT_SHARED_CACHE - p->lock.pBtree = p; - p->lock.iTable = 1; -#endif - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* - ** If this Btree is a candidate for shared cache, try to find an - ** existing BtShared object that we can share with - */ - if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ - if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ - int nFilename = sqlite3Strlen30(zFilename)+1; - int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); - MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) - - p->sharable = 1; - if( !zFullPathname ){ - sqlite3_free(p); - return SQLITE_NOMEM_BKPT; - } - if( isMemdb ){ - memcpy(zFullPathname, zFilename, nFilename); - }else{ - rc = sqlite3OsFullPathname(pVfs, zFilename, - nFullPathname, zFullPathname); - if( rc ){ - sqlite3_free(zFullPathname); - sqlite3_free(p); - return rc; - } - } -#if SQLITE_THREADSAFE - mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); - sqlite3_mutex_enter(mutexOpen); - mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); - sqlite3_mutex_enter(mutexShared); -#endif - for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ - assert( pBt->nRef>0 ); - if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) - && sqlite3PagerVfs(pBt->pPager)==pVfs ){ - int iDb; - for(iDb=db->nDb-1; iDb>=0; iDb--){ - Btree *pExisting = db->aDb[iDb].pBt; - if( pExisting && pExisting->pBt==pBt ){ - sqlite3_mutex_leave(mutexShared); - sqlite3_mutex_leave(mutexOpen); - sqlite3_free(zFullPathname); - sqlite3_free(p); - return SQLITE_CONSTRAINT; - } - } - p->pBt = pBt; - pBt->nRef++; - break; - } - } - sqlite3_mutex_leave(mutexShared); - sqlite3_free(zFullPathname); - } -#ifdef SQLITE_DEBUG - else{ - /* In debug mode, we mark all persistent databases as sharable - ** even when they are not. This exercises the locking code and - ** gives more opportunity for asserts(sqlite3_mutex_held()) - ** statements to find locking problems. - */ - p->sharable = 1; - } -#endif - } -#endif - if( pBt==0 ){ - /* - ** The following asserts make sure that structures used by the btree are - ** the right size. This is to guard against size changes that result - ** when compiling on a different architecture. - */ - assert( sizeof(i64)==8 ); - assert( sizeof(u64)==8 ); - assert( sizeof(u32)==4 ); - assert( sizeof(u16)==2 ); - assert( sizeof(Pgno)==4 ); - - pBt = sqlite3MallocZero( sizeof(*pBt) ); - if( pBt==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto btree_open_out; - } - rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, - EXTRA_SIZE, flags, vfsFlags, pageReinit); - if( rc==SQLITE_OK ){ - sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); - rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); - } - if( rc!=SQLITE_OK ){ - goto btree_open_out; - } - pBt->openFlags = (u8)flags; - pBt->db = db; - sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); - p->pBt = pBt; - - pBt->pCursor = 0; - pBt->pPage1 = 0; - if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; -#ifdef SQLITE_SECURE_DELETE - pBt->btsFlags |= BTS_SECURE_DELETE; -#endif - /* EVIDENCE-OF: R-51873-39618 The page size for a database file is - ** determined by the 2-byte integer located at an offset of 16 bytes from - ** the beginning of the database file. */ - pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); - if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE - || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ - pBt->pageSize = 0; -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If the magic name ":memory:" will create an in-memory database, then - ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if - ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if - ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a - ** regular file-name. In this case the auto-vacuum applies as per normal. - */ - if( zFilename && !isMemdb ){ - pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); - pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); - } -#endif - nReserve = 0; - }else{ - /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is - ** determined by the one-byte unsigned integer found at an offset of 20 - ** into the database file header. */ - nReserve = zDbHeader[20]; - pBt->btsFlags |= BTS_PAGESIZE_FIXED; -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); - pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); -#endif - } - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); - if( rc ) goto btree_open_out; - pBt->usableSize = pBt->pageSize - nReserve; - assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* Add the new BtShared object to the linked list sharable BtShareds. - */ - pBt->nRef = 1; - if( p->sharable ){ - MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) - MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) - if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ - pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); - if( pBt->mutex==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto btree_open_out; - } - } - sqlite3_mutex_enter(mutexShared); - pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); - GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; - sqlite3_mutex_leave(mutexShared); - } -#endif - } - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) - /* If the new Btree uses a sharable pBtShared, then link the new - ** Btree into the list of all sharable Btrees for the same connection. - ** The list is kept in ascending order by pBt address. - */ - if( p->sharable ){ - int i; - Btree *pSib; - for(i=0; inDb; i++){ - if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ - while( pSib->pPrev ){ pSib = pSib->pPrev; } - if( (uptr)p->pBt<(uptr)pSib->pBt ){ - p->pNext = pSib; - p->pPrev = 0; - pSib->pPrev = p; - }else{ - while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ - pSib = pSib->pNext; - } - p->pNext = pSib->pNext; - p->pPrev = pSib; - if( p->pNext ){ - p->pNext->pPrev = p; - } - pSib->pNext = p; - } - break; - } - } - } -#endif - *ppBtree = p; - -btree_open_out: - if( rc!=SQLITE_OK ){ - if( pBt && pBt->pPager ){ - sqlite3PagerClose(pBt->pPager); - } - sqlite3_free(pBt); - sqlite3_free(p); - *ppBtree = 0; - }else{ - /* If the B-Tree was successfully opened, set the pager-cache size to the - ** default value. Except, when opening on an existing shared pager-cache, - ** do not change the pager-cache size. - */ - if( sqlite3BtreeSchema(p, 0, 0)==0 ){ - sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); - } - } - if( mutexOpen ){ - assert( sqlite3_mutex_held(mutexOpen) ); - sqlite3_mutex_leave(mutexOpen); - } - assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 ); - return rc; -} - -/* -** Decrement the BtShared.nRef counter. When it reaches zero, -** remove the BtShared structure from the sharing list. Return -** true if the BtShared.nRef counter reaches zero and return -** false if it is still positive. -*/ -static int removeFromSharingList(BtShared *pBt){ -#ifndef SQLITE_OMIT_SHARED_CACHE - MUTEX_LOGIC( sqlite3_mutex *pMaster; ) - BtShared *pList; - int removed = 0; - - assert( sqlite3_mutex_notheld(pBt->mutex) ); - MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - sqlite3_mutex_enter(pMaster); - pBt->nRef--; - if( pBt->nRef<=0 ){ - if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ - GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; - }else{ - pList = GLOBAL(BtShared*,sqlite3SharedCacheList); - while( ALWAYS(pList) && pList->pNext!=pBt ){ - pList=pList->pNext; - } - if( ALWAYS(pList) ){ - pList->pNext = pBt->pNext; - } - } - if( SQLITE_THREADSAFE ){ - sqlite3_mutex_free(pBt->mutex); - } - removed = 1; - } - sqlite3_mutex_leave(pMaster); - return removed; -#else - return 1; -#endif -} - -/* -** Make sure pBt->pTmpSpace points to an allocation of -** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child -** pointer. -*/ -static void allocateTempSpace(BtShared *pBt){ - if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); - - /* One of the uses of pBt->pTmpSpace is to format cells before - ** inserting them into a leaf page (function fillInCell()). If - ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes - ** by the various routines that manipulate binary cells. Which - ** can mean that fillInCell() only initializes the first 2 or 3 - ** bytes of pTmpSpace, but that the first 4 bytes are copied from - ** it into a database page. This is not actually a problem, but it - ** does cause a valgrind error when the 1 or 2 bytes of unitialized - ** data is passed to system call write(). So to avoid this error, - ** zero the first 4 bytes of temp space here. - ** - ** Also: Provide four bytes of initialized space before the - ** beginning of pTmpSpace as an area available to prepend the - ** left-child pointer to the beginning of a cell. - */ - if( pBt->pTmpSpace ){ - memset(pBt->pTmpSpace, 0, 8); - pBt->pTmpSpace += 4; - } - } -} - -/* -** Free the pBt->pTmpSpace allocation -*/ -static void freeTempSpace(BtShared *pBt){ - if( pBt->pTmpSpace ){ - pBt->pTmpSpace -= 4; - sqlite3PageFree(pBt->pTmpSpace); - pBt->pTmpSpace = 0; - } -} - -/* -** Close an open database and invalidate all cursors. -*/ -SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ - BtShared *pBt = p->pBt; - BtCursor *pCur; - - /* Close all cursors opened via this handle. */ - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - pCur = pBt->pCursor; - while( pCur ){ - BtCursor *pTmp = pCur; - pCur = pCur->pNext; - if( pTmp->pBtree==p ){ - sqlite3BtreeCloseCursor(pTmp); - } - } - - /* Rollback any active transaction and free the handle structure. - ** The call to sqlite3BtreeRollback() drops any table-locks held by - ** this handle. - */ - sqlite3BtreeRollback(p, SQLITE_OK, 0); - sqlite3BtreeLeave(p); - - /* If there are still other outstanding references to the shared-btree - ** structure, return now. The remainder of this procedure cleans - ** up the shared-btree. - */ - assert( p->wantToLock==0 && p->locked==0 ); - if( !p->sharable || removeFromSharingList(pBt) ){ - /* The pBt is no longer on the sharing list, so we can access - ** it without having to hold the mutex. - ** - ** Clean out and delete the BtShared object. - */ - assert( !pBt->pCursor ); - sqlite3PagerClose(pBt->pPager); - if( pBt->xFreeSchema && pBt->pSchema ){ - pBt->xFreeSchema(pBt->pSchema); - } - sqlite3DbFree(0, pBt->pSchema); - freeTempSpace(pBt); - sqlite3_free(pBt); - } - -#ifndef SQLITE_OMIT_SHARED_CACHE - assert( p->wantToLock==0 ); - assert( p->locked==0 ); - if( p->pPrev ) p->pPrev->pNext = p->pNext; - if( p->pNext ) p->pNext->pPrev = p->pPrev; -#endif - - sqlite3_free(p); - return SQLITE_OK; -} - -/* -** Change the "soft" limit on the number of pages in the cache. -** Unused and unmodified pages will be recycled when the number of -** pages in the cache exceeds this soft limit. But the size of the -** cache is allowed to grow larger than this limit if it contains -** dirty pages or pages still in active use. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - sqlite3PagerSetCachesize(pBt->pPager, mxPage); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} - -/* -** Change the "spill" limit on the number of pages in the cache. -** If the number of pages exceeds this limit during a write transaction, -** the pager might attempt to "spill" pages to the journal early in -** order to free up memory. -** -** The value returned is the current spill size. If zero is passed -** as an argument, no changes are made to the spill size setting, so -** using mxPage of 0 is a way to query the current spill size. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){ - BtShared *pBt = p->pBt; - int res; - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage); - sqlite3BtreeLeave(p); - return res; -} - -#if SQLITE_MAX_MMAP_SIZE>0 -/* -** Change the limit on the amount of the database file that may be -** memory mapped. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ - -/* -** Change the way data is synced to disk in order to increase or decrease -** how well the database resists damage due to OS crashes and power -** failures. Level 1 is the same as asynchronous (no syncs() occur and -** there is a high probability of damage) Level 2 is the default. There -** is a very low but non-zero probability of damage. Level 3 reduces the -** probability of damage to near zero but with a write performance reduction. -*/ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( - Btree *p, /* The btree to set the safety level on */ - unsigned pgFlags /* Various PAGER_* flags */ -){ - BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - sqlite3PagerSetFlags(pBt->pPager, pgFlags); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} -#endif - -/* -** Change the default pages size and the number of reserved bytes per page. -** Or, if the page size has already been fixed, return SQLITE_READONLY -** without changing anything. -** -** The page size must be a power of 2 between 512 and 65536. If the page -** size supplied does not meet this constraint then the page size is not -** changed. -** -** Page sizes are constrained to be a power of two so that the region -** of the database file used for locking (beginning at PENDING_BYTE, -** the first byte past the 1GB boundary, 0x40000000) needs to occur -** at the beginning of a page. -** -** If parameter nReserve is less than zero, then the number of reserved -** bytes per page is left unchanged. -** -** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size -** and autovacuum mode can no longer be changed. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ - int rc = SQLITE_OK; - BtShared *pBt = p->pBt; - assert( nReserve>=-1 && nReserve<=255 ); - sqlite3BtreeEnter(p); -#if SQLITE_HAS_CODEC - if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve; -#endif - if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ - sqlite3BtreeLeave(p); - return SQLITE_READONLY; - } - if( nReserve<0 ){ - nReserve = pBt->pageSize - pBt->usableSize; - } - assert( nReserve>=0 && nReserve<=255 ); - if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && - ((pageSize-1)&pageSize)==0 ){ - assert( (pageSize & 7)==0 ); - assert( !pBt->pCursor ); - pBt->pageSize = (u32)pageSize; - freeTempSpace(pBt); - } - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); - pBt->usableSize = pBt->pageSize - (u16)nReserve; - if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Return the currently defined page size -*/ -SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ - return p->pBt->pageSize; -} - -/* -** This function is similar to sqlite3BtreeGetReserve(), except that it -** may only be called if it is guaranteed that the b-tree mutex is already -** held. -** -** This is useful in one special case in the backup API code where it is -** known that the shared b-tree mutex is held, but the mutex on the -** database handle that owns *p is not. In this case if sqlite3BtreeEnter() -** were to be called, it might collide with some other operation on the -** database handle that owns *p, causing undefined behavior. -*/ -SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ - int n; - assert( sqlite3_mutex_held(p->pBt->mutex) ); - n = p->pBt->pageSize - p->pBt->usableSize; - return n; -} - -/* -** Return the number of bytes of space at the end of every page that -** are intentually left unused. This is the "reserved" space that is -** sometimes used by extensions. -** -** If SQLITE_HAS_MUTEX is defined then the number returned is the -** greater of the current reserved space and the maximum requested -** reserve space. -*/ -SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){ - int n; - sqlite3BtreeEnter(p); - n = sqlite3BtreeGetReserveNoMutex(p); -#ifdef SQLITE_HAS_CODEC - if( npBt->optimalReserve ) n = p->pBt->optimalReserve; -#endif - sqlite3BtreeLeave(p); - return n; -} - - -/* -** Set the maximum page count for a database if mxPage is positive. -** No changes are made if mxPage is 0 or negative. -** Regardless of the value of mxPage, return the maximum page count. -*/ -SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ - int n; - sqlite3BtreeEnter(p); - n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); - sqlite3BtreeLeave(p); - return n; -} - -/* -** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1, -** then make no changes. Always return the value of the BTS_SECURE_DELETE -** setting after the change. -*/ -SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ - int b; - if( p==0 ) return 0; - sqlite3BtreeEnter(p); - if( newFlag>=0 ){ - p->pBt->btsFlags &= ~BTS_SECURE_DELETE; - if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE; - } - b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0; - sqlite3BtreeLeave(p); - return b; -} - -/* -** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' -** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it -** is disabled. The default value for the auto-vacuum property is -** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ -#ifdef SQLITE_OMIT_AUTOVACUUM - return SQLITE_READONLY; -#else - BtShared *pBt = p->pBt; - int rc = SQLITE_OK; - u8 av = (u8)autoVacuum; - - sqlite3BtreeEnter(p); - if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ - rc = SQLITE_READONLY; - }else{ - pBt->autoVacuum = av ?1:0; - pBt->incrVacuum = av==2 ?1:0; - } - sqlite3BtreeLeave(p); - return rc; -#endif -} - -/* -** Return the value of the 'auto-vacuum' property. If auto-vacuum is -** enabled 1 is returned. Otherwise 0. -*/ -SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ -#ifdef SQLITE_OMIT_AUTOVACUUM - return BTREE_AUTOVACUUM_NONE; -#else - int rc; - sqlite3BtreeEnter(p); - rc = ( - (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: - (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: - BTREE_AUTOVACUUM_INCR - ); - sqlite3BtreeLeave(p); - return rc; -#endif -} - - -/* -** Get a reference to pPage1 of the database file. This will -** also acquire a readlock on that file. -** -** SQLITE_OK is returned on success. If the file is not a -** well-formed database file, then SQLITE_CORRUPT is returned. -** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM -** is returned if we run out of memory. -*/ -static int lockBtree(BtShared *pBt){ - int rc; /* Result code from subfunctions */ - MemPage *pPage1; /* Page 1 of the database file */ - int nPage; /* Number of pages in the database */ - int nPageFile = 0; /* Number of pages in the database file */ - int nPageHeader; /* Number of pages in the database according to hdr */ - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pBt->pPage1==0 ); - rc = sqlite3PagerSharedLock(pBt->pPager); - if( rc!=SQLITE_OK ) return rc; - rc = btreeGetPage(pBt, 1, &pPage1, 0); - if( rc!=SQLITE_OK ) return rc; - - /* Do some checking to help insure the file we opened really is - ** a valid database file. - */ - nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); - sqlite3PagerPagecount(pBt->pPager, &nPageFile); - if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ - nPage = nPageFile; - } - if( nPage>0 ){ - u32 pageSize; - u32 usableSize; - u8 *page1 = pPage1->aData; - rc = SQLITE_NOTADB; - /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins - ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d - ** 61 74 20 33 00. */ - if( memcmp(page1, zMagicHeader, 16)!=0 ){ - goto page1_init_failed; - } - -#ifdef SQLITE_OMIT_WAL - if( page1[18]>1 ){ - pBt->btsFlags |= BTS_READ_ONLY; - } - if( page1[19]>1 ){ - goto page1_init_failed; - } -#else - if( page1[18]>2 ){ - pBt->btsFlags |= BTS_READ_ONLY; - } - if( page1[19]>2 ){ - goto page1_init_failed; - } - - /* If the write version is set to 2, this database should be accessed - ** in WAL mode. If the log is not already open, open it now. Then - ** return SQLITE_OK and return without populating BtShared.pPage1. - ** The caller detects this and calls this function again. This is - ** required as the version of page 1 currently in the page1 buffer - ** may not be the latest version - there may be a newer one in the log - ** file. - */ - if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ - int isOpen = 0; - rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); - if( rc!=SQLITE_OK ){ - goto page1_init_failed; - }else{ -#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS - sqlite3 *db; - Db *pDb; - if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ - while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } - if( pDb->bSyncSet==0 - && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1 - ){ - pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1; - sqlite3PagerSetFlags(pBt->pPager, - pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); - } - } -#endif - if( isOpen==0 ){ - releasePage(pPage1); - return SQLITE_OK; - } - } - rc = SQLITE_NOTADB; - } -#endif - - /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload - ** fractions and the leaf payload fraction values must be 64, 32, and 32. - ** - ** The original design allowed these amounts to vary, but as of - ** version 3.6.0, we require them to be fixed. - */ - if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ - goto page1_init_failed; - } - /* EVIDENCE-OF: R-51873-39618 The page size for a database file is - ** determined by the 2-byte integer located at an offset of 16 bytes from - ** the beginning of the database file. */ - pageSize = (page1[16]<<8) | (page1[17]<<16); - /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two - ** between 512 and 65536 inclusive. */ - if( ((pageSize-1)&pageSize)!=0 - || pageSize>SQLITE_MAX_PAGE_SIZE - || pageSize<=256 - ){ - goto page1_init_failed; - } - assert( (pageSize & 7)==0 ); - /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte - ** integer at offset 20 is the number of bytes of space at the end of - ** each page to reserve for extensions. - ** - ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is - ** determined by the one-byte unsigned integer found at an offset of 20 - ** into the database file header. */ - usableSize = pageSize - page1[20]; - if( (u32)pageSize!=pBt->pageSize ){ - /* After reading the first page of the database assuming a page size - ** of BtShared.pageSize, we have discovered that the page-size is - ** actually pageSize. Unlock the database, leave pBt->pPage1 at - ** zero and return SQLITE_OK. The caller will call this function - ** again with the correct page-size. - */ - releasePage(pPage1); - pBt->usableSize = usableSize; - pBt->pageSize = pageSize; - freeTempSpace(pBt); - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, - pageSize-usableSize); - return rc; - } - if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){ - rc = SQLITE_CORRUPT_BKPT; - goto page1_init_failed; - } - /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to - ** be less than 480. In other words, if the page size is 512, then the - ** reserved space size cannot exceed 32. */ - if( usableSize<480 ){ - goto page1_init_failed; - } - pBt->pageSize = pageSize; - pBt->usableSize = usableSize; -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); - pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); -#endif - } - - /* maxLocal is the maximum amount of payload to store locally for - ** a cell. Make sure it is small enough so that at least minFanout - ** cells can will fit on one page. We assume a 10-byte page header. - ** Besides the payload, the cell must store: - ** 2-byte pointer to the cell - ** 4-byte child pointer - ** 9-byte nKey value - ** 4-byte nData value - ** 4-byte overflow page pointer - ** So a cell consists of a 2-byte pointer, a header which is as much as - ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow - ** page pointer. - */ - pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); - pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); - pBt->maxLeaf = (u16)(pBt->usableSize - 35); - pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); - if( pBt->maxLocal>127 ){ - pBt->max1bytePayload = 127; - }else{ - pBt->max1bytePayload = (u8)pBt->maxLocal; - } - assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); - pBt->pPage1 = pPage1; - pBt->nPage = nPage; - return SQLITE_OK; - -page1_init_failed: - releasePage(pPage1); - pBt->pPage1 = 0; - return rc; -} - -#ifndef NDEBUG -/* -** Return the number of cursors open on pBt. This is for use -** in assert() expressions, so it is only compiled if NDEBUG is not -** defined. -** -** Only write cursors are counted if wrOnly is true. If wrOnly is -** false then all cursors are counted. -** -** For the purposes of this routine, a cursor is any cursor that -** is capable of reading or writing to the database. Cursors that -** have been tripped into the CURSOR_FAULT state are not counted. -*/ -static int countValidCursors(BtShared *pBt, int wrOnly){ - BtCursor *pCur; - int r = 0; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) - && pCur->eState!=CURSOR_FAULT ) r++; - } - return r; -} -#endif - -/* -** If there are no outstanding cursors and we are not in the middle -** of a transaction but there is a read lock on the database, then -** this routine unrefs the first page of the database file which -** has the effect of releasing the read lock. -** -** If there is a transaction in progress, this routine is a no-op. -*/ -static void unlockBtreeIfUnused(BtShared *pBt){ - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); - if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ - MemPage *pPage1 = pBt->pPage1; - assert( pPage1->aData ); - assert( sqlite3PagerRefcount(pBt->pPager)==1 ); - pBt->pPage1 = 0; - releasePageNotNull(pPage1); - } -} - -/* -** If pBt points to an empty file then convert that empty file -** into a new empty database by initializing the first page of -** the database. -*/ -static int newDatabase(BtShared *pBt){ - MemPage *pP1; - unsigned char *data; - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->nPage>0 ){ - return SQLITE_OK; - } - pP1 = pBt->pPage1; - assert( pP1!=0 ); - data = pP1->aData; - rc = sqlite3PagerWrite(pP1->pDbPage); - if( rc ) return rc; - memcpy(data, zMagicHeader, sizeof(zMagicHeader)); - assert( sizeof(zMagicHeader)==16 ); - data[16] = (u8)((pBt->pageSize>>8)&0xff); - data[17] = (u8)((pBt->pageSize>>16)&0xff); - data[18] = 1; - data[19] = 1; - assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); - data[20] = (u8)(pBt->pageSize - pBt->usableSize); - data[21] = 64; - data[22] = 32; - data[23] = 32; - memset(&data[24], 0, 100-24); - zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); - pBt->btsFlags |= BTS_PAGESIZE_FIXED; -#ifndef SQLITE_OMIT_AUTOVACUUM - assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); - assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); - put4byte(&data[36 + 4*4], pBt->autoVacuum); - put4byte(&data[36 + 7*4], pBt->incrVacuum); -#endif - pBt->nPage = 1; - data[31] = 1; - return SQLITE_OK; -} - -/* -** Initialize the first page of the database file (creating a database -** consisting of a single page and no schema objects). Return SQLITE_OK -** if successful, or an SQLite error code otherwise. -*/ -SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ - int rc; - sqlite3BtreeEnter(p); - p->pBt->nPage = 0; - rc = newDatabase(p->pBt); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Attempt to start a new transaction. A write-transaction -** is started if the second argument is nonzero, otherwise a read- -** transaction. If the second argument is 2 or more and exclusive -** transaction is started, meaning that no other process is allowed -** to access the database. A preexisting transaction may not be -** upgraded to exclusive by calling this routine a second time - the -** exclusivity flag only works for a new transaction. -** -** A write-transaction must be started before attempting any -** changes to the database. None of the following routines -** will work unless a transaction is started first: -** -** sqlite3BtreeCreateTable() -** sqlite3BtreeCreateIndex() -** sqlite3BtreeClearTable() -** sqlite3BtreeDropTable() -** sqlite3BtreeInsert() -** sqlite3BtreeDelete() -** sqlite3BtreeUpdateMeta() -** -** If an initial attempt to acquire the lock fails because of lock contention -** and the database was previously unlocked, then invoke the busy handler -** if there is one. But if there was previously a read-lock, do not -** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is -** returned when there is already a read-lock in order to avoid a deadlock. -** -** Suppose there are two processes A and B. A has a read lock and B has -** a reserved lock. B tries to promote to exclusive but is blocked because -** of A's read lock. A tries to promote to reserved but is blocked by B. -** One or the other of the two processes must give way or there can be -** no progress. By returning SQLITE_BUSY and not invoking the busy callback -** when A already has a read lock, we encourage A to give up and let B -** proceed. -*/ -SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ - BtShared *pBt = p->pBt; - int rc = SQLITE_OK; - - sqlite3BtreeEnter(p); - btreeIntegrity(p); - - /* If the btree is already in a write-transaction, or it - ** is already in a read-transaction and a read-transaction - ** is requested, this is a no-op. - */ - if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ - goto trans_begun; - } - assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); - - /* Write transactions are not possible on a read-only database */ - if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ - rc = SQLITE_READONLY; - goto trans_begun; - } - -#ifndef SQLITE_OMIT_SHARED_CACHE - { - sqlite3 *pBlock = 0; - /* If another database handle has already opened a write transaction - ** on this shared-btree structure and a second write transaction is - ** requested, return SQLITE_LOCKED. - */ - if( (wrflag && pBt->inTransaction==TRANS_WRITE) - || (pBt->btsFlags & BTS_PENDING)!=0 - ){ - pBlock = pBt->pWriter->db; - }else if( wrflag>1 ){ - BtLock *pIter; - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - if( pIter->pBtree!=p ){ - pBlock = pIter->pBtree->db; - break; - } - } - } - if( pBlock ){ - sqlite3ConnectionBlocked(p->db, pBlock); - rc = SQLITE_LOCKED_SHAREDCACHE; - goto trans_begun; - } - } -#endif - - /* Any read-only or read-write transaction implies a read-lock on - ** page 1. So if some other shared-cache client already has a write-lock - ** on page 1, the transaction cannot be opened. */ - rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); - if( SQLITE_OK!=rc ) goto trans_begun; - - pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; - if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; - do { - /* Call lockBtree() until either pBt->pPage1 is populated or - ** lockBtree() returns something other than SQLITE_OK. lockBtree() - ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after - ** reading page 1 it discovers that the page-size of the database - ** file is not pBt->pageSize. In this case lockBtree() will update - ** pBt->pageSize to the page-size of the file on disk. - */ - while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); - - if( rc==SQLITE_OK && wrflag ){ - if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ - rc = SQLITE_READONLY; - }else{ - rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); - if( rc==SQLITE_OK ){ - rc = newDatabase(pBt); - } - } - } - - if( rc!=SQLITE_OK ){ - unlockBtreeIfUnused(pBt); - } - }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && - btreeInvokeBusyHandler(pBt) ); - - if( rc==SQLITE_OK ){ - if( p->inTrans==TRANS_NONE ){ - pBt->nTransaction++; -#ifndef SQLITE_OMIT_SHARED_CACHE - if( p->sharable ){ - assert( p->lock.pBtree==p && p->lock.iTable==1 ); - p->lock.eLock = READ_LOCK; - p->lock.pNext = pBt->pLock; - pBt->pLock = &p->lock; - } -#endif - } - p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); - if( p->inTrans>pBt->inTransaction ){ - pBt->inTransaction = p->inTrans; - } - if( wrflag ){ - MemPage *pPage1 = pBt->pPage1; -#ifndef SQLITE_OMIT_SHARED_CACHE - assert( !pBt->pWriter ); - pBt->pWriter = p; - pBt->btsFlags &= ~BTS_EXCLUSIVE; - if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; -#endif - - /* If the db-size header field is incorrect (as it may be if an old - ** client has been writing the database file), update it now. Doing - ** this sooner rather than later means the database size can safely - ** re-read the database size from page 1 if a savepoint or transaction - ** rollback occurs within the transaction. - */ - if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ - rc = sqlite3PagerWrite(pPage1->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(&pPage1->aData[28], pBt->nPage); - } - } - } - } - - -trans_begun: - if( rc==SQLITE_OK && wrflag ){ - /* This call makes sure that the pager has the correct number of - ** open savepoints. If the second parameter is greater than 0 and - ** the sub-journal is not already open, then it will be opened here. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); - } - - btreeIntegrity(p); - sqlite3BtreeLeave(p); - return rc; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM - -/* -** Set the pointer-map entries for all children of page pPage. Also, if -** pPage contains cells that point to overflow pages, set the pointer -** map entries for the overflow pages as well. -*/ -static int setChildPtrmaps(MemPage *pPage){ - int i; /* Counter variable */ - int nCell; /* Number of cells in page pPage */ - int rc; /* Return code */ - BtShared *pBt = pPage->pBt; - u8 isInitOrig = pPage->isInit; - Pgno pgno = pPage->pgno; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - rc = btreeInitPage(pPage); - if( rc!=SQLITE_OK ){ - goto set_child_ptrmaps_out; - } - nCell = pPage->nCell; - - for(i=0; ileaf ){ - Pgno childPgno = get4byte(pCell); - ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); - } - } - - if( !pPage->leaf ){ - Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); - } - -set_child_ptrmaps_out: - pPage->isInit = isInitOrig; - return rc; -} - -/* -** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so -** that it points to iTo. Parameter eType describes the type of pointer to -** be modified, as follows: -** -** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child -** page of pPage. -** -** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow -** page pointed to by one of the cells on pPage. -** -** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next -** overflow page in the list. -*/ -static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - if( eType==PTRMAP_OVERFLOW2 ){ - /* The pointer is always the first 4 bytes of the page in this case. */ - if( get4byte(pPage->aData)!=iFrom ){ - return SQLITE_CORRUPT_BKPT; - } - put4byte(pPage->aData, iTo); - }else{ - u8 isInitOrig = pPage->isInit; - int i; - int nCell; - int rc; - - rc = btreeInitPage(pPage); - if( rc ) return rc; - nCell = pPage->nCell; - - for(i=0; ixParseCell(pPage, pCell, &info); - if( info.nLocalaData+pPage->maskPage - && iFrom==get4byte(pCell+info.nSize-4) - ){ - put4byte(pCell+info.nSize-4, iTo); - break; - } - }else{ - if( get4byte(pCell)==iFrom ){ - put4byte(pCell, iTo); - break; - } - } - } - - if( i==nCell ){ - if( eType!=PTRMAP_BTREE || - get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ - return SQLITE_CORRUPT_BKPT; - } - put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); - } - - pPage->isInit = isInitOrig; - } - return SQLITE_OK; -} - - -/* -** Move the open database page pDbPage to location iFreePage in the -** database. The pDbPage reference remains valid. -** -** The isCommit flag indicates that there is no need to remember that -** the journal needs to be sync()ed before database page pDbPage->pgno -** can be written to. The caller has already promised not to write to that -** page. -*/ -static int relocatePage( - BtShared *pBt, /* Btree */ - MemPage *pDbPage, /* Open page to move */ - u8 eType, /* Pointer map 'type' entry for pDbPage */ - Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ - Pgno iFreePage, /* The location to move pDbPage to */ - int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ -){ - MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ - Pgno iDbPage = pDbPage->pgno; - Pager *pPager = pBt->pPager; - int rc; - - assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || - eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pDbPage->pBt==pBt ); - - /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", - iDbPage, iFreePage, iPtrPage, eType)); - rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); - if( rc!=SQLITE_OK ){ - return rc; - } - pDbPage->pgno = iFreePage; - - /* If pDbPage was a btree-page, then it may have child pages and/or cells - ** that point to overflow pages. The pointer map entries for all these - ** pages need to be changed. - ** - ** If pDbPage is an overflow page, then the first 4 bytes may store a - ** pointer to a subsequent overflow page. If this is the case, then - ** the pointer map needs to be updated for the subsequent overflow page. - */ - if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ - rc = setChildPtrmaps(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - Pgno nextOvfl = get4byte(pDbPage->aData); - if( nextOvfl!=0 ){ - ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); - if( rc!=SQLITE_OK ){ - return rc; - } - } - } - - /* Fix the database pointer on page iPtrPage that pointed at iDbPage so - ** that it points at iFreePage. Also fix the pointer map entry for - ** iPtrPage. - */ - if( eType!=PTRMAP_ROOTPAGE ){ - rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3PagerWrite(pPtrPage->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pPtrPage); - return rc; - } - rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); - releasePage(pPtrPage); - if( rc==SQLITE_OK ){ - ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); - } - } - return rc; -} - -/* Forward declaration required by incrVacuumStep(). */ -static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); - -/* -** Perform a single step of an incremental-vacuum. If successful, return -** SQLITE_OK. If there is no work to do (and therefore no point in -** calling this function again), return SQLITE_DONE. Or, if an error -** occurs, return some other error code. -** -** More specifically, this function attempts to re-organize the database so -** that the last page of the file currently in use is no longer in use. -** -** Parameter nFin is the number of pages that this database would contain -** were this function called until it returns SQLITE_DONE. -** -** If the bCommit parameter is non-zero, this function assumes that the -** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE -** or an error. bCommit is passed true for an auto-vacuum-on-commit -** operation, or false for an incremental vacuum. -*/ -static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ - Pgno nFreeList; /* Number of pages still on the free-list */ - int rc; - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( iLastPg>nFin ); - - if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ - u8 eType; - Pgno iPtrPage; - - nFreeList = get4byte(&pBt->pPage1->aData[36]); - if( nFreeList==0 ){ - return SQLITE_DONE; - } - - rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); - if( rc!=SQLITE_OK ){ - return rc; - } - if( eType==PTRMAP_ROOTPAGE ){ - return SQLITE_CORRUPT_BKPT; - } - - if( eType==PTRMAP_FREEPAGE ){ - if( bCommit==0 ){ - /* Remove the page from the files free-list. This is not required - ** if bCommit is non-zero. In that case, the free-list will be - ** truncated to zero after this function returns, so it doesn't - ** matter if it still contains some garbage entries. - */ - Pgno iFreePg; - MemPage *pFreePg; - rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( iFreePg==iLastPg ); - releasePage(pFreePg); - } - } else { - Pgno iFreePg; /* Index of free page to move pLastPg to */ - MemPage *pLastPg; - u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ - Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ - - rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* If bCommit is zero, this loop runs exactly once and page pLastPg - ** is swapped with the first free page pulled off the free list. - ** - ** On the other hand, if bCommit is greater than zero, then keep - ** looping until a free-page located within the first nFin pages - ** of the file is found. - */ - if( bCommit==0 ){ - eMode = BTALLOC_LE; - iNear = nFin; - } - do { - MemPage *pFreePg; - rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); - if( rc!=SQLITE_OK ){ - releasePage(pLastPg); - return rc; - } - releasePage(pFreePg); - }while( bCommit && iFreePg>nFin ); - assert( iFreePgbDoTruncate = 1; - pBt->nPage = iLastPg; - } - return SQLITE_OK; -} - -/* -** The database opened by the first argument is an auto-vacuum database -** nOrig pages in size containing nFree free pages. Return the expected -** size of the database in pages following an auto-vacuum operation. -*/ -static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ - int nEntry; /* Number of entries on one ptrmap page */ - Pgno nPtrmap; /* Number of PtrMap pages to be freed */ - Pgno nFin; /* Return value */ - - nEntry = pBt->usableSize/5; - nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; - nFin = nOrig - nFree - nPtrmap; - if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinpBt; - - sqlite3BtreeEnter(p); - assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); - if( !pBt->autoVacuum ){ - rc = SQLITE_DONE; - }else{ - Pgno nOrig = btreePagecount(pBt); - Pgno nFree = get4byte(&pBt->pPage1->aData[36]); - Pgno nFin = finalDbSize(pBt, nOrig, nFree); - - if( nOrig0 ){ - rc = saveAllCursors(pBt, 0, 0); - if( rc==SQLITE_OK ){ - invalidateAllOverflowCache(pBt); - rc = incrVacuumStep(pBt, nFin, nOrig, 0); - } - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - put4byte(&pBt->pPage1->aData[28], pBt->nPage); - } - }else{ - rc = SQLITE_DONE; - } - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** This routine is called prior to sqlite3PagerCommit when a transaction -** is committed for an auto-vacuum database. -** -** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages -** the database file should be truncated to during the commit process. -** i.e. the database has been reorganized so that only the first *pnTrunc -** pages are in use. -*/ -static int autoVacuumCommit(BtShared *pBt){ - int rc = SQLITE_OK; - Pager *pPager = pBt->pPager; - VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); ) - - assert( sqlite3_mutex_held(pBt->mutex) ); - invalidateAllOverflowCache(pBt); - assert(pBt->autoVacuum); - if( !pBt->incrVacuum ){ - Pgno nFin; /* Number of pages in database after autovacuuming */ - Pgno nFree; /* Number of pages on the freelist initially */ - Pgno iFree; /* The next page to be freed */ - Pgno nOrig; /* Database size before freeing */ - - nOrig = btreePagecount(pBt); - if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ - /* It is not possible to create a database for which the final page - ** is either a pointer-map page or the pending-byte page. If one - ** is encountered, this indicates corruption. - */ - return SQLITE_CORRUPT_BKPT; - } - - nFree = get4byte(&pBt->pPage1->aData[36]); - nFin = finalDbSize(pBt, nOrig, nFree); - if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; - if( nFinnFin && rc==SQLITE_OK; iFree--){ - rc = incrVacuumStep(pBt, nFin, iFree, 1); - } - if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - put4byte(&pBt->pPage1->aData[32], 0); - put4byte(&pBt->pPage1->aData[36], 0); - put4byte(&pBt->pPage1->aData[28], nFin); - pBt->bDoTruncate = 1; - pBt->nPage = nFin; - } - if( rc!=SQLITE_OK ){ - sqlite3PagerRollback(pPager); - } - } - - assert( nRef>=sqlite3PagerRefcount(pPager) ); - return rc; -} - -#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ -# define setChildPtrmaps(x) SQLITE_OK -#endif - -/* -** This routine does the first phase of a two-phase commit. This routine -** causes a rollback journal to be created (if it does not already exist) -** and populated with enough information so that if a power loss occurs -** the database can be restored to its original state by playing back -** the journal. Then the contents of the journal are flushed out to -** the disk. After the journal is safely on oxide, the changes to the -** database are written into the database file and flushed to oxide. -** At the end of this call, the rollback journal still exists on the -** disk and we are still holding all locks, so the transaction has not -** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the -** commit process. -** -** This call is a no-op if no write-transaction is currently active on pBt. -** -** Otherwise, sync the database file for the btree pBt. zMaster points to -** the name of a master journal file that should be written into the -** individual journal file, or is NULL, indicating no master journal file -** (single database transaction). -** -** When this is called, the master journal should already have been -** created, populated with this journal pointer and synced to disk. -** -** Once this is routine has returned, the only thing required to commit -** the write-transaction for this database file is to delete the journal. -*/ -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ - int rc = SQLITE_OK; - if( p->inTrans==TRANS_WRITE ){ - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - rc = autoVacuumCommit(pBt); - if( rc!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return rc; - } - } - if( pBt->bDoTruncate ){ - sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); - } -#endif - rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); - sqlite3BtreeLeave(p); - } - return rc; -} - -/* -** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() -** at the conclusion of a transaction. -*/ -static void btreeEndTransaction(Btree *p){ - BtShared *pBt = p->pBt; - sqlite3 *db = p->db; - assert( sqlite3BtreeHoldsMutex(p) ); - -#ifndef SQLITE_OMIT_AUTOVACUUM - pBt->bDoTruncate = 0; -#endif - if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){ - /* If there are other active statements that belong to this database - ** handle, downgrade to a read-only transaction. The other statements - ** may still be reading from the database. */ - downgradeAllSharedCacheTableLocks(p); - p->inTrans = TRANS_READ; - }else{ - /* If the handle had any kind of transaction open, decrement the - ** transaction count of the shared btree. If the transaction count - ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() - ** call below will unlock the pager. */ - if( p->inTrans!=TRANS_NONE ){ - clearAllSharedCacheTableLocks(p); - pBt->nTransaction--; - if( 0==pBt->nTransaction ){ - pBt->inTransaction = TRANS_NONE; - } - } - - /* Set the current transaction state to TRANS_NONE and unlock the - ** pager if this call closed the only read or write transaction. */ - p->inTrans = TRANS_NONE; - unlockBtreeIfUnused(pBt); - } - - btreeIntegrity(p); -} - -/* -** Commit the transaction currently in progress. -** -** This routine implements the second phase of a 2-phase commit. The -** sqlite3BtreeCommitPhaseOne() routine does the first phase and should -** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() -** routine did all the work of writing information out to disk and flushing the -** contents so that they are written onto the disk platter. All this -** routine has to do is delete or truncate or zero the header in the -** the rollback journal (which causes the transaction to commit) and -** drop locks. -** -** Normally, if an error occurs while the pager layer is attempting to -** finalize the underlying journal file, this function returns an error and -** the upper layer will attempt a rollback. However, if the second argument -** is non-zero then this b-tree transaction is part of a multi-file -** transaction. In this case, the transaction has already been committed -** (by deleting a master journal file) and the caller will ignore this -** functions return code. So, even if an error occurs in the pager layer, -** reset the b-tree objects internal state to indicate that the write -** transaction has been closed. This is quite safe, as the pager will have -** transitioned to the error state. -** -** This will release the write lock on the database file. If there -** are no active cursors, it also releases the read lock. -*/ -SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ - - if( p->inTrans==TRANS_NONE ) return SQLITE_OK; - sqlite3BtreeEnter(p); - btreeIntegrity(p); - - /* If the handle has a write-transaction open, commit the shared-btrees - ** transaction and set the shared state to TRANS_READ. - */ - if( p->inTrans==TRANS_WRITE ){ - int rc; - BtShared *pBt = p->pBt; - assert( pBt->inTransaction==TRANS_WRITE ); - assert( pBt->nTransaction>0 ); - rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); - if( rc!=SQLITE_OK && bCleanup==0 ){ - sqlite3BtreeLeave(p); - return rc; - } - p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ - pBt->inTransaction = TRANS_READ; - btreeClearHasContent(pBt); - } - - btreeEndTransaction(p); - sqlite3BtreeLeave(p); - return SQLITE_OK; -} - -/* -** Do both phases of a commit. -*/ -SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ - int rc; - sqlite3BtreeEnter(p); - rc = sqlite3BtreeCommitPhaseOne(p, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeCommitPhaseTwo(p, 0); - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** This routine sets the state to CURSOR_FAULT and the error -** code to errCode for every cursor on any BtShared that pBtree -** references. Or if the writeOnly flag is set to 1, then only -** trip write cursors and leave read cursors unchanged. -** -** Every cursor is a candidate to be tripped, including cursors -** that belong to other database connections that happen to be -** sharing the cache with pBtree. -** -** This routine gets called when a rollback occurs. If the writeOnly -** flag is true, then only write-cursors need be tripped - read-only -** cursors save their current positions so that they may continue -** following the rollback. Or, if writeOnly is false, all cursors are -** tripped. In general, writeOnly is false if the transaction being -** rolled back modified the database schema. In this case b-tree root -** pages may be moved or deleted from the database altogether, making -** it unsafe for read cursors to continue. -** -** If the writeOnly flag is true and an error is encountered while -** saving the current position of a read-only cursor, all cursors, -** including all read-cursors are tripped. -** -** SQLITE_OK is returned if successful, or if an error occurs while -** saving a cursor position, an SQLite error code. -*/ -SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ - BtCursor *p; - int rc = SQLITE_OK; - - assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 ); - if( pBtree ){ - sqlite3BtreeEnter(pBtree); - for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - int i; - if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ - if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ - rc = saveCursorPosition(p); - if( rc!=SQLITE_OK ){ - (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); - break; - } - } - }else{ - sqlite3BtreeClearCursor(p); - p->eState = CURSOR_FAULT; - p->skipNext = errCode; - } - for(i=0; i<=p->iPage; i++){ - releasePage(p->apPage[i]); - p->apPage[i] = 0; - } - } - sqlite3BtreeLeave(pBtree); - } - return rc; -} - -/* -** Rollback the transaction in progress. -** -** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped). -** Only write cursors are tripped if writeOnly is true but all cursors are -** tripped if writeOnly is false. Any attempt to use -** a tripped cursor will result in an error. -** -** This will release the write lock on the database file. If there -** are no active cursors, it also releases the read lock. -*/ -SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ - int rc; - BtShared *pBt = p->pBt; - MemPage *pPage1; - - assert( writeOnly==1 || writeOnly==0 ); - assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK ); - sqlite3BtreeEnter(p); - if( tripCode==SQLITE_OK ){ - rc = tripCode = saveAllCursors(pBt, 0, 0); - if( rc ) writeOnly = 0; - }else{ - rc = SQLITE_OK; - } - if( tripCode ){ - int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); - assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) ); - if( rc2!=SQLITE_OK ) rc = rc2; - } - btreeIntegrity(p); - - if( p->inTrans==TRANS_WRITE ){ - int rc2; - - assert( TRANS_WRITE==pBt->inTransaction ); - rc2 = sqlite3PagerRollback(pBt->pPager); - if( rc2!=SQLITE_OK ){ - rc = rc2; - } - - /* The rollback may have destroyed the pPage1->aData value. So - ** call btreeGetPage() on page 1 again to make - ** sure pPage1->aData is set correctly. */ - if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ - int nPage = get4byte(28+(u8*)pPage1->aData); - testcase( nPage==0 ); - if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); - testcase( pBt->nPage!=nPage ); - pBt->nPage = nPage; - releasePage(pPage1); - } - assert( countValidCursors(pBt, 1)==0 ); - pBt->inTransaction = TRANS_READ; - btreeClearHasContent(pBt); - } - - btreeEndTransaction(p); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Start a statement subtransaction. The subtransaction can be rolled -** back independently of the main transaction. You must start a transaction -** before starting a subtransaction. The subtransaction is ended automatically -** if the main transaction commits or rolls back. -** -** Statement subtransactions are used around individual SQL statements -** that are contained within a BEGIN...COMMIT block. If a constraint -** error occurs within the statement, the effect of that one statement -** can be rolled back without having to rollback the entire transaction. -** -** A statement sub-transaction is implemented as an anonymous savepoint. The -** value passed as the second parameter is the total number of savepoints, -** including the new anonymous savepoint, open on the B-Tree. i.e. if there -** are no active savepoints and no other statement-transactions open, -** iStatement is 1. This anonymous savepoint can be released or rolled back -** using the sqlite3BtreeSavepoint() function. -*/ -SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ - int rc; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - assert( p->inTrans==TRANS_WRITE ); - assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( iStatement>0 ); - assert( iStatement>p->db->nSavepoint ); - assert( pBt->inTransaction==TRANS_WRITE ); - /* At the pager level, a statement transaction is a savepoint with - ** an index greater than all savepoints created explicitly using - ** SQL statements. It is illegal to open, release or rollback any - ** such savepoints while the statement transaction savepoint is active. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** The second argument to this function, op, is always SAVEPOINT_ROLLBACK -** or SAVEPOINT_RELEASE. This function either releases or rolls back the -** savepoint identified by parameter iSavepoint, depending on the value -** of op. -** -** Normally, iSavepoint is greater than or equal to zero. However, if op is -** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the -** contents of the entire transaction are rolled back. This is different -** from a normal transaction rollback, as no locks are released and the -** transaction remains open. -*/ -SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ - int rc = SQLITE_OK; - if( p && p->inTrans==TRANS_WRITE ){ - BtShared *pBt = p->pBt; - assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); - assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); - sqlite3BtreeEnter(p); - rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); - if( rc==SQLITE_OK ){ - if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ - pBt->nPage = 0; - } - rc = newDatabase(pBt); - pBt->nPage = get4byte(28 + pBt->pPage1->aData); - - /* The database size was written into the offset 28 of the header - ** when the transaction started, so we know that the value at offset - ** 28 is nonzero. */ - assert( pBt->nPage>0 ); - } - sqlite3BtreeLeave(p); - } - return rc; -} - -/* -** Create a new cursor for the BTree whose root is on the page -** iTable. If a read-only cursor is requested, it is assumed that -** the caller already has at least a read-only transaction open -** on the database already. If a write-cursor is requested, then -** the caller is assumed to have an open write transaction. -** -** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only -** be used for reading. If the BTREE_WRCSR bit is set, then the cursor -** can be used for reading or for writing if other conditions for writing -** are also met. These are the conditions that must be met in order -** for writing to be allowed: -** -** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR -** -** 2: Other database connections that share the same pager cache -** but which are not in the READ_UNCOMMITTED state may not have -** cursors open with wrFlag==0 on the same table. Otherwise -** the changes made by this write cursor would be visible to -** the read cursors in the other database connection. -** -** 3: The database must be writable (not on read-only media) -** -** 4: There must be an active transaction. -** -** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR -** is set. If FORDELETE is set, that is a hint to the implementation that -** this cursor will only be used to seek to and delete entries of an index -** as part of a larger DELETE statement. The FORDELETE hint is not used by -** this implementation. But in a hypothetical alternative storage engine -** in which index entries are automatically deleted when corresponding table -** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE -** operations on this cursor can be no-ops and all READ operations can -** return a null row (2-bytes: 0x01 0x00). -** -** No checking is done to make sure that page iTable really is the -** root page of a b-tree. If it is not, then the cursor acquired -** will not work correctly. -** -** It is assumed that the sqlite3BtreeCursorZero() has been called -** on pCur to initialize the memory space prior to invoking this routine. -*/ -static int btreeCursor( - Btree *p, /* The btree */ - int iTable, /* Root page of table to open */ - int wrFlag, /* 1 to write. 0 read-only */ - struct KeyInfo *pKeyInfo, /* First arg to comparison function */ - BtCursor *pCur /* Space for new cursor */ -){ - BtShared *pBt = p->pBt; /* Shared b-tree handle */ - BtCursor *pX; /* Looping over other all cursors */ - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( wrFlag==0 - || wrFlag==BTREE_WRCSR - || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) - ); - - /* The following assert statements verify that if this is a sharable - ** b-tree database, the connection is holding the required table locks, - ** and that no other connection has any open cursor that conflicts with - ** this lock. */ - assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) ); - assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); - - /* Assert that the caller has opened the required transaction. */ - assert( p->inTrans>TRANS_NONE ); - assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); - assert( pBt->pPage1 && pBt->pPage1->aData ); - assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); - - if( wrFlag ){ - allocateTempSpace(pBt); - if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT; - } - if( iTable==1 && btreePagecount(pBt)==0 ){ - assert( wrFlag==0 ); - iTable = 0; - } - - /* Now that no other errors can occur, finish filling in the BtCursor - ** variables and link the cursor into the BtShared list. */ - pCur->pgnoRoot = (Pgno)iTable; - pCur->iPage = -1; - pCur->pKeyInfo = pKeyInfo; - pCur->pBtree = p; - pCur->pBt = pBt; - pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; - pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY; - /* If there are two or more cursors on the same btree, then all such - ** cursors *must* have the BTCF_Multiple flag set. */ - for(pX=pBt->pCursor; pX; pX=pX->pNext){ - if( pX->pgnoRoot==(Pgno)iTable ){ - pX->curFlags |= BTCF_Multiple; - pCur->curFlags |= BTCF_Multiple; - } - } - pCur->pNext = pBt->pCursor; - pBt->pCursor = pCur; - pCur->eState = CURSOR_INVALID; - return SQLITE_OK; -} -SQLITE_PRIVATE int sqlite3BtreeCursor( - Btree *p, /* The btree */ - int iTable, /* Root page of table to open */ - int wrFlag, /* 1 to write. 0 read-only */ - struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ - BtCursor *pCur /* Write new cursor here */ -){ - int rc; - if( iTable<1 ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - sqlite3BtreeEnter(p); - rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); - sqlite3BtreeLeave(p); - } - return rc; -} - -/* -** Return the size of a BtCursor object in bytes. -** -** This interfaces is needed so that users of cursors can preallocate -** sufficient storage to hold a cursor. The BtCursor object is opaque -** to users so they cannot do the sizeof() themselves - they must call -** this routine. -*/ -SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ - return ROUND8(sizeof(BtCursor)); -} - -/* -** Initialize memory that will be converted into a BtCursor object. -** -** The simple approach here would be to memset() the entire object -** to zero. But it turns out that the apPage[] and aiIdx[] arrays -** do not need to be zeroed and they are large, so we can save a lot -** of run-time by skipping the initialization of those elements. -*/ -SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ - memset(p, 0, offsetof(BtCursor, iPage)); -} - -/* -** Close a cursor. The read lock on the database file is released -** when the last cursor is closed. -*/ -SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ - Btree *pBtree = pCur->pBtree; - if( pBtree ){ - int i; - BtShared *pBt = pCur->pBt; - sqlite3BtreeEnter(pBtree); - sqlite3BtreeClearCursor(pCur); - assert( pBt->pCursor!=0 ); - if( pBt->pCursor==pCur ){ - pBt->pCursor = pCur->pNext; - }else{ - BtCursor *pPrev = pBt->pCursor; - do{ - if( pPrev->pNext==pCur ){ - pPrev->pNext = pCur->pNext; - break; - } - pPrev = pPrev->pNext; - }while( ALWAYS(pPrev) ); - } - for(i=0; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - } - unlockBtreeIfUnused(pBt); - sqlite3_free(pCur->aOverflow); - /* sqlite3_free(pCur); */ - sqlite3BtreeLeave(pBtree); - } - return SQLITE_OK; -} - -/* -** Make sure the BtCursor* given in the argument has a valid -** BtCursor.info structure. If it is not already valid, call -** btreeParseCell() to fill it in. -** -** BtCursor.info is a cache of the information in the current cell. -** Using this cache reduces the number of calls to btreeParseCell(). -*/ -#ifndef NDEBUG - static void assertCellInfo(BtCursor *pCur){ - CellInfo info; - int iPage = pCur->iPage; - memset(&info, 0, sizeof(info)); - btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); - assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); - } -#else - #define assertCellInfo(x) -#endif -static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ - if( pCur->info.nSize==0 ){ - int iPage = pCur->iPage; - pCur->curFlags |= BTCF_ValidNKey; - btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); - }else{ - assertCellInfo(pCur); - } -} - -#ifndef NDEBUG /* The next routine used only within assert() statements */ -/* -** Return true if the given BtCursor is valid. A valid cursor is one -** that is currently pointing to a row in a (non-empty) table. -** This is a verification routine is used only within assert() statements. -*/ -SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ - return pCur && pCur->eState==CURSOR_VALID; -} -#endif /* NDEBUG */ - -/* -** Return the value of the integer key or "rowid" for a table btree. -** This routine is only valid for a cursor that is pointing into a -** ordinary table btree. If the cursor points to an index btree or -** is invalid, the result of this routine is undefined. -*/ -SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->curIntKey ); - getCellInfo(pCur); - return pCur->info.nKey; -} - -/* -** Return the number of bytes of payload for the entry that pCur is -** currently pointing to. For table btrees, this will be the amount -** of data. For index btrees, this will be the size of the key. -** -** The caller must guarantee that the cursor is pointing to a non-NULL -** valid entry. In other words, the calling procedure must guarantee -** that the cursor has Cursor.eState==CURSOR_VALID. -*/ -SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - getCellInfo(pCur); - return pCur->info.nPayload; -} - -/* -** Given the page number of an overflow page in the database (parameter -** ovfl), this function finds the page number of the next page in the -** linked list of overflow pages. If possible, it uses the auto-vacuum -** pointer-map data instead of reading the content of page ovfl to do so. -** -** If an error occurs an SQLite error code is returned. Otherwise: -** -** The page number of the next overflow page in the linked list is -** written to *pPgnoNext. If page ovfl is the last page in its linked -** list, *pPgnoNext is set to zero. -** -** If ppPage is not NULL, and a reference to the MemPage object corresponding -** to page number pOvfl was obtained, then *ppPage is set to point to that -** reference. It is the responsibility of the caller to call releasePage() -** on *ppPage to free the reference. In no reference was obtained (because -** the pointer-map was used to obtain the value for *pPgnoNext), then -** *ppPage is set to zero. -*/ -static int getOverflowPage( - BtShared *pBt, /* The database file */ - Pgno ovfl, /* Current overflow page number */ - MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ - Pgno *pPgnoNext /* OUT: Next overflow page number */ -){ - Pgno next = 0; - MemPage *pPage = 0; - int rc = SQLITE_OK; - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert(pPgnoNext); - -#ifndef SQLITE_OMIT_AUTOVACUUM - /* Try to find the next page in the overflow list using the - ** autovacuum pointer-map pages. Guess that the next page in - ** the overflow list is page number (ovfl+1). If that guess turns - ** out to be wrong, fall back to loading the data of page - ** number ovfl to determine the next page number. - */ - if( pBt->autoVacuum ){ - Pgno pgno; - Pgno iGuess = ovfl+1; - u8 eType; - - while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ - iGuess++; - } - - if( iGuess<=btreePagecount(pBt) ){ - rc = ptrmapGet(pBt, iGuess, &eType, &pgno); - if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ - next = iGuess; - rc = SQLITE_DONE; - } - } - } -#endif - - assert( next==0 || rc==SQLITE_DONE ); - if( rc==SQLITE_OK ){ - rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0); - assert( rc==SQLITE_OK || pPage==0 ); - if( rc==SQLITE_OK ){ - next = get4byte(pPage->aData); - } - } - - *pPgnoNext = next; - if( ppPage ){ - *ppPage = pPage; - }else{ - releasePage(pPage); - } - return (rc==SQLITE_DONE ? SQLITE_OK : rc); -} - -/* -** Copy data from a buffer to a page, or from a page to a buffer. -** -** pPayload is a pointer to data stored on database page pDbPage. -** If argument eOp is false, then nByte bytes of data are copied -** from pPayload to the buffer pointed at by pBuf. If eOp is true, -** then sqlite3PagerWrite() is called on pDbPage and nByte bytes -** of data are copied from the buffer pBuf to pPayload. -** -** SQLITE_OK is returned on success, otherwise an error code. -*/ -static int copyPayload( - void *pPayload, /* Pointer to page data */ - void *pBuf, /* Pointer to buffer */ - int nByte, /* Number of bytes to copy */ - int eOp, /* 0 -> copy from page, 1 -> copy to page */ - DbPage *pDbPage /* Page containing pPayload */ -){ - if( eOp ){ - /* Copy data from buffer to page (a write operation) */ - int rc = sqlite3PagerWrite(pDbPage); - if( rc!=SQLITE_OK ){ - return rc; - } - memcpy(pPayload, pBuf, nByte); - }else{ - /* Copy data from page to buffer (a read operation) */ - memcpy(pBuf, pPayload, nByte); - } - return SQLITE_OK; -} - -/* -** This function is used to read or overwrite payload information -** for the entry that the pCur cursor is pointing to. The eOp -** argument is interpreted as follows: -** -** 0: The operation is a read. Populate the overflow cache. -** 1: The operation is a write. Populate the overflow cache. -** 2: The operation is a read. Do not populate the overflow cache. -** -** A total of "amt" bytes are read or written beginning at "offset". -** Data is read to or from the buffer pBuf. -** -** The content being read or written might appear on the main page -** or be scattered out on multiple overflow pages. -** -** If the current cursor entry uses one or more overflow pages and the -** eOp argument is not 2, this function may allocate space for and lazily -** populates the overflow page-list cache array (BtCursor.aOverflow). -** Subsequent calls use this cache to make seeking to the supplied offset -** more efficient. -** -** Once an overflow page-list cache has been allocated, it may be -** invalidated if some other cursor writes to the same table, or if -** the cursor is moved to a different row. Additionally, in auto-vacuum -** mode, the following events may invalidate an overflow page-list cache. -** -** * An incremental vacuum, -** * A commit in auto_vacuum="full" mode, -** * Creating a table (may require moving an overflow page). -*/ -static int accessPayload( - BtCursor *pCur, /* Cursor pointing to entry to read from */ - u32 offset, /* Begin reading this far into payload */ - u32 amt, /* Read this many bytes */ - unsigned char *pBuf, /* Write the bytes into this buffer */ - int eOp /* zero to read. non-zero to write. */ -){ - unsigned char *aPayload; - int rc = SQLITE_OK; - int iIdx = 0; - MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ - BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ -#ifdef SQLITE_DIRECT_OVERFLOW_READ - unsigned char * const pBufStart = pBuf; - int bEnd; /* True if reading to end of data */ -#endif - - assert( pPage ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->aiIdx[pCur->iPage]nCell ); - assert( cursorHoldsMutex(pCur) ); - assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */ - - getCellInfo(pCur); - aPayload = pCur->info.pPayload; -#ifdef SQLITE_DIRECT_OVERFLOW_READ - bEnd = offset+amt==pCur->info.nPayload; -#endif - assert( offset+amt <= pCur->info.nPayload ); - - assert( aPayload > pPage->aData ); - if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ - /* Trying to read or write past the end of the data is an error. The - ** conditional above is really: - ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] - ** but is recast into its current form to avoid integer overflow problems - */ - return SQLITE_CORRUPT_BKPT; - } - - /* Check if data must be read/written to/from the btree page itself. */ - if( offsetinfo.nLocal ){ - int a = amt; - if( a+offset>pCur->info.nLocal ){ - a = pCur->info.nLocal - offset; - } - rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage); - offset = 0; - pBuf += a; - amt -= a; - }else{ - offset -= pCur->info.nLocal; - } - - - if( rc==SQLITE_OK && amt>0 ){ - const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ - Pgno nextPage; - - nextPage = get4byte(&aPayload[pCur->info.nLocal]); - - /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. - ** Except, do not allocate aOverflow[] for eOp==2. - ** - ** The aOverflow[] array is sized at one entry for each overflow page - ** in the overflow chain. The page number of the first overflow page is - ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array - ** means "not yet known" (the cache is lazily populated). - */ - if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){ - int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; - if( nOvfl>pCur->nOvflAlloc ){ - Pgno *aNew = (Pgno*)sqlite3Realloc( - pCur->aOverflow, nOvfl*2*sizeof(Pgno) - ); - if( aNew==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - pCur->nOvflAlloc = nOvfl*2; - pCur->aOverflow = aNew; - } - } - if( rc==SQLITE_OK ){ - memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); - pCur->curFlags |= BTCF_ValidOvfl; - } - } - - /* If the overflow page-list cache has been allocated and the - ** entry for the first required overflow page is valid, skip - ** directly to it. - */ - if( (pCur->curFlags & BTCF_ValidOvfl)!=0 - && pCur->aOverflow[offset/ovflSize] - ){ - iIdx = (offset/ovflSize); - nextPage = pCur->aOverflow[iIdx]; - offset = (offset%ovflSize); - } - - for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){ - - /* If required, populate the overflow page-list cache. */ - if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ - assert( pCur->aOverflow[iIdx]==0 - || pCur->aOverflow[iIdx]==nextPage - || CORRUPT_DB ); - pCur->aOverflow[iIdx] = nextPage; - } - - if( offset>=ovflSize ){ - /* The only reason to read this page is to obtain the page - ** number for the next page in the overflow chain. The page - ** data is not required. So first try to lookup the overflow - ** page-list cache, if any, then fall back to the getOverflowPage() - ** function. - ** - ** Note that the aOverflow[] array must be allocated because eOp!=2 - ** here. If eOp==2, then offset==0 and this branch is never taken. - */ - assert( eOp!=2 ); - assert( pCur->curFlags & BTCF_ValidOvfl ); - assert( pCur->pBtree->db==pBt->db ); - if( pCur->aOverflow[iIdx+1] ){ - nextPage = pCur->aOverflow[iIdx+1]; - }else{ - rc = getOverflowPage(pBt, nextPage, 0, &nextPage); - } - offset -= ovflSize; - }else{ - /* Need to read this page properly. It contains some of the - ** range of data that is being read (eOp==0) or written (eOp!=0). - */ -#ifdef SQLITE_DIRECT_OVERFLOW_READ - sqlite3_file *fd; -#endif - int a = amt; - if( a + offset > ovflSize ){ - a = ovflSize - offset; - } - -#ifdef SQLITE_DIRECT_OVERFLOW_READ - /* If all the following are true: - ** - ** 1) this is a read operation, and - ** 2) data is required from the start of this overflow page, and - ** 3) the database is file-backed, and - ** 4) there is no open write-transaction, and - ** 5) the database is not a WAL database, - ** 6) all data from the page is being read. - ** 7) at least 4 bytes have already been read into the output buffer - ** - ** then data can be read directly from the database file into the - ** output buffer, bypassing the page-cache altogether. This speeds - ** up loading large records that span many overflow pages. - */ - if( (eOp&0x01)==0 /* (1) */ - && offset==0 /* (2) */ - && (bEnd || a==ovflSize) /* (6) */ - && pBt->inTransaction==TRANS_READ /* (4) */ - && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ - && 0==sqlite3PagerUseWal(pBt->pPager) /* (5) */ - && &pBuf[-4]>=pBufStart /* (7) */ - ){ - u8 aSave[4]; - u8 *aWrite = &pBuf[-4]; - assert( aWrite>=pBufStart ); /* hence (7) */ - memcpy(aSave, aWrite, 4); - rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); - nextPage = get4byte(aWrite); - memcpy(aWrite, aSave, 4); - }else -#endif - - { - DbPage *pDbPage; - rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, - ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0) - ); - if( rc==SQLITE_OK ){ - aPayload = sqlite3PagerGetData(pDbPage); - nextPage = get4byte(aPayload); - rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage); - sqlite3PagerUnref(pDbPage); - offset = 0; - } - } - amt -= a; - pBuf += a; - } - } - } - - if( rc==SQLITE_OK && amt>0 ){ - return SQLITE_CORRUPT_BKPT; - } - return rc; -} - -/* -** Read part of the key associated with cursor pCur. Exactly -** "amt" bytes will be transferred into pBuf[]. The transfer -** begins at "offset". -** -** The caller must ensure that pCur is pointing to a valid row -** in the table. -** -** Return SQLITE_OK on success or an error code if anything goes -** wrong. An error is returned if "offset+amt" is larger than -** the available payload. -*/ -SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - assert( cursorHoldsMutex(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); -} - -/* -** Read part of the data associated with cursor pCur. Exactly -** "amt" bytes will be transfered into pBuf[]. The transfer -** begins at "offset". -** -** Return SQLITE_OK on success or an error code if anything goes -** wrong. An error is returned if "offset+amt" is larger than -** the available payload. -*/ -SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc; - -#ifndef SQLITE_OMIT_INCRBLOB - if ( pCur->eState==CURSOR_INVALID ){ - return SQLITE_ABORT; - } -#endif - - assert( cursorOwnsBtShared(pCur) ); - rc = restoreCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - rc = accessPayload(pCur, offset, amt, pBuf, 0); - } - return rc; -} - -/* -** Return a pointer to payload information from the entry that the -** pCur cursor is pointing to. The pointer is to the beginning of -** the key if index btrees (pPage->intKey==0) and is the data for -** table btrees (pPage->intKey==1). The number of bytes of available -** key/data is written into *pAmt. If *pAmt==0, then the value -** returned will not be a valid pointer. -** -** This routine is an optimization. It is common for the entire key -** and data to fit on the local page and for there to be no overflow -** pages. When that is so, this routine can be used to access the -** key and data without making a copy. If the key and/or data spills -** onto overflow pages, then accessPayload() must be used to reassemble -** the key/data and copy it into a preallocated buffer. -** -** The pointer returned by this routine looks directly into the cached -** page of the database. The data might change or move the next time -** any btree routine is called. -*/ -static const void *fetchPayload( - BtCursor *pCur, /* Cursor pointing to entry to read from */ - u32 *pAmt /* Write the number of available bytes here */ -){ - u32 amt; - assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); - assert( pCur->eState==CURSOR_VALID ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - assert( pCur->info.nSize>0 ); - assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); - assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); - amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); - if( pCur->info.nLocalinfo.nLocal; - *pAmt = amt; - return (void*)pCur->info.pPayload; -} - - -/* -** For the entry that cursor pCur is point to, return as -** many bytes of the key or data as are available on the local -** b-tree page. Write the number of available bytes into *pAmt. -** -** The pointer returned is ephemeral. The key/data may move -** or be destroyed on the next call to any Btree routine, -** including calls from other threads against the same cache. -** Hence, a mutex on the BtShared should be held prior to calling -** this routine. -** -** These routines is used to get quick access to key and data -** in the common case where no overflow pages are used. -*/ -SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ - return fetchPayload(pCur, pAmt); -} - - -/* -** Move the cursor down to a new child page. The newPgno argument is the -** page number of the child page to move to. -** -** This function returns SQLITE_CORRUPT if the page-header flags field of -** the new child page does not match the flags field of the parent (i.e. -** if an intkey page appears to be the parent of a non-intkey page, or -** vice-versa). -*/ -static int moveToChild(BtCursor *pCur, u32 newPgno){ - BtShared *pBt = pCur->pBt; - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPageiPage>=0 ); - if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ - return SQLITE_CORRUPT_BKPT; - } - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->iPage++; - pCur->aiIdx[pCur->iPage] = 0; - return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], - pCur, pCur->curPagerFlags); -} - -#if SQLITE_DEBUG -/* -** Page pParent is an internal (non-leaf) tree page. This function -** asserts that page number iChild is the left-child if the iIdx'th -** cell in page pParent. Or, if iIdx is equal to the total number of -** cells in pParent, that page number iChild is the right-child of -** the page. -*/ -static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ - if( CORRUPT_DB ) return; /* The conditions tested below might not be true - ** in a corrupt database */ - assert( iIdx<=pParent->nCell ); - if( iIdx==pParent->nCell ){ - assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); - }else{ - assert( get4byte(findCell(pParent, iIdx))==iChild ); - } -} -#else -# define assertParentIndex(x,y,z) -#endif - -/* -** Move the cursor up to the parent page. -** -** pCur->idx is set to the cell index that contains the pointer -** to the page we are coming from. If we are coming from the -** right-most child page then pCur->idx is set to one more than -** the largest cell index. -*/ -static void moveToParent(BtCursor *pCur){ - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>0 ); - assert( pCur->apPage[pCur->iPage] ); - assertParentIndex( - pCur->apPage[pCur->iPage-1], - pCur->aiIdx[pCur->iPage-1], - pCur->apPage[pCur->iPage]->pgno - ); - testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - releasePageNotNull(pCur->apPage[pCur->iPage--]); -} - -/* -** Move the cursor to point to the root page of its b-tree structure. -** -** If the table has a virtual root page, then the cursor is moved to point -** to the virtual root page instead of the actual root page. A table has a -** virtual root page when the actual root page contains no cells and a -** single child page. This can only happen with the table rooted at page 1. -** -** If the b-tree structure is empty, the cursor state is set to -** CURSOR_INVALID. Otherwise, the cursor is set to point to the first -** cell located on the root (or virtual root) page and the cursor state -** is set to CURSOR_VALID. -** -** If this function returns successfully, it may be assumed that the -** page-header flags indicate that the [virtual] root-page is the expected -** kind of b-tree page (i.e. if when opening the cursor the caller did not -** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, -** indicating a table b-tree, or if the caller did specify a KeyInfo -** structure the flags byte is set to 0x02 or 0x0A, indicating an index -** b-tree). -*/ -static int moveToRoot(BtCursor *pCur){ - MemPage *pRoot; - int rc = SQLITE_OK; - - assert( cursorOwnsBtShared(pCur) ); - assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); - assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); - if( pCur->eState>=CURSOR_REQUIRESEEK ){ - if( pCur->eState==CURSOR_FAULT ){ - assert( pCur->skipNext!=SQLITE_OK ); - return pCur->skipNext; - } - sqlite3BtreeClearCursor(pCur); - } - - if( pCur->iPage>=0 ){ - while( pCur->iPage ){ - assert( pCur->apPage[pCur->iPage]!=0 ); - releasePageNotNull(pCur->apPage[pCur->iPage--]); - } - }else if( pCur->pgnoRoot==0 ){ - pCur->eState = CURSOR_INVALID; - return SQLITE_OK; - }else{ - assert( pCur->iPage==(-1) ); - rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], - 0, pCur->curPagerFlags); - if( rc!=SQLITE_OK ){ - pCur->eState = CURSOR_INVALID; - return rc; - } - pCur->iPage = 0; - pCur->curIntKey = pCur->apPage[0]->intKey; - } - pRoot = pCur->apPage[0]; - assert( pRoot->pgno==pCur->pgnoRoot ); - - /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor - ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is - ** NULL, the caller expects a table b-tree. If this is not the case, - ** return an SQLITE_CORRUPT error. - ** - ** Earlier versions of SQLite assumed that this test could not fail - ** if the root page was already loaded when this function was called (i.e. - ** if pCur->iPage>=0). But this is not so if the database is corrupted - ** in such a way that page pRoot is linked into a second b-tree table - ** (or the freelist). */ - assert( pRoot->intKey==1 || pRoot->intKey==0 ); - if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ - return SQLITE_CORRUPT_BKPT; - } - - pCur->aiIdx[0] = 0; - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - - if( pRoot->nCell>0 ){ - pCur->eState = CURSOR_VALID; - }else if( !pRoot->leaf ){ - Pgno subpage; - if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; - subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); - pCur->eState = CURSOR_VALID; - rc = moveToChild(pCur, subpage); - }else{ - pCur->eState = CURSOR_INVALID; - } - return rc; -} - -/* -** Move the cursor down to the left-most leaf entry beneath the -** entry to which it is currently pointing. -** -** The left-most leaf is the one with the smallest key - the first -** in ascending order. -*/ -static int moveToLeftmost(BtCursor *pCur){ - Pgno pgno; - int rc = SQLITE_OK; - MemPage *pPage; - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ - assert( pCur->aiIdx[pCur->iPage]nCell ); - pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage])); - rc = moveToChild(pCur, pgno); - } - return rc; -} - -/* -** Move the cursor down to the right-most leaf entry beneath the -** page to which it is currently pointing. Notice the difference -** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() -** finds the left-most entry beneath the *entry* whereas moveToRightmost() -** finds the right-most entry beneath the *page*. -** -** The right-most entry is the one with the largest key - the last -** key in ascending order. -*/ -static int moveToRightmost(BtCursor *pCur){ - Pgno pgno; - int rc = SQLITE_OK; - MemPage *pPage = 0; - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->eState==CURSOR_VALID ); - while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ - pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - pCur->aiIdx[pCur->iPage] = pPage->nCell; - rc = moveToChild(pCur, pgno); - if( rc ) return rc; - } - pCur->aiIdx[pCur->iPage] = pPage->nCell-1; - assert( pCur->info.nSize==0 ); - assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); - return SQLITE_OK; -} - -/* Move the cursor to the first entry in the table. Return SQLITE_OK -** on success. Set *pRes to 0 if the cursor actually points to something -** or set *pRes to 1 if the table is empty. -*/ -SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ - int rc; - - assert( cursorOwnsBtShared(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - if( pCur->eState==CURSOR_INVALID ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; - }else{ - assert( pCur->apPage[pCur->iPage]->nCell>0 ); - *pRes = 0; - rc = moveToLeftmost(pCur); - } - } - return rc; -} - -/* Move the cursor to the last entry in the table. Return SQLITE_OK -** on success. Set *pRes to 0 if the cursor actually points to something -** or set *pRes to 1 if the table is empty. -*/ -SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ - int rc; - - assert( cursorOwnsBtShared(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - - /* If the cursor already points to the last entry, this is a no-op. */ - if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ -#ifdef SQLITE_DEBUG - /* This block serves to assert() that the cursor really does point - ** to the last entry in the b-tree. */ - int ii; - for(ii=0; iiiPage; ii++){ - assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); - } - assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 ); - assert( pCur->apPage[pCur->iPage]->leaf ); -#endif - return SQLITE_OK; - } - - rc = moveToRoot(pCur); - if( rc==SQLITE_OK ){ - if( CURSOR_INVALID==pCur->eState ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; - }else{ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - if( rc==SQLITE_OK ){ - pCur->curFlags |= BTCF_AtLast; - }else{ - pCur->curFlags &= ~BTCF_AtLast; - } - - } - } - return rc; -} - -/* Move the cursor so that it points to an entry near the key -** specified by pIdxKey or intKey. Return a success code. -** -** For INTKEY tables, the intKey parameter is used. pIdxKey -** must be NULL. For index tables, pIdxKey is used and intKey -** is ignored. -** -** If an exact match is not found, then the cursor is always -** left pointing at a leaf page which would hold the entry if it -** were present. The cursor might point to an entry that comes -** before or after the key. -** -** An integer is written into *pRes which is the result of -** comparing the key with the entry to which the cursor is -** pointing. The meaning of the integer written into -** *pRes is as follows: -** -** *pRes<0 The cursor is left pointing at an entry that -** is smaller than intKey/pIdxKey or if the table is empty -** and the cursor is therefore left point to nothing. -** -** *pRes==0 The cursor is left pointing at an entry that -** exactly matches intKey/pIdxKey. -** -** *pRes>0 The cursor is left pointing at an entry that -** is larger than intKey/pIdxKey. -** -** For index tables, the pIdxKey->eqSeen field is set to 1 if there -** exists an entry in the table that exactly matches pIdxKey. -*/ -SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( - BtCursor *pCur, /* The cursor to be moved */ - UnpackedRecord *pIdxKey, /* Unpacked index key */ - i64 intKey, /* The table key */ - int biasRight, /* If true, bias the search to the high end */ - int *pRes /* Write search results here */ -){ - int rc; - RecordCompare xRecordCompare; - - assert( cursorOwnsBtShared(pCur) ); - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - assert( pRes ); - assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); - assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) ); - - /* If the cursor is already positioned at the point we are trying - ** to move to, then just return without doing any work */ - if( pIdxKey==0 - && pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 - ){ - if( pCur->info.nKey==intKey ){ - *pRes = 0; - return SQLITE_OK; - } - if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKeyerrCode = 0; - assert( pIdxKey->default_rc==1 - || pIdxKey->default_rc==0 - || pIdxKey->default_rc==-1 - ); - }else{ - xRecordCompare = 0; /* All keys are integers */ - } - - rc = moveToRoot(pCur); - if( rc ){ - return rc; - } - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); - assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); - if( pCur->eState==CURSOR_INVALID ){ - *pRes = -1; - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - return SQLITE_OK; - } - assert( pCur->apPage[0]->intKey==pCur->curIntKey ); - assert( pCur->curIntKey || pIdxKey ); - for(;;){ - int lwr, upr, idx, c; - Pgno chldPg; - MemPage *pPage = pCur->apPage[pCur->iPage]; - u8 *pCell; /* Pointer to current cell in pPage */ - - /* pPage->nCell must be greater than zero. If this is the root-page - ** the cursor would have been INVALID above and this for(;;) loop - ** not run. If this is not the root-page, then the moveToChild() routine - ** would have already detected db corruption. Similarly, pPage must - ** be the right kind (index or table) of b-tree page. Otherwise - ** a moveToChild() or moveToRoot() call would have detected corruption. */ - assert( pPage->nCell>0 ); - assert( pPage->intKey==(pIdxKey==0) ); - lwr = 0; - upr = pPage->nCell-1; - assert( biasRight==0 || biasRight==1 ); - idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ - pCur->aiIdx[pCur->iPage] = (u16)idx; - if( xRecordCompare==0 ){ - for(;;){ - i64 nCellKey; - pCell = findCellPastPtr(pPage, idx); - if( pPage->intKeyLeaf ){ - while( 0x80 <= *(pCell++) ){ - if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; - } - } - getVarint(pCell, (u64*)&nCellKey); - if( nCellKeyupr ){ c = -1; break; } - }else if( nCellKey>intKey ){ - upr = idx-1; - if( lwr>upr ){ c = +1; break; } - }else{ - assert( nCellKey==intKey ); - pCur->curFlags |= BTCF_ValidNKey; - pCur->info.nKey = nCellKey; - pCur->aiIdx[pCur->iPage] = (u16)idx; - if( !pPage->leaf ){ - lwr = idx; - goto moveto_next_layer; - }else{ - *pRes = 0; - rc = SQLITE_OK; - goto moveto_finish; - } - } - assert( lwr+upr>=0 ); - idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ - } - }else{ - for(;;){ - int nCell; /* Size of the pCell cell in bytes */ - pCell = findCellPastPtr(pPage, idx); - - /* The maximum supported page-size is 65536 bytes. This means that - ** the maximum number of record bytes stored on an index B-Tree - ** page is less than 16384 bytes and may be stored as a 2-byte - ** varint. This information is used to attempt to avoid parsing - ** the entire cell by checking for the cases where the record is - ** stored entirely within the b-tree page by inspecting the first - ** 2 bytes of the cell. - */ - nCell = pCell[0]; - if( nCell<=pPage->max1bytePayload ){ - /* This branch runs if the record-size field of the cell is a - ** single byte varint and the record fits entirely on the main - ** b-tree page. */ - testcase( pCell+nCell+1==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) - && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal - ){ - /* The record-size field is a 2 byte varint and the record - ** fits entirely on the main b-tree page. */ - testcase( pCell+nCell+2==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); - }else{ - /* The record flows over onto one or more overflow pages. In - ** this case the whole cell needs to be parsed, a buffer allocated - ** and accessPayload() used to retrieve the record into the - ** buffer before VdbeRecordCompare() can be called. - ** - ** If the record is corrupt, the xRecordCompare routine may read - ** up to two varints past the end of the buffer. An extra 18 - ** bytes of padding is allocated at the end of the buffer in - ** case this happens. */ - void *pCellKey; - u8 * const pCellBody = pCell - pPage->childPtrSize; - pPage->xParseCell(pPage, pCellBody, &pCur->info); - nCell = (int)pCur->info.nKey; - testcase( nCell<0 ); /* True if key size is 2^32 or more */ - testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ - testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ - testcase( nCell==2 ); /* Minimum legal index key size */ - if( nCell<2 ){ - rc = SQLITE_CORRUPT_BKPT; - goto moveto_finish; - } - pCellKey = sqlite3Malloc( nCell+18 ); - if( pCellKey==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto moveto_finish; - } - pCur->aiIdx[pCur->iPage] = (u16)idx; - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); - if( rc ){ - sqlite3_free(pCellKey); - goto moveto_finish; - } - c = xRecordCompare(nCell, pCellKey, pIdxKey); - sqlite3_free(pCellKey); - } - assert( - (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) - && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) - ); - if( c<0 ){ - lwr = idx+1; - }else if( c>0 ){ - upr = idx-1; - }else{ - assert( c==0 ); - *pRes = 0; - rc = SQLITE_OK; - pCur->aiIdx[pCur->iPage] = (u16)idx; - if( pIdxKey->errCode ) rc = SQLITE_CORRUPT; - goto moveto_finish; - } - if( lwr>upr ) break; - assert( lwr+upr>=0 ); - idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ - } - } - assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); - assert( pPage->isInit ); - if( pPage->leaf ){ - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - pCur->aiIdx[pCur->iPage] = (u16)idx; - *pRes = c; - rc = SQLITE_OK; - goto moveto_finish; - } -moveto_next_layer: - if( lwr>=pPage->nCell ){ - chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); - }else{ - chldPg = get4byte(findCell(pPage, lwr)); - } - pCur->aiIdx[pCur->iPage] = (u16)lwr; - rc = moveToChild(pCur, chldPg); - if( rc ) break; - } -moveto_finish: - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - return rc; -} - - -/* -** Return TRUE if the cursor is not pointing at an entry of the table. -** -** TRUE will be returned after a call to sqlite3BtreeNext() moves -** past the last entry in the table or sqlite3BtreePrev() moves past -** the first entry. TRUE is also returned if the table is empty. -*/ -SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){ - /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries - ** have been deleted? This API will need to change to return an error code - ** as well as the boolean result value. - */ - return (CURSOR_VALID!=pCur->eState); -} - -/* -** Advance the cursor to the next entry in the database. If -** successful then set *pRes=0. If the cursor -** was already pointing to the last entry in the database before -** this routine was called, then set *pRes=1. -** -** The main entry point is sqlite3BtreeNext(). That routine is optimized -** for the common case of merely incrementing the cell counter BtCursor.aiIdx -** to the next cell on the current page. The (slower) btreeNext() helper -** routine is called when it is necessary to move to a different page or -** to restore the cursor. -** -** The calling function will set *pRes to 0 or 1. The initial *pRes value -** will be 1 if the cursor being stepped corresponds to an SQL index and -** if this routine could have been skipped if that SQL index had been -** a unique index. Otherwise the caller will have set *pRes to zero. -** Zero is the common case. The btree implementation is free to use the -** initial *pRes value as a hint to improve performance, but the current -** SQLite btree implementation does not. (Note that the comdb2 btree -** implementation does use this hint, however.) -*/ -static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){ - int rc; - int idx; - MemPage *pPage; - - assert( cursorOwnsBtShared(pCur) ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - assert( *pRes==0 ); - if( pCur->eState!=CURSOR_VALID ){ - assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); - rc = restoreCursorPosition(pCur); - if( rc!=SQLITE_OK ){ - return rc; - } - if( CURSOR_INVALID==pCur->eState ){ - *pRes = 1; - return SQLITE_OK; - } - if( pCur->skipNext ){ - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); - pCur->eState = CURSOR_VALID; - if( pCur->skipNext>0 ){ - pCur->skipNext = 0; - return SQLITE_OK; - } - pCur->skipNext = 0; - } - } - - pPage = pCur->apPage[pCur->iPage]; - idx = ++pCur->aiIdx[pCur->iPage]; - assert( pPage->isInit ); - - /* If the database file is corrupt, it is possible for the value of idx - ** to be invalid here. This can only occur if a second cursor modifies - ** the page while cursor pCur is holding a reference to it. Which can - ** only happen if the database is corrupt in such a way as to link the - ** page into more than one b-tree structure. */ - testcase( idx>pPage->nCell ); - - if( idx>=pPage->nCell ){ - if( !pPage->leaf ){ - rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); - if( rc ) return rc; - return moveToLeftmost(pCur); - } - do{ - if( pCur->iPage==0 ){ - *pRes = 1; - pCur->eState = CURSOR_INVALID; - return SQLITE_OK; - } - moveToParent(pCur); - pPage = pCur->apPage[pCur->iPage]; - }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); - if( pPage->intKey ){ - return sqlite3BtreeNext(pCur, pRes); - }else{ - return SQLITE_OK; - } - } - if( pPage->leaf ){ - return SQLITE_OK; - }else{ - return moveToLeftmost(pCur); - } -} -SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ - MemPage *pPage; - assert( cursorOwnsBtShared(pCur) ); - assert( pRes!=0 ); - assert( *pRes==0 || *pRes==1 ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - *pRes = 0; - if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes); - pPage = pCur->apPage[pCur->iPage]; - if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){ - pCur->aiIdx[pCur->iPage]--; - return btreeNext(pCur, pRes); - } - if( pPage->leaf ){ - return SQLITE_OK; - }else{ - return moveToLeftmost(pCur); - } -} - -/* -** Step the cursor to the back to the previous entry in the database. If -** successful then set *pRes=0. If the cursor -** was already pointing to the first entry in the database before -** this routine was called, then set *pRes=1. -** -** The main entry point is sqlite3BtreePrevious(). That routine is optimized -** for the common case of merely decrementing the cell counter BtCursor.aiIdx -** to the previous cell on the current page. The (slower) btreePrevious() -** helper routine is called when it is necessary to move to a different page -** or to restore the cursor. -** -** The calling function will set *pRes to 0 or 1. The initial *pRes value -** will be 1 if the cursor being stepped corresponds to an SQL index and -** if this routine could have been skipped if that SQL index had been -** a unique index. Otherwise the caller will have set *pRes to zero. -** Zero is the common case. The btree implementation is free to use the -** initial *pRes value as a hint to improve performance, but the current -** SQLite btree implementation does not. (Note that the comdb2 btree -** implementation does use this hint, however.) -*/ -static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){ - int rc; - MemPage *pPage; - - assert( cursorOwnsBtShared(pCur) ); - assert( pRes!=0 ); - assert( *pRes==0 ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); - assert( pCur->info.nSize==0 ); - if( pCur->eState!=CURSOR_VALID ){ - rc = restoreCursorPosition(pCur); - if( rc!=SQLITE_OK ){ - return rc; - } - if( CURSOR_INVALID==pCur->eState ){ - *pRes = 1; - return SQLITE_OK; - } - if( pCur->skipNext ){ - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); - pCur->eState = CURSOR_VALID; - if( pCur->skipNext<0 ){ - pCur->skipNext = 0; - return SQLITE_OK; - } - pCur->skipNext = 0; - } - } - - pPage = pCur->apPage[pCur->iPage]; - assert( pPage->isInit ); - if( !pPage->leaf ){ - int idx = pCur->aiIdx[pCur->iPage]; - rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); - if( rc ) return rc; - rc = moveToRightmost(pCur); - }else{ - while( pCur->aiIdx[pCur->iPage]==0 ){ - if( pCur->iPage==0 ){ - pCur->eState = CURSOR_INVALID; - *pRes = 1; - return SQLITE_OK; - } - moveToParent(pCur); - } - assert( pCur->info.nSize==0 ); - assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 ); - - pCur->aiIdx[pCur->iPage]--; - pPage = pCur->apPage[pCur->iPage]; - if( pPage->intKey && !pPage->leaf ){ - rc = sqlite3BtreePrevious(pCur, pRes); - }else{ - rc = SQLITE_OK; - } - } - return rc; -} -SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ - assert( cursorOwnsBtShared(pCur) ); - assert( pRes!=0 ); - assert( *pRes==0 || *pRes==1 ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); - *pRes = 0; - pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); - pCur->info.nSize = 0; - if( pCur->eState!=CURSOR_VALID - || pCur->aiIdx[pCur->iPage]==0 - || pCur->apPage[pCur->iPage]->leaf==0 - ){ - return btreePrevious(pCur, pRes); - } - pCur->aiIdx[pCur->iPage]--; - return SQLITE_OK; -} - -/* -** Allocate a new page from the database file. -** -** The new page is marked as dirty. (In other words, sqlite3PagerWrite() -** has already been called on the new page.) The new page has also -** been referenced and the calling routine is responsible for calling -** sqlite3PagerUnref() on the new page when it is done. -** -** SQLITE_OK is returned on success. Any other return value indicates -** an error. *ppPage is set to NULL in the event of an error. -** -** If the "nearby" parameter is not 0, then an effort is made to -** locate a page close to the page number "nearby". This can be used in an -** attempt to keep related pages close to each other in the database file, -** which in turn can make database access faster. -** -** If the eMode parameter is BTALLOC_EXACT and the nearby page exists -** anywhere on the free-list, then it is guaranteed to be returned. If -** eMode is BTALLOC_LT then the page returned will be less than or equal -** to nearby if any such page exists. If eMode is BTALLOC_ANY then there -** are no restrictions on which page is returned. -*/ -static int allocateBtreePage( - BtShared *pBt, /* The btree */ - MemPage **ppPage, /* Store pointer to the allocated page here */ - Pgno *pPgno, /* Store the page number here */ - Pgno nearby, /* Search for a page near this one */ - u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */ -){ - MemPage *pPage1; - int rc; - u32 n; /* Number of pages on the freelist */ - u32 k; /* Number of leaves on the trunk of the freelist */ - MemPage *pTrunk = 0; - MemPage *pPrevTrunk = 0; - Pgno mxPage; /* Total size of the database file */ - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); - pPage1 = pBt->pPage1; - mxPage = btreePagecount(pBt); - /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 - ** stores stores the total number of pages on the freelist. */ - n = get4byte(&pPage1->aData[36]); - testcase( n==mxPage-1 ); - if( n>=mxPage ){ - return SQLITE_CORRUPT_BKPT; - } - if( n>0 ){ - /* There are pages on the freelist. Reuse one of those pages. */ - Pgno iTrunk; - u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ - u32 nSearch = 0; /* Count of the number of search attempts */ - - /* If eMode==BTALLOC_EXACT and a query of the pointer-map - ** shows that the page 'nearby' is somewhere on the free-list, then - ** the entire-list will be searched for that page. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - if( eMode==BTALLOC_EXACT ){ - if( nearby<=mxPage ){ - u8 eType; - assert( nearby>0 ); - assert( pBt->autoVacuum ); - rc = ptrmapGet(pBt, nearby, &eType, 0); - if( rc ) return rc; - if( eType==PTRMAP_FREEPAGE ){ - searchList = 1; - } - } - }else if( eMode==BTALLOC_LE ){ - searchList = 1; - } -#endif - - /* Decrement the free-list count by 1. Set iTrunk to the index of the - ** first free-list trunk page. iPrevTrunk is initially 1. - */ - rc = sqlite3PagerWrite(pPage1->pDbPage); - if( rc ) return rc; - put4byte(&pPage1->aData[36], n-1); - - /* The code within this loop is run only once if the 'searchList' variable - ** is not true. Otherwise, it runs once for each trunk-page on the - ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT) - ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT) - */ - do { - pPrevTrunk = pTrunk; - if( pPrevTrunk ){ - /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page - ** is the page number of the next freelist trunk page in the list or - ** zero if this is the last freelist trunk page. */ - iTrunk = get4byte(&pPrevTrunk->aData[0]); - }else{ - /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32 - ** stores the page number of the first page of the freelist, or zero if - ** the freelist is empty. */ - iTrunk = get4byte(&pPage1->aData[32]); - } - testcase( iTrunk==mxPage ); - if( iTrunk>mxPage || nSearch++ > n ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0); - } - if( rc ){ - pTrunk = 0; - goto end_allocate_page; - } - assert( pTrunk!=0 ); - assert( pTrunk->aData!=0 ); - /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page - ** is the number of leaf page pointers to follow. */ - k = get4byte(&pTrunk->aData[4]); - if( k==0 && !searchList ){ - /* The trunk has no leaves and the list is not being searched. - ** So extract the trunk page itself and use it as the newly - ** allocated page */ - assert( pPrevTrunk==0 ); - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - *pPgno = iTrunk; - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - *ppPage = pTrunk; - pTrunk = 0; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>(u32)(pBt->usableSize/4 - 2) ){ - /* Value of k is out of range. Database corruption */ - rc = SQLITE_CORRUPT_BKPT; - goto end_allocate_page; -#ifndef SQLITE_OMIT_AUTOVACUUM - }else if( searchList - && (nearby==iTrunk || (iTrunkpDbPage); - if( rc ){ - goto end_allocate_page; - } - if( k==0 ){ - if( !pPrevTrunk ){ - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - }else{ - rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); - if( rc!=SQLITE_OK ){ - goto end_allocate_page; - } - memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); - } - }else{ - /* The trunk page is required by the caller but it contains - ** pointers to free-list leaves. The first leaf becomes a trunk - ** page in this case. - */ - MemPage *pNewTrunk; - Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); - if( iNewTrunk>mxPage ){ - rc = SQLITE_CORRUPT_BKPT; - goto end_allocate_page; - } - testcase( iNewTrunk==mxPage ); - rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0); - if( rc!=SQLITE_OK ){ - goto end_allocate_page; - } - rc = sqlite3PagerWrite(pNewTrunk->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pNewTrunk); - goto end_allocate_page; - } - memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); - put4byte(&pNewTrunk->aData[4], k-1); - memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); - releasePage(pNewTrunk); - if( !pPrevTrunk ){ - assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); - put4byte(&pPage1->aData[32], iNewTrunk); - }else{ - rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); - if( rc ){ - goto end_allocate_page; - } - put4byte(&pPrevTrunk->aData[0], iNewTrunk); - } - } - pTrunk = 0; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); -#endif - }else if( k>0 ){ - /* Extract a leaf from the trunk */ - u32 closest; - Pgno iPage; - unsigned char *aData = pTrunk->aData; - if( nearby>0 ){ - u32 i; - closest = 0; - if( eMode==BTALLOC_LE ){ - for(i=0; imxPage ){ - rc = SQLITE_CORRUPT_BKPT; - goto end_allocate_page; - } - testcase( iPage==mxPage ); - if( !searchList - || (iPage==nearby || (iPagepgno, n-1)); - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc ) goto end_allocate_page; - if( closestpDbPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - *ppPage = 0; - } - } - searchList = 0; - } - } - releasePage(pPrevTrunk); - pPrevTrunk = 0; - }while( searchList ); - }else{ - /* There are no pages on the freelist, so append a new page to the - ** database image. - ** - ** Normally, new pages allocated by this block can be requested from the - ** pager layer with the 'no-content' flag set. This prevents the pager - ** from trying to read the pages content from disk. However, if the - ** current transaction has already run one or more incremental-vacuum - ** steps, then the page we are about to allocate may contain content - ** that is required in the event of a rollback. In this case, do - ** not set the no-content flag. This causes the pager to load and journal - ** the current page content before overwriting it. - ** - ** Note that the pager will not actually attempt to load or journal - ** content for any page that really does lie past the end of the database - ** file on disk. So the effects of disabling the no-content optimization - ** here are confined to those pages that lie between the end of the - ** database image and the end of the database file. - */ - int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0; - - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc ) return rc; - pBt->nPage++; - if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; - -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ - /* If *pPgno refers to a pointer-map page, allocate two new pages - ** at the end of the file instead of one. The first allocated page - ** becomes a new pointer-map page, the second is used by the caller. - */ - MemPage *pPg = 0; - TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); - assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); - rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pPg->pDbPage); - releasePage(pPg); - } - if( rc ) return rc; - pBt->nPage++; - if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } - } -#endif - put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); - *pPgno = pBt->nPage; - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent); - if( rc ) return rc; - rc = sqlite3PagerWrite((*ppPage)->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(*ppPage); - *ppPage = 0; - } - TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); - } - - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - -end_allocate_page: - releasePage(pTrunk); - releasePage(pPrevTrunk); - assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); - assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 ); - return rc; -} - -/* -** This function is used to add page iPage to the database file free-list. -** It is assumed that the page is not already a part of the free-list. -** -** The value passed as the second argument to this function is optional. -** If the caller happens to have a pointer to the MemPage object -** corresponding to page iPage handy, it may pass it as the second value. -** Otherwise, it may pass NULL. -** -** If a pointer to a MemPage object is passed as the second argument, -** its reference count is not altered by this function. -*/ -static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ - MemPage *pTrunk = 0; /* Free-list trunk page */ - Pgno iTrunk = 0; /* Page number of free-list trunk page */ - MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ - MemPage *pPage; /* Page being freed. May be NULL. */ - int rc; /* Return Code */ - int nFree; /* Initial number of pages on free-list */ - - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( CORRUPT_DB || iPage>1 ); - assert( !pMemPage || pMemPage->pgno==iPage ); - - if( iPage<2 ) return SQLITE_CORRUPT_BKPT; - if( pMemPage ){ - pPage = pMemPage; - sqlite3PagerRef(pPage->pDbPage); - }else{ - pPage = btreePageLookup(pBt, iPage); - } - - /* Increment the free page count on pPage1 */ - rc = sqlite3PagerWrite(pPage1->pDbPage); - if( rc ) goto freepage_out; - nFree = get4byte(&pPage1->aData[36]); - put4byte(&pPage1->aData[36], nFree+1); - - if( pBt->btsFlags & BTS_SECURE_DELETE ){ - /* If the secure_delete option is enabled, then - ** always fully overwrite deleted information with zeros. - */ - if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) - || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) - ){ - goto freepage_out; - } - memset(pPage->aData, 0, pPage->pBt->pageSize); - } - - /* If the database supports auto-vacuum, write an entry in the pointer-map - ** to indicate that the page is free. - */ - if( ISAUTOVACUUM ){ - ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); - if( rc ) goto freepage_out; - } - - /* Now manipulate the actual database free-list structure. There are two - ** possibilities. If the free-list is currently empty, or if the first - ** trunk page in the free-list is full, then this page will become a - ** new free-list trunk page. Otherwise, it will become a leaf of the - ** first trunk page in the current free-list. This block tests if it - ** is possible to add the page as a new free-list leaf. - */ - if( nFree!=0 ){ - u32 nLeaf; /* Initial number of leaf cells on trunk page */ - - iTrunk = get4byte(&pPage1->aData[32]); - rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); - if( rc!=SQLITE_OK ){ - goto freepage_out; - } - - nLeaf = get4byte(&pTrunk->aData[4]); - assert( pBt->usableSize>32 ); - if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ - rc = SQLITE_CORRUPT_BKPT; - goto freepage_out; - } - if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ - /* In this case there is room on the trunk page to insert the page - ** being freed as a new leaf. - ** - ** Note that the trunk page is not really full until it contains - ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have - ** coded. But due to a coding error in versions of SQLite prior to - ** 3.6.0, databases with freelist trunk pages holding more than - ** usableSize/4 - 8 entries will be reported as corrupt. In order - ** to maintain backwards compatibility with older versions of SQLite, - ** we will continue to restrict the number of entries to usableSize/4 - 8 - ** for now. At some point in the future (once everyone has upgraded - ** to 3.6.0 or later) we should consider fixing the conditional above - ** to read "usableSize/4-2" instead of "usableSize/4-8". - ** - ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still - ** avoid using the last six entries in the freelist trunk page array in - ** order that database files created by newer versions of SQLite can be - ** read by older versions of SQLite. - */ - rc = sqlite3PagerWrite(pTrunk->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(&pTrunk->aData[4], nLeaf+1); - put4byte(&pTrunk->aData[8+nLeaf*4], iPage); - if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ - sqlite3PagerDontWrite(pPage->pDbPage); - } - rc = btreeSetHasContent(pBt, iPage); - } - TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); - goto freepage_out; - } - } - - /* If control flows to this point, then it was not possible to add the - ** the page being freed as a leaf page of the first trunk in the free-list. - ** Possibly because the free-list is empty, or possibly because the - ** first trunk in the free-list is full. Either way, the page being freed - ** will become the new first trunk page in the free-list. - */ - if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ - goto freepage_out; - } - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc!=SQLITE_OK ){ - goto freepage_out; - } - put4byte(pPage->aData, iTrunk); - put4byte(&pPage->aData[4], 0); - put4byte(&pPage1->aData[32], iPage); - TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); - -freepage_out: - if( pPage ){ - pPage->isInit = 0; - } - releasePage(pPage); - releasePage(pTrunk); - return rc; -} -static void freePage(MemPage *pPage, int *pRC){ - if( (*pRC)==SQLITE_OK ){ - *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); - } -} - -/* -** Free any overflow pages associated with the given Cell. Write the -** local Cell size (the number of bytes on the original page, omitting -** overflow) into *pnSize. -*/ -static int clearCell( - MemPage *pPage, /* The page that contains the Cell */ - unsigned char *pCell, /* First byte of the Cell */ - u16 *pnSize /* Write the size of the Cell here */ -){ - BtShared *pBt = pPage->pBt; - CellInfo info; - Pgno ovflPgno; - int rc; - int nOvfl; - u32 ovflPageSize; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->xParseCell(pPage, pCell, &info); - *pnSize = info.nSize; - if( info.nLocal==info.nPayload ){ - return SQLITE_OK; /* No overflow pages. Return without doing anything */ - } - if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){ - return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */ - } - ovflPgno = get4byte(pCell + info.nSize - 4); - assert( pBt->usableSize > 4 ); - ovflPageSize = pBt->usableSize - 4; - nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize; - assert( nOvfl>0 || - (CORRUPT_DB && (info.nPayload + ovflPageSize)btreePagecount(pBt) ){ - /* 0 is not a legal page number and page 1 cannot be an - ** overflow page. Therefore if ovflPgno<2 or past the end of the - ** file the database must be corrupt. */ - return SQLITE_CORRUPT_BKPT; - } - if( nOvfl ){ - rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); - if( rc ) return rc; - } - - if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) - && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 - ){ - /* There is no reason any cursor should have an outstanding reference - ** to an overflow page belonging to a cell that is being deleted/updated. - ** So if there exists more than one reference to this page, then it - ** must not really be an overflow page and the database must be corrupt. - ** It is helpful to detect this before calling freePage2(), as - ** freePage2() may zero the page contents if secure-delete mode is - ** enabled. If this 'overflow' page happens to be a page that the - ** caller is iterating through or using in some other way, this - ** can be problematic. - */ - rc = SQLITE_CORRUPT_BKPT; - }else{ - rc = freePage2(pBt, pOvfl, ovflPgno); - } - - if( pOvfl ){ - sqlite3PagerUnref(pOvfl->pDbPage); - } - if( rc ) return rc; - ovflPgno = iNext; - } - return SQLITE_OK; -} - -/* -** Create the byte sequence used to represent a cell on page pPage -** and write that byte sequence into pCell[]. Overflow pages are -** allocated and filled in as necessary. The calling procedure -** is responsible for making sure sufficient space has been allocated -** for pCell[]. -** -** Note that pCell does not necessary need to point to the pPage->aData -** area. pCell might point to some temporary storage. The cell will -** be constructed in this temporary area then copied into pPage->aData -** later. -*/ -static int fillInCell( - MemPage *pPage, /* The page that contains the cell */ - unsigned char *pCell, /* Complete text of the cell */ - const BtreePayload *pX, /* Payload with which to construct the cell */ - int *pnSize /* Write cell size here */ -){ - int nPayload; - const u8 *pSrc; - int nSrc, n, rc; - int spaceLeft; - MemPage *pOvfl = 0; - MemPage *pToRelease = 0; - unsigned char *pPrior; - unsigned char *pPayload; - BtShared *pBt = pPage->pBt; - Pgno pgnoOvfl = 0; - int nHeader; - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - - /* pPage is not necessarily writeable since pCell might be auxiliary - ** buffer space that is separate from the pPage buffer area */ - assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - /* Fill in the header. */ - nHeader = pPage->childPtrSize; - if( pPage->intKey ){ - nPayload = pX->nData + pX->nZero; - pSrc = pX->pData; - nSrc = pX->nData; - assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ - nHeader += putVarint32(&pCell[nHeader], nPayload); - nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); - }else{ - assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); - nSrc = nPayload = (int)pX->nKey; - pSrc = pX->pKey; - nHeader += putVarint32(&pCell[nHeader], nPayload); - } - - /* Fill in the payload */ - if( nPayload<=pPage->maxLocal ){ - n = nHeader + nPayload; - testcase( n==3 ); - testcase( n==4 ); - if( n<4 ) n = 4; - *pnSize = n; - spaceLeft = nPayload; - pPrior = pCell; - }else{ - int mn = pPage->minLocal; - n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); - testcase( n==pPage->maxLocal ); - testcase( n==pPage->maxLocal+1 ); - if( n > pPage->maxLocal ) n = mn; - spaceLeft = n; - *pnSize = n + nHeader + 4; - pPrior = &pCell[nHeader+n]; - } - pPayload = &pCell[nHeader]; - - /* At this point variables should be set as follows: - ** - ** nPayload Total payload size in bytes - ** pPayload Begin writing payload here - ** spaceLeft Space available at pPayload. If nPayload>spaceLeft, - ** that means content must spill into overflow pages. - ** *pnSize Size of the local cell (not counting overflow pages) - ** pPrior Where to write the pgno of the first overflow page - ** - ** Use a call to btreeParseCellPtr() to verify that the values above - ** were computed correctly. - */ -#if SQLITE_DEBUG - { - CellInfo info; - pPage->xParseCell(pPage, pCell, &info); - assert( nHeader==(int)(info.pPayload - pCell) ); - assert( info.nKey==pX->nKey ); - assert( *pnSize == info.nSize ); - assert( spaceLeft == info.nLocal ); - } -#endif - - /* Write the payload into the local Cell and any extra into overflow pages */ - while( nPayload>0 ){ - if( spaceLeft==0 ){ -#ifndef SQLITE_OMIT_AUTOVACUUM - Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ - if( pBt->autoVacuum ){ - do{ - pgnoOvfl++; - } while( - PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) - ); - } -#endif - rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); -#ifndef SQLITE_OMIT_AUTOVACUUM - /* If the database supports auto-vacuum, and the second or subsequent - ** overflow page is being allocated, add an entry to the pointer-map - ** for that page now. - ** - ** If this is the first overflow page, then write a partial entry - ** to the pointer-map. If we write nothing to this pointer-map slot, - ** then the optimistic overflow chain processing in clearCell() - ** may misinterpret the uninitialized values and delete the - ** wrong pages from the database. - */ - if( pBt->autoVacuum && rc==SQLITE_OK ){ - u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); - ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); - if( rc ){ - releasePage(pOvfl); - } - } -#endif - if( rc ){ - releasePage(pToRelease); - return rc; - } - - /* If pToRelease is not zero than pPrior points into the data area - ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); - - /* If pPrior is part of the data area of pPage, then make sure pPage - ** is still writeable */ - assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - put4byte(pPrior, pgnoOvfl); - releasePage(pToRelease); - pToRelease = pOvfl; - pPrior = pOvfl->aData; - put4byte(pPrior, 0); - pPayload = &pOvfl->aData[4]; - spaceLeft = pBt->usableSize - 4; - } - n = nPayload; - if( n>spaceLeft ) n = spaceLeft; - - /* If pToRelease is not zero than pPayload points into the data area - ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); - - /* If pPayload is part of the data area of pPage, then make sure pPage - ** is still writeable */ - assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - if( nSrc>0 ){ - if( n>nSrc ) n = nSrc; - assert( pSrc ); - memcpy(pPayload, pSrc, n); - }else{ - memset(pPayload, 0, n); - } - nPayload -= n; - pPayload += n; - pSrc += n; - nSrc -= n; - spaceLeft -= n; - } - releasePage(pToRelease); - return SQLITE_OK; -} - -/* -** Remove the i-th cell from pPage. This routine effects pPage only. -** The cell content is not freed or deallocated. It is assumed that -** the cell content has been copied someplace else. This routine just -** removes the reference to the cell from pPage. -** -** "sz" must be the number of bytes in the cell. -*/ -static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ - u32 pc; /* Offset to cell content of cell being deleted */ - u8 *data; /* pPage->aData */ - u8 *ptr; /* Used to move bytes around within data[] */ - int rc; /* The return code */ - int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ - - if( *pRC ) return; - - assert( idx>=0 && idxnCell ); - assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - data = pPage->aData; - ptr = &pPage->aCellIdx[2*idx]; - pc = get2byte(ptr); - hdr = pPage->hdrOffset; - testcase( pc==get2byte(&data[hdr+5]) ); - testcase( pc+sz==pPage->pBt->usableSize ); - if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ - *pRC = SQLITE_CORRUPT_BKPT; - return; - } - rc = freeSpace(pPage, pc, sz); - if( rc ){ - *pRC = rc; - return; - } - pPage->nCell--; - if( pPage->nCell==0 ){ - memset(&data[hdr+1], 0, 4); - data[hdr+7] = 0; - put2byte(&data[hdr+5], pPage->pBt->usableSize); - pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset - - pPage->childPtrSize - 8; - }else{ - memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); - put2byte(&data[hdr+3], pPage->nCell); - pPage->nFree += 2; - } -} - -/* -** Insert a new cell on pPage at cell index "i". pCell points to the -** content of the cell. -** -** If the cell content will fit on the page, then put it there. If it -** will not fit, then make a copy of the cell content into pTemp if -** pTemp is not null. Regardless of pTemp, allocate a new entry -** in pPage->apOvfl[] and make it point to the cell content (either -** in pTemp or the original pCell) and also record its index. -** Allocating a new entry in pPage->aCell[] implies that -** pPage->nOverflow is incremented. -** -** *pRC must be SQLITE_OK when this routine is called. -*/ -static void insertCell( - MemPage *pPage, /* Page into which we are copying */ - int i, /* New cell becomes the i-th cell of the page */ - u8 *pCell, /* Content of the new cell */ - int sz, /* Bytes of content in pCell */ - u8 *pTemp, /* Temp storage space for pCell, if needed */ - Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ - int *pRC /* Read and write return code from here */ -){ - int idx = 0; /* Where to write new cell content in data[] */ - int j; /* Loop counter */ - u8 *data; /* The content of the whole page */ - u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ - - assert( *pRC==SQLITE_OK ); - assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( MX_CELL(pPage->pBt)<=10921 ); - assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); - assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); - assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - /* The cell should normally be sized correctly. However, when moving a - ** malformed cell from a leaf page to an interior page, if the cell size - ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size - ** might be less than 8 (leaf-size + pointer) on the interior node. Hence - ** the term after the || in the following assert(). */ - assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) ); - if( pPage->nOverflow || sz+2>pPage->nFree ){ - if( pTemp ){ - memcpy(pTemp, pCell, sz); - pCell = pTemp; - } - if( iChild ){ - put4byte(pCell, iChild); - } - j = pPage->nOverflow++; - assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) ); - pPage->apOvfl[j] = pCell; - pPage->aiOvfl[j] = (u16)i; - - /* When multiple overflows occur, they are always sequential and in - ** sorted order. This invariants arise because multiple overflows can - ** only occur when inserting divider cells into the parent page during - ** balancing, and the dividers are adjacent and sorted. - */ - assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ - assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ - }else{ - int rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc!=SQLITE_OK ){ - *pRC = rc; - return; - } - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - data = pPage->aData; - assert( &data[pPage->cellOffset]==pPage->aCellIdx ); - rc = allocateSpace(pPage, sz, &idx); - if( rc ){ *pRC = rc; return; } - /* The allocateSpace() routine guarantees the following properties - ** if it returns successfully */ - assert( idx >= 0 ); - assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); - assert( idx+sz <= (int)pPage->pBt->usableSize ); - pPage->nFree -= (u16)(2 + sz); - memcpy(&data[idx], pCell, sz); - if( iChild ){ - put4byte(&data[idx], iChild); - } - pIns = pPage->aCellIdx + i*2; - memmove(pIns+2, pIns, 2*(pPage->nCell - i)); - put2byte(pIns, idx); - pPage->nCell++; - /* increment the cell count */ - if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; - assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell ); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pPage->pBt->autoVacuum ){ - /* The cell may contain a pointer to an overflow page. If so, write - ** the entry for the overflow page into the pointer map. - */ - ptrmapPutOvflPtr(pPage, pCell, pRC); - } -#endif - } -} - -/* -** A CellArray object contains a cache of pointers and sizes for a -** consecutive sequence of cells that might be held on multiple pages. -*/ -typedef struct CellArray CellArray; -struct CellArray { - int nCell; /* Number of cells in apCell[] */ - MemPage *pRef; /* Reference page */ - u8 **apCell; /* All cells begin balanced */ - u16 *szCell; /* Local size of all cells in apCell[] */ -}; - -/* -** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been -** computed. -*/ -static void populateCellCache(CellArray *p, int idx, int N){ - assert( idx>=0 && idx+N<=p->nCell ); - while( N>0 ){ - assert( p->apCell[idx]!=0 ); - if( p->szCell[idx]==0 ){ - p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]); - }else{ - assert( CORRUPT_DB || - p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) ); - } - idx++; - N--; - } -} - -/* -** Return the size of the Nth element of the cell array -*/ -static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){ - assert( N>=0 && NnCell ); - assert( p->szCell[N]==0 ); - p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]); - return p->szCell[N]; -} -static u16 cachedCellSize(CellArray *p, int N){ - assert( N>=0 && NnCell ); - if( p->szCell[N] ) return p->szCell[N]; - return computeCellSize(p, N); -} - -/* -** Array apCell[] contains pointers to nCell b-tree page cells. The -** szCell[] array contains the size in bytes of each cell. This function -** replaces the current contents of page pPg with the contents of the cell -** array. -** -** Some of the cells in apCell[] may currently be stored in pPg. This -** function works around problems caused by this by making a copy of any -** such cells before overwriting the page data. -** -** The MemPage.nFree field is invalidated by this function. It is the -** responsibility of the caller to set it correctly. -*/ -static int rebuildPage( - MemPage *pPg, /* Edit this page */ - int nCell, /* Final number of cells on page */ - u8 **apCell, /* Array of cells */ - u16 *szCell /* Array of cell sizes */ -){ - const int hdr = pPg->hdrOffset; /* Offset of header on pPg */ - u8 * const aData = pPg->aData; /* Pointer to data for pPg */ - const int usableSize = pPg->pBt->usableSize; - u8 * const pEnd = &aData[usableSize]; - int i; - u8 *pCellptr = pPg->aCellIdx; - u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); - u8 *pData; - - i = get2byte(&aData[hdr+5]); - memcpy(&pTmp[i], &aData[i], usableSize - i); - - pData = pEnd; - for(i=0; ixCellSize(pPg, pCell) || CORRUPT_DB ); - testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) ); - } - - /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ - pPg->nCell = nCell; - pPg->nOverflow = 0; - - put2byte(&aData[hdr+1], 0); - put2byte(&aData[hdr+3], pPg->nCell); - put2byte(&aData[hdr+5], pData - aData); - aData[hdr+7] = 0x00; - return SQLITE_OK; -} - -/* -** Array apCell[] contains nCell pointers to b-tree cells. Array szCell -** contains the size in bytes of each such cell. This function attempts to -** add the cells stored in the array to page pPg. If it cannot (because -** the page needs to be defragmented before the cells will fit), non-zero -** is returned. Otherwise, if the cells are added successfully, zero is -** returned. -** -** Argument pCellptr points to the first entry in the cell-pointer array -** (part of page pPg) to populate. After cell apCell[0] is written to the -** page body, a 16-bit offset is written to pCellptr. And so on, for each -** cell in the array. It is the responsibility of the caller to ensure -** that it is safe to overwrite this part of the cell-pointer array. -** -** When this function is called, *ppData points to the start of the -** content area on page pPg. If the size of the content area is extended, -** *ppData is updated to point to the new start of the content area -** before returning. -** -** Finally, argument pBegin points to the byte immediately following the -** end of the space required by this page for the cell-pointer area (for -** all cells - not just those inserted by the current call). If the content -** area must be extended to before this point in order to accomodate all -** cells in apCell[], then the cells do not fit and non-zero is returned. -*/ -static int pageInsertArray( - MemPage *pPg, /* Page to add cells to */ - u8 *pBegin, /* End of cell-pointer array */ - u8 **ppData, /* IN/OUT: Page content -area pointer */ - u8 *pCellptr, /* Pointer to cell-pointer area */ - int iFirst, /* Index of first cell to add */ - int nCell, /* Number of cells to add to pPg */ - CellArray *pCArray /* Array of cells */ -){ - int i; - u8 *aData = pPg->aData; - u8 *pData = *ppData; - int iEnd = iFirst + nCell; - assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ - for(i=iFirst; iapCell[i] will never overlap on a well-formed - ** database. But they might for a corrupt database. Hence use memmove() - ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */ - assert( (pSlot+sz)<=pCArray->apCell[i] - || pSlot>=(pCArray->apCell[i]+sz) - || CORRUPT_DB ); - memmove(pSlot, pCArray->apCell[i], sz); - put2byte(pCellptr, (pSlot - aData)); - pCellptr += 2; - } - *ppData = pData; - return 0; -} - -/* -** Array apCell[] contains nCell pointers to b-tree cells. Array szCell -** contains the size in bytes of each such cell. This function adds the -** space associated with each cell in the array that is currently stored -** within the body of pPg to the pPg free-list. The cell-pointers and other -** fields of the page are not updated. -** -** This function returns the total number of cells added to the free-list. -*/ -static int pageFreeArray( - MemPage *pPg, /* Page to edit */ - int iFirst, /* First cell to delete */ - int nCell, /* Cells to delete */ - CellArray *pCArray /* Array of cells */ -){ - u8 * const aData = pPg->aData; - u8 * const pEnd = &aData[pPg->pBt->usableSize]; - u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; - int nRet = 0; - int i; - int iEnd = iFirst + nCell; - u8 *pFree = 0; - int szFree = 0; - - for(i=iFirst; iapCell[i]; - if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ - int sz; - /* No need to use cachedCellSize() here. The sizes of all cells that - ** are to be freed have already been computing while deciding which - ** cells need freeing */ - sz = pCArray->szCell[i]; assert( sz>0 ); - if( pFree!=(pCell + sz) ){ - if( pFree ){ - assert( pFree>aData && (pFree - aData)<65536 ); - freeSpace(pPg, (u16)(pFree - aData), szFree); - } - pFree = pCell; - szFree = sz; - if( pFree+sz>pEnd ) return 0; - }else{ - pFree = pCell; - szFree += sz; - } - nRet++; - } - } - if( pFree ){ - assert( pFree>aData && (pFree - aData)<65536 ); - freeSpace(pPg, (u16)(pFree - aData), szFree); - } - return nRet; -} - -/* -** apCell[] and szCell[] contains pointers to and sizes of all cells in the -** pages being balanced. The current page, pPg, has pPg->nCell cells starting -** with apCell[iOld]. After balancing, this page should hold nNew cells -** starting at apCell[iNew]. -** -** This routine makes the necessary adjustments to pPg so that it contains -** the correct cells after being balanced. -** -** The pPg->nFree field is invalid when this function returns. It is the -** responsibility of the caller to set it correctly. -*/ -static int editPage( - MemPage *pPg, /* Edit this page */ - int iOld, /* Index of first cell currently on page */ - int iNew, /* Index of new first cell on page */ - int nNew, /* Final number of cells on page */ - CellArray *pCArray /* Array of cells and sizes */ -){ - u8 * const aData = pPg->aData; - const int hdr = pPg->hdrOffset; - u8 *pBegin = &pPg->aCellIdx[nNew * 2]; - int nCell = pPg->nCell; /* Cells stored on pPg */ - u8 *pData; - u8 *pCellptr; - int i; - int iOldEnd = iOld + pPg->nCell + pPg->nOverflow; - int iNewEnd = iNew + nNew; - -#ifdef SQLITE_DEBUG - u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); - memcpy(pTmp, aData, pPg->pBt->usableSize); -#endif - - /* Remove cells from the start and end of the page */ - if( iOldaCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); - nCell -= nShift; - } - if( iNewEnd < iOldEnd ){ - nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); - } - - pData = &aData[get2byteNotZero(&aData[hdr+5])]; - if( pDataaCellIdx; - memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); - if( pageInsertArray( - pPg, pBegin, &pData, pCellptr, - iNew, nAdd, pCArray - ) ) goto editpage_fail; - nCell += nAdd; - } - - /* Add any overflow cells */ - for(i=0; inOverflow; i++){ - int iCell = (iOld + pPg->aiOvfl[i]) - iNew; - if( iCell>=0 && iCellaCellIdx[iCell * 2]; - memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); - nCell++; - if( pageInsertArray( - pPg, pBegin, &pData, pCellptr, - iCell+iNew, 1, pCArray - ) ) goto editpage_fail; - } - } - - /* Append cells to the end of the page */ - pCellptr = &pPg->aCellIdx[nCell*2]; - if( pageInsertArray( - pPg, pBegin, &pData, pCellptr, - iNew+nCell, nNew-nCell, pCArray - ) ) goto editpage_fail; - - pPg->nCell = nNew; - pPg->nOverflow = 0; - - put2byte(&aData[hdr+3], pPg->nCell); - put2byte(&aData[hdr+5], pData - aData); - -#ifdef SQLITE_DEBUG - for(i=0; iapCell[i+iNew]; - int iOff = get2byteAligned(&pPg->aCellIdx[i*2]); - if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){ - pCell = &pTmp[pCell - aData]; - } - assert( 0==memcmp(pCell, &aData[iOff], - pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) ); - } -#endif - - return SQLITE_OK; - editpage_fail: - /* Unable to edit this page. Rebuild it from scratch instead. */ - populateCellCache(pCArray, iNew, nNew); - return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]); -} - -/* -** The following parameters determine how many adjacent pages get involved -** in a balancing operation. NN is the number of neighbors on either side -** of the page that participate in the balancing operation. NB is the -** total number of pages that participate, including the target page and -** NN neighbors on either side. -** -** The minimum value of NN is 1 (of course). Increasing NN above 1 -** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance -** in exchange for a larger degradation in INSERT and UPDATE performance. -** The value of NN appears to give the best results overall. -*/ -#define NN 1 /* Number of neighbors on either side of pPage */ -#define NB (NN*2+1) /* Total pages involved in the balance */ - - -#ifndef SQLITE_OMIT_QUICKBALANCE -/* -** This version of balance() handles the common special case where -** a new entry is being inserted on the extreme right-end of the -** tree, in other words, when the new entry will become the largest -** entry in the tree. -** -** Instead of trying to balance the 3 right-most leaf pages, just add -** a new page to the right-hand side and put the one new entry in -** that page. This leaves the right side of the tree somewhat -** unbalanced. But odds are that we will be inserting new entries -** at the end soon afterwards so the nearly empty page will quickly -** fill up. On average. -** -** pPage is the leaf page which is the right-most page in the tree. -** pParent is its parent. pPage must have a single overflow entry -** which is also the right-most entry on the page. -** -** The pSpace buffer is used to store a temporary copy of the divider -** cell that will be inserted into pParent. Such a cell consists of a 4 -** byte page number followed by a variable length integer. In other -** words, at most 13 bytes. Hence the pSpace buffer must be at -** least 13 bytes in size. -*/ -static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ - BtShared *const pBt = pPage->pBt; /* B-Tree Database */ - MemPage *pNew; /* Newly allocated page */ - int rc; /* Return Code */ - Pgno pgnoNew; /* Page number of pNew */ - - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - assert( pPage->nOverflow==1 ); - - /* This error condition is now caught prior to reaching this function */ - if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; - - /* Allocate a new page. This page will become the right-sibling of - ** pPage. Make the parent page writable, so that the new divider cell - ** may be inserted. If both these operations are successful, proceed. - */ - rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); - - if( rc==SQLITE_OK ){ - - u8 *pOut = &pSpace[4]; - u8 *pCell = pPage->apOvfl[0]; - u16 szCell = pPage->xCellSize(pPage, pCell); - u8 *pStop; - - assert( sqlite3PagerIswriteable(pNew->pDbPage) ); - assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); - zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); - rc = rebuildPage(pNew, 1, &pCell, &szCell); - if( NEVER(rc) ) return rc; - pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; - - /* If this is an auto-vacuum database, update the pointer map - ** with entries for the new page, and any pointer from the - ** cell on the page to an overflow page. If either of these - ** operations fails, the return code is set, but the contents - ** of the parent page are still manipulated by thh code below. - ** That is Ok, at this point the parent page is guaranteed to - ** be marked as dirty. Returning an error code will cause a - ** rollback, undoing any changes made to the parent page. - */ - if( ISAUTOVACUUM ){ - ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); - if( szCell>pNew->minLocal ){ - ptrmapPutOvflPtr(pNew, pCell, &rc); - } - } - - /* Create a divider cell to insert into pParent. The divider cell - ** consists of a 4-byte page number (the page number of pPage) and - ** a variable length key value (which must be the same value as the - ** largest key on pPage). - ** - ** To find the largest key value on pPage, first find the right-most - ** cell on pPage. The first two fields of this cell are the - ** record-length (a variable length integer at most 32-bits in size) - ** and the key value (a variable length integer, may have any value). - ** The first of the while(...) loops below skips over the record-length - ** field. The second while(...) loop copies the key value from the - ** cell on pPage into the pSpace buffer. - */ - pCell = findCell(pPage, pPage->nCell-1); - pStop = &pCell[9]; - while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), - 0, pPage->pgno, &rc); - } - - /* Set the right-child pointer of pParent to point to the new page. */ - put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - - /* Release the reference to the new page. */ - releasePage(pNew); - } - - return rc; -} -#endif /* SQLITE_OMIT_QUICKBALANCE */ - -#if 0 -/* -** This function does not contribute anything to the operation of SQLite. -** it is sometimes activated temporarily while debugging code responsible -** for setting pointer-map entries. -*/ -static int ptrmapCheckPages(MemPage **apPage, int nPage){ - int i, j; - for(i=0; ipBt; - assert( pPage->isInit ); - - for(j=0; jnCell; j++){ - CellInfo info; - u8 *z; - - z = findCell(pPage, j); - pPage->xParseCell(pPage, z, &info); - if( info.nLocalpgno && e==PTRMAP_OVERFLOW1 ); - } - if( !pPage->leaf ){ - Pgno child = get4byte(z); - ptrmapGet(pBt, child, &e, &n); - assert( n==pPage->pgno && e==PTRMAP_BTREE ); - } - } - if( !pPage->leaf ){ - Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); - ptrmapGet(pBt, child, &e, &n); - assert( n==pPage->pgno && e==PTRMAP_BTREE ); - } - } - return 1; -} -#endif - -/* -** This function is used to copy the contents of the b-tree node stored -** on page pFrom to page pTo. If page pFrom was not a leaf page, then -** the pointer-map entries for each child page are updated so that the -** parent page stored in the pointer map is page pTo. If pFrom contained -** any cells with overflow page pointers, then the corresponding pointer -** map entries are also updated so that the parent page is page pTo. -** -** If pFrom is currently carrying any overflow cells (entries in the -** MemPage.apOvfl[] array), they are not copied to pTo. -** -** Before returning, page pTo is reinitialized using btreeInitPage(). -** -** The performance of this function is not critical. It is only used by -** the balance_shallower() and balance_deeper() procedures, neither of -** which are called often under normal circumstances. -*/ -static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ - if( (*pRC)==SQLITE_OK ){ - BtShared * const pBt = pFrom->pBt; - u8 * const aFrom = pFrom->aData; - u8 * const aTo = pTo->aData; - int const iFromHdr = pFrom->hdrOffset; - int const iToHdr = ((pTo->pgno==1) ? 100 : 0); - int rc; - int iData; - - - assert( pFrom->isInit ); - assert( pFrom->nFree>=iToHdr ); - assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); - - /* Copy the b-tree node content from page pFrom to page pTo. */ - iData = get2byte(&aFrom[iFromHdr+5]); - memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); - memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); - - /* Reinitialize page pTo so that the contents of the MemPage structure - ** match the new data. The initialization of pTo can actually fail under - ** fairly obscure circumstances, even though it is a copy of initialized - ** page pFrom. - */ - pTo->isInit = 0; - rc = btreeInitPage(pTo); - if( rc!=SQLITE_OK ){ - *pRC = rc; - return; - } - - /* If this is an auto-vacuum database, update the pointer-map entries - ** for any b-tree or overflow pages that pTo now contains the pointers to. - */ - if( ISAUTOVACUUM ){ - *pRC = setChildPtrmaps(pTo); - } - } -} - -/* -** This routine redistributes cells on the iParentIdx'th child of pParent -** (hereafter "the page") and up to 2 siblings so that all pages have about the -** same amount of free space. Usually a single sibling on either side of the -** page are used in the balancing, though both siblings might come from one -** side if the page is the first or last child of its parent. If the page -** has fewer than 2 siblings (something which can only happen if the page -** is a root page or a child of a root page) then all available siblings -** participate in the balancing. -** -** The number of siblings of the page might be increased or decreased by -** one or two in an effort to keep pages nearly full but not over full. -** -** Note that when this routine is called, some of the cells on the page -** might not actually be stored in MemPage.aData[]. This can happen -** if the page is overfull. This routine ensures that all cells allocated -** to the page and its siblings fit into MemPage.aData[] before returning. -** -** In the course of balancing the page and its siblings, cells may be -** inserted into or removed from the parent page (pParent). Doing so -** may cause the parent page to become overfull or underfull. If this -** happens, it is the responsibility of the caller to invoke the correct -** balancing routine to fix this problem (see the balance() routine). -** -** If this routine fails for any reason, it might leave the database -** in a corrupted state. So if this routine fails, the database should -** be rolled back. -** -** The third argument to this function, aOvflSpace, is a pointer to a -** buffer big enough to hold one page. If while inserting cells into the parent -** page (pParent) the parent page becomes overfull, this buffer is -** used to store the parent's overflow cells. Because this function inserts -** a maximum of four divider cells into the parent page, and the maximum -** size of a cell stored within an internal node is always less than 1/4 -** of the page-size, the aOvflSpace[] buffer is guaranteed to be large -** enough for all overflow cells. -** -** If aOvflSpace is set to a null pointer, this function returns -** SQLITE_NOMEM. -*/ -static int balance_nonroot( - MemPage *pParent, /* Parent page of siblings being balanced */ - int iParentIdx, /* Index of "the page" in pParent */ - u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ - int isRoot, /* True if pParent is a root-page */ - int bBulk /* True if this call is part of a bulk load */ -){ - BtShared *pBt; /* The whole database */ - int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ - int nNew = 0; /* Number of pages in apNew[] */ - int nOld; /* Number of pages in apOld[] */ - int i, j, k; /* Loop counters */ - int nxDiv; /* Next divider slot in pParent->aCell[] */ - int rc = SQLITE_OK; /* The return code */ - u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ - int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ - int usableSpace; /* Bytes in pPage beyond the header */ - int pageFlags; /* Value of pPage->aData[0] */ - int iSpace1 = 0; /* First unused byte of aSpace1[] */ - int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ - int szScratch; /* Size of scratch memory requested */ - MemPage *apOld[NB]; /* pPage and up to two siblings */ - MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ - u8 *pRight; /* Location in parent of right-sibling pointer */ - u8 *apDiv[NB-1]; /* Divider cells in pParent */ - int cntNew[NB+2]; /* Index in b.paCell[] of cell after i-th page */ - int cntOld[NB+2]; /* Old index in b.apCell[] */ - int szNew[NB+2]; /* Combined size of cells placed on i-th page */ - u8 *aSpace1; /* Space for copies of dividers cells */ - Pgno pgno; /* Temp var to store a page number in */ - u8 abDone[NB+2]; /* True after i'th new page is populated */ - Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ - Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ - u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ - CellArray b; /* Parsed information on cells being balanced */ - - memset(abDone, 0, sizeof(abDone)); - b.nCell = 0; - b.apCell = 0; - pBt = pParent->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - -#if 0 - TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); -#endif - - /* At this point pParent may have at most one overflow cell. And if - ** this overflow cell is present, it must be the cell with - ** index iParentIdx. This scenario comes about when this function - ** is called (indirectly) from sqlite3BtreeDelete(). - */ - assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); - assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); - - if( !aOvflSpace ){ - return SQLITE_NOMEM_BKPT; - } - - /* Find the sibling pages to balance. Also locate the cells in pParent - ** that divide the siblings. An attempt is made to find NN siblings on - ** either side of pPage. More siblings are taken from one side, however, - ** if there are fewer than NN siblings on the other side. If pParent - ** has NB or fewer children then all children of pParent are taken. - ** - ** This loop also drops the divider cells from the parent page. This - ** way, the remainder of the function does not have to deal with any - ** overflow cells in the parent page, since if any existed they will - ** have already been removed. - */ - i = pParent->nOverflow + pParent->nCell; - if( i<2 ){ - nxDiv = 0; - }else{ - assert( bBulk==0 || bBulk==1 ); - if( iParentIdx==0 ){ - nxDiv = 0; - }else if( iParentIdx==i ){ - nxDiv = i-2+bBulk; - }else{ - nxDiv = iParentIdx-1; - } - i = 2-bBulk; - } - nOld = i+1; - if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ - pRight = &pParent->aData[pParent->hdrOffset+8]; - }else{ - pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); - } - pgno = get4byte(pRight); - while( 1 ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); - if( rc ){ - memset(apOld, 0, (i+1)*sizeof(MemPage*)); - goto balance_cleanup; - } - nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; - if( (i--)==0 ) break; - - if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){ - apDiv[i] = pParent->apOvfl[0]; - pgno = get4byte(apDiv[i]); - szNew[i] = pParent->xCellSize(pParent, apDiv[i]); - pParent->nOverflow = 0; - }else{ - apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); - pgno = get4byte(apDiv[i]); - szNew[i] = pParent->xCellSize(pParent, apDiv[i]); - - /* Drop the cell from the parent page. apDiv[i] still points to - ** the cell within the parent, even though it has been dropped. - ** This is safe because dropping a cell only overwrites the first - ** four bytes of it, and this function does not need the first - ** four bytes of the divider cell. So the pointer is safe to use - ** later on. - ** - ** But not if we are in secure-delete mode. In secure-delete mode, - ** the dropCell() routine will overwrite the entire cell with zeroes. - ** In this case, temporarily copy the cell into the aOvflSpace[] - ** buffer. It will be copied out again as soon as the aSpace[] buffer - ** is allocated. */ - if( pBt->btsFlags & BTS_SECURE_DELETE ){ - int iOff; - - iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); - if( (iOff+szNew[i])>(int)pBt->usableSize ){ - rc = SQLITE_CORRUPT_BKPT; - memset(apOld, 0, (i+1)*sizeof(MemPage*)); - goto balance_cleanup; - }else{ - memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); - apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; - } - } - dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); - } - } - - /* Make nMaxCells a multiple of 4 in order to preserve 8-byte - ** alignment */ - nMaxCells = (nMaxCells + 3)&~3; - - /* - ** Allocate space for memory structures - */ - szScratch = - nMaxCells*sizeof(u8*) /* b.apCell */ - + nMaxCells*sizeof(u16) /* b.szCell */ - + pBt->pageSize; /* aSpace1 */ - - /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer - ** that is more than 6 times the database page size. */ - assert( szScratch<=6*(int)pBt->pageSize ); - b.apCell = sqlite3ScratchMalloc( szScratch ); - if( b.apCell==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto balance_cleanup; - } - b.szCell = (u16*)&b.apCell[nMaxCells]; - aSpace1 = (u8*)&b.szCell[nMaxCells]; - assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); - - /* - ** Load pointers to all cells on sibling pages and the divider cells - ** into the local b.apCell[] array. Make copies of the divider cells - ** into space obtained from aSpace1[]. The divider cells have already - ** been removed from pParent. - ** - ** If the siblings are on leaf pages, then the child pointers of the - ** divider cells are stripped from the cells before they are copied - ** into aSpace1[]. In this way, all cells in b.apCell[] are without - ** child pointers. If siblings are not leaves, then all cell in - ** b.apCell[] include child pointers. Either way, all cells in b.apCell[] - ** are alike. - ** - ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. - ** leafData: 1 if pPage holds key+data and pParent holds only keys. - */ - b.pRef = apOld[0]; - leafCorrection = b.pRef->leaf*4; - leafData = b.pRef->intKeyLeaf; - for(i=0; inCell; - u8 *aData = pOld->aData; - u16 maskPage = pOld->maskPage; - u8 *piCell = aData + pOld->cellOffset; - u8 *piEnd; - - /* Verify that all sibling pages are of the same "type" (table-leaf, - ** table-interior, index-leaf, or index-interior). - */ - if( pOld->aData[0]!=apOld[0]->aData[0] ){ - rc = SQLITE_CORRUPT_BKPT; - goto balance_cleanup; - } - - /* Load b.apCell[] with pointers to all cells in pOld. If pOld - ** constains overflow cells, include them in the b.apCell[] array - ** in the correct spot. - ** - ** Note that when there are multiple overflow cells, it is always the - ** case that they are sequential and adjacent. This invariant arises - ** because multiple overflows can only occurs when inserting divider - ** cells into a parent on a prior balance, and divider cells are always - ** adjacent and are inserted in order. There is an assert() tagged - ** with "NOTE 1" in the overflow cell insertion loop to prove this - ** invariant. - ** - ** This must be done in advance. Once the balance starts, the cell - ** offset section of the btree page will be overwritten and we will no - ** long be able to find the cells if a pointer to each cell is not saved - ** first. - */ - memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); - if( pOld->nOverflow>0 ){ - limit = pOld->aiOvfl[0]; - for(j=0; jnOverflow; k++){ - assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */ - b.apCell[b.nCell] = pOld->apOvfl[k]; - b.nCell++; - } - } - piEnd = aData + pOld->cellOffset + 2*pOld->nCell; - while( piCellmaxLocal+23 ); - assert( iSpace1 <= (int)pBt->pageSize ); - memcpy(pTemp, apDiv[i], sz); - b.apCell[b.nCell] = pTemp+leafCorrection; - assert( leafCorrection==0 || leafCorrection==4 ); - b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; - if( !pOld->leaf ){ - assert( leafCorrection==0 ); - assert( pOld->hdrOffset==0 ); - /* The right pointer of the child page pOld becomes the left - ** pointer of the divider cell */ - memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); - }else{ - assert( leafCorrection==4 ); - while( b.szCell[b.nCell]<4 ){ - /* Do not allow any cells smaller than 4 bytes. If a smaller cell - ** does exist, pad it with 0x00 bytes. */ - assert( b.szCell[b.nCell]==3 || CORRUPT_DB ); - assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB ); - aSpace1[iSpace1++] = 0x00; - b.szCell[b.nCell]++; - } - } - b.nCell++; - } - } - - /* - ** Figure out the number of pages needed to hold all b.nCell cells. - ** Store this number in "k". Also compute szNew[] which is the total - ** size of all cells on the i-th page and cntNew[] which is the index - ** in b.apCell[] of the cell that divides page i from page i+1. - ** cntNew[k] should equal b.nCell. - ** - ** Values computed by this block: - ** - ** k: The total number of sibling pages - ** szNew[i]: Spaced used on the i-th sibling page. - ** cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to - ** the right of the i-th sibling page. - ** usableSpace: Number of bytes of space available on each sibling. - ** - */ - usableSpace = pBt->usableSize - 12 + leafCorrection; - for(i=0; inFree; - if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } - for(j=0; jnOverflow; j++){ - szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); - } - cntNew[i] = cntOld[i]; - } - k = nOld; - for(i=0; iusableSpace ){ - if( i+1>=k ){ - k = i+2; - if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } - szNew[k-1] = 0; - cntNew[k-1] = b.nCell; - } - sz = 2 + cachedCellSize(&b, cntNew[i]-1); - szNew[i] -= sz; - if( !leafData ){ - if( cntNew[i]usableSpace ) break; - szNew[i] += sz; - cntNew[i]++; - if( !leafData ){ - if( cntNew[i]=b.nCell ){ - k = i+1; - }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){ - rc = SQLITE_CORRUPT_BKPT; - goto balance_cleanup; - } - } - - /* - ** The packing computed by the previous block is biased toward the siblings - ** on the left side (siblings with smaller keys). The left siblings are - ** always nearly full, while the right-most sibling might be nearly empty. - ** The next block of code attempts to adjust the packing of siblings to - ** get a better balance. - ** - ** This adjustment is more than an optimization. The packing above might - ** be so out of balance as to be illegal. For example, the right-most - ** sibling might be completely empty. This adjustment is not optional. - */ - for(i=k-1; i>0; i--){ - int szRight = szNew[i]; /* Size of sibling on the right */ - int szLeft = szNew[i-1]; /* Size of sibling on the left */ - int r; /* Index of right-most cell in left sibling */ - int d; /* Index of first cell to the left of right sibling */ - - r = cntNew[i-1] - 1; - d = r + 1 - leafData; - (void)cachedCellSize(&b, d); - do{ - assert( d szLeft-(b.szCell[r]+(i==k-1?0:2)))){ - break; - } - szRight += b.szCell[d] + 2; - szLeft -= b.szCell[r] + 2; - cntNew[i-1] = r; - r--; - d--; - }while( r>=0 ); - szNew[i] = szRight; - szNew[i-1] = szLeft; - if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ - rc = SQLITE_CORRUPT_BKPT; - goto balance_cleanup; - } - } - - /* Sanity check: For a non-corrupt database file one of the follwing - ** must be true: - ** (1) We found one or more cells (cntNew[0])>0), or - ** (2) pPage is a virtual root page. A virtual root page is when - ** the real root page is page 1 and we are the only child of - ** that page. - */ - assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); - TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n", - apOld[0]->pgno, apOld[0]->nCell, - nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, - nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 - )); - - /* - ** Allocate k new pages. Reuse old pages where possible. - */ - pageFlags = apOld[0]->aData[0]; - for(i=0; ipDbPage); - nNew++; - if( rc ) goto balance_cleanup; - }else{ - assert( i>0 ); - rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); - if( rc ) goto balance_cleanup; - zeroPage(pNew, pageFlags); - apNew[i] = pNew; - nNew++; - cntOld[i] = b.nCell; - - /* Set the pointer-map entry for the new sibling page. */ - if( ISAUTOVACUUM ){ - ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - } - - /* - ** Reassign page numbers so that the new pages are in ascending order. - ** This helps to keep entries in the disk file in order so that a scan - ** of the table is closer to a linear scan through the file. That in turn - ** helps the operating system to deliver pages from the disk more rapidly. - ** - ** An O(n^2) insertion sort algorithm is used, but since n is never more - ** than (NB+2) (a small constant), that should not be a problem. - ** - ** When NB==3, this one optimization makes the database about 25% faster - ** for large insertions and deletions. - */ - for(i=0; ipgno; - aPgFlags[i] = apNew[i]->pDbPage->flags; - for(j=0; ji ){ - sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); - } - sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); - apNew[i]->pgno = pgno; - } - } - - TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " - "%d(%d nc=%d) %d(%d nc=%d)\n", - apNew[0]->pgno, szNew[0], cntNew[0], - nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, - nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, - nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, - nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0, - nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, - nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, - nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, - nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 - )); - - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - put4byte(pRight, apNew[nNew-1]->pgno); - - /* If the sibling pages are not leaves, ensure that the right-child pointer - ** of the right-most new sibling page is set to the value that was - ** originally in the same field of the right-most old sibling page. */ - if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ - MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; - memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); - } - - /* Make any required updates to pointer map entries associated with - ** cells stored on sibling pages following the balance operation. Pointer - ** map entries associated with divider cells are set by the insertCell() - ** routine. The associated pointer map entries are: - ** - ** a) if the cell contains a reference to an overflow chain, the - ** entry associated with the first page in the overflow chain, and - ** - ** b) if the sibling pages are not leaves, the child page associated - ** with the cell. - ** - ** If the sibling pages are not leaves, then the pointer map entry - ** associated with the right-child of each sibling may also need to be - ** updated. This happens below, after the sibling pages have been - ** populated, not here. - */ - if( ISAUTOVACUUM ){ - MemPage *pNew = apNew[0]; - u8 *aOld = pNew->aData; - int cntOldNext = pNew->nCell + pNew->nOverflow; - int usableSize = pBt->usableSize; - int iNew = 0; - int iOld = 0; - - for(i=0; inCell + pOld->nOverflow + !leafData; - aOld = pOld->aData; - } - if( i==cntNew[iNew] ){ - pNew = apNew[++iNew]; - if( !leafData ) continue; - } - - /* Cell pCell is destined for new sibling page pNew. Originally, it - ** was either part of sibling page iOld (possibly an overflow cell), - ** or else the divider cell to the left of sibling page iOld. So, - ** if sibling page iOld had the same page number as pNew, and if - ** pCell really was a part of sibling page iOld (not a divider or - ** overflow cell), we can skip updating the pointer map entries. */ - if( iOld>=nNew - || pNew->pgno!=aPgno[iOld] - || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize]) - ){ - if( !leafCorrection ){ - ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); - } - if( cachedCellSize(&b,i)>pNew->minLocal ){ - ptrmapPutOvflPtr(pNew, pCell, &rc); - } - if( rc ) goto balance_cleanup; - } - } - } - - /* Insert new divider cells into pParent. */ - for(i=0; ileaf ){ - memcpy(&pNew->aData[8], pCell, 4); - }else if( leafData ){ - /* If the tree is a leaf-data tree, and the siblings are leaves, - ** then there is no divider cell in b.apCell[]. Instead, the divider - ** cell consists of the integer key for the right-most cell of - ** the sibling-page assembled above only. - */ - CellInfo info; - j--; - pNew->xParseCell(pNew, b.apCell[j], &info); - pCell = pTemp; - sz = 4 + putVarint(&pCell[4], info.nKey); - pTemp = 0; - }else{ - pCell -= 4; - /* Obscure case for non-leaf-data trees: If the cell at pCell was - ** previously stored on a leaf node, and its reported size was 4 - ** bytes, then it may actually be smaller than this - ** (see btreeParseCellPtr(), 4 bytes is the minimum size of - ** any cell). But it is important to pass the correct size to - ** insertCell(), so reparse the cell now. - ** - ** This can only happen for b-trees used to evaluate "IN (SELECT ...)" - ** and WITHOUT ROWID tables with exactly one column which is the - ** primary key. - */ - if( b.szCell[j]==4 ){ - assert(leafCorrection==4); - sz = pParent->xCellSize(pParent, pCell); - } - } - iOvflSpace += sz; - assert( sz<=pBt->maxLocal+23 ); - assert( iOvflSpace <= (int)pBt->pageSize ); - insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); - if( rc!=SQLITE_OK ) goto balance_cleanup; - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - } - - /* Now update the actual sibling pages. The order in which they are updated - ** is important, as this code needs to avoid disrupting any page from which - ** cells may still to be read. In practice, this means: - ** - ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1]) - ** then it is not safe to update page apNew[iPg] until after - ** the left-hand sibling apNew[iPg-1] has been updated. - ** - ** (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1]) - ** then it is not safe to update page apNew[iPg] until after - ** the right-hand sibling apNew[iPg+1] has been updated. - ** - ** If neither of the above apply, the page is safe to update. - ** - ** The iPg value in the following loop starts at nNew-1 goes down - ** to 0, then back up to nNew-1 again, thus making two passes over - ** the pages. On the initial downward pass, only condition (1) above - ** needs to be tested because (2) will always be true from the previous - ** step. On the upward pass, both conditions are always true, so the - ** upwards pass simply processes pages that were missed on the downward - ** pass. - */ - for(i=1-nNew; i=0 && iPg=0 /* On the upwards pass, or... */ - || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ - ){ - int iNew; - int iOld; - int nNewCell; - - /* Verify condition (1): If cells are moving left, update iPg - ** only after iPg-1 has already been updated. */ - assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] ); - - /* Verify condition (2): If cells are moving right, update iPg - ** only after iPg+1 has already been updated. */ - assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] ); - - if( iPg==0 ){ - iNew = iOld = 0; - nNewCell = cntNew[0]; - }else{ - iOld = iPgnFree = usableSpace-szNew[iPg]; - assert( apNew[iPg]->nOverflow==0 ); - assert( apNew[iPg]->nCell==nNewCell ); - } - } - - /* All pages have been processed exactly once */ - assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 ); - - assert( nOld>0 ); - assert( nNew>0 ); - - if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ - /* The root page of the b-tree now contains no cells. The only sibling - ** page is the right-child of the parent. Copy the contents of the - ** child page into the parent, decreasing the overall height of the - ** b-tree structure by one. This is described as the "balance-shallower" - ** sub-algorithm in some documentation. - ** - ** If this is an auto-vacuum database, the call to copyNodeContent() - ** sets all pointer-map entries corresponding to database image pages - ** for which the pointer is stored within the content being copied. - ** - ** It is critical that the child page be defragmented before being - ** copied into the parent, because if the parent is page 1 then it will - ** by smaller than the child due to the database header, and so all the - ** free space needs to be up front. - */ - assert( nNew==1 || CORRUPT_DB ); - rc = defragmentPage(apNew[0]); - testcase( rc!=SQLITE_OK ); - assert( apNew[0]->nFree == - (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) - || rc!=SQLITE_OK - ); - copyNodeContent(apNew[0], pParent, &rc); - freePage(apNew[0], &rc); - }else if( ISAUTOVACUUM && !leafCorrection ){ - /* Fix the pointer map entries associated with the right-child of each - ** sibling page. All other pointer map entries have already been taken - ** care of. */ - for(i=0; iaData[8]); - ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); - } - } - - assert( pParent->isInit ); - TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", - nOld, nNew, b.nCell)); - - /* Free any old pages that were not reused as new pages. - */ - for(i=nNew; iisInit ){ - /* The ptrmapCheckPages() contains assert() statements that verify that - ** all pointer map pages are set correctly. This is helpful while - ** debugging. This is usually disabled because a corrupt database may - ** cause an assert() statement to fail. */ - ptrmapCheckPages(apNew, nNew); - ptrmapCheckPages(&pParent, 1); - } -#endif - - /* - ** Cleanup before returning. - */ -balance_cleanup: - sqlite3ScratchFree(b.apCell); - for(i=0; ipBt; /* The BTree */ - - assert( pRoot->nOverflow>0 ); - assert( sqlite3_mutex_held(pBt->mutex) ); - - /* Make pRoot, the root page of the b-tree, writable. Allocate a new - ** page that will become the new right-child of pPage. Copy the contents - ** of the node stored on pRoot into the new child page. - */ - rc = sqlite3PagerWrite(pRoot->pDbPage); - if( rc==SQLITE_OK ){ - rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); - copyNodeContent(pRoot, pChild, &rc); - if( ISAUTOVACUUM ){ - ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); - } - } - if( rc ){ - *ppChild = 0; - releasePage(pChild); - return rc; - } - assert( sqlite3PagerIswriteable(pChild->pDbPage) ); - assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); - assert( pChild->nCell==pRoot->nCell ); - - TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); - - /* Copy the overflow cells from pRoot to pChild */ - memcpy(pChild->aiOvfl, pRoot->aiOvfl, - pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); - memcpy(pChild->apOvfl, pRoot->apOvfl, - pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); - pChild->nOverflow = pRoot->nOverflow; - - /* Zero the contents of pRoot. Then install pChild as the right-child. */ - zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); - put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); - - *ppChild = pChild; - return SQLITE_OK; -} - -/* -** The page that pCur currently points to has just been modified in -** some way. This function figures out if this modification means the -** tree needs to be balanced, and if so calls the appropriate balancing -** routine. Balancing routines are: -** -** balance_quick() -** balance_deeper() -** balance_nonroot() -*/ -static int balance(BtCursor *pCur){ - int rc = SQLITE_OK; - const int nMin = pCur->pBt->usableSize * 2 / 3; - u8 aBalanceQuickSpace[13]; - u8 *pFree = 0; - - VVA_ONLY( int balance_quick_called = 0 ); - VVA_ONLY( int balance_deeper_called = 0 ); - - do { - int iPage = pCur->iPage; - MemPage *pPage = pCur->apPage[iPage]; - - if( iPage==0 ){ - if( pPage->nOverflow ){ - /* The root page of the b-tree is overfull. In this case call the - ** balance_deeper() function to create a new child for the root-page - ** and copy the current contents of the root-page to it. The - ** next iteration of the do-loop will balance the child page. - */ - assert( balance_deeper_called==0 ); - VVA_ONLY( balance_deeper_called++ ); - rc = balance_deeper(pPage, &pCur->apPage[1]); - if( rc==SQLITE_OK ){ - pCur->iPage = 1; - pCur->aiIdx[0] = 0; - pCur->aiIdx[1] = 0; - assert( pCur->apPage[1]->nOverflow ); - } - }else{ - break; - } - }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ - break; - }else{ - MemPage * const pParent = pCur->apPage[iPage-1]; - int const iIdx = pCur->aiIdx[iPage-1]; - - rc = sqlite3PagerWrite(pParent->pDbPage); - if( rc==SQLITE_OK ){ -#ifndef SQLITE_OMIT_QUICKBALANCE - if( pPage->intKeyLeaf - && pPage->nOverflow==1 - && pPage->aiOvfl[0]==pPage->nCell - && pParent->pgno!=1 - && pParent->nCell==iIdx - ){ - /* Call balance_quick() to create a new sibling of pPage on which - ** to store the overflow cell. balance_quick() inserts a new cell - ** into pParent, which may cause pParent overflow. If this - ** happens, the next iteration of the do-loop will balance pParent - ** use either balance_nonroot() or balance_deeper(). Until this - ** happens, the overflow cell is stored in the aBalanceQuickSpace[] - ** buffer. - ** - ** The purpose of the following assert() is to check that only a - ** single call to balance_quick() is made for each call to this - ** function. If this were not verified, a subtle bug involving reuse - ** of the aBalanceQuickSpace[] might sneak in. - */ - assert( balance_quick_called==0 ); - VVA_ONLY( balance_quick_called++ ); - rc = balance_quick(pParent, pPage, aBalanceQuickSpace); - }else -#endif - { - /* In this case, call balance_nonroot() to redistribute cells - ** between pPage and up to 2 of its sibling pages. This involves - ** modifying the contents of pParent, which may cause pParent to - ** become overfull or underfull. The next iteration of the do-loop - ** will balance the parent page to correct this. - ** - ** If the parent page becomes overfull, the overflow cell or cells - ** are stored in the pSpace buffer allocated immediately below. - ** A subsequent iteration of the do-loop will deal with this by - ** calling balance_nonroot() (balance_deeper() may be called first, - ** but it doesn't deal with overflow cells - just moves them to a - ** different page). Once this subsequent call to balance_nonroot() - ** has completed, it is safe to release the pSpace buffer used by - ** the previous call, as the overflow cell data will have been - ** copied either into the body of a database page or into the new - ** pSpace buffer passed to the latter call to balance_nonroot(). - */ - u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); - rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, - pCur->hints&BTREE_BULKLOAD); - if( pFree ){ - /* If pFree is not NULL, it points to the pSpace buffer used - ** by a previous call to balance_nonroot(). Its contents are - ** now stored either on real database pages or within the - ** new pSpace buffer, so it may be safely freed here. */ - sqlite3PageFree(pFree); - } - - /* The pSpace buffer will be freed after the next call to - ** balance_nonroot(), or just before this function returns, whichever - ** comes first. */ - pFree = pSpace; - } - } - - pPage->nOverflow = 0; - - /* The next iteration of the do-loop balances the parent page. */ - releasePage(pPage); - pCur->iPage--; - assert( pCur->iPage>=0 ); - } - }while( rc==SQLITE_OK ); - - if( pFree ){ - sqlite3PageFree(pFree); - } - return rc; -} - - -/* -** Insert a new record into the BTree. The content of the new record -** is described by the pX object. The pCur cursor is used only to -** define what table the record should be inserted into, and is left -** pointing at a random location. -** -** For a table btree (used for rowid tables), only the pX.nKey value of -** the key is used. The pX.pKey value must be NULL. The pX.nKey is the -** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields -** hold the content of the row. -** -** For an index btree (used for indexes and WITHOUT ROWID tables), the -** key is an arbitrary byte sequence stored in pX.pKey,nKey. The -** pX.pData,nData,nZero fields must be zero. -** -** If the seekResult parameter is non-zero, then a successful call to -** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already -** been performed. seekResult is the search result returned (a negative -** number if pCur points at an entry that is smaller than (pKey, nKey), or -** a positive value if pCur points at an entry that is larger than -** (pKey, nKey)). -** -** If the seekResult parameter is non-zero, then the caller guarantees that -** cursor pCur is pointing at the existing copy of a row that is to be -** overwritten. If the seekResult parameter is 0, then cursor pCur may -** point to any entry or to no entry at all and so this function has to seek -** the cursor before the new key can be inserted. -*/ -SQLITE_PRIVATE int sqlite3BtreeInsert( - BtCursor *pCur, /* Insert data into the table of this cursor */ - const BtreePayload *pX, /* Content of the row to be inserted */ - int appendBias, /* True if this is likely an append */ - int seekResult /* Result of prior MovetoUnpacked() call */ -){ - int rc; - int loc = seekResult; /* -1: before desired location +1: after */ - int szNew = 0; - int idx; - MemPage *pPage; - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; - unsigned char *oldCell; - unsigned char *newCell = 0; - - if( pCur->eState==CURSOR_FAULT ){ - assert( pCur->skipNext!=SQLITE_OK ); - return pCur->skipNext; - } - - assert( cursorOwnsBtShared(pCur) ); - assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && pBt->inTransaction==TRANS_WRITE - && (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - - /* Assert that the caller has been consistent. If this cursor was opened - ** expecting an index b-tree, then the caller should be inserting blob - ** keys with no associated data. If the cursor was opened expecting an - ** intkey table, the caller should be inserting integer keys with a - ** blob of associated data. */ - assert( (pX->pKey==0)==(pCur->pKeyInfo==0) ); - - /* Save the positions of any other cursors open on this table. - ** - ** In some cases, the call to btreeMoveto() below is a no-op. For - ** example, when inserting data into a table with auto-generated integer - ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the - ** integer key to use. It then calls this function to actually insert the - ** data into the intkey B-Tree. In this case btreeMoveto() recognizes - ** that the cursor is already where it needs to be and returns without - ** doing any work. To avoid thwarting these optimizations, it is important - ** not to clear the cursor here. - */ - if( pCur->curFlags & BTCF_Multiple ){ - rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); - if( rc ) return rc; - } - - if( pCur->pKeyInfo==0 ){ - assert( pX->pKey==0 ); - /* If this is an insert into a table b-tree, invalidate any incrblob - ** cursors open on the row being replaced */ - invalidateIncrblobCursors(p, pX->nKey, 0); - - /* If the cursor is currently on the last row and we are appending a - ** new row onto the end, set the "loc" to avoid an unnecessary - ** btreeMoveto() call */ - if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0 - && pCur->info.nKey==pX->nKey-1 ){ - loc = -1; - }else if( loc==0 ){ - rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, appendBias, &loc); - if( rc ) return rc; - } - }else if( loc==0 ){ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc); - if( rc ) return rc; - } - assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); - - pPage = pCur->apPage[pCur->iPage]; - assert( pPage->intKey || pX->nKey>=0 ); - assert( pPage->leaf || !pPage->intKey ); - - TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", - pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, - loc==0 ? "overwrite" : "new entry")); - assert( pPage->isInit ); - newCell = pBt->pTmpSpace; - assert( newCell!=0 ); - rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; - assert( szNew==pPage->xCellSize(pPage, newCell) ); - assert( szNew <= MX_CELL_SIZE(pBt) ); - idx = pCur->aiIdx[pCur->iPage]; - if( loc==0 ){ - u16 szOld; - assert( idxnCell ); - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ){ - goto end_insert; - } - oldCell = findCell(pPage, idx); - if( !pPage->leaf ){ - memcpy(newCell, oldCell, 4); - } - rc = clearCell(pPage, oldCell, &szOld); - dropCell(pPage, idx, szOld, &rc); - if( rc ) goto end_insert; - }else if( loc<0 && pPage->nCell>0 ){ - assert( pPage->leaf ); - idx = ++pCur->aiIdx[pCur->iPage]; - }else{ - assert( pPage->leaf ); - } - insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); - assert( pPage->nOverflow==0 || rc==SQLITE_OK ); - assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); - - /* If no error has occurred and pPage has an overflow cell, call balance() - ** to redistribute the cells within the tree. Since balance() may move - ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey - ** variables. - ** - ** Previous versions of SQLite called moveToRoot() to move the cursor - ** back to the root page as balance() used to invalidate the contents - ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, - ** set the cursor state to "invalid". This makes common insert operations - ** slightly faster. - ** - ** There is a subtle but important optimization here too. When inserting - ** multiple records into an intkey b-tree using a single cursor (as can - ** happen while processing an "INSERT INTO ... SELECT" statement), it - ** is advantageous to leave the cursor pointing to the last entry in - ** the b-tree if possible. If the cursor is left pointing to the last - ** entry in the table, and the next row inserted has an integer key - ** larger than the largest existing key, it is possible to insert the - ** row without seeking the cursor. This can be a big performance boost. - */ - pCur->info.nSize = 0; - if( pPage->nOverflow ){ - assert( rc==SQLITE_OK ); - pCur->curFlags &= ~(BTCF_ValidNKey); - rc = balance(pCur); - - /* Must make sure nOverflow is reset to zero even if the balance() - ** fails. Internal data structure corruption will result otherwise. - ** Also, set the cursor state to invalid. This stops saveCursorPosition() - ** from trying to save the current position of the cursor. */ - pCur->apPage[pCur->iPage]->nOverflow = 0; - pCur->eState = CURSOR_INVALID; - } - assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); - -end_insert: - return rc; -} - -/* -** Delete the entry that the cursor is pointing to. -** -** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then -** the cursor is left pointing at an arbitrary location after the delete. -** But if that bit is set, then the cursor is left in a state such that -** the next call to BtreeNext() or BtreePrev() moves it to the same row -** as it would have been on if the call to BtreeDelete() had been omitted. -** -** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes -** associated with a single table entry and its indexes. Only one of those -** deletes is considered the "primary" delete. The primary delete occurs -** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete -** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag. -** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, -** but which might be used by alternative storage engines. -*/ -SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ - Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; - int rc; /* Return code */ - MemPage *pPage; /* Page to delete cell from */ - unsigned char *pCell; /* Pointer to cell to delete */ - int iCellIdx; /* Index of cell to delete */ - int iCellDepth; /* Depth of node containing pCell */ - u16 szCell; /* Size of the cell being deleted */ - int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ - u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ - - assert( cursorOwnsBtShared(pCur) ); - assert( pBt->inTransaction==TRANS_WRITE ); - assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( pCur->curFlags & BTCF_WriteFlag ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - assert( pCur->eState==CURSOR_VALID ); - assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); - - iCellDepth = pCur->iPage; - iCellIdx = pCur->aiIdx[iCellDepth]; - pPage = pCur->apPage[iCellDepth]; - pCell = findCell(pPage, iCellIdx); - - /* If the bPreserve flag is set to true, then the cursor position must - ** be preserved following this delete operation. If the current delete - ** will cause a b-tree rebalance, then this is done by saving the cursor - ** key and leaving the cursor in CURSOR_REQUIRESEEK state before - ** returning. - ** - ** Or, if the current delete will not cause a rebalance, then the cursor - ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately - ** before or after the deleted entry. In this case set bSkipnext to true. */ - if( bPreserve ){ - if( !pPage->leaf - || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) - ){ - /* A b-tree rebalance will be required after deleting this entry. - ** Save the cursor key. */ - rc = saveCursorKey(pCur); - if( rc ) return rc; - }else{ - bSkipnext = 1; - } - } - - /* If the page containing the entry to delete is not a leaf page, move - ** the cursor to the largest entry in the tree that is smaller than - ** the entry being deleted. This cell will replace the cell being deleted - ** from the internal node. The 'previous' entry is used for this instead - ** of the 'next' entry, as the previous entry is always a part of the - ** sub-tree headed by the child page of the cell being deleted. This makes - ** balancing the tree following the delete operation easier. */ - if( !pPage->leaf ){ - int notUsed = 0; - rc = sqlite3BtreePrevious(pCur, ¬Used); - if( rc ) return rc; - } - - /* Save the positions of any other cursors open on this table before - ** making any modifications. */ - if( pCur->curFlags & BTCF_Multiple ){ - rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); - if( rc ) return rc; - } - - /* If this is a delete operation to remove a row from a table b-tree, - ** invalidate any incrblob cursors open on the row being deleted. */ - if( pCur->pKeyInfo==0 ){ - invalidateIncrblobCursors(p, pCur->info.nKey, 0); - } - - /* Make the page containing the entry to be deleted writable. Then free any - ** overflow pages associated with the entry and finally remove the cell - ** itself from within the page. */ - rc = sqlite3PagerWrite(pPage->pDbPage); - if( rc ) return rc; - rc = clearCell(pPage, pCell, &szCell); - dropCell(pPage, iCellIdx, szCell, &rc); - if( rc ) return rc; - - /* If the cell deleted was not located on a leaf page, then the cursor - ** is currently pointing to the largest entry in the sub-tree headed - ** by the child-page of the cell that was just deleted from an internal - ** node. The cell from the leaf node needs to be moved to the internal - ** node to replace the deleted cell. */ - if( !pPage->leaf ){ - MemPage *pLeaf = pCur->apPage[pCur->iPage]; - int nCell; - Pgno n = pCur->apPage[iCellDepth+1]->pgno; - unsigned char *pTmp; - - pCell = findCell(pLeaf, pLeaf->nCell-1); - if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; - nCell = pLeaf->xCellSize(pLeaf, pCell); - assert( MX_CELL_SIZE(pBt) >= nCell ); - pTmp = pBt->pTmpSpace; - assert( pTmp!=0 ); - rc = sqlite3PagerWrite(pLeaf->pDbPage); - if( rc==SQLITE_OK ){ - insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); - } - dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); - if( rc ) return rc; - } - - /* Balance the tree. If the entry deleted was located on a leaf page, - ** then the cursor still points to that page. In this case the first - ** call to balance() repairs the tree, and the if(...) condition is - ** never true. - ** - ** Otherwise, if the entry deleted was on an internal node page, then - ** pCur is pointing to the leaf page from which a cell was removed to - ** replace the cell deleted from the internal node. This is slightly - ** tricky as the leaf node may be underfull, and the internal node may - ** be either under or overfull. In this case run the balancing algorithm - ** on the leaf node first. If the balance proceeds far enough up the - ** tree that we can be sure that any problem in the internal node has - ** been corrected, so be it. Otherwise, after balancing the leaf node, - ** walk the cursor up the tree to the internal node and balance it as - ** well. */ - rc = balance(pCur); - if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ - while( pCur->iPage>iCellDepth ){ - releasePage(pCur->apPage[pCur->iPage--]); - } - rc = balance(pCur); - } - - if( rc==SQLITE_OK ){ - if( bSkipnext ){ - assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); - assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); - assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); - pCur->eState = CURSOR_SKIPNEXT; - if( iCellIdx>=pPage->nCell ){ - pCur->skipNext = -1; - pCur->aiIdx[iCellDepth] = pPage->nCell-1; - }else{ - pCur->skipNext = 1; - } - }else{ - rc = moveToRoot(pCur); - if( bPreserve ){ - pCur->eState = CURSOR_REQUIRESEEK; - } - } - } - return rc; -} - -/* -** Create a new BTree table. Write into *piTable the page -** number for the root page of the new table. -** -** The type of type is determined by the flags parameter. Only the -** following values of flags are currently in use. Other values for -** flags might not work: -** -** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys -** BTREE_ZERODATA Used for SQL indices -*/ -static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ - BtShared *pBt = p->pBt; - MemPage *pRoot; - Pgno pgnoRoot; - int rc; - int ptfFlags; /* Page-type flage for the root page of new table */ - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( pBt->inTransaction==TRANS_WRITE ); - assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); - -#ifdef SQLITE_OMIT_AUTOVACUUM - rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); - if( rc ){ - return rc; - } -#else - if( pBt->autoVacuum ){ - Pgno pgnoMove; /* Move a page here to make room for the root-page */ - MemPage *pPageMove; /* The page to move to. */ - - /* Creating a new table may probably require moving an existing database - ** to make room for the new tables root page. In case this page turns - ** out to be an overflow page, delete all overflow page-map caches - ** held by open cursors. - */ - invalidateAllOverflowCache(pBt); - - /* Read the value of meta[3] from the database to determine where the - ** root page of the new table should go. meta[3] is the largest root-page - ** created so far, so the new root-page is (meta[3]+1). - */ - sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); - pgnoRoot++; - - /* The new root-page may not be allocated on a pointer-map page, or the - ** PENDING_BYTE page. - */ - while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || - pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ - pgnoRoot++; - } - assert( pgnoRoot>=3 || CORRUPT_DB ); - testcase( pgnoRoot<3 ); - - /* Allocate a page. The page that currently resides at pgnoRoot will - ** be moved to the allocated page (unless the allocated page happens - ** to reside at pgnoRoot). - */ - rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT); - if( rc!=SQLITE_OK ){ - return rc; - } - - if( pgnoMove!=pgnoRoot ){ - /* pgnoRoot is the page that will be used for the root-page of - ** the new table (assuming an error did not occur). But we were - ** allocated pgnoMove. If required (i.e. if it was not allocated - ** by extending the file), the current page at position pgnoMove - ** is already journaled. - */ - u8 eType = 0; - Pgno iPtrPage = 0; - - /* Save the positions of any open cursors. This is required in - ** case they are holding a reference to an xFetch reference - ** corresponding to page pgnoRoot. */ - rc = saveAllCursors(pBt, 0, 0); - releasePage(pPageMove); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Move the page currently at pgnoRoot to pgnoMove. */ - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); - if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ - rc = SQLITE_CORRUPT_BKPT; - } - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - assert( eType!=PTRMAP_ROOTPAGE ); - assert( eType!=PTRMAP_FREEPAGE ); - rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); - releasePage(pRoot); - - /* Obtain the page at pgnoRoot */ - if( rc!=SQLITE_OK ){ - return rc; - } - rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = sqlite3PagerWrite(pRoot->pDbPage); - if( rc!=SQLITE_OK ){ - releasePage(pRoot); - return rc; - } - }else{ - pRoot = pPageMove; - } - - /* Update the pointer-map and meta-data with the new root-page number. */ - ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); - if( rc ){ - releasePage(pRoot); - return rc; - } - - /* When the new root page was allocated, page 1 was made writable in - ** order either to increase the database filesize, or to decrement the - ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. - */ - assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); - rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); - if( NEVER(rc) ){ - releasePage(pRoot); - return rc; - } - - }else{ - rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); - if( rc ) return rc; - } -#endif - assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); - if( createTabFlags & BTREE_INTKEY ){ - ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; - }else{ - ptfFlags = PTF_ZERODATA | PTF_LEAF; - } - zeroPage(pRoot, ptfFlags); - sqlite3PagerUnref(pRoot->pDbPage); - assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); - *piTable = (int)pgnoRoot; - return SQLITE_OK; -} -SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ - int rc; - sqlite3BtreeEnter(p); - rc = btreeCreateTable(p, piTable, flags); - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Erase the given database page and all its children. Return -** the page to the freelist. -*/ -static int clearDatabasePage( - BtShared *pBt, /* The BTree that contains the table */ - Pgno pgno, /* Page number to clear */ - int freePageFlag, /* Deallocate page if true */ - int *pnChange /* Add number of Cells freed to this counter */ -){ - MemPage *pPage; - int rc; - unsigned char *pCell; - int i; - int hdr; - u16 szCell; - - assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno>btreePagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; - } - rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); - if( rc ) return rc; - if( pPage->bBusy ){ - rc = SQLITE_CORRUPT_BKPT; - goto cleardatabasepage_out; - } - pPage->bBusy = 1; - hdr = pPage->hdrOffset; - for(i=0; inCell; i++){ - pCell = findCell(pPage, i); - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); - if( rc ) goto cleardatabasepage_out; - } - rc = clearCell(pPage, pCell, &szCell); - if( rc ) goto cleardatabasepage_out; - } - if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); - if( rc ) goto cleardatabasepage_out; - }else if( pnChange ){ - assert( pPage->intKey || CORRUPT_DB ); - testcase( !pPage->intKey ); - *pnChange += pPage->nCell; - } - if( freePageFlag ){ - freePage(pPage, &rc); - }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ - zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); - } - -cleardatabasepage_out: - pPage->bBusy = 0; - releasePage(pPage); - return rc; -} - -/* -** Delete all information from a single table in the database. iTable is -** the page number of the root of the table. After this routine returns, -** the root page is empty, but still exists. -** -** This routine will fail with SQLITE_LOCKED if there are any open -** read cursors on the table. Open write cursors are moved to the -** root of the table. -** -** If pnChange is not NULL, then table iTable must be an intkey table. The -** integer value pointed to by pnChange is incremented by the number of -** entries in the table. -*/ -SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ - int rc; - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - assert( p->inTrans==TRANS_WRITE ); - - rc = saveAllCursors(pBt, (Pgno)iTable, 0); - - if( SQLITE_OK==rc ){ - /* Invalidate all incrblob cursors open on table iTable (assuming iTable - ** is the root of a table b-tree - if it is not, the following call is - ** a no-op). */ - invalidateIncrblobCursors(p, 0, 1); - rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); - } - sqlite3BtreeLeave(p); - return rc; -} - -/* -** Delete all information from the single table that pCur is open on. -** -** This routine only work for pCur on an ephemeral table. -*/ -SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ - return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); -} - -/* -** Erase all information in a table and add the root of the table to -** the freelist. Except, the root of the principle table (the one on -** page 1) is never added to the freelist. -** -** This routine will fail with SQLITE_LOCKED if there are any open -** cursors on the table. -** -** If AUTOVACUUM is enabled and the page at iTable is not the last -** root page in the database file, then the last root page -** in the database file is moved into the slot formerly occupied by -** iTable and that last slot formerly occupied by the last root page -** is added to the freelist instead of iTable. In this say, all -** root pages are kept at the beginning of the database file, which -** is necessary for AUTOVACUUM to work right. *piMoved is set to the -** page number that used to be the last root page in the file before -** the move. If no page gets moved, *piMoved is set to 0. -** The last root page is recorded in meta[3] and the value of -** meta[3] is updated by this procedure. -*/ -static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ - int rc; - MemPage *pPage = 0; - BtShared *pBt = p->pBt; - - assert( sqlite3BtreeHoldsMutex(p) ); - assert( p->inTrans==TRANS_WRITE ); - - /* It is illegal to drop a table if any cursors are open on the - ** database. This is because in auto-vacuum mode the backend may - ** need to move another root-page to fill a gap left by the deleted - ** root page. If an open cursor was using this page a problem would - ** occur. - ** - ** This error is caught long before control reaches this point. - */ - if( NEVER(pBt->pCursor) ){ - sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); - return SQLITE_LOCKED_SHAREDCACHE; - } - - /* - ** It is illegal to drop the sqlite_master table on page 1. But again, - ** this error is caught long before reaching this point. - */ - if( NEVER(iTable<2) ){ - return SQLITE_CORRUPT_BKPT; - } - - rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); - if( rc ) return rc; - rc = sqlite3BtreeClearTable(p, iTable, 0); - if( rc ){ - releasePage(pPage); - return rc; - } - - *piMoved = 0; - -#ifdef SQLITE_OMIT_AUTOVACUUM - freePage(pPage, &rc); - releasePage(pPage); -#else - if( pBt->autoVacuum ){ - Pgno maxRootPgno; - sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); - - if( iTable==maxRootPgno ){ - /* If the table being dropped is the table with the largest root-page - ** number in the database, put the root page on the free list. - */ - freePage(pPage, &rc); - releasePage(pPage); - if( rc!=SQLITE_OK ){ - return rc; - } - }else{ - /* The table being dropped does not have the largest root-page - ** number in the database. So move the page that does into the - ** gap left by the deleted root-page. - */ - MemPage *pMove; - releasePage(pPage); - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - pMove = 0; - rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); - freePage(pMove, &rc); - releasePage(pMove); - if( rc!=SQLITE_OK ){ - return rc; - } - *piMoved = maxRootPgno; - } - - /* Set the new 'max-root-page' value in the database header. This - ** is the old value less one, less one more if that happens to - ** be a root-page number, less one again if that is the - ** PENDING_BYTE_PAGE. - */ - maxRootPgno--; - while( maxRootPgno==PENDING_BYTE_PAGE(pBt) - || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ - maxRootPgno--; - } - assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); - - rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); - }else{ - freePage(pPage, &rc); - releasePage(pPage); - } -#endif - return rc; -} -SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ - int rc; - sqlite3BtreeEnter(p); - rc = btreeDropTable(p, iTable, piMoved); - sqlite3BtreeLeave(p); - return rc; -} - - -/* -** This function may only be called if the b-tree connection already -** has a read or write transaction open on the database. -** -** Read the meta-information out of a database file. Meta[0] -** is the number of free pages currently in the database. Meta[1] -** through meta[15] are available for use by higher layers. Meta[0] -** is read-only, the others are read/write. -** -** The schema layer numbers meta values differently. At the schema -** layer (and the SetCookie and ReadCookie opcodes) the number of -** free pages is not visible. So Cookie[0] is the same as Meta[1]. -** -** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead -** of reading the value out of the header, it instead loads the "DataVersion" -** from the pager. The BTREE_DATA_VERSION value is not actually stored in the -** database file. It is a number computed by the pager. But its access -** pattern is the same as header meta values, and so it is convenient to -** read it from this routine. -*/ -SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ - BtShared *pBt = p->pBt; - - sqlite3BtreeEnter(p); - assert( p->inTrans>TRANS_NONE ); - assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); - assert( pBt->pPage1 ); - assert( idx>=0 && idx<=15 ); - - if( idx==BTREE_DATA_VERSION ){ - *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; - }else{ - *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); - } - - /* If auto-vacuum is disabled in this build and this is an auto-vacuum - ** database, mark the database as read-only. */ -#ifdef SQLITE_OMIT_AUTOVACUUM - if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ - pBt->btsFlags |= BTS_READ_ONLY; - } -#endif - - sqlite3BtreeLeave(p); -} - -/* -** Write meta-information back into the database. Meta[0] is -** read-only and may not be written. -*/ -SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ - BtShared *pBt = p->pBt; - unsigned char *pP1; - int rc; - assert( idx>=1 && idx<=15 ); - sqlite3BtreeEnter(p); - assert( p->inTrans==TRANS_WRITE ); - assert( pBt->pPage1!=0 ); - pP1 = pBt->pPage1->aData; - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc==SQLITE_OK ){ - put4byte(&pP1[36 + idx*4], iMeta); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( idx==BTREE_INCR_VACUUM ){ - assert( pBt->autoVacuum || iMeta==0 ); - assert( iMeta==0 || iMeta==1 ); - pBt->incrVacuum = (u8)iMeta; - } -#endif - } - sqlite3BtreeLeave(p); - return rc; -} - -#ifndef SQLITE_OMIT_BTREECOUNT -/* -** The first argument, pCur, is a cursor opened on some b-tree. Count the -** number of entries in the b-tree and write the result to *pnEntry. -** -** SQLITE_OK is returned if the operation is successfully executed. -** Otherwise, if an error is encountered (i.e. an IO error or database -** corruption) an SQLite error code is returned. -*/ -SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ - i64 nEntry = 0; /* Value to return in *pnEntry */ - int rc; /* Return code */ - - if( pCur->pgnoRoot==0 ){ - *pnEntry = 0; - return SQLITE_OK; - } - rc = moveToRoot(pCur); - - /* Unless an error occurs, the following loop runs one iteration for each - ** page in the B-Tree structure (not including overflow pages). - */ - while( rc==SQLITE_OK ){ - int iIdx; /* Index of child node in parent */ - MemPage *pPage; /* Current page of the b-tree */ - - /* If this is a leaf page or the tree is not an int-key tree, then - ** this page contains countable entries. Increment the entry counter - ** accordingly. - */ - pPage = pCur->apPage[pCur->iPage]; - if( pPage->leaf || !pPage->intKey ){ - nEntry += pPage->nCell; - } - - /* pPage is a leaf node. This loop navigates the cursor so that it - ** points to the first interior cell that it points to the parent of - ** the next page in the tree that has not yet been visited. The - ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell - ** of the page, or to the number of cells in the page if the next page - ** to visit is the right-child of its parent. - ** - ** If all pages in the tree have been visited, return SQLITE_OK to the - ** caller. - */ - if( pPage->leaf ){ - do { - if( pCur->iPage==0 ){ - /* All pages of the b-tree have been visited. Return successfully. */ - *pnEntry = nEntry; - return moveToRoot(pCur); - } - moveToParent(pCur); - }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); - - pCur->aiIdx[pCur->iPage]++; - pPage = pCur->apPage[pCur->iPage]; - } - - /* Descend to the child node of the cell that the cursor currently - ** points at. This is the right-child if (iIdx==pPage->nCell). - */ - iIdx = pCur->aiIdx[pCur->iPage]; - if( iIdx==pPage->nCell ){ - rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); - }else{ - rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); - } - } - - /* An error has occurred. Return an error code. */ - return rc; -} -#endif - -/* -** Return the pager associated with a BTree. This routine is used for -** testing and debugging only. -*/ -SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ - return p->pBt->pPager; -} - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** Append a message to the error message string. -*/ -static void checkAppendMsg( - IntegrityCk *pCheck, - const char *zFormat, - ... -){ - va_list ap; - if( !pCheck->mxErr ) return; - pCheck->mxErr--; - pCheck->nErr++; - va_start(ap, zFormat); - if( pCheck->errMsg.nChar ){ - sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); - } - if( pCheck->zPfx ){ - sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); - } - sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap); - va_end(ap); - if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ - pCheck->mallocFailed = 1; - } -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK - -/* -** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that -** corresponds to page iPg is already set. -*/ -static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); - return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); -} - -/* -** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. -*/ -static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); - pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); -} - - -/* -** Add 1 to the reference count for page iPage. If this is the second -** reference to the page, add an error message to pCheck->zErrMsg. -** Return 1 if there are 2 or more references to the page and 0 if -** if this is the first reference to the page. -** -** Also check that the page number is in bounds. -*/ -static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage==0 ) return 1; - if( iPage>pCheck->nPage ){ - checkAppendMsg(pCheck, "invalid page number %d", iPage); - return 1; - } - if( getPageReferenced(pCheck, iPage) ){ - checkAppendMsg(pCheck, "2nd reference to page %d", iPage); - return 1; - } - setPageReferenced(pCheck, iPage); - return 0; -} - -#ifndef SQLITE_OMIT_AUTOVACUUM -/* -** Check that the entry in the pointer-map for page iChild maps to -** page iParent, pointer type ptrType. If not, append an error message -** to pCheck. -*/ -static void checkPtrmap( - IntegrityCk *pCheck, /* Integrity check context */ - Pgno iChild, /* Child page number */ - u8 eType, /* Expected pointer map type */ - Pgno iParent /* Expected pointer map parent page number */ -){ - int rc; - u8 ePtrmapType; - Pgno iPtrmapParent; - - rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1; - checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); - return; - } - - if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ - checkAppendMsg(pCheck, - "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", - iChild, eType, iParent, ePtrmapType, iPtrmapParent); - } -} -#endif - -/* -** Check the integrity of the freelist or of an overflow page list. -** Verify that the number of pages on the list is N. -*/ -static void checkList( - IntegrityCk *pCheck, /* Integrity checking context */ - int isFreeList, /* True for a freelist. False for overflow page list */ - int iPage, /* Page number for first page in the list */ - int N /* Expected number of pages in the list */ -){ - int i; - int expected = N; - int iFirst = iPage; - while( N-- > 0 && pCheck->mxErr ){ - DbPage *pOvflPage; - unsigned char *pOvflData; - if( iPage<1 ){ - checkAppendMsg(pCheck, - "%d of %d pages missing from overflow list starting at %d", - N+1, expected, iFirst); - break; - } - if( checkRef(pCheck, iPage) ) break; - if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ - checkAppendMsg(pCheck, "failed to get page %d", iPage); - break; - } - pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); - if( isFreeList ){ - int n = get4byte(&pOvflData[4]); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pCheck->pBt->autoVacuum ){ - checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); - } -#endif - if( n>(int)pCheck->pBt->usableSize/4-2 ){ - checkAppendMsg(pCheck, - "freelist leaf count too big on page %d", iPage); - N--; - }else{ - for(i=0; ipBt->autoVacuum ){ - checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0); - } -#endif - checkRef(pCheck, iFreePage); - } - N -= n; - } - } -#ifndef SQLITE_OMIT_AUTOVACUUM - else{ - /* If this database supports auto-vacuum and iPage is not the last - ** page in this overflow list, check that the pointer-map entry for - ** the following page matches iPage. - */ - if( pCheck->pBt->autoVacuum && N>0 ){ - i = get4byte(pOvflData); - checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage); - } - } -#endif - iPage = get4byte(pOvflData); - sqlite3PagerUnref(pOvflPage); - - if( isFreeList && N<(iPage!=0) ){ - checkAppendMsg(pCheck, "free-page count in header is too small"); - } - } -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -/* -** An implementation of a min-heap. -** -** aHeap[0] is the number of elements on the heap. aHeap[1] is the -** root element. The daughter nodes of aHeap[N] are aHeap[N*2] -** and aHeap[N*2+1]. -** -** The heap property is this: Every node is less than or equal to both -** of its daughter nodes. A consequence of the heap property is that the -** root node aHeap[1] is always the minimum value currently in the heap. -** -** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto -** the heap, preserving the heap property. The btreeHeapPull() routine -** removes the root element from the heap (the minimum value in the heap) -** and then moves other nodes around as necessary to preserve the heap -** property. -** -** This heap is used for cell overlap and coverage testing. Each u32 -** entry represents the span of a cell or freeblock on a btree page. -** The upper 16 bits are the index of the first byte of a range and the -** lower 16 bits are the index of the last byte of that range. -*/ -static void btreeHeapInsert(u32 *aHeap, u32 x){ - u32 j, i = ++aHeap[0]; - aHeap[i] = x; - while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ - x = aHeap[j]; - aHeap[j] = aHeap[i]; - aHeap[i] = x; - i = j; - } -} -static int btreeHeapPull(u32 *aHeap, u32 *pOut){ - u32 j, i, x; - if( (x = aHeap[0])==0 ) return 0; - *pOut = aHeap[1]; - aHeap[1] = aHeap[x]; - aHeap[x] = 0xffffffff; - aHeap[0]--; - i = 1; - while( (j = i*2)<=aHeap[0] ){ - if( aHeap[j]>aHeap[j+1] ) j++; - if( aHeap[i]zPfx; - int saved_v1 = pCheck->v1; - int saved_v2 = pCheck->v2; - u8 savedIsInit = 0; - - /* Check that the page exists - */ - pBt = pCheck->pBt; - usableSize = pBt->usableSize; - if( iPage==0 ) return 0; - if( checkRef(pCheck, iPage) ) return 0; - pCheck->zPfx = "Page %d: "; - pCheck->v1 = iPage; - if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ - checkAppendMsg(pCheck, - "unable to get the page. error code=%d", rc); - goto end_of_check; - } - - /* Clear MemPage.isInit to make sure the corruption detection code in - ** btreeInitPage() is executed. */ - savedIsInit = pPage->isInit; - pPage->isInit = 0; - if( (rc = btreeInitPage(pPage))!=0 ){ - assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ - checkAppendMsg(pCheck, - "btreeInitPage() returns error code %d", rc); - goto end_of_check; - } - data = pPage->aData; - hdr = pPage->hdrOffset; - - /* Set up for cell analysis */ - pCheck->zPfx = "On tree page %d cell %d: "; - contentOffset = get2byteNotZero(&data[hdr+5]); - assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ - - /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the - ** number of cells on the page. */ - nCell = get2byte(&data[hdr+3]); - assert( pPage->nCell==nCell ); - - /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page - ** immediately follows the b-tree page header. */ - cellStart = hdr + 12 - 4*pPage->leaf; - assert( pPage->aCellIdx==&data[cellStart] ); - pCellIdx = &data[cellStart + 2*(nCell-1)]; - - if( !pPage->leaf ){ - /* Analyze the right-child page of internal pages */ - pgno = get4byte(&data[hdr+8]); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - pCheck->zPfx = "On page %d at right child: "; - checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); - } -#endif - depth = checkTreePage(pCheck, pgno, &maxKey, maxKey); - keyCanBeEqual = 0; - }else{ - /* For leaf pages, the coverage check will occur in the same loop - ** as the other cell checks, so initialize the heap. */ - heap = pCheck->heap; - heap[0] = 0; - } - - /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte - ** integer offsets to the cell contents. */ - for(i=nCell-1; i>=0 && pCheck->mxErr; i--){ - CellInfo info; - - /* Check cell size */ - pCheck->v2 = i; - assert( pCellIdx==&data[cellStart + i*2] ); - pc = get2byteAligned(pCellIdx); - pCellIdx -= 2; - if( pcusableSize-4 ){ - checkAppendMsg(pCheck, "Offset %d out of range %d..%d", - pc, contentOffset, usableSize-4); - doCoverageCheck = 0; - continue; - } - pCell = &data[pc]; - pPage->xParseCell(pPage, pCell, &info); - if( pc+info.nSize>usableSize ){ - checkAppendMsg(pCheck, "Extends off end of page"); - doCoverageCheck = 0; - continue; - } - - /* Check for integer primary key out of range */ - if( pPage->intKey ){ - if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){ - checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey); - } - maxKey = info.nKey; - } - - /* Check the content overflow list */ - if( info.nPayload>info.nLocal ){ - int nPage; /* Number of pages on the overflow chain */ - Pgno pgnoOvfl; /* First page of the overflow chain */ - assert( pc + info.nSize - 4 <= usableSize ); - nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4); - pgnoOvfl = get4byte(&pCell[info.nSize - 4]); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage); - } -#endif - checkList(pCheck, 0, pgnoOvfl, nPage); - } - - if( !pPage->leaf ){ - /* Check sanity of left child page for internal pages */ - pgno = get4byte(pCell); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( pBt->autoVacuum ){ - checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); - } -#endif - d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey); - keyCanBeEqual = 0; - if( d2!=depth ){ - checkAppendMsg(pCheck, "Child page depth differs"); - depth = d2; - } - }else{ - /* Populate the coverage-checking heap for leaf pages */ - btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); - } - } - *piMinKey = maxKey; - - /* Check for complete coverage of the page - */ - pCheck->zPfx = 0; - if( doCoverageCheck && pCheck->mxErr>0 ){ - /* For leaf pages, the min-heap has already been initialized and the - ** cells have already been inserted. But for internal pages, that has - ** not yet been done, so do it now */ - if( !pPage->leaf ){ - heap = pCheck->heap; - heap[0] = 0; - for(i=nCell-1; i>=0; i--){ - u32 size; - pc = get2byteAligned(&data[cellStart+i*2]); - size = pPage->xCellSize(pPage, &data[pc]); - btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); - } - } - /* Add the freeblocks to the min-heap - ** - ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header - ** is the offset of the first freeblock, or zero if there are no - ** freeblocks on the page. - */ - i = get2byte(&data[hdr+1]); - while( i>0 ){ - int size, j; - assert( (u32)i<=usableSize-4 ); /* Enforced by btreeInitPage() */ - size = get2byte(&data[i+2]); - assert( (u32)(i+size)<=usableSize ); /* Enforced by btreeInitPage() */ - btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); - /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a - ** big-endian integer which is the offset in the b-tree page of the next - ** freeblock in the chain, or zero if the freeblock is the last on the - ** chain. */ - j = get2byte(&data[i]); - /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of - ** increasing offset. */ - assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ - assert( (u32)j<=usableSize-4 ); /* Enforced by btreeInitPage() */ - i = j; - } - /* Analyze the min-heap looking for overlap between cells and/or - ** freeblocks, and counting the number of untracked bytes in nFrag. - ** - ** Each min-heap entry is of the form: (start_address<<16)|end_address. - ** There is an implied first entry the covers the page header, the cell - ** pointer index, and the gap between the cell pointer index and the start - ** of cell content. - ** - ** The loop below pulls entries from the min-heap in order and compares - ** the start_address against the previous end_address. If there is an - ** overlap, that means bytes are used multiple times. If there is a gap, - ** that gap is added to the fragmentation count. - */ - nFrag = 0; - prev = contentOffset - 1; /* Implied first min-heap entry */ - while( btreeHeapPull(heap,&x) ){ - if( (prev&0xffff)>=(x>>16) ){ - checkAppendMsg(pCheck, - "Multiple uses for byte %u of page %d", x>>16, iPage); - break; - }else{ - nFrag += (x>>16) - (prev&0xffff) - 1; - prev = x; - } - } - nFrag += usableSize - (prev&0xffff) - 1; - /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments - ** is stored in the fifth field of the b-tree page header. - ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the - ** number of fragmented free bytes within the cell content area. - */ - if( heap[0]==0 && nFrag!=data[hdr+7] ){ - checkAppendMsg(pCheck, - "Fragmentation of %d bytes reported as %d on page %d", - nFrag, data[hdr+7], iPage); - } - } - -end_of_check: - if( !doCoverageCheck ) pPage->isInit = savedIsInit; - releasePage(pPage); - pCheck->zPfx = saved_zPfx; - pCheck->v1 = saved_v1; - pCheck->v2 = saved_v2; - return depth+1; -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* -** This routine does a complete check of the given BTree file. aRoot[] is -** an array of pages numbers were each page number is the root page of -** a table. nRoot is the number of entries in aRoot. -** -** A read-only or read-write transaction must be opened before calling -** this function. -** -** Write the number of error seen in *pnErr. Except for some memory -** allocation errors, an error message held in memory obtained from -** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is -** returned. If a memory allocation error occurs, NULL is returned. -*/ -SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( - Btree *p, /* The btree to be checked */ - int *aRoot, /* An array of root pages numbers for individual trees */ - int nRoot, /* Number of entries in aRoot[] */ - int mxErr, /* Stop reporting errors after this many */ - int *pnErr /* Write number of errors seen to this variable */ -){ - Pgno i; - IntegrityCk sCheck; - BtShared *pBt = p->pBt; - int savedDbFlags = pBt->db->flags; - char zErr[100]; - VVA_ONLY( int nRef ); - - sqlite3BtreeEnter(p); - assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); - VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); - assert( nRef>=0 ); - sCheck.pBt = pBt; - sCheck.pPager = pBt->pPager; - sCheck.nPage = btreePagecount(sCheck.pBt); - sCheck.mxErr = mxErr; - sCheck.nErr = 0; - sCheck.mallocFailed = 0; - sCheck.zPfx = 0; - sCheck.v1 = 0; - sCheck.v2 = 0; - sCheck.aPgRef = 0; - sCheck.heap = 0; - sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); - sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; - if( sCheck.nPage==0 ){ - goto integrity_ck_cleanup; - } - - sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); - if( !sCheck.aPgRef ){ - sCheck.mallocFailed = 1; - goto integrity_ck_cleanup; - } - sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); - if( sCheck.heap==0 ){ - sCheck.mallocFailed = 1; - goto integrity_ck_cleanup; - } - - i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); - - /* Check the integrity of the freelist - */ - sCheck.zPfx = "Main freelist: "; - checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), - get4byte(&pBt->pPage1->aData[36])); - sCheck.zPfx = 0; - - /* Check all the tables. - */ - testcase( pBt->db->flags & SQLITE_CellSizeCk ); - pBt->db->flags &= ~SQLITE_CellSizeCk; - for(i=0; (int)iautoVacuum && aRoot[i]>1 ){ - checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); - } -#endif - checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); - } - pBt->db->flags = savedDbFlags; - - /* Make sure every page in the file is referenced - */ - for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ -#ifdef SQLITE_OMIT_AUTOVACUUM - if( getPageReferenced(&sCheck, i)==0 ){ - checkAppendMsg(&sCheck, "Page %d is never used", i); - } -#else - /* If the database supports auto-vacuum, make sure no tables contain - ** references to pointer-map pages. - */ - if( getPageReferenced(&sCheck, i)==0 && - (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Page %d is never used", i); - } - if( getPageReferenced(&sCheck, i)!=0 && - (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); - } -#endif - } - - /* Clean up and report errors. - */ -integrity_ck_cleanup: - sqlite3PageFree(sCheck.heap); - sqlite3_free(sCheck.aPgRef); - if( sCheck.mallocFailed ){ - sqlite3StrAccumReset(&sCheck.errMsg); - sCheck.nErr++; - } - *pnErr = sCheck.nErr; - if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); - /* Make sure this analysis did not leave any unref() pages. */ - assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); - sqlite3BtreeLeave(p); - return sqlite3StrAccumFinish(&sCheck.errMsg); -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -/* -** Return the full pathname of the underlying database file. Return -** an empty string if the database is in-memory or a TEMP database. -** -** The pager filename is invariant as long as the pager is -** open so it is safe to access without the BtShared mutex. -*/ -SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ - assert( p->pBt->pPager!=0 ); - return sqlite3PagerFilename(p->pBt->pPager, 1); -} - -/* -** Return the pathname of the journal file for this database. The return -** value of this routine is the same regardless of whether the journal file -** has been created or not. -** -** The pager journal filename is invariant as long as the pager is -** open so it is safe to access without the BtShared mutex. -*/ -SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ - assert( p->pBt->pPager!=0 ); - return sqlite3PagerJournalname(p->pBt->pPager); -} - -/* -** Return non-zero if a transaction is active. -*/ -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ - assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); - return (p && (p->inTrans==TRANS_WRITE)); -} - -#ifndef SQLITE_OMIT_WAL -/* -** Run a checkpoint on the Btree passed as the first argument. -** -** Return SQLITE_LOCKED if this or any other connection has an open -** transaction on the shared-cache the argument Btree is connected to. -** -** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. -*/ -SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ - int rc = SQLITE_OK; - if( p ){ - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( pBt->inTransaction!=TRANS_NONE ){ - rc = SQLITE_LOCKED; - }else{ - rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt); - } - sqlite3BtreeLeave(p); - } - return rc; -} -#endif - -/* -** Return non-zero if a read (or write) transaction is active. -*/ -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){ - assert( p ); - assert( sqlite3_mutex_held(p->db->mutex) ); - return p->inTrans!=TRANS_NONE; -} - -SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ - assert( p ); - assert( sqlite3_mutex_held(p->db->mutex) ); - return p->nBackup!=0; -} - -/* -** This function returns a pointer to a blob of memory associated with -** a single shared-btree. The memory is used by client code for its own -** purposes (for example, to store a high-level schema associated with -** the shared-btree). The btree layer manages reference counting issues. -** -** The first time this is called on a shared-btree, nBytes bytes of memory -** are allocated, zeroed, and returned to the caller. For each subsequent -** call the nBytes parameter is ignored and a pointer to the same blob -** of memory returned. -** -** If the nBytes parameter is 0 and the blob of memory has not yet been -** allocated, a null pointer is returned. If the blob has already been -** allocated, it is returned as normal. -** -** Just before the shared-btree is closed, the function passed as the -** xFree argument when the memory allocation was made is invoked on the -** blob of allocated memory. The xFree function should not call sqlite3_free() -** on the memory, the btree layer does that. -*/ -SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ - BtShared *pBt = p->pBt; - sqlite3BtreeEnter(p); - if( !pBt->pSchema && nBytes ){ - pBt->pSchema = sqlite3DbMallocZero(0, nBytes); - pBt->xFreeSchema = xFree; - } - sqlite3BtreeLeave(p); - return pBt->pSchema; -} - -/* -** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared -** btree as the argument handle holds an exclusive lock on the -** sqlite_master table. Otherwise SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ - int rc; - assert( sqlite3_mutex_held(p->db->mutex) ); - sqlite3BtreeEnter(p); - rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); - assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); - sqlite3BtreeLeave(p); - return rc; -} - - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** Obtain a lock on the table whose root page is iTab. The -** lock is a write lock if isWritelock is true or a read lock -** if it is false. -*/ -SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ - int rc = SQLITE_OK; - assert( p->inTrans!=TRANS_NONE ); - if( p->sharable ){ - u8 lockType = READ_LOCK + isWriteLock; - assert( READ_LOCK+1==WRITE_LOCK ); - assert( isWriteLock==0 || isWriteLock==1 ); - - sqlite3BtreeEnter(p); - rc = querySharedCacheTableLock(p, iTab, lockType); - if( rc==SQLITE_OK ){ - rc = setSharedCacheTableLock(p, iTab, lockType); - } - sqlite3BtreeLeave(p); - } - return rc; -} -#endif - -#ifndef SQLITE_OMIT_INCRBLOB -/* -** Argument pCsr must be a cursor opened for writing on an -** INTKEY table currently pointing at a valid table entry. -** This function modifies the data stored as part of that entry. -** -** Only the data content may only be modified, it is not possible to -** change the length of the data stored. If this function is called with -** parameters that attempt to write past the end of the existing data, -** no modifications are made and SQLITE_CORRUPT is returned. -*/ -SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ - int rc; - assert( cursorOwnsBtShared(pCsr) ); - assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); - assert( pCsr->curFlags & BTCF_Incrblob ); - - rc = restoreCursorPosition(pCsr); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pCsr->eState!=CURSOR_REQUIRESEEK ); - if( pCsr->eState!=CURSOR_VALID ){ - return SQLITE_ABORT; - } - - /* Save the positions of all other cursors open on this table. This is - ** required in case any of them are holding references to an xFetch - ** version of the b-tree page modified by the accessPayload call below. - ** - ** Note that pCsr must be open on a INTKEY table and saveCursorPosition() - ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence - ** saveAllCursors can only return SQLITE_OK. - */ - VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); - assert( rc==SQLITE_OK ); - - /* Check some assumptions: - ** (a) the cursor is open for writing, - ** (b) there is a read/write transaction open, - ** (c) the connection holds a write-lock on the table (if required), - ** (d) there are no conflicting read-locks, and - ** (e) the cursor points at a valid row of an intKey table. - */ - if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ - return SQLITE_READONLY; - } - assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 - && pCsr->pBt->inTransaction==TRANS_WRITE ); - assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); - assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); - assert( pCsr->apPage[pCsr->iPage]->intKey ); - - return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); -} - -/* -** Mark this cursor as an incremental blob cursor. -*/ -SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ - pCur->curFlags |= BTCF_Incrblob; - pCur->pBtree->hasIncrblobCur = 1; -} -#endif - -/* -** Set both the "read version" (single byte at byte offset 18) and -** "write version" (single byte at byte offset 19) fields in the database -** header to iVersion. -*/ -SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ - BtShared *pBt = pBtree->pBt; - int rc; /* Return code */ - - assert( iVersion==1 || iVersion==2 ); - - /* If setting the version fields to 1, do not automatically open the - ** WAL connection, even if the version fields are currently set to 2. - */ - pBt->btsFlags &= ~BTS_NO_WAL; - if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - - rc = sqlite3BtreeBeginTrans(pBtree, 0); - if( rc==SQLITE_OK ){ - u8 *aData = pBt->pPage1->aData; - if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ - rc = sqlite3BtreeBeginTrans(pBtree, 2); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - if( rc==SQLITE_OK ){ - aData[18] = (u8)iVersion; - aData[19] = (u8)iVersion; - } - } - } - } - - pBt->btsFlags &= ~BTS_NO_WAL; - return rc; -} - -/* -** Return true if the cursor has a hint specified. This routine is -** only used from within assert() statements -*/ -SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ - return (pCsr->hints & mask)!=0; -} - -/* -** Return true if the given Btree is read-only. -*/ -SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ - return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; -} - -/* -** Return the size of the header added to each page by this module. -*/ -SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } - -#if !defined(SQLITE_OMIT_SHARED_CACHE) -/* -** Return true if the Btree passed as the only argument is sharable. -*/ -SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ - return p->sharable; -} - -/* -** Return the number of connections to the BtShared object accessed by -** the Btree handle passed as the only argument. For private caches -** this is always 1. For shared caches it may be 1 or greater. -*/ -SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ - testcase( p->sharable ); - return p->pBt->nRef; -} -#endif - -/************** End of btree.c ***********************************************/ -/************** Begin file backup.c ******************************************/ -/* -** 2009 January 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the implementation of the sqlite3_backup_XXX() -** API functions and the related features. -*/ -/* #include "sqliteInt.h" */ -/* #include "btreeInt.h" */ - -/* -** Structure allocated for each backup operation. -*/ -struct sqlite3_backup { - sqlite3* pDestDb; /* Destination database handle */ - Btree *pDest; /* Destination b-tree file */ - u32 iDestSchema; /* Original schema cookie in destination */ - int bDestLocked; /* True once a write-transaction is open on pDest */ - - Pgno iNext; /* Page number of the next source page to copy */ - sqlite3* pSrcDb; /* Source database handle */ - Btree *pSrc; /* Source b-tree file */ - - int rc; /* Backup process error code */ - - /* These two variables are set by every call to backup_step(). They are - ** read by calls to backup_remaining() and backup_pagecount(). - */ - Pgno nRemaining; /* Number of pages left to copy */ - Pgno nPagecount; /* Total number of pages to copy */ - - int isAttached; /* True once backup has been registered with pager */ - sqlite3_backup *pNext; /* Next backup associated with source pager */ -}; - -/* -** THREAD SAFETY NOTES: -** -** Once it has been created using backup_init(), a single sqlite3_backup -** structure may be accessed via two groups of thread-safe entry points: -** -** * Via the sqlite3_backup_XXX() API function backup_step() and -** backup_finish(). Both these functions obtain the source database -** handle mutex and the mutex associated with the source BtShared -** structure, in that order. -** -** * Via the BackupUpdate() and BackupRestart() functions, which are -** invoked by the pager layer to report various state changes in -** the page cache associated with the source database. The mutex -** associated with the source database BtShared structure will always -** be held when either of these functions are invoked. -** -** The other sqlite3_backup_XXX() API functions, backup_remaining() and -** backup_pagecount() are not thread-safe functions. If they are called -** while some other thread is calling backup_step() or backup_finish(), -** the values returned may be invalid. There is no way for a call to -** BackupUpdate() or BackupRestart() to interfere with backup_remaining() -** or backup_pagecount(). -** -** Depending on the SQLite configuration, the database handles and/or -** the Btree objects may have their own mutexes that require locking. -** Non-sharable Btrees (in-memory databases for example), do not have -** associated mutexes. -*/ - -/* -** Return a pointer corresponding to database zDb (i.e. "main", "temp") -** in connection handle pDb. If such a database cannot be found, return -** a NULL pointer and write an error message to pErrorDb. -** -** If the "temp" database is requested, it may need to be opened by this -** function. If an error occurs while doing so, return 0 and write an -** error message to pErrorDb. -*/ -static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ - int i = sqlite3FindDbName(pDb, zDb); - - if( i==1 ){ - Parse sParse; - int rc = 0; - memset(&sParse, 0, sizeof(sParse)); - sParse.db = pDb; - if( sqlite3OpenTempDatabase(&sParse) ){ - sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); - rc = SQLITE_ERROR; - } - sqlite3DbFree(pErrorDb, sParse.zErrMsg); - sqlite3ParserReset(&sParse); - if( rc ){ - return 0; - } - } - - if( i<0 ){ - sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); - return 0; - } - - return pDb->aDb[i].pBt; -} - -/* -** Attempt to set the page size of the destination to match the page size -** of the source. -*/ -static int setDestPgsz(sqlite3_backup *p){ - int rc; - rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0); - return rc; -} - -/* -** Check that there is no open read-transaction on the b-tree passed as the -** second argument. If there is not, return SQLITE_OK. Otherwise, if there -** is an open read-transaction, return SQLITE_ERROR and leave an error -** message in database handle db. -*/ -static int checkReadTransaction(sqlite3 *db, Btree *p){ - if( sqlite3BtreeIsInReadTrans(p) ){ - sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); - return SQLITE_ERROR; - } - return SQLITE_OK; -} - -/* -** Create an sqlite3_backup process to copy the contents of zSrcDb from -** connection handle pSrcDb to zDestDb in pDestDb. If successful, return -** a pointer to the new sqlite3_backup object. -** -** If an error occurs, NULL is returned and an error code and error message -** stored in database handle pDestDb. -*/ -SQLITE_API sqlite3_backup *sqlite3_backup_init( - sqlite3* pDestDb, /* Database to write to */ - const char *zDestDb, /* Name of database within pDestDb */ - sqlite3* pSrcDb, /* Database connection to read from */ - const char *zSrcDb /* Name of database within pSrcDb */ -){ - sqlite3_backup *p; /* Value to return */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - - /* Lock the source database handle. The destination database - ** handle is not locked in this routine, but it is locked in - ** sqlite3_backup_step(). The user is required to ensure that no - ** other thread accesses the destination handle for the duration - ** of the backup operation. Any attempt to use the destination - ** database connection while a backup is in progress may cause - ** a malfunction or a deadlock. - */ - sqlite3_mutex_enter(pSrcDb->mutex); - sqlite3_mutex_enter(pDestDb->mutex); - - if( pSrcDb==pDestDb ){ - sqlite3ErrorWithMsg( - pDestDb, SQLITE_ERROR, "source and destination must be distinct" - ); - p = 0; - }else { - /* Allocate space for a new sqlite3_backup object... - ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a - ** call to sqlite3_backup_init() and is destroyed by a call to - ** sqlite3_backup_finish(). */ - p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); - if( !p ){ - sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); - } - } - - /* If the allocation succeeded, populate the new object. */ - if( p ){ - p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); - p->pDest = findBtree(pDestDb, pDestDb, zDestDb); - p->pDestDb = pDestDb; - p->pSrcDb = pSrcDb; - p->iNext = 1; - p->isAttached = 0; - - if( 0==p->pSrc || 0==p->pDest - || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK - ){ - /* One (or both) of the named databases did not exist or an OOM - ** error was hit. Or there is a transaction open on the destination - ** database. The error has already been written into the pDestDb - ** handle. All that is left to do here is free the sqlite3_backup - ** structure. */ - sqlite3_free(p); - p = 0; - } - } - if( p ){ - p->pSrc->nBackup++; - } - - sqlite3_mutex_leave(pDestDb->mutex); - sqlite3_mutex_leave(pSrcDb->mutex); - return p; -} - -/* -** Argument rc is an SQLite error code. Return true if this error is -** considered fatal if encountered during a backup operation. All errors -** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. -*/ -static int isFatalError(int rc){ - return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED)); -} - -/* -** Parameter zSrcData points to a buffer containing the data for -** page iSrcPg from the source database. Copy this data into the -** destination database. -*/ -static int backupOnePage( - sqlite3_backup *p, /* Backup handle */ - Pgno iSrcPg, /* Source database page to backup */ - const u8 *zSrcData, /* Source database page data */ - int bUpdate /* True for an update, false otherwise */ -){ - Pager * const pDestPager = sqlite3BtreePager(p->pDest); - const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); - int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); - const int nCopy = MIN(nSrcPgsz, nDestPgsz); - const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; -#ifdef SQLITE_HAS_CODEC - /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is - ** guaranteed that the shared-mutex is held by this thread, handle - ** p->pSrc may not actually be the owner. */ - int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); - int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest); -#endif - int rc = SQLITE_OK; - i64 iOff; - - assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); - assert( p->bDestLocked ); - assert( !isFatalError(p->rc) ); - assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); - assert( zSrcData ); - - /* Catch the case where the destination is an in-memory database and the - ** page sizes of the source and destination differ. - */ - if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ - rc = SQLITE_READONLY; - } - -#ifdef SQLITE_HAS_CODEC - /* Backup is not possible if the page size of the destination is changing - ** and a codec is in use. - */ - if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ - rc = SQLITE_READONLY; - } - - /* Backup is not possible if the number of bytes of reserve space differ - ** between source and destination. If there is a difference, try to - ** fix the destination to agree with the source. If that is not possible, - ** then the backup cannot proceed. - */ - if( nSrcReserve!=nDestReserve ){ - u32 newPgsz = nSrcPgsz; - rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); - if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; - } -#endif - - /* This loop runs once for each destination page spanned by the source - ** page. For each iteration, variable iOff is set to the byte offset - ** of the destination page. - */ - for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffpDest->pBt) ) continue; - if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) - && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) - ){ - const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; - u8 *zDestData = sqlite3PagerGetData(pDestPg); - u8 *zOut = &zDestData[iOff%nDestPgsz]; - - /* Copy the data from the source page into the destination page. - ** Then clear the Btree layer MemPage.isInit flag. Both this module - ** and the pager code use this trick (clearing the first byte - ** of the page 'extra' space to invalidate the Btree layers - ** cached parse of the page). MemPage.isInit is marked - ** "MUST BE FIRST" for this purpose. - */ - memcpy(zOut, zIn, nCopy); - ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; - if( iOff==0 && bUpdate==0 ){ - sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); - } - } - sqlite3PagerUnref(pDestPg); - } - - return rc; -} - -/* -** If pFile is currently larger than iSize bytes, then truncate it to -** exactly iSize bytes. If pFile is not larger than iSize bytes, then -** this function is a no-op. -** -** Return SQLITE_OK if everything is successful, or an SQLite error -** code if an error occurs. -*/ -static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ - i64 iCurrent; - int rc = sqlite3OsFileSize(pFile, &iCurrent); - if( rc==SQLITE_OK && iCurrent>iSize ){ - rc = sqlite3OsTruncate(pFile, iSize); - } - return rc; -} - -/* -** Register this backup object with the associated source pager for -** callbacks when pages are changed or the cache invalidated. -*/ -static void attachBackupObject(sqlite3_backup *p){ - sqlite3_backup **pp; - assert( sqlite3BtreeHoldsMutex(p->pSrc) ); - pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); - p->pNext = *pp; - *pp = p; - p->isAttached = 1; -} - -/* -** Copy nPage pages from the source b-tree to the destination. -*/ -SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ - int rc; - int destMode; /* Destination journal mode */ - int pgszSrc = 0; /* Source page size */ - int pgszDest = 0; /* Destination page size */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(p->pSrcDb->mutex); - sqlite3BtreeEnter(p->pSrc); - if( p->pDestDb ){ - sqlite3_mutex_enter(p->pDestDb->mutex); - } - - rc = p->rc; - if( !isFatalError(rc) ){ - Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ - Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ - int ii; /* Iterator variable */ - int nSrcPage = -1; /* Size of source db in pages */ - int bCloseTrans = 0; /* True if src db requires unlocking */ - - /* If the source pager is currently in a write-transaction, return - ** SQLITE_BUSY immediately. - */ - if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ - rc = SQLITE_BUSY; - }else{ - rc = SQLITE_OK; - } - - /* If there is no open read-transaction on the source database, open - ** one now. If a transaction is opened here, then it will be closed - ** before this function exits. - */ - if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ - rc = sqlite3BtreeBeginTrans(p->pSrc, 0); - bCloseTrans = 1; - } - - /* If the destination database has not yet been locked (i.e. if this - ** is the first call to backup_step() for the current backup operation), - ** try to set its page size to the same as the source database. This - ** is especially important on ZipVFS systems, as in that case it is - ** not possible to create a database file that uses one page size by - ** writing to it with another. */ - if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ - rc = SQLITE_NOMEM; - } - - /* Lock the destination database, if it is not locked already. */ - if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) - ){ - p->bDestLocked = 1; - sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); - } - - /* Do not allow backup if the destination database is in WAL mode - ** and the page sizes are different between source and destination */ - pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); - pgszDest = sqlite3BtreeGetPageSize(p->pDest); - destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); - if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ - rc = SQLITE_READONLY; - } - - /* Now that there is a read-lock on the source database, query the - ** source pager for the number of pages in the database. - */ - nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); - assert( nSrcPage>=0 ); - for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ - const Pgno iSrcPg = p->iNext; /* Source page number */ - if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ - DbPage *pSrcPg; /* Source page object */ - rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); - if( rc==SQLITE_OK ){ - rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); - sqlite3PagerUnref(pSrcPg); - } - } - p->iNext++; - } - if( rc==SQLITE_OK ){ - p->nPagecount = nSrcPage; - p->nRemaining = nSrcPage+1-p->iNext; - if( p->iNext>(Pgno)nSrcPage ){ - rc = SQLITE_DONE; - }else if( !p->isAttached ){ - attachBackupObject(p); - } - } - - /* Update the schema version field in the destination database. This - ** is to make sure that the schema-version really does change in - ** the case where the source and destination databases have the - ** same schema version. - */ - if( rc==SQLITE_DONE ){ - if( nSrcPage==0 ){ - rc = sqlite3BtreeNewDb(p->pDest); - nSrcPage = 1; - } - if( rc==SQLITE_OK || rc==SQLITE_DONE ){ - rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); - } - if( rc==SQLITE_OK ){ - if( p->pDestDb ){ - sqlite3ResetAllSchemasOfConnection(p->pDestDb); - } - if( destMode==PAGER_JOURNALMODE_WAL ){ - rc = sqlite3BtreeSetVersion(p->pDest, 2); - } - } - if( rc==SQLITE_OK ){ - int nDestTruncate; - /* Set nDestTruncate to the final number of pages in the destination - ** database. The complication here is that the destination page - ** size may be different to the source page size. - ** - ** If the source page size is smaller than the destination page size, - ** round up. In this case the call to sqlite3OsTruncate() below will - ** fix the size of the file. However it is important to call - ** sqlite3PagerTruncateImage() here so that any pages in the - ** destination file that lie beyond the nDestTruncate page mark are - ** journalled by PagerCommitPhaseOne() before they are destroyed - ** by the file truncation. - */ - assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); - assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); - if( pgszSrcpDest->pBt) ){ - nDestTruncate--; - } - }else{ - nDestTruncate = nSrcPage * (pgszSrc/pgszDest); - } - assert( nDestTruncate>0 ); - - if( pgszSrc= iSize || ( - nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) - && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest - )); - - /* This block ensures that all data required to recreate the original - ** database has been stored in the journal for pDestPager and the - ** journal synced to disk. So at this point we may safely modify - ** the database file in any way, knowing that if a power failure - ** occurs, the original database will be reconstructed from the - ** journal file. */ - sqlite3PagerPagecount(pDestPager, &nDstPage); - for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){ - if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){ - DbPage *pPg; - rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerWrite(pPg); - sqlite3PagerUnref(pPg); - } - } - } - if( rc==SQLITE_OK ){ - rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); - } - - /* Write the extra pages and truncate the database file as required */ - iEnd = MIN(PENDING_BYTE + pgszDest, iSize); - for( - iOff=PENDING_BYTE+pgszSrc; - rc==SQLITE_OK && iOffpDest, 0)) - ){ - rc = SQLITE_DONE; - } - } - } - - /* If bCloseTrans is true, then this function opened a read transaction - ** on the source database. Close the read transaction here. There is - ** no need to check the return values of the btree methods here, as - ** "committing" a read-only transaction cannot fail. - */ - if( bCloseTrans ){ - TESTONLY( int rc2 ); - TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); - TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); - assert( rc2==SQLITE_OK ); - } - - if( rc==SQLITE_IOERR_NOMEM ){ - rc = SQLITE_NOMEM_BKPT; - } - p->rc = rc; - } - if( p->pDestDb ){ - sqlite3_mutex_leave(p->pDestDb->mutex); - } - sqlite3BtreeLeave(p->pSrc); - sqlite3_mutex_leave(p->pSrcDb->mutex); - return rc; -} - -/* -** Release all resources associated with an sqlite3_backup* handle. -*/ -SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ - sqlite3_backup **pp; /* Ptr to head of pagers backup list */ - sqlite3 *pSrcDb; /* Source database connection */ - int rc; /* Value to return */ - - /* Enter the mutexes */ - if( p==0 ) return SQLITE_OK; - pSrcDb = p->pSrcDb; - sqlite3_mutex_enter(pSrcDb->mutex); - sqlite3BtreeEnter(p->pSrc); - if( p->pDestDb ){ - sqlite3_mutex_enter(p->pDestDb->mutex); - } - - /* Detach this backup from the source pager. */ - if( p->pDestDb ){ - p->pSrc->nBackup--; - } - if( p->isAttached ){ - pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); - while( *pp!=p ){ - pp = &(*pp)->pNext; - } - *pp = p->pNext; - } - - /* If a transaction is still open on the Btree, roll it back. */ - sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); - - /* Set the error code of the destination database handle. */ - rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; - if( p->pDestDb ){ - sqlite3Error(p->pDestDb, rc); - - /* Exit the mutexes and free the backup context structure. */ - sqlite3LeaveMutexAndCloseZombie(p->pDestDb); - } - sqlite3BtreeLeave(p->pSrc); - if( p->pDestDb ){ - /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a - ** call to sqlite3_backup_init() and is destroyed by a call to - ** sqlite3_backup_finish(). */ - sqlite3_free(p); - } - sqlite3LeaveMutexAndCloseZombie(pSrcDb); - return rc; -} - -/* -** Return the number of pages still to be backed up as of the most recent -** call to sqlite3_backup_step(). -*/ -SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return p->nRemaining; -} - -/* -** Return the total number of pages in the source database as of the most -** recent call to sqlite3_backup_step(). -*/ -SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( p==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return p->nPagecount; -} - -/* -** This function is called after the contents of page iPage of the -** source database have been modified. If page iPage has already been -** copied into the destination database, then the data written to the -** destination is now invalidated. The destination copy of iPage needs -** to be updated with the new data before the backup operation is -** complete. -** -** It is assumed that the mutex associated with the BtShared object -** corresponding to the source database is held when this function is -** called. -*/ -static SQLITE_NOINLINE void backupUpdate( - sqlite3_backup *p, - Pgno iPage, - const u8 *aData -){ - assert( p!=0 ); - do{ - assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); - if( !isFatalError(p->rc) && iPageiNext ){ - /* The backup process p has already copied page iPage. But now it - ** has been modified by a transaction on the source pager. Copy - ** the new data into the backup. - */ - int rc; - assert( p->pDestDb ); - sqlite3_mutex_enter(p->pDestDb->mutex); - rc = backupOnePage(p, iPage, aData, 1); - sqlite3_mutex_leave(p->pDestDb->mutex); - assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); - if( rc!=SQLITE_OK ){ - p->rc = rc; - } - } - }while( (p = p->pNext)!=0 ); -} -SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ - if( pBackup ) backupUpdate(pBackup, iPage, aData); -} - -/* -** Restart the backup process. This is called when the pager layer -** detects that the database has been modified by an external database -** connection. In this case there is no way of knowing which of the -** pages that have been copied into the destination database are still -** valid and which are not, so the entire process needs to be restarted. -** -** It is assumed that the mutex associated with the BtShared object -** corresponding to the source database is held when this function is -** called. -*/ -SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ - sqlite3_backup *p; /* Iterator variable */ - for(p=pBackup; p; p=p->pNext){ - assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); - p->iNext = 1; - } -} - -#ifndef SQLITE_OMIT_VACUUM -/* -** Copy the complete content of pBtFrom into pBtTo. A transaction -** must be active for both files. -** -** The size of file pTo may be reduced by this operation. If anything -** goes wrong, the transaction on pTo is rolled back. If successful, the -** transaction is committed before returning. -*/ -SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ - int rc; - sqlite3_file *pFd; /* File descriptor for database pTo */ - sqlite3_backup b; - sqlite3BtreeEnter(pTo); - sqlite3BtreeEnter(pFrom); - - assert( sqlite3BtreeIsInTrans(pTo) ); - pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); - if( pFd->pMethods ){ - i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); - rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - if( rc ) goto copy_finished; - } - - /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set - ** to 0. This is used by the implementations of sqlite3_backup_step() - ** and sqlite3_backup_finish() to detect that they are being called - ** from this function, not directly by the user. - */ - memset(&b, 0, sizeof(b)); - b.pSrcDb = pFrom->db; - b.pSrc = pFrom; - b.pDest = pTo; - b.iNext = 1; - -#ifdef SQLITE_HAS_CODEC - sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom)); -#endif - - /* 0x7FFFFFFF is the hard limit for the number of pages in a database - ** file. By passing this as the number of pages to copy to - ** sqlite3_backup_step(), we can guarantee that the copy finishes - ** within a single call (unless an error occurs). The assert() statement - ** checks this assumption - (p->rc) should be set to either SQLITE_DONE - ** or an error code. */ - sqlite3_backup_step(&b, 0x7FFFFFFF); - assert( b.rc!=SQLITE_OK ); - - rc = sqlite3_backup_finish(&b); - if( rc==SQLITE_OK ){ - pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; - }else{ - sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); - } - - assert( sqlite3BtreeIsInTrans(pTo)==0 ); -copy_finished: - sqlite3BtreeLeave(pFrom); - sqlite3BtreeLeave(pTo); - return rc; -} -#endif /* SQLITE_OMIT_VACUUM */ - -/************** End of backup.c **********************************************/ -/************** Begin file vdbemem.c *****************************************/ -/* -** 2004 May 26 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code use to manipulate "Mem" structure. A "Mem" -** stores a single value in the VDBE. Mem is an opaque structure visible -** only within the VDBE. Interface routines refer to a Mem using the -** name sqlite_value -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -#ifdef SQLITE_DEBUG -/* -** Check invariants on a Mem object. -** -** This routine is intended for use inside of assert() statements, like -** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); -*/ -SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ - /* If MEM_Dyn is set then Mem.xDel!=0. - ** Mem.xDel is might not be initialized if MEM_Dyn is clear. - */ - assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); - - /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we - ** ensure that if Mem.szMalloc>0 then it is safe to do - ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. - ** That saves a few cycles in inner loops. */ - assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); - - /* Cannot be both MEM_Int and MEM_Real at the same time */ - assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); - - /* The szMalloc field holds the correct memory allocation size */ - assert( p->szMalloc==0 - || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); - - /* If p holds a string or blob, the Mem.z must point to exactly - ** one of the following: - ** - ** (1) Memory in Mem.zMalloc and managed by the Mem object - ** (2) Memory to be freed using Mem.xDel - ** (3) An ephemeral string or blob - ** (4) A static string or blob - */ - if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){ - assert( - ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) + - ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + - ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + - ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 - ); - } - return 1; -} -#endif - - -/* -** If pMem is an object with a valid string representation, this routine -** ensures the internal encoding for the string representation is -** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. -** -** If pMem is not a string object, or the encoding of the string -** representation is already stored using the requested encoding, then this -** routine is a no-op. -** -** SQLITE_OK is returned if the conversion is successful (or not required). -** SQLITE_NOMEM may be returned if a malloc() fails during conversion -** between formats. -*/ -SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ -#ifndef SQLITE_OMIT_UTF16 - int rc; -#endif - assert( (pMem->flags&MEM_RowSet)==0 ); - assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE - || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ - return SQLITE_OK; - } - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); -#ifdef SQLITE_OMIT_UTF16 - return SQLITE_ERROR; -#else - - /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, - ** then the encoding of the value may not have changed. - */ - rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); - assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); - assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); - assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); - return rc; -#endif -} - -/* -** Make sure pMem->z points to a writable allocation of at least -** min(n,32) bytes. -** -** If the bPreserve argument is true, then copy of the content of -** pMem->z into the new allocation. pMem must be either a string or -** blob if bPreserve is true. If bPreserve is false, any prior content -** in pMem->z is discarded. -*/ -SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ - assert( sqlite3VdbeCheckMemInvariants(pMem) ); - assert( (pMem->flags&MEM_RowSet)==0 ); - testcase( pMem->db==0 ); - - /* If the bPreserve flag is set to true, then the memory cell must already - ** contain a valid string or blob value. */ - assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); - testcase( bPreserve && pMem->z==0 ); - - assert( pMem->szMalloc==0 - || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); - if( pMem->szMallocszMalloc>0 && pMem->z==pMem->zMalloc ){ - pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); - bPreserve = 0; - }else{ - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); - pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); - } - if( pMem->zMalloc==0 ){ - sqlite3VdbeMemSetNull(pMem); - pMem->z = 0; - pMem->szMalloc = 0; - return SQLITE_NOMEM_BKPT; - }else{ - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); - } - } - - if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ - memcpy(pMem->zMalloc, pMem->z, pMem->n); - } - if( (pMem->flags&MEM_Dyn)!=0 ){ - assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); - pMem->xDel((void *)(pMem->z)); - } - - pMem->z = pMem->zMalloc; - pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); - return SQLITE_OK; -} - -/* -** Change the pMem->zMalloc allocation to be at least szNew bytes. -** If pMem->zMalloc already meets or exceeds the requested size, this -** routine is a no-op. -** -** Any prior string or blob content in the pMem object may be discarded. -** The pMem->xDel destructor is called, if it exists. Though MEM_Str -** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null -** values are preserved. -** -** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) -** if unable to complete the resizing. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ - assert( szNew>0 ); - assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); - if( pMem->szMallocflags & MEM_Dyn)==0 ); - pMem->z = pMem->zMalloc; - pMem->flags &= (MEM_Null|MEM_Int|MEM_Real); - return SQLITE_OK; -} - -/* -** Change pMem so that its MEM_Str or MEM_Blob value is stored in -** MEM.zMalloc, where it can be safely written. -** -** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags&MEM_RowSet)==0 ); - if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ - if( ExpandBlob(pMem) ) return SQLITE_NOMEM; - if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ - if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ - return SQLITE_NOMEM_BKPT; - } - pMem->z[pMem->n] = 0; - pMem->z[pMem->n+1] = 0; - pMem->flags |= MEM_Term; - } - } - pMem->flags &= ~MEM_Ephem; -#ifdef SQLITE_DEBUG - pMem->pScopyFrom = 0; -#endif - - return SQLITE_OK; -} - -/* -** If the given Mem* has a zero-filled tail, turn it into an ordinary -** blob stored in dynamically allocated space. -*/ -#ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ - int nByte; - assert( pMem->flags & MEM_Zero ); - assert( pMem->flags&MEM_Blob ); - assert( (pMem->flags&MEM_RowSet)==0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - - /* Set nByte to the number of bytes required to store the expanded blob. */ - nByte = pMem->n + pMem->u.nZero; - if( nByte<=0 ){ - nByte = 1; - } - if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ - return SQLITE_NOMEM_BKPT; - } - - memset(&pMem->z[pMem->n], 0, pMem->u.nZero); - pMem->n += pMem->u.nZero; - pMem->flags &= ~(MEM_Zero|MEM_Term); - return SQLITE_OK; -} -#endif - -/* -** It is already known that pMem contains an unterminated string. -** Add the zero terminator. -*/ -static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ - if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ - return SQLITE_NOMEM_BKPT; - } - pMem->z[pMem->n] = 0; - pMem->z[pMem->n+1] = 0; - pMem->flags |= MEM_Term; - return SQLITE_OK; -} - -/* -** Make sure the given Mem is \u0000 terminated. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); - testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); - if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ - return SQLITE_OK; /* Nothing to do */ - }else{ - return vdbeMemAddTerminator(pMem); - } -} - -/* -** Add MEM_Str to the set of representations for the given Mem. Numbers -** are converted using sqlite3_snprintf(). Converting a BLOB to a string -** is a no-op. -** -** Existing representations MEM_Int and MEM_Real are invalidated if -** bForce is true but are retained if bForce is false. -** -** A MEM_Null value will never be passed to this function. This function is -** used for converting values to text for returning to the user (i.e. via -** sqlite3_value_text()), or for ensuring that values to be used as btree -** keys are strings. In the former case a NULL pointer is returned the -** user and the latter is an internal programming error. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ - int fg = pMem->flags; - const int nByte = 32; - - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( !(fg&MEM_Zero) ); - assert( !(fg&(MEM_Str|MEM_Blob)) ); - assert( fg&(MEM_Int|MEM_Real) ); - assert( (pMem->flags&MEM_RowSet)==0 ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - - if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ - pMem->enc = 0; - return SQLITE_NOMEM_BKPT; - } - - /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 - ** string representation of the value. Then, if the required encoding - ** is UTF-16le or UTF-16be do a translation. - ** - ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. - */ - if( fg & MEM_Int ){ - sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); - }else{ - assert( fg & MEM_Real ); - sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); - } - pMem->n = sqlite3Strlen30(pMem->z); - pMem->enc = SQLITE_UTF8; - pMem->flags |= MEM_Str|MEM_Term; - if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); - sqlite3VdbeChangeEncoding(pMem, enc); - return SQLITE_OK; -} - -/* -** Memory cell pMem contains the context of an aggregate function. -** This routine calls the finalize method for that function. The -** result of the aggregate is stored back into pMem. -** -** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK -** otherwise. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ - int rc = SQLITE_OK; - if( ALWAYS(pFunc && pFunc->xFinalize) ){ - sqlite3_context ctx; - Mem t; - assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - memset(&ctx, 0, sizeof(ctx)); - memset(&t, 0, sizeof(t)); - t.flags = MEM_Null; - t.db = pMem->db; - ctx.pOut = &t; - ctx.pMem = pMem; - ctx.pFunc = pFunc; - pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ - assert( (pMem->flags & MEM_Dyn)==0 ); - if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); - memcpy(pMem, &t, sizeof(t)); - rc = ctx.isError; - } - return rc; -} - -/* -** If the memory cell contains a value that must be freed by -** invoking the external callback in Mem.xDel, then this routine -** will free that value. It also sets Mem.flags to MEM_Null. -** -** This is a helper routine for sqlite3VdbeMemSetNull() and -** for sqlite3VdbeMemRelease(). Use those other routines as the -** entry point for releasing Mem resources. -*/ -static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ - assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); - assert( VdbeMemDynamic(p) ); - if( p->flags&MEM_Agg ){ - sqlite3VdbeMemFinalize(p, p->u.pDef); - assert( (p->flags & MEM_Agg)==0 ); - testcase( p->flags & MEM_Dyn ); - } - if( p->flags&MEM_Dyn ){ - assert( (p->flags&MEM_RowSet)==0 ); - assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); - p->xDel((void *)p->z); - }else if( p->flags&MEM_RowSet ){ - sqlite3RowSetClear(p->u.pRowSet); - }else if( p->flags&MEM_Frame ){ - VdbeFrame *pFrame = p->u.pFrame; - pFrame->pParent = pFrame->v->pDelFrame; - pFrame->v->pDelFrame = pFrame; - } - p->flags = MEM_Null; -} - -/* -** Release memory held by the Mem p, both external memory cleared -** by p->xDel and memory in p->zMalloc. -** -** This is a helper routine invoked by sqlite3VdbeMemRelease() in -** the unusual case where there really is memory in p that needs -** to be freed. -*/ -static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ - if( VdbeMemDynamic(p) ){ - vdbeMemClearExternAndSetNull(p); - } - if( p->szMalloc ){ - sqlite3DbFree(p->db, p->zMalloc); - p->szMalloc = 0; - } - p->z = 0; -} - -/* -** Release any memory resources held by the Mem. Both the memory that is -** free by Mem.xDel and the Mem.zMalloc allocation are freed. -** -** Use this routine prior to clean up prior to abandoning a Mem, or to -** reset a Mem back to its minimum memory utilization. -** -** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space -** prior to inserting new content into the Mem. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ - assert( sqlite3VdbeCheckMemInvariants(p) ); - if( VdbeMemDynamic(p) || p->szMalloc ){ - vdbeMemClear(p); - } -} - -/* -** Convert a 64-bit IEEE double into a 64-bit signed integer. -** If the double is out of range of a 64-bit signed integer then -** return the closest available 64-bit signed integer. -*/ -static i64 doubleToInt64(double r){ -#ifdef SQLITE_OMIT_FLOATING_POINT - /* When floating-point is omitted, double and int64 are the same thing */ - return r; -#else - /* - ** Many compilers we encounter do not define constants for the - ** minimum and maximum 64-bit integers, or they define them - ** inconsistently. And many do not understand the "LL" notation. - ** So we define our own static constants here using nothing - ** larger than a 32-bit integer constant. - */ - static const i64 maxInt = LARGEST_INT64; - static const i64 minInt = SMALLEST_INT64; - - if( r<=(double)minInt ){ - return minInt; - }else if( r>=(double)maxInt ){ - return maxInt; - }else{ - return (i64)r; - } -#endif -} - -/* -** Return some kind of integer value which is the best we can do -** at representing the value that *pMem describes as an integer. -** If pMem is an integer, then the value is exact. If pMem is -** a floating-point then the value returned is the integer part. -** If pMem is a string or blob, then we make an attempt to convert -** it into an integer and return that. If pMem represents an -** an SQL-NULL value, return 0. -** -** If pMem represents a string value, its encoding might be changed. -*/ -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ - int flags; - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - flags = pMem->flags; - if( flags & MEM_Int ){ - return pMem->u.i; - }else if( flags & MEM_Real ){ - return doubleToInt64(pMem->u.r); - }else if( flags & (MEM_Str|MEM_Blob) ){ - i64 value = 0; - assert( pMem->z || pMem->n==0 ); - sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); - return value; - }else{ - return 0; - } -} - -/* -** Return the best representation of pMem that we can get into a -** double. If pMem is already a double or an integer, return its -** value. If it is a string or blob, try to convert it to a double. -** If it is a NULL, return 0.0. -*/ -SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - if( pMem->flags & MEM_Real ){ - return pMem->u.r; - }else if( pMem->flags & MEM_Int ){ - return (double)pMem->u.i; - }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - double val = (double)0; - sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); - return val; - }else{ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - return (double)0; - } -} - -/* -** The MEM structure is already a MEM_Real. Try to also make it a -** MEM_Int if we can. -*/ -SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ - i64 ix; - assert( pMem->flags & MEM_Real ); - assert( (pMem->flags & MEM_RowSet)==0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - ix = doubleToInt64(pMem->u.r); - - /* Only mark the value as an integer if - ** - ** (1) the round-trip conversion real->int->real is a no-op, and - ** (2) The integer is neither the largest nor the smallest - ** possible integer (ticket #3922) - ** - ** The second and third terms in the following conditional enforces - ** the second condition under the assumption that addition overflow causes - ** values to wrap around. - */ - if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; - MemSetTypeFlag(pMem, MEM_Int); - } -} - -/* -** Convert pMem to type integer. Invalidate any prior representations. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - pMem->u.i = sqlite3VdbeIntValue(pMem); - MemSetTypeFlag(pMem, MEM_Int); - return SQLITE_OK; -} - -/* -** Convert pMem so that it is of type MEM_Real. -** Invalidate any prior representations. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - - pMem->u.r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - return SQLITE_OK; -} - -/* -** Convert pMem so that it has types MEM_Real or MEM_Int or both. -** Invalidate any prior representations. -** -** Every effort is made to force the conversion, even if the input -** is a string that does not look completely like a number. Convert -** as much of the string as we can and ignore the rest. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ - if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ - assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - pMem->u.r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - sqlite3VdbeIntegerAffinity(pMem); - } - } - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); - pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); - return SQLITE_OK; -} - -/* -** Cast the datatype of the value in pMem according to the affinity -** "aff". Casting is different from applying affinity in that a cast -** is forced. In other words, the value is converted into the desired -** affinity even if that results in loss of data. This routine is -** used (for example) to implement the SQL "cast()" operator. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ - if( pMem->flags & MEM_Null ) return; - switch( aff ){ - case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */ - if( (pMem->flags & MEM_Blob)==0 ){ - sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); - assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); - if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); - }else{ - pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); - } - break; - } - case SQLITE_AFF_NUMERIC: { - sqlite3VdbeMemNumerify(pMem); - break; - } - case SQLITE_AFF_INTEGER: { - sqlite3VdbeMemIntegerify(pMem); - break; - } - case SQLITE_AFF_REAL: { - sqlite3VdbeMemRealify(pMem); - break; - } - default: { - assert( aff==SQLITE_AFF_TEXT ); - assert( MEM_Str==(MEM_Blob>>3) ); - pMem->flags |= (pMem->flags&MEM_Blob)>>3; - sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); - assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); - pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); - break; - } - } -} - -/* -** Initialize bulk memory to be a consistent Mem object. -** -** The minimum amount of initialization feasible is performed. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ - assert( (flags & ~MEM_TypeMask)==0 ); - pMem->flags = flags; - pMem->db = db; - pMem->szMalloc = 0; -} - - -/* -** Delete any previous value and set the value stored in *pMem to NULL. -** -** This routine calls the Mem.xDel destructor to dispose of values that -** require the destructor. But it preserves the Mem.zMalloc memory allocation. -** To free all resources, use sqlite3VdbeMemRelease(), which both calls this -** routine to invoke the destructor and deallocates Mem.zMalloc. -** -** Use this routine to reset the Mem prior to insert a new value. -** -** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ - if( VdbeMemDynamic(pMem) ){ - vdbeMemClearExternAndSetNull(pMem); - }else{ - pMem->flags = MEM_Null; - } -} -SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ - sqlite3VdbeMemSetNull((Mem*)p); -} - -/* -** Delete any previous value and set the value to be a BLOB of length -** n containing all zeros. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ - sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Blob|MEM_Zero; - pMem->n = 0; - if( n<0 ) n = 0; - pMem->u.nZero = n; - pMem->enc = SQLITE_UTF8; - pMem->z = 0; -} - -/* -** The pMem is known to contain content that needs to be destroyed prior -** to a value change. So invoke the destructor, then set the value to -** a 64-bit integer. -*/ -static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ - sqlite3VdbeMemSetNull(pMem); - pMem->u.i = val; - pMem->flags = MEM_Int; -} - -/* -** Delete any previous value and set the value stored in *pMem to val, -** manifest type INTEGER. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ - if( VdbeMemDynamic(pMem) ){ - vdbeReleaseAndSetInt64(pMem, val); - }else{ - pMem->u.i = val; - pMem->flags = MEM_Int; - } -} - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** Delete any previous value and set the value stored in *pMem to val, -** manifest type REAL. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ - sqlite3VdbeMemSetNull(pMem); - if( !sqlite3IsNaN(val) ){ - pMem->u.r = val; - pMem->flags = MEM_Real; - } -} -#endif - -/* -** Delete any previous value and set the value of pMem to be an -** empty boolean index. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ - sqlite3 *db = pMem->db; - assert( db!=0 ); - assert( (pMem->flags & MEM_RowSet)==0 ); - sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); - if( db->mallocFailed ){ - pMem->flags = MEM_Null; - pMem->szMalloc = 0; - }else{ - assert( pMem->zMalloc ); - pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); - assert( pMem->u.pRowSet!=0 ); - pMem->flags = MEM_RowSet; - } -} - -/* -** Return true if the Mem object contains a TEXT or BLOB that is -** too large - whose size exceeds SQLITE_MAX_LENGTH. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ - assert( p->db!=0 ); - if( p->flags & (MEM_Str|MEM_Blob) ){ - int n = p->n; - if( p->flags & MEM_Zero ){ - n += p->u.nZero; - } - return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; - } - return 0; -} - -#ifdef SQLITE_DEBUG -/* -** This routine prepares a memory cell for modification by breaking -** its link to a shallow copy and by marking any current shallow -** copies of this cell as invalid. -** -** This is used for testing and debugging only - to make sure shallow -** copies are not misused. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ - int i; - Mem *pX; - for(i=0, pX=pVdbe->aMem; inMem; i++, pX++){ - if( pX->pScopyFrom==pMem ){ - pX->flags |= MEM_Undefined; - pX->pScopyFrom = 0; - } - } - pMem->pScopyFrom = 0; -} -#endif /* SQLITE_DEBUG */ - - -/* -** Make an shallow copy of pFrom into pTo. Prior contents of -** pTo are freed. The pFrom->z field is not duplicated. If -** pFrom->z is used, then pTo->z points to the same thing as pFrom->z -** and flags gets srcType (either MEM_Ephem or MEM_Static). -*/ -static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ - vdbeMemClearExternAndSetNull(pTo); - assert( !VdbeMemDynamic(pTo) ); - sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); -} -SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ - assert( (pFrom->flags & MEM_RowSet)==0 ); - assert( pTo->db==pFrom->db ); - if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } - memcpy(pTo, pFrom, MEMCELLSIZE); - if( (pFrom->flags&MEM_Static)==0 ){ - pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); - assert( srcType==MEM_Ephem || srcType==MEM_Static ); - pTo->flags |= srcType; - } -} - -/* -** Make a full copy of pFrom into pTo. Prior contents of pTo are -** freed before the copy is made. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ - int rc = SQLITE_OK; - - assert( (pFrom->flags & MEM_RowSet)==0 ); - if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); - memcpy(pTo, pFrom, MEMCELLSIZE); - pTo->flags &= ~MEM_Dyn; - if( pTo->flags&(MEM_Str|MEM_Blob) ){ - if( 0==(pFrom->flags&MEM_Static) ){ - pTo->flags |= MEM_Ephem; - rc = sqlite3VdbeMemMakeWriteable(pTo); - } - } - - return rc; -} - -/* -** Transfer the contents of pFrom to pTo. Any existing value in pTo is -** freed. If pFrom contains ephemeral data, a copy is made. -** -** pFrom contains an SQL NULL when this routine returns. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ - assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); - assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); - assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); - - sqlite3VdbeMemRelease(pTo); - memcpy(pTo, pFrom, sizeof(Mem)); - pFrom->flags = MEM_Null; - pFrom->szMalloc = 0; -} - -/* -** Change the value of a Mem to be a string or a BLOB. -** -** The memory management strategy depends on the value of the xDel -** parameter. If the value passed is SQLITE_TRANSIENT, then the -** string is copied into a (possibly existing) buffer managed by the -** Mem structure. Otherwise, any existing buffer is freed and the -** pointer copied. -** -** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH -** size limit) then no memory allocation occurs. If the string can be -** stored without allocating memory, then it is. If a memory allocation -** is required to store the string, then value of pMem is unchanged. In -** either case, SQLITE_TOOBIG is returned. -*/ -SQLITE_PRIVATE int sqlite3VdbeMemSetStr( - Mem *pMem, /* Memory cell to set to string value */ - const char *z, /* String pointer */ - int n, /* Bytes in string, or negative */ - u8 enc, /* Encoding of z. 0 for BLOBs */ - void (*xDel)(void*) /* Destructor function */ -){ - int nByte = n; /* New value for pMem->n */ - int iLimit; /* Maximum allowed string or blob size */ - u16 flags = 0; /* New value for pMem->flags */ - - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); - - /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ - if( !z ){ - sqlite3VdbeMemSetNull(pMem); - return SQLITE_OK; - } - - if( pMem->db ){ - iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH]; - }else{ - iLimit = SQLITE_MAX_LENGTH; - } - flags = (enc==0?MEM_Blob:MEM_Str); - if( nByte<0 ){ - assert( enc!=0 ); - if( enc==SQLITE_UTF8 ){ - nByte = sqlite3Strlen30(z); - if( nByte>iLimit ) nByte = iLimit+1; - }else{ - for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} - } - flags |= MEM_Term; - } - - /* The following block sets the new values of Mem.z and Mem.xDel. It - ** also sets a flag in local variable "flags" to indicate the memory - ** management (one of MEM_Dyn or MEM_Static). - */ - if( xDel==SQLITE_TRANSIENT ){ - int nAlloc = nByte; - if( flags&MEM_Term ){ - nAlloc += (enc==SQLITE_UTF8?1:2); - } - if( nByte>iLimit ){ - return SQLITE_TOOBIG; - } - testcase( nAlloc==0 ); - testcase( nAlloc==31 ); - testcase( nAlloc==32 ); - if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){ - return SQLITE_NOMEM_BKPT; - } - memcpy(pMem->z, z, nAlloc); - }else if( xDel==SQLITE_DYNAMIC ){ - sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = pMem->z = (char *)z; - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); - }else{ - sqlite3VdbeMemRelease(pMem); - pMem->z = (char *)z; - pMem->xDel = xDel; - flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); - } - - pMem->n = nByte; - pMem->flags = flags; - pMem->enc = (enc==0 ? SQLITE_UTF8 : enc); - -#ifndef SQLITE_OMIT_UTF16 - if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ - return SQLITE_NOMEM_BKPT; - } -#endif - - if( nByte>iLimit ){ - return SQLITE_TOOBIG; - } - - return SQLITE_OK; -} - -/* -** Move data out of a btree key or data field and into a Mem structure. -** The data or key is taken from the entry that pCur is currently pointing -** to. offset and amt determine what portion of the data or key to retrieve. -** key is true to get the key or false to get data. The result is written -** into the pMem element. -** -** The pMem object must have been initialized. This routine will use -** pMem->zMalloc to hold the content from the btree, if possible. New -** pMem->zMalloc space will be allocated if necessary. The calling routine -** is responsible for making sure that the pMem object is eventually -** destroyed. -** -** If this routine fails for any reason (malloc returns NULL or unable -** to read from the disk) then the pMem is left in an inconsistent state. -*/ -static SQLITE_NOINLINE int vdbeMemFromBtreeResize( - BtCursor *pCur, /* Cursor pointing at record to retrieve. */ - u32 offset, /* Offset from the start of data to return bytes from. */ - u32 amt, /* Number of bytes to return. */ - int key, /* If true, retrieve from the btree key, not data. */ - Mem *pMem /* OUT: Return data in this Mem structure. */ -){ - int rc; - pMem->flags = MEM_Null; - if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ - if( key ){ - rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); - }else{ - rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); - } - if( rc==SQLITE_OK ){ - pMem->z[amt] = 0; - pMem->z[amt+1] = 0; - pMem->flags = MEM_Blob|MEM_Term; - pMem->n = (int)amt; - }else{ - sqlite3VdbeMemRelease(pMem); - } - } - return rc; -} -SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( - BtCursor *pCur, /* Cursor pointing at record to retrieve. */ - u32 offset, /* Offset from the start of data to return bytes from. */ - u32 amt, /* Number of bytes to return. */ - int key, /* If true, retrieve from the btree key, not data. */ - Mem *pMem /* OUT: Return data in this Mem structure. */ -){ - char *zData; /* Data from the btree layer */ - u32 available = 0; /* Number of bytes available on the local btree page */ - int rc = SQLITE_OK; /* Return code */ - - assert( sqlite3BtreeCursorIsValid(pCur) ); - assert( !VdbeMemDynamic(pMem) ); - - /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() - ** that both the BtShared and database handle mutexes are held. */ - assert( (pMem->flags & MEM_RowSet)==0 ); - zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); - assert( zData!=0 ); - - if( offset+amt<=available ){ - pMem->z = &zData[offset]; - pMem->flags = MEM_Blob|MEM_Ephem; - pMem->n = (int)amt; - }else{ - rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem); - } - - return rc; -} - -/* -** The pVal argument is known to be a value other than NULL. -** Convert it into a string with encoding enc and return a pointer -** to a zero-terminated version of that string. -*/ -static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ - assert( pVal!=0 ); - assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); - assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); - assert( (pVal->flags & (MEM_Null))==0 ); - if( pVal->flags & (MEM_Blob|MEM_Str) ){ - pVal->flags |= MEM_Str; - if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ - sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); - } - if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ - assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); - if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ - return 0; - } - } - sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ - }else{ - sqlite3VdbeMemStringify(pVal, enc, 0); - assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); - } - assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 - || pVal->db->mallocFailed ); - if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ - return pVal->z; - }else{ - return 0; - } -} - -/* This function is only available internally, it is not part of the -** external API. It works in a similar way to sqlite3_value_text(), -** except the data returned is in the encoding specified by the second -** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or -** SQLITE_UTF8. -** -** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. -** If that is the case, then the result must be aligned on an even byte -** boundary. -*/ -SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ - if( !pVal ) return 0; - assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); - assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); - if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ - return pVal->z; - } - if( pVal->flags&MEM_Null ){ - return 0; - } - return valueToText(pVal, enc); -} - -/* -** Create a new sqlite3_value object. -*/ -SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){ - Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); - if( p ){ - p->flags = MEM_Null; - p->db = db; - } - return p; -} - -/* -** Context object passed by sqlite3Stat4ProbeSetValue() through to -** valueNew(). See comments above valueNew() for details. -*/ -struct ValueNewStat4Ctx { - Parse *pParse; - Index *pIdx; - UnpackedRecord **ppRec; - int iVal; -}; - -/* -** Allocate and return a pointer to a new sqlite3_value object. If -** the second argument to this function is NULL, the object is allocated -** by calling sqlite3ValueNew(). -** -** Otherwise, if the second argument is non-zero, then this function is -** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not -** already been allocated, allocate the UnpackedRecord structure that -** that function will return to its caller here. Then return a pointer to -** an sqlite3_value within the UnpackedRecord.a[] array. -*/ -static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( p ){ - UnpackedRecord *pRec = p->ppRec[0]; - - if( pRec==0 ){ - Index *pIdx = p->pIdx; /* Index being probed */ - int nByte; /* Bytes of space to allocate */ - int i; /* Counter variable */ - int nCol = pIdx->nColumn; /* Number of index columns including rowid */ - - nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); - pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); - if( pRec ){ - pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); - if( pRec->pKeyInfo ){ - assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); - assert( pRec->pKeyInfo->enc==ENC(db) ); - pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); - for(i=0; iaMem[i].flags = MEM_Null; - pRec->aMem[i].db = db; - } - }else{ - sqlite3DbFree(db, pRec); - pRec = 0; - } - } - if( pRec==0 ) return 0; - p->ppRec[0] = pRec; - } - - pRec->nField = p->iVal+1; - return &pRec->aMem[p->iVal]; - } -#else - UNUSED_PARAMETER(p); -#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */ - return sqlite3ValueNew(db); -} - -/* -** The expression object indicated by the second argument is guaranteed -** to be a scalar SQL function. If -** -** * all function arguments are SQL literals, -** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and -** * the SQLITE_FUNC_NEEDCOLL function flag is not set, -** -** then this routine attempts to invoke the SQL function. Assuming no -** error occurs, output parameter (*ppVal) is set to point to a value -** object containing the result before returning SQLITE_OK. -** -** Affinity aff is applied to the result of the function before returning. -** If the result is a text value, the sqlite3_value object uses encoding -** enc. -** -** If the conditions above are not met, this function returns SQLITE_OK -** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to -** NULL and an SQLite error code returned. -*/ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -static int valueFromFunction( - sqlite3 *db, /* The database connection */ - Expr *p, /* The expression to evaluate */ - u8 enc, /* Encoding to use */ - u8 aff, /* Affinity to use */ - sqlite3_value **ppVal, /* Write the new value here */ - struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ -){ - sqlite3_context ctx; /* Context object for function invocation */ - sqlite3_value **apVal = 0; /* Function arguments */ - int nVal = 0; /* Size of apVal[] array */ - FuncDef *pFunc = 0; /* Function definition */ - sqlite3_value *pVal = 0; /* New value */ - int rc = SQLITE_OK; /* Return code */ - ExprList *pList = 0; /* Function arguments */ - int i; /* Iterator variable */ - - assert( pCtx!=0 ); - assert( (p->flags & EP_TokenOnly)==0 ); - pList = p->x.pList; - if( pList ) nVal = pList->nExpr; - pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); - assert( pFunc ); - if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 - || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) - ){ - return SQLITE_OK; - } - - if( pList ){ - apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); - if( apVal==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto value_from_function_out; - } - for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); - if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; - } - } - - pVal = valueNew(db, pCtx); - if( pVal==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto value_from_function_out; - } - - assert( pCtx->pParse->rc==SQLITE_OK ); - memset(&ctx, 0, sizeof(ctx)); - ctx.pOut = pVal; - ctx.pFunc = pFunc; - pFunc->xSFunc(&ctx, nVal, apVal); - if( ctx.isError ){ - rc = ctx.isError; - sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); - }else{ - sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); - assert( rc==SQLITE_OK ); - rc = sqlite3VdbeChangeEncoding(pVal, enc); - if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ - rc = SQLITE_TOOBIG; - pCtx->pParse->nErr++; - } - } - pCtx->pParse->rc = rc; - - value_from_function_out: - if( rc!=SQLITE_OK ){ - pVal = 0; - } - if( apVal ){ - for(i=0; iop)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; - if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; - - /* Compressed expressions only appear when parsing the DEFAULT clause - ** on a table column definition, and hence only when pCtx==0. This - ** check ensures that an EP_TokenOnly expression is never passed down - ** into valueFromFunction(). */ - assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); - - if( op==TK_CAST ){ - u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); - rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); - testcase( rc!=SQLITE_OK ); - if( *ppVal ){ - sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); - sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); - } - return rc; - } - - /* Handle negative integers in a single step. This is needed in the - ** case when the value is -9223372036854775808. - */ - if( op==TK_UMINUS - && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ - pExpr = pExpr->pLeft; - op = pExpr->op; - negInt = -1; - zNeg = "-"; - } - - if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ - pVal = valueNew(db, pCtx); - if( pVal==0 ) goto no_mem; - if( ExprHasProperty(pExpr, EP_IntValue) ){ - sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); - }else{ - zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); - if( zVal==0 ) goto no_mem; - sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); - } - if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ - sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); - }else{ - sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); - } - if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; - if( enc!=SQLITE_UTF8 ){ - rc = sqlite3VdbeChangeEncoding(pVal, enc); - } - }else if( op==TK_UMINUS ) { - /* This branch happens for multiple negative signs. Ex: -(-5) */ - if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) - && pVal!=0 - ){ - sqlite3VdbeMemNumerify(pVal); - if( pVal->flags & MEM_Real ){ - pVal->u.r = -pVal->u.r; - }else if( pVal->u.i==SMALLEST_INT64 ){ - pVal->u.r = -(double)SMALLEST_INT64; - MemSetTypeFlag(pVal, MEM_Real); - }else{ - pVal->u.i = -pVal->u.i; - } - sqlite3ValueApplyAffinity(pVal, affinity, enc); - } - }else if( op==TK_NULL ){ - pVal = valueNew(db, pCtx); - if( pVal==0 ) goto no_mem; - } -#ifndef SQLITE_OMIT_BLOB_LITERAL - else if( op==TK_BLOB ){ - int nVal; - assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); - assert( pExpr->u.zToken[1]=='\'' ); - pVal = valueNew(db, pCtx); - if( !pVal ) goto no_mem; - zVal = &pExpr->u.zToken[2]; - nVal = sqlite3Strlen30(zVal)-1; - assert( zVal[nVal]=='\'' ); - sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, - 0, SQLITE_DYNAMIC); - } -#endif - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - else if( op==TK_FUNCTION && pCtx!=0 ){ - rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); - } -#endif - - *ppVal = pVal; - return rc; - -no_mem: - sqlite3OomFault(db); - sqlite3DbFree(db, zVal); - assert( *ppVal==0 ); -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( pCtx==0 ) sqlite3ValueFree(pVal); -#else - assert( pCtx==0 ); sqlite3ValueFree(pVal); -#endif - return SQLITE_NOMEM_BKPT; -} - -/* -** Create a new sqlite3_value object, containing the value of pExpr. -** -** This only works for very simple expressions that consist of one constant -** token (i.e. "5", "5.1", "'a string'"). If the expression can -** be converted directly into a value, then the value is allocated and -** a pointer written to *ppVal. The caller is responsible for deallocating -** the value by passing it to sqlite3ValueFree() later on. If the expression -** cannot be converted to a value, then *ppVal is set to NULL. -*/ -SQLITE_PRIVATE int sqlite3ValueFromExpr( - sqlite3 *db, /* The database connection */ - Expr *pExpr, /* The expression to evaluate */ - u8 enc, /* Encoding to use */ - u8 affinity, /* Affinity to use */ - sqlite3_value **ppVal /* Write the new value here */ -){ - return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; -} - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** The implementation of the sqlite_record() function. This function accepts -** a single argument of any type. The return value is a formatted database -** record (a blob) containing the argument value. -** -** This is used to convert the value stored in the 'sample' column of the -** sqlite_stat3 table to the record format SQLite uses internally. -*/ -static void recordFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const int file_format = 1; - u32 iSerial; /* Serial type */ - int nSerial; /* Bytes of space for iSerial as varint */ - u32 nVal; /* Bytes of space required for argv[0] */ - int nRet; - sqlite3 *db; - u8 *aRet; - - UNUSED_PARAMETER( argc ); - iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal); - nSerial = sqlite3VarintLen(iSerial); - db = sqlite3_context_db_handle(context); - - nRet = 1 + nSerial + nVal; - aRet = sqlite3DbMallocRawNN(db, nRet); - if( aRet==0 ){ - sqlite3_result_error_nomem(context); - }else{ - aRet[0] = nSerial+1; - putVarint32(&aRet[1], iSerial); - sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); - sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); - sqlite3DbFree(db, aRet); - } -} - -/* -** Register built-in functions used to help read ANALYZE data. -*/ -SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ - static FuncDef aAnalyzeTableFuncs[] = { - FUNCTION(sqlite_record, 1, 0, 0, recordFunc), - }; - sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs)); -} - -/* -** Attempt to extract a value from pExpr and use it to construct *ppVal. -** -** If pAlloc is not NULL, then an UnpackedRecord object is created for -** pAlloc if one does not exist and the new value is added to the -** UnpackedRecord object. -** -** A value is extracted in the following cases: -** -** * (pExpr==0). In this case the value is assumed to be an SQL NULL, -** -** * The expression is a bound variable, and this is a reprepare, or -** -** * The expression is a literal value. -** -** On success, *ppVal is made to point to the extracted value. The caller -** is responsible for ensuring that the value is eventually freed. -*/ -static int stat4ValueFromExpr( - Parse *pParse, /* Parse context */ - Expr *pExpr, /* The expression to extract a value from */ - u8 affinity, /* Affinity to use */ - struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */ - sqlite3_value **ppVal /* OUT: New value object (or NULL) */ -){ - int rc = SQLITE_OK; - sqlite3_value *pVal = 0; - sqlite3 *db = pParse->db; - - /* Skip over any TK_COLLATE nodes */ - pExpr = sqlite3ExprSkipCollate(pExpr); - - if( !pExpr ){ - pVal = valueNew(db, pAlloc); - if( pVal ){ - sqlite3VdbeMemSetNull((Mem*)pVal); - } - }else if( pExpr->op==TK_VARIABLE - || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) - ){ - Vdbe *v; - int iBindVar = pExpr->iColumn; - sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); - if( (v = pParse->pReprepare)!=0 ){ - pVal = valueNew(db, pAlloc); - if( pVal ){ - rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); - if( rc==SQLITE_OK ){ - sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); - } - pVal->db = pParse->db; - } - } - }else{ - rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc); - } - - assert( pVal==0 || pVal->db==db ); - *ppVal = pVal; - return rc; -} - -/* -** This function is used to allocate and populate UnpackedRecord -** structures intended to be compared against sample index keys stored -** in the sqlite_stat4 table. -** -** A single call to this function populates zero or more fields of the -** record starting with field iVal (fields are numbered from left to -** right starting with 0). A single field is populated if: -** -** * (pExpr==0). In this case the value is assumed to be an SQL NULL, -** -** * The expression is a bound variable, and this is a reprepare, or -** -** * The sqlite3ValueFromExpr() function is able to extract a value -** from the expression (i.e. the expression is a literal value). -** -** Or, if pExpr is a TK_VECTOR, one field is populated for each of the -** vector components that match either of the two latter criteria listed -** above. -** -** Before any value is appended to the record, the affinity of the -** corresponding column within index pIdx is applied to it. Before -** this function returns, output parameter *pnExtract is set to the -** number of values appended to the record. -** -** When this function is called, *ppRec must either point to an object -** allocated by an earlier call to this function, or must be NULL. If it -** is NULL and a value can be successfully extracted, a new UnpackedRecord -** is allocated (and *ppRec set to point to it) before returning. -** -** Unless an error is encountered, SQLITE_OK is returned. It is not an -** error if a value cannot be extracted from pExpr. If an error does -** occur, an SQLite error code is returned. -*/ -SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( - Parse *pParse, /* Parse context */ - Index *pIdx, /* Index being probed */ - UnpackedRecord **ppRec, /* IN/OUT: Probe record */ - Expr *pExpr, /* The expression to extract a value from */ - int nElem, /* Maximum number of values to append */ - int iVal, /* Array element to populate */ - int *pnExtract /* OUT: Values appended to the record */ -){ - int rc = SQLITE_OK; - int nExtract = 0; - - if( pExpr==0 || pExpr->op!=TK_SELECT ){ - int i; - struct ValueNewStat4Ctx alloc; - - alloc.pParse = pParse; - alloc.pIdx = pIdx; - alloc.ppRec = ppRec; - - for(i=0; idb, pIdx, iVal+i); - alloc.iVal = iVal+i; - rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); - if( !pVal ) break; - nExtract++; - } - } - - *pnExtract = nExtract; - return rc; -} - -/* -** Attempt to extract a value from expression pExpr using the methods -** as described for sqlite3Stat4ProbeSetValue() above. -** -** If successful, set *ppVal to point to a new value object and return -** SQLITE_OK. If no value can be extracted, but no other error occurs -** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error -** does occur, return an SQLite error code. The final value of *ppVal -** is undefined in this case. -*/ -SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( - Parse *pParse, /* Parse context */ - Expr *pExpr, /* The expression to extract a value from */ - u8 affinity, /* Affinity to use */ - sqlite3_value **ppVal /* OUT: New value object (or NULL) */ -){ - return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal); -} - -/* -** Extract the iCol-th column from the nRec-byte record in pRec. Write -** the column value into *ppVal. If *ppVal is initially NULL then a new -** sqlite3_value object is allocated. -** -** If *ppVal is initially NULL then the caller is responsible for -** ensuring that the value written into *ppVal is eventually freed. -*/ -SQLITE_PRIVATE int sqlite3Stat4Column( - sqlite3 *db, /* Database handle */ - const void *pRec, /* Pointer to buffer containing record */ - int nRec, /* Size of buffer pRec in bytes */ - int iCol, /* Column to extract */ - sqlite3_value **ppVal /* OUT: Extracted value */ -){ - u32 t; /* a column type code */ - int nHdr; /* Size of the header in the record */ - int iHdr; /* Next unread header byte */ - int iField; /* Next unread data byte */ - int szField; /* Size of the current data field */ - int i; /* Column index */ - u8 *a = (u8*)pRec; /* Typecast byte array */ - Mem *pMem = *ppVal; /* Write result into this Mem object */ - - assert( iCol>0 ); - iHdr = getVarint32(a, nHdr); - if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; - iField = nHdr; - for(i=0; i<=iCol; i++){ - iHdr += getVarint32(&a[iHdr], t); - testcase( iHdr==nHdr ); - testcase( iHdr==nHdr+1 ); - if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT; - szField = sqlite3VdbeSerialTypeLen(t); - iField += szField; - } - testcase( iField==nRec ); - testcase( iField==nRec+1 ); - if( iField>nRec ) return SQLITE_CORRUPT_BKPT; - if( pMem==0 ){ - pMem = *ppVal = sqlite3ValueNew(db); - if( pMem==0 ) return SQLITE_NOMEM_BKPT; - } - sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); - pMem->enc = ENC(db); - return SQLITE_OK; -} - -/* -** Unless it is NULL, the argument must be an UnpackedRecord object returned -** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes -** the object. -*/ -SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ - if( pRec ){ - int i; - int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField; - Mem *aMem = pRec->aMem; - sqlite3 *db = aMem[0].db; - for(i=0; ipKeyInfo); - sqlite3DbFree(db, pRec); - } -} -#endif /* ifdef SQLITE_ENABLE_STAT4 */ - -/* -** Change the string value of an sqlite3_value object -*/ -SQLITE_PRIVATE void sqlite3ValueSetStr( - sqlite3_value *v, /* Value to be set */ - int n, /* Length of string z */ - const void *z, /* Text of the new string */ - u8 enc, /* Encoding to use */ - void (*xDel)(void*) /* Destructor for the string */ -){ - if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); -} - -/* -** Free an sqlite3_value object -*/ -SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ - if( !v ) return; - sqlite3VdbeMemRelease((Mem *)v); - sqlite3DbFree(((Mem*)v)->db, v); -} - -/* -** The sqlite3ValueBytes() routine returns the number of bytes in the -** sqlite3_value object assuming that it uses the encoding "enc". -** The valueBytes() routine is a helper function. -*/ -static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){ - return valueToText(pVal, enc)!=0 ? pVal->n : 0; -} -SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ - Mem *p = (Mem*)pVal; - assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); - if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ - return p->n; - } - if( (p->flags & MEM_Blob)!=0 ){ - if( p->flags & MEM_Zero ){ - return p->n + p->u.nZero; - }else{ - return p->n; - } - } - if( p->flags & MEM_Null ) return 0; - return valueBytes(pVal, enc); -} - -/************** End of vdbemem.c *********************************************/ -/************** Begin file vdbeaux.c *****************************************/ -/* -** 2003 September 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used for creating, destroying, and populating -** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -/* -** Create a new virtual database engine. -*/ -SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ - sqlite3 *db = pParse->db; - Vdbe *p; - p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); - if( p==0 ) return 0; - memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); - p->db = db; - if( db->pVdbe ){ - db->pVdbe->pPrev = p; - } - p->pNext = db->pVdbe; - p->pPrev = 0; - db->pVdbe = p; - p->magic = VDBE_MAGIC_INIT; - p->pParse = pParse; - assert( pParse->aLabel==0 ); - assert( pParse->nLabel==0 ); - assert( pParse->nOpAlloc==0 ); - assert( pParse->szOpAlloc==0 ); - return p; -} - -/* -** Change the error string stored in Vdbe.zErrMsg -*/ -SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ - va_list ap; - sqlite3DbFree(p->db, p->zErrMsg); - va_start(ap, zFormat); - p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap); - va_end(ap); -} - -/* -** Remember the SQL string for a prepared statement. -*/ -SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){ - assert( isPrepareV2==1 || isPrepareV2==0 ); - if( p==0 ) return; -#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG) - if( !isPrepareV2 ) return; -#endif - assert( p->zSql==0 ); - p->zSql = sqlite3DbStrNDup(p->db, z, n); - p->isPrepareV2 = (u8)isPrepareV2; -} - -/* -** Swap all content between two VDBE structures. -*/ -SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ - Vdbe tmp, *pTmp; - char *zTmp; - assert( pA->db==pB->db ); - tmp = *pA; - *pA = *pB; - *pB = tmp; - pTmp = pA->pNext; - pA->pNext = pB->pNext; - pB->pNext = pTmp; - pTmp = pA->pPrev; - pA->pPrev = pB->pPrev; - pB->pPrev = pTmp; - zTmp = pA->zSql; - pA->zSql = pB->zSql; - pB->zSql = zTmp; - pB->isPrepareV2 = pA->isPrepareV2; -} - -/* -** Resize the Vdbe.aOp array so that it is at least nOp elements larger -** than its current size. nOp is guaranteed to be less than or equal -** to 1024/sizeof(Op). -** -** If an out-of-memory error occurs while resizing the array, return -** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain -** unchanged (this is so that any opcodes already allocated can be -** correctly deallocated along with the rest of the Vdbe). -*/ -static int growOpArray(Vdbe *v, int nOp){ - VdbeOp *pNew; - Parse *p = v->pParse; - - /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force - ** more frequent reallocs and hence provide more opportunities for - ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used - ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array - ** by the minimum* amount required until the size reaches 512. Normal - ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current - ** size of the op array or add 1KB of space, whichever is smaller. */ -#ifdef SQLITE_TEST_REALLOC_STRESS - int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp); -#else - int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); - UNUSED_PARAMETER(nOp); -#endif - - assert( nOp<=(1024/sizeof(Op)) ); - assert( nNew>=(p->nOpAlloc+nOp) ); - pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); - if( pNew ){ - p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); - p->nOpAlloc = p->szOpAlloc/sizeof(Op); - v->aOp = pNew; - } - return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); -} - -#ifdef SQLITE_DEBUG -/* This routine is just a convenient place to set a breakpoint that will -** fire after each opcode is inserted and displayed using -** "PRAGMA vdbe_addoptrace=on". -*/ -static void test_addop_breakpoint(void){ - static int n = 0; - n++; -} -#endif - -/* -** Add a new instruction to the list of instructions current in the -** VDBE. Return the address of the new instruction. -** -** Parameters: -** -** p Pointer to the VDBE -** -** op The opcode for this instruction -** -** p1, p2, p3 Operands -** -** Use the sqlite3VdbeResolveLabel() function to fix an address and -** the sqlite3VdbeChangeP4() function to change the value of the P4 -** operand. -*/ -static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ - assert( p->pParse->nOpAlloc<=p->nOp ); - if( growOpArray(p, 1) ) return 1; - assert( p->pParse->nOpAlloc>p->nOp ); - return sqlite3VdbeAddOp3(p, op, p1, p2, p3); -} -SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ - int i; - VdbeOp *pOp; - - i = p->nOp; - assert( p->magic==VDBE_MAGIC_INIT ); - assert( op>=0 && op<0xff ); - if( p->pParse->nOpAlloc<=i ){ - return growOp3(p, op, p1, p2, p3); - } - p->nOp++; - pOp = &p->aOp[i]; - pOp->opcode = (u8)op; - pOp->p5 = 0; - pOp->p1 = p1; - pOp->p2 = p2; - pOp->p3 = p3; - pOp->p4.p = 0; - pOp->p4type = P4_NOTUSED; -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - pOp->zComment = 0; -#endif -#ifdef SQLITE_DEBUG - if( p->db->flags & SQLITE_VdbeAddopTrace ){ - int jj, kk; - Parse *pParse = p->pParse; - for(jj=kk=0; jjnColCache; jj++){ - struct yColCache *x = pParse->aColCache + jj; - printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); - kk++; - } - if( kk ) printf("\n"); - sqlite3VdbePrintOp(0, i, &p->aOp[i]); - test_addop_breakpoint(); - } -#endif -#ifdef VDBE_PROFILE - pOp->cycles = 0; - pOp->cnt = 0; -#endif -#ifdef SQLITE_VDBE_COVERAGE - pOp->iSrcLine = 0; -#endif - return i; -} -SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ - return sqlite3VdbeAddOp3(p, op, 0, 0, 0); -} -SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ - return sqlite3VdbeAddOp3(p, op, p1, 0, 0); -} -SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ - return sqlite3VdbeAddOp3(p, op, p1, p2, 0); -} - -/* Generate code for an unconditional jump to instruction iDest -*/ -SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ - return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); -} - -/* Generate code to cause the string zStr to be loaded into -** register iDest -*/ -SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ - return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); -} - -/* -** Generate code that initializes multiple registers to string or integer -** constants. The registers begin with iDest and increase consecutively. -** One register is initialized for each characgter in zTypes[]. For each -** "s" character in zTypes[], the register is a string if the argument is -** not NULL, or OP_Null if the value is a null pointer. For each "i" character -** in zTypes[], the register is initialized to an integer. -*/ -SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ - va_list ap; - int i; - char c; - va_start(ap, zTypes); - for(i=0; (c = zTypes[i])!=0; i++){ - if( c=='s' ){ - const char *z = va_arg(ap, const char*); - sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest++, 0, z, 0); - }else{ - assert( c=='i' ); - sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest++); - } - } - va_end(ap); -} - -/* -** Add an opcode that includes the p4 value as a pointer. -*/ -SQLITE_PRIVATE int sqlite3VdbeAddOp4( - Vdbe *p, /* Add the opcode to this VM */ - int op, /* The new opcode */ - int p1, /* The P1 operand */ - int p2, /* The P2 operand */ - int p3, /* The P3 operand */ - const char *zP4, /* The P4 operand */ - int p4type /* P4 operand type */ -){ - int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); - sqlite3VdbeChangeP4(p, addr, zP4, p4type); - return addr; -} - -/* -** Add an opcode that includes the p4 value with a P4_INT64 or -** P4_REAL type. -*/ -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( - Vdbe *p, /* Add the opcode to this VM */ - int op, /* The new opcode */ - int p1, /* The P1 operand */ - int p2, /* The P2 operand */ - int p3, /* The P3 operand */ - const u8 *zP4, /* The P4 operand */ - int p4type /* P4 operand type */ -){ - char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); - if( p4copy ) memcpy(p4copy, zP4, 8); - return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); -} - -/* -** Add an OP_ParseSchema opcode. This routine is broken out from -** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees -** as having been used. -** -** The zWhere string must have been obtained from sqlite3_malloc(). -** This routine will take ownership of the allocated memory. -*/ -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ - int j; - sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); - for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); -} - -/* -** Add an opcode that includes the p4 value as an integer. -*/ -SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( - Vdbe *p, /* Add the opcode to this VM */ - int op, /* The new opcode */ - int p1, /* The P1 operand */ - int p2, /* The P2 operand */ - int p3, /* The P3 operand */ - int p4 /* The P4 operand as an integer */ -){ - int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); - sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32); - return addr; -} - -/* Insert the end of a co-routine -*/ -SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); - - /* Clear the temporary register cache, thereby ensuring that each - ** co-routine has its own independent set of registers, because co-routines - ** might expect their registers to be preserved across an OP_Yield, and - ** that could cause problems if two or more co-routines are using the same - ** temporary register. - */ - v->pParse->nTempReg = 0; - v->pParse->nRangeReg = 0; -} - -/* -** Create a new symbolic label for an instruction that has yet to be -** coded. The symbolic label is really just a negative number. The -** label can be used as the P2 value of an operation. Later, when -** the label is resolved to a specific address, the VDBE will scan -** through its operation list and change all values of P2 which match -** the label into the resolved address. -** -** The VDBE knows that a P2 value is a label because labels are -** always negative and P2 values are suppose to be non-negative. -** Hence, a negative P2 value is a label that has yet to be resolved. -** -** Zero is returned if a malloc() fails. -*/ -SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){ - Parse *p = v->pParse; - int i = p->nLabel++; - assert( v->magic==VDBE_MAGIC_INIT ); - if( (i & (i-1))==0 ){ - p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, - (i*2+1)*sizeof(p->aLabel[0])); - } - if( p->aLabel ){ - p->aLabel[i] = -1; - } - return ADDR(i); -} - -/* -** Resolve label "x" to be the address of the next instruction to -** be inserted. The parameter "x" must have been obtained from -** a prior call to sqlite3VdbeMakeLabel(). -*/ -SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ - Parse *p = v->pParse; - int j = ADDR(x); - assert( v->magic==VDBE_MAGIC_INIT ); - assert( jnLabel ); - assert( j>=0 ); - if( p->aLabel ){ - p->aLabel[j] = v->nOp; - } -} - -/* -** Mark the VDBE as one that can only be run one time. -*/ -SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ - p->runOnlyOnce = 1; -} - -/* -** Mark the VDBE as one that can only be run multiple times. -*/ -SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){ - p->runOnlyOnce = 0; -} - -#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ - -/* -** The following type and function are used to iterate through all opcodes -** in a Vdbe main program and each of the sub-programs (triggers) it may -** invoke directly or indirectly. It should be used as follows: -** -** Op *pOp; -** VdbeOpIter sIter; -** -** memset(&sIter, 0, sizeof(sIter)); -** sIter.v = v; // v is of type Vdbe* -** while( (pOp = opIterNext(&sIter)) ){ -** // Do something with pOp -** } -** sqlite3DbFree(v->db, sIter.apSub); -** -*/ -typedef struct VdbeOpIter VdbeOpIter; -struct VdbeOpIter { - Vdbe *v; /* Vdbe to iterate through the opcodes of */ - SubProgram **apSub; /* Array of subprograms */ - int nSub; /* Number of entries in apSub */ - int iAddr; /* Address of next instruction to return */ - int iSub; /* 0 = main program, 1 = first sub-program etc. */ -}; -static Op *opIterNext(VdbeOpIter *p){ - Vdbe *v = p->v; - Op *pRet = 0; - Op *aOp; - int nOp; - - if( p->iSub<=p->nSub ){ - - if( p->iSub==0 ){ - aOp = v->aOp; - nOp = v->nOp; - }else{ - aOp = p->apSub[p->iSub-1]->aOp; - nOp = p->apSub[p->iSub-1]->nOp; - } - assert( p->iAddriAddr]; - p->iAddr++; - if( p->iAddr==nOp ){ - p->iSub++; - p->iAddr = 0; - } - - if( pRet->p4type==P4_SUBPROGRAM ){ - int nByte = (p->nSub+1)*sizeof(SubProgram*); - int j; - for(j=0; jnSub; j++){ - if( p->apSub[j]==pRet->p4.pProgram ) break; - } - if( j==p->nSub ){ - p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); - if( !p->apSub ){ - pRet = 0; - }else{ - p->apSub[p->nSub++] = pRet->p4.pProgram; - } - } - } - } - - return pRet; -} - -/* -** Check if the program stored in the VM associated with pParse may -** throw an ABORT exception (causing the statement, but not entire transaction -** to be rolled back). This condition is true if the main program or any -** sub-programs contains any of the following: -** -** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. -** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. -** * OP_Destroy -** * OP_VUpdate -** * OP_VRename -** * OP_FkCounter with P2==0 (immediate foreign key constraint) -** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...) -** -** Then check that the value of Parse.mayAbort is true if an -** ABORT may be thrown, or false otherwise. Return true if it does -** match, or false otherwise. This function is intended to be used as -** part of an assert statement in the compiler. Similar to: -** -** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); -*/ -SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ - int hasAbort = 0; - int hasFkCounter = 0; - int hasCreateTable = 0; - int hasInitCoroutine = 0; - Op *pOp; - VdbeOpIter sIter; - memset(&sIter, 0, sizeof(sIter)); - sIter.v = v; - - while( (pOp = opIterNext(&sIter))!=0 ){ - int opcode = pOp->opcode; - if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename - || ((opcode==OP_Halt || opcode==OP_HaltIfNull) - && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) - ){ - hasAbort = 1; - break; - } - if( opcode==OP_CreateTable ) hasCreateTable = 1; - if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; -#ifndef SQLITE_OMIT_FOREIGN_KEY - if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ - hasFkCounter = 1; - } -#endif - } - sqlite3DbFree(v->db, sIter.apSub); - - /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred. - ** If malloc failed, then the while() loop above may not have iterated - ** through all opcodes and hasAbort may be set incorrectly. Return - ** true for this case to prevent the assert() in the callers frame - ** from failing. */ - return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter - || (hasCreateTable && hasInitCoroutine) ); -} -#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ - -/* -** This routine is called after all opcodes have been inserted. It loops -** through all the opcodes and fixes up some details. -** -** (1) For each jump instruction with a negative P2 value (a label) -** resolve the P2 value to an actual address. -** -** (2) Compute the maximum number of arguments used by any SQL function -** and store that value in *pMaxFuncArgs. -** -** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately -** indicate what the prepared statement actually does. -** -** (4) Initialize the p4.xAdvance pointer on opcodes that use it. -** -** (5) Reclaim the memory allocated for storing labels. -** -** This routine will only function correctly if the mkopcodeh.tcl generator -** script numbers the opcodes correctly. Changes to this routine must be -** coordinated with changes to mkopcodeh.tcl. -*/ -static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ - int nMaxArgs = *pMaxFuncArgs; - Op *pOp; - Parse *pParse = p->pParse; - int *aLabel = pParse->aLabel; - p->readOnly = 1; - p->bIsReader = 0; - pOp = &p->aOp[p->nOp-1]; - while(1){ - - /* Only JUMP opcodes and the short list of special opcodes in the switch - ** below need to be considered. The mkopcodeh.tcl generator script groups - ** all these opcodes together near the front of the opcode list. Skip - ** any opcode that does not need processing by virtual of the fact that - ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. - */ - if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){ - /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing - ** cases from this switch! */ - switch( pOp->opcode ){ - case OP_Transaction: { - if( pOp->p2!=0 ) p->readOnly = 0; - /* fall thru */ - } - case OP_AutoCommit: - case OP_Savepoint: { - p->bIsReader = 1; - break; - } -#ifndef SQLITE_OMIT_WAL - case OP_Checkpoint: -#endif - case OP_Vacuum: - case OP_JournalMode: { - p->readOnly = 0; - p->bIsReader = 1; - break; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - case OP_VUpdate: { - if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; - break; - } - case OP_VFilter: { - int n; - assert( (pOp - p->aOp) >= 3 ); - assert( pOp[-1].opcode==OP_Integer ); - n = pOp[-1].p1; - if( n>nMaxArgs ) nMaxArgs = n; - break; - } -#endif - case OP_Next: - case OP_NextIfOpen: - case OP_SorterNext: { - pOp->p4.xAdvance = sqlite3BtreeNext; - pOp->p4type = P4_ADVANCE; - break; - } - case OP_Prev: - case OP_PrevIfOpen: { - pOp->p4.xAdvance = sqlite3BtreePrevious; - pOp->p4type = P4_ADVANCE; - break; - } - } - if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){ - assert( ADDR(pOp->p2)nLabel ); - pOp->p2 = aLabel[ADDR(pOp->p2)]; - } - } - if( pOp==p->aOp ) break; - pOp--; - } - sqlite3DbFree(p->db, pParse->aLabel); - pParse->aLabel = 0; - pParse->nLabel = 0; - *pMaxFuncArgs = nMaxArgs; - assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); -} - -/* -** Return the address of the next instruction to be inserted. -*/ -SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->magic==VDBE_MAGIC_INIT ); - return p->nOp; -} - -/* -** Verify that at least N opcode slots are available in p without -** having to malloc for more space (except when compiled using -** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing -** to verify that certain calls to sqlite3VdbeAddOpList() can never -** fail due to a OOM fault and hence that the return value from -** sqlite3VdbeAddOpList() will always be non-NULL. -*/ -#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) -SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ - assert( p->nOp + N <= p->pParse->nOpAlloc ); -} -#endif - -/* -** This function returns a pointer to the array of opcodes associated with -** the Vdbe passed as the first argument. It is the callers responsibility -** to arrange for the returned array to be eventually freed using the -** vdbeFreeOpArray() function. -** -** Before returning, *pnOp is set to the number of entries in the returned -** array. Also, *pnMaxArg is set to the larger of its current value and -** the number of entries in the Vdbe.apArg[] array required to execute the -** returned program. -*/ -SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ - VdbeOp *aOp = p->aOp; - assert( aOp && !p->db->mallocFailed ); - - /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ - assert( DbMaskAllZero(p->btreeMask) ); - - resolveP2Values(p, pnMaxArg); - *pnOp = p->nOp; - p->aOp = 0; - return aOp; -} - -/* -** Add a whole list of operations to the operation stack. Return a -** pointer to the first operation inserted. -** -** Non-zero P2 arguments to jump instructions are automatically adjusted -** so that the jump target is relative to the first operation inserted. -*/ -SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( - Vdbe *p, /* Add opcodes to the prepared statement */ - int nOp, /* Number of opcodes to add */ - VdbeOpList const *aOp, /* The opcodes to be added */ - int iLineno /* Source-file line number of first opcode */ -){ - int i; - VdbeOp *pOut, *pFirst; - assert( nOp>0 ); - assert( p->magic==VDBE_MAGIC_INIT ); - if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ - return 0; - } - pFirst = pOut = &p->aOp[p->nOp]; - for(i=0; iopcode = aOp->opcode; - pOut->p1 = aOp->p1; - pOut->p2 = aOp->p2; - assert( aOp->p2>=0 ); - if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ - pOut->p2 += p->nOp; - } - pOut->p3 = aOp->p3; - pOut->p4type = P4_NOTUSED; - pOut->p4.p = 0; - pOut->p5 = 0; -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - pOut->zComment = 0; -#endif -#ifdef SQLITE_VDBE_COVERAGE - pOut->iSrcLine = iLineno+i; -#else - (void)iLineno; -#endif -#ifdef SQLITE_DEBUG - if( p->db->flags & SQLITE_VdbeAddopTrace ){ - sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); - } -#endif - } - p->nOp += nOp; - return pFirst; -} - -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) -/* -** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus(). -*/ -SQLITE_PRIVATE void sqlite3VdbeScanStatus( - Vdbe *p, /* VM to add scanstatus() to */ - int addrExplain, /* Address of OP_Explain (or 0) */ - int addrLoop, /* Address of loop counter */ - int addrVisit, /* Address of rows visited counter */ - LogEst nEst, /* Estimated number of output rows */ - const char *zName /* Name of table or index being scanned */ -){ - int nByte = (p->nScan+1) * sizeof(ScanStatus); - ScanStatus *aNew; - aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); - if( aNew ){ - ScanStatus *pNew = &aNew[p->nScan++]; - pNew->addrExplain = addrExplain; - pNew->addrLoop = addrLoop; - pNew->addrVisit = addrVisit; - pNew->nEst = nEst; - pNew->zName = sqlite3DbStrDup(p->db, zName); - p->aScan = aNew; - } -} -#endif - - -/* -** Change the value of the opcode, or P1, P2, P3, or P5 operands -** for a specific instruction. -*/ -SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){ - sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; -} -SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){ - sqlite3VdbeGetOp(p,addr)->p1 = val; -} -SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){ - sqlite3VdbeGetOp(p,addr)->p2 = val; -} -SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){ - sqlite3VdbeGetOp(p,addr)->p3 = val; -} -SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){ - assert( p->nOp>0 || p->db->mallocFailed ); - if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; -} - -/* -** Change the P2 operand of instruction addr so that it points to -** the address of the next instruction to be coded. -*/ -SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ - sqlite3VdbeChangeP2(p, addr, p->nOp); -} - - -/* -** If the input FuncDef structure is ephemeral, then free it. If -** the FuncDef is not ephermal, then do nothing. -*/ -static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ - if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - sqlite3DbFree(db, pDef); - } -} - -static void vdbeFreeOpArray(sqlite3 *, Op *, int); - -/* -** Delete a P4 value if necessary. -*/ -static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ - if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - sqlite3DbFree(db, p); -} -static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ - freeEphemeralFunction(db, p->pFunc); - sqlite3DbFree(db, p); -} -static void freeP4(sqlite3 *db, int p4type, void *p4){ - assert( db ); - switch( p4type ){ - case P4_FUNCCTX: { - freeP4FuncCtx(db, (sqlite3_context*)p4); - break; - } - case P4_REAL: - case P4_INT64: - case P4_DYNAMIC: - case P4_INTARRAY: { - sqlite3DbFree(db, p4); - break; - } - case P4_KEYINFO: { - if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); - break; - } -#ifdef SQLITE_ENABLE_CURSOR_HINTS - case P4_EXPR: { - sqlite3ExprDelete(db, (Expr*)p4); - break; - } -#endif - case P4_MPRINTF: { - if( db->pnBytesFreed==0 ) sqlite3_free(p4); - break; - } - case P4_FUNCDEF: { - freeEphemeralFunction(db, (FuncDef*)p4); - break; - } - case P4_MEM: { - if( db->pnBytesFreed==0 ){ - sqlite3ValueFree((sqlite3_value*)p4); - }else{ - freeP4Mem(db, (Mem*)p4); - } - break; - } - case P4_VTAB : { - if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); - break; - } - } -} - -/* -** Free the space allocated for aOp and any p4 values allocated for the -** opcodes contained within. If aOp is not NULL it is assumed to contain -** nOp entries. -*/ -static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ - if( aOp ){ - Op *pOp; - for(pOp=aOp; pOp<&aOp[nOp]; pOp++){ - if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p); -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - sqlite3DbFree(db, pOp->zComment); -#endif - } - } - sqlite3DbFree(db, aOp); -} - -/* -** Link the SubProgram object passed as the second argument into the linked -** list at Vdbe.pSubProgram. This list is used to delete all sub-program -** objects when the VM is no longer required. -*/ -SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ - p->pNext = pVdbe->pProgram; - pVdbe->pProgram = p; -} - -/* -** Change the opcode at addr into OP_Noop -*/ -SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ - VdbeOp *pOp; - if( p->db->mallocFailed ) return 0; - assert( addr>=0 && addrnOp ); - pOp = &p->aOp[addr]; - freeP4(p->db, pOp->p4type, pOp->p4.p); - pOp->p4type = P4_NOTUSED; - pOp->p4.z = 0; - pOp->opcode = OP_Noop; - return 1; -} - -/* -** If the last opcode is "op" and it is not a jump destination, -** then remove it. Return true if and only if an opcode was removed. -*/ -SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ - if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){ - return sqlite3VdbeChangeToNoop(p, p->nOp-1); - }else{ - return 0; - } -} - -/* -** Change the value of the P4 operand for a specific instruction. -** This routine is useful when a large program is loaded from a -** static array using sqlite3VdbeAddOpList but we want to make a -** few minor changes to the program. -** -** If n>=0 then the P4 operand is dynamic, meaning that a copy of -** the string is made into memory obtained from sqlite3_malloc(). -** A value of n==0 means copy bytes of zP4 up to and including the -** first null byte. If n>0 then copy n+1 bytes of zP4. -** -** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points -** to a string or structure that is guaranteed to exist for the lifetime of -** the Vdbe. In these cases we can just copy the pointer. -** -** If addr<0 then change P4 on the most recently inserted instruction. -*/ -static void SQLITE_NOINLINE vdbeChangeP4Full( - Vdbe *p, - Op *pOp, - const char *zP4, - int n -){ - if( pOp->p4type ){ - freeP4(p->db, pOp->p4type, pOp->p4.p); - pOp->p4type = 0; - pOp->p4.p = 0; - } - if( n<0 ){ - sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n); - }else{ - if( n==0 ) n = sqlite3Strlen30(zP4); - pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n); - pOp->p4type = P4_DYNAMIC; - } -} -SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ - Op *pOp; - sqlite3 *db; - assert( p!=0 ); - db = p->db; - assert( p->magic==VDBE_MAGIC_INIT ); - assert( p->aOp!=0 || db->mallocFailed ); - if( db->mallocFailed ){ - if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); - return; - } - assert( p->nOp>0 ); - assert( addrnOp ); - if( addr<0 ){ - addr = p->nOp - 1; - } - pOp = &p->aOp[addr]; - if( n>=0 || pOp->p4type ){ - vdbeChangeP4Full(p, pOp, zP4, n); - return; - } - if( n==P4_INT32 ){ - /* Note: this cast is safe, because the origin data point was an int - ** that was cast to a (const char *). */ - pOp->p4.i = SQLITE_PTR_TO_INT(zP4); - pOp->p4type = P4_INT32; - }else if( zP4!=0 ){ - assert( n<0 ); - pOp->p4.p = (void*)zP4; - pOp->p4type = (signed char)n; - if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4); - } -} - -/* -** Set the P4 on the most recently added opcode to the KeyInfo for the -** index given. -*/ -SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ - Vdbe *v = pParse->pVdbe; - assert( v!=0 ); - assert( pIdx!=0 ); - sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx), - P4_KEYINFO); -} - -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS -/* -** Change the comment on the most recently coded instruction. Or -** insert a No-op and add the comment to that new instruction. This -** makes the code easier to read during debugging. None of this happens -** in a production build. -*/ -static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ - assert( p->nOp>0 || p->aOp==0 ); - assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); - if( p->nOp ){ - assert( p->aOp ); - sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); - p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap); - } -} -SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ - va_list ap; - if( p ){ - va_start(ap, zFormat); - vdbeVComment(p, zFormat, ap); - va_end(ap); - } -} -SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ - va_list ap; - if( p ){ - sqlite3VdbeAddOp0(p, OP_Noop); - va_start(ap, zFormat); - vdbeVComment(p, zFormat, ap); - va_end(ap); - } -} -#endif /* NDEBUG */ - -#ifdef SQLITE_VDBE_COVERAGE -/* -** Set the value if the iSrcLine field for the previously coded instruction. -*/ -SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ - sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; -} -#endif /* SQLITE_VDBE_COVERAGE */ - -/* -** Return the opcode for a given address. If the address is -1, then -** return the most recently inserted opcode. -** -** If a memory allocation error has occurred prior to the calling of this -** routine, then a pointer to a dummy VdbeOp will be returned. That opcode -** is readable but not writable, though it is cast to a writable value. -** The return of a dummy opcode allows the call to continue functioning -** after an OOM fault without having to check to see if the return from -** this routine is a valid pointer. But because the dummy.opcode is 0, -** dummy will never be written to. This is verified by code inspection and -** by running with Valgrind. -*/ -SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ - /* C89 specifies that the constant "dummy" will be initialized to all - ** zeros, which is correct. MSVC generates a warning, nevertheless. */ - static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ - assert( p->magic==VDBE_MAGIC_INIT ); - if( addr<0 ){ - addr = p->nOp - 1; - } - assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); - if( p->db->mallocFailed ){ - return (VdbeOp*)&dummy; - }else{ - return &p->aOp[addr]; - } -} - -#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) -/* -** Return an integer value for one of the parameters to the opcode pOp -** determined by character c. -*/ -static int translateP(char c, const Op *pOp){ - if( c=='1' ) return pOp->p1; - if( c=='2' ) return pOp->p2; - if( c=='3' ) return pOp->p3; - if( c=='4' ) return pOp->p4.i; - return pOp->p5; -} - -/* -** Compute a string for the "comment" field of a VDBE opcode listing. -** -** The Synopsis: field in comments in the vdbe.c source file gets converted -** to an extra string that is appended to the sqlite3OpcodeName(). In the -** absence of other comments, this synopsis becomes the comment on the opcode. -** Some translation occurs: -** -** "PX" -> "r[X]" -** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 -** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 -** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x -*/ -static int displayComment( - const Op *pOp, /* The opcode to be commented */ - const char *zP4, /* Previously obtained value for P4 */ - char *zTemp, /* Write result here */ - int nTemp /* Space available in zTemp[] */ -){ - const char *zOpName; - const char *zSynopsis; - int nOpName; - int ii, jj; - char zAlt[50]; - zOpName = sqlite3OpcodeName(pOp->opcode); - nOpName = sqlite3Strlen30(zOpName); - if( zOpName[nOpName+1] ){ - int seenCom = 0; - char c; - zSynopsis = zOpName += nOpName + 1; - if( strncmp(zSynopsis,"IF ",3)==0 ){ - if( pOp->p5 & SQLITE_STOREP2 ){ - sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); - }else{ - sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); - } - zSynopsis = zAlt; - } - for(ii=jj=0; jjzComment); - seenCom = 1; - }else{ - int v1 = translateP(c, pOp); - int v2; - sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1); - if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ - ii += 3; - jj += sqlite3Strlen30(zTemp+jj); - v2 = translateP(zSynopsis[ii], pOp); - if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ - ii += 2; - v2++; - } - if( v2>1 ){ - sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); - } - }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ - ii += 4; - } - } - jj += sqlite3Strlen30(zTemp+jj); - }else{ - zTemp[jj++] = c; - } - } - if( !seenCom && jjzComment ){ - sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment); - jj += sqlite3Strlen30(zTemp+jj); - } - if( jjzComment ){ - sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment); - jj = sqlite3Strlen30(zTemp); - }else{ - zTemp[0] = 0; - jj = 0; - } - return jj; -} -#endif /* SQLITE_DEBUG */ - -#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) -/* -** Translate the P4.pExpr value for an OP_CursorHint opcode into text -** that can be displayed in the P4 column of EXPLAIN output. -*/ -static void displayP4Expr(StrAccum *p, Expr *pExpr){ - const char *zOp = 0; - switch( pExpr->op ){ - case TK_STRING: - sqlite3XPrintf(p, "%Q", pExpr->u.zToken); - break; - case TK_INTEGER: - sqlite3XPrintf(p, "%d", pExpr->u.iValue); - break; - case TK_NULL: - sqlite3XPrintf(p, "NULL"); - break; - case TK_REGISTER: { - sqlite3XPrintf(p, "r[%d]", pExpr->iTable); - break; - } - case TK_COLUMN: { - if( pExpr->iColumn<0 ){ - sqlite3XPrintf(p, "rowid"); - }else{ - sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); - } - break; - } - case TK_LT: zOp = "LT"; break; - case TK_LE: zOp = "LE"; break; - case TK_GT: zOp = "GT"; break; - case TK_GE: zOp = "GE"; break; - case TK_NE: zOp = "NE"; break; - case TK_EQ: zOp = "EQ"; break; - case TK_IS: zOp = "IS"; break; - case TK_ISNOT: zOp = "ISNOT"; break; - case TK_AND: zOp = "AND"; break; - case TK_OR: zOp = "OR"; break; - case TK_PLUS: zOp = "ADD"; break; - case TK_STAR: zOp = "MUL"; break; - case TK_MINUS: zOp = "SUB"; break; - case TK_REM: zOp = "REM"; break; - case TK_BITAND: zOp = "BITAND"; break; - case TK_BITOR: zOp = "BITOR"; break; - case TK_SLASH: zOp = "DIV"; break; - case TK_LSHIFT: zOp = "LSHIFT"; break; - case TK_RSHIFT: zOp = "RSHIFT"; break; - case TK_CONCAT: zOp = "CONCAT"; break; - case TK_UMINUS: zOp = "MINUS"; break; - case TK_UPLUS: zOp = "PLUS"; break; - case TK_BITNOT: zOp = "BITNOT"; break; - case TK_NOT: zOp = "NOT"; break; - case TK_ISNULL: zOp = "ISNULL"; break; - case TK_NOTNULL: zOp = "NOTNULL"; break; - - default: - sqlite3XPrintf(p, "%s", "expr"); - break; - } - - if( zOp ){ - sqlite3XPrintf(p, "%s(", zOp); - displayP4Expr(p, pExpr->pLeft); - if( pExpr->pRight ){ - sqlite3StrAccumAppend(p, ",", 1); - displayP4Expr(p, pExpr->pRight); - } - sqlite3StrAccumAppend(p, ")", 1); - } -} -#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ - - -#if VDBE_DISPLAY_P4 -/* -** Compute a string that describes the P4 parameter for an opcode. -** Use zTemp for any required temporary buffer space. -*/ -static char *displayP4(Op *pOp, char *zTemp, int nTemp){ - char *zP4 = zTemp; - StrAccum x; - assert( nTemp>=20 ); - sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); - switch( pOp->p4type ){ - case P4_KEYINFO: { - int j; - KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; - assert( pKeyInfo->aSortOrder!=0 ); - sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField); - for(j=0; jnField; j++){ - CollSeq *pColl = pKeyInfo->aColl[j]; - const char *zColl = pColl ? pColl->zName : ""; - if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; - sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl); - } - sqlite3StrAccumAppend(&x, ")", 1); - break; - } -#ifdef SQLITE_ENABLE_CURSOR_HINTS - case P4_EXPR: { - displayP4Expr(&x, pOp->p4.pExpr); - break; - } -#endif - case P4_COLLSEQ: { - CollSeq *pColl = pOp->p4.pColl; - sqlite3XPrintf(&x, "(%.20s)", pColl->zName); - break; - } - case P4_FUNCDEF: { - FuncDef *pDef = pOp->p4.pFunc; - sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); - break; - } -#ifdef SQLITE_DEBUG - case P4_FUNCCTX: { - FuncDef *pDef = pOp->p4.pCtx->pFunc; - sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); - break; - } -#endif - case P4_INT64: { - sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); - break; - } - case P4_INT32: { - sqlite3XPrintf(&x, "%d", pOp->p4.i); - break; - } - case P4_REAL: { - sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); - break; - } - case P4_MEM: { - Mem *pMem = pOp->p4.pMem; - if( pMem->flags & MEM_Str ){ - zP4 = pMem->z; - }else if( pMem->flags & MEM_Int ){ - sqlite3XPrintf(&x, "%lld", pMem->u.i); - }else if( pMem->flags & MEM_Real ){ - sqlite3XPrintf(&x, "%.16g", pMem->u.r); - }else if( pMem->flags & MEM_Null ){ - zP4 = "NULL"; - }else{ - assert( pMem->flags & MEM_Blob ); - zP4 = "(blob)"; - } - break; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - case P4_VTAB: { - sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; - sqlite3XPrintf(&x, "vtab:%p", pVtab); - break; - } -#endif - case P4_INTARRAY: { - int i; - int *ai = pOp->p4.ai; - int n = ai[0]; /* The first element of an INTARRAY is always the - ** count of the number of elements to follow */ - for(i=1; ip4.pTab->zName); - break; - } - default: { - zP4 = pOp->p4.z; - if( zP4==0 ){ - zP4 = zTemp; - zTemp[0] = 0; - } - } - } - sqlite3StrAccumFinish(&x); - assert( zP4!=0 ); - return zP4; -} -#endif /* VDBE_DISPLAY_P4 */ - -/* -** Declare to the Vdbe that the BTree object at db->aDb[i] is used. -** -** The prepared statements need to know in advance the complete set of -** attached databases that will be use. A mask of these databases -** is maintained in p->btreeMask. The p->lockMask value is the subset of -** p->btreeMask of databases that will require a lock. -*/ -SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ - assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); - assert( i<(int)sizeof(p->btreeMask)*8 ); - DbMaskSet(p->btreeMask, i); - if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ - DbMaskSet(p->lockMask, i); - } -} - -#if !defined(SQLITE_OMIT_SHARED_CACHE) -/* -** If SQLite is compiled to support shared-cache mode and to be threadsafe, -** this routine obtains the mutex associated with each BtShared structure -** that may be accessed by the VM passed as an argument. In doing so it also -** sets the BtShared.db member of each of the BtShared structures, ensuring -** that the correct busy-handler callback is invoked if required. -** -** If SQLite is not threadsafe but does support shared-cache mode, then -** sqlite3BtreeEnter() is invoked to set the BtShared.db variables -** of all of BtShared structures accessible via the database handle -** associated with the VM. -** -** If SQLite is not threadsafe and does not support shared-cache mode, this -** function is a no-op. -** -** The p->btreeMask field is a bitmask of all btrees that the prepared -** statement p will ever use. Let N be the number of bits in p->btreeMask -** corresponding to btrees that use shared cache. Then the runtime of -** this routine is N*N. But as N is rarely more than 1, this should not -** be a problem. -*/ -SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ - int i; - sqlite3 *db; - Db *aDb; - int nDb; - if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ - db = p->db; - aDb = db->aDb; - nDb = db->nDb; - for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ - sqlite3BtreeEnter(aDb[i].pBt); - } - } -} -#endif - -#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 -/* -** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). -*/ -static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){ - int i; - sqlite3 *db; - Db *aDb; - int nDb; - db = p->db; - aDb = db->aDb; - nDb = db->nDb; - for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ - sqlite3BtreeLeave(aDb[i].pBt); - } - } -} -SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ - if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ - vdbeLeave(p); -} -#endif - -#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) -/* -** Print a single opcode. This routine is used for debugging only. -*/ -SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ - char *zP4; - char zPtr[50]; - char zCom[100]; - static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n"; - if( pOut==0 ) pOut = stdout; - zP4 = displayP4(pOp, zPtr, sizeof(zPtr)); -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - displayComment(pOp, zP4, zCom, sizeof(zCom)); -#else - zCom[0] = 0; -#endif - /* NB: The sqlite3OpcodeName() function is implemented by code created - ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the - ** information from the vdbe.c source text */ - fprintf(pOut, zFormat1, pc, - sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, - zCom - ); - fflush(pOut); -} -#endif - -/* -** Initialize an array of N Mem element. -*/ -static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ - while( (N--)>0 ){ - p->db = db; - p->flags = flags; - p->szMalloc = 0; -#ifdef SQLITE_DEBUG - p->pScopyFrom = 0; -#endif - p++; - } -} - -/* -** Release an array of N Mem elements -*/ -static void releaseMemArray(Mem *p, int N){ - if( p && N ){ - Mem *pEnd = &p[N]; - sqlite3 *db = p->db; - if( db->pnBytesFreed ){ - do{ - if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); - }while( (++p)flags & MEM_Agg ); - testcase( p->flags & MEM_Dyn ); - testcase( p->flags & MEM_Frame ); - testcase( p->flags & MEM_RowSet ); - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ - sqlite3VdbeMemRelease(p); - }else if( p->szMalloc ){ - sqlite3DbFree(db, p->zMalloc); - p->szMalloc = 0; - } - - p->flags = MEM_Undefined; - }while( (++p)nChildMem]; - for(i=0; inChildCsr; i++){ - sqlite3VdbeFreeCursor(p->v, apCsr[i]); - } - releaseMemArray(aMem, p->nChildMem); - sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); - sqlite3DbFree(p->v->db, p); -} - -#ifndef SQLITE_OMIT_EXPLAIN -/* -** Give a listing of the program in the virtual machine. -** -** The interface is the same as sqlite3VdbeExec(). But instead of -** running the code, it invokes the callback once for each instruction. -** This feature is used to implement "EXPLAIN". -** -** When p->explain==1, each instruction is listed. When -** p->explain==2, only OP_Explain instructions are listed and these -** are shown in a different format. p->explain==2 is used to implement -** EXPLAIN QUERY PLAN. -** -** When p->explain==1, first the main program is listed, then each of -** the trigger subprograms are listed one by one. -*/ -SQLITE_PRIVATE int sqlite3VdbeList( - Vdbe *p /* The VDBE */ -){ - int nRow; /* Stop when row count reaches this */ - int nSub = 0; /* Number of sub-vdbes seen so far */ - SubProgram **apSub = 0; /* Array of sub-vdbes */ - Mem *pSub = 0; /* Memory cell hold array of subprogs */ - sqlite3 *db = p->db; /* The database connection */ - int i; /* Loop counter */ - int rc = SQLITE_OK; /* Return code */ - Mem *pMem = &p->aMem[1]; /* First Mem of result set */ - - assert( p->explain ); - assert( p->magic==VDBE_MAGIC_RUN ); - assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); - - /* Even though this opcode does not use dynamic strings for - ** the result, result columns may become dynamic if the user calls - ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. - */ - releaseMemArray(pMem, 8); - p->pResultSet = 0; - - if( p->rc==SQLITE_NOMEM_BKPT ){ - /* This happens if a malloc() inside a call to sqlite3_column_text() or - ** sqlite3_column_text16() failed. */ - sqlite3OomFault(db); - return SQLITE_ERROR; - } - - /* When the number of output rows reaches nRow, that means the - ** listing has finished and sqlite3_step() should return SQLITE_DONE. - ** nRow is the sum of the number of rows in the main program, plus - ** the sum of the number of rows in all trigger subprograms encountered - ** so far. The nRow value will increase as new trigger subprograms are - ** encountered, but p->pc will eventually catch up to nRow. - */ - nRow = p->nOp; - if( p->explain==1 ){ - /* The first 8 memory cells are used for the result set. So we will - ** commandeer the 9th cell to use as storage for an array of pointers - ** to trigger subprograms. The VDBE is guaranteed to have at least 9 - ** cells. */ - assert( p->nMem>9 ); - pSub = &p->aMem[9]; - if( pSub->flags&MEM_Blob ){ - /* On the first call to sqlite3_step(), pSub will hold a NULL. It is - ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */ - nSub = pSub->n/sizeof(Vdbe*); - apSub = (SubProgram **)pSub->z; - } - for(i=0; inOp; - } - } - - do{ - i = p->pc++; - }while( iexplain==2 && p->aOp[i].opcode!=OP_Explain ); - if( i>=nRow ){ - p->rc = SQLITE_OK; - rc = SQLITE_DONE; - }else if( db->u1.isInterrupted ){ - p->rc = SQLITE_INTERRUPT; - rc = SQLITE_ERROR; - sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); - }else{ - char *zP4; - Op *pOp; - if( inOp ){ - /* The output line number is small enough that we are still in the - ** main program. */ - pOp = &p->aOp[i]; - }else{ - /* We are currently listing subprograms. Figure out which one and - ** pick up the appropriate opcode. */ - int j; - i -= p->nOp; - for(j=0; i>=apSub[j]->nOp; j++){ - i -= apSub[j]->nOp; - } - pOp = &apSub[j]->aOp[i]; - } - if( p->explain==1 ){ - pMem->flags = MEM_Int; - pMem->u.i = i; /* Program counter */ - pMem++; - - pMem->flags = MEM_Static|MEM_Str|MEM_Term; - pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ - assert( pMem->z!=0 ); - pMem->n = sqlite3Strlen30(pMem->z); - pMem->enc = SQLITE_UTF8; - pMem++; - - /* When an OP_Program opcode is encounter (the only opcode that has - ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms - ** kept in p->aMem[9].z to hold the new program - assuming this subprogram - ** has not already been seen. - */ - if( pOp->p4type==P4_SUBPROGRAM ){ - int nByte = (nSub+1)*sizeof(SubProgram*); - int j; - for(j=0; jp4.pProgram ) break; - } - if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){ - apSub = (SubProgram **)pSub->z; - apSub[nSub++] = pOp->p4.pProgram; - pSub->flags |= MEM_Blob; - pSub->n = nSub*sizeof(SubProgram*); - } - } - } - - pMem->flags = MEM_Int; - pMem->u.i = pOp->p1; /* P1 */ - pMem++; - - pMem->flags = MEM_Int; - pMem->u.i = pOp->p2; /* P2 */ - pMem++; - - pMem->flags = MEM_Int; - pMem->u.i = pOp->p3; /* P3 */ - pMem++; - - if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; - } - pMem->flags = MEM_Str|MEM_Term; - zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); - if( zP4!=pMem->z ){ - pMem->n = 0; - sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); - }else{ - assert( pMem->z!=0 ); - pMem->n = sqlite3Strlen30(pMem->z); - pMem->enc = SQLITE_UTF8; - } - pMem++; - - if( p->explain==1 ){ - if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; - } - pMem->flags = MEM_Str|MEM_Term; - pMem->n = 2; - sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ - pMem->enc = SQLITE_UTF8; - pMem++; - -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ - assert( p->db->mallocFailed ); - return SQLITE_ERROR; - } - pMem->flags = MEM_Str|MEM_Term; - pMem->n = displayComment(pOp, zP4, pMem->z, 500); - pMem->enc = SQLITE_UTF8; -#else - pMem->flags = MEM_Null; /* Comment */ -#endif - } - - p->nResColumn = 8 - 4*(p->explain-1); - p->pResultSet = &p->aMem[1]; - p->rc = SQLITE_OK; - rc = SQLITE_ROW; - } - return rc; -} -#endif /* SQLITE_OMIT_EXPLAIN */ - -#ifdef SQLITE_DEBUG -/* -** Print the SQL that was used to generate a VDBE program. -*/ -SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ - const char *z = 0; - if( p->zSql ){ - z = p->zSql; - }else if( p->nOp>=1 ){ - const VdbeOp *pOp = &p->aOp[0]; - if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ - z = pOp->p4.z; - while( sqlite3Isspace(*z) ) z++; - } - } - if( z ) printf("SQL: [%s]\n", z); -} -#endif - -#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) -/* -** Print an IOTRACE message showing SQL content. -*/ -SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ - int nOp = p->nOp; - VdbeOp *pOp; - if( sqlite3IoTrace==0 ) return; - if( nOp<1 ) return; - pOp = &p->aOp[0]; - if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ - int i, j; - char z[1000]; - sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); - for(i=0; sqlite3Isspace(z[i]); i++){} - for(j=0; z[i]; i++){ - if( sqlite3Isspace(z[i]) ){ - if( z[i-1]!=' ' ){ - z[j++] = ' '; - } - }else{ - z[j++] = z[i]; - } - } - z[j] = 0; - sqlite3IoTrace("SQL %s\n", z); - } -} -#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ - -/* An instance of this object describes bulk memory available for use -** by subcomponents of a prepared statement. Space is allocated out -** of a ReusableSpace object by the allocSpace() routine below. -*/ -struct ReusableSpace { - u8 *pSpace; /* Available memory */ - int nFree; /* Bytes of available memory */ - int nNeeded; /* Total bytes that could not be allocated */ -}; - -/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf -** from the ReusableSpace object. Return a pointer to the allocated -** memory on success. If insufficient memory is available in the -** ReusableSpace object, increase the ReusableSpace.nNeeded -** value by the amount needed and return NULL. -** -** If pBuf is not initially NULL, that means that the memory has already -** been allocated by a prior call to this routine, so just return a copy -** of pBuf and leave ReusableSpace unchanged. -** -** This allocator is employed to repurpose unused slots at the end of the -** opcode array of prepared state for other memory needs of the prepared -** statement. -*/ -static void *allocSpace( - struct ReusableSpace *p, /* Bulk memory available for allocation */ - void *pBuf, /* Pointer to a prior allocation */ - int nByte /* Bytes of memory needed */ -){ - assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); - if( pBuf==0 ){ - nByte = ROUND8(nByte); - if( nByte <= p->nFree ){ - p->nFree -= nByte; - pBuf = &p->pSpace[p->nFree]; - }else{ - p->nNeeded += nByte; - } - } - assert( EIGHT_BYTE_ALIGNMENT(pBuf) ); - return pBuf; -} - -/* -** Rewind the VDBE back to the beginning in preparation for -** running it. -*/ -SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) - int i; -#endif - assert( p!=0 ); - assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET ); - - /* There should be at least one opcode. - */ - assert( p->nOp>0 ); - - /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ - p->magic = VDBE_MAGIC_RUN; - -#ifdef SQLITE_DEBUG - for(i=0; inMem; i++){ - assert( p->aMem[i].db==p->db ); - } -#endif - p->pc = -1; - p->rc = SQLITE_OK; - p->errorAction = OE_Abort; - p->nChange = 0; - p->cacheCtr = 1; - p->minWriteFileFormat = 255; - p->iStatement = 0; - p->nFkConstraint = 0; -#ifdef VDBE_PROFILE - for(i=0; inOp; i++){ - p->aOp[i].cnt = 0; - p->aOp[i].cycles = 0; - } -#endif -} - -/* -** Prepare a virtual machine for execution for the first time after -** creating the virtual machine. This involves things such -** as allocating registers and initializing the program counter. -** After the VDBE has be prepped, it can be executed by one or more -** calls to sqlite3VdbeExec(). -** -** This function may be called exactly once on each virtual machine. -** After this routine is called the VM has been "packaged" and is ready -** to run. After this routine is called, further calls to -** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects -** the Vdbe from the Parse object that helped generate it so that the -** the Vdbe becomes an independent entity and the Parse object can be -** destroyed. -** -** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back -** to its initial state after it has been run. -*/ -SQLITE_PRIVATE void sqlite3VdbeMakeReady( - Vdbe *p, /* The VDBE */ - Parse *pParse /* Parsing context */ -){ - sqlite3 *db; /* The database connection */ - int nVar; /* Number of parameters */ - int nMem; /* Number of VM memory registers */ - int nCursor; /* Number of cursors required */ - int nArg; /* Number of arguments in subprograms */ - int n; /* Loop counter */ - struct ReusableSpace x; /* Reusable bulk memory */ - - assert( p!=0 ); - assert( p->nOp>0 ); - assert( pParse!=0 ); - assert( p->magic==VDBE_MAGIC_INIT ); - assert( pParse==p->pParse ); - db = p->db; - assert( db->mallocFailed==0 ); - nVar = pParse->nVar; - nMem = pParse->nMem; - nCursor = pParse->nTab; - nArg = pParse->nMaxArg; - - /* Each cursor uses a memory cell. The first cursor (cursor 0) can - ** use aMem[0] which is not otherwise used by the VDBE program. Allocate - ** space at the end of aMem[] for cursors 1 and greater. - ** See also: allocateCursor(). - */ - nMem += nCursor; - if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ - - /* Figure out how much reusable memory is available at the end of the - ** opcode array. This extra memory will be reallocated for other elements - ** of the prepared statement. - */ - n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ - x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ - assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); - x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ - assert( x.nFree>=0 ); - assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); - - resolveP2Values(p, &nArg); - p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); - if( pParse->explain && nMem<10 ){ - nMem = 10; - } - p->expired = 0; - - /* Memory for registers, parameters, cursor, etc, is allocated in one or two - ** passes. On the first pass, we try to reuse unused memory at the - ** end of the opcode array. If we are unable to satisfy all memory - ** requirements by reusing the opcode array tail, then the second - ** pass will fill in the remainder using a fresh memory allocation. - ** - ** This two-pass approach that reuses as much memory as possible from - ** the leftover memory at the end of the opcode array. This can significantly - ** reduce the amount of memory held by a prepared statement. - */ - do { - x.nNeeded = 0; - p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); - p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); - p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); - p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); -#endif - if( x.nNeeded==0 ) break; - x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); - x.nFree = x.nNeeded; - }while( !db->mallocFailed ); - - p->nzVar = pParse->nzVar; - p->azVar = pParse->azVar; - pParse->nzVar = 0; - pParse->azVar = 0; - p->explain = pParse->explain; - if( db->mallocFailed ){ - p->nVar = 0; - p->nCursor = 0; - p->nMem = 0; - }else{ - p->nCursor = nCursor; - p->nVar = (ynVar)nVar; - initMemArray(p->aVar, nVar, db, MEM_Null); - p->nMem = nMem; - initMemArray(p->aMem, nMem, db, MEM_Undefined); - memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - memset(p->anExec, 0, p->nOp*sizeof(i64)); -#endif - } - sqlite3VdbeRewind(p); -} - -/* -** Close a VDBE cursor and release all the resources that cursor -** happens to hold. -*/ -SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ - if( pCx==0 ){ - return; - } - assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE ); - switch( pCx->eCurType ){ - case CURTYPE_SORTER: { - sqlite3VdbeSorterClose(p->db, pCx); - break; - } - case CURTYPE_BTREE: { - if( pCx->pBt ){ - sqlite3BtreeClose(pCx->pBt); - /* The pCx->pCursor will be close automatically, if it exists, by - ** the call above. */ - }else{ - assert( pCx->uc.pCursor!=0 ); - sqlite3BtreeCloseCursor(pCx->uc.pCursor); - } - break; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - case CURTYPE_VTAB: { - sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; - const sqlite3_module *pModule = pVCur->pVtab->pModule; - assert( pVCur->pVtab->nRef>0 ); - pVCur->pVtab->nRef--; - pModule->xClose(pVCur); - break; - } -#endif - } -} - -/* -** Close all cursors in the current frame. -*/ -static void closeCursorsInFrame(Vdbe *p){ - if( p->apCsr ){ - int i; - for(i=0; inCursor; i++){ - VdbeCursor *pC = p->apCsr[i]; - if( pC ){ - sqlite3VdbeFreeCursor(p, pC); - p->apCsr[i] = 0; - } - } - } -} - -/* -** Copy the values stored in the VdbeFrame structure to its Vdbe. This -** is used, for example, when a trigger sub-program is halted to restore -** control to the main program. -*/ -SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ - Vdbe *v = pFrame->v; - closeCursorsInFrame(v); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - v->anExec = pFrame->anExec; -#endif - v->aOp = pFrame->aOp; - v->nOp = pFrame->nOp; - v->aMem = pFrame->aMem; - v->nMem = pFrame->nMem; - v->apCsr = pFrame->apCsr; - v->nCursor = pFrame->nCursor; - v->db->lastRowid = pFrame->lastRowid; - v->nChange = pFrame->nChange; - v->db->nChange = pFrame->nDbChange; - sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0); - v->pAuxData = pFrame->pAuxData; - pFrame->pAuxData = 0; - return pFrame->pc; -} - -/* -** Close all cursors. -** -** Also release any dynamic memory held by the VM in the Vdbe.aMem memory -** cell array. This is necessary as the memory cell array may contain -** pointers to VdbeFrame objects, which may in turn contain pointers to -** open cursors. -*/ -static void closeAllCursors(Vdbe *p){ - if( p->pFrame ){ - VdbeFrame *pFrame; - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - sqlite3VdbeFrameRestore(pFrame); - p->pFrame = 0; - p->nFrame = 0; - } - assert( p->nFrame==0 ); - closeCursorsInFrame(p); - if( p->aMem ){ - releaseMemArray(p->aMem, p->nMem); - } - while( p->pDelFrame ){ - VdbeFrame *pDel = p->pDelFrame; - p->pDelFrame = pDel->pParent; - sqlite3VdbeFrameDelete(pDel); - } - - /* Delete any auxdata allocations made by the VM */ - if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0); - assert( p->pAuxData==0 ); -} - -/* -** Clean up the VM after a single run. -*/ -static void Cleanup(Vdbe *p){ - sqlite3 *db = p->db; - -#ifdef SQLITE_DEBUG - /* Execute assert() statements to ensure that the Vdbe.apCsr[] and - ** Vdbe.aMem[] arrays have already been cleaned up. */ - int i; - if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); - if( p->aMem ){ - for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); - } -#endif - - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; - p->pResultSet = 0; -} - -/* -** Set the number of result columns that will be returned by this SQL -** statement. This is now set at compile time, rather than during -** execution of the vdbe program so that sqlite3_column_count() can -** be called on an SQL statement before sqlite3_step(). -*/ -SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ - Mem *pColName; - int n; - sqlite3 *db = p->db; - - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - sqlite3DbFree(db, p->aColName); - n = nResColumn*COLNAME_N; - p->nResColumn = (u16)nResColumn; - p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); - if( p->aColName==0 ) return; - initMemArray(p->aColName, n, p->db, MEM_Null); -} - -/* -** Set the name of the idx'th column to be returned by the SQL statement. -** zName must be a pointer to a nul terminated string. -** -** This call must be made after a call to sqlite3VdbeSetNumCols(). -** -** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC -** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed -** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. -*/ -SQLITE_PRIVATE int sqlite3VdbeSetColName( - Vdbe *p, /* Vdbe being configured */ - int idx, /* Index of column zName applies to */ - int var, /* One of the COLNAME_* constants */ - const char *zName, /* Pointer to buffer containing name */ - void (*xDel)(void*) /* Memory management strategy for zName */ -){ - int rc; - Mem *pColName; - assert( idxnResColumn ); - assert( vardb->mallocFailed ){ - assert( !zName || xDel!=SQLITE_DYNAMIC ); - return SQLITE_NOMEM_BKPT; - } - assert( p->aColName!=0 ); - pColName = &(p->aColName[idx+var*p->nResColumn]); - rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); - assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); - return rc; -} - -/* -** A read or write transaction may or may not be active on database handle -** db. If a transaction is active, commit it. If there is a -** write-transaction spanning more than one database file, this routine -** takes care of the master journal trickery. -*/ -static int vdbeCommit(sqlite3 *db, Vdbe *p){ - int i; - int nTrans = 0; /* Number of databases with an active write-transaction - ** that are candidates for a two-phase commit using a - ** master-journal */ - int rc = SQLITE_OK; - int needXcommit = 0; - -#ifdef SQLITE_OMIT_VIRTUALTABLE - /* With this option, sqlite3VtabSync() is defined to be simply - ** SQLITE_OK so p is not used. - */ - UNUSED_PARAMETER(p); -#endif - - /* Before doing anything else, call the xSync() callback for any - ** virtual module tables written in this transaction. This has to - ** be done before determining whether a master journal file is - ** required, as an xSync() callback may add an attached database - ** to the transaction. - */ - rc = sqlite3VtabSync(db, p); - - /* This loop determines (a) if the commit hook should be invoked and - ** (b) how many database files have open write transactions, not - ** including the temp database. (b) is important because if more than - ** one database file has an open write transaction, a master journal - ** file is required for an atomic commit. - */ - for(i=0; rc==SQLITE_OK && inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ - /* Whether or not a database might need a master journal depends upon - ** its journal mode (among other things). This matrix determines which - ** journal modes use a master journal and which do not */ - static const u8 aMJNeeded[] = { - /* DELETE */ 1, - /* PERSIST */ 1, - /* OFF */ 0, - /* TRUNCATE */ 1, - /* MEMORY */ 0, - /* WAL */ 0 - }; - Pager *pPager; /* Pager associated with pBt */ - needXcommit = 1; - sqlite3BtreeEnter(pBt); - pPager = sqlite3BtreePager(pBt); - if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF - && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] - ){ - assert( i!=1 ); - nTrans++; - } - rc = sqlite3PagerExclusiveLock(pPager); - sqlite3BtreeLeave(pBt); - } - } - if( rc!=SQLITE_OK ){ - return rc; - } - - /* If there are any write-transactions at all, invoke the commit hook */ - if( needXcommit && db->xCommitCallback ){ - rc = db->xCommitCallback(db->pCommitArg); - if( rc ){ - return SQLITE_CONSTRAINT_COMMITHOOK; - } - } - - /* The simple case - no more than one database file (not counting the - ** TEMP database) has a transaction active. There is no need for the - ** master-journal. - ** - ** If the return value of sqlite3BtreeGetFilename() is a zero length - ** string, it means the main database is :memory: or a temp file. In - ** that case we do not support atomic multi-file commits, so use the - ** simple case then too. - */ - if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) - || nTrans<=1 - ){ - for(i=0; rc==SQLITE_OK && inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - rc = sqlite3BtreeCommitPhaseOne(pBt, 0); - } - } - - /* Do the commit only if all databases successfully complete phase 1. - ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an - ** IO error while deleting or truncating a journal file. It is unlikely, - ** but could happen. In this case abandon processing and return the error. - */ - for(i=0; rc==SQLITE_OK && inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); - } - } - if( rc==SQLITE_OK ){ - sqlite3VtabCommit(db); - } - } - - /* The complex case - There is a multi-file write-transaction active. - ** This requires a master journal file to ensure the transaction is - ** committed atomically. - */ -#ifndef SQLITE_OMIT_DISKIO - else{ - sqlite3_vfs *pVfs = db->pVfs; - char *zMaster = 0; /* File-name for the master journal */ - char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); - sqlite3_file *pMaster = 0; - i64 offset = 0; - int res; - int retryCount = 0; - int nMainFile; - - /* Select a master journal file name */ - nMainFile = sqlite3Strlen30(zMainFile); - zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile); - if( zMaster==0 ) return SQLITE_NOMEM_BKPT; - do { - u32 iRandom; - if( retryCount ){ - if( retryCount>100 ){ - sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); - sqlite3OsDelete(pVfs, zMaster, 0); - break; - }else if( retryCount==1 ){ - sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); - } - } - retryCount++; - sqlite3_randomness(sizeof(iRandom), &iRandom); - sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", - (iRandom>>8)&0xffffff, iRandom&0xff); - /* The antipenultimate character of the master journal name must - ** be "9" to avoid name collisions when using 8+3 filenames. */ - assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' ); - sqlite3FileSuffix3(zMainFile, zMaster); - rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); - }while( rc==SQLITE_OK && res ); - if( rc==SQLITE_OK ){ - /* Open the master journal. */ - rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| - SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 - ); - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, zMaster); - return rc; - } - - /* Write the name of each database file in the transaction into the new - ** master journal file. If an error occurs at this point close - ** and delete the master journal file. All the individual journal files - ** still have 'null' as the master journal pointer, so they will roll - ** back independently if a failure occurs. - */ - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ - char const *zFile = sqlite3BtreeGetJournalname(pBt); - if( zFile==0 ){ - continue; /* Ignore TEMP and :memory: databases */ - } - assert( zFile[0]!=0 ); - rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset); - offset += sqlite3Strlen30(zFile)+1; - if( rc!=SQLITE_OK ){ - sqlite3OsCloseFree(pMaster); - sqlite3OsDelete(pVfs, zMaster, 0); - sqlite3DbFree(db, zMaster); - return rc; - } - } - } - - /* Sync the master journal file. If the IOCAP_SEQUENTIAL device - ** flag is set this is not required. - */ - if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL) - && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL)) - ){ - sqlite3OsCloseFree(pMaster); - sqlite3OsDelete(pVfs, zMaster, 0); - sqlite3DbFree(db, zMaster); - return rc; - } - - /* Sync all the db files involved in the transaction. The same call - ** sets the master journal pointer in each individual journal. If - ** an error occurs here, do not delete the master journal file. - ** - ** If the error occurs during the first call to - ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the - ** master journal file will be orphaned. But we cannot delete it, - ** in case the master journal file name was written into the journal - ** file before the failure occurred. - */ - for(i=0; rc==SQLITE_OK && inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); - } - } - sqlite3OsCloseFree(pMaster); - assert( rc!=SQLITE_BUSY ); - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, zMaster); - return rc; - } - - /* Delete the master journal file. This commits the transaction. After - ** doing this the directory is synced again before any individual - ** transaction files are deleted. - */ - rc = sqlite3OsDelete(pVfs, zMaster, 1); - sqlite3DbFree(db, zMaster); - zMaster = 0; - if( rc ){ - return rc; - } - - /* All files and directories have already been synced, so the following - ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and - ** deleting or truncating journals. If something goes wrong while - ** this is happening we don't really care. The integrity of the - ** transaction is already guaranteed, but some stray 'cold' journals - ** may be lying around. Returning an error code won't help matters. - */ - disable_simulated_io_errors(); - sqlite3BeginBenignMalloc(); - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - sqlite3BtreeCommitPhaseTwo(pBt, 1); - } - } - sqlite3EndBenignMalloc(); - enable_simulated_io_errors(); - - sqlite3VtabCommit(db); - } -#endif - - return rc; -} - -/* -** This routine checks that the sqlite3.nVdbeActive count variable -** matches the number of vdbe's in the list sqlite3.pVdbe that are -** currently active. An assertion fails if the two counts do not match. -** This is an internal self-check only - it is not an essential processing -** step. -** -** This is a no-op if NDEBUG is defined. -*/ -#ifndef NDEBUG -static void checkActiveVdbeCnt(sqlite3 *db){ - Vdbe *p; - int cnt = 0; - int nWrite = 0; - int nRead = 0; - p = db->pVdbe; - while( p ){ - if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ - cnt++; - if( p->readOnly==0 ) nWrite++; - if( p->bIsReader ) nRead++; - } - p = p->pNext; - } - assert( cnt==db->nVdbeActive ); - assert( nWrite==db->nVdbeWrite ); - assert( nRead==db->nVdbeRead ); -} -#else -#define checkActiveVdbeCnt(x) -#endif - -/* -** If the Vdbe passed as the first argument opened a statement-transaction, -** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or -** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement -** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the -** statement transaction is committed. -** -** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. -** Otherwise SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ - sqlite3 *const db = p->db; - int rc = SQLITE_OK; - - /* If p->iStatement is greater than zero, then this Vdbe opened a - ** statement transaction that should be closed here. The only exception - ** is that an IO error may have occurred, causing an emergency rollback. - ** In this case (db->nStatement==0), and there is nothing to do. - */ - if( db->nStatement && p->iStatement ){ - int i; - const int iSavepoint = p->iStatement-1; - - assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); - assert( db->nStatement>0 ); - assert( p->iStatement==(db->nStatement+db->nSavepoint) ); - - for(i=0; inDb; i++){ - int rc2 = SQLITE_OK; - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - if( eOp==SAVEPOINT_ROLLBACK ){ - rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); - } - if( rc2==SQLITE_OK ){ - rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); - } - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - db->nStatement--; - p->iStatement = 0; - - if( rc==SQLITE_OK ){ - if( eOp==SAVEPOINT_ROLLBACK ){ - rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); - } - if( rc==SQLITE_OK ){ - rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); - } - } - - /* If the statement transaction is being rolled back, also restore the - ** database handles deferred constraint counter to the value it had when - ** the statement transaction was opened. */ - if( eOp==SAVEPOINT_ROLLBACK ){ - db->nDeferredCons = p->nStmtDefCons; - db->nDeferredImmCons = p->nStmtDefImmCons; - } - } - return rc; -} - -/* -** This function is called when a transaction opened by the database -** handle associated with the VM passed as an argument is about to be -** committed. If there are outstanding deferred foreign key constraint -** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. -** -** If there are outstanding FK violations and this function returns -** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY -** and write an error message to it. Then return SQLITE_ERROR. -*/ -#ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ - sqlite3 *db = p->db; - if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) - || (!deferred && p->nFkConstraint>0) - ){ - p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; - p->errorAction = OE_Abort; - sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); - return SQLITE_ERROR; - } - return SQLITE_OK; -} -#endif - -/* -** This routine is called the when a VDBE tries to halt. If the VDBE -** has made changes and is in autocommit mode, then commit those -** changes. If a rollback is needed, then do the rollback. -** -** This routine is the only way to move the state of a VM from -** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to -** call this on a VM that is in the SQLITE_MAGIC_HALT state. -** -** Return an error code. If the commit could not complete because of -** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it -** means the close did not happen and needs to be repeated. -*/ -SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ - int rc; /* Used to store transient return codes */ - sqlite3 *db = p->db; - - /* This function contains the logic that determines if a statement or - ** transaction will be committed or rolled back as a result of the - ** execution of this virtual machine. - ** - ** If any of the following errors occur: - ** - ** SQLITE_NOMEM - ** SQLITE_IOERR - ** SQLITE_FULL - ** SQLITE_INTERRUPT - ** - ** Then the internal cache might have been left in an inconsistent - ** state. We need to rollback the statement transaction, if there is - ** one, or the complete transaction if there is no statement transaction. - */ - - if( db->mallocFailed ){ - p->rc = SQLITE_NOMEM_BKPT; - } - closeAllCursors(p); - if( p->magic!=VDBE_MAGIC_RUN ){ - return SQLITE_OK; - } - checkActiveVdbeCnt(db); - - /* No commit or rollback needed if the program never started or if the - ** SQL statement does not read or write a database file. */ - if( p->pc>=0 && p->bIsReader ){ - int mrc; /* Primary error code from p->rc */ - int eStatementOp = 0; - int isSpecialError; /* Set to true if a 'special' error */ - - /* Lock all btrees used by the statement */ - sqlite3VdbeEnter(p); - - /* Check for one of the special errors */ - mrc = p->rc & 0xff; - isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR - || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; - if( isSpecialError ){ - /* If the query was read-only and the error code is SQLITE_INTERRUPT, - ** no rollback is necessary. Otherwise, at least a savepoint - ** transaction must be rolled back to restore the database to a - ** consistent state. - ** - ** Even if the statement is read-only, it is important to perform - ** a statement or transaction rollback operation. If the error - ** occurred while writing to the journal, sub-journal or database - ** file as part of an effort to free up cache space (see function - ** pagerStress() in pager.c), the rollback is required to restore - ** the pager to a consistent state. - */ - if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ - if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ - eStatementOp = SAVEPOINT_ROLLBACK; - }else{ - /* We are forced to roll back the active transaction. Before doing - ** so, abort any other statements this handle currently has active. - */ - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - sqlite3CloseSavepoints(db); - db->autoCommit = 1; - p->nChange = 0; - } - } - } - - /* Check for immediate foreign key violations. */ - if( p->rc==SQLITE_OK ){ - sqlite3VdbeCheckFk(p, 0); - } - - /* If the auto-commit flag is set and this is the only active writer - ** VM, then we do either a commit or rollback of the current transaction. - ** - ** Note: This block also runs if one of the special errors handled - ** above has occurred. - */ - if( !sqlite3VtabInSync(db) - && db->autoCommit - && db->nVdbeWrite==(p->readOnly==0) - ){ - if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - rc = sqlite3VdbeCheckFk(p, 1); - if( rc!=SQLITE_OK ){ - if( NEVER(p->readOnly) ){ - sqlite3VdbeLeave(p); - return SQLITE_ERROR; - } - rc = SQLITE_CONSTRAINT_FOREIGNKEY; - }else{ - /* The auto-commit flag is true, the vdbe program was successful - ** or hit an 'OR FAIL' constraint and there are no deferred foreign - ** key constraints to hold up the transaction. This means a commit - ** is required. */ - rc = vdbeCommit(db, p); - } - if( rc==SQLITE_BUSY && p->readOnly ){ - sqlite3VdbeLeave(p); - return SQLITE_BUSY; - }else if( rc!=SQLITE_OK ){ - p->rc = rc; - sqlite3RollbackAll(db, SQLITE_OK); - p->nChange = 0; - }else{ - db->nDeferredCons = 0; - db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferFKs; - sqlite3CommitInternalChanges(db); - } - }else{ - sqlite3RollbackAll(db, SQLITE_OK); - p->nChange = 0; - } - db->nStatement = 0; - }else if( eStatementOp==0 ){ - if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ - eStatementOp = SAVEPOINT_RELEASE; - }else if( p->errorAction==OE_Abort ){ - eStatementOp = SAVEPOINT_ROLLBACK; - }else{ - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - sqlite3CloseSavepoints(db); - db->autoCommit = 1; - p->nChange = 0; - } - } - - /* If eStatementOp is non-zero, then a statement transaction needs to - ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to - ** do so. If this operation returns an error, and the current statement - ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the - ** current statement error code. - */ - if( eStatementOp ){ - rc = sqlite3VdbeCloseStatement(p, eStatementOp); - if( rc ){ - if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ - p->rc = rc; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; - } - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - sqlite3CloseSavepoints(db); - db->autoCommit = 1; - p->nChange = 0; - } - } - - /* If this was an INSERT, UPDATE or DELETE and no statement transaction - ** has been rolled back, update the database connection change-counter. - */ - if( p->changeCntOn ){ - if( eStatementOp!=SAVEPOINT_ROLLBACK ){ - sqlite3VdbeSetChanges(db, p->nChange); - }else{ - sqlite3VdbeSetChanges(db, 0); - } - p->nChange = 0; - } - - /* Release the locks */ - sqlite3VdbeLeave(p); - } - - /* We have successfully halted and closed the VM. Record this fact. */ - if( p->pc>=0 ){ - db->nVdbeActive--; - if( !p->readOnly ) db->nVdbeWrite--; - if( p->bIsReader ) db->nVdbeRead--; - assert( db->nVdbeActive>=db->nVdbeRead ); - assert( db->nVdbeRead>=db->nVdbeWrite ); - assert( db->nVdbeWrite>=0 ); - } - p->magic = VDBE_MAGIC_HALT; - checkActiveVdbeCnt(db); - if( db->mallocFailed ){ - p->rc = SQLITE_NOMEM_BKPT; - } - - /* If the auto-commit flag is set to true, then any locks that were held - ** by connection db have now been released. Call sqlite3ConnectionUnlocked() - ** to invoke any required unlock-notify callbacks. - */ - if( db->autoCommit ){ - sqlite3ConnectionUnlocked(db); - } - - assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); - return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); -} - - -/* -** Each VDBE holds the result of the most recent sqlite3_step() call -** in p->rc. This routine sets that result back to SQLITE_OK. -*/ -SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ - p->rc = SQLITE_OK; -} - -/* -** Copy the error code and error message belonging to the VDBE passed -** as the first argument to its database handle (so that they will be -** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). -** -** This function does not clear the VDBE error code or message, just -** copies them to the database handle. -*/ -SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ - sqlite3 *db = p->db; - int rc = p->rc; - if( p->zErrMsg ){ - db->bBenignMalloc++; - sqlite3BeginBenignMalloc(); - if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); - sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); - sqlite3EndBenignMalloc(); - db->bBenignMalloc--; - db->errCode = rc; - }else{ - sqlite3Error(db, rc); - } - return rc; -} - -#ifdef SQLITE_ENABLE_SQLLOG -/* -** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, -** invoke it. -*/ -static void vdbeInvokeSqllog(Vdbe *v){ - if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ - char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql); - assert( v->db->init.busy==0 ); - if( zExpanded ){ - sqlite3GlobalConfig.xSqllog( - sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 - ); - sqlite3DbFree(v->db, zExpanded); - } - } -} -#else -# define vdbeInvokeSqllog(x) -#endif - -/* -** Clean up a VDBE after execution but do not delete the VDBE just yet. -** Write any error messages into *pzErrMsg. Return the result code. -** -** After this routine is run, the VDBE should be ready to be executed -** again. -** -** To look at it another way, this routine resets the state of the -** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to -** VDBE_MAGIC_INIT. -*/ -SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ - sqlite3 *db; - db = p->db; - - /* If the VM did not run to completion or if it encountered an - ** error, then it might not have been halted properly. So halt - ** it now. - */ - sqlite3VdbeHalt(p); - - /* If the VDBE has be run even partially, then transfer the error code - ** and error message from the VDBE into the main database structure. But - ** if the VDBE has just been set to run but has not actually executed any - ** instructions yet, leave the main database error information unchanged. - */ - if( p->pc>=0 ){ - vdbeInvokeSqllog(p); - sqlite3VdbeTransferError(p); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; - if( p->runOnlyOnce ) p->expired = 1; - }else if( p->rc && p->expired ){ - /* The expired flag was set on the VDBE before the first call - ** to sqlite3_step(). For consistency (since sqlite3_step() was - ** called), set the database error in this case as well. - */ - sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = 0; - } - - /* Reclaim all memory used by the VDBE - */ - Cleanup(p); - - /* Save profiling information from this VDBE run. - */ -#ifdef VDBE_PROFILE - { - FILE *out = fopen("vdbe_profile.out", "a"); - if( out ){ - int i; - fprintf(out, "---- "); - for(i=0; inOp; i++){ - fprintf(out, "%02x", p->aOp[i].opcode); - } - fprintf(out, "\n"); - if( p->zSql ){ - char c, pc = 0; - fprintf(out, "-- "); - for(i=0; (c = p->zSql[i])!=0; i++){ - if( pc=='\n' ) fprintf(out, "-- "); - putc(c, out); - pc = c; - } - if( pc!='\n' ) fprintf(out, "\n"); - } - for(i=0; inOp; i++){ - char zHdr[100]; - sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", - p->aOp[i].cnt, - p->aOp[i].cycles, - p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 - ); - fprintf(out, "%s", zHdr); - sqlite3VdbePrintOp(out, i, &p->aOp[i]); - } - fclose(out); - } - } -#endif - p->iCurrentTime = 0; - p->magic = VDBE_MAGIC_RESET; - return p->rc & db->errMask; -} - -/* -** Clean up and delete a VDBE after execution. Return an integer which is -** the result code. Write any error message text into *pzErrMsg. -*/ -SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ - int rc = SQLITE_OK; - if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ - rc = sqlite3VdbeReset(p); - assert( (rc & p->db->errMask)==rc ); - } - sqlite3VdbeDelete(p); - return rc; -} - -/* -** If parameter iOp is less than zero, then invoke the destructor for -** all auxiliary data pointers currently cached by the VM passed as -** the first argument. -** -** Or, if iOp is greater than or equal to zero, then the destructor is -** only invoked for those auxiliary data pointers created by the user -** function invoked by the OP_Function opcode at instruction iOp of -** VM pVdbe, and only then if: -** -** * the associated function parameter is the 32nd or later (counting -** from left to right), or -** -** * the corresponding bit in argument mask is clear (where the first -** function parameter corresponds to bit 0 etc.). -*/ -SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ - while( *pp ){ - AuxData *pAux = *pp; - if( (iOp<0) - || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg)))) - ){ - testcase( pAux->iArg==31 ); - if( pAux->xDelete ){ - pAux->xDelete(pAux->pAux); - } - *pp = pAux->pNext; - sqlite3DbFree(db, pAux); - }else{ - pp= &pAux->pNext; - } - } -} - -/* -** Free all memory associated with the Vdbe passed as the second argument, -** except for object itself, which is preserved. -** -** The difference between this function and sqlite3VdbeDelete() is that -** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with -** the database connection and frees the object itself. -*/ -SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ - SubProgram *pSub, *pNext; - int i; - assert( p->db==0 || p->db==db ); - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - for(pSub=p->pProgram; pSub; pSub=pNext){ - pNext = pSub->pNext; - vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); - sqlite3DbFree(db, pSub); - } - if( p->magic!=VDBE_MAGIC_INIT ){ - releaseMemArray(p->aVar, p->nVar); - for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); - sqlite3DbFree(db, p->azVar); - sqlite3DbFree(db, p->pFree); - } - vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p->aColName); - sqlite3DbFree(db, p->zSql); -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - for(i=0; inScan; i++){ - sqlite3DbFree(db, p->aScan[i].zName); - } - sqlite3DbFree(db, p->aScan); -#endif -} - -/* -** Delete an entire VDBE. -*/ -SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ - sqlite3 *db; - - if( NEVER(p==0) ) return; - db = p->db; - assert( sqlite3_mutex_held(db->mutex) ); - sqlite3VdbeClearObject(db, p); - if( p->pPrev ){ - p->pPrev->pNext = p->pNext; - }else{ - assert( db->pVdbe==p ); - db->pVdbe = p->pNext; - } - if( p->pNext ){ - p->pNext->pPrev = p->pPrev; - } - p->magic = VDBE_MAGIC_DEAD; - p->db = 0; - sqlite3DbFree(db, p); -} - -/* -** The cursor "p" has a pending seek operation that has not yet been -** carried out. Seek the cursor now. If an error occurs, return -** the appropriate error code. -*/ -static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ - int res, rc; -#ifdef SQLITE_TEST - extern int sqlite3_search_count; -#endif - assert( p->deferredMoveto ); - assert( p->isTable ); - assert( p->eCurType==CURTYPE_BTREE ); - rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res); - if( rc ) return rc; - if( res!=0 ) return SQLITE_CORRUPT_BKPT; -#ifdef SQLITE_TEST - sqlite3_search_count++; -#endif - p->deferredMoveto = 0; - p->cacheStatus = CACHE_STALE; - return SQLITE_OK; -} - -/* -** Something has moved cursor "p" out of place. Maybe the row it was -** pointed to was deleted out from under it. Or maybe the btree was -** rebalanced. Whatever the cause, try to restore "p" to the place it -** is supposed to be pointing. If the row was deleted out from under the -** cursor, set the cursor to point to a NULL row. -*/ -static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ - int isDifferentRow, rc; - assert( p->eCurType==CURTYPE_BTREE ); - assert( p->uc.pCursor!=0 ); - assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); - rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); - p->cacheStatus = CACHE_STALE; - if( isDifferentRow ) p->nullRow = 1; - return rc; -} - -/* -** Check to ensure that the cursor is valid. Restore the cursor -** if need be. Return any I/O error from the restore operation. -*/ -SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ - assert( p->eCurType==CURTYPE_BTREE ); - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); - } - return SQLITE_OK; -} - -/* -** Make sure the cursor p is ready to read or write the row to which it -** was last positioned. Return an error code if an OOM fault or I/O error -** prevents us from positioning the cursor to its correct position. -** -** If a MoveTo operation is pending on the given cursor, then do that -** MoveTo now. If no move is pending, check to see if the row has been -** deleted out from under the cursor and if it has, mark the row as -** a NULL row. -** -** If the cursor is already pointing to the correct row and that row has -** not been deleted out from under the cursor, then this routine is a no-op. -*/ -SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ - VdbeCursor *p = *pp; - if( p->eCurType==CURTYPE_BTREE ){ - if( p->deferredMoveto ){ - int iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ - *pp = p->pAltCursor; - *piCol = iMap - 1; - return SQLITE_OK; - } - return handleDeferredMoveto(p); - } - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); - } - } - return SQLITE_OK; -} - -/* -** The following functions: -** -** sqlite3VdbeSerialType() -** sqlite3VdbeSerialTypeLen() -** sqlite3VdbeSerialLen() -** sqlite3VdbeSerialPut() -** sqlite3VdbeSerialGet() -** -** encapsulate the code that serializes values for storage in SQLite -** data and index records. Each serialized value consists of a -** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned -** integer, stored as a varint. -** -** In an SQLite index record, the serial type is stored directly before -** the blob of data that it corresponds to. In a table record, all serial -** types are stored at the start of the record, and the blobs of data at -** the end. Hence these functions allow the caller to handle the -** serial-type and data blob separately. -** -** The following table describes the various storage classes for data: -** -** serial type bytes of data type -** -------------- --------------- --------------- -** 0 0 NULL -** 1 1 signed integer -** 2 2 signed integer -** 3 3 signed integer -** 4 4 signed integer -** 5 6 signed integer -** 6 8 signed integer -** 7 8 IEEE float -** 8 0 Integer constant 0 -** 9 0 Integer constant 1 -** 10,11 reserved for expansion -** N>=12 and even (N-12)/2 BLOB -** N>=13 and odd (N-13)/2 text -** -** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions -** of SQLite will not understand those serial types. -*/ - -/* -** Return the serial-type for the value stored in pMem. -*/ -SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ - int flags = pMem->flags; - u32 n; - - assert( pLen!=0 ); - if( flags&MEM_Null ){ - *pLen = 0; - return 0; - } - if( flags&MEM_Int ){ - /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ -# define MAX_6BYTE ((((i64)0x00008000)<<32)-1) - i64 i = pMem->u.i; - u64 u; - if( i<0 ){ - u = ~i; - }else{ - u = i; - } - if( u<=127 ){ - if( (i&1)==i && file_format>=4 ){ - *pLen = 0; - return 8+(u32)u; - }else{ - *pLen = 1; - return 1; - } - } - if( u<=32767 ){ *pLen = 2; return 2; } - if( u<=8388607 ){ *pLen = 3; return 3; } - if( u<=2147483647 ){ *pLen = 4; return 4; } - if( u<=MAX_6BYTE ){ *pLen = 6; return 5; } - *pLen = 8; - return 6; - } - if( flags&MEM_Real ){ - *pLen = 8; - return 7; - } - assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); - assert( pMem->n>=0 ); - n = (u32)pMem->n; - if( flags & MEM_Zero ){ - n += pMem->u.nZero; - } - *pLen = n; - return ((n*2) + 12 + ((flags&MEM_Str)!=0)); -} - -/* -** The sizes for serial types less than 128 -*/ -static const u8 sqlite3SmallTypeSizes[] = { - /* 0 1 2 3 4 5 6 7 8 9 */ -/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, -/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, -/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, -/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, -/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, -/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, -/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, -/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, -/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, -/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, -/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, -/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, -/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57 -}; - -/* -** Return the length of the data corresponding to the supplied serial-type. -*/ -SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ - if( serial_type>=128 ){ - return (serial_type-12)/2; - }else{ - assert( serial_type<12 - || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); - return sqlite3SmallTypeSizes[serial_type]; - } -} -SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ - assert( serial_type<128 ); - return sqlite3SmallTypeSizes[serial_type]; -} - -/* -** If we are on an architecture with mixed-endian floating -** points (ex: ARM7) then swap the lower 4 bytes with the -** upper 4 bytes. Return the result. -** -** For most architectures, this is a no-op. -** -** (later): It is reported to me that the mixed-endian problem -** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems -** that early versions of GCC stored the two words of a 64-bit -** float in the wrong order. And that error has been propagated -** ever since. The blame is not necessarily with GCC, though. -** GCC might have just copying the problem from a prior compiler. -** I am also told that newer versions of GCC that follow a different -** ABI get the byte order right. -** -** Developers using SQLite on an ARM7 should compile and run their -** application using -DSQLITE_DEBUG=1 at least once. With DEBUG -** enabled, some asserts below will ensure that the byte order of -** floating point values is correct. -** -** (2007-08-30) Frank van Vugt has studied this problem closely -** and has send his findings to the SQLite developers. Frank -** writes that some Linux kernels offer floating point hardware -** emulation that uses only 32-bit mantissas instead of a full -** 48-bits as required by the IEEE standard. (This is the -** CONFIG_FPE_FASTFPE option.) On such systems, floating point -** byte swapping becomes very complicated. To avoid problems, -** the necessary byte swapping is carried out using a 64-bit integer -** rather than a 64-bit float. Frank assures us that the code here -** works for him. We, the developers, have no way to independently -** verify this, but Frank seems to know what he is talking about -** so we trust him. -*/ -#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -static u64 floatSwap(u64 in){ - union { - u64 r; - u32 i[2]; - } u; - u32 t; - - u.r = in; - t = u.i[0]; - u.i[0] = u.i[1]; - u.i[1] = t; - return u.r; -} -# define swapMixedEndianFloat(X) X = floatSwap(X) -#else -# define swapMixedEndianFloat(X) -#endif - -/* -** Write the serialized data blob for the value stored in pMem into -** buf. It is assumed that the caller has allocated sufficient space. -** Return the number of bytes written. -** -** nBuf is the amount of space left in buf[]. The caller is responsible -** for allocating enough space to buf[] to hold the entire field, exclusive -** of the pMem->u.nZero bytes for a MEM_Zero value. -** -** Return the number of bytes actually written into buf[]. The number -** of bytes in the zero-filled tail is included in the return value only -** if those bytes were zeroed in buf[]. -*/ -SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ - u32 len; - - /* Integer and Real */ - if( serial_type<=7 && serial_type>0 ){ - u64 v; - u32 i; - if( serial_type==7 ){ - assert( sizeof(v)==sizeof(pMem->u.r) ); - memcpy(&v, &pMem->u.r, sizeof(v)); - swapMixedEndianFloat(v); - }else{ - v = pMem->u.i; - } - len = i = sqlite3SmallTypeSizes[serial_type]; - assert( i>0 ); - do{ - buf[--i] = (u8)(v&0xFF); - v >>= 8; - }while( i ); - return len; - } - - /* String or blob */ - if( serial_type>=12 ){ - assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) - == (int)sqlite3VdbeSerialTypeLen(serial_type) ); - len = pMem->n; - if( len>0 ) memcpy(buf, pMem->z, len); - return len; - } - - /* NULL or constants 0 or 1 */ - return 0; -} - -/* Input "x" is a sequence of unsigned characters that represent a -** big-endian integer. Return the equivalent native integer -*/ -#define ONE_BYTE_INT(x) ((i8)(x)[0]) -#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) -#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) -#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) -#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) - -/* -** Deserialize the data blob pointed to by buf as serial type serial_type -** and store the result in pMem. Return the number of bytes read. -** -** This function is implemented as two separate routines for performance. -** The few cases that require local variables are broken out into a separate -** routine so that in most cases the overhead of moving the stack pointer -** is avoided. -*/ -static u32 SQLITE_NOINLINE serialGet( - const unsigned char *buf, /* Buffer to deserialize from */ - u32 serial_type, /* Serial type to deserialize */ - Mem *pMem /* Memory cell to write value into */ -){ - u64 x = FOUR_BYTE_UINT(buf); - u32 y = FOUR_BYTE_UINT(buf+4); - x = (x<<32) + y; - if( serial_type==6 ){ - /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit - ** twos-complement integer. */ - pMem->u.i = *(i64*)&x; - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - }else{ - /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit - ** floating point number. */ -#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) - /* Verify that integers and floating point values use the same - ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is - ** defined that 64-bit floating point values really are mixed - ** endian. - */ - static const u64 t1 = ((u64)0x3ff00000)<<32; - static const double r1 = 1.0; - u64 t2 = t1; - swapMixedEndianFloat(t2); - assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); -#endif - assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); - swapMixedEndianFloat(x); - memcpy(&pMem->u.r, &x, sizeof(x)); - pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real; - } - return 8; -} -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( - const unsigned char *buf, /* Buffer to deserialize from */ - u32 serial_type, /* Serial type to deserialize */ - Mem *pMem /* Memory cell to write value into */ -){ - switch( serial_type ){ - case 10: /* Reserved for future use */ - case 11: /* Reserved for future use */ - case 0: { /* Null */ - /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ - pMem->flags = MEM_Null; - break; - } - case 1: { - /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement - ** integer. */ - pMem->u.i = ONE_BYTE_INT(buf); - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - return 1; - } - case 2: { /* 2-byte signed integer */ - /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit - ** twos-complement integer. */ - pMem->u.i = TWO_BYTE_INT(buf); - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - return 2; - } - case 3: { /* 3-byte signed integer */ - /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit - ** twos-complement integer. */ - pMem->u.i = THREE_BYTE_INT(buf); - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - return 3; - } - case 4: { /* 4-byte signed integer */ - /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit - ** twos-complement integer. */ - pMem->u.i = FOUR_BYTE_INT(buf); -#ifdef __HP_cc - /* Work around a sign-extension bug in the HP compiler for HP/UX */ - if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL; -#endif - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - return 4; - } - case 5: { /* 6-byte signed integer */ - /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit - ** twos-complement integer. */ - pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - return 6; - } - case 6: /* 8-byte signed integer */ - case 7: { /* IEEE floating point */ - /* These use local variables, so do them in a separate routine - ** to avoid having to move the frame pointer in the common case */ - return serialGet(buf,serial_type,pMem); - } - case 8: /* Integer 0 */ - case 9: { /* Integer 1 */ - /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */ - /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ - pMem->u.i = serial_type-8; - pMem->flags = MEM_Int; - return 0; - } - default: { - /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in - ** length. - ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and - ** (N-13)/2 bytes in length. */ - static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; - pMem->z = (char *)buf; - pMem->n = (serial_type-12)/2; - pMem->flags = aFlag[serial_type&1]; - return pMem->n; - } - } - return 0; -} -/* -** This routine is used to allocate sufficient space for an UnpackedRecord -** structure large enough to be used with sqlite3VdbeRecordUnpack() if -** the first argument is a pointer to KeyInfo structure pKeyInfo. -** -** The space is either allocated using sqlite3DbMallocRaw() or from within -** the unaligned buffer passed via the second and third arguments (presumably -** stack space). If the former, then *ppFree is set to a pointer that should -** be eventually freed by the caller using sqlite3DbFree(). Or, if the -** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL -** before returning. -** -** If an OOM error occurs, NULL is returned. -*/ -SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( - KeyInfo *pKeyInfo, /* Description of the record */ - char *pSpace, /* Unaligned space available */ - int szSpace, /* Size of pSpace[] in bytes */ - char **ppFree /* OUT: Caller should free this pointer */ -){ - UnpackedRecord *p; /* Unpacked record to return */ - int nOff; /* Increment pSpace by nOff to align it */ - int nByte; /* Number of bytes required for *p */ - - /* We want to shift the pointer pSpace up such that it is 8-byte aligned. - ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift - ** it by. If pSpace is already 8-byte aligned, nOff should be zero. - */ - nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7; - nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1); - if( nByte>szSpace+nOff ){ - p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); - *ppFree = (char *)p; - if( !p ) return 0; - }else{ - p = (UnpackedRecord*)&pSpace[nOff]; - *ppFree = 0; - } - - p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; - assert( pKeyInfo->aSortOrder!=0 ); - p->pKeyInfo = pKeyInfo; - p->nField = pKeyInfo->nField + 1; - return p; -} - -/* -** Given the nKey-byte encoding of a record in pKey[], populate the -** UnpackedRecord structure indicated by the fourth argument with the -** contents of the decoded record. -*/ -SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( - KeyInfo *pKeyInfo, /* Information about the record format */ - int nKey, /* Size of the binary record */ - const void *pKey, /* The binary record */ - UnpackedRecord *p /* Populate this structure before returning. */ -){ - const unsigned char *aKey = (const unsigned char *)pKey; - int d; - u32 idx; /* Offset in aKey[] to read from */ - u16 u; /* Unsigned loop counter */ - u32 szHdr; - Mem *pMem = p->aMem; - - p->default_rc = 0; - assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - idx = getVarint32(aKey, szHdr); - d = szHdr; - u = 0; - while( idxenc = pKeyInfo->enc; - pMem->db = pKeyInfo->db; - /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ - pMem->szMalloc = 0; - pMem->z = 0; - d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); - pMem++; - if( (++u)>=p->nField ) break; - } - assert( u<=pKeyInfo->nField + 1 ); - p->nField = u; -} - -#if SQLITE_DEBUG -/* -** This function compares two index or table record keys in the same way -** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), -** this function deserializes and compares values using the -** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used -** in assert() statements to ensure that the optimized code in -** sqlite3VdbeRecordCompare() returns results with these two primitives. -** -** Return true if the result of comparison is equivalent to desiredResult. -** Return false if there is a disagreement. -*/ -static int vdbeRecordCompareDebug( - int nKey1, const void *pKey1, /* Left key */ - const UnpackedRecord *pPKey2, /* Right key */ - int desiredResult /* Correct answer */ -){ - u32 d1; /* Offset into aKey[] of next data element */ - u32 idx1; /* Offset into aKey[] of next header element */ - u32 szHdr1; /* Number of bytes in header */ - int i = 0; - int rc = 0; - const unsigned char *aKey1 = (const unsigned char *)pKey1; - KeyInfo *pKeyInfo; - Mem mem1; - - pKeyInfo = pPKey2->pKeyInfo; - if( pKeyInfo->db==0 ) return 1; - mem1.enc = pKeyInfo->enc; - mem1.db = pKeyInfo->db; - /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ - VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ - - /* Compilers may complain that mem1.u.i is potentially uninitialized. - ** We could initialize it, as shown here, to silence those complaints. - ** But in fact, mem1.u.i will never actually be used uninitialized, and doing - ** the unnecessary initialization has a measurable negative performance - ** impact, since this routine is a very high runner. And so, we choose - ** to ignore the compiler warnings and leave this variable uninitialized. - */ - /* mem1.u.i = 0; // not needed, here to silence compiler warning */ - - idx1 = getVarint32(aKey1, szHdr1); - if( szHdr1>98307 ) return SQLITE_CORRUPT; - d1 = szHdr1; - assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); - assert( pKeyInfo->aSortOrder!=0 ); - assert( pKeyInfo->nField>0 ); - assert( idx1<=szHdr1 || CORRUPT_DB ); - do{ - u32 serial_type1; - - /* Read the serial types for the next element in each key. */ - idx1 += getVarint32( aKey1+idx1, serial_type1 ); - - /* Verify that there is enough key space remaining to avoid - ** a buffer overread. The "d1+serial_type1+2" subexpression will - ** always be greater than or equal to the amount of required key space. - ** Use that approximation to avoid the more expensive call to - ** sqlite3VdbeSerialTypeLen() in the common case. - */ - if( d1+serial_type1+2>(u32)nKey1 - && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 - ){ - break; - } - - /* Extract the values to be compared. - */ - d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); - - /* Do the comparison - */ - rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]); - if( rc!=0 ){ - assert( mem1.szMalloc==0 ); /* See comment below */ - if( pKeyInfo->aSortOrder[i] ){ - rc = -rc; /* Invert the result for DESC sort order. */ - } - goto debugCompareEnd; - } - i++; - }while( idx1nField ); - - /* No memory allocation is ever used on mem1. Prove this using - ** the following assert(). If the assert() fails, it indicates a - ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). - */ - assert( mem1.szMalloc==0 ); - - /* rc==0 here means that one of the keys ran out of fields and - ** all the fields up to that point were equal. Return the default_rc - ** value. */ - rc = pPKey2->default_rc; - -debugCompareEnd: - if( desiredResult==0 && rc==0 ) return 1; - if( desiredResult<0 && rc<0 ) return 1; - if( desiredResult>0 && rc>0 ) return 1; - if( CORRUPT_DB ) return 1; - if( pKeyInfo->db->mallocFailed ) return 1; - return 0; -} -#endif - -#if SQLITE_DEBUG -/* -** Count the number of fields (a.k.a. columns) in the record given by -** pKey,nKey. The verify that this count is less than or equal to the -** limit given by pKeyInfo->nField + pKeyInfo->nXField. -** -** If this constraint is not satisfied, it means that the high-speed -** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will -** not work correctly. If this assert() ever fires, it probably means -** that the KeyInfo.nField or KeyInfo.nXField values were computed -** incorrectly. -*/ -static void vdbeAssertFieldCountWithinLimits( - int nKey, const void *pKey, /* The record to verify */ - const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */ -){ - int nField = 0; - u32 szHdr; - u32 idx; - u32 notUsed; - const unsigned char *aKey = (const unsigned char*)pKey; - - if( CORRUPT_DB ) return; - idx = getVarint32(aKey, szHdr); - assert( nKey>=0 ); - assert( szHdr<=(u32)nKey ); - while( idxnField+pKeyInfo->nXField ); -} -#else -# define vdbeAssertFieldCountWithinLimits(A,B,C) -#endif - -/* -** Both *pMem1 and *pMem2 contain string values. Compare the two values -** using the collation sequence pColl. As usual, return a negative , zero -** or positive value if *pMem1 is less than, equal to or greater than -** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". -*/ -static int vdbeCompareMemString( - const Mem *pMem1, - const Mem *pMem2, - const CollSeq *pColl, - u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ -){ - if( pMem1->enc==pColl->enc ){ - /* The strings are already in the correct encoding. Call the - ** comparison function directly */ - return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); - }else{ - int rc; - const void *v1, *v2; - int n1, n2; - Mem c1; - Mem c2; - sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); - sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); - sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); - sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); - v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); - n1 = v1==0 ? 0 : c1.n; - v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); - n2 = v2==0 ? 0 : c2.n; - rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2); - if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM_BKPT; - sqlite3VdbeMemRelease(&c1); - sqlite3VdbeMemRelease(&c2); - return rc; - } -} - -/* -** The input pBlob is guaranteed to be a Blob that is not marked -** with MEM_Zero. Return true if it could be a zero-blob. -*/ -static int isAllZero(const char *z, int n){ - int i; - for(i=0; in; - int n2 = pB2->n; - - /* It is possible to have a Blob value that has some non-zero content - ** followed by zero content. But that only comes up for Blobs formed - ** by the OP_MakeRecord opcode, and such Blobs never get passed into - ** sqlite3MemCompare(). */ - assert( (pB1->flags & MEM_Zero)==0 || n1==0 ); - assert( (pB2->flags & MEM_Zero)==0 || n2==0 ); - - if( (pB1->flags|pB2->flags) & MEM_Zero ){ - if( pB1->flags & pB2->flags & MEM_Zero ){ - return pB1->u.nZero - pB2->u.nZero; - }else if( pB1->flags & MEM_Zero ){ - if( !isAllZero(pB2->z, pB2->n) ) return -1; - return pB1->u.nZero - n2; - }else{ - if( !isAllZero(pB1->z, pB1->n) ) return +1; - return n1 - pB2->u.nZero; - } - } - c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1); - if( c ) return c; - return n1 - n2; -} - -/* -** Do a comparison between a 64-bit signed integer and a 64-bit floating-point -** number. Return negative, zero, or positive if the first (i64) is less than, -** equal to, or greater than the second (double). -*/ -static int sqlite3IntFloatCompare(i64 i, double r){ - if( sizeof(LONGDOUBLE_TYPE)>8 ){ - LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; - if( xr ) return +1; - return 0; - }else{ - i64 y; - double s; - if( r<-9223372036854775808.0 ) return +1; - if( r>9223372036854775807.0 ) return -1; - y = (i64)r; - if( iy ){ - if( y==SMALLEST_INT64 && r>0.0 ) return -1; - return +1; - } - s = (double)i; - if( sr ) return +1; - return 0; - } -} - -/* -** Compare the values contained by the two memory cells, returning -** negative, zero or positive if pMem1 is less than, equal to, or greater -** than pMem2. Sorting order is NULL's first, followed by numbers (integers -** and reals) sorted numerically, followed by text ordered by the collating -** sequence pColl and finally blob's ordered by memcmp(). -** -** Two NULL values are considered equal by this function. -*/ -SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ - int f1, f2; - int combined_flags; - - f1 = pMem1->flags; - f2 = pMem2->flags; - combined_flags = f1|f2; - assert( (combined_flags & MEM_RowSet)==0 ); - - /* If one value is NULL, it is less than the other. If both values - ** are NULL, return 0. - */ - if( combined_flags&MEM_Null ){ - return (f2&MEM_Null) - (f1&MEM_Null); - } - - /* At least one of the two values is a number - */ - if( combined_flags&(MEM_Int|MEM_Real) ){ - if( (f1 & f2 & MEM_Int)!=0 ){ - if( pMem1->u.i < pMem2->u.i ) return -1; - if( pMem1->u.i > pMem2->u.i ) return +1; - return 0; - } - if( (f1 & f2 & MEM_Real)!=0 ){ - if( pMem1->u.r < pMem2->u.r ) return -1; - if( pMem1->u.r > pMem2->u.r ) return +1; - return 0; - } - if( (f1&MEM_Int)!=0 ){ - if( (f2&MEM_Real)!=0 ){ - return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); - }else{ - return -1; - } - } - if( (f1&MEM_Real)!=0 ){ - if( (f2&MEM_Int)!=0 ){ - return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); - }else{ - return -1; - } - } - return +1; - } - - /* If one value is a string and the other is a blob, the string is less. - ** If both are strings, compare using the collating functions. - */ - if( combined_flags&MEM_Str ){ - if( (f1 & MEM_Str)==0 ){ - return 1; - } - if( (f2 & MEM_Str)==0 ){ - return -1; - } - - assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed ); - assert( pMem1->enc==SQLITE_UTF8 || - pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); - - /* The collation sequence must be defined at this point, even if - ** the user deletes the collation sequence after the vdbe program is - ** compiled (this was not always the case). - */ - assert( !pColl || pColl->xCmp ); - - if( pColl ){ - return vdbeCompareMemString(pMem1, pMem2, pColl, 0); - } - /* If a NULL pointer was passed as the collate function, fall through - ** to the blob case and use memcmp(). */ - } - - /* Both values must be blobs. Compare using memcmp(). */ - return sqlite3BlobCompare(pMem1, pMem2); -} - - -/* -** The first argument passed to this function is a serial-type that -** corresponds to an integer - all values between 1 and 9 inclusive -** except 7. The second points to a buffer containing an integer value -** serialized according to serial_type. This function deserializes -** and returns the value. -*/ -static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ - u32 y; - assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) ); - switch( serial_type ){ - case 0: - case 1: - testcase( aKey[0]&0x80 ); - return ONE_BYTE_INT(aKey); - case 2: - testcase( aKey[0]&0x80 ); - return TWO_BYTE_INT(aKey); - case 3: - testcase( aKey[0]&0x80 ); - return THREE_BYTE_INT(aKey); - case 4: { - testcase( aKey[0]&0x80 ); - y = FOUR_BYTE_UINT(aKey); - return (i64)*(int*)&y; - } - case 5: { - testcase( aKey[0]&0x80 ); - return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); - } - case 6: { - u64 x = FOUR_BYTE_UINT(aKey); - testcase( aKey[0]&0x80 ); - x = (x<<32) | FOUR_BYTE_UINT(aKey+4); - return (i64)*(i64*)&x; - } - } - - return (serial_type - 8); -} - -/* -** This function compares the two table rows or index records -** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero -** or positive integer if key1 is less than, equal to or -** greater than key2. The {nKey1, pKey1} key must be a blob -** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 -** key must be a parsed key such as obtained from -** sqlite3VdbeParseRecord. -** -** If argument bSkip is non-zero, it is assumed that the caller has already -** determined that the first fields of the keys are equal. -** -** Key1 and Key2 do not have to contain the same number of fields. If all -** fields that appear in both keys are equal, then pPKey2->default_rc is -** returned. -** -** If database corruption is discovered, set pPKey2->errCode to -** SQLITE_CORRUPT and return 0. If an OOM error is encountered, -** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the -** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). -*/ -SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( - int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2, /* Right key */ - int bSkip /* If true, skip the first field */ -){ - u32 d1; /* Offset into aKey[] of next data element */ - int i; /* Index of next field to compare */ - u32 szHdr1; /* Size of record header in bytes */ - u32 idx1; /* Offset of first type in header */ - int rc = 0; /* Return value */ - Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ - KeyInfo *pKeyInfo = pPKey2->pKeyInfo; - const unsigned char *aKey1 = (const unsigned char *)pKey1; - Mem mem1; - - /* If bSkip is true, then the caller has already determined that the first - ** two elements in the keys are equal. Fix the various stack variables so - ** that this routine begins comparing at the second field. */ - if( bSkip ){ - u32 s1; - idx1 = 1 + getVarint32(&aKey1[1], s1); - szHdr1 = aKey1[0]; - d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); - i = 1; - pRhs++; - }else{ - idx1 = getVarint32(aKey1, szHdr1); - d1 = szHdr1; - if( d1>(unsigned)nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ - } - i = 0; - } - - VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ - assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField - || CORRUPT_DB ); - assert( pPKey2->pKeyInfo->aSortOrder!=0 ); - assert( pPKey2->pKeyInfo->nField>0 ); - assert( idx1<=szHdr1 || CORRUPT_DB ); - do{ - u32 serial_type; - - /* RHS is an integer */ - if( pRhs->flags & MEM_Int ){ - serial_type = aKey1[idx1]; - testcase( serial_type==12 ); - if( serial_type>=10 ){ - rc = +1; - }else if( serial_type==0 ){ - rc = -1; - }else if( serial_type==7 ){ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); - rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); - }else{ - i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); - i64 rhs = pRhs->u.i; - if( lhsrhs ){ - rc = +1; - } - } - } - - /* RHS is real */ - else if( pRhs->flags & MEM_Real ){ - serial_type = aKey1[idx1]; - if( serial_type>=10 ){ - /* Serial types 12 or greater are strings and blobs (greater than - ** numbers). Types 10 and 11 are currently "reserved for future - ** use", so it doesn't really matter what the results of comparing - ** them to numberic values are. */ - rc = +1; - }else if( serial_type==0 ){ - rc = -1; - }else{ - sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); - if( serial_type==7 ){ - if( mem1.u.ru.r ){ - rc = -1; - }else if( mem1.u.r>pRhs->u.r ){ - rc = +1; - } - }else{ - rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); - } - } - } - - /* RHS is a string */ - else if( pRhs->flags & MEM_Str ){ - getVarint32(&aKey1[idx1], serial_type); - testcase( serial_type==12 ); - if( serial_type<12 ){ - rc = -1; - }else if( !(serial_type & 0x01) ){ - rc = +1; - }else{ - mem1.n = (serial_type - 12) / 2; - testcase( (d1+mem1.n)==(unsigned)nKey1 ); - testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); - if( (d1+mem1.n) > (unsigned)nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ - }else if( pKeyInfo->aColl[i] ){ - mem1.enc = pKeyInfo->enc; - mem1.db = pKeyInfo->db; - mem1.flags = MEM_Str; - mem1.z = (char*)&aKey1[d1]; - rc = vdbeCompareMemString( - &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode - ); - }else{ - int nCmp = MIN(mem1.n, pRhs->n); - rc = memcmp(&aKey1[d1], pRhs->z, nCmp); - if( rc==0 ) rc = mem1.n - pRhs->n; - } - } - } - - /* RHS is a blob */ - else if( pRhs->flags & MEM_Blob ){ - assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 ); - getVarint32(&aKey1[idx1], serial_type); - testcase( serial_type==12 ); - if( serial_type<12 || (serial_type & 0x01) ){ - rc = -1; - }else{ - int nStr = (serial_type - 12) / 2; - testcase( (d1+nStr)==(unsigned)nKey1 ); - testcase( (d1+nStr+1)==(unsigned)nKey1 ); - if( (d1+nStr) > (unsigned)nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ - }else if( pRhs->flags & MEM_Zero ){ - if( !isAllZero((const char*)&aKey1[d1],nStr) ){ - rc = 1; - }else{ - rc = nStr - pRhs->u.nZero; - } - }else{ - int nCmp = MIN(nStr, pRhs->n); - rc = memcmp(&aKey1[d1], pRhs->z, nCmp); - if( rc==0 ) rc = nStr - pRhs->n; - } - } - } - - /* RHS is null */ - else{ - serial_type = aKey1[idx1]; - rc = (serial_type!=0); - } - - if( rc!=0 ){ - if( pKeyInfo->aSortOrder[i] ){ - rc = -rc; - } - assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); - assert( mem1.szMalloc==0 ); /* See comment below */ - return rc; - } - - i++; - pRhs++; - d1 += sqlite3VdbeSerialTypeLen(serial_type); - idx1 += sqlite3VarintLen(serial_type); - }while( idx1<(unsigned)szHdr1 && inField && d1<=(unsigned)nKey1 ); - - /* No memory allocation is ever used on mem1. Prove this using - ** the following assert(). If the assert() fails, it indicates a - ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ - assert( mem1.szMalloc==0 ); - - /* rc==0 here means that one or both of the keys ran out of fields and - ** all the fields up to that point were equal. Return the default_rc - ** value. */ - assert( CORRUPT_DB - || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) - || pKeyInfo->db->mallocFailed - ); - pPKey2->eqSeen = 1; - return pPKey2->default_rc; -} -SQLITE_PRIVATE int sqlite3VdbeRecordCompare( - int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2 /* Right key */ -){ - return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); -} - - -/* -** This function is an optimized version of sqlite3VdbeRecordCompare() -** that (a) the first field of pPKey2 is an integer, and (b) the -** size-of-header varint at the start of (pKey1/nKey1) fits in a single -** byte (i.e. is less than 128). -** -** To avoid concerns about buffer overreads, this routine is only used -** on schemas where the maximum valid header size is 63 bytes or less. -*/ -static int vdbeRecordCompareInt( - int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2 /* Right key */ -){ - const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; - int serial_type = ((const u8*)pKey1)[1]; - int res; - u32 y; - u64 x; - i64 v; - i64 lhs; - - vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); - assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); - switch( serial_type ){ - case 1: { /* 1-byte signed integer */ - lhs = ONE_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 2: { /* 2-byte signed integer */ - lhs = TWO_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 3: { /* 3-byte signed integer */ - lhs = THREE_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 4: { /* 4-byte signed integer */ - y = FOUR_BYTE_UINT(aKey); - lhs = (i64)*(int*)&y; - testcase( lhs<0 ); - break; - } - case 5: { /* 6-byte signed integer */ - lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 6: { /* 8-byte signed integer */ - x = FOUR_BYTE_UINT(aKey); - x = (x<<32) | FOUR_BYTE_UINT(aKey+4); - lhs = *(i64*)&x; - testcase( lhs<0 ); - break; - } - case 8: - lhs = 0; - break; - case 9: - lhs = 1; - break; - - /* This case could be removed without changing the results of running - ** this code. Including it causes gcc to generate a faster switch - ** statement (since the range of switch targets now starts at zero and - ** is contiguous) but does not cause any duplicate code to be generated - ** (as gcc is clever enough to combine the two like cases). Other - ** compilers might be similar. */ - case 0: case 7: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); - - default: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); - } - - v = pPKey2->aMem[0].u.i; - if( v>lhs ){ - res = pPKey2->r1; - }else if( vr2; - }else if( pPKey2->nField>1 ){ - /* The first fields of the two keys are equal. Compare the trailing - ** fields. */ - res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); - }else{ - /* The first fields of the two keys are equal and there are no trailing - ** fields. Return pPKey2->default_rc in this case. */ - res = pPKey2->default_rc; - pPKey2->eqSeen = 1; - } - - assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) ); - return res; -} - -/* -** This function is an optimized version of sqlite3VdbeRecordCompare() -** that (a) the first field of pPKey2 is a string, that (b) the first field -** uses the collation sequence BINARY and (c) that the size-of-header varint -** at the start of (pKey1/nKey1) fits in a single byte. -*/ -static int vdbeRecordCompareString( - int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2 /* Right key */ -){ - const u8 *aKey1 = (const u8*)pKey1; - int serial_type; - int res; - - assert( pPKey2->aMem[0].flags & MEM_Str ); - vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); - getVarint32(&aKey1[1], serial_type); - if( serial_type<12 ){ - res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ - }else if( !(serial_type & 0x01) ){ - res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ - }else{ - int nCmp; - int nStr; - int szHdr = aKey1[0]; - - nStr = (serial_type-12) / 2; - if( (szHdr + nStr) > nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ - } - nCmp = MIN( pPKey2->aMem[0].n, nStr ); - res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp); - - if( res==0 ){ - res = nStr - pPKey2->aMem[0].n; - if( res==0 ){ - if( pPKey2->nField>1 ){ - res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); - }else{ - res = pPKey2->default_rc; - pPKey2->eqSeen = 1; - } - }else if( res>0 ){ - res = pPKey2->r2; - }else{ - res = pPKey2->r1; - } - }else if( res>0 ){ - res = pPKey2->r2; - }else{ - res = pPKey2->r1; - } - } - - assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) - || CORRUPT_DB - || pPKey2->pKeyInfo->db->mallocFailed - ); - return res; -} - -/* -** Return a pointer to an sqlite3VdbeRecordCompare() compatible function -** suitable for comparing serialized records to the unpacked record passed -** as the only argument. -*/ -SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ - /* varintRecordCompareInt() and varintRecordCompareString() both assume - ** that the size-of-header varint that occurs at the start of each record - ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() - ** also assumes that it is safe to overread a buffer by at least the - ** maximum possible legal header size plus 8 bytes. Because there is - ** guaranteed to be at least 74 (but not 136) bytes of padding following each - ** buffer passed to varintRecordCompareInt() this makes it convenient to - ** limit the size of the header to 64 bytes in cases where the first field - ** is an integer. - ** - ** The easiest way to enforce this limit is to consider only records with - ** 13 fields or less. If the first field is an integer, the maximum legal - ** header size is (12*5 + 1 + 1) bytes. */ - if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){ - int flags = p->aMem[0].flags; - if( p->pKeyInfo->aSortOrder[0] ){ - p->r1 = 1; - p->r2 = -1; - }else{ - p->r1 = -1; - p->r2 = 1; - } - if( (flags & MEM_Int) ){ - return vdbeRecordCompareInt; - } - testcase( flags & MEM_Real ); - testcase( flags & MEM_Null ); - testcase( flags & MEM_Blob ); - if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ - assert( flags & MEM_Str ); - return vdbeRecordCompareString; - } - } - - return sqlite3VdbeRecordCompare; -} - -/* -** pCur points at an index entry created using the OP_MakeRecord opcode. -** Read the rowid (the last field in the record) and store it in *rowid. -** Return SQLITE_OK if everything works, or an error code otherwise. -** -** pCur might be pointing to text obtained from a corrupt database file. -** So the content cannot be trusted. Do appropriate checks on the content. -*/ -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ - i64 nCellKey = 0; - int rc; - u32 szHdr; /* Size of the header */ - u32 typeRowid; /* Serial type of the rowid */ - u32 lenRowid; /* Size of the rowid */ - Mem m, v; - - /* Get the size of the index entry. Only indices entries of less - ** than 2GiB are support - anything large must be database corruption. - ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so - ** this code can safely assume that nCellKey is 32-bits - */ - assert( sqlite3BtreeCursorIsValid(pCur) ); - nCellKey = sqlite3BtreePayloadSize(pCur); - assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); - - /* Read in the complete content of the index entry */ - sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); - if( rc ){ - return rc; - } - - /* The index entry must begin with a header size */ - (void)getVarint32((u8*)m.z, szHdr); - testcase( szHdr==3 ); - testcase( szHdr==m.n ); - if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ - goto idx_rowid_corruption; - } - - /* The last field of the index should be an integer - the ROWID. - ** Verify that the last entry really is an integer. */ - (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid); - testcase( typeRowid==1 ); - testcase( typeRowid==2 ); - testcase( typeRowid==3 ); - testcase( typeRowid==4 ); - testcase( typeRowid==5 ); - testcase( typeRowid==6 ); - testcase( typeRowid==8 ); - testcase( typeRowid==9 ); - if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ - goto idx_rowid_corruption; - } - lenRowid = sqlite3SmallTypeSizes[typeRowid]; - testcase( (u32)m.n==szHdr+lenRowid ); - if( unlikely((u32)m.neCurType==CURTYPE_BTREE ); - pCur = pC->uc.pCursor; - assert( sqlite3BtreeCursorIsValid(pCur) ); - nCellKey = sqlite3BtreePayloadSize(pCur); - /* nCellKey will always be between 0 and 0xffffffff because of the way - ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ - if( nCellKey<=0 || nCellKey>0x7fffffff ){ - *res = 0; - return SQLITE_CORRUPT_BKPT; - } - sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); - if( rc ){ - return rc; - } - *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); - sqlite3VdbeMemRelease(&m); - return SQLITE_OK; -} - -/* -** This routine sets the value to be returned by subsequent calls to -** sqlite3_changes() on the database handle 'db'. -*/ -SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ - assert( sqlite3_mutex_held(db->mutex) ); - db->nChange = nChange; - db->nTotalChange += nChange; -} - -/* -** Set a flag in the vdbe to update the change counter when it is finalised -** or reset. -*/ -SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ - v->changeCntOn = 1; -} - -/* -** Mark every prepared statement associated with a database connection -** as expired. -** -** An expired statement means that recompilation of the statement is -** recommend. Statements expire when things happen that make their -** programs obsolete. Removing user-defined functions or collating -** sequences, or changing an authorization function are the types of -** things that make prepared statements obsolete. -*/ -SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){ - Vdbe *p; - for(p = db->pVdbe; p; p=p->pNext){ - p->expired = 1; - } -} - -/* -** Return the database associated with the Vdbe. -*/ -SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ - return v->db; -} - -/* -** Return a pointer to an sqlite3_value structure containing the value bound -** parameter iVar of VM v. Except, if the value is an SQL NULL, return -** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* -** constants) to the value before returning it. -** -** The returned value must be freed by the caller using sqlite3ValueFree(). -*/ -SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ - assert( iVar>0 ); - if( v ){ - Mem *pMem = &v->aVar[iVar-1]; - if( 0==(pMem->flags & MEM_Null) ){ - sqlite3_value *pRet = sqlite3ValueNew(v->db); - if( pRet ){ - sqlite3VdbeMemCopy((Mem *)pRet, pMem); - sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); - } - return pRet; - } - } - return 0; -} - -/* -** Configure SQL variable iVar so that binding a new value to it signals -** to sqlite3_reoptimize() that re-preparing the statement may result -** in a better query plan. -*/ -SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ - assert( iVar>0 ); - if( iVar>32 ){ - v->expmask = 0xffffffff; - }else{ - v->expmask |= ((u32)1 << (iVar-1)); - } -} - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* -** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored -** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored -** in memory obtained from sqlite3DbMalloc). -*/ -SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ - if( pVtab->zErrMsg ){ - sqlite3 *db = p->db; - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); - sqlite3_free(pVtab->zErrMsg); - pVtab->zErrMsg = 0; - } -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - -/* -** If the second argument is not NULL, release any allocations associated -** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord -** structure itself, using sqlite3DbFree(). -** -** This function is used to free UnpackedRecord structures allocated by -** the vdbeUnpackRecord() function found in vdbeapi.c. -*/ -static void vdbeFreeUnpacked(sqlite3 *db, UnpackedRecord *p){ - if( p ){ - int i; - for(i=0; inField; i++){ - Mem *pMem = &p->aMem[i]; - if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); - } - sqlite3DbFree(db, p); - } -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, -** then cursor passed as the second argument should point to the row about -** to be update or deleted. If the application calls sqlite3_preupdate_old(), -** the required value will be read from the row the cursor points to. -*/ -SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( - Vdbe *v, /* Vdbe pre-update hook is invoked by */ - VdbeCursor *pCsr, /* Cursor to grab old.* values from */ - int op, /* SQLITE_INSERT, UPDATE or DELETE */ - const char *zDb, /* Database name */ - Table *pTab, /* Modified table */ - i64 iKey1, /* Initial key value */ - int iReg /* Register for new.* record */ -){ - sqlite3 *db = v->db; - i64 iKey2; - PreUpdate preupdate; - const char *zTbl = pTab->zName; - static const u8 fakeSortOrder = 0; - - assert( db->pPreUpdate==0 ); - memset(&preupdate, 0, sizeof(PreUpdate)); - if( op==SQLITE_UPDATE ){ - iKey2 = v->aMem[iReg].u.i; - }else{ - iKey2 = iKey1; - } - - assert( pCsr->nField==pTab->nCol - || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1) - ); - - preupdate.v = v; - preupdate.pCsr = pCsr; - preupdate.op = op; - preupdate.iNewReg = iReg; - preupdate.keyinfo.db = db; - preupdate.keyinfo.enc = ENC(db); - preupdate.keyinfo.nField = pTab->nCol; - preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder; - preupdate.iKey1 = iKey1; - preupdate.iKey2 = iKey2; - preupdate.pTab = pTab; - - db->pPreUpdate = &preupdate; - db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); - db->pPreUpdate = 0; - sqlite3DbFree(db, preupdate.aRecord); - vdbeFreeUnpacked(db, preupdate.pUnpacked); - vdbeFreeUnpacked(db, preupdate.pNewUnpacked); - if( preupdate.aNew ){ - int i; - for(i=0; inField; i++){ - sqlite3VdbeMemRelease(&preupdate.aNew[i]); - } - sqlite3DbFree(db, preupdate.aNew); - } -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -/************** End of vdbeaux.c *********************************************/ -/************** Begin file vdbeapi.c *****************************************/ -/* -** 2004 May 26 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code use to implement APIs that are part of the -** VDBE. -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Return TRUE (non-zero) of the statement supplied as an argument needs -** to be recompiled. A statement needs to be recompiled whenever the -** execution environment changes in a way that would alter the program -** that sqlite3_prepare() generates. For example, if new functions or -** collating sequences are registered or if an authorizer function is -** added or changed. -*/ -SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe*)pStmt; - return p==0 || p->expired; -} -#endif - -/* -** Check on a Vdbe to make sure it has not been finalized. Log -** an error and return true if it has been finalized (or is otherwise -** invalid). Return false if it is ok. -*/ -static int vdbeSafety(Vdbe *p){ - if( p->db==0 ){ - sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); - return 1; - }else{ - return 0; - } -} -static int vdbeSafetyNotNull(Vdbe *p){ - if( p==0 ){ - sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); - return 1; - }else{ - return vdbeSafety(p); - } -} - -#ifndef SQLITE_OMIT_TRACE -/* -** Invoke the profile callback. This routine is only called if we already -** know that the profile callback is defined and needs to be invoked. -*/ -static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ - sqlite3_int64 iNow; - sqlite3_int64 iElapse; - assert( p->startTime>0 ); - assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 ); - assert( db->init.busy==0 ); - assert( p->zSql!=0 ); - sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); - iElapse = (iNow - p->startTime)*1000000; - if( db->xProfile ){ - db->xProfile(db->pProfileArg, p->zSql, iElapse); - } - if( db->mTrace & SQLITE_TRACE_PROFILE ){ - db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse); - } - p->startTime = 0; -} -/* -** The checkProfileCallback(DB,P) macro checks to see if a profile callback -** is needed, and it invokes the callback if it is needed. -*/ -# define checkProfileCallback(DB,P) \ - if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } -#else -# define checkProfileCallback(DB,P) /*no-op*/ -#endif - -/* -** The following routine destroys a virtual machine that is created by -** the sqlite3_compile() routine. The integer returned is an SQLITE_ -** success/failure code that describes the result of executing the virtual -** machine. -** -** This routine sets the error code and string returned by -** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). -*/ -SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ - int rc; - if( pStmt==0 ){ - /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL - ** pointer is a harmless no-op. */ - rc = SQLITE_OK; - }else{ - Vdbe *v = (Vdbe*)pStmt; - sqlite3 *db = v->db; - if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; - sqlite3_mutex_enter(db->mutex); - checkProfileCallback(db, v); - rc = sqlite3VdbeFinalize(v); - rc = sqlite3ApiExit(db, rc); - sqlite3LeaveMutexAndCloseZombie(db); - } - return rc; -} - -/* -** Terminate the current execution of an SQL statement and reset it -** back to its starting state so that it can be reused. A success code from -** the prior execution is returned. -** -** This routine sets the error code and string returned by -** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). -*/ -SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ - int rc; - if( pStmt==0 ){ - rc = SQLITE_OK; - }else{ - Vdbe *v = (Vdbe*)pStmt; - sqlite3 *db = v->db; - sqlite3_mutex_enter(db->mutex); - checkProfileCallback(db, v); - rc = sqlite3VdbeReset(v); - sqlite3VdbeRewind(v); - assert( (rc & (db->errMask))==rc ); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - } - return rc; -} - -/* -** Set all the parameters in the compiled SQL statement to NULL. -*/ -SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ - int i; - int rc = SQLITE_OK; - Vdbe *p = (Vdbe*)pStmt; -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; -#endif - sqlite3_mutex_enter(mutex); - for(i=0; inVar; i++){ - sqlite3VdbeMemRelease(&p->aVar[i]); - p->aVar[i].flags = MEM_Null; - } - if( p->isPrepareV2 && p->expmask ){ - p->expired = 1; - } - sqlite3_mutex_leave(mutex); - return rc; -} - - -/**************************** sqlite3_value_ ******************************* -** The following routines extract information from a Mem or sqlite3_value -** structure. -*/ -SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ - Mem *p = (Mem*)pVal; - if( p->flags & (MEM_Blob|MEM_Str) ){ - if( ExpandBlob(p)!=SQLITE_OK ){ - assert( p->flags==MEM_Null && p->z==0 ); - return 0; - } - p->flags |= MEM_Blob; - return p->n ? p->z : 0; - }else{ - return sqlite3_value_text(pVal); - } -} -SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){ - return sqlite3ValueBytes(pVal, SQLITE_UTF8); -} -SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){ - return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); -} -SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){ - return sqlite3VdbeRealValue((Mem*)pVal); -} -SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){ - return (int)sqlite3VdbeIntValue((Mem*)pVal); -} -SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ - return sqlite3VdbeIntValue((Mem*)pVal); -} -SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ - Mem *pMem = (Mem*)pVal; - return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); -} -SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ - return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){ - return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); -} -SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){ - return sqlite3ValueText(pVal, SQLITE_UTF16BE); -} -SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){ - return sqlite3ValueText(pVal, SQLITE_UTF16LE); -} -#endif /* SQLITE_OMIT_UTF16 */ -/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five -** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating -** point number string BLOB NULL -*/ -SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ - static const u8 aType[] = { - SQLITE_BLOB, /* 0x00 */ - SQLITE_NULL, /* 0x01 */ - SQLITE_TEXT, /* 0x02 */ - SQLITE_NULL, /* 0x03 */ - SQLITE_INTEGER, /* 0x04 */ - SQLITE_NULL, /* 0x05 */ - SQLITE_INTEGER, /* 0x06 */ - SQLITE_NULL, /* 0x07 */ - SQLITE_FLOAT, /* 0x08 */ - SQLITE_NULL, /* 0x09 */ - SQLITE_FLOAT, /* 0x0a */ - SQLITE_NULL, /* 0x0b */ - SQLITE_INTEGER, /* 0x0c */ - SQLITE_NULL, /* 0x0d */ - SQLITE_INTEGER, /* 0x0e */ - SQLITE_NULL, /* 0x0f */ - SQLITE_BLOB, /* 0x10 */ - SQLITE_NULL, /* 0x11 */ - SQLITE_TEXT, /* 0x12 */ - SQLITE_NULL, /* 0x13 */ - SQLITE_INTEGER, /* 0x14 */ - SQLITE_NULL, /* 0x15 */ - SQLITE_INTEGER, /* 0x16 */ - SQLITE_NULL, /* 0x17 */ - SQLITE_FLOAT, /* 0x18 */ - SQLITE_NULL, /* 0x19 */ - SQLITE_FLOAT, /* 0x1a */ - SQLITE_NULL, /* 0x1b */ - SQLITE_INTEGER, /* 0x1c */ - SQLITE_NULL, /* 0x1d */ - SQLITE_INTEGER, /* 0x1e */ - SQLITE_NULL, /* 0x1f */ - }; - return aType[pVal->flags&MEM_AffMask]; -} - -/* Make a copy of an sqlite3_value object -*/ -SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ - sqlite3_value *pNew; - if( pOrig==0 ) return 0; - pNew = sqlite3_malloc( sizeof(*pNew) ); - if( pNew==0 ) return 0; - memset(pNew, 0, sizeof(*pNew)); - memcpy(pNew, pOrig, MEMCELLSIZE); - pNew->flags &= ~MEM_Dyn; - pNew->db = 0; - if( pNew->flags&(MEM_Str|MEM_Blob) ){ - pNew->flags &= ~(MEM_Static|MEM_Dyn); - pNew->flags |= MEM_Ephem; - if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ - sqlite3ValueFree(pNew); - pNew = 0; - } - } - return pNew; -} - -/* Destroy an sqlite3_value object previously obtained from -** sqlite3_value_dup(). -*/ -SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ - sqlite3ValueFree(pOld); -} - - -/**************************** sqlite3_result_ ******************************* -** The following routines are used by user-defined functions to specify -** the function result. -** -** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the -** result as a string or blob but if the string or blob is too large, it -** then sets the error code to SQLITE_TOOBIG -** -** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P is not going to be used and need to be destroyed. -*/ -static void setResultStrOrError( - sqlite3_context *pCtx, /* Function context */ - const char *z, /* String pointer */ - int n, /* Bytes in string, or negative */ - u8 enc, /* Encoding of z. 0 for BLOBs */ - void (*xDel)(void*) /* Destructor function */ -){ - if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ - sqlite3_result_error_toobig(pCtx); - } -} -static int invokeValueDestructor( - const void *p, /* Value to destroy */ - void (*xDel)(void*), /* The destructor */ - sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ -){ - assert( xDel!=SQLITE_DYNAMIC ); - if( xDel==0 ){ - /* noop */ - }else if( xDel==SQLITE_TRANSIENT ){ - /* noop */ - }else{ - xDel((void*)p); - } - if( pCtx ) sqlite3_result_error_toobig(pCtx); - return SQLITE_TOOBIG; -} -SQLITE_API void sqlite3_result_blob( - sqlite3_context *pCtx, - const void *z, - int n, - void (*xDel)(void *) -){ - assert( n>=0 ); - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n, 0, xDel); -} -SQLITE_API void sqlite3_result_blob64( - sqlite3_context *pCtx, - const void *z, - sqlite3_uint64 n, - void (*xDel)(void *) -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - assert( xDel!=SQLITE_DYNAMIC ); - if( n>0x7fffffff ){ - (void)invokeValueDestructor(z, xDel, pCtx); - }else{ - setResultStrOrError(pCtx, z, (int)n, 0, xDel); - } -} -SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); -} -SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); -} -#endif -SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); -} -SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); -} -SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetNull(pCtx->pOut); -} -SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - Mem *pOut = pCtx->pOut; - assert( sqlite3_mutex_held(pOut->db->mutex) ); - pOut->eSubtype = eSubtype & 0xff; - pOut->flags |= MEM_Subtype; -} -SQLITE_API void sqlite3_result_text( - sqlite3_context *pCtx, - const char *z, - int n, - void (*xDel)(void *) -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); -} -SQLITE_API void sqlite3_result_text64( - sqlite3_context *pCtx, - const char *z, - sqlite3_uint64 n, - void (*xDel)(void *), - unsigned char enc -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - assert( xDel!=SQLITE_DYNAMIC ); - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - if( n>0x7fffffff ){ - (void)invokeValueDestructor(z, xDel, pCtx); - }else{ - setResultStrOrError(pCtx, z, (int)n, enc, xDel); - } -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API void sqlite3_result_text16( - sqlite3_context *pCtx, - const void *z, - int n, - void (*xDel)(void *) -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); -} -SQLITE_API void sqlite3_result_text16be( - sqlite3_context *pCtx, - const void *z, - int n, - void (*xDel)(void *) -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); -} -SQLITE_API void sqlite3_result_text16le( - sqlite3_context *pCtx, - const void *z, - int n, - void (*xDel)(void *) -){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); -} -#endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemCopy(pCtx->pOut, pValue); -} -SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); -} -SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ - Mem *pOut = pCtx->pOut; - assert( sqlite3_mutex_held(pOut->db->mutex) ); - if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ - return SQLITE_TOOBIG; - } - sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); - return SQLITE_OK; -} -SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ - pCtx->isError = errCode; - pCtx->fErrorOrAux = 1; -#ifdef SQLITE_DEBUG - if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; -#endif - if( pCtx->pOut->flags & MEM_Null ){ - sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, - SQLITE_UTF8, SQLITE_STATIC); - } -} - -/* Force an SQLITE_TOOBIG error. */ -SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->isError = SQLITE_TOOBIG; - pCtx->fErrorOrAux = 1; - sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, - SQLITE_UTF8, SQLITE_STATIC); -} - -/* An SQLITE_NOMEM error. */ -SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetNull(pCtx->pOut); - pCtx->isError = SQLITE_NOMEM_BKPT; - pCtx->fErrorOrAux = 1; - sqlite3OomFault(pCtx->pOut->db); -} - -/* -** This function is called after a transaction has been committed. It -** invokes callbacks registered with sqlite3_wal_hook() as required. -*/ -static int doWalCallbacks(sqlite3 *db){ - int rc = SQLITE_OK; -#ifndef SQLITE_OMIT_WAL - int i; - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - int nEntry; - sqlite3BtreeEnter(pBt); - nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); - sqlite3BtreeLeave(pBt); - if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ - rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); - } - } - } -#endif - return rc; -} - - -/* -** Execute the statement pStmt, either until a row of data is ready, the -** statement is completely executed or an error occurs. -** -** This routine implements the bulk of the logic behind the sqlite_step() -** API. The only thing omitted is the automatic recompile if a -** schema change has occurred. That detail is handled by the -** outer sqlite3_step() wrapper procedure. -*/ -static int sqlite3Step(Vdbe *p){ - sqlite3 *db; - int rc; - - assert(p); - if( p->magic!=VDBE_MAGIC_RUN ){ - /* We used to require that sqlite3_reset() be called before retrying - ** sqlite3_step() after any error or after SQLITE_DONE. But beginning - ** with version 3.7.0, we changed this so that sqlite3_reset() would - ** be called automatically instead of throwing the SQLITE_MISUSE error. - ** This "automatic-reset" change is not technically an incompatibility, - ** since any application that receives an SQLITE_MISUSE is broken by - ** definition. - ** - ** Nevertheless, some published applications that were originally written - ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE - ** returns, and those were broken by the automatic-reset change. As a - ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the - ** legacy behavior of returning SQLITE_MISUSE for cases where the - ** previous sqlite3_step() returned something other than a SQLITE_LOCKED - ** or SQLITE_BUSY error. - */ -#ifdef SQLITE_OMIT_AUTORESET - if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - sqlite3_reset((sqlite3_stmt*)p); - }else{ - return SQLITE_MISUSE_BKPT; - } -#else - sqlite3_reset((sqlite3_stmt*)p); -#endif - } - - /* Check that malloc() has not failed. If it has, return early. */ - db = p->db; - if( db->mallocFailed ){ - p->rc = SQLITE_NOMEM; - return SQLITE_NOMEM_BKPT; - } - - if( p->pc<=0 && p->expired ){ - p->rc = SQLITE_SCHEMA; - rc = SQLITE_ERROR; - goto end_of_step; - } - if( p->pc<0 ){ - /* If there are no other statements currently running, then - ** reset the interrupt flag. This prevents a call to sqlite3_interrupt - ** from interrupting a statement that has not yet started. - */ - if( db->nVdbeActive==0 ){ - db->u1.isInterrupted = 0; - } - - assert( db->nVdbeWrite>0 || db->autoCommit==0 - || (db->nDeferredCons==0 && db->nDeferredImmCons==0) - ); - -#ifndef SQLITE_OMIT_TRACE - if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0) - && !db->init.busy && p->zSql ){ - sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); - }else{ - assert( p->startTime==0 ); - } -#endif - - db->nVdbeActive++; - if( p->readOnly==0 ) db->nVdbeWrite++; - if( p->bIsReader ) db->nVdbeRead++; - p->pc = 0; - } -#ifdef SQLITE_DEBUG - p->rcApp = SQLITE_OK; -#endif -#ifndef SQLITE_OMIT_EXPLAIN - if( p->explain ){ - rc = sqlite3VdbeList(p); - }else -#endif /* SQLITE_OMIT_EXPLAIN */ - { - db->nVdbeExec++; - rc = sqlite3VdbeExec(p); - db->nVdbeExec--; - } - -#ifndef SQLITE_OMIT_TRACE - /* If the statement completed successfully, invoke the profile callback */ - if( rc!=SQLITE_ROW ) checkProfileCallback(db, p); -#endif - - if( rc==SQLITE_DONE ){ - assert( p->rc==SQLITE_OK ); - p->rc = doWalCallbacks(db); - if( p->rc!=SQLITE_OK ){ - rc = SQLITE_ERROR; - } - } - - db->errCode = rc; - if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ - p->rc = SQLITE_NOMEM_BKPT; - } -end_of_step: - /* At this point local variable rc holds the value that should be - ** returned if this statement was compiled using the legacy - ** sqlite3_prepare() interface. According to the docs, this can only - ** be one of the values in the first assert() below. Variable p->rc - ** contains the value that would be returned if sqlite3_finalize() - ** were called on statement p. - */ - assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR - || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE - ); - assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp ); - if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ - /* If this statement was prepared using sqlite3_prepare_v2(), and an - ** error has occurred, then return the error code in p->rc to the - ** caller. Set the error code in the database handle to the same value. - */ - rc = sqlite3VdbeTransferError(p); - } - return (rc&db->errMask); -} - -/* -** This is the top-level implementation of sqlite3_step(). Call -** sqlite3Step() to do most of the work. If a schema error occurs, -** call sqlite3Reprepare() and try again. -*/ -SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int rc = SQLITE_OK; /* Result from sqlite3Step() */ - int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ - Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ - int cnt = 0; /* Counter to prevent infinite loop of reprepares */ - sqlite3 *db; /* The database connection */ - - if( vdbeSafetyNotNull(v) ){ - return SQLITE_MISUSE_BKPT; - } - db = v->db; - sqlite3_mutex_enter(db->mutex); - v->doingRerun = 0; - while( (rc = sqlite3Step(v))==SQLITE_SCHEMA - && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ - int savedPc = v->pc; - rc2 = rc = sqlite3Reprepare(v); - if( rc!=SQLITE_OK) break; - sqlite3_reset(pStmt); - if( savedPc>=0 ) v->doingRerun = 1; - assert( v->expired==0 ); - } - if( rc2!=SQLITE_OK ){ - /* This case occurs after failing to recompile an sql statement. - ** The error message from the SQL compiler has already been loaded - ** into the database handle. This block copies the error message - ** from the database handle into the statement and sets the statement - ** program counter to 0 to ensure that when the statement is - ** finalized or reset the parser error message is available via - ** sqlite3_errmsg() and sqlite3_errcode(). - */ - const char *zErr = (const char *)sqlite3_value_text(db->pErr); - sqlite3DbFree(db, v->zErrMsg); - if( !db->mallocFailed ){ - v->zErrMsg = sqlite3DbStrDup(db, zErr); - v->rc = rc2; - } else { - v->zErrMsg = 0; - v->rc = rc = SQLITE_NOMEM_BKPT; - } - } - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - - -/* -** Extract the user data from a sqlite3_context structure and return a -** pointer to it. -*/ -SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ - assert( p && p->pFunc ); - return p->pFunc->pUserData; -} - -/* -** Extract the user data from a sqlite3_context structure and return a -** pointer to it. -** -** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface -** returns a copy of the pointer to the database connection (the 1st -** parameter) of the sqlite3_create_function() and -** sqlite3_create_function16() routines that originally registered the -** application defined function. -*/ -SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ - assert( p && p->pOut ); - return p->pOut->db; -} - -/* -** Return the current time for a statement. If the current time -** is requested more than once within the same run of a single prepared -** statement, the exact same time is returned for each invocation regardless -** of the amount of time that elapses between invocations. In other words, -** the time returned is always the time of the first call. -*/ -SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ - int rc; -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; - assert( p->pVdbe!=0 ); -#else - sqlite3_int64 iTime = 0; - sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; -#endif - if( *piTime==0 ){ - rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); - if( rc ) *piTime = 0; - } - return *piTime; -} - -/* -** The following is the implementation of an SQL function that always -** fails with an error message stating that the function is used in the -** wrong context. The sqlite3_overload_function() API might construct -** SQL function that use this routine so that the functions will exist -** for name resolution but are actually overloaded by the xFindFunction -** method of virtual tables. -*/ -SQLITE_PRIVATE void sqlite3InvalidFunction( - sqlite3_context *context, /* The function calling context */ - int NotUsed, /* Number of arguments to the function */ - sqlite3_value **NotUsed2 /* Value of each argument */ -){ - const char *zName = context->pFunc->zName; - char *zErr; - UNUSED_PARAMETER2(NotUsed, NotUsed2); - zErr = sqlite3_mprintf( - "unable to use function %s in the requested context", zName); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); -} - -/* -** Create a new aggregate context for p and return a pointer to -** its pMem->z element. -*/ -static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ - Mem *pMem = p->pMem; - assert( (pMem->flags & MEM_Agg)==0 ); - if( nByte<=0 ){ - sqlite3VdbeMemSetNull(pMem); - pMem->z = 0; - }else{ - sqlite3VdbeMemClearAndResize(pMem, nByte); - pMem->flags = MEM_Agg; - pMem->u.pDef = p->pFunc; - if( pMem->z ){ - memset(pMem->z, 0, nByte); - } - } - return (void*)pMem->z; -} - -/* -** Allocate or return the aggregate context for a user function. A new -** context is allocated on the first call. Subsequent calls return the -** same context that was returned on prior calls. -*/ -SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ - assert( p && p->pFunc && p->pFunc->xFinalize ); - assert( sqlite3_mutex_held(p->pOut->db->mutex) ); - testcase( nByte<0 ); - if( (p->pMem->flags & MEM_Agg)==0 ){ - return createAggContext(p, nByte); - }else{ - return (void*)p->pMem->z; - } -} - -/* -** Return the auxiliary data pointer, if any, for the iArg'th argument to -** the user-function defined by pCtx. -*/ -SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ - AuxData *pAuxData; - - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); -#if SQLITE_ENABLE_STAT3_OR_STAT4 - if( pCtx->pVdbe==0 ) return 0; -#else - assert( pCtx->pVdbe!=0 ); -#endif - for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ - if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; - } - - return (pAuxData ? pAuxData->pAux : 0); -} - -/* -** Set the auxiliary data pointer and delete function, for the iArg'th -** argument to the user-function defined by pCtx. Any previous value is -** deleted by calling the delete function specified when it was set. -*/ -SQLITE_API void sqlite3_set_auxdata( - sqlite3_context *pCtx, - int iArg, - void *pAux, - void (*xDelete)(void*) -){ - AuxData *pAuxData; - Vdbe *pVdbe = pCtx->pVdbe; - - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - if( iArg<0 ) goto failed; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( pVdbe==0 ) goto failed; -#else - assert( pVdbe!=0 ); -#endif - - for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){ - if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break; - } - if( pAuxData==0 ){ - pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); - if( !pAuxData ) goto failed; - pAuxData->iOp = pCtx->iOp; - pAuxData->iArg = iArg; - pAuxData->pNext = pVdbe->pAuxData; - pVdbe->pAuxData = pAuxData; - if( pCtx->fErrorOrAux==0 ){ - pCtx->isError = 0; - pCtx->fErrorOrAux = 1; - } - }else if( pAuxData->xDelete ){ - pAuxData->xDelete(pAuxData->pAux); - } - - pAuxData->pAux = pAux; - pAuxData->xDelete = xDelete; - return; - -failed: - if( xDelete ){ - xDelete(pAux); - } -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Return the number of times the Step function of an aggregate has been -** called. -** -** This function is deprecated. Do not use it for new code. It is -** provide only to avoid breaking legacy code. New aggregate function -** implementations should keep their own counts within their aggregate -** context. -*/ -SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ - assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize ); - return p->pMem->n; -} -#endif - -/* -** Return the number of columns in the result set for the statement pStmt. -*/ -SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ - Vdbe *pVm = (Vdbe *)pStmt; - return pVm ? pVm->nResColumn : 0; -} - -/* -** Return the number of values available from the current row of the -** currently executing statement pStmt. -*/ -SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ - Vdbe *pVm = (Vdbe *)pStmt; - if( pVm==0 || pVm->pResultSet==0 ) return 0; - return pVm->nResColumn; -} - -/* -** Return a pointer to static memory containing an SQL NULL value. -*/ -static const Mem *columnNullValue(void){ - /* Even though the Mem structure contains an element - ** of type i64, on certain architectures (x86) with certain compiler - ** switches (-Os), gcc may align this Mem object on a 4-byte boundary - ** instead of an 8-byte one. This all works fine, except that when - ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s - ** that a Mem structure is located on an 8-byte boundary. To prevent - ** these assert()s from failing, when building with SQLITE_DEBUG defined - ** using gcc, we force nullMem to be 8-byte aligned using the magical - ** __attribute__((aligned(8))) macro. */ - static const Mem nullMem -#if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) -#endif - = { - /* .u = */ {0}, - /* .flags = */ (u16)MEM_Null, - /* .enc = */ (u8)0, - /* .eSubtype = */ (u8)0, - /* .n = */ (int)0, - /* .z = */ (char*)0, - /* .zMalloc = */ (char*)0, - /* .szMalloc = */ (int)0, - /* .uTemp = */ (u32)0, - /* .db = */ (sqlite3*)0, - /* .xDel = */ (void(*)(void*))0, -#ifdef SQLITE_DEBUG - /* .pScopyFrom = */ (Mem*)0, - /* .pFiller = */ (void*)0, -#endif - }; - return &nullMem; -} - -/* -** Check to see if column iCol of the given statement is valid. If -** it is, return a pointer to the Mem for the value of that column. -** If iCol is not valid, return a pointer to a Mem which has a value -** of NULL. -*/ -static Mem *columnMem(sqlite3_stmt *pStmt, int i){ - Vdbe *pVm; - Mem *pOut; - - pVm = (Vdbe *)pStmt; - if( pVm==0 ) return (Mem*)columnNullValue(); - assert( pVm->db ); - sqlite3_mutex_enter(pVm->db->mutex); - if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ - pOut = &pVm->pResultSet[i]; - }else{ - sqlite3Error(pVm->db, SQLITE_RANGE); - pOut = (Mem*)columnNullValue(); - } - return pOut; -} - -/* -** This function is called after invoking an sqlite3_value_XXX function on a -** column value (i.e. a value returned by evaluating an SQL expression in the -** select list of a SELECT statement) that may cause a malloc() failure. If -** malloc() has failed, the threads mallocFailed flag is cleared and the result -** code of statement pStmt set to SQLITE_NOMEM. -** -** Specifically, this is called from within: -** -** sqlite3_column_int() -** sqlite3_column_int64() -** sqlite3_column_text() -** sqlite3_column_text16() -** sqlite3_column_real() -** sqlite3_column_bytes() -** sqlite3_column_bytes16() -** sqiite3_column_blob() -*/ -static void columnMallocFailure(sqlite3_stmt *pStmt) -{ - /* If malloc() failed during an encoding conversion within an - ** sqlite3_column_XXX API, then set the return code of the statement to - ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR - ** and _finalize() will return NOMEM. - */ - Vdbe *p = (Vdbe *)pStmt; - if( p ){ - assert( p->db!=0 ); - assert( sqlite3_mutex_held(p->db->mutex) ); - p->rc = sqlite3ApiExit(p->db, p->rc); - sqlite3_mutex_leave(p->db->mutex); - } -} - -/**************************** sqlite3_column_ ******************************* -** The following routines are used to access elements of the current row -** in the result set. -*/ -SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ - const void *val; - val = sqlite3_value_blob( columnMem(pStmt,i) ); - /* Even though there is no encoding conversion, value_blob() might - ** need to call malloc() to expand the result of a zeroblob() - ** expression. - */ - columnMallocFailure(pStmt); - return val; -} -SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ - int val = sqlite3_value_bytes( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ - int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ - double val = sqlite3_value_double( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ - int val = sqlite3_value_int( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ - sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ - const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ - Mem *pOut = columnMem(pStmt, i); - if( pOut->flags&MEM_Static ){ - pOut->flags &= ~MEM_Static; - pOut->flags |= MEM_Ephem; - } - columnMallocFailure(pStmt); - return (sqlite3_value *)pOut; -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ - const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return val; -} -#endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ - int iType = sqlite3_value_type( columnMem(pStmt,i) ); - columnMallocFailure(pStmt); - return iType; -} - -/* -** Convert the N-th element of pStmt->pColName[] into a string using -** xFunc() then return that string. If N is out of range, return 0. -** -** There are up to 5 names for each column. useType determines which -** name is returned. Here are the names: -** -** 0 The column name as it should be displayed for output -** 1 The datatype name for the column -** 2 The name of the database that the column derives from -** 3 The name of the table that the column derives from -** 4 The name of the table column that the result column derives from -** -** If the result is not a simple column reference (if it is an expression -** or a constant) then useTypes 2, 3, and 4 return NULL. -*/ -static const void *columnName( - sqlite3_stmt *pStmt, - int N, - const void *(*xFunc)(Mem*), - int useType -){ - const void *ret; - Vdbe *p; - int n; - sqlite3 *db; -#ifdef SQLITE_ENABLE_API_ARMOR - if( pStmt==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - ret = 0; - p = (Vdbe *)pStmt; - db = p->db; - assert( db!=0 ); - n = sqlite3_column_count(pStmt); - if( N=0 ){ - N += useType*n; - sqlite3_mutex_enter(db->mutex); - assert( db->mallocFailed==0 ); - ret = xFunc(&p->aColName[N]); - /* A malloc may have failed inside of the xFunc() call. If this - ** is the case, clear the mallocFailed flag and return NULL. - */ - if( db->mallocFailed ){ - sqlite3OomClear(db); - ret = 0; - } - sqlite3_mutex_leave(db->mutex); - } - return ret; -} - -/* -** Return the name of the Nth column of the result set returned by SQL -** statement pStmt. -*/ -SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME); -} -#endif - -/* -** Constraint: If you have ENABLE_COLUMN_METADATA then you must -** not define OMIT_DECLTYPE. -*/ -#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA) -# error "Must not define both SQLITE_OMIT_DECLTYPE \ - and SQLITE_ENABLE_COLUMN_METADATA" -#endif - -#ifndef SQLITE_OMIT_DECLTYPE -/* -** Return the column declaration type (if applicable) of the 'i'th column -** of the result set of SQL statement pStmt. -*/ -SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE); -} -#endif /* SQLITE_OMIT_UTF16 */ -#endif /* SQLITE_OMIT_DECLTYPE */ - -#ifdef SQLITE_ENABLE_COLUMN_METADATA -/* -** Return the name of the database from which a result column derives. -** NULL is returned if the result column is an expression or constant or -** anything else which is not an unambiguous reference to a database column. -*/ -SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE); -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Return the name of the table from which a result column derives. -** NULL is returned if the result column is an expression or constant or -** anything else which is not an unambiguous reference to a database column. -*/ -SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE); -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Return the name of the table column from which a result column derives. -** NULL is returned if the result column is an expression or constant or -** anything else which is not an unambiguous reference to a database column. -*/ -SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN); -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ - return columnName( - pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN); -} -#endif /* SQLITE_OMIT_UTF16 */ -#endif /* SQLITE_ENABLE_COLUMN_METADATA */ - - -/******************************* sqlite3_bind_ *************************** -** -** Routines used to attach values to wildcards in a compiled SQL statement. -*/ -/* -** Unbind the value bound to variable i in virtual machine p. This is the -** the same as binding a NULL value to the column. If the "i" parameter is -** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. -** -** A successful evaluation of this routine acquires the mutex on p. -** the mutex is released if any kind of error occurs. -** -** The error code stored in database p->db is overwritten with the return -** value in any case. -*/ -static int vdbeUnbind(Vdbe *p, int i){ - Mem *pVar; - if( vdbeSafetyNotNull(p) ){ - return SQLITE_MISUSE_BKPT; - } - sqlite3_mutex_enter(p->db->mutex); - if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ - sqlite3Error(p->db, SQLITE_MISUSE); - sqlite3_mutex_leave(p->db->mutex); - sqlite3_log(SQLITE_MISUSE, - "bind on a busy prepared statement: [%s]", p->zSql); - return SQLITE_MISUSE_BKPT; - } - if( i<1 || i>p->nVar ){ - sqlite3Error(p->db, SQLITE_RANGE); - sqlite3_mutex_leave(p->db->mutex); - return SQLITE_RANGE; - } - i--; - pVar = &p->aVar[i]; - sqlite3VdbeMemRelease(pVar); - pVar->flags = MEM_Null; - sqlite3Error(p->db, SQLITE_OK); - - /* If the bit corresponding to this variable in Vdbe.expmask is set, then - ** binding a new value to this variable invalidates the current query plan. - ** - ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host - ** parameter in the WHERE clause might influence the choice of query plan - ** for a statement, then the statement will be automatically recompiled, - ** as if there had been a schema change, on the first sqlite3_step() call - ** following any change to the bindings of that parameter. - */ - if( p->isPrepareV2 && - ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff) - ){ - p->expired = 1; - } - return SQLITE_OK; -} - -/* -** Bind a text or BLOB value. -*/ -static int bindText( - sqlite3_stmt *pStmt, /* The statement to bind against */ - int i, /* Index of the parameter to bind */ - const void *zData, /* Pointer to the data to be bound */ - int nData, /* Number of bytes of data to be bound */ - void (*xDel)(void*), /* Destructor for the data */ - u8 encoding /* Encoding for the data */ -){ - Vdbe *p = (Vdbe *)pStmt; - Mem *pVar; - int rc; - - rc = vdbeUnbind(p, i); - if( rc==SQLITE_OK ){ - if( zData!=0 ){ - pVar = &p->aVar[i-1]; - rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); - if( rc==SQLITE_OK && encoding!=0 ){ - rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); - } - sqlite3Error(p->db, rc); - rc = sqlite3ApiExit(p->db, rc); - } - sqlite3_mutex_leave(p->db->mutex); - }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ - xDel((void*)zData); - } - return rc; -} - - -/* -** Bind a blob value to an SQL statement variable. -*/ -SQLITE_API int sqlite3_bind_blob( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int nData, - void (*xDel)(void*) -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( nData<0 ) return SQLITE_MISUSE_BKPT; -#endif - return bindText(pStmt, i, zData, nData, xDel, 0); -} -SQLITE_API int sqlite3_bind_blob64( - sqlite3_stmt *pStmt, - int i, - const void *zData, - sqlite3_uint64 nData, - void (*xDel)(void*) -){ - assert( xDel!=SQLITE_DYNAMIC ); - if( nData>0x7fffffff ){ - return invokeValueDestructor(zData, xDel, 0); - }else{ - return bindText(pStmt, i, zData, (int)nData, xDel, 0); - } -} -SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ - int rc; - Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, i); - if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); - sqlite3_mutex_leave(p->db->mutex); - } - return rc; -} -SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ - return sqlite3_bind_int64(p, i, (i64)iValue); -} -SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ - int rc; - Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, i); - if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); - sqlite3_mutex_leave(p->db->mutex); - } - return rc; -} -SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ - int rc; - Vdbe *p = (Vdbe*)pStmt; - rc = vdbeUnbind(p, i); - if( rc==SQLITE_OK ){ - sqlite3_mutex_leave(p->db->mutex); - } - return rc; -} -SQLITE_API int sqlite3_bind_text( - sqlite3_stmt *pStmt, - int i, - const char *zData, - int nData, - void (*xDel)(void*) -){ - return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); -} -SQLITE_API int sqlite3_bind_text64( - sqlite3_stmt *pStmt, - int i, - const char *zData, - sqlite3_uint64 nData, - void (*xDel)(void*), - unsigned char enc -){ - assert( xDel!=SQLITE_DYNAMIC ); - if( nData>0x7fffffff ){ - return invokeValueDestructor(zData, xDel, 0); - }else{ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - return bindText(pStmt, i, zData, (int)nData, xDel, enc); - } -} -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API int sqlite3_bind_text16( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int nData, - void (*xDel)(void*) -){ - return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); -} -#endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ - int rc; - switch( sqlite3_value_type((sqlite3_value*)pValue) ){ - case SQLITE_INTEGER: { - rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); - break; - } - case SQLITE_FLOAT: { - rc = sqlite3_bind_double(pStmt, i, pValue->u.r); - break; - } - case SQLITE_BLOB: { - if( pValue->flags & MEM_Zero ){ - rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); - }else{ - rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); - } - break; - } - case SQLITE_TEXT: { - rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT, - pValue->enc); - break; - } - default: { - rc = sqlite3_bind_null(pStmt, i); - break; - } - } - return rc; -} -SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ - int rc; - Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, i); - if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); - sqlite3_mutex_leave(p->db->mutex); - } - return rc; -} -SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ - int rc; - Vdbe *p = (Vdbe *)pStmt; - sqlite3_mutex_enter(p->db->mutex); - if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ - rc = SQLITE_TOOBIG; - }else{ - assert( (n & 0x7FFFFFFF)==n ); - rc = sqlite3_bind_zeroblob(pStmt, i, n); - } - rc = sqlite3ApiExit(p->db, rc); - sqlite3_mutex_leave(p->db->mutex); - return rc; -} - -/* -** Return the number of wildcards that can be potentially bound to. -** This routine is added to support DBD::SQLite. -*/ -SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe*)pStmt; - return p ? p->nVar : 0; -} - -/* -** Return the name of a wildcard parameter. Return NULL if the index -** is out of range or if the wildcard is unnamed. -** -** The result is always UTF-8. -*/ -SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ - Vdbe *p = (Vdbe*)pStmt; - if( p==0 || i<1 || i>p->nzVar ){ - return 0; - } - return p->azVar[i-1]; -} - -/* -** Given a wildcard parameter name, return the index of the variable -** with that name. If there is no variable with the given name, -** return 0. -*/ -SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ - int i; - if( p==0 ){ - return 0; - } - if( zName ){ - for(i=0; inzVar; i++){ - const char *z = p->azVar[i]; - if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){ - return i+1; - } - } - } - return 0; -} -SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ - return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); -} - -/* -** Transfer all bindings from the first statement over to the second. -*/ -SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ - Vdbe *pFrom = (Vdbe*)pFromStmt; - Vdbe *pTo = (Vdbe*)pToStmt; - int i; - assert( pTo->db==pFrom->db ); - assert( pTo->nVar==pFrom->nVar ); - sqlite3_mutex_enter(pTo->db->mutex); - for(i=0; inVar; i++){ - sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); - } - sqlite3_mutex_leave(pTo->db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Deprecated external interface. Internal/core SQLite code -** should call sqlite3TransferBindings. -** -** It is misuse to call this routine with statements from different -** database connections. But as this is a deprecated interface, we -** will not bother to check for that condition. -** -** If the two statements contain a different number of bindings, then -** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise -** SQLITE_OK is returned. -*/ -SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ - Vdbe *pFrom = (Vdbe*)pFromStmt; - Vdbe *pTo = (Vdbe*)pToStmt; - if( pFrom->nVar!=pTo->nVar ){ - return SQLITE_ERROR; - } - if( pTo->isPrepareV2 && pTo->expmask ){ - pTo->expired = 1; - } - if( pFrom->isPrepareV2 && pFrom->expmask ){ - pFrom->expired = 1; - } - return sqlite3TransferBindings(pFromStmt, pToStmt); -} -#endif - -/* -** Return the sqlite3* database handle to which the prepared statement given -** in the argument belongs. This is the same database handle that was -** the first argument to the sqlite3_prepare() that was used to create -** the statement in the first place. -*/ -SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ - return pStmt ? ((Vdbe*)pStmt)->db : 0; -} - -/* -** Return true if the prepared statement is guaranteed to not modify the -** database. -*/ -SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ - return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; -} - -/* -** Return true if the prepared statement is in need of being reset. -*/ -SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ - Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; -} - -/* -** Return a pointer to the next prepared statement after pStmt associated -** with database connection pDb. If pStmt is NULL, return the first -** prepared statement for the database connection. Return NULL if there -** are no more. -*/ -SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ - sqlite3_stmt *pNext; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(pDb) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(pDb->mutex); - if( pStmt==0 ){ - pNext = (sqlite3_stmt*)pDb->pVdbe; - }else{ - pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; - } - sqlite3_mutex_leave(pDb->mutex); - return pNext; -} - -/* -** Return the value of a status counter for a prepared statement -*/ -SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ - Vdbe *pVdbe = (Vdbe*)pStmt; - u32 v; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !pStmt ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - v = pVdbe->aCounter[op]; - if( resetFlag ) pVdbe->aCounter[op] = 0; - return (int)v; -} - -/* -** Return the SQL associated with a prepared statement -*/ -SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe *)pStmt; - return p ? p->zSql : 0; -} - -/* -** Return the SQL associated with a prepared statement with -** bound parameters expanded. Space to hold the returned string is -** obtained from sqlite3_malloc(). The caller is responsible for -** freeing the returned string by passing it to sqlite3_free(). -** -** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of -** expanded bound parameters. -*/ -SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ -#ifdef SQLITE_OMIT_TRACE - return 0; -#else - char *z = 0; - const char *zSql = sqlite3_sql(pStmt); - if( zSql ){ - Vdbe *p = (Vdbe *)pStmt; - sqlite3_mutex_enter(p->db->mutex); - z = sqlite3VdbeExpandSql(p, zSql); - sqlite3_mutex_leave(p->db->mutex); - } - return z; -#endif -} - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** Allocate and populate an UnpackedRecord structure based on the serialized -** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure -** if successful, or a NULL pointer if an OOM error is encountered. -*/ -static UnpackedRecord *vdbeUnpackRecord( - KeyInfo *pKeyInfo, - int nKey, - const void *pKey -){ - char *dummy; /* Dummy argument for AllocUnpackedRecord() */ - UnpackedRecord *pRet; /* Return value */ - - pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy); - if( pRet ){ - memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1)); - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); - } - return pRet; -} - -/* -** This function is called from within a pre-update callback to retrieve -** a field of the row currently being updated or deleted. -*/ -SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; - int rc = SQLITE_OK; - - /* Test that this call is being made from within an SQLITE_DELETE or - ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ - if( !p || p->op==SQLITE_INSERT ){ - rc = SQLITE_MISUSE_BKPT; - goto preupdate_old_out; - } - if( iIdx>=p->pCsr->nField || iIdx<0 ){ - rc = SQLITE_RANGE; - goto preupdate_old_out; - } - - /* If the old.* record has not yet been loaded into memory, do so now. */ - if( p->pUnpacked==0 ){ - u32 nRec; - u8 *aRec; - - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; - } - p->aRecord = aRec; - } - - if( iIdx>=p->pUnpacked->nField ){ - *ppValue = (sqlite3_value *)columnNullValue(); - }else{ - Mem *pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; - *ppValue = &p->pUnpacked->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & MEM_Int ){ - sqlite3VdbeMemRealify(pMem); - } - } - } - - preupdate_old_out: - sqlite3Error(db, rc); - return sqlite3ApiExit(db, rc); -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** This function is called from within a pre-update callback to retrieve -** the number of columns in the row being updated, deleted or inserted. -*/ -SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; - return (p ? p->keyinfo.nField : 0); -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** This function is designed to be called from within a pre-update callback -** only. It returns zero if the change that caused the callback was made -** immediately by a user SQL statement. Or, if the change was made by a -** trigger program, it returns the number of trigger programs currently -** on the stack (1 for a top-level trigger, 2 for a trigger fired by a -** top-level trigger etc.). -** -** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL -** or SET DEFAULT action is considered a trigger. -*/ -SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; - return (p ? p->v->nFrame : 0); -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** This function is called from within a pre-update callback to retrieve -** a field of the row currently being updated or inserted. -*/ -SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; - int rc = SQLITE_OK; - Mem *pMem; - - if( !p || p->op==SQLITE_DELETE ){ - rc = SQLITE_MISUSE_BKPT; - goto preupdate_new_out; - } - if( iIdx>=p->pCsr->nField || iIdx<0 ){ - rc = SQLITE_RANGE; - goto preupdate_new_out; - } - - if( p->op==SQLITE_INSERT ){ - /* For an INSERT, memory cell p->iNewReg contains the serialized record - ** that is being inserted. Deserialize it. */ - UnpackedRecord *pUnpack = p->pNewUnpacked; - if( !pUnpack ){ - Mem *pData = &p->v->aMem[p->iNewReg]; - rc = ExpandBlob(pData); - if( rc!=SQLITE_OK ) goto preupdate_new_out; - pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); - if( !pUnpack ){ - rc = SQLITE_NOMEM; - goto preupdate_new_out; - } - p->pNewUnpacked = pUnpack; - } - if( iIdx>=pUnpack->nField ){ - pMem = (sqlite3_value *)columnNullValue(); - }else{ - pMem = &pUnpack->aMem[iIdx]; - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey2); - } - } - }else{ - /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required - ** value. Make a copy of the cell contents and return a pointer to it. - ** It is not safe to return a pointer to the memory cell itself as the - ** caller may modify the value text encoding. - */ - assert( p->op==SQLITE_UPDATE ); - if( !p->aNew ){ - p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); - if( !p->aNew ){ - rc = SQLITE_NOMEM; - goto preupdate_new_out; - } - } - assert( iIdx>=0 && iIdxpCsr->nField ); - pMem = &p->aNew[iIdx]; - if( pMem->flags==0 ){ - if( iIdx==p->pTab->iPKey ){ - sqlite3VdbeMemSetInt64(pMem, p->iKey2); - }else{ - rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); - if( rc!=SQLITE_OK ) goto preupdate_new_out; - } - } - } - *ppValue = pMem; - - preupdate_new_out: - sqlite3Error(db, rc); - return sqlite3ApiExit(db, rc); -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -/* -** Return status data for a single loop within query pStmt. -*/ -SQLITE_API int sqlite3_stmt_scanstatus( - sqlite3_stmt *pStmt, /* Prepared statement being queried */ - int idx, /* Index of loop to report on */ - int iScanStatusOp, /* Which metric to return */ - void *pOut /* OUT: Write the answer here */ -){ - Vdbe *p = (Vdbe*)pStmt; - ScanStatus *pScan; - if( idx<0 || idx>=p->nScan ) return 1; - pScan = &p->aScan[idx]; - switch( iScanStatusOp ){ - case SQLITE_SCANSTAT_NLOOP: { - *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; - break; - } - case SQLITE_SCANSTAT_NVISIT: { - *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; - break; - } - case SQLITE_SCANSTAT_EST: { - double r = 1.0; - LogEst x = pScan->nEst; - while( x<100 ){ - x += 10; - r *= 0.5; - } - *(double*)pOut = r*sqlite3LogEstToInt(x); - break; - } - case SQLITE_SCANSTAT_NAME: { - *(const char**)pOut = pScan->zName; - break; - } - case SQLITE_SCANSTAT_EXPLAIN: { - if( pScan->addrExplain ){ - *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; - }else{ - *(const char**)pOut = 0; - } - break; - } - case SQLITE_SCANSTAT_SELECTID: { - if( pScan->addrExplain ){ - *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; - }else{ - *(int*)pOut = -1; - } - break; - } - default: { - return 1; - } - } - return 0; -} - -/* -** Zero all counters associated with the sqlite3_stmt_scanstatus() data. -*/ -SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ - Vdbe *p = (Vdbe*)pStmt; - memset(p->anExec, 0, p->nOp * sizeof(i64)); -} -#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ - -/************** End of vdbeapi.c *********************************************/ -/************** Begin file vdbetrace.c ***************************************/ -/* -** 2009 November 25 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code used to insert the values of host parameters -** (aka "wildcards") into the SQL text output by sqlite3_trace(). -** -** The Vdbe parse-tree explainer is also found here. -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -#ifndef SQLITE_OMIT_TRACE - -/* -** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of -** bytes in this text up to but excluding the first character in -** a host parameter. If the text contains no host parameters, return -** the total number of bytes in the text. -*/ -static int findNextHostParameter(const char *zSql, int *pnToken){ - int tokenType; - int nTotal = 0; - int n; - - *pnToken = 0; - while( zSql[0] ){ - n = sqlite3GetToken((u8*)zSql, &tokenType); - assert( n>0 && tokenType!=TK_ILLEGAL ); - if( tokenType==TK_VARIABLE ){ - *pnToken = n; - break; - } - nTotal += n; - zSql += n; - } - return nTotal; -} - -/* -** This function returns a pointer to a nul-terminated string in memory -** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the -** string contains a copy of zRawSql but with host parameters expanded to -** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, -** then the returned string holds a copy of zRawSql with "-- " prepended -** to each line of text. -** -** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then -** then long strings and blobs are truncated to that many bytes. This -** can be used to prevent unreasonably large trace strings when dealing -** with large (multi-megabyte) strings and blobs. -** -** The calling function is responsible for making sure the memory returned -** is eventually freed. -** -** ALGORITHM: Scan the input string looking for host parameters in any of -** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within -** string literals, quoted identifier names, and comments. For text forms, -** the host parameter index is found by scanning the prepared -** statement for the corresponding OP_Variable opcode. Once the host -** parameter index is known, locate the value in p->aVar[]. Then render -** the value as a literal in place of the host parameter name. -*/ -SQLITE_PRIVATE char *sqlite3VdbeExpandSql( - Vdbe *p, /* The prepared statement being evaluated */ - const char *zRawSql /* Raw text of the SQL statement */ -){ - sqlite3 *db; /* The database connection */ - int idx = 0; /* Index of a host parameter */ - int nextIndex = 1; /* Index of next ? host parameter */ - int n; /* Length of a token prefix */ - int nToken; /* Length of the parameter token */ - int i; /* Loop counter */ - Mem *pVar; /* Value of a host parameter */ - StrAccum out; /* Accumulate the output here */ -#ifndef SQLITE_OMIT_UTF16 - Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */ -#endif - char zBase[100]; /* Initial working space */ - - db = p->db; - sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), - db->aLimit[SQLITE_LIMIT_LENGTH]); - if( db->nVdbeExec>1 ){ - while( *zRawSql ){ - const char *zStart = zRawSql; - while( *(zRawSql++)!='\n' && *zRawSql ); - sqlite3StrAccumAppend(&out, "-- ", 3); - assert( (zRawSql - zStart) > 0 ); - sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); - } - }else if( p->nVar==0 ){ - sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql)); - }else{ - while( zRawSql[0] ){ - n = findNextHostParameter(zRawSql, &nToken); - assert( n>0 ); - sqlite3StrAccumAppend(&out, zRawSql, n); - zRawSql += n; - assert( zRawSql[0] || nToken==0 ); - if( nToken==0 ) break; - if( zRawSql[0]=='?' ){ - if( nToken>1 ){ - assert( sqlite3Isdigit(zRawSql[1]) ); - sqlite3GetInt32(&zRawSql[1], &idx); - }else{ - idx = nextIndex; - } - }else{ - assert( zRawSql[0]==':' || zRawSql[0]=='$' || - zRawSql[0]=='@' || zRawSql[0]=='#' ); - testcase( zRawSql[0]==':' ); - testcase( zRawSql[0]=='$' ); - testcase( zRawSql[0]=='@' ); - testcase( zRawSql[0]=='#' ); - idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); - assert( idx>0 ); - } - zRawSql += nToken; - nextIndex = idx + 1; - assert( idx>0 && idx<=p->nVar ); - pVar = &p->aVar[idx-1]; - if( pVar->flags & MEM_Null ){ - sqlite3StrAccumAppend(&out, "NULL", 4); - }else if( pVar->flags & MEM_Int ){ - sqlite3XPrintf(&out, "%lld", pVar->u.i); - }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, "%!.15g", pVar->u.r); - }else if( pVar->flags & MEM_Str ){ - int nOut; /* Number of bytes of the string text to include in output */ -#ifndef SQLITE_OMIT_UTF16 - u8 enc = ENC(db); - if( enc!=SQLITE_UTF8 ){ - memset(&utf8, 0, sizeof(utf8)); - utf8.db = db; - sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); - if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ - out.accError = STRACCUM_NOMEM; - out.nAlloc = 0; - } - pVar = &utf8; - } -#endif - nOut = pVar->n; -#ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ - nOut = SQLITE_TRACE_SIZE_LIMIT; - while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } - } -#endif - sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); -#ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOutn ){ - sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); - } -#endif -#ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); -#endif - }else if( pVar->flags & MEM_Zero ){ - sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); - }else{ - int nOut; /* Number of bytes of the blob to include in output */ - assert( pVar->flags & MEM_Blob ); - sqlite3StrAccumAppend(&out, "x'", 2); - nOut = pVar->n; -#ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; -#endif - for(i=0; iz[i]&0xff); - } - sqlite3StrAccumAppend(&out, "'", 1); -#ifdef SQLITE_TRACE_SIZE_LIMIT - if( nOutn ){ - sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); - } -#endif - } - } - } - if( out.accError ) sqlite3StrAccumReset(&out); - return sqlite3StrAccumFinish(&out); -} - -#endif /* #ifndef SQLITE_OMIT_TRACE */ - -/************** End of vdbetrace.c *******************************************/ -/************** Begin file vdbe.c ********************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** The code in this file implements the function that runs the -** bytecode of a prepared statement. -** -** Various scripts scan this source file in order to generate HTML -** documentation, headers files, or other derived files. The formatting -** of the code in this file is, therefore, important. See other comments -** in this file for details. If in doubt, do not deviate from existing -** commenting and indentation practices when changing or adding code. -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -/* -** Invoke this macro on memory cells just prior to changing the -** value of the cell. This macro verifies that shallow copies are -** not misused. A shallow copy of a string or blob just copies a -** pointer to the string or blob, not the content. If the original -** is changed while the copy is still in use, the string or blob might -** be changed out from under the copy. This macro verifies that nothing -** like that ever happens. -*/ -#ifdef SQLITE_DEBUG -# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) -#else -# define memAboutToChange(P,M) -#endif - -/* -** The following global variable is incremented every time a cursor -** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test -** procedures use this information to make sure that indices are -** working correctly. This variable has no function other than to -** help verify the correct operation of the library. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_search_count = 0; -#endif - -/* -** When this global variable is positive, it gets decremented once before -** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted -** field of the sqlite3 structure is set in order to simulate an interrupt. -** -** This facility is used for testing purposes only. It does not function -** in an ordinary build. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_interrupt_count = 0; -#endif - -/* -** The next global variable is incremented each type the OP_Sort opcode -** is executed. The test procedures use this information to make sure that -** sorting is occurring or not occurring at appropriate times. This variable -** has no function other than to help verify the correct operation of the -** library. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_sort_count = 0; -#endif - -/* -** The next global variable records the size of the largest MEM_Blob -** or MEM_Str that has been used by a VDBE opcode. The test procedures -** use this information to make sure that the zero-blob functionality -** is working correctly. This variable has no function other than to -** help verify the correct operation of the library. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_max_blobsize = 0; -static void updateMaxBlobsize(Mem *p){ - if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ - sqlite3_max_blobsize = p->n; - } -} -#endif - -/* -** This macro evaluates to true if either the update hook or the preupdate -** hook are enabled for database connect DB. -*/ -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) -#else -# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) -#endif - -/* -** The next global variable is incremented each time the OP_Found opcode -** is executed. This is used to test whether or not the foreign key -** operation implemented using OP_FkIsZero is working. This variable -** has no function other than to help verify the correct operation of the -** library. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_found_count = 0; -#endif - -/* -** Test a register to see if it exceeds the current maximum blob size. -** If it does, record the new maximum blob size. -*/ -#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST) -# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) -#else -# define UPDATE_MAX_BLOBSIZE(P) -#endif - -/* -** Invoke the VDBE coverage callback, if that callback is defined. This -** feature is used for test suite validation only and does not appear an -** production builds. -** -** M is an integer, 2 or 3, that indices how many different ways the -** branch can go. It is usually 2. "I" is the direction the branch -** goes. 0 means falls through. 1 means branch is taken. 2 means the -** second alternative branch is taken. -** -** iSrcLine is the source code line (from the __LINE__ macro) that -** generated the VDBE instruction. This instrumentation assumes that all -** source code is in a single file (the amalgamation). Special values 1 -** and 2 for the iSrcLine parameter mean that this particular branch is -** always taken or never taken, respectively. -*/ -#if !defined(SQLITE_VDBE_COVERAGE) -# define VdbeBranchTaken(I,M) -#else -# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) - static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ - if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ - M = iSrcLine; - /* Assert the truth of VdbeCoverageAlwaysTaken() and - ** VdbeCoverageNeverTaken() */ - assert( (M & I)==I ); - }else{ - if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ - sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, - iSrcLine,I,M); - } - } -#endif - -/* -** Convert the given register into a string if it isn't one -** already. Return non-zero if a malloc() fails. -*/ -#define Stringify(P, enc) \ - if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \ - { goto no_mem; } - -/* -** An ephemeral string value (signified by the MEM_Ephem flag) contains -** a pointer to a dynamically allocated string where some other entity -** is responsible for deallocating that string. Because the register -** does not control the string, it might be deleted without the register -** knowing it. -** -** This routine converts an ephemeral string into a dynamically allocated -** string that the register itself controls. In other words, it -** converts an MEM_Ephem string into a string with P.z==P.zMalloc. -*/ -#define Deephemeralize(P) \ - if( ((P)->flags&MEM_Ephem)!=0 \ - && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} - -/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ -#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER) - -/* -** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL -** if we run out of memory. -*/ -static VdbeCursor *allocateCursor( - Vdbe *p, /* The virtual machine */ - int iCur, /* Index of the new VdbeCursor */ - int nField, /* Number of fields in the table or index */ - int iDb, /* Database the cursor belongs to, or -1 */ - u8 eCurType /* Type of the new cursor */ -){ - /* Find the memory cell that will be used to store the blob of memory - ** required for this VdbeCursor structure. It is convenient to use a - ** vdbe memory cell to manage the memory allocation required for a - ** VdbeCursor structure for the following reasons: - ** - ** * Sometimes cursor numbers are used for a couple of different - ** purposes in a vdbe program. The different uses might require - ** different sized allocations. Memory cells provide growable - ** allocations. - ** - ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can - ** be freed lazily via the sqlite3_release_memory() API. This - ** minimizes the number of malloc calls made by the system. - ** - ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from - ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. - ** Cursor 2 is at Mem[p->nMem-2]. And so forth. - */ - Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; - - int nByte; - VdbeCursor *pCx = 0; - nByte = - ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + - (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); - - assert( iCur>=0 && iCurnCursor ); - if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); - p->apCsr[iCur] = 0; - } - if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ - p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; - memset(pCx, 0, sizeof(VdbeCursor)); - pCx->eCurType = eCurType; - pCx->iDb = iDb; - pCx->nField = nField; - pCx->aOffset = &pCx->aType[nField]; - if( eCurType==CURTYPE_BTREE ){ - pCx->uc.pCursor = (BtCursor*) - &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; - sqlite3BtreeCursorZero(pCx->uc.pCursor); - } - } - return pCx; -} - -/* -** Try to convert a value into a numeric representation if we can -** do so without loss of information. In other words, if the string -** looks like a number, convert it into a number. If it does not -** look like a number, leave it alone. -** -** If the bTryForInt flag is true, then extra effort is made to give -** an integer representation. Strings that look like floating point -** values but which have no fractional component (example: '48.00') -** will have a MEM_Int representation when bTryForInt is true. -** -** If bTryForInt is false, then if the input string contains a decimal -** point or exponential notation, the result is only MEM_Real, even -** if there is an exact integer representation of the quantity. -*/ -static void applyNumericAffinity(Mem *pRec, int bTryForInt){ - double rValue; - i64 iValue; - u8 enc = pRec->enc; - assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); - if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; - if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ - pRec->u.i = iValue; - pRec->flags |= MEM_Int; - }else{ - pRec->u.r = rValue; - pRec->flags |= MEM_Real; - if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); - } -} - -/* -** Processing is determine by the affinity parameter: -** -** SQLITE_AFF_INTEGER: -** SQLITE_AFF_REAL: -** SQLITE_AFF_NUMERIC: -** Try to convert pRec to an integer representation or a -** floating-point representation if an integer representation -** is not possible. Note that the integer representation is -** always preferred, even if the affinity is REAL, because -** an integer representation is more space efficient on disk. -** -** SQLITE_AFF_TEXT: -** Convert pRec to a text representation. -** -** SQLITE_AFF_BLOB: -** No-op. pRec is unchanged. -*/ -static void applyAffinity( - Mem *pRec, /* The value to apply affinity to */ - char affinity, /* The affinity to be applied */ - u8 enc /* Use this text encoding */ -){ - if( affinity>=SQLITE_AFF_NUMERIC ){ - assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL - || affinity==SQLITE_AFF_NUMERIC ); - if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ - if( (pRec->flags & MEM_Real)==0 ){ - if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); - }else{ - sqlite3VdbeIntegerAffinity(pRec); - } - } - }else if( affinity==SQLITE_AFF_TEXT ){ - /* Only attempt the conversion to TEXT if there is an integer or real - ** representation (blob and NULL do not get converted) but no string - ** representation. It would be harmless to repeat the conversion if - ** there is already a string rep, but it is pointless to waste those - ** CPU cycles. */ - if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ - if( (pRec->flags&(MEM_Real|MEM_Int)) ){ - sqlite3VdbeMemStringify(pRec, enc, 1); - } - } - pRec->flags &= ~(MEM_Real|MEM_Int); - } -} - -/* -** Try to convert the type of a function argument or a result column -** into a numeric representation. Use either INTEGER or REAL whichever -** is appropriate. But only do the conversion if it is possible without -** loss of information and return the revised type of the argument. -*/ -SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ - int eType = sqlite3_value_type(pVal); - if( eType==SQLITE_TEXT ){ - Mem *pMem = (Mem*)pVal; - applyNumericAffinity(pMem, 0); - eType = sqlite3_value_type(pVal); - } - return eType; -} - -/* -** Exported version of applyAffinity(). This one works on sqlite3_value*, -** not the internal Mem* type. -*/ -SQLITE_PRIVATE void sqlite3ValueApplyAffinity( - sqlite3_value *pVal, - u8 affinity, - u8 enc -){ - applyAffinity((Mem *)pVal, affinity, enc); -} - -/* -** pMem currently only holds a string type (or maybe a BLOB that we can -** interpret as a string if we want to). Compute its corresponding -** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields -** accordingly. -*/ -static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ - assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); - assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); - if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ - return 0; - } - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ - return MEM_Int; - } - return MEM_Real; -} - -/* -** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or -** none. -** -** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. -** But it does set pMem->u.r and pMem->u.i appropriately. -*/ -static u16 numericType(Mem *pMem){ - if( pMem->flags & (MEM_Int|MEM_Real) ){ - return pMem->flags & (MEM_Int|MEM_Real); - } - if( pMem->flags & (MEM_Str|MEM_Blob) ){ - return computeNumericType(pMem); - } - return 0; -} - -#ifdef SQLITE_DEBUG -/* -** Write a nice string representation of the contents of cell pMem -** into buffer zBuf, length nBuf. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ - char *zCsr = zBuf; - int f = pMem->flags; - - static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; - - if( f&MEM_Blob ){ - int i; - char c; - if( f & MEM_Dyn ){ - c = 'z'; - assert( (f & (MEM_Static|MEM_Ephem))==0 ); - }else if( f & MEM_Static ){ - c = 't'; - assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); - }else if( f & MEM_Ephem ){ - c = 'e'; - assert( (f & (MEM_Static|MEM_Dyn))==0 ); - }else{ - c = 's'; - } - - sqlite3_snprintf(100, zCsr, "%c", c); - zCsr += sqlite3Strlen30(zCsr); - sqlite3_snprintf(100, zCsr, "%d[", pMem->n); - zCsr += sqlite3Strlen30(zCsr); - for(i=0; i<16 && in; i++){ - sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); - zCsr += sqlite3Strlen30(zCsr); - } - for(i=0; i<16 && in; i++){ - char z = pMem->z[i]; - if( z<32 || z>126 ) *zCsr++ = '.'; - else *zCsr++ = z; - } - - sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]); - zCsr += sqlite3Strlen30(zCsr); - if( f & MEM_Zero ){ - sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero); - zCsr += sqlite3Strlen30(zCsr); - } - *zCsr = '\0'; - }else if( f & MEM_Str ){ - int j, k; - zBuf[0] = ' '; - if( f & MEM_Dyn ){ - zBuf[1] = 'z'; - assert( (f & (MEM_Static|MEM_Ephem))==0 ); - }else if( f & MEM_Static ){ - zBuf[1] = 't'; - assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); - }else if( f & MEM_Ephem ){ - zBuf[1] = 'e'; - assert( (f & (MEM_Static|MEM_Dyn))==0 ); - }else{ - zBuf[1] = 's'; - } - k = 2; - sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); - k += sqlite3Strlen30(&zBuf[k]); - zBuf[k++] = '['; - for(j=0; j<15 && jn; j++){ - u8 c = pMem->z[j]; - if( c>=0x20 && c<0x7f ){ - zBuf[k++] = c; - }else{ - zBuf[k++] = '.'; - } - } - zBuf[k++] = ']'; - sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]); - k += sqlite3Strlen30(&zBuf[k]); - zBuf[k++] = 0; - } -} -#endif - -#ifdef SQLITE_DEBUG -/* -** Print the value of a register for tracing purposes: -*/ -static void memTracePrint(Mem *p){ - if( p->flags & MEM_Undefined ){ - printf(" undefined"); - }else if( p->flags & MEM_Null ){ - printf(" NULL"); - }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ - printf(" si:%lld", p->u.i); - }else if( p->flags & MEM_Int ){ - printf(" i:%lld", p->u.i); -#ifndef SQLITE_OMIT_FLOATING_POINT - }else if( p->flags & MEM_Real ){ - printf(" r:%g", p->u.r); -#endif - }else if( p->flags & MEM_RowSet ){ - printf(" (rowset)"); - }else{ - char zBuf[200]; - sqlite3VdbeMemPrettyPrint(p, zBuf); - printf(" %s", zBuf); - } - if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); -} -static void registerTrace(int iReg, Mem *p){ - printf("REG[%d] = ", iReg); - memTracePrint(p); - printf("\n"); -} -#endif - -#ifdef SQLITE_DEBUG -# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) -#else -# define REGISTER_TRACE(R,M) -#endif - - -#ifdef VDBE_PROFILE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of vdbe.c *********************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - #error Need implementation of sqlite3Hwtime() for your platform. - - /* - ** To compile without implementing sqlite3Hwtime() for your platform, - ** you can remove the above #error and use the following - ** stub function. You will lose timing support for many - ** of the debugging and testing utilities, but it should at - ** least compile and run. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in vdbe.c ***********************/ - -#endif - -#ifndef NDEBUG -/* -** This function is only called from within an assert() expression. It -** checks that the sqlite3.nTransaction variable is correctly set to -** the number of non-transaction savepoints currently in the -** linked list starting at sqlite3.pSavepoint. -** -** Usage: -** -** assert( checkSavepointCount(db) ); -*/ -static int checkSavepointCount(sqlite3 *db){ - int n = 0; - Savepoint *p; - for(p=db->pSavepoint; p; p=p->pNext) n++; - assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); - return 1; -} -#endif - -/* -** Return the register of pOp->p2 after first preparing it to be -** overwritten with an integer value. -*/ -static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ - sqlite3VdbeMemSetNull(pOut); - pOut->flags = MEM_Int; - return pOut; -} -static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ - Mem *pOut; - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); - pOut = &p->aMem[pOp->p2]; - memAboutToChange(p, pOut); - if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ - return out2PrereleaseWithClear(pOut); - }else{ - pOut->flags = MEM_Int; - return pOut; - } -} - - -/* -** Execute as much of a VDBE program as we can. -** This is the core of sqlite3_step(). -*/ -SQLITE_PRIVATE int sqlite3VdbeExec( - Vdbe *p /* The VDBE */ -){ - Op *aOp = p->aOp; /* Copy of p->aOp */ - Op *pOp = aOp; /* Current operation */ -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) - Op *pOrigOp; /* Value of pOp at the top of the loop */ -#endif -#ifdef SQLITE_DEBUG - int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ -#endif - int rc = SQLITE_OK; /* Value to return */ - sqlite3 *db = p->db; /* The database */ - u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ - u8 encoding = ENC(db); /* The database encoding */ - int iCompare = 0; /* Result of last comparison */ - unsigned nVmStep = 0; /* Number of virtual machine steps */ -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */ -#endif - Mem *aMem = p->aMem; /* Copy of p->aMem */ - Mem *pIn1 = 0; /* 1st input operand */ - Mem *pIn2 = 0; /* 2nd input operand */ - Mem *pIn3 = 0; /* 3rd input operand */ - Mem *pOut = 0; /* Output operand */ - int *aPermute = 0; /* Permutation of columns for OP_Compare */ - i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ -#ifdef VDBE_PROFILE - u64 start; /* CPU clock count at start of opcode */ -#endif - /*** INSERT STACK UNION HERE ***/ - - assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ - sqlite3VdbeEnter(p); - if( p->rc==SQLITE_NOMEM ){ - /* This happens if a malloc() inside a call to sqlite3_column_text() or - ** sqlite3_column_text16() failed. */ - goto no_mem; - } - assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); - assert( p->bIsReader || p->readOnly!=0 ); - p->rc = SQLITE_OK; - p->iCurrentTime = 0; - assert( p->explain==0 ); - p->pResultSet = 0; - db->busyHandler.nBusy = 0; - if( db->u1.isInterrupted ) goto abort_due_to_interrupt; - sqlite3VdbeIOTraceSql(p); -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress ){ - u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; - assert( 0 < db->nProgressOps ); - nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); - } -#endif -#ifdef SQLITE_DEBUG - sqlite3BeginBenignMalloc(); - if( p->pc==0 - && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 - ){ - int i; - int once = 1; - sqlite3VdbePrintSql(p); - if( p->db->flags & SQLITE_VdbeListing ){ - printf("VDBE Program Listing:\n"); - for(i=0; inOp; i++){ - sqlite3VdbePrintOp(stdout, i, &aOp[i]); - } - } - if( p->db->flags & SQLITE_VdbeEQP ){ - for(i=0; inOp; i++){ - if( aOp[i].opcode==OP_Explain ){ - if( once ) printf("VDBE Query Plan:\n"); - printf("%s\n", aOp[i].p4.z); - once = 0; - } - } - } - if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); - } - sqlite3EndBenignMalloc(); -#endif - for(pOp=&aOp[p->pc]; 1; pOp++){ - /* Errors are detected by individual opcodes, with an immediate - ** jumps to abort_due_to_error. */ - assert( rc==SQLITE_OK ); - - assert( pOp>=aOp && pOp<&aOp[p->nOp]); -#ifdef VDBE_PROFILE - start = sqlite3Hwtime(); -#endif - nVmStep++; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; -#endif - - /* Only allow tracing if SQLITE_DEBUG is defined. - */ -#ifdef SQLITE_DEBUG - if( db->flags & SQLITE_VdbeTrace ){ - sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); - } -#endif - - - /* Check to see if we need to simulate an interrupt. This only happens - ** if we have a special test build. - */ -#ifdef SQLITE_TEST - if( sqlite3_interrupt_count>0 ){ - sqlite3_interrupt_count--; - if( sqlite3_interrupt_count==0 ){ - sqlite3_interrupt(db); - } - } -#endif - - /* Sanity checking on other operands */ -#ifdef SQLITE_DEBUG - { - u8 opProperty = sqlite3OpcodeProperty[pOp->opcode]; - if( (opProperty & OPFLG_IN1)!=0 ){ - assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p1]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); - REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); - } - if( (opProperty & OPFLG_IN2)!=0 ){ - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p2]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); - REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); - } - if( (opProperty & OPFLG_IN3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - assert( memIsValid(&aMem[pOp->p3]) ); - assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); - REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); - } - if( (opProperty & OPFLG_OUT2)!=0 ){ - assert( pOp->p2>0 ); - assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); - memAboutToChange(p, &aMem[pOp->p2]); - } - if( (opProperty & OPFLG_OUT3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - memAboutToChange(p, &aMem[pOp->p3]); - } - } -#endif -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) - pOrigOp = pOp; -#endif - - switch( pOp->opcode ){ - -/***************************************************************************** -** What follows is a massive switch statement where each case implements a -** separate instruction in the virtual machine. If we follow the usual -** indentation conventions, each case should be indented by 6 spaces. But -** that is a lot of wasted space on the left margin. So the code within -** the switch statement will break with convention and be flush-left. Another -** big comment (similar to this one) will mark the point in the code where -** we transition back to normal indentation. -** -** The formatting of each case is important. The makefile for SQLite -** generates two C files "opcodes.h" and "opcodes.c" by scanning this -** file looking for lines that begin with "case OP_". The opcodes.h files -** will be filled with #defines that give unique integer values to each -** opcode and the opcodes.c file is filled with an array of strings where -** each string is the symbolic name for the corresponding opcode. If the -** case statement is followed by a comment of the form "/# same as ... #/" -** that comment is used to determine the particular value of the opcode. -** -** Other keywords in the comment that follows each case are used to -** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. -** Keywords include: in1, in2, in3, out2, out3. See -** the mkopcodeh.awk script for additional information. -** -** Documentation about VDBE opcodes is generated by scanning this file -** for lines of that contain "Opcode:". That line and all subsequent -** comment lines are used in the generation of the opcode.html documentation -** file. -** -** SUMMARY: -** -** Formatting is important to scripts that scan this file. -** Do not deviate from the formatting style currently in use. -** -*****************************************************************************/ - -/* Opcode: Goto * P2 * * * -** -** An unconditional jump to address P2. -** The next instruction executed will be -** the one at index P2 from the beginning of -** the program. -** -** The P1 parameter is not actually used by this opcode. However, it -** is sometimes set to 1 instead of 0 as a hint to the command-line shell -** that this Goto is the bottom of a loop and that the lines from P2 down -** to the current line should be indented for EXPLAIN output. -*/ -case OP_Goto: { /* jump */ -jump_to_p2_and_check_for_interrupt: - pOp = &aOp[pOp->p2 - 1]; - - /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, - ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon - ** completion. Check to see if sqlite3_interrupt() has been called - ** or if the progress callback needs to be invoked. - ** - ** This code uses unstructured "goto" statements and does not look clean. - ** But that is not due to sloppy coding habits. The code is written this - ** way for performance, to avoid having to run the interrupt and progress - ** checks on every opcode. This helps sqlite3_step() to run about 1.5% - ** faster according to "valgrind --tool=cachegrind" */ -check_for_interrupt: - if( db->u1.isInterrupted ) goto abort_due_to_interrupt; -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - /* Call the progress callback if it is configured and the required number - ** of VDBE ops have been executed (either since this invocation of - ** sqlite3VdbeExec() or since last time the progress callback was called). - ** If the progress callback returns non-zero, exit the virtual machine with - ** a return code SQLITE_ABORT. - */ - if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ - assert( db->nProgressOps!=0 ); - nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); - if( db->xProgress(db->pProgressArg) ){ - rc = SQLITE_INTERRUPT; - goto abort_due_to_error; - } - } -#endif - - break; -} - -/* Opcode: Gosub P1 P2 * * * -** -** Write the current address onto register P1 -** and then jump to address P2. -*/ -case OP_Gosub: { /* jump */ - assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); - pIn1 = &aMem[pOp->p1]; - assert( VdbeMemDynamic(pIn1)==0 ); - memAboutToChange(p, pIn1); - pIn1->flags = MEM_Int; - pIn1->u.i = (int)(pOp-aOp); - REGISTER_TRACE(pOp->p1, pIn1); - - /* Most jump operations do a goto to this spot in order to update - ** the pOp pointer. */ -jump_to_p2: - pOp = &aOp[pOp->p2 - 1]; - break; -} - -/* Opcode: Return P1 * * * * -** -** Jump to the next instruction after the address in register P1. After -** the jump, register P1 becomes undefined. -*/ -case OP_Return: { /* in1 */ - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags==MEM_Int ); - pOp = &aOp[pIn1->u.i]; - pIn1->flags = MEM_Undefined; - break; -} - -/* Opcode: InitCoroutine P1 P2 P3 * * -** -** Set up register P1 so that it will Yield to the coroutine -** located at address P3. -** -** If P2!=0 then the coroutine implementation immediately follows -** this opcode. So jump over the coroutine implementation to -** address P2. -** -** See also: EndCoroutine -*/ -case OP_InitCoroutine: { /* jump */ - assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); - assert( pOp->p2>=0 && pOp->p2nOp ); - assert( pOp->p3>=0 && pOp->p3nOp ); - pOut = &aMem[pOp->p1]; - assert( !VdbeMemDynamic(pOut) ); - pOut->u.i = pOp->p3 - 1; - pOut->flags = MEM_Int; - if( pOp->p2 ) goto jump_to_p2; - break; -} - -/* Opcode: EndCoroutine P1 * * * * -** -** The instruction at the address in register P1 is a Yield. -** Jump to the P2 parameter of that Yield. -** After the jump, register P1 becomes undefined. -** -** See also: InitCoroutine -*/ -case OP_EndCoroutine: { /* in1 */ - VdbeOp *pCaller; - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags==MEM_Int ); - assert( pIn1->u.i>=0 && pIn1->u.inOp ); - pCaller = &aOp[pIn1->u.i]; - assert( pCaller->opcode==OP_Yield ); - assert( pCaller->p2>=0 && pCaller->p2nOp ); - pOp = &aOp[pCaller->p2 - 1]; - pIn1->flags = MEM_Undefined; - break; -} - -/* Opcode: Yield P1 P2 * * * -** -** Swap the program counter with the value in register P1. This -** has the effect of yielding to a coroutine. -** -** If the coroutine that is launched by this instruction ends with -** Yield or Return then continue to the next instruction. But if -** the coroutine launched by this instruction ends with -** EndCoroutine, then jump to P2 rather than continuing with the -** next instruction. -** -** See also: InitCoroutine -*/ -case OP_Yield: { /* in1, jump */ - int pcDest; - pIn1 = &aMem[pOp->p1]; - assert( VdbeMemDynamic(pIn1)==0 ); - pIn1->flags = MEM_Int; - pcDest = (int)pIn1->u.i; - pIn1->u.i = (int)(pOp - aOp); - REGISTER_TRACE(pOp->p1, pIn1); - pOp = &aOp[pcDest]; - break; -} - -/* Opcode: HaltIfNull P1 P2 P3 P4 P5 -** Synopsis: if r[P3]=null halt -** -** Check the value in register P3. If it is NULL then Halt using -** parameter P1, P2, and P4 as if this were a Halt instruction. If the -** value in register P3 is not NULL, then this routine is a no-op. -** The P5 parameter should be 1. -*/ -case OP_HaltIfNull: { /* in3 */ - pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & MEM_Null)==0 ) break; - /* Fall through into OP_Halt */ -} - -/* Opcode: Halt P1 P2 * P4 P5 -** -** Exit immediately. All open cursors, etc are closed -** automatically. -** -** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), -** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). -** For errors, it can be some other value. If P1!=0 then P2 will determine -** whether or not to rollback the current transaction. Do not rollback -** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, -** then back out all changes that have occurred during this execution of the -** VDBE, but do not rollback the transaction. -** -** If P4 is not null then it is an error message string. -** -** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. -** -** 0: (no change) -** 1: NOT NULL contraint failed: P4 -** 2: UNIQUE constraint failed: P4 -** 3: CHECK constraint failed: P4 -** 4: FOREIGN KEY constraint failed: P4 -** -** If P5 is not zero and P4 is NULL, then everything after the ":" is -** omitted. -** -** There is an implied "Halt 0 0 0" instruction inserted at the very end of -** every program. So a jump past the last instruction of the program -** is the same as executing Halt. -*/ -case OP_Halt: { - VdbeFrame *pFrame; - int pcx; - - pcx = (int)(pOp - aOp); - if( pOp->p1==SQLITE_OK && p->pFrame ){ - /* Halt the sub-program. Return control to the parent frame. */ - pFrame = p->pFrame; - p->pFrame = pFrame->pParent; - p->nFrame--; - sqlite3VdbeSetChanges(db, p->nChange); - pcx = sqlite3VdbeFrameRestore(pFrame); - lastRowid = db->lastRowid; - if( pOp->p2==OE_Ignore ){ - /* Instruction pcx is the OP_Program that invoked the sub-program - ** currently being halted. If the p2 instruction of this OP_Halt - ** instruction is set to OE_Ignore, then the sub-program is throwing - ** an IGNORE exception. In this case jump to the address specified - ** as the p2 of the calling OP_Program. */ - pcx = p->aOp[pcx].p2-1; - } - aOp = p->aOp; - aMem = p->aMem; - pOp = &aOp[pcx]; - break; - } - p->rc = pOp->p1; - p->errorAction = (u8)pOp->p2; - p->pc = pcx; - assert( pOp->p5>=0 && pOp->p5<=4 ); - if( p->rc ){ - if( pOp->p5 ){ - static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", - "FOREIGN KEY" }; - testcase( pOp->p5==1 ); - testcase( pOp->p5==2 ); - testcase( pOp->p5==3 ); - testcase( pOp->p5==4 ); - sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); - if( pOp->p4.z ){ - p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); - } - }else{ - sqlite3VdbeError(p, "%s", pOp->p4.z); - } - sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); - } - rc = sqlite3VdbeHalt(p); - assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); - if( rc==SQLITE_BUSY ){ - p->rc = SQLITE_BUSY; - }else{ - assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); - assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); - rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; - } - goto vdbe_return; -} - -/* Opcode: Integer P1 P2 * * * -** Synopsis: r[P2]=P1 -** -** The 32-bit integer value P1 is written into register P2. -*/ -case OP_Integer: { /* out2 */ - pOut = out2Prerelease(p, pOp); - pOut->u.i = pOp->p1; - break; -} - -/* Opcode: Int64 * P2 * P4 * -** Synopsis: r[P2]=P4 -** -** P4 is a pointer to a 64-bit integer value. -** Write that value into register P2. -*/ -case OP_Int64: { /* out2 */ - pOut = out2Prerelease(p, pOp); - assert( pOp->p4.pI64!=0 ); - pOut->u.i = *pOp->p4.pI64; - break; -} - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* Opcode: Real * P2 * P4 * -** Synopsis: r[P2]=P4 -** -** P4 is a pointer to a 64-bit floating point value. -** Write that value into register P2. -*/ -case OP_Real: { /* same as TK_FLOAT, out2 */ - pOut = out2Prerelease(p, pOp); - pOut->flags = MEM_Real; - assert( !sqlite3IsNaN(*pOp->p4.pReal) ); - pOut->u.r = *pOp->p4.pReal; - break; -} -#endif - -/* Opcode: String8 * P2 * P4 * -** Synopsis: r[P2]='P4' -** -** P4 points to a nul terminated UTF-8 string. This opcode is transformed -** into a String opcode before it is executed for the first time. During -** this transformation, the length of string P4 is computed and stored -** as the P1 parameter. -*/ -case OP_String8: { /* same as TK_STRING, out2 */ - assert( pOp->p4.z!=0 ); - pOut = out2Prerelease(p, pOp); - pOp->opcode = OP_String; - pOp->p1 = sqlite3Strlen30(pOp->p4.z); - -#ifndef SQLITE_OMIT_UTF16 - if( encoding!=SQLITE_UTF8 ){ - rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); - assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG ); - if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; - assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); - assert( VdbeMemDynamic(pOut)==0 ); - pOut->szMalloc = 0; - pOut->flags |= MEM_Static; - if( pOp->p4type==P4_DYNAMIC ){ - sqlite3DbFree(db, pOp->p4.z); - } - pOp->p4type = P4_DYNAMIC; - pOp->p4.z = pOut->z; - pOp->p1 = pOut->n; - } - testcase( rc==SQLITE_TOOBIG ); -#endif - if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - assert( rc==SQLITE_OK ); - /* Fall through to the next case, OP_String */ -} - -/* Opcode: String P1 P2 P3 P4 P5 -** Synopsis: r[P2]='P4' (len=P1) -** -** The string value P4 of length P1 (bytes) is stored in register P2. -** -** If P3 is not zero and the content of register P3 is equal to P5, then -** the datatype of the register P2 is converted to BLOB. The content is -** the same sequence of bytes, it is merely interpreted as a BLOB instead -** of a string, as if it had been CAST. In other words: -** -** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB) -*/ -case OP_String: { /* out2 */ - assert( pOp->p4.z!=0 ); - pOut = out2Prerelease(p, pOp); - pOut->flags = MEM_Str|MEM_Static|MEM_Term; - pOut->z = pOp->p4.z; - pOut->n = pOp->p1; - pOut->enc = encoding; - UPDATE_MAX_BLOBSIZE(pOut); -#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( pOp->p3>0 ){ - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - pIn3 = &aMem[pOp->p3]; - assert( pIn3->flags & MEM_Int ); - if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; - } -#endif - break; -} - -/* Opcode: Null P1 P2 P3 * * -** Synopsis: r[P2..P3]=NULL -** -** Write a NULL into registers P2. If P3 greater than P2, then also write -** NULL into register P3 and every register in between P2 and P3. If P3 -** is less than P2 (typically P3 is zero) then only register P2 is -** set to NULL. -** -** If the P1 value is non-zero, then also set the MEM_Cleared flag so that -** NULL values will not compare equal even if SQLITE_NULLEQ is set on -** OP_Ne or OP_Eq. -*/ -case OP_Null: { /* out2 */ - int cnt; - u16 nullFlag; - pOut = out2Prerelease(p, pOp); - cnt = pOp->p3-pOp->p2; - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; - pOut->n = 0; - while( cnt>0 ){ - pOut++; - memAboutToChange(p, pOut); - sqlite3VdbeMemSetNull(pOut); - pOut->flags = nullFlag; - pOut->n = 0; - cnt--; - } - break; -} - -/* Opcode: SoftNull P1 * * * * -** Synopsis: r[P1]=NULL -** -** Set register P1 to have the value NULL as seen by the OP_MakeRecord -** instruction, but do not free any string or blob memory associated with -** the register, so that if the value was a string or blob that was -** previously copied using OP_SCopy, the copies will continue to be valid. -*/ -case OP_SoftNull: { - assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); - pOut = &aMem[pOp->p1]; - pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; - break; -} - -/* Opcode: Blob P1 P2 * P4 * -** Synopsis: r[P2]=P4 (len=P1) -** -** P4 points to a blob of data P1 bytes long. Store this -** blob in register P2. -*/ -case OP_Blob: { /* out2 */ - assert( pOp->p1 <= SQLITE_MAX_LENGTH ); - pOut = out2Prerelease(p, pOp); - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); - pOut->enc = encoding; - UPDATE_MAX_BLOBSIZE(pOut); - break; -} - -/* Opcode: Variable P1 P2 * P4 * -** Synopsis: r[P2]=parameter(P1,P4) -** -** Transfer the values of bound parameter P1 into register P2 -** -** If the parameter is named, then its name appears in P4. -** The P4 value is used by sqlite3_bind_parameter_name(). -*/ -case OP_Variable: { /* out2 */ - Mem *pVar; /* Value being transferred */ - - assert( pOp->p1>0 && pOp->p1<=p->nVar ); - assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); - pVar = &p->aVar[pOp->p1 - 1]; - if( sqlite3VdbeMemTooBig(pVar) ){ - goto too_big; - } - pOut = out2Prerelease(p, pOp); - sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); - UPDATE_MAX_BLOBSIZE(pOut); - break; -} - -/* Opcode: Move P1 P2 P3 * * -** Synopsis: r[P2@P3]=r[P1@P3] -** -** Move the P3 values in register P1..P1+P3-1 over into -** registers P2..P2+P3-1. Registers P1..P1+P3-1 are -** left holding a NULL. It is an error for register ranges -** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error -** for P3 to be less than 1. -*/ -case OP_Move: { - int n; /* Number of registers left to copy */ - int p1; /* Register to copy from */ - int p2; /* Register to copy to */ - - n = pOp->p3; - p1 = pOp->p1; - p2 = pOp->p2; - assert( n>0 && p1>0 && p2>0 ); - assert( p1+n<=p2 || p2+n<=p1 ); - - pIn1 = &aMem[p1]; - pOut = &aMem[p2]; - do{ - assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); - assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); - assert( memIsValid(pIn1) ); - memAboutToChange(p, pOut); - sqlite3VdbeMemMove(pOut, pIn1); -#ifdef SQLITE_DEBUG - if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrompScopyFrom += pOp->p2 - p1; - } -#endif - Deephemeralize(pOut); - REGISTER_TRACE(p2++, pOut); - pIn1++; - pOut++; - }while( --n ); - break; -} - -/* Opcode: Copy P1 P2 P3 * * -** Synopsis: r[P2@P3+1]=r[P1@P3+1] -** -** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. -** -** This instruction makes a deep copy of the value. A duplicate -** is made of any string or blob constant. See also OP_SCopy. -*/ -case OP_Copy: { - int n; - - n = pOp->p3; - pIn1 = &aMem[pOp->p1]; - pOut = &aMem[pOp->p2]; - assert( pOut!=pIn1 ); - while( 1 ){ - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); - Deephemeralize(pOut); -#ifdef SQLITE_DEBUG - pOut->pScopyFrom = 0; -#endif - REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); - if( (n--)==0 ) break; - pOut++; - pIn1++; - } - break; -} - -/* Opcode: SCopy P1 P2 * * * -** Synopsis: r[P2]=r[P1] -** -** Make a shallow copy of register P1 into register P2. -** -** This instruction makes a shallow copy of the value. If the value -** is a string or blob, then the copy is only a pointer to the -** original and hence if the original changes so will the copy. -** Worse, if the original is deallocated, the copy becomes invalid. -** Thus the program must guarantee that the original will not change -** during the lifetime of the copy. Use OP_Copy to make a complete -** copy. -*/ -case OP_SCopy: { /* out2 */ - pIn1 = &aMem[pOp->p1]; - pOut = &aMem[pOp->p2]; - assert( pOut!=pIn1 ); - sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); -#ifdef SQLITE_DEBUG - if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; -#endif - break; -} - -/* Opcode: IntCopy P1 P2 * * * -** Synopsis: r[P2]=r[P1] -** -** Transfer the integer value held in register P1 into register P2. -** -** This is an optimized version of SCopy that works only for integer -** values. -*/ -case OP_IntCopy: { /* out2 */ - pIn1 = &aMem[pOp->p1]; - assert( (pIn1->flags & MEM_Int)!=0 ); - pOut = &aMem[pOp->p2]; - sqlite3VdbeMemSetInt64(pOut, pIn1->u.i); - break; -} - -/* Opcode: ResultRow P1 P2 * * * -** Synopsis: output=r[P1@P2] -** -** The registers P1 through P1+P2-1 contain a single row of -** results. This opcode causes the sqlite3_step() call to terminate -** with an SQLITE_ROW return code and it sets up the sqlite3_stmt -** structure to provide access to the r(P1)..r(P1+P2-1) values as -** the result row. -*/ -case OP_ResultRow: { - Mem *pMem; - int i; - assert( p->nResColumn==pOp->p2 ); - assert( pOp->p1>0 ); - assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - /* Run the progress counter just before returning. - */ - if( db->xProgress!=0 - && nVmStep>=nProgressLimit - && db->xProgress(db->pProgressArg)!=0 - ){ - rc = SQLITE_INTERRUPT; - goto abort_due_to_error; - } -#endif - - /* If this statement has violated immediate foreign key constraints, do - ** not return the number of rows modified. And do not RELEASE the statement - ** transaction. It needs to be rolled back. */ - if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ - assert( db->flags&SQLITE_CountRows ); - assert( p->usesStmtJournal ); - goto abort_due_to_error; - } - - /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then - ** DML statements invoke this opcode to return the number of rows - ** modified to the user. This is the only way that a VM that - ** opens a statement transaction may invoke this opcode. - ** - ** In case this is such a statement, close any statement transaction - ** opened by this VM before returning control to the user. This is to - ** ensure that statement-transactions are always nested, not overlapping. - ** If the open statement-transaction is not closed here, then the user - ** may step another VM that opens its own statement transaction. This - ** may lead to overlapping statement transactions. - ** - ** The statement transaction is never a top-level transaction. Hence - ** the RELEASE call below can never fail. - */ - assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); - assert( rc==SQLITE_OK ); - - /* Invalidate all ephemeral cursor row caches */ - p->cacheCtr = (p->cacheCtr + 2)|1; - - /* Make sure the results of the current row are \000 terminated - ** and have an assigned type. The results are de-ephemeralized as - ** a side effect. - */ - pMem = p->pResultSet = &aMem[pOp->p1]; - for(i=0; ip2; i++){ - assert( memIsValid(&pMem[i]) ); - Deephemeralize(&pMem[i]); - assert( (pMem[i].flags & MEM_Ephem)==0 - || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); - sqlite3VdbeMemNulTerminate(&pMem[i]); - REGISTER_TRACE(pOp->p1+i, &pMem[i]); - } - if( db->mallocFailed ) goto no_mem; - - if( db->mTrace & SQLITE_TRACE_ROW ){ - db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); - } - - /* Return SQLITE_ROW - */ - p->pc = (int)(pOp - aOp) + 1; - rc = SQLITE_ROW; - goto vdbe_return; -} - -/* Opcode: Concat P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]+r[P1] -** -** Add the text in register P1 onto the end of the text in -** register P2 and store the result in register P3. -** If either the P1 or P2 text are NULL then store NULL in P3. -** -** P3 = P2 || P1 -** -** It is illegal for P1 and P3 to be the same register. Sometimes, -** if P3 is the same register as P2, the implementation is able -** to avoid a memcpy(). -*/ -case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ - i64 nByte; - - pIn1 = &aMem[pOp->p1]; - pIn2 = &aMem[pOp->p2]; - pOut = &aMem[pOp->p3]; - assert( pIn1!=pOut ); - if( (pIn1->flags | pIn2->flags) & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - break; - } - if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; - Stringify(pIn1, encoding); - Stringify(pIn2, encoding); - nByte = pIn1->n + pIn2->n; - if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ - goto no_mem; - } - MemSetTypeFlag(pOut, MEM_Str); - if( pOut!=pIn2 ){ - memcpy(pOut->z, pIn2->z, pIn2->n); - } - memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); - pOut->z[nByte]=0; - pOut->z[nByte+1] = 0; - pOut->flags |= MEM_Term; - pOut->n = (int)nByte; - pOut->enc = encoding; - UPDATE_MAX_BLOBSIZE(pOut); - break; -} - -/* Opcode: Add P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]+r[P2] -** -** Add the value in register P1 to the value in register P2 -** and store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -/* Opcode: Multiply P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]*r[P2] -** -** -** Multiply the value in register P1 by the value in register P2 -** and store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -/* Opcode: Subtract P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]-r[P1] -** -** Subtract the value in register P1 from the value in register P2 -** and store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -/* Opcode: Divide P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]/r[P1] -** -** Divide the value in register P1 by the value in register P2 -** and store the result in register P3 (P3=P2/P1). If the value in -** register P1 is zero, then the result is NULL. If either input is -** NULL, the result is NULL. -*/ -/* Opcode: Remainder P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]%r[P1] -** -** Compute the remainder after integer register P2 is divided by -** register P1 and store the result in register P3. -** If the value in register P1 is zero the result is NULL. -** If either operand is NULL, the result is NULL. -*/ -case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ -case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ -case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ -case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ -case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ - char bIntint; /* Started out as two integer operands */ - u16 flags; /* Combined MEM_* flags from both inputs */ - u16 type1; /* Numeric type of left operand */ - u16 type2; /* Numeric type of right operand */ - i64 iA; /* Integer value of left operand */ - i64 iB; /* Integer value of right operand */ - double rA; /* Real value of left operand */ - double rB; /* Real value of right operand */ - - pIn1 = &aMem[pOp->p1]; - type1 = numericType(pIn1); - pIn2 = &aMem[pOp->p2]; - type2 = numericType(pIn2); - pOut = &aMem[pOp->p3]; - flags = pIn1->flags | pIn2->flags; - if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; - if( (type1 & type2 & MEM_Int)!=0 ){ - iA = pIn1->u.i; - iB = pIn2->u.i; - bIntint = 1; - switch( pOp->opcode ){ - case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; - case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; - case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; - case OP_Divide: { - if( iA==0 ) goto arithmetic_result_is_null; - if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; - iB /= iA; - break; - } - default: { - if( iA==0 ) goto arithmetic_result_is_null; - if( iA==-1 ) iA = 1; - iB %= iA; - break; - } - } - pOut->u.i = iB; - MemSetTypeFlag(pOut, MEM_Int); - }else{ - bIntint = 0; -fp_math: - rA = sqlite3VdbeRealValue(pIn1); - rB = sqlite3VdbeRealValue(pIn2); - switch( pOp->opcode ){ - case OP_Add: rB += rA; break; - case OP_Subtract: rB -= rA; break; - case OP_Multiply: rB *= rA; break; - case OP_Divide: { - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - if( rA==(double)0 ) goto arithmetic_result_is_null; - rB /= rA; - break; - } - default: { - iA = (i64)rA; - iB = (i64)rB; - if( iA==0 ) goto arithmetic_result_is_null; - if( iA==-1 ) iA = 1; - rB = (double)(iB % iA); - break; - } - } -#ifdef SQLITE_OMIT_FLOATING_POINT - pOut->u.i = rB; - MemSetTypeFlag(pOut, MEM_Int); -#else - if( sqlite3IsNaN(rB) ){ - goto arithmetic_result_is_null; - } - pOut->u.r = rB; - MemSetTypeFlag(pOut, MEM_Real); - if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ - sqlite3VdbeIntegerAffinity(pOut); - } -#endif - } - break; - -arithmetic_result_is_null: - sqlite3VdbeMemSetNull(pOut); - break; -} - -/* Opcode: CollSeq P1 * * P4 -** -** P4 is a pointer to a CollSeq struct. If the next call to a user function -** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will -** be returned. This is used by the built-in min(), max() and nullif() -** functions. -** -** If P1 is not zero, then it is a register that a subsequent min() or -** max() aggregate will set to 1 if the current row is not the minimum or -** maximum. The P1 register is initialized to 0 by this instruction. -** -** The interface used by the implementation of the aforementioned functions -** to retrieve the collation sequence set by this opcode is not available -** publicly. Only built-in functions have access to this feature. -*/ -case OP_CollSeq: { - assert( pOp->p4type==P4_COLLSEQ ); - if( pOp->p1 ){ - sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); - } - break; -} - -/* Opcode: Function0 P1 P2 P3 P4 P5 -** Synopsis: r[P3]=func(r[P2@P5]) -** -** Invoke a user function (P4 is a pointer to a FuncDef object that -** defines the function) with P5 arguments taken from register P2 and -** successors. The result of the function is stored in register P3. -** Register P3 must not be one of the function inputs. -** -** P1 is a 32-bit bitmask indicating whether or not each argument to the -** function was determined to be constant at compile time. If the first -** argument was constant then bit 0 of P1 is set. This is used to determine -** whether meta data associated with a user function argument using the -** sqlite3_set_auxdata() API may be safely retained until the next -** invocation of this opcode. -** -** See also: Function, AggStep, AggFinal -*/ -/* Opcode: Function P1 P2 P3 P4 P5 -** Synopsis: r[P3]=func(r[P2@P5]) -** -** Invoke a user function (P4 is a pointer to an sqlite3_context object that -** contains a pointer to the function to be run) with P5 arguments taken -** from register P2 and successors. The result of the function is stored -** in register P3. Register P3 must not be one of the function inputs. -** -** P1 is a 32-bit bitmask indicating whether or not each argument to the -** function was determined to be constant at compile time. If the first -** argument was constant then bit 0 of P1 is set. This is used to determine -** whether meta data associated with a user function argument using the -** sqlite3_set_auxdata() API may be safely retained until the next -** invocation of this opcode. -** -** SQL functions are initially coded as OP_Function0 with P4 pointing -** to a FuncDef object. But on first evaluation, the P4 operand is -** automatically converted into an sqlite3_context object and the operation -** changed to this OP_Function opcode. In this way, the initialization of -** the sqlite3_context object occurs only once, rather than once for each -** evaluation of the function. -** -** See also: Function0, AggStep, AggFinal -*/ -case OP_Function0: { - int n; - sqlite3_context *pCtx; - - assert( pOp->p4type==P4_FUNCDEF ); - n = pOp->p5; - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); - assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); - if( pCtx==0 ) goto no_mem; - pCtx->pOut = 0; - pCtx->pFunc = pOp->p4.pFunc; - pCtx->iOp = (int)(pOp - aOp); - pCtx->pVdbe = p; - pCtx->argc = n; - pOp->p4type = P4_FUNCCTX; - pOp->p4.pCtx = pCtx; - pOp->opcode = OP_Function; - /* Fall through into OP_Function */ -} -case OP_Function: { - int i; - sqlite3_context *pCtx; - - assert( pOp->p4type==P4_FUNCCTX ); - pCtx = pOp->p4.pCtx; - - /* If this function is inside of a trigger, the register array in aMem[] - ** might change from one evaluation to the next. The next block of code - ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the sqlite3_context object */ - pOut = &aMem[pOp->p3]; - if( pCtx->pOut != pOut ){ - pCtx->pOut = pOut; - for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; - } - - memAboutToChange(p, pCtx->pOut); -#ifdef SQLITE_DEBUG - for(i=0; iargc; i++){ - assert( memIsValid(pCtx->argv[i]) ); - REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); - } -#endif - MemSetTypeFlag(pCtx->pOut, MEM_Null); - pCtx->fErrorOrAux = 0; - db->lastRowid = lastRowid; - (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ - lastRowid = db->lastRowid; /* Remember rowid changes made by xSFunc */ - - /* If the function returned an error, throw an exception */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); - rc = pCtx->isError; - } - sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); - if( rc ) goto abort_due_to_error; - } - - /* Copy the result of the function into register P3 */ - if( pOut->flags & (MEM_Str|MEM_Blob) ){ - sqlite3VdbeChangeEncoding(pCtx->pOut, encoding); - if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big; - } - - REGISTER_TRACE(pOp->p3, pCtx->pOut); - UPDATE_MAX_BLOBSIZE(pCtx->pOut); - break; -} - -/* Opcode: BitAnd P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]&r[P2] -** -** Take the bit-wise AND of the values in register P1 and P2 and -** store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -/* Opcode: BitOr P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]|r[P2] -** -** Take the bit-wise OR of the values in register P1 and P2 and -** store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -/* Opcode: ShiftLeft P1 P2 P3 * * -** Synopsis: r[P3]=r[P2]<>r[P1] -** -** Shift the integer value in register P2 to the right by the -** number of bits specified by the integer in register P1. -** Store the result in register P3. -** If either input is NULL, the result is NULL. -*/ -case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ -case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ -case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ -case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ - i64 iA; - u64 uA; - i64 iB; - u8 op; - - pIn1 = &aMem[pOp->p1]; - pIn2 = &aMem[pOp->p2]; - pOut = &aMem[pOp->p3]; - if( (pIn1->flags | pIn2->flags) & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - break; - } - iA = sqlite3VdbeIntValue(pIn2); - iB = sqlite3VdbeIntValue(pIn1); - op = pOp->opcode; - if( op==OP_BitAnd ){ - iA &= iB; - }else if( op==OP_BitOr ){ - iA |= iB; - }else if( iB!=0 ){ - assert( op==OP_ShiftRight || op==OP_ShiftLeft ); - - /* If shifting by a negative amount, shift in the other direction */ - if( iB<0 ){ - assert( OP_ShiftRight==OP_ShiftLeft+1 ); - op = 2*OP_ShiftLeft + 1 - op; - iB = iB>(-64) ? -iB : 64; - } - - if( iB>=64 ){ - iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; - }else{ - memcpy(&uA, &iA, sizeof(uA)); - if( op==OP_ShiftLeft ){ - uA <<= iB; - }else{ - uA >>= iB; - /* Sign-extend on a right shift of a negative number */ - if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); - } - memcpy(&iA, &uA, sizeof(iA)); - } - } - pOut->u.i = iA; - MemSetTypeFlag(pOut, MEM_Int); - break; -} - -/* Opcode: AddImm P1 P2 * * * -** Synopsis: r[P1]=r[P1]+P2 -** -** Add the constant P2 to the value in register P1. -** The result is always an integer. -** -** To force any register to be an integer, just add 0. -*/ -case OP_AddImm: { /* in1 */ - pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); - sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i += pOp->p2; - break; -} - -/* Opcode: MustBeInt P1 P2 * * * -** -** Force the value in register P1 to be an integer. If the value -** in P1 is not an integer and cannot be converted into an integer -** without data loss, then jump immediately to P2, or if P2==0 -** raise an SQLITE_MISMATCH exception. -*/ -case OP_MustBeInt: { /* jump, in1 */ - pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_Int)==0 ){ - applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); - VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2); - if( (pIn1->flags & MEM_Int)==0 ){ - if( pOp->p2==0 ){ - rc = SQLITE_MISMATCH; - goto abort_due_to_error; - }else{ - goto jump_to_p2; - } - } - } - MemSetTypeFlag(pIn1, MEM_Int); - break; -} - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* Opcode: RealAffinity P1 * * * * -** -** If register P1 holds an integer convert it to a real value. -** -** This opcode is used when extracting information from a column that -** has REAL affinity. Such column values may still be stored as -** integers, for space efficiency, but after extraction we want them -** to have only a real value. -*/ -case OP_RealAffinity: { /* in1 */ - pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Int ){ - sqlite3VdbeMemRealify(pIn1); - } - break; -} -#endif - -#ifndef SQLITE_OMIT_CAST -/* Opcode: Cast P1 P2 * * * -** Synopsis: affinity(r[P1]) -** -** Force the value in register P1 to be the type defined by P2. -** -**
      -**
    • TEXT -**
    • BLOB -**
    • NUMERIC -**
    • INTEGER -**
    • REAL -**
    -** -** A NULL value is not changed by this routine. It remains NULL. -*/ -case OP_Cast: { /* in1 */ - assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL ); - testcase( pOp->p2==SQLITE_AFF_TEXT ); - testcase( pOp->p2==SQLITE_AFF_BLOB ); - testcase( pOp->p2==SQLITE_AFF_NUMERIC ); - testcase( pOp->p2==SQLITE_AFF_INTEGER ); - testcase( pOp->p2==SQLITE_AFF_REAL ); - pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); - rc = ExpandBlob(pIn1); - sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); - UPDATE_MAX_BLOBSIZE(pIn1); - if( rc ) goto abort_due_to_error; - break; -} -#endif /* SQLITE_OMIT_CAST */ - -/* Opcode: Eq P1 P2 P3 P4 P5 -** Synopsis: IF r[P3]==r[P1] -** -** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then -** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then -** store the result of comparison in register P2. -** -** The SQLITE_AFF_MASK portion of P5 must be an affinity character - -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made -** to coerce both inputs according to this affinity before the -** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric -** affinity is used. Note that the affinity conversions are stored -** back into the input registers P1 and P3. So this opcode can cause -** persistent changes to registers P1 and P3. -** -** Once any conversions have taken place, and neither value is NULL, -** the values are compared. If both values are blobs then memcmp() is -** used to determine the results of the comparison. If both values -** are text, then the appropriate collating function specified in -** P4 is used to do the comparison. If P4 is not specified then -** memcmp() is used to compare text string. If both values are -** numeric, then a numeric comparison is used. If the two values -** are of different types, then numbers are considered less than -** strings and strings are considered less than blobs. -** -** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either -** true or false and is never NULL. If both operands are NULL then the result -** of comparison is true. If either operand is NULL then the result is false. -** If neither operand is NULL the result is the same as it would be if -** the SQLITE_NULLEQ flag were omitted from P5. -** -** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only changed if the new value is NULL or 0 (false). -** In other words, a prior r[P2] value will not be overwritten by 1 (true). -*/ -/* Opcode: Ne P1 P2 P3 P4 P5 -** Synopsis: IF r[P3]!=r[P1] -** -** This works just like the Eq opcode except that the jump is taken if -** the operands in registers P1 and P3 are not equal. See the Eq opcode for -** additional information. -** -** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only changed if the new value is NULL or 1 (true). -** In other words, a prior r[P2] value will not be overwritten by 0 (false). -*/ -/* Opcode: Lt P1 P2 P3 P4 P5 -** Synopsis: IF r[P3]r[P1] -** -** This works just like the Lt opcode except that the jump is taken if -** the content of register P3 is greater than the content of -** register P1. See the Lt opcode for additional information. -*/ -/* Opcode: Ge P1 P2 P3 P4 P5 -** Synopsis: IF r[P3]>=r[P1] -** -** This works just like the Lt opcode except that the jump is taken if -** the content of register P3 is greater than or equal to the content of -** register P1. See the Lt opcode for additional information. -*/ -case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ -case OP_Ne: /* same as TK_NE, jump, in1, in3 */ -case OP_Lt: /* same as TK_LT, jump, in1, in3 */ -case OP_Le: /* same as TK_LE, jump, in1, in3 */ -case OP_Gt: /* same as TK_GT, jump, in1, in3 */ -case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ - int res, res2; /* Result of the comparison of pIn1 against pIn3 */ - char affinity; /* Affinity to use for comparison */ - u16 flags1; /* Copy of initial value of pIn1->flags */ - u16 flags3; /* Copy of initial value of pIn3->flags */ - - pIn1 = &aMem[pOp->p1]; - pIn3 = &aMem[pOp->p3]; - flags1 = pIn1->flags; - flags3 = pIn3->flags; - if( (flags1 | flags3)&MEM_Null ){ - /* One or both operands are NULL */ - if( pOp->p5 & SQLITE_NULLEQ ){ - /* If SQLITE_NULLEQ is set (which will only happen if the operator is - ** OP_Eq or OP_Ne) then take the jump or not depending on whether - ** or not both operands are null. - */ - assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); - assert( (flags1 & MEM_Cleared)==0 ); - assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); - if( (flags1&MEM_Null)!=0 - && (flags3&MEM_Null)!=0 - && (flags3&MEM_Cleared)==0 - ){ - res = 0; /* Operands are equal */ - }else{ - res = 1; /* Operands are not equal */ - } - }else{ - /* SQLITE_NULLEQ is clear and at least one operand is NULL, - ** then the result is always NULL. - ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. - */ - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &aMem[pOp->p2]; - iCompare = 1; /* Operands are not equal */ - memAboutToChange(p, pOut); - MemSetTypeFlag(pOut, MEM_Null); - REGISTER_TRACE(pOp->p2, pOut); - }else{ - VdbeBranchTaken(2,3); - if( pOp->p5 & SQLITE_JUMPIFNULL ){ - goto jump_to_p2; - } - } - break; - } - }else{ - /* Neither operand is NULL. Do a comparison. */ - affinity = pOp->p5 & SQLITE_AFF_MASK; - if( affinity>=SQLITE_AFF_NUMERIC ){ - if( (flags1 | flags3)&MEM_Str ){ - if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn1,0); - testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ - flags3 = pIn3->flags; - } - if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn3,0); - } - } - /* Handle the common case of integer comparison here, as an - ** optimization, to avoid a call to sqlite3MemCompare() */ - if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){ - if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; } - if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; } - res = 0; - goto compare_op; - } - }else if( affinity==SQLITE_AFF_TEXT ){ - if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){ - testcase( pIn1->flags & MEM_Int ); - testcase( pIn1->flags & MEM_Real ); - sqlite3VdbeMemStringify(pIn1, encoding, 1); - testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); - flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - assert( pIn1!=pIn3 ); - } - if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ - testcase( pIn3->flags & MEM_Int ); - testcase( pIn3->flags & MEM_Real ); - sqlite3VdbeMemStringify(pIn3, encoding, 1); - testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); - flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); - } - } - assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); - res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); - } -compare_op: - switch( pOp->opcode ){ - case OP_Eq: res2 = res==0; break; - case OP_Ne: res2 = res; break; - case OP_Lt: res2 = res<0; break; - case OP_Le: res2 = res<=0; break; - case OP_Gt: res2 = res>0; break; - default: res2 = res>=0; break; - } - - /* Undo any changes made by applyAffinity() to the input registers. */ - assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); - pIn1->flags = flags1; - assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); - pIn3->flags = flags3; - - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &aMem[pOp->p2]; - iCompare = res; - res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */ - if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){ - /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 - ** and prevents OP_Ne from overwriting NULL with 0. This flag - ** is only used in contexts where either: - ** (1) op==OP_Eq && (r[P2]==NULL || r[P2]==0) - ** (2) op==OP_Ne && (r[P2]==NULL || r[P2]==1) - ** Therefore it is not necessary to check the content of r[P2] for - ** NULL. */ - assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq ); - assert( res2==0 || res2==1 ); - testcase( res2==0 && pOp->opcode==OP_Eq ); - testcase( res2==1 && pOp->opcode==OP_Eq ); - testcase( res2==0 && pOp->opcode==OP_Ne ); - testcase( res2==1 && pOp->opcode==OP_Ne ); - if( (pOp->opcode==OP_Eq)==res2 ) break; - } - memAboutToChange(p, pOut); - MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = res2; - REGISTER_TRACE(pOp->p2, pOut); - }else{ - VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); - if( res2 ){ - goto jump_to_p2; - } - } - break; -} - -/* Opcode: ElseNotEq * P2 * * * -** -** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator. -** If result of an OP_Eq comparison on the same two operands -** would have be NULL or false (0), then then jump to P2. -** If the result of an OP_Eq comparison on the two previous operands -** would have been true (1), then fall through. -*/ -case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ - assert( pOp>aOp ); - assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt ); - assert( pOp[-1].p5 & SQLITE_STOREP2 ); - VdbeBranchTaken(iCompare!=0, 2); - if( iCompare!=0 ) goto jump_to_p2; - break; -} - - -/* Opcode: Permutation * * * P4 * -** -** Set the permutation used by the OP_Compare operator to be the array -** of integers in P4. -** -** The permutation is only valid until the next OP_Compare that has -** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should -** occur immediately prior to the OP_Compare. -** -** The first integer in the P4 integer array is the length of the array -** and does not become part of the permutation. -*/ -case OP_Permutation: { - assert( pOp->p4type==P4_INTARRAY ); - assert( pOp->p4.ai ); - aPermute = pOp->p4.ai + 1; - break; -} - -/* Opcode: Compare P1 P2 P3 P4 P5 -** Synopsis: r[P1@P3] <-> r[P2@P3] -** -** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this -** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of -** the comparison for use by the next OP_Jump instruct. -** -** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is -** determined by the most recent OP_Permutation operator. If the -** OPFLAG_PERMUTE bit is clear, then register are compared in sequential -** order. -** -** P4 is a KeyInfo structure that defines collating sequences and sort -** orders for the comparison. The permutation applies to registers -** only. The KeyInfo elements are used sequentially. -** -** The comparison is a sort comparison, so NULLs compare equal, -** NULLs are less than numbers, numbers are less than strings, -** and strings are less than blobs. -*/ -case OP_Compare: { - int n; - int i; - int p1; - int p2; - const KeyInfo *pKeyInfo; - int idx; - CollSeq *pColl; /* Collating sequence to use on this term */ - int bRev; /* True for DESCENDING sort order */ - - if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0; - n = pOp->p3; - pKeyInfo = pOp->p4.pKeyInfo; - assert( n>0 ); - assert( pKeyInfo!=0 ); - p1 = pOp->p1; - p2 = pOp->p2; -#if SQLITE_DEBUG - if( aPermute ){ - int k, mx = 0; - for(k=0; kmx ) mx = aPermute[k]; - assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); - assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); - }else{ - assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); - assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); - } -#endif /* SQLITE_DEBUG */ - for(i=0; inField ); - pColl = pKeyInfo->aColl[i]; - bRev = pKeyInfo->aSortOrder[i]; - iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); - if( iCompare ){ - if( bRev ) iCompare = -iCompare; - break; - } - } - aPermute = 0; - break; -} - -/* Opcode: Jump P1 P2 P3 * * -** -** Jump to the instruction at address P1, P2, or P3 depending on whether -** in the most recent OP_Compare instruction the P1 vector was less than -** equal to, or greater than the P2 vector, respectively. -*/ -case OP_Jump: { /* jump */ - if( iCompare<0 ){ - VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; - }else if( iCompare==0 ){ - VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; - }else{ - VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; - } - break; -} - -/* Opcode: And P1 P2 P3 * * -** Synopsis: r[P3]=(r[P1] && r[P2]) -** -** Take the logical AND of the values in registers P1 and P2 and -** write the result into register P3. -** -** If either P1 or P2 is 0 (false) then the result is 0 even if -** the other input is NULL. A NULL and true or two NULLs give -** a NULL output. -*/ -/* Opcode: Or P1 P2 P3 * * -** Synopsis: r[P3]=(r[P1] || r[P2]) -** -** Take the logical OR of the values in register P1 and P2 and -** store the answer in register P3. -** -** If either P1 or P2 is nonzero (true) then the result is 1 (true) -** even if the other input is NULL. A NULL and false or two NULLs -** give a NULL output. -*/ -case OP_And: /* same as TK_AND, in1, in2, out3 */ -case OP_Or: { /* same as TK_OR, in1, in2, out3 */ - int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - - pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Null ){ - v1 = 2; - }else{ - v1 = sqlite3VdbeIntValue(pIn1)!=0; - } - pIn2 = &aMem[pOp->p2]; - if( pIn2->flags & MEM_Null ){ - v2 = 2; - }else{ - v2 = sqlite3VdbeIntValue(pIn2)!=0; - } - if( pOp->opcode==OP_And ){ - static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; - v1 = and_logic[v1*3+v2]; - }else{ - static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; - v1 = or_logic[v1*3+v2]; - } - pOut = &aMem[pOp->p3]; - if( v1==2 ){ - MemSetTypeFlag(pOut, MEM_Null); - }else{ - pOut->u.i = v1; - MemSetTypeFlag(pOut, MEM_Int); - } - break; -} - -/* Opcode: Not P1 P2 * * * -** Synopsis: r[P2]= !r[P1] -** -** Interpret the value in register P1 as a boolean value. Store the -** boolean complement in register P2. If the value in register P1 is -** NULL, then a NULL is stored in P2. -*/ -case OP_Not: { /* same as TK_NOT, in1, out2 */ - pIn1 = &aMem[pOp->p1]; - pOut = &aMem[pOp->p2]; - sqlite3VdbeMemSetNull(pOut); - if( (pIn1->flags & MEM_Null)==0 ){ - pOut->flags = MEM_Int; - pOut->u.i = !sqlite3VdbeIntValue(pIn1); - } - break; -} - -/* Opcode: BitNot P1 P2 * * * -** Synopsis: r[P1]= ~r[P1] -** -** Interpret the content of register P1 as an integer. Store the -** ones-complement of the P1 value into register P2. If P1 holds -** a NULL then store a NULL in P2. -*/ -case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ - pIn1 = &aMem[pOp->p1]; - pOut = &aMem[pOp->p2]; - sqlite3VdbeMemSetNull(pOut); - if( (pIn1->flags & MEM_Null)==0 ){ - pOut->flags = MEM_Int; - pOut->u.i = ~sqlite3VdbeIntValue(pIn1); - } - break; -} - -/* Opcode: Once P1 P2 * * * -** -** If the P1 value is equal to the P1 value on the OP_Init opcode at -** instruction 0, then jump to P2. If the two P1 values differ, then -** set the P1 value on this opcode to equal the P1 value on the OP_Init -** and fall through. -*/ -case OP_Once: { /* jump */ - assert( p->aOp[0].opcode==OP_Init ); - VdbeBranchTaken(p->aOp[0].p1==pOp->p1, 2); - if( p->aOp[0].p1==pOp->p1 ){ - goto jump_to_p2; - }else{ - pOp->p1 = p->aOp[0].p1; - } - break; -} - -/* Opcode: If P1 P2 P3 * * -** -** Jump to P2 if the value in register P1 is true. The value -** is considered true if it is numeric and non-zero. If the value -** in P1 is NULL then take the jump if and only if P3 is non-zero. -*/ -/* Opcode: IfNot P1 P2 P3 * * -** -** Jump to P2 if the value in register P1 is False. The value -** is considered false if it has a numeric value of zero. If the value -** in P1 is NULL then take the jump if and only if P3 is non-zero. -*/ -case OP_If: /* jump, in1 */ -case OP_IfNot: { /* jump, in1 */ - int c; - pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Null ){ - c = pOp->p3; - }else{ -#ifdef SQLITE_OMIT_FLOATING_POINT - c = sqlite3VdbeIntValue(pIn1)!=0; -#else - c = sqlite3VdbeRealValue(pIn1)!=0.0; -#endif - if( pOp->opcode==OP_IfNot ) c = !c; - } - VdbeBranchTaken(c!=0, 2); - if( c ){ - goto jump_to_p2; - } - break; -} - -/* Opcode: IsNull P1 P2 * * * -** Synopsis: if r[P1]==NULL goto P2 -** -** Jump to P2 if the value in register P1 is NULL. -*/ -case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ - pIn1 = &aMem[pOp->p1]; - VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); - if( (pIn1->flags & MEM_Null)!=0 ){ - goto jump_to_p2; - } - break; -} - -/* Opcode: NotNull P1 P2 * * * -** Synopsis: if r[P1]!=NULL goto P2 -** -** Jump to P2 if the value in register P1 is not NULL. -*/ -case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ - pIn1 = &aMem[pOp->p1]; - VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); - if( (pIn1->flags & MEM_Null)==0 ){ - goto jump_to_p2; - } - break; -} - -/* Opcode: Column P1 P2 P3 P4 P5 -** Synopsis: r[P3]=PX -** -** Interpret the data that cursor P1 points to as a structure built using -** the MakeRecord instruction. (See the MakeRecord opcode for additional -** information about the format of the data.) Extract the P2-th column -** from this record. If there are less that (P2+1) -** values in the record, extract a NULL. -** -** The value extracted is stored in register P3. -** -** If the column contains fewer than P2 fields, then extract a NULL. Or, -** if the P4 argument is a P4_MEM use the value of the P4 argument as -** the result. -** -** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, -** then the cache of the cursor is reset prior to extracting the column. -** The first OP_Column against a pseudo-table after the value of the content -** register has changed should have this bit set. -** -** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when -** the result is guaranteed to only be used as the argument of a length() -** or typeof() function, respectively. The loading of large blobs can be -** skipped for length() and all content loading can be skipped for typeof(). -*/ -case OP_Column: { - int p2; /* column number to retrieve */ - VdbeCursor *pC; /* The VDBE cursor */ - BtCursor *pCrsr; /* The BTree cursor */ - u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ - int len; /* The length of the serialized data for the column */ - int i; /* Loop counter */ - Mem *pDest; /* Where to write the extracted value */ - Mem sMem; /* For storing the record being decoded */ - const u8 *zData; /* Part of the record being decoded */ - const u8 *zHdr; /* Next unparsed byte of the header */ - const u8 *zEndHdr; /* Pointer to first byte after the header */ - u32 offset; /* Offset into the data */ - u64 offset64; /* 64-bit offset */ - u32 avail; /* Number of bytes of available data */ - u32 t; /* A type code from the record header */ - Mem *pReg; /* PseudoTable input register */ - - pC = p->apCsr[pOp->p1]; - p2 = pOp->p2; - - /* If the cursor cache is stale, bring it up-to-date */ - rc = sqlite3VdbeCursorMoveto(&pC, &p2); - if( rc ) goto abort_due_to_error; - - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pC!=0 ); - assert( p2nField ); - aOffset = pC->aOffset; - assert( pC->eCurType!=CURTYPE_VTAB ); - assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); - assert( pC->eCurType!=CURTYPE_SORTER ); - pCrsr = pC->uc.pCursor; - - if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ - if( pC->nullRow ){ - if( pC->eCurType==CURTYPE_PSEUDO ){ - assert( pC->uc.pseudoTableReg>0 ); - pReg = &aMem[pC->uc.pseudoTableReg]; - assert( pReg->flags & MEM_Blob ); - assert( memIsValid(pReg) ); - pC->payloadSize = pC->szRow = avail = pReg->n; - pC->aRow = (u8*)pReg->z; - }else{ - sqlite3VdbeMemSetNull(pDest); - goto op_column_out; - } - }else{ - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pCrsr ); - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); - pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail); - assert( avail<=65536 ); /* Maximum page size is 64KiB */ - if( pC->payloadSize <= (u32)avail ){ - pC->szRow = pC->payloadSize; - }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - }else{ - pC->szRow = avail; - } - } - pC->cacheStatus = p->cacheCtr; - pC->iHdrOffset = getVarint32(pC->aRow, offset); - pC->nHdrParsed = 0; - aOffset[0] = offset; - - - if( availaRow does not have to hold the entire row, but it does at least - ** need to cover the header of the record. If pC->aRow does not contain - ** the complete header, then set it to zero, forcing the header to be - ** dynamically allocated. */ - pC->aRow = 0; - pC->szRow = 0; - - /* Make sure a corrupt database has not given us an oversize header. - ** Do this now to avoid an oversize memory allocation. - ** - ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte - ** types use so much data space that there can only be 4096 and 32 of - ** them, respectively. So the maximum header length results from a - ** 3-byte type for each of the maximum of 32768 columns plus three - ** extra bytes for the header length itself. 32768*3 + 3 = 98307. - */ - if( offset > 98307 || offset > pC->payloadSize ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* The following goto is an optimization. It can be omitted and - ** everything will still work. But OP_Column is measurably faster - ** by skipping the subsequent conditional, which is always true. - */ - zData = pC->aRow; - assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ - goto op_column_read_header; - } - } - - /* Make sure at least the first p2+1 entries of the header have been - ** parsed and valid information is in aOffset[] and pC->aType[]. - */ - if( pC->nHdrParsed<=p2 ){ - /* If there is more header available for parsing in the record, try - ** to extract additional fields up through the p2+1-th field - */ - if( pC->iHdrOffsetaRow==0 ){ - memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - zData = (u8*)sMem.z; - }else{ - zData = pC->aRow; - } - - /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ - op_column_read_header: - i = pC->nHdrParsed; - offset64 = aOffset[i]; - zHdr = zData + pC->iHdrOffset; - zEndHdr = zData + aOffset[0]; - do{ - if( (t = zHdr[0])<0x80 ){ - zHdr++; - offset64 += sqlite3VdbeOneByteSerialTypeLen(t); - }else{ - zHdr += sqlite3GetVarint32(zHdr, &t); - offset64 += sqlite3VdbeSerialTypeLen(t); - } - pC->aType[i++] = t; - aOffset[i] = (u32)(offset64 & 0xffffffff); - }while( i<=p2 && zHdr=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) - || (offset64 > pC->payloadSize) - ){ - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - - pC->nHdrParsed = i; - pC->iHdrOffset = (u32)(zHdr - zData); - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); - }else{ - t = 0; - } - - /* If after trying to extract new entries from the header, nHdrParsed is - ** still not up to p2, that means that the record has fewer than p2 - ** columns. So the result will be either the default value or a NULL. - */ - if( pC->nHdrParsed<=p2 ){ - if( pOp->p4type==P4_MEM ){ - sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); - }else{ - sqlite3VdbeMemSetNull(pDest); - } - goto op_column_out; - } - }else{ - t = pC->aType[p2]; - } - - /* Extract the content for the p2+1-th column. Control can only - ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are - ** all valid. - */ - assert( p2nHdrParsed ); - assert( rc==SQLITE_OK ); - assert( sqlite3VdbeCheckMemInvariants(pDest) ); - if( VdbeMemDynamic(pDest) ){ - sqlite3VdbeMemSetNull(pDest); - } - assert( t==pC->aType[p2] ); - if( pC->szRow>=aOffset[p2+1] ){ - /* This is the common case where the desired content fits on the original - ** page - where the content is not on an overflow page */ - zData = pC->aRow + aOffset[p2]; - if( t<12 ){ - sqlite3VdbeSerialGet(zData, t, pDest); - }else{ - /* If the column value is a string, we need a persistent value, not - ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent - ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). - */ - static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; - pDest->n = len = (t-12)/2; - pDest->enc = encoding; - if( pDest->szMalloc < len+2 ){ - pDest->flags = MEM_Null; - if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; - }else{ - pDest->z = pDest->zMalloc; - } - memcpy(pDest->z, zData, len); - pDest->z[len] = 0; - pDest->z[len+1] = 0; - pDest->flags = aFlag[t&1]; - } - }else{ - pDest->enc = encoding; - /* This branch happens only when content is on overflow pages */ - if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 - && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) - || (len = sqlite3VdbeSerialTypeLen(t))==0 - ){ - /* Content is irrelevant for - ** 1. the typeof() function, - ** 2. the length(X) function if X is a blob, and - ** 3. if the content length is zero. - ** So we might as well use bogus content rather than reading - ** content from disk. */ - static u8 aZero[8]; /* This is the bogus content */ - sqlite3VdbeSerialGet(aZero, t, pDest); - }else{ - rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, - pDest); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); - pDest->flags &= ~MEM_Ephem; - } - } - -op_column_out: - UPDATE_MAX_BLOBSIZE(pDest); - REGISTER_TRACE(pOp->p3, pDest); - break; -} - -/* Opcode: Affinity P1 P2 * P4 * -** Synopsis: affinity(r[P1@P2]) -** -** Apply affinities to a range of P2 registers starting with P1. -** -** P4 is a string that is P2 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth -** memory cell in the range. -*/ -case OP_Affinity: { - const char *zAffinity; /* The affinity to be applied */ - char cAff; /* A single character of affinity */ - - zAffinity = pOp->p4.z; - assert( zAffinity!=0 ); - assert( zAffinity[pOp->p2]==0 ); - pIn1 = &aMem[pOp->p1]; - while( (cAff = *(zAffinity++))!=0 ){ - assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); - assert( memIsValid(pIn1) ); - applyAffinity(pIn1, cAff, encoding); - pIn1++; - } - break; -} - -/* Opcode: MakeRecord P1 P2 P3 P4 * -** Synopsis: r[P3]=mkrec(r[P1@P2]) -** -** Convert P2 registers beginning with P1 into the [record format] -** use as a data record in a database table or as a key -** in an index. The OP_Column opcode can decode the record later. -** -** P4 may be a string that is P2 characters long. The nth character of the -** string indicates the column affinity that should be used for the nth -** field of the index key. -** -** The mapping from character to affinity is given by the SQLITE_AFF_ -** macros defined in sqliteInt.h. -** -** If P4 is NULL then all index fields have the affinity BLOB. -*/ -case OP_MakeRecord: { - u8 *zNewRecord; /* A buffer to hold the data for the new record */ - Mem *pRec; /* The new record */ - u64 nData; /* Number of bytes of data space */ - int nHdr; /* Number of bytes of header space */ - i64 nByte; /* Data space required for this record */ - i64 nZero; /* Number of zero bytes at the end of the record */ - int nVarint; /* Number of bytes in a varint */ - u32 serial_type; /* Type field */ - Mem *pData0; /* First field to be combined into the record */ - Mem *pLast; /* Last field of the record */ - int nField; /* Number of fields in the record */ - char *zAffinity; /* The affinity string for the record */ - int file_format; /* File format to use for encoding */ - int i; /* Space used in zNewRecord[] header */ - int j; /* Space used in zNewRecord[] content */ - u32 len; /* Length of a field */ - - /* Assuming the record contains N fields, the record format looks - ** like this: - ** - ** ------------------------------------------------------------------------ - ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | - ** ------------------------------------------------------------------------ - ** - ** Data(0) is taken from register P1. Data(1) comes from register P1+1 - ** and so forth. - ** - ** Each type field is a varint representing the serial type of the - ** corresponding data element (see sqlite3VdbeSerialType()). The - ** hdr-size field is also a varint which is the offset from the beginning - ** of the record to data0. - */ - nData = 0; /* Number of bytes of data space */ - nHdr = 0; /* Number of bytes of header space */ - nZero = 0; /* Number of zero bytes at the end of the record */ - nField = pOp->p1; - zAffinity = pOp->p4.z; - assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); - pData0 = &aMem[nField]; - nField = pOp->p2; - pLast = &pData0[nField-1]; - file_format = p->minWriteFileFormat; - - /* Identify the output register */ - assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); - pOut = &aMem[pOp->p3]; - memAboutToChange(p, pOut); - - /* Apply the requested affinity to all inputs - */ - assert( pData0<=pLast ); - if( zAffinity ){ - pRec = pData0; - do{ - applyAffinity(pRec++, *(zAffinity++), encoding); - assert( zAffinity[0]==0 || pRec<=pLast ); - }while( zAffinity[0] ); - } - - /* Loop through the elements that will make up the record to figure - ** out how much space is required for the new record. - */ - pRec = pLast; - do{ - assert( memIsValid(pRec) ); - pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); - if( pRec->flags & MEM_Zero ){ - if( nData ){ - if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; - }else{ - nZero += pRec->u.nZero; - len -= pRec->u.nZero; - } - } - nData += len; - testcase( serial_type==127 ); - testcase( serial_type==128 ); - nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); - if( pRec==pData0 ) break; - pRec--; - }while(1); - - /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint - ** which determines the total number of bytes in the header. The varint - ** value is the size of the header in bytes including the size varint - ** itself. */ - testcase( nHdr==126 ); - testcase( nHdr==127 ); - if( nHdr<=126 ){ - /* The common case */ - nHdr += 1; - }else{ - /* Rare case of a really large header */ - nVarint = sqlite3VarintLen(nHdr); - nHdr += nVarint; - if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - - /* Make sure the output register has a buffer large enough to store - ** the new record. The output register (pOp->p3) is not allowed to - ** be one of the input registers (because the following call to - ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). - */ - if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ - goto no_mem; - } - zNewRecord = (u8 *)pOut->z; - - /* Write the record */ - i = putVarint32(zNewRecord, nHdr); - j = nHdr; - assert( pData0<=pLast ); - pRec = pData0; - do{ - serial_type = pRec->uTemp; - /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more - ** additional varints, one per column. */ - i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - /* EVIDENCE-OF: R-64536-51728 The values for each column in the record - ** immediately follow the header. */ - j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ - }while( (++pRec)<=pLast ); - assert( i==nHdr ); - assert( j==nByte ); - - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pOut->n = (int)nByte; - pOut->flags = MEM_Blob; - if( nZero ){ - pOut->u.nZero = nZero; - pOut->flags |= MEM_Zero; - } - pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ - REGISTER_TRACE(pOp->p3, pOut); - UPDATE_MAX_BLOBSIZE(pOut); - break; -} - -/* Opcode: Count P1 P2 * * * -** Synopsis: r[P2]=count() -** -** Store the number of entries (an integer value) in the table or index -** opened by cursor P1 in register P2 -*/ -#ifndef SQLITE_OMIT_BTREECOUNT -case OP_Count: { /* out2 */ - i64 nEntry; - BtCursor *pCrsr; - - assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE ); - pCrsr = p->apCsr[pOp->p1]->uc.pCursor; - assert( pCrsr ); - nEntry = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3BtreeCount(pCrsr, &nEntry); - if( rc ) goto abort_due_to_error; - pOut = out2Prerelease(p, pOp); - pOut->u.i = nEntry; - break; -} -#endif - -/* Opcode: Savepoint P1 * * P4 * -** -** Open, release or rollback the savepoint named by parameter P4, depending -** on the value of P1. To open a new savepoint, P1==0. To release (commit) an -** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. -*/ -case OP_Savepoint: { - int p1; /* Value of P1 operand */ - char *zName; /* Name of savepoint */ - int nName; - Savepoint *pNew; - Savepoint *pSavepoint; - Savepoint *pTmp; - int iSavepoint; - int ii; - - p1 = pOp->p1; - zName = pOp->p4.z; - - /* Assert that the p1 parameter is valid. Also that if there is no open - ** transaction, then there cannot be any savepoints. - */ - assert( db->pSavepoint==0 || db->autoCommit==0 ); - assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); - assert( db->pSavepoint || db->isTransactionSavepoint==0 ); - assert( checkSavepointCount(db) ); - assert( p->bIsReader ); - - if( p1==SAVEPOINT_BEGIN ){ - if( db->nVdbeWrite>0 ){ - /* A new savepoint cannot be created if there are active write - ** statements (i.e. open read/write incremental blob handles). - */ - sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); - rc = SQLITE_BUSY; - }else{ - nName = sqlite3Strlen30(zName); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* This call is Ok even if this savepoint is actually a transaction - ** savepoint (and therefore should not prompt xSavepoint()) callbacks. - ** If this is a transaction savepoint being opened, it is guaranteed - ** that the db->aVTrans[] array is empty. */ - assert( db->autoCommit==0 || db->nVTrans==0 ); - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, - db->nStatement+db->nSavepoint); - if( rc!=SQLITE_OK ) goto abort_due_to_error; -#endif - - /* Create a new savepoint structure. */ - pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); - if( pNew ){ - pNew->zName = (char *)&pNew[1]; - memcpy(pNew->zName, zName, nName+1); - - /* If there is no open transaction, then mark this as a special - ** "transaction savepoint". */ - if( db->autoCommit ){ - db->autoCommit = 0; - db->isTransactionSavepoint = 1; - }else{ - db->nSavepoint++; - } - - /* Link the new savepoint into the database handle's list. */ - pNew->pNext = db->pSavepoint; - db->pSavepoint = pNew; - pNew->nDeferredCons = db->nDeferredCons; - pNew->nDeferredImmCons = db->nDeferredImmCons; - } - } - }else{ - iSavepoint = 0; - - /* Find the named savepoint. If there is no such savepoint, then an - ** an error is returned to the user. */ - for( - pSavepoint = db->pSavepoint; - pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); - pSavepoint = pSavepoint->pNext - ){ - iSavepoint++; - } - if( !pSavepoint ){ - sqlite3VdbeError(p, "no such savepoint: %s", zName); - rc = SQLITE_ERROR; - }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ - /* It is not possible to release (commit) a savepoint if there are - ** active write statements. - */ - sqlite3VdbeError(p, "cannot release savepoint - " - "SQL statements in progress"); - rc = SQLITE_BUSY; - }else{ - - /* Determine whether or not this is a transaction savepoint. If so, - ** and this is a RELEASE command, then the current transaction - ** is committed. - */ - int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; - if( isTransaction && p1==SAVEPOINT_RELEASE ){ - if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ - goto vdbe_return; - } - db->autoCommit = 1; - if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ - p->pc = (int)(pOp - aOp); - db->autoCommit = 0; - p->rc = rc = SQLITE_BUSY; - goto vdbe_return; - } - db->isTransactionSavepoint = 0; - rc = p->rc; - }else{ - int isSchemaChange; - iSavepoint = db->nSavepoint - iSavepoint - 1; - if( p1==SAVEPOINT_ROLLBACK ){ - isSchemaChange = (db->flags & SQLITE_InternChanges)!=0; - for(ii=0; iinDb; ii++){ - rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, - SQLITE_ABORT_ROLLBACK, - isSchemaChange==0); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - } - }else{ - isSchemaChange = 0; - } - for(ii=0; iinDb; ii++){ - rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - } - if( isSchemaChange ){ - sqlite3ExpirePreparedStatements(db); - sqlite3ResetAllSchemasOfConnection(db); - db->flags = (db->flags | SQLITE_InternChanges); - } - } - - /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all - ** savepoints nested inside of the savepoint being operated on. */ - while( db->pSavepoint!=pSavepoint ){ - pTmp = db->pSavepoint; - db->pSavepoint = pTmp->pNext; - sqlite3DbFree(db, pTmp); - db->nSavepoint--; - } - - /* If it is a RELEASE, then destroy the savepoint being operated on - ** too. If it is a ROLLBACK TO, then set the number of deferred - ** constraint violations present in the database to the value stored - ** when the savepoint was created. */ - if( p1==SAVEPOINT_RELEASE ){ - assert( pSavepoint==db->pSavepoint ); - db->pSavepoint = pSavepoint->pNext; - sqlite3DbFree(db, pSavepoint); - if( !isTransaction ){ - db->nSavepoint--; - } - }else{ - db->nDeferredCons = pSavepoint->nDeferredCons; - db->nDeferredImmCons = pSavepoint->nDeferredImmCons; - } - - if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ - rc = sqlite3VtabSavepoint(db, p1, iSavepoint); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - } - } - } - if( rc ) goto abort_due_to_error; - - break; -} - -/* Opcode: AutoCommit P1 P2 * * * -** -** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll -** back any currently active btree transactions. If there are any active -** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if -** there are active writing VMs or active VMs that use shared cache. -** -** This instruction causes the VM to halt. -*/ -case OP_AutoCommit: { - int desiredAutoCommit; - int iRollback; - - desiredAutoCommit = pOp->p1; - iRollback = pOp->p2; - assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); - assert( desiredAutoCommit==1 || iRollback==0 ); - assert( db->nVdbeActive>0 ); /* At least this one VM is active */ - assert( p->bIsReader ); - - if( desiredAutoCommit!=db->autoCommit ){ - if( iRollback ){ - assert( desiredAutoCommit==1 ); - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - db->autoCommit = 1; - }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ - /* If this instruction implements a COMMIT and other VMs are writing - ** return an error indicating that the other VMs must complete first. - */ - sqlite3VdbeError(p, "cannot commit transaction - " - "SQL statements in progress"); - rc = SQLITE_BUSY; - goto abort_due_to_error; - }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ - goto vdbe_return; - }else{ - db->autoCommit = (u8)desiredAutoCommit; - } - if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ - p->pc = (int)(pOp - aOp); - db->autoCommit = (u8)(1-desiredAutoCommit); - p->rc = rc = SQLITE_BUSY; - goto vdbe_return; - } - assert( db->nStatement==0 ); - sqlite3CloseSavepoints(db); - if( p->rc==SQLITE_OK ){ - rc = SQLITE_DONE; - }else{ - rc = SQLITE_ERROR; - } - goto vdbe_return; - }else{ - sqlite3VdbeError(p, - (!desiredAutoCommit)?"cannot start a transaction within a transaction":( - (iRollback)?"cannot rollback - no transaction is active": - "cannot commit - no transaction is active")); - - rc = SQLITE_ERROR; - goto abort_due_to_error; - } - break; -} - -/* Opcode: Transaction P1 P2 P3 P4 P5 -** -** Begin a transaction on database P1 if a transaction is not already -** active. -** If P2 is non-zero, then a write-transaction is started, or if a -** read-transaction is already active, it is upgraded to a write-transaction. -** If P2 is zero, then a read-transaction is started. -** -** P1 is the index of the database file on which the transaction is -** started. Index 0 is the main database file and index 1 is the -** file used for temporary tables. Indices of 2 or more are used for -** attached databases. -** -** If a write-transaction is started and the Vdbe.usesStmtJournal flag is -** true (this flag is set if the Vdbe may modify more than one row and may -** throw an ABORT exception), a statement transaction may also be opened. -** More specifically, a statement transaction is opened iff the database -** connection is currently not in autocommit mode, or if there are other -** active statements. A statement transaction allows the changes made by this -** VDBE to be rolled back after an error without having to roll back the -** entire transaction. If no error is encountered, the statement transaction -** will automatically commit when the VDBE halts. -** -** If P5!=0 then this opcode also checks the schema cookie against P3 -** and the schema generation counter against P4. -** The cookie changes its value whenever the database schema changes. -** This operation is used to detect when that the cookie has changed -** and that the current process needs to reread the schema. If the schema -** cookie in P3 differs from the schema cookie in the database header or -** if the schema generation counter in P4 differs from the current -** generation counter, then an SQLITE_SCHEMA error is raised and execution -** halts. The sqlite3_step() wrapper function might then reprepare the -** statement and rerun it from the beginning. -*/ -case OP_Transaction: { - Btree *pBt; - int iMeta; - int iGen; - - assert( p->bIsReader ); - assert( p->readOnly==0 || pOp->p2==0 ); - assert( pOp->p1>=0 && pOp->p1nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); - if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ - rc = SQLITE_READONLY; - goto abort_due_to_error; - } - pBt = db->aDb[pOp->p1].pBt; - - if( pBt ){ - rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); - testcase( rc==SQLITE_BUSY_SNAPSHOT ); - testcase( rc==SQLITE_BUSY_RECOVERY ); - if( rc!=SQLITE_OK ){ - if( (rc&0xff)==SQLITE_BUSY ){ - p->pc = (int)(pOp - aOp); - p->rc = rc; - goto vdbe_return; - } - goto abort_due_to_error; - } - - if( pOp->p2 && p->usesStmtJournal - && (db->autoCommit==0 || db->nVdbeRead>1) - ){ - assert( sqlite3BtreeIsInTrans(pBt) ); - if( p->iStatement==0 ){ - assert( db->nStatement>=0 && db->nSavepoint>=0 ); - db->nStatement++; - p->iStatement = db->nSavepoint + db->nStatement; - } - - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); - } - - /* Store the current value of the database handles deferred constraint - ** counter. If the statement transaction needs to be rolled back, - ** the value of this counter needs to be restored too. */ - p->nStmtDefCons = db->nDeferredCons; - p->nStmtDefImmCons = db->nDeferredImmCons; - } - - /* Gather the schema version number for checking: - ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema - ** version is checked to ensure that the schema has not changed since the - ** SQL statement was prepared. - */ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); - iGen = db->aDb[pOp->p1].pSchema->iGeneration; - }else{ - iGen = iMeta = 0; - } - assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); - if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); - /* If the schema-cookie from the database file matches the cookie - ** stored with the in-memory representation of the schema, do - ** not reload the schema from the database file. - ** - ** If virtual-tables are in use, this is not just an optimization. - ** Often, v-tables store their data in other SQLite tables, which - ** are queried from within xNext() and other v-table methods using - ** prepared queries. If such a query is out-of-date, we do not want to - ** discard the database schema, as the user code implementing the - ** v-table would have to be ready for the sqlite3_vtab structure itself - ** to be invalidated whenever sqlite3_step() is called from within - ** a v-table method. - */ - if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ - sqlite3ResetOneSchema(db, pOp->p1); - } - p->expired = 1; - rc = SQLITE_SCHEMA; - } - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: ReadCookie P1 P2 P3 * * -** -** Read cookie number P3 from database P1 and write it into register P2. -** P3==1 is the schema version. P3==2 is the database format. -** P3==3 is the recommended pager cache size, and so forth. P1==0 is -** the main database file and P1==1 is the database file used to store -** temporary tables. -** -** There must be a read-lock on the database (either a transaction -** must be started or there must be an open cursor) before -** executing this instruction. -*/ -case OP_ReadCookie: { /* out2 */ - int iMeta; - int iDb; - int iCookie; - - assert( p->bIsReader ); - iDb = pOp->p1; - iCookie = pOp->p3; - assert( pOp->p3=0 && iDbnDb ); - assert( db->aDb[iDb].pBt!=0 ); - assert( DbMaskTest(p->btreeMask, iDb) ); - - sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); - pOut = out2Prerelease(p, pOp); - pOut->u.i = iMeta; - break; -} - -/* Opcode: SetCookie P1 P2 P3 * * -** -** Write the integer value P3 into cookie number P2 of database P1. -** P2==1 is the schema version. P2==2 is the database format. -** P2==3 is the recommended pager cache -** size, and so forth. P1==0 is the main database file and P1==1 is the -** database file used to store temporary tables. -** -** A transaction must be started before executing this opcode. -*/ -case OP_SetCookie: { - Db *pDb; - assert( pOp->p2p1>=0 && pOp->p1nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); - assert( p->readOnly==0 ); - pDb = &db->aDb[pOp->p1]; - assert( pDb->pBt!=0 ); - assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); - /* See note about index shifting on OP_ReadCookie */ - rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); - if( pOp->p2==BTREE_SCHEMA_VERSION ){ - /* When the schema cookie changes, record the new cookie internally */ - pDb->pSchema->schema_cookie = pOp->p3; - db->flags |= SQLITE_InternChanges; - }else if( pOp->p2==BTREE_FILE_FORMAT ){ - /* Record changes in the file format */ - pDb->pSchema->file_format = pOp->p3; - } - if( pOp->p1==1 ){ - /* Invalidate all prepared statements whenever the TEMP database - ** schema is changed. Ticket #1644 */ - sqlite3ExpirePreparedStatements(db); - p->expired = 0; - } - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: OpenRead P1 P2 P3 P4 P5 -** Synopsis: root=P2 iDb=P3 -** -** Open a read-only cursor for the database table whose root page is -** P2 in a database file. The database file is determined by P3. -** P3==0 means the main database, P3==1 means the database used for -** temporary tables, and P3>1 means used the corresponding attached -** database. Give the new cursor an identifier of P1. The P1 -** values need not be contiguous but all P1 values should be small integers. -** It is an error for P1 to be negative. -** -** If P5!=0 then use the content of register P2 as the root page, not -** the value of P2 itself. -** -** There will be a read lock on the database whenever there is an -** open cursor. If the database was unlocked prior to this instruction -** then a read lock is acquired as part of this instruction. A read -** lock allows other processes to read the database but prohibits -** any other process from modifying the database. The read lock is -** released when all cursors are closed. If this instruction attempts -** to get a read lock but fails, the script terminates with an -** SQLITE_BUSY error code. -** -** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table. -** -** See also: OpenWrite, ReopenIdx -*/ -/* Opcode: ReopenIdx P1 P2 P3 P4 P5 -** Synopsis: root=P2 iDb=P3 -** -** The ReopenIdx opcode works exactly like ReadOpen except that it first -** checks to see if the cursor on P1 is already open with a root page -** number of P2 and if it is this opcode becomes a no-op. In other words, -** if the cursor is already open, do not reopen it. -** -** The ReopenIdx opcode may only be used with P5==0 and with P4 being -** a P4_KEYINFO object. Furthermore, the P3 value must be the same as -** every other ReopenIdx or OpenRead for the same cursor number. -** -** See the OpenRead opcode documentation for additional information. -*/ -/* Opcode: OpenWrite P1 P2 P3 P4 P5 -** Synopsis: root=P2 iDb=P3 -** -** Open a read/write cursor named P1 on the table or index whose root -** page is P2. Or if P5!=0 use the content of register P2 to find the -** root page. -** -** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table, or to the -** largest index of any column of the table that is actually used. -** -** This instruction works just like OpenRead except that it opens the cursor -** in read/write mode. For a given table, there can be one or more read-only -** cursors or a single read/write cursor but not both. -** -** See also OpenRead. -*/ -case OP_ReopenIdx: { - int nField; - KeyInfo *pKeyInfo; - int p2; - int iDb; - int wrFlag; - Btree *pX; - VdbeCursor *pCur; - Db *pDb; - - assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); - assert( pOp->p4type==P4_KEYINFO ); - pCur = p->apCsr[pOp->p1]; - if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ - assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ - goto open_cursor_set_hints; - } - /* If the cursor is not currently open or is open on a different - ** index, then fall through into OP_OpenRead to force a reopen */ -case OP_OpenRead: -case OP_OpenWrite: - - assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); - assert( p->bIsReader ); - assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx - || p->readOnly==0 ); - - if( p->expired ){ - rc = SQLITE_ABORT_ROLLBACK; - goto abort_due_to_error; - } - - nField = 0; - pKeyInfo = 0; - p2 = pOp->p2; - iDb = pOp->p3; - assert( iDb>=0 && iDbnDb ); - assert( DbMaskTest(p->btreeMask, iDb) ); - pDb = &db->aDb[iDb]; - pX = pDb->pBt; - assert( pX!=0 ); - if( pOp->opcode==OP_OpenWrite ){ - assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); - wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( pDb->pSchema->file_format < p->minWriteFileFormat ){ - p->minWriteFileFormat = pDb->pSchema->file_format; - } - }else{ - wrFlag = 0; - } - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(p->nMem+1 - p->nCursor) ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateTable opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ - assert( p2>=2 ); - } - if( pOp->p4type==P4_KEYINFO ){ - pKeyInfo = pOp->p4.pKeyInfo; - assert( pKeyInfo->enc==ENC(db) ); - assert( pKeyInfo->db==db ); - nField = pKeyInfo->nField+pKeyInfo->nXField; - }else if( pOp->p4type==P4_INT32 ){ - nField = pOp->p4.i; - } - assert( pOp->p1>=0 ); - assert( nField>=0 ); - testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ - pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); - if( pCur==0 ) goto no_mem; - pCur->nullRow = 1; - pCur->isOrdered = 1; - pCur->pgnoRoot = p2; -#ifdef SQLITE_DEBUG - pCur->wrFlag = wrFlag; -#endif - rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); - pCur->pKeyInfo = pKeyInfo; - /* Set the VdbeCursor.isTable variable. Previous versions of - ** SQLite used to check if the root-page flags were sane at this point - ** and report database corruption if they were not, but this check has - ** since moved into the btree layer. */ - pCur->isTable = pOp->p4type!=P4_KEYINFO; - -open_cursor_set_hints: - assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); - assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); - testcase( pOp->p5 & OPFLAG_BULKCSR ); -#ifdef SQLITE_ENABLE_CURSOR_HINTS - testcase( pOp->p2 & OPFLAG_SEEKEQ ); -#endif - sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, - (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: OpenEphemeral P1 P2 * P4 P5 -** Synopsis: nColumn=P2 -** -** Open a new cursor P1 to a transient table. -** The cursor is always opened read/write even if -** the main database is read-only. The ephemeral -** table is deleted automatically when the cursor is closed. -** -** P2 is the number of columns in the ephemeral table. -** The cursor points to a BTree table if P4==0 and to a BTree index -** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure -** that defines the format of keys in the index. -** -** The P5 parameter can be a mask of the BTREE_* flags defined -** in btree.h. These flags control aspects of the operation of -** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are -** added automatically. -*/ -/* Opcode: OpenAutoindex P1 P2 * P4 * -** Synopsis: nColumn=P2 -** -** This opcode works the same as OP_OpenEphemeral. It has a -** different name to distinguish its use. Tables created using -** by this opcode will be used for automatically created transient -** indices in joins. -*/ -case OP_OpenAutoindex: -case OP_OpenEphemeral: { - VdbeCursor *pCx; - KeyInfo *pKeyInfo; - - static const int vfsFlags = - SQLITE_OPEN_READWRITE | - SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | - SQLITE_OPEN_DELETEONCLOSE | - SQLITE_OPEN_TRANSIENT_DB; - assert( pOp->p1>=0 ); - assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); - if( pCx==0 ) goto no_mem; - pCx->nullRow = 1; - pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, - BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); - } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before - ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an BLOB_INTKEY table). - */ - if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ - int pgno; - assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); - if( rc==SQLITE_OK ){ - assert( pgno==MASTER_ROOT+1 ); - assert( pKeyInfo->db==db ); - assert( pKeyInfo->enc==ENC(db) ); - pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, - pKeyInfo, pCx->uc.pCursor); - } - pCx->isTable = 0; - }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, - 0, pCx->uc.pCursor); - pCx->isTable = 1; - } - } - if( rc ) goto abort_due_to_error; - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); - break; -} - -/* Opcode: SorterOpen P1 P2 P3 P4 * -** -** This opcode works like OP_OpenEphemeral except that it opens -** a transient index that is specifically designed to sort large -** tables using an external merge-sort algorithm. -** -** If argument P3 is non-zero, then it indicates that the sorter may -** assume that a stable sort considering the first P3 fields of each -** key is sufficient to produce the required results. -*/ -case OP_SorterOpen: { - VdbeCursor *pCx; - - assert( pOp->p1>=0 ); - assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER); - if( pCx==0 ) goto no_mem; - pCx->pKeyInfo = pOp->p4.pKeyInfo; - assert( pCx->pKeyInfo->db==db ); - assert( pCx->pKeyInfo->enc==ENC(db) ); - rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: SequenceTest P1 P2 * * * -** Synopsis: if( cursor[P1].ctr++ ) pc = P2 -** -** P1 is a sorter cursor. If the sequence counter is currently zero, jump -** to P2. Regardless of whether or not the jump is taken, increment the -** the sequence value. -*/ -case OP_SequenceTest: { - VdbeCursor *pC; - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( isSorter(pC) ); - if( (pC->seqCount++)==0 ){ - goto jump_to_p2; - } - break; -} - -/* Opcode: OpenPseudo P1 P2 P3 * * -** Synopsis: P3 columns in r[P2] -** -** Open a new cursor that points to a fake table that contains a single -** row of data. The content of that one row is the content of memory -** register P2. In other words, cursor P1 becomes an alias for the -** MEM_Blob content contained in register P2. -** -** A pseudo-table created by this opcode is used to hold a single -** row output from the sorter so that the row can be decomposed into -** individual columns using the OP_Column opcode. The OP_Column opcode -** is the only cursor opcode that works with a pseudo-table. -** -** P3 is the number of fields in the records that will be stored by -** the pseudo-table. -*/ -case OP_OpenPseudo: { - VdbeCursor *pCx; - - assert( pOp->p1>=0 ); - assert( pOp->p3>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); - if( pCx==0 ) goto no_mem; - pCx->nullRow = 1; - pCx->uc.pseudoTableReg = pOp->p2; - pCx->isTable = 1; - assert( pOp->p5==0 ); - break; -} - -/* Opcode: Close P1 * * * * -** -** Close a cursor previously opened as P1. If P1 is not -** currently open, this instruction is a no-op. -*/ -case OP_Close: { - assert( pOp->p1>=0 && pOp->p1nCursor ); - sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); - p->apCsr[pOp->p1] = 0; - break; -} - -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK -/* Opcode: ColumnsUsed P1 * * P4 * -** -** This opcode (which only exists if SQLite was compiled with -** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the -** table or index for cursor P1 are used. P4 is a 64-bit integer -** (P4_INT64) in which the first 63 bits are one for each of the -** first 63 columns of the table or index that are actually used -** by the cursor. The high-order bit is set if any column after -** the 64th is used. -*/ -case OP_ColumnsUsed: { - VdbeCursor *pC; - pC = p->apCsr[pOp->p1]; - assert( pC->eCurType==CURTYPE_BTREE ); - pC->maskUsed = *(u64*)pOp->p4.pI64; - break; -} -#endif - -/* Opcode: SeekGE P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as the key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. -** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than or equal to the key value. If there are no records -** greater than or equal to the key and P2 is not zero, then jump to P2. -** -** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this -** opcode will always land on a record that equally equals the key, or -** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this -** opcode must be followed by an IdxLE opcode with the same arguments. -** The IdxLE opcode will be skipped if this opcode succeeds, but the -** IdxLE opcode will be used on subsequent loop iterations. -** -** This opcode leaves the cursor configured to move in forward order, -** from the beginning toward the end. In other words, the cursor is -** configured to use Next, not Prev. -** -** See also: Found, NotFound, SeekLt, SeekGt, SeekLe -*/ -/* Opcode: SeekGT P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. -** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than the key value. If there are no records greater than -** the key and P2 is not zero, then jump to P2. -** -** This opcode leaves the cursor configured to move in forward order, -** from the beginning toward the end. In other words, the cursor is -** configured to use Next, not Prev. -** -** See also: Found, NotFound, SeekLt, SeekGe, SeekLe -*/ -/* Opcode: SeekLT P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. -** -** Reposition cursor P1 so that it points to the largest entry that -** is less than the key value. If there are no records less than -** the key and P2 is not zero, then jump to P2. -** -** This opcode leaves the cursor configured to move in reverse order, -** from the end toward the beginning. In other words, the cursor is -** configured to use Prev, not Next. -** -** See also: Found, NotFound, SeekGt, SeekGe, SeekLe -*/ -/* Opcode: SeekLE P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. -** -** Reposition cursor P1 so that it points to the largest entry that -** is less than or equal to the key value. If there are no records -** less than or equal to the key and P2 is not zero, then jump to P2. -** -** This opcode leaves the cursor configured to move in reverse order, -** from the end toward the beginning. In other words, the cursor is -** configured to use Prev, not Next. -** -** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this -** opcode will always land on a record that equally equals the key, or -** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this -** opcode must be followed by an IdxGE opcode with the same arguments. -** The IdxGE opcode will be skipped if this opcode succeeds, but the -** IdxGE opcode will be used on subsequent loop iterations. -** -** See also: Found, NotFound, SeekGt, SeekGe, SeekLt -*/ -case OP_SeekLT: /* jump, in3 */ -case OP_SeekLE: /* jump, in3 */ -case OP_SeekGE: /* jump, in3 */ -case OP_SeekGT: { /* jump, in3 */ - int res; /* Comparison result */ - int oc; /* Opcode */ - VdbeCursor *pC; /* The cursor to seek */ - UnpackedRecord r; /* The key to seek for */ - int nField; /* Number of columns or fields in the key */ - i64 iKey; /* The rowid we are to seek to */ - int eqOnly; /* Only interested in == results */ - - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p2!=0 ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( OP_SeekLE == OP_SeekLT+1 ); - assert( OP_SeekGE == OP_SeekLT+2 ); - assert( OP_SeekGT == OP_SeekLT+3 ); - assert( pC->isOrdered ); - assert( pC->uc.pCursor!=0 ); - oc = pOp->opcode; - eqOnly = 0; - pC->nullRow = 0; -#ifdef SQLITE_DEBUG - pC->seekOp = pOp->opcode; -#endif - - if( pC->isTable ){ - /* The BTREE_SEEK_EQ flag is only set on index cursors */ - assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 ); - - /* The input value in P3 might be of any type: integer, real, string, - ** blob, or NULL. But it needs to be an integer before we can do - ** the seek, so convert it. */ - pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ - applyNumericAffinity(pIn3, 0); - } - iKey = sqlite3VdbeIntValue(pIn3); - - /* If the P3 value could not be converted into an integer without - ** loss of information, then special processing is required... */ - if( (pIn3->flags & MEM_Int)==0 ){ - if( (pIn3->flags & MEM_Real)==0 ){ - /* If the P3 value cannot be converted into any kind of a number, - ** then the seek is not possible, so jump to P2 */ - VdbeBranchTaken(1,2); goto jump_to_p2; - break; - } - - /* If the approximation iKey is larger than the actual real search - ** term, substitute >= for > and < for <=. e.g. if the search term - ** is 4.9 and the integer approximation 5: - ** - ** (x > 4.9) -> (x >= 5) - ** (x <= 4.9) -> (x < 5) - */ - if( pIn3->u.r<(double)iKey ){ - assert( OP_SeekGE==(OP_SeekGT-1) ); - assert( OP_SeekLT==(OP_SeekLE-1) ); - assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); - if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; - } - - /* If the approximation iKey is smaller than the actual real search - ** term, substitute <= for < and > for >=. */ - else if( pIn3->u.r>(double)iKey ){ - assert( OP_SeekLE==(OP_SeekLT+1) ); - assert( OP_SeekGT==(OP_SeekGE+1) ); - assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); - if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; - } - } - rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); - pC->movetoTarget = iKey; /* Used by OP_Delete */ - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - }else{ - /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and - ** OP_SeekLE opcodes are allowed, and these must be immediately followed - ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key. - */ - if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ - eqOnly = 1; - assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); - assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); - assert( pOp[1].p1==pOp[0].p1 ); - assert( pOp[1].p2==pOp[0].p2 ); - assert( pOp[1].p3==pOp[0].p3 ); - assert( pOp[1].p4.i==pOp[0].p4.i ); - } - - nField = pOp->p4.i; - assert( pOp->p4type==P4_INT32 ); - assert( nField>0 ); - r.pKeyInfo = pC->pKeyInfo; - r.nField = (u16)nField; - - /* The next line of code computes as follows, only faster: - ** if( oc==OP_SeekGT || oc==OP_SeekLE ){ - ** r.default_rc = -1; - ** }else{ - ** r.default_rc = +1; - ** } - */ - r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1); - assert( oc!=OP_SeekGT || r.default_rc==-1 ); - assert( oc!=OP_SeekLE || r.default_rc==-1 ); - assert( oc!=OP_SeekGE || r.default_rc==+1 ); - assert( oc!=OP_SeekLT || r.default_rc==+1 ); - - r.aMem = &aMem[pOp->p3]; -#ifdef SQLITE_DEBUG - { int i; for(i=0; iuc.pCursor, &r, 0, 0, &res); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( eqOnly && r.eqSeen==0 ){ - assert( res!=0 ); - goto seek_not_found; - } - } - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; -#ifdef SQLITE_TEST - sqlite3_search_count++; -#endif - if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); - if( res<0 || (res==0 && oc==OP_SeekGT) ){ - res = 0; - rc = sqlite3BtreeNext(pC->uc.pCursor, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - }else{ - res = 0; - } - }else{ - assert( oc==OP_SeekLT || oc==OP_SeekLE ); - if( res>0 || (res==0 && oc==OP_SeekLT) ){ - res = 0; - rc = sqlite3BtreePrevious(pC->uc.pCursor, &res); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - }else{ - /* res might be negative because the table is empty. Check to - ** see if this is the case. - */ - res = sqlite3BtreeEof(pC->uc.pCursor); - } - } -seek_not_found: - assert( pOp->p2>0 ); - VdbeBranchTaken(res!=0,2); - if( res ){ - goto jump_to_p2; - }else if( eqOnly ){ - assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); - pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */ - } - break; -} - -/* Opcode: Found P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If P4==0 then register P3 holds a blob constructed by MakeRecord. If -** P4>0 then register P3 is the first of P4 registers that form an unpacked -** record. -** -** Cursor P1 is on an index btree. If the record identified by P3 and P4 -** is a prefix of any entry in P1 then a jump is made to P2 and -** P1 is left pointing at the matching entry. -** -** This operation leaves the cursor in a state where it can be -** advanced in the forward direction. The Next instruction will work, -** but not the Prev instruction. -** -** See also: NotFound, NoConflict, NotExists. SeekGe -*/ -/* Opcode: NotFound P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If P4==0 then register P3 holds a blob constructed by MakeRecord. If -** P4>0 then register P3 is the first of P4 registers that form an unpacked -** record. -** -** Cursor P1 is on an index btree. If the record identified by P3 and P4 -** is not the prefix of any entry in P1 then a jump is made to P2. If P1 -** does contain an entry whose prefix matches the P3/P4 record then control -** falls through to the next instruction and P1 is left pointing at the -** matching entry. -** -** This operation leaves the cursor in a state where it cannot be -** advanced in either direction. In other words, the Next and Prev -** opcodes do not work after this operation. -** -** See also: Found, NotExists, NoConflict -*/ -/* Opcode: NoConflict P1 P2 P3 P4 * -** Synopsis: key=r[P3@P4] -** -** If P4==0 then register P3 holds a blob constructed by MakeRecord. If -** P4>0 then register P3 is the first of P4 registers that form an unpacked -** record. -** -** Cursor P1 is on an index btree. If the record identified by P3 and P4 -** contains any NULL value, jump immediately to P2. If all terms of the -** record are not-NULL then a check is done to determine if any row in the -** P1 index btree has a matching key prefix. If there are no matches, jump -** immediately to P2. If there is a match, fall through and leave the P1 -** cursor pointing to the matching row. -** -** This opcode is similar to OP_NotFound with the exceptions that the -** branch is always taken if any part of the search key input is NULL. -** -** This operation leaves the cursor in a state where it cannot be -** advanced in either direction. In other words, the Next and Prev -** opcodes do not work after this operation. -** -** See also: NotFound, Found, NotExists -*/ -case OP_NoConflict: /* jump, in3 */ -case OP_NotFound: /* jump, in3 */ -case OP_Found: { /* jump, in3 */ - int alreadyExists; - int takeJump; - int ii; - VdbeCursor *pC; - int res; - char *pFree; - UnpackedRecord *pIdxKey; - UnpackedRecord r; - char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; - -#ifdef SQLITE_TEST - if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; -#endif - - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p4type==P4_INT32 ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); -#ifdef SQLITE_DEBUG - pC->seekOp = pOp->opcode; -#endif - pIn3 = &aMem[pOp->p3]; - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->isTable==0 ); - pFree = 0; - if( pOp->p4.i>0 ){ - r.pKeyInfo = pC->pKeyInfo; - r.nField = (u16)pOp->p4.i; - r.aMem = pIn3; -#ifdef SQLITE_DEBUG - for(ii=0; iip3+ii, &r.aMem[ii]); - } -#endif - pIdxKey = &r; - }else{ - pIdxKey = sqlite3VdbeAllocUnpackedRecord( - pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree - ); - if( pIdxKey==0 ) goto no_mem; - assert( pIn3->flags & MEM_Blob ); - (void)ExpandBlob(pIn3); - sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); - } - pIdxKey->default_rc = 0; - takeJump = 0; - if( pOp->opcode==OP_NoConflict ){ - /* For the OP_NoConflict opcode, take the jump if any of the - ** input fields are NULL, since any key with a NULL will not - ** conflict */ - for(ii=0; iinField; ii++){ - if( pIdxKey->aMem[ii].flags & MEM_Null ){ - takeJump = 1; - break; - } - } - } - rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); - sqlite3DbFree(db, pFree); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - pC->seekResult = res; - alreadyExists = (res==0); - pC->nullRow = 1-alreadyExists; - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - if( pOp->opcode==OP_Found ){ - VdbeBranchTaken(alreadyExists!=0,2); - if( alreadyExists ) goto jump_to_p2; - }else{ - VdbeBranchTaken(takeJump||alreadyExists==0,2); - if( takeJump || !alreadyExists ) goto jump_to_p2; - } - break; -} - -/* Opcode: SeekRowid P1 P2 P3 * * -** Synopsis: intkey=r[P3] -** -** P1 is the index of a cursor open on an SQL table btree (with integer -** keys). If register P3 does not contain an integer or if P1 does not -** contain a record with rowid P3 then jump immediately to P2. -** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain -** a record with rowid P3 then -** leave the cursor pointing at that record and fall through to the next -** instruction. -** -** The OP_NotExists opcode performs the same operation, but with OP_NotExists -** the P3 register must be guaranteed to contain an integer value. With this -** opcode, register P3 might not contain an integer. -** -** The OP_NotFound opcode performs the same operation on index btrees -** (with arbitrary multi-value keys). -** -** This opcode leaves the cursor in a state where it cannot be advanced -** in either direction. In other words, the Next and Prev opcodes will -** not work following this opcode. -** -** See also: Found, NotFound, NoConflict, SeekRowid -*/ -/* Opcode: NotExists P1 P2 P3 * * -** Synopsis: intkey=r[P3] -** -** P1 is the index of a cursor open on an SQL table btree (with integer -** keys). P3 is an integer rowid. If P1 does not contain a record with -** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an -** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then -** leave the cursor pointing at that record and fall through to the next -** instruction. -** -** The OP_SeekRowid opcode performs the same operation but also allows the -** P3 register to contain a non-integer value, in which case the jump is -** always taken. This opcode requires that P3 always contain an integer. -** -** The OP_NotFound opcode performs the same operation on index btrees -** (with arbitrary multi-value keys). -** -** This opcode leaves the cursor in a state where it cannot be advanced -** in either direction. In other words, the Next and Prev opcodes will -** not work following this opcode. -** -** See also: Found, NotFound, NoConflict, SeekRowid -*/ -case OP_SeekRowid: { /* jump, in3 */ - VdbeCursor *pC; - BtCursor *pCrsr; - int res; - u64 iKey; - - pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & MEM_Int)==0 ){ - applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding); - if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2; - } - /* Fall through into OP_NotExists */ -case OP_NotExists: /* jump, in3 */ - pIn3 = &aMem[pOp->p3]; - assert( pIn3->flags & MEM_Int ); - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); -#ifdef SQLITE_DEBUG - pC->seekOp = 0; -#endif - assert( pC->isTable ); - assert( pC->eCurType==CURTYPE_BTREE ); - pCrsr = pC->uc.pCursor; - assert( pCrsr!=0 ); - res = 0; - iKey = pIn3->u.i; - rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); - assert( rc==SQLITE_OK || res==0 ); - pC->movetoTarget = iKey; /* Used by OP_Delete */ - pC->nullRow = 0; - pC->cacheStatus = CACHE_STALE; - pC->deferredMoveto = 0; - VdbeBranchTaken(res!=0,2); - pC->seekResult = res; - if( res!=0 ){ - assert( rc==SQLITE_OK ); - if( pOp->p2==0 ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - goto jump_to_p2; - } - } - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: Sequence P1 P2 * * * -** Synopsis: r[P2]=cursor[P1].ctr++ -** -** Find the next available sequence number for cursor P1. -** Write the sequence number into register P2. -** The sequence number on the cursor is incremented after this -** instruction. -*/ -case OP_Sequence: { /* out2 */ - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( p->apCsr[pOp->p1]!=0 ); - assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB ); - pOut = out2Prerelease(p, pOp); - pOut->u.i = p->apCsr[pOp->p1]->seqCount++; - break; -} - - -/* Opcode: NewRowid P1 P2 P3 * * -** Synopsis: r[P2]=rowid -** -** Get a new integer record number (a.k.a "rowid") used as the key to a table. -** The record number is not previously used as a key in the database -** table that cursor P1 points to. The new record number is written -** written to register P2. -** -** If P3>0 then P3 is a register in the root frame of this VDBE that holds -** the largest previously generated record number. No new record numbers are -** allowed to be less than this value. When this value reaches its maximum, -** an SQLITE_FULL error is generated. The P3 register is updated with the ' -** generated record number. This P3 mechanism is used to help implement the -** AUTOINCREMENT feature. -*/ -case OP_NewRowid: { /* out2 */ - i64 v; /* The new rowid */ - VdbeCursor *pC; /* Cursor of table to get the new rowid */ - int res; /* Result of an sqlite3BtreeLast() */ - int cnt; /* Counter to limit the number of searches */ - Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ - VdbeFrame *pFrame; /* Root frame of VDBE */ - - v = 0; - res = 0; - pOut = out2Prerelease(p, pOp); - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - { - /* The next rowid or record number (different terms for the same - ** thing) is obtained in a two-step algorithm. - ** - ** First we attempt to find the largest existing rowid and add one - ** to that. But if the largest existing rowid is already the maximum - ** positive integer, we have to fall through to the second - ** probabilistic algorithm - ** - ** The second algorithm is to select a rowid at random and see if - ** it already exists in the table. If it does not exist, we have - ** succeeded. If the random rowid does exist, we select a new one - ** and try again, up to 100 times. - */ - assert( pC->isTable ); - -#ifdef SQLITE_32BIT_ROWID -# define MAX_ROWID 0x7fffffff -#else - /* Some compilers complain about constants of the form 0x7fffffffffffffff. - ** Others complain about 0x7ffffffffffffffffLL. The following macro seems - ** to provide the constant while making all compilers happy. - */ -# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) -#endif - - if( !pC->useRandomRowid ){ - rc = sqlite3BtreeLast(pC->uc.pCursor, &res); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( res ){ - v = 1; /* IMP: R-61914-48074 */ - }else{ - assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); - v = sqlite3BtreeIntegerKey(pC->uc.pCursor); - if( v>=MAX_ROWID ){ - pC->useRandomRowid = 1; - }else{ - v++; /* IMP: R-29538-34987 */ - } - } - } - -#ifndef SQLITE_OMIT_AUTOINCREMENT - if( pOp->p3 ){ - /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3>0 ); - if( p->pFrame ){ - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=pFrame->nMem ); - pMem = &pFrame->aMem[pOp->p3]; - }else{ - /* Assert that P3 is a valid memory cell. */ - assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); - pMem = &aMem[pOp->p3]; - memAboutToChange(p, pMem); - } - assert( memIsValid(pMem) ); - - REGISTER_TRACE(pOp->p3, pMem); - sqlite3VdbeMemIntegerify(pMem); - assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ - if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ - rc = SQLITE_FULL; /* IMP: R-12275-61338 */ - goto abort_due_to_error; - } - if( vu.i+1 ){ - v = pMem->u.i + 1; - } - pMem->u.i = v; - } -#endif - if( pC->useRandomRowid ){ - /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the - ** largest possible integer (9223372036854775807) then the database - ** engine starts picking positive candidate ROWIDs at random until - ** it finds one that is not previously used. */ - assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is - ** an AUTOINCREMENT table. */ - cnt = 0; - do{ - sqlite3_randomness(sizeof(v), &v); - v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ - }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v, - 0, &res))==SQLITE_OK) - && (res==0) - && (++cnt<100)); - if( rc ) goto abort_due_to_error; - if( res==0 ){ - rc = SQLITE_FULL; /* IMP: R-38219-53002 */ - goto abort_due_to_error; - } - assert( v>0 ); /* EV: R-40812-03570 */ - } - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - } - pOut->u.i = v; - break; -} - -/* Opcode: Insert P1 P2 P3 P4 P5 -** Synopsis: intkey=r[P3] data=r[P2] -** -** Write an entry into the table of cursor P1. A new entry is -** created if it doesn't already exist or the data for an existing -** entry is overwritten. The data is the value MEM_Blob stored in register -** number P2. The key is stored in register P3. The key must -** be a MEM_Int. -** -** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is -** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, -** then rowid is stored for subsequent return by the -** sqlite3_last_insert_rowid() function (otherwise it is unmodified). -** -** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of -** the last seek operation (OP_NotExists or OP_SeekRowid) was a success, -** then this -** operation will not attempt to find the appropriate row before doing -** the insert but will instead overwrite the row that the cursor is -** currently pointing to. Presumably, the prior OP_NotExists or -** OP_SeekRowid opcode -** has already positioned the cursor correctly. This is an optimization -** that boosts performance by avoiding redundant seeks. -** -** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an -** UPDATE operation. Otherwise (if the flag is clear) then this opcode -** is part of an INSERT operation. The difference is only important to -** the update hook. -** -** Parameter P4 may point to a Table structure, or may be NULL. If it is -** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked -** following a successful insert. -** -** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically -** allocated, then ownership of P2 is transferred to the pseudo-cursor -** and register P2 becomes ephemeral. If the cursor is changed, the -** value of register P2 will then change. Make sure this does not -** cause any problems.) -** -** This instruction only works on tables. The equivalent instruction -** for indices is OP_IdxInsert. -*/ -/* Opcode: InsertInt P1 P2 P3 P4 P5 -** Synopsis: intkey=P3 data=r[P2] -** -** This works exactly like OP_Insert except that the key is the -** integer value P3, not the value of the integer stored in register P3. -*/ -case OP_Insert: -case OP_InsertInt: { - Mem *pData; /* MEM cell holding data for the record to be inserted */ - Mem *pKey; /* MEM cell holding key for the record */ - VdbeCursor *pC; /* Cursor to table into which insert is written */ - int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ - const char *zDb; /* database name - used by the update hook */ - Table *pTab; /* Table structure - used by update and pre-update hooks */ - int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ - BtreePayload x; /* Payload to be inserted */ - - op = 0; - pData = &aMem[pOp->p2]; - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( memIsValid(pData) ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->isTable ); - assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); - REGISTER_TRACE(pOp->p2, pData); - - if( pOp->opcode==OP_Insert ){ - pKey = &aMem[pOp->p3]; - assert( pKey->flags & MEM_Int ); - assert( memIsValid(pKey) ); - REGISTER_TRACE(pOp->p3, pKey); - x.nKey = pKey->u.i; - }else{ - assert( pOp->opcode==OP_InsertInt ); - x.nKey = pOp->p3; - } - - if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ - assert( pC->isTable ); - assert( pC->iDb>=0 ); - zDb = db->aDb[pC->iDb].zDbSName; - pTab = pOp->p4.pTab; - assert( HasRowid(pTab) ); - op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - }else{ - pTab = 0; /* Not needed. Silence a comiler warning. */ - zDb = 0; /* Not needed. Silence a compiler warning. */ - } - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - /* Invoke the pre-update hook, if any */ - if( db->xPreUpdateCallback - && pOp->p4type==P4_TABLE - && !(pOp->p5 & OPFLAG_ISUPDATE) - ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2); - } -#endif - - if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = x.nKey; - if( pData->flags & MEM_Null ){ - x.pData = 0; - x.nData = 0; - }else{ - assert( pData->flags & (MEM_Blob|MEM_Str) ); - x.pData = pData->z; - x.nData = pData->n; - } - seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); - if( pData->flags & MEM_Zero ){ - x.nZero = pData->u.nZero; - }else{ - x.nZero = 0; - } - x.pKey = 0; - rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & OPFLAG_APPEND)!=0, seekResult - ); - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - - /* Invoke the update-hook if required. */ - if( rc ) goto abort_due_to_error; - if( db->xUpdateCallback && op ){ - db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey); - } - break; -} - -/* Opcode: Delete P1 P2 P3 P4 P5 -** -** Delete the record at which the P1 cursor is currently pointing. -** -** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then -** the cursor will be left pointing at either the next or the previous -** record in the table. If it is left pointing at the next record, then -** the next Next instruction will be a no-op. As a result, in this case -** it is ok to delete a record from within a Next loop. If -** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be -** left in an undefined state. -** -** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this -** delete one of several associated with deleting a table row and all its -** associated index entries. Exactly one of those deletes is the "primary" -** delete. The others are all on OPFLAG_FORDELETE cursors or else are -** marked with the AUXDELETE flag. -** -** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row -** change count is incremented (otherwise not). -** -** P1 must not be pseudo-table. It has to be a real table with -** multiple rows. -** -** If P4 is not NULL then it points to a Table object. In this case either -** the update or pre-update hook, or both, may be invoked. The P1 cursor must -** have been positioned using OP_NotFound prior to invoking this opcode in -** this case. Specifically, if one is configured, the pre-update hook is -** invoked if P4 is not NULL. The update-hook is invoked if one is configured, -** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2. -** -** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address -** of the memory cell that contains the value that the rowid of the row will -** be set to by the update. -*/ -case OP_Delete: { - VdbeCursor *pC; - const char *zDb; - Table *pTab; - int opflags; - - opflags = pOp->p2; - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->deferredMoveto==0 ); - -#ifdef SQLITE_DEBUG - if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){ - /* If p5 is zero, the seek operation that positioned the cursor prior to - ** OP_Delete will have also set the pC->movetoTarget field to the rowid of - ** the row that is being deleted */ - i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor); - assert( pC->movetoTarget==iKey ); - } -#endif - - /* If the update-hook or pre-update-hook will be invoked, set zDb to - ** the name of the db to pass as to it. Also set local pTab to a copy - ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was - ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set - ** VdbeCursor.movetoTarget to the current rowid. */ - if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ - assert( pC->iDb>=0 ); - assert( pOp->p4.pTab!=0 ); - zDb = db->aDb[pC->iDb].zDbSName; - pTab = pOp->p4.pTab; - if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ - pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); - } - }else{ - zDb = 0; /* Not needed. Silence a compiler warning. */ - pTab = 0; /* Not needed. Silence a compiler warning. */ - } - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - /* Invoke the pre-update-hook if required. */ - if( db->xPreUpdateCallback && pOp->p4.pTab && HasRowid(pTab) ){ - assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) ); - sqlite3VdbePreUpdateHook(p, pC, - (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, - zDb, pTab, pC->movetoTarget, - pOp->p3 - ); - } - if( opflags & OPFLAG_ISNOOP ) break; -#endif - - /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ - assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); - assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); - assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); - -#ifdef SQLITE_DEBUG - if( p->pFrame==0 ){ - if( pC->isEphemeral==0 - && (pOp->p5 & OPFLAG_AUXDELETE)==0 - && (pC->wrFlag & OPFLAG_FORDELETE)==0 - ){ - nExtraDelete++; - } - if( pOp->p2 & OPFLAG_NCHANGE ){ - nExtraDelete--; - } - } -#endif - - rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); - pC->cacheStatus = CACHE_STALE; - if( rc ) goto abort_due_to_error; - - /* Invoke the update-hook if required. */ - if( opflags & OPFLAG_NCHANGE ){ - p->nChange++; - if( db->xUpdateCallback && HasRowid(pTab) ){ - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, - pC->movetoTarget); - assert( pC->iDb>=0 ); - } - } - - break; -} -/* Opcode: ResetCount * * * * * -** -** The value of the change counter is copied to the database handle -** change counter (returned by subsequent calls to sqlite3_changes()). -** Then the VMs internal change counter resets to 0. -** This is used by trigger programs. -*/ -case OP_ResetCount: { - sqlite3VdbeSetChanges(db, p->nChange); - p->nChange = 0; - break; -} - -/* Opcode: SorterCompare P1 P2 P3 P4 -** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 -** -** P1 is a sorter cursor. This instruction compares a prefix of the -** record blob in register P3 against a prefix of the entry that -** the sorter cursor currently points to. Only the first P4 fields -** of r[P3] and the sorter record are compared. -** -** If either P3 or the sorter contains a NULL in one of their significant -** fields (not counting the P4 fields at the end which are ignored) then -** the comparison is assumed to be equal. -** -** Fall through to next instruction if the two records compare equal to -** each other. Jump to P2 if they are different. -*/ -case OP_SorterCompare: { - VdbeCursor *pC; - int res; - int nKeyCol; - - pC = p->apCsr[pOp->p1]; - assert( isSorter(pC) ); - assert( pOp->p4type==P4_INT32 ); - pIn3 = &aMem[pOp->p3]; - nKeyCol = pOp->p4.i; - res = 0; - rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); - VdbeBranchTaken(res!=0,2); - if( rc ) goto abort_due_to_error; - if( res ) goto jump_to_p2; - break; -}; - -/* Opcode: SorterData P1 P2 P3 * * -** Synopsis: r[P2]=data -** -** Write into register P2 the current sorter data for sorter cursor P1. -** Then clear the column header cache on cursor P3. -** -** This opcode is normally use to move a record out of the sorter and into -** a register that is the source for a pseudo-table cursor created using -** OpenPseudo. That pseudo-table cursor is the one that is identified by -** parameter P3. Clearing the P3 column cache as part of this opcode saves -** us from having to issue a separate NullRow instruction to clear that cache. -*/ -case OP_SorterData: { - VdbeCursor *pC; - - pOut = &aMem[pOp->p2]; - pC = p->apCsr[pOp->p1]; - assert( isSorter(pC) ); - rc = sqlite3VdbeSorterRowkey(pC, pOut); - assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); - assert( pOp->p1>=0 && pOp->p1nCursor ); - if( rc ) goto abort_due_to_error; - p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; - break; -} - -/* Opcode: RowData P1 P2 * * * -** Synopsis: r[P2]=data -** -** Write into register P2 the complete row data for cursor P1. -** There is no interpretation of the data. -** It is just copied onto the P2 register exactly as -** it is found in the database file. -** -** If the P1 cursor must be pointing to a valid row (not a NULL row) -** of a real table, not a pseudo-table. -*/ -/* Opcode: RowKey P1 P2 * * * -** Synopsis: r[P2]=key -** -** Write into register P2 the complete row key for cursor P1. -** There is no interpretation of the data. -** The key is copied onto the P2 register exactly as -** it is found in the database file. -** -** If the P1 cursor must be pointing to a valid row (not a NULL row) -** of a real table, not a pseudo-table. -*/ -case OP_RowKey: -case OP_RowData: { - VdbeCursor *pC; - BtCursor *pCrsr; - u32 n; - - pOut = &aMem[pOp->p2]; - memAboutToChange(p, pOut); - - /* Note that RowKey and RowData are really exactly the same instruction */ - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( isSorter(pC)==0 ); - assert( pC->isTable || pOp->opcode!=OP_RowData ); - assert( pC->isTable==0 || pOp->opcode==OP_RowData ); - assert( pC->nullRow==0 ); - assert( pC->uc.pCursor!=0 ); - pCrsr = pC->uc.pCursor; - - /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or - ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions - ** that might invalidate the cursor. - ** If this where not the case, on of the following assert()s - ** would fail. Should this ever change (because of changes in the code - ** generator) then the fix would be to insert a call to - ** sqlite3VdbeCursorMoveto(). - */ - assert( pC->deferredMoveto==0 ); - assert( sqlite3BtreeCursorIsValid(pCrsr) ); -#if 0 /* Not required due to the previous to assert() statements */ - rc = sqlite3VdbeCursorMoveto(pC); - if( rc!=SQLITE_OK ) goto abort_due_to_error; -#endif - - n = sqlite3BtreePayloadSize(pCrsr); - if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - testcase( n==0 ); - if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){ - goto no_mem; - } - pOut->n = n; - MemSetTypeFlag(pOut, MEM_Blob); - if( pC->isTable==0 ){ - rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); - }else{ - rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); - } - if( rc ) goto abort_due_to_error; - pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ - UPDATE_MAX_BLOBSIZE(pOut); - REGISTER_TRACE(pOp->p2, pOut); - break; -} - -/* Opcode: Rowid P1 P2 * * * -** Synopsis: r[P2]=rowid -** -** Store in register P2 an integer which is the key of the table entry that -** P1 is currently point to. -** -** P1 can be either an ordinary table or a virtual table. There used to -** be a separate OP_VRowid opcode for use with virtual tables, but this -** one opcode now works for both table types. -*/ -case OP_Rowid: { /* out2 */ - VdbeCursor *pC; - i64 v; - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - - pOut = out2Prerelease(p, pOp); - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); - if( pC->nullRow ){ - pOut->flags = MEM_Null; - break; - }else if( pC->deferredMoveto ){ - v = pC->movetoTarget; -#ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( pC->eCurType==CURTYPE_VTAB ){ - assert( pC->uc.pVCur!=0 ); - pVtab = pC->uc.pVCur->pVtab; - pModule = pVtab->pModule; - assert( pModule->xRowid ); - rc = pModule->xRowid(pC->uc.pVCur, &v); - sqlite3VtabImportErrmsg(p, pVtab); - if( rc ) goto abort_due_to_error; -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - }else{ - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - rc = sqlite3VdbeCursorRestore(pC); - if( rc ) goto abort_due_to_error; - if( pC->nullRow ){ - pOut->flags = MEM_Null; - break; - } - v = sqlite3BtreeIntegerKey(pC->uc.pCursor); - } - pOut->u.i = v; - break; -} - -/* Opcode: NullRow P1 * * * * -** -** Move the cursor P1 to a null row. Any OP_Column operations -** that occur while the cursor is on the null row will always -** write a NULL. -*/ -case OP_NullRow: { - VdbeCursor *pC; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - pC->nullRow = 1; - pC->cacheStatus = CACHE_STALE; - if( pC->eCurType==CURTYPE_BTREE ){ - assert( pC->uc.pCursor!=0 ); - sqlite3BtreeClearCursor(pC->uc.pCursor); - } - break; -} - -/* Opcode: Last P1 P2 P3 * * -** -** The next use of the Rowid or Column or Prev instruction for P1 -** will refer to the last entry in the database table or index. -** If the table or index is empty and P2>0, then jump immediately to P2. -** If P2 is 0 or if the table or index is not empty, fall through -** to the following instruction. -** -** This opcode leaves the cursor configured to move in reverse order, -** from the end toward the beginning. In other words, the cursor is -** configured to use Prev, not Next. -*/ -case OP_Last: { /* jump */ - VdbeCursor *pC; - BtCursor *pCrsr; - int res; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - pCrsr = pC->uc.pCursor; - res = 0; - assert( pCrsr!=0 ); - rc = sqlite3BtreeLast(pCrsr, &res); - pC->nullRow = (u8)res; - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - pC->seekResult = pOp->p3; -#ifdef SQLITE_DEBUG - pC->seekOp = OP_Last; -#endif - if( rc ) goto abort_due_to_error; - if( pOp->p2>0 ){ - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; - } - break; -} - - -/* Opcode: Sort P1 P2 * * * -** -** This opcode does exactly the same thing as OP_Rewind except that -** it increments an undocumented global variable used for testing. -** -** Sorting is accomplished by writing records into a sorting index, -** then rewinding that index and playing it back from beginning to -** end. We use the OP_Sort opcode instead of OP_Rewind to do the -** rewinding so that the global variable will be incremented and -** regression tests can determine whether or not the optimizer is -** correctly optimizing out sorts. -*/ -case OP_SorterSort: /* jump */ -case OP_Sort: { /* jump */ -#ifdef SQLITE_TEST - sqlite3_sort_count++; - sqlite3_search_count--; -#endif - p->aCounter[SQLITE_STMTSTATUS_SORT]++; - /* Fall through into OP_Rewind */ -} -/* Opcode: Rewind P1 P2 * * * -** -** The next use of the Rowid or Column or Next instruction for P1 -** will refer to the first entry in the database table or index. -** If the table or index is empty, jump immediately to P2. -** If the table or index is not empty, fall through to the following -** instruction. -** -** This opcode leaves the cursor configured to move in forward order, -** from the beginning toward the end. In other words, the cursor is -** configured to use Next, not Prev. -*/ -case OP_Rewind: { /* jump */ - VdbeCursor *pC; - BtCursor *pCrsr; - int res; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); - res = 1; -#ifdef SQLITE_DEBUG - pC->seekOp = OP_Rewind; -#endif - if( isSorter(pC) ){ - rc = sqlite3VdbeSorterRewind(pC, &res); - }else{ - assert( pC->eCurType==CURTYPE_BTREE ); - pCrsr = pC->uc.pCursor; - assert( pCrsr ); - rc = sqlite3BtreeFirst(pCrsr, &res); - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; - } - if( rc ) goto abort_due_to_error; - pC->nullRow = (u8)res; - assert( pOp->p2>0 && pOp->p2nOp ); - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; - break; -} - -/* Opcode: Next P1 P2 P3 P4 P5 -** -** Advance cursor P1 so that it points to the next key/data pair in its -** table or index. If there are no more key/value pairs then fall through -** to the following instruction. But if the cursor advance was successful, -** jump immediately to P2. -** -** The Next opcode is only valid following an SeekGT, SeekGE, or -** OP_Rewind opcode used to position the cursor. Next is not allowed -** to follow SeekLT, SeekLE, or OP_Last. -** -** The P1 cursor must be for a real table, not a pseudo-table. P1 must have -** been opened prior to this opcode or the program will segfault. -** -** The P3 value is a hint to the btree implementation. If P3==1, that -** means P1 is an SQL index and that this instruction could have been -** omitted if that index had been unique. P3 is usually 0. P3 is -** always either 0 or 1. -** -** P4 is always of type P4_ADVANCE. The function pointer points to -** sqlite3BtreeNext(). -** -** If P5 is positive and the jump is taken, then event counter -** number P5-1 in the prepared statement is incremented. -** -** See also: Prev, NextIfOpen -*/ -/* Opcode: NextIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Next except that if cursor P1 is not -** open it behaves a no-op. -*/ -/* Opcode: Prev P1 P2 P3 P4 P5 -** -** Back up cursor P1 so that it points to the previous key/data pair in its -** table or index. If there is no previous key/value pairs then fall through -** to the following instruction. But if the cursor backup was successful, -** jump immediately to P2. -** -** -** The Prev opcode is only valid following an SeekLT, SeekLE, or -** OP_Last opcode used to position the cursor. Prev is not allowed -** to follow SeekGT, SeekGE, or OP_Rewind. -** -** The P1 cursor must be for a real table, not a pseudo-table. If P1 is -** not open then the behavior is undefined. -** -** The P3 value is a hint to the btree implementation. If P3==1, that -** means P1 is an SQL index and that this instruction could have been -** omitted if that index had been unique. P3 is usually 0. P3 is -** always either 0 or 1. -** -** P4 is always of type P4_ADVANCE. The function pointer points to -** sqlite3BtreePrevious(). -** -** If P5 is positive and the jump is taken, then event counter -** number P5-1 in the prepared statement is incremented. -*/ -/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Prev except that if cursor P1 is not -** open it behaves a no-op. -*/ -case OP_SorterNext: { /* jump */ - VdbeCursor *pC; - int res; - - pC = p->apCsr[pOp->p1]; - assert( isSorter(pC) ); - res = 0; - rc = sqlite3VdbeSorterNext(db, pC, &res); - goto next_tail; -case OP_PrevIfOpen: /* jump */ -case OP_NextIfOpen: /* jump */ - if( p->apCsr[pOp->p1]==0 ) break; - /* Fall through */ -case OP_Prev: /* jump */ -case OP_Next: /* jump */ - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p5aCounter) ); - pC = p->apCsr[pOp->p1]; - res = pOp->p3; - assert( pC!=0 ); - assert( pC->deferredMoveto==0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( res==0 || (res==1 && pC->isTable==0) ); - testcase( res==1 ); - assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); - assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); - - /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. - ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ - assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen - || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); - assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen - || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last ); - - rc = pOp->p4.xAdvance(pC->uc.pCursor, &res); -next_tail: - pC->cacheStatus = CACHE_STALE; - VdbeBranchTaken(res==0,2); - if( rc ) goto abort_due_to_error; - if( res==0 ){ - pC->nullRow = 0; - p->aCounter[pOp->p5]++; -#ifdef SQLITE_TEST - sqlite3_search_count++; -#endif - goto jump_to_p2_and_check_for_interrupt; - }else{ - pC->nullRow = 1; - } - goto check_for_interrupt; -} - -/* Opcode: IdxInsert P1 P2 P3 * P5 -** Synopsis: key=r[P2] -** -** Register P2 holds an SQL index key made using the -** MakeRecord instructions. This opcode writes that key -** into the index P1. Data for the entry is nil. -** -** P3 is a flag that provides a hint to the b-tree layer that this -** insert is likely to be an append. -** -** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is -** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, -** then the change counter is unchanged. -** -** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have -** just done a seek to the spot where the new entry is to be inserted. -** This flag avoids doing an extra seek. -** -** This instruction only works for indices. The equivalent instruction -** for tables is OP_Insert. -*/ -case OP_SorterInsert: /* in2 */ -case OP_IdxInsert: { /* in2 */ - VdbeCursor *pC; - BtreePayload x; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); - pIn2 = &aMem[pOp->p2]; - assert( pIn2->flags & MEM_Blob ); - if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert ); - assert( pC->isTable==0 ); - rc = ExpandBlob(pIn2); - if( rc ) goto abort_due_to_error; - if( pOp->opcode==OP_SorterInsert ){ - rc = sqlite3VdbeSorterWrite(pC, pIn2); - }else{ - x.nKey = pIn2->n; - x.pKey = pIn2->z; - rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3, - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) - ); - assert( pC->deferredMoveto==0 ); - pC->cacheStatus = CACHE_STALE; - } - if( rc) goto abort_due_to_error; - break; -} - -/* Opcode: IdxDelete P1 P2 P3 * * -** Synopsis: key=r[P2@P3] -** -** The content of P3 registers starting at register P2 form -** an unpacked index key. This opcode removes that entry from the -** index opened by cursor P1. -*/ -case OP_IdxDelete: { - VdbeCursor *pC; - BtCursor *pCrsr; - int res; - UnpackedRecord r; - - assert( pOp->p3>0 ); - assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - pCrsr = pC->uc.pCursor; - assert( pCrsr!=0 ); - assert( pOp->p5==0 ); - r.pKeyInfo = pC->pKeyInfo; - r.nField = (u16)pOp->p3; - r.default_rc = 0; - r.aMem = &aMem[pOp->p2]; - rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); - if( rc ) goto abort_due_to_error; - if( res==0 ){ - rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); - if( rc ) goto abort_due_to_error; - } - assert( pC->deferredMoveto==0 ); - pC->cacheStatus = CACHE_STALE; - break; -} - -/* Opcode: Seek P1 * P3 P4 * -** Synopsis: Move P3 to P1.rowid -** -** P1 is an open index cursor and P3 is a cursor on the corresponding -** table. This opcode does a deferred seek of the P3 table cursor -** to the row that corresponds to the current row of P1. -** -** This is a deferred seek. Nothing actually happens until -** the cursor is used to read a record. That way, if no reads -** occur, no unnecessary I/O happens. -** -** P4 may be an array of integers (type P4_INTARRAY) containing -** one entry for each column in the P3 table. If array entry a(i) -** is non-zero, then reading column a(i)-1 from cursor P3 is -** equivalent to performing the deferred seek and then reading column i -** from P1. This information is stored in P3 and used to redirect -** reads against P3 over to P1, thus possibly avoiding the need to -** seek and read cursor P3. -*/ -/* Opcode: IdxRowid P1 P2 * * * -** Synopsis: r[P2]=rowid -** -** Write into register P2 an integer which is the last entry in the record at -** the end of the index key pointed to by cursor P1. This integer should be -** the rowid of the table entry to which this index entry points. -** -** See also: Rowid, MakeRecord. -*/ -case OP_Seek: -case OP_IdxRowid: { /* out2 */ - VdbeCursor *pC; /* The P1 index cursor */ - VdbeCursor *pTabCur; /* The P2 table cursor (OP_Seek only) */ - i64 rowid; /* Rowid that P1 current points to */ - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->isTable==0 ); - assert( pC->deferredMoveto==0 ); - assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); - - /* The IdxRowid and Seek opcodes are combined because of the commonality - ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ - rc = sqlite3VdbeCursorRestore(pC); - - /* sqlite3VbeCursorRestore() can only fail if the record has been deleted - ** out from under the cursor. That will never happens for an IdxRowid - ** or Seek opcode */ - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; - - if( !pC->nullRow ){ - rowid = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); - if( rc!=SQLITE_OK ){ - goto abort_due_to_error; - } - if( pOp->opcode==OP_Seek ){ - assert( pOp->p3>=0 && pOp->p3nCursor ); - pTabCur = p->apCsr[pOp->p3]; - assert( pTabCur!=0 ); - assert( pTabCur->eCurType==CURTYPE_BTREE ); - assert( pTabCur->uc.pCursor!=0 ); - assert( pTabCur->isTable ); - pTabCur->nullRow = 0; - pTabCur->movetoTarget = rowid; - pTabCur->deferredMoveto = 1; - assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); - pTabCur->aAltMap = pOp->p4.ai; - pTabCur->pAltCursor = pC; - }else{ - pOut = out2Prerelease(p, pOp); - pOut->u.i = rowid; - pOut->flags = MEM_Int; - } - }else{ - assert( pOp->opcode==OP_IdxRowid ); - sqlite3VdbeMemSetNull(&aMem[pOp->p2]); - } - break; -} - -/* Opcode: IdxGE P1 P2 P3 P4 P5 -** Synopsis: key=r[P3@P4] -** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY. Compare this key value against the index -** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID -** fields at the end. -** -** If the P1 index entry is greater than or equal to the key value -** then jump to P2. Otherwise fall through to the next instruction. -*/ -/* Opcode: IdxGT P1 P2 P3 P4 P5 -** Synopsis: key=r[P3@P4] -** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY. Compare this key value against the index -** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID -** fields at the end. -** -** If the P1 index entry is greater than the key value -** then jump to P2. Otherwise fall through to the next instruction. -*/ -/* Opcode: IdxLT P1 P2 P3 P4 P5 -** Synopsis: key=r[P3@P4] -** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY or ROWID. Compare this key value against -** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or -** ROWID on the P1 index. -** -** If the P1 index entry is less than the key value then jump to P2. -** Otherwise fall through to the next instruction. -*/ -/* Opcode: IdxLE P1 P2 P3 P4 P5 -** Synopsis: key=r[P3@P4] -** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY or ROWID. Compare this key value against -** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or -** ROWID on the P1 index. -** -** If the P1 index entry is less than or equal to the key value then jump -** to P2. Otherwise fall through to the next instruction. -*/ -case OP_IdxLE: /* jump */ -case OP_IdxGT: /* jump */ -case OP_IdxLT: /* jump */ -case OP_IdxGE: { /* jump */ - VdbeCursor *pC; - int res; - UnpackedRecord r; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->isOrdered ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0); - assert( pC->deferredMoveto==0 ); - assert( pOp->p5==0 || pOp->p5==1 ); - assert( pOp->p4type==P4_INT32 ); - r.pKeyInfo = pC->pKeyInfo; - r.nField = (u16)pOp->p4.i; - if( pOp->opcodeopcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); - r.default_rc = -1; - }else{ - assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); - r.default_rc = 0; - } - r.aMem = &aMem[pOp->p3]; -#ifdef SQLITE_DEBUG - { int i; for(i=0; iopcode&1)==(OP_IdxLT&1) ){ - assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); - res = -res; - }else{ - assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); - res++; - } - VdbeBranchTaken(res>0,2); - if( rc ) goto abort_due_to_error; - if( res>0 ) goto jump_to_p2; - break; -} - -/* Opcode: Destroy P1 P2 P3 * * -** -** Delete an entire database table or index whose root page in the database -** file is given by P1. -** -** The table being destroyed is in the main database file if P3==0. If -** P3==1 then the table to be clear is in the auxiliary database file -** that is used to store tables create using CREATE TEMPORARY TABLE. -** -** If AUTOVACUUM is enabled then it is possible that another root page -** might be moved into the newly deleted root page in order to keep all -** root pages contiguous at the beginning of the database. The former -** value of the root page that moved - its value before the move occurred - -** is stored in register P2. If no page -** movement was required (because the table being dropped was already -** the last one in the database) then a zero is stored in register P2. -** If AUTOVACUUM is disabled then a zero is stored in register P2. -** -** See also: Clear -*/ -case OP_Destroy: { /* out2 */ - int iMoved; - int iDb; - - assert( p->readOnly==0 ); - assert( pOp->p1>1 ); - pOut = out2Prerelease(p, pOp); - pOut->flags = MEM_Null; - if( db->nVdbeRead > db->nVDestroy+1 ){ - rc = SQLITE_LOCKED; - p->errorAction = OE_Abort; - goto abort_due_to_error; - }else{ - iDb = pOp->p3; - assert( DbMaskTest(p->btreeMask, iDb) ); - iMoved = 0; /* Not needed. Only to silence a warning. */ - rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); - pOut->flags = MEM_Int; - pOut->u.i = iMoved; - if( rc ) goto abort_due_to_error; -#ifndef SQLITE_OMIT_AUTOVACUUM - if( iMoved!=0 ){ - sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); - /* All OP_Destroy operations occur on the same btree */ - assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); - resetSchemaOnFault = iDb+1; - } -#endif - } - break; -} - -/* Opcode: Clear P1 P2 P3 -** -** Delete all contents of the database table or index whose root page -** in the database file is given by P1. But, unlike Destroy, do not -** remove the table or index from the database file. -** -** The table being clear is in the main database file if P2==0. If -** P2==1 then the table to be clear is in the auxiliary database file -** that is used to store tables create using CREATE TEMPORARY TABLE. -** -** If the P3 value is non-zero, then the table referred to must be an -** intkey table (an SQL table, not an index). In this case the row change -** count is incremented by the number of rows in the table being cleared. -** If P3 is greater than zero, then the value stored in register P3 is -** also incremented by the number of rows in the table being cleared. -** -** See also: Destroy -*/ -case OP_Clear: { - int nChange; - - nChange = 0; - assert( p->readOnly==0 ); - assert( DbMaskTest(p->btreeMask, pOp->p2) ); - rc = sqlite3BtreeClearTable( - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) - ); - if( pOp->p3 ){ - p->nChange += nChange; - if( pOp->p3>0 ){ - assert( memIsValid(&aMem[pOp->p3]) ); - memAboutToChange(p, &aMem[pOp->p3]); - aMem[pOp->p3].u.i += nChange; - } - } - if( rc ) goto abort_due_to_error; - break; -} - -/* Opcode: ResetSorter P1 * * * * -** -** Delete all contents from the ephemeral table or sorter -** that is open on cursor P1. -** -** This opcode only works for cursors used for sorting and -** opened with OP_OpenEphemeral or OP_SorterOpen. -*/ -case OP_ResetSorter: { - VdbeCursor *pC; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - if( isSorter(pC) ){ - sqlite3VdbeSorterReset(db, pC->uc.pSorter); - }else{ - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->isEphemeral ); - rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor); - if( rc ) goto abort_due_to_error; - } - break; -} - -/* Opcode: CreateTable P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 -** -** Allocate a new table in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2 -** -** The difference between a table and an index is this: A table must -** have a 4-byte integer key and can have arbitrary data. An index -** has an arbitrary key but no data. -** -** See also: CreateIndex -*/ -/* Opcode: CreateIndex P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 -** -** Allocate a new index in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2. -** -** See documentation on OP_CreateTable for additional information. -*/ -case OP_CreateIndex: /* out2 */ -case OP_CreateTable: { /* out2 */ - int pgno; - int flags; - Db *pDb; - - pOut = out2Prerelease(p, pOp); - pgno = 0; - assert( pOp->p1>=0 && pOp->p1nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); - assert( p->readOnly==0 ); - pDb = &db->aDb[pOp->p1]; - assert( pDb->pBt!=0 ); - if( pOp->opcode==OP_CreateTable ){ - /* flags = BTREE_INTKEY; */ - flags = BTREE_INTKEY; - }else{ - flags = BTREE_BLOBKEY; - } - rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); - if( rc ) goto abort_due_to_error; - pOut->u.i = pgno; - break; -} - -/* Opcode: ParseSchema P1 * * P4 * -** -** Read and parse all entries from the SQLITE_MASTER table of database P1 -** that match the WHERE clause P4. -** -** This opcode invokes the parser to create a new virtual machine, -** then runs the new virtual machine. It is thus a re-entrant opcode. -*/ -case OP_ParseSchema: { - int iDb; - const char *zMaster; - char *zSql; - InitData initData; - - /* Any prepared statement that invokes this opcode will hold mutexes - ** on every btree. This is a prerequisite for invoking - ** sqlite3InitCallback(). - */ -#ifdef SQLITE_DEBUG - for(iDb=0; iDbnDb; iDb++){ - assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - } -#endif - - iDb = pOp->p1; - assert( iDb>=0 && iDbnDb ); - assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); - /* Used to be a conditional */ { - zMaster = SCHEMA_TABLE(iDb); - initData.db = db; - initData.iDb = pOp->p1; - initData.pzErrMsg = &p->zErrMsg; - zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", - db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); - if( zSql==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - assert( db->init.busy==0 ); - db->init.busy = 1; - initData.rc = SQLITE_OK; - assert( !db->mallocFailed ); - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); - if( rc==SQLITE_OK ) rc = initData.rc; - sqlite3DbFree(db, zSql); - db->init.busy = 0; - } - } - if( rc ){ - sqlite3ResetAllSchemasOfConnection(db); - if( rc==SQLITE_NOMEM ){ - goto no_mem; - } - goto abort_due_to_error; - } - break; -} - -#if !defined(SQLITE_OMIT_ANALYZE) -/* Opcode: LoadAnalysis P1 * * * * -** -** Read the sqlite_stat1 table for database P1 and load the content -** of that table into the internal index hash table. This will cause -** the analysis to be used when preparing all subsequent queries. -*/ -case OP_LoadAnalysis: { - assert( pOp->p1>=0 && pOp->p1nDb ); - rc = sqlite3AnalysisLoad(db, pOp->p1); - if( rc ) goto abort_due_to_error; - break; -} -#endif /* !defined(SQLITE_OMIT_ANALYZE) */ - -/* Opcode: DropTable P1 * * P4 * -** -** Remove the internal (in-memory) data structures that describe -** the table named P4 in database P1. This is called after a table -** is dropped from disk (using the Destroy opcode) in order to keep -** the internal representation of the -** schema consistent with what is on disk. -*/ -case OP_DropTable: { - sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); - break; -} - -/* Opcode: DropIndex P1 * * P4 * -** -** Remove the internal (in-memory) data structures that describe -** the index named P4 in database P1. This is called after an index -** is dropped from disk (using the Destroy opcode) -** in order to keep the internal representation of the -** schema consistent with what is on disk. -*/ -case OP_DropIndex: { - sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); - break; -} - -/* Opcode: DropTrigger P1 * * P4 * -** -** Remove the internal (in-memory) data structures that describe -** the trigger named P4 in database P1. This is called after a trigger -** is dropped from disk (using the Destroy opcode) in order to keep -** the internal representation of the -** schema consistent with what is on disk. -*/ -case OP_DropTrigger: { - sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); - break; -} - - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK -/* Opcode: IntegrityCk P1 P2 P3 P4 P5 -** -** Do an analysis of the currently open database. Store in -** register P1 the text of an error message describing any problems. -** If no problems are found, store a NULL in register P1. -** -** The register P3 contains the maximum number of allowed errors. -** At most reg(P3) errors will be reported. -** In other words, the analysis stops as soon as reg(P1) errors are -** seen. Reg(P1) is updated with the number of errors remaining. -** -** The root page numbers of all tables in the database are integers -** stored in P4_INTARRAY argument. -** -** If P5 is not zero, the check is done on the auxiliary database -** file, not the main database file. -** -** This opcode is used to implement the integrity_check pragma. -*/ -case OP_IntegrityCk: { - int nRoot; /* Number of tables to check. (Number of root pages.) */ - int *aRoot; /* Array of rootpage numbers for tables to be checked */ - int nErr; /* Number of errors reported */ - char *z; /* Text of the error report */ - Mem *pnErr; /* Register keeping track of errors remaining */ - - assert( p->bIsReader ); - nRoot = pOp->p2; - aRoot = pOp->p4.ai; - assert( nRoot>0 ); - assert( aRoot[nRoot]==0 ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pnErr = &aMem[pOp->p3]; - assert( (pnErr->flags & MEM_Int)!=0 ); - assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); - pIn1 = &aMem[pOp->p1]; - assert( pOp->p5nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p5) ); - z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, - (int)pnErr->u.i, &nErr); - pnErr->u.i -= nErr; - sqlite3VdbeMemSetNull(pIn1); - if( nErr==0 ){ - assert( z==0 ); - }else if( z==0 ){ - goto no_mem; - }else{ - sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); - } - UPDATE_MAX_BLOBSIZE(pIn1); - sqlite3VdbeChangeEncoding(pIn1, encoding); - break; -} -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -/* Opcode: RowSetAdd P1 P2 * * * -** Synopsis: rowset(P1)=r[P2] -** -** Insert the integer value held by register P2 into a boolean index -** held in register P1. -** -** An assertion fails if P2 is not an integer. -*/ -case OP_RowSetAdd: { /* in1, in2 */ - pIn1 = &aMem[pOp->p1]; - pIn2 = &aMem[pOp->p2]; - assert( (pIn2->flags & MEM_Int)!=0 ); - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; - } - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); - break; -} - -/* Opcode: RowSetRead P1 P2 P3 * * -** Synopsis: r[P3]=rowset(P1) -** -** Extract the smallest value from boolean index P1 and put that value into -** register P3. Or, if boolean index P1 is initially empty, leave P3 -** unchanged and jump to instruction P2. -*/ -case OP_RowSetRead: { /* jump, in1, out3 */ - i64 val; - - pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 - ){ - /* The boolean index is empty */ - sqlite3VdbeMemSetNull(pIn1); - VdbeBranchTaken(1,2); - goto jump_to_p2_and_check_for_interrupt; - }else{ - /* A value was pulled from the index */ - VdbeBranchTaken(0,2); - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); - } - goto check_for_interrupt; -} - -/* Opcode: RowSetTest P1 P2 P3 P4 -** Synopsis: if r[P3] in rowset(P1) goto P2 -** -** Register P3 is assumed to hold a 64-bit integer value. If register P1 -** contains a RowSet object and that RowSet object contains -** the value held in P3, jump to register P2. Otherwise, insert the -** integer in P3 into the RowSet and continue on to the -** next opcode. -** -** The RowSet object is optimized for the case where successive sets -** of integers, where each set contains no duplicates. Each set -** of values is identified by a unique P4 value. The first set -** must have P4==0, the final set P4=-1. P4 must be either -1 or -** non-negative. For non-negative values of P4 only the lower 4 -** bits are significant. -** -** This allows optimizations: (a) when P4==0 there is no need to test -** the rowset object for P3, as it is guaranteed not to contain it, -** (b) when P4==-1 there is no need to insert the value, as it will -** never be tested for, and (c) when a value that is part of set X is -** inserted, there is no need to search to see if the same value was -** previously inserted as part of set X (only if it was previously -** inserted as part of some other set). -*/ -case OP_RowSetTest: { /* jump, in1, in3 */ - int iSet; - int exists; - - pIn1 = &aMem[pOp->p1]; - pIn3 = &aMem[pOp->p3]; - iSet = pOp->p4.i; - assert( pIn3->flags&MEM_Int ); - - /* If there is anything other than a rowset object in memory cell P1, - ** delete it now and initialize P1 with an empty rowset - */ - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; - } - - assert( pOp->p4type==P4_INT32 ); - assert( iSet==-1 || iSet>=0 ); - if( iSet ){ - exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); - VdbeBranchTaken(exists!=0,2); - if( exists ) goto jump_to_p2; - } - if( iSet>=0 ){ - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); - } - break; -} - - -#ifndef SQLITE_OMIT_TRIGGER - -/* Opcode: Program P1 P2 P3 P4 P5 -** -** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). -** -** P1 contains the address of the memory cell that contains the first memory -** cell in an array of values used as arguments to the sub-program. P2 -** contains the address to jump to if the sub-program throws an IGNORE -** exception using the RAISE() function. Register P3 contains the address -** of a memory cell in this (the parent) VM that is used to allocate the -** memory required by the sub-vdbe at runtime. -** -** P4 is a pointer to the VM containing the trigger program. -** -** If P5 is non-zero, then recursive program invocation is enabled. -*/ -case OP_Program: { /* jump */ - int nMem; /* Number of memory registers for sub-program */ - int nByte; /* Bytes of runtime space required for sub-program */ - Mem *pRt; /* Register to allocate runtime space */ - Mem *pMem; /* Used to iterate through memory cells */ - Mem *pEnd; /* Last memory cell in new array */ - VdbeFrame *pFrame; /* New vdbe frame to execute in */ - SubProgram *pProgram; /* Sub-program to execute */ - void *t; /* Token identifying trigger */ - - pProgram = pOp->p4.pProgram; - pRt = &aMem[pOp->p3]; - assert( pProgram->nOp>0 ); - - /* If the p5 flag is clear, then recursive invocation of triggers is - ** disabled for backwards compatibility (p5 is set if this sub-program - ** is really a trigger, not a foreign key action, and the flag set - ** and cleared by the "PRAGMA recursive_triggers" command is clear). - ** - ** It is recursive invocation of triggers, at the SQL level, that is - ** disabled. In some cases a single trigger may generate more than one - ** SubProgram (if the trigger may be executed with more than one different - ** ON CONFLICT algorithm). SubProgram structures associated with a - ** single trigger all have the same value for the SubProgram.token - ** variable. */ - if( pOp->p5 ){ - t = pProgram->token; - for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); - if( pFrame ) break; - } - - if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ - rc = SQLITE_ERROR; - sqlite3VdbeError(p, "too many levels of trigger recursion"); - goto abort_due_to_error; - } - - /* Register pRt is used to store the memory required to save the state - ** of the current program, and the memory required at runtime to execute - ** the trigger program. If this trigger has been fired before, then pRt - ** is already allocated. Otherwise, it must be initialized. */ - if( (pRt->flags&MEM_Frame)==0 ){ - /* SubProgram.nMem is set to the number of memory cells used by the - ** program stored in SubProgram.aOp. As well as these, one memory - ** cell is required for each cursor used by the program. Set local - ** variable nMem (and later, VdbeFrame.nChildMem) to this value. - */ - nMem = pProgram->nMem + pProgram->nCsr; - assert( nMem>0 ); - if( pProgram->nCsr==0 ) nMem++; - nByte = ROUND8(sizeof(VdbeFrame)) - + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor *); - pFrame = sqlite3DbMallocZero(db, nByte); - if( !pFrame ){ - goto no_mem; - } - sqlite3VdbeMemRelease(pRt); - pRt->flags = MEM_Frame; - pRt->u.pFrame = pFrame; - - pFrame->v = p; - pFrame->nChildMem = nMem; - pFrame->nChildCsr = pProgram->nCsr; - pFrame->pc = (int)(pOp - aOp); - pFrame->aMem = p->aMem; - pFrame->nMem = p->nMem; - pFrame->apCsr = p->apCsr; - pFrame->nCursor = p->nCursor; - pFrame->aOp = p->aOp; - pFrame->nOp = p->nOp; - pFrame->token = pProgram->token; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pFrame->anExec = p->anExec; -#endif - - pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; - for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ - pMem->flags = MEM_Undefined; - pMem->db = db; - } - }else{ - pFrame = pRt->u.pFrame; - assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem - || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); - assert( pProgram->nCsr==pFrame->nChildCsr ); - assert( (int)(pOp - aOp)==pFrame->pc ); - } - - p->nFrame++; - pFrame->pParent = p->pFrame; - pFrame->lastRowid = lastRowid; - pFrame->nChange = p->nChange; - pFrame->nDbChange = p->db->nChange; - assert( pFrame->pAuxData==0 ); - pFrame->pAuxData = p->pAuxData; - p->pAuxData = 0; - p->nChange = 0; - p->pFrame = pFrame; - p->aMem = aMem = VdbeFrameMem(pFrame); - p->nMem = pFrame->nChildMem; - p->nCursor = (u16)pFrame->nChildCsr; - p->apCsr = (VdbeCursor **)&aMem[p->nMem]; - p->aOp = aOp = pProgram->aOp; - p->nOp = pProgram->nOp; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - p->anExec = 0; -#endif - pOp = &aOp[-1]; - - break; -} - -/* Opcode: Param P1 P2 * * * -** -** This opcode is only ever present in sub-programs called via the -** OP_Program instruction. Copy a value currently stored in a memory -** cell of the calling (parent) frame to cell P2 in the current frames -** address space. This is used by trigger programs to access the new.* -** and old.* values. -** -** The address of the cell in the parent frame is determined by adding -** the value of the P1 argument to the value of the P1 argument to the -** calling OP_Program instruction. -*/ -case OP_Param: { /* out2 */ - VdbeFrame *pFrame; - Mem *pIn; - pOut = out2Prerelease(p, pOp); - pFrame = p->pFrame; - pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; - sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); - break; -} - -#endif /* #ifndef SQLITE_OMIT_TRIGGER */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY -/* Opcode: FkCounter P1 P2 * * * -** Synopsis: fkctr[P1]+=P2 -** -** Increment a "constraint counter" by P2 (P2 may be negative or positive). -** If P1 is non-zero, the database constraint counter is incremented -** (deferred foreign key constraints). Otherwise, if P1 is zero, the -** statement counter is incremented (immediate foreign key constraints). -*/ -case OP_FkCounter: { - if( db->flags & SQLITE_DeferFKs ){ - db->nDeferredImmCons += pOp->p2; - }else if( pOp->p1 ){ - db->nDeferredCons += pOp->p2; - }else{ - p->nFkConstraint += pOp->p2; - } - break; -} - -/* Opcode: FkIfZero P1 P2 * * * -** Synopsis: if fkctr[P1]==0 goto P2 -** -** This opcode tests if a foreign key constraint-counter is currently zero. -** If so, jump to instruction P2. Otherwise, fall through to the next -** instruction. -** -** If P1 is non-zero, then the jump is taken if the database constraint-counter -** is zero (the one that counts deferred constraint violations). If P1 is -** zero, the jump is taken if the statement constraint-counter is zero -** (immediate foreign key constraint violations). -*/ -case OP_FkIfZero: { /* jump */ - if( pOp->p1 ){ - VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); - if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; - }else{ - VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); - if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; - } - break; -} -#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */ - -#ifndef SQLITE_OMIT_AUTOINCREMENT -/* Opcode: MemMax P1 P2 * * * -** Synopsis: r[P1]=max(r[P1],r[P2]) -** -** P1 is a register in the root frame of this VM (the root frame is -** different from the current frame if this instruction is being executed -** within a sub-program). Set the value of register P1 to the maximum of -** its current value and the value in register P2. -** -** This instruction throws an error if the memory cell is not initially -** an integer. -*/ -case OP_MemMax: { /* in2 */ - VdbeFrame *pFrame; - if( p->pFrame ){ - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - pIn1 = &pFrame->aMem[pOp->p1]; - }else{ - pIn1 = &aMem[pOp->p1]; - } - assert( memIsValid(pIn1) ); - sqlite3VdbeMemIntegerify(pIn1); - pIn2 = &aMem[pOp->p2]; - sqlite3VdbeMemIntegerify(pIn2); - if( pIn1->u.iu.i){ - pIn1->u.i = pIn2->u.i; - } - break; -} -#endif /* SQLITE_OMIT_AUTOINCREMENT */ - -/* Opcode: IfPos P1 P2 P3 * * -** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 -** -** Register P1 must contain an integer. -** If the value of register P1 is 1 or greater, subtract P3 from the -** value in P1 and jump to P2. -** -** If the initial value of register P1 is less than 1, then the -** value is unchanged and control passes through to the next instruction. -*/ -case OP_IfPos: { /* jump, in1 */ - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags&MEM_Int ); - VdbeBranchTaken( pIn1->u.i>0, 2); - if( pIn1->u.i>0 ){ - pIn1->u.i -= pOp->p3; - goto jump_to_p2; - } - break; -} - -/* Opcode: OffsetLimit P1 P2 P3 * * -** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) -** -** This opcode performs a commonly used computation associated with -** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] -** holds the offset counter. The opcode computes the combined value -** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] -** value computed is the total number of rows that will need to be -** visited in order to complete the query. -** -** If r[P3] is zero or negative, that means there is no OFFSET -** and r[P2] is set to be the value of the LIMIT, r[P1]. -** -** if r[P1] is zero or negative, that means there is no LIMIT -** and r[P2] is set to -1. -** -** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. -*/ -case OP_OffsetLimit: { /* in1, out2, in3 */ - pIn1 = &aMem[pOp->p1]; - pIn3 = &aMem[pOp->p3]; - pOut = out2Prerelease(p, pOp); - assert( pIn1->flags & MEM_Int ); - assert( pIn3->flags & MEM_Int ); - pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0); - break; -} - -/* Opcode: IfNotZero P1 P2 P3 * * -** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 -** -** Register P1 must contain an integer. If the content of register P1 is -** initially nonzero, then subtract P3 from the value in register P1 and -** jump to P2. If register P1 is initially zero, leave it unchanged -** and fall through. -*/ -case OP_IfNotZero: { /* jump, in1 */ - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags&MEM_Int ); - VdbeBranchTaken(pIn1->u.i<0, 2); - if( pIn1->u.i ){ - pIn1->u.i -= pOp->p3; - goto jump_to_p2; - } - break; -} - -/* Opcode: DecrJumpZero P1 P2 * * * -** Synopsis: if (--r[P1])==0 goto P2 -** -** Register P1 must hold an integer. Decrement the value in register P1 -** then jump to P2 if the new value is exactly zero. -*/ -case OP_DecrJumpZero: { /* jump, in1 */ - pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags&MEM_Int ); - pIn1->u.i--; - VdbeBranchTaken(pIn1->u.i==0, 2); - if( pIn1->u.i==0 ) goto jump_to_p2; - break; -} - - -/* Opcode: AggStep0 * P2 P3 P4 P5 -** Synopsis: accum=r[P3] step(r[P2@P5]) -** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to the FuncDef -** structure that specifies the function. Register P3 is the -** accumulator. -** -** The P5 arguments are taken from register P2 and its -** successors. -*/ -/* Opcode: AggStep * P2 P3 P4 P5 -** Synopsis: accum=r[P3] step(r[P2@P5]) -** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to an sqlite3_context -** object that is used to run the function. Register P3 is -** as the accumulator. -** -** The P5 arguments are taken from register P2 and its -** successors. -** -** This opcode is initially coded as OP_AggStep0. On first evaluation, -** the FuncDef stored in P4 is converted into an sqlite3_context and -** the opcode is changed. In this way, the initialization of the -** sqlite3_context only happens once, instead of on each call to the -** step function. -*/ -case OP_AggStep0: { - int n; - sqlite3_context *pCtx; - - assert( pOp->p4type==P4_FUNCDEF ); - n = pOp->p5; - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); - assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); - if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; - pCtx->pFunc = pOp->p4.pFunc; - pCtx->iOp = (int)(pOp - aOp); - pCtx->pVdbe = p; - pCtx->argc = n; - pOp->p4type = P4_FUNCCTX; - pOp->p4.pCtx = pCtx; - pOp->opcode = OP_AggStep; - /* Fall through into OP_AggStep */ -} -case OP_AggStep: { - int i; - sqlite3_context *pCtx; - Mem *pMem; - Mem t; - - assert( pOp->p4type==P4_FUNCCTX ); - pCtx = pOp->p4.pCtx; - pMem = &aMem[pOp->p3]; - - /* If this function is inside of a trigger, the register array in aMem[] - ** might change from one evaluation to the next. The next block of code - ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the sqlite3_context object */ - if( pCtx->pMem != pMem ){ - pCtx->pMem = pMem; - for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; - } - -#ifdef SQLITE_DEBUG - for(i=0; iargc; i++){ - assert( memIsValid(pCtx->argv[i]) ); - REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); - } -#endif - - pMem->n++; - sqlite3VdbeMemInit(&t, db, MEM_Null); - pCtx->pOut = &t; - pCtx->fErrorOrAux = 0; - pCtx->skipFlag = 0; - (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(&t)); - rc = pCtx->isError; - } - sqlite3VdbeMemRelease(&t); - if( rc ) goto abort_due_to_error; - }else{ - assert( t.flags==MEM_Null ); - } - if( pCtx->skipFlag ){ - assert( pOp[-1].opcode==OP_CollSeq ); - i = pOp[-1].p1; - if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); - } - break; -} - -/* Opcode: AggFinal P1 P2 * P4 * -** Synopsis: accum=r[P1] N=P2 -** -** Execute the finalizer function for an aggregate. P1 is -** the memory location that is the accumulator for the aggregate. -** -** P2 is the number of arguments that the step function takes and -** P4 is a pointer to the FuncDef for this function. The P2 -** argument is not used by this opcode. It is only there to disambiguate -** functions that can take varying numbers of arguments. The -** P4 argument is only needed for the degenerate case where -** the step function was not previously called. -*/ -case OP_AggFinal: { - Mem *pMem; - assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); - pMem = &aMem[pOp->p1]; - assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); - if( rc ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); - goto abort_due_to_error; - } - sqlite3VdbeChangeEncoding(pMem, encoding); - UPDATE_MAX_BLOBSIZE(pMem); - if( sqlite3VdbeMemTooBig(pMem) ){ - goto too_big; - } - break; -} - -#ifndef SQLITE_OMIT_WAL -/* Opcode: Checkpoint P1 P2 P3 * * -** -** Checkpoint database P1. This is a no-op if P1 is not currently in -** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, -** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns -** SQLITE_BUSY or not, respectively. Write the number of pages in the -** WAL after the checkpoint into mem[P3+1] and the number of pages -** in the WAL that have been checkpointed after the checkpoint -** completes into mem[P3+2]. However on an error, mem[P3+1] and -** mem[P3+2] are initialized to -1. -*/ -case OP_Checkpoint: { - int i; /* Loop counter */ - int aRes[3]; /* Results */ - Mem *pMem; /* Write results here */ - - assert( p->readOnly==0 ); - aRes[0] = 0; - aRes[1] = aRes[2] = -1; - assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE - || pOp->p2==SQLITE_CHECKPOINT_FULL - || pOp->p2==SQLITE_CHECKPOINT_RESTART - || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE - ); - rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); - if( rc ){ - if( rc!=SQLITE_BUSY ) goto abort_due_to_error; - rc = SQLITE_OK; - aRes[0] = 1; - } - for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ - sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); - } - break; -}; -#endif - -#ifndef SQLITE_OMIT_PRAGMA -/* Opcode: JournalMode P1 P2 P3 * * -** -** Change the journal mode of database P1 to P3. P3 must be one of the -** PAGER_JOURNALMODE_XXX values. If changing between the various rollback -** modes (delete, truncate, persist, off and memory), this is a simple -** operation. No IO is required. -** -** If changing into or out of WAL mode the procedure is more complicated. -** -** Write a string containing the final journal-mode to register P2. -*/ -case OP_JournalMode: { /* out2 */ - Btree *pBt; /* Btree to change journal mode of */ - Pager *pPager; /* Pager associated with pBt */ - int eNew; /* New journal mode */ - int eOld; /* The old journal mode */ -#ifndef SQLITE_OMIT_WAL - const char *zFilename; /* Name of database file for pPager */ -#endif - - pOut = out2Prerelease(p, pOp); - eNew = pOp->p3; - assert( eNew==PAGER_JOURNALMODE_DELETE - || eNew==PAGER_JOURNALMODE_TRUNCATE - || eNew==PAGER_JOURNALMODE_PERSIST - || eNew==PAGER_JOURNALMODE_OFF - || eNew==PAGER_JOURNALMODE_MEMORY - || eNew==PAGER_JOURNALMODE_WAL - || eNew==PAGER_JOURNALMODE_QUERY - ); - assert( pOp->p1>=0 && pOp->p1nDb ); - assert( p->readOnly==0 ); - - pBt = db->aDb[pOp->p1].pBt; - pPager = sqlite3BtreePager(pBt); - eOld = sqlite3PagerGetJournalMode(pPager); - if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; - if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; - -#ifndef SQLITE_OMIT_WAL - zFilename = sqlite3PagerFilename(pPager, 1); - - /* Do not allow a transition to journal_mode=WAL for a database - ** in temporary storage or if the VFS does not support shared memory - */ - if( eNew==PAGER_JOURNALMODE_WAL - && (sqlite3Strlen30(zFilename)==0 /* Temp file */ - || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ - ){ - eNew = eOld; - } - - if( (eNew!=eOld) - && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) - ){ - if( !db->autoCommit || db->nVdbeRead>1 ){ - rc = SQLITE_ERROR; - sqlite3VdbeError(p, - "cannot change %s wal mode from within a transaction", - (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") - ); - goto abort_due_to_error; - }else{ - - if( eOld==PAGER_JOURNALMODE_WAL ){ - /* If leaving WAL mode, close the log file. If successful, the call - ** to PagerCloseWal() checkpoints and deletes the write-ahead-log - ** file. An EXCLUSIVE lock may still be held on the database file - ** after a successful return. - */ - rc = sqlite3PagerCloseWal(pPager); - if( rc==SQLITE_OK ){ - sqlite3PagerSetJournalMode(pPager, eNew); - } - }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ - /* Cannot transition directly from MEMORY to WAL. Use mode OFF - ** as an intermediate */ - sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); - } - - /* Open a transaction on the database file. Regardless of the journal - ** mode, this transaction always uses a rollback journal. - */ - assert( sqlite3BtreeIsInTrans(pBt)==0 ); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); - } - } - } -#endif /* ifndef SQLITE_OMIT_WAL */ - - if( rc ) eNew = eOld; - eNew = sqlite3PagerSetJournalMode(pPager, eNew); - - pOut->flags = MEM_Str|MEM_Static|MEM_Term; - pOut->z = (char *)sqlite3JournalModename(eNew); - pOut->n = sqlite3Strlen30(pOut->z); - pOut->enc = SQLITE_UTF8; - sqlite3VdbeChangeEncoding(pOut, encoding); - if( rc ) goto abort_due_to_error; - break; -}; -#endif /* SQLITE_OMIT_PRAGMA */ - -#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) -/* Opcode: Vacuum P1 * * * * -** -** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more -** for an attached database. The "temp" database may not be vacuumed. -*/ -case OP_Vacuum: { - assert( p->readOnly==0 ); - rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1); - if( rc ) goto abort_due_to_error; - break; -} -#endif - -#if !defined(SQLITE_OMIT_AUTOVACUUM) -/* Opcode: IncrVacuum P1 P2 * * * -** -** Perform a single step of the incremental vacuum procedure on -** the P1 database. If the vacuum has finished, jump to instruction -** P2. Otherwise, fall through to the next instruction. -*/ -case OP_IncrVacuum: { /* jump */ - Btree *pBt; - - assert( pOp->p1>=0 && pOp->p1nDb ); - assert( DbMaskTest(p->btreeMask, pOp->p1) ); - assert( p->readOnly==0 ); - pBt = db->aDb[pOp->p1].pBt; - rc = sqlite3BtreeIncrVacuum(pBt); - VdbeBranchTaken(rc==SQLITE_DONE,2); - if( rc ){ - if( rc!=SQLITE_DONE ) goto abort_due_to_error; - rc = SQLITE_OK; - goto jump_to_p2; - } - break; -} -#endif - -/* Opcode: Expire P1 * * * * -** -** Cause precompiled statements to expire. When an expired statement -** is executed using sqlite3_step() it will either automatically -** reprepare itself (if it was originally created using sqlite3_prepare_v2()) -** or it will fail with SQLITE_SCHEMA. -** -** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, -** then only the currently executing statement is expired. -*/ -case OP_Expire: { - if( !pOp->p1 ){ - sqlite3ExpirePreparedStatements(db); - }else{ - p->expired = 1; - } - break; -} - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* Opcode: TableLock P1 P2 P3 P4 * -** Synopsis: iDb=P1 root=P2 write=P3 -** -** Obtain a lock on a particular table. This instruction is only used when -** the shared-cache feature is enabled. -** -** P1 is the index of the database in sqlite3.aDb[] of the database -** on which the lock is acquired. A readlock is obtained if P3==0 or -** a write lock if P3==1. -** -** P2 contains the root-page of the table to lock. -** -** P4 contains a pointer to the name of the table being locked. This is only -** used to generate an error message if the lock cannot be obtained. -*/ -case OP_TableLock: { - u8 isWriteLock = (u8)pOp->p3; - if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ - int p1 = pOp->p1; - assert( p1>=0 && p1nDb ); - assert( DbMaskTest(p->btreeMask, p1) ); - assert( isWriteLock==0 || isWriteLock==1 ); - rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); - if( rc ){ - if( (rc&0xFF)==SQLITE_LOCKED ){ - const char *z = pOp->p4.z; - sqlite3VdbeError(p, "database table is locked: %s", z); - } - goto abort_due_to_error; - } - } - break; -} -#endif /* SQLITE_OMIT_SHARED_CACHE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VBegin * * * P4 * -** -** P4 may be a pointer to an sqlite3_vtab structure. If so, call the -** xBegin method for that table. -** -** Also, whether or not P4 is set, check that this is not being called from -** within a callback to a virtual table xSync() method. If it is, the error -** code will be set to SQLITE_LOCKED. -*/ -case OP_VBegin: { - VTable *pVTab; - pVTab = pOp->p4.pVtab; - rc = sqlite3VtabBegin(db, pVTab); - if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); - if( rc ) goto abort_due_to_error; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VCreate P1 P2 * * * -** -** P2 is a register that holds the name of a virtual table in database -** P1. Call the xCreate method for that table. -*/ -case OP_VCreate: { - Mem sMem; /* For storing the record being decoded */ - const char *zTab; /* Name of the virtual table */ - - memset(&sMem, 0, sizeof(sMem)); - sMem.db = db; - /* Because P2 is always a static string, it is impossible for the - ** sqlite3VdbeMemCopy() to fail */ - assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); - assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); - rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); - assert( rc==SQLITE_OK ); - zTab = (const char*)sqlite3_value_text(&sMem); - assert( zTab || db->mallocFailed ); - if( zTab ){ - rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); - } - sqlite3VdbeMemRelease(&sMem); - if( rc ) goto abort_due_to_error; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VDestroy P1 * * P4 * -** -** P4 is the name of a virtual table in database P1. Call the xDestroy method -** of that table. -*/ -case OP_VDestroy: { - db->nVDestroy++; - rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); - db->nVDestroy--; - if( rc ) goto abort_due_to_error; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VOpen P1 * * P4 * -** -** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. -** P1 is a cursor number. This opcode opens a cursor to the virtual -** table and stores that cursor in P1. -*/ -case OP_VOpen: { - VdbeCursor *pCur; - sqlite3_vtab_cursor *pVCur; - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - - assert( p->bIsReader ); - pCur = 0; - pVCur = 0; - pVtab = pOp->p4.pVtab->pVtab; - if( pVtab==0 || NEVER(pVtab->pModule==0) ){ - rc = SQLITE_LOCKED; - goto abort_due_to_error; - } - pModule = pVtab->pModule; - rc = pModule->xOpen(pVtab, &pVCur); - sqlite3VtabImportErrmsg(p, pVtab); - if( rc ) goto abort_due_to_error; - - /* Initialize sqlite3_vtab_cursor base class */ - pVCur->pVtab = pVtab; - - /* Initialize vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB); - if( pCur ){ - pCur->uc.pVCur = pVCur; - pVtab->nRef++; - }else{ - assert( db->mallocFailed ); - pModule->xClose(pVCur); - goto no_mem; - } - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VFilter P1 P2 P3 P4 * -** Synopsis: iplan=r[P3] zplan='P4' -** -** P1 is a cursor opened using VOpen. P2 is an address to jump to if -** the filtered result set is empty. -** -** P4 is either NULL or a string that was generated by the xBestIndex -** method of the module. The interpretation of the P4 string is left -** to the module implementation. -** -** This opcode invokes the xFilter method on the virtual table specified -** by P1. The integer query plan parameter to xFilter is stored in register -** P3. Register P3+1 stores the argc parameter to be passed to the -** xFilter method. Registers P3+2..P3+1+argc are the argc -** additional parameters which are passed to -** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. -** -** A jump is made to P2 if the result set after filtering would be empty. -*/ -case OP_VFilter: { /* jump */ - int nArg; - int iQuery; - const sqlite3_module *pModule; - Mem *pQuery; - Mem *pArgc; - sqlite3_vtab_cursor *pVCur; - sqlite3_vtab *pVtab; - VdbeCursor *pCur; - int res; - int i; - Mem **apArg; - - pQuery = &aMem[pOp->p3]; - pArgc = &pQuery[1]; - pCur = p->apCsr[pOp->p1]; - assert( memIsValid(pQuery) ); - REGISTER_TRACE(pOp->p3, pQuery); - assert( pCur->eCurType==CURTYPE_VTAB ); - pVCur = pCur->uc.pVCur; - pVtab = pVCur->pVtab; - pModule = pVtab->pModule; - - /* Grab the index number and argc parameters */ - assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); - nArg = (int)pArgc->u.i; - iQuery = (int)pQuery->u.i; - - /* Invoke the xFilter method */ - res = 0; - apArg = p->apArg; - for(i = 0; ixFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg); - sqlite3VtabImportErrmsg(p, pVtab); - if( rc ) goto abort_due_to_error; - res = pModule->xEof(pVCur); - pCur->nullRow = 0; - VdbeBranchTaken(res!=0,2); - if( res ) goto jump_to_p2; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VColumn P1 P2 P3 * * -** Synopsis: r[P3]=vcolumn(P2) -** -** Store the value of the P2-th column of -** the row of the virtual-table that the -** P1 cursor is pointing to into register P3. -*/ -case OP_VColumn: { - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - Mem *pDest; - sqlite3_context sContext; - - VdbeCursor *pCur = p->apCsr[pOp->p1]; - assert( pCur->eCurType==CURTYPE_VTAB ); - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); - pDest = &aMem[pOp->p3]; - memAboutToChange(p, pDest); - if( pCur->nullRow ){ - sqlite3VdbeMemSetNull(pDest); - break; - } - pVtab = pCur->uc.pVCur->pVtab; - pModule = pVtab->pModule; - assert( pModule->xColumn ); - memset(&sContext, 0, sizeof(sContext)); - sContext.pOut = pDest; - MemSetTypeFlag(pDest, MEM_Null); - rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); - sqlite3VtabImportErrmsg(p, pVtab); - if( sContext.isError ){ - rc = sContext.isError; - } - sqlite3VdbeChangeEncoding(pDest, encoding); - REGISTER_TRACE(pOp->p3, pDest); - UPDATE_MAX_BLOBSIZE(pDest); - - if( sqlite3VdbeMemTooBig(pDest) ){ - goto too_big; - } - if( rc ) goto abort_due_to_error; - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VNext P1 P2 * * * -** -** Advance virtual table P1 to the next row in its result set and -** jump to instruction P2. Or, if the virtual table has reached -** the end of its result set, then fall through to the next instruction. -*/ -case OP_VNext: { /* jump */ - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - int res; - VdbeCursor *pCur; - - res = 0; - pCur = p->apCsr[pOp->p1]; - assert( pCur->eCurType==CURTYPE_VTAB ); - if( pCur->nullRow ){ - break; - } - pVtab = pCur->uc.pVCur->pVtab; - pModule = pVtab->pModule; - assert( pModule->xNext ); - - /* Invoke the xNext() method of the module. There is no way for the - ** underlying implementation to return an error if one occurs during - ** xNext(). Instead, if an error occurs, true is returned (indicating that - ** data is available) and the error code returned when xColumn or - ** some other method is next invoked on the save virtual table cursor. - */ - rc = pModule->xNext(pCur->uc.pVCur); - sqlite3VtabImportErrmsg(p, pVtab); - if( rc ) goto abort_due_to_error; - res = pModule->xEof(pCur->uc.pVCur); - VdbeBranchTaken(!res,2); - if( !res ){ - /* If there is data, jump to P2 */ - goto jump_to_p2_and_check_for_interrupt; - } - goto check_for_interrupt; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VRename P1 * * P4 * -** -** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. -** This opcode invokes the corresponding xRename method. The value -** in register P1 is passed as the zName argument to the xRename method. -*/ -case OP_VRename: { - sqlite3_vtab *pVtab; - Mem *pName; - - pVtab = pOp->p4.pVtab->pVtab; - pName = &aMem[pOp->p1]; - assert( pVtab->pModule->xRename ); - assert( memIsValid(pName) ); - assert( p->readOnly==0 ); - REGISTER_TRACE(pOp->p1, pName); - assert( pName->flags & MEM_Str ); - testcase( pName->enc==SQLITE_UTF8 ); - testcase( pName->enc==SQLITE_UTF16BE ); - testcase( pName->enc==SQLITE_UTF16LE ); - rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); - if( rc ) goto abort_due_to_error; - rc = pVtab->pModule->xRename(pVtab, pName->z); - sqlite3VtabImportErrmsg(p, pVtab); - p->expired = 0; - if( rc ) goto abort_due_to_error; - break; -} -#endif - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VUpdate P1 P2 P3 P4 P5 -** Synopsis: data=r[P3@P2] -** -** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. -** This opcode invokes the corresponding xUpdate method. P2 values -** are contiguous memory cells starting at P3 to pass to the xUpdate -** invocation. The value in register (P3+P2-1) corresponds to the -** p2th element of the argv array passed to xUpdate. -** -** The xUpdate method will do a DELETE or an INSERT or both. -** The argv[0] element (which corresponds to memory cell P3) -** is the rowid of a row to delete. If argv[0] is NULL then no -** deletion occurs. The argv[1] element is the rowid of the new -** row. This can be NULL to have the virtual table select the new -** rowid for itself. The subsequent elements in the array are -** the values of columns in the new row. -** -** If P2==1 then no insert is performed. argv[0] is the rowid of -** a row to delete. -** -** P1 is a boolean flag. If it is set to true and the xUpdate call -** is successful, then the value returned by sqlite3_last_insert_rowid() -** is set to the value of the rowid for the row just inserted. -** -** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to -** apply in the case of a constraint failure on an insert or update. -*/ -case OP_VUpdate: { - sqlite3_vtab *pVtab; - const sqlite3_module *pModule; - int nArg; - int i; - sqlite_int64 rowid; - Mem **apArg; - Mem *pX; - - assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback - || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace - ); - assert( p->readOnly==0 ); - pVtab = pOp->p4.pVtab->pVtab; - if( pVtab==0 || NEVER(pVtab->pModule==0) ){ - rc = SQLITE_LOCKED; - goto abort_due_to_error; - } - pModule = pVtab->pModule; - nArg = pOp->p2; - assert( pOp->p4type==P4_VTAB ); - if( ALWAYS(pModule->xUpdate) ){ - u8 vtabOnConflict = db->vtabOnConflict; - apArg = p->apArg; - pX = &aMem[pOp->p3]; - for(i=0; ivtabOnConflict = pOp->p5; - rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); - db->vtabOnConflict = vtabOnConflict; - sqlite3VtabImportErrmsg(p, pVtab); - if( rc==SQLITE_OK && pOp->p1 ){ - assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); - db->lastRowid = lastRowid = rowid; - } - if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ - if( pOp->p5==OE_Ignore ){ - rc = SQLITE_OK; - }else{ - p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); - } - }else{ - p->nChange++; - } - if( rc ) goto abort_due_to_error; - } - break; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* Opcode: Pagecount P1 P2 * * * -** -** Write the current number of pages in database P1 to memory cell P2. -*/ -case OP_Pagecount: { /* out2 */ - pOut = out2Prerelease(p, pOp); - pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); - break; -} -#endif - - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* Opcode: MaxPgcnt P1 P2 P3 * * -** -** Try to set the maximum page count for database P1 to the value in P3. -** Do not let the maximum page count fall below the current page count and -** do not change the maximum page count value if P3==0. -** -** Store the maximum page count after the change in register P2. -*/ -case OP_MaxPgcnt: { /* out2 */ - unsigned int newMax; - Btree *pBt; - - pOut = out2Prerelease(p, pOp); - pBt = db->aDb[pOp->p1].pBt; - newMax = 0; - if( pOp->p3 ){ - newMax = sqlite3BtreeLastPage(pBt); - if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; - } - pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); - break; -} -#endif - - -/* Opcode: Init P1 P2 * P4 * -** Synopsis: Start at P2 -** -** Programs contain a single instance of this opcode as the very first -** opcode. -** -** If tracing is enabled (by the sqlite3_trace()) interface, then -** the UTF-8 string contained in P4 is emitted on the trace callback. -** Or if P4 is blank, use the string returned by sqlite3_sql(). -** -** If P2 is not zero, jump to instruction P2. -** -** Increment the value of P1 so that OP_Once opcodes will jump the -** first time they are evaluated for this run. -*/ -case OP_Init: { /* jump */ - char *zTrace; - int i; - - /* If the P4 argument is not NULL, then it must be an SQL comment string. - ** The "--" string is broken up to prevent false-positives with srcck1.c. - ** - ** This assert() provides evidence for: - ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that - ** would have been returned by the legacy sqlite3_trace() interface by - ** using the X argument when X begins with "--" and invoking - ** sqlite3_expanded_sql(P) otherwise. - */ - assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); - assert( pOp==p->aOp ); /* Always instruction 0 */ - -#ifndef SQLITE_OMIT_TRACE - if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 - && !p->doingRerun - && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 - ){ -#ifndef SQLITE_OMIT_DEPRECATED - if( db->mTrace & SQLITE_TRACE_LEGACY ){ - void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace; - char *z = sqlite3VdbeExpandSql(p, zTrace); - x(db->pTraceArg, z); - sqlite3_free(z); - }else -#endif - { - (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); - } - } -#ifdef SQLITE_USE_FCNTL_TRACE - zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); - if( zTrace ){ - int j; - for(j=0; jnDb; j++){ - if( DbMaskTest(p->btreeMask, j)==0 ) continue; - sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); - } - } -#endif /* SQLITE_USE_FCNTL_TRACE */ -#ifdef SQLITE_DEBUG - if( (db->flags & SQLITE_SqlTrace)!=0 - && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 - ){ - sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); - } -#endif /* SQLITE_DEBUG */ -#endif /* SQLITE_OMIT_TRACE */ - assert( pOp->p2>0 ); - if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ - for(i=1; inOp; i++){ - if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; - } - pOp->p1 = 0; - } - pOp->p1++; - goto jump_to_p2; -} - -#ifdef SQLITE_ENABLE_CURSOR_HINTS -/* Opcode: CursorHint P1 * * P4 * -** -** Provide a hint to cursor P1 that it only needs to return rows that -** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer -** to values currently held in registers. TK_COLUMN terms in the P4 -** expression refer to columns in the b-tree to which cursor P1 is pointing. -*/ -case OP_CursorHint: { - VdbeCursor *pC; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p4type==P4_EXPR ); - pC = p->apCsr[pOp->p1]; - if( pC ){ - assert( pC->eCurType==CURTYPE_BTREE ); - sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, - pOp->p4.pExpr, aMem); - } - break; -} -#endif /* SQLITE_ENABLE_CURSOR_HINTS */ - -/* Opcode: Noop * * * * * -** -** Do nothing. This instruction is often useful as a jump -** destination. -*/ -/* -** The magic Explain opcode are only inserted when explain==2 (which -** is to say when the EXPLAIN QUERY PLAN syntax is used.) -** This opcode records information from the optimizer. It is the -** the same as a no-op. This opcodesnever appears in a real VM program. -*/ -default: { /* This is really OP_Noop and OP_Explain */ - assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); - break; -} - -/***************************************************************************** -** The cases of the switch statement above this line should all be indented -** by 6 spaces. But the left-most 6 spaces have been removed to improve the -** readability. From this point on down, the normal indentation rules are -** restored. -*****************************************************************************/ - } - -#ifdef VDBE_PROFILE - { - u64 endTime = sqlite3Hwtime(); - if( endTime>start ) pOrigOp->cycles += endTime - start; - pOrigOp->cnt++; - } -#endif - - /* The following code adds nothing to the actual functionality - ** of the program. It is only here for testing and debugging. - ** On the other hand, it does burn CPU cycles every time through - ** the evaluator loop. So we can leave it out when NDEBUG is defined. - */ -#ifndef NDEBUG - assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); - -#ifdef SQLITE_DEBUG - if( db->flags & SQLITE_VdbeTrace ){ - u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode]; - if( rc!=0 ) printf("rc=%d\n",rc); - if( opProperty & (OPFLG_OUT2) ){ - registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); - } - if( opProperty & OPFLG_OUT3 ){ - registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); - } - } -#endif /* SQLITE_DEBUG */ -#endif /* NDEBUG */ - } /* The end of the for(;;) loop the loops through opcodes */ - - /* If we reach this point, it means that execution is finished with - ** an error of some kind. - */ -abort_due_to_error: - if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT; - assert( rc ); - if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ - sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); - } - p->rc = rc; - sqlite3SystemError(db, rc); - testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(rc, "statement aborts at %d: [%s] %s", - (int)(pOp - aOp), p->zSql, p->zErrMsg); - sqlite3VdbeHalt(p); - if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); - rc = SQLITE_ERROR; - if( resetSchemaOnFault>0 ){ - sqlite3ResetOneSchema(db, resetSchemaOnFault-1); - } - - /* This is the only way out of this procedure. We have to - ** release the mutexes on btrees that were acquired at the - ** top. */ -vdbe_return: - db->lastRowid = lastRowid; - testcase( nVmStep>0 ); - p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - sqlite3VdbeLeave(p); - assert( rc!=SQLITE_OK || nExtraDelete==0 - || sqlite3_strlike("DELETE%",p->zSql,0)!=0 - ); - return rc; - - /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH - ** is encountered. - */ -too_big: - sqlite3VdbeError(p, "string or blob too big"); - rc = SQLITE_TOOBIG; - goto abort_due_to_error; - - /* Jump to here if a malloc() fails. - */ -no_mem: - sqlite3OomFault(db); - sqlite3VdbeError(p, "out of memory"); - rc = SQLITE_NOMEM_BKPT; - goto abort_due_to_error; - - /* Jump to here if the sqlite3_interrupt() API sets the interrupt - ** flag. - */ -abort_due_to_interrupt: - assert( db->u1.isInterrupted ); - rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; - p->rc = rc; - sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); - goto abort_due_to_error; -} - - -/************** End of vdbe.c ************************************************/ -/************** Begin file vdbeblob.c ****************************************/ -/* -** 2007 May 1 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code used to implement incremental BLOB I/O. -*/ - -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -#ifndef SQLITE_OMIT_INCRBLOB - -/* -** Valid sqlite3_blob* handles point to Incrblob structures. -*/ -typedef struct Incrblob Incrblob; -struct Incrblob { - int flags; /* Copy of "flags" passed to sqlite3_blob_open() */ - int nByte; /* Size of open blob, in bytes */ - int iOffset; /* Byte offset of blob in cursor data */ - int iCol; /* Table column this handle is open on */ - BtCursor *pCsr; /* Cursor pointing at blob row */ - sqlite3_stmt *pStmt; /* Statement holding cursor open */ - sqlite3 *db; /* The associated database */ - char *zDb; /* Database name */ - Table *pTab; /* Table object */ -}; - - -/* -** This function is used by both blob_open() and blob_reopen(). It seeks -** the b-tree cursor associated with blob handle p to point to row iRow. -** If successful, SQLITE_OK is returned and subsequent calls to -** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. -** -** If an error occurs, or if the specified row does not exist or does not -** contain a value of type TEXT or BLOB in the column nominated when the -** blob handle was opened, then an error code is returned and *pzErr may -** be set to point to a buffer containing an error message. It is the -** responsibility of the caller to free the error message buffer using -** sqlite3DbFree(). -** -** If an error does occur, then the b-tree cursor is closed. All subsequent -** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will -** immediately return SQLITE_ABORT. -*/ -static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ - int rc; /* Error code */ - char *zErr = 0; /* Error message */ - Vdbe *v = (Vdbe *)p->pStmt; - - /* Set the value of the SQL statements only variable to integer iRow. - ** This is done directly instead of using sqlite3_bind_int64() to avoid - ** triggering asserts related to mutexes. - */ - assert( v->aVar[0].flags&MEM_Int ); - v->aVar[0].u.i = iRow; - - rc = sqlite3_step(p->pStmt); - if( rc==SQLITE_ROW ){ - VdbeCursor *pC = v->apCsr[0]; - u32 type = pC->aType[p->iCol]; - if( type<12 ){ - zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", - type==0?"null": type==7?"real": "integer" - ); - rc = SQLITE_ERROR; - sqlite3_finalize(p->pStmt); - p->pStmt = 0; - }else{ - p->iOffset = pC->aType[p->iCol + pC->nField]; - p->nByte = sqlite3VdbeSerialTypeLen(type); - p->pCsr = pC->uc.pCursor; - sqlite3BtreeIncrblobCursor(p->pCsr); - } - } - - if( rc==SQLITE_ROW ){ - rc = SQLITE_OK; - }else if( p->pStmt ){ - rc = sqlite3_finalize(p->pStmt); - p->pStmt = 0; - if( rc==SQLITE_OK ){ - zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); - rc = SQLITE_ERROR; - }else{ - zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); - } - } - - assert( rc!=SQLITE_OK || zErr==0 ); - assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE ); - - *pzErr = zErr; - return rc; -} - -/* -** Open a blob handle. -*/ -SQLITE_API int sqlite3_blob_open( - sqlite3* db, /* The database connection */ - const char *zDb, /* The attached database containing the blob */ - const char *zTable, /* The table containing the blob */ - const char *zColumn, /* The column containing the blob */ - sqlite_int64 iRow, /* The row containing the glob */ - int flags, /* True -> read/write access, false -> read-only */ - sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ -){ - int nAttempt = 0; - int iCol; /* Index of zColumn in row-record */ - int rc = SQLITE_OK; - char *zErr = 0; - Table *pTab; - Parse *pParse = 0; - Incrblob *pBlob = 0; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( ppBlob==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - *ppBlob = 0; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - flags = !!flags; /* flags = (flags ? 1 : 0); */ - - sqlite3_mutex_enter(db->mutex); - - pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); - if( !pBlob ) goto blob_open_out; - pParse = sqlite3StackAllocRaw(db, sizeof(*pParse)); - if( !pParse ) goto blob_open_out; - - do { - memset(pParse, 0, sizeof(Parse)); - pParse->db = db; - sqlite3DbFree(db, zErr); - zErr = 0; - - sqlite3BtreeEnterAll(db); - pTab = sqlite3LocateTable(pParse, 0, zTable, zDb); - if( pTab && IsVirtual(pTab) ){ - pTab = 0; - sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); - } - if( pTab && !HasRowid(pTab) ){ - pTab = 0; - sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable); - } -#ifndef SQLITE_OMIT_VIEW - if( pTab && pTab->pSelect ){ - pTab = 0; - sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable); - } -#endif - if( !pTab ){ - if( pParse->zErrMsg ){ - sqlite3DbFree(db, zErr); - zErr = pParse->zErrMsg; - pParse->zErrMsg = 0; - } - rc = SQLITE_ERROR; - sqlite3BtreeLeaveAll(db); - goto blob_open_out; - } - pBlob->pTab = pTab; - pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; - - /* Now search pTab for the exact column. */ - for(iCol=0; iColnCol; iCol++) { - if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ - break; - } - } - if( iCol==pTab->nCol ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); - rc = SQLITE_ERROR; - sqlite3BtreeLeaveAll(db); - goto blob_open_out; - } - - /* If the value is being opened for writing, check that the - ** column is not indexed, and that it is not part of a foreign key. - ** It is against the rules to open a column to which either of these - ** descriptions applies for writing. */ - if( flags ){ - const char *zFault = 0; - Index *pIdx; -#ifndef SQLITE_OMIT_FOREIGN_KEY - if( db->flags&SQLITE_ForeignKeys ){ - /* Check that the column is not part of an FK child key definition. It - ** is not necessary to check if it is part of a parent key, as parent - ** key columns must be indexed. The check below will pick up this - ** case. */ - FKey *pFKey; - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ - int j; - for(j=0; jnCol; j++){ - if( pFKey->aCol[j].iFrom==iCol ){ - zFault = "foreign key"; - } - } - } - } -#endif - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int j; - for(j=0; jnKeyCol; j++){ - /* FIXME: Be smarter about indexes that use expressions */ - if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){ - zFault = "indexed"; - } - } - } - if( zFault ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); - rc = SQLITE_ERROR; - sqlite3BtreeLeaveAll(db); - goto blob_open_out; - } - } - - pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); - assert( pBlob->pStmt || db->mallocFailed ); - if( pBlob->pStmt ){ - - /* This VDBE program seeks a btree cursor to the identified - ** db/table/row entry. The reason for using a vdbe program instead - ** of writing code to use the b-tree layer directly is that the - ** vdbe program will take advantage of the various transaction, - ** locking and error handling infrastructure built into the vdbe. - ** - ** After seeking the cursor, the vdbe executes an OP_ResultRow. - ** Code external to the Vdbe then "borrows" the b-tree cursor and - ** uses it to implement the blob_read(), blob_write() and - ** blob_bytes() functions. - ** - ** The sqlite3_blob_close() function finalizes the vdbe program, - ** which closes the b-tree cursor and (possibly) commits the - ** transaction. - */ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList openBlob[] = { - {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ - {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ - {OP_Variable, 1, 1, 0}, /* 2: Move ?1 into reg[1] */ - {OP_NotExists, 0, 7, 1}, /* 3: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 4 */ - {OP_ResultRow, 1, 0, 0}, /* 5 */ - {OP_Goto, 0, 2, 0}, /* 6 */ - {OP_Close, 0, 0, 0}, /* 7 */ - {OP_Halt, 0, 0, 0}, /* 8 */ - }; - Vdbe *v = (Vdbe *)pBlob->pStmt; - int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - VdbeOp *aOp; - - sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, - pTab->pSchema->schema_cookie, - pTab->pSchema->iGeneration); - sqlite3VdbeChangeP5(v, 1); - aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); - - /* Make sure a mutex is held on the table to be accessed */ - sqlite3VdbeUsesBtree(v, iDb); - - if( db->mallocFailed==0 ){ - assert( aOp!=0 ); - /* Configure the OP_TableLock instruction */ -#ifdef SQLITE_OMIT_SHARED_CACHE - aOp[0].opcode = OP_Noop; -#else - aOp[0].p1 = iDb; - aOp[0].p2 = pTab->tnum; - aOp[0].p3 = flags; - sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); - } - if( db->mallocFailed==0 ){ -#endif - - /* Remove either the OP_OpenWrite or OpenRead. Set the P2 - ** parameter of the other to pTab->tnum. */ - if( flags ) aOp[1].opcode = OP_OpenWrite; - aOp[1].p2 = pTab->tnum; - aOp[1].p3 = iDb; - - /* Configure the number of columns. Configure the cursor to - ** think that the table has one more column than it really - ** does. An OP_Column to retrieve this imaginary column will - ** always return an SQL NULL. This is useful because it means - ** we can invoke OP_Column to fill in the vdbe cursors type - ** and offset cache without causing any IO. - */ - aOp[1].p4type = P4_INT32; - aOp[1].p4.i = pTab->nCol+1; - aOp[4].p2 = pTab->nCol; - - pParse->nVar = 1; - pParse->nMem = 1; - pParse->nTab = 1; - sqlite3VdbeMakeReady(v, pParse); - } - } - - pBlob->flags = flags; - pBlob->iCol = iCol; - pBlob->db = db; - sqlite3BtreeLeaveAll(db); - if( db->mallocFailed ){ - goto blob_open_out; - } - sqlite3_bind_int64(pBlob->pStmt, 1, iRow); - rc = blobSeekToRow(pBlob, iRow, &zErr); - } while( (++nAttempt)mallocFailed==0 ){ - *ppBlob = (sqlite3_blob *)pBlob; - }else{ - if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); - sqlite3DbFree(db, pBlob); - } - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); - sqlite3ParserReset(pParse); - sqlite3StackFree(db, pParse); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Close a blob handle that was previously created using -** sqlite3_blob_open(). -*/ -SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ - Incrblob *p = (Incrblob *)pBlob; - int rc; - sqlite3 *db; - - if( p ){ - db = p->db; - sqlite3_mutex_enter(db->mutex); - rc = sqlite3_finalize(p->pStmt); - sqlite3DbFree(db, p); - sqlite3_mutex_leave(db->mutex); - }else{ - rc = SQLITE_OK; - } - return rc; -} - -/* -** Perform a read or write operation on a blob -*/ -static int blobReadWrite( - sqlite3_blob *pBlob, - void *z, - int n, - int iOffset, - int (*xCall)(BtCursor*, u32, u32, void*) -){ - int rc; - Incrblob *p = (Incrblob *)pBlob; - Vdbe *v; - sqlite3 *db; - - if( p==0 ) return SQLITE_MISUSE_BKPT; - db = p->db; - sqlite3_mutex_enter(db->mutex); - v = (Vdbe*)p->pStmt; - - if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ - /* Request is out of range. Return a transient error. */ - rc = SQLITE_ERROR; - }else if( v==0 ){ - /* If there is no statement handle, then the blob-handle has - ** already been invalidated. Return SQLITE_ABORT in this case. - */ - rc = SQLITE_ABORT; - }else{ - /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is - ** returned, clean-up the statement handle. - */ - assert( db == v->db ); - sqlite3BtreeEnterCursor(p->pCsr); - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){ - /* If a pre-update hook is registered and this is a write cursor, - ** invoke it here. - ** - ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this - ** operation should really be an SQLITE_UPDATE. This is probably - ** incorrect, but is convenient because at this point the new.* values - ** are not easily obtainable. And for the sessions module, an - ** SQLITE_UPDATE where the PK columns do not change is handled in the - ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually - ** slightly more efficient). Since you cannot write to a PK column - ** using the incremental-blob API, this works. For the sessions module - ** anyhow. - */ - sqlite3_int64 iKey; - iKey = sqlite3BtreeIntegerKey(p->pCsr); - sqlite3VdbePreUpdateHook( - v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1 - ); - } -#endif - - rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); - sqlite3BtreeLeaveCursor(p->pCsr); - if( rc==SQLITE_ABORT ){ - sqlite3VdbeFinalize(v); - p->pStmt = 0; - }else{ - v->rc = rc; - } - } - sqlite3Error(db, rc); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Read data from a blob handle. -*/ -SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ - return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData); -} - -/* -** Write data to a blob handle. -*/ -SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ - return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); -} - -/* -** Query a blob handle for the size of the data. -** -** The Incrblob.nByte field is fixed for the lifetime of the Incrblob -** so no mutex is required for access. -*/ -SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ - Incrblob *p = (Incrblob *)pBlob; - return (p && p->pStmt) ? p->nByte : 0; -} - -/* -** Move an existing blob handle to point to a different row of the same -** database table. -** -** If an error occurs, or if the specified row does not exist or does not -** contain a blob or text value, then an error code is returned and the -** database handle error code and message set. If this happens, then all -** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) -** immediately return SQLITE_ABORT. -*/ -SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ - int rc; - Incrblob *p = (Incrblob *)pBlob; - sqlite3 *db; - - if( p==0 ) return SQLITE_MISUSE_BKPT; - db = p->db; - sqlite3_mutex_enter(db->mutex); - - if( p->pStmt==0 ){ - /* If there is no statement handle, then the blob-handle has - ** already been invalidated. Return SQLITE_ABORT in this case. - */ - rc = SQLITE_ABORT; - }else{ - char *zErr; - rc = blobSeekToRow(p, iRow, &zErr); - if( rc!=SQLITE_OK ){ - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); - } - assert( rc!=SQLITE_SCHEMA ); - } - - rc = sqlite3ApiExit(db, rc); - assert( rc==SQLITE_OK || p->pStmt==0 ); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#endif /* #ifndef SQLITE_OMIT_INCRBLOB */ - -/************** End of vdbeblob.c ********************************************/ -/************** Begin file vdbesort.c ****************************************/ -/* -** 2011-07-09 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code for the VdbeSorter object, used in concert with -** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements -** or by SELECT statements with ORDER BY clauses that cannot be satisfied -** using indexes and without LIMIT clauses. -** -** The VdbeSorter object implements a multi-threaded external merge sort -** algorithm that is efficient even if the number of elements being sorted -** exceeds the available memory. -** -** Here is the (internal, non-API) interface between this module and the -** rest of the SQLite system: -** -** sqlite3VdbeSorterInit() Create a new VdbeSorter object. -** -** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter -** object. The row is a binary blob in the -** OP_MakeRecord format that contains both -** the ORDER BY key columns and result columns -** in the case of a SELECT w/ ORDER BY, or -** the complete record for an index entry -** in the case of a CREATE INDEX. -** -** sqlite3VdbeSorterRewind() Sort all content previously added. -** Position the read cursor on the -** first sorted element. -** -** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted -** element. -** -** sqlite3VdbeSorterRowkey() Return the complete binary blob for the -** row currently under the read cursor. -** -** sqlite3VdbeSorterCompare() Compare the binary blob for the row -** currently under the read cursor against -** another binary blob X and report if -** X is strictly less than the read cursor. -** Used to enforce uniqueness in a -** CREATE UNIQUE INDEX statement. -** -** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim -** all resources. -** -** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This -** is like Close() followed by Init() only -** much faster. -** -** The interfaces above must be called in a particular order. Write() can -** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and -** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. -** -** Init() -** for each record: Write() -** Rewind() -** Rowkey()/Compare() -** Next() -** Close() -** -** Algorithm: -** -** Records passed to the sorter via calls to Write() are initially held -** unsorted in main memory. Assuming the amount of memory used never exceeds -** a threshold, when Rewind() is called the set of records is sorted using -** an in-memory merge sort. In this case, no temporary files are required -** and subsequent calls to Rowkey(), Next() and Compare() read records -** directly from main memory. -** -** If the amount of space used to store records in main memory exceeds the -** threshold, then the set of records currently in memory are sorted and -** written to a temporary file in "Packed Memory Array" (PMA) format. -** A PMA created at this point is known as a "level-0 PMA". Higher levels -** of PMAs may be created by merging existing PMAs together - for example -** merging two or more level-0 PMAs together creates a level-1 PMA. -** -** The threshold for the amount of main memory to use before flushing -** records to a PMA is roughly the same as the limit configured for the -** page-cache of the main database. Specifically, the threshold is set to -** the value returned by "PRAGMA main.page_size" multipled by -** that returned by "PRAGMA main.cache_size", in bytes. -** -** If the sorter is running in single-threaded mode, then all PMAs generated -** are appended to a single temporary file. Or, if the sorter is running in -** multi-threaded mode then up to (N+1) temporary files may be opened, where -** N is the configured number of worker threads. In this case, instead of -** sorting the records and writing the PMA to a temporary file itself, the -** calling thread usually launches a worker thread to do so. Except, if -** there are already N worker threads running, the main thread does the work -** itself. -** -** The sorter is running in multi-threaded mode if (a) the library was built -** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater -** than zero, and (b) worker threads have been enabled at runtime by calling -** "PRAGMA threads=N" with some value of N greater than 0. -** -** When Rewind() is called, any data remaining in memory is flushed to a -** final PMA. So at this point the data is stored in some number of sorted -** PMAs within temporary files on disk. -** -** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the -** sorter is running in single-threaded mode, then these PMAs are merged -** incrementally as keys are retreived from the sorter by the VDBE. The -** MergeEngine object, described in further detail below, performs this -** merge. -** -** Or, if running in multi-threaded mode, then a background thread is -** launched to merge the existing PMAs. Once the background thread has -** merged T bytes of data into a single sorted PMA, the main thread -** begins reading keys from that PMA while the background thread proceeds -** with merging the next T bytes of data. And so on. -** -** Parameter T is set to half the value of the memory threshold used -** by Write() above to determine when to create a new PMA. -** -** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when -** Rewind() is called, then a hierarchy of incremental-merges is used. -** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on -** disk are merged together. Then T bytes of data from the second set, and -** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT -** PMAs at a time. This done is to improve locality. -** -** If running in multi-threaded mode and there are more than -** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more -** than one background thread may be created. Specifically, there may be -** one background thread for each temporary file on disk, and one background -** thread to merge the output of each of the others to a single PMA for -** the main thread to read from. -*/ -/* #include "sqliteInt.h" */ -/* #include "vdbeInt.h" */ - -/* -** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various -** messages to stderr that may be helpful in understanding the performance -** characteristics of the sorter in multi-threaded mode. -*/ -#if 0 -# define SQLITE_DEBUG_SORTER_THREADS 1 -#endif - -/* -** Hard-coded maximum amount of data to accumulate in memory before flushing -** to a level 0 PMA. The purpose of this limit is to prevent various integer -** overflows. 512MiB. -*/ -#define SQLITE_MAX_PMASZ (1<<29) - -/* -** Private objects used by the sorter -*/ -typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ -typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ -typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ -typedef struct SorterRecord SorterRecord; /* A record being sorted */ -typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ -typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ -typedef struct SorterList SorterList; /* In-memory list of records */ -typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ - -/* -** A container for a temp file handle and the current amount of data -** stored in the file. -*/ -struct SorterFile { - sqlite3_file *pFd; /* File handle */ - i64 iEof; /* Bytes of data stored in pFd */ -}; - -/* -** An in-memory list of objects to be sorted. -** -** If aMemory==0 then each object is allocated separately and the objects -** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects -** are stored in the aMemory[] bulk memory, one right after the other, and -** are connected using SorterRecord.u.iNext. -*/ -struct SorterList { - SorterRecord *pList; /* Linked list of records */ - u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ - int szPMA; /* Size of pList as PMA in bytes */ -}; - -/* -** The MergeEngine object is used to combine two or more smaller PMAs into -** one big PMA using a merge operation. Separate PMAs all need to be -** combined into one big PMA in order to be able to step through the sorted -** records in order. -** -** The aReadr[] array contains a PmaReader object for each of the PMAs being -** merged. An aReadr[] object either points to a valid key or else is at EOF. -** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.) -** For the purposes of the paragraphs below, we assume that the array is -** actually N elements in size, where N is the smallest power of 2 greater -** to or equal to the number of PMAs being merged. The extra aReadr[] elements -** are treated as if they are empty (always at EOF). -** -** The aTree[] array is also N elements in size. The value of N is stored in -** the MergeEngine.nTree variable. -** -** The final (N/2) elements of aTree[] contain the results of comparing -** pairs of PMA keys together. Element i contains the result of -** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the -** aTree element is set to the index of it. -** -** For the purposes of this comparison, EOF is considered greater than any -** other key value. If the keys are equal (only possible with two EOF -** values), it doesn't matter which index is stored. -** -** The (N/4) elements of aTree[] that precede the final (N/2) described -** above contains the index of the smallest of each block of 4 PmaReaders -** And so on. So that aTree[1] contains the index of the PmaReader that -** currently points to the smallest key value. aTree[0] is unused. -** -** Example: -** -** aReadr[0] -> Banana -** aReadr[1] -> Feijoa -** aReadr[2] -> Elderberry -** aReadr[3] -> Currant -** aReadr[4] -> Grapefruit -** aReadr[5] -> Apple -** aReadr[6] -> Durian -** aReadr[7] -> EOF -** -** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } -** -** The current element is "Apple" (the value of the key indicated by -** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will -** be advanced to the next key in its segment. Say the next key is -** "Eggplant": -** -** aReadr[5] -> Eggplant -** -** The contents of aTree[] are updated first by comparing the new PmaReader -** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader -** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. -** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader -** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Bananafile2. And instead of using a -** background thread to prepare data for the PmaReader, with a single -** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with -** keys from pMerger by the calling thread whenever the PmaReader runs out -** of data. -*/ -struct IncrMerger { - SortSubtask *pTask; /* Task that owns this merger */ - MergeEngine *pMerger; /* Merge engine thread reads data from */ - i64 iStartOff; /* Offset to start writing file at */ - int mxSz; /* Maximum bytes of data to store */ - int bEof; /* Set to true when merge is finished */ - int bUseThread; /* True to use a bg thread for this object */ - SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */ -}; - -/* -** An instance of this object is used for writing a PMA. -** -** The PMA is written one record at a time. Each record is of an arbitrary -** size. But I/O is more efficient if it occurs in page-sized blocks where -** each block is aligned on a page boundary. This object caches writes to -** the PMA so that aligned, page-size blocks are written. -*/ -struct PmaWriter { - int eFWErr; /* Non-zero if in an error state */ - u8 *aBuffer; /* Pointer to write buffer */ - int nBuffer; /* Size of write buffer in bytes */ - int iBufStart; /* First byte of buffer to write */ - int iBufEnd; /* Last byte of buffer to write */ - i64 iWriteOff; /* Offset of start of buffer in file */ - sqlite3_file *pFd; /* File handle to write to */ -}; - -/* -** This object is the header on a single record while that record is being -** held in memory and prior to being written out as part of a PMA. -** -** How the linked list is connected depends on how memory is being managed -** by this module. If using a separate allocation for each in-memory record -** (VdbeSorter.list.aMemory==0), then the list is always connected using the -** SorterRecord.u.pNext pointers. -** -** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), -** then while records are being accumulated the list is linked using the -** SorterRecord.u.iNext offset. This is because the aMemory[] array may -** be sqlite3Realloc()ed while records are being accumulated. Once the VM -** has finished passing records to the sorter, or when the in-memory buffer -** is full, the list is sorted. As part of the sorting process, it is -** converted to use the SorterRecord.u.pNext pointers. See function -** vdbeSorterSort() for details. -*/ -struct SorterRecord { - int nVal; /* Size of the record in bytes */ - union { - SorterRecord *pNext; /* Pointer to next record in list */ - int iNext; /* Offset within aMemory of next record */ - } u; - /* The data for the record immediately follows this header */ -}; - -/* Return a pointer to the buffer containing the record data for SorterRecord -** object p. Should be used as if: -** -** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } -*/ -#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) - - -/* Maximum number of PMAs that a single MergeEngine can merge */ -#define SORTER_MAX_MERGE_COUNT 16 - -static int vdbeIncrSwap(IncrMerger*); -static void vdbeIncrFree(IncrMerger *); - -/* -** Free all memory belonging to the PmaReader object passed as the -** argument. All structure fields are set to zero before returning. -*/ -static void vdbePmaReaderClear(PmaReader *pReadr){ - sqlite3_free(pReadr->aAlloc); - sqlite3_free(pReadr->aBuffer); - if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); - vdbeIncrFree(pReadr->pIncr); - memset(pReadr, 0, sizeof(PmaReader)); -} - -/* -** Read the next nByte bytes of data from the PMA p. -** If successful, set *ppOut to point to a buffer containing the data -** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite -** error code. -** -** The buffer returned in *ppOut is only valid until the -** next call to this function. -*/ -static int vdbePmaReadBlob( - PmaReader *p, /* PmaReader from which to take the blob */ - int nByte, /* Bytes of data to read */ - u8 **ppOut /* OUT: Pointer to buffer containing data */ -){ - int iBuf; /* Offset within buffer to read from */ - int nAvail; /* Bytes of data available in buffer */ - - if( p->aMap ){ - *ppOut = &p->aMap[p->iReadOff]; - p->iReadOff += nByte; - return SQLITE_OK; - } - - assert( p->aBuffer ); - - /* If there is no more data to be read from the buffer, read the next - ** p->nBuffer bytes of data from the file into it. Or, if there are less - ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ - iBuf = p->iReadOff % p->nBuffer; - if( iBuf==0 ){ - int nRead; /* Bytes to read from disk */ - int rc; /* sqlite3OsRead() return code */ - - /* Determine how many bytes of data to read. */ - if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ - nRead = p->nBuffer; - }else{ - nRead = (int)(p->iEof - p->iReadOff); - } - assert( nRead>0 ); - - /* Readr data from the file. Return early if an error occurs. */ - rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); - assert( rc!=SQLITE_IOERR_SHORT_READ ); - if( rc!=SQLITE_OK ) return rc; - } - nAvail = p->nBuffer - iBuf; - - if( nByte<=nAvail ){ - /* The requested data is available in the in-memory buffer. In this - ** case there is no need to make a copy of the data, just return a - ** pointer into the buffer to the caller. */ - *ppOut = &p->aBuffer[iBuf]; - p->iReadOff += nByte; - }else{ - /* The requested data is not all available in the in-memory buffer. - ** In this case, allocate space at p->aAlloc[] to copy the requested - ** range into. Then return a copy of pointer p->aAlloc to the caller. */ - int nRem; /* Bytes remaining to copy */ - - /* Extend the p->aAlloc[] allocation if required. */ - if( p->nAllocnAlloc*2); - while( nByte>nNew ) nNew = nNew*2; - aNew = sqlite3Realloc(p->aAlloc, nNew); - if( !aNew ) return SQLITE_NOMEM_BKPT; - p->nAlloc = nNew; - p->aAlloc = aNew; - } - - /* Copy as much data as is available in the buffer into the start of - ** p->aAlloc[]. */ - memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); - p->iReadOff += nAvail; - nRem = nByte - nAvail; - - /* The following loop copies up to p->nBuffer bytes per iteration into - ** the p->aAlloc[] buffer. */ - while( nRem>0 ){ - int rc; /* vdbePmaReadBlob() return code */ - int nCopy; /* Number of bytes to copy */ - u8 *aNext; /* Pointer to buffer to copy data from */ - - nCopy = nRem; - if( nRem>p->nBuffer ) nCopy = p->nBuffer; - rc = vdbePmaReadBlob(p, nCopy, &aNext); - if( rc!=SQLITE_OK ) return rc; - assert( aNext!=p->aAlloc ); - memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); - nRem -= nCopy; - } - - *ppOut = p->aAlloc; - } - - return SQLITE_OK; -} - -/* -** Read a varint from the stream of data accessed by p. Set *pnOut to -** the value read. -*/ -static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ - int iBuf; - - if( p->aMap ){ - p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); - }else{ - iBuf = p->iReadOff % p->nBuffer; - if( iBuf && (p->nBuffer-iBuf)>=9 ){ - p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); - }else{ - u8 aVarint[16], *a; - int i = 0, rc; - do{ - rc = vdbePmaReadBlob(p, 1, &a); - if( rc ) return rc; - aVarint[(i++)&0xf] = a[0]; - }while( (a[0]&0x80)!=0 ); - sqlite3GetVarint(aVarint, pnOut); - } - } - - return SQLITE_OK; -} - -/* -** Attempt to memory map file pFile. If successful, set *pp to point to the -** new mapping and return SQLITE_OK. If the mapping is not attempted -** (because the file is too large or the VFS layer is configured not to use -** mmap), return SQLITE_OK and set *pp to NULL. -** -** Or, if an error occurs, return an SQLite error code. The final value of -** *pp is undefined in this case. -*/ -static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ - int rc = SQLITE_OK; - if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ - sqlite3_file *pFd = pFile->pFd; - if( pFd->pMethods->iVersion>=3 ){ - rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); - testcase( rc!=SQLITE_OK ); - } - } - return rc; -} - -/* -** Attach PmaReader pReadr to file pFile (if it is not already attached to -** that file) and seek it to offset iOff within the file. Return SQLITE_OK -** if successful, or an SQLite error code if an error occurs. -*/ -static int vdbePmaReaderSeek( - SortSubtask *pTask, /* Task context */ - PmaReader *pReadr, /* Reader whose cursor is to be moved */ - SorterFile *pFile, /* Sorter file to read from */ - i64 iOff /* Offset in pFile */ -){ - int rc = SQLITE_OK; - - assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); - - if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; - if( pReadr->aMap ){ - sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); - pReadr->aMap = 0; - } - pReadr->iReadOff = iOff; - pReadr->iEof = pFile->iEof; - pReadr->pFd = pFile->pFd; - - rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap); - if( rc==SQLITE_OK && pReadr->aMap==0 ){ - int pgsz = pTask->pSorter->pgsz; - int iBuf = pReadr->iReadOff % pgsz; - if( pReadr->aBuffer==0 ){ - pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); - if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT; - pReadr->nBuffer = pgsz; - } - if( rc==SQLITE_OK && iBuf ){ - int nRead = pgsz - iBuf; - if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ - nRead = (int)(pReadr->iEof - pReadr->iReadOff); - } - rc = sqlite3OsRead( - pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff - ); - testcase( rc!=SQLITE_OK ); - } - } - - return rc; -} - -/* -** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if -** no error occurs, or an SQLite error code if one does. -*/ -static int vdbePmaReaderNext(PmaReader *pReadr){ - int rc = SQLITE_OK; /* Return Code */ - u64 nRec = 0; /* Size of record in bytes */ - - - if( pReadr->iReadOff>=pReadr->iEof ){ - IncrMerger *pIncr = pReadr->pIncr; - int bEof = 1; - if( pIncr ){ - rc = vdbeIncrSwap(pIncr); - if( rc==SQLITE_OK && pIncr->bEof==0 ){ - rc = vdbePmaReaderSeek( - pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff - ); - bEof = 0; - } - } - - if( bEof ){ - /* This is an EOF condition */ - vdbePmaReaderClear(pReadr); - testcase( rc!=SQLITE_OK ); - return rc; - } - } - - if( rc==SQLITE_OK ){ - rc = vdbePmaReadVarint(pReadr, &nRec); - } - if( rc==SQLITE_OK ){ - pReadr->nKey = (int)nRec; - rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey); - testcase( rc!=SQLITE_OK ); - } - - return rc; -} - -/* -** Initialize PmaReader pReadr to scan through the PMA stored in file pFile -** starting at offset iStart and ending at offset iEof-1. This function -** leaves the PmaReader pointing to the first key in the PMA (or EOF if the -** PMA is empty). -** -** If the pnByte parameter is NULL, then it is assumed that the file -** contains a single PMA, and that that PMA omits the initial length varint. -*/ -static int vdbePmaReaderInit( - SortSubtask *pTask, /* Task context */ - SorterFile *pFile, /* Sorter file to read from */ - i64 iStart, /* Start offset in pFile */ - PmaReader *pReadr, /* PmaReader to populate */ - i64 *pnByte /* IN/OUT: Increment this value by PMA size */ -){ - int rc; - - assert( pFile->iEof>iStart ); - assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 ); - assert( pReadr->aBuffer==0 ); - assert( pReadr->aMap==0 ); - - rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart); - if( rc==SQLITE_OK ){ - u64 nByte = 0; /* Size of PMA in bytes */ - rc = vdbePmaReadVarint(pReadr, &nByte); - pReadr->iEof = pReadr->iReadOff + nByte; - *pnByte += nByte; - } - - if( rc==SQLITE_OK ){ - rc = vdbePmaReaderNext(pReadr); - } - return rc; -} - -/* -** A version of vdbeSorterCompare() that assumes that it has already been -** determined that the first field of key1 is equal to the first field of -** key2. -*/ -static int vdbeSorterCompareTail( - SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ - int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ - const void *pKey1, int nKey1, /* Left side of comparison */ - const void *pKey2, int nKey2 /* Right side of comparison */ -){ - UnpackedRecord *r2 = pTask->pUnpacked; - if( *pbKey2Cached==0 ){ - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); - *pbKey2Cached = 1; - } - return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); -} - -/* -** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, -** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences -** used by the comparison. Return the result of the comparison. -** -** If IN/OUT parameter *pbKey2Cached is true when this function is called, -** it is assumed that (pTask->pUnpacked) contains the unpacked version -** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked -** version of key2 and *pbKey2Cached set to true before returning. -** -** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set -** to SQLITE_NOMEM. -*/ -static int vdbeSorterCompare( - SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ - int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ - const void *pKey1, int nKey1, /* Left side of comparison */ - const void *pKey2, int nKey2 /* Right side of comparison */ -){ - UnpackedRecord *r2 = pTask->pUnpacked; - if( !*pbKey2Cached ){ - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); - *pbKey2Cached = 1; - } - return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); -} - -/* -** A specially optimized version of vdbeSorterCompare() that assumes that -** the first field of each key is a TEXT value and that the collation -** sequence to compare them with is BINARY. -*/ -static int vdbeSorterCompareText( - SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ - int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ - const void *pKey1, int nKey1, /* Left side of comparison */ - const void *pKey2, int nKey2 /* Right side of comparison */ -){ - const u8 * const p1 = (const u8 * const)pKey1; - const u8 * const p2 = (const u8 * const)pKey2; - const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ - const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ - - int n1; - int n2; - int res; - - getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2; - getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2; - res = memcmp(v1, v2, MIN(n1, n2)); - if( res==0 ){ - res = n1 - n2; - } - - if( res==0 ){ - if( pTask->pSorter->pKeyInfo->nField>1 ){ - res = vdbeSorterCompareTail( - pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 - ); - } - }else{ - if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ - res = res * -1; - } - } - - return res; -} - -/* -** A specially optimized version of vdbeSorterCompare() that assumes that -** the first field of each key is an INTEGER value. -*/ -static int vdbeSorterCompareInt( - SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ - int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ - const void *pKey1, int nKey1, /* Left side of comparison */ - const void *pKey2, int nKey2 /* Right side of comparison */ -){ - const u8 * const p1 = (const u8 * const)pKey1; - const u8 * const p2 = (const u8 * const)pKey2; - const int s1 = p1[1]; /* Left hand serial type */ - const int s2 = p2[1]; /* Right hand serial type */ - const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ - const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ - int res; /* Return value */ - - assert( (s1>0 && s1<7) || s1==8 || s1==9 ); - assert( (s2>0 && s2<7) || s2==8 || s2==9 ); - - if( s1>7 && s2>7 ){ - res = s1 - s2; - }else{ - if( s1==s2 ){ - if( (*v1 ^ *v2) & 0x80 ){ - /* The two values have different signs */ - res = (*v1 & 0x80) ? -1 : +1; - }else{ - /* The two values have the same sign. Compare using memcmp(). */ - static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 }; - int i; - res = 0; - for(i=0; i7 ){ - res = +1; - }else if( s1>7 ){ - res = -1; - }else{ - res = s1 - s2; - } - assert( res!=0 ); - - if( res>0 ){ - if( *v1 & 0x80 ) res = -1; - }else{ - if( *v2 & 0x80 ) res = +1; - } - } - } - - if( res==0 ){ - if( pTask->pSorter->pKeyInfo->nField>1 ){ - res = vdbeSorterCompareTail( - pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 - ); - } - }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ - res = res * -1; - } - - return res; -} - -/* -** Initialize the temporary index cursor just opened as a sorter cursor. -** -** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField) -** to determine the number of fields that should be compared from the -** records being sorted. However, if the value passed as argument nField -** is non-zero and the sorter is able to guarantee a stable sort, nField -** is used instead. This is used when sorting records for a CREATE INDEX -** statement. In this case, keys are always delivered to the sorter in -** order of the primary key, which happens to be make up the final part -** of the records being sorted. So if the sort is stable, there is never -** any reason to compare PK fields and they can be ignored for a small -** performance boost. -** -** The sorter can guarantee a stable sort when running in single-threaded -** mode, but not in multi-threaded mode. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterInit( - sqlite3 *db, /* Database connection (for malloc()) */ - int nField, /* Number of key fields in each record */ - VdbeCursor *pCsr /* Cursor that holds the new sorter */ -){ - int pgsz; /* Page size of main database */ - int i; /* Used to iterate through aTask[] */ - VdbeSorter *pSorter; /* The new sorter */ - KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ - int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ - int sz; /* Size of pSorter in bytes */ - int rc = SQLITE_OK; -#if SQLITE_MAX_WORKER_THREADS==0 -# define nWorker 0 -#else - int nWorker; -#endif - - /* Initialize the upper limit on the number of worker threads */ -#if SQLITE_MAX_WORKER_THREADS>0 - if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ - nWorker = 0; - }else{ - nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; - } -#endif - - /* Do not allow the total number of threads (main thread + all workers) - ** to exceed the maximum merge count */ -#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT - if( nWorker>=SORTER_MAX_MERGE_COUNT ){ - nWorker = SORTER_MAX_MERGE_COUNT-1; - } -#endif - - assert( pCsr->pKeyInfo && pCsr->pBt==0 ); - assert( pCsr->eCurType==CURTYPE_SORTER ); - szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*); - sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); - - pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); - pCsr->uc.pSorter = pSorter; - if( pSorter==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); - memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); - pKeyInfo->db = 0; - if( nField && nWorker==0 ){ - pKeyInfo->nXField += (pKeyInfo->nField - nField); - pKeyInfo->nField = nField; - } - pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); - pSorter->nTask = nWorker + 1; - pSorter->iPrev = (u8)(nWorker - 1); - pSorter->bUseThreads = (pSorter->nTask>1); - pSorter->db = db; - for(i=0; inTask; i++){ - SortSubtask *pTask = &pSorter->aTask[i]; - pTask->pSorter = pSorter; - } - - if( !sqlite3TempInMemory(db) ){ - i64 mxCache; /* Cache size in bytes*/ - u32 szPma = sqlite3GlobalConfig.szPma; - pSorter->mnPmaSize = szPma * pgsz; - - mxCache = db->aDb[0].pSchema->cache_size; - if( mxCache<0 ){ - /* A negative cache-size value C indicates that the cache is abs(C) - ** KiB in size. */ - mxCache = mxCache * -1024; - }else{ - mxCache = mxCache * pgsz; - } - mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); - pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); - - /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of - ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary - ** large heap allocations. - */ - if( sqlite3GlobalConfig.pScratch==0 ){ - assert( pSorter->iMemory==0 ); - pSorter->nMemory = pgsz; - pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); - if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; - } - } - - if( (pKeyInfo->nField+pKeyInfo->nXField)<13 - && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) - ){ - pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; - } - } - - return rc; -} -#undef nWorker /* Defined at the top of this function */ - -/* -** Free the list of sorted records starting at pRecord. -*/ -static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ - SorterRecord *p; - SorterRecord *pNext; - for(p=pRecord; p; p=pNext){ - pNext = p->u.pNext; - sqlite3DbFree(db, p); - } -} - -/* -** Free all resources owned by the object indicated by argument pTask. All -** fields of *pTask are zeroed before returning. -*/ -static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ - sqlite3DbFree(db, pTask->pUnpacked); -#if SQLITE_MAX_WORKER_THREADS>0 - /* pTask->list.aMemory can only be non-zero if it was handed memory - ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ - if( pTask->list.aMemory ){ - sqlite3_free(pTask->list.aMemory); - }else -#endif - { - assert( pTask->list.aMemory==0 ); - vdbeSorterRecordFree(0, pTask->list.pList); - } - if( pTask->file.pFd ){ - sqlite3OsCloseFree(pTask->file.pFd); - } - if( pTask->file2.pFd ){ - sqlite3OsCloseFree(pTask->file2.pFd); - } - memset(pTask, 0, sizeof(SortSubtask)); -} - -#ifdef SQLITE_DEBUG_SORTER_THREADS -static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ - i64 t; - int iTask = (pTask - pTask->pSorter->aTask); - sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); -} -static void vdbeSorterRewindDebug(const char *zEvent){ - i64 t; - sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t); - fprintf(stderr, "%lld:X %s\n", t, zEvent); -} -static void vdbeSorterPopulateDebug( - SortSubtask *pTask, - const char *zEvent -){ - i64 t; - int iTask = (pTask - pTask->pSorter->aTask); - sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); -} -static void vdbeSorterBlockDebug( - SortSubtask *pTask, - int bBlocked, - const char *zEvent -){ - if( bBlocked ){ - i64 t; - sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); - fprintf(stderr, "%lld:main %s\n", t, zEvent); - } -} -#else -# define vdbeSorterWorkDebug(x,y) -# define vdbeSorterRewindDebug(y) -# define vdbeSorterPopulateDebug(x,y) -# define vdbeSorterBlockDebug(x,y,z) -#endif - -#if SQLITE_MAX_WORKER_THREADS>0 -/* -** Join thread pTask->thread. -*/ -static int vdbeSorterJoinThread(SortSubtask *pTask){ - int rc = SQLITE_OK; - if( pTask->pThread ){ -#ifdef SQLITE_DEBUG_SORTER_THREADS - int bDone = pTask->bDone; -#endif - void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); - vdbeSorterBlockDebug(pTask, !bDone, "enter"); - (void)sqlite3ThreadJoin(pTask->pThread, &pRet); - vdbeSorterBlockDebug(pTask, !bDone, "exit"); - rc = SQLITE_PTR_TO_INT(pRet); - assert( pTask->bDone==1 ); - pTask->bDone = 0; - pTask->pThread = 0; - } - return rc; -} - -/* -** Launch a background thread to run xTask(pIn). -*/ -static int vdbeSorterCreateThread( - SortSubtask *pTask, /* Thread will use this task object */ - void *(*xTask)(void*), /* Routine to run in a separate thread */ - void *pIn /* Argument passed into xTask() */ -){ - assert( pTask->pThread==0 && pTask->bDone==0 ); - return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); -} - -/* -** Join all outstanding threads launched by SorterWrite() to create -** level-0 PMAs. -*/ -static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ - int rc = rcin; - int i; - - /* This function is always called by the main user thread. - ** - ** If this function is being called after SorterRewind() has been called, - ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread - ** is currently attempt to join one of the other threads. To avoid a race - ** condition where this thread also attempts to join the same object, join - ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ - for(i=pSorter->nTask-1; i>=0; i--){ - SortSubtask *pTask = &pSorter->aTask[i]; - int rc2 = vdbeSorterJoinThread(pTask); - if( rc==SQLITE_OK ) rc = rc2; - } - return rc; -} -#else -# define vdbeSorterJoinAll(x,rcin) (rcin) -# define vdbeSorterJoinThread(pTask) SQLITE_OK -#endif - -/* -** Allocate a new MergeEngine object capable of handling up to -** nReader PmaReader inputs. -** -** nReader is automatically rounded up to the next power of two. -** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up. -*/ -static MergeEngine *vdbeMergeEngineNew(int nReader){ - int N = 2; /* Smallest power of two >= nReader */ - int nByte; /* Total bytes of space to allocate */ - MergeEngine *pNew; /* Pointer to allocated object to return */ - - assert( nReader<=SORTER_MAX_MERGE_COUNT ); - - while( NnTree = N; - pNew->pTask = 0; - pNew->aReadr = (PmaReader*)&pNew[1]; - pNew->aTree = (int*)&pNew->aReadr[N]; - } - return pNew; -} - -/* -** Free the MergeEngine object passed as the only argument. -*/ -static void vdbeMergeEngineFree(MergeEngine *pMerger){ - int i; - if( pMerger ){ - for(i=0; inTree; i++){ - vdbePmaReaderClear(&pMerger->aReadr[i]); - } - } - sqlite3_free(pMerger); -} - -/* -** Free all resources associated with the IncrMerger object indicated by -** the first argument. -*/ -static void vdbeIncrFree(IncrMerger *pIncr){ - if( pIncr ){ -#if SQLITE_MAX_WORKER_THREADS>0 - if( pIncr->bUseThread ){ - vdbeSorterJoinThread(pIncr->pTask); - if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); - if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); - } -#endif - vdbeMergeEngineFree(pIncr->pMerger); - sqlite3_free(pIncr); - } -} - -/* -** Reset a sorting cursor back to its original empty state. -*/ -SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ - int i; - (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); - assert( pSorter->bUseThreads || pSorter->pReader==0 ); -#if SQLITE_MAX_WORKER_THREADS>0 - if( pSorter->pReader ){ - vdbePmaReaderClear(pSorter->pReader); - sqlite3DbFree(db, pSorter->pReader); - pSorter->pReader = 0; - } -#endif - vdbeMergeEngineFree(pSorter->pMerger); - pSorter->pMerger = 0; - for(i=0; inTask; i++){ - SortSubtask *pTask = &pSorter->aTask[i]; - vdbeSortSubtaskCleanup(db, pTask); - pTask->pSorter = pSorter; - } - if( pSorter->list.aMemory==0 ){ - vdbeSorterRecordFree(0, pSorter->list.pList); - } - pSorter->list.pList = 0; - pSorter->list.szPMA = 0; - pSorter->bUsePMA = 0; - pSorter->iMemory = 0; - pSorter->mxKeysize = 0; - sqlite3DbFree(db, pSorter->pUnpacked); - pSorter->pUnpacked = 0; -} - -/* -** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. -*/ -SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ - VdbeSorter *pSorter; - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - if( pSorter ){ - sqlite3VdbeSorterReset(db, pSorter); - sqlite3_free(pSorter->list.aMemory); - sqlite3DbFree(db, pSorter); - pCsr->uc.pSorter = 0; - } -} - -#if SQLITE_MAX_MMAP_SIZE>0 -/* -** The first argument is a file-handle open on a temporary file. The file -** is guaranteed to be nByte bytes or smaller in size. This function -** attempts to extend the file to nByte bytes in size and to ensure that -** the VFS has memory mapped it. -** -** Whether or not the file does end up memory mapped of course depends on -** the specific VFS implementation. -*/ -static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ - if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ - void *p = 0; - int chunksize = 4*1024; - sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); - sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); - sqlite3OsFetch(pFd, 0, (int)nByte, &p); - sqlite3OsUnfetch(pFd, 0, p); - } -} -#else -# define vdbeSorterExtendFile(x,y,z) -#endif - -/* -** Allocate space for a file-handle and open a temporary file. If successful, -** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. -** Otherwise, set *ppFd to 0 and return an SQLite error code. -*/ -static int vdbeSorterOpenTempFile( - sqlite3 *db, /* Database handle doing sort */ - i64 nExtend, /* Attempt to extend file to this size */ - sqlite3_file **ppFd -){ - int rc; - if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; - rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, - SQLITE_OPEN_TEMP_JOURNAL | - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc - ); - if( rc==SQLITE_OK ){ - i64 max = SQLITE_MAX_MMAP_SIZE; - sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); - if( nExtend>0 ){ - vdbeSorterExtendFile(db, *ppFd, nExtend); - } - } - return rc; -} - -/* -** If it has not already been allocated, allocate the UnpackedRecord -** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or -** if no allocation was required), or SQLITE_NOMEM otherwise. -*/ -static int vdbeSortAllocUnpacked(SortSubtask *pTask){ - if( pTask->pUnpacked==0 ){ - char *pFree; - pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord( - pTask->pSorter->pKeyInfo, 0, 0, &pFree - ); - assert( pTask->pUnpacked==(UnpackedRecord*)pFree ); - if( pFree==0 ) return SQLITE_NOMEM_BKPT; - pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField; - pTask->pUnpacked->errCode = 0; - } - return SQLITE_OK; -} - - -/* -** Merge the two sorted lists p1 and p2 into a single list. -*/ -static SorterRecord *vdbeSorterMerge( - SortSubtask *pTask, /* Calling thread context */ - SorterRecord *p1, /* First list to merge */ - SorterRecord *p2 /* Second list to merge */ -){ - SorterRecord *pFinal = 0; - SorterRecord **pp = &pFinal; - int bCached = 0; - - assert( p1!=0 && p2!=0 ); - for(;;){ - int res; - res = pTask->xCompare( - pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal - ); - - if( res<=0 ){ - *pp = p1; - pp = &p1->u.pNext; - p1 = p1->u.pNext; - if( p1==0 ){ - *pp = p2; - break; - } - }else{ - *pp = p2; - pp = &p2->u.pNext; - p2 = p2->u.pNext; - bCached = 0; - if( p2==0 ){ - *pp = p1; - break; - } - } - } - return pFinal; -} - -/* -** Return the SorterCompare function to compare values collected by the -** sorter object passed as the only argument. -*/ -static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ - if( p->typeMask==SORTER_TYPE_INTEGER ){ - return vdbeSorterCompareInt; - }else if( p->typeMask==SORTER_TYPE_TEXT ){ - return vdbeSorterCompareText; - } - return vdbeSorterCompare; -} - -/* -** Sort the linked list of records headed at pTask->pList. Return -** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if -** an error occurs. -*/ -static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ - int i; - SorterRecord **aSlot; - SorterRecord *p; - int rc; - - rc = vdbeSortAllocUnpacked(pTask); - if( rc!=SQLITE_OK ) return rc; - - p = pList->pList; - pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); - - aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); - if( !aSlot ){ - return SQLITE_NOMEM_BKPT; - } - - while( p ){ - SorterRecord *pNext; - if( pList->aMemory ){ - if( (u8*)p==pList->aMemory ){ - pNext = 0; - }else{ - assert( p->u.iNextaMemory) ); - pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; - } - }else{ - pNext = p->u.pNext; - } - - p->u.pNext = 0; - for(i=0; aSlot[i]; i++){ - p = vdbeSorterMerge(pTask, p, aSlot[i]); - aSlot[i] = 0; - } - aSlot[i] = p; - p = pNext; - } - - p = 0; - for(i=0; i<64; i++){ - if( aSlot[i]==0 ) continue; - p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i]; - } - pList->pList = p; - - sqlite3_free(aSlot); - assert( pTask->pUnpacked->errCode==SQLITE_OK - || pTask->pUnpacked->errCode==SQLITE_NOMEM - ); - return pTask->pUnpacked->errCode; -} - -/* -** Initialize a PMA-writer object. -*/ -static void vdbePmaWriterInit( - sqlite3_file *pFd, /* File handle to write to */ - PmaWriter *p, /* Object to populate */ - int nBuf, /* Buffer size */ - i64 iStart /* Offset of pFd to begin writing at */ -){ - memset(p, 0, sizeof(PmaWriter)); - p->aBuffer = (u8*)sqlite3Malloc(nBuf); - if( !p->aBuffer ){ - p->eFWErr = SQLITE_NOMEM_BKPT; - }else{ - p->iBufEnd = p->iBufStart = (iStart % nBuf); - p->iWriteOff = iStart - p->iBufStart; - p->nBuffer = nBuf; - p->pFd = pFd; - } -} - -/* -** Write nData bytes of data to the PMA. Return SQLITE_OK -** if successful, or an SQLite error code if an error occurs. -*/ -static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ - int nRem = nData; - while( nRem>0 && p->eFWErr==0 ){ - int nCopy = nRem; - if( nCopy>(p->nBuffer - p->iBufEnd) ){ - nCopy = p->nBuffer - p->iBufEnd; - } - - memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); - p->iBufEnd += nCopy; - if( p->iBufEnd==p->nBuffer ){ - p->eFWErr = sqlite3OsWrite(p->pFd, - &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, - p->iWriteOff + p->iBufStart - ); - p->iBufStart = p->iBufEnd = 0; - p->iWriteOff += p->nBuffer; - } - assert( p->iBufEndnBuffer ); - - nRem -= nCopy; - } -} - -/* -** Flush any buffered data to disk and clean up the PMA-writer object. -** The results of using the PMA-writer after this call are undefined. -** Return SQLITE_OK if flushing the buffered data succeeds or is not -** required. Otherwise, return an SQLite error code. -** -** Before returning, set *piEof to the offset immediately following the -** last byte written to the file. -*/ -static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ - int rc; - if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ - p->eFWErr = sqlite3OsWrite(p->pFd, - &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, - p->iWriteOff + p->iBufStart - ); - } - *piEof = (p->iWriteOff + p->iBufEnd); - sqlite3_free(p->aBuffer); - rc = p->eFWErr; - memset(p, 0, sizeof(PmaWriter)); - return rc; -} - -/* -** Write value iVal encoded as a varint to the PMA. Return -** SQLITE_OK if successful, or an SQLite error code if an error occurs. -*/ -static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ - int nByte; - u8 aByte[10]; - nByte = sqlite3PutVarint(aByte, iVal); - vdbePmaWriteBlob(p, aByte, nByte); -} - -/* -** Write the current contents of in-memory linked-list pList to a level-0 -** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if -** successful, or an SQLite error code otherwise. -** -** The format of a PMA is: -** -** * A varint. This varint contains the total number of bytes of content -** in the PMA (not including the varint itself). -** -** * One or more records packed end-to-end in order of ascending keys. -** Each record consists of a varint followed by a blob of data (the -** key). The varint is the number of bytes in the blob of data. -*/ -static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ - sqlite3 *db = pTask->pSorter->db; - int rc = SQLITE_OK; /* Return code */ - PmaWriter writer; /* Object used to write to the file */ - -#ifdef SQLITE_DEBUG - /* Set iSz to the expected size of file pTask->file after writing the PMA. - ** This is used by an assert() statement at the end of this function. */ - i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; -#endif - - vdbeSorterWorkDebug(pTask, "enter"); - memset(&writer, 0, sizeof(PmaWriter)); - assert( pList->szPMA>0 ); - - /* If the first temporary PMA file has not been opened, open it now. */ - if( pTask->file.pFd==0 ){ - rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd); - assert( rc!=SQLITE_OK || pTask->file.pFd ); - assert( pTask->file.iEof==0 ); - assert( pTask->nPMA==0 ); - } - - /* Try to get the file to memory map */ - if( rc==SQLITE_OK ){ - vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9); - } - - /* Sort the list */ - if( rc==SQLITE_OK ){ - rc = vdbeSorterSort(pTask, pList); - } - - if( rc==SQLITE_OK ){ - SorterRecord *p; - SorterRecord *pNext = 0; - - vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz, - pTask->file.iEof); - pTask->nPMA++; - vdbePmaWriteVarint(&writer, pList->szPMA); - for(p=pList->pList; p; p=pNext){ - pNext = p->u.pNext; - vdbePmaWriteVarint(&writer, p->nVal); - vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); - if( pList->aMemory==0 ) sqlite3_free(p); - } - pList->pList = p; - rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); - } - - vdbeSorterWorkDebug(pTask, "exit"); - assert( rc!=SQLITE_OK || pList->pList==0 ); - assert( rc!=SQLITE_OK || pTask->file.iEof==iSz ); - return rc; -} - -/* -** Advance the MergeEngine to its next entry. -** Set *pbEof to true there is no next entry because -** the MergeEngine has reached the end of all its inputs. -** -** Return SQLITE_OK if successful or an error code if an error occurs. -*/ -static int vdbeMergeEngineStep( - MergeEngine *pMerger, /* The merge engine to advance to the next row */ - int *pbEof /* Set TRUE at EOF. Set false for more content */ -){ - int rc; - int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */ - SortSubtask *pTask = pMerger->pTask; - - /* Advance the current PmaReader */ - rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); - - /* Update contents of aTree[] */ - if( rc==SQLITE_OK ){ - int i; /* Index of aTree[] to recalculate */ - PmaReader *pReadr1; /* First PmaReader to compare */ - PmaReader *pReadr2; /* Second PmaReader to compare */ - int bCached = 0; - - /* Find the first two PmaReaders to compare. The one that was just - ** advanced (iPrev) and the one next to it in the array. */ - pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; - pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; - - for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ - /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ - int iRes; - if( pReadr1->pFd==0 ){ - iRes = +1; - }else if( pReadr2->pFd==0 ){ - iRes = -1; - }else{ - iRes = pTask->xCompare(pTask, &bCached, - pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey - ); - } - - /* If pReadr1 contained the smaller value, set aTree[i] to its index. - ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this - ** case there is no cache of pReadr2 in pTask->pUnpacked, so set - ** pKey2 to point to the record belonging to pReadr2. - ** - ** Alternatively, if pReadr2 contains the smaller of the two values, - ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() - ** was actually called above, then pTask->pUnpacked now contains - ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent - ** vdbeSorterCompare() from decoding pReadr2 again. - ** - ** If the two values were equal, then the value from the oldest - ** PMA should be considered smaller. The VdbeSorter.aReadr[] array - ** is sorted from oldest to newest, so pReadr1 contains older values - ** than pReadr2 iff (pReadr1aTree[i] = (int)(pReadr1 - pMerger->aReadr); - pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; - bCached = 0; - }else{ - if( pReadr1->pFd ) bCached = 0; - pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); - pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; - } - } - *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); - } - - return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); -} - -#if SQLITE_MAX_WORKER_THREADS>0 -/* -** The main routine for background threads that write level-0 PMAs. -*/ -static void *vdbeSorterFlushThread(void *pCtx){ - SortSubtask *pTask = (SortSubtask*)pCtx; - int rc; /* Return code */ - assert( pTask->bDone==0 ); - rc = vdbeSorterListToPMA(pTask, &pTask->list); - pTask->bDone = 1; - return SQLITE_INT_TO_PTR(rc); -} -#endif /* SQLITE_MAX_WORKER_THREADS>0 */ - -/* -** Flush the current contents of VdbeSorter.list to a new PMA, possibly -** using a background thread. -*/ -static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ -#if SQLITE_MAX_WORKER_THREADS==0 - pSorter->bUsePMA = 1; - return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); -#else - int rc = SQLITE_OK; - int i; - SortSubtask *pTask = 0; /* Thread context used to create new PMA */ - int nWorker = (pSorter->nTask-1); - - /* Set the flag to indicate that at least one PMA has been written. - ** Or will be, anyhow. */ - pSorter->bUsePMA = 1; - - /* Select a sub-task to sort and flush the current list of in-memory - ** records to disk. If the sorter is running in multi-threaded mode, - ** round-robin between the first (pSorter->nTask-1) tasks. Except, if - ** the background thread from a sub-tasks previous turn is still running, - ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, - ** fall back to using the final sub-task. The first (pSorter->nTask-1) - ** sub-tasks are prefered as they use background threads - the final - ** sub-task uses the main thread. */ - for(i=0; iiPrev + i + 1) % nWorker; - pTask = &pSorter->aTask[iTest]; - if( pTask->bDone ){ - rc = vdbeSorterJoinThread(pTask); - } - if( rc!=SQLITE_OK || pTask->pThread==0 ) break; - } - - if( rc==SQLITE_OK ){ - if( i==nWorker ){ - /* Use the foreground thread for this operation */ - rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); - }else{ - /* Launch a background thread for this operation */ - u8 *aMem = pTask->list.aMemory; - void *pCtx = (void*)pTask; - - assert( pTask->pThread==0 && pTask->bDone==0 ); - assert( pTask->list.pList==0 ); - assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); - - pSorter->iPrev = (u8)(pTask - pSorter->aTask); - pTask->list = pSorter->list; - pSorter->list.pList = 0; - pSorter->list.szPMA = 0; - if( aMem ){ - pSorter->list.aMemory = aMem; - pSorter->nMemory = sqlite3MallocSize(aMem); - }else if( pSorter->list.aMemory ){ - pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); - if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT; - } - - rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx); - } - } - - return rc; -#endif /* SQLITE_MAX_WORKER_THREADS!=0 */ -} - -/* -** Add a record to the sorter. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterWrite( - const VdbeCursor *pCsr, /* Sorter cursor */ - Mem *pVal /* Memory cell containing record */ -){ - VdbeSorter *pSorter; - int rc = SQLITE_OK; /* Return Code */ - SorterRecord *pNew; /* New list element */ - int bFlush; /* True to flush contents of memory to PMA */ - int nReq; /* Bytes of memory required */ - int nPMA; /* Bytes of PMA space required */ - int t; /* serial type of first record field */ - - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - getVarint32((const u8*)&pVal->z[1], t); - if( t>0 && t<10 && t!=7 ){ - pSorter->typeMask &= SORTER_TYPE_INTEGER; - }else if( t>10 && (t & 0x01) ){ - pSorter->typeMask &= SORTER_TYPE_TEXT; - }else{ - pSorter->typeMask = 0; - } - - assert( pSorter ); - - /* Figure out whether or not the current contents of memory should be - ** flushed to a PMA before continuing. If so, do so. - ** - ** If using the single large allocation mode (pSorter->aMemory!=0), then - ** flush the contents of memory to a new PMA if (a) at least one value is - ** already in memory and (b) the new value will not fit in memory. - ** - ** Or, if using separate allocations for each record, flush the contents - ** of memory to a PMA if either of the following are true: - ** - ** * The total memory allocated for the in-memory list is greater - ** than (page-size * cache-size), or - ** - ** * The total memory allocated for the in-memory list is greater - ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. - */ - nReq = pVal->n + sizeof(SorterRecord); - nPMA = pVal->n + sqlite3VarintLen(pVal->n); - if( pSorter->mxPmaSize ){ - if( pSorter->list.aMemory ){ - bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; - }else{ - bFlush = ( - (pSorter->list.szPMA > pSorter->mxPmaSize) - || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) - ); - } - if( bFlush ){ - rc = vdbeSorterFlushPMA(pSorter); - pSorter->list.szPMA = 0; - pSorter->iMemory = 0; - assert( rc!=SQLITE_OK || pSorter->list.pList==0 ); - } - } - - pSorter->list.szPMA += nPMA; - if( nPMA>pSorter->mxKeysize ){ - pSorter->mxKeysize = nPMA; - } - - if( pSorter->list.aMemory ){ - int nMin = pSorter->iMemory + nReq; - - if( nMin>pSorter->nMemory ){ - u8 *aNew; - int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; - int nNew = pSorter->nMemory * 2; - while( nNew < nMin ) nNew = nNew*2; - if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; - if( nNew < nMin ) nNew = nMin; - - aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); - if( !aNew ) return SQLITE_NOMEM_BKPT; - pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; - pSorter->list.aMemory = aNew; - pSorter->nMemory = nNew; - } - - pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; - pSorter->iMemory += ROUND8(nReq); - if( pSorter->list.pList ){ - pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); - } - }else{ - pNew = (SorterRecord *)sqlite3Malloc(nReq); - if( pNew==0 ){ - return SQLITE_NOMEM_BKPT; - } - pNew->u.pNext = pSorter->list.pList; - } - - memcpy(SRVAL(pNew), pVal->z, pVal->n); - pNew->nVal = pVal->n; - pSorter->list.pList = pNew; - - return rc; -} - -/* -** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format -** of the data stored in aFile[1] is the same as that used by regular PMAs, -** except that the number-of-bytes varint is omitted from the start. -*/ -static int vdbeIncrPopulate(IncrMerger *pIncr){ - int rc = SQLITE_OK; - int rc2; - i64 iStart = pIncr->iStartOff; - SorterFile *pOut = &pIncr->aFile[1]; - SortSubtask *pTask = pIncr->pTask; - MergeEngine *pMerger = pIncr->pMerger; - PmaWriter writer; - assert( pIncr->bEof==0 ); - - vdbeSorterPopulateDebug(pTask, "enter"); - - vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); - while( rc==SQLITE_OK ){ - int dummy; - PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ]; - int nKey = pReader->nKey; - i64 iEof = writer.iWriteOff + writer.iBufEnd; - - /* Check if the output file is full or if the input has been exhausted. - ** In either case exit the loop. */ - if( pReader->pFd==0 ) break; - if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; - - /* Write the next key to the output. */ - vdbePmaWriteVarint(&writer, nKey); - vdbePmaWriteBlob(&writer, pReader->aKey, nKey); - assert( pIncr->pMerger->pTask==pTask ); - rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy); - } - - rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof); - if( rc==SQLITE_OK ) rc = rc2; - vdbeSorterPopulateDebug(pTask, "exit"); - return rc; -} - -#if SQLITE_MAX_WORKER_THREADS>0 -/* -** The main routine for background threads that populate aFile[1] of -** multi-threaded IncrMerger objects. -*/ -static void *vdbeIncrPopulateThread(void *pCtx){ - IncrMerger *pIncr = (IncrMerger*)pCtx; - void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) ); - pIncr->pTask->bDone = 1; - return pRet; -} - -/* -** Launch a background thread to populate aFile[1] of pIncr. -*/ -static int vdbeIncrBgPopulate(IncrMerger *pIncr){ - void *p = (void*)pIncr; - assert( pIncr->bUseThread ); - return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); -} -#endif - -/* -** This function is called when the PmaReader corresponding to pIncr has -** finished reading the contents of aFile[0]. Its purpose is to "refill" -** aFile[0] such that the PmaReader should start rereading it from the -** beginning. -** -** For single-threaded objects, this is accomplished by literally reading -** keys from pIncr->pMerger and repopulating aFile[0]. -** -** For multi-threaded objects, all that is required is to wait until the -** background thread is finished (if it is not already) and then swap -** aFile[0] and aFile[1] in place. If the contents of pMerger have not -** been exhausted, this function also launches a new background thread -** to populate the new aFile[1]. -** -** SQLITE_OK is returned on success, or an SQLite error code otherwise. -*/ -static int vdbeIncrSwap(IncrMerger *pIncr){ - int rc = SQLITE_OK; - -#if SQLITE_MAX_WORKER_THREADS>0 - if( pIncr->bUseThread ){ - rc = vdbeSorterJoinThread(pIncr->pTask); - - if( rc==SQLITE_OK ){ - SorterFile f0 = pIncr->aFile[0]; - pIncr->aFile[0] = pIncr->aFile[1]; - pIncr->aFile[1] = f0; - } - - if( rc==SQLITE_OK ){ - if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ - pIncr->bEof = 1; - }else{ - rc = vdbeIncrBgPopulate(pIncr); - } - } - }else -#endif - { - rc = vdbeIncrPopulate(pIncr); - pIncr->aFile[0] = pIncr->aFile[1]; - if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ - pIncr->bEof = 1; - } - } - - return rc; -} - -/* -** Allocate and return a new IncrMerger object to read data from pMerger. -** -** If an OOM condition is encountered, return NULL. In this case free the -** pMerger argument before returning. -*/ -static int vdbeIncrMergerNew( - SortSubtask *pTask, /* The thread that will be using the new IncrMerger */ - MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */ - IncrMerger **ppOut /* Write the new IncrMerger here */ -){ - int rc = SQLITE_OK; - IncrMerger *pIncr = *ppOut = (IncrMerger*) - (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); - if( pIncr ){ - pIncr->pMerger = pMerger; - pIncr->pTask = pTask; - pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2); - pTask->file2.iEof += pIncr->mxSz; - }else{ - vdbeMergeEngineFree(pMerger); - rc = SQLITE_NOMEM_BKPT; - } - return rc; -} - -#if SQLITE_MAX_WORKER_THREADS>0 -/* -** Set the "use-threads" flag on object pIncr. -*/ -static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){ - pIncr->bUseThread = 1; - pIncr->pTask->file2.iEof -= pIncr->mxSz; -} -#endif /* SQLITE_MAX_WORKER_THREADS>0 */ - - - -/* -** Recompute pMerger->aTree[iOut] by comparing the next keys on the -** two PmaReaders that feed that entry. Neither of the PmaReaders -** are advanced. This routine merely does the comparison. -*/ -static void vdbeMergeEngineCompare( - MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */ - int iOut /* Store the result in pMerger->aTree[iOut] */ -){ - int i1; - int i2; - int iRes; - PmaReader *p1; - PmaReader *p2; - - assert( iOutnTree && iOut>0 ); - - if( iOut>=(pMerger->nTree/2) ){ - i1 = (iOut - pMerger->nTree/2) * 2; - i2 = i1 + 1; - }else{ - i1 = pMerger->aTree[iOut*2]; - i2 = pMerger->aTree[iOut*2+1]; - } - - p1 = &pMerger->aReadr[i1]; - p2 = &pMerger->aReadr[i2]; - - if( p1->pFd==0 ){ - iRes = i2; - }else if( p2->pFd==0 ){ - iRes = i1; - }else{ - SortSubtask *pTask = pMerger->pTask; - int bCached = 0; - int res; - assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ - res = pTask->xCompare( - pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey - ); - if( res<=0 ){ - iRes = i1; - }else{ - iRes = i2; - } - } - - pMerger->aTree[iOut] = iRes; -} - -/* -** Allowed values for the eMode parameter to vdbeMergeEngineInit() -** and vdbePmaReaderIncrMergeInit(). -** -** Only INCRINIT_NORMAL is valid in single-threaded builds (when -** SQLITE_MAX_WORKER_THREADS==0). The other values are only used -** when there exists one or more separate worker threads. -*/ -#define INCRINIT_NORMAL 0 -#define INCRINIT_TASK 1 -#define INCRINIT_ROOT 2 - -/* -** Forward reference required as the vdbeIncrMergeInit() and -** vdbePmaReaderIncrInit() routines are called mutually recursively when -** building a merge tree. -*/ -static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); - -/* -** Initialize the MergeEngine object passed as the second argument. Once this -** function returns, the first key of merged data may be read from the -** MergeEngine object in the usual fashion. -** -** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge -** objects attached to the PmaReader objects that the merger reads from have -** already been populated, but that they have not yet populated aFile[0] and -** set the PmaReader objects up to read from it. In this case all that is -** required is to call vdbePmaReaderNext() on each PmaReader to point it at -** its first key. -** -** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use -** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data -** to pMerger. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -static int vdbeMergeEngineInit( - SortSubtask *pTask, /* Thread that will run pMerger */ - MergeEngine *pMerger, /* MergeEngine to initialize */ - int eMode /* One of the INCRINIT_XXX constants */ -){ - int rc = SQLITE_OK; /* Return code */ - int i; /* For looping over PmaReader objects */ - int nTree = pMerger->nTree; - - /* eMode is always INCRINIT_NORMAL in single-threaded mode */ - assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); - - /* Verify that the MergeEngine is assigned to a single thread */ - assert( pMerger->pTask==0 ); - pMerger->pTask = pTask; - - for(i=0; i0 && eMode==INCRINIT_ROOT ){ - /* PmaReaders should be normally initialized in order, as if they are - ** reading from the same temp file this makes for more linear file IO. - ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is - ** in use it will block the vdbePmaReaderNext() call while it uses - ** the main thread to fill its buffer. So calling PmaReaderNext() - ** on this PmaReader before any of the multi-threaded PmaReaders takes - ** better advantage of multi-processor hardware. */ - rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); - }else{ - rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL); - } - if( rc!=SQLITE_OK ) return rc; - } - - for(i=pMerger->nTree-1; i>0; i--){ - vdbeMergeEngineCompare(pMerger, i); - } - return pTask->pUnpacked->errCode; -} - -/* -** The PmaReader passed as the first argument is guaranteed to be an -** incremental-reader (pReadr->pIncr!=0). This function serves to open -** and/or initialize the temp file related fields of the IncrMerge -** object at (pReadr->pIncr). -** -** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders -** in the sub-tree headed by pReadr are also initialized. Data is then -** loaded into the buffers belonging to pReadr and it is set to point to -** the first key in its range. -** -** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed -** to be a multi-threaded PmaReader and this function is being called in a -** background thread. In this case all PmaReaders in the sub-tree are -** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to -** pReadr is populated. However, pReadr itself is not set up to point -** to its first key. A call to vdbePmaReaderNext() is still required to do -** that. -** -** The reason this function does not call vdbePmaReaderNext() immediately -** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has -** to block on thread (pTask->thread) before accessing aFile[1]. But, since -** this entire function is being run by thread (pTask->thread), that will -** lead to the current background thread attempting to join itself. -** -** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed -** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all -** child-trees have already been initialized using IncrInit(INCRINIT_TASK). -** In this case vdbePmaReaderNext() is called on all child PmaReaders and -** the current PmaReader set to point to the first key in its range. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ - int rc = SQLITE_OK; - IncrMerger *pIncr = pReadr->pIncr; - SortSubtask *pTask = pIncr->pTask; - sqlite3 *db = pTask->pSorter->db; - - /* eMode is always INCRINIT_NORMAL in single-threaded mode */ - assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); - - rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); - - /* Set up the required files for pIncr. A multi-theaded IncrMerge object - ** requires two temp files to itself, whereas a single-threaded object - ** only requires a region of pTask->file2. */ - if( rc==SQLITE_OK ){ - int mxSz = pIncr->mxSz; -#if SQLITE_MAX_WORKER_THREADS>0 - if( pIncr->bUseThread ){ - rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); - if( rc==SQLITE_OK ){ - rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); - } - }else -#endif - /*if( !pIncr->bUseThread )*/{ - if( pTask->file2.pFd==0 ){ - assert( pTask->file2.iEof>0 ); - rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); - pTask->file2.iEof = 0; - } - if( rc==SQLITE_OK ){ - pIncr->aFile[1].pFd = pTask->file2.pFd; - pIncr->iStartOff = pTask->file2.iEof; - pTask->file2.iEof += mxSz; - } - } - } - -#if SQLITE_MAX_WORKER_THREADS>0 - if( rc==SQLITE_OK && pIncr->bUseThread ){ - /* Use the current thread to populate aFile[1], even though this - ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, - ** then this function is already running in background thread - ** pIncr->pTask->thread. - ** - ** If this is the INCRINIT_ROOT object, then it is running in the - ** main VDBE thread. But that is Ok, as that thread cannot return - ** control to the VDBE or proceed with anything useful until the - ** first results are ready from this merger object anyway. - */ - assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); - rc = vdbeIncrPopulate(pIncr); - } -#endif - - if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){ - rc = vdbePmaReaderNext(pReadr); - } - - return rc; -} - -#if SQLITE_MAX_WORKER_THREADS>0 -/* -** The main routine for vdbePmaReaderIncrMergeInit() operations run in -** background threads. -*/ -static void *vdbePmaReaderBgIncrInit(void *pCtx){ - PmaReader *pReader = (PmaReader*)pCtx; - void *pRet = SQLITE_INT_TO_PTR( - vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) - ); - pReader->pIncr->pTask->bDone = 1; - return pRet; -} -#endif - -/* -** If the PmaReader passed as the first argument is not an incremental-reader -** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes -** the vdbePmaReaderIncrMergeInit() function with the parameters passed to -** this routine to initialize the incremental merge. -** -** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), -** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). -** Or, if the IncrMerger is single threaded, the same function is called -** using the current thread. -*/ -static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){ - IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ - int rc = SQLITE_OK; /* Return code */ - if( pIncr ){ -#if SQLITE_MAX_WORKER_THREADS>0 - assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK ); - if( pIncr->bUseThread ){ - void *pCtx = (void*)pReadr; - rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx); - }else -#endif - { - rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); - } - } - return rc; -} - -/* -** Allocate a new MergeEngine object to merge the contents of nPMA level-0 -** PMAs from pTask->file. If no error occurs, set *ppOut to point to -** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut -** to NULL and return an SQLite error code. -** -** When this function is called, *piOffset is set to the offset of the -** first PMA to read from pTask->file. Assuming no error occurs, it is -** set to the offset immediately following the last byte of the last -** PMA before returning. If an error does occur, then the final value of -** *piOffset is undefined. -*/ -static int vdbeMergeEngineLevel0( - SortSubtask *pTask, /* Sorter task to read from */ - int nPMA, /* Number of PMAs to read */ - i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */ - MergeEngine **ppOut /* OUT: New merge-engine */ -){ - MergeEngine *pNew; /* Merge engine to return */ - i64 iOff = *piOffset; - int i; - int rc = SQLITE_OK; - - *ppOut = pNew = vdbeMergeEngineNew(nPMA); - if( pNew==0 ) rc = SQLITE_NOMEM_BKPT; - - for(i=0; iaReadr[i]; - rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy); - iOff = pReadr->iEof; - } - - if( rc!=SQLITE_OK ){ - vdbeMergeEngineFree(pNew); - *ppOut = 0; - } - *piOffset = iOff; - return rc; -} - -/* -** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of -** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes. -** -** i.e. -** -** nPMA<=16 -> TreeDepth() == 0 -** nPMA<=256 -> TreeDepth() == 1 -** nPMA<=65536 -> TreeDepth() == 2 -*/ -static int vdbeSorterTreeDepth(int nPMA){ - int nDepth = 0; - i64 nDiv = SORTER_MAX_MERGE_COUNT; - while( nDiv < (i64)nPMA ){ - nDiv = nDiv * SORTER_MAX_MERGE_COUNT; - nDepth++; - } - return nDepth; -} - -/* -** pRoot is the root of an incremental merge-tree with depth nDepth (according -** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the -** tree, counting from zero. This function adds pLeaf to the tree. -** -** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error -** code is returned and pLeaf is freed. -*/ -static int vdbeSorterAddToTree( - SortSubtask *pTask, /* Task context */ - int nDepth, /* Depth of tree according to TreeDepth() */ - int iSeq, /* Sequence number of leaf within tree */ - MergeEngine *pRoot, /* Root of tree */ - MergeEngine *pLeaf /* Leaf to add to tree */ -){ - int rc = SQLITE_OK; - int nDiv = 1; - int i; - MergeEngine *p = pRoot; - IncrMerger *pIncr; - - rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr); - - for(i=1; iaReadr[iIter]; - - if( pReadr->pIncr==0 ){ - MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); - if( pNew==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr); - } - } - if( rc==SQLITE_OK ){ - p = pReadr->pIncr->pMerger; - nDiv = nDiv / SORTER_MAX_MERGE_COUNT; - } - } - - if( rc==SQLITE_OK ){ - p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr; - }else{ - vdbeIncrFree(pIncr); - } - return rc; -} - -/* -** This function is called as part of a SorterRewind() operation on a sorter -** that has already written two or more level-0 PMAs to one or more temp -** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that -** can be used to incrementally merge all PMAs on disk. -** -** If successful, SQLITE_OK is returned and *ppOut set to point to the -** MergeEngine object at the root of the tree before returning. Or, if an -** error occurs, an SQLite error code is returned and the final value -** of *ppOut is undefined. -*/ -static int vdbeSorterMergeTreeBuild( - VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */ - MergeEngine **ppOut /* Write the MergeEngine here */ -){ - MergeEngine *pMain = 0; - int rc = SQLITE_OK; - int iTask; - -#if SQLITE_MAX_WORKER_THREADS>0 - /* If the sorter uses more than one task, then create the top-level - ** MergeEngine here. This MergeEngine will read data from exactly - ** one PmaReader per sub-task. */ - assert( pSorter->bUseThreads || pSorter->nTask==1 ); - if( pSorter->nTask>1 ){ - pMain = vdbeMergeEngineNew(pSorter->nTask); - if( pMain==0 ) rc = SQLITE_NOMEM_BKPT; - } -#endif - - for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ - SortSubtask *pTask = &pSorter->aTask[iTask]; - assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 ); - if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){ - MergeEngine *pRoot = 0; /* Root node of tree for this task */ - int nDepth = vdbeSorterTreeDepth(pTask->nPMA); - i64 iReadOff = 0; - - if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){ - rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot); - }else{ - int i; - int iSeq = 0; - pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); - if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT; - for(i=0; inPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){ - MergeEngine *pMerger = 0; /* New level-0 PMA merger */ - int nReader; /* Number of level-0 PMAs to merge */ - - nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT); - rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger); - if( rc==SQLITE_OK ){ - rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger); - } - } - } - - if( rc==SQLITE_OK ){ -#if SQLITE_MAX_WORKER_THREADS>0 - if( pMain!=0 ){ - rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr); - }else -#endif - { - assert( pMain==0 ); - pMain = pRoot; - } - }else{ - vdbeMergeEngineFree(pRoot); - } - } - } - - if( rc!=SQLITE_OK ){ - vdbeMergeEngineFree(pMain); - pMain = 0; - } - *ppOut = pMain; - return rc; -} - -/* -** This function is called as part of an sqlite3VdbeSorterRewind() operation -** on a sorter that has written two or more PMAs to temporary files. It sets -** up either VdbeSorter.pMerger (for single threaded sorters) or pReader -** (for multi-threaded sorters) so that it can be used to iterate through -** all records stored in the sorter. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ - int rc; /* Return code */ - SortSubtask *pTask0 = &pSorter->aTask[0]; - MergeEngine *pMain = 0; -#if SQLITE_MAX_WORKER_THREADS - sqlite3 *db = pTask0->pSorter->db; - int i; - SorterCompare xCompare = vdbeSorterGetCompare(pSorter); - for(i=0; inTask; i++){ - pSorter->aTask[i].xCompare = xCompare; - } -#endif - - rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); - if( rc==SQLITE_OK ){ -#if SQLITE_MAX_WORKER_THREADS - assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); - if( pSorter->bUseThreads ){ - int iTask; - PmaReader *pReadr = 0; - SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; - rc = vdbeSortAllocUnpacked(pLast); - if( rc==SQLITE_OK ){ - pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); - pSorter->pReader = pReadr; - if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT; - } - if( rc==SQLITE_OK ){ - rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); - if( rc==SQLITE_OK ){ - vdbeIncrMergerSetThreads(pReadr->pIncr); - for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ - IncrMerger *pIncr; - if( (pIncr = pMain->aReadr[iTask].pIncr) ){ - vdbeIncrMergerSetThreads(pIncr); - assert( pIncr->pTask!=pLast ); - } - } - for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ - /* Check that: - ** - ** a) The incremental merge object is configured to use the - ** right task, and - ** b) If it is using task (nTask-1), it is configured to run - ** in single-threaded mode. This is important, as the - ** root merge (INCRINIT_ROOT) will be using the same task - ** object. - */ - PmaReader *p = &pMain->aReadr[iTask]; - assert( p->pIncr==0 || ( - (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */ - && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */ - )); - rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); - } - } - pMain = 0; - } - if( rc==SQLITE_OK ){ - rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); - } - }else -#endif - { - rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); - pSorter->pMerger = pMain; - pMain = 0; - } - } - - if( rc!=SQLITE_OK ){ - vdbeMergeEngineFree(pMain); - } - return rc; -} - - -/* -** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, -** this function is called to prepare for iterating through the records -** in sorted order. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ - VdbeSorter *pSorter; - int rc = SQLITE_OK; /* Return code */ - - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - assert( pSorter ); - - /* If no data has been written to disk, then do not do so now. Instead, - ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly - ** from the in-memory list. */ - if( pSorter->bUsePMA==0 ){ - if( pSorter->list.pList ){ - *pbEof = 0; - rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); - }else{ - *pbEof = 1; - } - return rc; - } - - /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() - ** function flushes the contents of memory to disk, it immediately always - ** creates a new list consisting of a single key immediately afterwards. - ** So the list is never empty at this point. */ - assert( pSorter->list.pList ); - rc = vdbeSorterFlushPMA(pSorter); - - /* Join all threads */ - rc = vdbeSorterJoinAll(pSorter, rc); - - vdbeSorterRewindDebug("rewind"); - - /* Assuming no errors have occurred, set up a merger structure to - ** incrementally read and merge all remaining PMAs. */ - assert( pSorter->pReader==0 ); - if( rc==SQLITE_OK ){ - rc = vdbeSorterSetupMerge(pSorter); - *pbEof = 0; - } - - vdbeSorterRewindDebug("rewinddone"); - return rc; -} - -/* -** Advance to the next element in the sorter. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ - VdbeSorter *pSorter; - int rc; /* Return code */ - - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); - if( pSorter->bUsePMA ){ - assert( pSorter->pReader==0 || pSorter->pMerger==0 ); - assert( pSorter->bUseThreads==0 || pSorter->pReader ); - assert( pSorter->bUseThreads==1 || pSorter->pMerger ); -#if SQLITE_MAX_WORKER_THREADS>0 - if( pSorter->bUseThreads ){ - rc = vdbePmaReaderNext(pSorter->pReader); - *pbEof = (pSorter->pReader->pFd==0); - }else -#endif - /*if( !pSorter->bUseThreads )*/ { - assert( pSorter->pMerger!=0 ); - assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); - rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof); - } - }else{ - SorterRecord *pFree = pSorter->list.pList; - pSorter->list.pList = pFree->u.pNext; - pFree->u.pNext = 0; - if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); - *pbEof = !pSorter->list.pList; - rc = SQLITE_OK; - } - return rc; -} - -/* -** Return a pointer to a buffer owned by the sorter that contains the -** current key. -*/ -static void *vdbeSorterRowkey( - const VdbeSorter *pSorter, /* Sorter object */ - int *pnKey /* OUT: Size of current key in bytes */ -){ - void *pKey; - if( pSorter->bUsePMA ){ - PmaReader *pReader; -#if SQLITE_MAX_WORKER_THREADS>0 - if( pSorter->bUseThreads ){ - pReader = pSorter->pReader; - }else -#endif - /*if( !pSorter->bUseThreads )*/{ - pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]]; - } - *pnKey = pReader->nKey; - pKey = pReader->aKey; - }else{ - *pnKey = pSorter->list.pList->nVal; - pKey = SRVAL(pSorter->list.pList); - } - return pKey; -} - -/* -** Copy the current sorter key into the memory cell pOut. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ - VdbeSorter *pSorter; - void *pKey; int nKey; /* Sorter key to copy into pOut */ - - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - pKey = vdbeSorterRowkey(pSorter, &nKey); - if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ - return SQLITE_NOMEM_BKPT; - } - pOut->n = nKey; - MemSetTypeFlag(pOut, MEM_Blob); - memcpy(pOut->z, pKey, nKey); - - return SQLITE_OK; -} - -/* -** Compare the key in memory cell pVal with the key that the sorter cursor -** passed as the first argument currently points to. For the purposes of -** the comparison, ignore the rowid field at the end of each record. -** -** If the sorter cursor key contains any NULL values, consider it to be -** less than pVal. Even if pVal also contains NULL values. -** -** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). -** Otherwise, set *pRes to a negative, zero or positive value if the -** key in pVal is smaller than, equal to or larger than the current sorter -** key. -** -** This routine forms the core of the OP_SorterCompare opcode, which in -** turn is used to verify uniqueness when constructing a UNIQUE INDEX. -*/ -SQLITE_PRIVATE int sqlite3VdbeSorterCompare( - const VdbeCursor *pCsr, /* Sorter cursor */ - Mem *pVal, /* Value to compare to current sorter key */ - int nKeyCol, /* Compare this many columns */ - int *pRes /* OUT: Result of comparison */ -){ - VdbeSorter *pSorter; - UnpackedRecord *r2; - KeyInfo *pKeyInfo; - int i; - void *pKey; int nKey; /* Sorter key to compare pVal with */ - - assert( pCsr->eCurType==CURTYPE_SORTER ); - pSorter = pCsr->uc.pSorter; - r2 = pSorter->pUnpacked; - pKeyInfo = pCsr->pKeyInfo; - if( r2==0 ){ - char *p; - r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p); - assert( pSorter->pUnpacked==(UnpackedRecord*)p ); - if( r2==0 ) return SQLITE_NOMEM_BKPT; - r2->nField = nKeyCol; - } - assert( r2->nField==nKeyCol ); - - pKey = vdbeSorterRowkey(pSorter, &nKey); - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); - for(i=0; iaMem[i].flags & MEM_Null ){ - *pRes = -1; - return SQLITE_OK; - } - } - - *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); - return SQLITE_OK; -} - -/************** End of vdbesort.c ********************************************/ -/************** Begin file memjournal.c **************************************/ -/* -** 2008 October 7 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains code use to implement an in-memory rollback journal. -** The in-memory rollback journal is used to journal transactions for -** ":memory:" databases and when the journal_mode=MEMORY pragma is used. -** -** Update: The in-memory journal is also used to temporarily cache -** smaller journals that are not critical for power-loss recovery. -** For example, statement journals that are not too big will be held -** entirely in memory, thus reducing the number of file I/O calls, and -** more importantly, reducing temporary file creation events. If these -** journals become too large for memory, they are spilled to disk. But -** in the common case, they are usually small and no file I/O needs to -** occur. -*/ -/* #include "sqliteInt.h" */ - -/* Forward references to internal structures */ -typedef struct MemJournal MemJournal; -typedef struct FilePoint FilePoint; -typedef struct FileChunk FileChunk; - -/* -** The rollback journal is composed of a linked list of these structures. -** -** The zChunk array is always at least 8 bytes in size - usually much more. -** Its actual size is stored in the MemJournal.nChunkSize variable. -*/ -struct FileChunk { - FileChunk *pNext; /* Next chunk in the journal */ - u8 zChunk[8]; /* Content of this chunk */ -}; - -/* -** By default, allocate this many bytes of memory for each FileChunk object. -*/ -#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024 - -/* -** For chunk size nChunkSize, return the number of bytes that should -** be allocated for each FileChunk structure. -*/ -#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8)) - -/* -** An instance of this object serves as a cursor into the rollback journal. -** The cursor can be either for reading or writing. -*/ -struct FilePoint { - sqlite3_int64 iOffset; /* Offset from the beginning of the file */ - FileChunk *pChunk; /* Specific chunk into which cursor points */ -}; - -/* -** This structure is a subclass of sqlite3_file. Each open memory-journal -** is an instance of this class. -*/ -struct MemJournal { - const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ - int nChunkSize; /* In-memory chunk-size */ - - int nSpill; /* Bytes of data before flushing */ - int nSize; /* Bytes of data currently in memory */ - FileChunk *pFirst; /* Head of in-memory chunk-list */ - FilePoint endpoint; /* Pointer to the end of the file */ - FilePoint readpoint; /* Pointer to the end of the last xRead() */ - - int flags; /* xOpen flags */ - sqlite3_vfs *pVfs; /* The "real" underlying VFS */ - const char *zJournal; /* Name of the journal file */ -}; - -/* -** Read data from the in-memory journal file. This is the implementation -** of the sqlite3_vfs.xRead method. -*/ -static int memjrnlRead( - sqlite3_file *pJfd, /* The journal file from which to read */ - void *zBuf, /* Put the results here */ - int iAmt, /* Number of bytes to read */ - sqlite_int64 iOfst /* Begin reading at this offset */ -){ - MemJournal *p = (MemJournal *)pJfd; - u8 *zOut = zBuf; - int nRead = iAmt; - int iChunkOffset; - FileChunk *pChunk; - -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - if( (iAmt+iOfst)>p->endpoint.iOffset ){ - return SQLITE_IOERR_SHORT_READ; - } -#endif - - assert( (iAmt+iOfst)<=p->endpoint.iOffset ); - assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); - if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ - sqlite3_int64 iOff = 0; - for(pChunk=p->pFirst; - ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst; - pChunk=pChunk->pNext - ){ - iOff += p->nChunkSize; - } - }else{ - pChunk = p->readpoint.pChunk; - assert( pChunk!=0 ); - } - - iChunkOffset = (int)(iOfst%p->nChunkSize); - do { - int iSpace = p->nChunkSize - iChunkOffset; - int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset)); - memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy); - zOut += nCopy; - nRead -= iSpace; - iChunkOffset = 0; - } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); - p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0; - p->readpoint.pChunk = pChunk; - - return SQLITE_OK; -} - -/* -** Free the list of FileChunk structures headed at MemJournal.pFirst. -*/ -static void memjrnlFreeChunks(MemJournal *p){ - FileChunk *pIter; - FileChunk *pNext; - for(pIter=p->pFirst; pIter; pIter=pNext){ - pNext = pIter->pNext; - sqlite3_free(pIter); - } - p->pFirst = 0; -} - -/* -** Flush the contents of memory to a real file on disk. -*/ -static int memjrnlCreateFile(MemJournal *p){ - int rc; - sqlite3_file *pReal = (sqlite3_file*)p; - MemJournal copy = *p; - - memset(p, 0, sizeof(MemJournal)); - rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0); - if( rc==SQLITE_OK ){ - int nChunk = copy.nChunkSize; - i64 iOff = 0; - FileChunk *pIter; - for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){ - if( iOff + nChunk > copy.endpoint.iOffset ){ - nChunk = copy.endpoint.iOffset - iOff; - } - rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff); - if( rc ) break; - iOff += nChunk; - } - if( rc==SQLITE_OK ){ - /* No error has occurred. Free the in-memory buffers. */ - memjrnlFreeChunks(©); - } - } - if( rc!=SQLITE_OK ){ - /* If an error occurred while creating or writing to the file, restore - ** the original before returning. This way, SQLite uses the in-memory - ** journal data to roll back changes made to the internal page-cache - ** before this function was called. */ - sqlite3OsClose(pReal); - *p = copy; - } - return rc; -} - - -/* -** Write data to the file. -*/ -static int memjrnlWrite( - sqlite3_file *pJfd, /* The journal file into which to write */ - const void *zBuf, /* Take data to be written from here */ - int iAmt, /* Number of bytes to write */ - sqlite_int64 iOfst /* Begin writing at this offset into the file */ -){ - MemJournal *p = (MemJournal *)pJfd; - int nWrite = iAmt; - u8 *zWrite = (u8 *)zBuf; - - /* If the file should be created now, create it and write the new data - ** into the file on disk. */ - if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){ - int rc = memjrnlCreateFile(p); - if( rc==SQLITE_OK ){ - rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst); - } - return rc; - } - - /* If the contents of this write should be stored in memory */ - else{ - /* An in-memory journal file should only ever be appended to. Random - ** access writes are not required. The only exception to this is when - ** the in-memory journal is being used by a connection using the - ** atomic-write optimization. In this case the first 28 bytes of the - ** journal file may be written as part of committing the transaction. */ - assert( iOfst==p->endpoint.iOffset || iOfst==0 ); -#ifdef SQLITE_ENABLE_ATOMIC_WRITE - if( iOfst==0 && p->pFirst ){ - assert( p->nChunkSize>iAmt ); - memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); - }else -#else - assert( iOfst>0 || p->pFirst==0 ); -#endif - { - while( nWrite>0 ){ - FileChunk *pChunk = p->endpoint.pChunk; - int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize); - int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset); - - if( iChunkOffset==0 ){ - /* New chunk is required to extend the file. */ - FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); - if( !pNew ){ - return SQLITE_IOERR_NOMEM_BKPT; - } - pNew->pNext = 0; - if( pChunk ){ - assert( p->pFirst ); - pChunk->pNext = pNew; - }else{ - assert( !p->pFirst ); - p->pFirst = pNew; - } - p->endpoint.pChunk = pNew; - } - - memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace); - zWrite += iSpace; - nWrite -= iSpace; - p->endpoint.iOffset += iSpace; - } - p->nSize = iAmt + iOfst; - } - } - - return SQLITE_OK; -} - -/* -** Truncate the file. -** -** If the journal file is already on disk, truncate it there. Or, if it -** is still in main memory but is being truncated to zero bytes in size, -** ignore -*/ -static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ - MemJournal *p = (MemJournal *)pJfd; - if( ALWAYS(size==0) ){ - memjrnlFreeChunks(p); - p->nSize = 0; - p->endpoint.pChunk = 0; - p->endpoint.iOffset = 0; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; - } - return SQLITE_OK; -} - -/* -** Close the file. -*/ -static int memjrnlClose(sqlite3_file *pJfd){ - MemJournal *p = (MemJournal *)pJfd; - memjrnlFreeChunks(p); - return SQLITE_OK; -} - -/* -** Sync the file. -** -** If the real file has been created, call its xSync method. Otherwise, -** syncing an in-memory journal is a no-op. -*/ -static int memjrnlSync(sqlite3_file *pJfd, int flags){ - UNUSED_PARAMETER2(pJfd, flags); - return SQLITE_OK; -} - -/* -** Query the size of the file in bytes. -*/ -static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ - MemJournal *p = (MemJournal *)pJfd; - *pSize = (sqlite_int64) p->endpoint.iOffset; - return SQLITE_OK; -} - -/* -** Table of methods for MemJournal sqlite3_file object. -*/ -static const struct sqlite3_io_methods MemJournalMethods = { - 1, /* iVersion */ - memjrnlClose, /* xClose */ - memjrnlRead, /* xRead */ - memjrnlWrite, /* xWrite */ - memjrnlTruncate, /* xTruncate */ - memjrnlSync, /* xSync */ - memjrnlFileSize, /* xFileSize */ - 0, /* xLock */ - 0, /* xUnlock */ - 0, /* xCheckReservedLock */ - 0, /* xFileControl */ - 0, /* xSectorSize */ - 0, /* xDeviceCharacteristics */ - 0, /* xShmMap */ - 0, /* xShmLock */ - 0, /* xShmBarrier */ - 0, /* xShmUnmap */ - 0, /* xFetch */ - 0 /* xUnfetch */ -}; - -/* -** Open a journal file. -** -** The behaviour of the journal file depends on the value of parameter -** nSpill. If nSpill is 0, then the journal file is always create and -** accessed using the underlying VFS. If nSpill is less than zero, then -** all content is always stored in main-memory. Finally, if nSpill is a -** positive value, then the journal file is initially created in-memory -** but may be flushed to disk later on. In this case the journal file is -** flushed to disk either when it grows larger than nSpill bytes in size, -** or when sqlite3JournalCreate() is called. -*/ -SQLITE_PRIVATE int sqlite3JournalOpen( - sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ - const char *zName, /* Name of the journal file */ - sqlite3_file *pJfd, /* Preallocated, blank file handle */ - int flags, /* Opening flags */ - int nSpill /* Bytes buffered before opening the file */ -){ - MemJournal *p = (MemJournal*)pJfd; - - /* Zero the file-handle object. If nSpill was passed zero, initialize - ** it using the sqlite3OsOpen() function of the underlying VFS. In this - ** case none of the code in this module is executed as a result of calls - ** made on the journal file-handle. */ - memset(p, 0, sizeof(MemJournal)); - if( nSpill==0 ){ - return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); - } - - if( nSpill>0 ){ - p->nChunkSize = nSpill; - }else{ - p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk); - assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) ); - } - - p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods; - p->nSpill = nSpill; - p->flags = flags; - p->zJournal = zName; - p->pVfs = pVfs; - return SQLITE_OK; -} - -/* -** Open an in-memory journal file. -*/ -SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ - sqlite3JournalOpen(0, 0, pJfd, 0, -1); -} - -#ifdef SQLITE_ENABLE_ATOMIC_WRITE -/* -** If the argument p points to a MemJournal structure that is not an -** in-memory-only journal file (i.e. is one that was opened with a +ve -** nSpill parameter), and the underlying file has not yet been created, -** create it now. -*/ -SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){ - int rc = SQLITE_OK; - if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){ - rc = memjrnlCreateFile((MemJournal*)p); - } - return rc; -} -#endif - -/* -** The file-handle passed as the only argument is open on a journal file. -** Return true if this "journal file" is currently stored in heap memory, -** or false otherwise. -*/ -SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){ - return p->pMethods==&MemJournalMethods; -} - -/* -** Return the number of bytes required to store a JournalFile that uses vfs -** pVfs to create the underlying on-disk files. -*/ -SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ - return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); -} - -/************** End of memjournal.c ******************************************/ -/************** Begin file walker.c ******************************************/ -/* -** 2008 August 16 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains routines used for walking the parser tree for -** an SQL statement. -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include */ - - -/* -** Walk an expression tree. Invoke the callback once for each node -** of the expression, while descending. (In other words, the callback -** is invoked before visiting children.) -** -** The return value from the callback should be one of the WRC_* -** constants to specify how to proceed with the walk. -** -** WRC_Continue Continue descending down the tree. -** -** WRC_Prune Do not descend into child nodes. But allow -** the walk to continue with sibling nodes. -** -** WRC_Abort Do no more callbacks. Unwind the stack and -** return the top-level walk call. -** -** The return value from this routine is WRC_Abort to abandon the tree walk -** and WRC_Continue to continue. -*/ -static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ - int rc; - testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); - testcase( ExprHasProperty(pExpr, EP_Reduced) ); - rc = pWalker->xExprCallback(pWalker, pExpr); - if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - return rc & WRC_Abort; - } - if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; - if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else if( pExpr->x.pList ){ - if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; - } - return WRC_Continue; -} -SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ - return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; -} - -/* -** Call sqlite3WalkExpr() for every expression in list p or until -** an abort request is seen. -*/ -SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ - int i; - struct ExprList_item *pItem; - if( p ){ - for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ - if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; - } - } - return WRC_Continue; -} - -/* -** Walk all expressions associated with SELECT statement p. Do -** not invoke the SELECT callback on p, but do (of course) invoke -** any expr callbacks and SELECT callbacks that come from subqueries. -** Return WRC_Abort or WRC_Continue. -*/ -SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ - if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; - if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; - if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort; - return WRC_Continue; -} - -/* -** Walk the parse trees associated with all subqueries in the -** FROM clause of SELECT statement p. Do not invoke the select -** callback on p, but do invoke it on each FROM clause subquery -** and on any subqueries further down in the tree. Return -** WRC_Abort or WRC_Continue; -*/ -SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ - SrcList *pSrc; - int i; - struct SrcList_item *pItem; - - pSrc = p->pSrc; - if( ALWAYS(pSrc) ){ - for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ - return WRC_Abort; - } - if( pItem->fg.isTabFunc - && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) - ){ - return WRC_Abort; - } - } - } - return WRC_Continue; -} - -/* -** Call sqlite3WalkExpr() for every expression in Select statement p. -** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and -** on the compound select chain, p->pPrior. -** -** If it is not NULL, the xSelectCallback() callback is invoked before -** the walk of the expressions and FROM clause. The xSelectCallback2() -** method, if it is not NULL, is invoked following the walk of the -** expressions and FROM clause. -** -** Return WRC_Continue under normal conditions. Return WRC_Abort if -** there is an abort request. -** -** If the Walker does not have an xSelectCallback() then this routine -** is a no-op returning WRC_Continue. -*/ -SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ - int rc; - if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){ - return WRC_Continue; - } - rc = WRC_Continue; - pWalker->walkerDepth++; - while( p ){ - if( pWalker->xSelectCallback ){ - rc = pWalker->xSelectCallback(pWalker, p); - if( rc ) break; - } - if( sqlite3WalkSelectExpr(pWalker, p) - || sqlite3WalkSelectFrom(pWalker, p) - ){ - pWalker->walkerDepth--; - return WRC_Abort; - } - if( pWalker->xSelectCallback2 ){ - pWalker->xSelectCallback2(pWalker, p); - } - p = p->pPrior; - } - pWalker->walkerDepth--; - return rc & WRC_Abort; -} - -/************** End of walker.c **********************************************/ -/************** Begin file resolve.c *****************************************/ -/* -** 2008 August 18 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains routines used for walking the parser tree and -** resolve all identifiers by associating them with a particular -** table and column. -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include */ - -/* -** Walk the expression tree pExpr and increase the aggregate function -** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. -** This needs to occur when copying a TK_AGG_FUNCTION node from an -** outer query into an inner subquery. -** -** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) -** is a helper function - a callback for the tree walker. -*/ -static int incrAggDepth(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; - return WRC_Continue; -} -static void incrAggFunctionDepth(Expr *pExpr, int N){ - if( N>0 ){ - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = incrAggDepth; - w.u.n = N; - sqlite3WalkExpr(&w, pExpr); - } -} - -/* -** Turn the pExpr expression into an alias for the iCol-th column of the -** result set in pEList. -** -** If the reference is followed by a COLLATE operator, then make sure -** the COLLATE operator is preserved. For example: -** -** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; -** -** Should be transformed into: -** -** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; -** -** The nSubquery parameter specifies how many levels of subquery the -** alias is removed from the original expression. The usual value is -** zero but it might be more if the alias is contained within a subquery -** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION -** structures must be increased by the nSubquery amount. -*/ -static void resolveAlias( - Parse *pParse, /* Parsing context */ - ExprList *pEList, /* A result set */ - int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ - Expr *pExpr, /* Transform this into an alias to the result set */ - const char *zType, /* "GROUP" or "ORDER" or "" */ - int nSubquery /* Number of subqueries that the label is moving */ -){ - Expr *pOrig; /* The iCol-th column of the result set */ - Expr *pDup; /* Copy of pOrig */ - sqlite3 *db; /* The database connection */ - - assert( iCol>=0 && iColnExpr ); - pOrig = pEList->a[iCol].pExpr; - assert( pOrig!=0 ); - db = pParse->db; - pDup = sqlite3ExprDup(db, pOrig, 0); - if( pDup==0 ) return; - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); - if( pExpr->op==TK_COLLATE ){ - pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); - } - ExprSetProperty(pDup, EP_Alias); - - /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This - ** prevents ExprDelete() from deleting the Expr structure itself, - ** allowing it to be repopulated by the memcpy() on the following line. - ** The pExpr->u.zToken might point into memory that will be freed by the - ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to - ** make a copy of the token before doing the sqlite3DbFree(). - */ - ExprSetProperty(pExpr, EP_Static); - sqlite3ExprDelete(db, pExpr); - memcpy(pExpr, pDup, sizeof(*pExpr)); - if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ - assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); - pExpr->flags |= EP_MemToken; - } - sqlite3DbFree(db, pDup); -} - - -/* -** Return TRUE if the name zCol occurs anywhere in the USING clause. -** -** Return FALSE if the USING clause is NULL or if it does not contain -** zCol. -*/ -static int nameInUsingClause(IdList *pUsing, const char *zCol){ - if( pUsing ){ - int k; - for(k=0; knId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; - } - } - return 0; -} - -/* -** Subqueries stores the original database, table and column names for their -** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". -** Check to see if the zSpan given to this routine matches the zDb, zTab, -** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will -** match anything. -*/ -SQLITE_PRIVATE int sqlite3MatchSpanName( - const char *zSpan, - const char *zCol, - const char *zTab, - const char *zDb -){ - int n; - for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} - if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ - return 0; - } - zSpan += n+1; - for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} - if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ - return 0; - } - zSpan += n+1; - if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ - return 0; - } - return 1; -} - -/* -** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up -** that name in the set of source tables in pSrcList and make the pExpr -** expression node refer back to that source column. The following changes -** are made to pExpr: -** -** pExpr->iDb Set the index in db->aDb[] of the database X -** (even if X is implied). -** pExpr->iTable Set to the cursor number for the table obtained -** from pSrcList. -** pExpr->pTab Points to the Table structure of X.Y (even if -** X and/or Y are implied.) -** pExpr->iColumn Set to the column number within the table. -** pExpr->op Set to TK_COLUMN. -** pExpr->pLeft Any expression this points to is deleted -** pExpr->pRight Any expression this points to is deleted. -** -** The zDb variable is the name of the database (the "X"). This value may be -** NULL meaning that name is of the form Y.Z or Z. Any available database -** can be used. The zTable variable is the name of the table (the "Y"). This -** value can be NULL if zDb is also NULL. If zTable is NULL it -** means that the form of the name is Z and that columns from any table -** can be used. -** -** If the name cannot be resolved unambiguously, leave an error message -** in pParse and return WRC_Abort. Return WRC_Prune on success. -*/ -static int lookupName( - Parse *pParse, /* The parsing context */ - const char *zDb, /* Name of the database containing table, or NULL */ - const char *zTab, /* Name of table containing column, or NULL */ - const char *zCol, /* Name of the column. */ - NameContext *pNC, /* The name context used to resolve the name */ - Expr *pExpr /* Make this EXPR node point to the selected column */ -){ - int i, j; /* Loop counters */ - int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of matching table names */ - int nSubquery = 0; /* How many levels of subquery */ - sqlite3 *db = pParse->db; /* The database connection */ - struct SrcList_item *pItem; /* Use for looping over pSrcList items */ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ - NameContext *pTopNC = pNC; /* First namecontext in the list */ - Schema *pSchema = 0; /* Schema of the expression */ - int isTrigger = 0; /* True if resolved to a trigger column */ - Table *pTab = 0; /* Table hold the row */ - Column *pCol; /* A column of pTab */ - - assert( pNC ); /* the name context cannot be NULL. */ - assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ - assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); - - /* Initialize the node to no-match */ - pExpr->iTable = -1; - pExpr->pTab = 0; - ExprSetVVAProperty(pExpr, EP_NoReduce); - - /* Translate the schema name in zDb into a pointer to the corresponding - ** schema. If not found, pSchema will remain NULL and nothing will match - ** resulting in an appropriate error message toward the end of this routine - */ - if( zDb ){ - testcase( pNC->ncFlags & NC_PartIdx ); - testcase( pNC->ncFlags & NC_IsCheck ); - if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ - /* Silently ignore database qualifiers inside CHECK constraints and - ** partial indices. Do not raise errors because that might break - ** legacy and because it does not hurt anything to just ignore the - ** database name. */ - zDb = 0; - }else{ - for(i=0; inDb; i++){ - assert( db->aDb[i].zDbSName ); - if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ - pSchema = db->aDb[i].pSchema; - break; - } - } - } - } - - /* Start at the inner-most context and move outward until a match is found */ - while( pNC && cnt==0 ){ - ExprList *pEList; - SrcList *pSrcList = pNC->pSrcList; - - if( pSrcList ){ - for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ - pTab = pItem->pTab; - assert( pTab!=0 && pTab->zName!=0 ); - assert( pTab->nCol>0 ); - if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ - int hit = 0; - pEList = pItem->pSelect->pEList; - for(j=0; jnExpr; j++){ - if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){ - cnt++; - cntTab = 2; - pMatch = pItem; - pExpr->iColumn = j; - hit = 1; - } - } - if( hit || zTab==0 ) continue; - } - if( zDb && pTab->pSchema!=pSchema ){ - continue; - } - if( zTab ){ - const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; - assert( zTabName!=0 ); - if( sqlite3StrICmp(zTabName, zTab)!=0 ){ - continue; - } - } - if( 0==(cntTab++) ){ - pMatch = pItem; - } - for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - /* If there has been exactly one prior match and this match - ** is for the right-hand table of a NATURAL JOIN or is in a - ** USING clause, then skip this match. - */ - if( cnt==1 ){ - if( pItem->fg.jointype & JT_NATURAL ) continue; - if( nameInUsingClause(pItem->pUsing, zCol) ) continue; - } - cnt++; - pMatch = pItem; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; - break; - } - } - } - if( pMatch ){ - pExpr->iTable = pMatch->iCursor; - pExpr->pTab = pMatch->pTab; - /* RIGHT JOIN not (yet) supported */ - assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); - if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ - ExprSetProperty(pExpr, EP_CanBeNull); - } - pSchema = pExpr->pTab->pSchema; - } - } /* if( pSrcList ) */ - -#ifndef SQLITE_OMIT_TRIGGER - /* If we have not already resolved the name, then maybe - ** it is a new.* or old.* trigger argument reference - */ - if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){ - int op = pParse->eTriggerOp; - assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ - pExpr->iTable = 1; - pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ - pExpr->iTable = 0; - pTab = pParse->pTriggerTab; - }else{ - pTab = 0; - } - - if( pTab ){ - int iCol; - pSchema = pTab->pSchema; - cntTab++; - for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - if( iCol==pTab->iPKey ){ - iCol = -1; - } - break; - } - } - if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ - /* IMP: R-51414-32910 */ - iCol = -1; - } - if( iColnCol ){ - cnt++; - if( iCol<0 ){ - pExpr->affinity = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iColumn = (i16)iCol; - pExpr->pTab = pTab; - isTrigger = 1; - } - } - } -#endif /* !defined(SQLITE_OMIT_TRIGGER) */ - - /* - ** Perhaps the name is a reference to the ROWID - */ - if( cnt==0 - && cntTab==1 - && pMatch - && (pNC->ncFlags & NC_IdxExpr)==0 - && sqlite3IsRowid(zCol) - && VisibleRowid(pMatch->pTab) - ){ - cnt = 1; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; - } - - /* - ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z - ** might refer to an result-set alias. This happens, for example, when - ** we are resolving names in the WHERE clause of the following command: - ** - ** SELECT a+b AS x FROM table WHERE x<10; - ** - ** In cases like this, replace pExpr with a copy of the expression that - ** forms the result set entry ("a+b" in the example) and return immediately. - ** Note that the expression in the result set should have already been - ** resolved by the time the WHERE clause is resolved. - ** - ** The ability to use an output result-set column in the WHERE, GROUP BY, - ** or HAVING clauses, or as part of a larger expression in the ORDER BY - ** clause is not standard SQL. This is a (goofy) SQLite extension, that - ** is supported for backwards compatibility only. Hence, we issue a warning - ** on sqlite3_log() whenever the capability is used. - */ - if( (pEList = pNC->pEList)!=0 - && zTab==0 - && cnt==0 - ){ - for(j=0; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - Expr *pOrig; - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - assert( pExpr->x.pList==0 ); - assert( pExpr->x.pSelect==0 ); - pOrig = pEList->a[j].pExpr; - if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ - sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); - return WRC_Abort; - } - resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); - cnt = 1; - pMatch = 0; - assert( zTab==0 && zDb==0 ); - goto lookupname_end; - } - } - } - - /* Advance to the next name context. The loop will exit when either - ** we have a match (cnt>0) or when we run out of name contexts. - */ - if( cnt==0 ){ - pNC = pNC->pNext; - nSubquery++; - } - } - - /* - ** If X and Y are NULL (in other words if only the column name Z is - ** supplied) and the value of Z is enclosed in double-quotes, then - ** Z is a string literal if it doesn't match any column names. In that - ** case, we need to return right away and not make any changes to - ** pExpr. - ** - ** Because no reference was made to outer contexts, the pNC->nRef - ** fields are not changed in any context. - */ - if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ - pExpr->op = TK_STRING; - pExpr->pTab = 0; - return WRC_Prune; - } - - /* - ** cnt==0 means there was not match. cnt>1 means there were two or - ** more matches. Either way, we have an error. - */ - if( cnt!=1 ){ - const char *zErr; - zErr = cnt==0 ? "no such column" : "ambiguous column name"; - if( zDb ){ - sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); - }else if( zTab ){ - sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); - }else{ - sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); - } - pParse->checkSchema = 1; - pTopNC->nErr++; - } - - /* If a column from a table in pSrcList is referenced, then record - ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes - ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the - ** column number is greater than the number of bits in the bitmask - ** then set the high-order bit of the bitmask. - */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ - int n = pExpr->iColumn; - testcase( n==BMS-1 ); - if( n>=BMS ){ - n = BMS-1; - } - assert( pMatch->iCursor==pExpr->iTable ); - pMatch->colUsed |= ((Bitmask)1)<pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); -lookupname_end: - if( cnt==1 ){ - assert( pNC!=0 ); - if( !ExprHasProperty(pExpr, EP_Alias) ){ - sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); - } - /* Increment the nRef value on all name contexts from TopNC up to - ** the point where the name matched. */ - for(;;){ - assert( pTopNC!=0 ); - pTopNC->nRef++; - if( pTopNC==pNC ) break; - pTopNC = pTopNC->pNext; - } - return WRC_Prune; - } else { - return WRC_Abort; - } -} - -/* -** Allocate and return a pointer to an expression to load the column iCol -** from datasource iSrc in SrcList pSrc. -*/ -SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ - Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); - if( p ){ - struct SrcList_item *pItem = &pSrc->a[iSrc]; - p->pTab = pItem->pTab; - p->iTable = pItem->iCursor; - if( p->pTab->iPKey==iCol ){ - p->iColumn = -1; - }else{ - p->iColumn = (ynVar)iCol; - testcase( iCol==BMS ); - testcase( iCol==BMS-1 ); - pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); - } - ExprSetProperty(p, EP_Resolved); - } - return p; -} - -/* -** Report an error that an expression is not valid for some set of -** pNC->ncFlags values determined by validMask. -*/ -static void notValid( - Parse *pParse, /* Leave error message here */ - NameContext *pNC, /* The name context */ - const char *zMsg, /* Type of error */ - int validMask /* Set of contexts for which prohibited */ -){ - assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 ); - if( (pNC->ncFlags & validMask)!=0 ){ - const char *zIn = "partial index WHERE clauses"; - if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; -#ifndef SQLITE_OMIT_CHECK - else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; -#endif - sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); - } -} - -/* -** Expression p should encode a floating point value between 1.0 and 0.0. -** Return 1024 times this value. Or return -1 if p is not a floating point -** value between 1.0 and 0.0. -*/ -static int exprProbability(Expr *p){ - double r = -1.0; - if( p->op!=TK_FLOAT ) return -1; - sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); - assert( r>=0.0 ); - if( r>1.0 ) return -1; - return (int)(r*134217728.0); -} - -/* -** This routine is callback for sqlite3WalkExpr(). -** -** Resolve symbolic names into TK_COLUMN operators for the current -** node in the expression tree. Return 0 to continue the search down -** the tree or 2 to abort the tree walk. -** -** This routine also does error checking and name resolution for -** function names. The operator for aggregate functions is changed -** to TK_AGG_FUNCTION. -*/ -static int resolveExprStep(Walker *pWalker, Expr *pExpr){ - NameContext *pNC; - Parse *pParse; - - pNC = pWalker->u.pNC; - assert( pNC!=0 ); - pParse = pNC->pParse; - assert( pParse==pWalker->pParse ); - - if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune; - ExprSetProperty(pExpr, EP_Resolved); -#ifndef NDEBUG - if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ - SrcList *pSrcList = pNC->pSrcList; - int i; - for(i=0; ipSrcList->nSrc; i++){ - assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); - } - } -#endif - switch( pExpr->op ){ - -#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) - /* The special operator TK_ROW means use the rowid for the first - ** column in the FROM clause. This is used by the LIMIT and ORDER BY - ** clause processing on UPDATE and DELETE statements. - */ - case TK_ROW: { - SrcList *pSrcList = pNC->pSrcList; - struct SrcList_item *pItem; - assert( pSrcList && pSrcList->nSrc==1 ); - pItem = pSrcList->a; - pExpr->op = TK_COLUMN; - pExpr->pTab = pItem->pTab; - pExpr->iTable = pItem->iCursor; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; - break; - } -#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) - && !defined(SQLITE_OMIT_SUBQUERY) */ - - /* A lone identifier is the name of a column. - */ - case TK_ID: { - return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); - } - - /* A table name and column name: ID.ID - ** Or a database, table and column: ID.ID.ID - */ - case TK_DOT: { - const char *zColumn; - const char *zTable; - const char *zDb; - Expr *pRight; - - /* if( pSrcList==0 ) break; */ - notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); - pRight = pExpr->pRight; - if( pRight->op==TK_ID ){ - zDb = 0; - zTable = pExpr->pLeft->u.zToken; - zColumn = pRight->u.zToken; - }else{ - assert( pRight->op==TK_DOT ); - zDb = pExpr->pLeft->u.zToken; - zTable = pRight->pLeft->u.zToken; - zColumn = pRight->pRight->u.zToken; - } - return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); - } - - /* Resolve function names - */ - case TK_FUNCTION: { - ExprList *pList = pExpr->x.pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ - int no_such_func = 0; /* True if no such function exists */ - int wrong_num_args = 0; /* True if wrong number of arguments */ - int is_agg = 0; /* True if is an aggregate function */ - int nId; /* Number of characters in function name */ - const char *zId; /* The function name. */ - FuncDef *pDef; /* Information about the function */ - u8 enc = ENC(pParse->db); /* The database encoding */ - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - zId = pExpr->u.zToken; - nId = sqlite3Strlen30(zId); - pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); - if( pDef==0 ){ - pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); - if( pDef==0 ){ - no_such_func = 1; - }else{ - wrong_num_args = 1; - } - }else{ - is_agg = pDef->xFinalize!=0; - if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ - ExprSetProperty(pExpr, EP_Unlikely|EP_Skip); - if( n==2 ){ - pExpr->iTable = exprProbability(pList->a[1].pExpr); - if( pExpr->iTable<0 ){ - sqlite3ErrorMsg(pParse, - "second argument to likelihood() must be a " - "constant between 0.0 and 1.0"); - pNC->nErr++; - } - }else{ - /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is - ** equivalent to likelihood(X, 0.0625). - ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is - ** short-hand for likelihood(X,0.0625). - ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand - ** for likelihood(X,0.9375). - ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent - ** to likelihood(X,0.9375). */ - /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ - pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; - } - } -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); - if( auth!=SQLITE_OK ){ - if( auth==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized to use function: %s", - pDef->zName); - pNC->nErr++; - } - pExpr->op = TK_NULL; - return WRC_Prune; - } - } -#endif - if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ - /* For the purposes of the EP_ConstFunc flag, date and time - ** functions and other functions that change slowly are considered - ** constant because they are constant for the duration of one query */ - ExprSetProperty(pExpr,EP_ConstFunc); - } - if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ - /* Date/time functions that use 'now', and other functions like - ** sqlite_version() that might change over time cannot be used - ** in an index. */ - notValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx); - } - } - if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); - pNC->nErr++; - is_agg = 0; - }else if( no_such_func && pParse->db->init.busy==0 -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - && pParse->explain==0 -#endif - ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - pNC->nErr++; - } - if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; - sqlite3WalkExprList(pWalker, pList); - if( is_agg ){ - NameContext *pNC2 = pNC; - pExpr->op = TK_AGG_FUNCTION; - pExpr->op2 = 0; - while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ - pExpr->op2++; - pNC2 = pNC2->pNext; - } - assert( pDef!=0 ); - if( pNC2 ){ - assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); - testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); - pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); - - } - pNC->ncFlags |= NC_AllowAgg; - } - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function - */ - return WRC_Prune; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: - case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); -#endif - case TK_IN: { - testcase( pExpr->op==TK_IN ); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - int nRef = pNC->nRef; - notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr); - sqlite3WalkSelect(pWalker, pExpr->x.pSelect); - assert( pNC->nRef>=nRef ); - if( nRef!=pNC->nRef ){ - ExprSetProperty(pExpr, EP_VarSelect); - pNC->ncFlags |= NC_VarSelect; - } - } - break; - } - case TK_VARIABLE: { - notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); - break; - } - case TK_EQ: - case TK_NE: - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_IS: - case TK_ISNOT: { - int nLeft, nRight; - if( pParse->db->mallocFailed ) break; - assert( pExpr->pRight!=0 ); - assert( pExpr->pLeft!=0 ); - nLeft = sqlite3ExprVectorSize(pExpr->pLeft); - nRight = sqlite3ExprVectorSize(pExpr->pRight); - if( nLeft!=nRight ){ - testcase( pExpr->op==TK_EQ ); - testcase( pExpr->op==TK_NE ); - testcase( pExpr->op==TK_LT ); - testcase( pExpr->op==TK_LE ); - testcase( pExpr->op==TK_GT ); - testcase( pExpr->op==TK_GE ); - testcase( pExpr->op==TK_IS ); - testcase( pExpr->op==TK_ISNOT ); - sqlite3ErrorMsg(pParse, "row value misused"); - } - break; - } - } - return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; -} - -/* -** pEList is a list of expressions which are really the result set of the -** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. -** This routine checks to see if pE is a simple identifier which corresponds -** to the AS-name of one of the terms of the expression list. If it is, -** this routine return an integer between 1 and N where N is the number of -** elements in pEList, corresponding to the matching entry. If there is -** no match, or if pE is not a simple identifier, then this routine -** return 0. -** -** pEList has been resolved. pE has not. -*/ -static int resolveAsName( - Parse *pParse, /* Parsing context for error messages */ - ExprList *pEList, /* List of expressions to scan */ - Expr *pE /* Expression we are trying to match */ -){ - int i; /* Loop counter */ - - UNUSED_PARAMETER(pParse); - - if( pE->op==TK_ID ){ - char *zCol = pE->u.zToken; - for(i=0; inExpr; i++){ - char *zAs = pEList->a[i].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - return i+1; - } - } - } - return 0; -} - -/* -** pE is a pointer to an expression which is a single term in the -** ORDER BY of a compound SELECT. The expression has not been -** name resolved. -** -** At the point this routine is called, we already know that the -** ORDER BY term is not an integer index into the result set. That -** case is handled by the calling routine. -** -** Attempt to match pE against result set columns in the left-most -** SELECT statement. Return the index i of the matching column, -** as an indication to the caller that it should sort by the i-th column. -** The left-most column is 1. In other words, the value returned is the -** same integer value that would be used in the SQL statement to indicate -** the column. -** -** If there is no match, return 0. Return -1 if an error occurs. -*/ -static int resolveOrderByTermToExprList( - Parse *pParse, /* Parsing context for error messages */ - Select *pSelect, /* The SELECT statement with the ORDER BY clause */ - Expr *pE /* The specific ORDER BY term */ -){ - int i; /* Loop counter */ - ExprList *pEList; /* The columns of the result set */ - NameContext nc; /* Name context for resolving pE */ - sqlite3 *db; /* Database connection */ - int rc; /* Return code from subprocedures */ - u8 savedSuppErr; /* Saved value of db->suppressErr */ - - assert( sqlite3ExprIsInteger(pE, &i)==0 ); - pEList = pSelect->pEList; - - /* Resolve all names in the ORDER BY term expression - */ - memset(&nc, 0, sizeof(nc)); - nc.pParse = pParse; - nc.pSrcList = pSelect->pSrc; - nc.pEList = pEList; - nc.ncFlags = NC_AllowAgg; - nc.nErr = 0; - db = pParse->db; - savedSuppErr = db->suppressErr; - db->suppressErr = 1; - rc = sqlite3ResolveExprNames(&nc, pE); - db->suppressErr = savedSuppErr; - if( rc ) return 0; - - /* Try to match the ORDER BY expression against an expression - ** in the result set. Return an 1-based index of the matching - ** result-set entry. - */ - for(i=0; inExpr; i++){ - if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){ - return i+1; - } - } - - /* If no match, return 0. */ - return 0; -} - -/* -** Generate an ORDER BY or GROUP BY term out-of-range error. -*/ -static void resolveOutOfRangeError( - Parse *pParse, /* The error context into which to write the error */ - const char *zType, /* "ORDER" or "GROUP" */ - int i, /* The index (1-based) of the term out of range */ - int mx /* Largest permissible value of i */ -){ - sqlite3ErrorMsg(pParse, - "%r %s BY term out of range - should be " - "between 1 and %d", i, zType, mx); -} - -/* -** Analyze the ORDER BY clause in a compound SELECT statement. Modify -** each term of the ORDER BY clause is a constant integer between 1 -** and N where N is the number of columns in the compound SELECT. -** -** ORDER BY terms that are already an integer between 1 and N are -** unmodified. ORDER BY terms that are integers outside the range of -** 1 through N generate an error. ORDER BY terms that are expressions -** are matched against result set expressions of compound SELECT -** beginning with the left-most SELECT and working toward the right. -** At the first match, the ORDER BY expression is transformed into -** the integer column number. -** -** Return the number of errors seen. -*/ -static int resolveCompoundOrderBy( - Parse *pParse, /* Parsing context. Leave error messages here */ - Select *pSelect /* The SELECT statement containing the ORDER BY */ -){ - int i; - ExprList *pOrderBy; - ExprList *pEList; - sqlite3 *db; - int moreToDo = 1; - - pOrderBy = pSelect->pOrderBy; - if( pOrderBy==0 ) return 0; - db = pParse->db; -#if SQLITE_MAX_COLUMN - if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); - return 1; - } -#endif - for(i=0; inExpr; i++){ - pOrderBy->a[i].done = 0; - } - pSelect->pNext = 0; - while( pSelect->pPrior ){ - pSelect->pPrior->pNext = pSelect; - pSelect = pSelect->pPrior; - } - while( pSelect && moreToDo ){ - struct ExprList_item *pItem; - moreToDo = 0; - pEList = pSelect->pEList; - assert( pEList!=0 ); - for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - int iCol = -1; - Expr *pE, *pDup; - if( pItem->done ) continue; - pE = sqlite3ExprSkipCollate(pItem->pExpr); - if( sqlite3ExprIsInteger(pE, &iCol) ){ - if( iCol<=0 || iCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); - return 1; - } - }else{ - iCol = resolveAsName(pParse, pEList, pE); - if( iCol==0 ){ - pDup = sqlite3ExprDup(db, pE, 0); - if( !db->mallocFailed ){ - assert(pDup); - iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); - } - sqlite3ExprDelete(db, pDup); - } - } - if( iCol>0 ){ - /* Convert the ORDER BY term into an integer column number iCol, - ** taking care to preserve the COLLATE clause if it exists */ - Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); - if( pNew==0 ) return 1; - pNew->flags |= EP_IntValue; - pNew->u.iValue = iCol; - if( pItem->pExpr==pE ){ - pItem->pExpr = pNew; - }else{ - Expr *pParent = pItem->pExpr; - assert( pParent->op==TK_COLLATE ); - while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; - assert( pParent->pLeft==pE ); - pParent->pLeft = pNew; - } - sqlite3ExprDelete(db, pE); - pItem->u.x.iOrderByCol = (u16)iCol; - pItem->done = 1; - }else{ - moreToDo = 1; - } - } - pSelect = pSelect->pNext; - } - for(i=0; inExpr; i++){ - if( pOrderBy->a[i].done==0 ){ - sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " - "column in the result set", i+1); - return 1; - } - } - return 0; -} - -/* -** Check every term in the ORDER BY or GROUP BY clause pOrderBy of -** the SELECT statement pSelect. If any term is reference to a -** result set expression (as determined by the ExprList.a.u.x.iOrderByCol -** field) then convert that term into a copy of the corresponding result set -** column. -** -** If any errors are detected, add an error message to pParse and -** return non-zero. Return zero if no errors are seen. -*/ -SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( - Parse *pParse, /* Parsing context. Leave error messages here */ - Select *pSelect, /* The SELECT statement containing the clause */ - ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ - const char *zType /* "ORDER" or "GROUP" */ -){ - int i; - sqlite3 *db = pParse->db; - ExprList *pEList; - struct ExprList_item *pItem; - - if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; -#if SQLITE_MAX_COLUMN - if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); - return 1; - } -#endif - pEList = pSelect->pEList; - assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ - for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - if( pItem->u.x.iOrderByCol ){ - if( pItem->u.x.iOrderByCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); - return 1; - } - resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, - zType,0); - } - } - return 0; -} - -/* -** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. -** The Name context of the SELECT statement is pNC. zType is either -** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. -** -** This routine resolves each term of the clause into an expression. -** If the order-by term is an integer I between 1 and N (where N is the -** number of columns in the result set of the SELECT) then the expression -** in the resolution is a copy of the I-th result-set expression. If -** the order-by term is an identifier that corresponds to the AS-name of -** a result-set expression, then the term resolves to a copy of the -** result-set expression. Otherwise, the expression is resolved in -** the usual way - using sqlite3ResolveExprNames(). -** -** This routine returns the number of errors. If errors occur, then -** an appropriate error message might be left in pParse. (OOM errors -** excepted.) -*/ -static int resolveOrderGroupBy( - NameContext *pNC, /* The name context of the SELECT statement */ - Select *pSelect, /* The SELECT statement holding pOrderBy */ - ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ - const char *zType /* Either "ORDER" or "GROUP", as appropriate */ -){ - int i, j; /* Loop counters */ - int iCol; /* Column number */ - struct ExprList_item *pItem; /* A term of the ORDER BY clause */ - Parse *pParse; /* Parsing context */ - int nResult; /* Number of terms in the result set */ - - if( pOrderBy==0 ) return 0; - nResult = pSelect->pEList->nExpr; - pParse = pNC->pParse; - for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - Expr *pE = pItem->pExpr; - Expr *pE2 = sqlite3ExprSkipCollate(pE); - if( zType[0]!='G' ){ - iCol = resolveAsName(pParse, pSelect->pEList, pE2); - if( iCol>0 ){ - /* If an AS-name match is found, mark this ORDER BY column as being - ** a copy of the iCol-th result-set column. The subsequent call to - ** sqlite3ResolveOrderGroupBy() will convert the expression to a - ** copy of the iCol-th result-set expression. */ - pItem->u.x.iOrderByCol = (u16)iCol; - continue; - } - } - if( sqlite3ExprIsInteger(pE2, &iCol) ){ - /* The ORDER BY term is an integer constant. Again, set the column - ** number so that sqlite3ResolveOrderGroupBy() will convert the - ** order-by term to a copy of the result-set expression */ - if( iCol<1 || iCol>0xffff ){ - resolveOutOfRangeError(pParse, zType, i+1, nResult); - return 1; - } - pItem->u.x.iOrderByCol = (u16)iCol; - continue; - } - - /* Otherwise, treat the ORDER BY term as an ordinary expression */ - pItem->u.x.iOrderByCol = 0; - if( sqlite3ResolveExprNames(pNC, pE) ){ - return 1; - } - for(j=0; jpEList->nExpr; j++){ - if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ - pItem->u.x.iOrderByCol = j+1; - } - } - } - return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); -} - -/* -** Resolve names in the SELECT statement p and all of its descendants. -*/ -static int resolveSelectStep(Walker *pWalker, Select *p){ - NameContext *pOuterNC; /* Context that contains this SELECT */ - NameContext sNC; /* Name context of this SELECT */ - int isCompound; /* True if p is a compound select */ - int nCompound; /* Number of compound terms processed so far */ - Parse *pParse; /* Parsing context */ - int i; /* Loop counter */ - ExprList *pGroupBy; /* The GROUP BY clause */ - Select *pLeftmost; /* Left-most of SELECT of a compound */ - sqlite3 *db; /* Database connection */ - - - assert( p!=0 ); - if( p->selFlags & SF_Resolved ){ - return WRC_Prune; - } - pOuterNC = pWalker->u.pNC; - pParse = pWalker->pParse; - db = pParse->db; - - /* Normally sqlite3SelectExpand() will be called first and will have - ** already expanded this SELECT. However, if this is a subquery within - ** an expression, sqlite3ResolveExprNames() will be called without a - ** prior call to sqlite3SelectExpand(). When that happens, let - ** sqlite3SelectPrep() do all of the processing for this SELECT. - ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and - ** this routine in the correct order. - */ - if( (p->selFlags & SF_Expanded)==0 ){ - sqlite3SelectPrep(pParse, p, pOuterNC); - return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; - } - - isCompound = p->pPrior!=0; - nCompound = 0; - pLeftmost = p; - while( p ){ - assert( (p->selFlags & SF_Expanded)!=0 ); - assert( (p->selFlags & SF_Resolved)==0 ); - p->selFlags |= SF_Resolved; - - /* Resolve the expressions in the LIMIT and OFFSET clauses. These - ** are not allowed to refer to any names, so pass an empty NameContext. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - if( sqlite3ResolveExprNames(&sNC, p->pLimit) || - sqlite3ResolveExprNames(&sNC, p->pOffset) ){ - return WRC_Abort; - } - - /* If the SF_Converted flags is set, then this Select object was - ** was created by the convertCompoundSelectToSubquery() function. - ** In this case the ORDER BY clause (p->pOrderBy) should be resolved - ** as if it were part of the sub-query, not the parent. This block - ** moves the pOrderBy down to the sub-query. It will be moved back - ** after the names have been resolved. */ - if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; - assert( p->pSrc->nSrc==1 && p->pOrderBy ); - assert( pSub->pPrior && pSub->pOrderBy==0 ); - pSub->pOrderBy = p->pOrderBy; - p->pOrderBy = 0; - } - - /* Recursively resolve names in all subqueries - */ - for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; - if( pItem->pSelect ){ - NameContext *pNC; /* Used to iterate name contexts */ - int nRef = 0; /* Refcount for pOuterNC and outer contexts */ - const char *zSavedContext = pParse->zAuthContext; - - /* Count the total number of references to pOuterNC and all of its - ** parent contexts. After resolving references to expressions in - ** pItem->pSelect, check if this value has changed. If so, then - ** SELECT statement pItem->pSelect must be correlated. Set the - ** pItem->fg.isCorrelated flag if this is the case. */ - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; - - if( pItem->zName ) pParse->zAuthContext = pItem->zName; - sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); - pParse->zAuthContext = zSavedContext; - if( pParse->nErr || db->mallocFailed ) return WRC_Abort; - - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; - assert( pItem->fg.isCorrelated==0 && nRef<=0 ); - pItem->fg.isCorrelated = (nRef!=0); - } - } - - /* Set up the local name-context to pass to sqlite3ResolveExprNames() to - ** resolve the result-set expression list. - */ - sNC.ncFlags = NC_AllowAgg; - sNC.pSrcList = p->pSrc; - sNC.pNext = pOuterNC; - - /* Resolve names in the result set. */ - if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; - - /* If there are no aggregate functions in the result-set, and no GROUP BY - ** expression, do not allow aggregates in any of the other expressions. - */ - assert( (p->selFlags & SF_Aggregate)==0 ); - pGroupBy = p->pGroupBy; - if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ - assert( NC_MinMaxAgg==SF_MinMaxAgg ); - p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); - }else{ - sNC.ncFlags &= ~NC_AllowAgg; - } - - /* If a HAVING clause is present, then there must be a GROUP BY clause. - */ - if( p->pHaving && !pGroupBy ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - return WRC_Abort; - } - - /* Add the output column list to the name-context before parsing the - ** other expressions in the SELECT statement. This is so that - ** expressions in the WHERE clause (etc.) can refer to expressions by - ** aliases in the result set. - ** - ** Minor point: If this is the case, then the expression will be - ** re-evaluated for each reference to it. - */ - sNC.pEList = p->pEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; - if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; - - /* Resolve names in table-valued-function arguments */ - for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; - if( pItem->fg.isTabFunc - && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) - ){ - return WRC_Abort; - } - } - - /* The ORDER BY and GROUP BY clauses may not refer to terms in - ** outer queries - */ - sNC.pNext = 0; - sNC.ncFlags |= NC_AllowAgg; - - /* If this is a converted compound query, move the ORDER BY clause from - ** the sub-query back to the parent query. At this point each term - ** within the ORDER BY clause has been transformed to an integer value. - ** These integers will be replaced by copies of the corresponding result - ** set expressions by the call to resolveOrderGroupBy() below. */ - if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; - p->pOrderBy = pSub->pOrderBy; - pSub->pOrderBy = 0; - } - - /* Process the ORDER BY clause for singleton SELECT statements. - ** The ORDER BY clause for compounds SELECT statements is handled - ** below, after all of the result-sets for all of the elements of - ** the compound have been resolved. - ** - ** If there is an ORDER BY clause on a term of a compound-select other - ** than the right-most term, then that is a syntax error. But the error - ** is not detected until much later, and so we need to go ahead and - ** resolve those symbols on the incorrect ORDER BY for consistency. - */ - if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ - && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") - ){ - return WRC_Abort; - } - if( db->mallocFailed ){ - return WRC_Abort; - } - - /* Resolve the GROUP BY clause. At the same time, make sure - ** the GROUP BY clause does not contain aggregate functions. - */ - if( pGroupBy ){ - struct ExprList_item *pItem; - - if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ - return WRC_Abort; - } - for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ - if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ - sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " - "the GROUP BY clause"); - return WRC_Abort; - } - } - } - - /* If this is part of a compound SELECT, check that it has the right - ** number of expressions in the select list. */ - if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ - sqlite3SelectWrongNumTermsError(pParse, p->pNext); - return WRC_Abort; - } - - /* Advance to the next term of the compound - */ - p = p->pPrior; - nCompound++; - } - - /* Resolve the ORDER BY on a compound SELECT after all terms of - ** the compound have been resolved. - */ - if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){ - return WRC_Abort; - } - - return WRC_Prune; -} - -/* -** This routine walks an expression tree and resolves references to -** table columns and result-set columns. At the same time, do error -** checking on function usage and set a flag if any aggregate functions -** are seen. -** -** To resolve table columns references we look for nodes (or subtrees) of the -** form X.Y.Z or Y.Z or just Z where -** -** X: The name of a database. Ex: "main" or "temp" or -** the symbolic name assigned to an ATTACH-ed database. -** -** Y: The name of a table in a FROM clause. Or in a trigger -** one of the special names "old" or "new". -** -** Z: The name of a column in table Y. -** -** The node at the root of the subtree is modified as follows: -** -** Expr.op Changed to TK_COLUMN -** Expr.pTab Points to the Table object for X.Y -** Expr.iColumn The column index in X.Y. -1 for the rowid. -** Expr.iTable The VDBE cursor number for X.Y -** -** -** To resolve result-set references, look for expression nodes of the -** form Z (with no X and Y prefix) where the Z matches the right-hand -** size of an AS clause in the result-set of a SELECT. The Z expression -** is replaced by a copy of the left-hand side of the result-set expression. -** Table-name and function resolution occurs on the substituted expression -** tree. For example, in: -** -** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; -** -** The "x" term of the order by is replaced by "a+b" to render: -** -** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; -** -** Function calls are checked to make sure that the function is -** defined and that the correct number of arguments are specified. -** If the function is an aggregate function, then the NC_HasAgg flag is -** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. -** If an expression contains aggregate functions then the EP_Agg -** property on the expression is set. -** -** An error message is left in pParse if anything is amiss. The number -** if errors is returned. -*/ -SQLITE_PRIVATE int sqlite3ResolveExprNames( - NameContext *pNC, /* Namespace to resolve expressions in. */ - Expr *pExpr /* The expression to be analyzed. */ -){ - u16 savedHasAgg; - Walker w; - - if( pExpr==0 ) return 0; -#if SQLITE_MAX_EXPR_DEPTH>0 - { - Parse *pParse = pNC->pParse; - if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){ - return 1; - } - pParse->nHeight += pExpr->nHeight; - } -#endif - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); - w.pParse = pNC->pParse; - w.xExprCallback = resolveExprStep; - w.xSelectCallback = resolveSelectStep; - w.xSelectCallback2 = 0; - w.walkerDepth = 0; - w.eCode = 0; - w.u.pNC = pNC; - sqlite3WalkExpr(&w, pExpr); -#if SQLITE_MAX_EXPR_DEPTH>0 - pNC->pParse->nHeight -= pExpr->nHeight; -#endif - if( pNC->nErr>0 || w.pParse->nErr>0 ){ - ExprSetProperty(pExpr, EP_Error); - } - if( pNC->ncFlags & NC_HasAgg ){ - ExprSetProperty(pExpr, EP_Agg); - } - pNC->ncFlags |= savedHasAgg; - return ExprHasProperty(pExpr, EP_Error); -} - -/* -** Resolve all names for all expression in an expression list. This is -** just like sqlite3ResolveExprNames() except that it works for an expression -** list rather than a single expression. -*/ -SQLITE_PRIVATE int sqlite3ResolveExprListNames( - NameContext *pNC, /* Namespace to resolve expressions in. */ - ExprList *pList /* The expression list to be analyzed. */ -){ - int i; - if( pList ){ - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; - } - } - return WRC_Continue; -} - -/* -** Resolve all names in all expressions of a SELECT and in all -** decendents of the SELECT, including compounds off of p->pPrior, -** subqueries in expressions, and subqueries used as FROM clause -** terms. -** -** See sqlite3ResolveExprNames() for a description of the kinds of -** transformations that occur. -** -** All SELECT statements should have been expanded using -** sqlite3SelectExpand() prior to invoking this routine. -*/ -SQLITE_PRIVATE void sqlite3ResolveSelectNames( - Parse *pParse, /* The parser context */ - Select *p, /* The SELECT statement being coded. */ - NameContext *pOuterNC /* Name context for parent SELECT statement */ -){ - Walker w; - - assert( p!=0 ); - memset(&w, 0, sizeof(w)); - w.xExprCallback = resolveExprStep; - w.xSelectCallback = resolveSelectStep; - w.pParse = pParse; - w.u.pNC = pOuterNC; - sqlite3WalkSelect(&w, p); -} - -/* -** Resolve names in expressions that can only reference a single table: -** -** * CHECK constraints -** * WHERE clauses on partial indices -** -** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression -** is set to -1 and the Expr.iColumn value is set to the column number. -** -** Any errors cause an error message to be set in pParse. -*/ -SQLITE_PRIVATE void sqlite3ResolveSelfReference( - Parse *pParse, /* Parsing context */ - Table *pTab, /* The table being referenced */ - int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ - Expr *pExpr, /* Expression to resolve. May be NULL. */ - ExprList *pList /* Expression list to resolve. May be NUL. */ -){ - SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ - NameContext sNC; /* Name context for pParse->pNewTable */ - - assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr ); - memset(&sNC, 0, sizeof(sNC)); - memset(&sSrc, 0, sizeof(sSrc)); - sSrc.nSrc = 1; - sSrc.a[0].zName = pTab->zName; - sSrc.a[0].pTab = pTab; - sSrc.a[0].iCursor = -1; - sNC.pParse = pParse; - sNC.pSrcList = &sSrc; - sNC.ncFlags = type; - if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; - if( pList ) sqlite3ResolveExprListNames(&sNC, pList); -} - -/************** End of resolve.c *********************************************/ -/************** Begin file expr.c ********************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains routines used for analyzing expressions and -** for generating VDBE code that evaluates expressions in SQLite. -*/ -/* #include "sqliteInt.h" */ - -/* Forward declarations */ -static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); -static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); - -/* -** Return the affinity character for a single column of a table. -*/ -SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){ - assert( iColnCol ); - return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER; -} - -/* -** Return the 'affinity' of the expression pExpr if any. -** -** If pExpr is a column, a reference to a column via an 'AS' alias, -** or a sub-select with a column as the return value, then the -** affinity of that column is returned. Otherwise, 0x00 is returned, -** indicating no affinity for the expression. -** -** i.e. the WHERE clause expressions in the following statements all -** have an affinity: -** -** CREATE TABLE t1(a); -** SELECT * FROM t1 WHERE a; -** SELECT a AS b FROM t1 WHERE b; -** SELECT * FROM t1 WHERE (select a from t1); -*/ -SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ - int op; - pExpr = sqlite3ExprSkipCollate(pExpr); - if( pExpr->flags & EP_Generic ) return 0; - op = pExpr->op; - if( op==TK_SELECT ){ - assert( pExpr->flags&EP_xIsSelect ); - return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); - } - if( op==TK_REGISTER ) op = pExpr->op2; -#ifndef SQLITE_OMIT_CAST - if( op==TK_CAST ){ - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - return sqlite3AffinityType(pExpr->u.zToken, 0); - } -#endif - if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ - return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); - } - if( op==TK_SELECT_COLUMN ){ - assert( pExpr->pLeft->flags&EP_xIsSelect ); - return sqlite3ExprAffinity( - pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr - ); - } - return pExpr->affinity; -} - -/* -** Set the collating sequence for expression pExpr to be the collating -** sequence named by pToken. Return a pointer to a new Expr node that -** implements the COLLATE operator. -** -** If a memory allocation error occurs, that fact is recorded in pParse->db -** and the pExpr parameter is returned unchanged. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* Add the "COLLATE" clause to this expression */ - const Token *pCollName, /* Name of collating sequence */ - int dequote /* True to dequote pCollName */ -){ - if( pCollName->n>0 ){ - Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); - if( pNew ){ - pNew->pLeft = pExpr; - pNew->flags |= EP_Collate|EP_Skip; - pExpr = pNew; - } - } - return pExpr; -} -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ - Token s; - assert( zC!=0 ); - sqlite3TokenInit(&s, (char*)zC); - return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); -} - -/* -** Skip over any TK_COLLATE operators and any unlikely() -** or likelihood() function at the root of an expression. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ - while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ - if( ExprHasProperty(pExpr, EP_Unlikely) ){ - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - assert( pExpr->x.pList->nExpr>0 ); - assert( pExpr->op==TK_FUNCTION ); - pExpr = pExpr->x.pList->a[0].pExpr; - }else{ - assert( pExpr->op==TK_COLLATE ); - pExpr = pExpr->pLeft; - } - } - return pExpr; -} - -/* -** Return the collation sequence for the expression pExpr. If -** there is no defined collating sequence, return NULL. -** -** The collating sequence might be determined by a COLLATE operator -** or by the presence of a column with a defined collating sequence. -** COLLATE operators take first precedence. Left operands take -** precedence over right operands. -*/ -SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ - sqlite3 *db = pParse->db; - CollSeq *pColl = 0; - Expr *p = pExpr; - while( p ){ - int op = p->op; - if( p->flags & EP_Generic ) break; - if( op==TK_CAST || op==TK_UPLUS ){ - p = p->pLeft; - continue; - } - if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ - pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); - break; - } - if( (op==TK_AGG_COLUMN || op==TK_COLUMN - || op==TK_REGISTER || op==TK_TRIGGER) - && p->pTab!=0 - ){ - /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally - ** a TK_COLUMN but was previously evaluated and cached in a register */ - int j = p->iColumn; - if( j>=0 ){ - const char *zColl = p->pTab->aCol[j].zColl; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); - } - break; - } - if( p->flags & EP_Collate ){ - if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ - p = p->pLeft; - }else{ - Expr *pNext = p->pRight; - /* The Expr.x union is never used at the same time as Expr.pRight */ - assert( p->x.pList==0 || p->pRight==0 ); - /* p->flags holds EP_Collate and p->pLeft->flags does not. And - ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at - ** least one EP_Collate. Thus the following two ALWAYS. */ - if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){ - int i; - for(i=0; ALWAYS(ix.pList->nExpr); i++){ - if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ - pNext = p->x.pList->a[i].pExpr; - break; - } - } - } - p = pNext; - } - }else{ - break; - } - } - if( sqlite3CheckCollSeq(pParse, pColl) ){ - pColl = 0; - } - return pColl; -} - -/* -** pExpr is an operand of a comparison operator. aff2 is the -** type affinity of the other operand. This routine returns the -** type affinity that should be used for the comparison operator. -*/ -SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){ - char aff1 = sqlite3ExprAffinity(pExpr); - if( aff1 && aff2 ){ - /* Both sides of the comparison are columns. If one has numeric - ** affinity, use that. Otherwise use no affinity. - */ - if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ - return SQLITE_AFF_NUMERIC; - }else{ - return SQLITE_AFF_BLOB; - } - }else if( !aff1 && !aff2 ){ - /* Neither side of the comparison is a column. Compare the - ** results directly. - */ - return SQLITE_AFF_BLOB; - }else{ - /* One side is a column, the other is not. Use the columns affinity. */ - assert( aff1==0 || aff2==0 ); - return (aff1 + aff2); - } -} - -/* -** pExpr is a comparison operator. Return the type affinity that should -** be applied to both operands prior to doing the comparison. -*/ -static char comparisonAffinity(Expr *pExpr){ - char aff; - assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || - pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || - pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); - assert( pExpr->pLeft ); - aff = sqlite3ExprAffinity(pExpr->pLeft); - if( pExpr->pRight ){ - aff = sqlite3CompareAffinity(pExpr->pRight, aff); - }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); - }else if( NEVER(aff==0) ){ - aff = SQLITE_AFF_BLOB; - } - return aff; -} - -/* -** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. -** idx_affinity is the affinity of an indexed column. Return true -** if the index with affinity idx_affinity may be used to implement -** the comparison in pExpr. -*/ -SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ - char aff = comparisonAffinity(pExpr); - switch( aff ){ - case SQLITE_AFF_BLOB: - return 1; - case SQLITE_AFF_TEXT: - return idx_affinity==SQLITE_AFF_TEXT; - default: - return sqlite3IsNumericAffinity(idx_affinity); - } -} - -/* -** Return the P5 value that should be used for a binary comparison -** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2. -*/ -static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ - u8 aff = (char)sqlite3ExprAffinity(pExpr2); - aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull; - return aff; -} - -/* -** Return a pointer to the collation sequence that should be used by -** a binary comparison operator comparing pLeft and pRight. -** -** If the left hand expression has a collating sequence type, then it is -** used. Otherwise the collation sequence for the right hand expression -** is used, or the default (BINARY) if neither expression has a collating -** type. -** -** Argument pRight (but not pLeft) may be a null pointer. In this case, -** it is not considered. -*/ -SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( - Parse *pParse, - Expr *pLeft, - Expr *pRight -){ - CollSeq *pColl; - assert( pLeft ); - if( pLeft->flags & EP_Collate ){ - pColl = sqlite3ExprCollSeq(pParse, pLeft); - }else if( pRight && (pRight->flags & EP_Collate)!=0 ){ - pColl = sqlite3ExprCollSeq(pParse, pRight); - }else{ - pColl = sqlite3ExprCollSeq(pParse, pLeft); - if( !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pRight); - } - } - return pColl; -} - -/* -** Generate code for a comparison operator. -*/ -static int codeCompare( - Parse *pParse, /* The parsing (and code generating) context */ - Expr *pLeft, /* The left operand */ - Expr *pRight, /* The right operand */ - int opcode, /* The comparison opcode */ - int in1, int in2, /* Register holding operands */ - int dest, /* Jump here if true. */ - int jumpIfNull /* If true, jump if either operand is NULL */ -){ - int p5; - int addr; - CollSeq *p4; - - p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); - p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); - addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, - (void*)p4, P4_COLLSEQ); - sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); - return addr; -} - -/* -** Return true if expression pExpr is a vector, or false otherwise. -** -** A vector is defined as any expression that results in two or more -** columns of result. Every TK_VECTOR node is an vector because the -** parser will not generate a TK_VECTOR with fewer than two entries. -** But a TK_SELECT might be either a vector or a scalar. It is only -** considered a vector if it has two or more result columns. -*/ -SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){ - return sqlite3ExprVectorSize(pExpr)>1; -} - -/* -** If the expression passed as the only argument is of type TK_VECTOR -** return the number of expressions in the vector. Or, if the expression -** is a sub-select, return the number of columns in the sub-select. For -** any other type of expression, return 1. -*/ -SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){ - u8 op = pExpr->op; - if( op==TK_REGISTER ) op = pExpr->op2; - if( op==TK_VECTOR ){ - return pExpr->x.pList->nExpr; - }else if( op==TK_SELECT ){ - return pExpr->x.pSelect->pEList->nExpr; - }else{ - return 1; - } -} - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Return a pointer to a subexpression of pVector that is the i-th -** column of the vector (numbered starting with 0). The caller must -** ensure that i is within range. -** -** If pVector is really a scalar (and "scalar" here includes subqueries -** that return a single column!) then return pVector unmodified. -** -** pVector retains ownership of the returned subexpression. -** -** If the vector is a (SELECT ...) then the expression returned is -** just the expression for the i-th term of the result set, and may -** not be ready for evaluation because the table cursor has not yet -** been positioned. -*/ -SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ - assert( iop2==0 || pVector->op==TK_REGISTER ); - if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ - return pVector->x.pSelect->pEList->a[i].pExpr; - }else{ - return pVector->x.pList->a[i].pExpr; - } - } - return pVector; -} -#endif /* !defined(SQLITE_OMIT_SUBQUERY) */ - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Compute and return a new Expr object which when passed to -** sqlite3ExprCode() will generate all necessary code to compute -** the iField-th column of the vector expression pVector. -** -** It is ok for pVector to be a scalar (as long as iField==0). -** In that case, this routine works like sqlite3ExprDup(). -** -** The caller owns the returned Expr object and is responsible for -** ensuring that the returned value eventually gets freed. -** -** The caller retains ownership of pVector. If pVector is a TK_SELECT, -** then the returned object will reference pVector and so pVector must remain -** valid for the life of the returned object. If pVector is a TK_VECTOR -** or a scalar expression, then it can be deleted as soon as this routine -** returns. -** -** A trick to cause a TK_SELECT pVector to be deleted together with -** the returned Expr object is to attach the pVector to the pRight field -** of the returned TK_SELECT_COLUMN Expr object. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( - Parse *pParse, /* Parsing context */ - Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ - int iField /* Which column of the vector to return */ -){ - Expr *pRet; - if( pVector->op==TK_SELECT ){ - assert( pVector->flags & EP_xIsSelect ); - /* The TK_SELECT_COLUMN Expr node: - ** - ** pLeft: pVector containing TK_SELECT - ** pRight: not used. But recursively deleted. - ** iColumn: Index of a column in pVector - ** pLeft->iTable: First in an array of register holding result, or 0 - ** if the result is not yet computed. - ** - ** sqlite3ExprDelete() specifically skips the recursive delete of - ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector - ** can be attached to pRight to cause this node to take ownership of - ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes - ** with the same pLeft pointer to the pVector, but only one of them - ** will own the pVector. - */ - pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0, 0); - if( pRet ){ - pRet->iColumn = iField; - pRet->pLeft = pVector; - } - assert( pRet==0 || pRet->iTable==0 ); - }else{ - if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; - pRet = sqlite3ExprDup(pParse->db, pVector, 0); - } - return pRet; -} -#endif /* !define(SQLITE_OMIT_SUBQUERY) */ - -/* -** If expression pExpr is of type TK_SELECT, generate code to evaluate -** it. Return the register in which the result is stored (or, if the -** sub-select returns more than one column, the first in an array -** of registers in which the result is stored). -** -** If pExpr is not a TK_SELECT expression, return 0. -*/ -static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ - int reg = 0; -#ifndef SQLITE_OMIT_SUBQUERY - if( pExpr->op==TK_SELECT ){ - reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); - } -#endif - return reg; -} - -/* -** Argument pVector points to a vector expression - either a TK_VECTOR -** or TK_SELECT that returns more than one column. This function returns -** the register number of a register that contains the value of -** element iField of the vector. -** -** If pVector is a TK_SELECT expression, then code for it must have -** already been generated using the exprCodeSubselect() routine. In this -** case parameter regSelect should be the first in an array of registers -** containing the results of the sub-select. -** -** If pVector is of type TK_VECTOR, then code for the requested field -** is generated. In this case (*pRegFree) may be set to the number of -** a temporary register to be freed by the caller before returning. -** -** Before returning, output parameter (*ppExpr) is set to point to the -** Expr object corresponding to element iElem of the vector. -*/ -static int exprVectorRegister( - Parse *pParse, /* Parse context */ - Expr *pVector, /* Vector to extract element from */ - int iField, /* Field to extract from pVector */ - int regSelect, /* First in array of registers */ - Expr **ppExpr, /* OUT: Expression element */ - int *pRegFree /* OUT: Temp register to free */ -){ - u8 op = pVector->op; - assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT ); - if( op==TK_REGISTER ){ - *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); - return pVector->iTable+iField; - } - if( op==TK_SELECT ){ - *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; - return regSelect+iField; - } - *ppExpr = pVector->x.pList->a[iField].pExpr; - return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); -} - -/* -** Expression pExpr is a comparison between two vector values. Compute -** the result of the comparison (1, 0, or NULL) and write that -** result into register dest. -** -** The caller must satisfy the following preconditions: -** -** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ -** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ -** otherwise: op==pExpr->op and p5==0 -*/ -static void codeVectorCompare( - Parse *pParse, /* Code generator context */ - Expr *pExpr, /* The comparison operation */ - int dest, /* Write results into this register */ - u8 op, /* Comparison operator */ - u8 p5 /* SQLITE_NULLEQ or zero */ -){ - Vdbe *v = pParse->pVdbe; - Expr *pLeft = pExpr->pLeft; - Expr *pRight = pExpr->pRight; - int nLeft = sqlite3ExprVectorSize(pLeft); - int i; - int regLeft = 0; - int regRight = 0; - u8 opx = op; - int addrDone = sqlite3VdbeMakeLabel(v); - - assert( nLeft==sqlite3ExprVectorSize(pRight) ); - assert( pExpr->op==TK_EQ || pExpr->op==TK_NE - || pExpr->op==TK_IS || pExpr->op==TK_ISNOT - || pExpr->op==TK_LT || pExpr->op==TK_GT - || pExpr->op==TK_LE || pExpr->op==TK_GE - ); - assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) - || (pExpr->op==TK_ISNOT && op==TK_NE) ); - assert( p5==0 || pExpr->op!=op ); - assert( p5==SQLITE_NULLEQ || pExpr->op==op ); - - p5 |= SQLITE_STOREP2; - if( opx==TK_LE ) opx = TK_LT; - if( opx==TK_GE ) opx = TK_GT; - - regLeft = exprCodeSubselect(pParse, pLeft); - regRight = exprCodeSubselect(pParse, pRight); - - for(i=0; 1 /*Loop exits by "break"*/; i++){ - int regFree1 = 0, regFree2 = 0; - Expr *pL, *pR; - int r1, r2; - assert( i>=0 && i0 ) sqlite3ExprCachePush(pParse); - r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); - r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); - codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); - testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); - if( i>0 ) sqlite3ExprCachePop(pParse); - if( i==nLeft-1 ){ - break; - } - if( opx==TK_EQ ){ - sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); - p5 |= SQLITE_KEEPNULL; - }else if( opx==TK_NE ){ - sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); - p5 |= SQLITE_KEEPNULL; - }else{ - assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE ); - sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); - VdbeCoverageIf(v, op==TK_LT); - VdbeCoverageIf(v, op==TK_GT); - VdbeCoverageIf(v, op==TK_LE); - VdbeCoverageIf(v, op==TK_GE); - if( i==nLeft-2 ) opx = op; - } - } - sqlite3VdbeResolveLabel(v, addrDone); -} - -#if SQLITE_MAX_EXPR_DEPTH>0 -/* -** Check that argument nHeight is less than or equal to the maximum -** expression depth allowed. If it is not, leave an error message in -** pParse. -*/ -SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ - int rc = SQLITE_OK; - int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; - if( nHeight>mxHeight ){ - sqlite3ErrorMsg(pParse, - "Expression tree is too large (maximum depth %d)", mxHeight - ); - rc = SQLITE_ERROR; - } - return rc; -} - -/* The following three functions, heightOfExpr(), heightOfExprList() -** and heightOfSelect(), are used to determine the maximum height -** of any expression tree referenced by the structure passed as the -** first argument. -** -** If this maximum height is greater than the current value pointed -** to by pnHeight, the second parameter, then set *pnHeight to that -** value. -*/ -static void heightOfExpr(Expr *p, int *pnHeight){ - if( p ){ - if( p->nHeight>*pnHeight ){ - *pnHeight = p->nHeight; - } - } -} -static void heightOfExprList(ExprList *p, int *pnHeight){ - if( p ){ - int i; - for(i=0; inExpr; i++){ - heightOfExpr(p->a[i].pExpr, pnHeight); - } - } -} -static void heightOfSelect(Select *p, int *pnHeight){ - if( p ){ - heightOfExpr(p->pWhere, pnHeight); - heightOfExpr(p->pHaving, pnHeight); - heightOfExpr(p->pLimit, pnHeight); - heightOfExpr(p->pOffset, pnHeight); - heightOfExprList(p->pEList, pnHeight); - heightOfExprList(p->pGroupBy, pnHeight); - heightOfExprList(p->pOrderBy, pnHeight); - heightOfSelect(p->pPrior, pnHeight); - } -} - -/* -** Set the Expr.nHeight variable in the structure passed as an -** argument. An expression with no children, Expr.pList or -** Expr.pSelect member has a height of 1. Any other expression -** has a height equal to the maximum height of any other -** referenced Expr plus one. -** -** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, -** if appropriate. -*/ -static void exprSetHeight(Expr *p){ - int nHeight = 0; - heightOfExpr(p->pLeft, &nHeight); - heightOfExpr(p->pRight, &nHeight); - if( ExprHasProperty(p, EP_xIsSelect) ){ - heightOfSelect(p->x.pSelect, &nHeight); - }else if( p->x.pList ){ - heightOfExprList(p->x.pList, &nHeight); - p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); - } - p->nHeight = nHeight + 1; -} - -/* -** Set the Expr.nHeight variable using the exprSetHeight() function. If -** the height is greater than the maximum allowed expression depth, -** leave an error in pParse. -** -** Also propagate all EP_Propagate flags from the Expr.x.pList into -** Expr.flags. -*/ -SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ - if( pParse->nErr ) return; - exprSetHeight(p); - sqlite3ExprCheckHeight(pParse, p->nHeight); -} - -/* -** Return the maximum height of any expression tree referenced -** by the select statement passed as an argument. -*/ -SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ - int nHeight = 0; - heightOfSelect(p, &nHeight); - return nHeight; -} -#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ -/* -** Propagate all EP_Propagate flags from the Expr.x.pList into -** Expr.flags. -*/ -SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ - if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ - p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); - } -} -#define exprSetHeight(y) -#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ - -/* -** This routine is the core allocator for Expr nodes. -** -** Construct a new expression node and return a pointer to it. Memory -** for this node and for the pToken argument is a single allocation -** obtained from sqlite3DbMalloc(). The calling function -** is responsible for making sure the node eventually gets freed. -** -** If dequote is true, then the token (if it exists) is dequoted. -** If dequote is false, no dequoting is performed. The deQuote -** parameter is ignored if pToken is NULL or if the token does not -** appear to be quoted. If the quotes were of the form "..." (double-quotes) -** then the EP_DblQuoted flag is set on the expression node. -** -** Special case: If op==TK_INTEGER and pToken points to a string that -** can be translated into a 32-bit integer, then the token is not -** stored in u.zToken. Instead, the integer values is written -** into u.iValue and the EP_IntValue flag is set. No extra storage -** is allocated to hold the integer text and the dequote flag is ignored. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprAlloc( - sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ - int op, /* Expression opcode */ - const Token *pToken, /* Token argument. Might be NULL */ - int dequote /* True to dequote */ -){ - Expr *pNew; - int nExtra = 0; - int iValue = 0; - - assert( db!=0 ); - if( pToken ){ - if( op!=TK_INTEGER || pToken->z==0 - || sqlite3GetInt32(pToken->z, &iValue)==0 ){ - nExtra = pToken->n+1; - assert( iValue>=0 ); - } - } - pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); - if( pNew ){ - memset(pNew, 0, sizeof(Expr)); - pNew->op = (u8)op; - pNew->iAgg = -1; - if( pToken ){ - if( nExtra==0 ){ - pNew->flags |= EP_IntValue; - pNew->u.iValue = iValue; - }else{ - pNew->u.zToken = (char*)&pNew[1]; - assert( pToken->z!=0 || pToken->n==0 ); - if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); - pNew->u.zToken[pToken->n] = 0; - if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ - if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted; - sqlite3Dequote(pNew->u.zToken); - } - } - } -#if SQLITE_MAX_EXPR_DEPTH>0 - pNew->nHeight = 1; -#endif - } - return pNew; -} - -/* -** Allocate a new expression node from a zero-terminated token that has -** already been dequoted. -*/ -SQLITE_PRIVATE Expr *sqlite3Expr( - sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ - int op, /* Expression opcode */ - const char *zToken /* Token argument. Might be NULL */ -){ - Token x; - x.z = zToken; - x.n = zToken ? sqlite3Strlen30(zToken) : 0; - return sqlite3ExprAlloc(db, op, &x, 0); -} - -/* -** Attach subtrees pLeft and pRight to the Expr node pRoot. -** -** If pRoot==NULL that means that a memory allocation error has occurred. -** In that case, delete the subtrees pLeft and pRight. -*/ -SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( - sqlite3 *db, - Expr *pRoot, - Expr *pLeft, - Expr *pRight -){ - if( pRoot==0 ){ - assert( db->mallocFailed ); - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); - }else{ - if( pRight ){ - pRoot->pRight = pRight; - pRoot->flags |= EP_Propagate & pRight->flags; - } - if( pLeft ){ - pRoot->pLeft = pLeft; - pRoot->flags |= EP_Propagate & pLeft->flags; - } - exprSetHeight(pRoot); - } -} - -/* -** Allocate an Expr node which joins as many as two subtrees. -** -** One or both of the subtrees can be NULL. Return a pointer to the new -** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, -** free the subtrees and return NULL. -*/ -SQLITE_PRIVATE Expr *sqlite3PExpr( - Parse *pParse, /* Parsing context */ - int op, /* Expression opcode */ - Expr *pLeft, /* Left operand */ - Expr *pRight, /* Right operand */ - const Token *pToken /* Argument token */ -){ - Expr *p; - if( op==TK_AND && pParse->nErr==0 ){ - /* Take advantage of short-circuit false optimization for AND */ - p = sqlite3ExprAnd(pParse->db, pLeft, pRight); - }else{ - p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1); - sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); - } - if( p ) { - sqlite3ExprCheckHeight(pParse, p->nHeight); - } - return p; -} - -/* -** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due -** do a memory allocation failure) then delete the pSelect object. -*/ -SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ - if( pExpr ){ - pExpr->x.pSelect = pSelect; - ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery); - sqlite3ExprSetHeightAndFlags(pParse, pExpr); - }else{ - assert( pParse->db->mallocFailed ); - sqlite3SelectDelete(pParse->db, pSelect); - } -} - - -/* -** If the expression is always either TRUE or FALSE (respectively), -** then return 1. If one cannot determine the truth value of the -** expression at compile-time return 0. -** -** This is an optimization. If is OK to return 0 here even if -** the expression really is always false or false (a false negative). -** But it is a bug to return 1 if the expression might have different -** boolean values in different circumstances (a false positive.) -** -** Note that if the expression is part of conditional for a -** LEFT JOIN, then we cannot determine at compile-time whether or not -** is it true or false, so always return 0. -*/ -static int exprAlwaysTrue(Expr *p){ - int v = 0; - if( ExprHasProperty(p, EP_FromJoin) ) return 0; - if( !sqlite3ExprIsInteger(p, &v) ) return 0; - return v!=0; -} -static int exprAlwaysFalse(Expr *p){ - int v = 0; - if( ExprHasProperty(p, EP_FromJoin) ) return 0; - if( !sqlite3ExprIsInteger(p, &v) ) return 0; - return v==0; -} - -/* -** Join two expressions using an AND operator. If either expression is -** NULL, then just return the other expression. -** -** If one side or the other of the AND is known to be false, then instead -** of returning an AND expression, just return a constant expression with -** a value of false. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ - if( pLeft==0 ){ - return pRight; - }else if( pRight==0 ){ - return pLeft; - }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){ - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); - return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); - }else{ - Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); - sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); - return pNew; - } -} - -/* -** Construct a new expression node for a function with multiple -** arguments. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ - Expr *pNew; - sqlite3 *db = pParse->db; - assert( pToken ); - pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); - if( pNew==0 ){ - sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ - return 0; - } - pNew->x.pList = pList; - assert( !ExprHasProperty(pNew, EP_xIsSelect) ); - sqlite3ExprSetHeightAndFlags(pParse, pNew); - return pNew; -} - -/* -** Assign a variable number to an expression that encodes a wildcard -** in the original SQL statement. -** -** Wildcards consisting of a single "?" are assigned the next sequential -** variable number. -** -** Wildcards of the form "?nnn" are assigned the number "nnn". We make -** sure "nnn" is not too be to avoid a denial of service attack when -** the SQL statement comes from an external source. -** -** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number -** as the previous instance of the same wildcard. Or if this is the first -** instance of the wildcard, the next sequential variable number is -** assigned. -*/ -SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ - sqlite3 *db = pParse->db; - const char *z; - - if( pExpr==0 ) return; - assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); - z = pExpr->u.zToken; - assert( z!=0 ); - assert( z[0]!=0 ); - assert( n==sqlite3Strlen30(z) ); - if( z[1]==0 ){ - /* Wildcard of the form "?". Assign the next variable number */ - assert( z[0]=='?' ); - pExpr->iColumn = (ynVar)(++pParse->nVar); - }else{ - ynVar x; - if( z[0]=='?' ){ - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and - ** use it as the variable number */ - i64 i; - int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); - x = (ynVar)i; - testcase( i==0 ); - testcase( i==1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); - if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", - db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); - return; - } - if( i>pParse->nVar ){ - pParse->nVar = (int)i; - } - }else{ - /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable - ** number as the prior appearance of the same name, or if the name - ** has never appeared before, reuse the same variable number - */ - ynVar i; - for(i=x=0; inzVar; i++){ - if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){ - x = (ynVar)i+1; - break; - } - } - if( x==0 ) x = (ynVar)(++pParse->nVar); - } - pExpr->iColumn = x; - if( x>pParse->nzVar ){ - char **a; - a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); - if( a==0 ){ - assert( db->mallocFailed ); /* Error reported through mallocFailed */ - return; - } - pParse->azVar = a; - memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); - pParse->nzVar = x; - } - if( pParse->azVar[x-1]==0 ){ - pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); - } - } - if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - sqlite3ErrorMsg(pParse, "too many SQL variables"); - } -} - -/* -** Recursively delete an expression tree. -*/ -static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ - assert( p!=0 ); - /* Sanity check: Assert that the IntValue is non-negative if it exists */ - assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); -#ifdef SQLITE_DEBUG - if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ - assert( p->pLeft==0 ); - assert( p->pRight==0 ); - assert( p->x.pSelect==0 ); - } -#endif - if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ - /* The Expr.x union is never used at the same time as Expr.pRight */ - assert( p->x.pList==0 || p->pRight==0 ); - if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); - sqlite3ExprDelete(db, p->pRight); - if( ExprHasProperty(p, EP_xIsSelect) ){ - sqlite3SelectDelete(db, p->x.pSelect); - }else{ - sqlite3ExprListDelete(db, p->x.pList); - } - } - if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); - if( !ExprHasProperty(p, EP_Static) ){ - sqlite3DbFree(db, p); - } -} -SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ - if( p ) sqlite3ExprDeleteNN(db, p); -} - -/* -** Return the number of bytes allocated for the expression structure -** passed as the first argument. This is always one of EXPR_FULLSIZE, -** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. -*/ -static int exprStructSize(Expr *p){ - if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; - if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; - return EXPR_FULLSIZE; -} - -/* -** The dupedExpr*Size() routines each return the number of bytes required -** to store a copy of an expression or expression tree. They differ in -** how much of the tree is measured. -** -** dupedExprStructSize() Size of only the Expr structure -** dupedExprNodeSize() Size of Expr + space for token -** dupedExprSize() Expr + token + subtree components -** -*************************************************************************** -** -** The dupedExprStructSize() function returns two values OR-ed together: -** (1) the space required for a copy of the Expr structure only and -** (2) the EP_xxx flags that indicate what the structure size should be. -** The return values is always one of: -** -** EXPR_FULLSIZE -** EXPR_REDUCEDSIZE | EP_Reduced -** EXPR_TOKENONLYSIZE | EP_TokenOnly -** -** The size of the structure can be found by masking the return value -** of this routine with 0xfff. The flags can be found by masking the -** return value with EP_Reduced|EP_TokenOnly. -** -** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size -** (unreduced) Expr objects as they or originally constructed by the parser. -** During expression analysis, extra information is computed and moved into -** later parts of teh Expr object and that extra information might get chopped -** off if the expression is reduced. Note also that it does not work to -** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal -** to reduce a pristine expression tree from the parser. The implementation -** of dupedExprStructSize() contain multiple assert() statements that attempt -** to enforce this constraint. -*/ -static int dupedExprStructSize(Expr *p, int flags){ - int nSize; - assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ - assert( EXPR_FULLSIZE<=0xfff ); - assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags ){ - nSize = EXPR_FULLSIZE; - }else{ - assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); - assert( !ExprHasProperty(p, EP_FromJoin) ); - assert( !ExprHasProperty(p, EP_MemToken) ); - assert( !ExprHasProperty(p, EP_NoReduce) ); - if( p->pLeft || p->x.pList ){ - nSize = EXPR_REDUCEDSIZE | EP_Reduced; - }else{ - assert( p->pRight==0 ); - nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; - } - } - return nSize; -} - -/* -** This function returns the space in bytes required to store the copy -** of the Expr structure and a copy of the Expr.u.zToken string (if that -** string is defined.) -*/ -static int dupedExprNodeSize(Expr *p, int flags){ - int nByte = dupedExprStructSize(p, flags) & 0xfff; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nByte += sqlite3Strlen30(p->u.zToken)+1; - } - return ROUND8(nByte); -} - -/* -** Return the number of bytes required to create a duplicate of the -** expression passed as the first argument. The second argument is a -** mask containing EXPRDUP_XXX flags. -** -** The value returned includes space to create a copy of the Expr struct -** itself and the buffer referred to by Expr.u.zToken, if any. -** -** If the EXPRDUP_REDUCE flag is set, then the return value includes -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft -** and Expr.pRight variables (but not for any structures pointed to or -** descended from the Expr.x.pList or Expr.x.pSelect variables). -*/ -static int dupedExprSize(Expr *p, int flags){ - int nByte = 0; - if( p ){ - nByte = dupedExprNodeSize(p, flags); - if( flags&EXPRDUP_REDUCE ){ - nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); - } - } - return nByte; -} - -/* -** This function is similar to sqlite3ExprDup(), except that if pzBuffer -** is not NULL then *pzBuffer is assumed to point to a buffer large enough -** to store the copy of expression p, the copies of p->u.zToken -** (if applicable), and the copies of the p->pLeft and p->pRight expressions, -** if any. Before returning, *pzBuffer is set to the first byte past the -** portion of the buffer copied into by this function. -*/ -static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ - Expr *pNew; /* Value to return */ - u8 *zAlloc; /* Memory space from which to build Expr object */ - u32 staticFlag; /* EP_Static if space not obtained from malloc */ - - assert( db!=0 ); - assert( p ); - assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); - - /* Figure out where to write the new Expr structure. */ - if( pzBuffer ){ - zAlloc = *pzBuffer; - staticFlag = EP_Static; - }else{ - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); - staticFlag = 0; - } - pNew = (Expr *)zAlloc; - - if( pNew ){ - /* Set nNewSize to the size allocated for the structure pointed to - ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or - ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed - ** by the copy of the p->u.zToken string (if any). - */ - const unsigned nStructSize = dupedExprStructSize(p, dupFlags); - const int nNewSize = nStructSize & 0xfff; - int nToken; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; - }else{ - nToken = 0; - } - if( dupFlags ){ - assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(zAlloc, p, nNewSize); - }else{ - u32 nSize = (u32)exprStructSize(p); - memcpy(zAlloc, p, nSize); - if( nSizeflags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); - pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); - pNew->flags |= staticFlag; - - /* Copy the p->u.zToken string, if any. */ - if( nToken ){ - char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; - memcpy(zToken, p->u.zToken, nToken); - } - - if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ - /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ - if( ExprHasProperty(p, EP_xIsSelect) ){ - pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); - }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); - } - } - - /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ - pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; - } - if( pzBuffer ){ - *pzBuffer = zAlloc; - } - }else{ - if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - if( pNew->op==TK_SELECT_COLUMN ){ - pNew->pLeft = p->pLeft; - }else{ - pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); - } - pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); - } - } - } - return pNew; -} - -/* -** Create and return a deep copy of the object passed as the second -** argument. If an OOM condition is encountered, NULL is returned -** and the db->mallocFailed flag set. -*/ -#ifndef SQLITE_OMIT_CTE -static With *withDup(sqlite3 *db, With *p){ - With *pRet = 0; - if( p ){ - int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); - pRet = sqlite3DbMallocZero(db, nByte); - if( pRet ){ - int i; - pRet->nCte = p->nCte; - for(i=0; inCte; i++){ - pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); - pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); - pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); - } - } - } - return pRet; -} -#else -# define withDup(x,y) 0 -#endif - -/* -** The following group of routines make deep copies of expressions, -** expression lists, ID lists, and select statements. The copies can -** be deleted (by being passed to their respective ...Delete() routines) -** without effecting the originals. -** -** The expression list, ID, and source lists return by sqlite3ExprListDup(), -** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded -** by subsequent calls to sqlite*ListAppend() routines. -** -** Any tables that the SrcList might point to are not duplicated. -** -** The flags parameter contains a combination of the EXPRDUP_XXX flags. -** If the EXPRDUP_REDUCE flag is set, then the structure returned is a -** truncated version of the usual Expr structure that will be stored as -** part of the in-memory representation of the database schema. -*/ -SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ - assert( flags==0 || flags==EXPRDUP_REDUCE ); - return p ? exprDup(db, p, flags, 0) : 0; -} -SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ - ExprList *pNew; - struct ExprList_item *pItem, *pOldItem; - int i; - assert( db!=0 ); - if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); - if( pNew==0 ) return 0; - pNew->nExpr = i = p->nExpr; - if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} - pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) ); - if( pItem==0 ){ - sqlite3DbFree(db, pNew); - return 0; - } - pOldItem = p->a; - for(i=0; inExpr; i++, pItem++, pOldItem++){ - Expr *pOldExpr = pOldItem->pExpr; - pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); - pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); - pItem->sortOrder = pOldItem->sortOrder; - pItem->done = 0; - pItem->bSpanIsTab = pOldItem->bSpanIsTab; - pItem->u = pOldItem->u; - } - return pNew; -} - -/* -** If cursors, triggers, views and subqueries are all omitted from -** the build, then none of the following routines, except for -** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes -** called with a NULL argument. -*/ -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ - || !defined(SQLITE_OMIT_SUBQUERY) -SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ - SrcList *pNew; - int i; - int nByte; - assert( db!=0 ); - if( p==0 ) return 0; - nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); - pNew = sqlite3DbMallocRawNN(db, nByte ); - if( pNew==0 ) return 0; - pNew->nSrc = pNew->nAlloc = p->nSrc; - for(i=0; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; - Table *pTab; - pNewItem->pSchema = pOldItem->pSchema; - pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); - pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->fg = pOldItem->fg; - pNewItem->iCursor = pOldItem->iCursor; - pNewItem->addrFillSub = pOldItem->addrFillSub; - pNewItem->regReturn = pOldItem->regReturn; - if( pNewItem->fg.isIndexedBy ){ - pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); - } - pNewItem->pIBIndex = pOldItem->pIBIndex; - if( pNewItem->fg.isTabFunc ){ - pNewItem->u1.pFuncArg = - sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); - } - pTab = pNewItem->pTab = pOldItem->pTab; - if( pTab ){ - pTab->nRef++; - } - pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); - pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); - pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); - pNewItem->colUsed = pOldItem->colUsed; - } - return pNew; -} -SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ - IdList *pNew; - int i; - assert( db!=0 ); - if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); - if( pNew==0 ) return 0; - pNew->nId = p->nId; - pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); - if( pNew->a==0 ){ - sqlite3DbFree(db, pNew); - return 0; - } - /* Note that because the size of the allocation for p->a[] is not - ** necessarily a power of two, sqlite3IdListAppend() may not be called - ** on the duplicate created by this function. */ - for(i=0; inId; i++){ - struct IdList_item *pNewItem = &pNew->a[i]; - struct IdList_item *pOldItem = &p->a[i]; - pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->idx = pOldItem->idx; - } - return pNew; -} -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - Select *pNew, *pPrior; - assert( db!=0 ); - if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); - if( pNew==0 ) return 0; - pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); - pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); - pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); - pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); - pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); - pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); - pNew->op = p->op; - pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags); - if( pPrior ) pPrior->pNext = pNew; - pNew->pNext = 0; - pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); - pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags); - pNew->iLimit = 0; - pNew->iOffset = 0; - pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = p->nSelectRow; - pNew->pWith = withDup(db, p->pWith); - sqlite3SelectSetName(pNew, p->zSelName); - return pNew; -} -#else -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ - assert( p==0 ); - return 0; -} -#endif - - -/* -** Add a new element to the end of an expression list. If pList is -** initially NULL, then create a new expression list. -** -** If a memory allocation error occurs, the entire list is freed and -** NULL is returned. If non-NULL is returned, then it is guaranteed -** that the new entry was successfully appended. -*/ -SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to append. Might be NULL */ - Expr *pExpr /* Expression to be appended. Might be NULL */ -){ - sqlite3 *db = pParse->db; - assert( db!=0 ); - if( pList==0 ){ - pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); - if( pList==0 ){ - goto no_mem; - } - pList->nExpr = 0; - pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0])); - if( pList->a==0 ) goto no_mem; - }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - struct ExprList_item *a; - assert( pList->nExpr>0 ); - a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0])); - if( a==0 ){ - goto no_mem; - } - pList->a = a; - } - assert( pList->a!=0 ); - if( 1 ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr++]; - memset(pItem, 0, sizeof(*pItem)); - pItem->pExpr = pExpr; - } - return pList; - -no_mem: - /* Avoid leaking memory if malloc has failed. */ - sqlite3ExprDelete(db, pExpr); - sqlite3ExprListDelete(db, pList); - return 0; -} - -/* -** pColumns and pExpr form a vector assignment which is part of the SET -** clause of an UPDATE statement. Like this: -** -** (a,b,c) = (expr1,expr2,expr3) -** Or: (a,b,c) = (SELECT x,y,z FROM ....) -** -** For each term of the vector assignment, append new entries to the -** expression list pList. In the case of a subquery on the LHS, append -** TK_SELECT_COLUMN expressions. -*/ -SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to append. Might be NULL */ - IdList *pColumns, /* List of names of LHS of the assignment */ - Expr *pExpr /* Vector expression to be appended. Might be NULL */ -){ - sqlite3 *db = pParse->db; - int n; - int i; - int iFirst = pList ? pList->nExpr : 0; - /* pColumns can only be NULL due to an OOM but an OOM will cause an - ** exit prior to this routine being invoked */ - if( NEVER(pColumns==0) ) goto vector_append_error; - if( pExpr==0 ) goto vector_append_error; - n = sqlite3ExprVectorSize(pExpr); - if( pColumns->nId!=n ){ - sqlite3ErrorMsg(pParse, "%d columns assigned %d values", - pColumns->nId, n); - goto vector_append_error; - } - for(i=0; inExpr==iFirst+i+1 ); - pList->a[pList->nExpr-1].zName = pColumns->a[i].zName; - pColumns->a[i].zName = 0; - } - } - if( pExpr->op==TK_SELECT ){ - if( pList && pList->a[iFirst].pExpr ){ - assert( pList->a[iFirst].pExpr->op==TK_SELECT_COLUMN ); - pList->a[iFirst].pExpr->pRight = pExpr; - pExpr = 0; - } - } - -vector_append_error: - sqlite3ExprDelete(db, pExpr); - sqlite3IdListDelete(db, pColumns); - return pList; -} - -/* -** Set the sort order for the last element on the given ExprList. -*/ -SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){ - if( p==0 ) return; - assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 ); - assert( p->nExpr>0 ); - if( iSortOrder<0 ){ - assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC ); - return; - } - p->a[p->nExpr-1].sortOrder = (u8)iSortOrder; -} - -/* -** Set the ExprList.a[].zName element of the most recently added item -** on the expression list. -** -** pList might be NULL following an OOM error. But pName should never be -** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag -** is set. -*/ -SQLITE_PRIVATE void sqlite3ExprListSetName( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to add the span. */ - Token *pName, /* Name to be added */ - int dequote /* True to cause the name to be dequoted */ -){ - assert( pList!=0 || pParse->db->mallocFailed!=0 ); - if( pList ){ - struct ExprList_item *pItem; - assert( pList->nExpr>0 ); - pItem = &pList->a[pList->nExpr-1]; - assert( pItem->zName==0 ); - pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); - if( dequote ) sqlite3Dequote(pItem->zName); - } -} - -/* -** Set the ExprList.a[].zSpan element of the most recently added item -** on the expression list. -** -** pList might be NULL following an OOM error. But pSpan should never be -** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag -** is set. -*/ -SQLITE_PRIVATE void sqlite3ExprListSetSpan( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List to which to add the span. */ - ExprSpan *pSpan /* The span to be added */ -){ - sqlite3 *db = pParse->db; - assert( pList!=0 || db->mallocFailed!=0 ); - if( pList ){ - struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; - assert( pList->nExpr>0 ); - assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr ); - sqlite3DbFree(db, pItem->zSpan); - pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart, - (int)(pSpan->zEnd - pSpan->zStart)); - } -} - -/* -** If the expression list pEList contains more than iLimit elements, -** leave an error message in pParse. -*/ -SQLITE_PRIVATE void sqlite3ExprListCheckLength( - Parse *pParse, - ExprList *pEList, - const char *zObject -){ - int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; - testcase( pEList && pEList->nExpr==mx ); - testcase( pEList && pEList->nExpr==mx+1 ); - if( pEList && pEList->nExpr>mx ){ - sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); - } -} - -/* -** Delete an entire expression list. -*/ -static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ - int i; - struct ExprList_item *pItem; - assert( pList->a!=0 || pList->nExpr==0 ); - for(pItem=pList->a, i=0; inExpr; i++, pItem++){ - sqlite3ExprDelete(db, pItem->pExpr); - sqlite3DbFree(db, pItem->zName); - sqlite3DbFree(db, pItem->zSpan); - } - sqlite3DbFree(db, pList->a); - sqlite3DbFree(db, pList); -} -SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ - if( pList ) exprListDeleteNN(db, pList); -} - -/* -** Return the bitwise-OR of all Expr.flags fields in the given -** ExprList. -*/ -SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ - int i; - u32 m = 0; - if( pList ){ - for(i=0; inExpr; i++){ - Expr *pExpr = pList->a[i].pExpr; - assert( pExpr!=0 ); - m |= pExpr->flags; - } - } - return m; -} - -/* -** These routines are Walker callbacks used to check expressions to -** see if they are "constant" for some definition of constant. The -** Walker.eCode value determines the type of "constant" we are looking -** for. -** -** These callback routines are used to implement the following: -** -** sqlite3ExprIsConstant() pWalker->eCode==1 -** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 -** sqlite3ExprIsTableConstant() pWalker->eCode==3 -** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 -** -** In all cases, the callbacks set Walker.eCode=0 and abort if the expression -** is found to not be a constant. -** -** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions -** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing -** an existing schema and 4 when processing a new statement. A bound -** parameter raises an error for new statements, but is silently converted -** to NULL for existing schemas. This allows sqlite_master tables that -** contain a bound parameter because they were generated by older versions -** of SQLite to be parsed by newer versions of SQLite without raising a -** malformed schema error. -*/ -static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ - - /* If pWalker->eCode is 2 then any term of the expression that comes from - ** the ON or USING clauses of a left join disqualifies the expression - ** from being considered constant. */ - if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){ - pWalker->eCode = 0; - return WRC_Abort; - } - - switch( pExpr->op ){ - /* Consider functions to be constant if all their arguments are constant - ** and either pWalker->eCode==4 or 5 or the function has the - ** SQLITE_FUNC_CONST flag. */ - case TK_FUNCTION: - if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){ - return WRC_Continue; - }else{ - pWalker->eCode = 0; - return WRC_Abort; - } - case TK_ID: - case TK_COLUMN: - case TK_AGG_FUNCTION: - case TK_AGG_COLUMN: - testcase( pExpr->op==TK_ID ); - testcase( pExpr->op==TK_COLUMN ); - testcase( pExpr->op==TK_AGG_FUNCTION ); - testcase( pExpr->op==TK_AGG_COLUMN ); - if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ - return WRC_Continue; - }else{ - pWalker->eCode = 0; - return WRC_Abort; - } - case TK_VARIABLE: - if( pWalker->eCode==5 ){ - /* Silently convert bound parameters that appear inside of CREATE - ** statements into a NULL when parsing the CREATE statement text out - ** of the sqlite_master table */ - pExpr->op = TK_NULL; - }else if( pWalker->eCode==4 ){ - /* A bound parameter in a CREATE statement that originates from - ** sqlite3_prepare() causes an error */ - pWalker->eCode = 0; - return WRC_Abort; - } - /* Fall through */ - default: - testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */ - testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */ - return WRC_Continue; - } -} -static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){ - UNUSED_PARAMETER(NotUsed); - pWalker->eCode = 0; - return WRC_Abort; -} -static int exprIsConst(Expr *p, int initFlag, int iCur){ - Walker w; - memset(&w, 0, sizeof(w)); - w.eCode = initFlag; - w.xExprCallback = exprNodeIsConstant; - w.xSelectCallback = selectNodeIsConstant; - w.u.iCur = iCur; - sqlite3WalkExpr(&w, p); - return w.eCode; -} - -/* -** Walk an expression tree. Return non-zero if the expression is constant -** and 0 if it involves variables or function calls. -** -** For the purposes of this function, a double-quoted string (ex: "abc") -** is considered a variable but a single-quoted string (ex: 'abc') is -** a constant. -*/ -SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ - return exprIsConst(p, 1, 0); -} - -/* -** Walk an expression tree. Return non-zero if the expression is constant -** that does no originate from the ON or USING clauses of a join. -** Return 0 if it involves variables or function calls or terms from -** an ON or USING clause. -*/ -SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ - return exprIsConst(p, 2, 0); -} - -/* -** Walk an expression tree. Return non-zero if the expression is constant -** for any single row of the table with cursor iCur. In other words, the -** expression must not refer to any non-deterministic function nor any -** table other than iCur. -*/ -SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ - return exprIsConst(p, 3, iCur); -} - -/* -** Walk an expression tree. Return non-zero if the expression is constant -** or a function call with constant arguments. Return and 0 if there -** are any variables. -** -** For the purposes of this function, a double-quoted string (ex: "abc") -** is considered a variable but a single-quoted string (ex: 'abc') is -** a constant. -*/ -SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ - assert( isInit==0 || isInit==1 ); - return exprIsConst(p, 4+isInit, 0); -} - -#ifdef SQLITE_ENABLE_CURSOR_HINTS -/* -** Walk an expression tree. Return 1 if the expression contains a -** subquery of some kind. Return 0 if there are no subqueries. -*/ -SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ - Walker w; - memset(&w, 0, sizeof(w)); - w.eCode = 1; - w.xExprCallback = sqlite3ExprWalkNoop; - w.xSelectCallback = selectNodeIsConstant; - sqlite3WalkExpr(&w, p); - return w.eCode==0; -} -#endif - -/* -** If the expression p codes a constant integer that is small enough -** to fit in a 32-bit integer, return 1 and put the value of the integer -** in *pValue. If the expression is not an integer or if it is too big -** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. -*/ -SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ - int rc = 0; - - /* If an expression is an integer literal that fits in a signed 32-bit - ** integer, then the EP_IntValue flag will have already been set */ - assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 - || sqlite3GetInt32(p->u.zToken, &rc)==0 ); - - if( p->flags & EP_IntValue ){ - *pValue = p->u.iValue; - return 1; - } - switch( p->op ){ - case TK_UPLUS: { - rc = sqlite3ExprIsInteger(p->pLeft, pValue); - break; - } - case TK_UMINUS: { - int v; - if( sqlite3ExprIsInteger(p->pLeft, &v) ){ - assert( v!=(-2147483647-1) ); - *pValue = -v; - rc = 1; - } - break; - } - default: break; - } - return rc; -} - -/* -** Return FALSE if there is no chance that the expression can be NULL. -** -** If the expression might be NULL or if the expression is too complex -** to tell return TRUE. -** -** This routine is used as an optimization, to skip OP_IsNull opcodes -** when we know that a value cannot be NULL. Hence, a false positive -** (returning TRUE when in fact the expression can never be NULL) might -** be a small performance hit but is otherwise harmless. On the other -** hand, a false negative (returning FALSE when the result could be NULL) -** will likely result in an incorrect answer. So when in doubt, return -** TRUE. -*/ -SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ - u8 op; - while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } - op = p->op; - if( op==TK_REGISTER ) op = p->op2; - switch( op ){ - case TK_INTEGER: - case TK_STRING: - case TK_FLOAT: - case TK_BLOB: - return 0; - case TK_COLUMN: - assert( p->pTab!=0 ); - return ExprHasProperty(p, EP_CanBeNull) || - (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); - default: - return 1; - } -} - -/* -** Return TRUE if the given expression is a constant which would be -** unchanged by OP_Affinity with the affinity given in the second -** argument. -** -** This routine is used to determine if the OP_Affinity operation -** can be omitted. When in doubt return FALSE. A false negative -** is harmless. A false positive, however, can result in the wrong -** answer. -*/ -SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ - u8 op; - if( aff==SQLITE_AFF_BLOB ) return 1; - while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } - op = p->op; - if( op==TK_REGISTER ) op = p->op2; - switch( op ){ - case TK_INTEGER: { - return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC; - } - case TK_FLOAT: { - return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC; - } - case TK_STRING: { - return aff==SQLITE_AFF_TEXT; - } - case TK_BLOB: { - return 1; - } - case TK_COLUMN: { - assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ - return p->iColumn<0 - && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC); - } - default: { - return 0; - } - } -} - -/* -** Return TRUE if the given string is a row-id column name. -*/ -SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ - if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; - if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; - if( sqlite3StrICmp(z, "OID")==0 ) return 1; - return 0; -} - -/* -** pX is the RHS of an IN operator. If pX is a SELECT statement -** that can be simplified to a direct table access, then return -** a pointer to the SELECT statement. If pX is not a SELECT statement, -** or if the SELECT statement needs to be manifested into a transient -** table, then return NULL. -*/ -#ifndef SQLITE_OMIT_SUBQUERY -static Select *isCandidateForInOpt(Expr *pX){ - Select *p; - SrcList *pSrc; - ExprList *pEList; - Table *pTab; - int i; - if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */ - if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */ - p = pX->x.pSelect; - if( p->pPrior ) return 0; /* Not a compound SELECT */ - if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ - testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); - testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); - return 0; /* No DISTINCT keyword and no aggregate functions */ - } - assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ - if( p->pLimit ) return 0; /* Has no LIMIT clause */ - assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */ - if( p->pWhere ) return 0; /* Has no WHERE clause */ - pSrc = p->pSrc; - assert( pSrc!=0 ); - if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ - if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ - pTab = pSrc->a[0].pTab; - assert( pTab!=0 ); - assert( pTab->pSelect==0 ); /* FROM clause is not a view */ - if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ - pEList = p->pEList; - assert( pEList!=0 ); - /* All SELECT results must be columns. */ - for(i=0; inExpr; i++){ - Expr *pRes = pEList->a[i].pExpr; - if( pRes->op!=TK_COLUMN ) return 0; - assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ - } - return p; -} -#endif /* SQLITE_OMIT_SUBQUERY */ - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Generate code that checks the left-most column of index table iCur to see if -** it contains any NULL entries. Cause the register at regHasNull to be set -** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull -** to be set to NULL if iCur contains one or more NULL values. -*/ -static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ - int addr1; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); - addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); - sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); - VdbeComment((v, "first_entry_in(%d)", iCur)); - sqlite3VdbeJumpHere(v, addr1); -} -#endif - - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** The argument is an IN operator with a list (not a subquery) on the -** right-hand side. Return TRUE if that list is constant. -*/ -static int sqlite3InRhsIsConstant(Expr *pIn){ - Expr *pLHS; - int res; - assert( !ExprHasProperty(pIn, EP_xIsSelect) ); - pLHS = pIn->pLeft; - pIn->pLeft = 0; - res = sqlite3ExprIsConstant(pIn); - pIn->pLeft = pLHS; - return res; -} -#endif - -/* -** This function is used by the implementation of the IN (...) operator. -** The pX parameter is the expression on the RHS of the IN operator, which -** might be either a list of expressions or a subquery. -** -** The job of this routine is to find or create a b-tree object that can -** be used either to test for membership in the RHS set or to iterate through -** all members of the RHS set, skipping duplicates. -** -** A cursor is opened on the b-tree object that is the RHS of the IN operator -** and pX->iTable is set to the index of that cursor. -** -** The returned value of this function indicates the b-tree type, as follows: -** -** IN_INDEX_ROWID - The cursor was opened on a database table. -** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. -** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. -** IN_INDEX_EPH - The cursor was opened on a specially created and -** populated epheremal table. -** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be -** implemented as a sequence of comparisons. -** -** An existing b-tree might be used if the RHS expression pX is a simple -** subquery such as: -** -** SELECT , ... FROM -** -** If the RHS of the IN operator is a list or a more complex subquery, then -** an ephemeral table might need to be generated from the RHS and then -** pX->iTable made to point to the ephemeral table instead of an -** existing table. -** -** The inFlags parameter must contain exactly one of the bits -** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains -** IN_INDEX_MEMBERSHIP, then the generated table will be used for a -** fast membership test. When the IN_INDEX_LOOP bit is set, the -** IN index will be used to loop over all values of the RHS of the -** IN operator. -** -** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate -** through the set members) then the b-tree must not contain duplicates. -** An epheremal table must be used unless the selected columns are guaranteed -** to be unique - either because it is an INTEGER PRIMARY KEY or due to -** a UNIQUE constraint or index. -** -** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used -** for fast set membership tests) then an epheremal table must -** be used unless is a single INTEGER PRIMARY KEY column or an -** index can be found with the specified as its left-most. -** -** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and -** if the RHS of the IN operator is a list (not a subquery) then this -** routine might decide that creating an ephemeral b-tree for membership -** testing is too expensive and return IN_INDEX_NOOP. In that case, the -** calling routine should implement the IN operator using a sequence -** of Eq or Ne comparison operations. -** -** When the b-tree is being used for membership tests, the calling function -** might need to know whether or not the RHS side of the IN operator -** contains a NULL. If prRhsHasNull is not a NULL pointer and -** if there is any chance that the (...) might contain a NULL value at -** runtime, then a register is allocated and the register number written -** to *prRhsHasNull. If there is no chance that the (...) contains a -** NULL value, then *prRhsHasNull is left unchanged. -** -** If a register is allocated and its location stored in *prRhsHasNull, then -** the value in that register will be NULL if the b-tree contains one or more -** NULL values, and it will be some non-NULL value if the b-tree contains no -** NULL values. -** -** If the aiMap parameter is not NULL, it must point to an array containing -** one element for each column returned by the SELECT statement on the RHS -** of the IN(...) operator. The i'th entry of the array is populated with the -** offset of the index column that matches the i'th column returned by the -** SELECT. For example, if the expression and selected index are: -** -** (?,?,?) IN (SELECT a, b, c FROM t1) -** CREATE INDEX i1 ON t1(b, c, a); -** -** then aiMap[] is populated with {2, 0, 1}. -*/ -#ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int sqlite3FindInIndex( - Parse *pParse, /* Parsing context */ - Expr *pX, /* The right-hand side (RHS) of the IN operator */ - u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ - int *prRhsHasNull, /* Register holding NULL status. See notes */ - int *aiMap /* Mapping from Index fields to RHS fields */ -){ - Select *p; /* SELECT to the right of IN operator */ - int eType = 0; /* Type of RHS table. IN_INDEX_* */ - int iTab = pParse->nTab++; /* Cursor of the RHS table */ - int mustBeUnique; /* True if RHS must be unique */ - Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ - - assert( pX->op==TK_IN ); - mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; - - /* If the RHS of this IN(...) operator is a SELECT, and if it matters - ** whether or not the SELECT result contains NULL values, check whether - ** or not NULL is actually possible (it may not be, for example, due - ** to NOT NULL constraints in the schema). If no NULL values are possible, - ** set prRhsHasNull to 0 before continuing. */ - if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){ - int i; - ExprList *pEList = pX->x.pSelect->pEList; - for(i=0; inExpr; i++){ - if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; - } - if( i==pEList->nExpr ){ - prRhsHasNull = 0; - } - } - - /* Check to see if an existing table or index can be used to - ** satisfy the query. This is preferable to generating a new - ** ephemeral table. */ - if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ - sqlite3 *db = pParse->db; /* Database connection */ - Table *pTab; /* Table
    . */ - i16 iDb; /* Database idx for pTab */ - ExprList *pEList = p->pEList; - int nExpr = pEList->nExpr; - - assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ - assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ - assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ - pTab = p->pSrc->a[0].pTab; - - /* Code an OP_Transaction and OP_TableLock for
    . */ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - sqlite3CodeVerifySchema(pParse, iDb); - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - - assert(v); /* sqlite3GetVdbe() has always been previously called */ - if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ - /* The "x IN (SELECT rowid FROM table)" case */ - int iAddr = sqlite3VdbeAddOp0(v, OP_Once); - VdbeCoverage(v); - - sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - eType = IN_INDEX_ROWID; - - sqlite3VdbeJumpHere(v, iAddr); - }else{ - Index *pIdx; /* Iterator variable */ - int affinity_ok = 1; - int i; - - /* Check that the affinity that will be used to perform each - ** comparison is the same as the affinity of each column in table - ** on the RHS of the IN operator. If it not, it is not possible to - ** use any index of the RHS table. */ - for(i=0; ipLeft, i); - int iCol = pEList->a[i].pExpr->iColumn; - char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ - char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); - testcase( cmpaff==SQLITE_AFF_BLOB ); - testcase( cmpaff==SQLITE_AFF_TEXT ); - switch( cmpaff ){ - case SQLITE_AFF_BLOB: - break; - case SQLITE_AFF_TEXT: - /* sqlite3CompareAffinity() only returns TEXT if one side or the - ** other has no affinity and the other side is TEXT. Hence, - ** the only way for cmpaff to be TEXT is for idxaff to be TEXT - ** and for the term on the LHS of the IN to have no affinity. */ - assert( idxaff==SQLITE_AFF_TEXT ); - break; - default: - affinity_ok = sqlite3IsNumericAffinity(idxaff); - } - } - - if( affinity_ok ){ - /* Search for an existing index that will work for this IN operator */ - for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){ - Bitmask colUsed; /* Columns of the index used */ - Bitmask mCol; /* Mask for the current column */ - if( pIdx->nColumnnColumn==BMS-2 ); - testcase( pIdx->nColumn==BMS-1 ); - if( pIdx->nColumn>=BMS-1 ) continue; - if( mustBeUnique ){ - if( pIdx->nKeyCol>nExpr - ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) - ){ - continue; /* This index is not unique over the IN RHS columns */ - } - } - - colUsed = 0; /* Columns of index used so far */ - for(i=0; ipLeft, i); - Expr *pRhs = pEList->a[i].pExpr; - CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - int j; - - assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); - for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; - assert( pIdx->azColl[j] ); - if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ - continue; - } - break; - } - if( j==nExpr ) break; - mCol = MASKBIT(j); - if( mCol & colUsed ) break; /* Each column used only once */ - colUsed |= mCol; - if( aiMap ) aiMap[i] = j; - } - - assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); - if( colUsed==(MASKBIT(nExpr)-1) ){ - /* If we reach this point, that means the index pIdx is usable */ - int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); -#ifndef SQLITE_OMIT_EXPLAIN - sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0, - sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName), - P4_DYNAMIC); -#endif - sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); - assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); - eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - - if( prRhsHasNull ){ -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK - i64 mask = (1<nMem; - if( nExpr==1 ){ - sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); - } - } - sqlite3VdbeJumpHere(v, iAddr); - } - } /* End loop over indexes */ - } /* End if( affinity_ok ) */ - } /* End if not an rowid index */ - } /* End attempt to optimize using an index */ - - /* If no preexisting index is available for the IN clause - ** and IN_INDEX_NOOP is an allowed reply - ** and the RHS of the IN operator is a list, not a subquery - ** and the RHS is not constant or has two or fewer terms, - ** then it is not worth creating an ephemeral table to evaluate - ** the IN operator so return IN_INDEX_NOOP. - */ - if( eType==0 - && (inFlags & IN_INDEX_NOOP_OK) - && !ExprHasProperty(pX, EP_xIsSelect) - && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) - ){ - eType = IN_INDEX_NOOP; - } - - if( eType==0 ){ - /* Could not find an existing table or index to use as the RHS b-tree. - ** We will have to generate an ephemeral table to do the job. - */ - u32 savedNQueryLoop = pParse->nQueryLoop; - int rMayHaveNull = 0; - eType = IN_INDEX_EPH; - if( inFlags & IN_INDEX_LOOP ){ - pParse->nQueryLoop = 0; - if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ - eType = IN_INDEX_ROWID; - } - }else if( prRhsHasNull ){ - *prRhsHasNull = rMayHaveNull = ++pParse->nMem; - } - sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); - pParse->nQueryLoop = savedNQueryLoop; - }else{ - pX->iTable = iTab; - } - - if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ - int i, n; - n = sqlite3ExprVectorSize(pX->pLeft); - for(i=0; ipLeft; - int nVal = sqlite3ExprVectorSize(pLeft); - Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0; - char *zRet; - - assert( pExpr->op==TK_IN ); - zRet = sqlite3DbMallocZero(pParse->db, nVal+1); - if( zRet ){ - int i; - for(i=0; ipEList->a[i].pExpr, a); - }else{ - zRet[i] = a; - } - } - zRet[nVal] = '\0'; - } - return zRet; -} -#endif - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Load the Parse object passed as the first argument with an error -** message of the form: -** -** "sub-select returns N columns - expected M" -*/ -SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ - const char *zFmt = "sub-select returns %d columns - expected %d"; - sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); -} -#endif - -/* -** Generate code for scalar subqueries used as a subquery expression, EXISTS, -** or IN operators. Examples: -** -** (SELECT a FROM b) -- subquery -** EXISTS (SELECT a FROM b) -- EXISTS subquery -** x IN (4,5,11) -- IN operator with list on right-hand side -** x IN (SELECT a FROM b) -- IN operator with subquery on the right -** -** The pExpr parameter describes the expression that contains the IN -** operator or subquery. -** -** If parameter isRowid is non-zero, then expression pExpr is guaranteed -** to be of the form " IN (?, ?, ?)", where is a reference -** to some integer key column of a table B-Tree. In this case, use an -** intkey B-Tree to store the set of IN(...) values instead of the usual -** (slower) variable length keys B-Tree. -** -** If rMayHaveNull is non-zero, that means that the operation is an IN -** (not a SELECT or EXISTS) and that the RHS might contains NULLs. -** All this routine does is initialize the register given by rMayHaveNull -** to NULL. Calling routines will take care of changing this register -** value to non-NULL if the RHS is NULL-free. -** -** For a SELECT or EXISTS operator, return the register that holds the -** result. For a multi-column SELECT, the result is stored in a contiguous -** array of registers and the return value is the register of the left-most -** result column. Return 0 for IN operators or if an error occurs. -*/ -#ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int sqlite3CodeSubselect( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ - int rHasNullFlag, /* Register that records whether NULLs exist in RHS */ - int isRowid /* If true, LHS of IN operator is a rowid */ -){ - int jmpIfDynamic = -1; /* One-time test address */ - int rReg = 0; /* Register storing resulting */ - Vdbe *v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return 0; - sqlite3ExprCachePush(pParse); - - /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it - ** is encountered if any of the following is true: - ** - ** * The right-hand side is a correlated subquery - ** * The right-hand side is an expression list containing variables - ** * We are inside a trigger - ** - ** If all of the above are false, then we can run this code just once - ** save the results, and reuse the same result on subsequent invocations. - */ - if( !ExprHasProperty(pExpr, EP_VarSelect) ){ - jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - -#ifndef SQLITE_OMIT_EXPLAIN - if( pParse->explain==2 ){ - char *zMsg = sqlite3MPrintf(pParse->db, "EXECUTE %s%s SUBQUERY %d", - jmpIfDynamic>=0?"":"CORRELATED ", - pExpr->op==TK_IN?"LIST":"SCALAR", - pParse->iNextSelectId - ); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } -#endif - - switch( pExpr->op ){ - case TK_IN: { - int addr; /* Address of OP_OpenEphemeral instruction */ - Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ - KeyInfo *pKeyInfo = 0; /* Key information */ - int nVal; /* Size of vector pLeft */ - - nVal = sqlite3ExprVectorSize(pLeft); - assert( !isRowid || nVal==1 ); - - /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' - ** expression it is handled the same way. An ephemeral table is - ** filled with index keys representing the results from the - ** SELECT or the . - ** - ** If the 'x' expression is a column value, or the SELECT... - ** statement returns a column value, then the affinity of that - ** column is used to build the index keys. If both 'x' and the - ** SELECT... statement are columns, then numeric affinity is used - ** if either column has NUMERIC or INTEGER affinity. If neither - ** 'x' nor the SELECT... statement are columns, then numeric affinity - ** is used. - */ - pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, - pExpr->iTable, (isRowid?0:nVal)); - pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1); - - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - /* Case 1: expr IN (SELECT ...) - ** - ** Generate code to write the results of the select into the temporary - ** table allocated and opened above. - */ - Select *pSelect = pExpr->x.pSelect; - ExprList *pEList = pSelect->pEList; - - assert( !isRowid ); - /* If the LHS and RHS of the IN operator do not match, that - ** error will have been caught long before we reach this point. */ - if( ALWAYS(pEList->nExpr==nVal) ){ - SelectDest dest; - int i; - sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); - dest.zAffSdst = exprINAffinity(pParse, pExpr); - assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); - pSelect->iLimit = 0; - testcase( pSelect->selFlags & SF_Distinct ); - testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ - if( sqlite3Select(pParse, pSelect, &dest) ){ - sqlite3DbFree(pParse->db, dest.zAffSdst); - sqlite3KeyInfoUnref(pKeyInfo); - return 0; - } - sqlite3DbFree(pParse->db, dest.zAffSdst); - assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ - assert( pEList!=0 ); - assert( pEList->nExpr>0 ); - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq( - pParse, p, pEList->a[i].pExpr - ); - } - } - }else if( ALWAYS(pExpr->x.pList!=0) ){ - /* Case 2: expr IN (exprlist) - ** - ** For each expression, build an index key from the evaluation and - ** store it in the temporary table. If is a column, then use - ** that columns affinity when building index keys. If is not - ** a column, use numeric affinity. - */ - char affinity; /* Affinity of the LHS of the IN */ - int i; - ExprList *pList = pExpr->x.pList; - struct ExprList_item *pItem; - int r1, r2, r3; - - affinity = sqlite3ExprAffinity(pLeft); - if( !affinity ){ - affinity = SQLITE_AFF_BLOB; - } - if( pKeyInfo ){ - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - } - - /* Loop through each expression in . */ - r1 = sqlite3GetTempReg(pParse); - r2 = sqlite3GetTempReg(pParse); - if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2); - for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ - Expr *pE2 = pItem->pExpr; - int iValToIns; - - /* If the expression is not constant then we will need to - ** disable the test that was generated above that makes sure - ** this code only executes once. Because for a non-constant - ** expression we need to rerun this code each time. - */ - if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, jmpIfDynamic); - jmpIfDynamic = -1; - } - - /* Evaluate the expression and insert it into the temp table */ - if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ - sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); - }else{ - r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); - if( isRowid ){ - sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, - sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); - }else{ - sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3ExprCacheAffinityChange(pParse, r3, 1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2); - } - } - } - sqlite3ReleaseTempReg(pParse, r1); - sqlite3ReleaseTempReg(pParse, r2); - } - if( pKeyInfo ){ - sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); - } - break; - } - - case TK_EXISTS: - case TK_SELECT: - default: { - /* Case 3: (SELECT ... FROM ...) - ** or: EXISTS(SELECT ... FROM ...) - ** - ** For a SELECT, generate code to put the values for all columns of - ** the first row into an array of registers and return the index of - ** the first register. - ** - ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) - ** into a register and return that register number. - ** - ** In both cases, the query is augmented with "LIMIT 1". Any - ** preexisting limit is discarded in place of the new LIMIT 1. - */ - Select *pSel; /* SELECT statement to encode */ - SelectDest dest; /* How to deal with SELECT result */ - int nReg; /* Registers to allocate */ - - testcase( pExpr->op==TK_EXISTS ); - testcase( pExpr->op==TK_SELECT ); - assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); - - pSel = pExpr->x.pSelect; - nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; - sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); - pParse->nMem += nReg; - if( pExpr->op==TK_SELECT ){ - dest.eDest = SRT_Mem; - dest.iSdst = dest.iSDParm; - dest.nSdst = nReg; - sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); - VdbeComment((v, "Init subquery result")); - }else{ - dest.eDest = SRT_Exists; - sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); - VdbeComment((v, "Init EXISTS result")); - } - sqlite3ExprDelete(pParse->db, pSel->pLimit); - pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER, - &sqlite3IntTokens[1], 0); - pSel->iLimit = 0; - pSel->selFlags &= ~SF_MultiValue; - if( sqlite3Select(pParse, pSel, &dest) ){ - return 0; - } - rReg = dest.iSDParm; - ExprSetVVAProperty(pExpr, EP_NoReduce); - break; - } - } - - if( rHasNullFlag ){ - sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag); - } - - if( jmpIfDynamic>=0 ){ - sqlite3VdbeJumpHere(v, jmpIfDynamic); - } - sqlite3ExprCachePop(pParse); - - return rReg; -} -#endif /* SQLITE_OMIT_SUBQUERY */ - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Expr pIn is an IN(...) expression. This function checks that the -** sub-select on the RHS of the IN() operator has the same number of -** columns as the vector on the LHS. Or, if the RHS of the IN() is not -** a sub-query, that the LHS is a vector of size 1. -*/ -SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ - int nVector = sqlite3ExprVectorSize(pIn->pLeft); - if( (pIn->flags & EP_xIsSelect) ){ - if( nVector!=pIn->x.pSelect->pEList->nExpr ){ - sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); - return 1; - } - }else if( nVector!=1 ){ - if( (pIn->pLeft->flags & EP_xIsSelect) ){ - sqlite3SubselectError(pParse, nVector, 1); - }else{ - sqlite3ErrorMsg(pParse, "row value misused"); - } - return 1; - } - return 0; -} -#endif - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** Generate code for an IN expression. -** -** x IN (SELECT ...) -** x IN (value, value, ...) -** -** The left-hand side (LHS) is a scalar or vector expression. The -** right-hand side (RHS) is an array of zero or more scalar values, or a -** subquery. If the RHS is a subquery, the number of result columns must -** match the number of columns in the vector on the LHS. If the RHS is -** a list of values, the LHS must be a scalar. -** -** The IN operator is true if the LHS value is contained within the RHS. -** The result is false if the LHS is definitely not in the RHS. The -** result is NULL if the presence of the LHS in the RHS cannot be -** determined due to NULLs. -** -** This routine generates code that jumps to destIfFalse if the LHS is not -** contained within the RHS. If due to NULLs we cannot determine if the LHS -** is contained in the RHS then jump to destIfNull. If the LHS is contained -** within the RHS then fall through. -** -** See the separate in-operator.md documentation file in the canonical -** SQLite source tree for additional information. -*/ -static void sqlite3ExprCodeIN( - Parse *pParse, /* Parsing and code generating context */ - Expr *pExpr, /* The IN expression */ - int destIfFalse, /* Jump here if LHS is not contained in the RHS */ - int destIfNull /* Jump here if the results are unknown due to NULLs */ -){ - int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ - int eType; /* Type of the RHS */ - int rLhs; /* Register(s) holding the LHS values */ - int rLhsOrig; /* LHS values prior to reordering by aiMap[] */ - Vdbe *v; /* Statement under construction */ - int *aiMap = 0; /* Map from vector field to index column */ - char *zAff = 0; /* Affinity string for comparisons */ - int nVector; /* Size of vectors for this IN operator */ - int iDummy; /* Dummy parameter to exprCodeVector() */ - Expr *pLeft; /* The LHS of the IN operator */ - int i; /* loop counter */ - int destStep2; /* Where to jump when NULLs seen in step 2 */ - int destStep6 = 0; /* Start of code for Step 6 */ - int addrTruthOp; /* Address of opcode that determines the IN is true */ - int destNotNull; /* Jump here if a comparison is not true in step 6 */ - int addrTop; /* Top of the step-6 loop */ - - pLeft = pExpr->pLeft; - if( sqlite3ExprCheckIN(pParse, pExpr) ) return; - zAff = exprINAffinity(pParse, pExpr); - nVector = sqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)sqlite3DbMallocZero( - pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 - ); - if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; - - /* Attempt to compute the RHS. After this step, if anything other than - ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable - ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, - ** the RHS has not yet been coded. */ - v = pParse->pVdbe; - assert( v!=0 ); /* OOM detected prior to this routine */ - VdbeNoopComment((v, "begin IN expr")); - eType = sqlite3FindInIndex(pParse, pExpr, - IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, - destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap); - - assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH - || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC - ); -#ifdef SQLITE_DEBUG - /* Confirm that aiMap[] contains nVector integer values between 0 and - ** nVector-1. */ - for(i=0; i from " IN (...)". If the LHS is a - ** vector, then it is stored in an array of nVector registers starting - ** at r1. - ** - ** sqlite3FindInIndex() might have reordered the fields of the LHS vector - ** so that the fields are in the same order as an existing index. The - ** aiMap[] array contains a mapping from the original LHS field order to - ** the field order that matches the RHS index. - */ - sqlite3ExprCachePush(pParse); - rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); - for(i=0; ix.pList; - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - int labelOk = sqlite3VdbeMakeLabel(v); - int r2, regToFree; - int regCkNull = 0; - int ii; - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - if( destIfNull!=destIfFalse ){ - regCkNull = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); - } - for(ii=0; iinExpr; ii++){ - r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); - if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ - sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); - } - if( iinExpr-1 || destIfNull!=destIfFalse ){ - sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2, - (void*)pColl, P4_COLLSEQ); - VdbeCoverageIf(v, iinExpr-1); - VdbeCoverageIf(v, ii==pList->nExpr-1); - sqlite3VdbeChangeP5(v, zAff[0]); - }else{ - assert( destIfNull==destIfFalse ); - sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2, - (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); - } - sqlite3ReleaseTempReg(pParse, regToFree); - } - if( regCkNull ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); - sqlite3VdbeGoto(v, destIfFalse); - } - sqlite3VdbeResolveLabel(v, labelOk); - sqlite3ReleaseTempReg(pParse, regCkNull); - goto sqlite3ExprCodeIN_finished; - } - - /* Step 2: Check to see if the LHS contains any NULL columns. If the - ** LHS does contain NULLs then the result must be either FALSE or NULL. - ** We will then skip the binary search of the RHS. - */ - if( destIfNull==destIfFalse ){ - destStep2 = destIfFalse; - }else{ - destStep2 = destStep6 = sqlite3VdbeMakeLabel(v); - } - for(i=0; ipLeft, i); - if( sqlite3ExprCanBeNull(p) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); - VdbeCoverage(v); - } - } - - /* Step 3. The LHS is now known to be non-NULL. Do the binary search - ** of the RHS using the LHS as a probe. If found, the result is - ** true. - */ - if( eType==IN_INDEX_ROWID ){ - /* In this case, the RHS is the ROWID of table b-tree and so we also - ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 - ** into a single opcode. */ - sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs); - VdbeCoverage(v); - addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ - }else{ - sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); - if( destIfFalse==destIfNull ){ - /* Combine Step 3 and Step 5 into a single opcode */ - sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, - rLhs, nVector); VdbeCoverage(v); - goto sqlite3ExprCodeIN_finished; - } - /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ - addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, - rLhs, nVector); VdbeCoverage(v); - } - - /* Step 4. If the RHS is known to be non-NULL and we did not find - ** an match on the search above, then the result must be FALSE. - */ - if( rRhsHasNull && nVector==1 ){ - sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); - VdbeCoverage(v); - } - - /* Step 5. If we do not care about the difference between NULL and - ** FALSE, then just return false. - */ - if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); - - /* Step 6: Loop through rows of the RHS. Compare each row to the LHS. - ** If any comparison is NULL, then the result is NULL. If all - ** comparisons are FALSE then the final result is FALSE. - ** - ** For a scalar LHS, it is sufficient to check just the first row - ** of the RHS. - */ - if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); - VdbeCoverage(v); - if( nVector>1 ){ - destNotNull = sqlite3VdbeMakeLabel(v); - }else{ - /* For nVector==1, combine steps 6 and 7 by immediately returning - ** FALSE if the first comparison is not NULL */ - destNotNull = destIfFalse; - } - for(i=0; iiTable, i, r3); - sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, - (void*)pColl, P4_COLLSEQ); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, r3); - } - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); - if( nVector>1 ){ - sqlite3VdbeResolveLabel(v, destNotNull); - sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1); - VdbeCoverage(v); - - /* Step 7: If we reach this point, we know that the result must - ** be false. */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); - } - - /* Jumps here in order to return true. */ - sqlite3VdbeJumpHere(v, addrTruthOp); - -sqlite3ExprCodeIN_finished: - if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs); - sqlite3ExprCachePop(pParse); - VdbeComment((v, "end IN expr")); -sqlite3ExprCodeIN_oom_error: - sqlite3DbFree(pParse->db, aiMap); - sqlite3DbFree(pParse->db, zAff); -} -#endif /* SQLITE_OMIT_SUBQUERY */ - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** Generate an instruction that will put the floating point -** value described by z[0..n-1] into register iMem. -** -** The z[] string will probably not be zero-terminated. But the -** z[n] character is guaranteed to be something that does not look -** like the continuation of the number. -*/ -static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ - if( ALWAYS(z!=0) ){ - double value; - sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); - assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ - if( negateFlag ) value = -value; - sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); - } -} -#endif - - -/* -** Generate an instruction that will put the integer describe by -** text z[0..n-1] into register iMem. -** -** Expr.u.zToken is always UTF8 and zero-terminated. -*/ -static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ - Vdbe *v = pParse->pVdbe; - if( pExpr->flags & EP_IntValue ){ - int i = pExpr->u.iValue; - assert( i>=0 ); - if( negFlag ) i = -i; - sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); - }else{ - int c; - i64 value; - const char *z = pExpr->u.zToken; - assert( z!=0 ); - c = sqlite3DecOrHexToI64(z, &value); - if( c==0 || (c==2 && negFlag) ){ - if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); - }else{ -#ifdef SQLITE_OMIT_FLOATING_POINT - sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); -#else -#ifndef SQLITE_OMIT_HEX_INTEGER - if( sqlite3_strnicmp(z,"0x",2)==0 ){ - sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); - }else -#endif - { - codeReal(v, z, negFlag, iMem); - } -#endif - } - } -} - -/* -** Erase column-cache entry number i -*/ -static void cacheEntryClear(Parse *pParse, int i){ - if( pParse->aColCache[i].tempReg ){ - if( pParse->nTempRegaTempReg) ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache--; - if( inColCache ){ - pParse->aColCache[i] = pParse->aColCache[pParse->nColCache]; - } -} - - -/* -** Record in the column cache that a particular column from a -** particular table is stored in a particular register. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ - int i; - int minLru; - int idxLru; - struct yColCache *p; - - /* Unless an error has occurred, register numbers are always positive. */ - assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); - assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ - - /* The SQLITE_ColumnCache flag disables the column cache. This is used - ** for testing only - to verify that SQLite always gets the same answer - ** with and without the column cache. - */ - if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; - - /* First replace any existing entry. - ** - ** Actually, the way the column cache is currently used, we are guaranteed - ** that the object will never already be in cache. Verify this guarantee. - */ -#ifndef NDEBUG - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - assert( p->iTable!=iTab || p->iColumn!=iCol ); - } -#endif - - /* If the cache is already full, delete the least recently used entry */ - if( pParse->nColCache>=SQLITE_N_COLCACHE ){ - minLru = 0x7fffffff; - idxLru = -1; - for(i=0, p=pParse->aColCache; ilrulru; - } - } - p = &pParse->aColCache[idxLru]; - }else{ - p = &pParse->aColCache[pParse->nColCache++]; - } - - /* Add the new entry to the end of the cache */ - p->iLevel = pParse->iCacheLevel; - p->iTable = iTab; - p->iColumn = iCol; - p->iReg = iReg; - p->tempReg = 0; - p->lru = pParse->iCacheCnt++; -} - -/* -** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. -** Purge the range of registers from the column cache. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ - int i = 0; - while( inColCache ){ - struct yColCache *p = &pParse->aColCache[i]; - if( p->iReg >= iReg && p->iReg < iReg+nReg ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** Remember the current column cache context. Any new entries added -** added to the column cache after this call are removed when the -** corresponding pop occurs. -*/ -SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){ - pParse->iCacheLevel++; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("PUSH to %d\n", pParse->iCacheLevel); - } -#endif -} - -/* -** Remove from the column cache any entries that were added since the -** the previous sqlite3ExprCachePush operation. In other words, restore -** the cache to the state it was in prior the most recent Push. -*/ -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ - int i = 0; - assert( pParse->iCacheLevel>=1 ); - pParse->iCacheLevel--; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("POP to %d\n", pParse->iCacheLevel); - } -#endif - while( inColCache ){ - if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** When a cached column is reused, make sure that its register is -** no longer available as a temp register. ticket #3879: that same -** register might be in the cache in multiple places, so be sure to -** get them all. -*/ -static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 0; - } - } -} - -/* Generate code that will load into register regOut a value that is -** appropriate for the iIdxCol-th column of index pIdx. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn( - Parse *pParse, /* The parsing context */ - Index *pIdx, /* The index whose column is to be loaded */ - int iTabCur, /* Cursor pointing to a table row */ - int iIdxCol, /* The column of the index to be loaded */ - int regOut /* Store the index column value in this register */ -){ - i16 iTabCol = pIdx->aiColumn[iIdxCol]; - if( iTabCol==XN_EXPR ){ - assert( pIdx->aColExpr ); - assert( pIdx->aColExpr->nExpr>iIdxCol ); - pParse->iSelfTab = iTabCur; - sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); - }else{ - sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, - iTabCol, regOut); - } -} - -/* -** Generate code to extract the value of the iCol-th column of a table. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( - Vdbe *v, /* The VDBE under construction */ - Table *pTab, /* The table containing the value */ - int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ - int iCol, /* Index of the column to extract */ - int regOut /* Extract the value into this register */ -){ - if( iCol<0 || iCol==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); - }else{ - int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; - int x = iCol; - if( !HasRowid(pTab) && !IsVirtual(pTab) ){ - x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol); - } - sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); - } - if( iCol>=0 ){ - sqlite3ColumnDefault(v, pTab, iCol, regOut); - } -} - -/* -** Generate code that will extract the iColumn-th column from -** table pTab and store the column value in a register. -** -** An effort is made to store the column value in register iReg. This -** is not garanteeed for GetColumn() - the result can be stored in -** any register. But the result is guaranteed to land in register iReg -** for GetColumnToReg(). -** -** There must be an open cursor to pTab in iTable when this routine -** is called. If iColumn<0 then code is generated that extracts the rowid. -*/ -SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg, /* Store results here */ - u8 p5 /* P5 value for OP_Column + FLAGS */ -){ - Vdbe *v = pParse->pVdbe; - int i; - struct yColCache *p; - - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iTable==iTable && p->iColumn==iColumn ){ - p->lru = pParse->iCacheCnt++; - sqlite3ExprCachePinRegister(pParse, p->iReg); - return p->iReg; - } - } - assert( v!=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); - if( p5 ){ - sqlite3VdbeChangeP5(v, p5); - }else{ - sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); - } - return iReg; -} -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg /* Store results here */ -){ - int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); - if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); -} - - -/* -** Clear all column cache entries. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){ - int i; - -#if SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("CLEAR\n"); - } -#endif - for(i=0; inColCache; i++){ - if( pParse->aColCache[i].tempReg - && pParse->nTempRegaTempReg) - ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache = 0; -} - -/* -** Record the fact that an affinity change has occurred on iCount -** registers starting with iStart. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ - sqlite3ExprCacheRemove(pParse, iStart, iCount); -} - -/* -** Generate code to move content from registers iFrom...iFrom+nReg-1 -** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ - assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); - sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); - sqlite3ExprCacheRemove(pParse, iFrom, nReg); -} - -#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) -/* -** Return true if any register in the range iFrom..iTo (inclusive) -** is used as part of the column cache. -** -** This routine is used within assert() and testcase() macros only -** and does not appear in a normal build. -*/ -static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - int r = p->iReg; - if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ - } - return 0; -} -#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ - - -/* -** Convert a scalar expression node to a TK_REGISTER referencing -** register iReg. The caller must ensure that iReg already contains -** the correct value for the expression. -*/ -static void exprToRegister(Expr *p, int iReg){ - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iReg; - ExprClearProperty(p, EP_Skip); -} - -/* -** Evaluate an expression (either a vector or a scalar expression) and store -** the result in continguous temporary registers. Return the index of -** the first register used to store the result. -** -** If the returned result register is a temporary scalar, then also write -** that register number into *piFreeable. If the returned result register -** is not a temporary or if the expression is a vector set *piFreeable -** to 0. -*/ -static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ - int iResult; - int nResult = sqlite3ExprVectorSize(p); - if( nResult==1 ){ - iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); - }else{ - *piFreeable = 0; - if( p->op==TK_SELECT ){ - iResult = sqlite3CodeSubselect(pParse, p, 0, 0); - }else{ - int i; - iResult = pParse->nMem+1; - pParse->nMem += nResult; - for(i=0; ix.pList->a[i].pExpr, i+iResult); - } - } - } - return iResult; -} - - -/* -** Generate code into the current Vdbe to evaluate the given -** expression. Attempt to store the results in register "target". -** Return the register where results are stored. -** -** With this routine, there is no guarantee that results will -** be stored in target. The result might be stored in some other -** register if it is convenient to do so. The calling function -** must check the return code and move the results to the desired -** register. -*/ -SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ - Vdbe *v = pParse->pVdbe; /* The VM under construction */ - int op; /* The opcode being coded */ - int inReg = target; /* Results stored in register inReg */ - int regFree1 = 0; /* If non-zero free this temporary register */ - int regFree2 = 0; /* If non-zero free this temporary register */ - int r1, r2; /* Various register numbers */ - Expr tempX; /* Temporary expression node */ - int p5 = 0; - - assert( target>0 && target<=pParse->nMem ); - if( v==0 ){ - assert( pParse->db->mallocFailed ); - return 0; - } - - if( pExpr==0 ){ - op = TK_NULL; - }else{ - op = pExpr->op; - } - switch( op ){ - case TK_AGG_COLUMN: { - AggInfo *pAggInfo = pExpr->pAggInfo; - struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg]; - if( !pAggInfo->directMode ){ - assert( pCol->iMem>0 ); - return pCol->iMem; - }else if( pAggInfo->useSortingIdx ){ - sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, - pCol->iSorterColumn, target); - return target; - } - /* Otherwise, fall thru into the TK_COLUMN case */ - } - case TK_COLUMN: { - int iTab = pExpr->iTable; - if( iTab<0 ){ - if( pParse->ckBase>0 ){ - /* Generating CHECK constraints or inserting into partial index */ - return pExpr->iColumn + pParse->ckBase; - }else{ - /* Coding an expression that is part of an index where column names - ** in the index refer to the table to which the index belongs */ - iTab = pParse->iSelfTab; - } - } - return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, - pExpr->iColumn, iTab, target, - pExpr->op2); - } - case TK_INTEGER: { - codeInteger(pParse, pExpr, 0, target); - return target; - } -#ifndef SQLITE_OMIT_FLOATING_POINT - case TK_FLOAT: { - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - codeReal(v, pExpr->u.zToken, 0, target); - return target; - } -#endif - case TK_STRING: { - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3VdbeLoadString(v, target, pExpr->u.zToken); - return target; - } - case TK_NULL: { - sqlite3VdbeAddOp2(v, OP_Null, 0, target); - return target; - } -#ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: { - int n; - const char *z; - char *zBlob; - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); - assert( pExpr->u.zToken[1]=='\'' ); - z = &pExpr->u.zToken[2]; - n = sqlite3Strlen30(z) - 1; - assert( z[n]=='\'' ); - zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); - sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); - return target; - } -#endif - case TK_VARIABLE: { - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - assert( pExpr->u.zToken!=0 ); - assert( pExpr->u.zToken[0]!=0 ); - sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); - if( pExpr->u.zToken[1]!=0 ){ - assert( pExpr->u.zToken[0]=='?' - || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); - sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); - } - return target; - } - case TK_REGISTER: { - return pExpr->iTable; - } -#ifndef SQLITE_OMIT_CAST - case TK_CAST: { - /* Expressions of the form: CAST(pLeft AS token) */ - inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - if( inReg!=target ){ - sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); - inReg = target; - } - sqlite3VdbeAddOp2(v, OP_Cast, target, - sqlite3AffinityType(pExpr->u.zToken, 0)); - testcase( usedAsColumnCache(pParse, inReg, inReg) ); - sqlite3ExprCacheAffinityChange(pParse, inReg, 1); - return inReg; - } -#endif /* SQLITE_OMIT_CAST */ - case TK_IS: - case TK_ISNOT: - op = (op==TK_IS) ? TK_EQ : TK_NE; - p5 = SQLITE_NULLEQ; - /* fall-through */ - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - Expr *pLeft = pExpr->pLeft; - if( sqlite3ExprIsVector(pLeft) ){ - codeVectorCompare(pParse, pExpr, target, op, p5); - }else{ - r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2 | p5); - assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - } - break; - } - case TK_AND: - case TK_OR: - case TK_PLUS: - case TK_STAR: - case TK_MINUS: - case TK_REM: - case TK_BITAND: - case TK_BITOR: - case TK_SLASH: - case TK_LSHIFT: - case TK_RSHIFT: - case TK_CONCAT: { - assert( TK_AND==OP_And ); testcase( op==TK_AND ); - assert( TK_OR==OP_Or ); testcase( op==TK_OR ); - assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); - assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS ); - assert( TK_REM==OP_Remainder ); testcase( op==TK_REM ); - assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND ); - assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR ); - assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH ); - assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); - assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); - assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - sqlite3VdbeAddOp3(v, op, r2, r1, target); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_UMINUS: { - Expr *pLeft = pExpr->pLeft; - assert( pLeft ); - if( pLeft->op==TK_INTEGER ){ - codeInteger(pParse, pLeft, 1, target); - return target; -#ifndef SQLITE_OMIT_FLOATING_POINT - }else if( pLeft->op==TK_FLOAT ){ - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - codeReal(v, pLeft->u.zToken, 1, target); - return target; -#endif - }else{ - tempX.op = TK_INTEGER; - tempX.flags = EP_IntValue|EP_TokenOnly; - tempX.u.iValue = 0; - r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); - sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); - testcase( regFree2==0 ); - } - break; - } - case TK_BITNOT: - case TK_NOT: { - assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); - assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - testcase( regFree1==0 ); - sqlite3VdbeAddOp2(v, op, r1, inReg); - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - int addr; - assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); - assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); - sqlite3VdbeAddOp2(v, OP_Integer, 1, target); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - testcase( regFree1==0 ); - addr = sqlite3VdbeAddOp1(v, op, r1); - VdbeCoverageIf(v, op==TK_ISNULL); - VdbeCoverageIf(v, op==TK_NOTNULL); - sqlite3VdbeAddOp2(v, OP_Integer, 0, target); - sqlite3VdbeJumpHere(v, addr); - break; - } - case TK_AGG_FUNCTION: { - AggInfo *pInfo = pExpr->pAggInfo; - if( pInfo==0 ){ - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); - }else{ - return pInfo->aFunc[pExpr->iAgg].iMem; - } - break; - } - case TK_FUNCTION: { - ExprList *pFarg; /* List of function arguments */ - int nFarg; /* Number of function arguments */ - FuncDef *pDef; /* The function definition object */ - const char *zId; /* The function name */ - u32 constMask = 0; /* Mask of function arguments that are constant */ - int i; /* Loop counter */ - sqlite3 *db = pParse->db; /* The database connection */ - u8 enc = ENC(db); /* The text encoding used by this database */ - CollSeq *pColl = 0; /* A collating sequence */ - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - if( ExprHasProperty(pExpr, EP_TokenOnly) ){ - pFarg = 0; - }else{ - pFarg = pExpr->x.pList; - } - nFarg = pFarg ? pFarg->nExpr : 0; - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - zId = pExpr->u.zToken; - pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0); -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - if( pDef==0 && pParse->explain ){ - pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); - } -#endif - if( pDef==0 || pDef->xFinalize!=0 ){ - sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); - break; - } - - /* Attempt a direct implementation of the built-in COALESCE() and - ** IFNULL() functions. This avoids unnecessary evaluation of - ** arguments past the first non-NULL argument. - */ - if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ - int endCoalesce = sqlite3VdbeMakeLabel(v); - assert( nFarg>=2 ); - sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); - for(i=1; ia[i].pExpr, target); - sqlite3ExprCachePop(pParse); - } - sqlite3VdbeResolveLabel(v, endCoalesce); - break; - } - - /* The UNLIKELY() function is a no-op. The result is the value - ** of the first argument. - */ - if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ - assert( nFarg>=1 ); - return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); - } - - for(i=0; ia[i].pExpr) ){ - testcase( i==31 ); - constMask |= MASKBIT32(i); - } - if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); - } - } - if( pFarg ){ - if( constMask ){ - r1 = pParse->nMem+1; - pParse->nMem += nFarg; - }else{ - r1 = sqlite3GetTempRange(pParse, nFarg); - } - - /* For length() and typeof() functions with a column argument, - ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG - ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data - ** loading. - */ - if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ - u8 exprOp; - assert( nFarg==1 ); - assert( pFarg->a[0].pExpr!=0 ); - exprOp = pFarg->a[0].pExpr->op; - if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ - assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); - assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); - testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); - pFarg->a[0].pExpr->op2 = - pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); - } - } - - sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ - sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, - SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); - sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ - }else{ - r1 = 0; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Possibly overload the function if the first argument is - ** a virtual table column. - ** - ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the - ** second argument, not the first, as the argument to test to - ** see if it is a column in a virtual table. This is done because - ** the left operand of infix functions (the operand we want to - ** control overloading) ends up as the second argument to the - ** function. The expression "A glob B" is equivalent to - ** "glob(B,A). We want to use the A in "A glob B" to test - ** for function overloading. But we use the B term in "glob(B,A)". - */ - if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); - }else if( nFarg>0 ){ - pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); - } -#endif - if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - if( !pColl ) pColl = db->pDfltColl; - sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); - } - sqlite3VdbeAddOp4(v, OP_Function0, constMask, r1, target, - (char*)pDef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nFarg); - if( nFarg && constMask==0 ){ - sqlite3ReleaseTempRange(pParse, r1, nFarg); - } - return target; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_EXISTS: - case TK_SELECT: { - int nCol; - testcase( op==TK_EXISTS ); - testcase( op==TK_SELECT ); - if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){ - sqlite3SubselectError(pParse, nCol, 1); - }else{ - return sqlite3CodeSubselect(pParse, pExpr, 0, 0); - } - break; - } - case TK_SELECT_COLUMN: { - if( pExpr->pLeft->iTable==0 ){ - pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0); - } - return pExpr->pLeft->iTable + pExpr->iColumn; - } - case TK_IN: { - int destIfFalse = sqlite3VdbeMakeLabel(v); - int destIfNull = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_Null, 0, target); - sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); - sqlite3VdbeAddOp2(v, OP_Integer, 1, target); - sqlite3VdbeResolveLabel(v, destIfFalse); - sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); - sqlite3VdbeResolveLabel(v, destIfNull); - return target; - } -#endif /* SQLITE_OMIT_SUBQUERY */ - - - /* - ** x BETWEEN y AND z - ** - ** This is equivalent to - ** - ** x>=y AND x<=z - ** - ** X is stored in pExpr->pLeft. - ** Y is stored in pExpr->pList->a[0].pExpr. - ** Z is stored in pExpr->pList->a[1].pExpr. - */ - case TK_BETWEEN: { - exprCodeBetween(pParse, pExpr, target, 0, 0); - return target; - } - case TK_SPAN: - case TK_COLLATE: - case TK_UPLUS: { - return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - } - - case TK_TRIGGER: { - /* If the opcode is TK_TRIGGER, then the expression is a reference - ** to a column in the new.* or old.* pseudo-tables available to - ** trigger programs. In this case Expr.iTable is set to 1 for the - ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn - ** is set to the column of the pseudo-table to read, or to -1 to - ** read the rowid field. - ** - ** The expression is implemented using an OP_Param opcode. The p1 - ** parameter is set to 0 for an old.rowid reference, or to (i+1) - ** to reference another column of the old.* pseudo-table, where - ** i is the index of the column. For a new.rowid reference, p1 is - ** set to (n+1), where n is the number of columns in each pseudo-table. - ** For a reference to any other column in the new.* pseudo-table, p1 - ** is set to (n+2+i), where n and i are as defined previously. For - ** example, if the table on which triggers are being fired is - ** declared as: - ** - ** CREATE TABLE t1(a, b); - ** - ** Then p1 is interpreted as follows: - ** - ** p1==0 -> old.rowid p1==3 -> new.rowid - ** p1==1 -> old.a p1==4 -> new.a - ** p1==2 -> old.b p1==5 -> new.b - */ - Table *pTab = pExpr->pTab; - int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; - - assert( pExpr->iTable==0 || pExpr->iTable==1 ); - assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol ); - assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey ); - assert( p1>=0 && p1<(pTab->nCol*2+2) ); - - sqlite3VdbeAddOp2(v, OP_Param, p1, target); - VdbeComment((v, "%s.%s -> $%d", - (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), - target - )); - -#ifndef SQLITE_OMIT_FLOATING_POINT - /* If the column has REAL affinity, it may currently be stored as an - ** integer. Use OP_RealAffinity to make sure it is really real. - ** - ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to - ** floating point when extracting it from the record. */ - if( pExpr->iColumn>=0 - && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL - ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, target); - } -#endif - break; - } - - case TK_VECTOR: { - sqlite3ErrorMsg(pParse, "row value misused"); - break; - } - - /* - ** Form A: - ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END - ** - ** Form B: - ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END - ** - ** Form A is can be transformed into the equivalent form B as follows: - ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... - ** WHEN x=eN THEN rN ELSE y END - ** - ** X (if it exists) is in pExpr->pLeft. - ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is - ** odd. The Y is also optional. If the number of elements in x.pList - ** is even, then Y is omitted and the "otherwise" result is NULL. - ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. - ** - ** The result of the expression is the Ri for the first matching Ei, - ** or if there is no matching Ei, the ELSE term Y, or if there is - ** no ELSE term, NULL. - */ - default: assert( op==TK_CASE ); { - int endLabel; /* GOTO label for end of CASE stmt */ - int nextCase; /* GOTO label for next WHEN clause */ - int nExpr; /* 2x number of WHEN terms */ - int i; /* Loop counter */ - ExprList *pEList; /* List of WHEN terms */ - struct ExprList_item *aListelem; /* Array of WHEN terms */ - Expr opCompare; /* The X==Ei expression */ - Expr *pX; /* The X expression */ - Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ - VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); - assert(pExpr->x.pList->nExpr > 0); - pEList = pExpr->x.pList; - aListelem = pEList->a; - nExpr = pEList->nExpr; - endLabel = sqlite3VdbeMakeLabel(v); - if( (pX = pExpr->pLeft)!=0 ){ - tempX = *pX; - testcase( pX->op==TK_COLUMN ); - exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1)); - testcase( regFree1==0 ); - memset(&opCompare, 0, sizeof(opCompare)); - opCompare.op = TK_EQ; - opCompare.pLeft = &tempX; - pTest = &opCompare; - /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: - ** The value in regFree1 might get SCopy-ed into the file result. - ** So make sure that the regFree1 register is not reused for other - ** purposes and possibly overwritten. */ - regFree1 = 0; - } - for(i=0; iop==TK_COLUMN ); - sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); - testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); - sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); - sqlite3VdbeGoto(v, endLabel); - sqlite3ExprCachePop(pParse); - sqlite3VdbeResolveLabel(v, nextCase); - } - if( (nExpr&1)!=0 ){ - sqlite3ExprCachePush(pParse); - sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); - sqlite3ExprCachePop(pParse); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, target); - } - assert( pParse->db->mallocFailed || pParse->nErr>0 - || pParse->iCacheLevel==iCacheLevel ); - sqlite3VdbeResolveLabel(v, endLabel); - break; - } -#ifndef SQLITE_OMIT_TRIGGER - case TK_RAISE: { - assert( pExpr->affinity==OE_Rollback - || pExpr->affinity==OE_Abort - || pExpr->affinity==OE_Fail - || pExpr->affinity==OE_Ignore - ); - if( !pParse->pTriggerTab ){ - sqlite3ErrorMsg(pParse, - "RAISE() may only be used within a trigger-program"); - return 0; - } - if( pExpr->affinity==OE_Abort ){ - sqlite3MayAbort(pParse); - } - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - if( pExpr->affinity==OE_Ignore ){ - sqlite3VdbeAddOp4( - v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); - VdbeCoverage(v); - }else{ - sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, - pExpr->affinity, pExpr->u.zToken, 0, 0); - } - - break; - } -#endif - } - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); - return inReg; -} - -/* -** Factor out the code of the given expression to initialization time. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeAtInit( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* The expression to code when the VDBE initializes */ - int regDest, /* Store the value in this register */ - u8 reusable /* True if this expression is reusable */ -){ - ExprList *p; - assert( ConstFactorOk(pParse) ); - p = pParse->pConstExpr; - pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); - p = sqlite3ExprListAppend(pParse, p, pExpr); - if( p ){ - struct ExprList_item *pItem = &p->a[p->nExpr-1]; - pItem->u.iConstExprReg = regDest; - pItem->reusable = reusable; - } - pParse->pConstExpr = p; -} - -/* -** Generate code to evaluate an expression and store the results -** into a register. Return the register number where the results -** are stored. -** -** If the register is a temporary register that can be deallocated, -** then write its number into *pReg. If the result register is not -** a temporary, then set *pReg to zero. -** -** If pExpr is a constant, then this routine might generate this -** code to fill the register in the initialization section of the -** VDBE program, in order to factor it out of the evaluation loop. -*/ -SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ - int r2; - pExpr = sqlite3ExprSkipCollate(pExpr); - if( ConstFactorOk(pParse) - && pExpr->op!=TK_REGISTER - && sqlite3ExprIsConstantNotJoin(pExpr) - ){ - ExprList *p = pParse->pConstExpr; - int i; - *pReg = 0; - if( p ){ - struct ExprList_item *pItem; - for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ - return pItem->u.iConstExprReg; - } - } - } - r2 = ++pParse->nMem; - sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1); - }else{ - int r1 = sqlite3GetTempReg(pParse); - r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); - if( r2==r1 ){ - *pReg = r1; - }else{ - sqlite3ReleaseTempReg(pParse, r1); - *pReg = 0; - } - } - return r2; -} - -/* -** Generate code that will evaluate expression pExpr and store the -** results in register target. The results are guaranteed to appear -** in register target. -*/ -SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ - int inReg; - - assert( target>0 && target<=pParse->nMem ); - if( pExpr && pExpr->op==TK_REGISTER ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target); - }else{ - inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); - assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); - if( inReg!=target && pParse->pVdbe ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target); - } - } -} - -/* -** Make a transient copy of expression pExpr and then code it using -** sqlite3ExprCode(). This routine works just like sqlite3ExprCode() -** except that the input expression is guaranteed to be unchanged. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ - sqlite3 *db = pParse->db; - pExpr = sqlite3ExprDup(db, pExpr, 0); - if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target); - sqlite3ExprDelete(db, pExpr); -} - -/* -** Generate code that will evaluate expression pExpr and store the -** results in register target. The results are guaranteed to appear -** in register target. If the expression is constant, then this routine -** might choose to code the expression at initialization time. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target, 0); - }else{ - sqlite3ExprCode(pParse, pExpr, target); - } -} - -/* -** Generate code that evaluates the given expression and puts the result -** in register target. -** -** Also make a copy of the expression results into another "cache" register -** and modify the expression so that the next time it is evaluated, -** the result is a copy of the cache register. -** -** This routine is used for expressions that are used multiple -** times. They are evaluated once and the results of the expression -** are reused. -*/ -SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ - Vdbe *v = pParse->pVdbe; - int iMem; - - assert( target>0 ); - assert( pExpr->op!=TK_REGISTER ); - sqlite3ExprCode(pParse, pExpr, target); - iMem = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Copy, target, iMem); - exprToRegister(pExpr, iMem); -} - -/* -** Generate code that pushes the value of every element of the given -** expression list into a sequence of registers beginning at target. -** -** Return the number of elements evaluated. -** -** The SQLITE_ECEL_DUP flag prevents the arguments from being -** filled using OP_SCopy. OP_Copy must be used instead. -** -** The SQLITE_ECEL_FACTOR argument allows constant arguments to be -** factored out into initialization code. -** -** The SQLITE_ECEL_REF flag means that expressions in the list with -** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored -** in registers at srcReg, and so the value can be copied from there. -*/ -SQLITE_PRIVATE int sqlite3ExprCodeExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* The expression list to be coded */ - int target, /* Where to write results */ - int srcReg, /* Source registers if SQLITE_ECEL_REF */ - u8 flags /* SQLITE_ECEL_* flags */ -){ - struct ExprList_item *pItem; - int i, j, n; - u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; - Vdbe *v = pParse->pVdbe; - assert( pList!=0 ); - assert( target>0 ); - assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ - n = pList->nExpr; - if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; - for(pItem=pList->a, i=0; ipExpr; - if( (flags & SQLITE_ECEL_REF)!=0 && (j = pList->a[i].u.x.iOrderByCol)>0 ){ - sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); - }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); - }else{ - int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); - if( inReg!=target+i ){ - VdbeOp *pOp; - if( copyOp==OP_Copy - && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy - && pOp->p1+pOp->p3+1==inReg - && pOp->p2+pOp->p3+1==target+i - ){ - pOp->p3++; - }else{ - sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); - } - } - } - } - return n; -} - -/* -** Generate code for a BETWEEN operator. -** -** x BETWEEN y AND z -** -** The above is equivalent to -** -** x>=y AND x<=z -** -** Code it as such, taking care to do the common subexpression -** elimination of x. -** -** The xJumpIf parameter determines details: -** -** NULL: Store the boolean result in reg[dest] -** sqlite3ExprIfTrue: Jump to dest if true -** sqlite3ExprIfFalse: Jump to dest if false -** -** The jumpIfNull parameter is ignored if xJumpIf is NULL. -*/ -static void exprCodeBetween( - Parse *pParse, /* Parsing and code generating context */ - Expr *pExpr, /* The BETWEEN expression */ - int dest, /* Jump destination or storage location */ - void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ - int jumpIfNull /* Take the jump if the BETWEEN is NULL */ -){ - Expr exprAnd; /* The AND operator in x>=y AND x<=z */ - Expr compLeft; /* The x>=y term */ - Expr compRight; /* The x<=z term */ - Expr exprX; /* The x subexpression */ - int regFree1 = 0; /* Temporary use register */ - - - memset(&compLeft, 0, sizeof(Expr)); - memset(&compRight, 0, sizeof(Expr)); - memset(&exprAnd, 0, sizeof(Expr)); - - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - exprX = *pExpr->pLeft; - exprAnd.op = TK_AND; - exprAnd.pLeft = &compLeft; - exprAnd.pRight = &compRight; - compLeft.op = TK_GE; - compLeft.pLeft = &exprX; - compLeft.pRight = pExpr->x.pList->a[0].pExpr; - compRight.op = TK_LE; - compRight.pLeft = &exprX; - compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprToRegister(&exprX, exprCodeVector(pParse, &exprX, ®Free1)); - if( xJump ){ - xJump(pParse, &exprAnd, dest, jumpIfNull); - }else{ - exprX.flags |= EP_FromJoin; - sqlite3ExprCodeTarget(pParse, &exprAnd, dest); - } - sqlite3ReleaseTempReg(pParse, regFree1); - - /* Ensure adequate test coverage */ - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); - testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); - testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); - testcase( xJump==0 ); -} - -/* -** Generate code for a boolean expression such that a jump is made -** to the label "dest" if the expression is true but execution -** continues straight thru if the expression is false. -** -** If the expression evaluates to NULL (neither true nor false), then -** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL. -** -** This code depends on the fact that certain token values (ex: TK_EQ) -** are the same as opcode values (ex: OP_Eq) that implement the corresponding -** operation. Special comments in vdbe.c and the mkopcodeh.awk script in -** the make process cause these values to align. Assert()s in the code -** below verify that the numbers are aligned correctly. -*/ -SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ - Vdbe *v = pParse->pVdbe; - int op = 0; - int regFree1 = 0; - int regFree2 = 0; - int r1, r2; - - assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); - if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ - if( NEVER(pExpr==0) ) return; /* No way this can happen */ - op = pExpr->op; - switch( op ){ - case TK_AND: { - int d2 = sqlite3VdbeMakeLabel(v); - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); - break; - } - case TK_OR: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); - break; - } - case TK_NOT: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } - case TK_IS: - case TK_ISNOT: - testcase( op==TK_IS ); - testcase( op==TK_ISNOT ); - op = (op==TK_IS) ? TK_EQ : TK_NE; - jumpIfNull = SQLITE_NULLEQ; - /* Fall thru */ - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; - testcase( jumpIfNull==0 ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); - assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); - assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); - VdbeCoverageIf(v, op==TK_ISNULL); - VdbeCoverageIf(v, op==TK_NOTNULL); - testcase( regFree1==0 ); - break; - } - case TK_BETWEEN: { - testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_IN: { - int destIfFalse = sqlite3VdbeMakeLabel(v); - int destIfNull = jumpIfNull ? dest : destIfFalse; - sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); - sqlite3VdbeGoto(v, dest); - sqlite3VdbeResolveLabel(v, destIfFalse); - break; - } -#endif - default: { - default_expr: - if( exprAlwaysTrue(pExpr) ){ - sqlite3VdbeGoto(v, dest); - }else if( exprAlwaysFalse(pExpr) ){ - /* No-op */ - }else{ - r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); - VdbeCoverage(v); - testcase( regFree1==0 ); - testcase( jumpIfNull==0 ); - } - break; - } - } - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); -} - -/* -** Generate code for a boolean expression such that a jump is made -** to the label "dest" if the expression is false but execution -** continues straight thru if the expression is true. -** -** If the expression evaluates to NULL (neither true nor false) then -** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull -** is 0. -*/ -SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ - Vdbe *v = pParse->pVdbe; - int op = 0; - int regFree1 = 0; - int regFree2 = 0; - int r1, r2; - - assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); - if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ - if( pExpr==0 ) return; - - /* The value of pExpr->op and op are related as follows: - ** - ** pExpr->op op - ** --------- ---------- - ** TK_ISNULL OP_NotNull - ** TK_NOTNULL OP_IsNull - ** TK_NE OP_Eq - ** TK_EQ OP_Ne - ** TK_GT OP_Le - ** TK_LE OP_Gt - ** TK_GE OP_Lt - ** TK_LT OP_Ge - ** - ** For other values of pExpr->op, op is undefined and unused. - ** The value of TK_ and OP_ constants are arranged such that we - ** can compute the mapping above using the following expression. - ** Assert()s verify that the computation is correct. - */ - op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); - - /* Verify correct alignment of TK_ and OP_ constants - */ - assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); - assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); - assert( pExpr->op!=TK_NE || op==OP_Eq ); - assert( pExpr->op!=TK_EQ || op==OP_Ne ); - assert( pExpr->op!=TK_LT || op==OP_Ge ); - assert( pExpr->op!=TK_LE || op==OP_Gt ); - assert( pExpr->op!=TK_GT || op==OP_Le ); - assert( pExpr->op!=TK_GE || op==OP_Lt ); - - switch( pExpr->op ){ - case TK_AND: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); - break; - } - case TK_OR: { - int d2 = sqlite3VdbeMakeLabel(v); - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); - break; - } - case TK_NOT: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - break; - } - case TK_IS: - case TK_ISNOT: - testcase( pExpr->op==TK_IS ); - testcase( pExpr->op==TK_ISNOT ); - op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; - jumpIfNull = SQLITE_NULLEQ; - /* Fall thru */ - case TK_LT: - case TK_LE: - case TK_GT: - case TK_GE: - case TK_NE: - case TK_EQ: { - if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; - testcase( jumpIfNull==0 ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, - r1, r2, dest, jumpIfNull); - assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); - assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); - assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); - assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); - assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); - assert(TK_NE==OP_Ne); testcase(op==OP_Ne); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); - VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); - testcase( regFree1==0 ); - testcase( regFree2==0 ); - break; - } - case TK_ISNULL: - case TK_NOTNULL: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - sqlite3VdbeAddOp2(v, op, r1, dest); - testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); - testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); - testcase( regFree1==0 ); - break; - } - case TK_BETWEEN: { - testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_IN: { - if( jumpIfNull ){ - sqlite3ExprCodeIN(pParse, pExpr, dest, dest); - }else{ - int destIfNull = sqlite3VdbeMakeLabel(v); - sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); - sqlite3VdbeResolveLabel(v, destIfNull); - } - break; - } -#endif - default: { - default_expr: - if( exprAlwaysFalse(pExpr) ){ - sqlite3VdbeGoto(v, dest); - }else if( exprAlwaysTrue(pExpr) ){ - /* no-op */ - }else{ - r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); - VdbeCoverage(v); - testcase( regFree1==0 ); - testcase( jumpIfNull==0 ); - } - break; - } - } - sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); -} - -/* -** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before -** code generation, and that copy is deleted after code generation. This -** ensures that the original pExpr is unchanged. -*/ -SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ - sqlite3 *db = pParse->db; - Expr *pCopy = sqlite3ExprDup(db, pExpr, 0); - if( db->mallocFailed==0 ){ - sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); - } - sqlite3ExprDelete(db, pCopy); -} - - -/* -** Do a deep comparison of two expression trees. Return 0 if the two -** expressions are completely identical. Return 1 if they differ only -** by a COLLATE operator at the top level. Return 2 if there are differences -** other than the top-level COLLATE operator. -** -** If any subelement of pB has Expr.iTable==(-1) then it is allowed -** to compare equal to an equivalent element in pA with Expr.iTable==iTab. -** -** The pA side might be using TK_REGISTER. If that is the case and pB is -** not using TK_REGISTER but is otherwise equivalent, then still return 0. -** -** Sometimes this routine will return 2 even if the two expressions -** really are equivalent. If we cannot prove that the expressions are -** identical, we return 2 just to be safe. So if this routine -** returns 2, then you do not really know for certain if the two -** expressions are the same. But if you get a 0 or 1 return, then you -** can be sure the expressions are the same. In the places where -** this routine is used, it does not hurt to get an extra 2 - that -** just might result in some slightly slower code. But returning -** an incorrect 0 or 1 could lead to a malfunction. -*/ -SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ - u32 combinedFlags; - if( pA==0 || pB==0 ){ - return pB==pA ? 0 : 2; - } - combinedFlags = pA->flags | pB->flags; - if( combinedFlags & EP_IntValue ){ - if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ - return 0; - } - return 2; - } - if( pA->op!=pB->op ){ - if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ - return 1; - } - if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){ - return 1; - } - return 2; - } - if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ - if( pA->op==TK_FUNCTION ){ - if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; - }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ - return pA->op==TK_COLLATE ? 1 : 2; - } - } - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ - if( combinedFlags & EP_xIsSelect ) return 2; - if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; - if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){ - if( pA->iColumn!=pB->iColumn ) return 2; - if( pA->iTable!=pB->iTable - && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; - } - } - return 0; -} - -/* -** Compare two ExprList objects. Return 0 if they are identical and -** non-zero if they differ in any way. -** -** If any subelement of pB has Expr.iTable==(-1) then it is allowed -** to compare equal to an equivalent element in pA with Expr.iTable==iTab. -** -** This routine might return non-zero for equivalent ExprLists. The -** only consequence will be disabled optimizations. But this routine -** must never return 0 if the two ExprList objects are different, or -** a malfunction will result. -** -** Two NULL pointers are considered to be the same. But a NULL pointer -** always differs from a non-NULL pointer. -*/ -SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ - int i; - if( pA==0 && pB==0 ) return 0; - if( pA==0 || pB==0 ) return 1; - if( pA->nExpr!=pB->nExpr ) return 1; - for(i=0; inExpr; i++){ - Expr *pExprA = pA->a[i].pExpr; - Expr *pExprB = pB->a[i].pExpr; - if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; - if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1; - } - return 0; -} - -/* -** Return true if we can prove the pE2 will always be true if pE1 is -** true. Return false if we cannot complete the proof or if pE2 might -** be false. Examples: -** -** pE1: x==5 pE2: x==5 Result: true -** pE1: x>0 pE2: x==5 Result: false -** pE1: x=21 pE2: x=21 OR y=43 Result: true -** pE1: x!=123 pE2: x IS NOT NULL Result: true -** pE1: x!=?1 pE2: x IS NOT NULL Result: true -** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false -** -** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has -** Expr.iTable<0 then assume a table number given by iTab. -** -** When in doubt, return false. Returning true might give a performance -** improvement. Returning false might cause a performance reduction, but -** it will always give the correct answer and is hence always safe. -*/ -SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){ - if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){ - return 1; - } - if( pE2->op==TK_OR - && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab) - || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) ) - ){ - return 1; - } - if( pE2->op==TK_NOTNULL - && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0 - && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS) - ){ - return 1; - } - return 0; -} - -/* -** An instance of the following structure is used by the tree walker -** to determine if an expression can be evaluated by reference to the -** index only, without having to do a search for the corresponding -** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur -** is the cursor for the table. -*/ -struct IdxCover { - Index *pIdx; /* The index to be tested for coverage */ - int iCur; /* Cursor number for the table corresponding to the index */ -}; - -/* -** Check to see if there are references to columns in table -** pWalker->u.pIdxCover->iCur can be satisfied using the index -** pWalker->u.pIdxCover->pIdx. -*/ -static int exprIdxCover(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_COLUMN - && pExpr->iTable==pWalker->u.pIdxCover->iCur - && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 - ){ - pWalker->eCode = 1; - return WRC_Abort; - } - return WRC_Continue; -} - -/* -** Determine if an index pIdx on table with cursor iCur contains will -** the expression pExpr. Return true if the index does cover the -** expression and false if the pExpr expression references table columns -** that are not found in the index pIdx. -** -** An index covering an expression means that the expression can be -** evaluated using only the index and without having to lookup the -** corresponding table entry. -*/ -SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( - Expr *pExpr, /* The index to be tested */ - int iCur, /* The cursor number for the corresponding table */ - Index *pIdx /* The index that might be used for coverage */ -){ - Walker w; - struct IdxCover xcov; - memset(&w, 0, sizeof(w)); - xcov.iCur = iCur; - xcov.pIdx = pIdx; - w.xExprCallback = exprIdxCover; - w.u.pIdxCover = &xcov; - sqlite3WalkExpr(&w, pExpr); - return !w.eCode; -} - - -/* -** An instance of the following structure is used by the tree walker -** to count references to table columns in the arguments of an -** aggregate function, in order to implement the -** sqlite3FunctionThisSrc() routine. -*/ -struct SrcCount { - SrcList *pSrc; /* One particular FROM clause in a nested query */ - int nThis; /* Number of references to columns in pSrcList */ - int nOther; /* Number of references to columns in other FROM clauses */ -}; - -/* -** Count the number of references to columns. -*/ -static int exprSrcCount(Walker *pWalker, Expr *pExpr){ - /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc() - ** is always called before sqlite3ExprAnalyzeAggregates() and so the - ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If - ** sqlite3FunctionUsesThisSrc() is used differently in the future, the - ** NEVER() will need to be removed. */ - if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){ - int i; - struct SrcCount *p = pWalker->u.pSrcCount; - SrcList *pSrc = p->pSrc; - int nSrc = pSrc ? pSrc->nSrc : 0; - for(i=0; iiTable==pSrc->a[i].iCursor ) break; - } - if( inThis++; - }else{ - p->nOther++; - } - } - return WRC_Continue; -} - -/* -** Determine if any of the arguments to the pExpr Function reference -** pSrcList. Return true if they do. Also return true if the function -** has no arguments or has only constant arguments. Return false if pExpr -** references columns but not columns of tables found in pSrcList. -*/ -SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ - Walker w; - struct SrcCount cnt; - assert( pExpr->op==TK_AGG_FUNCTION ); - memset(&w, 0, sizeof(w)); - w.xExprCallback = exprSrcCount; - w.u.pSrcCount = &cnt; - cnt.pSrc = pSrcList; - cnt.nThis = 0; - cnt.nOther = 0; - sqlite3WalkExprList(&w, pExpr->x.pList); - return cnt.nThis>0 || cnt.nOther==0; -} - -/* -** Add a new element to the pAggInfo->aCol[] array. Return the index of -** the new element. Return a negative number if malloc fails. -*/ -static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ - int i; - pInfo->aCol = sqlite3ArrayAllocate( - db, - pInfo->aCol, - sizeof(pInfo->aCol[0]), - &pInfo->nColumn, - &i - ); - return i; -} - -/* -** Add a new element to the pAggInfo->aFunc[] array. Return the index of -** the new element. Return a negative number if malloc fails. -*/ -static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ - int i; - pInfo->aFunc = sqlite3ArrayAllocate( - db, - pInfo->aFunc, - sizeof(pInfo->aFunc[0]), - &pInfo->nFunc, - &i - ); - return i; -} - -/* -** This is the xExprCallback for a tree walker. It is used to -** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates -** for additional information. -*/ -static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ - int i; - NameContext *pNC = pWalker->u.pNC; - Parse *pParse = pNC->pParse; - SrcList *pSrcList = pNC->pSrcList; - AggInfo *pAggInfo = pNC->pAggInfo; - - switch( pExpr->op ){ - case TK_AGG_COLUMN: - case TK_COLUMN: { - testcase( pExpr->op==TK_AGG_COLUMN ); - testcase( pExpr->op==TK_COLUMN ); - /* Check to see if the column is in one of the tables in the FROM - ** clause of the aggregate query */ - if( ALWAYS(pSrcList!=0) ){ - struct SrcList_item *pItem = pSrcList->a; - for(i=0; inSrc; i++, pItem++){ - struct AggInfo_col *pCol; - assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); - if( pExpr->iTable==pItem->iCursor ){ - /* If we reach this point, it means that pExpr refers to a table - ** that is in the FROM clause of the aggregate query. - ** - ** Make an entry for the column in pAggInfo->aCol[] if there - ** is not an entry there already. - */ - int k; - pCol = pAggInfo->aCol; - for(k=0; knColumn; k++, pCol++){ - if( pCol->iTable==pExpr->iTable && - pCol->iColumn==pExpr->iColumn ){ - break; - } - } - if( (k>=pAggInfo->nColumn) - && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 - ){ - pCol = &pAggInfo->aCol[k]; - pCol->pTab = pExpr->pTab; - pCol->iTable = pExpr->iTable; - pCol->iColumn = pExpr->iColumn; - pCol->iMem = ++pParse->nMem; - pCol->iSorterColumn = -1; - pCol->pExpr = pExpr; - if( pAggInfo->pGroupBy ){ - int j, n; - ExprList *pGB = pAggInfo->pGroupBy; - struct ExprList_item *pTerm = pGB->a; - n = pGB->nExpr; - for(j=0; jpExpr; - if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable && - pE->iColumn==pExpr->iColumn ){ - pCol->iSorterColumn = j; - break; - } - } - } - if( pCol->iSorterColumn<0 ){ - pCol->iSorterColumn = pAggInfo->nSortingColumn++; - } - } - /* There is now an entry for pExpr in pAggInfo->aCol[] (either - ** because it was there before or because we just created it). - ** Convert the pExpr to be a TK_AGG_COLUMN referring to that - ** pAggInfo->aCol[] entry. - */ - ExprSetVVAProperty(pExpr, EP_NoReduce); - pExpr->pAggInfo = pAggInfo; - pExpr->op = TK_AGG_COLUMN; - pExpr->iAgg = (i16)k; - break; - } /* endif pExpr->iTable==pItem->iCursor */ - } /* end loop over pSrcList */ - } - return WRC_Prune; - } - case TK_AGG_FUNCTION: { - if( (pNC->ncFlags & NC_InAggFunc)==0 - && pWalker->walkerDepth==pExpr->op2 - ){ - /* Check to see if pExpr is a duplicate of another aggregate - ** function that is already in the pAggInfo structure - */ - struct AggInfo_func *pItem = pAggInfo->aFunc; - for(i=0; inFunc; i++, pItem++){ - if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){ - break; - } - } - if( i>=pAggInfo->nFunc ){ - /* pExpr is original. Make a new entry in pAggInfo->aFunc[] - */ - u8 enc = ENC(pParse->db); - i = addAggInfoFunc(pParse->db, pAggInfo); - if( i>=0 ){ - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - pItem = &pAggInfo->aFunc[i]; - pItem->pExpr = pExpr; - pItem->iMem = ++pParse->nMem; - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->u.zToken, - pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); - if( pExpr->flags & EP_Distinct ){ - pItem->iDistinct = pParse->nTab++; - }else{ - pItem->iDistinct = -1; - } - } - } - /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry - */ - assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pExpr, EP_NoReduce); - pExpr->iAgg = (i16)i; - pExpr->pAggInfo = pAggInfo; - return WRC_Prune; - }else{ - return WRC_Continue; - } - } - } - return WRC_Continue; -} -static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){ - UNUSED_PARAMETER(pWalker); - UNUSED_PARAMETER(pSelect); - return WRC_Continue; -} - -/* -** Analyze the pExpr expression looking for aggregate functions and -** for variables that need to be added to AggInfo object that pNC->pAggInfo -** points to. Additional entries are made on the AggInfo object as -** necessary. -** -** This routine should only be called after the expression has been -** analyzed by sqlite3ResolveExprNames(). -*/ -SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = analyzeAggregate; - w.xSelectCallback = analyzeAggregatesInSelect; - w.u.pNC = pNC; - assert( pNC->pSrcList!=0 ); - sqlite3WalkExpr(&w, pExpr); -} - -/* -** Call sqlite3ExprAnalyzeAggregates() for every expression in an -** expression list. Return the number of errors. -** -** If an error is found, the analysis is cut short. -*/ -SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ - struct ExprList_item *pItem; - int i; - if( pList ){ - for(pItem=pList->a, i=0; inExpr; i++, pItem++){ - sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); - } - } -} - -/* -** Allocate a single new register for use to hold some intermediate result. -*/ -SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ - if( pParse->nTempReg==0 ){ - return ++pParse->nMem; - } - return pParse->aTempReg[--pParse->nTempReg]; -} - -/* -** Deallocate a register, making available for reuse for some other -** purpose. -** -** If a register is currently being used by the column cache, then -** the deallocation is deferred until the column cache line that uses -** the register becomes stale. -*/ -SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ - if( iReg && pParse->nTempRegaTempReg) ){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 1; - return; - } - } - pParse->aTempReg[pParse->nTempReg++] = iReg; - } -} - -/* -** Allocate or deallocate a block of nReg consecutive registers. -*/ -SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ - int i, n; - if( nReg==1 ) return sqlite3GetTempReg(pParse); - i = pParse->iRangeReg; - n = pParse->nRangeReg; - if( nReg<=n ){ - assert( !usedAsColumnCache(pParse, i, i+n-1) ); - pParse->iRangeReg += nReg; - pParse->nRangeReg -= nReg; - }else{ - i = pParse->nMem+1; - pParse->nMem += nReg; - } - return i; -} -SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ - if( nReg==1 ){ - sqlite3ReleaseTempReg(pParse, iReg); - return; - } - sqlite3ExprCacheRemove(pParse, iReg, nReg); - if( nReg>pParse->nRangeReg ){ - pParse->nRangeReg = nReg; - pParse->iRangeReg = iReg; - } -} - -/* -** Mark all temporary registers as being unavailable for reuse. -*/ -SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ - pParse->nTempReg = 0; - pParse->nRangeReg = 0; -} - -/* -** Validate that no temporary register falls within the range of -** iFirst..iLast, inclusive. This routine is only call from within assert() -** statements. -*/ -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ - int i; - if( pParse->nRangeReg>0 - && pParse->iRangeReg+pParse->nRangeRegiRangeReg>=iFirst - ){ - return 0; - } - for(i=0; inTempReg; i++){ - if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ - return 0; - } - } - return 1; -} -#endif /* SQLITE_DEBUG */ - -/************** End of expr.c ************************************************/ -/************** Begin file alter.c *******************************************/ -/* -** 2005 February 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that used to generate VDBE code -** that implements the ALTER TABLE command. -*/ -/* #include "sqliteInt.h" */ - -/* -** The code in this file only exists if we are not omitting the -** ALTER TABLE logic from the build. -*/ -#ifndef SQLITE_OMIT_ALTERTABLE - - -/* -** This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TABLE or -** CREATE INDEX command. The second is a table name. The table name in -** the CREATE TABLE or CREATE INDEX statement is replaced with the third -** argument and the result returned. Examples: -** -** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') -** -> 'CREATE TABLE def(a, b, c)' -** -** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') -** -> 'CREATE INDEX i ON def(a, b, c)' -*/ -static void renameTableFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TABLE - ** statement is that the table name is the first non-space token that - ** is immediately followed by a TK_LP or TK_USING token. - */ - if( zSql ){ - do { - if( !*zCsr ){ - /* Ran out of input before finding an opening bracket. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - } while( token==TK_SPACE ); - assert( len>0 ); - } while( token!=TK_LP && token!=TK_USING ); - - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} - -/* -** This C function implements an SQL user function that is used by SQL code -** generated by the ALTER TABLE ... RENAME command to modify the definition -** of any foreign key constraints that use the table being renamed as the -** parent table. It is passed three arguments: -** -** 1) The complete text of the CREATE TABLE statement being modified, -** 2) The old name of the table being renamed, and -** 3) The new name of the table being renamed. -** -** It returns the new CREATE TABLE statement. For example: -** -** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') -** -> 'CREATE TABLE t1(a REFERENCES t3)' -*/ -#ifndef SQLITE_OMIT_FOREIGN_KEY -static void renameParentFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_context_db_handle(context); - char *zOutput = 0; - char *zResult; - unsigned char const *zInput = sqlite3_value_text(argv[0]); - unsigned char const *zOld = sqlite3_value_text(argv[1]); - unsigned char const *zNew = sqlite3_value_text(argv[2]); - - unsigned const char *z; /* Pointer to token */ - int n; /* Length of token z */ - int token; /* Type of token */ - - UNUSED_PARAMETER(NotUsed); - if( zInput==0 || zOld==0 ) return; - for(z=zInput; *z; z=z+n){ - n = sqlite3GetToken(z, &token); - if( token==TK_REFERENCES ){ - char *zParent; - do { - z += n; - n = sqlite3GetToken(z, &token); - }while( token==TK_SPACE ); - - if( token==TK_ILLEGAL ) break; - zParent = sqlite3DbStrNDup(db, (const char *)z, n); - if( zParent==0 ) break; - sqlite3Dequote(zParent); - if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ - char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", - (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew - ); - sqlite3DbFree(db, zOutput); - zOutput = zOut; - zInput = &z[n]; - } - sqlite3DbFree(db, zParent); - } - } - - zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), - sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); - sqlite3DbFree(db, zOutput); -} -#endif - -#ifndef SQLITE_OMIT_TRIGGER -/* This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER -** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the third argument and the result -** returned. This is analagous to renameTableFunc() above, except for CREATE -** TRIGGER, not CREATE INDEX and CREATE TABLE. -*/ -static void renameTriggerFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - int dist = 3; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TRIGGER - ** statement is that the table name is the first token that is immediately - ** preceded by either TK_ON or TK_DOT and immediately followed by one - ** of TK_WHEN, TK_BEGIN or TK_FOR. - */ - if( zSql ){ - do { - - if( !*zCsr ){ - /* Ran out of input before finding the table name. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - }while( token==TK_SPACE ); - assert( len>0 ); - - /* Variable 'dist' stores the number of tokens read since the most - ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN - ** token is read and 'dist' equals 2, the condition stated above - ** to be met. - ** - ** Note that ON cannot be a database, table or column name, so - ** there is no need to worry about syntax like - ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. - */ - dist++; - if( token==TK_DOT || token==TK_ON ){ - dist = 0; - } - } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); - - /* Variable tname now contains the token that is the old table-name - ** in the CREATE TRIGGER statement. - */ - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} -#endif /* !SQLITE_OMIT_TRIGGER */ - -/* -** Register built-in functions used to help implement ALTER TABLE -*/ -SQLITE_PRIVATE void sqlite3AlterFunctions(void){ - static FuncDef aAlterTableFuncs[] = { - FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), -#ifndef SQLITE_OMIT_TRIGGER - FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), -#endif -#ifndef SQLITE_OMIT_FOREIGN_KEY - FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), -#endif - }; - sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); -} - -/* -** This function is used to create the text of expressions of the form: -** -** name= OR name= OR ... -** -** If argument zWhere is NULL, then a pointer string containing the text -** "name=" is returned, where is the quoted version -** of the string passed as argument zConstant. The returned buffer is -** allocated using sqlite3DbMalloc(). It is the responsibility of the -** caller to ensure that it is eventually freed. -** -** If argument zWhere is not NULL, then the string returned is -** " OR name=", where is the contents of zWhere. -** In this case zWhere is passed to sqlite3DbFree() before returning. -** -*/ -static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ - char *zNew; - if( !zWhere ){ - zNew = sqlite3MPrintf(db, "name=%Q", zConstant); - }else{ - zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); - sqlite3DbFree(db, zWhere); - } - return zNew; -} - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -/* -** Generate the text of a WHERE expression which can be used to select all -** tables that have foreign key constraints that refer to table pTab (i.e. -** constraints for which pTab is the parent table) from the sqlite_master -** table. -*/ -static char *whereForeignKeys(Parse *pParse, Table *pTab){ - FKey *p; - char *zWhere = 0; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); - } - return zWhere; -} -#endif - -/* -** Generate the text of a WHERE expression which can be used to select all -** temporary triggers on table pTab from the sqlite_temp_master table. If -** table pTab has no temporary triggers, or is itself stored in the -** temporary database, NULL is returned. -*/ -static char *whereTempTriggers(Parse *pParse, Table *pTab){ - Trigger *pTrig; - char *zWhere = 0; - const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ - - /* If the table is not located in the temp-db (in which case NULL is - ** returned, loop through the tables list of triggers. For each trigger - ** that is not part of the temp-db schema, add a clause to the WHERE - ** expression being built up in zWhere. - */ - if( pTab->pSchema!=pTempSchema ){ - sqlite3 *db = pParse->db; - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - if( pTrig->pSchema==pTempSchema ){ - zWhere = whereOrName(db, zWhere, pTrig->zName); - } - } - } - if( zWhere ){ - char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); - sqlite3DbFree(pParse->db, zWhere); - zWhere = zNew; - } - return zWhere; -} - -/* -** Generate code to drop and reload the internal representation of table -** pTab from the database, including triggers and temporary triggers. -** Argument zName is the name of the table in the database schema at -** the time the generated code is executed. This can be different from -** pTab->zName if this function is being called to code part of an -** "ALTER TABLE RENAME TO" statement. -*/ -static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ - Vdbe *v; - char *zWhere; - int iDb; /* Index of database containing pTab */ -#ifndef SQLITE_OMIT_TRIGGER - Trigger *pTrig; -#endif - - v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return; - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 ); - -#ifndef SQLITE_OMIT_TRIGGER - /* Drop any table triggers from the internal schema. */ - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); - assert( iTrigDb==iDb || iTrigDb==1 ); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); - } -#endif - - /* Drop the table and index from the internal schema. */ - sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - - /* Reload the table, index and permanent trigger schemas. */ - zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); - if( !zWhere ) return; - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); - -#ifndef SQLITE_OMIT_TRIGGER - /* Now, if the table is not stored in the temp database, reload any temp - ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); - } -#endif -} - -/* -** Parameter zName is the name of a table that is about to be altered -** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). -** If the table is a system table, this function leaves an error message -** in pParse->zErr (system tables may not be altered) and returns non-zero. -** -** Or, if zName is not a system table, zero is returned. -*/ -static int isSystemTable(Parse *pParse, const char *zName){ - if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); - return 1; - } - return 0; -} - -/* -** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" -** command. -*/ -SQLITE_PRIVATE void sqlite3AlterRenameTable( - Parse *pParse, /* Parser context. */ - SrcList *pSrc, /* The table to rename. */ - Token *pName /* The new table name. */ -){ - int iDb; /* Database that contains the table */ - char *zDb; /* Name of database iDb */ - Table *pTab; /* Table being renamed */ - char *zName = 0; /* NULL-terminated version of pName */ - sqlite3 *db = pParse->db; /* Database connection */ - int nTabName; /* Number of UTF-8 characters in zTabName */ - const char *zTabName; /* Original name of the table */ - Vdbe *v; -#ifndef SQLITE_OMIT_TRIGGER - char *zWhere = 0; /* Where clause to locate temp triggers */ -#endif - VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ - int savedDbFlags; /* Saved value of db->flags */ - - savedDbFlags = db->flags; - if( NEVER(db->mallocFailed) ) goto exit_rename_table; - assert( pSrc->nSrc==1 ); - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - - pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); - if( !pTab ) goto exit_rename_table; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - zDb = db->aDb[iDb].zDbSName; - db->flags |= SQLITE_PreferBuiltin; - - /* Get a NULL terminated version of the new table name. */ - zName = sqlite3NameFromToken(db, pName); - if( !zName ) goto exit_rename_table; - - /* Check that a table or index named 'zName' does not already exist - ** in database iDb. If so, this is an error. - */ - if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ - sqlite3ErrorMsg(pParse, - "there is already another table or index with this name: %s", zName); - goto exit_rename_table; - } - - /* Make sure it is not a system table being altered, or a reserved name - ** that the table is being renamed to. - */ - if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ - goto exit_rename_table; - } - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto - exit_rename_table; - } - -#ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); - goto exit_rename_table; - } -#endif - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Invoke the authorization callback. */ - if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ - goto exit_rename_table; - } -#endif - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_rename_table; - } - if( IsVirtual(pTab) ){ - pVTab = sqlite3GetVTable(db, pTab); - if( pVTab->pVtab->pModule->xRename==0 ){ - pVTab = 0; - } - } -#endif - - /* Begin a transaction for database iDb. - ** Then modify the schema cookie (since the ALTER TABLE modifies the - ** schema). Open a statement transaction if the table is a virtual - ** table. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ){ - goto exit_rename_table; - } - sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); - sqlite3ChangeCookie(pParse, iDb); - - /* If this is a virtual table, invoke the xRename() function if - ** one is defined. The xRename() callback will modify the names - ** of any resources used by the v-table implementation (including other - ** SQLite tables) that are identified by the name of the virtual table. - */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pVTab ){ - int i = ++pParse->nMem; - sqlite3VdbeLoadString(v, i, zName); - sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); - sqlite3MayAbort(pParse); - } -#endif - - /* figure out how many UTF-8 characters are in zName */ - zTabName = pTab->zName; - nTabName = sqlite3Utf8CharLen(zTabName, -1); - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - /* If foreign-key support is enabled, rewrite the CREATE TABLE - ** statements corresponding to all child tables of foreign key constraints - ** for which the renamed table is the parent table. */ - if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".%s SET " - "sql = sqlite_rename_parent(sql, %Q, %Q) " - "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } - } -#endif - - /* Modify the sqlite_master table to use the new table name. */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " -#ifdef SQLITE_OMIT_TRIGGER - "sql = sqlite_rename_table(sql, %Q), " -#else - "sql = CASE " - "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" - "ELSE sqlite_rename_table(sql, %Q) END, " -#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name,%d+18) " - "ELSE name END " - "WHERE tbl_name=%Q COLLATE nocase AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, SCHEMA_TABLE(iDb), zName, zName, zName, -#ifndef SQLITE_OMIT_TRIGGER - zName, -#endif - zName, nTabName, zTabName - ); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update - ** it with the new table name. - */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", - zDb, zName, pTab->zName); - } -#endif - -#ifndef SQLITE_OMIT_TRIGGER - /* If there are TEMP triggers on this table, modify the sqlite_temp_master - ** table. Don't do this if the table being ALTERed is itself located in - ** the temp database. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " - "sql = sqlite_rename_trigger(sql, %Q), " - "tbl_name = %Q " - "WHERE %s;", zName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } -#endif - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - FKey *p; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - Table *pFrom = p->pFrom; - if( pFrom!=pTab ){ - reloadTableSchema(pParse, p->pFrom, pFrom->zName); - } - } - } -#endif - - /* Drop and reload the internal table schema. */ - reloadTableSchema(pParse, pTab, zName); - -exit_rename_table: - sqlite3SrcListDelete(db, pSrc); - sqlite3DbFree(db, zName); - db->flags = savedDbFlags; -} - -/* -** This function is called after an "ALTER TABLE ... ADD" statement -** has been parsed. Argument pColDef contains the text of the new -** column definition. -** -** The Table structure pParse->pNewTable was extended to include -** the new column during parsing. -*/ -SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ - Table *pNew; /* Copy of pParse->pNewTable */ - Table *pTab; /* Table being altered */ - int iDb; /* Database number */ - const char *zDb; /* Database name */ - const char *zTab; /* Table name */ - char *zCol; /* Null-terminated column definition */ - Column *pCol; /* The new column */ - Expr *pDflt; /* Default value for the new column */ - sqlite3 *db; /* The database connection; */ - Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ - int r1; /* Temporary registers */ - - db = pParse->db; - if( pParse->nErr || db->mallocFailed ) return; - assert( v!=0 ); - pNew = pParse->pNewTable; - assert( pNew ); - - assert( sqlite3BtreeHoldsAllMutexes(db) ); - iDb = sqlite3SchemaToIndex(db, pNew->pSchema); - zDb = db->aDb[iDb].zDbSName; - zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ - pCol = &pNew->aCol[pNew->nCol-1]; - pDflt = pCol->pDflt; - pTab = sqlite3FindTable(db, zTab, zDb); - assert( pTab ); - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Invoke the authorization callback. */ - if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ - return; - } -#endif - - /* If the default value for the new column was specified with a - ** literal NULL, then set pDflt to 0. This simplifies checking - ** for an SQL NULL default below. - */ - assert( pDflt==0 || pDflt->op==TK_SPAN ); - if( pDflt && pDflt->pLeft->op==TK_NULL ){ - pDflt = 0; - } - - /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. - ** If there is a NOT NULL constraint, then the default value for the - ** column must not be NULL. - */ - if( pCol->colFlags & COLFLAG_PRIMKEY ){ - sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); - return; - } - if( pNew->pIndex ){ - sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); - return; - } - if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ - sqlite3ErrorMsg(pParse, - "Cannot add a REFERENCES column with non-NULL default value"); - return; - } - if( pCol->notNull && !pDflt ){ - sqlite3ErrorMsg(pParse, - "Cannot add a NOT NULL column with default value NULL"); - return; - } - - /* Ensure the default expression is something that sqlite3ValueFromExpr() - ** can handle (i.e. not CURRENT_TIME etc.) - */ - if( pDflt ){ - sqlite3_value *pVal = 0; - int rc; - rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); - assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); - if( rc!=SQLITE_OK ){ - assert( db->mallocFailed == 1 ); - return; - } - if( !pVal ){ - sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); - return; - } - sqlite3ValueFree(pVal); - } - - /* Modify the CREATE TABLE statement. */ - zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); - if( zCol ){ - char *zEnd = &zCol[pColDef->n-1]; - int savedDbFlags = db->flags; - while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ - *zEnd-- = '\0'; - } - db->flags |= SQLITE_PreferBuiltin; - sqlite3NestedParse(pParse, - "UPDATE \"%w\".%s SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " - "WHERE type = 'table' AND name = %Q", - zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, - zTab - ); - sqlite3DbFree(db, zCol); - db->flags = savedDbFlags; - } - - /* Make sure the schema version is at least 3. But do not upgrade - ** from less than 3 to 4, as that will corrupt any preexisting DESC - ** index. - */ - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); - sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); - sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); - sqlite3ReleaseTempReg(pParse, r1); - - /* Reload the schema of the modified table. */ - reloadTableSchema(pParse, pTab, pTab->zName); -} - -/* -** This function is called by the parser after the table-name in -** an "ALTER TABLE ADD" statement is parsed. Argument -** pSrc is the full-name of the table being altered. -** -** This routine makes a (partial) copy of the Table structure -** for the table being altered and sets Parse.pNewTable to point -** to it. Routines called by the parser as the column definition -** is parsed (i.e. sqlite3AddColumn()) add the new Column data to -** the copy. The copy of the Table structure is deleted by tokenize.c -** after parsing is finished. -** -** Routine sqlite3AlterFinishAddColumn() will be called to complete -** coding the "ALTER TABLE ... ADD" statement. -*/ -SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ - Table *pNew; - Table *pTab; - Vdbe *v; - int iDb; - int i; - int nAlloc; - sqlite3 *db = pParse->db; - - /* Look up the table being altered. */ - assert( pParse->pNewTable==0 ); - assert( sqlite3BtreeHoldsAllMutexes(db) ); - if( db->mallocFailed ) goto exit_begin_add_column; - pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); - if( !pTab ) goto exit_begin_add_column; - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); - goto exit_begin_add_column; - } -#endif - - /* Make sure this is not an attempt to ALTER a view. */ - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); - goto exit_begin_add_column; - } - if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ - goto exit_begin_add_column; - } - - assert( pTab->addColOffset>0 ); - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - - /* Put a copy of the Table struct in Parse.pNewTable for the - ** sqlite3AddColumn() function and friends to modify. But modify - ** the name by adding an "sqlite_altertab_" prefix. By adding this - ** prefix, we insure that the name will not collide with an existing - ** table because user table are not allowed to have the "sqlite_" - ** prefix on their name. - */ - pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); - if( !pNew ) goto exit_begin_add_column; - pParse->pNewTable = pNew; - pNew->nRef = 1; - pNew->nCol = pTab->nCol; - assert( pNew->nCol>0 ); - nAlloc = (((pNew->nCol-1)/8)*8)+8; - assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); - pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); - pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); - if( !pNew->aCol || !pNew->zName ){ - assert( db->mallocFailed ); - goto exit_begin_add_column; - } - memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); - for(i=0; inCol; i++){ - Column *pCol = &pNew->aCol[i]; - pCol->zName = sqlite3DbStrDup(db, pCol->zName); - pCol->zColl = 0; - pCol->pDflt = 0; - } - pNew->pSchema = db->aDb[iDb].pSchema; - pNew->addColOffset = pTab->addColOffset; - pNew->nRef = 1; - - /* Begin a transaction and increment the schema cookie. */ - sqlite3BeginWriteOperation(pParse, 0, iDb); - v = sqlite3GetVdbe(pParse); - if( !v ) goto exit_begin_add_column; - sqlite3ChangeCookie(pParse, iDb); - -exit_begin_add_column: - sqlite3SrcListDelete(db, pSrc); - return; -} -#endif /* SQLITE_ALTER_TABLE */ - -/************** End of alter.c ***********************************************/ -/************** Begin file analyze.c *****************************************/ -/* -** 2005-07-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code associated with the ANALYZE command. -** -** The ANALYZE command gather statistics about the content of tables -** and indices. These statistics are made available to the query planner -** to help it make better decisions about how to perform queries. -** -** The following system tables are or have been supported: -** -** CREATE TABLE sqlite_stat1(tbl, idx, stat); -** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); -** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); -** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); -** -** Additional tables might be added in future releases of SQLite. -** The sqlite_stat2 table is not created or used unless the SQLite version -** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled -** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. -** The sqlite_stat2 table is superseded by sqlite_stat3, which is only -** created and used by SQLite versions 3.7.9 and later and with -** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 -** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced -** version of sqlite_stat3 and is only available when compiled with -** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is -** not possible to enable both STAT3 and STAT4 at the same time. If they -** are both enabled, then STAT4 takes precedence. -** -** For most applications, sqlite_stat1 provides all the statistics required -** for the query planner to make good choices. -** -** Format of sqlite_stat1: -** -** There is normally one row per index, with the index identified by the -** name in the idx column. The tbl column is the name of the table to -** which the index belongs. In each such row, the stat column will be -** a string consisting of a list of integers. The first integer in this -** list is the number of rows in the index. (This is the same as the -** number of rows in the table, except for partial indices.) The second -** integer is the average number of rows in the index that have the same -** value in the first column of the index. The third integer is the average -** number of rows in the index that have the same value for the first two -** columns. The N-th integer (for N>1) is the average number of rows in -** the index which have the same value for the first N-1 columns. For -** a K-column index, there will be K+1 integers in the stat column. If -** the index is unique, then the last integer will be 1. -** -** The list of integers in the stat column can optionally be followed -** by the keyword "unordered". The "unordered" keyword, if it is present, -** must be separated from the last integer by a single space. If the -** "unordered" keyword is present, then the query planner assumes that -** the index is unordered and will not use the index for a range query. -** -** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat -** column contains a single integer which is the (estimated) number of -** rows in the table identified by sqlite_stat1.tbl. -** -** Format of sqlite_stat2: -** -** The sqlite_stat2 is only created and is only used if SQLite is compiled -** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between -** 3.6.18 and 3.7.8. The "stat2" table contains additional information -** about the distribution of keys within an index. The index is identified by -** the "idx" column and the "tbl" column is the name of the table to which -** the index belongs. There are usually 10 rows in the sqlite_stat2 -** table for each index. -** -** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 -** inclusive are samples of the left-most key value in the index taken at -** evenly spaced points along the index. Let the number of samples be S -** (10 in the standard build) and let C be the number of rows in the index. -** Then the sampled rows are given by: -** -** rownumber = (i*C*2 + C)/(S*2) -** -** For i between 0 and S-1. Conceptually, the index space is divided into -** S uniform buckets and the samples are the middle row from each bucket. -** -** The format for sqlite_stat2 is recorded here for legacy reference. This -** version of SQLite does not support sqlite_stat2. It neither reads nor -** writes the sqlite_stat2 table. This version of SQLite only supports -** sqlite_stat3. -** -** Format for sqlite_stat3: -** -** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the -** sqlite_stat4 format will be described first. Further information -** about sqlite_stat3 follows the sqlite_stat4 description. -** -** Format for sqlite_stat4: -** -** As with sqlite_stat2, the sqlite_stat4 table contains histogram data -** to aid the query planner in choosing good indices based on the values -** that indexed columns are compared against in the WHERE clauses of -** queries. -** -** The sqlite_stat4 table contains multiple entries for each index. -** The idx column names the index and the tbl column is the table of the -** index. If the idx and tbl columns are the same, then the sample is -** of the INTEGER PRIMARY KEY. The sample column is a blob which is the -** binary encoding of a key from the index. The nEq column is a -** list of integers. The first integer is the approximate number -** of entries in the index whose left-most column exactly matches -** the left-most column of the sample. The second integer in nEq -** is the approximate number of entries in the index where the -** first two columns match the first two columns of the sample. -** And so forth. nLt is another list of integers that show the approximate -** number of entries that are strictly less than the sample. The first -** integer in nLt contains the number of entries in the index where the -** left-most column is less than the left-most column of the sample. -** The K-th integer in the nLt entry is the number of index entries -** where the first K columns are less than the first K columns of the -** sample. The nDLt column is like nLt except that it contains the -** number of distinct entries in the index that are less than the -** sample. -** -** There can be an arbitrary number of sqlite_stat4 entries per index. -** The ANALYZE command will typically generate sqlite_stat4 tables -** that contain between 10 and 40 samples which are distributed across -** the key space, though not uniformly, and which include samples with -** large nEq values. -** -** Format for sqlite_stat3 redux: -** -** The sqlite_stat3 table is like sqlite_stat4 except that it only -** looks at the left-most column of the index. The sqlite_stat3.sample -** column contains the actual value of the left-most column instead -** of a blob encoding of the complete index key as is found in -** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 -** all contain just a single integer which is the same as the first -** integer in the equivalent columns in sqlite_stat4. -*/ -#ifndef SQLITE_OMIT_ANALYZE -/* #include "sqliteInt.h" */ - -#if defined(SQLITE_ENABLE_STAT4) -# define IsStat4 1 -# define IsStat3 0 -#elif defined(SQLITE_ENABLE_STAT3) -# define IsStat4 0 -# define IsStat3 1 -#else -# define IsStat4 0 -# define IsStat3 0 -# undef SQLITE_STAT4_SAMPLES -# define SQLITE_STAT4_SAMPLES 1 -#endif -#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ - -/* -** This routine generates code that opens the sqlite_statN tables. -** The sqlite_stat1 table is always relevant. sqlite_stat2 is now -** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when -** appropriate compile-time options are provided. -** -** If the sqlite_statN tables do not previously exist, it is created. -** -** Argument zWhere may be a pointer to a buffer containing a table name, -** or it may be a NULL pointer. If it is not NULL, then all entries in -** the sqlite_statN tables associated with the named table are deleted. -** If zWhere==0, then code is generated to delete all stat table entries. -*/ -static void openStatTable( - Parse *pParse, /* Parsing context */ - int iDb, /* The database we are looking in */ - int iStatCur, /* Open the sqlite_stat1 table on this cursor */ - const char *zWhere, /* Delete entries for this table or index */ - const char *zWhereType /* Either "tbl" or "idx" */ -){ - static const struct { - const char *zName; - const char *zCols; - } aTable[] = { - { "sqlite_stat1", "tbl,idx,stat" }, -#if defined(SQLITE_ENABLE_STAT4) - { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, - { "sqlite_stat3", 0 }, -#elif defined(SQLITE_ENABLE_STAT3) - { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, - { "sqlite_stat4", 0 }, -#else - { "sqlite_stat3", 0 }, - { "sqlite_stat4", 0 }, -#endif - }; - int i; - sqlite3 *db = pParse->db; - Db *pDb; - Vdbe *v = sqlite3GetVdbe(pParse); - int aRoot[ArraySize(aTable)]; - u8 aCreateTbl[ArraySize(aTable)]; - - if( v==0 ) return; - assert( sqlite3BtreeHoldsAllMutexes(db) ); - assert( sqlite3VdbeDb(v)==db ); - pDb = &db->aDb[iDb]; - - /* Create new statistic tables if they do not exist, or clear them - ** if they do already exist. - */ - for(i=0; izDbSName))==0 ){ - if( aTable[i].zCols ){ - /* The sqlite_statN table does not exist. Create it. Note that a - ** side-effect of the CREATE TABLE statement is to leave the rootpage - ** of the new table in register pParse->regRoot. This is important - ** because the OpenWrite opcode below will be needing it. */ - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols - ); - aRoot[i] = pParse->regRoot; - aCreateTbl[i] = OPFLAG_P2ISREG; - } - }else{ - /* The table already exists. If zWhere is not NULL, delete all entries - ** associated with the table zWhere. If zWhere is NULL, delete the - ** entire contents of the table. */ - aRoot[i] = pStat->tnum; - aCreateTbl[i] = 0; - sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); - if( zWhere ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE %s=%Q", - pDb->zDbSName, zTab, zWhereType, zWhere - ); - }else{ - /* The sqlite_stat[134] table already exists. Delete all rows. */ - sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); - } - } - } - - /* Open the sqlite_stat[134] tables for writing. */ - for(i=0; aTable[i].zCols; i++){ - assert( inRowid ){ - sqlite3DbFree(db, p->u.aRowid); - p->nRowid = 0; - } -} -#endif - -/* Initialize the BLOB value of a ROWID -*/ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ - assert( db!=0 ); - if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); - p->u.aRowid = sqlite3DbMallocRawNN(db, n); - if( p->u.aRowid ){ - p->nRowid = n; - memcpy(p->u.aRowid, pData, n); - }else{ - p->nRowid = 0; - } -} -#endif - -/* Initialize the INTEGER value of a ROWID. -*/ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){ - assert( db!=0 ); - if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); - p->nRowid = 0; - p->u.iRowid = iRowid; -} -#endif - - -/* -** Copy the contents of object (*pFrom) into (*pTo). -*/ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ - pTo->isPSample = pFrom->isPSample; - pTo->iCol = pFrom->iCol; - pTo->iHash = pFrom->iHash; - memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); - memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); - memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); - if( pFrom->nRowid ){ - sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid); - }else{ - sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid); - } -} -#endif - -/* -** Reclaim all memory of a Stat4Accum structure. -*/ -static void stat4Destructor(void *pOld){ - Stat4Accum *p = (Stat4Accum*)pOld; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int i; - for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i); - for(i=0; imxSample; i++) sampleClear(p->db, p->a+i); - sampleClear(p->db, &p->current); -#endif - sqlite3DbFree(p->db, p); -} - -/* -** Implementation of the stat_init(N,K,C) SQL function. The three parameters -** are: -** N: The number of columns in the index including the rowid/pk (note 1) -** K: The number of columns in the index excluding the rowid/pk. -** C: The number of rows in the index (note 2) -** -** Note 1: In the special case of the covering index that implements a -** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the -** total number of columns in the table. -** -** Note 2: C is only used for STAT3 and STAT4. -** -** For indexes on ordinary rowid tables, N==K+1. But for indexes on -** WITHOUT ROWID tables, N=K+P where P is the number of columns in the -** PRIMARY KEY of the table. The covering index that implements the -** original WITHOUT ROWID table as N==K as a special case. -** -** This routine allocates the Stat4Accum object in heap memory. The return -** value is a pointer to the Stat4Accum object. The datatype of the -** return value is BLOB, but it is really just a pointer to the Stat4Accum -** object. -*/ -static void statInit( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - Stat4Accum *p; - int nCol; /* Number of columns in index being sampled */ - int nKeyCol; /* Number of key columns */ - int nColUp; /* nCol rounded up for alignment */ - int n; /* Bytes of space to allocate */ - sqlite3 *db; /* Database connection */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int mxSample = SQLITE_STAT4_SAMPLES; -#endif - - /* Decode the three function arguments */ - UNUSED_PARAMETER(argc); - nCol = sqlite3_value_int(argv[0]); - assert( nCol>0 ); - nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; - nKeyCol = sqlite3_value_int(argv[1]); - assert( nKeyCol<=nCol ); - assert( nKeyCol>0 ); - - /* Allocate the space required for the Stat4Accum object */ - n = sizeof(*p) - + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ - + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ - + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ - + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) -#endif - ; - db = sqlite3_context_db_handle(context); - p = sqlite3DbMallocZero(db, n); - if( p==0 ){ - sqlite3_result_error_nomem(context); - return; - } - - p->db = db; - p->nRow = 0; - p->nCol = nCol; - p->nKeyCol = nKeyCol; - p->current.anDLt = (tRowcnt*)&p[1]; - p->current.anEq = &p->current.anDLt[nColUp]; - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - { - u8 *pSpace; /* Allocated space not yet assigned */ - int i; /* Used to iterate through p->aSample[] */ - - p->iGet = -1; - p->mxSample = mxSample; - p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); - p->current.anLt = &p->current.anEq[nColUp]; - p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); - - /* Set up the Stat4Accum.a[] and aBest[] arrays */ - p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; - p->aBest = &p->a[mxSample]; - pSpace = (u8*)(&p->a[mxSample+nCol]); - for(i=0; i<(mxSample+nCol); i++){ - p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); - p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); - p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); - } - assert( (pSpace - (u8*)p)==n ); - - for(i=0; iaBest[i].iCol = i; - } - } -#endif - - /* Return a pointer to the allocated object to the caller. Note that - ** only the pointer (the 2nd parameter) matters. The size of the object - ** (given by the 3rd parameter) is never used and can be any positive - ** value. */ - sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); -} -static const FuncDef statInitFuncdef = { - 2+IsStat34, /* nArg */ - SQLITE_UTF8, /* funcFlags */ - 0, /* pUserData */ - 0, /* pNext */ - statInit, /* xSFunc */ - 0, /* xFinalize */ - "stat_init", /* zName */ - {0} -}; - -#ifdef SQLITE_ENABLE_STAT4 -/* -** pNew and pOld are both candidate non-periodic samples selected for -** the same column (pNew->iCol==pOld->iCol). Ignoring this column and -** considering only any trailing columns and the sample hash value, this -** function returns true if sample pNew is to be preferred over pOld. -** In other words, if we assume that the cardinalities of the selected -** column for pNew and pOld are equal, is pNew to be preferred over pOld. -** -** This function assumes that for each argument sample, the contents of -** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. -*/ -static int sampleIsBetterPost( - Stat4Accum *pAccum, - Stat4Sample *pNew, - Stat4Sample *pOld -){ - int nCol = pAccum->nCol; - int i; - assert( pNew->iCol==pOld->iCol ); - for(i=pNew->iCol+1; ianEq[i]>pOld->anEq[i] ) return 1; - if( pNew->anEq[i]anEq[i] ) return 0; - } - if( pNew->iHash>pOld->iHash ) return 1; - return 0; -} -#endif - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Return true if pNew is to be preferred over pOld. -** -** This function assumes that for each argument sample, the contents of -** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. -*/ -static int sampleIsBetter( - Stat4Accum *pAccum, - Stat4Sample *pNew, - Stat4Sample *pOld -){ - tRowcnt nEqNew = pNew->anEq[pNew->iCol]; - tRowcnt nEqOld = pOld->anEq[pOld->iCol]; - - assert( pOld->isPSample==0 && pNew->isPSample==0 ); - assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); - - if( (nEqNew>nEqOld) ) return 1; -#ifdef SQLITE_ENABLE_STAT4 - if( nEqNew==nEqOld ){ - if( pNew->iColiCol ) return 1; - return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); - } - return 0; -#else - return (nEqNew==nEqOld && pNew->iHash>pOld->iHash); -#endif -} - -/* -** Copy the contents of sample *pNew into the p->a[] array. If necessary, -** remove the least desirable sample from p->a[] to make room. -*/ -static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ - Stat4Sample *pSample = 0; - int i; - - assert( IsStat4 || nEqZero==0 ); - -#ifdef SQLITE_ENABLE_STAT4 - if( pNew->isPSample==0 ){ - Stat4Sample *pUpgrade = 0; - assert( pNew->anEq[pNew->iCol]>0 ); - - /* This sample is being added because the prefix that ends in column - ** iCol occurs many times in the table. However, if we have already - ** added a sample that shares this prefix, there is no need to add - ** this one. Instead, upgrade the priority of the highest priority - ** existing sample that shares this prefix. */ - for(i=p->nSample-1; i>=0; i--){ - Stat4Sample *pOld = &p->a[i]; - if( pOld->anEq[pNew->iCol]==0 ){ - if( pOld->isPSample ) return; - assert( pOld->iCol>pNew->iCol ); - assert( sampleIsBetter(p, pNew, pOld) ); - if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ - pUpgrade = pOld; - } - } - } - if( pUpgrade ){ - pUpgrade->iCol = pNew->iCol; - pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; - goto find_new_min; - } - } -#endif - - /* If necessary, remove sample iMin to make room for the new sample. */ - if( p->nSample>=p->mxSample ){ - Stat4Sample *pMin = &p->a[p->iMin]; - tRowcnt *anEq = pMin->anEq; - tRowcnt *anLt = pMin->anLt; - tRowcnt *anDLt = pMin->anDLt; - sampleClear(p->db, pMin); - memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); - pSample = &p->a[p->nSample-1]; - pSample->nRowid = 0; - pSample->anEq = anEq; - pSample->anDLt = anDLt; - pSample->anLt = anLt; - p->nSample = p->mxSample-1; - } - - /* The "rows less-than" for the rowid column must be greater than that - ** for the last sample in the p->a[] array. Otherwise, the samples would - ** be out of order. */ -#ifdef SQLITE_ENABLE_STAT4 - assert( p->nSample==0 - || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); -#endif - - /* Insert the new sample */ - pSample = &p->a[p->nSample]; - sampleCopy(p, pSample, pNew); - p->nSample++; - - /* Zero the first nEqZero entries in the anEq[] array. */ - memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); - -#ifdef SQLITE_ENABLE_STAT4 - find_new_min: -#endif - if( p->nSample>=p->mxSample ){ - int iMin = -1; - for(i=0; imxSample; i++){ - if( p->a[i].isPSample ) continue; - if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ - iMin = i; - } - } - assert( iMin>=0 ); - p->iMin = iMin; - } -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - -/* -** Field iChng of the index being scanned has changed. So at this point -** p->current contains a sample that reflects the previous row of the -** index. The value of anEq[iChng] and subsequent anEq[] elements are -** correct at this point. -*/ -static void samplePushPrevious(Stat4Accum *p, int iChng){ -#ifdef SQLITE_ENABLE_STAT4 - int i; - - /* Check if any samples from the aBest[] array should be pushed - ** into IndexSample.a[] at this point. */ - for(i=(p->nCol-2); i>=iChng; i--){ - Stat4Sample *pBest = &p->aBest[i]; - pBest->anEq[i] = p->current.anEq[i]; - if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ - sampleInsert(p, pBest, i); - } - } - - /* Update the anEq[] fields of any samples already collected. */ - for(i=p->nSample-1; i>=0; i--){ - int j; - for(j=iChng; jnCol; j++){ - if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; - } - } -#endif - -#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) - if( iChng==0 ){ - tRowcnt nLt = p->current.anLt[0]; - tRowcnt nEq = p->current.anEq[0]; - - /* Check if this is to be a periodic sample. If so, add it. */ - if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ - p->current.isPSample = 1; - sampleInsert(p, &p->current, 0); - p->current.isPSample = 0; - }else - - /* Or if it is a non-periodic sample. Add it in this case too. */ - if( p->nSamplemxSample - || sampleIsBetter(p, &p->current, &p->a[p->iMin]) - ){ - sampleInsert(p, &p->current, 0); - } - } -#endif - -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 - UNUSED_PARAMETER( p ); - UNUSED_PARAMETER( iChng ); -#endif -} - -/* -** Implementation of the stat_push SQL function: stat_push(P,C,R) -** Arguments: -** -** P Pointer to the Stat4Accum object created by stat_init() -** C Index of left-most column to differ from previous row -** R Rowid for the current row. Might be a key record for -** WITHOUT ROWID tables. -** -** This SQL function always returns NULL. It's purpose it to accumulate -** statistical data and/or samples in the Stat4Accum object about the -** index being analyzed. The stat_get() SQL function will later be used to -** extract relevant information for constructing the sqlite_statN tables. -** -** The R parameter is only used for STAT3 and STAT4 -*/ -static void statPush( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - - /* The three function arguments */ - Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); - int iChng = sqlite3_value_int(argv[1]); - - UNUSED_PARAMETER( argc ); - UNUSED_PARAMETER( context ); - assert( p->nCol>0 ); - assert( iChngnCol ); - - if( p->nRow==0 ){ - /* This is the first call to this function. Do initialization. */ - for(i=0; inCol; i++) p->current.anEq[i] = 1; - }else{ - /* Second and subsequent calls get processed here */ - samplePushPrevious(p, iChng); - - /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply - ** to the current row of the index. */ - for(i=0; icurrent.anEq[i]++; - } - for(i=iChng; inCol; i++){ - p->current.anDLt[i]++; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - p->current.anLt[i] += p->current.anEq[i]; -#endif - p->current.anEq[i] = 1; - } - } - p->nRow++; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ - sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); - }else{ - sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), - sqlite3_value_blob(argv[2])); - } - p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; -#endif - -#ifdef SQLITE_ENABLE_STAT4 - { - tRowcnt nLt = p->current.anLt[p->nCol-1]; - - /* Check if this is to be a periodic sample. If so, add it. */ - if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ - p->current.isPSample = 1; - p->current.iCol = 0; - sampleInsert(p, &p->current, p->nCol-1); - p->current.isPSample = 0; - } - - /* Update the aBest[] array. */ - for(i=0; i<(p->nCol-1); i++){ - p->current.iCol = i; - if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ - sampleCopy(p, &p->aBest[i], &p->current); - } - } - } -#endif -} -static const FuncDef statPushFuncdef = { - 2+IsStat34, /* nArg */ - SQLITE_UTF8, /* funcFlags */ - 0, /* pUserData */ - 0, /* pNext */ - statPush, /* xSFunc */ - 0, /* xFinalize */ - "stat_push", /* zName */ - {0} -}; - -#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ -#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ -#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ -#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ -#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ - -/* -** Implementation of the stat_get(P,J) SQL function. This routine is -** used to query statistical information that has been gathered into -** the Stat4Accum object by prior calls to stat_push(). The P parameter -** has type BLOB but it is really just a pointer to the Stat4Accum object. -** The content to returned is determined by the parameter J -** which is one of the STAT_GET_xxxx values defined above. -** -** If neither STAT3 nor STAT4 are enabled, then J is always -** STAT_GET_STAT1 and is hence omitted and this routine becomes -** a one-parameter function, stat_get(P), that always returns the -** stat1 table entry information. -*/ -static void statGet( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - /* STAT3 and STAT4 have a parameter on this routine. */ - int eCall = sqlite3_value_int(argv[1]); - assert( argc==2 ); - assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ - || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT - || eCall==STAT_GET_NDLT - ); - if( eCall==STAT_GET_STAT1 ) -#else - assert( argc==1 ); -#endif - { - /* Return the value to store in the "stat" column of the sqlite_stat1 - ** table for this index. - ** - ** The value is a string composed of a list of integers describing - ** the index. The first integer in the list is the total number of - ** entries in the index. There is one additional integer in the list - ** for each indexed column. This additional integer is an estimate of - ** the number of rows matched by a stabbing query on the index using - ** a key with the corresponding number of fields. In other words, - ** if the index is on columns (a,b) and the sqlite_stat1 value is - ** "100 10 2", then SQLite estimates that: - ** - ** * the index contains 100 rows, - ** * "WHERE a=?" matches 10 rows, and - ** * "WHERE a=? AND b=?" matches 2 rows. - ** - ** If D is the count of distinct values and K is the total number of - ** rows, then each estimate is computed as: - ** - ** I = (K+D-1)/D - */ - char *z; - int i; - - char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 ); - if( zRet==0 ){ - sqlite3_result_error_nomem(context); - return; - } - - sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow); - z = zRet + sqlite3Strlen30(zRet); - for(i=0; inKeyCol; i++){ - u64 nDistinct = p->current.anDLt[i] + 1; - u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; - sqlite3_snprintf(24, z, " %llu", iVal); - z += sqlite3Strlen30(z); - assert( p->current.anEq[i] ); - } - assert( z[0]=='\0' && z>zRet ); - - sqlite3_result_text(context, zRet, -1, sqlite3_free); - } -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - else if( eCall==STAT_GET_ROWID ){ - if( p->iGet<0 ){ - samplePushPrevious(p, 0); - p->iGet = 0; - } - if( p->iGetnSample ){ - Stat4Sample *pS = p->a + p->iGet; - if( pS->nRowid==0 ){ - sqlite3_result_int64(context, pS->u.iRowid); - }else{ - sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, - SQLITE_TRANSIENT); - } - } - }else{ - tRowcnt *aCnt = 0; - - assert( p->iGetnSample ); - switch( eCall ){ - case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; - case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; - default: { - aCnt = p->a[p->iGet].anDLt; - p->iGet++; - break; - } - } - - if( IsStat3 ){ - sqlite3_result_int64(context, (i64)aCnt[0]); - }else{ - char *zRet = sqlite3MallocZero(p->nCol * 25); - if( zRet==0 ){ - sqlite3_result_error_nomem(context); - }else{ - int i; - char *z = zRet; - for(i=0; inCol; i++){ - sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); - z += sqlite3Strlen30(z); - } - assert( z[0]=='\0' && z>zRet ); - z[-1] = '\0'; - sqlite3_result_text(context, zRet, -1, sqlite3_free); - } - } - } -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ -#ifndef SQLITE_DEBUG - UNUSED_PARAMETER( argc ); -#endif -} -static const FuncDef statGetFuncdef = { - 1+IsStat34, /* nArg */ - SQLITE_UTF8, /* funcFlags */ - 0, /* pUserData */ - 0, /* pNext */ - statGet, /* xSFunc */ - 0, /* xFinalize */ - "stat_get", /* zName */ - {0} -}; - -static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ - assert( regOut!=regStat4 && regOut!=regStat4+1 ); -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); -#elif SQLITE_DEBUG - assert( iParam==STAT_GET_STAT1 ); -#else - UNUSED_PARAMETER( iParam ); -#endif - sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, - (char*)&statGetFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 1 + IsStat34); -} - -/* -** Generate code to do an analysis of all indices associated with -** a single table. -*/ -static void analyzeOneTable( - Parse *pParse, /* Parser context */ - Table *pTab, /* Table whose indices are to be analyzed */ - Index *pOnlyIdx, /* If not NULL, only analyze this one index */ - int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ - int iMem, /* Available memory locations begin here */ - int iTab /* Next available cursor */ -){ - sqlite3 *db = pParse->db; /* Database handle */ - Index *pIdx; /* An index to being analyzed */ - int iIdxCur; /* Cursor open on index being analyzed */ - int iTabCur; /* Table cursor */ - Vdbe *v; /* The virtual machine being built up */ - int i; /* Loop counter */ - int jZeroRows = -1; /* Jump from here if number of rows is zero */ - int iDb; /* Index of database containing pTab */ - u8 needTableCnt = 1; /* True to count the table */ - int regNewRowid = iMem++; /* Rowid for the inserted record */ - int regStat4 = iMem++; /* Register to hold Stat4Accum object */ - int regChng = iMem++; /* Index of changed index field */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int regRowid = iMem++; /* Rowid argument passed to stat_push() */ -#endif - int regTemp = iMem++; /* Temporary use register */ - int regTabname = iMem++; /* Register containing table name */ - int regIdxname = iMem++; /* Register containing index name */ - int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ - int regPrev = iMem; /* MUST BE LAST (see below) */ - - pParse->nMem = MAX(pParse->nMem, iMem); - v = sqlite3GetVdbe(pParse); - if( v==0 || NEVER(pTab==0) ){ - return; - } - if( pTab->tnum==0 ){ - /* Do not gather statistics on views or virtual tables */ - return; - } - if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ - /* Do not gather statistics on system tables */ - return; - } - assert( sqlite3BtreeHoldsAllMutexes(db) ); - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 ); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); -#ifndef SQLITE_OMIT_AUTHORIZATION - if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, - db->aDb[iDb].zDbSName ) ){ - return; - } -#endif - - /* Establish a read-lock on the table at the shared-cache level. - ** Open a read-only cursor on the table. Also allocate a cursor number - ** to use for scanning indexes (iIdxCur). No index cursor is opened at - ** this time though. */ - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - iTabCur = iTab++; - iIdxCur = iTab++; - pParse->nTab = MAX(pParse->nTab, iTab); - sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeLoadString(v, regTabname, pTab->zName); - - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int nCol; /* Number of columns in pIdx. "N" */ - int addrRewind; /* Address of "OP_Rewind iIdxCur" */ - int addrNextRow; /* Address of "next_row:" */ - const char *zIdxName; /* Name of the index */ - int nColTest; /* Number of columns to test for changes */ - - if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; - if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; - if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ - nCol = pIdx->nKeyCol; - zIdxName = pTab->zName; - nColTest = nCol - 1; - }else{ - nCol = pIdx->nColumn; - zIdxName = pIdx->zName; - nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; - } - - /* Populate the register containing the index name. */ - sqlite3VdbeLoadString(v, regIdxname, zIdxName); - VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); - - /* - ** Pseudo-code for loop that calls stat_push(): - ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; - ** regChng = 0 - ** goto chng_addr_0; - ** - ** next_row: - ** regChng = 0 - ** if( idx(0) != regPrev(0) ) goto chng_addr_0 - ** regChng = 1 - ** if( idx(1) != regPrev(1) ) goto chng_addr_1 - ** ... - ** regChng = N - ** goto chng_addr_N - ** - ** chng_addr_0: - ** regPrev(0) = idx(0) - ** chng_addr_1: - ** regPrev(1) = idx(1) - ** ... - ** - ** endDistinctTest: - ** regRowid = idx(rowid) - ** stat_push(P, regChng, regRowid) - ** Next csr - ** if !eof(csr) goto next_row; - ** - ** end_of_scan: - */ - - /* Make sure there are enough memory cells allocated to accommodate - ** the regPrev array and a trailing rowid (the rowid slot is required - ** when building a record to insert into the sample column of - ** the sqlite_stat4 table. */ - pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); - - /* Open a read-only cursor on the index being analyzed. */ - assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); - sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); - - /* Invoke the stat_init() function. The arguments are: - ** - ** (1) the number of columns in the index including the rowid - ** (or for a WITHOUT ROWID table, the number of PK columns), - ** (2) the number of columns in the key without the rowid/pk - ** (3) the number of rows in the index, - ** - ** - ** The third argument is only used for STAT3 and STAT4 - */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); -#endif - sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); - sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); - sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, - (char*)&statInitFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 2+IsStat34); - - /* Implementation of the following: - ** - ** Rewind csr - ** if eof(csr) goto end_of_scan; - ** regChng = 0 - ** goto next_push_0; - ** - */ - addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); - addrNextRow = sqlite3VdbeCurrentAddr(v); - - if( nColTest>0 ){ - int endDistinctTest = sqlite3VdbeMakeLabel(v); - int *aGotoChng; /* Array of jump instruction addresses */ - aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); - if( aGotoChng==0 ) continue; - - /* - ** next_row: - ** regChng = 0 - ** if( idx(0) != regPrev(0) ) goto chng_addr_0 - ** regChng = 1 - ** if( idx(1) != regPrev(1) ) goto chng_addr_1 - ** ... - ** regChng = N - ** goto endDistinctTest - */ - sqlite3VdbeAddOp0(v, OP_Goto); - addrNextRow = sqlite3VdbeCurrentAddr(v); - if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ - /* For a single-column UNIQUE index, once we have found a non-NULL - ** row, we know that all the rest will be distinct, so skip - ** subsequent distinctness tests. */ - sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); - VdbeCoverage(v); - } - for(i=0; iazColl[i]); - sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); - aGotoChng[i] = - sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); - sqlite3VdbeGoto(v, endDistinctTest); - - - /* - ** chng_addr_0: - ** regPrev(0) = idx(0) - ** chng_addr_1: - ** regPrev(1) = idx(1) - ** ... - */ - sqlite3VdbeJumpHere(v, addrNextRow-1); - for(i=0; ipTable); - int j, k, regKey; - regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); - for(j=0; jnKeyCol; j++){ - k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); - assert( k>=0 && knCol ); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); - VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); - } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); - sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); - } -#endif - assert( regChng==(regStat4+1) ); - sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, - (char*)&statPushFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 2+IsStat34); - sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); - - /* Add the entry to the stat1 table. */ - callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); - assert( "BBB"[0]==SQLITE_AFF_TEXT ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - - /* Add the entries to the stat3 or stat4 table. */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - { - int regEq = regStat1; - int regLt = regStat1+1; - int regDLt = regStat1+2; - int regSample = regStat1+3; - int regCol = regStat1+4; - int regSampleRowid = regCol + nCol; - int addrNext; - int addrIsNull; - u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; - - pParse->nMem = MAX(pParse->nMem, regCol+nCol); - - addrNext = sqlite3VdbeCurrentAddr(v); - callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); - addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); - VdbeCoverage(v); - callStatGet(v, regStat4, STAT_GET_NEQ, regEq); - callStatGet(v, regStat4, STAT_GET_NLT, regLt); - callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); - sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); - /* We know that the regSampleRowid row exists because it was read by - ** the previous loop. Thus the not-found jump of seekOp will never - ** be taken */ - VdbeCoverageNeverTaken(v); -#ifdef SQLITE_ENABLE_STAT3 - sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); -#else - for(i=0; izName)); - sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); - assert( "BBB"[0]==SQLITE_AFF_TEXT ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3VdbeJumpHere(v, jZeroRows); - } -} - - -/* -** Generate code that will cause the most recent index analysis to -** be loaded into internal hash tables where is can be used. -*/ -static void loadAnalysis(Parse *pParse, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); - } -} - -/* -** Generate code that will do an analysis of an entire database -*/ -static void analyzeDatabase(Parse *pParse, int iDb){ - sqlite3 *db = pParse->db; - Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ - HashElem *k; - int iStatCur; - int iMem; - int iTab; - - sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab; - pParse->nTab += 3; - openStatTable(pParse, iDb, iStatCur, 0, 0); - iMem = pParse->nMem+1; - iTab = pParse->nTab; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ - Table *pTab = (Table*)sqliteHashData(k); - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); - } - loadAnalysis(pParse, iDb); -} - -/* -** Generate code that will do an analysis of a single table in -** a database. If pOnlyIdx is not NULL then it is a single index -** in pTab that should be analyzed. -*/ -static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ - int iDb; - int iStatCur; - - assert( pTab!=0 ); - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab; - pParse->nTab += 3; - if( pOnlyIdx ){ - openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); - }else{ - openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); - } - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); - loadAnalysis(pParse, iDb); -} - -/* -** Generate code for the ANALYZE command. The parser calls this routine -** when it recognizes an ANALYZE command. -** -** ANALYZE -- 1 -** ANALYZE -- 2 -** ANALYZE ?.? -- 3 -** -** Form 1 causes all indices in all attached databases to be analyzed. -** Form 2 analyzes all indices the single database named. -** Form 3 analyzes all indices associated with the named table. -*/ -SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ - sqlite3 *db = pParse->db; - int iDb; - int i; - char *z, *zDb; - Table *pTab; - Index *pIdx; - Token *pTableName; - Vdbe *v; - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return; - } - - assert( pName2!=0 || pName1==0 ); - if( pName1==0 ){ - /* Form 1: Analyze everything */ - for(i=0; inDb; i++){ - if( i==1 ) continue; /* Do not analyze the TEMP database */ - analyzeDatabase(pParse, i); - } - }else if( pName2->n==0 ){ - /* Form 2: Analyze the database or table named */ - iDb = sqlite3FindDb(db, pName1); - if( iDb>=0 ){ - analyzeDatabase(pParse, iDb); - }else{ - z = sqlite3NameFromToken(db, pName1); - if( z ){ - if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){ - analyzeTable(pParse, pIdx->pTable, pIdx); - }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ - analyzeTable(pParse, pTab, 0); - } - sqlite3DbFree(db, z); - } - } - }else{ - /* Form 3: Analyze the fully qualified table name */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); - if( iDb>=0 ){ - zDb = db->aDb[iDb].zDbSName; - z = sqlite3NameFromToken(db, pTableName); - if( z ){ - if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ - analyzeTable(pParse, pIdx->pTable, pIdx); - }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ - analyzeTable(pParse, pTab, 0); - } - sqlite3DbFree(db, z); - } - } - } - v = sqlite3GetVdbe(pParse); - if( v ) sqlite3VdbeAddOp0(v, OP_Expire); -} - -/* -** Used to pass information from the analyzer reader through to the -** callback routine. -*/ -typedef struct analysisInfo analysisInfo; -struct analysisInfo { - sqlite3 *db; - const char *zDatabase; -}; - -/* -** The first argument points to a nul-terminated string containing a -** list of space separated integers. Read the first nOut of these into -** the array aOut[]. -*/ -static void decodeIntArray( - char *zIntArray, /* String containing int array to decode */ - int nOut, /* Number of slots in aOut[] */ - tRowcnt *aOut, /* Store integers here */ - LogEst *aLog, /* Or, if aOut==0, here */ - Index *pIndex /* Handle extra flags for this index, if not NULL */ -){ - char *z = zIntArray; - int c; - int i; - tRowcnt v; - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( z==0 ) z = ""; -#else - assert( z!=0 ); -#endif - for(i=0; *z && i='0' && c<='9' ){ - v = v*10 + c - '0'; - z++; - } -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( aOut ) aOut[i] = v; - if( aLog ) aLog[i] = sqlite3LogEst(v); -#else - assert( aOut==0 ); - UNUSED_PARAMETER(aOut); - assert( aLog!=0 ); - aLog[i] = sqlite3LogEst(v); -#endif - if( *z==' ' ) z++; - } -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 - assert( pIndex!=0 ); { -#else - if( pIndex ){ -#endif - pIndex->bUnordered = 0; - pIndex->noSkipScan = 0; - while( z[0] ){ - if( sqlite3_strglob("unordered*", z)==0 ){ - pIndex->bUnordered = 1; - }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ - pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); - }else if( sqlite3_strglob("noskipscan*", z)==0 ){ - pIndex->noSkipScan = 1; - } -#ifdef SQLITE_ENABLE_COSTMULT - else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ - pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); - } -#endif - while( z[0]!=0 && z[0]!=' ' ) z++; - while( z[0]==' ' ) z++; - } - } -} - -/* -** This callback is invoked once for each index when reading the -** sqlite_stat1 table. -** -** argv[0] = name of the table -** argv[1] = name of the index (might be NULL) -** argv[2] = results of analysis - on integer for each column -** -** Entries for which argv[1]==NULL simply record the number of rows in -** the table. -*/ -static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ - analysisInfo *pInfo = (analysisInfo*)pData; - Index *pIndex; - Table *pTable; - const char *z; - - assert( argc==3 ); - UNUSED_PARAMETER2(NotUsed, argc); - - if( argv==0 || argv[0]==0 || argv[2]==0 ){ - return 0; - } - pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); - if( pTable==0 ){ - return 0; - } - if( argv[1]==0 ){ - pIndex = 0; - }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ - pIndex = sqlite3PrimaryKeyIndex(pTable); - }else{ - pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); - } - z = argv[2]; - - if( pIndex ){ - tRowcnt *aiRowEst = 0; - int nCol = pIndex->nKeyCol+1; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - /* Index.aiRowEst may already be set here if there are duplicate - ** sqlite_stat1 entries for this index. In that case just clobber - ** the old data with the new instead of allocating a new array. */ - if( pIndex->aiRowEst==0 ){ - pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); - if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); - } - aiRowEst = pIndex->aiRowEst; -#endif - pIndex->bUnordered = 0; - decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); - if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; - }else{ - Index fakeIdx; - fakeIdx.szIdxRow = pTable->szTabRow; -#ifdef SQLITE_ENABLE_COSTMULT - fakeIdx.pTable = pTable; -#endif - decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); - pTable->szTabRow = fakeIdx.szIdxRow; - } - - return 0; -} - -/* -** If the Index.aSample variable is not NULL, delete the aSample[] array -** and its contents. -*/ -SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( pIdx->aSample ){ - int j; - for(j=0; jnSample; j++){ - IndexSample *p = &pIdx->aSample[j]; - sqlite3DbFree(db, p->p); - } - sqlite3DbFree(db, pIdx->aSample); - } - if( db && db->pnBytesFreed==0 ){ - pIdx->nSample = 0; - pIdx->aSample = 0; - } -#else - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(pIdx); -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ -} - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Populate the pIdx->aAvgEq[] array based on the samples currently -** stored in pIdx->aSample[]. -*/ -static void initAvgEq(Index *pIdx){ - if( pIdx ){ - IndexSample *aSample = pIdx->aSample; - IndexSample *pFinal = &aSample[pIdx->nSample-1]; - int iCol; - int nCol = 1; - if( pIdx->nSampleCol>1 ){ - /* If this is stat4 data, then calculate aAvgEq[] values for all - ** sample columns except the last. The last is always set to 1, as - ** once the trailing PK fields are considered all index keys are - ** unique. */ - nCol = pIdx->nSampleCol-1; - pIdx->aAvgEq[nCol] = 1; - } - for(iCol=0; iColnSample; - int i; /* Used to iterate through samples */ - tRowcnt sumEq = 0; /* Sum of the nEq values */ - tRowcnt avgEq = 0; - tRowcnt nRow; /* Number of rows in index */ - i64 nSum100 = 0; /* Number of terms contributing to sumEq */ - i64 nDist100; /* Number of distinct values in index */ - - if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ - nRow = pFinal->anLt[iCol]; - nDist100 = (i64)100 * pFinal->anDLt[iCol]; - nSample--; - }else{ - nRow = pIdx->aiRowEst[0]; - nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; - } - pIdx->nRowEst0 = nRow; - - /* Set nSum to the number of distinct (iCol+1) field prefixes that - ** occur in the stat4 table for this index. Set sumEq to the sum of - ** the nEq values for column iCol for the same set (adding the value - ** only once where there exist duplicate prefixes). */ - for(i=0; inSample-1) - || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] - ){ - sumEq += aSample[i].anEq[iCol]; - nSum100 += 100; - } - } - - if( nDist100>nSum100 ){ - avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); - } - if( avgEq==0 ) avgEq = 1; - pIdx->aAvgEq[iCol] = avgEq; - } - } -} - -/* -** Look up an index by name. Or, if the name of a WITHOUT ROWID table -** is supplied instead, find the PRIMARY KEY index for that table. -*/ -static Index *findIndexOrPrimaryKey( - sqlite3 *db, - const char *zName, - const char *zDb -){ - Index *pIdx = sqlite3FindIndex(db, zName, zDb); - if( pIdx==0 ){ - Table *pTab = sqlite3FindTable(db, zName, zDb); - if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); - } - return pIdx; -} - -/* -** Load the content from either the sqlite_stat4 or sqlite_stat3 table -** into the relevant Index.aSample[] arrays. -** -** Arguments zSql1 and zSql2 must point to SQL statements that return -** data equivalent to the following (statements are different for stat3, -** see the caller of this function for details): -** -** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx -** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 -** -** where %Q is replaced with the database name before the SQL is executed. -*/ -static int loadStatTbl( - sqlite3 *db, /* Database handle */ - int bStat3, /* Assume single column records only */ - const char *zSql1, /* SQL statement 1 (see above) */ - const char *zSql2, /* SQL statement 2 (see above) */ - const char *zDb /* Database name (e.g. "main") */ -){ - int rc; /* Result codes from subroutines */ - sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ - char *zSql; /* Text of the SQL statement */ - Index *pPrevIdx = 0; /* Previous index in the loop */ - IndexSample *pSample; /* A slot in pIdx->aSample[] */ - - assert( db->lookaside.bDisable ); - zSql = sqlite3MPrintf(db, zSql1, zDb); - if( !zSql ){ - return SQLITE_NOMEM_BKPT; - } - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); - sqlite3DbFree(db, zSql); - if( rc ) return rc; - - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - int nIdxCol = 1; /* Number of columns in stat4 records */ - - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - int nSample; /* Number of samples */ - int nByte; /* Bytes of space required */ - int i; /* Bytes of space required */ - tRowcnt *pSpace; - - zIndex = (char *)sqlite3_column_text(pStmt, 0); - if( zIndex==0 ) continue; - nSample = sqlite3_column_int(pStmt, 1); - pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); - assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); - /* Index.nSample is non-zero at this point if data has already been - ** loaded from the stat4 table. In this case ignore stat3 data. */ - if( pIdx==0 || pIdx->nSample ) continue; - if( bStat3==0 ){ - assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); - if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ - nIdxCol = pIdx->nKeyCol; - }else{ - nIdxCol = pIdx->nColumn; - } - } - pIdx->nSampleCol = nIdxCol; - nByte = sizeof(IndexSample) * nSample; - nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; - nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ - - pIdx->aSample = sqlite3DbMallocZero(db, nByte); - if( pIdx->aSample==0 ){ - sqlite3_finalize(pStmt); - return SQLITE_NOMEM_BKPT; - } - pSpace = (tRowcnt*)&pIdx->aSample[nSample]; - pIdx->aAvgEq = pSpace; pSpace += nIdxCol; - for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; - pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; - pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; - } - assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); - } - rc = sqlite3_finalize(pStmt); - if( rc ) return rc; - - zSql = sqlite3MPrintf(db, zSql2, zDb); - if( !zSql ){ - return SQLITE_NOMEM_BKPT; - } - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); - sqlite3DbFree(db, zSql); - if( rc ) return rc; - - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - int nCol = 1; /* Number of columns in index */ - - zIndex = (char *)sqlite3_column_text(pStmt, 0); - if( zIndex==0 ) continue; - pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); - if( pIdx==0 ) continue; - /* This next condition is true if data has already been loaded from - ** the sqlite_stat4 table. In this case ignore stat3 data. */ - nCol = pIdx->nSampleCol; - if( bStat3 && nCol>1 ) continue; - if( pIdx!=pPrevIdx ){ - initAvgEq(pPrevIdx); - pPrevIdx = pIdx; - } - pSample = &pIdx->aSample[pIdx->nSample]; - decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); - decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); - decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); - - /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. - ** This is in case the sample record is corrupted. In that case, the - ** sqlite3VdbeRecordCompare() may read up to two varints past the - ** end of the allocated buffer before it realizes it is dealing with - ** a corrupt record. Adding the two 0x00 bytes prevents this from causing - ** a buffer overread. */ - pSample->n = sqlite3_column_bytes(pStmt, 4); - pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); - if( pSample->p==0 ){ - sqlite3_finalize(pStmt); - return SQLITE_NOMEM_BKPT; - } - memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); - pIdx->nSample++; - } - rc = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); - return rc; -} - -/* -** Load content from the sqlite_stat4 and sqlite_stat3 tables into -** the Index.aSample[] arrays of all indices. -*/ -static int loadStat4(sqlite3 *db, const char *zDb){ - int rc = SQLITE_OK; /* Result codes from subroutines */ - - assert( db->lookaside.bDisable ); - if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ - rc = loadStatTbl(db, 0, - "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", - "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", - zDb - ); - } - - if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ - rc = loadStatTbl(db, 1, - "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", - "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", - zDb - ); - } - - return rc; -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - -/* -** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The -** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] -** arrays. The contents of sqlite_stat3/4 are used to populate the -** Index.aSample[] arrays. -** -** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR -** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined -** during compilation and the sqlite_stat3/4 table is present, no data is -** read from it. -** -** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the -** sqlite_stat4 table is not present in the database, SQLITE_ERROR is -** returned. However, in this case, data is read from the sqlite_stat1 -** table (if it is present) before returning. -** -** If an OOM error occurs, this function always sets db->mallocFailed. -** This means if the caller does not care about other errors, the return -** code may be ignored. -*/ -SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ - analysisInfo sInfo; - HashElem *i; - char *zSql; - int rc = SQLITE_OK; - - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pBt!=0 ); - - /* Clear any prior statistics */ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ - Index *pIdx = sqliteHashData(i); - pIdx->aiRowLogEst[0] = 0; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3DeleteIndexSamples(db, pIdx); - pIdx->aSample = 0; -#endif - } - - /* Load new statistics out of the sqlite_stat1 table */ - sInfo.db = db; - sInfo.zDatabase = db->aDb[iDb].zDbSName; - if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ - zSql = sqlite3MPrintf(db, - "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); - if( zSql==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); - sqlite3DbFree(db, zSql); - } - } - - /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ - Index *pIdx = sqliteHashData(i); - if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx); - } - - /* Load the statistics from the sqlite_stat4 table. */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ - db->lookaside.bDisable++; - rc = loadStat4(db, sInfo.zDatabase); - db->lookaside.bDisable--; - } - for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ - Index *pIdx = sqliteHashData(i); - sqlite3_free(pIdx->aiRowEst); - pIdx->aiRowEst = 0; - } -#endif - - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(db); - } - return rc; -} - - -#endif /* SQLITE_OMIT_ANALYZE */ - -/************** End of analyze.c *********************************************/ -/************** Begin file attach.c ******************************************/ -/* -** 2003 April 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used to implement the ATTACH and DETACH commands. -*/ -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_OMIT_ATTACH -/* -** Resolve an expression that was part of an ATTACH or DETACH statement. This -** is slightly different from resolving a normal SQL expression, because simple -** identifiers are treated as strings, not possible column names or aliases. -** -** i.e. if the parser sees: -** -** ATTACH DATABASE abc AS def -** -** it treats the two expressions as literal strings 'abc' and 'def' instead of -** looking for columns of the same name. -** -** This only applies to the root node of pExpr, so the statement: -** -** ATTACH DATABASE abc||def AS 'db2' -** -** will fail because neither abc or def can be resolved. -*/ -static int resolveAttachExpr(NameContext *pName, Expr *pExpr) -{ - int rc = SQLITE_OK; - if( pExpr ){ - if( pExpr->op!=TK_ID ){ - rc = sqlite3ResolveExprNames(pName, pExpr); - }else{ - pExpr->op = TK_STRING; - } - } - return rc; -} - -/* -** An SQL user-function registered to do the work of an ATTACH statement. The -** three arguments to the function come directly from an attach statement: -** -** ATTACH DATABASE x AS y KEY z -** -** SELECT sqlite_attach(x, y, z) -** -** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the -** third argument. -*/ -static void attachFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - int i; - int rc = 0; - sqlite3 *db = sqlite3_context_db_handle(context); - const char *zName; - const char *zFile; - char *zPath = 0; - char *zErr = 0; - unsigned int flags; - Db *aNew; - char *zErrDyn = 0; - sqlite3_vfs *pVfs; - - UNUSED_PARAMETER(NotUsed); - - zFile = (const char *)sqlite3_value_text(argv[0]); - zName = (const char *)sqlite3_value_text(argv[1]); - if( zFile==0 ) zFile = ""; - if( zName==0 ) zName = ""; - - /* Check for the following errors: - ** - ** * Too many attached databases, - ** * Transaction currently open - ** * Specified database name already being used. - */ - if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ - zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", - db->aLimit[SQLITE_LIMIT_ATTACHED] - ); - goto attach_error; - } - if( !db->autoCommit ){ - zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); - goto attach_error; - } - for(i=0; inDb; i++){ - char *z = db->aDb[i].zDbSName; - assert( z && zName ); - if( sqlite3StrICmp(z, zName)==0 ){ - zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); - goto attach_error; - } - } - - /* Allocate the new entry in the db->aDb[] array and initialize the schema - ** hash tables. - */ - if( db->aDb==db->aDbStatic ){ - aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); - if( aNew==0 ) return; - memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); - }else{ - aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ) return; - } - db->aDb = aNew; - aNew = &db->aDb[db->nDb]; - memset(aNew, 0, sizeof(*aNew)); - - /* Open the database file. If the btree is successfully opened, use - ** it to obtain the database schema. At this point the schema may - ** or may not be initialized. - */ - flags = db->openFlags; - rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); - return; - } - assert( pVfs ); - flags |= SQLITE_OPEN_MAIN_DB; - rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); - sqlite3_free( zPath ); - db->nDb++; - if( rc==SQLITE_CONSTRAINT ){ - rc = SQLITE_ERROR; - zErrDyn = sqlite3MPrintf(db, "database is already attached"); - }else if( rc==SQLITE_OK ){ - Pager *pPager; - aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); - if( !aNew->pSchema ){ - rc = SQLITE_NOMEM_BKPT; - }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){ - zErrDyn = sqlite3MPrintf(db, - "attached databases must use the same text encoding as main database"); - rc = SQLITE_ERROR; - } - sqlite3BtreeEnter(aNew->pBt); - pPager = sqlite3BtreePager(aNew->pBt); - sqlite3PagerLockingMode(pPager, db->dfltLockMode); - sqlite3BtreeSecureDelete(aNew->pBt, - sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - sqlite3BtreeSetPagerFlags(aNew->pBt, - PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); -#endif - sqlite3BtreeLeave(aNew->pBt); - } - aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - aNew->zDbSName = sqlite3DbStrDup(db, zName); - if( rc==SQLITE_OK && aNew->zDbSName==0 ){ - rc = SQLITE_NOMEM_BKPT; - } - - -#ifdef SQLITE_HAS_CODEC - if( rc==SQLITE_OK ){ - extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); - extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); - int nKey; - char *zKey; - int t = sqlite3_value_type(argv[2]); - switch( t ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: - zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); - rc = SQLITE_ERROR; - break; - - case SQLITE_TEXT: - case SQLITE_BLOB: - nKey = sqlite3_value_bytes(argv[2]); - zKey = (char *)sqlite3_value_blob(argv[2]); - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - break; - - case SQLITE_NULL: - /* No key specified. Use the key from the main database */ - sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - } - break; - } - } -#endif - - /* If the file was opened successfully, read the schema for the new database. - ** If this fails, or if opening the file failed, then close the file and - ** remove the entry from the db->aDb[] array. i.e. put everything back the way - ** we found it. - */ - if( rc==SQLITE_OK ){ - sqlite3BtreeEnterAll(db); - rc = sqlite3Init(db, &zErrDyn); - sqlite3BtreeLeaveAll(db); - } -#ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK ){ - u8 newAuth = 0; - rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); - if( newAuthauth.authLevel ){ - rc = SQLITE_AUTH_USER; - } - } -#endif - if( rc ){ - int iDb = db->nDb - 1; - assert( iDb>=2 ); - if( db->aDb[iDb].pBt ){ - sqlite3BtreeClose(db->aDb[iDb].pBt); - db->aDb[iDb].pBt = 0; - db->aDb[iDb].pSchema = 0; - } - sqlite3ResetAllSchemasOfConnection(db); - db->nDb = iDb; - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); - sqlite3DbFree(db, zErrDyn); - zErrDyn = sqlite3MPrintf(db, "out of memory"); - }else if( zErrDyn==0 ){ - zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); - } - goto attach_error; - } - - return; - -attach_error: - /* Return an error if we get here */ - if( zErrDyn ){ - sqlite3_result_error(context, zErrDyn, -1); - sqlite3DbFree(db, zErrDyn); - } - if( rc ) sqlite3_result_error_code(context, rc); -} - -/* -** An SQL user-function registered to do the work of an DETACH statement. The -** three arguments to the function come directly from a detach statement: -** -** DETACH DATABASE x -** -** SELECT sqlite_detach(x) -*/ -static void detachFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - const char *zName = (const char *)sqlite3_value_text(argv[0]); - sqlite3 *db = sqlite3_context_db_handle(context); - int i; - Db *pDb = 0; - char zErr[128]; - - UNUSED_PARAMETER(NotUsed); - - if( zName==0 ) zName = ""; - for(i=0; inDb; i++){ - pDb = &db->aDb[i]; - if( pDb->pBt==0 ) continue; - if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; - } - - if( i>=db->nDb ){ - sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); - goto detach_error; - } - if( i<2 ){ - sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); - goto detach_error; - } - if( !db->autoCommit ){ - sqlite3_snprintf(sizeof(zErr), zErr, - "cannot DETACH database within transaction"); - goto detach_error; - } - if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ - sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); - goto detach_error; - } - - sqlite3BtreeClose(pDb->pBt); - pDb->pBt = 0; - pDb->pSchema = 0; - sqlite3CollapseDatabaseArray(db); - return; - -detach_error: - sqlite3_result_error(context, zErr, -1); -} - -/* -** This procedure generates VDBE code for a single invocation of either the -** sqlite_detach() or sqlite_attach() SQL user functions. -*/ -static void codeAttach( - Parse *pParse, /* The parser context */ - int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ - FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ - Expr *pAuthArg, /* Expression to pass to authorization callback */ - Expr *pFilename, /* Name of database file */ - Expr *pDbname, /* Name of the database to use internally */ - Expr *pKey /* Database key for encryption extension */ -){ - int rc; - NameContext sName; - Vdbe *v; - sqlite3* db = pParse->db; - int regArgs; - - memset(&sName, 0, sizeof(NameContext)); - sName.pParse = pParse; - - if( - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) - ){ - goto attach_end; - } - -#ifndef SQLITE_OMIT_AUTHORIZATION - if( pAuthArg ){ - char *zAuthArg; - if( pAuthArg->op==TK_STRING ){ - zAuthArg = pAuthArg->u.zToken; - }else{ - zAuthArg = 0; - } - rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); - if(rc!=SQLITE_OK ){ - goto attach_end; - } - } -#endif /* SQLITE_OMIT_AUTHORIZATION */ - - - v = sqlite3GetVdbe(pParse); - regArgs = sqlite3GetTempRange(pParse, 4); - sqlite3ExprCode(pParse, pFilename, regArgs); - sqlite3ExprCode(pParse, pDbname, regArgs+1); - sqlite3ExprCode(pParse, pKey, regArgs+2); - - assert( v || db->mallocFailed ); - if( v ){ - sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3, - (char *)pFunc, P4_FUNCDEF); - assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); - sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); - - /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this - ** statement only). For DETACH, set it to false (expire all existing - ** statements). - */ - sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); - } - -attach_end: - sqlite3ExprDelete(db, pFilename); - sqlite3ExprDelete(db, pDbname); - sqlite3ExprDelete(db, pKey); -} - -/* -** Called by the parser to compile a DETACH statement. -** -** DETACH pDbname -*/ -SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ - static const FuncDef detach_func = { - 1, /* nArg */ - SQLITE_UTF8, /* funcFlags */ - 0, /* pUserData */ - 0, /* pNext */ - detachFunc, /* xSFunc */ - 0, /* xFinalize */ - "sqlite_detach", /* zName */ - {0} - }; - codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); -} - -/* -** Called by the parser to compile an ATTACH statement. -** -** ATTACH p AS pDbname KEY pKey -*/ -SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ - static const FuncDef attach_func = { - 3, /* nArg */ - SQLITE_UTF8, /* funcFlags */ - 0, /* pUserData */ - 0, /* pNext */ - attachFunc, /* xSFunc */ - 0, /* xFinalize */ - "sqlite_attach", /* zName */ - {0} - }; - codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); -} -#endif /* SQLITE_OMIT_ATTACH */ - -/* -** Initialize a DbFixer structure. This routine must be called prior -** to passing the structure to one of the sqliteFixAAAA() routines below. -*/ -SQLITE_PRIVATE void sqlite3FixInit( - DbFixer *pFix, /* The fixer to be initialized */ - Parse *pParse, /* Error messages will be written here */ - int iDb, /* This is the database that must be used */ - const char *zType, /* "view", "trigger", or "index" */ - const Token *pName /* Name of the view, trigger, or index */ -){ - sqlite3 *db; - - db = pParse->db; - assert( db->nDb>iDb ); - pFix->pParse = pParse; - pFix->zDb = db->aDb[iDb].zDbSName; - pFix->pSchema = db->aDb[iDb].pSchema; - pFix->zType = zType; - pFix->pName = pName; - pFix->bVarOnly = (iDb==1); -} - -/* -** The following set of routines walk through the parse tree and assign -** a specific database to all table references where the database name -** was left unspecified in the original SQL statement. The pFix structure -** must have been initialized by a prior call to sqlite3FixInit(). -** -** These routines are used to make sure that an index, trigger, or -** view in one database does not refer to objects in a different database. -** (Exception: indices, triggers, and views in the TEMP database are -** allowed to refer to anything.) If a reference is explicitly made -** to an object in a different database, an error message is added to -** pParse->zErrMsg and these routines return non-zero. If everything -** checks out, these routines return 0. -*/ -SQLITE_PRIVATE int sqlite3FixSrcList( - DbFixer *pFix, /* Context of the fixation */ - SrcList *pList /* The Source list to check and modify */ -){ - int i; - const char *zDb; - struct SrcList_item *pItem; - - if( NEVER(pList==0) ) return 0; - zDb = pFix->zDb; - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bVarOnly==0 ){ - if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; - } - sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); - pItem->zDatabase = 0; - pItem->pSchema = pFix->pSchema; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; -#endif - } - return 0; -} -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE int sqlite3FixSelect( - DbFixer *pFix, /* Context of the fixation */ - Select *pSelect /* The SELECT statement to be fixed to one database */ -){ - while( pSelect ){ - if( sqlite3FixExprList(pFix, pSelect->pEList) ){ - return 1; - } - if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ - return 1; - } - pSelect = pSelect->pPrior; - } - return 0; -} -SQLITE_PRIVATE int sqlite3FixExpr( - DbFixer *pFix, /* Context of the fixation */ - Expr *pExpr /* The expression to be fixed to one database */ -){ - while( pExpr ){ - if( pExpr->op==TK_VARIABLE ){ - if( pFix->pParse->db->init.busy ){ - pExpr->op = TK_NULL; - }else{ - sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); - return 1; - } - } - if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; - }else{ - if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; - } - if( sqlite3FixExpr(pFix, pExpr->pRight) ){ - return 1; - } - pExpr = pExpr->pLeft; - } - return 0; -} -SQLITE_PRIVATE int sqlite3FixExprList( - DbFixer *pFix, /* Context of the fixation */ - ExprList *pList /* The expression to be fixed to one database */ -){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return 0; - for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; -} -#endif - -#ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE int sqlite3FixTriggerStep( - DbFixer *pFix, /* Context of the fixation */ - TriggerStep *pStep /* The trigger step be fixed to one database */ -){ - while( pStep ){ - if( sqlite3FixSelect(pFix, pStep->pSelect) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pStep->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } - pStep = pStep->pNext; - } - return 0; -} -#endif - -/************** End of attach.c **********************************************/ -/************** Begin file auth.c ********************************************/ -/* -** 2003 January 11 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used to implement the sqlite3_set_authorizer() -** API. This facility is an optional feature of the library. Embedded -** systems that do not need this facility may omit it by recompiling -** the library with -DSQLITE_OMIT_AUTHORIZATION=1 -*/ -/* #include "sqliteInt.h" */ - -/* -** All of the code in this file may be omitted by defining a single -** macro. -*/ -#ifndef SQLITE_OMIT_AUTHORIZATION - -/* -** Set or clear the access authorization function. -** -** The access authorization function is be called during the compilation -** phase to verify that the user has read and/or write access permission on -** various fields of the database. The first argument to the auth function -** is a copy of the 3rd argument to this routine. The second argument -** to the auth function is one of these constants: -** -** SQLITE_CREATE_INDEX -** SQLITE_CREATE_TABLE -** SQLITE_CREATE_TEMP_INDEX -** SQLITE_CREATE_TEMP_TABLE -** SQLITE_CREATE_TEMP_TRIGGER -** SQLITE_CREATE_TEMP_VIEW -** SQLITE_CREATE_TRIGGER -** SQLITE_CREATE_VIEW -** SQLITE_DELETE -** SQLITE_DROP_INDEX -** SQLITE_DROP_TABLE -** SQLITE_DROP_TEMP_INDEX -** SQLITE_DROP_TEMP_TABLE -** SQLITE_DROP_TEMP_TRIGGER -** SQLITE_DROP_TEMP_VIEW -** SQLITE_DROP_TRIGGER -** SQLITE_DROP_VIEW -** SQLITE_INSERT -** SQLITE_PRAGMA -** SQLITE_READ -** SQLITE_SELECT -** SQLITE_TRANSACTION -** SQLITE_UPDATE -** -** The third and fourth arguments to the auth function are the name of -** the table and the column that are being accessed. The auth function -** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If -** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY -** means that the SQL statement will never-run - the sqlite3_exec() call -** will return with an error. SQLITE_IGNORE means that the SQL statement -** should run but attempts to read the specified column will return NULL -** and attempts to write the column will be ignored. -** -** Setting the auth function to NULL disables this hook. The default -** setting of the auth function is NULL. -*/ -SQLITE_API int sqlite3_set_authorizer( - sqlite3 *db, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pArg -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - db->xAuth = (sqlite3_xauth)xAuth; - db->pAuthArg = pArg; - sqlite3ExpirePreparedStatements(db); - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -/* -** Write an error message into pParse->zErrMsg that explains that the -** user-supplied authorization function returned an illegal value. -*/ -static void sqliteAuthBadReturnCode(Parse *pParse){ - sqlite3ErrorMsg(pParse, "authorizer malfunction"); - pParse->rc = SQLITE_ERROR; -} - -/* -** Invoke the authorization callback for permission to read column zCol from -** table zTab in database zDb. This function assumes that an authorization -** callback has been registered (i.e. that sqlite3.xAuth is not NULL). -** -** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed -** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE -** is treated as SQLITE_DENY. In this case an error is left in pParse. -*/ -SQLITE_PRIVATE int sqlite3AuthReadCol( - Parse *pParse, /* The parser context */ - const char *zTab, /* Table name */ - const char *zCol, /* Column name */ - int iDb /* Index of containing database. */ -){ - sqlite3 *db = pParse->db; /* Database handle */ - char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */ - int rc; /* Auth callback return code */ - - if( db->init.busy ) return SQLITE_OK; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); - if( rc==SQLITE_DENY ){ - if( db->nDb>2 || iDb!=0 ){ - sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); - }else{ - sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); - } - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ - sqliteAuthBadReturnCode(pParse); - } - return rc; -} - -/* -** The pExpr should be a TK_COLUMN expression. The table referred to -** is in pTabList or else it is the NEW or OLD table of a trigger. -** Check to see if it is OK to read this particular column. -** -** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN -** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, -** then generate an error. -*/ -SQLITE_PRIVATE void sqlite3AuthRead( - Parse *pParse, /* The parser context */ - Expr *pExpr, /* The expression to check authorization on */ - Schema *pSchema, /* The schema of the expression */ - SrcList *pTabList /* All table that pExpr might refer to */ -){ - sqlite3 *db = pParse->db; - Table *pTab = 0; /* The table being read */ - const char *zCol; /* Name of the column of the table */ - int iSrc; /* Index in pTabList->a[] of table being read */ - int iDb; /* The index of the database the expression refers to */ - int iCol; /* Index of column in table */ - - if( db->xAuth==0 ) return; - iDb = sqlite3SchemaToIndex(pParse->db, pSchema); - if( iDb<0 ){ - /* An attempt to read a column out of a subquery or other - ** temporary table. */ - return; - } - - assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); - if( pExpr->op==TK_TRIGGER ){ - pTab = pParse->pTriggerTab; - }else{ - assert( pTabList ); - for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ - if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ - pTab = pTabList->a[iSrc].pTab; - break; - } - } - } - iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; - - if( iCol>=0 ){ - assert( iColnCol ); - zCol = pTab->aCol[iCol].zName; - }else if( pTab->iPKey>=0 ){ - assert( pTab->iPKeynCol ); - zCol = pTab->aCol[pTab->iPKey].zName; - }else{ - zCol = "ROWID"; - } - assert( iDb>=0 && iDbnDb ); - if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ - pExpr->op = TK_NULL; - } -} - -/* -** Do an authorization check using the code and arguments given. Return -** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY -** is returned, then the error count and error message in pParse are -** modified appropriately. -*/ -SQLITE_PRIVATE int sqlite3AuthCheck( - Parse *pParse, - int code, - const char *zArg1, - const char *zArg2, - const char *zArg3 -){ - sqlite3 *db = pParse->db; - int rc; - - /* Don't do any authorization checks if the database is initialising - ** or if the parser is being invoked from within sqlite3_declare_vtab. - */ - if( db->init.busy || IN_DECLARE_VTAB ){ - return SQLITE_OK; - } - - if( db->xAuth==0 ){ - return SQLITE_OK; - } - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext -#ifdef SQLITE_USER_AUTHENTICATION - ,db->auth.zAuthUser -#endif - ); - if( rc==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized"); - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ - rc = SQLITE_DENY; - sqliteAuthBadReturnCode(pParse); - } - return rc; -} - -/* -** Push an authorization context. After this routine is called, the -** zArg3 argument to authorization callbacks will be zContext until -** popped. Or if pParse==0, this routine is a no-op. -*/ -SQLITE_PRIVATE void sqlite3AuthContextPush( - Parse *pParse, - AuthContext *pContext, - const char *zContext -){ - assert( pParse ); - pContext->pParse = pParse; - pContext->zAuthContext = pParse->zAuthContext; - pParse->zAuthContext = zContext; -} - -/* -** Pop an authorization context that was previously pushed -** by sqlite3AuthContextPush -*/ -SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ - if( pContext->pParse ){ - pContext->pParse->zAuthContext = pContext->zAuthContext; - pContext->pParse = 0; - } -} - -#endif /* SQLITE_OMIT_AUTHORIZATION */ - -/************** End of auth.c ************************************************/ -/************** Begin file build.c *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that are called by the SQLite parser -** when syntax rules are reduced. The routines in this file handle the -** following kinds of SQL syntax: -** -** CREATE TABLE -** DROP TABLE -** CREATE INDEX -** DROP INDEX -** creating ID lists -** BEGIN TRANSACTION -** COMMIT -** ROLLBACK -*/ -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_OMIT_SHARED_CACHE -/* -** The TableLock structure is only used by the sqlite3TableLock() and -** codeTableLocks() functions. -*/ -struct TableLock { - int iDb; /* The database containing the table to be locked */ - int iTab; /* The root page of the table to be locked */ - u8 isWriteLock; /* True for write lock. False for a read lock */ - const char *zName; /* Name of the table */ -}; - -/* -** Record the fact that we want to lock a table at run-time. -** -** The table to be locked has root page iTab and is found in database iDb. -** A read or a write lock can be taken depending on isWritelock. -** -** This routine just records the fact that the lock is desired. The -** code to make the lock occur is generated by a later call to -** codeTableLocks() which occurs during sqlite3FinishCoding(). -*/ -SQLITE_PRIVATE void sqlite3TableLock( - Parse *pParse, /* Parsing context */ - int iDb, /* Index of the database containing the table to lock */ - int iTab, /* Root page number of the table to be locked */ - u8 isWriteLock, /* True for a write lock */ - const char *zName /* Name of the table to be locked */ -){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - int i; - int nBytes; - TableLock *p; - assert( iDb>=0 ); - - for(i=0; inTableLock; i++){ - p = &pToplevel->aTableLock[i]; - if( p->iDb==iDb && p->iTab==iTab ){ - p->isWriteLock = (p->isWriteLock || isWriteLock); - return; - } - } - - nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); - pToplevel->aTableLock = - sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); - if( pToplevel->aTableLock ){ - p = &pToplevel->aTableLock[pToplevel->nTableLock++]; - p->iDb = iDb; - p->iTab = iTab; - p->isWriteLock = isWriteLock; - p->zName = zName; - }else{ - pToplevel->nTableLock = 0; - sqlite3OomFault(pToplevel->db); - } -} - -/* -** Code an OP_TableLock instruction for each table locked by the -** statement (configured by calls to sqlite3TableLock()). -*/ -static void codeTableLocks(Parse *pParse){ - int i; - Vdbe *pVdbe; - - pVdbe = sqlite3GetVdbe(pParse); - assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ - - for(i=0; inTableLock; i++){ - TableLock *p = &pParse->aTableLock[i]; - int p1 = p->iDb; - sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, - p->zName, P4_STATIC); - } -} -#else - #define codeTableLocks(x) -#endif - -/* -** Return TRUE if the given yDbMask object is empty - if it contains no -** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() -** macros when SQLITE_MAX_ATTACHED is greater than 30. -*/ -#if SQLITE_MAX_ATTACHED>30 -SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ - int i; - for(i=0; ipToplevel==0 ); - db = pParse->db; - if( pParse->nested ) return; - if( db->mallocFailed || pParse->nErr ){ - if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; - return; - } - - /* Begin by generating some termination code at the end of the - ** vdbe program - */ - v = sqlite3GetVdbe(pParse); - assert( !pParse->isMultiWrite - || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); - if( v ){ - sqlite3VdbeAddOp0(v, OP_Halt); - -#if SQLITE_USER_AUTHENTICATION - if( pParse->nTableLock>0 && db->init.busy==0 ){ - sqlite3UserAuthInit(db); - if( db->auth.authLevelrc = SQLITE_AUTH_USER; - return; - } - } -#endif - - /* The cookie mask contains one bit for each database file open. - ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are - ** set for each database that is used. Generate code to start a - ** transaction on each used database and to verify the schema cookie - ** on each used database. - */ - if( db->mallocFailed==0 - && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) - ){ - int iDb, i; - assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); - sqlite3VdbeJumpHere(v, 0); - for(iDb=0; iDbnDb; iDb++){ - Schema *pSchema; - if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; - sqlite3VdbeUsesBtree(v, iDb); - pSchema = db->aDb[iDb].pSchema; - sqlite3VdbeAddOp4Int(v, - OP_Transaction, /* Opcode */ - iDb, /* P1 */ - DbMaskTest(pParse->writeMask,iDb), /* P2 */ - pSchema->schema_cookie, /* P3 */ - pSchema->iGeneration /* P4 */ - ); - if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); - VdbeComment((v, - "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - for(i=0; inVtabLock; i++){ - char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); - sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); - } - pParse->nVtabLock = 0; -#endif - - /* Once all the cookies have been verified and transactions opened, - ** obtain the required table-locks. This is a no-op unless the - ** shared-cache feature is enabled. - */ - codeTableLocks(pParse); - - /* Initialize any AUTOINCREMENT data structures required. - */ - sqlite3AutoincrementBegin(pParse); - - /* Code constant expressions that where factored out of inner loops */ - if( pParse->pConstExpr ){ - ExprList *pEL = pParse->pConstExpr; - pParse->okConstFactor = 0; - for(i=0; inExpr; i++){ - sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); - } - } - - /* Finally, jump back to the beginning of the executable code. */ - sqlite3VdbeGoto(v, 1); - } - } - - - /* Get the VDBE program ready for execution - */ - if( v && pParse->nErr==0 && !db->mallocFailed ){ - assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ - /* A minimum of one cursor is required if autoincrement is used - * See ticket [a696379c1f08866] */ - if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; - sqlite3VdbeMakeReady(v, pParse); - pParse->rc = SQLITE_DONE; - }else{ - pParse->rc = SQLITE_ERROR; - } -} - -/* -** Run the parser and code generator recursively in order to generate -** code for the SQL statement given onto the end of the pParse context -** currently under construction. When the parser is run recursively -** this way, the final OP_Halt is not appended and other initialization -** and finalization steps are omitted because those are handling by the -** outermost parser. -** -** Not everything is nestable. This facility is designed to permit -** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use -** care if you decide to try to use this routine for some other purposes. -*/ -SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ - va_list ap; - char *zSql; - char *zErrMsg = 0; - sqlite3 *db = pParse->db; - char saveBuf[PARSE_TAIL_SZ]; - - if( pParse->nErr ) return; - assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ - va_start(ap, zFormat); - zSql = sqlite3VMPrintf(db, zFormat, ap); - va_end(ap); - if( zSql==0 ){ - return; /* A malloc must have failed */ - } - pParse->nested++; - memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); - memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); - sqlite3RunParser(pParse, zSql, &zErrMsg); - sqlite3DbFree(db, zErrMsg); - sqlite3DbFree(db, zSql); - memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); - pParse->nested--; -} - -#if SQLITE_USER_AUTHENTICATION -/* -** Return TRUE if zTable is the name of the system table that stores the -** list of users and their access credentials. -*/ -SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ - return sqlite3_stricmp(zTable, "sqlite_user")==0; -} -#endif - -/* -** Locate the in-memory structure that describes a particular database -** table given the name of that table and (optionally) the name of the -** database containing the table. Return NULL if not found. -** -** If zDatabase is 0, all databases are searched for the table and the -** first matching table is returned. (No checking for duplicate table -** names is done.) The search order is TEMP first, then MAIN, then any -** auxiliary databases added using the ATTACH command. -** -** See also sqlite3LocateTable(). -*/ -SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ - Table *p = 0; - int i; - - /* All mutexes are required for schema access. Make sure we hold them. */ - assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); -#if SQLITE_USER_AUTHENTICATION - /* Only the admin user is allowed to know that the sqlite_user table - ** exists */ - if( db->auth.authLevelnDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); - if( p ) break; - } - } - return p; -} - -/* -** Locate the in-memory structure that describes a particular database -** table given the name of that table and (optionally) the name of the -** database containing the table. Return NULL if not found. Also leave an -** error message in pParse->zErrMsg. -** -** The difference between this routine and sqlite3FindTable() is that this -** routine leaves an error message in pParse->zErrMsg where -** sqlite3FindTable() does not. -*/ -SQLITE_PRIVATE Table *sqlite3LocateTable( - Parse *pParse, /* context in which to report errors */ - u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */ - const char *zName, /* Name of the table we are looking for */ - const char *zDbase /* Name of the database. Might be NULL */ -){ - Table *p; - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return 0; - } - - p = sqlite3FindTable(pParse->db, zName, zDbase); - if( p==0 ){ - const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3FindDbName(pParse->db, zDbase)<1 ){ - /* If zName is the not the name of a table in the schema created using - ** CREATE, then check to see if it is the name of an virtual table that - ** can be an eponymous virtual table. */ - Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName); - if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ - return pMod->pEpoTab; - } - } -#endif - if( (flags & LOCATE_NOERR)==0 ){ - if( zDbase ){ - sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); - }else{ - sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); - } - pParse->checkSchema = 1; - } - } - - return p; -} - -/* -** Locate the table identified by *p. -** -** This is a wrapper around sqlite3LocateTable(). The difference between -** sqlite3LocateTable() and this function is that this function restricts -** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be -** non-NULL if it is part of a view or trigger program definition. See -** sqlite3FixSrcList() for details. -*/ -SQLITE_PRIVATE Table *sqlite3LocateTableItem( - Parse *pParse, - u32 flags, - struct SrcList_item *p -){ - const char *zDb; - assert( p->pSchema==0 || p->zDatabase==0 ); - if( p->pSchema ){ - int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); - zDb = pParse->db->aDb[iDb].zDbSName; - }else{ - zDb = p->zDatabase; - } - return sqlite3LocateTable(pParse, flags, p->zName, zDb); -} - -/* -** Locate the in-memory structure that describes -** a particular index given the name of that index -** and the name of the database that contains the index. -** Return NULL if not found. -** -** If zDatabase is 0, all databases are searched for the -** table and the first matching index is returned. (No checking -** for duplicate index names is done.) The search order is -** TEMP first, then MAIN, then any auxiliary databases added -** using the ATTACH command. -*/ -SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ - Index *p = 0; - int i; - /* All mutexes are required for schema access. Make sure we hold them. */ - assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); - for(i=OMIT_TEMPDB; inDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - Schema *pSchema = db->aDb[j].pSchema; - assert( pSchema ); - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - p = sqlite3HashFind(&pSchema->idxHash, zName); - if( p ) break; - } - return p; -} - -/* -** Reclaim the memory used by an index -*/ -static void freeIndex(sqlite3 *db, Index *p){ -#ifndef SQLITE_OMIT_ANALYZE - sqlite3DeleteIndexSamples(db, p); -#endif - sqlite3ExprDelete(db, p->pPartIdxWhere); - sqlite3ExprListDelete(db, p->aColExpr); - sqlite3DbFree(db, p->zColAff); - if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3_free(p->aiRowEst); -#endif - sqlite3DbFree(db, p); -} - -/* -** For the index called zIdxName which is found in the database iDb, -** unlike that index from its Table then remove the index from -** the index hash table and free all memory structures associated -** with the index. -*/ -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ - Index *pIndex; - Hash *pHash; - - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pHash = &db->aDb[iDb].pSchema->idxHash; - pIndex = sqlite3HashInsert(pHash, zIdxName, 0); - if( ALWAYS(pIndex) ){ - if( pIndex->pTable->pIndex==pIndex ){ - pIndex->pTable->pIndex = pIndex->pNext; - }else{ - Index *p; - /* Justification of ALWAYS(); The index must be on the list of - ** indices. */ - p = pIndex->pTable->pIndex; - while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; } - if( ALWAYS(p && p->pNext==pIndex) ){ - p->pNext = pIndex->pNext; - } - } - freeIndex(db, pIndex); - } - db->flags |= SQLITE_InternChanges; -} - -/* -** Look through the list of open database files in db->aDb[] and if -** any have been closed, remove them from the list. Reallocate the -** db->aDb[] structure to a smaller size, if possible. -** -** Entry 0 (the "main" database) and entry 1 (the "temp" database) -** are never candidates for being collapsed. -*/ -SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ - int i, j; - for(i=j=2; inDb; i++){ - struct Db *pDb = &db->aDb[i]; - if( pDb->pBt==0 ){ - sqlite3DbFree(db, pDb->zDbSName); - pDb->zDbSName = 0; - continue; - } - if( jaDb[j] = db->aDb[i]; - } - j++; - } - db->nDb = j; - if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ - memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); - sqlite3DbFree(db, db->aDb); - db->aDb = db->aDbStatic; - } -} - -/* -** Reset the schema for the database at index iDb. Also reset the -** TEMP schema. -*/ -SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ - Db *pDb; - assert( iDbnDb ); - - /* Case 1: Reset the single schema identified by iDb */ - pDb = &db->aDb[iDb]; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); - - /* If any database other than TEMP is reset, then also reset TEMP - ** since TEMP might be holding triggers that reference tables in the - ** other database. - */ - if( iDb!=1 ){ - pDb = &db->aDb[1]; - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); - } - return; -} - -/* -** Erase all schema information from all attached databases (including -** "main" and "temp") for a single database connection. -*/ -SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ - int i; - sqlite3BtreeEnterAll(db); - for(i=0; inDb; i++){ - Db *pDb = &db->aDb[i]; - if( pDb->pSchema ){ - sqlite3SchemaClear(pDb->pSchema); - } - } - db->flags &= ~SQLITE_InternChanges; - sqlite3VtabUnlockList(db); - sqlite3BtreeLeaveAll(db); - sqlite3CollapseDatabaseArray(db); -} - -/* -** This routine is called when a commit occurs. -*/ -SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ - db->flags &= ~SQLITE_InternChanges; -} - -/* -** Delete memory allocated for the column names of a table or view (the -** Table.aCol[] array). -*/ -SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ - int i; - Column *pCol; - assert( pTable!=0 ); - if( (pCol = pTable->aCol)!=0 ){ - for(i=0; inCol; i++, pCol++){ - sqlite3DbFree(db, pCol->zName); - sqlite3ExprDelete(db, pCol->pDflt); - sqlite3DbFree(db, pCol->zColl); - } - sqlite3DbFree(db, pTable->aCol); - } -} - -/* -** Remove the memory data structures associated with the given -** Table. No changes are made to disk by this routine. -** -** This routine just deletes the data structure. It does not unlink -** the table data structure from the hash table. But it does destroy -** memory structures of the indices and foreign keys associated with -** the table. -** -** The db parameter is optional. It is needed if the Table object -** contains lookaside memory. (Table objects in the schema do not use -** lookaside memory, but some ephemeral Table objects do.) Or the -** db parameter can be used with db->pnBytesFreed to measure the memory -** used by the Table object. -*/ -static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ - Index *pIndex, *pNext; - TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */ - - /* Record the number of outstanding lookaside allocations in schema Tables - ** prior to doing any free() operations. Since schema Tables do not use - ** lookaside, this number should not change. */ - TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ? - db->lookaside.nOut : 0 ); - - /* Delete all indices associated with this table. */ - for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ - pNext = pIndex->pNext; - assert( pIndex->pSchema==pTable->pSchema - || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); - if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ - char *zName = pIndex->zName; - TESTONLY ( Index *pOld = ) sqlite3HashInsert( - &pIndex->pSchema->idxHash, zName, 0 - ); - assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); - assert( pOld==pIndex || pOld==0 ); - } - freeIndex(db, pIndex); - } - - /* Delete any foreign keys attached to this table. */ - sqlite3FkDelete(db, pTable); - - /* Delete the Table structure itself. - */ - sqlite3DeleteColumnNames(db, pTable); - sqlite3DbFree(db, pTable->zName); - sqlite3DbFree(db, pTable->zColAff); - sqlite3SelectDelete(db, pTable->pSelect); - sqlite3ExprListDelete(db, pTable->pCheck); -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3VtabClear(db, pTable); -#endif - sqlite3DbFree(db, pTable); - - /* Verify that no lookaside memory was used by schema tables */ - assert( nLookaside==0 || nLookaside==db->lookaside.nOut ); -} -SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ - /* Do not delete the table until the reference count reaches zero. */ - if( !pTable ) return; - if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return; - deleteTable(db, pTable); -} - - -/* -** Unlink the given table from the hash tables and the delete the -** table structure with all its indices and foreign keys. -*/ -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ - Table *p; - Db *pDb; - - assert( db!=0 ); - assert( iDb>=0 && iDbnDb ); - assert( zTabName ); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ - pDb = &db->aDb[iDb]; - p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); - sqlite3DeleteTable(db, p); - db->flags |= SQLITE_InternChanges; -} - -/* -** Given a token, return a string that consists of the text of that -** token. Space to hold the returned string -** is obtained from sqliteMalloc() and must be freed by the calling -** function. -** -** Any quotation marks (ex: "name", 'name', [name], or `name`) that -** surround the body of the token are removed. -** -** Tokens are often just pointers into the original SQL text and so -** are not \000 terminated and are not persistent. The returned string -** is \000 terminated and is persistent. -*/ -SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ - char *zName; - if( pName ){ - zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); - sqlite3Dequote(zName); - }else{ - zName = 0; - } - return zName; -} - -/* -** Open the sqlite_master table stored in database number iDb for -** writing. The table is opened using cursor 0. -*/ -SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){ - Vdbe *v = sqlite3GetVdbe(p); - sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb)); - sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); - if( p->nTab==0 ){ - p->nTab = 1; - } -} - -/* -** Parameter zName points to a nul-terminated buffer containing the name -** of a database ("main", "temp" or the name of an attached db). This -** function returns the index of the named database in db->aDb[], or -** -1 if the named db cannot be found. -*/ -SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ - int i = -1; /* Database number */ - if( zName ){ - Db *pDb; - for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( 0==sqlite3StrICmp(pDb->zDbSName, zName) ) break; - } - } - return i; -} - -/* -** The token *pName contains the name of a database (either "main" or -** "temp" or the name of an attached db). This routine returns the -** index of the named database in db->aDb[], or -1 if the named db -** does not exist. -*/ -SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ - int i; /* Database number */ - char *zName; /* Name we are searching for */ - zName = sqlite3NameFromToken(db, pName); - i = sqlite3FindDbName(db, zName); - sqlite3DbFree(db, zName); - return i; -} - -/* The table or view or trigger name is passed to this routine via tokens -** pName1 and pName2. If the table name was fully qualified, for example: -** -** CREATE TABLE xxx.yyy (...); -** -** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if -** the table name is not fully qualified, i.e.: -** -** CREATE TABLE yyy(...); -** -** Then pName1 is set to "yyy" and pName2 is "". -** -** This routine sets the *ppUnqual pointer to point at the token (pName1 or -** pName2) that stores the unqualified table name. The index of the -** database "xxx" is returned. -*/ -SQLITE_PRIVATE int sqlite3TwoPartName( - Parse *pParse, /* Parsing and code generating context */ - Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ - Token *pName2, /* The "yyy" in the name "xxx.yyy" */ - Token **pUnqual /* Write the unqualified object name here */ -){ - int iDb; /* Database holding the object */ - sqlite3 *db = pParse->db; - - assert( pName2!=0 ); - if( pName2->n>0 ){ - if( db->init.busy ) { - sqlite3ErrorMsg(pParse, "corrupt database"); - return -1; - } - *pUnqual = pName2; - iDb = sqlite3FindDb(db, pName1); - if( iDb<0 ){ - sqlite3ErrorMsg(pParse, "unknown database %T", pName1); - return -1; - } - }else{ - assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0); - iDb = db->init.iDb; - *pUnqual = pName1; - } - return iDb; -} - -/* -** This routine is used to check if the UTF-8 string zName is a legal -** unqualified name for a new schema object (table, index, view or -** trigger). All names are legal except those that begin with the string -** "sqlite_" (in upper, lower or mixed case). This portion of the namespace -** is reserved for internal use. -*/ -SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && pParse->nested==0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); - return SQLITE_ERROR; - } - return SQLITE_OK; -} - -/* -** Return the PRIMARY KEY index of a table -*/ -SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ - Index *p; - for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} - return p; -} - -/* -** Return the column of index pIdx that corresponds to table -** column iCol. Return -1 if not found. -*/ -SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){ - int i; - for(i=0; inColumn; i++){ - if( iCol==pIdx->aiColumn[i] ) return i; - } - return -1; -} - -/* -** Begin constructing a new table representation in memory. This is -** the first of several action routines that get called in response -** to a CREATE TABLE statement. In particular, this routine is called -** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp -** flag is true if the table should be stored in the auxiliary database -** file instead of in the main database file. This is normally the case -** when the "TEMP" or "TEMPORARY" keyword occurs in between -** CREATE and TABLE. -** -** The new table record is initialized and put in pParse->pNewTable. -** As more of the CREATE TABLE statement is parsed, additional action -** routines will be called to add more information to this record. -** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine -** is called to complete the construction of the new table record. -*/ -SQLITE_PRIVATE void sqlite3StartTable( - Parse *pParse, /* Parser context */ - Token *pName1, /* First part of the name of the table or view */ - Token *pName2, /* Second part of the name of the table or view */ - int isTemp, /* True if this is a TEMP table */ - int isView, /* True if this is a VIEW */ - int isVirtual, /* True if this is a VIRTUAL table */ - int noErr /* Do nothing if table already exists */ -){ - Table *pTable; - char *zName = 0; /* The name of the new table */ - sqlite3 *db = pParse->db; - Vdbe *v; - int iDb; /* Database number to create the table in */ - Token *pName; /* Unqualified name of the table to create */ - - if( db->init.busy && db->init.newTnum==1 ){ - /* Special case: Parsing the sqlite_master or sqlite_temp_master schema */ - iDb = db->init.iDb; - zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); - pName = pName1; - }else{ - /* The common case */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ) return; - if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ - /* If creating a temp table, the name may not be qualified. Unless - ** the database name is "temp" anyway. */ - sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - return; - } - if( !OMIT_TEMPDB && isTemp ) iDb = 1; - zName = sqlite3NameFromToken(db, pName); - } - pParse->sNameToken = *pName; - if( zName==0 ) return; - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto begin_table_error; - } - if( db->init.iDb==1 ) isTemp = 1; -#ifndef SQLITE_OMIT_AUTHORIZATION - assert( isTemp==0 || isTemp==1 ); - assert( isView==0 || isView==1 ); - { - static const u8 aCode[] = { - SQLITE_CREATE_TABLE, - SQLITE_CREATE_TEMP_TABLE, - SQLITE_CREATE_VIEW, - SQLITE_CREATE_TEMP_VIEW - }; - char *zDb = db->aDb[iDb].zDbSName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - goto begin_table_error; - } - if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], - zName, 0, zDb) ){ - goto begin_table_error; - } - } -#endif - - /* Make sure the new table name does not collide with an existing - ** index or table name in the same database. Issue an error message if - ** it does. The exception is if the statement being parsed was passed - ** to an sqlite3_declare_vtab() call. In that case only the column names - ** and types will be used, so there is no need to test for namespace - ** collisions. - */ - if( !IN_DECLARE_VTAB ){ - char *zDb = db->aDb[iDb].zDbSName; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto begin_table_error; - } - pTable = sqlite3FindTable(db, zName, zDb); - if( pTable ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "table %T already exists", pName); - }else{ - assert( !db->init.busy || CORRUPT_DB ); - sqlite3CodeVerifySchema(pParse, iDb); - } - goto begin_table_error; - } - if( sqlite3FindIndex(db, zName, zDb)!=0 ){ - sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - goto begin_table_error; - } - } - - pTable = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTable==0 ){ - assert( db->mallocFailed ); - pParse->rc = SQLITE_NOMEM_BKPT; - pParse->nErr++; - goto begin_table_error; - } - pTable->zName = zName; - pTable->iPKey = -1; - pTable->pSchema = db->aDb[iDb].pSchema; - pTable->nRef = 1; - pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - assert( pParse->pNewTable==0 ); - pParse->pNewTable = pTable; - - /* If this is the magic sqlite_sequence table used by autoincrement, - ** then record a pointer to this table in the main database structure - ** so that INSERT can find the table easily. - */ -#ifndef SQLITE_OMIT_AUTOINCREMENT - if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pTable->pSchema->pSeqTab = pTable; - } -#endif - - /* Begin generating the code that will insert the table record into - ** the SQLITE_MASTER table. Note in particular that we must go ahead - ** and allocate the record number for the table entry now. Before any - ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause - ** indices to be created and the table record must come before the - ** indices. Hence, the record number for the table must be allocated - ** now. - */ - if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ - int addr1; - int fileFormat; - int reg1, reg2, reg3; - /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */ - static const char nullRow[] = { 6, 0, 0, 0, 0, 0 }; - sqlite3BeginWriteOperation(pParse, 1, iDb); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( isVirtual ){ - sqlite3VdbeAddOp0(v, OP_VBegin); - } -#endif - - /* If the file format and encoding in the database have not been set, - ** set them now. - */ - reg1 = pParse->regRowid = ++pParse->nMem; - reg2 = pParse->regRoot = ++pParse->nMem; - reg3 = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); - sqlite3VdbeUsesBtree(v, iDb); - addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); - fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? - 1 : SQLITE_MAX_FILE_FORMAT; - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); - sqlite3VdbeJumpHere(v, addr1); - - /* This just creates a place-holder record in the sqlite_master table. - ** The record created does not contain anything yet. It will be replaced - ** by the real entry in code generated at sqlite3EndTable(). - ** - ** The rowid for the new entry is left in register pParse->regRowid. - ** The root page number of the new table is left in reg pParse->regRoot. - ** The rowid and root page number values are needed by the code that - ** sqlite3EndTable will generate. - */ -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) - if( isView || isVirtual ){ - sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); - }else -#endif - { - pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); - } - sqlite3OpenMasterTable(pParse, iDb); - sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); - sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); - sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3VdbeAddOp0(v, OP_Close); - } - - /* Normal (non-error) return. */ - return; - - /* If an error occurs, we jump here */ -begin_table_error: - sqlite3DbFree(db, zName); - return; -} - -/* Set properties of a table column based on the (magical) -** name of the column. -*/ -#if SQLITE_ENABLE_HIDDEN_COLUMNS -SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ - if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ - pCol->colFlags |= COLFLAG_HIDDEN; - }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ - pTab->tabFlags |= TF_OOOHidden; - } -} -#endif - - -/* -** Add a new column to the table currently being constructed. -** -** The parser calls this routine once for each column declaration -** in a CREATE TABLE statement. sqlite3StartTable() gets called -** first to get things going. Then this routine is called for each -** column. -*/ -SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ - Table *p; - int i; - char *z; - char *zType; - Column *pCol; - sqlite3 *db = pParse->db; - if( (p = pParse->pNewTable)==0 ) return; -#if SQLITE_MAX_COLUMN - if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); - return; - } -#endif - z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); - if( z==0 ) return; - memcpy(z, pName->z, pName->n); - z[pName->n] = 0; - sqlite3Dequote(z); - for(i=0; inCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ - sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); - sqlite3DbFree(db, z); - return; - } - } - if( (p->nCol & 0x7)==0 ){ - Column *aNew; - aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); - if( aNew==0 ){ - sqlite3DbFree(db, z); - return; - } - p->aCol = aNew; - } - pCol = &p->aCol[p->nCol]; - memset(pCol, 0, sizeof(p->aCol[0])); - pCol->zName = z; - sqlite3ColumnPropertiesFromName(p, pCol); - - if( pType->n==0 ){ - /* If there is no type specified, columns have the default affinity - ** 'BLOB'. */ - pCol->affinity = SQLITE_AFF_BLOB; - pCol->szEst = 1; - }else{ - zType = z + sqlite3Strlen30(z) + 1; - memcpy(zType, pType->z, pType->n); - zType[pType->n] = 0; - sqlite3Dequote(zType); - pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst); - pCol->colFlags |= COLFLAG_HASTYPE; - } - p->nCol++; - pParse->constraintName.n = 0; -} - -/* -** This routine is called by the parser while in the middle of -** parsing a CREATE TABLE statement. A "NOT NULL" constraint has -** been seen on a column. This routine sets the notNull flag on -** the column currently under construction. -*/ -SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ - Table *p; - p = pParse->pNewTable; - if( p==0 || NEVER(p->nCol<1) ) return; - p->aCol[p->nCol-1].notNull = (u8)onError; -} - -/* -** Scan the column type name zType (length nType) and return the -** associated affinity type. -** -** This routine does a case-independent search of zType for the -** substrings in the following table. If one of the substrings is -** found, the corresponding affinity is returned. If zType contains -** more than one of the substrings, entries toward the top of -** the table take priority. For example, if zType is 'BLOBINT', -** SQLITE_AFF_INTEGER is returned. -** -** Substring | Affinity -** -------------------------------- -** 'INT' | SQLITE_AFF_INTEGER -** 'CHAR' | SQLITE_AFF_TEXT -** 'CLOB' | SQLITE_AFF_TEXT -** 'TEXT' | SQLITE_AFF_TEXT -** 'BLOB' | SQLITE_AFF_BLOB -** 'REAL' | SQLITE_AFF_REAL -** 'FLOA' | SQLITE_AFF_REAL -** 'DOUB' | SQLITE_AFF_REAL -** -** If none of the substrings in the above table are found, -** SQLITE_AFF_NUMERIC is returned. -*/ -SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){ - u32 h = 0; - char aff = SQLITE_AFF_NUMERIC; - const char *zChar = 0; - - assert( zIn!=0 ); - while( zIn[0] ){ - h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; - zIn++; - if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ - aff = SQLITE_AFF_TEXT; - zChar = zIn; - }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ - aff = SQLITE_AFF_TEXT; - }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ - aff = SQLITE_AFF_TEXT; - }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ - && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ - aff = SQLITE_AFF_BLOB; - if( zIn[0]=='(' ) zChar = zIn; -#ifndef SQLITE_OMIT_FLOATING_POINT - }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; - }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; - }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ - && aff==SQLITE_AFF_NUMERIC ){ - aff = SQLITE_AFF_REAL; -#endif - }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ - aff = SQLITE_AFF_INTEGER; - break; - } - } - - /* If pszEst is not NULL, store an estimate of the field size. The - ** estimate is scaled so that the size of an integer is 1. */ - if( pszEst ){ - *pszEst = 1; /* default size is approx 4 bytes */ - if( aff255 ) v = 255; - *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */ - break; - } - zChar++; - } - }else{ - *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ - } - } - } - return aff; -} - -/* -** The expression is the default value for the most recently added column -** of the table currently under construction. -** -** Default value expressions must be constant. Raise an exception if this -** is not the case. -** -** This routine is called by the parser while in the middle of -** parsing a CREATE TABLE statement. -*/ -SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){ - Table *p; - Column *pCol; - sqlite3 *db = pParse->db; - p = pParse->pNewTable; - if( p!=0 ){ - pCol = &(p->aCol[p->nCol-1]); - if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){ - sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", - pCol->zName); - }else{ - /* A copy of pExpr is used instead of the original, as pExpr contains - ** tokens that point to volatile memory. The 'span' of the expression - ** is required by pragma table_info. - */ - Expr x; - sqlite3ExprDelete(db, pCol->pDflt); - memset(&x, 0, sizeof(x)); - x.op = TK_SPAN; - x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart, - (int)(pSpan->zEnd - pSpan->zStart)); - x.pLeft = pSpan->pExpr; - x.flags = EP_Skip; - pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); - sqlite3DbFree(db, x.u.zToken); - } - } - sqlite3ExprDelete(db, pSpan->pExpr); -} - -/* -** Backwards Compatibility Hack: -** -** Historical versions of SQLite accepted strings as column names in -** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: -** -** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim) -** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC); -** -** This is goofy. But to preserve backwards compatibility we continue to -** accept it. This routine does the necessary conversion. It converts -** the expression given in its argument from a TK_STRING into a TK_ID -** if the expression is just a TK_STRING with an optional COLLATE clause. -** If the epxression is anything other than TK_STRING, the expression is -** unchanged. -*/ -static void sqlite3StringToId(Expr *p){ - if( p->op==TK_STRING ){ - p->op = TK_ID; - }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ - p->pLeft->op = TK_ID; - } -} - -/* -** Designate the PRIMARY KEY for the table. pList is a list of names -** of columns that form the primary key. If pList is NULL, then the -** most recently added column of the table is the primary key. -** -** A table can have at most one primary key. If the table already has -** a primary key (and this is the second primary key) then create an -** error. -** -** If the PRIMARY KEY is on a single column whose datatype is INTEGER, -** then we will try to use that column as the rowid. Set the Table.iPKey -** field of the table under construction to be the index of the -** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is -** no INTEGER PRIMARY KEY. -** -** If the key is not an INTEGER PRIMARY KEY, then create a unique -** index for the key. No index is created for INTEGER PRIMARY KEYs. -*/ -SQLITE_PRIVATE void sqlite3AddPrimaryKey( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* List of field names to be indexed */ - int onError, /* What to do with a uniqueness conflict */ - int autoInc, /* True if the AUTOINCREMENT keyword is present */ - int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ -){ - Table *pTab = pParse->pNewTable; - Column *pCol = 0; - int iCol = -1, i; - int nTerm; - if( pTab==0 ) goto primary_key_exit; - if( pTab->tabFlags & TF_HasPrimaryKey ){ - sqlite3ErrorMsg(pParse, - "table \"%s\" has more than one primary key", pTab->zName); - goto primary_key_exit; - } - pTab->tabFlags |= TF_HasPrimaryKey; - if( pList==0 ){ - iCol = pTab->nCol - 1; - pCol = &pTab->aCol[iCol]; - pCol->colFlags |= COLFLAG_PRIMKEY; - nTerm = 1; - }else{ - nTerm = pList->nExpr; - for(i=0; ia[i].pExpr); - assert( pCExpr!=0 ); - sqlite3StringToId(pCExpr); - if( pCExpr->op==TK_ID ){ - const char *zCName = pCExpr->u.zToken; - for(iCol=0; iColnCol; iCol++){ - if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ - pCol = &pTab->aCol[iCol]; - pCol->colFlags |= COLFLAG_PRIMKEY; - break; - } - } - } - } - } - if( nTerm==1 - && pCol - && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 - && sortOrder!=SQLITE_SO_DESC - ){ - pTab->iPKey = iCol; - pTab->keyConf = (u8)onError; - assert( autoInc==0 || autoInc==1 ); - pTab->tabFlags |= autoInc*TF_Autoincrement; - if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; - }else if( autoInc ){ -#ifndef SQLITE_OMIT_AUTOINCREMENT - sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " - "INTEGER PRIMARY KEY"); -#endif - }else{ - sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, - 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY); - pList = 0; - } - -primary_key_exit: - sqlite3ExprListDelete(pParse->db, pList); - return; -} - -/* -** Add a new CHECK constraint to the table currently under construction. -*/ -SQLITE_PRIVATE void sqlite3AddCheckConstraint( - Parse *pParse, /* Parsing context */ - Expr *pCheckExpr /* The check expression */ -){ -#ifndef SQLITE_OMIT_CHECK - Table *pTab = pParse->pNewTable; - sqlite3 *db = pParse->db; - if( pTab && !IN_DECLARE_VTAB - && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) - ){ - pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); - if( pParse->constraintName.n ){ - sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); - } - }else -#endif - { - sqlite3ExprDelete(pParse->db, pCheckExpr); - } -} - -/* -** Set the collation function of the most recently parsed table column -** to the CollSeq given. -*/ -SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ - Table *p; - int i; - char *zColl; /* Dequoted name of collation sequence */ - sqlite3 *db; - - if( (p = pParse->pNewTable)==0 ) return; - i = p->nCol-1; - db = pParse->db; - zColl = sqlite3NameFromToken(db, pToken); - if( !zColl ) return; - - if( sqlite3LocateCollSeq(pParse, zColl) ){ - Index *pIdx; - sqlite3DbFree(db, p->aCol[i].zColl); - p->aCol[i].zColl = zColl; - - /* If the column is declared as " PRIMARY KEY COLLATE ", - ** then an index may have been created on this column before the - ** collation type was added. Correct this if it is the case. - */ - for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ - assert( pIdx->nKeyCol==1 ); - if( pIdx->aiColumn[0]==i ){ - pIdx->azColl[0] = p->aCol[i].zColl; - } - } - }else{ - sqlite3DbFree(db, zColl); - } -} - -/* -** This function returns the collation sequence for database native text -** encoding identified by the string zName, length nName. -** -** If the requested collation sequence is not available, or not available -** in the database native encoding, the collation factory is invoked to -** request it. If the collation factory does not supply such a sequence, -** and the sequence is available in another text encoding, then that is -** returned instead. -** -** If no versions of the requested collations sequence are available, or -** another error occurs, NULL is returned and an error message written into -** pParse. -** -** This routine is a wrapper around sqlite3FindCollSeq(). This routine -** invokes the collation factory if the named collation cannot be found -** and generates an error message. -** -** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() -*/ -SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ - sqlite3 *db = pParse->db; - u8 enc = ENC(db); - u8 initbusy = db->init.busy; - CollSeq *pColl; - - pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); - if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); - } - - return pColl; -} - - -/* -** Generate code that will increment the schema cookie. -** -** The schema cookie is used to determine when the schema for the -** database changes. After each schema change, the cookie value -** changes. When a process first reads the schema it records the -** cookie. Thereafter, whenever it goes to access the database, -** it checks the cookie to make sure the schema has not changed -** since it was last read. -** -** This plan is not completely bullet-proof. It is possible for -** the schema to change multiple times and for the cookie to be -** set back to prior value. But schema changes are infrequent -** and the probability of hitting the same cookie value is only -** 1 chance in 2^32. So we're safe enough. -** -** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments -** the schema-version whenever the schema changes. -*/ -SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ - sqlite3 *db = pParse->db; - Vdbe *v = pParse->pVdbe; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, - db->aDb[iDb].pSchema->schema_cookie+1); -} - -/* -** Measure the number of characters needed to output the given -** identifier. The number returned includes any quotes used -** but does not include the null terminator. -** -** The estimate is conservative. It might be larger that what is -** really needed. -*/ -static int identLength(const char *z){ - int n; - for(n=0; *z; n++, z++){ - if( *z=='"' ){ n++; } - } - return n + 2; -} - -/* -** The first parameter is a pointer to an output buffer. The second -** parameter is a pointer to an integer that contains the offset at -** which to write into the output buffer. This function copies the -** nul-terminated string pointed to by the third parameter, zSignedIdent, -** to the specified offset in the buffer and updates *pIdx to refer -** to the first byte after the last byte written before returning. -** -** If the string zSignedIdent consists entirely of alpha-numeric -** characters, does not begin with a digit and is not an SQL keyword, -** then it is copied to the output buffer exactly as it is. Otherwise, -** it is quoted using double-quotes. -*/ -static void identPut(char *z, int *pIdx, char *zSignedIdent){ - unsigned char *zIdent = (unsigned char*)zSignedIdent; - int i, j, needQuote; - i = *pIdx; - - for(j=0; zIdent[j]; j++){ - if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; - } - needQuote = sqlite3Isdigit(zIdent[0]) - || sqlite3KeywordCode(zIdent, j)!=TK_ID - || zIdent[j]!=0 - || j==0; - - if( needQuote ) z[i++] = '"'; - for(j=0; zIdent[j]; j++){ - z[i++] = zIdent[j]; - if( zIdent[j]=='"' ) z[i++] = '"'; - } - if( needQuote ) z[i++] = '"'; - z[i] = 0; - *pIdx = i; -} - -/* -** Generate a CREATE TABLE statement appropriate for the given -** table. Memory to hold the text of the statement is obtained -** from sqliteMalloc() and must be freed by the calling function. -*/ -static char *createTableStmt(sqlite3 *db, Table *p){ - int i, k, n; - char *zStmt; - char *zSep, *zSep2, *zEnd; - Column *pCol; - n = 0; - for(pCol = p->aCol, i=0; inCol; i++, pCol++){ - n += identLength(pCol->zName) + 5; - } - n += identLength(p->zName); - if( n<50 ){ - zSep = ""; - zSep2 = ","; - zEnd = ")"; - }else{ - zSep = "\n "; - zSep2 = ",\n "; - zEnd = "\n)"; - } - n += 35 + 6*p->nCol; - zStmt = sqlite3DbMallocRaw(0, n); - if( zStmt==0 ){ - sqlite3OomFault(db); - return 0; - } - sqlite3_snprintf(n, zStmt, "CREATE TABLE "); - k = sqlite3Strlen30(zStmt); - identPut(zStmt, &k, p->zName); - zStmt[k++] = '('; - for(pCol=p->aCol, i=0; inCol; i++, pCol++){ - static const char * const azType[] = { - /* SQLITE_AFF_BLOB */ "", - /* SQLITE_AFF_TEXT */ " TEXT", - /* SQLITE_AFF_NUMERIC */ " NUM", - /* SQLITE_AFF_INTEGER */ " INT", - /* SQLITE_AFF_REAL */ " REAL" - }; - int len; - const char *zType; - - sqlite3_snprintf(n-k, &zStmt[k], zSep); - k += sqlite3Strlen30(&zStmt[k]); - zSep = zSep2; - identPut(zStmt, &k, pCol->zName); - assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 ); - assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); - testcase( pCol->affinity==SQLITE_AFF_BLOB ); - testcase( pCol->affinity==SQLITE_AFF_TEXT ); - testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); - testcase( pCol->affinity==SQLITE_AFF_INTEGER ); - testcase( pCol->affinity==SQLITE_AFF_REAL ); - - zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; - len = sqlite3Strlen30(zType); - assert( pCol->affinity==SQLITE_AFF_BLOB - || pCol->affinity==sqlite3AffinityType(zType, 0) ); - memcpy(&zStmt[k], zType, len); - k += len; - assert( k<=n ); - } - sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); - return zStmt; -} - -/* -** Resize an Index object to hold N columns total. Return SQLITE_OK -** on success and SQLITE_NOMEM on an OOM error. -*/ -static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ - char *zExtra; - int nByte; - if( pIdx->nColumn>=N ) return SQLITE_OK; - assert( pIdx->isResized==0 ); - nByte = (sizeof(char*) + sizeof(i16) + 1)*N; - zExtra = sqlite3DbMallocZero(db, nByte); - if( zExtra==0 ) return SQLITE_NOMEM_BKPT; - memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); - pIdx->azColl = (const char**)zExtra; - zExtra += sizeof(char*)*N; - memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); - pIdx->aiColumn = (i16*)zExtra; - zExtra += sizeof(i16)*N; - memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); - pIdx->aSortOrder = (u8*)zExtra; - pIdx->nColumn = N; - pIdx->isResized = 1; - return SQLITE_OK; -} - -/* -** Estimate the total row width for a table. -*/ -static void estimateTableWidth(Table *pTab){ - unsigned wTable = 0; - const Column *pTabCol; - int i; - for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ - wTable += pTabCol->szEst; - } - if( pTab->iPKey<0 ) wTable++; - pTab->szTabRow = sqlite3LogEst(wTable*4); -} - -/* -** Estimate the average size of a row for an index. -*/ -static void estimateIndexWidth(Index *pIdx){ - unsigned wIndex = 0; - int i; - const Column *aCol = pIdx->pTable->aCol; - for(i=0; inColumn; i++){ - i16 x = pIdx->aiColumn[i]; - assert( xpTable->nCol ); - wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; - } - pIdx->szIdxRow = sqlite3LogEst(wIndex*4); -} - -/* Return true if value x is found any of the first nCol entries of aiCol[] -*/ -static int hasColumn(const i16 *aiCol, int nCol, int x){ - while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1; - return 0; -} - -/* -** This routine runs at the end of parsing a CREATE TABLE statement that -** has a WITHOUT ROWID clause. The job of this routine is to convert both -** internal schema data structures and the generated VDBE code so that they -** are appropriate for a WITHOUT ROWID table instead of a rowid table. -** Changes include: -** -** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. -** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is -** no rowid btree for a WITHOUT ROWID. Instead, the canonical -** data storage is a covering index btree. -** (3) Bypass the creation of the sqlite_master table entry -** for the PRIMARY KEY as the primary key index is now -** identified by the sqlite_master table entry of the table itself. -** (4) Set the Index.tnum of the PRIMARY KEY Index object in the -** schema to the rootpage from the main table. -** (5) Add all table columns to the PRIMARY KEY Index object -** so that the PRIMARY KEY is a covering index. The surplus -** columns are part of KeyInfo.nXField and are not used for -** sorting or lookup or uniqueness checks. -** (6) Replace the rowid tail on all automatically generated UNIQUE -** indices with the PRIMARY KEY columns. -** -** For virtual tables, only (1) is performed. -*/ -static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ - Index *pIdx; - Index *pPk; - int nPk; - int i, j; - sqlite3 *db = pParse->db; - Vdbe *v = pParse->pVdbe; - - /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) - */ - if( !db->init.imposterTable ){ - for(i=0; inCol; i++){ - if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){ - pTab->aCol[i].notNull = OE_Abort; - } - } - } - - /* The remaining transformations only apply to b-tree tables, not to - ** virtual tables */ - if( IN_DECLARE_VTAB ) return; - - /* Convert the OP_CreateTable opcode that would normally create the - ** root-page for the table into an OP_CreateIndex opcode. The index - ** created will become the PRIMARY KEY index. - */ - if( pParse->addrCrTab ){ - assert( v ); - sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex); - } - - /* Locate the PRIMARY KEY index. Or, if this table was originally - ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. - */ - if( pTab->iPKey>=0 ){ - ExprList *pList; - Token ipkToken; - sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); - pList = sqlite3ExprListAppend(pParse, 0, - sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); - if( pList==0 ) return; - pList->a[0].sortOrder = pParse->iPkSortOrder; - assert( pParse->pNewTable==pTab ); - sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, - SQLITE_IDXTYPE_PRIMARYKEY); - if( db->mallocFailed ) return; - pPk = sqlite3PrimaryKeyIndex(pTab); - pTab->iPKey = -1; - }else{ - pPk = sqlite3PrimaryKeyIndex(pTab); - - /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master - ** table entry. This is only required if currently generating VDBE - ** code for a CREATE TABLE (not when parsing one as part of reading - ** a database schema). */ - if( v ){ - assert( db->init.busy==0 ); - sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto); - } - - /* - ** Remove all redundant columns from the PRIMARY KEY. For example, change - ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later - ** code assumes the PRIMARY KEY contains no repeated columns. - */ - for(i=j=1; inKeyCol; i++){ - if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){ - pPk->nColumn--; - }else{ - pPk->aiColumn[j++] = pPk->aiColumn[i]; - } - } - pPk->nKeyCol = j; - } - assert( pPk!=0 ); - pPk->isCovering = 1; - if( !db->init.imposterTable ) pPk->uniqNotNull = 1; - nPk = pPk->nKeyCol; - - /* The root page of the PRIMARY KEY is the table root page */ - pPk->tnum = pTab->tnum; - - /* Update the in-memory representation of all UNIQUE indices by converting - ** the final rowid column into one or more columns of the PRIMARY KEY. - */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int n; - if( IsPrimaryKeyIndex(pIdx) ) continue; - for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++; - } - if( n==0 ){ - /* This index is a superset of the primary key */ - pIdx->nColumn = pIdx->nKeyCol; - continue; - } - if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; - for(i=0, j=pIdx->nKeyCol; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){ - pIdx->aiColumn[j] = pPk->aiColumn[i]; - pIdx->azColl[j] = pPk->azColl[i]; - j++; - } - } - assert( pIdx->nColumn>=pIdx->nKeyCol+n ); - assert( pIdx->nColumn>=j ); - } - - /* Add all table columns to the PRIMARY KEY index - */ - if( nPknCol ){ - if( resizeIndexObject(db, pPk, pTab->nCol) ) return; - for(i=0, j=nPk; inCol; i++){ - if( !hasColumn(pPk->aiColumn, j, i) ){ - assert( jnColumn ); - pPk->aiColumn[j] = i; - pPk->azColl[j] = sqlite3StrBINARY; - j++; - } - } - assert( pPk->nColumn==j ); - assert( pTab->nCol==j ); - }else{ - pPk->nColumn = pTab->nCol; - } -} - -/* -** This routine is called to report the final ")" that terminates -** a CREATE TABLE statement. -** -** The table structure that other action routines have been building -** is added to the internal hash tables, assuming no errors have -** occurred. -** -** An entry for the table is made in the master table on disk, unless -** this is a temporary table or db->init.busy==1. When db->init.busy==1 -** it means we are reading the sqlite_master table because we just -** connected to the database or because the sqlite_master table has -** recently changed, so the entry for this table already exists in -** the sqlite_master table. We do not want to create it again. -** -** If the pSelect argument is not NULL, it means that this routine -** was called to create a table generated from a -** "CREATE TABLE ... AS SELECT ..." statement. The column names of -** the new table will match the result set of the SELECT. -*/ -SQLITE_PRIVATE void sqlite3EndTable( - Parse *pParse, /* Parse context */ - Token *pCons, /* The ',' token after the last column defn. */ - Token *pEnd, /* The ')' before options in the CREATE TABLE */ - u8 tabOpts, /* Extra table options. Usually 0. */ - Select *pSelect /* Select from a "CREATE ... AS SELECT" */ -){ - Table *p; /* The new table */ - sqlite3 *db = pParse->db; /* The database connection */ - int iDb; /* Database in which the table lives */ - Index *pIdx; /* An implied index of the table */ - - if( pEnd==0 && pSelect==0 ){ - return; - } - assert( !db->mallocFailed ); - p = pParse->pNewTable; - if( p==0 ) return; - - assert( !db->init.busy || !pSelect ); - - /* If the db->init.busy is 1 it means we are reading the SQL off the - ** "sqlite_master" or "sqlite_temp_master" table on the disk. - ** So do not write to the disk again. Extract the root page number - ** for the table from the db->init.newTnum field. (The page number - ** should have been put there by the sqliteOpenCb routine.) - ** - ** If the root page number is 1, that means this is the sqlite_master - ** table itself. So mark it read-only. - */ - if( db->init.busy ){ - p->tnum = db->init.newTnum; - if( p->tnum==1 ) p->tabFlags |= TF_Readonly; - } - - /* Special processing for WITHOUT ROWID Tables */ - if( tabOpts & TF_WithoutRowid ){ - if( (p->tabFlags & TF_Autoincrement) ){ - sqlite3ErrorMsg(pParse, - "AUTOINCREMENT not allowed on WITHOUT ROWID tables"); - return; - } - if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ - sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); - }else{ - p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; - convertToWithoutRowidTable(pParse, p); - } - } - - iDb = sqlite3SchemaToIndex(db, p->pSchema); - -#ifndef SQLITE_OMIT_CHECK - /* Resolve names in all CHECK constraint expressions. - */ - if( p->pCheck ){ - sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); - } -#endif /* !defined(SQLITE_OMIT_CHECK) */ - - /* Estimate the average row size for the table and for all implied indices */ - estimateTableWidth(p); - for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ - estimateIndexWidth(pIdx); - } - - /* If not initializing, then create a record for the new table - ** in the SQLITE_MASTER table of the database. - ** - ** If this is a TEMPORARY table, write the entry into the auxiliary - ** file instead of into the main database file. - */ - if( !db->init.busy ){ - int n; - Vdbe *v; - char *zType; /* "view" or "table" */ - char *zType2; /* "VIEW" or "TABLE" */ - char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ - - v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return; - - sqlite3VdbeAddOp1(v, OP_Close, 0); - - /* - ** Initialize zType for the new view or table. - */ - if( p->pSelect==0 ){ - /* A regular table */ - zType = "table"; - zType2 = "TABLE"; -#ifndef SQLITE_OMIT_VIEW - }else{ - /* A view */ - zType = "view"; - zType2 = "VIEW"; -#endif - } - - /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT - ** statement to populate the new table. The root-page number for the - ** new table is in register pParse->regRoot. - ** - ** Once the SELECT has been coded by sqlite3Select(), it is in a - ** suitable state to query for the column names and types to be used - ** by the new table. - ** - ** A shared-cache write-lock is not required to write to the new table, - ** as a schema-lock must have already been obtained to create it. Since - ** a schema-lock excludes all other database users, the write-lock would - ** be redundant. - */ - if( pSelect ){ - SelectDest dest; /* Where the SELECT should store results */ - int regYield; /* Register holding co-routine entry-point */ - int addrTop; /* Top of the co-routine */ - int regRec; /* A record to be insert into the new table */ - int regRowid; /* Rowid of the next row to insert */ - int addrInsLoop; /* Top of the loop for inserting rows */ - Table *pSelTab; /* A table that describes the SELECT results */ - - regYield = ++pParse->nMem; - regRec = ++pParse->nMem; - regRowid = ++pParse->nMem; - assert(pParse->nTab==1); - sqlite3MayAbort(pParse); - sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); - sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); - pParse->nTab = 2; - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - sqlite3Select(pParse, pSelect, &dest); - sqlite3VdbeEndCoroutine(v, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); - if( pParse->nErr ) return; - pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); - if( pSelTab==0 ) return; - assert( p->aCol==0 ); - p->nCol = pSelTab->nCol; - p->aCol = pSelTab->aCol; - pSelTab->nCol = 0; - pSelTab->aCol = 0; - sqlite3DeleteTable(db, pSelTab); - addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); - sqlite3TableAffinity(v, p, 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); - sqlite3VdbeGoto(v, addrInsLoop); - sqlite3VdbeJumpHere(v, addrInsLoop); - sqlite3VdbeAddOp1(v, OP_Close, 1); - } - - /* Compute the complete text of the CREATE statement */ - if( pSelect ){ - zStmt = createTableStmt(db, p); - }else{ - Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; - n = (int)(pEnd2->z - pParse->sNameToken.z); - if( pEnd2->z[0]!=';' ) n += pEnd2->n; - zStmt = sqlite3MPrintf(db, - "CREATE %s %.*s", zType2, n, pParse->sNameToken.z - ); - } - - /* A slot for the record has already been allocated in the - ** SQLITE_MASTER table. We just need to update that slot with all - ** the information we've collected. - */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s " - "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " - "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), - zType, - p->zName, - p->zName, - pParse->regRoot, - zStmt, - pParse->regRowid - ); - sqlite3DbFree(db, zStmt); - sqlite3ChangeCookie(pParse, iDb); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* Check to see if we need to create an sqlite_sequence table for - ** keeping track of autoincrement keys. - */ - if( (p->tabFlags & TF_Autoincrement)!=0 ){ - Db *pDb = &db->aDb[iDb]; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( pDb->pSchema->pSeqTab==0 ){ - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.sqlite_sequence(name,seq)", - pDb->zDbSName - ); - } - } -#endif - - /* Reparse everything to update our internal data structures */ - sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); - } - - - /* Add the table to the in-memory representation of the database. - */ - if( db->init.busy ){ - Table *pOld; - Schema *pSchema = p->pSchema; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); - if( pOld ){ - assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ - sqlite3OomFault(db); - return; - } - pParse->pNewTable = 0; - db->flags |= SQLITE_InternChanges; - -#ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ - const char *zName = (const char *)pParse->sNameToken.z; - int nName; - assert( !pSelect && pCons && pEnd ); - if( pCons->z==0 ){ - pCons = pEnd; - } - nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); - } -#endif - } -} - -#ifndef SQLITE_OMIT_VIEW -/* -** The parser calls this routine in order to create a new VIEW -*/ -SQLITE_PRIVATE void sqlite3CreateView( - Parse *pParse, /* The parsing context */ - Token *pBegin, /* The CREATE token that begins the statement */ - Token *pName1, /* The token that holds the name of the view */ - Token *pName2, /* The token that holds the name of the view */ - ExprList *pCNames, /* Optional list of view column names */ - Select *pSelect, /* A SELECT statement that will become the new view */ - int isTemp, /* TRUE for a TEMPORARY view */ - int noErr /* Suppress error messages if VIEW already exists */ -){ - Table *p; - int n; - const char *z; - Token sEnd; - DbFixer sFix; - Token *pName = 0; - int iDb; - sqlite3 *db = pParse->db; - - if( pParse->nVar>0 ){ - sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); - goto create_view_fail; - } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); - p = pParse->pNewTable; - if( p==0 || pParse->nErr ) goto create_view_fail; - sqlite3TwoPartName(pParse, pName1, pName2, &pName); - iDb = sqlite3SchemaToIndex(db, p->pSchema); - sqlite3FixInit(&sFix, pParse, iDb, "view", pName); - if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; - - /* Make a copy of the entire SELECT statement that defines the view. - ** This will force all the Expr.token.z values to be dynamically - ** allocated rather than point to the input string - which means that - ** they will persist after the current sqlite3_exec() call returns. - */ - p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); - p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); - if( db->mallocFailed ) goto create_view_fail; - - /* Locate the end of the CREATE VIEW statement. Make sEnd point to - ** the end. - */ - sEnd = pParse->sLastToken; - assert( sEnd.z[0]!=0 ); - if( sEnd.z[0]!=';' ){ - sEnd.z += sEnd.n; - } - sEnd.n = 0; - n = (int)(sEnd.z - pBegin->z); - assert( n>0 ); - z = pBegin->z; - while( sqlite3Isspace(z[n-1]) ){ n--; } - sEnd.z = &z[n-1]; - sEnd.n = 1; - - /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ - sqlite3EndTable(pParse, 0, &sEnd, 0, 0); - -create_view_fail: - sqlite3SelectDelete(db, pSelect); - sqlite3ExprListDelete(db, pCNames); - return; -} -#endif /* SQLITE_OMIT_VIEW */ - -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -/* -** The Table structure pTable is really a VIEW. Fill in the names of -** the columns of the view in the pTable structure. Return the number -** of errors. If an error is seen leave an error message in pParse->zErrMsg. -*/ -SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - Table *pSelTab; /* A fake table from which we get the result set */ - Select *pSel; /* Copy of the SELECT that implements the view */ - int nErr = 0; /* Number of errors encountered */ - int n; /* Temporarily holds the number of cursors assigned */ - sqlite3 *db = pParse->db; /* Database connection for malloc errors */ -#ifndef SQLITE_OMIT_AUTHORIZATION - sqlite3_xauth xAuth; /* Saved xAuth pointer */ -#endif - - assert( pTable ); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3VtabCallConnect(pParse, pTable) ){ - return SQLITE_ERROR; - } - if( IsVirtual(pTable) ) return 0; -#endif - -#ifndef SQLITE_OMIT_VIEW - /* A positive nCol means the columns names for this view are - ** already known. - */ - if( pTable->nCol>0 ) return 0; - - /* A negative nCol is a special marker meaning that we are currently - ** trying to compute the column names. If we enter this routine with - ** a negative nCol, it means two or more views form a loop, like this: - ** - ** CREATE VIEW one AS SELECT * FROM two; - ** CREATE VIEW two AS SELECT * FROM one; - ** - ** Actually, the error above is now caught prior to reaching this point. - ** But the following test is still important as it does come up - ** in the following: - ** - ** CREATE TABLE main.ex1(a); - ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; - ** SELECT * FROM temp.ex1; - */ - if( pTable->nCol<0 ){ - sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); - return 1; - } - assert( pTable->nCol>=0 ); - - /* If we get this far, it means we need to compute the table names. - ** Note that the call to sqlite3ResultSetOfSelect() will expand any - ** "*" elements in the results set of the view and will assign cursors - ** to the elements of the FROM clause. But we do not want these changes - ** to be permanent. So the computation is done on a copy of the SELECT - ** statement that defines the view. - */ - assert( pTable->pSelect ); - pSel = sqlite3SelectDup(db, pTable->pSelect, 0); - if( pSel ){ - n = pParse->nTab; - sqlite3SrcListAssignCursors(pParse, pSel->pSrc); - pTable->nCol = -1; - db->lookaside.bDisable++; -#ifndef SQLITE_OMIT_AUTHORIZATION - xAuth = db->xAuth; - db->xAuth = 0; - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); - db->xAuth = xAuth; -#else - pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); -#endif - pParse->nTab = n; - if( pTable->pCheck ){ - /* CREATE VIEW name(arglist) AS ... - ** The names of the columns in the table are taken from - ** arglist which is stored in pTable->pCheck. The pCheck field - ** normally holds CHECK constraints on an ordinary table, but for - ** a VIEW it holds the list of column names. - */ - sqlite3ColumnsFromExprList(pParse, pTable->pCheck, - &pTable->nCol, &pTable->aCol); - if( db->mallocFailed==0 - && pParse->nErr==0 - && pTable->nCol==pSel->pEList->nExpr - ){ - sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel); - } - }else if( pSelTab ){ - /* CREATE VIEW name AS... without an argument list. Construct - ** the column names from the SELECT statement that defines the view. - */ - assert( pTable->aCol==0 ); - pTable->nCol = pSelTab->nCol; - pTable->aCol = pSelTab->aCol; - pSelTab->nCol = 0; - pSelTab->aCol = 0; - assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); - }else{ - pTable->nCol = 0; - nErr++; - } - sqlite3DeleteTable(db, pSelTab); - sqlite3SelectDelete(db, pSel); - db->lookaside.bDisable--; - } else { - nErr++; - } - pTable->pSchema->schemaFlags |= DB_UnresetViews; -#endif /* SQLITE_OMIT_VIEW */ - return nErr; -} -#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ - -#ifndef SQLITE_OMIT_VIEW -/* -** Clear the column names from every VIEW in database idx. -*/ -static void sqliteViewResetAll(sqlite3 *db, int idx){ - HashElem *i; - assert( sqlite3SchemaMutexHeld(db, idx, 0) ); - if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; - for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ - Table *pTab = sqliteHashData(i); - if( pTab->pSelect ){ - sqlite3DeleteColumnNames(db, pTab); - pTab->aCol = 0; - pTab->nCol = 0; - } - } - DbClearProperty(db, idx, DB_UnresetViews); -} -#else -# define sqliteViewResetAll(A,B) -#endif /* SQLITE_OMIT_VIEW */ - -/* -** This function is called by the VDBE to adjust the internal schema -** used by SQLite when the btree layer moves a table root page. The -** root-page of a table or index in database iDb has changed from iFrom -** to iTo. -** -** Ticket #1728: The symbol table might still contain information -** on tables and/or indices that are the process of being deleted. -** If you are unlucky, one of those deleted indices or tables might -** have the same rootpage number as the real table or index that is -** being moved. So we cannot stop searching after the first match -** because the first match might be for one of the deleted indices -** or tables and not the table/index that is actually being moved. -** We must continue looping until all tables and indices with -** rootpage==iFrom have been converted to have a rootpage of iTo -** in order to be certain that we got the right one. -*/ -#ifndef SQLITE_OMIT_AUTOVACUUM -SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ - HashElem *pElem; - Hash *pHash; - Db *pDb; - - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pDb = &db->aDb[iDb]; - pHash = &pDb->pSchema->tblHash; - for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ - Table *pTab = sqliteHashData(pElem); - if( pTab->tnum==iFrom ){ - pTab->tnum = iTo; - } - } - pHash = &pDb->pSchema->idxHash; - for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ - Index *pIdx = sqliteHashData(pElem); - if( pIdx->tnum==iFrom ){ - pIdx->tnum = iTo; - } - } -} -#endif - -/* -** Write code to erase the table with root-page iTable from database iDb. -** Also write code to modify the sqlite_master table and internal schema -** if a root-page of another table is moved by the btree-layer whilst -** erasing iTable (this can happen with an auto-vacuum database). -*/ -static void destroyRootPage(Parse *pParse, int iTable, int iDb){ - Vdbe *v = sqlite3GetVdbe(pParse); - int r1 = sqlite3GetTempReg(pParse); - assert( iTable>1 ); - sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); - sqlite3MayAbort(pParse); -#ifndef SQLITE_OMIT_AUTOVACUUM - /* OP_Destroy stores an in integer r1. If this integer - ** is non-zero, then it is the root page number of a table moved to - ** location iTable. The following code modifies the sqlite_master table to - ** reflect this. - ** - ** The "#NNN" in the SQL is a special constant that means whatever value - ** is in register NNN. See grammar rules associated with the TK_REGISTER - ** token for additional information. - */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", - pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1); -#endif - sqlite3ReleaseTempReg(pParse, r1); -} - -/* -** Write VDBE code to erase table pTab and all associated indices on disk. -** Code to update the sqlite_master tables and internal schema definitions -** in case a root-page belonging to another table is moved by the btree layer -** is also added (this can happen with an auto-vacuum database). -*/ -static void destroyTable(Parse *pParse, Table *pTab){ -#ifdef SQLITE_OMIT_AUTOVACUUM - Index *pIdx; - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - destroyRootPage(pParse, pTab->tnum, iDb); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - destroyRootPage(pParse, pIdx->tnum, iDb); - } -#else - /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM - ** is not defined), then it is important to call OP_Destroy on the - ** table and index root-pages in order, starting with the numerically - ** largest root-page number. This guarantees that none of the root-pages - ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the - ** following were coded: - ** - ** OP_Destroy 4 0 - ** ... - ** OP_Destroy 5 0 - ** - ** and root page 5 happened to be the largest root-page number in the - ** database, then root page 5 would be moved to page 4 by the - ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit - ** a free-list page. - */ - int iTab = pTab->tnum; - int iDestroyed = 0; - - while( 1 ){ - Index *pIdx; - int iLargest = 0; - - if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ - int iIdx = pIdx->tnum; - assert( pIdx->pSchema==pTab->pSchema ); - if( (iDestroyed==0 || (iIdxiLargest ){ - iLargest = iIdx; - } - } - if( iLargest==0 ){ - return; - }else{ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 && iDbdb->nDb ); - destroyRootPage(pParse, iLargest, iDb); - iDestroyed = iLargest; - } - } -#endif -} - -/* -** Remove entries from the sqlite_statN tables (for N in (1,2,3)) -** after a DROP INDEX or DROP TABLE command. -*/ -static void sqlite3ClearStatTables( - Parse *pParse, /* The parsing context */ - int iDb, /* The database number */ - const char *zType, /* "idx" or "tbl" */ - const char *zName /* Name of index or table */ -){ - int i; - const char *zDbName = pParse->db->aDb[iDb].zDbSName; - for(i=1; i<=4; i++){ - char zTab[24]; - sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); - if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE %s=%Q", - zDbName, zTab, zType, zName - ); - } - } -} - -/* -** Generate code to drop a table. -*/ -SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ - Vdbe *v; - sqlite3 *db = pParse->db; - Trigger *pTrigger; - Db *pDb = &db->aDb[iDb]; - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - sqlite3BeginWriteOperation(pParse, 1, iDb); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3VdbeAddOp0(v, OP_VBegin); - } -#endif - - /* Drop all triggers associated with the table being dropped. Code - ** is generated to remove entries from sqlite_master and/or - ** sqlite_temp_master if required. - */ - pTrigger = sqlite3TriggerList(pParse, pTab); - while( pTrigger ){ - assert( pTrigger->pSchema==pTab->pSchema || - pTrigger->pSchema==db->aDb[1].pSchema ); - sqlite3DropTriggerPtr(pParse, pTrigger); - pTrigger = pTrigger->pNext; - } - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* Remove any entries of the sqlite_sequence table associated with - ** the table being dropped. This is done before the table is dropped - ** at the btree level, in case the sqlite_sequence table needs to - ** move as a result of the drop (can happen in auto-vacuum mode). - */ - if( pTab->tabFlags & TF_Autoincrement ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", - pDb->zDbSName, pTab->zName - ); - } -#endif - - /* Drop all SQLITE_MASTER table and index entries that refer to the - ** table. The program name loops through the master table and deletes - ** every row that refers to a table of the same name as the one being - ** dropped. Triggers are handled separately because a trigger can be - ** created in the temp database that refers to a table in another - ** database. - */ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName); - if( !isView && !IsVirtual(pTab) ){ - destroyTable(pParse, pTab); - } - - /* Remove the table entry from SQLite's internal schema and modify - ** the schema cookie. - */ - if( IsVirtual(pTab) ){ - sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); - } - sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - sqlite3ChangeCookie(pParse, iDb); - sqliteViewResetAll(db, iDb); -} - -/* -** This routine is called to do the work of a DROP TABLE statement. -** pName is the name of the table to be dropped. -*/ -SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ - Table *pTab; - Vdbe *v; - sqlite3 *db = pParse->db; - int iDb; - - if( db->mallocFailed ){ - goto exit_drop_table; - } - assert( pParse->nErr==0 ); - assert( pName->nSrc==1 ); - if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; - if( noErr ) db->suppressErr++; - assert( isView==0 || isView==LOCATE_VIEW ); - pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); - if( noErr ) db->suppressErr--; - - if( pTab==0 ){ - if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); - goto exit_drop_table; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDbnDb ); - - /* If pTab is a virtual table, call ViewGetColumnNames() to ensure - ** it is initialized. - */ - if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto exit_drop_table; - } -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int code; - const char *zTab = SCHEMA_TABLE(iDb); - const char *zDb = db->aDb[iDb].zDbSName; - const char *zArg2 = 0; - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ - goto exit_drop_table; - } - if( isView ){ - if( !OMIT_TEMPDB && iDb==1 ){ - code = SQLITE_DROP_TEMP_VIEW; - }else{ - code = SQLITE_DROP_VIEW; - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( IsVirtual(pTab) ){ - code = SQLITE_DROP_VTABLE; - zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; -#endif - }else{ - if( !OMIT_TEMPDB && iDb==1 ){ - code = SQLITE_DROP_TEMP_TABLE; - }else{ - code = SQLITE_DROP_TABLE; - } - } - if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ - goto exit_drop_table; - } - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ - goto exit_drop_table; - } - } -#endif - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 - && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){ - sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); - goto exit_drop_table; - } - -#ifndef SQLITE_OMIT_VIEW - /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used - ** on a table. - */ - if( isView && pTab->pSelect==0 ){ - sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); - goto exit_drop_table; - } - if( !isView && pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); - goto exit_drop_table; - } -#endif - - /* Generate code to remove the table from the master table - ** on disk. - */ - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - sqlite3FkDropTable(pParse, pName, pTab); - sqlite3CodeDropTable(pParse, pTab, iDb, isView); - } - -exit_drop_table: - sqlite3SrcListDelete(db, pName); -} - -/* -** This routine is called to create a new foreign key on the table -** currently under construction. pFromCol determines which columns -** in the current table point to the foreign key. If pFromCol==0 then -** connect the key to the last column inserted. pTo is the name of -** the table referred to (a.k.a the "parent" table). pToCol is a list -** of tables in the parent pTo table. flags contains all -** information about the conflict resolution algorithms specified -** in the ON DELETE, ON UPDATE and ON INSERT clauses. -** -** An FKey structure is created and added to the table currently -** under construction in the pParse->pNewTable field. -** -** The foreign key is set for IMMEDIATE processing. A subsequent call -** to sqlite3DeferForeignKey() might change this to DEFERRED. -*/ -SQLITE_PRIVATE void sqlite3CreateForeignKey( - Parse *pParse, /* Parsing context */ - ExprList *pFromCol, /* Columns in this table that point to other table */ - Token *pTo, /* Name of the other table */ - ExprList *pToCol, /* Columns in the other table */ - int flags /* Conflict resolution algorithms. */ -){ - sqlite3 *db = pParse->db; -#ifndef SQLITE_OMIT_FOREIGN_KEY - FKey *pFKey = 0; - FKey *pNextTo; - Table *p = pParse->pNewTable; - int nByte; - int i; - int nCol; - char *z; - - assert( pTo!=0 ); - if( p==0 || IN_DECLARE_VTAB ) goto fk_end; - if( pFromCol==0 ){ - int iCol = p->nCol-1; - if( NEVER(iCol<0) ) goto fk_end; - if( pToCol && pToCol->nExpr!=1 ){ - sqlite3ErrorMsg(pParse, "foreign key on %s" - " should reference only one column of table %T", - p->aCol[iCol].zName, pTo); - goto fk_end; - } - nCol = 1; - }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ - sqlite3ErrorMsg(pParse, - "number of columns in foreign key does not match the number of " - "columns in the referenced table"); - goto fk_end; - }else{ - nCol = pFromCol->nExpr; - } - nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; - if( pToCol ){ - for(i=0; inExpr; i++){ - nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1; - } - } - pFKey = sqlite3DbMallocZero(db, nByte ); - if( pFKey==0 ){ - goto fk_end; - } - pFKey->pFrom = p; - pFKey->pNextFrom = p->pFKey; - z = (char*)&pFKey->aCol[nCol]; - pFKey->zTo = z; - memcpy(z, pTo->z, pTo->n); - z[pTo->n] = 0; - sqlite3Dequote(z); - z += pTo->n+1; - pFKey->nCol = nCol; - if( pFromCol==0 ){ - pFKey->aCol[0].iFrom = p->nCol-1; - }else{ - for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){ - pFKey->aCol[i].iFrom = j; - break; - } - } - if( j>=p->nCol ){ - sqlite3ErrorMsg(pParse, - "unknown column \"%s\" in foreign key definition", - pFromCol->a[i].zName); - goto fk_end; - } - } - } - if( pToCol ){ - for(i=0; ia[i].zName); - pFKey->aCol[i].zCol = z; - memcpy(z, pToCol->a[i].zName, n); - z[n] = 0; - z += n+1; - } - } - pFKey->isDeferred = 0; - pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ - pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ - - assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); - pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, - pFKey->zTo, (void *)pFKey - ); - if( pNextTo==pFKey ){ - sqlite3OomFault(db); - goto fk_end; - } - if( pNextTo ){ - assert( pNextTo->pPrevTo==0 ); - pFKey->pNextTo = pNextTo; - pNextTo->pPrevTo = pFKey; - } - - /* Link the foreign key to the table as the last step. - */ - p->pFKey = pFKey; - pFKey = 0; - -fk_end: - sqlite3DbFree(db, pFKey); -#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - sqlite3ExprListDelete(db, pFromCol); - sqlite3ExprListDelete(db, pToCol); -} - -/* -** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED -** clause is seen as part of a foreign key definition. The isDeferred -** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. -** The behavior of the most recently created foreign key is adjusted -** accordingly. -*/ -SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ -#ifndef SQLITE_OMIT_FOREIGN_KEY - Table *pTab; - FKey *pFKey; - if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; - assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ - pFKey->isDeferred = (u8)isDeferred; -#endif -} - -/* -** Generate code that will erase and refill index *pIdx. This is -** used to initialize a newly created index or to recompute the -** content of an index in response to a REINDEX command. -** -** if memRootPage is not negative, it means that the index is newly -** created. The register specified by memRootPage contains the -** root page number of the index. If memRootPage is negative, then -** the index already exists and must be cleared before being refilled and -** the root page number of the index is taken from pIndex->tnum. -*/ -static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ - Table *pTab = pIndex->pTable; /* The table that is indexed */ - int iTab = pParse->nTab++; /* Btree cursor used for pTab */ - int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ - int iSorter; /* Cursor opened by OpenSorter (if in use) */ - int addr1; /* Address of top of loop */ - int addr2; /* Address to jump to for next iteration */ - int tnum; /* Root page of index */ - int iPartIdxLabel; /* Jump to this label to skip a row */ - Vdbe *v; /* Generate code into this virtual machine */ - KeyInfo *pKey; /* KeyInfo for index */ - int regRecord; /* Register holding assembled index record */ - sqlite3 *db = pParse->db; /* The database connection */ - int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); - -#ifndef SQLITE_OMIT_AUTHORIZATION - if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, - db->aDb[iDb].zDbSName ) ){ - return; - } -#endif - - /* Require a write-lock on the table to perform this operation */ - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); - - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; - if( memRootPage>=0 ){ - tnum = memRootPage; - }else{ - tnum = pIndex->tnum; - } - pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); - assert( pKey!=0 || db->mallocFailed || pParse->nErr ); - - /* Open the sorter cursor if we are to use one. */ - iSorter = pParse->nTab++; - sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) - sqlite3KeyInfoRef(pKey), P4_KEYINFO); - - /* Open the table. Loop through all rows of the table, inserting index - ** records into the sorter. */ - sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); - regRecord = sqlite3GetTempReg(pParse); - - sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); - sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); - sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr1); - if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); - sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, - (char *)pKey, P4_KEYINFO); - sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); - - addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); - if( IsUniqueIndex(pIndex) ){ - int j2 = sqlite3VdbeCurrentAddr(v) + 3; - sqlite3VdbeGoto(v, j2); - addr2 = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, - pIndex->nKeyCol); VdbeCoverage(v); - sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); - }else{ - addr2 = sqlite3VdbeCurrentAddr(v); - } - sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); - sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1); - sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr1); - - sqlite3VdbeAddOp1(v, OP_Close, iTab); - sqlite3VdbeAddOp1(v, OP_Close, iIdx); - sqlite3VdbeAddOp1(v, OP_Close, iSorter); -} - -/* -** Allocate heap space to hold an Index object with nCol columns. -** -** Increase the allocation size to provide an extra nExtra bytes -** of 8-byte aligned space after the Index object and return a -** pointer to this extra space in *ppExtra. -*/ -SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( - sqlite3 *db, /* Database connection */ - i16 nCol, /* Total number of columns in the index */ - int nExtra, /* Number of bytes of extra space to alloc */ - char **ppExtra /* Pointer to the "extra" space */ -){ - Index *p; /* Allocated index object */ - int nByte; /* Bytes of space for Index object + arrays */ - - nByte = ROUND8(sizeof(Index)) + /* Index structure */ - ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ - ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ - sizeof(i16)*nCol + /* Index.aiColumn */ - sizeof(u8)*nCol); /* Index.aSortOrder */ - p = sqlite3DbMallocZero(db, nByte + nExtra); - if( p ){ - char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); - p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); - p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); - p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; - p->aSortOrder = (u8*)pExtra; - p->nColumn = nCol; - p->nKeyCol = nCol - 1; - *ppExtra = ((char*)p) + nByte; - } - return p; -} - -/* -** Create a new index for an SQL table. pName1.pName2 is the name of the index -** and pTblList is the name of the table that is to be indexed. Both will -** be NULL for a primary key or an index that is created to satisfy a -** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable -** as the table to be indexed. pParse->pNewTable is a table that is -** currently being constructed by a CREATE TABLE statement. -** -** pList is a list of columns to be indexed. pList will be NULL if this -** is a primary key or unique-constraint on the most recent column added -** to the table currently under construction. -*/ -SQLITE_PRIVATE void sqlite3CreateIndex( - Parse *pParse, /* All information about this parse */ - Token *pName1, /* First part of index name. May be NULL */ - Token *pName2, /* Second part of index name. May be NULL */ - SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ - ExprList *pList, /* A list of columns to be indexed */ - int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins this statement */ - Expr *pPIWhere, /* WHERE clause for partial indices */ - int sortOrder, /* Sort order of primary key when pList==NULL */ - int ifNotExist, /* Omit error if index already exists */ - u8 idxType /* The index type */ -){ - Table *pTab = 0; /* Table to be indexed */ - Index *pIndex = 0; /* The index to be created */ - char *zName = 0; /* Name of the index */ - int nName; /* Number of characters in zName */ - int i, j; - DbFixer sFix; /* For assigning database names to pTable */ - int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ - sqlite3 *db = pParse->db; - Db *pDb; /* The specific table containing the indexed database */ - int iDb; /* Index of the database that is being written */ - Token *pName = 0; /* Unqualified name of the index to create */ - struct ExprList_item *pListItem; /* For looping over pList */ - int nExtra = 0; /* Space allocated for zExtra[] */ - int nExtraCol; /* Number of extra columns needed */ - char *zExtra = 0; /* Extra space after the Index object */ - Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ - - if( db->mallocFailed || pParse->nErr>0 ){ - goto exit_create_index; - } - if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ - goto exit_create_index; - } - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto exit_create_index; - } - - /* - ** Find the table that is to be indexed. Return early if not found. - */ - if( pTblName!=0 ){ - - /* Use the two-part index name to determine the database - ** to search for the table. 'Fix' the table name to this db - ** before looking up the table. - */ - assert( pName1 && pName2 ); - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ) goto exit_create_index; - assert( pName && pName->z ); - -#ifndef SQLITE_OMIT_TEMPDB - /* If the index name was unqualified, check if the table - ** is a temp table. If so, set the database to 1. Do not do this - ** if initialising a database schema. - */ - if( !db->init.busy ){ - pTab = sqlite3SrcListLookup(pParse, pTblName); - if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ - iDb = 1; - } - } -#endif - - sqlite3FixInit(&sFix, pParse, iDb, "index", pName); - if( sqlite3FixSrcList(&sFix, pTblName) ){ - /* Because the parser constructs pTblName from a single identifier, - ** sqlite3FixSrcList can never fail. */ - assert(0); - } - pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); - assert( db->mallocFailed==0 || pTab==0 ); - if( pTab==0 ) goto exit_create_index; - if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ - sqlite3ErrorMsg(pParse, - "cannot create a TEMP index on non-TEMP table \"%s\"", - pTab->zName); - goto exit_create_index; - } - if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab); - }else{ - assert( pName==0 ); - assert( pStart==0 ); - pTab = pParse->pNewTable; - if( !pTab ) goto exit_create_index; - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - } - pDb = &db->aDb[iDb]; - - assert( pTab!=0 ); - assert( pParse->nErr==0 ); - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 - && db->init.busy==0 -#if SQLITE_USER_AUTHENTICATION - && sqlite3UserAuthTable(pTab->zName)==0 -#endif - && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){ - sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); - goto exit_create_index; - } -#ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ - sqlite3ErrorMsg(pParse, "views may not be indexed"); - goto exit_create_index; - } -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); - goto exit_create_index; - } -#endif - - /* - ** Find the name of the index. Make sure there is not already another - ** index or table with the same name. - ** - ** Exception: If we are reading the names of permanent indices from the - ** sqlite_master table (because some other process changed the schema) and - ** one of the index names collides with the name of a temporary table or - ** index, then we will continue to process this index. - ** - ** If pName==0 it means that we are - ** dealing with a primary key or UNIQUE constraint. We have to invent our - ** own name. - */ - if( pName ){ - zName = sqlite3NameFromToken(db, pName); - if( zName==0 ) goto exit_create_index; - assert( pName->z!=0 ); - if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto exit_create_index; - } - if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, 0)!=0 ){ - sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); - goto exit_create_index; - } - } - if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ - if( !ifNotExist ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); - } - goto exit_create_index; - } - }else{ - int n; - Index *pLoop; - for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} - zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); - if( zName==0 ){ - goto exit_create_index; - } - - /* Automatic index names generated from within sqlite3_declare_vtab() - ** must have names that are distinct from normal automatic index names. - ** The following statement converts "sqlite3_autoindex..." into - ** "sqlite3_butoindex..." in order to make the names distinct. - ** The "vtab_err.test" test demonstrates the need of this statement. */ - if( IN_DECLARE_VTAB ) zName[7]++; - } - - /* Check for authorization to create an index. - */ -#ifndef SQLITE_OMIT_AUTHORIZATION - { - const char *zDb = pDb->zDbSName; - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ - goto exit_create_index; - } - i = SQLITE_CREATE_INDEX; - if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; - if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ - goto exit_create_index; - } - } -#endif - - /* If pList==0, it means this routine was called to make a primary - ** key out of the last column added to the table under construction. - ** So create a fake list to simulate this. - */ - if( pList==0 ){ - Token prevCol; - sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName); - pList = sqlite3ExprListAppend(pParse, 0, - sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); - if( pList==0 ) goto exit_create_index; - assert( pList->nExpr==1 ); - sqlite3ExprListSetSortOrder(pList, sortOrder); - }else{ - sqlite3ExprListCheckLength(pParse, pList, "index"); - } - - /* Figure out how many bytes of space are required to store explicitly - ** specified collation sequence names. - */ - for(i=0; inExpr; i++){ - Expr *pExpr = pList->a[i].pExpr; - assert( pExpr!=0 ); - if( pExpr->op==TK_COLLATE ){ - nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); - } - } - - /* - ** Allocate the index structure. - */ - nName = sqlite3Strlen30(zName); - nExtraCol = pPk ? pPk->nKeyCol : 1; - pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, - nName + nExtra + 1, &zExtra); - if( db->mallocFailed ){ - goto exit_create_index; - } - assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); - assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); - pIndex->zName = zExtra; - zExtra += nName + 1; - memcpy(pIndex->zName, zName, nName+1); - pIndex->pTable = pTab; - pIndex->onError = (u8)onError; - pIndex->uniqNotNull = onError!=OE_None; - pIndex->idxType = idxType; - pIndex->pSchema = db->aDb[iDb].pSchema; - pIndex->nKeyCol = pList->nExpr; - if( pPIWhere ){ - sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); - pIndex->pPartIdxWhere = pPIWhere; - pPIWhere = 0; - } - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - - /* Check to see if we should honor DESC requests on index columns - */ - if( pDb->pSchema->file_format>=4 ){ - sortOrderMask = -1; /* Honor DESC */ - }else{ - sortOrderMask = 0; /* Ignore DESC */ - } - - /* Analyze the list of expressions that form the terms of the index and - ** report any errors. In the common case where the expression is exactly - ** a table column, store that column in aiColumn[]. For general expressions, - ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[]. - ** - ** TODO: Issue a warning if two or more columns of the index are identical. - ** TODO: Issue a warning if the table primary key is used as part of the - ** index key. - */ - for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ - Expr *pCExpr; /* The i-th index expression */ - int requestedSortOrder; /* ASC or DESC on the i-th expression */ - const char *zColl; /* Collation sequence name */ - - sqlite3StringToId(pListItem->pExpr); - sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); - if( pParse->nErr ) goto exit_create_index; - pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr); - if( pCExpr->op!=TK_COLUMN ){ - if( pTab==pParse->pNewTable ){ - sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and " - "UNIQUE constraints"); - goto exit_create_index; - } - if( pIndex->aColExpr==0 ){ - ExprList *pCopy = sqlite3ExprListDup(db, pList, 0); - pIndex->aColExpr = pCopy; - if( !db->mallocFailed ){ - assert( pCopy!=0 ); - pListItem = &pCopy->a[i]; - } - } - j = XN_EXPR; - pIndex->aiColumn[i] = XN_EXPR; - pIndex->uniqNotNull = 0; - }else{ - j = pCExpr->iColumn; - assert( j<=0x7fff ); - if( j<0 ){ - j = pTab->iPKey; - }else if( pTab->aCol[j].notNull==0 ){ - pIndex->uniqNotNull = 0; - } - pIndex->aiColumn[i] = (i16)j; - } - zColl = 0; - if( pListItem->pExpr->op==TK_COLLATE ){ - int nColl; - zColl = pListItem->pExpr->u.zToken; - nColl = sqlite3Strlen30(zColl) + 1; - assert( nExtra>=nColl ); - memcpy(zExtra, zColl, nColl); - zColl = zExtra; - zExtra += nColl; - nExtra -= nColl; - }else if( j>=0 ){ - zColl = pTab->aCol[j].zColl; - } - if( !zColl ) zColl = sqlite3StrBINARY; - if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ - goto exit_create_index; - } - pIndex->azColl[i] = zColl; - requestedSortOrder = pListItem->sortOrder & sortOrderMask; - pIndex->aSortOrder[i] = (u8)requestedSortOrder; - } - - /* Append the table key to the end of the index. For WITHOUT ROWID - ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For - ** normal tables (when pPk==0) this will be the rowid. - */ - if( pPk ){ - for(j=0; jnKeyCol; j++){ - int x = pPk->aiColumn[j]; - assert( x>=0 ); - if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){ - pIndex->nColumn--; - }else{ - pIndex->aiColumn[i] = x; - pIndex->azColl[i] = pPk->azColl[j]; - pIndex->aSortOrder[i] = pPk->aSortOrder[j]; - i++; - } - } - assert( i==pIndex->nColumn ); - }else{ - pIndex->aiColumn[i] = XN_ROWID; - pIndex->azColl[i] = sqlite3StrBINARY; - } - sqlite3DefaultRowEst(pIndex); - if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); - - /* If this index contains every column of its table, then mark - ** it as a covering index */ - assert( HasRowid(pTab) - || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); - if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ - pIndex->isCovering = 1; - for(j=0; jnCol; j++){ - if( j==pTab->iPKey ) continue; - if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue; - pIndex->isCovering = 0; - break; - } - } - - if( pTab==pParse->pNewTable ){ - /* This routine has been called to create an automatic index as a - ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or - ** a PRIMARY KEY or UNIQUE clause following the column definitions. - ** i.e. one of: - ** - ** CREATE TABLE t(x PRIMARY KEY, y); - ** CREATE TABLE t(x, y, UNIQUE(x, y)); - ** - ** Either way, check to see if the table already has such an index. If - ** so, don't bother creating this one. This only applies to - ** automatically created indices. Users can do as they wish with - ** explicit indices. - ** - ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent - ** (and thus suppressing the second one) even if they have different - ** sort orders. - ** - ** If there are different collating sequences or if the columns of - ** the constraint occur in different orders, then the constraints are - ** considered distinct and both result in separate indices. - */ - Index *pIdx; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int k; - assert( IsUniqueIndex(pIdx) ); - assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); - assert( IsUniqueIndex(pIndex) ); - - if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; - for(k=0; knKeyCol; k++){ - const char *z1; - const char *z2; - assert( pIdx->aiColumn[k]>=0 ); - if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; - z1 = pIdx->azColl[k]; - z2 = pIndex->azColl[k]; - if( sqlite3StrICmp(z1, z2) ) break; - } - if( k==pIdx->nKeyCol ){ - if( pIdx->onError!=pIndex->onError ){ - /* This constraint creates the same index as a previous - ** constraint specified somewhere in the CREATE TABLE statement. - ** However the ON CONFLICT clauses are different. If both this - ** constraint and the previous equivalent constraint have explicit - ** ON CONFLICT clauses this is an error. Otherwise, use the - ** explicitly specified behavior for the index. - */ - if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ - sqlite3ErrorMsg(pParse, - "conflicting ON CONFLICT clauses specified", 0); - } - if( pIdx->onError==OE_Default ){ - pIdx->onError = pIndex->onError; - } - } - if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType; - goto exit_create_index; - } - } - } - - /* Link the new Index structure to its table and to the other - ** in-memory database structures. - */ - assert( pParse->nErr==0 ); - if( db->init.busy ){ - Index *p; - assert( !IN_DECLARE_VTAB ); - assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, - pIndex->zName, pIndex); - if( p ){ - assert( p==pIndex ); /* Malloc must have failed */ - sqlite3OomFault(db); - goto exit_create_index; - } - db->flags |= SQLITE_InternChanges; - if( pTblName!=0 ){ - pIndex->tnum = db->init.newTnum; - } - } - - /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the - ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then - ** emit code to allocate the index rootpage on disk and make an entry for - ** the index in the sqlite_master table and populate the index with - ** content. But, do not do this if we are simply reading the sqlite_master - ** table to parse the schema, or if this index is the PRIMARY KEY index - ** of a WITHOUT ROWID table. - ** - ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY - ** or UNIQUE index in a CREATE TABLE statement. Since the table - ** has just been created, it contains no data and the index initialization - ** step can be skipped. - */ - else if( HasRowid(pTab) || pTblName!=0 ){ - Vdbe *v; - char *zStmt; - int iMem = ++pParse->nMem; - - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto exit_create_index; - - sqlite3BeginWriteOperation(pParse, 1, iDb); - - /* Create the rootpage for the index using CreateIndex. But before - ** doing so, code a Noop instruction and store its address in - ** Index.tnum. This is required in case this index is actually a - ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In - ** that case the convertToWithoutRowidTable() routine will replace - ** the Noop with a Goto to jump over the VDBE code generated below. */ - pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); - sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); - - /* Gather the complete text of the CREATE INDEX statement into - ** the zStmt variable - */ - if( pStart ){ - int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; - if( pName->z[n-1]==';' ) n--; - /* A named index with an explicit CREATE INDEX statement */ - zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", - onError==OE_None ? "" : " UNIQUE", n, pName->z); - }else{ - /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = sqlite3MPrintf(""); */ - zStmt = 0; - } - - /* Add an entry in sqlite_master for this index - */ - sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), - pIndex->zName, - pTab->zName, - iMem, - zStmt - ); - sqlite3DbFree(db, zStmt); - - /* Fill the index with data and reparse the schema. Code an OP_Expire - ** to invalidate all pre-compiled statements. - */ - if( pTblName ){ - sqlite3RefillIndex(pParse, pIndex, iMem); - sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); - sqlite3VdbeAddOp0(v, OP_Expire); - } - - sqlite3VdbeJumpHere(v, pIndex->tnum); - } - - /* When adding an index to the list of indices for a table, make - ** sure all indices labeled OE_Replace come after all those labeled - ** OE_Ignore. This is necessary for the correct constraint check - ** processing (in sqlite3GenerateConstraintChecks()) as part of - ** UPDATE and INSERT statements. - */ - if( db->init.busy || pTblName==0 ){ - if( onError!=OE_Replace || pTab->pIndex==0 - || pTab->pIndex->onError==OE_Replace){ - pIndex->pNext = pTab->pIndex; - pTab->pIndex = pIndex; - }else{ - Index *pOther = pTab->pIndex; - while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ - pOther = pOther->pNext; - } - pIndex->pNext = pOther->pNext; - pOther->pNext = pIndex; - } - pIndex = 0; - } - - /* Clean up before exiting */ -exit_create_index: - if( pIndex ) freeIndex(db, pIndex); - sqlite3ExprDelete(db, pPIWhere); - sqlite3ExprListDelete(db, pList); - sqlite3SrcListDelete(db, pTblName); - sqlite3DbFree(db, zName); -} - -/* -** Fill the Index.aiRowEst[] array with default information - information -** to be used when we have not run the ANALYZE command. -** -** aiRowEst[0] is supposed to contain the number of elements in the index. -** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the -** number of rows in the table that match any particular value of the -** first column of the index. aiRowEst[2] is an estimate of the number -** of rows that match any particular combination of the first 2 columns -** of the index. And so forth. It must always be the case that -* -** aiRowEst[N]<=aiRowEst[N-1] -** aiRowEst[N]>=1 -** -** Apart from that, we have little to go on besides intuition as to -** how aiRowEst[] should be initialized. The numbers generated here -** are based on typical values found in actual indices. -*/ -SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ - /* 10, 9, 8, 7, 6 */ - LogEst aVal[] = { 33, 32, 30, 28, 26 }; - LogEst *a = pIdx->aiRowLogEst; - int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); - int i; - - /* Set the first entry (number of rows in the index) to the estimated - ** number of rows in the table, or half the number of rows in the table - ** for a partial index. But do not let the estimate drop below 10. */ - a[0] = pIdx->pTable->nRowLogEst; - if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==sqlite3LogEst(2) ); - if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); - - /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is - ** 6 and each subsequent value (if any) is 5. */ - memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); - for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ - a[i] = 23; assert( 23==sqlite3LogEst(5) ); - } - - assert( 0==sqlite3LogEst(1) ); - if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; -} - -/* -** This routine will drop an existing named index. This routine -** implements the DROP INDEX statement. -*/ -SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ - Index *pIndex; - Vdbe *v; - sqlite3 *db = pParse->db; - int iDb; - - assert( pParse->nErr==0 ); /* Never called with prior errors */ - if( db->mallocFailed ){ - goto exit_drop_index; - } - assert( pName->nSrc==1 ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto exit_drop_index; - } - pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); - if( pIndex==0 ){ - if( !ifExists ){ - sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); - }else{ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); - } - pParse->checkSchema = 1; - goto exit_drop_index; - } - if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ - sqlite3ErrorMsg(pParse, "index associated with UNIQUE " - "or PRIMARY KEY constraint cannot be dropped", 0); - goto exit_drop_index; - } - iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int code = SQLITE_DROP_INDEX; - Table *pTab = pIndex->pTable; - const char *zDb = db->aDb[iDb].zDbSName; - const char *zTab = SCHEMA_TABLE(iDb); - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ - goto exit_drop_index; - } - if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX; - if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ - goto exit_drop_index; - } - } -#endif - - /* Generate code to remove the index and from the master table */ - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName - ); - sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); - sqlite3ChangeCookie(pParse, iDb); - destroyRootPage(pParse, pIndex->tnum, iDb); - sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); - } - -exit_drop_index: - sqlite3SrcListDelete(db, pName); -} - -/* -** pArray is a pointer to an array of objects. Each object in the -** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() -** to extend the array so that there is space for a new object at the end. -** -** When this function is called, *pnEntry contains the current size of -** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes -** in total). -** -** If the realloc() is successful (i.e. if no OOM condition occurs), the -** space allocated for the new object is zeroed, *pnEntry updated to -** reflect the new size of the array and a pointer to the new allocation -** returned. *pIdx is set to the index of the new array entry in this case. -** -** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains -** unchanged and a copy of pArray returned. -*/ -SQLITE_PRIVATE void *sqlite3ArrayAllocate( - sqlite3 *db, /* Connection to notify of malloc failures */ - void *pArray, /* Array of objects. Might be reallocated */ - int szEntry, /* Size of each object in the array */ - int *pnEntry, /* Number of objects currently in use */ - int *pIdx /* Write the index of a new slot here */ -){ - char *z; - int n = *pnEntry; - if( (n & (n-1))==0 ){ - int sz = (n==0) ? 1 : 2*n; - void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); - if( pNew==0 ){ - *pIdx = -1; - return pArray; - } - pArray = pNew; - } - z = (char*)pArray; - memset(&z[n * szEntry], 0, szEntry); - *pIdx = n; - ++*pnEntry; - return pArray; -} - -/* -** Append a new element to the given IdList. Create a new IdList if -** need be. -** -** A new IdList is returned, or NULL if malloc() fails. -*/ -SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ - int i; - if( pList==0 ){ - pList = sqlite3DbMallocZero(db, sizeof(IdList) ); - if( pList==0 ) return 0; - } - pList->a = sqlite3ArrayAllocate( - db, - pList->a, - sizeof(pList->a[0]), - &pList->nId, - &i - ); - if( i<0 ){ - sqlite3IdListDelete(db, pList); - return 0; - } - pList->a[i].zName = sqlite3NameFromToken(db, pToken); - return pList; -} - -/* -** Delete an IdList. -*/ -SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ - int i; - if( pList==0 ) return; - for(i=0; inId; i++){ - sqlite3DbFree(db, pList->a[i].zName); - } - sqlite3DbFree(db, pList->a); - sqlite3DbFree(db, pList); -} - -/* -** Return the index in pList of the identifier named zId. Return -1 -** if not found. -*/ -SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ - int i; - if( pList==0 ) return -1; - for(i=0; inId; i++){ - if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; - } - return -1; -} - -/* -** Expand the space allocated for the given SrcList object by -** creating nExtra new slots beginning at iStart. iStart is zero based. -** New slots are zeroed. -** -** For example, suppose a SrcList initially contains two entries: A,B. -** To append 3 new entries onto the end, do this: -** -** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); -** -** After the call above it would contain: A, B, nil, nil, nil. -** If the iStart argument had been 1 instead of 2, then the result -** would have been: A, nil, nil, nil, B. To prepend the new slots, -** the iStart value would be 0. The result then would -** be: nil, nil, nil, A, B. -** -** If a memory allocation fails the SrcList is unchanged. The -** db->mallocFailed flag will be set to true. -*/ -SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( - sqlite3 *db, /* Database connection to notify of OOM errors */ - SrcList *pSrc, /* The SrcList to be enlarged */ - int nExtra, /* Number of new slots to add to pSrc->a[] */ - int iStart /* Index in pSrc->a[] of first new slot */ -){ - int i; - - /* Sanity checking on calling parameters */ - assert( iStart>=0 ); - assert( nExtra>=1 ); - assert( pSrc!=0 ); - assert( iStart<=pSrc->nSrc ); - - /* Allocate additional space if needed */ - if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ - SrcList *pNew; - int nAlloc = pSrc->nSrc+nExtra; - int nGot; - pNew = sqlite3DbRealloc(db, pSrc, - sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); - if( pNew==0 ){ - assert( db->mallocFailed ); - return pSrc; - } - pSrc = pNew; - nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1; - pSrc->nAlloc = nGot; - } - - /* Move existing slots that come after the newly inserted slots - ** out of the way */ - for(i=pSrc->nSrc-1; i>=iStart; i--){ - pSrc->a[i+nExtra] = pSrc->a[i]; - } - pSrc->nSrc += nExtra; - - /* Zero the newly allocated slots */ - memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra); - for(i=iStart; ia[i].iCursor = -1; - } - - /* Return a pointer to the enlarged SrcList */ - return pSrc; -} - - -/* -** Append a new table name to the given SrcList. Create a new SrcList if -** need be. A new entry is created in the SrcList even if pTable is NULL. -** -** A SrcList is returned, or NULL if there is an OOM error. The returned -** SrcList might be the same as the SrcList that was input or it might be -** a new one. If an OOM error does occurs, then the prior value of pList -** that is input to this routine is automatically freed. -** -** If pDatabase is not null, it means that the table has an optional -** database name prefix. Like this: "database.table". The pDatabase -** points to the table name and the pTable points to the database name. -** The SrcList.a[].zName field is filled with the table name which might -** come from pTable (if pDatabase is NULL) or from pDatabase. -** SrcList.a[].zDatabase is filled with the database name from pTable, -** or with NULL if no database is specified. -** -** In other words, if call like this: -** -** sqlite3SrcListAppend(D,A,B,0); -** -** Then B is a table name and the database name is unspecified. If called -** like this: -** -** sqlite3SrcListAppend(D,A,B,C); -** -** Then C is the table name and B is the database name. If C is defined -** then so is B. In other words, we never have a case where: -** -** sqlite3SrcListAppend(D,A,0,C); -** -** Both pTable and pDatabase are assumed to be quoted. They are dequoted -** before being added to the SrcList. -*/ -SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( - sqlite3 *db, /* Connection to notify of malloc failures */ - SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ - Token *pTable, /* Table to append */ - Token *pDatabase /* Database of the table */ -){ - struct SrcList_item *pItem; - assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ - assert( db!=0 ); - if( pList==0 ){ - pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); - if( pList==0 ) return 0; - pList->nAlloc = 1; - pList->nSrc = 0; - } - pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); - if( db->mallocFailed ){ - sqlite3SrcListDelete(db, pList); - return 0; - } - pItem = &pList->a[pList->nSrc-1]; - if( pDatabase && pDatabase->z==0 ){ - pDatabase = 0; - } - if( pDatabase ){ - Token *pTemp = pDatabase; - pDatabase = pTable; - pTable = pTemp; - } - pItem->zName = sqlite3NameFromToken(db, pTable); - pItem->zDatabase = sqlite3NameFromToken(db, pDatabase); - return pList; -} - -/* -** Assign VdbeCursor index numbers to all tables in a SrcList -*/ -SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ - int i; - struct SrcList_item *pItem; - assert(pList || pParse->db->mallocFailed ); - if( pList ){ - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->iCursor>=0 ) break; - pItem->iCursor = pParse->nTab++; - if( pItem->pSelect ){ - sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); - } - } - } -} - -/* -** Delete an entire SrcList including all its substructure. -*/ -SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ - int i; - struct SrcList_item *pItem; - if( pList==0 ) return; - for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - sqlite3DbFree(db, pItem->zDatabase); - sqlite3DbFree(db, pItem->zName); - sqlite3DbFree(db, pItem->zAlias); - if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); - if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); - sqlite3DeleteTable(db, pItem->pTab); - sqlite3SelectDelete(db, pItem->pSelect); - sqlite3ExprDelete(db, pItem->pOn); - sqlite3IdListDelete(db, pItem->pUsing); - } - sqlite3DbFree(db, pList); -} - -/* -** This routine is called by the parser to add a new term to the -** end of a growing FROM clause. The "p" parameter is the part of -** the FROM clause that has already been constructed. "p" is NULL -** if this is the first term of the FROM clause. pTable and pDatabase -** are the name of the table and database named in the FROM clause term. -** pDatabase is NULL if the database name qualifier is missing - the -** usual case. If the term has an alias, then pAlias points to the -** alias token. If the term is a subquery, then pSubquery is the -** SELECT statement that the subquery encodes. The pTable and -** pDatabase parameters are NULL for subqueries. The pOn and pUsing -** parameters are the content of the ON and USING clauses. -** -** Return a new SrcList which encodes is the FROM with the new -** term added. -*/ -SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( - Parse *pParse, /* Parsing context */ - SrcList *p, /* The left part of the FROM clause already seen */ - Token *pTable, /* Name of the table to add to the FROM clause */ - Token *pDatabase, /* Name of the database containing pTable */ - Token *pAlias, /* The right-hand side of the AS subexpression */ - Select *pSubquery, /* A subquery used in place of a table name */ - Expr *pOn, /* The ON clause of a join */ - IdList *pUsing /* The USING clause of a join */ -){ - struct SrcList_item *pItem; - sqlite3 *db = pParse->db; - if( !p && (pOn || pUsing) ){ - sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", - (pOn ? "ON" : "USING") - ); - goto append_from_error; - } - p = sqlite3SrcListAppend(db, p, pTable, pDatabase); - if( p==0 || NEVER(p->nSrc==0) ){ - goto append_from_error; - } - pItem = &p->a[p->nSrc-1]; - assert( pAlias!=0 ); - if( pAlias->n ){ - pItem->zAlias = sqlite3NameFromToken(db, pAlias); - } - pItem->pSelect = pSubquery; - pItem->pOn = pOn; - pItem->pUsing = pUsing; - return p; - - append_from_error: - assert( p==0 ); - sqlite3ExprDelete(db, pOn); - sqlite3IdListDelete(db, pUsing); - sqlite3SelectDelete(db, pSubquery); - return 0; -} - -/* -** Add an INDEXED BY or NOT INDEXED clause to the most recently added -** element of the source-list passed as the second argument. -*/ -SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ - assert( pIndexedBy!=0 ); - if( p && ALWAYS(p->nSrc>0) ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; - assert( pItem->fg.notIndexed==0 ); - assert( pItem->fg.isIndexedBy==0 ); - assert( pItem->fg.isTabFunc==0 ); - if( pIndexedBy->n==1 && !pIndexedBy->z ){ - /* A "NOT INDEXED" clause was supplied. See parse.y - ** construct "indexed_opt" for details. */ - pItem->fg.notIndexed = 1; - }else{ - pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); - pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0); - } - } -} - -/* -** Add the list of function arguments to the SrcList entry for a -** table-valued-function. -*/ -SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ - if( p ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; - assert( pItem->fg.notIndexed==0 ); - assert( pItem->fg.isIndexedBy==0 ); - assert( pItem->fg.isTabFunc==0 ); - pItem->u1.pFuncArg = pList; - pItem->fg.isTabFunc = 1; - }else{ - sqlite3ExprListDelete(pParse->db, pList); - } -} - -/* -** When building up a FROM clause in the parser, the join operator -** is initially attached to the left operand. But the code generator -** expects the join operator to be on the right operand. This routine -** Shifts all join operators from left to right for an entire FROM -** clause. -** -** Example: Suppose the join is like this: -** -** A natural cross join B -** -** The operator is "natural cross join". The A and B operands are stored -** in p->a[0] and p->a[1], respectively. The parser initially stores the -** operator with A. This routine shifts that operator over to B. -*/ -SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ - if( p ){ - int i; - for(i=p->nSrc-1; i>0; i--){ - p->a[i].fg.jointype = p->a[i-1].fg.jointype; - } - p->a[0].fg.jointype = 0; - } -} - -/* -** Generate VDBE code for a BEGIN statement. -*/ -SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ - sqlite3 *db; - Vdbe *v; - int i; - - assert( pParse!=0 ); - db = pParse->db; - assert( db!=0 ); - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ - return; - } - v = sqlite3GetVdbe(pParse); - if( !v ) return; - if( type!=TK_DEFERRED ){ - for(i=0; inDb; i++){ - sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); - sqlite3VdbeUsesBtree(v, i); - } - } - sqlite3VdbeAddOp0(v, OP_AutoCommit); -} - -/* -** Generate VDBE code for a COMMIT statement. -*/ -SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){ - Vdbe *v; - - assert( pParse!=0 ); - assert( pParse->db!=0 ); - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){ - return; - } - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp1(v, OP_AutoCommit, 1); - } -} - -/* -** Generate VDBE code for a ROLLBACK statement. -*/ -SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){ - Vdbe *v; - - assert( pParse!=0 ); - assert( pParse->db!=0 ); - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){ - return; - } - v = sqlite3GetVdbe(pParse); - if( v ){ - sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1); - } -} - -/* -** This function is called by the parser when it parses a command to create, -** release or rollback an SQL savepoint. -*/ -SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ - char *zName = sqlite3NameFromToken(pParse->db, pName); - if( zName ){ - Vdbe *v = sqlite3GetVdbe(pParse); -#ifndef SQLITE_OMIT_AUTHORIZATION - static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; - assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); -#endif - if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ - sqlite3DbFree(pParse->db, zName); - return; - } - sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); - } -} - -/* -** Make sure the TEMP database is open and available for use. Return -** the number of errors. Leave any error messages in the pParse structure. -*/ -SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ - sqlite3 *db = pParse->db; - if( db->aDb[1].pBt==0 && !pParse->explain ){ - int rc; - Btree *pBt; - static const int flags = - SQLITE_OPEN_READWRITE | - SQLITE_OPEN_CREATE | - SQLITE_OPEN_EXCLUSIVE | - SQLITE_OPEN_DELETEONCLOSE | - SQLITE_OPEN_TEMP_DB; - - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "unable to open a temporary database " - "file for storing temporary tables"); - pParse->rc = rc; - return 1; - } - db->aDb[1].pBt = pBt; - assert( db->aDb[1].pSchema ); - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ - sqlite3OomFault(db); - return 1; - } - } - return 0; -} - -/* -** Record the fact that the schema cookie will need to be verified -** for database iDb. The code to actually verify the schema cookie -** will occur at the end of the top-level VDBE and will be generated -** later, by sqlite3FinishCoding(). -*/ -SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - - assert( iDb>=0 && iDbdb->nDb ); - assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDbdb, iDb, 0) ); - if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ - DbMaskSet(pToplevel->cookieMask, iDb); - if( !OMIT_TEMPDB && iDb==1 ){ - sqlite3OpenTempDatabase(pToplevel); - } - } -} - -/* -** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each -** attached database. Otherwise, invoke it for the database named zDb only. -*/ -SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ - sqlite3 *db = pParse->db; - int i; - for(i=0; inDb; i++){ - Db *pDb = &db->aDb[i]; - if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){ - sqlite3CodeVerifySchema(pParse, i); - } - } -} - -/* -** Generate VDBE code that prepares for doing an operation that -** might change the database. -** -** This routine starts a new transaction if we are not already within -** a transaction. If we are already within a transaction, then a checkpoint -** is set if the setStatement parameter is true. A checkpoint should -** be set for operations that might fail (due to a constraint) part of -** the way through and which will need to undo some writes without having to -** rollback the whole transaction. For operations where all constraints -** can be checked before any changes are made to the database, it is never -** necessary to undo a write and the checkpoint should not be set. -*/ -SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3CodeVerifySchema(pParse, iDb); - DbMaskSet(pToplevel->writeMask, iDb); - pToplevel->isMultiWrite |= setStatement; -} - -/* -** Indicate that the statement currently under construction might write -** more than one entry (example: deleting one row then inserting another, -** inserting multiple rows in a table, or inserting a row and index entries.) -** If an abort occurs after some of these writes have completed, then it will -** be necessary to undo the completed writes. -*/ -SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - pToplevel->isMultiWrite = 1; -} - -/* -** The code generator calls this routine if is discovers that it is -** possible to abort a statement prior to completion. In order to -** perform this abort without corrupting the database, we need to make -** sure that the statement is protected by a statement transaction. -** -** Technically, we only need to set the mayAbort flag if the -** isMultiWrite flag was previously set. There is a time dependency -** such that the abort must occur after the multiwrite. This makes -** some statements involving the REPLACE conflict resolution algorithm -** go a little faster. But taking advantage of this time dependency -** makes it more difficult to prove that the code is correct (in -** particular, it prevents us from writing an effective -** implementation of sqlite3AssertMayAbort()) and so we have chosen -** to take the safe route and skip the optimization. -*/ -SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - pToplevel->mayAbort = 1; -} - -/* -** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT -** error. The onError parameter determines which (if any) of the statement -** and/or current transaction is rolled back. -*/ -SQLITE_PRIVATE void sqlite3HaltConstraint( - Parse *pParse, /* Parsing context */ - int errCode, /* extended error code */ - int onError, /* Constraint type */ - char *p4, /* Error message */ - i8 p4type, /* P4_STATIC or P4_TRANSIENT */ - u8 p5Errmsg /* P5_ErrMsg type */ -){ - Vdbe *v = sqlite3GetVdbe(pParse); - assert( (errCode&0xff)==SQLITE_CONSTRAINT ); - if( onError==OE_Abort ){ - sqlite3MayAbort(pParse); - } - sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); - sqlite3VdbeChangeP5(v, p5Errmsg); -} - -/* -** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation. -*/ -SQLITE_PRIVATE void sqlite3UniqueConstraint( - Parse *pParse, /* Parsing context */ - int onError, /* Constraint type */ - Index *pIdx /* The index that triggers the constraint */ -){ - char *zErr; - int j; - StrAccum errMsg; - Table *pTab = pIdx->pTable; - - sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); - if( pIdx->aColExpr ){ - sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); - }else{ - for(j=0; jnKeyCol; j++){ - char *zCol; - assert( pIdx->aiColumn[j]>=0 ); - zCol = pTab->aCol[pIdx->aiColumn[j]].zName; - if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); - sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol); - } - } - zErr = sqlite3StrAccumFinish(&errMsg); - sqlite3HaltConstraint(pParse, - IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY - : SQLITE_CONSTRAINT_UNIQUE, - onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); -} - - -/* -** Code an OP_Halt due to non-unique rowid. -*/ -SQLITE_PRIVATE void sqlite3RowidConstraint( - Parse *pParse, /* Parsing context */ - int onError, /* Conflict resolution algorithm */ - Table *pTab /* The table with the non-unique rowid */ -){ - char *zMsg; - int rc; - if( pTab->iPKey>=0 ){ - zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, - pTab->aCol[pTab->iPKey].zName); - rc = SQLITE_CONSTRAINT_PRIMARYKEY; - }else{ - zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); - rc = SQLITE_CONSTRAINT_ROWID; - } - sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, - P5_ConstraintUnique); -} - -/* -** Check to see if pIndex uses the collating sequence pColl. Return -** true if it does and false if it does not. -*/ -#ifndef SQLITE_OMIT_REINDEX -static int collationMatch(const char *zColl, Index *pIndex){ - int i; - assert( zColl!=0 ); - for(i=0; inColumn; i++){ - const char *z = pIndex->azColl[i]; - assert( z!=0 || pIndex->aiColumn[i]<0 ); - if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){ - return 1; - } - } - return 0; -} -#endif - -/* -** Recompute all indices of pTab that use the collating sequence pColl. -** If pColl==0 then recompute all indices of pTab. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ - Index *pIndex; /* An index associated with pTab */ - - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( zColl==0 || collationMatch(zColl, pIndex) ){ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - } - } -} -#endif - -/* -** Recompute all indices of all tables in all databases where the -** indices use the collating sequence pColl. If pColl==0 then recompute -** all indices everywhere. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexDatabases(Parse *pParse, char const *zColl){ - Db *pDb; /* A single database */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - HashElem *k; /* For looping over tables in pDb */ - Table *pTab; /* A table in the database */ - - assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ - for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ - assert( pDb!=0 ); - for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ - pTab = (Table*)sqliteHashData(k); - reindexTable(pParse, pTab, zColl); - } - } -} -#endif - -/* -** Generate code for the REINDEX command. -** -** REINDEX -- 1 -** REINDEX -- 2 -** REINDEX ?.? -- 3 -** REINDEX ?.? -- 4 -** -** Form 1 causes all indices in all attached databases to be rebuilt. -** Form 2 rebuilds all indices in all databases that use the named -** collating function. Forms 3 and 4 rebuild the named index or all -** indices associated with the named table. -*/ -#ifndef SQLITE_OMIT_REINDEX -SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ - CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ - char *z; /* Name of a table or index */ - const char *zDb; /* Name of the database */ - Table *pTab; /* A table in the database */ - Index *pIndex; /* An index associated with pTab */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - Token *pObjName; /* Name of the table or index to be reindexed */ - - /* Read the database schema. If an error occurs, leave an error message - ** and code in pParse and return NULL. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - return; - } - - if( pName1==0 ){ - reindexDatabases(pParse, 0); - return; - }else if( NEVER(pName2==0) || pName2->z==0 ){ - char *zColl; - assert( pName1->z ); - zColl = sqlite3NameFromToken(pParse->db, pName1); - if( !zColl ) return; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); - if( pColl ){ - reindexDatabases(pParse, zColl); - sqlite3DbFree(db, zColl); - return; - } - sqlite3DbFree(db, zColl); - } - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); - if( iDb<0 ) return; - z = sqlite3NameFromToken(db, pObjName); - if( z==0 ) return; - zDb = db->aDb[iDb].zDbSName; - pTab = sqlite3FindTable(db, z, zDb); - if( pTab ){ - reindexTable(pParse, pTab, 0); - sqlite3DbFree(db, z); - return; - } - pIndex = sqlite3FindIndex(db, z, zDb); - sqlite3DbFree(db, z); - if( pIndex ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - return; - } - sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); -} -#endif - -/* -** Return a KeyInfo structure that is appropriate for the given Index. -** -** The caller should invoke sqlite3KeyInfoUnref() on the returned object -** when it has finished using it. -*/ -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ - int i; - int nCol = pIdx->nColumn; - int nKey = pIdx->nKeyCol; - KeyInfo *pKey; - if( pParse->nErr ) return 0; - if( pIdx->uniqNotNull ){ - pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); - }else{ - pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); - } - if( pKey ){ - assert( sqlite3KeyInfoIsWriteable(pKey) ); - for(i=0; iazColl[i]; - pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : - sqlite3LocateCollSeq(pParse, zColl); - pKey->aSortOrder[i] = pIdx->aSortOrder[i]; - } - if( pParse->nErr ){ - sqlite3KeyInfoUnref(pKey); - pKey = 0; - } - } - return pKey; -} - -#ifndef SQLITE_OMIT_CTE -/* -** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. -*/ -SQLITE_PRIVATE With *sqlite3WithAdd( - Parse *pParse, /* Parsing context */ - With *pWith, /* Existing WITH clause, or NULL */ - Token *pName, /* Name of the common-table */ - ExprList *pArglist, /* Optional column name list for the table */ - Select *pQuery /* Query used to initialize the table */ -){ - sqlite3 *db = pParse->db; - With *pNew; - char *zName; - - /* Check that the CTE name is unique within this WITH clause. If - ** not, store an error in the Parse structure. */ - zName = sqlite3NameFromToken(pParse->db, pName); - if( zName && pWith ){ - int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ - sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); - } - } - } - - if( pWith ){ - int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); - pNew = sqlite3DbRealloc(db, pWith, nByte); - }else{ - pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); - } - assert( (pNew!=0 && zName!=0) || db->mallocFailed ); - - if( db->mallocFailed ){ - sqlite3ExprListDelete(db, pArglist); - sqlite3SelectDelete(db, pQuery); - sqlite3DbFree(db, zName); - pNew = pWith; - }else{ - pNew->a[pNew->nCte].pSelect = pQuery; - pNew->a[pNew->nCte].pCols = pArglist; - pNew->a[pNew->nCte].zName = zName; - pNew->a[pNew->nCte].zCteErr = 0; - pNew->nCte++; - } - - return pNew; -} - -/* -** Free the contents of the With object passed as the second argument. -*/ -SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ - if( pWith ){ - int i; - for(i=0; inCte; i++){ - struct Cte *pCte = &pWith->a[i]; - sqlite3ExprListDelete(db, pCte->pCols); - sqlite3SelectDelete(db, pCte->pSelect); - sqlite3DbFree(db, pCte->zName); - } - sqlite3DbFree(db, pWith); - } -} -#endif /* !defined(SQLITE_OMIT_CTE) */ - -/************** End of build.c ***********************************************/ -/************** Begin file callback.c ****************************************/ -/* -** 2005 May 23 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains functions used to access the internal hash tables -** of user defined functions and collation sequences. -*/ - -/* #include "sqliteInt.h" */ - -/* -** Invoke the 'collation needed' callback to request a collation sequence -** in the encoding enc of name zName, length nName. -*/ -static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ - assert( !db->xCollNeeded || !db->xCollNeeded16 ); - if( db->xCollNeeded ){ - char *zExternal = sqlite3DbStrDup(db, zName); - if( !zExternal ) return; - db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); - sqlite3DbFree(db, zExternal); - } -#ifndef SQLITE_OMIT_UTF16 - if( db->xCollNeeded16 ){ - char const *zExternal; - sqlite3_value *pTmp = sqlite3ValueNew(db); - sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); - zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); - if( zExternal ){ - db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); - } - sqlite3ValueFree(pTmp); - } -#endif -} - -/* -** This routine is called if the collation factory fails to deliver a -** collation function in the best encoding but there may be other versions -** of this collation function (for other text encodings) available. Use one -** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if -** possible. -*/ -static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ - CollSeq *pColl2; - char *z = pColl->zName; - int i; - static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; - for(i=0; i<3; i++){ - pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); - if( pColl2->xCmp!=0 ){ - memcpy(pColl, pColl2, sizeof(CollSeq)); - pColl->xDel = 0; /* Do not copy the destructor */ - return SQLITE_OK; - } - } - return SQLITE_ERROR; -} - -/* -** This function is responsible for invoking the collation factory callback -** or substituting a collation sequence of a different encoding when the -** requested collation sequence is not available in the desired encoding. -** -** If it is not NULL, then pColl must point to the database native encoding -** collation sequence with name zName, length nName. -** -** The return value is either the collation sequence to be used in database -** db for collation type name zName, length nName, or NULL, if no collation -** sequence can be found. If no collation is found, leave an error message. -** -** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() -*/ -SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( - Parse *pParse, /* Parsing context */ - u8 enc, /* The desired encoding for the collating sequence */ - CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ - const char *zName /* Collating sequence name */ -){ - CollSeq *p; - sqlite3 *db = pParse->db; - - p = pColl; - if( !p ){ - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( !p || !p->xCmp ){ - /* No collation sequence of this type for this encoding is registered. - ** Call the collation factory to see if it can supply us with one. - */ - callCollNeeded(db, enc, zName); - p = sqlite3FindCollSeq(db, enc, zName, 0); - } - if( p && !p->xCmp && synthCollSeq(db, p) ){ - p = 0; - } - assert( !p || p->xCmp ); - if( p==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - } - return p; -} - -/* -** This routine is called on a collation sequence before it is used to -** check that it is defined. An undefined collation sequence exists when -** a database is loaded that contains references to collation sequences -** that have not been defined by sqlite3_create_collation() etc. -** -** If required, this routine calls the 'collation needed' callback to -** request a definition of the collating sequence. If this doesn't work, -** an equivalent collating sequence that uses a text encoding different -** from the main database is substituted, if one is available. -*/ -SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ - if( pColl ){ - const char *zName = pColl->zName; - sqlite3 *db = pParse->db; - CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); - if( !p ){ - return SQLITE_ERROR; - } - assert( p==pColl ); - } - return SQLITE_OK; -} - - - -/* -** Locate and return an entry from the db.aCollSeq hash table. If the entry -** specified by zName and nName is not found and parameter 'create' is -** true, then create a new entry. Otherwise return NULL. -** -** Each pointer stored in the sqlite3.aCollSeq hash table contains an -** array of three CollSeq structures. The first is the collation sequence -** preferred for UTF-8, the second UTF-16le, and the third UTF-16be. -** -** Stored immediately after the three collation sequences is a copy of -** the collation sequence name. A pointer to this string is stored in -** each collation sequence structure. -*/ -static CollSeq *findCollSeqEntry( - sqlite3 *db, /* Database connection */ - const char *zName, /* Name of the collating sequence */ - int create /* Create a new entry if true */ -){ - CollSeq *pColl; - pColl = sqlite3HashFind(&db->aCollSeq, zName); - - if( 0==pColl && create ){ - int nName = sqlite3Strlen30(zName); - pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1); - if( pColl ){ - CollSeq *pDel = 0; - pColl[0].zName = (char*)&pColl[3]; - pColl[0].enc = SQLITE_UTF8; - pColl[1].zName = (char*)&pColl[3]; - pColl[1].enc = SQLITE_UTF16LE; - pColl[2].zName = (char*)&pColl[3]; - pColl[2].enc = SQLITE_UTF16BE; - memcpy(pColl[0].zName, zName, nName); - pColl[0].zName[nName] = 0; - pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); - - /* If a malloc() failure occurred in sqlite3HashInsert(), it will - ** return the pColl pointer to be deleted (because it wasn't added - ** to the hash table). - */ - assert( pDel==0 || pDel==pColl ); - if( pDel!=0 ){ - sqlite3OomFault(db); - sqlite3DbFree(db, pDel); - pColl = 0; - } - } - } - return pColl; -} - -/* -** Parameter zName points to a UTF-8 encoded string nName bytes long. -** Return the CollSeq* pointer for the collation sequence named zName -** for the encoding 'enc' from the database 'db'. -** -** If the entry specified is not found and 'create' is true, then create a -** new entry. Otherwise return NULL. -** -** A separate function sqlite3LocateCollSeq() is a wrapper around -** this routine. sqlite3LocateCollSeq() invokes the collation factory -** if necessary and generates an error message if the collating sequence -** cannot be found. -** -** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() -*/ -SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( - sqlite3 *db, - u8 enc, - const char *zName, - int create -){ - CollSeq *pColl; - if( zName ){ - pColl = findCollSeqEntry(db, zName, create); - }else{ - pColl = db->pDfltColl; - } - assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); - if( pColl ) pColl += enc-1; - return pColl; -} - -/* During the search for the best function definition, this procedure -** is called to test how well the function passed as the first argument -** matches the request for a function with nArg arguments in a system -** that uses encoding enc. The value returned indicates how well the -** request is matched. A higher value indicates a better match. -** -** If nArg is -1 that means to only return a match (non-zero) if p->nArg -** is also -1. In other words, we are searching for a function that -** takes a variable number of arguments. -** -** If nArg is -2 that means that we are searching for any function -** regardless of the number of arguments it uses, so return a positive -** match score for any -** -** The returned value is always between 0 and 6, as follows: -** -** 0: Not a match. -** 1: UTF8/16 conversion required and function takes any number of arguments. -** 2: UTF16 byte order change required and function takes any number of args. -** 3: encoding matches and function takes any number of arguments -** 4: UTF8/16 conversion required - argument count matches exactly -** 5: UTF16 byte order conversion required - argument count matches exactly -** 6: Perfect match: encoding and argument count match exactly. -** -** If nArg==(-2) then any function with a non-null xSFunc is -** a perfect match and any function with xSFunc NULL is -** a non-match. -*/ -#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ -static int matchQuality( - FuncDef *p, /* The function we are evaluating for match quality */ - int nArg, /* Desired number of arguments. (-1)==any */ - u8 enc /* Desired text encoding */ -){ - int match; - - /* nArg of -2 is a special case */ - if( nArg==(-2) ) return (p->xSFunc==0) ? 0 : FUNC_PERFECT_MATCH; - - /* Wrong number of arguments means "no match" */ - if( p->nArg!=nArg && p->nArg>=0 ) return 0; - - /* Give a better score to a function with a specific number of arguments - ** than to function that accepts any number of arguments. */ - if( p->nArg==nArg ){ - match = 4; - }else{ - match = 1; - } - - /* Bonus points if the text encoding matches */ - if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ - match += 2; /* Exact encoding match */ - }else if( (enc & p->funcFlags & 2)!=0 ){ - match += 1; /* Both are UTF16, but with different byte orders */ - } - - return match; -} - -/* -** Search a FuncDefHash for a function with the given name. Return -** a pointer to the matching FuncDef if found, or 0 if there is no match. -*/ -static FuncDef *functionSearch( - int h, /* Hash of the name */ - const char *zFunc /* Name of function */ -){ - FuncDef *p; - for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ - if( sqlite3StrICmp(p->zName, zFunc)==0 ){ - return p; - } - } - return 0; -} - -/* -** Insert a new FuncDef into a FuncDefHash hash table. -*/ -SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( - FuncDef *aDef, /* List of global functions to be inserted */ - int nDef /* Length of the apDef[] list */ -){ - int i; - for(i=0; ipNext!=&aDef[i] ); - aDef[i].pNext = pOther->pNext; - pOther->pNext = &aDef[i]; - }else{ - aDef[i].pNext = 0; - aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h]; - sqlite3BuiltinFunctions.a[h] = &aDef[i]; - } - } -} - - - -/* -** Locate a user function given a name, a number of arguments and a flag -** indicating whether the function prefers UTF-16 over UTF-8. Return a -** pointer to the FuncDef structure that defines that function, or return -** NULL if the function does not exist. -** -** If the createFlag argument is true, then a new (blank) FuncDef -** structure is created and liked into the "db" structure if a -** no matching function previously existed. -** -** If nArg is -2, then the first valid function found is returned. A -** function is valid if xSFunc is non-zero. The nArg==(-2) -** case is used to see if zName is a valid function name for some number -** of arguments. If nArg is -2, then createFlag must be 0. -** -** If createFlag is false, then a function with the required name and -** number of arguments may be returned even if the eTextRep flag does not -** match that requested. -*/ -SQLITE_PRIVATE FuncDef *sqlite3FindFunction( - sqlite3 *db, /* An open database */ - const char *zName, /* Name of the function. zero-terminated */ - int nArg, /* Number of arguments. -1 means any number */ - u8 enc, /* Preferred text encoding */ - u8 createFlag /* Create new entry if true and does not otherwise exist */ -){ - FuncDef *p; /* Iterator variable */ - FuncDef *pBest = 0; /* Best match found so far */ - int bestScore = 0; /* Score of best match */ - int h; /* Hash value */ - int nName; /* Length of the name */ - - assert( nArg>=(-2) ); - assert( nArg>=(-1) || createFlag==0 ); - nName = sqlite3Strlen30(zName); - - /* First search for a match amongst the application-defined functions. - */ - p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName); - while( p ){ - int score = matchQuality(p, nArg, enc); - if( score>bestScore ){ - pBest = p; - bestScore = score; - } - p = p->pNext; - } - - /* If no match is found, search the built-in functions. - ** - ** If the SQLITE_PreferBuiltin flag is set, then search the built-in - ** functions even if a prior app-defined function was found. And give - ** priority to built-in functions. - ** - ** Except, if createFlag is true, that means that we are trying to - ** install a new function. Whatever FuncDef structure is returned it will - ** have fields overwritten with new information appropriate for the - ** new function. But the FuncDefs for built-in functions are read-only. - ** So we must not search for built-ins when creating a new function. - */ - if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ - bestScore = 0; - h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ; - p = functionSearch(h, zName); - while( p ){ - int score = matchQuality(p, nArg, enc); - if( score>bestScore ){ - pBest = p; - bestScore = score; - } - p = p->pNext; - } - } - - /* If the createFlag parameter is true and the search did not reveal an - ** exact match for the name, number of arguments and encoding, then add a - ** new entry to the hash table and return it. - */ - if( createFlag && bestScorezName = (const char*)&pBest[1]; - pBest->nArg = (u16)nArg; - pBest->funcFlags = enc; - memcpy((char*)&pBest[1], zName, nName+1); - pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); - if( pOther==pBest ){ - sqlite3DbFree(db, pBest); - sqlite3OomFault(db); - return 0; - }else{ - pBest->pNext = pOther; - } - } - - if( pBest && (pBest->xSFunc || createFlag) ){ - return pBest; - } - return 0; -} - -/* -** Free all resources held by the schema structure. The void* argument points -** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the -** pointer itself, it just cleans up subsidiary resources (i.e. the contents -** of the schema hash tables). -** -** The Schema.cache_size variable is not cleared. -*/ -SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ - Hash temp1; - Hash temp2; - HashElem *pElem; - Schema *pSchema = (Schema *)p; - - temp1 = pSchema->tblHash; - temp2 = pSchema->trigHash; - sqlite3HashInit(&pSchema->trigHash); - sqlite3HashClear(&pSchema->idxHash); - for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); - } - sqlite3HashClear(&temp2); - sqlite3HashInit(&pSchema->tblHash); - for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ - Table *pTab = sqliteHashData(pElem); - sqlite3DeleteTable(0, pTab); - } - sqlite3HashClear(&temp1); - sqlite3HashClear(&pSchema->fkeyHash); - pSchema->pSeqTab = 0; - if( pSchema->schemaFlags & DB_SchemaLoaded ){ - pSchema->iGeneration++; - pSchema->schemaFlags &= ~DB_SchemaLoaded; - } -} - -/* -** Find and return the schema associated with a BTree. Create -** a new one if necessary. -*/ -SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ - Schema * p; - if( pBt ){ - p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); - }else{ - p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); - } - if( !p ){ - sqlite3OomFault(db); - }else if ( 0==p->file_format ){ - sqlite3HashInit(&p->tblHash); - sqlite3HashInit(&p->idxHash); - sqlite3HashInit(&p->trigHash); - sqlite3HashInit(&p->fkeyHash); - p->enc = SQLITE_UTF8; - } - return p; -} - -/************** End of callback.c ********************************************/ -/************** Begin file delete.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that are called by the parser -** in order to generate code for DELETE FROM statements. -*/ -/* #include "sqliteInt.h" */ - -/* -** While a SrcList can in general represent multiple tables and subqueries -** (as in the FROM clause of a SELECT statement) in this case it contains -** the name of a single table, as one might find in an INSERT, DELETE, -** or UPDATE statement. Look up that table in the symbol table and -** return a pointer. Set an error message and return NULL if the table -** name is not found or if any other error occurs. -** -** The following fields are initialized appropriate in pSrc: -** -** pSrc->a[0].pTab Pointer to the Table object -** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one -** -*/ -SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ - struct SrcList_item *pItem = pSrc->a; - Table *pTab; - assert( pItem && pSrc->nSrc==1 ); - pTab = sqlite3LocateTableItem(pParse, 0, pItem); - sqlite3DeleteTable(pParse->db, pItem->pTab); - pItem->pTab = pTab; - if( pTab ){ - pTab->nRef++; - } - if( sqlite3IndexedByLookup(pParse, pItem) ){ - pTab = 0; - } - return pTab; -} - -/* -** Check to make sure the given table is writable. If it is not -** writable, generate an error message and return 1. If it is -** writable return 0; -*/ -SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ - /* A table is not writable under the following circumstances: - ** - ** 1) It is a virtual table and no implementation of the xUpdate method - ** has been provided, or - ** 2) It is a system table (i.e. sqlite_master), this call is not - ** part of a nested parse and writable_schema pragma has not - ** been specified. - ** - ** In either case leave an error message in pParse and return non-zero. - */ - if( ( IsVirtual(pTab) - && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) - || ( (pTab->tabFlags & TF_Readonly)!=0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 - && pParse->nested==0 ) - ){ - sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); - return 1; - } - -#ifndef SQLITE_OMIT_VIEW - if( !viewOk && pTab->pSelect ){ - sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); - return 1; - } -#endif - return 0; -} - - -#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) -/* -** Evaluate a view and store its result in an ephemeral table. The -** pWhere argument is an optional WHERE clause that restricts the -** set of rows in the view that are to be added to the ephemeral table. -*/ -SQLITE_PRIVATE void sqlite3MaterializeView( - Parse *pParse, /* Parsing context */ - Table *pView, /* View definition */ - Expr *pWhere, /* Optional WHERE clause to be added */ - int iCur /* Cursor number for ephemeral table */ -){ - SelectDest dest; - Select *pSel; - SrcList *pFrom; - sqlite3 *db = pParse->db; - int iDb = sqlite3SchemaToIndex(db, pView->pSchema); - pWhere = sqlite3ExprDup(db, pWhere, 0); - pFrom = sqlite3SrcListAppend(db, 0, 0, 0); - if( pFrom ){ - assert( pFrom->nSrc==1 ); - pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); - assert( pFrom->a[0].pOn==0 ); - assert( pFrom->a[0].pUsing==0 ); - } - pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, - SF_IncludeHidden, 0, 0); - sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); - sqlite3Select(pParse, pSel, &dest); - sqlite3SelectDelete(db, pSel); -} -#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ - -#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) -/* -** Generate an expression tree to implement the WHERE, ORDER BY, -** and LIMIT/OFFSET portion of DELETE and UPDATE statements. -** -** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; -** \__________________________/ -** pLimitWhere (pInClause) -*/ -SQLITE_PRIVATE Expr *sqlite3LimitWhere( - Parse *pParse, /* The parser context */ - SrcList *pSrc, /* the FROM clause -- which tables to scan */ - Expr *pWhere, /* The WHERE clause. May be null */ - ExprList *pOrderBy, /* The ORDER BY clause. May be null */ - Expr *pLimit, /* The LIMIT clause. May be null */ - Expr *pOffset, /* The OFFSET clause. May be null */ - char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ -){ - Expr *pWhereRowid = NULL; /* WHERE rowid .. */ - Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ - Expr *pSelectRowid = NULL; /* SELECT rowid ... */ - ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ - SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ - Select *pSelect = NULL; /* Complete SELECT tree */ - - /* Check that there isn't an ORDER BY without a LIMIT clause. - */ - if( pOrderBy && (pLimit == 0) ) { - sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - goto limit_where_cleanup; - } - - /* We only need to generate a select expression if there - ** is a limit/offset term to enforce. - */ - if( pLimit == 0 ) { - /* if pLimit is null, pOffset will always be null as well. */ - assert( pOffset == 0 ); - return pWhere; - } - - /* Generate a select expression tree to enforce the limit/offset - ** term for the DELETE or UPDATE statement. For example: - ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 - ** becomes: - ** DELETE FROM table_a WHERE rowid IN ( - ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 - ** ); - */ - - pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); - if( pSelectRowid == 0 ) goto limit_where_cleanup; - pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid); - if( pEList == 0 ) goto limit_where_cleanup; - - /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree - ** and the SELECT subtree. */ - pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); - if( pSelectSrc == 0 ) { - sqlite3ExprListDelete(pParse->db, pEList); - goto limit_where_cleanup; - } - - /* generate the SELECT expression tree. */ - pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0, - pOrderBy,0,pLimit,pOffset); - if( pSelect == 0 ) return 0; - - /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ - pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0); - pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0; - sqlite3PExprAddSelect(pParse, pInClause, pSelect); - return pInClause; - -limit_where_cleanup: - sqlite3ExprDelete(pParse->db, pWhere); - sqlite3ExprListDelete(pParse->db, pOrderBy); - sqlite3ExprDelete(pParse->db, pLimit); - sqlite3ExprDelete(pParse->db, pOffset); - return 0; -} -#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ - /* && !defined(SQLITE_OMIT_SUBQUERY) */ - -/* -** Generate code for a DELETE FROM statement. -** -** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; -** \________/ \________________/ -** pTabList pWhere -*/ -SQLITE_PRIVATE void sqlite3DeleteFrom( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* The table from which we should delete things */ - Expr *pWhere /* The WHERE clause. May be null */ -){ - Vdbe *v; /* The virtual database engine */ - Table *pTab; /* The table from which records will be deleted */ - int i; /* Loop counter */ - WhereInfo *pWInfo; /* Information about the WHERE clause */ - Index *pIdx; /* For looping over indices of the table */ - int iTabCur; /* Cursor number for the table */ - int iDataCur = 0; /* VDBE cursor for the canonical data source */ - int iIdxCur = 0; /* Cursor number of the first index */ - int nIdx; /* Number of indices */ - sqlite3 *db; /* Main database structure */ - AuthContext sContext; /* Authorization context */ - NameContext sNC; /* Name context to resolve expressions in */ - int iDb; /* Database number */ - int memCnt = -1; /* Memory cell used for change counting */ - int rcauth; /* Value returned by authorization callback */ - int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */ - int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ - u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ - Index *pPk; /* The PRIMARY KEY index on the table */ - int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ - i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ - int iKey; /* Memory cell holding key of row to be deleted */ - i16 nKey; /* Number of memory cells in the row key */ - int iEphCur = 0; /* Ephemeral table holding all primary key values */ - int iRowSet = 0; /* Register for rowset of rows to delete */ - int addrBypass = 0; /* Address of jump over the delete logic */ - int addrLoop = 0; /* Top of the delete loop */ - int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ - int bComplex; /* True if there are triggers or FKs or - ** subqueries in the WHERE clause */ - -#ifndef SQLITE_OMIT_TRIGGER - int isView; /* True if attempting to delete from a view */ - Trigger *pTrigger; /* List of table triggers, if required */ -#endif - - memset(&sContext, 0, sizeof(sContext)); - db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ - goto delete_from_cleanup; - } - assert( pTabList->nSrc==1 ); - - /* Locate the table which we want to delete. This table has to be - ** put in an SrcList structure because some of the subroutines we - ** will be calling are designed to work with multiple tables and expect - ** an SrcList* parameter instead of just a Table* parameter. - */ - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ) goto delete_from_cleanup; - - /* Figure out if we have any triggers and if the table being - ** deleted from is a view - */ -#ifndef SQLITE_OMIT_TRIGGER - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - isView = pTab->pSelect!=0; - bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); -#else -# define pTrigger 0 -# define isView 0 -#endif -#ifdef SQLITE_OMIT_VIEW -# undef isView -# define isView 0 -#endif - - /* If pTab is really a view, make sure it has been initialized. - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto delete_from_cleanup; - } - - if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ - goto delete_from_cleanup; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDbnDb ); - rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, - db->aDb[iDb].zDbSName); - assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); - if( rcauth==SQLITE_DENY ){ - goto delete_from_cleanup; - } - assert(!isView || pTrigger); - - /* Assign cursor numbers to the table and all its indices. - */ - assert( pTabList->nSrc==1 ); - iTabCur = pTabList->a[0].iCursor = pParse->nTab++; - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ - pParse->nTab++; - } - - /* Start the view context - */ - if( isView ){ - sqlite3AuthContextPush(pParse, &sContext, pTab->zName); - } - - /* Begin generating code. - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ){ - goto delete_from_cleanup; - } - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1, iDb); - - /* If we are trying to delete from a view, realize that view into - ** an ephemeral table. - */ -#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) - if( isView ){ - sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur); - iDataCur = iIdxCur = iTabCur; - } -#endif - - /* Resolve the column names in the WHERE clause. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - if( sqlite3ResolveExprNames(&sNC, pWhere) ){ - goto delete_from_cleanup; - } - - /* Initialize the counter of the number of rows deleted, if - ** we are counting rows. - */ - if( db->flags & SQLITE_CountRows ){ - memCnt = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); - } - -#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION - /* Special case: A DELETE without a WHERE clause deletes everything. - ** It is easier just to erase the whole table. Prior to version 3.6.5, - ** this optimization caused the row change count (the value returned by - ** API function sqlite3_count_changes) to be set incorrectly. */ - if( rcauth==SQLITE_OK - && pWhere==0 - && !bComplex - && !IsVirtual(pTab) -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - && db->xPreUpdateCallback==0 -#endif - ){ - assert( !isView ); - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, - pTab->zName, P4_STATIC); - } - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - assert( pIdx->pSchema==pTab->pSchema ); - sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); - } - }else -#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ - { - u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE; - if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; - wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); - if( HasRowid(pTab) ){ - /* For a rowid table, initialize the RowSet to an empty set */ - pPk = 0; - nPk = 1; - iRowSet = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); - }else{ - /* For a WITHOUT ROWID table, create an ephemeral table used to - ** hold all primary keys for rows to be deleted. */ - pPk = sqlite3PrimaryKeyIndex(pTab); - assert( pPk!=0 ); - nPk = pPk->nKeyCol; - iPk = pParse->nMem+1; - pParse->nMem += nPk; - iEphCur = pParse->nTab++; - addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - } - - /* Construct a query to find the rowid or primary key for every row - ** to be deleted, based on the WHERE clause. Set variable eOnePass - ** to indicate the strategy used to implement this delete: - ** - ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values. - ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. - ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. - */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1); - if( pWInfo==0 ) goto delete_from_cleanup; - eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); - assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); - - /* Keep track of the number of rows to be deleted */ - if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); - } - - /* Extract the rowid or primary key for the current row */ - if( pPk ){ - for(i=0; iaiColumn[i]>=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, - pPk->aiColumn[i], iPk+i); - } - iKey = iPk; - }else{ - iKey = pParse->nMem + 1; - iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); - if( iKey>pParse->nMem ) pParse->nMem = iKey; - } - - if( eOnePass!=ONEPASS_OFF ){ - /* For ONEPASS, no need to store the rowid/primary-key. There is only - ** one, so just keep it in its register(s) and fall through to the - ** delete code. */ - nKey = nPk; /* OP_Found will use an unpacked key */ - aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); - if( aToOpen==0 ){ - sqlite3WhereEnd(pWInfo); - goto delete_from_cleanup; - } - memset(aToOpen, 1, nIdx+1); - aToOpen[nIdx+1] = 0; - if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; - if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; - if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); - }else{ - if( pPk ){ - /* Add the PK key for this row to the temporary table */ - iKey = ++pParse->nMem; - nKey = 0; /* Zero tells OP_Found to use a composite key */ - sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, - sqlite3IndexAffinityStr(pParse->db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); - }else{ - /* Add the rowid of the row to be deleted to the RowSet */ - nKey = 1; /* OP_Seek always uses a single rowid */ - sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); - } - } - - /* If this DELETE cannot use the ONEPASS strategy, this is the - ** end of the WHERE loop */ - if( eOnePass!=ONEPASS_OFF ){ - addrBypass = sqlite3VdbeMakeLabel(v); - }else{ - sqlite3WhereEnd(pWInfo); - } - - /* Unless this is a view, open cursors for the table we are - ** deleting from and all its indices. If this is a view, then the - ** only effect this statement has is to fire the INSTEAD OF - ** triggers. - */ - if( !isView ){ - int iAddrOnce = 0; - if( eOnePass==ONEPASS_MULTI ){ - iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - testcase( IsVirtual(pTab) ); - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, - iTabCur, aToOpen, &iDataCur, &iIdxCur); - assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); - assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); - if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); - } - - /* Set up a loop over the rowids/primary-keys that were found in the - ** where-clause loop above. - */ - if( eOnePass!=ONEPASS_OFF ){ - assert( nKey==nPk ); /* OP_Found will use an unpacked key */ - if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ - assert( pPk!=0 || pTab->pSelect!=0 ); - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); - VdbeCoverage(v); - } - }else if( pPk ){ - addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); - assert( nKey==0 ); /* OP_Found will use a composite key */ - }else{ - addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); - VdbeCoverage(v); - assert( nKey==1 ); - } - - /* Delete the row */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); - sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); - sqlite3VdbeChangeP5(v, OE_Abort); - assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); - sqlite3MayAbort(pParse); - if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){ - pParse->isMultiWrite = 0; - } - }else -#endif - { - int count = (pParse->nested==0); /* True to count changes */ - int iIdxNoSeek = -1; - if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){ - iIdxNoSeek = aiCurOnePass[1]; - } - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek); - } - - /* End of the loop over all rowids/primary-keys. */ - if( eOnePass!=ONEPASS_OFF ){ - sqlite3VdbeResolveLabel(v, addrBypass); - sqlite3WhereEnd(pWInfo); - }else if( pPk ){ - sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addrLoop); - }else{ - sqlite3VdbeGoto(v, addrLoop); - sqlite3VdbeJumpHere(v, addrLoop); - } - - /* Close the cursors open on the table and its indexes. */ - if( !isView && !IsVirtual(pTab) ){ - if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); - for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); - } - } - } /* End non-truncate path */ - - /* Update the sqlite_sequence table by storing the content of the - ** maximum rowid counter values recorded while inserting into - ** autoincrement tables. - */ - if( pParse->nested==0 && pParse->pTriggerTab==0 ){ - sqlite3AutoincrementEnd(pParse); - } - - /* Return the number of rows that were deleted. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ - if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); - } - -delete_from_cleanup: - sqlite3AuthContextPop(&sContext); - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprDelete(db, pWhere); - sqlite3DbFree(db, aToOpen); - return; -} -/* Make sure "isView" and other macros defined above are undefined. Otherwise -** they may interfere with compilation of other functions in this file -** (or in another file, if this file becomes part of the amalgamation). */ -#ifdef isView - #undef isView -#endif -#ifdef pTrigger - #undef pTrigger -#endif - -/* -** This routine generates VDBE code that causes a single row of a -** single table to be deleted. Both the original table entry and -** all indices are removed. -** -** Preconditions: -** -** 1. iDataCur is an open cursor on the btree that is the canonical data -** store for the table. (This will be either the table itself, -** in the case of a rowid table, or the PRIMARY KEY index in the case -** of a WITHOUT ROWID table.) -** -** 2. Read/write cursors for all indices of pTab must be open as -** cursor number iIdxCur+i for the i-th index. -** -** 3. The primary key for the row to be deleted must be stored in a -** sequence of nPk memory cells starting at iPk. If nPk==0 that means -** that a search record formed from OP_MakeRecord is contained in the -** single memory location iPk. -** -** eMode: -** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or -** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor -** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF -** then this function must seek iDataCur to the entry identified by iPk -** and nPk before reading from it. -** -** If eMode is ONEPASS_MULTI, then this call is being made as part -** of a ONEPASS delete that affects multiple rows. In this case, if -** iIdxNoSeek is a valid cursor number (>=0), then its position should -** be preserved following the delete operation. Or, if iIdxNoSeek is not -** a valid cursor number, the position of iDataCur should be preserved -** instead. -** -** iIdxNoSeek: -** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an -** index cursor (from within array of cursors starting at iIdxCur) that -** already points to the index entry to be deleted. -*/ -SQLITE_PRIVATE void sqlite3GenerateRowDelete( - Parse *pParse, /* Parsing context */ - Table *pTab, /* Table containing the row to be deleted */ - Trigger *pTrigger, /* List of triggers to (potentially) fire */ - int iDataCur, /* Cursor from which column data is extracted */ - int iIdxCur, /* First index cursor */ - int iPk, /* First memory cell containing the PRIMARY KEY */ - i16 nPk, /* Number of PRIMARY KEY memory cells */ - u8 count, /* If non-zero, increment the row change counter */ - u8 onconf, /* Default ON CONFLICT policy for triggers */ - u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */ - int iIdxNoSeek /* Cursor number of cursor that does not need seeking */ -){ - Vdbe *v = pParse->pVdbe; /* Vdbe */ - int iOld = 0; /* First register in OLD.* array */ - int iLabel; /* Label resolved to end of generated code */ - u8 opSeek; /* Seek opcode */ - - /* Vdbe is guaranteed to have been allocated by this stage. */ - assert( v ); - VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", - iDataCur, iIdxCur, iPk, (int)nPk)); - - /* Seek cursor iCur to the row to delete. If this row no longer exists - ** (this can happen if a trigger program has already deleted it), do - ** not attempt to delete it or fire any DELETE triggers. */ - iLabel = sqlite3VdbeMakeLabel(v); - opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; - if( eMode==ONEPASS_OFF ){ - sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); - VdbeCoverageIf(v, opSeek==OP_NotExists); - VdbeCoverageIf(v, opSeek==OP_NotFound); - } - - /* If there are any triggers to fire, allocate a range of registers to - ** use for the old.* references in the triggers. */ - if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ - u32 mask; /* Mask of OLD.* columns in use */ - int iCol; /* Iterator used while populating OLD.* */ - int addrStart; /* Start of BEFORE trigger programs */ - - /* TODO: Could use temporary registers here. Also could attempt to - ** avoid copying the contents of the rowid register. */ - mask = sqlite3TriggerColmask( - pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf - ); - mask |= sqlite3FkOldmask(pParse, pTab); - iOld = pParse->nMem+1; - pParse->nMem += (1 + pTab->nCol); - - /* Populate the OLD.* pseudo-table register array. These values will be - ** used by any BEFORE and AFTER triggers that exist. */ - sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); - for(iCol=0; iColnCol; iCol++){ - testcase( mask!=0xffffffff && iCol==31 ); - testcase( mask!=0xffffffff && iCol==32 ); - if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1); - } - } - - /* Invoke BEFORE DELETE trigger programs. */ - addrStart = sqlite3VdbeCurrentAddr(v); - sqlite3CodeRowTrigger(pParse, pTrigger, - TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel - ); - - /* If any BEFORE triggers were coded, then seek the cursor to the - ** row to be deleted again. It may be that the BEFORE triggers moved - ** the cursor or of already deleted the row that the cursor was - ** pointing to. - */ - if( addrStartpSelect==0 ){ - u8 p5 = 0; - sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); - sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); - sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE); - if( eMode!=ONEPASS_OFF ){ - sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); - } - if( iIdxNoSeek>=0 ){ - sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); - } - if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; - sqlite3VdbeChangeP5(v, p5); - } - - /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to - ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just deleted. */ - sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); - - /* Invoke AFTER DELETE trigger programs. */ - sqlite3CodeRowTrigger(pParse, pTrigger, - TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel - ); - - /* Jump here if the row had already been deleted before any BEFORE - ** trigger programs were invoked. Or if a trigger program throws a - ** RAISE(IGNORE) exception. */ - sqlite3VdbeResolveLabel(v, iLabel); - VdbeModuleComment((v, "END: GenRowDel()")); -} - -/* -** This routine generates VDBE code that causes the deletion of all -** index entries associated with a single row of a single table, pTab -** -** Preconditions: -** -** 1. A read/write cursor "iDataCur" must be open on the canonical storage -** btree for the table pTab. (This will be either the table itself -** for rowid tables or to the primary key index for WITHOUT ROWID -** tables.) -** -** 2. Read/write cursors for all indices of pTab must be open as -** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex -** index is the 0-th index.) -** -** 3. The "iDataCur" cursor must be already be positioned on the row -** that is to be deleted. -*/ -SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* Table containing the row to be deleted */ - int iDataCur, /* Cursor of table holding data. */ - int iIdxCur, /* First index cursor */ - int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ - int iIdxNoSeek /* Do not delete from this cursor */ -){ - int i; /* Index loop counter */ - int r1 = -1; /* Register holding an index key */ - int iPartIdxLabel; /* Jump destination for skipping partial index entries */ - Index *pIdx; /* Current index */ - Index *pPrior = 0; /* Prior index */ - Vdbe *v; /* The prepared statement under construction */ - Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ - - v = pParse->pVdbe; - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - assert( iIdxCur+i!=iDataCur || pPk==pIdx ); - if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; - if( pIdx==pPk ) continue; - if( iIdxCur+i==iIdxNoSeek ) continue; - VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, - &iPartIdxLabel, pPrior, r1); - sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, - pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); - sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); - pPrior = pIdx; - } -} - -/* -** Generate code that will assemble an index key and stores it in register -** regOut. The key with be for index pIdx which is an index on pTab. -** iCur is the index of a cursor open on the pTab table and pointing to -** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then -** iCur must be the cursor of the PRIMARY KEY index. -** -** Return a register number which is the first in a block of -** registers that holds the elements of the index key. The -** block of registers has already been deallocated by the time -** this routine returns. -** -** If *piPartIdxLabel is not NULL, fill it in with a label and jump -** to that label if pIdx is a partial index that should be skipped. -** The label should be resolved using sqlite3ResolvePartIdxLabel(). -** A partial index should be skipped if its WHERE clause evaluates -** to false or null. If pIdx is not a partial index, *piPartIdxLabel -** will be set to zero which is an empty label that is ignored by -** sqlite3ResolvePartIdxLabel(). -** -** The pPrior and regPrior parameters are used to implement a cache to -** avoid unnecessary register loads. If pPrior is not NULL, then it is -** a pointer to a different index for which an index key has just been -** computed into register regPrior. If the current pIdx index is generating -** its key into the same sequence of registers and if pPrior and pIdx share -** a column in common, then the register corresponding to that column already -** holds the correct value and the loading of that register is skipped. -** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK -** on a table with multiple indices, and especially with the ROWID or -** PRIMARY KEY columns of the index. -*/ -SQLITE_PRIVATE int sqlite3GenerateIndexKey( - Parse *pParse, /* Parsing context */ - Index *pIdx, /* The index for which to generate a key */ - int iDataCur, /* Cursor number from which to take column data */ - int regOut, /* Put the new key into this register if not 0 */ - int prefixOnly, /* Compute only a unique prefix of the key */ - int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ - Index *pPrior, /* Previously generated index key */ - int regPrior /* Register holding previous generated key */ -){ - Vdbe *v = pParse->pVdbe; - int j; - int regBase; - int nCol; - - if( piPartIdxLabel ){ - if( pIdx->pPartIdxWhere ){ - *piPartIdxLabel = sqlite3VdbeMakeLabel(v); - pParse->iSelfTab = iDataCur; - sqlite3ExprCachePush(pParse); - sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, - SQLITE_JUMPIFNULL); - }else{ - *piPartIdxLabel = 0; - } - } - nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; - regBase = sqlite3GetTempRange(pParse, nCol); - if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; - for(j=0; jaiColumn[j]==pIdx->aiColumn[j] - && pPrior->aiColumn[j]!=XN_EXPR - ){ - /* This column was already computed by the previous index */ - continue; - } - sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j); - /* If the column affinity is REAL but the number is an integer, then it - ** might be stored in the table as an integer (using a compact - ** representation) then converted to REAL by an OP_RealAffinity opcode. - ** But we are getting ready to store this value back into an index, where - ** it should be converted by to INTEGER again. So omit the OP_RealAffinity - ** opcode if it is present */ - sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); - } - if( regOut ){ - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); - } - sqlite3ReleaseTempRange(pParse, regBase, nCol); - return regBase; -} - -/* -** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label -** because it was a partial index, then this routine should be called to -** resolve that label. -*/ -SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ - if( iLabel ){ - sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); - sqlite3ExprCachePop(pParse); - } -} - -/************** End of delete.c **********************************************/ -/************** Begin file func.c ********************************************/ -/* -** 2002 February 23 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the C-language implementations for many of the SQL -** functions of SQLite. (Some function, and in particular the date and -** time functions, are implemented separately.) -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include */ -/* #include "vdbeInt.h" */ - -/* -** Return the collating function associated with a function. -*/ -static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ - VdbeOp *pOp; - assert( context->pVdbe!=0 ); - pOp = &context->pVdbe->aOp[context->iOp-1]; - assert( pOp->opcode==OP_CollSeq ); - assert( pOp->p4type==P4_COLLSEQ ); - return pOp->p4.pColl; -} - -/* -** Indicate that the accumulator load should be skipped on this -** iteration of the aggregate loop. -*/ -static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ - context->skipFlag = 1; -} - -/* -** Implementation of the non-aggregate min() and max() functions -*/ -static void minmaxFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i; - int mask; /* 0 for min() or 0xffffffff for max() */ - int iBest; - CollSeq *pColl; - - assert( argc>1 ); - mask = sqlite3_user_data(context)==0 ? 0 : -1; - pColl = sqlite3GetFuncCollSeq(context); - assert( pColl ); - assert( mask==-1 || mask==0 ); - iBest = 0; - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - for(i=1; i=0 ){ - testcase( mask==0 ); - iBest = i; - } - } - sqlite3_result_value(context, argv[iBest]); -} - -/* -** Return the type of the argument. -*/ -static void typeofFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - const char *z = 0; - UNUSED_PARAMETER(NotUsed); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_INTEGER: z = "integer"; break; - case SQLITE_TEXT: z = "text"; break; - case SQLITE_FLOAT: z = "real"; break; - case SQLITE_BLOB: z = "blob"; break; - default: z = "null"; break; - } - sqlite3_result_text(context, z, -1, SQLITE_STATIC); -} - - -/* -** Implementation of the length() function -*/ -static void lengthFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int len; - - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_BLOB: - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); - break; - } - case SQLITE_TEXT: { - const unsigned char *z = sqlite3_value_text(argv[0]); - if( z==0 ) return; - len = 0; - while( *z ){ - len++; - SQLITE_SKIP_UTF8(z); - } - sqlite3_result_int(context, len); - break; - } - default: { - sqlite3_result_null(context); - break; - } - } -} - -/* -** Implementation of the abs() function. -** -** IMP: R-23979-26855 The abs(X) function returns the absolute value of -** the numeric argument X. -*/ -static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_INTEGER: { - i64 iVal = sqlite3_value_int64(argv[0]); - if( iVal<0 ){ - if( iVal==SMALLEST_INT64 ){ - /* IMP: R-31676-45509 If X is the integer -9223372036854775808 - ** then abs(X) throws an integer overflow error since there is no - ** equivalent positive 64-bit two complement value. */ - sqlite3_result_error(context, "integer overflow", -1); - return; - } - iVal = -iVal; - } - sqlite3_result_int64(context, iVal); - break; - } - case SQLITE_NULL: { - /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ - sqlite3_result_null(context); - break; - } - default: { - /* Because sqlite3_value_double() returns 0.0 if the argument is not - ** something that can be converted into a number, we have: - ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob - ** that cannot be converted to a numeric value. - */ - double rVal = sqlite3_value_double(argv[0]); - if( rVal<0 ) rVal = -rVal; - sqlite3_result_double(context, rVal); - break; - } - } -} - -/* -** Implementation of the instr() function. -** -** instr(haystack,needle) finds the first occurrence of needle -** in haystack and returns the number of previous characters plus 1, -** or 0 if needle does not occur within haystack. -** -** If both haystack and needle are BLOBs, then the result is one more than -** the number of bytes in haystack prior to the first occurrence of needle, -** or 0 if needle never occurs in haystack. -*/ -static void instrFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zHaystack; - const unsigned char *zNeedle; - int nHaystack; - int nNeedle; - int typeHaystack, typeNeedle; - int N = 1; - int isText; - - UNUSED_PARAMETER(argc); - typeHaystack = sqlite3_value_type(argv[0]); - typeNeedle = sqlite3_value_type(argv[1]); - if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; - nHaystack = sqlite3_value_bytes(argv[0]); - nNeedle = sqlite3_value_bytes(argv[1]); - if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ - zHaystack = sqlite3_value_blob(argv[0]); - zNeedle = sqlite3_value_blob(argv[1]); - isText = 0; - }else{ - zHaystack = sqlite3_value_text(argv[0]); - zNeedle = sqlite3_value_text(argv[1]); - isText = 1; - } - while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ - N++; - do{ - nHaystack--; - zHaystack++; - }while( isText && (zHaystack[0]&0xc0)==0x80 ); - } - if( nNeedle>nHaystack ) N = 0; - sqlite3_result_int(context, N); -} - -/* -** Implementation of the printf() function. -*/ -static void printfFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - PrintfArguments x; - StrAccum str; - const char *zFormat; - int n; - sqlite3 *db = sqlite3_context_db_handle(context); - - if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ - x.nArg = argc-1; - x.nUsed = 0; - x.apArg = argv+1; - sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); - str.printfFlags = SQLITE_PRINTF_SQLFUNC; - sqlite3XPrintf(&str, zFormat, &x); - n = str.nChar; - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, - SQLITE_DYNAMIC); - } -} - -/* -** Implementation of the substr() function. -** -** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. -** p1 is 1-indexed. So substr(x,1,1) returns the first character -** of x. If x is text, then we actually count UTF-8 characters. -** If x is a blob, then we count bytes. -** -** If p1 is negative, then we begin abs(p1) from the end of x[]. -** -** If p2 is negative, return the p2 characters preceding p1. -*/ -static void substrFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *z; - const unsigned char *z2; - int len; - int p0type; - i64 p1, p2; - int negP2 = 0; - - assert( argc==3 || argc==2 ); - if( sqlite3_value_type(argv[1])==SQLITE_NULL - || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) - ){ - return; - } - p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int(argv[1]); - if( p0type==SQLITE_BLOB ){ - len = sqlite3_value_bytes(argv[0]); - z = sqlite3_value_blob(argv[0]); - if( z==0 ) return; - assert( len==sqlite3_value_bytes(argv[0]) ); - }else{ - z = sqlite3_value_text(argv[0]); - if( z==0 ) return; - len = 0; - if( p1<0 ){ - for(z2=z; *z2; len++){ - SQLITE_SKIP_UTF8(z2); - } - } - } -#ifdef SQLITE_SUBSTR_COMPATIBILITY - /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as - ** as substr(X,1,N) - it returns the first N characters of X. This - ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] - ** from 2009-02-02 for compatibility of applications that exploited the - ** old buggy behavior. */ - if( p1==0 ) p1 = 1; /* */ -#endif - if( argc==3 ){ - p2 = sqlite3_value_int(argv[2]); - if( p2<0 ){ - p2 = -p2; - negP2 = 1; - } - }else{ - p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; - } - if( p1<0 ){ - p1 += len; - if( p1<0 ){ - p2 += p1; - if( p2<0 ) p2 = 0; - p1 = 0; - } - }else if( p1>0 ){ - p1--; - }else if( p2>0 ){ - p2--; - } - if( negP2 ){ - p1 -= p2; - if( p1<0 ){ - p2 += p1; - p1 = 0; - } - } - assert( p1>=0 && p2>=0 ); - if( p0type!=SQLITE_BLOB ){ - while( *z && p1 ){ - SQLITE_SKIP_UTF8(z); - p1--; - } - for(z2=z; *z2 && p2; p2--){ - SQLITE_SKIP_UTF8(z2); - } - sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, - SQLITE_UTF8); - }else{ - if( p1+p2>len ){ - p2 = len-p1; - if( p2<0 ) p2 = 0; - } - sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); - } -} - -/* -** Implementation of the round() function -*/ -#ifndef SQLITE_OMIT_FLOATING_POINT -static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - int n = 0; - double r; - char *zBuf; - assert( argc==1 || argc==2 ); - if( argc==2 ){ - if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; - n = sqlite3_value_int(argv[1]); - if( n>30 ) n = 30; - if( n<0 ) n = 0; - } - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - r = sqlite3_value_double(argv[0]); - /* If Y==0 and X will fit in a 64-bit int, - ** handle the rounding directly, - ** otherwise use printf. - */ - if( n==0 && r>=0 && r0 ); - testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); - testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); - if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(context); - z = 0; - }else{ - z = sqlite3Malloc(nByte); - if( !z ){ - sqlite3_result_error_nomem(context); - } - } - return z; -} - -/* -** Implementation of the upper() and lower() SQL functions. -*/ -static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - char *z1; - const char *z2; - int i, n; - UNUSED_PARAMETER(argc); - z2 = (char*)sqlite3_value_text(argv[0]); - n = sqlite3_value_bytes(argv[0]); - /* Verify that the call to _bytes() does not invalidate the _text() pointer */ - assert( z2==(char*)sqlite3_value_text(argv[0]) ); - if( z2 ){ - z1 = contextMalloc(context, ((i64)n)+1); - if( z1 ){ - for(i=0; imatchOne; /* "?" or "_" */ - u32 matchAll = pInfo->matchAll; /* "*" or "%" */ - u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */ - const u8 *zEscaped = 0; /* One past the last escaped input char */ - - while( (c = Utf8Read(zPattern))!=0 ){ - if( c==matchAll ){ /* Match "*" */ - /* Skip over multiple "*" characters in the pattern. If there - ** are also "?" characters, skip those as well, but consume a - ** single character of the input string for each "?" skipped */ - while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ - if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ - return 0; - } - } - if( c==0 ){ - return 1; /* "*" at the end of the pattern matches */ - }else if( c==matchOther ){ - if( pInfo->matchSet==0 ){ - c = sqlite3Utf8Read(&zPattern); - if( c==0 ) return 0; - }else{ - /* "[...]" immediately follows the "*". We have to do a slow - ** recursive search in this case, but it is an unusual case. */ - assert( matchOther<0x80 ); /* '[' is a single-byte character */ - while( *zString - && patternCompare(&zPattern[-1],zString,pInfo,matchOther)==0 ){ - SQLITE_SKIP_UTF8(zString); - } - return *zString!=0; - } - } - - /* At this point variable c contains the first character of the - ** pattern string past the "*". Search in the input string for the - ** first matching character and recursively contine the match from - ** that point. - ** - ** For a case-insensitive search, set variable cx to be the same as - ** c but in the other case and search the input string for either - ** c or cx. - */ - if( c<=0x80 ){ - u32 cx; - if( noCase ){ - cx = sqlite3Toupper(c); - c = sqlite3Tolower(c); - }else{ - cx = c; - } - while( (c2 = *(zString++))!=0 ){ - if( c2!=c && c2!=cx ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1; - } - }else{ - while( (c2 = Utf8Read(zString))!=0 ){ - if( c2!=c ) continue; - if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1; - } - } - return 0; - } - if( c==matchOther ){ - if( pInfo->matchSet==0 ){ - c = sqlite3Utf8Read(&zPattern); - if( c==0 ) return 0; - zEscaped = zPattern; - }else{ - u32 prior_c = 0; - int seen = 0; - int invert = 0; - c = sqlite3Utf8Read(&zString); - if( c==0 ) return 0; - c2 = sqlite3Utf8Read(&zPattern); - if( c2=='^' ){ - invert = 1; - c2 = sqlite3Utf8Read(&zPattern); - } - if( c2==']' ){ - if( c==']' ) seen = 1; - c2 = sqlite3Utf8Read(&zPattern); - } - while( c2 && c2!=']' ){ - if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ - c2 = sqlite3Utf8Read(&zPattern); - if( c>=prior_c && c<=c2 ) seen = 1; - prior_c = 0; - }else{ - if( c==c2 ){ - seen = 1; - } - prior_c = c2; - } - c2 = sqlite3Utf8Read(&zPattern); - } - if( c2==0 || (seen ^ invert)==0 ){ - return 0; - } - continue; - } - } - c2 = Utf8Read(zString); - if( c==c2 ) continue; - if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ - continue; - } - if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; - return 0; - } - return *zString==0; -} - -/* -** The sqlite3_strglob() interface. -*/ -SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ - return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0; -} - -/* -** The sqlite3_strlike() interface. -*/ -SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ - return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0; -} - -/* -** Count the number of times that the LIKE operator (or GLOB which is -** just a variation of LIKE) gets called. This is used for testing -** only. -*/ -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_like_count = 0; -#endif - - -/* -** Implementation of the like() SQL function. This function implements -** the build-in LIKE operator. The first argument to the function is the -** pattern and the second argument is the string. So, the SQL statements: -** -** A LIKE B -** -** is implemented as like(B,A). -** -** This same function (with a different compareInfo structure) computes -** the GLOB operator. -*/ -static void likeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zA, *zB; - u32 escape; - int nPat; - sqlite3 *db = sqlite3_context_db_handle(context); - struct compareInfo *pInfo = sqlite3_user_data(context); - -#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( sqlite3_value_type(argv[0])==SQLITE_BLOB - || sqlite3_value_type(argv[1])==SQLITE_BLOB - ){ -#ifdef SQLITE_TEST - sqlite3_like_count++; -#endif - sqlite3_result_int(context, 0); - return; - } -#endif - zB = sqlite3_value_text(argv[0]); - zA = sqlite3_value_text(argv[1]); - - /* Limit the length of the LIKE or GLOB pattern to avoid problems - ** of deep recursion and N*N behavior in patternCompare(). - */ - nPat = sqlite3_value_bytes(argv[0]); - testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); - testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); - if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ - sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); - return; - } - assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ - - if( argc==3 ){ - /* The escape character string must consist of a single UTF-8 character. - ** Otherwise, return an error. - */ - const unsigned char *zEsc = sqlite3_value_text(argv[2]); - if( zEsc==0 ) return; - if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ - sqlite3_result_error(context, - "ESCAPE expression must be a single character", -1); - return; - } - escape = sqlite3Utf8Read(&zEsc); - }else{ - escape = pInfo->matchSet; - } - if( zA && zB ){ -#ifdef SQLITE_TEST - sqlite3_like_count++; -#endif - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)); - } -} - -/* -** Implementation of the NULLIF(x,y) function. The result is the first -** argument if the arguments are different. The result is NULL if the -** arguments are equal to each other. -*/ -static void nullifFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - CollSeq *pColl = sqlite3GetFuncCollSeq(context); - UNUSED_PARAMETER(NotUsed); - if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ - sqlite3_result_value(context, argv[0]); - } -} - -/* -** Implementation of the sqlite_version() function. The result is the version -** of the SQLite library that is running. -*/ -static void versionFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **NotUsed2 -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - /* IMP: R-48699-48617 This function is an SQL wrapper around the - ** sqlite3_libversion() C-interface. */ - sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); -} - -/* -** Implementation of the sqlite_source_id() function. The result is a string -** that identifies the particular version of the source code used to build -** SQLite. -*/ -static void sourceidFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **NotUsed2 -){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - /* IMP: R-24470-31136 This function is an SQL wrapper around the - ** sqlite3_sourceid() C interface. */ - sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); -} - -/* -** Implementation of the sqlite_log() function. This is a wrapper around -** sqlite3_log(). The return value is NULL. The function exists purely for -** its side-effects. -*/ -static void errlogFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(context); - sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); -} - -/* -** Implementation of the sqlite_compileoption_used() function. -** The result is an integer that identifies if the compiler option -** was used to build SQLite. -*/ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -static void compileoptionusedFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *zOptName; - assert( argc==1 ); - UNUSED_PARAMETER(argc); - /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL - ** function is a wrapper around the sqlite3_compileoption_used() C/C++ - ** function. - */ - if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ - sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); - } -} -#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ - -/* -** Implementation of the sqlite_compileoption_get() function. -** The result is a string that identifies the compiler options -** used to build SQLite. -*/ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -static void compileoptiongetFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int n; - assert( argc==1 ); - UNUSED_PARAMETER(argc); - /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function - ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. - */ - n = sqlite3_value_int(argv[0]); - sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); -} -#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ - -/* Array for converting from half-bytes (nybbles) into ASCII hex -** digits. */ -static const char hexdigits[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -/* -** Implementation of the QUOTE() function. This function takes a single -** argument. If the argument is numeric, the return value is the same as -** the argument. If the argument is NULL, the return value is the string -** "NULL". Otherwise, the argument is enclosed in single quotes with -** single-quote escapes. -*/ -static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_FLOAT: { - double r1, r2; - char zBuf[50]; - r1 = sqlite3_value_double(argv[0]); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); - sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); - if( r1!=r2 ){ - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); - } - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); - break; - } - case SQLITE_INTEGER: { - sqlite3_result_value(context, argv[0]); - break; - } - case SQLITE_BLOB: { - char *zText = 0; - char const *zBlob = sqlite3_value_blob(argv[0]); - int nBlob = sqlite3_value_bytes(argv[0]); - assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); - if( zText ){ - int i; - for(i=0; i>4)&0x0F]; - zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; - } - zText[(nBlob*2)+2] = '\''; - zText[(nBlob*2)+3] = '\0'; - zText[0] = 'X'; - zText[1] = '\''; - sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); - sqlite3_free(zText); - } - break; - } - case SQLITE_TEXT: { - int i,j; - u64 n; - const unsigned char *zArg = sqlite3_value_text(argv[0]); - char *z; - - if( zArg==0 ) return; - for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } - z = contextMalloc(context, ((i64)i)+((i64)n)+3); - if( z ){ - z[0] = '\''; - for(i=0, j=1; zArg[i]; i++){ - z[j++] = zArg[i]; - if( zArg[i]=='\'' ){ - z[j++] = '\''; - } - } - z[j++] = '\''; - z[j] = 0; - sqlite3_result_text(context, z, j, sqlite3_free); - } - break; - } - default: { - assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); - sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); - break; - } - } -} - -/* -** The unicode() function. Return the integer unicode code-point value -** for the first character of the input string. -*/ -static void unicodeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *z = sqlite3_value_text(argv[0]); - (void)argc; - if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z)); -} - -/* -** The char() function takes zero or more arguments, each of which is -** an integer. It constructs a string where each character of the string -** is the unicode character for the corresponding integer argument. -*/ -static void charFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - unsigned char *z, *zOut; - int i; - zOut = z = sqlite3_malloc64( argc*4+1 ); - if( z==0 ){ - sqlite3_result_error_nomem(context); - return; - } - for(i=0; i0x10ffff ) x = 0xfffd; - c = (unsigned)(x & 0x1fffff); - if( c<0x00080 ){ - *zOut++ = (u8)(c&0xFF); - }else if( c<0x00800 ){ - *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); - *zOut++ = 0x80 + (u8)(c & 0x3F); - }else if( c<0x10000 ){ - *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); - *zOut++ = 0x80 + (u8)(c & 0x3F); - }else{ - *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); - *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); - *zOut++ = 0x80 + (u8)(c & 0x3F); - } \ - } - sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); -} - -/* -** The hex() function. Interpret the argument as a blob. Return -** a hexadecimal rendering as text. -*/ -static void hexFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int i, n; - const unsigned char *pBlob; - char *zHex, *z; - assert( argc==1 ); - UNUSED_PARAMETER(argc); - pBlob = sqlite3_value_blob(argv[0]); - n = sqlite3_value_bytes(argv[0]); - assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - z = zHex = contextMalloc(context, ((i64)n)*2 + 1); - if( zHex ){ - for(i=0; i>4)&0xf]; - *(z++) = hexdigits[c&0xf]; - } - *z = 0; - sqlite3_result_text(context, zHex, n*2, sqlite3_free); - } -} - -/* -** The zeroblob(N) function returns a zero-filled blob of size N bytes. -*/ -static void zeroblobFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - i64 n; - int rc; - assert( argc==1 ); - UNUSED_PARAMETER(argc); - n = sqlite3_value_int64(argv[0]); - if( n<0 ) n = 0; - rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */ - if( rc ){ - sqlite3_result_error_code(context, rc); - } -} - -/* -** The replace() function. Three arguments are all strings: call -** them A, B, and C. The result is also a string which is derived -** from A by replacing every occurrence of B with C. The match -** must be exact. Collating sequences are not used. -*/ -static void replaceFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zStr; /* The input string A */ - const unsigned char *zPattern; /* The pattern string B */ - const unsigned char *zRep; /* The replacement string C */ - unsigned char *zOut; /* The output */ - int nStr; /* Size of zStr */ - int nPattern; /* Size of zPattern */ - int nRep; /* Size of zRep */ - i64 nOut; /* Maximum size of zOut */ - int loopLimit; /* Last zStr[] that might match zPattern[] */ - int i, j; /* Loop counters */ - - assert( argc==3 ); - UNUSED_PARAMETER(argc); - zStr = sqlite3_value_text(argv[0]); - if( zStr==0 ) return; - nStr = sqlite3_value_bytes(argv[0]); - assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */ - zPattern = sqlite3_value_text(argv[1]); - if( zPattern==0 ){ - assert( sqlite3_value_type(argv[1])==SQLITE_NULL - || sqlite3_context_db_handle(context)->mallocFailed ); - return; - } - if( zPattern[0]==0 ){ - assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); - sqlite3_result_value(context, argv[0]); - return; - } - nPattern = sqlite3_value_bytes(argv[1]); - assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ - zRep = sqlite3_value_text(argv[2]); - if( zRep==0 ) return; - nRep = sqlite3_value_bytes(argv[2]); - assert( zRep==sqlite3_value_text(argv[2]) ); - nOut = nStr + 1; - assert( nOutaLimit[SQLITE_LIMIT_LENGTH] ); - testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); - if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(context); - sqlite3_free(zOut); - return; - } - zOld = zOut; - zOut = sqlite3_realloc64(zOut, (int)nOut); - if( zOut==0 ){ - sqlite3_result_error_nomem(context); - sqlite3_free(zOld); - return; - } - memcpy(&zOut[j], zRep, nRep); - j += nRep; - i += nPattern-1; - } - } - assert( j+nStr-i+1==nOut ); - memcpy(&zOut[j], &zStr[i], nStr-i); - j += nStr - i; - assert( j<=nOut ); - zOut[j] = 0; - sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); -} - -/* -** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. -** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. -*/ -static void trimFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zIn; /* Input string */ - const unsigned char *zCharSet; /* Set of characters to trim */ - int nIn; /* Number of bytes in input */ - int flags; /* 1: trimleft 2: trimright 3: trim */ - int i; /* Loop counter */ - unsigned char *aLen = 0; /* Length of each character in zCharSet */ - unsigned char **azChar = 0; /* Individual characters in zCharSet */ - int nChar; /* Number of characters in zCharSet */ - - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ - return; - } - zIn = sqlite3_value_text(argv[0]); - if( zIn==0 ) return; - nIn = sqlite3_value_bytes(argv[0]); - assert( zIn==sqlite3_value_text(argv[0]) ); - if( argc==1 ){ - static const unsigned char lenOne[] = { 1 }; - static unsigned char * const azOne[] = { (u8*)" " }; - nChar = 1; - aLen = (u8*)lenOne; - azChar = (unsigned char **)azOne; - zCharSet = 0; - }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ - return; - }else{ - const unsigned char *z; - for(z=zCharSet, nChar=0; *z; nChar++){ - SQLITE_SKIP_UTF8(z); - } - if( nChar>0 ){ - azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); - if( azChar==0 ){ - return; - } - aLen = (unsigned char*)&azChar[nChar]; - for(z=zCharSet, nChar=0; *z; nChar++){ - azChar[nChar] = (unsigned char *)z; - SQLITE_SKIP_UTF8(z); - aLen[nChar] = (u8)(z - azChar[nChar]); - } - } - } - if( nChar>0 ){ - flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); - if( flags & 1 ){ - while( nIn>0 ){ - int len = 0; - for(i=0; i=nChar ) break; - zIn += len; - nIn -= len; - } - } - if( flags & 2 ){ - while( nIn>0 ){ - int len = 0; - for(i=0; i=nChar ) break; - nIn -= len; - } - } - if( zCharSet ){ - sqlite3_free(azChar); - } - } - sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); -} - - -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -/* -** The "unknown" function is automatically substituted in place of -** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN -** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. -** When the "sqlite3" command-line shell is built using this functionality, -** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries -** involving application-defined functions to be examined in a generic -** sqlite3 shell. -*/ -static void unknownFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - /* no-op */ -} -#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ - - -/* IMP: R-25361-16150 This function is omitted from SQLite by default. It -** is only available if the SQLITE_SOUNDEX compile-time option is used -** when SQLite is built. -*/ -#ifdef SQLITE_SOUNDEX -/* -** Compute the soundex encoding of a word. -** -** IMP: R-59782-00072 The soundex(X) function returns a string that is the -** soundex encoding of the string X. -*/ -static void soundexFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - char zResult[8]; - const u8 *zIn; - int i, j; - static const unsigned char iCode[] = { - 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, - 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, - 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, - 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, - 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, - }; - assert( argc==1 ); - zIn = (u8*)sqlite3_value_text(argv[0]); - if( zIn==0 ) zIn = (u8*)""; - for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} - if( zIn[i] ){ - u8 prevcode = iCode[zIn[i]&0x7f]; - zResult[0] = sqlite3Toupper(zIn[i]); - for(j=1; j<4 && zIn[i]; i++){ - int code = iCode[zIn[i]&0x7f]; - if( code>0 ){ - if( code!=prevcode ){ - prevcode = code; - zResult[j++] = code + '0'; - } - }else{ - prevcode = 0; - } - } - while( j<4 ){ - zResult[j++] = '0'; - } - zResult[j] = 0; - sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); - }else{ - /* IMP: R-64894-50321 The string "?000" is returned if the argument - ** is NULL or contains no ASCII alphabetic characters. */ - sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); - } -} -#endif /* SQLITE_SOUNDEX */ - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** A function that loads a shared-library extension then returns NULL. -*/ -static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ - const char *zFile = (const char *)sqlite3_value_text(argv[0]); - const char *zProc; - sqlite3 *db = sqlite3_context_db_handle(context); - char *zErrMsg = 0; - - /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc - ** flag is set. See the sqlite3_enable_load_extension() API. - */ - if( (db->flags & SQLITE_LoadExtFunc)==0 ){ - sqlite3_result_error(context, "not authorized", -1); - return; - } - - if( argc==2 ){ - zProc = (const char *)sqlite3_value_text(argv[1]); - }else{ - zProc = 0; - } - if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ - sqlite3_result_error(context, zErrMsg, -1); - sqlite3_free(zErrMsg); - } -} -#endif - - -/* -** An instance of the following structure holds the context of a -** sum() or avg() aggregate computation. -*/ -typedef struct SumCtx SumCtx; -struct SumCtx { - double rSum; /* Floating point sum */ - i64 iSum; /* Integer sum */ - i64 cnt; /* Number of elements summed */ - u8 overflow; /* True if integer overflow seen */ - u8 approx; /* True if non-integer value was input to the sum */ -}; - -/* -** Routines used to compute the sum, average, and total. -** -** The SUM() function follows the (broken) SQL standard which means -** that it returns NULL if it sums over no inputs. TOTAL returns -** 0.0 in that case. In addition, TOTAL always returns a float where -** SUM might return an integer if it never encounters a floating point -** value. TOTAL never fails, but SUM might through an exception if -** it overflows an integer. -*/ -static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ - SumCtx *p; - int type; - assert( argc==1 ); - UNUSED_PARAMETER(argc); - p = sqlite3_aggregate_context(context, sizeof(*p)); - type = sqlite3_value_numeric_type(argv[0]); - if( p && type!=SQLITE_NULL ){ - p->cnt++; - if( type==SQLITE_INTEGER ){ - i64 v = sqlite3_value_int64(argv[0]); - p->rSum += v; - if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ - p->overflow = 1; - } - }else{ - p->rSum += sqlite3_value_double(argv[0]); - p->approx = 1; - } - } -} -static void sumFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - if( p && p->cnt>0 ){ - if( p->overflow ){ - sqlite3_result_error(context,"integer overflow",-1); - }else if( p->approx ){ - sqlite3_result_double(context, p->rSum); - }else{ - sqlite3_result_int64(context, p->iSum); - } - } -} -static void avgFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - if( p && p->cnt>0 ){ - sqlite3_result_double(context, p->rSum/(double)p->cnt); - } -} -static void totalFinalize(sqlite3_context *context){ - SumCtx *p; - p = sqlite3_aggregate_context(context, 0); - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - sqlite3_result_double(context, p ? p->rSum : (double)0); -} - -/* -** The following structure keeps track of state information for the -** count() aggregate function. -*/ -typedef struct CountCtx CountCtx; -struct CountCtx { - i64 n; -}; - -/* -** Routines to implement the count() aggregate function. -*/ -static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ - CountCtx *p; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ - p->n++; - } - -#ifndef SQLITE_OMIT_DEPRECATED - /* The sqlite3_aggregate_count() function is deprecated. But just to make - ** sure it still operates correctly, verify that its count agrees with our - ** internal count when using count(*) and when the total count can be - ** expressed as a 32-bit integer. */ - assert( argc==1 || p==0 || p->n>0x7fffffff - || p->n==sqlite3_aggregate_count(context) ); -#endif -} -static void countFinalize(sqlite3_context *context){ - CountCtx *p; - p = sqlite3_aggregate_context(context, 0); - sqlite3_result_int64(context, p ? p->n : 0); -} - -/* -** Routines to implement min() and max() aggregate functions. -*/ -static void minmaxStep( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - Mem *pArg = (Mem *)argv[0]; - Mem *pBest; - UNUSED_PARAMETER(NotUsed); - - pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); - if( !pBest ) return; - - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ - if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); - }else if( pBest->flags ){ - int max; - int cmp; - CollSeq *pColl = sqlite3GetFuncCollSeq(context); - /* This step function is used for both the min() and max() aggregates, - ** the only difference between the two being that the sense of the - ** comparison is inverted. For the max() aggregate, the - ** sqlite3_user_data() function returns (void *)-1. For min() it - ** returns (void *)db, where db is the sqlite3* database pointer. - ** Therefore the next statement sets variable 'max' to 1 for the max() - ** aggregate, or 0 for min(). - */ - max = sqlite3_user_data(context)!=0; - cmp = sqlite3MemCompare(pBest, pArg, pColl); - if( (max && cmp<0) || (!max && cmp>0) ){ - sqlite3VdbeMemCopy(pBest, pArg); - }else{ - sqlite3SkipAccumulatorLoad(context); - } - }else{ - pBest->db = sqlite3_context_db_handle(context); - sqlite3VdbeMemCopy(pBest, pArg); - } -} -static void minMaxFinalize(sqlite3_context *context){ - sqlite3_value *pRes; - pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); - if( pRes ){ - if( pRes->flags ){ - sqlite3_result_value(context, pRes); - } - sqlite3VdbeMemRelease(pRes); - } -} - -/* -** group_concat(EXPR, ?SEPARATOR?) -*/ -static void groupConcatStep( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *zVal; - StrAccum *pAccum; - const char *zSep; - int nVal, nSep; - assert( argc==1 || argc==2 ); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); - - if( pAccum ){ - sqlite3 *db = sqlite3_context_db_handle(context); - int firstTerm = pAccum->mxAlloc==0; - pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; - if( !firstTerm ){ - if( argc==2 ){ - zSep = (char*)sqlite3_value_text(argv[1]); - nSep = sqlite3_value_bytes(argv[1]); - }else{ - zSep = ","; - nSep = 1; - } - if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); - } - zVal = (char*)sqlite3_value_text(argv[0]); - nVal = sqlite3_value_bytes(argv[0]); - if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); - } -} -static void groupConcatFinalize(sqlite3_context *context){ - StrAccum *pAccum; - pAccum = sqlite3_aggregate_context(context, 0); - if( pAccum ){ - if( pAccum->accError==STRACCUM_TOOBIG ){ - sqlite3_result_error_toobig(context); - }else if( pAccum->accError==STRACCUM_NOMEM ){ - sqlite3_result_error_nomem(context); - }else{ - sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, - sqlite3_free); - } - } -} - -/* -** This routine does per-connection function registration. Most -** of the built-in functions above are part of the global function set. -** This routine only deals with those that are not global. -*/ -SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ - int rc = sqlite3_overload_function(db, "MATCH", 2); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(db); - } -} - -/* -** Set the LIKEOPT flag on the 2-argument function with the given name. -*/ -static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ - FuncDef *pDef; - pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0); - if( ALWAYS(pDef) ){ - pDef->funcFlags |= flagVal; - } -} - -/* -** Register the built-in LIKE and GLOB functions. The caseSensitive -** parameter determines whether or not the LIKE operator is case -** sensitive. GLOB is always case sensitive. -*/ -SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ - struct compareInfo *pInfo; - if( caseSensitive ){ - pInfo = (struct compareInfo*)&likeInfoAlt; - }else{ - pInfo = (struct compareInfo*)&likeInfoNorm; - } - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); - sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, - (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); - setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); - setLikeOptFlag(db, "like", - caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); -} - -/* -** pExpr points to an expression which implements a function. If -** it is appropriate to apply the LIKE optimization to that function -** then set aWc[0] through aWc[2] to the wildcard characters and -** return TRUE. If the function is not a LIKE-style function then -** return FALSE. -** -** *pIsNocase is set to true if uppercase and lowercase are equivalent for -** the function (default for LIKE). If the function makes the distinction -** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to -** false. -*/ -SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ - FuncDef *pDef; - if( pExpr->op!=TK_FUNCTION - || !pExpr->x.pList - || pExpr->x.pList->nExpr!=2 - ){ - return 0; - } - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0); - if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ - return 0; - } - - /* The memcpy() statement assumes that the wildcard characters are - ** the first three statements in the compareInfo structure. The - ** asserts() that follow verify that assumption - */ - memcpy(aWc, pDef->pUserData, 3); - assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); - assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); - assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); - *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0; - return 1; -} - -/* -** All of the FuncDef structures in the aBuiltinFunc[] array above -** to the global function hash table. This occurs at start-time (as -** a consequence of calling sqlite3_initialize()). -** -** After this routine runs -*/ -SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ - /* - ** The following array holds FuncDef structures for all of the functions - ** defined in this file. - ** - ** The array cannot be constant since changes are made to the - ** FuncDef.pHash elements at start-time. The elements of this array - ** are read-only after initialization is complete. - ** - ** For peak efficiency, put the most frequently used function last. - */ - static FuncDef aBuiltinFunc[] = { -#ifdef SQLITE_SOUNDEX - FUNCTION(soundex, 1, 0, 0, soundexFunc ), -#endif -#ifndef SQLITE_OMIT_LOAD_EXTENSION - VFUNCTION(load_extension, 1, 0, 0, loadExt ), - VFUNCTION(load_extension, 2, 0, 0, loadExt ), -#endif -#if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), -#endif -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), - DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), -#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ - FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION(ltrim, 1, 1, 0, trimFunc ), - FUNCTION(ltrim, 2, 1, 0, trimFunc ), - FUNCTION(rtrim, 1, 2, 0, trimFunc ), - FUNCTION(rtrim, 2, 2, 0, trimFunc ), - FUNCTION(trim, 1, 3, 0, trimFunc ), - FUNCTION(trim, 2, 3, 0, trimFunc ), - FUNCTION(min, -1, 0, 1, minmaxFunc ), - FUNCTION(min, 0, 0, 1, 0 ), - AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, - SQLITE_FUNC_MINMAX ), - FUNCTION(max, -1, 1, 1, minmaxFunc ), - FUNCTION(max, 0, 1, 1, 0 ), - AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, - SQLITE_FUNC_MINMAX ), - FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), - FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), - FUNCTION(instr, 2, 0, 0, instrFunc ), - FUNCTION(printf, -1, 0, 0, printfFunc ), - FUNCTION(unicode, 1, 0, 0, unicodeFunc ), - FUNCTION(char, -1, 0, 0, charFunc ), - FUNCTION(abs, 1, 0, 0, absFunc ), -#ifndef SQLITE_OMIT_FLOATING_POINT - FUNCTION(round, 1, 0, 0, roundFunc ), - FUNCTION(round, 2, 0, 0, roundFunc ), -#endif - FUNCTION(upper, 1, 0, 0, upperFunc ), - FUNCTION(lower, 1, 0, 0, lowerFunc ), - FUNCTION(hex, 1, 0, 0, hexFunc ), - FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), - VFUNCTION(random, 0, 0, 0, randomFunc ), - VFUNCTION(randomblob, 1, 0, 0, randomBlob ), - FUNCTION(nullif, 2, 0, 1, nullifFunc ), - DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), - DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), - FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), - FUNCTION(quote, 1, 0, 0, quoteFunc ), - VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), - VFUNCTION(changes, 0, 0, 0, changes ), - VFUNCTION(total_changes, 0, 0, 0, total_changes ), - FUNCTION(replace, 3, 0, 0, replaceFunc ), - FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), - FUNCTION(substr, 2, 0, 0, substrFunc ), - FUNCTION(substr, 3, 0, 0, substrFunc ), - AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), - AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), - AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), - AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, - SQLITE_FUNC_COUNT ), - AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), - AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), - AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), - - LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), -#ifdef SQLITE_CASE_SENSITIVE_LIKE - LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), - LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), -#else - LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), - LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), -#endif -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - FUNCTION(unknown, -1, 0, 0, unknownFunc ), -#endif - FUNCTION(coalesce, 1, 0, 0, 0 ), - FUNCTION(coalesce, 0, 0, 0, 0 ), - FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), - }; -#ifndef SQLITE_OMIT_ALTERTABLE - sqlite3AlterFunctions(); -#endif -#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) - sqlite3AnalyzeFunctions(); -#endif - sqlite3RegisterDateTimeFunctions(); - sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); - -#if 0 /* Enable to print out how the built-in functions are hashed */ - { - int i; - FuncDef *p; - for(i=0; iu.pHash){ - int n = sqlite3Strlen30(p->zName); - int h = p->zName[0] + n; - printf(" %s(%d)", p->zName, h); - } - printf("\n"); - } - } -#endif -} - -/************** End of func.c ************************************************/ -/************** Begin file fkey.c ********************************************/ -/* -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used by the compiler to add foreign key -** support to compiled SQL statements. -*/ -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY -#ifndef SQLITE_OMIT_TRIGGER - -/* -** Deferred and Immediate FKs -** -------------------------- -** -** Foreign keys in SQLite come in two flavours: deferred and immediate. -** If an immediate foreign key constraint is violated, -** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current -** statement transaction rolled back. If a -** deferred foreign key constraint is violated, no action is taken -** immediately. However if the application attempts to commit the -** transaction before fixing the constraint violation, the attempt fails. -** -** Deferred constraints are implemented using a simple counter associated -** with the database handle. The counter is set to zero each time a -** database transaction is opened. Each time a statement is executed -** that causes a foreign key violation, the counter is incremented. Each -** time a statement is executed that removes an existing violation from -** the database, the counter is decremented. When the transaction is -** committed, the commit fails if the current value of the counter is -** greater than zero. This scheme has two big drawbacks: -** -** * When a commit fails due to a deferred foreign key constraint, -** there is no way to tell which foreign constraint is not satisfied, -** or which row it is not satisfied for. -** -** * If the database contains foreign key violations when the -** transaction is opened, this may cause the mechanism to malfunction. -** -** Despite these problems, this approach is adopted as it seems simpler -** than the alternatives. -** -** INSERT operations: -** -** I.1) For each FK for which the table is the child table, search -** the parent table for a match. If none is found increment the -** constraint counter. -** -** I.2) For each FK for which the table is the parent table, -** search the child table for rows that correspond to the new -** row in the parent table. Decrement the counter for each row -** found (as the constraint is now satisfied). -** -** DELETE operations: -** -** D.1) For each FK for which the table is the child table, -** search the parent table for a row that corresponds to the -** deleted row in the child table. If such a row is not found, -** decrement the counter. -** -** D.2) For each FK for which the table is the parent table, search -** the child table for rows that correspond to the deleted row -** in the parent table. For each found increment the counter. -** -** UPDATE operations: -** -** An UPDATE command requires that all 4 steps above are taken, but only -** for FK constraints for which the affected columns are actually -** modified (values must be compared at runtime). -** -** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. -** This simplifies the implementation a bit. -** -** For the purposes of immediate FK constraints, the OR REPLACE conflict -** resolution is considered to delete rows before the new row is inserted. -** If a delete caused by OR REPLACE violates an FK constraint, an exception -** is thrown, even if the FK constraint would be satisfied after the new -** row is inserted. -** -** Immediate constraints are usually handled similarly. The only difference -** is that the counter used is stored as part of each individual statement -** object (struct Vdbe). If, after the statement has run, its immediate -** constraint counter is greater than zero, -** it returns SQLITE_CONSTRAINT_FOREIGNKEY -** and the statement transaction is rolled back. An exception is an INSERT -** statement that inserts a single row only (no triggers). In this case, -** instead of using a counter, an exception is thrown immediately if the -** INSERT violates a foreign key constraint. This is necessary as such -** an INSERT does not open a statement transaction. -** -** TODO: How should dropping a table be handled? How should renaming a -** table be handled? -** -** -** Query API Notes -** --------------- -** -** Before coding an UPDATE or DELETE row operation, the code-generator -** for those two operations needs to know whether or not the operation -** requires any FK processing and, if so, which columns of the original -** row are required by the FK processing VDBE code (i.e. if FKs were -** implemented using triggers, which of the old.* columns would be -** accessed). No information is required by the code-generator before -** coding an INSERT operation. The functions used by the UPDATE/DELETE -** generation code to query for this information are: -** -** sqlite3FkRequired() - Test to see if FK processing is required. -** sqlite3FkOldmask() - Query for the set of required old.* columns. -** -** -** Externally accessible module functions -** -------------------------------------- -** -** sqlite3FkCheck() - Check for foreign key violations. -** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. -** sqlite3FkDelete() - Delete an FKey structure. -*/ - -/* -** VDBE Calling Convention -** ----------------------- -** -** Example: -** -** For the following INSERT statement: -** -** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c); -** INSERT INTO t1 VALUES(1, 2, 3.1); -** -** Register (x): 2 (type integer) -** Register (x+1): 1 (type integer) -** Register (x+2): NULL (type NULL) -** Register (x+3): 3.1 (type real) -*/ - -/* -** A foreign key constraint requires that the key columns in the parent -** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. -** Given that pParent is the parent table for foreign key constraint pFKey, -** search the schema for a unique index on the parent key columns. -** -** If successful, zero is returned. If the parent key is an INTEGER PRIMARY -** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx -** is set to point to the unique index. -** -** If the parent key consists of a single column (the foreign key constraint -** is not a composite foreign key), output variable *paiCol is set to NULL. -** Otherwise, it is set to point to an allocated array of size N, where -** N is the number of columns in the parent key. The first element of the -** array is the index of the child table column that is mapped by the FK -** constraint to the parent table column stored in the left-most column -** of index *ppIdx. The second element of the array is the index of the -** child table column that corresponds to the second left-most column of -** *ppIdx, and so on. -** -** If the required index cannot be found, either because: -** -** 1) The named parent key columns do not exist, or -** -** 2) The named parent key columns do exist, but are not subject to a -** UNIQUE or PRIMARY KEY constraint, or -** -** 3) No parent key columns were provided explicitly as part of the -** foreign key definition, and the parent table does not have a -** PRIMARY KEY, or -** -** 4) No parent key columns were provided explicitly as part of the -** foreign key definition, and the PRIMARY KEY of the parent table -** consists of a different number of columns to the child key in -** the child table. -** -** then non-zero is returned, and a "foreign key mismatch" error loaded -** into pParse. If an OOM error occurs, non-zero is returned and the -** pParse->db->mallocFailed flag is set. -*/ -SQLITE_PRIVATE int sqlite3FkLocateIndex( - Parse *pParse, /* Parse context to store any error in */ - Table *pParent, /* Parent table of FK constraint pFKey */ - FKey *pFKey, /* Foreign key to find index for */ - Index **ppIdx, /* OUT: Unique index on parent table */ - int **paiCol /* OUT: Map of index columns in pFKey */ -){ - Index *pIdx = 0; /* Value to return via *ppIdx */ - int *aiCol = 0; /* Value to return via *paiCol */ - int nCol = pFKey->nCol; /* Number of columns in parent key */ - char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ - - /* The caller is responsible for zeroing output parameters. */ - assert( ppIdx && *ppIdx==0 ); - assert( !paiCol || *paiCol==0 ); - assert( pParse ); - - /* If this is a non-composite (single column) foreign key, check if it - ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx - ** and *paiCol set to zero and return early. - ** - ** Otherwise, for a composite foreign key (more than one column), allocate - ** space for the aiCol array (returned via output parameter *paiCol). - ** Non-composite foreign keys do not require the aiCol array. - */ - if( nCol==1 ){ - /* The FK maps to the IPK if any of the following are true: - ** - ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly - ** mapped to the primary key of table pParent, or - ** 2) The FK is explicitly mapped to a column declared as INTEGER - ** PRIMARY KEY. - */ - if( pParent->iPKey>=0 ){ - if( !zKey ) return 0; - if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; - } - }else if( paiCol ){ - assert( nCol>1 ); - aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); - if( !aiCol ) return 1; - *paiCol = aiCol; - } - - for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){ - /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number - ** of columns. If each indexed column corresponds to a foreign key - ** column of pFKey, then this index is a winner. */ - - if( zKey==0 ){ - /* If zKey is NULL, then this foreign key is implicitly mapped to - ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be - ** identified by the test. */ - if( IsPrimaryKeyIndex(pIdx) ){ - if( aiCol ){ - int i; - for(i=0; iaCol[i].iFrom; - } - break; - } - }else{ - /* If zKey is non-NULL, then this foreign key was declared to - ** map to an explicit list of columns in table pParent. Check if this - ** index matches those columns. Also, check that the index uses - ** the default collation sequences for each column. */ - int i, j; - for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ - const char *zDfltColl; /* Def. collation for column */ - char *zIdxCol; /* Name of indexed column */ - - if( iCol<0 ) break; /* No foreign keys against expression indexes */ - - /* If the index uses a collation sequence that is different from - ** the default collation sequence for the column, this index is - ** unusable. Bail out early in this case. */ - zDfltColl = pParent->aCol[iCol].zColl; - if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; - if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; - - zIdxCol = pParent->aCol[iCol].zName; - for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ - if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; - break; - } - } - if( j==nCol ) break; - } - if( i==nCol ) break; /* pIdx is usable */ - } - } - } - - if( !pIdx ){ - if( !pParse->disableTriggers ){ - sqlite3ErrorMsg(pParse, - "foreign key mismatch - \"%w\" referencing \"%w\"", - pFKey->pFrom->zName, pFKey->zTo); - } - sqlite3DbFree(pParse->db, aiCol); - return 1; - } - - *ppIdx = pIdx; - return 0; -} - -/* -** This function is called when a row is inserted into or deleted from the -** child table of foreign key constraint pFKey. If an SQL UPDATE is executed -** on the child table of pFKey, this function is invoked twice for each row -** affected - once to "delete" the old row, and then again to "insert" the -** new row. -** -** Each time it is called, this function generates VDBE code to locate the -** row in the parent table that corresponds to the row being inserted into -** or deleted from the child table. If the parent row can be found, no -** special action is taken. Otherwise, if the parent row can *not* be -** found in the parent table: -** -** Operation | FK type | Action taken -** -------------------------------------------------------------------------- -** INSERT immediate Increment the "immediate constraint counter". -** -** DELETE immediate Decrement the "immediate constraint counter". -** -** INSERT deferred Increment the "deferred constraint counter". -** -** DELETE deferred Decrement the "deferred constraint counter". -** -** These operations are identified in the comment at the top of this file -** (fkey.c) as "I.1" and "D.1". -*/ -static void fkLookupParent( - Parse *pParse, /* Parse context */ - int iDb, /* Index of database housing pTab */ - Table *pTab, /* Parent table of FK pFKey */ - Index *pIdx, /* Unique index on parent key columns in pTab */ - FKey *pFKey, /* Foreign key constraint */ - int *aiCol, /* Map from parent key columns to child table columns */ - int regData, /* Address of array containing child table row */ - int nIncr, /* Increment constraint counter by this */ - int isIgnore /* If true, pretend pTab contains all NULL values */ -){ - int i; /* Iterator variable */ - Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ - int iCur = pParse->nTab - 1; /* Cursor number to use */ - int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ - - /* If nIncr is less than zero, then check at runtime if there are any - ** outstanding constraints to resolve. If there are not, there is no need - ** to check if deleting this row resolves any outstanding violations. - ** - ** Check if any of the key columns in the child table row are NULL. If - ** any are, then the constraint is considered satisfied. No need to - ** search for a matching row in the parent table. */ - if( nIncr<0 ){ - sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); - VdbeCoverage(v); - } - for(i=0; inCol; i++){ - int iReg = aiCol[i] + regData + 1; - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); - } - - if( isIgnore==0 ){ - if( pIdx==0 ){ - /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY - ** column of the parent table (table pTab). */ - int iMustBeInt; /* Address of MustBeInt instruction */ - int regTemp = sqlite3GetTempReg(pParse); - - /* Invoke MustBeInt to coerce the child key value to an integer (i.e. - ** apply the affinity of the parent key). If this fails, then there - ** is no matching parent key. Before using MustBeInt, make a copy of - ** the value. Otherwise, the value inserted into the child key column - ** will have INTEGER affinity applied to it, which may not be correct. */ - sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); - iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); - VdbeCoverage(v); - - /* If the parent table is the same as the child table, and we are about - ** to increment the constraint-counter (i.e. this is an INSERT operation), - ** then check if the row being inserted matches itself. If so, do not - ** increment the constraint-counter. */ - if( pTab==pFKey->pFrom && nIncr==1 ){ - sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - } - - sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); - sqlite3VdbeGoto(v, iOk); - sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); - sqlite3VdbeJumpHere(v, iMustBeInt); - sqlite3ReleaseTempReg(pParse, regTemp); - }else{ - int nCol = pFKey->nCol; - int regTemp = sqlite3GetTempRange(pParse, nCol); - int regRec = sqlite3GetTempReg(pParse); - - sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - for(i=0; ipFrom && nIncr==1 ){ - int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; - for(i=0; iaiColumn[i]+1+regData; - assert( pIdx->aiColumn[i]>=0 ); - assert( aiCol[i]!=pTab->iPKey ); - if( pIdx->aiColumn[i]==pTab->iPKey ){ - /* The parent key is a composite key that includes the IPK column */ - iParent = regData; - } - sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); - } - sqlite3VdbeGoto(v, iOk); - } - - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, - sqlite3IndexAffinityStr(pParse->db,pIdx), nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); - - sqlite3ReleaseTempReg(pParse, regRec); - sqlite3ReleaseTempRange(pParse, regTemp, nCol); - } - } - - if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) - && !pParse->pToplevel - && !pParse->isMultiWrite - ){ - /* Special case: If this is an INSERT statement that will insert exactly - ** one row into the table, raise a constraint immediately instead of - ** incrementing a counter. This is necessary as the VM code is being - ** generated for will not open a statement transaction. */ - assert( nIncr==1 ); - sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, - OE_Abort, 0, P4_STATIC, P5_ConstraintFK); - }else{ - if( nIncr>0 && pFKey->isDeferred==0 ){ - sqlite3MayAbort(pParse); - } - sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); - } - - sqlite3VdbeResolveLabel(v, iOk); - sqlite3VdbeAddOp1(v, OP_Close, iCur); -} - - -/* -** Return an Expr object that refers to a memory register corresponding -** to column iCol of table pTab. -** -** regBase is the first of an array of register that contains the data -** for pTab. regBase itself holds the rowid. regBase+1 holds the first -** column. regBase+2 holds the second column, and so forth. -*/ -static Expr *exprTableRegister( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* The table whose content is at r[regBase]... */ - int regBase, /* Contents of table pTab */ - i16 iCol /* Which column of pTab is desired */ -){ - Expr *pExpr; - Column *pCol; - const char *zColl; - sqlite3 *db = pParse->db; - - pExpr = sqlite3Expr(db, TK_REGISTER, 0); - if( pExpr ){ - if( iCol>=0 && iCol!=pTab->iPKey ){ - pCol = &pTab->aCol[iCol]; - pExpr->iTable = regBase + iCol + 1; - pExpr->affinity = pCol->affinity; - zColl = pCol->zColl; - if( zColl==0 ) zColl = db->pDfltColl->zName; - pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); - }else{ - pExpr->iTable = regBase; - pExpr->affinity = SQLITE_AFF_INTEGER; - } - } - return pExpr; -} - -/* -** Return an Expr object that refers to column iCol of table pTab which -** has cursor iCur. -*/ -static Expr *exprTableColumn( - sqlite3 *db, /* The database connection */ - Table *pTab, /* The table whose column is desired */ - int iCursor, /* The open cursor on the table */ - i16 iCol /* The column that is wanted */ -){ - Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); - if( pExpr ){ - pExpr->pTab = pTab; - pExpr->iTable = iCursor; - pExpr->iColumn = iCol; - } - return pExpr; -} - -/* -** This function is called to generate code executed when a row is deleted -** from the parent table of foreign key constraint pFKey and, if pFKey is -** deferred, when a row is inserted into the same table. When generating -** code for an SQL UPDATE operation, this function may be called twice - -** once to "delete" the old row and once to "insert" the new row. -** -** Parameter nIncr is passed -1 when inserting a row (as this may decrease -** the number of FK violations in the db) or +1 when deleting one (as this -** may increase the number of FK constraint problems). -** -** The code generated by this function scans through the rows in the child -** table that correspond to the parent table row being deleted or inserted. -** For each child row found, one of the following actions is taken: -** -** Operation | FK type | Action taken -** -------------------------------------------------------------------------- -** DELETE immediate Increment the "immediate constraint counter". -** Or, if the ON (UPDATE|DELETE) action is RESTRICT, -** throw a "FOREIGN KEY constraint failed" exception. -** -** INSERT immediate Decrement the "immediate constraint counter". -** -** DELETE deferred Increment the "deferred constraint counter". -** Or, if the ON (UPDATE|DELETE) action is RESTRICT, -** throw a "FOREIGN KEY constraint failed" exception. -** -** INSERT deferred Decrement the "deferred constraint counter". -** -** These operations are identified in the comment at the top of this file -** (fkey.c) as "I.2" and "D.2". -*/ -static void fkScanChildren( - Parse *pParse, /* Parse context */ - SrcList *pSrc, /* The child table to be scanned */ - Table *pTab, /* The parent table */ - Index *pIdx, /* Index on parent covering the foreign key */ - FKey *pFKey, /* The foreign key linking pSrc to pTab */ - int *aiCol, /* Map from pIdx cols to child table cols */ - int regData, /* Parent row data starts here */ - int nIncr /* Amount to increment deferred counter by */ -){ - sqlite3 *db = pParse->db; /* Database handle */ - int i; /* Iterator variable */ - Expr *pWhere = 0; /* WHERE clause to scan with */ - NameContext sNameContext; /* Context used to resolve WHERE clause */ - WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ - int iFkIfZero = 0; /* Address of OP_FkIfZero */ - Vdbe *v = sqlite3GetVdbe(pParse); - - assert( pIdx==0 || pIdx->pTable==pTab ); - assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); - assert( pIdx!=0 || pFKey->nCol==1 ); - assert( pIdx!=0 || HasRowid(pTab) ); - - if( nIncr<0 ){ - iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); - VdbeCoverage(v); - } - - /* Create an Expr object representing an SQL expression like: - ** - ** = AND = ... - ** - ** The collation sequence used for the comparison should be that of - ** the parent key columns. The affinity of the parent key column should - ** be applied to each child key value before the comparison takes place. - */ - for(i=0; inCol; i++){ - Expr *pLeft; /* Value from parent table row */ - Expr *pRight; /* Column ref to child table */ - Expr *pEq; /* Expression (pLeft = pRight) */ - i16 iCol; /* Index of column in child table */ - const char *zCol; /* Name of column in child table */ - - iCol = pIdx ? pIdx->aiColumn[i] : -1; - pLeft = exprTableRegister(pParse, pTab, regData, iCol); - iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; - assert( iCol>=0 ); - zCol = pFKey->pFrom->aCol[iCol].zName; - pRight = sqlite3Expr(db, TK_ID, zCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); - pWhere = sqlite3ExprAnd(db, pWhere, pEq); - } - - /* If the child table is the same as the parent table, then add terms - ** to the WHERE clause that prevent this entry from being scanned. - ** The added WHERE clause terms are like this: - ** - ** $current_rowid!=rowid - ** NOT( $current_a==a AND $current_b==b AND ... ) - ** - ** The first form is used for rowid tables. The second form is used - ** for WITHOUT ROWID tables. In the second form, the primary key is - ** (a,b,...) - */ - if( pTab==pFKey->pFrom && nIncr>0 ){ - Expr *pNe; /* Expression (pLeft != pRight) */ - Expr *pLeft; /* Value from parent table row */ - Expr *pRight; /* Column ref to child table */ - if( HasRowid(pTab) ){ - pLeft = exprTableRegister(pParse, pTab, regData, -1); - pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); - pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); - }else{ - Expr *pEq, *pAll = 0; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - assert( pIdx!=0 ); - for(i=0; inKeyCol; i++){ - i16 iCol = pIdx->aiColumn[i]; - assert( iCol>=0 ); - pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); - pAll = sqlite3ExprAnd(db, pAll, pEq); - } - pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0); - } - pWhere = sqlite3ExprAnd(db, pWhere, pNe); - } - - /* Resolve the references in the WHERE clause. */ - memset(&sNameContext, 0, sizeof(NameContext)); - sNameContext.pSrcList = pSrc; - sNameContext.pParse = pParse; - sqlite3ResolveExprNames(&sNameContext, pWhere); - - /* Create VDBE to loop through the entries in pSrc that match the WHERE - ** clause. For each row found, increment either the deferred or immediate - ** foreign key constraint counter. */ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); - sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); - if( pWInfo ){ - sqlite3WhereEnd(pWInfo); - } - - /* Clean up the WHERE clause constructed above. */ - sqlite3ExprDelete(db, pWhere); - if( iFkIfZero ){ - sqlite3VdbeJumpHere(v, iFkIfZero); - } -} - -/* -** This function returns a linked list of FKey objects (connected by -** FKey.pNextTo) holding all children of table pTab. For example, -** given the following schema: -** -** CREATE TABLE t1(a PRIMARY KEY); -** CREATE TABLE t2(b REFERENCES t1(a); -** -** Calling this function with table "t1" as an argument returns a pointer -** to the FKey structure representing the foreign key constraint on table -** "t2". Calling this function with "t2" as the argument would return a -** NULL pointer (as there are no FK constraints for which t2 is the parent -** table). -*/ -SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ - return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); -} - -/* -** The second argument is a Trigger structure allocated by the -** fkActionTrigger() routine. This function deletes the Trigger structure -** and all of its sub-components. -** -** The Trigger structure or any of its sub-components may be allocated from -** the lookaside buffer belonging to database handle dbMem. -*/ -static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ - if( p ){ - TriggerStep *pStep = p->step_list; - sqlite3ExprDelete(dbMem, pStep->pWhere); - sqlite3ExprListDelete(dbMem, pStep->pExprList); - sqlite3SelectDelete(dbMem, pStep->pSelect); - sqlite3ExprDelete(dbMem, p->pWhen); - sqlite3DbFree(dbMem, p); - } -} - -/* -** This function is called to generate code that runs when table pTab is -** being dropped from the database. The SrcList passed as the second argument -** to this function contains a single entry guaranteed to resolve to -** table pTab. -** -** Normally, no code is required. However, if either -** -** (a) The table is the parent table of a FK constraint, or -** (b) The table is the child table of a deferred FK constraint and it is -** determined at runtime that there are outstanding deferred FK -** constraint violations in the database, -** -** then the equivalent of "DELETE FROM " is executed before dropping -** the table from the database. Triggers are disabled while running this -** DELETE, but foreign key actions are not. -*/ -SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ - sqlite3 *db = pParse->db; - if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ - int iSkip = 0; - Vdbe *v = sqlite3GetVdbe(pParse); - - assert( v ); /* VDBE has already been allocated */ - if( sqlite3FkReferences(pTab)==0 ){ - /* Search for a deferred foreign key constraint for which this table - ** is the child table. If one cannot be found, return without - ** generating any VDBE code. If one can be found, then jump over - ** the entire DELETE if there are no outstanding deferred constraints - ** when this statement is run. */ - FKey *p; - for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; - } - if( !p ) return; - iSkip = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); - } - - pParse->disableTriggers = 1; - sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); - pParse->disableTriggers = 0; - - /* If the DELETE has generated immediate foreign key constraint - ** violations, halt the VDBE and return an error at this point, before - ** any modifications to the schema are made. This is because statement - ** transactions are not able to rollback schema changes. - ** - ** If the SQLITE_DeferFKs flag is set, then this is not required, as - ** the statement transaction will not be rolled back even if FK - ** constraints are violated. - */ - if( (db->flags & SQLITE_DeferFKs)==0 ){ - sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, - OE_Abort, 0, P4_STATIC, P5_ConstraintFK); - } - - if( iSkip ){ - sqlite3VdbeResolveLabel(v, iSkip); - } - } -} - - -/* -** The second argument points to an FKey object representing a foreign key -** for which pTab is the child table. An UPDATE statement against pTab -** is currently being processed. For each column of the table that is -** actually updated, the corresponding element in the aChange[] array -** is zero or greater (if a column is unmodified the corresponding element -** is set to -1). If the rowid column is modified by the UPDATE statement -** the bChngRowid argument is non-zero. -** -** This function returns true if any of the columns that are part of the -** child key for FK constraint *p are modified. -*/ -static int fkChildIsModified( - Table *pTab, /* Table being updated */ - FKey *p, /* Foreign key for which pTab is the child */ - int *aChange, /* Array indicating modified columns */ - int bChngRowid /* True if rowid is modified by this update */ -){ - int i; - for(i=0; inCol; i++){ - int iChildKey = p->aCol[i].iFrom; - if( aChange[iChildKey]>=0 ) return 1; - if( iChildKey==pTab->iPKey && bChngRowid ) return 1; - } - return 0; -} - -/* -** The second argument points to an FKey object representing a foreign key -** for which pTab is the parent table. An UPDATE statement against pTab -** is currently being processed. For each column of the table that is -** actually updated, the corresponding element in the aChange[] array -** is zero or greater (if a column is unmodified the corresponding element -** is set to -1). If the rowid column is modified by the UPDATE statement -** the bChngRowid argument is non-zero. -** -** This function returns true if any of the columns that are part of the -** parent key for FK constraint *p are modified. -*/ -static int fkParentIsModified( - Table *pTab, - FKey *p, - int *aChange, - int bChngRowid -){ - int i; - for(i=0; inCol; i++){ - char *zKey = p->aCol[i].zCol; - int iKey; - for(iKey=0; iKeynCol; iKey++){ - if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ - Column *pCol = &pTab->aCol[iKey]; - if( zKey ){ - if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; - }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ - return 1; - } - } - } - } - return 0; -} - -/* -** Return true if the parser passed as the first argument is being -** used to code a trigger that is really a "SET NULL" action belonging -** to trigger pFKey. -*/ -static int isSetNullAction(Parse *pParse, FKey *pFKey){ - Parse *pTop = sqlite3ParseToplevel(pParse); - if( pTop->pTriggerPrg ){ - Trigger *p = pTop->pTriggerPrg->pTrigger; - if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) - || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) - ){ - return 1; - } - } - return 0; -} - -/* -** This function is called when inserting, deleting or updating a row of -** table pTab to generate VDBE code to perform foreign key constraint -** processing for the operation. -** -** For a DELETE operation, parameter regOld is passed the index of the -** first register in an array of (pTab->nCol+1) registers containing the -** rowid of the row being deleted, followed by each of the column values -** of the row being deleted, from left to right. Parameter regNew is passed -** zero in this case. -** -** For an INSERT operation, regOld is passed zero and regNew is passed the -** first register of an array of (pTab->nCol+1) registers containing the new -** row data. -** -** For an UPDATE operation, this function is called twice. Once before -** the original record is deleted from the table using the calling convention -** described for DELETE. Then again after the original record is deleted -** but before the new record is inserted using the INSERT convention. -*/ -SQLITE_PRIVATE void sqlite3FkCheck( - Parse *pParse, /* Parse context */ - Table *pTab, /* Row is being deleted from this table */ - int regOld, /* Previous row data is stored here */ - int regNew, /* New row data is stored here */ - int *aChange, /* Array indicating UPDATEd columns (or 0) */ - int bChngRowid /* True if rowid is UPDATEd */ -){ - sqlite3 *db = pParse->db; /* Database handle */ - FKey *pFKey; /* Used to iterate through FKs */ - int iDb; /* Index of database containing pTab */ - const char *zDb; /* Name of database containing pTab */ - int isIgnoreErrors = pParse->disableTriggers; - - /* Exactly one of regOld and regNew should be non-zero. */ - assert( (regOld==0)!=(regNew==0) ); - - /* If foreign-keys are disabled, this function is a no-op. */ - if( (db->flags&SQLITE_ForeignKeys)==0 ) return; - - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - zDb = db->aDb[iDb].zDbSName; - - /* Loop through all the foreign key constraints for which pTab is the - ** child table (the table that the foreign key definition is part of). */ - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ - Table *pTo; /* Parent table of foreign key pFKey */ - Index *pIdx = 0; /* Index on key columns in pTo */ - int *aiFree = 0; - int *aiCol; - int iCol; - int i; - int bIgnore = 0; - - if( aChange - && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 - && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 - ){ - continue; - } - - /* Find the parent table of this foreign key. Also find a unique index - ** on the parent key columns in the parent table. If either of these - ** schema items cannot be located, set an error in pParse and return - ** early. */ - if( pParse->disableTriggers ){ - pTo = sqlite3FindTable(db, pFKey->zTo, zDb); - }else{ - pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); - } - if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ - assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); - if( !isIgnoreErrors || db->mallocFailed ) return; - if( pTo==0 ){ - /* If isIgnoreErrors is true, then a table is being dropped. In this - ** case SQLite runs a "DELETE FROM xxx" on the table being dropped - ** before actually dropping it in order to check FK constraints. - ** If the parent table of an FK constraint on the current table is - ** missing, behave as if it is empty. i.e. decrement the relevant - ** FK counter for each row of the current table with non-NULL keys. - */ - Vdbe *v = sqlite3GetVdbe(pParse); - int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; - for(i=0; inCol; i++){ - int iReg = pFKey->aCol[i].iFrom + regOld + 1; - sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); - } - continue; - } - assert( pFKey->nCol==1 || (aiFree && pIdx) ); - - if( aiFree ){ - aiCol = aiFree; - }else{ - iCol = pFKey->aCol[0].iFrom; - aiCol = &iCol; - } - for(i=0; inCol; i++){ - if( aiCol[i]==pTab->iPKey ){ - aiCol[i] = -1; - } - assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Request permission to read the parent key columns. If the - ** authorization callback returns SQLITE_IGNORE, behave as if any - ** values read from the parent table are NULL. */ - if( db->xAuth ){ - int rcauth; - char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; - rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); - bIgnore = (rcauth==SQLITE_IGNORE); - } -#endif - } - - /* Take a shared-cache advisory read-lock on the parent table. Allocate - ** a cursor to use to search the unique index on the parent key columns - ** in the parent table. */ - sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); - pParse->nTab++; - - if( regOld!=0 ){ - /* A row is being removed from the child table. Search for the parent. - ** If the parent does not exist, removing the child row resolves an - ** outstanding foreign key constraint violation. */ - fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore); - } - if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){ - /* A row is being added to the child table. If a parent row cannot - ** be found, adding the child row has violated the FK constraint. - ** - ** If this operation is being performed as part of a trigger program - ** that is actually a "SET NULL" action belonging to this very - ** foreign key, then omit this scan altogether. As all child key - ** values are guaranteed to be NULL, it is not possible for adding - ** this row to cause an FK violation. */ - fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); - } - - sqlite3DbFree(db, aiFree); - } - - /* Loop through all the foreign key constraints that refer to this table. - ** (the "child" constraints) */ - for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ - Index *pIdx = 0; /* Foreign key index for pFKey */ - SrcList *pSrc; - int *aiCol = 0; - - if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ - continue; - } - - if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) - && !pParse->pToplevel && !pParse->isMultiWrite - ){ - assert( regOld==0 && regNew!=0 ); - /* Inserting a single row into a parent table cannot cause (or fix) - ** an immediate foreign key violation. So do nothing in this case. */ - continue; - } - - if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ - if( !isIgnoreErrors || db->mallocFailed ) return; - continue; - } - assert( aiCol || pFKey->nCol==1 ); - - /* Create a SrcList structure containing the child table. We need the - ** child table as a SrcList for sqlite3WhereBegin() */ - pSrc = sqlite3SrcListAppend(db, 0, 0, 0); - if( pSrc ){ - struct SrcList_item *pItem = pSrc->a; - pItem->pTab = pFKey->pFrom; - pItem->zName = pFKey->pFrom->zName; - pItem->pTab->nRef++; - pItem->iCursor = pParse->nTab++; - - if( regNew!=0 ){ - fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); - } - if( regOld!=0 ){ - int eAction = pFKey->aAction[aChange!=0]; - fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); - /* If this is a deferred FK constraint, or a CASCADE or SET NULL - ** action applies, then any foreign key violations caused by - ** removing the parent key will be rectified by the action trigger. - ** So do not set the "may-abort" flag in this case. - ** - ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the - ** may-abort flag will eventually be set on this statement anyway - ** (when this function is called as part of processing the UPDATE - ** within the action trigger). - ** - ** Note 2: At first glance it may seem like SQLite could simply omit - ** all OP_FkCounter related scans when either CASCADE or SET NULL - ** applies. The trouble starts if the CASCADE or SET NULL action - ** trigger causes other triggers or action rules attached to the - ** child table to fire. In these cases the fk constraint counters - ** might be set incorrectly if any OP_FkCounter related scans are - ** omitted. */ - if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ - sqlite3MayAbort(pParse); - } - } - pItem->zName = 0; - sqlite3SrcListDelete(db, pSrc); - } - sqlite3DbFree(db, aiCol); - } -} - -#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) - -/* -** This function is called before generating code to update or delete a -** row contained in table pTab. -*/ -SQLITE_PRIVATE u32 sqlite3FkOldmask( - Parse *pParse, /* Parse context */ - Table *pTab /* Table being modified */ -){ - u32 mask = 0; - if( pParse->db->flags&SQLITE_ForeignKeys ){ - FKey *p; - int i; - for(p=pTab->pFKey; p; p=p->pNextFrom){ - for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); - } - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - Index *pIdx = 0; - sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); - if( pIdx ){ - for(i=0; inKeyCol; i++){ - assert( pIdx->aiColumn[i]>=0 ); - mask |= COLUMN_MASK(pIdx->aiColumn[i]); - } - } - } - } - return mask; -} - - -/* -** This function is called before generating code to update or delete a -** row contained in table pTab. If the operation is a DELETE, then -** parameter aChange is passed a NULL value. For an UPDATE, aChange points -** to an array of size N, where N is the number of columns in table pTab. -** If the i'th column is not modified by the UPDATE, then the corresponding -** entry in the aChange[] array is set to -1. If the column is modified, -** the value is 0 or greater. Parameter chngRowid is set to true if the -** UPDATE statement modifies the rowid fields of the table. -** -** If any foreign key processing will be required, this function returns -** true. If there is no foreign key related processing, this function -** returns false. -*/ -SQLITE_PRIVATE int sqlite3FkRequired( - Parse *pParse, /* Parse context */ - Table *pTab, /* Table being modified */ - int *aChange, /* Non-NULL for UPDATE operations */ - int chngRowid /* True for UPDATE that affects rowid */ -){ - if( pParse->db->flags&SQLITE_ForeignKeys ){ - if( !aChange ){ - /* A DELETE operation. Foreign key processing is required if the - ** table in question is either the child or parent table for any - ** foreign key constraint. */ - return (sqlite3FkReferences(pTab) || pTab->pFKey); - }else{ - /* This is an UPDATE. Foreign key processing is only required if the - ** operation modifies one or more child or parent key columns. */ - FKey *p; - - /* Check if any child key columns are being modified. */ - for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1; - } - - /* Check if any parent key columns are being modified. */ - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1; - } - } - } - return 0; -} - -/* -** This function is called when an UPDATE or DELETE operation is being -** compiled on table pTab, which is the parent table of foreign-key pFKey. -** If the current operation is an UPDATE, then the pChanges parameter is -** passed a pointer to the list of columns being modified. If it is a -** DELETE, pChanges is passed a NULL pointer. -** -** It returns a pointer to a Trigger structure containing a trigger -** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. -** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is -** returned (these actions require no special handling by the triggers -** sub-system, code for them is created by fkScanChildren()). -** -** For example, if pFKey is the foreign key and pTab is table "p" in -** the following schema: -** -** CREATE TABLE p(pk PRIMARY KEY); -** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); -** -** then the returned trigger structure is equivalent to: -** -** CREATE TRIGGER ... DELETE ON p BEGIN -** DELETE FROM c WHERE ck = old.pk; -** END; -** -** The returned pointer is cached as part of the foreign key object. It -** is eventually freed along with the rest of the foreign key object by -** sqlite3FkDelete(). -*/ -static Trigger *fkActionTrigger( - Parse *pParse, /* Parse context */ - Table *pTab, /* Table being updated or deleted from */ - FKey *pFKey, /* Foreign key to get action for */ - ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ -){ - sqlite3 *db = pParse->db; /* Database handle */ - int action; /* One of OE_None, OE_Cascade etc. */ - Trigger *pTrigger; /* Trigger definition to return */ - int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ - - action = pFKey->aAction[iAction]; - if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ - return 0; - } - pTrigger = pFKey->apTrigger[iAction]; - - if( action!=OE_None && !pTrigger ){ - char const *zFrom; /* Name of child table */ - int nFrom; /* Length in bytes of zFrom */ - Index *pIdx = 0; /* Parent key index for this FK */ - int *aiCol = 0; /* child table cols -> parent key cols */ - TriggerStep *pStep = 0; /* First (only) step of trigger program */ - Expr *pWhere = 0; /* WHERE clause of trigger step */ - ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ - Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ - int i; /* Iterator variable */ - Expr *pWhen = 0; /* WHEN clause for the trigger */ - - if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; - assert( aiCol || pFKey->nCol==1 ); - - for(i=0; inCol; i++){ - Token tOld = { "old", 3 }; /* Literal "old" token */ - Token tNew = { "new", 3 }; /* Literal "new" token */ - Token tFromCol; /* Name of column in child table */ - Token tToCol; /* Name of column in parent table */ - int iFromCol; /* Idx of column in child table */ - Expr *pEq; /* tFromCol = OLD.tToCol */ - - iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; - assert( iFromCol>=0 ); - assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); - assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); - sqlite3TokenInit(&tToCol, - pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); - sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); - - /* Create the expression "OLD.zToCol = zFromCol". It is important - ** that the "OLD.zToCol" term is on the LHS of the = operator, so - ** that the affinity and collation sequence associated with the - ** parent table are used for the comparison. */ - pEq = sqlite3PExpr(pParse, TK_EQ, - sqlite3PExpr(pParse, TK_DOT, - sqlite3ExprAlloc(db, TK_ID, &tOld, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) - , 0), - sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) - , 0); - pWhere = sqlite3ExprAnd(db, pWhere, pEq); - - /* For ON UPDATE, construct the next term of the WHEN clause. - ** The final WHEN clause will be like this: - ** - ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) - */ - if( pChanges ){ - pEq = sqlite3PExpr(pParse, TK_IS, - sqlite3PExpr(pParse, TK_DOT, - sqlite3ExprAlloc(db, TK_ID, &tOld, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), - 0), - sqlite3PExpr(pParse, TK_DOT, - sqlite3ExprAlloc(db, TK_ID, &tNew, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0), - 0), - 0); - pWhen = sqlite3ExprAnd(db, pWhen, pEq); - } - - if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ - Expr *pNew; - if( action==OE_Cascade ){ - pNew = sqlite3PExpr(pParse, TK_DOT, - sqlite3ExprAlloc(db, TK_ID, &tNew, 0), - sqlite3ExprAlloc(db, TK_ID, &tToCol, 0) - , 0); - }else if( action==OE_SetDflt ){ - Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; - if( pDflt ){ - pNew = sqlite3ExprDup(db, pDflt, 0); - }else{ - pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); - } - }else{ - pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); - } - pList = sqlite3ExprListAppend(pParse, pList, pNew); - sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); - } - } - sqlite3DbFree(db, aiCol); - - zFrom = pFKey->pFrom->zName; - nFrom = sqlite3Strlen30(zFrom); - - if( action==OE_Restrict ){ - Token tFrom; - Expr *pRaise; - - tFrom.z = zFrom; - tFrom.n = nFrom; - pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); - if( pRaise ){ - pRaise->affinity = OE_Abort; - } - pSelect = sqlite3SelectNew(pParse, - sqlite3ExprListAppend(pParse, 0, pRaise), - sqlite3SrcListAppend(db, 0, &tFrom, 0), - pWhere, - 0, 0, 0, 0, 0, 0 - ); - pWhere = 0; - } - - /* Disable lookaside memory allocation */ - db->lookaside.bDisable++; - - pTrigger = (Trigger *)sqlite3DbMallocZero(db, - sizeof(Trigger) + /* struct Trigger */ - sizeof(TriggerStep) + /* Single step in trigger program */ - nFrom + 1 /* Space for pStep->zTarget */ - ); - if( pTrigger ){ - pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; - pStep->zTarget = (char *)&pStep[1]; - memcpy((char *)pStep->zTarget, zFrom, nFrom); - - pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); - pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); - pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); - if( pWhen ){ - pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); - pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); - } - } - - /* Re-enable the lookaside buffer, if it was disabled earlier. */ - db->lookaside.bDisable--; - - sqlite3ExprDelete(db, pWhere); - sqlite3ExprDelete(db, pWhen); - sqlite3ExprListDelete(db, pList); - sqlite3SelectDelete(db, pSelect); - if( db->mallocFailed==1 ){ - fkTriggerDelete(db, pTrigger); - return 0; - } - assert( pStep!=0 ); - - switch( action ){ - case OE_Restrict: - pStep->op = TK_SELECT; - break; - case OE_Cascade: - if( !pChanges ){ - pStep->op = TK_DELETE; - break; - } - default: - pStep->op = TK_UPDATE; - } - pStep->pTrig = pTrigger; - pTrigger->pSchema = pTab->pSchema; - pTrigger->pTabSchema = pTab->pSchema; - pFKey->apTrigger[iAction] = pTrigger; - pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); - } - - return pTrigger; -} - -/* -** This function is called when deleting or updating a row to implement -** any required CASCADE, SET NULL or SET DEFAULT actions. -*/ -SQLITE_PRIVATE void sqlite3FkActions( - Parse *pParse, /* Parse context */ - Table *pTab, /* Table being updated or deleted from */ - ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ - int regOld, /* Address of array containing old row */ - int *aChange, /* Array indicating UPDATEd columns (or 0) */ - int bChngRowid /* True if rowid is UPDATEd */ -){ - /* If foreign-key support is enabled, iterate through all FKs that - ** refer to table pTab. If there is an action associated with the FK - ** for this operation (either update or delete), invoke the associated - ** trigger sub-program. */ - if( pParse->db->flags&SQLITE_ForeignKeys ){ - FKey *pFKey; /* Iterator variable */ - for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ - if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ - Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); - if( pAct ){ - sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); - } - } - } - } -} - -#endif /* ifndef SQLITE_OMIT_TRIGGER */ - -/* -** Free all memory associated with foreign key definitions attached to -** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash -** hash table. -*/ -SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ - FKey *pFKey; /* Iterator variable */ - FKey *pNext; /* Copy of pFKey->pNextFrom */ - - assert( db==0 || IsVirtual(pTab) - || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); - for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ - - /* Remove the FK from the fkeyHash hash table. */ - if( !db || db->pnBytesFreed==0 ){ - if( pFKey->pPrevTo ){ - pFKey->pPrevTo->pNextTo = pFKey->pNextTo; - }else{ - void *p = (void *)pFKey->pNextTo; - const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); - } - if( pFKey->pNextTo ){ - pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; - } - } - - /* EV: R-30323-21917 Each foreign key constraint in SQLite is - ** classified as either immediate or deferred. - */ - assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); - - /* Delete any triggers created to implement actions for this FK. */ -#ifndef SQLITE_OMIT_TRIGGER - fkTriggerDelete(db, pFKey->apTrigger[0]); - fkTriggerDelete(db, pFKey->apTrigger[1]); -#endif - - pNext = pFKey->pNextFrom; - sqlite3DbFree(db, pFKey); - } -} -#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ - -/************** End of fkey.c ************************************************/ -/************** Begin file insert.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that are called by the parser -** to handle INSERT statements in SQLite. -*/ -/* #include "sqliteInt.h" */ - -/* -** Generate code that will -** -** (1) acquire a lock for table pTab then -** (2) open pTab as cursor iCur. -** -** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index -** for that table that is actually opened. -*/ -SQLITE_PRIVATE void sqlite3OpenTable( - Parse *pParse, /* Generate code into this VDBE */ - int iCur, /* The cursor number of the table */ - int iDb, /* The database index in sqlite3.aDb[] */ - Table *pTab, /* The table to be opened */ - int opcode /* OP_OpenRead or OP_OpenWrite */ -){ - Vdbe *v; - assert( !IsVirtual(pTab) ); - v = sqlite3GetVdbe(pParse); - assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); - sqlite3TableLock(pParse, iDb, pTab->tnum, - (opcode==OP_OpenWrite)?1:0, pTab->zName); - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol); - VdbeComment((v, "%s", pTab->zName)); - }else{ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - assert( pPk!=0 ); - assert( pPk->tnum==pTab->tnum ); - sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - VdbeComment((v, "%s", pTab->zName)); - } -} - -/* -** Return a pointer to the column affinity string associated with index -** pIdx. A column affinity string has one character for each column in -** the table, according to the affinity of the column: -** -** Character Column affinity -** ------------------------------ -** 'A' BLOB -** 'B' TEXT -** 'C' NUMERIC -** 'D' INTEGER -** 'F' REAL -** -** An extra 'D' is appended to the end of the string to cover the -** rowid that appears as the last column in every index. -** -** Memory for the buffer containing the column index affinity string -** is managed along with the rest of the Index structure. It will be -** released when sqlite3DeleteIndex() is called. -*/ -SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ - if( !pIdx->zColAff ){ - /* The first time a column affinity string for a particular index is - ** required, it is allocated and populated here. It is then stored as - ** a member of the Index structure for subsequent use. - ** - ** The column affinity string will eventually be deleted by - ** sqliteDeleteIndex() when the Index structure itself is cleaned - ** up. - */ - int n; - Table *pTab = pIdx->pTable; - pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); - if( !pIdx->zColAff ){ - sqlite3OomFault(db); - return 0; - } - for(n=0; nnColumn; n++){ - i16 x = pIdx->aiColumn[n]; - if( x>=0 ){ - pIdx->zColAff[n] = pTab->aCol[x].affinity; - }else if( x==XN_ROWID ){ - pIdx->zColAff[n] = SQLITE_AFF_INTEGER; - }else{ - char aff; - assert( x==XN_EXPR ); - assert( pIdx->aColExpr!=0 ); - aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); - if( aff==0 ) aff = SQLITE_AFF_BLOB; - pIdx->zColAff[n] = aff; - } - } - pIdx->zColAff[n] = 0; - } - - return pIdx->zColAff; -} - -/* -** Compute the affinity string for table pTab, if it has not already been -** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities. -** -** If the affinity exists (if it is no entirely SQLITE_AFF_BLOB values) and -** if iReg>0 then code an OP_Affinity opcode that will set the affinities -** for register iReg and following. Or if affinities exists and iReg==0, -** then just set the P4 operand of the previous opcode (which should be -** an OP_MakeRecord) to the affinity string. -** -** A column affinity string has one character per column: -** -** Character Column affinity -** ------------------------------ -** 'A' BLOB -** 'B' TEXT -** 'C' NUMERIC -** 'D' INTEGER -** 'E' REAL -*/ -SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ - int i; - char *zColAff = pTab->zColAff; - if( zColAff==0 ){ - sqlite3 *db = sqlite3VdbeDb(v); - zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); - if( !zColAff ){ - sqlite3OomFault(db); - return; - } - - for(i=0; inCol; i++){ - zColAff[i] = pTab->aCol[i].affinity; - } - do{ - zColAff[i--] = 0; - }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB ); - pTab->zColAff = zColAff; - } - i = sqlite3Strlen30(zColAff); - if( i ){ - if( iReg ){ - sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); - }else{ - sqlite3VdbeChangeP4(v, -1, zColAff, i); - } - } -} - -/* -** Return non-zero if the table pTab in database iDb or any of its indices -** have been opened at any point in the VDBE program. This is used to see if -** a statement of the form "INSERT INTO SELECT ..." can -** run without using a temporary table for the results of the SELECT. -*/ -static int readsTable(Parse *p, int iDb, Table *pTab){ - Vdbe *v = sqlite3GetVdbe(p); - int i; - int iEnd = sqlite3VdbeCurrentAddr(v); -#ifndef SQLITE_OMIT_VIRTUALTABLE - VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; -#endif - - for(i=1; iopcode==OP_OpenRead && pOp->p3==iDb ){ - Index *pIndex; - int tnum = pOp->p2; - if( tnum==pTab->tnum ){ - return 1; - } - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( tnum==pIndex->tnum ){ - return 1; - } - } - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ - assert( pOp->p4.pVtab!=0 ); - assert( pOp->p4type==P4_VTAB ); - return 1; - } -#endif - } - return 0; -} - -#ifndef SQLITE_OMIT_AUTOINCREMENT -/* -** Locate or create an AutoincInfo structure associated with table pTab -** which is in database iDb. Return the register number for the register -** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT -** table. (Also return zero when doing a VACUUM since we do not want to -** update the AUTOINCREMENT counters during a VACUUM.) -** -** There is at most one AutoincInfo structure per table even if the -** same table is autoincremented multiple times due to inserts within -** triggers. A new AutoincInfo structure is created if this is the -** first use of table pTab. On 2nd and subsequent uses, the original -** AutoincInfo structure is used. -** -** Three memory locations are allocated: -** -** (1) Register to hold the name of the pTab table. -** (2) Register to hold the maximum ROWID of pTab. -** (3) Register to hold the rowid in sqlite_sequence of pTab -** -** The 2nd register is the one that is returned. That is all the -** insert routine needs to know about. -*/ -static int autoIncBegin( - Parse *pParse, /* Parsing context */ - int iDb, /* Index of the database holding pTab */ - Table *pTab /* The table we are writing to */ -){ - int memId = 0; /* Register holding maximum rowid */ - if( (pTab->tabFlags & TF_Autoincrement)!=0 - && (pParse->db->flags & SQLITE_Vacuum)==0 - ){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - AutoincInfo *pInfo; - - pInfo = pToplevel->pAinc; - while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } - if( pInfo==0 ){ - pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); - if( pInfo==0 ) return 0; - pInfo->pNext = pToplevel->pAinc; - pToplevel->pAinc = pInfo; - pInfo->pTab = pTab; - pInfo->iDb = iDb; - pToplevel->nMem++; /* Register to hold name of table */ - pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ - pToplevel->nMem++; /* Rowid in sqlite_sequence */ - } - memId = pInfo->regCtr; - } - return memId; -} - -/* -** This routine generates code that will initialize all of the -** register used by the autoincrement tracker. -*/ -SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ - AutoincInfo *p; /* Information about an AUTOINCREMENT */ - sqlite3 *db = pParse->db; /* The database connection */ - Db *pDb; /* Database only autoinc table */ - int memId; /* Register holding max rowid */ - Vdbe *v = pParse->pVdbe; /* VDBE under construction */ - - /* This routine is never called during trigger-generation. It is - ** only called from the top-level */ - assert( pParse->pTriggerTab==0 ); - assert( sqlite3IsToplevel(pParse) ); - - assert( v ); /* We failed long ago if this is not so */ - for(p = pParse->pAinc; p; p = p->pNext){ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList autoInc[] = { - /* 0 */ {OP_Null, 0, 0, 0}, - /* 1 */ {OP_Rewind, 0, 9, 0}, - /* 2 */ {OP_Column, 0, 0, 0}, - /* 3 */ {OP_Ne, 0, 7, 0}, - /* 4 */ {OP_Rowid, 0, 0, 0}, - /* 5 */ {OP_Column, 0, 1, 0}, - /* 6 */ {OP_Goto, 0, 9, 0}, - /* 7 */ {OP_Next, 0, 2, 0}, - /* 8 */ {OP_Integer, 0, 0, 0}, - /* 9 */ {OP_Close, 0, 0, 0} - }; - VdbeOp *aOp; - pDb = &db->aDb[p->iDb]; - memId = p->regCtr; - assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); - sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); - sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); - aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); - if( aOp==0 ) break; - aOp[0].p2 = memId; - aOp[0].p3 = memId+1; - aOp[2].p3 = memId; - aOp[3].p1 = memId-1; - aOp[3].p3 = memId; - aOp[3].p5 = SQLITE_JUMPIFNULL; - aOp[4].p2 = memId+1; - aOp[5].p3 = memId; - aOp[8].p2 = memId; - } -} - -/* -** Update the maximum rowid for an autoincrement calculation. -** -** This routine should be called when the regRowid register holds a -** new rowid that is about to be inserted. If that new rowid is -** larger than the maximum rowid in the memId memory cell, then the -** memory cell is updated. -*/ -static void autoIncStep(Parse *pParse, int memId, int regRowid){ - if( memId>0 ){ - sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); - } -} - -/* -** This routine generates the code needed to write autoincrement -** maximum rowid values back into the sqlite_sequence register. -** Every statement that might do an INSERT into an autoincrement -** table (either directly or through triggers) needs to call this -** routine just before the "exit" code. -*/ -static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ - AutoincInfo *p; - Vdbe *v = pParse->pVdbe; - sqlite3 *db = pParse->db; - - assert( v ); - for(p = pParse->pAinc; p; p = p->pNext){ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList autoIncEnd[] = { - /* 0 */ {OP_NotNull, 0, 2, 0}, - /* 1 */ {OP_NewRowid, 0, 0, 0}, - /* 2 */ {OP_MakeRecord, 0, 2, 0}, - /* 3 */ {OP_Insert, 0, 0, 0}, - /* 4 */ {OP_Close, 0, 0, 0} - }; - VdbeOp *aOp; - Db *pDb = &db->aDb[p->iDb]; - int iRec; - int memId = p->regCtr; - - iRec = sqlite3GetTempReg(pParse); - assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); - sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); - if( aOp==0 ) break; - aOp[0].p1 = memId+1; - aOp[1].p2 = memId+1; - aOp[2].p1 = memId-1; - aOp[2].p3 = iRec; - aOp[3].p2 = iRec; - aOp[3].p3 = memId+1; - aOp[3].p5 = OPFLAG_APPEND; - sqlite3ReleaseTempReg(pParse, iRec); - } -} -SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ - if( pParse->pAinc ) autoIncrementEnd(pParse); -} -#else -/* -** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines -** above are all no-ops -*/ -# define autoIncBegin(A,B,C) (0) -# define autoIncStep(A,B,C) -#endif /* SQLITE_OMIT_AUTOINCREMENT */ - - -/* Forward declaration */ -static int xferOptimization( - Parse *pParse, /* Parser context */ - Table *pDest, /* The table we are inserting into */ - Select *pSelect, /* A SELECT statement to use as the data source */ - int onError, /* How to handle constraint errors */ - int iDbDest /* The database of pDest */ -); - -/* -** This routine is called to handle SQL of the following forms: -** -** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... -** insert into TABLE (IDLIST) select -** insert into TABLE (IDLIST) default values -** -** The IDLIST following the table name is always optional. If omitted, -** then a list of all (non-hidden) columns for the table is substituted. -** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST -** is omitted. -** -** For the pSelect parameter holds the values to be inserted for the -** first two forms shown above. A VALUES clause is really just short-hand -** for a SELECT statement that omits the FROM clause and everything else -** that follows. If the pSelect parameter is NULL, that means that the -** DEFAULT VALUES form of the INSERT statement is intended. -** -** The code generated follows one of four templates. For a simple -** insert with data coming from a single-row VALUES clause, the code executes -** once straight down through. Pseudo-code follows (we call this -** the "1st template"): -** -** open write cursor to
    and its indices -** put VALUES clause expressions into registers -** write the resulting record into
    -** cleanup -** -** The three remaining templates assume the statement is of the form -** -** INSERT INTO
    SELECT ... -** -** If the SELECT clause is of the restricted form "SELECT * FROM " - -** in other words if the SELECT pulls all columns from a single table -** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and -** if and are distinct tables but have identical -** schemas, including all the same indices, then a special optimization -** is invoked that copies raw records from over to . -** See the xferOptimization() function for the implementation of this -** template. This is the 2nd template. -** -** open a write cursor to
    -** open read cursor on -** transfer all records in over to
    -** close cursors -** foreach index on
    -** open a write cursor on the
    index -** open a read cursor on the corresponding index -** transfer all records from the read to the write cursors -** close cursors -** end foreach -** -** The 3rd template is for when the second template does not apply -** and the SELECT clause does not read from
    at any time. -** The generated code follows this template: -** -** X <- A -** goto B -** A: setup for the SELECT -** loop over the rows in the SELECT -** load values into registers R..R+n -** yield X -** end loop -** cleanup after the SELECT -** end-coroutine X -** B: open write cursor to
    and its indices -** C: yield X, at EOF goto D -** insert the select result into
    from R..R+n -** goto C -** D: cleanup -** -** The 4th template is used if the insert statement takes its -** values from a SELECT but the data is being inserted into a table -** that is also read as part of the SELECT. In the third form, -** we have to use an intermediate table to store the results of -** the select. The template is like this: -** -** X <- A -** goto B -** A: setup for the SELECT -** loop over the tables in the SELECT -** load value into register R..R+n -** yield X -** end loop -** cleanup after the SELECT -** end co-routine R -** B: open temp table -** L: yield X, at EOF goto M -** insert row from R..R+n into temp table -** goto L -** M: open write cursor to
    and its indices -** rewind temp table -** C: loop over rows of intermediate table -** transfer values form intermediate table into
    -** end loop -** D: cleanup -*/ -SQLITE_PRIVATE void sqlite3Insert( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* Name of table into which we are inserting */ - Select *pSelect, /* A SELECT statement to use as the data source */ - IdList *pColumn, /* Column names corresponding to IDLIST. */ - int onError /* How to handle constraint errors */ -){ - sqlite3 *db; /* The main database structure */ - Table *pTab; /* The table to insert into. aka TABLE */ - char *zTab; /* Name of the table into which we are inserting */ - int i, j, idx; /* Loop counters */ - Vdbe *v; /* Generate code into this virtual machine */ - Index *pIdx; /* For looping over indices of the table */ - int nColumn; /* Number of columns in the data */ - int nHidden = 0; /* Number of hidden columns if TABLE is virtual */ - int iDataCur = 0; /* VDBE cursor that is the main data repository */ - int iIdxCur = 0; /* First index cursor */ - int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ - int endOfLoop; /* Label for the end of the insertion loop */ - int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ - int addrInsTop = 0; /* Jump to label "D" */ - int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ - SelectDest dest; /* Destination for SELECT on rhs of INSERT */ - int iDb; /* Index of database holding TABLE */ - u8 useTempTable = 0; /* Store SELECT results in intermediate table */ - u8 appendFlag = 0; /* True if the insert is likely to be an append */ - u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ - u8 bIdListInOrder; /* True if IDLIST is in table order */ - ExprList *pList = 0; /* List of VALUES() to be inserted */ - - /* Register allocations */ - int regFromSelect = 0;/* Base register for data coming from SELECT */ - int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ - int regRowCount = 0; /* Memory cell used for the row counter */ - int regIns; /* Block of regs holding rowid+data being inserted */ - int regRowid; /* registers holding insert rowid */ - int regData; /* register holding first column to insert */ - int *aRegIdx = 0; /* One register allocated to each index */ - -#ifndef SQLITE_OMIT_TRIGGER - int isView; /* True if attempting to insert into a view */ - Trigger *pTrigger; /* List of triggers on pTab, if required */ - int tmask; /* Mask of trigger times */ -#endif - - db = pParse->db; - memset(&dest, 0, sizeof(dest)); - if( pParse->nErr || db->mallocFailed ){ - goto insert_cleanup; - } - - /* If the Select object is really just a simple VALUES() list with a - ** single row (the common case) then keep that one row of values - ** and discard the other (unused) parts of the pSelect object - */ - if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ - pList = pSelect->pEList; - pSelect->pEList = 0; - sqlite3SelectDelete(db, pSelect); - pSelect = 0; - } - - /* Locate the table into which we will be inserting new information. - */ - assert( pTabList->nSrc==1 ); - zTab = pTabList->a[0].zName; - if( NEVER(zTab==0) ) goto insert_cleanup; - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ){ - goto insert_cleanup; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDbnDb ); - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, - db->aDb[iDb].zDbSName) ){ - goto insert_cleanup; - } - withoutRowid = !HasRowid(pTab); - - /* Figure out if we have any triggers and if the table being - ** inserted into is a view - */ -#ifndef SQLITE_OMIT_TRIGGER - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); - isView = pTab->pSelect!=0; -#else -# define pTrigger 0 -# define tmask 0 -# define isView 0 -#endif -#ifdef SQLITE_OMIT_VIEW -# undef isView -# define isView 0 -#endif - assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); - - /* If pTab is really a view, make sure it has been initialized. - ** ViewGetColumnNames() is a no-op if pTab is not a view. - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto insert_cleanup; - } - - /* Cannot insert into a read-only table. - */ - if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ - goto insert_cleanup; - } - - /* Allocate a VDBE - */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto insert_cleanup; - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); - -#ifndef SQLITE_OMIT_XFER_OPT - /* If the statement is of the form - ** - ** INSERT INTO SELECT * FROM ; - ** - ** Then special optimizations can be applied that make the transfer - ** very fast and which reduce fragmentation of indices. - ** - ** This is the 2nd template. - */ - if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ - assert( !pTrigger ); - assert( pList==0 ); - goto insert_end; - } -#endif /* SQLITE_OMIT_XFER_OPT */ - - /* If this is an AUTOINCREMENT table, look up the sequence number in the - ** sqlite_sequence table and store it in memory cell regAutoinc. - */ - regAutoinc = autoIncBegin(pParse, iDb, pTab); - - /* Allocate registers for holding the rowid of the new row, - ** the content of the new row, and the assembled row record. - */ - regRowid = regIns = pParse->nMem+1; - pParse->nMem += pTab->nCol + 1; - if( IsVirtual(pTab) ){ - regRowid++; - pParse->nMem++; - } - regData = regRowid+1; - - /* If the INSERT statement included an IDLIST term, then make sure - ** all elements of the IDLIST really are columns of the table and - ** remember the column indices. - ** - ** If the table has an INTEGER PRIMARY KEY column and that column - ** is named in the IDLIST, then record in the ipkColumn variable - ** the index into IDLIST of the primary key column. ipkColumn is - ** the index of the primary key as it appears in IDLIST, not as - ** is appears in the original table. (The index of the INTEGER - ** PRIMARY KEY in the original table is pTab->iPKey.) - */ - bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0; - if( pColumn ){ - for(i=0; inId; i++){ - pColumn->a[i].idx = -1; - } - for(i=0; inId; i++){ - for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ - pColumn->a[i].idx = j; - if( i!=j ) bIdListInOrder = 0; - if( j==pTab->iPKey ){ - ipkColumn = i; assert( !withoutRowid ); - } - break; - } - } - if( j>=pTab->nCol ){ - if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ - ipkColumn = i; - bIdListInOrder = 0; - }else{ - sqlite3ErrorMsg(pParse, "table %S has no column named %s", - pTabList, 0, pColumn->a[i].zName); - pParse->checkSchema = 1; - goto insert_cleanup; - } - } - } - } - - /* Figure out how many columns of data are supplied. If the data - ** is coming from a SELECT statement, then generate a co-routine that - ** produces a single row of the SELECT on each invocation. The - ** co-routine is the common header to the 3rd and 4th templates. - */ - if( pSelect ){ - /* Data is coming from a SELECT or from a multi-row VALUES clause. - ** Generate a co-routine to run the SELECT. */ - int regYield; /* Register holding co-routine entry-point */ - int addrTop; /* Top of the co-routine */ - int rc; /* Result code */ - - regYield = ++pParse->nMem; - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - dest.iSdst = bIdListInOrder ? regData : 0; - dest.nSdst = pTab->nCol; - rc = sqlite3Select(pParse, pSelect, &dest); - regFromSelect = dest.iSdst; - if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; - sqlite3VdbeEndCoroutine(v, regYield); - sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ - assert( pSelect->pEList ); - nColumn = pSelect->pEList->nExpr; - - /* Set useTempTable to TRUE if the result of the SELECT statement - ** should be written into a temporary table (template 4). Set to - ** FALSE if each output row of the SELECT can be written directly into - ** the destination table (template 3). - ** - ** A temp table must be used if the table being updated is also one - ** of the tables being read by the SELECT statement. Also use a - ** temp table in the case of row triggers. - */ - if( pTrigger || readsTable(pParse, iDb, pTab) ){ - useTempTable = 1; - } - - if( useTempTable ){ - /* Invoke the coroutine to extract information from the SELECT - ** and add it to a transient table srcTab. The code generated - ** here is from the 4th template: - ** - ** B: open temp table - ** L: yield X, goto M at EOF - ** insert row from R..R+n into temp table - ** goto L - ** M: ... - */ - int regRec; /* Register to hold packed record */ - int regTempRowid; /* Register to hold temp table ROWID */ - int addrL; /* Label "L" */ - - srcTab = pParse->nTab++; - regRec = sqlite3GetTempReg(pParse); - regTempRowid = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); - addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); - sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); - sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); - sqlite3VdbeGoto(v, addrL); - sqlite3VdbeJumpHere(v, addrL); - sqlite3ReleaseTempReg(pParse, regRec); - sqlite3ReleaseTempReg(pParse, regTempRowid); - } - }else{ - /* This is the case if the data for the INSERT is coming from a - ** single-row VALUES clause - */ - NameContext sNC; - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - srcTab = -1; - assert( useTempTable==0 ); - if( pList ){ - nColumn = pList->nExpr; - if( sqlite3ResolveExprListNames(&sNC, pList) ){ - goto insert_cleanup; - } - }else{ - nColumn = 0; - } - } - - /* If there is no IDLIST term but the table has an integer primary - ** key, the set the ipkColumn variable to the integer primary key - ** column index in the original table definition. - */ - if( pColumn==0 && nColumn>0 ){ - ipkColumn = pTab->iPKey; - } - - /* Make sure the number of columns in the source data matches the number - ** of columns to be inserted into the table. - */ - for(i=0; inCol; i++){ - nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); - } - if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, - "table %S has %d columns but %d values were supplied", - pTabList, 0, pTab->nCol-nHidden, nColumn); - goto insert_cleanup; - } - if( pColumn!=0 && nColumn!=pColumn->nId ){ - sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); - goto insert_cleanup; - } - - /* Initialize the count of rows to be inserted - */ - if( db->flags & SQLITE_CountRows ){ - regRowCount = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); - } - - /* If this is not a view, open the table and and all indices */ - if( !isView ){ - int nIdx; - nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, - &iDataCur, &iIdxCur); - aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); - if( aRegIdx==0 ){ - goto insert_cleanup; - } - for(i=0; inMem; - } - } - - /* This is the top of the main insertion loop */ - if( useTempTable ){ - /* This block codes the top of loop only. The complete loop is the - ** following pseudocode (template 4): - ** - ** rewind temp table, if empty goto D - ** C: loop over rows of intermediate table - ** transfer values form intermediate table into
    - ** end loop - ** D: ... - */ - addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); - addrCont = sqlite3VdbeCurrentAddr(v); - }else if( pSelect ){ - /* This block codes the top of loop only. The complete loop is the - ** following pseudocode (template 3): - ** - ** C: yield X, at EOF goto D - ** insert the select result into
    from R..R+n - ** goto C - ** D: ... - */ - addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); - VdbeCoverage(v); - } - - /* Run the BEFORE and INSTEAD OF triggers, if there are any - */ - endOfLoop = sqlite3VdbeMakeLabel(v); - if( tmask & TRIGGER_BEFORE ){ - int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); - - /* build the NEW.* reference row. Note that if there is an INTEGER - ** PRIMARY KEY into which a NULL is being inserted, that NULL will be - ** translated into a unique ID for the row. But on a BEFORE trigger, - ** we do not know what the unique ID will be (because the insert has - ** not happened yet) so we substitute a rowid of -1 - */ - if( ipkColumn<0 ){ - sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); - }else{ - int addr1; - assert( !withoutRowid ); - if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); - }else{ - assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); - } - addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); - } - - /* Cannot have triggers on a virtual table. If it were possible, - ** this block would have to account for hidden column. - */ - assert( !IsVirtual(pTab) ); - - /* Create the new column data - */ - for(i=j=0; inCol; i++){ - if( pColumn ){ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) - || (pColumn==0 && IsOrdinaryHiddenColumn(&pTab->aCol[i])) ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); - }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); - }else{ - assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); - } - if( pColumn==0 && !IsOrdinaryHiddenColumn(&pTab->aCol[i]) ) j++; - } - - /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, - ** do not attempt any conversions before assembling the record. - ** If this is a real table, attempt conversions as required by the - ** table column affinities. - */ - if( !isView ){ - sqlite3TableAffinity(v, pTab, regCols+1); - } - - /* Fire BEFORE or INSTEAD OF triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, - pTab, regCols-pTab->nCol-1, onError, endOfLoop); - - sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); - } - - /* Compute the content of the next row to insert into a range of - ** registers beginning at regIns. - */ - if( !isView ){ - if( IsVirtual(pTab) ){ - /* The row that the VUpdate opcode will delete: none */ - sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); - } - if( ipkColumn>=0 ){ - if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); - }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); - }else{ - VdbeOp *pOp; - sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); - pOp = sqlite3VdbeGetOp(v, -1); - if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){ - appendFlag = 1; - pOp->opcode = OP_NewRowid; - pOp->p1 = iDataCur; - pOp->p2 = regRowid; - pOp->p3 = regAutoinc; - } - } - /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid - ** to generate a unique primary key value. - */ - if( !appendFlag ){ - int addr1; - if( !IsVirtual(pTab) ){ - addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); - sqlite3VdbeJumpHere(v, addr1); - }else{ - addr1 = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); - } - sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); - } - }else if( IsVirtual(pTab) || withoutRowid ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); - }else{ - sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); - appendFlag = 1; - } - autoIncStep(pParse, regAutoinc, regRowid); - - /* Compute data for all columns of the new entry, beginning - ** with the first column. - */ - nHidden = 0; - for(i=0; inCol; i++){ - int iRegStore = regRowid+1+i; - if( i==pTab->iPKey ){ - /* The value of the INTEGER PRIMARY KEY column is always a NULL. - ** Whenever this column is read, the rowid will be substituted - ** in its place. Hence, fill this column with a NULL to avoid - ** taking up data space with information that will never be used. - ** As there may be shallow copies of this value, make it a soft-NULL */ - sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); - continue; - } - if( pColumn==0 ){ - if( IsHiddenColumn(&pTab->aCol[i]) ){ - j = -1; - nHidden++; - }else{ - j = i - nHidden; - } - }else{ - for(j=0; jnId; j++){ - if( pColumn->a[j].idx==i ) break; - } - } - if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); - }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore); - }else if( pSelect ){ - if( regFromSelect!=regData ){ - sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore); - } - }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore); - } - } - - /* Generate code to check constraints and generate index keys and - ** do the insertion. - */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); - sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); - sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); - sqlite3MayAbort(pParse); - }else -#endif - { - int isReplace; /* Set to true if constraints may cause a replace */ - sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, - regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0 - ); - sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); - sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, - regIns, aRegIdx, 0, appendFlag, isReplace==0); - } - } - - /* Update the count of rows that are inserted - */ - if( (db->flags & SQLITE_CountRows)!=0 ){ - sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); - } - - if( pTrigger ){ - /* Code AFTER triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, - pTab, regData-2-pTab->nCol, onError, endOfLoop); - } - - /* The bottom of the main insertion loop, if the data source - ** is a SELECT statement. - */ - sqlite3VdbeResolveLabel(v, endOfLoop); - if( useTempTable ){ - sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addrInsTop); - sqlite3VdbeAddOp1(v, OP_Close, srcTab); - }else if( pSelect ){ - sqlite3VdbeGoto(v, addrCont); - sqlite3VdbeJumpHere(v, addrInsTop); - } - - if( !IsVirtual(pTab) && !isView ){ - /* Close all tables opened */ - if( iDataCurpIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur); - } - } - -insert_end: - /* Update the sqlite_sequence table by storing the content of the - ** maximum rowid counter values recorded while inserting into - ** autoincrement tables. - */ - if( pParse->nested==0 && pParse->pTriggerTab==0 ){ - sqlite3AutoincrementEnd(pParse); - } - - /* - ** Return the number of rows inserted. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ - if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); - } - -insert_cleanup: - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprListDelete(db, pList); - sqlite3SelectDelete(db, pSelect); - sqlite3IdListDelete(db, pColumn); - sqlite3DbFree(db, aRegIdx); -} - -/* Make sure "isView" and other macros defined above are undefined. Otherwise -** they may interfere with compilation of other functions in this file -** (or in another file, if this file becomes part of the amalgamation). */ -#ifdef isView - #undef isView -#endif -#ifdef pTrigger - #undef pTrigger -#endif -#ifdef tmask - #undef tmask -#endif - -/* -** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged() -*/ -#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ -#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ - -/* This is the Walker callback from checkConstraintUnchanged(). Set -** bit 0x01 of pWalker->eCode if -** pWalker->eCode to 0 if this expression node references any of the -** columns that are being modifed by an UPDATE statement. -*/ -static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_COLUMN ){ - assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 ); - if( pExpr->iColumn>=0 ){ - if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){ - pWalker->eCode |= CKCNSTRNT_COLUMN; - } - }else{ - pWalker->eCode |= CKCNSTRNT_ROWID; - } - } - return WRC_Continue; -} - -/* -** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The -** only columns that are modified by the UPDATE are those for which -** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. -** -** Return true if CHECK constraint pExpr does not use any of the -** changing columns (or the rowid if it is changing). In other words, -** return true if this CHECK constraint can be skipped when validating -** the new row in the UPDATE statement. -*/ -static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ - Walker w; - memset(&w, 0, sizeof(w)); - w.eCode = 0; - w.xExprCallback = checkConstraintExprNode; - w.u.aiCol = aiChng; - sqlite3WalkExpr(&w, pExpr); - if( !chngRowid ){ - testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 ); - w.eCode &= ~CKCNSTRNT_ROWID; - } - testcase( w.eCode==0 ); - testcase( w.eCode==CKCNSTRNT_COLUMN ); - testcase( w.eCode==CKCNSTRNT_ROWID ); - testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); - return !w.eCode; -} - -/* -** Generate code to do constraint checks prior to an INSERT or an UPDATE -** on table pTab. -** -** The regNewData parameter is the first register in a range that contains -** the data to be inserted or the data after the update. There will be -** pTab->nCol+1 registers in this range. The first register (the one -** that regNewData points to) will contain the new rowid, or NULL in the -** case of a WITHOUT ROWID table. The second register in the range will -** contain the content of the first table column. The third register will -** contain the content of the second table column. And so forth. -** -** The regOldData parameter is similar to regNewData except that it contains -** the data prior to an UPDATE rather than afterwards. regOldData is zero -** for an INSERT. This routine can distinguish between UPDATE and INSERT by -** checking regOldData for zero. -** -** For an UPDATE, the pkChng boolean is true if the true primary key (the -** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table) -** might be modified by the UPDATE. If pkChng is false, then the key of -** the iDataCur content table is guaranteed to be unchanged by the UPDATE. -** -** For an INSERT, the pkChng boolean indicates whether or not the rowid -** was explicitly specified as part of the INSERT statement. If pkChng -** is zero, it means that the either rowid is computed automatically or -** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT, -** pkChng will only be true if the INSERT statement provides an integer -** value for either the rowid column or its INTEGER PRIMARY KEY alias. -** -** The code generated by this routine will store new index entries into -** registers identified by aRegIdx[]. No index entry is created for -** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is -** the same as the order of indices on the linked list of indices -** at pTab->pIndex. -** -** The caller must have already opened writeable cursors on the main -** table and all applicable indices (that is to say, all indices for which -** aRegIdx[] is not zero). iDataCur is the cursor for the main table when -** inserting or updating a rowid table, or the cursor for the PRIMARY KEY -** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor -** for the first index in the pTab->pIndex list. Cursors for other indices -** are at iIdxCur+N for the N-th element of the pTab->pIndex list. -** -** This routine also generates code to check constraints. NOT NULL, -** CHECK, and UNIQUE constraints are all checked. If a constraint fails, -** then the appropriate action is performed. There are five possible -** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. -** -** Constraint type Action What Happens -** --------------- ---------- ---------------------------------------- -** any ROLLBACK The current transaction is rolled back and -** sqlite3_step() returns immediately with a -** return code of SQLITE_CONSTRAINT. -** -** any ABORT Back out changes from the current command -** only (do not do a complete rollback) then -** cause sqlite3_step() to return immediately -** with SQLITE_CONSTRAINT. -** -** any FAIL Sqlite3_step() returns immediately with a -** return code of SQLITE_CONSTRAINT. The -** transaction is not rolled back and any -** changes to prior rows are retained. -** -** any IGNORE The attempt in insert or update the current -** row is skipped, without throwing an error. -** Processing continues with the next row. -** (There is an immediate jump to ignoreDest.) -** -** NOT NULL REPLACE The NULL value is replace by the default -** value for that column. If the default value -** is NULL, the action is the same as ABORT. -** -** UNIQUE REPLACE The other row that conflicts with the row -** being inserted is removed. -** -** CHECK REPLACE Illegal. The results in an exception. -** -** Which action to take is determined by the overrideError parameter. -** Or if overrideError==OE_Default, then the pParse->onError parameter -** is used. Or if pParse->onError==OE_Default then the onError value -** for the constraint is used. -*/ -SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( - Parse *pParse, /* The parser context */ - Table *pTab, /* The table being inserted or updated */ - int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */ - int iDataCur, /* Canonical data cursor (main table or PK index) */ - int iIdxCur, /* First index cursor */ - int regNewData, /* First register in a range holding values to insert */ - int regOldData, /* Previous content. 0 for INSERTs */ - u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ - u8 overrideError, /* Override onError to this if not OE_Default */ - int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ - int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ - int *aiChng /* column i is unchanged if aiChng[i]<0 */ -){ - Vdbe *v; /* VDBE under constrution */ - Index *pIdx; /* Pointer to one of the indices */ - Index *pPk = 0; /* The PRIMARY KEY index */ - sqlite3 *db; /* Database connection */ - int i; /* loop counter */ - int ix; /* Index loop counter */ - int nCol; /* Number of columns */ - int onError; /* Conflict resolution strategy */ - int addr1; /* Address of jump instruction */ - int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ - int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - int ipkTop = 0; /* Top of the rowid change constraint check */ - int ipkBottom = 0; /* Bottom of the rowid change constraint check */ - u8 isUpdate; /* True if this is an UPDATE operation */ - u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ - int regRowid = -1; /* Register holding ROWID value */ - - isUpdate = regOldData!=0; - db = pParse->db; - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ - nCol = pTab->nCol; - - /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for - ** normal rowid tables. nPkField is the number of key fields in the - ** pPk index or 1 for a rowid table. In other words, nPkField is the - ** number of fields in the true primary key of the table. */ - if( HasRowid(pTab) ){ - pPk = 0; - nPkField = 1; - }else{ - pPk = sqlite3PrimaryKeyIndex(pTab); - nPkField = pPk->nKeyCol; - } - - /* Record that this module has started */ - VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)", - iDataCur, iIdxCur, regNewData, regOldData, pkChng)); - - /* Test all NOT NULL constraints. - */ - for(i=0; iiPKey ){ - continue; /* ROWID is never NULL */ - } - if( aiChng && aiChng[i]<0 ){ - /* Don't bother checking for NOT NULL on columns that do not change */ - continue; - } - onError = pTab->aCol[i].notNull; - if( onError==OE_None ) continue; /* This column is allowed to be NULL */ - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ - onError = OE_Abort; - } - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); - switch( onError ){ - case OE_Abort: - sqlite3MayAbort(pParse); - /* Fall through */ - case OE_Rollback: - case OE_Fail: { - char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, - pTab->aCol[i].zName); - sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, - regNewData+1+i, zMsg, P4_DYNAMIC); - sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); - VdbeCoverage(v); - break; - } - case OE_Ignore: { - sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); - VdbeCoverage(v); - break; - } - default: { - assert( onError==OE_Replace ); - addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); - VdbeCoverage(v); - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); - sqlite3VdbeJumpHere(v, addr1); - break; - } - } - } - - /* Test all CHECK constraints - */ -#ifndef SQLITE_OMIT_CHECK - if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ - ExprList *pCheck = pTab->pCheck; - pParse->ckBase = regNewData+1; - onError = overrideError!=OE_Default ? overrideError : OE_Abort; - for(i=0; inExpr; i++){ - int allOk; - Expr *pExpr = pCheck->a[i].pExpr; - if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue; - allOk = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); - if( onError==OE_Ignore ){ - sqlite3VdbeGoto(v, ignoreDest); - }else{ - char *zName = pCheck->a[i].zName; - if( zName==0 ) zName = pTab->zName; - if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */ - sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, - onError, zName, P4_TRANSIENT, - P5_ConstraintCheck); - } - sqlite3VdbeResolveLabel(v, allOk); - } - } -#endif /* !defined(SQLITE_OMIT_CHECK) */ - - /* If rowid is changing, make sure the new rowid does not previously - ** exist in the table. - */ - if( pkChng && pPk==0 ){ - int addrRowidOk = sqlite3VdbeMakeLabel(v); - - /* Figure out what action to take in case of a rowid collision */ - onError = pTab->keyConf; - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - - if( isUpdate ){ - /* pkChng!=0 does not mean that the rowid has change, only that - ** it might have changed. Skip the conflict logic below if the rowid - ** is unchanged. */ - sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - VdbeCoverage(v); - } - - /* If the response to a rowid conflict is REPLACE but the response - ** to some other UNIQUE constraint is FAIL or IGNORE, then we need - ** to defer the running of the rowid conflict checking until after - ** the UNIQUE constraints have run. - */ - if( onError==OE_Replace && overrideError!=OE_Replace ){ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){ - ipkTop = sqlite3VdbeAddOp0(v, OP_Goto); - break; - } - } - } - - /* Check to see if the new rowid already exists in the table. Skip - ** the following conflict logic if it does not. */ - sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); - VdbeCoverage(v); - - /* Generate code that deals with a rowid collision */ - switch( onError ){ - default: { - onError = OE_Abort; - /* Fall thru into the next case */ - } - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - sqlite3RowidConstraint(pParse, onError, pTab); - break; - } - case OE_Replace: { - /* If there are DELETE triggers on this table and the - ** recursive-triggers flag is set, call GenerateRowDelete() to - ** remove the conflicting row from the table. This will fire - ** the triggers and remove both the table and index b-tree entries. - ** - ** Otherwise, if there are no triggers or the recursive-triggers - ** flag is not set, but the table has one or more indexes, call - ** GenerateRowIndexDelete(). This removes the index b-tree entries - ** only. The table b-tree entry will be replaced by the new entry - ** when it is inserted. - ** - ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, - ** also invoke MultiWrite() to indicate that this VDBE may require - ** statement rollback (if the statement is aborted after the delete - ** takes place). Earlier versions called sqlite3MultiWrite() regardless, - ** but being more selective here allows statements like: - ** - ** REPLACE INTO t(rowid) VALUES($newrowid) - ** - ** to run without a statement journal if there are no indexes on the - ** table. - */ - Trigger *pTrigger = 0; - if( db->flags&SQLITE_RecTriggers ){ - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - } - if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ - sqlite3MultiWrite(pParse); - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - regNewData, 1, 0, OE_Replace, 1, -1); - }else{ -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( HasRowid(pTab) ){ - /* This OP_Delete opcode fires the pre-update-hook only. It does - ** not modify the b-tree. It is more efficient to let the coming - ** OP_Insert replace the existing entry than it is to delete the - ** existing entry and then insert a new one. */ - sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); - sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); - } -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - if( pTab->pIndex ){ - sqlite3MultiWrite(pParse); - sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1); - } - } - seenReplace = 1; - break; - } - case OE_Ignore: { - /*assert( seenReplace==0 );*/ - sqlite3VdbeGoto(v, ignoreDest); - break; - } - } - sqlite3VdbeResolveLabel(v, addrRowidOk); - if( ipkTop ){ - ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, ipkTop); - } - } - - /* Test all UNIQUE constraints by creating entries for each UNIQUE - ** index and making sure that duplicate entries do not already exist. - ** Compute the revised record entries for indices as we go. - ** - ** This loop also handles the case of the PRIMARY KEY index for a - ** WITHOUT ROWID table. - */ - for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ - int regIdx; /* Range of registers hold conent for pIdx */ - int regR; /* Range of registers holding conflicting PK */ - int iThisCur; /* Cursor for this UNIQUE index */ - int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ - - if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( bAffinityDone==0 ){ - sqlite3TableAffinity(v, pTab, regNewData+1); - bAffinityDone = 1; - } - iThisCur = iIdxCur+ix; - addrUniqueOk = sqlite3VdbeMakeLabel(v); - - /* Skip partial indices for which the WHERE clause is not true */ - if( pIdx->pPartIdxWhere ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); - pParse->ckBase = regNewData+1; - sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk, - SQLITE_JUMPIFNULL); - pParse->ckBase = 0; - } - - /* Create a record for this index entry as it should appear after - ** the insert or update. Store that record in the aRegIdx[ix] register - */ - regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn); - for(i=0; inColumn; i++){ - int iField = pIdx->aiColumn[i]; - int x; - if( iField==XN_EXPR ){ - pParse->ckBase = regNewData+1; - sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); - pParse->ckBase = 0; - VdbeComment((v, "%s column %d", pIdx->zName, i)); - }else{ - if( iField==XN_ROWID || iField==pTab->iPKey ){ - if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */ - x = regNewData; - regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i; - }else{ - x = iField + regNewData + 1; - } - sqlite3VdbeAddOp2(v, iField<0 ? OP_IntCopy : OP_SCopy, x, regIdx+i); - VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName)); - } - } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); - VdbeComment((v, "for %s", pIdx->zName)); - sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn); - - /* In an UPDATE operation, if this index is the PRIMARY KEY index - ** of a WITHOUT ROWID table and there has been no change the - ** primary key, then no collision is possible. The collision detection - ** logic below can all be skipped. */ - if( isUpdate && pPk==pIdx && pkChng==0 ){ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - continue; - } - - /* Find out what action to take in case there is a uniqueness conflict */ - onError = pIdx->onError; - if( onError==OE_None ){ - sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); - sqlite3VdbeResolveLabel(v, addrUniqueOk); - continue; /* pIdx is not a UNIQUE index */ - } - if( overrideError!=OE_Default ){ - onError = overrideError; - }else if( onError==OE_Default ){ - onError = OE_Abort; - } - - /* Check to see if the new index entry will be unique */ - sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, - regIdx, pIdx->nKeyCol); VdbeCoverage(v); - - /* Generate code to handle collisions */ - regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); - if( isUpdate || onError==OE_Replace ){ - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); - /* Conflict only if the rowid of the existing index entry - ** is different from old-rowid */ - if( isUpdate ){ - sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - VdbeCoverage(v); - } - }else{ - int x; - /* Extract the PRIMARY KEY from the end of the index entry and - ** store it in registers regR..regR+nPk-1 */ - if( pIdx!=pPk ){ - for(i=0; inKeyCol; i++){ - assert( pPk->aiColumn[i]>=0 ); - x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]); - sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); - VdbeComment((v, "%s.%s", pTab->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); - } - } - if( isUpdate ){ - /* If currently processing the PRIMARY KEY of a WITHOUT ROWID - ** table, only conflict if the new PRIMARY KEY values are actually - ** different from the old. - ** - ** For a UNIQUE index, only conflict if the PRIMARY KEY values - ** of the matched index row are different from the original PRIMARY - ** KEY values of this row before the update. */ - int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; - int op = OP_Ne; - int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); - - for(i=0; inKeyCol; i++){ - char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); - x = pPk->aiColumn[i]; - assert( x>=0 ); - if( i==(pPk->nKeyCol-1) ){ - addrJump = addrUniqueOk; - op = OP_Eq; - } - sqlite3VdbeAddOp4(v, op, - regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ - ); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - VdbeCoverageIf(v, op==OP_Eq); - VdbeCoverageIf(v, op==OP_Ne); - } - } - } - } - - /* Generate code that executes if the new index entry is not unique */ - assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail - || onError==OE_Ignore || onError==OE_Replace ); - switch( onError ){ - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - sqlite3UniqueConstraint(pParse, onError, pIdx); - break; - } - case OE_Ignore: { - sqlite3VdbeGoto(v, ignoreDest); - break; - } - default: { - Trigger *pTrigger = 0; - assert( onError==OE_Replace ); - sqlite3MultiWrite(pParse); - if( db->flags&SQLITE_RecTriggers ){ - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - } - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - regR, nPkField, 0, OE_Replace, - (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1); - seenReplace = 1; - break; - } - } - sqlite3VdbeResolveLabel(v, addrUniqueOk); - sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn); - if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); - } - if( ipkTop ){ - sqlite3VdbeGoto(v, ipkTop+1); - sqlite3VdbeJumpHere(v, ipkBottom); - } - - *pbMayReplace = seenReplace; - VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); -} - -/* -** This routine generates code to finish the INSERT or UPDATE operation -** that was started by a prior call to sqlite3GenerateConstraintChecks. -** A consecutive range of registers starting at regNewData contains the -** rowid and the content to be inserted. -** -** The arguments to this routine should be the same as the first six -** arguments to sqlite3GenerateConstraintChecks. -*/ -SQLITE_PRIVATE void sqlite3CompleteInsertion( - Parse *pParse, /* The parser context */ - Table *pTab, /* the table into which we are inserting */ - int iDataCur, /* Cursor of the canonical data source */ - int iIdxCur, /* First index cursor */ - int regNewData, /* Range of content */ - int *aRegIdx, /* Register used by each index. 0 for unused indices */ - int isUpdate, /* True for UPDATE, False for INSERT */ - int appendBias, /* True if this is likely to be an append */ - int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ -){ - Vdbe *v; /* Prepared statements under construction */ - Index *pIdx; /* An index being inserted or updated */ - u8 pik_flags; /* flag values passed to the btree insert */ - int regData; /* Content registers (after the rowid) */ - int regRec; /* Register holding assembled record for the table */ - int i; /* Loop counter */ - u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - if( aRegIdx[i]==0 ) continue; - bAffinityDone = 1; - if( pIdx->pPartIdxWhere ){ - sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); - pik_flags = 0; - if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; - if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - assert( pParse->nested==0 ); - pik_flags |= OPFLAG_NCHANGE; - } - sqlite3VdbeChangeP5(v, pik_flags); - } - if( !HasRowid(pTab) ) return; - regData = regNewData + 1; - regRec = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); - if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); - sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); - if( pParse->nested ){ - pik_flags = 0; - }else{ - pik_flags = OPFLAG_NCHANGE; - pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); - } - if( appendBias ){ - pik_flags |= OPFLAG_APPEND; - } - if( useSeekResult ){ - pik_flags |= OPFLAG_USESEEKRESULT; - } - sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData); - if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE); - } - sqlite3VdbeChangeP5(v, pik_flags); -} - -/* -** Allocate cursors for the pTab table and all its indices and generate -** code to open and initialized those cursors. -** -** The cursor for the object that contains the complete data (normally -** the table itself, but the PRIMARY KEY index in the case of a WITHOUT -** ROWID table) is returned in *piDataCur. The first index cursor is -** returned in *piIdxCur. The number of indices is returned. -** -** Use iBase as the first cursor (either the *piDataCur for rowid tables -** or the first index for WITHOUT ROWID tables) if it is non-negative. -** If iBase is negative, then allocate the next available cursor. -** -** For a rowid table, *piDataCur will be exactly one less than *piIdxCur. -** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range -** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the -** pTab->pIndex list. -** -** If pTab is a virtual table, then this routine is a no-op and the -** *piDataCur and *piIdxCur values are left uninitialized. -*/ -SQLITE_PRIVATE int sqlite3OpenTableAndIndices( - Parse *pParse, /* Parsing context */ - Table *pTab, /* Table to be opened */ - int op, /* OP_OpenRead or OP_OpenWrite */ - u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */ - int iBase, /* Use this for the table cursor, if there is one */ - u8 *aToOpen, /* If not NULL: boolean for each table and index */ - int *piDataCur, /* Write the database source cursor number here */ - int *piIdxCur /* Write the first index cursor number here */ -){ - int i; - int iDb; - int iDataCur; - Index *pIdx; - Vdbe *v; - - assert( op==OP_OpenRead || op==OP_OpenWrite ); - assert( op==OP_OpenWrite || p5==0 ); - if( IsVirtual(pTab) ){ - /* This routine is a no-op for virtual tables. Leave the output - ** variables *piDataCur and *piIdxCur uninitialized so that valgrind - ** can detect if they are used by mistake in the caller. */ - return 0; - } - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - if( iBase<0 ) iBase = pParse->nTab; - iDataCur = iBase++; - if( piDataCur ) *piDataCur = iDataCur; - if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ - sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); - }else{ - sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); - } - if( piIdxCur ) *piIdxCur = iBase; - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - int iIdxCur = iBase++; - assert( pIdx->pSchema==pTab->pSchema ); - if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - if( piDataCur ) *piDataCur = iIdxCur; - p5 = 0; - } - if( aToOpen==0 || aToOpen[i+1] ){ - sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - sqlite3VdbeChangeP5(v, p5); - VdbeComment((v, "%s", pIdx->zName)); - } - } - if( iBase>pParse->nTab ) pParse->nTab = iBase; - return i; -} - - -#ifdef SQLITE_TEST -/* -** The following global variable is incremented whenever the -** transfer optimization is used. This is used for testing -** purposes only - to make sure the transfer optimization really -** is happening when it is supposed to. -*/ -SQLITE_API int sqlite3_xferopt_count; -#endif /* SQLITE_TEST */ - - -#ifndef SQLITE_OMIT_XFER_OPT -/* -** Check to see if index pSrc is compatible as a source of data -** for index pDest in an insert transfer optimization. The rules -** for a compatible index: -** -** * The index is over the same set of columns -** * The same DESC and ASC markings occurs on all columns -** * The same onError processing (OE_Abort, OE_Ignore, etc) -** * The same collating sequence on each column -** * The index has the exact same WHERE clause -*/ -static int xferCompatibleIndex(Index *pDest, Index *pSrc){ - int i; - assert( pDest && pSrc ); - assert( pDest->pTable!=pSrc->pTable ); - if( pDest->nKeyCol!=pSrc->nKeyCol ){ - return 0; /* Different number of columns */ - } - if( pDest->onError!=pSrc->onError ){ - return 0; /* Different conflict resolution strategies */ - } - for(i=0; inKeyCol; i++){ - if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ - return 0; /* Different columns indexed */ - } - if( pSrc->aiColumn[i]==XN_EXPR ){ - assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 ); - if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr, - pDest->aColExpr->a[i].pExpr, -1)!=0 ){ - return 0; /* Different expressions in the index */ - } - } - if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ - return 0; /* Different sort orders */ - } - if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){ - return 0; /* Different collating sequences */ - } - } - if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ - return 0; /* Different WHERE clauses */ - } - - /* If no test above fails then the indices must be compatible */ - return 1; -} - -/* -** Attempt the transfer optimization on INSERTs of the form -** -** INSERT INTO tab1 SELECT * FROM tab2; -** -** The xfer optimization transfers raw records from tab2 over to tab1. -** Columns are not decoded and reassembled, which greatly improves -** performance. Raw index records are transferred in the same way. -** -** The xfer optimization is only attempted if tab1 and tab2 are compatible. -** There are lots of rules for determining compatibility - see comments -** embedded in the code for details. -** -** This routine returns TRUE if the optimization is guaranteed to be used. -** Sometimes the xfer optimization will only work if the destination table -** is empty - a factor that can only be determined at run-time. In that -** case, this routine generates code for the xfer optimization but also -** does a test to see if the destination table is empty and jumps over the -** xfer optimization code if the test fails. In that case, this routine -** returns FALSE so that the caller will know to go ahead and generate -** an unoptimized transfer. This routine also returns FALSE if there -** is no chance that the xfer optimization can be applied. -** -** This optimization is particularly useful at making VACUUM run faster. -*/ -static int xferOptimization( - Parse *pParse, /* Parser context */ - Table *pDest, /* The table we are inserting into */ - Select *pSelect, /* A SELECT statement to use as the data source */ - int onError, /* How to handle constraint errors */ - int iDbDest /* The database of pDest */ -){ - sqlite3 *db = pParse->db; - ExprList *pEList; /* The result set of the SELECT */ - Table *pSrc; /* The table in the FROM clause of SELECT */ - Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ - struct SrcList_item *pItem; /* An element of pSelect->pSrc */ - int i; /* Loop counter */ - int iDbSrc; /* The database of pSrc */ - int iSrc, iDest; /* Cursors from source and destination */ - int addr1, addr2; /* Loop addresses */ - int emptyDestTest = 0; /* Address of test for empty pDest */ - int emptySrcTest = 0; /* Address of test for empty pSrc */ - Vdbe *v; /* The VDBE we are building */ - int regAutoinc; /* Memory register used by AUTOINC */ - int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ - int regData, regRowid; /* Registers holding data and rowid */ - - if( pSelect==0 ){ - return 0; /* Must be of the form INSERT INTO ... SELECT ... */ - } - if( pParse->pWith || pSelect->pWith ){ - /* Do not attempt to process this query if there are an WITH clauses - ** attached to it. Proceeding may generate a false "no such table: xxx" - ** error if pSelect reads from a CTE named "xxx". */ - return 0; - } - if( sqlite3TriggerList(pParse, pDest) ){ - return 0; /* tab1 must not have triggers */ - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pDest->tabFlags & TF_Virtual ){ - return 0; /* tab1 must not be a virtual table */ - } -#endif - if( onError==OE_Default ){ - if( pDest->iPKey>=0 ) onError = pDest->keyConf; - if( onError==OE_Default ) onError = OE_Abort; - } - assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ - if( pSelect->pSrc->nSrc!=1 ){ - return 0; /* FROM clause must have exactly one term */ - } - if( pSelect->pSrc->a[0].pSelect ){ - return 0; /* FROM clause cannot contain a subquery */ - } - if( pSelect->pWhere ){ - return 0; /* SELECT may not have a WHERE clause */ - } - if( pSelect->pOrderBy ){ - return 0; /* SELECT may not have an ORDER BY clause */ - } - /* Do not need to test for a HAVING clause. If HAVING is present but - ** there is no ORDER BY, we will get an error. */ - if( pSelect->pGroupBy ){ - return 0; /* SELECT may not have a GROUP BY clause */ - } - if( pSelect->pLimit ){ - return 0; /* SELECT may not have a LIMIT clause */ - } - assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ - if( pSelect->pPrior ){ - return 0; /* SELECT may not be a compound query */ - } - if( pSelect->selFlags & SF_Distinct ){ - return 0; /* SELECT may not be DISTINCT */ - } - pEList = pSelect->pEList; - assert( pEList!=0 ); - if( pEList->nExpr!=1 ){ - return 0; /* The result set must have exactly one column */ - } - assert( pEList->a[0].pExpr ); - if( pEList->a[0].pExpr->op!=TK_ASTERISK ){ - return 0; /* The result set must be the special operator "*" */ - } - - /* At this point we have established that the statement is of the - ** correct syntactic form to participate in this optimization. Now - ** we have to check the semantics. - */ - pItem = pSelect->pSrc->a; - pSrc = sqlite3LocateTableItem(pParse, 0, pItem); - if( pSrc==0 ){ - return 0; /* FROM clause does not contain a real table */ - } - if( pSrc==pDest ){ - return 0; /* tab1 and tab2 may not be the same table */ - } - if( HasRowid(pDest)!=HasRowid(pSrc) ){ - return 0; /* source and destination must both be WITHOUT ROWID or not */ - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( pSrc->tabFlags & TF_Virtual ){ - return 0; /* tab2 must not be a virtual table */ - } -#endif - if( pSrc->pSelect ){ - return 0; /* tab2 may not be a view */ - } - if( pDest->nCol!=pSrc->nCol ){ - return 0; /* Number of columns must be the same in tab1 and tab2 */ - } - if( pDest->iPKey!=pSrc->iPKey ){ - return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ - } - for(i=0; inCol; i++){ - Column *pDestCol = &pDest->aCol[i]; - Column *pSrcCol = &pSrc->aCol[i]; -#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS - if( (db->flags & SQLITE_Vacuum)==0 - && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN - ){ - return 0; /* Neither table may have __hidden__ columns */ - } -#endif - if( pDestCol->affinity!=pSrcCol->affinity ){ - return 0; /* Affinity must be the same on all columns */ - } - if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){ - return 0; /* Collating sequence must be the same on all columns */ - } - if( pDestCol->notNull && !pSrcCol->notNull ){ - return 0; /* tab2 must be NOT NULL if tab1 is */ - } - /* Default values for second and subsequent columns need to match. */ - if( i>0 ){ - assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN ); - assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN ); - if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) - || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken, - pSrcCol->pDflt->u.zToken)!=0) - ){ - return 0; /* Default values must be the same for all columns */ - } - } - } - for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ - if( IsUniqueIndex(pDestIdx) ){ - destHasUniqueIdx = 1; - } - for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ - if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; - } - if( pSrcIdx==0 ){ - return 0; /* pDestIdx has no corresponding index in pSrc */ - } - } -#ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ - return 0; /* Tables have different CHECK constraints. Ticket #2252 */ - } -#endif -#ifndef SQLITE_OMIT_FOREIGN_KEY - /* Disallow the transfer optimization if the destination table constains - ** any foreign key constraints. This is more restrictive than necessary. - ** But the main beneficiary of the transfer optimization is the VACUUM - ** command, and the VACUUM command disables foreign key constraints. So - ** the extra complication to make this rule less restrictive is probably - ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] - */ - if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ - return 0; - } -#endif - if( (db->flags & SQLITE_CountRows)!=0 ){ - return 0; /* xfer opt does not play well with PRAGMA count_changes */ - } - - /* If we get this far, it means that the xfer optimization is at - ** least a possibility, though it might only work if the destination - ** table (tab1) is initially empty. - */ -#ifdef SQLITE_TEST - sqlite3_xferopt_count++; -#endif - iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); - v = sqlite3GetVdbe(pParse); - sqlite3CodeVerifySchema(pParse, iDbSrc); - iSrc = pParse->nTab++; - iDest = pParse->nTab++; - regAutoinc = autoIncBegin(pParse, iDbDest, pDest); - regData = sqlite3GetTempReg(pParse); - regRowid = sqlite3GetTempReg(pParse); - sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - assert( HasRowid(pDest) || destHasUniqueIdx ); - if( (db->flags & SQLITE_Vacuum)==0 && ( - (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ - || destHasUniqueIdx /* (2) */ - || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ - )){ - /* In some circumstances, we are able to run the xfer optimization - ** only if the destination table is initially empty. Unless the - ** SQLITE_Vacuum flag is set, this block generates code to make - ** that determination. If SQLITE_Vacuum is set, then the destination - ** table is always empty. - ** - ** Conditions under which the destination must be empty: - ** - ** (1) There is no INTEGER PRIMARY KEY but there are indices. - ** (If the destination is not initially empty, the rowid fields - ** of index entries might need to change.) - ** - ** (2) The destination has a unique index. (The xfer optimization - ** is unable to test uniqueness.) - ** - ** (3) onError is something other than OE_Abort and OE_Rollback. - */ - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); - emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, addr1); - } - if( HasRowid(pSrc) ){ - sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); - emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - if( pDest->iPKey>=0 ){ - addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - VdbeCoverage(v); - sqlite3RowidConstraint(pParse, onError, pDest); - sqlite3VdbeJumpHere(v, addr2); - autoIncStep(pParse, regAutoinc, regRowid); - }else if( pDest->pIndex==0 ){ - addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); - }else{ - addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - assert( (pDest->tabFlags & TF_Autoincrement)==0 ); - } - sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData); - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); - sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); - sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); - sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); - }else{ - sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); - sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); - } - for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ - u8 idxInsFlags = 0; - for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ - if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; - } - assert( pSrcIdx ); - sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); - sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); - VdbeComment((v, "%s", pSrcIdx->zName)); - sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); - sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); - sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); - VdbeComment((v, "%s", pDestIdx->zName)); - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData); - if( db->flags & SQLITE_Vacuum ){ - /* This INSERT command is part of a VACUUM operation, which guarantees - ** that the destination table is empty. If all indexed columns use - ** collation sequence BINARY, then it can also be assumed that the - ** index will be populated by inserting keys in strictly sorted - ** order. In this case, instead of seeking within the b-tree as part - ** of every OP_IdxInsert opcode, an OP_Last is added before the - ** OP_IdxInsert to seek to the point within the b-tree where each key - ** should be inserted. This is faster. - ** - ** If any of the indexed columns use a collation sequence other than - ** BINARY, this optimization is disabled. This is because the user - ** might change the definition of a collation sequence and then run - ** a VACUUM command. In that case keys may not be written in strictly - ** sorted order. */ - for(i=0; inColumn; i++){ - const char *zColl = pSrcIdx->azColl[i]; - assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0 - || sqlite3StrBINARY==zColl ); - if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; - } - if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT; - sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1); - } - } - if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){ - idxInsFlags |= OPFLAG_NCHANGE; - } - sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1); - sqlite3VdbeChangeP5(v, idxInsFlags); - sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); - sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); - } - if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); - sqlite3ReleaseTempReg(pParse, regRowid); - sqlite3ReleaseTempReg(pParse, regData); - if( emptyDestTest ){ - sqlite3AutoincrementEnd(pParse); - sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); - sqlite3VdbeJumpHere(v, emptyDestTest); - sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); - return 0; - }else{ - return 1; - } -} -#endif /* SQLITE_OMIT_XFER_OPT */ - -/************** End of insert.c **********************************************/ -/************** Begin file legacy.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Main file for the SQLite library. The routines in this file -** implement the programmer interface to the library. Routines in -** other files are for internal use by SQLite and should not be -** accessed by users of the library. -*/ - -/* #include "sqliteInt.h" */ - -/* -** Execute SQL code. Return one of the SQLITE_ success/failure -** codes. Also write an error message into memory obtained from -** malloc() and make *pzErrMsg point to that message. -** -** If the SQL is a query, then for each row in the query result -** the xCallback() function is called. pArg becomes the first -** argument to xCallback(). If xCallback=NULL then no callback -** is invoked, even for queries. -*/ -SQLITE_API int sqlite3_exec( - sqlite3 *db, /* The database on which the SQL executes */ - const char *zSql, /* The SQL to be executed */ - sqlite3_callback xCallback, /* Invoke this callback routine */ - void *pArg, /* First argument to xCallback() */ - char **pzErrMsg /* Write error messages here */ -){ - int rc = SQLITE_OK; /* Return code */ - const char *zLeftover; /* Tail of unprocessed SQL */ - sqlite3_stmt *pStmt = 0; /* The current SQL statement */ - char **azCols = 0; /* Names of result columns */ - int callbackIsInit; /* True if callback data is initialized */ - - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; - if( zSql==0 ) zSql = ""; - - sqlite3_mutex_enter(db->mutex); - sqlite3Error(db, SQLITE_OK); - while( rc==SQLITE_OK && zSql[0] ){ - int nCol; - char **azVals = 0; - - pStmt = 0; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); - assert( rc==SQLITE_OK || pStmt==0 ); - if( rc!=SQLITE_OK ){ - continue; - } - if( !pStmt ){ - /* this happens for a comment or white-space */ - zSql = zLeftover; - continue; - } - - callbackIsInit = 0; - nCol = sqlite3_column_count(pStmt); - - while( 1 ){ - int i; - rc = sqlite3_step(pStmt); - - /* Invoke the callback function if required */ - if( xCallback && (SQLITE_ROW==rc || - (SQLITE_DONE==rc && !callbackIsInit - && db->flags&SQLITE_NullCallback)) ){ - if( !callbackIsInit ){ - azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); - if( azCols==0 ){ - goto exec_out; - } - for(i=0; ierrMask)==rc ); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/************** End of legacy.c **********************************************/ -/************** Begin file loadext.c *****************************************/ -/* -** 2006 June 7 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used to dynamically load extensions into -** the SQLite library. -*/ - -#ifndef SQLITE_CORE - #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ -#endif -/************** Include sqlite3ext.h in the middle of loadext.c **************/ -/************** Begin file sqlite3ext.h **************************************/ -/* -** 2006 June 7 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This header file defines the SQLite interface for use by -** shared libraries that want to be imported as extensions into -** an SQLite instance. Shared libraries that intend to be loaded -** as extensions by SQLite should #include this file instead of -** sqlite3.h. -*/ -#ifndef SQLITE3EXT_H -#define SQLITE3EXT_H -/* #include "sqlite3.h" */ - -/* -** The following structure holds pointers to all of the SQLite API -** routines. -** -** WARNING: In order to maintain backwards compatibility, add new -** interfaces to the end of this structure only. If you insert new -** interfaces in the middle of this structure, then older different -** versions of SQLite will not be able to load each other's shared -** libraries! -*/ -struct sqlite3_api_routines { - void * (*aggregate_context)(sqlite3_context*,int nBytes); - int (*aggregate_count)(sqlite3_context*); - int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); - int (*bind_double)(sqlite3_stmt*,int,double); - int (*bind_int)(sqlite3_stmt*,int,int); - int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); - int (*bind_null)(sqlite3_stmt*,int); - int (*bind_parameter_count)(sqlite3_stmt*); - int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); - const char * (*bind_parameter_name)(sqlite3_stmt*,int); - int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); - int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); - int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); - int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); - int (*busy_timeout)(sqlite3*,int ms); - int (*changes)(sqlite3*); - int (*close)(sqlite3*); - int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, - int eTextRep,const char*)); - int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, - int eTextRep,const void*)); - const void * (*column_blob)(sqlite3_stmt*,int iCol); - int (*column_bytes)(sqlite3_stmt*,int iCol); - int (*column_bytes16)(sqlite3_stmt*,int iCol); - int (*column_count)(sqlite3_stmt*pStmt); - const char * (*column_database_name)(sqlite3_stmt*,int); - const void * (*column_database_name16)(sqlite3_stmt*,int); - const char * (*column_decltype)(sqlite3_stmt*,int i); - const void * (*column_decltype16)(sqlite3_stmt*,int); - double (*column_double)(sqlite3_stmt*,int iCol); - int (*column_int)(sqlite3_stmt*,int iCol); - sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); - const char * (*column_name)(sqlite3_stmt*,int); - const void * (*column_name16)(sqlite3_stmt*,int); - const char * (*column_origin_name)(sqlite3_stmt*,int); - const void * (*column_origin_name16)(sqlite3_stmt*,int); - const char * (*column_table_name)(sqlite3_stmt*,int); - const void * (*column_table_name16)(sqlite3_stmt*,int); - const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); - const void * (*column_text16)(sqlite3_stmt*,int iCol); - int (*column_type)(sqlite3_stmt*,int iCol); - sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); - void * (*commit_hook)(sqlite3*,int(*)(void*),void*); - int (*complete)(const char*sql); - int (*complete16)(const void*sql); - int (*create_collation)(sqlite3*,const char*,int,void*, - int(*)(void*,int,const void*,int,const void*)); - int (*create_collation16)(sqlite3*,const void*,int,void*, - int(*)(void*,int,const void*,int,const void*)); - int (*create_function)(sqlite3*,const char*,int,int,void*, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*)); - int (*create_function16)(sqlite3*,const void*,int,int,void*, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*)); - int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); - int (*data_count)(sqlite3_stmt*pStmt); - sqlite3 * (*db_handle)(sqlite3_stmt*); - int (*declare_vtab)(sqlite3*,const char*); - int (*enable_shared_cache)(int); - int (*errcode)(sqlite3*db); - const char * (*errmsg)(sqlite3*); - const void * (*errmsg16)(sqlite3*); - int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); - int (*expired)(sqlite3_stmt*); - int (*finalize)(sqlite3_stmt*pStmt); - void (*free)(void*); - void (*free_table)(char**result); - int (*get_autocommit)(sqlite3*); - void * (*get_auxdata)(sqlite3_context*,int); - int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); - int (*global_recover)(void); - void (*interruptx)(sqlite3*); - sqlite_int64 (*last_insert_rowid)(sqlite3*); - const char * (*libversion)(void); - int (*libversion_number)(void); - void *(*malloc)(int); - char * (*mprintf)(const char*,...); - int (*open)(const char*,sqlite3**); - int (*open16)(const void*,sqlite3**); - int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); - int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); - void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); - void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); - void *(*realloc)(void*,int); - int (*reset)(sqlite3_stmt*pStmt); - void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); - void (*result_double)(sqlite3_context*,double); - void (*result_error)(sqlite3_context*,const char*,int); - void (*result_error16)(sqlite3_context*,const void*,int); - void (*result_int)(sqlite3_context*,int); - void (*result_int64)(sqlite3_context*,sqlite_int64); - void (*result_null)(sqlite3_context*); - void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); - void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); - void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); - void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); - void (*result_value)(sqlite3_context*,sqlite3_value*); - void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); - int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, - const char*,const char*),void*); - void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); - char * (*snprintf)(int,char*,const char*,...); - int (*step)(sqlite3_stmt*); - int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, - char const**,char const**,int*,int*,int*); - void (*thread_cleanup)(void); - int (*total_changes)(sqlite3*); - void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); - int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); - void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, - sqlite_int64),void*); - void * (*user_data)(sqlite3_context*); - const void * (*value_blob)(sqlite3_value*); - int (*value_bytes)(sqlite3_value*); - int (*value_bytes16)(sqlite3_value*); - double (*value_double)(sqlite3_value*); - int (*value_int)(sqlite3_value*); - sqlite_int64 (*value_int64)(sqlite3_value*); - int (*value_numeric_type)(sqlite3_value*); - const unsigned char * (*value_text)(sqlite3_value*); - const void * (*value_text16)(sqlite3_value*); - const void * (*value_text16be)(sqlite3_value*); - const void * (*value_text16le)(sqlite3_value*); - int (*value_type)(sqlite3_value*); - char *(*vmprintf)(const char*,va_list); - /* Added ??? */ - int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); - /* Added by 3.3.13 */ - int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); - int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); - int (*clear_bindings)(sqlite3_stmt*); - /* Added by 3.4.1 */ - int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, - void (*xDestroy)(void *)); - /* Added by 3.5.0 */ - int (*bind_zeroblob)(sqlite3_stmt*,int,int); - int (*blob_bytes)(sqlite3_blob*); - int (*blob_close)(sqlite3_blob*); - int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, - int,sqlite3_blob**); - int (*blob_read)(sqlite3_blob*,void*,int,int); - int (*blob_write)(sqlite3_blob*,const void*,int,int); - int (*create_collation_v2)(sqlite3*,const char*,int,void*, - int(*)(void*,int,const void*,int,const void*), - void(*)(void*)); - int (*file_control)(sqlite3*,const char*,int,void*); - sqlite3_int64 (*memory_highwater)(int); - sqlite3_int64 (*memory_used)(void); - sqlite3_mutex *(*mutex_alloc)(int); - void (*mutex_enter)(sqlite3_mutex*); - void (*mutex_free)(sqlite3_mutex*); - void (*mutex_leave)(sqlite3_mutex*); - int (*mutex_try)(sqlite3_mutex*); - int (*open_v2)(const char*,sqlite3**,int,const char*); - int (*release_memory)(int); - void (*result_error_nomem)(sqlite3_context*); - void (*result_error_toobig)(sqlite3_context*); - int (*sleep)(int); - void (*soft_heap_limit)(int); - sqlite3_vfs *(*vfs_find)(const char*); - int (*vfs_register)(sqlite3_vfs*,int); - int (*vfs_unregister)(sqlite3_vfs*); - int (*xthreadsafe)(void); - void (*result_zeroblob)(sqlite3_context*,int); - void (*result_error_code)(sqlite3_context*,int); - int (*test_control)(int, ...); - void (*randomness)(int,void*); - sqlite3 *(*context_db_handle)(sqlite3_context*); - int (*extended_result_codes)(sqlite3*,int); - int (*limit)(sqlite3*,int,int); - sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); - const char *(*sql)(sqlite3_stmt*); - int (*status)(int,int*,int*,int); - int (*backup_finish)(sqlite3_backup*); - sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); - int (*backup_pagecount)(sqlite3_backup*); - int (*backup_remaining)(sqlite3_backup*); - int (*backup_step)(sqlite3_backup*,int); - const char *(*compileoption_get)(int); - int (*compileoption_used)(const char*); - int (*create_function_v2)(sqlite3*,const char*,int,int,void*, - void (*xFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*), - void(*xDestroy)(void*)); - int (*db_config)(sqlite3*,int,...); - sqlite3_mutex *(*db_mutex)(sqlite3*); - int (*db_status)(sqlite3*,int,int*,int*,int); - int (*extended_errcode)(sqlite3*); - void (*log)(int,const char*,...); - sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); - const char *(*sourceid)(void); - int (*stmt_status)(sqlite3_stmt*,int,int); - int (*strnicmp)(const char*,const char*,int); - int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); - int (*wal_autocheckpoint)(sqlite3*,int); - int (*wal_checkpoint)(sqlite3*,const char*); - void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); - int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); - int (*vtab_config)(sqlite3*,int op,...); - int (*vtab_on_conflict)(sqlite3*); - /* Version 3.7.16 and later */ - int (*close_v2)(sqlite3*); - const char *(*db_filename)(sqlite3*,const char*); - int (*db_readonly)(sqlite3*,const char*); - int (*db_release_memory)(sqlite3*); - const char *(*errstr)(int); - int (*stmt_busy)(sqlite3_stmt*); - int (*stmt_readonly)(sqlite3_stmt*); - int (*stricmp)(const char*,const char*); - int (*uri_boolean)(const char*,const char*,int); - sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); - const char *(*uri_parameter)(const char*,const char*); - char *(*vsnprintf)(int,char*,const char*,va_list); - int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); - /* Version 3.8.7 and later */ - int (*auto_extension)(void(*)(void)); - int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, - void(*)(void*)); - int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, - void(*)(void*),unsigned char); - int (*cancel_auto_extension)(void(*)(void)); - int (*load_extension)(sqlite3*,const char*,const char*,char**); - void *(*malloc64)(sqlite3_uint64); - sqlite3_uint64 (*msize)(void*); - void *(*realloc64)(void*,sqlite3_uint64); - void (*reset_auto_extension)(void); - void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, - void(*)(void*)); - void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, - void(*)(void*), unsigned char); - int (*strglob)(const char*,const char*); - /* Version 3.8.11 and later */ - sqlite3_value *(*value_dup)(const sqlite3_value*); - void (*value_free)(sqlite3_value*); - int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); - int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); - /* Version 3.9.0 and later */ - unsigned int (*value_subtype)(sqlite3_value*); - void (*result_subtype)(sqlite3_context*,unsigned int); - /* Version 3.10.0 and later */ - int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); - int (*strlike)(const char*,const char*,unsigned int); - int (*db_cacheflush)(sqlite3*); - /* Version 3.12.0 and later */ - int (*system_errno)(sqlite3*); - /* Version 3.14.0 and later */ - int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); - char *(*expanded_sql)(sqlite3_stmt*); -}; - -/* -** This is the function signature used for all extension entry points. It -** is also defined in the file "loadext.c". -*/ -typedef int (*sqlite3_loadext_entry)( - sqlite3 *db, /* Handle to the database. */ - char **pzErrMsg, /* Used to set error string on failure. */ - const sqlite3_api_routines *pThunk /* Extension API function pointers. */ -); - -/* -** The following macros redefine the API routines so that they are -** redirected through the global sqlite3_api structure. -** -** This header file is also used by the loadext.c source file -** (part of the main SQLite library - not an extension) so that -** it can get access to the sqlite3_api_routines structure -** definition. But the main library does not want to redefine -** the API. So the redefinition macros are only valid if the -** SQLITE_CORE macros is undefined. -*/ -#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) -#define sqlite3_aggregate_context sqlite3_api->aggregate_context -#ifndef SQLITE_OMIT_DEPRECATED -#define sqlite3_aggregate_count sqlite3_api->aggregate_count -#endif -#define sqlite3_bind_blob sqlite3_api->bind_blob -#define sqlite3_bind_double sqlite3_api->bind_double -#define sqlite3_bind_int sqlite3_api->bind_int -#define sqlite3_bind_int64 sqlite3_api->bind_int64 -#define sqlite3_bind_null sqlite3_api->bind_null -#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count -#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index -#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name -#define sqlite3_bind_text sqlite3_api->bind_text -#define sqlite3_bind_text16 sqlite3_api->bind_text16 -#define sqlite3_bind_value sqlite3_api->bind_value -#define sqlite3_busy_handler sqlite3_api->busy_handler -#define sqlite3_busy_timeout sqlite3_api->busy_timeout -#define sqlite3_changes sqlite3_api->changes -#define sqlite3_close sqlite3_api->close -#define sqlite3_collation_needed sqlite3_api->collation_needed -#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 -#define sqlite3_column_blob sqlite3_api->column_blob -#define sqlite3_column_bytes sqlite3_api->column_bytes -#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 -#define sqlite3_column_count sqlite3_api->column_count -#define sqlite3_column_database_name sqlite3_api->column_database_name -#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 -#define sqlite3_column_decltype sqlite3_api->column_decltype -#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 -#define sqlite3_column_double sqlite3_api->column_double -#define sqlite3_column_int sqlite3_api->column_int -#define sqlite3_column_int64 sqlite3_api->column_int64 -#define sqlite3_column_name sqlite3_api->column_name -#define sqlite3_column_name16 sqlite3_api->column_name16 -#define sqlite3_column_origin_name sqlite3_api->column_origin_name -#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 -#define sqlite3_column_table_name sqlite3_api->column_table_name -#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 -#define sqlite3_column_text sqlite3_api->column_text -#define sqlite3_column_text16 sqlite3_api->column_text16 -#define sqlite3_column_type sqlite3_api->column_type -#define sqlite3_column_value sqlite3_api->column_value -#define sqlite3_commit_hook sqlite3_api->commit_hook -#define sqlite3_complete sqlite3_api->complete -#define sqlite3_complete16 sqlite3_api->complete16 -#define sqlite3_create_collation sqlite3_api->create_collation -#define sqlite3_create_collation16 sqlite3_api->create_collation16 -#define sqlite3_create_function sqlite3_api->create_function -#define sqlite3_create_function16 sqlite3_api->create_function16 -#define sqlite3_create_module sqlite3_api->create_module -#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 -#define sqlite3_data_count sqlite3_api->data_count -#define sqlite3_db_handle sqlite3_api->db_handle -#define sqlite3_declare_vtab sqlite3_api->declare_vtab -#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache -#define sqlite3_errcode sqlite3_api->errcode -#define sqlite3_errmsg sqlite3_api->errmsg -#define sqlite3_errmsg16 sqlite3_api->errmsg16 -#define sqlite3_exec sqlite3_api->exec -#ifndef SQLITE_OMIT_DEPRECATED -#define sqlite3_expired sqlite3_api->expired -#endif -#define sqlite3_finalize sqlite3_api->finalize -#define sqlite3_free sqlite3_api->free -#define sqlite3_free_table sqlite3_api->free_table -#define sqlite3_get_autocommit sqlite3_api->get_autocommit -#define sqlite3_get_auxdata sqlite3_api->get_auxdata -#define sqlite3_get_table sqlite3_api->get_table -#ifndef SQLITE_OMIT_DEPRECATED -#define sqlite3_global_recover sqlite3_api->global_recover -#endif -#define sqlite3_interrupt sqlite3_api->interruptx -#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid -#define sqlite3_libversion sqlite3_api->libversion -#define sqlite3_libversion_number sqlite3_api->libversion_number -#define sqlite3_malloc sqlite3_api->malloc -#define sqlite3_mprintf sqlite3_api->mprintf -#define sqlite3_open sqlite3_api->open -#define sqlite3_open16 sqlite3_api->open16 -#define sqlite3_prepare sqlite3_api->prepare -#define sqlite3_prepare16 sqlite3_api->prepare16 -#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 -#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 -#define sqlite3_profile sqlite3_api->profile -#define sqlite3_progress_handler sqlite3_api->progress_handler -#define sqlite3_realloc sqlite3_api->realloc -#define sqlite3_reset sqlite3_api->reset -#define sqlite3_result_blob sqlite3_api->result_blob -#define sqlite3_result_double sqlite3_api->result_double -#define sqlite3_result_error sqlite3_api->result_error -#define sqlite3_result_error16 sqlite3_api->result_error16 -#define sqlite3_result_int sqlite3_api->result_int -#define sqlite3_result_int64 sqlite3_api->result_int64 -#define sqlite3_result_null sqlite3_api->result_null -#define sqlite3_result_text sqlite3_api->result_text -#define sqlite3_result_text16 sqlite3_api->result_text16 -#define sqlite3_result_text16be sqlite3_api->result_text16be -#define sqlite3_result_text16le sqlite3_api->result_text16le -#define sqlite3_result_value sqlite3_api->result_value -#define sqlite3_rollback_hook sqlite3_api->rollback_hook -#define sqlite3_set_authorizer sqlite3_api->set_authorizer -#define sqlite3_set_auxdata sqlite3_api->set_auxdata -#define sqlite3_snprintf sqlite3_api->snprintf -#define sqlite3_step sqlite3_api->step -#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata -#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup -#define sqlite3_total_changes sqlite3_api->total_changes -#define sqlite3_trace sqlite3_api->trace -#ifndef SQLITE_OMIT_DEPRECATED -#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings -#endif -#define sqlite3_update_hook sqlite3_api->update_hook -#define sqlite3_user_data sqlite3_api->user_data -#define sqlite3_value_blob sqlite3_api->value_blob -#define sqlite3_value_bytes sqlite3_api->value_bytes -#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 -#define sqlite3_value_double sqlite3_api->value_double -#define sqlite3_value_int sqlite3_api->value_int -#define sqlite3_value_int64 sqlite3_api->value_int64 -#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type -#define sqlite3_value_text sqlite3_api->value_text -#define sqlite3_value_text16 sqlite3_api->value_text16 -#define sqlite3_value_text16be sqlite3_api->value_text16be -#define sqlite3_value_text16le sqlite3_api->value_text16le -#define sqlite3_value_type sqlite3_api->value_type -#define sqlite3_vmprintf sqlite3_api->vmprintf -#define sqlite3_vsnprintf sqlite3_api->vsnprintf -#define sqlite3_overload_function sqlite3_api->overload_function -#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 -#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 -#define sqlite3_clear_bindings sqlite3_api->clear_bindings -#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob -#define sqlite3_blob_bytes sqlite3_api->blob_bytes -#define sqlite3_blob_close sqlite3_api->blob_close -#define sqlite3_blob_open sqlite3_api->blob_open -#define sqlite3_blob_read sqlite3_api->blob_read -#define sqlite3_blob_write sqlite3_api->blob_write -#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 -#define sqlite3_file_control sqlite3_api->file_control -#define sqlite3_memory_highwater sqlite3_api->memory_highwater -#define sqlite3_memory_used sqlite3_api->memory_used -#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc -#define sqlite3_mutex_enter sqlite3_api->mutex_enter -#define sqlite3_mutex_free sqlite3_api->mutex_free -#define sqlite3_mutex_leave sqlite3_api->mutex_leave -#define sqlite3_mutex_try sqlite3_api->mutex_try -#define sqlite3_open_v2 sqlite3_api->open_v2 -#define sqlite3_release_memory sqlite3_api->release_memory -#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem -#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig -#define sqlite3_sleep sqlite3_api->sleep -#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit -#define sqlite3_vfs_find sqlite3_api->vfs_find -#define sqlite3_vfs_register sqlite3_api->vfs_register -#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister -#define sqlite3_threadsafe sqlite3_api->xthreadsafe -#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob -#define sqlite3_result_error_code sqlite3_api->result_error_code -#define sqlite3_test_control sqlite3_api->test_control -#define sqlite3_randomness sqlite3_api->randomness -#define sqlite3_context_db_handle sqlite3_api->context_db_handle -#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes -#define sqlite3_limit sqlite3_api->limit -#define sqlite3_next_stmt sqlite3_api->next_stmt -#define sqlite3_sql sqlite3_api->sql -#define sqlite3_status sqlite3_api->status -#define sqlite3_backup_finish sqlite3_api->backup_finish -#define sqlite3_backup_init sqlite3_api->backup_init -#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount -#define sqlite3_backup_remaining sqlite3_api->backup_remaining -#define sqlite3_backup_step sqlite3_api->backup_step -#define sqlite3_compileoption_get sqlite3_api->compileoption_get -#define sqlite3_compileoption_used sqlite3_api->compileoption_used -#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 -#define sqlite3_db_config sqlite3_api->db_config -#define sqlite3_db_mutex sqlite3_api->db_mutex -#define sqlite3_db_status sqlite3_api->db_status -#define sqlite3_extended_errcode sqlite3_api->extended_errcode -#define sqlite3_log sqlite3_api->log -#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 -#define sqlite3_sourceid sqlite3_api->sourceid -#define sqlite3_stmt_status sqlite3_api->stmt_status -#define sqlite3_strnicmp sqlite3_api->strnicmp -#define sqlite3_unlock_notify sqlite3_api->unlock_notify -#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint -#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint -#define sqlite3_wal_hook sqlite3_api->wal_hook -#define sqlite3_blob_reopen sqlite3_api->blob_reopen -#define sqlite3_vtab_config sqlite3_api->vtab_config -#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict -/* Version 3.7.16 and later */ -#define sqlite3_close_v2 sqlite3_api->close_v2 -#define sqlite3_db_filename sqlite3_api->db_filename -#define sqlite3_db_readonly sqlite3_api->db_readonly -#define sqlite3_db_release_memory sqlite3_api->db_release_memory -#define sqlite3_errstr sqlite3_api->errstr -#define sqlite3_stmt_busy sqlite3_api->stmt_busy -#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly -#define sqlite3_stricmp sqlite3_api->stricmp -#define sqlite3_uri_boolean sqlite3_api->uri_boolean -#define sqlite3_uri_int64 sqlite3_api->uri_int64 -#define sqlite3_uri_parameter sqlite3_api->uri_parameter -#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf -#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 -/* Version 3.8.7 and later */ -#define sqlite3_auto_extension sqlite3_api->auto_extension -#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 -#define sqlite3_bind_text64 sqlite3_api->bind_text64 -#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension -#define sqlite3_load_extension sqlite3_api->load_extension -#define sqlite3_malloc64 sqlite3_api->malloc64 -#define sqlite3_msize sqlite3_api->msize -#define sqlite3_realloc64 sqlite3_api->realloc64 -#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension -#define sqlite3_result_blob64 sqlite3_api->result_blob64 -#define sqlite3_result_text64 sqlite3_api->result_text64 -#define sqlite3_strglob sqlite3_api->strglob -/* Version 3.8.11 and later */ -#define sqlite3_value_dup sqlite3_api->value_dup -#define sqlite3_value_free sqlite3_api->value_free -#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 -#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 -/* Version 3.9.0 and later */ -#define sqlite3_value_subtype sqlite3_api->value_subtype -#define sqlite3_result_subtype sqlite3_api->result_subtype -/* Version 3.10.0 and later */ -#define sqlite3_status64 sqlite3_api->status64 -#define sqlite3_strlike sqlite3_api->strlike -#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush -/* Version 3.12.0 and later */ -#define sqlite3_system_errno sqlite3_api->system_errno -/* Version 3.14.0 and later */ -#define sqlite3_trace_v2 sqlite3_api->trace_v2 -#define sqlite3_expanded_sql sqlite3_api->expanded_sql -#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - -#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) - /* This case when the file really is being compiled as a loadable - ** extension */ -# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; -# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; -# define SQLITE_EXTENSION_INIT3 \ - extern const sqlite3_api_routines *sqlite3_api; -#else - /* This case when the file is being statically linked into the - ** application */ -# define SQLITE_EXTENSION_INIT1 /*no-op*/ -# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ -# define SQLITE_EXTENSION_INIT3 /*no-op*/ -#endif - -#endif /* SQLITE3EXT_H */ - -/************** End of sqlite3ext.h ******************************************/ -/************** Continuing where we left off in loadext.c ********************/ -/* #include "sqliteInt.h" */ -/* #include */ - -#ifndef SQLITE_OMIT_LOAD_EXTENSION -/* -** Some API routines are omitted when various features are -** excluded from a build of SQLite. Substitute a NULL pointer -** for any missing APIs. -*/ -#ifndef SQLITE_ENABLE_COLUMN_METADATA -# define sqlite3_column_database_name 0 -# define sqlite3_column_database_name16 0 -# define sqlite3_column_table_name 0 -# define sqlite3_column_table_name16 0 -# define sqlite3_column_origin_name 0 -# define sqlite3_column_origin_name16 0 -#endif - -#ifdef SQLITE_OMIT_AUTHORIZATION -# define sqlite3_set_authorizer 0 -#endif - -#ifdef SQLITE_OMIT_UTF16 -# define sqlite3_bind_text16 0 -# define sqlite3_collation_needed16 0 -# define sqlite3_column_decltype16 0 -# define sqlite3_column_name16 0 -# define sqlite3_column_text16 0 -# define sqlite3_complete16 0 -# define sqlite3_create_collation16 0 -# define sqlite3_create_function16 0 -# define sqlite3_errmsg16 0 -# define sqlite3_open16 0 -# define sqlite3_prepare16 0 -# define sqlite3_prepare16_v2 0 -# define sqlite3_result_error16 0 -# define sqlite3_result_text16 0 -# define sqlite3_result_text16be 0 -# define sqlite3_result_text16le 0 -# define sqlite3_value_text16 0 -# define sqlite3_value_text16be 0 -# define sqlite3_value_text16le 0 -# define sqlite3_column_database_name16 0 -# define sqlite3_column_table_name16 0 -# define sqlite3_column_origin_name16 0 -#endif - -#ifdef SQLITE_OMIT_COMPLETE -# define sqlite3_complete 0 -# define sqlite3_complete16 0 -#endif - -#ifdef SQLITE_OMIT_DECLTYPE -# define sqlite3_column_decltype16 0 -# define sqlite3_column_decltype 0 -#endif - -#ifdef SQLITE_OMIT_PROGRESS_CALLBACK -# define sqlite3_progress_handler 0 -#endif - -#ifdef SQLITE_OMIT_VIRTUALTABLE -# define sqlite3_create_module 0 -# define sqlite3_create_module_v2 0 -# define sqlite3_declare_vtab 0 -# define sqlite3_vtab_config 0 -# define sqlite3_vtab_on_conflict 0 -#endif - -#ifdef SQLITE_OMIT_SHARED_CACHE -# define sqlite3_enable_shared_cache 0 -#endif - -#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) -# define sqlite3_profile 0 -# define sqlite3_trace 0 -#endif - -#ifdef SQLITE_OMIT_GET_TABLE -# define sqlite3_free_table 0 -# define sqlite3_get_table 0 -#endif - -#ifdef SQLITE_OMIT_INCRBLOB -#define sqlite3_bind_zeroblob 0 -#define sqlite3_blob_bytes 0 -#define sqlite3_blob_close 0 -#define sqlite3_blob_open 0 -#define sqlite3_blob_read 0 -#define sqlite3_blob_write 0 -#define sqlite3_blob_reopen 0 -#endif - -#if defined(SQLITE_OMIT_TRACE) -# define sqlite3_trace_v2 0 -#endif - -/* -** The following structure contains pointers to all SQLite API routines. -** A pointer to this structure is passed into extensions when they are -** loaded so that the extension can make calls back into the SQLite -** library. -** -** When adding new APIs, add them to the bottom of this structure -** in order to preserve backwards compatibility. -** -** Extensions that use newer APIs should first call the -** sqlite3_libversion_number() to make sure that the API they -** intend to use is supported by the library. Extensions should -** also check to make sure that the pointer to the function is -** not NULL before calling it. -*/ -static const sqlite3_api_routines sqlite3Apis = { - sqlite3_aggregate_context, -#ifndef SQLITE_OMIT_DEPRECATED - sqlite3_aggregate_count, -#else - 0, -#endif - sqlite3_bind_blob, - sqlite3_bind_double, - sqlite3_bind_int, - sqlite3_bind_int64, - sqlite3_bind_null, - sqlite3_bind_parameter_count, - sqlite3_bind_parameter_index, - sqlite3_bind_parameter_name, - sqlite3_bind_text, - sqlite3_bind_text16, - sqlite3_bind_value, - sqlite3_busy_handler, - sqlite3_busy_timeout, - sqlite3_changes, - sqlite3_close, - sqlite3_collation_needed, - sqlite3_collation_needed16, - sqlite3_column_blob, - sqlite3_column_bytes, - sqlite3_column_bytes16, - sqlite3_column_count, - sqlite3_column_database_name, - sqlite3_column_database_name16, - sqlite3_column_decltype, - sqlite3_column_decltype16, - sqlite3_column_double, - sqlite3_column_int, - sqlite3_column_int64, - sqlite3_column_name, - sqlite3_column_name16, - sqlite3_column_origin_name, - sqlite3_column_origin_name16, - sqlite3_column_table_name, - sqlite3_column_table_name16, - sqlite3_column_text, - sqlite3_column_text16, - sqlite3_column_type, - sqlite3_column_value, - sqlite3_commit_hook, - sqlite3_complete, - sqlite3_complete16, - sqlite3_create_collation, - sqlite3_create_collation16, - sqlite3_create_function, - sqlite3_create_function16, - sqlite3_create_module, - sqlite3_data_count, - sqlite3_db_handle, - sqlite3_declare_vtab, - sqlite3_enable_shared_cache, - sqlite3_errcode, - sqlite3_errmsg, - sqlite3_errmsg16, - sqlite3_exec, -#ifndef SQLITE_OMIT_DEPRECATED - sqlite3_expired, -#else - 0, -#endif - sqlite3_finalize, - sqlite3_free, - sqlite3_free_table, - sqlite3_get_autocommit, - sqlite3_get_auxdata, - sqlite3_get_table, - 0, /* Was sqlite3_global_recover(), but that function is deprecated */ - sqlite3_interrupt, - sqlite3_last_insert_rowid, - sqlite3_libversion, - sqlite3_libversion_number, - sqlite3_malloc, - sqlite3_mprintf, - sqlite3_open, - sqlite3_open16, - sqlite3_prepare, - sqlite3_prepare16, - sqlite3_profile, - sqlite3_progress_handler, - sqlite3_realloc, - sqlite3_reset, - sqlite3_result_blob, - sqlite3_result_double, - sqlite3_result_error, - sqlite3_result_error16, - sqlite3_result_int, - sqlite3_result_int64, - sqlite3_result_null, - sqlite3_result_text, - sqlite3_result_text16, - sqlite3_result_text16be, - sqlite3_result_text16le, - sqlite3_result_value, - sqlite3_rollback_hook, - sqlite3_set_authorizer, - sqlite3_set_auxdata, - sqlite3_snprintf, - sqlite3_step, - sqlite3_table_column_metadata, -#ifndef SQLITE_OMIT_DEPRECATED - sqlite3_thread_cleanup, -#else - 0, -#endif - sqlite3_total_changes, - sqlite3_trace, -#ifndef SQLITE_OMIT_DEPRECATED - sqlite3_transfer_bindings, -#else - 0, -#endif - sqlite3_update_hook, - sqlite3_user_data, - sqlite3_value_blob, - sqlite3_value_bytes, - sqlite3_value_bytes16, - sqlite3_value_double, - sqlite3_value_int, - sqlite3_value_int64, - sqlite3_value_numeric_type, - sqlite3_value_text, - sqlite3_value_text16, - sqlite3_value_text16be, - sqlite3_value_text16le, - sqlite3_value_type, - sqlite3_vmprintf, - /* - ** The original API set ends here. All extensions can call any - ** of the APIs above provided that the pointer is not NULL. But - ** before calling APIs that follow, extension should check the - ** sqlite3_libversion_number() to make sure they are dealing with - ** a library that is new enough to support that API. - ************************************************************************* - */ - sqlite3_overload_function, - - /* - ** Added after 3.3.13 - */ - sqlite3_prepare_v2, - sqlite3_prepare16_v2, - sqlite3_clear_bindings, - - /* - ** Added for 3.4.1 - */ - sqlite3_create_module_v2, - - /* - ** Added for 3.5.0 - */ - sqlite3_bind_zeroblob, - sqlite3_blob_bytes, - sqlite3_blob_close, - sqlite3_blob_open, - sqlite3_blob_read, - sqlite3_blob_write, - sqlite3_create_collation_v2, - sqlite3_file_control, - sqlite3_memory_highwater, - sqlite3_memory_used, -#ifdef SQLITE_MUTEX_OMIT - 0, - 0, - 0, - 0, - 0, -#else - sqlite3_mutex_alloc, - sqlite3_mutex_enter, - sqlite3_mutex_free, - sqlite3_mutex_leave, - sqlite3_mutex_try, -#endif - sqlite3_open_v2, - sqlite3_release_memory, - sqlite3_result_error_nomem, - sqlite3_result_error_toobig, - sqlite3_sleep, - sqlite3_soft_heap_limit, - sqlite3_vfs_find, - sqlite3_vfs_register, - sqlite3_vfs_unregister, - - /* - ** Added for 3.5.8 - */ - sqlite3_threadsafe, - sqlite3_result_zeroblob, - sqlite3_result_error_code, - sqlite3_test_control, - sqlite3_randomness, - sqlite3_context_db_handle, - - /* - ** Added for 3.6.0 - */ - sqlite3_extended_result_codes, - sqlite3_limit, - sqlite3_next_stmt, - sqlite3_sql, - sqlite3_status, - - /* - ** Added for 3.7.4 - */ - sqlite3_backup_finish, - sqlite3_backup_init, - sqlite3_backup_pagecount, - sqlite3_backup_remaining, - sqlite3_backup_step, -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - sqlite3_compileoption_get, - sqlite3_compileoption_used, -#else - 0, - 0, -#endif - sqlite3_create_function_v2, - sqlite3_db_config, - sqlite3_db_mutex, - sqlite3_db_status, - sqlite3_extended_errcode, - sqlite3_log, - sqlite3_soft_heap_limit64, - sqlite3_sourceid, - sqlite3_stmt_status, - sqlite3_strnicmp, -#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY - sqlite3_unlock_notify, -#else - 0, -#endif -#ifndef SQLITE_OMIT_WAL - sqlite3_wal_autocheckpoint, - sqlite3_wal_checkpoint, - sqlite3_wal_hook, -#else - 0, - 0, - 0, -#endif - sqlite3_blob_reopen, - sqlite3_vtab_config, - sqlite3_vtab_on_conflict, - sqlite3_close_v2, - sqlite3_db_filename, - sqlite3_db_readonly, - sqlite3_db_release_memory, - sqlite3_errstr, - sqlite3_stmt_busy, - sqlite3_stmt_readonly, - sqlite3_stricmp, - sqlite3_uri_boolean, - sqlite3_uri_int64, - sqlite3_uri_parameter, - sqlite3_vsnprintf, - sqlite3_wal_checkpoint_v2, - /* Version 3.8.7 and later */ - sqlite3_auto_extension, - sqlite3_bind_blob64, - sqlite3_bind_text64, - sqlite3_cancel_auto_extension, - sqlite3_load_extension, - sqlite3_malloc64, - sqlite3_msize, - sqlite3_realloc64, - sqlite3_reset_auto_extension, - sqlite3_result_blob64, - sqlite3_result_text64, - sqlite3_strglob, - /* Version 3.8.11 and later */ - (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup, - sqlite3_value_free, - sqlite3_result_zeroblob64, - sqlite3_bind_zeroblob64, - /* Version 3.9.0 and later */ - sqlite3_value_subtype, - sqlite3_result_subtype, - /* Version 3.10.0 and later */ - sqlite3_status64, - sqlite3_strlike, - sqlite3_db_cacheflush, - /* Version 3.12.0 and later */ - sqlite3_system_errno, - /* Version 3.14.0 and later */ - sqlite3_trace_v2, - sqlite3_expanded_sql -}; - -/* -** Attempt to load an SQLite extension library contained in the file -** zFile. The entry point is zProc. zProc may be 0 in which case a -** default entry point name (sqlite3_extension_init) is used. Use -** of the default name is recommended. -** -** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. -** -** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with -** error message text. The calling function should free this memory -** by calling sqlite3DbFree(db, ). -*/ -static int sqlite3LoadExtension( - sqlite3 *db, /* Load the extension into this database connection */ - const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ - char **pzErrMsg /* Put error message here if not 0 */ -){ - sqlite3_vfs *pVfs = db->pVfs; - void *handle; - sqlite3_loadext_entry xInit; - char *zErrmsg = 0; - const char *zEntry; - char *zAltEntry = 0; - void **aHandle; - u64 nMsg = 300 + sqlite3Strlen30(zFile); - int ii; - int rc; - - /* Shared library endings to try if zFile cannot be loaded as written */ - static const char *azEndings[] = { -#if SQLITE_OS_WIN - "dll" -#elif defined(__APPLE__) - "dylib" -#else - "so" -#endif - }; - - - if( pzErrMsg ) *pzErrMsg = 0; - - /* Ticket #1863. To avoid a creating security problems for older - ** applications that relink against newer versions of SQLite, the - ** ability to run load_extension is turned off by default. One - ** must call either sqlite3_enable_load_extension(db) or - ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) - ** to turn on extension loading. - */ - if( (db->flags & SQLITE_LoadExtension)==0 ){ - if( pzErrMsg ){ - *pzErrMsg = sqlite3_mprintf("not authorized"); - } - return SQLITE_ERROR; - } - - zEntry = zProc ? zProc : "sqlite3_extension_init"; - - handle = sqlite3OsDlOpen(pVfs, zFile); -#if SQLITE_OS_UNIX || SQLITE_OS_WIN - for(ii=0; ii sqlite3_example_init - ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init - */ - if( xInit==0 && zProc==0 ){ - int iFile, iEntry, c; - int ncFile = sqlite3Strlen30(zFile); - zAltEntry = sqlite3_malloc64(ncFile+30); - if( zAltEntry==0 ){ - sqlite3OsDlClose(pVfs, handle); - return SQLITE_NOMEM_BKPT; - } - memcpy(zAltEntry, "sqlite3_", 8); - for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} - iFile++; - if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; - for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ - if( sqlite3Isalpha(c) ){ - zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; - } - } - memcpy(zAltEntry+iEntry, "_init", 6); - zEntry = zAltEntry; - xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); - } - if( xInit==0 ){ - if( pzErrMsg ){ - nMsg += sqlite3Strlen30(zEntry); - *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); - if( zErrmsg ){ - sqlite3_snprintf(nMsg, zErrmsg, - "no entry point [%s] in shared library [%s]", zEntry, zFile); - sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); - } - } - sqlite3OsDlClose(pVfs, handle); - sqlite3_free(zAltEntry); - return SQLITE_ERROR; - } - sqlite3_free(zAltEntry); - rc = xInit(db, &zErrmsg, &sqlite3Apis); - if( rc ){ - if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK; - if( pzErrMsg ){ - *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); - } - sqlite3_free(zErrmsg); - sqlite3OsDlClose(pVfs, handle); - return SQLITE_ERROR; - } - - /* Append the new shared library handle to the db->aExtension array. */ - aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); - if( aHandle==0 ){ - return SQLITE_NOMEM_BKPT; - } - if( db->nExtension>0 ){ - memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); - } - sqlite3DbFree(db, db->aExtension); - db->aExtension = aHandle; - - db->aExtension[db->nExtension++] = handle; - return SQLITE_OK; -} -SQLITE_API int sqlite3_load_extension( - sqlite3 *db, /* Load the extension into this database connection */ - const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ - char **pzErrMsg /* Put error message here if not 0 */ -){ - int rc; - sqlite3_mutex_enter(db->mutex); - rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Call this routine when the database connection is closing in order -** to clean up loaded extensions -*/ -SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ - int i; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inExtension; i++){ - sqlite3OsDlClose(db->pVfs, db->aExtension[i]); - } - sqlite3DbFree(db, db->aExtension); -} - -/* -** Enable or disable extension loading. Extension loading is disabled by -** default so as not to open security holes in older applications. -*/ -SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ - sqlite3_mutex_enter(db->mutex); - if( onoff ){ - db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; - }else{ - db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc); - } - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - -/* -** The following object holds the list of automatically loaded -** extensions. -** -** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER -** mutex must be held while accessing this list. -*/ -typedef struct sqlite3AutoExtList sqlite3AutoExtList; -static SQLITE_WSD struct sqlite3AutoExtList { - u32 nExt; /* Number of entries in aExt[] */ - void (**aExt)(void); /* Pointers to the extension init functions */ -} sqlite3Autoext = { 0, 0 }; - -/* The "wsdAutoext" macro will resolve to the autoextension -** state vector. If writable static data is unsupported on the target, -** we have to locate the state vector at run-time. In the more common -** case where writable static data is supported, wsdStat can refer directly -** to the "sqlite3Autoext" state vector declared above. -*/ -#ifdef SQLITE_OMIT_WSD -# define wsdAutoextInit \ - sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) -# define wsdAutoext x[0] -#else -# define wsdAutoextInit -# define wsdAutoext sqlite3Autoext -#endif - - -/* -** Register a statically linked extension that is automatically -** loaded by every new database connection. -*/ -SQLITE_API int sqlite3_auto_extension( - void (*xInit)(void) -){ - int rc = SQLITE_OK; -#ifndef SQLITE_OMIT_AUTOINIT - rc = sqlite3_initialize(); - if( rc ){ - return rc; - }else -#endif - { - u32 i; -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - wsdAutoextInit; - sqlite3_mutex_enter(mutex); - for(i=0; i=0; i--){ - if( wsdAutoext.aExt[i]==xInit ){ - wsdAutoext.nExt--; - wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; - n++; - break; - } - } - sqlite3_mutex_leave(mutex); - return n; -} - -/* -** Reset the automatic extension loading mechanism. -*/ -SQLITE_API void sqlite3_reset_auto_extension(void){ -#ifndef SQLITE_OMIT_AUTOINIT - if( sqlite3_initialize()==SQLITE_OK ) -#endif - { -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif - wsdAutoextInit; - sqlite3_mutex_enter(mutex); - sqlite3_free(wsdAutoext.aExt); - wsdAutoext.aExt = 0; - wsdAutoext.nExt = 0; - sqlite3_mutex_leave(mutex); - } -} - -/* -** Load all automatic extensions. -** -** If anything goes wrong, set an error in the database connection. -*/ -SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ - u32 i; - int go = 1; - int rc; - sqlite3_loadext_entry xInit; - - wsdAutoextInit; - if( wsdAutoext.nExt==0 ){ - /* Common case: early out without every having to acquire a mutex */ - return; - } - for(i=0; go; i++){ - char *zErrmsg; -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); -#endif -#ifdef SQLITE_OMIT_LOAD_EXTENSION - const sqlite3_api_routines *pThunk = 0; -#else - const sqlite3_api_routines *pThunk = &sqlite3Apis; -#endif - sqlite3_mutex_enter(mutex); - if( i>=wsdAutoext.nExt ){ - xInit = 0; - go = 0; - }else{ - xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i]; - } - sqlite3_mutex_leave(mutex); - zErrmsg = 0; - if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ - sqlite3ErrorWithMsg(db, rc, - "automatic extension loading failed: %s", zErrmsg); - go = 0; - } - sqlite3_free(zErrmsg); - } -} - -/************** End of loadext.c *********************************************/ -/************** Begin file pragma.c ******************************************/ -/* -** 2003 April 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used to implement the PRAGMA command. -*/ -/* #include "sqliteInt.h" */ - -#if !defined(SQLITE_ENABLE_LOCKING_STYLE) -# if defined(__APPLE__) -# define SQLITE_ENABLE_LOCKING_STYLE 1 -# else -# define SQLITE_ENABLE_LOCKING_STYLE 0 -# endif -#endif - -/*************************************************************************** -** The "pragma.h" include file is an automatically generated file that -** that includes the PragType_XXXX macro definitions and the aPragmaName[] -** object. This ensures that the aPragmaName[] table is arranged in -** lexicographical order to facility a binary search of the pragma name. -** Do not edit pragma.h directly. Edit and rerun the script in at -** ../tool/mkpragmatab.tcl. */ -/************** Include pragma.h in the middle of pragma.c *******************/ -/************** Begin file pragma.h ******************************************/ -/* DO NOT EDIT! -** This file is automatically generated by the script at -** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit -** that script and rerun it. -*/ -#define PragTyp_HEADER_VALUE 0 -#define PragTyp_AUTO_VACUUM 1 -#define PragTyp_FLAG 2 -#define PragTyp_BUSY_TIMEOUT 3 -#define PragTyp_CACHE_SIZE 4 -#define PragTyp_CACHE_SPILL 5 -#define PragTyp_CASE_SENSITIVE_LIKE 6 -#define PragTyp_COLLATION_LIST 7 -#define PragTyp_COMPILE_OPTIONS 8 -#define PragTyp_DATA_STORE_DIRECTORY 9 -#define PragTyp_DATABASE_LIST 10 -#define PragTyp_DEFAULT_CACHE_SIZE 11 -#define PragTyp_ENCODING 12 -#define PragTyp_FOREIGN_KEY_CHECK 13 -#define PragTyp_FOREIGN_KEY_LIST 14 -#define PragTyp_INCREMENTAL_VACUUM 15 -#define PragTyp_INDEX_INFO 16 -#define PragTyp_INDEX_LIST 17 -#define PragTyp_INTEGRITY_CHECK 18 -#define PragTyp_JOURNAL_MODE 19 -#define PragTyp_JOURNAL_SIZE_LIMIT 20 -#define PragTyp_LOCK_PROXY_FILE 21 -#define PragTyp_LOCKING_MODE 22 -#define PragTyp_PAGE_COUNT 23 -#define PragTyp_MMAP_SIZE 24 -#define PragTyp_PAGE_SIZE 25 -#define PragTyp_SECURE_DELETE 26 -#define PragTyp_SHRINK_MEMORY 27 -#define PragTyp_SOFT_HEAP_LIMIT 28 -#define PragTyp_STATS 29 -#define PragTyp_SYNCHRONOUS 30 -#define PragTyp_TABLE_INFO 31 -#define PragTyp_TEMP_STORE 32 -#define PragTyp_TEMP_STORE_DIRECTORY 33 -#define PragTyp_THREADS 34 -#define PragTyp_WAL_AUTOCHECKPOINT 35 -#define PragTyp_WAL_CHECKPOINT 36 -#define PragTyp_ACTIVATE_EXTENSIONS 37 -#define PragTyp_HEXKEY 38 -#define PragTyp_KEY 39 -#define PragTyp_REKEY 40 -#define PragTyp_LOCK_STATUS 41 -#define PragTyp_PARSER_TRACE 42 -#define PragFlag_NeedSchema 0x01 -#define PragFlag_ReadOnly 0x02 -static const struct sPragmaNames { - const char *const zName; /* Name of pragma */ - u8 ePragTyp; /* PragTyp_XXX value */ - u8 mPragFlag; /* Zero or more PragFlag_XXX values */ - u32 iArg; /* Extra argument */ -} aPragmaNames[] = { -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) - { /* zName: */ "activate_extensions", - /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "application_id", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_APPLICATION_ID }, -#endif -#if !defined(SQLITE_OMIT_AUTOVACUUM) - { /* zName: */ "auto_vacuum", - /* ePragTyp: */ PragTyp_AUTO_VACUUM, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) - { /* zName: */ "automatic_index", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_AutoIndex }, -#endif -#endif - { /* zName: */ "busy_timeout", - /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "cache_size", - /* ePragTyp: */ PragTyp_CACHE_SIZE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "cache_spill", - /* ePragTyp: */ PragTyp_CACHE_SPILL, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif - { /* zName: */ "case_sensitive_like", - /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "cell_size_check", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CellSizeCk }, -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "checkpoint_fullfsync", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CkptFullFSync }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "collation_list", - /* ePragTyp: */ PragTyp_COLLATION_LIST, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) - { /* zName: */ "compile_options", - /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "count_changes", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_CountRows }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN - { /* zName: */ "data_store_directory", - /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "data_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ PragFlag_ReadOnly, - /* iArg: */ BTREE_DATA_VERSION }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "database_list", - /* ePragTyp: */ PragTyp_DATABASE_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) - { /* zName: */ "default_cache_size", - /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "defer_foreign_keys", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_DeferFKs }, -#endif -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "empty_result_callbacks", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_NullCallback }, -#endif -#if !defined(SQLITE_OMIT_UTF16) - { /* zName: */ "encoding", - /* ePragTyp: */ PragTyp_ENCODING, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "foreign_key_check", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FOREIGN_KEY) - { /* zName: */ "foreign_key_list", - /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - { /* zName: */ "foreign_keys", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ForeignKeys }, -#endif -#endif -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "freelist_count", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ PragFlag_ReadOnly, - /* iArg: */ BTREE_FREE_PAGE_COUNT }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "full_column_names", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_FullColNames }, - { /* zName: */ "fullfsync", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_FullFSync }, -#endif -#if defined(SQLITE_HAS_CODEC) - { /* zName: */ "hexkey", - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "hexrekey", - /* ePragTyp: */ PragTyp_HEXKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if !defined(SQLITE_OMIT_CHECK) - { /* zName: */ "ignore_check_constraints", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_IgnoreChecks }, -#endif -#endif -#if !defined(SQLITE_OMIT_AUTOVACUUM) - { /* zName: */ "incremental_vacuum", - /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "index_info", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "index_list", - /* ePragTyp: */ PragTyp_INDEX_LIST, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "index_xinfo", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 1 }, -#endif -#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { /* zName: */ "integrity_check", - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "journal_mode", - /* ePragTyp: */ PragTyp_JOURNAL_MODE, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "journal_size_limit", - /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if defined(SQLITE_HAS_CODEC) - { /* zName: */ "key", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "legacy_file_format", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_LegacyFileFmt }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE - { /* zName: */ "lock_proxy_file", - /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - { /* zName: */ "lock_status", - /* ePragTyp: */ PragTyp_LOCK_STATUS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "locking_mode", - /* ePragTyp: */ PragTyp_LOCKING_MODE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "max_page_count", - /* ePragTyp: */ PragTyp_PAGE_COUNT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "mmap_size", - /* ePragTyp: */ PragTyp_MMAP_SIZE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "page_count", - /* ePragTyp: */ PragTyp_PAGE_COUNT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, - { /* zName: */ "page_size", - /* ePragTyp: */ PragTyp_PAGE_SIZE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) - { /* zName: */ "parser_trace", - /* ePragTyp: */ PragTyp_PARSER_TRACE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "query_only", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_QueryOnly }, -#endif -#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) - { /* zName: */ "quick_check", - /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "read_uncommitted", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ReadUncommitted }, - { /* zName: */ "recursive_triggers", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_RecTriggers }, -#endif -#if defined(SQLITE_HAS_CODEC) - { /* zName: */ "rekey", - /* ePragTyp: */ PragTyp_REKEY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "reverse_unordered_selects", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ReverseOrder }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "schema_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_SCHEMA_VERSION }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "secure_delete", - /* ePragTyp: */ PragTyp_SECURE_DELETE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "short_column_names", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_ShortColNames }, -#endif - { /* zName: */ "shrink_memory", - /* ePragTyp: */ PragTyp_SHRINK_MEMORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "soft_heap_limit", - /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if defined(SQLITE_DEBUG) - { /* zName: */ "sql_trace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_SqlTrace }, -#endif -#endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "stats", - /* ePragTyp: */ PragTyp_STATS, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "synchronous", - /* ePragTyp: */ PragTyp_SYNCHRONOUS, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - { /* zName: */ "table_info", - /* ePragTyp: */ PragTyp_TABLE_INFO, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - { /* zName: */ "temp_store", - /* ePragTyp: */ PragTyp_TEMP_STORE, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "temp_store_directory", - /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#endif - { /* zName: */ "threads", - /* ePragTyp: */ PragTyp_THREADS, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, -#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) - { /* zName: */ "user_version", - /* ePragTyp: */ PragTyp_HEADER_VALUE, - /* ePragFlag: */ 0, - /* iArg: */ BTREE_USER_VERSION }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -#if defined(SQLITE_DEBUG) - { /* zName: */ "vdbe_addoptrace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeAddopTrace }, - { /* zName: */ "vdbe_debug", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, - { /* zName: */ "vdbe_eqp", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeEQP }, - { /* zName: */ "vdbe_listing", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeListing }, - { /* zName: */ "vdbe_trace", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_VdbeTrace }, -#endif -#endif -#if !defined(SQLITE_OMIT_WAL) - { /* zName: */ "wal_autocheckpoint", - /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, - /* ePragFlag: */ 0, - /* iArg: */ 0 }, - { /* zName: */ "wal_checkpoint", - /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, - /* ePragFlag: */ PragFlag_NeedSchema, - /* iArg: */ 0 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) - { /* zName: */ "writable_schema", - /* ePragTyp: */ PragTyp_FLAG, - /* ePragFlag: */ 0, - /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, -#endif -}; -/* Number of pragmas: 60 on by default, 73 total. */ - -/************** End of pragma.h **********************************************/ -/************** Continuing where we left off in pragma.c *********************/ - -/* -** Interpret the given string as a safety level. Return 0 for OFF, -** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or -** unrecognized string argument. The FULL and EXTRA option is disallowed -** if the omitFull parameter it 1. -** -** Note that the values returned are one less that the values that -** should be passed into sqlite3BtreeSetSafetyLevel(). The is done -** to support legacy SQL code. The safety level used to be boolean -** and older scripts may have used numbers 0 for OFF and 1 for ON. -*/ -static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ - /* 123456789 123456789 123 */ - static const char zText[] = "onoffalseyestruextrafull"; - static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20}; - static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; - static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; - /* on no off false yes true extra full */ - int i, n; - if( sqlite3Isdigit(*z) ){ - return (u8)sqlite3Atoi(z); - } - n = sqlite3Strlen30(z); - for(i=0; i=0&&i<=2)?i:0); -} -#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** Interpret the given string as a temp db location. Return 1 for file -** backed temporary databases, 2 for the Red-Black tree in memory database -** and 0 to use the compile-time default. -*/ -static int getTempStore(const char *z){ - if( z[0]>='0' && z[0]<='2' ){ - return z[0] - '0'; - }else if( sqlite3StrICmp(z, "file")==0 ){ - return 1; - }else if( sqlite3StrICmp(z, "memory")==0 ){ - return 2; - }else{ - return 0; - } -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** Invalidate temp storage, either when the temp storage is changed -** from default, or when 'file' and the temp_store_directory has changed -*/ -static int invalidateTempStorage(Parse *pParse){ - sqlite3 *db = pParse->db; - if( db->aDb[1].pBt!=0 ){ - if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ - sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " - "from within a transaction"); - return SQLITE_ERROR; - } - sqlite3BtreeClose(db->aDb[1].pBt); - db->aDb[1].pBt = 0; - sqlite3ResetAllSchemasOfConnection(db); - } - return SQLITE_OK; -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS -/* -** If the TEMP database is open, close it and mark the database schema -** as needing reloading. This must be done when using the SQLITE_TEMP_STORE -** or DEFAULT_TEMP_STORE pragmas. -*/ -static int changeTempStorage(Parse *pParse, const char *zStorageType){ - int ts = getTempStore(zStorageType); - sqlite3 *db = pParse->db; - if( db->temp_store==ts ) return SQLITE_OK; - if( invalidateTempStorage( pParse ) != SQLITE_OK ){ - return SQLITE_ERROR; - } - db->temp_store = (u8)ts; - return SQLITE_OK; -} -#endif /* SQLITE_PAGER_PRAGMAS */ - -/* -** Set the names of the first N columns to the values in azCol[] -*/ -static void setAllColumnNames( - Vdbe *v, /* The query under construction */ - int N, /* Number of columns */ - const char **azCol /* Names of columns */ -){ - int i; - sqlite3VdbeSetNumCols(v, N); - for(i=0; iautoCommit ){ - Db *pDb = db->aDb; - int n = db->nDb; - assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); - assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); - assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); - assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) - == PAGER_FLAGS_MASK ); - assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); - while( (n--) > 0 ){ - if( pDb->pBt ){ - sqlite3BtreeSetPagerFlags(pDb->pBt, - pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); - } - pDb++; - } - } -} -#else -# define setAllPagerFlags(X) /* no-op */ -#endif - - -/* -** Return a human-readable name for a constraint resolution action. -*/ -#ifndef SQLITE_OMIT_FOREIGN_KEY -static const char *actionName(u8 action){ - const char *zName; - switch( action ){ - case OE_SetNull: zName = "SET NULL"; break; - case OE_SetDflt: zName = "SET DEFAULT"; break; - case OE_Cascade: zName = "CASCADE"; break; - case OE_Restrict: zName = "RESTRICT"; break; - default: zName = "NO ACTION"; - assert( action==OE_None ); break; - } - return zName; -} -#endif - - -/* -** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants -** defined in pager.h. This function returns the associated lowercase -** journal-mode name. -*/ -SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ - static char * const azModeName[] = { - "delete", "persist", "off", "truncate", "memory" -#ifndef SQLITE_OMIT_WAL - , "wal" -#endif - }; - assert( PAGER_JOURNALMODE_DELETE==0 ); - assert( PAGER_JOURNALMODE_PERSIST==1 ); - assert( PAGER_JOURNALMODE_OFF==2 ); - assert( PAGER_JOURNALMODE_TRUNCATE==3 ); - assert( PAGER_JOURNALMODE_MEMORY==4 ); - assert( PAGER_JOURNALMODE_WAL==5 ); - assert( eMode>=0 && eMode<=ArraySize(azModeName) ); - - if( eMode==ArraySize(azModeName) ) return 0; - return azModeName[eMode]; -} - -/* -** Process a pragma statement. -** -** Pragmas are of this form: -** -** PRAGMA [schema.]id [= value] -** -** The identifier might also be a string. The value is a string, and -** identifier, or a number. If minusFlag is true, then the value is -** a number that was preceded by a minus sign. -** -** If the left side is "database.id" then pId1 is the database name -** and pId2 is the id. If the left side is just "id" then pId1 is the -** id and pId2 is any empty string. -*/ -SQLITE_PRIVATE void sqlite3Pragma( - Parse *pParse, - Token *pId1, /* First part of [schema.]id field */ - Token *pId2, /* Second part of [schema.]id field, or NULL */ - Token *pValue, /* Token for , or NULL */ - int minusFlag /* True if a '-' sign preceded */ -){ - char *zLeft = 0; /* Nul-terminated UTF-8 string */ - char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ - const char *zDb = 0; /* The database name */ - Token *pId; /* Pointer to token */ - char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ - int iDb; /* Database index for */ - int lwr, upr, mid = 0; /* Binary search bounds */ - int rc; /* return value form SQLITE_FCNTL_PRAGMA */ - sqlite3 *db = pParse->db; /* The database connection */ - Db *pDb; /* The specific database being pragmaed */ - Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ - const struct sPragmaNames *pPragma; - - if( v==0 ) return; - sqlite3VdbeRunOnlyOnce(v); - pParse->nMem = 2; - - /* Interpret the [schema.] part of the pragma statement. iDb is the - ** index of the database this pragma is being applied to in db.aDb[]. */ - iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); - if( iDb<0 ) return; - pDb = &db->aDb[iDb]; - - /* If the temp database has been explicitly named as part of the - ** pragma, make sure it is open. - */ - if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ - return; - } - - zLeft = sqlite3NameFromToken(db, pId); - if( !zLeft ) return; - if( minusFlag ){ - zRight = sqlite3MPrintf(db, "-%T", pValue); - }else{ - zRight = sqlite3NameFromToken(db, pValue); - } - - assert( pId2 ); - zDb = pId2->n>0 ? pDb->zDbSName : 0; - if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ - goto pragma_out; - } - - /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS - ** connection. If it returns SQLITE_OK, then assume that the VFS - ** handled the pragma and generate a no-op prepared statement. - ** - ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, - ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file - ** object corresponding to the database file to which the pragma - ** statement refers. - ** - ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA - ** file control is an array of pointers to strings (char**) in which the - ** second element of the array is the name of the pragma and the third - ** element is the argument to the pragma or NULL if the pragma has no - ** argument. - */ - aFcntl[0] = 0; - aFcntl[1] = zLeft; - aFcntl[2] = zRight; - aFcntl[3] = 0; - db->busyHandler.nBusy = 0; - rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); - if( rc==SQLITE_OK ){ - returnSingleText(v, "result", aFcntl[0]); - sqlite3_free(aFcntl[0]); - goto pragma_out; - } - if( rc!=SQLITE_NOTFOUND ){ - if( aFcntl[0] ){ - sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); - sqlite3_free(aFcntl[0]); - } - pParse->nErr++; - pParse->rc = rc; - goto pragma_out; - } - - /* Locate the pragma in the lookup table */ - lwr = 0; - upr = ArraySize(aPragmaNames)-1; - while( lwr<=upr ){ - mid = (lwr+upr)/2; - rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName); - if( rc==0 ) break; - if( rc<0 ){ - upr = mid - 1; - }else{ - lwr = mid + 1; - } - } - if( lwr>upr ) goto pragma_out; - pPragma = &aPragmaNames[mid]; - - /* Make sure the database schema is loaded if the pragma requires that */ - if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - } - - /* Jump to the appropriate pragma handler */ - switch( pPragma->ePragTyp ){ - -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) - /* - ** PRAGMA [schema.]default_cache_size - ** PRAGMA [schema.]default_cache_size=N - ** - ** The first form reports the current persistent setting for the - ** page cache size. The value returned is the maximum number of - ** pages in the page cache. The second form sets both the current - ** page cache size value and the persistent page cache size value - ** stored in the database file. - ** - ** Older versions of SQLite would set the default cache size to a - ** negative number to indicate synchronous=OFF. These days, synchronous - ** is always on by default regardless of the sign of the default cache - ** size. But continue to take the absolute value of the default cache - ** size of historical compatibility. - */ - case PragTyp_DEFAULT_CACHE_SIZE: { - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList getCacheSize[] = { - { OP_Transaction, 0, 0, 0}, /* 0 */ - { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ - { OP_IfPos, 1, 8, 0}, - { OP_Integer, 0, 2, 0}, - { OP_Subtract, 1, 2, 1}, - { OP_IfPos, 1, 8, 0}, - { OP_Integer, 0, 1, 0}, /* 6 */ - { OP_Noop, 0, 0, 0}, - { OP_ResultRow, 1, 1, 0}, - }; - VdbeOp *aOp; - sqlite3VdbeUsesBtree(v, iDb); - if( !zRight ){ - setOneColumnName(v, "cache_size"); - pParse->nMem += 2; - sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); - aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); - if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; - aOp[0].p1 = iDb; - aOp[1].p1 = iDb; - aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; - }else{ - int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pDb->pSchema->cache_size = size; - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - } - break; - } -#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ - -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) - /* - ** PRAGMA [schema.]page_size - ** PRAGMA [schema.]page_size=N - ** - ** The first form reports the current setting for the - ** database page size in bytes. The second form sets the - ** database page size value. The value can only be set if - ** the database has not yet been created. - */ - case PragTyp_PAGE_SIZE: { - Btree *pBt = pDb->pBt; - assert( pBt!=0 ); - if( !zRight ){ - int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; - returnSingleInt(v, "page_size", size); - }else{ - /* Malloc may fail when setting the page-size, as there is an internal - ** buffer that the pager module resizes using sqlite3_realloc(). - */ - db->nextPagesize = sqlite3Atoi(zRight); - if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ - sqlite3OomFault(db); - } - } - break; - } - - /* - ** PRAGMA [schema.]secure_delete - ** PRAGMA [schema.]secure_delete=ON/OFF - ** - ** The first form reports the current setting for the - ** secure_delete flag. The second form changes the secure_delete - ** flag setting and reports thenew value. - */ - case PragTyp_SECURE_DELETE: { - Btree *pBt = pDb->pBt; - int b = -1; - assert( pBt!=0 ); - if( zRight ){ - b = sqlite3GetBoolean(zRight, 0); - } - if( pId2->n==0 && b>=0 ){ - int ii; - for(ii=0; iinDb; ii++){ - sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); - } - } - b = sqlite3BtreeSecureDelete(pBt, b); - returnSingleInt(v, "secure_delete", b); - break; - } - - /* - ** PRAGMA [schema.]max_page_count - ** PRAGMA [schema.]max_page_count=N - ** - ** The first form reports the current setting for the - ** maximum number of pages in the database file. The - ** second form attempts to change this setting. Both - ** forms return the current setting. - ** - ** The absolute value of N is used. This is undocumented and might - ** change. The only purpose is to provide an easy way to test - ** the sqlite3AbsInt32() function. - ** - ** PRAGMA [schema.]page_count - ** - ** Return the number of pages in the specified database. - */ - case PragTyp_PAGE_COUNT: { - int iReg; - sqlite3CodeVerifySchema(pParse, iDb); - iReg = ++pParse->nMem; - if( sqlite3Tolower(zLeft[0])=='p' ){ - sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); - }else{ - sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, - sqlite3AbsInt32(sqlite3Atoi(zRight))); - } - sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); - break; - } - - /* - ** PRAGMA [schema.]locking_mode - ** PRAGMA [schema.]locking_mode = (normal|exclusive) - */ - case PragTyp_LOCKING_MODE: { - const char *zRet = "normal"; - int eMode = getLockingMode(zRight); - - if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ - /* Simple "PRAGMA locking_mode;" statement. This is a query for - ** the current default locking mode (which may be different to - ** the locking-mode of the main database). - */ - eMode = db->dfltLockMode; - }else{ - Pager *pPager; - if( pId2->n==0 ){ - /* This indicates that no database name was specified as part - ** of the PRAGMA command. In this case the locking-mode must be - ** set on all attached databases, as well as the main db file. - ** - ** Also, the sqlite3.dfltLockMode variable is set so that - ** any subsequently attached databases also use the specified - ** locking mode. - */ - int ii; - assert(pDb==&db->aDb[0]); - for(ii=2; iinDb; ii++){ - pPager = sqlite3BtreePager(db->aDb[ii].pBt); - sqlite3PagerLockingMode(pPager, eMode); - } - db->dfltLockMode = (u8)eMode; - } - pPager = sqlite3BtreePager(pDb->pBt); - eMode = sqlite3PagerLockingMode(pPager, eMode); - } - - assert( eMode==PAGER_LOCKINGMODE_NORMAL - || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); - if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ - zRet = "exclusive"; - } - returnSingleText(v, "locking_mode", zRet); - break; - } - - /* - ** PRAGMA [schema.]journal_mode - ** PRAGMA [schema.]journal_mode = - ** (delete|persist|off|truncate|memory|wal|off) - */ - case PragTyp_JOURNAL_MODE: { - int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ - int ii; /* Loop counter */ - - setOneColumnName(v, "journal_mode"); - if( zRight==0 ){ - /* If there is no "=MODE" part of the pragma, do a query for the - ** current mode */ - eMode = PAGER_JOURNALMODE_QUERY; - }else{ - const char *zMode; - int n = sqlite3Strlen30(zRight); - for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ - if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; - } - if( !zMode ){ - /* If the "=MODE" part does not match any known journal mode, - ** then do a query */ - eMode = PAGER_JOURNALMODE_QUERY; - } - } - if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ - /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ - iDb = 0; - pId2->n = 1; - } - for(ii=db->nDb-1; ii>=0; ii--){ - if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ - sqlite3VdbeUsesBtree(v, ii); - sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); - } - } - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - break; - } - - /* - ** PRAGMA [schema.]journal_size_limit - ** PRAGMA [schema.]journal_size_limit=N - ** - ** Get or set the size limit on rollback journal files. - */ - case PragTyp_JOURNAL_SIZE_LIMIT: { - Pager *pPager = sqlite3BtreePager(pDb->pBt); - i64 iLimit = -2; - if( zRight ){ - sqlite3DecOrHexToI64(zRight, &iLimit); - if( iLimit<-1 ) iLimit = -1; - } - iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); - returnSingleInt(v, "journal_size_limit", iLimit); - break; - } - -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ - - /* - ** PRAGMA [schema.]auto_vacuum - ** PRAGMA [schema.]auto_vacuum=N - ** - ** Get or set the value of the database 'auto-vacuum' parameter. - ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - case PragTyp_AUTO_VACUUM: { - Btree *pBt = pDb->pBt; - assert( pBt!=0 ); - if( !zRight ){ - returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt)); - }else{ - int eAuto = getAutoVacuum(zRight); - assert( eAuto>=0 && eAuto<=2 ); - db->nextAutovac = (u8)eAuto; - /* Call SetAutoVacuum() to set initialize the internal auto and - ** incr-vacuum flags. This is required in case this connection - ** creates the database file. It is important that it is created - ** as an auto-vacuum capable db. - */ - rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); - if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ - /* When setting the auto_vacuum mode to either "full" or - ** "incremental", write the value of meta[6] in the database - ** file. Before writing to meta[6], check that meta[3] indicates - ** that this really is an auto-vacuum capable database. - */ - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList setMeta6[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, - { OP_If, 1, 0, 0}, /* 2 */ - { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ - { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ - }; - VdbeOp *aOp; - int iAddr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); - aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); - if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; - aOp[0].p1 = iDb; - aOp[1].p1 = iDb; - aOp[2].p2 = iAddr+4; - aOp[4].p1 = iDb; - aOp[4].p3 = eAuto - 1; - sqlite3VdbeUsesBtree(v, iDb); - } - } - break; - } -#endif - - /* - ** PRAGMA [schema.]incremental_vacuum(N) - ** - ** Do N steps of incremental vacuuming on a database. - */ -#ifndef SQLITE_OMIT_AUTOVACUUM - case PragTyp_INCREMENTAL_VACUUM: { - int iLimit, addr; - if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ - iLimit = 0x7fffffff; - } - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); - addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); - sqlite3VdbeAddOp1(v, OP_ResultRow, 1); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr); - break; - } -#endif - -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - /* - ** PRAGMA [schema.]cache_size - ** PRAGMA [schema.]cache_size=N - ** - ** The first form reports the current local setting for the - ** page cache size. The second form sets the local - ** page cache size value. If N is positive then that is the - ** number of pages in the cache. If N is negative, then the - ** number of pages is adjusted so that the cache uses -N kibibytes - ** of memory. - */ - case PragTyp_CACHE_SIZE: { - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( !zRight ){ - returnSingleInt(v, "cache_size", pDb->pSchema->cache_size); - }else{ - int size = sqlite3Atoi(zRight); - pDb->pSchema->cache_size = size; - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - } - break; - } - - /* - ** PRAGMA [schema.]cache_spill - ** PRAGMA cache_spill=BOOLEAN - ** PRAGMA [schema.]cache_spill=N - ** - ** The first form reports the current local setting for the - ** page cache spill size. The second form turns cache spill on - ** or off. When turnning cache spill on, the size is set to the - ** current cache_size. The third form sets a spill size that - ** may be different form the cache size. - ** If N is positive then that is the - ** number of pages in the cache. If N is negative, then the - ** number of pages is adjusted so that the cache uses -N kibibytes - ** of memory. - ** - ** If the number of cache_spill pages is less then the number of - ** cache_size pages, no spilling occurs until the page count exceeds - ** the number of cache_size pages. - ** - ** The cache_spill=BOOLEAN setting applies to all attached schemas, - ** not just the schema specified. - */ - case PragTyp_CACHE_SPILL: { - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( !zRight ){ - returnSingleInt(v, "cache_spill", - (db->flags & SQLITE_CacheSpill)==0 ? 0 : - sqlite3BtreeSetSpillSize(pDb->pBt,0)); - }else{ - int size = 1; - if( sqlite3GetInt32(zRight, &size) ){ - sqlite3BtreeSetSpillSize(pDb->pBt, size); - } - if( sqlite3GetBoolean(zRight, size!=0) ){ - db->flags |= SQLITE_CacheSpill; - }else{ - db->flags &= ~SQLITE_CacheSpill; - } - setAllPagerFlags(db); - } - break; - } - - /* - ** PRAGMA [schema.]mmap_size(N) - ** - ** Used to set mapping size limit. The mapping size limit is - ** used to limit the aggregate size of all memory mapped regions of the - ** database file. If this parameter is set to zero, then memory mapping - ** is not used at all. If N is negative, then the default memory map - ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. - ** The parameter N is measured in bytes. - ** - ** This value is advisory. The underlying VFS is free to memory map - ** as little or as much as it wants. Except, if N is set to 0 then the - ** upper layers will never invoke the xFetch interfaces to the VFS. - */ - case PragTyp_MMAP_SIZE: { - sqlite3_int64 sz; -#if SQLITE_MAX_MMAP_SIZE>0 - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( zRight ){ - int ii; - sqlite3DecOrHexToI64(zRight, &sz); - if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; - if( pId2->n==0 ) db->szMmap = sz; - for(ii=db->nDb-1; ii>=0; ii--){ - if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ - sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); - } - } - } - sz = -1; - rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); -#else - sz = 0; - rc = SQLITE_OK; -#endif - if( rc==SQLITE_OK ){ - returnSingleInt(v, "mmap_size", sz); - }else if( rc!=SQLITE_NOTFOUND ){ - pParse->nErr++; - pParse->rc = rc; - } - break; - } - - /* - ** PRAGMA temp_store - ** PRAGMA temp_store = "default"|"memory"|"file" - ** - ** Return or set the local value of the temp_store flag. Changing - ** the local value does not make changes to the disk file and the default - ** value will be restored the next time the database is opened. - ** - ** Note that it is possible for the library compile-time options to - ** override this setting - */ - case PragTyp_TEMP_STORE: { - if( !zRight ){ - returnSingleInt(v, "temp_store", db->temp_store); - }else{ - changeTempStorage(pParse, zRight); - } - break; - } - - /* - ** PRAGMA temp_store_directory - ** PRAGMA temp_store_directory = ""|"directory_name" - ** - ** Return or set the local value of the temp_store_directory flag. Changing - ** the value sets a specific directory to be used for temporary files. - ** Setting to a null string reverts to the default temporary directory search. - ** If temporary directory is changed, then invalidateTempStorage. - ** - */ - case PragTyp_TEMP_STORE_DIRECTORY: { - if( !zRight ){ - returnSingleText(v, "temp_store_directory", sqlite3_temp_directory); - }else{ -#ifndef SQLITE_OMIT_WSD - if( zRight[0] ){ - int res; - rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); - if( rc!=SQLITE_OK || res==0 ){ - sqlite3ErrorMsg(pParse, "not a writable directory"); - goto pragma_out; - } - } - if( SQLITE_TEMP_STORE==0 - || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) - || (SQLITE_TEMP_STORE==2 && db->temp_store==1) - ){ - invalidateTempStorage(pParse); - } - sqlite3_free(sqlite3_temp_directory); - if( zRight[0] ){ - sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); - }else{ - sqlite3_temp_directory = 0; - } -#endif /* SQLITE_OMIT_WSD */ - } - break; - } - -#if SQLITE_OS_WIN - /* - ** PRAGMA data_store_directory - ** PRAGMA data_store_directory = ""|"directory_name" - ** - ** Return or set the local value of the data_store_directory flag. Changing - ** the value sets a specific directory to be used for database files that - ** were specified with a relative pathname. Setting to a null string reverts - ** to the default database directory, which for database files specified with - ** a relative path will probably be based on the current directory for the - ** process. Database file specified with an absolute path are not impacted - ** by this setting, regardless of its value. - ** - */ - case PragTyp_DATA_STORE_DIRECTORY: { - if( !zRight ){ - returnSingleText(v, "data_store_directory", sqlite3_data_directory); - }else{ -#ifndef SQLITE_OMIT_WSD - if( zRight[0] ){ - int res; - rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); - if( rc!=SQLITE_OK || res==0 ){ - sqlite3ErrorMsg(pParse, "not a writable directory"); - goto pragma_out; - } - } - sqlite3_free(sqlite3_data_directory); - if( zRight[0] ){ - sqlite3_data_directory = sqlite3_mprintf("%s", zRight); - }else{ - sqlite3_data_directory = 0; - } -#endif /* SQLITE_OMIT_WSD */ - } - break; - } -#endif - -#if SQLITE_ENABLE_LOCKING_STYLE - /* - ** PRAGMA [schema.]lock_proxy_file - ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path" - ** - ** Return or set the value of the lock_proxy_file flag. Changing - ** the value sets a specific file to be used for database access locks. - ** - */ - case PragTyp_LOCK_PROXY_FILE: { - if( !zRight ){ - Pager *pPager = sqlite3BtreePager(pDb->pBt); - char *proxy_file_path = NULL; - sqlite3_file *pFile = sqlite3PagerFile(pPager); - sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, - &proxy_file_path); - returnSingleText(v, "lock_proxy_file", proxy_file_path); - }else{ - Pager *pPager = sqlite3BtreePager(pDb->pBt); - sqlite3_file *pFile = sqlite3PagerFile(pPager); - int res; - if( zRight[0] ){ - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, - zRight); - } else { - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, - NULL); - } - if( res!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); - goto pragma_out; - } - } - break; - } -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - - /* - ** PRAGMA [schema.]synchronous - ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA - ** - ** Return or set the local value of the synchronous flag. Changing - ** the local value does not make changes to the disk file and the - ** default value will be restored the next time the database is - ** opened. - */ - case PragTyp_SYNCHRONOUS: { - if( !zRight ){ - returnSingleInt(v, "synchronous", pDb->safety_level-1); - }else{ - if( !db->autoCommit ){ - sqlite3ErrorMsg(pParse, - "Safety level may not be changed inside a transaction"); - }else{ - int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; - if( iLevel==0 ) iLevel = 1; - pDb->safety_level = iLevel; - pDb->bSyncSet = 1; - setAllPagerFlags(db); - } - } - break; - } -#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ - -#ifndef SQLITE_OMIT_FLAG_PRAGMAS - case PragTyp_FLAG: { - if( zRight==0 ){ - returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 ); - }else{ - int mask = pPragma->iArg; /* Mask of bits to set or clear. */ - if( db->autoCommit==0 ){ - /* Foreign key support may not be enabled or disabled while not - ** in auto-commit mode. */ - mask &= ~(SQLITE_ForeignKeys); - } -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevel==UAUTH_User ){ - /* Do not allow non-admin users to modify the schema arbitrarily */ - mask &= ~(SQLITE_WriteSchema); - } -#endif - - if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; - }else{ - db->flags &= ~mask; - if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; - } - - /* Many of the flag-pragmas modify the code generated by the SQL - ** compiler (eg. count_changes). So add an opcode to expire all - ** compiled SQL statements after modifying a pragma value. - */ - sqlite3VdbeAddOp0(v, OP_Expire); - setAllPagerFlags(db); - } - break; - } -#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ - -#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS - /* - ** PRAGMA table_info(
    ) - ** - ** Return a single row for each column of the named table. The columns of - ** the returned data set are: - ** - ** cid: Column id (numbered from left to right, starting at 0) - ** name: Column name - ** type: Column declaration type. - ** notnull: True if 'NOT NULL' is part of column declaration - ** dflt_value: The default value for the column, if any. - */ - case PragTyp_TABLE_INFO: if( zRight ){ - Table *pTab; - pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); - if( pTab ){ - static const char *azCol[] = { - "cid", "name", "type", "notnull", "dflt_value", "pk" - }; - int i, k; - int nHidden = 0; - Column *pCol; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - pParse->nMem = 6; - sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) ); - sqlite3ViewGetColumnNames(pParse, pTab); - for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - if( IsHiddenColumn(pCol) ){ - nHidden++; - continue; - } - if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ - k = 0; - }else if( pPk==0 ){ - k = 1; - }else{ - for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} - } - assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); - sqlite3VdbeMultiLoad(v, 1, "issisi", - i-nHidden, - pCol->zName, - sqlite3ColumnType(pCol,""), - pCol->notNull ? 1 : 0, - pCol->pDflt ? pCol->pDflt->u.zToken : 0, - k); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6); - } - } - } - break; - - case PragTyp_STATS: { - static const char *azCol[] = { "table", "index", "width", "height" }; - Index *pIdx; - HashElem *i; - v = sqlite3GetVdbe(pParse); - pParse->nMem = 4; - sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); - for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ - Table *pTab = sqliteHashData(i); - sqlite3VdbeMultiLoad(v, 1, "ssii", - pTab->zName, - 0, - pTab->szTabRow, - pTab->nRowLogEst); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeMultiLoad(v, 2, "sii", - pIdx->zName, - pIdx->szIdxRow, - pIdx->aiRowLogEst[0]); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4); - } - } - } - break; - - case PragTyp_INDEX_INFO: if( zRight ){ - Index *pIdx; - Table *pTab; - pIdx = sqlite3FindIndex(db, zRight, zDb); - if( pIdx ){ - static const char *azCol[] = { - "seqno", "cid", "name", "desc", "coll", "key" - }; - int i; - int mx; - if( pPragma->iArg ){ - /* PRAGMA index_xinfo (newer version with more rows and columns) */ - mx = pIdx->nColumn; - pParse->nMem = 6; - }else{ - /* PRAGMA index_info (legacy version) */ - mx = pIdx->nKeyCol; - pParse->nMem = 3; - } - pTab = pIdx->pTable; - sqlite3CodeVerifySchema(pParse, iDb); - assert( pParse->nMem<=ArraySize(azCol) ); - setAllColumnNames(v, pParse->nMem, azCol); - for(i=0; iaiColumn[i]; - sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum, - cnum<0 ? 0 : pTab->aCol[cnum].zName); - if( pPragma->iArg ){ - sqlite3VdbeMultiLoad(v, 4, "isi", - pIdx->aSortOrder[i], - pIdx->azColl[i], - inKeyCol); - } - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); - } - } - } - break; - - case PragTyp_INDEX_LIST: if( zRight ){ - Index *pIdx; - Table *pTab; - int i; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - static const char *azCol[] = { - "seq", "name", "unique", "origin", "partial" - }; - v = sqlite3GetVdbe(pParse); - pParse->nMem = 5; - sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) ); - for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ - const char *azOrigin[] = { "c", "u", "pk" }; - sqlite3VdbeMultiLoad(v, 1, "isisi", - i, - pIdx->zName, - IsUniqueIndex(pIdx), - azOrigin[pIdx->idxType], - pIdx->pPartIdxWhere!=0); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); - } - } - } - break; - - case PragTyp_DATABASE_LIST: { - static const char *azCol[] = { "seq", "name", "file" }; - int i; - pParse->nMem = 3; - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); - for(i=0; inDb; i++){ - if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zDbSName!=0 ); - sqlite3VdbeMultiLoad(v, 1, "iss", - i, - db->aDb[i].zDbSName, - sqlite3BtreeGetFilename(db->aDb[i].pBt)); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); - } - } - break; - - case PragTyp_COLLATION_LIST: { - static const char *azCol[] = { "seq", "name" }; - int i = 0; - HashElem *p; - pParse->nMem = 2; - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); - for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ - CollSeq *pColl = (CollSeq *)sqliteHashData(p); - sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); - } - } - break; -#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY - case PragTyp_FOREIGN_KEY_LIST: if( zRight ){ - FKey *pFK; - Table *pTab; - pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - v = sqlite3GetVdbe(pParse); - pFK = pTab->pFKey; - if( pFK ){ - static const char *azCol[] = { - "id", "seq", "table", "from", "to", "on_update", "on_delete", - "match" - }; - int i = 0; - pParse->nMem = 8; - sqlite3CodeVerifySchema(pParse, iDb); - setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) ); - while(pFK){ - int j; - for(j=0; jnCol; j++){ - sqlite3VdbeMultiLoad(v, 1, "iissssss", - i, - j, - pFK->zTo, - pTab->aCol[pFK->aCol[j].iFrom].zName, - pFK->aCol[j].zCol, - actionName(pFK->aAction[1]), /* ON UPDATE */ - actionName(pFK->aAction[0]), /* ON DELETE */ - "NONE"); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8); - } - ++i; - pFK = pFK->pNextFrom; - } - } - } - } - break; -#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - -#ifndef SQLITE_OMIT_FOREIGN_KEY -#ifndef SQLITE_OMIT_TRIGGER - case PragTyp_FOREIGN_KEY_CHECK: { - FKey *pFK; /* A foreign key constraint */ - Table *pTab; /* Child table contain "REFERENCES" keyword */ - Table *pParent; /* Parent table that child points to */ - Index *pIdx; /* Index in the parent table */ - int i; /* Loop counter: Foreign key number for pTab */ - int j; /* Loop counter: Field of the foreign key */ - HashElem *k; /* Loop counter: Next table in schema */ - int x; /* result variable */ - int regResult; /* 3 registers to hold a result row */ - int regKey; /* Register to hold key for checking the FK */ - int regRow; /* Registers to hold a row from pTab */ - int addrTop; /* Top of a loop checking foreign keys */ - int addrOk; /* Jump here if the key is OK */ - int *aiCols; /* child to parent column mapping */ - static const char *azCol[] = { "table", "rowid", "parent", "fkid" }; - - regResult = pParse->nMem+1; - pParse->nMem += 4; - regKey = ++pParse->nMem; - regRow = ++pParse->nMem; - v = sqlite3GetVdbe(pParse); - setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) ); - sqlite3CodeVerifySchema(pParse, iDb); - k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); - while( k ){ - if( zRight ){ - pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); - k = 0; - }else{ - pTab = (Table*)sqliteHashData(k); - k = sqliteHashNext(k); - } - if( pTab==0 || pTab->pFKey==0 ) continue; - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; - sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); - sqlite3VdbeLoadString(v, regResult, pTab->zName); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3FindTable(db, pFK->zTo, zDb); - if( pParent==0 ) continue; - pIdx = 0; - sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); - x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); - if( x==0 ){ - if( pIdx==0 ){ - sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); - }else{ - sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - } - }else{ - k = 0; - break; - } - } - assert( pParse->nErr>0 || pFK==0 ); - if( pFK ) break; - if( pParse->nTabnTab = i; - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = sqlite3FindTable(db, pFK->zTo, zDb); - pIdx = 0; - aiCols = 0; - if( pParent ){ - x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); - assert( x==0 ); - } - addrOk = sqlite3VdbeMakeLabel(v); - if( pParent && pIdx==0 ){ - int iKey = pFK->aCol[0].iFrom; - assert( iKey>=0 && iKeynCol ); - if( iKey!=pTab->iPKey ){ - sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow); - sqlite3ColumnDefault(v, pTab, iKey, regRow); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v); - }else{ - sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow); - } - sqlite3VdbeAddOp3(v, OP_SeekRowid, i, 0, regRow); VdbeCoverage(v); - sqlite3VdbeGoto(v, addrOk); - sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); - }else{ - for(j=0; jnCol; j++){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, - aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j); - sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); - } - if( pParent ){ - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, - sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); - VdbeCoverage(v); - } - } - sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); - sqlite3VdbeMultiLoad(v, regResult+2, "si", pFK->zTo, i-1); - sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); - sqlite3VdbeResolveLabel(v, addrOk); - sqlite3DbFree(db, aiCols); - } - sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addrTop); - } - } - break; -#endif /* !defined(SQLITE_OMIT_TRIGGER) */ -#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - -#ifndef NDEBUG - case PragTyp_PARSER_TRACE: { - if( zRight ){ - if( sqlite3GetBoolean(zRight, 0) ){ - sqlite3ParserTrace(stdout, "parser: "); - }else{ - sqlite3ParserTrace(0, 0); - } - } - } - break; -#endif - - /* Reinstall the LIKE and GLOB functions. The variant of LIKE - ** used will be case sensitive or not depending on the RHS. - */ - case PragTyp_CASE_SENSITIVE_LIKE: { - if( zRight ){ - sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); - } - } - break; - -#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX -# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 -#endif - -#ifndef SQLITE_OMIT_INTEGRITY_CHECK - /* Pragma "quick_check" is reduced version of - ** integrity_check designed to detect most database corruption - ** without most of the overhead of a full integrity-check. - */ - case PragTyp_INTEGRITY_CHECK: { - int i, j, addr, mxErr; - - int isQuick = (sqlite3Tolower(zLeft[0])=='q'); - - /* If the PRAGMA command was of the form "PRAGMA .integrity_check", - ** then iDb is set to the index of the database identified by . - ** In this case, the integrity of database iDb only is verified by - ** the VDBE created below. - ** - ** Otherwise, if the command was simply "PRAGMA integrity_check" (or - ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb - ** to -1 here, to indicate that the VDBE should verify the integrity - ** of all attached databases. */ - assert( iDb>=0 ); - assert( iDb==0 || pId2->z ); - if( pId2->z==0 ) iDb = -1; - - /* Initialize the VDBE program */ - pParse->nMem = 6; - setOneColumnName(v, "integrity_check"); - - /* Set the maximum error count */ - mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; - if( zRight ){ - sqlite3GetInt32(zRight, &mxErr); - if( mxErr<=0 ){ - mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; - } - } - sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */ - - /* Do an integrity check on each database file */ - for(i=0; inDb; i++){ - HashElem *x; - Hash *pTbls; - int *aRoot; - int cnt = 0; - int mxIdx = 0; - int nIdx; - - if( OMIT_TEMPDB && i==1 ) continue; - if( iDb>=0 && i!=iDb ) continue; - - sqlite3CodeVerifySchema(pParse, i); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - - /* Do an integrity check of the B-Tree - ** - ** Begin by finding the root pages numbers - ** for all tables and indices in the database. - */ - assert( sqlite3SchemaMutexHeld(db, i, 0) ); - pTbls = &db->aDb[i].pSchema->tblHash; - for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; - if( HasRowid(pTab) ) cnt++; - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } - if( nIdx>mxIdx ) mxIdx = nIdx; - } - aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); - if( aRoot==0 ) break; - for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx; - if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - aRoot[cnt++] = pIdx->tnum; - } - } - aRoot[cnt] = 0; - - /* Make sure sufficient number of registers have been allocated */ - pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); - - /* Do the b-tree integrity checks */ - sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); - sqlite3VdbeChangeP5(v, (u8)i); - addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, - sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), - P4_DYNAMIC); - sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2); - sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1); - sqlite3VdbeJumpHere(v, addr); - - /* Make sure all the indices are constructed correctly. - */ - for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){ - Table *pTab = sqliteHashData(x); - Index *pIdx, *pPk; - Index *pPrior = 0; - int loopTop; - int iDataCur, iIdxCur; - int r1 = -1; - - if( pTab->pIndex==0 ) continue; - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeJumpHere(v, addr); - sqlite3ExprCacheClear(pParse); - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, - 1, 0, &iDataCur, &iIdxCur); - sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ - } - assert( pParse->nMem>=8+j ); - assert( sqlite3NoTempsInRange(pParse,1,7+j) ); - sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); - loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); - /* Verify that all NOT NULL columns really are NOT NULL */ - for(j=0; jnCol; j++){ - char *zErr; - int jmp2, jmp3; - if( j==pTab->iPKey ) continue; - if( pTab->aCol[j].notNull==0 ) continue; - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); - jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ - zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, - pTab->aCol[j].zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); - sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeJumpHere(v, jmp3); - } - /* Validate index entries for the current row */ - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int jmp2, jmp3, jmp4, jmp5; - int ckUniq = sqlite3VdbeMakeLabel(v); - if( pPk==pIdx ) continue; - r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, - pPrior, r1); - pPrior = pIdx; - sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */ - /* Verify that an index entry exists for the current table row */ - jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, - pIdx->nColumn); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ - sqlite3VdbeLoadString(v, 3, "row "); - sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - sqlite3VdbeLoadString(v, 4, " missing from index "); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v); - sqlite3VdbeAddOp0(v, OP_Halt); - sqlite3VdbeJumpHere(v, jmp2); - /* For UNIQUE indexes, verify that only one entry exists with the - ** current key. The entry is unique if (1) any column is NULL - ** or (2) the next entry has a different key */ - if( IsUniqueIndex(pIdx) ){ - int uniqOk = sqlite3VdbeMakeLabel(v); - int jmp6; - int kk; - for(kk=0; kknKeyCol; kk++){ - int iCol = pIdx->aiColumn[kk]; - assert( iCol!=XN_ROWID && iColnCol ); - if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; - sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); - VdbeCoverage(v); - } - jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); - sqlite3VdbeGoto(v, uniqOk); - sqlite3VdbeJumpHere(v, jmp6); - sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, - pIdx->nKeyCol); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */ - sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); - sqlite3VdbeGoto(v, jmp5); - sqlite3VdbeResolveLabel(v, uniqOk); - } - sqlite3VdbeJumpHere(v, jmp4); - sqlite3ResolvePartIdxLabel(pParse, jmp3); - } - sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, loopTop-1); -#ifndef SQLITE_OMIT_BTREECOUNT - sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - if( pPk==pIdx ) continue; - addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - sqlite3VdbeLoadString(v, 3, pIdx->zName); - sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7); - sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1); - } -#endif /* SQLITE_OMIT_BTREECOUNT */ - } - } - { - static const int iLn = VDBE_OFFSET_LINENO(2); - static const VdbeOpList endCode[] = { - { OP_AddImm, 1, 0, 0}, /* 0 */ - { OP_If, 1, 4, 0}, /* 1 */ - { OP_String8, 0, 3, 0}, /* 2 */ - { OP_ResultRow, 3, 1, 0}, /* 3 */ - }; - VdbeOp *aOp; - - aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); - if( aOp ){ - aOp[0].p2 = -mxErr; - aOp[2].p4type = P4_STATIC; - aOp[2].p4.z = "ok"; - } - } - } - break; -#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ - -#ifndef SQLITE_OMIT_UTF16 - /* - ** PRAGMA encoding - ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" - ** - ** In its first form, this pragma returns the encoding of the main - ** database. If the database is not initialized, it is initialized now. - ** - ** The second form of this pragma is a no-op if the main database file - ** has not already been initialized. In this case it sets the default - ** encoding that will be used for the main database file if a new file - ** is created. If an existing main database file is opened, then the - ** default text encoding for the existing database is used. - ** - ** In all cases new databases created using the ATTACH command are - ** created to use the same default text encoding as the main database. If - ** the main database has not been initialized and/or created when ATTACH - ** is executed, this is done before the ATTACH operation. - ** - ** In the second form this pragma sets the text encoding to be used in - ** new database files created using this database handle. It is only - ** useful if invoked immediately after the main database i - */ - case PragTyp_ENCODING: { - static const struct EncName { - char *zName; - u8 enc; - } encnames[] = { - { "UTF8", SQLITE_UTF8 }, - { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */ - { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */ - { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */ - { "UTF16le", SQLITE_UTF16LE }, - { "UTF16be", SQLITE_UTF16BE }, - { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ - { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ - { 0, 0 } - }; - const struct EncName *pEnc; - if( !zRight ){ /* "PRAGMA encoding" */ - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); - assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); - assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); - returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName); - }else{ /* "PRAGMA encoding = XXX" */ - /* Only change the value of sqlite.enc if the database handle is not - ** initialized. If the main database exists, the new sqlite.enc value - ** will be overwritten when the schema is next loaded. If it does not - ** already exists, it will be created to use the new encoding value. - */ - if( - !(DbHasProperty(db, 0, DB_SchemaLoaded)) || - DbHasProperty(db, 0, DB_Empty) - ){ - for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ - if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ - SCHEMA_ENC(db) = ENC(db) = - pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; - break; - } - } - if( !pEnc->zName ){ - sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); - } - } - } - } - break; -#endif /* SQLITE_OMIT_UTF16 */ - -#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS - /* - ** PRAGMA [schema.]schema_version - ** PRAGMA [schema.]schema_version = - ** - ** PRAGMA [schema.]user_version - ** PRAGMA [schema.]user_version = - ** - ** PRAGMA [schema.]freelist_count - ** - ** PRAGMA [schema.]data_version - ** - ** PRAGMA [schema.]application_id - ** PRAGMA [schema.]application_id = - ** - ** The pragma's schema_version and user_version are used to set or get - ** the value of the schema-version and user-version, respectively. Both - ** the schema-version and the user-version are 32-bit signed integers - ** stored in the database header. - ** - ** The schema-cookie is usually only manipulated internally by SQLite. It - ** is incremented by SQLite whenever the database schema is modified (by - ** creating or dropping a table or index). The schema version is used by - ** SQLite each time a query is executed to ensure that the internal cache - ** of the schema used when compiling the SQL query matches the schema of - ** the database against which the compiled query is actually executed. - ** Subverting this mechanism by using "PRAGMA schema_version" to modify - ** the schema-version is potentially dangerous and may lead to program - ** crashes or database corruption. Use with caution! - ** - ** The user-version is not used internally by SQLite. It may be used by - ** applications for any purpose. - */ - case PragTyp_HEADER_VALUE: { - int iCookie = pPragma->iArg; /* Which cookie to read or write */ - sqlite3VdbeUsesBtree(v, iDb); - if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){ - /* Write the specified cookie value */ - static const VdbeOpList setCookie[] = { - { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_SetCookie, 0, 0, 0}, /* 1 */ - }; - VdbeOp *aOp; - sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); - aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); - if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; - aOp[0].p1 = iDb; - aOp[1].p1 = iDb; - aOp[1].p2 = iCookie; - aOp[1].p3 = sqlite3Atoi(zRight); - }else{ - /* Read the specified cookie value */ - static const VdbeOpList readCookie[] = { - { OP_Transaction, 0, 0, 0}, /* 0 */ - { OP_ReadCookie, 0, 1, 0}, /* 1 */ - { OP_ResultRow, 1, 1, 0} - }; - VdbeOp *aOp; - sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); - aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); - if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; - aOp[0].p1 = iDb; - aOp[1].p1 = iDb; - aOp[1].p3 = iCookie; - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); - sqlite3VdbeReusable(v); - } - } - break; -#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ - -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - /* - ** PRAGMA compile_options - ** - ** Return the names of all compile-time options used in this build, - ** one option per row. - */ - case PragTyp_COMPILE_OPTIONS: { - int i = 0; - const char *zOpt; - pParse->nMem = 1; - setOneColumnName(v, "compile_option"); - while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ - sqlite3VdbeLoadString(v, 1, zOpt); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); - } - sqlite3VdbeReusable(v); - } - break; -#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ - -#ifndef SQLITE_OMIT_WAL - /* - ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate - ** - ** Checkpoint the database. - */ - case PragTyp_WAL_CHECKPOINT: { - static const char *azCol[] = { "busy", "log", "checkpointed" }; - int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); - int eMode = SQLITE_CHECKPOINT_PASSIVE; - if( zRight ){ - if( sqlite3StrICmp(zRight, "full")==0 ){ - eMode = SQLITE_CHECKPOINT_FULL; - }else if( sqlite3StrICmp(zRight, "restart")==0 ){ - eMode = SQLITE_CHECKPOINT_RESTART; - }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ - eMode = SQLITE_CHECKPOINT_TRUNCATE; - } - } - setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) ); - pParse->nMem = 3; - sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); - } - break; - - /* - ** PRAGMA wal_autocheckpoint - ** PRAGMA wal_autocheckpoint = N - ** - ** Configure a database connection to automatically checkpoint a database - ** after accumulating N frames in the log. Or query for the current value - ** of N. - */ - case PragTyp_WAL_AUTOCHECKPOINT: { - if( zRight ){ - sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); - } - returnSingleInt(v, "wal_autocheckpoint", - db->xWalCallback==sqlite3WalDefaultHook ? - SQLITE_PTR_TO_INT(db->pWalArg) : 0); - } - break; -#endif - - /* - ** PRAGMA shrink_memory - ** - ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database - ** connection on which it is invoked to free up as much memory as it - ** can, by calling sqlite3_db_release_memory(). - */ - case PragTyp_SHRINK_MEMORY: { - sqlite3_db_release_memory(db); - break; - } - - /* - ** PRAGMA busy_timeout - ** PRAGMA busy_timeout = N - ** - ** Call sqlite3_busy_timeout(db, N). Return the current timeout value - ** if one is set. If no busy handler or a different busy handler is set - ** then 0 is returned. Setting the busy_timeout to 0 or negative - ** disables the timeout. - */ - /*case PragTyp_BUSY_TIMEOUT*/ default: { - assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); - if( zRight ){ - sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); - } - returnSingleInt(v, "timeout", db->busyTimeout); - break; - } - - /* - ** PRAGMA soft_heap_limit - ** PRAGMA soft_heap_limit = N - ** - ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the - ** sqlite3_soft_heap_limit64() interface with the argument N, if N is - ** specified and is a non-negative integer. - ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always - ** returns the same integer that would be returned by the - ** sqlite3_soft_heap_limit64(-1) C-language function. - */ - case PragTyp_SOFT_HEAP_LIMIT: { - sqlite3_int64 N; - if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ - sqlite3_soft_heap_limit64(N); - } - returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); - break; - } - - /* - ** PRAGMA threads - ** PRAGMA threads = N - ** - ** Configure the maximum number of worker threads. Return the new - ** maximum, which might be less than requested. - */ - case PragTyp_THREADS: { - sqlite3_int64 N; - if( zRight - && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK - && N>=0 - ){ - sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); - } - returnSingleInt(v, "threads", - sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); - break; - } - -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - /* - ** Report the current state of file logs for all databases - */ - case PragTyp_LOCK_STATUS: { - static const char *const azLockName[] = { - "unlocked", "shared", "reserved", "pending", "exclusive" - }; - static const char *azCol[] = { "database", "status" }; - int i; - setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) ); - pParse->nMem = 2; - for(i=0; inDb; i++){ - Btree *pBt; - const char *zState = "unknown"; - int j; - if( db->aDb[i].zDbSName==0 ) continue; - pBt = db->aDb[i].pBt; - if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ - zState = "closed"; - }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, - SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ - zState = azLockName[j]; - } - sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); - } - break; - } -#endif - -#ifdef SQLITE_HAS_CODEC - case PragTyp_KEY: { - if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); - break; - } - case PragTyp_REKEY: { - if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); - break; - } - case PragTyp_HEXKEY: { - if( zRight ){ - u8 iByte; - int i; - char zKey[40]; - for(i=0, iByte=0; idb; - if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ - char *z; - if( zObj==0 ) zObj = "?"; - z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); - if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); - sqlite3DbFree(db, *pData->pzErrMsg); - *pData->pzErrMsg = z; - } - pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; -} - -/* -** This is the callback routine for the code that initializes the -** database. See sqlite3Init() below for additional information. -** This routine is also called from the OP_ParseSchema opcode of the VDBE. -** -** Each callback contains the following information: -** -** argv[0] = name of thing being created -** argv[1] = root page number for table or index. 0 for trigger or view. -** argv[2] = SQL text for the CREATE statement. -** -*/ -SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ - InitData *pData = (InitData*)pInit; - sqlite3 *db = pData->db; - int iDb = pData->iDb; - - assert( argc==3 ); - UNUSED_PARAMETER2(NotUsed, argc); - assert( sqlite3_mutex_held(db->mutex) ); - DbClearProperty(db, iDb, DB_Empty); - if( db->mallocFailed ){ - corruptSchema(pData, argv[0], 0); - return 1; - } - - assert( iDb>=0 && iDbnDb ); - if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ - if( argv[1]==0 ){ - corruptSchema(pData, argv[0], 0); - }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){ - /* Call the parser to process a CREATE TABLE, INDEX or VIEW. - ** But because db->init.busy is set to 1, no VDBE code is generated - ** or executed. All the parser does is build the internal data - ** structures that describe the table, index, or view. - */ - int rc; - u8 saved_iDb = db->init.iDb; - sqlite3_stmt *pStmt; - TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ - - assert( db->init.busy ); - db->init.iDb = iDb; - db->init.newTnum = sqlite3Atoi(argv[1]); - db->init.orphanTrigger = 0; - TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); - rc = db->errCode; - assert( (rc&0xFF)==(rcp&0xFF) ); - db->init.iDb = saved_iDb; - assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 ); - if( SQLITE_OK!=rc ){ - if( db->init.orphanTrigger ){ - assert( iDb==1 ); - }else{ - pData->rc = rc; - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(db); - }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[0], sqlite3_errmsg(db)); - } - } - } - sqlite3_finalize(pStmt); - }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ - corruptSchema(pData, argv[0], 0); - }else{ - /* If the SQL column is blank it means this is an index that - ** was created to be the PRIMARY KEY or to fulfill a UNIQUE - ** constraint for a CREATE TABLE. The index should have already - ** been created when we processed the CREATE TABLE. All we have - ** to do here is record the root page number for that index. - */ - Index *pIndex; - pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName); - if( pIndex==0 ){ - /* This can occur if there exists an index on a TEMP table which - ** has the same name as another index on a permanent index. Since - ** the permanent table is hidden by the TEMP table, we can also - ** safely ignore the index on the permanent table. - */ - /* Do Nothing */; - }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ - corruptSchema(pData, argv[0], "invalid rootpage"); - } - } - return 0; -} - -/* -** Attempt to read the database schema and initialize internal -** data structures for a single database file. The index of the -** database file is given by iDb. iDb==0 is used for the main -** database. iDb==1 should never be used. iDb>=2 is used for -** auxiliary databases. Return one of the SQLITE_ error codes to -** indicate success or failure. -*/ -static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ - int rc; - int i; -#ifndef SQLITE_OMIT_DEPRECATED - int size; -#endif - Db *pDb; - char const *azArg[4]; - int meta[5]; - InitData initData; - const char *zMasterName; - int openedTransaction = 0; - - assert( iDb>=0 && iDbnDb ); - assert( db->aDb[iDb].pSchema ); - assert( sqlite3_mutex_held(db->mutex) ); - assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - - /* Construct the in-memory representation schema tables (sqlite_master or - ** sqlite_temp_master) by invoking the parser directly. The appropriate - ** table name will be inserted automatically by the parser so we can just - ** use the abbreviation "x" here. The parser will also automatically tag - ** the schema table as read-only. */ - azArg[0] = zMasterName = SCHEMA_TABLE(iDb); - azArg[1] = "1"; - azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," - "rootpage integer,sql text)"; - azArg[3] = 0; - initData.db = db; - initData.iDb = iDb; - initData.rc = SQLITE_OK; - initData.pzErrMsg = pzErrMsg; - sqlite3InitCallback(&initData, 3, (char **)azArg, 0); - if( initData.rc ){ - rc = initData.rc; - goto error_out; - } - - /* Create a cursor to hold the database open - */ - pDb = &db->aDb[iDb]; - if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ - DbSetProperty(db, 1, DB_SchemaLoaded); - } - return SQLITE_OK; - } - - /* If there is not already a read-only (or read-write) transaction opened - ** on the b-tree database, open one now. If a transaction is opened, it - ** will be closed before this function returns. */ - sqlite3BtreeEnter(pDb->pBt); - if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ - rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); - if( rc!=SQLITE_OK ){ - sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); - goto initone_error_out; - } - openedTransaction = 1; - } - - /* Get the database meta information. - ** - ** Meta values are as follows: - ** meta[0] Schema cookie. Changes with each schema change. - ** meta[1] File format of schema layer. - ** meta[2] Size of the page cache. - ** meta[3] Largest rootpage (auto/incr_vacuum mode) - ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE - ** meta[5] User version - ** meta[6] Incremental vacuum mode - ** meta[7] unused - ** meta[8] unused - ** meta[9] unused - ** - ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to - ** the possible values of meta[4]. - */ - for(i=0; ipBt, i+1, (u32 *)&meta[i]); - } - pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; - - /* If opening a non-empty database, check the text encoding. For the - ** main database, set sqlite3.enc to the encoding of the main database. - ** For an attached db, it is an error if the encoding is not the same - ** as sqlite3.enc. - */ - if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ - if( iDb==0 ){ -#ifndef SQLITE_OMIT_UTF16 - u8 encoding; - /* If opening the main database, set ENC(db). */ - encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; - if( encoding==0 ) encoding = SQLITE_UTF8; - ENC(db) = encoding; -#else - ENC(db) = SQLITE_UTF8; -#endif - }else{ - /* If opening an attached database, the encoding much match ENC(db) */ - if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ - sqlite3SetString(pzErrMsg, db, "attached databases must use the same" - " text encoding as main database"); - rc = SQLITE_ERROR; - goto initone_error_out; - } - } - }else{ - DbSetProperty(db, iDb, DB_Empty); - } - pDb->pSchema->enc = ENC(db); - - if( pDb->pSchema->cache_size==0 ){ -#ifndef SQLITE_OMIT_DEPRECATED - size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); - if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } - pDb->pSchema->cache_size = size; -#else - pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; -#endif - sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); - } - - /* - ** file_format==1 Version 3.0.0. - ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN - ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults - ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants - */ - pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1]; - if( pDb->pSchema->file_format==0 ){ - pDb->pSchema->file_format = 1; - } - if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ - sqlite3SetString(pzErrMsg, db, "unsupported file format"); - rc = SQLITE_ERROR; - goto initone_error_out; - } - - /* Ticket #2804: When we open a database in the newer file format, - ** clear the legacy_file_format pragma flag so that a VACUUM will - ** not downgrade the database and thus invalidate any descending - ** indices that the user might have created. - */ - if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ - db->flags &= ~SQLITE_LegacyFileFmt; - } - - /* Read the schema information out of the schema tables - */ - assert( db->init.busy ); - { - char *zSql; - zSql = sqlite3MPrintf(db, - "SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid", - db->aDb[iDb].zDbSName, zMasterName); -#ifndef SQLITE_OMIT_AUTHORIZATION - { - sqlite3_xauth xAuth; - xAuth = db->xAuth; - db->xAuth = 0; -#endif - rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); -#ifndef SQLITE_OMIT_AUTHORIZATION - db->xAuth = xAuth; - } -#endif - if( rc==SQLITE_OK ) rc = initData.rc; - sqlite3DbFree(db, zSql); -#ifndef SQLITE_OMIT_ANALYZE - if( rc==SQLITE_OK ){ - sqlite3AnalysisLoad(db, iDb); - } -#endif - } - if( db->mallocFailed ){ - rc = SQLITE_NOMEM_BKPT; - sqlite3ResetAllSchemasOfConnection(db); - } - if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ - /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider - ** the schema loaded, even if errors occurred. In this situation the - ** current sqlite3_prepare() operation will fail, but the following one - ** will attempt to compile the supplied statement against whatever subset - ** of the schema was loaded before the error occurred. The primary - ** purpose of this is to allow access to the sqlite_master table - ** even when its contents have been corrupted. - */ - DbSetProperty(db, iDb, DB_SchemaLoaded); - rc = SQLITE_OK; - } - - /* Jump here for an error that occurs after successfully allocating - ** curMain and calling sqlite3BtreeEnter(). For an error that occurs - ** before that point, jump to error_out. - */ -initone_error_out: - if( openedTransaction ){ - sqlite3BtreeCommit(pDb->pBt); - } - sqlite3BtreeLeave(pDb->pBt); - -error_out: - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); - } - return rc; -} - -/* -** Initialize all database files - the main database file, the file -** used to store temporary tables, and any additional database files -** created using ATTACH statements. Return a success code. If an -** error occurs, write an error message into *pzErrMsg. -** -** After a database is initialized, the DB_SchemaLoaded bit is set -** bit is set in the flags field of the Db structure. If the database -** file was of zero-length, then the DB_Empty flag is also set. -*/ -SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ - int i, rc; - int commit_internal = !(db->flags&SQLITE_InternChanges); - - assert( sqlite3_mutex_held(db->mutex) ); - assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); - assert( db->init.busy==0 ); - rc = SQLITE_OK; - db->init.busy = 1; - ENC(db) = SCHEMA_ENC(db); - for(i=0; rc==SQLITE_OK && inDb; i++){ - if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; - rc = sqlite3InitOne(db, i, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, i); - } - } - - /* Once all the other databases have been initialized, load the schema - ** for the TEMP database. This is loaded last, as the TEMP database - ** schema may contain references to objects in other databases. - */ -#ifndef SQLITE_OMIT_TEMPDB - assert( db->nDb>1 ); - if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, 1); - } - } -#endif - - db->init.busy = 0; - if( rc==SQLITE_OK && commit_internal ){ - sqlite3CommitInternalChanges(db); - } - - return rc; -} - -/* -** This routine is a no-op if the database schema is already initialized. -** Otherwise, the schema is loaded. An error code is returned. -*/ -SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ - int rc = SQLITE_OK; - sqlite3 *db = pParse->db; - assert( sqlite3_mutex_held(db->mutex) ); - if( !db->init.busy ){ - rc = sqlite3Init(db, &pParse->zErrMsg); - } - if( rc!=SQLITE_OK ){ - pParse->rc = rc; - pParse->nErr++; - } - return rc; -} - - -/* -** Check schema cookies in all databases. If any cookie is out -** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies -** make no changes to pParse->rc. -*/ -static void schemaIsValid(Parse *pParse){ - sqlite3 *db = pParse->db; - int iDb; - int rc; - int cookie; - - assert( pParse->checkSchema ); - assert( sqlite3_mutex_held(db->mutex) ); - for(iDb=0; iDbnDb; iDb++){ - int openedTransaction = 0; /* True if a transaction is opened */ - Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ - if( pBt==0 ) continue; - - /* If there is not already a read-only (or read-write) transaction opened - ** on the b-tree database, open one now. If a transaction is opened, it - ** will be closed immediately after reading the meta-value. */ - if( !sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); - } - if( rc!=SQLITE_OK ) return; - openedTransaction = 1; - } - - /* Read the schema cookie from the database. If it does not match the - ** value stored as part of the in-memory schema representation, - ** set Parse.rc to SQLITE_SCHEMA. */ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - sqlite3ResetOneSchema(db, iDb); - pParse->rc = SQLITE_SCHEMA; - } - - /* Close the transaction, if one was opened. */ - if( openedTransaction ){ - sqlite3BtreeCommit(pBt); - } - } -} - -/* -** Convert a schema pointer into the iDb index that indicates -** which database file in db->aDb[] the schema refers to. -** -** If the same database is attached more than once, the first -** attached database is returned. -*/ -SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ - int i = -1000000; - - /* If pSchema is NULL, then return -1000000. This happens when code in - ** expr.c is trying to resolve a reference to a transient table (i.e. one - ** created by a sub-select). In this case the return value of this - ** function should never be used. - ** - ** We return -1000000 instead of the more usual -1 simply because using - ** -1000000 as the incorrect index into db->aDb[] is much - ** more likely to cause a segfault than -1 (of course there are assert() - ** statements too, but it never hurts to play the odds). - */ - assert( sqlite3_mutex_held(db->mutex) ); - if( pSchema ){ - for(i=0; ALWAYS(inDb); i++){ - if( db->aDb[i].pSchema==pSchema ){ - break; - } - } - assert( i>=0 && inDb ); - } - return i; -} - -/* -** Free all memory allocations in the pParse object -*/ -SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ - if( pParse ){ - sqlite3 *db = pParse->db; - sqlite3DbFree(db, pParse->aLabel); - sqlite3ExprListDelete(db, pParse->pConstExpr); - if( db ){ - assert( db->lookaside.bDisable >= pParse->disableLookaside ); - db->lookaside.bDisable -= pParse->disableLookaside; - } - pParse->disableLookaside = 0; - } -} - -/* -** Compile the UTF-8 encoded SQL statement zSql into a statement handle. -*/ -static int sqlite3Prepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ - Vdbe *pReprepare, /* VM being reprepared */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - char *zErrMsg = 0; /* Error message */ - int rc = SQLITE_OK; /* Result code */ - int i; /* Loop counter */ - Parse sParse; /* Parsing context */ - - memset(&sParse, 0, PARSE_HDR_SZ); - memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); - sParse.pReprepare = pReprepare; - assert( ppStmt && *ppStmt==0 ); - /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ - assert( sqlite3_mutex_held(db->mutex) ); - - /* Check to verify that it is possible to get a read lock on all - ** database schemas. The inability to get a read lock indicates that - ** some other database connection is holding a write-lock, which in - ** turn means that the other connection has made uncommitted changes - ** to the schema. - ** - ** Were we to proceed and prepare the statement against the uncommitted - ** schema changes and if those schema changes are subsequently rolled - ** back and different changes are made in their place, then when this - ** prepared statement goes to run the schema cookie would fail to detect - ** the schema change. Disaster would follow. - ** - ** This thread is currently holding mutexes on all Btrees (because - ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it - ** is not possible for another thread to start a new schema change - ** while this routine is running. Hence, we do not need to hold - ** locks on the schema, we just need to make sure nobody else is - ** holding them. - ** - ** Note that setting READ_UNCOMMITTED overrides most lock detection, - ** but it does *not* override schema lock detection, so this all still - ** works even if READ_UNCOMMITTED is set. - */ - for(i=0; inDb; i++) { - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - assert( sqlite3BtreeHoldsMutex(pBt) ); - rc = sqlite3BtreeSchemaLocked(pBt); - if( rc ){ - const char *zDb = db->aDb[i].zDbSName; - sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); - testcase( db->flags & SQLITE_ReadUncommitted ); - goto end_prepare; - } - } - } - - sqlite3VtabUnlockList(db); - - sParse.db = db; - if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ - char *zSqlCopy; - int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; - testcase( nBytes==mxLen ); - testcase( nBytes==mxLen+1 ); - if( nBytes>mxLen ){ - sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); - rc = sqlite3ApiExit(db, SQLITE_TOOBIG); - goto end_prepare; - } - zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); - if( zSqlCopy ){ - sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); - sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; - sqlite3DbFree(db, zSqlCopy); - }else{ - sParse.zTail = &zSql[nBytes]; - } - }else{ - sqlite3RunParser(&sParse, zSql, &zErrMsg); - } - assert( 0==sParse.nQueryLoop ); - - if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK; - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } - if( db->mallocFailed ){ - sParse.rc = SQLITE_NOMEM_BKPT; - } - if( pzTail ){ - *pzTail = sParse.zTail; - } - rc = sParse.rc; - -#ifndef SQLITE_OMIT_EXPLAIN - if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ - static const char * const azColName[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", - "selectid", "order", "from", "detail" - }; - int iFirst, mx; - if( sParse.explain==2 ){ - sqlite3VdbeSetNumCols(sParse.pVdbe, 4); - iFirst = 8; - mx = 12; - }else{ - sqlite3VdbeSetNumCols(sParse.pVdbe, 8); - iFirst = 0; - mx = 8; - } - for(i=iFirst; iinit.busy==0 ){ - Vdbe *pVdbe = sParse.pVdbe; - sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag); - } - if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){ - sqlite3VdbeFinalize(sParse.pVdbe); - assert(!(*ppStmt)); - }else{ - *ppStmt = (sqlite3_stmt*)sParse.pVdbe; - } - - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); - }else{ - sqlite3Error(db, rc); - } - - /* Delete any TriggerPrg structures allocated while parsing this statement. */ - while( sParse.pTriggerPrg ){ - TriggerPrg *pT = sParse.pTriggerPrg; - sParse.pTriggerPrg = pT->pNext; - sqlite3DbFree(db, pT); - } - -end_prepare: - - sqlite3ParserReset(&sParse); - rc = sqlite3ApiExit(db, rc); - assert( (rc&db->errMask)==rc ); - return rc; -} -static int sqlite3LockAndPrepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ - Vdbe *pOld, /* VM being reprepared */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - int rc; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; -#endif - *ppStmt = 0; - if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ - return SQLITE_MISUSE_BKPT; - } - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); - if( rc==SQLITE_SCHEMA ){ - sqlite3_finalize(*ppStmt); - rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); - } - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - assert( rc==SQLITE_OK || *ppStmt==0 ); - return rc; -} - -/* -** Rerun the compilation of a statement after a schema change. -** -** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, -** if the statement cannot be recompiled because another connection has -** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error -** occurs, return SQLITE_SCHEMA. -*/ -SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ - int rc; - sqlite3_stmt *pNew; - const char *zSql; - sqlite3 *db; - - assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); - zSql = sqlite3_sql((sqlite3_stmt *)p); - assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ - db = sqlite3VdbeDb(p); - assert( sqlite3_mutex_held(db->mutex) ); - rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); - if( rc ){ - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(db); - } - assert( pNew==0 ); - return rc; - }else{ - assert( pNew!=0 ); - } - sqlite3VdbeSwap((Vdbe*)pNew, p); - sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); - sqlite3VdbeResetStepResult((Vdbe*)pNew); - sqlite3VdbeFinalize((Vdbe*)pNew); - return SQLITE_OK; -} - - -/* -** Two versions of the official API. Legacy and new use. In the legacy -** version, the original SQL text is not saved in the prepared statement -** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** sqlite3_step(). In the new version, the original SQL text is retained -** and the statement is automatically recompiled if an schema change -** occurs. -*/ -SQLITE_API int sqlite3_prepare( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - int rc; - rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); - assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ - return rc; -} -SQLITE_API int sqlite3_prepare_v2( - sqlite3 *db, /* Database handle. */ - const char *zSql, /* UTF-8 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const char **pzTail /* OUT: End of parsed string */ -){ - int rc; - rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail); - assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ - return rc; -} - - -#ifndef SQLITE_OMIT_UTF16 -/* -** Compile the UTF-16 encoded SQL statement zSql into a statement handle. -*/ -static int sqlite3Prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-16 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - /* This function currently works by first transforming the UTF-16 - ** encoded string to UTF-8, then invoking sqlite3_prepare(). The - ** tricky bit is figuring out the pointer to return in *pzTail. - */ - char *zSql8; - const char *zTail8 = 0; - int rc = SQLITE_OK; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; -#endif - *ppStmt = 0; - if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ - return SQLITE_MISUSE_BKPT; - } - if( nBytes>=0 ){ - int sz; - const char *z = (const char*)zSql; - for(sz=0; szmutex); - zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); - if( zSql8 ){ - rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8); - } - - if( zTail8 && pzTail ){ - /* If sqlite3_prepare returns a tail pointer, we calculate the - ** equivalent pointer into the UTF-16 string by counting the unicode - ** characters between zSql8 and zTail8, and then returning a pointer - ** the same number of characters into the UTF-16 string. - */ - int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); - *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); - } - sqlite3DbFree(db, zSql8); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Two versions of the official API. Legacy and new use. In the legacy -** version, the original SQL text is not saved in the prepared statement -** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** sqlite3_step(). In the new version, the original SQL text is retained -** and the statement is automatically recompiled if an schema change -** occurs. -*/ -SQLITE_API int sqlite3_prepare16( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-16 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - int rc; - rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); - assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ - return rc; -} -SQLITE_API int sqlite3_prepare16_v2( - sqlite3 *db, /* Database handle. */ - const void *zSql, /* UTF-16 encoded SQL statement. */ - int nBytes, /* Length of zSql in bytes. */ - sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ - const void **pzTail /* OUT: End of parsed string */ -){ - int rc; - rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail); - assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ - return rc; -} - -#endif /* SQLITE_OMIT_UTF16 */ - -/************** End of prepare.c *********************************************/ -/************** Begin file select.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that are called by the parser -** to handle SELECT statements in SQLite. -*/ -/* #include "sqliteInt.h" */ - -/* -** Trace output macros -*/ -#if SELECTTRACE_ENABLED -/***/ int sqlite3SelectTrace = 0; -# define SELECTTRACE(K,P,S,X) \ - if(sqlite3SelectTrace&(K)) \ - sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\ - (S)->zSelName,(S)),\ - sqlite3DebugPrintf X -#else -# define SELECTTRACE(K,P,S,X) -#endif - - -/* -** An instance of the following object is used to record information about -** how to process the DISTINCT keyword, to simplify passing that information -** into the selectInnerLoop() routine. -*/ -typedef struct DistinctCtx DistinctCtx; -struct DistinctCtx { - u8 isTnct; /* True if the DISTINCT keyword is present */ - u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ - int tabTnct; /* Ephemeral table used for DISTINCT processing */ - int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ -}; - -/* -** An instance of the following object is used to record information about -** the ORDER BY (or GROUP BY) clause of query is being coded. -*/ -typedef struct SortCtx SortCtx; -struct SortCtx { - ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ - int nOBSat; /* Number of ORDER BY terms satisfied by indices */ - int iECursor; /* Cursor number for the sorter */ - int regReturn; /* Register holding block-output return address */ - int labelBkOut; /* Start label for the block-output subroutine */ - int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ - int labelDone; /* Jump here when done, ex: LIMIT reached */ - u8 sortFlags; /* Zero or more SORTFLAG_* bits */ - u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */ -}; -#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ - -/* -** Delete all the content of a Select structure. Deallocate the structure -** itself only if bFree is true. -*/ -static void clearSelect(sqlite3 *db, Select *p, int bFree){ - while( p ){ - Select *pPrior = p->pPrior; - sqlite3ExprListDelete(db, p->pEList); - sqlite3SrcListDelete(db, p->pSrc); - sqlite3ExprDelete(db, p->pWhere); - sqlite3ExprListDelete(db, p->pGroupBy); - sqlite3ExprDelete(db, p->pHaving); - sqlite3ExprListDelete(db, p->pOrderBy); - sqlite3ExprDelete(db, p->pLimit); - sqlite3ExprDelete(db, p->pOffset); - if( p->pWith ) sqlite3WithDelete(db, p->pWith); - if( bFree ) sqlite3DbFree(db, p); - p = pPrior; - bFree = 1; - } -} - -/* -** Initialize a SelectDest structure. -*/ -SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ - pDest->eDest = (u8)eDest; - pDest->iSDParm = iParm; - pDest->zAffSdst = 0; - pDest->iSdst = 0; - pDest->nSdst = 0; -} - - -/* -** Allocate a new Select structure and return a pointer to that -** structure. -*/ -SQLITE_PRIVATE Select *sqlite3SelectNew( - Parse *pParse, /* Parsing context */ - ExprList *pEList, /* which columns to include in the result */ - SrcList *pSrc, /* the FROM clause -- which tables to scan */ - Expr *pWhere, /* the WHERE clause */ - ExprList *pGroupBy, /* the GROUP BY clause */ - Expr *pHaving, /* the HAVING clause */ - ExprList *pOrderBy, /* the ORDER BY clause */ - u32 selFlags, /* Flag parameters, such as SF_Distinct */ - Expr *pLimit, /* LIMIT value. NULL means not used */ - Expr *pOffset /* OFFSET value. NULL means no offset */ -){ - Select *pNew; - Select standin; - sqlite3 *db = pParse->db; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); - if( pNew==0 ){ - assert( db->mallocFailed ); - pNew = &standin; - } - if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0)); - } - pNew->pEList = pEList; - pNew->op = TK_SELECT; - pNew->selFlags = selFlags; - pNew->iLimit = 0; - pNew->iOffset = 0; -#if SELECTTRACE_ENABLED - pNew->zSelName[0] = 0; -#endif - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = 0; - if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); - pNew->pSrc = pSrc; - pNew->pWhere = pWhere; - pNew->pGroupBy = pGroupBy; - pNew->pHaving = pHaving; - pNew->pOrderBy = pOrderBy; - pNew->pPrior = 0; - pNew->pNext = 0; - pNew->pLimit = pLimit; - pNew->pOffset = pOffset; - pNew->pWith = 0; - assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); - if( db->mallocFailed ) { - clearSelect(db, pNew, pNew!=&standin); - pNew = 0; - }else{ - assert( pNew->pSrc!=0 || pParse->nErr>0 ); - } - assert( pNew!=&standin ); - return pNew; -} - -#if SELECTTRACE_ENABLED -/* -** Set the name of a Select object -*/ -SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){ - if( p && zName ){ - sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); - } -} -#endif - - -/* -** Delete the given Select structure and all of its substructures. -*/ -SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ - if( p ) clearSelect(db, p, 1); -} - -/* -** Return a pointer to the right-most SELECT statement in a compound. -*/ -static Select *findRightmost(Select *p){ - while( p->pNext ) p = p->pNext; - return p; -} - -/* -** Given 1 to 3 identifiers preceding the JOIN keyword, determine the -** type of join. Return an integer constant that expresses that type -** in terms of the following bit values: -** -** JT_INNER -** JT_CROSS -** JT_OUTER -** JT_NATURAL -** JT_LEFT -** JT_RIGHT -** -** A full outer join is the combination of JT_LEFT and JT_RIGHT. -** -** If an illegal or unsupported join type is seen, then still return -** a join type, but put an error in the pParse structure. -*/ -SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ - int jointype = 0; - Token *apAll[3]; - Token *p; - /* 0123456789 123456789 123456789 123 */ - static const char zKeyText[] = "naturaleftouterightfullinnercross"; - static const struct { - u8 i; /* Beginning of keyword text in zKeyText[] */ - u8 nChar; /* Length of the keyword in characters */ - u8 code; /* Join type mask */ - } aKeyword[] = { - /* natural */ { 0, 7, JT_NATURAL }, - /* left */ { 6, 4, JT_LEFT|JT_OUTER }, - /* outer */ { 10, 5, JT_OUTER }, - /* right */ { 14, 5, JT_RIGHT|JT_OUTER }, - /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, - /* inner */ { 23, 5, JT_INNER }, - /* cross */ { 28, 5, JT_INNER|JT_CROSS }, - }; - int i, j; - apAll[0] = pA; - apAll[1] = pB; - apAll[2] = pC; - for(i=0; i<3 && apAll[i]; i++){ - p = apAll[i]; - for(j=0; jn==aKeyword[j].nChar - && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ - jointype |= aKeyword[j].code; - break; - } - } - testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); - if( j>=ArraySize(aKeyword) ){ - jointype |= JT_ERROR; - break; - } - } - if( - (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || - (jointype & JT_ERROR)!=0 - ){ - const char *zSp = " "; - assert( pB!=0 ); - if( pC==0 ){ zSp++; } - sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " - "%T %T%s%T", pA, pB, zSp, pC); - jointype = JT_INNER; - }else if( (jointype & JT_OUTER)!=0 - && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ - sqlite3ErrorMsg(pParse, - "RIGHT and FULL OUTER JOINs are not currently supported"); - jointype = JT_INNER; - } - return jointype; -} - -/* -** Return the index of a column in a table. Return -1 if the column -** is not contained in the table. -*/ -static int columnIndex(Table *pTab, const char *zCol){ - int i; - for(i=0; inCol; i++){ - if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; - } - return -1; -} - -/* -** Search the first N tables in pSrc, from left to right, looking for a -** table that has a column named zCol. -** -** When found, set *piTab and *piCol to the table index and column index -** of the matching column and return TRUE. -** -** If not found, return FALSE. -*/ -static int tableAndColumnIndex( - SrcList *pSrc, /* Array of tables to search */ - int N, /* Number of tables in pSrc->a[] to search */ - const char *zCol, /* Name of the column we are looking for */ - int *piTab, /* Write index of pSrc->a[] here */ - int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ -){ - int i; /* For looping over tables in pSrc */ - int iCol; /* Index of column matching zCol */ - - assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ - for(i=0; ia[i].pTab, zCol); - if( iCol>=0 ){ - if( piTab ){ - *piTab = i; - *piCol = iCol; - } - return 1; - } - } - return 0; -} - -/* -** This function is used to add terms implied by JOIN syntax to the -** WHERE clause expression of a SELECT statement. The new term, which -** is ANDed with the existing WHERE clause, is of the form: -** -** (tab1.col1 = tab2.col2) -** -** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the -** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is -** column iColRight of tab2. -*/ -static void addWhereTerm( - Parse *pParse, /* Parsing context */ - SrcList *pSrc, /* List of tables in FROM clause */ - int iLeft, /* Index of first table to join in pSrc */ - int iColLeft, /* Index of column in first table */ - int iRight, /* Index of second table in pSrc */ - int iColRight, /* Index of column in second table */ - int isOuterJoin, /* True if this is an OUTER join */ - Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ -){ - sqlite3 *db = pParse->db; - Expr *pE1; - Expr *pE2; - Expr *pEq; - - assert( iLeftnSrc>iRight ); - assert( pSrc->a[iLeft].pTab ); - assert( pSrc->a[iRight].pTab ); - - pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); - pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); - - pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); - if( pEq && isOuterJoin ){ - ExprSetProperty(pEq, EP_FromJoin); - assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; - } - *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); -} - -/* -** Set the EP_FromJoin property on all terms of the given expression. -** And set the Expr.iRightJoinTable to iTable for every term in the -** expression. -** -** The EP_FromJoin property is used on terms of an expression to tell -** the LEFT OUTER JOIN processing logic that this term is part of the -** join restriction specified in the ON or USING clause and not a part -** of the more general WHERE clause. These terms are moved over to the -** WHERE clause during join processing but we need to remember that they -** originated in the ON or USING clause. -** -** The Expr.iRightJoinTable tells the WHERE clause processing that the -** expression depends on table iRightJoinTable even if that table is not -** explicitly mentioned in the expression. That information is needed -** for cases like this: -** -** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 -** -** The where clause needs to defer the handling of the t1.x=5 -** term until after the t2 loop of the join. In that way, a -** NULL t2 row will be inserted whenever t1.x!=5. If we do not -** defer the handling of t1.x=5, it will be processed immediately -** after the t1 loop and rows with t1.x!=5 will never appear in -** the output, which is incorrect. -*/ -static void setJoinExpr(Expr *p, int iTable){ - while( p ){ - ExprSetProperty(p, EP_FromJoin); - assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(p, EP_NoReduce); - p->iRightJoinTable = (i16)iTable; - if( p->op==TK_FUNCTION && p->x.pList ){ - int i; - for(i=0; ix.pList->nExpr; i++){ - setJoinExpr(p->x.pList->a[i].pExpr, iTable); - } - } - setJoinExpr(p->pLeft, iTable); - p = p->pRight; - } -} - -/* -** This routine processes the join information for a SELECT statement. -** ON and USING clauses are converted into extra terms of the WHERE clause. -** NATURAL joins also create extra WHERE clause terms. -** -** The terms of a FROM clause are contained in the Select.pSrc structure. -** The left most table is the first entry in Select.pSrc. The right-most -** table is the last entry. The join operator is held in the entry to -** the left. Thus entry 0 contains the join operator for the join between -** entries 0 and 1. Any ON or USING clauses associated with the join are -** also attached to the left entry. -** -** This routine returns the number of errors encountered. -*/ -static int sqliteProcessJoin(Parse *pParse, Select *p){ - SrcList *pSrc; /* All tables in the FROM clause */ - int i, j; /* Loop counters */ - struct SrcList_item *pLeft; /* Left table being joined */ - struct SrcList_item *pRight; /* Right table being joined */ - - pSrc = p->pSrc; - pLeft = &pSrc->a[0]; - pRight = &pLeft[1]; - for(i=0; inSrc-1; i++, pRight++, pLeft++){ - Table *pLeftTab = pLeft->pTab; - Table *pRightTab = pRight->pTab; - int isOuter; - - if( NEVER(pLeftTab==0 || pRightTab==0) ) continue; - isOuter = (pRight->fg.jointype & JT_OUTER)!=0; - - /* When the NATURAL keyword is present, add WHERE clause terms for - ** every column that the two tables have in common. - */ - if( pRight->fg.jointype & JT_NATURAL ){ - if( pRight->pOn || pRight->pUsing ){ - sqlite3ErrorMsg(pParse, "a NATURAL join may not have " - "an ON or USING clause", 0); - return 1; - } - for(j=0; jnCol; j++){ - char *zName; /* Name of column in the right table */ - int iLeft; /* Matching left table */ - int iLeftCol; /* Matching column in the left table */ - - zName = pRightTab->aCol[j].zName; - if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){ - addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, - isOuter, &p->pWhere); - } - } - } - - /* Disallow both ON and USING clauses in the same join - */ - if( pRight->pOn && pRight->pUsing ){ - sqlite3ErrorMsg(pParse, "cannot have both ON and USING " - "clauses in the same join"); - return 1; - } - - /* Add the ON clause to the end of the WHERE clause, connected by - ** an AND operator. - */ - if( pRight->pOn ){ - if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); - pRight->pOn = 0; - } - - /* Create extra terms on the WHERE clause for each column named - ** in the USING clause. Example: If the two tables to be joined are - ** A and B and the USING clause names X, Y, and Z, then add this - ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z - ** Report an error if any column mentioned in the USING clause is - ** not contained in both tables to be joined. - */ - if( pRight->pUsing ){ - IdList *pList = pRight->pUsing; - for(j=0; jnId; j++){ - char *zName; /* Name of the term in the USING clause */ - int iLeft; /* Table on the left with matching column name */ - int iLeftCol; /* Column number of matching column on the left */ - int iRightCol; /* Column number of matching column on the right */ - - zName = pList->a[j].zName; - iRightCol = columnIndex(pRightTab, zName); - if( iRightCol<0 - || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) - ){ - sqlite3ErrorMsg(pParse, "cannot join using column %s - column " - "not present in both tables", zName); - return 1; - } - addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, - isOuter, &p->pWhere); - } - } - } - return 0; -} - -/* Forward reference */ -static KeyInfo *keyInfoFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* Form the KeyInfo object from this ExprList */ - int iStart, /* Begin with this column of pList */ - int nExtra /* Add this many extra columns to the end */ -); - -/* -** Generate code that will push the record in registers regData -** through regData+nData-1 onto the sorter. -*/ -static void pushOntoSorter( - Parse *pParse, /* Parser context */ - SortCtx *pSort, /* Information about the ORDER BY clause */ - Select *pSelect, /* The whole SELECT statement */ - int regData, /* First register holding data to be sorted */ - int regOrigData, /* First register holding data before packing */ - int nData, /* Number of elements in the data array */ - int nPrefixReg /* No. of reg prior to regData available for use */ -){ - Vdbe *v = pParse->pVdbe; /* Stmt under construction */ - int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); - int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ - int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ - int regBase; /* Regs for sorter record */ - int regRecord = ++pParse->nMem; /* Assembled sorter record */ - int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ - int op; /* Opcode to add sorter record to sorter */ - int iLimit; /* LIMIT counter */ - - assert( bSeq==0 || bSeq==1 ); - assert( nData==1 || regData==regOrigData ); - if( nPrefixReg ){ - assert( nPrefixReg==nExpr+bSeq ); - regBase = regData - nExpr - bSeq; - }else{ - regBase = pParse->nMem + 1; - pParse->nMem += nBase; - } - assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); - iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; - pSort->labelDone = sqlite3VdbeMakeLabel(v); - sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, - SQLITE_ECEL_DUP|SQLITE_ECEL_REF); - if( bSeq ){ - sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); - } - if( nPrefixReg==0 ){ - sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); - } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); - if( nOBSat>0 ){ - int regPrevKey; /* The first nOBSat columns of the previous row */ - int addrFirst; /* Address of the OP_IfNot opcode */ - int addrJmp; /* Address of the OP_Jump opcode */ - VdbeOp *pOp; /* Opcode that opens the sorter */ - int nKey; /* Number of sorting key columns, including OP_Sequence */ - KeyInfo *pKI; /* Original KeyInfo on the sorter table */ - - regPrevKey = pParse->nMem+1; - pParse->nMem += pSort->nOBSat; - nKey = nExpr - pSort->nOBSat + bSeq; - if( bSeq ){ - addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); - }else{ - addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); - } - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); - pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); - if( pParse->db->mallocFailed ) return; - pOp->p2 = nKey + nData; - pKI = pOp->p4.pKeyInfo; - memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */ - sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); - testcase( pKI->nXField>2 ); - pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, - pKI->nXField-1); - addrJmp = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); - pSort->labelBkOut = sqlite3VdbeMakeLabel(v); - pSort->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); - sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); - if( iLimit ){ - sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); - VdbeCoverage(v); - } - sqlite3VdbeJumpHere(v, addrFirst); - sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); - sqlite3VdbeJumpHere(v, addrJmp); - } - if( pSort->sortFlags & SORTFLAG_UseSorter ){ - op = OP_SorterInsert; - }else{ - op = OP_IdxInsert; - } - sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord); - if( iLimit ){ - int addr; - int r1 = 0; - /* Fill the sorter until it contains LIMIT+OFFSET entries. (The iLimit - ** register is initialized with value of LIMIT+OFFSET.) After the sorter - ** fills up, delete the least entry in the sorter after each insert. - ** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */ - addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v); - sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor); - if( pSort->bOrderedInnerLoop ){ - r1 = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_Column, pSort->iECursor, nExpr, r1); - VdbeComment((v, "seq")); - } - sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor); - if( pSort->bOrderedInnerLoop ){ - /* If the inner loop is driven by an index such that values from - ** the same iteration of the inner loop are in sorted order, then - ** immediately jump to the next iteration of an inner loop if the - ** entry from the current iteration does not fit into the top - ** LIMIT+OFFSET entries of the sorter. */ - int iBrk = sqlite3VdbeCurrentAddr(v) + 2; - sqlite3VdbeAddOp3(v, OP_Eq, regBase+nExpr, iBrk, r1); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - VdbeCoverage(v); - } - sqlite3VdbeJumpHere(v, addr); - } -} - -/* -** Add code to implement the OFFSET -*/ -static void codeOffset( - Vdbe *v, /* Generate code into this VM */ - int iOffset, /* Register holding the offset counter */ - int iContinue /* Jump here to skip the current record */ -){ - if( iOffset>0 ){ - sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); - VdbeComment((v, "OFFSET")); - } -} - -/* -** Add code that will check to make sure the N registers starting at iMem -** form a distinct entry. iTab is a sorting index that holds previously -** seen combinations of the N values. A new entry is made in iTab -** if the current N values are new. -** -** A jump to addrRepeat is made and the N+1 values are popped from the -** stack if the top N elements are not distinct. -*/ -static void codeDistinct( - Parse *pParse, /* Parsing and code generating context */ - int iTab, /* A sorting index used to test for distinctness */ - int addrRepeat, /* Jump to here if not distinct */ - int N, /* Number of elements */ - int iMem /* First element */ -){ - Vdbe *v; - int r1; - - v = pParse->pVdbe; - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1); - sqlite3ReleaseTempReg(pParse, r1); -} - -/* -** This routine generates the code for the inside of the inner loop -** of a SELECT. -** -** If srcTab is negative, then the pEList expressions -** are evaluated in order to get the data for this row. If srcTab is -** zero or more, then data is pulled from srcTab and pEList is used only -** to get number columns and the datatype for each column. -*/ -static void selectInnerLoop( - Parse *pParse, /* The parser context */ - Select *p, /* The complete select statement being coded */ - ExprList *pEList, /* List of values being extracted */ - int srcTab, /* Pull data from this table */ - SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ - DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ - SelectDest *pDest, /* How to dispose of the results */ - int iContinue, /* Jump here to continue with next row */ - int iBreak /* Jump here to break out of the inner loop */ -){ - Vdbe *v = pParse->pVdbe; - int i; - int hasDistinct; /* True if the DISTINCT keyword is present */ - int regResult; /* Start of memory holding result set */ - int eDest = pDest->eDest; /* How to dispose of results */ - int iParm = pDest->iSDParm; /* First argument to disposal method */ - int nResultCol; /* Number of result columns */ - int nPrefixReg = 0; /* Number of extra registers before regResult */ - - assert( v ); - assert( pEList!=0 ); - hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; - if( pSort && pSort->pOrderBy==0 ) pSort = 0; - if( pSort==0 && !hasDistinct ){ - assert( iContinue!=0 ); - codeOffset(v, p->iOffset, iContinue); - } - - /* Pull the requested columns. - */ - nResultCol = pEList->nExpr; - - if( pDest->iSdst==0 ){ - if( pSort ){ - nPrefixReg = pSort->pOrderBy->nExpr; - if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; - pParse->nMem += nPrefixReg; - } - pDest->iSdst = pParse->nMem+1; - pParse->nMem += nResultCol; - }else if( pDest->iSdst+nResultCol > pParse->nMem ){ - /* This is an error condition that can result, for example, when a SELECT - ** on the right-hand side of an INSERT contains more result columns than - ** there are columns in the table on the left. The error will be caught - ** and reported later. But we need to make sure enough memory is allocated - ** to avoid other spurious errors in the meantime. */ - pParse->nMem += nResultCol; - } - pDest->nSdst = nResultCol; - regResult = pDest->iSdst; - if( srcTab>=0 ){ - for(i=0; ia[i].zName)); - } - }else if( eDest!=SRT_Exists ){ - /* If the destination is an EXISTS(...) expression, the actual - ** values returned by the SELECT are not required. - */ - u8 ecelFlags; - if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ - ecelFlags = SQLITE_ECEL_DUP; - }else{ - ecelFlags = 0; - } - sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags); - } - - /* If the DISTINCT keyword was present on the SELECT statement - ** and this row has been seen before, then do not make this row - ** part of the result. - */ - if( hasDistinct ){ - switch( pDistinct->eTnctType ){ - case WHERE_DISTINCT_ORDERED: { - VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ - int iJump; /* Jump destination */ - int regPrev; /* Previous row content */ - - /* Allocate space for the previous row */ - regPrev = pParse->nMem+1; - pParse->nMem += nResultCol; - - /* Change the OP_OpenEphemeral coded earlier to an OP_Null - ** sets the MEM_Cleared bit on the first register of the - ** previous value. This will cause the OP_Ne below to always - ** fail on the first iteration of the loop even if the first - ** row is all NULLs. - */ - sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); - pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); - pOp->opcode = OP_Null; - pOp->p1 = 1; - pOp->p2 = regPrev; - - iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; - for(i=0; ia[i].pExpr); - if( idb->mallocFailed ); - sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1); - break; - } - - case WHERE_DISTINCT_UNIQUE: { - sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); - break; - } - - default: { - assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); - codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, - regResult); - break; - } - } - if( pSort==0 ){ - codeOffset(v, p->iOffset, iContinue); - } - } - - switch( eDest ){ - /* In this mode, write each query result to the key of the temporary - ** table iParm. - */ -#ifndef SQLITE_OMIT_COMPOUND_SELECT - case SRT_Union: { - int r1; - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); - sqlite3ReleaseTempReg(pParse, r1); - break; - } - - /* Construct a record from the query result, but instead of - ** saving that record, use it as a key to delete elements from - ** the temporary table iParm. - */ - case SRT_Except: { - sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); - break; - } -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - - /* Store the result as data using a unique key. - */ - case SRT_Fifo: - case SRT_DistFifo: - case SRT_Table: - case SRT_EphemTab: { - int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); - testcase( eDest==SRT_Table ); - testcase( eDest==SRT_EphemTab ); - testcase( eDest==SRT_Fifo ); - testcase( eDest==SRT_DistFifo ); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); -#ifndef SQLITE_OMIT_CTE - if( eDest==SRT_DistFifo ){ - /* If the destination is DistFifo, then cursor (iParm+1) is open - ** on an ephemeral index. If the current row is already present - ** in the index, do not write it to the output. If not, add the - ** current row to the index and proceed with writing it to the - ** output table as well. */ - int addr = sqlite3VdbeCurrentAddr(v) + 4; - sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1); - assert( pSort==0 ); - } -#endif - if( pSort ){ - pushOntoSorter(pParse, pSort, p, r1+nPrefixReg,regResult,1,nPrefixReg); - }else{ - int r2 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); - sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3ReleaseTempReg(pParse, r2); - } - sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); - break; - } - -#ifndef SQLITE_OMIT_SUBQUERY - /* If we are creating a set for an "expr IN (SELECT ...)" construct, - ** then there should be a single item on the stack. Write this - ** item into the set table with bogus data. - */ - case SRT_Set: { - if( pSort ){ - /* At first glance you would think we could optimize out the - ** ORDER BY in this case since the order of entries in the set - ** does not matter. But there might be a LIMIT clause, in which - ** case the order does matter */ - pushOntoSorter( - pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); - }else{ - int r1 = sqlite3GetTempReg(pParse); - assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, - r1, pDest->zAffSdst, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); - sqlite3ReleaseTempReg(pParse, r1); - } - break; - } - - /* If any row exist in the result set, record that fact and abort. - */ - case SRT_Exists: { - sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); - /* The LIMIT clause will terminate the loop for us */ - break; - } - - /* If this is a scalar select that is part of an expression, then - ** store the results in the appropriate memory cell or array of - ** memory cells and break out of the scan loop. - */ - case SRT_Mem: { - assert( nResultCol==pDest->nSdst ); - if( pSort ){ - pushOntoSorter( - pParse, pSort, p, regResult, regResult, nResultCol, nPrefixReg); - }else{ - assert( regResult==iParm ); - /* The LIMIT clause will jump out of the loop for us */ - } - break; - } -#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ - - case SRT_Coroutine: /* Send data to a co-routine */ - case SRT_Output: { /* Return the results */ - testcase( eDest==SRT_Coroutine ); - testcase( eDest==SRT_Output ); - if( pSort ){ - pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol, - nPrefixReg); - }else if( eDest==SRT_Coroutine ){ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); - }else{ - sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); - } - break; - } - -#ifndef SQLITE_OMIT_CTE - /* Write the results into a priority queue that is order according to - ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an - ** index with pSO->nExpr+2 columns. Build a key using pSO for the first - ** pSO->nExpr columns, then make sure all keys are unique by adding a - ** final OP_Sequence column. The last column is the record as a blob. - */ - case SRT_DistQueue: - case SRT_Queue: { - int nKey; - int r1, r2, r3; - int addrTest = 0; - ExprList *pSO; - pSO = pDest->pOrderBy; - assert( pSO ); - nKey = pSO->nExpr; - r1 = sqlite3GetTempReg(pParse); - r2 = sqlite3GetTempRange(pParse, nKey+2); - r3 = r2+nKey+1; - if( eDest==SRT_DistQueue ){ - /* If the destination is DistQueue, then cursor (iParm+1) is open - ** on a second ephemeral index that holds all values every previously - ** added to the queue. */ - addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, - regResult, nResultCol); - VdbeCoverage(v); - } - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); - if( eDest==SRT_DistQueue ){ - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - } - for(i=0; ia[i].u.x.iOrderByCol - 1, - r2+i); - } - sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); - sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); - if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); - sqlite3ReleaseTempReg(pParse, r1); - sqlite3ReleaseTempRange(pParse, r2, nKey+2); - break; - } -#endif /* SQLITE_OMIT_CTE */ - - - -#if !defined(SQLITE_OMIT_TRIGGER) - /* Discard the results. This is used for SELECT statements inside - ** the body of a TRIGGER. The purpose of such selects is to call - ** user-defined functions that have side effects. We do not care - ** about the actual results of the select. - */ - default: { - assert( eDest==SRT_Discard ); - break; - } -#endif - } - - /* Jump to the end of the loop if the LIMIT is reached. Except, if - ** there is a sorter, in which case the sorter has already limited - ** the output for us. - */ - if( pSort==0 && p->iLimit ){ - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); - } -} - -/* -** Allocate a KeyInfo object sufficient for an index of N key columns and -** X extra columns. -*/ -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ - int nExtra = (N+X)*(sizeof(CollSeq*)+1); - KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); - if( p ){ - p->aSortOrder = (u8*)&p->aColl[N+X]; - p->nField = (u16)N; - p->nXField = (u16)X; - p->enc = ENC(db); - p->db = db; - p->nRef = 1; - memset(&p[1], 0, nExtra); - }else{ - sqlite3OomFault(db); - } - return p; -} - -/* -** Deallocate a KeyInfo object -*/ -SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ - if( p ){ - assert( p->nRef>0 ); - p->nRef--; - if( p->nRef==0 ) sqlite3DbFree(p->db, p); - } -} - -/* -** Make a new pointer to a KeyInfo object -*/ -SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){ - if( p ){ - assert( p->nRef>0 ); - p->nRef++; - } - return p; -} - -#ifdef SQLITE_DEBUG -/* -** Return TRUE if a KeyInfo object can be change. The KeyInfo object -** can only be changed if this is just a single reference to the object. -** -** This routine is used only inside of assert() statements. -*/ -SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } -#endif /* SQLITE_DEBUG */ - -/* -** Given an expression list, generate a KeyInfo structure that records -** the collating sequence for each expression in that expression list. -** -** If the ExprList is an ORDER BY or GROUP BY clause then the resulting -** KeyInfo structure is appropriate for initializing a virtual index to -** implement that clause. If the ExprList is the result set of a SELECT -** then the KeyInfo structure is appropriate for initializing a virtual -** index to implement a DISTINCT test. -** -** Space to hold the KeyInfo structure is obtained from malloc. The calling -** function is responsible for seeing that this structure is eventually -** freed. -*/ -static KeyInfo *keyInfoFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* Form the KeyInfo object from this ExprList */ - int iStart, /* Begin with this column of pList */ - int nExtra /* Add this many extra columns to the end */ -){ - int nExpr; - KeyInfo *pInfo; - struct ExprList_item *pItem; - sqlite3 *db = pParse->db; - int i; - - nExpr = pList->nExpr; - pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); - if( pInfo ){ - assert( sqlite3KeyInfoIsWriteable(pInfo) ); - for(i=iStart, pItem=pList->a+iStart; ipExpr); - if( !pColl ) pColl = db->pDfltColl; - pInfo->aColl[i-iStart] = pColl; - pInfo->aSortOrder[i-iStart] = pItem->sortOrder; - } - } - return pInfo; -} - -/* -** Name of the connection operator, used for error messages. -*/ -static const char *selectOpName(int id){ - char *z; - switch( id ){ - case TK_ALL: z = "UNION ALL"; break; - case TK_INTERSECT: z = "INTERSECT"; break; - case TK_EXCEPT: z = "EXCEPT"; break; - default: z = "UNION"; break; - } - return z; -} - -#ifndef SQLITE_OMIT_EXPLAIN -/* -** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function -** is a no-op. Otherwise, it adds a single row of output to the EQP result, -** where the caption is of the form: -** -** "USE TEMP B-TREE FOR xxx" -** -** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which -** is determined by the zUsage argument. -*/ -static void explainTempTable(Parse *pParse, const char *zUsage){ - if( pParse->explain==2 ){ - Vdbe *v = pParse->pVdbe; - char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } -} - -/* -** Assign expression b to lvalue a. A second, no-op, version of this macro -** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code -** in sqlite3Select() to assign values to structure member variables that -** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the -** code with #ifndef directives. -*/ -# define explainSetInteger(a, b) a = b - -#else -/* No-op versions of the explainXXX() functions and macros. */ -# define explainTempTable(y,z) -# define explainSetInteger(y,z) -#endif - -#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT) -/* -** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function -** is a no-op. Otherwise, it adds a single row of output to the EQP result, -** where the caption is of one of the two forms: -** -** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)" -** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)" -** -** where iSub1 and iSub2 are the integers passed as the corresponding -** function parameters, and op is the text representation of the parameter -** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT, -** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is -** false, or the second form if it is true. -*/ -static void explainComposite( - Parse *pParse, /* Parse context */ - int op, /* One of TK_UNION, TK_EXCEPT etc. */ - int iSub1, /* Subquery id 1 */ - int iSub2, /* Subquery id 2 */ - int bUseTmp /* True if a temp table was used */ -){ - assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL ); - if( pParse->explain==2 ){ - Vdbe *v = pParse->pVdbe; - char *zMsg = sqlite3MPrintf( - pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2, - bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op) - ); - sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC); - } -} -#else -/* No-op versions of the explainXXX() functions and macros. */ -# define explainComposite(v,w,x,y,z) -#endif - -/* -** If the inner loop was generated using a non-null pOrderBy argument, -** then the results were placed in a sorter. After the loop is terminated -** we need to run the sorter and output the results. The following -** routine generates the code needed to do that. -*/ -static void generateSortTail( - Parse *pParse, /* Parsing context */ - Select *p, /* The SELECT statement */ - SortCtx *pSort, /* Information on the ORDER BY clause */ - int nColumn, /* Number of columns of data */ - SelectDest *pDest /* Write the sorted results here */ -){ - Vdbe *v = pParse->pVdbe; /* The prepared statement */ - int addrBreak = pSort->labelDone; /* Jump here to exit loop */ - int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ - int addr; - int addrOnce = 0; - int iTab; - ExprList *pOrderBy = pSort->pOrderBy; - int eDest = pDest->eDest; - int iParm = pDest->iSDParm; - int regRow; - int regRowid; - int nKey; - int iSortTab; /* Sorter cursor to read from */ - int nSortData; /* Trailing values to read from sorter */ - int i; - int bSeq; /* True if sorter record includes seq. no. */ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - struct ExprList_item *aOutEx = p->pEList->a; -#endif - - assert( addrBreak<0 ); - if( pSort->labelBkOut ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); - sqlite3VdbeGoto(v, addrBreak); - sqlite3VdbeResolveLabel(v, pSort->labelBkOut); - } - iTab = pSort->iECursor; - if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ - regRowid = 0; - regRow = pDest->iSdst; - nSortData = nColumn; - }else{ - regRowid = sqlite3GetTempReg(pParse); - regRow = sqlite3GetTempRange(pParse, nColumn); - nSortData = nColumn; - } - nKey = pOrderBy->nExpr - pSort->nOBSat; - if( pSort->sortFlags & SORTFLAG_UseSorter ){ - int regSortOut = ++pParse->nMem; - iSortTab = pParse->nTab++; - if( pSort->labelBkOut ){ - addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData); - if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); - addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); - VdbeCoverage(v); - codeOffset(v, p->iOffset, addrContinue); - sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); - bSeq = 0; - }else{ - addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); - codeOffset(v, p->iOffset, addrContinue); - iSortTab = iTab; - bSeq = 1; - } - for(i=0; izAffSdst) ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, - pDest->zAffSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid); - break; - } - case SRT_Mem: { - /* The LIMIT clause will terminate the loop for us */ - break; - } -#endif - default: { - assert( eDest==SRT_Output || eDest==SRT_Coroutine ); - testcase( eDest==SRT_Output ); - testcase( eDest==SRT_Coroutine ); - if( eDest==SRT_Output ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); - }else{ - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); - } - break; - } - } - if( regRowid ){ - if( eDest==SRT_Set ){ - sqlite3ReleaseTempRange(pParse, regRow, nColumn); - }else{ - sqlite3ReleaseTempReg(pParse, regRow); - } - sqlite3ReleaseTempReg(pParse, regRowid); - } - /* The bottom of the loop - */ - sqlite3VdbeResolveLabel(v, addrContinue); - if( pSort->sortFlags & SORTFLAG_UseSorter ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); - }else{ - sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); - } - if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); - sqlite3VdbeResolveLabel(v, addrBreak); -} - -/* -** Return a pointer to a string containing the 'declaration type' of the -** expression pExpr. The string may be treated as static by the caller. -** -** Also try to estimate the size of the returned value and return that -** result in *pEstWidth. -** -** The declaration type is the exact datatype definition extracted from the -** original CREATE TABLE statement if the expression is a column. The -** declaration type for a ROWID field is INTEGER. Exactly when an expression -** is considered a column can be complex in the presence of subqueries. The -** result-set expression in all of the following SELECT statements is -** considered a column by this function. -** -** SELECT col FROM tbl; -** SELECT (SELECT col FROM tbl; -** SELECT (SELECT col FROM tbl); -** SELECT abc FROM (SELECT col AS abc FROM tbl); -** -** The declaration type for any expression other than a column is NULL. -** -** This routine has either 3 or 6 parameters depending on whether or not -** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. -*/ -#ifdef SQLITE_ENABLE_COLUMN_METADATA -# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F) -#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ -# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F) -#endif -static const char *columnTypeImpl( - NameContext *pNC, - Expr *pExpr, -#ifdef SQLITE_ENABLE_COLUMN_METADATA - const char **pzOrigDb, - const char **pzOrigTab, - const char **pzOrigCol, -#endif - u8 *pEstWidth -){ - char const *zType = 0; - int j; - u8 estWidth = 1; -#ifdef SQLITE_ENABLE_COLUMN_METADATA - char const *zOrigDb = 0; - char const *zOrigTab = 0; - char const *zOrigCol = 0; -#endif - - assert( pExpr!=0 ); - assert( pNC->pSrcList!=0 ); - switch( pExpr->op ){ - case TK_AGG_COLUMN: - case TK_COLUMN: { - /* The expression is a column. Locate the table the column is being - ** extracted from in NameContext.pSrcList. This table may be real - ** database table or a subquery. - */ - Table *pTab = 0; /* Table structure column is extracted from */ - Select *pS = 0; /* Select the column is extracted from */ - int iCol = pExpr->iColumn; /* Index of column in pTab */ - testcase( pExpr->op==TK_AGG_COLUMN ); - testcase( pExpr->op==TK_COLUMN ); - while( pNC && !pTab ){ - SrcList *pTabList = pNC->pSrcList; - for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); - if( jnSrc ){ - pTab = pTabList->a[j].pTab; - pS = pTabList->a[j].pSelect; - }else{ - pNC = pNC->pNext; - } - } - - if( pTab==0 ){ - /* At one time, code such as "SELECT new.x" within a trigger would - ** cause this condition to run. Since then, we have restructured how - ** trigger code is generated and so this condition is no longer - ** possible. However, it can still be true for statements like - ** the following: - ** - ** CREATE TABLE t1(col INTEGER); - ** SELECT (SELECT t1.col) FROM FROM t1; - ** - ** when columnType() is called on the expression "t1.col" in the - ** sub-select. In this case, set the column type to NULL, even - ** though it should really be "INTEGER". - ** - ** This is not a problem, as the column type of "t1.col" is never - ** used. When columnType() is called on the expression - ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT - ** branch below. */ - break; - } - - assert( pTab && pExpr->pTab==pTab ); - if( pS ){ - /* The "table" is actually a sub-select or a view in the FROM clause - ** of the SELECT statement. Return the declaration type and origin - ** data for the result-set column of the sub-select. - */ - if( iCol>=0 && ALWAYS(iColpEList->nExpr) ){ - /* If iCol is less than zero, then the expression requests the - ** rowid of the sub-select or view. This expression is legal (see - ** test case misc2.2.2) - it always evaluates to NULL. - ** - ** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been - ** caught already by name resolution. - */ - NameContext sNC; - Expr *p = pS->pEList->a[iCol].pExpr; - sNC.pSrcList = pS->pSrc; - sNC.pNext = pNC; - sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth); - } - }else if( pTab->pSchema ){ - /* A real table */ - assert( !pS ); - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); -#ifdef SQLITE_ENABLE_COLUMN_METADATA - if( iCol<0 ){ - zType = "INTEGER"; - zOrigCol = "rowid"; - }else{ - zOrigCol = pTab->aCol[iCol].zName; - zType = sqlite3ColumnType(&pTab->aCol[iCol],0); - estWidth = pTab->aCol[iCol].szEst; - } - zOrigTab = pTab->zName; - if( pNC->pParse ){ - int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); - zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; - } -#else - if( iCol<0 ){ - zType = "INTEGER"; - }else{ - zType = sqlite3ColumnType(&pTab->aCol[iCol],0); - estWidth = pTab->aCol[iCol].szEst; - } -#endif - } - break; - } -#ifndef SQLITE_OMIT_SUBQUERY - case TK_SELECT: { - /* The expression is a sub-select. Return the declaration type and - ** origin info for the single column in the result set of the SELECT - ** statement. - */ - NameContext sNC; - Select *pS = pExpr->x.pSelect; - Expr *p = pS->pEList->a[0].pExpr; - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); - sNC.pSrcList = pS->pSrc; - sNC.pNext = pNC; - sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth); - break; - } -#endif - } - -#ifdef SQLITE_ENABLE_COLUMN_METADATA - if( pzOrigDb ){ - assert( pzOrigTab && pzOrigCol ); - *pzOrigDb = zOrigDb; - *pzOrigTab = zOrigTab; - *pzOrigCol = zOrigCol; - } -#endif - if( pEstWidth ) *pEstWidth = estWidth; - return zType; -} - -/* -** Generate code that will tell the VDBE the declaration types of columns -** in the result set. -*/ -static void generateColumnTypes( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* List of tables */ - ExprList *pEList /* Expressions defining the result set */ -){ -#ifndef SQLITE_OMIT_DECLTYPE - Vdbe *v = pParse->pVdbe; - int i; - NameContext sNC; - sNC.pSrcList = pTabList; - sNC.pParse = pParse; - for(i=0; inExpr; i++){ - Expr *p = pEList->a[i].pExpr; - const char *zType; -#ifdef SQLITE_ENABLE_COLUMN_METADATA - const char *zOrigDb = 0; - const char *zOrigTab = 0; - const char *zOrigCol = 0; - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0); - - /* The vdbe must make its own copy of the column-type and other - ** column specific strings, in case the schema is reset before this - ** virtual machine is deleted. - */ - sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); - sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); -#else - zType = columnType(&sNC, p, 0, 0, 0, 0); -#endif - sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); - } -#endif /* !defined(SQLITE_OMIT_DECLTYPE) */ -} - -/* -** Generate code that will tell the VDBE the names of columns -** in the result set. This information is used to provide the -** azCol[] values in the callback. -*/ -static void generateColumnNames( - Parse *pParse, /* Parser context */ - SrcList *pTabList, /* List of tables */ - ExprList *pEList /* Expressions defining the result set */ -){ - Vdbe *v = pParse->pVdbe; - int i, j; - sqlite3 *db = pParse->db; - int fullNames, shortNames; - -#ifndef SQLITE_OMIT_EXPLAIN - /* If this is an EXPLAIN, skip this step */ - if( pParse->explain ){ - return; - } -#endif - - if( pParse->colNamesSet || db->mallocFailed ) return; - assert( v!=0 ); - assert( pTabList!=0 ); - pParse->colNamesSet = 1; - fullNames = (db->flags & SQLITE_FullColNames)!=0; - shortNames = (db->flags & SQLITE_ShortColNames)!=0; - sqlite3VdbeSetNumCols(v, pEList->nExpr); - for(i=0; inExpr; i++){ - Expr *p; - p = pEList->a[i].pExpr; - if( NEVER(p==0) ) continue; - if( pEList->a[i].zName ){ - char *zName = pEList->a[i].zName; - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); - }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){ - Table *pTab; - char *zCol; - int iCol = p->iColumn; - for(j=0; ALWAYS(jnSrc); j++){ - if( pTabList->a[j].iCursor==p->iTable ) break; - } - assert( jnSrc ); - pTab = pTabList->a[j].pTab; - if( iCol<0 ) iCol = pTab->iPKey; - assert( iCol==-1 || (iCol>=0 && iColnCol) ); - if( iCol<0 ){ - zCol = "rowid"; - }else{ - zCol = pTab->aCol[iCol].zName; - } - if( !shortNames && !fullNames ){ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, - sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC); - }else if( fullNames ){ - char *zName = 0; - zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); - }else{ - sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); - } - }else{ - const char *z = pEList->a[i].zSpan; - z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); - sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); - } - } - generateColumnTypes(pParse, pTabList, pEList); -} - -/* -** Given an expression list (which is really the list of expressions -** that form the result set of a SELECT statement) compute appropriate -** column names for a table that would hold the expression list. -** -** All column names will be unique. -** -** Only the column names are computed. Column.zType, Column.zColl, -** and other fields of Column are zeroed. -** -** Return SQLITE_OK on success. If a memory allocation error occurs, -** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. -*/ -SQLITE_PRIVATE int sqlite3ColumnsFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pEList, /* Expr list from which to derive column names */ - i16 *pnCol, /* Write the number of columns here */ - Column **paCol /* Write the new column list here */ -){ - sqlite3 *db = pParse->db; /* Database connection */ - int i, j; /* Loop counters */ - u32 cnt; /* Index added to make the name unique */ - Column *aCol, *pCol; /* For looping over result columns */ - int nCol; /* Number of columns in the result set */ - Expr *p; /* Expression for a single result column */ - char *zName; /* Column name */ - int nName; /* Size of name in zName[] */ - Hash ht; /* Hash table of column names */ - - sqlite3HashInit(&ht); - if( pEList ){ - nCol = pEList->nExpr; - aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); - testcase( aCol==0 ); - }else{ - nCol = 0; - aCol = 0; - } - assert( nCol==(i16)nCol ); - *pnCol = nCol; - *paCol = aCol; - - for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ - /* Get an appropriate name for the column - */ - p = sqlite3ExprSkipCollate(pEList->a[i].pExpr); - if( (zName = pEList->a[i].zName)!=0 ){ - /* If the column contains an "AS " phrase, use as the name */ - }else{ - Expr *pColExpr = p; /* The expression that is the result column name */ - Table *pTab; /* Table associated with this expression */ - while( pColExpr->op==TK_DOT ){ - pColExpr = pColExpr->pRight; - assert( pColExpr!=0 ); - } - if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){ - /* For columns use the column name name */ - int iCol = pColExpr->iColumn; - pTab = pColExpr->pTab; - if( iCol<0 ) iCol = pTab->iPKey; - zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; - }else if( pColExpr->op==TK_ID ){ - assert( !ExprHasProperty(pColExpr, EP_IntValue) ); - zName = pColExpr->u.zToken; - }else{ - /* Use the original text of the column expression as its name */ - zName = pEList->a[i].zSpan; - } - } - zName = sqlite3MPrintf(db, "%s", zName); - - /* Make sure the column name is unique. If the name is not unique, - ** append an integer to the name so that it becomes unique. - */ - cnt = 0; - while( zName && sqlite3HashFind(&ht, zName)!=0 ){ - nName = sqlite3Strlen30(zName); - if( nName>0 ){ - for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} - if( zName[j]==':' ) nName = j; - } - zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); - if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); - } - pCol->zName = zName; - sqlite3ColumnPropertiesFromName(0, pCol); - if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ - sqlite3OomFault(db); - } - } - sqlite3HashClear(&ht); - if( db->mallocFailed ){ - for(j=0; jdb; - NameContext sNC; - Column *pCol; - CollSeq *pColl; - int i; - Expr *p; - struct ExprList_item *a; - u64 szAll = 0; - - assert( pSelect!=0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 ); - assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed ); - if( db->mallocFailed ) return; - memset(&sNC, 0, sizeof(sNC)); - sNC.pSrcList = pSelect->pSrc; - a = pSelect->pEList->a; - for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - const char *zType; - int n, m; - p = a[i].pExpr; - zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst); - szAll += pCol->szEst; - pCol->affinity = sqlite3ExprAffinity(p); - if( zType && (m = sqlite3Strlen30(zType))>0 ){ - n = sqlite3Strlen30(pCol->zName); - pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); - if( pCol->zName ){ - memcpy(&pCol->zName[n+1], zType, m+1); - pCol->colFlags |= COLFLAG_HASTYPE; - } - } - if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB; - pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl && pCol->zColl==0 ){ - pCol->zColl = sqlite3DbStrDup(db, pColl->zName); - } - } - pTab->szTabRow = sqlite3LogEst(szAll*4); -} - -/* -** Given a SELECT statement, generate a Table structure that describes -** the result set of that SELECT. -*/ -SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ - Table *pTab; - sqlite3 *db = pParse->db; - int savedFlags; - - savedFlags = db->flags; - db->flags &= ~SQLITE_FullColNames; - db->flags |= SQLITE_ShortColNames; - sqlite3SelectPrep(pParse, pSelect, 0); - if( pParse->nErr ) return 0; - while( pSelect->pPrior ) pSelect = pSelect->pPrior; - db->flags = savedFlags; - pTab = sqlite3DbMallocZero(db, sizeof(Table) ); - if( pTab==0 ){ - return 0; - } - /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside - ** is disabled */ - assert( db->lookaside.bDisable ); - pTab->nRef = 1; - pTab->zName = 0; - pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); - sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect); - pTab->iPKey = -1; - if( db->mallocFailed ){ - sqlite3DeleteTable(db, pTab); - return 0; - } - return pTab; -} - -/* -** Get a VDBE for the given parser context. Create a new one if necessary. -** If an error occurs, return NULL and leave a message in pParse. -*/ -static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse); - if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1); - if( pParse->pToplevel==0 - && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) - ){ - pParse->okConstFactor = 1; - } - return v; -} -SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ - Vdbe *v = pParse->pVdbe; - return v ? v : allocVdbe(pParse); -} - - -/* -** Compute the iLimit and iOffset fields of the SELECT based on the -** pLimit and pOffset expressions. pLimit and pOffset hold the expressions -** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or NULL if those keywords are omitted. iLimit and iOffset -** are the integer memory register numbers for counters used to compute -** the limit and offset. If there is no limit and/or offset, then -** iLimit and iOffset are negative. -** -** This routine changes the values of iLimit and iOffset only if -** a limit or offset is defined by pLimit and pOffset. iLimit and -** iOffset should have been preset to appropriate default values (zero) -** prior to calling this routine. -** -** The iOffset register (if it exists) is initialized to the value -** of the OFFSET. The iLimit register is initialized to LIMIT. Register -** iOffset+1 is initialized to LIMIT+OFFSET. -** -** Only if pLimit!=0 or pOffset!=0 do the limit registers get -** redefined. The UNION ALL operator uses this property to force -** the reuse of the same limit and offset registers across multiple -** SELECT statements. -*/ -static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ - Vdbe *v = 0; - int iLimit = 0; - int iOffset; - int n; - if( p->iLimit ) return; - - /* - ** "LIMIT -1" always shows all rows. There is some - ** controversy about what the correct behavior should be. - ** The current implementation interprets "LIMIT 0" to mean - ** no rows. - */ - sqlite3ExprCacheClear(pParse); - assert( p->pOffset==0 || p->pLimit!=0 ); - if( p->pLimit ){ - p->iLimit = iLimit = ++pParse->nMem; - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); - if( sqlite3ExprIsInteger(p->pLimit, &n) ){ - sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); - VdbeComment((v, "LIMIT counter")); - if( n==0 ){ - sqlite3VdbeGoto(v, iBreak); - }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){ - p->nSelectRow = sqlite3LogEst((u64)n); - p->selFlags |= SF_FixedLimit; - } - }else{ - sqlite3ExprCode(pParse, p->pLimit, iLimit); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); - VdbeComment((v, "LIMIT counter")); - sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); - } - if( p->pOffset ){ - p->iOffset = iOffset = ++pParse->nMem; - pParse->nMem++; /* Allocate an extra register for limit+offset */ - sqlite3ExprCode(pParse, p->pOffset, iOffset); - sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); - VdbeComment((v, "OFFSET counter")); - sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); - VdbeComment((v, "LIMIT+OFFSET")); - } - } -} - -#ifndef SQLITE_OMIT_COMPOUND_SELECT -/* -** Return the appropriate collating sequence for the iCol-th column of -** the result set for the compound-select statement "p". Return NULL if -** the column has no default collating sequence. -** -** The collating sequence for the compound select is taken from the -** left-most term of the select that has a collating sequence. -*/ -static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ - CollSeq *pRet; - if( p->pPrior ){ - pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); - }else{ - pRet = 0; - } - assert( iCol>=0 ); - /* iCol must be less than p->pEList->nExpr. Otherwise an error would - ** have been thrown during name resolution and we would not have gotten - ** this far */ - if( pRet==0 && ALWAYS(iColpEList->nExpr) ){ - pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); - } - return pRet; -} - -/* -** The select statement passed as the second parameter is a compound SELECT -** with an ORDER BY clause. This function allocates and returns a KeyInfo -** structure suitable for implementing the ORDER BY. -** -** Space to hold the KeyInfo structure is obtained from malloc. The calling -** function is responsible for ensuring that this structure is eventually -** freed. -*/ -static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ - ExprList *pOrderBy = p->pOrderBy; - int nOrderBy = p->pOrderBy->nExpr; - sqlite3 *db = pParse->db; - KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); - if( pRet ){ - int i; - for(i=0; ia[i]; - Expr *pTerm = pItem->pExpr; - CollSeq *pColl; - - if( pTerm->flags & EP_Collate ){ - pColl = sqlite3ExprCollSeq(pParse, pTerm); - }else{ - pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); - if( pColl==0 ) pColl = db->pDfltColl; - pOrderBy->a[i].pExpr = - sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); - } - assert( sqlite3KeyInfoIsWriteable(pRet) ); - pRet->aColl[i] = pColl; - pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder; - } - } - - return pRet; -} - -#ifndef SQLITE_OMIT_CTE -/* -** This routine generates VDBE code to compute the content of a WITH RECURSIVE -** query of the form: -** -** AS ( UNION [ALL] ) -** \___________/ \_______________/ -** p->pPrior p -** -** -** There is exactly one reference to the recursive-table in the FROM clause -** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag. -** -** The setup-query runs once to generate an initial set of rows that go -** into a Queue table. Rows are extracted from the Queue table one by -** one. Each row extracted from Queue is output to pDest. Then the single -** extracted row (now in the iCurrent table) becomes the content of the -** recursive-table for a recursive-query run. The output of the recursive-query -** is added back into the Queue table. Then another row is extracted from Queue -** and the iteration continues until the Queue table is empty. -** -** If the compound query operator is UNION then no duplicate rows are ever -** inserted into the Queue table. The iDistinct table keeps a copy of all rows -** that have ever been inserted into Queue and causes duplicates to be -** discarded. If the operator is UNION ALL, then duplicates are allowed. -** -** If the query has an ORDER BY, then entries in the Queue table are kept in -** ORDER BY order and the first entry is extracted for each cycle. Without -** an ORDER BY, the Queue table is just a FIFO. -** -** If a LIMIT clause is provided, then the iteration stops after LIMIT rows -** have been output to pDest. A LIMIT of zero means to output no rows and a -** negative LIMIT means to output all rows. If there is also an OFFSET clause -** with a positive value, then the first OFFSET outputs are discarded rather -** than being sent to pDest. The LIMIT count does not begin until after OFFSET -** rows have been skipped. -*/ -static void generateWithRecursiveQuery( - Parse *pParse, /* Parsing context */ - Select *p, /* The recursive SELECT to be coded */ - SelectDest *pDest /* What to do with query results */ -){ - SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ - int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ - Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ - Select *pSetup = p->pPrior; /* The setup query */ - int addrTop; /* Top of the loop */ - int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ - int iCurrent = 0; /* The Current table */ - int regCurrent; /* Register holding Current table */ - int iQueue; /* The Queue table */ - int iDistinct = 0; /* To ensure unique results if UNION */ - int eDest = SRT_Fifo; /* How to write to Queue */ - SelectDest destQueue; /* SelectDest targetting the Queue table */ - int i; /* Loop counter */ - int rc; /* Result code */ - ExprList *pOrderBy; /* The ORDER BY clause */ - Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */ - int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ - - /* Obtain authorization to do a recursive query */ - if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; - - /* Process the LIMIT and OFFSET clauses, if they exist */ - addrBreak = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, addrBreak); - pLimit = p->pLimit; - pOffset = p->pOffset; - regLimit = p->iLimit; - regOffset = p->iOffset; - p->pLimit = p->pOffset = 0; - p->iLimit = p->iOffset = 0; - pOrderBy = p->pOrderBy; - - /* Locate the cursor number of the Current table */ - for(i=0; ALWAYS(inSrc); i++){ - if( pSrc->a[i].fg.isRecursive ){ - iCurrent = pSrc->a[i].iCursor; - break; - } - } - - /* Allocate cursors numbers for Queue and Distinct. The cursor number for - ** the Distinct table must be exactly one greater than Queue in order - ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ - iQueue = pParse->nTab++; - if( p->op==TK_UNION ){ - eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; - iDistinct = pParse->nTab++; - }else{ - eDest = pOrderBy ? SRT_Queue : SRT_Fifo; - } - sqlite3SelectDestInit(&destQueue, eDest, iQueue); - - /* Allocate cursors for Current, Queue, and Distinct. */ - regCurrent = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); - if( pOrderBy ){ - KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, - (char*)pKeyInfo, P4_KEYINFO); - destQueue.pOrderBy = pOrderBy; - }else{ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); - } - VdbeComment((v, "Queue table")); - if( iDistinct ){ - p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); - p->selFlags |= SF_UsesEphemeral; - } - - /* Detach the ORDER BY clause from the compound SELECT */ - p->pOrderBy = 0; - - /* Store the results of the setup-query in Queue. */ - pSetup->pNext = 0; - rc = sqlite3Select(pParse, pSetup, &destQueue); - pSetup->pNext = p; - if( rc ) goto end_of_recursive_query; - - /* Find the next row in the Queue and output that row */ - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); - - /* Transfer the next row in Queue over to Current */ - sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ - if( pOrderBy ){ - sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); - }else{ - sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); - } - sqlite3VdbeAddOp1(v, OP_Delete, iQueue); - - /* Output the single row in Current */ - addrCont = sqlite3VdbeMakeLabel(v); - codeOffset(v, regOffset, addrCont); - selectInnerLoop(pParse, p, p->pEList, iCurrent, - 0, 0, pDest, addrCont, addrBreak); - if( regLimit ){ - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); - VdbeCoverage(v); - } - sqlite3VdbeResolveLabel(v, addrCont); - - /* Execute the recursive SELECT taking the single row in Current as - ** the value for the recursive-table. Store the results in the Queue. - */ - if( p->selFlags & SF_Aggregate ){ - sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); - }else{ - p->pPrior = 0; - sqlite3Select(pParse, p, &destQueue); - assert( p->pPrior==0 ); - p->pPrior = pSetup; - } - - /* Keep running the loop until the Queue is empty */ - sqlite3VdbeGoto(v, addrTop); - sqlite3VdbeResolveLabel(v, addrBreak); - -end_of_recursive_query: - sqlite3ExprListDelete(pParse->db, p->pOrderBy); - p->pOrderBy = pOrderBy; - p->pLimit = pLimit; - p->pOffset = pOffset; - return; -} -#endif /* SQLITE_OMIT_CTE */ - -/* Forward references */ -static int multiSelectOrderBy( - Parse *pParse, /* Parsing context */ - Select *p, /* The right-most of SELECTs to be coded */ - SelectDest *pDest /* What to do with query results */ -); - -/* -** Handle the special case of a compound-select that originates from a -** VALUES clause. By handling this as a special case, we avoid deep -** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT -** on a VALUES clause. -** -** Because the Select object originates from a VALUES clause: -** (1) It has no LIMIT or OFFSET -** (2) All terms are UNION ALL -** (3) There is no ORDER BY clause -*/ -static int multiSelectValues( - Parse *pParse, /* Parsing context */ - Select *p, /* The right-most of SELECTs to be coded */ - SelectDest *pDest /* What to do with query results */ -){ - Select *pPrior; - int nRow = 1; - int rc = 0; - assert( p->selFlags & SF_MultiValue ); - do{ - assert( p->selFlags & SF_Values ); - assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); - assert( p->pLimit==0 ); - assert( p->pOffset==0 ); - assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); - if( p->pPrior==0 ) break; - assert( p->pPrior->pNext==p ); - p = p->pPrior; - nRow++; - }while(1); - while( p ){ - pPrior = p->pPrior; - p->pPrior = 0; - rc = sqlite3Select(pParse, p, pDest); - p->pPrior = pPrior; - if( rc ) break; - p->nSelectRow = nRow; - p = p->pNext; - } - return rc; -} - -/* -** This routine is called to process a compound query form from -** two or more separate queries using UNION, UNION ALL, EXCEPT, or -** INTERSECT -** -** "p" points to the right-most of the two queries. the query on the -** left is p->pPrior. The left query could also be a compound query -** in which case this routine will be called recursively. -** -** The results of the total query are to be written into a destination -** of type eDest with parameter iParm. -** -** Example 1: Consider a three-way compound SQL statement. -** -** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 -** -** This statement is parsed up as follows: -** -** SELECT c FROM t3 -** | -** `-----> SELECT b FROM t2 -** | -** `------> SELECT a FROM t1 -** -** The arrows in the diagram above represent the Select.pPrior pointer. -** So if this routine is called with p equal to the t3 query, then -** pPrior will be the t2 query. p->op will be TK_UNION in this case. -** -** Notice that because of the way SQLite parses compound SELECTs, the -** individual selects always group from left to right. -*/ -static int multiSelect( - Parse *pParse, /* Parsing context */ - Select *p, /* The right-most of SELECTs to be coded */ - SelectDest *pDest /* What to do with query results */ -){ - int rc = SQLITE_OK; /* Success code from a subroutine */ - Select *pPrior; /* Another SELECT immediately to our left */ - Vdbe *v; /* Generate code to this VDBE */ - SelectDest dest; /* Alternative data destination */ - Select *pDelete = 0; /* Chain of simple selects to delete */ - sqlite3 *db; /* Database connection */ -#ifndef SQLITE_OMIT_EXPLAIN - int iSub1 = 0; /* EQP id of left-hand query */ - int iSub2 = 0; /* EQP id of right-hand query */ -#endif - - /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only - ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. - */ - assert( p && p->pPrior ); /* Calling function guarantees this much */ - assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); - db = pParse->db; - pPrior = p->pPrior; - dest = *pDest; - if( pPrior->pOrderBy ){ - sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", - selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - if( pPrior->pLimit ){ - sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", - selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } - - v = sqlite3GetVdbe(pParse); - assert( v!=0 ); /* The VDBE already created by calling function */ - - /* Create the destination temporary table if necessary - */ - if( dest.eDest==SRT_EphemTab ){ - assert( p->pEList ); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); - dest.eDest = SRT_Table; - } - - /* Special handling for a compound-select that originates as a VALUES clause. - */ - if( p->selFlags & SF_MultiValue ){ - rc = multiSelectValues(pParse, p, &dest); - goto multi_select_end; - } - - /* Make sure all SELECTs in the statement have the same number of elements - ** in their result sets. - */ - assert( p->pEList && pPrior->pEList ); - assert( p->pEList->nExpr==pPrior->pEList->nExpr ); - -#ifndef SQLITE_OMIT_CTE - if( p->selFlags & SF_Recursive ){ - generateWithRecursiveQuery(pParse, p, &dest); - }else -#endif - - /* Compound SELECTs that have an ORDER BY clause are handled separately. - */ - if( p->pOrderBy ){ - return multiSelectOrderBy(pParse, p, pDest); - }else - - /* Generate code for the left and right SELECT statements. - */ - switch( p->op ){ - case TK_ALL: { - int addr = 0; - int nLimit; - assert( !pPrior->pLimit ); - pPrior->iLimit = p->iLimit; - pPrior->iOffset = p->iOffset; - pPrior->pLimit = p->pLimit; - pPrior->pOffset = p->pOffset; - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; - p->pOffset = 0; - if( rc ){ - goto multi_select_end; - } - p->pPrior = 0; - p->iLimit = pPrior->iLimit; - p->iOffset = pPrior->iOffset; - if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); - VdbeComment((v, "Jump ahead if LIMIT reached")); - if( p->iOffset ){ - sqlite3VdbeAddOp3(v, OP_OffsetLimit, - p->iLimit, p->iOffset+1, p->iOffset); - } - } - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &dest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - if( pPrior->pLimit - && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) - && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) - ){ - p->nSelectRow = sqlite3LogEst((u64)nLimit); - } - if( addr ){ - sqlite3VdbeJumpHere(v, addr); - } - break; - } - case TK_EXCEPT: - case TK_UNION: { - int unionTab; /* Cursor number of the temporary table holding result */ - u8 op = 0; /* One of the SRT_ operations to apply to self */ - int priorOp; /* The SRT_ operation to apply to prior selects */ - Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ - int addr; - SelectDest uniondest; - - testcase( p->op==TK_EXCEPT ); - testcase( p->op==TK_UNION ); - priorOp = SRT_Union; - if( dest.eDest==priorOp ){ - /* We can reuse a temporary table generated by a SELECT to our - ** right. - */ - assert( p->pLimit==0 ); /* Not allowed on leftward elements */ - assert( p->pOffset==0 ); /* Not allowed on leftward elements */ - unionTab = dest.iSDParm; - }else{ - /* We will need to create our own temporary table to hold the - ** intermediate results. - */ - unionTab = pParse->nTab++; - assert( p->pOrderBy==0 ); - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); - } - - /* Code the SELECT statements to our left - */ - assert( !pPrior->pOrderBy ); - sqlite3SelectDestInit(&uniondest, priorOp, unionTab); - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &uniondest); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT statement - */ - if( p->op==TK_EXCEPT ){ - op = SRT_Except; - }else{ - assert( p->op==TK_UNION ); - op = SRT_Union; - } - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - uniondest.eDest = op; - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &uniondest); - testcase( rc!=SQLITE_OK ); - /* Query flattening in sqlite3Select() might refill p->pOrderBy. - ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ - sqlite3ExprListDelete(db, p->pOrderBy); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->pOrderBy = 0; - if( p->op==TK_UNION ){ - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - } - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - p->iLimit = 0; - p->iOffset = 0; - - /* Convert the data in the temporary table into whatever form - ** it is that we currently need. - */ - assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); - if( dest.eDest!=priorOp ){ - int iCont, iBreak, iStart; - assert( p->pEList ); - if( dest.eDest==SRT_Output ){ - Select *pFirst = p; - while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); - } - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); - iStart = sqlite3VdbeCurrentAddr(v); - selectInnerLoop(pParse, p, p->pEList, unionTab, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); - } - break; - } - default: assert( p->op==TK_INTERSECT ); { - int tab1, tab2; - int iCont, iBreak, iStart; - Expr *pLimit, *pOffset; - int addr; - SelectDest intersectdest; - int r1; - - /* INTERSECT is different from the others since it requires - ** two temporary tables. Hence it has its own case. Begin - ** by allocating the tables we will need. - */ - tab1 = pParse->nTab++; - tab2 = pParse->nTab++; - assert( p->pOrderBy==0 ); - - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); - - /* Code the SELECTs to our left into temporary table "tab1". - */ - sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - explainSetInteger(iSub1, pParse->iNextSelectId); - rc = sqlite3Select(pParse, pPrior, &intersectdest); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT into temporary table "tab2" - */ - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); - assert( p->addrOpenEphm[1] == -1 ); - p->addrOpenEphm[1] = addr; - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - pOffset = p->pOffset; - p->pOffset = 0; - intersectdest.iSDParm = tab2; - explainSetInteger(iSub2, pParse->iNextSelectId); - rc = sqlite3Select(pParse, p, &intersectdest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = pLimit; - p->pOffset = pOffset; - - /* Generate code to take the intersection of the two temporary - ** tables. - */ - assert( p->pEList ); - if( dest.eDest==SRT_Output ){ - Select *pFirst = p; - while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); - } - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); - r1 = sqlite3GetTempReg(pParse); - iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1); - sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, r1); - selectInnerLoop(pParse, p, p->pEList, tab1, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); - sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); - break; - } - } - - explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL); - - /* Compute collating sequences used by - ** temporary tables needed to implement the compound select. - ** Attach the KeyInfo structure to all temporary tables. - ** - ** This section is run by the right-most SELECT statement only. - ** SELECT statements to the left always skip this part. The right-most - ** SELECT might also skip this part if it has no ORDER BY clause and - ** no temp tables are required. - */ - if( p->selFlags & SF_UsesEphemeral ){ - int i; /* Loop counter */ - KeyInfo *pKeyInfo; /* Collating sequence for the result set */ - Select *pLoop; /* For looping through SELECT statements */ - CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ - int nCol; /* Number of columns in result set */ - - assert( p->pNext==0 ); - nCol = p->pEList->nExpr; - pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); - if( !pKeyInfo ){ - rc = SQLITE_NOMEM_BKPT; - goto multi_select_end; - } - for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; - } - } - - for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ - for(i=0; i<2; i++){ - int addr = pLoop->addrOpenEphm[i]; - if( addr<0 ){ - /* If [0] is unused then [1] is also unused. So we can - ** always safely abort as soon as the first unused slot is found */ - assert( pLoop->addrOpenEphm[1]<0 ); - break; - } - sqlite3VdbeChangeP2(v, addr, nCol); - sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo), - P4_KEYINFO); - pLoop->addrOpenEphm[i] = -1; - } - } - sqlite3KeyInfoUnref(pKeyInfo); - } - -multi_select_end: - pDest->iSdst = dest.iSdst; - pDest->nSdst = dest.nSdst; - sqlite3SelectDelete(db, pDelete); - return rc; -} -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - -/* -** Error message for when two or more terms of a compound select have different -** size result sets. -*/ -SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ - if( p->selFlags & SF_Values ){ - sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); - }else{ - sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" - " do not have the same number of result columns", selectOpName(p->op)); - } -} - -/* -** Code an output subroutine for a coroutine implementation of a -** SELECT statment. -** -** The data to be output is contained in pIn->iSdst. There are -** pIn->nSdst columns to be output. pDest is where the output should -** be sent. -** -** regReturn is the number of the register holding the subroutine -** return address. -** -** If regPrev>0 then it is the first register in a vector that -** records the previous output. mem[regPrev] is a flag that is false -** if there has been no previous output. If regPrev>0 then code is -** generated to suppress duplicates. pKeyInfo is used for comparing -** keys. -** -** If the LIMIT found in p->iLimit is reached, jump immediately to -** iBreak. -*/ -static int generateOutputSubroutine( - Parse *pParse, /* Parsing context */ - Select *p, /* The SELECT statement */ - SelectDest *pIn, /* Coroutine supplying data */ - SelectDest *pDest, /* Where to send the data */ - int regReturn, /* The return address register */ - int regPrev, /* Previous result register. No uniqueness if 0 */ - KeyInfo *pKeyInfo, /* For comparing with previous entry */ - int iBreak /* Jump here if we hit the LIMIT */ -){ - Vdbe *v = pParse->pVdbe; - int iContinue; - int addr; - - addr = sqlite3VdbeCurrentAddr(v); - iContinue = sqlite3VdbeMakeLabel(v); - - /* Suppress duplicates for UNION, EXCEPT, and INTERSECT - */ - if( regPrev ){ - int addr1, addr2; - addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); - addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, - (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); - sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); - } - if( pParse->db->mallocFailed ) return 0; - - /* Suppress the first OFFSET entries if there is an OFFSET clause - */ - codeOffset(v, p->iOffset, iContinue); - - assert( pDest->eDest!=SRT_Exists ); - assert( pDest->eDest!=SRT_Table ); - switch( pDest->eDest ){ - /* Store the result as data using a unique key. - */ - case SRT_EphemTab: { - int r1 = sqlite3GetTempReg(pParse); - int r2 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); - sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); - sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3ReleaseTempReg(pParse, r2); - sqlite3ReleaseTempReg(pParse, r1); - break; - } - -#ifndef SQLITE_OMIT_SUBQUERY - /* If we are creating a set for an "expr IN (SELECT ...)". - */ - case SRT_Set: { - int r1; - testcase( pIn->nSdst>1 ); - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, - r1, pDest->zAffSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); - sqlite3ReleaseTempReg(pParse, r1); - break; - } - - /* If this is a scalar select that is part of an expression, then - ** store the results in the appropriate memory cell and break out - ** of the scan loop. - */ - case SRT_Mem: { - assert( pIn->nSdst==1 || pParse->nErr>0 ); testcase( pIn->nSdst!=1 ); - sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); - /* The LIMIT clause will jump out of the loop for us */ - break; - } -#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ - - /* The results are stored in a sequence of registers - ** starting at pDest->iSdst. Then the co-routine yields. - */ - case SRT_Coroutine: { - if( pDest->iSdst==0 ){ - pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); - pDest->nSdst = pIn->nSdst; - } - sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); - break; - } - - /* If none of the above, then the result destination must be - ** SRT_Output. This routine is never called with any other - ** destination other than the ones handled above or SRT_Output. - ** - ** For SRT_Output, results are stored in a sequence of registers. - ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to - ** return the next row of result. - */ - default: { - assert( pDest->eDest==SRT_Output ); - sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); - break; - } - } - - /* Jump to the end of the loop if the LIMIT is reached. - */ - if( p->iLimit ){ - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); - } - - /* Generate the subroutine return - */ - sqlite3VdbeResolveLabel(v, iContinue); - sqlite3VdbeAddOp1(v, OP_Return, regReturn); - - return addr; -} - -/* -** Alternative compound select code generator for cases when there -** is an ORDER BY clause. -** -** We assume a query of the following form: -** -** ORDER BY -** -** is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea -** is to code both and with the ORDER BY clause as -** co-routines. Then run the co-routines in parallel and merge the results -** into the output. In addition to the two coroutines (called selectA and -** selectB) there are 7 subroutines: -** -** outA: Move the output of the selectA coroutine into the output -** of the compound query. -** -** outB: Move the output of the selectB coroutine into the output -** of the compound query. (Only generated for UNION and -** UNION ALL. EXCEPT and INSERTSECT never output a row that -** appears only in B.) -** -** AltB: Called when there is data from both coroutines and AB. -** -** EofA: Called when data is exhausted from selectA. -** -** EofB: Called when data is exhausted from selectB. -** -** The implementation of the latter five subroutines depend on which -** is used: -** -** -** UNION ALL UNION EXCEPT INTERSECT -** ------------- ----------------- -------------- ----------------- -** AltB: outA, nextA outA, nextA outA, nextA nextA -** -** AeqB: outA, nextA nextA nextA outA, nextA -** -** AgtB: outB, nextB outB, nextB nextB nextB -** -** EofA: outB, nextB outB, nextB halt halt -** -** EofB: outA, nextA outA, nextA outA, nextA halt -** -** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA -** causes an immediate jump to EofA and an EOF on B following nextB causes -** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or -** following nextX causes a jump to the end of the select processing. -** -** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled -** within the output subroutine. The regPrev register set holds the previously -** output value. A comparison is made against this value and the output -** is skipped if the next results would be the same as the previous. -** -** The implementation plan is to implement the two coroutines and seven -** subroutines first, then put the control logic at the bottom. Like this: -** -** goto Init -** coA: coroutine for left query (A) -** coB: coroutine for right query (B) -** outA: output one row of A -** outB: output one row of B (UNION and UNION ALL only) -** EofA: ... -** EofB: ... -** AltB: ... -** AeqB: ... -** AgtB: ... -** Init: initialize coroutine registers -** yield coA -** if eof(A) goto EofA -** yield coB -** if eof(B) goto EofB -** Cmpr: Compare A, B -** Jump AltB, AeqB, AgtB -** End: ... -** -** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not -** actually called using Gosub and they do not Return. EofA and EofB loop -** until all data is exhausted then jump to the "end" labe. AltB, AeqB, -** and AgtB jump to either L2 or to one of EofA or EofB. -*/ -#ifndef SQLITE_OMIT_COMPOUND_SELECT -static int multiSelectOrderBy( - Parse *pParse, /* Parsing context */ - Select *p, /* The right-most of SELECTs to be coded */ - SelectDest *pDest /* What to do with query results */ -){ - int i, j; /* Loop counters */ - Select *pPrior; /* Another SELECT immediately to our left */ - Vdbe *v; /* Generate code to this VDBE */ - SelectDest destA; /* Destination for coroutine A */ - SelectDest destB; /* Destination for coroutine B */ - int regAddrA; /* Address register for select-A coroutine */ - int regAddrB; /* Address register for select-B coroutine */ - int addrSelectA; /* Address of the select-A coroutine */ - int addrSelectB; /* Address of the select-B coroutine */ - int regOutA; /* Address register for the output-A subroutine */ - int regOutB; /* Address register for the output-B subroutine */ - int addrOutA; /* Address of the output-A subroutine */ - int addrOutB = 0; /* Address of the output-B subroutine */ - int addrEofA; /* Address of the select-A-exhausted subroutine */ - int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */ - int addrEofB; /* Address of the select-B-exhausted subroutine */ - int addrAltB; /* Address of the AB subroutine */ - int regLimitA; /* Limit register for select-A */ - int regLimitB; /* Limit register for select-A */ - int regPrev; /* A range of registers to hold previous output */ - int savedLimit; /* Saved value of p->iLimit */ - int savedOffset; /* Saved value of p->iOffset */ - int labelCmpr; /* Label for the start of the merge algorithm */ - int labelEnd; /* Label for the end of the overall SELECT stmt */ - int addr1; /* Jump instructions that get retargetted */ - int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ - KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ - KeyInfo *pKeyMerge; /* Comparison information for merging rows */ - sqlite3 *db; /* Database connection */ - ExprList *pOrderBy; /* The ORDER BY clause */ - int nOrderBy; /* Number of terms in the ORDER BY clause */ - int *aPermute; /* Mapping from ORDER BY terms to result set columns */ -#ifndef SQLITE_OMIT_EXPLAIN - int iSub1; /* EQP id of left-hand query */ - int iSub2; /* EQP id of right-hand query */ -#endif - - assert( p->pOrderBy!=0 ); - assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ - db = pParse->db; - v = pParse->pVdbe; - assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ - labelEnd = sqlite3VdbeMakeLabel(v); - labelCmpr = sqlite3VdbeMakeLabel(v); - - - /* Patch up the ORDER BY clause - */ - op = p->op; - pPrior = p->pPrior; - assert( pPrior->pOrderBy==0 ); - pOrderBy = p->pOrderBy; - assert( pOrderBy ); - nOrderBy = pOrderBy->nExpr; - - /* For operators other than UNION ALL we have to make sure that - ** the ORDER BY clause covers every term of the result set. Add - ** terms to the ORDER BY clause as necessary. - */ - if( op!=TK_ALL ){ - for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ - struct ExprList_item *pItem; - for(j=0, pItem=pOrderBy->a; ju.x.iOrderByCol>0 ); - if( pItem->u.x.iOrderByCol==i ) break; - } - if( j==nOrderBy ){ - Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); - if( pNew==0 ) return SQLITE_NOMEM_BKPT; - pNew->flags |= EP_IntValue; - pNew->u.iValue = i; - pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; - } - } - } - - /* Compute the comparison permutation and keyinfo that is used with - ** the permutation used to determine if the next - ** row of results comes from selectA or selectB. Also add explicit - ** collations to the ORDER BY clause terms so that when the subqueries - ** to the right and the left are evaluated, they use the correct - ** collation. - */ - aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1)); - if( aPermute ){ - struct ExprList_item *pItem; - aPermute[0] = nOrderBy; - for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ - assert( pItem->u.x.iOrderByCol>0 ); - assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); - aPermute[i] = pItem->u.x.iOrderByCol - 1; - } - pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); - }else{ - pKeyMerge = 0; - } - - /* Reattach the ORDER BY clause to the query. - */ - p->pOrderBy = pOrderBy; - pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); - - /* Allocate a range of temporary registers and the KeyInfo needed - ** for the logic that removes duplicate result rows when the - ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). - */ - if( op==TK_ALL ){ - regPrev = 0; - }else{ - int nExpr = p->pEList->nExpr; - assert( nOrderBy>=nExpr || db->mallocFailed ); - regPrev = pParse->nMem+1; - pParse->nMem += nExpr+1; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); - pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); - if( pKeyDup ){ - assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); - for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); - pKeyDup->aSortOrder[i] = 0; - } - } - } - - /* Separate the left and the right query from one another - */ - p->pPrior = 0; - pPrior->pNext = 0; - sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); - if( pPrior->pPrior==0 ){ - sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); - } - - /* Compute the limit registers */ - computeLimitRegisters(pParse, p, labelEnd); - if( p->iLimit && op==TK_ALL ){ - regLimitA = ++pParse->nMem; - regLimitB = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, - regLimitA); - sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); - }else{ - regLimitA = regLimitB = 0; - } - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = 0; - sqlite3ExprDelete(db, p->pOffset); - p->pOffset = 0; - - regAddrA = ++pParse->nMem; - regAddrB = ++pParse->nMem; - regOutA = ++pParse->nMem; - regOutB = ++pParse->nMem; - sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); - sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - - /* Generate a coroutine to evaluate the SELECT statement to the - ** left of the compound operator - the "A" select. - */ - addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; - addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); - VdbeComment((v, "left SELECT")); - pPrior->iLimit = regLimitA; - explainSetInteger(iSub1, pParse->iNextSelectId); - sqlite3Select(pParse, pPrior, &destA); - sqlite3VdbeEndCoroutine(v, regAddrA); - sqlite3VdbeJumpHere(v, addr1); - - /* Generate a coroutine to evaluate the SELECT statement on - ** the right - the "B" select - */ - addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; - addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); - VdbeComment((v, "right SELECT")); - savedLimit = p->iLimit; - savedOffset = p->iOffset; - p->iLimit = regLimitB; - p->iOffset = 0; - explainSetInteger(iSub2, pParse->iNextSelectId); - sqlite3Select(pParse, p, &destB); - p->iLimit = savedLimit; - p->iOffset = savedOffset; - sqlite3VdbeEndCoroutine(v, regAddrB); - - /* Generate a subroutine that outputs the current row of the A - ** select as the next output row of the compound select. - */ - VdbeNoopComment((v, "Output routine for A")); - addrOutA = generateOutputSubroutine(pParse, - p, &destA, pDest, regOutA, - regPrev, pKeyDup, labelEnd); - - /* Generate a subroutine that outputs the current row of the B - ** select as the next output row of the compound select. - */ - if( op==TK_ALL || op==TK_UNION ){ - VdbeNoopComment((v, "Output routine for B")); - addrOutB = generateOutputSubroutine(pParse, - p, &destB, pDest, regOutB, - regPrev, pKeyDup, labelEnd); - } - sqlite3KeyInfoUnref(pKeyDup); - - /* Generate a subroutine to run when the results from select A - ** are exhausted and only data in select B remains. - */ - if( op==TK_EXCEPT || op==TK_INTERSECT ){ - addrEofA_noB = addrEofA = labelEnd; - }else{ - VdbeNoopComment((v, "eof-A subroutine")); - addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); - addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); - VdbeCoverage(v); - sqlite3VdbeGoto(v, addrEofA); - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - } - - /* Generate a subroutine to run when the results from select B - ** are exhausted and only data in select A remains. - */ - if( op==TK_INTERSECT ){ - addrEofB = addrEofA; - if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; - }else{ - VdbeNoopComment((v, "eof-B subroutine")); - addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); - sqlite3VdbeGoto(v, addrEofB); - } - - /* Generate code to handle the case of AB - */ - VdbeNoopComment((v, "A-gt-B subroutine")); - addrAgtB = sqlite3VdbeCurrentAddr(v); - if( op==TK_ALL || op==TK_UNION ){ - sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); - } - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); - sqlite3VdbeGoto(v, labelCmpr); - - /* This code runs once to initialize everything. - */ - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); - - /* Implement the main merge loop - */ - sqlite3VdbeResolveLabel(v, labelCmpr); - sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); - sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, - (char*)pKeyMerge, P4_KEYINFO); - sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); - sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); - - /* Jump to the this point in order to terminate the query. - */ - sqlite3VdbeResolveLabel(v, labelEnd); - - /* Set the number of output columns - */ - if( pDest->eDest==SRT_Output ){ - Select *pFirst = pPrior; - while( pFirst->pPrior ) pFirst = pFirst->pPrior; - generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList); - } - - /* Reassembly the compound query so that it will be freed correctly - ** by the calling function */ - if( p->pPrior ){ - sqlite3SelectDelete(db, p->pPrior); - } - p->pPrior = pPrior; - pPrior->pNext = p; - - /*** TBD: Insert subroutine calls to close cursors on incomplete - **** subqueries ****/ - explainComposite(pParse, p->op, iSub1, iSub2, 0); - return pParse->nErr!=0; -} -#endif - -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) -/* Forward Declarations */ -static void substExprList(sqlite3*, ExprList*, int, ExprList*); -static void substSelect(sqlite3*, Select *, int, ExprList*, int); - -/* -** Scan through the expression pExpr. Replace every reference to -** a column in table number iTable with a copy of the iColumn-th -** entry in pEList. (But leave references to the ROWID column -** unchanged.) -** -** This routine is part of the flattening procedure. A subquery -** whose result set is defined by pEList appears as entry in the -** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine make the necessary -** changes to pExpr so that it refers directly to the source table -** of the subquery rather the result set of the subquery. -*/ -static Expr *substExpr( - sqlite3 *db, /* Report malloc errors to this connection */ - Expr *pExpr, /* Expr in which substitution occurs */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute expressions */ -){ - if( pExpr==0 ) return 0; - if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ - if( pExpr->iColumn<0 ){ - pExpr->op = TK_NULL; - }else{ - Expr *pNew; - assert( pEList!=0 && pExpr->iColumnnExpr ); - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); - sqlite3ExprDelete(db, pExpr); - pExpr = pNew; - } - }else{ - pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList); - pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - substSelect(db, pExpr->x.pSelect, iTable, pEList, 1); - }else{ - substExprList(db, pExpr->x.pList, iTable, pEList); - } - } - return pExpr; -} -static void substExprList( - sqlite3 *db, /* Report malloc errors here */ - ExprList *pList, /* List to scan and in which to make substitutes */ - int iTable, /* Table to be substituted */ - ExprList *pEList /* Substitute values */ -){ - int i; - if( pList==0 ) return; - for(i=0; inExpr; i++){ - pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList); - } -} -static void substSelect( - sqlite3 *db, /* Report malloc errors here */ - Select *p, /* SELECT statement in which to make substitutions */ - int iTable, /* Table to be replaced */ - ExprList *pEList, /* Substitute values */ - int doPrior /* Do substitutes on p->pPrior too */ -){ - SrcList *pSrc; - struct SrcList_item *pItem; - int i; - if( !p ) return; - do{ - substExprList(db, p->pEList, iTable, pEList); - substExprList(db, p->pGroupBy, iTable, pEList); - substExprList(db, p->pOrderBy, iTable, pEList); - p->pHaving = substExpr(db, p->pHaving, iTable, pEList); - p->pWhere = substExpr(db, p->pWhere, iTable, pEList); - pSrc = p->pSrc; - assert( pSrc!=0 ); - for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(db, pItem->pSelect, iTable, pEList, 1); - if( pItem->fg.isTabFunc ){ - substExprList(db, pItem->u1.pFuncArg, iTable, pEList); - } - } - }while( doPrior && (p = p->pPrior)!=0 ); -} -#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) -/* -** This routine attempts to flatten subqueries as a performance optimization. -** This routine returns 1 if it makes changes and 0 if no flattening occurs. -** -** To understand the concept of flattening, consider the following -** query: -** -** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 -** -** The default way of implementing this query is to execute the -** subquery first and store the results in a temporary table, then -** run the outer query on that temporary table. This requires two -** passes over the data. Furthermore, because the temporary table -** has no indices, the WHERE clause on the outer query cannot be -** optimized. -** -** This routine attempts to rewrite queries such as the above into -** a single flat select, like this: -** -** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 -** -** The code generated for this simplification gives the same result -** but only has to scan the data once. And because indices might -** exist on the table t1, a complete scan of the data might be -** avoided. -** -** Flattening is only attempted if all of the following are true: -** -** (1) The subquery and the outer query do not both use aggregates. -** -** (2) The subquery is not an aggregate or (2a) the outer query is not a join -** and (2b) the outer query does not use subqueries other than the one -** FROM-clause subquery that is a candidate for flattening. (2b is -** due to ticket [2f7170d73bf9abf80] from 2015-02-09.) -** -** (3) The subquery is not the right operand of a left outer join -** (Originally ticket #306. Strengthened by ticket #3300) -** -** (4) The subquery is not DISTINCT. -** -** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT -** sub-queries that were excluded from this optimization. Restriction -** (4) has since been expanded to exclude all DISTINCT subqueries. -** -** (6) The subquery does not use aggregates or the outer query is not -** DISTINCT. -** -** (7) The subquery has a FROM clause. TODO: For subqueries without -** A FROM clause, consider adding a FROM close with the special -** table sqlite_once that consists of a single row containing a -** single NULL. -** -** (8) The subquery does not use LIMIT or the outer query is not a join. -** -** (9) The subquery does not use LIMIT or the outer query does not use -** aggregates. -** -** (**) Restriction (10) was removed from the code on 2005-02-05 but we -** accidently carried the comment forward until 2014-09-15. Original -** text: "The subquery does not use aggregates or the outer query -** does not use LIMIT." -** -** (11) The subquery and the outer query do not both have ORDER BY clauses. -** -** (**) Not implemented. Subsumed into restriction (3). Was previously -** a separate restriction deriving from ticket #350. -** -** (13) The subquery and outer query do not both use LIMIT. -** -** (14) The subquery does not use OFFSET. -** -** (15) The outer query is not part of a compound select or the -** subquery does not have a LIMIT clause. -** (See ticket #2339 and ticket [02a8e81d44]). -** -** (16) The outer query is not an aggregate or the subquery does -** not contain ORDER BY. (Ticket #2942) This used to not matter -** until we introduced the group_concat() function. -** -** (17) The sub-query is not a compound select, or it is a UNION ALL -** compound clause made up entirely of non-aggregate queries, and -** the parent query: -** -** * is not itself part of a compound select, -** * is not an aggregate or DISTINCT query, and -** * is not a join -** -** The parent and sub-query may contain WHERE clauses. Subject to -** rules (11), (13) and (14), they may also contain ORDER BY, -** LIMIT and OFFSET clauses. The subquery cannot use any compound -** operator other than UNION ALL because all the other compound -** operators have an implied DISTINCT which is disallowed by -** restriction (4). -** -** Also, each component of the sub-query must return the same number -** of result columns. This is actually a requirement for any compound -** SELECT statement, but all the code here does is make sure that no -** such (illegal) sub-query is flattened. The caller will detect the -** syntax error and return a detailed message. -** -** (18) If the sub-query is a compound select, then all terms of the -** ORDER by clause of the parent must be simple references to -** columns of the sub-query. -** -** (19) The subquery does not use LIMIT or the outer query does not -** have a WHERE clause. -** -** (20) If the sub-query is a compound select, then it must not use -** an ORDER BY clause. Ticket #3773. We could relax this constraint -** somewhat by saying that the terms of the ORDER BY clause must -** appear as unmodified result columns in the outer query. But we -** have other optimizations in mind to deal with that case. -** -** (21) The subquery does not use LIMIT or the outer query is not -** DISTINCT. (See ticket [752e1646fc]). -** -** (22) The subquery is not a recursive CTE. -** -** (23) The parent is not a recursive CTE, or the sub-query is not a -** compound query. This restriction is because transforming the -** parent to a compound query confuses the code that handles -** recursive queries in multiSelect(). -** -** (24) The subquery is not an aggregate that uses the built-in min() or -** or max() functions. (Without this restriction, a query like: -** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily -** return the value X for which Y was maximal.) -** -** -** In this routine, the "p" parameter is a pointer to the outer query. -** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query -** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates. -** -** If flattening is not attempted, this routine is a no-op and returns 0. -** If flattening is attempted this routine returns 1. -** -** All of the expression analysis must occur on both the outer query and -** the subquery before this routine runs. -*/ -static int flattenSubquery( - Parse *pParse, /* Parsing context */ - Select *p, /* The parent or outer SELECT statement */ - int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ - int isAgg, /* True if outer SELECT uses aggregate functions */ - int subqueryIsAgg /* True if the subquery uses aggregate functions */ -){ - const char *zSavedAuthContext = pParse->zAuthContext; - Select *pParent; /* Current UNION ALL term of the other query */ - Select *pSub; /* The inner query or "subquery" */ - Select *pSub1; /* Pointer to the rightmost select in sub-query */ - SrcList *pSrc; /* The FROM clause of the outer query */ - SrcList *pSubSrc; /* The FROM clause of the subquery */ - ExprList *pList; /* The result set of the outer query */ - int iParent; /* VDBE cursor number of the pSub result set temp table */ - int i; /* Loop counter */ - Expr *pWhere; /* The WHERE clause */ - struct SrcList_item *pSubitem; /* The subquery */ - sqlite3 *db = pParse->db; - - /* Check to see if flattening is permitted. Return 0 if not. - */ - assert( p!=0 ); - assert( p->pPrior==0 ); /* Unable to flatten compound queries */ - if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; - pSrc = p->pSrc; - assert( pSrc && iFrom>=0 && iFromnSrc ); - pSubitem = &pSrc->a[iFrom]; - iParent = pSubitem->iCursor; - pSub = pSubitem->pSelect; - assert( pSub!=0 ); - if( subqueryIsAgg ){ - if( isAgg ) return 0; /* Restriction (1) */ - if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */ - if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery)) - || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0 - || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0 - ){ - return 0; /* Restriction (2b) */ - } - } - - pSubSrc = pSub->pSrc; - assert( pSubSrc ); - /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, - ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET - ** because they could be computed at compile-time. But when LIMIT and OFFSET - ** became arbitrary expressions, we were forced to add restrictions (13) - ** and (14). */ - if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ - if( pSub->pOffset ) return 0; /* Restriction (14) */ - if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ - return 0; /* Restriction (15) */ - } - if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ - if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */ - if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ - return 0; /* Restrictions (8)(9) */ - } - if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){ - return 0; /* Restriction (6) */ - } - if( p->pOrderBy && pSub->pOrderBy ){ - return 0; /* Restriction (11) */ - } - if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ - if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ - if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ - return 0; /* Restriction (21) */ - } - testcase( pSub->selFlags & SF_Recursive ); - testcase( pSub->selFlags & SF_MinMaxAgg ); - if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){ - return 0; /* Restrictions (22) and (24) */ - } - if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ - return 0; /* Restriction (23) */ - } - - /* OBSOLETE COMMENT 1: - ** Restriction 3: If the subquery is a join, make sure the subquery is - ** not used as the right operand of an outer join. Examples of why this - ** is not allowed: - ** - ** t1 LEFT OUTER JOIN (t2 JOIN t3) - ** - ** If we flatten the above, we would get - ** - ** (t1 LEFT OUTER JOIN t2) JOIN t3 - ** - ** which is not at all the same thing. - ** - ** OBSOLETE COMMENT 2: - ** Restriction 12: If the subquery is the right operand of a left outer - ** join, make sure the subquery has no WHERE clause. - ** An examples of why this is not allowed: - ** - ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0) - ** - ** If we flatten the above, we would get - ** - ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0 - ** - ** But the t2.x>0 test will always fail on a NULL row of t2, which - ** effectively converts the OUTER JOIN into an INNER JOIN. - ** - ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE: - ** Ticket #3300 shows that flattening the right term of a LEFT JOIN - ** is fraught with danger. Best to avoid the whole thing. If the - ** subquery is the right term of a LEFT JOIN, then do not flatten. - */ - if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ - return 0; - } - - /* Restriction 17: If the sub-query is a compound SELECT, then it must - ** use only the UNION ALL operator. And none of the simple select queries - ** that make up the compound SELECT are allowed to be aggregate or distinct - ** queries. - */ - if( pSub->pPrior ){ - if( pSub->pOrderBy ){ - return 0; /* Restriction 20 */ - } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ - return 0; - } - for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ - testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); - testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); - assert( pSub->pSrc!=0 ); - assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); - if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 - || (pSub1->pPrior && pSub1->op!=TK_ALL) - || pSub1->pSrc->nSrc<1 - ){ - return 0; - } - testcase( pSub1->pSrc->nSrc>1 ); - } - - /* Restriction 18. */ - if( p->pOrderBy ){ - int ii; - for(ii=0; iipOrderBy->nExpr; ii++){ - if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; - } - } - } - - /***** If we reach this point, flattening is permitted. *****/ - SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", - pSub->zSelName, pSub, iFrom)); - - /* Authorize the subquery */ - pParse->zAuthContext = pSubitem->zName; - TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); - testcase( i==SQLITE_DENY ); - pParse->zAuthContext = zSavedAuthContext; - - /* If the sub-query is a compound SELECT statement, then (by restrictions - ** 17 and 18 above) it must be a UNION ALL and the parent query must - ** be of the form: - ** - ** SELECT FROM () - ** - ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block - ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or - ** OFFSET clauses and joins them to the left-hand-side of the original - ** using UNION ALL operators. In this case N is the number of simple - ** select statements in the compound sub-query. - ** - ** Example: - ** - ** SELECT a+1 FROM ( - ** SELECT x FROM tab - ** UNION ALL - ** SELECT y FROM tab - ** UNION ALL - ** SELECT abs(z*2) FROM tab2 - ** ) WHERE a!=5 ORDER BY 1 - ** - ** Transformed into: - ** - ** SELECT x+1 FROM tab WHERE x+1!=5 - ** UNION ALL - ** SELECT y+1 FROM tab WHERE y+1!=5 - ** UNION ALL - ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5 - ** ORDER BY 1 - ** - ** We call this the "compound-subquery flattening". - */ - for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ - Select *pNew; - ExprList *pOrderBy = p->pOrderBy; - Expr *pLimit = p->pLimit; - Expr *pOffset = p->pOffset; - Select *pPrior = p->pPrior; - p->pOrderBy = 0; - p->pSrc = 0; - p->pPrior = 0; - p->pLimit = 0; - p->pOffset = 0; - pNew = sqlite3SelectDup(db, p, 0); - sqlite3SelectSetName(pNew, pSub->zSelName); - p->pOffset = pOffset; - p->pLimit = pLimit; - p->pOrderBy = pOrderBy; - p->pSrc = pSrc; - p->op = TK_ALL; - if( pNew==0 ){ - p->pPrior = pPrior; - }else{ - pNew->pPrior = pPrior; - if( pPrior ) pPrior->pNext = pNew; - pNew->pNext = p; - p->pPrior = pNew; - SELECTTRACE(2,pParse,p, - ("compound-subquery flattener creates %s.%p as peer\n", - pNew->zSelName, pNew)); - } - if( db->mallocFailed ) return 1; - } - - /* Begin flattening the iFrom-th entry of the FROM clause - ** in the outer query. - */ - pSub = pSub1 = pSubitem->pSelect; - - /* Delete the transient table structure associated with the - ** subquery - */ - sqlite3DbFree(db, pSubitem->zDatabase); - sqlite3DbFree(db, pSubitem->zName); - sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; - pSubitem->zName = 0; - pSubitem->zAlias = 0; - pSubitem->pSelect = 0; - - /* Defer deleting the Table object associated with the - ** subquery until code generation is - ** complete, since there may still exist Expr.pTab entries that - ** refer to the subquery even after flattening. Ticket #3346. - ** - ** pSubitem->pTab is always non-NULL by test restrictions and tests above. - */ - if( ALWAYS(pSubitem->pTab!=0) ){ - Table *pTabToDel = pSubitem->pTab; - if( pTabToDel->nRef==1 ){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - pTabToDel->pNextZombie = pToplevel->pZombieTab; - pToplevel->pZombieTab = pTabToDel; - }else{ - pTabToDel->nRef--; - } - pSubitem->pTab = 0; - } - - /* The following loop runs once for each term in a compound-subquery - ** flattening (as described above). If we are doing a different kind - ** of flattening - a flattening other than a compound-subquery flattening - - ** then this loop only runs once. - ** - ** This loop moves all of the FROM elements of the subquery into the - ** the FROM clause of the outer query. Before doing this, remember - ** the cursor number for the original outer query FROM element in - ** iParent. The iParent cursor will never be used. Subsequent code - ** will scan expressions looking for iParent references and replace - ** those references with expressions that resolve to the subquery FROM - ** elements we are now copying in. - */ - for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ - int nSubSrc; - u8 jointype = 0; - pSubSrc = pSub->pSrc; /* FROM clause of subquery */ - nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ - pSrc = pParent->pSrc; /* FROM clause of the outer query */ - - if( pSrc ){ - assert( pParent==p ); /* First time through the loop */ - jointype = pSubitem->fg.jointype; - }else{ - assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); - if( pSrc==0 ){ - assert( db->mallocFailed ); - break; - } - } - - /* The subquery uses a single slot of the FROM clause of the outer - ** query. If the subquery has more than one element in its FROM clause, - ** then expand the outer query to make space for it to hold all elements - ** of the subquery. - ** - ** Example: - ** - ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB; - ** - ** The outer query has 3 slots in its FROM clause. One slot of the - ** outer query (the middle slot) is used by the subquery. The next - ** block of code will expand the outer query FROM clause to 4 slots. - ** The middle slot is expanded to two slots in order to make space - ** for the two elements in the FROM clause of the subquery. - */ - if( nSubSrc>1 ){ - pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1); - if( db->mallocFailed ){ - break; - } - } - - /* Transfer the FROM clause terms from the subquery into the - ** outer query. - */ - for(i=0; ia[i+iFrom].pUsing); - assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); - pSrc->a[i+iFrom] = pSubSrc->a[i]; - memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); - } - pSrc->a[iFrom].fg.jointype = jointype; - - /* Now begin substituting subquery result set expressions for - ** references to the iParent in the outer query. - ** - ** Example: - ** - ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; - ** \ \_____________ subquery __________/ / - ** \_____________________ outer query ______________________________/ - ** - ** We look at every expression in the outer query and every place we see - ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". - */ - pList = pParent->pEList; - for(i=0; inExpr; i++){ - if( pList->a[i].zName==0 ){ - char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan); - sqlite3Dequote(zName); - pList->a[i].zName = zName; - } - } - if( pSub->pOrderBy ){ - /* At this point, any non-zero iOrderByCol values indicate that the - ** ORDER BY column expression is identical to the iOrderByCol'th - ** expression returned by SELECT statement pSub. Since these values - ** do not necessarily correspond to columns in SELECT statement pParent, - ** zero them before transfering the ORDER BY clause. - ** - ** Not doing this may cause an error if a subsequent call to this - ** function attempts to flatten a compound sub-query into pParent - ** (the only way this can happen is if the compound sub-query is - ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ - ExprList *pOrderBy = pSub->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } - assert( pParent->pOrderBy==0 ); - assert( pSub->pPrior==0 ); - pParent->pOrderBy = pOrderBy; - pSub->pOrderBy = 0; - } - pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); - if( subqueryIsAgg ){ - assert( pParent->pHaving==0 ); - pParent->pHaving = pParent->pWhere; - pParent->pWhere = pWhere; - pParent->pHaving = sqlite3ExprAnd(db, - sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving - ); - assert( pParent->pGroupBy==0 ); - pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0); - }else{ - pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); - } - substSelect(db, pParent, iParent, pSub->pEList, 0); - - /* The flattened query is distinct if either the inner or the - ** outer query is distinct. - */ - pParent->selFlags |= pSub->selFlags & SF_Distinct; - - /* - ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; - ** - ** One is tempted to try to add a and b to combine the limits. But this - ** does not work if either limit is negative. - */ - if( pSub->pLimit ){ - pParent->pLimit = pSub->pLimit; - pSub->pLimit = 0; - } - } - - /* Finially, delete what is left of the subquery and return - ** success. - */ - sqlite3SelectDelete(db, pSub1); - -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p,("After flattening:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - - return 1; -} -#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - - - -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) -/* -** Make copies of relevant WHERE clause terms of the outer query into -** the WHERE clause of subquery. Example: -** -** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10; -** -** Transformed into: -** -** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10) -** WHERE x=5 AND y=10; -** -** The hope is that the terms added to the inner query will make it more -** efficient. -** -** Do not attempt this optimization if: -** -** (1) The inner query is an aggregate. (In that case, we'd really want -** to copy the outer WHERE-clause terms onto the HAVING clause of the -** inner query. But they probably won't help there so do not bother.) -** -** (2) The inner query is the recursive part of a common table expression. -** -** (3) The inner query has a LIMIT clause (since the changes to the WHERE -** close would change the meaning of the LIMIT). -** -** (4) The inner query is the right operand of a LEFT JOIN. (The caller -** enforces this restriction since this routine does not have enough -** information to know.) -** -** (5) The WHERE clause expression originates in the ON or USING clause -** of a LEFT JOIN. -** -** Return 0 if no changes are made and non-zero if one or more WHERE clause -** terms are duplicated into the subquery. -*/ -static int pushDownWhereTerms( - sqlite3 *db, /* The database connection (for malloc()) */ - Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ - Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor /* Cursor number of the subquery */ -){ - Expr *pNew; - int nChng = 0; - Select *pX; /* For looping over compound SELECTs in pSubq */ - if( pWhere==0 ) return 0; - for(pX=pSubq; pX; pX=pX->pPrior){ - if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){ - testcase( pX->selFlags & SF_Aggregate ); - testcase( pX->selFlags & SF_Recursive ); - testcase( pX!=pSubq ); - return 0; /* restrictions (1) and (2) */ - } - } - if( pSubq->pLimit!=0 ){ - return 0; /* restriction (3) */ - } - while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor); - pWhere = pWhere->pLeft; - } - if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */ - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ - nChng++; - while( pSubq ){ - pNew = sqlite3ExprDup(db, pWhere, 0); - pNew = substExpr(db, pNew, iCursor, pSubq->pEList); - pSubq->pWhere = sqlite3ExprAnd(db, pSubq->pWhere, pNew); - pSubq = pSubq->pPrior; - } - } - return nChng; -} -#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ - -/* -** Based on the contents of the AggInfo structure indicated by the first -** argument, this function checks if the following are true: -** -** * the query contains just a single aggregate function, -** * the aggregate function is either min() or max(), and -** * the argument to the aggregate function is a column value. -** -** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX -** is returned as appropriate. Also, *ppMinMax is set to point to the -** list of arguments passed to the aggregate before returning. -** -** Or, if the conditions above are not met, *ppMinMax is set to 0 and -** WHERE_ORDERBY_NORMAL is returned. -*/ -static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ - int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ - - *ppMinMax = 0; - if( pAggInfo->nFunc==1 ){ - Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */ - ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */ - - assert( pExpr->op==TK_AGG_FUNCTION ); - if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){ - const char *zFunc = pExpr->u.zToken; - if( sqlite3StrICmp(zFunc, "min")==0 ){ - eRet = WHERE_ORDERBY_MIN; - *ppMinMax = pEList; - }else if( sqlite3StrICmp(zFunc, "max")==0 ){ - eRet = WHERE_ORDERBY_MAX; - *ppMinMax = pEList; - } - } - } - - assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 ); - return eRet; -} - -/* -** The select statement passed as the first argument is an aggregate query. -** The second argument is the associated aggregate-info object. This -** function tests if the SELECT is of the form: -** -** SELECT count(*) FROM -** -** where table is a database table, not a sub-select or view. If the query -** does match this pattern, then a pointer to the Table object representing -** is returned. Otherwise, 0 is returned. -*/ -static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ - Table *pTab; - Expr *pExpr; - - assert( !p->pGroupBy ); - - if( p->pWhere || p->pEList->nExpr!=1 - || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect - ){ - return 0; - } - pTab = p->pSrc->a[0].pTab; - pExpr = p->pEList->a[0].pExpr; - assert( pTab && !pTab->pSelect && pExpr ); - - if( IsVirtual(pTab) ) return 0; - if( pExpr->op!=TK_AGG_FUNCTION ) return 0; - if( NEVER(pAggInfo->nFunc==0) ) return 0; - if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; - if( pExpr->flags&EP_Distinct ) return 0; - - return pTab; -} - -/* -** If the source-list item passed as an argument was augmented with an -** INDEXED BY clause, then try to locate the specified index. If there -** was such a clause and the named index cannot be found, return -** SQLITE_ERROR and leave an error in pParse. Otherwise, populate -** pFrom->pIndex and return SQLITE_OK. -*/ -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->pTab && pFrom->fg.isIndexedBy ){ - Table *pTab = pFrom->pTab; - char *zIndexedBy = pFrom->u1.zIndexedBy; - Index *pIdx; - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); - pIdx=pIdx->pNext - ); - if( !pIdx ){ - sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); - pParse->checkSchema = 1; - return SQLITE_ERROR; - } - pFrom->pIBIndex = pIdx; - } - return SQLITE_OK; -} -/* -** Detect compound SELECT statements that use an ORDER BY clause with -** an alternative collating sequence. -** -** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ... -** -** These are rewritten as a subquery: -** -** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) -** ORDER BY ... COLLATE ... -** -** This transformation is necessary because the multiSelectOrderBy() routine -** above that generates the code for a compound SELECT with an ORDER BY clause -** uses a merge algorithm that requires the same collating sequence on the -** result columns as on the ORDER BY clause. See ticket -** http://www.sqlite.org/src/info/6709574d2a -** -** This transformation is only needed for EXCEPT, INTERSECT, and UNION. -** The UNION ALL operator works fine with multiSelectOrderBy() even when -** there are COLLATE terms in the ORDER BY. -*/ -static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ - int i; - Select *pNew; - Select *pX; - sqlite3 *db; - struct ExprList_item *a; - SrcList *pNewSrc; - Parse *pParse; - Token dummy; - - if( p->pPrior==0 ) return WRC_Continue; - if( p->pOrderBy==0 ) return WRC_Continue; - for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){} - if( pX==0 ) return WRC_Continue; - a = p->pOrderBy->a; - for(i=p->pOrderBy->nExpr-1; i>=0; i--){ - if( a[i].pExpr->flags & EP_Collate ) break; - } - if( i<0 ) return WRC_Continue; - - /* If we reach this point, that means the transformation is required. */ - - pParse = pWalker->pParse; - db = pParse->db; - pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); - if( pNew==0 ) return WRC_Abort; - memset(&dummy, 0, sizeof(dummy)); - pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); - if( pNewSrc==0 ) return WRC_Abort; - *pNew = *p; - p->pSrc = pNewSrc; - p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); - p->op = TK_SELECT; - p->pWhere = 0; - pNew->pGroupBy = 0; - pNew->pHaving = 0; - pNew->pOrderBy = 0; - p->pPrior = 0; - p->pNext = 0; - p->pWith = 0; - p->selFlags &= ~SF_Compound; - assert( (p->selFlags & SF_Converted)==0 ); - p->selFlags |= SF_Converted; - assert( pNew->pPrior!=0 ); - pNew->pPrior->pNext = pNew; - pNew->pLimit = 0; - pNew->pOffset = 0; - return WRC_Continue; -} - -/* -** Check to see if the FROM clause term pFrom has table-valued function -** arguments. If it does, leave an error message in pParse and return -** non-zero, since pFrom is not allowed to be a table-valued function. -*/ -static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->fg.isTabFunc ){ - sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); - return 1; - } - return 0; -} - -#ifndef SQLITE_OMIT_CTE -/* -** Argument pWith (which may be NULL) points to a linked list of nested -** WITH contexts, from inner to outermost. If the table identified by -** FROM clause element pItem is really a common-table-expression (CTE) -** then return a pointer to the CTE definition for that table. Otherwise -** return NULL. -** -** If a non-NULL value is returned, set *ppContext to point to the With -** object that the returned CTE belongs to. -*/ -static struct Cte *searchWith( - With *pWith, /* Current innermost WITH clause */ - struct SrcList_item *pItem, /* FROM clause element to resolve */ - With **ppContext /* OUT: WITH clause return value belongs to */ -){ - const char *zName; - if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ - With *p; - for(p=pWith; p; p=p->pOuter){ - int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ - *ppContext = p; - return &p->a[i]; - } - } - } - } - return 0; -} - -/* The code generator maintains a stack of active WITH clauses -** with the inner-most WITH clause being at the top of the stack. -** -** This routine pushes the WITH clause passed as the second argument -** onto the top of the stack. If argument bFree is true, then this -** WITH clause will never be popped from the stack. In this case it -** should be freed along with the Parse object. In other cases, when -** bFree==0, the With object will be freed along with the SELECT -** statement with which it is associated. -*/ -SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); - if( pWith ){ - assert( pParse->pWith!=pWith ); - pWith->pOuter = pParse->pWith; - pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; - } -} - -/* -** This function checks if argument pFrom refers to a CTE declared by -** a WITH clause on the stack currently maintained by the parser. And, -** if currently processing a CTE expression, if it is a recursive -** reference to the current CTE. -** -** If pFrom falls into either of the two categories above, pFrom->pTab -** and other fields are populated accordingly. The caller should check -** (pFrom->pTab!=0) to determine whether or not a successful match -** was found. -** -** Whether or not a match is found, SQLITE_OK is returned if no error -** occurs. If an error does occur, an error message is stored in the -** parser and some error code other than SQLITE_OK returned. -*/ -static int withExpand( - Walker *pWalker, - struct SrcList_item *pFrom -){ - Parse *pParse = pWalker->pParse; - sqlite3 *db = pParse->db; - struct Cte *pCte; /* Matched CTE (or NULL if no match) */ - With *pWith; /* WITH clause that pCte belongs to */ - - assert( pFrom->pTab==0 ); - - pCte = searchWith(pParse->pWith, pFrom, &pWith); - if( pCte ){ - Table *pTab; - ExprList *pEList; - Select *pSel; - Select *pLeft; /* Left-most SELECT statement */ - int bMayRecursive; /* True if compound joined by UNION [ALL] */ - With *pSavedWith; /* Initial value of pParse->pWith */ - - /* If pCte->zCteErr is non-NULL at this point, then this is an illegal - ** recursive reference to CTE pCte. Leave an error in pParse and return - ** early. If pCte->zCteErr is NULL, then this is not a recursive reference. - ** In this case, proceed. */ - if( pCte->zCteErr ){ - sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); - return SQLITE_ERROR; - } - if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; - - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; - pTab->nRef = 1; - pTab->zName = sqlite3DbStrDup(db, pCte->zName); - pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; - pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - assert( pFrom->pSelect ); - - /* Check if this is a recursive CTE. */ - pSel = pFrom->pSelect; - bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); - if( bMayRecursive ){ - int i; - SrcList *pSrc = pFrom->pSelect->pSrc; - for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; - if( pItem->zDatabase==0 - && pItem->zName!=0 - && 0==sqlite3StrICmp(pItem->zName, pCte->zName) - ){ - pItem->pTab = pTab; - pItem->fg.isRecursive = 1; - pTab->nRef++; - pSel->selFlags |= SF_Recursive; - } - } - } - - /* Only one recursive reference is permitted. */ - if( pTab->nRef>2 ){ - sqlite3ErrorMsg( - pParse, "multiple references to recursive table: %s", pCte->zName - ); - return SQLITE_ERROR; - } - assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 )); - - pCte->zCteErr = "circular reference: %s"; - pSavedWith = pParse->pWith; - pParse->pWith = pWith; - sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel); - pParse->pWith = pWith; - - for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); - pEList = pLeft->pEList; - if( pCte->pCols ){ - if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ - sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", - pCte->zName, pEList->nExpr, pCte->pCols->nExpr - ); - pParse->pWith = pSavedWith; - return SQLITE_ERROR; - } - pEList = pCte->pCols; - } - - sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); - if( bMayRecursive ){ - if( pSel->selFlags & SF_Recursive ){ - pCte->zCteErr = "multiple recursive references: %s"; - }else{ - pCte->zCteErr = "recursive reference in a subquery: %s"; - } - sqlite3WalkSelect(pWalker, pSel); - } - pCte->zCteErr = 0; - pParse->pWith = pSavedWith; - } - - return SQLITE_OK; -} -#endif - -#ifndef SQLITE_OMIT_CTE -/* -** If the SELECT passed as the second argument has an associated WITH -** clause, pop it from the stack stored as part of the Parse object. -** -** This function is used as the xSelectCallback2() callback by -** sqlite3SelectExpand() when walking a SELECT tree to resolve table -** names and other FROM clause elements. -*/ -static void selectPopWith(Walker *pWalker, Select *p){ - Parse *pParse = pWalker->pParse; - With *pWith = findRightmost(p)->pWith; - if( pWith!=0 ){ - assert( pParse->pWith==pWith ); - pParse->pWith = pWith->pOuter; - } -} -#else -#define selectPopWith 0 -#endif - -/* -** This routine is a Walker callback for "expanding" a SELECT statement. -** "Expanding" means to do the following: -** -** (1) Make sure VDBE cursor numbers have been assigned to every -** element of the FROM clause. -** -** (2) Fill in the pTabList->a[].pTab fields in the SrcList that -** defines FROM clause. When views appear in the FROM clause, -** fill pTabList->a[].pSelect with a copy of the SELECT statement -** that implements the view. A copy is made of the view's SELECT -** statement so that we can freely modify or delete that statement -** without worrying about messing up the persistent representation -** of the view. -** -** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword -** on joins and the ON and USING clause of joins. -** -** (4) Scan the list of columns in the result set (pEList) looking -** for instances of the "*" operator or the TABLE.* operator. -** If found, expand each "*" to be every column in every table -** and TABLE.* to be every column in TABLE. -** -*/ -static int selectExpander(Walker *pWalker, Select *p){ - Parse *pParse = pWalker->pParse; - int i, j, k; - SrcList *pTabList; - ExprList *pEList; - struct SrcList_item *pFrom; - sqlite3 *db = pParse->db; - Expr *pE, *pRight, *pExpr; - u16 selFlags = p->selFlags; - - p->selFlags |= SF_Expanded; - if( db->mallocFailed ){ - return WRC_Abort; - } - if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){ - return WRC_Prune; - } - pTabList = p->pSrc; - pEList = p->pEList; - if( pWalker->xSelectCallback2==selectPopWith ){ - sqlite3WithPush(pParse, findRightmost(p)->pWith, 0); - } - - /* Make sure cursor numbers have been assigned to all entries in - ** the FROM clause of the SELECT statement. - */ - sqlite3SrcListAssignCursors(pParse, pTabList); - - /* Look up every table named in the FROM clause of the select. If - ** an entry of the FROM clause is a subquery instead of a table or view, - ** then create a transient table structure to describe the subquery. - */ - for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab; - assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); - if( pFrom->fg.isRecursive ) continue; - assert( pFrom->pTab==0 ); -#ifndef SQLITE_OMIT_CTE - if( withExpand(pWalker, pFrom) ) return WRC_Abort; - if( pFrom->pTab ) {} else -#endif - if( pFrom->zName==0 ){ -#ifndef SQLITE_OMIT_SUBQUERY - Select *pSel = pFrom->pSelect; - /* A sub-query in the FROM clause of a SELECT */ - assert( pSel!=0 ); - assert( pFrom->pTab==0 ); - if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; - pTab->nRef = 1; - pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab); - while( pSel->pPrior ){ pSel = pSel->pPrior; } - sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); - pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral; -#endif - }else{ - /* An ordinary table or view name in the FROM clause */ - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); - if( pTab==0 ) return WRC_Abort; - if( pTab->nRef==0xffff ){ - sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", - pTab->zName); - pFrom->pTab = 0; - return WRC_Abort; - } - pTab->nRef++; - if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ - return WRC_Abort; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE) - if( IsVirtual(pTab) || pTab->pSelect ){ - i16 nCol; - if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; - assert( pFrom->pSelect==0 ); - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); - sqlite3SelectSetName(pFrom->pSelect, pTab->zName); - nCol = pTab->nCol; - pTab->nCol = -1; - sqlite3WalkSelect(pWalker, pFrom->pSelect); - pTab->nCol = nCol; - } -#endif - } - - /* Locate the index named by the INDEXED BY clause, if any. */ - if( sqlite3IndexedByLookup(pParse, pFrom) ){ - return WRC_Abort; - } - } - - /* Process NATURAL keywords, and ON and USING clauses of joins. - */ - if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){ - return WRC_Abort; - } - - /* For every "*" that occurs in the column list, insert the names of - ** all columns in all tables. And for every TABLE.* insert the names - ** of all columns in TABLE. The parser inserted a special expression - ** with the TK_ASTERISK operator for each "*" that it found in the column - ** list. The following code just has to locate the TK_ASTERISK - ** expressions and expand each one to the list of all columns in - ** all tables. - ** - ** The first loop just checks to see if there are any "*" operators - ** that need expanding. - */ - for(k=0; knExpr; k++){ - pE = pEList->a[k].pExpr; - if( pE->op==TK_ASTERISK ) break; - assert( pE->op!=TK_DOT || pE->pRight!=0 ); - assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); - if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; - } - if( knExpr ){ - /* - ** If we get here it means the result set contains one or more "*" - ** operators that need to be expanded. Loop through each expression - ** in the result set and expand them one by one. - */ - struct ExprList_item *a = pEList->a; - ExprList *pNew = 0; - int flags = pParse->db->flags; - int longNames = (flags & SQLITE_FullColNames)!=0 - && (flags & SQLITE_ShortColNames)==0; - - for(k=0; knExpr; k++){ - pE = a[k].pExpr; - pRight = pE->pRight; - assert( pE->op!=TK_DOT || pRight!=0 ); - if( pE->op!=TK_ASTERISK - && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK) - ){ - /* This particular expression does not need to be expanded. - */ - pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); - if( pNew ){ - pNew->a[pNew->nExpr-1].zName = a[k].zName; - pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan; - a[k].zName = 0; - a[k].zSpan = 0; - } - a[k].pExpr = 0; - }else{ - /* This expression is a "*" or a "TABLE.*" and needs to be - ** expanded. */ - int tableSeen = 0; /* Set to 1 when TABLE matches */ - char *zTName = 0; /* text of name of TABLE */ - if( pE->op==TK_DOT ){ - assert( pE->pLeft!=0 ); - assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); - zTName = pE->pLeft->u.zToken; - } - for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; - Select *pSub = pFrom->pSelect; - char *zTabName = pFrom->zAlias; - const char *zSchemaName = 0; - int iDb; - if( zTabName==0 ){ - zTabName = pTab->zName; - } - if( db->mallocFailed ) break; - if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){ - pSub = 0; - if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ - continue; - } - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; - } - for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zName; - char *zColname; /* The computed column name */ - char *zToFree; /* Malloced string that needs to be freed */ - Token sColname; /* Computed column name as a token */ - - assert( zName ); - if( zTName && pSub - && sqlite3MatchSpanName(pSub->pEList->a[j].zSpan, 0, zTName, 0)==0 - ){ - continue; - } - - /* If a column is marked as 'hidden', omit it from the expanded - ** result-set list unless the SELECT has the SF_IncludeHidden - ** bit set. - */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ - continue; - } - tableSeen = 1; - - if( i>0 && zTName==0 ){ - if( (pFrom->fg.jointype & JT_NATURAL)!=0 - && tableAndColumnIndex(pTabList, i, zName, 0, 0) - ){ - /* In a NATURAL join, omit the join columns from the - ** table to the right of the join */ - continue; - } - if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ - /* In a join with a USING clause, omit columns in the - ** using clause from the table on the right. */ - continue; - } - } - pRight = sqlite3Expr(db, TK_ID, zName); - zColname = zName; - zToFree = 0; - if( longNames || pTabList->nSrc>1 ){ - Expr *pLeft; - pLeft = sqlite3Expr(db, TK_ID, zTabName); - pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - if( zSchemaName ){ - pLeft = sqlite3Expr(db, TK_ID, zSchemaName); - pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0); - } - if( longNames ){ - zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); - zToFree = zColname; - } - }else{ - pExpr = pRight; - } - pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); - sqlite3TokenInit(&sColname, zColname); - sqlite3ExprListSetName(pParse, pNew, &sColname, 0); - if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ - struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; - if( pSub ){ - pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan); - testcase( pX->zSpan==0 ); - }else{ - pX->zSpan = sqlite3MPrintf(db, "%s.%s.%s", - zSchemaName, zTabName, zColname); - testcase( pX->zSpan==0 ); - } - pX->bSpanIsTab = 1; - } - sqlite3DbFree(db, zToFree); - } - } - if( !tableSeen ){ - if( zTName ){ - sqlite3ErrorMsg(pParse, "no such table: %s", zTName); - }else{ - sqlite3ErrorMsg(pParse, "no tables specified"); - } - } - } - } - sqlite3ExprListDelete(db, pEList); - p->pEList = pNew; - } -#if SQLITE_MAX_COLUMN - if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - sqlite3ErrorMsg(pParse, "too many columns in result set"); - return WRC_Abort; - } -#endif - return WRC_Continue; -} - -/* -** No-op routine for the parse-tree walker. -** -** When this routine is the Walker.xExprCallback then expression trees -** are walked without any actions being taken at each node. Presumably, -** when this routine is used for Walker.xExprCallback then -** Walker.xSelectCallback is set to do something useful for every -** subquery in the parser tree. -*/ -SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ - UNUSED_PARAMETER2(NotUsed, NotUsed2); - return WRC_Continue; -} - -/* -** This routine "expands" a SELECT statement and all of its subqueries. -** For additional information on what it means to "expand" a SELECT -** statement, see the comment on the selectExpand worker callback above. -** -** Expanding a SELECT statement is the first step in processing a -** SELECT statement. The SELECT statement must be expanded before -** name resolution is performed. -** -** If anything goes wrong, an error message is written into pParse. -** The calling function can detect the problem by looking at pParse->nErr -** and/or pParse->db->mallocFailed. -*/ -static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ - Walker w; - memset(&w, 0, sizeof(w)); - w.xExprCallback = sqlite3ExprWalkNoop; - w.pParse = pParse; - if( pParse->hasCompound ){ - w.xSelectCallback = convertCompoundSelectToSubquery; - sqlite3WalkSelect(&w, pSelect); - } - w.xSelectCallback = selectExpander; - if( (pSelect->selFlags & SF_MultiValue)==0 ){ - w.xSelectCallback2 = selectPopWith; - } - sqlite3WalkSelect(&w, pSelect); -} - - -#ifndef SQLITE_OMIT_SUBQUERY -/* -** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() -** interface. -** -** For each FROM-clause subquery, add Column.zType and Column.zColl -** information to the Table structure that represents the result set -** of that subquery. -** -** The Table structure that represents the result set was constructed -** by selectExpander() but the type and collation information was omitted -** at that point because identifiers had not yet been resolved. This -** routine is called after identifier resolution. -*/ -static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ - Parse *pParse; - int i; - SrcList *pTabList; - struct SrcList_item *pFrom; - - assert( p->selFlags & SF_Resolved ); - assert( (p->selFlags & SF_HasTypeInfo)==0 ); - p->selFlags |= SF_HasTypeInfo; - pParse = pWalker->pParse; - pTabList = p->pSrc; - for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; - assert( pTab!=0 ); - if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ - /* A sub-query in the FROM clause of a SELECT */ - Select *pSel = pFrom->pSelect; - if( pSel ){ - while( pSel->pPrior ) pSel = pSel->pPrior; - sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel); - } - } - } -} -#endif - - -/* -** This routine adds datatype and collating sequence information to -** the Table structures of all FROM-clause subqueries in a -** SELECT statement. -** -** Use this routine after name resolution. -*/ -static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ -#ifndef SQLITE_OMIT_SUBQUERY - Walker w; - memset(&w, 0, sizeof(w)); - w.xSelectCallback2 = selectAddSubqueryTypeInfo; - w.xExprCallback = sqlite3ExprWalkNoop; - w.pParse = pParse; - sqlite3WalkSelect(&w, pSelect); -#endif -} - - -/* -** This routine sets up a SELECT statement for processing. The -** following is accomplished: -** -** * VDBE Cursor numbers are assigned to all FROM-clause terms. -** * Ephemeral Table objects are created for all FROM-clause subqueries. -** * ON and USING clauses are shifted into WHERE statements -** * Wildcards "*" and "TABLE.*" in result sets are expanded. -** * Identifiers in expression are matched to tables. -** -** This routine acts recursively on all subqueries within the SELECT. -*/ -SQLITE_PRIVATE void sqlite3SelectPrep( - Parse *pParse, /* The parser context */ - Select *p, /* The SELECT statement being coded. */ - NameContext *pOuterNC /* Name context for container */ -){ - sqlite3 *db; - if( NEVER(p==0) ) return; - db = pParse->db; - if( db->mallocFailed ) return; - if( p->selFlags & SF_HasTypeInfo ) return; - sqlite3SelectExpand(pParse, p); - if( pParse->nErr || db->mallocFailed ) return; - sqlite3ResolveSelectNames(pParse, p, pOuterNC); - if( pParse->nErr || db->mallocFailed ) return; - sqlite3SelectAddTypeInfo(pParse, p); -} - -/* -** Reset the aggregate accumulator. -** -** The aggregate accumulator is a set of memory cells that hold -** intermediate results while calculating an aggregate. This -** routine generates code that stores NULLs in all of those memory -** cells. -*/ -static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - struct AggInfo_func *pFunc; - int nReg = pAggInfo->nFunc + pAggInfo->nColumn; - if( nReg==0 ) return; -#ifdef SQLITE_DEBUG - /* Verify that all AggInfo registers are within the range specified by - ** AggInfo.mnReg..AggInfo.mxReg */ - assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); - for(i=0; inColumn; i++){ - assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg - && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); - } - for(i=0; inFunc; i++){ - assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg - && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); - } -#endif - sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); - for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ - if( pFunc->iDistinct>=0 ){ - Expr *pE = pFunc->pExpr; - assert( !ExprHasProperty(pE, EP_xIsSelect) ); - if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ - sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " - "argument"); - pFunc->iDistinct = -1; - }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, - (char*)pKeyInfo, P4_KEYINFO); - } - } - } -} - -/* -** Invoke the OP_AggFinalize opcode for every aggregate function -** in the AggInfo structure. -*/ -static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - struct AggInfo_func *pF; - for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ - ExprList *pList = pF->pExpr->x.pList; - assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); - sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0, - (void*)pF->pFunc, P4_FUNCDEF); - } -} - -/* -** Update the accumulator memory cells for an aggregate based on -** the current cursor position. -*/ -static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ - Vdbe *v = pParse->pVdbe; - int i; - int regHit = 0; - int addrHitTest = 0; - struct AggInfo_func *pF; - struct AggInfo_col *pC; - - pAggInfo->directMode = 1; - for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ - int nArg; - int addrNext = 0; - int regAgg; - ExprList *pList = pF->pExpr->x.pList; - assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); - if( pList ){ - nArg = pList->nExpr; - regAgg = sqlite3GetTempRange(pParse, nArg); - sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); - }else{ - nArg = 0; - regAgg = 0; - } - if( pF->iDistinct>=0 ){ - addrNext = sqlite3VdbeMakeLabel(v); - testcase( nArg==0 ); /* Error condition */ - testcase( nArg>1 ); /* Also an error */ - codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); - } - if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ - for(j=0, pItem=pList->a; !pColl && jpExpr); - } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); - } - sqlite3VdbeAddOp4(v, OP_AggStep0, 0, regAgg, pF->iMem, - (void*)pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); - if( addrNext ){ - sqlite3VdbeResolveLabel(v, addrNext); - sqlite3ExprCacheClear(pParse); - } - } - - /* Before populating the accumulator registers, clear the column cache. - ** Otherwise, if any of the required column values are already present - ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value - ** to pC->iMem. But by the time the value is used, the original register - ** may have been used, invalidating the underlying buffer holding the - ** text or blob value. See ticket [883034dcb5]. - ** - ** Another solution would be to change the OP_SCopy used to copy cached - ** values to an OP_Copy. - */ - if( regHit ){ - addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); - } - sqlite3ExprCacheClear(pParse); - for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); - } - pAggInfo->directMode = 0; - sqlite3ExprCacheClear(pParse); - if( addrHitTest ){ - sqlite3VdbeJumpHere(v, addrHitTest); - } -} - -/* -** Add a single OP_Explain instruction to the VDBE to explain a simple -** count(*) query ("SELECT count(*) FROM pTab"). -*/ -#ifndef SQLITE_OMIT_EXPLAIN -static void explainSimpleCount( - Parse *pParse, /* Parse context */ - Table *pTab, /* Table being queried */ - Index *pIdx /* Index used to optimize scan, or NULL */ -){ - if( pParse->explain==2 ){ - int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); - char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s", - pTab->zName, - bCover ? " USING COVERING INDEX " : "", - bCover ? pIdx->zName : "" - ); - sqlite3VdbeAddOp4( - pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC - ); - } -} -#else -# define explainSimpleCount(a,b,c) -#endif - -/* -** Generate code for the SELECT statement given in the p argument. -** -** The results are returned according to the SelectDest structure. -** See comments in sqliteInt.h for further information. -** -** This routine returns the number of errors. If any errors are -** encountered, then an appropriate error message is left in -** pParse->zErrMsg. -** -** This routine does NOT free the Select structure passed in. The -** calling function needs to do that. -*/ -SQLITE_PRIVATE int sqlite3Select( - Parse *pParse, /* The parser context */ - Select *p, /* The SELECT statement being coded. */ - SelectDest *pDest /* What to do with the query results */ -){ - int i, j; /* Loop counters */ - WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ - Vdbe *v; /* The virtual machine under construction */ - int isAgg; /* True for select lists like "count(*)" */ - ExprList *pEList = 0; /* List of columns to extract. */ - SrcList *pTabList; /* List of tables to select from */ - Expr *pWhere; /* The WHERE clause. May be NULL */ - ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ - Expr *pHaving; /* The HAVING clause. May be NULL */ - int rc = 1; /* Value to return from this function */ - DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ - SortCtx sSort; /* Info on how to code the ORDER BY clause */ - AggInfo sAggInfo; /* Information used by aggregate queries */ - int iEnd; /* Address of the end of the query */ - sqlite3 *db; /* The database connection */ - -#ifndef SQLITE_OMIT_EXPLAIN - int iRestoreSelectId = pParse->iSelectId; - pParse->iSelectId = pParse->iNextSelectId++; -#endif - - db = pParse->db; - if( p==0 || db->mallocFailed || pParse->nErr ){ - return 1; - } - if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; - memset(&sAggInfo, 0, sizeof(sAggInfo)); -#if SELECTTRACE_ENABLED - pParse->nSelectIndent++; - SELECTTRACE(1,pParse,p, ("begin processing:\n")); - if( sqlite3SelectTrace & 0x100 ){ - sqlite3TreeViewSelect(0, p, 0); - } -#endif - - assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); - assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); - assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); - assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); - if( IgnorableOrderby(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || - pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || - pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo || - pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); - /* If ORDER BY makes no difference in the output then neither does - ** DISTINCT so it can be removed too. */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; - p->selFlags &= ~SF_Distinct; - } - sqlite3SelectPrep(pParse, p, 0); - memset(&sSort, 0, sizeof(sSort)); - sSort.pOrderBy = p->pOrderBy; - pTabList = p->pSrc; - if( pParse->nErr || db->mallocFailed ){ - goto select_end; - } - assert( p->pEList!=0 ); - isAgg = (p->selFlags & SF_Aggregate)!=0; -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p, ("after name resolution:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - - /* Try to flatten subqueries in the FROM clause up into the main query - */ -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) - for(i=0; !p->pPrior && inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; - Select *pSub = pItem->pSelect; - int isAggSub; - Table *pTab = pItem->pTab; - if( pSub==0 ) continue; - - /* Catch mismatch in the declared columns of a view and the number of - ** columns in the SELECT on the RHS */ - if( pTab->nCol!=pSub->pEList->nExpr ){ - sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", - pTab->nCol, pTab->zName, pSub->pEList->nExpr); - goto select_end; - } - - isAggSub = (pSub->selFlags & SF_Aggregate)!=0; - if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){ - /* This subquery can be absorbed into its parent. */ - if( isAggSub ){ - isAgg = 1; - p->selFlags |= SF_Aggregate; - } - i = -1; - } - pTabList = p->pSrc; - if( db->mallocFailed ) goto select_end; - if( !IgnorableOrderby(pDest) ){ - sSort.pOrderBy = p->pOrderBy; - } - } -#endif - - /* Get a pointer the VDBE under construction, allocating a new VDBE if one - ** does not already exist */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto select_end; - -#ifndef SQLITE_OMIT_COMPOUND_SELECT - /* Handle compound SELECT statements using the separate multiSelect() - ** procedure. - */ - if( p->pPrior ){ - rc = multiSelect(pParse, p, pDest); - explainSetInteger(pParse->iSelectId, iRestoreSelectId); -#if SELECTTRACE_ENABLED - SELECTTRACE(1,pParse,p,("end compound-select processing\n")); - pParse->nSelectIndent--; -#endif - return rc; - } -#endif - - /* Generate code for all sub-queries in the FROM clause - */ -#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) - for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; - SelectDest dest; - Select *pSub = pItem->pSelect; - if( pSub==0 ) continue; - - /* Sometimes the code for a subquery will be generated more than - ** once, if the subquery is part of the WHERE clause in a LEFT JOIN, - ** for example. In that case, do not regenerate the code to manifest - ** a view or the co-routine to implement a view. The first instance - ** is sufficient, though the subroutine to manifest the view does need - ** to be invoked again. */ - if( pItem->addrFillSub ){ - if( pItem->fg.viaCoroutine==0 ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); - } - continue; - } - - /* Increment Parse.nHeight by the height of the largest expression - ** tree referred to by this, the parent select. The child select - ** may contain expression trees of at most - ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit - ** more conservative than necessary, but much easier than enforcing - ** an exact limit. - */ - pParse->nHeight += sqlite3SelectExprHeight(p); - - /* Make copies of constant WHERE-clause terms in the outer query down - ** inside the subquery. This can help the subquery to run more efficiently. - */ - if( (pItem->fg.jointype & JT_OUTER)==0 - && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor) - ){ -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - } - - /* Generate code to implement the subquery - ** - ** The subquery is implemented as a co-routine if all of these are true: - ** (1) The subquery is guaranteed to be the outer loop (so that it - ** does not need to be computed more than once) - ** (2) The ALL keyword after SELECT is omitted. (Applications are - ** allowed to say "SELECT ALL" instead of just "SELECT" to disable - ** the use of co-routines.) - ** (3) Co-routines are not disabled using sqlite3_test_control() - ** with SQLITE_TESTCTRL_OPTIMIZATIONS. - ** - ** TODO: Are there other reasons beside (1) to use a co-routine - ** implementation? - */ - if( i==0 - && (pTabList->nSrc==1 - || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ - && (p->selFlags & SF_All)==0 /* (2) */ - && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */ - ){ - /* Implement a co-routine that will return a single row of the result - ** set on each invocation. - */ - int addrTop = sqlite3VdbeCurrentAddr(v)+1; - pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); - VdbeComment((v, "%s", pItem->pTab->zName)); - pItem->addrFillSub = addrTop; - sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); - explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); - sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; - pItem->fg.viaCoroutine = 1; - pItem->regResult = dest.iSdst; - sqlite3VdbeEndCoroutine(v, pItem->regReturn); - sqlite3VdbeJumpHere(v, addrTop-1); - sqlite3ClearTempRegCache(pParse); - }else{ - /* Generate a subroutine that will fill an ephemeral table with - ** the content of this subquery. pItem->addrFillSub will point - ** to the address of the generated subroutine. pItem->regReturn - ** is a register allocated to hold the subroutine return address - */ - int topAddr; - int onceAddr = 0; - int retAddr; - assert( pItem->addrFillSub==0 ); - pItem->regReturn = ++pParse->nMem; - topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); - pItem->addrFillSub = topAddr+1; - if( pItem->fg.isCorrelated==0 ){ - /* If the subquery is not correlated and if we are not inside of - ** a trigger, then we only need to compute the value of the subquery - ** once. */ - onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); - }else{ - VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); - } - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId); - sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; - if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); - retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); - VdbeComment((v, "end %s", pItem->pTab->zName)); - sqlite3VdbeChangeP1(v, topAddr, retAddr); - sqlite3ClearTempRegCache(pParse); - } - if( db->mallocFailed ) goto select_end; - pParse->nHeight -= sqlite3SelectExprHeight(p); - } -#endif - - /* Various elements of the SELECT copied into local variables for - ** convenience */ - pEList = p->pEList; - pWhere = p->pWhere; - pGroupBy = p->pGroupBy; - pHaving = p->pHaving; - sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; - -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ - SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and - ** if the select-list is the same as the ORDER BY list, then this query - ** can be rewritten as a GROUP BY. In other words, this: - ** - ** SELECT DISTINCT xyz FROM ... ORDER BY xyz - ** - ** is transformed to: - ** - ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz - ** - ** The second form is preferred as a single index (or temp-table) may be - ** used for both the ORDER BY and DISTINCT processing. As originally - ** written the query must use a temp-table for at least one of the ORDER - ** BY and DISTINCT, and an index or separate temp-table for the other. - */ - if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 - ){ - p->selFlags &= ~SF_Distinct; - pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); - /* Notice that even thought SF_Distinct has been cleared from p->selFlags, - ** the sDistinct.isTnct is still set. Hence, isTnct represents the - ** original setting of the SF_Distinct flag, not the current setting */ - assert( sDistinct.isTnct ); - -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ - SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - } - - /* If there is an ORDER BY clause, then create an ephemeral index to - ** do the sorting. But this sorting ephemeral index might end up - ** being unused if the data can be extracted in pre-sorted order. - ** If that is the case, then the OP_OpenEphemeral instruction will be - ** changed to an OP_Noop once we figure out that the sorting index is - ** not needed. The sSort.addrSortIndex variable is used to facilitate - ** that change. - */ - if( sSort.pOrderBy ){ - KeyInfo *pKeyInfo; - pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr); - sSort.iECursor = pParse->nTab++; - sSort.addrSortIndex = - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, - (char*)pKeyInfo, P4_KEYINFO - ); - }else{ - sSort.addrSortIndex = -1; - } - - /* If the output is destined for a temporary table, open that table. - */ - if( pDest->eDest==SRT_EphemTab ){ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); - } - - /* Set the limiter. - */ - iEnd = sqlite3VdbeMakeLabel(v); - p->nSelectRow = 320; /* 4 billion rows */ - computeLimitRegisters(pParse, p, iEnd); - if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ - sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); - sSort.sortFlags |= SORTFLAG_UseSorter; - } - - /* Open an ephemeral index to use for the distinct set. - */ - if( p->selFlags & SF_Distinct ){ - sDistinct.tabTnct = pParse->nTab++; - sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - sDistinct.tabTnct, 0, 0, - (char*)keyInfoFromExprList(pParse, p->pEList,0,0), - P4_KEYINFO); - sqlite3VdbeChangeP5(v, BTREE_UNORDERED); - sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; - }else{ - sDistinct.eTnctType = WHERE_DISTINCT_NOOP; - } - - if( !isAgg && pGroupBy==0 ){ - /* No aggregate functions and no GROUP BY clause */ - u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); - assert( WHERE_USE_LIMIT==SF_FixedLimit ); - wctrlFlags |= p->selFlags & SF_FixedLimit; - - /* Begin the database scan. */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, - p->pEList, wctrlFlags, p->nSelectRow); - if( pWInfo==0 ) goto select_end; - if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ - p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); - } - if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ - sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); - } - if( sSort.pOrderBy ){ - sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); - sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo); - if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ - sSort.pOrderBy = 0; - } - } - - /* If sorting index that was created by a prior OP_OpenEphemeral - ** instruction ended up not being needed, then change the OP_OpenEphemeral - ** into an OP_Noop. - */ - if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ - sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); - } - - /* Use the standard inner loop. */ - selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest, - sqlite3WhereContinueLabel(pWInfo), - sqlite3WhereBreakLabel(pWInfo)); - - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); - }else{ - /* This case when there exist aggregate functions or a GROUP BY clause - ** or both */ - NameContext sNC; /* Name context for processing aggregate information */ - int iAMem; /* First Mem address for storing current GROUP BY */ - int iBMem; /* First Mem address for previous GROUP BY */ - int iUseFlag; /* Mem address holding flag indicating that at least - ** one row of the input to the aggregator has been - ** processed */ - int iAbortFlag; /* Mem address which causes query abort if positive */ - int groupBySort; /* Rows come from source in GROUP BY order */ - int addrEnd; /* End of processing for this SELECT */ - int sortPTab = 0; /* Pseudotable used to decode sorting results */ - int sortOut = 0; /* Output register from the sorter */ - int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ - - /* Remove any and all aliases between the result set and the - ** GROUP BY clause. - */ - if( pGroupBy ){ - int k; /* Loop counter */ - struct ExprList_item *pItem; /* For looping over expression in a list */ - - for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ - pItem->u.x.iAlias = 0; - } - for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ - pItem->u.x.iAlias = 0; - } - assert( 66==sqlite3LogEst(100) ); - if( p->nSelectRow>66 ) p->nSelectRow = 66; - }else{ - assert( 0==sqlite3LogEst(1) ); - p->nSelectRow = 0; - } - - /* If there is both a GROUP BY and an ORDER BY clause and they are - ** identical, then it may be possible to disable the ORDER BY clause - ** on the grounds that the GROUP BY will cause elements to come out - ** in the correct order. It also may not - the GROUP BY might use a - ** database index that causes rows to be grouped together as required - ** but not actually sorted. Either way, record the fact that the - ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp - ** variable. */ - if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ - orderByGrp = 1; - } - - /* Create a label to jump to when we want to abort the query */ - addrEnd = sqlite3VdbeMakeLabel(v); - - /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in - ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the - ** SELECT statement. - */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - sNC.pAggInfo = &sAggInfo; - sAggInfo.mnReg = pParse->nMem+1; - sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; - sAggInfo.pGroupBy = pGroupBy; - sqlite3ExprAnalyzeAggList(&sNC, pEList); - sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); - if( pHaving ){ - sqlite3ExprAnalyzeAggregates(&sNC, pHaving); - } - sAggInfo.nAccumulator = sAggInfo.nColumn; - for(i=0; ix.pList); - sNC.ncFlags &= ~NC_InAggFunc; - } - sAggInfo.mxReg = pParse->nMem; - if( db->mallocFailed ) goto select_end; - - /* Processing for aggregates with GROUP BY is very different and - ** much more complex than aggregates without a GROUP BY. - */ - if( pGroupBy ){ - KeyInfo *pKeyInfo; /* Keying information for the group by clause */ - int addr1; /* A-vs-B comparision jump */ - int addrOutputRow; /* Start of subroutine that outputs a result row */ - int regOutputRow; /* Return address register for output subroutine */ - int addrSetAbort; /* Set the abort flag and return */ - int addrTopOfLoop; /* Top of the input loop */ - int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ - int addrReset; /* Subroutine for resetting the accumulator */ - int regReset; /* Return address register for reset subroutine */ - - /* If there is a GROUP BY clause we might need a sorting index to - ** implement it. Allocate that sorting index now. If it turns out - ** that we do not need it after all, the OP_SorterOpen instruction - ** will be converted into a Noop. - */ - sAggInfo.sortingIdx = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn); - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, - sAggInfo.sortingIdx, sAggInfo.nSortingColumn, - 0, (char*)pKeyInfo, P4_KEYINFO); - - /* Initialize memory locations used by GROUP BY aggregate processing - */ - iUseFlag = ++pParse->nMem; - iAbortFlag = ++pParse->nMem; - regOutputRow = ++pParse->nMem; - addrOutputRow = sqlite3VdbeMakeLabel(v); - regReset = ++pParse->nMem; - addrReset = sqlite3VdbeMakeLabel(v); - iAMem = pParse->nMem + 1; - pParse->nMem += pGroupBy->nExpr; - iBMem = pParse->nMem + 1; - pParse->nMem += pGroupBy->nExpr; - sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); - VdbeComment((v, "clear abort flag")); - sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); - VdbeComment((v, "indicate accumulator empty")); - sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); - - /* Begin a loop that will extract all source rows in GROUP BY order. - ** This might involve two separate loops with an OP_Sort in between, or - ** it might be a single loop that uses an index to extract information - ** in the right order to begin with. - */ - sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, - WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 - ); - if( pWInfo==0 ) goto select_end; - if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ - /* The optimizer is able to deliver rows in group by order so - ** we do not have to sort. The OP_OpenEphemeral table will be - ** cancelled later because we still need to use the pKeyInfo - */ - groupBySort = 0; - }else{ - /* Rows are coming out in undetermined order. We have to push - ** each row into a sorting index, terminate the first loop, - ** then loop over the sorting index in order to get the output - ** in sorted order - */ - int regBase; - int regRecord; - int nCol; - int nGroupBy; - - explainTempTable(pParse, - (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? - "DISTINCT" : "GROUP BY"); - - groupBySort = 1; - nGroupBy = pGroupBy->nExpr; - nCol = nGroupBy; - j = nGroupBy; - for(i=0; i=j ){ - nCol++; - j++; - } - } - regBase = sqlite3GetTempRange(pParse, nCol); - sqlite3ExprCacheClear(pParse); - sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); - j = nGroupBy; - for(i=0; iiSorterColumn>=j ){ - int r1 = j + regBase; - sqlite3ExprCodeGetColumnToReg(pParse, - pCol->pTab, pCol->iColumn, pCol->iTable, r1); - j++; - } - } - regRecord = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); - sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); - sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3ReleaseTempRange(pParse, regBase, nCol); - sqlite3WhereEnd(pWInfo); - sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; - sortOut = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); - sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); - VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); - sAggInfo.useSortingIdx = 1; - sqlite3ExprCacheClear(pParse); - - } - - /* If the index or temporary table used by the GROUP BY sort - ** will naturally deliver rows in the order required by the ORDER BY - ** clause, cancel the ephemeral table open coded earlier. - ** - ** This is an optimization - the correct answer should result regardless. - ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to - ** disable this optimization for testing purposes. */ - if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) - && (groupBySort || sqlite3WhereIsSorted(pWInfo)) - ){ - sSort.pOrderBy = 0; - sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); - } - - /* Evaluate the current GROUP BY terms and store in b0, b1, b2... - ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) - ** Then compare the current GROUP BY terms against the GROUP BY terms - ** from the previous row currently stored in a0, a1, a2... - */ - addrTopOfLoop = sqlite3VdbeCurrentAddr(v); - sqlite3ExprCacheClear(pParse); - if( groupBySort ){ - sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, - sortOut, sortPTab); - } - for(j=0; jnExpr; j++){ - if( groupBySort ){ - sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); - }else{ - sAggInfo.directMode = 1; - sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); - } - } - sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, - (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); - addr1 = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); - - /* Generate code that runs whenever the GROUP BY changes. - ** Changes in the GROUP BY are detected by the previous code - ** block. If there were no changes, this block is skipped. - ** - ** This code copies current group by terms in b0,b1,b2,... - ** over to a0,a1,a2. It then calls the output subroutine - ** and resets the aggregate accumulator registers in preparation - ** for the next GROUP BY batch. - */ - sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); - sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); - VdbeComment((v, "output one row")); - sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); - VdbeComment((v, "check abort flag")); - sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); - VdbeComment((v, "reset accumulator")); - - /* Update the aggregate accumulators based on the content of - ** the current row - */ - sqlite3VdbeJumpHere(v, addr1); - updateAccumulator(pParse, &sAggInfo); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); - VdbeComment((v, "indicate data in accumulator")); - - /* End of the loop - */ - if( groupBySort ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); - VdbeCoverage(v); - }else{ - sqlite3WhereEnd(pWInfo); - sqlite3VdbeChangeToNoop(v, addrSortingIdx); - } - - /* Output the final row of result - */ - sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); - VdbeComment((v, "output final row")); - - /* Jump over the subroutines - */ - sqlite3VdbeGoto(v, addrEnd); - - /* Generate a subroutine that outputs a single row of the result - ** set. This subroutine first looks at the iUseFlag. If iUseFlag - ** is less than or equal to zero, the subroutine is a no-op. If - ** the processing calls for the query to abort, this subroutine - ** increments the iAbortFlag memory location before returning in - ** order to signal the caller to abort. - */ - addrSetAbort = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); - VdbeComment((v, "set abort flag")); - sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - sqlite3VdbeResolveLabel(v, addrOutputRow); - addrOutputRow = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); - VdbeCoverage(v); - VdbeComment((v, "Groupby result generator entry point")); - sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - finalizeAggFunctions(pParse, &sAggInfo); - sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, -1, &sSort, - &sDistinct, pDest, - addrOutputRow+1, addrSetAbort); - sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - VdbeComment((v, "end groupby result generator")); - - /* Generate a subroutine that will reset the group-by accumulator - */ - sqlite3VdbeResolveLabel(v, addrReset); - resetAccumulator(pParse, &sAggInfo); - sqlite3VdbeAddOp1(v, OP_Return, regReset); - - } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ - else { - ExprList *pDel = 0; -#ifndef SQLITE_OMIT_BTREECOUNT - Table *pTab; - if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){ - /* If isSimpleCount() returns a pointer to a Table structure, then - ** the SQL statement is of the form: - ** - ** SELECT count(*) FROM - ** - ** where the Table structure returned represents table . - ** - ** This statement is so common that it is optimized specially. The - ** OP_Count instruction is executed either on the intkey table that - ** contains the data for table or on one of its indexes. It - ** is better to execute the op on an index, as indexes are almost - ** always spread across less pages than their corresponding tables. - */ - const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ - Index *pIdx; /* Iterator variable */ - KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ - Index *pBest = 0; /* Best index found so far */ - int iRoot = pTab->tnum; /* Root page of scanned b-tree */ - - sqlite3CodeVerifySchema(pParse, iDb); - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - - /* Search for the index that has the lowest scan cost. - ** - ** (2011-04-15) Do not do a full scan of an unordered index. - ** - ** (2013-10-03) Do not count the entries in a partial index. - ** - ** In practice the KeyInfo structure will not be used. It is only - ** passed to keep OP_OpenRead happy. - */ - if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->bUnordered==0 - && pIdx->szIdxRowszTabRow - && pIdx->pPartIdxWhere==0 - && (!pBest || pIdx->szIdxRowszIdxRow) - ){ - pBest = pIdx; - } - } - if( pBest ){ - iRoot = pBest->tnum; - pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest); - } - - /* Open a read-only cursor, execute the OP_Count, close the cursor. */ - sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); - if( pKeyInfo ){ - sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); - } - sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); - sqlite3VdbeAddOp1(v, OP_Close, iCsr); - explainSimpleCount(pParse, pTab, pBest); - }else -#endif /* SQLITE_OMIT_BTREECOUNT */ - { - /* Check if the query is of one of the following forms: - ** - ** SELECT min(x) FROM ... - ** SELECT max(x) FROM ... - ** - ** If it is, then ask the code in where.c to attempt to sort results - ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause. - ** If where.c is able to produce results sorted in this order, then - ** add vdbe code to break out of the processing loop after the - ** first iteration (since the first iteration of the loop is - ** guaranteed to operate on the row with the minimum or maximum - ** value of x, the only row required). - ** - ** A special flag must be passed to sqlite3WhereBegin() to slightly - ** modify behavior as follows: - ** - ** + If the query is a "SELECT min(x)", then the loop coded by - ** where.c should not iterate over any values with a NULL value - ** for x. - ** - ** + The optimizer code in where.c (the thing that decides which - ** index or indices to use) should place a different priority on - ** satisfying the 'ORDER BY' clause than it does in other cases. - ** Refer to code and comments in where.c for details. - */ - ExprList *pMinMax = 0; - u8 flag = WHERE_ORDERBY_NORMAL; - - assert( p->pGroupBy==0 ); - assert( flag==0 ); - if( p->pHaving==0 ){ - flag = minMaxQuery(&sAggInfo, &pMinMax); - } - assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) ); - - if( flag ){ - pMinMax = sqlite3ExprListDup(db, pMinMax, 0); - pDel = pMinMax; - assert( db->mallocFailed || pMinMax!=0 ); - if( !db->mallocFailed ){ - pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; - pMinMax->a[0].pExpr->op = TK_COLUMN; - } - } - - /* This case runs if the aggregate has no GROUP BY clause. The - ** processing is much simpler since there is only a single row - ** of output. - */ - resetAccumulator(pParse, &sAggInfo); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0); - if( pWInfo==0 ){ - sqlite3ExprListDelete(db, pDel); - goto select_end; - } - updateAccumulator(pParse, &sAggInfo); - assert( pMinMax==0 || pMinMax->nExpr==1 ); - if( sqlite3WhereIsOrdered(pWInfo)>0 ){ - sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); - VdbeComment((v, "%s() by index", - (flag==WHERE_ORDERBY_MIN?"min":"max"))); - } - sqlite3WhereEnd(pWInfo); - finalizeAggFunctions(pParse, &sAggInfo); - } - - sSort.pOrderBy = 0; - sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, p->pEList, -1, 0, 0, - pDest, addrEnd, addrEnd); - sqlite3ExprListDelete(db, pDel); - } - sqlite3VdbeResolveLabel(v, addrEnd); - - } /* endif aggregate query */ - - if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ - explainTempTable(pParse, "DISTINCT"); - } - - /* If there is an ORDER BY clause, then we need to sort the results - ** and send them to the callback one by one. - */ - if( sSort.pOrderBy ){ - explainTempTable(pParse, - sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); - generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); - } - - /* Jump here to skip this query - */ - sqlite3VdbeResolveLabel(v, iEnd); - - /* The SELECT has been coded. If there is an error in the Parse structure, - ** set the return code to 1. Otherwise 0. */ - rc = (pParse->nErr>0); - - /* Control jumps to here if an error is encountered above, or upon - ** successful coding of the SELECT. - */ -select_end: - explainSetInteger(pParse->iSelectId, iRestoreSelectId); - - /* Identify column names if results of the SELECT are to be output. - */ - if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){ - generateColumnNames(pParse, pTabList, pEList); - } - - sqlite3DbFree(db, sAggInfo.aCol); - sqlite3DbFree(db, sAggInfo.aFunc); -#if SELECTTRACE_ENABLED - SELECTTRACE(1,pParse,p,("end processing\n")); - pParse->nSelectIndent--; -#endif - return rc; -} - -/************** End of select.c **********************************************/ -/************** Begin file table.c *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains the sqlite3_get_table() and sqlite3_free_table() -** interface routines. These are just wrappers around the main -** interface routine of sqlite3_exec(). -** -** These routines are in a separate files so that they will not be linked -** if they are not used. -*/ -/* #include "sqliteInt.h" */ -/* #include */ -/* #include */ - -#ifndef SQLITE_OMIT_GET_TABLE - -/* -** This structure is used to pass data from sqlite3_get_table() through -** to the callback function is uses to build the result. -*/ -typedef struct TabResult { - char **azResult; /* Accumulated output */ - char *zErrMsg; /* Error message text, if an error occurs */ - u32 nAlloc; /* Slots allocated for azResult[] */ - u32 nRow; /* Number of rows in the result */ - u32 nColumn; /* Number of columns in the result */ - u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ - int rc; /* Return code from sqlite3_exec() */ -} TabResult; - -/* -** This routine is called once for each row in the result table. Its job -** is to fill in the TabResult structure appropriately, allocating new -** memory as necessary. -*/ -static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ - TabResult *p = (TabResult*)pArg; /* Result accumulator */ - int need; /* Slots needed in p->azResult[] */ - int i; /* Loop counter */ - char *z; /* A single column of result */ - - /* Make sure there is enough space in p->azResult to hold everything - ** we need to remember from this invocation of the callback. - */ - if( p->nRow==0 && argv!=0 ){ - need = nCol*2; - }else{ - need = nCol; - } - if( p->nData + need > p->nAlloc ){ - char **azNew; - p->nAlloc = p->nAlloc*2 + need; - azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); - if( azNew==0 ) goto malloc_failed; - p->azResult = azNew; - } - - /* If this is the first row, then generate an extra row containing - ** the names of all columns. - */ - if( p->nRow==0 ){ - p->nColumn = nCol; - for(i=0; iazResult[p->nData++] = z; - } - }else if( (int)p->nColumn!=nCol ){ - sqlite3_free(p->zErrMsg); - p->zErrMsg = sqlite3_mprintf( - "sqlite3_get_table() called with two or more incompatible queries" - ); - p->rc = SQLITE_ERROR; - return 1; - } - - /* Copy over the row data - */ - if( argv!=0 ){ - for(i=0; iazResult[p->nData++] = z; - } - p->nRow++; - } - return 0; - -malloc_failed: - p->rc = SQLITE_NOMEM_BKPT; - return 1; -} - -/* -** Query the database. But instead of invoking a callback for each row, -** malloc() for space to hold the result and return the entire results -** at the conclusion of the call. -** -** The result that is written to ***pazResult is held in memory obtained -** from malloc(). But the caller cannot free this memory directly. -** Instead, the entire table should be passed to sqlite3_free_table() when -** the calling procedure is finished using it. -*/ -SQLITE_API int sqlite3_get_table( - sqlite3 *db, /* The database on which the SQL executes */ - const char *zSql, /* The SQL to be executed */ - char ***pazResult, /* Write the result table here */ - int *pnRow, /* Write the number of rows in the result here */ - int *pnColumn, /* Write the number of columns of result here */ - char **pzErrMsg /* Write error messages here */ -){ - int rc; - TabResult res; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; -#endif - *pazResult = 0; - if( pnColumn ) *pnColumn = 0; - if( pnRow ) *pnRow = 0; - if( pzErrMsg ) *pzErrMsg = 0; - res.zErrMsg = 0; - res.nRow = 0; - res.nColumn = 0; - res.nData = 1; - res.nAlloc = 20; - res.rc = SQLITE_OK; - res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); - if( res.azResult==0 ){ - db->errCode = SQLITE_NOMEM; - return SQLITE_NOMEM_BKPT; - } - res.azResult[0] = 0; - rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); - assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); - res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); - if( (rc&0xff)==SQLITE_ABORT ){ - sqlite3_free_table(&res.azResult[1]); - if( res.zErrMsg ){ - if( pzErrMsg ){ - sqlite3_free(*pzErrMsg); - *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); - } - sqlite3_free(res.zErrMsg); - } - db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ - return res.rc; - } - sqlite3_free(res.zErrMsg); - if( rc!=SQLITE_OK ){ - sqlite3_free_table(&res.azResult[1]); - return rc; - } - if( res.nAlloc>res.nData ){ - char **azNew; - azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); - if( azNew==0 ){ - sqlite3_free_table(&res.azResult[1]); - db->errCode = SQLITE_NOMEM; - return SQLITE_NOMEM_BKPT; - } - res.azResult = azNew; - } - *pazResult = &res.azResult[1]; - if( pnColumn ) *pnColumn = res.nColumn; - if( pnRow ) *pnRow = res.nRow; - return rc; -} - -/* -** This routine frees the space the sqlite3_get_table() malloced. -*/ -SQLITE_API void sqlite3_free_table( - char **azResult /* Result returned from sqlite3_get_table() */ -){ - if( azResult ){ - int i, n; - azResult--; - assert( azResult!=0 ); - n = SQLITE_PTR_TO_INT(azResult[0]); - for(i=1; ipNext; - - sqlite3ExprDelete(db, pTmp->pWhere); - sqlite3ExprListDelete(db, pTmp->pExprList); - sqlite3SelectDelete(db, pTmp->pSelect); - sqlite3IdListDelete(db, pTmp->pIdList); - - sqlite3DbFree(db, pTmp); - } -} - -/* -** Given table pTab, return a list of all the triggers attached to -** the table. The list is connected by Trigger.pNext pointers. -** -** All of the triggers on pTab that are in the same database as pTab -** are already attached to pTab->pTrigger. But there might be additional -** triggers on pTab in the TEMP schema. This routine prepends all -** TEMP triggers on pTab to the beginning of the pTab->pTrigger list -** and returns the combined list. -** -** To state it another way: This routine returns a list of all triggers -** that fire off of pTab. The list will include any TEMP triggers on -** pTab as well as the triggers lised in pTab->pTrigger. -*/ -SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ - Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; - Trigger *pList = 0; /* List of triggers to return */ - - if( pParse->disableTriggers ){ - return 0; - } - - if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ - Trigger *pTrig = (Trigger *)sqliteHashData(p); - if( pTrig->pTabSchema==pTab->pSchema - && 0==sqlite3StrICmp(pTrig->table, pTab->zName) - ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); - pList = pTrig; - } - } - } - - return (pList ? pList : pTab->pTrigger); -} - -/* -** This is called by the parser when it sees a CREATE TRIGGER statement -** up to the point of the BEGIN before the trigger actions. A Trigger -** structure is generated based on the information available and stored -** in pParse->pNewTrigger. After the trigger actions have been parsed, the -** sqlite3FinishTrigger() function is called to complete the trigger -** construction process. -*/ -SQLITE_PRIVATE void sqlite3BeginTrigger( - Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ - Token *pName1, /* The name of the trigger */ - Token *pName2, /* The name of the trigger */ - int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ - int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ - IdList *pColumns, /* column list if this is an UPDATE OF trigger */ - SrcList *pTableName,/* The name of the table/view the trigger applies to */ - Expr *pWhen, /* WHEN clause */ - int isTemp, /* True if the TEMPORARY keyword is present */ - int noErr /* Suppress errors if the trigger already exists */ -){ - Trigger *pTrigger = 0; /* The new trigger */ - Table *pTab; /* Table that the trigger fires off of */ - char *zName = 0; /* Name of the trigger */ - sqlite3 *db = pParse->db; /* The database connection */ - int iDb; /* The database to store the trigger in */ - Token *pName; /* The unqualified db name */ - DbFixer sFix; /* State vector for the DB fixer */ - - assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ - assert( pName2!=0 ); - assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE ); - assert( op>0 && op<0xff ); - if( isTemp ){ - /* If TEMP was specified, then the trigger name may not be qualified. */ - if( pName2->n>0 ){ - sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); - goto trigger_cleanup; - } - iDb = 1; - pName = pName1; - }else{ - /* Figure out the db that the trigger will be created in */ - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); - if( iDb<0 ){ - goto trigger_cleanup; - } - } - if( !pTableName || db->mallocFailed ){ - goto trigger_cleanup; - } - - /* A long-standing parser bug is that this syntax was allowed: - ** - ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... - ** ^^^^^^^^ - ** - ** To maintain backwards compatibility, ignore the database - ** name on pTableName if we are reparsing out of SQLITE_MASTER. - */ - if( db->init.busy && iDb!=1 ){ - sqlite3DbFree(db, pTableName->a[0].zDatabase); - pTableName->a[0].zDatabase = 0; - } - - /* If the trigger name was unqualified, and the table is a temp table, - ** then set iDb to 1 to create the trigger in the temporary database. - ** If sqlite3SrcListLookup() returns 0, indicating the table does not - ** exist, the error is caught by the block below. - */ - pTab = sqlite3SrcListLookup(pParse, pTableName); - if( db->init.busy==0 && pName2->n==0 && pTab - && pTab->pSchema==db->aDb[1].pSchema ){ - iDb = 1; - } - - /* Ensure the table name matches database name and that the table exists */ - if( db->mallocFailed ) goto trigger_cleanup; - assert( pTableName->nSrc==1 ); - sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); - if( sqlite3FixSrcList(&sFix, pTableName) ){ - goto trigger_cleanup; - } - pTab = sqlite3SrcListLookup(pParse, pTableName); - if( !pTab ){ - /* The table does not exist. */ - if( db->init.iDb==1 ){ - /* Ticket #3810. - ** Normally, whenever a table is dropped, all associated triggers are - ** dropped too. But if a TEMP trigger is created on a non-TEMP table - ** and the table is dropped by a different database connection, the - ** trigger is not visible to the database connection that does the - ** drop so the trigger cannot be dropped. This results in an - ** "orphaned trigger" - a trigger whose associated table is missing. - */ - db->init.orphanTrigger = 1; - } - goto trigger_cleanup; - } - if( IsVirtual(pTab) ){ - sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); - goto trigger_cleanup; - } - - /* Check that the trigger name is not reserved and that no trigger of the - ** specified name exists */ - zName = sqlite3NameFromToken(db, pName); - if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - goto trigger_cleanup; - } - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); - } - goto trigger_cleanup; - } - - /* Do not create a trigger on a system table */ - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ - sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); - goto trigger_cleanup; - } - - /* INSTEAD of triggers are only for views and views only support INSTEAD - ** of triggers. - */ - if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ - sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", - (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); - goto trigger_cleanup; - } - if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ - sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" - " trigger on table: %S", pTableName, 0); - goto trigger_cleanup; - } - -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - int code = SQLITE_CREATE_TRIGGER; - const char *zDb = db->aDb[iTabDb].zDbSName; - const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; - if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; - if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ - goto trigger_cleanup; - } - if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ - goto trigger_cleanup; - } - } -#endif - - /* INSTEAD OF triggers can only appear on views and BEFORE triggers - ** cannot appear on views. So we might as well translate every - ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code - ** elsewhere. - */ - if (tr_tm == TK_INSTEAD){ - tr_tm = TK_BEFORE; - } - - /* Build the Trigger object */ - pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); - if( pTrigger==0 ) goto trigger_cleanup; - pTrigger->zName = zName; - zName = 0; - pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); - pTrigger->pSchema = db->aDb[iDb].pSchema; - pTrigger->pTabSchema = pTab->pSchema; - pTrigger->op = (u8)op; - pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; - pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); - pTrigger->pColumns = sqlite3IdListDup(db, pColumns); - assert( pParse->pNewTrigger==0 ); - pParse->pNewTrigger = pTrigger; - -trigger_cleanup: - sqlite3DbFree(db, zName); - sqlite3SrcListDelete(db, pTableName); - sqlite3IdListDelete(db, pColumns); - sqlite3ExprDelete(db, pWhen); - if( !pParse->pNewTrigger ){ - sqlite3DeleteTrigger(db, pTrigger); - }else{ - assert( pParse->pNewTrigger==pTrigger ); - } -} - -/* -** This routine is called after all of the trigger actions have been parsed -** in order to complete the process of building the trigger. -*/ -SQLITE_PRIVATE void sqlite3FinishTrigger( - Parse *pParse, /* Parser context */ - TriggerStep *pStepList, /* The triggered program */ - Token *pAll /* Token that describes the complete CREATE TRIGGER */ -){ - Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ - char *zName; /* Name of trigger */ - sqlite3 *db = pParse->db; /* The database */ - DbFixer sFix; /* Fixer object */ - int iDb; /* Database containing the trigger */ - Token nameToken; /* Trigger name for error reporting */ - - pParse->pNewTrigger = 0; - if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; - zName = pTrig->zName; - iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); - pTrig->step_list = pStepList; - while( pStepList ){ - pStepList->pTrig = pTrig; - pStepList = pStepList->pNext; - } - sqlite3TokenInit(&nameToken, pTrig->zName); - sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); - if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) - || sqlite3FixExpr(&sFix, pTrig->pWhen) - ){ - goto triggerfinish_cleanup; - } - - /* if we are not initializing, - ** build the sqlite_master entry - */ - if( !db->init.busy ){ - Vdbe *v; - char *z; - - /* Make an entry in the sqlite_master table */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto triggerfinish_cleanup; - sqlite3BeginWriteOperation(pParse, 0, iDb); - z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); - sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName, - pTrig->table, z); - sqlite3DbFree(db, z); - sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); - } - - if( db->init.busy ){ - Trigger *pLink = pTrig; - Hash *pHash = &db->aDb[iDb].pSchema->trigHash; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pTrig = sqlite3HashInsert(pHash, zName, pTrig); - if( pTrig ){ - sqlite3OomFault(db); - }else if( pLink->pSchema==pLink->pTabSchema ){ - Table *pTab; - pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); - assert( pTab!=0 ); - pLink->pNext = pTab->pTrigger; - pTab->pTrigger = pLink; - } - } - -triggerfinish_cleanup: - sqlite3DeleteTrigger(db, pTrig); - assert( !pParse->pNewTrigger ); - sqlite3DeleteTriggerStep(db, pStepList); -} - -/* -** Turn a SELECT statement (that the pSelect parameter points to) into -** a trigger step. Return a pointer to a TriggerStep structure. -** -** The parser calls this routine when it finds a SELECT statement in -** body of a TRIGGER. -*/ -SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){ - TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); - if( pTriggerStep==0 ) { - sqlite3SelectDelete(db, pSelect); - return 0; - } - pTriggerStep->op = TK_SELECT; - pTriggerStep->pSelect = pSelect; - pTriggerStep->orconf = OE_Default; - return pTriggerStep; -} - -/* -** Allocate space to hold a new trigger step. The allocated space -** holds both the TriggerStep object and the TriggerStep.target.z string. -** -** If an OOM error occurs, NULL is returned and db->mallocFailed is set. -*/ -static TriggerStep *triggerStepAllocate( - sqlite3 *db, /* Database connection */ - u8 op, /* Trigger opcode */ - Token *pName /* The target name */ -){ - TriggerStep *pTriggerStep; - - pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); - if( pTriggerStep ){ - char *z = (char*)&pTriggerStep[1]; - memcpy(z, pName->z, pName->n); - sqlite3Dequote(z); - pTriggerStep->zTarget = z; - pTriggerStep->op = op; - } - return pTriggerStep; -} - -/* -** Build a trigger step out of an INSERT statement. Return a pointer -** to the new trigger step. -** -** The parser calls this routine when it sees an INSERT inside the -** body of a trigger. -*/ -SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( - sqlite3 *db, /* The database connection */ - Token *pTableName, /* Name of the table into which we insert */ - IdList *pColumn, /* List of columns in pTableName to insert into */ - Select *pSelect, /* A SELECT statement that supplies values */ - u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ -){ - TriggerStep *pTriggerStep; - - assert(pSelect != 0 || db->mallocFailed); - - pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName); - if( pTriggerStep ){ - pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); - pTriggerStep->pIdList = pColumn; - pTriggerStep->orconf = orconf; - }else{ - sqlite3IdListDelete(db, pColumn); - } - sqlite3SelectDelete(db, pSelect); - - return pTriggerStep; -} - -/* -** Construct a trigger step that implements an UPDATE statement and return -** a pointer to that trigger step. The parser calls this routine when it -** sees an UPDATE statement inside the body of a CREATE TRIGGER. -*/ -SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( - sqlite3 *db, /* The database connection */ - Token *pTableName, /* Name of the table to be updated */ - ExprList *pEList, /* The SET clause: list of column and new values */ - Expr *pWhere, /* The WHERE clause */ - u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ -){ - TriggerStep *pTriggerStep; - - pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName); - if( pTriggerStep ){ - pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); - pTriggerStep->orconf = orconf; - } - sqlite3ExprListDelete(db, pEList); - sqlite3ExprDelete(db, pWhere); - return pTriggerStep; -} - -/* -** Construct a trigger step that implements a DELETE statement and return -** a pointer to that trigger step. The parser calls this routine when it -** sees a DELETE statement inside the body of a CREATE TRIGGER. -*/ -SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( - sqlite3 *db, /* Database connection */ - Token *pTableName, /* The table from which rows are deleted */ - Expr *pWhere /* The WHERE clause */ -){ - TriggerStep *pTriggerStep; - - pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName); - if( pTriggerStep ){ - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); - pTriggerStep->orconf = OE_Default; - } - sqlite3ExprDelete(db, pWhere); - return pTriggerStep; -} - -/* -** Recursively delete a Trigger structure -*/ -SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 ) return; - sqlite3DeleteTriggerStep(db, pTrigger->step_list); - sqlite3DbFree(db, pTrigger->zName); - sqlite3DbFree(db, pTrigger->table); - sqlite3ExprDelete(db, pTrigger->pWhen); - sqlite3IdListDelete(db, pTrigger->pColumns); - sqlite3DbFree(db, pTrigger); -} - -/* -** This function is called to drop a trigger from the database schema. -** -** This may be called directly from the parser and therefore identifies -** the trigger by name. The sqlite3DropTriggerPtr() routine does the -** same job as this routine except it takes a pointer to the trigger -** instead of the trigger name. -**/ -SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ - Trigger *pTrigger = 0; - int i; - const char *zDb; - const char *zName; - sqlite3 *db = pParse->db; - - if( db->mallocFailed ) goto drop_trigger_cleanup; - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ - goto drop_trigger_cleanup; - } - - assert( pName->nSrc==1 ); - zDb = pName->a[0].zDatabase; - zName = pName->a[0].zName; - assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); - for(i=OMIT_TEMPDB; inDb; i++){ - int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; - assert( sqlite3SchemaMutexHeld(db, j, 0) ); - pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); - if( pTrigger ) break; - } - if( !pTrigger ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); - }else{ - sqlite3CodeVerifyNamedSchema(pParse, zDb); - } - pParse->checkSchema = 1; - goto drop_trigger_cleanup; - } - sqlite3DropTriggerPtr(pParse, pTrigger); - -drop_trigger_cleanup: - sqlite3SrcListDelete(db, pName); -} - -/* -** Return a pointer to the Table structure for the table that a trigger -** is set on. -*/ -static Table *tableOfTrigger(Trigger *pTrigger){ - return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); -} - - -/* -** Drop a trigger given a pointer to that trigger. -*/ -SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ - Table *pTable; - Vdbe *v; - sqlite3 *db = pParse->db; - int iDb; - - iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); - assert( iDb>=0 && iDbnDb ); - pTable = tableOfTrigger(pTrigger); - assert( pTable ); - assert( pTable->pSchema==pTrigger->pSchema || iDb==1 ); -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int code = SQLITE_DROP_TRIGGER; - const char *zDb = db->aDb[iDb].zDbSName; - const char *zTab = SCHEMA_TABLE(iDb); - if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; - if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || - sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ - return; - } - } -#endif - - /* Generate code to destroy the database record of the trigger. - */ - assert( pTable!=0 ); - if( (v = sqlite3GetVdbe(pParse))!=0 ){ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName - ); - sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); - } -} - -/* -** Remove a trigger from the hash tables of the sqlite* pointer. -*/ -SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ - Trigger *pTrigger; - Hash *pHash; - - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pHash = &(db->aDb[iDb].pSchema->trigHash); - pTrigger = sqlite3HashInsert(pHash, zName, 0); - if( ALWAYS(pTrigger) ){ - if( pTrigger->pSchema==pTrigger->pTabSchema ){ - Table *pTab = tableOfTrigger(pTrigger); - Trigger **pp; - for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; - } - sqlite3DeleteTrigger(db, pTrigger); - db->flags |= SQLITE_InternChanges; - } -} - -/* -** pEList is the SET clause of an UPDATE statement. Each entry -** in pEList is of the format =. If any of the entries -** in pEList have an which matches an identifier in pIdList, -** then return TRUE. If pIdList==NULL, then it is considered a -** wildcard that matches anything. Likewise if pEList==NULL then -** it matches anything so always return true. Return false only -** if there is no match. -*/ -static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ - int e; - if( pIdList==0 || NEVER(pEList==0) ) return 1; - for(e=0; enExpr; e++){ - if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1; - } - return 0; -} - -/* -** Return a list of all triggers on table pTab if there exists at least -** one trigger that must be fired when an operation of type 'op' is -** performed on the table, and, if that operation is an UPDATE, if at -** least one of the columns in pChanges is being modified. -*/ -SQLITE_PRIVATE Trigger *sqlite3TriggersExist( - Parse *pParse, /* Parse context */ - Table *pTab, /* The table the contains the triggers */ - int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ - ExprList *pChanges, /* Columns that change in an UPDATE statement */ - int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ -){ - int mask = 0; - Trigger *pList = 0; - Trigger *p; - - if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ - pList = sqlite3TriggerList(pParse, pTab); - } - assert( pList==0 || IsVirtual(pTab)==0 ); - for(p=pList; p; p=p->pNext){ - if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ - mask |= p->tr_tm; - } - } - if( pMask ){ - *pMask = mask; - } - return (mask ? pList : 0); -} - -/* -** Convert the pStep->zTarget string into a SrcList and return a pointer -** to that SrcList. -** -** This routine adds a specific database name, if needed, to the target when -** forming the SrcList. This prevents a trigger in one database from -** referring to a target in another database. An exception is when the -** trigger is in TEMP in which case it can refer to any other database it -** wants. -*/ -static SrcList *targetSrcList( - Parse *pParse, /* The parsing context */ - TriggerStep *pStep /* The trigger containing the target token */ -){ - sqlite3 *db = pParse->db; - int iDb; /* Index of the database to use */ - SrcList *pSrc; /* SrcList to be returned */ - - pSrc = sqlite3SrcListAppend(db, 0, 0, 0); - if( pSrc ){ - assert( pSrc->nSrc>0 ); - pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); - iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema); - if( iDb==0 || iDb>=2 ){ - const char *zDb; - assert( iDbnDb ); - zDb = db->aDb[iDb].zDbSName; - pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb); - } - } - return pSrc; -} - -/* -** Generate VDBE code for the statements inside the body of a single -** trigger. -*/ -static int codeTriggerProgram( - Parse *pParse, /* The parser context */ - TriggerStep *pStepList, /* List of statements inside the trigger body */ - int orconf /* Conflict algorithm. (OE_Abort, etc) */ -){ - TriggerStep *pStep; - Vdbe *v = pParse->pVdbe; - sqlite3 *db = pParse->db; - - assert( pParse->pTriggerTab && pParse->pToplevel ); - assert( pStepList ); - assert( v!=0 ); - for(pStep=pStepList; pStep; pStep=pStep->pNext){ - /* Figure out the ON CONFLICT policy that will be used for this step - ** of the trigger program. If the statement that caused this trigger - ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use - ** the ON CONFLICT policy that was specified as part of the trigger - ** step statement. Example: - ** - ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; - ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); - ** END; - ** - ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy - ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy - */ - pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; - assert( pParse->okConstFactor==0 ); - - switch( pStep->op ){ - case TK_UPDATE: { - sqlite3Update(pParse, - targetSrcList(pParse, pStep), - sqlite3ExprListDup(db, pStep->pExprList, 0), - sqlite3ExprDup(db, pStep->pWhere, 0), - pParse->eOrconf - ); - break; - } - case TK_INSERT: { - sqlite3Insert(pParse, - targetSrcList(pParse, pStep), - sqlite3SelectDup(db, pStep->pSelect, 0), - sqlite3IdListDup(db, pStep->pIdList), - pParse->eOrconf - ); - break; - } - case TK_DELETE: { - sqlite3DeleteFrom(pParse, - targetSrcList(pParse, pStep), - sqlite3ExprDup(db, pStep->pWhere, 0) - ); - break; - } - default: assert( pStep->op==TK_SELECT ); { - SelectDest sDest; - Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); - sqlite3SelectDestInit(&sDest, SRT_Discard, 0); - sqlite3Select(pParse, pSelect, &sDest); - sqlite3SelectDelete(db, pSelect); - break; - } - } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } - } - - return 0; -} - -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS -/* -** This function is used to add VdbeComment() annotations to a VDBE -** program. It is not used in production code, only for debugging. -*/ -static const char *onErrorText(int onError){ - switch( onError ){ - case OE_Abort: return "abort"; - case OE_Rollback: return "rollback"; - case OE_Fail: return "fail"; - case OE_Replace: return "replace"; - case OE_Ignore: return "ignore"; - case OE_Default: return "default"; - } - return "n/a"; -} -#endif - -/* -** Parse context structure pFrom has just been used to create a sub-vdbe -** (trigger program). If an error has occurred, transfer error information -** from pFrom to pTo. -*/ -static void transferParseError(Parse *pTo, Parse *pFrom){ - assert( pFrom->zErrMsg==0 || pFrom->nErr ); - assert( pTo->zErrMsg==0 || pTo->nErr ); - if( pTo->nErr==0 ){ - pTo->zErrMsg = pFrom->zErrMsg; - pTo->nErr = pFrom->nErr; - pTo->rc = pFrom->rc; - }else{ - sqlite3DbFree(pFrom->db, pFrom->zErrMsg); - } -} - -/* -** Create and populate a new TriggerPrg object with a sub-program -** implementing trigger pTrigger with ON CONFLICT policy orconf. -*/ -static TriggerPrg *codeRowTrigger( - Parse *pParse, /* Current parse context */ - Trigger *pTrigger, /* Trigger to code */ - Table *pTab, /* The table pTrigger is attached to */ - int orconf /* ON CONFLICT policy to code trigger program with */ -){ - Parse *pTop = sqlite3ParseToplevel(pParse); - sqlite3 *db = pParse->db; /* Database handle */ - TriggerPrg *pPrg; /* Value to return */ - Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ - Vdbe *v; /* Temporary VM */ - NameContext sNC; /* Name context for sub-vdbe */ - SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ - Parse *pSubParse; /* Parse context for sub-vdbe */ - int iEndTrigger = 0; /* Label to jump to if WHEN is false */ - - assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); - assert( pTop->pVdbe ); - - /* Allocate the TriggerPrg and SubProgram objects. To ensure that they - ** are freed if an error occurs, link them into the Parse.pTriggerPrg - ** list of the top-level Parse object sooner rather than later. */ - pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); - if( !pPrg ) return 0; - pPrg->pNext = pTop->pTriggerPrg; - pTop->pTriggerPrg = pPrg; - pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); - if( !pProgram ) return 0; - sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); - pPrg->pTrigger = pTrigger; - pPrg->orconf = orconf; - pPrg->aColmask[0] = 0xffffffff; - pPrg->aColmask[1] = 0xffffffff; - - /* Allocate and populate a new Parse context to use for coding the - ** trigger sub-program. */ - pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); - if( !pSubParse ) return 0; - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pSubParse; - pSubParse->db = db; - pSubParse->pTriggerTab = pTab; - pSubParse->pToplevel = pTop; - pSubParse->zAuthContext = pTrigger->zName; - pSubParse->eTriggerOp = pTrigger->op; - pSubParse->nQueryLoop = pParse->nQueryLoop; - - v = sqlite3GetVdbe(pSubParse); - if( v ){ - VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", - pTrigger->zName, onErrorText(orconf), - (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), - (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), - (pTrigger->op==TK_INSERT ? "INSERT" : ""), - (pTrigger->op==TK_DELETE ? "DELETE" : ""), - pTab->zName - )); -#ifndef SQLITE_OMIT_TRACE - sqlite3VdbeChangeP4(v, -1, - sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC - ); -#endif - - /* If one was specified, code the WHEN clause. If it evaluates to false - ** (or NULL) the sub-vdbe is immediately halted by jumping to the - ** OP_Halt inserted at the end of the program. */ - if( pTrigger->pWhen ){ - pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); - if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) - && db->mallocFailed==0 - ){ - iEndTrigger = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); - } - sqlite3ExprDelete(db, pWhen); - } - - /* Code the trigger program into the sub-vdbe. */ - codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); - - /* Insert an OP_Halt at the end of the sub-program. */ - if( iEndTrigger ){ - sqlite3VdbeResolveLabel(v, iEndTrigger); - } - sqlite3VdbeAddOp0(v, OP_Halt); - VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); - - transferParseError(pParse, pSubParse); - if( db->mallocFailed==0 ){ - pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); - } - pProgram->nMem = pSubParse->nMem; - pProgram->nCsr = pSubParse->nTab; - pProgram->token = (void *)pTrigger; - pPrg->aColmask[0] = pSubParse->oldmask; - pPrg->aColmask[1] = pSubParse->newmask; - sqlite3VdbeDelete(v); - } - - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); - assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); - sqlite3ParserReset(pSubParse); - sqlite3StackFree(db, pSubParse); - - return pPrg; -} - -/* -** Return a pointer to a TriggerPrg object containing the sub-program for -** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such -** TriggerPrg object exists, a new object is allocated and populated before -** being returned. -*/ -static TriggerPrg *getRowTrigger( - Parse *pParse, /* Current parse context */ - Trigger *pTrigger, /* Trigger to code */ - Table *pTab, /* The table trigger pTrigger is attached to */ - int orconf /* ON CONFLICT algorithm. */ -){ - Parse *pRoot = sqlite3ParseToplevel(pParse); - TriggerPrg *pPrg; - - assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); - - /* It may be that this trigger has already been coded (or is in the - ** process of being coded). If this is the case, then an entry with - ** a matching TriggerPrg.pTrigger field will be present somewhere - ** in the Parse.pTriggerPrg list. Search for such an entry. */ - for(pPrg=pRoot->pTriggerPrg; - pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); - pPrg=pPrg->pNext - ); - - /* If an existing TriggerPrg could not be located, create a new one. */ - if( !pPrg ){ - pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); - } - - return pPrg; -} - -/* -** Generate code for the trigger program associated with trigger p on -** table pTab. The reg, orconf and ignoreJump parameters passed to this -** function are the same as those described in the header function for -** sqlite3CodeRowTrigger() -*/ -SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( - Parse *pParse, /* Parse context */ - Trigger *p, /* Trigger to code */ - Table *pTab, /* The table to code triggers from */ - int reg, /* Reg array containing OLD.* and NEW.* values */ - int orconf, /* ON CONFLICT policy */ - int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ -){ - Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ - TriggerPrg *pPrg; - pPrg = getRowTrigger(pParse, p, pTab, orconf); - assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); - - /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program - ** is a pointer to the sub-vdbe containing the trigger program. */ - if( pPrg ){ - int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); - - sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, - (const char *)pPrg->pProgram, P4_SUBPROGRAM); - VdbeComment( - (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); - - /* Set the P5 operand of the OP_Program instruction to non-zero if - ** recursive invocation of this trigger program is disallowed. Recursive - ** invocation is disallowed if (a) the sub-program is really a trigger, - ** not a foreign key action, and (b) the flag to enable recursive triggers - ** is clear. */ - sqlite3VdbeChangeP5(v, (u8)bRecursive); - } -} - -/* -** This is called to code the required FOR EACH ROW triggers for an operation -** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) -** is given by the op parameter. The tr_tm parameter determines whether the -** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then -** parameter pChanges is passed the list of columns being modified. -** -** If there are no triggers that fire at the specified time for the specified -** operation on pTab, this function is a no-op. -** -** The reg argument is the address of the first in an array of registers -** that contain the values substituted for the new.* and old.* references -** in the trigger program. If N is the number of columns in table pTab -** (a copy of pTab->nCol), then registers are populated as follows: -** -** Register Contains -** ------------------------------------------------------ -** reg+0 OLD.rowid -** reg+1 OLD.* value of left-most column of pTab -** ... ... -** reg+N OLD.* value of right-most column of pTab -** reg+N+1 NEW.rowid -** reg+N+2 OLD.* value of left-most column of pTab -** ... ... -** reg+N+N+1 NEW.* value of right-most column of pTab -** -** For ON DELETE triggers, the registers containing the NEW.* values will -** never be accessed by the trigger program, so they are not allocated or -** populated by the caller (there is no data to populate them with anyway). -** Similarly, for ON INSERT triggers the values stored in the OLD.* registers -** are never accessed, and so are not allocated by the caller. So, for an -** ON INSERT trigger, the value passed to this function as parameter reg -** is not a readable register, although registers (reg+N) through -** (reg+N+N+1) are. -** -** Parameter orconf is the default conflict resolution algorithm for the -** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump -** is the instruction that control should jump to if a trigger program -** raises an IGNORE exception. -*/ -SQLITE_PRIVATE void sqlite3CodeRowTrigger( - Parse *pParse, /* Parse context */ - Trigger *pTrigger, /* List of triggers on table pTab */ - int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ - ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ - int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ - Table *pTab, /* The table to code triggers from */ - int reg, /* The first in an array of registers (see above) */ - int orconf, /* ON CONFLICT policy */ - int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ -){ - Trigger *p; /* Used to iterate through pTrigger list */ - - assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); - assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); - assert( (op==TK_UPDATE)==(pChanges!=0) ); - - for(p=pTrigger; p; p=p->pNext){ - - /* Sanity checking: The schema for the trigger and for the table are - ** always defined. The trigger must be in the same schema as the table - ** or else it must be a TEMP trigger. */ - assert( p->pSchema!=0 ); - assert( p->pTabSchema!=0 ); - assert( p->pSchema==p->pTabSchema - || p->pSchema==pParse->db->aDb[1].pSchema ); - - /* Determine whether we should code this trigger */ - if( p->op==op - && p->tr_tm==tr_tm - && checkColumnOverlap(p->pColumns, pChanges) - ){ - sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); - } - } -} - -/* -** Triggers may access values stored in the old.* or new.* pseudo-table. -** This function returns a 32-bit bitmask indicating which columns of the -** old.* or new.* tables actually are used by triggers. This information -** may be used by the caller, for example, to avoid having to load the entire -** old.* record into memory when executing an UPDATE or DELETE command. -** -** Bit 0 of the returned mask is set if the left-most column of the -** table may be accessed using an [old|new].reference. Bit 1 is set if -** the second leftmost column value is required, and so on. If there -** are more than 32 columns in the table, and at least one of the columns -** with an index greater than 32 may be accessed, 0xffffffff is returned. -** -** It is not possible to determine if the old.rowid or new.rowid column is -** accessed by triggers. The caller must always assume that it is. -** -** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned -** applies to the old.* table. If 1, the new.* table. -** -** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE -** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only -** included in the returned mask if the TRIGGER_BEFORE bit is set in the -** tr_tm parameter. Similarly, values accessed by AFTER triggers are only -** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. -*/ -SQLITE_PRIVATE u32 sqlite3TriggerColmask( - Parse *pParse, /* Parse context */ - Trigger *pTrigger, /* List of triggers on table pTab */ - ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ - int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */ - int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ - Table *pTab, /* The table to code triggers from */ - int orconf /* Default ON CONFLICT policy for trigger steps */ -){ - const int op = pChanges ? TK_UPDATE : TK_DELETE; - u32 mask = 0; - Trigger *p; - - assert( isNew==1 || isNew==0 ); - for(p=pTrigger; p; p=p->pNext){ - if( p->op==op && (tr_tm&p->tr_tm) - && checkColumnOverlap(p->pColumns,pChanges) - ){ - TriggerPrg *pPrg; - pPrg = getRowTrigger(pParse, p, pTab, orconf); - if( pPrg ){ - mask |= pPrg->aColmask[isNew]; - } - } - } - - return mask; -} - -#endif /* !defined(SQLITE_OMIT_TRIGGER) */ - -/************** End of trigger.c *********************************************/ -/************** Begin file update.c ******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains C code routines that are called by the parser -** to handle UPDATE statements. -*/ -/* #include "sqliteInt.h" */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* Forward declaration */ -static void updateVirtualTable( - Parse *pParse, /* The parsing context */ - SrcList *pSrc, /* The virtual table to be modified */ - Table *pTab, /* The virtual table */ - ExprList *pChanges, /* The columns to change in the UPDATE statement */ - Expr *pRowidExpr, /* Expression used to recompute the rowid */ - int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ - Expr *pWhere, /* WHERE clause of the UPDATE statement */ - int onError /* ON CONFLICT strategy */ -); -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/* -** The most recently coded instruction was an OP_Column to retrieve the -** i-th column of table pTab. This routine sets the P4 parameter of the -** OP_Column to the default value, if any. -** -** The default value of a column is specified by a DEFAULT clause in the -** column definition. This was either supplied by the user when the table -** was created, or added later to the table definition by an ALTER TABLE -** command. If the latter, then the row-records in the table btree on disk -** may not contain a value for the column and the default value, taken -** from the P4 parameter of the OP_Column instruction, is returned instead. -** If the former, then all row-records are guaranteed to include a value -** for the column and the P4 value is not required. -** -** Column definitions created by an ALTER TABLE command may only have -** literal default values specified: a number, null or a string. (If a more -** complicated default expression value was provided, it is evaluated -** when the ALTER TABLE is executed and one of the literal values written -** into the sqlite_master table.) -** -** Therefore, the P4 parameter is only required if the default value for -** the column is a literal number, string or null. The sqlite3ValueFromExpr() -** function is capable of transforming these types of expressions into -** sqlite3_value objects. -** -** If parameter iReg is not negative, code an OP_RealAffinity instruction -** on register iReg. This is used when an equivalent integer value is -** stored in place of an 8-byte floating point value in order to save -** space. -*/ -SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ - assert( pTab!=0 ); - if( !pTab->pSelect ){ - sqlite3_value *pValue = 0; - u8 enc = ENC(sqlite3VdbeDb(v)); - Column *pCol = &pTab->aCol[i]; - VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); - assert( inCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, - pCol->affinity, &pValue); - if( pValue ){ - sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); - } -#ifndef SQLITE_OMIT_FLOATING_POINT - if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); - } -#endif - } -} - -/* -** Process an UPDATE statement. -** -** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; -** \_______/ \________/ \______/ \________________/ -* onError pTabList pChanges pWhere -*/ -SQLITE_PRIVATE void sqlite3Update( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* The table in which we should change things */ - ExprList *pChanges, /* Things to be changed */ - Expr *pWhere, /* The WHERE clause. May be null */ - int onError /* How to handle constraint errors */ -){ - int i, j; /* Loop counters */ - Table *pTab; /* The table to be updated */ - int addrTop = 0; /* VDBE instruction address of the start of the loop */ - WhereInfo *pWInfo; /* Information about the WHERE clause */ - Vdbe *v; /* The virtual database engine */ - Index *pIdx; /* For looping over indices */ - Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ - int nIdx; /* Number of indices that need updating */ - int iBaseCur; /* Base cursor number */ - int iDataCur; /* Cursor for the canonical data btree */ - int iIdxCur; /* Cursor for the first index */ - sqlite3 *db; /* The database structure */ - int *aRegIdx = 0; /* One register assigned to each index to be updated */ - int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the - ** an expression for the i-th column of the table. - ** aXRef[i]==-1 if the i-th column is not changed. */ - u8 *aToOpen; /* 1 for tables and indices to be opened */ - u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ - u8 chngRowid; /* Rowid changed in a normal table */ - u8 chngKey; /* Either chngPk or chngRowid */ - Expr *pRowidExpr = 0; /* Expression defining the new record number */ - AuthContext sContext; /* The authorization context */ - NameContext sNC; /* The name-context to resolve expressions in */ - int iDb; /* Database containing the table being updated */ - int okOnePass; /* True for one-pass algorithm without the FIFO */ - int hasFK; /* True if foreign key processing is required */ - int labelBreak; /* Jump here to break out of UPDATE loop */ - int labelContinue; /* Jump here to continue next step of UPDATE loop */ - -#ifndef SQLITE_OMIT_TRIGGER - int isView; /* True when updating a view (INSTEAD OF trigger) */ - Trigger *pTrigger; /* List of triggers on pTab, if required */ - int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ -#endif - int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */ - int iEph = 0; /* Ephemeral table holding all primary key values */ - int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ - int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ - - /* Register Allocations */ - int regRowCount = 0; /* A count of rows changed */ - int regOldRowid = 0; /* The old rowid */ - int regNewRowid = 0; /* The new rowid */ - int regNew = 0; /* Content of the NEW.* table in triggers */ - int regOld = 0; /* Content of OLD.* table in triggers */ - int regRowSet = 0; /* Rowset of rows to be updated */ - int regKey = 0; /* composite PRIMARY KEY value */ - - memset(&sContext, 0, sizeof(sContext)); - db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ - goto update_cleanup; - } - assert( pTabList->nSrc==1 ); - - /* Locate the table which we want to update. - */ - pTab = sqlite3SrcListLookup(pParse, pTabList); - if( pTab==0 ) goto update_cleanup; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - - /* Figure out if we have any triggers and if the table being - ** updated is a view. - */ -#ifndef SQLITE_OMIT_TRIGGER - pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); - isView = pTab->pSelect!=0; - assert( pTrigger || tmask==0 ); -#else -# define pTrigger 0 -# define isView 0 -# define tmask 0 -#endif -#ifdef SQLITE_OMIT_VIEW -# undef isView -# define isView 0 -#endif - - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto update_cleanup; - } - if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ - goto update_cleanup; - } - - /* Allocate a cursors for the main database table and for all indices. - ** The index cursors might not be used, but if they are used they - ** need to occur right after the database cursor. So go ahead and - ** allocate enough space, just in case. - */ - pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; - iIdxCur = iDataCur+1; - pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ - if( IsPrimaryKeyIndex(pIdx) && pPk!=0 ){ - iDataCur = pParse->nTab; - pTabList->a[0].iCursor = iDataCur; - } - pParse->nTab++; - } - - /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. - ** Initialize aXRef[] and aToOpen[] to their default values. - */ - aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); - if( aXRef==0 ) goto update_cleanup; - aRegIdx = aXRef+pTab->nCol; - aToOpen = (u8*)(aRegIdx+nIdx); - memset(aToOpen, 1, nIdx+1); - aToOpen[nIdx+1] = 0; - for(i=0; inCol; i++) aXRef[i] = -1; - - /* Initialize the name-context */ - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - sNC.pSrcList = pTabList; - - /* Resolve the column names in all the expressions of the - ** of the UPDATE statement. Also find the column index - ** for each column to be updated in the pChanges array. For each - ** column to be updated, make sure we have authorization to change - ** that column. - */ - chngRowid = chngPk = 0; - for(i=0; inExpr; i++){ - if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ - goto update_cleanup; - } - for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ - if( j==pTab->iPKey ){ - chngRowid = 1; - pRowidExpr = pChanges->a[i].pExpr; - }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ - chngPk = 1; - } - aXRef[j] = i; - break; - } - } - if( j>=pTab->nCol ){ - if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){ - j = -1; - chngRowid = 1; - pRowidExpr = pChanges->a[i].pExpr; - }else{ - sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); - pParse->checkSchema = 1; - goto update_cleanup; - } - } -#ifndef SQLITE_OMIT_AUTHORIZATION - { - int rc; - rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, - j<0 ? "ROWID" : pTab->aCol[j].zName, - db->aDb[iDb].zDbSName); - if( rc==SQLITE_DENY ){ - goto update_cleanup; - }else if( rc==SQLITE_IGNORE ){ - aXRef[j] = -1; - } - } -#endif - } - assert( (chngRowid & chngPk)==0 ); - assert( chngRowid==0 || chngRowid==1 ); - assert( chngPk==0 || chngPk==1 ); - chngKey = chngRowid + chngPk; - - /* The SET expressions are not actually used inside the WHERE loop. - ** So reset the colUsed mask. Unless this is a virtual table. In that - ** case, set all bits of the colUsed mask (to ensure that the virtual - ** table implementation makes all columns available). - */ - pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0; - - hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); - - /* There is one entry in the aRegIdx[] array for each index on the table - ** being updated. Fill in aRegIdx[] with a register number that will hold - ** the key for accessing each index. - ** - ** FIXME: Be smarter about omitting indexes that use expressions. - */ - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - int reg; - if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ - reg = ++pParse->nMem; - }else{ - reg = 0; - for(i=0; inKeyCol; i++){ - i16 iIdxCol = pIdx->aiColumn[i]; - if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ - reg = ++pParse->nMem; - break; - } - } - } - if( reg==0 ) aToOpen[j+1] = 0; - aRegIdx[j] = reg; - } - - /* Begin generating code. */ - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto update_cleanup; - if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, 1, iDb); - - /* Allocate required registers. */ - if( !IsVirtual(pTab) ){ - regRowSet = ++pParse->nMem; - regOldRowid = regNewRowid = ++pParse->nMem; - if( chngPk || pTrigger || hasFK ){ - regOld = pParse->nMem + 1; - pParse->nMem += pTab->nCol; - } - if( chngKey || pTrigger || hasFK ){ - regNewRowid = ++pParse->nMem; - } - regNew = pParse->nMem + 1; - pParse->nMem += pTab->nCol; - } - - /* Start the view context. */ - if( isView ){ - sqlite3AuthContextPush(pParse, &sContext, pTab->zName); - } - - /* If we are trying to update a view, realize that view into - ** an ephemeral table. - */ -#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) - if( isView ){ - sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur); - } -#endif - - /* Resolve the column names in all the expressions in the - ** WHERE clause. - */ - if( sqlite3ResolveExprNames(&sNC, pWhere) ){ - goto update_cleanup; - } - -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Virtual tables must be handled separately */ - if( IsVirtual(pTab) ){ - updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, - pWhere, onError); - goto update_cleanup; - } -#endif - - /* Begin the database scan - */ - if( HasRowid(pTab) ){ - sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); - pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, - WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE, iIdxCur - ); - if( pWInfo==0 ) goto update_cleanup; - okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - - /* Remember the rowid of every item to be updated. - */ - sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); - if( !okOnePass ){ - sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); - } - - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); - }else{ - int iPk; /* First of nPk memory cells holding PRIMARY KEY value */ - i16 nPk; /* Number of components of the PRIMARY KEY */ - int addrOpen; /* Address of the OpenEphemeral instruction */ - - assert( pPk!=0 ); - nPk = pPk->nKeyCol; - iPk = pParse->nMem+1; - pParse->nMem += nPk; - regKey = ++pParse->nMem; - iEph = pParse->nTab++; - sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); - addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, - WHERE_ONEPASS_DESIRED, iIdxCur); - if( pWInfo==0 ) goto update_cleanup; - okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - for(i=0; iaiColumn[i]>=0 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i], - iPk+i); - } - if( okOnePass ){ - sqlite3VdbeChangeToNoop(v, addrOpen); - nKey = nPk; - regKey = iPk; - }else{ - sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, - sqlite3IndexAffinityStr(db, pPk), nPk); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey); - } - sqlite3WhereEnd(pWInfo); - } - - /* Initialize the count of updated rows - */ - if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ - regRowCount = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); - } - - labelBreak = sqlite3VdbeMakeLabel(v); - if( !isView ){ - /* - ** Open every index that needs updating. Note that if any - ** index could potentially invoke a REPLACE conflict resolution - ** action, then we need to open all indices because we might need - ** to be deleting some records. - */ - if( onError==OE_Replace ){ - memset(aToOpen, 1, nIdx+1); - }else{ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->onError==OE_Replace ){ - memset(aToOpen, 1, nIdx+1); - break; - } - } - } - if( okOnePass ){ - if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; - if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; - } - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, - 0, 0); - } - - /* Top of the update loop */ - if( okOnePass ){ - if( aToOpen[iDataCur-iBaseCur] && !isView ){ - assert( pPk ); - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); - VdbeCoverageNeverTaken(v); - } - labelContinue = labelBreak; - sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); - VdbeCoverageIf(v, pPk==0); - VdbeCoverageIf(v, pPk!=0); - }else if( pPk ){ - labelContinue = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); - addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey); - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); - VdbeCoverage(v); - }else{ - labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak, - regOldRowid); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); - VdbeCoverage(v); - } - - /* If the record number will change, set register regNewRowid to - ** contain the new value. If the record number is not being modified, - ** then regNewRowid is the same register as regOldRowid, which is - ** already populated. */ - assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); - if( chngRowid ){ - sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); - } - - /* Compute the old pre-UPDATE content of the row being changed, if that - ** information is needed */ - if( chngPk || hasFK || pTrigger ){ - u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); - oldmask |= sqlite3TriggerColmask(pParse, - pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError - ); - for(i=0; inCol; i++){ - if( oldmask==0xffffffff - || (i<32 && (oldmask & MASKBIT32(i))!=0) - || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 - ){ - testcase( oldmask!=0xffffffff && i==31 ); - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i); - } - } - if( chngRowid==0 && pPk==0 ){ - sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); - } - } - - /* Populate the array of registers beginning at regNew with the new - ** row data. This array is used to check constants, create the new - ** table and index records, and as the values for any new.* references - ** made by triggers. - ** - ** If there are one or more BEFORE triggers, then do not populate the - ** registers associated with columns that are (a) not modified by - ** this UPDATE statement and (b) not accessed by new.* references. The - ** values for registers not modified by the UPDATE must be reloaded from - ** the database after the BEFORE triggers are fired anyway (as the trigger - ** may have modified them). So not loading those that are not going to - ** be used eliminates some redundant opcodes. - */ - newmask = sqlite3TriggerColmask( - pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError - ); - for(i=0; inCol; i++){ - if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); - }else{ - j = aXRef[i]; - if( j>=0 ){ - sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); - }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ - /* This branch loads the value of a column that will not be changed - ** into a register. This is done if there are no BEFORE triggers, or - ** if there are one or more BEFORE triggers that use this value via - ** a new.* reference in a trigger program. - */ - testcase( i==31 ); - testcase( i==32 ); - sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); - } - } - } - - /* Fire any BEFORE UPDATE triggers. This happens before constraints are - ** verified. One could argue that this is wrong. - */ - if( tmask&TRIGGER_BEFORE ){ - sqlite3TableAffinity(v, pTab, regNew); - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); - - /* The row-trigger may have deleted the row being updated. In this - ** case, jump to the next row. No updates or AFTER triggers are - ** required. This behavior - what happens when the row being updated - ** is deleted or renamed by a BEFORE trigger - is left undefined in the - ** documentation. - */ - if( pPk ){ - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); - VdbeCoverage(v); - }else{ - sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); - VdbeCoverage(v); - } - - /* If it did not delete it, the row-trigger may still have modified - ** some of the columns of the row being updated. Load the values for - ** all columns not modified by the update statement into their - ** registers in case this has happened. - */ - for(i=0; inCol; i++){ - if( aXRef[i]<0 && i!=pTab->iPKey ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); - } - } - } - - if( !isView ){ - int addr1 = 0; /* Address of jump instruction */ - int bReplace = 0; /* True if REPLACE conflict resolution might happen */ - - /* Do constraint checks. */ - assert( regOldRowid>0 ); - sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, - regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, - aXRef); - - /* Do FK constraint checks. */ - if( hasFK ){ - sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); - } - - /* Delete the index entries associated with the current record. */ - if( bReplace || chngKey ){ - if( pPk ){ - addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey); - }else{ - addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid); - } - VdbeCoverageNeverTaken(v); - } - sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); - - /* If changing the rowid value, or if there are foreign key constraints - ** to process, delete the old record. Otherwise, add a noop OP_Delete - ** to invoke the pre-update hook. - ** - ** That (regNew==regnewRowid+1) is true is also important for the - ** pre-update hook. If the caller invokes preupdate_new(), the returned - ** value is copied from memory cell (regNewRowid+1+iCol), where iCol - ** is the column index supplied by the user. - */ - assert( regNew==regNewRowid+1 ); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK - sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, - OPFLAG_ISUPDATE | ((hasFK || chngKey || pPk!=0) ? 0 : OPFLAG_ISNOOP), - regNewRowid - ); - if( !pParse->nested ){ - sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE); - } -#else - if( hasFK || chngKey || pPk!=0 ){ - sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); - } -#endif - if( bReplace || chngKey ){ - sqlite3VdbeJumpHere(v, addr1); - } - - if( hasFK ){ - sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); - } - - /* Insert the new index entries and the new record. */ - sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, - regNewRowid, aRegIdx, 1, 0, 0); - - /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to - ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just updated. */ - if( hasFK ){ - sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); - } - } - - /* Increment the row counter - */ - if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ - sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); - } - - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); - - /* Repeat the above with the next record to be updated, until - ** all record selected by the WHERE clause have been updated. - */ - if( okOnePass ){ - /* Nothing to do at end-of-loop for a single-pass */ - }else if( pPk ){ - sqlite3VdbeResolveLabel(v, labelContinue); - sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); - }else{ - sqlite3VdbeGoto(v, labelContinue); - } - sqlite3VdbeResolveLabel(v, labelBreak); - - /* Close all tables */ - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - assert( aRegIdx ); - if( aToOpen[i+1] ){ - sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0); - } - } - if( iDataCurnested==0 && pParse->pTriggerTab==0 ){ - sqlite3AutoincrementEnd(pParse); - } - - /* - ** Return the number of rows that were changed. If this routine is - ** generating code because of a call to sqlite3NestedParse(), do not - ** invoke the callback function. - */ - if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); - } - -update_cleanup: - sqlite3AuthContextPop(&sContext); - sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ - sqlite3SrcListDelete(db, pTabList); - sqlite3ExprListDelete(db, pChanges); - sqlite3ExprDelete(db, pWhere); - return; -} -/* Make sure "isView" and other macros defined above are undefined. Otherwise -** they may interfere with compilation of other functions in this file -** (or in another file, if this file becomes part of the amalgamation). */ -#ifdef isView - #undef isView -#endif -#ifdef pTrigger - #undef pTrigger -#endif - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* -** Generate code for an UPDATE of a virtual table. -** -** There are two possible strategies - the default and the special -** "onepass" strategy. Onepass is only used if the virtual table -** implementation indicates that pWhere may match at most one row. -** -** The default strategy is to create an ephemeral table that contains -** for each row to be changed: -** -** (A) The original rowid of that row. -** (B) The revised rowid for the row. -** (C) The content of every column in the row. -** -** Then loop through the contents of this ephemeral table executing a -** VUpdate for each row. When finished, drop the ephemeral table. -** -** The "onepass" strategy does not use an ephemeral table. Instead, it -** stores the same values (A, B and C above) in a register array and -** makes a single invocation of VUpdate. -*/ -static void updateVirtualTable( - Parse *pParse, /* The parsing context */ - SrcList *pSrc, /* The virtual table to be modified */ - Table *pTab, /* The virtual table */ - ExprList *pChanges, /* The columns to change in the UPDATE statement */ - Expr *pRowid, /* Expression used to recompute the rowid */ - int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ - Expr *pWhere, /* WHERE clause of the UPDATE statement */ - int onError /* ON CONFLICT strategy */ -){ - Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ - int ephemTab; /* Table holding the result of the SELECT */ - int i; /* Loop counter */ - sqlite3 *db = pParse->db; /* Database connection */ - const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); - WhereInfo *pWInfo; - int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ - int regArg; /* First register in VUpdate arg array */ - int regRec; /* Register in which to assemble record */ - int regRowid; /* Register for ephem table rowid */ - int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ - int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ - int bOnePass; /* True to use onepass strategy */ - int addr; /* Address of OP_OpenEphemeral */ - - /* Allocate nArg registers to martial the arguments to VUpdate. Then - ** create and open the ephemeral table in which the records created from - ** these arguments will be temporarily stored. */ - assert( v ); - ephemTab = pParse->nTab++; - addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg); - regArg = pParse->nMem + 1; - pParse->nMem += nArg; - regRec = ++pParse->nMem; - regRowid = ++pParse->nMem; - - /* Start scanning the virtual table */ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0); - if( pWInfo==0 ) return; - - /* Populate the argument registers. */ - sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); - if( pRowid ){ - sqlite3ExprCode(pParse, pRowid, regArg+1); - }else{ - sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); - } - for(i=0; inCol; i++){ - if( aXRef[i]>=0 ){ - sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); - }else{ - sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); - } - } - - bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); - - if( bOnePass ){ - /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded - ** above. Also, if this is a top-level parse (not a trigger), clear the - ** multi-write flag so that the VM does not open a statement journal */ - sqlite3VdbeChangeToNoop(v, addr); - if( sqlite3IsToplevel(pParse) ){ - pParse->isMultiWrite = 0; - } - }else{ - /* Create a record from the argument register contents and insert it into - ** the ephemeral table. */ - sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); - sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); - } - - - if( bOnePass==0 ){ - /* End the virtual table scan */ - sqlite3WhereEnd(pWInfo); - - /* Begin scannning through the ephemeral table. */ - addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); - - /* Extract arguments from the current row of the ephemeral table and - ** invoke the VUpdate method. */ - for(i=0; i=2 || iDb==0) ){ - sqlite3VdbeAddOp1(v, OP_Vacuum, iDb); - sqlite3VdbeUsesBtree(v, iDb); - } - return; -} - -/* -** This routine implements the OP_Vacuum opcode of the VDBE. -*/ -SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ - int rc = SQLITE_OK; /* Return code from service routines */ - Btree *pMain; /* The database being vacuumed */ - Btree *pTemp; /* The temporary database we vacuum into */ - int saved_flags; /* Saved value of the db->flags */ - int saved_nChange; /* Saved value of db->nChange */ - int saved_nTotalChange; /* Saved value of db->nTotalChange */ - u8 saved_mTrace; /* Saved trace settings */ - Db *pDb = 0; /* Database to detach at end of vacuum */ - int isMemDb; /* True if vacuuming a :memory: database */ - int nRes; /* Bytes of reserved space at the end of each page */ - int nDb; /* Number of attached databases */ - const char *zDbMain; /* Schema name of database to vacuum */ - - if( !db->autoCommit ){ - sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); - return SQLITE_ERROR; - } - if( db->nVdbeActive>1 ){ - sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); - return SQLITE_ERROR; - } - - /* Save the current value of the database flags so that it can be - ** restored before returning. Then set the writable-schema flag, and - ** disable CHECK and foreign key constraints. */ - saved_flags = db->flags; - saved_nChange = db->nChange; - saved_nTotalChange = db->nTotalChange; - saved_mTrace = db->mTrace; - db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks - | SQLITE_PreferBuiltin | SQLITE_Vacuum); - db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows); - db->mTrace = 0; - - zDbMain = db->aDb[iDb].zDbSName; - pMain = db->aDb[iDb].pBt; - isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma - ** can be set to 'off' for this file, as it is not recovered if a crash - ** occurs anyway. The integrity of the database is maintained by a - ** (possibly synchronous) transaction opened on the main database before - ** sqlite3BtreeCopyFile() is called. - ** - ** An optimisation would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but - ** that actually made the VACUUM run slower. Very little journalling - ** actually occurs when doing a vacuum since the vacuum_db is initially - ** empty. Only the journal header is written. Apparently it takes more - ** time to parse and run the PRAGMA to turn journalling off than it does - ** to write the journal header file. - */ - nDb = db->nDb; - rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db"); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - assert( (db->nDb-1)==nDb ); - pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); - pTemp = pDb->pBt; - - /* The call to execSql() to attach the temp database has left the file - ** locked (as there was more than one active statement when the transaction - ** to read the schema was concluded. Unlock it here so that this doesn't - ** cause problems for the call to BtreeSetPageSize() below. */ - sqlite3BtreeCommit(pTemp); - - nRes = sqlite3BtreeGetOptimalReserve(pMain); - - /* A VACUUM cannot change the pagesize of an encrypted database. */ -#ifdef SQLITE_HAS_CODEC - if( db->nextPagesize ){ - extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); - int nKey; - char *zKey; - sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey ) db->nextPagesize = 0; - } -#endif - - sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); - sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); - sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); - - /* Begin a transaction and take an exclusive lock on the main database - ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, - ** to ensure that we do not try to change the page-size on a WAL database. - */ - rc = execSql(db, pzErrMsg, "BEGIN"); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeBeginTrans(pMain, 2); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - - /* Do not attempt to change the page size for a WAL database */ - if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) - ==PAGER_JOURNALMODE_WAL ){ - db->nextPagesize = 0; - } - - if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) - || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) - || NEVER(db->mallocFailed) - ){ - rc = SQLITE_NOMEM_BKPT; - goto end_of_vacuum; - } - -#ifndef SQLITE_OMIT_AUTOVACUUM - sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : - sqlite3BtreeGetAutoVacuum(pMain)); -#endif - - /* Query the schema of the main database. Create a mirror schema - ** in the temporary database. - */ - db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */ - rc = execSqlF(db, pzErrMsg, - "SELECT sql FROM \"%w\".sqlite_master" - " WHERE type='table'AND name<>'sqlite_sequence'" - " AND coalesce(rootpage,1)>0", - zDbMain - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = execSqlF(db, pzErrMsg, - "SELECT sql FROM \"%w\".sqlite_master" - " WHERE type='index' AND length(sql)>10", - zDbMain - ); - if( rc!=SQLITE_OK ) goto end_of_vacuum; - db->init.iDb = 0; - - /* Loop through the tables in the main database. For each, do - ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy - ** the contents to the temporary database. - */ - rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" - "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_master " - "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain - ); - assert( (db->flags & SQLITE_Vacuum)!=0 ); - db->flags &= ~SQLITE_Vacuum; - if( rc!=SQLITE_OK ) goto end_of_vacuum; - - /* Copy the triggers, views, and virtual tables from the main database - ** over to the temporary database. None of these objects has any - ** associated storage, so all we have to do is copy their entries - ** from the SQLITE_MASTER table. - */ - rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_master" - " SELECT*FROM \"%w\".sqlite_master" - " WHERE type IN('view','trigger')" - " OR(type='table'AND rootpage=0)", - zDbMain - ); - if( rc ) goto end_of_vacuum; - - /* At this point, there is a write transaction open on both the - ** vacuum database and the main database. Assuming no error occurs, - ** both transactions are closed by this block - the main database - ** transaction by sqlite3BtreeCopyFile() and the other by an explicit - ** call to sqlite3BtreeCommit(). - */ - { - u32 meta; - int i; - - /* This array determines which meta meta values are preserved in the - ** vacuum. Even entries are the meta value number and odd entries - ** are an increment to apply to the meta value after the vacuum. - ** The increment is used to increase the schema cookie so that other - ** connections to the same database will know to reread the schema. - */ - static const unsigned char aCopy[] = { - BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ - BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */ - BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */ - BTREE_USER_VERSION, 0, /* Preserve the user version */ - BTREE_APPLICATION_ID, 0, /* Preserve the application id */ - }; - - assert( 1==sqlite3BtreeIsInTrans(pTemp) ); - assert( 1==sqlite3BtreeIsInTrans(pMain) ); - - /* Copy Btree meta values */ - for(i=0; iflags */ - db->init.iDb = 0; - db->flags = saved_flags; - db->nChange = saved_nChange; - db->nTotalChange = saved_nTotalChange; - db->mTrace = saved_mTrace; - sqlite3BtreeSetPageSize(pMain, -1, -1, 1); - - /* Currently there is an SQL level transaction open on the vacuum - ** database. No locks are held on any other files (since the main file - ** was committed at the btree level). So it safe to end the transaction - ** by manually setting the autoCommit flag to true and detaching the - ** vacuum database. The vacuum_db journal file is deleted when the pager - ** is closed by the DETACH. - */ - db->autoCommit = 1; - - if( pDb ){ - sqlite3BtreeClose(pDb->pBt); - pDb->pBt = 0; - pDb->pSchema = 0; - } - - /* This both clears the schemas and reduces the size of the db->aDb[] - ** array. */ - sqlite3ResetAllSchemasOfConnection(db); - - return rc; -} - -#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ - -/************** End of vacuum.c **********************************************/ -/************** Begin file vtab.c ********************************************/ -/* -** 2006 June 10 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code used to help implement virtual tables. -*/ -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* #include "sqliteInt.h" */ - -/* -** Before a virtual table xCreate() or xConnect() method is invoked, the -** sqlite3.pVtabCtx member variable is set to point to an instance of -** this struct allocated on the stack. It is used by the implementation of -** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which -** are invoked only from within xCreate and xConnect methods. -*/ -struct VtabCtx { - VTable *pVTable; /* The virtual table being constructed */ - Table *pTab; /* The Table object to which the virtual table belongs */ - VtabCtx *pPrior; /* Parent context (if any) */ - int bDeclared; /* True after sqlite3_declare_vtab() is called */ -}; - -/* -** The actual function that does the work of creating a new module. -** This function implements the sqlite3_create_module() and -** sqlite3_create_module_v2() interfaces. -*/ -static int createModule( - sqlite3 *db, /* Database in which module is registered */ - const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ - void *pAux, /* Context pointer for xCreate/xConnect */ - void (*xDestroy)(void *) /* Module destructor function */ -){ - int rc = SQLITE_OK; - int nName; - - sqlite3_mutex_enter(db->mutex); - nName = sqlite3Strlen30(zName); - if( sqlite3HashFind(&db->aModule, zName) ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - Module *pMod; - pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); - if( pMod ){ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); - memcpy(zCopy, zName, nName+1); - pMod->zName = zCopy; - pMod->pModule = pModule; - pMod->pAux = pAux; - pMod->xDestroy = xDestroy; - pMod->pEpoTab = 0; - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); - assert( pDel==0 || pDel==pMod ); - if( pDel ){ - sqlite3OomFault(db); - sqlite3DbFree(db, pDel); - } - } - } - rc = sqlite3ApiExit(db, rc); - if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); - - sqlite3_mutex_leave(db->mutex); - return rc; -} - - -/* -** External API function used to create a new virtual-table module. -*/ -SQLITE_API int sqlite3_create_module( - sqlite3 *db, /* Database in which module is registered */ - const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ - void *pAux /* Context pointer for xCreate/xConnect */ -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; -#endif - return createModule(db, zName, pModule, pAux, 0); -} - -/* -** External API function used to create a new virtual-table module. -*/ -SQLITE_API int sqlite3_create_module_v2( - sqlite3 *db, /* Database in which module is registered */ - const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ - void *pAux, /* Context pointer for xCreate/xConnect */ - void (*xDestroy)(void *) /* Module destructor function */ -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; -#endif - return createModule(db, zName, pModule, pAux, xDestroy); -} - -/* -** Lock the virtual table so that it cannot be disconnected. -** Locks nest. Every lock should have a corresponding unlock. -** If an unlock is omitted, resources leaks will occur. -** -** If a disconnect is attempted while a virtual table is locked, -** the disconnect is deferred until all locks have been removed. -*/ -SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ - pVTab->nRef++; -} - - -/* -** pTab is a pointer to a Table structure representing a virtual-table. -** Return a pointer to the VTable object used by connection db to access -** this virtual-table, if one has been created, or NULL otherwise. -*/ -SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ - VTable *pVtab; - assert( IsVirtual(pTab) ); - for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); - return pVtab; -} - -/* -** Decrement the ref-count on a virtual table object. When the ref-count -** reaches zero, call the xDisconnect() method to delete the object. -*/ -SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ - sqlite3 *db = pVTab->db; - - assert( db ); - assert( pVTab->nRef>0 ); - assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); - - pVTab->nRef--; - if( pVTab->nRef==0 ){ - sqlite3_vtab *p = pVTab->pVtab; - if( p ){ - p->pModule->xDisconnect(p); - } - sqlite3DbFree(db, pVTab); - } -} - -/* -** Table p is a virtual table. This function moves all elements in the -** p->pVTable list to the sqlite3.pDisconnect lists of their associated -** database connections to be disconnected at the next opportunity. -** Except, if argument db is not NULL, then the entry associated with -** connection db is left in the p->pVTable list. -*/ -static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ - VTable *pRet = 0; - VTable *pVTable = p->pVTable; - p->pVTable = 0; - - /* Assert that the mutex (if any) associated with the BtShared database - ** that contains table p is held by the caller. See header comments - ** above function sqlite3VtabUnlockList() for an explanation of why - ** this makes it safe to access the sqlite3.pDisconnect list of any - ** database connection that may have an entry in the p->pVTable list. - */ - assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); - - while( pVTable ){ - sqlite3 *db2 = pVTable->db; - VTable *pNext = pVTable->pNext; - assert( db2 ); - if( db2==db ){ - pRet = pVTable; - p->pVTable = pRet; - pRet->pNext = 0; - }else{ - pVTable->pNext = db2->pDisconnect; - db2->pDisconnect = pVTable; - } - pVTable = pNext; - } - - assert( !db || pRet ); - return pRet; -} - -/* -** Table *p is a virtual table. This function removes the VTable object -** for table *p associated with database connection db from the linked -** list in p->pVTab. It also decrements the VTable ref count. This is -** used when closing database connection db to free all of its VTable -** objects without disturbing the rest of the Schema object (which may -** be being used by other shared-cache connections). -*/ -SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ - VTable **ppVTab; - - assert( IsVirtual(p) ); - assert( sqlite3BtreeHoldsAllMutexes(db) ); - assert( sqlite3_mutex_held(db->mutex) ); - - for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ - if( (*ppVTab)->db==db ){ - VTable *pVTab = *ppVTab; - *ppVTab = pVTab->pNext; - sqlite3VtabUnlock(pVTab); - break; - } - } -} - - -/* -** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. -** -** This function may only be called when the mutexes associated with all -** shared b-tree databases opened using connection db are held by the -** caller. This is done to protect the sqlite3.pDisconnect list. The -** sqlite3.pDisconnect list is accessed only as follows: -** -** 1) By this function. In this case, all BtShared mutexes and the mutex -** associated with the database handle itself must be held. -** -** 2) By function vtabDisconnectAll(), when it adds a VTable entry to -** the sqlite3.pDisconnect list. In this case either the BtShared mutex -** associated with the database the virtual table is stored in is held -** or, if the virtual table is stored in a non-sharable database, then -** the database handle mutex is held. -** -** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously -** by multiple threads. It is thread-safe. -*/ -SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ - VTable *p = db->pDisconnect; - db->pDisconnect = 0; - - assert( sqlite3BtreeHoldsAllMutexes(db) ); - assert( sqlite3_mutex_held(db->mutex) ); - - if( p ){ - sqlite3ExpirePreparedStatements(db); - do { - VTable *pNext = p->pNext; - sqlite3VtabUnlock(p); - p = pNext; - }while( p ); - } -} - -/* -** Clear any and all virtual-table information from the Table record. -** This routine is called, for example, just before deleting the Table -** record. -** -** Since it is a virtual-table, the Table structure contains a pointer -** to the head of a linked list of VTable structures. Each VTable -** structure is associated with a single sqlite3* user of the schema. -** The reference count of the VTable structure associated with database -** connection db is decremented immediately (which may lead to the -** structure being xDisconnected and free). Any other VTable structures -** in the list are moved to the sqlite3.pDisconnect list of the associated -** database connection. -*/ -SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ - if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); - if( p->azModuleArg ){ - int i; - for(i=0; inModuleArg; i++){ - if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); - } - sqlite3DbFree(db, p->azModuleArg); - } -} - -/* -** Add a new module argument to pTable->azModuleArg[]. -** The string is not copied - the pointer is stored. The -** string will be freed automatically when the table is -** deleted. -*/ -static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){ - int nBytes = sizeof(char *)*(2+pTable->nModuleArg); - char **azModuleArg; - azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); - if( azModuleArg==0 ){ - sqlite3DbFree(db, zArg); - }else{ - int i = pTable->nModuleArg++; - azModuleArg[i] = zArg; - azModuleArg[i+1] = 0; - pTable->azModuleArg = azModuleArg; - } -} - -/* -** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE -** statement. The module name has been parsed, but the optional list -** of parameters that follow the module name are still pending. -*/ -SQLITE_PRIVATE void sqlite3VtabBeginParse( - Parse *pParse, /* Parsing context */ - Token *pName1, /* Name of new table, or database name */ - Token *pName2, /* Name of new table or NULL */ - Token *pModuleName, /* Name of the module for the virtual table */ - int ifNotExists /* No error if the table already exists */ -){ - int iDb; /* The database the table is being created in */ - Table *pTable; /* The new virtual table */ - sqlite3 *db; /* Database connection */ - - sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); - pTable = pParse->pNewTable; - if( pTable==0 ) return; - assert( 0==pTable->pIndex ); - - db = pParse->db; - iDb = sqlite3SchemaToIndex(db, pTable->pSchema); - assert( iDb>=0 ); - - pTable->tabFlags |= TF_Virtual; - pTable->nModuleArg = 0; - addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); - addModuleArgument(db, pTable, 0); - addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); - assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) - || (pParse->sNameToken.z==pName1->z && pName2->z==0) - ); - pParse->sNameToken.n = (int)( - &pModuleName->z[pModuleName->n] - pParse->sNameToken.z - ); - -#ifndef SQLITE_OMIT_AUTHORIZATION - /* Creating a virtual table invokes the authorization callback twice. - ** The first invocation, to obtain permission to INSERT a row into the - ** sqlite_master table, has already been made by sqlite3StartTable(). - ** The second call, to obtain permission to create the table, is made now. - */ - if( pTable->azModuleArg ){ - sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, - pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); - } -#endif -} - -/* -** This routine takes the module argument that has been accumulating -** in pParse->zArg[] and appends it to the list of arguments on the -** virtual table currently under construction in pParse->pTable. -*/ -static void addArgumentToVtab(Parse *pParse){ - if( pParse->sArg.z && pParse->pNewTable ){ - const char *z = (const char*)pParse->sArg.z; - int n = pParse->sArg.n; - sqlite3 *db = pParse->db; - addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); - } -} - -/* -** The parser calls this routine after the CREATE VIRTUAL TABLE statement -** has been completely parsed. -*/ -SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ - Table *pTab = pParse->pNewTable; /* The table being constructed */ - sqlite3 *db = pParse->db; /* The database connection */ - - if( pTab==0 ) return; - addArgumentToVtab(pParse); - pParse->sArg.z = 0; - if( pTab->nModuleArg<1 ) return; - - /* If the CREATE VIRTUAL TABLE statement is being entered for the - ** first time (in other words if the virtual table is actually being - ** created now instead of just being read out of sqlite_master) then - ** do additional initialization work and store the statement text - ** in the sqlite_master table. - */ - if( !db->init.busy ){ - char *zStmt; - char *zWhere; - int iDb; - int iReg; - Vdbe *v; - - /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ - if( pEnd ){ - pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; - } - zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); - - /* A slot for the record has already been allocated in the - ** SQLITE_MASTER table. We just need to update that slot with all - ** the information we've collected. - ** - ** The VM register number pParse->regRowid holds the rowid of an - ** entry in the sqlite_master table tht was created for this vtab - ** by sqlite3StartTable(). - */ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - sqlite3NestedParse(pParse, - "UPDATE %Q.%s " - "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " - "WHERE rowid=#%d", - db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), - pTab->zName, - pTab->zName, - zStmt, - pParse->regRowid - ); - sqlite3DbFree(db, zStmt); - v = sqlite3GetVdbe(pParse); - sqlite3ChangeCookie(pParse, iDb); - - sqlite3VdbeAddOp0(v, OP_Expire); - zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName); - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); - - iReg = ++pParse->nMem; - sqlite3VdbeLoadString(v, iReg, pTab->zName); - sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); - } - - /* If we are rereading the sqlite_master table create the in-memory - ** record of the table. The xConnect() method is not called until - ** the first time the virtual table is used in an SQL statement. This - ** allows a schema that contains virtual tables to be loaded before - ** the required virtual table implementations are registered. */ - else { - Table *pOld; - Schema *pSchema = pTab->pSchema; - const char *zName = pTab->zName; - assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); - pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); - if( pOld ){ - sqlite3OomFault(db); - assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ - return; - } - pParse->pNewTable = 0; - } -} - -/* -** The parser calls this routine when it sees the first token -** of an argument to the module name in a CREATE VIRTUAL TABLE statement. -*/ -SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){ - addArgumentToVtab(pParse); - pParse->sArg.z = 0; - pParse->sArg.n = 0; -} - -/* -** The parser calls this routine for each token after the first token -** in an argument to the module name in a CREATE VIRTUAL TABLE statement. -*/ -SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ - Token *pArg = &pParse->sArg; - if( pArg->z==0 ){ - pArg->z = p->z; - pArg->n = p->n; - }else{ - assert(pArg->z <= p->z); - pArg->n = (int)(&p->z[p->n] - pArg->z); - } -} - -/* -** Invoke a virtual table constructor (either xCreate or xConnect). The -** pointer to the function to invoke is passed as the fourth parameter -** to this procedure. -*/ -static int vtabCallConstructor( - sqlite3 *db, - Table *pTab, - Module *pMod, - int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), - char **pzErr -){ - VtabCtx sCtx; - VTable *pVTable; - int rc; - const char *const*azArg = (const char *const*)pTab->azModuleArg; - int nArg = pTab->nModuleArg; - char *zErr = 0; - char *zModuleName; - int iDb; - VtabCtx *pCtx; - - /* Check that the virtual-table is not already being initialized */ - for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ - if( pCtx->pTab==pTab ){ - *pzErr = sqlite3MPrintf(db, - "vtable constructor called recursively: %s", pTab->zName - ); - return SQLITE_LOCKED; - } - } - - zModuleName = sqlite3MPrintf(db, "%s", pTab->zName); - if( !zModuleName ){ - return SQLITE_NOMEM_BKPT; - } - - pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); - if( !pVTable ){ - sqlite3DbFree(db, zModuleName); - return SQLITE_NOMEM_BKPT; - } - pVTable->db = db; - pVTable->pMod = pMod; - - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; - - /* Invoke the virtual table constructor */ - assert( &db->pVtabCtx ); - assert( xConstruct ); - sCtx.pTab = pTab; - sCtx.pVTable = pVTable; - sCtx.pPrior = db->pVtabCtx; - sCtx.bDeclared = 0; - db->pVtabCtx = &sCtx; - rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); - db->pVtabCtx = sCtx.pPrior; - if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); - assert( sCtx.pTab==pTab ); - - if( SQLITE_OK!=rc ){ - if( zErr==0 ){ - *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); - }else { - *pzErr = sqlite3MPrintf(db, "%s", zErr); - sqlite3_free(zErr); - } - sqlite3DbFree(db, pVTable); - }else if( ALWAYS(pVTable->pVtab) ){ - /* Justification of ALWAYS(): A correct vtab constructor must allocate - ** the sqlite3_vtab object if successful. */ - memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); - pVTable->pVtab->pModule = pMod->pModule; - pVTable->nRef = 1; - if( sCtx.bDeclared==0 ){ - const char *zFormat = "vtable constructor did not declare schema: %s"; - *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); - sqlite3VtabUnlock(pVTable); - rc = SQLITE_ERROR; - }else{ - int iCol; - u8 oooHidden = 0; - /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->pVTable. Then loop through the - ** columns of the table to see if any of them contain the token "hidden". - ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from - ** the type string. */ - pVTable->pNext = pTab->pVTable; - pTab->pVTable = pVTable; - - for(iCol=0; iColnCol; iCol++){ - char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); - int nType; - int i = 0; - nType = sqlite3Strlen30(zType); - for(i=0; i0 ){ - assert(zType[i-1]==' '); - zType[i-1] = '\0'; - } - pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; - oooHidden = TF_OOOHidden; - }else{ - pTab->tabFlags |= oooHidden; - } - } - } - } - - sqlite3DbFree(db, zModuleName); - return rc; -} - -/* -** This function is invoked by the parser to call the xConnect() method -** of the virtual table pTab. If an error occurs, an error code is returned -** and an error left in pParse. -** -** This call is a no-op if table pTab is not a virtual table. -*/ -SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ - sqlite3 *db = pParse->db; - const char *zMod; - Module *pMod; - int rc; - - assert( pTab ); - if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){ - return SQLITE_OK; - } - - /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; - pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); - - if( !pMod ){ - const char *zModule = pTab->azModuleArg[0]; - sqlite3ErrorMsg(pParse, "no such module: %s", zModule); - rc = SQLITE_ERROR; - }else{ - char *zErr = 0; - rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); - if( rc!=SQLITE_OK ){ - sqlite3ErrorMsg(pParse, "%s", zErr); - } - sqlite3DbFree(db, zErr); - } - - return rc; -} -/* -** Grow the db->aVTrans[] array so that there is room for at least one -** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. -*/ -static int growVTrans(sqlite3 *db){ - const int ARRAY_INCR = 5; - - /* Grow the sqlite3.aVTrans array if required */ - if( (db->nVTrans%ARRAY_INCR)==0 ){ - VTable **aVTrans; - int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); - aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); - if( !aVTrans ){ - return SQLITE_NOMEM_BKPT; - } - memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); - db->aVTrans = aVTrans; - } - - return SQLITE_OK; -} - -/* -** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should -** have already been reserved using growVTrans(). -*/ -static void addToVTrans(sqlite3 *db, VTable *pVTab){ - /* Add pVtab to the end of sqlite3.aVTrans */ - db->aVTrans[db->nVTrans++] = pVTab; - sqlite3VtabLock(pVTab); -} - -/* -** This function is invoked by the vdbe to call the xCreate method -** of the virtual table named zTab in database iDb. -** -** If an error occurs, *pzErr is set to point to an English language -** description of the error and an SQLITE_XXX error code is returned. -** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. -*/ -SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ - int rc = SQLITE_OK; - Table *pTab; - Module *pMod; - const char *zMod; - - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); - - /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; - pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); - - /* If the module has been registered and includes a Create method, - ** invoke it now. If the module has not been registered, return an - ** error. Otherwise, do nothing. - */ - if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ - *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); - rc = SQLITE_ERROR; - }else{ - rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); - } - - /* Justification of ALWAYS(): The xConstructor method is required to - ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ - if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ - rc = growVTrans(db); - if( rc==SQLITE_OK ){ - addToVTrans(db, sqlite3GetVTable(db, pTab)); - } - } - - return rc; -} - -/* -** This function is used to set the schema of a virtual table. It is only -** valid to call this function from within the xCreate() or xConnect() of a -** virtual table module. -*/ -SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ - VtabCtx *pCtx; - Parse *pParse; - int rc = SQLITE_OK; - Table *pTab; - char *zErr = 0; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - pCtx = db->pVtabCtx; - if( !pCtx || pCtx->bDeclared ){ - sqlite3Error(db, SQLITE_MISUSE); - sqlite3_mutex_leave(db->mutex); - return SQLITE_MISUSE_BKPT; - } - pTab = pCtx->pTab; - assert( (pTab->tabFlags & TF_Virtual)!=0 ); - - pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); - if( pParse==0 ){ - rc = SQLITE_NOMEM_BKPT; - }else{ - pParse->declareVtab = 1; - pParse->db = db; - pParse->nQueryLoop = 1; - - if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr) - && pParse->pNewTable - && !db->mallocFailed - && !pParse->pNewTable->pSelect - && (pParse->pNewTable->tabFlags & TF_Virtual)==0 - ){ - if( !pTab->aCol ){ - Table *pNew = pParse->pNewTable; - Index *pIdx; - pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; - pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); - pNew->nCol = 0; - pNew->aCol = 0; - assert( pTab->pIndex==0 ); - if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){ - rc = SQLITE_ERROR; - } - pIdx = pNew->pIndex; - if( pIdx ){ - assert( pIdx->pNext==0 ); - pTab->pIndex = pIdx; - pNew->pIndex = 0; - pIdx->pTable = pTab; - } - } - pCtx->bDeclared = 1; - }else{ - sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); - rc = SQLITE_ERROR; - } - pParse->declareVtab = 0; - - if( pParse->pVdbe ){ - sqlite3VdbeFinalize(pParse->pVdbe); - } - sqlite3DeleteTable(db, pParse->pNewTable); - sqlite3ParserReset(pParse); - sqlite3StackFree(db, pParse); - } - - assert( (rc&0xff)==rc ); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** This function is invoked by the vdbe to call the xDestroy method -** of the virtual table named zTab in database iDb. This occurs -** when a DROP TABLE is mentioned. -** -** This call is a no-op if zTab is not a virtual table. -*/ -SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ - int rc = SQLITE_OK; - Table *pTab; - - pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ - VTable *p; - int (*xDestroy)(sqlite3_vtab *); - for(p=pTab->pVTable; p; p=p->pNext){ - assert( p->pVtab ); - if( p->pVtab->nRef>0 ){ - return SQLITE_LOCKED; - } - } - p = vtabDisconnectAll(db, pTab); - xDestroy = p->pMod->pModule->xDestroy; - assert( xDestroy!=0 ); /* Checked before the virtual table is created */ - rc = xDestroy(p->pVtab); - /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ - if( rc==SQLITE_OK ){ - assert( pTab->pVTable==p && p->pNext==0 ); - p->pVtab = 0; - pTab->pVTable = 0; - sqlite3VtabUnlock(p); - } - } - - return rc; -} - -/* -** This function invokes either the xRollback or xCommit method -** of each of the virtual tables in the sqlite3.aVTrans array. The method -** called is identified by the second argument, "offset", which is -** the offset of the method to call in the sqlite3_module structure. -** -** The array is cleared after invoking the callbacks. -*/ -static void callFinaliser(sqlite3 *db, int offset){ - int i; - if( db->aVTrans ){ - VTable **aVTrans = db->aVTrans; - db->aVTrans = 0; - for(i=0; inVTrans; i++){ - VTable *pVTab = aVTrans[i]; - sqlite3_vtab *p = pVTab->pVtab; - if( p ){ - int (*x)(sqlite3_vtab *); - x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); - if( x ) x(p); - } - pVTab->iSavepoint = 0; - sqlite3VtabUnlock(pVTab); - } - sqlite3DbFree(db, aVTrans); - db->nVTrans = 0; - } -} - -/* -** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans -** array. Return the error code for the first error that occurs, or -** SQLITE_OK if all xSync operations are successful. -** -** If an error message is available, leave it in p->zErrMsg. -*/ -SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ - int i; - int rc = SQLITE_OK; - VTable **aVTrans = db->aVTrans; - - db->aVTrans = 0; - for(i=0; rc==SQLITE_OK && inVTrans; i++){ - int (*x)(sqlite3_vtab *); - sqlite3_vtab *pVtab = aVTrans[i]->pVtab; - if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ - rc = x(pVtab); - sqlite3VtabImportErrmsg(p, pVtab); - } - } - db->aVTrans = aVTrans; - return rc; -} - -/* -** Invoke the xRollback method of all virtual tables in the -** sqlite3.aVTrans array. Then clear the array itself. -*/ -SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ - callFinaliser(db, offsetof(sqlite3_module,xRollback)); - return SQLITE_OK; -} - -/* -** Invoke the xCommit method of all virtual tables in the -** sqlite3.aVTrans array. Then clear the array itself. -*/ -SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ - callFinaliser(db, offsetof(sqlite3_module,xCommit)); - return SQLITE_OK; -} - -/* -** If the virtual table pVtab supports the transaction interface -** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is -** not currently open, invoke the xBegin method now. -** -** If the xBegin call is successful, place the sqlite3_vtab pointer -** in the sqlite3.aVTrans array. -*/ -SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ - int rc = SQLITE_OK; - const sqlite3_module *pModule; - - /* Special case: If db->aVTrans is NULL and db->nVTrans is greater - ** than zero, then this function is being called from within a - ** virtual module xSync() callback. It is illegal to write to - ** virtual module tables in this case, so return SQLITE_LOCKED. - */ - if( sqlite3VtabInSync(db) ){ - return SQLITE_LOCKED; - } - if( !pVTab ){ - return SQLITE_OK; - } - pModule = pVTab->pVtab->pModule; - - if( pModule->xBegin ){ - int i; - - /* If pVtab is already in the aVTrans array, return early */ - for(i=0; inVTrans; i++){ - if( db->aVTrans[i]==pVTab ){ - return SQLITE_OK; - } - } - - /* Invoke the xBegin method. If successful, add the vtab to the - ** sqlite3.aVTrans[] array. */ - rc = growVTrans(db); - if( rc==SQLITE_OK ){ - rc = pModule->xBegin(pVTab->pVtab); - if( rc==SQLITE_OK ){ - int iSvpt = db->nStatement + db->nSavepoint; - addToVTrans(db, pVTab); - if( iSvpt && pModule->xSavepoint ){ - pVTab->iSavepoint = iSvpt; - rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1); - } - } - } - } - return rc; -} - -/* -** Invoke either the xSavepoint, xRollbackTo or xRelease method of all -** virtual tables that currently have an open transaction. Pass iSavepoint -** as the second argument to the virtual table method invoked. -** -** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is -** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is -** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with -** an open transaction is invoked. -** -** If any virtual table method returns an error code other than SQLITE_OK, -** processing is abandoned and the error returned to the caller of this -** function immediately. If all calls to virtual table methods are successful, -** SQLITE_OK is returned. -*/ -SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ - int rc = SQLITE_OK; - - assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); - assert( iSavepoint>=-1 ); - if( db->aVTrans ){ - int i; - for(i=0; rc==SQLITE_OK && inVTrans; i++){ - VTable *pVTab = db->aVTrans[i]; - const sqlite3_module *pMod = pVTab->pMod->pModule; - if( pVTab->pVtab && pMod->iVersion>=2 ){ - int (*xMethod)(sqlite3_vtab *, int); - switch( op ){ - case SAVEPOINT_BEGIN: - xMethod = pMod->xSavepoint; - pVTab->iSavepoint = iSavepoint+1; - break; - case SAVEPOINT_ROLLBACK: - xMethod = pMod->xRollbackTo; - break; - default: - xMethod = pMod->xRelease; - break; - } - if( xMethod && pVTab->iSavepoint>iSavepoint ){ - rc = xMethod(pVTab->pVtab, iSavepoint); - } - } - } - } - return rc; -} - -/* -** The first parameter (pDef) is a function implementation. The -** second parameter (pExpr) is the first argument to this function. -** If pExpr is a column in a virtual table, then let the virtual -** table implementation have an opportunity to overload the function. -** -** This routine is used to allow virtual table implementations to -** overload MATCH, LIKE, GLOB, and REGEXP operators. -** -** Return either the pDef argument (indicating no change) or a -** new FuncDef structure that is marked as ephemeral using the -** SQLITE_FUNC_EPHEM flag. -*/ -SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( - sqlite3 *db, /* Database connection for reporting malloc problems */ - FuncDef *pDef, /* Function to possibly overload */ - int nArg, /* Number of arguments to the function */ - Expr *pExpr /* First argument to the function */ -){ - Table *pTab; - sqlite3_vtab *pVtab; - sqlite3_module *pMod; - void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0; - void *pArg = 0; - FuncDef *pNew; - int rc = 0; - char *zLowerName; - unsigned char *z; - - - /* Check to see the left operand is a column in a virtual table */ - if( NEVER(pExpr==0) ) return pDef; - if( pExpr->op!=TK_COLUMN ) return pDef; - pTab = pExpr->pTab; - if( NEVER(pTab==0) ) return pDef; - if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; - pVtab = sqlite3GetVTable(db, pTab)->pVtab; - assert( pVtab!=0 ); - assert( pVtab->pModule!=0 ); - pMod = (sqlite3_module *)pVtab->pModule; - if( pMod->xFindFunction==0 ) return pDef; - - /* Call the xFindFunction method on the virtual table implementation - ** to see if the implementation wants to overload this function - */ - zLowerName = sqlite3DbStrDup(db, pDef->zName); - if( zLowerName ){ - for(z=(unsigned char*)zLowerName; *z; z++){ - *z = sqlite3UpperToLower[*z]; - } - rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xSFunc, &pArg); - sqlite3DbFree(db, zLowerName); - } - if( rc==0 ){ - return pDef; - } - - /* Create a new ephemeral function definition for the overloaded - ** function */ - pNew = sqlite3DbMallocZero(db, sizeof(*pNew) - + sqlite3Strlen30(pDef->zName) + 1); - if( pNew==0 ){ - return pDef; - } - *pNew = *pDef; - pNew->zName = (const char*)&pNew[1]; - memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1); - pNew->xSFunc = xSFunc; - pNew->pUserData = pArg; - pNew->funcFlags |= SQLITE_FUNC_EPHEM; - return pNew; -} - -/* -** Make sure virtual table pTab is contained in the pParse->apVirtualLock[] -** array so that an OP_VBegin will get generated for it. Add pTab to the -** array if it is missing. If pTab is already in the array, this routine -** is a no-op. -*/ -SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - int i, n; - Table **apVtabLock; - - assert( IsVirtual(pTab) ); - for(i=0; inVtabLock; i++){ - if( pTab==pToplevel->apVtabLock[i] ) return; - } - n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); - apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); - if( apVtabLock ){ - pToplevel->apVtabLock = apVtabLock; - pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; - }else{ - sqlite3OomFault(pToplevel->db); - } -} - -/* -** Check to see if virtual table module pMod can be have an eponymous -** virtual table instance. If it can, create one if one does not already -** exist. Return non-zero if the eponymous virtual table instance exists -** when this routine returns, and return zero if it does not exist. -** -** An eponymous virtual table instance is one that is named after its -** module, and more importantly, does not require a CREATE VIRTUAL TABLE -** statement in order to come into existance. Eponymous virtual table -** instances always exist. They cannot be DROP-ed. -** -** Any virtual table module for which xConnect and xCreate are the same -** method can have an eponymous virtual table instance. -*/ -SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ - const sqlite3_module *pModule = pMod->pModule; - Table *pTab; - char *zErr = 0; - int rc; - sqlite3 *db = pParse->db; - if( pMod->pEpoTab ) return 1; - if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; - pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return 0; - pTab->zName = sqlite3DbStrDup(db, pMod->zName); - if( pTab->zName==0 ){ - sqlite3DbFree(db, pTab); - return 0; - } - pMod->pEpoTab = pTab; - pTab->nRef = 1; - pTab->pSchema = db->aDb[0].pSchema; - pTab->tabFlags |= TF_Virtual; - pTab->nModuleArg = 0; - pTab->iPKey = -1; - addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); - addModuleArgument(db, pTab, 0); - addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName)); - rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); - if( rc ){ - sqlite3ErrorMsg(pParse, "%s", zErr); - sqlite3DbFree(db, zErr); - sqlite3VtabEponymousTableClear(db, pMod); - return 0; - } - return 1; -} - -/* -** Erase the eponymous virtual table instance associated with -** virtual table module pMod, if it exists. -*/ -SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ - Table *pTab = pMod->pEpoTab; - if( pTab!=0 ){ - /* Mark the table as Ephemeral prior to deleting it, so that the - ** sqlite3DeleteTable() routine will know that it is not stored in - ** the schema. */ - pTab->tabFlags |= TF_Ephemeral; - sqlite3DeleteTable(db, pTab); - pMod->pEpoTab = 0; - } -} - -/* -** Return the ON CONFLICT resolution mode in effect for the virtual -** table update operation currently in progress. -** -** The results of this routine are undefined unless it is called from -** within an xUpdate method. -*/ -SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ - static const unsigned char aMap[] = { - SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE - }; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); - assert( OE_Ignore==4 && OE_Replace==5 ); - assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); - return (int)aMap[db->vtabOnConflict-1]; -} - -/* -** Call from within the xCreate() or xConnect() methods to provide -** the SQLite core with additional information about the behavior -** of the virtual table being implemented. -*/ -SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ - va_list ap; - int rc = SQLITE_OK; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - va_start(ap, op); - switch( op ){ - case SQLITE_VTAB_CONSTRAINT_SUPPORT: { - VtabCtx *p = db->pVtabCtx; - if( !p ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 ); - p->pVTable->bConstraint = (u8)va_arg(ap, int); - } - break; - } - default: - rc = SQLITE_MISUSE_BKPT; - break; - } - va_end(ap); - - if( rc!=SQLITE_OK ) sqlite3Error(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/************** End of vtab.c ************************************************/ -/************** Begin file wherecode.c ***************************************/ -/* -** 2015-06-06 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This module contains C code that generates VDBE code used to process -** the WHERE clause of SQL statements. -** -** This file was split off from where.c on 2015-06-06 in order to reduce the -** size of where.c and make it easier to edit. This file contains the routines -** that actually generate the bulk of the WHERE loop code. The original where.c -** file retains the code that does query planning and analysis. -*/ -/* #include "sqliteInt.h" */ -/************** Include whereInt.h in the middle of wherecode.c **************/ -/************** Begin file whereInt.h ****************************************/ -/* -** 2013-11-12 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains structure and macro definitions for the query -** planner logic in "where.c". These definitions are broken out into -** a separate source file for easier editing. -*/ - -/* -** Trace output macros -*/ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int sqlite3WhereTrace; -#endif -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X -# define WHERETRACE_ENABLED 1 -#else -# define WHERETRACE(K,X) -#endif - -/* Forward references -*/ -typedef struct WhereClause WhereClause; -typedef struct WhereMaskSet WhereMaskSet; -typedef struct WhereOrInfo WhereOrInfo; -typedef struct WhereAndInfo WhereAndInfo; -typedef struct WhereLevel WhereLevel; -typedef struct WhereLoop WhereLoop; -typedef struct WherePath WherePath; -typedef struct WhereTerm WhereTerm; -typedef struct WhereLoopBuilder WhereLoopBuilder; -typedef struct WhereScan WhereScan; -typedef struct WhereOrCost WhereOrCost; -typedef struct WhereOrSet WhereOrSet; - -/* -** This object contains information needed to implement a single nested -** loop in WHERE clause. -** -** Contrast this object with WhereLoop. This object describes the -** implementation of the loop. WhereLoop describes the algorithm. -** This object contains a pointer to the WhereLoop algorithm as one of -** its elements. -** -** The WhereInfo object contains a single instance of this object for -** each term in the FROM clause (which is to say, for each of the -** nested loops as implemented). The order of WhereLevel objects determines -** the loop nested order, with WhereInfo.a[0] being the outer loop and -** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop. -*/ -struct WhereLevel { - int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ - int iTabCur; /* The VDBE cursor used to access the table */ - int iIdxCur; /* The VDBE cursor used to access pIdx */ - int addrBrk; /* Jump here to break out of the loop */ - int addrNxt; /* Jump here to start the next IN combination */ - int addrSkip; /* Jump here for next iteration of skip-scan */ - int addrCont; /* Jump here to continue with the next loop cycle */ - int addrFirst; /* First instruction of interior of the loop */ - int addrBody; /* Beginning of the body of this loop */ -#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ - int addrLikeRep; /* LIKE range processing address */ -#endif - u8 iFrom; /* Which entry in the FROM clause */ - u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ - int p1, p2; /* Operands of the opcode used to ends the loop */ - union { /* Information that depends on pWLoop->wsFlags */ - struct { - int nIn; /* Number of entries in aInLoop[] */ - struct InLoop { - int iCur; /* The VDBE cursor used by this IN operator */ - int addrInTop; /* Top of the IN loop */ - u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ - } *aInLoop; /* Information about each nested IN operator */ - } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ - Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ - } u; - struct WhereLoop *pWLoop; /* The selected WhereLoop object */ - Bitmask notReady; /* FROM entries not usable at this level */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrVisit; /* Address at which row is visited */ -#endif -}; - -/* -** Each instance of this object represents an algorithm for evaluating one -** term of a join. Every term of the FROM clause will have at least -** one corresponding WhereLoop object (unless INDEXED BY constraints -** prevent a query solution - which is an error) and many terms of the -** FROM clause will have multiple WhereLoop objects, each describing a -** potential way of implementing that FROM-clause term, together with -** dependencies and cost estimates for using the chosen algorithm. -** -** Query planning consists of building up a collection of these WhereLoop -** objects, then computing a particular sequence of WhereLoop objects, with -** one WhereLoop object per FROM clause term, that satisfy all dependencies -** and that minimize the overall cost. -*/ -struct WhereLoop { - Bitmask prereq; /* Bitmask of other loops that must run first */ - Bitmask maskSelf; /* Bitmask identifying table iTab */ -#ifdef SQLITE_DEBUG - char cId; /* Symbolic ID of this loop for debugging use */ -#endif - u8 iTab; /* Position in FROM clause of table for this loop */ - u8 iSortIdx; /* Sorting index number. 0==None */ - LogEst rSetup; /* One-time setup cost (ex: create transient index) */ - LogEst rRun; /* Cost of running each loop */ - LogEst nOut; /* Estimated number of output rows */ - union { - struct { /* Information for internal btree tables */ - u16 nEq; /* Number of equality constraints */ - u16 nBtm; /* Size of BTM vector */ - u16 nTop; /* Size of TOP vector */ - Index *pIndex; /* Index used, or NULL */ - } btree; - struct { /* Information for virtual tables */ - int idxNum; /* Index number */ - u8 needFree; /* True if sqlite3_free(idxStr) is needed */ - i8 isOrdered; /* True if satisfies ORDER BY */ - u16 omitMask; /* Terms that may be omitted */ - char *idxStr; /* Index identifier string */ - } vtab; - } u; - u32 wsFlags; /* WHERE_* flags describing the plan */ - u16 nLTerm; /* Number of entries in aLTerm[] */ - u16 nSkip; /* Number of NULL aLTerm[] entries */ - /**** whereLoopXfer() copies fields above ***********************/ -# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) - u16 nLSlot; /* Number of slots allocated for aLTerm[] */ - WhereTerm **aLTerm; /* WhereTerms used */ - WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ - WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ -}; - -/* This object holds the prerequisites and the cost of running a -** subquery on one operand of an OR operator in the WHERE clause. -** See WhereOrSet for additional information -*/ -struct WhereOrCost { - Bitmask prereq; /* Prerequisites */ - LogEst rRun; /* Cost of running this subquery */ - LogEst nOut; /* Number of outputs for this subquery */ -}; - -/* The WhereOrSet object holds a set of possible WhereOrCosts that -** correspond to the subquery(s) of OR-clause processing. Only the -** best N_OR_COST elements are retained. -*/ -#define N_OR_COST 3 -struct WhereOrSet { - u16 n; /* Number of valid a[] entries */ - WhereOrCost a[N_OR_COST]; /* Set of best costs */ -}; - -/* -** Each instance of this object holds a sequence of WhereLoop objects -** that implement some or all of a query plan. -** -** Think of each WhereLoop object as a node in a graph with arcs -** showing dependencies and costs for travelling between nodes. (That is -** not a completely accurate description because WhereLoop costs are a -** vector, not a scalar, and because dependencies are many-to-one, not -** one-to-one as are graph nodes. But it is a useful visualization aid.) -** Then a WherePath object is a path through the graph that visits some -** or all of the WhereLoop objects once. -** -** The "solver" works by creating the N best WherePath objects of length -** 1. Then using those as a basis to compute the N best WherePath objects -** of length 2. And so forth until the length of WherePaths equals the -** number of nodes in the FROM clause. The best (lowest cost) WherePath -** at the end is the chosen query plan. -*/ -struct WherePath { - Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ - Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ - LogEst nRow; /* Estimated number of rows generated by this path */ - LogEst rCost; /* Total cost of this path */ - LogEst rUnsorted; /* Total cost of this path ignoring sorting costs */ - i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ - WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ -}; - -/* -** The query generator uses an array of instances of this structure to -** help it analyze the subexpressions of the WHERE clause. Each WHERE -** clause subexpression is separated from the others by AND operators, -** usually, or sometimes subexpressions separated by OR. -** -** All WhereTerms are collected into a single WhereClause structure. -** The following identity holds: -** -** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm -** -** When a term is of the form: -** -** X -** -** where X is a column name and is one of certain operators, -** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the -** cursor number and column number for X. WhereTerm.eOperator records -** the using a bitmask encoding defined by WO_xxx below. The -** use of a bitmask encoding for the operator allows us to search -** quickly for terms that match any of several different operators. -** -** A WhereTerm might also be two or more subterms connected by OR: -** -** (t1.X ) OR (t1.Y ) OR .... -** -** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR -** and the WhereTerm.u.pOrInfo field points to auxiliary information that -** is collected about the OR clause. -** -** If a term in the WHERE clause does not match either of the two previous -** categories, then eOperator==0. The WhereTerm.pExpr field is still set -** to the original subexpression content and wtFlags is set up appropriately -** but no other fields in the WhereTerm object are meaningful. -** -** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers, -** but they do so indirectly. A single WhereMaskSet structure translates -** cursor number into bits and the translated bit is stored in the prereq -** fields. The translation is used in order to maximize the number of -** bits that will fit in a Bitmask. The VDBE cursor numbers might be -** spread out over the non-negative integers. For example, the cursor -** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet -** translates these sparse cursor numbers into consecutive integers -** beginning with 0 in order to make the best possible use of the available -** bits in the Bitmask. So, in the example above, the cursor numbers -** would be mapped into integers 0 through 7. -** -** The number of terms in a join is limited by the number of bits -** in prereqRight and prereqAll. The default is 64 bits, hence SQLite -** is only able to process joins with 64 or fewer tables. -*/ -struct WhereTerm { - Expr *pExpr; /* Pointer to the subexpression that is this term */ - WhereClause *pWC; /* The clause this term is part of */ - LogEst truthProb; /* Probability of truth for this expression */ - u16 wtFlags; /* TERM_xxx bit flags. See below */ - u16 eOperator; /* A WO_xx value describing */ - u8 nChild; /* Number of children that must disable us */ - u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ - int iParent; /* Disable pWC->a[iParent] when this term disabled */ - int leftCursor; /* Cursor number of X in "X " */ - int iField; /* Field in (?,?,?) IN (SELECT...) vector */ - union { - int leftColumn; /* Column number of X in "X " */ - WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ - WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ - } u; - Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ - Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ -}; - -/* -** Allowed values of WhereTerm.wtFlags -*/ -#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */ -#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */ -#define TERM_CODED 0x04 /* This term is already coded */ -#define TERM_COPIED 0x08 /* Has a child */ -#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ -#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ -#define TERM_OR_OK 0x40 /* Used during OR-clause processing */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ -#else -# define TERM_VNULL 0x00 /* Disabled if not using stat3 */ -#endif -#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */ -#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */ -#define TERM_LIKE 0x400 /* The original LIKE operator */ -#define TERM_IS 0x800 /* Term.pExpr is an IS operator */ - -/* -** An instance of the WhereScan object is used as an iterator for locating -** terms in the WHERE clause that are useful to the query planner. -*/ -struct WhereScan { - WhereClause *pOrigWC; /* Original, innermost WhereClause */ - WhereClause *pWC; /* WhereClause currently being scanned */ - const char *zCollName; /* Required collating sequence, if not NULL */ - Expr *pIdxExpr; /* Search for this index expression */ - char idxaff; /* Must match this affinity, if zCollName!=NULL */ - unsigned char nEquiv; /* Number of entries in aEquiv[] */ - unsigned char iEquiv; /* Next unused slot in aEquiv[] */ - u32 opMask; /* Acceptable operators */ - int k; /* Resume scanning at this->pWC->a[this->k] */ - int aiCur[11]; /* Cursors in the equivalence class */ - i16 aiColumn[11]; /* Corresponding column number in the eq-class */ -}; - -/* -** An instance of the following structure holds all information about a -** WHERE clause. Mostly this is a container for one or more WhereTerms. -** -** Explanation of pOuter: For a WHERE clause of the form -** -** a AND ((b AND c) OR (d AND e)) AND f -** -** There are separate WhereClause objects for the whole clause and for -** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the -** subclauses points to the WhereClause object for the whole clause. -*/ -struct WhereClause { - WhereInfo *pWInfo; /* WHERE clause processing context */ - WhereClause *pOuter; /* Outer conjunction */ - u8 op; /* Split operator. TK_AND or TK_OR */ - int nTerm; /* Number of terms */ - int nSlot; /* Number of entries in a[] */ - WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ -#if defined(SQLITE_SMALL_STACK) - WhereTerm aStatic[1]; /* Initial static space for a[] */ -#else - WhereTerm aStatic[8]; /* Initial static space for a[] */ -#endif -}; - -/* -** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to -** a dynamically allocated instance of the following structure. -*/ -struct WhereOrInfo { - WhereClause wc; /* Decomposition into subterms */ - Bitmask indexable; /* Bitmask of all indexable tables in the clause */ -}; - -/* -** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to -** a dynamically allocated instance of the following structure. -*/ -struct WhereAndInfo { - WhereClause wc; /* The subexpression broken out */ -}; - -/* -** An instance of the following structure keeps track of a mapping -** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. -** -** The VDBE cursor numbers are small integers contained in -** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE -** clause, the cursor numbers might not begin with 0 and they might -** contain gaps in the numbering sequence. But we want to make maximum -** use of the bits in our bitmasks. This structure provides a mapping -** from the sparse cursor numbers into consecutive integers beginning -** with 0. -** -** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask -** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<3, 5->1, 8->2, 29->0, -** 57->5, 73->4. Or one of 719 other combinations might be used. It -** does not really matter. What is important is that sparse cursor -** numbers all get mapped into bit numbers that begin with 0 and contain -** no gaps. -*/ -struct WhereMaskSet { - int n; /* Number of assigned cursor values */ - int ix[BMS]; /* Cursor assigned to each bit */ -}; - -/* -** Initialize a WhereMaskSet object -*/ -#define initMaskSet(P) (P)->n=0 - -/* -** This object is a convenience wrapper holding all information needed -** to construct WhereLoop objects for a particular query. -*/ -struct WhereLoopBuilder { - WhereInfo *pWInfo; /* Information about this WHERE */ - WhereClause *pWC; /* WHERE clause terms */ - ExprList *pOrderBy; /* ORDER BY clause */ - WhereLoop *pNew; /* Template WhereLoop */ - WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - UnpackedRecord *pRec; /* Probe for stat4 (if required) */ - int nRecValid; /* Number of valid fields currently in pRec */ -#endif -}; - -/* -** The WHERE clause processing routine has two halves. The -** first part does the start of the WHERE loop and the second -** half does the tail of the WHERE loop. An instance of -** this structure is returned by the first half and passed -** into the second half to give some continuity. -** -** An instance of this object holds the complete state of the query -** planner. -*/ -struct WhereInfo { - Parse *pParse; /* Parsing and code generating context */ - SrcList *pTabList; /* List of tables in the join */ - ExprList *pOrderBy; /* The ORDER BY clause or NULL */ - ExprList *pDistinctSet; /* DISTINCT over all these values */ - LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ - int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ - int iContinue; /* Jump here to continue with next record */ - int iBreak; /* Jump here to break out of the loop */ - int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ - u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ - u8 nLevel; /* Number of nested loop */ - i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ - u8 sorted; /* True if really sorted (not just grouped) */ - u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ - u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ - u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ - u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */ - int iTop; /* The very beginning of the WHERE loop */ - WhereLoop *pLoops; /* List of all WhereLoop objects */ - Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ - LogEst nRowOut; /* Estimated number of output rows */ - WhereClause sWC; /* Decomposition of the WHERE clause */ - WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ - WhereLevel a[1]; /* Information about each nest loop in WHERE */ -}; - -/* -** Private interfaces - callable only by other where.c routines. -** -** where.c: -*/ -SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); -#ifdef WHERETRACE_ENABLED -SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); -#endif -SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( - WhereClause *pWC, /* The WHERE clause to be searched */ - int iCur, /* Cursor number of LHS */ - int iColumn, /* Column number of LHS */ - Bitmask notReady, /* RHS must not overlap with this mask */ - u32 op, /* Mask of WO_xx values describing operator */ - Index *pIdx /* Must be compatible with this index, if not NULL */ -); - -/* wherecode.c: */ -#ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE int sqlite3WhereExplainOneScan( - Parse *pParse, /* Parse context */ - SrcList *pTabList, /* Table list this loop refers to */ - WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - int iLevel, /* Value for "level" column of output */ - int iFrom, /* Value for "from" column of output */ - u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ -); -#else -# define sqlite3WhereExplainOneScan(u,v,w,x,y,z) 0 -#endif /* SQLITE_OMIT_EXPLAIN */ -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -SQLITE_PRIVATE void sqlite3WhereAddScanStatus( - Vdbe *v, /* Vdbe to add scanstatus entry to */ - SrcList *pSrclist, /* FROM clause pLvl reads data from */ - WhereLevel *pLvl, /* Level to add scanstatus() entry for */ - int addrExplain /* Address of OP_Explain (or 0) */ -); -#else -# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d) -#endif -SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - WhereInfo *pWInfo, /* Complete information about the WHERE clause */ - int iLevel, /* Which level of pWInfo->a[] should be coded */ - Bitmask notReady /* Which tables are currently available */ -); - -/* whereexpr.c: */ -SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); -SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); -SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); -SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); -SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); -SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); -SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); - - - - - -/* -** Bitmasks for the operators on WhereTerm objects. These are all -** operators that are of interest to the query planner. An -** OR-ed combination of these values can be used when searching for -** particular WhereTerms within a WhereClause. -** -** Value constraints: -** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ -** WO_LT == SQLITE_INDEX_CONSTRAINT_LT -** WO_LE == SQLITE_INDEX_CONSTRAINT_LE -** WO_GT == SQLITE_INDEX_CONSTRAINT_GT -** WO_GE == SQLITE_INDEX_CONSTRAINT_GE -** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH -*/ -#define WO_IN 0x0001 -#define WO_EQ 0x0002 -#define WO_LT (WO_EQ<<(TK_LT-TK_EQ)) -#define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) -#define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) -#define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) -#define WO_MATCH 0x0040 -#define WO_IS 0x0080 -#define WO_ISNULL 0x0100 -#define WO_OR 0x0200 /* Two or more OR-connected terms */ -#define WO_AND 0x0400 /* Two or more AND-connected terms */ -#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */ -#define WO_NOOP 0x1000 /* This term does not restrict search space */ - -#define WO_ALL 0x1fff /* Mask of all possible WO_* values */ -#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */ - -/* -** These are definitions of bits in the WhereLoop.wsFlags field. -** The particular combination of bits in each WhereLoop help to -** determine the algorithm that WhereLoop represents. -*/ -#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */ -#define WHERE_COLUMN_RANGE 0x00000002 /* xEXPR */ -#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ -#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ -#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */ -#define WHERE_TOP_LIMIT 0x00000010 /* xEXPR or x>=EXPR constraint */ -#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and xaiColumn[i]; - if( i==XN_EXPR ) return ""; - if( i==XN_ROWID ) return "rowid"; - return pIdx->pTable->aCol[i].zName; -} - -/* -** This routine is a helper for explainIndexRange() below -** -** pStr holds the text of an expression that we are building up one term -** at a time. This routine adds a new term to the end of the expression. -** Terms are separated by AND so add the "AND" text for second and subsequent -** terms only. -*/ -static void explainAppendTerm( - StrAccum *pStr, /* The text expression being built */ - Index *pIdx, /* Index to read column names from */ - int nTerm, /* Number of terms */ - int iTerm, /* Zero-based index of first term. */ - int bAnd, /* Non-zero to append " AND " */ - const char *zOp /* Name of the operator */ -){ - int i; - - assert( nTerm>=1 ); - if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5); - - if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); - for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); - - sqlite3StrAccumAppend(pStr, zOp, 1); - - if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1); - for(i=0; i1 ) sqlite3StrAccumAppend(pStr, ")", 1); -} - -/* -** Argument pLevel describes a strategy for scanning table pTab. This -** function appends text to pStr that describes the subset of table -** rows scanned by the strategy in the form of an SQL expression. -** -** For example, if the query: -** -** SELECT * FROM t1 WHERE a=1 AND b>2; -** -** is run and there is an index on (a, b), then this function returns a -** string similar to: -** -** "a=? AND b>?" -*/ -static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ - Index *pIndex = pLoop->u.btree.pIndex; - u16 nEq = pLoop->u.btree.nEq; - u16 nSkip = pLoop->nSkip; - int i, j; - - if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; - sqlite3StrAccumAppend(pStr, " (", 2); - for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); - } - - j = i; - if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ - explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">"); - i = 1; - } - if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ - explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); - } - sqlite3StrAccumAppend(pStr, ")", 1); -} - -/* -** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was -** defined at compile-time. If it is not a no-op, a single OP_Explain opcode -** is added to the output to describe the table scan strategy in pLevel. -** -** If an OP_Explain opcode is added to the VM, its address is returned. -** Otherwise, if no OP_Explain is coded, zero is returned. -*/ -SQLITE_PRIVATE int sqlite3WhereExplainOneScan( - Parse *pParse, /* Parse context */ - SrcList *pTabList, /* Table list this loop refers to */ - WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - int iLevel, /* Value for "level" column of output */ - int iFrom, /* Value for "from" column of output */ - u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ -){ - int ret = 0; -#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pParse->explain==2 ) -#endif - { - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; - Vdbe *v = pParse->pVdbe; /* VM being constructed */ - sqlite3 *db = pParse->db; /* Database handle */ - int iId = pParse->iSelectId; /* Select id (left-most output column) */ - int isSearch; /* True for a SEARCH. False for SCAN. */ - WhereLoop *pLoop; /* The controlling WhereLoop object */ - u32 flags; /* Flags that describe this loop */ - char *zMsg; /* Text to add to EQP output */ - StrAccum str; /* EQP output string */ - char zBuf[100]; /* Initial space for EQP output string */ - - pLoop = pLevel->pWLoop; - flags = pLoop->wsFlags; - if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0; - - isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 - || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) - || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); - - sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); - sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); - if( pItem->pSelect ){ - sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId); - }else{ - sqlite3XPrintf(&str, " TABLE %s", pItem->zName); - } - - if( pItem->zAlias ){ - sqlite3XPrintf(&str, " AS %s", pItem->zAlias); - } - if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ - const char *zFmt = 0; - Index *pIdx; - - assert( pLoop->u.btree.pIndex!=0 ); - pIdx = pLoop->u.btree.pIndex; - assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); - if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ - if( isSearch ){ - zFmt = "PRIMARY KEY"; - } - }else if( flags & WHERE_PARTIALIDX ){ - zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; - }else if( flags & WHERE_AUTO_INDEX ){ - zFmt = "AUTOMATIC COVERING INDEX"; - }else if( flags & WHERE_IDX_ONLY ){ - zFmt = "COVERING INDEX %s"; - }else{ - zFmt = "INDEX %s"; - } - if( zFmt ){ - sqlite3StrAccumAppend(&str, " USING ", 7); - sqlite3XPrintf(&str, zFmt, pIdx->zName); - explainIndexRange(&str, pLoop); - } - }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ - const char *zRangeOp; - if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ - zRangeOp = "="; - }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ - zRangeOp = ">? AND rowid<"; - }else if( flags&WHERE_BTM_LIMIT ){ - zRangeOp = ">"; - }else{ - assert( flags&WHERE_TOP_LIMIT); - zRangeOp = "<"; - } - sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); - } -#ifndef SQLITE_OMIT_VIRTUALTABLE - else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s", - pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); - } -#endif -#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS - if( pLoop->nOut>=10 ){ - sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); - }else{ - sqlite3StrAccumAppend(&str, " (~1 row)", 9); - } -#endif - zMsg = sqlite3StrAccumFinish(&str); - ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC); - } - return ret; -} -#endif /* SQLITE_OMIT_EXPLAIN */ - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -/* -** Configure the VM passed as the first argument with an -** sqlite3_stmt_scanstatus() entry corresponding to the scan used to -** implement level pLvl. Argument pSrclist is a pointer to the FROM -** clause that the scan reads data from. -** -** If argument addrExplain is not 0, it must be the address of an -** OP_Explain instruction that describes the same loop. -*/ -SQLITE_PRIVATE void sqlite3WhereAddScanStatus( - Vdbe *v, /* Vdbe to add scanstatus entry to */ - SrcList *pSrclist, /* FROM clause pLvl reads data from */ - WhereLevel *pLvl, /* Level to add scanstatus() entry for */ - int addrExplain /* Address of OP_Explain (or 0) */ -){ - const char *zObj = 0; - WhereLoop *pLoop = pLvl->pWLoop; - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ - zObj = pLoop->u.btree.pIndex->zName; - }else{ - zObj = pSrclist->a[pLvl->iFrom].zName; - } - sqlite3VdbeScanStatus( - v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj - ); -} -#endif - - -/* -** Disable a term in the WHERE clause. Except, do not disable the term -** if it controls a LEFT OUTER JOIN and it did not originate in the ON -** or USING clause of that join. -** -** Consider the term t2.z='ok' in the following queries: -** -** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' -** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' -** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' -** -** The t2.z='ok' is disabled in the in (2) because it originates -** in the ON clause. The term is disabled in (3) because it is not part -** of a LEFT OUTER JOIN. In (1), the term is not disabled. -** -** Disabling a term causes that term to not be tested in the inner loop -** of the join. Disabling is an optimization. When terms are satisfied -** by indices, we disable them to prevent redundant tests in the inner -** loop. We would get the correct results if nothing were ever disabled, -** but joins might run a little slower. The trick is to disable as much -** as we can without disabling too much. If we disabled in (1), we'd get -** the wrong answer. See ticket #813. -** -** If all the children of a term are disabled, then that term is also -** automatically disabled. In this way, terms get disabled if derived -** virtual terms are tested first. For example: -** -** x GLOB 'abc*' AND x>='abc' AND x<'acd' -** \___________/ \______/ \_____/ -** parent child1 child2 -** -** Only the parent term was in the original WHERE clause. The child1 -** and child2 terms were added by the LIKE optimization. If both of -** the virtual child terms are valid, then testing of the parent can be -** skipped. -** -** Usually the parent term is marked as TERM_CODED. But if the parent -** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. -** The TERM_LIKECOND marking indicates that the term should be coded inside -** a conditional such that is only evaluated on the second pass of a -** LIKE-optimization loop, when scanning BLOBs instead of strings. -*/ -static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ - int nLoop = 0; - while( ALWAYS(pTerm!=0) - && (pTerm->wtFlags & TERM_CODED)==0 - && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) - && (pLevel->notReady & pTerm->prereqAll)==0 - ){ - if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ - pTerm->wtFlags |= TERM_LIKECOND; - }else{ - pTerm->wtFlags |= TERM_CODED; - } - if( pTerm->iParent<0 ) break; - pTerm = &pTerm->pWC->a[pTerm->iParent]; - pTerm->nChild--; - if( pTerm->nChild!=0 ) break; - nLoop++; - } -} - -/* -** Code an OP_Affinity opcode to apply the column affinity string zAff -** to the n registers starting at base. -** -** As an optimization, SQLITE_AFF_BLOB entries (which are no-ops) at the -** beginning and end of zAff are ignored. If all entries in zAff are -** SQLITE_AFF_BLOB, then no code gets generated. -** -** This routine makes its own copy of zAff so that the caller is free -** to modify zAff after this routine returns. -*/ -static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ - Vdbe *v = pParse->pVdbe; - if( zAff==0 ){ - assert( pParse->db->mallocFailed ); - return; - } - assert( v!=0 ); - - /* Adjust base and n to skip over SQLITE_AFF_BLOB entries at the beginning - ** and end of the affinity string. - */ - while( n>0 && zAff[0]==SQLITE_AFF_BLOB ){ - n--; - base++; - zAff++; - } - while( n>1 && zAff[n-1]==SQLITE_AFF_BLOB ){ - n--; - } - - /* Code the OP_Affinity opcode if there is anything left to do. */ - if( n>0 ){ - sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); - sqlite3ExprCacheAffinityChange(pParse, base, n); - } -} - -/* -** Expression pRight, which is the RHS of a comparison operation, is -** either a vector of n elements or, if n==1, a scalar expression. -** Before the comparison operation, affinity zAff is to be applied -** to the pRight values. This function modifies characters within the -** affinity string to SQLITE_AFF_BLOB if either: -** -** * the comparison will be performed with no affinity, or -** * the affinity change in zAff is guaranteed not to change the value. -*/ -static void updateRangeAffinityStr( - Expr *pRight, /* RHS of comparison */ - int n, /* Number of vector elements in comparison */ - char *zAff /* Affinity string to modify */ -){ - int i; - for(i=0; ipExpr; - Vdbe *v = pParse->pVdbe; - int iReg; /* Register holding results */ - - assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); - assert( iTarget>0 ); - if( pX->op==TK_EQ || pX->op==TK_IS ){ - iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); - }else if( pX->op==TK_ISNULL ){ - iReg = iTarget; - sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); -#ifndef SQLITE_OMIT_SUBQUERY - }else{ - int eType = IN_INDEX_NOOP; - int iTab; - struct InLoop *pIn; - WhereLoop *pLoop = pLevel->pWLoop; - int i; - int nEq = 0; - int *aiMap = 0; - - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 - && pLoop->u.btree.pIndex!=0 - && pLoop->u.btree.pIndex->aSortOrder[iEq] - ){ - testcase( iEq==0 ); - testcase( bRev ); - bRev = !bRev; - } - assert( pX->op==TK_IN ); - iReg = iTarget; - - for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ - disableTerm(pLevel, pTerm); - return iTarget; - } - } - for(i=iEq;inLTerm; i++){ - if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } - - if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); - }else{ - Select *pSelect = pX->x.pSelect; - sqlite3 *db = pParse->db; - ExprList *pOrigRhs = pSelect->pEList; - ExprList *pOrigLhs = pX->pLeft->x.pList; - ExprList *pRhs = 0; /* New Select.pEList for RHS */ - ExprList *pLhs = 0; /* New pX->pLeft vector */ - - for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iField = pLoop->aLTerm[i]->iField - 1; - Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0); - Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0); - - pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs); - pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs); - } - } - if( !db->mallocFailed ){ - Expr *pLeft = pX->pLeft; - - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } - } - - /* Take care here not to generate a TK_VECTOR containing only a - ** single value. Since the parser never creates such a vector, some - ** of the subroutines do not handle this case. */ - if( pLhs->nExpr==1 ){ - pX->pLeft = pLhs->a[0].pExpr; - }else{ - pLeft->x.pList = pLhs; - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq); - testcase( aiMap==0 ); - } - pSelect->pEList = pRhs; - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); - testcase( aiMap!=0 && aiMap[0]!=0 ); - pSelect->pEList = pOrigRhs; - pLeft->x.pList = pOrigLhs; - pX->pLeft = pLeft; - } - sqlite3ExprListDelete(pParse->db, pLhs); - sqlite3ExprListDelete(pParse->db, pRhs); - } - - if( eType==IN_INDEX_INDEX_DESC ){ - testcase( bRev ); - bRev = !bRev; - } - iTab = pX->iTable; - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); - VdbeCoverageIf(v, bRev); - VdbeCoverageIf(v, !bRev); - assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); - - pLoop->wsFlags |= WHERE_IN_ABLE; - if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = sqlite3VdbeMakeLabel(v); - } - - i = pLevel->u.in.nIn; - pLevel->u.in.nIn += nEq; - pLevel->u.in.aInLoop = - sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); - pIn = pLevel->u.in.aInLoop; - if( pIn ){ - int iMap = 0; /* Index in aiMap[] */ - pIn += i; - for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iOut = iReg + i - iEq; - if( eType==IN_INDEX_ROWID ){ - testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); - }else{ - int iCol = aiMap ? aiMap[iMap++] : 0; - pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); - } - sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); - if( i==iEq ){ - pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; - }else{ - pIn->eEndLoopOp = OP_Noop; - } - pIn++; - } - } - }else{ - pLevel->u.in.nIn = 0; - } - sqlite3DbFree(pParse->db, aiMap); -#endif - } - disableTerm(pLevel, pTerm); - return iReg; -} - -/* -** Generate code that will evaluate all == and IN constraints for an -** index scan. -** -** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). -** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 -** The index has as many as three equality constraints, but in this -** example, the third "c" value is an inequality. So only two -** constraints are coded. This routine will generate code to evaluate -** a==5 and b IN (1,2,3). The current values for a and b will be stored -** in consecutive registers and the index of the first register is returned. -** -** In the example above nEq==2. But this subroutine works for any value -** of nEq including 0. If nEq==0, this routine is nearly a no-op. -** The only thing it does is allocate the pLevel->iMem memory cell and -** compute the affinity string. -** -** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints -** are == or IN and are covered by the nEq. nExtraReg is 1 if there is -** an inequality constraint (such as the "c>=5 AND c<10" in the example) that -** occurs after the nEq quality constraints. -** -** This routine allocates a range of nEq+nExtraReg memory cells and returns -** the index of the first memory cell in that range. The code that -** calls this routine will use that memory range to store keys for -** start and termination conditions of the loop. -** key value of the loop. If one or more IN operators appear, then -** this routine allocates an additional nEq memory cells for internal -** use. -** -** Before returning, *pzAff is set to point to a buffer containing a -** copy of the column affinity string of the index allocated using -** sqlite3DbMalloc(). Except, entries in the copy of the string associated -** with equality constraints that use BLOB or NONE affinity are set to -** SQLITE_AFF_BLOB. This is to deal with SQL such as the following: -** -** CREATE TABLE t1(a TEXT PRIMARY KEY, b); -** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; -** -** In the example above, the index on t1(a) has TEXT affinity. But since -** the right hand side of the equality constraint (t2.b) has BLOB/NONE affinity, -** no conversion should be attempted before using a t2.b value as part of -** a key to search the index. Hence the first byte in the returned affinity -** string in this example would be set to SQLITE_AFF_BLOB. -*/ -static int codeAllEqualityTerms( - Parse *pParse, /* Parsing context */ - WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ - int bRev, /* Reverse the order of IN operators */ - int nExtraReg, /* Number of extra registers to allocate */ - char **pzAff /* OUT: Set to point to affinity string */ -){ - u16 nEq; /* The number of == or IN constraints to code */ - u16 nSkip; /* Number of left-most columns to skip */ - Vdbe *v = pParse->pVdbe; /* The vm under construction */ - Index *pIdx; /* The index being used for this loop */ - WhereTerm *pTerm; /* A single constraint term */ - WhereLoop *pLoop; /* The WhereLoop object */ - int j; /* Loop counter */ - int regBase; /* Base register */ - int nReg; /* Number of registers to allocate */ - char *zAff; /* Affinity string to return */ - - /* This module is only called on query plans that use an index. */ - pLoop = pLevel->pWLoop; - assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); - nEq = pLoop->u.btree.nEq; - nSkip = pLoop->nSkip; - pIdx = pLoop->u.btree.pIndex; - assert( pIdx!=0 ); - - /* Figure out how many memory cells we will need then allocate them. - */ - regBase = pParse->nMem + 1; - nReg = pLoop->u.btree.nEq + nExtraReg; - pParse->nMem += nReg; - - zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); - assert( zAff!=0 || pParse->db->mallocFailed ); - - if( nSkip ){ - int iIdxCur = pLevel->iIdxCur; - sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); - VdbeCoverageIf(v, bRev==0); - VdbeCoverageIf(v, bRev!=0); - VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); - j = sqlite3VdbeAddOp0(v, OP_Goto); - pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), - iIdxCur, 0, regBase, nSkip); - VdbeCoverageIf(v, bRev==0); - VdbeCoverageIf(v, bRev!=0); - sqlite3VdbeJumpHere(v, j); - for(j=0; jaiColumn[j]==XN_EXPR ); - VdbeComment((v, "%s", explainIndexColumnName(pIdx, j))); - } - } - - /* Evaluate the equality constraints - */ - assert( zAff==0 || (int)strlen(zAff)>=nEq ); - for(j=nSkip; jaLTerm[j]; - assert( pTerm!=0 ); - /* The following testcase is true for indices with redundant columns. - ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ - testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); - if( r1!=regBase+j ){ - if( nReg==1 ){ - sqlite3ReleaseTempReg(pParse, regBase); - regBase = r1; - }else{ - sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); - } - } - if( pTerm->eOperator & WO_IN ){ - if( pTerm->pExpr->flags & EP_xIsSelect ){ - /* No affinity ever needs to be (or should be) applied to a value - ** from the RHS of an "? IN (SELECT ...)" expression. The - ** sqlite3FindInIndex() routine has already ensured that the - ** affinity of the comparison has been applied to the value. */ - if( zAff ) zAff[j] = SQLITE_AFF_BLOB; - } - }else if( (pTerm->eOperator & WO_ISNULL)==0 ){ - Expr *pRight = pTerm->pExpr->pRight; - if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); - VdbeCoverage(v); - } - if( zAff ){ - if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ - zAff[j] = SQLITE_AFF_BLOB; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ - zAff[j] = SQLITE_AFF_BLOB; - } - } - } - } - *pzAff = zAff; - return regBase; -} - -#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS -/* -** If the most recently coded instruction is a constant range constraint -** (a string literal) that originated from the LIKE optimization, then -** set P3 and P5 on the OP_String opcode so that the string will be cast -** to a BLOB at appropriate times. -** -** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range -** expression: "x>='ABC' AND x<'abd'". But this requires that the range -** scan loop run twice, once for strings and a second time for BLOBs. -** The OP_String opcodes on the second pass convert the upper and lower -** bound string constants to blobs. This routine makes the necessary changes -** to the OP_String opcodes for that to happen. -** -** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then -** only the one pass through the string space is required, so this routine -** becomes a no-op. -*/ -static void whereLikeOptimizationStringFixup( - Vdbe *v, /* prepared statement under construction */ - WhereLevel *pLevel, /* The loop that contains the LIKE operator */ - WhereTerm *pTerm /* The upper or lower bound just coded */ -){ - if( pTerm->wtFlags & TERM_LIKEOPT ){ - VdbeOp *pOp; - assert( pLevel->iLikeRepCntr>0 ); - pOp = sqlite3VdbeGetOp(v, -1); - assert( pOp!=0 ); - assert( pOp->opcode==OP_String8 - || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); - pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ - pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ - } -} -#else -# define whereLikeOptimizationStringFixup(A,B,C) -#endif - -#ifdef SQLITE_ENABLE_CURSOR_HINTS -/* -** Information is passed from codeCursorHint() down to individual nodes of -** the expression tree (by sqlite3WalkExpr()) using an instance of this -** structure. -*/ -struct CCurHint { - int iTabCur; /* Cursor for the main table */ - int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */ - Index *pIdx; /* The index used to access the table */ -}; - -/* -** This function is called for every node of an expression that is a candidate -** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference -** the table CCurHint.iTabCur, verify that the same column can be -** accessed through the index. If it cannot, then set pWalker->eCode to 1. -*/ -static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ - struct CCurHint *pHint = pWalker->u.pCCurHint; - assert( pHint->pIdx!=0 ); - if( pExpr->op==TK_COLUMN - && pExpr->iTable==pHint->iTabCur - && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0 - ){ - pWalker->eCode = 1; - } - return WRC_Continue; -} - -/* -** Test whether or not expression pExpr, which was part of a WHERE clause, -** should be included in the cursor-hint for a table that is on the rhs -** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the -** expression is not suitable. -** -** An expression is unsuitable if it might evaluate to non NULL even if -** a TK_COLUMN node that does affect the value of the expression is set -** to NULL. For example: -** -** col IS NULL -** col IS NOT NULL -** coalesce(col, 1) -** CASE WHEN col THEN 0 ELSE 1 END -*/ -static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_IS - || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT - || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE - ){ - pWalker->eCode = 1; - }else if( pExpr->op==TK_FUNCTION ){ - int d1; - char d2[3]; - if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ - pWalker->eCode = 1; - } - } - - return WRC_Continue; -} - - -/* -** This function is called on every node of an expression tree used as an -** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN -** that accesses any table other than the one identified by -** CCurHint.iTabCur, then do the following: -** -** 1) allocate a register and code an OP_Column instruction to read -** the specified column into the new register, and -** -** 2) transform the expression node to a TK_REGISTER node that reads -** from the newly populated register. -** -** Also, if the node is a TK_COLUMN that does access the table idenified -** by pCCurHint.iTabCur, and an index is being used (which we will -** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into -** an access of the index rather than the original table. -*/ -static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ - int rc = WRC_Continue; - struct CCurHint *pHint = pWalker->u.pCCurHint; - if( pExpr->op==TK_COLUMN ){ - if( pExpr->iTable!=pHint->iTabCur ){ - Vdbe *v = pWalker->pParse->pVdbe; - int reg = ++pWalker->pParse->nMem; /* Register for column value */ - sqlite3ExprCodeGetColumnOfTable( - v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg - ); - pExpr->op = TK_REGISTER; - pExpr->iTable = reg; - }else if( pHint->pIdx!=0 ){ - pExpr->iTable = pHint->iIdxCur; - pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn); - assert( pExpr->iColumn>=0 ); - } - }else if( pExpr->op==TK_AGG_FUNCTION ){ - /* An aggregate function in the WHERE clause of a query means this must - ** be a correlated sub-query, and expression pExpr is an aggregate from - ** the parent context. Do not walk the function arguments in this case. - ** - ** todo: It should be possible to replace this node with a TK_REGISTER - ** expression, as the result of the expression must be stored in a - ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ - rc = WRC_Prune; - } - return rc; -} - -/* -** Insert an OP_CursorHint instruction if it is appropriate to do so. -*/ -static void codeCursorHint( - struct SrcList_item *pTabItem, /* FROM clause item */ - WhereInfo *pWInfo, /* The where clause */ - WhereLevel *pLevel, /* Which loop to provide hints for */ - WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ -){ - Parse *pParse = pWInfo->pParse; - sqlite3 *db = pParse->db; - Vdbe *v = pParse->pVdbe; - Expr *pExpr = 0; - WhereLoop *pLoop = pLevel->pWLoop; - int iCur; - WhereClause *pWC; - WhereTerm *pTerm; - int i, j; - struct CCurHint sHint; - Walker sWalker; - - if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; - iCur = pLevel->iTabCur; - assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor ); - sHint.iTabCur = iCur; - sHint.iIdxCur = pLevel->iIdxCur; - sHint.pIdx = pLoop->u.btree.pIndex; - memset(&sWalker, 0, sizeof(sWalker)); - sWalker.pParse = pParse; - sWalker.u.pCCurHint = &sHint; - pWC = &pWInfo->sWC; - for(i=0; inTerm; i++){ - pTerm = &pWC->a[i]; - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( pTerm->prereqAll & pLevel->notReady ) continue; - - /* Any terms specified as part of the ON(...) clause for any LEFT - ** JOIN for which the current table is not the rhs are omitted - ** from the cursor-hint. - ** - ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms - ** that were specified as part of the WHERE clause must be excluded. - ** This is to address the following: - ** - ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; - ** - ** Say there is a single row in t2 that matches (t1.a=t2.b), but its - ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is - ** pushed down to the cursor, this row is filtered out, causing - ** SQLite to synthesize a row of NULL values. Which does match the - ** WHERE clause, and so the query returns a row. Which is incorrect. - ** - ** For the same reason, WHERE terms such as: - ** - ** WHERE 1 = (t2.c IS NULL) - ** - ** are also excluded. See codeCursorHintIsOrFunction() for details. - */ - if( pTabItem->fg.jointype & JT_LEFT ){ - Expr *pExpr = pTerm->pExpr; - if( !ExprHasProperty(pExpr, EP_FromJoin) - || pExpr->iRightJoinTable!=pTabItem->iCursor - ){ - sWalker.eCode = 0; - sWalker.xExprCallback = codeCursorHintIsOrFunction; - sqlite3WalkExpr(&sWalker, pTerm->pExpr); - if( sWalker.eCode ) continue; - } - }else{ - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; - } - - /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize - ** the cursor. These terms are not needed as hints for a pure range - ** scan (that has no == terms) so omit them. */ - if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){ - for(j=0; jnLTerm && pLoop->aLTerm[j]!=pTerm; j++){} - if( jnLTerm ) continue; - } - - /* No subqueries or non-deterministic functions allowed */ - if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; - - /* For an index scan, make sure referenced columns are actually in - ** the index. */ - if( sHint.pIdx!=0 ){ - sWalker.eCode = 0; - sWalker.xExprCallback = codeCursorHintCheckExpr; - sqlite3WalkExpr(&sWalker, pTerm->pExpr); - if( sWalker.eCode ) continue; - } - - /* If we survive all prior tests, that means this term is worth hinting */ - pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); - } - if( pExpr!=0 ){ - sWalker.xExprCallback = codeCursorHintFixExpr; - sqlite3WalkExpr(&sWalker, pExpr); - sqlite3VdbeAddOp4(v, OP_CursorHint, - (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, - (const char*)pExpr, P4_EXPR); - } -} -#else -# define codeCursorHint(A,B,C,D) /* No-op */ -#endif /* SQLITE_ENABLE_CURSOR_HINTS */ - -/* -** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains -** a rowid value just read from cursor iIdxCur, open on index pIdx. This -** function generates code to do a deferred seek of cursor iCur to the -** rowid stored in register iRowid. -** -** Normally, this is just: -** -** OP_Seek $iCur $iRowid -** -** However, if the scan currently being coded is a branch of an OR-loop and -** the statement currently being coded is a SELECT, then P3 of the OP_Seek -** is set to iIdxCur and P4 is set to point to an array of integers -** containing one entry for each column of the table cursor iCur is open -** on. For each table column, if the column is the i'th column of the -** index, then the corresponding array entry is set to (i+1). If the column -** does not appear in the index at all, the array entry is set to 0. -*/ -static void codeDeferredSeek( - WhereInfo *pWInfo, /* Where clause context */ - Index *pIdx, /* Index scan is using */ - int iCur, /* Cursor for IPK b-tree */ - int iIdxCur /* Index cursor */ -){ - Parse *pParse = pWInfo->pParse; /* Parse context */ - Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */ - - assert( iIdxCur>0 ); - assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); - - sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur); - if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) - && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) - ){ - int i; - Table *pTab = pIdx->pTable; - int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1)); - if( ai ){ - ai[0] = pTab->nCol; - for(i=0; inColumn-1; i++){ - assert( pIdx->aiColumn[i]nCol ); - if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1; - } - sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); - } - } -} - -/* -** If the expression passed as the second argument is a vector, generate -** code to write the first nReg elements of the vector into an array -** of registers starting with iReg. -** -** If the expression is not a vector, then nReg must be passed 1. In -** this case, generate code to evaluate the expression and leave the -** result in register iReg. -*/ -static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ - assert( nReg>0 ); - if( sqlite3ExprIsVector(p) ){ -#ifndef SQLITE_OMIT_SUBQUERY - if( (p->flags & EP_xIsSelect) ){ - Vdbe *v = pParse->pVdbe; - int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); - sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); - }else -#endif - { - int i; - ExprList *pList = p->x.pList; - assert( nReg<=pList->nExpr ); - for(i=0; ia[i].pExpr, iReg+i); - } - } - }else{ - assert( nReg==1 ); - sqlite3ExprCode(pParse, p, iReg); - } -} - -/* -** Generate code for the start of the iLevel-th loop in the WHERE clause -** implementation described by pWInfo. -*/ -SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - WhereInfo *pWInfo, /* Complete information about the WHERE clause */ - int iLevel, /* Which level of pWInfo->a[] should be coded */ - Bitmask notReady /* Which tables are currently available */ -){ - int j, k; /* Loop counters */ - int iCur; /* The VDBE cursor for the table */ - int addrNxt; /* Where to jump to continue with the next IN case */ - int omitTable; /* True if we use the index only */ - int bRev; /* True if we need to scan in reverse order */ - WhereLevel *pLevel; /* The where level to be coded */ - WhereLoop *pLoop; /* The WhereLoop object being coded */ - WhereClause *pWC; /* Decomposition of the entire WHERE clause */ - WhereTerm *pTerm; /* A WHERE clause term */ - Parse *pParse; /* Parsing context */ - sqlite3 *db; /* Database connection */ - Vdbe *v; /* The prepared stmt under constructions */ - struct SrcList_item *pTabItem; /* FROM clause term being coded */ - int addrBrk; /* Jump here to break out of the loop */ - int addrCont; /* Jump here to continue with next cycle */ - int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ - int iReleaseReg = 0; /* Temp register to free before returning */ - - pParse = pWInfo->pParse; - v = pParse->pVdbe; - pWC = &pWInfo->sWC; - db = pParse->db; - pLevel = &pWInfo->a[iLevel]; - pLoop = pLevel->pWLoop; - pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; - iCur = pTabItem->iCursor; - pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); - bRev = (pWInfo->revMask>>iLevel)&1; - omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; - VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); - - /* Create labels for the "break" and "continue" instructions - ** for the current loop. Jump to addrBrk to break out of a loop. - ** Jump to cont to go immediately to the next iteration of the - ** loop. - ** - ** When there is an IN operator, we also have a "addrNxt" label that - ** means to continue with the next IN value combination. When - ** there are no IN operators in the constraints, the "addrNxt" label - ** is the same as "addrBrk". - */ - addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v); - addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v); - - /* If this is the right table of a LEFT OUTER JOIN, allocate and - ** initialize a memory cell that records if this table matches any - ** row of the left table of the join. - */ - if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ - pLevel->iLeftJoin = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); - VdbeComment((v, "init LEFT JOIN no-match flag")); - } - - /* Special case of a FROM clause subquery implemented as a co-routine */ - if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); - VdbeCoverage(v); - VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); - pLevel->op = OP_Goto; - }else - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ - /* Case 1: The table is a virtual-table. Use the VFilter and VNext - ** to access the data. - */ - int iReg; /* P3 Value for OP_VFilter */ - int addrNotFound; - int nConstraint = pLoop->nLTerm; - int iIn; /* Counter for IN constraints */ - - sqlite3ExprCachePush(pParse); - iReg = sqlite3GetTempRange(pParse, nConstraint+2); - addrNotFound = pLevel->addrBrk; - for(j=0; jaLTerm[j]; - if( NEVER(pTerm==0) ) continue; - if( pTerm->eOperator & WO_IN ){ - codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); - addrNotFound = pLevel->addrNxt; - }else{ - Expr *pRight = pTerm->pExpr->pRight; - codeExprOrVector(pParse, pRight, iTarget, 1); - } - } - sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); - sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); - sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, - pLoop->u.vtab.idxStr, - pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC); - VdbeCoverage(v); - pLoop->u.vtab.needFree = 0; - pLevel->p1 = iCur; - pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; - pLevel->p2 = sqlite3VdbeCurrentAddr(v); - iIn = pLevel->u.in.nIn; - for(j=nConstraint-1; j>=0; j--){ - pTerm = pLoop->aLTerm[j]; - if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ - disableTerm(pLevel, pTerm); - }else if( (pTerm->eOperator & WO_IN)!=0 ){ - Expr *pCompare; /* The comparison operator */ - Expr *pRight; /* RHS of the comparison */ - VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ - - /* Reload the constraint value into reg[iReg+j+2]. The same value - ** was loaded into the same register prior to the OP_VFilter, but - ** the xFilter implementation might have changed the datatype or - ** encoding of the value in the register, so it *must* be reloaded. */ - assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed ); - if( !db->mallocFailed ){ - assert( iIn>0 ); - pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop); - assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid ); - assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 ); - assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 ); - testcase( pOp->opcode==OP_Rowid ); - sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); - } - - /* Generate code that will continue to the next row if - ** the IN constraint is not satisfied */ - pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0, 0); - assert( pCompare!=0 || db->mallocFailed ); - if( pCompare ){ - pCompare->pLeft = pTerm->pExpr->pLeft; - pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); - if( pRight ){ - pRight->iTable = iReg+j+2; - sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0); - } - pCompare->pLeft = 0; - sqlite3ExprDelete(db, pCompare); - } - } - } - /* These registers need to be preserved in case there is an IN operator - ** loop. So we could deallocate the registers here (and potentially - ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems - ** simpler and safer to simply not reuse the registers. - ** - ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); - */ - sqlite3ExprCachePop(pParse); - }else -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - - if( (pLoop->wsFlags & WHERE_IPK)!=0 - && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 - ){ - /* Case 2: We can directly reference a single row using an - ** equality comparison against the ROWID field. Or - ** we reference multiple rows using a "rowid IN (...)" - ** construct. - */ - assert( pLoop->u.btree.nEq==1 ); - pTerm = pLoop->aLTerm[0]; - assert( pTerm!=0 ); - assert( pTerm->pExpr!=0 ); - assert( omitTable==0 ); - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - iReleaseReg = ++pParse->nMem; - iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); - if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); - addrNxt = pLevel->addrNxt; - sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); - VdbeCoverage(v); - sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - VdbeComment((v, "pk")); - pLevel->op = OP_Noop; - }else if( (pLoop->wsFlags & WHERE_IPK)!=0 - && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 - ){ - /* Case 3: We have an inequality comparison against the ROWID field. - */ - int testOp = OP_Noop; - int start; - int memEndValue = 0; - WhereTerm *pStart, *pEnd; - - assert( omitTable==0 ); - j = 0; - pStart = pEnd = 0; - if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++]; - if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++]; - assert( pStart!=0 || pEnd!=0 ); - if( bRev ){ - pTerm = pStart; - pStart = pEnd; - pEnd = pTerm; - } - codeCursorHint(pTabItem, pWInfo, pLevel, pEnd); - if( pStart ){ - Expr *pX; /* The expression that defines the start bound */ - int r1, rTemp; /* Registers for holding the start boundary */ - int op; /* Cursor seek operation */ - - /* The following constant maps TK_xx codes into corresponding - ** seek opcodes. It depends on a particular ordering of TK_xx - */ - const u8 aMoveOp[] = { - /* TK_GT */ OP_SeekGT, - /* TK_LE */ OP_SeekLE, - /* TK_LT */ OP_SeekLT, - /* TK_GE */ OP_SeekGE - }; - assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ - assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ - assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ - - assert( (pStart->wtFlags & TERM_VNULL)==0 ); - testcase( pStart->wtFlags & TERM_VIRTUAL ); - pX = pStart->pExpr; - assert( pX!=0 ); - testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ - if( sqlite3ExprIsVector(pX->pRight) ){ - r1 = rTemp = sqlite3GetTempReg(pParse); - codeExprOrVector(pParse, pX->pRight, r1, 1); - op = aMoveOp[(pX->op - TK_GT) | 0x0001]; - }else{ - r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); - disableTerm(pLevel, pStart); - op = aMoveOp[(pX->op - TK_GT)]; - } - sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); - VdbeComment((v, "pk")); - VdbeCoverageIf(v, pX->op==TK_GT); - VdbeCoverageIf(v, pX->op==TK_LE); - VdbeCoverageIf(v, pX->op==TK_LT); - VdbeCoverageIf(v, pX->op==TK_GE); - sqlite3ExprCacheAffinityChange(pParse, r1, 1); - sqlite3ReleaseTempReg(pParse, rTemp); - }else{ - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk); - VdbeCoverageIf(v, bRev==0); - VdbeCoverageIf(v, bRev!=0); - } - if( pEnd ){ - Expr *pX; - pX = pEnd->pExpr; - assert( pX!=0 ); - assert( (pEnd->wtFlags & TERM_VNULL)==0 ); - testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ - testcase( pEnd->wtFlags & TERM_VIRTUAL ); - memEndValue = ++pParse->nMem; - codeExprOrVector(pParse, pX->pRight, memEndValue, 1); - if( 0==sqlite3ExprIsVector(pX->pRight) - && (pX->op==TK_LT || pX->op==TK_GT) - ){ - testOp = bRev ? OP_Le : OP_Ge; - }else{ - testOp = bRev ? OP_Lt : OP_Gt; - } - if( 0==sqlite3ExprIsVector(pX->pRight) ){ - disableTerm(pLevel, pEnd); - } - } - start = sqlite3VdbeCurrentAddr(v); - pLevel->op = bRev ? OP_Prev : OP_Next; - pLevel->p1 = iCur; - pLevel->p2 = start; - assert( pLevel->p5==0 ); - if( testOp!=OP_Noop ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); - VdbeCoverageIf(v, testOp==OP_Le); - VdbeCoverageIf(v, testOp==OP_Lt); - VdbeCoverageIf(v, testOp==OP_Ge); - VdbeCoverageIf(v, testOp==OP_Gt); - sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); - } - }else if( pLoop->wsFlags & WHERE_INDEXED ){ - /* Case 4: A scan using an index. - ** - ** The WHERE clause may contain zero or more equality - ** terms ("==" or "IN" operators) that refer to the N - ** left-most columns of the index. It may also contain - ** inequality constraints (>, <, >= or <=) on the indexed - ** column that immediately follows the N equalities. Only - ** the right-most column can be an inequality - the rest must - ** use the "==" and "IN" operators. For example, if the - ** index is on (x,y,z), then the following clauses are all - ** optimized: - ** - ** x=5 - ** x=5 AND y=10 - ** x=5 AND y<10 - ** x=5 AND y>5 AND y<10 - ** x=5 AND y=5 AND z<=10 - ** - ** The z<10 term of the following cannot be used, only - ** the x=5 term: - ** - ** x=5 AND z<10 - ** - ** N may be zero if there are inequality constraints. - ** If there are no inequality constraints, then N is at - ** least one. - ** - ** This case is also used when there are no WHERE clause - ** constraints but an index is selected anyway, in order - ** to force the output order to conform to an ORDER BY. - */ - static const u8 aStartOp[] = { - 0, - 0, - OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ - OP_Last, /* 3: (!start_constraints && startEq && bRev) */ - OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */ - OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */ - OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */ - OP_SeekLE /* 7: (start_constraints && startEq && bRev) */ - }; - static const u8 aEndOp[] = { - OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */ - OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */ - OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */ - OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ - }; - u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ - u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */ - u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */ - int regBase; /* Base register holding constraint values */ - WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ - WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ - int startEq; /* True if range start uses ==, >= or <= */ - int endEq; /* True if range end uses ==, >= or <= */ - int start_constraints; /* Start of range is constrained */ - int nConstraint; /* Number of constraint terms */ - Index *pIdx; /* The index we will be using */ - int iIdxCur; /* The VDBE cursor for the index */ - int nExtraReg = 0; /* Number of extra registers needed */ - int op; /* Instruction opcode */ - char *zStartAff; /* Affinity for start of range constraint */ - char *zEndAff = 0; /* Affinity for end of range constraint */ - u8 bSeekPastNull = 0; /* True to seek past initial nulls */ - u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ - - pIdx = pLoop->u.btree.pIndex; - iIdxCur = pLevel->iIdxCur; - assert( nEq>=pLoop->nSkip ); - - /* If this loop satisfies a sort order (pOrderBy) request that - ** was passed to this function to implement a "SELECT min(x) ..." - ** query, then the caller will only allow the loop to run for - ** a single iteration. This means that the first row returned - ** should not have a NULL value stored in 'x'. If column 'x' is - ** the first one after the nEq equality constraints in the index, - ** this requires some special handling. - */ - assert( pWInfo->pOrderBy==0 - || pWInfo->pOrderBy->nExpr==1 - || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 ); - if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 - && pWInfo->nOBSat>0 - && (pIdx->nKeyCol>nEq) - ){ - assert( pLoop->nSkip==0 ); - bSeekPastNull = 1; - nExtraReg = 1; - } - - /* Find any inequality constraint terms for the start and end - ** of the range. - */ - j = nEq; - if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ - pRangeStart = pLoop->aLTerm[j++]; - nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); - /* Like optimization range constraints always occur in pairs */ - assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || - (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); - } - if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ - pRangeEnd = pLoop->aLTerm[j++]; - nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop); -#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ - assert( pRangeStart!=0 ); /* LIKE opt constraints */ - assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ - pLevel->iLikeRepCntr = (u32)++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); - VdbeComment((v, "LIKE loop counter")); - pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); - /* iLikeRepCntr actually stores 2x the counter register number. The - ** bottom bit indicates whether the search order is ASC or DESC. */ - testcase( bRev ); - testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); - assert( (bRev & ~1)==0 ); - pLevel->iLikeRepCntr <<=1; - pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC); - } -#endif - if( pRangeStart==0 ){ - j = pIdx->aiColumn[nEq]; - if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ - bSeekPastNull = 1; - } - } - } - assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); - - /* If we are doing a reverse order scan on an ascending index, or - ** a forward order scan on a descending index, interchange the - ** start and end terms (pRangeStart and pRangeEnd). - */ - if( (nEqnKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) - || (bRev && pIdx->nKeyCol==nEq) - ){ - SWAP(WhereTerm *, pRangeEnd, pRangeStart); - SWAP(u8, bSeekPastNull, bStopAtNull); - SWAP(u8, nBtm, nTop); - } - - /* Generate code to evaluate all constraint terms using == or IN - ** and store the values of those terms in an array of registers - ** starting at regBase. - */ - codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); - regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); - assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); - if( zStartAff && nTop ){ - zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); - } - addrNxt = pLevel->addrNxt; - - testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); - testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); - testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); - testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 ); - startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); - endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); - start_constraints = pRangeStart || nEq>0; - - /* Seek the index cursor to the start of the range. */ - nConstraint = nEq; - if( pRangeStart ){ - Expr *pRight = pRangeStart->pExpr->pRight; - codeExprOrVector(pParse, pRight, regBase+nEq, nBtm); - whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); - if( (pRangeStart->wtFlags & TERM_VNULL)==0 - && sqlite3ExprCanBeNull(pRight) - ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); - VdbeCoverage(v); - } - if( zStartAff ){ - updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]); - } - nConstraint += nBtm; - testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); - if( sqlite3ExprIsVector(pRight)==0 ){ - disableTerm(pLevel, pRangeStart); - }else{ - startEq = 1; - } - bSeekPastNull = 0; - }else if( bSeekPastNull ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); - nConstraint++; - startEq = 0; - start_constraints = 1; - } - codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); - if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){ - /* The skip-scan logic inside the call to codeAllEqualityConstraints() - ** above has already left the cursor sitting on the correct row, - ** so no further seeking is needed */ - }else{ - op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; - assert( op!=0 ); - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - VdbeCoverage(v); - VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); - VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); - VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); - VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); - VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); - VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); - } - - /* Load the value for the inequality constraint at the end of the - ** range (if any). - */ - nConstraint = nEq; - if( pRangeEnd ){ - Expr *pRight = pRangeEnd->pExpr->pRight; - sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); - codeExprOrVector(pParse, pRight, regBase+nEq, nTop); - whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); - if( (pRangeEnd->wtFlags & TERM_VNULL)==0 - && sqlite3ExprCanBeNull(pRight) - ){ - sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); - VdbeCoverage(v); - } - if( zEndAff ){ - updateRangeAffinityStr(pRight, nTop, zEndAff); - codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); - }else{ - assert( pParse->db->mallocFailed ); - } - nConstraint += nTop; - testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); - - if( sqlite3ExprIsVector(pRight)==0 ){ - disableTerm(pLevel, pRangeEnd); - }else{ - endEq = 1; - } - }else if( bStopAtNull ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); - endEq = 0; - nConstraint++; - } - sqlite3DbFree(db, zStartAff); - sqlite3DbFree(db, zEndAff); - - /* Top of the loop body */ - pLevel->p2 = sqlite3VdbeCurrentAddr(v); - - /* Check if the index cursor is past the end of the range. */ - if( nConstraint ){ - op = aEndOp[bRev*2 + endEq]; - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); - testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); - testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); - testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); - } - - /* Seek the table cursor, if required */ - if( omitTable ){ - /* pIdx is a covering index. No need to access the main table. */ - }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); - VdbeCoverage(v); - }else{ - codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); - } - }else if( iCur!=iIdxCur ){ - Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); - iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); - for(j=0; jnKeyCol; j++){ - k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); - } - sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, - iRowidReg, pPk->nKeyCol); VdbeCoverage(v); - } - - /* Record the instruction used to terminate the loop. */ - if( pLoop->wsFlags & WHERE_ONEROW ){ - pLevel->op = OP_Noop; - }else if( bRev ){ - pLevel->op = OP_Prev; - }else{ - pLevel->op = OP_Next; - } - pLevel->p1 = iIdxCur; - pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; - if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ - pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; - }else{ - assert( pLevel->p5==0 ); - } - }else - -#ifndef SQLITE_OMIT_OR_OPTIMIZATION - if( pLoop->wsFlags & WHERE_MULTI_OR ){ - /* Case 5: Two or more separately indexed terms connected by OR - ** - ** Example: - ** - ** CREATE TABLE t1(a,b,c,d); - ** CREATE INDEX i1 ON t1(a); - ** CREATE INDEX i2 ON t1(b); - ** CREATE INDEX i3 ON t1(c); - ** - ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13) - ** - ** In the example, there are three indexed terms connected by OR. - ** The top of the loop looks like this: - ** - ** Null 1 # Zero the rowset in reg 1 - ** - ** Then, for each indexed term, the following. The arguments to - ** RowSetTest are such that the rowid of the current row is inserted - ** into the RowSet. If it is already present, control skips the - ** Gosub opcode and jumps straight to the code generated by WhereEnd(). - ** - ** sqlite3WhereBegin() - ** RowSetTest # Insert rowid into rowset - ** Gosub 2 A - ** sqlite3WhereEnd() - ** - ** Following the above, code to terminate the loop. Label A, the target - ** of the Gosub above, jumps to the instruction right after the Goto. - ** - ** Null 1 # Zero the rowset in reg 1 - ** Goto B # The loop is finished. - ** - ** A: # Return data, whatever. - ** - ** Return 2 # Jump back to the Gosub - ** - ** B: - ** - ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then - ** use an ephemeral index instead of a RowSet to record the primary - ** keys of the rows we have already seen. - ** - */ - WhereClause *pOrWc; /* The OR-clause broken out into subterms */ - SrcList *pOrTab; /* Shortened table list or OR-clause generation */ - Index *pCov = 0; /* Potential covering index (or NULL) */ - int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ - - int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ - int regRowset = 0; /* Register for RowSet object */ - int regRowid = 0; /* Register holding rowid */ - int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ - int iRetInit; /* Address of regReturn init */ - int untestedTerms = 0; /* Some terms not completely tested */ - int ii; /* Loop counter */ - u16 wctrlFlags; /* Flags for sub-WHERE clause */ - Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ - Table *pTab = pTabItem->pTab; - - pTerm = pLoop->aLTerm[0]; - assert( pTerm!=0 ); - assert( pTerm->eOperator & WO_OR ); - assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); - pOrWc = &pTerm->u.pOrInfo->wc; - pLevel->op = OP_Return; - pLevel->p1 = regReturn; - - /* Set up a new SrcList in pOrTab containing the table being scanned - ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. - ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). - */ - if( pWInfo->nLevel>1 ){ - int nNotReady; /* The number of notReady tables */ - struct SrcList_item *origSrc; /* Original list of tables */ - nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = sqlite3StackAllocRaw(db, - sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); - if( pOrTab==0 ) return notReady; - pOrTab->nAlloc = (u8)(nNotReady + 1); - pOrTab->nSrc = pOrTab->nAlloc; - memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); - origSrc = pWInfo->pTabList->a; - for(k=1; k<=nNotReady; k++){ - memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); - } - }else{ - pOrTab = pWInfo->pTabList; - } - - /* Initialize the rowset register to contain NULL. An SQL NULL is - ** equivalent to an empty rowset. Or, create an ephemeral index - ** capable of holding primary keys in the case of a WITHOUT ROWID. - ** - ** Also initialize regReturn to contain the address of the instruction - ** immediately following the OP_Return at the bottom of the loop. This - ** is required in a few obscure LEFT JOIN cases where control jumps - ** over the top of the loop into the body of it. In this case the - ** correct response for the end-of-loop code (the OP_Return) is to - ** fall through to the next instruction, just as an OP_Next does if - ** called on an uninitialized cursor. - */ - if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - if( HasRowid(pTab) ){ - regRowset = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); - }else{ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - regRowset = pParse->nTab++; - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); - } - regRowid = ++pParse->nMem; - } - iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); - - /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y - ** Then for every term xN, evaluate as the subexpression: xN AND z - ** That way, terms in y that are factored into the disjunction will - ** be picked up by the recursive calls to sqlite3WhereBegin() below. - ** - ** Actually, each subexpression is converted to "xN AND w" where w is - ** the "interesting" terms of z - terms that did not originate in the - ** ON or USING clause of a LEFT JOIN, and terms that are usable as - ** indices. - ** - ** This optimization also only applies if the (x1 OR x2 OR ...) term - ** is not contained in the ON clause of a LEFT JOIN. - ** See ticket http://www.sqlite.org/src/info/f2369304e4 - */ - if( pWC->nTerm>1 ){ - int iTerm; - for(iTerm=0; iTermnTerm; iTerm++){ - Expr *pExpr = pWC->a[iTerm].pExpr; - if( &pWC->a[iTerm] == pTerm ) continue; - if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; - testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); - testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); - if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; - if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; - testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); - pExpr = sqlite3ExprDup(db, pExpr, 0); - pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); - } - if( pAndExpr ){ - pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0); - } - } - - /* Run a separate WHERE clause for each term of the OR clause. After - ** eliminating duplicates from other WHERE clauses, the action for each - ** sub-WHERE clause is to to invoke the main loop body as a subroutine. - */ - wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); - for(ii=0; iinTerm; ii++){ - WhereTerm *pOrTerm = &pOrWc->a[ii]; - if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ - WhereInfo *pSubWInfo; /* Info for single OR-term scan */ - Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ - int jmp1 = 0; /* Address of jump operation */ - if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ - pAndExpr->pLeft = pOrExpr; - pOrExpr = pAndExpr; - } - /* Loop through table entries that match term pOrTerm. */ - WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); - pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, - wctrlFlags, iCovCur); - assert( pSubWInfo || pParse->nErr || db->mallocFailed ); - if( pSubWInfo ){ - WhereLoop *pSubLoop; - int addrExplain = sqlite3WhereExplainOneScan( - pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0 - ); - sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); - - /* This is the sub-WHERE clause body. First skip over - ** duplicate rows from prior sub-WHERE clauses, and record the - ** rowid (or PRIMARY KEY) for the current row so that the same - ** row will be skipped in subsequent sub-WHERE clauses. - */ - if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - int r; - int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); - if( HasRowid(pTab) ){ - r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); - jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, - r,iSet); - VdbeCoverage(v); - }else{ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - int nPk = pPk->nKeyCol; - int iPk; - - /* Read the PK into an array of temp registers. */ - r = sqlite3GetTempRange(pParse, nPk); - for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk); - } - - /* Check if the temp table already contains this key. If so, - ** the row has already been included in the result set and - ** can be ignored (by jumping past the Gosub below). Otherwise, - ** insert the key into the temp table and proceed with processing - ** the row. - ** - ** Use some of the same optimizations as OP_RowSetTest: If iSet - ** is zero, assume that the key cannot already be present in - ** the temp table. And if iSet is -1, assume that there is no - ** need to insert the key into the temp table, as it will never - ** be tested for. */ - if( iSet ){ - jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); - VdbeCoverage(v); - } - if( iSet>=0 ){ - sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); - sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0); - if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - } - - /* Release the array of temp registers */ - sqlite3ReleaseTempRange(pParse, r, nPk); - } - } - - /* Invoke the main loop body as a subroutine */ - sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); - - /* Jump here (skipping the main loop body subroutine) if the - ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ - if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1); - - /* The pSubWInfo->untestedTerms flag means that this OR term - ** contained one or more AND term from a notReady table. The - ** terms from the notReady table could not be tested and will - ** need to be tested later. - */ - if( pSubWInfo->untestedTerms ) untestedTerms = 1; - - /* If all of the OR-connected terms are optimized using the same - ** index, and the index is opened using the same cursor number - ** by each call to sqlite3WhereBegin() made by this loop, it may - ** be possible to use that index as a covering index. - ** - ** If the call to sqlite3WhereBegin() above resulted in a scan that - ** uses an index, and this is either the first OR-connected term - ** processed or the index is the same as that used by all previous - ** terms, set pCov to the candidate covering index. Otherwise, set - ** pCov to NULL to indicate that no candidate covering index will - ** be available. - */ - pSubLoop = pSubWInfo->a[0].pWLoop; - assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); - if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 - && (ii==0 || pSubLoop->u.btree.pIndex==pCov) - && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) - ){ - assert( pSubWInfo->a[0].iIdxCur==iCovCur ); - pCov = pSubLoop->u.btree.pIndex; - }else{ - pCov = 0; - } - - /* Finish the loop through table entries that match term pOrTerm. */ - sqlite3WhereEnd(pSubWInfo); - } - } - } - pLevel->u.pCovidx = pCov; - if( pCov ) pLevel->iIdxCur = iCovCur; - if( pAndExpr ){ - pAndExpr->pLeft = 0; - sqlite3ExprDelete(db, pAndExpr); - } - sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); - sqlite3VdbeGoto(v, pLevel->addrBrk); - sqlite3VdbeResolveLabel(v, iLoopBody); - - if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab); - if( !untestedTerms ) disableTerm(pLevel, pTerm); - }else -#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ - - { - /* Case 6: There is no usable index. We must do a complete - ** scan of the entire table. - */ - static const u8 aStep[] = { OP_Next, OP_Prev }; - static const u8 aStart[] = { OP_Rewind, OP_Last }; - assert( bRev==0 || bRev==1 ); - if( pTabItem->fg.isRecursive ){ - /* Tables marked isRecursive have only a single row that is stored in - ** a pseudo-cursor. No need to Rewind or Next such cursors. */ - pLevel->op = OP_Noop; - }else{ - codeCursorHint(pTabItem, pWInfo, pLevel, 0); - pLevel->op = aStep[bRev]; - pLevel->p1 = iCur; - pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); - VdbeCoverageIf(v, bRev==0); - VdbeCoverageIf(v, bRev!=0); - pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; - } - } - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); -#endif - - /* Insert code to test every subexpression that can be completely - ** computed using the current set of tables. - */ - for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ - Expr *pE; - int skipLikeAddr = 0; - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ - testcase( pWInfo->untestedTerms==0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); - pWInfo->untestedTerms = 1; - continue; - } - pE = pTerm->pExpr; - assert( pE!=0 ); - if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){ - continue; - } - if( pTerm->wtFlags & TERM_LIKECOND ){ - /* If the TERM_LIKECOND flag is set, that means that the range search - ** is sufficient to guarantee that the LIKE operator is true, so we - ** can skip the call to the like(A,B) function. But this only works - ** for strings. So do not skip the call to the function on the pass - ** that compares BLOBs. */ -#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS - continue; -#else - u32 x = pLevel->iLikeRepCntr; - assert( x>0 ); - skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)? OP_IfNot : OP_If, (int)(x>>1)); - VdbeCoverage(v); -#endif - } - sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); - if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); - pTerm->wtFlags |= TERM_CODED; - } - - /* Insert code to test for implied constraints based on transitivity - ** of the "==" operator. - ** - ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" - ** and we are coding the t1 loop and the t2 loop has not yet coded, - ** then we cannot use the "t1.a=t2.b" constraint, but we can code - ** the implied "t1.a=123" constraint. - */ - for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ - Expr *pE, sEAlt; - WhereTerm *pAlt; - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; - if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; - if( pTerm->leftCursor!=iCur ) continue; - if( pLevel->iLeftJoin ) continue; - pE = pTerm->pExpr; - assert( !ExprHasProperty(pE, EP_FromJoin) ); - assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); - pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, - WO_EQ|WO_IN|WO_IS, 0); - if( pAlt==0 ) continue; - if( pAlt->wtFlags & (TERM_CODED) ) continue; - testcase( pAlt->eOperator & WO_EQ ); - testcase( pAlt->eOperator & WO_IS ); - testcase( pAlt->eOperator & WO_IN ); - VdbeModuleComment((v, "begin transitive constraint")); - sEAlt = *pAlt->pExpr; - sEAlt.pLeft = pE->pLeft; - sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); - } - - /* For a LEFT OUTER JOIN, generate code that will record the fact that - ** at least one row of the right table has matched the left table. - */ - if( pLevel->iLeftJoin ){ - pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); - VdbeComment((v, "record LEFT JOIN hit")); - sqlite3ExprCacheClear(pParse); - for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ - assert( pWInfo->untestedTerms ); - continue; - } - assert( pTerm->pExpr ); - sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); - pTerm->wtFlags |= TERM_CODED; - } - } - - return pLevel->notReady; -} - -/************** End of wherecode.c *******************************************/ -/************** Begin file whereexpr.c ***************************************/ -/* -** 2015-06-08 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This module contains C code that generates VDBE code used to process -** the WHERE clause of SQL statements. -** -** This file was originally part of where.c but was split out to improve -** readability and editabiliity. This file contains utility routines for -** analyzing Expr objects in the WHERE clause. -*/ -/* #include "sqliteInt.h" */ -/* #include "whereInt.h" */ - -/* Forward declarations */ -static void exprAnalyze(SrcList*, WhereClause*, int); - -/* -** Deallocate all memory associated with a WhereOrInfo object. -*/ -static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ - sqlite3WhereClauseClear(&p->wc); - sqlite3DbFree(db, p); -} - -/* -** Deallocate all memory associated with a WhereAndInfo object. -*/ -static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ - sqlite3WhereClauseClear(&p->wc); - sqlite3DbFree(db, p); -} - -/* -** Add a single new WhereTerm entry to the WhereClause object pWC. -** The new WhereTerm object is constructed from Expr p and with wtFlags. -** The index in pWC->a[] of the new WhereTerm is returned on success. -** 0 is returned if the new WhereTerm could not be added due to a memory -** allocation error. The memory allocation failure will be recorded in -** the db->mallocFailed flag so that higher-level functions can detect it. -** -** This routine will increase the size of the pWC->a[] array as necessary. -** -** If the wtFlags argument includes TERM_DYNAMIC, then responsibility -** for freeing the expression p is assumed by the WhereClause object pWC. -** This is true even if this routine fails to allocate a new WhereTerm. -** -** WARNING: This routine might reallocate the space used to store -** WhereTerms. All pointers to WhereTerms should be invalidated after -** calling this routine. Such pointers may be reinitialized by referencing -** the pWC->a[] array. -*/ -static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ - WhereTerm *pTerm; - int idx; - testcase( wtFlags & TERM_VIRTUAL ); - if( pWC->nTerm>=pWC->nSlot ){ - WhereTerm *pOld = pWC->a; - sqlite3 *db = pWC->pWInfo->pParse->db; - pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); - if( pWC->a==0 ){ - if( wtFlags & TERM_DYNAMIC ){ - sqlite3ExprDelete(db, p); - } - pWC->a = pOld; - return 0; - } - memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); - if( pOld!=pWC->aStatic ){ - sqlite3DbFree(db, pOld); - } - pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); - } - pTerm = &pWC->a[idx = pWC->nTerm++]; - if( p && ExprHasProperty(p, EP_Unlikely) ){ - pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; - }else{ - pTerm->truthProb = 1; - } - pTerm->pExpr = sqlite3ExprSkipCollate(p); - pTerm->wtFlags = wtFlags; - pTerm->pWC = pWC; - pTerm->iParent = -1; - memset(&pTerm->eOperator, 0, - sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); - return idx; -} - -/* -** Return TRUE if the given operator is one of the operators that is -** allowed for an indexable WHERE clause term. The allowed operators are -** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" -*/ -static int allowedOp(int op){ - assert( TK_GT>TK_EQ && TK_GTTK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; -} - -/* -** Commute a comparison operator. Expressions of the form "X op Y" -** are converted into "Y op X". -** -** If left/right precedence rules come into play when determining the -** collating sequence, then COLLATE operators are adjusted to ensure -** that the collating sequence does not change. For example: -** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on -** the left hand side of a comparison overrides any collation sequence -** attached to the right. For the same reason the EP_Collate flag -** is not commuted. -*/ -static void exprCommute(Parse *pParse, Expr *pExpr){ - u16 expRight = (pExpr->pRight->flags & EP_Collate); - u16 expLeft = (pExpr->pLeft->flags & EP_Collate); - assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); - if( expRight==expLeft ){ - /* Either X and Y both have COLLATE operator or neither do */ - if( expRight ){ - /* Both X and Y have COLLATE operators. Make sure X is always - ** used by clearing the EP_Collate flag from Y. */ - pExpr->pRight->flags &= ~EP_Collate; - }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ - /* Neither X nor Y have COLLATE operators, but X has a non-default - ** collating sequence. So add the EP_Collate marker on X to cause - ** it to be searched first. */ - pExpr->pLeft->flags |= EP_Collate; - } - } - SWAP(Expr*,pExpr->pRight,pExpr->pLeft); - if( pExpr->op>=TK_GT ){ - assert( TK_LT==TK_GT+2 ); - assert( TK_GE==TK_LE+2 ); - assert( TK_GT>TK_EQ ); - assert( TK_GTop>=TK_GT && pExpr->op<=TK_GE ); - pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; - } -} - -/* -** Translate from TK_xx operator to WO_xx bitmask. -*/ -static u16 operatorMask(int op){ - u16 c; - assert( allowedOp(op) ); - if( op==TK_IN ){ - c = WO_IN; - }else if( op==TK_ISNULL ){ - c = WO_ISNULL; - }else if( op==TK_IS ){ - c = WO_IS; - }else{ - assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); - c = (u16)(WO_EQ<<(op-TK_EQ)); - } - assert( op!=TK_ISNULL || c==WO_ISNULL ); - assert( op!=TK_IN || c==WO_IN ); - assert( op!=TK_EQ || c==WO_EQ ); - assert( op!=TK_LT || c==WO_LT ); - assert( op!=TK_LE || c==WO_LE ); - assert( op!=TK_GT || c==WO_GT ); - assert( op!=TK_GE || c==WO_GE ); - assert( op!=TK_IS || c==WO_IS ); - return c; -} - - -#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION -/* -** Check to see if the given expression is a LIKE or GLOB operator that -** can be optimized using inequality constraints. Return TRUE if it is -** so and false if not. -** -** In order for the operator to be optimizible, the RHS must be a string -** literal that does not begin with a wildcard. The LHS must be a column -** that may only be NULL, a string, or a BLOB, never a number. (This means -** that virtual tables cannot participate in the LIKE optimization.) The -** collating sequence for the column on the LHS must be appropriate for -** the operator. -*/ -static int isLikeOrGlob( - Parse *pParse, /* Parsing and code generating context */ - Expr *pExpr, /* Test this expression */ - Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */ - int *pisComplete, /* True if the only wildcard is % in the last character */ - int *pnoCase /* True if uppercase is equivalent to lowercase */ -){ - const char *z = 0; /* String on RHS of LIKE operator */ - Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ - ExprList *pList; /* List of operands to the LIKE operator */ - int c; /* One character in z[] */ - int cnt; /* Number of non-wildcard prefix characters */ - char wc[3]; /* Wildcard characters */ - sqlite3 *db = pParse->db; /* Database connection */ - sqlite3_value *pVal = 0; - int op; /* Opcode of pRight */ - int rc; /* Result code to return */ - - if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ - return 0; - } -#ifdef SQLITE_EBCDIC - if( *pnoCase ) return 0; -#endif - pList = pExpr->x.pList; - pLeft = pList->a[1].pExpr; - if( pLeft->op!=TK_COLUMN - || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) /* Value might be numeric */ - ){ - /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must - ** be the name of an indexed column with TEXT affinity. */ - return 0; - } - assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ - - pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); - op = pRight->op; - if( op==TK_VARIABLE ){ - Vdbe *pReprepare = pParse->pReprepare; - int iCol = pRight->iColumn; - pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); - if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ - z = (char *)sqlite3_value_text(pVal); - } - sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); - assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); - }else if( op==TK_STRING ){ - z = pRight->u.zToken; - } - if( z ){ - cnt = 0; - while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ - cnt++; - } - if( cnt!=0 && 255!=(u8)z[cnt-1] ){ - Expr *pPrefix; - *pisComplete = c==wc[0] && z[cnt+1]==0; - pPrefix = sqlite3Expr(db, TK_STRING, z); - if( pPrefix ) pPrefix->u.zToken[cnt] = 0; - *ppPrefix = pPrefix; - if( op==TK_VARIABLE ){ - Vdbe *v = pParse->pVdbe; - sqlite3VdbeSetVarmask(v, pRight->iColumn); - if( *pisComplete && pRight->u.zToken[1] ){ - /* If the rhs of the LIKE expression is a variable, and the current - ** value of the variable means there is no need to invoke the LIKE - ** function, then no OP_Variable will be added to the program. - ** This causes problems for the sqlite3_bind_parameter_name() - ** API. To work around them, add a dummy OP_Variable here. - */ - int r1 = sqlite3GetTempReg(pParse); - sqlite3ExprCodeTarget(pParse, pRight, r1); - sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); - sqlite3ReleaseTempReg(pParse, r1); - } - } - }else{ - z = 0; - } - } - - rc = (z!=0); - sqlite3ValueFree(pVal); - return rc; -} -#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ - - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* -** Check to see if the given expression is of the form -** -** column OP expr -** -** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a -** column of a virtual table. -** -** If it is then return TRUE. If not, return FALSE. -*/ -static int isMatchOfColumn( - Expr *pExpr, /* Test this expression */ - unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */ -){ - static const struct Op2 { - const char *zOp; - unsigned char eOp2; - } aOp[] = { - { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, - { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, - { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, - { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } - }; - ExprList *pList; - Expr *pCol; /* Column reference */ - int i; - - if( pExpr->op!=TK_FUNCTION ){ - return 0; - } - pList = pExpr->x.pList; - if( pList==0 || pList->nExpr!=2 ){ - return 0; - } - pCol = pList->a[1].pExpr; - if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ - return 0; - } - for(i=0; iu.zToken, aOp[i].zOp)==0 ){ - *peOp2 = aOp[i].eOp2; - return 1; - } - } - return 0; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/* -** If the pBase expression originated in the ON or USING clause of -** a join, then transfer the appropriate markings over to derived. -*/ -static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ - if( pDerived ){ - pDerived->flags |= pBase->flags & EP_FromJoin; - pDerived->iRightJoinTable = pBase->iRightJoinTable; - } -} - -/* -** Mark term iChild as being a child of term iParent -*/ -static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ - pWC->a[iChild].iParent = iParent; - pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; - pWC->a[iParent].nChild++; -} - -/* -** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not -** a conjunction, then return just pTerm when N==0. If N is exceeds -** the number of available subterms, return NULL. -*/ -static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ - if( pTerm->eOperator!=WO_AND ){ - return N==0 ? pTerm : 0; - } - if( Nu.pAndInfo->wc.nTerm ){ - return &pTerm->u.pAndInfo->wc.a[N]; - } - return 0; -} - -/* -** Subterms pOne and pTwo are contained within WHERE clause pWC. The -** two subterms are in disjunction - they are OR-ed together. -** -** If these two terms are both of the form: "A op B" with the same -** A and B values but different operators and if the operators are -** compatible (if one is = and the other is <, for example) then -** add a new virtual AND term to pWC that is the combination of the -** two. -** -** Some examples: -** -** x x<=y -** x=y OR x=y --> x=y -** x<=y OR x x<=y -** -** The following is NOT generated: -** -** xy --> x!=y -*/ -static void whereCombineDisjuncts( - SrcList *pSrc, /* the FROM clause */ - WhereClause *pWC, /* The complete WHERE clause */ - WhereTerm *pOne, /* First disjunct */ - WhereTerm *pTwo /* Second disjunct */ -){ - u16 eOp = pOne->eOperator | pTwo->eOperator; - sqlite3 *db; /* Database connection (for malloc) */ - Expr *pNew; /* New virtual expression */ - int op; /* Operator for the combined expression */ - int idxNew; /* Index in pWC of the next virtual term */ - - if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; - if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; - if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp - && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; - assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); - assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); - if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; - if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return; - /* If we reach this point, it means the two subterms can be combined */ - if( (eOp & (eOp-1))!=0 ){ - if( eOp & (WO_LT|WO_LE) ){ - eOp = WO_LE; - }else{ - assert( eOp & (WO_GT|WO_GE) ); - eOp = WO_GE; - } - } - db = pWC->pWInfo->pParse->db; - pNew = sqlite3ExprDup(db, pOne->pExpr, 0); - if( pNew==0 ) return; - for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; - idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); - exprAnalyze(pSrc, pWC, idxNew); -} - -#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) -/* -** Analyze a term that consists of two or more OR-connected -** subterms. So in: -** -** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13) -** ^^^^^^^^^^^^^^^^^^^^ -** -** This routine analyzes terms such as the middle term in the above example. -** A WhereOrTerm object is computed and attached to the term under -** analysis, regardless of the outcome of the analysis. Hence: -** -** WhereTerm.wtFlags |= TERM_ORINFO -** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object -** -** The term being analyzed must have two or more of OR-connected subterms. -** A single subterm might be a set of AND-connected sub-subterms. -** Examples of terms under analysis: -** -** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5 -** (B) x=expr1 OR expr2=x OR x=expr3 -** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) -** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') -** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) -** (F) x>A OR (x=A AND y>=B) -** -** CASE 1: -** -** If all subterms are of the form T.C=expr for some single column of C and -** a single table T (as shown in example B above) then create a new virtual -** term that is an equivalent IN expression. In other words, if the term -** being analyzed is: -** -** x = expr1 OR expr2 = x OR x = expr3 -** -** then create a new virtual term like this: -** -** x IN (expr1,expr2,expr3) -** -** CASE 2: -** -** If there are exactly two disjuncts and one side has x>A and the other side -** has x=A (for the same x and A) then add a new virtual conjunct term to the -** WHERE clause of the form "x>=A". Example: -** -** x>A OR (x=A AND y>B) adds: x>=A -** -** The added conjunct can sometimes be helpful in query planning. -** -** CASE 3: -** -** If all subterms are indexable by a single table T, then set -** -** WhereTerm.eOperator = WO_OR -** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T -** -** A subterm is "indexable" if it is of the form -** "T.C " where C is any column of table T and -** is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". -** A subterm is also indexable if it is an AND of two or more -** subsubterms at least one of which is indexable. Indexable AND -** subterms have their eOperator set to WO_AND and they have -** u.pAndInfo set to a dynamically allocated WhereAndTerm object. -** -** From another point of view, "indexable" means that the subterm could -** potentially be used with an index if an appropriate index exists. -** This analysis does not consider whether or not the index exists; that -** is decided elsewhere. This analysis only looks at whether subterms -** appropriate for indexing exist. -** -** All examples A through E above satisfy case 3. But if a term -** also satisfies case 1 (such as B) we know that the optimizer will -** always prefer case 1, so in that case we pretend that case 3 is not -** satisfied. -** -** It might be the case that multiple tables are indexable. For example, -** (E) above is indexable on tables P, Q, and R. -** -** Terms that satisfy case 3 are candidates for lookup by using -** separate indices to find rowids for each subterm and composing -** the union of all rowids using a RowSet object. This is similar -** to "bitmap indices" in other database engines. -** -** OTHERWISE: -** -** If none of cases 1, 2, or 3 apply, then leave the eOperator set to -** zero. This term is not useful for search. -*/ -static void exprAnalyzeOrTerm( - SrcList *pSrc, /* the FROM clause */ - WhereClause *pWC, /* the complete WHERE clause */ - int idxTerm /* Index of the OR-term to be analyzed */ -){ - WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ - Parse *pParse = pWInfo->pParse; /* Parser context */ - sqlite3 *db = pParse->db; /* Database connection */ - WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ - Expr *pExpr = pTerm->pExpr; /* The expression of the term */ - int i; /* Loop counters */ - WhereClause *pOrWc; /* Breakup of pTerm into subterms */ - WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */ - WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */ - Bitmask chngToIN; /* Tables that might satisfy case 1 */ - Bitmask indexable; /* Tables that are indexable, satisfying case 2 */ - - /* - ** Break the OR clause into its separate subterms. The subterms are - ** stored in a WhereClause structure containing within the WhereOrInfo - ** object that is attached to the original OR clause term. - */ - assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); - assert( pExpr->op==TK_OR ); - pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); - if( pOrInfo==0 ) return; - pTerm->wtFlags |= TERM_ORINFO; - pOrWc = &pOrInfo->wc; - memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic)); - sqlite3WhereClauseInit(pOrWc, pWInfo); - sqlite3WhereSplit(pOrWc, pExpr, TK_OR); - sqlite3WhereExprAnalyze(pSrc, pOrWc); - if( db->mallocFailed ) return; - assert( pOrWc->nTerm>=2 ); - - /* - ** Compute the set of tables that might satisfy cases 1 or 3. - */ - indexable = ~(Bitmask)0; - chngToIN = ~(Bitmask)0; - for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ - if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ - WhereAndInfo *pAndInfo; - assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); - chngToIN = 0; - pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); - if( pAndInfo ){ - WhereClause *pAndWC; - WhereTerm *pAndTerm; - int j; - Bitmask b = 0; - pOrTerm->u.pAndInfo = pAndInfo; - pOrTerm->wtFlags |= TERM_ANDINFO; - pOrTerm->eOperator = WO_AND; - pAndWC = &pAndInfo->wc; - memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic)); - sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); - sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); - sqlite3WhereExprAnalyze(pSrc, pAndWC); - pAndWC->pOuter = pWC; - if( !db->mallocFailed ){ - for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ - assert( pAndTerm->pExpr ); - if( allowedOp(pAndTerm->pExpr->op) - || pAndTerm->eOperator==WO_MATCH - ){ - b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); - } - } - } - indexable &= b; - } - }else if( pOrTerm->wtFlags & TERM_COPIED ){ - /* Skip this term for now. We revisit it when we process the - ** corresponding TERM_VIRTUAL term */ - }else{ - Bitmask b; - b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); - if( pOrTerm->wtFlags & TERM_VIRTUAL ){ - WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; - b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor); - } - indexable &= b; - if( (pOrTerm->eOperator & WO_EQ)==0 ){ - chngToIN = 0; - }else{ - chngToIN &= b; - } - } - } - - /* - ** Record the set of tables that satisfy case 3. The set might be - ** empty. - */ - pOrInfo->indexable = indexable; - pTerm->eOperator = indexable==0 ? 0 : WO_OR; - - /* For a two-way OR, attempt to implementation case 2. - */ - if( indexable && pOrWc->nTerm==2 ){ - int iOne = 0; - WhereTerm *pOne; - while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ - int iTwo = 0; - WhereTerm *pTwo; - while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ - whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); - } - } - } - - /* - ** chngToIN holds a set of tables that *might* satisfy case 1. But - ** we have to do some additional checking to see if case 1 really - ** is satisfied. - ** - ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means - ** that there is no possibility of transforming the OR clause into an - ** IN operator because one or more terms in the OR clause contain - ** something other than == on a column in the single table. The 1-bit - ** case means that every term of the OR clause is of the form - ** "table.column=expr" for some single table. The one bit that is set - ** will correspond to the common table. We still need to check to make - ** sure the same column is used on all terms. The 2-bit case is when - ** the all terms are of the form "table1.column=table2.column". It - ** might be possible to form an IN operator with either table1.column - ** or table2.column as the LHS if either is common to every term of - ** the OR clause. - ** - ** Note that terms of the form "table.column1=table.column2" (the - ** same table on both sizes of the ==) cannot be optimized. - */ - if( chngToIN ){ - int okToChngToIN = 0; /* True if the conversion to IN is valid */ - int iColumn = -1; /* Column index on lhs of IN operator */ - int iCursor = -1; /* Table cursor common to all terms */ - int j = 0; /* Loop counter */ - - /* Search for a table and column that appears on one side or the - ** other of the == operator in every subterm. That table and column - ** will be recorded in iCursor and iColumn. There might not be any - ** such table and column. Set okToChngToIN if an appropriate table - ** and column is found but leave okToChngToIN false if not found. - */ - for(j=0; j<2 && !okToChngToIN; j++){ - pOrTerm = pOrWc->a; - for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ - assert( pOrTerm->eOperator & WO_EQ ); - pOrTerm->wtFlags &= ~TERM_OR_OK; - if( pOrTerm->leftCursor==iCursor ){ - /* This is the 2-bit case and we are on the second iteration and - ** current term is from the first iteration. So skip this term. */ - assert( j==1 ); - continue; - } - if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, - pOrTerm->leftCursor))==0 ){ - /* This term must be of the form t1.a==t2.b where t2 is in the - ** chngToIN set but t1 is not. This term will be either preceded - ** or follwed by an inverted copy (t2.b==t1.a). Skip this term - ** and use its inversion. */ - testcase( pOrTerm->wtFlags & TERM_COPIED ); - testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); - assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); - continue; - } - iColumn = pOrTerm->u.leftColumn; - iCursor = pOrTerm->leftCursor; - break; - } - if( i<0 ){ - /* No candidate table+column was found. This can only occur - ** on the second iteration */ - assert( j==1 ); - assert( IsPowerOfTwo(chngToIN) ); - assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); - break; - } - testcase( j==1 ); - - /* We have found a candidate table and column. Check to see if that - ** table and column is common to every term in the OR clause */ - okToChngToIN = 1; - for(; i>=0 && okToChngToIN; i--, pOrTerm++){ - assert( pOrTerm->eOperator & WO_EQ ); - if( pOrTerm->leftCursor!=iCursor ){ - pOrTerm->wtFlags &= ~TERM_OR_OK; - }else if( pOrTerm->u.leftColumn!=iColumn ){ - okToChngToIN = 0; - }else{ - int affLeft, affRight; - /* If the right-hand side is also a column, then the affinities - ** of both right and left sides must be such that no type - ** conversions are required on the right. (Ticket #2249) - */ - affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); - affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); - if( affRight!=0 && affRight!=affLeft ){ - okToChngToIN = 0; - }else{ - pOrTerm->wtFlags |= TERM_OR_OK; - } - } - } - } - - /* At this point, okToChngToIN is true if original pTerm satisfies - ** case 1. In that case, construct a new virtual term that is - ** pTerm converted into an IN operator. - */ - if( okToChngToIN ){ - Expr *pDup; /* A transient duplicate expression */ - ExprList *pList = 0; /* The RHS of the IN operator */ - Expr *pLeft = 0; /* The LHS of the IN operator */ - Expr *pNew; /* The complete IN operator */ - - for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ - if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; - assert( pOrTerm->eOperator & WO_EQ ); - assert( pOrTerm->leftCursor==iCursor ); - assert( pOrTerm->u.leftColumn==iColumn ); - pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); - pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); - pLeft = pOrTerm->pExpr->pLeft; - } - assert( pLeft!=0 ); - pDup = sqlite3ExprDup(db, pLeft, 0); - pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0); - if( pNew ){ - int idxNew; - transferJoinMarkings(pNew, pExpr); - assert( !ExprHasProperty(pNew, EP_xIsSelect) ); - pNew->x.pList = pList; - idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - exprAnalyze(pSrc, pWC, idxNew); - pTerm = &pWC->a[idxTerm]; - markTermAsChild(pWC, idxNew, idxTerm); - }else{ - sqlite3ExprListDelete(db, pList); - } - pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */ - } - } -} -#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ - -/* -** We already know that pExpr is a binary operator where both operands are -** column references. This routine checks to see if pExpr is an equivalence -** relation: -** 1. The SQLITE_Transitive optimization must be enabled -** 2. Must be either an == or an IS operator -** 3. Not originating in the ON clause of an OUTER JOIN -** 4. The affinities of A and B must be compatible -** 5a. Both operands use the same collating sequence OR -** 5b. The overall collating sequence is BINARY -** If this routine returns TRUE, that means that the RHS can be substituted -** for the LHS anyplace else in the WHERE clause where the LHS column occurs. -** This is an optimization. No harm comes from returning 0. But if 1 is -** returned when it should not be, then incorrect answers might result. -*/ -static int termIsEquivalence(Parse *pParse, Expr *pExpr){ - char aff1, aff2; - CollSeq *pColl; - const char *zColl1, *zColl2; - if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; - if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; - if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; - aff1 = sqlite3ExprAffinity(pExpr->pLeft); - aff2 = sqlite3ExprAffinity(pExpr->pRight); - if( aff1!=aff2 - && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) - ){ - return 0; - } - pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); - if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1; - pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - zColl1 = pColl ? pColl->zName : 0; - pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight); - zColl2 = pColl ? pColl->zName : 0; - return sqlite3_stricmp(zColl1, zColl2)==0; -} - -/* -** Recursively walk the expressions of a SELECT statement and generate -** a bitmask indicating which tables are used in that expression -** tree. -*/ -static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ - Bitmask mask = 0; - while( pS ){ - SrcList *pSrc = pS->pSrc; - mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList); - mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); - mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); - mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); - mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); - if( ALWAYS(pSrc!=0) ){ - int i; - for(i=0; inSrc; i++){ - mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); - mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); - } - } - pS = pS->pPrior; - } - return mask; -} - -/* -** Expression pExpr is one operand of a comparison operator that might -** be useful for indexing. This routine checks to see if pExpr appears -** in any index. Return TRUE (1) if pExpr is an indexed term and return -** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor -** number of the table that is indexed and *piColumn to the column number -** of the column that is indexed, or XN_EXPR (-2) if an expression is being -** indexed. -** -** If pExpr is a TK_COLUMN column reference, then this routine always returns -** true even if that particular column is not indexed, because the column -** might be added to an automatic index later. -*/ -static int exprMightBeIndexed( - SrcList *pFrom, /* The FROM clause */ - int op, /* The specific comparison operator */ - Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ - Expr *pExpr, /* An operand of a comparison operator */ - int *piCur, /* Write the referenced table cursor number here */ - int *piColumn /* Write the referenced table column number here */ -){ - Index *pIdx; - int i; - int iCur; - - /* If this expression is a vector to the left or right of a - ** inequality constraint (>, <, >= or <=), perform the processing - ** on the first element of the vector. */ - assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); - assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ - pExpr = pExpr->x.pList->a[0].pExpr; - } - - if( pExpr->op==TK_COLUMN ){ - *piCur = pExpr->iTable; - *piColumn = pExpr->iColumn; - return 1; - } - if( mPrereq==0 ) return 0; /* No table references */ - if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */ - for(i=0; mPrereq>1; i++, mPrereq>>=1){} - iCur = pFrom->a[i].iCursor; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->aColExpr==0 ) continue; - for(i=0; inKeyCol; i++){ - if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ - *piCur = iCur; - *piColumn = XN_EXPR; - return 1; - } - } - } - return 0; -} - -/* -** The input to this routine is an WhereTerm structure with only the -** "pExpr" field filled in. The job of this routine is to analyze the -** subexpression and populate all the other fields of the WhereTerm -** structure. -** -** If the expression is of the form " X" it gets commuted -** to the standard form of "X ". -** -** If the expression is of the form "X Y" where both X and Y are -** columns, then the original expression is unchanged and a new virtual -** term of the form "Y X" is added to the WHERE clause and -** analyzed separately. The original term is marked with TERM_COPIED -** and the new term is marked with TERM_DYNAMIC (because it's pExpr -** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it -** is a commuted copy of a prior term.) The original term has nChild=1 -** and the copy has idxParent set to the index of the original term. -*/ -static void exprAnalyze( - SrcList *pSrc, /* the FROM clause */ - WhereClause *pWC, /* the WHERE clause */ - int idxTerm /* Index of the term to be analyzed */ -){ - WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ - WhereTerm *pTerm; /* The term to be analyzed */ - WhereMaskSet *pMaskSet; /* Set of table index masks */ - Expr *pExpr; /* The expression to be analyzed */ - Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ - Bitmask prereqAll; /* Prerequesites of pExpr */ - Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ - Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ - int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ - int noCase = 0; /* uppercase equivalent to lowercase */ - int op; /* Top-level operator. pExpr->op */ - Parse *pParse = pWInfo->pParse; /* Parsing context */ - sqlite3 *db = pParse->db; /* Database connection */ - unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */ - - if( db->mallocFailed ){ - return; - } - pTerm = &pWC->a[idxTerm]; - pMaskSet = &pWInfo->sMaskSet; - pExpr = pTerm->pExpr; - assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); - prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); - op = pExpr->op; - if( op==TK_IN ){ - assert( pExpr->pRight==0 ); - if( sqlite3ExprCheckIN(pParse, pExpr) ) return; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); - }else{ - pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); - } - }else if( op==TK_ISNULL ){ - pTerm->prereqRight = 0; - }else{ - pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); - } - prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); - if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); - prereqAll |= x; - extraRight = x-1; /* ON clause terms may not be used with an index - ** on left table of a LEFT JOIN. Ticket #3015 */ - } - pTerm->prereqAll = prereqAll; - pTerm->leftCursor = -1; - pTerm->iParent = -1; - pTerm->eOperator = 0; - if( allowedOp(op) ){ - int iCur, iColumn; - Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); - Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); - u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; - - if( pTerm->iField>0 ){ - assert( op==TK_IN ); - assert( pLeft->op==TK_VECTOR ); - pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; - } - - if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){ - pTerm->leftCursor = iCur; - pTerm->u.leftColumn = iColumn; - pTerm->eOperator = operatorMask(op) & opMask; - } - if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; - if( pRight - && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn) - ){ - WhereTerm *pNew; - Expr *pDup; - u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ - assert( pTerm->iField==0 ); - if( pTerm->leftCursor>=0 ){ - int idxNew; - pDup = sqlite3ExprDup(db, pExpr, 0); - if( db->mallocFailed ){ - sqlite3ExprDelete(db, pDup); - return; - } - idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); - if( idxNew==0 ) return; - pNew = &pWC->a[idxNew]; - markTermAsChild(pWC, idxNew, idxTerm); - if( op==TK_IS ) pNew->wtFlags |= TERM_IS; - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - - if( termIsEquivalence(pParse, pDup) ){ - pTerm->eOperator |= WO_EQUIV; - eExtraOp = WO_EQUIV; - } - }else{ - pDup = pExpr; - pNew = pTerm; - } - exprCommute(pParse, pDup); - pNew->leftCursor = iCur; - pNew->u.leftColumn = iColumn; - testcase( (prereqLeft | extraRight) != prereqLeft ); - pNew->prereqRight = prereqLeft | extraRight; - pNew->prereqAll = prereqAll; - pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; - } - } - -#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION - /* If a term is the BETWEEN operator, create two new virtual terms - ** that define the range that the BETWEEN implements. For example: - ** - ** a BETWEEN b AND c - ** - ** is converted into: - ** - ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c) - ** - ** The two new terms are added onto the end of the WhereClause object. - ** The new terms are "dynamic" and are children of the original BETWEEN - ** term. That means that if the BETWEEN term is coded, the children are - ** skipped. Or, if the children are satisfied by an index, the original - ** BETWEEN term is skipped. - */ - else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ - ExprList *pList = pExpr->x.pList; - int i; - static const u8 ops[] = {TK_GE, TK_LE}; - assert( pList!=0 ); - assert( pList->nExpr==2 ); - for(i=0; i<2; i++){ - Expr *pNewExpr; - int idxNew; - pNewExpr = sqlite3PExpr(pParse, ops[i], - sqlite3ExprDup(db, pExpr->pLeft, 0), - sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0); - transferJoinMarkings(pNewExpr, pExpr); - idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - exprAnalyze(pSrc, pWC, idxNew); - pTerm = &pWC->a[idxTerm]; - markTermAsChild(pWC, idxNew, idxTerm); - } - } -#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ - -#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) - /* Analyze a term that is composed of two or more subterms connected by - ** an OR operator. - */ - else if( pExpr->op==TK_OR ){ - assert( pWC->op==TK_AND ); - exprAnalyzeOrTerm(pSrc, pWC, idxTerm); - pTerm = &pWC->a[idxTerm]; - } -#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ - -#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION - /* Add constraints to reduce the search space on a LIKE or GLOB - ** operator. - ** - ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints - ** - ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' - ** - ** The last character of the prefix "abc" is incremented to form the - ** termination condition "abd". If case is not significant (the default - ** for LIKE) then the lower-bound is made all uppercase and the upper- - ** bound is made all lowercase so that the bounds also work when comparing - ** BLOBs. - */ - if( pWC->op==TK_AND - && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) - ){ - Expr *pLeft; /* LHS of LIKE/GLOB operator */ - Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */ - Expr *pNewExpr1; - Expr *pNewExpr2; - int idxNew1; - int idxNew2; - const char *zCollSeqName; /* Name of collating sequence */ - const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; - - pLeft = pExpr->x.pList->a[1].pExpr; - pStr2 = sqlite3ExprDup(db, pStr1, 0); - - /* Convert the lower bound to upper-case and the upper bound to - ** lower-case (upper-case is less than lower-case in ASCII) so that - ** the range constraints also work for BLOBs - */ - if( noCase && !pParse->db->mallocFailed ){ - int i; - char c; - pTerm->wtFlags |= TERM_LIKE; - for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ - pStr1->u.zToken[i] = sqlite3Toupper(c); - pStr2->u.zToken[i] = sqlite3Tolower(c); - } - } - - if( !db->mallocFailed ){ - u8 c, *pC; /* Last character before the first wildcard */ - pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; - c = *pC; - if( noCase ){ - /* The point is to increment the last character before the first - ** wildcard. But if we increment '@', that will push it into the - ** alphabetic range where case conversions will mess up the - ** inequality. To avoid this, make sure to also run the full - ** LIKE on all candidate expressions by clearing the isComplete flag - */ - if( c=='A'-1 ) isComplete = 0; - c = sqlite3UpperToLower[c]; - } - *pC = c + 1; - } - zCollSeqName = noCase ? "NOCASE" : "BINARY"; - pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); - pNewExpr1 = sqlite3PExpr(pParse, TK_GE, - sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), - pStr1, 0); - transferJoinMarkings(pNewExpr1, pExpr); - idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); - testcase( idxNew1==0 ); - exprAnalyze(pSrc, pWC, idxNew1); - pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); - pNewExpr2 = sqlite3PExpr(pParse, TK_LT, - sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), - pStr2, 0); - transferJoinMarkings(pNewExpr2, pExpr); - idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); - testcase( idxNew2==0 ); - exprAnalyze(pSrc, pWC, idxNew2); - pTerm = &pWC->a[idxTerm]; - if( isComplete ){ - markTermAsChild(pWC, idxNew1, idxTerm); - markTermAsChild(pWC, idxNew2, idxTerm); - } - } -#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Add a WO_MATCH auxiliary term to the constraint set if the - ** current expression is of the form: column MATCH expr. - ** This information is used by the xBestIndex methods of - ** virtual tables. The native query optimizer does not attempt - ** to do anything with MATCH functions. - */ - if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){ - int idxNew; - Expr *pRight, *pLeft; - WhereTerm *pNewTerm; - Bitmask prereqColumn, prereqExpr; - - pRight = pExpr->x.pList->a[0].pExpr; - pLeft = pExpr->x.pList->a[1].pExpr; - prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); - prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); - if( (prereqExpr & prereqColumn)==0 ){ - Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, - 0, sqlite3ExprDup(db, pRight, 0), 0); - idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = prereqExpr; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_MATCH; - pNewTerm->eMatchOp = eOp2; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; - } - } -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - - /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create - ** new terms for each component comparison - "a = ?" and "b = ?". The - ** new terms completely replace the original vector comparison, which is - ** no longer used. - ** - ** This is only required if at least one side of the comparison operation - ** is not a sub-select. */ - if( pWC->op==TK_AND - && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && sqlite3ExprIsVector(pExpr->pLeft) - && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 - || (pExpr->pRight->flags & EP_xIsSelect)==0 - )){ - int nLeft = sqlite3ExprVectorSize(pExpr->pLeft); - int i; - assert( nLeft==sqlite3ExprVectorSize(pExpr->pRight) ); - for(i=0; ipLeft, i); - Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); - - pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight, 0); - transferJoinMarkings(pNew, pExpr); - idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); - exprAnalyze(pSrc, pWC, idxNew); - } - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */ - pTerm->eOperator = 0; - } - - /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create - ** a virtual term for each vector component. The expression object - ** used by each such virtual term is pExpr (the full vector IN(...) - ** expression). The WhereTerm.iField variable identifies the index within - ** the vector on the LHS that the virtual term represents. - ** - ** This only works if the RHS is a simple SELECT, not a compound - */ - if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 - && pExpr->pLeft->op==TK_VECTOR - && pExpr->x.pSelect->pPrior==0 - ){ - int i; - for(i=0; ipLeft); i++){ - int idxNew; - idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); - pWC->a[idxNew].iField = i+1; - exprAnalyze(pSrc, pWC, idxNew); - markTermAsChild(pWC, idxNew, idxTerm); - } - } - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - /* When sqlite_stat3 histogram data is available an operator of the - ** form "x IS NOT NULL" can sometimes be evaluated more efficiently - ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a - ** virtual term of that form. - ** - ** Note that the virtual term must be tagged with TERM_VNULL. - */ - if( pExpr->op==TK_NOTNULL - && pExpr->pLeft->op==TK_COLUMN - && pExpr->pLeft->iColumn>=0 - && OptimizationEnabled(db, SQLITE_Stat34) - ){ - Expr *pNewExpr; - Expr *pLeft = pExpr->pLeft; - int idxNew; - WhereTerm *pNewTerm; - - pNewExpr = sqlite3PExpr(pParse, TK_GT, - sqlite3ExprDup(db, pLeft, 0), - sqlite3ExprAlloc(db, TK_NULL, 0, 0), 0); - - idxNew = whereClauseInsert(pWC, pNewExpr, - TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); - if( idxNew ){ - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = 0; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_GT; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; - } - } -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - - /* Prevent ON clause terms of a LEFT JOIN from being used to drive - ** an index for tables to the left of the join. - */ - pTerm->prereqRight |= extraRight; -} - -/*************************************************************************** -** Routines with file scope above. Interface to the rest of the where.c -** subsystem follows. -***************************************************************************/ - -/* -** This routine identifies subexpressions in the WHERE clause where -** each subexpression is separated by the AND operator or some other -** operator specified in the op parameter. The WhereClause structure -** is filled with pointers to subexpressions. For example: -** -** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22) -** \________/ \_______________/ \________________/ -** slot[0] slot[1] slot[2] -** -** The original WHERE clause in pExpr is unaltered. All this routine -** does is make slot[] entries point to substructure within pExpr. -** -** In the previous sentence and in the diagram, "slot[]" refers to -** the WhereClause.a[] array. The slot[] array grows as needed to contain -** all terms of the WHERE clause. -*/ -SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ - Expr *pE2 = sqlite3ExprSkipCollate(pExpr); - pWC->op = op; - if( pE2==0 ) return; - if( pE2->op!=op ){ - whereClauseInsert(pWC, pExpr, 0); - }else{ - sqlite3WhereSplit(pWC, pE2->pLeft, op); - sqlite3WhereSplit(pWC, pE2->pRight, op); - } -} - -/* -** Initialize a preallocated WhereClause structure. -*/ -SQLITE_PRIVATE void sqlite3WhereClauseInit( - WhereClause *pWC, /* The WhereClause to be initialized */ - WhereInfo *pWInfo /* The WHERE processing context */ -){ - pWC->pWInfo = pWInfo; - pWC->pOuter = 0; - pWC->nTerm = 0; - pWC->nSlot = ArraySize(pWC->aStatic); - pWC->a = pWC->aStatic; -} - -/* -** Deallocate a WhereClause structure. The WhereClause structure -** itself is not freed. This routine is the inverse of -** sqlite3WhereClauseInit(). -*/ -SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ - int i; - WhereTerm *a; - sqlite3 *db = pWC->pWInfo->pParse->db; - for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ - if( a->wtFlags & TERM_DYNAMIC ){ - sqlite3ExprDelete(db, a->pExpr); - } - if( a->wtFlags & TERM_ORINFO ){ - whereOrInfoDelete(db, a->u.pOrInfo); - }else if( a->wtFlags & TERM_ANDINFO ){ - whereAndInfoDelete(db, a->u.pAndInfo); - } - } - if( pWC->a!=pWC->aStatic ){ - sqlite3DbFree(db, pWC->a); - } -} - - -/* -** These routines walk (recursively) an expression tree and generate -** a bitmask indicating which tables are used in that expression -** tree. -*/ -SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ - Bitmask mask; - if( p==0 ) return 0; - if( p->op==TK_COLUMN ){ - mask = sqlite3WhereGetMask(pMaskSet, p->iTable); - return mask; - } - assert( !ExprHasProperty(p, EP_TokenOnly) ); - mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0; - if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); - if( ExprHasProperty(p, EP_xIsSelect) ){ - mask |= exprSelectUsage(pMaskSet, p->x.pSelect); - }else if( p->x.pList ){ - mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); - } - return mask; -} -SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ - int i; - Bitmask mask = 0; - if( pList ){ - for(i=0; inExpr; i++){ - mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr); - } - } - return mask; -} - - -/* -** Call exprAnalyze on all terms in a WHERE clause. -** -** Note that exprAnalyze() might add new virtual terms onto the -** end of the WHERE clause. We do not want to analyze these new -** virtual terms, so start analyzing at the end and work forward -** so that the added virtual terms are never processed. -*/ -SQLITE_PRIVATE void sqlite3WhereExprAnalyze( - SrcList *pTabList, /* the FROM clause */ - WhereClause *pWC /* the WHERE clause to be analyzed */ -){ - int i; - for(i=pWC->nTerm-1; i>=0; i--){ - exprAnalyze(pTabList, pWC, i); - } -} - -/* -** For table-valued-functions, transform the function arguments into -** new WHERE clause terms. -** -** Each function argument translates into an equality constraint against -** a HIDDEN column in the table. -*/ -SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( - Parse *pParse, /* Parsing context */ - struct SrcList_item *pItem, /* The FROM clause term to process */ - WhereClause *pWC /* Xfer function arguments to here */ -){ - Table *pTab; - int j, k; - ExprList *pArgs; - Expr *pColRef; - Expr *pTerm; - if( pItem->fg.isTabFunc==0 ) return; - pTab = pItem->pTab; - assert( pTab!=0 ); - pArgs = pItem->u1.pFuncArg; - if( pArgs==0 ) return; - for(j=k=0; jnExpr; j++){ - while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} - if( k>=pTab->nCol ){ - sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", - pTab->zName, j); - return; - } - pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); - if( pColRef==0 ) return; - pColRef->iTable = pItem->iCursor; - pColRef->iColumn = k++; - pColRef->pTab = pTab; - pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, - sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); - whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); - } -} - -/************** End of whereexpr.c *******************************************/ -/************** Begin file where.c *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This module contains C code that generates VDBE code used to process -** the WHERE clause of SQL statements. This module is responsible for -** generating the code that loops through a table looking for applicable -** rows. Indices are selected and used to speed the search when doing -** so is applicable. Because this module is responsible for selecting -** indices, you might also think of this module as the "query optimizer". -*/ -/* #include "sqliteInt.h" */ -/* #include "whereInt.h" */ - -/* Forward declaration of methods */ -static int whereLoopResize(sqlite3*, WhereLoop*, int); - -/* Test variable that can be set to enable WHERE tracing */ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int sqlite3WhereTrace = 0; -#endif - - -/* -** Return the estimated number of output rows from a WHERE clause -*/ -SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ - return pWInfo->nRowOut; -} - -/* -** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this -** WHERE clause returns outputs for DISTINCT processing. -*/ -SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ - return pWInfo->eDistinct; -} - -/* -** Return TRUE if the WHERE clause returns rows in ORDER BY order. -** Return FALSE if the output needs to be sorted. -*/ -SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ - return pWInfo->nOBSat; -} - -/* -** Return TRUE if the innermost loop of the WHERE clause implementation -** returns rows in ORDER BY order for complete run of the inner loop. -** -** Across multiple iterations of outer loops, the output rows need not be -** sorted. As long as rows are sorted for just the innermost loop, this -** routine can return TRUE. -*/ -SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){ - return pWInfo->bOrderedInnerLoop; -} - -/* -** Return the VDBE address or label to jump to in order to continue -** immediately with the next row of a WHERE clause. -*/ -SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ - assert( pWInfo->iContinue!=0 ); - return pWInfo->iContinue; -} - -/* -** Return the VDBE address or label to jump to in order to break -** out of a WHERE loop. -*/ -SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ - return pWInfo->iBreak; -} - -/* -** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to -** operate directly on the rowis returned by a WHERE clause. Return -** ONEPASS_SINGLE (1) if the statement can operation directly because only -** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass -** optimization can be used on multiple -** -** If the ONEPASS optimization is used (if this routine returns true) -** then also write the indices of open cursors used by ONEPASS -** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data -** table and iaCur[1] gets the cursor used by an auxiliary index. -** Either value may be -1, indicating that cursor is not used. -** Any cursors returned will have been opened for writing. -** -** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is -** unable to use the ONEPASS optimization. -*/ -SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ - memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2); -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){ - sqlite3DebugPrintf("%s cursors: %d %d\n", - pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI", - aiCur[0], aiCur[1]); - } -#endif - return pWInfo->eOnePass; -} - -/* -** Move the content of pSrc into pDest -*/ -static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ - pDest->n = pSrc->n; - memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); -} - -/* -** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. -** -** The new entry might overwrite an existing entry, or it might be -** appended, or it might be discarded. Do whatever is the right thing -** so that pSet keeps the N_OR_COST best entries seen so far. -*/ -static int whereOrInsert( - WhereOrSet *pSet, /* The WhereOrSet to be updated */ - Bitmask prereq, /* Prerequisites of the new entry */ - LogEst rRun, /* Run-cost of the new entry */ - LogEst nOut /* Number of outputs for the new entry */ -){ - u16 i; - WhereOrCost *p; - for(i=pSet->n, p=pSet->a; i>0; i--, p++){ - if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ - goto whereOrInsert_done; - } - if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){ - return 0; - } - } - if( pSet->na[pSet->n++]; - p->nOut = nOut; - }else{ - p = pSet->a; - for(i=1; in; i++){ - if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i; - } - if( p->rRun<=rRun ) return 0; - } -whereOrInsert_done: - p->prereq = prereq; - p->rRun = rRun; - if( p->nOut>nOut ) p->nOut = nOut; - return 1; -} - -/* -** Return the bitmask for the given cursor number. Return 0 if -** iCursor is not in the set. -*/ -SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ - int i; - assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); - for(i=0; in; i++){ - if( pMaskSet->ix[i]==iCursor ){ - return MASKBIT(i); - } - } - return 0; -} - -/* -** Create a new mask for cursor iCursor. -** -** There is one cursor per table in the FROM clause. The number of -** tables in the FROM clause is limited by a test early in the -** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] -** array will never overflow. -*/ -static void createMask(WhereMaskSet *pMaskSet, int iCursor){ - assert( pMaskSet->n < ArraySize(pMaskSet->ix) ); - pMaskSet->ix[pMaskSet->n++] = iCursor; -} - -/* -** Advance to the next WhereTerm that matches according to the criteria -** established when the pScan object was initialized by whereScanInit(). -** Return NULL if there are no more matching WhereTerms. -*/ -static WhereTerm *whereScanNext(WhereScan *pScan){ - int iCur; /* The cursor on the LHS of the term */ - i16 iColumn; /* The column on the LHS of the term. -1 for IPK */ - Expr *pX; /* An expression being tested */ - WhereClause *pWC; /* Shorthand for pScan->pWC */ - WhereTerm *pTerm; /* The term being tested */ - int k = pScan->k; /* Where to start scanning */ - - while( pScan->iEquiv<=pScan->nEquiv ){ - iCur = pScan->aiCur[pScan->iEquiv-1]; - iColumn = pScan->aiColumn[pScan->iEquiv-1]; - if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0; - while( (pWC = pScan->pWC)!=0 ){ - for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ - if( pTerm->leftCursor==iCur - && pTerm->u.leftColumn==iColumn - && (iColumn!=XN_EXPR - || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0) - && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) - ){ - if( (pTerm->eOperator & WO_EQUIV)!=0 - && pScan->nEquivaiCur) - && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN - ){ - int j; - for(j=0; jnEquiv; j++){ - if( pScan->aiCur[j]==pX->iTable - && pScan->aiColumn[j]==pX->iColumn ){ - break; - } - } - if( j==pScan->nEquiv ){ - pScan->aiCur[j] = pX->iTable; - pScan->aiColumn[j] = pX->iColumn; - pScan->nEquiv++; - } - } - if( (pTerm->eOperator & pScan->opMask)!=0 ){ - /* Verify the affinity and collating sequence match */ - if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ - CollSeq *pColl; - Parse *pParse = pWC->pWInfo->pParse; - pX = pTerm->pExpr; - if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ - continue; - } - assert(pX->pLeft); - pColl = sqlite3BinaryCompareCollSeq(pParse, - pX->pLeft, pX->pRight); - if( pColl==0 ) pColl = pParse->db->pDfltColl; - if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ - continue; - } - } - if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0 - && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN - && pX->iTable==pScan->aiCur[0] - && pX->iColumn==pScan->aiColumn[0] - ){ - testcase( pTerm->eOperator & WO_IS ); - continue; - } - pScan->k = k+1; - return pTerm; - } - } - } - pScan->pWC = pScan->pWC->pOuter; - k = 0; - } - pScan->pWC = pScan->pOrigWC; - k = 0; - pScan->iEquiv++; - } - return 0; -} - -/* -** Initialize a WHERE clause scanner object. Return a pointer to the -** first match. Return NULL if there are no matches. -** -** The scanner will be searching the WHERE clause pWC. It will look -** for terms of the form "X " where X is column iColumn of table -** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx -** must be one of the indexes of table iCur. -** -** The must be one of the operators described by opMask. -** -** If the search is for X and the WHERE clause contains terms of the -** form X=Y then this routine might also return terms of the form -** "Y ". The number of levels of transitivity is limited, -** but is enough to handle most commonly occurring SQL statements. -** -** If X is not the INTEGER PRIMARY KEY then X must be compatible with -** index pIdx. -*/ -static WhereTerm *whereScanInit( - WhereScan *pScan, /* The WhereScan object being initialized */ - WhereClause *pWC, /* The WHERE clause to be scanned */ - int iCur, /* Cursor to scan for */ - int iColumn, /* Column to scan for */ - u32 opMask, /* Operator(s) to scan for */ - Index *pIdx /* Must be compatible with this index */ -){ - int j = 0; - - /* memset(pScan, 0, sizeof(*pScan)); */ - pScan->pOrigWC = pWC; - pScan->pWC = pWC; - pScan->pIdxExpr = 0; - if( pIdx ){ - j = iColumn; - iColumn = pIdx->aiColumn[j]; - if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID; - } - if( pIdx && iColumn>=0 ){ - pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; - pScan->zCollName = pIdx->azColl[j]; - }else{ - pScan->idxaff = 0; - pScan->zCollName = 0; - } - pScan->opMask = opMask; - pScan->k = 0; - pScan->aiCur[0] = iCur; - pScan->aiColumn[0] = iColumn; - pScan->nEquiv = 1; - pScan->iEquiv = 1; - return whereScanNext(pScan); -} - -/* -** Search for a term in the WHERE clause that is of the form "X " -** where X is a reference to the iColumn of table iCur or of index pIdx -** if pIdx!=0 and is one of the WO_xx operator codes specified by -** the op parameter. Return a pointer to the term. Return 0 if not found. -** -** If pIdx!=0 then it must be one of the indexes of table iCur. -** Search for terms matching the iColumn-th column of pIdx -** rather than the iColumn-th column of table iCur. -** -** The term returned might by Y= if there is another constraint in -** the WHERE clause that specifies that X=Y. Any such constraints will be -** identified by the WO_EQUIV bit in the pTerm->eOperator field. The -** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11 -** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10 -** other equivalent values. Hence a search for X will return if X=A1 -** and A1=A2 and A2=A3 and ... and A9=A10 and A10=. -** -** If there are multiple terms in the WHERE clause of the form "X " -** then try for the one with no dependencies on - in other words where -** is a constant expression of some kind. Only return entries of -** the form "X Y" where Y is a column in another table if no terms of -** the form "X " exist. If no terms with a constant RHS -** exist, try to return a term that does not use WO_EQUIV. -*/ -SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( - WhereClause *pWC, /* The WHERE clause to be searched */ - int iCur, /* Cursor number of LHS */ - int iColumn, /* Column number of LHS */ - Bitmask notReady, /* RHS must not overlap with this mask */ - u32 op, /* Mask of WO_xx values describing operator */ - Index *pIdx /* Must be compatible with this index, if not NULL */ -){ - WhereTerm *pResult = 0; - WhereTerm *p; - WhereScan scan; - - p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx); - op &= WO_EQ|WO_IS; - while( p ){ - if( (p->prereqRight & notReady)==0 ){ - if( p->prereqRight==0 && (p->eOperator&op)!=0 ){ - testcase( p->eOperator & WO_IS ); - return p; - } - if( pResult==0 ) pResult = p; - } - p = whereScanNext(&scan); - } - return pResult; -} - -/* -** This function searches pList for an entry that matches the iCol-th column -** of index pIdx. -** -** If such an expression is found, its index in pList->a[] is returned. If -** no expression is found, -1 is returned. -*/ -static int findIndexCol( - Parse *pParse, /* Parse context */ - ExprList *pList, /* Expression list to search */ - int iBase, /* Cursor for table associated with pIdx */ - Index *pIdx, /* Index to match column of */ - int iCol /* Column of index to match */ -){ - int i; - const char *zColl = pIdx->azColl[iCol]; - - for(i=0; inExpr; i++){ - Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr); - if( p->op==TK_COLUMN - && p->iColumn==pIdx->aiColumn[iCol] - && p->iTable==iBase - ){ - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr); - if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){ - return i; - } - } - } - - return -1; -} - -/* -** Return TRUE if the iCol-th column of index pIdx is NOT NULL -*/ -static int indexColumnNotNull(Index *pIdx, int iCol){ - int j; - assert( pIdx!=0 ); - assert( iCol>=0 && iColnColumn ); - j = pIdx->aiColumn[iCol]; - if( j>=0 ){ - return pIdx->pTable->aCol[j].notNull; - }else if( j==(-1) ){ - return 1; - }else{ - assert( j==(-2) ); - return 0; /* Assume an indexed expression can always yield a NULL */ - - } -} - -/* -** Return true if the DISTINCT expression-list passed as the third argument -** is redundant. -** -** A DISTINCT list is redundant if any subset of the columns in the -** DISTINCT list are collectively unique and individually non-null. -*/ -static int isDistinctRedundant( - Parse *pParse, /* Parsing context */ - SrcList *pTabList, /* The FROM clause */ - WhereClause *pWC, /* The WHERE clause */ - ExprList *pDistinct /* The result set that needs to be DISTINCT */ -){ - Table *pTab; - Index *pIdx; - int i; - int iBase; - - /* If there is more than one table or sub-select in the FROM clause of - ** this query, then it will not be possible to show that the DISTINCT - ** clause is redundant. */ - if( pTabList->nSrc!=1 ) return 0; - iBase = pTabList->a[0].iCursor; - pTab = pTabList->a[0].pTab; - - /* If any of the expressions is an IPK column on table iBase, then return - ** true. Note: The (p->iTable==iBase) part of this test may be false if the - ** current SELECT is a correlated sub-query. - */ - for(i=0; inExpr; i++){ - Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr); - if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; - } - - /* Loop through all indices on the table, checking each to see if it makes - ** the DISTINCT qualifier redundant. It does so if: - ** - ** 1. The index is itself UNIQUE, and - ** - ** 2. All of the columns in the index are either part of the pDistinct - ** list, or else the WHERE clause contains a term of the form "col=X", - ** where X is a constant value. The collation sequences of the - ** comparison and select-list expressions must match those of the index. - ** - ** 3. All of those index columns for which the WHERE clause does not - ** contain a "col=X" term are subject to a NOT NULL constraint. - */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( !IsUniqueIndex(pIdx) ) continue; - for(i=0; inKeyCol; i++){ - if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ - if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break; - if( indexColumnNotNull(pIdx, i)==0 ) break; - } - } - if( i==pIdx->nKeyCol ){ - /* This index implies that the DISTINCT qualifier is redundant. */ - return 1; - } - } - - return 0; -} - - -/* -** Estimate the logarithm of the input value to base 2. -*/ -static LogEst estLog(LogEst N){ - return N<=10 ? 0 : sqlite3LogEst(N) - 33; -} - -/* -** Convert OP_Column opcodes to OP_Copy in previously generated code. -** -** This routine runs over generated VDBE code and translates OP_Column -** opcodes into OP_Copy when the table is being accessed via co-routine -** instead of via table lookup. -** -** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on -** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero, -** then each OP_Rowid is transformed into an instruction to increment the -** value stored in its output register. -*/ -static void translateColumnToCopy( - Vdbe *v, /* The VDBE containing code to translate */ - int iStart, /* Translate from this opcode to the end */ - int iTabCur, /* OP_Column/OP_Rowid references to this table */ - int iRegister, /* The first column is in this register */ - int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */ -){ - VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); - int iEnd = sqlite3VdbeCurrentAddr(v); - for(; iStartp1!=iTabCur ) continue; - if( pOp->opcode==OP_Column ){ - pOp->opcode = OP_Copy; - pOp->p1 = pOp->p2 + iRegister; - pOp->p2 = pOp->p3; - pOp->p3 = 0; - }else if( pOp->opcode==OP_Rowid ){ - if( bIncrRowid ){ - /* Increment the value stored in the P2 operand of the OP_Rowid. */ - pOp->opcode = OP_AddImm; - pOp->p1 = pOp->p2; - pOp->p2 = 1; - }else{ - pOp->opcode = OP_Null; - pOp->p1 = 0; - pOp->p3 = 0; - } - } - } -} - -/* -** Two routines for printing the content of an sqlite3_index_info -** structure. Used for testing and debugging only. If neither -** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines -** are no-ops. -*/ -#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) -static void TRACE_IDX_INPUTS(sqlite3_index_info *p){ - int i; - if( !sqlite3WhereTrace ) return; - for(i=0; inConstraint; i++){ - sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", - i, - p->aConstraint[i].iColumn, - p->aConstraint[i].iTermOffset, - p->aConstraint[i].op, - p->aConstraint[i].usable); - } - for(i=0; inOrderBy; i++){ - sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", - i, - p->aOrderBy[i].iColumn, - p->aOrderBy[i].desc); - } -} -static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){ - int i; - if( !sqlite3WhereTrace ) return; - for(i=0; inConstraint; i++){ - sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", - i, - p->aConstraintUsage[i].argvIndex, - p->aConstraintUsage[i].omit); - } - sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); - sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); - sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); - sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); - sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); -} -#else -#define TRACE_IDX_INPUTS(A) -#define TRACE_IDX_OUTPUTS(A) -#endif - -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX -/* -** Return TRUE if the WHERE clause term pTerm is of a form where it -** could be used with an index to access pSrc, assuming an appropriate -** index existed. -*/ -static int termCanDriveIndex( - WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ - Bitmask notReady /* Tables in outer loops of the join */ -){ - char aff; - if( pTerm->leftCursor!=pSrc->iCursor ) return 0; - if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; - if( (pTerm->prereqRight & notReady)!=0 ) return 0; - if( pTerm->u.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; - if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; - testcase( pTerm->pExpr->op==TK_IS ); - return 1; -} -#endif - - -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX -/* -** Generate code to construct the Index object for an automatic index -** and to set up the WhereLevel object pLevel so that the code generator -** makes use of the automatic index. -*/ -static void constructAutomaticIndex( - Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ - Bitmask notReady, /* Mask of cursors that are not available */ - WhereLevel *pLevel /* Write new index here */ -){ - int nKeyCol; /* Number of columns in the constructed index */ - WhereTerm *pTerm; /* A single term of the WHERE clause */ - WhereTerm *pWCEnd; /* End of pWC->a[] */ - Index *pIdx; /* Object describing the transient index */ - Vdbe *v; /* Prepared statement under construction */ - int addrInit; /* Address of the initialization bypass jump */ - Table *pTable; /* The table being indexed */ - int addrTop; /* Top of the index fill loop */ - int regRecord; /* Register holding an index record */ - int n; /* Column counter */ - int i; /* Loop counter */ - int mxBitCol; /* Maximum column in pSrc->colUsed */ - CollSeq *pColl; /* Collating sequence to on a column */ - WhereLoop *pLoop; /* The Loop object */ - char *zNotUsed; /* Extra space on the end of pIdx */ - Bitmask idxCols; /* Bitmap of columns used for indexing */ - Bitmask extraCols; /* Bitmap of additional columns */ - u8 sentWarning = 0; /* True if a warnning has been issued */ - Expr *pPartial = 0; /* Partial Index Expression */ - int iContinue = 0; /* Jump here to skip excluded rows */ - struct SrcList_item *pTabItem; /* FROM clause term being indexed */ - int addrCounter = 0; /* Address where integer counter is initialized */ - int regBase; /* Array of registers where record is assembled */ - - /* Generate code to skip over the creation and initialization of the - ** transient index on 2nd and subsequent iterations of the loop. */ - v = pParse->pVdbe; - assert( v!=0 ); - addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - - /* Count the number of columns that will be added to the index - ** and used to match WHERE clause constraints */ - nKeyCol = 0; - pTable = pSrc->pTab; - pWCEnd = &pWC->a[pWC->nTerm]; - pLoop = pLevel->pWLoop; - idxCols = 0; - for(pTerm=pWC->a; pTermpExpr; - assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ - || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ - || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ - if( pLoop->prereq==0 - && (pTerm->wtFlags & TERM_VIRTUAL)==0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ - pPartial = sqlite3ExprAnd(pParse->db, pPartial, - sqlite3ExprDup(pParse->db, pExpr, 0)); - } - if( termCanDriveIndex(pTerm, pSrc, notReady) ){ - int iCol = pTerm->u.leftColumn; - Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); - testcase( iCol==BMS ); - testcase( iCol==BMS-1 ); - if( !sentWarning ){ - sqlite3_log(SQLITE_WARNING_AUTOINDEX, - "automatic index on %s(%s)", pTable->zName, - pTable->aCol[iCol].zName); - sentWarning = 1; - } - if( (idxCols & cMask)==0 ){ - if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){ - goto end_auto_index_create; - } - pLoop->aLTerm[nKeyCol++] = pTerm; - idxCols |= cMask; - } - } - } - assert( nKeyCol>0 ); - pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol; - pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED - | WHERE_AUTO_INDEX; - - /* Count the number of additional columns needed to create a - ** covering index. A "covering index" is an index that contains all - ** columns that are needed by the query. With a covering index, the - ** original table never needs to be accessed. Automatic indices must - ** be a covering index because the index will not be updated if the - ** original table changes and the index and table cannot both be used - ** if they go out of sync. - */ - extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); - mxBitCol = MIN(BMS-1,pTable->nCol); - testcase( pTable->nCol==BMS-1 ); - testcase( pTable->nCol==BMS-2 ); - for(i=0; icolUsed & MASKBIT(BMS-1) ){ - nKeyCol += pTable->nCol - BMS + 1; - } - - /* Construct the Index object to describe this index */ - pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed); - if( pIdx==0 ) goto end_auto_index_create; - pLoop->u.btree.pIndex = pIdx; - pIdx->zName = "auto-index"; - pIdx->pTable = pTable; - n = 0; - idxCols = 0; - for(pTerm=pWC->a; pTermu.leftColumn; - Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); - testcase( iCol==BMS-1 ); - testcase( iCol==BMS ); - if( (idxCols & cMask)==0 ){ - Expr *pX = pTerm->pExpr; - idxCols |= cMask; - pIdx->aiColumn[n] = pTerm->u.leftColumn; - pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; - n++; - } - } - } - assert( (u32)n==pLoop->u.btree.nEq ); - - /* Add additional columns needed to make the automatic index into - ** a covering index */ - for(i=0; iaiColumn[n] = i; - pIdx->azColl[n] = sqlite3StrBINARY; - n++; - } - } - if( pSrc->colUsed & MASKBIT(BMS-1) ){ - for(i=BMS-1; inCol; i++){ - pIdx->aiColumn[n] = i; - pIdx->azColl[n] = sqlite3StrBINARY; - n++; - } - } - assert( n==nKeyCol ); - pIdx->aiColumn[n] = XN_ROWID; - pIdx->azColl[n] = sqlite3StrBINARY; - - /* Create the automatic index */ - assert( pLevel->iIdxCur>=0 ); - pLevel->iIdxCur = pParse->nTab++; - sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "for %s", pTable->zName)); - - /* Fill the automatic index with content */ - sqlite3ExprCachePush(pParse); - pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; - if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; - addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); - VdbeCoverage(v); - VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); - }else{ - addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); - } - if( pPartial ){ - iContinue = sqlite3VdbeMakeLabel(v); - sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); - pLoop->wsFlags |= WHERE_PARTIALIDX; - } - regRecord = sqlite3GetTempReg(pParse); - regBase = sqlite3GenerateIndexKey( - pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 - ); - sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); - if( pTabItem->fg.viaCoroutine ){ - sqlite3VdbeChangeP2(v, addrCounter, regBase+n); - translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1); - sqlite3VdbeGoto(v, addrTop); - pTabItem->fg.viaCoroutine = 0; - }else{ - sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); - } - sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); - sqlite3VdbeJumpHere(v, addrTop); - sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3ExprCachePop(pParse); - - /* Jump here when skipping the initialization */ - sqlite3VdbeJumpHere(v, addrInit); - -end_auto_index_create: - sqlite3ExprDelete(pParse->db, pPartial); -} -#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/* -** Allocate and populate an sqlite3_index_info structure. It is the -** responsibility of the caller to eventually release the structure -** by passing the pointer returned by this function to sqlite3_free(). -*/ -static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, - WhereClause *pWC, - Bitmask mUnusable, /* Ignore terms with these prereqs */ - struct SrcList_item *pSrc, - ExprList *pOrderBy, - u16 *pmNoOmit /* Mask of terms not to omit */ -){ - int i, j; - int nTerm; - struct sqlite3_index_constraint *pIdxCons; - struct sqlite3_index_orderby *pIdxOrderBy; - struct sqlite3_index_constraint_usage *pUsage; - WhereTerm *pTerm; - int nOrderBy; - sqlite3_index_info *pIdxInfo; - u16 mNoOmit = 0; - - /* Count the number of possible WHERE clause constraints referring - ** to this virtual table */ - for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( pTerm->u.leftColumn>=(-1) ); - nTerm++; - } - - /* If the ORDER BY clause contains only columns in the current - ** virtual table then allocate space for the aOrderBy part of - ** the sqlite3_index_info structure. - */ - nOrderBy = 0; - if( pOrderBy ){ - int n = pOrderBy->nExpr; - for(i=0; ia[i].pExpr; - if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; - } - if( i==n){ - nOrderBy = n; - } - } - - /* Allocate the sqlite3_index_info structure - */ - pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) - + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm - + sizeof(*pIdxOrderBy)*nOrderBy ); - if( pIdxInfo==0 ){ - sqlite3ErrorMsg(pParse, "out of memory"); - return 0; - } - - /* Initialize the structure. The sqlite3_index_info structure contains - ** many fields that are declared "const" to prevent xBestIndex from - ** changing them. We have to do some funky casting in order to - ** initialize those fields. - */ - pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; - pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; - pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; - *(int*)&pIdxInfo->nConstraint = nTerm; - *(int*)&pIdxInfo->nOrderBy = nOrderBy; - *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; - *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; - *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = - pUsage; - - for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - u8 op; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( pTerm->u.leftColumn>=(-1) ); - pIdxCons[j].iColumn = pTerm->u.leftColumn; - pIdxCons[j].iTermOffset = i; - op = (u8)pTerm->eOperator & WO_ALL; - if( op==WO_IN ) op = WO_EQ; - if( op==WO_MATCH ){ - op = pTerm->eMatchOp; - } - pIdxCons[j].op = op; - /* The direct assignment in the previous line is possible only because - ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The - ** following asserts verify this fact. */ - assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); - assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); - assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); - assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); - assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); - assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); - assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); - - if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) - ){ - if( i<16 ) mNoOmit |= (1 << i); - if( op==WO_LT ) pIdxCons[j].op = WO_LE; - if( op==WO_GT ) pIdxCons[j].op = WO_GE; - } - - j++; - } - for(i=0; ia[i].pExpr; - pIdxOrderBy[i].iColumn = pExpr->iColumn; - pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; - } - - *pmNoOmit = mNoOmit; - return pIdxInfo; -} - -/* -** The table object reference passed as the second argument to this function -** must represent a virtual table. This function invokes the xBestIndex() -** method of the virtual table with the sqlite3_index_info object that -** comes in as the 3rd argument to this function. -** -** If an error occurs, pParse is populated with an error message and a -** non-zero value is returned. Otherwise, 0 is returned and the output -** part of the sqlite3_index_info structure is left populated. -** -** Whether or not an error is returned, it is the responsibility of the -** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates -** that this is required. -*/ -static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ - sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; - int rc; - - TRACE_IDX_INPUTS(p); - rc = pVtab->pModule->xBestIndex(pVtab, p); - TRACE_IDX_OUTPUTS(p); - - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ){ - sqlite3OomFault(pParse->db); - }else if( !pVtab->zErrMsg ){ - sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); - }else{ - sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); - } - } - sqlite3_free(pVtab->zErrMsg); - pVtab->zErrMsg = 0; - -#if 0 - /* This error is now caught by the caller. - ** Search for "xBestIndex malfunction" below */ - for(i=0; inConstraint; i++){ - if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ - sqlite3ErrorMsg(pParse, - "table %s: xBestIndex returned an invalid plan", pTab->zName); - } - } -#endif - - return pParse->nErr; -} -#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Estimate the location of a particular key among all keys in an -** index. Store the results in aStat as follows: -** -** aStat[0] Est. number of rows less than pRec -** aStat[1] Est. number of rows equal to pRec -** -** Return the index of the sample that is the smallest sample that -** is greater than or equal to pRec. Note that this index is not an index -** into the aSample[] array - it is an index into a virtual set of samples -** based on the contents of aSample[] and the number of fields in record -** pRec. -*/ -static int whereKeyStats( - Parse *pParse, /* Database connection */ - Index *pIdx, /* Index to consider domain of */ - UnpackedRecord *pRec, /* Vector of values to consider */ - int roundUp, /* Round up if true. Round down if false */ - tRowcnt *aStat /* OUT: stats written here */ -){ - IndexSample *aSample = pIdx->aSample; - int iCol; /* Index of required stats in anEq[] etc. */ - int i; /* Index of first sample >= pRec */ - int iSample; /* Smallest sample larger than or equal to pRec */ - int iMin = 0; /* Smallest sample not yet tested */ - int iTest; /* Next sample to test */ - int res; /* Result of comparison operation */ - int nField; /* Number of fields in pRec */ - tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ - -#ifndef SQLITE_DEBUG - UNUSED_PARAMETER( pParse ); -#endif - assert( pRec!=0 ); - assert( pIdx->nSample>0 ); - assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol ); - - /* Do a binary search to find the first sample greater than or equal - ** to pRec. If pRec contains a single field, the set of samples to search - ** is simply the aSample[] array. If the samples in aSample[] contain more - ** than one fields, all fields following the first are ignored. - ** - ** If pRec contains N fields, where N is more than one, then as well as the - ** samples in aSample[] (truncated to N fields), the search also has to - ** consider prefixes of those samples. For example, if the set of samples - ** in aSample is: - ** - ** aSample[0] = (a, 5) - ** aSample[1] = (a, 10) - ** aSample[2] = (b, 5) - ** aSample[3] = (c, 100) - ** aSample[4] = (c, 105) - ** - ** Then the search space should ideally be the samples above and the - ** unique prefixes [a], [b] and [c]. But since that is hard to organize, - ** the code actually searches this set: - ** - ** 0: (a) - ** 1: (a, 5) - ** 2: (a, 10) - ** 3: (a, 10) - ** 4: (b) - ** 5: (b, 5) - ** 6: (c) - ** 7: (c, 100) - ** 8: (c, 105) - ** 9: (c, 105) - ** - ** For each sample in the aSample[] array, N samples are present in the - ** effective sample array. In the above, samples 0 and 1 are based on - ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. - ** - ** Often, sample i of each block of N effective samples has (i+1) fields. - ** Except, each sample may be extended to ensure that it is greater than or - ** equal to the previous sample in the array. For example, in the above, - ** sample 2 is the first sample of a block of N samples, so at first it - ** appears that it should be 1 field in size. However, that would make it - ** smaller than sample 1, so the binary search would not work. As a result, - ** it is extended to two fields. The duplicates that this creates do not - ** cause any problems. - */ - nField = pRec->nField; - iCol = 0; - iSample = pIdx->nSample * nField; - do{ - int iSamp; /* Index in aSample[] of test sample */ - int n; /* Number of fields in test sample */ - - iTest = (iMin+iSample)/2; - iSamp = iTest / nField; - if( iSamp>0 ){ - /* The proposed effective sample is a prefix of sample aSample[iSamp]. - ** Specifically, the shortest prefix of at least (1 + iTest%nField) - ** fields that is greater than the previous effective sample. */ - for(n=(iTest % nField) + 1; nnField = n; - res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); - if( res<0 ){ - iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; - iMin = iTest+1; - }else if( res==0 && ndb->mallocFailed==0 ){ - if( res==0 ){ - /* If (res==0) is true, then pRec must be equal to sample i. */ - assert( inSample ); - assert( iCol==nField-1 ); - pRec->nField = nField; - assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) - || pParse->db->mallocFailed - ); - }else{ - /* Unless i==pIdx->nSample, indicating that pRec is larger than - ** all samples in the aSample[] array, pRec must be smaller than the - ** (iCol+1) field prefix of sample i. */ - assert( i<=pIdx->nSample && i>=0 ); - pRec->nField = iCol+1; - assert( i==pIdx->nSample - || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 - || pParse->db->mallocFailed ); - - /* if i==0 and iCol==0, then record pRec is smaller than all samples - ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must - ** be greater than or equal to the (iCol) field prefix of sample i. - ** If (i>0), then pRec must also be greater than sample (i-1). */ - if( iCol>0 ){ - pRec->nField = iCol; - assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 - || pParse->db->mallocFailed ); - } - if( i>0 ){ - pRec->nField = nField; - assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 - || pParse->db->mallocFailed ); - } - } - } -#endif /* ifdef SQLITE_DEBUG */ - - if( res==0 ){ - /* Record pRec is equal to sample i */ - assert( iCol==nField-1 ); - aStat[0] = aSample[i].anLt[iCol]; - aStat[1] = aSample[i].anEq[iCol]; - }else{ - /* At this point, the (iCol+1) field prefix of aSample[i] is the first - ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec - ** is larger than all samples in the array. */ - tRowcnt iUpper, iGap; - if( i>=pIdx->nSample ){ - iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); - }else{ - iUpper = aSample[i].anLt[iCol]; - } - - if( iLower>=iUpper ){ - iGap = 0; - }else{ - iGap = iUpper - iLower; - } - if( roundUp ){ - iGap = (iGap*2)/3; - }else{ - iGap = iGap/3; - } - aStat[0] = iLower + iGap; - aStat[1] = pIdx->aAvgEq[iCol]; - } - - /* Restore the pRec->nField value before returning. */ - pRec->nField = nField; - return i; -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - -/* -** If it is not NULL, pTerm is a term that provides an upper or lower -** bound on a range scan. Without considering pTerm, it is estimated -** that the scan will visit nNew rows. This function returns the number -** estimated to be visited after taking pTerm into account. -** -** If the user explicitly specified a likelihood() value for this term, -** then the return value is the likelihood multiplied by the number of -** input rows. Otherwise, this function assumes that an "IS NOT NULL" term -** has a likelihood of 0.50, and any other term a likelihood of 0.25. -*/ -static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ - LogEst nRet = nNew; - if( pTerm ){ - if( pTerm->truthProb<=0 ){ - nRet += pTerm->truthProb; - }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ - nRet -= 20; assert( 20==sqlite3LogEst(4) ); - } - } - return nRet; -} - - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Return the affinity for a single column of an index. -*/ -SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ - assert( iCol>=0 && iColnColumn ); - if( !pIdx->zColAff ){ - if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; - } - return pIdx->zColAff[iCol]; -} -#endif - - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** This function is called to estimate the number of rows visited by a -** range-scan on a skip-scan index. For example: -** -** CREATE INDEX i1 ON t1(a, b, c); -** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; -** -** Value pLoop->nOut is currently set to the estimated number of rows -** visited for scanning (a=? AND b=?). This function reduces that estimate -** by some factor to account for the (c BETWEEN ? AND ?) expression based -** on the stat4 data for the index. this scan will be peformed multiple -** times (once for each (a,b) combination that matches a=?) is dealt with -** by the caller. -** -** It does this by scanning through all stat4 samples, comparing values -** extracted from pLower and pUpper with the corresponding column in each -** sample. If L and U are the number of samples found to be less than or -** equal to the values extracted from pLower and pUpper respectively, and -** N is the total number of samples, the pLoop->nOut value is adjusted -** as follows: -** -** nOut = nOut * ( min(U - L, 1) / N ) -** -** If pLower is NULL, or a value cannot be extracted from the term, L is -** set to zero. If pUpper is NULL, or a value cannot be extracted from it, -** U is set to N. -** -** Normally, this function sets *pbDone to 1 before returning. However, -** if no value can be extracted from either pLower or pUpper (and so the -** estimate of the number of rows delivered remains unchanged), *pbDone -** is left as is. -** -** If an error occurs, an SQLite error code is returned. Otherwise, -** SQLITE_OK. -*/ -static int whereRangeSkipScanEst( - Parse *pParse, /* Parsing & code generating context */ - WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ - WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ - WhereLoop *pLoop, /* Update the .nOut value of this loop */ - int *pbDone /* Set to true if at least one expr. value extracted */ -){ - Index *p = pLoop->u.btree.pIndex; - int nEq = pLoop->u.btree.nEq; - sqlite3 *db = pParse->db; - int nLower = -1; - int nUpper = p->nSample+1; - int rc = SQLITE_OK; - u8 aff = sqlite3IndexColumnAffinity(db, p, nEq); - CollSeq *pColl; - - sqlite3_value *p1 = 0; /* Value extracted from pLower */ - sqlite3_value *p2 = 0; /* Value extracted from pUpper */ - sqlite3_value *pVal = 0; /* Value extracted from record */ - - pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]); - if( pLower ){ - rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); - nLower = 0; - } - if( pUpper && rc==SQLITE_OK ){ - rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); - nUpper = p2 ? 0 : p->nSample; - } - - if( p1 || p2 ){ - int i; - int nDiff; - for(i=0; rc==SQLITE_OK && inSample; i++){ - rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); - if( rc==SQLITE_OK && p1 ){ - int res = sqlite3MemCompare(p1, pVal, pColl); - if( res>=0 ) nLower++; - } - if( rc==SQLITE_OK && p2 ){ - int res = sqlite3MemCompare(p2, pVal, pColl); - if( res>=0 ) nUpper++; - } - } - nDiff = (nUpper - nLower); - if( nDiff<=0 ) nDiff = 1; - - /* If there is both an upper and lower bound specified, and the - ** comparisons indicate that they are close together, use the fallback - ** method (assume that the scan visits 1/64 of the rows) for estimating - ** the number of rows visited. Otherwise, estimate the number of rows - ** using the method described in the header comment for this function. */ - if( nDiff!=1 || pUpper==0 || pLower==0 ){ - int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); - pLoop->nOut -= nAdjust; - *pbDone = 1; - WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", - nLower, nUpper, nAdjust*-1, pLoop->nOut)); - } - - }else{ - assert( *pbDone==0 ); - } - - sqlite3ValueFree(p1); - sqlite3ValueFree(p2); - sqlite3ValueFree(pVal); - - return rc; -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - -/* -** This function is used to estimate the number of rows that will be visited -** by scanning an index for a range of values. The range may have an upper -** bound, a lower bound, or both. The WHERE clause terms that set the upper -** and lower bounds are represented by pLower and pUpper respectively. For -** example, assuming that index p is on t1(a): -** -** ... FROM t1 WHERE a > ? AND a < ? ... -** |_____| |_____| -** | | -** pLower pUpper -** -** If either of the upper or lower bound is not present, then NULL is passed in -** place of the corresponding WhereTerm. -** -** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index -** column subject to the range constraint. Or, equivalently, the number of -** equality constraints optimized by the proposed index scan. For example, -** assuming index p is on t1(a, b), and the SQL query is: -** -** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... -** -** then nEq is set to 1 (as the range restricted column, b, is the second -** left-most column of the index). Or, if the query is: -** -** ... FROM t1 WHERE a > ? AND a < ? ... -** -** then nEq is set to 0. -** -** When this function is called, *pnOut is set to the sqlite3LogEst() of the -** number of rows that the index scan is expected to visit without -** considering the range constraints. If nEq is 0, then *pnOut is the number of -** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) -** to account for the range constraints pLower and pUpper. -** -** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be -** used, a single range inequality reduces the search space by a factor of 4. -** and a pair of constraints (x>? AND x123" Might be NULL */ - WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ - WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ -){ - int rc = SQLITE_OK; - int nOut = pLoop->nOut; - LogEst nNew; - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - Index *p = pLoop->u.btree.pIndex; - int nEq = pLoop->u.btree.nEq; - - if( p->nSample>0 && nEqnSampleCol ){ - if( nEq==pBuilder->nRecValid ){ - UnpackedRecord *pRec = pBuilder->pRec; - tRowcnt a[2]; - int nBtm = pLoop->u.btree.nBtm; - int nTop = pLoop->u.btree.nTop; - - /* Variable iLower will be set to the estimate of the number of rows in - ** the index that are less than the lower bound of the range query. The - ** lower bound being the concatenation of $P and $L, where $P is the - ** key-prefix formed by the nEq values matched against the nEq left-most - ** columns of the index, and $L is the value in pLower. - ** - ** Or, if pLower is NULL or $L cannot be extracted from it (because it - ** is not a simple variable or literal value), the lower bound of the - ** range is $P. Due to a quirk in the way whereKeyStats() works, even - ** if $L is available, whereKeyStats() is called for both ($P) and - ** ($P:$L) and the larger of the two returned values is used. - ** - ** Similarly, iUpper is to be set to the estimate of the number of rows - ** less than the upper bound of the range query. Where the upper bound - ** is either ($P) or ($P:$U). Again, even if $U is available, both values - ** of iUpper are requested of whereKeyStats() and the smaller used. - ** - ** The number of rows between the two bounds is then just iUpper-iLower. - */ - tRowcnt iLower; /* Rows less than the lower bound */ - tRowcnt iUpper; /* Rows less than the upper bound */ - int iLwrIdx = -2; /* aSample[] for the lower bound */ - int iUprIdx = -1; /* aSample[] for the upper bound */ - - if( pRec ){ - testcase( pRec->nField!=pBuilder->nRecValid ); - pRec->nField = pBuilder->nRecValid; - } - /* Determine iLower and iUpper using ($P) only. */ - if( nEq==0 ){ - iLower = 0; - iUpper = p->nRowEst0; - }else{ - /* Note: this call could be optimized away - since the same values must - ** have been requested when testing key $P in whereEqualScanEst(). */ - whereKeyStats(pParse, p, pRec, 0, a); - iLower = a[0]; - iUpper = a[0] + a[1]; - } - - assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); - assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); - assert( p->aSortOrder!=0 ); - if( p->aSortOrder[nEq] ){ - /* The roles of pLower and pUpper are swapped for a DESC index */ - SWAP(WhereTerm*, pLower, pUpper); - SWAP(int, nBtm, nTop); - } - - /* If possible, improve on the iLower estimate using ($P:$L). */ - if( pLower ){ - int n; /* Values extracted from pExpr */ - Expr *pExpr = pLower->pExpr->pRight; - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); - if( rc==SQLITE_OK && n ){ - tRowcnt iNew; - u16 mask = WO_GT|WO_LE; - if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); - iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); - iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0); - if( iNew>iLower ) iLower = iNew; - nOut--; - pLower = 0; - } - } - - /* If possible, improve on the iUpper estimate using ($P:$U). */ - if( pUpper ){ - int n; /* Values extracted from pExpr */ - Expr *pExpr = pUpper->pExpr->pRight; - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); - if( rc==SQLITE_OK && n ){ - tRowcnt iNew; - u16 mask = WO_GT|WO_LE; - if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); - iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); - iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0); - if( iNewpRec = pRec; - if( rc==SQLITE_OK ){ - if( iUpper>iLower ){ - nNew = sqlite3LogEst(iUpper - iLower); - /* TUNING: If both iUpper and iLower are derived from the same - ** sample, then assume they are 4x more selective. This brings - ** the estimated selectivity more in line with what it would be - ** if estimated without the use of STAT3/4 tables. */ - if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); - }else{ - nNew = 10; assert( 10==sqlite3LogEst(2) ); - } - if( nNewwtFlags & TERM_VNULL)==0 ); - nNew = whereRangeAdjust(pLower, nOut); - nNew = whereRangeAdjust(pUpper, nNew); - - /* TUNING: If there is both an upper and lower limit and neither limit - ** has an application-defined likelihood(), assume the range is - ** reduced by an additional 75%. This means that, by default, an open-ended - ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the - ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to - ** match 1/64 of the index. */ - if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){ - nNew -= 20; - } - - nOut -= (pLower!=0) + (pUpper!=0); - if( nNew<10 ) nNew = 10; - if( nNewnOut>nOut ){ - WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", - pLoop->nOut, nOut)); - } -#endif - pLoop->nOut = (LogEst)nOut; - return rc; -} - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Estimate the number of rows that will be returned based on -** an equality constraint x=VALUE and where that VALUE occurs in -** the histogram data. This only works when x is the left-most -** column of an index and sqlite_stat3 histogram data is available -** for that index. When pExpr==NULL that means the constraint is -** "x IS NULL" instead of "x=VALUE". -** -** Write the estimated row count into *pnRow and return SQLITE_OK. -** If unable to make an estimate, leave *pnRow unchanged and return -** non-zero. -** -** This routine can fail if it is unable to load a collating sequence -** required for string comparison, or if unable to allocate memory -** for a UTF conversion required for comparison. The error is stored -** in the pParse structure. -*/ -static int whereEqualScanEst( - Parse *pParse, /* Parsing & code generating context */ - WhereLoopBuilder *pBuilder, - Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ - tRowcnt *pnRow /* Write the revised row estimate here */ -){ - Index *p = pBuilder->pNew->u.btree.pIndex; - int nEq = pBuilder->pNew->u.btree.nEq; - UnpackedRecord *pRec = pBuilder->pRec; - int rc; /* Subfunction return code */ - tRowcnt a[2]; /* Statistics */ - int bOk; - - assert( nEq>=1 ); - assert( nEq<=p->nColumn ); - assert( p->aSample!=0 ); - assert( p->nSample>0 ); - assert( pBuilder->nRecValidnRecValid<(nEq-1) ){ - return SQLITE_NOTFOUND; - } - - /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() - ** below would return the same value. */ - if( nEq>=p->nColumn ){ - *pnRow = 1; - return SQLITE_OK; - } - - rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); - pBuilder->pRec = pRec; - if( rc!=SQLITE_OK ) return rc; - if( bOk==0 ) return SQLITE_NOTFOUND; - pBuilder->nRecValid = nEq; - - whereKeyStats(pParse, p, pRec, 0, a); - WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", - p->zName, nEq-1, (int)a[1])); - *pnRow = a[1]; - - return rc; -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 -/* -** Estimate the number of rows that will be returned based on -** an IN constraint where the right-hand side of the IN operator -** is a list of values. Example: -** -** WHERE x IN (1,2,3,4) -** -** Write the estimated row count into *pnRow and return SQLITE_OK. -** If unable to make an estimate, leave *pnRow unchanged and return -** non-zero. -** -** This routine can fail if it is unable to load a collating sequence -** required for string comparison, or if unable to allocate memory -** for a UTF conversion required for comparison. The error is stored -** in the pParse structure. -*/ -static int whereInScanEst( - Parse *pParse, /* Parsing & code generating context */ - WhereLoopBuilder *pBuilder, - ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ - tRowcnt *pnRow /* Write the revised row estimate here */ -){ - Index *p = pBuilder->pNew->u.btree.pIndex; - i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); - int nRecValid = pBuilder->nRecValid; - int rc = SQLITE_OK; /* Subfunction return code */ - tRowcnt nEst; /* Number of rows for a single term */ - tRowcnt nRowEst = 0; /* New estimate of the number of rows */ - int i; /* Loop counter */ - - assert( p->aSample!=0 ); - for(i=0; rc==SQLITE_OK && inExpr; i++){ - nEst = nRow0; - rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); - nRowEst += nEst; - pBuilder->nRecValid = nRecValid; - } - - if( rc==SQLITE_OK ){ - if( nRowEst > nRow0 ) nRowEst = nRow0; - *pnRow = nRowEst; - WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); - } - assert( pBuilder->nRecValid==nRecValid ); - return rc; -} -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ - - -#ifdef WHERETRACE_ENABLED -/* -** Print the content of a WhereTerm object -*/ -static void whereTermPrint(WhereTerm *pTerm, int iTerm){ - if( pTerm==0 ){ - sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); - }else{ - char zType[4]; - char zLeft[50]; - memcpy(zType, "...", 4); - if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; - if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; - if( pTerm->eOperator & WO_SINGLE ){ - sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", - pTerm->leftCursor, pTerm->u.leftColumn); - }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ - sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", - pTerm->u.pOrInfo->indexable); - }else{ - sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); - } - sqlite3DebugPrintf( - "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x", - iTerm, pTerm, zType, zLeft, pTerm->truthProb, - pTerm->eOperator, pTerm->wtFlags); - if( pTerm->iField ){ - sqlite3DebugPrintf(" iField=%d\n", pTerm->iField); - }else{ - sqlite3DebugPrintf("\n"); - } - sqlite3TreeViewExpr(0, pTerm->pExpr, 0); - } -} -#endif - -#ifdef WHERETRACE_ENABLED -/* -** Show the complete content of a WhereClause -*/ -SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ - int i; - for(i=0; inTerm; i++){ - whereTermPrint(&pWC->a[i], i); - } -} -#endif - -#ifdef WHERETRACE_ENABLED -/* -** Print a WhereLoop object for debugging purposes -*/ -static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){ - WhereInfo *pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; - Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; - sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, - p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); - sqlite3DebugPrintf(" %12s", - pItem->zAlias ? pItem->zAlias : pTab->zName); - if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ - const char *zName; - if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ - if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ - int i = sqlite3Strlen30(zName) - 1; - while( zName[i]!='_' ) i--; - zName += i; - } - sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); - }else{ - sqlite3DebugPrintf("%20s",""); - } - }else{ - char *z; - if( p->u.vtab.idxStr ){ - z = sqlite3_mprintf("(%d,\"%s\",%x)", - p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); - }else{ - z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); - } - sqlite3DebugPrintf(" %-19s", z); - sqlite3_free(z); - } - if( p->wsFlags & WHERE_SKIPSCAN ){ - sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); - }else{ - sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); - } - sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); - if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ - int i; - for(i=0; inLTerm; i++){ - whereTermPrint(p->aLTerm[i], i); - } - } -} -#endif - -/* -** Convert bulk memory into a valid WhereLoop that can be passed -** to whereLoopClear harmlessly. -*/ -static void whereLoopInit(WhereLoop *p){ - p->aLTerm = p->aLTermSpace; - p->nLTerm = 0; - p->nLSlot = ArraySize(p->aLTermSpace); - p->wsFlags = 0; -} - -/* -** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. -*/ -static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ - if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ - if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ - sqlite3_free(p->u.vtab.idxStr); - p->u.vtab.needFree = 0; - p->u.vtab.idxStr = 0; - }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ - sqlite3DbFree(db, p->u.btree.pIndex->zColAff); - sqlite3DbFree(db, p->u.btree.pIndex); - p->u.btree.pIndex = 0; - } - } -} - -/* -** Deallocate internal memory used by a WhereLoop object -*/ -static void whereLoopClear(sqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); - whereLoopClearUnion(db, p); - whereLoopInit(p); -} - -/* -** Increase the memory allocation for pLoop->aLTerm[] to be at least n. -*/ -static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ - WhereTerm **paNew; - if( p->nLSlot>=n ) return SQLITE_OK; - n = (n+7)&~7; - paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); - if( paNew==0 ) return SQLITE_NOMEM_BKPT; - memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); - if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); - p->aLTerm = paNew; - p->nLSlot = n; - return SQLITE_OK; -} - -/* -** Transfer content from the second pLoop into the first. -*/ -static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ - whereLoopClearUnion(db, pTo); - if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ - memset(&pTo->u, 0, sizeof(pTo->u)); - return SQLITE_NOMEM_BKPT; - } - memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); - memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); - if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ - pFrom->u.vtab.needFree = 0; - }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ - pFrom->u.btree.pIndex = 0; - } - return SQLITE_OK; -} - -/* -** Delete a WhereLoop object -*/ -static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ - whereLoopClear(db, p); - sqlite3DbFree(db, p); -} - -/* -** Free a WhereInfo structure -*/ -static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ - if( ALWAYS(pWInfo) ){ - int i; - for(i=0; inLevel; i++){ - WhereLevel *pLevel = &pWInfo->a[i]; - if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ - sqlite3DbFree(db, pLevel->u.in.aInLoop); - } - } - sqlite3WhereClauseClear(&pWInfo->sWC); - while( pWInfo->pLoops ){ - WhereLoop *p = pWInfo->pLoops; - pWInfo->pLoops = p->pNextLoop; - whereLoopDelete(db, p); - } - sqlite3DbFree(db, pWInfo); - } -} - -/* -** Return TRUE if all of the following are true: -** -** (1) X has the same or lower cost that Y -** (2) X is a proper subset of Y -** (3) X skips at least as many columns as Y -** -** By "proper subset" we mean that X uses fewer WHERE clause terms -** than Y and that every WHERE clause term used by X is also used -** by Y. -** -** If X is a proper subset of Y then Y is a better choice and ought -** to have a lower cost. This routine returns TRUE when that cost -** relationship is inverted and needs to be adjusted. The third rule -** was added because if X uses skip-scan less than Y it still might -** deserve a lower cost even if it is a proper subset of Y. -*/ -static int whereLoopCheaperProperSubset( - const WhereLoop *pX, /* First WhereLoop to compare */ - const WhereLoop *pY /* Compare against this WhereLoop */ -){ - int i, j; - if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ - return 0; /* X is not a subset of Y */ - } - if( pY->nSkip > pX->nSkip ) return 0; - if( pX->rRun >= pY->rRun ){ - if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ - if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ - } - for(i=pX->nLTerm-1; i>=0; i--){ - if( pX->aLTerm[i]==0 ) continue; - for(j=pY->nLTerm-1; j>=0; j--){ - if( pY->aLTerm[j]==pX->aLTerm[i] ) break; - } - if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ - } - return 1; /* All conditions meet */ -} - -/* -** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so -** that: -** -** (1) pTemplate costs less than any other WhereLoops that are a proper -** subset of pTemplate -** -** (2) pTemplate costs more than any other WhereLoops for which pTemplate -** is a proper subset. -** -** To say "WhereLoop X is a proper subset of Y" means that X uses fewer -** WHERE clause terms than Y and that every WHERE clause term used by X is -** also used by Y. -*/ -static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ - if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; - for(; p; p=p->pNextLoop){ - if( p->iTab!=pTemplate->iTab ) continue; - if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; - if( whereLoopCheaperProperSubset(p, pTemplate) ){ - /* Adjust pTemplate cost downward so that it is cheaper than its - ** subset p. */ - WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1)); - pTemplate->rRun = p->rRun; - pTemplate->nOut = p->nOut - 1; - }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ - /* Adjust pTemplate cost upward so that it is costlier than p since - ** pTemplate is a proper subset of p */ - WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1)); - pTemplate->rRun = p->rRun; - pTemplate->nOut = p->nOut + 1; - } - } -} - -/* -** Search the list of WhereLoops in *ppPrev looking for one that can be -** supplanted by pTemplate. -** -** Return NULL if the WhereLoop list contains an entry that can supplant -** pTemplate, in other words if pTemplate does not belong on the list. -** -** If pX is a WhereLoop that pTemplate can supplant, then return the -** link that points to pX. -** -** If pTemplate cannot supplant any existing element of the list but needs -** to be added to the list, then return a pointer to the tail of the list. -*/ -static WhereLoop **whereLoopFindLesser( - WhereLoop **ppPrev, - const WhereLoop *pTemplate -){ - WhereLoop *p; - for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){ - if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ - /* If either the iTab or iSortIdx values for two WhereLoop are different - ** then those WhereLoops need to be considered separately. Neither is - ** a candidate to replace the other. */ - continue; - } - /* In the current implementation, the rSetup value is either zero - ** or the cost of building an automatic index (NlogN) and the NlogN - ** is the same for compatible WhereLoops. */ - assert( p->rSetup==0 || pTemplate->rSetup==0 - || p->rSetup==pTemplate->rSetup ); - - /* whereLoopAddBtree() always generates and inserts the automatic index - ** case first. Hence compatible candidate WhereLoops never have a larger - ** rSetup. Call this SETUP-INVARIANT */ - assert( p->rSetup>=pTemplate->rSetup ); - - /* Any loop using an appliation-defined index (or PRIMARY KEY or - ** UNIQUE constraint) with one or more == constraints is better - ** than an automatic index. Unless it is a skip-scan. */ - if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 - && (pTemplate->nSkip)==0 - && (pTemplate->wsFlags & WHERE_INDEXED)!=0 - && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 - && (p->prereq & pTemplate->prereq)==pTemplate->prereq - ){ - break; - } - - /* If existing WhereLoop p is better than pTemplate, pTemplate can be - ** discarded. WhereLoop p is better if: - ** (1) p has no more dependencies than pTemplate, and - ** (2) p has an equal or lower cost than pTemplate - */ - if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */ - && p->rSetup<=pTemplate->rSetup /* (2a) */ - && p->rRun<=pTemplate->rRun /* (2b) */ - && p->nOut<=pTemplate->nOut /* (2c) */ - ){ - return 0; /* Discard pTemplate */ - } - - /* If pTemplate is always better than p, then cause p to be overwritten - ** with pTemplate. pTemplate is better than p if: - ** (1) pTemplate has no more dependences than p, and - ** (2) pTemplate has an equal or lower cost than p. - */ - if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ - && p->rRun>=pTemplate->rRun /* (2a) */ - && p->nOut>=pTemplate->nOut /* (2b) */ - ){ - assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ - break; /* Cause p to be overwritten by pTemplate */ - } - } - return ppPrev; -} - -/* -** Insert or replace a WhereLoop entry using the template supplied. -** -** An existing WhereLoop entry might be overwritten if the new template -** is better and has fewer dependencies. Or the template will be ignored -** and no insert will occur if an existing WhereLoop is faster and has -** fewer dependencies than the template. Otherwise a new WhereLoop is -** added based on the template. -** -** If pBuilder->pOrSet is not NULL then we care about only the -** prerequisites and rRun and nOut costs of the N best loops. That -** information is gathered in the pBuilder->pOrSet object. This special -** processing mode is used only for OR clause processing. -** -** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we -** still might overwrite similar loops with the new template if the -** new template is better. Loops may be overwritten if the following -** conditions are met: -** -** (1) They have the same iTab. -** (2) They have the same iSortIdx. -** (3) The template has same or fewer dependencies than the current loop -** (4) The template has the same or lower cost than the current loop -*/ -static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ - WhereLoop **ppPrev, *p; - WhereInfo *pWInfo = pBuilder->pWInfo; - sqlite3 *db = pWInfo->pParse->db; - int rc; - - /* If pBuilder->pOrSet is defined, then only keep track of the costs - ** and prereqs. - */ - if( pBuilder->pOrSet!=0 ){ - if( pTemplate->nLTerm ){ -#if WHERETRACE_ENABLED - u16 n = pBuilder->pOrSet->n; - int x = -#endif - whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, - pTemplate->nOut); -#if WHERETRACE_ENABLED /* 0x8 */ - if( sqlite3WhereTrace & 0x8 ){ - sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); - whereLoopPrint(pTemplate, pBuilder->pWC); - } -#endif - } - return SQLITE_OK; - } - - /* Look for an existing WhereLoop to replace with pTemplate - */ - whereLoopAdjustCost(pWInfo->pLoops, pTemplate); - ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); - - if( ppPrev==0 ){ - /* There already exists a WhereLoop on the list that is better - ** than pTemplate, so just ignore pTemplate */ -#if WHERETRACE_ENABLED /* 0x8 */ - if( sqlite3WhereTrace & 0x8 ){ - sqlite3DebugPrintf(" skip: "); - whereLoopPrint(pTemplate, pBuilder->pWC); - } -#endif - return SQLITE_OK; - }else{ - p = *ppPrev; - } - - /* If we reach this point it means that either p[] should be overwritten - ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new - ** WhereLoop and insert it. - */ -#if WHERETRACE_ENABLED /* 0x8 */ - if( sqlite3WhereTrace & 0x8 ){ - if( p!=0 ){ - sqlite3DebugPrintf("replace: "); - whereLoopPrint(p, pBuilder->pWC); - } - sqlite3DebugPrintf(" add: "); - whereLoopPrint(pTemplate, pBuilder->pWC); - } -#endif - if( p==0 ){ - /* Allocate a new WhereLoop to add to the end of the list */ - *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); - if( p==0 ) return SQLITE_NOMEM_BKPT; - whereLoopInit(p); - p->pNextLoop = 0; - }else{ - /* We will be overwriting WhereLoop p[]. But before we do, first - ** go through the rest of the list and delete any other entries besides - ** p[] that are also supplated by pTemplate */ - WhereLoop **ppTail = &p->pNextLoop; - WhereLoop *pToDel; - while( *ppTail ){ - ppTail = whereLoopFindLesser(ppTail, pTemplate); - if( ppTail==0 ) break; - pToDel = *ppTail; - if( pToDel==0 ) break; - *ppTail = pToDel->pNextLoop; -#if WHERETRACE_ENABLED /* 0x8 */ - if( sqlite3WhereTrace & 0x8 ){ - sqlite3DebugPrintf(" delete: "); - whereLoopPrint(pToDel, pBuilder->pWC); - } -#endif - whereLoopDelete(db, pToDel); - } - } - rc = whereLoopXfer(db, p, pTemplate); - if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ - Index *pIndex = p->u.btree.pIndex; - if( pIndex && pIndex->tnum==0 ){ - p->u.btree.pIndex = 0; - } - } - return rc; -} - -/* -** Adjust the WhereLoop.nOut value downward to account for terms of the -** WHERE clause that reference the loop but which are not used by an -** index. -* -** For every WHERE clause term that is not used by the index -** and which has a truth probability assigned by one of the likelihood(), -** likely(), or unlikely() SQL functions, reduce the estimated number -** of output rows by the probability specified. -** -** TUNING: For every WHERE clause term that is not used by the index -** and which does not have an assigned truth probability, heuristics -** described below are used to try to estimate the truth probability. -** TODO --> Perhaps this is something that could be improved by better -** table statistics. -** -** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75% -** value corresponds to -1 in LogEst notation, so this means decrement -** the WhereLoop.nOut field for every such WHERE clause term. -** -** Heuristic 2: If there exists one or more WHERE clause terms of the -** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the -** final output row estimate is no greater than 1/4 of the total number -** of rows in the table. In other words, assume that x==EXPR will filter -** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the -** "x" column is boolean or else -1 or 0 or 1 is a common default value -** on the "x" column and so in that case only cap the output row estimate -** at 1/2 instead of 1/4. -*/ -static void whereLoopOutputAdjust( - WhereClause *pWC, /* The WHERE clause */ - WhereLoop *pLoop, /* The loop to adjust downward */ - LogEst nRow /* Number of rows in the entire table */ -){ - WhereTerm *pTerm, *pX; - Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); - int i, j, k; - LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ - - assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); - for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ - if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; - if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; - if( (pTerm->prereqAll & notAllowed)!=0 ) continue; - for(j=pLoop->nLTerm-1; j>=0; j--){ - pX = pLoop->aLTerm[j]; - if( pX==0 ) continue; - if( pX==pTerm ) break; - if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; - } - if( j<0 ){ - if( pTerm->truthProb<=0 ){ - /* If a truth probability is specified using the likelihood() hints, - ** then use the probability provided by the application. */ - pLoop->nOut += pTerm->truthProb; - }else{ - /* In the absence of explicit truth probabilities, use heuristics to - ** guess a reasonable truth probability. */ - pLoop->nOut--; - if( pTerm->eOperator&(WO_EQ|WO_IS) ){ - Expr *pRight = pTerm->pExpr->pRight; - testcase( pTerm->pExpr->op==TK_IS ); - if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ - k = 10; - }else{ - k = 20; - } - if( iReducenOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; -} - -/* -** Term pTerm is a vector range comparison operation. The first comparison -** in the vector can be optimized using column nEq of the index. This -** function returns the total number of vector elements that can be used -** as part of the range comparison. -** -** For example, if the query is: -** -** WHERE a = ? AND (b, c, d) > (?, ?, ?) -** -** and the index: -** -** CREATE INDEX ... ON (a, b, c, d, e) -** -** then this function would be invoked with nEq=1. The value returned in -** this case is 3. -*/ -static int whereRangeVectorLen( - Parse *pParse, /* Parsing context */ - int iCur, /* Cursor open on pIdx */ - Index *pIdx, /* The index to be used for a inequality constraint */ - int nEq, /* Number of prior equality constraints on same index */ - WhereTerm *pTerm /* The vector inequality constraint */ -){ - int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); - int i; - - nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); - for(i=1; ipExpr->pLeft->x.pList->a[i].pExpr; - Expr *pRhs = pTerm->pExpr->pRight; - if( pRhs->flags & EP_xIsSelect ){ - pRhs = pRhs->x.pSelect->pEList->a[i].pExpr; - }else{ - pRhs = pRhs->x.pList->a[i].pExpr; - } - - /* Check that the LHS of the comparison is a column reference to - ** the right column of the right source table. And that the sort - ** order of the index column is the same as the sort order of the - ** leftmost index column. */ - if( pLhs->op!=TK_COLUMN - || pLhs->iTable!=iCur - || pLhs->iColumn!=pIdx->aiColumn[i+nEq] - || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq] - ){ - break; - } - - testcase( pLhs->iColumn==XN_ROWID ); - aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); - idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); - if( aff!=idxaff ) break; - - pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); - if( pColl==0 ) break; - if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; - } - return i; -} - -/* -** Adjust the cost C by the costMult facter T. This only occurs if -** compiled with -DSQLITE_ENABLE_COSTMULT -*/ -#ifdef SQLITE_ENABLE_COSTMULT -# define ApplyCostMultiplier(C,T) C += T -#else -# define ApplyCostMultiplier(C,T) -#endif - -/* -** We have so far matched pBuilder->pNew->u.btree.nEq terms of the -** index pIndex. Try to match one more. -** -** When this function is called, pBuilder->pNew->nOut contains the -** number of rows expected to be visited by filtering using the nEq -** terms only. If it is modified, this value is restored before this -** function returns. -** -** If pProbe->tnum==0, that means pIndex is a fake index used for the -** INTEGER PRIMARY KEY. -*/ -static int whereLoopAddBtreeIndex( - WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ - struct SrcList_item *pSrc, /* FROM clause term being analyzed */ - Index *pProbe, /* An index on pSrc */ - LogEst nInMul /* log(Number of iterations due to IN) */ -){ - WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ - Parse *pParse = pWInfo->pParse; /* Parsing context */ - sqlite3 *db = pParse->db; /* Database connection malloc context */ - WhereLoop *pNew; /* Template WhereLoop under construction */ - WhereTerm *pTerm; /* A WhereTerm under consideration */ - int opMask; /* Valid operators for constraints */ - WhereScan scan; /* Iterator for WHERE terms */ - Bitmask saved_prereq; /* Original value of pNew->prereq */ - u16 saved_nLTerm; /* Original value of pNew->nLTerm */ - u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ - u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */ - u16 saved_nTop; /* Original value of pNew->u.btree.nTop */ - u16 saved_nSkip; /* Original value of pNew->nSkip */ - u32 saved_wsFlags; /* Original value of pNew->wsFlags */ - LogEst saved_nOut; /* Original value of pNew->nOut */ - int rc = SQLITE_OK; /* Return code */ - LogEst rSize; /* Number of rows in the table */ - LogEst rLogSize; /* Logarithm of table size */ - WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ - - pNew = pBuilder->pNew; - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n", - pProbe->zName, pNew->u.btree.nEq)); - - assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); - assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); - if( pNew->wsFlags & WHERE_BTM_LIMIT ){ - opMask = WO_LT|WO_LE; - }else{ - assert( pNew->u.btree.nBtm==0 ); - opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; - } - if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); - - assert( pNew->u.btree.nEqnColumn ); - - saved_nEq = pNew->u.btree.nEq; - saved_nBtm = pNew->u.btree.nBtm; - saved_nTop = pNew->u.btree.nTop; - saved_nSkip = pNew->nSkip; - saved_nLTerm = pNew->nLTerm; - saved_wsFlags = pNew->wsFlags; - saved_prereq = pNew->prereq; - saved_nOut = pNew->nOut; - pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq, - opMask, pProbe); - pNew->rSetup = 0; - rSize = pProbe->aiRowLogEst[0]; - rLogSize = estLog(rSize); - for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ - u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ - LogEst rCostIdx; - LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ - int nIn = 0; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - int nRecValid = pBuilder->nRecValid; -#endif - if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) - && indexColumnNotNull(pProbe, saved_nEq) - ){ - continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ - } - if( pTerm->prereqRight & pNew->maskSelf ) continue; - - /* Do not allow the upper bound of a LIKE optimization range constraint - ** to mix with a lower range bound from some other source */ - if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; - - /* Do not allow IS constraints from the WHERE clause to be used by the - ** right table of a LEFT JOIN. Only constraints in the ON clause are - ** allowed */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - && (eOp & (WO_IS|WO_ISNULL))!=0 - ){ - testcase( eOp & WO_IS ); - testcase( eOp & WO_ISNULL ); - continue; - } - - pNew->wsFlags = saved_wsFlags; - pNew->u.btree.nEq = saved_nEq; - pNew->u.btree.nBtm = saved_nBtm; - pNew->u.btree.nTop = saved_nTop; - pNew->nLTerm = saved_nLTerm; - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ - pNew->aLTerm[pNew->nLTerm++] = pTerm; - pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; - - assert( nInMul==0 - || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 - || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 - || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 - ); - - if( eOp & WO_IN ){ - Expr *pExpr = pTerm->pExpr; - pNew->wsFlags |= WHERE_COLUMN_IN; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ - int i; - nIn = 46; assert( 46==sqlite3LogEst(25) ); - - /* The expression may actually be of the form (x, y) IN (SELECT...). - ** In this case there is a separate term for each of (x) and (y). - ** However, the nIn multiplier should only be applied once, not once - ** for each such term. The following loop checks that pTerm is the - ** first such term in use, and sets nIn back to 0 if it is not. */ - for(i=0; inLTerm-1; i++){ - if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; - } - }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ - /* "x IN (value, value, ...)" */ - nIn = sqlite3LogEst(pExpr->x.pList->nExpr); - assert( nIn>0 ); /* RHS always has 2 or more terms... The parser - ** changes "x IN (?)" into "x=?". */ - } - }else if( eOp & (WO_EQ|WO_IS) ){ - int iCol = pProbe->aiColumn[saved_nEq]; - pNew->wsFlags |= WHERE_COLUMN_EQ; - assert( saved_nEq==pNew->u.btree.nEq ); - if( iCol==XN_ROWID - || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) - ){ - if( iCol>=0 && pProbe->uniqNotNull==0 ){ - pNew->wsFlags |= WHERE_UNQ_WANTED; - }else{ - pNew->wsFlags |= WHERE_ONEROW; - } - } - }else if( eOp & WO_ISNULL ){ - pNew->wsFlags |= WHERE_COLUMN_NULL; - }else if( eOp & (WO_GT|WO_GE) ){ - testcase( eOp & WO_GT ); - testcase( eOp & WO_GE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; - pNew->u.btree.nBtm = whereRangeVectorLen( - pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm - ); - pBtm = pTerm; - pTop = 0; - if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range contraints that come from the LIKE optimization are - ** always used in pairs. */ - pTop = &pTerm[1]; - assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); - assert( pTop->wtFlags & TERM_LIKEOPT ); - assert( pTop->eOperator==WO_LT ); - if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ - pNew->aLTerm[pNew->nLTerm++] = pTop; - pNew->wsFlags |= WHERE_TOP_LIMIT; - pNew->u.btree.nTop = 1; - } - }else{ - assert( eOp & (WO_LT|WO_LE) ); - testcase( eOp & WO_LT ); - testcase( eOp & WO_LE ); - pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; - pNew->u.btree.nTop = whereRangeVectorLen( - pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm - ); - pTop = pTerm; - pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? - pNew->aLTerm[pNew->nLTerm-2] : 0; - } - - /* At this point pNew->nOut is set to the number of rows expected to - ** be visited by the index scan before considering term pTerm, or the - ** values of nIn and nInMul. In other words, assuming that all - ** "x IN(...)" terms are replaced with "x = ?". This block updates - ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ - assert( pNew->nOut==saved_nOut ); - if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ - /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4 - ** data, using some other estimate. */ - whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); - }else{ - int nEq = ++pNew->u.btree.nEq; - assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) ); - - assert( pNew->nOut==saved_nOut ); - if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){ - assert( (eOp & WO_IN) || nIn==0 ); - testcase( eOp & WO_IN ); - pNew->nOut += pTerm->truthProb; - pNew->nOut -= nIn; - }else{ -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - tRowcnt nOut = 0; - if( nInMul==0 - && pProbe->nSample - && pNew->u.btree.nEq<=pProbe->nSampleCol - && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) - ){ - Expr *pExpr = pTerm->pExpr; - if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ - testcase( eOp & WO_EQ ); - testcase( eOp & WO_IS ); - testcase( eOp & WO_ISNULL ); - rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); - }else{ - rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); - } - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; - if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ - if( nOut ){ - pNew->nOut = sqlite3LogEst(nOut); - if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; - pNew->nOut -= nIn; - } - } - if( nOut==0 ) -#endif - { - pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); - if( eOp & WO_ISNULL ){ - /* TUNING: If there is no likelihood() value, assume that a - ** "col IS NULL" expression matches twice as many rows - ** as (col=?). */ - pNew->nOut += 10; - } - } - } - } - - /* Set rCostIdx to the cost of visiting selected rows in index. Add - ** it to pNew->rRun, which is currently set to the cost of the index - ** seek only. Then, if this is a non-covering index, add the cost of - ** visiting the rows in the main table. */ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; - pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); - if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ - pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); - } - ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); - - nOutUnadjusted = pNew->nOut; - pNew->rRun += nInMul + nIn; - pNew->nOut += nInMul + nIn; - whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); - rc = whereLoopInsert(pBuilder, pNew); - - if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ - pNew->nOut = saved_nOut; - }else{ - pNew->nOut = nOutUnadjusted; - } - - if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 - && pNew->u.btree.nEqnColumn - ){ - whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); - } - pNew->nOut = saved_nOut; -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - pBuilder->nRecValid = nRecValid; -#endif - } - pNew->prereq = saved_prereq; - pNew->u.btree.nEq = saved_nEq; - pNew->u.btree.nBtm = saved_nBtm; - pNew->u.btree.nTop = saved_nTop; - pNew->nSkip = saved_nSkip; - pNew->wsFlags = saved_wsFlags; - pNew->nOut = saved_nOut; - pNew->nLTerm = saved_nLTerm; - - /* Consider using a skip-scan if there are no WHERE clause constraints - ** available for the left-most terms of the index, and if the average - ** number of repeats in the left-most terms is at least 18. - ** - ** The magic number 18 is selected on the basis that scanning 17 rows - ** is almost always quicker than an index seek (even though if the index - ** contains fewer than 2^17 rows we assume otherwise in other parts of - ** the code). And, even if it is not, it should not be too much slower. - ** On the other hand, the extra seeks could end up being significantly - ** more expensive. */ - assert( 42==sqlite3LogEst(18) ); - if( saved_nEq==saved_nSkip - && saved_nEq+1nKeyCol - && pProbe->noSkipScan==0 - && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ - && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK - ){ - LogEst nIter; - pNew->u.btree.nEq++; - pNew->nSkip++; - pNew->aLTerm[pNew->nLTerm++] = 0; - pNew->wsFlags |= WHERE_SKIPSCAN; - nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; - pNew->nOut -= nIter; - /* TUNING: Because uncertainties in the estimates for skip-scan queries, - ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ - nIter += 5; - whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); - pNew->nOut = saved_nOut; - pNew->u.btree.nEq = saved_nEq; - pNew->nSkip = saved_nSkip; - pNew->wsFlags = saved_wsFlags; - } - - WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n", - pProbe->zName, saved_nEq, rc)); - return rc; -} - -/* -** Return True if it is possible that pIndex might be useful in -** implementing the ORDER BY clause in pBuilder. -** -** Return False if pBuilder does not contain an ORDER BY clause or -** if there is no way for pIndex to be useful in implementing that -** ORDER BY clause. -*/ -static int indexMightHelpWithOrderBy( - WhereLoopBuilder *pBuilder, - Index *pIndex, - int iCursor -){ - ExprList *pOB; - ExprList *aColExpr; - int ii, jj; - - if( pIndex->bUnordered ) return 0; - if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; - for(ii=0; iinExpr; ii++){ - Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr); - if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ - if( pExpr->iColumn<0 ) return 1; - for(jj=0; jjnKeyCol; jj++){ - if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; - } - }else if( (aColExpr = pIndex->aColExpr)!=0 ){ - for(jj=0; jjnKeyCol; jj++){ - if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; - if( sqlite3ExprCompare(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ - return 1; - } - } - } - } - return 0; -} - -/* -** Return a bitmask where 1s indicate that the corresponding column of -** the table is used by an index. Only the first 63 columns are considered. -*/ -static Bitmask columnsInIndex(Index *pIdx){ - Bitmask m = 0; - int j; - for(j=pIdx->nColumn-1; j>=0; j--){ - int x = pIdx->aiColumn[j]; - if( x>=0 ){ - testcase( x==BMS-1 ); - testcase( x==BMS-2 ); - if( xop==TK_AND ){ - if( !whereUsablePartialIndex(iTab,pWC,pWhere->pLeft) ) return 0; - pWhere = pWhere->pRight; - } - for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - Expr *pExpr = pTerm->pExpr; - if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) - && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) - ){ - return 1; - } - } - return 0; -} - -/* -** Add all WhereLoop objects for a single table of the join where the table -** is identified by pBuilder->pNew->iTab. That table is guaranteed to be -** a b-tree table, not a virtual table. -** -** The costs (WhereLoop.rRun) of the b-tree loops added by this function -** are calculated as follows: -** -** For a full scan, assuming the table (or index) contains nRow rows: -** -** cost = nRow * 3.0 // full-table scan -** cost = nRow * K // scan of covering index -** cost = nRow * (K+3.0) // scan of non-covering index -** -** where K is a value between 1.1 and 3.0 set based on the relative -** estimated average size of the index and table records. -** -** For an index scan, where nVisit is the number of index rows visited -** by the scan, and nSeek is the number of seek operations required on -** the index b-tree: -** -** cost = nSeek * (log(nRow) + K * nVisit) // covering index -** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index -** -** Normally, nSeek is 1. nSeek values greater than 1 come about if the -** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when -** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. -** -** The estimated values (nRow, nVisit, nSeek) often contain a large amount -** of uncertainty. For this reason, scoring is designed to pick plans that -** "do the least harm" if the estimates are inaccurate. For example, a -** log(nRow) factor is omitted from a non-covering index scan in order to -** bias the scoring in favor of using an index, since the worst-case -** performance of using an index is far better than the worst-case performance -** of a full table scan. -*/ -static int whereLoopAddBtree( - WhereLoopBuilder *pBuilder, /* WHERE clause information */ - Bitmask mPrereq /* Extra prerequesites for using this table */ -){ - WhereInfo *pWInfo; /* WHERE analysis context */ - Index *pProbe; /* An index we are evaluating */ - Index sPk; /* A fake index object for the primary key */ - LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ - i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ - SrcList *pTabList; /* The FROM clause */ - struct SrcList_item *pSrc; /* The FROM clause btree term to add */ - WhereLoop *pNew; /* Template WhereLoop object */ - int rc = SQLITE_OK; /* Return code */ - int iSortIdx = 1; /* Index number */ - int b; /* A boolean value */ - LogEst rSize; /* number of rows in the table */ - LogEst rLogSize; /* Logarithm of the number of rows in the table */ - WhereClause *pWC; /* The parsed WHERE clause */ - Table *pTab; /* Table being queried */ - - pNew = pBuilder->pNew; - pWInfo = pBuilder->pWInfo; - pTabList = pWInfo->pTabList; - pSrc = pTabList->a + pNew->iTab; - pTab = pSrc->pTab; - pWC = pBuilder->pWC; - assert( !IsVirtual(pSrc->pTab) ); - - if( pSrc->pIBIndex ){ - /* An INDEXED BY clause specifies a particular index to use */ - pProbe = pSrc->pIBIndex; - }else if( !HasRowid(pTab) ){ - pProbe = pTab->pIndex; - }else{ - /* There is no INDEXED BY clause. Create a fake Index object in local - ** variable sPk to represent the rowid primary key index. Make this - ** fake index the first in a chain of Index objects with all of the real - ** indices to follow */ - Index *pFirst; /* First of real indices on the table */ - memset(&sPk, 0, sizeof(Index)); - sPk.nKeyCol = 1; - sPk.nColumn = 1; - sPk.aiColumn = &aiColumnPk; - sPk.aiRowLogEst = aiRowEstPk; - sPk.onError = OE_Replace; - sPk.pTable = pTab; - sPk.szIdxRow = pTab->szTabRow; - aiRowEstPk[0] = pTab->nRowLogEst; - aiRowEstPk[1] = 0; - pFirst = pSrc->pTab->pIndex; - if( pSrc->fg.notIndexed==0 ){ - /* The real indices of the table are only considered if the - ** NOT INDEXED qualifier is omitted from the FROM clause */ - sPk.pNext = pFirst; - } - pProbe = &sPk; - } - rSize = pTab->nRowLogEst; - rLogSize = estLog(rSize); - -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX - /* Automatic indexes */ - if( !pBuilder->pOrSet /* Not part of an OR optimization */ - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 - && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ - && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ - && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ - && !pSrc->fg.isCorrelated /* Not a correlated subquery */ - && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ - ){ - /* Generate auto-index WhereLoops */ - WhereTerm *pTerm; - WhereTerm *pWCEnd = pWC->a + pWC->nTerm; - for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; - if( termCanDriveIndex(pTerm, pSrc, 0) ){ - pNew->u.btree.nEq = 1; - pNew->nSkip = 0; - pNew->u.btree.pIndex = 0; - pNew->nLTerm = 1; - pNew->aLTerm[0] = pTerm; - /* TUNING: One-time cost for computing the automatic index is - ** estimated to be X*N*log2(N) where N is the number of rows in - ** the table being indexed and where X is 7 (LogEst=28) for normal - ** tables or 1.375 (LogEst=4) for views and subqueries. The value - ** of X is smaller for views and subqueries so that the query planner - ** will be more aggressive about generating automatic indexes for - ** those objects, since there is no opportunity to add schema - ** indexes on subqueries and views. */ - pNew->rSetup = rLogSize + rSize + 4; - if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ - pNew->rSetup += 24; - } - ApplyCostMultiplier(pNew->rSetup, pTab->costMult); - if( pNew->rSetup<0 ) pNew->rSetup = 0; - /* TUNING: Each index lookup yields 20 rows in the table. This - ** is more than the usual guess of 10 rows, since we have no way - ** of knowing how selective the index will ultimately be. It would - ** not be unreasonable to make this value much larger. */ - pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); - pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); - pNew->wsFlags = WHERE_AUTO_INDEX; - pNew->prereq = mPrereq | pTerm->prereqRight; - rc = whereLoopInsert(pBuilder, pNew); - } - } - } -#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ - - /* Loop over all indices - */ - for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){ - if( pProbe->pPartIdxWhere!=0 - && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){ - testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ - continue; /* Partial index inappropriate for this query */ - } - rSize = pProbe->aiRowLogEst[0]; - pNew->u.btree.nEq = 0; - pNew->u.btree.nBtm = 0; - pNew->u.btree.nTop = 0; - pNew->nSkip = 0; - pNew->nLTerm = 0; - pNew->iSortIdx = 0; - pNew->rSetup = 0; - pNew->prereq = mPrereq; - pNew->nOut = rSize; - pNew->u.btree.pIndex = pProbe; - b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); - /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ - assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); - if( pProbe->tnum<=0 ){ - /* Integer primary key index */ - pNew->wsFlags = WHERE_IPK; - - /* Full table scan */ - pNew->iSortIdx = b ? iSortIdx : 0; - /* TUNING: Cost of full table scan is (N*3.0). */ - pNew->rRun = rSize + 16; - ApplyCostMultiplier(pNew->rRun, pTab->costMult); - whereLoopOutputAdjust(pWC, pNew, rSize); - rc = whereLoopInsert(pBuilder, pNew); - pNew->nOut = rSize; - if( rc ) break; - }else{ - Bitmask m; - if( pProbe->isCovering ){ - pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; - m = 0; - }else{ - m = pSrc->colUsed & ~columnsInIndex(pProbe); - pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; - } - - /* Full scan via index */ - if( b - || !HasRowid(pTab) - || pProbe->pPartIdxWhere!=0 - || ( m==0 - && pProbe->bUnordered==0 - && (pProbe->szIdxRowszTabRow) - && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 - && sqlite3GlobalConfig.bUseCis - && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) - ) - ){ - pNew->iSortIdx = b ? iSortIdx : 0; - - /* The cost of visiting the index rows is N*K, where K is - ** between 1.1 and 3.0, depending on the relative sizes of the - ** index and table rows. */ - pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; - if( m!=0 ){ - /* If this is a non-covering index scan, add in the cost of - ** doing table lookups. The cost will be 3x the number of - ** lookups. Take into account WHERE clause terms that can be - ** satisfied using just the index, and that do not require a - ** table lookup. */ - LogEst nLookup = rSize + 16; /* Base cost: N*3 */ - int ii; - int iCur = pSrc->iCursor; - WhereClause *pWC2 = &pWInfo->sWC; - for(ii=0; iinTerm; ii++){ - WhereTerm *pTerm = &pWC2->a[ii]; - if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ - break; - } - /* pTerm can be evaluated using just the index. So reduce - ** the expected number of table lookups accordingly */ - if( pTerm->truthProb<=0 ){ - nLookup += pTerm->truthProb; - }else{ - nLookup--; - if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19; - } - } - - pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); - } - ApplyCostMultiplier(pNew->rRun, pTab->costMult); - whereLoopOutputAdjust(pWC, pNew, rSize); - rc = whereLoopInsert(pBuilder, pNew); - pNew->nOut = rSize; - if( rc ) break; - } - } - - rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - sqlite3Stat4ProbeFree(pBuilder->pRec); - pBuilder->nRecValid = 0; - pBuilder->pRec = 0; -#endif - - /* If there was an INDEXED BY clause, then only that one index is - ** considered. */ - if( pSrc->pIBIndex ) break; - } - return rc; -} - -#ifndef SQLITE_OMIT_VIRTUALTABLE - -/* -** Argument pIdxInfo is already populated with all constraints that may -** be used by the virtual table identified by pBuilder->pNew->iTab. This -** function marks a subset of those constraints usable, invokes the -** xBestIndex method and adds the returned plan to pBuilder. -** -** A constraint is marked usable if: -** -** * Argument mUsable indicates that its prerequisites are available, and -** -** * It is not one of the operators specified in the mExclude mask passed -** as the fourth argument (which in practice is either WO_IN or 0). -** -** Argument mPrereq is a mask of tables that must be scanned before the -** virtual table in question. These are added to the plans prerequisites -** before it is added to pBuilder. -** -** Output parameter *pbIn is set to true if the plan added to pBuilder -** uses one or more WO_IN terms, or false otherwise. -*/ -static int whereLoopAddVirtualOne( - WhereLoopBuilder *pBuilder, - Bitmask mPrereq, /* Mask of tables that must be used. */ - Bitmask mUsable, /* Mask of usable tables */ - u16 mExclude, /* Exclude terms using these operators */ - sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ - u16 mNoOmit, /* Do not omit these constraints */ - int *pbIn /* OUT: True if plan uses an IN(...) op */ -){ - WhereClause *pWC = pBuilder->pWC; - struct sqlite3_index_constraint *pIdxCons; - struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; - int i; - int mxTerm; - int rc = SQLITE_OK; - WhereLoop *pNew = pBuilder->pNew; - Parse *pParse = pBuilder->pWInfo->pParse; - struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; - int nConstraint = pIdxInfo->nConstraint; - - assert( (mUsable & mPrereq)==mPrereq ); - *pbIn = 0; - pNew->prereq = mPrereq; - - /* Set the usable flag on the subset of constraints identified by - ** arguments mUsable and mExclude. */ - pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; - for(i=0; ia[pIdxCons->iTermOffset]; - pIdxCons->usable = 0; - if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight - && (pTerm->eOperator & mExclude)==0 - ){ - pIdxCons->usable = 1; - } - } - - /* Initialize the output fields of the sqlite3_index_info structure */ - memset(pUsage, 0, sizeof(pUsage[0])*nConstraint); - assert( pIdxInfo->needToFreeIdxStr==0 ); - pIdxInfo->idxStr = 0; - pIdxInfo->idxNum = 0; - pIdxInfo->orderByConsumed = 0; - pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; - pIdxInfo->estimatedRows = 25; - pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; - - /* Invoke the virtual table xBestIndex() method */ - rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); - if( rc ) return rc; - - mxTerm = -1; - assert( pNew->nLSlot>=nConstraint ); - for(i=0; iaLTerm[i] = 0; - pNew->u.vtab.omitMask = 0; - pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; - for(i=0; i=0 ){ - WhereTerm *pTerm; - int j = pIdxCons->iTermOffset; - if( iTerm>=nConstraint - || j<0 - || j>=pWC->nTerm - || pNew->aLTerm[iTerm]!=0 - || pIdxCons->usable==0 - ){ - rc = SQLITE_ERROR; - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - return rc; - } - testcase( iTerm==nConstraint-1 ); - testcase( j==0 ); - testcase( j==pWC->nTerm-1 ); - pTerm = &pWC->a[j]; - pNew->prereq |= pTerm->prereqRight; - assert( iTermnLSlot ); - pNew->aLTerm[iTerm] = pTerm; - if( iTerm>mxTerm ) mxTerm = iTerm; - testcase( iTerm==15 ); - testcase( iTerm==16 ); - if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<eOperator & WO_IN)!=0 ){ - /* A virtual table that is constrained by an IN clause may not - ** consume the ORDER BY clause because (1) the order of IN terms - ** is not necessarily related to the order of output terms and - ** (2) Multiple outputs from a single IN value will not merge - ** together. */ - pIdxInfo->orderByConsumed = 0; - pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; - *pbIn = 1; assert( (mExclude & WO_IN)==0 ); - } - } - } - pNew->u.vtab.omitMask &= ~mNoOmit; - - pNew->nLTerm = mxTerm+1; - assert( pNew->nLTerm<=pNew->nLSlot ); - pNew->u.vtab.idxNum = pIdxInfo->idxNum; - pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; - pIdxInfo->needToFreeIdxStr = 0; - pNew->u.vtab.idxStr = pIdxInfo->idxStr; - pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? - pIdxInfo->nOrderBy : 0); - pNew->rSetup = 0; - pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); - pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); - - /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated - ** that the scan will visit at most one row. Clear it otherwise. */ - if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){ - pNew->wsFlags |= WHERE_ONEROW; - }else{ - pNew->wsFlags &= ~WHERE_ONEROW; - } - rc = whereLoopInsert(pBuilder, pNew); - if( pNew->u.vtab.needFree ){ - sqlite3_free(pNew->u.vtab.idxStr); - pNew->u.vtab.needFree = 0; - } - WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", - *pbIn, (sqlite3_uint64)mPrereq, - (sqlite3_uint64)(pNew->prereq & ~mPrereq))); - - return rc; -} - - -/* -** Add all WhereLoop objects for a table of the join identified by -** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. -** -** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and -** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause -** entries that occur before the virtual table in the FROM clause and are -** separated from it by at least one LEFT or CROSS JOIN. Similarly, the -** mUnusable mask contains all FROM clause entries that occur after the -** virtual table and are separated from it by at least one LEFT or -** CROSS JOIN. -** -** For example, if the query were: -** -** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6; -** -** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6). -** -** All the tables in mPrereq must be scanned before the current virtual -** table. So any terms for which all prerequisites are satisfied by -** mPrereq may be specified as "usable" in all calls to xBestIndex. -** Conversely, all tables in mUnusable must be scanned after the current -** virtual table, so any terms for which the prerequisites overlap with -** mUnusable should always be configured as "not-usable" for xBestIndex. -*/ -static int whereLoopAddVirtual( - WhereLoopBuilder *pBuilder, /* WHERE clause information */ - Bitmask mPrereq, /* Tables that must be scanned before this one */ - Bitmask mUnusable /* Tables that must be scanned after this one */ -){ - int rc = SQLITE_OK; /* Return code */ - WhereInfo *pWInfo; /* WHERE analysis context */ - Parse *pParse; /* The parsing context */ - WhereClause *pWC; /* The WHERE clause */ - struct SrcList_item *pSrc; /* The FROM clause term to search */ - sqlite3_index_info *p; /* Object to pass to xBestIndex() */ - int nConstraint; /* Number of constraints in p */ - int bIn; /* True if plan uses IN(...) operator */ - WhereLoop *pNew; - Bitmask mBest; /* Tables used by best possible plan */ - u16 mNoOmit; - - assert( (mPrereq & mUnusable)==0 ); - pWInfo = pBuilder->pWInfo; - pParse = pWInfo->pParse; - pWC = pBuilder->pWC; - pNew = pBuilder->pNew; - pSrc = &pWInfo->pTabList->a[pNew->iTab]; - assert( IsVirtual(pSrc->pTab) ); - p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy, - &mNoOmit); - if( p==0 ) return SQLITE_NOMEM_BKPT; - pNew->rSetup = 0; - pNew->wsFlags = WHERE_VIRTUALTABLE; - pNew->nLTerm = 0; - pNew->u.vtab.needFree = 0; - nConstraint = p->nConstraint; - if( whereLoopResize(pParse->db, pNew, nConstraint) ){ - sqlite3DbFree(pParse->db, p); - return SQLITE_NOMEM_BKPT; - } - - /* First call xBestIndex() with all constraints usable. */ - WHERETRACE(0x40, (" VirtualOne: all usable\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); - - /* If the call to xBestIndex() with all terms enabled produced a plan - ** that does not require any source tables (IOW: a plan with mBest==0), - ** then there is no point in making any further calls to xBestIndex() - ** since they will all return the same result (if the xBestIndex() - ** implementation is sane). */ - if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){ - int seenZero = 0; /* True if a plan with no prereqs seen */ - int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */ - Bitmask mPrev = 0; - Bitmask mBestNoIn = 0; - - /* If the plan produced by the earlier call uses an IN(...) term, call - ** xBestIndex again, this time with IN(...) terms disabled. */ - if( bIn ){ - WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); - rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn); - assert( bIn==0 ); - mBestNoIn = pNew->prereq & ~mPrereq; - if( mBestNoIn==0 ){ - seenZero = 1; - seenZeroNoIN = 1; - } - } - - /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) - ** in the set of terms that apply to the current virtual table. */ - while( rc==SQLITE_OK ){ - int i; - Bitmask mNext = ALLBITS; - assert( mNext>0 ); - for(i=0; ia[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq - ); - if( mThis>mPrev && mThisprereq==mPrereq ){ - seenZero = 1; - if( bIn==0 ) seenZeroNoIN = 1; - } - } - - /* If the calls to xBestIndex() in the above loop did not find a plan - ** that requires no source tables at all (i.e. one guaranteed to be - ** usable), make a call here with all source tables disabled */ - if( rc==SQLITE_OK && seenZero==0 ){ - WHERETRACE(0x40, (" VirtualOne: all disabled\n")); - rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn); - if( bIn==0 ) seenZeroNoIN = 1; - } - - /* If the calls to xBestIndex() have so far failed to find a plan - ** that requires no source tables at all and does not use an IN(...) - ** operator, make a final call to obtain one here. */ - if( rc==SQLITE_OK && seenZeroNoIN==0 ){ - WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); - rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); - } - } - - if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFree(pParse->db, p); - return rc; -} -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/* -** Add WhereLoop entries to handle OR terms. This works for either -** btrees or virtual tables. -*/ -static int whereLoopAddOr( - WhereLoopBuilder *pBuilder, - Bitmask mPrereq, - Bitmask mUnusable -){ - WhereInfo *pWInfo = pBuilder->pWInfo; - WhereClause *pWC; - WhereLoop *pNew; - WhereTerm *pTerm, *pWCEnd; - int rc = SQLITE_OK; - int iCur; - WhereClause tempWC; - WhereLoopBuilder sSubBuild; - WhereOrSet sSum, sCur; - struct SrcList_item *pItem; - - pWC = pBuilder->pWC; - pWCEnd = pWC->a + pWC->nTerm; - pNew = pBuilder->pNew; - memset(&sSum, 0, sizeof(sSum)); - pItem = pWInfo->pTabList->a + pNew->iTab; - iCur = pItem->iCursor; - - for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 - && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 - ){ - WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; - WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; - WhereTerm *pOrTerm; - int once = 1; - int i, j; - - sSubBuild = *pBuilder; - sSubBuild.pOrderBy = 0; - sSubBuild.pOrSet = &sCur; - - WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); - for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ - sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; - }else if( pOrTerm->leftCursor==iCur ){ - tempWC.pWInfo = pWC->pWInfo; - tempWC.pOuter = pWC; - tempWC.op = TK_AND; - tempWC.nTerm = 1; - tempWC.a = pOrTerm; - sSubBuild.pWC = &tempWC; - }else{ - continue; - } - sCur.n = 0; -#ifdef WHERETRACE_ENABLED - WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", - (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); - if( sqlite3WhereTrace & 0x400 ){ - sqlite3WhereClausePrint(sSubBuild.pWC); - } -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ - rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); - }else -#endif - { - rc = whereLoopAddBtree(&sSubBuild, mPrereq); - } - if( rc==SQLITE_OK ){ - rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); - } - assert( rc==SQLITE_OK || sCur.n==0 ); - if( sCur.n==0 ){ - sSum.n = 0; - break; - }else if( once ){ - whereOrMove(&sSum, &sCur); - once = 0; - }else{ - WhereOrSet sPrev; - whereOrMove(&sPrev, &sSum); - sSum.n = 0; - for(i=0; inLTerm = 1; - pNew->aLTerm[0] = pTerm; - pNew->wsFlags = WHERE_MULTI_OR; - pNew->rSetup = 0; - pNew->iSortIdx = 0; - memset(&pNew->u, 0, sizeof(pNew->u)); - for(i=0; rc==SQLITE_OK && irRun = sSum.a[i].rRun + 1; - pNew->nOut = sSum.a[i].nOut; - pNew->prereq = sSum.a[i].prereq; - rc = whereLoopInsert(pBuilder, pNew); - } - WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm)); - } - } - return rc; -} - -/* -** Add all WhereLoop objects for all tables -*/ -static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ - WhereInfo *pWInfo = pBuilder->pWInfo; - Bitmask mPrereq = 0; - Bitmask mPrior = 0; - int iTab; - SrcList *pTabList = pWInfo->pTabList; - struct SrcList_item *pItem; - struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; - sqlite3 *db = pWInfo->pParse->db; - int rc = SQLITE_OK; - WhereLoop *pNew; - u8 priorJointype = 0; - - /* Loop over the tables in the join, from left to right */ - pNew = pBuilder->pNew; - whereLoopInit(pNew); - for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; - pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ - /* This condition is true when pItem is the FROM clause term on the - ** right-hand-side of a LEFT or CROSS JOIN. */ - mPrereq = mPrior; - } - priorJointype = pItem->fg.jointype; -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; - for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ - mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); - } - } - rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); - }else -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - { - rc = whereLoopAddBtree(pBuilder, mPrereq); - } - if( rc==SQLITE_OK ){ - rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); - } - mPrior |= pNew->maskSelf; - if( rc || db->mallocFailed ) break; - } - - whereLoopClear(db, pNew); - return rc; -} - -/* -** Examine a WherePath (with the addition of the extra WhereLoop of the 5th -** parameters) to see if it outputs rows in the requested ORDER BY -** (or GROUP BY) without requiring a separate sort operation. Return N: -** -** N>0: N terms of the ORDER BY clause are satisfied -** N==0: No terms of the ORDER BY clause are satisfied -** N<0: Unknown yet how many terms of ORDER BY might be satisfied. -** -** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as -** strict. With GROUP BY and DISTINCT the only requirement is that -** equivalent rows appear immediately adjacent to one another. GROUP BY -** and DISTINCT do not require rows to appear in any particular order as long -** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT -** the pOrderBy terms can be matched in any order. With ORDER BY, the -** pOrderBy terms must be matched in strict left-to-right order. -*/ -static i8 wherePathSatisfiesOrderBy( - WhereInfo *pWInfo, /* The WHERE clause */ - ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ - WherePath *pPath, /* The WherePath to check */ - u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ - u16 nLoop, /* Number of entries in pPath->aLoop[] */ - WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ - Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ -){ - u8 revSet; /* True if rev is known */ - u8 rev; /* Composite sort order */ - u8 revIdx; /* Index sort order */ - u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ - u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ - u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ - u16 eqOpMask; /* Allowed equality operators */ - u16 nKeyCol; /* Number of key columns in pIndex */ - u16 nColumn; /* Total number of ordered columns in the index */ - u16 nOrderBy; /* Number terms in the ORDER BY clause */ - int iLoop; /* Index of WhereLoop in pPath being processed */ - int i, j; /* Loop counters */ - int iCur; /* Cursor number for current WhereLoop */ - int iColumn; /* A column number within table iCur */ - WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */ - WhereTerm *pTerm; /* A single term of the WHERE clause */ - Expr *pOBExpr; /* An expression from the ORDER BY clause */ - CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */ - Index *pIndex; /* The index associated with pLoop */ - sqlite3 *db = pWInfo->pParse->db; /* Database connection */ - Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */ - Bitmask obDone; /* Mask of all ORDER BY terms */ - Bitmask orderDistinctMask; /* Mask of all well-ordered loops */ - Bitmask ready; /* Mask of inner loops */ - - /* - ** We say the WhereLoop is "one-row" if it generates no more than one - ** row of output. A WhereLoop is one-row if all of the following are true: - ** (a) All index columns match with WHERE_COLUMN_EQ. - ** (b) The index is unique - ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row. - ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags. - ** - ** We say the WhereLoop is "order-distinct" if the set of columns from - ** that WhereLoop that are in the ORDER BY clause are different for every - ** row of the WhereLoop. Every one-row WhereLoop is automatically - ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause - ** is not order-distinct. To be order-distinct is not quite the same as being - ** UNIQUE since a UNIQUE column or index can have multiple rows that - ** are NULL and NULL values are equivalent for the purpose of order-distinct. - ** To be order-distinct, the columns must be UNIQUE and NOT NULL. - ** - ** The rowid for a table is always UNIQUE and NOT NULL so whenever the - ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is - ** automatically order-distinct. - */ - - assert( pOrderBy!=0 ); - if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; - - nOrderBy = pOrderBy->nExpr; - testcase( nOrderBy==BMS-1 ); - if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ - isOrderDistinct = 1; - obDone = MASKBIT(nOrderBy)-1; - orderDistinctMask = 0; - ready = 0; - eqOpMask = WO_EQ | WO_IS | WO_ISNULL; - if( wctrlFlags & WHERE_ORDERBY_LIMIT ) eqOpMask |= WO_IN; - for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; - if( iLoopaLoop[iLoop]; - if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; - }else{ - pLoop = pLast; - } - if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered ) obSat = obDone; - break; - } - iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; - - /* Mark off any ORDER BY term X that is a column in the table of - ** the current loop for which there is term in the WHERE - ** clause of the form X IS NULL or X=? that reference only outer - ** loops. - */ - for(i=0; ia[i].pExpr); - if( pOBExpr->op!=TK_COLUMN ) continue; - if( pOBExpr->iTable!=iCur ) continue; - pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, - ~ready, eqOpMask, 0); - if( pTerm==0 ) continue; - if( pTerm->eOperator==WO_IN ){ - /* IN terms are only valid for sorting in the ORDER BY LIMIT - ** optimization, and then only if they are actually used - ** by the query plan */ - assert( wctrlFlags & WHERE_ORDERBY_LIMIT ); - for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){} - if( j>=pLoop->nLTerm ) continue; - } - if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ - const char *z1, *z2; - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( !pColl ) pColl = db->pDfltColl; - z1 = pColl->zName; - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr); - if( !pColl ) pColl = db->pDfltColl; - z2 = pColl->zName; - if( sqlite3StrICmp(z1, z2)!=0 ) continue; - testcase( pTerm->pExpr->op==TK_IS ); - } - obSat |= MASKBIT(i); - } - - if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ - if( pLoop->wsFlags & WHERE_IPK ){ - pIndex = 0; - nKeyCol = 0; - nColumn = 1; - }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ - return 0; - }else{ - nKeyCol = pIndex->nKeyCol; - nColumn = pIndex->nColumn; - assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); - assert( pIndex->aiColumn[nColumn-1]==XN_ROWID - || !HasRowid(pIndex->pTable)); - isOrderDistinct = IsUniqueIndex(pIndex); - } - - /* Loop through all columns of the index and deal with the ones - ** that are not constrained by == or IN. - */ - rev = revSet = 0; - distinctColumns = 0; - for(j=0; j=pLoop->u.btree.nEq - || (pLoop->aLTerm[j]==0)==(jnSkip) - ); - if( ju.btree.nEq && j>=pLoop->nSkip ){ - u16 eOp = pLoop->aLTerm[j]->eOperator; - - /* Skip over == and IS and ISNULL terms. (Also skip IN terms when - ** doing WHERE_ORDERBY_LIMIT processing). - ** - ** If the current term is a column of an ((?,?) IN (SELECT...)) - ** expression for which the SELECT returns more than one column, - ** check that it is the only column used by this loop. Otherwise, - ** if it is one of two or more, none of the columns can be - ** considered to match an ORDER BY term. */ - if( (eOp & eqOpMask)!=0 ){ - if( eOp & WO_ISNULL ){ - testcase( isOrderDistinct ); - isOrderDistinct = 0; - } - continue; - }else if( ALWAYS(eOp & WO_IN) ){ - /* ALWAYS() justification: eOp is an equality operator due to the - ** ju.btree.nEq constraint above. Any equality other - ** than WO_IN is captured by the previous "if". So this one - ** always has to be WO_IN. */ - Expr *pX = pLoop->aLTerm[j]->pExpr; - for(i=j+1; iu.btree.nEq; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - assert( (pLoop->aLTerm[i]->eOperator & WO_IN) ); - bOnce = 0; - break; - } - } - } - } - - /* Get the column number in the table (iColumn) and sort order - ** (revIdx) for the j-th column of the index. - */ - if( pIndex ){ - iColumn = pIndex->aiColumn[j]; - revIdx = pIndex->aSortOrder[j]; - if( iColumn==pIndex->pTable->iPKey ) iColumn = -1; - }else{ - iColumn = XN_ROWID; - revIdx = 0; - } - - /* An unconstrained column that might be NULL means that this - ** WhereLoop is not well-ordered - */ - if( isOrderDistinct - && iColumn>=0 - && j>=pLoop->u.btree.nEq - && pIndex->pTable->aCol[iColumn].notNull==0 - ){ - isOrderDistinct = 0; - } - - /* Find the ORDER BY term that corresponds to the j-th column - ** of the index and mark that ORDER BY term off - */ - isMatch = 0; - for(i=0; bOnce && ia[i].pExpr); - testcase( wctrlFlags & WHERE_GROUPBY ); - testcase( wctrlFlags & WHERE_DISTINCTBY ); - if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; - if( iColumn>=(-1) ){ - if( pOBExpr->op!=TK_COLUMN ) continue; - if( pOBExpr->iTable!=iCur ) continue; - if( pOBExpr->iColumn!=iColumn ) continue; - }else{ - if( sqlite3ExprCompare(pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){ - continue; - } - } - if( iColumn>=0 ){ - pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( !pColl ) pColl = db->pDfltColl; - if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; - } - isMatch = 1; - break; - } - if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ - /* Make sure the sort order is compatible in an ORDER BY clause. - ** Sort order is irrelevant for a GROUP BY clause. */ - if( revSet ){ - if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; - }else{ - rev = revIdx ^ pOrderBy->a[i].sortOrder; - if( rev ) *pRevMask |= MASKBIT(iLoop); - revSet = 1; - } - } - if( isMatch ){ - if( iColumn==XN_ROWID ){ - testcase( distinctColumns==0 ); - distinctColumns = 1; - } - obSat |= MASKBIT(i); - }else{ - /* No match found */ - if( j==0 || jmaskSelf; - for(i=0; ia[i].pExpr; - mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); - if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; - if( (mTerm&~orderDistinctMask)==0 ){ - obSat |= MASKBIT(i); - } - } - } - } /* End the loop over all WhereLoops from outer-most down to inner-most */ - if( obSat==obDone ) return (i8)nOrderBy; - if( !isOrderDistinct ){ - for(i=nOrderBy-1; i>0; i--){ - Bitmask m = MASKBIT(i) - 1; - if( (obSat&m)==m ) return i; - } - return 0; - } - return -1; -} - - -/* -** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(), -** the planner assumes that the specified pOrderBy list is actually a GROUP -** BY clause - and so any order that groups rows as required satisfies the -** request. -** -** Normally, in this case it is not possible for the caller to determine -** whether or not the rows are really being delivered in sorted order, or -** just in some other order that provides the required grouping. However, -** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then -** this function may be called on the returned WhereInfo object. It returns -** true if the rows really will be sorted in the specified order, or false -** otherwise. -** -** For example, assuming: -** -** CREATE INDEX i1 ON t1(x, Y); -** -** then -** -** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 -** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 -*/ -SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ - assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); - assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); - return pWInfo->sorted; -} - -#ifdef WHERETRACE_ENABLED -/* For debugging use only: */ -static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ - static char zName[65]; - int i; - for(i=0; iaLoop[i]->cId; } - if( pLast ) zName[i++] = pLast->cId; - zName[i] = 0; - return zName; -} -#endif - -/* -** Return the cost of sorting nRow rows, assuming that the keys have -** nOrderby columns and that the first nSorted columns are already in -** order. -*/ -static LogEst whereSortingCost( - WhereInfo *pWInfo, - LogEst nRow, - int nOrderBy, - int nSorted -){ - /* TUNING: Estimated cost of a full external sort, where N is - ** the number of rows to sort is: - ** - ** cost = (3.0 * N * log(N)). - ** - ** Or, if the order-by clause has X terms but only the last Y - ** terms are out of order, then block-sorting will reduce the - ** sorting cost to: - ** - ** cost = (3.0 * N * log(N)) * (Y/X) - ** - ** The (Y/X) term is implemented using stack variable rScale - ** below. */ - LogEst rScale, rSortCost; - assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); - rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; - rSortCost = nRow + rScale + 16; - - /* Multiple by log(M) where M is the number of output rows. - ** Use the LIMIT for M if it is smaller */ - if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimitiLimit; - } - rSortCost += estLog(nRow); - return rSortCost; -} - -/* -** Given the list of WhereLoop objects at pWInfo->pLoops, this routine -** attempts to find the lowest cost path that visits each WhereLoop -** once. This path is then loaded into the pWInfo->a[].pWLoop fields. -** -** Assume that the total number of output rows that will need to be sorted -** will be nRowEst (in the 10*log2 representation). Or, ignore sorting -** costs if nRowEst==0. -** -** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation -** error occurs. -*/ -static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ - int mxChoice; /* Maximum number of simultaneous paths tracked */ - int nLoop; /* Number of terms in the join */ - Parse *pParse; /* Parsing context */ - sqlite3 *db; /* The database connection */ - int iLoop; /* Loop counter over the terms of the join */ - int ii, jj; /* Loop counters */ - int mxI = 0; /* Index of next entry to replace */ - int nOrderBy; /* Number of ORDER BY clause terms */ - LogEst mxCost = 0; /* Maximum cost of a set of paths */ - LogEst mxUnsorted = 0; /* Maximum unsorted cost of a set of path */ - int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ - WherePath *aFrom; /* All nFrom paths at the previous level */ - WherePath *aTo; /* The nTo best paths at the current level */ - WherePath *pFrom; /* An element of aFrom[] that we are working on */ - WherePath *pTo; /* An element of aTo[] that we are working on */ - WhereLoop *pWLoop; /* One of the WhereLoop objects */ - WhereLoop **pX; /* Used to divy up the pSpace memory */ - LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ - char *pSpace; /* Temporary memory used by this routine */ - int nSpace; /* Bytes of space allocated at pSpace */ - - pParse = pWInfo->pParse; - db = pParse->db; - nLoop = pWInfo->nLevel; - /* TUNING: For simple queries, only the best path is tracked. - ** For 2-way joins, the 5 best paths are followed. - ** For joins of 3 or more tables, track the 10 best paths */ - mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); - assert( nLoop<=pWInfo->pTabList->nSrc ); - WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); - - /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this - ** case the purpose of this call is to estimate the number of rows returned - ** by the overall query. Once this estimate has been obtained, the caller - ** will invoke this function a second time, passing the estimate as the - ** nRowEst parameter. */ - if( pWInfo->pOrderBy==0 || nRowEst==0 ){ - nOrderBy = 0; - }else{ - nOrderBy = pWInfo->pOrderBy->nExpr; - } - - /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ - nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; - nSpace += sizeof(LogEst) * nOrderBy; - pSpace = sqlite3DbMallocRawNN(db, nSpace); - if( pSpace==0 ) return SQLITE_NOMEM_BKPT; - aTo = (WherePath*)pSpace; - aFrom = aTo+mxChoice; - memset(aFrom, 0, sizeof(aFrom[0])); - pX = (WhereLoop**)(aFrom+mxChoice); - for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){ - pFrom->aLoop = pX; - } - if( nOrderBy ){ - /* If there is an ORDER BY clause and it is not being ignored, set up - ** space for the aSortCost[] array. Each element of the aSortCost array - ** is either zero - meaning it has not yet been initialized - or the - ** cost of sorting nRowEst rows of data where the first X terms of - ** the ORDER BY clause are already in order, where X is the array - ** index. */ - aSortCost = (LogEst*)pX; - memset(aSortCost, 0, sizeof(LogEst) * nOrderBy); - } - assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] ); - assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX ); - - /* Seed the search with a single WherePath containing zero WhereLoops. - ** - ** TUNING: Do not let the number of iterations go above 28. If the cost - ** of computing an automatic index is not paid back within the first 28 - ** rows, then do not use the automatic index. */ - aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); - nFrom = 1; - assert( aFrom[0].isOrdered==0 ); - if( nOrderBy ){ - /* If nLoop is zero, then there are no FROM terms in the query. Since - ** in this case the query may return a maximum of one row, the results - ** are already in the requested order. Set isOrdered to nOrderBy to - ** indicate this. Or, if nLoop is greater than zero, set isOrdered to - ** -1, indicating that the result set may or may not be ordered, - ** depending on the loops added to the current plan. */ - aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy; - } - - /* Compute successively longer WherePaths using the previous generation - ** of WherePaths as the basis for the next. Keep track of the mxChoice - ** best paths at each generation */ - for(iLoop=0; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ - LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ - LogEst rCost; /* Cost of path (pFrom+pWLoop) */ - LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ - i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ - Bitmask maskNew; /* Mask of src visited by (..) */ - Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ - - if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; - if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; - if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){ - /* Do not use an automatic index if the this loop is expected - ** to run less than 2 times. */ - assert( 10==sqlite3LogEst(2) ); - continue; - } - /* At this point, pWLoop is a candidate to be the next loop. - ** Compute its cost */ - rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); - rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); - nOut = pFrom->nRow + pWLoop->nOut; - maskNew = pFrom->maskLoop | pWLoop->maskSelf; - if( isOrdered<0 ){ - isOrdered = wherePathSatisfiesOrderBy(pWInfo, - pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, - iLoop, pWLoop, &revMask); - }else{ - revMask = pFrom->revLoop; - } - if( isOrdered>=0 && isOrderedisOrdered^isOrdered)&0x80)==0" is equivalent - ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range - ** of legal values for isOrdered, -1..64. - */ - for(jj=0, pTo=aTo; jjmaskLoop==maskNew - && ((pTo->isOrdered^isOrdered)&0x80)==0 - ){ - testcase( jj==nTo-1 ); - break; - } - } - if( jj>=nTo ){ - /* None of the existing best-so-far paths match the candidate. */ - if( nTo>=mxChoice - && (rCost>mxCost || (rCost==mxCost && rUnsorted>=mxUnsorted)) - ){ - /* The current candidate is no better than any of the mxChoice - ** paths currently in the best-so-far buffer. So discard - ** this candidate as not viable. */ -#ifdef WHERETRACE_ENABLED /* 0x4 */ - if( sqlite3WhereTrace&0x4 ){ - sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n", - wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, - isOrdered>=0 ? isOrdered+'0' : '?'); - } -#endif - continue; - } - /* If we reach this points it means that the new candidate path - ** needs to be added to the set of best-so-far paths. */ - if( nTo=0 ? isOrdered+'0' : '?'); - } -#endif - }else{ - /* Control reaches here if best-so-far path pTo=aTo[jj] covers the - ** same set of loops and has the sam isOrdered setting as the - ** candidate path. Check to see if the candidate should replace - ** pTo or if the candidate should be skipped */ - if( pTo->rCostrCost==rCost && pTo->nRow<=nOut) ){ -#ifdef WHERETRACE_ENABLED /* 0x4 */ - if( sqlite3WhereTrace&0x4 ){ - sqlite3DebugPrintf( - "Skip %s cost=%-3d,%3d order=%c", - wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, - isOrdered>=0 ? isOrdered+'0' : '?'); - sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n", - wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, - pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); - } -#endif - /* Discard the candidate path from further consideration */ - testcase( pTo->rCost==rCost ); - continue; - } - testcase( pTo->rCost==rCost+1 ); - /* Control reaches here if the candidate path is better than the - ** pTo path. Replace pTo with the candidate. */ -#ifdef WHERETRACE_ENABLED /* 0x4 */ - if( sqlite3WhereTrace&0x4 ){ - sqlite3DebugPrintf( - "Update %s cost=%-3d,%3d order=%c", - wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, - isOrdered>=0 ? isOrdered+'0' : '?'); - sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n", - wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, - pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); - } -#endif - } - /* pWLoop is a winner. Add it to the set of best so far */ - pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; - pTo->revLoop = revMask; - pTo->nRow = nOut; - pTo->rCost = rCost; - pTo->rUnsorted = rUnsorted; - pTo->isOrdered = isOrdered; - memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); - pTo->aLoop[iLoop] = pWLoop; - if( nTo>=mxChoice ){ - mxI = 0; - mxCost = aTo[0].rCost; - mxUnsorted = aTo[0].nRow; - for(jj=1, pTo=&aTo[1]; jjrCost>mxCost - || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted) - ){ - mxCost = pTo->rCost; - mxUnsorted = pTo->rUnsorted; - mxI = jj; - } - } - } - } - } - -#ifdef WHERETRACE_ENABLED /* >=2 */ - if( sqlite3WhereTrace & 0x02 ){ - sqlite3DebugPrintf("---- after round %d ----\n", iLoop); - for(ii=0, pTo=aTo; iirCost, pTo->nRow, - pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); - if( pTo->isOrdered>0 ){ - sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); - }else{ - sqlite3DebugPrintf("\n"); - } - } - } -#endif - - /* Swap the roles of aFrom and aTo for the next generation */ - pFrom = aTo; - aTo = aFrom; - aFrom = pFrom; - nFrom = nTo; - } - - if( nFrom==0 ){ - sqlite3ErrorMsg(pParse, "no query solution"); - sqlite3DbFree(db, pSpace); - return SQLITE_ERROR; - } - - /* Find the lowest cost path. pFrom will be left pointing to that path */ - pFrom = aFrom; - for(ii=1; iirCost>aFrom[ii].rCost ) pFrom = &aFrom[ii]; - } - assert( pWInfo->nLevel==nLoop ); - /* Load the lowest cost path into pWInfo */ - for(iLoop=0; iLoopa + iLoop; - pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; - pLevel->iFrom = pWLoop->iTab; - pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; - } - if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 - && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 - && pWInfo->eDistinct==WHERE_DISTINCT_NOOP - && nRowEst - ){ - Bitmask notUsed; - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom, - WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); - if( rc==pWInfo->pDistinctSet->nExpr ){ - pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; - } - } - if( pWInfo->pOrderBy ){ - if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ - if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ - pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; - } - }else{ - pWInfo->nOBSat = pFrom->isOrdered; - pWInfo->revMask = pFrom->revLoop; - if( pWInfo->nOBSat<=0 ){ - pWInfo->nOBSat = 0; - if( nLoop>0 ){ - u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; - if( (wsFlags & WHERE_ONEROW)==0 - && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) - ){ - Bitmask m = 0; - int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, - WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); - testcase( wsFlags & WHERE_IPK ); - testcase( wsFlags & WHERE_COLUMN_IN ); - if( rc==pWInfo->pOrderBy->nExpr ){ - pWInfo->bOrderedInnerLoop = 1; - pWInfo->revMask = m; - } - } - } - } - } - if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) - && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 - ){ - Bitmask revMask = 0; - int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, - pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask - ); - assert( pWInfo->sorted==0 ); - if( nOrder==pWInfo->pOrderBy->nExpr ){ - pWInfo->sorted = 1; - pWInfo->revMask = revMask; - } - } - } - - - pWInfo->nRowOut = pFrom->nRow; - - /* Free temporary memory and return success */ - sqlite3DbFree(db, pSpace); - return SQLITE_OK; -} - -/* -** Most queries use only a single table (they are not joins) and have -** simple == constraints against indexed fields. This routine attempts -** to plan those simple cases using much less ceremony than the -** general-purpose query planner, and thereby yield faster sqlite3_prepare() -** times for the common case. -** -** Return non-zero on success, if this query can be handled by this -** no-frills query planner. Return zero if this query needs the -** general-purpose query planner. -*/ -static int whereShortCut(WhereLoopBuilder *pBuilder){ - WhereInfo *pWInfo; - struct SrcList_item *pItem; - WhereClause *pWC; - WhereTerm *pTerm; - WhereLoop *pLoop; - int iCur; - int j; - Table *pTab; - Index *pIdx; - - pWInfo = pBuilder->pWInfo; - if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; - assert( pWInfo->pTabList->nSrc>=1 ); - pItem = pWInfo->pTabList->a; - pTab = pItem->pTab; - if( IsVirtual(pTab) ) return 0; - if( pItem->fg.isIndexedBy ) return 0; - iCur = pItem->iCursor; - pWC = &pWInfo->sWC; - pLoop = pBuilder->pNew; - pLoop->wsFlags = 0; - pLoop->nSkip = 0; - pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0); - if( pTerm ){ - testcase( pTerm->eOperator & WO_IS ); - pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; - pLoop->aLTerm[0] = pTerm; - pLoop->nLTerm = 1; - pLoop->u.btree.nEq = 1; - /* TUNING: Cost of a rowid lookup is 10 */ - pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ - }else{ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int opMask; - assert( pLoop->aLTermSpace==pLoop->aLTerm ); - if( !IsUniqueIndex(pIdx) - || pIdx->pPartIdxWhere!=0 - || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) - ) continue; - opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; - for(j=0; jnKeyCol; j++){ - pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx); - if( pTerm==0 ) break; - testcase( pTerm->eOperator & WO_IS ); - pLoop->aLTerm[j] = pTerm; - } - if( j!=pIdx->nKeyCol ) continue; - pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; - if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ - pLoop->wsFlags |= WHERE_IDX_ONLY; - } - pLoop->nLTerm = j; - pLoop->u.btree.nEq = j; - pLoop->u.btree.pIndex = pIdx; - /* TUNING: Cost of a unique index lookup is 15 */ - pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ - break; - } - } - if( pLoop->wsFlags ){ - pLoop->nOut = (LogEst)1; - pWInfo->a[0].pWLoop = pLoop; - pLoop->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); - pWInfo->a[0].iTabCur = iCur; - pWInfo->nRowOut = 1; - if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; - if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ - pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; - } -#ifdef SQLITE_DEBUG - pLoop->cId = '0'; -#endif - return 1; - } - return 0; -} - -/* -** Generate the beginning of the loop used for WHERE clause processing. -** The return value is a pointer to an opaque structure that contains -** information needed to terminate the loop. Later, the calling routine -** should invoke sqlite3WhereEnd() with the return value of this function -** in order to complete the WHERE clause processing. -** -** If an error occurs, this routine returns NULL. -** -** The basic idea is to do a nested loop, one loop for each table in -** the FROM clause of a select. (INSERT and UPDATE statements are the -** same as a SELECT with only a single table in the FROM clause.) For -** example, if the SQL is this: -** -** SELECT * FROM t1, t2, t3 WHERE ...; -** -** Then the code generated is conceptually like the following: -** -** foreach row1 in t1 do \ Code generated -** foreach row2 in t2 do |-- by sqlite3WhereBegin() -** foreach row3 in t3 do / -** ... -** end \ Code generated -** end |-- by sqlite3WhereEnd() -** end / -** -** Note that the loops might not be nested in the order in which they -** appear in the FROM clause if a different order is better able to make -** use of indices. Note also that when the IN operator appears in -** the WHERE clause, it might result in additional nested loops for -** scanning through all values on the right-hand side of the IN. -** -** There are Btree cursors associated with each table. t1 uses cursor -** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. -** And so forth. This routine generates code to open those VDBE cursors -** and sqlite3WhereEnd() generates the code to close them. -** -** The code that sqlite3WhereBegin() generates leaves the cursors named -** in pTabList pointing at their appropriate entries. The [...] code -** can use OP_Column and OP_Rowid opcodes on these cursors to extract -** data from the various tables of the loop. -** -** If the WHERE clause is empty, the foreach loops must each scan their -** entire tables. Thus a three-way join is an O(N^3) operation. But if -** the tables have indices and there are terms in the WHERE clause that -** refer to those indices, a complete table scan can be avoided and the -** code will run much faster. Most of the work of this routine is checking -** to see if there are indices that can be used to speed up the loop. -** -** Terms of the WHERE clause are also used to limit which rows actually -** make it to the "..." in the middle of the loop. After each "foreach", -** terms of the WHERE clause that use only terms in that loop and outer -** loops are evaluated and if false a jump is made around all subsequent -** inner loops (or around the "..." if the test occurs within the inner- -** most loop) -** -** OUTER JOINS -** -** An outer join of tables t1 and t2 is conceptally coded as follows: -** -** foreach row1 in t1 do -** flag = 0 -** foreach row2 in t2 do -** start: -** ... -** flag = 1 -** end -** if flag==0 then -** move the row2 cursor to a null row -** goto start -** fi -** end -** -** ORDER BY CLAUSE PROCESSING -** -** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause -** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement -** if there is one. If there is no ORDER BY clause or if this routine -** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. -** -** The iIdxCur parameter is the cursor number of an index. If -** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index -** to use for OR clause processing. The WHERE clause should use this -** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is -** the first cursor in an array of cursors for all indices. iIdxCur should -** be used to compute the appropriate cursor depending on which index is -** used. -*/ -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( - Parse *pParse, /* The parser context */ - SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ - Expr *pWhere, /* The WHERE clause */ - ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ - ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */ - u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ - int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number - ** If WHERE_USE_LIMIT, then the limit amount */ -){ - int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ - int nTabList; /* Number of elements in pTabList */ - WhereInfo *pWInfo; /* Will become the return value of this function */ - Vdbe *v = pParse->pVdbe; /* The virtual database engine */ - Bitmask notReady; /* Cursors that are not yet positioned */ - WhereLoopBuilder sWLB; /* The WhereLoop builder */ - WhereMaskSet *pMaskSet; /* The expression mask set */ - WhereLevel *pLevel; /* A single level in pWInfo->a[] */ - WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ - int ii; /* Loop counter */ - sqlite3 *db; /* Database connection */ - int rc; /* Return code */ - u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ - - assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( - (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - )); - - /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */ - assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - || (wctrlFlags & WHERE_USE_LIMIT)==0 ); - - /* Variable initialization */ - db = pParse->db; - memset(&sWLB, 0, sizeof(sWLB)); - - /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ - testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); - if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; - sWLB.pOrderBy = pOrderBy; - - /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via - ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ - if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ - wctrlFlags &= ~WHERE_WANT_DISTINCT; - } - - /* The number of tables in the FROM clause is limited by the number of - ** bits in a Bitmask - */ - testcase( pTabList->nSrc==BMS ); - if( pTabList->nSrc>BMS ){ - sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); - return 0; - } - - /* This function normally generates a nested loop for all tables in - ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should - ** only generate code for the first table in pTabList and assume that - ** any cursors associated with subsequent tables are uninitialized. - */ - nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc; - - /* Allocate and initialize the WhereInfo structure that will become the - ** return value. A single allocation is used to store the WhereInfo - ** struct, the contents of WhereInfo.a[], the WhereClause structure - ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte - ** field (type Bitmask) it must be aligned on an 8-byte boundary on - ** some architectures. Hence the ROUND8() below. - */ - nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); - pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); - if( db->mallocFailed ){ - sqlite3DbFree(db, pWInfo); - pWInfo = 0; - goto whereBeginError; - } - pWInfo->pParse = pParse; - pWInfo->pTabList = pTabList; - pWInfo->pOrderBy = pOrderBy; - pWInfo->pDistinctSet = pDistinctSet; - pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; - pWInfo->nLevel = nTabList; - pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); - pWInfo->wctrlFlags = wctrlFlags; - pWInfo->iLimit = iAuxArg; - pWInfo->savedNQueryLoop = pParse->nQueryLoop; - memset(&pWInfo->nOBSat, 0, - offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); - memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); - assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ - pMaskSet = &pWInfo->sMaskSet; - sWLB.pWInfo = pWInfo; - sWLB.pWC = &pWInfo->sWC; - sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); - assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) ); - whereLoopInit(sWLB.pNew); -#ifdef SQLITE_DEBUG - sWLB.pNew->cId = '*'; -#endif - - /* Split the WHERE clause into separate subexpressions where each - ** subexpression is separated by an AND operator. - */ - initMaskSet(pMaskSet); - sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); - sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); - - /* Special case: a WHERE clause that is constant. Evaluate the - ** expression and either jump over all of the code or fall thru. - */ - for(ii=0; iinTerm; ii++){ - if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){ - sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak, - SQLITE_JUMPIFNULL); - sWLB.pWC->a[ii].wtFlags |= TERM_CODED; - } - } - - /* Special case: No FROM clause - */ - if( nTabList==0 ){ - if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; - if( wctrlFlags & WHERE_WANT_DISTINCT ){ - pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; - } - } - - /* Assign a bit from the bitmask to every term in the FROM clause. - ** - ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in - ** pTabList, not just the first nTabList tables. nTabList is normally - ** equal to pTabList->nSrc but might be shortened to 1 if the - ** WHERE_OR_SUBCLAUSE flag is set. - */ - for(ii=0; iinSrc; ii++){ - createMask(pMaskSet, pTabList->a[ii].iCursor); - sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); - } -#ifdef SQLITE_DEBUG - for(ii=0; iinSrc; ii++){ - Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); - assert( m==MASKBIT(ii) ); - } -#endif - - /* Analyze all of the subexpressions. */ - sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); - if( db->mallocFailed ) goto whereBeginError; - - if( wctrlFlags & WHERE_WANT_DISTINCT ){ - if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){ - /* The DISTINCT marking is pointless. Ignore it. */ - pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; - }else if( pOrderBy==0 ){ - /* Try to ORDER BY the result set to make distinct processing easier */ - pWInfo->wctrlFlags |= WHERE_DISTINCTBY; - pWInfo->pOrderBy = pDistinctSet; - } - } - - /* Construct the WhereLoop objects */ -#if defined(WHERETRACE_ENABLED) - if( sqlite3WhereTrace & 0xffff ){ - sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); - if( wctrlFlags & WHERE_USE_LIMIT ){ - sqlite3DebugPrintf(", limit: %d", iAuxArg); - } - sqlite3DebugPrintf(")\n"); - } - if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ - sqlite3WhereClausePrint(sWLB.pWC); - } -#endif - - if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ - rc = whereLoopAddAll(&sWLB); - if( rc ) goto whereBeginError; - -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ - WhereLoop *p; - int i; - static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" - "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; - for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ - p->cId = zLabel[i%sizeof(zLabel)]; - whereLoopPrint(p, sWLB.pWC); - } - } -#endif - - wherePathSolver(pWInfo, 0); - if( db->mallocFailed ) goto whereBeginError; - if( pWInfo->pOrderBy ){ - wherePathSolver(pWInfo, pWInfo->nRowOut+1); - if( db->mallocFailed ) goto whereBeginError; - } - } - if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ - pWInfo->revMask = ALLBITS; - } - if( pParse->nErr || NEVER(db->mallocFailed) ){ - goto whereBeginError; - } -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace ){ - sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); - if( pWInfo->nOBSat>0 ){ - sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); - } - switch( pWInfo->eDistinct ){ - case WHERE_DISTINCT_UNIQUE: { - sqlite3DebugPrintf(" DISTINCT=unique"); - break; - } - case WHERE_DISTINCT_ORDERED: { - sqlite3DebugPrintf(" DISTINCT=ordered"); - break; - } - case WHERE_DISTINCT_UNORDERED: { - sqlite3DebugPrintf(" DISTINCT=unordered"); - break; - } - } - sqlite3DebugPrintf("\n"); - for(ii=0; iinLevel; ii++){ - whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); - } - } -#endif - /* Attempt to omit tables from the join that do not effect the result */ - if( pWInfo->nLevel>=2 - && pDistinctSet!=0 - && OptimizationEnabled(db, SQLITE_OmitNoopJoin) - ){ - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet); - if( sWLB.pOrderBy ){ - tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); - } - while( pWInfo->nLevel>=2 ){ - WhereTerm *pTerm, *pEnd; - pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; - if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break; - if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 - && (pLoop->wsFlags & WHERE_ONEROW)==0 - ){ - break; - } - if( (tabUsed & pLoop->maskSelf)!=0 ) break; - pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; - for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - ){ - break; - } - } - if( pTerm drop loop %c not used\n", pLoop->cId)); - pWInfo->nLevel--; - nTabList--; - } - } - WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); - pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; - - /* If the caller is an UPDATE or DELETE statement that is requesting - ** to use a one-pass algorithm, determine if this is appropriate. - */ - assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); - if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ - int wsFlags = pWInfo->a[0].pWLoop->wsFlags; - int bOnerow = (wsFlags & WHERE_ONEROW)!=0; - if( bOnerow - || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0 - && 0==(wsFlags & WHERE_VIRTUALTABLE)) - ){ - pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ - if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ - bFordelete = OPFLAG_FORDELETE; - } - pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); - } - } - } - - /* Open all tables in the pTabList and any indices selected for - ** searching those tables. - */ - for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; - pTab = pTabItem->pTab; - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pLoop = pLevel->pWLoop; - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ - /* Do nothing */ - }else -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ - const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); - int iCur = pTabItem->iCursor; - sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); - }else if( IsVirtual(pTab) ){ - /* noop */ - }else -#endif - if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ - int op = OP_OpenRead; - if( pWInfo->eOnePass!=ONEPASS_OFF ){ - op = OP_OpenWrite; - pWInfo->aiCurOnePass[0] = pTabItem->iCursor; - }; - sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); - assert( pTabItem->iCursor==pLevel->iTabCur ); - testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); - testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); - if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nColcolUsed; - int n = 0; - for(; b; b=b>>1, n++){} - sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); - assert( n<=pTab->nCol ); - } -#ifdef SQLITE_ENABLE_CURSOR_HINTS - if( pLoop->u.btree.pIndex!=0 ){ - sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); - }else -#endif - { - sqlite3VdbeChangeP5(v, bFordelete); - } -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, - (const u8*)&pTabItem->colUsed, P4_INT64); -#endif - }else{ - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - } - if( pLoop->wsFlags & WHERE_INDEXED ){ - Index *pIx = pLoop->u.btree.pIndex; - int iIndexCur; - int op = OP_OpenRead; - /* iAuxArg is always set if to a positive value if ONEPASS is possible */ - assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); - if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) - && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 - ){ - /* This is one term of an OR-optimization using the PRIMARY KEY of a - ** WITHOUT ROWID table. No need for a separate index */ - iIndexCur = pLevel->iTabCur; - op = 0; - }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ - Index *pJ = pTabItem->pTab->pIndex; - iIndexCur = iAuxArg; - assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); - while( ALWAYS(pJ) && pJ!=pIx ){ - iIndexCur++; - pJ = pJ->pNext; - } - op = OP_OpenWrite; - pWInfo->aiCurOnePass[1] = iIndexCur; - }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ - iIndexCur = iAuxArg; - op = OP_ReopenIdx; - }else{ - iIndexCur = pParse->nTab++; - } - pLevel->iIdxCur = iIndexCur; - assert( pIx->pSchema==pTab->pSchema ); - assert( iIndexCur>=0 ); - if( op ){ - sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIx); - if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 - && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 - && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 - ){ - sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ - } - VdbeComment((v, "%s", pIx->zName)); -#ifdef SQLITE_ENABLE_COLUMN_USED_MASK - { - u64 colUsed = 0; - int ii, jj; - for(ii=0; iinColumn; ii++){ - jj = pIx->aiColumn[ii]; - if( jj<0 ) continue; - if( jj>63 ) jj = 63; - if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; - colUsed |= ((u64)1)<<(ii<63 ? ii : 63); - } - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, - (u8*)&colUsed, P4_INT64); - } -#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ - } - } - if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); - } - pWInfo->iTop = sqlite3VdbeCurrentAddr(v); - if( db->mallocFailed ) goto whereBeginError; - - /* Generate the code to do the search. Each iteration of the for - ** loop below generates code for a single nested loop of the VM - ** program. - */ - notReady = ~(Bitmask)0; - for(ii=0; iia[ii]; - wsFlags = pLevel->pWLoop->wsFlags; -#ifndef SQLITE_OMIT_AUTOMATIC_INDEX - if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ - constructAutomaticIndex(pParse, &pWInfo->sWC, - &pTabList->a[pLevel->iFrom], notReady, pLevel); - if( db->mallocFailed ) goto whereBeginError; - } -#endif - addrExplain = sqlite3WhereExplainOneScan( - pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags - ); - pLevel->addrBody = sqlite3VdbeCurrentAddr(v); - notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady); - pWInfo->iContinue = pLevel->addrCont; - if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ - sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); - } - } - - /* Done. */ - VdbeModuleComment((v, "Begin WHERE-core")); - return pWInfo; - - /* Jump here if malloc fails */ -whereBeginError: - if( pWInfo ){ - pParse->nQueryLoop = pWInfo->savedNQueryLoop; - whereInfoFree(db, pWInfo); - } - return 0; -} - -/* -** Generate the end of the WHERE loop. See comments on -** sqlite3WhereBegin() for additional information. -*/ -SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ - Parse *pParse = pWInfo->pParse; - Vdbe *v = pParse->pVdbe; - int i; - WhereLevel *pLevel; - WhereLoop *pLoop; - SrcList *pTabList = pWInfo->pTabList; - sqlite3 *db = pParse->db; - - /* Generate loop termination code. - */ - VdbeModuleComment((v, "End WHERE-core")); - sqlite3ExprCacheClear(pParse); - for(i=pWInfo->nLevel-1; i>=0; i--){ - int addr; - pLevel = &pWInfo->a[i]; - pLoop = pLevel->pWLoop; - sqlite3VdbeResolveLabel(v, pLevel->addrCont); - if( pLevel->op!=OP_Noop ){ - sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); - sqlite3VdbeChangeP5(v, pLevel->p5); - VdbeCoverage(v); - VdbeCoverageIf(v, pLevel->op==OP_Next); - VdbeCoverageIf(v, pLevel->op==OP_Prev); - VdbeCoverageIf(v, pLevel->op==OP_VNext); - } - if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ - struct InLoop *pIn; - int j; - sqlite3VdbeResolveLabel(v, pLevel->addrNxt); - for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ - sqlite3VdbeJumpHere(v, pIn->addrInTop+1); - if( pIn->eEndLoopOp!=OP_Noop ){ - sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); - VdbeCoverage(v); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); - } - sqlite3VdbeJumpHere(v, pIn->addrInTop-1); - } - } - sqlite3VdbeResolveLabel(v, pLevel->addrBrk); - if( pLevel->addrSkip ){ - sqlite3VdbeGoto(v, pLevel->addrSkip); - VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); - sqlite3VdbeJumpHere(v, pLevel->addrSkip); - sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); - } -#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( pLevel->addrLikeRep ){ - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), - pLevel->addrLikeRep); - VdbeCoverage(v); - } -#endif - if( pLevel->iLeftJoin ){ - int ws = pLoop->wsFlags; - addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); - assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); - if( (ws & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); - } - if( (ws & WHERE_INDEXED) - || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) - ){ - sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); - } - if( pLevel->op==OP_Return ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); - }else{ - sqlite3VdbeGoto(v, pLevel->addrFirst); - } - sqlite3VdbeJumpHere(v, addr); - } - VdbeModuleComment((v, "End WHERE-loop%d: %s", i, - pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); - } - - /* The "break" point is here, just past the end of the outer loop. - ** Set it. - */ - sqlite3VdbeResolveLabel(v, pWInfo->iBreak); - - assert( pWInfo->nLevel<=pTabList->nSrc ); - for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ - int k, last; - VdbeOp *pOp; - Index *pIdx = 0; - struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; - Table *pTab = pTabItem->pTab; - assert( pTab!=0 ); - pLoop = pLevel->pWLoop; - - /* For a co-routine, change all OP_Column references to the table of - ** the co-routine into OP_Copy of result contained in a register. - ** OP_Rowid becomes OP_Null. - */ - if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){ - translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur, - pTabItem->regResult, 0); - continue; - } - - /* Close all of the cursors that were opened by sqlite3WhereBegin. - ** Except, do not close cursors that will be reused by the OR optimization - ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors - ** created for the ONEPASS optimization. - */ - if( (pTab->tabFlags & TF_Ephemeral)==0 - && pTab->pSelect==0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - ){ - int ws = pLoop->wsFlags; - if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); - } - if( (ws & WHERE_INDEXED)!=0 - && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 - && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] - ){ - sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); - } - } - - /* If this scan uses an index, make VDBE code substitutions to read data - ** from the index instead of from the table where possible. In some cases - ** this optimization prevents the table from ever being read, which can - ** yield a significant performance boost. - ** - ** Calls to the code generator in between sqlite3WhereBegin and - ** sqlite3WhereEnd will have created code that references the table - ** directly. This loop scans all that code looking for opcodes - ** that reference the table and converts them into opcodes that - ** reference the index. - */ - if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){ - pIdx = pLoop->u.btree.pIndex; - }else if( pLoop->wsFlags & WHERE_MULTI_OR ){ - pIdx = pLevel->u.pCovidx; - } - if( pIdx - && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable)) - && !db->mallocFailed - ){ - last = sqlite3VdbeCurrentAddr(v); - k = pLevel->addrBody; - pOp = sqlite3VdbeGetOp(v, k); - for(; kp1!=pLevel->iTabCur ) continue; - if( pOp->opcode==OP_Column ){ - int x = pOp->p2; - assert( pIdx->pTable==pTab ); - if( !HasRowid(pTab) ){ - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - x = pPk->aiColumn[x]; - assert( x>=0 ); - } - x = sqlite3ColumnOfIndex(pIdx, x); - if( x>=0 ){ - pOp->p2 = x; - pOp->p1 = pLevel->iIdxCur; - } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 ); - }else if( pOp->opcode==OP_Rowid ){ - pOp->p1 = pLevel->iIdxCur; - pOp->opcode = OP_IdxRowid; - } - } - } - } - - /* Final cleanup - */ - pParse->nQueryLoop = pWInfo->savedNQueryLoop; - whereInfoFree(db, pWInfo); - return; -} - -/************** End of where.c ***********************************************/ -/************** Begin file parse.c *******************************************/ -/* -** 2000-05-29 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Driver template for the LEMON parser generator. -** -** The "lemon" program processes an LALR(1) input grammar file, then uses -** this template to construct a parser. The "lemon" program inserts text -** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the -** interstitial "-" characters) contained in this template is changed into -** the value of the %name directive from the grammar. Otherwise, the content -** of this template is copied straight through into the generate parser -** source file. -** -** The following is the concatenation of all %include directives from the -** input grammar file: -*/ -/* #include */ -/************ Begin %include sections from the grammar ************************/ - -/* #include "sqliteInt.h" */ - -/* -** Disable all error recovery processing in the parser push-down -** automaton. -*/ -#define YYNOERRORRECOVERY 1 - -/* -** Make yytestcase() the same as testcase() -*/ -#define yytestcase(X) testcase(X) - -/* -** Indicate that sqlite3ParserFree() will never be called with a null -** pointer. -*/ -#define YYPARSEFREENEVERNULL 1 - -/* -** Alternative datatype for the argument to the malloc() routine passed -** into sqlite3ParserAlloc(). The default is size_t. -*/ -#define YYMALLOCARGTYPE u64 - -/* -** An instance of this structure holds information about the -** LIMIT clause of a SELECT statement. -*/ -struct LimitVal { - Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ - Expr *pOffset; /* The OFFSET expression. NULL if there is none */ -}; - -/* -** An instance of the following structure describes the event of a -** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, -** TK_DELETE, or TK_INSTEAD. If the event is of the form -** -** UPDATE ON (a,b,c) -** -** Then the "b" IdList records the list "a,b,c". -*/ -struct TrigEvent { int a; IdList * b; }; - -/* -** Disable lookaside memory allocation for objects that might be -** shared across database connections. -*/ -static void disableLookaside(Parse *pParse){ - pParse->disableLookaside++; - pParse->db->lookaside.bDisable++; -} - - - /* - ** For a compound SELECT statement, make sure p->pPrior->pNext==p for - ** all elements in the list. And make sure list length does not exceed - ** SQLITE_LIMIT_COMPOUND_SELECT. - */ - static void parserDoubleLinkSelect(Parse *pParse, Select *p){ - if( p->pPrior ){ - Select *pNext = 0, *pLoop; - int mxSelect, cnt = 0; - for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ - pLoop->pNext = pNext; - pLoop->selFlags |= SF_Compound; - } - if( (p->selFlags & SF_MultiValue)==0 && - (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && - cnt>mxSelect - ){ - sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); - } - } - } - - /* This is a utility routine used to set the ExprSpan.zStart and - ** ExprSpan.zEnd values of pOut so that the span covers the complete - ** range of text beginning with pStart and going to the end of pEnd. - */ - static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){ - pOut->zStart = pStart->z; - pOut->zEnd = &pEnd->z[pEnd->n]; - } - - /* Construct a new Expr object from a single identifier. Use the - ** new Expr to populate pOut. Set the span of pOut to be the identifier - ** that created the expression. - */ - static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){ - Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); - if( p ){ - memset(p, 0, sizeof(Expr)); - p->op = (u8)op; - p->flags = EP_Leaf; - p->iAgg = -1; - p->u.zToken = (char*)&p[1]; - memcpy(p->u.zToken, t.z, t.n); - p->u.zToken[t.n] = 0; - if( sqlite3Isquote(p->u.zToken[0]) ){ - if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted; - sqlite3Dequote(p->u.zToken); - } -#if SQLITE_MAX_EXPR_DEPTH>0 - p->nHeight = 1; -#endif - } - pOut->pExpr = p; - pOut->zStart = t.z; - pOut->zEnd = &t.z[t.n]; - } - - /* This routine constructs a binary expression node out of two ExprSpan - ** objects and uses the result to populate a new ExprSpan object. - */ - static void spanBinaryExpr( - Parse *pParse, /* The parsing context. Errors accumulate here */ - int op, /* The binary operation */ - ExprSpan *pLeft, /* The left operand, and output */ - ExprSpan *pRight /* The right operand */ - ){ - pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0); - pLeft->zEnd = pRight->zEnd; - } - - /* If doNot is true, then add a TK_NOT Expr-node wrapper around the - ** outside of *ppExpr. - */ - static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){ - if( doNot ){ - pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0); - } - } - - /* Construct an expression node for a unary postfix operator - */ - static void spanUnaryPostfix( - Parse *pParse, /* Parsing context to record errors */ - int op, /* The operator */ - ExprSpan *pOperand, /* The operand, and output */ - Token *pPostOp /* The operand token for setting the span */ - ){ - pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); - pOperand->zEnd = &pPostOp->z[pPostOp->n]; - } - - /* A routine to convert a binary TK_IS or TK_ISNOT expression into a - ** unary TK_ISNULL or TK_NOTNULL expression. */ - static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ - sqlite3 *db = pParse->db; - if( pA && pY && pY->op==TK_NULL ){ - pA->op = (u8)op; - sqlite3ExprDelete(db, pA->pRight); - pA->pRight = 0; - } - } - - /* Construct an expression node for a unary prefix operator - */ - static void spanUnaryPrefix( - ExprSpan *pOut, /* Write the new expression node here */ - Parse *pParse, /* Parsing context to record errors */ - int op, /* The operator */ - ExprSpan *pOperand, /* The operand */ - Token *pPreOp /* The operand token for setting the span */ - ){ - pOut->zStart = pPreOp->z; - pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0); - pOut->zEnd = pOperand->zEnd; - } - - /* Add a single new term to an ExprList that is used to store a - ** list of identifiers. Report an error if the ID list contains - ** a COLLATE clause or an ASC or DESC keyword, except ignore the - ** error while parsing a legacy schema. - */ - static ExprList *parserAddExprIdListTerm( - Parse *pParse, - ExprList *pPrior, - Token *pIdToken, - int hasCollate, - int sortOrder - ){ - ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0); - if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED) - && pParse->db->init.busy==0 - ){ - sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", - pIdToken->n, pIdToken->z); - } - sqlite3ExprListSetName(pParse, p, pIdToken, 1); - return p; - } -/**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ - -/* The next sections is a series of control #defines. -** various aspects of the generated parser. -** YYCODETYPE is the data type used to store the integer codes -** that represent terminal and non-terminal symbols. -** "unsigned char" is used if there are fewer than -** 256 symbols. Larger types otherwise. -** YYNOCODE is a number of type YYCODETYPE that is not used for -** any terminal or nonterminal symbol. -** YYFALLBACK If defined, this indicates that one or more tokens -** (also known as: "terminal symbols") have fall-back -** values which should be used if the original symbol -** would not parse. This permits keywords to sometimes -** be used as identifiers, for example. -** YYACTIONTYPE is the data type used for "action codes" - numbers -** that indicate what to do in response to the next -** token. -** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal -** symbols. Background: A "minor type" is a semantic -** value associated with a terminal or non-terminal -** symbols. For example, for an "ID" terminal symbol, -** the minor type might be the name of the identifier. -** Each non-terminal can have a different minor type. -** Terminal symbols all have the same minor type, though. -** This macros defines the minor type for terminal -** symbols. -** YYMINORTYPE is the data type used for all minor types. -** This is typically a union of many types, one of -** which is sqlite3ParserTOKENTYPE. The entry in the union -** for terminal symbols is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument -** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument -** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser -** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YY_MAX_SHIFT Maximum value for shift actions -** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions -** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions -** YY_MIN_REDUCE Maximum value for reduce actions -** YY_ERROR_ACTION The yy_action[] code for syntax error -** YY_ACCEPT_ACTION The yy_action[] code for accept -** YY_NO_ACTION The yy_action[] code for no-op -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/************* Begin control #defines *****************************************/ -#define YYCODETYPE unsigned char -#define YYNOCODE 252 -#define YYACTIONTYPE unsigned short int -#define YYWILDCARD 96 -#define sqlite3ParserTOKENTYPE Token -typedef union { - int yyinit; - sqlite3ParserTOKENTYPE yy0; - Expr* yy72; - TriggerStep* yy145; - ExprList* yy148; - SrcList* yy185; - ExprSpan yy190; - int yy194; - Select* yy243; - IdList* yy254; - With* yy285; - struct TrigEvent yy332; - struct LimitVal yy354; - struct {int value; int mask;} yy497; -} YYMINORTYPE; -#ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 100 -#endif -#define sqlite3ParserARG_SDECL Parse *pParse; -#define sqlite3ParserARG_PDECL ,Parse *pParse -#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse -#define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYFALLBACK 1 -#define YYNSTATE 456 -#define YYNRULE 332 -#define YY_MAX_SHIFT 455 -#define YY_MIN_SHIFTREDUCE 668 -#define YY_MAX_SHIFTREDUCE 999 -#define YY_MIN_REDUCE 1000 -#define YY_MAX_REDUCE 1331 -#define YY_ERROR_ACTION 1332 -#define YY_ACCEPT_ACTION 1333 -#define YY_NO_ACTION 1334 -/************* End control #defines *******************************************/ - -/* Define the yytestcase() macro to be a no-op if is not already defined -** otherwise. -** -** Applications can choose to define yytestcase() in the %include section -** to a macro that can assist in verifying code coverage. For production -** code the yytestcase() macro should be turned off. But it is useful -** for testing. -*/ -#ifndef yytestcase -# define yytestcase(X) -#endif - - -/* Next are the tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then -** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. -** -** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE -** and YY_MAX_REDUCE -** -** N == YY_ERROR_ACTION A syntax error has occurred. -** -** N == YY_ACCEPT_ACTION The parser accepts its input. -** -** N == YY_NO_ACTION No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as either: -** -** (A) N = yy_action[ yy_shift_ofst[S] + X ] -** (B) N = yy_default[S] -** -** The (A) formula is preferred. The B formula is used instead if: -** (1) The yy_shift_ofst[S]+X value is out of range, or -** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or -** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. -** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that -** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. -** Hence only tests (1) and (2) need to be evaluated.) -** -** The formulas above are for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -** -*********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1567) -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100, - /* 10 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98, - /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95, - /* 30 */ 94, 94, 94, 93, 351, 325, 977, 977, 824, 824, - /* 40 */ 826, 947, 354, 99, 100, 90, 842, 842, 854, 857, - /* 50 */ 846, 846, 97, 97, 98, 98, 98, 98, 338, 96, - /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, - /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 977, 977, - /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100, - /* 90 */ 90, 842, 842, 854, 857, 846, 846, 97, 97, 98, - /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95, - /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325, - /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90, - /* 130 */ 842, 842, 854, 857, 846, 846, 97, 97, 98, 98, - /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94, - /* 150 */ 94, 94, 93, 351, 958, 958, 325, 268, 428, 413, - /* 160 */ 411, 61, 752, 752, 99, 100, 90, 842, 842, 854, - /* 170 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 60, - /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 190 */ 351, 325, 270, 329, 273, 277, 959, 960, 250, 99, - /* 200 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97, - /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95, - /* 220 */ 95, 94, 94, 94, 93, 351, 325, 938, 1326, 698, - /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 842, 842, 854, - /* 240 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 347, - /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 260 */ 351, 325, 938, 1327, 384, 699, 1327, 381, 379, 99, - /* 270 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97, - /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95, - /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178, - /* 300 */ 833, 936, 373, 700, 99, 100, 90, 842, 842, 854, - /* 310 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 375, - /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 330 */ 351, 325, 1276, 947, 354, 818, 936, 739, 739, 99, - /* 340 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97, - /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95, - /* 360 */ 95, 94, 94, 94, 93, 351, 325, 969, 227, 92, - /* 370 */ 89, 178, 373, 300, 99, 100, 90, 842, 842, 854, - /* 380 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 921, - /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99, - /* 410 */ 100, 90, 842, 842, 854, 857, 846, 846, 97, 97, - /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95, - /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 958, - /* 440 */ 958, 158, 25, 422, 99, 100, 90, 842, 842, 854, - /* 450 */ 857, 846, 846, 97, 97, 98, 98, 98, 98, 450, - /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 470 */ 351, 443, 224, 224, 420, 958, 958, 962, 325, 52, - /* 480 */ 52, 959, 960, 176, 415, 78, 99, 100, 90, 842, - /* 490 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98, - /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94, - /* 510 */ 94, 93, 351, 325, 428, 418, 298, 959, 960, 962, - /* 520 */ 81, 99, 88, 90, 842, 842, 854, 857, 846, 846, - /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96, - /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 843, - /* 550 */ 843, 855, 858, 996, 318, 343, 379, 100, 90, 842, - /* 560 */ 842, 854, 857, 846, 846, 97, 97, 98, 98, 98, - /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94, - /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340, - /* 590 */ 929, 52, 52, 90, 842, 842, 854, 857, 846, 846, - /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96, - /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445, - /* 620 */ 847, 3, 1203, 361, 360, 378, 344, 813, 958, 958, - /* 630 */ 1300, 86, 445, 729, 3, 212, 169, 287, 405, 282, - /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245, - /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83, - /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246, - /* 670 */ 959, 960, 194, 455, 670, 402, 399, 398, 448, 243, - /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224, - /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427, - /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452, - /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1271, - /* 720 */ 1271, 23, 958, 958, 86, 445, 397, 3, 228, 429, - /* 730 */ 895, 824, 824, 826, 827, 19, 203, 720, 52, 52, - /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229, - /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85, - /* 760 */ 352, 352, 120, 157, 959, 960, 58, 977, 409, 355, - /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86, - /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96, - /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351, - /* 800 */ 832, 120, 452, 451, 813, 887, 819, 83, 84, 977, - /* 810 */ 813, 132, 410, 920, 85, 352, 352, 132, 407, 789, - /* 820 */ 958, 958, 92, 89, 178, 917, 448, 262, 370, 261, - /* 830 */ 82, 914, 80, 262, 370, 261, 776, 824, 824, 826, - /* 840 */ 827, 19, 934, 434, 96, 96, 96, 96, 95, 95, - /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 958, - /* 860 */ 958, 819, 959, 960, 120, 92, 89, 178, 945, 2, - /* 870 */ 918, 965, 268, 1, 976, 76, 445, 762, 3, 708, - /* 880 */ 901, 901, 387, 958, 958, 757, 919, 371, 740, 778, - /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450, - /* 900 */ 24, 959, 960, 83, 84, 369, 958, 958, 177, 226, - /* 910 */ 85, 352, 352, 885, 315, 314, 313, 215, 311, 10, - /* 920 */ 10, 683, 448, 349, 348, 959, 960, 909, 777, 157, - /* 930 */ 120, 958, 958, 337, 776, 416, 711, 310, 450, 434, - /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 959, 960, - /* 950 */ 908, 832, 792, 452, 451, 9, 9, 819, 10, 10, - /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171, - /* 970 */ 170, 167, 339, 959, 960, 247, 984, 702, 702, 450, - /* 980 */ 715, 233, 686, 982, 889, 983, 182, 914, 824, 824, - /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10, - /* 1000 */ 10, 889, 891, 749, 958, 958, 917, 268, 985, 198, - /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825, - /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91, - /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93, - /* 1040 */ 351, 157, 810, 371, 382, 359, 959, 960, 358, 268, - /* 1050 */ 450, 918, 368, 324, 824, 824, 826, 450, 709, 450, - /* 1060 */ 264, 380, 889, 450, 877, 746, 253, 919, 255, 433, - /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12, - /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162, - /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450, - /* 1100 */ 709, 1210, 450, 132, 450, 39, 39, 450, 40, 40, - /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28, - /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450, - /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767, - /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47, - /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172, - /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122, - /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 898, 56, 56, - /* 1180 */ 450, 897, 35, 35, 450, 267, 450, 817, 450, 817, - /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817, - /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119, - /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111, - /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 912, - /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331, - /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 937, 197, - /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436, - /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 933, - /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202, - /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 884, - /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74, - /* 1300 */ 726, 727, 785, 783, 880, 202, 999, 208, 894, 893, - /* 1310 */ 894, 893, 694, 816, 763, 116, 774, 1290, 431, 432, - /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289, - /* 1330 */ 679, 884, 681, 952, 291, 218, 293, 7, 316, 828, - /* 1340 */ 173, 805, 259, 364, 252, 911, 376, 713, 295, 435, - /* 1350 */ 308, 168, 955, 993, 135, 400, 990, 284, 882, 881, - /* 1360 */ 205, 928, 926, 59, 333, 62, 144, 156, 130, 72, - /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383, - /* 1380 */ 67, 896, 140, 141, 142, 148, 389, 812, 775, 266, - /* 1390 */ 219, 190, 154, 391, 913, 876, 271, 406, 191, 322, - /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421, - /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346, - /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 967, 239, - /* 1430 */ 769, 102, 862, 438, 426, 240, 424, 442, 73, 213, - /* 1440 */ 688, 238, 22, 453, 953, 214, 217, 216, 454, 677, - /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166, - /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 892, - /* 1470 */ 327, 890, 811, 328, 134, 128, 136, 138, 743, 258, - /* 1480 */ 907, 184, 143, 129, 910, 186, 63, 64, 145, 187, - /* 1490 */ 906, 65, 8, 66, 13, 188, 202, 899, 265, 149, - /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396, - /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131, - /* 1520 */ 830, 860, 70, 751, 16, 414, 755, 4, 174, 220, - /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 875, - /* 1540 */ 861, 859, 916, 864, 915, 207, 206, 942, 163, 437, - /* 1550 */ 948, 943, 164, 209, 1002, 441, 863, 165, 210, 829, - /* 1560 */ 695, 87, 312, 211, 1292, 1291, 309, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28, - /* 10 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - /* 20 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48, - /* 30 */ 49, 50, 51, 52, 53, 19, 55, 55, 132, 133, - /* 40 */ 134, 1, 2, 27, 28, 29, 30, 31, 32, 33, - /* 50 */ 34, 35, 36, 37, 38, 39, 40, 41, 187, 43, - /* 60 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 70 */ 47, 48, 49, 50, 51, 52, 53, 61, 97, 97, - /* 80 */ 19, 49, 50, 51, 52, 53, 70, 26, 27, 28, - /* 90 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - /* 100 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48, - /* 110 */ 49, 50, 51, 52, 53, 144, 145, 146, 147, 19, - /* 120 */ 16, 22, 92, 172, 173, 52, 53, 27, 28, 29, - /* 130 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - /* 140 */ 40, 41, 81, 43, 44, 45, 46, 47, 48, 49, - /* 150 */ 50, 51, 52, 53, 55, 56, 19, 152, 207, 208, - /* 160 */ 115, 24, 117, 118, 27, 28, 29, 30, 31, 32, - /* 170 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 79, - /* 180 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 190 */ 53, 19, 88, 157, 90, 23, 97, 98, 193, 27, - /* 200 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 210 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47, - /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 172, - /* 230 */ 23, 26, 119, 120, 27, 28, 29, 30, 31, 32, - /* 240 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 187, - /* 250 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 260 */ 53, 19, 22, 23, 228, 23, 26, 231, 152, 27, - /* 270 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 280 */ 38, 39, 40, 41, 172, 43, 44, 45, 46, 47, - /* 290 */ 48, 49, 50, 51, 52, 53, 19, 221, 222, 223, - /* 300 */ 23, 96, 152, 172, 27, 28, 29, 30, 31, 32, - /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152, - /* 320 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 330 */ 53, 19, 0, 1, 2, 23, 96, 190, 191, 27, - /* 340 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 350 */ 38, 39, 40, 41, 238, 43, 44, 45, 46, 47, - /* 360 */ 48, 49, 50, 51, 52, 53, 19, 185, 218, 221, - /* 370 */ 222, 223, 152, 152, 27, 28, 29, 30, 31, 32, - /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 241, - /* 390 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 400 */ 53, 19, 152, 168, 169, 170, 22, 190, 191, 27, - /* 410 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - /* 420 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47, - /* 430 */ 48, 49, 50, 51, 52, 53, 19, 19, 218, 55, - /* 440 */ 56, 24, 22, 152, 27, 28, 29, 30, 31, 32, - /* 450 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152, - /* 460 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 470 */ 53, 250, 194, 195, 56, 55, 56, 55, 19, 172, - /* 480 */ 173, 97, 98, 152, 206, 138, 27, 28, 29, 30, - /* 490 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - /* 500 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50, - /* 510 */ 51, 52, 53, 19, 207, 208, 152, 97, 98, 97, - /* 520 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35, - /* 530 */ 36, 37, 38, 39, 40, 41, 181, 43, 44, 45, - /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 30, - /* 550 */ 31, 32, 33, 247, 248, 19, 152, 28, 29, 30, - /* 560 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - /* 570 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50, - /* 580 */ 51, 52, 53, 19, 168, 169, 170, 238, 19, 53, - /* 590 */ 152, 172, 173, 29, 30, 31, 32, 33, 34, 35, - /* 600 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45, - /* 610 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 20, - /* 620 */ 101, 22, 23, 169, 170, 56, 207, 85, 55, 56, - /* 630 */ 23, 19, 20, 26, 22, 99, 100, 101, 102, 103, - /* 640 */ 104, 105, 238, 152, 152, 210, 47, 48, 112, 152, - /* 650 */ 108, 109, 110, 54, 55, 56, 221, 222, 223, 47, - /* 660 */ 48, 119, 120, 172, 173, 66, 54, 55, 56, 152, - /* 670 */ 97, 98, 99, 148, 149, 102, 103, 104, 66, 154, - /* 680 */ 23, 156, 83, 26, 230, 152, 113, 152, 163, 194, - /* 690 */ 195, 92, 92, 30, 95, 83, 97, 98, 207, 208, - /* 700 */ 101, 206, 179, 180, 92, 172, 173, 95, 152, 97, - /* 710 */ 98, 188, 99, 101, 219, 102, 103, 104, 152, 119, - /* 720 */ 120, 196, 55, 56, 19, 20, 113, 22, 193, 163, - /* 730 */ 11, 132, 133, 134, 135, 136, 24, 65, 172, 173, - /* 740 */ 207, 208, 250, 152, 132, 133, 134, 135, 136, 193, - /* 750 */ 78, 84, 47, 48, 49, 98, 199, 152, 86, 54, - /* 760 */ 55, 56, 196, 152, 97, 98, 209, 55, 163, 244, - /* 770 */ 107, 66, 152, 207, 208, 164, 175, 172, 173, 19, - /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43, - /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97, - /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175, - /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110, - /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134, - /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48, - /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55, - /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147, - /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179, - /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124, - /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152, - /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5, - /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172, - /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152, - /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83, - /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98, - /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173, - /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47, - /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152, - /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133, - /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172, - /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30, - /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97, - /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42, - /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152, - /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152, - /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75, - /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172, - /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24, - /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152, - /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173, - /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172, - /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152, - /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213, - /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172, - /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26, - /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173, - /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173, - /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152, - /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152, - /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173, - /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173, - /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163, - /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167, - /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108, - /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163, - /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23, - /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26, - /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55, - /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26, - /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132, - /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191, - /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210, - /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97, - /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227, - /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175, - /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130, - /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159, - /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235, - /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177, - /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125, - /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53, - /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229, - /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25, - /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151, - /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22, - /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23, - /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16, - /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122, - /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80, - /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79, - /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68, - /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23, - /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23, - /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24, - /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23, - /* 1560 */ 23, 22, 15, 122, 122, 122, 23, -}; -#define YY_SHIFT_USE_DFLT (1567) -#define YY_SHIFT_COUNT (455) -#define YY_SHIFT_MIN (-94) -#define YY_SHIFT_MAX (1549) -static const short yy_shift_ofst[] = { - /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19, - /* 10 */ 16, 16, 100, 760, 760, 760, 760, 760, 760, 760, - /* 20 */ 876, 876, 573, 542, 719, 600, 61, 137, 172, 207, - /* 30 */ 242, 277, 312, 347, 382, 417, 459, 459, 459, 459, - /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, - /* 50 */ 459, 459, 459, 494, 459, 529, 564, 564, 705, 760, - /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760, - /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746, - /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73, - /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99, - /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949, - /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113, - /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922, - /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949, - /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, - /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949, - /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949, - /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118, - /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418, - /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882, - /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238, - /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239, - /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238, - /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290, - /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304, - /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280, - /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414, - /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567, - /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104, - /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273, - /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177, - /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452, - /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479, - /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367, - /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429, - /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491, - /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498, - /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475, - /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517, - /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527, - /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436, - /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549, -}; -#define YY_REDUCE_USE_DFLT (-130) -#define YY_REDUCE_COUNT (324) -#define YY_REDUCE_MIN (-129) -#define YY_REDUCE_MAX (1300) -static const short yy_reduce_ofst[] = { - /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435, - /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790, - /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76, - /* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - /* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, - /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898, - /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950, - /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984, - /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021, - /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062, - /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76, - /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76, - /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220, - /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620, - /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047, - /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808, - /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57, - /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438, - /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908, - /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101, - /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171, - /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102, - /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130, - /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183, - /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205, - /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193, - /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231, - /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232, - /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201, - /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215, - /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278, - /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228, - /* 320 */ 1288, 1291, 1276, 1277, 1295, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1281, 1271, 1271, 1271, 1203, 1203, 1203, 1203, 1271, 1096, - /* 10 */ 1125, 1125, 1255, 1332, 1332, 1332, 1332, 1332, 1332, 1202, - /* 20 */ 1332, 1332, 1332, 1332, 1271, 1100, 1131, 1332, 1332, 1332, - /* 30 */ 1332, 1204, 1205, 1332, 1332, 1332, 1254, 1256, 1141, 1140, - /* 40 */ 1139, 1138, 1237, 1112, 1136, 1129, 1133, 1204, 1198, 1199, - /* 50 */ 1197, 1201, 1205, 1332, 1132, 1167, 1182, 1166, 1332, 1332, - /* 60 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 70 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 80 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 90 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 100 */ 1332, 1332, 1332, 1332, 1176, 1181, 1188, 1180, 1177, 1169, - /* 110 */ 1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172, - /* 120 */ 1332, 1173, 1185, 1184, 1183, 1262, 1289, 1288, 1332, 1332, - /* 130 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 140 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 150 */ 1332, 1332, 1332, 1332, 1332, 1281, 1271, 1025, 1025, 1332, - /* 160 */ 1271, 1271, 1271, 1271, 1271, 1271, 1267, 1100, 1091, 1332, - /* 170 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 180 */ 1259, 1257, 1332, 1218, 1332, 1332, 1332, 1332, 1332, 1332, - /* 190 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 200 */ 1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332, - /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1283, 1332, 1232, - /* 220 */ 1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114, - /* 230 */ 1321, 1135, 1321, 1042, 1303, 1039, 1125, 1114, 1200, 1125, - /* 240 */ 1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105, - /* 250 */ 1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135, - /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1236, 1318, 1105, 1105, - /* 270 */ 1016, 1211, 1105, 1016, 1105, 1016, 1211, 1068, 1068, 1068, - /* 280 */ 1057, 1211, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113, - /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1206, 1105, 1332, - /* 300 */ 1211, 1215, 1215, 1211, 1130, 1119, 1128, 1126, 1135, 1022, - /* 310 */ 1060, 1286, 1286, 1282, 1282, 1282, 1282, 1329, 1329, 1267, - /* 320 */ 1298, 1298, 1044, 1044, 1298, 1332, 1332, 1332, 1332, 1332, - /* 330 */ 1332, 1293, 1332, 1220, 1332, 1332, 1332, 1332, 1332, 1332, - /* 340 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 350 */ 1332, 1332, 1152, 1332, 1000, 1264, 1332, 1332, 1263, 1332, - /* 360 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 370 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320, - /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1235, 1234, 1332, 1332, - /* 390 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 400 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, - /* 410 */ 1332, 1082, 1332, 1332, 1332, 1307, 1332, 1332, 1332, 1332, - /* 420 */ 1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332, - /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1273, - /* 440 */ 1332, 1332, 1332, 1272, 1332, 1332, 1332, 1332, 1332, 1154, - /* 450 */ 1332, 1153, 1157, 1332, 1010, 1332, -}; -/********** End of lemon-generated parsing tables *****************************/ - -/* The next table maps tokens (terminal symbols) into fallback tokens. -** If a construct like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammar, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -** -** This feature can be used, for example, to cause some keywords in a language -** to revert to identifiers if they keyword does not apply in the context where -** it appears. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { - 0, /* $ => nothing */ - 0, /* SEMI => nothing */ - 55, /* EXPLAIN => ID */ - 55, /* QUERY => ID */ - 55, /* PLAN => ID */ - 55, /* BEGIN => ID */ - 0, /* TRANSACTION => nothing */ - 55, /* DEFERRED => ID */ - 55, /* IMMEDIATE => ID */ - 55, /* EXCLUSIVE => ID */ - 0, /* COMMIT => nothing */ - 55, /* END => ID */ - 55, /* ROLLBACK => ID */ - 55, /* SAVEPOINT => ID */ - 55, /* RELEASE => ID */ - 0, /* TO => nothing */ - 0, /* TABLE => nothing */ - 0, /* CREATE => nothing */ - 55, /* IF => ID */ - 0, /* NOT => nothing */ - 0, /* EXISTS => nothing */ - 55, /* TEMP => ID */ - 0, /* LP => nothing */ - 0, /* RP => nothing */ - 0, /* AS => nothing */ - 55, /* WITHOUT => ID */ - 0, /* COMMA => nothing */ - 0, /* OR => nothing */ - 0, /* AND => nothing */ - 0, /* IS => nothing */ - 55, /* MATCH => ID */ - 55, /* LIKE_KW => ID */ - 0, /* BETWEEN => nothing */ - 0, /* IN => nothing */ - 0, /* ISNULL => nothing */ - 0, /* NOTNULL => nothing */ - 0, /* NE => nothing */ - 0, /* EQ => nothing */ - 0, /* GT => nothing */ - 0, /* LE => nothing */ - 0, /* LT => nothing */ - 0, /* GE => nothing */ - 0, /* ESCAPE => nothing */ - 0, /* BITAND => nothing */ - 0, /* BITOR => nothing */ - 0, /* LSHIFT => nothing */ - 0, /* RSHIFT => nothing */ - 0, /* PLUS => nothing */ - 0, /* MINUS => nothing */ - 0, /* STAR => nothing */ - 0, /* SLASH => nothing */ - 0, /* REM => nothing */ - 0, /* CONCAT => nothing */ - 0, /* COLLATE => nothing */ - 0, /* BITNOT => nothing */ - 0, /* ID => nothing */ - 0, /* INDEXED => nothing */ - 55, /* ABORT => ID */ - 55, /* ACTION => ID */ - 55, /* AFTER => ID */ - 55, /* ANALYZE => ID */ - 55, /* ASC => ID */ - 55, /* ATTACH => ID */ - 55, /* BEFORE => ID */ - 55, /* BY => ID */ - 55, /* CASCADE => ID */ - 55, /* CAST => ID */ - 55, /* COLUMNKW => ID */ - 55, /* CONFLICT => ID */ - 55, /* DATABASE => ID */ - 55, /* DESC => ID */ - 55, /* DETACH => ID */ - 55, /* EACH => ID */ - 55, /* FAIL => ID */ - 55, /* FOR => ID */ - 55, /* IGNORE => ID */ - 55, /* INITIALLY => ID */ - 55, /* INSTEAD => ID */ - 55, /* NO => ID */ - 55, /* KEY => ID */ - 55, /* OF => ID */ - 55, /* OFFSET => ID */ - 55, /* PRAGMA => ID */ - 55, /* RAISE => ID */ - 55, /* RECURSIVE => ID */ - 55, /* REPLACE => ID */ - 55, /* RESTRICT => ID */ - 55, /* ROW => ID */ - 55, /* TRIGGER => ID */ - 55, /* VACUUM => ID */ - 55, /* VIEW => ID */ - 55, /* VIRTUAL => ID */ - 55, /* WITH => ID */ - 55, /* REINDEX => ID */ - 55, /* RENAME => ID */ - 55, /* CTIME_KW => ID */ -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -** -** After the "shift" half of a SHIFTREDUCE action, the stateno field -** actually contains the reduce action for the second half of the -** SHIFTREDUCE. -*/ -struct yyStackEntry { - YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */ - YYCODETYPE major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - yyStackEntry *yytos; /* Pointer to top element of the stack */ -#ifdef YYTRACKMAXSTACKDEPTH - int yyhwm; /* High-water mark of the stack */ -#endif -#ifndef YYNOERRORRECOVERY - int yyerrcnt; /* Shifts left before out of the error */ -#endif - sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ - yyStackEntry yystk0; /* First stack entry */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -/* #include */ -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
      -**
    • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
    • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
    -** -** Outputs: -** None. -*/ -SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "SEMI", "EXPLAIN", "QUERY", - "PLAN", "BEGIN", "TRANSACTION", "DEFERRED", - "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END", - "ROLLBACK", "SAVEPOINT", "RELEASE", "TO", - "TABLE", "CREATE", "IF", "NOT", - "EXISTS", "TEMP", "LP", "RP", - "AS", "WITHOUT", "COMMA", "OR", - "AND", "IS", "MATCH", "LIKE_KW", - "BETWEEN", "IN", "ISNULL", "NOTNULL", - "NE", "EQ", "GT", "LE", - "LT", "GE", "ESCAPE", "BITAND", - "BITOR", "LSHIFT", "RSHIFT", "PLUS", - "MINUS", "STAR", "SLASH", "REM", - "CONCAT", "COLLATE", "BITNOT", "ID", - "INDEXED", "ABORT", "ACTION", "AFTER", - "ANALYZE", "ASC", "ATTACH", "BEFORE", - "BY", "CASCADE", "CAST", "COLUMNKW", - "CONFLICT", "DATABASE", "DESC", "DETACH", - "EACH", "FAIL", "FOR", "IGNORE", - "INITIALLY", "INSTEAD", "NO", "KEY", - "OF", "OFFSET", "PRAGMA", "RAISE", - "RECURSIVE", "REPLACE", "RESTRICT", "ROW", - "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", - "WITH", "REINDEX", "RENAME", "CTIME_KW", - "ANY", "STRING", "JOIN_KW", "CONSTRAINT", - "DEFAULT", "NULL", "PRIMARY", "UNIQUE", - "CHECK", "REFERENCES", "AUTOINCR", "ON", - "INSERT", "DELETE", "UPDATE", "SET", - "DEFERRABLE", "FOREIGN", "DROP", "UNION", - "ALL", "EXCEPT", "INTERSECT", "SELECT", - "VALUES", "DISTINCT", "DOT", "FROM", - "JOIN", "USING", "ORDER", "GROUP", - "HAVING", "LIMIT", "WHERE", "INTO", - "FLOAT", "BLOB", "INTEGER", "VARIABLE", - "CASE", "WHEN", "THEN", "ELSE", - "INDEX", "ALTER", "ADD", "error", - "input", "cmdlist", "ecmd", "explain", - "cmdx", "cmd", "transtype", "trans_opt", - "nm", "savepoint_opt", "create_table", "create_table_args", - "createkw", "temp", "ifnotexists", "dbnm", - "columnlist", "conslist_opt", "table_options", "select", - "columnname", "carglist", "typetoken", "typename", - "signed", "plus_num", "minus_num", "ccons", - "term", "expr", "onconf", "sortorder", - "autoinc", "eidlist_opt", "refargs", "defer_subclause", - "refarg", "refact", "init_deferred_pred_opt", "conslist", - "tconscomma", "tcons", "sortlist", "eidlist", - "defer_subclause_opt", "orconf", "resolvetype", "raisetype", - "ifexists", "fullname", "selectnowith", "oneselect", - "with", "multiselect_op", "distinct", "selcollist", - "from", "where_opt", "groupby_opt", "having_opt", - "orderby_opt", "limit_opt", "values", "nexprlist", - "exprlist", "sclp", "as", "seltablist", - "stl_prefix", "joinop", "indexed_opt", "on_opt", - "using_opt", "idlist", "setlist", "insert_cmd", - "idlist_opt", "likeop", "between_op", "in_op", - "paren_exprlist", "case_operand", "case_exprlist", "case_else", - "uniqueflag", "collate", "nmnum", "trigger_decl", - "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", - "when_clause", "trigger_cmd", "trnm", "tridxby", - "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt", - "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken", - "lp", "anylist", "wqlist", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "explain ::= EXPLAIN", - /* 1 */ "explain ::= EXPLAIN QUERY PLAN", - /* 2 */ "cmdx ::= cmd", - /* 3 */ "cmd ::= BEGIN transtype trans_opt", - /* 4 */ "transtype ::=", - /* 5 */ "transtype ::= DEFERRED", - /* 6 */ "transtype ::= IMMEDIATE", - /* 7 */ "transtype ::= EXCLUSIVE", - /* 8 */ "cmd ::= COMMIT trans_opt", - /* 9 */ "cmd ::= END trans_opt", - /* 10 */ "cmd ::= ROLLBACK trans_opt", - /* 11 */ "cmd ::= SAVEPOINT nm", - /* 12 */ "cmd ::= RELEASE savepoint_opt nm", - /* 13 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm", - /* 14 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm", - /* 15 */ "createkw ::= CREATE", - /* 16 */ "ifnotexists ::=", - /* 17 */ "ifnotexists ::= IF NOT EXISTS", - /* 18 */ "temp ::= TEMP", - /* 19 */ "temp ::=", - /* 20 */ "create_table_args ::= LP columnlist conslist_opt RP table_options", - /* 21 */ "create_table_args ::= AS select", - /* 22 */ "table_options ::=", - /* 23 */ "table_options ::= WITHOUT nm", - /* 24 */ "columnname ::= nm typetoken", - /* 25 */ "typetoken ::=", - /* 26 */ "typetoken ::= typename LP signed RP", - /* 27 */ "typetoken ::= typename LP signed COMMA signed RP", - /* 28 */ "typename ::= typename ID|STRING", - /* 29 */ "ccons ::= CONSTRAINT nm", - /* 30 */ "ccons ::= DEFAULT term", - /* 31 */ "ccons ::= DEFAULT LP expr RP", - /* 32 */ "ccons ::= DEFAULT PLUS term", - /* 33 */ "ccons ::= DEFAULT MINUS term", - /* 34 */ "ccons ::= DEFAULT ID|INDEXED", - /* 35 */ "ccons ::= NOT NULL onconf", - /* 36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", - /* 37 */ "ccons ::= UNIQUE onconf", - /* 38 */ "ccons ::= CHECK LP expr RP", - /* 39 */ "ccons ::= REFERENCES nm eidlist_opt refargs", - /* 40 */ "ccons ::= defer_subclause", - /* 41 */ "ccons ::= COLLATE ID|STRING", - /* 42 */ "autoinc ::=", - /* 43 */ "autoinc ::= AUTOINCR", - /* 44 */ "refargs ::=", - /* 45 */ "refargs ::= refargs refarg", - /* 46 */ "refarg ::= MATCH nm", - /* 47 */ "refarg ::= ON INSERT refact", - /* 48 */ "refarg ::= ON DELETE refact", - /* 49 */ "refarg ::= ON UPDATE refact", - /* 50 */ "refact ::= SET NULL", - /* 51 */ "refact ::= SET DEFAULT", - /* 52 */ "refact ::= CASCADE", - /* 53 */ "refact ::= RESTRICT", - /* 54 */ "refact ::= NO ACTION", - /* 55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 57 */ "init_deferred_pred_opt ::=", - /* 58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 60 */ "conslist_opt ::=", - /* 61 */ "tconscomma ::= COMMA", - /* 62 */ "tcons ::= CONSTRAINT nm", - /* 63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", - /* 64 */ "tcons ::= UNIQUE LP sortlist RP onconf", - /* 65 */ "tcons ::= CHECK LP expr RP onconf", - /* 66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", - /* 67 */ "defer_subclause_opt ::=", - /* 68 */ "onconf ::=", - /* 69 */ "onconf ::= ON CONFLICT resolvetype", - /* 70 */ "orconf ::=", - /* 71 */ "orconf ::= OR resolvetype", - /* 72 */ "resolvetype ::= IGNORE", - /* 73 */ "resolvetype ::= REPLACE", - /* 74 */ "cmd ::= DROP TABLE ifexists fullname", - /* 75 */ "ifexists ::= IF EXISTS", - /* 76 */ "ifexists ::=", - /* 77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", - /* 78 */ "cmd ::= DROP VIEW ifexists fullname", - /* 79 */ "cmd ::= select", - /* 80 */ "select ::= with selectnowith", - /* 81 */ "selectnowith ::= selectnowith multiselect_op oneselect", - /* 82 */ "multiselect_op ::= UNION", - /* 83 */ "multiselect_op ::= UNION ALL", - /* 84 */ "multiselect_op ::= EXCEPT|INTERSECT", - /* 85 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 86 */ "values ::= VALUES LP nexprlist RP", - /* 87 */ "values ::= values COMMA LP exprlist RP", - /* 88 */ "distinct ::= DISTINCT", - /* 89 */ "distinct ::= ALL", - /* 90 */ "distinct ::=", - /* 91 */ "sclp ::=", - /* 92 */ "selcollist ::= sclp expr as", - /* 93 */ "selcollist ::= sclp STAR", - /* 94 */ "selcollist ::= sclp nm DOT STAR", - /* 95 */ "as ::= AS nm", - /* 96 */ "as ::=", - /* 97 */ "from ::=", - /* 98 */ "from ::= FROM seltablist", - /* 99 */ "stl_prefix ::= seltablist joinop", - /* 100 */ "stl_prefix ::=", - /* 101 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", - /* 102 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", - /* 103 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", - /* 104 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", - /* 105 */ "dbnm ::=", - /* 106 */ "dbnm ::= DOT nm", - /* 107 */ "fullname ::= nm dbnm", - /* 108 */ "joinop ::= COMMA|JOIN", - /* 109 */ "joinop ::= JOIN_KW JOIN", - /* 110 */ "joinop ::= JOIN_KW nm JOIN", - /* 111 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 112 */ "on_opt ::= ON expr", - /* 113 */ "on_opt ::=", - /* 114 */ "indexed_opt ::=", - /* 115 */ "indexed_opt ::= INDEXED BY nm", - /* 116 */ "indexed_opt ::= NOT INDEXED", - /* 117 */ "using_opt ::= USING LP idlist RP", - /* 118 */ "using_opt ::=", - /* 119 */ "orderby_opt ::=", - /* 120 */ "orderby_opt ::= ORDER BY sortlist", - /* 121 */ "sortlist ::= sortlist COMMA expr sortorder", - /* 122 */ "sortlist ::= expr sortorder", - /* 123 */ "sortorder ::= ASC", - /* 124 */ "sortorder ::= DESC", - /* 125 */ "sortorder ::=", - /* 126 */ "groupby_opt ::=", - /* 127 */ "groupby_opt ::= GROUP BY nexprlist", - /* 128 */ "having_opt ::=", - /* 129 */ "having_opt ::= HAVING expr", - /* 130 */ "limit_opt ::=", - /* 131 */ "limit_opt ::= LIMIT expr", - /* 132 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 133 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 134 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt", - /* 135 */ "where_opt ::=", - /* 136 */ "where_opt ::= WHERE expr", - /* 137 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt", - /* 138 */ "setlist ::= setlist COMMA nm EQ expr", - /* 139 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 140 */ "setlist ::= nm EQ expr", - /* 141 */ "setlist ::= LP idlist RP EQ expr", - /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select", - /* 143 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES", - /* 144 */ "insert_cmd ::= INSERT orconf", - /* 145 */ "insert_cmd ::= REPLACE", - /* 146 */ "idlist_opt ::=", - /* 147 */ "idlist_opt ::= LP idlist RP", - /* 148 */ "idlist ::= idlist COMMA nm", - /* 149 */ "idlist ::= nm", - /* 150 */ "expr ::= LP expr RP", - /* 151 */ "term ::= NULL", - /* 152 */ "expr ::= ID|INDEXED", - /* 153 */ "expr ::= JOIN_KW", - /* 154 */ "expr ::= nm DOT nm", - /* 155 */ "expr ::= nm DOT nm DOT nm", - /* 156 */ "term ::= FLOAT|BLOB", - /* 157 */ "term ::= STRING", - /* 158 */ "term ::= INTEGER", - /* 159 */ "expr ::= VARIABLE", - /* 160 */ "expr ::= expr COLLATE ID|STRING", - /* 161 */ "expr ::= CAST LP expr AS typetoken RP", - /* 162 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 163 */ "expr ::= ID|INDEXED LP STAR RP", - /* 164 */ "term ::= CTIME_KW", - /* 165 */ "expr ::= LP nexprlist COMMA expr RP", - /* 166 */ "expr ::= expr AND expr", - /* 167 */ "expr ::= expr OR expr", - /* 168 */ "expr ::= expr LT|GT|GE|LE expr", - /* 169 */ "expr ::= expr EQ|NE expr", - /* 170 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 171 */ "expr ::= expr PLUS|MINUS expr", - /* 172 */ "expr ::= expr STAR|SLASH|REM expr", - /* 173 */ "expr ::= expr CONCAT expr", - /* 174 */ "likeop ::= LIKE_KW|MATCH", - /* 175 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 176 */ "expr ::= expr likeop expr", - /* 177 */ "expr ::= expr likeop expr ESCAPE expr", - /* 178 */ "expr ::= expr ISNULL|NOTNULL", - /* 179 */ "expr ::= expr NOT NULL", - /* 180 */ "expr ::= expr IS expr", - /* 181 */ "expr ::= expr IS NOT expr", - /* 182 */ "expr ::= NOT expr", - /* 183 */ "expr ::= BITNOT expr", - /* 184 */ "expr ::= MINUS expr", - /* 185 */ "expr ::= PLUS expr", - /* 186 */ "between_op ::= BETWEEN", - /* 187 */ "between_op ::= NOT BETWEEN", - /* 188 */ "expr ::= expr between_op expr AND expr", - /* 189 */ "in_op ::= IN", - /* 190 */ "in_op ::= NOT IN", - /* 191 */ "expr ::= expr in_op LP exprlist RP", - /* 192 */ "expr ::= LP select RP", - /* 193 */ "expr ::= expr in_op LP select RP", - /* 194 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 195 */ "expr ::= EXISTS LP select RP", - /* 196 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 197 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 198 */ "case_exprlist ::= WHEN expr THEN expr", - /* 199 */ "case_else ::= ELSE expr", - /* 200 */ "case_else ::=", - /* 201 */ "case_operand ::= expr", - /* 202 */ "case_operand ::=", - /* 203 */ "exprlist ::=", - /* 204 */ "nexprlist ::= nexprlist COMMA expr", - /* 205 */ "nexprlist ::= expr", - /* 206 */ "paren_exprlist ::=", - /* 207 */ "paren_exprlist ::= LP exprlist RP", - /* 208 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 209 */ "uniqueflag ::= UNIQUE", - /* 210 */ "uniqueflag ::=", - /* 211 */ "eidlist_opt ::=", - /* 212 */ "eidlist_opt ::= LP eidlist RP", - /* 213 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 214 */ "eidlist ::= nm collate sortorder", - /* 215 */ "collate ::=", - /* 216 */ "collate ::= COLLATE ID|STRING", - /* 217 */ "cmd ::= DROP INDEX ifexists fullname", - /* 218 */ "cmd ::= VACUUM", - /* 219 */ "cmd ::= VACUUM nm", - /* 220 */ "cmd ::= PRAGMA nm dbnm", - /* 221 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 222 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 223 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 224 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 225 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 226 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 227 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 228 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 229 */ "trigger_time ::= BEFORE", - /* 230 */ "trigger_time ::= AFTER", - /* 231 */ "trigger_time ::= INSTEAD OF", - /* 232 */ "trigger_time ::=", - /* 233 */ "trigger_event ::= DELETE|INSERT", - /* 234 */ "trigger_event ::= UPDATE", - /* 235 */ "trigger_event ::= UPDATE OF idlist", - /* 236 */ "when_clause ::=", - /* 237 */ "when_clause ::= WHEN expr", - /* 238 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 239 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 240 */ "trnm ::= nm DOT nm", - /* 241 */ "tridxby ::= INDEXED BY nm", - /* 242 */ "tridxby ::= NOT INDEXED", - /* 243 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", - /* 244 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select", - /* 245 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", - /* 246 */ "trigger_cmd ::= select", - /* 247 */ "expr ::= RAISE LP IGNORE RP", - /* 248 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 249 */ "raisetype ::= ROLLBACK", - /* 250 */ "raisetype ::= ABORT", - /* 251 */ "raisetype ::= FAIL", - /* 252 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 253 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 254 */ "cmd ::= DETACH database_kw_opt expr", - /* 255 */ "key_opt ::=", - /* 256 */ "key_opt ::= KEY expr", - /* 257 */ "cmd ::= REINDEX", - /* 258 */ "cmd ::= REINDEX nm dbnm", - /* 259 */ "cmd ::= ANALYZE", - /* 260 */ "cmd ::= ANALYZE nm dbnm", - /* 261 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 262 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 263 */ "add_column_fullname ::= fullname", - /* 264 */ "cmd ::= create_vtab", - /* 265 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 266 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 267 */ "vtabarg ::=", - /* 268 */ "vtabargtoken ::= ANY", - /* 269 */ "vtabargtoken ::= lp anylist RP", - /* 270 */ "lp ::= LP", - /* 271 */ "with ::=", - /* 272 */ "with ::= WITH wqlist", - /* 273 */ "with ::= WITH RECURSIVE wqlist", - /* 274 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 275 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 276 */ "input ::= cmdlist", - /* 277 */ "cmdlist ::= cmdlist ecmd", - /* 278 */ "cmdlist ::= ecmd", - /* 279 */ "ecmd ::= SEMI", - /* 280 */ "ecmd ::= explain cmdx SEMI", - /* 281 */ "explain ::=", - /* 282 */ "trans_opt ::=", - /* 283 */ "trans_opt ::= TRANSACTION", - /* 284 */ "trans_opt ::= TRANSACTION nm", - /* 285 */ "savepoint_opt ::= SAVEPOINT", - /* 286 */ "savepoint_opt ::=", - /* 287 */ "cmd ::= create_table create_table_args", - /* 288 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 289 */ "columnlist ::= columnname carglist", - /* 290 */ "nm ::= ID|INDEXED", - /* 291 */ "nm ::= STRING", - /* 292 */ "nm ::= JOIN_KW", - /* 293 */ "typetoken ::= typename", - /* 294 */ "typename ::= ID|STRING", - /* 295 */ "signed ::= plus_num", - /* 296 */ "signed ::= minus_num", - /* 297 */ "carglist ::= carglist ccons", - /* 298 */ "carglist ::=", - /* 299 */ "ccons ::= NULL onconf", - /* 300 */ "conslist_opt ::= COMMA conslist", - /* 301 */ "conslist ::= conslist tconscomma tcons", - /* 302 */ "conslist ::= tcons", - /* 303 */ "tconscomma ::=", - /* 304 */ "defer_subclause_opt ::= defer_subclause", - /* 305 */ "resolvetype ::= raisetype", - /* 306 */ "selectnowith ::= oneselect", - /* 307 */ "oneselect ::= values", - /* 308 */ "sclp ::= selcollist COMMA", - /* 309 */ "as ::= ID|STRING", - /* 310 */ "expr ::= term", - /* 311 */ "exprlist ::= nexprlist", - /* 312 */ "nmnum ::= plus_num", - /* 313 */ "nmnum ::= nm", - /* 314 */ "nmnum ::= ON", - /* 315 */ "nmnum ::= DELETE", - /* 316 */ "nmnum ::= DEFAULT", - /* 317 */ "plus_num ::= INTEGER|FLOAT", - /* 318 */ "foreach_clause ::=", - /* 319 */ "foreach_clause ::= FOR EACH ROW", - /* 320 */ "trnm ::= nm", - /* 321 */ "tridxby ::=", - /* 322 */ "database_kw_opt ::= DATABASE", - /* 323 */ "database_kw_opt ::=", - /* 324 */ "kwcolumn_opt ::=", - /* 325 */ "kwcolumn_opt ::= COLUMNKW", - /* 326 */ "vtabarglist ::= vtabarg", - /* 327 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 328 */ "vtabarg ::= vtabarg vtabargtoken", - /* 329 */ "anylist ::=", - /* 330 */ "anylist ::= anylist LP anylist RP", - /* 331 */ "anylist ::= anylist ANY", -}; -#endif /* NDEBUG */ - - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. Return the number -** of errors. Return 0 on success. -*/ -static int yyGrowStack(yyParser *p){ - int newSize; - int idx; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; - if( p->yystack==&p->yystk0 ){ - pNew = malloc(newSize*sizeof(pNew[0])); - if( pNew ) pNew[0] = p->yystk0; - }else{ - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - } - if( pNew ){ - p->yystack = pNew; - p->yytos = &p->yystack[idx]; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", - yyTracePrompt, p->yystksz, newSize); - } -#endif - p->yystksz = newSize; - } - return pNew==0; -} -#endif - -/* Datatype of the argument to the memory allocated passed as the -** second argument to sqlite3ParserAlloc() below. This can be changed by -** putting an appropriate #define in the %include section of the input -** grammar. -*/ -#ifndef YYMALLOCARGTYPE -# define YYMALLOCARGTYPE size_t -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to sqlite3Parser and sqlite3ParserFree. -*/ -SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); - if( pParser ){ -#ifdef YYTRACKMAXSTACKDEPTH - pParser->yyhwm = 0; -#endif -#if YYSTACKDEPTH<=0 - pParser->yytos = NULL; - pParser->yystack = NULL; - pParser->yystksz = 0; - if( yyGrowStack(pParser) ){ - pParser->yystack = &pParser->yystk0; - pParser->yystksz = 1; - } -#endif -#ifndef YYNOERRORRECOVERY - pParser->yyerrcnt = -1; -#endif - pParser->yytos = pParser->yystack; - pParser->yystack[0].stateno = 0; - pParser->yystack[0].major = 0; - } - return pParser; -} - -/* The following function deletes the "minor type" or semantic value -** associated with a symbol. The symbol can be either a terminal -** or nonterminal. "yymajor" is the symbol code, and "yypminor" is -** a pointer to the value to be deleted. The code used to do the -** deletions is derived from the %destructor and/or %token_destructor -** directives of the input grammar. -*/ -static void yy_destructor( - yyParser *yypParser, /* The parser */ - YYCODETYPE yymajor, /* Type code for object to destroy */ - YYMINORTYPE *yypminor /* The object to be destroyed */ -){ - sqlite3ParserARG_FETCH; - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are *not* used - ** inside the C code. - */ -/********* Begin destructor definitions ***************************************/ - case 163: /* select */ - case 194: /* selectnowith */ - case 195: /* oneselect */ - case 206: /* values */ -{ -sqlite3SelectDelete(pParse->db, (yypminor->yy243)); -} - break; - case 172: /* term */ - case 173: /* expr */ -{ -sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr); -} - break; - case 177: /* eidlist_opt */ - case 186: /* sortlist */ - case 187: /* eidlist */ - case 199: /* selcollist */ - case 202: /* groupby_opt */ - case 204: /* orderby_opt */ - case 207: /* nexprlist */ - case 208: /* exprlist */ - case 209: /* sclp */ - case 218: /* setlist */ - case 224: /* paren_exprlist */ - case 226: /* case_exprlist */ -{ -sqlite3ExprListDelete(pParse->db, (yypminor->yy148)); -} - break; - case 193: /* fullname */ - case 200: /* from */ - case 211: /* seltablist */ - case 212: /* stl_prefix */ -{ -sqlite3SrcListDelete(pParse->db, (yypminor->yy185)); -} - break; - case 196: /* with */ - case 250: /* wqlist */ -{ -sqlite3WithDelete(pParse->db, (yypminor->yy285)); -} - break; - case 201: /* where_opt */ - case 203: /* having_opt */ - case 215: /* on_opt */ - case 225: /* case_operand */ - case 227: /* case_else */ - case 236: /* when_clause */ - case 241: /* key_opt */ -{ -sqlite3ExprDelete(pParse->db, (yypminor->yy72)); -} - break; - case 216: /* using_opt */ - case 217: /* idlist */ - case 220: /* idlist_opt */ -{ -sqlite3IdListDelete(pParse->db, (yypminor->yy254)); -} - break; - case 232: /* trigger_cmd_list */ - case 237: /* trigger_cmd */ -{ -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145)); -} - break; - case 234: /* trigger_event */ -{ -sqlite3IdListDelete(pParse->db, (yypminor->yy332).b); -} - break; -/********* End destructor definitions *****************************************/ - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -*/ -static void yy_pop_parser_stack(yyParser *pParser){ - yyStackEntry *yytos; - assert( pParser->yytos!=0 ); - assert( pParser->yytos > pParser->yystack ); - yytos = pParser->yytos--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yy_destructor(pParser, yytos->major, &yytos->minor); -} - -/* -** Deallocate and destroy a parser. Destructors are called for -** all stack elements before shutting the parser down. -** -** If the YYPARSEFREENEVERNULL macro exists (for example because it -** is defined in a %include section of the input grammar) then it is -** assumed that the input pointer is never NULL. -*/ -SQLITE_PRIVATE void sqlite3ParserFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; -#ifndef YYPARSEFREENEVERNULL - if( pParser==0 ) return; -#endif - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Return the peak depth of the stack for a parser. -*/ -#ifdef YYTRACKMAXSTACKDEPTH -SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){ - yyParser *pParser = (yyParser*)p; - return pParser->yyhwm; -} -#endif - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -*/ -static unsigned int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yytos->stateno; - - if( stateno>=YY_MIN_REDUCE ) return stateno; - assert( stateno <= YY_SHIFT_COUNT ); - do{ - i = yy_shift_ofst[stateno]; - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ -#ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ - iLookAhead = iFallback; - continue; - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( -#if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && -#endif -#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 - ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], - yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - return yy_default[stateno]; - }else{ - return yy_action[i]; - } - }while(1); -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; -#ifdef YYERRORSYMBOL - if( stateno>YY_REDUCE_COUNT ){ - return yy_default[stateno]; - } -#else - assert( stateno<=YY_REDUCE_COUNT ); -#endif - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; -#ifdef YYERRORSYMBOL - if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ - return yy_default[stateno]; - } -#else - assert( i>=0 && iyytos--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -/******** Begin %stack_overflow code ******************************************/ - - sqlite3ErrorMsg(pParse, "parser stack overflow"); -/******** End %stack_overflow code ********************************************/ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Print tracing information for a SHIFT action -*/ -#ifndef NDEBUG -static void yyTraceShift(yyParser *yypParser, int yyNewState){ - if( yyTraceFILE ){ - if( yyNewStateyytos->major], - yyNewState); - }else{ - fprintf(yyTraceFILE,"%sShift '%s'\n", - yyTracePrompt,yyTokenName[yypParser->yytos->major]); - } - } -} -#else -# define yyTraceShift(X,Y) -#endif - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yytos++; -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){ - yyStackOverflow(yypParser); - return; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - return; - } - } -#endif - if( yyNewState > YY_MAX_SHIFT ){ - yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } - yytos = yypParser->yytos; - yytos->stateno = (YYACTIONTYPE)yyNewState; - yytos->major = (YYCODETYPE)yyMajor; - yytos->minor.yy0 = yyMinor; - yyTraceShift(yypParser, yyNewState); -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 147, 1 }, - { 147, 3 }, - { 148, 1 }, - { 149, 3 }, - { 150, 0 }, - { 150, 1 }, - { 150, 1 }, - { 150, 1 }, - { 149, 2 }, - { 149, 2 }, - { 149, 2 }, - { 149, 2 }, - { 149, 3 }, - { 149, 5 }, - { 154, 6 }, - { 156, 1 }, - { 158, 0 }, - { 158, 3 }, - { 157, 1 }, - { 157, 0 }, - { 155, 5 }, - { 155, 2 }, - { 162, 0 }, - { 162, 2 }, - { 164, 2 }, - { 166, 0 }, - { 166, 4 }, - { 166, 6 }, - { 167, 2 }, - { 171, 2 }, - { 171, 2 }, - { 171, 4 }, - { 171, 3 }, - { 171, 3 }, - { 171, 2 }, - { 171, 3 }, - { 171, 5 }, - { 171, 2 }, - { 171, 4 }, - { 171, 4 }, - { 171, 1 }, - { 171, 2 }, - { 176, 0 }, - { 176, 1 }, - { 178, 0 }, - { 178, 2 }, - { 180, 2 }, - { 180, 3 }, - { 180, 3 }, - { 180, 3 }, - { 181, 2 }, - { 181, 2 }, - { 181, 1 }, - { 181, 1 }, - { 181, 2 }, - { 179, 3 }, - { 179, 2 }, - { 182, 0 }, - { 182, 2 }, - { 182, 2 }, - { 161, 0 }, - { 184, 1 }, - { 185, 2 }, - { 185, 7 }, - { 185, 5 }, - { 185, 5 }, - { 185, 10 }, - { 188, 0 }, - { 174, 0 }, - { 174, 3 }, - { 189, 0 }, - { 189, 2 }, - { 190, 1 }, - { 190, 1 }, - { 149, 4 }, - { 192, 2 }, - { 192, 0 }, - { 149, 9 }, - { 149, 4 }, - { 149, 1 }, - { 163, 2 }, - { 194, 3 }, - { 197, 1 }, - { 197, 2 }, - { 197, 1 }, - { 195, 9 }, - { 206, 4 }, - { 206, 5 }, - { 198, 1 }, - { 198, 1 }, - { 198, 0 }, - { 209, 0 }, - { 199, 3 }, - { 199, 2 }, - { 199, 4 }, - { 210, 2 }, - { 210, 0 }, - { 200, 0 }, - { 200, 2 }, - { 212, 2 }, - { 212, 0 }, - { 211, 7 }, - { 211, 9 }, - { 211, 7 }, - { 211, 7 }, - { 159, 0 }, - { 159, 2 }, - { 193, 2 }, - { 213, 1 }, - { 213, 2 }, - { 213, 3 }, - { 213, 4 }, - { 215, 2 }, - { 215, 0 }, - { 214, 0 }, - { 214, 3 }, - { 214, 2 }, - { 216, 4 }, - { 216, 0 }, - { 204, 0 }, - { 204, 3 }, - { 186, 4 }, - { 186, 2 }, - { 175, 1 }, - { 175, 1 }, - { 175, 0 }, - { 202, 0 }, - { 202, 3 }, - { 203, 0 }, - { 203, 2 }, - { 205, 0 }, - { 205, 2 }, - { 205, 4 }, - { 205, 4 }, - { 149, 6 }, - { 201, 0 }, - { 201, 2 }, - { 149, 8 }, - { 218, 5 }, - { 218, 7 }, - { 218, 3 }, - { 218, 5 }, - { 149, 6 }, - { 149, 7 }, - { 219, 2 }, - { 219, 1 }, - { 220, 0 }, - { 220, 3 }, - { 217, 3 }, - { 217, 1 }, - { 173, 3 }, - { 172, 1 }, - { 173, 1 }, - { 173, 1 }, - { 173, 3 }, - { 173, 5 }, - { 172, 1 }, - { 172, 1 }, - { 172, 1 }, - { 173, 1 }, - { 173, 3 }, - { 173, 6 }, - { 173, 5 }, - { 173, 4 }, - { 172, 1 }, - { 173, 5 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 173, 3 }, - { 221, 1 }, - { 221, 2 }, - { 173, 3 }, - { 173, 5 }, - { 173, 2 }, - { 173, 3 }, - { 173, 3 }, - { 173, 4 }, - { 173, 2 }, - { 173, 2 }, - { 173, 2 }, - { 173, 2 }, - { 222, 1 }, - { 222, 2 }, - { 173, 5 }, - { 223, 1 }, - { 223, 2 }, - { 173, 5 }, - { 173, 3 }, - { 173, 5 }, - { 173, 5 }, - { 173, 4 }, - { 173, 5 }, - { 226, 5 }, - { 226, 4 }, - { 227, 2 }, - { 227, 0 }, - { 225, 1 }, - { 225, 0 }, - { 208, 0 }, - { 207, 3 }, - { 207, 1 }, - { 224, 0 }, - { 224, 3 }, - { 149, 12 }, - { 228, 1 }, - { 228, 0 }, - { 177, 0 }, - { 177, 3 }, - { 187, 5 }, - { 187, 3 }, - { 229, 0 }, - { 229, 2 }, - { 149, 4 }, - { 149, 1 }, - { 149, 2 }, - { 149, 3 }, - { 149, 5 }, - { 149, 6 }, - { 149, 5 }, - { 149, 6 }, - { 169, 2 }, - { 170, 2 }, - { 149, 5 }, - { 231, 11 }, - { 233, 1 }, - { 233, 1 }, - { 233, 2 }, - { 233, 0 }, - { 234, 1 }, - { 234, 1 }, - { 234, 3 }, - { 236, 0 }, - { 236, 2 }, - { 232, 3 }, - { 232, 2 }, - { 238, 3 }, - { 239, 3 }, - { 239, 2 }, - { 237, 7 }, - { 237, 5 }, - { 237, 5 }, - { 237, 1 }, - { 173, 4 }, - { 173, 6 }, - { 191, 1 }, - { 191, 1 }, - { 191, 1 }, - { 149, 4 }, - { 149, 6 }, - { 149, 3 }, - { 241, 0 }, - { 241, 2 }, - { 149, 1 }, - { 149, 3 }, - { 149, 1 }, - { 149, 3 }, - { 149, 6 }, - { 149, 7 }, - { 242, 1 }, - { 149, 1 }, - { 149, 4 }, - { 244, 8 }, - { 246, 0 }, - { 247, 1 }, - { 247, 3 }, - { 248, 1 }, - { 196, 0 }, - { 196, 2 }, - { 196, 3 }, - { 250, 6 }, - { 250, 8 }, - { 144, 1 }, - { 145, 2 }, - { 145, 1 }, - { 146, 1 }, - { 146, 3 }, - { 147, 0 }, - { 151, 0 }, - { 151, 1 }, - { 151, 2 }, - { 153, 1 }, - { 153, 0 }, - { 149, 2 }, - { 160, 4 }, - { 160, 2 }, - { 152, 1 }, - { 152, 1 }, - { 152, 1 }, - { 166, 1 }, - { 167, 1 }, - { 168, 1 }, - { 168, 1 }, - { 165, 2 }, - { 165, 0 }, - { 171, 2 }, - { 161, 2 }, - { 183, 3 }, - { 183, 1 }, - { 184, 0 }, - { 188, 1 }, - { 190, 1 }, - { 194, 1 }, - { 195, 1 }, - { 209, 2 }, - { 210, 1 }, - { 173, 1 }, - { 208, 1 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, - { 230, 1 }, - { 169, 1 }, - { 235, 0 }, - { 235, 3 }, - { 238, 1 }, - { 239, 0 }, - { 240, 1 }, - { 240, 0 }, - { 243, 0 }, - { 243, 1 }, - { 245, 1 }, - { 245, 3 }, - { 246, 2 }, - { 249, 0 }, - { 249, 4 }, - { 249, 2 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - unsigned int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - sqlite3ParserARG_FETCH; - yymsp = yypParser->yytos; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; - fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt, - yyRuleName[yyruleno], yymsp[-yysize].stateno); - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfo[yyruleno].nrhs==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){ - yyStackOverflow(yypParser); - return; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - return; - } - yymsp = yypParser->yytos; - } -#endif - } - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ -/********** Begin reduce actions **********************************************/ - YYMINORTYPE yylhsminor; - case 0: /* explain ::= EXPLAIN */ -{ pParse->explain = 1; } - break; - case 1: /* explain ::= EXPLAIN QUERY PLAN */ -{ pParse->explain = 2; } - break; - case 2: /* cmdx ::= cmd */ -{ sqlite3FinishCoding(pParse); } - break; - case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);} - break; - case 4: /* transtype ::= */ -{yymsp[1].minor.yy194 = TK_DEFERRED;} - break; - case 5: /* transtype ::= DEFERRED */ - case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); - case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); -{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/} - break; - case 8: /* cmd ::= COMMIT trans_opt */ - case 9: /* cmd ::= END trans_opt */ yytestcase(yyruleno==9); -{sqlite3CommitTransaction(pParse);} - break; - case 10: /* cmd ::= ROLLBACK trans_opt */ -{sqlite3RollbackTransaction(pParse);} - break; - case 11: /* cmd ::= SAVEPOINT nm */ -{ - sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); -} - break; - case 12: /* cmd ::= RELEASE savepoint_opt nm */ -{ - sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); -} - break; - case 13: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ -{ - sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); -} - break; - case 14: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ -{ - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194); -} - break; - case 15: /* createkw ::= CREATE */ -{disableLookaside(pParse);} - break; - case 16: /* ifnotexists ::= */ - case 19: /* temp ::= */ yytestcase(yyruleno==19); - case 22: /* table_options ::= */ yytestcase(yyruleno==22); - case 42: /* autoinc ::= */ yytestcase(yyruleno==42); - case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57); - case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67); - case 76: /* ifexists ::= */ yytestcase(yyruleno==76); - case 90: /* distinct ::= */ yytestcase(yyruleno==90); - case 215: /* collate ::= */ yytestcase(yyruleno==215); -{yymsp[1].minor.yy194 = 0;} - break; - case 17: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy194 = 1;} - break; - case 18: /* temp ::= TEMP */ - case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43); -{yymsp[0].minor.yy194 = 1;} - break; - case 20: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ -{ - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0); -} - break; - case 21: /* create_table_args ::= AS select */ -{ - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); -} - break; - case 23: /* table_options ::= WITHOUT nm */ -{ - if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid; - }else{ - yymsp[-1].minor.yy194 = 0; - sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); - } -} - break; - case 24: /* columnname ::= nm typetoken */ -{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} - break; - case 25: /* typetoken ::= */ - case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60); - case 96: /* as ::= */ yytestcase(yyruleno==96); -{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} - break; - case 26: /* typetoken ::= typename LP signed RP */ -{ - yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); -} - break; - case 27: /* typetoken ::= typename LP signed COMMA signed RP */ -{ - yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); -} - break; - case 28: /* typename ::= typename ID|STRING */ -{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} - break; - case 29: /* ccons ::= CONSTRAINT nm */ - case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62); -{pParse->constraintName = yymsp[0].minor.yy0;} - break; - case 30: /* ccons ::= DEFAULT term */ - case 32: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==32); -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);} - break; - case 31: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);} - break; - case 33: /* ccons ::= DEFAULT MINUS term */ -{ - ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0, 0); - v.zStart = yymsp[-1].minor.yy0.z; - v.zEnd = yymsp[0].minor.yy190.zEnd; - sqlite3AddDefaultValue(pParse,&v); -} - break; - case 34: /* ccons ::= DEFAULT ID|INDEXED */ -{ - ExprSpan v; - spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0); - sqlite3AddDefaultValue(pParse,&v); -} - break; - case 35: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);} - break; - case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);} - break; - case 37: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0, - SQLITE_IDXTYPE_UNIQUE);} - break; - case 38: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);} - break; - case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);} - break; - case 40: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);} - break; - case 41: /* ccons ::= COLLATE ID|STRING */ -{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} - break; - case 44: /* refargs ::= */ -{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */} - break; - case 45: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; } - break; - case 46: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy497.value = 0; yymsp[-1].minor.yy497.mask = 0x000000; } - break; - case 47: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy497.value = 0; yymsp[-2].minor.yy497.mask = 0x000000; } - break; - case 48: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194; yymsp[-2].minor.yy497.mask = 0x0000ff; } - break; - case 49: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8; yymsp[-2].minor.yy497.mask = 0x00ff00; } - break; - case 50: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy194 = OE_SetNull; /* EV: R-33326-45252 */} - break; - case 51: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy194 = OE_SetDflt; /* EV: R-33326-45252 */} - break; - case 52: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy194 = OE_Cascade; /* EV: R-33326-45252 */} - break; - case 53: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */} - break; - case 54: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy194 = OE_None; /* EV: R-33326-45252 */} - break; - case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy194 = 0;} - break; - case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71); - case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144); -{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;} - break; - case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ - case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75); - case 187: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==187); - case 190: /* in_op ::= NOT IN */ yytestcase(yyruleno==190); - case 216: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==216); -{yymsp[-1].minor.yy194 = 1;} - break; - case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy194 = 0;} - break; - case 61: /* tconscomma ::= COMMA */ -{pParse->constraintName.n = 0;} - break; - case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);} - break; - case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0, - SQLITE_IDXTYPE_UNIQUE);} - break; - case 65: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);} - break; - case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ -{ - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194); -} - break; - case 68: /* onconf ::= */ - case 70: /* orconf ::= */ yytestcase(yyruleno==70); -{yymsp[1].minor.yy194 = OE_Default;} - break; - case 69: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;} - break; - case 72: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy194 = OE_Ignore;} - break; - case 73: /* resolvetype ::= REPLACE */ - case 145: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==145); -{yymsp[0].minor.yy194 = OE_Replace;} - break; - case 74: /* cmd ::= DROP TABLE ifexists fullname */ -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194); -} - break; - case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ -{ - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194); -} - break; - case 78: /* cmd ::= DROP VIEW ifexists fullname */ -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194); -} - break; - case 79: /* cmd ::= select */ -{ - SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy243, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); -} - break; - case 80: /* select ::= with selectnowith */ -{ - Select *p = yymsp[0].minor.yy243; - if( p ){ - p->pWith = yymsp[-1].minor.yy285; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285); - } - yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/ -} - break; - case 81: /* selectnowith ::= selectnowith multiselect_op oneselect */ -{ - Select *pRhs = yymsp[0].minor.yy243; - Select *pLhs = yymsp[-2].minor.yy243; - if( pRhs && pRhs->pPrior ){ - SrcList *pFrom; - Token x; - x.n = 0; - parserDoubleLinkSelect(pParse, pRhs); - pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); - pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0); - } - if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy194; - pRhs->pPrior = pLhs; - if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; - pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1; - }else{ - sqlite3SelectDelete(pParse->db, pLhs); - } - yymsp[-2].minor.yy243 = pRhs; -} - break; - case 82: /* multiselect_op ::= UNION */ - case 84: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==84); -{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/} - break; - case 83: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy194 = TK_ALL;} - break; - case 85: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ -{ -#if SELECTTRACE_ENABLED - Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/ -#endif - yymsp[-8].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset); -#if SELECTTRACE_ENABLED - /* Populate the Select.zSelName[] string that is used to help with - ** query planner debugging, to differentiate between multiple Select - ** objects in a complex query. - ** - ** If the SELECT keyword is immediately followed by a C-style comment - ** then extract the first few alphanumeric characters from within that - ** comment to be the zSelName value. Otherwise, the label is #N where - ** is an integer that is incremented with each SELECT statement seen. - */ - if( yymsp[-8].minor.yy243!=0 ){ - const char *z = s.z+6; - int i; - sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "#%d", - ++pParse->nSelect); - while( z[0]==' ' ) z++; - if( z[0]=='/' && z[1]=='*' ){ - z += 2; - while( z[0]==' ' ) z++; - for(i=0; sqlite3Isalnum(z[i]); i++){} - sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, z); - } - } -#endif /* SELECTRACE_ENABLED */ -} - break; - case 86: /* values ::= VALUES LP nexprlist RP */ -{ - yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0); -} - break; - case 87: /* values ::= values COMMA LP exprlist RP */ -{ - Select *pRight, *pLeft = yymsp[-4].minor.yy243; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0); - if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; - if( pRight ){ - pRight->op = TK_ALL; - pRight->pPrior = pLeft; - yymsp[-4].minor.yy243 = pRight; - }else{ - yymsp[-4].minor.yy243 = pLeft; - } -} - break; - case 88: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy194 = SF_Distinct;} - break; - case 89: /* distinct ::= ALL */ -{yymsp[0].minor.yy194 = SF_All;} - break; - case 91: /* sclp ::= */ - case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119); - case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126); - case 203: /* exprlist ::= */ yytestcase(yyruleno==203); - case 206: /* paren_exprlist ::= */ yytestcase(yyruleno==206); - case 211: /* eidlist_opt ::= */ yytestcase(yyruleno==211); -{yymsp[1].minor.yy148 = 0;} - break; - case 92: /* selcollist ::= sclp expr as */ -{ - yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy148, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy148,&yymsp[-1].minor.yy190); -} - break; - case 93: /* selcollist ::= sclp STAR */ -{ - Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p); -} - break; - case 94: /* selcollist ::= sclp nm DOT STAR */ -{ - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, 0); - Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot); -} - break; - case 95: /* as ::= AS nm */ - case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106); - case 225: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==225); - case 226: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==226); -{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} - break; - case 97: /* from ::= */ -{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));} - break; - case 98: /* from ::= FROM seltablist */ -{ - yymsp[-1].minor.yy185 = yymsp[0].minor.yy185; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185); -} - break; - case 99: /* stl_prefix ::= seltablist joinop */ -{ - if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194; -} - break; - case 100: /* stl_prefix ::= */ -{yymsp[1].minor.yy185 = 0;} - break; - case 101: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ -{ - yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0); -} - break; - case 102: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ -{ - yymsp[-8].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148); -} - break; - case 103: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ -{ - yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - } - break; - case 104: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ -{ - if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){ - yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185; - }else if( yymsp[-4].minor.yy185->nSrc==1 ){ - yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - if( yymsp[-6].minor.yy185 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy185->a; - pNew->zName = pOld->zName; - pNew->zDatabase = pOld->zDatabase; - pNew->pSelect = pOld->pSelect; - pOld->zName = pOld->zDatabase = 0; - pOld->pSelect = 0; - } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy185); - }else{ - Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0); - yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - } - } - break; - case 105: /* dbnm ::= */ - case 114: /* indexed_opt ::= */ yytestcase(yyruleno==114); -{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} - break; - case 107: /* fullname ::= nm dbnm */ -{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; - case 108: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy194 = JT_INNER; } - break; - case 109: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} - break; - case 110: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} - break; - case 111: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} - break; - case 112: /* on_opt ::= ON expr */ - case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129); - case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136); - case 199: /* case_else ::= ELSE expr */ yytestcase(yyruleno==199); -{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;} - break; - case 113: /* on_opt ::= */ - case 128: /* having_opt ::= */ yytestcase(yyruleno==128); - case 135: /* where_opt ::= */ yytestcase(yyruleno==135); - case 200: /* case_else ::= */ yytestcase(yyruleno==200); - case 202: /* case_operand ::= */ yytestcase(yyruleno==202); -{yymsp[1].minor.yy72 = 0;} - break; - case 115: /* indexed_opt ::= INDEXED BY nm */ -{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} - break; - case 116: /* indexed_opt ::= NOT INDEXED */ -{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} - break; - case 117: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} - break; - case 118: /* using_opt ::= */ - case 146: /* idlist_opt ::= */ yytestcase(yyruleno==146); -{yymsp[1].minor.yy254 = 0;} - break; - case 120: /* orderby_opt ::= ORDER BY sortlist */ - case 127: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==127); -{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;} - break; - case 121: /* sortlist ::= sortlist COMMA expr sortorder */ -{ - yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr); - sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194); -} - break; - case 122: /* sortlist ::= expr sortorder */ -{ - yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194); -} - break; - case 123: /* sortorder ::= ASC */ -{yymsp[0].minor.yy194 = SQLITE_SO_ASC;} - break; - case 124: /* sortorder ::= DESC */ -{yymsp[0].minor.yy194 = SQLITE_SO_DESC;} - break; - case 125: /* sortorder ::= */ -{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;} - break; - case 130: /* limit_opt ::= */ -{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;} - break; - case 131: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;} - break; - case 132: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;} - break; - case 133: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;} - break; - case 134: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */ -{ - sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1); - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72); -} - break; - case 137: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */ -{ - sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1); - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194); -} - break; - case 138: /* setlist ::= setlist COMMA nm EQ expr */ -{ - yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1); -} - break; - case 139: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ -{ - yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr); -} - break; - case 140: /* setlist ::= nm EQ expr */ -{ - yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr); - sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1); -} - yymsp[-2].minor.yy148 = yylhsminor.yy148; - break; - case 141: /* setlist ::= LP idlist RP EQ expr */ -{ - yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr); -} - break; - case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */ -{ - sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1); - sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194); -} - break; - case 143: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */ -{ - sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1); - sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194); -} - break; - case 147: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} - break; - case 148: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} - break; - case 149: /* idlist ::= nm */ -{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} - break; - case 150: /* expr ::= LP expr RP */ -{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;} - break; - case 151: /* term ::= NULL */ - case 156: /* term ::= FLOAT|BLOB */ yytestcase(yyruleno==156); - case 157: /* term ::= STRING */ yytestcase(yyruleno==157); -{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/} - break; - case 152: /* expr ::= ID|INDEXED */ - case 153: /* expr ::= JOIN_KW */ yytestcase(yyruleno==153); -{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; - case 154: /* expr ::= nm DOT nm */ -{ - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ - yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); -} - break; - case 155: /* expr ::= nm DOT nm DOT nm */ -{ - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); - spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); -} - break; - case 158: /* term ::= INTEGER */ -{ - yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); - yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z; - yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n; - if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf; -} - yymsp[0].minor.yy190 = yylhsminor.yy190; - break; - case 159: /* expr ::= VARIABLE */ -{ - if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ - u32 n = yymsp[0].minor.yy0.n; - spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n); - }else{ - /* When doing a nested parse, one can include terms in an expression - ** that look like this: #1 #2 ... These terms refer to registers - ** in the virtual machine. #N is the N-th register. */ - Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ - assert( t.n>=2 ); - spanSet(&yymsp[0].minor.yy190, &t, &t); - if( pParse->nested==0 ){ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy190.pExpr = 0; - }else{ - yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, 0); - if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable); - } - } -} - break; - case 160: /* expr ::= expr COLLATE ID|STRING */ -{ - yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1); - yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; -} - break; - case 161: /* expr ::= CAST LP expr AS typetoken RP */ -{ - spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ - yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0); -} - break; - case 162: /* expr ::= ID|INDEXED LP distinct exprlist RP */ -{ - if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ - sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); - } - yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0); - spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){ - yylhsminor.yy190.pExpr->flags |= EP_Distinct; - } -} - yymsp[-4].minor.yy190 = yylhsminor.yy190; - break; - case 163: /* expr ::= ID|INDEXED LP STAR RP */ -{ - yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); - spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -} - yymsp[-3].minor.yy190 = yylhsminor.yy190; - break; - case 164: /* term ::= CTIME_KW */ -{ - yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); - spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); -} - yymsp[0].minor.yy190 = yylhsminor.yy190; - break; - case 165: /* expr ::= LP nexprlist COMMA expr RP */ -{ - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr); - yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0, 0); - if( yylhsminor.yy190.pExpr ){ - yylhsminor.yy190.pExpr->x.pList = pList; - spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); - }else{ - sqlite3ExprListDelete(pParse->db, pList); - } -} - yymsp[-4].minor.yy190 = yylhsminor.yy190; - break; - case 166: /* expr ::= expr AND expr */ - case 167: /* expr ::= expr OR expr */ yytestcase(yyruleno==167); - case 168: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==168); - case 169: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==169); - case 170: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==170); - case 171: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==171); - case 172: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==172); - case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173); -{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);} - break; - case 174: /* likeop ::= LIKE_KW|MATCH */ -{yymsp[0].minor.yy0=yymsp[0].minor.yy0;/*A-overwrites-X*/} - break; - case 175: /* likeop ::= NOT LIKE_KW|MATCH */ -{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} - break; - case 176: /* expr ::= expr likeop expr */ -{ - ExprList *pList; - int bNot = yymsp[-1].minor.yy0.n & 0x80000000; - yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr); - yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0); - exprNot(pParse, bNot, &yymsp[-2].minor.yy190); - yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; - if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc; -} - break; - case 177: /* expr ::= expr likeop expr ESCAPE expr */ -{ - ExprList *pList; - int bNot = yymsp[-3].minor.yy0.n & 0x80000000; - yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); - yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0); - exprNot(pParse, bNot, &yymsp[-4].minor.yy190); - yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; - if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc; -} - break; - case 178: /* expr ::= expr ISNULL|NOTNULL */ -{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);} - break; - case 179: /* expr ::= expr NOT NULL */ -{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);} - break; - case 180: /* expr ::= expr IS expr */ -{ - spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL); -} - break; - case 181: /* expr ::= expr IS NOT expr */ -{ - spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL); -} - break; - case 182: /* expr ::= NOT expr */ - case 183: /* expr ::= BITNOT expr */ yytestcase(yyruleno==183); -{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} - break; - case 184: /* expr ::= MINUS expr */ -{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} - break; - case 185: /* expr ::= PLUS expr */ -{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/} - break; - case 186: /* between_op ::= BETWEEN */ - case 189: /* in_op ::= IN */ yytestcase(yyruleno==189); -{yymsp[0].minor.yy194 = 0;} - break; - case 188: /* expr ::= expr between_op expr AND expr */ -{ - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0); - if( yymsp[-4].minor.yy190.pExpr ){ - yymsp[-4].minor.yy190.pExpr->x.pList = pList; - }else{ - sqlite3ExprListDelete(pParse->db, pList); - } - exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); - yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; -} - break; - case 191: /* expr ::= expr in_op LP exprlist RP */ -{ - if( yymsp[-1].minor.yy148==0 ){ - /* Expressions of the form - ** - ** expr1 IN () - ** expr1 NOT IN () - ** - ** simplify to constants 0 (false) and 1 (true), respectively, - ** regardless of the value of expr1. - */ - sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr); - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy194]); - }else if( yymsp[-1].minor.yy148->nExpr==1 ){ - /* Expressions of the form: - ** - ** expr1 IN (?1) - ** expr1 NOT IN (?2) - ** - ** with exactly one value on the RHS can be simplified to something - ** like this: - ** - ** expr1 == ?1 - ** expr1 <> ?2 - ** - ** But, the RHS of the == or <> is marked with the EP_Generic flag - ** so that it may not contribute to the computation of comparison - ** affinity or the collating sequence to use for comparison. Otherwise, - ** the semantics would be subtly different from IN or NOT IN. - */ - Expr *pRHS = yymsp[-1].minor.yy148->a[0].pExpr; - yymsp[-1].minor.yy148->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148); - /* pRHS cannot be NULL because a malloc error would have been detected - ** before now and control would have never reached this point */ - if( ALWAYS(pRHS) ){ - pRHS->flags &= ~EP_Collate; - pRHS->flags |= EP_Generic; - } - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS, 0); - }else{ - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0); - if( yymsp[-4].minor.yy190.pExpr ){ - yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr); - }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148); - } - exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); - } - yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 192: /* expr ::= LP select RP */ -{ - spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ - yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243); - } - break; - case 193: /* expr ::= expr in_op LP select RP */ -{ - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243); - exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); - yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; - } - break; - case 194: /* expr ::= expr in_op nm dbnm paren_exprlist */ -{ - SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); - Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148); - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect); - exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190); - yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n]; - } - break; - case 195: /* expr ::= EXISTS LP select RP */ -{ - Expr *p; - spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ - p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243); - } - break; - case 196: /* expr ::= CASE case_operand case_exprlist case_else END */ -{ - spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/ - yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0, 0); - if( yymsp[-4].minor.yy190.pExpr ){ - yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr); - }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72); - } -} - break; - case 197: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ -{ - yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr); - yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); -} - break; - case 198: /* case_exprlist ::= WHEN expr THEN expr */ -{ - yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); - yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr); -} - break; - case 201: /* case_operand ::= expr */ -{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/} - break; - case 204: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);} - break; - case 205: /* nexprlist ::= expr */ -{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/} - break; - case 207: /* paren_exprlist ::= LP exprlist RP */ - case 212: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==212); -{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;} - break; - case 208: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ -{ - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF); -} - break; - case 209: /* uniqueflag ::= UNIQUE */ - case 250: /* raisetype ::= ABORT */ yytestcase(yyruleno==250); -{yymsp[0].minor.yy194 = OE_Abort;} - break; - case 210: /* uniqueflag ::= */ -{yymsp[1].minor.yy194 = OE_None;} - break; - case 213: /* eidlist ::= eidlist COMMA nm collate sortorder */ -{ - yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); -} - break; - case 214: /* eidlist ::= nm collate sortorder */ -{ - yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/ -} - break; - case 217: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);} - break; - case 218: /* cmd ::= VACUUM */ -{sqlite3Vacuum(pParse,0);} - break; - case 219: /* cmd ::= VACUUM nm */ -{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);} - break; - case 220: /* cmd ::= PRAGMA nm dbnm */ -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} - break; - case 221: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} - break; - case 222: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} - break; - case 223: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} - break; - case 224: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} - break; - case 227: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ -{ - Token all; - all.z = yymsp[-3].minor.yy0.z; - all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all); -} - break; - case 228: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ -{ - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194); - yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ -} - break; - case 229: /* trigger_time ::= BEFORE */ -{ yymsp[0].minor.yy194 = TK_BEFORE; } - break; - case 230: /* trigger_time ::= AFTER */ -{ yymsp[0].minor.yy194 = TK_AFTER; } - break; - case 231: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy194 = TK_INSTEAD;} - break; - case 232: /* trigger_time ::= */ -{ yymsp[1].minor.yy194 = TK_BEFORE; } - break; - case 233: /* trigger_event ::= DELETE|INSERT */ - case 234: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==234); -{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;} - break; - case 235: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;} - break; - case 236: /* when_clause ::= */ - case 255: /* key_opt ::= */ yytestcase(yyruleno==255); -{ yymsp[1].minor.yy72 = 0; } - break; - case 237: /* when_clause ::= WHEN expr */ - case 256: /* key_opt ::= KEY expr */ yytestcase(yyruleno==256); -{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; } - break; - case 238: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -{ - assert( yymsp[-2].minor.yy145!=0 ); - yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145; - yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145; -} - break; - case 239: /* trigger_cmd_list ::= trigger_cmd SEMI */ -{ - assert( yymsp[-1].minor.yy145!=0 ); - yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145; -} - break; - case 240: /* trnm ::= nm DOT nm */ -{ - yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; - sqlite3ErrorMsg(pParse, - "qualified table names are not allowed on INSERT, UPDATE, and DELETE " - "statements within triggers"); -} - break; - case 241: /* tridxby ::= INDEXED BY nm */ -{ - sqlite3ErrorMsg(pParse, - "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " - "within triggers"); -} - break; - case 242: /* tridxby ::= NOT INDEXED */ -{ - sqlite3ErrorMsg(pParse, - "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " - "within triggers"); -} - break; - case 243: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ -{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);} - break; - case 244: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */ -{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/} - break; - case 245: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ -{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);} - break; - case 246: /* trigger_cmd ::= select */ -{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/} - break; - case 247: /* expr ::= RAISE LP IGNORE RP */ -{ - spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ - yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); - if( yymsp[-3].minor.yy190.pExpr ){ - yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore; - } -} - break; - case 248: /* expr ::= RAISE LP raisetype COMMA nm RP */ -{ - spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/ - yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); - if( yymsp[-5].minor.yy190.pExpr ) { - yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194; - } -} - break; - case 249: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy194 = OE_Rollback;} - break; - case 251: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy194 = OE_Fail;} - break; - case 252: /* cmd ::= DROP TRIGGER ifexists fullname */ -{ - sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194); -} - break; - case 253: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ -{ - sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72); -} - break; - case 254: /* cmd ::= DETACH database_kw_opt expr */ -{ - sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr); -} - break; - case 257: /* cmd ::= REINDEX */ -{sqlite3Reindex(pParse, 0, 0);} - break; - case 258: /* cmd ::= REINDEX nm dbnm */ -{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} - break; - case 259: /* cmd ::= ANALYZE */ -{sqlite3Analyze(pParse, 0, 0);} - break; - case 260: /* cmd ::= ANALYZE nm dbnm */ -{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} - break; - case 261: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ -{ - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0); -} - break; - case 262: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ -{ - yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; - sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); -} - break; - case 263: /* add_column_fullname ::= fullname */ -{ - disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185); -} - break; - case 264: /* cmd ::= create_vtab */ -{sqlite3VtabFinishParse(pParse,0);} - break; - case 265: /* cmd ::= create_vtab LP vtabarglist RP */ -{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} - break; - case 266: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ -{ - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194); -} - break; - case 267: /* vtabarg ::= */ -{sqlite3VtabArgInit(pParse);} - break; - case 268: /* vtabargtoken ::= ANY */ - case 269: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==269); - case 270: /* lp ::= LP */ yytestcase(yyruleno==270); -{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} - break; - case 271: /* with ::= */ -{yymsp[1].minor.yy285 = 0;} - break; - case 272: /* with ::= WITH wqlist */ -{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; } - break; - case 273: /* with ::= WITH RECURSIVE wqlist */ -{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; } - break; - case 274: /* wqlist ::= nm eidlist_opt AS LP select RP */ -{ - yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/ -} - break; - case 275: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ -{ - yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); -} - break; - default: - /* (276) input ::= cmdlist */ yytestcase(yyruleno==276); - /* (277) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==277); - /* (278) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=278); - /* (279) ecmd ::= SEMI */ yytestcase(yyruleno==279); - /* (280) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==280); - /* (281) explain ::= */ yytestcase(yyruleno==281); - /* (282) trans_opt ::= */ yytestcase(yyruleno==282); - /* (283) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==283); - /* (284) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==284); - /* (285) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==285); - /* (286) savepoint_opt ::= */ yytestcase(yyruleno==286); - /* (287) cmd ::= create_table create_table_args */ yytestcase(yyruleno==287); - /* (288) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==288); - /* (289) columnlist ::= columnname carglist */ yytestcase(yyruleno==289); - /* (290) nm ::= ID|INDEXED */ yytestcase(yyruleno==290); - /* (291) nm ::= STRING */ yytestcase(yyruleno==291); - /* (292) nm ::= JOIN_KW */ yytestcase(yyruleno==292); - /* (293) typetoken ::= typename */ yytestcase(yyruleno==293); - /* (294) typename ::= ID|STRING */ yytestcase(yyruleno==294); - /* (295) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=295); - /* (296) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=296); - /* (297) carglist ::= carglist ccons */ yytestcase(yyruleno==297); - /* (298) carglist ::= */ yytestcase(yyruleno==298); - /* (299) ccons ::= NULL onconf */ yytestcase(yyruleno==299); - /* (300) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==300); - /* (301) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==301); - /* (302) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=302); - /* (303) tconscomma ::= */ yytestcase(yyruleno==303); - /* (304) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=304); - /* (305) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=305); - /* (306) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=306); - /* (307) oneselect ::= values */ yytestcase(yyruleno==307); - /* (308) sclp ::= selcollist COMMA */ yytestcase(yyruleno==308); - /* (309) as ::= ID|STRING */ yytestcase(yyruleno==309); - /* (310) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=310); - /* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311); - /* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312); - /* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313); - /* (314) nmnum ::= ON */ yytestcase(yyruleno==314); - /* (315) nmnum ::= DELETE */ yytestcase(yyruleno==315); - /* (316) nmnum ::= DEFAULT */ yytestcase(yyruleno==316); - /* (317) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==317); - /* (318) foreach_clause ::= */ yytestcase(yyruleno==318); - /* (319) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==319); - /* (320) trnm ::= nm */ yytestcase(yyruleno==320); - /* (321) tridxby ::= */ yytestcase(yyruleno==321); - /* (322) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==322); - /* (323) database_kw_opt ::= */ yytestcase(yyruleno==323); - /* (324) kwcolumn_opt ::= */ yytestcase(yyruleno==324); - /* (325) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==325); - /* (326) vtabarglist ::= vtabarg */ yytestcase(yyruleno==326); - /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==327); - /* (328) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==328); - /* (329) anylist ::= */ yytestcase(yyruleno==329); - /* (330) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==330); - /* (331) anylist ::= anylist ANY */ yytestcase(yyruleno==331); - break; -/********** End reduce actions ************************************************/ - }; - assert( yyrulenoYY_MAX_SHIFT ){ - yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - } - yymsp -= yysize-1; - yypParser->yytos = yymsp; - yymsp->stateno = (YYACTIONTYPE)yyact; - yymsp->major = (YYCODETYPE)yygoto; - yyTraceShift(yypParser, yyact); - }else{ - assert( yyact == YY_ACCEPT_ACTION ); - yypParser->yytos -= yysize; - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -#ifndef YYNOERRORRECOVERY -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - sqlite3ParserARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ -/************ Begin %parse_failure code ***************************************/ -/************ End %parse_failure code *****************************************/ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} -#endif /* YYNOERRORRECOVERY */ - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ -){ - sqlite3ParserARG_FETCH; -#define TOKEN yyminor -/************ Begin %syntax_error code ****************************************/ - - UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ - assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */ - sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); -/************ End %syntax_error code ******************************************/ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - sqlite3ParserARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - assert( yypParser->yytos==yypParser->yystack ); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ -/*********** Begin %parse_accept code *****************************************/ -/*********** End %parse_accept code *******************************************/ - sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "sqlite3ParserAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
      -**
    • A pointer to the parser (an opaque structure.) -**
    • The major token number. -**
    • The minor token number. -**
    • An option argument of a grammar-specified type. -**
    -** -** Outputs: -** None. -*/ -SQLITE_PRIVATE void sqlite3Parser( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - sqlite3ParserTOKENTYPE yyminor /* The value for the token */ - sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - unsigned int yyact; /* The parser action. */ -#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) - int yyendofinput; /* True if we are at the end of input */ -#endif -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - yypParser = (yyParser*)yyp; - assert( yypParser->yytos!=0 ); -#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) - yyendofinput = (yymajor==0); -#endif - sqlite3ParserARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); - if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,yymajor,yyminor); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt--; -#endif - yymajor = YYNOCODE; - }else if( yyact <= YY_MAX_REDUCE ){ - yy_reduce(yypParser,yyact-YY_MIN_REDUCE); - }else{ - assert( yyact == YY_ERROR_ACTION ); - yyminorunion.yy0 = yyminor; -#ifdef YYERRORSYMBOL - int yymx; -#endif -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminor); - } - yymx = yypParser->yytos->major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); - yymajor = YYNOCODE; - }else{ - while( yypParser->yytos >= yypParser->yystack - && yymx != YYERRORSYMBOL - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) >= YY_MIN_REDUCE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yy_parse_failed(yypParser); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#elif defined(YYNOERRORRECOVERY) - /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to - ** do any kind of error recovery. Instead, simply invoke the syntax - ** error routine and continue going as if nothing had happened. - ** - ** Applications can set this macro (for example inside %include) if - ** they intend to abandon the parse upon the first syntax error seen. - */ - yy_syntax_error(yypParser,yymajor, yyminor); - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - yymajor = YYNOCODE; - -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor, yyminor); - } - yypParser->yyerrcnt = 3; - yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yyStackEntry *i; - char cDiv = '['; - fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); - for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ - fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); - cDiv = ' '; - } - fprintf(yyTraceFILE,"]\n"); - } -#endif - return; -} - -/************** End of parse.c ***********************************************/ -/************** Begin file tokenize.c ****************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** An tokenizer for SQL -** -** This file contains C code that splits an SQL input string up into -** individual tokens and sends those tokens one-by-one over to the -** parser for analysis. -*/ -/* #include "sqliteInt.h" */ -/* #include */ - -/* Character classes for tokenizing -** -** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented -** using a lookup table, whereas a switch() directly on c uses a binary search. -** The lookup table is much faster. To maximize speed, and to ensure that -** a lookup table is used, all of the classes need to be small integers and -** all of them need to be used within the switch. -*/ -#define CC_X 0 /* The letter 'x', or start of BLOB literal */ -#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ -#define CC_ID 2 /* unicode characters usable in IDs */ -#define CC_DIGIT 3 /* Digits */ -#define CC_DOLLAR 4 /* '$' */ -#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ -#define CC_VARNUM 6 /* '?'. Numeric SQL variables */ -#define CC_SPACE 7 /* Space characters */ -#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ -#define CC_QUOTE2 9 /* '['. [...] style quoted ids */ -#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ -#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ -#define CC_LT 12 /* '<'. Part of < or <= or <> */ -#define CC_GT 13 /* '>'. Part of > or >= */ -#define CC_EQ 14 /* '='. Part of = or == */ -#define CC_BANG 15 /* '!'. Part of != */ -#define CC_SLASH 16 /* '/'. / or c-style comment */ -#define CC_LP 17 /* '(' */ -#define CC_RP 18 /* ')' */ -#define CC_SEMI 19 /* ';' */ -#define CC_PLUS 20 /* '+' */ -#define CC_STAR 21 /* '*' */ -#define CC_PERCENT 22 /* '%' */ -#define CC_COMMA 23 /* ',' */ -#define CC_AND 24 /* '&' */ -#define CC_TILDA 25 /* '~' */ -#define CC_DOT 26 /* '.' */ -#define CC_ILLEGAL 27 /* Illegal character */ - -static const unsigned char aiClass[] = { -#ifdef SQLITE_ASCII -/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, -/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, -/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, -/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, -/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 -#endif -#ifdef SQLITE_EBCDIC -/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10, -/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7, -/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, -/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, -/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, -#endif -}; - -/* -** The charMap() macro maps alphabetic characters (only) into their -** lower-case ASCII equivalent. On ASCII machines, this is just -** an upper-to-lower case map. On EBCDIC machines we also need -** to adjust the encoding. The mapping is only valid for alphabetics -** which are the only characters for which this feature is used. -** -** Used by keywordhash.h -*/ -#ifdef SQLITE_ASCII -# define charMap(X) sqlite3UpperToLower[(unsigned char)X] -#endif -#ifdef SQLITE_EBCDIC -# define charMap(X) ebcdicToAscii[(unsigned char)X] -const unsigned char ebcdicToAscii[] = { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */ - 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */ - 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */ - 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ - 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */ - 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */ - 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */ -}; -#endif - -/* -** The sqlite3KeywordCode function looks up an identifier to determine if -** it is a keyword. If it is a keyword, the token code of that keyword is -** returned. If the input is not a keyword, TK_ID is returned. -** -** The implementation of this routine was generated by a program, -** mkkeywordhash.c, located in the tool subdirectory of the distribution. -** The output of the mkkeywordhash.c program is written into a file -** named keywordhash.h and then included into this source file by -** the #include below. -*/ -/************** Include keywordhash.h in the middle of tokenize.c ************/ -/************** Begin file keywordhash.h *************************************/ -/***** This file contains automatically generated code ****** -** -** The code in this file has been automatically generated by -** -** sqlite/tool/mkkeywordhash.c -** -** The code in this file implements a function that determines whether -** or not a given identifier is really an SQL keyword. The same thing -** might be implemented more directly using a hand-written hash table. -** But by using this automatically generated code, the size of the code -** is substantially reduced. This is important for embedded applications -** on platforms with limited memory. -*/ -/* Hash score: 182 */ -static int keywordCode(const char *z, int n, int *pType){ - /* zText[] encodes 834 bytes of keywords in 554 bytes */ - /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ - /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ - /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ - /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */ - /* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */ - /* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */ - /* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */ - /* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */ - /* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */ - /* VACUUMVIEWINITIALLY */ - static const char zText[553] = { - 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', - 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', - 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', - 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F', - 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N', - 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I', - 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E', - 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E', - 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T', - 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q', - 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S', - 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A', - 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E', - 'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A', - 'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A', - 'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A', - 'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J', - 'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L', - 'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E', - 'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H', - 'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E', - 'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E', - 'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M', - 'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R', - 'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A', - 'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D', - 'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O', - 'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T', - 'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R', - 'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M', - 'V','I','E','W','I','N','I','T','I','A','L','L','Y', - }; - static const unsigned char aHash[127] = { - 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0, - 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0, - 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71, - 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44, - 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25, - 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0, - 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14, - 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113, - 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0, - 29, 0, 86, 63, 64, 0, 20, 61, 0, 56, - }; - static const unsigned char aNext[124] = { - 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, - 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50, - 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38, - 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0, - 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34, - 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8, - 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37, - 73, 83, 0, 35, 68, 0, 0, - }; - static const unsigned char aLen[124] = { - 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, - 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, - 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, - 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7, - 6, 6, 5, 6, 5, 5, 9, 7, 7, 3, 2, 4, 4, - 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4, - 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7, - 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, - 2, 4, 4, 4, 4, 4, 2, 2, 6, 5, 8, 5, 8, - 3, 5, 5, 6, 4, 9, 3, - }; - static const unsigned short int aOffset[124] = { - 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, - 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, - 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, - 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192, - 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246, - 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318, - 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380, - 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459, - 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513, - 521, 524, 529, 534, 540, 544, 549, - }; - static const unsigned char aCode[124] = { - TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, - TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, - TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, - TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, - TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, - TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, - TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, - TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, - TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, - TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH, - TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, - TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN, - TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, - TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, - TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, - TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, - TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, - TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND, - TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, - TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, - TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, - TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, - TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, - TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, - TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, - }; - int i, j; - const char *zKW; - if( n>=2 ){ - i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127; - for(i=((int)aHash[i])-1; i>=0; i=((int)aNext[i])-1){ - if( aLen[i]!=n ) continue; - j = 0; - zKW = &zText[aOffset[i]]; -#ifdef SQLITE_ASCII - while( j=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) -#endif - -/* Make the IdChar function accessible from ctime.c */ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } -#endif - - -/* -** Return the length (in bytes) of the token that begins at z[0]. -** Store the token type in *tokenType before returning. -*/ -SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ - int i, c; - switch( aiClass[*z] ){ /* Switch on the character-class of the first byte - ** of the token. See the comment on the CC_ defines - ** above. */ - case CC_SPACE: { - testcase( z[0]==' ' ); - testcase( z[0]=='\t' ); - testcase( z[0]=='\n' ); - testcase( z[0]=='\f' ); - testcase( z[0]=='\r' ); - for(i=1; sqlite3Isspace(z[i]); i++){} - *tokenType = TK_SPACE; - return i; - } - case CC_MINUS: { - if( z[1]=='-' ){ - for(i=2; (c=z[i])!=0 && c!='\n'; i++){} - *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ - return i; - } - *tokenType = TK_MINUS; - return 1; - } - case CC_LP: { - *tokenType = TK_LP; - return 1; - } - case CC_RP: { - *tokenType = TK_RP; - return 1; - } - case CC_SEMI: { - *tokenType = TK_SEMI; - return 1; - } - case CC_PLUS: { - *tokenType = TK_PLUS; - return 1; - } - case CC_STAR: { - *tokenType = TK_STAR; - return 1; - } - case CC_SLASH: { - if( z[1]!='*' || z[2]==0 ){ - *tokenType = TK_SLASH; - return 1; - } - for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} - if( c ) i++; - *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ - return i; - } - case CC_PERCENT: { - *tokenType = TK_REM; - return 1; - } - case CC_EQ: { - *tokenType = TK_EQ; - return 1 + (z[1]=='='); - } - case CC_LT: { - if( (c=z[1])=='=' ){ - *tokenType = TK_LE; - return 2; - }else if( c=='>' ){ - *tokenType = TK_NE; - return 2; - }else if( c=='<' ){ - *tokenType = TK_LSHIFT; - return 2; - }else{ - *tokenType = TK_LT; - return 1; - } - } - case CC_GT: { - if( (c=z[1])=='=' ){ - *tokenType = TK_GE; - return 2; - }else if( c=='>' ){ - *tokenType = TK_RSHIFT; - return 2; - }else{ - *tokenType = TK_GT; - return 1; - } - } - case CC_BANG: { - if( z[1]!='=' ){ - *tokenType = TK_ILLEGAL; - return 1; - }else{ - *tokenType = TK_NE; - return 2; - } - } - case CC_PIPE: { - if( z[1]!='|' ){ - *tokenType = TK_BITOR; - return 1; - }else{ - *tokenType = TK_CONCAT; - return 2; - } - } - case CC_COMMA: { - *tokenType = TK_COMMA; - return 1; - } - case CC_AND: { - *tokenType = TK_BITAND; - return 1; - } - case CC_TILDA: { - *tokenType = TK_BITNOT; - return 1; - } - case CC_QUOTE: { - int delim = z[0]; - testcase( delim=='`' ); - testcase( delim=='\'' ); - testcase( delim=='"' ); - for(i=1; (c=z[i])!=0; i++){ - if( c==delim ){ - if( z[i+1]==delim ){ - i++; - }else{ - break; - } - } - } - if( c=='\'' ){ - *tokenType = TK_STRING; - return i+1; - }else if( c!=0 ){ - *tokenType = TK_ID; - return i+1; - }else{ - *tokenType = TK_ILLEGAL; - return i; - } - } - case CC_DOT: { -#ifndef SQLITE_OMIT_FLOATING_POINT - if( !sqlite3Isdigit(z[1]) ) -#endif - { - *tokenType = TK_DOT; - return 1; - } - /* If the next character is a digit, this is a floating point - ** number that begins with ".". Fall thru into the next case */ - } - case CC_DIGIT: { - testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); - testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); - testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); - testcase( z[0]=='9' ); - *tokenType = TK_INTEGER; -#ifndef SQLITE_OMIT_HEX_INTEGER - if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ - for(i=3; sqlite3Isxdigit(z[i]); i++){} - return i; - } -#endif - for(i=0; sqlite3Isdigit(z[i]); i++){} -#ifndef SQLITE_OMIT_FLOATING_POINT - if( z[i]=='.' ){ - i++; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } - if( (z[i]=='e' || z[i]=='E') && - ( sqlite3Isdigit(z[i+1]) - || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) - ) - ){ - i += 2; - while( sqlite3Isdigit(z[i]) ){ i++; } - *tokenType = TK_FLOAT; - } -#endif - while( IdChar(z[i]) ){ - *tokenType = TK_ILLEGAL; - i++; - } - return i; - } - case CC_QUOTE2: { - for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} - *tokenType = c==']' ? TK_ID : TK_ILLEGAL; - return i; - } - case CC_VARNUM: { - *tokenType = TK_VARIABLE; - for(i=1; sqlite3Isdigit(z[i]); i++){} - return i; - } - case CC_DOLLAR: - case CC_VARALPHA: { - int n = 0; - testcase( z[0]=='$' ); testcase( z[0]=='@' ); - testcase( z[0]==':' ); testcase( z[0]=='#' ); - *tokenType = TK_VARIABLE; - for(i=1; (c=z[i])!=0; i++){ - if( IdChar(c) ){ - n++; -#ifndef SQLITE_OMIT_TCL_VARIABLE - }else if( c=='(' && n>0 ){ - do{ - i++; - }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' ); - if( c==')' ){ - i++; - }else{ - *tokenType = TK_ILLEGAL; - } - break; - }else if( c==':' && z[i+1]==':' ){ - i++; -#endif - }else{ - break; - } - } - if( n==0 ) *tokenType = TK_ILLEGAL; - return i; - } - case CC_KYWD: { - for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} - if( IdChar(z[i]) ){ - /* This token started out using characters that can appear in keywords, - ** but z[i] is a character not allowed within keywords, so this must - ** be an identifier instead */ - i++; - break; - } - *tokenType = TK_ID; - return keywordCode((char*)z, i, tokenType); - } - case CC_X: { -#ifndef SQLITE_OMIT_BLOB_LITERAL - testcase( z[0]=='x' ); testcase( z[0]=='X' ); - if( z[1]=='\'' ){ - *tokenType = TK_BLOB; - for(i=2; sqlite3Isxdigit(z[i]); i++){} - if( z[i]!='\'' || i%2 ){ - *tokenType = TK_ILLEGAL; - while( z[i] && z[i]!='\'' ){ i++; } - } - if( z[i] ) i++; - return i; - } -#endif - /* If it is not a BLOB literal, then it must be an ID, since no - ** SQL keywords start with the letter 'x'. Fall through */ - } - case CC_ID: { - i = 1; - break; - } - default: { - *tokenType = TK_ILLEGAL; - return 1; - } - } - while( IdChar(z[i]) ){ i++; } - *tokenType = TK_ID; - return i; -} - -/* -** Run the parser on the given SQL string. The parser structure is -** passed in. An SQLITE_ status code is returned. If an error occurs -** then an and attempt is made to write an error message into -** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that -** error message. -*/ -SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ - int nErr = 0; /* Number of errors encountered */ - int i; /* Loop counter */ - void *pEngine; /* The LEMON-generated LALR(1) parser */ - int tokenType; /* type of the next token */ - int lastTokenParsed = -1; /* type of the previous token */ - sqlite3 *db = pParse->db; /* The database connection */ - int mxSqlLen; /* Max length of an SQL string */ - - assert( zSql!=0 ); - mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; - if( db->nVdbeActive==0 ){ - db->u1.isInterrupted = 0; - } - pParse->rc = SQLITE_OK; - pParse->zTail = zSql; - i = 0; - assert( pzErrMsg!=0 ); - /* sqlite3ParserTrace(stdout, "parser: "); */ - pEngine = sqlite3ParserAlloc(sqlite3Malloc); - if( pEngine==0 ){ - sqlite3OomFault(db); - return SQLITE_NOMEM_BKPT; - } - assert( pParse->pNewTable==0 ); - assert( pParse->pNewTrigger==0 ); - assert( pParse->nVar==0 ); - assert( pParse->nzVar==0 ); - assert( pParse->azVar==0 ); - while( 1 ){ - assert( i>=0 ); - if( zSql[i]!=0 ){ - pParse->sLastToken.z = &zSql[i]; - pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType); - i += pParse->sLastToken.n; - if( i>mxSqlLen ){ - pParse->rc = SQLITE_TOOBIG; - break; - } - }else{ - /* Upon reaching the end of input, call the parser two more times - ** with tokens TK_SEMI and 0, in that order. */ - if( lastTokenParsed==TK_SEMI ){ - tokenType = 0; - }else if( lastTokenParsed==0 ){ - break; - }else{ - tokenType = TK_SEMI; - } - } - if( tokenType>=TK_SPACE ){ - assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); - if( db->u1.isInterrupted ){ - pParse->rc = SQLITE_INTERRUPT; - break; - } - if( tokenType==TK_ILLEGAL ){ - sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", - &pParse->sLastToken); - break; - } - }else{ - sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse); - lastTokenParsed = tokenType; - if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; - } - } - assert( nErr==0 ); - pParse->zTail = &zSql[i]; -#ifdef YYTRACKMAXSTACKDEPTH - sqlite3_mutex_enter(sqlite3MallocMutex()); - sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, - sqlite3ParserStackPeak(pEngine) - ); - sqlite3_mutex_leave(sqlite3MallocMutex()); -#endif /* YYDEBUG */ - sqlite3ParserFree(pEngine, sqlite3_free); - if( db->mallocFailed ){ - pParse->rc = SQLITE_NOMEM_BKPT; - } - if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ - pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); - } - assert( pzErrMsg!=0 ); - if( pParse->zErrMsg ){ - *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s", *pzErrMsg); - pParse->zErrMsg = 0; - nErr++; - } - if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ - sqlite3VdbeDelete(pParse->pVdbe); - pParse->pVdbe = 0; - } -#ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->nested==0 ){ - sqlite3DbFree(db, pParse->aTableLock); - pParse->aTableLock = 0; - pParse->nTableLock = 0; - } -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_free(pParse->apVtabLock); -#endif - - if( !IN_DECLARE_VTAB ){ - /* If the pParse->declareVtab flag is set, do not delete any table - ** structure built up in pParse->pNewTable. The calling code (see vtab.c) - ** will take responsibility for freeing the Table structure. - */ - sqlite3DeleteTable(db, pParse->pNewTable); - } - - if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); - sqlite3DeleteTrigger(db, pParse->pNewTrigger); - for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); - sqlite3DbFree(db, pParse->azVar); - while( pParse->pAinc ){ - AutoincInfo *p = pParse->pAinc; - pParse->pAinc = p->pNext; - sqlite3DbFree(db, p); - } - while( pParse->pZombieTab ){ - Table *p = pParse->pZombieTab; - pParse->pZombieTab = p->pNextZombie; - sqlite3DeleteTable(db, p); - } - assert( nErr==0 || pParse->rc!=SQLITE_OK ); - return nErr; -} - -/************** End of tokenize.c ********************************************/ -/************** Begin file complete.c ****************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** An tokenizer for SQL -** -** This file contains C code that implements the sqlite3_complete() API. -** This code used to be part of the tokenizer.c source file. But by -** separating it out, the code will be automatically omitted from -** static links that do not use it. -*/ -/* #include "sqliteInt.h" */ -#ifndef SQLITE_OMIT_COMPLETE - -/* -** This is defined in tokenize.c. We just have to import the definition. -*/ -#ifndef SQLITE_AMALGAMATION -#ifdef SQLITE_ASCII -#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) -#endif -#ifdef SQLITE_EBCDIC -SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; -#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) -#endif -#endif /* SQLITE_AMALGAMATION */ - - -/* -** Token types used by the sqlite3_complete() routine. See the header -** comments on that procedure for additional information. -*/ -#define tkSEMI 0 -#define tkWS 1 -#define tkOTHER 2 -#ifndef SQLITE_OMIT_TRIGGER -#define tkEXPLAIN 3 -#define tkCREATE 4 -#define tkTEMP 5 -#define tkTRIGGER 6 -#define tkEND 7 -#endif - -/* -** Return TRUE if the given SQL string ends in a semicolon. -** -** Special handling is require for CREATE TRIGGER statements. -** Whenever the CREATE TRIGGER keywords are seen, the statement -** must end with ";END;". -** -** This implementation uses a state machine with 8 states: -** -** (0) INVALID We have not yet seen a non-whitespace character. -** -** (1) START At the beginning or end of an SQL statement. This routine -** returns 1 if it ends in the START state and 0 if it ends -** in any other state. -** -** (2) NORMAL We are in the middle of statement which ends with a single -** semicolon. -** -** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of -** a statement. -** -** (4) CREATE The keyword CREATE has been seen at the beginning of a -** statement, possibly preceded by EXPLAIN and/or followed by -** TEMP or TEMPORARY -** -** (5) TRIGGER We are in the middle of a trigger definition that must be -** ended by a semicolon, the keyword END, and another semicolon. -** -** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at -** the end of a trigger definition. -** -** (7) END We've seen the ";END" of the ";END;" that occurs at the end -** of a trigger definition. -** -** Transitions between states above are determined by tokens extracted -** from the input. The following tokens are significant: -** -** (0) tkSEMI A semicolon. -** (1) tkWS Whitespace. -** (2) tkOTHER Any other SQL token. -** (3) tkEXPLAIN The "explain" keyword. -** (4) tkCREATE The "create" keyword. -** (5) tkTEMP The "temp" or "temporary" keyword. -** (6) tkTRIGGER The "trigger" keyword. -** (7) tkEND The "end" keyword. -** -** Whitespace never causes a state transition and is always ignored. -** This means that a SQL string of all whitespace is invalid. -** -** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed -** to recognize the end of a trigger can be omitted. All we have to do -** is look for a semicolon that is not part of an string or comment. -*/ -SQLITE_API int sqlite3_complete(const char *zSql){ - u8 state = 0; /* Current state, using numbers defined in header comment */ - u8 token; /* Value of the next token */ - -#ifndef SQLITE_OMIT_TRIGGER - /* A complex statement machine used to detect the end of a CREATE TRIGGER - ** statement. This is the normal case. - */ - static const u8 trans[8][8] = { - /* Token: */ - /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ - /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, - /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, - /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, - /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, - /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, }, - /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, }, - /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, }, - /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, }, - }; -#else - /* If triggers are not supported by this compile then the statement machine - ** used to detect the end of a statement is much simpler - */ - static const u8 trans[3][3] = { - /* Token: */ - /* State: ** SEMI WS OTHER */ - /* 0 INVALID: */ { 1, 0, 2, }, - /* 1 START: */ { 1, 1, 2, }, - /* 2 NORMAL: */ { 1, 2, 2, }, - }; -#endif /* SQLITE_OMIT_TRIGGER */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( zSql==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - - while( *zSql ){ - switch( *zSql ){ - case ';': { /* A semicolon */ - token = tkSEMI; - break; - } - case ' ': - case '\r': - case '\t': - case '\n': - case '\f': { /* White space is ignored */ - token = tkWS; - break; - } - case '/': { /* C-style comments */ - if( zSql[1]!='*' ){ - token = tkOTHER; - break; - } - zSql += 2; - while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } - if( zSql[0]==0 ) return 0; - zSql++; - token = tkWS; - break; - } - case '-': { /* SQL-style comments from "--" to end of line */ - if( zSql[1]!='-' ){ - token = tkOTHER; - break; - } - while( *zSql && *zSql!='\n' ){ zSql++; } - if( *zSql==0 ) return state==1; - token = tkWS; - break; - } - case '[': { /* Microsoft-style identifiers in [...] */ - zSql++; - while( *zSql && *zSql!=']' ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - case '`': /* Grave-accent quoted symbols used by MySQL */ - case '"': /* single- and double-quoted strings */ - case '\'': { - int c = *zSql; - zSql++; - while( *zSql && *zSql!=c ){ zSql++; } - if( *zSql==0 ) return 0; - token = tkOTHER; - break; - } - default: { -#ifdef SQLITE_EBCDIC - unsigned char c; -#endif - if( IdChar((u8)*zSql) ){ - /* Keywords and unquoted identifiers */ - int nId; - for(nId=1; IdChar(zSql[nId]); nId++){} -#ifdef SQLITE_OMIT_TRIGGER - token = tkOTHER; -#else - switch( *zSql ){ - case 'c': case 'C': { - if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ - token = tkCREATE; - }else{ - token = tkOTHER; - } - break; - } - case 't': case 'T': { - if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ - token = tkTRIGGER; - }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ - token = tkTEMP; - }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ - token = tkTEMP; - }else{ - token = tkOTHER; - } - break; - } - case 'e': case 'E': { - if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ - token = tkEND; - }else -#ifndef SQLITE_OMIT_EXPLAIN - if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ - token = tkEXPLAIN; - }else -#endif - { - token = tkOTHER; - } - break; - } - default: { - token = tkOTHER; - break; - } - } -#endif /* SQLITE_OMIT_TRIGGER */ - zSql += nId-1; - }else{ - /* Operators and special symbols */ - token = tkOTHER; - } - break; - } - } - state = trans[state][token]; - zSql++; - } - return state==1; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** This routine is the same as the sqlite3_complete() routine described -** above, except that the parameter is required to be UTF-16 encoded, not -** UTF-8. -*/ -SQLITE_API int sqlite3_complete16(const void *zSql){ - sqlite3_value *pVal; - char const *zSql8; - int rc; - -#ifndef SQLITE_OMIT_AUTOINIT - rc = sqlite3_initialize(); - if( rc ) return rc; -#endif - pVal = sqlite3ValueNew(0); - sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); - if( zSql8 ){ - rc = sqlite3_complete(zSql8); - }else{ - rc = SQLITE_NOMEM_BKPT; - } - sqlite3ValueFree(pVal); - return rc & 0xff; -} -#endif /* SQLITE_OMIT_UTF16 */ -#endif /* SQLITE_OMIT_COMPLETE */ - -/************** End of complete.c ********************************************/ -/************** Begin file main.c ********************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Main file for the SQLite library. The routines in this file -** implement the programmer interface to the library. Routines in -** other files are for internal use by SQLite and should not be -** accessed by users of the library. -*/ -/* #include "sqliteInt.h" */ - -#ifdef SQLITE_ENABLE_FTS3 -/************** Include fts3.h in the middle of main.c ***********************/ -/************** Begin file fts3.h ********************************************/ -/* -** 2006 Oct 10 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This header file is used by programs that want to link against the -** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. -*/ -/* #include "sqlite3.h" */ - -#if 0 -extern "C" { -#endif /* __cplusplus */ - -SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); - -#if 0 -} /* extern "C" */ -#endif /* __cplusplus */ - -/************** End of fts3.h ************************************************/ -/************** Continuing where we left off in main.c ***********************/ -#endif -#ifdef SQLITE_ENABLE_RTREE -/************** Include rtree.h in the middle of main.c **********************/ -/************** Begin file rtree.h *******************************************/ -/* -** 2008 May 26 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This header file is used by programs that want to link against the -** RTREE library. All it does is declare the sqlite3RtreeInit() interface. -*/ -/* #include "sqlite3.h" */ - -#if 0 -extern "C" { -#endif /* __cplusplus */ - -SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); - -#if 0 -} /* extern "C" */ -#endif /* __cplusplus */ - -/************** End of rtree.h ***********************************************/ -/************** Continuing where we left off in main.c ***********************/ -#endif -#ifdef SQLITE_ENABLE_ICU -/************** Include sqliteicu.h in the middle of main.c ******************/ -/************** Begin file sqliteicu.h ***************************************/ -/* -** 2008 May 26 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This header file is used by programs that want to link against the -** ICU extension. All it does is declare the sqlite3IcuInit() interface. -*/ -/* #include "sqlite3.h" */ - -#if 0 -extern "C" { -#endif /* __cplusplus */ - -SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); - -#if 0 -} /* extern "C" */ -#endif /* __cplusplus */ - - -/************** End of sqliteicu.h *******************************************/ -/************** Continuing where we left off in main.c ***********************/ -#endif -#ifdef SQLITE_ENABLE_JSON1 -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*); -#endif -#ifdef SQLITE_ENABLE_FTS5 -SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); -#endif - -#ifndef SQLITE_AMALGAMATION -/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant -** contains the text of SQLITE_VERSION macro. -*/ -SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; -#endif - -/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns -** a pointer to the to the sqlite3_version[] string constant. -*/ -SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } - -/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a -** pointer to a string constant whose value is the same as the -** SQLITE_SOURCE_ID C preprocessor macro. -*/ -SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } - -/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function -** returns an integer equal to SQLITE_VERSION_NUMBER. -*/ -SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } - -/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns -** zero if and only if SQLite was compiled with mutexing code omitted due to -** the SQLITE_THREADSAFE compile-time option being set to 0. -*/ -SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } - -/* -** When compiling the test fixture or with debugging enabled (on Win32), -** this variable being set to non-zero will cause OSTRACE macros to emit -** extra diagnostic information. -*/ -#ifdef SQLITE_HAVE_OS_TRACE -# ifndef SQLITE_DEBUG_OS_TRACE -# define SQLITE_DEBUG_OS_TRACE 0 -# endif - int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; -#endif - -#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) -/* -** If the following function pointer is not NULL and if -** SQLITE_ENABLE_IOTRACE is enabled, then messages describing -** I/O active are written using this function. These messages -** are intended for debugging activity only. -*/ -SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; -#endif - -/* -** If the following global variable points to a string which is the -** name of a directory, then that directory will be used to store -** temporary files. -** -** See also the "PRAGMA temp_store_directory" SQL command. -*/ -SQLITE_API char *sqlite3_temp_directory = 0; - -/* -** If the following global variable points to a string which is the -** name of a directory, then that directory will be used to store -** all database files specified with a relative pathname. -** -** See also the "PRAGMA data_store_directory" SQL command. -*/ -SQLITE_API char *sqlite3_data_directory = 0; - -/* -** Initialize SQLite. -** -** This routine must be called to initialize the memory allocation, -** VFS, and mutex subsystems prior to doing any serious work with -** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT -** this routine will be called automatically by key routines such as -** sqlite3_open(). -** -** This routine is a no-op except on its very first call for the process, -** or for the first call after a call to sqlite3_shutdown. -** -** The first thread to call this routine runs the initialization to -** completion. If subsequent threads call this routine before the first -** thread has finished the initialization process, then the subsequent -** threads must block until the first thread finishes with the initialization. -** -** The first thread might call this routine recursively. Recursive -** calls to this routine should not block, of course. Otherwise the -** initialization process would never complete. -** -** Let X be the first thread to enter this routine. Let Y be some other -** thread. Then while the initial invocation of this routine by X is -** incomplete, it is required that: -** -** * Calls to this routine from Y must block until the outer-most -** call by X completes. -** -** * Recursive calls to this routine from thread X return immediately -** without blocking. -*/ -SQLITE_API int sqlite3_initialize(void){ - MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ - int rc; /* Result code */ -#ifdef SQLITE_EXTRA_INIT - int bRunExtraInit = 0; /* Extra initialization needed */ -#endif - -#ifdef SQLITE_OMIT_WSD - rc = sqlite3_wsd_init(4096, 24); - if( rc!=SQLITE_OK ){ - return rc; - } -#endif - - /* If the following assert() fails on some obscure processor/compiler - ** combination, the work-around is to set the correct pointer - ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ - assert( SQLITE_PTRSIZE==sizeof(char*) ); - - /* If SQLite is already completely initialized, then this call - ** to sqlite3_initialize() should be a no-op. But the initialization - ** must be complete. So isInit must not be set until the very end - ** of this routine. - */ - if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; - - /* Make sure the mutex subsystem is initialized. If unable to - ** initialize the mutex subsystem, return early with the error. - ** If the system is so sick that we are unable to allocate a mutex, - ** there is not much SQLite is going to be able to do. - ** - ** The mutex subsystem must take care of serializing its own - ** initialization. - */ - rc = sqlite3MutexInit(); - if( rc ) return rc; - - /* Initialize the malloc() system and the recursive pInitMutex mutex. - ** This operation is protected by the STATIC_MASTER mutex. Note that - ** MutexAlloc() is called for a static mutex prior to initializing the - ** malloc subsystem - this implies that the allocation of a static - ** mutex must not require support from the malloc subsystem. - */ - MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - sqlite3_mutex_enter(pMaster); - sqlite3GlobalConfig.isMutexInit = 1; - if( !sqlite3GlobalConfig.isMallocInit ){ - rc = sqlite3MallocInit(); - } - if( rc==SQLITE_OK ){ - sqlite3GlobalConfig.isMallocInit = 1; - if( !sqlite3GlobalConfig.pInitMutex ){ - sqlite3GlobalConfig.pInitMutex = - sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); - if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ - rc = SQLITE_NOMEM_BKPT; - } - } - } - if( rc==SQLITE_OK ){ - sqlite3GlobalConfig.nRefInitMutex++; - } - sqlite3_mutex_leave(pMaster); - - /* If rc is not SQLITE_OK at this point, then either the malloc - ** subsystem could not be initialized or the system failed to allocate - ** the pInitMutex mutex. Return an error in either case. */ - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Do the rest of the initialization under the recursive mutex so - ** that we will be able to handle recursive calls into - ** sqlite3_initialize(). The recursive calls normally come through - ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other - ** recursive calls might also be possible. - ** - ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls - ** to the xInit method, so the xInit method need not be threadsafe. - ** - ** The following mutex is what serializes access to the appdef pcache xInit - ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the - ** call to sqlite3PcacheInitialize(). - */ - sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); - if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ - sqlite3GlobalConfig.inProgress = 1; -#ifdef SQLITE_ENABLE_SQLLOG - { - extern void sqlite3_init_sqllog(void); - sqlite3_init_sqllog(); - } -#endif - memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions)); - sqlite3RegisterBuiltinFunctions(); - if( sqlite3GlobalConfig.isPCacheInit==0 ){ - rc = sqlite3PcacheInitialize(); - } - if( rc==SQLITE_OK ){ - sqlite3GlobalConfig.isPCacheInit = 1; - rc = sqlite3OsInit(); - } - if( rc==SQLITE_OK ){ - sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, - sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); - sqlite3GlobalConfig.isInit = 1; -#ifdef SQLITE_EXTRA_INIT - bRunExtraInit = 1; -#endif - } - sqlite3GlobalConfig.inProgress = 0; - } - sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); - - /* Go back under the static mutex and clean up the recursive - ** mutex to prevent a resource leak. - */ - sqlite3_mutex_enter(pMaster); - sqlite3GlobalConfig.nRefInitMutex--; - if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ - assert( sqlite3GlobalConfig.nRefInitMutex==0 ); - sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); - sqlite3GlobalConfig.pInitMutex = 0; - } - sqlite3_mutex_leave(pMaster); - - /* The following is just a sanity check to make sure SQLite has - ** been compiled correctly. It is important to run this code, but - ** we don't want to run it too often and soak up CPU cycles for no - ** reason. So we run it once during initialization. - */ -#ifndef NDEBUG -#ifndef SQLITE_OMIT_FLOATING_POINT - /* This section of code's only "output" is via assert() statements. */ - if ( rc==SQLITE_OK ){ - u64 x = (((u64)1)<<63)-1; - double y; - assert(sizeof(x)==8); - assert(sizeof(x)==sizeof(y)); - memcpy(&y, &x, 8); - assert( sqlite3IsNaN(y) ); - } -#endif -#endif - - /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT - ** compile-time option. - */ -#ifdef SQLITE_EXTRA_INIT - if( bRunExtraInit ){ - int SQLITE_EXTRA_INIT(const char*); - rc = SQLITE_EXTRA_INIT(0); - } -#endif - - return rc; -} - -/* -** Undo the effects of sqlite3_initialize(). Must not be called while -** there are outstanding database connections or memory allocations or -** while any part of SQLite is otherwise in use in any thread. This -** routine is not threadsafe. But it is safe to invoke this routine -** on when SQLite is already shut down. If SQLite is already shut down -** when this routine is invoked, then this routine is a harmless no-op. -*/ -SQLITE_API int sqlite3_shutdown(void){ -#ifdef SQLITE_OMIT_WSD - int rc = sqlite3_wsd_init(4096, 24); - if( rc!=SQLITE_OK ){ - return rc; - } -#endif - - if( sqlite3GlobalConfig.isInit ){ -#ifdef SQLITE_EXTRA_SHUTDOWN - void SQLITE_EXTRA_SHUTDOWN(void); - SQLITE_EXTRA_SHUTDOWN(); -#endif - sqlite3_os_end(); - sqlite3_reset_auto_extension(); - sqlite3GlobalConfig.isInit = 0; - } - if( sqlite3GlobalConfig.isPCacheInit ){ - sqlite3PcacheShutdown(); - sqlite3GlobalConfig.isPCacheInit = 0; - } - if( sqlite3GlobalConfig.isMallocInit ){ - sqlite3MallocEnd(); - sqlite3GlobalConfig.isMallocInit = 0; - -#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES - /* The heap subsystem has now been shutdown and these values are supposed - ** to be NULL or point to memory that was obtained from sqlite3_malloc(), - ** which would rely on that heap subsystem; therefore, make sure these - ** values cannot refer to heap memory that was just invalidated when the - ** heap subsystem was shutdown. This is only done if the current call to - ** this function resulted in the heap subsystem actually being shutdown. - */ - sqlite3_data_directory = 0; - sqlite3_temp_directory = 0; -#endif - } - if( sqlite3GlobalConfig.isMutexInit ){ - sqlite3MutexEnd(); - sqlite3GlobalConfig.isMutexInit = 0; - } - - return SQLITE_OK; -} - -/* -** This API allows applications to modify the global configuration of -** the SQLite library at run-time. -** -** This routine should only be called when there are no outstanding -** database connections or memory allocations. This routine is not -** threadsafe. Failure to heed these warnings can lead to unpredictable -** behavior. -*/ -SQLITE_API int sqlite3_config(int op, ...){ - va_list ap; - int rc = SQLITE_OK; - - /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while - ** the SQLite library is in use. */ - if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; - - va_start(ap, op); - switch( op ){ - - /* Mutex configuration options are only available in a threadsafe - ** compile. - */ -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ - case SQLITE_CONFIG_SINGLETHREAD: { - /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to - ** Single-thread. */ - sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ - sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ - break; - } -#endif -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ - case SQLITE_CONFIG_MULTITHREAD: { - /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to - ** Multi-thread. */ - sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ - sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ - break; - } -#endif -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ - case SQLITE_CONFIG_SERIALIZED: { - /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to - ** Serialized. */ - sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ - sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ - break; - } -#endif -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */ - case SQLITE_CONFIG_MUTEX: { - /* Specify an alternative mutex implementation */ - sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); - break; - } -#endif -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */ - case SQLITE_CONFIG_GETMUTEX: { - /* Retrieve the current mutex implementation */ - *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; - break; - } -#endif - - case SQLITE_CONFIG_MALLOC: { - /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a - ** single argument which is a pointer to an instance of the - ** sqlite3_mem_methods structure. The argument specifies alternative - ** low-level memory allocation routines to be used in place of the memory - ** allocation routines built into SQLite. */ - sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); - break; - } - case SQLITE_CONFIG_GETMALLOC: { - /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a - ** single argument which is a pointer to an instance of the - ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is - ** filled with the currently defined memory allocation routines. */ - if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); - *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; - break; - } - case SQLITE_CONFIG_MEMSTATUS: { - /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes - ** single argument of type int, interpreted as a boolean, which enables - ** or disables the collection of memory allocation statistics. */ - sqlite3GlobalConfig.bMemstat = va_arg(ap, int); - break; - } - case SQLITE_CONFIG_SCRATCH: { - /* EVIDENCE-OF: R-08404-60887 There are three arguments to - ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from - ** which the scratch allocations will be drawn, the size of each scratch - ** allocation (sz), and the maximum number of scratch allocations (N). */ - sqlite3GlobalConfig.pScratch = va_arg(ap, void*); - sqlite3GlobalConfig.szScratch = va_arg(ap, int); - sqlite3GlobalConfig.nScratch = va_arg(ap, int); - break; - } - case SQLITE_CONFIG_PAGECACHE: { - /* EVIDENCE-OF: R-18761-36601 There are three arguments to - ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem), - ** the size of each page cache line (sz), and the number of cache lines - ** (N). */ - sqlite3GlobalConfig.pPage = va_arg(ap, void*); - sqlite3GlobalConfig.szPage = va_arg(ap, int); - sqlite3GlobalConfig.nPage = va_arg(ap, int); - break; - } - case SQLITE_CONFIG_PCACHE_HDRSZ: { - /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes - ** a single parameter which is a pointer to an integer and writes into - ** that integer the number of extra bytes per page required for each page - ** in SQLITE_CONFIG_PAGECACHE. */ - *va_arg(ap, int*) = - sqlite3HeaderSizeBtree() + - sqlite3HeaderSizePcache() + - sqlite3HeaderSizePcache1(); - break; - } - - case SQLITE_CONFIG_PCACHE: { - /* no-op */ - break; - } - case SQLITE_CONFIG_GETPCACHE: { - /* now an error */ - rc = SQLITE_ERROR; - break; - } - - case SQLITE_CONFIG_PCACHE2: { - /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a - ** single argument which is a pointer to an sqlite3_pcache_methods2 - ** object. This object specifies the interface to a custom page cache - ** implementation. */ - sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); - break; - } - case SQLITE_CONFIG_GETPCACHE2: { - /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a - ** single argument which is a pointer to an sqlite3_pcache_methods2 - ** object. SQLite copies of the current page cache implementation into - ** that object. */ - if( sqlite3GlobalConfig.pcache2.xInit==0 ){ - sqlite3PCacheSetDefault(); - } - *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; - break; - } - -/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only -** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or -** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */ -#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) - case SQLITE_CONFIG_HEAP: { - /* EVIDENCE-OF: R-19854-42126 There are three arguments to - ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the - ** number of bytes in the memory buffer, and the minimum allocation size. - */ - sqlite3GlobalConfig.pHeap = va_arg(ap, void*); - sqlite3GlobalConfig.nHeap = va_arg(ap, int); - sqlite3GlobalConfig.mnReq = va_arg(ap, int); - - if( sqlite3GlobalConfig.mnReq<1 ){ - sqlite3GlobalConfig.mnReq = 1; - }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ - /* cap min request size at 2^12 */ - sqlite3GlobalConfig.mnReq = (1<<12); - } - - if( sqlite3GlobalConfig.pHeap==0 ){ - /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer) - ** is NULL, then SQLite reverts to using its default memory allocator - ** (the system malloc() implementation), undoing any prior invocation of - ** SQLITE_CONFIG_MALLOC. - ** - ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to - ** revert to its default implementation when sqlite3_initialize() is run - */ - memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); - }else{ - /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the - ** alternative memory allocator is engaged to handle all of SQLites - ** memory allocation needs. */ -#ifdef SQLITE_ENABLE_MEMSYS3 - sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); -#endif -#ifdef SQLITE_ENABLE_MEMSYS5 - sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); -#endif - } - break; - } -#endif - - case SQLITE_CONFIG_LOOKASIDE: { - sqlite3GlobalConfig.szLookaside = va_arg(ap, int); - sqlite3GlobalConfig.nLookaside = va_arg(ap, int); - break; - } - - /* Record a pointer to the logger function and its first argument. - ** The default is NULL. Logging is disabled if the function pointer is - ** NULL. - */ - case SQLITE_CONFIG_LOG: { - /* MSVC is picky about pulling func ptrs from va lists. - ** http://support.microsoft.com/kb/47961 - ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); - */ - typedef void(*LOGFUNC_t)(void*,int,const char*); - sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); - sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); - break; - } - - /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames - ** can be changed at start-time using the - ** sqlite3_config(SQLITE_CONFIG_URI,1) or - ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. - */ - case SQLITE_CONFIG_URI: { - /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single - ** argument of type int. If non-zero, then URI handling is globally - ** enabled. If the parameter is zero, then URI handling is globally - ** disabled. */ - sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); - break; - } - - case SQLITE_CONFIG_COVERING_INDEX_SCAN: { - /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN - ** option takes a single integer argument which is interpreted as a - ** boolean in order to enable or disable the use of covering indices for - ** full table scans in the query optimizer. */ - sqlite3GlobalConfig.bUseCis = va_arg(ap, int); - break; - } - -#ifdef SQLITE_ENABLE_SQLLOG - case SQLITE_CONFIG_SQLLOG: { - typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); - sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); - sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); - break; - } -#endif - - case SQLITE_CONFIG_MMAP_SIZE: { - /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit - ** integer (sqlite3_int64) values that are the default mmap size limit - ** (the default setting for PRAGMA mmap_size) and the maximum allowed - ** mmap size limit. */ - sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); - sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); - /* EVIDENCE-OF: R-53367-43190 If either argument to this option is - ** negative, then that argument is changed to its compile-time default. - ** - ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be - ** silently truncated if necessary so that it does not exceed the - ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE - ** compile-time option. - */ - if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ - mxMmap = SQLITE_MAX_MMAP_SIZE; - } - if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; - if( szMmap>mxMmap) szMmap = mxMmap; - sqlite3GlobalConfig.mxMmap = mxMmap; - sqlite3GlobalConfig.szMmap = szMmap; - break; - } - -#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */ - case SQLITE_CONFIG_WIN32_HEAPSIZE: { - /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit - ** unsigned integer value that specifies the maximum size of the created - ** heap. */ - sqlite3GlobalConfig.nHeap = va_arg(ap, int); - break; - } -#endif - - case SQLITE_CONFIG_PMASZ: { - sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); - break; - } - - case SQLITE_CONFIG_STMTJRNL_SPILL: { - sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int); - break; - } - - default: { - rc = SQLITE_ERROR; - break; - } - } - va_end(ap); - return rc; -} - -/* -** Set up the lookaside buffers for a database connection. -** Return SQLITE_OK on success. -** If lookaside is already active, return SQLITE_BUSY. -** -** The sz parameter is the number of bytes in each lookaside slot. -** The cnt parameter is the number of slots. If pStart is NULL the -** space for the lookaside memory is obtained from sqlite3_malloc(). -** If pStart is not NULL then it is sz*cnt bytes of memory to use for -** the lookaside memory. -*/ -static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ -#ifndef SQLITE_OMIT_LOOKASIDE - void *pStart; - if( db->lookaside.nOut ){ - return SQLITE_BUSY; - } - /* Free any existing lookaside buffer for this handle before - ** allocating a new one so we don't have to have space for - ** both at the same time. - */ - if( db->lookaside.bMalloced ){ - sqlite3_free(db->lookaside.pStart); - } - /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger - ** than a pointer to be useful. - */ - sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ - if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; - if( cnt<0 ) cnt = 0; - if( sz==0 || cnt==0 ){ - sz = 0; - pStart = 0; - }else if( pBuf==0 ){ - sqlite3BeginBenignMalloc(); - pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */ - sqlite3EndBenignMalloc(); - if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; - }else{ - pStart = pBuf; - } - db->lookaside.pStart = pStart; - db->lookaside.pFree = 0; - db->lookaside.sz = (u16)sz; - if( pStart ){ - int i; - LookasideSlot *p; - assert( sz > (int)sizeof(LookasideSlot*) ); - p = (LookasideSlot*)pStart; - for(i=cnt-1; i>=0; i--){ - p->pNext = db->lookaside.pFree; - db->lookaside.pFree = p; - p = (LookasideSlot*)&((u8*)p)[sz]; - } - db->lookaside.pEnd = p; - db->lookaside.bDisable = 0; - db->lookaside.bMalloced = pBuf==0 ?1:0; - }else{ - db->lookaside.pStart = db; - db->lookaside.pEnd = db; - db->lookaside.bDisable = 1; - db->lookaside.bMalloced = 0; - } -#endif /* SQLITE_OMIT_LOOKASIDE */ - return SQLITE_OK; -} - -/* -** Return the mutex associated with a database connection. -*/ -SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return db->mutex; -} - -/* -** Free up as much memory as we can from the given database -** connection. -*/ -SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ - int i; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - for(i=0; inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt ){ - Pager *pPager = sqlite3BtreePager(pBt); - sqlite3PagerShrink(pPager); - } - } - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -/* -** Flush any dirty pages in the pager-cache for any attached database -** to disk. -*/ -SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ - int i; - int rc = SQLITE_OK; - int bSeenBusy = 0; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - for(i=0; rc==SQLITE_OK && inDb; i++){ - Btree *pBt = db->aDb[i].pBt; - if( pBt && sqlite3BtreeIsInTrans(pBt) ){ - Pager *pPager = sqlite3BtreePager(pBt); - rc = sqlite3PagerFlush(pPager); - if( rc==SQLITE_BUSY ){ - bSeenBusy = 1; - rc = SQLITE_OK; - } - } - } - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); -} - -/* -** Configuration settings for an individual database connection -*/ -SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ - va_list ap; - int rc; - va_start(ap, op); - switch( op ){ - case SQLITE_DBCONFIG_MAINDBNAME: { - db->aDb[0].zDbSName = va_arg(ap,char*); - rc = SQLITE_OK; - break; - } - case SQLITE_DBCONFIG_LOOKASIDE: { - void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ - int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ - int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ - rc = setupLookaside(db, pBuf, sz, cnt); - break; - } - default: { - static const struct { - int op; /* The opcode */ - u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ - } aFlagOp[] = { - { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, - { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, - { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, - { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, - }; - unsigned int i; - rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ - for(i=0; iflags; - if( onoff>0 ){ - db->flags |= aFlagOp[i].mask; - }else if( onoff==0 ){ - db->flags &= ~aFlagOp[i].mask; - } - if( oldFlags!=db->flags ){ - sqlite3ExpirePreparedStatements(db); - } - if( pRes ){ - *pRes = (db->flags & aFlagOp[i].mask)!=0; - } - rc = SQLITE_OK; - break; - } - } - break; - } - } - va_end(ap); - return rc; -} - - -/* -** Return true if the buffer z[0..n-1] contains all spaces. -*/ -static int allSpaces(const char *z, int n){ - while( n>0 && z[n-1]==' ' ){ n--; } - return n==0; -} - -/* -** This is the default collating function named "BINARY" which is always -** available. -** -** If the padFlag argument is not NULL then space padding at the end -** of strings is ignored. This implements the RTRIM collation. -*/ -static int binCollFunc( - void *padFlag, - int nKey1, const void *pKey1, - int nKey2, const void *pKey2 -){ - int rc, n; - n = nKey1lastRowid; -} - -/* -** Return the number of changes in the most recent call to sqlite3_exec(). -*/ -SQLITE_API int sqlite3_changes(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return db->nChange; -} - -/* -** Return the number of changes since the database handle was opened. -*/ -SQLITE_API int sqlite3_total_changes(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return db->nTotalChange; -} - -/* -** Close all open savepoints. This function only manipulates fields of the -** database handle object, it does not close any savepoints that may be open -** at the b-tree/pager level. -*/ -SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ - while( db->pSavepoint ){ - Savepoint *pTmp = db->pSavepoint; - db->pSavepoint = pTmp->pNext; - sqlite3DbFree(db, pTmp); - } - db->nSavepoint = 0; - db->nStatement = 0; - db->isTransactionSavepoint = 0; -} - -/* -** Invoke the destructor function associated with FuncDef p, if any. Except, -** if this is not the last copy of the function, do not invoke it. Multiple -** copies of a single function are created when create_function() is called -** with SQLITE_ANY as the encoding. -*/ -static void functionDestroy(sqlite3 *db, FuncDef *p){ - FuncDestructor *pDestructor = p->u.pDestructor; - if( pDestructor ){ - pDestructor->nRef--; - if( pDestructor->nRef==0 ){ - pDestructor->xDestroy(pDestructor->pUserData); - sqlite3DbFree(db, pDestructor); - } - } -} - -/* -** Disconnect all sqlite3_vtab objects that belong to database connection -** db. This is called when db is being closed. -*/ -static void disconnectAllVtab(sqlite3 *db){ -#ifndef SQLITE_OMIT_VIRTUALTABLE - int i; - HashElem *p; - sqlite3BtreeEnterAll(db); - for(i=0; inDb; i++){ - Schema *pSchema = db->aDb[i].pSchema; - if( db->aDb[i].pSchema ){ - for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ - Table *pTab = (Table *)sqliteHashData(p); - if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); - } - } - } - for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ - Module *pMod = (Module *)sqliteHashData(p); - if( pMod->pEpoTab ){ - sqlite3VtabDisconnect(db, pMod->pEpoTab); - } - } - sqlite3VtabUnlockList(db); - sqlite3BtreeLeaveAll(db); -#else - UNUSED_PARAMETER(db); -#endif -} - -/* -** Return TRUE if database connection db has unfinalized prepared -** statements or unfinished sqlite3_backup objects. -*/ -static int connectionIsBusy(sqlite3 *db){ - int j; - assert( sqlite3_mutex_held(db->mutex) ); - if( db->pVdbe ) return 1; - for(j=0; jnDb; j++){ - Btree *pBt = db->aDb[j].pBt; - if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; - } - return 0; -} - -/* -** Close an existing SQLite database -*/ -static int sqlite3Close(sqlite3 *db, int forceZombie){ - if( !db ){ - /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or - ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ - return SQLITE_OK; - } - if( !sqlite3SafetyCheckSickOrOk(db) ){ - return SQLITE_MISUSE_BKPT; - } - sqlite3_mutex_enter(db->mutex); - if( db->mTrace & SQLITE_TRACE_CLOSE ){ - db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); - } - - /* Force xDisconnect calls on all virtual tables */ - disconnectAllVtab(db); - - /* If a transaction is open, the disconnectAllVtab() call above - ** will not have called the xDisconnect() method on any virtual - ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() - ** call will do so. We need to do this before the check for active - ** SQL statements below, as the v-table implementation may be storing - ** some prepared statements internally. - */ - sqlite3VtabRollback(db); - - /* Legacy behavior (sqlite3_close() behavior) is to return - ** SQLITE_BUSY if the connection can not be closed immediately. - */ - if( !forceZombie && connectionIsBusy(db) ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " - "statements or unfinished backups"); - sqlite3_mutex_leave(db->mutex); - return SQLITE_BUSY; - } - -#ifdef SQLITE_ENABLE_SQLLOG - if( sqlite3GlobalConfig.xSqllog ){ - /* Closing the handle. Fourth parameter is passed the value 2. */ - sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); - } -#endif - - /* Convert the connection into a zombie and then close it. - */ - db->magic = SQLITE_MAGIC_ZOMBIE; - sqlite3LeaveMutexAndCloseZombie(db); - return SQLITE_OK; -} - -/* -** Two variations on the public interface for closing a database -** connection. The sqlite3_close() version returns SQLITE_BUSY and -** leaves the connection option if there are unfinalized prepared -** statements or unfinished sqlite3_backups. The sqlite3_close_v2() -** version forces the connection to become a zombie if there are -** unclosed resources, and arranges for deallocation when the last -** prepare statement or sqlite3_backup closes. -*/ -SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } -SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } - - -/* -** Close the mutex on database connection db. -** -** Furthermore, if database connection db is a zombie (meaning that there -** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and -** every sqlite3_stmt has now been finalized and every sqlite3_backup has -** finished, then free all resources. -*/ -SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ - HashElem *i; /* Hash table iterator */ - int j; - - /* If there are outstanding sqlite3_stmt or sqlite3_backup objects - ** or if the connection has not yet been closed by sqlite3_close_v2(), - ** then just leave the mutex and return. - */ - if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ - sqlite3_mutex_leave(db->mutex); - return; - } - - /* If we reach this point, it means that the database connection has - ** closed all sqlite3_stmt and sqlite3_backup objects and has been - ** passed to sqlite3_close (meaning that it is a zombie). Therefore, - ** go ahead and free all resources. - */ - - /* If a transaction is open, roll it back. This also ensures that if - ** any database schemas have been modified by an uncommitted transaction - ** they are reset. And that the required b-tree mutex is held to make - ** the pager rollback and schema reset an atomic operation. */ - sqlite3RollbackAll(db, SQLITE_OK); - - /* Free any outstanding Savepoint structures. */ - sqlite3CloseSavepoints(db); - - /* Close all database connections */ - for(j=0; jnDb; j++){ - struct Db *pDb = &db->aDb[j]; - if( pDb->pBt ){ - sqlite3BtreeClose(pDb->pBt); - pDb->pBt = 0; - if( j!=1 ){ - pDb->pSchema = 0; - } - } - } - /* Clear the TEMP schema separately and last */ - if( db->aDb[1].pSchema ){ - sqlite3SchemaClear(db->aDb[1].pSchema); - } - sqlite3VtabUnlockList(db); - - /* Free up the array of auxiliary databases */ - sqlite3CollapseDatabaseArray(db); - assert( db->nDb<=2 ); - assert( db->aDb==db->aDbStatic ); - - /* Tell the code in notify.c that the connection no longer holds any - ** locks and does not require any further unlock-notify callbacks. - */ - sqlite3ConnectionClosed(db); - - for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ - FuncDef *pNext, *p; - p = sqliteHashData(i); - do{ - functionDestroy(db, p); - pNext = p->pNext; - sqlite3DbFree(db, p); - p = pNext; - }while( p ); - } - sqlite3HashClear(&db->aFunc); - for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ - CollSeq *pColl = (CollSeq *)sqliteHashData(i); - /* Invoke any destructors registered for collation sequence user data. */ - for(j=0; j<3; j++){ - if( pColl[j].xDel ){ - pColl[j].xDel(pColl[j].pUser); - } - } - sqlite3DbFree(db, pColl); - } - sqlite3HashClear(&db->aCollSeq); -#ifndef SQLITE_OMIT_VIRTUALTABLE - for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ - Module *pMod = (Module *)sqliteHashData(i); - if( pMod->xDestroy ){ - pMod->xDestroy(pMod->pAux); - } - sqlite3VtabEponymousTableClear(db, pMod); - sqlite3DbFree(db, pMod); - } - sqlite3HashClear(&db->aModule); -#endif - - sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ - sqlite3ValueFree(db->pErr); - sqlite3CloseExtensions(db); -#if SQLITE_USER_AUTHENTICATION - sqlite3_free(db->auth.zAuthUser); - sqlite3_free(db->auth.zAuthPW); -#endif - - db->magic = SQLITE_MAGIC_ERROR; - - /* The temp-database schema is allocated differently from the other schema - ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). - ** So it needs to be freed here. Todo: Why not roll the temp schema into - ** the same sqliteMalloc() as the one that allocates the database - ** structure? - */ - sqlite3DbFree(db, db->aDb[1].pSchema); - sqlite3_mutex_leave(db->mutex); - db->magic = SQLITE_MAGIC_CLOSED; - sqlite3_mutex_free(db->mutex); - assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */ - if( db->lookaside.bMalloced ){ - sqlite3_free(db->lookaside.pStart); - } - sqlite3_free(db); -} - -/* -** Rollback all database files. If tripCode is not SQLITE_OK, then -** any write cursors are invalidated ("tripped" - as in "tripping a circuit -** breaker") and made to return tripCode if there are any further -** attempts to use that cursor. Read cursors remain open and valid -** but are "saved" in case the table pages are moved around. -*/ -SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ - int i; - int inTrans = 0; - int schemaChange; - assert( sqlite3_mutex_held(db->mutex) ); - sqlite3BeginBenignMalloc(); - - /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). - ** This is important in case the transaction being rolled back has - ** modified the database schema. If the b-tree mutexes are not taken - ** here, then another shared-cache connection might sneak in between - ** the database rollback and schema reset, which can cause false - ** corruption reports in some cases. */ - sqlite3BtreeEnterAll(db); - schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0; - - for(i=0; inDb; i++){ - Btree *p = db->aDb[i].pBt; - if( p ){ - if( sqlite3BtreeIsInTrans(p) ){ - inTrans = 1; - } - sqlite3BtreeRollback(p, tripCode, !schemaChange); - } - } - sqlite3VtabRollback(db); - sqlite3EndBenignMalloc(); - - if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ - sqlite3ExpirePreparedStatements(db); - sqlite3ResetAllSchemasOfConnection(db); - } - sqlite3BtreeLeaveAll(db); - - /* Any deferred constraint violations have now been resolved. */ - db->nDeferredCons = 0; - db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferFKs; - - /* If one has been configured, invoke the rollback-hook callback */ - if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ - db->xRollbackCallback(db->pRollbackArg); - } -} - -/* -** Return a static string containing the name corresponding to the error code -** specified in the argument. -*/ -#if defined(SQLITE_NEED_ERR_NAME) -SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ - const char *zName = 0; - int i, origRc = rc; - for(i=0; i<2 && zName==0; i++, rc &= 0xff){ - switch( rc ){ - case SQLITE_OK: zName = "SQLITE_OK"; break; - case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; - case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; - case SQLITE_PERM: zName = "SQLITE_PERM"; break; - case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; - case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; - case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; - case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; - case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break; - case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; - case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; - case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; - case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; - case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; - case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; - case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; - case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; - case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; - case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; - case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; - case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; - case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; - case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; - case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; - case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; - case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; - case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; - case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; - case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; - case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; - case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; - case SQLITE_IOERR_CHECKRESERVEDLOCK: - zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; - case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; - case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; - case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; - case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; - case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; - case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; - case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; - case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; - case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; - case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; - case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; - case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; - case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; - case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; - case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; - case SQLITE_FULL: zName = "SQLITE_FULL"; break; - case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; - case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; - case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; - case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; - case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; - case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; - case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; - case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; - case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; - case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; - case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; - case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; - case SQLITE_CONSTRAINT_FOREIGNKEY: - zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; - case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; - case SQLITE_CONSTRAINT_PRIMARYKEY: - zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; - case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; - case SQLITE_CONSTRAINT_COMMITHOOK: - zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; - case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; - case SQLITE_CONSTRAINT_FUNCTION: - zName = "SQLITE_CONSTRAINT_FUNCTION"; break; - case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break; - case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; - case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; - case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; - case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; - case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; - case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; - case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; - case SQLITE_ROW: zName = "SQLITE_ROW"; break; - case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; - case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; - case SQLITE_NOTICE_RECOVER_ROLLBACK: - zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; - case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; - case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; - case SQLITE_DONE: zName = "SQLITE_DONE"; break; - } - } - if( zName==0 ){ - static char zBuf[50]; - sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); - zName = zBuf; - } - return zName; -} -#endif - -/* -** Return a static string that describes the kind of error specified in the -** argument. -*/ -SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ - static const char* const aMsg[] = { - /* SQLITE_OK */ "not an error", - /* SQLITE_ERROR */ "SQL logic error or missing database", - /* SQLITE_INTERNAL */ 0, - /* SQLITE_PERM */ "access permission denied", - /* SQLITE_ABORT */ "callback requested query abort", - /* SQLITE_BUSY */ "database is locked", - /* SQLITE_LOCKED */ "database table is locked", - /* SQLITE_NOMEM */ "out of memory", - /* SQLITE_READONLY */ "attempt to write a readonly database", - /* SQLITE_INTERRUPT */ "interrupted", - /* SQLITE_IOERR */ "disk I/O error", - /* SQLITE_CORRUPT */ "database disk image is malformed", - /* SQLITE_NOTFOUND */ "unknown operation", - /* SQLITE_FULL */ "database or disk is full", - /* SQLITE_CANTOPEN */ "unable to open database file", - /* SQLITE_PROTOCOL */ "locking protocol", - /* SQLITE_EMPTY */ "table contains no data", - /* SQLITE_SCHEMA */ "database schema has changed", - /* SQLITE_TOOBIG */ "string or blob too big", - /* SQLITE_CONSTRAINT */ "constraint failed", - /* SQLITE_MISMATCH */ "datatype mismatch", - /* SQLITE_MISUSE */ "library routine called out of sequence", - /* SQLITE_NOLFS */ "large file support is disabled", - /* SQLITE_AUTH */ "authorization denied", - /* SQLITE_FORMAT */ "auxiliary database format error", - /* SQLITE_RANGE */ "bind or column index out of range", - /* SQLITE_NOTADB */ "file is encrypted or is not a database", - }; - const char *zErr = "unknown error"; - switch( rc ){ - case SQLITE_ABORT_ROLLBACK: { - zErr = "abort due to ROLLBACK"; - break; - } - default: { - rc &= 0xff; - if( ALWAYS(rc>=0) && rcbusyTimeout; - int delay, prior; - - assert( count>=0 ); - if( count < NDELAY ){ - delay = delays[count]; - prior = totals[count]; - }else{ - delay = delays[NDELAY-1]; - prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); - } - if( prior + delay > timeout ){ - delay = timeout - prior; - if( delay<=0 ) return 0; - } - sqlite3OsSleep(db->pVfs, delay*1000); - return 1; -#else - sqlite3 *db = (sqlite3 *)ptr; - int timeout = ((sqlite3 *)ptr)->busyTimeout; - if( (count+1)*1000 > timeout ){ - return 0; - } - sqlite3OsSleep(db->pVfs, 1000000); - return 1; -#endif -} - -/* -** Invoke the given busy handler. -** -** This routine is called when an operation failed with a lock. -** If this routine returns non-zero, the lock is retried. If it -** returns 0, the operation aborts with an SQLITE_BUSY error. -*/ -SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ - int rc; - if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0; - rc = p->xFunc(p->pArg, p->nBusy); - if( rc==0 ){ - p->nBusy = -1; - }else{ - p->nBusy++; - } - return rc; -} - -/* -** This routine sets the busy callback for an Sqlite database to the -** given callback function with the given argument. -*/ -SQLITE_API int sqlite3_busy_handler( - sqlite3 *db, - int (*xBusy)(void*,int), - void *pArg -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - db->busyHandler.xFunc = xBusy; - db->busyHandler.pArg = pArg; - db->busyHandler.nBusy = 0; - db->busyTimeout = 0; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK -/* -** This routine sets the progress callback for an Sqlite database to the -** given callback function with the given argument. The progress callback will -** be invoked every nOps opcodes. -*/ -SQLITE_API void sqlite3_progress_handler( - sqlite3 *db, - int nOps, - int (*xProgress)(void*), - void *pArg -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( nOps>0 ){ - db->xProgress = xProgress; - db->nProgressOps = (unsigned)nOps; - db->pProgressArg = pArg; - }else{ - db->xProgress = 0; - db->nProgressOps = 0; - db->pProgressArg = 0; - } - sqlite3_mutex_leave(db->mutex); -} -#endif - - -/* -** This routine installs a default busy handler that waits for the -** specified number of milliseconds before returning 0. -*/ -SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - if( ms>0 ){ - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); - db->busyTimeout = ms; - }else{ - sqlite3_busy_handler(db, 0, 0); - } - return SQLITE_OK; -} - -/* -** Cause any pending operation to stop at its earliest opportunity. -*/ -SQLITE_API void sqlite3_interrupt(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return; - } -#endif - db->u1.isInterrupted = 1; -} - - -/* -** This function is exactly the same as sqlite3_create_function(), except -** that it is designed to be called by internal code. The difference is -** that if a malloc() fails in sqlite3_create_function(), an error code -** is returned and the mallocFailed flag cleared. -*/ -SQLITE_PRIVATE int sqlite3CreateFunc( - sqlite3 *db, - const char *zFunctionName, - int nArg, - int enc, - void *pUserData, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*), - FuncDestructor *pDestructor -){ - FuncDef *p; - int nName; - int extraFlags; - - assert( sqlite3_mutex_held(db->mutex) ); - if( zFunctionName==0 || - (xSFunc && (xFinal || xStep)) || - (!xSFunc && (xFinal && !xStep)) || - (!xSFunc && (!xFinal && xStep)) || - (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || - (255<(nName = sqlite3Strlen30( zFunctionName))) ){ - return SQLITE_MISUSE_BKPT; - } - - assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); - extraFlags = enc & SQLITE_DETERMINISTIC; - enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); - -#ifndef SQLITE_OMIT_UTF16 - /* If SQLITE_UTF16 is specified as the encoding type, transform this - ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the - ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. - ** - ** If SQLITE_ANY is specified, add three versions of the function - ** to the hash table. - */ - if( enc==SQLITE_UTF16 ){ - enc = SQLITE_UTF16NATIVE; - }else if( enc==SQLITE_ANY ){ - int rc; - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); - if( rc==SQLITE_OK ){ - rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); - } - if( rc!=SQLITE_OK ){ - return rc; - } - enc = SQLITE_UTF16BE; - } -#else - enc = SQLITE_UTF8; -#endif - - /* Check if an existing function is being overridden or deleted. If so, - ** and there are active VMs, then return SQLITE_BUSY. If a function - ** is being overridden/deleted but there are no active VMs, allow the - ** operation to continue but invalidate all precompiled statements. - */ - p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); - if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ - if( db->nVdbeActive ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, - "unable to delete/modify user-function due to active statements"); - assert( !db->mallocFailed ); - return SQLITE_BUSY; - }else{ - sqlite3ExpirePreparedStatements(db); - } - } - - p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1); - assert(p || db->mallocFailed); - if( !p ){ - return SQLITE_NOMEM_BKPT; - } - - /* If an older version of the function with a configured destructor is - ** being replaced invoke the destructor function here. */ - functionDestroy(db, p); - - if( pDestructor ){ - pDestructor->nRef++; - } - p->u.pDestructor = pDestructor; - p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; - testcase( p->funcFlags & SQLITE_DETERMINISTIC ); - p->xSFunc = xSFunc ? xSFunc : xStep; - p->xFinalize = xFinal; - p->pUserData = pUserData; - p->nArg = (u16)nArg; - return SQLITE_OK; -} - -/* -** Create new user functions. -*/ -SQLITE_API int sqlite3_create_function( - sqlite3 *db, - const char *zFunc, - int nArg, - int enc, - void *p, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*) -){ - return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep, - xFinal, 0); -} - -SQLITE_API int sqlite3_create_function_v2( - sqlite3 *db, - const char *zFunc, - int nArg, - int enc, - void *p, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*), - void (*xDestroy)(void *) -){ - int rc = SQLITE_ERROR; - FuncDestructor *pArg = 0; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( xDestroy ){ - pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor)); - if( !pArg ){ - xDestroy(p); - goto out; - } - pArg->xDestroy = xDestroy; - pArg->pUserData = p; - } - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg); - if( pArg && pArg->nRef==0 ){ - assert( rc!=SQLITE_OK ); - xDestroy(p); - sqlite3DbFree(db, pArg); - } - - out: - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_UTF16 -SQLITE_API int sqlite3_create_function16( - sqlite3 *db, - const void *zFunctionName, - int nArg, - int eTextRep, - void *p, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), - void (*xStep)(sqlite3_context*,int,sqlite3_value**), - void (*xFinal)(sqlite3_context*) -){ - int rc; - char *zFunc8; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0); - sqlite3DbFree(db, zFunc8); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} -#endif - - -/* -** Declare that a function has been overloaded by a virtual table. -** -** If the function already exists as a regular global function, then -** this routine is a no-op. If the function does not exist, then create -** a new one that always throws a run-time error. -** -** When virtual tables intend to provide an overloaded function, they -** should call this routine to make sure the global function exists. -** A global function must exist in order for name resolution to work -** properly. -*/ -SQLITE_API int sqlite3_overload_function( - sqlite3 *db, - const char *zName, - int nArg -){ - int rc = SQLITE_OK; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){ - rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, - 0, sqlite3InvalidFunction, 0, 0, 0); - } - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_TRACE -/* -** Register a trace function. The pArg from the previously registered trace -** is returned. -** -** A NULL trace function means that no tracing is executes. A non-NULL -** trace is a pointer to a function that is invoked at the start of each -** SQL statement. -*/ -#ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ - void *pOld; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pOld = db->pTraceArg; - db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; - db->xTrace = (int(*)(u32,void*,void*,void*))xTrace; - db->pTraceArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} -#endif /* SQLITE_OMIT_DEPRECATED */ - -/* Register a trace callback using the version-2 interface. -*/ -SQLITE_API int sqlite3_trace_v2( - sqlite3 *db, /* Trace this connection */ - unsigned mTrace, /* Mask of events to be traced */ - int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */ - void *pArg /* Context */ -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( mTrace==0 ) xTrace = 0; - if( xTrace==0 ) mTrace = 0; - db->mTrace = mTrace; - db->xTrace = xTrace; - db->pTraceArg = pArg; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** Register a profile function. The pArg from the previously registered -** profile function is returned. -** -** A NULL profile function means that no profiling is executes. A non-NULL -** profile is a pointer to a function that is invoked at the conclusion of -** each SQL statement that is run. -*/ -SQLITE_API void *sqlite3_profile( - sqlite3 *db, - void (*xProfile)(void*,const char*,sqlite_uint64), - void *pArg -){ - void *pOld; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pOld = db->pProfileArg; - db->xProfile = xProfile; - db->pProfileArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} -#endif /* SQLITE_OMIT_DEPRECATED */ -#endif /* SQLITE_OMIT_TRACE */ - -/* -** Register a function to be invoked when a transaction commits. -** If the invoked function returns non-zero, then the commit becomes a -** rollback. -*/ -SQLITE_API void *sqlite3_commit_hook( - sqlite3 *db, /* Attach the hook to this database */ - int (*xCallback)(void*), /* Function to invoke on each commit */ - void *pArg /* Argument to the function */ -){ - void *pOld; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pOld = db->pCommitArg; - db->xCommitCallback = xCallback; - db->pCommitArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pOld; -} - -/* -** Register a callback to be invoked each time a row is updated, -** inserted or deleted using this database connection. -*/ -SQLITE_API void *sqlite3_update_hook( - sqlite3 *db, /* Attach the hook to this database */ - void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), - void *pArg /* Argument to the function */ -){ - void *pRet; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pRet = db->pUpdateArg; - db->xUpdateCallback = xCallback; - db->pUpdateArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} - -/* -** Register a callback to be invoked each time a transaction is rolled -** back by this database connection. -*/ -SQLITE_API void *sqlite3_rollback_hook( - sqlite3 *db, /* Attach the hook to this database */ - void (*xCallback)(void*), /* Callback function */ - void *pArg /* Argument to the function */ -){ - void *pRet; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pRet = db->pRollbackArg; - db->xRollbackCallback = xCallback; - db->pRollbackArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} - -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK -/* -** Register a callback to be invoked each time a row is updated, -** inserted or deleted using this database connection. -*/ -SQLITE_API void *sqlite3_preupdate_hook( - sqlite3 *db, /* Attach the hook to this database */ - void(*xCallback)( /* Callback function */ - void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64), - void *pArg /* First callback argument */ -){ - void *pRet; - sqlite3_mutex_enter(db->mutex); - pRet = db->pPreUpdateArg; - db->xPreUpdateCallback = xCallback; - db->pPreUpdateArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -} -#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -#ifndef SQLITE_OMIT_WAL -/* -** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). -** Invoke sqlite3_wal_checkpoint if the number of frames in the log file -** is greater than sqlite3.pWalArg cast to an integer (the value configured by -** wal_autocheckpoint()). -*/ -SQLITE_PRIVATE int sqlite3WalDefaultHook( - void *pClientData, /* Argument */ - sqlite3 *db, /* Connection */ - const char *zDb, /* Database */ - int nFrame /* Size of WAL */ -){ - if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ - sqlite3BeginBenignMalloc(); - sqlite3_wal_checkpoint(db, zDb); - sqlite3EndBenignMalloc(); - } - return SQLITE_OK; -} -#endif /* SQLITE_OMIT_WAL */ - -/* -** Configure an sqlite3_wal_hook() callback to automatically checkpoint -** a database after committing a transaction if there are nFrame or -** more frames in the log file. Passing zero or a negative value as the -** nFrame parameter disables automatic checkpoints entirely. -** -** The callback registered by this function replaces any existing callback -** registered using sqlite3_wal_hook(). Likewise, registering a callback -** using sqlite3_wal_hook() disables the automatic checkpoint mechanism -** configured by this function. -*/ -SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ -#ifdef SQLITE_OMIT_WAL - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(nFrame); -#else -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - if( nFrame>0 ){ - sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); - }else{ - sqlite3_wal_hook(db, 0, 0); - } -#endif - return SQLITE_OK; -} - -/* -** Register a callback to be invoked each time a transaction is written -** into the write-ahead-log by this database connection. -*/ -SQLITE_API void *sqlite3_wal_hook( - sqlite3 *db, /* Attach the hook to this db handle */ - int(*xCallback)(void *, sqlite3*, const char*, int), - void *pArg /* First argument passed to xCallback() */ -){ -#ifndef SQLITE_OMIT_WAL - void *pRet; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - sqlite3_mutex_enter(db->mutex); - pRet = db->pWalArg; - db->xWalCallback = xCallback; - db->pWalArg = pArg; - sqlite3_mutex_leave(db->mutex); - return pRet; -#else - return 0; -#endif -} - -/* -** Checkpoint database zDb. -*/ -SQLITE_API int sqlite3_wal_checkpoint_v2( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of attached database (or NULL) */ - int eMode, /* SQLITE_CHECKPOINT_* value */ - int *pnLog, /* OUT: Size of WAL log in frames */ - int *pnCkpt /* OUT: Total number of frames checkpointed */ -){ -#ifdef SQLITE_OMIT_WAL - return SQLITE_OK; -#else - int rc; /* Return code */ - int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - - /* Initialize the output variables to -1 in case an error occurs. */ - if( pnLog ) *pnLog = -1; - if( pnCkpt ) *pnCkpt = -1; - - assert( SQLITE_CHECKPOINT_PASSIVE==0 ); - assert( SQLITE_CHECKPOINT_FULL==1 ); - assert( SQLITE_CHECKPOINT_RESTART==2 ); - assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); - if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ - /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint - ** mode: */ - return SQLITE_MISUSE; - } - - sqlite3_mutex_enter(db->mutex); - if( zDb && zDb[0] ){ - iDb = sqlite3FindDbName(db, zDb); - } - if( iDb<0 ){ - rc = SQLITE_ERROR; - sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); - }else{ - db->busyHandler.nBusy = 0; - rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); - sqlite3Error(db, rc); - } - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -#endif -} - - -/* -** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points -** to contains a zero-length string, all attached databases are -** checkpointed. -*/ -SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ - /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to - ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ - return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); -} - -#ifndef SQLITE_OMIT_WAL -/* -** Run a checkpoint on database iDb. This is a no-op if database iDb is -** not currently open in WAL mode. -** -** If a transaction is open on the database being checkpointed, this -** function returns SQLITE_LOCKED and a checkpoint is not attempted. If -** an error occurs while running the checkpoint, an SQLite error code is -** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. -** -** The mutex on database handle db should be held by the caller. The mutex -** associated with the specific b-tree being checkpointed is taken by -** this function while the checkpoint is running. -** -** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are -** checkpointed. If an error is encountered it is returned immediately - -** no attempt is made to checkpoint any remaining databases. -** -** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. -*/ -SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ - int rc = SQLITE_OK; /* Return code */ - int i; /* Used to iterate through attached dbs */ - int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ - - assert( sqlite3_mutex_held(db->mutex) ); - assert( !pnLog || *pnLog==-1 ); - assert( !pnCkpt || *pnCkpt==-1 ); - - for(i=0; inDb && rc==SQLITE_OK; i++){ - if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ - rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); - pnLog = 0; - pnCkpt = 0; - if( rc==SQLITE_BUSY ){ - bBusy = 1; - rc = SQLITE_OK; - } - } - } - - return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; -} -#endif /* SQLITE_OMIT_WAL */ - -/* -** This function returns true if main-memory should be used instead of -** a temporary file for transient pager files and statement journals. -** The value returned depends on the value of db->temp_store (runtime -** parameter) and the compile time value of SQLITE_TEMP_STORE. The -** following table describes the relationship between these two values -** and this functions return value. -** -** SQLITE_TEMP_STORE db->temp_store Location of temporary database -** ----------------- -------------- ------------------------------ -** 0 any file (return 0) -** 1 1 file (return 0) -** 1 2 memory (return 1) -** 1 0 file (return 0) -** 2 1 file (return 0) -** 2 2 memory (return 1) -** 2 0 memory (return 1) -** 3 any memory (return 1) -*/ -SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ -#if SQLITE_TEMP_STORE==1 - return ( db->temp_store==2 ); -#endif -#if SQLITE_TEMP_STORE==2 - return ( db->temp_store!=1 ); -#endif -#if SQLITE_TEMP_STORE==3 - UNUSED_PARAMETER(db); - return 1; -#endif -#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3 - UNUSED_PARAMETER(db); - return 0; -#endif -} - -/* -** Return UTF-8 encoded English language explanation of the most recent -** error. -*/ -SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ - const char *z; - if( !db ){ - return sqlite3ErrStr(SQLITE_NOMEM_BKPT); - } - if( !sqlite3SafetyCheckSickOrOk(db) ){ - return sqlite3ErrStr(SQLITE_MISUSE_BKPT); - } - sqlite3_mutex_enter(db->mutex); - if( db->mallocFailed ){ - z = sqlite3ErrStr(SQLITE_NOMEM_BKPT); - }else{ - testcase( db->pErr==0 ); - z = (char*)sqlite3_value_text(db->pErr); - assert( !db->mallocFailed ); - if( z==0 ){ - z = sqlite3ErrStr(db->errCode); - } - } - sqlite3_mutex_leave(db->mutex); - return z; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Return UTF-16 encoded English language explanation of the most recent -** error. -*/ -SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ - static const u16 outOfMem[] = { - 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 - }; - static const u16 misuse[] = { - 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ', - 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ', - 'c', 'a', 'l', 'l', 'e', 'd', ' ', - 'o', 'u', 't', ' ', - 'o', 'f', ' ', - 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0 - }; - - const void *z; - if( !db ){ - return (void *)outOfMem; - } - if( !sqlite3SafetyCheckSickOrOk(db) ){ - return (void *)misuse; - } - sqlite3_mutex_enter(db->mutex); - if( db->mallocFailed ){ - z = (void *)outOfMem; - }else{ - z = sqlite3_value_text16(db->pErr); - if( z==0 ){ - sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); - z = sqlite3_value_text16(db->pErr); - } - /* A malloc() may have failed within the call to sqlite3_value_text16() - ** above. If this is the case, then the db->mallocFailed flag needs to - ** be cleared before returning. Do this directly, instead of via - ** sqlite3ApiExit(), to avoid setting the database handle error message. - */ - sqlite3OomClear(db); - } - sqlite3_mutex_leave(db->mutex); - return z; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Return the most recent error code generated by an SQLite routine. If NULL is -** passed to this function, we assume a malloc() failed during sqlite3_open(). -*/ -SQLITE_API int sqlite3_errcode(sqlite3 *db){ - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ - return SQLITE_MISUSE_BKPT; - } - if( !db || db->mallocFailed ){ - return SQLITE_NOMEM_BKPT; - } - return db->errCode & db->errMask; -} -SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ - return SQLITE_MISUSE_BKPT; - } - if( !db || db->mallocFailed ){ - return SQLITE_NOMEM_BKPT; - } - return db->errCode; -} -SQLITE_API int sqlite3_system_errno(sqlite3 *db){ - return db ? db->iSysErrno : 0; -} - -/* -** Return a string that describes the kind of error specified in the -** argument. For now, this simply calls the internal sqlite3ErrStr() -** function. -*/ -SQLITE_API const char *sqlite3_errstr(int rc){ - return sqlite3ErrStr(rc); -} - -/* -** Create a new collating function for database "db". The name is zName -** and the encoding is enc. -*/ -static int createCollation( - sqlite3* db, - const char *zName, - u8 enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDel)(void*) -){ - CollSeq *pColl; - int enc2; - - assert( sqlite3_mutex_held(db->mutex) ); - - /* If SQLITE_UTF16 is specified as the encoding type, transform this - ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the - ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. - */ - enc2 = enc; - testcase( enc2==SQLITE_UTF16 ); - testcase( enc2==SQLITE_UTF16_ALIGNED ); - if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){ - enc2 = SQLITE_UTF16NATIVE; - } - if( enc2SQLITE_UTF16BE ){ - return SQLITE_MISUSE_BKPT; - } - - /* Check if this call is removing or replacing an existing collation - ** sequence. If so, and there are active VMs, return busy. If there - ** are no active VMs, invalidate any pre-compiled statements. - */ - pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); - if( pColl && pColl->xCmp ){ - if( db->nVdbeActive ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, - "unable to delete/modify collation sequence due to active statements"); - return SQLITE_BUSY; - } - sqlite3ExpirePreparedStatements(db); - - /* If collation sequence pColl was created directly by a call to - ** sqlite3_create_collation, and not generated by synthCollSeq(), - ** then any copies made by synthCollSeq() need to be invalidated. - ** Also, collation destructor - CollSeq.xDel() - function may need - ** to be called. - */ - if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ - CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); - int j; - for(j=0; j<3; j++){ - CollSeq *p = &aColl[j]; - if( p->enc==pColl->enc ){ - if( p->xDel ){ - p->xDel(p->pUser); - } - p->xCmp = 0; - } - } - } - } - - pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); - if( pColl==0 ) return SQLITE_NOMEM_BKPT; - pColl->xCmp = xCompare; - pColl->pUser = pCtx; - pColl->xDel = xDel; - pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); - sqlite3Error(db, SQLITE_OK); - return SQLITE_OK; -} - - -/* -** This array defines hard upper bounds on limit values. The -** initializer must be kept in sync with the SQLITE_LIMIT_* -** #defines in sqlite3.h. -*/ -static const int aHardLimit[] = { - SQLITE_MAX_LENGTH, - SQLITE_MAX_SQL_LENGTH, - SQLITE_MAX_COLUMN, - SQLITE_MAX_EXPR_DEPTH, - SQLITE_MAX_COMPOUND_SELECT, - SQLITE_MAX_VDBE_OP, - SQLITE_MAX_FUNCTION_ARG, - SQLITE_MAX_ATTACHED, - SQLITE_MAX_LIKE_PATTERN_LENGTH, - SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ - SQLITE_MAX_TRIGGER_DEPTH, - SQLITE_MAX_WORKER_THREADS, -}; - -/* -** Make sure the hard limits are set to reasonable values -*/ -#if SQLITE_MAX_LENGTH<100 -# error SQLITE_MAX_LENGTH must be at least 100 -#endif -#if SQLITE_MAX_SQL_LENGTH<100 -# error SQLITE_MAX_SQL_LENGTH must be at least 100 -#endif -#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH -# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH -#endif -#if SQLITE_MAX_COMPOUND_SELECT<2 -# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 -#endif -#if SQLITE_MAX_VDBE_OP<40 -# error SQLITE_MAX_VDBE_OP must be at least 40 -#endif -#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127 -# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127 -#endif -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 -# error SQLITE_MAX_ATTACHED must be between 0 and 125 -#endif -#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 -# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 -#endif -#if SQLITE_MAX_COLUMN>32767 -# error SQLITE_MAX_COLUMN must not exceed 32767 -#endif -#if SQLITE_MAX_TRIGGER_DEPTH<1 -# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 -#endif -#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 -# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 -#endif - - -/* -** Change the value of a limit. Report the old value. -** If an invalid limit index is supplied, report -1. -** Make no changes but still report the old value if the -** new limit is negative. -** -** A new lower limit does not shrink existing constructs. -** It merely prevents new constructs that exceed the limit -** from forming. -*/ -SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ - int oldLimit; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return -1; - } -#endif - - /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME - ** there is a hard upper bound set at compile-time by a C preprocessor - ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to - ** "_MAX_".) - */ - assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); - assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); - assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); - assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); - assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); - assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); - assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); - assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); - assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== - SQLITE_MAX_LIKE_PATTERN_LENGTH ); - assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); - assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); - assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); - assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); - - - if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ - return -1; - } - oldLimit = db->aLimit[limitId]; - if( newLimit>=0 ){ /* IMP: R-52476-28732 */ - if( newLimit>aHardLimit[limitId] ){ - newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ - } - db->aLimit[limitId] = newLimit; - } - return oldLimit; /* IMP: R-53341-35419 */ -} - -/* -** This function is used to parse both URIs and non-URI filenames passed by the -** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database -** URIs specified as part of ATTACH statements. -** -** The first argument to this function is the name of the VFS to use (or -** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" -** query parameter. The second argument contains the URI (or non-URI filename) -** itself. When this function is called the *pFlags variable should contain -** the default flags to open the database handle with. The value stored in -** *pFlags may be updated before returning if the URI filename contains -** "cache=xxx" or "mode=xxx" query parameters. -** -** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to -** the VFS that should be used to open the database file. *pzFile is set to -** point to a buffer containing the name of the file to open. It is the -** responsibility of the caller to eventually call sqlite3_free() to release -** this buffer. -** -** If an error occurs, then an SQLite error code is returned and *pzErrMsg -** may be set to point to a buffer containing an English language error -** message. It is the responsibility of the caller to eventually release -** this buffer by calling sqlite3_free(). -*/ -SQLITE_PRIVATE int sqlite3ParseUri( - const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ - const char *zUri, /* Nul-terminated URI to parse */ - unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ - sqlite3_vfs **ppVfs, /* OUT: VFS to use */ - char **pzFile, /* OUT: Filename component of URI */ - char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ -){ - int rc = SQLITE_OK; - unsigned int flags = *pFlags; - const char *zVfs = zDefaultVfs; - char *zFile; - char c; - int nUri = sqlite3Strlen30(zUri); - - assert( *pzErrMsg==0 ); - - if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ - || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ - && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ - ){ - char *zOpt; - int eState; /* Parser state when parsing URI */ - int iIn; /* Input character index */ - int iOut = 0; /* Output character index */ - u64 nByte = nUri+2; /* Bytes of space to allocate */ - - /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen - ** method that there may be extra parameters following the file-name. */ - flags |= SQLITE_OPEN_URI; - - for(iIn=0; iIn=0 && octet<256 ); - if( octet==0 ){ - /* This branch is taken when "%00" appears within the URI. In this - ** case we ignore all text in the remainder of the path, name or - ** value currently being parsed. So ignore the current character - ** and skip to the next "?", "=" or "&", as appropriate. */ - while( (c = zUri[iIn])!=0 && c!='#' - && (eState!=0 || c!='?') - && (eState!=1 || (c!='=' && c!='&')) - && (eState!=2 || c!='&') - ){ - iIn++; - } - continue; - } - c = octet; - }else if( eState==1 && (c=='&' || c=='=') ){ - if( zFile[iOut-1]==0 ){ - /* An empty option name. Ignore this option altogether. */ - while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; - continue; - } - if( c=='&' ){ - zFile[iOut++] = '\0'; - }else{ - eState = 2; - } - c = 0; - }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ - c = 0; - eState = 1; - } - zFile[iOut++] = c; - } - if( eState==1 ) zFile[iOut++] = '\0'; - zFile[iOut++] = '\0'; - zFile[iOut++] = '\0'; - - /* Check if there were any options specified that should be interpreted - ** here. Options that are interpreted here include "vfs" and those that - ** correspond to flags that may be passed to the sqlite3_open_v2() - ** method. */ - zOpt = &zFile[sqlite3Strlen30(zFile)+1]; - while( zOpt[0] ){ - int nOpt = sqlite3Strlen30(zOpt); - char *zVal = &zOpt[nOpt+1]; - int nVal = sqlite3Strlen30(zVal); - - if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ - zVfs = zVal; - }else{ - struct OpenMode { - const char *z; - int mode; - } *aMode = 0; - char *zModeType = 0; - int mask = 0; - int limit = 0; - - if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ - static struct OpenMode aCacheMode[] = { - { "shared", SQLITE_OPEN_SHAREDCACHE }, - { "private", SQLITE_OPEN_PRIVATECACHE }, - { 0, 0 } - }; - - mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; - aMode = aCacheMode; - limit = mask; - zModeType = "cache"; - } - if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ - static struct OpenMode aOpenMode[] = { - { "ro", SQLITE_OPEN_READONLY }, - { "rw", SQLITE_OPEN_READWRITE }, - { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, - { "memory", SQLITE_OPEN_MEMORY }, - { 0, 0 } - }; - - mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE - | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; - aMode = aOpenMode; - limit = mask & flags; - zModeType = "access"; - } - - if( aMode ){ - int i; - int mode = 0; - for(i=0; aMode[i].z; i++){ - const char *z = aMode[i].z; - if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ - mode = aMode[i].mode; - break; - } - } - if( mode==0 ){ - *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); - rc = SQLITE_ERROR; - goto parse_uri_out; - } - if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ - *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", - zModeType, zVal); - rc = SQLITE_PERM; - goto parse_uri_out; - } - flags = (flags & ~mask) | mode; - } - } - - zOpt = &zVal[nVal+1]; - } - - }else{ - zFile = sqlite3_malloc64(nUri+2); - if( !zFile ) return SQLITE_NOMEM_BKPT; - memcpy(zFile, zUri, nUri); - zFile[nUri] = '\0'; - zFile[nUri+1] = '\0'; - flags &= ~SQLITE_OPEN_URI; - } - - *ppVfs = sqlite3_vfs_find(zVfs); - if( *ppVfs==0 ){ - *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); - rc = SQLITE_ERROR; - } - parse_uri_out: - if( rc!=SQLITE_OK ){ - sqlite3_free(zFile); - zFile = 0; - } - *pFlags = flags; - *pzFile = zFile; - return rc; -} - - -/* -** This routine does the work of opening a database on behalf of -** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" -** is UTF-8 encoded. -*/ -static int openDatabase( - const char *zFilename, /* Database filename UTF-8 encoded */ - sqlite3 **ppDb, /* OUT: Returned database handle */ - unsigned int flags, /* Operational flags */ - const char *zVfs /* Name of the VFS to use */ -){ - sqlite3 *db; /* Store allocated handle here */ - int rc; /* Return code */ - int isThreadsafe; /* True for threadsafe connections */ - char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ - char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ - -#ifdef SQLITE_ENABLE_API_ARMOR - if( ppDb==0 ) return SQLITE_MISUSE_BKPT; -#endif - *ppDb = 0; -#ifndef SQLITE_OMIT_AUTOINIT - rc = sqlite3_initialize(); - if( rc ) return rc; -#endif - - /* Only allow sensible combinations of bits in the flags argument. - ** Throw an error if any non-sense combination is used. If we - ** do not block illegal combinations here, it could trigger - ** assert() statements in deeper layers. Sensible combinations - ** are: - ** - ** 1: SQLITE_OPEN_READONLY - ** 2: SQLITE_OPEN_READWRITE - ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE - */ - assert( SQLITE_OPEN_READONLY == 0x01 ); - assert( SQLITE_OPEN_READWRITE == 0x02 ); - assert( SQLITE_OPEN_CREATE == 0x04 ); - testcase( (1<<(flags&7))==0x02 ); /* READONLY */ - testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ - testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ - if( ((1<<(flags&7)) & 0x46)==0 ){ - return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ - } - - if( sqlite3GlobalConfig.bCoreMutex==0 ){ - isThreadsafe = 0; - }else if( flags & SQLITE_OPEN_NOMUTEX ){ - isThreadsafe = 0; - }else if( flags & SQLITE_OPEN_FULLMUTEX ){ - isThreadsafe = 1; - }else{ - isThreadsafe = sqlite3GlobalConfig.bFullMutex; - } - if( flags & SQLITE_OPEN_PRIVATECACHE ){ - flags &= ~SQLITE_OPEN_SHAREDCACHE; - }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ - flags |= SQLITE_OPEN_SHAREDCACHE; - } - - /* Remove harmful bits from the flags parameter - ** - ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were - ** dealt with in the previous code block. Besides these, the only - ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, - ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, - ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask - ** off all other flags. - */ - flags &= ~( SQLITE_OPEN_DELETEONCLOSE | - SQLITE_OPEN_EXCLUSIVE | - SQLITE_OPEN_MAIN_DB | - SQLITE_OPEN_TEMP_DB | - SQLITE_OPEN_TRANSIENT_DB | - SQLITE_OPEN_MAIN_JOURNAL | - SQLITE_OPEN_TEMP_JOURNAL | - SQLITE_OPEN_SUBJOURNAL | - SQLITE_OPEN_MASTER_JOURNAL | - SQLITE_OPEN_NOMUTEX | - SQLITE_OPEN_FULLMUTEX | - SQLITE_OPEN_WAL - ); - - /* Allocate the sqlite data structure */ - db = sqlite3MallocZero( sizeof(sqlite3) ); - if( db==0 ) goto opendb_out; - if( isThreadsafe ){ - db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); - if( db->mutex==0 ){ - sqlite3_free(db); - db = 0; - goto opendb_out; - } - } - sqlite3_mutex_enter(db->mutex); - db->errMask = 0xff; - db->nDb = 2; - db->magic = SQLITE_MAGIC_BUSY; - db->aDb = db->aDbStatic; - - assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); - memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); - db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; - db->autoCommit = 1; - db->nextAutovac = -1; - db->szMmap = sqlite3GlobalConfig.szMmap; - db->nextPagesize = 0; - db->nMaxSorterMmap = 0x7FFFFFFF; - db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill -#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX - | SQLITE_AutoIndex -#endif -#if SQLITE_DEFAULT_CKPTFULLFSYNC - | SQLITE_CkptFullFSync -#endif -#if SQLITE_DEFAULT_FILE_FORMAT<4 - | SQLITE_LegacyFileFmt -#endif -#ifdef SQLITE_ENABLE_LOAD_EXTENSION - | SQLITE_LoadExtension -#endif -#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS - | SQLITE_RecTriggers -#endif -#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS - | SQLITE_ForeignKeys -#endif -#if defined(SQLITE_REVERSE_UNORDERED_SELECTS) - | SQLITE_ReverseOrder -#endif -#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) - | SQLITE_CellSizeCk -#endif -#if defined(SQLITE_ENABLE_FTS3_TOKENIZER) - | SQLITE_Fts3Tokenizer -#endif - ; - sqlite3HashInit(&db->aCollSeq); -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3HashInit(&db->aModule); -#endif - - /* Add the default collation sequence BINARY. BINARY works for both UTF-8 - ** and UTF-16, so add a version for each to avoid any unnecessary - ** conversions. The only error that can occur here is a malloc() failure. - ** - ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating - ** functions: - */ - createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); - createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); - createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); - if( db->mallocFailed ){ - goto opendb_out; - } - /* EVIDENCE-OF: R-08308-17224 The default collating function for all - ** strings is BINARY. - */ - db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); - assert( db->pDfltColl!=0 ); - - /* Parse the filename/URI argument. */ - db->openFlags = flags; - rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); - sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); - sqlite3_free(zErrMsg); - goto opendb_out; - } - - /* Open the backend database driver */ - rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, - flags | SQLITE_OPEN_MAIN_DB); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_IOERR_NOMEM ){ - rc = SQLITE_NOMEM_BKPT; - } - sqlite3Error(db, rc); - goto opendb_out; - } - sqlite3BtreeEnter(db->aDb[0].pBt); - db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); - if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); - sqlite3BtreeLeave(db->aDb[0].pBt); - db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); - - /* The default safety_level for the main database is FULL; for the temp - ** database it is OFF. This matches the pager layer defaults. - */ - db->aDb[0].zDbSName = "main"; - db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - db->aDb[1].zDbSName = "temp"; - db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; - - db->magic = SQLITE_MAGIC_OPEN; - if( db->mallocFailed ){ - goto opendb_out; - } - - /* Register all built-in functions, but do not attempt to read the - ** database schema yet. This is delayed until the first time the database - ** is accessed. - */ - sqlite3Error(db, SQLITE_OK); - sqlite3RegisterPerConnectionBuiltinFunctions(db); - rc = sqlite3_errcode(db); - -#ifdef SQLITE_ENABLE_FTS5 - /* Register any built-in FTS5 module before loading the automatic - ** extensions. This allows automatic extensions to register FTS5 - ** tokenizers and auxiliary functions. */ - if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = sqlite3Fts5Init(db); - } -#endif - - /* Load automatic extensions - extensions that have been registered - ** using the sqlite3_automatic_extension() API. - */ - if( rc==SQLITE_OK ){ - sqlite3AutoLoadExtensions(db); - rc = sqlite3_errcode(db); - if( rc!=SQLITE_OK ){ - goto opendb_out; - } - } - -#ifdef SQLITE_ENABLE_FTS1 - if( !db->mallocFailed ){ - extern int sqlite3Fts1Init(sqlite3*); - rc = sqlite3Fts1Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_FTS2 - if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int sqlite3Fts2Init(sqlite3*); - rc = sqlite3Fts2Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */ - if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = sqlite3Fts3Init(db); - } -#endif - -#ifdef SQLITE_ENABLE_ICU - if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = sqlite3IcuInit(db); - } -#endif - -#ifdef SQLITE_ENABLE_RTREE - if( !db->mallocFailed && rc==SQLITE_OK){ - rc = sqlite3RtreeInit(db); - } -#endif - -#ifdef SQLITE_ENABLE_DBSTAT_VTAB - if( !db->mallocFailed && rc==SQLITE_OK){ - rc = sqlite3DbstatRegister(db); - } -#endif - -#ifdef SQLITE_ENABLE_JSON1 - if( !db->mallocFailed && rc==SQLITE_OK){ - rc = sqlite3Json1Init(db); - } -#endif - - /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking - ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking - ** mode. Doing nothing at all also makes NORMAL the default. - */ -#ifdef SQLITE_DEFAULT_LOCKING_MODE - db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; - sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), - SQLITE_DEFAULT_LOCKING_MODE); -#endif - - if( rc ) sqlite3Error(db, rc); - - /* Enable the lookaside-malloc subsystem */ - setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, - sqlite3GlobalConfig.nLookaside); - - sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); - -opendb_out: - if( db ){ - assert( db->mutex!=0 || isThreadsafe==0 - || sqlite3GlobalConfig.bFullMutex==0 ); - sqlite3_mutex_leave(db->mutex); - } - rc = sqlite3_errcode(db); - assert( db!=0 || rc==SQLITE_NOMEM ); - if( rc==SQLITE_NOMEM ){ - sqlite3_close(db); - db = 0; - }else if( rc!=SQLITE_OK ){ - db->magic = SQLITE_MAGIC_SICK; - } - *ppDb = db; -#ifdef SQLITE_ENABLE_SQLLOG - if( sqlite3GlobalConfig.xSqllog ){ - /* Opening a db handle. Fourth parameter is passed 0. */ - void *pArg = sqlite3GlobalConfig.pSqllogArg; - sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); - } -#endif -#if defined(SQLITE_HAS_CODEC) - if( rc==SQLITE_OK ){ - const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey"); - if( zHexKey && zHexKey[0] ){ - u8 iByte; - int i; - char zKey[40]; - for(i=0, iByte=0; imutex); - assert( !db->mallocFailed ); - rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Register a new collation sequence with the database handle db. -*/ -SQLITE_API int sqlite3_create_collation16( - sqlite3* db, - const void *zName, - int enc, - void* pCtx, - int(*xCompare)(void*,int,const void*,int,const void*) -){ - int rc = SQLITE_OK; - char *zName8; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - assert( !db->mallocFailed ); - zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); - if( zName8 ){ - rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); - sqlite3DbFree(db, zName8); - } - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} -#endif /* SQLITE_OMIT_UTF16 */ - -/* -** Register a collation sequence factory callback with the database handle -** db. Replace any previously installed collation sequence factory. -*/ -SQLITE_API int sqlite3_collation_needed( - sqlite3 *db, - void *pCollNeededArg, - void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - db->xCollNeeded = xCollNeeded; - db->xCollNeeded16 = 0; - db->pCollNeededArg = pCollNeededArg; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -#ifndef SQLITE_OMIT_UTF16 -/* -** Register a collation sequence factory callback with the database handle -** db. Replace any previously installed collation sequence factory. -*/ -SQLITE_API int sqlite3_collation_needed16( - sqlite3 *db, - void *pCollNeededArg, - void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) -){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - db->xCollNeeded = 0; - db->xCollNeeded16 = xCollNeeded16; - db->pCollNeededArg = pCollNeededArg; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} -#endif /* SQLITE_OMIT_UTF16 */ - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** This function is now an anachronism. It used to be used to recover from a -** malloc() failure, but SQLite now does this automatically. -*/ -SQLITE_API int sqlite3_global_recover(void){ - return SQLITE_OK; -} -#endif - -/* -** Test to see whether or not the database connection is in autocommit -** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on -** by default. Autocommit is disabled by a BEGIN statement and reenabled -** by the next COMMIT or ROLLBACK. -*/ -SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - return db->autoCommit; -} - -/* -** The following routines are substitutes for constants SQLITE_CORRUPT, -** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error -** constants. They serve two purposes: -** -** 1. Serve as a convenient place to set a breakpoint in a debugger -** to detect when version error conditions occurs. -** -** 2. Invoke sqlite3_log() to provide the source code location where -** a low-level error is first detected. -*/ -static int reportError(int iErr, int lineno, const char *zType){ - sqlite3_log(iErr, "%s at line %d of [%.10s]", - zType, lineno, 20+sqlite3_sourceid()); - return iErr; -} -SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_CORRUPT, lineno, "database corruption"); -} -SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_MISUSE, lineno, "misuse"); -} -SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_CANTOPEN, lineno, "cannot open file"); -} -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3NomemError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_NOMEM, lineno, "OOM"); -} -SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){ - testcase( sqlite3GlobalConfig.xLog!=0 ); - return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); -} -#endif - -#ifndef SQLITE_OMIT_DEPRECATED -/* -** This is a convenience routine that makes sure that all thread-specific -** data for this thread has been deallocated. -** -** SQLite no longer uses thread-specific data so this routine is now a -** no-op. It is retained for historical compatibility. -*/ -SQLITE_API void sqlite3_thread_cleanup(void){ -} -#endif - -/* -** Return meta information about a specific column of a database table. -** See comment in sqlite3.h (sqlite.h.in) for details. -*/ -SQLITE_API int sqlite3_table_column_metadata( - sqlite3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if column is auto-increment */ -){ - int rc; - char *zErrMsg = 0; - Table *pTab = 0; - Column *pCol = 0; - int iCol = 0; - char const *zDataType = 0; - char const *zCollSeq = 0; - int notnull = 0; - int primarykey = 0; - int autoinc = 0; - - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ - return SQLITE_MISUSE_BKPT; - } -#endif - - /* Ensure the database schema has been loaded */ - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - rc = sqlite3Init(db, &zErrMsg); - if( SQLITE_OK!=rc ){ - goto error_out; - } - - /* Locate the table in question */ - pTab = sqlite3FindTable(db, zTableName, zDbName); - if( !pTab || pTab->pSelect ){ - pTab = 0; - goto error_out; - } - - /* Find the column for which info is requested */ - if( zColumnName==0 ){ - /* Query for existance of table only */ - }else{ - for(iCol=0; iColnCol; iCol++){ - pCol = &pTab->aCol[iCol]; - if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ - break; - } - } - if( iCol==pTab->nCol ){ - if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ - iCol = pTab->iPKey; - pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; - }else{ - pTab = 0; - goto error_out; - } - } - } - - /* The following block stores the meta information that will be returned - ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey - ** and autoinc. At this point there are two possibilities: - ** - ** 1. The specified column name was rowid", "oid" or "_rowid_" - ** and there is no explicitly declared IPK column. - ** - ** 2. The table is not a view and the column name identified an - ** explicitly declared column. Copy meta information from *pCol. - */ - if( pCol ){ - zDataType = sqlite3ColumnType(pCol,0); - zCollSeq = pCol->zColl; - notnull = pCol->notNull!=0; - primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; - autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; - }else{ - zDataType = "INTEGER"; - primarykey = 1; - } - if( !zCollSeq ){ - zCollSeq = sqlite3StrBINARY; - } - -error_out: - sqlite3BtreeLeaveAll(db); - - /* Whether the function call succeeded or failed, set the output parameters - ** to whatever their local counterparts contain. If an error did occur, - ** this has the effect of zeroing all output parameters. - */ - if( pzDataType ) *pzDataType = zDataType; - if( pzCollSeq ) *pzCollSeq = zCollSeq; - if( pNotNull ) *pNotNull = notnull; - if( pPrimaryKey ) *pPrimaryKey = primarykey; - if( pAutoinc ) *pAutoinc = autoinc; - - if( SQLITE_OK==rc && !pTab ){ - sqlite3DbFree(db, zErrMsg); - zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, - zColumnName); - rc = SQLITE_ERROR; - } - sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); - sqlite3DbFree(db, zErrMsg); - rc = sqlite3ApiExit(db, rc); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Sleep for a little while. Return the amount of time slept. -*/ -SQLITE_API int sqlite3_sleep(int ms){ - sqlite3_vfs *pVfs; - int rc; - pVfs = sqlite3_vfs_find(0); - if( pVfs==0 ) return 0; - - /* This function works in milliseconds, but the underlying OsSleep() - ** API uses microseconds. Hence the 1000's. - */ - rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); - return rc; -} - -/* -** Enable or disable the extended result codes. -*/ -SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - db->errMask = onoff ? 0xffffffff : 0xff; - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; -} - -/* -** Invoke the xFileControl method on a particular database. -*/ -SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ - int rc = SQLITE_ERROR; - Btree *pBtree; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -#endif - sqlite3_mutex_enter(db->mutex); - pBtree = sqlite3DbNameToBtree(db, zDbName); - if( pBtree ){ - Pager *pPager; - sqlite3_file *fd; - sqlite3BtreeEnter(pBtree); - pPager = sqlite3BtreePager(pBtree); - assert( pPager!=0 ); - fd = sqlite3PagerFile(pPager); - assert( fd!=0 ); - if( op==SQLITE_FCNTL_FILE_POINTER ){ - *(sqlite3_file**)pArg = fd; - rc = SQLITE_OK; - }else if( op==SQLITE_FCNTL_VFS_POINTER ){ - *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); - rc = SQLITE_OK; - }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ - *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); - rc = SQLITE_OK; - }else if( fd->pMethods ){ - rc = sqlite3OsFileControl(fd, op, pArg); - }else{ - rc = SQLITE_NOTFOUND; - } - sqlite3BtreeLeave(pBtree); - } - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** Interface to the testing logic. -*/ -SQLITE_API int sqlite3_test_control(int op, ...){ - int rc = 0; -#ifdef SQLITE_OMIT_BUILTIN_TEST - UNUSED_PARAMETER(op); -#else - va_list ap; - va_start(ap, op); - switch( op ){ - - /* - ** Save the current state of the PRNG. - */ - case SQLITE_TESTCTRL_PRNG_SAVE: { - sqlite3PrngSaveState(); - break; - } - - /* - ** Restore the state of the PRNG to the last state saved using - ** PRNG_SAVE. If PRNG_SAVE has never before been called, then - ** this verb acts like PRNG_RESET. - */ - case SQLITE_TESTCTRL_PRNG_RESTORE: { - sqlite3PrngRestoreState(); - break; - } - - /* - ** Reset the PRNG back to its uninitialized state. The next call - ** to sqlite3_randomness() will reseed the PRNG using a single call - ** to the xRandomness method of the default VFS. - */ - case SQLITE_TESTCTRL_PRNG_RESET: { - sqlite3_randomness(0,0); - break; - } - - /* - ** sqlite3_test_control(BITVEC_TEST, size, program) - ** - ** Run a test against a Bitvec object of size. The program argument - ** is an array of integers that defines the test. Return -1 on a - ** memory allocation error, 0 on success, or non-zero for an error. - ** See the sqlite3BitvecBuiltinTest() for additional information. - */ - case SQLITE_TESTCTRL_BITVEC_TEST: { - int sz = va_arg(ap, int); - int *aProg = va_arg(ap, int*); - rc = sqlite3BitvecBuiltinTest(sz, aProg); - break; - } - - /* - ** sqlite3_test_control(FAULT_INSTALL, xCallback) - ** - ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, - ** if xCallback is not NULL. - ** - ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) - ** is called immediately after installing the new callback and the return - ** value from sqlite3FaultSim(0) becomes the return from - ** sqlite3_test_control(). - */ - case SQLITE_TESTCTRL_FAULT_INSTALL: { - /* MSVC is picky about pulling func ptrs from va lists. - ** http://support.microsoft.com/kb/47961 - ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); - */ - typedef int(*TESTCALLBACKFUNC_t)(int); - sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); - rc = sqlite3FaultSim(0); - break; - } - - /* - ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) - ** - ** Register hooks to call to indicate which malloc() failures - ** are benign. - */ - case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { - typedef void (*void_function)(void); - void_function xBenignBegin; - void_function xBenignEnd; - xBenignBegin = va_arg(ap, void_function); - xBenignEnd = va_arg(ap, void_function); - sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); - break; - } - - /* - ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) - ** - ** Set the PENDING byte to the value in the argument, if X>0. - ** Make no changes if X==0. Return the value of the pending byte - ** as it existing before this routine was called. - ** - ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in - ** an incompatible database file format. Changing the PENDING byte - ** while any database connection is open results in undefined and - ** deleterious behavior. - */ - case SQLITE_TESTCTRL_PENDING_BYTE: { - rc = PENDING_BYTE; -#ifndef SQLITE_OMIT_WSD - { - unsigned int newVal = va_arg(ap, unsigned int); - if( newVal ) sqlite3PendingByte = newVal; - } -#endif - break; - } - - /* - ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) - ** - ** This action provides a run-time test to see whether or not - ** assert() was enabled at compile-time. If X is true and assert() - ** is enabled, then the return value is true. If X is true and - ** assert() is disabled, then the return value is zero. If X is - ** false and assert() is enabled, then the assertion fires and the - ** process aborts. If X is false and assert() is disabled, then the - ** return value is zero. - */ - case SQLITE_TESTCTRL_ASSERT: { - volatile int x = 0; - assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); - rc = x; - break; - } - - - /* - ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) - ** - ** This action provides a run-time test to see how the ALWAYS and - ** NEVER macros were defined at compile-time. - ** - ** The return value is ALWAYS(X). - ** - ** The recommended test is X==2. If the return value is 2, that means - ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the - ** default setting. If the return value is 1, then ALWAYS() is either - ** hard-coded to true or else it asserts if its argument is false. - ** The first behavior (hard-coded to true) is the case if - ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second - ** behavior (assert if the argument to ALWAYS() is false) is the case if - ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled. - ** - ** The run-time test procedure might look something like this: - ** - ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ - ** // ALWAYS() and NEVER() are no-op pass-through macros - ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ - ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. - ** }else{ - ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. - ** } - */ - case SQLITE_TESTCTRL_ALWAYS: { - int x = va_arg(ap,int); - rc = ALWAYS(x); - break; - } - - /* - ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); - ** - ** The integer returned reveals the byte-order of the computer on which - ** SQLite is running: - ** - ** 1 big-endian, determined at run-time - ** 10 little-endian, determined at run-time - ** 432101 big-endian, determined at compile-time - ** 123410 little-endian, determined at compile-time - */ - case SQLITE_TESTCTRL_BYTEORDER: { - rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) - ** - ** Set the nReserve size to N for the main database on the database - ** connection db. - */ - case SQLITE_TESTCTRL_RESERVE: { - sqlite3 *db = va_arg(ap, sqlite3*); - int x = va_arg(ap,int); - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); - sqlite3_mutex_leave(db->mutex); - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) - ** - ** Enable or disable various optimizations for testing purposes. The - ** argument N is a bitmask of optimizations to be disabled. For normal - ** operation N should be 0. The idea is that a test program (like the - ** SQL Logic Test or SLT test module) can run the same SQL multiple times - ** with various optimizations disabled to verify that the same answer - ** is obtained in every case. - */ - case SQLITE_TESTCTRL_OPTIMIZATIONS: { - sqlite3 *db = va_arg(ap, sqlite3*); - db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); - break; - } - -#ifdef SQLITE_N_KEYWORD - /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord) - ** - ** If zWord is a keyword recognized by the parser, then return the - ** number of keywords. Or if zWord is not a keyword, return 0. - ** - ** This test feature is only available in the amalgamation since - ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite - ** is built using separate source files. - */ - case SQLITE_TESTCTRL_ISKEYWORD: { - const char *zWord = va_arg(ap, const char*); - int n = sqlite3Strlen30(zWord); - rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0; - break; - } -#endif - - /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); - ** - ** Pass pFree into sqlite3ScratchFree(). - ** If sz>0 then allocate a scratch buffer into pNew. - */ - case SQLITE_TESTCTRL_SCRATCHMALLOC: { - void *pFree, **ppNew; - int sz; - sz = va_arg(ap, int); - ppNew = va_arg(ap, void**); - pFree = va_arg(ap, void*); - if( sz ) *ppNew = sqlite3ScratchMalloc(sz); - sqlite3ScratchFree(pFree); - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); - ** - ** If parameter onoff is non-zero, configure the wrappers so that all - ** subsequent calls to localtime() and variants fail. If onoff is zero, - ** undo this setting. - */ - case SQLITE_TESTCTRL_LOCALTIME_FAULT: { - sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); - ** - ** Set or clear a flag that indicates that the database file is always well- - ** formed and never corrupt. This flag is clear by default, indicating that - ** database files might have arbitrary corruption. Setting the flag during - ** testing causes certain assert() statements in the code to be activated - ** that demonstrat invariants on well-formed database files. - */ - case SQLITE_TESTCTRL_NEVER_CORRUPT: { - sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); - break; - } - - /* Set the threshold at which OP_Once counters reset back to zero. - ** By default this is 0x7ffffffe (over 2 billion), but that value is - ** too big to test in a reasonable amount of time, so this control is - ** provided to set a small and easily reachable reset value. - */ - case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { - sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); - ** - ** Set the VDBE coverage callback function to xCallback with context - ** pointer ptr. - */ - case SQLITE_TESTCTRL_VDBE_COVERAGE: { -#ifdef SQLITE_VDBE_COVERAGE - typedef void (*branch_callback)(void*,int,u8,u8); - sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); - sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); -#endif - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ - case SQLITE_TESTCTRL_SORTER_MMAP: { - sqlite3 *db = va_arg(ap, sqlite3*); - db->nMaxSorterMmap = va_arg(ap, int); - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); - ** - ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if - ** not. - */ - case SQLITE_TESTCTRL_ISINIT: { - if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; - break; - } - - /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); - ** - ** This test control is used to create imposter tables. "db" is a pointer - ** to the database connection. dbName is the database name (ex: "main" or - ** "temp") which will receive the imposter. "onOff" turns imposter mode on - ** or off. "tnum" is the root page of the b-tree to which the imposter - ** table should connect. - ** - ** Enable imposter mode only when the schema has already been parsed. Then - ** run a single CREATE TABLE statement to construct the imposter table in - ** the parsed schema. Then turn imposter mode back off again. - ** - ** If onOff==0 and tnum>0 then reset the schema for all databases, causing - ** the schema to be reparsed the next time it is needed. This has the - ** effect of erasing all imposter tables. - */ - case SQLITE_TESTCTRL_IMPOSTER: { - sqlite3 *db = va_arg(ap, sqlite3*); - sqlite3_mutex_enter(db->mutex); - db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); - db->init.busy = db->init.imposterTable = va_arg(ap,int); - db->init.newTnum = va_arg(ap,int); - if( db->init.busy==0 && db->init.newTnum>0 ){ - sqlite3ResetAllSchemasOfConnection(db); - } - sqlite3_mutex_leave(db->mutex); - break; - } - } - va_end(ap); -#endif /* SQLITE_OMIT_BUILTIN_TEST */ - return rc; -} - -/* -** This is a utility routine, useful to VFS implementations, that checks -** to see if a database file was a URI that contained a specific query -** parameter, and if so obtains the value of the query parameter. -** -** The zFilename argument is the filename pointer passed into the xOpen() -** method of a VFS implementation. The zParam argument is the name of the -** query parameter we seek. This routine returns the value of the zParam -** parameter if it exists. If the parameter does not exist, this routine -** returns a NULL pointer. -*/ -SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ - if( zFilename==0 || zParam==0 ) return 0; - zFilename += sqlite3Strlen30(zFilename) + 1; - while( zFilename[0] ){ - int x = strcmp(zFilename, zParam); - zFilename += sqlite3Strlen30(zFilename) + 1; - if( x==0 ) return zFilename; - zFilename += sqlite3Strlen30(zFilename) + 1; - } - return 0; -} - -/* -** Return a boolean value for a query parameter. -*/ -SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ - const char *z = sqlite3_uri_parameter(zFilename, zParam); - bDflt = bDflt!=0; - return z ? sqlite3GetBoolean(z, bDflt) : bDflt; -} - -/* -** Return a 64-bit integer value for a query parameter. -*/ -SQLITE_API sqlite3_int64 sqlite3_uri_int64( - const char *zFilename, /* Filename as passed to xOpen */ - const char *zParam, /* URI parameter sought */ - sqlite3_int64 bDflt /* return if parameter is missing */ -){ - const char *z = sqlite3_uri_parameter(zFilename, zParam); - sqlite3_int64 v; - if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ - bDflt = v; - } - return bDflt; -} - -/* -** Return the Btree pointer identified by zDbName. Return NULL if not found. -*/ -SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ - int i; - for(i=0; inDb; i++){ - if( db->aDb[i].pBt - && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zDbSName)==0) - ){ - return db->aDb[i].pBt; - } - } - return 0; -} - -/* -** Return the filename of the database associated with a database -** connection. -*/ -SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ - Btree *pBt; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return 0; - } -#endif - pBt = sqlite3DbNameToBtree(db, zDbName); - return pBt ? sqlite3BtreeGetFilename(pBt) : 0; -} - -/* -** Return 1 if database is read-only or 0 if read/write. Return -1 if -** no such database exists. -*/ -SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ - Btree *pBt; -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - (void)SQLITE_MISUSE_BKPT; - return -1; - } -#endif - pBt = sqlite3DbNameToBtree(db, zDbName); - return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; -} - -#ifdef SQLITE_ENABLE_SNAPSHOT -/* -** Obtain a snapshot handle for the snapshot of database zDb currently -** being read by handle db. -*/ -SQLITE_API int sqlite3_snapshot_get( - sqlite3 *db, - const char *zDb, - sqlite3_snapshot **ppSnapshot -){ - int rc = SQLITE_ERROR; -#ifndef SQLITE_OMIT_WAL - int iDb; - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - - iDb = sqlite3FindDbName(db, zDb); - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); - } - } - } - - sqlite3_mutex_leave(db->mutex); -#endif /* SQLITE_OMIT_WAL */ - return rc; -} - -/* -** Open a read-transaction on the snapshot idendified by pSnapshot. -*/ -SQLITE_API int sqlite3_snapshot_open( - sqlite3 *db, - const char *zDb, - sqlite3_snapshot *pSnapshot -){ - int rc = SQLITE_ERROR; -#ifndef SQLITE_OMIT_WAL - -#ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) ){ - return SQLITE_MISUSE_BKPT; - } -#endif - sqlite3_mutex_enter(db->mutex); - if( db->autoCommit==0 ){ - int iDb; - iDb = sqlite3FindDbName(db, zDb); - if( iDb==0 || iDb>1 ){ - Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); - } - } - } - } - - sqlite3_mutex_leave(db->mutex); -#endif /* SQLITE_OMIT_WAL */ - return rc; -} - -/* -** Free a snapshot handle obtained from sqlite3_snapshot_get(). -*/ -SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ - sqlite3_free(pSnapshot); -} -#endif /* SQLITE_ENABLE_SNAPSHOT */ - -/************** End of main.c ************************************************/ -/************** Begin file notify.c ******************************************/ -/* -** 2009 March 3 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the implementation of the sqlite3_unlock_notify() -** API method and its associated functionality. -*/ -/* #include "sqliteInt.h" */ -/* #include "btreeInt.h" */ - -/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ -#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY - -/* -** Public interfaces: -** -** sqlite3ConnectionBlocked() -** sqlite3ConnectionUnlocked() -** sqlite3ConnectionClosed() -** sqlite3_unlock_notify() -*/ - -#define assertMutexHeld() \ - assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ) - -/* -** Head of a linked list of all sqlite3 objects created by this process -** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection -** is not NULL. This variable may only accessed while the STATIC_MASTER -** mutex is held. -*/ -static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0; - -#ifndef NDEBUG -/* -** This function is a complex assert() that verifies the following -** properties of the blocked connections list: -** -** 1) Each entry in the list has a non-NULL value for either -** pUnlockConnection or pBlockingConnection, or both. -** -** 2) All entries in the list that share a common value for -** xUnlockNotify are grouped together. -** -** 3) If the argument db is not NULL, then none of the entries in the -** blocked connections list have pUnlockConnection or pBlockingConnection -** set to db. This is used when closing connection db. -*/ -static void checkListProperties(sqlite3 *db){ - sqlite3 *p; - for(p=sqlite3BlockedList; p; p=p->pNextBlocked){ - int seen = 0; - sqlite3 *p2; - - /* Verify property (1) */ - assert( p->pUnlockConnection || p->pBlockingConnection ); - - /* Verify property (2) */ - for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ - if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; - assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); - assert( db==0 || p->pUnlockConnection!=db ); - assert( db==0 || p->pBlockingConnection!=db ); - } - } -} -#else -# define checkListProperties(x) -#endif - -/* -** Remove connection db from the blocked connections list. If connection -** db is not currently a part of the list, this function is a no-op. -*/ -static void removeFromBlockedList(sqlite3 *db){ - sqlite3 **pp; - assertMutexHeld(); - for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ - if( *pp==db ){ - *pp = (*pp)->pNextBlocked; - break; - } - } -} - -/* -** Add connection db to the blocked connections list. It is assumed -** that it is not already a part of the list. -*/ -static void addToBlockedList(sqlite3 *db){ - sqlite3 **pp; - assertMutexHeld(); - for( - pp=&sqlite3BlockedList; - *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; - pp=&(*pp)->pNextBlocked - ); - db->pNextBlocked = *pp; - *pp = db; -} - -/* -** Obtain the STATIC_MASTER mutex. -*/ -static void enterMutex(void){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); - checkListProperties(0); -} - -/* -** Release the STATIC_MASTER mutex. -*/ -static void leaveMutex(void){ - assertMutexHeld(); - checkListProperties(0); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); -} - -/* -** Register an unlock-notify callback. -** -** This is called after connection "db" has attempted some operation -** but has received an SQLITE_LOCKED error because another connection -** (call it pOther) in the same process was busy using the same shared -** cache. pOther is found by looking at db->pBlockingConnection. -** -** If there is no blocking connection, the callback is invoked immediately, -** before this routine returns. -** -** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate -** a deadlock. -** -** Otherwise, make arrangements to invoke xNotify when pOther drops -** its locks. -** -** Each call to this routine overrides any prior callbacks registered -** on the same "db". If xNotify==0 then any prior callbacks are immediately -** cancelled. -*/ -SQLITE_API int sqlite3_unlock_notify( - sqlite3 *db, - void (*xNotify)(void **, int), - void *pArg -){ - int rc = SQLITE_OK; - - sqlite3_mutex_enter(db->mutex); - enterMutex(); - - if( xNotify==0 ){ - removeFromBlockedList(db); - db->pBlockingConnection = 0; - db->pUnlockConnection = 0; - db->xUnlockNotify = 0; - db->pUnlockArg = 0; - }else if( 0==db->pBlockingConnection ){ - /* The blocking transaction has been concluded. Or there never was a - ** blocking transaction. In either case, invoke the notify callback - ** immediately. - */ - xNotify(&pArg, 1); - }else{ - sqlite3 *p; - - for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} - if( p ){ - rc = SQLITE_LOCKED; /* Deadlock detected. */ - }else{ - db->pUnlockConnection = db->pBlockingConnection; - db->xUnlockNotify = xNotify; - db->pUnlockArg = pArg; - removeFromBlockedList(db); - addToBlockedList(db); - } - } - - leaveMutex(); - assert( !db->mallocFailed ); - sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); - sqlite3_mutex_leave(db->mutex); - return rc; -} - -/* -** This function is called while stepping or preparing a statement -** associated with connection db. The operation will return SQLITE_LOCKED -** to the user because it requires a lock that will not be available -** until connection pBlocker concludes its current transaction. -*/ -SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ - enterMutex(); - if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ - addToBlockedList(db); - } - db->pBlockingConnection = pBlocker; - leaveMutex(); -} - -/* -** This function is called when -** the transaction opened by database db has just finished. Locks held -** by database connection db have been released. -** -** This function loops through each entry in the blocked connections -** list and does the following: -** -** 1) If the sqlite3.pBlockingConnection member of a list entry is -** set to db, then set pBlockingConnection=0. -** -** 2) If the sqlite3.pUnlockConnection member of a list entry is -** set to db, then invoke the configured unlock-notify callback and -** set pUnlockConnection=0. -** -** 3) If the two steps above mean that pBlockingConnection==0 and -** pUnlockConnection==0, remove the entry from the blocked connections -** list. -*/ -SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ - void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ - int nArg = 0; /* Number of entries in aArg[] */ - sqlite3 **pp; /* Iterator variable */ - void **aArg; /* Arguments to the unlock callback */ - void **aDyn = 0; /* Dynamically allocated space for aArg[] */ - void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ - - aArg = aStatic; - enterMutex(); /* Enter STATIC_MASTER mutex */ - - /* This loop runs once for each entry in the blocked-connections list. */ - for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ - sqlite3 *p = *pp; - - /* Step 1. */ - if( p->pBlockingConnection==db ){ - p->pBlockingConnection = 0; - } - - /* Step 2. */ - if( p->pUnlockConnection==db ){ - assert( p->xUnlockNotify ); - if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){ - xUnlockNotify(aArg, nArg); - nArg = 0; - } - - sqlite3BeginBenignMalloc(); - assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); - assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); - if( (!aDyn && nArg==(int)ArraySize(aStatic)) - || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) - ){ - /* The aArg[] array needs to grow. */ - void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); - if( pNew ){ - memcpy(pNew, aArg, nArg*sizeof(void *)); - sqlite3_free(aDyn); - aDyn = aArg = pNew; - }else{ - /* This occurs when the array of context pointers that need to - ** be passed to the unlock-notify callback is larger than the - ** aStatic[] array allocated on the stack and the attempt to - ** allocate a larger array from the heap has failed. - ** - ** This is a difficult situation to handle. Returning an error - ** code to the caller is insufficient, as even if an error code - ** is returned the transaction on connection db will still be - ** closed and the unlock-notify callbacks on blocked connections - ** will go unissued. This might cause the application to wait - ** indefinitely for an unlock-notify callback that will never - ** arrive. - ** - ** Instead, invoke the unlock-notify callback with the context - ** array already accumulated. We can then clear the array and - ** begin accumulating any further context pointers without - ** requiring any dynamic allocation. This is sub-optimal because - ** it means that instead of one callback with a large array of - ** context pointers the application will receive two or more - ** callbacks with smaller arrays of context pointers, which will - ** reduce the applications ability to prioritize multiple - ** connections. But it is the best that can be done under the - ** circumstances. - */ - xUnlockNotify(aArg, nArg); - nArg = 0; - } - } - sqlite3EndBenignMalloc(); - - aArg[nArg++] = p->pUnlockArg; - xUnlockNotify = p->xUnlockNotify; - p->pUnlockConnection = 0; - p->xUnlockNotify = 0; - p->pUnlockArg = 0; - } - - /* Step 3. */ - if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){ - /* Remove connection p from the blocked connections list. */ - *pp = p->pNextBlocked; - p->pNextBlocked = 0; - }else{ - pp = &p->pNextBlocked; - } - } - - if( nArg!=0 ){ - xUnlockNotify(aArg, nArg); - } - sqlite3_free(aDyn); - leaveMutex(); /* Leave STATIC_MASTER mutex */ -} - -/* -** This is called when the database connection passed as an argument is -** being closed. The connection is removed from the blocked list. -*/ -SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ - sqlite3ConnectionUnlocked(db); - enterMutex(); - removeFromBlockedList(db); - checkListProperties(db); - leaveMutex(); -} -#endif - -/************** End of notify.c **********************************************/ -/************** Begin file fts3.c ********************************************/ -/* -** 2006 Oct 10 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This is an SQLite module implementing full-text search. -*/ - -/* -** The code in this file is only compiled if: -** -** * The FTS3 module is being built as an extension -** (in which case SQLITE_CORE is not defined), or -** -** * The FTS3 module is being built into the core of -** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). -*/ - -/* The full-text index is stored in a series of b+tree (-like) -** structures called segments which map terms to doclists. The -** structures are like b+trees in layout, but are constructed from the -** bottom up in optimal fashion and are not updatable. Since trees -** are built from the bottom up, things will be described from the -** bottom up. -** -** -**** Varints **** -** The basic unit of encoding is a variable-length integer called a -** varint. We encode variable-length integers in little-endian order -** using seven bits * per byte as follows: -** -** KEY: -** A = 0xxxxxxx 7 bits of data and one flag bit -** B = 1xxxxxxx 7 bits of data and one flag bit -** -** 7 bits - A -** 14 bits - BA -** 21 bits - BBA -** and so on. -** -** This is similar in concept to how sqlite encodes "varints" but -** the encoding is not the same. SQLite varints are big-endian -** are are limited to 9 bytes in length whereas FTS3 varints are -** little-endian and can be up to 10 bytes in length (in theory). -** -** Example encodings: -** -** 1: 0x01 -** 127: 0x7f -** 128: 0x81 0x00 -** -** -**** Document lists **** -** A doclist (document list) holds a docid-sorted list of hits for a -** given term. Doclists hold docids and associated token positions. -** A docid is the unique integer identifier for a single document. -** A position is the index of a word within the document. The first -** word of the document has a position of 0. -** -** FTS3 used to optionally store character offsets using a compile-time -** option. But that functionality is no longer supported. -** -** A doclist is stored like this: -** -** array { -** varint docid; (delta from previous doclist) -** array { (position list for column 0) -** varint position; (2 more than the delta from previous position) -** } -** array { -** varint POS_COLUMN; (marks start of position list for new column) -** varint column; (index of new column) -** array { -** varint position; (2 more than the delta from previous position) -** } -** } -** varint POS_END; (marks end of positions for this document. -** } -** -** Here, array { X } means zero or more occurrences of X, adjacent in -** memory. A "position" is an index of a token in the token stream -** generated by the tokenizer. Note that POS_END and POS_COLUMN occur -** in the same logical place as the position element, and act as sentinals -** ending a position list array. POS_END is 0. POS_COLUMN is 1. -** The positions numbers are not stored literally but rather as two more -** than the difference from the prior position, or the just the position plus -** 2 for the first position. Example: -** -** label: A B C D E F G H I J K -** value: 123 5 9 1 1 14 35 0 234 72 0 -** -** The 123 value is the first docid. For column zero in this document -** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 -** at D signals the start of a new column; the 1 at E indicates that the -** new column is column number 1. There are two positions at 12 and 45 -** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The -** 234 at I is the delta to next docid (357). It has one position 70 -** (72-2) and then terminates with the 0 at K. -** -** A "position-list" is the list of positions for multiple columns for -** a single docid. A "column-list" is the set of positions for a single -** column. Hence, a position-list consists of one or more column-lists, -** a document record consists of a docid followed by a position-list and -** a doclist consists of one or more document records. -** -** A bare doclist omits the position information, becoming an -** array of varint-encoded docids. -** -**** Segment leaf nodes **** -** Segment leaf nodes store terms and doclists, ordered by term. Leaf -** nodes are written using LeafWriter, and read using LeafReader (to -** iterate through a single leaf node's data) and LeavesReader (to -** iterate through a segment's entire leaf layer). Leaf nodes have -** the format: -** -** varint iHeight; (height from leaf level, always 0) -** varint nTerm; (length of first term) -** char pTerm[nTerm]; (content of first term) -** varint nDoclist; (length of term's associated doclist) -** char pDoclist[nDoclist]; (content of doclist) -** array { -** (further terms are delta-encoded) -** varint nPrefix; (length of prefix shared with previous term) -** varint nSuffix; (length of unshared suffix) -** char pTermSuffix[nSuffix];(unshared suffix of next term) -** varint nDoclist; (length of term's associated doclist) -** char pDoclist[nDoclist]; (content of doclist) -** } -** -** Here, array { X } means zero or more occurrences of X, adjacent in -** memory. -** -** Leaf nodes are broken into blocks which are stored contiguously in -** the %_segments table in sorted order. This means that when the end -** of a node is reached, the next term is in the node with the next -** greater node id. -** -** New data is spilled to a new leaf node when the current node -** exceeds LEAF_MAX bytes (default 2048). New data which itself is -** larger than STANDALONE_MIN (default 1024) is placed in a standalone -** node (a leaf node with a single term and doclist). The goal of -** these settings is to pack together groups of small doclists while -** making it efficient to directly access large doclists. The -** assumption is that large doclists represent terms which are more -** likely to be query targets. -** -** TODO(shess) It may be useful for blocking decisions to be more -** dynamic. For instance, it may make more sense to have a 2.5k leaf -** node rather than splitting into 2k and .5k nodes. My intuition is -** that this might extend through 2x or 4x the pagesize. -** -** -**** Segment interior nodes **** -** Segment interior nodes store blockids for subtree nodes and terms -** to describe what data is stored by the each subtree. Interior -** nodes are written using InteriorWriter, and read using -** InteriorReader. InteriorWriters are created as needed when -** SegmentWriter creates new leaf nodes, or when an interior node -** itself grows too big and must be split. The format of interior -** nodes: -** -** varint iHeight; (height from leaf level, always >0) -** varint iBlockid; (block id of node's leftmost subtree) -** optional { -** varint nTerm; (length of first term) -** char pTerm[nTerm]; (content of first term) -** array { -** (further terms are delta-encoded) -** varint nPrefix; (length of shared prefix with previous term) -** varint nSuffix; (length of unshared suffix) -** char pTermSuffix[nSuffix]; (unshared suffix of next term) -** } -** } -** -** Here, optional { X } means an optional element, while array { X } -** means zero or more occurrences of X, adjacent in memory. -** -** An interior node encodes n terms separating n+1 subtrees. The -** subtree blocks are contiguous, so only the first subtree's blockid -** is encoded. The subtree at iBlockid will contain all terms less -** than the first term encoded (or all terms if no term is encoded). -** Otherwise, for terms greater than or equal to pTerm[i] but less -** than pTerm[i+1], the subtree for that term will be rooted at -** iBlockid+i. Interior nodes only store enough term data to -** distinguish adjacent children (if the rightmost term of the left -** child is "something", and the leftmost term of the right child is -** "wicked", only "w" is stored). -** -** New data is spilled to a new interior node at the same height when -** the current node exceeds INTERIOR_MAX bytes (default 2048). -** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing -** interior nodes and making the tree too skinny. The interior nodes -** at a given height are naturally tracked by interior nodes at -** height+1, and so on. -** -** -**** Segment directory **** -** The segment directory in table %_segdir stores meta-information for -** merging and deleting segments, and also the root node of the -** segment's tree. -** -** The root node is the top node of the segment's tree after encoding -** the entire segment, restricted to ROOT_MAX bytes (default 1024). -** This could be either a leaf node or an interior node. If the top -** node requires more than ROOT_MAX bytes, it is flushed to %_segments -** and a new root interior node is generated (which should always fit -** within ROOT_MAX because it only needs space for 2 varints, the -** height and the blockid of the previous root). -** -** The meta-information in the segment directory is: -** level - segment level (see below) -** idx - index within level -** - (level,idx uniquely identify a segment) -** start_block - first leaf node -** leaves_end_block - last leaf node -** end_block - last block (including interior nodes) -** root - contents of root node -** -** If the root node is a leaf node, then start_block, -** leaves_end_block, and end_block are all 0. -** -** -**** Segment merging **** -** To amortize update costs, segments are grouped into levels and -** merged in batches. Each increase in level represents exponentially -** more documents. -** -** New documents (actually, document updates) are tokenized and -** written individually (using LeafWriter) to a level 0 segment, with -** incrementing idx. When idx reaches MERGE_COUNT (default 16), all -** level 0 segments are merged into a single level 1 segment. Level 1 -** is populated like level 0, and eventually MERGE_COUNT level 1 -** segments are merged to a single level 2 segment (representing -** MERGE_COUNT^2 updates), and so on. -** -** A segment merge traverses all segments at a given level in -** parallel, performing a straightforward sorted merge. Since segment -** leaf nodes are written in to the %_segments table in order, this -** merge traverses the underlying sqlite disk structures efficiently. -** After the merge, all segment blocks from the merged level are -** deleted. -** -** MERGE_COUNT controls how often we merge segments. 16 seems to be -** somewhat of a sweet spot for insertion performance. 32 and 64 show -** very similar performance numbers to 16 on insertion, though they're -** a tiny bit slower (perhaps due to more overhead in merge-time -** sorting). 8 is about 20% slower than 16, 4 about 50% slower than -** 16, 2 about 66% slower than 16. -** -** At query time, high MERGE_COUNT increases the number of segments -** which need to be scanned and merged. For instance, with 100k docs -** inserted: -** -** MERGE_COUNT segments -** 16 25 -** 8 12 -** 4 10 -** 2 6 -** -** This appears to have only a moderate impact on queries for very -** frequent terms (which are somewhat dominated by segment merge -** costs), and infrequent and non-existent terms still seem to be fast -** even with many segments. -** -** TODO(shess) That said, it would be nice to have a better query-side -** argument for MERGE_COUNT of 16. Also, it is possible/likely that -** optimizations to things like doclist merging will swing the sweet -** spot around. -** -** -** -**** Handling of deletions and updates **** -** Since we're using a segmented structure, with no docid-oriented -** index into the term index, we clearly cannot simply update the term -** index when a document is deleted or updated. For deletions, we -** write an empty doclist (varint(docid) varint(POS_END)), for updates -** we simply write the new doclist. Segment merges overwrite older -** data for a particular docid with newer data, so deletes or updates -** will eventually overtake the earlier data and knock it out. The -** query logic likewise merges doclists so that newer data knocks out -** older data. -*/ - -/************** Include fts3Int.h in the middle of fts3.c ********************/ -/************** Begin file fts3Int.h *****************************************/ -/* -** 2009 Nov 12 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -*/ -#ifndef _FTSINT_H -#define _FTSINT_H - -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif - -/* FTS3/FTS4 require virtual tables */ -#ifdef SQLITE_OMIT_VIRTUALTABLE -# undef SQLITE_ENABLE_FTS3 -# undef SQLITE_ENABLE_FTS4 -#endif - -/* -** FTS4 is really an extension for FTS3. It is enabled using the -** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all -** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. -*/ -#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) -# define SQLITE_ENABLE_FTS3 -#endif - -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* If not building as part of the core, include sqlite3ext.h. */ -#ifndef SQLITE_CORE -/* # include "sqlite3ext.h" */ -SQLITE_EXTENSION_INIT3 -#endif - -/* #include "sqlite3.h" */ -/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ -/************** Begin file fts3_tokenizer.h **********************************/ -/* -** 2006 July 10 -** -** The author disclaims copyright to this source code. -** -************************************************************************* -** Defines the interface to tokenizers used by fulltext-search. There -** are three basic components: -** -** sqlite3_tokenizer_module is a singleton defining the tokenizer -** interface functions. This is essentially the class structure for -** tokenizers. -** -** sqlite3_tokenizer is used to define a particular tokenizer, perhaps -** including customization information defined at creation time. -** -** sqlite3_tokenizer_cursor is generated by a tokenizer to generate -** tokens from a particular input. -*/ -#ifndef _FTS3_TOKENIZER_H_ -#define _FTS3_TOKENIZER_H_ - -/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. -** If tokenizers are to be allowed to call sqlite3_*() functions, then -** we will need a way to register the API consistently. -*/ -/* #include "sqlite3.h" */ - -/* -** Structures used by the tokenizer interface. When a new tokenizer -** implementation is registered, the caller provides a pointer to -** an sqlite3_tokenizer_module containing pointers to the callback -** functions that make up an implementation. -** -** When an fts3 table is created, it passes any arguments passed to -** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the -** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer -** implementation. The xCreate() function in turn returns an -** sqlite3_tokenizer structure representing the specific tokenizer to -** be used for the fts3 table (customized by the tokenizer clause arguments). -** -** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() -** method is called. It returns an sqlite3_tokenizer_cursor object -** that may be used to tokenize a specific input buffer based on -** the tokenization rules supplied by a specific sqlite3_tokenizer -** object. -*/ -typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; -typedef struct sqlite3_tokenizer sqlite3_tokenizer; -typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; - -struct sqlite3_tokenizer_module { - - /* - ** Structure version. Should always be set to 0 or 1. - */ - int iVersion; - - /* - ** Create a new tokenizer. The values in the argv[] array are the - ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL - ** TABLE statement that created the fts3 table. For example, if - ** the following SQL is executed: - ** - ** CREATE .. USING fts3( ... , tokenizer arg1 arg2) - ** - ** then argc is set to 2, and the argv[] array contains pointers - ** to the strings "arg1" and "arg2". - ** - ** This method should return either SQLITE_OK (0), or an SQLite error - ** code. If SQLITE_OK is returned, then *ppTokenizer should be set - ** to point at the newly created tokenizer structure. The generic - ** sqlite3_tokenizer.pModule variable should not be initialized by - ** this callback. The caller will do so. - */ - int (*xCreate)( - int argc, /* Size of argv array */ - const char *const*argv, /* Tokenizer argument strings */ - sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ - ); - - /* - ** Destroy an existing tokenizer. The fts3 module calls this method - ** exactly once for each successful call to xCreate(). - */ - int (*xDestroy)(sqlite3_tokenizer *pTokenizer); - - /* - ** Create a tokenizer cursor to tokenize an input buffer. The caller - ** is responsible for ensuring that the input buffer remains valid - ** until the cursor is closed (using the xClose() method). - */ - int (*xOpen)( - sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ - const char *pInput, int nBytes, /* Input buffer */ - sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ - ); - - /* - ** Destroy an existing tokenizer cursor. The fts3 module calls this - ** method exactly once for each successful call to xOpen(). - */ - int (*xClose)(sqlite3_tokenizer_cursor *pCursor); - - /* - ** Retrieve the next token from the tokenizer cursor pCursor. This - ** method should either return SQLITE_OK and set the values of the - ** "OUT" variables identified below, or SQLITE_DONE to indicate that - ** the end of the buffer has been reached, or an SQLite error code. - ** - ** *ppToken should be set to point at a buffer containing the - ** normalized version of the token (i.e. after any case-folding and/or - ** stemming has been performed). *pnBytes should be set to the length - ** of this buffer in bytes. The input text that generated the token is - ** identified by the byte offsets returned in *piStartOffset and - ** *piEndOffset. *piStartOffset should be set to the index of the first - ** byte of the token in the input buffer. *piEndOffset should be set - ** to the index of the first byte just past the end of the token in - ** the input buffer. - ** - ** The buffer *ppToken is set to point at is managed by the tokenizer - ** implementation. It is only required to be valid until the next call - ** to xNext() or xClose(). - */ - /* TODO(shess) current implementation requires pInput to be - ** nul-terminated. This should either be fixed, or pInput/nBytes - ** should be converted to zInput. - */ - int (*xNext)( - sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ - const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ - int *piStartOffset, /* OUT: Byte offset of token in input buffer */ - int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ - int *piPosition /* OUT: Number of tokens returned before this one */ - ); - - /*********************************************************************** - ** Methods below this point are only available if iVersion>=1. - */ - - /* - ** Configure the language id of a tokenizer cursor. - */ - int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); -}; - -struct sqlite3_tokenizer { - const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ - /* Tokenizer implementations will typically add additional fields */ -}; - -struct sqlite3_tokenizer_cursor { - sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ - /* Tokenizer implementations will typically add additional fields */ -}; - -int fts3_global_term_cnt(int iTerm, int iCol); -int fts3_term_cnt(int iTerm, int iCol); - - -#endif /* _FTS3_TOKENIZER_H_ */ - -/************** End of fts3_tokenizer.h **************************************/ -/************** Continuing where we left off in fts3Int.h ********************/ -/************** Include fts3_hash.h in the middle of fts3Int.h ***************/ -/************** Begin file fts3_hash.h ***************************************/ -/* -** 2001 September 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This is the header file for the generic hash-table implementation -** used in SQLite. We've modified it slightly to serve as a standalone -** hash table implementation for the full-text indexing module. -** -*/ -#ifndef _FTS3_HASH_H_ -#define _FTS3_HASH_H_ - -/* Forward declarations of structures. */ -typedef struct Fts3Hash Fts3Hash; -typedef struct Fts3HashElem Fts3HashElem; - -/* A complete hash table is an instance of the following structure. -** The internals of this structure are intended to be opaque -- client -** code should not attempt to access or modify the fields of this structure -** directly. Change this structure only by using the routines below. -** However, many of the "procedures" and "functions" for modifying and -** accessing this structure are really macros, so we can't really make -** this structure opaque. -*/ -struct Fts3Hash { - char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ - char copyKey; /* True if copy of key made on insert */ - int count; /* Number of entries in this table */ - Fts3HashElem *first; /* The first element of the array */ - int htsize; /* Number of buckets in the hash table */ - struct _fts3ht { /* the hash table */ - int count; /* Number of entries with this hash */ - Fts3HashElem *chain; /* Pointer to first entry with this hash */ - } *ht; -}; - -/* Each element in the hash table is an instance of the following -** structure. All elements are stored on a single doubly-linked list. -** -** Again, this structure is intended to be opaque, but it can't really -** be opaque because it is used by macros. -*/ -struct Fts3HashElem { - Fts3HashElem *next, *prev; /* Next and previous elements in the table */ - void *data; /* Data associated with this element */ - void *pKey; int nKey; /* Key associated with this element */ -}; - -/* -** There are 2 different modes of operation for a hash table: -** -** FTS3_HASH_STRING pKey points to a string that is nKey bytes long -** (including the null-terminator, if any). Case -** is respected in comparisons. -** -** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. -** memcmp() is used to compare keys. -** -** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. -*/ -#define FTS3_HASH_STRING 1 -#define FTS3_HASH_BINARY 2 - -/* -** Access routines. To delete, insert a NULL pointer. -*/ -SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); -SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); -SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); -SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*); -SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); - -/* -** Shorthand for the functions above -*/ -#define fts3HashInit sqlite3Fts3HashInit -#define fts3HashInsert sqlite3Fts3HashInsert -#define fts3HashFind sqlite3Fts3HashFind -#define fts3HashClear sqlite3Fts3HashClear -#define fts3HashFindElem sqlite3Fts3HashFindElem - -/* -** Macros for looping over all elements of a hash table. The idiom is -** like this: -** -** Fts3Hash h; -** Fts3HashElem *p; -** ... -** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ -** SomeStructure *pData = fts3HashData(p); -** // do something with pData -** } -*/ -#define fts3HashFirst(H) ((H)->first) -#define fts3HashNext(E) ((E)->next) -#define fts3HashData(E) ((E)->data) -#define fts3HashKey(E) ((E)->pKey) -#define fts3HashKeysize(E) ((E)->nKey) - -/* -** Number of entries in a hash table -*/ -#define fts3HashCount(H) ((H)->count) - -#endif /* _FTS3_HASH_H_ */ - -/************** End of fts3_hash.h *******************************************/ -/************** Continuing where we left off in fts3Int.h ********************/ - -/* -** This constant determines the maximum depth of an FTS expression tree -** that the library will create and use. FTS uses recursion to perform -** various operations on the query tree, so the disadvantage of a large -** limit is that it may allow very large queries to use large amounts -** of stack space (perhaps causing a stack overflow). -*/ -#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH -# define SQLITE_FTS3_MAX_EXPR_DEPTH 12 -#endif - - -/* -** This constant controls how often segments are merged. Once there are -** FTS3_MERGE_COUNT segments of level N, they are merged into a single -** segment of level N+1. -*/ -#define FTS3_MERGE_COUNT 16 - -/* -** This is the maximum amount of data (in bytes) to store in the -** Fts3Table.pendingTerms hash table. Normally, the hash table is -** populated as documents are inserted/updated/deleted in a transaction -** and used to create a new segment when the transaction is committed. -** However if this limit is reached midway through a transaction, a new -** segment is created and the hash table cleared immediately. -*/ -#define FTS3_MAX_PENDING_DATA (1*1024*1024) - -/* -** Macro to return the number of elements in an array. SQLite has a -** similar macro called ArraySize(). Use a different name to avoid -** a collision when building an amalgamation with built-in FTS3. -*/ -#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) - - -#ifndef MIN -# define MIN(x,y) ((x)<(y)?(x):(y)) -#endif -#ifndef MAX -# define MAX(x,y) ((x)>(y)?(x):(y)) -#endif - -/* -** Maximum length of a varint encoded integer. The varint format is different -** from that used by SQLite, so the maximum length is 10, not 9. -*/ -#define FTS3_VARINT_MAX 10 - -/* -** FTS4 virtual tables may maintain multiple indexes - one index of all terms -** in the document set and zero or more prefix indexes. All indexes are stored -** as one or more b+-trees in the %_segments and %_segdir tables. -** -** It is possible to determine which index a b+-tree belongs to based on the -** value stored in the "%_segdir.level" column. Given this value L, the index -** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with -** level values between 0 and 1023 (inclusive) belong to index 0, all levels -** between 1024 and 2047 to index 1, and so on. -** -** It is considered impossible for an index to use more than 1024 levels. In -** theory though this may happen, but only after at least -** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables. -*/ -#define FTS3_SEGDIR_MAXLEVEL 1024 -#define FTS3_SEGDIR_MAXLEVEL_STR "1024" - -/* -** The testcase() macro is only used by the amalgamation. If undefined, -** make it a no-op. -*/ -#ifndef testcase -# define testcase(X) -#endif - -/* -** Terminator values for position-lists and column-lists. -*/ -#define POS_COLUMN (1) /* Column-list terminator */ -#define POS_END (0) /* Position-list terminator */ - -/* -** This section provides definitions to allow the -** FTS3 extension to be compiled outside of the -** amalgamation. -*/ -#ifndef SQLITE_AMALGAMATION -/* -** Macros indicating that conditional expressions are always true or -** false. -*/ -#ifdef SQLITE_COVERAGE_TEST -# define ALWAYS(x) (1) -# define NEVER(X) (0) -#elif defined(SQLITE_DEBUG) -# define ALWAYS(x) sqlite3Fts3Always((x)!=0) -# define NEVER(x) sqlite3Fts3Never((x)!=0) -SQLITE_PRIVATE int sqlite3Fts3Always(int b); -SQLITE_PRIVATE int sqlite3Fts3Never(int b); -#else -# define ALWAYS(x) (x) -# define NEVER(x) (x) -#endif - -/* -** Internal types used by SQLite. -*/ -typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ -typedef short int i16; /* 2-byte (or larger) signed integer */ -typedef unsigned int u32; /* 4-byte unsigned integer */ -typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ -typedef sqlite3_int64 i64; /* 8-byte signed integer */ - -/* -** Macro used to suppress compiler warnings for unused parameters. -*/ -#define UNUSED_PARAMETER(x) (void)(x) - -/* -** Activate assert() only if SQLITE_TEST is enabled. -*/ -#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) -# define NDEBUG 1 -#endif - -/* -** The TESTONLY macro is used to enclose variable declarations or -** other bits of code that are needed to support the arguments -** within testcase() and assert() macros. -*/ -#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) -# define TESTONLY(X) X -#else -# define TESTONLY(X) -#endif - -#endif /* SQLITE_AMALGAMATION */ - -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); -# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() -#else -# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB -#endif - -typedef struct Fts3Table Fts3Table; -typedef struct Fts3Cursor Fts3Cursor; -typedef struct Fts3Expr Fts3Expr; -typedef struct Fts3Phrase Fts3Phrase; -typedef struct Fts3PhraseToken Fts3PhraseToken; - -typedef struct Fts3Doclist Fts3Doclist; -typedef struct Fts3SegFilter Fts3SegFilter; -typedef struct Fts3DeferredToken Fts3DeferredToken; -typedef struct Fts3SegReader Fts3SegReader; -typedef struct Fts3MultiSegReader Fts3MultiSegReader; - -typedef struct MatchinfoBuffer MatchinfoBuffer; - -/* -** A connection to a fulltext index is an instance of the following -** structure. The xCreate and xConnect methods create an instance -** of this structure and xDestroy and xDisconnect free that instance. -** All other methods receive a pointer to the structure as one of their -** arguments. -*/ -struct Fts3Table { - sqlite3_vtab base; /* Base class used by SQLite core */ - sqlite3 *db; /* The database connection */ - const char *zDb; /* logical database name */ - const char *zName; /* virtual table name */ - int nColumn; /* number of named columns in virtual table */ - char **azColumn; /* column names. malloced */ - u8 *abNotindexed; /* True for 'notindexed' columns */ - sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ - char *zContentTbl; /* content=xxx option, or NULL */ - char *zLanguageid; /* languageid=xxx option, or NULL */ - int nAutoincrmerge; /* Value configured by 'automerge' */ - u32 nLeafAdd; /* Number of leaf blocks added this trans */ - - /* Precompiled statements used by the implementation. Each of these - ** statements is run and reset within a single virtual table API call. - */ - sqlite3_stmt *aStmt[40]; - - char *zReadExprlist; - char *zWriteExprlist; - - int nNodeSize; /* Soft limit for node size */ - u8 bFts4; /* True for FTS4, false for FTS3 */ - u8 bHasStat; /* True if %_stat table exists (2==unknown) */ - u8 bHasDocsize; /* True if %_docsize table exists */ - u8 bDescIdx; /* True if doclists are in reverse order */ - u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ - int nPgsz; /* Page size for host database */ - char *zSegmentsTbl; /* Name of %_segments table */ - sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ - - /* - ** The following array of hash tables is used to buffer pending index - ** updates during transactions. All pending updates buffered at any one - ** time must share a common language-id (see the FTS4 langid= feature). - ** The current language id is stored in variable iPrevLangid. - ** - ** A single FTS4 table may have multiple full-text indexes. For each index - ** there is an entry in the aIndex[] array. Index 0 is an index of all the - ** terms that appear in the document set. Each subsequent index in aIndex[] - ** is an index of prefixes of a specific length. - ** - ** Variable nPendingData contains an estimate the memory consumed by the - ** pending data structures, including hash table overhead, but not including - ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash - ** tables are flushed to disk. Variable iPrevDocid is the docid of the most - ** recently inserted record. - */ - int nIndex; /* Size of aIndex[] */ - struct Fts3Index { - int nPrefix; /* Prefix length (0 for main terms index) */ - Fts3Hash hPending; /* Pending terms table for this index */ - } *aIndex; - int nMaxPendingData; /* Max pending data before flush to disk */ - int nPendingData; /* Current bytes of pending data */ - sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ - int iPrevLangid; /* Langid of recently inserted document */ - int bPrevDelete; /* True if last operation was a delete */ - -#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) - /* State variables used for validating that the transaction control - ** methods of the virtual table are called at appropriate times. These - ** values do not contribute to FTS functionality; they are used for - ** verifying the operation of the SQLite core. - */ - int inTransaction; /* True after xBegin but before xCommit/xRollback */ - int mxSavepoint; /* Largest valid xSavepoint integer */ -#endif - -#ifdef SQLITE_TEST - /* True to disable the incremental doclist optimization. This is controled - ** by special insert command 'test-no-incr-doclist'. */ - int bNoIncrDoclist; -#endif -}; - -/* -** When the core wants to read from the virtual table, it creates a -** virtual table cursor (an instance of the following structure) using -** the xOpen method. Cursors are destroyed using the xClose method. -*/ -struct Fts3Cursor { - sqlite3_vtab_cursor base; /* Base class used by SQLite core */ - i16 eSearch; /* Search strategy (see below) */ - u8 isEof; /* True if at End Of Results */ - u8 isRequireSeek; /* True if must seek pStmt to %_content row */ - sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ - Fts3Expr *pExpr; /* Parsed MATCH query string */ - int iLangid; /* Language being queried for */ - int nPhrase; /* Number of matchable phrases in query */ - Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ - sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ - char *pNextId; /* Pointer into the body of aDoclist */ - char *aDoclist; /* List of docids for full-text queries */ - int nDoclist; /* Size of buffer at aDoclist */ - u8 bDesc; /* True to sort in descending order */ - int eEvalmode; /* An FTS3_EVAL_XX constant */ - int nRowAvg; /* Average size of database rows, in pages */ - sqlite3_int64 nDoc; /* Documents in table */ - i64 iMinDocid; /* Minimum docid to return */ - i64 iMaxDocid; /* Maximum docid to return */ - int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ - MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */ -}; - -#define FTS3_EVAL_FILTER 0 -#define FTS3_EVAL_NEXT 1 -#define FTS3_EVAL_MATCHINFO 2 - -/* -** The Fts3Cursor.eSearch member is always set to one of the following. -** Actualy, Fts3Cursor.eSearch can be greater than or equal to -** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index -** of the column to be searched. For example, in -** -** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); -** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; -** -** Because the LHS of the MATCH operator is 2nd column "b", -** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a, -** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" -** indicating that all columns should be searched, -** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4. -*/ -#define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ -#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ -#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ - -/* -** The lower 16-bits of the sqlite3_index_info.idxNum value set by -** the xBestIndex() method contains the Fts3Cursor.eSearch value described -** above. The upper 16-bits contain a combination of the following -** bits, used to describe extra constraints on full-text searches. -*/ -#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ -#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ -#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ - -struct Fts3Doclist { - char *aAll; /* Array containing doclist (or NULL) */ - int nAll; /* Size of a[] in bytes */ - char *pNextDocid; /* Pointer to next docid */ - - sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ - int bFreeList; /* True if pList should be sqlite3_free()d */ - char *pList; /* Pointer to position list following iDocid */ - int nList; /* Length of position list */ -}; - -/* -** A "phrase" is a sequence of one or more tokens that must match in -** sequence. A single token is the base case and the most common case. -** For a sequence of tokens contained in double-quotes (i.e. "one two three") -** nToken will be the number of tokens in the string. -*/ -struct Fts3PhraseToken { - char *z; /* Text of the token */ - int n; /* Number of bytes in buffer z */ - int isPrefix; /* True if token ends with a "*" character */ - int bFirst; /* True if token must appear at position 0 */ - - /* Variables above this point are populated when the expression is - ** parsed (by code in fts3_expr.c). Below this point the variables are - ** used when evaluating the expression. */ - Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ - Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ -}; - -struct Fts3Phrase { - /* Cache of doclist for this phrase. */ - Fts3Doclist doclist; - int bIncr; /* True if doclist is loaded incrementally */ - int iDoclistToken; - - /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an - ** OR condition. */ - char *pOrPoslist; - i64 iOrDocid; - - /* Variables below this point are populated by fts3_expr.c when parsing - ** a MATCH expression. Everything above is part of the evaluation phase. - */ - int nToken; /* Number of tokens in the phrase */ - int iColumn; /* Index of column this phrase must match */ - Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ -}; - -/* -** A tree of these objects forms the RHS of a MATCH operator. -** -** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist -** points to a malloced buffer, size nDoclist bytes, containing the results -** of this phrase query in FTS3 doclist format. As usual, the initial -** "Length" field found in doclists stored on disk is omitted from this -** buffer. -** -** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global -** matchinfo data. If it is not NULL, it points to an array of size nCol*3, -** where nCol is the number of columns in the queried FTS table. The array -** is populated as follows: -** -** aMI[iCol*3 + 0] = Undefined -** aMI[iCol*3 + 1] = Number of occurrences -** aMI[iCol*3 + 2] = Number of rows containing at least one instance -** -** The aMI array is allocated using sqlite3_malloc(). It should be freed -** when the expression node is. -*/ -struct Fts3Expr { - int eType; /* One of the FTSQUERY_XXX values defined below */ - int nNear; /* Valid if eType==FTSQUERY_NEAR */ - Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */ - Fts3Expr *pLeft; /* Left operand */ - Fts3Expr *pRight; /* Right operand */ - Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ - - /* The following are used by the fts3_eval.c module. */ - sqlite3_int64 iDocid; /* Current docid */ - u8 bEof; /* True this expression is at EOF already */ - u8 bStart; /* True if iDocid is valid */ - u8 bDeferred; /* True if this expression is entirely deferred */ - - /* The following are used by the fts3_snippet.c module. */ - int iPhrase; /* Index of this phrase in matchinfo() results */ - u32 *aMI; /* See above */ -}; - -/* -** Candidate values for Fts3Query.eType. Note that the order of the first -** four values is in order of precedence when parsing expressions. For -** example, the following: -** -** "a OR b AND c NOT d NEAR e" -** -** is equivalent to: -** -** "a OR (b AND (c NOT (d NEAR e)))" -*/ -#define FTSQUERY_NEAR 1 -#define FTSQUERY_NOT 2 -#define FTSQUERY_AND 3 -#define FTSQUERY_OR 4 -#define FTSQUERY_PHRASE 5 - - -/* fts3_write.c */ -SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); -SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); -SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); -SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); -SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, - sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); -SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( - Fts3Table*,int,const char*,int,int,Fts3SegReader**); -SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); -SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); -SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); - -SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); -SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); - -#ifndef SQLITE_DISABLE_FTS4_DEFERRED -SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); -SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); -SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); -SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); -SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); -#else -# define sqlite3Fts3FreeDeferredTokens(x) -# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK -# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK -# define sqlite3Fts3FreeDeferredDoclists(x) -# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK -#endif - -SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); -SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); - -/* Special values interpreted by sqlite3SegReaderCursor() */ -#define FTS3_SEGCURSOR_PENDING -1 -#define FTS3_SEGCURSOR_ALL -2 - -SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); -SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); -SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); - -SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, - int, int, int, const char *, int, int, int, Fts3MultiSegReader *); - -/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ -#define FTS3_SEGMENT_REQUIRE_POS 0x00000001 -#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 -#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 -#define FTS3_SEGMENT_PREFIX 0x00000008 -#define FTS3_SEGMENT_SCAN 0x00000010 -#define FTS3_SEGMENT_FIRST 0x00000020 - -/* Type passed as 4th argument to SegmentReaderIterate() */ -struct Fts3SegFilter { - const char *zTerm; - int nTerm; - int iCol; - int flags; -}; - -struct Fts3MultiSegReader { - /* Used internally by sqlite3Fts3SegReaderXXX() calls */ - Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ - int nSegment; /* Size of apSegment array */ - int nAdvance; /* How many seg-readers to advance */ - Fts3SegFilter *pFilter; /* Pointer to filter object */ - char *aBuffer; /* Buffer to merge doclists in */ - int nBuffer; /* Allocated size of aBuffer[] in bytes */ - - int iColFilter; /* If >=0, filter for this column */ - int bRestart; - - /* Used by fts3.c only. */ - int nCost; /* Cost of running iterator */ - int bLookup; /* True if a lookup of a single entry. */ - - /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ - char *zTerm; /* Pointer to term buffer */ - int nTerm; /* Size of zTerm in bytes */ - char *aDoclist; /* Pointer to doclist buffer */ - int nDoclist; /* Size of aDoclist[] in bytes */ -}; - -SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); - -#define fts3GetVarint32(p, piVal) ( \ - (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ -) - -/* fts3.c */ -SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); -SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); -SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); -SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); -SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); -SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); -SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); -SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); -SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); -SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); -SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc); - -/* fts3_tokenizer.c */ -SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); -SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); -SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, - sqlite3_tokenizer **, char ** -); -SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); - -/* fts3_snippet.c */ -SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); -SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, - const char *, const char *, int, int -); -SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); -SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p); - -/* fts3_expr.c */ -SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, - char **, int, int, int, const char *, int, Fts3Expr **, char ** -); -SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); -#ifdef SQLITE_TEST -SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); -SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); -#endif - -SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, - sqlite3_tokenizer_cursor ** -); - -/* fts3_aux.c */ -SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); - -SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); - -SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( - Fts3Table*, Fts3MultiSegReader*, int, const char*, int); -SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( - Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); -SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); -SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); -SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); - -/* fts3_tokenize_vtab.c */ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); - -/* fts3_unicode2.c (functions generated by parsing unicode text files) */ -#ifndef SQLITE_DISABLE_FTS3_UNICODE -SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); -SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); -SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); -#endif - -#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ -#endif /* _FTSINT_H */ - -/************** End of fts3Int.h *********************************************/ -/************** Continuing where we left off in fts3.c ***********************/ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) -# define SQLITE_CORE 1 -#endif - -/* #include */ -/* #include */ -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* #include "fts3.h" */ -#ifndef SQLITE_CORE -/* # include "sqlite3ext.h" */ - SQLITE_EXTENSION_INIT1 -#endif - -static int fts3EvalNext(Fts3Cursor *pCsr); -static int fts3EvalStart(Fts3Cursor *pCsr); -static int fts3TermSegReaderCursor( - Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); - -#ifndef SQLITE_AMALGAMATION -# if defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } -SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } -# endif -#endif - -/* -** Write a 64-bit variable-length integer to memory starting at p[0]. -** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. -** The number of bytes written is returned. -*/ -SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ - unsigned char *q = (unsigned char *) p; - sqlite_uint64 vu = v; - do{ - *q++ = (unsigned char) ((vu & 0x7f) | 0x80); - vu >>= 7; - }while( vu!=0 ); - q[-1] &= 0x7f; /* turn off high bit in final byte */ - assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); - return (int) (q - (unsigned char *)p); -} - -#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ - v = (v & mask1) | ( (*ptr++) << shift ); \ - if( (v & mask2)==0 ){ var = v; return ret; } -#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ - v = (*ptr++); \ - if( (v & mask2)==0 ){ var = v; return ret; } - -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read, or 0 on error. -** The value is stored in *v. -*/ -SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ - const char *pStart = p; - u32 a; - u64 b; - int shift; - - GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); - GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); - GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); - GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); - b = (a & 0x0FFFFFFF ); - - for(shift=28; shift<=63; shift+=7){ - u64 c = *p++; - b += (c&0x7F) << shift; - if( (c & 0x80)==0 ) break; - } - *v = b; - return (int)(p - pStart); -} - -/* -** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a -** 32-bit integer before it is returned. -*/ -SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ - u32 a; - -#ifndef fts3GetVarint32 - GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1); -#else - a = (*p++); - assert( a & 0x80 ); -#endif - - GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2); - GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3); - GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4); - a = (a & 0x0FFFFFFF ); - *pi = (int)(a | ((u32)(*p & 0x0F) << 28)); - return 5; -} - -/* -** Return the number of bytes required to encode v as a varint -*/ -SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ - int i = 0; - do{ - i++; - v >>= 7; - }while( v!=0 ); - return i; -} - -/* -** Convert an SQL-style quoted string into a normal string by removing -** the quote characters. The conversion is done in-place. If the -** input does not begin with a quote character, then this routine -** is a no-op. -** -** Examples: -** -** "abc" becomes abc -** 'xyz' becomes xyz -** [pqr] becomes pqr -** `mno` becomes mno -** -*/ -SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ - char quote; /* Quote character (if any ) */ - - quote = z[0]; - if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){ - int iIn = 1; /* Index of next byte to read from input */ - int iOut = 0; /* Index of next byte to write to output */ - - /* If the first byte was a '[', then the close-quote character is a ']' */ - if( quote=='[' ) quote = ']'; - - while( z[iIn] ){ - if( z[iIn]==quote ){ - if( z[iIn+1]!=quote ) break; - z[iOut++] = quote; - iIn += 2; - }else{ - z[iOut++] = z[iIn++]; - } - } - z[iOut] = '\0'; - } -} - -/* -** Read a single varint from the doclist at *pp and advance *pp to point -** to the first byte past the end of the varint. Add the value of the varint -** to *pVal. -*/ -static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ - sqlite3_int64 iVal; - *pp += sqlite3Fts3GetVarint(*pp, &iVal); - *pVal += iVal; -} - -/* -** When this function is called, *pp points to the first byte following a -** varint that is part of a doclist (or position-list, or any other list -** of varints). This function moves *pp to point to the start of that varint, -** and sets *pVal by the varint value. -** -** Argument pStart points to the first byte of the doclist that the -** varint is part of. -*/ -static void fts3GetReverseVarint( - char **pp, - char *pStart, - sqlite3_int64 *pVal -){ - sqlite3_int64 iVal; - char *p; - - /* Pointer p now points at the first byte past the varint we are - ** interested in. So, unless the doclist is corrupt, the 0x80 bit is - ** clear on character p[-1]. */ - for(p = (*pp)-2; p>=pStart && *p&0x80; p--); - p++; - *pp = p; - - sqlite3Fts3GetVarint(p, &iVal); - *pVal = iVal; -} - -/* -** The xDisconnect() virtual table method. -*/ -static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ - Fts3Table *p = (Fts3Table *)pVtab; - int i; - - assert( p->nPendingData==0 ); - assert( p->pSegments==0 ); - - /* Free any prepared statements held */ - for(i=0; iaStmt); i++){ - sqlite3_finalize(p->aStmt[i]); - } - sqlite3_free(p->zSegmentsTbl); - sqlite3_free(p->zReadExprlist); - sqlite3_free(p->zWriteExprlist); - sqlite3_free(p->zContentTbl); - sqlite3_free(p->zLanguageid); - - /* Invoke the tokenizer destructor to free the tokenizer. */ - p->pTokenizer->pModule->xDestroy(p->pTokenizer); - - sqlite3_free(p); - return SQLITE_OK; -} - -/* -** Write an error message into *pzErr -*/ -SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ - va_list ap; - sqlite3_free(*pzErr); - va_start(ap, zFormat); - *pzErr = sqlite3_vmprintf(zFormat, ap); - va_end(ap); -} - -/* -** Construct one or more SQL statements from the format string given -** and then evaluate those statements. The success code is written -** into *pRc. -** -** If *pRc is initially non-zero then this routine is a no-op. -*/ -static void fts3DbExec( - int *pRc, /* Success code */ - sqlite3 *db, /* Database in which to run SQL */ - const char *zFormat, /* Format string for SQL */ - ... /* Arguments to the format string */ -){ - va_list ap; - char *zSql; - if( *pRc ) return; - va_start(ap, zFormat); - zSql = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( zSql==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - *pRc = sqlite3_exec(db, zSql, 0, 0, 0); - sqlite3_free(zSql); - } -} - -/* -** The xDestroy() virtual table method. -*/ -static int fts3DestroyMethod(sqlite3_vtab *pVtab){ - Fts3Table *p = (Fts3Table *)pVtab; - int rc = SQLITE_OK; /* Return code */ - const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */ - sqlite3 *db = p->db; /* Database handle */ - - /* Drop the shadow tables */ - if( p->zContentTbl==0 ){ - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName); - } - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName); - - /* If everything has worked, invoke fts3DisconnectMethod() to free the - ** memory associated with the Fts3Table structure and return SQLITE_OK. - ** Otherwise, return an SQLite error code. - */ - return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc); -} - - -/* -** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table -** passed as the first argument. This is done as part of the xConnect() -** and xCreate() methods. -** -** If *pRc is non-zero when this function is called, it is a no-op. -** Otherwise, if an error occurs, an SQLite error code is stored in *pRc -** before returning. -*/ -static void fts3DeclareVtab(int *pRc, Fts3Table *p){ - if( *pRc==SQLITE_OK ){ - int i; /* Iterator variable */ - int rc; /* Return code */ - char *zSql; /* SQL statement passed to declare_vtab() */ - char *zCols; /* List of user defined columns */ - const char *zLanguageid; - - zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); - sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - - /* Create a list of user columns for the virtual table */ - zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); - for(i=1; zCols && inColumn; i++){ - zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); - } - - /* Create the whole "CREATE TABLE" statement to pass to SQLite */ - zSql = sqlite3_mprintf( - "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", - zCols, p->zName, zLanguageid - ); - if( !zCols || !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_declare_vtab(p->db, zSql); - } - - sqlite3_free(zSql); - sqlite3_free(zCols); - *pRc = rc; - } -} - -/* -** Create the %_stat table if it does not already exist. -*/ -SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ - fts3DbExec(pRc, p->db, - "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" - "(id INTEGER PRIMARY KEY, value BLOB);", - p->zDb, p->zName - ); - if( (*pRc)==SQLITE_OK ) p->bHasStat = 1; -} - -/* -** Create the backing store tables (%_content, %_segments and %_segdir) -** required by the FTS3 table passed as the only argument. This is done -** as part of the vtab xCreate() method. -** -** If the p->bHasDocsize boolean is true (indicating that this is an -** FTS4 table, not an FTS3 table) then also create the %_docsize and -** %_stat tables required by FTS4. -*/ -static int fts3CreateTables(Fts3Table *p){ - int rc = SQLITE_OK; /* Return code */ - int i; /* Iterator variable */ - sqlite3 *db = p->db; /* The database connection */ - - if( p->zContentTbl==0 ){ - const char *zLanguageid = p->zLanguageid; - char *zContentCols; /* Columns of %_content table */ - - /* Create a list of user columns for the content table */ - zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); - for(i=0; zContentCols && inColumn; i++){ - char *z = p->azColumn[i]; - zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); - } - if( zLanguageid && zContentCols ){ - zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); - } - if( zContentCols==0 ) rc = SQLITE_NOMEM; - - /* Create the content table */ - fts3DbExec(&rc, db, - "CREATE TABLE %Q.'%q_content'(%s)", - p->zDb, p->zName, zContentCols - ); - sqlite3_free(zContentCols); - } - - /* Create other tables */ - fts3DbExec(&rc, db, - "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", - p->zDb, p->zName - ); - fts3DbExec(&rc, db, - "CREATE TABLE %Q.'%q_segdir'(" - "level INTEGER," - "idx INTEGER," - "start_block INTEGER," - "leaves_end_block INTEGER," - "end_block INTEGER," - "root BLOB," - "PRIMARY KEY(level, idx)" - ");", - p->zDb, p->zName - ); - if( p->bHasDocsize ){ - fts3DbExec(&rc, db, - "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", - p->zDb, p->zName - ); - } - assert( p->bHasStat==p->bFts4 ); - if( p->bHasStat ){ - sqlite3Fts3CreateStatTable(&rc, p); - } - return rc; -} - -/* -** Store the current database page-size in bytes in p->nPgsz. -** -** If *pRc is non-zero when this function is called, it is a no-op. -** Otherwise, if an error occurs, an SQLite error code is stored in *pRc -** before returning. -*/ -static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ - if( *pRc==SQLITE_OK ){ - int rc; /* Return code */ - char *zSql; /* SQL text "PRAGMA %Q.page_size" */ - sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ - - zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_step(pStmt); - p->nPgsz = sqlite3_column_int(pStmt, 0); - rc = sqlite3_finalize(pStmt); - }else if( rc==SQLITE_AUTH ){ - p->nPgsz = 1024; - rc = SQLITE_OK; - } - } - assert( p->nPgsz>0 || rc!=SQLITE_OK ); - sqlite3_free(zSql); - *pRc = rc; - } -} - -/* -** "Special" FTS4 arguments are column specifications of the following form: -** -** = -** -** There may not be whitespace surrounding the "=" character. The -** term may be quoted, but the may not. -*/ -static int fts3IsSpecialColumn( - const char *z, - int *pnKey, - char **pzValue -){ - char *zValue; - const char *zCsr = z; - - while( *zCsr!='=' ){ - if( *zCsr=='\0' ) return 0; - zCsr++; - } - - *pnKey = (int)(zCsr-z); - zValue = sqlite3_mprintf("%s", &zCsr[1]); - if( zValue ){ - sqlite3Fts3Dequote(zValue); - } - *pzValue = zValue; - return 1; -} - -/* -** Append the output of a printf() style formatting to an existing string. -*/ -static void fts3Appendf( - int *pRc, /* IN/OUT: Error code */ - char **pz, /* IN/OUT: Pointer to string buffer */ - const char *zFormat, /* Printf format string to append */ - ... /* Arguments for printf format string */ -){ - if( *pRc==SQLITE_OK ){ - va_list ap; - char *z; - va_start(ap, zFormat); - z = sqlite3_vmprintf(zFormat, ap); - va_end(ap); - if( z && *pz ){ - char *z2 = sqlite3_mprintf("%s%s", *pz, z); - sqlite3_free(z); - z = z2; - } - if( z==0 ) *pRc = SQLITE_NOMEM; - sqlite3_free(*pz); - *pz = z; - } -} - -/* -** Return a copy of input string zInput enclosed in double-quotes (") and -** with all double quote characters escaped. For example: -** -** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" -** -** The pointer returned points to memory obtained from sqlite3_malloc(). It -** is the callers responsibility to call sqlite3_free() to release this -** memory. -*/ -static char *fts3QuoteId(char const *zInput){ - int nRet; - char *zRet; - nRet = 2 + (int)strlen(zInput)*2 + 1; - zRet = sqlite3_malloc(nRet); - if( zRet ){ - int i; - char *z = zRet; - *(z++) = '"'; - for(i=0; zInput[i]; i++){ - if( zInput[i]=='"' ) *(z++) = '"'; - *(z++) = zInput[i]; - } - *(z++) = '"'; - *(z++) = '\0'; - } - return zRet; -} - -/* -** Return a list of comma separated SQL expressions and a FROM clause that -** could be used in a SELECT statement such as the following: -** -** SELECT FROM %_content AS x ... -** -** to return the docid, followed by each column of text data in order -** from left to write. If parameter zFunc is not NULL, then instead of -** being returned directly each column of text data is passed to an SQL -** function named zFunc first. For example, if zFunc is "unzip" and the -** table has the three user-defined columns "a", "b", and "c", the following -** string is returned: -** -** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x" -** -** The pointer returned points to a buffer allocated by sqlite3_malloc(). It -** is the responsibility of the caller to eventually free it. -** -** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and -** a NULL pointer is returned). Otherwise, if an OOM error is encountered -** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If -** no error occurs, *pRc is left unmodified. -*/ -static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ - char *zRet = 0; - char *zFree = 0; - char *zFunction; - int i; - - if( p->zContentTbl==0 ){ - if( !zFunc ){ - zFunction = ""; - }else{ - zFree = zFunction = fts3QuoteId(zFunc); - } - fts3Appendf(pRc, &zRet, "docid"); - for(i=0; inColumn; i++){ - fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); - } - if( p->zLanguageid ){ - fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); - } - sqlite3_free(zFree); - }else{ - fts3Appendf(pRc, &zRet, "rowid"); - for(i=0; inColumn; i++){ - fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]); - } - if( p->zLanguageid ){ - fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid); - } - } - fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", - p->zDb, - (p->zContentTbl ? p->zContentTbl : p->zName), - (p->zContentTbl ? "" : "_content") - ); - return zRet; -} - -/* -** Return a list of N comma separated question marks, where N is the number -** of columns in the %_content table (one for the docid plus one for each -** user-defined text column). -** -** If argument zFunc is not NULL, then all but the first question mark -** is preceded by zFunc and an open bracket, and followed by a closed -** bracket. For example, if zFunc is "zip" and the FTS3 table has three -** user-defined text columns, the following string is returned: -** -** "?, zip(?), zip(?), zip(?)" -** -** The pointer returned points to a buffer allocated by sqlite3_malloc(). It -** is the responsibility of the caller to eventually free it. -** -** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and -** a NULL pointer is returned). Otherwise, if an OOM error is encountered -** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If -** no error occurs, *pRc is left unmodified. -*/ -static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ - char *zRet = 0; - char *zFree = 0; - char *zFunction; - int i; - - if( !zFunc ){ - zFunction = ""; - }else{ - zFree = zFunction = fts3QuoteId(zFunc); - } - fts3Appendf(pRc, &zRet, "?"); - for(i=0; inColumn; i++){ - fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); - } - if( p->zLanguageid ){ - fts3Appendf(pRc, &zRet, ", ?"); - } - sqlite3_free(zFree); - return zRet; -} - -/* -** This function interprets the string at (*pp) as a non-negative integer -** value. It reads the integer and sets *pnOut to the value read, then -** sets *pp to point to the byte immediately following the last byte of -** the integer value. -** -** Only decimal digits ('0'..'9') may be part of an integer value. -** -** If *pp does not being with a decimal digit SQLITE_ERROR is returned and -** the output value undefined. Otherwise SQLITE_OK is returned. -** -** This function is used when parsing the "prefix=" FTS4 parameter. -*/ -static int fts3GobbleInt(const char **pp, int *pnOut){ - const int MAX_NPREFIX = 10000000; - const char *p; /* Iterator pointer */ - int nInt = 0; /* Output value */ - - for(p=*pp; p[0]>='0' && p[0]<='9'; p++){ - nInt = nInt * 10 + (p[0] - '0'); - if( nInt>MAX_NPREFIX ){ - nInt = 0; - break; - } - } - if( p==*pp ) return SQLITE_ERROR; - *pnOut = nInt; - *pp = p; - return SQLITE_OK; -} - -/* -** This function is called to allocate an array of Fts3Index structures -** representing the indexes maintained by the current FTS table. FTS tables -** always maintain the main "terms" index, but may also maintain one or -** more "prefix" indexes, depending on the value of the "prefix=" parameter -** (if any) specified as part of the CREATE VIRTUAL TABLE statement. -** -** Argument zParam is passed the value of the "prefix=" option if one was -** specified, or NULL otherwise. -** -** If no error occurs, SQLITE_OK is returned and *apIndex set to point to -** the allocated array. *pnIndex is set to the number of elements in the -** array. If an error does occur, an SQLite error code is returned. -** -** Regardless of whether or not an error is returned, it is the responsibility -** of the caller to call sqlite3_free() on the output array to free it. -*/ -static int fts3PrefixParameter( - const char *zParam, /* ABC in prefix=ABC parameter to parse */ - int *pnIndex, /* OUT: size of *apIndex[] array */ - struct Fts3Index **apIndex /* OUT: Array of indexes for this table */ -){ - struct Fts3Index *aIndex; /* Allocated array */ - int nIndex = 1; /* Number of entries in array */ - - if( zParam && zParam[0] ){ - const char *p; - nIndex++; - for(p=zParam; *p; p++){ - if( *p==',' ) nIndex++; - } - } - - aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex); - *apIndex = aIndex; - if( !aIndex ){ - return SQLITE_NOMEM; - } - - memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex); - if( zParam ){ - const char *p = zParam; - int i; - for(i=1; i=0 ); - if( nPrefix==0 ){ - nIndex--; - i--; - }else{ - aIndex[i].nPrefix = nPrefix; - } - p++; - } - } - - *pnIndex = nIndex; - return SQLITE_OK; -} - -/* -** This function is called when initializing an FTS4 table that uses the -** content=xxx option. It determines the number of and names of the columns -** of the new FTS4 table. -** -** The third argument passed to this function is the value passed to the -** config=xxx option (i.e. "xxx"). This function queries the database for -** a table of that name. If found, the output variables are populated -** as follows: -** -** *pnCol: Set to the number of columns table xxx has, -** -** *pnStr: Set to the total amount of space required to store a copy -** of each columns name, including the nul-terminator. -** -** *pazCol: Set to point to an array of *pnCol strings. Each string is -** the name of the corresponding column in table xxx. The array -** and its contents are allocated using a single allocation. It -** is the responsibility of the caller to free this allocation -** by eventually passing the *pazCol value to sqlite3_free(). -** -** If the table cannot be found, an error code is returned and the output -** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is -** returned (and the output variables are undefined). -*/ -static int fts3ContentColumns( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ - const char *zTbl, /* Name of content table */ - const char ***pazCol, /* OUT: Malloc'd array of column names */ - int *pnCol, /* OUT: Size of array *pazCol */ - int *pnStr, /* OUT: Bytes of string content */ - char **pzErr /* OUT: error message */ -){ - int rc = SQLITE_OK; /* Return code */ - char *zSql; /* "SELECT *" statement on zTbl */ - sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ - - zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); - if( rc!=SQLITE_OK ){ - sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); - } - } - sqlite3_free(zSql); - - if( rc==SQLITE_OK ){ - const char **azCol; /* Output array */ - int nStr = 0; /* Size of all column names (incl. 0x00) */ - int nCol; /* Number of table columns */ - int i; /* Used to iterate through columns */ - - /* Loop through the returned columns. Set nStr to the number of bytes of - ** space required to store a copy of each column name, including the - ** nul-terminator byte. */ - nCol = sqlite3_column_count(pStmt); - for(i=0; i module name ("fts3" or "fts4") -** argv[1] -> database name -** argv[2] -> table name -** argv[...] -> "column name" and other module argument fields. -*/ -static int fts3InitVtab( - int isCreate, /* True for xCreate, false for xConnect */ - sqlite3 *db, /* The SQLite database connection */ - void *pAux, /* Hash table containing tokenizers */ - int argc, /* Number of elements in argv array */ - const char * const *argv, /* xCreate/xConnect argument array */ - sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ - char **pzErr /* Write any error message here */ -){ - Fts3Hash *pHash = (Fts3Hash *)pAux; - Fts3Table *p = 0; /* Pointer to allocated vtab */ - int rc = SQLITE_OK; /* Return code */ - int i; /* Iterator variable */ - int nByte; /* Size of allocation used for *p */ - int iCol; /* Column index */ - int nString = 0; /* Bytes required to hold all column names */ - int nCol = 0; /* Number of columns in the FTS table */ - char *zCsr; /* Space for holding column names */ - int nDb; /* Bytes required to hold database name */ - int nName; /* Bytes required to hold table name */ - int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ - const char **aCol; /* Array of column names */ - sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ - - int nIndex = 0; /* Size of aIndex[] array */ - struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ - - /* The results of parsing supported FTS4 key=value options: */ - int bNoDocsize = 0; /* True to omit %_docsize table */ - int bDescIdx = 0; /* True to store descending indexes */ - char *zPrefix = 0; /* Prefix parameter value (or NULL) */ - char *zCompress = 0; /* compress=? parameter (or NULL) */ - char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ - char *zContent = 0; /* content=? parameter (or NULL) */ - char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ - char **azNotindexed = 0; /* The set of notindexed= columns */ - int nNotindexed = 0; /* Size of azNotindexed[] array */ - - assert( strlen(argv[0])==4 ); - assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) - || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) - ); - - nDb = (int)strlen(argv[1]) + 1; - nName = (int)strlen(argv[2]) + 1; - - nByte = sizeof(const char *) * (argc-2); - aCol = (const char **)sqlite3_malloc(nByte); - if( aCol ){ - memset((void*)aCol, 0, nByte); - azNotindexed = (char **)sqlite3_malloc(nByte); - } - if( azNotindexed ){ - memset(azNotindexed, 0, nByte); - } - if( !aCol || !azNotindexed ){ - rc = SQLITE_NOMEM; - goto fts3_init_out; - } - - /* Loop through all of the arguments passed by the user to the FTS3/4 - ** module (i.e. all the column names and special arguments). This loop - ** does the following: - ** - ** + Figures out the number of columns the FTSX table will have, and - ** the number of bytes of space that must be allocated to store copies - ** of the column names. - ** - ** + If there is a tokenizer specification included in the arguments, - ** initializes the tokenizer pTokenizer. - */ - for(i=3; rc==SQLITE_OK && i8 - && 0==sqlite3_strnicmp(z, "tokenize", 8) - && 0==sqlite3Fts3IsIdChar(z[8]) - ){ - rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); - } - - /* Check if it is an FTS4 special argument. */ - else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){ - struct Fts4Option { - const char *zOpt; - int nOpt; - } aFts4Opt[] = { - { "matchinfo", 9 }, /* 0 -> MATCHINFO */ - { "prefix", 6 }, /* 1 -> PREFIX */ - { "compress", 8 }, /* 2 -> COMPRESS */ - { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ - { "order", 5 }, /* 4 -> ORDER */ - { "content", 7 }, /* 5 -> CONTENT */ - { "languageid", 10 }, /* 6 -> LANGUAGEID */ - { "notindexed", 10 } /* 7 -> NOTINDEXED */ - }; - - int iOpt; - if( !zVal ){ - rc = SQLITE_NOMEM; - }else{ - for(iOpt=0; iOptnOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ - break; - } - } - if( iOpt==SizeofArray(aFts4Opt) ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); - rc = SQLITE_ERROR; - }else{ - switch( iOpt ){ - case 0: /* MATCHINFO */ - if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); - rc = SQLITE_ERROR; - } - bNoDocsize = 1; - break; - - case 1: /* PREFIX */ - sqlite3_free(zPrefix); - zPrefix = zVal; - zVal = 0; - break; - - case 2: /* COMPRESS */ - sqlite3_free(zCompress); - zCompress = zVal; - zVal = 0; - break; - - case 3: /* UNCOMPRESS */ - sqlite3_free(zUncompress); - zUncompress = zVal; - zVal = 0; - break; - - case 4: /* ORDER */ - if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) - && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) - ){ - sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); - rc = SQLITE_ERROR; - } - bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); - break; - - case 5: /* CONTENT */ - sqlite3_free(zContent); - zContent = zVal; - zVal = 0; - break; - - case 6: /* LANGUAGEID */ - assert( iOpt==6 ); - sqlite3_free(zLanguageid); - zLanguageid = zVal; - zVal = 0; - break; - - case 7: /* NOTINDEXED */ - azNotindexed[nNotindexed++] = zVal; - zVal = 0; - break; - } - } - sqlite3_free(zVal); - } - } - - /* Otherwise, the argument is a column name. */ - else { - nString += (int)(strlen(z) + 1); - aCol[nCol++] = z; - } - } - - /* If a content=xxx option was specified, the following: - ** - ** 1. Ignore any compress= and uncompress= options. - ** - ** 2. If no column names were specified as part of the CREATE VIRTUAL - ** TABLE statement, use all columns from the content table. - */ - if( rc==SQLITE_OK && zContent ){ - sqlite3_free(zCompress); - sqlite3_free(zUncompress); - zCompress = 0; - zUncompress = 0; - if( nCol==0 ){ - sqlite3_free((void*)aCol); - aCol = 0; - rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); - - /* If a languageid= option was specified, remove the language id - ** column from the aCol[] array. */ - if( rc==SQLITE_OK && zLanguageid ){ - int j; - for(j=0; jdb = db; - p->nColumn = nCol; - p->nPendingData = 0; - p->azColumn = (char **)&p[1]; - p->pTokenizer = pTokenizer; - p->nMaxPendingData = FTS3_MAX_PENDING_DATA; - p->bHasDocsize = (isFts4 && bNoDocsize==0); - p->bHasStat = isFts4; - p->bFts4 = isFts4; - p->bDescIdx = bDescIdx; - p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ - p->zContentTbl = zContent; - p->zLanguageid = zLanguageid; - zContent = 0; - zLanguageid = 0; - TESTONLY( p->inTransaction = -1 ); - TESTONLY( p->mxSavepoint = -1 ); - - p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; - memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); - p->nIndex = nIndex; - for(i=0; iaIndex[i].hPending, FTS3_HASH_STRING, 1); - } - p->abNotindexed = (u8 *)&p->aIndex[nIndex]; - - /* Fill in the zName and zDb fields of the vtab structure. */ - zCsr = (char *)&p->abNotindexed[nCol]; - p->zName = zCsr; - memcpy(zCsr, argv[2], nName); - zCsr += nName; - p->zDb = zCsr; - memcpy(zCsr, argv[1], nDb); - zCsr += nDb; - - /* Fill in the azColumn array */ - for(iCol=0; iColazColumn[iCol] = zCsr; - zCsr += n+1; - assert( zCsr <= &((char *)p)[nByte] ); - } - - /* Fill in the abNotindexed array */ - for(iCol=0; iColazColumn[iCol]); - for(i=0; iazColumn[iCol], zNot, n) - ){ - p->abNotindexed[iCol] = 1; - sqlite3_free(zNot); - azNotindexed[i] = 0; - } - } - } - for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc); - p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); - if( rc!=SQLITE_OK ) goto fts3_init_out; - - /* If this is an xCreate call, create the underlying tables in the - ** database. TODO: For xConnect(), it could verify that said tables exist. - */ - if( isCreate ){ - rc = fts3CreateTables(p); - } - - /* Check to see if a legacy fts3 table has been "upgraded" by the - ** addition of a %_stat table so that it can use incremental merge. - */ - if( !isFts4 && !isCreate ){ - p->bHasStat = 2; - } - - /* Figure out the page-size for the database. This is required in order to - ** estimate the cost of loading large doclists from the database. */ - fts3DatabasePageSize(&rc, p); - p->nNodeSize = p->nPgsz-35; - - /* Declare the table schema to SQLite. */ - fts3DeclareVtab(&rc, p); - -fts3_init_out: - sqlite3_free(zPrefix); - sqlite3_free(aIndex); - sqlite3_free(zCompress); - sqlite3_free(zUncompress); - sqlite3_free(zContent); - sqlite3_free(zLanguageid); - for(i=0; ipModule->xDestroy(pTokenizer); - } - }else{ - assert( p->pSegments==0 ); - *ppVTab = &p->base; - } - return rc; -} - -/* -** The xConnect() and xCreate() methods for the virtual table. All the -** work is done in function fts3InitVtab(). -*/ -static int fts3ConnectMethod( - sqlite3 *db, /* Database connection */ - void *pAux, /* Pointer to tokenizer hash table */ - int argc, /* Number of elements in argv array */ - const char * const *argv, /* xCreate/xConnect argument array */ - sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ - char **pzErr /* OUT: sqlite3_malloc'd error message */ -){ - return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); -} -static int fts3CreateMethod( - sqlite3 *db, /* Database connection */ - void *pAux, /* Pointer to tokenizer hash table */ - int argc, /* Number of elements in argv array */ - const char * const *argv, /* xCreate/xConnect argument array */ - sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ - char **pzErr /* OUT: sqlite3_malloc'd error message */ -){ - return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); -} - -/* -** Set the pIdxInfo->estimatedRows variable to nRow. Unless this -** extension is currently being used by a version of SQLite too old to -** support estimatedRows. In that case this function is a no-op. -*/ -static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ -#if SQLITE_VERSION_NUMBER>=3008002 - if( sqlite3_libversion_number()>=3008002 ){ - pIdxInfo->estimatedRows = nRow; - } -#endif -} - -/* -** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this -** extension is currently being used by a version of SQLite too old to -** support index-info flags. In that case this function is a no-op. -*/ -static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){ -#if SQLITE_VERSION_NUMBER>=3008012 - if( sqlite3_libversion_number()>=3008012 ){ - pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; - } -#endif -} - -/* -** Implementation of the xBestIndex method for FTS3 tables. There -** are three possible strategies, in order of preference: -** -** 1. Direct lookup by rowid or docid. -** 2. Full-text search using a MATCH operator on a non-docid column. -** 3. Linear scan of %_content table. -*/ -static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ - Fts3Table *p = (Fts3Table *)pVTab; - int i; /* Iterator variable */ - int iCons = -1; /* Index of constraint to use */ - - int iLangidCons = -1; /* Index of langid=x constraint, if present */ - int iDocidGe = -1; /* Index of docid>=x constraint, if present */ - int iDocidLe = -1; /* Index of docid<=x constraint, if present */ - int iIdx; - - /* By default use a full table scan. This is an expensive option, - ** so search through the constraints to see if a more efficient - ** strategy is possible. - */ - pInfo->idxNum = FTS3_FULLSCAN_SEARCH; - pInfo->estimatedCost = 5000000; - for(i=0; inConstraint; i++){ - int bDocid; /* True if this constraint is on docid */ - struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; - if( pCons->usable==0 ){ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ - /* There exists an unusable MATCH constraint. This means that if - ** the planner does elect to use the results of this call as part - ** of the overall query plan the user will see an "unable to use - ** function MATCH in the requested context" error. To discourage - ** this, return a very high cost here. */ - pInfo->idxNum = FTS3_FULLSCAN_SEARCH; - pInfo->estimatedCost = 1e50; - fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); - return SQLITE_OK; - } - continue; - } - - bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); - - /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ - if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ - pInfo->idxNum = FTS3_DOCID_SEARCH; - pInfo->estimatedCost = 1.0; - iCons = i; - } - - /* A MATCH constraint. Use a full-text search. - ** - ** If there is more than one MATCH constraint available, use the first - ** one encountered. If there is both a MATCH constraint and a direct - ** rowid/docid lookup, prefer the MATCH strategy. This is done even - ** though the rowid/docid lookup is faster than a MATCH query, selecting - ** it would lead to an "unable to use function MATCH in the requested - ** context" error. - */ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH - && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn - ){ - pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; - pInfo->estimatedCost = 2.0; - iCons = i; - } - - /* Equality constraint on the langid column */ - if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ - && pCons->iColumn==p->nColumn + 2 - ){ - iLangidCons = i; - } - - if( bDocid ){ - switch( pCons->op ){ - case SQLITE_INDEX_CONSTRAINT_GE: - case SQLITE_INDEX_CONSTRAINT_GT: - iDocidGe = i; - break; - - case SQLITE_INDEX_CONSTRAINT_LE: - case SQLITE_INDEX_CONSTRAINT_LT: - iDocidLe = i; - break; - } - } - } - - /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */ - if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo); - - iIdx = 1; - if( iCons>=0 ){ - pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; - pInfo->aConstraintUsage[iCons].omit = 1; - } - if( iLangidCons>=0 ){ - pInfo->idxNum |= FTS3_HAVE_LANGID; - pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; - } - if( iDocidGe>=0 ){ - pInfo->idxNum |= FTS3_HAVE_DOCID_GE; - pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; - } - if( iDocidLe>=0 ){ - pInfo->idxNum |= FTS3_HAVE_DOCID_LE; - pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; - } - - /* Regardless of the strategy selected, FTS can deliver rows in rowid (or - ** docid) order. Both ascending and descending are possible. - */ - if( pInfo->nOrderBy==1 ){ - struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; - if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ - if( pOrder->desc ){ - pInfo->idxStr = "DESC"; - }else{ - pInfo->idxStr = "ASC"; - } - pInfo->orderByConsumed = 1; - } - } - - assert( p->pSegments==0 ); - return SQLITE_OK; -} - -/* -** Implementation of xOpen method. -*/ -static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ - sqlite3_vtab_cursor *pCsr; /* Allocated cursor */ - - UNUSED_PARAMETER(pVTab); - - /* Allocate a buffer large enough for an Fts3Cursor structure. If the - ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, - ** if the allocation fails, return SQLITE_NOMEM. - */ - *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); - if( !pCsr ){ - return SQLITE_NOMEM; - } - memset(pCsr, 0, sizeof(Fts3Cursor)); - return SQLITE_OK; -} - -/* -** Close the cursor. For additional information see the documentation -** on the xClose method of the virtual table interface. -*/ -static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ - Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; - assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - sqlite3_finalize(pCsr->pStmt); - sqlite3Fts3ExprFree(pCsr->pExpr); - sqlite3Fts3FreeDeferredTokens(pCsr); - sqlite3_free(pCsr->aDoclist); - sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); - assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then -** compose and prepare an SQL statement of the form: -** -** "SELECT FROM %_content WHERE rowid = ?" -** -** (or the equivalent for a content=xxx table) and set pCsr->pStmt to -** it. If an error occurs, return an SQLite error code. -** -** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK. -*/ -static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){ - int rc = SQLITE_OK; - if( pCsr->pStmt==0 ){ - Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; - char *zSql; - zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); - if( !zSql ) return SQLITE_NOMEM; - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); - sqlite3_free(zSql); - } - *ppStmt = pCsr->pStmt; - return rc; -} - -/* -** Position the pCsr->pStmt statement so that it is on the row -** of the %_content table that contains the last match. Return -** SQLITE_OK on success. -*/ -static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ - int rc = SQLITE_OK; - if( pCsr->isRequireSeek ){ - sqlite3_stmt *pStmt = 0; - - rc = fts3CursorSeekStmt(pCsr, &pStmt); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); - pCsr->isRequireSeek = 0; - if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ - return SQLITE_OK; - }else{ - rc = sqlite3_reset(pCsr->pStmt); - if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ - /* If no row was found and no error has occurred, then the %_content - ** table is missing a row that is present in the full-text index. - ** The data structures are corrupt. */ - rc = FTS_CORRUPT_VTAB; - pCsr->isEof = 1; - } - } - } - } - - if( rc!=SQLITE_OK && pContext ){ - sqlite3_result_error_code(pContext, rc); - } - return rc; -} - -/* -** This function is used to process a single interior node when searching -** a b-tree for a term or term prefix. The node data is passed to this -** function via the zNode/nNode parameters. The term to search for is -** passed in zTerm/nTerm. -** -** If piFirst is not NULL, then this function sets *piFirst to the blockid -** of the child node that heads the sub-tree that may contain the term. -** -** If piLast is not NULL, then *piLast is set to the right-most child node -** that heads a sub-tree that may contain a term for which zTerm/nTerm is -** a prefix. -** -** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. -*/ -static int fts3ScanInteriorNode( - const char *zTerm, /* Term to select leaves for */ - int nTerm, /* Size of term zTerm in bytes */ - const char *zNode, /* Buffer containing segment interior node */ - int nNode, /* Size of buffer at zNode */ - sqlite3_int64 *piFirst, /* OUT: Selected child node */ - sqlite3_int64 *piLast /* OUT: Selected child node */ -){ - int rc = SQLITE_OK; /* Return code */ - const char *zCsr = zNode; /* Cursor to iterate through node */ - const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ - char *zBuffer = 0; /* Buffer to load terms into */ - int nAlloc = 0; /* Size of allocated buffer */ - int isFirstTerm = 1; /* True when processing first term on page */ - sqlite3_int64 iChild; /* Block id of child node to descend to */ - - /* Skip over the 'height' varint that occurs at the start of every - ** interior node. Then load the blockid of the left-child of the b-tree - ** node into variable iChild. - ** - ** Even if the data structure on disk is corrupted, this (reading two - ** varints from the buffer) does not risk an overread. If zNode is a - ** root node, then the buffer comes from a SELECT statement. SQLite does - ** not make this guarantee explicitly, but in practice there are always - ** either more than 20 bytes of allocated space following the nNode bytes of - ** contents, or two zero bytes. Or, if the node is read from the %_segments - ** table, then there are always 20 bytes of zeroed padding following the - ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). - */ - zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); - zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); - if( zCsr>zEnd ){ - return FTS_CORRUPT_VTAB; - } - - while( zCsrzEnd ){ - rc = FTS_CORRUPT_VTAB; - goto finish_scan; - } - if( nPrefix+nSuffix>nAlloc ){ - char *zNew; - nAlloc = (nPrefix+nSuffix) * 2; - zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); - if( !zNew ){ - rc = SQLITE_NOMEM; - goto finish_scan; - } - zBuffer = zNew; - } - assert( zBuffer ); - memcpy(&zBuffer[nPrefix], zCsr, nSuffix); - nBuffer = nPrefix + nSuffix; - zCsr += nSuffix; - - /* Compare the term we are searching for with the term just loaded from - ** the interior node. If the specified term is greater than or equal - ** to the term from the interior node, then all terms on the sub-tree - ** headed by node iChild are smaller than zTerm. No need to search - ** iChild. - ** - ** If the interior node term is larger than the specified term, then - ** the tree headed by iChild may contain the specified term. - */ - cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); - if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ - *piFirst = iChild; - piFirst = 0; - } - - if( piLast && cmp<0 ){ - *piLast = iChild; - piLast = 0; - } - - iChild++; - }; - - if( piFirst ) *piFirst = iChild; - if( piLast ) *piLast = iChild; - - finish_scan: - sqlite3_free(zBuffer); - return rc; -} - - -/* -** The buffer pointed to by argument zNode (size nNode bytes) contains an -** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes) -** contains a term. This function searches the sub-tree headed by the zNode -** node for the range of leaf nodes that may contain the specified term -** or terms for which the specified term is a prefix. -** -** If piLeaf is not NULL, then *piLeaf is set to the blockid of the -** left-most leaf node in the tree that may contain the specified term. -** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the -** right-most leaf node that may contain a term for which the specified -** term is a prefix. -** -** It is possible that the range of returned leaf nodes does not contain -** the specified term or any terms for which it is a prefix. However, if the -** segment does contain any such terms, they are stored within the identified -** range. Because this function only inspects interior segment nodes (and -** never loads leaf nodes into memory), it is not possible to be sure. -** -** If an error occurs, an error code other than SQLITE_OK is returned. -*/ -static int fts3SelectLeaf( - Fts3Table *p, /* Virtual table handle */ - const char *zTerm, /* Term to select leaves for */ - int nTerm, /* Size of term zTerm in bytes */ - const char *zNode, /* Buffer containing segment interior node */ - int nNode, /* Size of buffer at zNode */ - sqlite3_int64 *piLeaf, /* Selected leaf node */ - sqlite3_int64 *piLeaf2 /* Selected leaf node */ -){ - int rc = SQLITE_OK; /* Return code */ - int iHeight; /* Height of this node in tree */ - - assert( piLeaf || piLeaf2 ); - - fts3GetVarint32(zNode, &iHeight); - rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); - assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); - - if( rc==SQLITE_OK && iHeight>1 ){ - char *zBlob = 0; /* Blob read from %_segments table */ - int nBlob = 0; /* Size of zBlob in bytes */ - - if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ - rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); - if( rc==SQLITE_OK ){ - rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); - } - sqlite3_free(zBlob); - piLeaf = 0; - zBlob = 0; - } - - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); - } - if( rc==SQLITE_OK ){ - rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); - } - sqlite3_free(zBlob); - } - - return rc; -} - -/* -** This function is used to create delta-encoded serialized lists of FTS3 -** varints. Each call to this function appends a single varint to a list. -*/ -static void fts3PutDeltaVarint( - char **pp, /* IN/OUT: Output pointer */ - sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ - sqlite3_int64 iVal /* Write this value to the list */ -){ - assert( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); - *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); - *piPrev = iVal; -} - -/* -** When this function is called, *ppPoslist is assumed to point to the -** start of a position-list. After it returns, *ppPoslist points to the -** first byte after the position-list. -** -** A position list is list of positions (delta encoded) and columns for -** a single document record of a doclist. So, in other words, this -** routine advances *ppPoslist so that it points to the next docid in -** the doclist, or to the first byte past the end of the doclist. -** -** If pp is not NULL, then the contents of the position list are copied -** to *pp. *pp is set to point to the first byte past the last byte copied -** before this function returns. -*/ -static void fts3PoslistCopy(char **pp, char **ppPoslist){ - char *pEnd = *ppPoslist; - char c = 0; - - /* The end of a position list is marked by a zero encoded as an FTS3 - ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by - ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail - ** of some other, multi-byte, value. - ** - ** The following while-loop moves pEnd to point to the first byte that is not - ** immediately preceded by a byte with the 0x80 bit set. Then increments - ** pEnd once more so that it points to the byte immediately following the - ** last byte in the position-list. - */ - while( *pEnd | c ){ - c = *pEnd++ & 0x80; - testcase( c!=0 && (*pEnd)==0 ); - } - pEnd++; /* Advance past the POS_END terminator byte */ - - if( pp ){ - int n = (int)(pEnd - *ppPoslist); - char *p = *pp; - memcpy(p, *ppPoslist, n); - p += n; - *pp = p; - } - *ppPoslist = pEnd; -} - -/* -** When this function is called, *ppPoslist is assumed to point to the -** start of a column-list. After it returns, *ppPoslist points to the -** to the terminator (POS_COLUMN or POS_END) byte of the column-list. -** -** A column-list is list of delta-encoded positions for a single column -** within a single document within a doclist. -** -** The column-list is terminated either by a POS_COLUMN varint (1) or -** a POS_END varint (0). This routine leaves *ppPoslist pointing to -** the POS_COLUMN or POS_END that terminates the column-list. -** -** If pp is not NULL, then the contents of the column-list are copied -** to *pp. *pp is set to point to the first byte past the last byte copied -** before this function returns. The POS_COLUMN or POS_END terminator -** is not copied into *pp. -*/ -static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ - char *pEnd = *ppPoslist; - char c = 0; - - /* A column-list is terminated by either a 0x01 or 0x00 byte that is - ** not part of a multi-byte varint. - */ - while( 0xFE & (*pEnd | c) ){ - c = *pEnd++ & 0x80; - testcase( c!=0 && ((*pEnd)&0xfe)==0 ); - } - if( pp ){ - int n = (int)(pEnd - *ppPoslist); - char *p = *pp; - memcpy(p, *ppPoslist, n); - p += n; - *pp = p; - } - *ppPoslist = pEnd; -} - -/* -** Value used to signify the end of an position-list. This is safe because -** it is not possible to have a document with 2^31 terms. -*/ -#define POSITION_LIST_END 0x7fffffff - -/* -** This function is used to help parse position-lists. When this function is -** called, *pp may point to the start of the next varint in the position-list -** being parsed, or it may point to 1 byte past the end of the position-list -** (in which case **pp will be a terminator bytes POS_END (0) or -** (1)). -** -** If *pp points past the end of the current position-list, set *pi to -** POSITION_LIST_END and return. Otherwise, read the next varint from *pp, -** increment the current value of *pi by the value read, and set *pp to -** point to the next value before returning. -** -** Before calling this routine *pi must be initialized to the value of -** the previous position, or zero if we are reading the first position -** in the position-list. Because positions are delta-encoded, the value -** of the previous position is needed in order to compute the value of -** the next position. -*/ -static void fts3ReadNextPos( - char **pp, /* IN/OUT: Pointer into position-list buffer */ - sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ -){ - if( (**pp)&0xFE ){ - fts3GetDeltaVarint(pp, pi); - *pi -= 2; - }else{ - *pi = POSITION_LIST_END; - } -} - -/* -** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by -** the value of iCol encoded as a varint to *pp. This will start a new -** column list. -** -** Set *pp to point to the byte just after the last byte written before -** returning (do not modify it if iCol==0). Return the total number of bytes -** written (0 if iCol==0). -*/ -static int fts3PutColNumber(char **pp, int iCol){ - int n = 0; /* Number of bytes written */ - if( iCol ){ - char *p = *pp; /* Output pointer */ - n = 1 + sqlite3Fts3PutVarint(&p[1], iCol); - *p = 0x01; - *pp = &p[n]; - } - return n; -} - -/* -** Compute the union of two position lists. The output written -** into *pp contains all positions of both *pp1 and *pp2 in sorted -** order and with any duplicates removed. All pointers are -** updated appropriately. The caller is responsible for insuring -** that there is enough space in *pp to hold the complete output. -*/ -static void fts3PoslistMerge( - char **pp, /* Output buffer */ - char **pp1, /* Left input list */ - char **pp2 /* Right input list */ -){ - char *p = *pp; - char *p1 = *pp1; - char *p2 = *pp2; - - while( *p1 || *p2 ){ - int iCol1; /* The current column index in pp1 */ - int iCol2; /* The current column index in pp2 */ - - if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1); - else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; - else iCol1 = 0; - - if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2); - else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; - else iCol2 = 0; - - if( iCol1==iCol2 ){ - sqlite3_int64 i1 = 0; /* Last position from pp1 */ - sqlite3_int64 i2 = 0; /* Last position from pp2 */ - sqlite3_int64 iPrev = 0; - int n = fts3PutColNumber(&p, iCol1); - p1 += n; - p2 += n; - - /* At this point, both p1 and p2 point to the start of column-lists - ** for the same column (the column with index iCol1 and iCol2). - ** A column-list is a list of non-negative delta-encoded varints, each - ** incremented by 2 before being stored. Each list is terminated by a - ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists - ** and writes the results to buffer p. p is left pointing to the byte - ** after the list written. No terminator (POS_END or POS_COLUMN) is - ** written to the output. - */ - fts3GetDeltaVarint(&p1, &i1); - fts3GetDeltaVarint(&p2, &i2); - do { - fts3PutDeltaVarint(&p, &iPrev, (i1pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e. -** when the *pp1 token appears before the *pp2 token, but not more than nToken -** slots before it. -** -** e.g. nToken==1 searches for adjacent positions. -*/ -static int fts3PoslistPhraseMerge( - char **pp, /* IN/OUT: Preallocated output buffer */ - int nToken, /* Maximum difference in token positions */ - int isSaveLeft, /* Save the left position */ - int isExact, /* If *pp1 is exactly nTokens before *pp2 */ - char **pp1, /* IN/OUT: Left input list */ - char **pp2 /* IN/OUT: Right input list */ -){ - char *p = *pp; - char *p1 = *pp1; - char *p2 = *pp2; - int iCol1 = 0; - int iCol2 = 0; - - /* Never set both isSaveLeft and isExact for the same invocation. */ - assert( isSaveLeft==0 || isExact==0 ); - - assert( p!=0 && *p1!=0 && *p2!=0 ); - if( *p1==POS_COLUMN ){ - p1++; - p1 += fts3GetVarint32(p1, &iCol1); - } - if( *p2==POS_COLUMN ){ - p2++; - p2 += fts3GetVarint32(p2, &iCol2); - } - - while( 1 ){ - if( iCol1==iCol2 ){ - char *pSave = p; - sqlite3_int64 iPrev = 0; - sqlite3_int64 iPos1 = 0; - sqlite3_int64 iPos2 = 0; - - if( iCol1 ){ - *p++ = POS_COLUMN; - p += sqlite3Fts3PutVarint(p, iCol1); - } - - assert( *p1!=POS_END && *p1!=POS_COLUMN ); - assert( *p2!=POS_END && *p2!=POS_COLUMN ); - fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; - fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; - - while( 1 ){ - if( iPos2==iPos1+nToken - || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) - ){ - sqlite3_int64 iSave; - iSave = isSaveLeft ? iPos1 : iPos2; - fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2; - pSave = 0; - assert( p ); - } - if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){ - if( (*p2&0xFE)==0 ) break; - fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; - }else{ - if( (*p1&0xFE)==0 ) break; - fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; - } - } - - if( pSave ){ - assert( pp && p ); - p = pSave; - } - - fts3ColumnlistCopy(0, &p1); - fts3ColumnlistCopy(0, &p2); - assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); - if( 0==*p1 || 0==*p2 ) break; - - p1++; - p1 += fts3GetVarint32(p1, &iCol1); - p2++; - p2 += fts3GetVarint32(p2, &iCol2); - } - - /* Advance pointer p1 or p2 (whichever corresponds to the smaller of - ** iCol1 and iCol2) so that it points to either the 0x00 that marks the - ** end of the position list, or the 0x01 that precedes the next - ** column-number in the position list. - */ - else if( iCol1=pEnd ){ - *pp = 0; - }else{ - sqlite3_int64 iVal; - *pp += sqlite3Fts3GetVarint(*pp, &iVal); - if( bDescIdx ){ - *pVal -= iVal; - }else{ - *pVal += iVal; - } - } -} - -/* -** This function is used to write a single varint to a buffer. The varint -** is written to *pp. Before returning, *pp is set to point 1 byte past the -** end of the value written. -** -** If *pbFirst is zero when this function is called, the value written to -** the buffer is that of parameter iVal. -** -** If *pbFirst is non-zero when this function is called, then the value -** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal) -** (if bDescIdx is non-zero). -** -** Before returning, this function always sets *pbFirst to 1 and *piPrev -** to the value of parameter iVal. -*/ -static void fts3PutDeltaVarint3( - char **pp, /* IN/OUT: Output pointer */ - int bDescIdx, /* True for descending docids */ - sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ - int *pbFirst, /* IN/OUT: True after first int written */ - sqlite3_int64 iVal /* Write this value to the list */ -){ - sqlite3_int64 iWrite; - if( bDescIdx==0 || *pbFirst==0 ){ - iWrite = iVal - *piPrev; - }else{ - iWrite = *piPrev - iVal; - } - assert( *pbFirst || *piPrev==0 ); - assert( *pbFirst==0 || iWrite>0 ); - *pp += sqlite3Fts3PutVarint(*pp, iWrite); - *piPrev = iVal; - *pbFirst = 1; -} - - -/* -** This macro is used by various functions that merge doclists. The two -** arguments are 64-bit docid values. If the value of the stack variable -** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). -** Otherwise, (i2-i1). -** -** Using this makes it easier to write code that can merge doclists that are -** sorted in either ascending or descending order. -*/ -#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2)) - -/* -** This function does an "OR" merge of two doclists (output contains all -** positions contained in either argument doclist). If the docids in the -** input doclists are sorted in ascending order, parameter bDescDoclist -** should be false. If they are sorted in ascending order, it should be -** passed a non-zero value. -** -** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer -** containing the output doclist and SQLITE_OK is returned. In this case -** *pnOut is set to the number of bytes in the output doclist. -** -** If an error occurs, an SQLite error code is returned. The output values -** are undefined in this case. -*/ -static int fts3DoclistOrMerge( - int bDescDoclist, /* True if arguments are desc */ - char *a1, int n1, /* First doclist */ - char *a2, int n2, /* Second doclist */ - char **paOut, int *pnOut /* OUT: Malloc'd doclist */ -){ - sqlite3_int64 i1 = 0; - sqlite3_int64 i2 = 0; - sqlite3_int64 iPrev = 0; - char *pEnd1 = &a1[n1]; - char *pEnd2 = &a2[n2]; - char *p1 = a1; - char *p2 = a2; - char *p; - char *aOut; - int bFirstOut = 0; - - *paOut = 0; - *pnOut = 0; - - /* Allocate space for the output. Both the input and output doclists - ** are delta encoded. If they are in ascending order (bDescDoclist==0), - ** then the first docid in each list is simply encoded as a varint. For - ** each subsequent docid, the varint stored is the difference between the - ** current and previous docid (a positive number - since the list is in - ** ascending order). - ** - ** The first docid written to the output is therefore encoded using the - ** same number of bytes as it is in whichever of the input lists it is - ** read from. And each subsequent docid read from the same input list - ** consumes either the same or less bytes as it did in the input (since - ** the difference between it and the previous value in the output must - ** be a positive value less than or equal to the delta value read from - ** the input list). The same argument applies to all but the first docid - ** read from the 'other' list. And to the contents of all position lists - ** that will be copied and merged from the input to the output. - ** - ** However, if the first docid copied to the output is a negative number, - ** then the encoding of the first docid from the 'other' input list may - ** be larger in the output than it was in the input (since the delta value - ** may be a larger positive integer than the actual docid). - ** - ** The space required to store the output is therefore the sum of the - ** sizes of the two inputs, plus enough space for exactly one of the input - ** docids to grow. - ** - ** A symetric argument may be made if the doclists are in descending - ** order. - */ - aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); - if( !aOut ) return SQLITE_NOMEM; - - p = aOut; - fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); - fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); - while( p1 || p2 ){ - sqlite3_int64 iDiff = DOCID_CMP(i1, i2); - - if( p2 && p1 && iDiff==0 ){ - fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); - fts3PoslistMerge(&p, &p1, &p2); - fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); - fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); - }else if( !p2 || (p1 && iDiff<0) ){ - fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); - fts3PoslistCopy(&p, &p1); - fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); - }else{ - fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); - fts3PoslistCopy(&p, &p2); - fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); - } - } - - *paOut = aOut; - *pnOut = (int)(p-aOut); - assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); - return SQLITE_OK; -} - -/* -** This function does a "phrase" merge of two doclists. In a phrase merge, -** the output contains a copy of each position from the right-hand input -** doclist for which there is a position in the left-hand input doclist -** exactly nDist tokens before it. -** -** If the docids in the input doclists are sorted in ascending order, -** parameter bDescDoclist should be false. If they are sorted in ascending -** order, it should be passed a non-zero value. -** -** The right-hand input doclist is overwritten by this function. -*/ -static int fts3DoclistPhraseMerge( - int bDescDoclist, /* True if arguments are desc */ - int nDist, /* Distance from left to right (1=adjacent) */ - char *aLeft, int nLeft, /* Left doclist */ - char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ -){ - sqlite3_int64 i1 = 0; - sqlite3_int64 i2 = 0; - sqlite3_int64 iPrev = 0; - char *aRight = *paRight; - char *pEnd1 = &aLeft[nLeft]; - char *pEnd2 = &aRight[*pnRight]; - char *p1 = aLeft; - char *p2 = aRight; - char *p; - int bFirstOut = 0; - char *aOut; - - assert( nDist>0 ); - if( bDescDoclist ){ - aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX); - if( aOut==0 ) return SQLITE_NOMEM; - }else{ - aOut = aRight; - } - p = aOut; - - fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); - fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); - - while( p1 && p2 ){ - sqlite3_int64 iDiff = DOCID_CMP(i1, i2); - if( iDiff==0 ){ - char *pSave = p; - sqlite3_int64 iPrevSave = iPrev; - int bFirstOutSave = bFirstOut; - - fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); - if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){ - p = pSave; - iPrev = iPrevSave; - bFirstOut = bFirstOutSave; - } - fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); - fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); - }else if( iDiff<0 ){ - fts3PoslistCopy(0, &p1); - fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); - }else{ - fts3PoslistCopy(0, &p2); - fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); - } - } - - *pnRight = (int)(p - aOut); - if( bDescDoclist ){ - sqlite3_free(aRight); - *paRight = aOut; - } - - return SQLITE_OK; -} - -/* -** Argument pList points to a position list nList bytes in size. This -** function checks to see if the position list contains any entries for -** a token in position 0 (of any column). If so, it writes argument iDelta -** to the output buffer pOut, followed by a position list consisting only -** of the entries from pList at position 0, and terminated by an 0x00 byte. -** The value returned is the number of bytes written to pOut (if any). -*/ -SQLITE_PRIVATE int sqlite3Fts3FirstFilter( - sqlite3_int64 iDelta, /* Varint that may be written to pOut */ - char *pList, /* Position list (no 0x00 term) */ - int nList, /* Size of pList in bytes */ - char *pOut /* Write output here */ -){ - int nOut = 0; - int bWritten = 0; /* True once iDelta has been written */ - char *p = pList; - char *pEnd = &pList[nList]; - - if( *p!=0x01 ){ - if( *p==0x02 ){ - nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta); - pOut[nOut++] = 0x02; - bWritten = 1; - } - fts3ColumnlistCopy(0, &p); - } - - while( paaOutput); i++){ - if( pTS->aaOutput[i] ){ - if( !aOut ){ - aOut = pTS->aaOutput[i]; - nOut = pTS->anOutput[i]; - pTS->aaOutput[i] = 0; - }else{ - int nNew; - char *aNew; - - int rc = fts3DoclistOrMerge(p->bDescIdx, - pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew - ); - if( rc!=SQLITE_OK ){ - sqlite3_free(aOut); - return rc; - } - - sqlite3_free(pTS->aaOutput[i]); - sqlite3_free(aOut); - pTS->aaOutput[i] = 0; - aOut = aNew; - nOut = nNew; - } - } - } - - pTS->aaOutput[0] = aOut; - pTS->anOutput[0] = nOut; - return SQLITE_OK; -} - -/* -** Merge the doclist aDoclist/nDoclist into the TermSelect object passed -** as the first argument. The merge is an "OR" merge (see function -** fts3DoclistOrMerge() for details). -** -** This function is called with the doclist for each term that matches -** a queried prefix. It merges all these doclists into one, the doclist -** for the specified prefix. Since there can be a very large number of -** doclists to merge, the merging is done pair-wise using the TermSelect -** object. -** -** This function returns SQLITE_OK if the merge is successful, or an -** SQLite error code (SQLITE_NOMEM) if an error occurs. -*/ -static int fts3TermSelectMerge( - Fts3Table *p, /* FTS table handle */ - TermSelect *pTS, /* TermSelect object to merge into */ - char *aDoclist, /* Pointer to doclist */ - int nDoclist /* Size of aDoclist in bytes */ -){ - if( pTS->aaOutput[0]==0 ){ - /* If this is the first term selected, copy the doclist to the output - ** buffer using memcpy(). - ** - ** Add FTS3_VARINT_MAX bytes of unused space to the end of the - ** allocation. This is so as to ensure that the buffer is big enough - ** to hold the current doclist AND'd with any other doclist. If the - ** doclists are stored in order=ASC order, this padding would not be - ** required (since the size of [doclistA AND doclistB] is always less - ** than or equal to the size of [doclistA] in that case). But this is - ** not true for order=DESC. For example, a doclist containing (1, -1) - ** may be smaller than (-1), as in the first example the -1 may be stored - ** as a single-byte delta, whereas in the second it must be stored as a - ** FTS3_VARINT_MAX byte varint. - ** - ** Similar padding is added in the fts3DoclistOrMerge() function. - */ - pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); - pTS->anOutput[0] = nDoclist; - if( pTS->aaOutput[0] ){ - memcpy(pTS->aaOutput[0], aDoclist, nDoclist); - }else{ - return SQLITE_NOMEM; - } - }else{ - char *aMerge = aDoclist; - int nMerge = nDoclist; - int iOut; - - for(iOut=0; iOutaaOutput); iOut++){ - if( pTS->aaOutput[iOut]==0 ){ - assert( iOut>0 ); - pTS->aaOutput[iOut] = aMerge; - pTS->anOutput[iOut] = nMerge; - break; - }else{ - char *aNew; - int nNew; - - int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge, - pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew - ); - if( rc!=SQLITE_OK ){ - if( aMerge!=aDoclist ) sqlite3_free(aMerge); - return rc; - } - - if( aMerge!=aDoclist ) sqlite3_free(aMerge); - sqlite3_free(pTS->aaOutput[iOut]); - pTS->aaOutput[iOut] = 0; - - aMerge = aNew; - nMerge = nNew; - if( (iOut+1)==SizeofArray(pTS->aaOutput) ){ - pTS->aaOutput[iOut] = aMerge; - pTS->anOutput[iOut] = nMerge; - } - } - } - } - return SQLITE_OK; -} - -/* -** Append SegReader object pNew to the end of the pCsr->apSegment[] array. -*/ -static int fts3SegReaderCursorAppend( - Fts3MultiSegReader *pCsr, - Fts3SegReader *pNew -){ - if( (pCsr->nSegment%16)==0 ){ - Fts3SegReader **apNew; - int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); - apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte); - if( !apNew ){ - sqlite3Fts3SegReaderFree(pNew); - return SQLITE_NOMEM; - } - pCsr->apSegment = apNew; - } - pCsr->apSegment[pCsr->nSegment++] = pNew; - return SQLITE_OK; -} - -/* -** Add seg-reader objects to the Fts3MultiSegReader object passed as the -** 8th argument. -** -** This function returns SQLITE_OK if successful, or an SQLite error code -** otherwise. -*/ -static int fts3SegReaderCursor( - Fts3Table *p, /* FTS3 table handle */ - int iLangid, /* Language id */ - int iIndex, /* Index to search (from 0 to p->nIndex-1) */ - int iLevel, /* Level of segments to scan */ - const char *zTerm, /* Term to query for */ - int nTerm, /* Size of zTerm in bytes */ - int isPrefix, /* True for a prefix search */ - int isScan, /* True to scan from zTerm to EOF */ - Fts3MultiSegReader *pCsr /* Cursor object to populate */ -){ - int rc = SQLITE_OK; /* Error code */ - sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ - int rc2; /* Result of sqlite3_reset() */ - - /* If iLevel is less than 0 and this is not a scan, include a seg-reader - ** for the pending-terms. If this is a scan, then this call must be being - ** made by an fts4aux module, not an FTS table. In this case calling - ** Fts3SegReaderPending might segfault, as the data structures used by - ** fts4aux are not completely populated. So it's easiest to filter these - ** calls out here. */ - if( iLevel<0 && p->aIndex ){ - Fts3SegReader *pSeg = 0; - rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); - if( rc==SQLITE_OK && pSeg ){ - rc = fts3SegReaderCursorAppend(pCsr, pSeg); - } - } - - if( iLevel!=FTS3_SEGCURSOR_PENDING ){ - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); - } - - while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ - Fts3SegReader *pSeg = 0; - - /* Read the values returned by the SELECT into local variables. */ - sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); - sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); - sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); - int nRoot = sqlite3_column_bytes(pStmt, 4); - char const *zRoot = sqlite3_column_blob(pStmt, 4); - - /* If zTerm is not NULL, and this segment is not stored entirely on its - ** root node, the range of leaves scanned can be reduced. Do this. */ - if( iStartBlock && zTerm ){ - sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); - rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); - if( rc!=SQLITE_OK ) goto finished; - if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; - } - - rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, - (isPrefix==0 && isScan==0), - iStartBlock, iLeavesEndBlock, - iEndBlock, zRoot, nRoot, &pSeg - ); - if( rc!=SQLITE_OK ) goto finished; - rc = fts3SegReaderCursorAppend(pCsr, pSeg); - } - } - - finished: - rc2 = sqlite3_reset(pStmt); - if( rc==SQLITE_DONE ) rc = rc2; - - return rc; -} - -/* -** Set up a cursor object for iterating through a full-text index or a -** single level therein. -*/ -SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( - Fts3Table *p, /* FTS3 table handle */ - int iLangid, /* Language-id to search */ - int iIndex, /* Index to search (from 0 to p->nIndex-1) */ - int iLevel, /* Level of segments to scan */ - const char *zTerm, /* Term to query for */ - int nTerm, /* Size of zTerm in bytes */ - int isPrefix, /* True for a prefix search */ - int isScan, /* True to scan from zTerm to EOF */ - Fts3MultiSegReader *pCsr /* Cursor object to populate */ -){ - assert( iIndex>=0 && iIndexnIndex ); - assert( iLevel==FTS3_SEGCURSOR_ALL - || iLevel==FTS3_SEGCURSOR_PENDING - || iLevel>=0 - ); - assert( iLevelbase.pVtab; - - if( isPrefix ){ - for(i=1; bFound==0 && inIndex; i++){ - if( p->aIndex[i].nPrefix==nTerm ){ - bFound = 1; - rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, - i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr - ); - pSegcsr->bLookup = 1; - } - } - - for(i=1; bFound==0 && inIndex; i++){ - if( p->aIndex[i].nPrefix==nTerm+1 ){ - bFound = 1; - rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, - i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr - ); - if( rc==SQLITE_OK ){ - rc = fts3SegReaderCursorAddZero( - p, pCsr->iLangid, zTerm, nTerm, pSegcsr - ); - } - } - } - } - - if( bFound==0 ){ - rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, - 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr - ); - pSegcsr->bLookup = !isPrefix; - } - } - - *ppSegcsr = pSegcsr; - return rc; -} - -/* -** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). -*/ -static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ - sqlite3Fts3SegReaderFinish(pSegcsr); - sqlite3_free(pSegcsr); -} - -/* -** This function retrieves the doclist for the specified term (or term -** prefix) from the database. -*/ -static int fts3TermSelect( - Fts3Table *p, /* Virtual table handle */ - Fts3PhraseToken *pTok, /* Token to query for */ - int iColumn, /* Column to query (or -ve for all columns) */ - int *pnOut, /* OUT: Size of buffer at *ppOut */ - char **ppOut /* OUT: Malloced result buffer */ -){ - int rc; /* Return code */ - Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */ - TermSelect tsc; /* Object for pair-wise doclist merging */ - Fts3SegFilter filter; /* Segment term filter configuration */ - - pSegcsr = pTok->pSegcsr; - memset(&tsc, 0, sizeof(TermSelect)); - - filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS - | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0) - | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0) - | (iColumnnColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); - filter.iCol = iColumn; - filter.zTerm = pTok->z; - filter.nTerm = pTok->n; - - rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); - while( SQLITE_OK==rc - && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) - ){ - rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); - } - - if( rc==SQLITE_OK ){ - rc = fts3TermSelectFinishMerge(p, &tsc); - } - if( rc==SQLITE_OK ){ - *ppOut = tsc.aaOutput[0]; - *pnOut = tsc.anOutput[0]; - }else{ - int i; - for(i=0; ipSegcsr = 0; - return rc; -} - -/* -** This function counts the total number of docids in the doclist stored -** in buffer aList[], size nList bytes. -** -** If the isPoslist argument is true, then it is assumed that the doclist -** contains a position-list following each docid. Otherwise, it is assumed -** that the doclist is simply a list of docids stored as delta encoded -** varints. -*/ -static int fts3DoclistCountDocids(char *aList, int nList){ - int nDoc = 0; /* Return value */ - if( aList ){ - char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */ - char *p = aList; /* Cursor */ - while( peSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ - if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ - pCsr->isEof = 1; - rc = sqlite3_reset(pCsr->pStmt); - }else{ - pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); - rc = SQLITE_OK; - } - }else{ - rc = fts3EvalNext((Fts3Cursor *)pCursor); - } - assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - return rc; -} - -/* -** The following are copied from sqliteInt.h. -** -** Constants for the largest and smallest possible 64-bit signed integers. -** These macros are designed to work correctly on both 32-bit and 64-bit -** compilers. -*/ -#ifndef SQLITE_AMALGAMATION -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - -/* -** If the numeric type of argument pVal is "integer", then return it -** converted to a 64-bit signed integer. Otherwise, return a copy of -** the second parameter, iDefault. -*/ -static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ - if( pVal ){ - int eType = sqlite3_value_numeric_type(pVal); - if( eType==SQLITE_INTEGER ){ - return sqlite3_value_int64(pVal); - } - } - return iDefault; -} - -/* -** This is the xFilter interface for the virtual table. See -** the virtual table xFilter method documentation for additional -** information. -** -** If idxNum==FTS3_FULLSCAN_SEARCH then do a full table scan against -** the %_content table. -** -** If idxNum==FTS3_DOCID_SEARCH then do a docid lookup for a single entry -** in the %_content table. -** -** If idxNum>=FTS3_FULLTEXT_SEARCH then use the full text index. The -** column on the left-hand side of the MATCH operator is column -** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand -** side of the MATCH operator. -*/ -static int fts3FilterMethod( - sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ - int idxNum, /* Strategy index */ - const char *idxStr, /* Unused */ - int nVal, /* Number of elements in apVal */ - sqlite3_value **apVal /* Arguments for the indexing scheme */ -){ - int rc = SQLITE_OK; - char *zSql; /* SQL statement used to access %_content */ - int eSearch; - Fts3Table *p = (Fts3Table *)pCursor->pVtab; - Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; - - sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ - sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ - sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ - sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ - int iIdx; - - UNUSED_PARAMETER(idxStr); - UNUSED_PARAMETER(nVal); - - eSearch = (idxNum & 0x0000FFFF); - assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); - assert( p->pSegments==0 ); - - /* Collect arguments into local variables */ - iIdx = 0; - if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; - if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; - if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; - if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; - assert( iIdx==nVal ); - - /* In case the cursor has been used before, clear it now. */ - sqlite3_finalize(pCsr->pStmt); - sqlite3_free(pCsr->aDoclist); - sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); - sqlite3Fts3ExprFree(pCsr->pExpr); - memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); - - /* Set the lower and upper bounds on docids to return */ - pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); - pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); - - if( idxStr ){ - pCsr->bDesc = (idxStr[0]=='D'); - }else{ - pCsr->bDesc = p->bDescIdx; - } - pCsr->eSearch = (i16)eSearch; - - if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ - int iCol = eSearch-FTS3_FULLTEXT_SEARCH; - const char *zQuery = (const char *)sqlite3_value_text(pCons); - - if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ - return SQLITE_NOMEM; - } - - pCsr->iLangid = 0; - if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); - - assert( p->base.zErrMsg==0 ); - rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, - p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, - &p->base.zErrMsg - ); - if( rc!=SQLITE_OK ){ - return rc; - } - - rc = fts3EvalStart(pCsr); - sqlite3Fts3SegmentsClose(p); - if( rc!=SQLITE_OK ) return rc; - pCsr->pNextId = pCsr->aDoclist; - pCsr->iPrevId = 0; - } - - /* Compile a SELECT statement for this cursor. For a full-table-scan, the - ** statement loops through all rows of the %_content table. For a - ** full-text query or docid lookup, the statement retrieves a single - ** row by docid. - */ - if( eSearch==FTS3_FULLSCAN_SEARCH ){ - if( pDocidGe || pDocidLe ){ - zSql = sqlite3_mprintf( - "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", - p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, - (pCsr->bDesc ? "DESC" : "ASC") - ); - }else{ - zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", - p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") - ); - } - if( zSql ){ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - }else if( eSearch==FTS3_DOCID_SEARCH ){ - rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt); - if( rc==SQLITE_OK ){ - rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); - } - } - if( rc!=SQLITE_OK ) return rc; - - return fts3NextMethod(pCursor); -} - -/* -** This is the xEof method of the virtual table. SQLite calls this -** routine to find out if it has reached the end of a result set. -*/ -static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ - return ((Fts3Cursor *)pCursor)->isEof; -} - -/* -** This is the xRowid method. The SQLite core calls this routine to -** retrieve the rowid for the current row of the result set. fts3 -** exposes %_content.docid as the rowid for the virtual table. The -** rowid should be written to *pRowid. -*/ -static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ - Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; - *pRowid = pCsr->iPrevId; - return SQLITE_OK; -} - -/* -** This is the xColumn method, called by SQLite to request a value from -** the row that the supplied cursor currently points to. -** -** If: -** -** (iCol < p->nColumn) -> The value of the iCol'th user column. -** (iCol == p->nColumn) -> Magic column with the same name as the table. -** (iCol == p->nColumn+1) -> Docid column -** (iCol == p->nColumn+2) -> Langid column -*/ -static int fts3ColumnMethod( - sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ - int iCol /* Index of column to read value from */ -){ - int rc = SQLITE_OK; /* Return Code */ - Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; - Fts3Table *p = (Fts3Table *)pCursor->pVtab; - - /* The column value supplied by SQLite must be in range. */ - assert( iCol>=0 && iCol<=p->nColumn+2 ); - - if( iCol==p->nColumn+1 ){ - /* This call is a request for the "docid" column. Since "docid" is an - ** alias for "rowid", use the xRowid() method to obtain the value. - */ - sqlite3_result_int64(pCtx, pCsr->iPrevId); - }else if( iCol==p->nColumn ){ - /* The extra column whose name is the same as the table. - ** Return a blob which is a pointer to the cursor. */ - sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT); - }else if( iCol==p->nColumn+2 && pCsr->pExpr ){ - sqlite3_result_int64(pCtx, pCsr->iLangid); - }else{ - /* The requested column is either a user column (one that contains - ** indexed data), or the language-id column. */ - rc = fts3CursorSeek(0, pCsr); - - if( rc==SQLITE_OK ){ - if( iCol==p->nColumn+2 ){ - int iLangid = 0; - if( p->zLanguageid ){ - iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1); - } - sqlite3_result_int(pCtx, iLangid); - }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){ - sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); - } - } - } - - assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - return rc; -} - -/* -** This function is the implementation of the xUpdate callback used by -** FTS3 virtual tables. It is invoked by SQLite each time a row is to be -** inserted, updated or deleted. -*/ -static int fts3UpdateMethod( - sqlite3_vtab *pVtab, /* Virtual table handle */ - int nArg, /* Size of argument array */ - sqlite3_value **apVal, /* Array of arguments */ - sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ -){ - return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); -} - -/* -** Implementation of xSync() method. Flush the contents of the pending-terms -** hash-table to the database. -*/ -static int fts3SyncMethod(sqlite3_vtab *pVtab){ - - /* Following an incremental-merge operation, assuming that the input - ** segments are not completely consumed (the usual case), they are updated - ** in place to remove the entries that have already been merged. This - ** involves updating the leaf block that contains the smallest unmerged - ** entry and each block (if any) between the leaf and the root node. So - ** if the height of the input segment b-trees is N, and input segments - ** are merged eight at a time, updating the input segments at the end - ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually - ** small - often between 0 and 2. So the overhead of the incremental - ** merge is somewhere between 8 and 24 blocks. To avoid this overhead - ** dwarfing the actual productive work accomplished, the incremental merge - ** is only attempted if it will write at least 64 leaf blocks. Hence - ** nMinMerge. - ** - ** Of course, updating the input segments also involves deleting a bunch - ** of blocks from the segments table. But this is not considered overhead - ** as it would also be required by a crisis-merge that used the same input - ** segments. - */ - const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ - - Fts3Table *p = (Fts3Table*)pVtab; - int rc = sqlite3Fts3PendingTermsFlush(p); - - if( rc==SQLITE_OK - && p->nLeafAdd>(nMinMerge/16) - && p->nAutoincrmerge && p->nAutoincrmerge!=0xff - ){ - int mxLevel = 0; /* Maximum relative level value in db */ - int A; /* Incr-merge parameter A */ - - rc = sqlite3Fts3MaxLevel(p, &mxLevel); - assert( rc==SQLITE_OK || mxLevel==0 ); - A = p->nLeafAdd * mxLevel; - A += (A/2); - if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); - } - sqlite3Fts3SegmentsClose(p); - return rc; -} - -/* -** If it is currently unknown whether or not the FTS table has an %_stat -** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat -** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code -** if an error occurs. -*/ -static int fts3SetHasStat(Fts3Table *p){ - int rc = SQLITE_OK; - if( p->bHasStat==2 ){ - const char *zFmt ="SELECT 1 FROM %Q.sqlite_master WHERE tbl_name='%q_stat'"; - char *zSql = sqlite3_mprintf(zFmt, p->zDb, p->zName); - if( zSql ){ - sqlite3_stmt *pStmt = 0; - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - if( rc==SQLITE_OK ){ - int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW); - rc = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) p->bHasStat = bHasStat; - } - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - } - return rc; -} - -/* -** Implementation of xBegin() method. -*/ -static int fts3BeginMethod(sqlite3_vtab *pVtab){ - Fts3Table *p = (Fts3Table*)pVtab; - UNUSED_PARAMETER(pVtab); - assert( p->pSegments==0 ); - assert( p->nPendingData==0 ); - assert( p->inTransaction!=1 ); - TESTONLY( p->inTransaction = 1 ); - TESTONLY( p->mxSavepoint = -1; ); - p->nLeafAdd = 0; - return fts3SetHasStat(p); -} - -/* -** Implementation of xCommit() method. This is a no-op. The contents of -** the pending-terms hash-table have already been flushed into the database -** by fts3SyncMethod(). -*/ -static int fts3CommitMethod(sqlite3_vtab *pVtab){ - TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); - UNUSED_PARAMETER(pVtab); - assert( p->nPendingData==0 ); - assert( p->inTransaction!=0 ); - assert( p->pSegments==0 ); - TESTONLY( p->inTransaction = 0 ); - TESTONLY( p->mxSavepoint = -1; ); - return SQLITE_OK; -} - -/* -** Implementation of xRollback(). Discard the contents of the pending-terms -** hash-table. Any changes made to the database are reverted by SQLite. -*/ -static int fts3RollbackMethod(sqlite3_vtab *pVtab){ - Fts3Table *p = (Fts3Table*)pVtab; - sqlite3Fts3PendingTermsClear(p); - assert( p->inTransaction!=0 ); - TESTONLY( p->inTransaction = 0 ); - TESTONLY( p->mxSavepoint = -1; ); - return SQLITE_OK; -} - -/* -** When called, *ppPoslist must point to the byte immediately following the -** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function -** moves *ppPoslist so that it instead points to the first byte of the -** same position list. -*/ -static void fts3ReversePoslist(char *pStart, char **ppPoslist){ - char *p = &(*ppPoslist)[-2]; - char c = 0; - - /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ - while( p>pStart && (c=*p--)==0 ); - - /* Search backwards for a varint with value zero (the end of the previous - ** poslist). This is an 0x00 byte preceded by some byte that does not - ** have the 0x80 bit set. */ - while( p>pStart && (*p & 0x80) | c ){ - c = *p--; - } - assert( p==pStart || c==0 ); - - /* At this point p points to that preceding byte without the 0x80 bit - ** set. So to find the start of the poslist, skip forward 2 bytes then - ** over a varint. - ** - ** Normally. The other case is that p==pStart and the poslist to return - ** is the first in the doclist. In this case do not skip forward 2 bytes. - ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) - ** is required for cases where the first byte of a doclist and the - ** doclist is empty. For example, if the first docid is 10, a doclist - ** that begins with: - ** - ** 0x0A 0x00 - */ - if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } - while( *p++&0x80 ); - *ppPoslist = p; -} - -/* -** Helper function used by the implementation of the overloaded snippet(), -** offsets() and optimize() SQL functions. -** -** If the value passed as the third argument is a blob of size -** sizeof(Fts3Cursor*), then the blob contents are copied to the -** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error -** message is written to context pContext and SQLITE_ERROR returned. The -** string passed via zFunc is used as part of the error message. -*/ -static int fts3FunctionArg( - sqlite3_context *pContext, /* SQL function call context */ - const char *zFunc, /* Function name */ - sqlite3_value *pVal, /* argv[0] passed to function */ - Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ -){ - Fts3Cursor *pRet; - if( sqlite3_value_type(pVal)!=SQLITE_BLOB - || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *) - ){ - char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); - sqlite3_result_error(pContext, zErr, -1); - sqlite3_free(zErr); - return SQLITE_ERROR; - } - memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *)); - *ppCsr = pRet; - return SQLITE_OK; -} - -/* -** Implementation of the snippet() function for FTS3 -*/ -static void fts3SnippetFunc( - sqlite3_context *pContext, /* SQLite function call context */ - int nVal, /* Size of apVal[] array */ - sqlite3_value **apVal /* Array of arguments */ -){ - Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ - const char *zStart = ""; - const char *zEnd = ""; - const char *zEllipsis = "..."; - int iCol = -1; - int nToken = 15; /* Default number of tokens in snippet */ - - /* There must be at least one argument passed to this function (otherwise - ** the non-overloaded version would have been called instead of this one). - */ - assert( nVal>=1 ); - - if( nVal>6 ){ - sqlite3_result_error(pContext, - "wrong number of arguments to function snippet()", -1); - return; - } - if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; - - switch( nVal ){ - case 6: nToken = sqlite3_value_int(apVal[5]); - case 5: iCol = sqlite3_value_int(apVal[4]); - case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); - case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); - case 2: zStart = (const char*)sqlite3_value_text(apVal[1]); - } - if( !zEllipsis || !zEnd || !zStart ){ - sqlite3_result_error_nomem(pContext); - }else if( nToken==0 ){ - sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); - }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ - sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); - } -} - -/* -** Implementation of the offsets() function for FTS3 -*/ -static void fts3OffsetsFunc( - sqlite3_context *pContext, /* SQLite function call context */ - int nVal, /* Size of argument array */ - sqlite3_value **apVal /* Array of arguments */ -){ - Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ - - UNUSED_PARAMETER(nVal); - - assert( nVal==1 ); - if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return; - assert( pCsr ); - if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ - sqlite3Fts3Offsets(pContext, pCsr); - } -} - -/* -** Implementation of the special optimize() function for FTS3. This -** function merges all segments in the database to a single segment. -** Example usage is: -** -** SELECT optimize(t) FROM t LIMIT 1; -** -** where 't' is the name of an FTS3 table. -*/ -static void fts3OptimizeFunc( - sqlite3_context *pContext, /* SQLite function call context */ - int nVal, /* Size of argument array */ - sqlite3_value **apVal /* Array of arguments */ -){ - int rc; /* Return code */ - Fts3Table *p; /* Virtual table handle */ - Fts3Cursor *pCursor; /* Cursor handle passed through apVal[0] */ - - UNUSED_PARAMETER(nVal); - - assert( nVal==1 ); - if( fts3FunctionArg(pContext, "optimize", apVal[0], &pCursor) ) return; - p = (Fts3Table *)pCursor->base.pVtab; - assert( p ); - - rc = sqlite3Fts3Optimize(p); - - switch( rc ){ - case SQLITE_OK: - sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); - break; - case SQLITE_DONE: - sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); - break; - default: - sqlite3_result_error_code(pContext, rc); - break; - } -} - -/* -** Implementation of the matchinfo() function for FTS3 -*/ -static void fts3MatchinfoFunc( - sqlite3_context *pContext, /* SQLite function call context */ - int nVal, /* Size of argument array */ - sqlite3_value **apVal /* Array of arguments */ -){ - Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ - assert( nVal==1 || nVal==2 ); - if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ - const char *zArg = 0; - if( nVal>1 ){ - zArg = (const char *)sqlite3_value_text(apVal[1]); - } - sqlite3Fts3Matchinfo(pContext, pCsr, zArg); - } -} - -/* -** This routine implements the xFindFunction method for the FTS3 -** virtual table. -*/ -static int fts3FindFunctionMethod( - sqlite3_vtab *pVtab, /* Virtual table handle */ - int nArg, /* Number of SQL function arguments */ - const char *zName, /* Name of SQL function */ - void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ - void **ppArg /* Unused */ -){ - struct Overloaded { - const char *zName; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } aOverload[] = { - { "snippet", fts3SnippetFunc }, - { "offsets", fts3OffsetsFunc }, - { "optimize", fts3OptimizeFunc }, - { "matchinfo", fts3MatchinfoFunc }, - }; - int i; /* Iterator variable */ - - UNUSED_PARAMETER(pVtab); - UNUSED_PARAMETER(nArg); - UNUSED_PARAMETER(ppArg); - - for(i=0; idb; /* Database connection */ - int rc; /* Return Code */ - - /* At this point it must be known if the %_stat table exists or not. - ** So bHasStat may not be 2. */ - rc = fts3SetHasStat(p); - - /* As it happens, the pending terms table is always empty here. This is - ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction - ** always opens a savepoint transaction. And the xSavepoint() method - ** flushes the pending terms table. But leave the (no-op) call to - ** PendingTermsFlush() in in case that changes. - */ - assert( p->nPendingData==0 ); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3PendingTermsFlush(p); - } - - if( p->zContentTbl==0 ){ - fts3DbExec(&rc, db, - "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", - p->zDb, p->zName, zName - ); - } - - if( p->bHasDocsize ){ - fts3DbExec(&rc, db, - "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';", - p->zDb, p->zName, zName - ); - } - if( p->bHasStat ){ - fts3DbExec(&rc, db, - "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';", - p->zDb, p->zName, zName - ); - } - fts3DbExec(&rc, db, - "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';", - p->zDb, p->zName, zName - ); - fts3DbExec(&rc, db, - "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", - p->zDb, p->zName, zName - ); - return rc; -} - -/* -** The xSavepoint() method. -** -** Flush the contents of the pending-terms table to disk. -*/ -static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - int rc = SQLITE_OK; - UNUSED_PARAMETER(iSavepoint); - assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); - TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); - if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ - rc = fts3SyncMethod(pVtab); - } - return rc; -} - -/* -** The xRelease() method. -** -** This is a no-op. -*/ -static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); - UNUSED_PARAMETER(iSavepoint); - UNUSED_PARAMETER(pVtab); - assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); - TESTONLY( p->mxSavepoint = iSavepoint-1 ); - return SQLITE_OK; -} - -/* -** The xRollbackTo() method. -** -** Discard the contents of the pending terms table. -*/ -static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *p = (Fts3Table*)pVtab; - UNUSED_PARAMETER(iSavepoint); - assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); - TESTONLY( p->mxSavepoint = iSavepoint ); - sqlite3Fts3PendingTermsClear(p); - return SQLITE_OK; -} - -static const sqlite3_module fts3Module = { - /* iVersion */ 2, - /* xCreate */ fts3CreateMethod, - /* xConnect */ fts3ConnectMethod, - /* xBestIndex */ fts3BestIndexMethod, - /* xDisconnect */ fts3DisconnectMethod, - /* xDestroy */ fts3DestroyMethod, - /* xOpen */ fts3OpenMethod, - /* xClose */ fts3CloseMethod, - /* xFilter */ fts3FilterMethod, - /* xNext */ fts3NextMethod, - /* xEof */ fts3EofMethod, - /* xColumn */ fts3ColumnMethod, - /* xRowid */ fts3RowidMethod, - /* xUpdate */ fts3UpdateMethod, - /* xBegin */ fts3BeginMethod, - /* xSync */ fts3SyncMethod, - /* xCommit */ fts3CommitMethod, - /* xRollback */ fts3RollbackMethod, - /* xFindFunction */ fts3FindFunctionMethod, - /* xRename */ fts3RenameMethod, - /* xSavepoint */ fts3SavepointMethod, - /* xRelease */ fts3ReleaseMethod, - /* xRollbackTo */ fts3RollbackToMethod, -}; - -/* -** This function is registered as the module destructor (called when an -** FTS3 enabled database connection is closed). It frees the memory -** allocated for the tokenizer hash table. -*/ -static void hashDestroy(void *p){ - Fts3Hash *pHash = (Fts3Hash *)p; - sqlite3Fts3HashClear(pHash); - sqlite3_free(pHash); -} - -/* -** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are -** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c -** respectively. The following three forward declarations are for functions -** declared in these files used to retrieve the respective implementations. -** -** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed -** to by the argument to point to the "simple" tokenizer implementation. -** And so on. -*/ -SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); -SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); -#ifndef SQLITE_DISABLE_FTS3_UNICODE -SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); -#endif -#ifdef SQLITE_ENABLE_ICU -SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); -#endif - -/* -** Initialize the fts3 extension. If this extension is built as part -** of the sqlite library, then this function is called directly by -** SQLite. If fts3 is built as a dynamically loadable extension, this -** function is called by the sqlite3_extension_init() entry point. -*/ -SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ - int rc = SQLITE_OK; - Fts3Hash *pHash = 0; - const sqlite3_tokenizer_module *pSimple = 0; - const sqlite3_tokenizer_module *pPorter = 0; -#ifndef SQLITE_DISABLE_FTS3_UNICODE - const sqlite3_tokenizer_module *pUnicode = 0; -#endif - -#ifdef SQLITE_ENABLE_ICU - const sqlite3_tokenizer_module *pIcu = 0; - sqlite3Fts3IcuTokenizerModule(&pIcu); -#endif - -#ifndef SQLITE_DISABLE_FTS3_UNICODE - sqlite3Fts3UnicodeTokenizer(&pUnicode); -#endif - -#ifdef SQLITE_TEST - rc = sqlite3Fts3InitTerm(db); - if( rc!=SQLITE_OK ) return rc; -#endif - - rc = sqlite3Fts3InitAux(db); - if( rc!=SQLITE_OK ) return rc; - - sqlite3Fts3SimpleTokenizerModule(&pSimple); - sqlite3Fts3PorterTokenizerModule(&pPorter); - - /* Allocate and initialize the hash-table used to store tokenizers. */ - pHash = sqlite3_malloc(sizeof(Fts3Hash)); - if( !pHash ){ - rc = SQLITE_NOMEM; - }else{ - sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); - } - - /* Load the built-in tokenizers into the hash table */ - if( rc==SQLITE_OK ){ - if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) - || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) - -#ifndef SQLITE_DISABLE_FTS3_UNICODE - || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) -#endif -#ifdef SQLITE_ENABLE_ICU - || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) -#endif - ){ - rc = SQLITE_NOMEM; - } - } - -#ifdef SQLITE_TEST - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ExprInitTestInterface(db); - } -#endif - - /* Create the virtual table wrapper around the hash-table and overload - ** the two scalar functions. If this is successful, register the - ** module with sqlite. - */ - if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) - && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) - ){ - rc = sqlite3_create_module_v2( - db, "fts3", &fts3Module, (void *)pHash, hashDestroy - ); - if( rc==SQLITE_OK ){ - rc = sqlite3_create_module_v2( - db, "fts4", &fts3Module, (void *)pHash, 0 - ); - } - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3InitTok(db, (void *)pHash); - } - return rc; - } - - - /* An error has occurred. Delete the hash table and return the error code. */ - assert( rc!=SQLITE_OK ); - if( pHash ){ - sqlite3Fts3HashClear(pHash); - sqlite3_free(pHash); - } - return rc; -} - -/* -** Allocate an Fts3MultiSegReader for each token in the expression headed -** by pExpr. -** -** An Fts3SegReader object is a cursor that can seek or scan a range of -** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple -** Fts3SegReader objects internally to provide an interface to seek or scan -** within the union of all segments of a b-tree. Hence the name. -** -** If the allocated Fts3MultiSegReader just seeks to a single entry in a -** segment b-tree (if the term is not a prefix or it is a prefix for which -** there exists prefix b-tree of the right length) then it may be traversed -** and merged incrementally. Otherwise, it has to be merged into an in-memory -** doclist and then traversed. -*/ -static void fts3EvalAllocateReaders( - Fts3Cursor *pCsr, /* FTS cursor handle */ - Fts3Expr *pExpr, /* Allocate readers for this expression */ - int *pnToken, /* OUT: Total number of tokens in phrase. */ - int *pnOr, /* OUT: Total number of OR nodes in expr. */ - int *pRc /* IN/OUT: Error code */ -){ - if( pExpr && SQLITE_OK==*pRc ){ - if( pExpr->eType==FTSQUERY_PHRASE ){ - int i; - int nToken = pExpr->pPhrase->nToken; - *pnToken += nToken; - for(i=0; ipPhrase->aToken[i]; - int rc = fts3TermSegReaderCursor(pCsr, - pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr - ); - if( rc!=SQLITE_OK ){ - *pRc = rc; - return; - } - } - assert( pExpr->pPhrase->iDoclistToken==0 ); - pExpr->pPhrase->iDoclistToken = -1; - }else{ - *pnOr += (pExpr->eType==FTSQUERY_OR); - fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); - fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); - } - } -} - -/* -** Arguments pList/nList contain the doclist for token iToken of phrase p. -** It is merged into the main doclist stored in p->doclist.aAll/nAll. -** -** This function assumes that pList points to a buffer allocated using -** sqlite3_malloc(). This function takes responsibility for eventually -** freeing the buffer. -** -** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. -*/ -static int fts3EvalPhraseMergeToken( - Fts3Table *pTab, /* FTS Table pointer */ - Fts3Phrase *p, /* Phrase to merge pList/nList into */ - int iToken, /* Token pList/nList corresponds to */ - char *pList, /* Pointer to doclist */ - int nList /* Number of bytes in pList */ -){ - int rc = SQLITE_OK; - assert( iToken!=p->iDoclistToken ); - - if( pList==0 ){ - sqlite3_free(p->doclist.aAll); - p->doclist.aAll = 0; - p->doclist.nAll = 0; - } - - else if( p->iDoclistToken<0 ){ - p->doclist.aAll = pList; - p->doclist.nAll = nList; - } - - else if( p->doclist.aAll==0 ){ - sqlite3_free(pList); - } - - else { - char *pLeft; - char *pRight; - int nLeft; - int nRight; - int nDiff; - - if( p->iDoclistTokendoclist.aAll; - nLeft = p->doclist.nAll; - pRight = pList; - nRight = nList; - nDiff = iToken - p->iDoclistToken; - }else{ - pRight = p->doclist.aAll; - nRight = p->doclist.nAll; - pLeft = pList; - nLeft = nList; - nDiff = p->iDoclistToken - iToken; - } - - rc = fts3DoclistPhraseMerge( - pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight - ); - sqlite3_free(pLeft); - p->doclist.aAll = pRight; - p->doclist.nAll = nRight; - } - - if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; - return rc; -} - -/* -** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist -** does not take deferred tokens into account. -** -** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. -*/ -static int fts3EvalPhraseLoad( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Phrase *p /* Phrase object */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int iToken; - int rc = SQLITE_OK; - - for(iToken=0; rc==SQLITE_OK && iTokennToken; iToken++){ - Fts3PhraseToken *pToken = &p->aToken[iToken]; - assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); - - if( pToken->pSegcsr ){ - int nThis = 0; - char *pThis = 0; - rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); - if( rc==SQLITE_OK ){ - rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); - } - } - assert( pToken->pSegcsr==0 ); - } - - return rc; -} - -/* -** This function is called on each phrase after the position lists for -** any deferred tokens have been loaded into memory. It updates the phrases -** current position list to include only those positions that are really -** instances of the phrase (after considering deferred tokens). If this -** means that the phrase does not appear in the current row, doclist.pList -** and doclist.nList are both zeroed. -** -** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. -*/ -static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ - int iToken; /* Used to iterate through phrase tokens */ - char *aPoslist = 0; /* Position list for deferred tokens */ - int nPoslist = 0; /* Number of bytes in aPoslist */ - int iPrev = -1; /* Token number of previous deferred token */ - - assert( pPhrase->doclist.bFreeList==0 ); - - for(iToken=0; iTokennToken; iToken++){ - Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; - Fts3DeferredToken *pDeferred = pToken->pDeferred; - - if( pDeferred ){ - char *pList; - int nList; - int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); - if( rc!=SQLITE_OK ) return rc; - - if( pList==0 ){ - sqlite3_free(aPoslist); - pPhrase->doclist.pList = 0; - pPhrase->doclist.nList = 0; - return SQLITE_OK; - - }else if( aPoslist==0 ){ - aPoslist = pList; - nPoslist = nList; - - }else{ - char *aOut = pList; - char *p1 = aPoslist; - char *p2 = aOut; - - assert( iPrev>=0 ); - fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); - sqlite3_free(aPoslist); - aPoslist = pList; - nPoslist = (int)(aOut - aPoslist); - if( nPoslist==0 ){ - sqlite3_free(aPoslist); - pPhrase->doclist.pList = 0; - pPhrase->doclist.nList = 0; - return SQLITE_OK; - } - } - iPrev = iToken; - } - } - - if( iPrev>=0 ){ - int nMaxUndeferred = pPhrase->iDoclistToken; - if( nMaxUndeferred<0 ){ - pPhrase->doclist.pList = aPoslist; - pPhrase->doclist.nList = nPoslist; - pPhrase->doclist.iDocid = pCsr->iPrevId; - pPhrase->doclist.bFreeList = 1; - }else{ - int nDistance; - char *p1; - char *p2; - char *aOut; - - if( nMaxUndeferred>iPrev ){ - p1 = aPoslist; - p2 = pPhrase->doclist.pList; - nDistance = nMaxUndeferred - iPrev; - }else{ - p1 = pPhrase->doclist.pList; - p2 = aPoslist; - nDistance = iPrev - nMaxUndeferred; - } - - aOut = (char *)sqlite3_malloc(nPoslist+8); - if( !aOut ){ - sqlite3_free(aPoslist); - return SQLITE_NOMEM; - } - - pPhrase->doclist.pList = aOut; - if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ - pPhrase->doclist.bFreeList = 1; - pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); - }else{ - sqlite3_free(aOut); - pPhrase->doclist.pList = 0; - pPhrase->doclist.nList = 0; - } - sqlite3_free(aPoslist); - } - } - - return SQLITE_OK; -} - -/* -** Maximum number of tokens a phrase may have to be considered for the -** incremental doclists strategy. -*/ -#define MAX_INCR_PHRASE_TOKENS 4 - -/* -** This function is called for each Fts3Phrase in a full-text query -** expression to initialize the mechanism for returning rows. Once this -** function has been called successfully on an Fts3Phrase, it may be -** used with fts3EvalPhraseNext() to iterate through the matching docids. -** -** If parameter bOptOk is true, then the phrase may (or may not) use the -** incremental loading strategy. Otherwise, the entire doclist is loaded into -** memory within this call. -** -** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. -*/ -static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc = SQLITE_OK; /* Error code */ - int i; - - /* Determine if doclists may be loaded from disk incrementally. This is - ** possible if the bOptOk argument is true, the FTS doclists will be - ** scanned in forward order, and the phrase consists of - ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" - ** tokens or prefix tokens that cannot use a prefix-index. */ - int bHaveIncr = 0; - int bIncrOk = (bOptOk - && pCsr->bDesc==pTab->bDescIdx - && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 -#ifdef SQLITE_TEST - && pTab->bNoIncrDoclist==0 -#endif - ); - for(i=0; bIncrOk==1 && inToken; i++){ - Fts3PhraseToken *pToken = &p->aToken[i]; - if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ - bIncrOk = 0; - } - if( pToken->pSegcsr ) bHaveIncr = 1; - } - - if( bIncrOk && bHaveIncr ){ - /* Use the incremental approach. */ - int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); - for(i=0; rc==SQLITE_OK && inToken; i++){ - Fts3PhraseToken *pToken = &p->aToken[i]; - Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; - if( pSegcsr ){ - rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); - } - } - p->bIncr = 1; - }else{ - /* Load the full doclist for the phrase into memory. */ - rc = fts3EvalPhraseLoad(pCsr, p); - p->bIncr = 0; - } - - assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr ); - return rc; -} - -/* -** This function is used to iterate backwards (from the end to start) -** through doclists. It is used by this module to iterate through phrase -** doclists in reverse and by the fts3_write.c module to iterate through -** pending-terms lists when writing to databases with "order=desc". -** -** The doclist may be sorted in ascending (parameter bDescIdx==0) or -** descending (parameter bDescIdx==1) order of docid. Regardless, this -** function iterates from the end of the doclist to the beginning. -*/ -SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( - int bDescIdx, /* True if the doclist is desc */ - char *aDoclist, /* Pointer to entire doclist */ - int nDoclist, /* Length of aDoclist in bytes */ - char **ppIter, /* IN/OUT: Iterator pointer */ - sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ - int *pnList, /* OUT: List length pointer */ - u8 *pbEof /* OUT: End-of-file flag */ -){ - char *p = *ppIter; - - assert( nDoclist>0 ); - assert( *pbEof==0 ); - assert( p || *piDocid==0 ); - assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); - - if( p==0 ){ - sqlite3_int64 iDocid = 0; - char *pNext = 0; - char *pDocid = aDoclist; - char *pEnd = &aDoclist[nDoclist]; - int iMul = 1; - - while( pDocid0 ); - assert( *pbEof==0 ); - assert( p || *piDocid==0 ); - assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); - - if( p==0 ){ - p = aDoclist; - p += sqlite3Fts3GetVarint(p, piDocid); - }else{ - fts3PoslistCopy(0, &p); - while( p<&aDoclist[nDoclist] && *p==0 ) p++; - if( p>=&aDoclist[nDoclist] ){ - *pbEof = 1; - }else{ - sqlite3_int64 iVar; - p += sqlite3Fts3GetVarint(p, &iVar); - *piDocid += ((bDescIdx ? -1 : 1) * iVar); - } - } - - *ppIter = p; -} - -/* -** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof -** to true if EOF is reached. -*/ -static void fts3EvalDlPhraseNext( - Fts3Table *pTab, - Fts3Doclist *pDL, - u8 *pbEof -){ - char *pIter; /* Used to iterate through aAll */ - char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ - - if( pDL->pNextDocid ){ - pIter = pDL->pNextDocid; - }else{ - pIter = pDL->aAll; - } - - if( pIter>=pEnd ){ - /* We have already reached the end of this doclist. EOF. */ - *pbEof = 1; - }else{ - sqlite3_int64 iDelta; - pIter += sqlite3Fts3GetVarint(pIter, &iDelta); - if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ - pDL->iDocid += iDelta; - }else{ - pDL->iDocid -= iDelta; - } - pDL->pList = pIter; - fts3PoslistCopy(0, &pIter); - pDL->nList = (int)(pIter - pDL->pList); - - /* pIter now points just past the 0x00 that terminates the position- - ** list for document pDL->iDocid. However, if this position-list was - ** edited in place by fts3EvalNearTrim(), then pIter may not actually - ** point to the start of the next docid value. The following line deals - ** with this case by advancing pIter past the zero-padding added by - ** fts3EvalNearTrim(). */ - while( pIterpNextDocid = pIter; - assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); - *pbEof = 0; - } -} - -/* -** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). -*/ -typedef struct TokenDoclist TokenDoclist; -struct TokenDoclist { - int bIgnore; - sqlite3_int64 iDocid; - char *pList; - int nList; -}; - -/* -** Token pToken is an incrementally loaded token that is part of a -** multi-token phrase. Advance it to the next matching document in the -** database and populate output variable *p with the details of the new -** entry. Or, if the iterator has reached EOF, set *pbEof to true. -** -** If an error occurs, return an SQLite error code. Otherwise, return -** SQLITE_OK. -*/ -static int incrPhraseTokenNext( - Fts3Table *pTab, /* Virtual table handle */ - Fts3Phrase *pPhrase, /* Phrase to advance token of */ - int iToken, /* Specific token to advance */ - TokenDoclist *p, /* OUT: Docid and doclist for new entry */ - u8 *pbEof /* OUT: True if iterator is at EOF */ -){ - int rc = SQLITE_OK; - - if( pPhrase->iDoclistToken==iToken ){ - assert( p->bIgnore==0 ); - assert( pPhrase->aToken[iToken].pSegcsr==0 ); - fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); - p->pList = pPhrase->doclist.pList; - p->nList = pPhrase->doclist.nList; - p->iDocid = pPhrase->doclist.iDocid; - }else{ - Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; - assert( pToken->pDeferred==0 ); - assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); - if( pToken->pSegcsr ){ - assert( p->bIgnore==0 ); - rc = sqlite3Fts3MsrIncrNext( - pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList - ); - if( p->pList==0 ) *pbEof = 1; - }else{ - p->bIgnore = 1; - } - } - - return rc; -} - - -/* -** The phrase iterator passed as the second argument: -** -** * features at least one token that uses an incremental doclist, and -** -** * does not contain any deferred tokens. -** -** Advance it to the next matching documnent in the database and populate -** the Fts3Doclist.pList and nList fields. -** -** If there is no "next" entry and no error occurs, then *pbEof is set to -** 1 before returning. Otherwise, if no error occurs and the iterator is -** successfully advanced, *pbEof is set to 0. -** -** If an error occurs, return an SQLite error code. Otherwise, return -** SQLITE_OK. -*/ -static int fts3EvalIncrPhraseNext( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Phrase *p, /* Phrase object to advance to next docid */ - u8 *pbEof /* OUT: Set to 1 if EOF */ -){ - int rc = SQLITE_OK; - Fts3Doclist *pDL = &p->doclist; - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - u8 bEof = 0; - - /* This is only called if it is guaranteed that the phrase has at least - ** one incremental token. In which case the bIncr flag is set. */ - assert( p->bIncr==1 ); - - if( p->nToken==1 && p->bIncr ){ - rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, - &pDL->iDocid, &pDL->pList, &pDL->nList - ); - if( pDL->pList==0 ) bEof = 1; - }else{ - int bDescDoclist = pCsr->bDesc; - struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; - - memset(a, 0, sizeof(a)); - assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); - assert( p->iDoclistTokennToken && bEof==0; i++){ - rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); - if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ - iMax = a[i].iDocid; - bMaxSet = 1; - } - } - assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); - assert( rc!=SQLITE_OK || bMaxSet ); - - /* Keep advancing iterators until they all point to the same document */ - for(i=0; inToken; i++){ - while( rc==SQLITE_OK && bEof==0 - && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 - ){ - rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); - if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ - iMax = a[i].iDocid; - i = 0; - } - } - } - - /* Check if the current entries really are a phrase match */ - if( bEof==0 ){ - int nList = 0; - int nByte = a[p->nToken-1].nList; - char *aDoclist = sqlite3_malloc(nByte+1); - if( !aDoclist ) return SQLITE_NOMEM; - memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); - - for(i=0; i<(p->nToken-1); i++){ - if( a[i].bIgnore==0 ){ - char *pL = a[i].pList; - char *pR = aDoclist; - char *pOut = aDoclist; - int nDist = p->nToken-1-i; - int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); - if( res==0 ) break; - nList = (int)(pOut - aDoclist); - } - } - if( i==(p->nToken-1) ){ - pDL->iDocid = iMax; - pDL->pList = aDoclist; - pDL->nList = nList; - pDL->bFreeList = 1; - break; - } - sqlite3_free(aDoclist); - } - } - } - - *pbEof = bEof; - return rc; -} - -/* -** Attempt to move the phrase iterator to point to the next matching docid. -** If an error occurs, return an SQLite error code. Otherwise, return -** SQLITE_OK. -** -** If there is no "next" entry and no error occurs, then *pbEof is set to -** 1 before returning. Otherwise, if no error occurs and the iterator is -** successfully advanced, *pbEof is set to 0. -*/ -static int fts3EvalPhraseNext( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Phrase *p, /* Phrase object to advance to next docid */ - u8 *pbEof /* OUT: Set to 1 if EOF */ -){ - int rc = SQLITE_OK; - Fts3Doclist *pDL = &p->doclist; - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - - if( p->bIncr ){ - rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); - }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ - sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, - &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof - ); - pDL->pList = pDL->pNextDocid; - }else{ - fts3EvalDlPhraseNext(pTab, pDL, pbEof); - } - - return rc; -} - -/* -** -** If *pRc is not SQLITE_OK when this function is called, it is a no-op. -** Otherwise, fts3EvalPhraseStart() is called on all phrases within the -** expression. Also the Fts3Expr.bDeferred variable is set to true for any -** expressions for which all descendent tokens are deferred. -** -** If parameter bOptOk is zero, then it is guaranteed that the -** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for -** each phrase in the expression (subject to deferred token processing). -** Or, if bOptOk is non-zero, then one or more tokens within the expression -** may be loaded incrementally, meaning doclist.aAll/nAll is not available. -** -** If an error occurs within this function, *pRc is set to an SQLite error -** code before returning. -*/ -static void fts3EvalStartReaders( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Expr *pExpr, /* Expression to initialize phrases in */ - int *pRc /* IN/OUT: Error code */ -){ - if( pExpr && SQLITE_OK==*pRc ){ - if( pExpr->eType==FTSQUERY_PHRASE ){ - int nToken = pExpr->pPhrase->nToken; - if( nToken ){ - int i; - for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break; - } - pExpr->bDeferred = (i==nToken); - } - *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); - }else{ - fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); - fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); - pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); - } - } -} - -/* -** An array of the following structures is assembled as part of the process -** of selecting tokens to defer before the query starts executing (as part -** of the xFilter() method). There is one element in the array for each -** token in the FTS expression. -** -** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong -** to phrases that are connected only by AND and NEAR operators (not OR or -** NOT). When determining tokens to defer, each AND/NEAR cluster is considered -** separately. The root of a tokens AND/NEAR cluster is stored in -** Fts3TokenAndCost.pRoot. -*/ -typedef struct Fts3TokenAndCost Fts3TokenAndCost; -struct Fts3TokenAndCost { - Fts3Phrase *pPhrase; /* The phrase the token belongs to */ - int iToken; /* Position of token in phrase */ - Fts3PhraseToken *pToken; /* The token itself */ - Fts3Expr *pRoot; /* Root of NEAR/AND cluster */ - int nOvfl; /* Number of overflow pages to load doclist */ - int iCol; /* The column the token must match */ -}; - -/* -** This function is used to populate an allocated Fts3TokenAndCost array. -** -** If *pRc is not SQLITE_OK when this function is called, it is a no-op. -** Otherwise, if an error occurs during execution, *pRc is set to an -** SQLite error code. -*/ -static void fts3EvalTokenCosts( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */ - Fts3Expr *pExpr, /* Expression to consider */ - Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */ - Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */ - int *pRc /* IN/OUT: Error code */ -){ - if( *pRc==SQLITE_OK ){ - if( pExpr->eType==FTSQUERY_PHRASE ){ - Fts3Phrase *pPhrase = pExpr->pPhrase; - int i; - for(i=0; *pRc==SQLITE_OK && inToken; i++){ - Fts3TokenAndCost *pTC = (*ppTC)++; - pTC->pPhrase = pPhrase; - pTC->iToken = i; - pTC->pRoot = pRoot; - pTC->pToken = &pPhrase->aToken[i]; - pTC->iCol = pPhrase->iColumn; - *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); - } - }else if( pExpr->eType!=FTSQUERY_NOT ){ - assert( pExpr->eType==FTSQUERY_OR - || pExpr->eType==FTSQUERY_AND - || pExpr->eType==FTSQUERY_NEAR - ); - assert( pExpr->pLeft && pExpr->pRight ); - if( pExpr->eType==FTSQUERY_OR ){ - pRoot = pExpr->pLeft; - **ppOr = pRoot; - (*ppOr)++; - } - fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc); - if( pExpr->eType==FTSQUERY_OR ){ - pRoot = pExpr->pRight; - **ppOr = pRoot; - (*ppOr)++; - } - fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc); - } - } -} - -/* -** Determine the average document (row) size in pages. If successful, -** write this value to *pnPage and return SQLITE_OK. Otherwise, return -** an SQLite error code. -** -** The average document size in pages is calculated by first calculating -** determining the average size in bytes, B. If B is less than the amount -** of data that will fit on a single leaf page of an intkey table in -** this database, then the average docsize is 1. Otherwise, it is 1 plus -** the number of overflow pages consumed by a record B bytes in size. -*/ -static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ - if( pCsr->nRowAvg==0 ){ - /* The average document size, which is required to calculate the cost - ** of each doclist, has not yet been determined. Read the required - ** data from the %_stat table to calculate it. - ** - ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 - ** varints, where nCol is the number of columns in the FTS3 table. - ** The first varint is the number of documents currently stored in - ** the table. The following nCol varints contain the total amount of - ** data stored in all rows of each column of the table, from left - ** to right. - */ - int rc; - Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; - sqlite3_stmt *pStmt; - sqlite3_int64 nDoc = 0; - sqlite3_int64 nByte = 0; - const char *pEnd; - const char *a; - - rc = sqlite3Fts3SelectDoctotal(p, &pStmt); - if( rc!=SQLITE_OK ) return rc; - a = sqlite3_column_blob(pStmt, 0); - assert( a ); - - pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; - a += sqlite3Fts3GetVarint(a, &nDoc); - while( anDoc = nDoc; - pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); - assert( pCsr->nRowAvg>0 ); - rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ) return rc; - } - - *pnPage = pCsr->nRowAvg; - return SQLITE_OK; -} - -/* -** This function is called to select the tokens (if any) that will be -** deferred. The array aTC[] has already been populated when this is -** called. -** -** This function is called once for each AND/NEAR cluster in the -** expression. Each invocation determines which tokens to defer within -** the cluster with root node pRoot. See comments above the definition -** of struct Fts3TokenAndCost for more details. -** -** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() -** called on each token to defer. Otherwise, an SQLite error code is -** returned. -*/ -static int fts3EvalSelectDeferred( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Expr *pRoot, /* Consider tokens with this root node */ - Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */ - int nTC /* Number of entries in aTC[] */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int nDocSize = 0; /* Number of pages per doc loaded */ - int rc = SQLITE_OK; /* Return code */ - int ii; /* Iterator variable for various purposes */ - int nOvfl = 0; /* Total overflow pages used by doclists */ - int nToken = 0; /* Total number of tokens in cluster */ - - int nMinEst = 0; /* The minimum count for any phrase so far. */ - int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ - - /* Tokens are never deferred for FTS tables created using the content=xxx - ** option. The reason being that it is not guaranteed that the content - ** table actually contains the same data as the index. To prevent this from - ** causing any problems, the deferred token optimization is completely - ** disabled for content=xxx tables. */ - if( pTab->zContentTbl ){ - return SQLITE_OK; - } - - /* Count the tokens in this AND/NEAR cluster. If none of the doclists - ** associated with the tokens spill onto overflow pages, or if there is - ** only 1 token, exit early. No tokens to defer in this case. */ - for(ii=0; ii0 ); - - - /* Iterate through all tokens in this AND/NEAR cluster, in ascending order - ** of the number of overflow pages that will be loaded by the pager layer - ** to retrieve the entire doclist for the token from the full-text index. - ** Load the doclists for tokens that are either: - ** - ** a. The cheapest token in the entire query (i.e. the one visited by the - ** first iteration of this loop), or - ** - ** b. Part of a multi-token phrase. - ** - ** After each token doclist is loaded, merge it with the others from the - ** same phrase and count the number of documents that the merged doclist - ** contains. Set variable "nMinEst" to the smallest number of documents in - ** any phrase doclist for which 1 or more token doclists have been loaded. - ** Let nOther be the number of other phrases for which it is certain that - ** one or more tokens will not be deferred. - ** - ** Then, for each token, defer it if loading the doclist would result in - ** loading N or more overflow pages into memory, where N is computed as: - ** - ** (nMinEst + 4^nOther - 1) / (4^nOther) - */ - for(ii=0; iinOvfl) - ){ - pTC = &aTC[iTC]; - } - } - assert( pTC ); - - if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){ - /* The number of overflow pages to load for this (and therefore all - ** subsequent) tokens is greater than the estimated number of pages - ** that will be loaded if all subsequent tokens are deferred. - */ - Fts3PhraseToken *pToken = pTC->pToken; - rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); - fts3SegReaderCursorFree(pToken->pSegcsr); - pToken->pSegcsr = 0; - }else{ - /* Set nLoad4 to the value of (4^nOther) for the next iteration of the - ** for-loop. Except, limit the value to 2^24 to prevent it from - ** overflowing the 32-bit integer it is stored in. */ - if( ii<12 ) nLoad4 = nLoad4*4; - - if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ - /* Either this is the cheapest token in the entire query, or it is - ** part of a multi-token phrase. Either way, the entire doclist will - ** (eventually) be loaded into memory. It may as well be now. */ - Fts3PhraseToken *pToken = pTC->pToken; - int nList = 0; - char *pList = 0; - rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); - assert( rc==SQLITE_OK || pList==0 ); - if( rc==SQLITE_OK ){ - rc = fts3EvalPhraseMergeToken( - pTab, pTC->pPhrase, pTC->iToken,pList,nList - ); - } - if( rc==SQLITE_OK ){ - int nCount; - nCount = fts3DoclistCountDocids( - pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll - ); - if( ii==0 || nCountpToken = 0; - } - - return rc; -} - -/* -** This function is called from within the xFilter method. It initializes -** the full-text query currently stored in pCsr->pExpr. To iterate through -** the results of a query, the caller does: -** -** fts3EvalStart(pCsr); -** while( 1 ){ -** fts3EvalNext(pCsr); -** if( pCsr->bEof ) break; -** ... return row pCsr->iPrevId to the caller ... -** } -*/ -static int fts3EvalStart(Fts3Cursor *pCsr){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc = SQLITE_OK; - int nToken = 0; - int nOr = 0; - - /* Allocate a MultiSegReader for each token in the expression. */ - fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); - - /* Determine which, if any, tokens in the expression should be deferred. */ -#ifndef SQLITE_DISABLE_FTS4_DEFERRED - if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ - Fts3TokenAndCost *aTC; - Fts3Expr **apOr; - aTC = (Fts3TokenAndCost *)sqlite3_malloc( - sizeof(Fts3TokenAndCost) * nToken - + sizeof(Fts3Expr *) * nOr * 2 - ); - apOr = (Fts3Expr **)&aTC[nToken]; - - if( !aTC ){ - rc = SQLITE_NOMEM; - }else{ - int ii; - Fts3TokenAndCost *pTC = aTC; - Fts3Expr **ppOr = apOr; - - fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); - nToken = (int)(pTC-aTC); - nOr = (int)(ppOr-apOr); - - if( rc==SQLITE_OK ){ - rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); - for(ii=0; rc==SQLITE_OK && iipExpr, &rc); - return rc; -} - -/* -** Invalidate the current position list for phrase pPhrase. -*/ -static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ - if( pPhrase->doclist.bFreeList ){ - sqlite3_free(pPhrase->doclist.pList); - } - pPhrase->doclist.pList = 0; - pPhrase->doclist.nList = 0; - pPhrase->doclist.bFreeList = 0; -} - -/* -** This function is called to edit the position list associated with -** the phrase object passed as the fifth argument according to a NEAR -** condition. For example: -** -** abc NEAR/5 "def ghi" -** -** Parameter nNear is passed the NEAR distance of the expression (5 in -** the example above). When this function is called, *paPoslist points to -** the position list, and *pnToken is the number of phrase tokens in, the -** phrase on the other side of the NEAR operator to pPhrase. For example, -** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to -** the position list associated with phrase "abc". -** -** All positions in the pPhrase position list that are not sufficiently -** close to a position in the *paPoslist position list are removed. If this -** leaves 0 positions, zero is returned. Otherwise, non-zero. -** -** Before returning, *paPoslist is set to point to the position lsit -** associated with pPhrase. And *pnToken is set to the number of tokens in -** pPhrase. -*/ -static int fts3EvalNearTrim( - int nNear, /* NEAR distance. As in "NEAR/nNear". */ - char *aTmp, /* Temporary space to use */ - char **paPoslist, /* IN/OUT: Position list */ - int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */ - Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */ -){ - int nParam1 = nNear + pPhrase->nToken; - int nParam2 = nNear + *pnToken; - int nNew; - char *p2; - char *pOut; - int res; - - assert( pPhrase->doclist.pList ); - - p2 = pOut = pPhrase->doclist.pList; - res = fts3PoslistNearMerge( - &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 - ); - if( res ){ - nNew = (int)(pOut - pPhrase->doclist.pList) - 1; - assert( pPhrase->doclist.pList[nNew]=='\0' ); - assert( nNew<=pPhrase->doclist.nList && nNew>0 ); - memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); - pPhrase->doclist.nList = nNew; - *paPoslist = pPhrase->doclist.pList; - *pnToken = pPhrase->nToken; - } - - return res; -} - -/* -** This function is a no-op if *pRc is other than SQLITE_OK when it is called. -** Otherwise, it advances the expression passed as the second argument to -** point to the next matching row in the database. Expressions iterate through -** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero, -** or descending if it is non-zero. -** -** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if -** successful, the following variables in pExpr are set: -** -** Fts3Expr.bEof (non-zero if EOF - there is no next row) -** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row) -** -** If the expression is of type FTSQUERY_PHRASE, and the expression is not -** at EOF, then the following variables are populated with the position list -** for the phrase for the visited row: -** -** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes) -** FTs3Expr.pPhrase->doclist.pList (pointer to position list) -** -** It says above that this function advances the expression to the next -** matching row. This is usually true, but there are the following exceptions: -** -** 1. Deferred tokens are not taken into account. If a phrase consists -** entirely of deferred tokens, it is assumed to match every row in -** the db. In this case the position-list is not populated at all. -** -** Or, if a phrase contains one or more deferred tokens and one or -** more non-deferred tokens, then the expression is advanced to the -** next possible match, considering only non-deferred tokens. In other -** words, if the phrase is "A B C", and "B" is deferred, the expression -** is advanced to the next row that contains an instance of "A * C", -** where "*" may match any single token. The position list in this case -** is populated as for "A * C" before returning. -** -** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is -** advanced to point to the next row that matches "x AND y". -** -** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is -** really a match, taking into account deferred tokens and NEAR operators. -*/ -static void fts3EvalNextRow( - Fts3Cursor *pCsr, /* FTS Cursor handle */ - Fts3Expr *pExpr, /* Expr. to advance to next matching row */ - int *pRc /* IN/OUT: Error code */ -){ - if( *pRc==SQLITE_OK ){ - int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ - assert( pExpr->bEof==0 ); - pExpr->bStart = 1; - - switch( pExpr->eType ){ - case FTSQUERY_NEAR: - case FTSQUERY_AND: { - Fts3Expr *pLeft = pExpr->pLeft; - Fts3Expr *pRight = pExpr->pRight; - assert( !pLeft->bDeferred || !pRight->bDeferred ); - - if( pLeft->bDeferred ){ - /* LHS is entirely deferred. So we assume it matches every row. - ** Advance the RHS iterator to find the next row visited. */ - fts3EvalNextRow(pCsr, pRight, pRc); - pExpr->iDocid = pRight->iDocid; - pExpr->bEof = pRight->bEof; - }else if( pRight->bDeferred ){ - /* RHS is entirely deferred. So we assume it matches every row. - ** Advance the LHS iterator to find the next row visited. */ - fts3EvalNextRow(pCsr, pLeft, pRc); - pExpr->iDocid = pLeft->iDocid; - pExpr->bEof = pLeft->bEof; - }else{ - /* Neither the RHS or LHS are deferred. */ - fts3EvalNextRow(pCsr, pLeft, pRc); - fts3EvalNextRow(pCsr, pRight, pRc); - while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ - sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); - if( iDiff==0 ) break; - if( iDiff<0 ){ - fts3EvalNextRow(pCsr, pLeft, pRc); - }else{ - fts3EvalNextRow(pCsr, pRight, pRc); - } - } - pExpr->iDocid = pLeft->iDocid; - pExpr->bEof = (pLeft->bEof || pRight->bEof); - if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ - if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){ - Fts3Doclist *pDl = &pRight->pPhrase->doclist; - while( *pRc==SQLITE_OK && pRight->bEof==0 ){ - memset(pDl->pList, 0, pDl->nList); - fts3EvalNextRow(pCsr, pRight, pRc); - } - } - if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ - Fts3Doclist *pDl = &pLeft->pPhrase->doclist; - while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ - memset(pDl->pList, 0, pDl->nList); - fts3EvalNextRow(pCsr, pLeft, pRc); - } - } - } - } - break; - } - - case FTSQUERY_OR: { - Fts3Expr *pLeft = pExpr->pLeft; - Fts3Expr *pRight = pExpr->pRight; - sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); - - assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); - assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); - - if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ - fts3EvalNextRow(pCsr, pLeft, pRc); - }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){ - fts3EvalNextRow(pCsr, pRight, pRc); - }else{ - fts3EvalNextRow(pCsr, pLeft, pRc); - fts3EvalNextRow(pCsr, pRight, pRc); - } - - pExpr->bEof = (pLeft->bEof && pRight->bEof); - iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); - if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ - pExpr->iDocid = pLeft->iDocid; - }else{ - pExpr->iDocid = pRight->iDocid; - } - - break; - } - - case FTSQUERY_NOT: { - Fts3Expr *pLeft = pExpr->pLeft; - Fts3Expr *pRight = pExpr->pRight; - - if( pRight->bStart==0 ){ - fts3EvalNextRow(pCsr, pRight, pRc); - assert( *pRc!=SQLITE_OK || pRight->bStart ); - } - - fts3EvalNextRow(pCsr, pLeft, pRc); - if( pLeft->bEof==0 ){ - while( !*pRc - && !pRight->bEof - && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 - ){ - fts3EvalNextRow(pCsr, pRight, pRc); - } - } - pExpr->iDocid = pLeft->iDocid; - pExpr->bEof = pLeft->bEof; - break; - } - - default: { - Fts3Phrase *pPhrase = pExpr->pPhrase; - fts3EvalInvalidatePoslist(pPhrase); - *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof); - pExpr->iDocid = pPhrase->doclist.iDocid; - break; - } - } - } -} - -/* -** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR -** cluster, then this function returns 1 immediately. -** -** Otherwise, it checks if the current row really does match the NEAR -** expression, using the data currently stored in the position lists -** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression. -** -** If the current row is a match, the position list associated with each -** phrase in the NEAR expression is edited in place to contain only those -** phrase instances sufficiently close to their peers to satisfy all NEAR -** constraints. In this case it returns 1. If the NEAR expression does not -** match the current row, 0 is returned. The position lists may or may not -** be edited if 0 is returned. -*/ -static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ - int res = 1; - - /* The following block runs if pExpr is the root of a NEAR query. - ** For example, the query: - ** - ** "w" NEAR "x" NEAR "y" NEAR "z" - ** - ** which is represented in tree form as: - ** - ** | - ** +--NEAR--+ <-- root of NEAR query - ** | | - ** +--NEAR--+ "z" - ** | | - ** +--NEAR--+ "y" - ** | | - ** "w" "x" - ** - ** The right-hand child of a NEAR node is always a phrase. The - ** left-hand child may be either a phrase or a NEAR node. There are - ** no exceptions to this - it's the way the parser in fts3_expr.c works. - */ - if( *pRc==SQLITE_OK - && pExpr->eType==FTSQUERY_NEAR - && pExpr->bEof==0 - && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) - ){ - Fts3Expr *p; - int nTmp = 0; /* Bytes of temp space */ - char *aTmp; /* Temp space for PoslistNearMerge() */ - - /* Allocate temporary working space. */ - for(p=pExpr; p->pLeft; p=p->pLeft){ - nTmp += p->pRight->pPhrase->doclist.nList; - } - nTmp += p->pPhrase->doclist.nList; - if( nTmp==0 ){ - res = 0; - }else{ - aTmp = sqlite3_malloc(nTmp*2); - if( !aTmp ){ - *pRc = SQLITE_NOMEM; - res = 0; - }else{ - char *aPoslist = p->pPhrase->doclist.pList; - int nToken = p->pPhrase->nToken; - - for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ - Fts3Phrase *pPhrase = p->pRight->pPhrase; - int nNear = p->nNear; - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); - } - - aPoslist = pExpr->pRight->pPhrase->doclist.pList; - nToken = pExpr->pRight->pPhrase->nToken; - for(p=pExpr->pLeft; p && res; p=p->pLeft){ - int nNear; - Fts3Phrase *pPhrase; - assert( p->pParent && p->pParent->pLeft==p ); - nNear = p->pParent->nNear; - pPhrase = ( - p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase - ); - res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); - } - } - - sqlite3_free(aTmp); - } - } - - return res; -} - -/* -** This function is a helper function for sqlite3Fts3EvalTestDeferred(). -** Assuming no error occurs or has occurred, It returns non-zero if the -** expression passed as the second argument matches the row that pCsr -** currently points to, or zero if it does not. -** -** If *pRc is not SQLITE_OK when this function is called, it is a no-op. -** If an error occurs during execution of this function, *pRc is set to -** the appropriate SQLite error code. In this case the returned value is -** undefined. -*/ -static int fts3EvalTestExpr( - Fts3Cursor *pCsr, /* FTS cursor handle */ - Fts3Expr *pExpr, /* Expr to test. May or may not be root. */ - int *pRc /* IN/OUT: Error code */ -){ - int bHit = 1; /* Return value */ - if( *pRc==SQLITE_OK ){ - switch( pExpr->eType ){ - case FTSQUERY_NEAR: - case FTSQUERY_AND: - bHit = ( - fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) - && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) - && fts3EvalNearTest(pExpr, pRc) - ); - - /* If the NEAR expression does not match any rows, zero the doclist for - ** all phrases involved in the NEAR. This is because the snippet(), - ** offsets() and matchinfo() functions are not supposed to recognize - ** any instances of phrases that are part of unmatched NEAR queries. - ** For example if this expression: - ** - ** ... MATCH 'a OR (b NEAR c)' - ** - ** is matched against a row containing: - ** - ** 'a b d e' - ** - ** then any snippet() should ony highlight the "a" term, not the "b" - ** (as "b" is part of a non-matching NEAR clause). - */ - if( bHit==0 - && pExpr->eType==FTSQUERY_NEAR - && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) - ){ - Fts3Expr *p; - for(p=pExpr; p->pPhrase==0; p=p->pLeft){ - if( p->pRight->iDocid==pCsr->iPrevId ){ - fts3EvalInvalidatePoslist(p->pRight->pPhrase); - } - } - if( p->iDocid==pCsr->iPrevId ){ - fts3EvalInvalidatePoslist(p->pPhrase); - } - } - - break; - - case FTSQUERY_OR: { - int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc); - int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc); - bHit = bHit1 || bHit2; - break; - } - - case FTSQUERY_NOT: - bHit = ( - fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) - && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) - ); - break; - - default: { -#ifndef SQLITE_DISABLE_FTS4_DEFERRED - if( pCsr->pDeferred - && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred) - ){ - Fts3Phrase *pPhrase = pExpr->pPhrase; - assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 ); - if( pExpr->bDeferred ){ - fts3EvalInvalidatePoslist(pPhrase); - } - *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); - bHit = (pPhrase->doclist.pList!=0); - pExpr->iDocid = pCsr->iPrevId; - }else -#endif - { - bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId); - } - break; - } - } - } - return bHit; -} - -/* -** This function is called as the second part of each xNext operation when -** iterating through the results of a full-text query. At this point the -** cursor points to a row that matches the query expression, with the -** following caveats: -** -** * Up until this point, "NEAR" operators in the expression have been -** treated as "AND". -** -** * Deferred tokens have not yet been considered. -** -** If *pRc is not SQLITE_OK when this function is called, it immediately -** returns 0. Otherwise, it tests whether or not after considering NEAR -** operators and deferred tokens the current row is still a match for the -** expression. It returns 1 if both of the following are true: -** -** 1. *pRc is SQLITE_OK when this function returns, and -** -** 2. After scanning the current FTS table row for the deferred tokens, -** it is determined that the row does *not* match the query. -** -** Or, if no error occurs and it seems the current row does match the FTS -** query, return 0. -*/ -SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ - int rc = *pRc; - int bMiss = 0; - if( rc==SQLITE_OK ){ - - /* If there are one or more deferred tokens, load the current row into - ** memory and scan it to determine the position list for each deferred - ** token. Then, see if this row is really a match, considering deferred - ** tokens and NEAR operators (neither of which were taken into account - ** earlier, by fts3EvalNextRow()). - */ - if( pCsr->pDeferred ){ - rc = fts3CursorSeek(0, pCsr); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3CacheDeferredDoclists(pCsr); - } - } - bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); - - /* Free the position-lists accumulated for each deferred token above. */ - sqlite3Fts3FreeDeferredDoclists(pCsr); - *pRc = rc; - } - return (rc==SQLITE_OK && bMiss); -} - -/* -** Advance to the next document that matches the FTS expression in -** Fts3Cursor.pExpr. -*/ -static int fts3EvalNext(Fts3Cursor *pCsr){ - int rc = SQLITE_OK; /* Return Code */ - Fts3Expr *pExpr = pCsr->pExpr; - assert( pCsr->isEof==0 ); - if( pExpr==0 ){ - pCsr->isEof = 1; - }else{ - do { - if( pCsr->isRequireSeek==0 ){ - sqlite3_reset(pCsr->pStmt); - } - assert( sqlite3_data_count(pCsr->pStmt)==0 ); - fts3EvalNextRow(pCsr, pExpr, &rc); - pCsr->isEof = pExpr->bEof; - pCsr->isRequireSeek = 1; - pCsr->isMatchinfoNeeded = 1; - pCsr->iPrevId = pExpr->iDocid; - }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) ); - } - - /* Check if the cursor is past the end of the docid range specified - ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ - if( rc==SQLITE_OK && ( - (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) - || (pCsr->bDesc!=0 && pCsr->iPrevIdiMinDocid) - )){ - pCsr->isEof = 1; - } - - return rc; -} - -/* -** Restart interation for expression pExpr so that the next call to -** fts3EvalNext() visits the first row. Do not allow incremental -** loading or merging of phrase doclists for this iteration. -** -** If *pRc is other than SQLITE_OK when this function is called, it is -** a no-op. If an error occurs within this function, *pRc is set to an -** SQLite error code before returning. -*/ -static void fts3EvalRestart( - Fts3Cursor *pCsr, - Fts3Expr *pExpr, - int *pRc -){ - if( pExpr && *pRc==SQLITE_OK ){ - Fts3Phrase *pPhrase = pExpr->pPhrase; - - if( pPhrase ){ - fts3EvalInvalidatePoslist(pPhrase); - if( pPhrase->bIncr ){ - int i; - for(i=0; inToken; i++){ - Fts3PhraseToken *pToken = &pPhrase->aToken[i]; - assert( pToken->pDeferred==0 ); - if( pToken->pSegcsr ){ - sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); - } - } - *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); - } - pPhrase->doclist.pNextDocid = 0; - pPhrase->doclist.iDocid = 0; - pPhrase->pOrPoslist = 0; - } - - pExpr->iDocid = 0; - pExpr->bEof = 0; - pExpr->bStart = 0; - - fts3EvalRestart(pCsr, pExpr->pLeft, pRc); - fts3EvalRestart(pCsr, pExpr->pRight, pRc); - } -} - -/* -** After allocating the Fts3Expr.aMI[] array for each phrase in the -** expression rooted at pExpr, the cursor iterates through all rows matched -** by pExpr, calling this function for each row. This function increments -** the values in Fts3Expr.aMI[] according to the position-list currently -** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase -** expression nodes. -*/ -static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ - if( pExpr ){ - Fts3Phrase *pPhrase = pExpr->pPhrase; - if( pPhrase && pPhrase->doclist.pList ){ - int iCol = 0; - char *p = pPhrase->doclist.pList; - - assert( *p ); - while( 1 ){ - u8 c = 0; - int iCnt = 0; - while( 0xFE & (*p | c) ){ - if( (c&0x80)==0 ) iCnt++; - c = *p++ & 0x80; - } - - /* aMI[iCol*3 + 1] = Number of occurrences - ** aMI[iCol*3 + 2] = Number of rows containing at least one instance - */ - pExpr->aMI[iCol*3 + 1] += iCnt; - pExpr->aMI[iCol*3 + 2] += (iCnt>0); - if( *p==0x00 ) break; - p++; - p += fts3GetVarint32(p, &iCol); - } - } - - fts3EvalUpdateCounts(pExpr->pLeft); - fts3EvalUpdateCounts(pExpr->pRight); - } -} - -/* -** Expression pExpr must be of type FTSQUERY_PHRASE. -** -** If it is not already allocated and populated, this function allocates and -** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part -** of a NEAR expression, then it also allocates and populates the same array -** for all other phrases that are part of the NEAR expression. -** -** SQLITE_OK is returned if the aMI[] array is successfully allocated and -** populated. Otherwise, if an error occurs, an SQLite error code is returned. -*/ -static int fts3EvalGatherStats( - Fts3Cursor *pCsr, /* Cursor object */ - Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ -){ - int rc = SQLITE_OK; /* Return code */ - - assert( pExpr->eType==FTSQUERY_PHRASE ); - if( pExpr->aMI==0 ){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - Fts3Expr *pRoot; /* Root of NEAR expression */ - Fts3Expr *p; /* Iterator used for several purposes */ - - sqlite3_int64 iPrevId = pCsr->iPrevId; - sqlite3_int64 iDocid; - u8 bEof; - - /* Find the root of the NEAR expression */ - pRoot = pExpr; - while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){ - pRoot = pRoot->pParent; - } - iDocid = pRoot->iDocid; - bEof = pRoot->bEof; - assert( pRoot->bStart ); - - /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ - for(p=pRoot; p; p=p->pLeft){ - Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); - assert( pE->aMI==0 ); - pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32)); - if( !pE->aMI ) return SQLITE_NOMEM; - memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); - } - - fts3EvalRestart(pCsr, pRoot, &rc); - - while( pCsr->isEof==0 && rc==SQLITE_OK ){ - - do { - /* Ensure the %_content statement is reset. */ - if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); - assert( sqlite3_data_count(pCsr->pStmt)==0 ); - - /* Advance to the next document */ - fts3EvalNextRow(pCsr, pRoot, &rc); - pCsr->isEof = pRoot->bEof; - pCsr->isRequireSeek = 1; - pCsr->isMatchinfoNeeded = 1; - pCsr->iPrevId = pRoot->iDocid; - }while( pCsr->isEof==0 - && pRoot->eType==FTSQUERY_NEAR - && sqlite3Fts3EvalTestDeferred(pCsr, &rc) - ); - - if( rc==SQLITE_OK && pCsr->isEof==0 ){ - fts3EvalUpdateCounts(pRoot); - } - } - - pCsr->isEof = 0; - pCsr->iPrevId = iPrevId; - - if( bEof ){ - pRoot->bEof = bEof; - }else{ - /* Caution: pRoot may iterate through docids in ascending or descending - ** order. For this reason, even though it seems more defensive, the - ** do loop can not be written: - ** - ** do {...} while( pRoot->iDocidbEof==0 ); - }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK ); - } - } - return rc; -} - -/* -** This function is used by the matchinfo() module to query a phrase -** expression node for the following information: -** -** 1. The total number of occurrences of the phrase in each column of -** the FTS table (considering all rows), and -** -** 2. For each column, the number of rows in the table for which the -** column contains at least one instance of the phrase. -** -** If no error occurs, SQLITE_OK is returned and the values for each column -** written into the array aiOut as follows: -** -** aiOut[iCol*3 + 1] = Number of occurrences -** aiOut[iCol*3 + 2] = Number of rows containing at least one instance -** -** Caveats: -** -** * If a phrase consists entirely of deferred tokens, then all output -** values are set to the number of documents in the table. In other -** words we assume that very common tokens occur exactly once in each -** column of each row of the table. -** -** * If a phrase contains some deferred tokens (and some non-deferred -** tokens), count the potential occurrence identified by considering -** the non-deferred tokens instead of actual phrase occurrences. -** -** * If the phrase is part of a NEAR expression, then only phrase instances -** that meet the NEAR constraint are included in the counts. -*/ -SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( - Fts3Cursor *pCsr, /* FTS cursor handle */ - Fts3Expr *pExpr, /* Phrase expression */ - u32 *aiOut /* Array to write results into (see above) */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc = SQLITE_OK; - int iCol; - - if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ - assert( pCsr->nDoc>0 ); - for(iCol=0; iColnColumn; iCol++){ - aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; - aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; - } - }else{ - rc = fts3EvalGatherStats(pCsr, pExpr); - if( rc==SQLITE_OK ){ - assert( pExpr->aMI ); - for(iCol=0; iColnColumn; iCol++){ - aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1]; - aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2]; - } - } - } - - return rc; -} - -/* -** The expression pExpr passed as the second argument to this function -** must be of type FTSQUERY_PHRASE. -** -** The returned value is either NULL or a pointer to a buffer containing -** a position-list indicating the occurrences of the phrase in column iCol -** of the current row. -** -** More specifically, the returned buffer contains 1 varint for each -** occurrence of the phrase in the column, stored using the normal (delta+2) -** compression and is terminated by either an 0x01 or 0x00 byte. For example, -** if the requested column contains "a b X c d X X" and the position-list -** for 'X' is requested, the buffer returned may contain: -** -** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 -** -** This function works regardless of whether or not the phrase is deferred, -** incremental, or neither. -*/ -SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( - Fts3Cursor *pCsr, /* FTS3 cursor object */ - Fts3Expr *pExpr, /* Phrase to return doclist for */ - int iCol, /* Column to return position list for */ - char **ppOut /* OUT: Pointer to position list */ -){ - Fts3Phrase *pPhrase = pExpr->pPhrase; - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - char *pIter; - int iThis; - sqlite3_int64 iDocid; - - /* If this phrase is applies specifically to some column other than - ** column iCol, return a NULL pointer. */ - *ppOut = 0; - assert( iCol>=0 && iColnColumn ); - if( (pPhrase->iColumnnColumn && pPhrase->iColumn!=iCol) ){ - return SQLITE_OK; - } - - iDocid = pExpr->iDocid; - pIter = pPhrase->doclist.pList; - if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ - int rc = SQLITE_OK; - int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ - int bOr = 0; - u8 bTreeEof = 0; - Fts3Expr *p; /* Used to iterate from pExpr to root */ - Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ - int bMatch; - - /* Check if this phrase descends from an OR expression node. If not, - ** return NULL. Otherwise, the entry that corresponds to docid - ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the - ** tree that the node is part of has been marked as EOF, but the node - ** itself is not EOF, then it may point to an earlier entry. */ - pNear = pExpr; - for(p=pExpr->pParent; p; p=p->pParent){ - if( p->eType==FTSQUERY_OR ) bOr = 1; - if( p->eType==FTSQUERY_NEAR ) pNear = p; - if( p->bEof ) bTreeEof = 1; - } - if( bOr==0 ) return SQLITE_OK; - - /* This is the descendent of an OR node. In this case we cannot use - ** an incremental phrase. Load the entire doclist for the phrase - ** into memory in this case. */ - if( pPhrase->bIncr ){ - int bEofSave = pNear->bEof; - fts3EvalRestart(pCsr, pNear, &rc); - while( rc==SQLITE_OK && !pNear->bEof ){ - fts3EvalNextRow(pCsr, pNear, &rc); - if( bEofSave==0 && pNear->iDocid==iDocid ) break; - } - assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); - } - if( bTreeEof ){ - while( rc==SQLITE_OK && !pNear->bEof ){ - fts3EvalNextRow(pCsr, pNear, &rc); - } - } - if( rc!=SQLITE_OK ) return rc; - - bMatch = 1; - for(p=pNear; p; p=p->pLeft){ - u8 bEof = 0; - Fts3Expr *pTest = p; - Fts3Phrase *pPh; - assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE ); - if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight; - assert( pTest->eType==FTSQUERY_PHRASE ); - pPh = pTest->pPhrase; - - pIter = pPh->pOrPoslist; - iDocid = pPh->iOrDocid; - if( pCsr->bDesc==bDescDoclist ){ - bEof = !pPh->doclist.nAll || - (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll)); - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ - sqlite3Fts3DoclistNext( - bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, - &pIter, &iDocid, &bEof - ); - } - }else{ - bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll); - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ - int dummy; - sqlite3Fts3DoclistPrev( - bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, - &pIter, &iDocid, &dummy, &bEof - ); - } - } - pPh->pOrPoslist = pIter; - pPh->iOrDocid = iDocid; - if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0; - } - - if( bMatch ){ - pIter = pPhrase->pOrPoslist; - }else{ - pIter = 0; - } - } - if( pIter==0 ) return SQLITE_OK; - - if( *pIter==0x01 ){ - pIter++; - pIter += fts3GetVarint32(pIter, &iThis); - }else{ - iThis = 0; - } - while( iThisdoclist, and -** * any Fts3MultiSegReader objects held by phrase tokens. -*/ -SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ - if( pPhrase ){ - int i; - sqlite3_free(pPhrase->doclist.aAll); - fts3EvalInvalidatePoslist(pPhrase); - memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); - for(i=0; inToken; i++){ - fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); - pPhrase->aToken[i].pSegcsr = 0; - } - } -} - - -/* -** Return SQLITE_CORRUPT_VTAB. -*/ -#ifdef SQLITE_DEBUG -SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ - return SQLITE_CORRUPT_VTAB; -} -#endif - -#if !SQLITE_CORE -/* -** Initialize API pointer table, if required. -*/ -#ifdef _WIN32 -__declspec(dllexport) -#endif -SQLITE_API int sqlite3_fts3_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - SQLITE_EXTENSION_INIT2(pApi) - return sqlite3Fts3Init(db); -} -#endif - -#endif - -/************** End of fts3.c ************************************************/ -/************** Begin file fts3_aux.c ****************************************/ -/* -** 2011 Jan 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ - -typedef struct Fts3auxTable Fts3auxTable; -typedef struct Fts3auxCursor Fts3auxCursor; - -struct Fts3auxTable { - sqlite3_vtab base; /* Base class used by SQLite core */ - Fts3Table *pFts3Tab; -}; - -struct Fts3auxCursor { - sqlite3_vtab_cursor base; /* Base class used by SQLite core */ - Fts3MultiSegReader csr; /* Must be right after "base" */ - Fts3SegFilter filter; - char *zStop; - int nStop; /* Byte-length of string zStop */ - int iLangid; /* Language id to query */ - int isEof; /* True if cursor is at EOF */ - sqlite3_int64 iRowid; /* Current rowid */ - - int iCol; /* Current value of 'col' column */ - int nStat; /* Size of aStat[] array */ - struct Fts3auxColstats { - sqlite3_int64 nDoc; /* 'documents' values for current csr row */ - sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ - } *aStat; -}; - -/* -** Schema of the terms table. -*/ -#define FTS3_AUX_SCHEMA \ - "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)" - -/* -** This function does all the work for both the xConnect and xCreate methods. -** These tables have no persistent representation of their own, so xConnect -** and xCreate are identical operations. -*/ -static int fts3auxConnectMethod( - sqlite3 *db, /* Database connection */ - void *pUnused, /* Unused */ - int argc, /* Number of elements in argv array */ - const char * const *argv, /* xCreate/xConnect argument array */ - sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ - char **pzErr /* OUT: sqlite3_malloc'd error message */ -){ - char const *zDb; /* Name of database (e.g. "main") */ - char const *zFts3; /* Name of fts3 table */ - int nDb; /* Result of strlen(zDb) */ - int nFts3; /* Result of strlen(zFts3) */ - int nByte; /* Bytes of space to allocate here */ - int rc; /* value returned by declare_vtab() */ - Fts3auxTable *p; /* Virtual table object to return */ - - UNUSED_PARAMETER(pUnused); - - /* The user should invoke this in one of two forms: - ** - ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table); - ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table); - */ - if( argc!=4 && argc!=5 ) goto bad_args; - - zDb = argv[1]; - nDb = (int)strlen(zDb); - if( argc==5 ){ - if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ - zDb = argv[3]; - nDb = (int)strlen(zDb); - zFts3 = argv[4]; - }else{ - goto bad_args; - } - }else{ - zFts3 = argv[3]; - } - nFts3 = (int)strlen(zFts3); - - rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); - if( rc!=SQLITE_OK ) return rc; - - nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; - p = (Fts3auxTable *)sqlite3_malloc(nByte); - if( !p ) return SQLITE_NOMEM; - memset(p, 0, nByte); - - p->pFts3Tab = (Fts3Table *)&p[1]; - p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; - p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; - p->pFts3Tab->db = db; - p->pFts3Tab->nIndex = 1; - - memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); - memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); - sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); - - *ppVtab = (sqlite3_vtab *)p; - return SQLITE_OK; - - bad_args: - sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); - return SQLITE_ERROR; -} - -/* -** This function does the work for both the xDisconnect and xDestroy methods. -** These tables have no persistent representation of their own, so xDisconnect -** and xDestroy are identical operations. -*/ -static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ - Fts3auxTable *p = (Fts3auxTable *)pVtab; - Fts3Table *pFts3 = p->pFts3Tab; - int i; - - /* Free any prepared statements held */ - for(i=0; iaStmt); i++){ - sqlite3_finalize(pFts3->aStmt[i]); - } - sqlite3_free(pFts3->zSegmentsTbl); - sqlite3_free(p); - return SQLITE_OK; -} - -#define FTS4AUX_EQ_CONSTRAINT 1 -#define FTS4AUX_GE_CONSTRAINT 2 -#define FTS4AUX_LE_CONSTRAINT 4 - -/* -** xBestIndex - Analyze a WHERE and ORDER BY clause. -*/ -static int fts3auxBestIndexMethod( - sqlite3_vtab *pVTab, - sqlite3_index_info *pInfo -){ - int i; - int iEq = -1; - int iGe = -1; - int iLe = -1; - int iLangid = -1; - int iNext = 1; /* Next free argvIndex value */ - - UNUSED_PARAMETER(pVTab); - - /* This vtab delivers always results in "ORDER BY term ASC" order. */ - if( pInfo->nOrderBy==1 - && pInfo->aOrderBy[0].iColumn==0 - && pInfo->aOrderBy[0].desc==0 - ){ - pInfo->orderByConsumed = 1; - } - - /* Search for equality and range constraints on the "term" column. - ** And equality constraints on the hidden "languageid" column. */ - for(i=0; inConstraint; i++){ - if( pInfo->aConstraint[i].usable ){ - int op = pInfo->aConstraint[i].op; - int iCol = pInfo->aConstraint[i].iColumn; - - if( iCol==0 ){ - if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; - if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; - if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; - if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; - if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; - } - if( iCol==4 ){ - if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i; - } - } - } - - if( iEq>=0 ){ - pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; - pInfo->aConstraintUsage[iEq].argvIndex = iNext++; - pInfo->estimatedCost = 5; - }else{ - pInfo->idxNum = 0; - pInfo->estimatedCost = 20000; - if( iGe>=0 ){ - pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; - pInfo->aConstraintUsage[iGe].argvIndex = iNext++; - pInfo->estimatedCost /= 2; - } - if( iLe>=0 ){ - pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; - pInfo->aConstraintUsage[iLe].argvIndex = iNext++; - pInfo->estimatedCost /= 2; - } - } - if( iLangid>=0 ){ - pInfo->aConstraintUsage[iLangid].argvIndex = iNext++; - pInfo->estimatedCost--; - } - - return SQLITE_OK; -} - -/* -** xOpen - Open a cursor. -*/ -static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ - Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ - - UNUSED_PARAMETER(pVTab); - - pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); - if( !pCsr ) return SQLITE_NOMEM; - memset(pCsr, 0, sizeof(Fts3auxCursor)); - - *ppCsr = (sqlite3_vtab_cursor *)pCsr; - return SQLITE_OK; -} - -/* -** xClose - Close a cursor. -*/ -static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ - Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; - Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - - sqlite3Fts3SegmentsClose(pFts3); - sqlite3Fts3SegReaderFinish(&pCsr->csr); - sqlite3_free((void *)pCsr->filter.zTerm); - sqlite3_free(pCsr->zStop); - sqlite3_free(pCsr->aStat); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ - if( nSize>pCsr->nStat ){ - struct Fts3auxColstats *aNew; - aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat, - sizeof(struct Fts3auxColstats) * nSize - ); - if( aNew==0 ) return SQLITE_NOMEM; - memset(&aNew[pCsr->nStat], 0, - sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat) - ); - pCsr->aStat = aNew; - pCsr->nStat = nSize; - } - return SQLITE_OK; -} - -/* -** xNext - Advance the cursor to the next row, if any. -*/ -static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ - Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; - int rc; - - /* Increment our pretend rowid value. */ - pCsr->iRowid++; - - for(pCsr->iCol++; pCsr->iColnStat; pCsr->iCol++){ - if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; - } - - rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); - if( rc==SQLITE_ROW ){ - int i = 0; - int nDoclist = pCsr->csr.nDoclist; - char *aDoclist = pCsr->csr.aDoclist; - int iCol; - - int eState = 0; - - if( pCsr->zStop ){ - int n = (pCsr->nStopcsr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm; - int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n); - if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){ - pCsr->isEof = 1; - return SQLITE_OK; - } - } - - if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; - memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); - iCol = 0; - - while( iaStat[0].nDoc++; - eState = 1; - iCol = 0; - break; - - /* State 1. In this state we are expecting either a 1, indicating - ** that the following integer will be a column number, or the - ** start of a position list for column 0. - ** - ** The only difference between state 1 and state 2 is that if the - ** integer encountered in state 1 is not 0 or 1, then we need to - ** increment the column 0 "nDoc" count for this term. - */ - case 1: - assert( iCol==0 ); - if( v>1 ){ - pCsr->aStat[1].nDoc++; - } - eState = 2; - /* fall through */ - - case 2: - if( v==0 ){ /* 0x00. Next integer will be a docid. */ - eState = 0; - }else if( v==1 ){ /* 0x01. Next integer will be a column number. */ - eState = 3; - }else{ /* 2 or greater. A position. */ - pCsr->aStat[iCol+1].nOcc++; - pCsr->aStat[0].nOcc++; - } - break; - - /* State 3. The integer just read is a column number. */ - default: assert( eState==3 ); - iCol = (int)v; - if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; - pCsr->aStat[iCol+1].nDoc++; - eState = 2; - break; - } - } - - pCsr->iCol = 0; - rc = SQLITE_OK; - }else{ - pCsr->isEof = 1; - } - return rc; -} - -/* -** xFilter - Initialize a cursor to point at the start of its data. -*/ -static int fts3auxFilterMethod( - sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ - int idxNum, /* Strategy index */ - const char *idxStr, /* Unused */ - int nVal, /* Number of elements in apVal */ - sqlite3_value **apVal /* Arguments for the indexing scheme */ -){ - Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; - int rc; - int isScan = 0; - int iLangVal = 0; /* Language id to query */ - - int iEq = -1; /* Index of term=? value in apVal */ - int iGe = -1; /* Index of term>=? value in apVal */ - int iLe = -1; /* Index of term<=? value in apVal */ - int iLangid = -1; /* Index of languageid=? value in apVal */ - int iNext = 0; - - UNUSED_PARAMETER(nVal); - UNUSED_PARAMETER(idxStr); - - assert( idxStr==0 ); - assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 - || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT - || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) - ); - - if( idxNum==FTS4AUX_EQ_CONSTRAINT ){ - iEq = iNext++; - }else{ - isScan = 1; - if( idxNum & FTS4AUX_GE_CONSTRAINT ){ - iGe = iNext++; - } - if( idxNum & FTS4AUX_LE_CONSTRAINT ){ - iLe = iNext++; - } - } - if( iNextfilter.zTerm); - sqlite3Fts3SegReaderFinish(&pCsr->csr); - sqlite3_free((void *)pCsr->filter.zTerm); - sqlite3_free(pCsr->aStat); - memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); - - pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; - if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; - - if( iEq>=0 || iGe>=0 ){ - const unsigned char *zStr = sqlite3_value_text(apVal[0]); - assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); - if( zStr ){ - pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); - pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); - if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; - } - } - - if( iLe>=0 ){ - pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); - pCsr->nStop = sqlite3_value_bytes(apVal[iLe]); - if( pCsr->zStop==0 ) return SQLITE_NOMEM; - } - - if( iLangid>=0 ){ - iLangVal = sqlite3_value_int(apVal[iLangid]); - - /* If the user specified a negative value for the languageid, use zero - ** instead. This works, as the "languageid=?" constraint will also - ** be tested by the VDBE layer. The test will always be false (since - ** this module will not return a row with a negative languageid), and - ** so the overall query will return zero rows. */ - if( iLangVal<0 ) iLangVal = 0; - } - pCsr->iLangid = iLangVal; - - rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, - pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr - ); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); - } - - if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); - return rc; -} - -/* -** xEof - Return true if the cursor is at EOF, or false otherwise. -*/ -static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ - Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - return pCsr->isEof; -} - -/* -** xColumn - Return a column value. -*/ -static int fts3auxColumnMethod( - sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ - int iCol /* Index of column to read value from */ -){ - Fts3auxCursor *p = (Fts3auxCursor *)pCursor; - - assert( p->isEof==0 ); - switch( iCol ){ - case 0: /* term */ - sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); - break; - - case 1: /* col */ - if( p->iCol ){ - sqlite3_result_int(pCtx, p->iCol-1); - }else{ - sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); - } - break; - - case 2: /* documents */ - sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); - break; - - case 3: /* occurrences */ - sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); - break; - - default: /* languageid */ - assert( iCol==4 ); - sqlite3_result_int(pCtx, p->iLangid); - break; - } - - return SQLITE_OK; -} - -/* -** xRowid - Return the current rowid for the cursor. -*/ -static int fts3auxRowidMethod( - sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite_int64 *pRowid /* OUT: Rowid value */ -){ - Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - *pRowid = pCsr->iRowid; - return SQLITE_OK; -} - -/* -** Register the fts3aux module with database connection db. Return SQLITE_OK -** if successful or an error code if sqlite3_create_module() fails. -*/ -SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ - static const sqlite3_module fts3aux_module = { - 0, /* iVersion */ - fts3auxConnectMethod, /* xCreate */ - fts3auxConnectMethod, /* xConnect */ - fts3auxBestIndexMethod, /* xBestIndex */ - fts3auxDisconnectMethod, /* xDisconnect */ - fts3auxDisconnectMethod, /* xDestroy */ - fts3auxOpenMethod, /* xOpen */ - fts3auxCloseMethod, /* xClose */ - fts3auxFilterMethod, /* xFilter */ - fts3auxNextMethod, /* xNext */ - fts3auxEofMethod, /* xEof */ - fts3auxColumnMethod, /* xColumn */ - fts3auxRowidMethod, /* xRowid */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindFunction */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ - }; - int rc; /* Return code */ - - rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); - return rc; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_aux.c ********************************************/ -/************** Begin file fts3_expr.c ***************************************/ -/* -** 2008 Nov 28 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This module contains code that implements a parser for fts3 query strings -** (the right-hand argument to the MATCH operator). Because the supported -** syntax is relatively simple, the whole tokenizer/parser system is -** hand-coded. -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* -** By default, this module parses the legacy syntax that has been -** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS -** is defined, then it uses the new syntax. The differences between -** the new and the old syntaxes are: -** -** a) The new syntax supports parenthesis. The old does not. -** -** b) The new syntax supports the AND and NOT operators. The old does not. -** -** c) The old syntax supports the "-" token qualifier. This is not -** supported by the new syntax (it is replaced by the NOT operator). -** -** d) When using the old syntax, the OR operator has a greater precedence -** than an implicit AND. When using the new, both implicity and explicit -** AND operators have a higher precedence than OR. -** -** If compiled with SQLITE_TEST defined, then this module exports the -** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable -** to zero causes the module to use the old syntax. If it is set to -** non-zero the new syntax is activated. This is so both syntaxes can -** be tested using a single build of testfixture. -** -** The following describes the syntax supported by the fts3 MATCH -** operator in a similar format to that used by the lemon parser -** generator. This module does not use actually lemon, it uses a -** custom parser. -** -** query ::= andexpr (OR andexpr)*. -** -** andexpr ::= notexpr (AND? notexpr)*. -** -** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*. -** notexpr ::= LP query RP. -** -** nearexpr ::= phrase (NEAR distance_opt nearexpr)*. -** -** distance_opt ::= . -** distance_opt ::= / INTEGER. -** -** phrase ::= TOKEN. -** phrase ::= COLUMN:TOKEN. -** phrase ::= "TOKEN TOKEN TOKEN...". -*/ - -#ifdef SQLITE_TEST -SQLITE_API int sqlite3_fts3_enable_parentheses = 0; -#else -# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS -# define sqlite3_fts3_enable_parentheses 1 -# else -# define sqlite3_fts3_enable_parentheses 0 -# endif -#endif - -/* -** Default span for NEAR operators. -*/ -#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 - -/* #include */ -/* #include */ - -/* -** isNot: -** This variable is used by function getNextNode(). When getNextNode() is -** called, it sets ParseContext.isNot to true if the 'next node' is a -** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the -** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to -** zero. -*/ -typedef struct ParseContext ParseContext; -struct ParseContext { - sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ - int iLangid; /* Language id used with tokenizer */ - const char **azCol; /* Array of column names for fts3 table */ - int bFts4; /* True to allow FTS4-only syntax */ - int nCol; /* Number of entries in azCol[] */ - int iDefaultCol; /* Default column to query */ - int isNot; /* True if getNextNode() sees a unary - */ - sqlite3_context *pCtx; /* Write error message here */ - int nNest; /* Number of nested brackets */ -}; - -/* -** This function is equivalent to the standard isspace() function. -** -** The standard isspace() can be awkward to use safely, because although it -** is defined to accept an argument of type int, its behavior when passed -** an integer that falls outside of the range of the unsigned char type -** is undefined (and sometimes, "undefined" means segfault). This wrapper -** is defined to accept an argument of type char, and always returns 0 for -** any values that fall outside of the range of the unsigned char type (i.e. -** negative values). -*/ -static int fts3isspace(char c){ - return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; -} - -/* -** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, -** zero the memory before returning a pointer to it. If unsuccessful, -** return NULL. -*/ -static void *fts3MallocZero(int nByte){ - void *pRet = sqlite3_malloc(nByte); - if( pRet ) memset(pRet, 0, nByte); - return pRet; -} - -SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( - sqlite3_tokenizer *pTokenizer, - int iLangid, - const char *z, - int n, - sqlite3_tokenizer_cursor **ppCsr -){ - sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - sqlite3_tokenizer_cursor *pCsr = 0; - int rc; - - rc = pModule->xOpen(pTokenizer, z, n, &pCsr); - assert( rc==SQLITE_OK || pCsr==0 ); - if( rc==SQLITE_OK ){ - pCsr->pTokenizer = pTokenizer; - if( pModule->iVersion>=1 ){ - rc = pModule->xLanguageid(pCsr, iLangid); - if( rc!=SQLITE_OK ){ - pModule->xClose(pCsr); - pCsr = 0; - } - } - } - *ppCsr = pCsr; - return rc; -} - -/* -** Function getNextNode(), which is called by fts3ExprParse(), may itself -** call fts3ExprParse(). So this forward declaration is required. -*/ -static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); - -/* -** Extract the next token from buffer z (length n) using the tokenizer -** and other information (column names etc.) in pParse. Create an Fts3Expr -** structure of type FTSQUERY_PHRASE containing a phrase consisting of this -** single token and set *ppExpr to point to it. If the end of the buffer is -** reached before a token is found, set *ppExpr to zero. It is the -** responsibility of the caller to eventually deallocate the allocated -** Fts3Expr structure (if any) by passing it to sqlite3_free(). -** -** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation -** fails. -*/ -static int getNextToken( - ParseContext *pParse, /* fts3 query parse context */ - int iCol, /* Value for Fts3Phrase.iColumn */ - const char *z, int n, /* Input string */ - Fts3Expr **ppExpr, /* OUT: expression */ - int *pnConsumed /* OUT: Number of bytes consumed */ -){ - sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; - sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - int rc; - sqlite3_tokenizer_cursor *pCursor; - Fts3Expr *pRet = 0; - int i = 0; - - /* Set variable i to the maximum number of bytes of input to tokenize. */ - for(i=0; iiLangid, z, i, &pCursor); - if( rc==SQLITE_OK ){ - const char *zToken; - int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; - int nByte; /* total space to allocate */ - - rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); - if( rc==SQLITE_OK ){ - nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; - pRet = (Fts3Expr *)fts3MallocZero(nByte); - if( !pRet ){ - rc = SQLITE_NOMEM; - }else{ - pRet->eType = FTSQUERY_PHRASE; - pRet->pPhrase = (Fts3Phrase *)&pRet[1]; - pRet->pPhrase->nToken = 1; - pRet->pPhrase->iColumn = iCol; - pRet->pPhrase->aToken[0].n = nToken; - pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; - memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); - - if( iEndpPhrase->aToken[0].isPrefix = 1; - iEnd++; - } - - while( 1 ){ - if( !sqlite3_fts3_enable_parentheses - && iStart>0 && z[iStart-1]=='-' - ){ - pParse->isNot = 1; - iStart--; - }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){ - pRet->pPhrase->aToken[0].bFirst = 1; - iStart--; - }else{ - break; - } - } - - } - *pnConsumed = iEnd; - }else if( i && rc==SQLITE_DONE ){ - rc = SQLITE_OK; - } - - pModule->xClose(pCursor); - } - - *ppExpr = pRet; - return rc; -} - - -/* -** Enlarge a memory allocation. If an out-of-memory allocation occurs, -** then free the old allocation. -*/ -static void *fts3ReallocOrFree(void *pOrig, int nNew){ - void *pRet = sqlite3_realloc(pOrig, nNew); - if( !pRet ){ - sqlite3_free(pOrig); - } - return pRet; -} - -/* -** Buffer zInput, length nInput, contains the contents of a quoted string -** that appeared as part of an fts3 query expression. Neither quote character -** is included in the buffer. This function attempts to tokenize the entire -** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE -** containing the results. -** -** If successful, SQLITE_OK is returned and *ppExpr set to point at the -** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory -** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set -** to 0. -*/ -static int getNextString( - ParseContext *pParse, /* fts3 query parse context */ - const char *zInput, int nInput, /* Input string */ - Fts3Expr **ppExpr /* OUT: expression */ -){ - sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; - sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - int rc; - Fts3Expr *p = 0; - sqlite3_tokenizer_cursor *pCursor = 0; - char *zTemp = 0; - int nTemp = 0; - - const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); - int nToken = 0; - - /* The final Fts3Expr data structure, including the Fts3Phrase, - ** Fts3PhraseToken structures token buffers are all stored as a single - ** allocation so that the expression can be freed with a single call to - ** sqlite3_free(). Setting this up requires a two pass approach. - ** - ** The first pass, in the block below, uses a tokenizer cursor to iterate - ** through the tokens in the expression. This pass uses fts3ReallocOrFree() - ** to assemble data in two dynamic buffers: - ** - ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase - ** structure, followed by the array of Fts3PhraseToken - ** structures. This pass only populates the Fts3PhraseToken array. - ** - ** Buffer zTemp: Contains copies of all tokens. - ** - ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, - ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase - ** structures. - */ - rc = sqlite3Fts3OpenTokenizer( - pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); - if( rc==SQLITE_OK ){ - int ii; - for(ii=0; rc==SQLITE_OK; ii++){ - const char *zByte; - int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; - rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); - if( rc==SQLITE_OK ){ - Fts3PhraseToken *pToken; - - p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); - if( !p ) goto no_mem; - - zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); - if( !zTemp ) goto no_mem; - - assert( nToken==ii ); - pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; - memset(pToken, 0, sizeof(Fts3PhraseToken)); - - memcpy(&zTemp[nTemp], zByte, nByte); - nTemp += nByte; - - pToken->n = nByte; - pToken->isPrefix = (iEndbFirst = (iBegin>0 && zInput[iBegin-1]=='^'); - nToken = ii+1; - } - } - - pModule->xClose(pCursor); - pCursor = 0; - } - - if( rc==SQLITE_DONE ){ - int jj; - char *zBuf = 0; - - p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); - if( !p ) goto no_mem; - memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); - p->eType = FTSQUERY_PHRASE; - p->pPhrase = (Fts3Phrase *)&p[1]; - p->pPhrase->iColumn = pParse->iDefaultCol; - p->pPhrase->nToken = nToken; - - zBuf = (char *)&p->pPhrase->aToken[nToken]; - if( zTemp ){ - memcpy(zBuf, zTemp, nTemp); - sqlite3_free(zTemp); - }else{ - assert( nTemp==0 ); - } - - for(jj=0; jjpPhrase->nToken; jj++){ - p->pPhrase->aToken[jj].z = zBuf; - zBuf += p->pPhrase->aToken[jj].n; - } - rc = SQLITE_OK; - } - - *ppExpr = p; - return rc; -no_mem: - - if( pCursor ){ - pModule->xClose(pCursor); - } - sqlite3_free(zTemp); - sqlite3_free(p); - *ppExpr = 0; - return SQLITE_NOMEM; -} - -/* -** The output variable *ppExpr is populated with an allocated Fts3Expr -** structure, or set to 0 if the end of the input buffer is reached. -** -** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM -** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered. -** If SQLITE_ERROR is returned, pContext is populated with an error message. -*/ -static int getNextNode( - ParseContext *pParse, /* fts3 query parse context */ - const char *z, int n, /* Input string */ - Fts3Expr **ppExpr, /* OUT: expression */ - int *pnConsumed /* OUT: Number of bytes consumed */ -){ - static const struct Fts3Keyword { - char *z; /* Keyword text */ - unsigned char n; /* Length of the keyword */ - unsigned char parenOnly; /* Only valid in paren mode */ - unsigned char eType; /* Keyword code */ - } aKeyword[] = { - { "OR" , 2, 0, FTSQUERY_OR }, - { "AND", 3, 1, FTSQUERY_AND }, - { "NOT", 3, 1, FTSQUERY_NOT }, - { "NEAR", 4, 0, FTSQUERY_NEAR } - }; - int ii; - int iCol; - int iColLen; - int rc; - Fts3Expr *pRet = 0; - - const char *zInput = z; - int nInput = n; - - pParse->isNot = 0; - - /* Skip over any whitespace before checking for a keyword, an open or - ** close bracket, or a quoted string. - */ - while( nInput>0 && fts3isspace(*zInput) ){ - nInput--; - zInput++; - } - if( nInput==0 ){ - return SQLITE_DONE; - } - - /* See if we are dealing with a keyword. */ - for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){ - const struct Fts3Keyword *pKey = &aKeyword[ii]; - - if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){ - continue; - } - - if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){ - int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM; - int nKey = pKey->n; - char cNext; - - /* If this is a "NEAR" keyword, check for an explicit nearness. */ - if( pKey->eType==FTSQUERY_NEAR ){ - assert( nKey==4 ); - if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ - nNear = 0; - for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){ - nNear = nNear * 10 + (zInput[nKey] - '0'); - } - } - } - - /* At this point this is probably a keyword. But for that to be true, - ** the next byte must contain either whitespace, an open or close - ** parenthesis, a quote character, or EOF. - */ - cNext = zInput[nKey]; - if( fts3isspace(cNext) - || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 - ){ - pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr)); - if( !pRet ){ - return SQLITE_NOMEM; - } - pRet->eType = pKey->eType; - pRet->nNear = nNear; - *ppExpr = pRet; - *pnConsumed = (int)((zInput - z) + nKey); - return SQLITE_OK; - } - - /* Turns out that wasn't a keyword after all. This happens if the - ** user has supplied a token such as "ORacle". Continue. - */ - } - } - - /* See if we are dealing with a quoted phrase. If this is the case, then - ** search for the closing quote and pass the whole string to getNextString() - ** for processing. This is easy to do, as fts3 has no syntax for escaping - ** a quote character embedded in a string. - */ - if( *zInput=='"' ){ - for(ii=1; iinNest++; - rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); - if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } - *pnConsumed = (int)(zInput - z) + 1 + nConsumed; - return rc; - }else if( *zInput==')' ){ - pParse->nNest--; - *pnConsumed = (int)((zInput - z) + 1); - *ppExpr = 0; - return SQLITE_DONE; - } - } - - /* If control flows to this point, this must be a regular token, or - ** the end of the input. Read a regular token using the sqlite3_tokenizer - ** interface. Before doing so, figure out if there is an explicit - ** column specifier for the token. - ** - ** TODO: Strangely, it is not possible to associate a column specifier - ** with a quoted phrase, only with a single token. Not sure if this was - ** an implementation artifact or an intentional decision when fts3 was - ** first implemented. Whichever it was, this module duplicates the - ** limitation. - */ - iCol = pParse->iDefaultCol; - iColLen = 0; - for(ii=0; iinCol; ii++){ - const char *zStr = pParse->azCol[ii]; - int nStr = (int)strlen(zStr); - if( nInput>nStr && zInput[nStr]==':' - && sqlite3_strnicmp(zStr, zInput, nStr)==0 - ){ - iCol = ii; - iColLen = (int)((zInput - z) + nStr + 1); - break; - } - } - rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed); - *pnConsumed += iColLen; - return rc; -} - -/* -** The argument is an Fts3Expr structure for a binary operator (any type -** except an FTSQUERY_PHRASE). Return an integer value representing the -** precedence of the operator. Lower values have a higher precedence (i.e. -** group more tightly). For example, in the C language, the == operator -** groups more tightly than ||, and would therefore have a higher precedence. -** -** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS -** is defined), the order of the operators in precedence from highest to -** lowest is: -** -** NEAR -** NOT -** AND (including implicit ANDs) -** OR -** -** Note that when using the old query syntax, the OR operator has a higher -** precedence than the AND operator. -*/ -static int opPrecedence(Fts3Expr *p){ - assert( p->eType!=FTSQUERY_PHRASE ); - if( sqlite3_fts3_enable_parentheses ){ - return p->eType; - }else if( p->eType==FTSQUERY_NEAR ){ - return 1; - }else if( p->eType==FTSQUERY_OR ){ - return 2; - } - assert( p->eType==FTSQUERY_AND ); - return 3; -} - -/* -** Argument ppHead contains a pointer to the current head of a query -** expression tree being parsed. pPrev is the expression node most recently -** inserted into the tree. This function adds pNew, which is always a binary -** operator node, into the expression tree based on the relative precedence -** of pNew and the existing nodes of the tree. This may result in the head -** of the tree changing, in which case *ppHead is set to the new root node. -*/ -static void insertBinaryOperator( - Fts3Expr **ppHead, /* Pointer to the root node of a tree */ - Fts3Expr *pPrev, /* Node most recently inserted into the tree */ - Fts3Expr *pNew /* New binary node to insert into expression tree */ -){ - Fts3Expr *pSplit = pPrev; - while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){ - pSplit = pSplit->pParent; - } - - if( pSplit->pParent ){ - assert( pSplit->pParent->pRight==pSplit ); - pSplit->pParent->pRight = pNew; - pNew->pParent = pSplit->pParent; - }else{ - *ppHead = pNew; - } - pNew->pLeft = pSplit; - pSplit->pParent = pNew; -} - -/* -** Parse the fts3 query expression found in buffer z, length n. This function -** returns either when the end of the buffer is reached or an unmatched -** closing bracket - ')' - is encountered. -** -** If successful, SQLITE_OK is returned, *ppExpr is set to point to the -** parsed form of the expression and *pnConsumed is set to the number of -** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM -** (out of memory error) or SQLITE_ERROR (parse error) is returned. -*/ -static int fts3ExprParse( - ParseContext *pParse, /* fts3 query parse context */ - const char *z, int n, /* Text of MATCH query */ - Fts3Expr **ppExpr, /* OUT: Parsed query structure */ - int *pnConsumed /* OUT: Number of bytes consumed */ -){ - Fts3Expr *pRet = 0; - Fts3Expr *pPrev = 0; - Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */ - int nIn = n; - const char *zIn = z; - int rc = SQLITE_OK; - int isRequirePhrase = 1; - - while( rc==SQLITE_OK ){ - Fts3Expr *p = 0; - int nByte = 0; - - rc = getNextNode(pParse, zIn, nIn, &p, &nByte); - assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); - if( rc==SQLITE_OK ){ - if( p ){ - int isPhrase; - - if( !sqlite3_fts3_enable_parentheses - && p->eType==FTSQUERY_PHRASE && pParse->isNot - ){ - /* Create an implicit NOT operator. */ - Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); - if( !pNot ){ - sqlite3Fts3ExprFree(p); - rc = SQLITE_NOMEM; - goto exprparse_out; - } - pNot->eType = FTSQUERY_NOT; - pNot->pRight = p; - p->pParent = pNot; - if( pNotBranch ){ - pNot->pLeft = pNotBranch; - pNotBranch->pParent = pNot; - } - pNotBranch = pNot; - p = pPrev; - }else{ - int eType = p->eType; - isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); - - /* The isRequirePhrase variable is set to true if a phrase or - ** an expression contained in parenthesis is required. If a - ** binary operator (AND, OR, NOT or NEAR) is encounted when - ** isRequirePhrase is set, this is a syntax error. - */ - if( !isPhrase && isRequirePhrase ){ - sqlite3Fts3ExprFree(p); - rc = SQLITE_ERROR; - goto exprparse_out; - } - - if( isPhrase && !isRequirePhrase ){ - /* Insert an implicit AND operator. */ - Fts3Expr *pAnd; - assert( pRet && pPrev ); - pAnd = fts3MallocZero(sizeof(Fts3Expr)); - if( !pAnd ){ - sqlite3Fts3ExprFree(p); - rc = SQLITE_NOMEM; - goto exprparse_out; - } - pAnd->eType = FTSQUERY_AND; - insertBinaryOperator(&pRet, pPrev, pAnd); - pPrev = pAnd; - } - - /* This test catches attempts to make either operand of a NEAR - ** operator something other than a phrase. For example, either of - ** the following: - ** - ** (bracketed expression) NEAR phrase - ** phrase NEAR (bracketed expression) - ** - ** Return an error in either case. - */ - if( pPrev && ( - (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) - || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) - )){ - sqlite3Fts3ExprFree(p); - rc = SQLITE_ERROR; - goto exprparse_out; - } - - if( isPhrase ){ - if( pRet ){ - assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); - pPrev->pRight = p; - p->pParent = pPrev; - }else{ - pRet = p; - } - }else{ - insertBinaryOperator(&pRet, pPrev, p); - } - isRequirePhrase = !isPhrase; - } - pPrev = p; - } - assert( nByte>0 ); - } - assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); - nIn -= nByte; - zIn += nByte; - } - - if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ - rc = SQLITE_ERROR; - } - - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - if( !sqlite3_fts3_enable_parentheses && pNotBranch ){ - if( !pRet ){ - rc = SQLITE_ERROR; - }else{ - Fts3Expr *pIter = pNotBranch; - while( pIter->pLeft ){ - pIter = pIter->pLeft; - } - pIter->pLeft = pRet; - pRet->pParent = pIter; - pRet = pNotBranch; - } - } - } - *pnConsumed = n - nIn; - -exprparse_out: - if( rc!=SQLITE_OK ){ - sqlite3Fts3ExprFree(pRet); - sqlite3Fts3ExprFree(pNotBranch); - pRet = 0; - } - *ppExpr = pRet; - return rc; -} - -/* -** Return SQLITE_ERROR if the maximum depth of the expression tree passed -** as the only argument is more than nMaxDepth. -*/ -static int fts3ExprCheckDepth(Fts3Expr *p, int nMaxDepth){ - int rc = SQLITE_OK; - if( p ){ - if( nMaxDepth<0 ){ - rc = SQLITE_TOOBIG; - }else{ - rc = fts3ExprCheckDepth(p->pLeft, nMaxDepth-1); - if( rc==SQLITE_OK ){ - rc = fts3ExprCheckDepth(p->pRight, nMaxDepth-1); - } - } - } - return rc; -} - -/* -** This function attempts to transform the expression tree at (*pp) to -** an equivalent but more balanced form. The tree is modified in place. -** If successful, SQLITE_OK is returned and (*pp) set to point to the -** new root expression node. -** -** nMaxDepth is the maximum allowable depth of the balanced sub-tree. -** -** Otherwise, if an error occurs, an SQLite error code is returned and -** expression (*pp) freed. -*/ -static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ - int rc = SQLITE_OK; /* Return code */ - Fts3Expr *pRoot = *pp; /* Initial root node */ - Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ - int eType = pRoot->eType; /* Type of node in this tree */ - - if( nMaxDepth==0 ){ - rc = SQLITE_ERROR; - } - - if( rc==SQLITE_OK ){ - if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ - Fts3Expr **apLeaf; - apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth); - if( 0==apLeaf ){ - rc = SQLITE_NOMEM; - }else{ - memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); - } - - if( rc==SQLITE_OK ){ - int i; - Fts3Expr *p; - - /* Set $p to point to the left-most leaf in the tree of eType nodes. */ - for(p=pRoot; p->eType==eType; p=p->pLeft){ - assert( p->pParent==0 || p->pParent->pLeft==p ); - assert( p->pLeft && p->pRight ); - } - - /* This loop runs once for each leaf in the tree of eType nodes. */ - while( 1 ){ - int iLvl; - Fts3Expr *pParent = p->pParent; /* Current parent of p */ - - assert( pParent==0 || pParent->pLeft==p ); - p->pParent = 0; - if( pParent ){ - pParent->pLeft = 0; - }else{ - pRoot = 0; - } - rc = fts3ExprBalance(&p, nMaxDepth-1); - if( rc!=SQLITE_OK ) break; - - for(iLvl=0; p && iLvlpLeft = apLeaf[iLvl]; - pFree->pRight = p; - pFree->pLeft->pParent = pFree; - pFree->pRight->pParent = pFree; - - p = pFree; - pFree = pFree->pParent; - p->pParent = 0; - apLeaf[iLvl] = 0; - } - } - if( p ){ - sqlite3Fts3ExprFree(p); - rc = SQLITE_TOOBIG; - break; - } - - /* If that was the last leaf node, break out of the loop */ - if( pParent==0 ) break; - - /* Set $p to point to the next leaf in the tree of eType nodes */ - for(p=pParent->pRight; p->eType==eType; p=p->pLeft); - - /* Remove pParent from the original tree. */ - assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); - pParent->pRight->pParent = pParent->pParent; - if( pParent->pParent ){ - pParent->pParent->pLeft = pParent->pRight; - }else{ - assert( pParent==pRoot ); - pRoot = pParent->pRight; - } - - /* Link pParent into the free node list. It will be used as an - ** internal node of the new tree. */ - pParent->pParent = pFree; - pFree = pParent; - } - - if( rc==SQLITE_OK ){ - p = 0; - for(i=0; ipParent = 0; - }else{ - assert( pFree!=0 ); - pFree->pRight = p; - pFree->pLeft = apLeaf[i]; - pFree->pLeft->pParent = pFree; - pFree->pRight->pParent = pFree; - - p = pFree; - pFree = pFree->pParent; - p->pParent = 0; - } - } - } - pRoot = p; - }else{ - /* An error occurred. Delete the contents of the apLeaf[] array - ** and pFree list. Everything else is cleaned up by the call to - ** sqlite3Fts3ExprFree(pRoot) below. */ - Fts3Expr *pDel; - for(i=0; ipParent; - sqlite3_free(pDel); - } - } - - assert( pFree==0 ); - sqlite3_free( apLeaf ); - } - }else if( eType==FTSQUERY_NOT ){ - Fts3Expr *pLeft = pRoot->pLeft; - Fts3Expr *pRight = pRoot->pRight; - - pRoot->pLeft = 0; - pRoot->pRight = 0; - pLeft->pParent = 0; - pRight->pParent = 0; - - rc = fts3ExprBalance(&pLeft, nMaxDepth-1); - if( rc==SQLITE_OK ){ - rc = fts3ExprBalance(&pRight, nMaxDepth-1); - } - - if( rc!=SQLITE_OK ){ - sqlite3Fts3ExprFree(pRight); - sqlite3Fts3ExprFree(pLeft); - }else{ - assert( pLeft && pRight ); - pRoot->pLeft = pLeft; - pLeft->pParent = pRoot; - pRoot->pRight = pRight; - pRight->pParent = pRoot; - } - } - } - - if( rc!=SQLITE_OK ){ - sqlite3Fts3ExprFree(pRoot); - pRoot = 0; - } - *pp = pRoot; - return rc; -} - -/* -** This function is similar to sqlite3Fts3ExprParse(), with the following -** differences: -** -** 1. It does not do expression rebalancing. -** 2. It does not check that the expression does not exceed the -** maximum allowable depth. -** 3. Even if it fails, *ppExpr may still be set to point to an -** expression tree. It should be deleted using sqlite3Fts3ExprFree() -** in this case. -*/ -static int fts3ExprParseUnbalanced( - sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ - int iLangid, /* Language id for tokenizer */ - char **azCol, /* Array of column names for fts3 table */ - int bFts4, /* True to allow FTS4-only syntax */ - int nCol, /* Number of entries in azCol[] */ - int iDefaultCol, /* Default column to query */ - const char *z, int n, /* Text of MATCH query */ - Fts3Expr **ppExpr /* OUT: Parsed query structure */ -){ - int nParsed; - int rc; - ParseContext sParse; - - memset(&sParse, 0, sizeof(ParseContext)); - sParse.pTokenizer = pTokenizer; - sParse.iLangid = iLangid; - sParse.azCol = (const char **)azCol; - sParse.nCol = nCol; - sParse.iDefaultCol = iDefaultCol; - sParse.bFts4 = bFts4; - if( z==0 ){ - *ppExpr = 0; - return SQLITE_OK; - } - if( n<0 ){ - n = (int)strlen(z); - } - rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed); - assert( rc==SQLITE_OK || *ppExpr==0 ); - - /* Check for mismatched parenthesis */ - if( rc==SQLITE_OK && sParse.nNest ){ - rc = SQLITE_ERROR; - } - - return rc; -} - -/* -** Parameters z and n contain a pointer to and length of a buffer containing -** an fts3 query expression, respectively. This function attempts to parse the -** query expression and create a tree of Fts3Expr structures representing the -** parsed expression. If successful, *ppExpr is set to point to the head -** of the parsed expression tree and SQLITE_OK is returned. If an error -** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse -** error) is returned and *ppExpr is set to 0. -** -** If parameter n is a negative number, then z is assumed to point to a -** nul-terminated string and the length is determined using strlen(). -** -** The first parameter, pTokenizer, is passed the fts3 tokenizer module to -** use to normalize query tokens while parsing the expression. The azCol[] -** array, which is assumed to contain nCol entries, should contain the names -** of each column in the target fts3 table, in order from left to right. -** Column names must be nul-terminated strings. -** -** The iDefaultCol parameter should be passed the index of the table column -** that appears on the left-hand-side of the MATCH operator (the default -** column to match against for tokens for which a column name is not explicitly -** specified as part of the query string), or -1 if tokens may by default -** match any table column. -*/ -SQLITE_PRIVATE int sqlite3Fts3ExprParse( - sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ - int iLangid, /* Language id for tokenizer */ - char **azCol, /* Array of column names for fts3 table */ - int bFts4, /* True to allow FTS4-only syntax */ - int nCol, /* Number of entries in azCol[] */ - int iDefaultCol, /* Default column to query */ - const char *z, int n, /* Text of MATCH query */ - Fts3Expr **ppExpr, /* OUT: Parsed query structure */ - char **pzErr /* OUT: Error message (sqlite3_malloc) */ -){ - int rc = fts3ExprParseUnbalanced( - pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr - ); - - /* Rebalance the expression. And check that its depth does not exceed - ** SQLITE_FTS3_MAX_EXPR_DEPTH. */ - if( rc==SQLITE_OK && *ppExpr ){ - rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); - if( rc==SQLITE_OK ){ - rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); - } - } - - if( rc!=SQLITE_OK ){ - sqlite3Fts3ExprFree(*ppExpr); - *ppExpr = 0; - if( rc==SQLITE_TOOBIG ){ - sqlite3Fts3ErrMsg(pzErr, - "FTS expression tree is too large (maximum depth %d)", - SQLITE_FTS3_MAX_EXPR_DEPTH - ); - rc = SQLITE_ERROR; - }else if( rc==SQLITE_ERROR ){ - sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); - } - } - - return rc; -} - -/* -** Free a single node of an expression tree. -*/ -static void fts3FreeExprNode(Fts3Expr *p){ - assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); - sqlite3Fts3EvalPhraseCleanup(p->pPhrase); - sqlite3_free(p->aMI); - sqlite3_free(p); -} - -/* -** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse(). -** -** This function would be simpler if it recursively called itself. But -** that would mean passing a sufficiently large expression to ExprParse() -** could cause a stack overflow. -*/ -SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){ - Fts3Expr *p; - assert( pDel==0 || pDel->pParent==0 ); - for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){ - assert( p->pParent==0 || p==p->pParent->pRight || p==p->pParent->pLeft ); - } - while( p ){ - Fts3Expr *pParent = p->pParent; - fts3FreeExprNode(p); - if( pParent && p==pParent->pLeft && pParent->pRight ){ - p = pParent->pRight; - while( p && (p->pLeft || p->pRight) ){ - assert( p==p->pParent->pRight || p==p->pParent->pLeft ); - p = (p->pLeft ? p->pLeft : p->pRight); - } - }else{ - p = pParent; - } - } -} - -/**************************************************************************** -***************************************************************************** -** Everything after this point is just test code. -*/ - -#ifdef SQLITE_TEST - -/* #include */ - -/* -** Function to query the hash-table of tokenizers (see README.tokenizers). -*/ -static int queryTestTokenizer( - sqlite3 *db, - const char *zName, - const sqlite3_tokenizer_module **pp -){ - int rc; - sqlite3_stmt *pStmt; - const char zSql[] = "SELECT fts3_tokenizer(?)"; - - *pp = 0; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ - memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); - } - } - - return sqlite3_finalize(pStmt); -} - -/* -** Return a pointer to a buffer containing a text representation of the -** expression passed as the first argument. The buffer is obtained from -** sqlite3_malloc(). It is the responsibility of the caller to use -** sqlite3_free() to release the memory. If an OOM condition is encountered, -** NULL is returned. -** -** If the second argument is not NULL, then its contents are prepended to -** the returned expression text and then freed using sqlite3_free(). -*/ -static char *exprToString(Fts3Expr *pExpr, char *zBuf){ - if( pExpr==0 ){ - return sqlite3_mprintf(""); - } - switch( pExpr->eType ){ - case FTSQUERY_PHRASE: { - Fts3Phrase *pPhrase = pExpr->pPhrase; - int i; - zBuf = sqlite3_mprintf( - "%zPHRASE %d 0", zBuf, pPhrase->iColumn); - for(i=0; zBuf && inToken; i++){ - zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, - pPhrase->aToken[i].n, pPhrase->aToken[i].z, - (pPhrase->aToken[i].isPrefix?"+":"") - ); - } - return zBuf; - } - - case FTSQUERY_NEAR: - zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); - break; - case FTSQUERY_NOT: - zBuf = sqlite3_mprintf("%zNOT ", zBuf); - break; - case FTSQUERY_AND: - zBuf = sqlite3_mprintf("%zAND ", zBuf); - break; - case FTSQUERY_OR: - zBuf = sqlite3_mprintf("%zOR ", zBuf); - break; - } - - if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); - if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); - if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); - - if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); - if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); - - return zBuf; -} - -/* -** This is the implementation of a scalar SQL function used to test the -** expression parser. It should be called as follows: -** -** fts3_exprtest(, , , ...); -** -** The first argument, , is the name of the fts3 tokenizer used -** to parse the query expression (see README.tokenizers). The second argument -** is the query expression to parse. Each subsequent argument is the name -** of a column of the fts3 table that the query expression may refer to. -** For example: -** -** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); -*/ -static void fts3ExprTest( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - sqlite3_tokenizer_module const *pModule = 0; - sqlite3_tokenizer *pTokenizer = 0; - int rc; - char **azCol = 0; - const char *zExpr; - int nExpr; - int nCol; - int ii; - Fts3Expr *pExpr; - char *zBuf = 0; - sqlite3 *db = sqlite3_context_db_handle(context); - - if( argc<3 ){ - sqlite3_result_error(context, - "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 - ); - return; - } - - rc = queryTestTokenizer(db, - (const char *)sqlite3_value_text(argv[0]), &pModule); - if( rc==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - goto exprtest_out; - }else if( !pModule ){ - sqlite3_result_error(context, "No such tokenizer module", -1); - goto exprtest_out; - } - - rc = pModule->xCreate(0, 0, &pTokenizer); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - goto exprtest_out; - } - pTokenizer->pModule = pModule; - - zExpr = (const char *)sqlite3_value_text(argv[1]); - nExpr = sqlite3_value_bytes(argv[1]); - nCol = argc-2; - azCol = (char **)sqlite3_malloc(nCol*sizeof(char *)); - if( !azCol ){ - sqlite3_result_error_nomem(context); - goto exprtest_out; - } - for(ii=0; iixDestroy(pTokenizer); - } - sqlite3_free(azCol); -} - -/* -** Register the query expression parser test function fts3_exprtest() -** with database connection db. -*/ -SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ - int rc = sqlite3_create_function( - db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0 - ); - if( rc==SQLITE_OK ){ - rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", - -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 - ); - } - return rc; -} - -#endif -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_expr.c *******************************************/ -/************** Begin file fts3_hash.c ***************************************/ -/* -** 2001 September 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This is the implementation of generic hash-tables used in SQLite. -** We've modified it slightly to serve as a standalone hash table -** implementation for the full-text indexing module. -*/ - -/* -** The code in this file is only compiled if: -** -** * The FTS3 module is being built as an extension -** (in which case SQLITE_CORE is not defined), or -** -** * The FTS3 module is being built into the core of -** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ -/* #include */ - -/* #include "fts3_hash.h" */ - -/* -** Malloc and Free functions -*/ -static void *fts3HashMalloc(int n){ - void *p = sqlite3_malloc(n); - if( p ){ - memset(p, 0, n); - } - return p; -} -static void fts3HashFree(void *p){ - sqlite3_free(p); -} - -/* Turn bulk memory into a hash table object by initializing the -** fields of the Hash structure. -** -** "pNew" is a pointer to the hash table that is to be initialized. -** keyClass is one of the constants -** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass -** determines what kind of key the hash table will use. "copyKey" is -** true if the hash table should make its own private copy of keys and -** false if it should just use the supplied pointer. -*/ -SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ - assert( pNew!=0 ); - assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); - pNew->keyClass = keyClass; - pNew->copyKey = copyKey; - pNew->first = 0; - pNew->count = 0; - pNew->htsize = 0; - pNew->ht = 0; -} - -/* Remove all entries from a hash table. Reclaim all memory. -** Call this routine to delete a hash table or to reset a hash table -** to the empty state. -*/ -SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){ - Fts3HashElem *elem; /* For looping over all elements of the table */ - - assert( pH!=0 ); - elem = pH->first; - pH->first = 0; - fts3HashFree(pH->ht); - pH->ht = 0; - pH->htsize = 0; - while( elem ){ - Fts3HashElem *next_elem = elem->next; - if( pH->copyKey && elem->pKey ){ - fts3HashFree(elem->pKey); - } - fts3HashFree(elem); - elem = next_elem; - } - pH->count = 0; -} - -/* -** Hash and comparison functions when the mode is FTS3_HASH_STRING -*/ -static int fts3StrHash(const void *pKey, int nKey){ - const char *z = (const char *)pKey; - unsigned h = 0; - if( nKey<=0 ) nKey = (int) strlen(z); - while( nKey > 0 ){ - h = (h<<3) ^ h ^ *z++; - nKey--; - } - return (int)(h & 0x7fffffff); -} -static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - if( n1!=n2 ) return 1; - return strncmp((const char*)pKey1,(const char*)pKey2,n1); -} - -/* -** Hash and comparison functions when the mode is FTS3_HASH_BINARY -*/ -static int fts3BinHash(const void *pKey, int nKey){ - int h = 0; - const char *z = (const char *)pKey; - while( nKey-- > 0 ){ - h = (h<<3) ^ h ^ *(z++); - } - return h & 0x7fffffff; -} -static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ - if( n1!=n2 ) return 1; - return memcmp(pKey1,pKey2,n1); -} - -/* -** Return a pointer to the appropriate hash function given the key class. -** -** The C syntax in this function definition may be unfamilar to some -** programmers, so we provide the following additional explanation: -** -** The name of the function is "ftsHashFunction". The function takes a -** single parameter "keyClass". The return value of ftsHashFunction() -** is a pointer to another function. Specifically, the return value -** of ftsHashFunction() is a pointer to a function that takes two parameters -** with types "const void*" and "int" and returns an "int". -*/ -static int (*ftsHashFunction(int keyClass))(const void*,int){ - if( keyClass==FTS3_HASH_STRING ){ - return &fts3StrHash; - }else{ - assert( keyClass==FTS3_HASH_BINARY ); - return &fts3BinHash; - } -} - -/* -** Return a pointer to the appropriate hash function given the key class. -** -** For help in interpreted the obscure C code in the function definition, -** see the header comment on the previous function. -*/ -static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){ - if( keyClass==FTS3_HASH_STRING ){ - return &fts3StrCompare; - }else{ - assert( keyClass==FTS3_HASH_BINARY ); - return &fts3BinCompare; - } -} - -/* Link an element into the hash table -*/ -static void fts3HashInsertElement( - Fts3Hash *pH, /* The complete hash table */ - struct _fts3ht *pEntry, /* The entry into which pNew is inserted */ - Fts3HashElem *pNew /* The element to be inserted */ -){ - Fts3HashElem *pHead; /* First element already in pEntry */ - pHead = pEntry->chain; - if( pHead ){ - pNew->next = pHead; - pNew->prev = pHead->prev; - if( pHead->prev ){ pHead->prev->next = pNew; } - else { pH->first = pNew; } - pHead->prev = pNew; - }else{ - pNew->next = pH->first; - if( pH->first ){ pH->first->prev = pNew; } - pNew->prev = 0; - pH->first = pNew; - } - pEntry->count++; - pEntry->chain = pNew; -} - - -/* Resize the hash table so that it cantains "new_size" buckets. -** "new_size" must be a power of 2. The hash table might fail -** to resize if sqliteMalloc() fails. -** -** Return non-zero if a memory allocation error occurs. -*/ -static int fts3Rehash(Fts3Hash *pH, int new_size){ - struct _fts3ht *new_ht; /* The new hash table */ - Fts3HashElem *elem, *next_elem; /* For looping over existing elements */ - int (*xHash)(const void*,int); /* The hash function */ - - assert( (new_size & (new_size-1))==0 ); - new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) ); - if( new_ht==0 ) return 1; - fts3HashFree(pH->ht); - pH->ht = new_ht; - pH->htsize = new_size; - xHash = ftsHashFunction(pH->keyClass); - for(elem=pH->first, pH->first=0; elem; elem = next_elem){ - int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); - next_elem = elem->next; - fts3HashInsertElement(pH, &new_ht[h], elem); - } - return 0; -} - -/* This function (for internal use only) locates an element in an -** hash table that matches the given key. The hash for this key has -** already been computed and is passed as the 4th parameter. -*/ -static Fts3HashElem *fts3FindElementByHash( - const Fts3Hash *pH, /* The pH to be searched */ - const void *pKey, /* The key we are searching for */ - int nKey, - int h /* The hash for this key. */ -){ - Fts3HashElem *elem; /* Used to loop thru the element list */ - int count; /* Number of elements left to test */ - int (*xCompare)(const void*,int,const void*,int); /* comparison function */ - - if( pH->ht ){ - struct _fts3ht *pEntry = &pH->ht[h]; - elem = pEntry->chain; - count = pEntry->count; - xCompare = ftsCompareFunction(pH->keyClass); - while( count-- && elem ){ - if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ - return elem; - } - elem = elem->next; - } - } - return 0; -} - -/* Remove a single entry from the hash table given a pointer to that -** element and a hash on the element's key. -*/ -static void fts3RemoveElementByHash( - Fts3Hash *pH, /* The pH containing "elem" */ - Fts3HashElem* elem, /* The element to be removed from the pH */ - int h /* Hash value for the element */ -){ - struct _fts3ht *pEntry; - if( elem->prev ){ - elem->prev->next = elem->next; - }else{ - pH->first = elem->next; - } - if( elem->next ){ - elem->next->prev = elem->prev; - } - pEntry = &pH->ht[h]; - if( pEntry->chain==elem ){ - pEntry->chain = elem->next; - } - pEntry->count--; - if( pEntry->count<=0 ){ - pEntry->chain = 0; - } - if( pH->copyKey && elem->pKey ){ - fts3HashFree(elem->pKey); - } - fts3HashFree( elem ); - pH->count--; - if( pH->count<=0 ){ - assert( pH->first==0 ); - assert( pH->count==0 ); - fts3HashClear(pH); - } -} - -SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( - const Fts3Hash *pH, - const void *pKey, - int nKey -){ - int h; /* A hash on key */ - int (*xHash)(const void*,int); /* The hash function */ - - if( pH==0 || pH->ht==0 ) return 0; - xHash = ftsHashFunction(pH->keyClass); - assert( xHash!=0 ); - h = (*xHash)(pKey,nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); -} - -/* -** Attempt to locate an element of the hash table pH with a key -** that matches pKey,nKey. Return the data for this element if it is -** found, or NULL if there is no match. -*/ -SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ - Fts3HashElem *pElem; /* The element that matches key (if any) */ - - pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey); - return pElem ? pElem->data : 0; -} - -/* Insert an element into the hash table pH. The key is pKey,nKey -** and the data is "data". -** -** If no element exists with a matching key, then a new -** element is created. A copy of the key is made if the copyKey -** flag is set. NULL is returned. -** -** If another element already exists with the same key, then the -** new data replaces the old data and the old data is returned. -** The key is not copied in this instance. If a malloc fails, then -** the new data is returned and the hash table is unchanged. -** -** If the "data" parameter to this function is NULL, then the -** element corresponding to "key" is removed from the hash table. -*/ -SQLITE_PRIVATE void *sqlite3Fts3HashInsert( - Fts3Hash *pH, /* The hash table to insert into */ - const void *pKey, /* The key */ - int nKey, /* Number of bytes in the key */ - void *data /* The data */ -){ - int hraw; /* Raw hash value of the key */ - int h; /* the hash of the key modulo hash table size */ - Fts3HashElem *elem; /* Used to loop thru the element list */ - Fts3HashElem *new_elem; /* New element added to the pH */ - int (*xHash)(const void*,int); /* The hash function */ - - assert( pH!=0 ); - xHash = ftsHashFunction(pH->keyClass); - assert( xHash!=0 ); - hraw = (*xHash)(pKey, nKey); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); - elem = fts3FindElementByHash(pH,pKey,nKey,h); - if( elem ){ - void *old_data = elem->data; - if( data==0 ){ - fts3RemoveElementByHash(pH,elem,h); - }else{ - elem->data = data; - } - return old_data; - } - if( data==0 ) return 0; - if( (pH->htsize==0 && fts3Rehash(pH,8)) - || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2)) - ){ - pH->count = 0; - return data; - } - assert( pH->htsize>0 ); - new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) ); - if( new_elem==0 ) return data; - if( pH->copyKey && pKey!=0 ){ - new_elem->pKey = fts3HashMalloc( nKey ); - if( new_elem->pKey==0 ){ - fts3HashFree(new_elem); - return data; - } - memcpy((void*)new_elem->pKey, pKey, nKey); - }else{ - new_elem->pKey = (void*)pKey; - } - new_elem->nKey = nKey; - pH->count++; - assert( pH->htsize>0 ); - assert( (pH->htsize & (pH->htsize-1))==0 ); - h = hraw & (pH->htsize-1); - fts3HashInsertElement(pH, &pH->ht[h], new_elem); - new_elem->data = data; - return 0; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_hash.c *******************************************/ -/************** Begin file fts3_porter.c *************************************/ -/* -** 2006 September 30 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** Implementation of the full-text-search tokenizer that implements -** a Porter stemmer. -*/ - -/* -** The code in this file is only compiled if: -** -** * The FTS3 module is being built as an extension -** (in which case SQLITE_CORE is not defined), or -** -** * The FTS3 module is being built into the core of -** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* #include "fts3_tokenizer.h" */ - -/* -** Class derived from sqlite3_tokenizer -*/ -typedef struct porter_tokenizer { - sqlite3_tokenizer base; /* Base class */ -} porter_tokenizer; - -/* -** Class derived from sqlite3_tokenizer_cursor -*/ -typedef struct porter_tokenizer_cursor { - sqlite3_tokenizer_cursor base; - const char *zInput; /* input we are tokenizing */ - int nInput; /* size of the input */ - int iOffset; /* current position in zInput */ - int iToken; /* index of next token to be returned */ - char *zToken; /* storage for current token */ - int nAllocated; /* space allocated to zToken buffer */ -} porter_tokenizer_cursor; - - -/* -** Create a new tokenizer instance. -*/ -static int porterCreate( - int argc, const char * const *argv, - sqlite3_tokenizer **ppTokenizer -){ - porter_tokenizer *t; - - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - - t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); - if( t==NULL ) return SQLITE_NOMEM; - memset(t, 0, sizeof(*t)); - *ppTokenizer = &t->base; - return SQLITE_OK; -} - -/* -** Destroy a tokenizer -*/ -static int porterDestroy(sqlite3_tokenizer *pTokenizer){ - sqlite3_free(pTokenizer); - return SQLITE_OK; -} - -/* -** Prepare to begin tokenizing a particular string. The input -** string to be tokenized is zInput[0..nInput-1]. A cursor -** used to incrementally tokenize this string is returned in -** *ppCursor. -*/ -static int porterOpen( - sqlite3_tokenizer *pTokenizer, /* The tokenizer */ - const char *zInput, int nInput, /* String to be tokenized */ - sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ -){ - porter_tokenizer_cursor *c; - - UNUSED_PARAMETER(pTokenizer); - - c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); - if( c==NULL ) return SQLITE_NOMEM; - - c->zInput = zInput; - if( zInput==0 ){ - c->nInput = 0; - }else if( nInput<0 ){ - c->nInput = (int)strlen(zInput); - }else{ - c->nInput = nInput; - } - c->iOffset = 0; /* start tokenizing at the beginning */ - c->iToken = 0; - c->zToken = NULL; /* no space allocated, yet. */ - c->nAllocated = 0; - - *ppCursor = &c->base; - return SQLITE_OK; -} - -/* -** Close a tokenization cursor previously opened by a call to -** porterOpen() above. -*/ -static int porterClose(sqlite3_tokenizer_cursor *pCursor){ - porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; - sqlite3_free(c->zToken); - sqlite3_free(c); - return SQLITE_OK; -} -/* -** Vowel or consonant -*/ -static const char cType[] = { - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 2, 1 -}; - -/* -** isConsonant() and isVowel() determine if their first character in -** the string they point to is a consonant or a vowel, according -** to Porter ruls. -** -** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. -** 'Y' is a consonant unless it follows another consonant, -** in which case it is a vowel. -** -** In these routine, the letters are in reverse order. So the 'y' rule -** is that 'y' is a consonant unless it is followed by another -** consonent. -*/ -static int isVowel(const char*); -static int isConsonant(const char *z){ - int j; - char x = *z; - if( x==0 ) return 0; - assert( x>='a' && x<='z' ); - j = cType[x-'a']; - if( j<2 ) return j; - return z[1]==0 || isVowel(z + 1); -} -static int isVowel(const char *z){ - int j; - char x = *z; - if( x==0 ) return 0; - assert( x>='a' && x<='z' ); - j = cType[x-'a']; - if( j<2 ) return 1-j; - return isConsonant(z + 1); -} - -/* -** Let any sequence of one or more vowels be represented by V and let -** C be sequence of one or more consonants. Then every word can be -** represented as: -** -** [C] (VC){m} [V] -** -** In prose: A word is an optional consonant followed by zero or -** vowel-consonant pairs followed by an optional vowel. "m" is the -** number of vowel consonant pairs. This routine computes the value -** of m for the first i bytes of a word. -** -** Return true if the m-value for z is 1 or more. In other words, -** return true if z contains at least one vowel that is followed -** by a consonant. -** -** In this routine z[] is in reverse order. So we are really looking -** for an instance of a consonant followed by a vowel. -*/ -static int m_gt_0(const char *z){ - while( isVowel(z) ){ z++; } - if( *z==0 ) return 0; - while( isConsonant(z) ){ z++; } - return *z!=0; -} - -/* Like mgt0 above except we are looking for a value of m which is -** exactly 1 -*/ -static int m_eq_1(const char *z){ - while( isVowel(z) ){ z++; } - if( *z==0 ) return 0; - while( isConsonant(z) ){ z++; } - if( *z==0 ) return 0; - while( isVowel(z) ){ z++; } - if( *z==0 ) return 1; - while( isConsonant(z) ){ z++; } - return *z==0; -} - -/* Like mgt0 above except we are looking for a value of m>1 instead -** or m>0 -*/ -static int m_gt_1(const char *z){ - while( isVowel(z) ){ z++; } - if( *z==0 ) return 0; - while( isConsonant(z) ){ z++; } - if( *z==0 ) return 0; - while( isVowel(z) ){ z++; } - if( *z==0 ) return 0; - while( isConsonant(z) ){ z++; } - return *z!=0; -} - -/* -** Return TRUE if there is a vowel anywhere within z[0..n-1] -*/ -static int hasVowel(const char *z){ - while( isConsonant(z) ){ z++; } - return *z!=0; -} - -/* -** Return TRUE if the word ends in a double consonant. -** -** The text is reversed here. So we are really looking at -** the first two characters of z[]. -*/ -static int doubleConsonant(const char *z){ - return isConsonant(z) && z[0]==z[1]; -} - -/* -** Return TRUE if the word ends with three letters which -** are consonant-vowel-consonent and where the final consonant -** is not 'w', 'x', or 'y'. -** -** The word is reversed here. So we are really checking the -** first three letters and the first one cannot be in [wxy]. -*/ -static int star_oh(const char *z){ - return - isConsonant(z) && - z[0]!='w' && z[0]!='x' && z[0]!='y' && - isVowel(z+1) && - isConsonant(z+2); -} - -/* -** If the word ends with zFrom and xCond() is true for the stem -** of the word that preceeds the zFrom ending, then change the -** ending to zTo. -** -** The input word *pz and zFrom are both in reverse order. zTo -** is in normal order. -** -** Return TRUE if zFrom matches. Return FALSE if zFrom does not -** match. Not that TRUE is returned even if xCond() fails and -** no substitution occurs. -*/ -static int stem( - char **pz, /* The word being stemmed (Reversed) */ - const char *zFrom, /* If the ending matches this... (Reversed) */ - const char *zTo, /* ... change the ending to this (not reversed) */ - int (*xCond)(const char*) /* Condition that must be true */ -){ - char *z = *pz; - while( *zFrom && *zFrom==*z ){ z++; zFrom++; } - if( *zFrom!=0 ) return 0; - if( xCond && !xCond(z) ) return 1; - while( *zTo ){ - *(--z) = *(zTo++); - } - *pz = z; - return 1; -} - -/* -** This is the fallback stemmer used when the porter stemmer is -** inappropriate. The input word is copied into the output with -** US-ASCII case folding. If the input word is too long (more -** than 20 bytes if it contains no digits or more than 6 bytes if -** it contains digits) then word is truncated to 20 or 6 bytes -** by taking 10 or 3 bytes from the beginning and end. -*/ -static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ - int i, mx, j; - int hasDigit = 0; - for(i=0; i='A' && c<='Z' ){ - zOut[i] = c - 'A' + 'a'; - }else{ - if( c>='0' && c<='9' ) hasDigit = 1; - zOut[i] = c; - } - } - mx = hasDigit ? 3 : 10; - if( nIn>mx*2 ){ - for(j=mx, i=nIn-mx; i=(int)sizeof(zReverse)-7 ){ - /* The word is too big or too small for the porter stemmer. - ** Fallback to the copy stemmer */ - copy_stemmer(zIn, nIn, zOut, pnOut); - return; - } - for(i=0, j=sizeof(zReverse)-6; i='A' && c<='Z' ){ - zReverse[j] = c + 'a' - 'A'; - }else if( c>='a' && c<='z' ){ - zReverse[j] = c; - }else{ - /* The use of a character not in [a-zA-Z] means that we fallback - ** to the copy stemmer */ - copy_stemmer(zIn, nIn, zOut, pnOut); - return; - } - } - memset(&zReverse[sizeof(zReverse)-5], 0, 5); - z = &zReverse[j+1]; - - - /* Step 1a */ - if( z[0]=='s' ){ - if( - !stem(&z, "sess", "ss", 0) && - !stem(&z, "sei", "i", 0) && - !stem(&z, "ss", "ss", 0) - ){ - z++; - } - } - - /* Step 1b */ - z2 = z; - if( stem(&z, "dee", "ee", m_gt_0) ){ - /* Do nothing. The work was all in the test */ - }else if( - (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) - && z!=z2 - ){ - if( stem(&z, "ta", "ate", 0) || - stem(&z, "lb", "ble", 0) || - stem(&z, "zi", "ize", 0) ){ - /* Do nothing. The work was all in the test */ - }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){ - z++; - }else if( m_eq_1(z) && star_oh(z) ){ - *(--z) = 'e'; - } - } - - /* Step 1c */ - if( z[0]=='y' && hasVowel(z+1) ){ - z[0] = 'i'; - } - - /* Step 2 */ - switch( z[1] ){ - case 'a': - if( !stem(&z, "lanoita", "ate", m_gt_0) ){ - stem(&z, "lanoit", "tion", m_gt_0); - } - break; - case 'c': - if( !stem(&z, "icne", "ence", m_gt_0) ){ - stem(&z, "icna", "ance", m_gt_0); - } - break; - case 'e': - stem(&z, "rezi", "ize", m_gt_0); - break; - case 'g': - stem(&z, "igol", "log", m_gt_0); - break; - case 'l': - if( !stem(&z, "ilb", "ble", m_gt_0) - && !stem(&z, "illa", "al", m_gt_0) - && !stem(&z, "iltne", "ent", m_gt_0) - && !stem(&z, "ile", "e", m_gt_0) - ){ - stem(&z, "ilsuo", "ous", m_gt_0); - } - break; - case 'o': - if( !stem(&z, "noitazi", "ize", m_gt_0) - && !stem(&z, "noita", "ate", m_gt_0) - ){ - stem(&z, "rota", "ate", m_gt_0); - } - break; - case 's': - if( !stem(&z, "msila", "al", m_gt_0) - && !stem(&z, "ssenevi", "ive", m_gt_0) - && !stem(&z, "ssenluf", "ful", m_gt_0) - ){ - stem(&z, "ssensuo", "ous", m_gt_0); - } - break; - case 't': - if( !stem(&z, "itila", "al", m_gt_0) - && !stem(&z, "itivi", "ive", m_gt_0) - ){ - stem(&z, "itilib", "ble", m_gt_0); - } - break; - } - - /* Step 3 */ - switch( z[0] ){ - case 'e': - if( !stem(&z, "etaci", "ic", m_gt_0) - && !stem(&z, "evita", "", m_gt_0) - ){ - stem(&z, "ezila", "al", m_gt_0); - } - break; - case 'i': - stem(&z, "itici", "ic", m_gt_0); - break; - case 'l': - if( !stem(&z, "laci", "ic", m_gt_0) ){ - stem(&z, "luf", "", m_gt_0); - } - break; - case 's': - stem(&z, "ssen", "", m_gt_0); - break; - } - - /* Step 4 */ - switch( z[1] ){ - case 'a': - if( z[0]=='l' && m_gt_1(z+2) ){ - z += 2; - } - break; - case 'c': - if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){ - z += 4; - } - break; - case 'e': - if( z[0]=='r' && m_gt_1(z+2) ){ - z += 2; - } - break; - case 'i': - if( z[0]=='c' && m_gt_1(z+2) ){ - z += 2; - } - break; - case 'l': - if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){ - z += 4; - } - break; - case 'n': - if( z[0]=='t' ){ - if( z[2]=='a' ){ - if( m_gt_1(z+3) ){ - z += 3; - } - }else if( z[2]=='e' ){ - if( !stem(&z, "tneme", "", m_gt_1) - && !stem(&z, "tnem", "", m_gt_1) - ){ - stem(&z, "tne", "", m_gt_1); - } - } - } - break; - case 'o': - if( z[0]=='u' ){ - if( m_gt_1(z+2) ){ - z += 2; - } - }else if( z[3]=='s' || z[3]=='t' ){ - stem(&z, "noi", "", m_gt_1); - } - break; - case 's': - if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){ - z += 3; - } - break; - case 't': - if( !stem(&z, "eta", "", m_gt_1) ){ - stem(&z, "iti", "", m_gt_1); - } - break; - case 'u': - if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ - z += 3; - } - break; - case 'v': - case 'z': - if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){ - z += 3; - } - break; - } - - /* Step 5a */ - if( z[0]=='e' ){ - if( m_gt_1(z+1) ){ - z++; - }else if( m_eq_1(z+1) && !star_oh(z+1) ){ - z++; - } - } - - /* Step 5b */ - if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){ - z++; - } - - /* z[] is now the stemmed word in reverse order. Flip it back - ** around into forward order and return. - */ - *pnOut = i = (int)strlen(z); - zOut[i] = 0; - while( *z ){ - zOut[--i] = *(z++); - } -} - -/* -** Characters that can be part of a token. We assume any character -** whose value is greater than 0x80 (any UTF character) can be -** part of a token. In other words, delimiters all must have -** values of 0x7f or lower. -*/ -static const char porterIdChar[] = { -/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ -}; -#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30])) - -/* -** Extract the next token from a tokenization cursor. The cursor must -** have been opened by a prior call to porterOpen(). -*/ -static int porterNext( - sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ - const char **pzToken, /* OUT: *pzToken is the token text */ - int *pnBytes, /* OUT: Number of bytes in token */ - int *piStartOffset, /* OUT: Starting offset of token */ - int *piEndOffset, /* OUT: Ending offset of token */ - int *piPosition /* OUT: Position integer of token */ -){ - porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; - const char *z = c->zInput; - - while( c->iOffsetnInput ){ - int iStartOffset, ch; - - /* Scan past delimiter characters */ - while( c->iOffsetnInput && isDelim(z[c->iOffset]) ){ - c->iOffset++; - } - - /* Count non-delimiter characters. */ - iStartOffset = c->iOffset; - while( c->iOffsetnInput && !isDelim(z[c->iOffset]) ){ - c->iOffset++; - } - - if( c->iOffset>iStartOffset ){ - int n = c->iOffset-iStartOffset; - if( n>c->nAllocated ){ - char *pNew; - c->nAllocated = n+20; - pNew = sqlite3_realloc(c->zToken, c->nAllocated); - if( !pNew ) return SQLITE_NOMEM; - c->zToken = pNew; - } - porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); - *pzToken = c->zToken; - *piStartOffset = iStartOffset; - *piEndOffset = c->iOffset; - *piPosition = c->iToken++; - return SQLITE_OK; - } - } - return SQLITE_DONE; -} - -/* -** The set of routines that implement the porter-stemmer tokenizer -*/ -static const sqlite3_tokenizer_module porterTokenizerModule = { - 0, - porterCreate, - porterDestroy, - porterOpen, - porterClose, - porterNext, - 0 -}; - -/* -** Allocate a new porter tokenizer. Return a pointer to the new -** tokenizer in *ppModule -*/ -SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( - sqlite3_tokenizer_module const**ppModule -){ - *ppModule = &porterTokenizerModule; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_porter.c *****************************************/ -/************** Begin file fts3_tokenizer.c **********************************/ -/* -** 2007 June 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This is part of an SQLite module implementing full-text search. -** This particular file implements the generic tokenizer interface. -*/ - -/* -** The code in this file is only compiled if: -** -** * The FTS3 module is being built as an extension -** (in which case SQLITE_CORE is not defined), or -** -** * The FTS3 module is being built into the core of -** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ - -/* -** Return true if the two-argument version of fts3_tokenizer() -** has been activated via a prior call to sqlite3_db_config(db, -** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); -*/ -static int fts3TokenizerEnabled(sqlite3_context *context){ - sqlite3 *db = sqlite3_context_db_handle(context); - int isEnabled = 0; - sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled); - return isEnabled; -} - -/* -** Implementation of the SQL scalar function for accessing the underlying -** hash table. This function may be called as follows: -** -** SELECT (); -** SELECT (, ); -** -** where is the name passed as the second argument -** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). -** -** If the argument is specified, it must be a blob value -** containing a pointer to be stored as the hash data corresponding -** to the string . If is not specified, then -** the string must already exist in the has table. Otherwise, -** an error is returned. -** -** Whether or not the argument is specified, the value returned -** is a blob containing the pointer stored as the hash data corresponding -** to string (after the hash-table is updated, if applicable). -*/ -static void fts3TokenizerFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - Fts3Hash *pHash; - void *pPtr = 0; - const unsigned char *zName; - int nName; - - assert( argc==1 || argc==2 ); - - pHash = (Fts3Hash *)sqlite3_user_data(context); - - zName = sqlite3_value_text(argv[0]); - nName = sqlite3_value_bytes(argv[0])+1; - - if( argc==2 ){ - if( fts3TokenizerEnabled(context) ){ - void *pOld; - int n = sqlite3_value_bytes(argv[1]); - if( zName==0 || n!=sizeof(pPtr) ){ - sqlite3_result_error(context, "argument type mismatch", -1); - return; - } - pPtr = *(void **)sqlite3_value_blob(argv[1]); - pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); - if( pOld==pPtr ){ - sqlite3_result_error(context, "out of memory", -1); - } - }else{ - sqlite3_result_error(context, "fts3tokenize disabled", -1); - return; - } - }else{ - if( zName ){ - pPtr = sqlite3Fts3HashFind(pHash, zName, nName); - } - if( !pPtr ){ - char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); - return; - } - } - sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); -} - -SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ - static const char isFtsIdChar[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ - 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ - }; - return (c&0x80 || isFtsIdChar[(int)(c)]); -} - -SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ - const char *z1; - const char *z2 = 0; - - /* Find the start of the next token. */ - z1 = zStr; - while( z2==0 ){ - char c = *z1; - switch( c ){ - case '\0': return 0; /* No more tokens here */ - case '\'': - case '"': - case '`': { - z2 = z1; - while( *++z2 && (*z2!=c || *++z2==c) ); - break; - } - case '[': - z2 = &z1[1]; - while( *z2 && z2[0]!=']' ) z2++; - if( *z2 ) z2++; - break; - - default: - if( sqlite3Fts3IsIdChar(*z1) ){ - z2 = &z1[1]; - while( sqlite3Fts3IsIdChar(*z2) ) z2++; - }else{ - z1++; - } - } - } - - *pn = (int)(z2-z1); - return z1; -} - -SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( - Fts3Hash *pHash, /* Tokenizer hash table */ - const char *zArg, /* Tokenizer name */ - sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ - char **pzErr /* OUT: Set to malloced error message */ -){ - int rc; - char *z = (char *)zArg; - int n = 0; - char *zCopy; - char *zEnd; /* Pointer to nul-term of zCopy */ - sqlite3_tokenizer_module *m; - - zCopy = sqlite3_mprintf("%s", zArg); - if( !zCopy ) return SQLITE_NOMEM; - zEnd = &zCopy[strlen(zCopy)]; - - z = (char *)sqlite3Fts3NextToken(zCopy, &n); - if( z==0 ){ - assert( n==0 ); - z = zCopy; - } - z[n] = '\0'; - sqlite3Fts3Dequote(z); - - m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); - if( !m ){ - sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); - rc = SQLITE_ERROR; - }else{ - char const **aArg = 0; - int iArg = 0; - z = &z[n+1]; - while( zxCreate(iArg, aArg, ppTok); - assert( rc!=SQLITE_OK || *ppTok ); - if( rc!=SQLITE_OK ){ - sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); - }else{ - (*ppTok)->pModule = m; - } - sqlite3_free((void *)aArg); - } - - sqlite3_free(zCopy); - return rc; -} - - -#ifdef SQLITE_TEST - -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif -/* #include */ - -/* -** Implementation of a special SQL scalar function for testing tokenizers -** designed to be used in concert with the Tcl testing framework. This -** function must be called with two or more arguments: -** -** SELECT (, ..., ); -** -** where is the name passed as the second argument -** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') -** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). -** -** The return value is a string that may be interpreted as a Tcl -** list. For each token in the , three elements are -** added to the returned list. The first is the token position, the -** second is the token text (folded, stemmed, etc.) and the third is the -** substring of associated with the token. For example, -** using the built-in "simple" tokenizer: -** -** SELECT fts_tokenizer_test('simple', 'I don't see how'); -** -** will return the string: -** -** "{0 i I 1 dont don't 2 see see 3 how how}" -** -*/ -static void testFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - Fts3Hash *pHash; - sqlite3_tokenizer_module *p; - sqlite3_tokenizer *pTokenizer = 0; - sqlite3_tokenizer_cursor *pCsr = 0; - - const char *zErr = 0; - - const char *zName; - int nName; - const char *zInput; - int nInput; - - const char *azArg[64]; - - const char *zToken; - int nToken = 0; - int iStart = 0; - int iEnd = 0; - int iPos = 0; - int i; - - Tcl_Obj *pRet; - - if( argc<2 ){ - sqlite3_result_error(context, "insufficient arguments", -1); - return; - } - - nName = sqlite3_value_bytes(argv[0]); - zName = (const char *)sqlite3_value_text(argv[0]); - nInput = sqlite3_value_bytes(argv[argc-1]); - zInput = (const char *)sqlite3_value_text(argv[argc-1]); - - pHash = (Fts3Hash *)sqlite3_user_data(context); - p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); - - if( !p ){ - char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); - sqlite3_result_error(context, zErr2, -1); - sqlite3_free(zErr2); - return; - } - - pRet = Tcl_NewObj(); - Tcl_IncrRefCount(pRet); - - for(i=1; ixCreate(argc-2, azArg, &pTokenizer) ){ - zErr = "error in xCreate()"; - goto finish; - } - pTokenizer->pModule = p; - if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ - zErr = "error in xOpen()"; - goto finish; - } - - while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ - Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); - Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); - zToken = &zInput[iStart]; - nToken = iEnd-iStart; - Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); - } - - if( SQLITE_OK!=p->xClose(pCsr) ){ - zErr = "error in xClose()"; - goto finish; - } - if( SQLITE_OK!=p->xDestroy(pTokenizer) ){ - zErr = "error in xDestroy()"; - goto finish; - } - -finish: - if( zErr ){ - sqlite3_result_error(context, zErr, -1); - }else{ - sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); - } - Tcl_DecrRefCount(pRet); -} - -static -int registerTokenizer( - sqlite3 *db, - char *zName, - const sqlite3_tokenizer_module *p -){ - int rc; - sqlite3_stmt *pStmt; - const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; - - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); - sqlite3_step(pStmt); - - return sqlite3_finalize(pStmt); -} - - -static -int queryTokenizer( - sqlite3 *db, - char *zName, - const sqlite3_tokenizer_module **pp -){ - int rc; - sqlite3_stmt *pStmt; - const char zSql[] = "SELECT fts3_tokenizer(?)"; - - *pp = 0; - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ - memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); - } - } - - return sqlite3_finalize(pStmt); -} - -SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); - -/* -** Implementation of the scalar function fts3_tokenizer_internal_test(). -** This function is used for testing only, it is not included in the -** build unless SQLITE_TEST is defined. -** -** The purpose of this is to test that the fts3_tokenizer() function -** can be used as designed by the C-code in the queryTokenizer and -** registerTokenizer() functions above. These two functions are repeated -** in the README.tokenizer file as an example, so it is important to -** test them. -** -** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar -** function with no arguments. An assert() will fail if a problem is -** detected. i.e.: -** -** SELECT fts3_tokenizer_internal_test(); -** -*/ -static void intTestFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - int rc; - const sqlite3_tokenizer_module *p1; - const sqlite3_tokenizer_module *p2; - sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); - - UNUSED_PARAMETER(argc); - UNUSED_PARAMETER(argv); - - /* Test the query function */ - sqlite3Fts3SimpleTokenizerModule(&p1); - rc = queryTokenizer(db, "simple", &p2); - assert( rc==SQLITE_OK ); - assert( p1==p2 ); - rc = queryTokenizer(db, "nosuchtokenizer", &p2); - assert( rc==SQLITE_ERROR ); - assert( p2==0 ); - assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); - - /* Test the storage function */ - if( fts3TokenizerEnabled(context) ){ - rc = registerTokenizer(db, "nosuchtokenizer", p1); - assert( rc==SQLITE_OK ); - rc = queryTokenizer(db, "nosuchtokenizer", &p2); - assert( rc==SQLITE_OK ); - assert( p2==p1 ); - } - - sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); -} - -#endif - -/* -** Set up SQL objects in database db used to access the contents of -** the hash table pointed to by argument pHash. The hash table must -** been initialized to use string keys, and to take a private copy -** of the key when a value is inserted. i.e. by a call similar to: -** -** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); -** -** This function adds a scalar function (see header comment above -** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is -** defined at compilation time, a temporary virtual table (see header -** comment above struct HashTableVtab) to the database schema. Both -** provide read/write access to the contents of *pHash. -** -** The third argument to this function, zName, is used as the name -** of both the scalar and, if created, the virtual table. -*/ -SQLITE_PRIVATE int sqlite3Fts3InitHashTable( - sqlite3 *db, - Fts3Hash *pHash, - const char *zName -){ - int rc = SQLITE_OK; - void *p = (void *)pHash; - const int any = SQLITE_ANY; - -#ifdef SQLITE_TEST - char *zTest = 0; - char *zTest2 = 0; - void *pdb = (void *)db; - zTest = sqlite3_mprintf("%s_test", zName); - zTest2 = sqlite3_mprintf("%s_internal_test", zName); - if( !zTest || !zTest2 ){ - rc = SQLITE_NOMEM; - } -#endif - - if( SQLITE_OK==rc ){ - rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0); - } - if( SQLITE_OK==rc ){ - rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0); - } -#ifdef SQLITE_TEST - if( SQLITE_OK==rc ){ - rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); - } - if( SQLITE_OK==rc ){ - rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); - } -#endif - -#ifdef SQLITE_TEST - sqlite3_free(zTest); - sqlite3_free(zTest2); -#endif - - return rc; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_tokenizer.c **************************************/ -/************** Begin file fts3_tokenizer1.c *********************************/ -/* -** 2006 Oct 10 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** Implementation of the "simple" full-text-search tokenizer. -*/ - -/* -** The code in this file is only compiled if: -** -** * The FTS3 module is being built as an extension -** (in which case SQLITE_CORE is not defined), or -** -** * The FTS3 module is being built into the core of -** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* #include "fts3_tokenizer.h" */ - -typedef struct simple_tokenizer { - sqlite3_tokenizer base; - char delim[128]; /* flag ASCII delimiters */ -} simple_tokenizer; - -typedef struct simple_tokenizer_cursor { - sqlite3_tokenizer_cursor base; - const char *pInput; /* input we are tokenizing */ - int nBytes; /* size of the input */ - int iOffset; /* current position in pInput */ - int iToken; /* index of next token to be returned */ - char *pToken; /* storage for current token */ - int nTokenAllocated; /* space allocated to zToken buffer */ -} simple_tokenizer_cursor; - - -static int simpleDelim(simple_tokenizer *t, unsigned char c){ - return c<0x80 && t->delim[c]; -} -static int fts3_isalnum(int x){ - return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z'); -} - -/* -** Create a new tokenizer instance. -*/ -static int simpleCreate( - int argc, const char * const *argv, - sqlite3_tokenizer **ppTokenizer -){ - simple_tokenizer *t; - - t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); - if( t==NULL ) return SQLITE_NOMEM; - memset(t, 0, sizeof(*t)); - - /* TODO(shess) Delimiters need to remain the same from run to run, - ** else we need to reindex. One solution would be a meta-table to - ** track such information in the database, then we'd only want this - ** information on the initial create. - */ - if( argc>1 ){ - int i, n = (int)strlen(argv[1]); - for(i=0; i=0x80 ){ - sqlite3_free(t); - return SQLITE_ERROR; - } - t->delim[ch] = 1; - } - } else { - /* Mark non-alphanumeric ASCII characters as delimiters */ - int i; - for(i=1; i<0x80; i++){ - t->delim[i] = !fts3_isalnum(i) ? -1 : 0; - } - } - - *ppTokenizer = &t->base; - return SQLITE_OK; -} - -/* -** Destroy a tokenizer -*/ -static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ - sqlite3_free(pTokenizer); - return SQLITE_OK; -} - -/* -** Prepare to begin tokenizing a particular string. The input -** string to be tokenized is pInput[0..nBytes-1]. A cursor -** used to incrementally tokenize this string is returned in -** *ppCursor. -*/ -static int simpleOpen( - sqlite3_tokenizer *pTokenizer, /* The tokenizer */ - const char *pInput, int nBytes, /* String to be tokenized */ - sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ -){ - simple_tokenizer_cursor *c; - - UNUSED_PARAMETER(pTokenizer); - - c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); - if( c==NULL ) return SQLITE_NOMEM; - - c->pInput = pInput; - if( pInput==0 ){ - c->nBytes = 0; - }else if( nBytes<0 ){ - c->nBytes = (int)strlen(pInput); - }else{ - c->nBytes = nBytes; - } - c->iOffset = 0; /* start tokenizing at the beginning */ - c->iToken = 0; - c->pToken = NULL; /* no space allocated, yet. */ - c->nTokenAllocated = 0; - - *ppCursor = &c->base; - return SQLITE_OK; -} - -/* -** Close a tokenization cursor previously opened by a call to -** simpleOpen() above. -*/ -static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ - simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; - sqlite3_free(c->pToken); - sqlite3_free(c); - return SQLITE_OK; -} - -/* -** Extract the next token from a tokenization cursor. The cursor must -** have been opened by a prior call to simpleOpen(). -*/ -static int simpleNext( - sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ - const char **ppToken, /* OUT: *ppToken is the token text */ - int *pnBytes, /* OUT: Number of bytes in token */ - int *piStartOffset, /* OUT: Starting offset of token */ - int *piEndOffset, /* OUT: Ending offset of token */ - int *piPosition /* OUT: Position integer of token */ -){ - simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; - simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer; - unsigned char *p = (unsigned char *)c->pInput; - - while( c->iOffsetnBytes ){ - int iStartOffset; - - /* Scan past delimiter characters */ - while( c->iOffsetnBytes && simpleDelim(t, p[c->iOffset]) ){ - c->iOffset++; - } - - /* Count non-delimiter characters. */ - iStartOffset = c->iOffset; - while( c->iOffsetnBytes && !simpleDelim(t, p[c->iOffset]) ){ - c->iOffset++; - } - - if( c->iOffset>iStartOffset ){ - int i, n = c->iOffset-iStartOffset; - if( n>c->nTokenAllocated ){ - char *pNew; - c->nTokenAllocated = n+20; - pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); - if( !pNew ) return SQLITE_NOMEM; - c->pToken = pNew; - } - for(i=0; ipToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch); - } - *ppToken = c->pToken; - *pnBytes = n; - *piStartOffset = iStartOffset; - *piEndOffset = c->iOffset; - *piPosition = c->iToken++; - - return SQLITE_OK; - } - } - return SQLITE_DONE; -} - -/* -** The set of routines that implement the simple tokenizer -*/ -static const sqlite3_tokenizer_module simpleTokenizerModule = { - 0, - simpleCreate, - simpleDestroy, - simpleOpen, - simpleClose, - simpleNext, - 0, -}; - -/* -** Allocate a new simple tokenizer. Return a pointer to the new -** tokenizer in *ppModule -*/ -SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( - sqlite3_tokenizer_module const**ppModule -){ - *ppModule = &simpleTokenizerModule; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_tokenizer1.c *************************************/ -/************** Begin file fts3_tokenize_vtab.c ******************************/ -/* -** 2013 Apr 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains code for the "fts3tokenize" virtual table module. -** An fts3tokenize virtual table is created as follows: -** -** CREATE VIRTUAL TABLE USING fts3tokenize( -** , , ... -** ); -** -** The table created has the following schema: -** -** CREATE TABLE (input, token, start, end, position) -** -** When queried, the query must include a WHERE clause of type: -** -** input = -** -** The virtual table module tokenizes this , using the FTS3 -** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE -** statement and returns one row for each token in the result. With -** fields set as follows: -** -** input: Always set to a copy of -** token: A token from the input. -** start: Byte offset of the token within the input . -** end: Byte offset of the byte immediately following the end of the -** token within the input string. -** pos: Token offset of token within input. -** -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ - -typedef struct Fts3tokTable Fts3tokTable; -typedef struct Fts3tokCursor Fts3tokCursor; - -/* -** Virtual table structure. -*/ -struct Fts3tokTable { - sqlite3_vtab base; /* Base class used by SQLite core */ - const sqlite3_tokenizer_module *pMod; - sqlite3_tokenizer *pTok; -}; - -/* -** Virtual table cursor structure. -*/ -struct Fts3tokCursor { - sqlite3_vtab_cursor base; /* Base class used by SQLite core */ - char *zInput; /* Input string */ - sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ - int iRowid; /* Current 'rowid' value */ - const char *zToken; /* Current 'token' value */ - int nToken; /* Size of zToken in bytes */ - int iStart; /* Current 'start' value */ - int iEnd; /* Current 'end' value */ - int iPos; /* Current 'pos' value */ -}; - -/* -** Query FTS for the tokenizer implementation named zName. -*/ -static int fts3tokQueryTokenizer( - Fts3Hash *pHash, - const char *zName, - const sqlite3_tokenizer_module **pp, - char **pzErr -){ - sqlite3_tokenizer_module *p; - int nName = (int)strlen(zName); - - p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); - if( !p ){ - sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); - return SQLITE_ERROR; - } - - *pp = p; - return SQLITE_OK; -} - -/* -** The second argument, argv[], is an array of pointers to nul-terminated -** strings. This function makes a copy of the array and strings into a -** single block of memory. It then dequotes any of the strings that appear -** to be quoted. -** -** If successful, output parameter *pazDequote is set to point at the -** array of dequoted strings and SQLITE_OK is returned. The caller is -** responsible for eventually calling sqlite3_free() to free the array -** in this case. Or, if an error occurs, an SQLite error code is returned. -** The final value of *pazDequote is undefined in this case. -*/ -static int fts3tokDequoteArray( - int argc, /* Number of elements in argv[] */ - const char * const *argv, /* Input array */ - char ***pazDequote /* Output array */ -){ - int rc = SQLITE_OK; /* Return code */ - if( argc==0 ){ - *pazDequote = 0; - }else{ - int i; - int nByte = 0; - char **azDequote; - - for(i=0; ixCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok); - } - - if( rc==SQLITE_OK ){ - pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); - if( pTab==0 ){ - rc = SQLITE_NOMEM; - } - } - - if( rc==SQLITE_OK ){ - memset(pTab, 0, sizeof(Fts3tokTable)); - pTab->pMod = pMod; - pTab->pTok = pTok; - *ppVtab = &pTab->base; - }else{ - if( pTok ){ - pMod->xDestroy(pTok); - } - } - - sqlite3_free(azDequote); - return rc; -} - -/* -** This function does the work for both the xDisconnect and xDestroy methods. -** These tables have no persistent representation of their own, so xDisconnect -** and xDestroy are identical operations. -*/ -static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ - Fts3tokTable *pTab = (Fts3tokTable *)pVtab; - - pTab->pMod->xDestroy(pTab->pTok); - sqlite3_free(pTab); - return SQLITE_OK; -} - -/* -** xBestIndex - Analyze a WHERE and ORDER BY clause. -*/ -static int fts3tokBestIndexMethod( - sqlite3_vtab *pVTab, - sqlite3_index_info *pInfo -){ - int i; - UNUSED_PARAMETER(pVTab); - - for(i=0; inConstraint; i++){ - if( pInfo->aConstraint[i].usable - && pInfo->aConstraint[i].iColumn==0 - && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ - ){ - pInfo->idxNum = 1; - pInfo->aConstraintUsage[i].argvIndex = 1; - pInfo->aConstraintUsage[i].omit = 1; - pInfo->estimatedCost = 1; - return SQLITE_OK; - } - } - - pInfo->idxNum = 0; - assert( pInfo->estimatedCost>1000000.0 ); - - return SQLITE_OK; -} - -/* -** xOpen - Open a cursor. -*/ -static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ - Fts3tokCursor *pCsr; - UNUSED_PARAMETER(pVTab); - - pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); - if( pCsr==0 ){ - return SQLITE_NOMEM; - } - memset(pCsr, 0, sizeof(Fts3tokCursor)); - - *ppCsr = (sqlite3_vtab_cursor *)pCsr; - return SQLITE_OK; -} - -/* -** Reset the tokenizer cursor passed as the only argument. As if it had -** just been returned by fts3tokOpenMethod(). -*/ -static void fts3tokResetCursor(Fts3tokCursor *pCsr){ - if( pCsr->pCsr ){ - Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab); - pTab->pMod->xClose(pCsr->pCsr); - pCsr->pCsr = 0; - } - sqlite3_free(pCsr->zInput); - pCsr->zInput = 0; - pCsr->zToken = 0; - pCsr->nToken = 0; - pCsr->iStart = 0; - pCsr->iEnd = 0; - pCsr->iPos = 0; - pCsr->iRowid = 0; -} - -/* -** xClose - Close a cursor. -*/ -static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - - fts3tokResetCursor(pCsr); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** xNext - Advance the cursor to the next row, if any. -*/ -static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); - int rc; /* Return code */ - - pCsr->iRowid++; - rc = pTab->pMod->xNext(pCsr->pCsr, - &pCsr->zToken, &pCsr->nToken, - &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos - ); - - if( rc!=SQLITE_OK ){ - fts3tokResetCursor(pCsr); - if( rc==SQLITE_DONE ) rc = SQLITE_OK; - } - - return rc; -} - -/* -** xFilter - Initialize a cursor to point at the start of its data. -*/ -static int fts3tokFilterMethod( - sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ - int idxNum, /* Strategy index */ - const char *idxStr, /* Unused */ - int nVal, /* Number of elements in apVal */ - sqlite3_value **apVal /* Arguments for the indexing scheme */ -){ - int rc = SQLITE_ERROR; - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); - UNUSED_PARAMETER(idxStr); - UNUSED_PARAMETER(nVal); - - fts3tokResetCursor(pCsr); - if( idxNum==1 ){ - const char *zByte = (const char *)sqlite3_value_text(apVal[0]); - int nByte = sqlite3_value_bytes(apVal[0]); - pCsr->zInput = sqlite3_malloc(nByte+1); - if( pCsr->zInput==0 ){ - rc = SQLITE_NOMEM; - }else{ - memcpy(pCsr->zInput, zByte, nByte); - pCsr->zInput[nByte] = 0; - rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); - if( rc==SQLITE_OK ){ - pCsr->pCsr->pTokenizer = pTab->pTok; - } - } - } - - if( rc!=SQLITE_OK ) return rc; - return fts3tokNextMethod(pCursor); -} - -/* -** xEof - Return true if the cursor is at EOF, or false otherwise. -*/ -static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - return (pCsr->zToken==0); -} - -/* -** xColumn - Return a column value. -*/ -static int fts3tokColumnMethod( - sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ - int iCol /* Index of column to read value from */ -){ - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - - /* CREATE TABLE x(input, token, start, end, position) */ - switch( iCol ){ - case 0: - sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); - break; - case 1: - sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); - break; - case 2: - sqlite3_result_int(pCtx, pCsr->iStart); - break; - case 3: - sqlite3_result_int(pCtx, pCsr->iEnd); - break; - default: - assert( iCol==4 ); - sqlite3_result_int(pCtx, pCsr->iPos); - break; - } - return SQLITE_OK; -} - -/* -** xRowid - Return the current rowid for the cursor. -*/ -static int fts3tokRowidMethod( - sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - sqlite_int64 *pRowid /* OUT: Rowid value */ -){ - Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - *pRowid = (sqlite3_int64)pCsr->iRowid; - return SQLITE_OK; -} - -/* -** Register the fts3tok module with database connection db. Return SQLITE_OK -** if successful or an error code if sqlite3_create_module() fails. -*/ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ - static const sqlite3_module fts3tok_module = { - 0, /* iVersion */ - fts3tokConnectMethod, /* xCreate */ - fts3tokConnectMethod, /* xConnect */ - fts3tokBestIndexMethod, /* xBestIndex */ - fts3tokDisconnectMethod, /* xDisconnect */ - fts3tokDisconnectMethod, /* xDestroy */ - fts3tokOpenMethod, /* xOpen */ - fts3tokCloseMethod, /* xClose */ - fts3tokFilterMethod, /* xFilter */ - fts3tokNextMethod, /* xNext */ - fts3tokEofMethod, /* xEof */ - fts3tokColumnMethod, /* xColumn */ - fts3tokRowidMethod, /* xRowid */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindFunction */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ - }; - int rc; /* Return code */ - - rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); - return rc; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_tokenize_vtab.c **********************************/ -/************** Begin file fts3_write.c **************************************/ -/* -** 2009 Oct 23 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file is part of the SQLite FTS3 extension module. Specifically, -** this file contains code to insert, update and delete rows from FTS3 -** tables. It also contains code to merge FTS3 b-tree segments. Some -** of the sub-routines used to merge segments are also used by the query -** code in fts3.c. -*/ - -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ -/* #include */ - - -#define FTS_MAX_APPENDABLE_HEIGHT 16 - -/* -** When full-text index nodes are loaded from disk, the buffer that they -** are loaded into has the following number of bytes of padding at the end -** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer -** of 920 bytes is allocated for it. -** -** This means that if we have a pointer into a buffer containing node data, -** it is always safe to read up to two varints from it without risking an -** overread, even if the node data is corrupted. -*/ -#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2) - -/* -** Under certain circumstances, b-tree nodes (doclists) can be loaded into -** memory incrementally instead of all at once. This can be a big performance -** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext() -** method before retrieving all query results (as may happen, for example, -** if a query has a LIMIT clause). -** -** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD -** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes. -** The code is written so that the hard lower-limit for each of these values -** is 1. Clearly such small values would be inefficient, but can be useful -** for testing purposes. -** -** If this module is built with SQLITE_TEST defined, these constants may -** be overridden at runtime for testing purposes. File fts3_test.c contains -** a Tcl interface to read and write the values. -*/ -#ifdef SQLITE_TEST -int test_fts3_node_chunksize = (4*1024); -int test_fts3_node_chunk_threshold = (4*1024)*4; -# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize -# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold -#else -# define FTS3_NODE_CHUNKSIZE (4*1024) -# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) -#endif - -/* -** The two values that may be meaningfully bound to the :1 parameter in -** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. -*/ -#define FTS_STAT_DOCTOTAL 0 -#define FTS_STAT_INCRMERGEHINT 1 -#define FTS_STAT_AUTOINCRMERGE 2 - -/* -** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic -** and incremental merge operation that takes place. This is used for -** debugging FTS only, it should not usually be turned on in production -** systems. -*/ -#ifdef FTS3_LOG_MERGES -static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ - sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); -} -#else -#define fts3LogMerge(x, y) -#endif - - -typedef struct PendingList PendingList; -typedef struct SegmentNode SegmentNode; -typedef struct SegmentWriter SegmentWriter; - -/* -** An instance of the following data structure is used to build doclists -** incrementally. See function fts3PendingListAppend() for details. -*/ -struct PendingList { - int nData; - char *aData; - int nSpace; - sqlite3_int64 iLastDocid; - sqlite3_int64 iLastCol; - sqlite3_int64 iLastPos; -}; - - -/* -** Each cursor has a (possibly empty) linked list of the following objects. -*/ -struct Fts3DeferredToken { - Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */ - int iCol; /* Column token must occur in */ - Fts3DeferredToken *pNext; /* Next in list of deferred tokens */ - PendingList *pList; /* Doclist is assembled here */ -}; - -/* -** An instance of this structure is used to iterate through the terms on -** a contiguous set of segment b-tree leaf nodes. Although the details of -** this structure are only manipulated by code in this file, opaque handles -** of type Fts3SegReader* are also used by code in fts3.c to iterate through -** terms when querying the full-text index. See functions: -** -** sqlite3Fts3SegReaderNew() -** sqlite3Fts3SegReaderFree() -** sqlite3Fts3SegReaderIterate() -** -** Methods used to manipulate Fts3SegReader structures: -** -** fts3SegReaderNext() -** fts3SegReaderFirstDocid() -** fts3SegReaderNextDocid() -*/ -struct Fts3SegReader { - int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ - u8 bLookup; /* True for a lookup only */ - u8 rootOnly; /* True for a root-only reader */ - - sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ - sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ - sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ - sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ - - char *aNode; /* Pointer to node data (or NULL) */ - int nNode; /* Size of buffer at aNode (or 0) */ - int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ - sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ - - Fts3HashElem **ppNextElem; - - /* Variables set by fts3SegReaderNext(). These may be read directly - ** by the caller. They are valid from the time SegmentReaderNew() returns - ** until SegmentReaderNext() returns something other than SQLITE_OK - ** (i.e. SQLITE_DONE). - */ - int nTerm; /* Number of bytes in current term */ - char *zTerm; /* Pointer to current term */ - int nTermAlloc; /* Allocated size of zTerm buffer */ - char *aDoclist; /* Pointer to doclist of current entry */ - int nDoclist; /* Size of doclist in current entry */ - - /* The following variables are used by fts3SegReaderNextDocid() to iterate - ** through the current doclist (aDoclist/nDoclist). - */ - char *pOffsetList; - int nOffsetList; /* For descending pending seg-readers only */ - sqlite3_int64 iDocid; -}; - -#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) -#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0) - -/* -** An instance of this structure is used to create a segment b-tree in the -** database. The internal details of this type are only accessed by the -** following functions: -** -** fts3SegWriterAdd() -** fts3SegWriterFlush() -** fts3SegWriterFree() -*/ -struct SegmentWriter { - SegmentNode *pTree; /* Pointer to interior tree structure */ - sqlite3_int64 iFirst; /* First slot in %_segments written */ - sqlite3_int64 iFree; /* Next free slot in %_segments */ - char *zTerm; /* Pointer to previous term buffer */ - int nTerm; /* Number of bytes in zTerm */ - int nMalloc; /* Size of malloc'd buffer at zMalloc */ - char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ - int nSize; /* Size of allocation at aData */ - int nData; /* Bytes of data in aData */ - char *aData; /* Pointer to block from malloc() */ - i64 nLeafData; /* Number of bytes of leaf data written */ -}; - -/* -** Type SegmentNode is used by the following three functions to create -** the interior part of the segment b+-tree structures (everything except -** the leaf nodes). These functions and type are only ever used by code -** within the fts3SegWriterXXX() family of functions described above. -** -** fts3NodeAddTerm() -** fts3NodeWrite() -** fts3NodeFree() -** -** When a b+tree is written to the database (either as a result of a merge -** or the pending-terms table being flushed), leaves are written into the -** database file as soon as they are completely populated. The interior of -** the tree is assembled in memory and written out only once all leaves have -** been populated and stored. This is Ok, as the b+-tree fanout is usually -** very large, meaning that the interior of the tree consumes relatively -** little memory. -*/ -struct SegmentNode { - SegmentNode *pParent; /* Parent node (or NULL for root node) */ - SegmentNode *pRight; /* Pointer to right-sibling */ - SegmentNode *pLeftmost; /* Pointer to left-most node of this depth */ - int nEntry; /* Number of terms written to node so far */ - char *zTerm; /* Pointer to previous term buffer */ - int nTerm; /* Number of bytes in zTerm */ - int nMalloc; /* Size of malloc'd buffer at zMalloc */ - char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ - int nData; /* Bytes of valid data so far */ - char *aData; /* Node data */ -}; - -/* -** Valid values for the second argument to fts3SqlStmt(). -*/ -#define SQL_DELETE_CONTENT 0 -#define SQL_IS_EMPTY 1 -#define SQL_DELETE_ALL_CONTENT 2 -#define SQL_DELETE_ALL_SEGMENTS 3 -#define SQL_DELETE_ALL_SEGDIR 4 -#define SQL_DELETE_ALL_DOCSIZE 5 -#define SQL_DELETE_ALL_STAT 6 -#define SQL_SELECT_CONTENT_BY_ROWID 7 -#define SQL_NEXT_SEGMENT_INDEX 8 -#define SQL_INSERT_SEGMENTS 9 -#define SQL_NEXT_SEGMENTS_ID 10 -#define SQL_INSERT_SEGDIR 11 -#define SQL_SELECT_LEVEL 12 -#define SQL_SELECT_LEVEL_RANGE 13 -#define SQL_SELECT_LEVEL_COUNT 14 -#define SQL_SELECT_SEGDIR_MAX_LEVEL 15 -#define SQL_DELETE_SEGDIR_LEVEL 16 -#define SQL_DELETE_SEGMENTS_RANGE 17 -#define SQL_CONTENT_INSERT 18 -#define SQL_DELETE_DOCSIZE 19 -#define SQL_REPLACE_DOCSIZE 20 -#define SQL_SELECT_DOCSIZE 21 -#define SQL_SELECT_STAT 22 -#define SQL_REPLACE_STAT 23 - -#define SQL_SELECT_ALL_PREFIX_LEVEL 24 -#define SQL_DELETE_ALL_TERMS_SEGDIR 25 -#define SQL_DELETE_SEGDIR_RANGE 26 -#define SQL_SELECT_ALL_LANGID 27 -#define SQL_FIND_MERGE_LEVEL 28 -#define SQL_MAX_LEAF_NODE_ESTIMATE 29 -#define SQL_DELETE_SEGDIR_ENTRY 30 -#define SQL_SHIFT_SEGDIR_ENTRY 31 -#define SQL_SELECT_SEGDIR 32 -#define SQL_CHOMP_SEGDIR 33 -#define SQL_SEGMENT_IS_APPENDABLE 34 -#define SQL_SELECT_INDEXES 35 -#define SQL_SELECT_MXLEVEL 36 - -#define SQL_SELECT_LEVEL_RANGE2 37 -#define SQL_UPDATE_LEVEL_IDX 38 -#define SQL_UPDATE_LEVEL 39 - -/* -** This function is used to obtain an SQLite prepared statement handle -** for the statement identified by the second argument. If successful, -** *pp is set to the requested statement handle and SQLITE_OK returned. -** Otherwise, an SQLite error code is returned and *pp is set to 0. -** -** If argument apVal is not NULL, then it must point to an array with -** at least as many entries as the requested statement has bound -** parameters. The values are bound to the statements parameters before -** returning. -*/ -static int fts3SqlStmt( - Fts3Table *p, /* Virtual table handle */ - int eStmt, /* One of the SQL_XXX constants above */ - sqlite3_stmt **pp, /* OUT: Statement handle */ - sqlite3_value **apVal /* Values to bind to statement */ -){ - const char *azSql[] = { -/* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?", -/* 1 */ "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)", -/* 2 */ "DELETE FROM %Q.'%q_content'", -/* 3 */ "DELETE FROM %Q.'%q_segments'", -/* 4 */ "DELETE FROM %Q.'%q_segdir'", -/* 5 */ "DELETE FROM %Q.'%q_docsize'", -/* 6 */ "DELETE FROM %Q.'%q_stat'", -/* 7 */ "SELECT %s WHERE rowid=?", -/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", -/* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", -/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", -/* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", - - /* Return segments in order from oldest to newest.*/ -/* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " - "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", -/* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " - "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" - "ORDER BY level DESC, idx ASC", - -/* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", -/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", - -/* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", -/* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", -/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", -/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", -/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", -/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", -/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", -/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", -/* 24 */ "", -/* 25 */ "", - -/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", -/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", - -/* This statement is used to determine which level to read the input from -** when performing an incremental merge. It returns the absolute level number -** of the oldest level in the db that contains at least ? segments. Or, -** if no level in the FTS index contains more than ? segments, the statement -** returns zero rows. */ -/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " - " GROUP BY level HAVING cnt>=?" - " ORDER BY (level %% 1024) ASC LIMIT 1", - -/* Estimate the upper limit on the number of leaf nodes in a new segment -** created by merging the oldest :2 segments from absolute level :1. See -** function sqlite3Fts3Incrmerge() for details. */ -/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " - " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", - -/* SQL_DELETE_SEGDIR_ENTRY -** Delete the %_segdir entry on absolute level :1 with index :2. */ -/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", - -/* SQL_SHIFT_SEGDIR_ENTRY -** Modify the idx value for the segment with idx=:3 on absolute level :2 -** to :1. */ -/* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?", - -/* SQL_SELECT_SEGDIR -** Read a single entry from the %_segdir table. The entry from absolute -** level :1 with index value :2. */ -/* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root " - "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", - -/* SQL_CHOMP_SEGDIR -** Update the start_block (:1) and root (:2) fields of the %_segdir -** entry located on absolute level :3 with index :4. */ -/* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?" - "WHERE level = ? AND idx = ?", - -/* SQL_SEGMENT_IS_APPENDABLE -** Return a single row if the segment with end_block=? is appendable. Or -** no rows otherwise. */ -/* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL", - -/* SQL_SELECT_INDEXES -** Return the list of valid segment indexes for absolute level ? */ -/* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", - -/* SQL_SELECT_MXLEVEL -** Return the largest relative level in the FTS index or indexes. */ -/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", - - /* Return segments in order from oldest to newest.*/ -/* 37 */ "SELECT level, idx, end_block " - "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " - "ORDER BY level DESC, idx ASC", - - /* Update statements used while promoting segments */ -/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " - "WHERE level=? AND idx=?", -/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" - - }; - int rc = SQLITE_OK; - sqlite3_stmt *pStmt; - - assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); - assert( eStmt=0 ); - - pStmt = p->aStmt[eStmt]; - if( !pStmt ){ - char *zSql; - if( eStmt==SQL_CONTENT_INSERT ){ - zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); - }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ - zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); - }else{ - zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); - } - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL); - sqlite3_free(zSql); - assert( rc==SQLITE_OK || pStmt==0 ); - p->aStmt[eStmt] = pStmt; - } - } - if( apVal ){ - int i; - int nParam = sqlite3_bind_parameter_count(pStmt); - for(i=0; rc==SQLITE_OK && inPendingData==0 ){ - sqlite3_stmt *pStmt; - rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_null(pStmt, 1); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - } - } - - return rc; -} - -/* -** FTS maintains a separate indexes for each language-id (a 32-bit integer). -** Within each language id, a separate index is maintained to store the -** document terms, and each configured prefix size (configured the FTS -** "prefix=" option). And each index consists of multiple levels ("relative -** levels"). -** -** All three of these values (the language id, the specific index and the -** level within the index) are encoded in 64-bit integer values stored -** in the %_segdir table on disk. This function is used to convert three -** separate component values into the single 64-bit integer value that -** can be used to query the %_segdir table. -** -** Specifically, each language-id/index combination is allocated 1024 -** 64-bit integer level values ("absolute levels"). The main terms index -** for language-id 0 is allocate values 0-1023. The first prefix index -** (if any) for language-id 0 is allocated values 1024-2047. And so on. -** Language 1 indexes are allocated immediately following language 0. -** -** So, for a system with nPrefix prefix indexes configured, the block of -** absolute levels that corresponds to language-id iLangid and index -** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). -*/ -static sqlite3_int64 getAbsoluteLevel( - Fts3Table *p, /* FTS3 table handle */ - int iLangid, /* Language id */ - int iIndex, /* Index in p->aIndex[] */ - int iLevel /* Level of segments */ -){ - sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ - assert( iLangid>=0 ); - assert( p->nIndex>0 ); - assert( iIndex>=0 && iIndexnIndex ); - - iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; - return iBase + iLevel; -} - -/* -** Set *ppStmt to a statement handle that may be used to iterate through -** all rows in the %_segdir table, from oldest to newest. If successful, -** return SQLITE_OK. If an error occurs while preparing the statement, -** return an SQLite error code. -** -** There is only ever one instance of this SQL statement compiled for -** each FTS3 table. -** -** The statement returns the following columns from the %_segdir table: -** -** 0: idx -** 1: start_block -** 2: leaves_end_block -** 3: end_block -** 4: root -*/ -SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( - Fts3Table *p, /* FTS3 table */ - int iLangid, /* Language being queried */ - int iIndex, /* Index for p->aIndex[] */ - int iLevel, /* Level to select (relative level) */ - sqlite3_stmt **ppStmt /* OUT: Compiled statement */ -){ - int rc; - sqlite3_stmt *pStmt = 0; - - assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); - assert( iLevel=0 && iIndexnIndex ); - - if( iLevel<0 ){ - /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); - sqlite3_bind_int64(pStmt, 2, - getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) - ); - } - }else{ - /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel)); - } - } - *ppStmt = pStmt; - return rc; -} - - -/* -** Append a single varint to a PendingList buffer. SQLITE_OK is returned -** if successful, or an SQLite error code otherwise. -** -** This function also serves to allocate the PendingList structure itself. -** For example, to create a new PendingList structure containing two -** varints: -** -** PendingList *p = 0; -** fts3PendingListAppendVarint(&p, 1); -** fts3PendingListAppendVarint(&p, 2); -*/ -static int fts3PendingListAppendVarint( - PendingList **pp, /* IN/OUT: Pointer to PendingList struct */ - sqlite3_int64 i /* Value to append to data */ -){ - PendingList *p = *pp; - - /* Allocate or grow the PendingList as required. */ - if( !p ){ - p = sqlite3_malloc(sizeof(*p) + 100); - if( !p ){ - return SQLITE_NOMEM; - } - p->nSpace = 100; - p->aData = (char *)&p[1]; - p->nData = 0; - } - else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ - int nNew = p->nSpace * 2; - p = sqlite3_realloc(p, sizeof(*p) + nNew); - if( !p ){ - sqlite3_free(*pp); - *pp = 0; - return SQLITE_NOMEM; - } - p->nSpace = nNew; - p->aData = (char *)&p[1]; - } - - /* Append the new serialized varint to the end of the list. */ - p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); - p->aData[p->nData] = '\0'; - *pp = p; - return SQLITE_OK; -} - -/* -** Add a docid/column/position entry to a PendingList structure. Non-zero -** is returned if the structure is sqlite3_realloced as part of adding -** the entry. Otherwise, zero. -** -** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning. -** Zero is always returned in this case. Otherwise, if no OOM error occurs, -** it is set to SQLITE_OK. -*/ -static int fts3PendingListAppend( - PendingList **pp, /* IN/OUT: PendingList structure */ - sqlite3_int64 iDocid, /* Docid for entry to add */ - sqlite3_int64 iCol, /* Column for entry to add */ - sqlite3_int64 iPos, /* Position of term for entry to add */ - int *pRc /* OUT: Return code */ -){ - PendingList *p = *pp; - int rc = SQLITE_OK; - - assert( !p || p->iLastDocid<=iDocid ); - - if( !p || p->iLastDocid!=iDocid ){ - sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0); - if( p ){ - assert( p->nDatanSpace ); - assert( p->aData[p->nData]==0 ); - p->nData++; - } - if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){ - goto pendinglistappend_out; - } - p->iLastCol = -1; - p->iLastPos = 0; - p->iLastDocid = iDocid; - } - if( iCol>0 && p->iLastCol!=iCol ){ - if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1)) - || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol)) - ){ - goto pendinglistappend_out; - } - p->iLastCol = iCol; - p->iLastPos = 0; - } - if( iCol>=0 ){ - assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) ); - rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos); - if( rc==SQLITE_OK ){ - p->iLastPos = iPos; - } - } - - pendinglistappend_out: - *pRc = rc; - if( p!=*pp ){ - *pp = p; - return 1; - } - return 0; -} - -/* -** Free a PendingList object allocated by fts3PendingListAppend(). -*/ -static void fts3PendingListDelete(PendingList *pList){ - sqlite3_free(pList); -} - -/* -** Add an entry to one of the pending-terms hash tables. -*/ -static int fts3PendingTermsAddOne( - Fts3Table *p, - int iCol, - int iPos, - Fts3Hash *pHash, /* Pending terms hash table to add entry to */ - const char *zToken, - int nToken -){ - PendingList *pList; - int rc = SQLITE_OK; - - pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); - if( pList ){ - p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); - } - if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ - if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ - /* Malloc failed while inserting the new entry. This can only - ** happen if there was no previous entry for this token. - */ - assert( 0==fts3HashFind(pHash, zToken, nToken) ); - sqlite3_free(pList); - rc = SQLITE_NOMEM; - } - } - if( rc==SQLITE_OK ){ - p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); - } - return rc; -} - -/* -** Tokenize the nul-terminated string zText and add all tokens to the -** pending-terms hash-table. The docid used is that currently stored in -** p->iPrevDocid, and the column is specified by argument iCol. -** -** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. -*/ -static int fts3PendingTermsAdd( - Fts3Table *p, /* Table into which text will be inserted */ - int iLangid, /* Language id to use */ - const char *zText, /* Text of document to be inserted */ - int iCol, /* Column into which text is being inserted */ - u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */ -){ - int rc; - int iStart = 0; - int iEnd = 0; - int iPos = 0; - int nWord = 0; - - char const *zToken; - int nToken = 0; - - sqlite3_tokenizer *pTokenizer = p->pTokenizer; - sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - sqlite3_tokenizer_cursor *pCsr; - int (*xNext)(sqlite3_tokenizer_cursor *pCursor, - const char**,int*,int*,int*,int*); - - assert( pTokenizer && pModule ); - - /* If the user has inserted a NULL value, this function may be called with - ** zText==0. In this case, add zero token entries to the hash table and - ** return early. */ - if( zText==0 ){ - *pnWord = 0; - return SQLITE_OK; - } - - rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); - if( rc!=SQLITE_OK ){ - return rc; - } - - xNext = pModule->xNext; - while( SQLITE_OK==rc - && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) - ){ - int i; - if( iPos>=nWord ) nWord = iPos+1; - - /* Positions cannot be negative; we use -1 as a terminator internally. - ** Tokens must have a non-zero length. - */ - if( iPos<0 || !zToken || nToken<=0 ){ - rc = SQLITE_ERROR; - break; - } - - /* Add the term to the terms index */ - rc = fts3PendingTermsAddOne( - p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken - ); - - /* Add the term to each of the prefix indexes that it is not too - ** short for. */ - for(i=1; rc==SQLITE_OK && inIndex; i++){ - struct Fts3Index *pIndex = &p->aIndex[i]; - if( nTokennPrefix ) continue; - rc = fts3PendingTermsAddOne( - p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix - ); - } - } - - pModule->xClose(pCsr); - *pnWord += nWord; - return (rc==SQLITE_DONE ? SQLITE_OK : rc); -} - -/* -** Calling this function indicates that subsequent calls to -** fts3PendingTermsAdd() are to add term/position-list pairs for the -** contents of the document with docid iDocid. -*/ -static int fts3PendingTermsDocid( - Fts3Table *p, /* Full-text table handle */ - int bDelete, /* True if this op is a delete */ - int iLangid, /* Language id of row being written */ - sqlite_int64 iDocid /* Docid of row being written */ -){ - assert( iLangid>=0 ); - assert( bDelete==1 || bDelete==0 ); - - /* TODO(shess) Explore whether partially flushing the buffer on - ** forced-flush would provide better performance. I suspect that if - ** we ordered the doclists by size and flushed the largest until the - ** buffer was half empty, that would let the less frequent terms - ** generate longer doclists. - */ - if( iDocidiPrevDocid - || (iDocid==p->iPrevDocid && p->bPrevDelete==0) - || p->iPrevLangid!=iLangid - || p->nPendingData>p->nMaxPendingData - ){ - int rc = sqlite3Fts3PendingTermsFlush(p); - if( rc!=SQLITE_OK ) return rc; - } - p->iPrevDocid = iDocid; - p->iPrevLangid = iLangid; - p->bPrevDelete = bDelete; - return SQLITE_OK; -} - -/* -** Discard the contents of the pending-terms hash tables. -*/ -SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ - int i; - for(i=0; inIndex; i++){ - Fts3HashElem *pElem; - Fts3Hash *pHash = &p->aIndex[i].hPending; - for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){ - PendingList *pList = (PendingList *)fts3HashData(pElem); - fts3PendingListDelete(pList); - } - fts3HashClear(pHash); - } - p->nPendingData = 0; -} - -/* -** This function is called by the xUpdate() method as part of an INSERT -** operation. It adds entries for each term in the new record to the -** pendingTerms hash table. -** -** Argument apVal is the same as the similarly named argument passed to -** fts3InsertData(). Parameter iDocid is the docid of the new row. -*/ -static int fts3InsertTerms( - Fts3Table *p, - int iLangid, - sqlite3_value **apVal, - u32 *aSz -){ - int i; /* Iterator variable */ - for(i=2; inColumn+2; i++){ - int iCol = i-2; - if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)sqlite3_value_text(apVal[i]); - int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); - if( rc!=SQLITE_OK ){ - return rc; - } - aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); - } - } - return SQLITE_OK; -} - -/* -** This function is called by the xUpdate() method for an INSERT operation. -** The apVal parameter is passed a copy of the apVal argument passed by -** SQLite to the xUpdate() method. i.e: -** -** apVal[0] Not used for INSERT. -** apVal[1] rowid -** apVal[2] Left-most user-defined column -** ... -** apVal[p->nColumn+1] Right-most user-defined column -** apVal[p->nColumn+2] Hidden column with same name as table -** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid) -** apVal[p->nColumn+4] Hidden languageid column -*/ -static int fts3InsertData( - Fts3Table *p, /* Full-text table */ - sqlite3_value **apVal, /* Array of values to insert */ - sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ -){ - int rc; /* Return code */ - sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ - - if( p->zContentTbl ){ - sqlite3_value *pRowid = apVal[p->nColumn+3]; - if( sqlite3_value_type(pRowid)==SQLITE_NULL ){ - pRowid = apVal[1]; - } - if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ - return SQLITE_CONSTRAINT; - } - *piDocid = sqlite3_value_int64(pRowid); - return SQLITE_OK; - } - - /* Locate the statement handle used to insert data into the %_content - ** table. The SQL for this statement is: - ** - ** INSERT INTO %_content VALUES(?, ?, ?, ...) - ** - ** The statement features N '?' variables, where N is the number of user - ** defined columns in the FTS3 table, plus one for the docid field. - */ - rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); - if( rc==SQLITE_OK && p->zLanguageid ){ - rc = sqlite3_bind_int( - pContentInsert, p->nColumn+2, - sqlite3_value_int(apVal[p->nColumn+4]) - ); - } - if( rc!=SQLITE_OK ) return rc; - - /* There is a quirk here. The users INSERT statement may have specified - ** a value for the "rowid" field, for the "docid" field, or for both. - ** Which is a problem, since "rowid" and "docid" are aliases for the - ** same value. For example: - ** - ** INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2); - ** - ** In FTS3, this is an error. It is an error to specify non-NULL values - ** for both docid and some other rowid alias. - */ - if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){ - if( SQLITE_NULL==sqlite3_value_type(apVal[0]) - && SQLITE_NULL!=sqlite3_value_type(apVal[1]) - ){ - /* A rowid/docid conflict. */ - return SQLITE_ERROR; - } - rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); - if( rc!=SQLITE_OK ) return rc; - } - - /* Execute the statement to insert the record. Set *piDocid to the - ** new docid value. - */ - sqlite3_step(pContentInsert); - rc = sqlite3_reset(pContentInsert); - - *piDocid = sqlite3_last_insert_rowid(p->db); - return rc; -} - - - -/* -** Remove all data from the FTS3 table. Clear the hash table containing -** pending terms. -*/ -static int fts3DeleteAll(Fts3Table *p, int bContent){ - int rc = SQLITE_OK; /* Return code */ - - /* Discard the contents of the pending-terms hash table. */ - sqlite3Fts3PendingTermsClear(p); - - /* Delete everything from the shadow tables. Except, leave %_content as - ** is if bContent is false. */ - assert( p->zContentTbl==0 || bContent==0 ); - if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0); - fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0); - fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); - if( p->bHasDocsize ){ - fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0); - } - if( p->bHasStat ){ - fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); - } - return rc; -} - -/* -** -*/ -static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ - int iLangid = 0; - if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); - return iLangid; -} - -/* -** The first element in the apVal[] array is assumed to contain the docid -** (an integer) of a row about to be deleted. Remove all terms from the -** full-text index. -*/ -static void fts3DeleteTerms( - int *pRC, /* Result code */ - Fts3Table *p, /* The FTS table to delete from */ - sqlite3_value *pRowid, /* The docid to be deleted */ - u32 *aSz, /* Sizes of deleted document written here */ - int *pbFound /* OUT: Set to true if row really does exist */ -){ - int rc; - sqlite3_stmt *pSelect; - - assert( *pbFound==0 ); - if( *pRC ) return; - rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); - if( rc==SQLITE_OK ){ - if( SQLITE_ROW==sqlite3_step(pSelect) ){ - int i; - int iLangid = langidFromSelect(p, pSelect); - i64 iDocid = sqlite3_column_int64(pSelect, 0); - rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid); - for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ - int iCol = i-1; - if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)sqlite3_column_text(pSelect, i); - rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); - aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); - } - } - if( rc!=SQLITE_OK ){ - sqlite3_reset(pSelect); - *pRC = rc; - return; - } - *pbFound = 1; - } - rc = sqlite3_reset(pSelect); - }else{ - sqlite3_reset(pSelect); - } - *pRC = rc; -} - -/* -** Forward declaration to account for the circular dependency between -** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). -*/ -static int fts3SegmentMerge(Fts3Table *, int, int, int); - -/* -** This function allocates a new level iLevel index in the segdir table. -** Usually, indexes are allocated within a level sequentially starting -** with 0, so the allocated index is one greater than the value returned -** by: -** -** SELECT max(idx) FROM %_segdir WHERE level = :iLevel -** -** However, if there are already FTS3_MERGE_COUNT indexes at the requested -** level, they are merged into a single level (iLevel+1) segment and the -** allocated index is 0. -** -** If successful, *piIdx is set to the allocated index slot and SQLITE_OK -** returned. Otherwise, an SQLite error code is returned. -*/ -static int fts3AllocateSegdirIdx( - Fts3Table *p, - int iLangid, /* Language id */ - int iIndex, /* Index for p->aIndex */ - int iLevel, - int *piIdx -){ - int rc; /* Return Code */ - sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ - int iNext = 0; /* Result of query pNextIdx */ - - assert( iLangid>=0 ); - assert( p->nIndex>=1 ); - - /* Set variable iNext to the next available segdir index at level iLevel. */ - rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64( - pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) - ); - if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ - iNext = sqlite3_column_int(pNextIdx, 0); - } - rc = sqlite3_reset(pNextIdx); - } - - if( rc==SQLITE_OK ){ - /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already - ** full, merge all segments in level iLevel into a single iLevel+1 - ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, - ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. - */ - if( iNext>=FTS3_MERGE_COUNT ){ - fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); - rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); - *piIdx = 0; - }else{ - *piIdx = iNext; - } - } - - return rc; -} - -/* -** The %_segments table is declared as follows: -** -** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB) -** -** This function reads data from a single row of the %_segments table. The -** specific row is identified by the iBlockid parameter. If paBlob is not -** NULL, then a buffer is allocated using sqlite3_malloc() and populated -** with the contents of the blob stored in the "block" column of the -** identified table row is. Whether or not paBlob is NULL, *pnBlob is set -** to the size of the blob in bytes before returning. -** -** If an error occurs, or the table does not contain the specified row, -** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If -** paBlob is non-NULL, then it is the responsibility of the caller to -** eventually free the returned buffer. -** -** This function may leave an open sqlite3_blob* handle in the -** Fts3Table.pSegments variable. This handle is reused by subsequent calls -** to this function. The handle may be closed by calling the -** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy -** performance improvement, but the blob handle should always be closed -** before control is returned to the user (to prevent a lock being held -** on the database file for longer than necessary). Thus, any virtual table -** method (xFilter etc.) that may directly or indirectly call this function -** must call sqlite3Fts3SegmentsClose() before returning. -*/ -SQLITE_PRIVATE int sqlite3Fts3ReadBlock( - Fts3Table *p, /* FTS3 table handle */ - sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ - char **paBlob, /* OUT: Blob data in malloc'd buffer */ - int *pnBlob, /* OUT: Size of blob data */ - int *pnLoad /* OUT: Bytes actually loaded */ -){ - int rc; /* Return code */ - - /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ - assert( pnBlob ); - - if( p->pSegments ){ - rc = sqlite3_blob_reopen(p->pSegments, iBlockid); - }else{ - if( 0==p->zSegmentsTbl ){ - p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); - if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; - } - rc = sqlite3_blob_open( - p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments - ); - } - - if( rc==SQLITE_OK ){ - int nByte = sqlite3_blob_bytes(p->pSegments); - *pnBlob = nByte; - if( paBlob ){ - char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); - if( !aByte ){ - rc = SQLITE_NOMEM; - }else{ - if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ - nByte = FTS3_NODE_CHUNKSIZE; - *pnLoad = nByte; - } - rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); - memset(&aByte[nByte], 0, FTS3_NODE_PADDING); - if( rc!=SQLITE_OK ){ - sqlite3_free(aByte); - aByte = 0; - } - } - *paBlob = aByte; - } - } - - return rc; -} - -/* -** Close the blob handle at p->pSegments, if it is open. See comments above -** the sqlite3Fts3ReadBlock() function for details. -*/ -SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ - sqlite3_blob_close(p->pSegments); - p->pSegments = 0; -} - -static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ - int nRead; /* Number of bytes to read */ - int rc; /* Return code */ - - nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); - rc = sqlite3_blob_read( - pReader->pBlob, - &pReader->aNode[pReader->nPopulate], - nRead, - pReader->nPopulate - ); - - if( rc==SQLITE_OK ){ - pReader->nPopulate += nRead; - memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); - if( pReader->nPopulate==pReader->nNode ){ - sqlite3_blob_close(pReader->pBlob); - pReader->pBlob = 0; - pReader->nPopulate = 0; - } - } - return rc; -} - -static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ - int rc = SQLITE_OK; - assert( !pReader->pBlob - || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode]) - ); - while( pReader->pBlob && rc==SQLITE_OK - && (pFrom - pReader->aNode + nByte)>pReader->nPopulate - ){ - rc = fts3SegReaderIncrRead(pReader); - } - return rc; -} - -/* -** Set an Fts3SegReader cursor to point at EOF. -*/ -static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ - if( !fts3SegReaderIsRootOnly(pSeg) ){ - sqlite3_free(pSeg->aNode); - sqlite3_blob_close(pSeg->pBlob); - pSeg->pBlob = 0; - } - pSeg->aNode = 0; -} - -/* -** Move the iterator passed as the first argument to the next term in the -** segment. If successful, SQLITE_OK is returned. If there is no next term, -** SQLITE_DONE. Otherwise, an SQLite error code. -*/ -static int fts3SegReaderNext( - Fts3Table *p, - Fts3SegReader *pReader, - int bIncr -){ - int rc; /* Return code of various sub-routines */ - char *pNext; /* Cursor variable */ - int nPrefix; /* Number of bytes in term prefix */ - int nSuffix; /* Number of bytes in term suffix */ - - if( !pReader->aDoclist ){ - pNext = pReader->aNode; - }else{ - pNext = &pReader->aDoclist[pReader->nDoclist]; - } - - if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ - - if( fts3SegReaderIsPending(pReader) ){ - Fts3HashElem *pElem = *(pReader->ppNextElem); - sqlite3_free(pReader->aNode); - pReader->aNode = 0; - if( pElem ){ - char *aCopy; - PendingList *pList = (PendingList *)fts3HashData(pElem); - int nCopy = pList->nData+1; - pReader->zTerm = (char *)fts3HashKey(pElem); - pReader->nTerm = fts3HashKeysize(pElem); - aCopy = (char*)sqlite3_malloc(nCopy); - if( !aCopy ) return SQLITE_NOMEM; - memcpy(aCopy, pList->aData, nCopy); - pReader->nNode = pReader->nDoclist = nCopy; - pReader->aNode = pReader->aDoclist = aCopy; - pReader->ppNextElem++; - assert( pReader->aNode ); - } - return SQLITE_OK; - } - - fts3SegReaderSetEof(pReader); - - /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf - ** blocks have already been traversed. */ - assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock ); - if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ - return SQLITE_OK; - } - - rc = sqlite3Fts3ReadBlock( - p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, - (bIncr ? &pReader->nPopulate : 0) - ); - if( rc!=SQLITE_OK ) return rc; - assert( pReader->pBlob==0 ); - if( bIncr && pReader->nPopulatenNode ){ - pReader->pBlob = p->pSegments; - p->pSegments = 0; - } - pNext = pReader->aNode; - } - - assert( !fts3SegReaderIsPending(pReader) ); - - rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); - if( rc!=SQLITE_OK ) return rc; - - /* Because of the FTS3_NODE_PADDING bytes of padding, the following is - ** safe (no risk of overread) even if the node data is corrupted. */ - pNext += fts3GetVarint32(pNext, &nPrefix); - pNext += fts3GetVarint32(pNext, &nSuffix); - if( nPrefix<0 || nSuffix<=0 - || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] - ){ - return FTS_CORRUPT_VTAB; - } - - if( nPrefix+nSuffix>pReader->nTermAlloc ){ - int nNew = (nPrefix+nSuffix)*2; - char *zNew = sqlite3_realloc(pReader->zTerm, nNew); - if( !zNew ){ - return SQLITE_NOMEM; - } - pReader->zTerm = zNew; - pReader->nTermAlloc = nNew; - } - - rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX); - if( rc!=SQLITE_OK ) return rc; - - memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); - pReader->nTerm = nPrefix+nSuffix; - pNext += nSuffix; - pNext += fts3GetVarint32(pNext, &pReader->nDoclist); - pReader->aDoclist = pNext; - pReader->pOffsetList = 0; - - /* Check that the doclist does not appear to extend past the end of the - ** b-tree node. And that the final byte of the doclist is 0x00. If either - ** of these statements is untrue, then the data structure is corrupt. - */ - if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] - || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) - ){ - return FTS_CORRUPT_VTAB; - } - return SQLITE_OK; -} - -/* -** Set the SegReader to point to the first docid in the doclist associated -** with the current term. -*/ -static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ - int rc = SQLITE_OK; - assert( pReader->aDoclist ); - assert( !pReader->pOffsetList ); - if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ - u8 bEof = 0; - pReader->iDocid = 0; - pReader->nOffsetList = 0; - sqlite3Fts3DoclistPrev(0, - pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, - &pReader->iDocid, &pReader->nOffsetList, &bEof - ); - }else{ - rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); - if( rc==SQLITE_OK ){ - int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); - pReader->pOffsetList = &pReader->aDoclist[n]; - } - } - return rc; -} - -/* -** Advance the SegReader to point to the next docid in the doclist -** associated with the current term. -** -** If arguments ppOffsetList and pnOffsetList are not NULL, then -** *ppOffsetList is set to point to the first column-offset list -** in the doclist entry (i.e. immediately past the docid varint). -** *pnOffsetList is set to the length of the set of column-offset -** lists, not including the nul-terminator byte. For example: -*/ -static int fts3SegReaderNextDocid( - Fts3Table *pTab, - Fts3SegReader *pReader, /* Reader to advance to next docid */ - char **ppOffsetList, /* OUT: Pointer to current position-list */ - int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */ -){ - int rc = SQLITE_OK; - char *p = pReader->pOffsetList; - char c = 0; - - assert( p ); - - if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ - /* A pending-terms seg-reader for an FTS4 table that uses order=desc. - ** Pending-terms doclists are always built up in ascending order, so - ** we have to iterate through them backwards here. */ - u8 bEof = 0; - if( ppOffsetList ){ - *ppOffsetList = pReader->pOffsetList; - *pnOffsetList = pReader->nOffsetList - 1; - } - sqlite3Fts3DoclistPrev(0, - pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, - &pReader->nOffsetList, &bEof - ); - if( bEof ){ - pReader->pOffsetList = 0; - }else{ - pReader->pOffsetList = p; - } - }else{ - char *pEnd = &pReader->aDoclist[pReader->nDoclist]; - - /* Pointer p currently points at the first byte of an offset list. The - ** following block advances it to point one byte past the end of - ** the same offset list. */ - while( 1 ){ - - /* The following line of code (and the "p++" below the while() loop) is - ** normally all that is required to move pointer p to the desired - ** position. The exception is if this node is being loaded from disk - ** incrementally and pointer "p" now points to the first byte past - ** the populated part of pReader->aNode[]. - */ - while( *p | c ) c = *p++ & 0x80; - assert( *p==0 ); - - if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break; - rc = fts3SegReaderIncrRead(pReader); - if( rc!=SQLITE_OK ) return rc; - } - p++; - - /* If required, populate the output variables with a pointer to and the - ** size of the previous offset-list. - */ - if( ppOffsetList ){ - *ppOffsetList = pReader->pOffsetList; - *pnOffsetList = (int)(p - pReader->pOffsetList - 1); - } - - /* List may have been edited in place by fts3EvalNearTrim() */ - while( p=pEnd ){ - pReader->pOffsetList = 0; - }else{ - rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); - if( rc==SQLITE_OK ){ - sqlite3_int64 iDelta; - pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); - if( pTab->bDescIdx ){ - pReader->iDocid -= iDelta; - }else{ - pReader->iDocid += iDelta; - } - } - } - } - - return SQLITE_OK; -} - - -SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( - Fts3Cursor *pCsr, - Fts3MultiSegReader *pMsr, - int *pnOvfl -){ - Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; - int nOvfl = 0; - int ii; - int rc = SQLITE_OK; - int pgsz = p->nPgsz; - - assert( p->bFts4 ); - assert( pgsz>0 ); - - for(ii=0; rc==SQLITE_OK && iinSegment; ii++){ - Fts3SegReader *pReader = pMsr->apSegment[ii]; - if( !fts3SegReaderIsPending(pReader) - && !fts3SegReaderIsRootOnly(pReader) - ){ - sqlite3_int64 jj; - for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ - int nBlob; - rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); - if( rc!=SQLITE_OK ) break; - if( (nBlob+35)>pgsz ){ - nOvfl += (nBlob + 34)/pgsz; - } - } - } - } - *pnOvfl = nOvfl; - return rc; -} - -/* -** Free all allocations associated with the iterator passed as the -** second argument. -*/ -SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ - if( pReader ){ - if( !fts3SegReaderIsPending(pReader) ){ - sqlite3_free(pReader->zTerm); - } - if( !fts3SegReaderIsRootOnly(pReader) ){ - sqlite3_free(pReader->aNode); - } - sqlite3_blob_close(pReader->pBlob); - } - sqlite3_free(pReader); -} - -/* -** Allocate a new SegReader object. -*/ -SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( - int iAge, /* Segment "age". */ - int bLookup, /* True for a lookup only */ - sqlite3_int64 iStartLeaf, /* First leaf to traverse */ - sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ - sqlite3_int64 iEndBlock, /* Final block of segment */ - const char *zRoot, /* Buffer containing root node */ - int nRoot, /* Size of buffer containing root node */ - Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ -){ - Fts3SegReader *pReader; /* Newly allocated SegReader object */ - int nExtra = 0; /* Bytes to allocate segment root node */ - - assert( iStartLeaf<=iEndLeaf ); - if( iStartLeaf==0 ){ - nExtra = nRoot + FTS3_NODE_PADDING; - } - - pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); - if( !pReader ){ - return SQLITE_NOMEM; - } - memset(pReader, 0, sizeof(Fts3SegReader)); - pReader->iIdx = iAge; - pReader->bLookup = bLookup!=0; - pReader->iStartBlock = iStartLeaf; - pReader->iLeafEndBlock = iEndLeaf; - pReader->iEndBlock = iEndBlock; - - if( nExtra ){ - /* The entire segment is stored in the root node. */ - pReader->aNode = (char *)&pReader[1]; - pReader->rootOnly = 1; - pReader->nNode = nRoot; - memcpy(pReader->aNode, zRoot, nRoot); - memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); - }else{ - pReader->iCurrentBlock = iStartLeaf-1; - } - *ppReader = pReader; - return SQLITE_OK; -} - -/* -** This is a comparison function used as a qsort() callback when sorting -** an array of pending terms by term. This occurs as part of flushing -** the contents of the pending-terms hash table to the database. -*/ -static int SQLITE_CDECL fts3CompareElemByTerm( - const void *lhs, - const void *rhs -){ - char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); - char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); - int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); - int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs); - - int n = (n1aIndex */ - const char *zTerm, /* Term to search for */ - int nTerm, /* Size of buffer zTerm */ - int bPrefix, /* True for a prefix iterator */ - Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ -){ - Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ - Fts3HashElem *pE; /* Iterator variable */ - Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ - int nElem = 0; /* Size of array at aElem */ - int rc = SQLITE_OK; /* Return Code */ - Fts3Hash *pHash; - - pHash = &p->aIndex[iIndex].hPending; - if( bPrefix ){ - int nAlloc = 0; /* Size of allocated array at aElem */ - - for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ - char *zKey = (char *)fts3HashKey(pE); - int nKey = fts3HashKeysize(pE); - if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ - if( nElem==nAlloc ){ - Fts3HashElem **aElem2; - nAlloc += 16; - aElem2 = (Fts3HashElem **)sqlite3_realloc( - aElem, nAlloc*sizeof(Fts3HashElem *) - ); - if( !aElem2 ){ - rc = SQLITE_NOMEM; - nElem = 0; - break; - } - aElem = aElem2; - } - - aElem[nElem++] = pE; - } - } - - /* If more than one term matches the prefix, sort the Fts3HashElem - ** objects in term order using qsort(). This uses the same comparison - ** callback as is used when flushing terms to disk. - */ - if( nElem>1 ){ - qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm); - } - - }else{ - /* The query is a simple term lookup that matches at most one term in - ** the index. All that is required is a straight hash-lookup. - ** - ** Because the stack address of pE may be accessed via the aElem pointer - ** below, the "Fts3HashElem *pE" must be declared so that it is valid - ** within this entire function, not just this "else{...}" block. - */ - pE = fts3HashFindElem(pHash, zTerm, nTerm); - if( pE ){ - aElem = &pE; - nElem = 1; - } - } - - if( nElem>0 ){ - int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); - pReader = (Fts3SegReader *)sqlite3_malloc(nByte); - if( !pReader ){ - rc = SQLITE_NOMEM; - }else{ - memset(pReader, 0, nByte); - pReader->iIdx = 0x7FFFFFFF; - pReader->ppNextElem = (Fts3HashElem **)&pReader[1]; - memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *)); - } - } - - if( bPrefix ){ - sqlite3_free(aElem); - } - *ppReader = pReader; - return rc; -} - -/* -** Compare the entries pointed to by two Fts3SegReader structures. -** Comparison is as follows: -** -** 1) EOF is greater than not EOF. -** -** 2) The current terms (if any) are compared using memcmp(). If one -** term is a prefix of another, the longer term is considered the -** larger. -** -** 3) By segment age. An older segment is considered larger. -*/ -static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ - int rc; - if( pLhs->aNode && pRhs->aNode ){ - int rc2 = pLhs->nTerm - pRhs->nTerm; - if( rc2<0 ){ - rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm); - }else{ - rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm); - } - if( rc==0 ){ - rc = rc2; - } - }else{ - rc = (pLhs->aNode==0) - (pRhs->aNode==0); - } - if( rc==0 ){ - rc = pRhs->iIdx - pLhs->iIdx; - } - assert( rc!=0 ); - return rc; -} - -/* -** A different comparison function for SegReader structures. In this -** version, it is assumed that each SegReader points to an entry in -** a doclist for identical terms. Comparison is made as follows: -** -** 1) EOF (end of doclist in this case) is greater than not EOF. -** -** 2) By current docid. -** -** 3) By segment age. An older segment is considered larger. -*/ -static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ - int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); - if( rc==0 ){ - if( pLhs->iDocid==pRhs->iDocid ){ - rc = pRhs->iIdx - pLhs->iIdx; - }else{ - rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1; - } - } - assert( pLhs->aNode && pRhs->aNode ); - return rc; -} -static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ - int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); - if( rc==0 ){ - if( pLhs->iDocid==pRhs->iDocid ){ - rc = pRhs->iIdx - pLhs->iIdx; - }else{ - rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1; - } - } - assert( pLhs->aNode && pRhs->aNode ); - return rc; -} - -/* -** Compare the term that the Fts3SegReader object passed as the first argument -** points to with the term specified by arguments zTerm and nTerm. -** -** If the pSeg iterator is already at EOF, return 0. Otherwise, return -** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are -** equal, or +ve if the pSeg term is greater than zTerm/nTerm. -*/ -static int fts3SegReaderTermCmp( - Fts3SegReader *pSeg, /* Segment reader object */ - const char *zTerm, /* Term to compare to */ - int nTerm /* Size of term zTerm in bytes */ -){ - int res = 0; - if( pSeg->aNode ){ - if( pSeg->nTerm>nTerm ){ - res = memcmp(pSeg->zTerm, zTerm, nTerm); - }else{ - res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm); - } - if( res==0 ){ - res = pSeg->nTerm-nTerm; - } - } - return res; -} - -/* -** Argument apSegment is an array of nSegment elements. It is known that -** the final (nSegment-nSuspect) members are already in sorted order -** (according to the comparison function provided). This function shuffles -** the array around until all entries are in sorted order. -*/ -static void fts3SegReaderSort( - Fts3SegReader **apSegment, /* Array to sort entries of */ - int nSegment, /* Size of apSegment array */ - int nSuspect, /* Unsorted entry count */ - int (*xCmp)(Fts3SegReader *, Fts3SegReader *) /* Comparison function */ -){ - int i; /* Iterator variable */ - - assert( nSuspect<=nSegment ); - - if( nSuspect==nSegment ) nSuspect--; - for(i=nSuspect-1; i>=0; i--){ - int j; - for(j=i; j<(nSegment-1); j++){ - Fts3SegReader *pTmp; - if( xCmp(apSegment[j], apSegment[j+1])<0 ) break; - pTmp = apSegment[j+1]; - apSegment[j+1] = apSegment[j]; - apSegment[j] = pTmp; - } - } - -#ifndef NDEBUG - /* Check that the list really is sorted now. */ - for(i=0; i<(nSuspect-1); i++){ - assert( xCmp(apSegment[i], apSegment[i+1])<0 ); - } -#endif -} - -/* -** Insert a record into the %_segments table. -*/ -static int fts3WriteSegment( - Fts3Table *p, /* Virtual table handle */ - sqlite3_int64 iBlock, /* Block id for new block */ - char *z, /* Pointer to buffer containing block data */ - int n /* Size of buffer z in bytes */ -){ - sqlite3_stmt *pStmt; - int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pStmt, 1, iBlock); - sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - } - return rc; -} - -/* -** Find the largest relative level number in the table. If successful, set -** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, -** set *pnMax to zero and return an SQLite error code. -*/ -SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ - int rc; - int mxLevel = 0; - sqlite3_stmt *pStmt = 0; - - rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); - if( rc==SQLITE_OK ){ - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - mxLevel = sqlite3_column_int(pStmt, 0); - } - rc = sqlite3_reset(pStmt); - } - *pnMax = mxLevel; - return rc; -} - -/* -** Insert a record into the %_segdir table. -*/ -static int fts3WriteSegdir( - Fts3Table *p, /* Virtual table handle */ - sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ - int iIdx, /* Value for "idx" field */ - sqlite3_int64 iStartBlock, /* Value for "start_block" field */ - sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ - sqlite3_int64 iEndBlock, /* Value for "end_block" field */ - sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ - char *zRoot, /* Blob value for "root" field */ - int nRoot /* Number of bytes in buffer zRoot */ -){ - sqlite3_stmt *pStmt; - int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pStmt, 1, iLevel); - sqlite3_bind_int(pStmt, 2, iIdx); - sqlite3_bind_int64(pStmt, 3, iStartBlock); - sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); - if( nLeafData==0 ){ - sqlite3_bind_int64(pStmt, 5, iEndBlock); - }else{ - char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); - if( !zEnd ) return SQLITE_NOMEM; - sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); - } - sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - } - return rc; -} - -/* -** Return the size of the common prefix (if any) shared by zPrev and -** zNext, in bytes. For example, -** -** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 -** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 -** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0 -*/ -static int fts3PrefixCompress( - const char *zPrev, /* Buffer containing previous term */ - int nPrev, /* Size of buffer zPrev in bytes */ - const char *zNext, /* Buffer containing next term */ - int nNext /* Size of buffer zNext in bytes */ -){ - int n; - UNUSED_PARAMETER(nNext); - for(n=0; nnData; /* Current size of node in bytes */ - int nReq = nData; /* Required space after adding zTerm */ - int nPrefix; /* Number of bytes of prefix compression */ - int nSuffix; /* Suffix length */ - - nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); - nSuffix = nTerm-nPrefix; - - nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; - if( nReq<=p->nNodeSize || !pTree->zTerm ){ - - if( nReq>p->nNodeSize ){ - /* An unusual case: this is the first term to be added to the node - ** and the static node buffer (p->nNodeSize bytes) is not large - ** enough. Use a separately malloced buffer instead This wastes - ** p->nNodeSize bytes, but since this scenario only comes about when - ** the database contain two terms that share a prefix of almost 2KB, - ** this is not expected to be a serious problem. - */ - assert( pTree->aData==(char *)&pTree[1] ); - pTree->aData = (char *)sqlite3_malloc(nReq); - if( !pTree->aData ){ - return SQLITE_NOMEM; - } - } - - if( pTree->zTerm ){ - /* There is no prefix-length field for first term in a node */ - nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); - } - - nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); - memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix); - pTree->nData = nData + nSuffix; - pTree->nEntry++; - - if( isCopyTerm ){ - if( pTree->nMalloczMalloc, nTerm*2); - if( !zNew ){ - return SQLITE_NOMEM; - } - pTree->nMalloc = nTerm*2; - pTree->zMalloc = zNew; - } - pTree->zTerm = pTree->zMalloc; - memcpy(pTree->zTerm, zTerm, nTerm); - pTree->nTerm = nTerm; - }else{ - pTree->zTerm = (char *)zTerm; - pTree->nTerm = nTerm; - } - return SQLITE_OK; - } - } - - /* If control flows to here, it was not possible to append zTerm to the - ** current node. Create a new node (a right-sibling of the current node). - ** If this is the first node in the tree, the term is added to it. - ** - ** Otherwise, the term is not added to the new node, it is left empty for - ** now. Instead, the term is inserted into the parent of pTree. If pTree - ** has no parent, one is created here. - */ - pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); - if( !pNew ){ - return SQLITE_NOMEM; - } - memset(pNew, 0, sizeof(SegmentNode)); - pNew->nData = 1 + FTS3_VARINT_MAX; - pNew->aData = (char *)&pNew[1]; - - if( pTree ){ - SegmentNode *pParent = pTree->pParent; - rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm); - if( pTree->pParent==0 ){ - pTree->pParent = pParent; - } - pTree->pRight = pNew; - pNew->pLeftmost = pTree->pLeftmost; - pNew->pParent = pParent; - pNew->zMalloc = pTree->zMalloc; - pNew->nMalloc = pTree->nMalloc; - pTree->zMalloc = 0; - }else{ - pNew->pLeftmost = pNew; - rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); - } - - *ppTree = pNew; - return rc; -} - -/* -** Helper function for fts3NodeWrite(). -*/ -static int fts3TreeFinishNode( - SegmentNode *pTree, - int iHeight, - sqlite3_int64 iLeftChild -){ - int nStart; - assert( iHeight>=1 && iHeight<128 ); - nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild); - pTree->aData[nStart] = (char)iHeight; - sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); - return nStart; -} - -/* -** Write the buffer for the segment node pTree and all of its peers to the -** database. Then call this function recursively to write the parent of -** pTree and its peers to the database. -** -** Except, if pTree is a root node, do not write it to the database. Instead, -** set output variables *paRoot and *pnRoot to contain the root node. -** -** If successful, SQLITE_OK is returned and output variable *piLast is -** set to the largest blockid written to the database (or zero if no -** blocks were written to the db). Otherwise, an SQLite error code is -** returned. -*/ -static int fts3NodeWrite( - Fts3Table *p, /* Virtual table handle */ - SegmentNode *pTree, /* SegmentNode handle */ - int iHeight, /* Height of this node in tree */ - sqlite3_int64 iLeaf, /* Block id of first leaf node */ - sqlite3_int64 iFree, /* Block id of next free slot in %_segments */ - sqlite3_int64 *piLast, /* OUT: Block id of last entry written */ - char **paRoot, /* OUT: Data for root node */ - int *pnRoot /* OUT: Size of root node in bytes */ -){ - int rc = SQLITE_OK; - - if( !pTree->pParent ){ - /* Root node of the tree. */ - int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf); - *piLast = iFree-1; - *pnRoot = pTree->nData - nStart; - *paRoot = &pTree->aData[nStart]; - }else{ - SegmentNode *pIter; - sqlite3_int64 iNextFree = iFree; - sqlite3_int64 iNextLeaf = iLeaf; - for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ - int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); - int nWrite = pIter->nData - nStart; - - rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite); - iNextFree++; - iNextLeaf += (pIter->nEntry+1); - } - if( rc==SQLITE_OK ){ - assert( iNextLeaf==iFree ); - rc = fts3NodeWrite( - p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot - ); - } - } - - return rc; -} - -/* -** Free all memory allocations associated with the tree pTree. -*/ -static void fts3NodeFree(SegmentNode *pTree){ - if( pTree ){ - SegmentNode *p = pTree->pLeftmost; - fts3NodeFree(p->pParent); - while( p ){ - SegmentNode *pRight = p->pRight; - if( p->aData!=(char *)&p[1] ){ - sqlite3_free(p->aData); - } - assert( pRight==0 || p->zMalloc==0 ); - sqlite3_free(p->zMalloc); - sqlite3_free(p); - p = pRight; - } - } -} - -/* -** Add a term to the segment being constructed by the SegmentWriter object -** *ppWriter. When adding the first term to a segment, *ppWriter should -** be passed NULL. This function will allocate a new SegmentWriter object -** and return it via the input/output variable *ppWriter in this case. -** -** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. -*/ -static int fts3SegWriterAdd( - Fts3Table *p, /* Virtual table handle */ - SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ - int isCopyTerm, /* True if buffer zTerm must be copied */ - const char *zTerm, /* Pointer to buffer containing term */ - int nTerm, /* Size of term in bytes */ - const char *aDoclist, /* Pointer to buffer containing doclist */ - int nDoclist /* Size of doclist in bytes */ -){ - int nPrefix; /* Size of term prefix in bytes */ - int nSuffix; /* Size of term suffix in bytes */ - int nReq; /* Number of bytes required on leaf page */ - int nData; - SegmentWriter *pWriter = *ppWriter; - - if( !pWriter ){ - int rc; - sqlite3_stmt *pStmt; - - /* Allocate the SegmentWriter structure */ - pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); - if( !pWriter ) return SQLITE_NOMEM; - memset(pWriter, 0, sizeof(SegmentWriter)); - *ppWriter = pWriter; - - /* Allocate a buffer in which to accumulate data */ - pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); - if( !pWriter->aData ) return SQLITE_NOMEM; - pWriter->nSize = p->nNodeSize; - - /* Find the next free blockid in the %_segments table */ - rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); - if( rc!=SQLITE_OK ) return rc; - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - pWriter->iFree = sqlite3_column_int64(pStmt, 0); - pWriter->iFirst = pWriter->iFree; - } - rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ) return rc; - } - nData = pWriter->nData; - - nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); - nSuffix = nTerm-nPrefix; - - /* Figure out how many bytes are required by this new entry */ - nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ - sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ - nSuffix + /* Term suffix */ - sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ - nDoclist; /* Doclist data */ - - if( nData>0 && nData+nReq>p->nNodeSize ){ - int rc; - - /* The current leaf node is full. Write it out to the database. */ - rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); - if( rc!=SQLITE_OK ) return rc; - p->nLeafAdd++; - - /* Add the current term to the interior node tree. The term added to - ** the interior tree must: - ** - ** a) be greater than the largest term on the leaf node just written - ** to the database (still available in pWriter->zTerm), and - ** - ** b) be less than or equal to the term about to be added to the new - ** leaf node (zTerm/nTerm). - ** - ** In other words, it must be the prefix of zTerm 1 byte longer than - ** the common prefix (if any) of zTerm and pWriter->zTerm. - */ - assert( nPrefixpTree, isCopyTerm, zTerm, nPrefix+1); - if( rc!=SQLITE_OK ) return rc; - - nData = 0; - pWriter->nTerm = 0; - - nPrefix = 0; - nSuffix = nTerm; - nReq = 1 + /* varint containing prefix size */ - sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ - nTerm + /* Term suffix */ - sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ - nDoclist; /* Doclist data */ - } - - /* Increase the total number of bytes written to account for the new entry. */ - pWriter->nLeafData += nReq; - - /* If the buffer currently allocated is too small for this entry, realloc - ** the buffer to make it large enough. - */ - if( nReq>pWriter->nSize ){ - char *aNew = sqlite3_realloc(pWriter->aData, nReq); - if( !aNew ) return SQLITE_NOMEM; - pWriter->aData = aNew; - pWriter->nSize = nReq; - } - assert( nData+nReq<=pWriter->nSize ); - - /* Append the prefix-compressed term and doclist to the buffer. */ - nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); - nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); - memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); - nData += nSuffix; - nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); - memcpy(&pWriter->aData[nData], aDoclist, nDoclist); - pWriter->nData = nData + nDoclist; - - /* Save the current term so that it can be used to prefix-compress the next. - ** If the isCopyTerm parameter is true, then the buffer pointed to by - ** zTerm is transient, so take a copy of the term data. Otherwise, just - ** store a copy of the pointer. - */ - if( isCopyTerm ){ - if( nTerm>pWriter->nMalloc ){ - char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); - if( !zNew ){ - return SQLITE_NOMEM; - } - pWriter->nMalloc = nTerm*2; - pWriter->zMalloc = zNew; - pWriter->zTerm = zNew; - } - assert( pWriter->zTerm==pWriter->zMalloc ); - memcpy(pWriter->zTerm, zTerm, nTerm); - }else{ - pWriter->zTerm = (char *)zTerm; - } - pWriter->nTerm = nTerm; - - return SQLITE_OK; -} - -/* -** Flush all data associated with the SegmentWriter object pWriter to the -** database. This function must be called after all terms have been added -** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is -** returned. Otherwise, an SQLite error code. -*/ -static int fts3SegWriterFlush( - Fts3Table *p, /* Virtual table handle */ - SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ - sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ - int iIdx /* Value for 'idx' column of %_segdir */ -){ - int rc; /* Return code */ - if( pWriter->pTree ){ - sqlite3_int64 iLast = 0; /* Largest block id written to database */ - sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ - char *zRoot = NULL; /* Pointer to buffer containing root node */ - int nRoot = 0; /* Size of buffer zRoot */ - - iLastLeaf = pWriter->iFree; - rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData); - if( rc==SQLITE_OK ){ - rc = fts3NodeWrite(p, pWriter->pTree, 1, - pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); - } - if( rc==SQLITE_OK ){ - rc = fts3WriteSegdir(p, iLevel, iIdx, - pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); - } - }else{ - /* The entire tree fits on the root node. Write it to the segdir table. */ - rc = fts3WriteSegdir(p, iLevel, iIdx, - 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); - } - p->nLeafAdd++; - return rc; -} - -/* -** Release all memory held by the SegmentWriter object passed as the -** first argument. -*/ -static void fts3SegWriterFree(SegmentWriter *pWriter){ - if( pWriter ){ - sqlite3_free(pWriter->aData); - sqlite3_free(pWriter->zMalloc); - fts3NodeFree(pWriter->pTree); - sqlite3_free(pWriter); - } -} - -/* -** The first value in the apVal[] array is assumed to contain an integer. -** This function tests if there exist any documents with docid values that -** are different from that integer. i.e. if deleting the document with docid -** pRowid would mean the FTS3 table were empty. -** -** If successful, *pisEmpty is set to true if the table is empty except for -** document pRowid, or false otherwise, and SQLITE_OK is returned. If an -** error occurs, an SQLite error code is returned. -*/ -static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ - sqlite3_stmt *pStmt; - int rc; - if( p->zContentTbl ){ - /* If using the content=xxx option, assume the table is never empty */ - *pisEmpty = 0; - rc = SQLITE_OK; - }else{ - rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); - if( rc==SQLITE_OK ){ - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pisEmpty = sqlite3_column_int(pStmt, 0); - } - rc = sqlite3_reset(pStmt); - } - } - return rc; -} - -/* -** Set *pnMax to the largest segment level in the database for the index -** iIndex. -** -** Segment levels are stored in the 'level' column of the %_segdir table. -** -** Return SQLITE_OK if successful, or an SQLite error code if not. -*/ -static int fts3SegmentMaxLevel( - Fts3Table *p, - int iLangid, - int iIndex, - sqlite3_int64 *pnMax -){ - sqlite3_stmt *pStmt; - int rc; - assert( iIndex>=0 && iIndexnIndex ); - - /* Set pStmt to the compiled version of: - ** - ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? - ** - ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). - */ - rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); - sqlite3_bind_int64(pStmt, 2, - getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) - ); - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pnMax = sqlite3_column_int64(pStmt, 0); - } - return sqlite3_reset(pStmt); -} - -/* -** iAbsLevel is an absolute level that may be assumed to exist within -** the database. This function checks if it is the largest level number -** within its index. Assuming no error occurs, *pbMax is set to 1 if -** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK -** is returned. If an error occurs, an error code is returned and the -** final value of *pbMax is undefined. -*/ -static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ - - /* Set pStmt to the compiled version of: - ** - ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? - ** - ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). - */ - sqlite3_stmt *pStmt; - int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); - sqlite3_bind_int64(pStmt, 2, - ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL - ); - - *pbMax = 0; - if( SQLITE_ROW==sqlite3_step(pStmt) ){ - *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; - } - return sqlite3_reset(pStmt); -} - -/* -** Delete all entries in the %_segments table associated with the segment -** opened with seg-reader pSeg. This function does not affect the contents -** of the %_segdir table. -*/ -static int fts3DeleteSegment( - Fts3Table *p, /* FTS table handle */ - Fts3SegReader *pSeg /* Segment to delete */ -){ - int rc = SQLITE_OK; /* Return code */ - if( pSeg->iStartBlock ){ - sqlite3_stmt *pDelete; /* SQL statement to delete rows */ - rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); - sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); - sqlite3_step(pDelete); - rc = sqlite3_reset(pDelete); - } - } - return rc; -} - -/* -** This function is used after merging multiple segments into a single large -** segment to delete the old, now redundant, segment b-trees. Specifically, -** it: -** -** 1) Deletes all %_segments entries for the segments associated with -** each of the SegReader objects in the array passed as the third -** argument, and -** -** 2) deletes all %_segdir entries with level iLevel, or all %_segdir -** entries regardless of level if (iLevel<0). -** -** SQLITE_OK is returned if successful, otherwise an SQLite error code. -*/ -static int fts3DeleteSegdir( - Fts3Table *p, /* Virtual table handle */ - int iLangid, /* Language id */ - int iIndex, /* Index for p->aIndex */ - int iLevel, /* Level of %_segdir entries to delete */ - Fts3SegReader **apSegment, /* Array of SegReader objects */ - int nReader /* Size of array apSegment */ -){ - int rc = SQLITE_OK; /* Return Code */ - int i; /* Iterator variable */ - sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ - - for(i=0; rc==SQLITE_OK && i=0 || iLevel==FTS3_SEGCURSOR_ALL ); - if( iLevel==FTS3_SEGCURSOR_ALL ){ - rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); - sqlite3_bind_int64(pDelete, 2, - getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) - ); - } - }else{ - rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64( - pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) - ); - } - } - - if( rc==SQLITE_OK ){ - sqlite3_step(pDelete); - rc = sqlite3_reset(pDelete); - } - - return rc; -} - -/* -** When this function is called, buffer *ppList (size *pnList bytes) contains -** a position list that may (or may not) feature multiple columns. This -** function adjusts the pointer *ppList and the length *pnList so that they -** identify the subset of the position list that corresponds to column iCol. -** -** If there are no entries in the input position list for column iCol, then -** *pnList is set to zero before returning. -** -** If parameter bZero is non-zero, then any part of the input list following -** the end of the output list is zeroed before returning. -*/ -static void fts3ColumnFilter( - int iCol, /* Column to filter on */ - int bZero, /* Zero out anything following *ppList */ - char **ppList, /* IN/OUT: Pointer to position list */ - int *pnList /* IN/OUT: Size of buffer *ppList in bytes */ -){ - char *pList = *ppList; - int nList = *pnList; - char *pEnd = &pList[nList]; - int iCurrent = 0; - char *p = pList; - - assert( iCol>=0 ); - while( 1 ){ - char c = 0; - while( ppMsr->nBuffer ){ - char *pNew; - pMsr->nBuffer = nList*2; - pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); - if( !pNew ) return SQLITE_NOMEM; - pMsr->aBuffer = pNew; - } - - memcpy(pMsr->aBuffer, pList, nList); - return SQLITE_OK; -} - -SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( - Fts3Table *p, /* Virtual table handle */ - Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ - sqlite3_int64 *piDocid, /* OUT: Docid value */ - char **paPoslist, /* OUT: Pointer to position list */ - int *pnPoslist /* OUT: Size of position list in bytes */ -){ - int nMerge = pMsr->nAdvance; - Fts3SegReader **apSegment = pMsr->apSegment; - int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( - p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp - ); - - if( nMerge==0 ){ - *paPoslist = 0; - return SQLITE_OK; - } - - while( 1 ){ - Fts3SegReader *pSeg; - pSeg = pMsr->apSegment[0]; - - if( pSeg->pOffsetList==0 ){ - *paPoslist = 0; - break; - }else{ - int rc; - char *pList; - int nList; - int j; - sqlite3_int64 iDocid = apSegment[0]->iDocid; - - rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); - j = 1; - while( rc==SQLITE_OK - && jpOffsetList - && apSegment[j]->iDocid==iDocid - ){ - rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0); - j++; - } - if( rc!=SQLITE_OK ) return rc; - fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); - - if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pMsr, pList, nList+1); - if( rc!=SQLITE_OK ) return rc; - assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); - pList = pMsr->aBuffer; - } - - if( pMsr->iColFilter>=0 ){ - fts3ColumnFilter(pMsr->iColFilter, 1, &pList, &nList); - } - - if( nList>0 ){ - *paPoslist = pList; - *piDocid = iDocid; - *pnPoslist = nList; - break; - } - } - } - - return SQLITE_OK; -} - -static int fts3SegReaderStart( - Fts3Table *p, /* Virtual table handle */ - Fts3MultiSegReader *pCsr, /* Cursor object */ - const char *zTerm, /* Term searched for (or NULL) */ - int nTerm /* Length of zTerm in bytes */ -){ - int i; - int nSeg = pCsr->nSegment; - - /* If the Fts3SegFilter defines a specific term (or term prefix) to search - ** for, then advance each segment iterator until it points to a term of - ** equal or greater value than the specified term. This prevents many - ** unnecessary merge/sort operations for the case where single segment - ** b-tree leaf nodes contain more than one term. - */ - for(i=0; pCsr->bRestart==0 && inSegment; i++){ - int res = 0; - Fts3SegReader *pSeg = pCsr->apSegment[i]; - do { - int rc = fts3SegReaderNext(p, pSeg, 0); - if( rc!=SQLITE_OK ) return rc; - }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 ); - - if( pSeg->bLookup && res!=0 ){ - fts3SegReaderSetEof(pSeg); - } - } - fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); - - return SQLITE_OK; -} - -SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( - Fts3Table *p, /* Virtual table handle */ - Fts3MultiSegReader *pCsr, /* Cursor object */ - Fts3SegFilter *pFilter /* Restrictions on range of iteration */ -){ - pCsr->pFilter = pFilter; - return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); -} - -SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( - Fts3Table *p, /* Virtual table handle */ - Fts3MultiSegReader *pCsr, /* Cursor object */ - int iCol, /* Column to match on. */ - const char *zTerm, /* Term to iterate through a doclist for */ - int nTerm /* Number of bytes in zTerm */ -){ - int i; - int rc; - int nSegment = pCsr->nSegment; - int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( - p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp - ); - - assert( pCsr->pFilter==0 ); - assert( zTerm && nTerm>0 ); - - /* Advance each segment iterator until it points to the term zTerm/nTerm. */ - rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); - if( rc!=SQLITE_OK ) return rc; - - /* Determine how many of the segments actually point to zTerm/nTerm. */ - for(i=0; iapSegment[i]; - if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ - break; - } - } - pCsr->nAdvance = i; - - /* Advance each of the segments to point to the first docid. */ - for(i=0; inAdvance; i++){ - rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); - if( rc!=SQLITE_OK ) return rc; - } - fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); - - assert( iCol<0 || iColnColumn ); - pCsr->iColFilter = iCol; - - return SQLITE_OK; -} - -/* -** This function is called on a MultiSegReader that has been started using -** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also -** have been made. Calling this function puts the MultiSegReader in such -** a state that if the next two calls are: -** -** sqlite3Fts3SegReaderStart() -** sqlite3Fts3SegReaderStep() -** -** then the entire doclist for the term is available in -** MultiSegReader.aDoclist/nDoclist. -*/ -SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ - int i; /* Used to iterate through segment-readers */ - - assert( pCsr->zTerm==0 ); - assert( pCsr->nTerm==0 ); - assert( pCsr->aDoclist==0 ); - assert( pCsr->nDoclist==0 ); - - pCsr->nAdvance = 0; - pCsr->bRestart = 1; - for(i=0; inSegment; i++){ - pCsr->apSegment[i]->pOffsetList = 0; - pCsr->apSegment[i]->nOffsetList = 0; - pCsr->apSegment[i]->iDocid = 0; - } - - return SQLITE_OK; -} - - -SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( - Fts3Table *p, /* Virtual table handle */ - Fts3MultiSegReader *pCsr /* Cursor object */ -){ - int rc = SQLITE_OK; - - int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); - int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); - int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); - int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX); - int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN); - int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST); - - Fts3SegReader **apSegment = pCsr->apSegment; - int nSegment = pCsr->nSegment; - Fts3SegFilter *pFilter = pCsr->pFilter; - int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( - p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp - ); - - if( pCsr->nSegment==0 ) return SQLITE_OK; - - do { - int nMerge; - int i; - - /* Advance the first pCsr->nAdvance entries in the apSegment[] array - ** forward. Then sort the list in order of current term again. - */ - for(i=0; inAdvance; i++){ - Fts3SegReader *pSeg = apSegment[i]; - if( pSeg->bLookup ){ - fts3SegReaderSetEof(pSeg); - }else{ - rc = fts3SegReaderNext(p, pSeg, 0); - } - if( rc!=SQLITE_OK ) return rc; - } - fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); - pCsr->nAdvance = 0; - - /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */ - assert( rc==SQLITE_OK ); - if( apSegment[0]->aNode==0 ) break; - - pCsr->nTerm = apSegment[0]->nTerm; - pCsr->zTerm = apSegment[0]->zTerm; - - /* If this is a prefix-search, and if the term that apSegment[0] points - ** to does not share a suffix with pFilter->zTerm/nTerm, then all - ** required callbacks have been made. In this case exit early. - ** - ** Similarly, if this is a search for an exact match, and the first term - ** of segment apSegment[0] is not a match, exit early. - */ - if( pFilter->zTerm && !isScan ){ - if( pCsr->nTermnTerm - || (!isPrefix && pCsr->nTerm>pFilter->nTerm) - || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) - ){ - break; - } - } - - nMerge = 1; - while( nMergeaNode - && apSegment[nMerge]->nTerm==pCsr->nTerm - && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm) - ){ - nMerge++; - } - - assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); - if( nMerge==1 - && !isIgnoreEmpty - && !isFirst - && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) - ){ - pCsr->nDoclist = apSegment[0]->nDoclist; - if( fts3SegReaderIsPending(apSegment[0]) ){ - rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); - pCsr->aDoclist = pCsr->aBuffer; - }else{ - pCsr->aDoclist = apSegment[0]->aDoclist; - } - if( rc==SQLITE_OK ) rc = SQLITE_ROW; - }else{ - int nDoclist = 0; /* Size of doclist */ - sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ - - /* The current term of the first nMerge entries in the array - ** of Fts3SegReader objects is the same. The doclists must be merged - ** and a single term returned with the merged doclist. - */ - for(i=0; ipOffsetList ){ - int j; /* Number of segments that share a docid */ - char *pList = 0; - int nList = 0; - int nByte; - sqlite3_int64 iDocid = apSegment[0]->iDocid; - fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); - j = 1; - while( jpOffsetList - && apSegment[j]->iDocid==iDocid - ){ - fts3SegReaderNextDocid(p, apSegment[j], 0, 0); - j++; - } - - if( isColFilter ){ - fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList); - } - - if( !isIgnoreEmpty || nList>0 ){ - - /* Calculate the 'docid' delta value to write into the merged - ** doclist. */ - sqlite3_int64 iDelta; - if( p->bDescIdx && nDoclist>0 ){ - iDelta = iPrev - iDocid; - }else{ - iDelta = iDocid - iPrev; - } - assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) ); - assert( nDoclist>0 || iDelta==iDocid ); - - nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); - if( nDoclist+nByte>pCsr->nBuffer ){ - char *aNew; - pCsr->nBuffer = (nDoclist+nByte)*2; - aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); - if( !aNew ){ - return SQLITE_NOMEM; - } - pCsr->aBuffer = aNew; - } - - if( isFirst ){ - char *a = &pCsr->aBuffer[nDoclist]; - int nWrite; - - nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a); - if( nWrite ){ - iPrev = iDocid; - nDoclist += nWrite; - } - }else{ - nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); - iPrev = iDocid; - if( isRequirePos ){ - memcpy(&pCsr->aBuffer[nDoclist], pList, nList); - nDoclist += nList; - pCsr->aBuffer[nDoclist++] = '\0'; - } - } - } - - fts3SegReaderSort(apSegment, nMerge, j, xCmp); - } - if( nDoclist>0 ){ - pCsr->aDoclist = pCsr->aBuffer; - pCsr->nDoclist = nDoclist; - rc = SQLITE_ROW; - } - } - pCsr->nAdvance = nMerge; - }while( rc==SQLITE_OK ); - - return rc; -} - - -SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( - Fts3MultiSegReader *pCsr /* Cursor object */ -){ - if( pCsr ){ - int i; - for(i=0; inSegment; i++){ - sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); - } - sqlite3_free(pCsr->apSegment); - sqlite3_free(pCsr->aBuffer); - - pCsr->nSegment = 0; - pCsr->apSegment = 0; - pCsr->aBuffer = 0; - } -} - -/* -** Decode the "end_block" field, selected by column iCol of the SELECT -** statement passed as the first argument. -** -** The "end_block" field may contain either an integer, or a text field -** containing the text representation of two non-negative integers separated -** by one or more space (0x20) characters. In the first case, set *piEndBlock -** to the integer value and *pnByte to zero before returning. In the second, -** set *piEndBlock to the first value and *pnByte to the second. -*/ -static void fts3ReadEndBlockField( - sqlite3_stmt *pStmt, - int iCol, - i64 *piEndBlock, - i64 *pnByte -){ - const unsigned char *zText = sqlite3_column_text(pStmt, iCol); - if( zText ){ - int i; - int iMul = 1; - i64 iVal = 0; - for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ - iVal = iVal*10 + (zText[i] - '0'); - } - *piEndBlock = iVal; - while( zText[i]==' ' ) i++; - iVal = 0; - if( zText[i]=='-' ){ - i++; - iMul = -1; - } - for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ - iVal = iVal*10 + (zText[i] - '0'); - } - *pnByte = (iVal * (i64)iMul); - } -} - - -/* -** A segment of size nByte bytes has just been written to absolute level -** iAbsLevel. Promote any segments that should be promoted as a result. -*/ -static int fts3PromoteSegments( - Fts3Table *p, /* FTS table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level just updated */ - sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ -){ - int rc = SQLITE_OK; - sqlite3_stmt *pRange; - - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); - - if( rc==SQLITE_OK ){ - int bOk = 0; - i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; - i64 nLimit = (nByte*3)/2; - - /* Loop through all entries in the %_segdir table corresponding to - ** segments in this index on levels greater than iAbsLevel. If there is - ** at least one such segment, and it is possible to determine that all - ** such segments are smaller than nLimit bytes in size, they will be - ** promoted to level iAbsLevel. */ - sqlite3_bind_int64(pRange, 1, iAbsLevel+1); - sqlite3_bind_int64(pRange, 2, iLast); - while( SQLITE_ROW==sqlite3_step(pRange) ){ - i64 nSize = 0, dummy; - fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); - if( nSize<=0 || nSize>nLimit ){ - /* If nSize==0, then the %_segdir.end_block field does not not - ** contain a size value. This happens if it was written by an - ** old version of FTS. In this case it is not possible to determine - ** the size of the segment, and so segment promotion does not - ** take place. */ - bOk = 0; - break; - } - bOk = 1; - } - rc = sqlite3_reset(pRange); - - if( bOk ){ - int iIdx = 0; - sqlite3_stmt *pUpdate1 = 0; - sqlite3_stmt *pUpdate2 = 0; - - if( rc==SQLITE_OK ){ - rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); - } - if( rc==SQLITE_OK ){ - rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); - } - - if( rc==SQLITE_OK ){ - - /* Loop through all %_segdir entries for segments in this index with - ** levels equal to or greater than iAbsLevel. As each entry is visited, - ** updated it to set (level = -1) and (idx = N), where N is 0 for the - ** oldest segment in the range, 1 for the next oldest, and so on. - ** - ** In other words, move all segments being promoted to level -1, - ** setting the "idx" fields as appropriate to keep them in the same - ** order. The contents of level -1 (which is never used, except - ** transiently here), will be moved back to level iAbsLevel below. */ - sqlite3_bind_int64(pRange, 1, iAbsLevel); - while( SQLITE_ROW==sqlite3_step(pRange) ){ - sqlite3_bind_int(pUpdate1, 1, iIdx++); - sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); - sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); - sqlite3_step(pUpdate1); - rc = sqlite3_reset(pUpdate1); - if( rc!=SQLITE_OK ){ - sqlite3_reset(pRange); - break; - } - } - } - if( rc==SQLITE_OK ){ - rc = sqlite3_reset(pRange); - } - - /* Move level -1 to level iAbsLevel */ - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); - sqlite3_step(pUpdate2); - rc = sqlite3_reset(pUpdate2); - } - } - } - - - return rc; -} - -/* -** Merge all level iLevel segments in the database into a single -** iLevel+1 segment. Or, if iLevel<0, merge all segments into a -** single segment with a level equal to the numerically largest level -** currently present in the database. -** -** If this function is called with iLevel<0, but there is only one -** segment in the database, SQLITE_DONE is returned immediately. -** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, -** an SQLite error code is returned. -*/ -static int fts3SegmentMerge( - Fts3Table *p, - int iLangid, /* Language id to merge */ - int iIndex, /* Index in p->aIndex[] to merge */ - int iLevel /* Level to merge */ -){ - int rc; /* Return code */ - int iIdx = 0; /* Index of new segment */ - sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ - SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ - Fts3SegFilter filter; /* Segment term filter condition */ - Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ - int bIgnoreEmpty = 0; /* True to ignore empty segments */ - i64 iMaxLevel = 0; /* Max level number for this index/langid */ - - assert( iLevel==FTS3_SEGCURSOR_ALL - || iLevel==FTS3_SEGCURSOR_PENDING - || iLevel>=0 - ); - assert( iLevel=0 && iIndexnIndex ); - - rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); - if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; - - if( iLevel!=FTS3_SEGCURSOR_PENDING ){ - rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); - if( rc!=SQLITE_OK ) goto finished; - } - - if( iLevel==FTS3_SEGCURSOR_ALL ){ - /* This call is to merge all segments in the database to a single - ** segment. The level of the new segment is equal to the numerically - ** greatest segment level currently present in the database for this - ** index. The idx of the new segment is always 0. */ - if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){ - rc = SQLITE_DONE; - goto finished; - } - iNewLevel = iMaxLevel; - bIgnoreEmpty = 1; - - }else{ - /* This call is to merge all segments at level iLevel. find the next - ** available segment index at level iLevel+1. The call to - ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to - ** a single iLevel+2 segment if necessary. */ - assert( FTS3_SEGCURSOR_PENDING==-1 ); - iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); - rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); - bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); - } - if( rc!=SQLITE_OK ) goto finished; - - assert( csr.nSegment>0 ); - assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); - assert( iNewLevelnLeafData); - } - } - } - - finished: - fts3SegWriterFree(pWriter); - sqlite3Fts3SegReaderFinish(&csr); - return rc; -} - - -/* -** Flush the contents of pendingTerms to level 0 segments. -*/ -SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ - int rc = SQLITE_OK; - int i; - - for(i=0; rc==SQLITE_OK && inIndex; i++){ - rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); - if( rc==SQLITE_DONE ) rc = SQLITE_OK; - } - sqlite3Fts3PendingTermsClear(p); - - /* Determine the auto-incr-merge setting if unknown. If enabled, - ** estimate the number of leaf blocks of content to be written - */ - if( rc==SQLITE_OK && p->bHasStat - && p->nAutoincrmerge==0xff && p->nLeafAdd>0 - ){ - sqlite3_stmt *pStmt = 0; - rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); - rc = sqlite3_step(pStmt); - if( rc==SQLITE_ROW ){ - p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); - if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; - }else if( rc==SQLITE_DONE ){ - p->nAutoincrmerge = 0; - } - rc = sqlite3_reset(pStmt); - } - } - return rc; -} - -/* -** Encode N integers as varints into a blob. -*/ -static void fts3EncodeIntArray( - int N, /* The number of integers to encode */ - u32 *a, /* The integer values */ - char *zBuf, /* Write the BLOB here */ - int *pNBuf /* Write number of bytes if zBuf[] used here */ -){ - int i, j; - for(i=j=0; iiPrevDocid. The sizes are encoded as -** a blob of varints. -*/ -static void fts3InsertDocsize( - int *pRC, /* Result code */ - Fts3Table *p, /* Table into which to insert */ - u32 *aSz /* Sizes of each column, in tokens */ -){ - char *pBlob; /* The BLOB encoding of the document size */ - int nBlob; /* Number of bytes in the BLOB */ - sqlite3_stmt *pStmt; /* Statement used to insert the encoding */ - int rc; /* Result code from subfunctions */ - - if( *pRC ) return; - pBlob = sqlite3_malloc( 10*p->nColumn ); - if( pBlob==0 ){ - *pRC = SQLITE_NOMEM; - return; - } - fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob); - rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0); - if( rc ){ - sqlite3_free(pBlob); - *pRC = rc; - return; - } - sqlite3_bind_int64(pStmt, 1, p->iPrevDocid); - sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free); - sqlite3_step(pStmt); - *pRC = sqlite3_reset(pStmt); -} - -/* -** Record 0 of the %_stat table contains a blob consisting of N varints, -** where N is the number of user defined columns in the fts3 table plus -** two. If nCol is the number of user defined columns, then values of the -** varints are set as follows: -** -** Varint 0: Total number of rows in the table. -** -** Varint 1..nCol: For each column, the total number of tokens stored in -** the column for all rows of the table. -** -** Varint 1+nCol: The total size, in bytes, of all text values in all -** columns of all rows of the table. -** -*/ -static void fts3UpdateDocTotals( - int *pRC, /* The result code */ - Fts3Table *p, /* Table being updated */ - u32 *aSzIns, /* Size increases */ - u32 *aSzDel, /* Size decreases */ - int nChng /* Change in the number of documents */ -){ - char *pBlob; /* Storage for BLOB written into %_stat */ - int nBlob; /* Size of BLOB written into %_stat */ - u32 *a; /* Array of integers that becomes the BLOB */ - sqlite3_stmt *pStmt; /* Statement for reading and writing */ - int i; /* Loop counter */ - int rc; /* Result code from subfunctions */ - - const int nStat = p->nColumn+2; - - if( *pRC ) return; - a = sqlite3_malloc( (sizeof(u32)+10)*nStat ); - if( a==0 ){ - *pRC = SQLITE_NOMEM; - return; - } - pBlob = (char*)&a[nStat]; - rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); - if( rc ){ - sqlite3_free(a); - *pRC = rc; - return; - } - sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); - if( sqlite3_step(pStmt)==SQLITE_ROW ){ - fts3DecodeIntArray(nStat, a, - sqlite3_column_blob(pStmt, 0), - sqlite3_column_bytes(pStmt, 0)); - }else{ - memset(a, 0, sizeof(u32)*(nStat) ); - } - rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ){ - sqlite3_free(a); - *pRC = rc; - return; - } - if( nChng<0 && a[0]<(u32)(-nChng) ){ - a[0] = 0; - }else{ - a[0] += nChng; - } - for(i=0; inColumn+1; i++){ - u32 x = a[i+1]; - if( x+aSzIns[i] < aSzDel[i] ){ - x = 0; - }else{ - x = x + aSzIns[i] - aSzDel[i]; - } - a[i+1] = x; - } - fts3EncodeIntArray(nStat, a, pBlob, &nBlob); - rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); - if( rc ){ - sqlite3_free(a); - *pRC = rc; - return; - } - sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); - sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); - sqlite3_step(pStmt); - *pRC = sqlite3_reset(pStmt); - sqlite3_free(a); -} - -/* -** Merge the entire database so that there is one segment for each -** iIndex/iLangid combination. -*/ -static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ - int bSeenDone = 0; - int rc; - sqlite3_stmt *pAllLangid = 0; - - rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); - if( rc==SQLITE_OK ){ - int rc2; - sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); - sqlite3_bind_int(pAllLangid, 2, p->nIndex); - while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ - int i; - int iLangid = sqlite3_column_int(pAllLangid, 0); - for(i=0; rc==SQLITE_OK && inIndex; i++){ - rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); - if( rc==SQLITE_DONE ){ - bSeenDone = 1; - rc = SQLITE_OK; - } - } - } - rc2 = sqlite3_reset(pAllLangid); - if( rc==SQLITE_OK ) rc = rc2; - } - - sqlite3Fts3SegmentsClose(p); - sqlite3Fts3PendingTermsClear(p); - - return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; -} - -/* -** This function is called when the user executes the following statement: -** -** INSERT INTO () VALUES('rebuild'); -** -** The entire FTS index is discarded and rebuilt. If the table is one -** created using the content=xxx option, then the new index is based on -** the current contents of the xxx table. Otherwise, it is rebuilt based -** on the contents of the %_content table. -*/ -static int fts3DoRebuild(Fts3Table *p){ - int rc; /* Return Code */ - - rc = fts3DeleteAll(p, 0); - if( rc==SQLITE_OK ){ - u32 *aSz = 0; - u32 *aSzIns = 0; - u32 *aSzDel = 0; - sqlite3_stmt *pStmt = 0; - int nEntry = 0; - - /* Compose and prepare an SQL statement to loop through the content table */ - char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - } - - if( rc==SQLITE_OK ){ - int nByte = sizeof(u32) * (p->nColumn+1)*3; - aSz = (u32 *)sqlite3_malloc(nByte); - if( aSz==0 ){ - rc = SQLITE_NOMEM; - }else{ - memset(aSz, 0, nByte); - aSzIns = &aSz[p->nColumn+1]; - aSzDel = &aSzIns[p->nColumn+1]; - } - } - - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - int iCol; - int iLangid = langidFromSelect(p, pStmt); - rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0)); - memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); - for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ - if( p->abNotindexed[iCol]==0 ){ - const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); - rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); - aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); - } - } - if( p->bHasDocsize ){ - fts3InsertDocsize(&rc, p, aSz); - } - if( rc!=SQLITE_OK ){ - sqlite3_finalize(pStmt); - pStmt = 0; - }else{ - nEntry++; - for(iCol=0; iCol<=p->nColumn; iCol++){ - aSzIns[iCol] += aSz[iCol]; - } - } - } - if( p->bFts4 ){ - fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); - } - sqlite3_free(aSz); - - if( pStmt ){ - int rc2 = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - - return rc; -} - - -/* -** This function opens a cursor used to read the input data for an -** incremental merge operation. Specifically, it opens a cursor to scan -** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute -** level iAbsLevel. -*/ -static int fts3IncrmergeCsr( - Fts3Table *p, /* FTS3 table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level to open */ - int nSeg, /* Number of segments to merge */ - Fts3MultiSegReader *pCsr /* Cursor object to populate */ -){ - int rc; /* Return Code */ - sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ - int nByte; /* Bytes allocated at pCsr->apSegment[] */ - - /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ - memset(pCsr, 0, sizeof(*pCsr)); - nByte = sizeof(Fts3SegReader *) * nSeg; - pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte); - - if( pCsr->apSegment==0 ){ - rc = SQLITE_NOMEM; - }else{ - memset(pCsr->apSegment, 0, nByte); - rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); - } - if( rc==SQLITE_OK ){ - int i; - int rc2; - sqlite3_bind_int64(pStmt, 1, iAbsLevel); - assert( pCsr->nSegment==0 ); - for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && iapSegment[i] - ); - pCsr->nSegment++; - } - rc2 = sqlite3_reset(pStmt); - if( rc==SQLITE_OK ) rc = rc2; - } - - return rc; -} - -typedef struct IncrmergeWriter IncrmergeWriter; -typedef struct NodeWriter NodeWriter; -typedef struct Blob Blob; -typedef struct NodeReader NodeReader; - -/* -** An instance of the following structure is used as a dynamic buffer -** to build up nodes or other blobs of data in. -** -** The function blobGrowBuffer() is used to extend the allocation. -*/ -struct Blob { - char *a; /* Pointer to allocation */ - int n; /* Number of valid bytes of data in a[] */ - int nAlloc; /* Allocated size of a[] (nAlloc>=n) */ -}; - -/* -** This structure is used to build up buffers containing segment b-tree -** nodes (blocks). -*/ -struct NodeWriter { - sqlite3_int64 iBlock; /* Current block id */ - Blob key; /* Last key written to the current block */ - Blob block; /* Current block image */ -}; - -/* -** An object of this type contains the state required to create or append -** to an appendable b-tree segment. -*/ -struct IncrmergeWriter { - int nLeafEst; /* Space allocated for leaf blocks */ - int nWork; /* Number of leaf pages flushed */ - sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ - int iIdx; /* Index of *output* segment in iAbsLevel+1 */ - sqlite3_int64 iStart; /* Block number of first allocated block */ - sqlite3_int64 iEnd; /* Block number of last allocated block */ - sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ - u8 bNoLeafData; /* If true, store 0 for segment size */ - NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; -}; - -/* -** An object of the following type is used to read data from a single -** FTS segment node. See the following functions: -** -** nodeReaderInit() -** nodeReaderNext() -** nodeReaderRelease() -*/ -struct NodeReader { - const char *aNode; - int nNode; - int iOff; /* Current offset within aNode[] */ - - /* Output variables. Containing the current node entry. */ - sqlite3_int64 iChild; /* Pointer to child node */ - Blob term; /* Current term */ - const char *aDoclist; /* Pointer to doclist */ - int nDoclist; /* Size of doclist in bytes */ -}; - -/* -** If *pRc is not SQLITE_OK when this function is called, it is a no-op. -** Otherwise, if the allocation at pBlob->a is not already at least nMin -** bytes in size, extend (realloc) it to be so. -** -** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a -** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc -** to reflect the new size of the pBlob->a[] buffer. -*/ -static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ - if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ - int nAlloc = nMin; - char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); - if( a ){ - pBlob->nAlloc = nAlloc; - pBlob->a = a; - }else{ - *pRc = SQLITE_NOMEM; - } - } -} - -/* -** Attempt to advance the node-reader object passed as the first argument to -** the next entry on the node. -** -** Return an error code if an error occurs (SQLITE_NOMEM is possible). -** Otherwise return SQLITE_OK. If there is no next entry on the node -** (e.g. because the current entry is the last) set NodeReader->aNode to -** NULL to indicate EOF. Otherwise, populate the NodeReader structure output -** variables for the new entry. -*/ -static int nodeReaderNext(NodeReader *p){ - int bFirst = (p->term.n==0); /* True for first term on the node */ - int nPrefix = 0; /* Bytes to copy from previous term */ - int nSuffix = 0; /* Bytes to append to the prefix */ - int rc = SQLITE_OK; /* Return code */ - - assert( p->aNode ); - if( p->iChild && bFirst==0 ) p->iChild++; - if( p->iOff>=p->nNode ){ - /* EOF */ - p->aNode = 0; - }else{ - if( bFirst==0 ){ - p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); - } - p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); - - blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); - if( rc==SQLITE_OK ){ - memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); - p->term.n = nPrefix+nSuffix; - p->iOff += nSuffix; - if( p->iChild==0 ){ - p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); - p->aDoclist = &p->aNode[p->iOff]; - p->iOff += p->nDoclist; - } - } - } - - assert( p->iOff<=p->nNode ); - - return rc; -} - -/* -** Release all dynamic resources held by node-reader object *p. -*/ -static void nodeReaderRelease(NodeReader *p){ - sqlite3_free(p->term.a); -} - -/* -** Initialize a node-reader object to read the node in buffer aNode/nNode. -** -** If successful, SQLITE_OK is returned and the NodeReader object set to -** point to the first entry on the node (if any). Otherwise, an SQLite -** error code is returned. -*/ -static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ - memset(p, 0, sizeof(NodeReader)); - p->aNode = aNode; - p->nNode = nNode; - - /* Figure out if this is a leaf or an internal node. */ - if( p->aNode[0] ){ - /* An internal node. */ - p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); - }else{ - p->iOff = 1; - } - - return nodeReaderNext(p); -} - -/* -** This function is called while writing an FTS segment each time a leaf o -** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed -** to be greater than the largest key on the node just written, but smaller -** than or equal to the first key that will be written to the next leaf -** node. -** -** The block id of the leaf node just written to disk may be found in -** (pWriter->aNodeWriter[0].iBlock) when this function is called. -*/ -static int fts3IncrmergePush( - Fts3Table *p, /* Fts3 table handle */ - IncrmergeWriter *pWriter, /* Writer object */ - const char *zTerm, /* Term to write to internal node */ - int nTerm /* Bytes at zTerm */ -){ - sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; - int iLayer; - - assert( nTerm>0 ); - for(iLayer=1; ALWAYS(iLayeraNodeWriter[iLayer]; - int rc = SQLITE_OK; - int nPrefix; - int nSuffix; - int nSpace; - - /* Figure out how much space the key will consume if it is written to - ** the current node of layer iLayer. Due to the prefix compression, - ** the space required changes depending on which node the key is to - ** be added to. */ - nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); - nSuffix = nTerm - nPrefix; - nSpace = sqlite3Fts3VarintLen(nPrefix); - nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; - - if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ - /* If the current node of layer iLayer contains zero keys, or if adding - ** the key to it will not cause it to grow to larger than nNodeSize - ** bytes in size, write the key here. */ - - Blob *pBlk = &pNode->block; - if( pBlk->n==0 ){ - blobGrowBuffer(pBlk, p->nNodeSize, &rc); - if( rc==SQLITE_OK ){ - pBlk->a[0] = (char)iLayer; - pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); - } - } - blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); - blobGrowBuffer(&pNode->key, nTerm, &rc); - - if( rc==SQLITE_OK ){ - if( pNode->key.n ){ - pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); - } - pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); - memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); - pBlk->n += nSuffix; - - memcpy(pNode->key.a, zTerm, nTerm); - pNode->key.n = nTerm; - } - }else{ - /* Otherwise, flush the current node of layer iLayer to disk. - ** Then allocate a new, empty sibling node. The key will be written - ** into the parent of this node. */ - rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); - - assert( pNode->block.nAlloc>=p->nNodeSize ); - pNode->block.a[0] = (char)iLayer; - pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); - - iNextPtr = pNode->iBlock; - pNode->iBlock++; - pNode->key.n = 0; - } - - if( rc!=SQLITE_OK || iNextPtr==0 ) return rc; - iPtr = iNextPtr; - } - - assert( 0 ); - return 0; -} - -/* -** Append a term and (optionally) doclist to the FTS segment node currently -** stored in blob *pNode. The node need not contain any terms, but the -** header must be written before this function is called. -** -** A node header is a single 0x00 byte for a leaf node, or a height varint -** followed by the left-hand-child varint for an internal node. -** -** The term to be appended is passed via arguments zTerm/nTerm. For a -** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal -** node, both aDoclist and nDoclist must be passed 0. -** -** If the size of the value in blob pPrev is zero, then this is the first -** term written to the node. Otherwise, pPrev contains a copy of the -** previous term. Before this function returns, it is updated to contain a -** copy of zTerm/nTerm. -** -** It is assumed that the buffer associated with pNode is already large -** enough to accommodate the new entry. The buffer associated with pPrev -** is extended by this function if requrired. -** -** If an error (i.e. OOM condition) occurs, an SQLite error code is -** returned. Otherwise, SQLITE_OK. -*/ -static int fts3AppendToNode( - Blob *pNode, /* Current node image to append to */ - Blob *pPrev, /* Buffer containing previous term written */ - const char *zTerm, /* New term to write */ - int nTerm, /* Size of zTerm in bytes */ - const char *aDoclist, /* Doclist (or NULL) to write */ - int nDoclist /* Size of aDoclist in bytes */ -){ - int rc = SQLITE_OK; /* Return code */ - int bFirst = (pPrev->n==0); /* True if this is the first term written */ - int nPrefix; /* Size of term prefix in bytes */ - int nSuffix; /* Size of term suffix in bytes */ - - /* Node must have already been started. There must be a doclist for a - ** leaf node, and there must not be a doclist for an internal node. */ - assert( pNode->n>0 ); - assert( (pNode->a[0]=='\0')==(aDoclist!=0) ); - - blobGrowBuffer(pPrev, nTerm, &rc); - if( rc!=SQLITE_OK ) return rc; - - nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); - nSuffix = nTerm - nPrefix; - memcpy(pPrev->a, zTerm, nTerm); - pPrev->n = nTerm; - - if( bFirst==0 ){ - pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); - } - pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); - memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); - pNode->n += nSuffix; - - if( aDoclist ){ - pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); - memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); - pNode->n += nDoclist; - } - - assert( pNode->n<=pNode->nAlloc ); - - return SQLITE_OK; -} - -/* -** Append the current term and doclist pointed to by cursor pCsr to the -** appendable b-tree segment opened for writing by pWriter. -** -** Return SQLITE_OK if successful, or an SQLite error code otherwise. -*/ -static int fts3IncrmergeAppend( - Fts3Table *p, /* Fts3 table handle */ - IncrmergeWriter *pWriter, /* Writer object */ - Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */ -){ - const char *zTerm = pCsr->zTerm; - int nTerm = pCsr->nTerm; - const char *aDoclist = pCsr->aDoclist; - int nDoclist = pCsr->nDoclist; - int rc = SQLITE_OK; /* Return code */ - int nSpace; /* Total space in bytes required on leaf */ - int nPrefix; /* Size of prefix shared with previous term */ - int nSuffix; /* Size of suffix (nTerm - nPrefix) */ - NodeWriter *pLeaf; /* Object used to write leaf nodes */ - - pLeaf = &pWriter->aNodeWriter[0]; - nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); - nSuffix = nTerm - nPrefix; - - nSpace = sqlite3Fts3VarintLen(nPrefix); - nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; - nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; - - /* If the current block is not empty, and if adding this term/doclist - ** to the current block would make it larger than Fts3Table.nNodeSize - ** bytes, write this block out to the database. */ - if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ - rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); - pWriter->nWork++; - - /* Add the current term to the parent node. The term added to the - ** parent must: - ** - ** a) be greater than the largest term on the leaf node just written - ** to the database (still available in pLeaf->key), and - ** - ** b) be less than or equal to the term about to be added to the new - ** leaf node (zTerm/nTerm). - ** - ** In other words, it must be the prefix of zTerm 1 byte longer than - ** the common prefix (if any) of zTerm and pWriter->zTerm. - */ - if( rc==SQLITE_OK ){ - rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1); - } - - /* Advance to the next output block */ - pLeaf->iBlock++; - pLeaf->key.n = 0; - pLeaf->block.n = 0; - - nSuffix = nTerm; - nSpace = 1; - nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; - nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; - } - - pWriter->nLeafData += nSpace; - blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); - if( rc==SQLITE_OK ){ - if( pLeaf->block.n==0 ){ - pLeaf->block.n = 1; - pLeaf->block.a[0] = '\0'; - } - rc = fts3AppendToNode( - &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist - ); - } - - return rc; -} - -/* -** This function is called to release all dynamic resources held by the -** merge-writer object pWriter, and if no error has occurred, to flush -** all outstanding node buffers held by pWriter to disk. -** -** If *pRc is not SQLITE_OK when this function is called, then no attempt -** is made to write any data to disk. Instead, this function serves only -** to release outstanding resources. -** -** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while -** flushing buffers to disk, *pRc is set to an SQLite error code before -** returning. -*/ -static void fts3IncrmergeRelease( - Fts3Table *p, /* FTS3 table handle */ - IncrmergeWriter *pWriter, /* Merge-writer object */ - int *pRc /* IN/OUT: Error code */ -){ - int i; /* Used to iterate through non-root layers */ - int iRoot; /* Index of root in pWriter->aNodeWriter */ - NodeWriter *pRoot; /* NodeWriter for root node */ - int rc = *pRc; /* Error code */ - - /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment - ** root node. If the segment fits entirely on a single leaf node, iRoot - ** will be set to 0. If the root node is the parent of the leaves, iRoot - ** will be 1. And so on. */ - for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){ - NodeWriter *pNode = &pWriter->aNodeWriter[iRoot]; - if( pNode->block.n>0 ) break; - assert( *pRc || pNode->block.nAlloc==0 ); - assert( *pRc || pNode->key.nAlloc==0 ); - sqlite3_free(pNode->block.a); - sqlite3_free(pNode->key.a); - } - - /* Empty output segment. This is a no-op. */ - if( iRoot<0 ) return; - - /* The entire output segment fits on a single node. Normally, this means - ** the node would be stored as a blob in the "root" column of the %_segdir - ** table. However, this is not permitted in this case. The problem is that - ** space has already been reserved in the %_segments table, and so the - ** start_block and end_block fields of the %_segdir table must be populated. - ** And, by design or by accident, released versions of FTS cannot handle - ** segments that fit entirely on the root node with start_block!=0. - ** - ** Instead, create a synthetic root node that contains nothing but a - ** pointer to the single content node. So that the segment consists of a - ** single leaf and a single interior (root) node. - ** - ** Todo: Better might be to defer allocating space in the %_segments - ** table until we are sure it is needed. - */ - if( iRoot==0 ){ - Blob *pBlock = &pWriter->aNodeWriter[1].block; - blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); - if( rc==SQLITE_OK ){ - pBlock->a[0] = 0x01; - pBlock->n = 1 + sqlite3Fts3PutVarint( - &pBlock->a[1], pWriter->aNodeWriter[0].iBlock - ); - } - iRoot = 1; - } - pRoot = &pWriter->aNodeWriter[iRoot]; - - /* Flush all currently outstanding nodes to disk. */ - for(i=0; iaNodeWriter[i]; - if( pNode->block.n>0 && rc==SQLITE_OK ){ - rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); - } - sqlite3_free(pNode->block.a); - sqlite3_free(pNode->key.a); - } - - /* Write the %_segdir record. */ - if( rc==SQLITE_OK ){ - rc = fts3WriteSegdir(p, - pWriter->iAbsLevel+1, /* level */ - pWriter->iIdx, /* idx */ - pWriter->iStart, /* start_block */ - pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ - pWriter->iEnd, /* end_block */ - (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ - pRoot->block.a, pRoot->block.n /* root */ - ); - } - sqlite3_free(pRoot->block.a); - sqlite3_free(pRoot->key.a); - - *pRc = rc; -} - -/* -** Compare the term in buffer zLhs (size in bytes nLhs) with that in -** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of -** the other, it is considered to be smaller than the other. -** -** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve -** if it is greater. -*/ -static int fts3TermCmp( - const char *zLhs, int nLhs, /* LHS of comparison */ - const char *zRhs, int nRhs /* RHS of comparison */ -){ - int nCmp = MIN(nLhs, nRhs); - int res; - - res = memcmp(zLhs, zRhs, nCmp); - if( res==0 ) res = nLhs - nRhs; - - return res; -} - - -/* -** Query to see if the entry in the %_segments table with blockid iEnd is -** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before -** returning. Otherwise, set *pbRes to 0. -** -** Or, if an error occurs while querying the database, return an SQLite -** error code. The final value of *pbRes is undefined in this case. -** -** This is used to test if a segment is an "appendable" segment. If it -** is, then a NULL entry has been inserted into the %_segments table -** with blockid %_segdir.end_block. -*/ -static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ - int bRes = 0; /* Result to set *pbRes to */ - sqlite3_stmt *pCheck = 0; /* Statement to query database with */ - int rc; /* Return code */ - - rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pCheck, 1, iEnd); - if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; - rc = sqlite3_reset(pCheck); - } - - *pbRes = bRes; - return rc; -} - -/* -** This function is called when initializing an incremental-merge operation. -** It checks if the existing segment with index value iIdx at absolute level -** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the -** merge-writer object *pWriter is initialized to write to it. -** -** An existing segment can be appended to by an incremental merge if: -** -** * It was initially created as an appendable segment (with all required -** space pre-allocated), and -** -** * The first key read from the input (arguments zKey and nKey) is -** greater than the largest key currently stored in the potential -** output segment. -*/ -static int fts3IncrmergeLoad( - Fts3Table *p, /* Fts3 table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ - int iIdx, /* Index of candidate output segment */ - const char *zKey, /* First key to write */ - int nKey, /* Number of bytes in nKey */ - IncrmergeWriter *pWriter /* Populate this object */ -){ - int rc; /* Return code */ - sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ - - rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); - if( rc==SQLITE_OK ){ - sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ - sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ - sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ - const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ - int nRoot = 0; /* Size of aRoot[] in bytes */ - int rc2; /* Return code from sqlite3_reset() */ - int bAppendable = 0; /* Set to true if segment is appendable */ - - /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ - sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); - sqlite3_bind_int(pSelect, 2, iIdx); - if( sqlite3_step(pSelect)==SQLITE_ROW ){ - iStart = sqlite3_column_int64(pSelect, 1); - iLeafEnd = sqlite3_column_int64(pSelect, 2); - fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); - if( pWriter->nLeafData<0 ){ - pWriter->nLeafData = pWriter->nLeafData * -1; - } - pWriter->bNoLeafData = (pWriter->nLeafData==0); - nRoot = sqlite3_column_bytes(pSelect, 4); - aRoot = sqlite3_column_blob(pSelect, 4); - }else{ - return sqlite3_reset(pSelect); - } - - /* Check for the zero-length marker in the %_segments table */ - rc = fts3IsAppendable(p, iEnd, &bAppendable); - - /* Check that zKey/nKey is larger than the largest key the candidate */ - if( rc==SQLITE_OK && bAppendable ){ - char *aLeaf = 0; - int nLeaf = 0; - - rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); - if( rc==SQLITE_OK ){ - NodeReader reader; - for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); - rc==SQLITE_OK && reader.aNode; - rc = nodeReaderNext(&reader) - ){ - assert( reader.aNode ); - } - if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){ - bAppendable = 0; - } - nodeReaderRelease(&reader); - } - sqlite3_free(aLeaf); - } - - if( rc==SQLITE_OK && bAppendable ){ - /* It is possible to append to this segment. Set up the IncrmergeWriter - ** object to do so. */ - int i; - int nHeight = (int)aRoot[0]; - NodeWriter *pNode; - - pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; - pWriter->iStart = iStart; - pWriter->iEnd = iEnd; - pWriter->iAbsLevel = iAbsLevel; - pWriter->iIdx = iIdx; - - for(i=nHeight+1; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; - } - - pNode = &pWriter->aNodeWriter[nHeight]; - pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight; - blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc); - if( rc==SQLITE_OK ){ - memcpy(pNode->block.a, aRoot, nRoot); - pNode->block.n = nRoot; - } - - for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ - NodeReader reader; - pNode = &pWriter->aNodeWriter[i]; - - rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n); - while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); - blobGrowBuffer(&pNode->key, reader.term.n, &rc); - if( rc==SQLITE_OK ){ - memcpy(pNode->key.a, reader.term.a, reader.term.n); - pNode->key.n = reader.term.n; - if( i>0 ){ - char *aBlock = 0; - int nBlock = 0; - pNode = &pWriter->aNodeWriter[i-1]; - pNode->iBlock = reader.iChild; - rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); - blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc); - if( rc==SQLITE_OK ){ - memcpy(pNode->block.a, aBlock, nBlock); - pNode->block.n = nBlock; - } - sqlite3_free(aBlock); - } - } - nodeReaderRelease(&reader); - } - } - - rc2 = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ) rc = rc2; - } - - return rc; -} - -/* -** Determine the largest segment index value that exists within absolute -** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus -** one before returning SQLITE_OK. Or, if there are no segments at all -** within level iAbsLevel, set *piIdx to zero. -** -** If an error occurs, return an SQLite error code. The final value of -** *piIdx is undefined in this case. -*/ -static int fts3IncrmergeOutputIdx( - Fts3Table *p, /* FTS Table handle */ - sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ - int *piIdx /* OUT: Next free index at iAbsLevel+1 */ -){ - int rc; - sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ - - rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); - sqlite3_step(pOutputIdx); - *piIdx = sqlite3_column_int(pOutputIdx, 0); - rc = sqlite3_reset(pOutputIdx); - } - - return rc; -} - -/* -** Allocate an appendable output segment on absolute level iAbsLevel+1 -** with idx value iIdx. -** -** In the %_segdir table, a segment is defined by the values in three -** columns: -** -** start_block -** leaves_end_block -** end_block -** -** When an appendable segment is allocated, it is estimated that the -** maximum number of leaf blocks that may be required is the sum of the -** number of leaf blocks consumed by the input segments, plus the number -** of input segments, multiplied by two. This value is stored in stack -** variable nLeafEst. -** -** A total of 16*nLeafEst blocks are allocated when an appendable segment -** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous -** array of leaf nodes starts at the first block allocated. The array -** of interior nodes that are parents of the leaf nodes start at block -** (start_block + (1 + end_block - start_block) / 16). And so on. -** -** In the actual code below, the value "16" is replaced with the -** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT. -*/ -static int fts3IncrmergeWriter( - Fts3Table *p, /* Fts3 table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ - int iIdx, /* Index of new output segment */ - Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ - IncrmergeWriter *pWriter /* Populate this object */ -){ - int rc; /* Return Code */ - int i; /* Iterator variable */ - int nLeafEst = 0; /* Blocks allocated for leaf nodes */ - sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ - sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ - - /* Calculate nLeafEst. */ - rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); - sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); - if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ - nLeafEst = sqlite3_column_int(pLeafEst, 0); - } - rc = sqlite3_reset(pLeafEst); - } - if( rc!=SQLITE_OK ) return rc; - - /* Calculate the first block to use in the output segment */ - rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); - if( rc==SQLITE_OK ){ - if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ - pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); - pWriter->iEnd = pWriter->iStart - 1; - pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; - } - rc = sqlite3_reset(pFirstBlock); - } - if( rc!=SQLITE_OK ) return rc; - - /* Insert the marker in the %_segments table to make sure nobody tries - ** to steal the space just allocated. This is also used to identify - ** appendable segments. */ - rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0); - if( rc!=SQLITE_OK ) return rc; - - pWriter->iAbsLevel = iAbsLevel; - pWriter->nLeafEst = nLeafEst; - pWriter->iIdx = iIdx; - - /* Set up the array of NodeWriter objects */ - for(i=0; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; - } - return SQLITE_OK; -} - -/* -** Remove an entry from the %_segdir table. This involves running the -** following two statements: -** -** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx -** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx -** -** The DELETE statement removes the specific %_segdir level. The UPDATE -** statement ensures that the remaining segments have contiguously allocated -** idx values. -*/ -static int fts3RemoveSegdirEntry( - Fts3Table *p, /* FTS3 table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ - int iIdx /* Index of %_segdir entry to delete */ -){ - int rc; /* Return code */ - sqlite3_stmt *pDelete = 0; /* DELETE statement */ - - rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDelete, 1, iAbsLevel); - sqlite3_bind_int(pDelete, 2, iIdx); - sqlite3_step(pDelete); - rc = sqlite3_reset(pDelete); - } - - return rc; -} - -/* -** One or more segments have just been removed from absolute level iAbsLevel. -** Update the 'idx' values of the remaining segments in the level so that -** the idx values are a contiguous sequence starting from 0. -*/ -static int fts3RepackSegdirLevel( - Fts3Table *p, /* FTS3 table handle */ - sqlite3_int64 iAbsLevel /* Absolute level to repack */ -){ - int rc; /* Return code */ - int *aIdx = 0; /* Array of remaining idx values */ - int nIdx = 0; /* Valid entries in aIdx[] */ - int nAlloc = 0; /* Allocated size of aIdx[] */ - int i; /* Iterator variable */ - sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ - sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ - - rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); - if( rc==SQLITE_OK ){ - int rc2; - sqlite3_bind_int64(pSelect, 1, iAbsLevel); - while( SQLITE_ROW==sqlite3_step(pSelect) ){ - if( nIdx>=nAlloc ){ - int *aNew; - nAlloc += 16; - aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); - if( !aNew ){ - rc = SQLITE_NOMEM; - break; - } - aIdx = aNew; - } - aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); - } - rc2 = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ) rc = rc2; - } - - if( rc==SQLITE_OK ){ - rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); - } - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pUpdate, 2, iAbsLevel); - } - - assert( p->bIgnoreSavepoint==0 ); - p->bIgnoreSavepoint = 1; - for(i=0; rc==SQLITE_OK && ibIgnoreSavepoint = 0; - - sqlite3_free(aIdx); - return rc; -} - -static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ - pNode->a[0] = (char)iHeight; - if( iChild ){ - assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); - pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); - }else{ - assert( pNode->nAlloc>=1 ); - pNode->n = 1; - } -} - -/* -** The first two arguments are a pointer to and the size of a segment b-tree -** node. The node may be a leaf or an internal node. -** -** This function creates a new node image in blob object *pNew by copying -** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes) -** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode. -*/ -static int fts3TruncateNode( - const char *aNode, /* Current node image */ - int nNode, /* Size of aNode in bytes */ - Blob *pNew, /* OUT: Write new node image here */ - const char *zTerm, /* Omit all terms smaller than this */ - int nTerm, /* Size of zTerm in bytes */ - sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ -){ - NodeReader reader; /* Reader object */ - Blob prev = {0, 0, 0}; /* Previous term written to new node */ - int rc = SQLITE_OK; /* Return code */ - int bLeaf = aNode[0]=='\0'; /* True for a leaf node */ - - /* Allocate required output space */ - blobGrowBuffer(pNew, nNode, &rc); - if( rc!=SQLITE_OK ) return rc; - pNew->n = 0; - - /* Populate new node buffer */ - for(rc = nodeReaderInit(&reader, aNode, nNode); - rc==SQLITE_OK && reader.aNode; - rc = nodeReaderNext(&reader) - ){ - if( pNew->n==0 ){ - int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm); - if( res<0 || (bLeaf==0 && res==0) ) continue; - fts3StartNode(pNew, (int)aNode[0], reader.iChild); - *piBlock = reader.iChild; - } - rc = fts3AppendToNode( - pNew, &prev, reader.term.a, reader.term.n, - reader.aDoclist, reader.nDoclist - ); - if( rc!=SQLITE_OK ) break; - } - if( pNew->n==0 ){ - fts3StartNode(pNew, (int)aNode[0], reader.iChild); - *piBlock = reader.iChild; - } - assert( pNew->n<=pNew->nAlloc ); - - nodeReaderRelease(&reader); - sqlite3_free(prev.a); - return rc; -} - -/* -** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute -** level iAbsLevel. This may involve deleting entries from the %_segments -** table, and modifying existing entries in both the %_segments and %_segdir -** tables. -** -** SQLITE_OK is returned if the segment is updated successfully. Or an -** SQLite error code otherwise. -*/ -static int fts3TruncateSegment( - Fts3Table *p, /* FTS3 table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ - int iIdx, /* Index within level of segment to modify */ - const char *zTerm, /* Remove terms smaller than this */ - int nTerm /* Number of bytes in buffer zTerm */ -){ - int rc = SQLITE_OK; /* Return code */ - Blob root = {0,0,0}; /* New root page image */ - Blob block = {0,0,0}; /* Buffer used for any other block */ - sqlite3_int64 iBlock = 0; /* Block id */ - sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ - sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ - sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ - - rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); - if( rc==SQLITE_OK ){ - int rc2; /* sqlite3_reset() return code */ - sqlite3_bind_int64(pFetch, 1, iAbsLevel); - sqlite3_bind_int(pFetch, 2, iIdx); - if( SQLITE_ROW==sqlite3_step(pFetch) ){ - const char *aRoot = sqlite3_column_blob(pFetch, 4); - int nRoot = sqlite3_column_bytes(pFetch, 4); - iOldStart = sqlite3_column_int64(pFetch, 1); - rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); - } - rc2 = sqlite3_reset(pFetch); - if( rc==SQLITE_OK ) rc = rc2; - } - - while( rc==SQLITE_OK && iBlock ){ - char *aBlock = 0; - int nBlock = 0; - iNewStart = iBlock; - - rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); - if( rc==SQLITE_OK ){ - rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); - } - if( rc==SQLITE_OK ){ - rc = fts3WriteSegment(p, iNewStart, block.a, block.n); - } - sqlite3_free(aBlock); - } - - /* Variable iNewStart now contains the first valid leaf node. */ - if( rc==SQLITE_OK && iNewStart ){ - sqlite3_stmt *pDel = 0; - rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDel, 1, iOldStart); - sqlite3_bind_int64(pDel, 2, iNewStart-1); - sqlite3_step(pDel); - rc = sqlite3_reset(pDel); - } - } - - if( rc==SQLITE_OK ){ - sqlite3_stmt *pChomp = 0; - rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pChomp, 1, iNewStart); - sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); - sqlite3_bind_int64(pChomp, 3, iAbsLevel); - sqlite3_bind_int(pChomp, 4, iIdx); - sqlite3_step(pChomp); - rc = sqlite3_reset(pChomp); - } - } - - sqlite3_free(root.a); - sqlite3_free(block.a); - return rc; -} - -/* -** This function is called after an incrmental-merge operation has run to -** merge (or partially merge) two or more segments from absolute level -** iAbsLevel. -** -** Each input segment is either removed from the db completely (if all of -** its data was copied to the output segment by the incrmerge operation) -** or modified in place so that it no longer contains those entries that -** have been duplicated in the output segment. -*/ -static int fts3IncrmergeChomp( - Fts3Table *p, /* FTS table handle */ - sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ - Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ - int *pnRem /* Number of segments not deleted */ -){ - int i; - int nRem = 0; - int rc = SQLITE_OK; - - for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){ - Fts3SegReader *pSeg = 0; - int j; - - /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding - ** somewhere in the pCsr->apSegment[] array. */ - for(j=0; ALWAYS(jnSegment); j++){ - pSeg = pCsr->apSegment[j]; - if( pSeg->iIdx==i ) break; - } - assert( jnSegment && pSeg->iIdx==i ); - - if( pSeg->aNode==0 ){ - /* Seg-reader is at EOF. Remove the entire input segment. */ - rc = fts3DeleteSegment(p, pSeg); - if( rc==SQLITE_OK ){ - rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx); - } - *pnRem = 0; - }else{ - /* The incremental merge did not copy all the data from this - ** segment to the upper level. The segment is modified in place - ** so that it contains no keys smaller than zTerm/nTerm. */ - const char *zTerm = pSeg->zTerm; - int nTerm = pSeg->nTerm; - rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm); - nRem++; - } - } - - if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){ - rc = fts3RepackSegdirLevel(p, iAbsLevel); - } - - *pnRem = nRem; - return rc; -} - -/* -** Store an incr-merge hint in the database. -*/ -static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ - sqlite3_stmt *pReplace = 0; - int rc; /* Return code */ - - rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); - if( rc==SQLITE_OK ){ - sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); - sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - } - - return rc; -} - -/* -** Load an incr-merge hint from the database. The incr-merge hint, if one -** exists, is stored in the rowid==1 row of the %_stat table. -** -** If successful, populate blob *pHint with the value read from the %_stat -** table and return SQLITE_OK. Otherwise, if an error occurs, return an -** SQLite error code. -*/ -static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ - sqlite3_stmt *pSelect = 0; - int rc; - - pHint->n = 0; - rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); - if( rc==SQLITE_OK ){ - int rc2; - sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); - if( SQLITE_ROW==sqlite3_step(pSelect) ){ - const char *aHint = sqlite3_column_blob(pSelect, 0); - int nHint = sqlite3_column_bytes(pSelect, 0); - if( aHint ){ - blobGrowBuffer(pHint, nHint, &rc); - if( rc==SQLITE_OK ){ - memcpy(pHint->a, aHint, nHint); - pHint->n = nHint; - } - } - } - rc2 = sqlite3_reset(pSelect); - if( rc==SQLITE_OK ) rc = rc2; - } - - return rc; -} - -/* -** If *pRc is not SQLITE_OK when this function is called, it is a no-op. -** Otherwise, append an entry to the hint stored in blob *pHint. Each entry -** consists of two varints, the absolute level number of the input segments -** and the number of input segments. -** -** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs, -** set *pRc to an SQLite error code before returning. -*/ -static void fts3IncrmergeHintPush( - Blob *pHint, /* Hint blob to append to */ - i64 iAbsLevel, /* First varint to store in hint */ - int nInput, /* Second varint to store in hint */ - int *pRc /* IN/OUT: Error code */ -){ - blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); - if( *pRc==SQLITE_OK ){ - pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); - pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); - } -} - -/* -** Read the last entry (most recently pushed) from the hint blob *pHint -** and then remove the entry. Write the two values read to *piAbsLevel and -** *pnInput before returning. -** -** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does -** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB. -*/ -static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ - const int nHint = pHint->n; - int i; - - i = pHint->n-2; - while( i>0 && (pHint->a[i-1] & 0x80) ) i--; - while( i>0 && (pHint->a[i-1] & 0x80) ) i--; - - pHint->n = i; - i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); - i += fts3GetVarint32(&pHint->a[i], pnInput); - if( i!=nHint ) return FTS_CORRUPT_VTAB; - - return SQLITE_OK; -} - - -/* -** Attempt an incremental merge that writes nMerge leaf blocks. -** -** Incremental merges happen nMin segments at a time. The segments -** to be merged are the nMin oldest segments (the ones with the smallest -** values for the _segdir.idx field) in the highest level that contains -** at least nMin segments. Multiple merges might occur in an attempt to -** write the quota of nMerge leaf blocks. -*/ -SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ - int rc; /* Return code */ - int nRem = nMerge; /* Number of leaf pages yet to be written */ - Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ - Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ - IncrmergeWriter *pWriter; /* Writer object */ - int nSeg = 0; /* Number of input segments */ - sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ - Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ - int bDirtyHint = 0; /* True if blob 'hint' has been modified */ - - /* Allocate space for the cursor, filter and writer objects */ - const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); - pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); - if( !pWriter ) return SQLITE_NOMEM; - pFilter = (Fts3SegFilter *)&pWriter[1]; - pCsr = (Fts3MultiSegReader *)&pFilter[1]; - - rc = fts3IncrmergeHintLoad(p, &hint); - while( rc==SQLITE_OK && nRem>0 ){ - const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; - sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ - int bUseHint = 0; /* True if attempting to append */ - int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ - - /* Search the %_segdir table for the absolute level with the smallest - ** relative level number that contains at least nMin segments, if any. - ** If one is found, set iAbsLevel to the absolute level number and - ** nSeg to nMin. If no level with at least nMin segments can be found, - ** set nSeg to -1. - */ - rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); - sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); - if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ - iAbsLevel = sqlite3_column_int64(pFindLevel, 0); - nSeg = sqlite3_column_int(pFindLevel, 1); - assert( nSeg>=2 ); - }else{ - nSeg = -1; - } - rc = sqlite3_reset(pFindLevel); - - /* If the hint read from the %_stat table is not empty, check if the - ** last entry in it specifies a relative level smaller than or equal - ** to the level identified by the block above (if any). If so, this - ** iteration of the loop will work on merging at the hinted level. - */ - if( rc==SQLITE_OK && hint.n ){ - int nHint = hint.n; - sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ - int nHintSeg = 0; /* Hint number of segments */ - - rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); - if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ - iAbsLevel = iHintAbsLevel; - nSeg = nHintSeg; - bUseHint = 1; - bDirtyHint = 1; - }else{ - /* This undoes the effect of the HintPop() above - so that no entry - ** is removed from the hint blob. */ - hint.n = nHint; - } - } - - /* If nSeg is less that zero, then there is no level with at least - ** nMin segments and no hint in the %_stat table. No work to do. - ** Exit early in this case. */ - if( nSeg<0 ) break; - - /* Open a cursor to iterate through the contents of the oldest nSeg - ** indexes of absolute level iAbsLevel. If this cursor is opened using - ** the 'hint' parameters, it is possible that there are less than nSeg - ** segments available in level iAbsLevel. In this case, no work is - ** done on iAbsLevel - fall through to the next iteration of the loop - ** to start work on some other level. */ - memset(pWriter, 0, nAlloc); - pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; - - if( rc==SQLITE_OK ){ - rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); - assert( bUseHint==1 || bUseHint==0 ); - if( iIdx==0 || (bUseHint && iIdx==1) ){ - int bIgnore = 0; - rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); - if( bIgnore ){ - pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; - } - } - } - - if( rc==SQLITE_OK ){ - rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); - } - if( SQLITE_OK==rc && pCsr->nSegment==nSeg - && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) - && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr)) - ){ - if( bUseHint && iIdx>0 ){ - const char *zKey = pCsr->zTerm; - int nKey = pCsr->nTerm; - rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); - }else{ - rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); - } - - if( rc==SQLITE_OK && pWriter->nLeafEst ){ - fts3LogMerge(nSeg, iAbsLevel); - do { - rc = fts3IncrmergeAppend(p, pWriter, pCsr); - if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); - if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; - }while( rc==SQLITE_ROW ); - - /* Update or delete the input segments */ - if( rc==SQLITE_OK ){ - nRem -= (1 + pWriter->nWork); - rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg); - if( nSeg!=0 ){ - bDirtyHint = 1; - fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); - } - } - } - - if( nSeg!=0 ){ - pWriter->nLeafData = pWriter->nLeafData * -1; - } - fts3IncrmergeRelease(p, pWriter, &rc); - if( nSeg==0 && pWriter->bNoLeafData==0 ){ - fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); - } - } - - sqlite3Fts3SegReaderFinish(pCsr); - } - - /* Write the hint values into the %_stat table for the next incr-merger */ - if( bDirtyHint && rc==SQLITE_OK ){ - rc = fts3IncrmergeHintStore(p, &hint); - } - - sqlite3_free(pWriter); - sqlite3_free(hint.a); - return rc; -} - -/* -** Convert the text beginning at *pz into an integer and return -** its value. Advance *pz to point to the first character past -** the integer. -*/ -static int fts3Getint(const char **pz){ - const char *z = *pz; - int i = 0; - while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0'; - *pz = z; - return i; -} - -/* -** Process statements of the form: -** -** INSERT INTO table(table) VALUES('merge=A,B'); -** -** A and B are integers that decode to be the number of leaf pages -** written for the merge, and the minimum number of segments on a level -** before it will be selected for a merge, respectively. -*/ -static int fts3DoIncrmerge( - Fts3Table *p, /* FTS3 table handle */ - const char *zParam /* Nul-terminated string containing "A,B" */ -){ - int rc; - int nMin = (FTS3_MERGE_COUNT / 2); - int nMerge = 0; - const char *z = zParam; - - /* Read the first integer value */ - nMerge = fts3Getint(&z); - - /* If the first integer value is followed by a ',', read the second - ** integer value. */ - if( z[0]==',' && z[1]!='\0' ){ - z++; - nMin = fts3Getint(&z); - } - - if( z[0]!='\0' || nMin<2 ){ - rc = SQLITE_ERROR; - }else{ - rc = SQLITE_OK; - if( !p->bHasStat ){ - assert( p->bFts4==0 ); - sqlite3Fts3CreateStatTable(&rc, p); - } - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); - } - sqlite3Fts3SegmentsClose(p); - } - return rc; -} - -/* -** Process statements of the form: -** -** INSERT INTO table(table) VALUES('automerge=X'); -** -** where X is an integer. X==0 means to turn automerge off. X!=0 means -** turn it on. The setting is persistent. -*/ -static int fts3DoAutoincrmerge( - Fts3Table *p, /* FTS3 table handle */ - const char *zParam /* Nul-terminated string containing boolean */ -){ - int rc = SQLITE_OK; - sqlite3_stmt *pStmt = 0; - p->nAutoincrmerge = fts3Getint(&zParam); - if( p->nAutoincrmerge==1 || p->nAutoincrmerge>FTS3_MERGE_COUNT ){ - p->nAutoincrmerge = 8; - } - if( !p->bHasStat ){ - assert( p->bFts4==0 ); - sqlite3Fts3CreateStatTable(&rc, p); - if( rc ) return rc; - } - rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); - if( rc ) return rc; - sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); - sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); - sqlite3_step(pStmt); - rc = sqlite3_reset(pStmt); - return rc; -} - -/* -** Return a 64-bit checksum for the FTS index entry specified by the -** arguments to this function. -*/ -static u64 fts3ChecksumEntry( - const char *zTerm, /* Pointer to buffer containing term */ - int nTerm, /* Size of zTerm in bytes */ - int iLangid, /* Language id for current row */ - int iIndex, /* Index (0..Fts3Table.nIndex-1) */ - i64 iDocid, /* Docid for current row. */ - int iCol, /* Column number */ - int iPos /* Position */ -){ - int i; - u64 ret = (u64)iDocid; - - ret += (ret<<3) + iLangid; - ret += (ret<<3) + iIndex; - ret += (ret<<3) + iCol; - ret += (ret<<3) + iPos; - for(i=0; inIndex-1) */ - int *pRc /* OUT: Return code */ -){ - Fts3SegFilter filter; - Fts3MultiSegReader csr; - int rc; - u64 cksum = 0; - - assert( *pRc==SQLITE_OK ); - - memset(&filter, 0, sizeof(filter)); - memset(&csr, 0, sizeof(csr)); - filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; - filter.flags |= FTS3_SEGMENT_SCAN; - - rc = sqlite3Fts3SegReaderCursor( - p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr - ); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); - } - - if( rc==SQLITE_OK ){ - while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ - char *pCsr = csr.aDoclist; - char *pEnd = &pCsr[csr.nDoclist]; - - i64 iDocid = 0; - i64 iCol = 0; - i64 iPos = 0; - - pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); - while( pCsriPrevLangid); - sqlite3_bind_int(pAllLangid, 2, p->nIndex); - while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ - int iLangid = sqlite3_column_int(pAllLangid, 0); - int i; - for(i=0; inIndex; i++){ - cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); - } - } - rc2 = sqlite3_reset(pAllLangid); - if( rc==SQLITE_OK ) rc = rc2; - } - - /* This block calculates the checksum according to the %_content table */ - if( rc==SQLITE_OK ){ - sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; - sqlite3_stmt *pStmt = 0; - char *zSql; - - zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - } - - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - i64 iDocid = sqlite3_column_int64(pStmt, 0); - int iLang = langidFromSelect(p, pStmt); - int iCol; - - for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ - if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); - int nText = sqlite3_column_bytes(pStmt, iCol+1); - sqlite3_tokenizer_cursor *pT = 0; - - rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT); - while( rc==SQLITE_OK ){ - char const *zToken; /* Buffer containing token */ - int nToken = 0; /* Number of bytes in token */ - int iDum1 = 0, iDum2 = 0; /* Dummy variables */ - int iPos = 0; /* Position of token in zText */ - - rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); - if( rc==SQLITE_OK ){ - int i; - cksum2 = cksum2 ^ fts3ChecksumEntry( - zToken, nToken, iLang, 0, iDocid, iCol, iPos - ); - for(i=1; inIndex; i++){ - if( p->aIndex[i].nPrefix<=nToken ){ - cksum2 = cksum2 ^ fts3ChecksumEntry( - zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos - ); - } - } - } - } - if( pT ) pModule->xClose(pT); - if( rc==SQLITE_DONE ) rc = SQLITE_OK; - } - } - } - - sqlite3_finalize(pStmt); - } - - *pbOk = (cksum1==cksum2); - return rc; -} - -/* -** Run the integrity-check. If no error occurs and the current contents of -** the FTS index are correct, return SQLITE_OK. Or, if the contents of the -** FTS index are incorrect, return SQLITE_CORRUPT_VTAB. -** -** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite -** error code. -** -** The integrity-check works as follows. For each token and indexed token -** prefix in the document set, a 64-bit checksum is calculated (by code -** in fts3ChecksumEntry()) based on the following: -** -** + The index number (0 for the main index, 1 for the first prefix -** index etc.), -** + The token (or token prefix) text itself, -** + The language-id of the row it appears in, -** + The docid of the row it appears in, -** + The column it appears in, and -** + The tokens position within that column. -** -** The checksums for all entries in the index are XORed together to create -** a single checksum for the entire index. -** -** The integrity-check code calculates the same checksum in two ways: -** -** 1. By scanning the contents of the FTS index, and -** 2. By scanning and tokenizing the content table. -** -** If the two checksums are identical, the integrity-check is deemed to have -** passed. -*/ -static int fts3DoIntegrityCheck( - Fts3Table *p /* FTS3 table handle */ -){ - int rc; - int bOk = 0; - rc = fts3IntegrityCheck(p, &bOk); - if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; - return rc; -} - -/* -** Handle a 'special' INSERT of the form: -** -** "INSERT INTO tbl(tbl) VALUES()" -** -** Argument pVal contains the result of . Currently the only -** meaningful value to insert is the text 'optimize'. -*/ -static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ - int rc; /* Return Code */ - const char *zVal = (const char *)sqlite3_value_text(pVal); - int nVal = sqlite3_value_bytes(pVal); - - if( !zVal ){ - return SQLITE_NOMEM; - }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ - rc = fts3DoOptimize(p, 0); - }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ - rc = fts3DoRebuild(p); - }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ - rc = fts3DoIntegrityCheck(p); - }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ - rc = fts3DoIncrmerge(p, &zVal[6]); - }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ - rc = fts3DoAutoincrmerge(p, &zVal[10]); -#ifdef SQLITE_TEST - }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ - p->nNodeSize = atoi(&zVal[9]); - rc = SQLITE_OK; - }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ - p->nMaxPendingData = atoi(&zVal[11]); - rc = SQLITE_OK; - }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){ - p->bNoIncrDoclist = atoi(&zVal[21]); - rc = SQLITE_OK; -#endif - }else{ - rc = SQLITE_ERROR; - } - - return rc; -} - -#ifndef SQLITE_DISABLE_FTS4_DEFERRED -/* -** Delete all cached deferred doclists. Deferred doclists are cached -** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. -*/ -SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ - Fts3DeferredToken *pDef; - for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ - fts3PendingListDelete(pDef->pList); - pDef->pList = 0; - } -} - -/* -** Free all entries in the pCsr->pDeffered list. Entries are added to -** this list using sqlite3Fts3DeferToken(). -*/ -SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ - Fts3DeferredToken *pDef; - Fts3DeferredToken *pNext; - for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ - pNext = pDef->pNext; - fts3PendingListDelete(pDef->pList); - sqlite3_free(pDef); - } - pCsr->pDeferred = 0; -} - -/* -** Generate deferred-doclists for all tokens in the pCsr->pDeferred list -** based on the row that pCsr currently points to. -** -** A deferred-doclist is like any other doclist with position information -** included, except that it only contains entries for a single row of the -** table, not for all rows. -*/ -SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ - int rc = SQLITE_OK; /* Return code */ - if( pCsr->pDeferred ){ - int i; /* Used to iterate through table columns */ - sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ - Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ - - Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; - sqlite3_tokenizer *pT = p->pTokenizer; - sqlite3_tokenizer_module const *pModule = pT->pModule; - - assert( pCsr->isRequireSeek==0 ); - iDocid = sqlite3_column_int64(pCsr->pStmt, 0); - - for(i=0; inColumn && rc==SQLITE_OK; i++){ - if( p->abNotindexed[i]==0 ){ - const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); - sqlite3_tokenizer_cursor *pTC = 0; - - rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); - while( rc==SQLITE_OK ){ - char const *zToken; /* Buffer containing token */ - int nToken = 0; /* Number of bytes in token */ - int iDum1 = 0, iDum2 = 0; /* Dummy variables */ - int iPos = 0; /* Position of token in zText */ - - rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ - Fts3PhraseToken *pPT = pDef->pToken; - if( (pDef->iCol>=p->nColumn || pDef->iCol==i) - && (pPT->bFirst==0 || iPos==0) - && (pPT->n==nToken || (pPT->isPrefix && pPT->nz, pPT->n)) - ){ - fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); - } - } - } - if( pTC ) pModule->xClose(pTC); - if( rc==SQLITE_DONE ) rc = SQLITE_OK; - } - } - - for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ - if( pDef->pList ){ - rc = fts3PendingListAppendVarint(&pDef->pList, 0); - } - } - } - - return rc; -} - -SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( - Fts3DeferredToken *p, - char **ppData, - int *pnData -){ - char *pRet; - int nSkip; - sqlite3_int64 dummy; - - *ppData = 0; - *pnData = 0; - - if( p->pList==0 ){ - return SQLITE_OK; - } - - pRet = (char *)sqlite3_malloc(p->pList->nData); - if( !pRet ) return SQLITE_NOMEM; - - nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); - *pnData = p->pList->nData - nSkip; - *ppData = pRet; - - memcpy(pRet, &p->pList->aData[nSkip], *pnData); - return SQLITE_OK; -} - -/* -** Add an entry for token pToken to the pCsr->pDeferred list. -*/ -SQLITE_PRIVATE int sqlite3Fts3DeferToken( - Fts3Cursor *pCsr, /* Fts3 table cursor */ - Fts3PhraseToken *pToken, /* Token to defer */ - int iCol /* Column that token must appear in (or -1) */ -){ - Fts3DeferredToken *pDeferred; - pDeferred = sqlite3_malloc(sizeof(*pDeferred)); - if( !pDeferred ){ - return SQLITE_NOMEM; - } - memset(pDeferred, 0, sizeof(*pDeferred)); - pDeferred->pToken = pToken; - pDeferred->pNext = pCsr->pDeferred; - pDeferred->iCol = iCol; - pCsr->pDeferred = pDeferred; - - assert( pToken->pDeferred==0 ); - pToken->pDeferred = pDeferred; - - return SQLITE_OK; -} -#endif - -/* -** SQLite value pRowid contains the rowid of a row that may or may not be -** present in the FTS3 table. If it is, delete it and adjust the contents -** of subsiduary data structures accordingly. -*/ -static int fts3DeleteByRowid( - Fts3Table *p, - sqlite3_value *pRowid, - int *pnChng, /* IN/OUT: Decrement if row is deleted */ - u32 *aSzDel -){ - int rc = SQLITE_OK; /* Return code */ - int bFound = 0; /* True if *pRowid really is in the table */ - - fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound); - if( bFound && rc==SQLITE_OK ){ - int isEmpty = 0; /* Deleting *pRowid leaves the table empty */ - rc = fts3IsEmpty(p, pRowid, &isEmpty); - if( rc==SQLITE_OK ){ - if( isEmpty ){ - /* Deleting this row means the whole table is empty. In this case - ** delete the contents of all three tables and throw away any - ** data in the pendingTerms hash table. */ - rc = fts3DeleteAll(p, 1); - *pnChng = 0; - memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2); - }else{ - *pnChng = *pnChng - 1; - if( p->zContentTbl==0 ){ - fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); - } - if( p->bHasDocsize ){ - fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid); - } - } - } - } - - return rc; -} - -/* -** This function does the work for the xUpdate method of FTS3 virtual -** tables. The schema of the virtual table being: -** -** CREATE TABLE
    ( -** , -**
    HIDDEN, -** docid HIDDEN, -** HIDDEN -** ); -** -** -*/ -SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( - sqlite3_vtab *pVtab, /* FTS3 vtab object */ - int nArg, /* Size of argument array */ - sqlite3_value **apVal, /* Array of arguments */ - sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ -){ - Fts3Table *p = (Fts3Table *)pVtab; - int rc = SQLITE_OK; /* Return Code */ - int isRemove = 0; /* True for an UPDATE or DELETE */ - u32 *aSzIns = 0; /* Sizes of inserted documents */ - u32 *aSzDel = 0; /* Sizes of deleted documents */ - int nChng = 0; /* Net change in number of documents */ - int bInsertDone = 0; - - /* At this point it must be known if the %_stat table exists or not. - ** So bHasStat may not be 2. */ - assert( p->bHasStat==0 || p->bHasStat==1 ); - - assert( p->pSegments==0 ); - assert( - nArg==1 /* DELETE operations */ - || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ - ); - - /* Check for a "special" INSERT operation. One of the form: - ** - ** INSERT INTO xyz(xyz) VALUES('command'); - */ - if( nArg>1 - && sqlite3_value_type(apVal[0])==SQLITE_NULL - && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL - ){ - rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); - goto update_out; - } - - if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ - rc = SQLITE_CONSTRAINT; - goto update_out; - } - - /* Allocate space to hold the change in document sizes */ - aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 ); - if( aSzDel==0 ){ - rc = SQLITE_NOMEM; - goto update_out; - } - aSzIns = &aSzDel[p->nColumn+1]; - memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2); - - rc = fts3Writelock(p); - if( rc!=SQLITE_OK ) goto update_out; - - /* If this is an INSERT operation, or an UPDATE that modifies the rowid - ** value, then this operation requires constraint handling. - ** - ** If the on-conflict mode is REPLACE, this means that the existing row - ** should be deleted from the database before inserting the new row. Or, - ** if the on-conflict mode is other than REPLACE, then this method must - ** detect the conflict and return SQLITE_CONSTRAINT before beginning to - ** modify the database file. - */ - if( nArg>1 && p->zContentTbl==0 ){ - /* Find the value object that holds the new rowid value. */ - sqlite3_value *pNewRowid = apVal[3+p->nColumn]; - if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ - pNewRowid = apVal[1]; - } - - if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( - sqlite3_value_type(apVal[0])==SQLITE_NULL - || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) - )){ - /* The new rowid is not NULL (in this case the rowid will be - ** automatically assigned and there is no chance of a conflict), and - ** the statement is either an INSERT or an UPDATE that modifies the - ** rowid column. So if the conflict mode is REPLACE, then delete any - ** existing row with rowid=pNewRowid. - ** - ** Or, if the conflict mode is not REPLACE, insert the new record into - ** the %_content table. If we hit the duplicate rowid constraint (or any - ** other error) while doing so, return immediately. - ** - ** This branch may also run if pNewRowid contains a value that cannot - ** be losslessly converted to an integer. In this case, the eventual - ** call to fts3InsertData() (either just below or further on in this - ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is - ** invoked, it will delete zero rows (since no row will have - ** docid=$pNewRowid if $pNewRowid is not an integer value). - */ - if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ - rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); - }else{ - rc = fts3InsertData(p, apVal, pRowid); - bInsertDone = 1; - } - } - } - if( rc!=SQLITE_OK ){ - goto update_out; - } - - /* If this is a DELETE or UPDATE operation, remove the old record. */ - if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ - assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); - rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); - isRemove = 1; - } - - /* If this is an INSERT or UPDATE operation, insert the new record. */ - if( nArg>1 && rc==SQLITE_OK ){ - int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); - if( bInsertDone==0 ){ - rc = fts3InsertData(p, apVal, pRowid); - if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ - rc = FTS_CORRUPT_VTAB; - } - } - if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){ - rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid); - } - if( rc==SQLITE_OK ){ - assert( p->iPrevDocid==*pRowid ); - rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); - } - if( p->bHasDocsize ){ - fts3InsertDocsize(&rc, p, aSzIns); - } - nChng++; - } - - if( p->bFts4 ){ - fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); - } - - update_out: - sqlite3_free(aSzDel); - sqlite3Fts3SegmentsClose(p); - return rc; -} - -/* -** Flush any data in the pending-terms hash table to disk. If successful, -** merge all segments in the database (including the new segment, if -** there was any data to flush) into a single segment. -*/ -SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ - int rc; - rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); - if( rc==SQLITE_OK ){ - rc = fts3DoOptimize(p, 1); - if( rc==SQLITE_OK || rc==SQLITE_DONE ){ - int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); - if( rc2!=SQLITE_OK ) rc = rc2; - }else{ - sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); - sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); - } - } - sqlite3Fts3SegmentsClose(p); - return rc; -} - -#endif - -/************** End of fts3_write.c ******************************************/ -/************** Begin file fts3_snippet.c ************************************/ -/* -** 2009 Oct 23 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -*/ - -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ - -/* -** Characters that may appear in the second argument to matchinfo(). -*/ -#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ -#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ -#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ -#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ -#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ -#define FTS3_MATCHINFO_LCS 's' /* nCol values */ -#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ -#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ -#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */ - -/* -** The default value for the second argument to matchinfo(). -*/ -#define FTS3_MATCHINFO_DEFAULT "pcx" - - -/* -** Used as an fts3ExprIterate() context when loading phrase doclists to -** Fts3Expr.aDoclist[]/nDoclist. -*/ -typedef struct LoadDoclistCtx LoadDoclistCtx; -struct LoadDoclistCtx { - Fts3Cursor *pCsr; /* FTS3 Cursor */ - int nPhrase; /* Number of phrases seen so far */ - int nToken; /* Number of tokens seen so far */ -}; - -/* -** The following types are used as part of the implementation of the -** fts3BestSnippet() routine. -*/ -typedef struct SnippetIter SnippetIter; -typedef struct SnippetPhrase SnippetPhrase; -typedef struct SnippetFragment SnippetFragment; - -struct SnippetIter { - Fts3Cursor *pCsr; /* Cursor snippet is being generated from */ - int iCol; /* Extract snippet from this column */ - int nSnippet; /* Requested snippet length (in tokens) */ - int nPhrase; /* Number of phrases in query */ - SnippetPhrase *aPhrase; /* Array of size nPhrase */ - int iCurrent; /* First token of current snippet */ -}; - -struct SnippetPhrase { - int nToken; /* Number of tokens in phrase */ - char *pList; /* Pointer to start of phrase position list */ - int iHead; /* Next value in position list */ - char *pHead; /* Position list data following iHead */ - int iTail; /* Next value in trailing position list */ - char *pTail; /* Position list data following iTail */ -}; - -struct SnippetFragment { - int iCol; /* Column snippet is extracted from */ - int iPos; /* Index of first token in snippet */ - u64 covered; /* Mask of query phrases covered */ - u64 hlmask; /* Mask of snippet terms to highlight */ -}; - -/* -** This type is used as an fts3ExprIterate() context object while -** accumulating the data returned by the matchinfo() function. -*/ -typedef struct MatchInfo MatchInfo; -struct MatchInfo { - Fts3Cursor *pCursor; /* FTS3 Cursor */ - int nCol; /* Number of columns in table */ - int nPhrase; /* Number of matchable phrases in query */ - sqlite3_int64 nDoc; /* Number of docs in database */ - char flag; - u32 *aMatchinfo; /* Pre-allocated buffer */ -}; - -/* -** An instance of this structure is used to manage a pair of buffers, each -** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below -** for details. -*/ -struct MatchinfoBuffer { - u8 aRef[3]; - int nElem; - int bGlobal; /* Set if global data is loaded */ - char *zMatchinfo; - u32 aMatchinfo[1]; -}; - - -/* -** The snippet() and offsets() functions both return text values. An instance -** of the following structure is used to accumulate those values while the -** functions are running. See fts3StringAppend() for details. -*/ -typedef struct StrBuffer StrBuffer; -struct StrBuffer { - char *z; /* Pointer to buffer containing string */ - int n; /* Length of z in bytes (excl. nul-term) */ - int nAlloc; /* Allocated size of buffer z in bytes */ -}; - - -/************************************************************************* -** Start of MatchinfoBuffer code. -*/ - -/* -** Allocate a two-slot MatchinfoBuffer object. -*/ -static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){ - MatchinfoBuffer *pRet; - int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer); - int nStr = (int)strlen(zMatchinfo); - - pRet = sqlite3_malloc(nByte + nStr+1); - if( pRet ){ - memset(pRet, 0, nByte); - pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; - pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1); - pRet->nElem = nElem; - pRet->zMatchinfo = ((char*)pRet) + nByte; - memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1); - pRet->aRef[0] = 1; - } - - return pRet; -} - -static void fts3MIBufferFree(void *p){ - MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); - - assert( (u32*)p==&pBuf->aMatchinfo[1] - || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] - ); - if( (u32*)p==&pBuf->aMatchinfo[1] ){ - pBuf->aRef[1] = 0; - }else{ - pBuf->aRef[2] = 0; - } - - if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){ - sqlite3_free(pBuf); - } -} - -static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ - void (*xRet)(void*) = 0; - u32 *aOut = 0; - - if( p->aRef[1]==0 ){ - p->aRef[1] = 1; - aOut = &p->aMatchinfo[1]; - xRet = fts3MIBufferFree; - } - else if( p->aRef[2]==0 ){ - p->aRef[2] = 1; - aOut = &p->aMatchinfo[p->nElem+2]; - xRet = fts3MIBufferFree; - }else{ - aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32)); - if( aOut ){ - xRet = sqlite3_free; - if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); - } - } - - *paOut = aOut; - return xRet; -} - -static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ - p->bGlobal = 1; - memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32)); -} - -/* -** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() -*/ -SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ - if( p ){ - assert( p->aRef[0]==1 ); - p->aRef[0] = 0; - if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){ - sqlite3_free(p); - } - } -} - -/* -** End of MatchinfoBuffer code. -*************************************************************************/ - - -/* -** This function is used to help iterate through a position-list. A position -** list is a list of unique integers, sorted from smallest to largest. Each -** element of the list is represented by an FTS3 varint that takes the value -** of the difference between the current element and the previous one plus -** two. For example, to store the position-list: -** -** 4 9 113 -** -** the three varints: -** -** 6 7 106 -** -** are encoded. -** -** When this function is called, *pp points to the start of an element of -** the list. *piPos contains the value of the previous entry in the list. -** After it returns, *piPos contains the value of the next element of the -** list and *pp is advanced to the following varint. -*/ -static void fts3GetDeltaPosition(char **pp, int *piPos){ - int iVal; - *pp += fts3GetVarint32(*pp, &iVal); - *piPos += (iVal-2); -} - -/* -** Helper function for fts3ExprIterate() (see below). -*/ -static int fts3ExprIterate2( - Fts3Expr *pExpr, /* Expression to iterate phrases of */ - int *piPhrase, /* Pointer to phrase counter */ - int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ - void *pCtx /* Second argument to pass to callback */ -){ - int rc; /* Return code */ - int eType = pExpr->eType; /* Type of expression node pExpr */ - - if( eType!=FTSQUERY_PHRASE ){ - assert( pExpr->pLeft && pExpr->pRight ); - rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx); - if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){ - rc = fts3ExprIterate2(pExpr->pRight, piPhrase, x, pCtx); - } - }else{ - rc = x(pExpr, *piPhrase, pCtx); - (*piPhrase)++; - } - return rc; -} - -/* -** Iterate through all phrase nodes in an FTS3 query, except those that -** are part of a sub-tree that is the right-hand-side of a NOT operator. -** For each phrase node found, the supplied callback function is invoked. -** -** If the callback function returns anything other than SQLITE_OK, -** the iteration is abandoned and the error code returned immediately. -** Otherwise, SQLITE_OK is returned after a callback has been made for -** all eligible phrase nodes. -*/ -static int fts3ExprIterate( - Fts3Expr *pExpr, /* Expression to iterate phrases of */ - int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ - void *pCtx /* Second argument to pass to callback */ -){ - int iPhrase = 0; /* Variable used as the phrase counter */ - return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); -} - - -/* -** This is an fts3ExprIterate() callback used while loading the doclists -** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also -** fts3ExprLoadDoclists(). -*/ -static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ - int rc = SQLITE_OK; - Fts3Phrase *pPhrase = pExpr->pPhrase; - LoadDoclistCtx *p = (LoadDoclistCtx *)ctx; - - UNUSED_PARAMETER(iPhrase); - - p->nPhrase++; - p->nToken += pPhrase->nToken; - - return rc; -} - -/* -** Load the doclists for each phrase in the query associated with FTS3 cursor -** pCsr. -** -** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable -** phrases in the expression (all phrases except those directly or -** indirectly descended from the right-hand-side of a NOT operator). If -** pnToken is not NULL, then it is set to the number of tokens in all -** matchable phrases of the expression. -*/ -static int fts3ExprLoadDoclists( - Fts3Cursor *pCsr, /* Fts3 cursor for current query */ - int *pnPhrase, /* OUT: Number of phrases in query */ - int *pnToken /* OUT: Number of tokens in query */ -){ - int rc; /* Return Code */ - LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ - sCtx.pCsr = pCsr; - rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); - if( pnPhrase ) *pnPhrase = sCtx.nPhrase; - if( pnToken ) *pnToken = sCtx.nToken; - return rc; -} - -static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ - (*(int *)ctx)++; - pExpr->iPhrase = iPhrase; - return SQLITE_OK; -} -static int fts3ExprPhraseCount(Fts3Expr *pExpr){ - int nPhrase = 0; - (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); - return nPhrase; -} - -/* -** Advance the position list iterator specified by the first two -** arguments so that it points to the first element with a value greater -** than or equal to parameter iNext. -*/ -static void fts3SnippetAdvance(char **ppIter, int *piIter, int iNext){ - char *pIter = *ppIter; - if( pIter ){ - int iIter = *piIter; - - while( iIteriCurrent<0 ){ - /* The SnippetIter object has just been initialized. The first snippet - ** candidate always starts at offset 0 (even if this candidate has a - ** score of 0.0). - */ - pIter->iCurrent = 0; - - /* Advance the 'head' iterator of each phrase to the first offset that - ** is greater than or equal to (iNext+nSnippet). - */ - for(i=0; inPhrase; i++){ - SnippetPhrase *pPhrase = &pIter->aPhrase[i]; - fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, pIter->nSnippet); - } - }else{ - int iStart; - int iEnd = 0x7FFFFFFF; - - for(i=0; inPhrase; i++){ - SnippetPhrase *pPhrase = &pIter->aPhrase[i]; - if( pPhrase->pHead && pPhrase->iHeadiHead; - } - } - if( iEnd==0x7FFFFFFF ){ - return 1; - } - - pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; - for(i=0; inPhrase; i++){ - SnippetPhrase *pPhrase = &pIter->aPhrase[i]; - fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); - fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); - } - } - - return 0; -} - -/* -** Retrieve information about the current candidate snippet of snippet -** iterator pIter. -*/ -static void fts3SnippetDetails( - SnippetIter *pIter, /* Snippet iterator */ - u64 mCovered, /* Bitmask of phrases already covered */ - int *piToken, /* OUT: First token of proposed snippet */ - int *piScore, /* OUT: "Score" for this snippet */ - u64 *pmCover, /* OUT: Bitmask of phrases covered */ - u64 *pmHighlight /* OUT: Bitmask of terms to highlight */ -){ - int iStart = pIter->iCurrent; /* First token of snippet */ - int iScore = 0; /* Score of this snippet */ - int i; /* Loop counter */ - u64 mCover = 0; /* Mask of phrases covered by this snippet */ - u64 mHighlight = 0; /* Mask of tokens to highlight in snippet */ - - for(i=0; inPhrase; i++){ - SnippetPhrase *pPhrase = &pIter->aPhrase[i]; - if( pPhrase->pTail ){ - char *pCsr = pPhrase->pTail; - int iCsr = pPhrase->iTail; - - while( iCsr<(iStart+pIter->nSnippet) ){ - int j; - u64 mPhrase = (u64)1 << i; - u64 mPos = (u64)1 << (iCsr - iStart); - assert( iCsr>=iStart ); - if( (mCover|mCovered)&mPhrase ){ - iScore++; - }else{ - iScore += 1000; - } - mCover |= mPhrase; - - for(j=0; jnToken; j++){ - mHighlight |= (mPos>>j); - } - - if( 0==(*pCsr & 0x0FE) ) break; - fts3GetDeltaPosition(&pCsr, &iCsr); - } - } - } - - /* Set the output variables before returning. */ - *piToken = iStart; - *piScore = iScore; - *pmCover = mCover; - *pmHighlight = mHighlight; -} - -/* -** This function is an fts3ExprIterate() callback used by fts3BestSnippet(). -** Each invocation populates an element of the SnippetIter.aPhrase[] array. -*/ -static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ - SnippetIter *p = (SnippetIter *)ctx; - SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; - char *pCsr; - int rc; - - pPhrase->nToken = pExpr->pPhrase->nToken; - rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); - assert( rc==SQLITE_OK || pCsr==0 ); - if( pCsr ){ - int iFirst = 0; - pPhrase->pList = pCsr; - fts3GetDeltaPosition(&pCsr, &iFirst); - assert( iFirst>=0 ); - pPhrase->pHead = pCsr; - pPhrase->pTail = pCsr; - pPhrase->iHead = iFirst; - pPhrase->iTail = iFirst; - }else{ - assert( rc!=SQLITE_OK || ( - pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 - )); - } - - return rc; -} - -/* -** Select the fragment of text consisting of nFragment contiguous tokens -** from column iCol that represent the "best" snippet. The best snippet -** is the snippet with the highest score, where scores are calculated -** by adding: -** -** (a) +1 point for each occurrence of a matchable phrase in the snippet. -** -** (b) +1000 points for the first occurrence of each matchable phrase in -** the snippet for which the corresponding mCovered bit is not set. -** -** The selected snippet parameters are stored in structure *pFragment before -** returning. The score of the selected snippet is stored in *piScore -** before returning. -*/ -static int fts3BestSnippet( - int nSnippet, /* Desired snippet length */ - Fts3Cursor *pCsr, /* Cursor to create snippet for */ - int iCol, /* Index of column to create snippet from */ - u64 mCovered, /* Mask of phrases already covered */ - u64 *pmSeen, /* IN/OUT: Mask of phrases seen */ - SnippetFragment *pFragment, /* OUT: Best snippet found */ - int *piScore /* OUT: Score of snippet pFragment */ -){ - int rc; /* Return Code */ - int nList; /* Number of phrases in expression */ - SnippetIter sIter; /* Iterates through snippet candidates */ - int nByte; /* Number of bytes of space to allocate */ - int iBestScore = -1; /* Best snippet score found so far */ - int i; /* Loop counter */ - - memset(&sIter, 0, sizeof(sIter)); - - /* Iterate through the phrases in the expression to count them. The same - ** callback makes sure the doclists are loaded for each phrase. - */ - rc = fts3ExprLoadDoclists(pCsr, &nList, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Now that it is known how many phrases there are, allocate and zero - ** the required space using malloc(). - */ - nByte = sizeof(SnippetPhrase) * nList; - sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte); - if( !sIter.aPhrase ){ - return SQLITE_NOMEM; - } - memset(sIter.aPhrase, 0, nByte); - - /* Initialize the contents of the SnippetIter object. Then iterate through - ** the set of phrases in the expression to populate the aPhrase[] array. - */ - sIter.pCsr = pCsr; - sIter.iCol = iCol; - sIter.nSnippet = nSnippet; - sIter.nPhrase = nList; - sIter.iCurrent = -1; - rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter); - if( rc==SQLITE_OK ){ - - /* Set the *pmSeen output variable. */ - for(i=0; iiCol = iCol; - while( !fts3SnippetNextCandidate(&sIter) ){ - int iPos; - int iScore; - u64 mCover; - u64 mHighlite; - fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); - assert( iScore>=0 ); - if( iScore>iBestScore ){ - pFragment->iPos = iPos; - pFragment->hlmask = mHighlite; - pFragment->covered = mCover; - iBestScore = iScore; - } - } - - *piScore = iBestScore; - } - sqlite3_free(sIter.aPhrase); - return rc; -} - - -/* -** Append a string to the string-buffer passed as the first argument. -** -** If nAppend is negative, then the length of the string zAppend is -** determined using strlen(). -*/ -static int fts3StringAppend( - StrBuffer *pStr, /* Buffer to append to */ - const char *zAppend, /* Pointer to data to append to buffer */ - int nAppend /* Size of zAppend in bytes (or -1) */ -){ - if( nAppend<0 ){ - nAppend = (int)strlen(zAppend); - } - - /* If there is insufficient space allocated at StrBuffer.z, use realloc() - ** to grow the buffer until so that it is big enough to accomadate the - ** appended data. - */ - if( pStr->n+nAppend+1>=pStr->nAlloc ){ - int nAlloc = pStr->nAlloc+nAppend+100; - char *zNew = sqlite3_realloc(pStr->z, nAlloc); - if( !zNew ){ - return SQLITE_NOMEM; - } - pStr->z = zNew; - pStr->nAlloc = nAlloc; - } - assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) ); - - /* Append the data to the string buffer. */ - memcpy(&pStr->z[pStr->n], zAppend, nAppend); - pStr->n += nAppend; - pStr->z[pStr->n] = '\0'; - - return SQLITE_OK; -} - -/* -** The fts3BestSnippet() function often selects snippets that end with a -** query term. That is, the final term of the snippet is always a term -** that requires highlighting. For example, if 'X' is a highlighted term -** and '.' is a non-highlighted term, BestSnippet() may select: -** -** ........X.....X -** -** This function "shifts" the beginning of the snippet forward in the -** document so that there are approximately the same number of -** non-highlighted terms to the right of the final highlighted term as there -** are to the left of the first highlighted term. For example, to this: -** -** ....X.....X.... -** -** This is done as part of extracting the snippet text, not when selecting -** the snippet. Snippet selection is done based on doclists only, so there -** is no way for fts3BestSnippet() to know whether or not the document -** actually contains terms that follow the final highlighted term. -*/ -static int fts3SnippetShift( - Fts3Table *pTab, /* FTS3 table snippet comes from */ - int iLangid, /* Language id to use in tokenizing */ - int nSnippet, /* Number of tokens desired for snippet */ - const char *zDoc, /* Document text to extract snippet from */ - int nDoc, /* Size of buffer zDoc in bytes */ - int *piPos, /* IN/OUT: First token of snippet */ - u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */ -){ - u64 hlmask = *pHlmask; /* Local copy of initial highlight-mask */ - - if( hlmask ){ - int nLeft; /* Tokens to the left of first highlight */ - int nRight; /* Tokens to the right of last highlight */ - int nDesired; /* Ideal number of tokens to shift forward */ - - for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++); - for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++); - nDesired = (nLeft-nRight)/2; - - /* Ideally, the start of the snippet should be pushed forward in the - ** document nDesired tokens. This block checks if there are actually - ** nDesired tokens to the right of the snippet. If so, *piPos and - ** *pHlMask are updated to shift the snippet nDesired tokens to the - ** right. Otherwise, the snippet is shifted by the number of tokens - ** available. - */ - if( nDesired>0 ){ - int nShift; /* Number of tokens to shift snippet by */ - int iCurrent = 0; /* Token counter */ - int rc; /* Return Code */ - sqlite3_tokenizer_module *pMod; - sqlite3_tokenizer_cursor *pC; - pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; - - /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) - ** or more tokens in zDoc/nDoc. - */ - rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); - if( rc!=SQLITE_OK ){ - return rc; - } - while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ - const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; - rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); - } - pMod->xClose(pC); - if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; } - - nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet; - assert( nShift<=nDesired ); - if( nShift>0 ){ - *piPos += nShift; - *pHlmask = hlmask >> nShift; - } - } - } - return SQLITE_OK; -} - -/* -** Extract the snippet text for fragment pFragment from cursor pCsr and -** append it to string buffer pOut. -*/ -static int fts3SnippetText( - Fts3Cursor *pCsr, /* FTS3 Cursor */ - SnippetFragment *pFragment, /* Snippet to extract */ - int iFragment, /* Fragment number */ - int isLast, /* True for final fragment in snippet */ - int nSnippet, /* Number of tokens in extracted snippet */ - const char *zOpen, /* String inserted before highlighted term */ - const char *zClose, /* String inserted after highlighted term */ - const char *zEllipsis, /* String inserted between snippets */ - StrBuffer *pOut /* Write output here */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc; /* Return code */ - const char *zDoc; /* Document text to extract snippet from */ - int nDoc; /* Size of zDoc in bytes */ - int iCurrent = 0; /* Current token number of document */ - int iEnd = 0; /* Byte offset of end of current token */ - int isShiftDone = 0; /* True after snippet is shifted */ - int iPos = pFragment->iPos; /* First token of snippet */ - u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ - int iCol = pFragment->iCol+1; /* Query column to extract text from */ - sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ - sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ - - zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); - if( zDoc==0 ){ - if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ - return SQLITE_NOMEM; - } - return SQLITE_OK; - } - nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); - - /* Open a token cursor on the document. */ - pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; - rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); - if( rc!=SQLITE_OK ){ - return rc; - } - - while( rc==SQLITE_OK ){ - const char *ZDUMMY; /* Dummy argument used with tokenizer */ - int DUMMY1 = -1; /* Dummy argument used with tokenizer */ - int iBegin = 0; /* Offset in zDoc of start of token */ - int iFin = 0; /* Offset in zDoc of end of token */ - int isHighlight = 0; /* True for highlighted terms */ - - /* Variable DUMMY1 is initialized to a negative value above. Elsewhere - ** in the FTS code the variable that the third argument to xNext points to - ** is initialized to zero before the first (*but not necessarily - ** subsequent*) call to xNext(). This is done for a particular application - ** that needs to know whether or not the tokenizer is being used for - ** snippet generation or for some other purpose. - ** - ** Extreme care is required when writing code to depend on this - ** initialization. It is not a documented part of the tokenizer interface. - ** If a tokenizer is used directly by any code outside of FTS, this - ** convention might not be respected. */ - rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); - if( rc!=SQLITE_OK ){ - if( rc==SQLITE_DONE ){ - /* Special case - the last token of the snippet is also the last token - ** of the column. Append any punctuation that occurred between the end - ** of the previous token and the end of the document to the output. - ** Then break out of the loop. */ - rc = fts3StringAppend(pOut, &zDoc[iEnd], -1); - } - break; - } - if( iCurrentiLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask - ); - isShiftDone = 1; - - /* Now that the shift has been done, check if the initial "..." are - ** required. They are required if (a) this is not the first fragment, - ** or (b) this fragment does not begin at position 0 of its column. - */ - if( rc==SQLITE_OK ){ - if( iPos>0 || iFragment>0 ){ - rc = fts3StringAppend(pOut, zEllipsis, -1); - }else if( iBegin ){ - rc = fts3StringAppend(pOut, zDoc, iBegin); - } - } - if( rc!=SQLITE_OK || iCurrent=(iPos+nSnippet) ){ - if( isLast ){ - rc = fts3StringAppend(pOut, zEllipsis, -1); - } - break; - } - - /* Set isHighlight to true if this term should be highlighted. */ - isHighlight = (hlmask & ((u64)1 << (iCurrent-iPos)))!=0; - - if( iCurrent>iPos ) rc = fts3StringAppend(pOut, &zDoc[iEnd], iBegin-iEnd); - if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zOpen, -1); - if( rc==SQLITE_OK ) rc = fts3StringAppend(pOut, &zDoc[iBegin], iFin-iBegin); - if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zClose, -1); - - iEnd = iFin; - } - - pMod->xClose(pC); - return rc; -} - - -/* -** This function is used to count the entries in a column-list (a -** delta-encoded list of term offsets within a single column of a single -** row). When this function is called, *ppCollist should point to the -** beginning of the first varint in the column-list (the varint that -** contains the position of the first matching term in the column data). -** Before returning, *ppCollist is set to point to the first byte after -** the last varint in the column-list (either the 0x00 signifying the end -** of the position-list, or the 0x01 that precedes the column number of -** the next column in the position-list). -** -** The number of elements in the column-list is returned. -*/ -static int fts3ColumnlistCount(char **ppCollist){ - char *pEnd = *ppCollist; - char c = 0; - int nEntry = 0; - - /* A column-list is terminated by either a 0x01 or 0x00. */ - while( 0xFE & (*pEnd | c) ){ - c = *pEnd++ & 0x80; - if( !c ) nEntry++; - } - - *ppCollist = pEnd; - return nEntry; -} - -/* -** This function gathers 'y' or 'b' data for a single phrase. -*/ -static void fts3ExprLHits( - Fts3Expr *pExpr, /* Phrase expression node */ - MatchInfo *p /* Matchinfo context */ -){ - Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab; - int iStart; - Fts3Phrase *pPhrase = pExpr->pPhrase; - char *pIter = pPhrase->doclist.pList; - int iCol = 0; - - assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS ); - if( p->flag==FTS3_MATCHINFO_LHITS ){ - iStart = pExpr->iPhrase * p->nCol; - }else{ - iStart = pExpr->iPhrase * ((p->nCol + 31) / 32); - } - - while( 1 ){ - int nHit = fts3ColumnlistCount(&pIter); - if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ - if( p->flag==FTS3_MATCHINFO_LHITS ){ - p->aMatchinfo[iStart + iCol] = (u32)nHit; - }else if( nHit ){ - p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F)); - } - } - assert( *pIter==0x00 || *pIter==0x01 ); - if( *pIter!=0x01 ) break; - pIter++; - pIter += fts3GetVarint32(pIter, &iCol); - } -} - -/* -** Gather the results for matchinfo directives 'y' and 'b'. -*/ -static void fts3ExprLHitGather( - Fts3Expr *pExpr, - MatchInfo *p -){ - assert( (pExpr->pLeft==0)==(pExpr->pRight==0) ); - if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ - if( pExpr->pLeft ){ - fts3ExprLHitGather(pExpr->pLeft, p); - fts3ExprLHitGather(pExpr->pRight, p); - }else{ - fts3ExprLHits(pExpr, p); - } - } -} - -/* -** fts3ExprIterate() callback used to collect the "global" matchinfo stats -** for a single query. -** -** fts3ExprIterate() callback to load the 'global' elements of a -** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements -** of the matchinfo array that are constant for all rows returned by the -** current query. -** -** Argument pCtx is actually a pointer to a struct of type MatchInfo. This -** function populates Matchinfo.aMatchinfo[] as follows: -** -** for(iCol=0; iColpCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] - ); -} - -/* -** fts3ExprIterate() callback used to collect the "local" part of the -** FTS3_MATCHINFO_HITS array. The local stats are those elements of the -** array that are different for each row returned by the query. -*/ -static int fts3ExprLocalHitsCb( - Fts3Expr *pExpr, /* Phrase expression node */ - int iPhrase, /* Phrase number */ - void *pCtx /* Pointer to MatchInfo structure */ -){ - int rc = SQLITE_OK; - MatchInfo *p = (MatchInfo *)pCtx; - int iStart = iPhrase * p->nCol * 3; - int i; - - for(i=0; inCol && rc==SQLITE_OK; i++){ - char *pCsr; - rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); - if( pCsr ){ - p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); - }else{ - p->aMatchinfo[iStart+i*3] = 0; - } - } - - return rc; -} - -static int fts3MatchinfoCheck( - Fts3Table *pTab, - char cArg, - char **pzErr -){ - if( (cArg==FTS3_MATCHINFO_NPHRASE) - || (cArg==FTS3_MATCHINFO_NCOL) - || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) - || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) - || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) - || (cArg==FTS3_MATCHINFO_LCS) - || (cArg==FTS3_MATCHINFO_HITS) - || (cArg==FTS3_MATCHINFO_LHITS) - || (cArg==FTS3_MATCHINFO_LHITS_BM) - ){ - return SQLITE_OK; - } - sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); - return SQLITE_ERROR; -} - -static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ - int nVal; /* Number of integers output by cArg */ - - switch( cArg ){ - case FTS3_MATCHINFO_NDOC: - case FTS3_MATCHINFO_NPHRASE: - case FTS3_MATCHINFO_NCOL: - nVal = 1; - break; - - case FTS3_MATCHINFO_AVGLENGTH: - case FTS3_MATCHINFO_LENGTH: - case FTS3_MATCHINFO_LCS: - nVal = pInfo->nCol; - break; - - case FTS3_MATCHINFO_LHITS: - nVal = pInfo->nCol * pInfo->nPhrase; - break; - - case FTS3_MATCHINFO_LHITS_BM: - nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32); - break; - - default: - assert( cArg==FTS3_MATCHINFO_HITS ); - nVal = pInfo->nCol * pInfo->nPhrase * 3; - break; - } - - return nVal; -} - -static int fts3MatchinfoSelectDoctotal( - Fts3Table *pTab, - sqlite3_stmt **ppStmt, - sqlite3_int64 *pnDoc, - const char **paLen -){ - sqlite3_stmt *pStmt; - const char *a; - sqlite3_int64 nDoc; - - if( !*ppStmt ){ - int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); - if( rc!=SQLITE_OK ) return rc; - } - pStmt = *ppStmt; - assert( sqlite3_data_count(pStmt)==1 ); - - a = sqlite3_column_blob(pStmt, 0); - a += sqlite3Fts3GetVarint(a, &nDoc); - if( nDoc==0 ) return FTS_CORRUPT_VTAB; - *pnDoc = (u32)nDoc; - - if( paLen ) *paLen = a; - return SQLITE_OK; -} - -/* -** An instance of the following structure is used to store state while -** iterating through a multi-column position-list corresponding to the -** hits for a single phrase on a single row in order to calculate the -** values for a matchinfo() FTS3_MATCHINFO_LCS request. -*/ -typedef struct LcsIterator LcsIterator; -struct LcsIterator { - Fts3Expr *pExpr; /* Pointer to phrase expression */ - int iPosOffset; /* Tokens count up to end of this phrase */ - char *pRead; /* Cursor used to iterate through aDoclist */ - int iPos; /* Current position */ -}; - -/* -** If LcsIterator.iCol is set to the following value, the iterator has -** finished iterating through all offsets for all columns. -*/ -#define LCS_ITERATOR_FINISHED 0x7FFFFFFF; - -static int fts3MatchinfoLcsCb( - Fts3Expr *pExpr, /* Phrase expression node */ - int iPhrase, /* Phrase number (numbered from zero) */ - void *pCtx /* Pointer to MatchInfo structure */ -){ - LcsIterator *aIter = (LcsIterator *)pCtx; - aIter[iPhrase].pExpr = pExpr; - return SQLITE_OK; -} - -/* -** Advance the iterator passed as an argument to the next position. Return -** 1 if the iterator is at EOF or if it now points to the start of the -** position list for the next column. -*/ -static int fts3LcsIteratorAdvance(LcsIterator *pIter){ - char *pRead = pIter->pRead; - sqlite3_int64 iRead; - int rc = 0; - - pRead += sqlite3Fts3GetVarint(pRead, &iRead); - if( iRead==0 || iRead==1 ){ - pRead = 0; - rc = 1; - }else{ - pIter->iPos += (int)(iRead-2); - } - - pIter->pRead = pRead; - return rc; -} - -/* -** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag. -** -** If the call is successful, the longest-common-substring lengths for each -** column are written into the first nCol elements of the pInfo->aMatchinfo[] -** array before returning. SQLITE_OK is returned in this case. -** -** Otherwise, if an error occurs, an SQLite error code is returned and the -** data written to the first nCol elements of pInfo->aMatchinfo[] is -** undefined. -*/ -static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ - LcsIterator *aIter; - int i; - int iCol; - int nToken = 0; - - /* Allocate and populate the array of LcsIterator objects. The array - ** contains one element for each matchable phrase in the query. - **/ - aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase); - if( !aIter ) return SQLITE_NOMEM; - memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); - (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); - - for(i=0; inPhrase; i++){ - LcsIterator *pIter = &aIter[i]; - nToken -= pIter->pExpr->pPhrase->nToken; - pIter->iPosOffset = nToken; - } - - for(iCol=0; iColnCol; iCol++){ - int nLcs = 0; /* LCS value for this column */ - int nLive = 0; /* Number of iterators in aIter not at EOF */ - - for(i=0; inPhrase; i++){ - int rc; - LcsIterator *pIt = &aIter[i]; - rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); - if( rc!=SQLITE_OK ) return rc; - if( pIt->pRead ){ - pIt->iPos = pIt->iPosOffset; - fts3LcsIteratorAdvance(&aIter[i]); - nLive++; - } - } - - while( nLive>0 ){ - LcsIterator *pAdv = 0; /* The iterator to advance by one position */ - int nThisLcs = 0; /* LCS for the current iterator positions */ - - for(i=0; inPhrase; i++){ - LcsIterator *pIter = &aIter[i]; - if( pIter->pRead==0 ){ - /* This iterator is already at EOF for this column. */ - nThisLcs = 0; - }else{ - if( pAdv==0 || pIter->iPosiPos ){ - pAdv = pIter; - } - if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){ - nThisLcs++; - }else{ - nThisLcs = 1; - } - if( nThisLcs>nLcs ) nLcs = nThisLcs; - } - } - if( fts3LcsIteratorAdvance(pAdv) ) nLive--; - } - - pInfo->aMatchinfo[iCol] = nLcs; - } - - sqlite3_free(aIter); - return SQLITE_OK; -} - -/* -** Populate the buffer pInfo->aMatchinfo[] with an array of integers to -** be returned by the matchinfo() function. Argument zArg contains the -** format string passed as the second argument to matchinfo (or the -** default value "pcx" if no second argument was specified). The format -** string has already been validated and the pInfo->aMatchinfo[] array -** is guaranteed to be large enough for the output. -** -** If bGlobal is true, then populate all fields of the matchinfo() output. -** If it is false, then assume that those fields that do not change between -** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS) -** have already been populated. -** -** Return SQLITE_OK if successful, or an SQLite error code if an error -** occurs. If a value other than SQLITE_OK is returned, the state the -** pInfo->aMatchinfo[] buffer is left in is undefined. -*/ -static int fts3MatchinfoValues( - Fts3Cursor *pCsr, /* FTS3 cursor object */ - int bGlobal, /* True to grab the global stats */ - MatchInfo *pInfo, /* Matchinfo context object */ - const char *zArg /* Matchinfo format string */ -){ - int rc = SQLITE_OK; - int i; - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - sqlite3_stmt *pSelect = 0; - - for(i=0; rc==SQLITE_OK && zArg[i]; i++){ - pInfo->flag = zArg[i]; - switch( zArg[i] ){ - case FTS3_MATCHINFO_NPHRASE: - if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; - break; - - case FTS3_MATCHINFO_NCOL: - if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; - break; - - case FTS3_MATCHINFO_NDOC: - if( bGlobal ){ - sqlite3_int64 nDoc = 0; - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); - pInfo->aMatchinfo[0] = (u32)nDoc; - } - break; - - case FTS3_MATCHINFO_AVGLENGTH: - if( bGlobal ){ - sqlite3_int64 nDoc; /* Number of rows in table */ - const char *a; /* Aggregate column length array */ - - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a); - if( rc==SQLITE_OK ){ - int iCol; - for(iCol=0; iColnCol; iCol++){ - u32 iVal; - sqlite3_int64 nToken; - a += sqlite3Fts3GetVarint(a, &nToken); - iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); - pInfo->aMatchinfo[iCol] = iVal; - } - } - } - break; - - case FTS3_MATCHINFO_LENGTH: { - sqlite3_stmt *pSelectDocsize = 0; - rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); - if( rc==SQLITE_OK ){ - int iCol; - const char *a = sqlite3_column_blob(pSelectDocsize, 0); - for(iCol=0; iColnCol; iCol++){ - sqlite3_int64 nToken; - a += sqlite3Fts3GetVarint(a, &nToken); - pInfo->aMatchinfo[iCol] = (u32)nToken; - } - } - sqlite3_reset(pSelectDocsize); - break; - } - - case FTS3_MATCHINFO_LCS: - rc = fts3ExprLoadDoclists(pCsr, 0, 0); - if( rc==SQLITE_OK ){ - rc = fts3MatchinfoLcs(pCsr, pInfo); - } - break; - - case FTS3_MATCHINFO_LHITS_BM: - case FTS3_MATCHINFO_LHITS: { - int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); - memset(pInfo->aMatchinfo, 0, nZero); - fts3ExprLHitGather(pCsr->pExpr, pInfo); - break; - } - - default: { - Fts3Expr *pExpr; - assert( zArg[i]==FTS3_MATCHINFO_HITS ); - pExpr = pCsr->pExpr; - rc = fts3ExprLoadDoclists(pCsr, 0, 0); - if( rc!=SQLITE_OK ) break; - if( bGlobal ){ - if( pCsr->pDeferred ){ - rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0); - if( rc!=SQLITE_OK ) break; - } - rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); - sqlite3Fts3EvalTestDeferred(pCsr, &rc); - if( rc!=SQLITE_OK ) break; - } - (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); - break; - } - } - - pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); - } - - sqlite3_reset(pSelect); - return rc; -} - - -/* -** Populate pCsr->aMatchinfo[] with data for the current row. The -** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). -*/ -static void fts3GetMatchinfo( - sqlite3_context *pCtx, /* Return results here */ - Fts3Cursor *pCsr, /* FTS3 Cursor object */ - const char *zArg /* Second argument to matchinfo() function */ -){ - MatchInfo sInfo; - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc = SQLITE_OK; - int bGlobal = 0; /* Collect 'global' stats as well as local */ - - u32 *aOut = 0; - void (*xDestroyOut)(void*) = 0; - - memset(&sInfo, 0, sizeof(MatchInfo)); - sInfo.pCursor = pCsr; - sInfo.nCol = pTab->nColumn; - - /* If there is cached matchinfo() data, but the format string for the - ** cache does not match the format string for this request, discard - ** the cached data. */ - if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){ - sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); - pCsr->pMIBuffer = 0; - } - - /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the - ** matchinfo function has been called for this query. In this case - ** allocate the array used to accumulate the matchinfo data and - ** initialize those elements that are constant for every row. - */ - if( pCsr->pMIBuffer==0 ){ - int nMatchinfo = 0; /* Number of u32 elements in match-info */ - int i; /* Used to iterate through zArg */ - - /* Determine the number of phrases in the query */ - pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); - sInfo.nPhrase = pCsr->nPhrase; - - /* Determine the number of integers in the buffer returned by this call. */ - for(i=0; zArg[i]; i++){ - char *zErr = 0; - if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ - sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); - return; - } - nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); - } - - /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ - pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg); - if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM; - - pCsr->isMatchinfoNeeded = 1; - bGlobal = 1; - } - - if( rc==SQLITE_OK ){ - xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut); - if( xDestroyOut==0 ){ - rc = SQLITE_NOMEM; - } - } - - if( rc==SQLITE_OK ){ - sInfo.aMatchinfo = aOut; - sInfo.nPhrase = pCsr->nPhrase; - rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); - if( bGlobal ){ - fts3MIBufferSetGlobal(pCsr->pMIBuffer); - } - } - - if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(pCtx, rc); - if( xDestroyOut ) xDestroyOut(aOut); - }else{ - int n = pCsr->pMIBuffer->nElem * sizeof(u32); - sqlite3_result_blob(pCtx, aOut, n, xDestroyOut); - } -} - -/* -** Implementation of snippet() function. -*/ -SQLITE_PRIVATE void sqlite3Fts3Snippet( - sqlite3_context *pCtx, /* SQLite function call context */ - Fts3Cursor *pCsr, /* Cursor object */ - const char *zStart, /* Snippet start text - "" */ - const char *zEnd, /* Snippet end text - "" */ - const char *zEllipsis, /* Snippet ellipsis text - "..." */ - int iCol, /* Extract snippet from this column */ - int nToken /* Approximate number of tokens in snippet */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - int rc = SQLITE_OK; - int i; - StrBuffer res = {0, 0, 0}; - - /* The returned text includes up to four fragments of text extracted from - ** the data in the current row. The first iteration of the for(...) loop - ** below attempts to locate a single fragment of text nToken tokens in - ** size that contains at least one instance of all phrases in the query - ** expression that appear in the current row. If such a fragment of text - ** cannot be found, the second iteration of the loop attempts to locate - ** a pair of fragments, and so on. - */ - int nSnippet = 0; /* Number of fragments in this snippet */ - SnippetFragment aSnippet[4]; /* Maximum of 4 fragments per snippet */ - int nFToken = -1; /* Number of tokens in each fragment */ - - if( !pCsr->pExpr ){ - sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); - return; - } - - for(nSnippet=1; 1; nSnippet++){ - - int iSnip; /* Loop counter 0..nSnippet-1 */ - u64 mCovered = 0; /* Bitmask of phrases covered by snippet */ - u64 mSeen = 0; /* Bitmask of phrases seen by BestSnippet() */ - - if( nToken>=0 ){ - nFToken = (nToken+nSnippet-1) / nSnippet; - }else{ - nFToken = -1 * nToken; - } - - for(iSnip=0; iSnipnColumn; iRead++){ - SnippetFragment sF = {0, 0, 0, 0}; - int iS = 0; - if( iCol>=0 && iRead!=iCol ) continue; - - /* Find the best snippet of nFToken tokens in column iRead. */ - rc = fts3BestSnippet(nFToken, pCsr, iRead, mCovered, &mSeen, &sF, &iS); - if( rc!=SQLITE_OK ){ - goto snippet_out; - } - if( iS>iBestScore ){ - *pFragment = sF; - iBestScore = iS; - } - } - - mCovered |= pFragment->covered; - } - - /* If all query phrases seen by fts3BestSnippet() are present in at least - ** one of the nSnippet snippet fragments, break out of the loop. - */ - assert( (mCovered&mSeen)==mCovered ); - if( mSeen==mCovered || nSnippet==SizeofArray(aSnippet) ) break; - } - - assert( nFToken>0 ); - - for(i=0; ipCsr, pExpr, p->iCol, &pList); - nTerm = pExpr->pPhrase->nToken; - if( pList ){ - fts3GetDeltaPosition(&pList, &iPos); - assert( iPos>=0 ); - } - - for(iTerm=0; iTermaTerm[p->iTerm++]; - pT->iOff = nTerm-iTerm-1; - pT->pList = pList; - pT->iPos = iPos; - } - - return rc; -} - -/* -** Implementation of offsets() function. -*/ -SQLITE_PRIVATE void sqlite3Fts3Offsets( - sqlite3_context *pCtx, /* SQLite function call context */ - Fts3Cursor *pCsr /* Cursor object */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; - int rc; /* Return Code */ - int nToken; /* Number of tokens in query */ - int iCol; /* Column currently being processed */ - StrBuffer res = {0, 0, 0}; /* Result string */ - TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ - - if( !pCsr->pExpr ){ - sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); - return; - } - - memset(&sCtx, 0, sizeof(sCtx)); - assert( pCsr->isRequireSeek==0 ); - - /* Count the number of terms in the query */ - rc = fts3ExprLoadDoclists(pCsr, 0, &nToken); - if( rc!=SQLITE_OK ) goto offsets_out; - - /* Allocate the array of TermOffset iterators. */ - sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken); - if( 0==sCtx.aTerm ){ - rc = SQLITE_NOMEM; - goto offsets_out; - } - sCtx.iDocid = pCsr->iPrevId; - sCtx.pCsr = pCsr; - - /* Loop through the table columns, appending offset information to - ** string-buffer res for each column. - */ - for(iCol=0; iColnColumn; iCol++){ - sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ - const char *ZDUMMY; /* Dummy argument used with xNext() */ - int NDUMMY = 0; /* Dummy argument used with xNext() */ - int iStart = 0; - int iEnd = 0; - int iCurrent = 0; - const char *zDoc; - int nDoc; - - /* Initialize the contents of sCtx.aTerm[] for column iCol. There is - ** no way that this operation can fail, so the return code from - ** fts3ExprIterate() can be discarded. - */ - sCtx.iCol = iCol; - sCtx.iTerm = 0; - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); - - /* Retreive the text stored in column iCol. If an SQL NULL is stored - ** in column iCol, jump immediately to the next iteration of the loop. - ** If an OOM occurs while retrieving the data (this can happen if SQLite - ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM - ** to the caller. - */ - zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); - nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); - if( zDoc==0 ){ - if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ - continue; - } - rc = SQLITE_NOMEM; - goto offsets_out; - } - - /* Initialize a tokenizer iterator to iterate through column iCol. */ - rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, - zDoc, nDoc, &pC - ); - if( rc!=SQLITE_OK ) goto offsets_out; - - rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); - while( rc==SQLITE_OK ){ - int i; /* Used to loop through terms */ - int iMinPos = 0x7FFFFFFF; /* Position of next token */ - TermOffset *pTerm = 0; /* TermOffset associated with next token */ - - for(i=0; ipList && (pT->iPos-pT->iOff)iPos-pT->iOff; - pTerm = pT; - } - } - - if( !pTerm ){ - /* All offsets for this column have been gathered. */ - rc = SQLITE_DONE; - }else{ - assert( iCurrent<=iMinPos ); - if( 0==(0xFE&*pTerm->pList) ){ - pTerm->pList = 0; - }else{ - fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos); - } - while( rc==SQLITE_OK && iCurrentxNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); - } - if( rc==SQLITE_OK ){ - char aBuffer[64]; - sqlite3_snprintf(sizeof(aBuffer), aBuffer, - "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart - ); - rc = fts3StringAppend(&res, aBuffer, -1); - }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){ - rc = FTS_CORRUPT_VTAB; - } - } - } - if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - } - - pMod->xClose(pC); - if( rc!=SQLITE_OK ) goto offsets_out; - } - - offsets_out: - sqlite3_free(sCtx.aTerm); - assert( rc!=SQLITE_DONE ); - sqlite3Fts3SegmentsClose(pTab); - if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(pCtx, rc); - sqlite3_free(res.z); - }else{ - sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free); - } - return; -} - -/* -** Implementation of matchinfo() function. -*/ -SQLITE_PRIVATE void sqlite3Fts3Matchinfo( - sqlite3_context *pContext, /* Function call context */ - Fts3Cursor *pCsr, /* FTS3 table cursor */ - const char *zArg /* Second arg to matchinfo() function */ -){ - Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - const char *zFormat; - - if( zArg ){ - zFormat = zArg; - }else{ - zFormat = FTS3_MATCHINFO_DEFAULT; - } - - if( !pCsr->pExpr ){ - sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); - return; - }else{ - /* Retrieve matchinfo() data. */ - fts3GetMatchinfo(pContext, pCsr, zFormat); - sqlite3Fts3SegmentsClose(pTab); - } -} - -#endif - -/************** End of fts3_snippet.c ****************************************/ -/************** Begin file fts3_unicode.c ************************************/ -/* -** 2012 May 24 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** Implementation of the "unicode" full-text-search tokenizer. -*/ - -#ifndef SQLITE_DISABLE_FTS3_UNICODE - -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) - -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* #include "fts3_tokenizer.h" */ - -/* -** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied -** from the sqlite3 source file utf.c. If this file is compiled as part -** of the amalgamation, they are not required. -*/ -#ifndef SQLITE_AMALGAMATION - -static const unsigned char sqlite3Utf8Trans1[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, -}; - -#define READ_UTF8(zIn, zTerm, c) \ - c = *(zIn++); \ - if( c>=0xc0 ){ \ - c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ - c = (c<<6) + (0x3f & *(zIn++)); \ - } \ - if( c<0x80 \ - || (c&0xFFFFF800)==0xD800 \ - || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ - } - -#define WRITE_UTF8(zOut, c) { \ - if( c<0x00080 ){ \ - *zOut++ = (u8)(c&0xFF); \ - } \ - else if( c<0x00800 ){ \ - *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ - else if( c<0x10000 ){ \ - *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - }else{ \ - *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ - *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ -} - -#endif /* ifndef SQLITE_AMALGAMATION */ - -typedef struct unicode_tokenizer unicode_tokenizer; -typedef struct unicode_cursor unicode_cursor; - -struct unicode_tokenizer { - sqlite3_tokenizer base; - int bRemoveDiacritic; - int nException; - int *aiException; -}; - -struct unicode_cursor { - sqlite3_tokenizer_cursor base; - const unsigned char *aInput; /* Input text being tokenized */ - int nInput; /* Size of aInput[] in bytes */ - int iOff; /* Current offset within aInput[] */ - int iToken; /* Index of next token to be returned */ - char *zToken; /* storage for current token */ - int nAlloc; /* space allocated at zToken */ -}; - - -/* -** Destroy a tokenizer allocated by unicodeCreate(). -*/ -static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ - if( pTokenizer ){ - unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer; - sqlite3_free(p->aiException); - sqlite3_free(p); - } - return SQLITE_OK; -} - -/* -** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE -** statement has specified that the tokenizer for this table shall consider -** all characters in string zIn/nIn to be separators (if bAlnum==0) or -** token characters (if bAlnum==1). -** -** For each codepoint in the zIn/nIn string, this function checks if the -** sqlite3FtsUnicodeIsalnum() function already returns the desired result. -** If so, no action is taken. Otherwise, the codepoint is added to the -** unicode_tokenizer.aiException[] array. For the purposes of tokenization, -** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all -** codepoints in the aiException[] array. -** -** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic() -** identifies as a diacritic) occurs in the zIn/nIn string it is ignored. -** It is not possible to change the behavior of the tokenizer with respect -** to these codepoints. -*/ -static int unicodeAddExceptions( - unicode_tokenizer *p, /* Tokenizer to add exceptions to */ - int bAlnum, /* Replace Isalnum() return value with this */ - const char *zIn, /* Array of characters to make exceptions */ - int nIn /* Length of z in bytes */ -){ - const unsigned char *z = (const unsigned char *)zIn; - const unsigned char *zTerm = &z[nIn]; - int iCode; - int nEntry = 0; - - assert( bAlnum==0 || bAlnum==1 ); - - while( zaiException, (p->nException+nEntry)*sizeof(int)); - if( aNew==0 ) return SQLITE_NOMEM; - nNew = p->nException; - - z = (const unsigned char *)zIn; - while( zi; j--) aNew[j] = aNew[j-1]; - aNew[i] = iCode; - nNew++; - } - } - p->aiException = aNew; - p->nException = nNew; - } - - return SQLITE_OK; -} - -/* -** Return true if the p->aiException[] array contains the value iCode. -*/ -static int unicodeIsException(unicode_tokenizer *p, int iCode){ - if( p->nException>0 ){ - int *a = p->aiException; - int iLo = 0; - int iHi = p->nException-1; - - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - if( iCode==a[iTest] ){ - return 1; - }else if( iCode>a[iTest] ){ - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - } - - return 0; -} - -/* -** Return true if, for the purposes of tokenization, codepoint iCode is -** considered a token character (not a separator). -*/ -static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){ - assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 ); - return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode); -} - -/* -** Create a new tokenizer instance. -*/ -static int unicodeCreate( - int nArg, /* Size of array argv[] */ - const char * const *azArg, /* Tokenizer creation arguments */ - sqlite3_tokenizer **pp /* OUT: New tokenizer handle */ -){ - unicode_tokenizer *pNew; /* New tokenizer object */ - int i; - int rc = SQLITE_OK; - - pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); - if( pNew==NULL ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(unicode_tokenizer)); - pNew->bRemoveDiacritic = 1; - - for(i=0; rc==SQLITE_OK && ibRemoveDiacritic = 1; - } - else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ - pNew->bRemoveDiacritic = 0; - } - else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){ - rc = unicodeAddExceptions(pNew, 1, &z[11], n-11); - } - else if( n>=11 && memcmp("separators=", z, 11)==0 ){ - rc = unicodeAddExceptions(pNew, 0, &z[11], n-11); - } - else{ - /* Unrecognized argument */ - rc = SQLITE_ERROR; - } - } - - if( rc!=SQLITE_OK ){ - unicodeDestroy((sqlite3_tokenizer *)pNew); - pNew = 0; - } - *pp = (sqlite3_tokenizer *)pNew; - return rc; -} - -/* -** Prepare to begin tokenizing a particular string. The input -** string to be tokenized is pInput[0..nBytes-1]. A cursor -** used to incrementally tokenize this string is returned in -** *ppCursor. -*/ -static int unicodeOpen( - sqlite3_tokenizer *p, /* The tokenizer */ - const char *aInput, /* Input string */ - int nInput, /* Size of string aInput in bytes */ - sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ -){ - unicode_cursor *pCsr; - - pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); - if( pCsr==0 ){ - return SQLITE_NOMEM; - } - memset(pCsr, 0, sizeof(unicode_cursor)); - - pCsr->aInput = (const unsigned char *)aInput; - if( aInput==0 ){ - pCsr->nInput = 0; - }else if( nInput<0 ){ - pCsr->nInput = (int)strlen(aInput); - }else{ - pCsr->nInput = nInput; - } - - *pp = &pCsr->base; - UNUSED_PARAMETER(p); - return SQLITE_OK; -} - -/* -** Close a tokenization cursor previously opened by a call to -** simpleOpen() above. -*/ -static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ - unicode_cursor *pCsr = (unicode_cursor *) pCursor; - sqlite3_free(pCsr->zToken); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** Extract the next token from a tokenization cursor. The cursor must -** have been opened by a prior call to simpleOpen(). -*/ -static int unicodeNext( - sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ - const char **paToken, /* OUT: Token text */ - int *pnToken, /* OUT: Number of bytes at *paToken */ - int *piStart, /* OUT: Starting offset of token */ - int *piEnd, /* OUT: Ending offset of token */ - int *piPos /* OUT: Position integer of token */ -){ - unicode_cursor *pCsr = (unicode_cursor *)pC; - unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer); - int iCode = 0; - char *zOut; - const unsigned char *z = &pCsr->aInput[pCsr->iOff]; - const unsigned char *zStart = z; - const unsigned char *zEnd; - const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput]; - - /* Scan past any delimiter characters before the start of the next token. - ** Return SQLITE_DONE early if this takes us all the way to the end of - ** the input. */ - while( z=zTerm ) return SQLITE_DONE; - - zOut = pCsr->zToken; - do { - int iOut; - - /* Grow the output buffer if required. */ - if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ - char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64); - if( !zNew ) return SQLITE_NOMEM; - zOut = &zNew[zOut - pCsr->zToken]; - pCsr->zToken = zNew; - pCsr->nAlloc += 64; - } - - /* Write the folded case of the last character read to the output */ - zEnd = z; - iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic); - if( iOut ){ - WRITE_UTF8(zOut, iOut); - } - - /* If the cursor is not at EOF, read the next character */ - if( z>=zTerm ) break; - READ_UTF8(z, zTerm, iCode); - }while( unicodeIsAlnum(p, iCode) - || sqlite3FtsUnicodeIsdiacritic(iCode) - ); - - /* Set the output variables and return. */ - pCsr->iOff = (int)(z - pCsr->aInput); - *paToken = pCsr->zToken; - *pnToken = (int)(zOut - pCsr->zToken); - *piStart = (int)(zStart - pCsr->aInput); - *piEnd = (int)(zEnd - pCsr->aInput); - *piPos = pCsr->iToken++; - return SQLITE_OK; -} - -/* -** Set *ppModule to a pointer to the sqlite3_tokenizer_module -** structure for the unicode tokenizer. -*/ -SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ - static const sqlite3_tokenizer_module module = { - 0, - unicodeCreate, - unicodeDestroy, - unicodeOpen, - unicodeClose, - unicodeNext, - 0, - }; - *ppModule = &module; -} - -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ -#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ - -/************** End of fts3_unicode.c ****************************************/ -/************** Begin file fts3_unicode2.c ***********************************/ -/* -** 2012 May 25 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -*/ - -/* -** DO NOT EDIT THIS MACHINE GENERATED FILE. -*/ - -#ifndef SQLITE_DISABLE_FTS3_UNICODE -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) - -/* #include */ - -/* -** Return true if the argument corresponds to a unicode codepoint -** classified as either a letter or a number. Otherwise false. -** -** The results are undefined if the value passed to this function -** is less than zero. -*/ -SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ - /* Each unsigned integer in the following array corresponds to a contiguous - ** range of unicode codepoints that are not either letters or numbers (i.e. - ** codepoints for which this function should return 0). - ** - ** The most significant 22 bits in each 32-bit value contain the first - ** codepoint in the range. The least significant 10 bits are used to store - ** the size of the range (always at least 1). In other words, the value - ** ((C<<22) + N) represents a range of N codepoints starting with codepoint - ** C. It is not possible to represent a range larger than 1023 codepoints - ** using this format. - */ - static const unsigned int aEntry[] = { - 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, - 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, - 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, - 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, - 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, - 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, - 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, - 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, - 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, - 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, - 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, - 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, - 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, - 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, - 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, - 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, - 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, - 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, - 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, - 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, - 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, - 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, - 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, - 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, - 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, - 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, - 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, - 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, - 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, - 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, - 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, - 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, - 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, - 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, - 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, - 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, - 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, - 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, - 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, - 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, - 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, - 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, - 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, - 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, - 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, - 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, - 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, - 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, - 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, - 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, - 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, - 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, - 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, - 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, - 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, - 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, - 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, - 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, - 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, - 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, - 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, - 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, - 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, - 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, - 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, - 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, - 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, - 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, - 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, - 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, - 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, - 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, - 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, - 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, - 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, - 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, - 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, - 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, - 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, - 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, - 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, - 0x380400F0, - }; - static const unsigned int aAscii[4] = { - 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, - }; - - if( c<128 ){ - return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); - }else if( c<(1<<22) ){ - unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; - int iRes = 0; - int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; - int iLo = 0; - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - if( key >= aEntry[iTest] ){ - iRes = iTest; - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - assert( aEntry[0]=aEntry[iRes] ); - return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); - } - return 1; -} - - -/* -** If the argument is a codepoint corresponding to a lowercase letter -** in the ASCII range with a diacritic added, return the codepoint -** of the ASCII letter only. For example, if passed 235 - "LATIN -** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER -** E"). The resuls of passing a codepoint that corresponds to an -** uppercase letter are undefined. -*/ -static int remove_diacritic(int c){ - unsigned short aDia[] = { - 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, - 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, - 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, - 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, - 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, - 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, - 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, - 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, - 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, - 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, - 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, - 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, - 62924, 63050, 63082, 63274, 63390, - }; - char aChar[] = { - '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', - 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', - 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', - 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', - 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', - 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', - 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', - 'e', 'i', 'o', 'u', 'y', - }; - - unsigned int key = (((unsigned int)c)<<3) | 0x00000007; - int iRes = 0; - int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; - int iLo = 0; - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - if( key >= aDia[iTest] ){ - iRes = iTest; - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - assert( key>=aDia[iRes] ); - return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]); -} - - -/* -** Return true if the argument interpreted as a unicode codepoint -** is a diacritical modifier character. -*/ -SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ - unsigned int mask0 = 0x08029FDF; - unsigned int mask1 = 0x000361F8; - if( c<768 || c>817 ) return 0; - return (c < 768+32) ? - (mask0 & (1 << (c-768))) : - (mask1 & (1 << (c-768-32))); -} - - -/* -** Interpret the argument as a unicode codepoint. If the codepoint -** is an upper case character that has a lower case equivalent, -** return the codepoint corresponding to the lower case version. -** Otherwise, return a copy of the argument. -** -** The results are undefined if the value passed to this function -** is less than zero. -*/ -SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ - /* Each entry in the following array defines a rule for folding a range - ** of codepoints to lower case. The rule applies to a range of nRange - ** codepoints starting at codepoint iCode. - ** - ** If the least significant bit in flags is clear, then the rule applies - ** to all nRange codepoints (i.e. all nRange codepoints are upper case and - ** need to be folded). Or, if it is set, then the rule only applies to - ** every second codepoint in the range, starting with codepoint C. - ** - ** The 7 most significant bits in flags are an index into the aiOff[] - ** array. If a specific codepoint C does require folding, then its lower - ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF). - ** - ** The contents of this array are generated by parsing the CaseFolding.txt - ** file distributed as part of the "Unicode Character Database". See - ** http://www.unicode.org for details. - */ - static const struct TableEntry { - unsigned short iCode; - unsigned char flags; - unsigned char nRange; - } aEntry[] = { - {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, - {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, - {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, - {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, - {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, - {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, - {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, - {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, - {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, - {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, - {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, - {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, - {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, - {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, - {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, - {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, - {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, - {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, - {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, - {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, - {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, - {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, - {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, - {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, - {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, - {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, - {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, - {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, - {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, - {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, - {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, - {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, - {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, - {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, - {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, - {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, - {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, - {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, - {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, - {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, - {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, - {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, - {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, - {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, - {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, - {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, - {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, - {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, - {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, - {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, - {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, - {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, - {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, - {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, - {65313, 14, 26}, - }; - static const unsigned short aiOff[] = { - 1, 2, 8, 15, 16, 26, 28, 32, - 37, 38, 40, 48, 63, 64, 69, 71, - 79, 80, 116, 202, 203, 205, 206, 207, - 209, 210, 211, 213, 214, 217, 218, 219, - 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, - 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, - 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, - 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, - 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, - 65514, 65521, 65527, 65528, 65529, - }; - - int ret = c; - - assert( c>=0 ); - assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); - - if( c<128 ){ - if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); - }else if( c<65536 ){ - int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; - int iLo = 0; - int iRes = -1; - - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - int cmp = (c - aEntry[iTest].iCode); - if( cmp>=0 ){ - iRes = iTest; - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - assert( iRes<0 || c>=aEntry[iRes].iCode ); - - if( iRes>=0 ){ - const struct TableEntry *p = &aEntry[iRes]; - if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ - ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; - assert( ret>0 ); - } - } - - if( bRemoveDiacritic ) ret = remove_diacritic(ret); - } - - else if( c>=66560 && c<66600 ){ - ret = c + 40; - } - - return ret; -} -#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ -#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ - -/************** End of fts3_unicode2.c ***************************************/ -/************** Begin file rtree.c *******************************************/ -/* -** 2001 September 15 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file contains code for implementations of the r-tree and r*-tree -** algorithms packaged as an SQLite virtual table module. -*/ - -/* -** Database Format of R-Tree Tables -** -------------------------------- -** -** The data structure for a single virtual r-tree table is stored in three -** native SQLite tables declared as follows. In each case, the '%' character -** in the table name is replaced with the user-supplied name of the r-tree -** table. -** -** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB) -** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) -** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER) -** -** The data for each node of the r-tree structure is stored in the %_node -** table. For each node that is not the root node of the r-tree, there is -** an entry in the %_parent table associating the node with its parent. -** And for each row of data in the table, there is an entry in the %_rowid -** table that maps from the entries rowid to the id of the node that it -** is stored on. -** -** The root node of an r-tree always exists, even if the r-tree table is -** empty. The nodeno of the root node is always 1. All other nodes in the -** table must be the same size as the root node. The content of each node -** is formatted as follows: -** -** 1. If the node is the root node (node 1), then the first 2 bytes -** of the node contain the tree depth as a big-endian integer. -** For non-root nodes, the first 2 bytes are left unused. -** -** 2. The next 2 bytes contain the number of entries currently -** stored in the node. -** -** 3. The remainder of the node contains the node entries. Each entry -** consists of a single 8-byte integer followed by an even number -** of 4-byte coordinates. For leaf nodes the integer is the rowid -** of a record. For internal nodes it is the node number of a -** child page. -*/ - -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) - -#ifndef SQLITE_CORE -/* #include "sqlite3ext.h" */ - SQLITE_EXTENSION_INIT1 -#else -/* #include "sqlite3.h" */ -#endif - -/* #include */ -/* #include */ -/* #include */ - -#ifndef SQLITE_AMALGAMATION -#include "sqlite3rtree.h" -typedef sqlite3_int64 i64; -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#endif - -/* The following macro is used to suppress compiler warnings. -*/ -#ifndef UNUSED_PARAMETER -# define UNUSED_PARAMETER(x) (void)(x) -#endif - -typedef struct Rtree Rtree; -typedef struct RtreeCursor RtreeCursor; -typedef struct RtreeNode RtreeNode; -typedef struct RtreeCell RtreeCell; -typedef struct RtreeConstraint RtreeConstraint; -typedef struct RtreeMatchArg RtreeMatchArg; -typedef struct RtreeGeomCallback RtreeGeomCallback; -typedef union RtreeCoord RtreeCoord; -typedef struct RtreeSearchPoint RtreeSearchPoint; - -/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ -#define RTREE_MAX_DIMENSIONS 5 - -/* Size of hash table Rtree.aHash. This hash table is not expected to -** ever contain very many entries, so a fixed number of buckets is -** used. -*/ -#define HASHSIZE 97 - -/* The xBestIndex method of this virtual table requires an estimate of -** the number of rows in the virtual table to calculate the costs of -** various strategies. If possible, this estimate is loaded from the -** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). -** Otherwise, if no sqlite_stat1 entry is available, use -** RTREE_DEFAULT_ROWEST. -*/ -#define RTREE_DEFAULT_ROWEST 1048576 -#define RTREE_MIN_ROWEST 100 - -/* -** An rtree virtual-table object. -*/ -struct Rtree { - sqlite3_vtab base; /* Base class. Must be first */ - sqlite3 *db; /* Host database connection */ - int iNodeSize; /* Size in bytes of each node in the node table */ - u8 nDim; /* Number of dimensions */ - u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ - u8 nBytesPerCell; /* Bytes consumed per cell */ - int iDepth; /* Current depth of the r-tree structure */ - char *zDb; /* Name of database containing r-tree table */ - char *zName; /* Name of r-tree table */ - int nBusy; /* Current number of users of this structure */ - i64 nRowEst; /* Estimated number of rows in this table */ - - /* List of nodes removed during a CondenseTree operation. List is - ** linked together via the pointer normally used for hash chains - - ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree - ** headed by the node (leaf nodes have RtreeNode.iNode==0). - */ - RtreeNode *pDeleted; - int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ - - /* Statements to read/write/delete a record from xxx_node */ - sqlite3_stmt *pReadNode; - sqlite3_stmt *pWriteNode; - sqlite3_stmt *pDeleteNode; - - /* Statements to read/write/delete a record from xxx_rowid */ - sqlite3_stmt *pReadRowid; - sqlite3_stmt *pWriteRowid; - sqlite3_stmt *pDeleteRowid; - - /* Statements to read/write/delete a record from xxx_parent */ - sqlite3_stmt *pReadParent; - sqlite3_stmt *pWriteParent; - sqlite3_stmt *pDeleteParent; - - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ -}; - -/* Possible values for Rtree.eCoordType: */ -#define RTREE_COORD_REAL32 0 -#define RTREE_COORD_INT32 1 - -/* -** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will -** only deal with integer coordinates. No floating point operations -** will be done. -*/ -#ifdef SQLITE_RTREE_INT_ONLY - typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ - typedef int RtreeValue; /* Low accuracy coordinate */ -# define RTREE_ZERO 0 -#else - typedef double RtreeDValue; /* High accuracy coordinate */ - typedef float RtreeValue; /* Low accuracy coordinate */ -# define RTREE_ZERO 0.0 -#endif - -/* -** When doing a search of an r-tree, instances of the following structure -** record intermediate results from the tree walk. -** -** The id is always a node-id. For iLevel>=1 the id is the node-id of -** the node that the RtreeSearchPoint represents. When iLevel==0, however, -** the id is of the parent node and the cell that RtreeSearchPoint -** represents is the iCell-th entry in the parent node. -*/ -struct RtreeSearchPoint { - RtreeDValue rScore; /* The score for this node. Smallest goes first. */ - sqlite3_int64 id; /* Node ID */ - u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ - u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ - u8 iCell; /* Cell index within the node */ -}; - -/* -** The minimum number of cells allowed for a node is a third of the -** maximum. In Gutman's notation: -** -** m = M/3 -** -** If an R*-tree "Reinsert" operation is required, the same number of -** cells are removed from the overfull node and reinserted into the tree. -*/ -#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) -#define RTREE_REINSERT(p) RTREE_MINCELLS(p) -#define RTREE_MAXCELLS 51 - -/* -** The smallest possible node-size is (512-64)==448 bytes. And the largest -** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). -** Therefore all non-root nodes must contain at least 3 entries. Since -** 2^40 is greater than 2^64, an r-tree structure always has a depth of -** 40 or less. -*/ -#define RTREE_MAX_DEPTH 40 - - -/* -** Number of entries in the cursor RtreeNode cache. The first entry is -** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining -** entries cache the RtreeNode for the first elements of the priority queue. -*/ -#define RTREE_CACHE_SZ 5 - -/* -** An rtree cursor object. -*/ -struct RtreeCursor { - sqlite3_vtab_cursor base; /* Base class. Must be first */ - u8 atEOF; /* True if at end of search */ - u8 bPoint; /* True if sPoint is valid */ - int iStrategy; /* Copy of idxNum search parameter */ - int nConstraint; /* Number of entries in aConstraint */ - RtreeConstraint *aConstraint; /* Search constraints. */ - int nPointAlloc; /* Number of slots allocated for aPoint[] */ - int nPoint; /* Number of slots used in aPoint[] */ - int mxLevel; /* iLevel value for root of the tree */ - RtreeSearchPoint *aPoint; /* Priority queue for search points */ - RtreeSearchPoint sPoint; /* Cached next search point */ - RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ - u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ -}; - -/* Return the Rtree of a RtreeCursor */ -#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) - -/* -** A coordinate can be either a floating point number or a integer. All -** coordinates within a single R-Tree are always of the same time. -*/ -union RtreeCoord { - RtreeValue f; /* Floating point value */ - int i; /* Integer value */ - u32 u; /* Unsigned for byte-order conversions */ -}; - -/* -** The argument is an RtreeCoord. Return the value stored within the RtreeCoord -** formatted as a RtreeDValue (double or int64). This macro assumes that local -** variable pRtree points to the Rtree structure associated with the -** RtreeCoord. -*/ -#ifdef SQLITE_RTREE_INT_ONLY -# define DCOORD(coord) ((RtreeDValue)coord.i) -#else -# define DCOORD(coord) ( \ - (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ - ((double)coord.f) : \ - ((double)coord.i) \ - ) -#endif - -/* -** A search constraint. -*/ -struct RtreeConstraint { - int iCoord; /* Index of constrained coordinate */ - int op; /* Constraining operation */ - union { - RtreeDValue rValue; /* Constraint value. */ - int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); - int (*xQueryFunc)(sqlite3_rtree_query_info*); - } u; - sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ -}; - -/* Possible values for RtreeConstraint.op */ -#define RTREE_EQ 0x41 /* A */ -#define RTREE_LE 0x42 /* B */ -#define RTREE_LT 0x43 /* C */ -#define RTREE_GE 0x44 /* D */ -#define RTREE_GT 0x45 /* E */ -#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ -#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ - - -/* -** An rtree structure node. -*/ -struct RtreeNode { - RtreeNode *pParent; /* Parent node */ - i64 iNode; /* The node number */ - int nRef; /* Number of references to this node */ - int isDirty; /* True if the node needs to be written to disk */ - u8 *zData; /* Content of the node, as should be on disk */ - RtreeNode *pNext; /* Next node in this hash collision chain */ -}; - -/* Return the number of cells in a node */ -#define NCELL(pNode) readInt16(&(pNode)->zData[2]) - -/* -** A single cell from a node, deserialized -*/ -struct RtreeCell { - i64 iRowid; /* Node or entry ID */ - RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ -}; - - -/* -** This object becomes the sqlite3_user_data() for the SQL functions -** that are created by sqlite3_rtree_geometry_callback() and -** sqlite3_rtree_query_callback() and which appear on the right of MATCH -** operators in order to constrain a search. -** -** xGeom and xQueryFunc are the callback functions. Exactly one of -** xGeom and xQueryFunc fields is non-NULL, depending on whether the -** SQL function was created using sqlite3_rtree_geometry_callback() or -** sqlite3_rtree_query_callback(). -** -** This object is deleted automatically by the destructor mechanism in -** sqlite3_create_function_v2(). -*/ -struct RtreeGeomCallback { - int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); - int (*xQueryFunc)(sqlite3_rtree_query_info*); - void (*xDestructor)(void*); - void *pContext; -}; - - -/* -** Value for the first field of every RtreeMatchArg object. The MATCH -** operator tests that the first field of a blob operand matches this -** value to avoid operating on invalid blobs (which could cause a segfault). -*/ -#define RTREE_GEOMETRY_MAGIC 0x891245AB - -/* -** An instance of this structure (in the form of a BLOB) is returned by -** the SQL functions that sqlite3_rtree_geometry_callback() and -** sqlite3_rtree_query_callback() create, and is read as the right-hand -** operand to the MATCH operator of an R-Tree. -*/ -struct RtreeMatchArg { - u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ - RtreeGeomCallback cb; /* Info about the callback functions */ - int nParam; /* Number of parameters to the SQL function */ - sqlite3_value **apSqlParam; /* Original SQL parameter values */ - RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ -}; - -#ifndef MAX -# define MAX(x,y) ((x) < (y) ? (y) : (x)) -#endif -#ifndef MIN -# define MIN(x,y) ((x) > (y) ? (y) : (x)) -#endif - -/* -** Functions to deserialize a 16 bit integer, 32 bit real number and -** 64 bit integer. The deserialized value is returned. -*/ -static int readInt16(u8 *p){ - return (p[0]<<8) + p[1]; -} -static void readCoord(u8 *p, RtreeCoord *pCoord){ - pCoord->u = ( - (((u32)p[0]) << 24) + - (((u32)p[1]) << 16) + - (((u32)p[2]) << 8) + - (((u32)p[3]) << 0) - ); -} -static i64 readInt64(u8 *p){ - return ( - (((i64)p[0]) << 56) + - (((i64)p[1]) << 48) + - (((i64)p[2]) << 40) + - (((i64)p[3]) << 32) + - (((i64)p[4]) << 24) + - (((i64)p[5]) << 16) + - (((i64)p[6]) << 8) + - (((i64)p[7]) << 0) - ); -} - -/* -** Functions to serialize a 16 bit integer, 32 bit real number and -** 64 bit integer. The value returned is the number of bytes written -** to the argument buffer (always 2, 4 and 8 respectively). -*/ -static int writeInt16(u8 *p, int i){ - p[0] = (i>> 8)&0xFF; - p[1] = (i>> 0)&0xFF; - return 2; -} -static int writeCoord(u8 *p, RtreeCoord *pCoord){ - u32 i; - assert( sizeof(RtreeCoord)==4 ); - assert( sizeof(u32)==4 ); - i = pCoord->u; - p[0] = (i>>24)&0xFF; - p[1] = (i>>16)&0xFF; - p[2] = (i>> 8)&0xFF; - p[3] = (i>> 0)&0xFF; - return 4; -} -static int writeInt64(u8 *p, i64 i){ - p[0] = (i>>56)&0xFF; - p[1] = (i>>48)&0xFF; - p[2] = (i>>40)&0xFF; - p[3] = (i>>32)&0xFF; - p[4] = (i>>24)&0xFF; - p[5] = (i>>16)&0xFF; - p[6] = (i>> 8)&0xFF; - p[7] = (i>> 0)&0xFF; - return 8; -} - -/* -** Increment the reference count of node p. -*/ -static void nodeReference(RtreeNode *p){ - if( p ){ - p->nRef++; - } -} - -/* -** Clear the content of node p (set all bytes to 0x00). -*/ -static void nodeZero(Rtree *pRtree, RtreeNode *p){ - memset(&p->zData[2], 0, pRtree->iNodeSize-2); - p->isDirty = 1; -} - -/* -** Given a node number iNode, return the corresponding key to use -** in the Rtree.aHash table. -*/ -static int nodeHash(i64 iNode){ - return iNode % HASHSIZE; -} - -/* -** Search the node hash table for node iNode. If found, return a pointer -** to it. Otherwise, return 0. -*/ -static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ - RtreeNode *p; - for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); - return p; -} - -/* -** Add node pNode to the node hash table. -*/ -static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ - int iHash; - assert( pNode->pNext==0 ); - iHash = nodeHash(pNode->iNode); - pNode->pNext = pRtree->aHash[iHash]; - pRtree->aHash[iHash] = pNode; -} - -/* -** Remove node pNode from the node hash table. -*/ -static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ - RtreeNode **pp; - if( pNode->iNode!=0 ){ - pp = &pRtree->aHash[nodeHash(pNode->iNode)]; - for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } - *pp = pNode->pNext; - pNode->pNext = 0; - } -} - -/* -** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), -** indicating that node has not yet been assigned a node number. It is -** assigned a node number when nodeWrite() is called to write the -** node contents out to the database. -*/ -static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ - RtreeNode *pNode; - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); - if( pNode ){ - memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; - pNode->pParent = pParent; - pNode->isDirty = 1; - nodeReference(pParent); - } - return pNode; -} - -/* -** Obtain a reference to an r-tree node. -*/ -static int nodeAcquire( - Rtree *pRtree, /* R-tree structure */ - i64 iNode, /* Node number to load */ - RtreeNode *pParent, /* Either the parent node or NULL */ - RtreeNode **ppNode /* OUT: Acquired node */ -){ - int rc; - int rc2 = SQLITE_OK; - RtreeNode *pNode; - - /* Check if the requested node is already in the hash table. If so, - ** increase its reference count and return it. - */ - if( (pNode = nodeHashLookup(pRtree, iNode)) ){ - assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); - if( pParent && !pNode->pParent ){ - nodeReference(pParent); - pNode->pParent = pParent; - } - pNode->nRef++; - *ppNode = pNode; - return SQLITE_OK; - } - - sqlite3_bind_int64(pRtree->pReadNode, 1, iNode); - rc = sqlite3_step(pRtree->pReadNode); - if( rc==SQLITE_ROW ){ - const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0); - if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){ - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); - if( !pNode ){ - rc2 = SQLITE_NOMEM; - }else{ - pNode->pParent = pParent; - pNode->zData = (u8 *)&pNode[1]; - pNode->nRef = 1; - pNode->iNode = iNode; - pNode->isDirty = 0; - pNode->pNext = 0; - memcpy(pNode->zData, zBlob, pRtree->iNodeSize); - nodeReference(pParent); - } - } - } - rc = sqlite3_reset(pRtree->pReadNode); - if( rc==SQLITE_OK ) rc = rc2; - - /* If the root node was just loaded, set pRtree->iDepth to the height - ** of the r-tree structure. A height of zero means all data is stored on - ** the root node. A height of one means the children of the root node - ** are the leaves, and so on. If the depth as specified on the root node - ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. - */ - if( pNode && iNode==1 ){ - pRtree->iDepth = readInt16(pNode->zData); - if( pRtree->iDepth>RTREE_MAX_DEPTH ){ - rc = SQLITE_CORRUPT_VTAB; - } - } - - /* If no error has occurred so far, check if the "number of entries" - ** field on the node is too large. If so, set the return code to - ** SQLITE_CORRUPT_VTAB. - */ - if( pNode && rc==SQLITE_OK ){ - if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ - rc = SQLITE_CORRUPT_VTAB; - } - } - - if( rc==SQLITE_OK ){ - if( pNode!=0 ){ - nodeHashInsert(pRtree, pNode); - }else{ - rc = SQLITE_CORRUPT_VTAB; - } - *ppNode = pNode; - }else{ - sqlite3_free(pNode); - *ppNode = 0; - } - - return rc; -} - -/* -** Overwrite cell iCell of node pNode with the contents of pCell. -*/ -static void nodeOverwriteCell( - Rtree *pRtree, /* The overall R-Tree */ - RtreeNode *pNode, /* The node into which the cell is to be written */ - RtreeCell *pCell, /* The cell to write */ - int iCell /* Index into pNode into which pCell is written */ -){ - int ii; - u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; - p += writeInt64(p, pCell->iRowid); - for(ii=0; ii<(pRtree->nDim*2); ii++){ - p += writeCoord(p, &pCell->aCoord[ii]); - } - pNode->isDirty = 1; -} - -/* -** Remove the cell with index iCell from node pNode. -*/ -static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ - u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; - u8 *pSrc = &pDst[pRtree->nBytesPerCell]; - int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; - memmove(pDst, pSrc, nByte); - writeInt16(&pNode->zData[2], NCELL(pNode)-1); - pNode->isDirty = 1; -} - -/* -** Insert the contents of cell pCell into node pNode. If the insert -** is successful, return SQLITE_OK. -** -** If there is not enough free space in pNode, return SQLITE_FULL. -*/ -static int nodeInsertCell( - Rtree *pRtree, /* The overall R-Tree */ - RtreeNode *pNode, /* Write new cell into this node */ - RtreeCell *pCell /* The cell to be inserted */ -){ - int nCell; /* Current number of cells in pNode */ - int nMaxCell; /* Maximum number of cells for pNode */ - - nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; - nCell = NCELL(pNode); - - assert( nCell<=nMaxCell ); - if( nCellzData[2], nCell+1); - pNode->isDirty = 1; - } - - return (nCell==nMaxCell); -} - -/* -** If the node is dirty, write it out to the database. -*/ -static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ - int rc = SQLITE_OK; - if( pNode->isDirty ){ - sqlite3_stmt *p = pRtree->pWriteNode; - if( pNode->iNode ){ - sqlite3_bind_int64(p, 1, pNode->iNode); - }else{ - sqlite3_bind_null(p, 1); - } - sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); - sqlite3_step(p); - pNode->isDirty = 0; - rc = sqlite3_reset(p); - if( pNode->iNode==0 && rc==SQLITE_OK ){ - pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); - nodeHashInsert(pRtree, pNode); - } - } - return rc; -} - -/* -** Release a reference to a node. If the node is dirty and the reference -** count drops to zero, the node data is written to the database. -*/ -static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ - int rc = SQLITE_OK; - if( pNode ){ - assert( pNode->nRef>0 ); - pNode->nRef--; - if( pNode->nRef==0 ){ - if( pNode->iNode==1 ){ - pRtree->iDepth = -1; - } - if( pNode->pParent ){ - rc = nodeRelease(pRtree, pNode->pParent); - } - if( rc==SQLITE_OK ){ - rc = nodeWrite(pRtree, pNode); - } - nodeHashDelete(pRtree, pNode); - sqlite3_free(pNode); - } - } - return rc; -} - -/* -** Return the 64-bit integer value associated with cell iCell of -** node pNode. If pNode is a leaf node, this is a rowid. If it is -** an internal node, then the 64-bit integer is a child page number. -*/ -static i64 nodeGetRowid( - Rtree *pRtree, /* The overall R-Tree */ - RtreeNode *pNode, /* The node from which to extract the ID */ - int iCell /* The cell index from which to extract the ID */ -){ - assert( iCellzData[4 + pRtree->nBytesPerCell*iCell]); -} - -/* -** Return coordinate iCoord from cell iCell in node pNode. -*/ -static void nodeGetCoord( - Rtree *pRtree, /* The overall R-Tree */ - RtreeNode *pNode, /* The node from which to extract a coordinate */ - int iCell, /* The index of the cell within the node */ - int iCoord, /* Which coordinate to extract */ - RtreeCoord *pCoord /* OUT: Space to write result to */ -){ - readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); -} - -/* -** Deserialize cell iCell of node pNode. Populate the structure pointed -** to by pCell with the results. -*/ -static void nodeGetCell( - Rtree *pRtree, /* The overall R-Tree */ - RtreeNode *pNode, /* The node containing the cell to be read */ - int iCell, /* Index of the cell within the node */ - RtreeCell *pCell /* OUT: Write the cell contents here */ -){ - u8 *pData; - RtreeCoord *pCoord; - int ii; - pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); - pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); - pCoord = pCell->aCoord; - for(ii=0; iinDim*2; ii++){ - readCoord(&pData[ii*4], &pCoord[ii]); - } -} - - -/* Forward declaration for the function that does the work of -** the virtual table module xCreate() and xConnect() methods. -*/ -static int rtreeInit( - sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int -); - -/* -** Rtree virtual table module xCreate method. -*/ -static int rtreeCreate( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); -} - -/* -** Rtree virtual table module xConnect method. -*/ -static int rtreeConnect( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); -} - -/* -** Increment the r-tree reference count. -*/ -static void rtreeReference(Rtree *pRtree){ - pRtree->nBusy++; -} - -/* -** Decrement the r-tree reference count. When the reference count reaches -** zero the structure is deleted. -*/ -static void rtreeRelease(Rtree *pRtree){ - pRtree->nBusy--; - if( pRtree->nBusy==0 ){ - sqlite3_finalize(pRtree->pReadNode); - sqlite3_finalize(pRtree->pWriteNode); - sqlite3_finalize(pRtree->pDeleteNode); - sqlite3_finalize(pRtree->pReadRowid); - sqlite3_finalize(pRtree->pWriteRowid); - sqlite3_finalize(pRtree->pDeleteRowid); - sqlite3_finalize(pRtree->pReadParent); - sqlite3_finalize(pRtree->pWriteParent); - sqlite3_finalize(pRtree->pDeleteParent); - sqlite3_free(pRtree); - } -} - -/* -** Rtree virtual table module xDisconnect method. -*/ -static int rtreeDisconnect(sqlite3_vtab *pVtab){ - rtreeRelease((Rtree *)pVtab); - return SQLITE_OK; -} - -/* -** Rtree virtual table module xDestroy method. -*/ -static int rtreeDestroy(sqlite3_vtab *pVtab){ - Rtree *pRtree = (Rtree *)pVtab; - int rc; - char *zCreate = sqlite3_mprintf( - "DROP TABLE '%q'.'%q_node';" - "DROP TABLE '%q'.'%q_rowid';" - "DROP TABLE '%q'.'%q_parent';", - pRtree->zDb, pRtree->zName, - pRtree->zDb, pRtree->zName, - pRtree->zDb, pRtree->zName - ); - if( !zCreate ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); - sqlite3_free(zCreate); - } - if( rc==SQLITE_OK ){ - rtreeRelease(pRtree); - } - - return rc; -} - -/* -** Rtree virtual table module xOpen method. -*/ -static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ - int rc = SQLITE_NOMEM; - RtreeCursor *pCsr; - - pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor)); - if( pCsr ){ - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = pVTab; - rc = SQLITE_OK; - } - *ppCursor = (sqlite3_vtab_cursor *)pCsr; - - return rc; -} - - -/* -** Free the RtreeCursor.aConstraint[] array and its contents. -*/ -static void freeCursorConstraints(RtreeCursor *pCsr){ - if( pCsr->aConstraint ){ - int i; /* Used to iterate through constraint array */ - for(i=0; inConstraint; i++){ - sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; - if( pInfo ){ - if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); - sqlite3_free(pInfo); - } - } - sqlite3_free(pCsr->aConstraint); - pCsr->aConstraint = 0; - } -} - -/* -** Rtree virtual table module xClose method. -*/ -static int rtreeClose(sqlite3_vtab_cursor *cur){ - Rtree *pRtree = (Rtree *)(cur->pVtab); - int ii; - RtreeCursor *pCsr = (RtreeCursor *)cur; - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - for(ii=0; iiaNode[ii]); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** Rtree virtual table module xEof method. -** -** Return non-zero if the cursor does not currently point to a valid -** record (i.e if the scan has finished), or zero otherwise. -*/ -static int rtreeEof(sqlite3_vtab_cursor *cur){ - RtreeCursor *pCsr = (RtreeCursor *)cur; - return pCsr->atEOF; -} - -/* -** Convert raw bits from the on-disk RTree record into a coordinate value. -** The on-disk format is big-endian and needs to be converted for little- -** endian platforms. The on-disk record stores integer coordinates if -** eInt is true and it stores 32-bit floating point records if eInt is -** false. a[] is the four bytes of the on-disk record to be decoded. -** Store the results in "r". -** -** There are three versions of this macro, one each for little-endian and -** big-endian processors and a third generic implementation. The endian- -** specific implementations are much faster and are preferred if the -** processor endianness is known at compile-time. The SQLITE_BYTEORDER -** macro is part of sqliteInt.h and hence the endian-specific -** implementation will only be used if this module is compiled as part -** of the amalgamation. -*/ -#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234 -#define RTREE_DECODE_COORD(eInt, a, r) { \ - RtreeCoord c; /* Coordinate decoded */ \ - memcpy(&c.u,a,4); \ - c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ - ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ - r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ -} -#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321 -#define RTREE_DECODE_COORD(eInt, a, r) { \ - RtreeCoord c; /* Coordinate decoded */ \ - memcpy(&c.u,a,4); \ - r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ -} -#else -#define RTREE_DECODE_COORD(eInt, a, r) { \ - RtreeCoord c; /* Coordinate decoded */ \ - c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ - +((u32)a[2]<<8) + a[3]; \ - r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ -} -#endif - -/* -** Check the RTree node or entry given by pCellData and p against the MATCH -** constraint pConstraint. -*/ -static int rtreeCallbackConstraint( - RtreeConstraint *pConstraint, /* The constraint to test */ - int eInt, /* True if RTree holding integer coordinates */ - u8 *pCellData, /* Raw cell content */ - RtreeSearchPoint *pSearch, /* Container of this cell */ - sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ - int *peWithin /* OUT: visibility of the cell */ -){ - int i; /* Loop counter */ - sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ - int nCoord = pInfo->nCoord; /* No. of coordinates */ - int rc; /* Callback return code */ - sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ - - assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); - assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); - - if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ - pInfo->iRowid = readInt64(pCellData); - } - pCellData += 8; - for(i=0; iop==RTREE_MATCH ){ - rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, - nCoord, aCoord, &i); - if( i==0 ) *peWithin = NOT_WITHIN; - *prScore = RTREE_ZERO; - }else{ - pInfo->aCoord = aCoord; - pInfo->iLevel = pSearch->iLevel - 1; - pInfo->rScore = pInfo->rParentScore = pSearch->rScore; - pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; - rc = pConstraint->u.xQueryFunc(pInfo); - if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; - if( pInfo->rScore<*prScore || *prScorerScore; - } - } - return rc; -} - -/* -** Check the internal RTree node given by pCellData against constraint p. -** If this constraint cannot be satisfied by any child within the node, -** set *peWithin to NOT_WITHIN. -*/ -static void rtreeNonleafConstraint( - RtreeConstraint *p, /* The constraint to test */ - int eInt, /* True if RTree holds integer coordinates */ - u8 *pCellData, /* Raw cell content as appears on disk */ - int *peWithin /* Adjust downward, as appropriate */ -){ - sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ - - /* p->iCoord might point to either a lower or upper bound coordinate - ** in a coordinate pair. But make pCellData point to the lower bound. - */ - pCellData += 8 + 4*(p->iCoord&0xfe); - - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ ); - switch( p->op ){ - case RTREE_LE: - case RTREE_LT: - case RTREE_EQ: - RTREE_DECODE_COORD(eInt, pCellData, val); - /* val now holds the lower bound of the coordinate pair */ - if( p->u.rValue>=val ) return; - if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ - /* Fall through for the RTREE_EQ case */ - - default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ - pCellData += 4; - RTREE_DECODE_COORD(eInt, pCellData, val); - /* val now holds the upper bound of the coordinate pair */ - if( p->u.rValue<=val ) return; - } - *peWithin = NOT_WITHIN; -} - -/* -** Check the leaf RTree cell given by pCellData against constraint p. -** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. -** If the constraint is satisfied, leave *peWithin unchanged. -** -** The constraint is of the form: xN op $val -** -** The op is given by p->op. The xN is p->iCoord-th coordinate in -** pCellData. $val is given by p->u.rValue. -*/ -static void rtreeLeafConstraint( - RtreeConstraint *p, /* The constraint to test */ - int eInt, /* True if RTree holds integer coordinates */ - u8 *pCellData, /* Raw cell content as appears on disk */ - int *peWithin /* Adjust downward, as appropriate */ -){ - RtreeDValue xN; /* Coordinate value converted to a double */ - - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ ); - pCellData += 8 + p->iCoord*4; - RTREE_DECODE_COORD(eInt, pCellData, xN); - switch( p->op ){ - case RTREE_LE: if( xN <= p->u.rValue ) return; break; - case RTREE_LT: if( xN < p->u.rValue ) return; break; - case RTREE_GE: if( xN >= p->u.rValue ) return; break; - case RTREE_GT: if( xN > p->u.rValue ) return; break; - default: if( xN == p->u.rValue ) return; break; - } - *peWithin = NOT_WITHIN; -} - -/* -** One of the cells in node pNode is guaranteed to have a 64-bit -** integer value equal to iRowid. Return the index of this cell. -*/ -static int nodeRowidIndex( - Rtree *pRtree, - RtreeNode *pNode, - i64 iRowid, - int *piIndex -){ - int ii; - int nCell = NCELL(pNode); - assert( nCell<200 ); - for(ii=0; iipParent; - if( pParent ){ - return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); - } - *piIndex = -1; - return SQLITE_OK; -} - -/* -** Compare two search points. Return negative, zero, or positive if the first -** is less than, equal to, or greater than the second. -** -** The rScore is the primary key. Smaller rScore values come first. -** If the rScore is a tie, then use iLevel as the tie breaker with smaller -** iLevel values coming first. In this way, if rScore is the same for all -** SearchPoints, then iLevel becomes the deciding factor and the result -** is a depth-first search, which is the desired default behavior. -*/ -static int rtreeSearchPointCompare( - const RtreeSearchPoint *pA, - const RtreeSearchPoint *pB -){ - if( pA->rScorerScore ) return -1; - if( pA->rScore>pB->rScore ) return +1; - if( pA->iLeveliLevel ) return -1; - if( pA->iLevel>pB->iLevel ) return +1; - return 0; -} - -/* -** Interchange to search points in a cursor. -*/ -static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ - RtreeSearchPoint t = p->aPoint[i]; - assert( iaPoint[i] = p->aPoint[j]; - p->aPoint[j] = t; - i++; j++; - if( i=RTREE_CACHE_SZ ){ - nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); - p->aNode[i] = 0; - }else{ - RtreeNode *pTemp = p->aNode[i]; - p->aNode[i] = p->aNode[j]; - p->aNode[j] = pTemp; - } - } -} - -/* -** Return the search point with the lowest current score. -*/ -static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ - return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; -} - -/* -** Get the RtreeNode for the search point with the lowest score. -*/ -static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ - sqlite3_int64 id; - int ii = 1 - pCur->bPoint; - assert( ii==0 || ii==1 ); - assert( pCur->bPoint || pCur->nPoint ); - if( pCur->aNode[ii]==0 ){ - assert( pRC!=0 ); - id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; - *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); - } - return pCur->aNode[ii]; -} - -/* -** Push a new element onto the priority queue -*/ -static RtreeSearchPoint *rtreeEnqueue( - RtreeCursor *pCur, /* The cursor */ - RtreeDValue rScore, /* Score for the new search point */ - u8 iLevel /* Level for the new search point */ -){ - int i, j; - RtreeSearchPoint *pNew; - if( pCur->nPoint>=pCur->nPointAlloc ){ - int nNew = pCur->nPointAlloc*2 + 8; - pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); - if( pNew==0 ) return 0; - pCur->aPoint = pNew; - pCur->nPointAlloc = nNew; - } - i = pCur->nPoint++; - pNew = pCur->aPoint + i; - pNew->rScore = rScore; - pNew->iLevel = iLevel; - assert( iLevel<=RTREE_MAX_DEPTH ); - while( i>0 ){ - RtreeSearchPoint *pParent; - j = (i-1)/2; - pParent = pCur->aPoint + j; - if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; - rtreeSearchPointSwap(pCur, j, i); - i = j; - pNew = pParent; - } - return pNew; -} - -/* -** Allocate a new RtreeSearchPoint and return a pointer to it. Return -** NULL if malloc fails. -*/ -static RtreeSearchPoint *rtreeSearchPointNew( - RtreeCursor *pCur, /* The cursor */ - RtreeDValue rScore, /* Score for the new search point */ - u8 iLevel /* Level for the new search point */ -){ - RtreeSearchPoint *pNew, *pFirst; - pFirst = rtreeSearchPointFirst(pCur); - pCur->anQueue[iLevel]++; - if( pFirst==0 - || pFirst->rScore>rScore - || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) - ){ - if( pCur->bPoint ){ - int ii; - pNew = rtreeEnqueue(pCur, rScore, iLevel); - if( pNew==0 ) return 0; - ii = (int)(pNew - pCur->aPoint) + 1; - if( iiaNode[ii]==0 ); - pCur->aNode[ii] = pCur->aNode[0]; - }else{ - nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); - } - pCur->aNode[0] = 0; - *pNew = pCur->sPoint; - } - pCur->sPoint.rScore = rScore; - pCur->sPoint.iLevel = iLevel; - pCur->bPoint = 1; - return &pCur->sPoint; - }else{ - return rtreeEnqueue(pCur, rScore, iLevel); - } -} - -#if 0 -/* Tracing routines for the RtreeSearchPoint queue */ -static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ - if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } - printf(" %d.%05lld.%02d %g %d", - p->iLevel, p->id, p->iCell, p->rScore, p->eWithin - ); - idx++; - if( idxaNode[idx]); - }else{ - printf("\n"); - } -} -static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ - int ii; - printf("=== %9s ", zPrefix); - if( pCur->bPoint ){ - tracePoint(&pCur->sPoint, -1, pCur); - } - for(ii=0; iinPoint; ii++){ - if( ii>0 || pCur->bPoint ) printf(" "); - tracePoint(&pCur->aPoint[ii], ii, pCur); - } -} -# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) -#else -# define RTREE_QUEUE_TRACE(A,B) /* no-op */ -#endif - -/* Remove the search point with the lowest current score. -*/ -static void rtreeSearchPointPop(RtreeCursor *p){ - int i, j, k, n; - i = 1 - p->bPoint; - assert( i==0 || i==1 ); - if( p->aNode[i] ){ - nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); - p->aNode[i] = 0; - } - if( p->bPoint ){ - p->anQueue[p->sPoint.iLevel]--; - p->bPoint = 0; - }else if( p->nPoint ){ - p->anQueue[p->aPoint[0].iLevel]--; - n = --p->nPoint; - p->aPoint[0] = p->aPoint[n]; - if( naNode[1] = p->aNode[n+1]; - p->aNode[n+1] = 0; - } - i = 0; - while( (j = i*2+1)aPoint[k], &p->aPoint[j])<0 ){ - if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ - rtreeSearchPointSwap(p, i, k); - i = k; - }else{ - break; - } - }else{ - if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ - rtreeSearchPointSwap(p, i, j); - i = j; - }else{ - break; - } - } - } - } -} - - -/* -** Continue the search on cursor pCur until the front of the queue -** contains an entry suitable for returning as a result-set row, -** or until the RtreeSearchPoint queue is empty, indicating that the -** query has completed. -*/ -static int rtreeStepToLeaf(RtreeCursor *pCur){ - RtreeSearchPoint *p; - Rtree *pRtree = RTREE_OF_CURSOR(pCur); - RtreeNode *pNode; - int eWithin; - int rc = SQLITE_OK; - int nCell; - int nConstraint = pCur->nConstraint; - int ii; - int eInt; - RtreeSearchPoint x; - - eInt = pRtree->eCoordType==RTREE_COORD_INT32; - while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ - pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); - if( rc ) return rc; - nCell = NCELL(pNode); - assert( nCell<200 ); - while( p->iCellzData + (4+pRtree->nBytesPerCell*p->iCell); - eWithin = FULLY_WITHIN; - for(ii=0; iiaConstraint + ii; - if( pConstraint->op>=RTREE_MATCH ){ - rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, - &rScore, &eWithin); - if( rc ) return rc; - }else if( p->iLevel==1 ){ - rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); - }else{ - rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); - } - if( eWithin==NOT_WITHIN ) break; - } - p->iCell++; - if( eWithin==NOT_WITHIN ) continue; - x.iLevel = p->iLevel - 1; - if( x.iLevel ){ - x.id = readInt64(pCellData); - x.iCell = 0; - }else{ - x.id = p->id; - x.iCell = p->iCell - 1; - } - if( p->iCell>=nCell ){ - RTREE_QUEUE_TRACE(pCur, "POP-S:"); - rtreeSearchPointPop(pCur); - } - if( rScoreeWithin = eWithin; - p->id = x.id; - p->iCell = x.iCell; - RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); - break; - } - if( p->iCell>=nCell ){ - RTREE_QUEUE_TRACE(pCur, "POP-Se:"); - rtreeSearchPointPop(pCur); - } - } - pCur->atEOF = p==0; - return SQLITE_OK; -} - -/* -** Rtree virtual table module xNext method. -*/ -static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ - RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; - int rc = SQLITE_OK; - - /* Move to the next entry that matches the configured constraints. */ - RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); - rtreeSearchPointPop(pCsr); - rc = rtreeStepToLeaf(pCsr); - return rc; -} - -/* -** Rtree virtual table module xRowid method. -*/ -static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ - RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; - RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); - int rc = SQLITE_OK; - RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); - if( rc==SQLITE_OK && p ){ - *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); - } - return rc; -} - -/* -** Rtree virtual table module xColumn method. -*/ -static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ - Rtree *pRtree = (Rtree *)cur->pVtab; - RtreeCursor *pCsr = (RtreeCursor *)cur; - RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); - RtreeCoord c; - int rc = SQLITE_OK; - RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); - - if( rc ) return rc; - if( p==0 ) return SQLITE_OK; - if( i==0 ){ - sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); - }else{ - if( rc ) return rc; - nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); -#ifndef SQLITE_RTREE_INT_ONLY - if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - sqlite3_result_double(ctx, c.f); - }else -#endif - { - assert( pRtree->eCoordType==RTREE_COORD_INT32 ); - sqlite3_result_int(ctx, c.i); - } - } - return SQLITE_OK; -} - -/* -** Use nodeAcquire() to obtain the leaf node containing the record with -** rowid iRowid. If successful, set *ppLeaf to point to the node and -** return SQLITE_OK. If there is no such record in the table, set -** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf -** to zero and return an SQLite error code. -*/ -static int findLeafNode( - Rtree *pRtree, /* RTree to search */ - i64 iRowid, /* The rowid searching for */ - RtreeNode **ppLeaf, /* Write the node here */ - sqlite3_int64 *piNode /* Write the node-id here */ -){ - int rc; - *ppLeaf = 0; - sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); - if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ - i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); - if( piNode ) *piNode = iNode; - rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); - sqlite3_reset(pRtree->pReadRowid); - }else{ - rc = sqlite3_reset(pRtree->pReadRowid); - } - return rc; -} - -/* -** This function is called to configure the RtreeConstraint object passed -** as the second argument for a MATCH constraint. The value passed as the -** first argument to this function is the right-hand operand to the MATCH -** operator. -*/ -static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ - RtreeMatchArg *pBlob; /* BLOB returned by geometry function */ - sqlite3_rtree_query_info *pInfo; /* Callback information */ - int nBlob; /* Size of the geometry function blob */ - int nExpected; /* Expected size of the BLOB */ - - /* Check that value is actually a blob. */ - if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; - - /* Check that the blob is roughly the right size. */ - nBlob = sqlite3_value_bytes(pValue); - if( nBlob<(int)sizeof(RtreeMatchArg) ){ - return SQLITE_ERROR; - } - - pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); - if( !pInfo ) return SQLITE_NOMEM; - memset(pInfo, 0, sizeof(*pInfo)); - pBlob = (RtreeMatchArg*)&pInfo[1]; - - memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); - nExpected = (int)(sizeof(RtreeMatchArg) + - pBlob->nParam*sizeof(sqlite3_value*) + - (pBlob->nParam-1)*sizeof(RtreeDValue)); - if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ - sqlite3_free(pInfo); - return SQLITE_ERROR; - } - pInfo->pContext = pBlob->cb.pContext; - pInfo->nParam = pBlob->nParam; - pInfo->aParam = pBlob->aParam; - pInfo->apSqlParam = pBlob->apSqlParam; - - if( pBlob->cb.xGeom ){ - pCons->u.xGeom = pBlob->cb.xGeom; - }else{ - pCons->op = RTREE_QUERY; - pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; - } - pCons->pInfo = pInfo; - return SQLITE_OK; -} - -/* -** Rtree virtual table module xFilter method. -*/ -static int rtreeFilter( - sqlite3_vtab_cursor *pVtabCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; - RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; - RtreeNode *pRoot = 0; - int ii; - int rc = SQLITE_OK; - int iCell = 0; - - rtreeReference(pRtree); - - /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (sqlite3_vtab*)pRtree; - - pCsr->iStrategy = idxNum; - if( idxNum==1 ){ - /* Special case - lookup by rowid. */ - RtreeNode *pLeaf; /* Leaf on which the required cell resides */ - RtreeSearchPoint *p; /* Search point for the leaf */ - i64 iRowid = sqlite3_value_int64(argv[0]); - i64 iNode = 0; - rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); - if( rc==SQLITE_OK && pLeaf!=0 ){ - p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); - assert( p!=0 ); /* Always returns pCsr->sPoint */ - pCsr->aNode[0] = pLeaf; - p->id = iNode; - p->eWithin = PARTLY_WITHIN; - rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); - p->iCell = iCell; - RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); - }else{ - pCsr->atEOF = 1; - } - }else{ - /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array - ** with the configured constraints. - */ - rc = nodeAcquire(pRtree, 1, 0, &pRoot); - if( rc==SQLITE_OK && argc>0 ){ - pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); - pCsr->nConstraint = argc; - if( !pCsr->aConstraint ){ - rc = SQLITE_NOMEM; - }else{ - memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); - memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); - assert( (idxStr==0 && argc==0) - || (idxStr && (int)strlen(idxStr)==argc*2) ); - for(ii=0; iiaConstraint[ii]; - p->op = idxStr[ii*2]; - p->iCoord = idxStr[ii*2+1]-'0'; - if( p->op>=RTREE_MATCH ){ - /* A MATCH operator. The right-hand-side must be a blob that - ** can be cast into an RtreeMatchArg object. One created using - ** an sqlite3_rtree_geometry_callback() SQL user function. - */ - rc = deserializeGeometry(argv[ii], p); - if( rc!=SQLITE_OK ){ - break; - } - p->pInfo->nCoord = pRtree->nDim*2; - p->pInfo->anQueue = pCsr->anQueue; - p->pInfo->mxLevel = pRtree->iDepth + 1; - }else{ -#ifdef SQLITE_RTREE_INT_ONLY - p->u.rValue = sqlite3_value_int64(argv[ii]); -#else - p->u.rValue = sqlite3_value_double(argv[ii]); -#endif - } - } - } - } - if( rc==SQLITE_OK ){ - RtreeSearchPoint *pNew; - pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1); - if( pNew==0 ) return SQLITE_NOMEM; - pNew->id = 1; - pNew->iCell = 0; - pNew->eWithin = PARTLY_WITHIN; - assert( pCsr->bPoint==1 ); - pCsr->aNode[0] = pRoot; - pRoot = 0; - RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); - rc = rtreeStepToLeaf(pCsr); - } - } - - nodeRelease(pRtree, pRoot); - rtreeRelease(pRtree); - return rc; -} - -/* -** Set the pIdxInfo->estimatedRows variable to nRow. Unless this -** extension is currently being used by a version of SQLite too old to -** support estimatedRows. In that case this function is a no-op. -*/ -static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ -#if SQLITE_VERSION_NUMBER>=3008002 - if( sqlite3_libversion_number()>=3008002 ){ - pIdxInfo->estimatedRows = nRow; - } -#endif -} - -/* -** Rtree virtual table module xBestIndex method. There are three -** table scan strategies to choose from (in order from most to -** least desirable): -** -** idxNum idxStr Strategy -** ------------------------------------------------ -** 1 Unused Direct lookup by rowid. -** 2 See below R-tree query or full-table scan. -** ------------------------------------------------ -** -** If strategy 1 is used, then idxStr is not meaningful. If strategy -** 2 is used, idxStr is formatted to contain 2 bytes for each -** constraint used. The first two bytes of idxStr correspond to -** the constraint in sqlite3_index_info.aConstraintUsage[] with -** (argvIndex==1) etc. -** -** The first of each pair of bytes in idxStr identifies the constraint -** operator as follows: -** -** Operator Byte Value -** ---------------------- -** = 0x41 ('A') -** <= 0x42 ('B') -** < 0x43 ('C') -** >= 0x44 ('D') -** > 0x45 ('E') -** MATCH 0x46 ('F') -** ---------------------- -** -** The second of each pair of bytes identifies the coordinate column -** to which the constraint applies. The leftmost coordinate column -** is 'a', the second from the left 'b' etc. -*/ -static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ - Rtree *pRtree = (Rtree*)tab; - int rc = SQLITE_OK; - int ii; - int bMatch = 0; /* True if there exists a MATCH constraint */ - i64 nRow; /* Estimated rows returned by this scan */ - - int iIdx = 0; - char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; - memset(zIdxStr, 0, sizeof(zIdxStr)); - - /* Check if there exists a MATCH constraint - even an unusable one. If there - ** is, do not consider the lookup-by-rowid plan as using such a plan would - ** require the VDBE to evaluate the MATCH constraint, which is not currently - ** possible. */ - for(ii=0; iinConstraint; ii++){ - if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){ - bMatch = 1; - } - } - - assert( pIdxInfo->idxStr==0 ); - for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ - struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; - - if( bMatch==0 && p->usable - && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ - ){ - /* We have an equality constraint on the rowid. Use strategy 1. */ - int jj; - for(jj=0; jjaConstraintUsage[jj].argvIndex = 0; - pIdxInfo->aConstraintUsage[jj].omit = 0; - } - pIdxInfo->idxNum = 1; - pIdxInfo->aConstraintUsage[ii].argvIndex = 1; - pIdxInfo->aConstraintUsage[jj].omit = 1; - - /* This strategy involves a two rowid lookups on an B-Tree structures - ** and then a linear search of an R-Tree node. This should be - ** considered almost as quick as a direct rowid lookup (for which - ** sqlite uses an internal cost of 0.0). It is expected to return - ** a single row. - */ - pIdxInfo->estimatedCost = 30.0; - setEstimatedRows(pIdxInfo, 1); - return SQLITE_OK; - } - - if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ - u8 op; - switch( p->op ){ - case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; - case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; - case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; - case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; - case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; - default: - assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); - op = RTREE_MATCH; - break; - } - zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = p->iColumn - 1 + '0'; - pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); - pIdxInfo->aConstraintUsage[ii].omit = 1; - } - } - - pIdxInfo->idxNum = 2; - pIdxInfo->needToFreeIdxStr = 1; - if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ - return SQLITE_NOMEM; - } - - nRow = pRtree->nRowEst >> (iIdx/2); - pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; - setEstimatedRows(pIdxInfo, nRow); - - return rc; -} - -/* -** Return the N-dimensional volumn of the cell stored in *p. -*/ -static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ - RtreeDValue area = (RtreeDValue)1; - int ii; - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]))); - } - return area; -} - -/* -** Return the margin length of cell p. The margin length is the sum -** of the objects size in each dimension. -*/ -static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ - RtreeDValue margin = (RtreeDValue)0; - int ii; - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); - } - return margin; -} - -/* -** Store the union of cells p1 and p2 in p1. -*/ -static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ - int ii; - if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); - p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); - } - }else{ - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); - p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); - } - } -} - -/* -** Return true if the area covered by p2 is a subset of the area covered -** by p1. False otherwise. -*/ -static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ - int ii; - int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); - for(ii=0; ii<(pRtree->nDim*2); ii+=2){ - RtreeCoord *a1 = &p1->aCoord[ii]; - RtreeCoord *a2 = &p2->aCoord[ii]; - if( (!isInt && (a2[0].fa1[1].f)) - || ( isInt && (a2[0].ia1[1].i)) - ){ - return 0; - } - } - return 1; -} - -/* -** Return the amount cell p would grow by if it were unioned with pCell. -*/ -static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ - RtreeDValue area; - RtreeCell cell; - memcpy(&cell, p, sizeof(RtreeCell)); - area = cellArea(pRtree, &cell); - cellUnion(pRtree, &cell, pCell); - return (cellArea(pRtree, &cell)-area); -} - -static RtreeDValue cellOverlap( - Rtree *pRtree, - RtreeCell *p, - RtreeCell *aCell, - int nCell -){ - int ii; - RtreeDValue overlap = RTREE_ZERO; - for(ii=0; iinDim*2); jj+=2){ - RtreeDValue x1, x2; - x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); - x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); - if( x2iDepth-iHeight); ii++){ - int iCell; - sqlite3_int64 iBest = 0; - - RtreeDValue fMinGrowth = RTREE_ZERO; - RtreeDValue fMinArea = RTREE_ZERO; - - int nCell = NCELL(pNode); - RtreeCell cell; - RtreeNode *pChild; - - RtreeCell *aCell = 0; - - /* Select the child node which will be enlarged the least if pCell - ** is inserted into it. Resolve ties by choosing the entry with - ** the smallest area. - */ - for(iCell=0; iCellpParent ){ - RtreeNode *pParent = p->pParent; - RtreeCell cell; - int iCell; - - if( nodeParentIndex(pRtree, p, &iCell) ){ - return SQLITE_CORRUPT_VTAB; - } - - nodeGetCell(pRtree, pParent, iCell, &cell); - if( !cellContains(pRtree, &cell, pCell) ){ - cellUnion(pRtree, &cell, pCell); - nodeOverwriteCell(pRtree, pParent, &cell, iCell); - } - - p = pParent; - } - return SQLITE_OK; -} - -/* -** Write mapping (iRowid->iNode) to the _rowid table. -*/ -static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ - sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); - sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); - sqlite3_step(pRtree->pWriteRowid); - return sqlite3_reset(pRtree->pWriteRowid); -} - -/* -** Write mapping (iNode->iPar) to the _parent table. -*/ -static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ - sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); - sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); - sqlite3_step(pRtree->pWriteParent); - return sqlite3_reset(pRtree->pWriteParent); -} - -static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); - - -/* -** Arguments aIdx, aDistance and aSpare all point to arrays of size -** nIdx. The aIdx array contains the set of integers from 0 to -** (nIdx-1) in no particular order. This function sorts the values -** in aIdx according to the indexed values in aDistance. For -** example, assuming the inputs: -** -** aIdx = { 0, 1, 2, 3 } -** aDistance = { 5.0, 2.0, 7.0, 6.0 } -** -** this function sets the aIdx array to contain: -** -** aIdx = { 0, 1, 2, 3 } -** -** The aSpare array is used as temporary working space by the -** sorting algorithm. -*/ -static void SortByDistance( - int *aIdx, - int nIdx, - RtreeDValue *aDistance, - int *aSpare -){ - if( nIdx>1 ){ - int iLeft = 0; - int iRight = 0; - - int nLeft = nIdx/2; - int nRight = nIdx-nLeft; - int *aLeft = aIdx; - int *aRight = &aIdx[nLeft]; - - SortByDistance(aLeft, nLeft, aDistance, aSpare); - SortByDistance(aRight, nRight, aDistance, aSpare); - - memcpy(aSpare, aLeft, sizeof(int)*nLeft); - aLeft = aSpare; - - while( iLeft1 ){ - - int iLeft = 0; - int iRight = 0; - - int nLeft = nIdx/2; - int nRight = nIdx-nLeft; - int *aLeft = aIdx; - int *aRight = &aIdx[nLeft]; - - SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); - SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); - - memcpy(aSpare, aLeft, sizeof(int)*nLeft); - aLeft = aSpare; - while( iLeftnDim+1)*(sizeof(int*)+nCell*sizeof(int)); - - aaSorted = (int **)sqlite3_malloc(nByte); - if( !aaSorted ){ - return SQLITE_NOMEM; - } - - aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; - memset(aaSorted, 0, nByte); - for(ii=0; iinDim; ii++){ - int jj; - aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; - for(jj=0; jjnDim; ii++){ - RtreeDValue margin = RTREE_ZERO; - RtreeDValue fBestOverlap = RTREE_ZERO; - RtreeDValue fBestArea = RTREE_ZERO; - int iBestLeft = 0; - int nLeft; - - for( - nLeft=RTREE_MINCELLS(pRtree); - nLeft<=(nCell-RTREE_MINCELLS(pRtree)); - nLeft++ - ){ - RtreeCell left; - RtreeCell right; - int kk; - RtreeDValue overlap; - RtreeDValue area; - - memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); - memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); - for(kk=1; kk<(nCell-1); kk++){ - if( kk0 ){ - RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); - if( pChild ){ - nodeRelease(pRtree, pChild->pParent); - nodeReference(pNode); - pChild->pParent = pNode; - } - } - return xSetMapping(pRtree, iRowid, pNode->iNode); -} - -static int SplitNode( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell, - int iHeight -){ - int i; - int newCellIsRight = 0; - - int rc = SQLITE_OK; - int nCell = NCELL(pNode); - RtreeCell *aCell; - int *aiUsed; - - RtreeNode *pLeft = 0; - RtreeNode *pRight = 0; - - RtreeCell leftbbox; - RtreeCell rightbbox; - - /* Allocate an array and populate it with a copy of pCell and - ** all cells from node pLeft. Then zero the original node. - */ - aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); - if( !aCell ){ - rc = SQLITE_NOMEM; - goto splitnode_out; - } - aiUsed = (int *)&aCell[nCell+1]; - memset(aiUsed, 0, sizeof(int)*(nCell+1)); - for(i=0; iiNode==1 ){ - pRight = nodeNew(pRtree, pNode); - pLeft = nodeNew(pRtree, pNode); - pRtree->iDepth++; - pNode->isDirty = 1; - writeInt16(pNode->zData, pRtree->iDepth); - }else{ - pLeft = pNode; - pRight = nodeNew(pRtree, pLeft->pParent); - nodeReference(pLeft); - } - - if( !pLeft || !pRight ){ - rc = SQLITE_NOMEM; - goto splitnode_out; - } - - memset(pLeft->zData, 0, pRtree->iNodeSize); - memset(pRight->zData, 0, pRtree->iNodeSize); - - rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, - &leftbbox, &rightbbox); - if( rc!=SQLITE_OK ){ - goto splitnode_out; - } - - /* Ensure both child nodes have node numbers assigned to them by calling - ** nodeWrite(). Node pRight always needs a node number, as it was created - ** by nodeNew() above. But node pLeft sometimes already has a node number. - ** In this case avoid the all to nodeWrite(). - */ - if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) - || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) - ){ - goto splitnode_out; - } - - rightbbox.iRowid = pRight->iNode; - leftbbox.iRowid = pLeft->iNode; - - if( pNode->iNode==1 ){ - rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); - if( rc!=SQLITE_OK ){ - goto splitnode_out; - } - }else{ - RtreeNode *pParent = pLeft->pParent; - int iCell; - rc = nodeParentIndex(pRtree, pLeft, &iCell); - if( rc==SQLITE_OK ){ - nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); - rc = AdjustTree(pRtree, pParent, &leftbbox); - } - if( rc!=SQLITE_OK ){ - goto splitnode_out; - } - } - if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ - goto splitnode_out; - } - - for(i=0; iiRowid ){ - newCellIsRight = 1; - } - if( rc!=SQLITE_OK ){ - goto splitnode_out; - } - } - if( pNode->iNode==1 ){ - for(i=0; iiRowid, pLeft, iHeight); - } - - if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pRight); - pRight = 0; - } - if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pLeft); - pLeft = 0; - } - -splitnode_out: - nodeRelease(pRtree, pRight); - nodeRelease(pRtree, pLeft); - sqlite3_free(aCell); - return rc; -} - -/* -** If node pLeaf is not the root of the r-tree and its pParent pointer is -** still NULL, load all ancestor nodes of pLeaf into memory and populate -** the pLeaf->pParent chain all the way up to the root node. -** -** This operation is required when a row is deleted (or updated - an update -** is implemented as a delete followed by an insert). SQLite provides the -** rowid of the row to delete, which can be used to find the leaf on which -** the entry resides (argument pLeaf). Once the leaf is located, this -** function is called to determine its ancestry. -*/ -static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ - int rc = SQLITE_OK; - RtreeNode *pChild = pLeaf; - while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ - int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ - sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); - rc = sqlite3_step(pRtree->pReadParent); - if( rc==SQLITE_ROW ){ - RtreeNode *pTest; /* Used to test for reference loops */ - i64 iNode; /* Node number of parent node */ - - /* Before setting pChild->pParent, test that we are not creating a - ** loop of references (as we would if, say, pChild==pParent). We don't - ** want to do this as it leads to a memory leak when trying to delete - ** the referenced counted node structures. - */ - iNode = sqlite3_column_int64(pRtree->pReadParent, 0); - for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); - if( !pTest ){ - rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); - } - } - rc = sqlite3_reset(pRtree->pReadParent); - if( rc==SQLITE_OK ) rc = rc2; - if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB; - pChild = pChild->pParent; - } - return rc; -} - -static int deleteCell(Rtree *, RtreeNode *, int, int); - -static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ - int rc; - int rc2; - RtreeNode *pParent = 0; - int iCell; - - assert( pNode->nRef==1 ); - - /* Remove the entry in the parent cell. */ - rc = nodeParentIndex(pRtree, pNode, &iCell); - if( rc==SQLITE_OK ){ - pParent = pNode->pParent; - pNode->pParent = 0; - rc = deleteCell(pRtree, pParent, iCell, iHeight+1); - } - rc2 = nodeRelease(pRtree, pParent); - if( rc==SQLITE_OK ){ - rc = rc2; - } - if( rc!=SQLITE_OK ){ - return rc; - } - - /* Remove the xxx_node entry. */ - sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); - sqlite3_step(pRtree->pDeleteNode); - if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ - return rc; - } - - /* Remove the xxx_parent entry. */ - sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); - sqlite3_step(pRtree->pDeleteParent); - if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ - return rc; - } - - /* Remove the node from the in-memory hash table and link it into - ** the Rtree.pDeleted list. Its contents will be re-inserted later on. - */ - nodeHashDelete(pRtree, pNode); - pNode->iNode = iHeight; - pNode->pNext = pRtree->pDeleted; - pNode->nRef++; - pRtree->pDeleted = pNode; - - return SQLITE_OK; -} - -static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ - RtreeNode *pParent = pNode->pParent; - int rc = SQLITE_OK; - if( pParent ){ - int ii; - int nCell = NCELL(pNode); - RtreeCell box; /* Bounding box for pNode */ - nodeGetCell(pRtree, pNode, 0, &box); - for(ii=1; iiiNode; - rc = nodeParentIndex(pRtree, pNode, &ii); - if( rc==SQLITE_OK ){ - nodeOverwriteCell(pRtree, pParent, &box, ii); - rc = fixBoundingBox(pRtree, pParent); - } - } - return rc; -} - -/* -** Delete the cell at index iCell of node pNode. After removing the -** cell, adjust the r-tree data structure if required. -*/ -static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ - RtreeNode *pParent; - int rc; - - if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ - return rc; - } - - /* Remove the cell from the node. This call just moves bytes around - ** the in-memory node image, so it cannot fail. - */ - nodeDeleteCell(pRtree, pNode, iCell); - - /* If the node is not the tree root and now has less than the minimum - ** number of cells, remove it from the tree. Otherwise, update the - ** cell in the parent node so that it tightly contains the updated - ** node. - */ - pParent = pNode->pParent; - assert( pParent || pNode->iNode==1 ); - if( pParent ){ - if( NCELL(pNode)nDim; iDim++){ - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); - } - } - for(iDim=0; iDimnDim; iDim++){ - aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); - } - - for(ii=0; iinDim; iDim++){ - RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - - DCOORD(aCell[ii].aCoord[iDim*2])); - aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); - } - } - - SortByDistance(aOrder, nCell, aDistance, aSpare); - nodeZero(pRtree, pNode); - - for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ - RtreeCell *p = &aCell[aOrder[ii]]; - nodeInsertCell(pRtree, pNode, p); - if( p->iRowid==pCell->iRowid ){ - if( iHeight==0 ){ - rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); - }else{ - rc = parentWrite(pRtree, p->iRowid, pNode->iNode); - } - } - } - if( rc==SQLITE_OK ){ - rc = fixBoundingBox(pRtree, pNode); - } - for(; rc==SQLITE_OK && iiiNode currently contains - ** the height of the sub-tree headed by the cell. - */ - RtreeNode *pInsert; - RtreeCell *p = &aCell[aOrder[ii]]; - rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); - if( rc==SQLITE_OK ){ - int rc2; - rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); - rc2 = nodeRelease(pRtree, pInsert); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - - sqlite3_free(aCell); - return rc; -} - -/* -** Insert cell pCell into node pNode. Node pNode is the head of a -** subtree iHeight high (leaf nodes have iHeight==0). -*/ -static int rtreeInsertCell( - Rtree *pRtree, - RtreeNode *pNode, - RtreeCell *pCell, - int iHeight -){ - int rc = SQLITE_OK; - if( iHeight>0 ){ - RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid); - if( pChild ){ - nodeRelease(pRtree, pChild->pParent); - nodeReference(pNode); - pChild->pParent = pNode; - } - } - if( nodeInsertCell(pRtree, pNode, pCell) ){ - if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ - rc = SplitNode(pRtree, pNode, pCell, iHeight); - }else{ - pRtree->iReinsertHeight = iHeight; - rc = Reinsert(pRtree, pNode, pCell, iHeight); - } - }else{ - rc = AdjustTree(pRtree, pNode, pCell); - if( rc==SQLITE_OK ){ - if( iHeight==0 ){ - rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); - }else{ - rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); - } - } - } - return rc; -} - -static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ - int ii; - int rc = SQLITE_OK; - int nCell = NCELL(pNode); - - for(ii=0; rc==SQLITE_OK && iiiNode currently contains - ** the height of the sub-tree headed by the cell. - */ - rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); - if( rc==SQLITE_OK ){ - int rc2; - rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); - rc2 = nodeRelease(pRtree, pInsert); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - return rc; -} - -/* -** Select a currently unused rowid for a new r-tree record. -*/ -static int newRowid(Rtree *pRtree, i64 *piRowid){ - int rc; - sqlite3_bind_null(pRtree->pWriteRowid, 1); - sqlite3_bind_null(pRtree->pWriteRowid, 2); - sqlite3_step(pRtree->pWriteRowid); - rc = sqlite3_reset(pRtree->pWriteRowid); - *piRowid = sqlite3_last_insert_rowid(pRtree->db); - return rc; -} - -/* -** Remove the entry with rowid=iDelete from the r-tree structure. -*/ -static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ - int rc; /* Return code */ - RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ - int iCell; /* Index of iDelete cell in pLeaf */ - RtreeNode *pRoot; /* Root node of rtree structure */ - - - /* Obtain a reference to the root node to initialize Rtree.iDepth */ - rc = nodeAcquire(pRtree, 1, 0, &pRoot); - - /* Obtain a reference to the leaf node that contains the entry - ** about to be deleted. - */ - if( rc==SQLITE_OK ){ - rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); - } - - /* Delete the cell in question from the leaf node. */ - if( rc==SQLITE_OK ){ - int rc2; - rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); - if( rc==SQLITE_OK ){ - rc = deleteCell(pRtree, pLeaf, iCell, 0); - } - rc2 = nodeRelease(pRtree, pLeaf); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - - /* Delete the corresponding entry in the _rowid table. */ - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); - sqlite3_step(pRtree->pDeleteRowid); - rc = sqlite3_reset(pRtree->pDeleteRowid); - } - - /* Check if the root node now has exactly one child. If so, remove - ** it, schedule the contents of the child for reinsertion and - ** reduce the tree height by one. - ** - ** This is equivalent to copying the contents of the child into - ** the root node (the operation that Gutman's paper says to perform - ** in this scenario). - */ - if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ - int rc2; - RtreeNode *pChild; - i64 iChild = nodeGetRowid(pRtree, pRoot, 0); - rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); - if( rc==SQLITE_OK ){ - rc = removeNode(pRtree, pChild, pRtree->iDepth-1); - } - rc2 = nodeRelease(pRtree, pChild); - if( rc==SQLITE_OK ) rc = rc2; - if( rc==SQLITE_OK ){ - pRtree->iDepth--; - writeInt16(pRoot->zData, pRtree->iDepth); - pRoot->isDirty = 1; - } - } - - /* Re-insert the contents of any underfull nodes removed from the tree. */ - for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ - if( rc==SQLITE_OK ){ - rc = reinsertNodeContent(pRtree, pLeaf); - } - pRtree->pDeleted = pLeaf->pNext; - sqlite3_free(pLeaf); - } - - /* Release the reference to the root node. */ - if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pRoot); - }else{ - nodeRelease(pRtree, pRoot); - } - - return rc; -} - -/* -** Rounding constants for float->double conversion. -*/ -#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ -#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ - -#if !defined(SQLITE_RTREE_INT_ONLY) -/* -** Convert an sqlite3_value into an RtreeValue (presumably a float) -** while taking care to round toward negative or positive, respectively. -*/ -static RtreeValue rtreeValueDown(sqlite3_value *v){ - double d = sqlite3_value_double(v); - float f = (float)d; - if( f>d ){ - f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); - } - return f; -} -static RtreeValue rtreeValueUp(sqlite3_value *v){ - double d = sqlite3_value_double(v); - float f = (float)d; - if( fbase.zErrMsg) to an appropriate value and returns -** SQLITE_CONSTRAINT. -** -** Parameter iCol is the index of the leftmost column involved in the -** constraint failure. If it is 0, then the constraint that failed is -** the unique constraint on the id column. Otherwise, it is the rtree -** (c1<=c2) constraint on columns iCol and iCol+1 that has failed. -** -** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT. -*/ -static int rtreeConstraintError(Rtree *pRtree, int iCol){ - sqlite3_stmt *pStmt = 0; - char *zSql; - int rc; - - assert( iCol==0 || iCol%2 ); - zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName); - if( zSql ){ - rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); - }else{ - rc = SQLITE_NOMEM; - } - sqlite3_free(zSql); - - if( rc==SQLITE_OK ){ - if( iCol==0 ){ - const char *zCol = sqlite3_column_name(pStmt, 0); - pRtree->base.zErrMsg = sqlite3_mprintf( - "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol - ); - }else{ - const char *zCol1 = sqlite3_column_name(pStmt, iCol); - const char *zCol2 = sqlite3_column_name(pStmt, iCol+1); - pRtree->base.zErrMsg = sqlite3_mprintf( - "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2 - ); - } - } - - sqlite3_finalize(pStmt); - return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc); -} - - - -/* -** The xUpdate method for rtree module virtual tables. -*/ -static int rtreeUpdate( - sqlite3_vtab *pVtab, - int nData, - sqlite3_value **azData, - sqlite_int64 *pRowid -){ - Rtree *pRtree = (Rtree *)pVtab; - int rc = SQLITE_OK; - RtreeCell cell; /* New cell to insert if nData>1 */ - int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ - - rtreeReference(pRtree); - assert(nData>=1); - - cell.iRowid = 0; /* Used only to suppress a compiler warning */ - - /* Constraint handling. A write operation on an r-tree table may return - ** SQLITE_CONSTRAINT for two reasons: - ** - ** 1. A duplicate rowid value, or - ** 2. The supplied data violates the "x2>=x1" constraint. - ** - ** In the first case, if the conflict-handling mode is REPLACE, then - ** the conflicting row can be removed before proceeding. In the second - ** case, SQLITE_CONSTRAINT must be returned regardless of the - ** conflict-handling mode specified by the user. - */ - if( nData>1 ){ - int ii; - - /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. - ** - ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared - ** with "column" that are interpreted as table constraints. - ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5)); - ** This problem was discovered after years of use, so we silently ignore - ** these kinds of misdeclared tables to avoid breaking any legacy. - */ - assert( nData<=(pRtree->nDim*2 + 3) ); - -#ifndef SQLITE_RTREE_INT_ONLY - if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - for(ii=0; iicell.aCoord[ii+1].f ){ - rc = rtreeConstraintError(pRtree, ii+1); - goto constraint; - } - } - }else -#endif - { - for(ii=0; iicell.aCoord[ii+1].i ){ - rc = rtreeConstraintError(pRtree, ii+1); - goto constraint; - } - } - } - - /* If a rowid value was supplied, check if it is already present in - ** the table. If so, the constraint has failed. */ - if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){ - cell.iRowid = sqlite3_value_int64(azData[2]); - if( sqlite3_value_type(azData[0])==SQLITE_NULL - || sqlite3_value_int64(azData[0])!=cell.iRowid - ){ - int steprc; - sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); - steprc = sqlite3_step(pRtree->pReadRowid); - rc = sqlite3_reset(pRtree->pReadRowid); - if( SQLITE_ROW==steprc ){ - if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ - rc = rtreeDeleteRowid(pRtree, cell.iRowid); - }else{ - rc = rtreeConstraintError(pRtree, 0); - goto constraint; - } - } - } - bHaveRowid = 1; - } - } - - /* If azData[0] is not an SQL NULL value, it is the rowid of a - ** record to delete from the r-tree table. The following block does - ** just that. - */ - if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){ - rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0])); - } - - /* If the azData[] array contains more than one element, elements - ** (azData[2]..azData[argc-1]) contain a new record to insert into - ** the r-tree structure. - */ - if( rc==SQLITE_OK && nData>1 ){ - /* Insert the new record into the r-tree */ - RtreeNode *pLeaf = 0; - - /* Figure out the rowid of the new row. */ - if( bHaveRowid==0 ){ - rc = newRowid(pRtree, &cell.iRowid); - } - *pRowid = cell.iRowid; - - if( rc==SQLITE_OK ){ - rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); - } - if( rc==SQLITE_OK ){ - int rc2; - pRtree->iReinsertHeight = -1; - rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); - rc2 = nodeRelease(pRtree, pLeaf); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - -constraint: - rtreeRelease(pRtree); - return rc; -} - -/* -** The xRename method for rtree module virtual tables. -*/ -static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ - Rtree *pRtree = (Rtree *)pVtab; - int rc = SQLITE_NOMEM; - char *zSql = sqlite3_mprintf( - "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" - "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" - "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" - , pRtree->zDb, pRtree->zName, zNewName - , pRtree->zDb, pRtree->zName, zNewName - , pRtree->zDb, pRtree->zName, zNewName - ); - if( zSql ){ - rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); - sqlite3_free(zSql); - } - return rc; -} - -/* -** This function populates the pRtree->nRowEst variable with an estimate -** of the number of rows in the virtual table. If possible, this is based -** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. -*/ -static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ - const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; - char *zSql; - sqlite3_stmt *p; - int rc; - i64 nRow = 0; - - rc = sqlite3_table_column_metadata( - db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 - ); - if( rc!=SQLITE_OK ){ - pRtree->nRowEst = RTREE_DEFAULT_ROWEST; - return rc==SQLITE_ERROR ? SQLITE_OK : rc; - } - zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); - if( rc==SQLITE_OK ){ - if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); - rc = sqlite3_finalize(p); - }else if( rc!=SQLITE_NOMEM ){ - rc = SQLITE_OK; - } - - if( rc==SQLITE_OK ){ - if( nRow==0 ){ - pRtree->nRowEst = RTREE_DEFAULT_ROWEST; - }else{ - pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); - } - } - sqlite3_free(zSql); - } - - return rc; -} - -static sqlite3_module rtreeModule = { - 0, /* iVersion */ - rtreeCreate, /* xCreate - create a table */ - rtreeConnect, /* xConnect - connect to an existing table */ - rtreeBestIndex, /* xBestIndex - Determine search strategy */ - rtreeDisconnect, /* xDisconnect - Disconnect from a table */ - rtreeDestroy, /* xDestroy - Drop a table */ - rtreeOpen, /* xOpen - open a cursor */ - rtreeClose, /* xClose - close a cursor */ - rtreeFilter, /* xFilter - configure scan constraints */ - rtreeNext, /* xNext - advance a cursor */ - rtreeEof, /* xEof */ - rtreeColumn, /* xColumn - read data */ - rtreeRowid, /* xRowid - read data */ - rtreeUpdate, /* xUpdate - write data */ - 0, /* xBegin - begin transaction */ - 0, /* xSync - sync transaction */ - 0, /* xCommit - commit transaction */ - 0, /* xRollback - rollback transaction */ - 0, /* xFindFunction - function overloading */ - rtreeRename, /* xRename - rename the table */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ -}; - -static int rtreeSqlInit( - Rtree *pRtree, - sqlite3 *db, - const char *zDb, - const char *zPrefix, - int isCreate -){ - int rc = SQLITE_OK; - - #define N_STATEMENT 9 - static const char *azSql[N_STATEMENT] = { - /* Read and write the xxx_node table */ - "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1", - "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1", - - /* Read and write the xxx_rowid table */ - "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1", - "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1", - - /* Read and write the xxx_parent table */ - "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1", - "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)", - "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1" - }; - sqlite3_stmt **appStmt[N_STATEMENT]; - int i; - - pRtree->db = db; - - if( isCreate ){ - char *zCreate = sqlite3_mprintf( -"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);" -"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);" -"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY," - " parentnode INTEGER);" -"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))", - zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize - ); - if( !zCreate ){ - return SQLITE_NOMEM; - } - rc = sqlite3_exec(db, zCreate, 0, 0, 0); - sqlite3_free(zCreate); - if( rc!=SQLITE_OK ){ - return rc; - } - } - - appStmt[0] = &pRtree->pReadNode; - appStmt[1] = &pRtree->pWriteNode; - appStmt[2] = &pRtree->pDeleteNode; - appStmt[3] = &pRtree->pReadRowid; - appStmt[4] = &pRtree->pWriteRowid; - appStmt[5] = &pRtree->pDeleteRowid; - appStmt[6] = &pRtree->pReadParent; - appStmt[7] = &pRtree->pWriteParent; - appStmt[8] = &pRtree->pDeleteParent; - - rc = rtreeQueryStat1(db, pRtree); - for(i=0; iiNodeSize is populated and SQLITE_OK returned. -** Otherwise, an SQLite error code is returned. -** -** If this function is being called as part of an xConnect(), then the rtree -** table already exists. In this case the node-size is determined by inspecting -** the root node of the tree. -** -** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. -** This ensures that each node is stored on a single database page. If the -** database page-size is so large that more than RTREE_MAXCELLS entries -** would fit in a single node, use a smaller node-size. -*/ -static int getNodeSize( - sqlite3 *db, /* Database handle */ - Rtree *pRtree, /* Rtree handle */ - int isCreate, /* True for xCreate, false for xConnect */ - char **pzErr /* OUT: Error message, if any */ -){ - int rc; - char *zSql; - if( isCreate ){ - int iPageSize = 0; - zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); - rc = getIntFromStmt(db, zSql, &iPageSize); - if( rc==SQLITE_OK ){ - pRtree->iNodeSize = iPageSize-64; - if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)iNodeSize ){ - pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; - } - }else{ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - } - }else{ - zSql = sqlite3_mprintf( - "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", - pRtree->zDb, pRtree->zName - ); - rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); - if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - } - } - - sqlite3_free(zSql); - return rc; -} - -/* -** This function is the implementation of both the xConnect and xCreate -** methods of the r-tree virtual table. -** -** argv[0] -> module name -** argv[1] -> database name -** argv[2] -> table name -** argv[...] -> column names... -*/ -static int rtreeInit( - sqlite3 *db, /* Database connection */ - void *pAux, /* One of the RTREE_COORD_* constants */ - int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ - sqlite3_vtab **ppVtab, /* OUT: New virtual table */ - char **pzErr, /* OUT: Error message, if any */ - int isCreate /* True for xCreate, false for xConnect */ -){ - int rc = SQLITE_OK; - Rtree *pRtree; - int nDb; /* Length of string argv[1] */ - int nName; /* Length of string argv[2] */ - int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); - - const char *aErrMsg[] = { - 0, /* 0 */ - "Wrong number of columns for an rtree table", /* 1 */ - "Too few columns for an rtree table", /* 2 */ - "Too many columns for an rtree table" /* 3 */ - }; - - int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2; - if( aErrMsg[iErr] ){ - *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); - return SQLITE_ERROR; - } - - sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - - /* Allocate the sqlite3_vtab structure */ - nDb = (int)strlen(argv[1]); - nName = (int)strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); - if( !pRtree ){ - return SQLITE_NOMEM; - } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); - pRtree->nBusy = 1; - pRtree->base.pModule = &rtreeModule; - pRtree->zDb = (char *)&pRtree[1]; - pRtree->zName = &pRtree->zDb[nDb+1]; - pRtree->nDim = (argc-4)/2; - pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2; - pRtree->eCoordType = eCoordType; - memcpy(pRtree->zDb, argv[1], nDb); - memcpy(pRtree->zName, argv[2], nName); - - /* Figure out the node size to use. */ - rc = getNodeSize(db, pRtree, isCreate, pzErr); - - /* Create/Connect to the underlying relational database schema. If - ** that is successful, call sqlite3_declare_vtab() to configure - ** the r-tree table schema. - */ - if( rc==SQLITE_OK ){ - if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){ - *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - }else{ - char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]); - char *zTmp; - int ii; - for(ii=4; zSql && iinBusy==1 ); - rtreeRelease(pRtree); - } - return rc; -} - - -/* -** Implementation of a scalar function that decodes r-tree nodes to -** human readable strings. This can be used for debugging and analysis. -** -** The scalar function takes two arguments: (1) the number of dimensions -** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing -** an r-tree node. For a two-dimensional r-tree structure called "rt", to -** deserialize all nodes, a statement like: -** -** SELECT rtreenode(2, data) FROM rt_node; -** -** The human readable string takes the form of a Tcl list with one -** entry for each cell in the r-tree node. Each entry is itself a -** list, containing the 8-byte rowid/pageno followed by the -** *2 coordinates. -*/ -static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ - char *zText = 0; - RtreeNode node; - Rtree tree; - int ii; - - UNUSED_PARAMETER(nArg); - memset(&node, 0, sizeof(RtreeNode)); - memset(&tree, 0, sizeof(Rtree)); - tree.nDim = sqlite3_value_int(apArg[0]); - tree.nBytesPerCell = 8 + 8 * tree.nDim; - node.zData = (u8 *)sqlite3_value_blob(apArg[1]); - - for(ii=0; iixDestructor ) pInfo->xDestructor(pInfo->pContext); - sqlite3_free(p); -} - -/* -** This routine frees the BLOB that is returned by geomCallback(). -*/ -static void rtreeMatchArgFree(void *pArg){ - int i; - RtreeMatchArg *p = (RtreeMatchArg*)pArg; - for(i=0; inParam; i++){ - sqlite3_value_free(p->apSqlParam[i]); - } - sqlite3_free(p); -} - -/* -** Each call to sqlite3_rtree_geometry_callback() or -** sqlite3_rtree_query_callback() creates an ordinary SQLite -** scalar function that is implemented by this routine. -** -** All this function does is construct an RtreeMatchArg object that -** contains the geometry-checking callback routines and a list of -** parameters to this function, then return that RtreeMatchArg object -** as a BLOB. -** -** The R-Tree MATCH operator will read the returned BLOB, deserialize -** the RtreeMatchArg object, and use the RtreeMatchArg object to figure -** out which elements of the R-Tree should be returned by the query. -*/ -static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ - RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); - RtreeMatchArg *pBlob; - int nBlob; - int memErr = 0; - - nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) - + nArg*sizeof(sqlite3_value*); - pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); - if( !pBlob ){ - sqlite3_result_error_nomem(ctx); - }else{ - int i; - pBlob->magic = RTREE_GEOMETRY_MAGIC; - pBlob->cb = pGeomCtx[0]; - pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg]; - pBlob->nParam = nArg; - for(i=0; iapSqlParam[i] = sqlite3_value_dup(aArg[i]); - if( pBlob->apSqlParam[i]==0 ) memErr = 1; -#ifdef SQLITE_RTREE_INT_ONLY - pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); -#else - pBlob->aParam[i] = sqlite3_value_double(aArg[i]); -#endif - } - if( memErr ){ - sqlite3_result_error_nomem(ctx); - rtreeMatchArgFree(pBlob); - }else{ - sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree); - } - } -} - -/* -** Register a new geometry function for use with the r-tree MATCH operator. -*/ -SQLITE_API int sqlite3_rtree_geometry_callback( - sqlite3 *db, /* Register SQL function on this connection */ - const char *zGeom, /* Name of the new SQL function */ - int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ - void *pContext /* Extra data associated with the callback */ -){ - RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ - - /* Allocate and populate the context object. */ - pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); - if( !pGeomCtx ) return SQLITE_NOMEM; - pGeomCtx->xGeom = xGeom; - pGeomCtx->xQueryFunc = 0; - pGeomCtx->xDestructor = 0; - pGeomCtx->pContext = pContext; - return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, - (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback - ); -} - -/* -** Register a new 2nd-generation geometry function for use with the -** r-tree MATCH operator. -*/ -SQLITE_API int sqlite3_rtree_query_callback( - sqlite3 *db, /* Register SQL function on this connection */ - const char *zQueryFunc, /* Name of new SQL function */ - int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ - void *pContext, /* Extra data passed into the callback */ - void (*xDestructor)(void*) /* Destructor for the extra data */ -){ - RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ - - /* Allocate and populate the context object. */ - pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); - if( !pGeomCtx ) return SQLITE_NOMEM; - pGeomCtx->xGeom = 0; - pGeomCtx->xQueryFunc = xQueryFunc; - pGeomCtx->xDestructor = xDestructor; - pGeomCtx->pContext = pContext; - return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, - (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback - ); -} - -#if !SQLITE_CORE -#ifdef _WIN32 -__declspec(dllexport) -#endif -SQLITE_API int sqlite3_rtree_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - SQLITE_EXTENSION_INIT2(pApi) - return sqlite3RtreeInit(db); -} -#endif - -#endif - -/************** End of rtree.c ***********************************************/ -/************** Begin file icu.c *********************************************/ -/* -** 2007 May 6 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ -** -** This file implements an integration between the ICU library -** ("International Components for Unicode", an open-source library -** for handling unicode data) and SQLite. The integration uses -** ICU to provide the following to SQLite: -** -** * An implementation of the SQL regexp() function (and hence REGEXP -** operator) using the ICU uregex_XX() APIs. -** -** * Implementations of the SQL scalar upper() and lower() functions -** for case mapping. -** -** * Integration of ICU and SQLite collation sequences. -** -** * An implementation of the LIKE operator that uses ICU to -** provide case-independent matching. -*/ - -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) - -/* Include ICU headers */ -#include -#include -#include -#include - -/* #include */ - -#ifndef SQLITE_CORE -/* #include "sqlite3ext.h" */ - SQLITE_EXTENSION_INIT1 -#else -/* #include "sqlite3.h" */ -#endif - -/* -** Maximum length (in bytes) of the pattern in a LIKE or GLOB -** operator. -*/ -#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH -# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 -#endif - -/* -** Version of sqlite3_free() that is always a function, never a macro. -*/ -static void xFree(void *p){ - sqlite3_free(p); -} - -/* -** This lookup table is used to help decode the first byte of -** a multi-byte UTF8 character. It is copied here from SQLite source -** code file utf8.c. -*/ -static const unsigned char icuUtf8Trans1[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, -}; - -#define SQLITE_ICU_READ_UTF8(zIn, c) \ - c = *(zIn++); \ - if( c>=0xc0 ){ \ - c = icuUtf8Trans1[c-0xc0]; \ - while( (*zIn & 0xc0)==0x80 ){ \ - c = (c<<6) + (0x3f & *(zIn++)); \ - } \ - } - -#define SQLITE_ICU_SKIP_UTF8(zIn) \ - assert( *zIn ); \ - if( *(zIn++)>=0xc0 ){ \ - while( (*zIn & 0xc0)==0x80 ){zIn++;} \ - } - - -/* -** Compare two UTF-8 strings for equality where the first string is -** a "LIKE" expression. Return true (1) if they are the same and -** false (0) if they are different. -*/ -static int icuLikeCompare( - const uint8_t *zPattern, /* LIKE pattern */ - const uint8_t *zString, /* The UTF-8 string to compare against */ - const UChar32 uEsc /* The escape character */ -){ - static const int MATCH_ONE = (UChar32)'_'; - static const int MATCH_ALL = (UChar32)'%'; - - int prevEscape = 0; /* True if the previous character was uEsc */ - - while( 1 ){ - - /* Read (and consume) the next character from the input pattern. */ - UChar32 uPattern; - SQLITE_ICU_READ_UTF8(zPattern, uPattern); - if( uPattern==0 ) break; - - /* There are now 4 possibilities: - ** - ** 1. uPattern is an unescaped match-all character "%", - ** 2. uPattern is an unescaped match-one character "_", - ** 3. uPattern is an unescaped escape character, or - ** 4. uPattern is to be handled as an ordinary character - */ - if( !prevEscape && uPattern==MATCH_ALL ){ - /* Case 1. */ - uint8_t c; - - /* Skip any MATCH_ALL or MATCH_ONE characters that follow a - ** MATCH_ALL. For each MATCH_ONE, skip one character in the - ** test string. - */ - while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){ - if( c==MATCH_ONE ){ - if( *zString==0 ) return 0; - SQLITE_ICU_SKIP_UTF8(zString); - } - zPattern++; - } - - if( *zPattern==0 ) return 1; - - while( *zString ){ - if( icuLikeCompare(zPattern, zString, uEsc) ){ - return 1; - } - SQLITE_ICU_SKIP_UTF8(zString); - } - return 0; - - }else if( !prevEscape && uPattern==MATCH_ONE ){ - /* Case 2. */ - if( *zString==0 ) return 0; - SQLITE_ICU_SKIP_UTF8(zString); - - }else if( !prevEscape && uPattern==uEsc){ - /* Case 3. */ - prevEscape = 1; - - }else{ - /* Case 4. */ - UChar32 uString; - SQLITE_ICU_READ_UTF8(zString, uString); - uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT); - uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT); - if( uString!=uPattern ){ - return 0; - } - prevEscape = 0; - } - } - - return *zString==0; -} - -/* -** Implementation of the like() SQL function. This function implements -** the build-in LIKE operator. The first argument to the function is the -** pattern and the second argument is the string. So, the SQL statements: -** -** A LIKE B -** -** is implemented as like(B, A). If there is an escape character E, -** -** A LIKE B ESCAPE E -** -** is mapped to like(B, A, E). -*/ -static void icuLikeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const unsigned char *zA = sqlite3_value_text(argv[0]); - const unsigned char *zB = sqlite3_value_text(argv[1]); - UChar32 uEsc = 0; - - /* Limit the length of the LIKE or GLOB pattern to avoid problems - ** of deep recursion and N*N behavior in patternCompare(). - */ - if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ - sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); - return; - } - - - if( argc==3 ){ - /* The escape character string must consist of a single UTF-8 character. - ** Otherwise, return an error. - */ - int nE= sqlite3_value_bytes(argv[2]); - const unsigned char *zE = sqlite3_value_text(argv[2]); - int i = 0; - if( zE==0 ) return; - U8_NEXT(zE, i, nE, uEsc); - if( i!=nE){ - sqlite3_result_error(context, - "ESCAPE expression must be a single character", -1); - return; - } - } - - if( zA && zB ){ - sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); - } -} - -/* -** This function is called when an ICU function called from within -** the implementation of an SQL scalar function returns an error. -** -** The scalar function context passed as the first argument is -** loaded with an error message based on the following two args. -*/ -static void icuFunctionError( - sqlite3_context *pCtx, /* SQLite scalar function context */ - const char *zName, /* Name of ICU function that failed */ - UErrorCode e /* Error code returned by ICU function */ -){ - char zBuf[128]; - sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); - zBuf[127] = '\0'; - sqlite3_result_error(pCtx, zBuf, -1); -} - -/* -** Function to delete compiled regexp objects. Registered as -** a destructor function with sqlite3_set_auxdata(). -*/ -static void icuRegexpDelete(void *p){ - URegularExpression *pExpr = (URegularExpression *)p; - uregex_close(pExpr); -} - -/* -** Implementation of SQLite REGEXP operator. This scalar function takes -** two arguments. The first is a regular expression pattern to compile -** the second is a string to match against that pattern. If either -** argument is an SQL NULL, then NULL Is returned. Otherwise, the result -** is 1 if the string matches the pattern, or 0 otherwise. -** -** SQLite maps the regexp() function to the regexp() operator such -** that the following two are equivalent: -** -** zString REGEXP zPattern -** regexp(zPattern, zString) -** -** Uses the following ICU regexp APIs: -** -** uregex_open() -** uregex_matches() -** uregex_close() -*/ -static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ - UErrorCode status = U_ZERO_ERROR; - URegularExpression *pExpr; - UBool res; - const UChar *zString = sqlite3_value_text16(apArg[1]); - - (void)nArg; /* Unused parameter */ - - /* If the left hand side of the regexp operator is NULL, - ** then the result is also NULL. - */ - if( !zString ){ - return; - } - - pExpr = sqlite3_get_auxdata(p, 0); - if( !pExpr ){ - const UChar *zPattern = sqlite3_value_text16(apArg[0]); - if( !zPattern ){ - return; - } - pExpr = uregex_open(zPattern, -1, 0, 0, &status); - - if( U_SUCCESS(status) ){ - sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); - }else{ - assert(!pExpr); - icuFunctionError(p, "uregex_open", status); - return; - } - } - - /* Configure the text that the regular expression operates on. */ - uregex_setText(pExpr, zString, -1, &status); - if( !U_SUCCESS(status) ){ - icuFunctionError(p, "uregex_setText", status); - return; - } - - /* Attempt the match */ - res = uregex_matches(pExpr, 0, &status); - if( !U_SUCCESS(status) ){ - icuFunctionError(p, "uregex_matches", status); - return; - } - - /* Set the text that the regular expression operates on to a NULL - ** pointer. This is not really necessary, but it is tidier than - ** leaving the regular expression object configured with an invalid - ** pointer after this function returns. - */ - uregex_setText(pExpr, 0, 0, &status); - - /* Return 1 or 0. */ - sqlite3_result_int(p, res ? 1 : 0); -} - -/* -** Implementations of scalar functions for case mapping - upper() and -** lower(). Function upper() converts its input to upper-case (ABC). -** Function lower() converts to lower-case (abc). -** -** ICU provides two types of case mapping, "general" case mapping and -** "language specific". Refer to ICU documentation for the differences -** between the two. -** -** To utilise "general" case mapping, the upper() or lower() scalar -** functions are invoked with one argument: -** -** upper('ABC') -> 'abc' -** lower('abc') -> 'ABC' -** -** To access ICU "language specific" case mapping, upper() or lower() -** should be invoked with two arguments. The second argument is the name -** of the locale to use. Passing an empty string ("") or SQL NULL value -** as the second argument is the same as invoking the 1 argument version -** of upper() or lower(). -** -** lower('I', 'en_us') -> 'i' -** lower('I', 'tr_tr') -> '\u131' (small dotless i) -** -** http://www.icu-project.org/userguide/posix.html#case_mappings -*/ -static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ - const UChar *zInput; /* Pointer to input string */ - UChar *zOutput = 0; /* Pointer to output buffer */ - int nInput; /* Size of utf-16 input string in bytes */ - int nOut; /* Size of output buffer in bytes */ - int cnt; - int bToUpper; /* True for toupper(), false for tolower() */ - UErrorCode status; - const char *zLocale = 0; - - assert(nArg==1 || nArg==2); - bToUpper = (sqlite3_user_data(p)!=0); - if( nArg==2 ){ - zLocale = (const char *)sqlite3_value_text(apArg[1]); - } - - zInput = sqlite3_value_text16(apArg[0]); - if( !zInput ){ - return; - } - nOut = nInput = sqlite3_value_bytes16(apArg[0]); - if( nOut==0 ){ - sqlite3_result_text16(p, "", 0, SQLITE_STATIC); - return; - } - - for(cnt=0; cnt<2; cnt++){ - UChar *zNew = sqlite3_realloc(zOutput, nOut); - if( zNew==0 ){ - sqlite3_free(zOutput); - sqlite3_result_error_nomem(p); - return; - } - zOutput = zNew; - status = U_ZERO_ERROR; - if( bToUpper ){ - nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); - }else{ - nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); - } - - if( U_SUCCESS(status) ){ - sqlite3_result_text16(p, zOutput, nOut, xFree); - }else if( status==U_BUFFER_OVERFLOW_ERROR ){ - assert( cnt==0 ); - continue; - }else{ - icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); - } - return; - } - assert( 0 ); /* Unreachable */ -} - -/* -** Collation sequence destructor function. The pCtx argument points to -** a UCollator structure previously allocated using ucol_open(). -*/ -static void icuCollationDel(void *pCtx){ - UCollator *p = (UCollator *)pCtx; - ucol_close(p); -} - -/* -** Collation sequence comparison function. The pCtx argument points to -** a UCollator structure previously allocated using ucol_open(). -*/ -static int icuCollationColl( - void *pCtx, - int nLeft, - const void *zLeft, - int nRight, - const void *zRight -){ - UCollationResult res; - UCollator *p = (UCollator *)pCtx; - res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2); - switch( res ){ - case UCOL_LESS: return -1; - case UCOL_GREATER: return +1; - case UCOL_EQUAL: return 0; - } - assert(!"Unexpected return value from ucol_strcoll()"); - return 0; -} - -/* -** Implementation of the scalar function icu_load_collation(). -** -** This scalar function is used to add ICU collation based collation -** types to an SQLite database connection. It is intended to be called -** as follows: -** -** SELECT icu_load_collation(, ); -** -** Where is a string containing an ICU locale identifier (i.e. -** "en_AU", "tr_TR" etc.) and is the name of the -** collation sequence to create. -*/ -static void icuLoadCollation( - sqlite3_context *p, - int nArg, - sqlite3_value **apArg -){ - sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); - UErrorCode status = U_ZERO_ERROR; - const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ - const char *zName; /* SQL Collation sequence name (eg. "japanese") */ - UCollator *pUCollator; /* ICU library collation object */ - int rc; /* Return code from sqlite3_create_collation_x() */ - - assert(nArg==2); - (void)nArg; /* Unused parameter */ - zLocale = (const char *)sqlite3_value_text(apArg[0]); - zName = (const char *)sqlite3_value_text(apArg[1]); - - if( !zLocale || !zName ){ - return; - } - - pUCollator = ucol_open(zLocale, &status); - if( !U_SUCCESS(status) ){ - icuFunctionError(p, "ucol_open", status); - return; - } - assert(p); - - rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, - icuCollationColl, icuCollationDel - ); - if( rc!=SQLITE_OK ){ - ucol_close(pUCollator); - sqlite3_result_error(p, "Error registering collation function", -1); - } -} - -/* -** Register the ICU extension functions with database db. -*/ -SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ - struct IcuScalar { - const char *zName; /* Function name */ - int nArg; /* Number of arguments */ - int enc; /* Optimal text encoding */ - void *pContext; /* sqlite3_user_data() context */ - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } scalars[] = { - {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc}, - - {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16}, - - {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16}, - {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16}, - {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16}, - {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16}, - - {"like", 2, SQLITE_UTF8, 0, icuLikeFunc}, - {"like", 3, SQLITE_UTF8, 0, icuLikeFunc}, - - {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation}, - }; - - int rc = SQLITE_OK; - int i; - - for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ - struct IcuScalar *p = &scalars[i]; - rc = sqlite3_create_function( - db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 - ); - } - - return rc; -} - -#if !SQLITE_CORE -#ifdef _WIN32 -__declspec(dllexport) -#endif -SQLITE_API int sqlite3_icu_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - SQLITE_EXTENSION_INIT2(pApi) - return sqlite3IcuInit(db); -} -#endif - -#endif - -/************** End of icu.c *************************************************/ -/************** Begin file fts3_icu.c ****************************************/ -/* -** 2007 June 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** This file implements a tokenizer for fts3 based on the ICU library. -*/ -/* #include "fts3Int.h" */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) -#ifdef SQLITE_ENABLE_ICU - -/* #include */ -/* #include */ -/* #include "fts3_tokenizer.h" */ - -#include -/* #include */ -/* #include */ -#include - -typedef struct IcuTokenizer IcuTokenizer; -typedef struct IcuCursor IcuCursor; - -struct IcuTokenizer { - sqlite3_tokenizer base; - char *zLocale; -}; - -struct IcuCursor { - sqlite3_tokenizer_cursor base; - - UBreakIterator *pIter; /* ICU break-iterator object */ - int nChar; /* Number of UChar elements in pInput */ - UChar *aChar; /* Copy of input using utf-16 encoding */ - int *aOffset; /* Offsets of each character in utf-8 input */ - - int nBuffer; - char *zBuffer; - - int iToken; -}; - -/* -** Create a new tokenizer instance. -*/ -static int icuCreate( - int argc, /* Number of entries in argv[] */ - const char * const *argv, /* Tokenizer creation arguments */ - sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ -){ - IcuTokenizer *p; - int n = 0; - - if( argc>0 ){ - n = strlen(argv[0])+1; - } - p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n); - if( !p ){ - return SQLITE_NOMEM; - } - memset(p, 0, sizeof(IcuTokenizer)); - - if( n ){ - p->zLocale = (char *)&p[1]; - memcpy(p->zLocale, argv[0], n); - } - - *ppTokenizer = (sqlite3_tokenizer *)p; - - return SQLITE_OK; -} - -/* -** Destroy a tokenizer -*/ -static int icuDestroy(sqlite3_tokenizer *pTokenizer){ - IcuTokenizer *p = (IcuTokenizer *)pTokenizer; - sqlite3_free(p); - return SQLITE_OK; -} - -/* -** Prepare to begin tokenizing a particular string. The input -** string to be tokenized is pInput[0..nBytes-1]. A cursor -** used to incrementally tokenize this string is returned in -** *ppCursor. -*/ -static int icuOpen( - sqlite3_tokenizer *pTokenizer, /* The tokenizer */ - const char *zInput, /* Input string */ - int nInput, /* Length of zInput in bytes */ - sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ -){ - IcuTokenizer *p = (IcuTokenizer *)pTokenizer; - IcuCursor *pCsr; - - const int32_t opt = U_FOLD_CASE_DEFAULT; - UErrorCode status = U_ZERO_ERROR; - int nChar; - - UChar32 c; - int iInput = 0; - int iOut = 0; - - *ppCursor = 0; - - if( zInput==0 ){ - nInput = 0; - zInput = ""; - }else if( nInput<0 ){ - nInput = strlen(zInput); - } - nChar = nInput+1; - pCsr = (IcuCursor *)sqlite3_malloc( - sizeof(IcuCursor) + /* IcuCursor */ - ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ - (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ - ); - if( !pCsr ){ - return SQLITE_NOMEM; - } - memset(pCsr, 0, sizeof(IcuCursor)); - pCsr->aChar = (UChar *)&pCsr[1]; - pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; - - pCsr->aOffset[iOut] = iInput; - U8_NEXT(zInput, iInput, nInput, c); - while( c>0 ){ - int isError = 0; - c = u_foldCase(c, opt); - U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); - if( isError ){ - sqlite3_free(pCsr); - return SQLITE_ERROR; - } - pCsr->aOffset[iOut] = iInput; - - if( iInputpIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); - if( !U_SUCCESS(status) ){ - sqlite3_free(pCsr); - return SQLITE_ERROR; - } - pCsr->nChar = iOut; - - ubrk_first(pCsr->pIter); - *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; - return SQLITE_OK; -} - -/* -** Close a tokenization cursor previously opened by a call to icuOpen(). -*/ -static int icuClose(sqlite3_tokenizer_cursor *pCursor){ - IcuCursor *pCsr = (IcuCursor *)pCursor; - ubrk_close(pCsr->pIter); - sqlite3_free(pCsr->zBuffer); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** Extract the next token from a tokenization cursor. -*/ -static int icuNext( - sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ - const char **ppToken, /* OUT: *ppToken is the token text */ - int *pnBytes, /* OUT: Number of bytes in token */ - int *piStartOffset, /* OUT: Starting offset of token */ - int *piEndOffset, /* OUT: Ending offset of token */ - int *piPosition /* OUT: Position integer of token */ -){ - IcuCursor *pCsr = (IcuCursor *)pCursor; - - int iStart = 0; - int iEnd = 0; - int nByte = 0; - - while( iStart==iEnd ){ - UChar32 c; - - iStart = ubrk_current(pCsr->pIter); - iEnd = ubrk_next(pCsr->pIter); - if( iEnd==UBRK_DONE ){ - return SQLITE_DONE; - } - - while( iStartaChar, iWhite, pCsr->nChar, c); - if( u_isspace(c) ){ - iStart = iWhite; - }else{ - break; - } - } - assert(iStart<=iEnd); - } - - do { - UErrorCode status = U_ZERO_ERROR; - if( nByte ){ - char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); - if( !zNew ){ - return SQLITE_NOMEM; - } - pCsr->zBuffer = zNew; - pCsr->nBuffer = nByte; - } - - u_strToUTF8( - pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */ - &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */ - &status /* Output success/failure */ - ); - } while( nByte>pCsr->nBuffer ); - - *ppToken = pCsr->zBuffer; - *pnBytes = nByte; - *piStartOffset = pCsr->aOffset[iStart]; - *piEndOffset = pCsr->aOffset[iEnd]; - *piPosition = pCsr->iToken++; - - return SQLITE_OK; -} - -/* -** The set of routines that implement the simple tokenizer -*/ -static const sqlite3_tokenizer_module icuTokenizerModule = { - 0, /* iVersion */ - icuCreate, /* xCreate */ - icuDestroy, /* xCreate */ - icuOpen, /* xOpen */ - icuClose, /* xClose */ - icuNext, /* xNext */ - 0, /* xLanguageid */ -}; - -/* -** Set *ppModule to point at the implementation of the ICU tokenizer. -*/ -SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( - sqlite3_tokenizer_module const**ppModule -){ - *ppModule = &icuTokenizerModule; -} - -#endif /* defined(SQLITE_ENABLE_ICU) */ -#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - -/************** End of fts3_icu.c ********************************************/ -/************** Begin file sqlite3rbu.c **************************************/ -/* -** 2014 August 30 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** -** OVERVIEW -** -** The RBU extension requires that the RBU update be packaged as an -** SQLite database. The tables it expects to find are described in -** sqlite3rbu.h. Essentially, for each table xyz in the target database -** that the user wishes to write to, a corresponding data_xyz table is -** created in the RBU database and populated with one row for each row to -** update, insert or delete from the target table. -** -** The update proceeds in three stages: -** -** 1) The database is updated. The modified database pages are written -** to a *-oal file. A *-oal file is just like a *-wal file, except -** that it is named "-oal" instead of "-wal". -** Because regular SQLite clients do not look for file named -** "-oal", they go on using the original database in -** rollback mode while the *-oal file is being generated. -** -** During this stage RBU does not update the database by writing -** directly to the target tables. Instead it creates "imposter" -** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses -** to update each b-tree individually. All updates required by each -** b-tree are completed before moving on to the next, and all -** updates are done in sorted key order. -** -** 2) The "-oal" file is moved to the equivalent "-wal" -** location using a call to rename(2). Before doing this the RBU -** module takes an EXCLUSIVE lock on the database file, ensuring -** that there are no other active readers. -** -** Once the EXCLUSIVE lock is released, any other database readers -** detect the new *-wal file and read the database in wal mode. At -** this point they see the new version of the database - including -** the updates made as part of the RBU update. -** -** 3) The new *-wal file is checkpointed. This proceeds in the same way -** as a regular database checkpoint, except that a single frame is -** checkpointed each time sqlite3rbu_step() is called. If the RBU -** handle is closed before the entire *-wal file is checkpointed, -** the checkpoint progress is saved in the RBU database and the -** checkpoint can be resumed by another RBU client at some point in -** the future. -** -** POTENTIAL PROBLEMS -** -** The rename() call might not be portable. And RBU is not currently -** syncing the directory after renaming the file. -** -** When state is saved, any commit to the *-oal file and the commit to -** the RBU update database are not atomic. So if the power fails at the -** wrong moment they might get out of sync. As the main database will be -** committed before the RBU update database this will likely either just -** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE -** constraint violations). -** -** If some client does modify the target database mid RBU update, or some -** other error occurs, the RBU extension will keep throwing errors. It's -** not really clear how to get out of this state. The system could just -** by delete the RBU update database and *-oal file and have the device -** download the update again and start over. -** -** At present, for an UPDATE, both the new.* and old.* records are -** collected in the rbu_xyz table. And for both UPDATEs and DELETEs all -** fields are collected. This means we're probably writing a lot more -** data to disk when saving the state of an ongoing update to the RBU -** update database than is strictly necessary. -** -*/ - -/* #include */ -/* #include */ -/* #include */ - -/* #include "sqlite3.h" */ - -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) -/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/ -/************** Begin file sqlite3rbu.h **************************************/ -/* -** 2014 August 30 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -************************************************************************* -** -** This file contains the public interface for the RBU extension. -*/ - -/* -** SUMMARY -** -** Writing a transaction containing a large number of operations on -** b-tree indexes that are collectively larger than the available cache -** memory can be very inefficient. -** -** The problem is that in order to update a b-tree, the leaf page (at least) -** containing the entry being inserted or deleted must be modified. If the -** working set of leaves is larger than the available cache memory, then a -** single leaf that is modified more than once as part of the transaction -** may be loaded from or written to the persistent media multiple times. -** Additionally, because the index updates are likely to be applied in -** random order, access to pages within the database is also likely to be in -** random order, which is itself quite inefficient. -** -** One way to improve the situation is to sort the operations on each index -** by index key before applying them to the b-tree. This leads to an IO -** pattern that resembles a single linear scan through the index b-tree, -** and all but guarantees each modified leaf page is loaded and stored -** exactly once. SQLite uses this trick to improve the performance of -** CREATE INDEX commands. This extension allows it to be used to improve -** the performance of large transactions on existing databases. -** -** Additionally, this extension allows the work involved in writing the -** large transaction to be broken down into sub-transactions performed -** sequentially by separate processes. This is useful if the system cannot -** guarantee that a single update process will run for long enough to apply -** the entire update, for example because the update is being applied on a -** mobile device that is frequently rebooted. Even after the writer process -** has committed one or more sub-transactions, other database clients continue -** to read from the original database snapshot. In other words, partially -** applied transactions are not visible to other clients. -** -** "RBU" stands for "Resumable Bulk Update". As in a large database update -** transmitted via a wireless network to a mobile device. A transaction -** applied using this extension is hence refered to as an "RBU update". -** -** -** LIMITATIONS -** -** An "RBU update" transaction is subject to the following limitations: -** -** * The transaction must consist of INSERT, UPDATE and DELETE operations -** only. -** -** * INSERT statements may not use any default values. -** -** * UPDATE and DELETE statements must identify their target rows by -** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY -** KEY fields may not be updated or deleted. If the table being written -** has no PRIMARY KEY, affected rows must be identified by rowid. -** -** * UPDATE statements may not modify PRIMARY KEY columns. -** -** * No triggers will be fired. -** -** * No foreign key violations are detected or reported. -** -** * CHECK constraints are not enforced. -** -** * No constraint handling mode except for "OR ROLLBACK" is supported. -** -** -** PREPARATION -** -** An "RBU update" is stored as a separate SQLite database. A database -** containing an RBU update is an "RBU database". For each table in the -** target database to be updated, the RBU database should contain a table -** named "data_" containing the same set of columns as the -** target table, and one more - "rbu_control". The data_% table should -** have no PRIMARY KEY or UNIQUE constraints, but each column should have -** the same type as the corresponding column in the target database. -** The "rbu_control" column should have no type at all. For example, if -** the target database contains: -** -** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE); -** -** Then the RBU database should contain: -** -** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control); -** -** The order of the columns in the data_% table does not matter. -** -** Instead of a regular table, the RBU database may also contain virtual -** tables or view named using the data_ naming scheme. -** -** Instead of the plain data_ naming scheme, RBU database tables -** may also be named data_, where is any sequence -** of zero or more numeric characters (0-9). This can be significant because -** tables within the RBU database are always processed in order sorted by -** name. By judicious selection of the portion of the names -** of the RBU tables the user can therefore control the order in which they -** are processed. This can be useful, for example, to ensure that "external -** content" FTS4 tables are updated before their underlying content tables. -** -** If the target database table is a virtual table or a table that has no -** PRIMARY KEY declaration, the data_% table must also contain a column -** named "rbu_rowid". This column is mapped to the tables implicit primary -** key column - "rowid". Virtual tables for which the "rowid" column does -** not function like a primary key value cannot be updated using RBU. For -** example, if the target db contains either of the following: -** -** CREATE VIRTUAL TABLE x1 USING fts3(a, b); -** CREATE TABLE x1(a, b) -** -** then the RBU database should contain: -** -** CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control); -** -** All non-hidden columns (i.e. all columns matched by "SELECT *") of the -** target table must be present in the input table. For virtual tables, -** hidden columns are optional - they are updated by RBU if present in -** the input table, or not otherwise. For example, to write to an fts4 -** table with a hidden languageid column such as: -** -** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid'); -** -** Either of the following input table schemas may be used: -** -** CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control); -** CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control); -** -** For each row to INSERT into the target database as part of the RBU -** update, the corresponding data_% table should contain a single record -** with the "rbu_control" column set to contain integer value 0. The -** other columns should be set to the values that make up the new record -** to insert. -** -** If the target database table has an INTEGER PRIMARY KEY, it is not -** possible to insert a NULL value into the IPK column. Attempting to -** do so results in an SQLITE_MISMATCH error. -** -** For each row to DELETE from the target database as part of the RBU -** update, the corresponding data_% table should contain a single record -** with the "rbu_control" column set to contain integer value 1. The -** real primary key values of the row to delete should be stored in the -** corresponding columns of the data_% table. The values stored in the -** other columns are not used. -** -** For each row to UPDATE from the target database as part of the RBU -** update, the corresponding data_% table should contain a single record -** with the "rbu_control" column set to contain a value of type text. -** The real primary key values identifying the row to update should be -** stored in the corresponding columns of the data_% table row, as should -** the new values of all columns being update. The text value in the -** "rbu_control" column must contain the same number of characters as -** there are columns in the target database table, and must consist entirely -** of 'x' and '.' characters (or in some special cases 'd' - see below). For -** each column that is being updated, the corresponding character is set to -** 'x'. For those that remain as they are, the corresponding character of the -** rbu_control value should be set to '.'. For example, given the tables -** above, the update statement: -** -** UPDATE t1 SET c = 'usa' WHERE a = 4; -** -** is represented by the data_t1 row created by: -** -** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x'); -** -** Instead of an 'x' character, characters of the rbu_control value specified -** for UPDATEs may also be set to 'd'. In this case, instead of updating the -** target table with the value stored in the corresponding data_% column, the -** user-defined SQL function "rbu_delta()" is invoked and the result stored in -** the target table column. rbu_delta() is invoked with two arguments - the -** original value currently stored in the target table column and the -** value specified in the data_xxx table. -** -** For example, this row: -** -** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d'); -** -** is similar to an UPDATE statement such as: -** -** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4; -** -** Finally, if an 'f' character appears in place of a 'd' or 's' in an -** ota_control string, the contents of the data_xxx table column is assumed -** to be a "fossil delta" - a patch to be applied to a blob value in the -** format used by the fossil source-code management system. In this case -** the existing value within the target database table must be of type BLOB. -** It is replaced by the result of applying the specified fossil delta to -** itself. -** -** If the target database table is a virtual table or a table with no PRIMARY -** KEY, the rbu_control value should not include a character corresponding -** to the rbu_rowid value. For example, this: -** -** INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control) -** VALUES(NULL, 'usa', 12, '.x'); -** -** causes a result similar to: -** -** UPDATE ft1 SET b = 'usa' WHERE rowid = 12; -** -** The data_xxx tables themselves should have no PRIMARY KEY declarations. -** However, RBU is more efficient if reading the rows in from each data_xxx -** table in "rowid" order is roughly the same as reading them sorted by -** the PRIMARY KEY of the corresponding target database table. In other -** words, rows should be sorted using the destination table PRIMARY KEY -** fields before they are inserted into the data_xxx tables. -** -** USAGE -** -** The API declared below allows an application to apply an RBU update -** stored on disk to an existing target database. Essentially, the -** application: -** -** 1) Opens an RBU handle using the sqlite3rbu_open() function. -** -** 2) Registers any required virtual table modules with the database -** handle returned by sqlite3rbu_db(). Also, if required, register -** the rbu_delta() implementation. -** -** 3) Calls the sqlite3rbu_step() function one or more times on -** the new handle. Each call to sqlite3rbu_step() performs a single -** b-tree operation, so thousands of calls may be required to apply -** a complete update. -** -** 4) Calls sqlite3rbu_close() to close the RBU update handle. If -** sqlite3rbu_step() has been called enough times to completely -** apply the update to the target database, then the RBU database -** is marked as fully applied. Otherwise, the state of the RBU -** update application is saved in the RBU database for later -** resumption. -** -** See comments below for more detail on APIs. -** -** If an update is only partially applied to the target database by the -** time sqlite3rbu_close() is called, various state information is saved -** within the RBU database. This allows subsequent processes to automatically -** resume the RBU update from where it left off. -** -** To remove all RBU extension state information, returning an RBU database -** to its original contents, it is sufficient to drop all tables that begin -** with the prefix "rbu_" -** -** DATABASE LOCKING -** -** An RBU update may not be applied to a database in WAL mode. Attempting -** to do so is an error (SQLITE_ERROR). -** -** While an RBU handle is open, a SHARED lock may be held on the target -** database file. This means it is possible for other clients to read the -** database, but not to write it. -** -** If an RBU update is started and then suspended before it is completed, -** then an external client writes to the database, then attempting to resume -** the suspended RBU update is also an error (SQLITE_BUSY). -*/ - -#ifndef _SQLITE3RBU_H -#define _SQLITE3RBU_H - -/* #include "sqlite3.h" ** Required for error code definitions ** */ - -#if 0 -extern "C" { -#endif - -typedef struct sqlite3rbu sqlite3rbu; - -/* -** Open an RBU handle. -** -** Argument zTarget is the path to the target database. Argument zRbu is -** the path to the RBU database. Each call to this function must be matched -** by a call to sqlite3rbu_close(). When opening the databases, RBU passes -** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget -** or zRbu begin with "file:", it will be interpreted as an SQLite -** database URI, not a regular file name. -** -** If the zState argument is passed a NULL value, the RBU extension stores -** the current state of the update (how many rows have been updated, which -** indexes are yet to be updated etc.) within the RBU database itself. This -** can be convenient, as it means that the RBU application does not need to -** organize removing a separate state file after the update is concluded. -** Or, if zState is non-NULL, it must be a path to a database file in which -** the RBU extension can store the state of the update. -** -** When resuming an RBU update, the zState argument must be passed the same -** value as when the RBU update was started. -** -** Once the RBU update is finished, the RBU extension does not -** automatically remove any zState database file, even if it created it. -** -** By default, RBU uses the default VFS to access the files on disk. To -** use a VFS other than the default, an SQLite "file:" URI containing a -** "vfs=..." option may be passed as the zTarget option. -** -** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of -** SQLite's built-in VFSs, including the multiplexor VFS. However it does -** not work out of the box with zipvfs. Refer to the comment describing -** the zipvfs_create_vfs() API below for details on using RBU with zipvfs. -*/ -SQLITE_API sqlite3rbu *sqlite3rbu_open( - const char *zTarget, - const char *zRbu, - const char *zState -); - -/* -** Open an RBU handle to perform an RBU vacuum on database file zTarget. -** An RBU vacuum is similar to SQLite's built-in VACUUM command, except -** that it can be suspended and resumed like an RBU update. -** -** The second argument to this function identifies a database in which -** to store the state of the RBU vacuum operation if it is suspended. The -** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum -** operation, the state database should either not exist or be empty -** (contain no tables). If an RBU vacuum is suspended by calling -** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has -** returned SQLITE_DONE, the vacuum state is stored in the state database. -** The vacuum can be resumed by calling this function to open a new RBU -** handle specifying the same target and state databases. -** -** If the second argument passed to this function is NULL, then the -** name of the state database is "-vacuum", where -** is the name of the target database file. In this case, on UNIX, if the -** state database is not already present in the file-system, it is created -** with the same permissions as the target db is made. -** -** This function does not delete the state database after an RBU vacuum -** is completed, even if it created it. However, if the call to -** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents -** of the state tables within the state database are zeroed. This way, -** the next call to sqlite3rbu_vacuum() opens a handle that starts a -** new RBU vacuum operation. -** -** As with sqlite3rbu_open(), Zipvfs users should rever to the comment -** describing the sqlite3rbu_create_vfs() API function below for -** a description of the complications associated with using RBU with -** zipvfs databases. -*/ -SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( - const char *zTarget, - const char *zState -); - -/* -** Internally, each RBU connection uses a separate SQLite database -** connection to access the target and rbu update databases. This -** API allows the application direct access to these database handles. -** -** The first argument passed to this function must be a valid, open, RBU -** handle. The second argument should be passed zero to access the target -** database handle, or non-zero to access the rbu update database handle. -** Accessing the underlying database handles may be useful in the -** following scenarios: -** -** * If any target tables are virtual tables, it may be necessary to -** call sqlite3_create_module() on the target database handle to -** register the required virtual table implementations. -** -** * If the data_xxx tables in the RBU source database are virtual -** tables, the application may need to call sqlite3_create_module() on -** the rbu update db handle to any required virtual table -** implementations. -** -** * If the application uses the "rbu_delta()" feature described above, -** it must use sqlite3_create_function() or similar to register the -** rbu_delta() implementation with the target database handle. -** -** If an error has occurred, either while opening or stepping the RBU object, -** this function may return NULL. The error code and message may be collected -** when sqlite3rbu_close() is called. -** -** Database handles returned by this function remain valid until the next -** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db(). -*/ -SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); - -/* -** Do some work towards applying the RBU update to the target db. -** -** Return SQLITE_DONE if the update has been completely applied, or -** SQLITE_OK if no error occurs but there remains work to do to apply -** the RBU update. If an error does occur, some other error code is -** returned. -** -** Once a call to sqlite3rbu_step() has returned a value other than -** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops -** that immediately return the same value. -*/ -SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu); - -/* -** Force RBU to save its state to disk. -** -** If a power failure or application crash occurs during an update, following -** system recovery RBU may resume the update from the point at which the state -** was last saved. In other words, from the most recent successful call to -** sqlite3rbu_close() or this function. -** -** SQLITE_OK is returned if successful, or an SQLite error code otherwise. -*/ -SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); - -/* -** Close an RBU handle. -** -** If the RBU update has been completely applied, mark the RBU database -** as fully applied. Otherwise, assuming no error has occurred, save the -** current state of the RBU update appliation to the RBU database. -** -** If an error has already occurred as part of an sqlite3rbu_step() -** or sqlite3rbu_open() call, or if one occurs within this function, an -** SQLite error code is returned. Additionally, *pzErrmsg may be set to -** point to a buffer containing a utf-8 formatted English language error -** message. It is the responsibility of the caller to eventually free any -** such buffer using sqlite3_free(). -** -** Otherwise, if no error occurs, this function returns SQLITE_OK if the -** update has been partially applied, or SQLITE_DONE if it has been -** completely applied. -*/ -SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); - -/* -** Return the total number of key-value operations (inserts, deletes or -** updates) that have been performed on the target database since the -** current RBU update was started. -*/ -SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); - -/* -** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) -** progress indications for the two stages of an RBU update. This API may -** be useful for driving GUI progress indicators and similar. -** -** An RBU update is divided into two stages: -** -** * Stage 1, in which changes are accumulated in an oal/wal file, and -** * Stage 2, in which the contents of the wal file are copied into the -** main database. -** -** The update is visible to non-RBU clients during stage 2. During stage 1 -** non-RBU reader clients may see the original database. -** -** If this API is called during stage 2 of the update, output variable -** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) -** to a value between 0 and 10000 to indicate the permyriadage progress of -** stage 2. A value of 5000 indicates that stage 2 is half finished, -** 9000 indicates that it is 90% finished, and so on. -** -** If this API is called during stage 1 of the update, output variable -** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The -** value to which (*pnOne) is set depends on whether or not the RBU -** database contains an "rbu_count" table. The rbu_count table, if it -** exists, must contain the same columns as the following: -** -** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; -** -** There must be one row in the table for each source (data_xxx) table within -** the RBU database. The 'tbl' column should contain the name of the source -** table. The 'cnt' column should contain the number of rows within the -** source table. -** -** If the rbu_count table is present and populated correctly and this -** API is called during stage 1, the *pnOne output variable is set to the -** permyriadage progress of the same stage. If the rbu_count table does -** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count -** table exists but is not correctly populated, the value of the *pnOne -** output variable during stage 1 is undefined. -*/ -SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); - -/* -** Obtain an indication as to the current stage of an RBU update or vacuum. -** This function always returns one of the SQLITE_RBU_STATE_XXX constants -** defined in this file. Return values should be interpreted as follows: -** -** SQLITE_RBU_STATE_OAL: -** RBU is currently building a *-oal file. The next call to sqlite3rbu_step() -** may either add further data to the *-oal file, or compute data that will -** be added by a subsequent call. -** -** SQLITE_RBU_STATE_MOVE: -** RBU has finished building the *-oal file. The next call to sqlite3rbu_step() -** will move the *-oal file to the equivalent *-wal path. If the current -** operation is an RBU update, then the updated version of the database -** file will become visible to ordinary SQLite clients following the next -** call to sqlite3rbu_step(). -** -** SQLITE_RBU_STATE_CHECKPOINT: -** RBU is currently performing an incremental checkpoint. The next call to -** sqlite3rbu_step() will copy a page of data from the *-wal file into -** the target database file. -** -** SQLITE_RBU_STATE_DONE: -** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step() -** will immediately return SQLITE_DONE. -** -** SQLITE_RBU_STATE_ERROR: -** An error has occurred. Any subsequent calls to sqlite3rbu_step() will -** immediately return the SQLite error code associated with the error. -*/ -#define SQLITE_RBU_STATE_OAL 1 -#define SQLITE_RBU_STATE_MOVE 2 -#define SQLITE_RBU_STATE_CHECKPOINT 3 -#define SQLITE_RBU_STATE_DONE 4 -#define SQLITE_RBU_STATE_ERROR 5 - -SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); - -/* -** Create an RBU VFS named zName that accesses the underlying file-system -** via existing VFS zParent. Or, if the zParent parameter is passed NULL, -** then the new RBU VFS uses the default system VFS to access the file-system. -** The new object is registered as a non-default VFS with SQLite before -** returning. -** -** Part of the RBU implementation uses a custom VFS object. Usually, this -** object is created and deleted automatically by RBU. -** -** The exception is for applications that also use zipvfs. In this case, -** the custom VFS must be explicitly created by the user before the RBU -** handle is opened. The RBU VFS should be installed so that the zipvfs -** VFS uses the RBU VFS, which in turn uses any other VFS layers in use -** (for example multiplexor) to access the file-system. For example, -** to assemble an RBU enabled VFS stack that uses both zipvfs and -** multiplexor (error checking omitted): -** -** // Create a VFS named "multiplex" (not the default). -** sqlite3_multiplex_initialize(0, 0); -** -** // Create an rbu VFS named "rbu" that uses multiplexor. If the -** // second argument were replaced with NULL, the "rbu" VFS would -** // access the file-system via the system default VFS, bypassing the -** // multiplexor. -** sqlite3rbu_create_vfs("rbu", "multiplex"); -** -** // Create a zipvfs VFS named "zipvfs" that uses rbu. -** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector); -** -** // Make zipvfs the default VFS. -** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1); -** -** Because the default VFS created above includes a RBU functionality, it -** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack -** that does not include the RBU layer results in an error. -** -** The overhead of adding the "rbu" VFS to the system is negligible for -** non-RBU users. There is no harm in an application accessing the -** file-system via "rbu" all the time, even if it only uses RBU functionality -** occasionally. -*/ -SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent); - -/* -** Deregister and destroy an RBU vfs created by an earlier call to -** sqlite3rbu_create_vfs(). -** -** VFS objects are not reference counted. If a VFS object is destroyed -** before all database handles that use it have been closed, the results -** are undefined. -*/ -SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName); - -#if 0 -} /* end of the 'extern "C"' block */ -#endif - -#endif /* _SQLITE3RBU_H */ - -/************** End of sqlite3rbu.h ******************************************/ -/************** Continuing where we left off in sqlite3rbu.c *****************/ - -#if defined(_WIN32_WCE) -/* #include "windows.h" */ -#endif - -/* Maximum number of prepared UPDATE statements held by this module */ -#define SQLITE_RBU_UPDATE_CACHESIZE 16 - -/* -** Swap two objects of type TYPE. -*/ -#if !defined(SQLITE_AMALGAMATION) -# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} -#endif - -/* -** The rbu_state table is used to save the state of a partially applied -** update so that it can be resumed later. The table consists of integer -** keys mapped to values as follows: -** -** RBU_STATE_STAGE: -** May be set to integer values 1, 2, 4 or 5. As follows: -** 1: the *-rbu file is currently under construction. -** 2: the *-rbu file has been constructed, but not yet moved -** to the *-wal path. -** 4: the checkpoint is underway. -** 5: the rbu update has been checkpointed. -** -** RBU_STATE_TBL: -** Only valid if STAGE==1. The target database name of the table -** currently being written. -** -** RBU_STATE_IDX: -** Only valid if STAGE==1. The target database name of the index -** currently being written, or NULL if the main table is currently being -** updated. -** -** RBU_STATE_ROW: -** Only valid if STAGE==1. Number of rows already processed for the current -** table/index. -** -** RBU_STATE_PROGRESS: -** Trbul number of sqlite3rbu_step() calls made so far as part of this -** rbu update. -** -** RBU_STATE_CKPT: -** Valid if STAGE==4. The 64-bit checksum associated with the wal-index -** header created by recovering the *-wal file. This is used to detect -** cases when another client appends frames to the *-wal file in the -** middle of an incremental checkpoint (an incremental checkpoint cannot -** be continued if this happens). -** -** RBU_STATE_COOKIE: -** Valid if STAGE==1. The current change-counter cookie value in the -** target db file. -** -** RBU_STATE_OALSZ: -** Valid if STAGE==1. The size in bytes of the *-oal file. -*/ -#define RBU_STATE_STAGE 1 -#define RBU_STATE_TBL 2 -#define RBU_STATE_IDX 3 -#define RBU_STATE_ROW 4 -#define RBU_STATE_PROGRESS 5 -#define RBU_STATE_CKPT 6 -#define RBU_STATE_COOKIE 7 -#define RBU_STATE_OALSZ 8 -#define RBU_STATE_PHASEONESTEP 9 - -#define RBU_STAGE_OAL 1 -#define RBU_STAGE_MOVE 2 -#define RBU_STAGE_CAPTURE 3 -#define RBU_STAGE_CKPT 4 -#define RBU_STAGE_DONE 5 - - -#define RBU_CREATE_STATE \ - "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" - -typedef struct RbuFrame RbuFrame; -typedef struct RbuObjIter RbuObjIter; -typedef struct RbuState RbuState; -typedef struct rbu_vfs rbu_vfs; -typedef struct rbu_file rbu_file; -typedef struct RbuUpdateStmt RbuUpdateStmt; - -#if !defined(SQLITE_AMALGAMATION) -typedef unsigned int u32; -typedef unsigned short u16; -typedef unsigned char u8; -typedef sqlite3_int64 i64; -#endif - -/* -** These values must match the values defined in wal.c for the equivalent -** locks. These are not magic numbers as they are part of the SQLite file -** format. -*/ -#define WAL_LOCK_WRITE 0 -#define WAL_LOCK_CKPT 1 -#define WAL_LOCK_READ0 3 - -#define SQLITE_FCNTL_RBUCNT 5149216 - -/* -** A structure to store values read from the rbu_state table in memory. -*/ -struct RbuState { - int eStage; - char *zTbl; - char *zIdx; - i64 iWalCksum; - int nRow; - i64 nProgress; - u32 iCookie; - i64 iOalSz; - i64 nPhaseOneStep; -}; - -struct RbuUpdateStmt { - char *zMask; /* Copy of update mask used with pUpdate */ - sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ - RbuUpdateStmt *pNext; -}; - -/* -** An iterator of this type is used to iterate through all objects in -** the target database that require updating. For each such table, the -** iterator visits, in order: -** -** * the table itself, -** * each index of the table (zero or more points to visit), and -** * a special "cleanup table" state. -** -** abIndexed: -** If the table has no indexes on it, abIndexed is set to NULL. Otherwise, -** it points to an array of flags nTblCol elements in size. The flag is -** set for each column that is either a part of the PK or a part of an -** index. Or clear otherwise. -** -*/ -struct RbuObjIter { - sqlite3_stmt *pTblIter; /* Iterate through tables */ - sqlite3_stmt *pIdxIter; /* Index iterator */ - int nTblCol; /* Size of azTblCol[] array */ - char **azTblCol; /* Array of unquoted target column names */ - char **azTblType; /* Array of target column types */ - int *aiSrcOrder; /* src table col -> target table col */ - u8 *abTblPk; /* Array of flags, set on target PK columns */ - u8 *abNotNull; /* Array of flags, set on NOT NULL columns */ - u8 *abIndexed; /* Array of flags, set on indexed & PK cols */ - int eType; /* Table type - an RBU_PK_XXX value */ - - /* Output variables. zTbl==0 implies EOF. */ - int bCleanup; /* True in "cleanup" state */ - const char *zTbl; /* Name of target db table */ - const char *zDataTbl; /* Name of rbu db table (or null) */ - const char *zIdx; /* Name of target db index (or null) */ - int iTnum; /* Root page of current object */ - int iPkTnum; /* If eType==EXTERNAL, root of PK index */ - int bUnique; /* Current index is unique */ - int nIndex; /* Number of aux. indexes on table zTbl */ - - /* Statements created by rbuObjIterPrepareAll() */ - int nCol; /* Number of columns in current object */ - sqlite3_stmt *pSelect; /* Source data */ - sqlite3_stmt *pInsert; /* Statement for INSERT operations */ - sqlite3_stmt *pDelete; /* Statement for DELETE ops */ - sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ - - /* Last UPDATE used (for PK b-tree updates only), or NULL. */ - RbuUpdateStmt *pRbuUpdate; -}; - -/* -** Values for RbuObjIter.eType -** -** 0: Table does not exist (error) -** 1: Table has an implicit rowid. -** 2: Table has an explicit IPK column. -** 3: Table has an external PK index. -** 4: Table is WITHOUT ROWID. -** 5: Table is a virtual table. -*/ -#define RBU_PK_NOTABLE 0 -#define RBU_PK_NONE 1 -#define RBU_PK_IPK 2 -#define RBU_PK_EXTERNAL 3 -#define RBU_PK_WITHOUT_ROWID 4 -#define RBU_PK_VTAB 5 - - -/* -** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs -** one of the following operations. -*/ -#define RBU_INSERT 1 /* Insert on a main table b-tree */ -#define RBU_DELETE 2 /* Delete a row from a main table b-tree */ -#define RBU_REPLACE 3 /* Delete and then insert a row */ -#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */ -#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */ - -#define RBU_UPDATE 6 /* Update a row in a main table b-tree */ - -/* -** A single step of an incremental checkpoint - frame iWalFrame of the wal -** file should be copied to page iDbPage of the database file. -*/ -struct RbuFrame { - u32 iDbPage; - u32 iWalFrame; -}; - -/* -** RBU handle. -** -** nPhaseOneStep: -** If the RBU database contains an rbu_count table, this value is set to -** a running estimate of the number of b-tree operations required to -** finish populating the *-oal file. This allows the sqlite3_bp_progress() -** API to calculate the permyriadage progress of populating the *-oal file -** using the formula: -** -** permyriadage = (10000 * nProgress) / nPhaseOneStep -** -** nPhaseOneStep is initialized to the sum of: -** -** nRow * (nIndex + 1) -** -** for all source tables in the RBU database, where nRow is the number -** of rows in the source table and nIndex the number of indexes on the -** corresponding target database table. -** -** This estimate is accurate if the RBU update consists entirely of -** INSERT operations. However, it is inaccurate if: -** -** * the RBU update contains any UPDATE operations. If the PK specified -** for an UPDATE operation does not exist in the target table, then -** no b-tree operations are required on index b-trees. Or if the -** specified PK does exist, then (nIndex*2) such operations are -** required (one delete and one insert on each index b-tree). -** -** * the RBU update contains any DELETE operations for which the specified -** PK does not exist. In this case no operations are required on index -** b-trees. -** -** * the RBU update contains REPLACE operations. These are similar to -** UPDATE operations. -** -** nPhaseOneStep is updated to account for the conditions above during the -** first pass of each source table. The updated nPhaseOneStep value is -** stored in the rbu_state table if the RBU update is suspended. -*/ -struct sqlite3rbu { - int eStage; /* Value of RBU_STATE_STAGE field */ - sqlite3 *dbMain; /* target database handle */ - sqlite3 *dbRbu; /* rbu database handle */ - char *zTarget; /* Path to target db */ - char *zRbu; /* Path to rbu db */ - char *zState; /* Path to state db (or NULL if zRbu) */ - char zStateDb[5]; /* Db name for state ("stat" or "main") */ - int rc; /* Value returned by last rbu_step() call */ - char *zErrmsg; /* Error message if rc!=SQLITE_OK */ - int nStep; /* Rows processed for current object */ - int nProgress; /* Rows processed for all objects */ - RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ - const char *zVfsName; /* Name of automatically created rbu vfs */ - rbu_file *pTargetFd; /* File handle open on target db */ - i64 iOalSz; - i64 nPhaseOneStep; - - /* The following state variables are used as part of the incremental - ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding - ** function rbuSetupCheckpoint() for details. */ - u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ - u32 mLock; - int nFrame; /* Entries in aFrame[] array */ - int nFrameAlloc; /* Allocated size of aFrame[] array */ - RbuFrame *aFrame; - int pgsz; - u8 *aBuf; - i64 iWalCksum; - - /* Used in RBU vacuum mode only */ - int nRbu; /* Number of RBU VFS in the stack */ - rbu_file *pRbuFd; /* Fd for main db of dbRbu */ -}; - -/* -** An rbu VFS is implemented using an instance of this structure. -*/ -struct rbu_vfs { - sqlite3_vfs base; /* rbu VFS shim methods */ - sqlite3_vfs *pRealVfs; /* Underlying VFS */ - sqlite3_mutex *mutex; /* Mutex to protect pMain */ - rbu_file *pMain; /* Linked list of main db files */ -}; - -/* -** Each file opened by an rbu VFS is represented by an instance of -** the following structure. -*/ -struct rbu_file { - sqlite3_file base; /* sqlite3_file methods */ - sqlite3_file *pReal; /* Underlying file handle */ - rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ - sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ - - int openFlags; /* Flags this file was opened with */ - u32 iCookie; /* Cookie value for main db files */ - u8 iWriteVer; /* "write-version" value for main db files */ - u8 bNolock; /* True to fail EXCLUSIVE locks */ - - int nShm; /* Number of entries in apShm[] array */ - char **apShm; /* Array of mmap'd *-shm regions */ - char *zDel; /* Delete this when closing file */ - - const char *zWal; /* Wal filename for this main db file */ - rbu_file *pWalFd; /* Wal file descriptor for this main db */ - rbu_file *pMainNext; /* Next MAIN_DB file */ -}; - -/* -** True for an RBU vacuum handle, or false otherwise. -*/ -#define rbuIsVacuum(p) ((p)->zTarget==0) - - -/************************************************************************* -** The following three functions, found below: -** -** rbuDeltaGetInt() -** rbuDeltaChecksum() -** rbuDeltaApply() -** -** are lifted from the fossil source code (http://fossil-scm.org). They -** are used to implement the scalar SQL function rbu_fossil_delta(). -*/ - -/* -** Read bytes from *pz and convert them into a positive integer. When -** finished, leave *pz pointing to the first character past the end of -** the integer. The *pLen parameter holds the length of the string -** in *pz and is decremented once for each character in the integer. -*/ -static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ - static const signed char zValue[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 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, -1, -1, -1, -1, 36, - -1, 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, -1, -1, -1, 63, -1, - }; - unsigned int v = 0; - int c; - unsigned char *z = (unsigned char*)*pz; - unsigned char *zStart = z; - while( (c = zValue[0x7f&*(z++)])>=0 ){ - v = (v<<6) + c; - } - z--; - *pLen -= z - zStart; - *pz = (char*)z; - return v; -} - -/* -** Compute a 32-bit checksum on the N-byte buffer. Return the result. -*/ -static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){ - const unsigned char *z = (const unsigned char *)zIn; - unsigned sum0 = 0; - unsigned sum1 = 0; - unsigned sum2 = 0; - unsigned sum3 = 0; - while(N >= 16){ - sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); - sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); - sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); - sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]); - z += 16; - N -= 16; - } - while(N >= 4){ - sum0 += z[0]; - sum1 += z[1]; - sum2 += z[2]; - sum3 += z[3]; - z += 4; - N -= 4; - } - sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); - switch(N){ - case 3: sum3 += (z[2] << 8); - case 2: sum3 += (z[1] << 16); - case 1: sum3 += (z[0] << 24); - default: ; - } - return sum3; -} - -/* -** Apply a delta. -** -** The output buffer should be big enough to hold the whole output -** file and a NUL terminator at the end. The delta_output_size() -** routine will determine this size for you. -** -** The delta string should be null-terminated. But the delta string -** may contain embedded NUL characters (if the input and output are -** binary files) so we also have to pass in the length of the delta in -** the lenDelta parameter. -** -** This function returns the size of the output file in bytes (excluding -** the final NUL terminator character). Except, if the delta string is -** malformed or intended for use with a source file other than zSrc, -** then this routine returns -1. -** -** Refer to the delta_create() documentation above for a description -** of the delta file format. -*/ -static int rbuDeltaApply( - const char *zSrc, /* The source or pattern file */ - int lenSrc, /* Length of the source file */ - const char *zDelta, /* Delta to apply to the pattern */ - int lenDelta, /* Length of the delta */ - char *zOut /* Write the output into this preallocated buffer */ -){ - unsigned int limit; - unsigned int total = 0; -#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST - char *zOrigOut = zOut; -#endif - - limit = rbuDeltaGetInt(&zDelta, &lenDelta); - if( *zDelta!='\n' ){ - /* ERROR: size integer not terminated by "\n" */ - return -1; - } - zDelta++; lenDelta--; - while( *zDelta && lenDelta>0 ){ - unsigned int cnt, ofst; - cnt = rbuDeltaGetInt(&zDelta, &lenDelta); - switch( zDelta[0] ){ - case '@': { - zDelta++; lenDelta--; - ofst = rbuDeltaGetInt(&zDelta, &lenDelta); - if( lenDelta>0 && zDelta[0]!=',' ){ - /* ERROR: copy command not terminated by ',' */ - return -1; - } - zDelta++; lenDelta--; - total += cnt; - if( total>limit ){ - /* ERROR: copy exceeds output file size */ - return -1; - } - if( (int)(ofst+cnt) > lenSrc ){ - /* ERROR: copy extends past end of input */ - return -1; - } - memcpy(zOut, &zSrc[ofst], cnt); - zOut += cnt; - break; - } - case ':': { - zDelta++; lenDelta--; - total += cnt; - if( total>limit ){ - /* ERROR: insert command gives an output larger than predicted */ - return -1; - } - if( (int)cnt>lenDelta ){ - /* ERROR: insert count exceeds size of delta */ - return -1; - } - memcpy(zOut, zDelta, cnt); - zOut += cnt; - zDelta += cnt; - lenDelta -= cnt; - break; - } - case ';': { - zDelta++; lenDelta--; - zOut[0] = 0; -#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST - if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){ - /* ERROR: bad checksum */ - return -1; - } -#endif - if( total!=limit ){ - /* ERROR: generated size does not match predicted size */ - return -1; - } - return total; - } - default: { - /* ERROR: unknown delta operator */ - return -1; - } - } - } - /* ERROR: unterminated delta */ - return -1; -} - -static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ - int size; - size = rbuDeltaGetInt(&zDelta, &lenDelta); - if( *zDelta!='\n' ){ - /* ERROR: size integer not terminated by "\n" */ - return -1; - } - return size; -} - -/* -** End of code taken from fossil. -*************************************************************************/ - -/* -** Implementation of SQL scalar function rbu_fossil_delta(). -** -** This function applies a fossil delta patch to a blob. Exactly two -** arguments must be passed to this function. The first is the blob to -** patch and the second the patch to apply. If no error occurs, this -** function returns the patched blob. -*/ -static void rbuFossilDeltaFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - const char *aDelta; - int nDelta; - const char *aOrig; - int nOrig; - - int nOut; - int nOut2; - char *aOut; - - assert( argc==2 ); - - nOrig = sqlite3_value_bytes(argv[0]); - aOrig = (const char*)sqlite3_value_blob(argv[0]); - nDelta = sqlite3_value_bytes(argv[1]); - aDelta = (const char*)sqlite3_value_blob(argv[1]); - - /* Figure out the size of the output */ - nOut = rbuDeltaOutputSize(aDelta, nDelta); - if( nOut<0 ){ - sqlite3_result_error(context, "corrupt fossil delta", -1); - return; - } - - aOut = sqlite3_malloc(nOut+1); - if( aOut==0 ){ - sqlite3_result_error_nomem(context); - }else{ - nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut); - if( nOut2!=nOut ){ - sqlite3_result_error(context, "corrupt fossil delta", -1); - }else{ - sqlite3_result_blob(context, aOut, nOut, sqlite3_free); - } - } -} - - -/* -** Prepare the SQL statement in buffer zSql against database handle db. -** If successful, set *ppStmt to point to the new statement and return -** SQLITE_OK. -** -** Otherwise, if an error does occur, set *ppStmt to NULL and return -** an SQLite error code. Additionally, set output variable *pzErrmsg to -** point to a buffer containing an error message. It is the responsibility -** of the caller to (eventually) free this buffer using sqlite3_free(). -*/ -static int prepareAndCollectError( - sqlite3 *db, - sqlite3_stmt **ppStmt, - char **pzErrmsg, - const char *zSql -){ - int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); - if( rc!=SQLITE_OK ){ - *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - *ppStmt = 0; - } - return rc; -} - -/* -** Reset the SQL statement passed as the first argument. Return a copy -** of the value returned by sqlite3_reset(). -** -** If an error has occurred, then set *pzErrmsg to point to a buffer -** containing an error message. It is the responsibility of the caller -** to eventually free this buffer using sqlite3_free(). -*/ -static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){ - int rc = sqlite3_reset(pStmt); - if( rc!=SQLITE_OK ){ - *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt))); - } - return rc; -} - -/* -** Unless it is NULL, argument zSql points to a buffer allocated using -** sqlite3_malloc containing an SQL statement. This function prepares the SQL -** statement against database db and frees the buffer. If statement -** compilation is successful, *ppStmt is set to point to the new statement -** handle and SQLITE_OK is returned. -** -** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code -** returned. In this case, *pzErrmsg may also be set to point to an error -** message. It is the responsibility of the caller to free this error message -** buffer using sqlite3_free(). -** -** If argument zSql is NULL, this function assumes that an OOM has occurred. -** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL. -*/ -static int prepareFreeAndCollectError( - sqlite3 *db, - sqlite3_stmt **ppStmt, - char **pzErrmsg, - char *zSql -){ - int rc; - assert( *pzErrmsg==0 ); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - *ppStmt = 0; - }else{ - rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); - sqlite3_free(zSql); - } - return rc; -} - -/* -** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated -** by an earlier call to rbuObjIterCacheTableInfo(). -*/ -static void rbuObjIterFreeCols(RbuObjIter *pIter){ - int i; - for(i=0; inTblCol; i++){ - sqlite3_free(pIter->azTblCol[i]); - sqlite3_free(pIter->azTblType[i]); - } - sqlite3_free(pIter->azTblCol); - pIter->azTblCol = 0; - pIter->azTblType = 0; - pIter->aiSrcOrder = 0; - pIter->abTblPk = 0; - pIter->abNotNull = 0; - pIter->nTblCol = 0; - pIter->eType = 0; /* Invalid value */ -} - -/* -** Finalize all statements and free all allocations that are specific to -** the current object (table/index pair). -*/ -static void rbuObjIterClearStatements(RbuObjIter *pIter){ - RbuUpdateStmt *pUp; - - sqlite3_finalize(pIter->pSelect); - sqlite3_finalize(pIter->pInsert); - sqlite3_finalize(pIter->pDelete); - sqlite3_finalize(pIter->pTmpInsert); - pUp = pIter->pRbuUpdate; - while( pUp ){ - RbuUpdateStmt *pTmp = pUp->pNext; - sqlite3_finalize(pUp->pUpdate); - sqlite3_free(pUp); - pUp = pTmp; - } - - pIter->pSelect = 0; - pIter->pInsert = 0; - pIter->pDelete = 0; - pIter->pRbuUpdate = 0; - pIter->pTmpInsert = 0; - pIter->nCol = 0; -} - -/* -** Clean up any resources allocated as part of the iterator object passed -** as the only argument. -*/ -static void rbuObjIterFinalize(RbuObjIter *pIter){ - rbuObjIterClearStatements(pIter); - sqlite3_finalize(pIter->pTblIter); - sqlite3_finalize(pIter->pIdxIter); - rbuObjIterFreeCols(pIter); - memset(pIter, 0, sizeof(RbuObjIter)); -} - -/* -** Advance the iterator to the next position. -** -** If no error occurs, SQLITE_OK is returned and the iterator is left -** pointing to the next entry. Otherwise, an error code and message is -** left in the RBU handle passed as the first argument. A copy of the -** error code is returned. -*/ -static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ - int rc = p->rc; - if( rc==SQLITE_OK ){ - - /* Free any SQLite statements used while processing the previous object */ - rbuObjIterClearStatements(pIter); - if( pIter->zIdx==0 ){ - rc = sqlite3_exec(p->dbMain, - "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;" - "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;" - "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;" - "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;" - , 0, 0, &p->zErrmsg - ); - } - - if( rc==SQLITE_OK ){ - if( pIter->bCleanup ){ - rbuObjIterFreeCols(pIter); - pIter->bCleanup = 0; - rc = sqlite3_step(pIter->pTblIter); - if( rc!=SQLITE_ROW ){ - rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); - pIter->zTbl = 0; - }else{ - pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); - pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); - rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM; - } - }else{ - if( pIter->zIdx==0 ){ - sqlite3_stmt *pIdx = pIter->pIdxIter; - rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); - } - if( rc==SQLITE_OK ){ - rc = sqlite3_step(pIter->pIdxIter); - if( rc!=SQLITE_ROW ){ - rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg); - pIter->bCleanup = 1; - pIter->zIdx = 0; - }else{ - pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0); - pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1); - pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2); - rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM; - } - } - } - } - } - - if( rc!=SQLITE_OK ){ - rbuObjIterFinalize(pIter); - p->rc = rc; - } - return rc; -} - - -/* -** The implementation of the rbu_target_name() SQL function. This function -** accepts one or two arguments. The first argument is the name of a table - -** the name of a table in the RBU database. The second, if it is present, is 1 -** for a view or 0 for a table. -** -** For a non-vacuum RBU handle, if the table name matches the pattern: -** -** data[0-9]_ -** -** where is any sequence of 1 or more characters, is returned. -** Otherwise, if the only argument does not match the above pattern, an SQL -** NULL is returned. -** -** "data_t1" -> "t1" -** "data0123_t2" -> "t2" -** "dataAB_t3" -> NULL -** -** For an rbu vacuum handle, a copy of the first argument is returned if -** the second argument is either missing or 0 (not a view). -*/ -static void rbuTargetNameFunc( - sqlite3_context *pCtx, - int argc, - sqlite3_value **argv -){ - sqlite3rbu *p = sqlite3_user_data(pCtx); - const char *zIn; - assert( argc==1 || argc==2 ); - - zIn = (const char*)sqlite3_value_text(argv[0]); - if( zIn ){ - if( rbuIsVacuum(p) ){ - if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ - sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); - } - }else{ - if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ - int i; - for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); - if( zIn[i]=='_' && zIn[i+1] ){ - sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); - } - } - } - } -} - -/* -** Initialize the iterator structure passed as the second argument. -** -** If no error occurs, SQLITE_OK is returned and the iterator is left -** pointing to the first entry. Otherwise, an error code and message is -** left in the RBU handle passed as the first argument. A copy of the -** error code is returned. -*/ -static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ - int rc; - memset(pIter, 0, sizeof(RbuObjIter)); - - rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, - sqlite3_mprintf( - "SELECT rbu_target_name(name, type='view') AS target, name " - "FROM sqlite_master " - "WHERE type IN ('table', 'view') AND target IS NOT NULL " - " %s " - "ORDER BY name" - , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : "")); - - if( rc==SQLITE_OK ){ - rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, - "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' " - " FROM main.sqlite_master " - " WHERE type='index' AND tbl_name = ?" - ); - } - - pIter->bCleanup = 1; - p->rc = rc; - return rbuObjIterNext(p, pIter); -} - -/* -** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, -** an error code is stored in the RBU handle passed as the first argument. -** -** If an error has already occurred (p->rc is already set to something other -** than SQLITE_OK), then this function returns NULL without modifying the -** stored error code. In this case it still calls sqlite3_free() on any -** printf() parameters associated with %z conversions. -*/ -static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){ - char *zSql = 0; - va_list ap; - va_start(ap, zFmt); - zSql = sqlite3_vmprintf(zFmt, ap); - if( p->rc==SQLITE_OK ){ - if( zSql==0 ) p->rc = SQLITE_NOMEM; - }else{ - sqlite3_free(zSql); - zSql = 0; - } - va_end(ap); - return zSql; -} - -/* -** Argument zFmt is a sqlite3_mprintf() style format string. The trailing -** arguments are the usual subsitution values. This function performs -** the printf() style substitutions and executes the result as an SQL -** statement on the RBU handles database. -** -** If an error occurs, an error code and error message is stored in the -** RBU handle. If an error has already occurred when this function is -** called, it is a no-op. -*/ -static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){ - va_list ap; - char *zSql; - va_start(ap, zFmt); - zSql = sqlite3_vmprintf(zFmt, ap); - if( p->rc==SQLITE_OK ){ - if( zSql==0 ){ - p->rc = SQLITE_NOMEM; - }else{ - p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); - } - } - sqlite3_free(zSql); - va_end(ap); - return p->rc; -} - -/* -** Attempt to allocate and return a pointer to a zeroed block of nByte -** bytes. -** -** If an error (i.e. an OOM condition) occurs, return NULL and leave an -** error code in the rbu handle passed as the first argument. Or, if an -** error has already occurred when this function is called, return NULL -** immediately without attempting the allocation or modifying the stored -** error code. -*/ -static void *rbuMalloc(sqlite3rbu *p, int nByte){ - void *pRet = 0; - if( p->rc==SQLITE_OK ){ - assert( nByte>0 ); - pRet = sqlite3_malloc64(nByte); - if( pRet==0 ){ - p->rc = SQLITE_NOMEM; - }else{ - memset(pRet, 0, nByte); - } - } - return pRet; -} - - -/* -** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that -** there is room for at least nCol elements. If an OOM occurs, store an -** error code in the RBU handle passed as the first argument. -*/ -static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){ - int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; - char **azNew; - - azNew = (char**)rbuMalloc(p, nByte); - if( azNew ){ - pIter->azTblCol = azNew; - pIter->azTblType = &azNew[nCol]; - pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol]; - pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol]; - pIter->abNotNull = (u8*)&pIter->abTblPk[nCol]; - pIter->abIndexed = (u8*)&pIter->abNotNull[nCol]; - } -} - -/* -** The first argument must be a nul-terminated string. This function -** returns a copy of the string in memory obtained from sqlite3_malloc(). -** It is the responsibility of the caller to eventually free this memory -** using sqlite3_free(). -** -** If an OOM condition is encountered when attempting to allocate memory, -** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, -** if the allocation succeeds, (*pRc) is left unchanged. -*/ -static char *rbuStrndup(const char *zStr, int *pRc){ - char *zRet = 0; - - assert( *pRc==SQLITE_OK ); - if( zStr ){ - size_t nCopy = strlen(zStr) + 1; - zRet = (char*)sqlite3_malloc64(nCopy); - if( zRet ){ - memcpy(zRet, zStr, nCopy); - }else{ - *pRc = SQLITE_NOMEM; - } - } - - return zRet; -} - -/* -** Finalize the statement passed as the second argument. -** -** If the sqlite3_finalize() call indicates that an error occurs, and the -** rbu handle error code is not already set, set the error code and error -** message accordingly. -*/ -static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){ - sqlite3 *db = sqlite3_db_handle(pStmt); - int rc = sqlite3_finalize(pStmt); - if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ - p->rc = rc; - p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - } -} - -/* Determine the type of a table. -** -** peType is of type (int*), a pointer to an output parameter of type -** (int). This call sets the output parameter as follows, depending -** on the type of the table specified by parameters dbName and zTbl. -** -** RBU_PK_NOTABLE: No such table. -** RBU_PK_NONE: Table has an implicit rowid. -** RBU_PK_IPK: Table has an explicit IPK column. -** RBU_PK_EXTERNAL: Table has an external PK index. -** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID. -** RBU_PK_VTAB: Table is a virtual table. -** -** Argument *piPk is also of type (int*), and also points to an output -** parameter. Unless the table has an external primary key index -** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or, -** if the table does have an external primary key index, then *piPk -** is set to the root page number of the primary key index before -** returning. -** -** ALGORITHM: -** -** if( no entry exists in sqlite_master ){ -** return RBU_PK_NOTABLE -** }else if( sql for the entry starts with "CREATE VIRTUAL" ){ -** return RBU_PK_VTAB -** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){ -** if( the index that is the pk exists in sqlite_master ){ -** *piPK = rootpage of that index. -** return RBU_PK_EXTERNAL -** }else{ -** return RBU_PK_WITHOUT_ROWID -** } -** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){ -** return RBU_PK_IPK -** }else{ -** return RBU_PK_NONE -** } -*/ -static void rbuTableType( - sqlite3rbu *p, - const char *zTab, - int *peType, - int *piTnum, - int *piPk -){ - /* - ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q) - ** 1) PRAGMA index_list = ? - ** 2) SELECT count(*) FROM sqlite_master where name=%Q - ** 3) PRAGMA table_info = ? - */ - sqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; - - *peType = RBU_PK_NOTABLE; - *piPk = 0; - - assert( p->rc==SQLITE_OK ); - p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, - sqlite3_mprintf( - "SELECT (sql LIKE 'create virtual%%'), rootpage" - " FROM sqlite_master" - " WHERE name=%Q", zTab - )); - if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){ - /* Either an error, or no such table. */ - goto rbuTableType_end; - } - if( sqlite3_column_int(aStmt[0], 0) ){ - *peType = RBU_PK_VTAB; /* virtual table */ - goto rbuTableType_end; - } - *piTnum = sqlite3_column_int(aStmt[0], 1); - - p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, - sqlite3_mprintf("PRAGMA index_list=%Q",zTab) - ); - if( p->rc ) goto rbuTableType_end; - while( sqlite3_step(aStmt[1])==SQLITE_ROW ){ - const u8 *zOrig = sqlite3_column_text(aStmt[1], 3); - const u8 *zIdx = sqlite3_column_text(aStmt[1], 1); - if( zOrig && zIdx && zOrig[0]=='p' ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, - sqlite3_mprintf( - "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx - )); - if( p->rc==SQLITE_OK ){ - if( sqlite3_step(aStmt[2])==SQLITE_ROW ){ - *piPk = sqlite3_column_int(aStmt[2], 0); - *peType = RBU_PK_EXTERNAL; - }else{ - *peType = RBU_PK_WITHOUT_ROWID; - } - } - goto rbuTableType_end; - } - } - - p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, - sqlite3_mprintf("PRAGMA table_info=%Q",zTab) - ); - if( p->rc==SQLITE_OK ){ - while( sqlite3_step(aStmt[3])==SQLITE_ROW ){ - if( sqlite3_column_int(aStmt[3],5)>0 ){ - *peType = RBU_PK_IPK; /* explicit IPK column */ - goto rbuTableType_end; - } - } - *peType = RBU_PK_NONE; - } - -rbuTableType_end: { - unsigned int i; - for(i=0; iabIndexed[] array. -*/ -static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ - sqlite3_stmt *pList = 0; - int bIndex = 0; - - if( p->rc==SQLITE_OK ){ - memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); - p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) - ); - } - - pIter->nIndex = 0; - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ - const char *zIdx = (const char*)sqlite3_column_text(pList, 1); - sqlite3_stmt *pXInfo = 0; - if( zIdx==0 ) break; - p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) - ); - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ - int iCid = sqlite3_column_int(pXInfo, 1); - if( iCid>=0 ) pIter->abIndexed[iCid] = 1; - } - rbuFinalize(p, pXInfo); - bIndex = 1; - pIter->nIndex++; - } - - if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ - /* "PRAGMA index_list" includes the main PK b-tree */ - pIter->nIndex--; - } - - rbuFinalize(p, pList); - if( bIndex==0 ) pIter->abIndexed = 0; -} - - -/* -** If they are not already populated, populate the pIter->azTblCol[], -** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to -** the table (not index) that the iterator currently points to. -** -** Return SQLITE_OK if successful, or an SQLite error code otherwise. If -** an error does occur, an error code and error message are also left in -** the RBU handle. -*/ -static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ - if( pIter->azTblCol==0 ){ - sqlite3_stmt *pStmt = 0; - int nCol = 0; - int i; /* for() loop iterator variable */ - int bRbuRowid = 0; /* If input table has column "rbu_rowid" */ - int iOrder = 0; - int iTnum = 0; - - /* Figure out the type of table this step will deal with. */ - assert( pIter->eType==0 ); - rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum); - if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl); - } - if( p->rc ) return p->rc; - if( pIter->zIdx==0 ) pIter->iTnum = iTnum; - - assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK - || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID - || pIter->eType==RBU_PK_VTAB - ); - - /* Populate the azTblCol[] and nTblCol variables based on the columns - ** of the input table. Ignore any input table columns that begin with - ** "rbu_". */ - p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, - sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl) - ); - if( p->rc==SQLITE_OK ){ - nCol = sqlite3_column_count(pStmt); - rbuAllocateIterArrays(p, pIter, nCol); - } - for(i=0; p->rc==SQLITE_OK && irc); - pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol; - pIter->azTblCol[pIter->nTblCol++] = zCopy; - } - else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ - bRbuRowid = 1; - } - } - sqlite3_finalize(pStmt); - pStmt = 0; - - if( p->rc==SQLITE_OK - && rbuIsVacuum(p)==0 - && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) - ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf( - "table %q %s rbu_rowid column", pIter->zDataTbl, - (bRbuRowid ? "may not have" : "requires") - ); - } - - /* Check that all non-HIDDEN columns in the destination table are also - ** present in the input table. Populate the abTblPk[], azTblType[] and - ** aiTblOrder[] arrays at the same time. */ - if( p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, - sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) - ); - } - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - const char *zName = (const char*)sqlite3_column_text(pStmt, 1); - if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ - for(i=iOrder; inTblCol; i++){ - if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; - } - if( i==pIter->nTblCol ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("column missing from %q: %s", - pIter->zDataTbl, zName - ); - }else{ - int iPk = sqlite3_column_int(pStmt, 5); - int bNotNull = sqlite3_column_int(pStmt, 3); - const char *zType = (const char*)sqlite3_column_text(pStmt, 2); - - if( i!=iOrder ){ - SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); - SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]); - } - - pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); - pIter->abTblPk[iOrder] = (iPk!=0); - pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); - iOrder++; - } - } - - rbuFinalize(p, pStmt); - rbuObjIterCacheIndexedCols(p, pIter); - assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); - assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); - } - - return p->rc; -} - -/* -** This function constructs and returns a pointer to a nul-terminated -** string containing some SQL clause or list based on one or more of the -** column names currently stored in the pIter->azTblCol[] array. -*/ -static char *rbuObjIterGetCollist( - sqlite3rbu *p, /* RBU object */ - RbuObjIter *pIter /* Object iterator for column names */ -){ - char *zList = 0; - const char *zSep = ""; - int i; - for(i=0; inTblCol; i++){ - const char *z = pIter->azTblCol[i]; - zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z); - zSep = ", "; - } - return zList; -} - -/* -** This function is used to create a SELECT list (the list of SQL -** expressions that follows a SELECT keyword) for a SELECT statement -** used to read from an data_xxx or rbu_tmp_xxx table while updating the -** index object currently indicated by the iterator object passed as the -** second argument. A "PRAGMA index_xinfo = " statement is used -** to obtain the required information. -** -** If the index is of the following form: -** -** CREATE INDEX i1 ON t1(c, b COLLATE nocase); -** -** and "t1" is a table with an explicit INTEGER PRIMARY KEY column -** "ipk", the returned string is: -** -** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'" -** -** As well as the returned string, three other malloc'd strings are -** returned via output parameters. As follows: -** -** pzImposterCols: ... -** pzImposterPk: ... -** pzWhere: ... -*/ -static char *rbuObjIterGetIndexCols( - sqlite3rbu *p, /* RBU object */ - RbuObjIter *pIter, /* Object iterator for column names */ - char **pzImposterCols, /* OUT: Columns for imposter table */ - char **pzImposterPk, /* OUT: Imposter PK clause */ - char **pzWhere, /* OUT: WHERE clause */ - int *pnBind /* OUT: Trbul number of columns */ -){ - int rc = p->rc; /* Error code */ - int rc2; /* sqlite3_finalize() return code */ - char *zRet = 0; /* String to return */ - char *zImpCols = 0; /* String to return via *pzImposterCols */ - char *zImpPK = 0; /* String to return via *pzImposterPK */ - char *zWhere = 0; /* String to return via *pzWhere */ - int nBind = 0; /* Value to return via *pnBind */ - const char *zCom = ""; /* Set to ", " later on */ - const char *zAnd = ""; /* Set to " AND " later on */ - sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */ - - if( rc==SQLITE_OK ){ - assert( p->zErrmsg==0 ); - rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) - ); - } - - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ - int iCid = sqlite3_column_int(pXInfo, 1); - int bDesc = sqlite3_column_int(pXInfo, 3); - const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); - const char *zCol; - const char *zType; - - if( iCid<0 ){ - /* An integer primary key. If the table has an explicit IPK, use - ** its name. Otherwise, use "rbu_rowid". */ - if( pIter->eType==RBU_PK_IPK ){ - int i; - for(i=0; pIter->abTblPk[i]==0; i++); - assert( inTblCol ); - zCol = pIter->azTblCol[i]; - }else if( rbuIsVacuum(p) ){ - zCol = "_rowid_"; - }else{ - zCol = "rbu_rowid"; - } - zType = "INTEGER"; - }else{ - zCol = pIter->azTblCol[iCid]; - zType = pIter->azTblType[iCid]; - } - - zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate); - if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ - const char *zOrder = (bDesc ? " DESC" : ""); - zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", - zImpPK, zCom, nBind, zCol, zOrder - ); - } - zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", - zImpCols, zCom, nBind, zCol, zType, zCollate - ); - zWhere = sqlite3_mprintf( - "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol - ); - if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; - zCom = ", "; - zAnd = " AND "; - nBind++; - } - - rc2 = sqlite3_finalize(pXInfo); - if( rc==SQLITE_OK ) rc = rc2; - - if( rc!=SQLITE_OK ){ - sqlite3_free(zRet); - sqlite3_free(zImpCols); - sqlite3_free(zImpPK); - sqlite3_free(zWhere); - zRet = 0; - zImpCols = 0; - zImpPK = 0; - zWhere = 0; - p->rc = rc; - } - - *pzImposterCols = zImpCols; - *pzImposterPk = zImpPK; - *pzWhere = zWhere; - *pnBind = nBind; - return zRet; -} - -/* -** Assuming the current table columns are "a", "b" and "c", and the zObj -** paramter is passed "old", return a string of the form: -** -** "old.a, old.b, old.b" -** -** With the column names escaped. -** -** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append -** the text ", old._rowid_" to the returned value. -*/ -static char *rbuObjIterGetOldlist( - sqlite3rbu *p, - RbuObjIter *pIter, - const char *zObj -){ - char *zList = 0; - if( p->rc==SQLITE_OK && pIter->abIndexed ){ - const char *zS = ""; - int i; - for(i=0; inTblCol; i++){ - if( pIter->abIndexed[i] ){ - const char *zCol = pIter->azTblCol[i]; - zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); - }else{ - zList = sqlite3_mprintf("%z%sNULL", zList, zS); - } - zS = ", "; - if( zList==0 ){ - p->rc = SQLITE_NOMEM; - break; - } - } - - /* For a table with implicit rowids, append "old._rowid_" to the list. */ - if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ - zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj); - } - } - return zList; -} - -/* -** Return an expression that can be used in a WHERE clause to match the -** primary key of the current table. For example, if the table is: -** -** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)); -** -** Return the string: -** -** "b = ?1 AND c = ?2" -*/ -static char *rbuObjIterGetWhere( - sqlite3rbu *p, - RbuObjIter *pIter -){ - char *zList = 0; - if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){ - zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1); - }else if( pIter->eType==RBU_PK_EXTERNAL ){ - const char *zSep = ""; - int i; - for(i=0; inTblCol; i++){ - if( pIter->abTblPk[i] ){ - zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1); - zSep = " AND "; - } - } - zList = rbuMPrintf(p, - "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList - ); - - }else{ - const char *zSep = ""; - int i; - for(i=0; inTblCol; i++){ - if( pIter->abTblPk[i] ){ - const char *zCol = pIter->azTblCol[i]; - zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1); - zSep = " AND "; - } - } - } - return zList; -} - -/* -** The SELECT statement iterating through the keys for the current object -** (p->objiter.pSelect) currently points to a valid row. However, there -** is something wrong with the rbu_control value in the rbu_control value -** stored in the (p->nCol+1)'th column. Set the error code and error message -** of the RBU handle to something reflecting this. -*/ -static void rbuBadControlError(sqlite3rbu *p){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("invalid rbu_control value"); -} - - -/* -** Return a nul-terminated string containing the comma separated list of -** assignments that should be included following the "SET" keyword of -** an UPDATE statement used to update the table object that the iterator -** passed as the second argument currently points to if the rbu_control -** column of the data_xxx table entry is set to zMask. -** -** The memory for the returned string is obtained from sqlite3_malloc(). -** It is the responsibility of the caller to eventually free it using -** sqlite3_free(). -** -** If an OOM error is encountered when allocating space for the new -** string, an error code is left in the rbu handle passed as the first -** argument and NULL is returned. Or, if an error has already occurred -** when this function is called, NULL is returned immediately, without -** attempting the allocation or modifying the stored error code. -*/ -static char *rbuObjIterGetSetlist( - sqlite3rbu *p, - RbuObjIter *pIter, - const char *zMask -){ - char *zList = 0; - if( p->rc==SQLITE_OK ){ - int i; - - if( (int)strlen(zMask)!=pIter->nTblCol ){ - rbuBadControlError(p); - }else{ - const char *zSep = ""; - for(i=0; inTblCol; i++){ - char c = zMask[pIter->aiSrcOrder[i]]; - if( c=='x' ){ - zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", - zList, zSep, pIter->azTblCol[i], i+1 - ); - zSep = ", "; - } - else if( c=='d' ){ - zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)", - zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 - ); - zSep = ", "; - } - else if( c=='f' ){ - zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)", - zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 - ); - zSep = ", "; - } - } - } - } - return zList; -} - -/* -** Return a nul-terminated string consisting of nByte comma separated -** "?" expressions. For example, if nByte is 3, return a pointer to -** a buffer containing the string "?,?,?". -** -** The memory for the returned string is obtained from sqlite3_malloc(). -** It is the responsibility of the caller to eventually free it using -** sqlite3_free(). -** -** If an OOM error is encountered when allocating space for the new -** string, an error code is left in the rbu handle passed as the first -** argument and NULL is returned. Or, if an error has already occurred -** when this function is called, NULL is returned immediately, without -** attempting the allocation or modifying the stored error code. -*/ -static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){ - char *zRet = 0; - int nByte = nBind*2 + 1; - - zRet = (char*)rbuMalloc(p, nByte); - if( zRet ){ - int i; - for(i=0; izIdx==0 ); - if( p->rc==SQLITE_OK ){ - const char *zSep = "PRIMARY KEY("; - sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ - sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ - - p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) - ); - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ - const char *zOrig = (const char*)sqlite3_column_text(pXList,3); - if( zOrig && strcmp(zOrig, "pk")==0 ){ - const char *zIdx = (const char*)sqlite3_column_text(pXList,1); - if( zIdx ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) - ); - } - break; - } - } - rbuFinalize(p, pXList); - - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ - if( sqlite3_column_int(pXInfo, 5) ){ - /* int iCid = sqlite3_column_int(pXInfo, 0); */ - const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); - const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; - z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); - zSep = ", "; - } - } - z = rbuMPrintf(p, "%z)", z); - rbuFinalize(p, pXInfo); - } - return z; -} - -/* -** This function creates the second imposter table used when writing to -** a table b-tree where the table has an external primary key. If the -** iterator passed as the second argument does not currently point to -** a table (not index) with an external primary key, this function is a -** no-op. -** -** Assuming the iterator does point to a table with an external PK, this -** function creates a WITHOUT ROWID imposter table named "rbu_imposter2" -** used to access that PK index. For example, if the target table is -** declared as follows: -** -** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c)); -** -** then the imposter table schema is: -** -** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID; -** -*/ -static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ - if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){ - int tnum = pIter->iPkTnum; /* Root page of PK index */ - sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ - const char *zIdx = 0; /* Name of PK index */ - sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ - const char *zComma = ""; - char *zCols = 0; /* Used to build up list of table cols */ - char *zPk = 0; /* Used to build up table PK declaration */ - - /* Figure out the name of the primary key index for the current table. - ** This is needed for the argument to "PRAGMA index_xinfo". Set - ** zIdx to point to a nul-terminated string containing this name. */ - p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, - "SELECT name FROM sqlite_master WHERE rootpage = ?" - ); - if( p->rc==SQLITE_OK ){ - sqlite3_bind_int(pQuery, 1, tnum); - if( SQLITE_ROW==sqlite3_step(pQuery) ){ - zIdx = (const char*)sqlite3_column_text(pQuery, 0); - } - } - if( zIdx ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) - ); - } - rbuFinalize(p, pQuery); - - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ - int bKey = sqlite3_column_int(pXInfo, 5); - if( bKey ){ - int iCid = sqlite3_column_int(pXInfo, 1); - int bDesc = sqlite3_column_int(pXInfo, 3); - const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); - zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, - iCid, pIter->azTblType[iCid], zCollate - ); - zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); - zComma = ", "; - } - } - zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); - rbuFinalize(p, pXInfo); - - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); - rbuMPrintfExec(p, p->dbMain, - "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", - zCols, zPk - ); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); - } -} - -/* -** If an error has already occurred when this function is called, it -** immediately returns zero (without doing any work). Or, if an error -** occurs during the execution of this function, it sets the error code -** in the sqlite3rbu object indicated by the first argument and returns -** zero. -** -** The iterator passed as the second argument is guaranteed to point to -** a table (not an index) when this function is called. This function -** attempts to create any imposter table required to write to the main -** table b-tree of the table before returning. Non-zero is returned if -** an imposter table are created, or zero otherwise. -** -** An imposter table is required in all cases except RBU_PK_VTAB. Only -** virtual tables are written to directly. The imposter table has the -** same schema as the actual target table (less any UNIQUE constraints). -** More precisely, the "same schema" means the same columns, types, -** collation sequences. For tables that do not have an external PRIMARY -** KEY, it also means the same PRIMARY KEY declaration. -*/ -static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ - if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){ - int tnum = pIter->iTnum; - const char *zComma = ""; - char *zSql = 0; - int iCol; - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); - - for(iCol=0; p->rc==SQLITE_OK && iColnTblCol; iCol++){ - const char *zPk = ""; - const char *zCol = pIter->azTblCol[iCol]; - const char *zColl = 0; - - p->rc = sqlite3_table_column_metadata( - p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0 - ); - - if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){ - /* If the target table column is an "INTEGER PRIMARY KEY", add - ** "PRIMARY KEY" to the imposter table column declaration. */ - zPk = "PRIMARY KEY "; - } - zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", - zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, - (pIter->abNotNull[iCol] ? " NOT NULL" : "") - ); - zComma = ", "; - } - - if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ - char *zPk = rbuWithoutRowidPK(p, pIter); - if( zPk ){ - zSql = rbuMPrintf(p, "%z, %z", zSql, zPk); - } - } - - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); - rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", - pIter->zTbl, zSql, - (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") - ); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); - } -} - -/* -** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table. -** Specifically a statement of the form: -** -** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...); -** -** The number of bound variables is equal to the number of columns in -** the target table, plus one (for the rbu_control column), plus one more -** (for the rbu_rowid column) if the target table is an implicit IPK or -** virtual table. -*/ -static void rbuObjIterPrepareTmpInsert( - sqlite3rbu *p, - RbuObjIter *pIter, - const char *zCollist, - const char *zRbuRowid -){ - int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE); - char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid); - if( zBind ){ - assert( pIter->pTmpInsert==0 ); - p->rc = prepareFreeAndCollectError( - p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf( - "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", - p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind - )); - } -} - -static void rbuTmpInsertFunc( - sqlite3_context *pCtx, - int nVal, - sqlite3_value **apVal -){ - sqlite3rbu *p = sqlite3_user_data(pCtx); - int rc = SQLITE_OK; - int i; - - assert( sqlite3_value_int(apVal[0])!=0 - || p->objiter.eType==RBU_PK_EXTERNAL - || p->objiter.eType==RBU_PK_NONE - ); - if( sqlite3_value_int(apVal[0])!=0 ){ - p->nPhaseOneStep += p->objiter.nIndex; - } - - for(i=0; rc==SQLITE_OK && iobjiter.pTmpInsert, i+1, apVal[i]); - } - if( rc==SQLITE_OK ){ - sqlite3_step(p->objiter.pTmpInsert); - rc = sqlite3_reset(p->objiter.pTmpInsert); - } - - if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(pCtx, rc); - } -} - -/* -** Ensure that the SQLite statement handles required to update the -** target database object currently indicated by the iterator passed -** as the second argument are available. -*/ -static int rbuObjIterPrepareAll( - sqlite3rbu *p, - RbuObjIter *pIter, - int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */ -){ - assert( pIter->bCleanup==0 ); - if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){ - const int tnum = pIter->iTnum; - char *zCollist = 0; /* List of indexed columns */ - char **pz = &p->zErrmsg; - const char *zIdx = pIter->zIdx; - char *zLimit = 0; - - if( nOffset ){ - zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); - if( !zLimit ) p->rc = SQLITE_NOMEM; - } - - if( zIdx ){ - const char *zTbl = pIter->zTbl; - char *zImposterCols = 0; /* Columns for imposter table */ - char *zImposterPK = 0; /* Primary key declaration for imposter */ - char *zWhere = 0; /* WHERE clause on PK columns */ - char *zBind = 0; - int nBind = 0; - - assert( pIter->eType!=RBU_PK_VTAB ); - zCollist = rbuObjIterGetIndexCols( - p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind - ); - zBind = rbuObjIterGetBindlist(p, nBind); - - /* Create the imposter table used to write to this index. */ - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); - rbuMPrintfExec(p, p->dbMain, - "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", - zTbl, zImposterCols, zImposterPK - ); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); - - /* Create the statement to insert index entries */ - pIter->nCol = nBind; - if( p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError( - p->dbMain, &pIter->pInsert, &p->zErrmsg, - sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) - ); - } - - /* And to delete index entries */ - if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError( - p->dbMain, &pIter->pDelete, &p->zErrmsg, - sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) - ); - } - - /* Create the SELECT statement to read keys in sorted order */ - if( p->rc==SQLITE_OK ){ - char *zSql; - if( rbuIsVacuum(p) ){ - zSql = sqlite3_mprintf( - "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s", - zCollist, - pIter->zDataTbl, - zCollist, zLimit - ); - }else - - if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ - zSql = sqlite3_mprintf( - "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", - zCollist, p->zStateDb, pIter->zDataTbl, - zCollist, zLimit - ); - }else{ - zSql = sqlite3_mprintf( - "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' " - "UNION ALL " - "SELECT %s, rbu_control FROM '%q' " - "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 " - "ORDER BY %s%s", - zCollist, p->zStateDb, pIter->zDataTbl, - zCollist, pIter->zDataTbl, - zCollist, zLimit - ); - } - p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql); - } - - sqlite3_free(zImposterCols); - sqlite3_free(zImposterPK); - sqlite3_free(zWhere); - sqlite3_free(zBind); - }else{ - int bRbuRowid = (pIter->eType==RBU_PK_VTAB) - ||(pIter->eType==RBU_PK_NONE) - ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)); - const char *zTbl = pIter->zTbl; /* Table this step applies to */ - const char *zWrite; /* Imposter table name */ - - char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid); - char *zWhere = rbuObjIterGetWhere(p, pIter); - char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old"); - char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new"); - - zCollist = rbuObjIterGetCollist(p, pIter); - pIter->nCol = pIter->nTblCol; - - /* Create the imposter table or tables (if required). */ - rbuCreateImposterTable(p, pIter); - rbuCreateImposterTable2(p, pIter); - zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_"); - - /* Create the INSERT statement to write to the target PK b-tree */ - if( p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, - sqlite3_mprintf( - "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", - zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings - ) - ); - } - - /* Create the DELETE statement to write to the target PK b-tree. - ** Because it only performs INSERT operations, this is not required for - ** an rbu vacuum handle. */ - if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, - sqlite3_mprintf( - "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere - ) - ); - } - - if( rbuIsVacuum(p)==0 && pIter->abIndexed ){ - const char *zRbuRowid = ""; - if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ - zRbuRowid = ", rbu_rowid"; - } - - /* Create the rbu_tmp_xxx table and the triggers to populate it. */ - rbuMPrintfExec(p, p->dbRbu, - "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS " - "SELECT *%s FROM '%q' WHERE 0;" - , p->zStateDb, pIter->zDataTbl - , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") - , pIter->zDataTbl - ); - - rbuMPrintfExec(p, p->dbMain, - "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " - "BEGIN " - " SELECT rbu_tmp_insert(3, %s);" - "END;" - - "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " - "BEGIN " - " SELECT rbu_tmp_insert(3, %s);" - "END;" - - "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " - "BEGIN " - " SELECT rbu_tmp_insert(4, %s);" - "END;", - zWrite, zTbl, zOldlist, - zWrite, zTbl, zOldlist, - zWrite, zTbl, zNewlist - ); - - if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ - rbuMPrintfExec(p, p->dbMain, - "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" " - "BEGIN " - " SELECT rbu_tmp_insert(0, %s);" - "END;", - zWrite, zTbl, zNewlist - ); - } - - rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid); - } - - /* Create the SELECT statement to read keys from data_xxx */ - if( p->rc==SQLITE_OK ){ - const char *zRbuRowid = ""; - if( bRbuRowid ){ - zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid"; - } - p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, - sqlite3_mprintf( - "SELECT %s,%s rbu_control%s FROM '%q'%s", - zCollist, - (rbuIsVacuum(p) ? "0 AS " : ""), - zRbuRowid, - pIter->zDataTbl, zLimit - ) - ); - } - - sqlite3_free(zWhere); - sqlite3_free(zOldlist); - sqlite3_free(zNewlist); - sqlite3_free(zBindings); - } - sqlite3_free(zCollist); - sqlite3_free(zLimit); - } - - return p->rc; -} - -/* -** Set output variable *ppStmt to point to an UPDATE statement that may -** be used to update the imposter table for the main table b-tree of the -** table object that pIter currently points to, assuming that the -** rbu_control column of the data_xyz table contains zMask. -** -** If the zMask string does not specify any columns to update, then this -** is not an error. Output variable *ppStmt is set to NULL in this case. -*/ -static int rbuGetUpdateStmt( - sqlite3rbu *p, /* RBU handle */ - RbuObjIter *pIter, /* Object iterator */ - const char *zMask, /* rbu_control value ('x.x.') */ - sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ -){ - RbuUpdateStmt **pp; - RbuUpdateStmt *pUp = 0; - int nUp = 0; - - /* In case an error occurs */ - *ppStmt = 0; - - /* Search for an existing statement. If one is found, shift it to the front - ** of the LRU queue and return immediately. Otherwise, leave nUp pointing - ** to the number of statements currently in the cache and pUp to the - ** last object in the list. */ - for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){ - pUp = *pp; - if( strcmp(pUp->zMask, zMask)==0 ){ - *pp = pUp->pNext; - pUp->pNext = pIter->pRbuUpdate; - pIter->pRbuUpdate = pUp; - *ppStmt = pUp->pUpdate; - return SQLITE_OK; - } - nUp++; - } - assert( pUp==0 || pUp->pNext==0 ); - - if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){ - for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext)); - *pp = 0; - sqlite3_finalize(pUp->pUpdate); - pUp->pUpdate = 0; - }else{ - pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1); - } - - if( pUp ){ - char *zWhere = rbuObjIterGetWhere(p, pIter); - char *zSet = rbuObjIterGetSetlist(p, pIter, zMask); - char *zUpdate = 0; - - pUp->zMask = (char*)&pUp[1]; - memcpy(pUp->zMask, zMask, pIter->nTblCol); - pUp->pNext = pIter->pRbuUpdate; - pIter->pRbuUpdate = pUp; - - if( zSet ){ - const char *zPrefix = ""; - - if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; - zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", - zPrefix, pIter->zTbl, zSet, zWhere - ); - p->rc = prepareFreeAndCollectError( - p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate - ); - *ppStmt = pUp->pUpdate; - } - sqlite3_free(zWhere); - sqlite3_free(zSet); - } - - return p->rc; -} - -static sqlite3 *rbuOpenDbhandle( - sqlite3rbu *p, - const char *zName, - int bUseVfs -){ - sqlite3 *db = 0; - if( p->rc==SQLITE_OK ){ - const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; - p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); - if( p->rc ){ - p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); - sqlite3_close(db); - db = 0; - } - } - return db; -} - -/* -** Free an RbuState object allocated by rbuLoadState(). -*/ -static void rbuFreeState(RbuState *p){ - if( p ){ - sqlite3_free(p->zTbl); - sqlite3_free(p->zIdx); - sqlite3_free(p); - } -} - -/* -** Allocate an RbuState object and load the contents of the rbu_state -** table into it. Return a pointer to the new object. It is the -** responsibility of the caller to eventually free the object using -** sqlite3_free(). -** -** If an error occurs, leave an error code and message in the rbu handle -** and return NULL. -*/ -static RbuState *rbuLoadState(sqlite3rbu *p){ - RbuState *pRet = 0; - sqlite3_stmt *pStmt = 0; - int rc; - int rc2; - - pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); - if( pRet==0 ) return 0; - - rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, - sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) - ); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - switch( sqlite3_column_int(pStmt, 0) ){ - case RBU_STATE_STAGE: - pRet->eStage = sqlite3_column_int(pStmt, 1); - if( pRet->eStage!=RBU_STAGE_OAL - && pRet->eStage!=RBU_STAGE_MOVE - && pRet->eStage!=RBU_STAGE_CKPT - ){ - p->rc = SQLITE_CORRUPT; - } - break; - - case RBU_STATE_TBL: - pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); - break; - - case RBU_STATE_IDX: - pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); - break; - - case RBU_STATE_ROW: - pRet->nRow = sqlite3_column_int(pStmt, 1); - break; - - case RBU_STATE_PROGRESS: - pRet->nProgress = sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_CKPT: - pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_COOKIE: - pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_OALSZ: - pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); - break; - - case RBU_STATE_PHASEONESTEP: - pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); - break; - - default: - rc = SQLITE_CORRUPT; - break; - } - } - rc2 = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) rc = rc2; - - p->rc = rc; - return pRet; -} - - -/* -** Open the database handle and attach the RBU database as "rbu". If an -** error occurs, leave an error code and message in the RBU handle. -*/ -static void rbuOpenDatabase(sqlite3rbu *p){ - assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); - assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); - - /* Open the RBU database */ - p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); - - if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ - sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); - if( p->zState==0 ){ - const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); - p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); - } - } - - /* If using separate RBU and state databases, attach the state database to - ** the RBU db handle now. */ - if( p->zState ){ - rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState); - memcpy(p->zStateDb, "stat", 4); - }else{ - memcpy(p->zStateDb, "main", 4); - } - -#if 0 - if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ - p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); - } -#endif - - /* If it has not already been created, create the rbu_state table */ - rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); - -#if 0 - if( rbuIsVacuum(p) ){ - if( p->rc==SQLITE_OK ){ - int rc2; - int bOk = 0; - sqlite3_stmt *pCnt = 0; - p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg, - "SELECT count(*) FROM stat.sqlite_master" - ); - if( p->rc==SQLITE_OK - && sqlite3_step(pCnt)==SQLITE_ROW - && 1==sqlite3_column_int(pCnt, 0) - ){ - bOk = 1; - } - rc2 = sqlite3_finalize(pCnt); - if( p->rc==SQLITE_OK ) p->rc = rc2; - - if( p->rc==SQLITE_OK && bOk==0 ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("invalid state database"); - } - - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); - } - } - } -#endif - - if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ - int bOpen = 0; - int rc; - p->nRbu = 0; - p->pRbuFd = 0; - rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); - if( rc!=SQLITE_NOTFOUND ) p->rc = rc; - if( p->eStage>=RBU_STAGE_MOVE ){ - bOpen = 1; - }else{ - RbuState *pState = rbuLoadState(p); - if( pState ){ - bOpen = (pState->eStage>RBU_STAGE_MOVE); - rbuFreeState(pState); - } - } - if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1); - } - - p->eStage = 0; - if( p->rc==SQLITE_OK && p->dbMain==0 ){ - if( !rbuIsVacuum(p) ){ - p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); - }else if( p->pRbuFd->pWalFd ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); - }else{ - char *zTarget; - char *zExtra = 0; - if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){ - zExtra = &p->zRbu[5]; - while( *zExtra ){ - if( *zExtra++=='?' ) break; - } - if( *zExtra=='\0' ) zExtra = 0; - } - - zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", - sqlite3_db_filename(p->dbRbu, "main"), - (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) - ); - - if( zTarget==0 ){ - p->rc = SQLITE_NOMEM; - return; - } - p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1); - sqlite3_free(zTarget); - } - } - - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_create_function(p->dbMain, - "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 - ); - } - - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_create_function(p->dbMain, - "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0 - ); - } - - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_create_function(p->dbRbu, - "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 - ); - } - - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); - } - rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master"); - - /* Mark the database file just opened as an RBU target database. If - ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. - ** This is an error. */ - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); - } - - if( p->rc==SQLITE_NOTFOUND ){ - p->rc = SQLITE_ERROR; - p->zErrmsg = sqlite3_mprintf("rbu vfs not found"); - } -} - -/* -** This routine is a copy of the sqlite3FileSuffix3() routine from the core. -** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined. -** -** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database -** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and -** if filename in z[] has a suffix (a.k.a. "extension") that is longer than -** three characters, then shorten the suffix on z[] to be the last three -** characters of the original suffix. -** -** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always -** do the suffix shortening regardless of URI parameter. -** -** Examples: -** -** test.db-journal => test.nal -** test.db-wal => test.wal -** test.db-shm => test.shm -** test.db-mj7f3319fa => test.9fa -*/ -static void rbuFileSuffix3(const char *zBase, char *z){ -#ifdef SQLITE_ENABLE_8_3_NAMES -#if SQLITE_ENABLE_8_3_NAMES<2 - if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) -#endif - { - int i, sz; - sz = (int)strlen(z)&0xffffff; - for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} - if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); - } -#endif -} - -/* -** Return the current wal-index header checksum for the target database -** as a 64-bit integer. -** -** The checksum is store in the first page of xShmMap memory as an 8-byte -** blob starting at byte offset 40. -*/ -static i64 rbuShmChecksum(sqlite3rbu *p){ - i64 iRet = 0; - if( p->rc==SQLITE_OK ){ - sqlite3_file *pDb = p->pTargetFd->pReal; - u32 volatile *ptr; - p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); - if( p->rc==SQLITE_OK ){ - iRet = ((i64)ptr[10] << 32) + ptr[11]; - } - } - return iRet; -} - -/* -** This function is called as part of initializing or reinitializing an -** incremental checkpoint. -** -** It populates the sqlite3rbu.aFrame[] array with the set of -** (wal frame -> db page) copy operations required to checkpoint the -** current wal file, and obtains the set of shm locks required to safely -** perform the copy operations directly on the file-system. -** -** If argument pState is not NULL, then the incremental checkpoint is -** being resumed. In this case, if the checksum of the wal-index-header -** following recovery is not the same as the checksum saved in the RbuState -** object, then the rbu handle is set to DONE state. This occurs if some -** other client appends a transaction to the wal file in the middle of -** an incremental checkpoint. -*/ -static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ - - /* If pState is NULL, then the wal file may not have been opened and - ** recovered. Running a read-statement here to ensure that doing so - ** does not interfere with the "capture" process below. */ - if( pState==0 ){ - p->eStage = 0; - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0); - } - } - - /* Assuming no error has occurred, run a "restart" checkpoint with the - ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following - ** special behaviour in the rbu VFS: - ** - ** * If the exclusive shm WRITER or READ0 lock cannot be obtained, - ** the checkpoint fails with SQLITE_BUSY (normally SQLite would - ** proceed with running a passive checkpoint instead of failing). - ** - ** * Attempts to read from the *-wal file or write to the database file - ** do not perform any IO. Instead, the frame/page combinations that - ** would be read/written are recorded in the sqlite3rbu.aFrame[] - ** array. - ** - ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, - ** READ0 and CHECKPOINT locks taken as part of the checkpoint are - ** no-ops. These locks will not be released until the connection - ** is closed. - ** - ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL - ** error. - ** - ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the - ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[] - ** array populated with a set of (frame -> page) mappings. Because the - ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy - ** data from the wal file into the database file according to the - ** contents of aFrame[]. - */ - if( p->rc==SQLITE_OK ){ - int rc2; - p->eStage = RBU_STAGE_CAPTURE; - rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); - if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; - } - - if( p->rc==SQLITE_OK ){ - p->eStage = RBU_STAGE_CKPT; - p->nStep = (pState ? pState->nRow : 0); - p->aBuf = rbuMalloc(p, p->pgsz); - p->iWalCksum = rbuShmChecksum(p); - } - - if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){ - p->rc = SQLITE_DONE; - p->eStage = RBU_STAGE_DONE; - } -} - -/* -** Called when iAmt bytes are read from offset iOff of the wal file while -** the rbu object is in capture mode. Record the frame number of the frame -** being read in the aFrame[] array. -*/ -static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ - const u32 mReq = (1<mLock!=mReq ){ - pRbu->rc = SQLITE_BUSY; - return SQLITE_INTERNAL; - } - - pRbu->pgsz = iAmt; - if( pRbu->nFrame==pRbu->nFrameAlloc ){ - int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; - RbuFrame *aNew; - aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame)); - if( aNew==0 ) return SQLITE_NOMEM; - pRbu->aFrame = aNew; - pRbu->nFrameAlloc = nNew; - } - - iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1; - if( pRbu->iMaxFrame